diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index a78eccbbc..bde71a039 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -87,7 +87,7 @@ jobs: - name: Install dependencies (Alpine) if: matrix.platform.type == 'container' run: | - apk add --no-cache cmake make g++ linux-headers zsh bash jq shellcheck pipx git perl-utils ca-certificates nodejs + apk add --no-cache cmake make g++ linux-headers zsh bash jq shellcheck pipx git perl-utils ca-certificates nodejs libcurl apk add --no-cache --repository https://dl-cdn.alpinelinux.org/alpine/edge/main --repository https://dl-cdn.alpinelinux.org/alpine/edge/community --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing fuse3 bindfs - name: Install pre-commit @@ -107,7 +107,7 @@ jobs: run: | sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test sudo apt-get update --yes - sudo apt-get install --yes g++-14 zsh bindfs + sudo apt-get install --yes g++-14 zsh bindfs libcurl4 - run: cmake --version diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d05ef528..0e4e3918c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -83,13 +83,13 @@ jobs: if: runner.os == 'windows' && matrix.platform.type == 'wsl-2' with: distribution: Ubuntu-24.04 - additional-packages: cmake build-essential gcc-14 g++-14 shellcheck pipx zsh jq bindfs nodejs + additional-packages: cmake build-essential gcc-14 g++-14 shellcheck pipx zsh jq bindfs nodejs libcurl4 wsl-version: 2 - name: Install dependencies (Alpine) if: matrix.platform.type == 'container' run: | - apk add --no-cache cmake make g++ linux-headers zsh bash jq shellcheck pipx git perl-utils ca-certificates nodejs + apk add --no-cache cmake make g++ linux-headers zsh bash jq shellcheck pipx git perl-utils ca-certificates nodejs libcurl apk add --no-cache --repository https://dl-cdn.alpinelinux.org/alpine/edge/main --repository https://dl-cdn.alpinelinux.org/alpine/edge/community --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing fuse3 bindfs - name: Install pre-commit @@ -114,7 +114,7 @@ jobs: run: | sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test sudo apt-get update --yes - sudo apt-get install --yes gcc-14 g++-14 zsh bindfs + sudo apt-get install --yes gcc-14 g++-14 zsh bindfs libcurl4 - run: cmake --version - name: Configure JSON Schema diff --git a/DEPENDENCIES b/DEPENDENCIES index 3af6a7568..7842dff44 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -2,10 +2,4 @@ vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b86 core https://github.com/sourcemeta/core 04e936961d1e31f6b70fa5a30e115b2f7855674a jsonbinpack https://github.com/sourcemeta/jsonbinpack ac8e1af733a781fc4c94a14157f80970ea569479 blaze https://github.com/sourcemeta/blaze e73e5e1667487717b44ab351a0f46e01d507fefb -mbedtls https://github.com/Mbed-TLS/mbedtls v3.6.6 -curl https://github.com/curl/curl curl-8_20_0 -nghttp2 https://github.com/nghttp2/nghttp2 v1.67.1 -c-ares https://github.com/c-ares/c-ares v1.34.5 -libpsl https://github.com/rockdaboot/libpsl 0.21.5 -zlib https://github.com/madler/zlib v1.3.2 ctrf https://github.com/ctrf-io/ctrf 93ea827d951390190171d37443bff169cf47c808 diff --git a/Dockerfile.test.alpine b/Dockerfile.test.alpine index 2966c1e20..60106d19d 100644 --- a/Dockerfile.test.alpine +++ b/Dockerfile.test.alpine @@ -1,5 +1,5 @@ FROM alpine:3.21 -RUN apk add --no-cache cmake make g++ linux-headers zsh bash jq perl-utils +RUN apk add --no-cache cmake make g++ linux-headers zsh bash jq perl-utils libcurl WORKDIR /src COPY CMakeLists.txt . COPY DEPENDENCIES DEPENDENCIES diff --git a/README.markdown b/README.markdown index 8f71d4890..bc65dd903 100644 --- a/README.markdown +++ b/README.markdown @@ -199,6 +199,17 @@ Keep in mind that it is hard to provide binaries that work across GNU/Linux distributions. We conservatively target Ubuntu and Alpine, but you might need to build from source if your distribution of choice is different. +> [!NOTE] +> On GNU/Linux (and other non-macOS, non-Windows platforms), the CLI performs +> HTTP requests through your system's cURL library, which it loads at runtime. +> This keeps the binaries distribution-independent and makes them respect your +> system's TLS trust store. `libcurl` is present on most systems, but if it is +> missing you can install it through your package manager (for example +> `apt install libcurl4`, `dnf install libcurl`, or `apk add libcurl`). If it +> lives in a non-standard location, point the CLI at it by setting the +> `SOURCEMETA_JSONSCHEMA_CURL_SO` environment variable to the full path of +> `libcurl.so.4`. + To verify the GPG signature of the checksums file: ```sh diff --git a/cmake/FindCAres.cmake b/cmake/FindCAres.cmake deleted file mode 100644 index 7b066e8fc..000000000 --- a/cmake/FindCAres.cmake +++ /dev/null @@ -1,288 +0,0 @@ -if(NOT CAres_FOUND) - set(CARES_DIR "${PROJECT_SOURCE_DIR}/vendor/c-ares") - - file(STRINGS "${PROJECT_SOURCE_DIR}/DEPENDENCIES" CARES_VERSION_LINE - REGEX "^c-ares ") - if(CARES_VERSION_LINE) - string(REGEX MATCH "v?([0-9]+)\\.([0-9]+)\\.([0-9]+)" CARES_VERSION_MATCH "${CARES_VERSION_LINE}") - set(CARES_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(CARES_VERSION_MINOR "${CMAKE_MATCH_2}") - set(CARES_VERSION_PATCH "${CMAKE_MATCH_3}") - set(CARES_VERSION_STRING "${CARES_VERSION_MAJOR}.${CARES_VERSION_MINOR}.${CARES_VERSION_PATCH}") - else() - message(FATAL_ERROR "Could not find c-ares version in DEPENDENCIES") - endif() - - set(CARES_PUBLIC_HEADERS - "${CARES_DIR}/include/ares.h" - "${CARES_DIR}/include/ares_nameser.h" - "${CARES_DIR}/include/ares_dns.h" - "${CARES_DIR}/include/ares_dns_record.h" - "${CARES_DIR}/include/ares_version.h") - - set(CARES_SOURCES - "${CARES_DIR}/src/lib/ares_addrinfo_localhost.c" - "${CARES_DIR}/src/lib/ares_addrinfo2hostent.c" - "${CARES_DIR}/src/lib/ares_android.c" - "${CARES_DIR}/src/lib/ares_cancel.c" - "${CARES_DIR}/src/lib/ares_close_sockets.c" - "${CARES_DIR}/src/lib/ares_conn.c" - "${CARES_DIR}/src/lib/ares_cookie.c" - "${CARES_DIR}/src/lib/ares_data.c" - "${CARES_DIR}/src/lib/ares_destroy.c" - "${CARES_DIR}/src/lib/ares_free_hostent.c" - "${CARES_DIR}/src/lib/ares_free_string.c" - "${CARES_DIR}/src/lib/ares_freeaddrinfo.c" - "${CARES_DIR}/src/lib/ares_getaddrinfo.c" - "${CARES_DIR}/src/lib/ares_getenv.c" - "${CARES_DIR}/src/lib/ares_gethostbyaddr.c" - "${CARES_DIR}/src/lib/ares_gethostbyname.c" - "${CARES_DIR}/src/lib/ares_getnameinfo.c" - "${CARES_DIR}/src/lib/ares_hosts_file.c" - "${CARES_DIR}/src/lib/ares_init.c" - "${CARES_DIR}/src/lib/ares_library_init.c" - "${CARES_DIR}/src/lib/ares_metrics.c" - "${CARES_DIR}/src/lib/ares_options.c" - "${CARES_DIR}/src/lib/ares_parse_into_addrinfo.c" - "${CARES_DIR}/src/lib/ares_process.c" - "${CARES_DIR}/src/lib/ares_qcache.c" - "${CARES_DIR}/src/lib/ares_query.c" - "${CARES_DIR}/src/lib/ares_search.c" - "${CARES_DIR}/src/lib/ares_send.c" - "${CARES_DIR}/src/lib/ares_set_socket_functions.c" - "${CARES_DIR}/src/lib/ares_socket.c" - "${CARES_DIR}/src/lib/ares_sortaddrinfo.c" - "${CARES_DIR}/src/lib/ares_strerror.c" - "${CARES_DIR}/src/lib/ares_sysconfig_files.c" - "${CARES_DIR}/src/lib/ares_sysconfig_mac.c" - "${CARES_DIR}/src/lib/ares_sysconfig_win.c" - "${CARES_DIR}/src/lib/ares_sysconfig.c" - "${CARES_DIR}/src/lib/ares_timeout.c" - "${CARES_DIR}/src/lib/ares_update_servers.c" - "${CARES_DIR}/src/lib/ares_version.c" - "${CARES_DIR}/src/lib/inet_net_pton.c" - "${CARES_DIR}/src/lib/inet_ntop.c" - "${CARES_DIR}/src/lib/windows_port.c" - "${CARES_DIR}/src/lib/dsa/ares_array.c" - "${CARES_DIR}/src/lib/dsa/ares_htable.c" - "${CARES_DIR}/src/lib/dsa/ares_htable_asvp.c" - "${CARES_DIR}/src/lib/dsa/ares_htable_dict.c" - "${CARES_DIR}/src/lib/dsa/ares_htable_strvp.c" - "${CARES_DIR}/src/lib/dsa/ares_htable_szvp.c" - "${CARES_DIR}/src/lib/dsa/ares_htable_vpstr.c" - "${CARES_DIR}/src/lib/dsa/ares_htable_vpvp.c" - "${CARES_DIR}/src/lib/dsa/ares_llist.c" - "${CARES_DIR}/src/lib/dsa/ares_slist.c" - "${CARES_DIR}/src/lib/event/ares_event_configchg.c" - "${CARES_DIR}/src/lib/event/ares_event_epoll.c" - "${CARES_DIR}/src/lib/event/ares_event_kqueue.c" - "${CARES_DIR}/src/lib/event/ares_event_poll.c" - "${CARES_DIR}/src/lib/event/ares_event_select.c" - "${CARES_DIR}/src/lib/event/ares_event_thread.c" - "${CARES_DIR}/src/lib/event/ares_event_wake_pipe.c" - "${CARES_DIR}/src/lib/event/ares_event_win32.c" - "${CARES_DIR}/src/lib/record/ares_dns_mapping.c" - "${CARES_DIR}/src/lib/record/ares_dns_multistring.c" - "${CARES_DIR}/src/lib/record/ares_dns_name.c" - "${CARES_DIR}/src/lib/record/ares_dns_parse.c" - "${CARES_DIR}/src/lib/record/ares_dns_record.c" - "${CARES_DIR}/src/lib/record/ares_dns_write.c" - "${CARES_DIR}/src/lib/str/ares_buf.c" - "${CARES_DIR}/src/lib/str/ares_str.c" - "${CARES_DIR}/src/lib/str/ares_strsplit.c" - "${CARES_DIR}/src/lib/util/ares_iface_ips.c" - "${CARES_DIR}/src/lib/util/ares_math.c" - "${CARES_DIR}/src/lib/util/ares_rand.c" - "${CARES_DIR}/src/lib/util/ares_threads.c" - "${CARES_DIR}/src/lib/util/ares_timeval.c" - "${CARES_DIR}/src/lib/util/ares_uri.c" - "${CARES_DIR}/src/lib/legacy/ares_create_query.c" - "${CARES_DIR}/src/lib/legacy/ares_expand_name.c" - "${CARES_DIR}/src/lib/legacy/ares_expand_string.c" - "${CARES_DIR}/src/lib/legacy/ares_fds.c" - "${CARES_DIR}/src/lib/legacy/ares_getsock.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_a_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_aaaa_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_caa_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_mx_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_naptr_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_ns_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_ptr_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_soa_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_srv_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_txt_reply.c" - "${CARES_DIR}/src/lib/legacy/ares_parse_uri_reply.c") - - add_library(cares ${CARES_SOURCES}) - - if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(cares PRIVATE /W3 /wd4996 /wd4013 /MP) - set(CARES_TYPEOF_ARES_SOCKLEN_T "int") - set(CARES_TYPEOF_ARES_SSIZE_T "SSIZE_T") - set(RECV_TYPE_ARG1 "SOCKET") - set(RECV_TYPE_ARG2 "char *") - set(RECV_TYPE_ARG3 "int") - set(RECV_TYPE_ARG4 "int") - set(RECVFROM_TYPE_ARG1 "SOCKET") - set(RECVFROM_TYPE_ARG2 "char *") - set(RECVFROM_TYPE_ARG3 "int") - set(RECVFROM_TYPE_ARG4 "int") - set(RECVFROM_TYPE_ARG5 "struct sockaddr *") - set(RECVFROM_TYPE_ARG6 "int *") - set(SEND_TYPE_ARG1 "SOCKET") - set(SEND_TYPE_ARG2 "const char *") - set(SEND_TYPE_ARG3 "int") - set(SEND_TYPE_ARG4 "int") - set(GETHOSTNAME_TYPE_ARG2 "int") - set(GETNAMEINFO_TYPE_ARG1 "struct sockaddr *") - set(GETNAMEINFO_TYPE_ARG2 "int") - set(GETNAMEINFO_TYPE_ARG46 "DWORD") - set(GETNAMEINFO_TYPE_ARG7 "int") - target_compile_definitions(cares PRIVATE _CRT_SECURE_NO_WARNINGS) - target_compile_definitions(cares PRIVATE HAVE_WINDOWS_H) - target_compile_definitions(cares PRIVATE HAVE_WINSOCK2_H) - target_compile_definitions(cares PRIVATE HAVE_WS2TCPIP_H) - target_compile_definitions(cares PRIVATE HAVE_IPHLPAPI_H) - target_compile_definitions(cares PRIVATE HAVE_NETIOAPI_H) - target_compile_definitions(cares PRIVATE HAVE_SYS_STAT_H) - target_compile_definitions(cares PRIVATE HAVE_STRUCT_TIMEVAL) - target_compile_definitions(cares PRIVATE HAVE_STRUCT_SOCKADDR_IN6) - target_compile_definitions(cares PRIVATE HAVE_STRUCT_ADDRINFO) - target_compile_definitions(cares PRIVATE HAVE_AF_INET6) - target_compile_definitions(cares PRIVATE HAVE_RECV) - target_compile_definitions(cares PRIVATE HAVE_RECVFROM) - target_compile_definitions(cares PRIVATE HAVE_SEND) - target_compile_definitions(cares PRIVATE HAVE_SENDTO) - target_compile_definitions(cares PRIVATE HAVE_IOCTLSOCKET) - target_compile_definitions(cares PRIVATE HAVE_IOCTLSOCKET_FIONBIO) - target_compile_definitions(cares PRIVATE HAVE_ERRNO_H) - target_compile_definitions(cares PRIVATE HAVE_STDLIB_H) - target_compile_definitions(cares PRIVATE HAVE_STRING_H) - target_compile_definitions(cares PRIVATE HAVE_LIMITS_H) - target_compile_definitions(cares PRIVATE HAVE_STDINT_H) - target_compile_definitions(cares PRIVATE _WIN32_WINNT=0x0600) - target_link_libraries(cares PRIVATE ws2_32) - target_link_libraries(cares PRIVATE iphlpapi) - else() - target_compile_options(cares PRIVATE - -Wall - -Wextra - -Wno-unused-parameter - -Wno-sign-conversion - -Wno-sign-compare - -Wno-shadow - -Wno-unused-variable - -Wno-unused-function) - - if(SOURCEMETA_COMPILER_GCC) - target_compile_options(cares PRIVATE -Wno-stringop-overflow -Wno-discarded-qualifiers) - endif() - - if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(cares PRIVATE - -funroll-loops - -fstrict-aliasing - -ftree-vectorize - -fno-math-errno - -fwrapv) - endif() - - set(CARES_TYPEOF_ARES_SOCKLEN_T "socklen_t") - set(CARES_TYPEOF_ARES_SSIZE_T "ssize_t") - set(RECV_TYPE_ARG1 "int") - set(RECV_TYPE_ARG2 "void *") - set(RECV_TYPE_ARG3 "size_t") - set(RECV_TYPE_ARG4 "int") - set(RECVFROM_TYPE_ARG1 "int") - set(RECVFROM_TYPE_ARG2 "void *") - set(RECVFROM_TYPE_ARG3 "size_t") - set(RECVFROM_TYPE_ARG4 "int") - set(RECVFROM_TYPE_ARG5 "struct sockaddr *") - set(RECVFROM_TYPE_ARG6 "socklen_t *") - set(SEND_TYPE_ARG1 "int") - set(SEND_TYPE_ARG2 "const void *") - set(SEND_TYPE_ARG3 "size_t") - set(SEND_TYPE_ARG4 "int") - set(GETHOSTNAME_TYPE_ARG2 "size_t") - set(GETNAMEINFO_TYPE_ARG1 "struct sockaddr *") - set(GETNAMEINFO_TYPE_ARG2 "socklen_t") - set(GETNAMEINFO_TYPE_ARG46 "size_t") - set(GETNAMEINFO_TYPE_ARG7 "int") - - if(NOT APPLE AND NOT CMAKE_SYSTEM_NAME STREQUAL "MSYS") - target_compile_definitions(cares PRIVATE _POSIX_C_SOURCE=199309L) - endif() - - target_compile_definitions(cares PRIVATE HAVE_SYS_TIME_H) - target_compile_definitions(cares PRIVATE HAVE_TIME_H) - target_compile_definitions(cares PRIVATE HAVE_SYS_SELECT_H) - target_compile_definitions(cares PRIVATE HAVE_SYS_TYPES_H) - target_compile_definitions(cares PRIVATE HAVE_STRUCT_TIMEVAL) - target_compile_definitions(cares PRIVATE HAVE_STRUCT_SOCKADDR_IN6) - target_compile_definitions(cares PRIVATE HAVE_STRUCT_ADDRINFO) - target_compile_definitions(cares PRIVATE HAVE_AF_INET6) - target_compile_definitions(cares PRIVATE HAVE_PF_INET6) - target_compile_definitions(cares PRIVATE HAVE_NETDB_H) - target_compile_definitions(cares PRIVATE HAVE_ARPA_INET_H) - target_compile_definitions(cares PRIVATE HAVE_NETINET_IN_H) - target_compile_definitions(cares PRIVATE HAVE_SYS_SOCKET_H) - target_compile_definitions(cares PRIVATE HAVE_UNISTD_H) - target_compile_definitions(cares PRIVATE HAVE_FCNTL_H) - target_compile_definitions(cares PRIVATE HAVE_ERRNO_H) - target_compile_definitions(cares PRIVATE HAVE_STDLIB_H) - target_compile_definitions(cares PRIVATE HAVE_STRING_H) - target_compile_definitions(cares PRIVATE HAVE_SYS_IOCTL_H) - target_compile_definitions(cares PRIVATE HAVE_PTHREAD_H) - target_compile_definitions(cares PRIVATE HAVE_LIMITS_H) - target_compile_definitions(cares PRIVATE HAVE_SYS_UIO_H) - target_compile_definitions(cares PRIVATE HAVE_FCNTL_O_NONBLOCK) - target_compile_definitions(cares PRIVATE HAVE_RECV) - target_compile_definitions(cares PRIVATE HAVE_RECVFROM) - target_compile_definitions(cares PRIVATE HAVE_SEND) - target_compile_definitions(cares PRIVATE HAVE_SENDTO) - target_compile_definitions(cares PRIVATE HAVE_WRITEV) - target_compile_definitions(cares PRIVATE HAVE_GETTIMEOFDAY) - target_compile_definitions(cares PRIVATE HAVE_CLOCK_GETTIME_MONOTONIC) - target_compile_definitions(cares PRIVATE HAVE_STDINT_H) - - if(APPLE) - target_link_libraries(cares PRIVATE "-framework CoreFoundation") - target_link_libraries(cares PRIVATE "-framework SystemConfiguration") - endif() - endif() - - configure_file("${CARES_DIR}/include/ares_build.h.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/cares_generated/ares_build.h" @ONLY) - configure_file("${CARES_DIR}/src/lib/ares_config.h.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/cares_generated/ares_config.h" @ONLY) - - target_compile_definitions(cares PRIVATE HAVE_CONFIG_H) - target_compile_definitions(cares PRIVATE CARES_BUILDING_LIBRARY) - if(NOT BUILD_SHARED_LIBS) - target_compile_definitions(cares PUBLIC CARES_STATICLIB) - endif() - - target_include_directories(cares PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/cares_generated") - target_include_directories(cares PRIVATE "${CARES_DIR}/src/lib") - target_include_directories(cares PRIVATE "${CARES_DIR}/src/lib/include") - target_include_directories(cares PUBLIC - "$" - "$" - "$") - - add_library(c-ares::cares ALIAS cares) - - set_target_properties(cares - PROPERTIES - C_STANDARD 11 - C_STANDARD_REQUIRED ON - C_EXTENSIONS OFF - POSITION_INDEPENDENT_CODE ON - OUTPUT_NAME cares - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - WINDOWS_EXPORT_ALL_SYMBOLS TRUE - EXPORT_NAME cares) - - set(CAres_FOUND ON) -endif() diff --git a/cmake/FindCURL.cmake b/cmake/FindCURL.cmake deleted file mode 100644 index 25a4412ff..000000000 --- a/cmake/FindCURL.cmake +++ /dev/null @@ -1,574 +0,0 @@ -if(NOT CURL_FOUND) - set(CURL_DIR "${PROJECT_SOURCE_DIR}/vendor/curl") - - set(CURL_PUBLIC_HEADER "${CURL_DIR}/include/curl/curl.h") - set(CURL_PRIVATE_HEADERS - "${CURL_DIR}/include/curl/stdcheaders.h" - "${CURL_DIR}/include/curl/header.h" - "${CURL_DIR}/include/curl/options.h" - "${CURL_DIR}/include/curl/mprintf.h" - "${CURL_DIR}/include/curl/easy.h" - "${CURL_DIR}/include/curl/websockets.h" - "${CURL_DIR}/include/curl/curlver.h" - "${CURL_DIR}/include/curl/system.h" - "${CURL_DIR}/include/curl/typecheck-gcc.h" - "${CURL_DIR}/include/curl/multi.h" - "${CURL_DIR}/include/curl/urlapi.h") - - add_library(curl - "${CURL_PUBLIC_HEADER}" ${CURL_PRIVATE_HEADERS} - - "${CURL_DIR}/lib/curl_fopen.c" - "${CURL_DIR}/lib/curl_fopen.h" - "${CURL_DIR}/lib/curlx/fopen.c" - "${CURL_DIR}/lib/curlx/fopen.h" - "${CURL_DIR}/lib/curlx/strerr.c" - "${CURL_DIR}/lib/curlx/strerr.h" - "${CURL_DIR}/lib/multi_ntfy.c" - "${CURL_DIR}/lib/multi_ntfy.h" - "${CURL_DIR}/lib/vtls/apple.c" - "${CURL_DIR}/lib/vtls/apple.h" - "${CURL_DIR}/lib/strcase.c" - "${CURL_DIR}/lib/cf-h2-proxy.h" - "${CURL_DIR}/lib/easyoptions.c" - "${CURL_DIR}/lib/dict.c" - "${CURL_DIR}/lib/llist.c" - "${CURL_DIR}/lib/mprintf.c" - "${CURL_DIR}/lib/pingpong.c" - "${CURL_DIR}/lib/httpsrr.c" - "${CURL_DIR}/lib/socks_gssapi.c" - "${CURL_DIR}/lib/psl.c" - "${CURL_DIR}/lib/progress.h" - "${CURL_DIR}/lib/url.c" - "${CURL_DIR}/lib/easyif.h" - "${CURL_DIR}/lib/curl_md4.h" - "${CURL_DIR}/lib/uint-hash.h" - "${CURL_DIR}/lib/http_aws_sigv4.h" - "${CURL_DIR}/lib/curl_get_line.c" - "${CURL_DIR}/lib/hmac.c" - "${CURL_DIR}/lib/curl_addrinfo.h" - "${CURL_DIR}/lib/md4.c" - "${CURL_DIR}/lib/curl_range.c" - "${CURL_DIR}/lib/uint-table.c" - "${CURL_DIR}/lib/idn.c" - "${CURL_DIR}/lib/multi_ev.c" - "${CURL_DIR}/lib/smtp.h" - "${CURL_DIR}/lib/curl_threads.c" - "${CURL_DIR}/lib/if2ip.c" - "${CURL_DIR}/lib/cf-socket.c" - "${CURL_DIR}/lib/cf-ip-happy.c" - "${CURL_DIR}/lib/uint-bset.h" - "${CURL_DIR}/lib/http_negotiate.c" - "${CURL_DIR}/lib/doh.c" - "${CURL_DIR}/lib/asyn-thrdd.c" - "${CURL_DIR}/lib/curl_endian.c" - "${CURL_DIR}/lib/formdata.c" - "${CURL_DIR}/lib/easygetopt.c" - "${CURL_DIR}/lib/cf-https-connect.c" - "${CURL_DIR}/lib/mime.h" - "${CURL_DIR}/lib/curlx/strdup.h" - "${CURL_DIR}/lib/fileinfo.h" - "${CURL_DIR}/lib/curl_ldap.h" - "${CURL_DIR}/lib/amigaos.h" - "${CURL_DIR}/lib/telnet.h" - "${CURL_DIR}/lib/rand.c" - "${CURL_DIR}/lib/http_chunks.h" - "${CURL_DIR}/lib/cshutdn.c" - "${CURL_DIR}/lib/http2.c" - "${CURL_DIR}/lib/strerror.h" - "${CURL_DIR}/lib/socketpair.h" - "${CURL_DIR}/lib/netrc.h" - "${CURL_DIR}/lib/bufref.h" - "${CURL_DIR}/lib/request.c" - "${CURL_DIR}/lib/dynhds.c" - "${CURL_DIR}/lib/curl_sasl.h" - "${CURL_DIR}/lib/content_encoding.c" - "${CURL_DIR}/lib/curl_ctype.h" - "${CURL_DIR}/lib/hostip.c" - "${CURL_DIR}/lib/curl_sspi.h" - "${CURL_DIR}/lib/http.h" - "${CURL_DIR}/lib/curl_gethostname.h" - "${CURL_DIR}/lib/rtsp.h" - "${CURL_DIR}/lib/splay.h" - "${CURL_DIR}/lib/escape.c" - "${CURL_DIR}/lib/easy.c" - "${CURL_DIR}/lib/ratelimit.c" - "${CURL_DIR}/lib/pop3.h" - "${CURL_DIR}/lib/curl_share.c" - "${CURL_DIR}/lib/slist.c" - "${CURL_DIR}/lib/tftp.c" - "${CURL_DIR}/lib/curl_ntlm_core.h" - "${CURL_DIR}/lib/mqtt.c" - "${CURL_DIR}/lib/curlx/basename.c" - "${CURL_DIR}/lib/curlx/basename.h" - "${CURL_DIR}/lib/noproxy.h" - "${CURL_DIR}/lib/gopher.h" - "${CURL_DIR}/lib/multihandle.h" - "${CURL_DIR}/lib/socks.c" - "${CURL_DIR}/lib/imap.h" - "${CURL_DIR}/lib/parsedate.c" - "${CURL_DIR}/lib/curl_trc.c" - "${CURL_DIR}/lib/hsts.h" - "${CURL_DIR}/lib/cf-haproxy.c" - "${CURL_DIR}/lib/http_digest.h" - "${CURL_DIR}/lib/curl_printf.h" - "${CURL_DIR}/lib/file.h" - "${CURL_DIR}/lib/cfilters.c" - "${CURL_DIR}/lib/ftp.h" - "${CURL_DIR}/lib/cf-h1-proxy.h" - "${CURL_DIR}/lib/smb.h" - "${CURL_DIR}/lib/curl_memrchr.h" - "${CURL_DIR}/lib/conncache.h" - "${CURL_DIR}/lib/altsvc.h" - "${CURL_DIR}/lib/ws.h" - "${CURL_DIR}/lib/curl_sha512_256.c" - "${CURL_DIR}/lib/connect.h" - "${CURL_DIR}/lib/system_win32.c" - "${CURL_DIR}/lib/transfer.c" - "${CURL_DIR}/lib/curl_gssapi.h" - "${CURL_DIR}/lib/select.c" - "${CURL_DIR}/lib/curl_fnmatch.h" - "${CURL_DIR}/lib/getinfo.h" - "${CURL_DIR}/lib/fake_addrinfo.h" - "${CURL_DIR}/lib/hostip4.c" - "${CURL_DIR}/lib/cw-out.h" - "${CURL_DIR}/lib/http1.c" - "${CURL_DIR}/lib/ratelimit.h" - "${CURL_DIR}/lib/urlapi.c" - "${CURL_DIR}/lib/ftplistparser.h" - "${CURL_DIR}/lib/openldap.c" - "${CURL_DIR}/lib/getenv.c" - "${CURL_DIR}/lib/cw-pause.h" - "${CURL_DIR}/lib/setopt.h" - "${CURL_DIR}/lib/hash.c" - "${CURL_DIR}/lib/bufq.c" - "${CURL_DIR}/lib/http_proxy.c" - "${CURL_DIR}/lib/http_ntlm.h" - "${CURL_DIR}/lib/vquic/curl_quiche.h" - "${CURL_DIR}/lib/vquic/vquic.c" - "${CURL_DIR}/lib/vquic/curl_ngtcp2.c" - "${CURL_DIR}/lib/vquic/vquic-tls.c" - "${CURL_DIR}/lib/vquic/curl_quiche.c" - "${CURL_DIR}/lib/vquic/curl_ngtcp2.h" - "${CURL_DIR}/lib/vquic/vquic.h" - "${CURL_DIR}/lib/vquic/vquic-tls.h" - "${CURL_DIR}/lib/vquic/vquic_int.h" - "${CURL_DIR}/lib/cookie.h" - "${CURL_DIR}/lib/uint-spbset.c" - "${CURL_DIR}/lib/macos.h" - "${CURL_DIR}/lib/headers.h" - "${CURL_DIR}/lib/multi.c" - "${CURL_DIR}/lib/asyn-base.c" - "${CURL_DIR}/lib/sendf.h" - "${CURL_DIR}/lib/cf-https-connect.h" - "${CURL_DIR}/lib/formdata.h" - "${CURL_DIR}/lib/urldata.h" - "${CURL_DIR}/lib/multiif.h" - "${CURL_DIR}/lib/curl_endian.h" - "${CURL_DIR}/lib/config-win32.h" - "${CURL_DIR}/lib/curlx/strdup.c" - "${CURL_DIR}/lib/mime.c" - "${CURL_DIR}/lib/uint-bset.c" - "${CURL_DIR}/lib/strequal.c" - "${CURL_DIR}/lib/cf-socket.h" - "${CURL_DIR}/lib/cf-ip-happy.h" - "${CURL_DIR}/lib/if2ip.h" - "${CURL_DIR}/lib/socks_sspi.c" - "${CURL_DIR}/lib/curl_threads.h" - "${CURL_DIR}/lib/smtp.c" - "${CURL_DIR}/lib/multi_ev.h" - "${CURL_DIR}/lib/doh.h" - "${CURL_DIR}/lib/http_negotiate.h" - "${CURL_DIR}/lib/curlx/snprintf.c" - "${CURL_DIR}/lib/curl_get_line.h" - "${CURL_DIR}/lib/http_aws_sigv4.c" - "${CURL_DIR}/lib/sockaddr.h" - "${CURL_DIR}/lib/uint-hash.c" - "${CURL_DIR}/lib/curl_hmac.h" - "${CURL_DIR}/lib/uint-table.h" - "${CURL_DIR}/lib/curl_range.h" - "${CURL_DIR}/lib/idn.h" - "${CURL_DIR}/lib/setup-os400.h" - "${CURL_DIR}/lib/curl_addrinfo.c" - "${CURL_DIR}/lib/curl_setup.h" - "${CURL_DIR}/lib/pingpong.h" - "${CURL_DIR}/lib/llist.h" - "${CURL_DIR}/lib/dict.h" - "${CURL_DIR}/lib/easyoptions.h" - "${CURL_DIR}/lib/strcase.h" - "${CURL_DIR}/lib/cf-h2-proxy.c" - "${CURL_DIR}/lib/url.h" - "${CURL_DIR}/lib/psl.h" - "${CURL_DIR}/lib/memdebug.c" - "${CURL_DIR}/lib/progress.c" - "${CURL_DIR}/lib/httpsrr.h" - "${CURL_DIR}/lib/curl_sha256.h" - "${CURL_DIR}/lib/mqtt.h" - "${CURL_DIR}/lib/curl_ntlm_core.c" - "${CURL_DIR}/lib/tftp.h" - "${CURL_DIR}/lib/slist.h" - "${CURL_DIR}/lib/curl_share.h" - "${CURL_DIR}/lib/pop3.c" - "${CURL_DIR}/lib/arpa_telnet.h" - "${CURL_DIR}/lib/noproxy.c" - "${CURL_DIR}/lib/gopher.c" - "${CURL_DIR}/lib/rtsp.c" - "${CURL_DIR}/lib/curl_gethostname.c" - "${CURL_DIR}/lib/functypes.h" - "${CURL_DIR}/lib/escape.h" - "${CURL_DIR}/lib/setup-win32.h" - "${CURL_DIR}/lib/splay.c" - "${CURL_DIR}/lib/curlx/timeval.c" - "${CURL_DIR}/lib/curlx/winapi.h" - "${CURL_DIR}/lib/curlx/timediff.c" - "${CURL_DIR}/lib/curlx/dynbuf.c" - "${CURL_DIR}/lib/curlx/base64.h" - "${CURL_DIR}/lib/curlx/version_win32.c" - "${CURL_DIR}/lib/curlx/inet_pton.c" - "${CURL_DIR}/lib/curlx/inet_ntop.c" - "${CURL_DIR}/lib/curlx/wait.c" - "${CURL_DIR}/lib/curlx/warnless.c" - "${CURL_DIR}/lib/curlx/multibyte.c" - "${CURL_DIR}/lib/curlx/nonblock.c" - "${CURL_DIR}/lib/curlx/strparse.h" - "${CURL_DIR}/lib/curlx/winapi.c" - "${CURL_DIR}/lib/curlx/timeval.h" - "${CURL_DIR}/lib/curlx/inet_pton.h" - "${CURL_DIR}/lib/curlx/inet_ntop.h" - "${CURL_DIR}/lib/curlx/wait.h" - "${CURL_DIR}/lib/curlx/base64.c" - "${CURL_DIR}/lib/curlx/version_win32.h" - "${CURL_DIR}/lib/curlx/dynbuf.h" - "${CURL_DIR}/lib/curlx/timediff.h" - "${CURL_DIR}/lib/curlx/warnless.h" - "${CURL_DIR}/lib/curlx/strparse.c" - "${CURL_DIR}/lib/curlx/multibyte.h" - "${CURL_DIR}/lib/curlx/nonblock.h" - "${CURL_DIR}/lib/curlx/strcopy.c" - "${CURL_DIR}/lib/curlx/strcopy.h" - "${CURL_DIR}/lib/curlx/snprintf.h" - "${CURL_DIR}/lib/setup-vms.h" - "${CURL_DIR}/lib/hostip.h" - "${CURL_DIR}/lib/content_encoding.h" - "${CURL_DIR}/lib/http.c" - "${CURL_DIR}/lib/curl_sspi.c" - "${CURL_DIR}/lib/http_chunks.c" - "${CURL_DIR}/lib/config-os400.h" - "${CURL_DIR}/lib/rand.h" - "${CURL_DIR}/lib/cshutdn.h" - "${CURL_DIR}/lib/telnet.c" - "${CURL_DIR}/lib/amigaos.c" - "${CURL_DIR}/lib/asyn.h" - "${CURL_DIR}/lib/fileinfo.c" - "${CURL_DIR}/lib/version.c" - "${CURL_DIR}/lib/ldap.c" - "${CURL_DIR}/lib/bufref.c" - "${CURL_DIR}/lib/curl_sasl.c" - "${CURL_DIR}/lib/request.h" - "${CURL_DIR}/lib/dynhds.h" - "${CURL_DIR}/lib/netrc.c" - "${CURL_DIR}/lib/socketpair.c" - "${CURL_DIR}/lib/strerror.c" - "${CURL_DIR}/lib/http2.h" - "${CURL_DIR}/lib/altsvc.c" - "${CURL_DIR}/lib/config-riscos.h" - "${CURL_DIR}/lib/conncache.c" - "${CURL_DIR}/lib/curl_memrchr.c" - "${CURL_DIR}/lib/smb.c" - "${CURL_DIR}/lib/transfer.h" - "${CURL_DIR}/lib/sha256.c" - "${CURL_DIR}/lib/system_win32.h" - "${CURL_DIR}/lib/connect.c" - "${CURL_DIR}/lib/curl_sha512_256.h" - "${CURL_DIR}/lib/ws.c" - "${CURL_DIR}/lib/ftp.c" - "${CURL_DIR}/lib/md5.c" - "${CURL_DIR}/lib/vauth/krb5_sspi.c" - "${CURL_DIR}/lib/vauth/spnego_sspi.c" - "${CURL_DIR}/lib/vauth/ntlm.c" - "${CURL_DIR}/lib/vauth/gsasl.c" - "${CURL_DIR}/lib/vauth/spnego_gssapi.c" - "${CURL_DIR}/lib/vauth/digest.h" - "${CURL_DIR}/lib/vauth/ntlm_sspi.c" - "${CURL_DIR}/lib/vauth/vauth.c" - "${CURL_DIR}/lib/vauth/oauth2.c" - "${CURL_DIR}/lib/vauth/cram.c" - "${CURL_DIR}/lib/vauth/cleartext.c" - "${CURL_DIR}/lib/vauth/krb5_gssapi.c" - "${CURL_DIR}/lib/vauth/digest.c" - "${CURL_DIR}/lib/vauth/digest_sspi.c" - "${CURL_DIR}/lib/vauth/vauth.h" - "${CURL_DIR}/lib/file.c" - "${CURL_DIR}/lib/cfilters.h" - "${CURL_DIR}/lib/http_digest.c" - "${CURL_DIR}/lib/cf-haproxy.h" - "${CURL_DIR}/lib/cf-h1-proxy.c" - "${CURL_DIR}/lib/curl_md5.h" - "${CURL_DIR}/lib/urlapi-int.h" - "${CURL_DIR}/lib/hsts.c" - "${CURL_DIR}/lib/vtls/mbedtls.c" - "${CURL_DIR}/lib/vtls/gtls.c" - "${CURL_DIR}/lib/vtls/vtls.h" - "${CURL_DIR}/lib/vtls/hostcheck.c" - "${CURL_DIR}/lib/vtls/rustls.c" - "${CURL_DIR}/lib/vtls/vtls_spack.h" - "${CURL_DIR}/lib/vtls/schannel.c" - "${CURL_DIR}/lib/vtls/openssl.h" - "${CURL_DIR}/lib/vtls/vtls_scache.c" - "${CURL_DIR}/lib/vtls/keylog.h" - "${CURL_DIR}/lib/vtls/cipher_suite.h" - "${CURL_DIR}/lib/vtls/schannel_verify.c" - "${CURL_DIR}/lib/vtls/x509asn1.h" - "${CURL_DIR}/lib/vtls/vtls.c" - "${CURL_DIR}/lib/vtls/hostcheck.h" - "${CURL_DIR}/lib/vtls/gtls.h" - "${CURL_DIR}/lib/vtls/mbedtls.h" - "${CURL_DIR}/lib/vtls/vtls_int.h" - "${CURL_DIR}/lib/vtls/schannel_int.h" - "${CURL_DIR}/lib/vtls/rustls.h" - "${CURL_DIR}/lib/vtls/cipher_suite.c" - "${CURL_DIR}/lib/vtls/vtls_scache.h" - "${CURL_DIR}/lib/vtls/keylog.c" - "${CURL_DIR}/lib/vtls/openssl.c" - "${CURL_DIR}/lib/vtls/vtls_spack.c" - "${CURL_DIR}/lib/vtls/schannel.h" - "${CURL_DIR}/lib/vtls/x509asn1.c" - "${CURL_DIR}/lib/parsedate.h" - "${CURL_DIR}/lib/curl_trc.h" - "${CURL_DIR}/lib/socks.h" - "${CURL_DIR}/lib/vssh/libssh.c" - "${CURL_DIR}/lib/vssh/libssh2.c" - "${CURL_DIR}/lib/vssh/vssh.h" - "${CURL_DIR}/lib/vssh/ssh.h" - "${CURL_DIR}/lib/vssh/vssh.c" - "${CURL_DIR}/lib/asyn-ares.c" - "${CURL_DIR}/lib/imap.c" - "${CURL_DIR}/lib/headers.c" - "${CURL_DIR}/lib/macos.c" - "${CURL_DIR}/lib/uint-spbset.h" - "${CURL_DIR}/lib/cookie.c" - "${CURL_DIR}/lib/hostip6.c" - "${CURL_DIR}/lib/sendf.c" - "${CURL_DIR}/lib/ftplistparser.c" - "${CURL_DIR}/lib/http_ntlm.c" - "${CURL_DIR}/lib/http_proxy.h" - "${CURL_DIR}/lib/bufq.h" - "${CURL_DIR}/lib/hash.h" - "${CURL_DIR}/lib/config-mac.h" - "${CURL_DIR}/lib/setopt.c" - "${CURL_DIR}/lib/cw-pause.c" - "${CURL_DIR}/lib/easy_lock.h" - "${CURL_DIR}/lib/sigpipe.h" - "${CURL_DIR}/lib/fake_addrinfo.c" - "${CURL_DIR}/lib/getinfo.c" - "${CURL_DIR}/lib/http1.h" - "${CURL_DIR}/lib/cw-out.c" - "${CURL_DIR}/lib/curl_gssapi.c" - "${CURL_DIR}/lib/curl_fnmatch.c" - "${CURL_DIR}/lib/select.h" - "${CURL_DIR}/lib/cf-dns.c" - "${CURL_DIR}/lib/cf-dns.h" - "${CURL_DIR}/lib/dnscache.c" - "${CURL_DIR}/lib/dnscache.h" - "${CURL_DIR}/lib/ftp-int.h" - "${CURL_DIR}/lib/protocol.c" - "${CURL_DIR}/lib/protocol.h" - "${CURL_DIR}/lib/thrdpool.c" - "${CURL_DIR}/lib/thrdpool.h" - "${CURL_DIR}/lib/thrdqueue.c" - "${CURL_DIR}/lib/thrdqueue.h") - - if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(curl PRIVATE /W3 /MP /wd4996 /wd4273 /wd4311 /GS-) - target_compile_definitions(curl PRIVATE _CRT_SECURE_NO_WARNINGS) - target_compile_definitions(curl PUBLIC _SSIZE_T_DEFINED) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - target_compile_definitions(curl PUBLIC "ssize_t=__int64") - else() - target_compile_definitions(curl PUBLIC "ssize_t=int") - endif() - else() - target_compile_options(curl PRIVATE - -Wall - -Wextra - -Wpedantic - -Werror - -Wdouble-promotion - -Wfloat-equal - -Wformat=2 - -Wmissing-declarations - -Wwrite-strings - -Wno-cast-align - -Wno-cast-qual - -Wno-unused-parameter - -Wno-sign-conversion - -Wno-sign-compare - -Wno-enum-conversion - -Wno-implicit-function-declaration - -Wno-int-conversion - -Wno-deprecated-declarations - -Wno-strict-overflow - -Wno-format-nonliteral) - - if(SOURCEMETA_COMPILER_LLVM) - target_compile_options(curl PRIVATE - -Wno-implicit-int-conversion - -Wno-documentation-deprecated-sync - -Wno-conditional-uninitialized) - endif() - - if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(curl PRIVATE - -funroll-loops - -fstrict-aliasing - -ftree-vectorize - -fno-math-errno - -fwrapv) - endif() - endif() - - # Common configuration variables for curl_config.h - set(USE_IPV6 ON) - set(HAVE_LIBZ ON) - set(USE_NGHTTP2 ON) - set(USE_LIBPSL ON) - set(HAVE_LONGLONG ON) - set(HAVE_RECV ON) - set(HAVE_SEND ON) - set(HAVE_SOCKET ON) - set(HAVE_SNPRINTF ON) - set(HAVE_SELECT ON) - set(HAVE_STRUCT_TIMEVAL ON) - set(HAVE_GETSOCKNAME ON) - set(SIZEOF_CURL_OFF_T_CODE "#define SIZEOF_CURL_OFF_T 8") - - if(WIN32) - set(CURL_OS "\"Windows\"") - set(USE_SCHANNEL ON) - set(USE_WINDOWS_SSPI ON) - set(USE_THREADS_WIN32 ON) - set(HAVE_GETADDRINFO ON) - set(HAVE_FREEADDRINFO ON) - set(HAVE_CLOSESOCKET ON) - set(HAVE_IOCTLSOCKET ON) - set(HAVE_IOCTLSOCKET_FIONBIO ON) - set(HAVE_WS2TCPIP_H ON) - set(HAVE_WINSOCK2_H ON) - set(HAVE_WINDOWS_H ON) - set(HAVE_FCNTL_H ON) - set(HAVE_IO_H ON) - target_link_libraries(curl PRIVATE ws2_32) - target_link_libraries(curl PRIVATE Crypt32) - target_link_libraries(curl PRIVATE Secur32) - target_link_libraries(curl PRIVATE Bcrypt) - target_link_libraries(curl PRIVATE Iphlpapi) - elseif(CMAKE_SYSTEM_NAME STREQUAL "MSYS") - set(CURL_OS "\"MSYS\"") - set(CURL_CA_BUNDLE "/usr/ssl/certs/ca-bundle.crt") - set(CURL_CA_PATH "/usr/ssl/certs") - set(USE_MBEDTLS ON) - set(USE_THREADS_POSIX ON) - set(HAVE_POLL ON) - set(HAVE_FCNTL_O_NONBLOCK ON) - set(HAVE_FCNTL_H ON) - set(HAVE_STDINT_H ON) - set(HAVE_NETDB_H ON) - set(HAVE_ARPA_INET_H ON) - set(HAVE_UNISTD_H ON) - set(HAVE_SYS_TYPES_H ON) - set(HAVE_SYS_SOCKET_H ON) - set(HAVE_NETINET_IN_H ON) - set(HAVE_PTHREAD_H ON) - set(HAVE_GETADDRINFO ON) - set(HAVE_GETADDRINFO_THREADSAFE ON) - set(HAVE_FREEADDRINFO ON) - target_compile_definitions(curl PRIVATE _POSIX_C_SOURCE=200809L) - target_compile_definitions(curl PRIVATE HAVE_SYS_TIME_H) - target_compile_definitions(curl PRIVATE HAVE_SYS_STAT_H) - target_link_libraries(curl PRIVATE MbedTLS::mbedtls) - target_link_libraries(curl PRIVATE pthread) - elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(CURL_OS "\"Linux\"") - set(CURL_CA_BUNDLE "/etc/ssl/certs/ca-certificates.crt") - set(CURL_CA_PATH "/etc/ssl/certs") - set(USE_MBEDTLS ON) - set(USE_ARES ON) - set(USE_RESOLV_ARES ON) - set(HAVE_POLL ON) - set(HAVE_FCNTL_O_NONBLOCK ON) - set(HAVE_FCNTL_H ON) - set(HAVE_STDINT_H ON) - set(HAVE_NETDB_H ON) - set(HAVE_ARPA_INET_H ON) - set(HAVE_UNISTD_H ON) - set(HAVE_SYS_TYPES_H ON) - set(HAVE_SYS_SOCKET_H ON) - set(HAVE_NETINET_IN_H ON) - target_compile_definitions(curl PRIVATE _POSIX_C_SOURCE=200809L) - target_compile_definitions(curl PRIVATE HAVE_SYS_TIME_H) - target_compile_definitions(curl PRIVATE HAVE_SYS_STAT_H) - target_link_libraries(curl PRIVATE MbedTLS::mbedtls) - target_link_libraries(curl PRIVATE c-ares::cares) - elseif(APPLE) - set(CURL_OS "\"Darwin\"") - set(CURL_CA_BUNDLE "/etc/ssl/cert.pem") - set(CURL_CA_PATH "/etc/ssl/certs") - set(USE_MBEDTLS ON) - set(USE_ARES ON) - set(USE_RESOLV_ARES ON) - set(HAVE_POLL ON) - set(HAVE_FCNTL_O_NONBLOCK ON) - set(HAVE_FCNTL_H ON) - set(HAVE_NETDB_H ON) - set(HAVE_UNISTD_H ON) - set(HAVE_SYS_TYPES_H ON) - set(HAVE_SYS_SOCKET_H ON) - set(HAVE_NETINET_IN_H ON) - target_link_libraries(curl PRIVATE MbedTLS::mbedtls) - target_link_libraries(curl PRIVATE c-ares::cares) - target_link_libraries(curl PRIVATE "-framework Foundation") - target_link_libraries(curl PRIVATE "-framework SystemConfiguration") - endif() - - # Generate curl_config.h from template - configure_file( - "${CURL_DIR}/lib/curl_config-cmake.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h") - - target_compile_definitions(curl PRIVATE BUILDING_LIBCURL) - target_compile_definitions(curl PRIVATE UNICODE) - target_compile_definitions(curl PRIVATE _UNICODE) - target_compile_definitions(curl PRIVATE HTTP_ONLY) - target_compile_definitions(curl PRIVATE HAVE_CONFIG_H) - - if(NOT BUILD_SHARED_LIBS) - target_compile_definitions(curl PUBLIC CURL_STATICLIB) - endif() - - target_link_libraries(curl PRIVATE ZLIB::ZLIB) - target_link_libraries(curl PRIVATE Nghttp2::nghttp2) - target_link_libraries(curl PRIVATE PSL::psl) - - target_include_directories(curl PRIVATE "${CURL_DIR}/lib") - target_include_directories(curl PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") - target_include_directories(curl PUBLIC - "$" - "$") - - add_library(CURL::libcurl ALIAS curl) - - set_target_properties(curl - PROPERTIES - C_STANDARD 11 - C_STANDARD_REQUIRED ON - C_EXTENSIONS OFF - POSITION_INDEPENDENT_CODE ON - OUTPUT_NAME curl - PUBLIC_HEADER "${CURL_PUBLIC_HEADER}" - PRIVATE_HEADER "${CURL_PRIVATE_HEADERS}" - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - EXPORT_NAME curl) - - set(CURL_FOUND ON) -endif() diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake deleted file mode 100644 index 42f98c36b..000000000 --- a/cmake/FindMbedTLS.cmake +++ /dev/null @@ -1,186 +0,0 @@ -if(NOT MbedTLS_FOUND) - set(MBEDTLS_DIR "${PROJECT_SOURCE_DIR}/vendor/mbedtls") - - set(MBEDTLS_SOURCES - # Crypto library sources - "${MBEDTLS_DIR}/library/aes.c" - "${MBEDTLS_DIR}/library/aesni.c" - "${MBEDTLS_DIR}/library/aesce.c" - "${MBEDTLS_DIR}/library/aria.c" - "${MBEDTLS_DIR}/library/asn1parse.c" - "${MBEDTLS_DIR}/library/asn1write.c" - "${MBEDTLS_DIR}/library/base64.c" - "${MBEDTLS_DIR}/library/bignum.c" - "${MBEDTLS_DIR}/library/bignum_core.c" - "${MBEDTLS_DIR}/library/bignum_mod.c" - "${MBEDTLS_DIR}/library/bignum_mod_raw.c" - "${MBEDTLS_DIR}/library/block_cipher.c" - "${MBEDTLS_DIR}/library/camellia.c" - "${MBEDTLS_DIR}/library/ccm.c" - "${MBEDTLS_DIR}/library/chacha20.c" - "${MBEDTLS_DIR}/library/chachapoly.c" - "${MBEDTLS_DIR}/library/cipher.c" - "${MBEDTLS_DIR}/library/cipher_wrap.c" - "${MBEDTLS_DIR}/library/constant_time.c" - "${MBEDTLS_DIR}/library/cmac.c" - "${MBEDTLS_DIR}/library/ctr_drbg.c" - "${MBEDTLS_DIR}/library/des.c" - "${MBEDTLS_DIR}/library/dhm.c" - "${MBEDTLS_DIR}/library/ecdh.c" - "${MBEDTLS_DIR}/library/ecdsa.c" - "${MBEDTLS_DIR}/library/ecjpake.c" - "${MBEDTLS_DIR}/library/ecp.c" - "${MBEDTLS_DIR}/library/ecp_curves.c" - "${MBEDTLS_DIR}/library/ecp_curves_new.c" - "${MBEDTLS_DIR}/library/entropy.c" - "${MBEDTLS_DIR}/library/entropy_poll.c" - "${MBEDTLS_DIR}/library/error.c" - "${MBEDTLS_DIR}/library/gcm.c" - "${MBEDTLS_DIR}/library/hkdf.c" - "${MBEDTLS_DIR}/library/hmac_drbg.c" - "${MBEDTLS_DIR}/library/lmots.c" - "${MBEDTLS_DIR}/library/lms.c" - "${MBEDTLS_DIR}/library/md.c" - "${MBEDTLS_DIR}/library/md5.c" - "${MBEDTLS_DIR}/library/memory_buffer_alloc.c" - "${MBEDTLS_DIR}/library/nist_kw.c" - "${MBEDTLS_DIR}/library/oid.c" - "${MBEDTLS_DIR}/library/padlock.c" - "${MBEDTLS_DIR}/library/pem.c" - "${MBEDTLS_DIR}/library/pk.c" - "${MBEDTLS_DIR}/library/pk_ecc.c" - "${MBEDTLS_DIR}/library/pk_wrap.c" - "${MBEDTLS_DIR}/library/pkcs12.c" - "${MBEDTLS_DIR}/library/pkcs5.c" - "${MBEDTLS_DIR}/library/pkparse.c" - "${MBEDTLS_DIR}/library/pkwrite.c" - "${MBEDTLS_DIR}/library/platform.c" - "${MBEDTLS_DIR}/library/platform_util.c" - "${MBEDTLS_DIR}/library/poly1305.c" - "${MBEDTLS_DIR}/library/psa_crypto.c" - "${MBEDTLS_DIR}/library/psa_crypto_aead.c" - "${MBEDTLS_DIR}/library/psa_crypto_cipher.c" - "${MBEDTLS_DIR}/library/psa_crypto_client.c" - "${MBEDTLS_DIR}/library/psa_crypto_driver_wrappers_no_static.c" - "${MBEDTLS_DIR}/library/psa_crypto_ecp.c" - "${MBEDTLS_DIR}/library/psa_crypto_ffdh.c" - "${MBEDTLS_DIR}/library/psa_crypto_hash.c" - "${MBEDTLS_DIR}/library/psa_crypto_mac.c" - "${MBEDTLS_DIR}/library/psa_crypto_pake.c" - "${MBEDTLS_DIR}/library/psa_crypto_random.c" - "${MBEDTLS_DIR}/library/psa_crypto_rsa.c" - "${MBEDTLS_DIR}/library/psa_crypto_se.c" - "${MBEDTLS_DIR}/library/psa_crypto_slot_management.c" - "${MBEDTLS_DIR}/library/psa_crypto_storage.c" - "${MBEDTLS_DIR}/library/psa_its_file.c" - "${MBEDTLS_DIR}/library/psa_util.c" - "${MBEDTLS_DIR}/library/ripemd160.c" - "${MBEDTLS_DIR}/library/rsa.c" - "${MBEDTLS_DIR}/library/rsa_alt_helpers.c" - "${MBEDTLS_DIR}/library/sha1.c" - "${MBEDTLS_DIR}/library/sha256.c" - "${MBEDTLS_DIR}/library/sha512.c" - "${MBEDTLS_DIR}/library/sha3.c" - "${MBEDTLS_DIR}/library/threading.c" - "${MBEDTLS_DIR}/library/threading_internal.h" - "${MBEDTLS_DIR}/library/timing.c" - "${MBEDTLS_DIR}/library/version.c" - "${MBEDTLS_DIR}/library/version_features.c" - # X509 library sources - "${MBEDTLS_DIR}/library/pkcs7.c" - "${MBEDTLS_DIR}/library/x509.c" - "${MBEDTLS_DIR}/library/x509_create.c" - "${MBEDTLS_DIR}/library/x509_crl.c" - "${MBEDTLS_DIR}/library/x509_crt.c" - "${MBEDTLS_DIR}/library/x509_csr.c" - "${MBEDTLS_DIR}/library/x509write.c" - "${MBEDTLS_DIR}/library/x509write_crt.c" - "${MBEDTLS_DIR}/library/x509write_csr.c" - # TLS library sources - "${MBEDTLS_DIR}/library/debug.c" - "${MBEDTLS_DIR}/library/mps_reader.c" - "${MBEDTLS_DIR}/library/mps_trace.c" - "${MBEDTLS_DIR}/library/net_sockets.c" - "${MBEDTLS_DIR}/library/ssl_cache.c" - "${MBEDTLS_DIR}/library/ssl_ciphersuites.c" - "${MBEDTLS_DIR}/library/ssl_client.c" - "${MBEDTLS_DIR}/library/ssl_cookie.c" - "${MBEDTLS_DIR}/library/ssl_debug_helpers_generated.c" - "${MBEDTLS_DIR}/library/ssl_msg.c" - "${MBEDTLS_DIR}/library/ssl_ticket.c" - "${MBEDTLS_DIR}/library/ssl_tls.c" - "${MBEDTLS_DIR}/library/ssl_tls12_client.c" - "${MBEDTLS_DIR}/library/ssl_tls12_server.c" - "${MBEDTLS_DIR}/library/ssl_tls13_keys.c" - "${MBEDTLS_DIR}/library/ssl_tls13_server.c" - "${MBEDTLS_DIR}/library/ssl_tls13_client.c" - "${MBEDTLS_DIR}/library/ssl_tls13_generic.c") - - if(WIN32) - add_library(mbedtls STATIC ${MBEDTLS_SOURCES}) - else() - add_library(mbedtls ${MBEDTLS_SOURCES}) - endif() - - if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(mbedtls PRIVATE - /W3 /MP /wd4244 /wd4267 /wd4996 /wd4146) - target_compile_definitions(mbedtls PRIVATE _CRT_SECURE_NO_WARNINGS) - else() - target_compile_options(mbedtls PRIVATE - -Wall - -Wextra - -Wpedantic - -Werror - -Wno-error=array-bounds - -Wdouble-promotion - -Wfloat-equal - -Wformat=2 - -Wmissing-declarations - -Wwrite-strings - -Wno-cast-align - -Wno-cast-qual - -Wno-unused-parameter - -Wno-sign-conversion - -Wno-implicit-int-conversion - -Wno-sign-compare - -Wno-shadow - -Wno-conditional-uninitialized - -Wno-documentation-deprecated-sync - -Wno-strict-overflow) - - if(SOURCEMETA_COMPILER_GCC) - target_compile_options(mbedtls PRIVATE -Wno-stringop-overflow) - endif() - - if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(mbedtls PRIVATE - -funroll-loops - -fstrict-aliasing - -ftree-vectorize - -fno-math-errno - -fwrapv) - endif() - endif() - - target_include_directories(mbedtls PRIVATE "${MBEDTLS_DIR}/library") - target_include_directories(mbedtls PUBLIC - "$" - "$") - - add_library(MbedTLS::mbedtls ALIAS mbedtls) - - set_target_properties(mbedtls - PROPERTIES - C_STANDARD 11 - C_STANDARD_REQUIRED ON - C_EXTENSIONS OFF - POSITION_INDEPENDENT_CODE ON - OUTPUT_NAME mbedtls - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - WINDOWS_EXPORT_ALL_SYMBOLS TRUE - EXPORT_NAME mbedtls) - - set(MbedTLS_FOUND ON) -endif() diff --git a/cmake/FindNghttp2.cmake b/cmake/FindNghttp2.cmake deleted file mode 100644 index 65f917c6f..000000000 --- a/cmake/FindNghttp2.cmake +++ /dev/null @@ -1,126 +0,0 @@ -if(NOT Nghttp2_FOUND) - set(NGHTTP2_DIR "${PROJECT_SOURCE_DIR}/vendor/nghttp2") - - file(STRINGS "${PROJECT_SOURCE_DIR}/DEPENDENCIES" NGHTTP2_VERSION_LINE - REGEX "^nghttp2 ") - if(NGHTTP2_VERSION_LINE) - string(REGEX MATCH "v?([0-9]+)\\.([0-9]+)\\.([0-9]+)" NGHTTP2_VERSION_MATCH "${NGHTTP2_VERSION_LINE}") - set(NGHTTP2_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(NGHTTP2_VERSION_MINOR "${CMAKE_MATCH_2}") - set(NGHTTP2_VERSION_PATCH "${CMAKE_MATCH_3}") - set(NGHTTP2_VERSION_STRING "${NGHTTP2_VERSION_MAJOR}.${NGHTTP2_VERSION_MINOR}.${NGHTTP2_VERSION_PATCH}") - math(EXPR NGHTTP2_VERSION_NUM - "(${NGHTTP2_VERSION_MAJOR} << 16) | (${NGHTTP2_VERSION_MINOR} << 8) | ${NGHTTP2_VERSION_PATCH}" - OUTPUT_FORMAT HEXADECIMAL) - else() - message(FATAL_ERROR "Could not find nghttp2 version in DEPENDENCIES") - endif() - - set(NGHTTP2_PUBLIC_HEADER "${NGHTTP2_DIR}/lib/includes/nghttp2/nghttp2.h") - - set(NGHTTP2_SOURCES - "${NGHTTP2_DIR}/lib/nghttp2_alpn.c" - "${NGHTTP2_DIR}/lib/nghttp2_buf.c" - "${NGHTTP2_DIR}/lib/nghttp2_callbacks.c" - "${NGHTTP2_DIR}/lib/nghttp2_debug.c" - "${NGHTTP2_DIR}/lib/nghttp2_extpri.c" - "${NGHTTP2_DIR}/lib/nghttp2_frame.c" - "${NGHTTP2_DIR}/lib/nghttp2_hd.c" - "${NGHTTP2_DIR}/lib/nghttp2_hd_huffman.c" - "${NGHTTP2_DIR}/lib/nghttp2_hd_huffman_data.c" - "${NGHTTP2_DIR}/lib/nghttp2_helper.c" - "${NGHTTP2_DIR}/lib/nghttp2_http.c" - "${NGHTTP2_DIR}/lib/nghttp2_map.c" - "${NGHTTP2_DIR}/lib/nghttp2_mem.c" - "${NGHTTP2_DIR}/lib/nghttp2_option.c" - "${NGHTTP2_DIR}/lib/nghttp2_outbound_item.c" - "${NGHTTP2_DIR}/lib/nghttp2_pq.c" - "${NGHTTP2_DIR}/lib/nghttp2_priority_spec.c" - "${NGHTTP2_DIR}/lib/nghttp2_queue.c" - "${NGHTTP2_DIR}/lib/nghttp2_ratelim.c" - "${NGHTTP2_DIR}/lib/nghttp2_rcbuf.c" - "${NGHTTP2_DIR}/lib/nghttp2_session.c" - "${NGHTTP2_DIR}/lib/nghttp2_stream.c" - "${NGHTTP2_DIR}/lib/nghttp2_submit.c" - "${NGHTTP2_DIR}/lib/nghttp2_time.c" - "${NGHTTP2_DIR}/lib/nghttp2_version.c" - "${NGHTTP2_DIR}/lib/sfparse.c") - - add_library(nghttp2 ${NGHTTP2_SOURCES}) - - if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(nghttp2 PRIVATE - /W3 /wd4996 /wd4334 /MP /Zc:inline- /GS-) - target_compile_definitions(nghttp2 PRIVATE _CRT_SECURE_NO_WARNINGS) - # Define ssize_t for MSVC using the same approach as curl's config-win32.h - # This ensures compatibility between nghttp2 and curl - target_compile_definitions(nghttp2 PUBLIC _SSIZE_T_DEFINED) - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - target_compile_definitions(nghttp2 PUBLIC "ssize_t=__int64") - else() - target_compile_definitions(nghttp2 PUBLIC "ssize_t=int") - endif() - else() - target_compile_options(nghttp2 PRIVATE - -Wall - -Wextra - -Wpedantic - -Werror - -Wdouble-promotion - -Wfloat-equal - -Wmissing-declarations - -Wwrite-strings - -Wno-cast-align - -Wno-cast-qual - -Wno-format-nonliteral - -Wno-unused-parameter - -Wno-sign-conversion - -Wno-implicit-int-conversion - -Wno-sign-compare - -Wno-shadow - -Wno-implicit-function-declaration - -Wno-strict-overflow) - - if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(nghttp2 PRIVATE - -funroll-loops - -fstrict-aliasing - -ftree-vectorize - -fno-math-errno - -fwrapv) - endif() - endif() - - set(PACKAGE_VERSION "${NGHTTP2_VERSION_STRING}") - set(PACKAGE_VERSION_NUM "${NGHTTP2_VERSION_NUM}") - configure_file("${NGHTTP2_DIR}/lib/includes/nghttp2/nghttp2ver.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/nghttp2_generated/nghttp2/nghttp2ver.h" @ONLY) - - target_compile_definitions(nghttp2 PRIVATE BUILDING_NGHTTP2) - target_compile_definitions(nghttp2 PRIVATE NGHTTP2_STATICLIB) - if(NOT BUILD_SHARED_LIBS) - target_compile_definitions(nghttp2 PUBLIC NGHTTP2_STATICLIB) - endif() - - target_include_directories(nghttp2 PRIVATE "${NGHTTP2_DIR}/lib") - target_include_directories(nghttp2 PUBLIC - "$" - "$" - "$") - - add_library(Nghttp2::nghttp2 ALIAS nghttp2) - - set_target_properties(nghttp2 - PROPERTIES - C_STANDARD 11 - C_STANDARD_REQUIRED ON - C_EXTENSIONS OFF - POSITION_INDEPENDENT_CODE ON - OUTPUT_NAME nghttp2 - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - WINDOWS_EXPORT_ALL_SYMBOLS TRUE - EXPORT_NAME nghttp2) - - set(Nghttp2_FOUND ON) -endif() diff --git a/cmake/FindPSL.cmake b/cmake/FindPSL.cmake deleted file mode 100644 index 97159fbf9..000000000 --- a/cmake/FindPSL.cmake +++ /dev/null @@ -1,90 +0,0 @@ -if(NOT PSL_FOUND) - set(LIBPSL_DIR "${PROJECT_SOURCE_DIR}/vendor/libpsl") - - file(STRINGS "${LIBPSL_DIR}/version.txt" LIBPSL_VERSION_LINE LIMIT_COUNT 1) - if(LIBPSL_VERSION_LINE) - string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" LIBPSL_VERSION_MATCH "${LIBPSL_VERSION_LINE}") - set(LIBPSL_VERSION_MAJOR "${CMAKE_MATCH_1}") - set(LIBPSL_VERSION_MINOR "${CMAKE_MATCH_2}") - set(LIBPSL_VERSION_PATCH "${CMAKE_MATCH_3}") - set(LIBPSL_VERSION_STRING "${LIBPSL_VERSION_MAJOR}.${LIBPSL_VERSION_MINOR}.${LIBPSL_VERSION_PATCH}") - math(EXPR LIBPSL_VERSION_NUMBER - "(${LIBPSL_VERSION_MAJOR} << 16) | (${LIBPSL_VERSION_MINOR} << 8) | ${LIBPSL_VERSION_PATCH}" - OUTPUT_FORMAT HEXADECIMAL) - else() - message(FATAL_ERROR "Could not find libpsl version in version.txt") - endif() - - set(LIBPSL_PUBLIC_HEADERS - "${CMAKE_CURRENT_BINARY_DIR}/libpsl_generated/libpsl.h") - - set(LIBPSL_SOURCES - "${LIBPSL_DIR}/src/psl.c" - "${LIBPSL_DIR}/src/lookup_string_in_fixed_set.c") - - add_library(psl ${LIBPSL_SOURCES}) - - if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(psl PRIVATE /W3 /wd4996 /wd4267 /wd4244 /MP) - target_compile_definitions(psl PRIVATE _CRT_SECURE_NO_WARNINGS) - else() - target_compile_options(psl PRIVATE - -Wall - -Wextra - -Wno-unused-parameter - -Wno-sign-conversion - -Wno-sign-compare - -Wno-shadow - -Wno-unused-variable - -Wno-unused-function - -Wno-char-subscripts) - - if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(psl PRIVATE - -funroll-loops - -fstrict-aliasing - -ftree-vectorize - -fno-math-errno - -fwrapv) - endif() - endif() - - configure_file("${LIBPSL_DIR}/include/libpsl.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/libpsl_generated/libpsl.h" @ONLY) - - target_compile_definitions(psl PRIVATE BUILDING_PSL) - target_compile_definitions(psl PRIVATE "PACKAGE_VERSION=\"${LIBPSL_VERSION_STRING}\"") - if(NOT BUILD_SHARED_LIBS) - target_compile_definitions(psl PUBLIC PSL_STATIC) - endif() - - if(UNIX) - target_compile_definitions(psl PRIVATE HAVE_VISIBILITY) - target_compile_definitions(psl PRIVATE _GNU_SOURCE) - endif() - - target_include_directories(psl PRIVATE "${LIBPSL_DIR}/src") - target_include_directories(psl PUBLIC - "$" - "$") - - if(WIN32) - target_link_libraries(psl PRIVATE ws2_32) - endif() - - add_library(PSL::psl ALIAS psl) - - set_target_properties(psl - PROPERTIES - C_STANDARD 11 - C_STANDARD_REQUIRED ON - C_EXTENSIONS OFF - POSITION_INDEPENDENT_CODE ON - OUTPUT_NAME psl - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - WINDOWS_EXPORT_ALL_SYMBOLS TRUE - EXPORT_NAME psl) - - set(PSL_FOUND ON) -endif() diff --git a/cmake/FindZLIB.cmake b/cmake/FindZLIB.cmake deleted file mode 100644 index de335c216..000000000 --- a/cmake/FindZLIB.cmake +++ /dev/null @@ -1,126 +0,0 @@ -if(NOT ZLIB_FOUND) - set(ZLIB_DIR "${PROJECT_SOURCE_DIR}/vendor/zlib") - set(ZLIB_PUBLIC_HEADER "${ZLIB_DIR}/zlib.h") - set(ZLIB_PRIVATE_HEADERS "${ZLIB_DIR}/zconf.h") - - add_library(zlib - "${ZLIB_PUBLIC_HEADER}" ${ZLIB_PRIVATE_HEADERS} - "${ZLIB_DIR}/adler32.c" - "${ZLIB_DIR}/compress.c" - "${ZLIB_DIR}/crc32.c" - "${ZLIB_DIR}/crc32.h" - "${ZLIB_DIR}/deflate.c" - "${ZLIB_DIR}/deflate.h" - "${ZLIB_DIR}/gzclose.c" - "${ZLIB_DIR}/gzguts.h" - "${ZLIB_DIR}/gzlib.c" - "${ZLIB_DIR}/gzread.c" - "${ZLIB_DIR}/gzwrite.c" - "${ZLIB_DIR}/infback.c" - "${ZLIB_DIR}/inffast.c" - "${ZLIB_DIR}/inffast.h" - "${ZLIB_DIR}/inffixed.h" - "${ZLIB_DIR}/inflate.c" - "${ZLIB_DIR}/inflate.h" - "${ZLIB_DIR}/inftrees.c" - "${ZLIB_DIR}/inftrees.h" - "${ZLIB_DIR}/trees.c" - "${ZLIB_DIR}/trees.h" - "${ZLIB_DIR}/uncompr.c" - "${ZLIB_DIR}/zutil.c" - "${ZLIB_DIR}/zutil.h") - - target_compile_definitions(zlib PUBLIC NO_FSEEKO) - target_compile_definitions(zlib PUBLIC _LARGEFILE64_SOURCE=1) - - if(SOURCEMETA_COMPILER_MSVC) - target_compile_options(zlib PRIVATE /W3 /MP /wd4996) - target_compile_definitions(zlib PRIVATE _CRT_SECURE_NO_WARNINGS) - else() - target_compile_options(zlib PRIVATE - -Wall - -Wextra - -Wpedantic - -Werror - -Wdouble-promotion - -Wfloat-equal - -Wmissing-declarations - -Wshadow - -Wwrite-strings - -Wno-cast-align - -Wno-cast-qual - -Wno-format-nonliteral - -Wno-sign-conversion - -Wno-shorten-64-to-32 - -Wno-implicit-int-conversion - -Wno-comma - -Wno-implicit-fallthrough) - - if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(zlib PRIVATE - -funroll-loops - -fstrict-aliasing - -ftree-vectorize - -fno-math-errno - -fwrapv) - endif() - - # Disable LTO for zlib to work around GCC LTO linker plugin not - # properly rescanning this archive for transitive dependencies - if(SOURCEMETA_COMPILER_GCC) - target_compile_options(zlib PRIVATE -fno-lto) - endif() - endif() - - target_include_directories(zlib PUBLIC - "$" - "$") - - add_library(ZLIB::ZLIB ALIAS zlib) - - set_target_properties(zlib - PROPERTIES - OUTPUT_NAME zlib - PUBLIC_HEADER "${ZLIB_PUBLIC_HEADER}" - PRIVATE_HEADER "${ZLIB_PRIVATE_HEADERS}" - C_STANDARD 11 - C_STANDARD_REQUIRED ON - C_EXTENSIONS OFF - POSITION_INDEPENDENT_CODE ON - C_VISIBILITY_PRESET "default" - C_VISIBILITY_INLINES_HIDDEN FALSE - VISIBILITY_INLINES_HIDDEN OFF - WINDOWS_EXPORT_ALL_SYMBOLS TRUE - EXPORT_NAME ZLIB) - - if(SOURCEMETA_CORE_INSTALL) - include(GNUInstallDirs) - install(TARGETS zlib - EXPORT zlib - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT sourcemeta_core_dev - PRIVATE_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - COMPONENT sourcemeta_core_dev - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - COMPONENT sourcemeta_core - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core - NAMELINK_COMPONENT sourcemeta_core_dev - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - COMPONENT sourcemeta_core_dev) - install(EXPORT zlib - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/zlib" - NAMESPACE ZLIB:: - COMPONENT sourcemeta_core_dev) - - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/zlib-config.cmake - "include(\"\${CMAKE_CURRENT_LIST_DIR}/zlib.cmake\")\n" - "check_required_components(\"zlib\")\n") - install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/zlib-config.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/zlib" - COMPONENT sourcemeta_core_dev) - endif() - - set(ZLIB_FOUND ON) -endif() diff --git a/patches/curl/0001-fix-schannel-alpn-init-order.patch b/patches/curl/0001-fix-schannel-alpn-init-order.patch deleted file mode 100644 index 22aba45a3..000000000 --- a/patches/curl/0001-fix-schannel-alpn-init-order.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Juan Cruz Viotti -Date: Thu, 13 Mar 2026 00:00:00 +0000 -Subject: [PATCH] Fix Schannel ALPN init order on Windows - -Curl_ssl_init() is called before Curl_win32_init() in global_init(). -The new curlx_verify_windows_version() requires curlx_verify_windows_init() -to be called first (from Curl_win32_init), but schannel_init() (called via -Curl_ssl_init) uses curlx_verify_windows_version() to check ALPN support. -Without the init, it falls back to VerifyVersionInfoW which lies about the -OS version on Windows 10+ without a compatibility manifest, causing the -ALPN check for >= 6.3 to fail and disabling HTTP/2. - -Move Curl_win32_init() before Curl_ssl_init() so the version function -pointer is set up before Schannel needs it. ---- - lib/easy.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/lib/easy.c b/lib/easy.c -index d05674e..a74d1da 100644 ---- a/lib/easy.c -+++ b/lib/easy.c -@@ -140,6 +140,11 @@ static CURLcode global_init(long flags, bool memoryfuncs) - goto fail; - } - -+ if(Curl_win32_init(flags)) { -+ DEBUGF(curl_mfprintf(stderr, "Error: win32_init failed\n")); -+ goto fail; -+ } -+ - if(!Curl_ssl_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_ssl_init failed\n")); - goto fail; -@@ -150,11 +155,6 @@ static CURLcode global_init(long flags, bool memoryfuncs) - goto fail; - } - -- if(Curl_win32_init(flags)) { -- DEBUGF(curl_mfprintf(stderr, "Error: win32_init failed\n")); -- goto fail; -- } -- - if(Curl_amiga_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_amiga_init failed\n")); - goto fail; --- -2.47.1 diff --git a/src/error.h b/src/error.h index 91e5a4712..0fe80176f 100644 --- a/src/error.h +++ b/src/error.h @@ -28,6 +28,7 @@ #include // std::vector #include "exit_code.h" +#include "http.h" // sourcemeta::jsonschema::HTTPDynamicBackendNotFound namespace sourcemeta::jsonschema { @@ -684,6 +685,39 @@ inline auto print_exception(const bool is_json, const Exception &exception) } } + if constexpr (requires(const Exception ¤t) { + { + current.variable() + } -> std::convertible_to; + }) { + if (is_json) { + error_json.assign("environmentVariable", + sourcemeta::core::JSON{exception.variable()}); + } else { + std::cerr << " with environment variable " << exception.variable() + << "\n"; + } + } + + if constexpr (requires(const Exception ¤t) { + { + current.paths() + } -> std::convertible_to &>; + }) { + if (is_json) { + auto paths_array{sourcemeta::core::JSON::make_array()}; + for (const auto &path : exception.paths()) { + paths_array.push_back(sourcemeta::core::JSON{path}); + } + error_json.assign("paths", std::move(paths_array)); + } else { + std::cerr << " with paths\n"; + for (const auto &path : exception.paths()) { + std::cerr << " - " << path << "\n"; + } + } + } + if (is_json) { sourcemeta::core::prettify(error_json, std::cout); std::cout << "\n"; @@ -1065,6 +1099,10 @@ inline auto try_catch(const sourcemeta::core::Options &options, const auto is_json{options.contains("json")}; print_exception(is_json, error); return EXIT_UNEXPECTED_ERROR; + } catch (const sourcemeta::jsonschema::HTTPDynamicBackendNotFound &error) { + const auto is_json{options.contains("json")}; + print_exception(is_json, error); + return EXIT_NOT_SUPPORTED; // Standard library handlers } catch (const sourcemeta::core::IOFileNotFoundError &error) { diff --git a/src/http/CMakeLists.txt b/src/http/CMakeLists.txt index 00482c829..64e1d32d0 100644 --- a/src/http/CMakeLists.txt +++ b/src/http/CMakeLists.txt @@ -1,6 +1,3 @@ -# On Apple and Windows platforms, HTTP requests are served by the -# operating system networking stack. Everywhere else, they go through -# cURL (by default vendored alongside its dependencies) if(APPLE) add_library(jsonschema_http STATIC http.h http_darwin.mm) set_source_files_properties(http_darwin.mm @@ -12,23 +9,14 @@ elseif(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "MSYS") target_link_libraries(jsonschema_http PRIVATE winhttp) target_link_libraries(jsonschema_http PRIVATE sourcemeta::core::unicode) else() + add_library(jsonschema_http STATIC http.h http_curl.cc) if(JSONSCHEMA_USE_SYSTEM_CURL) - list(REMOVE_ITEM CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") find_package(CURL REQUIRED) - list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") + target_compile_definitions(jsonschema_http PRIVATE JSONSCHEMA_USE_SYSTEM_CURL) + target_link_libraries(jsonschema_http PRIVATE CURL::libcurl) else() - find_package(MbedTLS REQUIRED) - find_package(Nghttp2 REQUIRED) - if(NOT CMAKE_SYSTEM_NAME STREQUAL "MSYS") - find_package(CAres REQUIRED) - endif() - find_package(PSL REQUIRED) - find_package(ZLIB REQUIRED) - find_package(CURL REQUIRED) + target_link_libraries(jsonschema_http PRIVATE ${CMAKE_DL_LIBS}) endif() - - add_library(jsonschema_http STATIC http.h http_curl.cc) - target_link_libraries(jsonschema_http PRIVATE CURL::libcurl) endif() sourcemeta_add_default_options(PRIVATE jsonschema_http) diff --git a/src/http/http.h b/src/http/http.h index 929298c63..c4c6aed5e 100644 --- a/src/http/http.h +++ b/src/http/http.h @@ -4,6 +4,7 @@ #include #include // std::size_t +#include // std::exception #include // std::optional #include // std::string #include // std::string_view @@ -48,6 +49,32 @@ struct HTTPResponse { std::string body; }; +class HTTPDynamicBackendNotFound : public std::exception { +public: + HTTPDynamicBackendNotFound(std::string message, std::string variable, + std::vector paths) + : message_{std::move(message)}, variable_{std::move(variable)}, + paths_{std::move(paths)} {} + + [[nodiscard]] auto what() const noexcept -> const char * override { + return this->message_.c_str(); + } + + [[nodiscard]] auto variable() const noexcept -> const std::string & { + return this->variable_; + } + + [[nodiscard]] auto paths() const noexcept + -> const std::vector & { + return this->paths_; + } + +private: + std::string message_; + std::string variable_; + std::vector paths_; +}; + // Perform an HTTP request, following redirects. This function is // implemented on top of NSURLSession on Apple platforms, WinHTTP on // Windows, and cURL everywhere else. Failures to obtain a response are diff --git a/src/http/http_curl.cc b/src/http/http_curl.cc index 4d173659e..93d3cd12e 100644 --- a/src/http/http_curl.cc +++ b/src/http/http_curl.cc @@ -1,6 +1,8 @@ #include "http.h" -#include // curl_easy_*, curl_slist_*, curl_global_init +#ifdef JSONSCHEMA_USE_SYSTEM_CURL +#include // curl_easy_*, curl_slist_*, curl_global_init, CURLOPT_* +#endif #include // std::size_t #include // std::uint16_t @@ -8,14 +10,95 @@ #include // std::string #include // std::string_view +#ifndef JSONSCHEMA_USE_SYSTEM_CURL +#include // dlopen, dlsym, dlerror, RTLD_NOW + +#include // std::array +#include // std::getenv +#include // std::memcpy +#include // std::vector + +// When cURL is not linked at build time, we load it at runtime via dlopen +// and therefore need no curl headers. The following reproduces the small +// subset of libcurl's C API this backend uses. Every type, prototype, and +// option id is part of libcurl's frozen ABI (SONAME libcurl.so.4, stable +// since 2006), so these values never change. The prototypes are never +// called directly (we invoke them through dlsym'd pointers) nor linked; +// they exist only so the shared CurlApi table can derive their types +extern "C" { + +using CURL = void; +using CURLcode = int; +using CURLoption = int; +using CURLINFO = int; +using curl_off_t = long long; + +struct curl_slist; + +auto curl_global_init(long flags) -> CURLcode; +auto curl_easy_init() -> CURL *; +auto curl_easy_cleanup(CURL *handle) -> void; +auto curl_easy_setopt(CURL *handle, CURLoption option, ...) -> CURLcode; +auto curl_easy_perform(CURL *handle) -> CURLcode; +auto curl_easy_getinfo(CURL *handle, CURLINFO info, ...) -> CURLcode; +auto curl_easy_strerror(CURLcode code) -> const char *; +auto curl_slist_append(curl_slist *list, const char *value) -> curl_slist *; +auto curl_slist_free_all(curl_slist *list) -> void; + +} // extern "C" + +// Option ids are a type-class base plus an index in libcurl's headers; the +// resolved values are reproduced here (see the trailing comments) +constexpr CURLcode CURLE_OK{0}; +constexpr long CURL_GLOBAL_ALL{3}; // SSL(1<<0) | WIN32(1<<1) +constexpr CURLoption CURLOPT_URL{10002}; // STRINGPOINT + 2 +constexpr CURLoption CURLOPT_FOLLOWLOCATION{52}; // LONG + 52 +constexpr CURLoption CURLOPT_NOSIGNAL{99}; // LONG + 99 +constexpr CURLoption CURLOPT_ACCEPT_ENCODING{10102}; // STRINGPOINT + 102 +constexpr CURLoption CURLOPT_WRITEFUNCTION{20011}; // FUNCTIONPOINT + 11 +constexpr CURLoption CURLOPT_WRITEDATA{10001}; // CBPOINT + 1 +constexpr CURLoption CURLOPT_HEADERFUNCTION{20079}; // FUNCTIONPOINT + 79 +constexpr CURLoption CURLOPT_HEADERDATA{10029}; // CBPOINT + 29 +constexpr CURLoption CURLOPT_POSTFIELDSIZE_LARGE{30120}; // OFF_T + 120 +constexpr CURLoption CURLOPT_POSTFIELDS{10015}; // OBJECTPOINT + 15 +constexpr CURLoption CURLOPT_HTTPHEADER{10023}; // SLISTPOINT + 23 +constexpr CURLoption CURLOPT_NOBODY{44}; // LONG + 44 +constexpr CURLoption CURLOPT_CUSTOMREQUEST{10036}; // STRINGPOINT + 36 +constexpr CURLINFO CURLINFO_RESPONSE_CODE{2097154}; // CURLINFO_LONG(0x200000)+2 +#endif + +namespace sourcemeta::jsonschema { + +// The subset of the libcurl C API this CLI relies on, captured as function +// pointers so the request logic is shared between the link-time backend +// (JSONSCHEMA_USE_SYSTEM_CURL) and the default runtime-loaded (dlopen) +// backend. Member types are derived from the curl headers, so they stay in +// sync with the real prototypes +struct CurlApi { + decltype(&curl_global_init) global_init; + decltype(&curl_easy_init) easy_init; + decltype(&curl_easy_cleanup) easy_cleanup; + decltype(&curl_easy_setopt) easy_setopt; + decltype(&curl_easy_perform) easy_perform; + decltype(&curl_easy_getinfo) easy_getinfo; + decltype(&curl_easy_strerror) easy_strerror; + decltype(&curl_slist_append) slist_append; + decltype(&curl_slist_free_all) slist_free_all; +}; + +} // namespace sourcemeta::jsonschema + namespace { +using sourcemeta::jsonschema::CurlApi; + class CurlHandle { public: - CurlHandle() : handle_{curl_easy_init()} {} + explicit CurlHandle(const CurlApi &api) + : api_{api}, handle_{api.easy_init()} {} ~CurlHandle() { if (this->handle_) { - curl_easy_cleanup(this->handle_); + this->api_.easy_cleanup(this->handle_); } } @@ -28,15 +111,16 @@ class CurlHandle { explicit operator bool() const { return this->handle_ != nullptr; } private: + const CurlApi &api_; CURL *handle_; }; class CurlHeaderList { public: - CurlHeaderList() = default; + explicit CurlHeaderList(const CurlApi &api) : api_{api} {} ~CurlHeaderList() { if (this->list_) { - curl_slist_free_all(this->list_); + this->api_.slist_free_all(this->list_); } } @@ -46,7 +130,7 @@ class CurlHeaderList { auto operator=(CurlHeaderList &&) -> CurlHeaderList & = delete; auto append(const std::string &line) -> void { - auto *result{curl_slist_append(this->list_, line.c_str())}; + auto *result{this->api_.slist_append(this->list_, line.c_str())}; if (result) { this->list_ = result; } @@ -55,6 +139,7 @@ class CurlHeaderList { auto get() const -> curl_slist * { return this->list_; } private: + const CurlApi &api_; curl_slist *list_{nullptr}; }; @@ -91,16 +176,15 @@ auto header_callback(char *data, std::size_t size, std::size_t count, namespace sourcemeta::jsonschema { -auto http_request(const HTTPRequest &request) -> HTTPResponse { - static const CURLcode global_initialization{ - curl_global_init(CURL_GLOBAL_ALL)}; +auto perform_request(const CurlApi &api, const HTTPRequest &request) + -> HTTPResponse { + static const CURLcode global_initialization{api.global_init(CURL_GLOBAL_ALL)}; if (global_initialization != CURLE_OK) { - throw sourcemeta::core::HTTPError{ - request.method, std::string{request.url}, - curl_easy_strerror(global_initialization)}; + throw sourcemeta::core::HTTPError{request.method, std::string{request.url}, + api.easy_strerror(global_initialization)}; } - const CurlHandle handle; + const CurlHandle handle{api}; if (!handle) { throw sourcemeta::core::HTTPError{request.method, std::string{request.url}, "Failed to initialise the HTTP client"}; @@ -108,21 +192,21 @@ auto http_request(const HTTPRequest &request) -> HTTPResponse { HTTPResponse response; const std::string url{request.url}; - curl_easy_setopt(handle.get(), CURLOPT_URL, url.c_str()); - curl_easy_setopt(handle.get(), CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(handle.get(), CURLOPT_NOSIGNAL, 1L); + api.easy_setopt(handle.get(), CURLOPT_URL, url.c_str()); + api.easy_setopt(handle.get(), CURLOPT_FOLLOWLOCATION, 1L); + api.easy_setopt(handle.get(), CURLOPT_NOSIGNAL, 1L); // Advertise and transparently decode all supported content encodings, // matching what the NSURLSession and WinHTTP backends do - curl_easy_setopt(handle.get(), CURLOPT_ACCEPT_ENCODING, ""); + api.easy_setopt(handle.get(), CURLOPT_ACCEPT_ENCODING, ""); std::string raw_headers; BodyContext body_context{&response.body, request.maximum_response_size}; - curl_easy_setopt(handle.get(), CURLOPT_WRITEFUNCTION, body_callback); - curl_easy_setopt(handle.get(), CURLOPT_WRITEDATA, &body_context); - curl_easy_setopt(handle.get(), CURLOPT_HEADERFUNCTION, header_callback); - curl_easy_setopt(handle.get(), CURLOPT_HEADERDATA, &raw_headers); + api.easy_setopt(handle.get(), CURLOPT_WRITEFUNCTION, body_callback); + api.easy_setopt(handle.get(), CURLOPT_WRITEDATA, &body_context); + api.easy_setopt(handle.get(), CURLOPT_HEADERFUNCTION, header_callback); + api.easy_setopt(handle.get(), CURLOPT_HEADERDATA, &raw_headers); - CurlHeaderList header_list; + CurlHeaderList header_list{api}; for (const auto &[name, value] : request.headers) { std::string line{name}; // The semicolon form is how cURL distinguishes a header with an @@ -141,26 +225,26 @@ auto http_request(const HTTPRequest &request) -> HTTPResponse { std::string content_type_line{"Content-Type: "}; content_type_line += request.body.value().content_type; header_list.append(content_type_line); - curl_easy_setopt(handle.get(), CURLOPT_POSTFIELDSIZE_LARGE, - static_cast(request.body.value().data.size())); - curl_easy_setopt(handle.get(), CURLOPT_POSTFIELDS, - request.body.value().data.data()); + api.easy_setopt(handle.get(), CURLOPT_POSTFIELDSIZE_LARGE, + static_cast(request.body.value().data.size())); + api.easy_setopt(handle.get(), CURLOPT_POSTFIELDS, + request.body.value().data.data()); } if (header_list.get()) { - curl_easy_setopt(handle.get(), CURLOPT_HTTPHEADER, header_list.get()); + api.easy_setopt(handle.get(), CURLOPT_HTTPHEADER, header_list.get()); } const std::string method{ sourcemeta::core::http_method_string(request.method)}; if (request.method == sourcemeta::core::HTTPMethod::HEAD) { - curl_easy_setopt(handle.get(), CURLOPT_NOBODY, 1L); + api.easy_setopt(handle.get(), CURLOPT_NOBODY, 1L); } else if (request.method != sourcemeta::core::HTTPMethod::GET || request.body.has_value()) { - curl_easy_setopt(handle.get(), CURLOPT_CUSTOMREQUEST, method.c_str()); + api.easy_setopt(handle.get(), CURLOPT_CUSTOMREQUEST, method.c_str()); } - const auto code{curl_easy_perform(handle.get())}; + const auto code{api.easy_perform(handle.get())}; if (code != CURLE_OK) { if (body_context.maximum_size_exceeded) { throw sourcemeta::core::HTTPError{ @@ -169,11 +253,11 @@ auto http_request(const HTTPRequest &request) -> HTTPResponse { } throw sourcemeta::core::HTTPError{request.method, std::string{request.url}, - curl_easy_strerror(code)}; + api.easy_strerror(code)}; } long status_code{0}; - curl_easy_getinfo(handle.get(), CURLINFO_RESPONSE_CODE, &status_code); + api.easy_getinfo(handle.get(), CURLINFO_RESPONSE_CODE, &status_code); sourcemeta::core::http_parse_headers(raw_headers, response.headers); response.status = sourcemeta::core::http_status_from_code( static_cast(status_code)); @@ -181,3 +265,129 @@ auto http_request(const HTTPRequest &request) -> HTTPResponse { } } // namespace sourcemeta::jsonschema + +#ifndef JSONSCHEMA_USE_SYSTEM_CURL + +namespace { + +using sourcemeta::jsonschema::HTTPDynamicBackendNotFound; + +constexpr std::string_view CURL_LIBRARY_ENV{"SOURCEMETA_JSONSCHEMA_CURL_SO"}; + +// Tried in order. Every entry carries the `.so.4` SONAME so we only ever +// bind an ABI-compatible cURL (never the unversioned `libcurl.so` dev +// symlink, which could point at a different major version). The bare +// soname is first because it resolves through the dynamic linker (ld.so +// cache on glibc, default /lib:/usr/lib on musl) and is present on every +// mainstream distribution. The absolute entries are fallbacks for +// environments where the cache is absent (custom prefixes, ldconfig not +// run). The trailing GnuTLS entry is an ABI-compatible last resort for +// minimal Debian and Ubuntu systems that ship only that build +constexpr std::array CURL_CANDIDATE_PATHS{ + {"libcurl.so.4", "/usr/lib/x86_64-linux-gnu/libcurl.so.4", + "/usr/lib/aarch64-linux-gnu/libcurl.so.4", + "/usr/lib/arm-linux-gnueabihf/libcurl.so.4", + "/usr/lib/i386-linux-gnu/libcurl.so.4", "/usr/lib64/libcurl.so.4", + "/lib64/libcurl.so.4", "/usr/lib/libcurl.so.4", + "/usr/local/lib/libcurl.so.4", "libcurl-gnutls.so.4"}}; + +struct ResolvedLibrary { + void *handle; + std::string path; +}; + +template +auto resolve_symbol(const ResolvedLibrary &library, const char *name) + -> Signature { + // Clear any stale error, then distinguish a null symbol from a null value + dlerror(); + void *symbol{dlsym(library.handle, name)}; + if (dlerror() != nullptr) { + throw HTTPDynamicBackendNotFound{ + "The cURL library was loaded but does not provide the expected API", + std::string{CURL_LIBRARY_ENV}, + {library.path}}; + } + + // Copy the pointer representation instead of reinterpret_cast, which the + // standard only conditionally supports for object-to-function conversions. + // POSIX guarantees dlsym results are convertible to function pointers + Signature function{}; + std::memcpy(&function, &symbol, sizeof(function)); + return function; +} + +auto open_library() -> ResolvedLibrary { + if (const auto *configured_path{std::getenv(CURL_LIBRARY_ENV.data())}; + configured_path != nullptr && configured_path[0] != '\0') { + if (auto *handle{dlopen(configured_path, RTLD_NOW)}; handle != nullptr) { + return {handle, configured_path}; + } + + throw HTTPDynamicBackendNotFound{ + "Could not load the cURL library from the configured path", + std::string{CURL_LIBRARY_ENV}, + {std::string{configured_path}}}; + } + + for (const auto candidate : CURL_CANDIDATE_PATHS) { + if (auto *handle{dlopen(candidate.data(), RTLD_NOW)}; handle != nullptr) { + return {handle, std::string{candidate}}; + } + } + + std::vector searched; + searched.reserve(CURL_CANDIDATE_PATHS.size()); + for (const auto candidate : CURL_CANDIDATE_PATHS) { + searched.emplace_back(candidate); + } + + throw HTTPDynamicBackendNotFound{ + "Could not find the system cURL library (libcurl)", + std::string{CURL_LIBRARY_ENV}, std::move(searched)}; +} + +auto load_curl() -> const CurlApi & { + // The handle is intentionally never dlclose()d: the function pointers + // must remain valid for the lifetime of the process + static const ResolvedLibrary library{open_library()}; + static const CurlApi api{ + resolve_symbol(library, + "curl_global_init"), + resolve_symbol(library, "curl_easy_init"), + resolve_symbol(library, + "curl_easy_cleanup"), + resolve_symbol(library, + "curl_easy_setopt"), + resolve_symbol(library, + "curl_easy_perform"), + resolve_symbol(library, + "curl_easy_getinfo"), + resolve_symbol(library, + "curl_easy_strerror"), + resolve_symbol(library, + "curl_slist_append"), + resolve_symbol(library, + "curl_slist_free_all")}; + return api; +} + +} // namespace + +#endif + +namespace sourcemeta::jsonschema { + +auto http_request(const HTTPRequest &request) -> HTTPResponse { +#ifdef JSONSCHEMA_USE_SYSTEM_CURL + static const CurlApi api{ + &curl_global_init, &curl_easy_init, &curl_easy_cleanup, + &curl_easy_setopt, &curl_easy_perform, &curl_easy_getinfo, + &curl_easy_strerror, &curl_slist_append, &curl_slist_free_all}; + return perform_request(api, request); +#else + return perform_request(load_curl(), request); +#endif +} + +} // namespace sourcemeta::jsonschema diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1c4c32a32..dd32909ef 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -971,6 +971,10 @@ add_jsonschema_test_unix_ci(pass_install_http_header_multiple) add_jsonschema_test_unix_ci(pass_validate_http_header_auth) add_jsonschema_test_unix_ci(precommit_lint) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT JSONSCHEMA_USE_SYSTEM_CURL) + add_jsonschema_test_unix_ci(fail_validate_http_missing_curl) +endif() + add_jsonschema_test_windows_ci(pass_bundle_http) add_jsonschema_test_windows_ci(fail_bundle_http_non_200) add_jsonschema_test_windows_ci(fail_bundle_http_non_schema) diff --git a/test/ci/fail_validate_http_missing_curl.sh b/test/ci/fail_validate_http_missing_curl.sh new file mode 100755 index 000000000..16a2ccbe9 --- /dev/null +++ b/test/ci/fail_validate_http_missing_curl.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +set -o errexit +set -o nounset + +TMP="$(mktemp -d)" +clean() { rm -rf "$TMP"; } +trap clean EXIT + +cat << 'EOF' > "$TMP/schema.json" +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Test", + "description": "Test schema", + "allOf": [ { "$ref": "https://one.sourcemeta.com" } ] +} +EOF + +cat << 'EOF' > "$TMP/instance.json" +{ "type": "string" } +EOF + +SOURCEMETA_JSONSCHEMA_CURL_SO="$TMP/does-not-exist.so" \ + "$1" validate "$TMP/schema.json" "$TMP/instance.json" --http \ + > "$TMP/stdout.txt" 2> "$TMP/stderr.txt" \ + && EXIT_CODE="$?" || EXIT_CODE="$?" +# Not supported +test "$EXIT_CODE" = "3" + +cat << EOF > "$TMP/expected.txt" +error: Could not load the cURL library from the configured path + with environment variable SOURCEMETA_JSONSCHEMA_CURL_SO + with paths + - $TMP/does-not-exist.so +EOF + +diff "$TMP/stderr.txt" "$TMP/expected.txt" + +SOURCEMETA_JSONSCHEMA_CURL_SO="$TMP/does-not-exist.so" \ + "$1" validate "$TMP/schema.json" "$TMP/instance.json" --http --json \ + > "$TMP/stdout_json.txt" 2> "$TMP/stderr_json.txt" \ + && EXIT_CODE="$?" || EXIT_CODE="$?" +# Not supported +test "$EXIT_CODE" = "3" + +cat << EOF > "$TMP/expected_json.txt" +{ + "error": "Could not load the cURL library from the configured path", + "environmentVariable": "SOURCEMETA_JSONSCHEMA_CURL_SO", + "paths": [ "$TMP/does-not-exist.so" ] +} +EOF + +diff "$TMP/stdout_json.txt" "$TMP/expected_json.txt" diff --git a/vendor/c-ares.mask b/vendor/c-ares.mask deleted file mode 100644 index f4012cc38..000000000 --- a/vendor/c-ares.mask +++ /dev/null @@ -1,51 +0,0 @@ -.cirrus.yml -.clang-format -.reuse -appveyor.yml -AUTHORS -buildconf -buildconf.bat -c-ares-config.cmake.in -ci -cmake -CMakeLists.txt -configure.ac -CONTRIBUTING.md -DEVELOPER-NOTES.md -docs -FEATURES.md -FUZZING.md -GIT-INFO -include/ares_build.h.dist -include/ares_build.h.in -include/CMakeLists.txt -include/Makefile.am -INSTALL.md -libcares.pc.cmake -libcares.pc.in -LICENSES -m4 -Makefile.am -Makefile.dj -Makefile.m32 -Makefile.msvc -Makefile.netware -Makefile.Watcom -README.md -README.msvc -RELEASE-NOTES.md -RELEASE-PROCEDURE.md -SECURITY.md -sonar-project.properties -src/CMakeLists.txt -src/lib/cares.rc -src/lib/CMakeLists.txt -src/lib/config-dos.h -src/lib/config-win32.h -src/lib/include/README.md -src/lib/Makefile.am -src/lib/Makefile.inc -src/lib/thirdparty/apple/README.md -src/Makefile.am -src/tools -test diff --git a/vendor/c-ares/LICENSE.md b/vendor/c-ares/LICENSE.md deleted file mode 100644 index 910ddded5..000000000 --- a/vendor/c-ares/LICENSE.md +++ /dev/null @@ -1,24 +0,0 @@ -MIT License - -Copyright (c) 1998 Massachusetts Institute of Technology -Copyright (c) 2007 - 2023 Daniel Stenberg with many contributors, see AUTHORS -file. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/c-ares/include/ares.h b/vendor/c-ares/include/ares.h deleted file mode 100644 index 7fe3ec78f..000000000 --- a/vendor/c-ares/include/ares.h +++ /dev/null @@ -1,1229 +0,0 @@ -/* MIT License - * - * Copyright (c) Massachusetts Institute of Technology - * Copyright (c) Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifndef ARES__H -#define ARES__H - -#include "ares_version.h" /* c-ares version defines */ -#include "ares_build.h" /* c-ares build definitions */ - -#if defined(_WIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -#endif - -#ifdef CARES_HAVE_SYS_TYPES_H -# include -#endif - -#ifdef CARES_HAVE_SYS_SOCKET_H -# include -#endif - -#ifdef CARES_HAVE_SYS_SELECT_H -# include -#endif - -#ifdef CARES_HAVE_WINSOCK2_H -# include -/* To aid with linking against a static c-ares build, lets tell the microsoft - * compiler to pull in needed dependencies */ -# ifdef _MSC_VER -# pragma comment(lib, "ws2_32") -# pragma comment(lib, "advapi32") -# pragma comment(lib, "iphlpapi") -# endif -#endif - -#ifdef CARES_HAVE_WS2TCPIP_H -# include -#endif - -#ifdef CARES_HAVE_WINDOWS_H -# include -#endif - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on system that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ - defined(__QNX__) || defined(__MVS__) || defined(__HAIKU__) -# include -#endif - -#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) -# include -#endif - -#if !defined(_WIN32) -# include -#endif - -#ifdef WATT32 -# include -#endif - -#if defined(ANDROID) || defined(__ANDROID__) -# include -#endif - -typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; -typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t; - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** c-ares external API function linkage decorations. -*/ - -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__SYMBIAN32__) -# ifdef CARES_STATICLIB -# define CARES_EXTERN -# else -# ifdef CARES_BUILDING_LIBRARY -# define CARES_EXTERN __declspec(dllexport) -# else -# define CARES_EXTERN __declspec(dllimport) -# endif -# endif -#else -# if defined(__GNUC__) && __GNUC__ >= 4 -# define CARES_EXTERN __attribute__((visibility("default"))) -# elif defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 900 -# define CARES_EXTERN __attribute__((visibility("default"))) -# elif defined(__SUNPRO_C) -# define CARES_EXTERN _global -# else -# define CARES_EXTERN -# endif -#endif - -#ifdef __GNUC__ -# define CARES_GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#else -# define CARES_GCC_VERSION 0 -#endif - -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif - -#ifdef CARES_NO_DEPRECATED -# define CARES_DEPRECATED -# define CARES_DEPRECATED_FOR(f) -#else -# if CARES_GCC_VERSION >= 30200 || __has_attribute(__deprecated__) -# define CARES_DEPRECATED __attribute__((__deprecated__)) -# else -# define CARES_DEPRECATED -# endif - -# if CARES_GCC_VERSION >= 40500 || defined(__clang__) -# define CARES_DEPRECATED_FOR(f) \ - __attribute__((deprecated("Use " #f " instead"))) -# elif defined(_MSC_VER) -# define CARES_DEPRECATED_FOR(f) __declspec(deprecated("Use " #f " instead")) -# else -# define CARES_DEPRECATED_FOR(f) CARES_DEPRECATED -# endif -#endif - -typedef enum { - ARES_SUCCESS = 0, - - /* Server error codes (ARES_ENODATA indicates no relevant answer) */ - ARES_ENODATA = 1, - ARES_EFORMERR = 2, - ARES_ESERVFAIL = 3, - ARES_ENOTFOUND = 4, - ARES_ENOTIMP = 5, - ARES_EREFUSED = 6, - - /* Locally generated error codes */ - ARES_EBADQUERY = 7, - ARES_EBADNAME = 8, - ARES_EBADFAMILY = 9, - ARES_EBADRESP = 10, - ARES_ECONNREFUSED = 11, - ARES_ETIMEOUT = 12, - ARES_EOF = 13, - ARES_EFILE = 14, - ARES_ENOMEM = 15, - ARES_EDESTRUCTION = 16, - ARES_EBADSTR = 17, - - /* ares_getnameinfo error codes */ - ARES_EBADFLAGS = 18, - - /* ares_getaddrinfo error codes */ - ARES_ENONAME = 19, - ARES_EBADHINTS = 20, - - /* Uninitialized library error code */ - ARES_ENOTINITIALIZED = 21, /* introduced in 1.7.0 */ - - /* ares_library_init error codes */ - ARES_ELOADIPHLPAPI = 22, /* introduced in 1.7.0 */ - ARES_EADDRGETNETWORKPARAMS = 23, /* introduced in 1.7.0 */ - - /* More error codes */ - ARES_ECANCELLED = 24, /* introduced in 1.7.0 */ - - /* More ares_getaddrinfo error codes */ - ARES_ESERVICE = 25, /* ares_getaddrinfo() was passed a text service name that - * is not recognized. introduced in 1.16.0 */ - - ARES_ENOSERVER = 26 /* No DNS servers were configured */ -} ares_status_t; - -typedef enum { - ARES_FALSE = 0, - ARES_TRUE = 1 -} ares_bool_t; - -/*! Values for ARES_OPT_EVENT_THREAD */ -typedef enum { - /*! Default (best choice) event system */ - ARES_EVSYS_DEFAULT = 0, - /*! Win32 IOCP/AFD_POLL event system */ - ARES_EVSYS_WIN32 = 1, - /*! Linux epoll */ - ARES_EVSYS_EPOLL = 2, - /*! BSD/MacOS kqueue */ - ARES_EVSYS_KQUEUE = 3, - /*! POSIX poll() */ - ARES_EVSYS_POLL = 4, - /*! last fallback on Unix-like systems, select() */ - ARES_EVSYS_SELECT = 5 -} ares_evsys_t; - -/* Flag values */ -#define ARES_FLAG_USEVC (1 << 0) -#define ARES_FLAG_PRIMARY (1 << 1) -#define ARES_FLAG_IGNTC (1 << 2) -#define ARES_FLAG_NORECURSE (1 << 3) -#define ARES_FLAG_STAYOPEN (1 << 4) -#define ARES_FLAG_NOSEARCH (1 << 5) -#define ARES_FLAG_NOALIASES (1 << 6) -#define ARES_FLAG_NOCHECKRESP (1 << 7) -#define ARES_FLAG_EDNS (1 << 8) -#define ARES_FLAG_NO_DFLT_SVR (1 << 9) -#define ARES_FLAG_DNS0x20 (1 << 10) - -/* Option mask values */ -#define ARES_OPT_FLAGS (1 << 0) -#define ARES_OPT_TIMEOUT (1 << 1) -#define ARES_OPT_TRIES (1 << 2) -#define ARES_OPT_NDOTS (1 << 3) -#define ARES_OPT_UDP_PORT (1 << 4) -#define ARES_OPT_TCP_PORT (1 << 5) -#define ARES_OPT_SERVERS (1 << 6) -#define ARES_OPT_DOMAINS (1 << 7) -#define ARES_OPT_LOOKUPS (1 << 8) -#define ARES_OPT_SOCK_STATE_CB (1 << 9) -#define ARES_OPT_SORTLIST (1 << 10) -#define ARES_OPT_SOCK_SNDBUF (1 << 11) -#define ARES_OPT_SOCK_RCVBUF (1 << 12) -#define ARES_OPT_TIMEOUTMS (1 << 13) -#define ARES_OPT_ROTATE (1 << 14) -#define ARES_OPT_EDNSPSZ (1 << 15) -#define ARES_OPT_NOROTATE (1 << 16) -#define ARES_OPT_RESOLVCONF (1 << 17) -#define ARES_OPT_HOSTS_FILE (1 << 18) -#define ARES_OPT_UDP_MAX_QUERIES (1 << 19) -#define ARES_OPT_MAXTIMEOUTMS (1 << 20) -#define ARES_OPT_QUERY_CACHE (1 << 21) -#define ARES_OPT_EVENT_THREAD (1 << 22) -#define ARES_OPT_SERVER_FAILOVER (1 << 23) - -/* Nameinfo flag values */ -#define ARES_NI_NOFQDN (1 << 0) -#define ARES_NI_NUMERICHOST (1 << 1) -#define ARES_NI_NAMEREQD (1 << 2) -#define ARES_NI_NUMERICSERV (1 << 3) -#define ARES_NI_DGRAM (1 << 4) -#define ARES_NI_TCP 0 -#define ARES_NI_UDP ARES_NI_DGRAM -#define ARES_NI_SCTP (1 << 5) -#define ARES_NI_DCCP (1 << 6) -#define ARES_NI_NUMERICSCOPE (1 << 7) -#define ARES_NI_LOOKUPHOST (1 << 8) -#define ARES_NI_LOOKUPSERVICE (1 << 9) -/* Reserved for future use */ -#define ARES_NI_IDN (1 << 10) -#define ARES_NI_IDN_ALLOW_UNASSIGNED (1 << 11) -#define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12) - -/* Addrinfo flag values */ -#define ARES_AI_CANONNAME (1 << 0) -#define ARES_AI_NUMERICHOST (1 << 1) -#define ARES_AI_PASSIVE (1 << 2) -#define ARES_AI_NUMERICSERV (1 << 3) -#define ARES_AI_V4MAPPED (1 << 4) -#define ARES_AI_ALL (1 << 5) -#define ARES_AI_ADDRCONFIG (1 << 6) -#define ARES_AI_NOSORT (1 << 7) -#define ARES_AI_ENVHOSTS (1 << 8) -/* Reserved for future use */ -#define ARES_AI_IDN (1 << 10) -#define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11) -#define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12) -#define ARES_AI_CANONIDN (1 << 13) - -#define ARES_AI_MASK \ - (ARES_AI_CANONNAME | ARES_AI_NUMERICHOST | ARES_AI_PASSIVE | \ - ARES_AI_NUMERICSERV | ARES_AI_V4MAPPED | ARES_AI_ALL | ARES_AI_ADDRCONFIG) -#define ARES_GETSOCK_MAXNUM \ - 16 /* ares_getsock() can return info about this \ - many sockets */ -#define ARES_GETSOCK_READABLE(bits, num) (bits & (1 << (num))) -#define ARES_GETSOCK_WRITABLE(bits, num) \ - (bits & (1 << ((num) + ARES_GETSOCK_MAXNUM))) - -/* c-ares library initialization flag values */ -#define ARES_LIB_INIT_NONE (0) -#define ARES_LIB_INIT_WIN32 (1 << 0) -#define ARES_LIB_INIT_ALL (ARES_LIB_INIT_WIN32) - -/* Server state callback flag values */ -#define ARES_SERV_STATE_UDP (1 << 0) /* Query used UDP */ -#define ARES_SERV_STATE_TCP (1 << 1) /* Query used TCP */ - -/* - * Typedef our socket type - */ - -#ifndef ares_socket_typedef -# if defined(_WIN32) && !defined(WATT32) -typedef SOCKET ares_socket_t; -# define ARES_SOCKET_BAD INVALID_SOCKET -# else -typedef int ares_socket_t; -# define ARES_SOCKET_BAD -1 -# endif -# define ares_socket_typedef -#endif /* ares_socket_typedef */ - -typedef void (*ares_sock_state_cb)(void *data, ares_socket_t socket_fd, - int readable, int writable); - -struct apattern; - -/* Options controlling server failover behavior. - * The retry chance is the probability (1/N) by which we will retry a failed - * server instead of the best server when selecting a server to send queries - * to. - * The retry delay is the minimum time in milliseconds to wait between doing - * such retries (applied per-server). - */ -struct ares_server_failover_options { - unsigned short retry_chance; - size_t retry_delay; -}; - -/* NOTE about the ares_options struct to users and developers. - - This struct will remain looking like this. It will not be extended nor - shrunk in future releases, but all new options will be set by ares_set_*() - options instead of with the ares_init_options() function. - - Eventually (in a galaxy far far away), all options will be settable by - ares_set_*() options and the ares_init_options() function will become - deprecated. - - When new options are added to c-ares, they are not added to this - struct. And they are not "saved" with the ares_save_options() function but - instead we encourage the use of the ares_dup() function. Needless to say, - if you add config options to c-ares you need to make sure ares_dup() - duplicates this new option. - - */ -struct ares_options { - int flags; - int timeout; /* in seconds or milliseconds, depending on options */ - int tries; - int ndots; - unsigned short udp_port; /* host byte order */ - unsigned short tcp_port; /* host byte order */ - int socket_send_buffer_size; - int socket_receive_buffer_size; - struct in_addr *servers; - int nservers; - char **domains; - int ndomains; - char *lookups; - ares_sock_state_cb sock_state_cb; - void *sock_state_cb_data; - struct apattern *sortlist; - int nsort; - int ednspsz; - char *resolvconf_path; - char *hosts_path; - int udp_max_queries; - int maxtimeout; /* in milliseconds */ - unsigned int qcache_max_ttl; /* Maximum TTL for query cache, 0=disabled */ - ares_evsys_t evsys; - struct ares_server_failover_options server_failover_opts; -}; - -struct hostent; -struct timeval; -struct sockaddr; -struct ares_channeldata; -struct ares_addrinfo; -struct ares_addrinfo_hints; - -/* Legacy typedef, don't use, you can't specify "const" */ -typedef struct ares_channeldata *ares_channel; - -/* Current main channel typedef */ -typedef struct ares_channeldata ares_channel_t; - -/* - * NOTE: before c-ares 1.7.0 we would most often use the system in6_addr - * struct below when ares itself was built, but many apps would use this - * private version since the header checked a HAVE_* define for it. Starting - * with 1.7.0 we always declare and use our own to stop relying on the - * system's one. - */ -struct ares_in6_addr { - union { - unsigned char _S6_u8[16]; - } _S6_un; -}; - -struct ares_addr { - int family; - - union { - struct in_addr addr4; - struct ares_in6_addr addr6; - } addr; -}; - -/* DNS record parser, writer, and helpers */ -#include "ares_dns_record.h" - -typedef void (*ares_callback)(void *arg, int status, int timeouts, - unsigned char *abuf, int alen); - -typedef void (*ares_callback_dnsrec)(void *arg, ares_status_t status, - size_t timeouts, - const ares_dns_record_t *dnsrec); - -typedef void (*ares_host_callback)(void *arg, int status, int timeouts, - struct hostent *hostent); - -typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts, - char *node, char *service); - -typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd, int type, - void *data); - -typedef int (*ares_sock_config_callback)(ares_socket_t socket_fd, int type, - void *data); - -typedef void (*ares_addrinfo_callback)(void *arg, int status, int timeouts, - struct ares_addrinfo *res); - -typedef void (*ares_server_state_callback)(const char *server_string, - ares_bool_t success, int flags, - void *data); - -typedef void (*ares_pending_write_cb)(void *data); - -CARES_EXTERN int ares_library_init(int flags); - -CARES_EXTERN int ares_library_init_mem(int flags, void *(*amalloc)(size_t size), - void (*afree)(void *ptr), - void *(*arealloc)(void *ptr, - size_t size)); - -#if defined(ANDROID) || defined(__ANDROID__) -CARES_EXTERN void ares_library_init_jvm(JavaVM *jvm); -CARES_EXTERN int ares_library_init_android(jobject connectivity_manager); -CARES_EXTERN int ares_library_android_initialized(void); -#endif - -#define CARES_HAVE_ARES_LIBRARY_INIT 1 -#define CARES_HAVE_ARES_LIBRARY_CLEANUP 1 - -CARES_EXTERN int ares_library_initialized(void); - -CARES_EXTERN void ares_library_cleanup(void); - -CARES_EXTERN const char *ares_version(int *version); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_init_options) int ares_init( - ares_channel_t **channelptr); - -CARES_EXTERN int ares_init_options(ares_channel_t **channelptr, - const struct ares_options *options, - int optmask); - -CARES_EXTERN int ares_save_options(const ares_channel_t *channel, - struct ares_options *options, int *optmask); - -CARES_EXTERN void ares_destroy_options(struct ares_options *options); - -CARES_EXTERN int ares_dup(ares_channel_t **dest, const ares_channel_t *src); - -CARES_EXTERN ares_status_t ares_reinit(ares_channel_t *channel); - -CARES_EXTERN void ares_destroy(ares_channel_t *channel); - -CARES_EXTERN void ares_cancel(ares_channel_t *channel); - -/* These next 3 configure local binding for the out-going socket - * connection. Use these to specify source IP and/or network device - * on multi-homed systems. - */ -CARES_EXTERN void ares_set_local_ip4(ares_channel_t *channel, - unsigned int local_ip); - -/* local_ip6 should be 16 bytes in length */ -CARES_EXTERN void ares_set_local_ip6(ares_channel_t *channel, - const unsigned char *local_ip6); - -/* local_dev_name should be null terminated. */ -CARES_EXTERN void ares_set_local_dev(ares_channel_t *channel, - const char *local_dev_name); - -CARES_EXTERN void ares_set_socket_callback(ares_channel_t *channel, - ares_sock_create_callback callback, - void *user_data); - -CARES_EXTERN void ares_set_socket_configure_callback( - ares_channel_t *channel, ares_sock_config_callback callback, void *user_data); - -CARES_EXTERN void - ares_set_server_state_callback(ares_channel_t *channel, - ares_server_state_callback callback, - void *user_data); - -CARES_EXTERN void ares_set_pending_write_cb(ares_channel_t *channel, - ares_pending_write_cb callback, - void *user_data); - -CARES_EXTERN void ares_process_pending_write(ares_channel_t *channel); - -CARES_EXTERN int ares_set_sortlist(ares_channel_t *channel, - const char *sortstr); - -CARES_EXTERN void ares_getaddrinfo(ares_channel_t *channel, const char *node, - const char *service, - const struct ares_addrinfo_hints *hints, - ares_addrinfo_callback callback, void *arg); - -CARES_EXTERN void ares_freeaddrinfo(struct ares_addrinfo *ai); - -/* - * Virtual function set to have user-managed socket IO. - * Note that all functions need to be defined, and when - * set, the library will not do any bind nor set any - * socket options, assuming the client handles these - * through either socket creation or the - * ares_sock_config_callback call. - */ -struct iovec; - -struct ares_socket_functions { - ares_socket_t (*asocket)(int, int, int, void *); - int (*aclose)(ares_socket_t, void *); - int (*aconnect)(ares_socket_t, const struct sockaddr *, ares_socklen_t, - void *); - ares_ssize_t (*arecvfrom)(ares_socket_t, void *, size_t, int, - struct sockaddr *, ares_socklen_t *, void *); - ares_ssize_t (*asendv)(ares_socket_t, const struct iovec *, int, void *); -}; - -CARES_EXTERN CARES_DEPRECATED_FOR( - ares_set_socket_functions_ex) void ares_set_socket_functions(ares_channel_t - *channel, - const struct - ares_socket_functions - *funcs, - void *user_data); - -/*! Flags defining behavior of socket functions */ -typedef enum { - /*! Strongly recommended to create sockets as non-blocking and set this - * flag */ - ARES_SOCKFUNC_FLAG_NONBLOCKING = 1 << 0 -} ares_sockfunc_flags_t; - -/*! Socket options in request to asetsockopt() in struct - * ares_socket_functions_ex */ -typedef enum { - /*! Set the send buffer size. Value is a pointer to an int. (SO_SNDBUF) */ - ARES_SOCKET_OPT_SENDBUF_SIZE, - /*! Set the recv buffer size. Value is a pointer to an int. (SO_RCVBUF) */ - ARES_SOCKET_OPT_RECVBUF_SIZE, - /*! Set the network interface to use as the source for communication. - * Value is a C string. (SO_BINDTODEVICE) */ - ARES_SOCKET_OPT_BIND_DEVICE, - /*! Enable TCP Fast Open. Value is a pointer to an ares_bool_t. On some - * systems this could be a no-op if it is known it is on by default and - * return success. Other systems may be a no-op if known the system does - * not support the feature and returns failure with errno set to ENOSYS or - * WSASetLastError(WSAEOPNOTSUPP). - */ - ARES_SOCKET_OPT_TCP_FASTOPEN -} ares_socket_opt_t; - -/*! Flags for behavior during connect */ -typedef enum { - /*! Connect using TCP Fast Open */ - ARES_SOCKET_CONN_TCP_FASTOPEN = 1 << 0 -} ares_socket_connect_flags_t; - -/*! Flags for behavior during bind */ -typedef enum { - /*! Bind is for a TCP connection */ - ARES_SOCKET_BIND_TCP = 1 << 0, - /*! Bind is for a client connection, not server */ - ARES_SOCKET_BIND_CLIENT = 1 << 1 -} ares_socket_bind_flags_t; - -/*! Socket functions to call rather than using OS-native functions */ -struct ares_socket_functions_ex { - /*! ABI Version: must be "1" */ - unsigned int version; - - /*! Flags indicating behavior of the subsystem. One or more - * ares_sockfunc_flags_t */ - unsigned int flags; - - /*! REQUIRED. Create a new socket file descriptor. The file descriptor must - * be opened in non-blocking mode (so that reads and writes never block). - * Recommended other options would be to disable signals on write errors - * (SO_NOSIGPIPE), Disable the Nagle algorithm on SOCK_STREAM (TCP_NODELAY), - * and to automatically close file descriptors on exec (FD_CLOEXEC). - * - * \param[in] domain Socket domain. Valid values are AF_INET, AF_INET6. - * \param[in] type Socket type. Valid values are SOCK_STREAM (tcp) and - * SOCK_DGRAM (udp). - * \param[in] protocol In general this should be ignored, may be passed as - * 0 (use as default for type), or may be IPPROTO_UDP - * or IPPROTO_TCP. - * \param[in] user_data Pointer provided to ares_set_socket_functions_ex(). - * \return ARES_SOCKET_BAD on error, or socket file descriptor on success. - * On error, it is expected to set errno (or WSASetLastError()) to an - * appropriate reason code such as EAFNOSUPPORT / WSAAFNOSUPPORT. */ - ares_socket_t (*asocket)(int domain, int type, int protocol, void *user_data); - - /*! REQUIRED. Close a socket file descriptor. - * \param[in] sock Socket file descriptor returned from asocket. - * \param[in] user_data Pointer provided to ares_set_socket_functions_ex(). - * \return 0 on success. On failure, should set errno (or WSASetLastError) - * to an appropriate code such as EBADF / WSAEBADF */ - int (*aclose)(ares_socket_t sock, void *user_data); - - - /*! REQUIRED. Set socket option. This shares a similar syntax to the BSD - * setsockopt() call, however we use our own options. The value is typically - * a pointer to the desired value and each option has its own data type it - * will express in the documentation. - * - * \param[in] sock Socket file descriptor returned from asocket. - * \param[in] opt Option to set. - * \param[in] val Pointer to value for option. - * \param[in] val_size Size of value. - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return Return 0 on success, otherwise -1 should be returned with an - * appropriate errno (or WSASetLastError()) set. If error is ENOSYS / - * WSAEOPNOTSUPP an error will not be propagated as it will take it - * to mean it is an intentional decision to not support the feature. - */ - int (*asetsockopt)(ares_socket_t sock, ares_socket_opt_t opt, const void *val, - ares_socklen_t val_size, void *user_data); - - /*! REQUIRED. Connect to the remote using the supplied address. For UDP - * sockets this will bind the file descriptor to only send and receive packets - * from the remote address provided. - * - * \param[in] sock Socket file descriptor returned from asocket. - * \param[in] address Address to connect to - * \param[in] address_len Size of address structure passed - * \param[in] flags One or more ares_socket_connect_flags_t - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return Return 0 upon successful establishement, otherwise -1 should be - * returned with an appropriate errno (or WSASetLastError()) set. It - * is generally expected that most TCP connections (not using TCP Fast Open) - * will return -1 with an error of EINPROGRESS / WSAEINPROGRESS due to the - * non-blocking nature of the connection. It is then the responsibility of - * the implementation to notify of writability on the socket to indicate the - * connection has succeeded (or readability on failure to retrieve the - * appropriate error). - */ - int (*aconnect)(ares_socket_t sock, const struct sockaddr *address, - ares_socklen_t address_len, unsigned int flags, - void *user_data); - - /*! REQUIRED. Attempt to read data from the remote. - * - * \param[in] sock Socket file descriptor returned from asocket. - * \param[in,out] buffer Allocated buffer to place data read from - * socket. - * \param[in] length Size of buffer - * \param[in] flags Unused, always 0. - * \param[in,out] address Buffer to hold address data was received from. - * May be NULL if address not desired. - * \param[in,out] address_len Input size of address buffer, output actual - * written size. Must be NULL if address is NULL. - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return -1 on error with appropriate errno (or WSASetLastError()) set, - * such as EWOULDBLOCK / EAGAIN / WSAEWOULDBLOCK, or ECONNRESET / - * WSAECONNRESET. - */ - ares_ssize_t (*arecvfrom)(ares_socket_t sock, void *buffer, size_t length, - int flags, struct sockaddr *address, - ares_socklen_t *address_len, void *user_data); - - /*! REQUIRED. Attempt to send data to the remote. Optional address may be - * specified which may be useful on unbound UDP sockets (though currently not - * used), and TCP FastOpen where the connection is delayed until first write. - * - * \param[in] sock Socket file descriptor returned from asocket. - * \param[in] buffer Containing data to place onto wire. - * \param[in] length Size of buffer - * \param[in] flags Flags for writing. Currently only used flag is - * MSG_NOSIGNAL if the host OS has such a flag. In - * general flags can be ignored. - * \param[in] address Buffer containing address to send data to. May - * be NULL. - * \param[in,out] address_len Size of address buffer. Must be 0 if address - * is NULL. - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return Number of bytes written. -1 on error with appropriate errno (or - * WSASetLastError()) set. - */ - ares_ssize_t (*asendto)(ares_socket_t sock, const void *buffer, size_t length, - int flags, const struct sockaddr *address, - ares_socklen_t address_len, void *user_data); - - /*! Optional. Retrieve the local address of the socket. - * - * \param[in] sock Socket file descriptor returned from asocket - * \param[in,out] address Buffer to hold address - * \param[in,out] address_len Size of address buffer on input, written size - * on output. - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return 0 on success. -1 on error with an appropriate errno (or - * WSASetLastError()) set. - */ - int (*agetsockname)(ares_socket_t sock, struct sockaddr *address, - ares_socklen_t *address_len, void *user_data); - - /*! Optional. Bind the socket to an address. This can be used for client - * connections to bind the source address for packets before connect, or - * for server connections to bind to an address and port before listening. - * Currently c-ares only supports client connections. - * - * \param[in] sock Socket file descriptor returned from asocket - * \param[in] flags ares_socket_bind_flags_t flags. - * \param[in] address Buffer containing address. - * \param[in] address_len Size of address buffer. - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return 0 on success. -1 on error with an appropriate errno (or - * WSASetLastError()) set. - */ - int (*abind)(ares_socket_t sock, unsigned int flags, - const struct sockaddr *address, socklen_t address_len, - void *user_data); - - /* Optional. Convert an interface name into the interface index. If this - * callback is not specified, then IPv6 Link-Local DNS servers cannot be used. - * - * \param[in] ifname Interface Name as NULL-terminated string. - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return 0 on failure, otherwise interface index. - */ - unsigned int (*aif_nametoindex)(const char *ifname, void *user_data); - - /* Optional. Convert an interface index into the interface name. If this - * callback is not specified, then IPv6 Link-Local DNS servers cannot be used. - * - * \param[in] ifindex Interface index, must be > 0 - * \param[in] ifname_buf Buffer to hold interface name. Must be at least - * IFNAMSIZ in length or 32 bytes if IFNAMSIZ isn't - * defined. - * \param[in] ifname_buf_len Size of ifname_buf for verification. - * \param[in] user_data Pointer provided to - * ares_set_socket_functions_ex(). - * \return NULL on failure, otherwise pointer to provided ifname_buf - */ - const char *(*aif_indextoname)(unsigned int ifindex, char *ifname_buf, - size_t ifname_buf_len, void *user_data); -}; - -/*! Override the native socket functions for the OS with the provided set. - * An optional user data thunk may be specified which will be passed to - * each registered callback. Replaces ares_set_socket_functions(). - * - * \param[in] channel An initialized c-ares channel. - * \param[in] funcs Structure registering the implementations for the - * various functions. See the structure definition. - * This will be duplicated and does not need to exist - * past the life of this call. - * \param[in] user_data User data thunk which will be passed to each call of - * the registered callbacks. - * \return ARES_SUCCESS on success, or another error code such as ARES_EFORMERR - * on misuse. - */ -CARES_EXTERN ares_status_t ares_set_socket_functions_ex( - ares_channel_t *channel, const struct ares_socket_functions_ex *funcs, - void *user_data); - - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_send_dnsrec) void ares_send( - ares_channel_t *channel, const unsigned char *qbuf, int qlen, - ares_callback callback, void *arg); - -/*! Send a DNS query as an ares_dns_record_t with a callback containing the - * parsed DNS record. - * - * \param[in] channel Pointer to channel on which queries will be sent. - * \param[in] dnsrec DNS Record to send - * \param[in] callback Callback function invoked on completion or failure of - * the query sequence. - * \param[in] arg Additional argument passed to the callback function. - * \param[out] qid Query ID - * \return One of the c-ares status codes. - */ -CARES_EXTERN ares_status_t ares_send_dnsrec(ares_channel_t *channel, - const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, - void *arg, unsigned short *qid); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_query_dnsrec) void ares_query( - ares_channel_t *channel, const char *name, int dnsclass, int type, - ares_callback callback, void *arg); - -/*! Perform a DNS query with a callback containing the parsed DNS record. - * - * \param[in] channel Pointer to channel on which queries will be sent. - * \param[in] name Query name - * \param[in] dnsclass DNS Class - * \param[in] type DNS Record Type - * \param[in] callback Callback function invoked on completion or failure of - * the query sequence. - * \param[in] arg Additional argument passed to the callback function. - * \param[out] qid Query ID - * \return One of the c-ares status codes. - */ -CARES_EXTERN ares_status_t ares_query_dnsrec(ares_channel_t *channel, - const char *name, - ares_dns_class_t dnsclass, - ares_dns_rec_type_t type, - ares_callback_dnsrec callback, - void *arg, unsigned short *qid); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_search_dnsrec) void ares_search( - ares_channel_t *channel, const char *name, int dnsclass, int type, - ares_callback callback, void *arg); - -/*! Search for a complete DNS message. - * - * \param[in] channel Pointer to channel on which queries will be sent. - * \param[in] dnsrec Pointer to initialized and filled DNS record object. - * \param[in] callback Callback function invoked on completion or failure of - * the query sequence. - * \param[in] arg Additional argument passed to the callback function. - * \return One of the c-ares status codes. In all cases, except - * ARES_EFORMERR due to misuse, this error code will also be sent - * to the provided callback. - */ -CARES_EXTERN ares_status_t ares_search_dnsrec(ares_channel_t *channel, - const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, - void *arg); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_getaddrinfo) void ares_gethostbyname( - ares_channel_t *channel, const char *name, int family, - ares_host_callback callback, void *arg); - -CARES_EXTERN int ares_gethostbyname_file(ares_channel_t *channel, - const char *name, int family, - struct hostent **host); - -CARES_EXTERN void ares_gethostbyaddr(ares_channel_t *channel, const void *addr, - int addrlen, int family, - ares_host_callback callback, void *arg); - -CARES_EXTERN void ares_getnameinfo(ares_channel_t *channel, - const struct sockaddr *sa, - ares_socklen_t salen, int flags, - ares_nameinfo_callback callback, void *arg); - -CARES_EXTERN CARES_DEPRECATED_FOR( - ARES_OPT_EVENT_THREAD or - ARES_OPT_SOCK_STATE_CB) int ares_fds(const ares_channel_t *channel, - fd_set *read_fds, fd_set *write_fds); - -CARES_EXTERN CARES_DEPRECATED_FOR( - ARES_OPT_EVENT_THREAD or - ARES_OPT_SOCK_STATE_CB) int ares_getsock(const ares_channel_t *channel, - ares_socket_t *socks, int numsocks); - -CARES_EXTERN struct timeval *ares_timeout(const ares_channel_t *channel, - struct timeval *maxtv, - struct timeval *tv); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_process_fds) void ares_process( - ares_channel_t *channel, fd_set *read_fds, fd_set *write_fds); - -/*! Events used by ares_fd_events_t */ -typedef enum { - ARES_FD_EVENT_NONE = 0, /*!< No events */ - ARES_FD_EVENT_READ = 1 << 0, /*!< Read event (including disconnect/error) */ - ARES_FD_EVENT_WRITE = 1 << 1 /*!< Write event */ -} ares_fd_eventflag_t; - -/*! Type holding a file descriptor and mask of events, used by - * ares_process_fds() */ -typedef struct { - ares_socket_t fd; /*!< File descriptor */ - unsigned int events; /*!< Mask of ares_fd_eventflag_t */ -} ares_fd_events_t; - -/*! Flags used by ares_process_fds() */ -typedef enum { - ARES_PROCESS_FLAG_NONE = 0, /*!< No flag value */ - ARES_PROCESS_FLAG_SKIP_NON_FD = 1 << 0 /*!< skip any processing unrelated to - * the file descriptor events passed - * in */ -} ares_process_flag_t; - -/*! Process events on multiple file descriptors based on the event mask - * associated with each file descriptor. Recommended over calling - * ares_process_fd() multiple times since it would trigger additional logic - * such as timeout processing on each call. - * - * \param[in] channel Initialized ares channel - * \param[in] events Array of file descriptors with events. May be NULL if - * no events, but may have timeouts to process. - * \param[in] nevents Number of elements in the events array. May be 0 if - * no events, but may have timeouts to process. - * \param[in] flags Flags to alter behavior of the process command. - * \return ARES_ENOMEM on out of memory, ARES_EFORMERR on misuse, - * otherwise ARES_SUCCESS - */ -CARES_EXTERN ares_status_t ares_process_fds(ares_channel_t *channel, - const ares_fd_events_t *events, - size_t nevents, unsigned int flags); - -CARES_EXTERN void ares_process_fd(ares_channel_t *channel, - ares_socket_t read_fd, - ares_socket_t write_fd); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_record_create) int ares_create_query( - const char *name, int dnsclass, int type, unsigned short id, int rd, - unsigned char **buf, int *buflen, int max_udp_size); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_record_create) int ares_mkquery( - const char *name, int dnsclass, int type, unsigned short id, int rd, - unsigned char **buf, int *buflen); - -CARES_EXTERN int ares_expand_name(const unsigned char *encoded, - const unsigned char *abuf, int alen, char **s, - long *enclen); - -CARES_EXTERN int ares_expand_string(const unsigned char *encoded, - const unsigned char *abuf, int alen, - unsigned char **s, long *enclen); - -struct ares_addrttl { - struct in_addr ipaddr; - int ttl; -}; - -struct ares_addr6ttl { - struct ares_in6_addr ip6addr; - int ttl; -}; - -struct ares_caa_reply { - struct ares_caa_reply *next; - int critical; - unsigned char *property; - size_t plength; /* plength excludes null termination */ - unsigned char *value; - size_t length; /* length excludes null termination */ -}; - -struct ares_srv_reply { - struct ares_srv_reply *next; - char *host; - unsigned short priority; - unsigned short weight; - unsigned short port; -}; - -struct ares_mx_reply { - struct ares_mx_reply *next; - char *host; - unsigned short priority; -}; - -struct ares_txt_reply { - struct ares_txt_reply *next; - unsigned char *txt; - size_t length; /* length excludes null termination */ -}; - -/* NOTE: This structure is a superset of ares_txt_reply - */ -struct ares_txt_ext { - struct ares_txt_ext *next; - unsigned char *txt; - size_t length; - /* 1 - if start of new record - * 0 - if a chunk in the same record */ - unsigned char record_start; -}; - -struct ares_naptr_reply { - struct ares_naptr_reply *next; - unsigned char *flags; - unsigned char *service; - unsigned char *regexp; - char *replacement; - unsigned short order; - unsigned short preference; -}; - -struct ares_soa_reply { - char *nsname; - char *hostmaster; - unsigned int serial; - unsigned int refresh; - unsigned int retry; - unsigned int expire; - unsigned int minttl; -}; - -struct ares_uri_reply { - struct ares_uri_reply *next; - unsigned short priority; - unsigned short weight; - char *uri; - int ttl; -}; - -/* - * Similar to addrinfo, but with extra ttl and missing canonname. - */ -struct ares_addrinfo_node { - int ai_ttl; - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - ares_socklen_t ai_addrlen; - struct sockaddr *ai_addr; - struct ares_addrinfo_node *ai_next; -}; - -/* - * alias - label of the resource record. - * name - value (canonical name) of the resource record. - * See RFC2181 10.1.1. CNAME terminology. - */ -struct ares_addrinfo_cname { - int ttl; - char *alias; - char *name; - struct ares_addrinfo_cname *next; -}; - -struct ares_addrinfo { - struct ares_addrinfo_cname *cnames; - struct ares_addrinfo_node *nodes; - char *name; -}; - -struct ares_addrinfo_hints { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; -}; - -/* -** Parse the buffer, starting at *abuf and of length alen bytes, previously -** obtained from an ares_search call. Put the results in *host, if nonnull. -** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with -** their TTLs in that array, and set *naddrttls to the number of addresses -** so written. -*/ - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_a_reply( - const unsigned char *abuf, int alen, struct hostent **host, - struct ares_addrttl *addrttls, int *naddrttls); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_aaaa_reply( - const unsigned char *abuf, int alen, struct hostent **host, - struct ares_addr6ttl *addrttls, int *naddrttls); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_caa_reply( - const unsigned char *abuf, int alen, struct ares_caa_reply **caa_out); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_ptr_reply( - const unsigned char *abuf, int alen, const void *addr, int addrlen, - int family, struct hostent **host); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_ns_reply( - const unsigned char *abuf, int alen, struct hostent **host); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_srv_reply( - const unsigned char *abuf, int alen, struct ares_srv_reply **srv_out); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_mx_reply( - const unsigned char *abuf, int alen, struct ares_mx_reply **mx_out); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_txt_reply( - const unsigned char *abuf, int alen, struct ares_txt_reply **txt_out); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_txt_reply_ext( - const unsigned char *abuf, int alen, struct ares_txt_ext **txt_out); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_naptr_reply( - const unsigned char *abuf, int alen, struct ares_naptr_reply **naptr_out); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_soa_reply( - const unsigned char *abuf, int alen, struct ares_soa_reply **soa_out); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_dns_parse) int ares_parse_uri_reply( - const unsigned char *abuf, int alen, struct ares_uri_reply **uri_out); - -CARES_EXTERN void ares_free_string(void *str); - -CARES_EXTERN void ares_free_hostent(struct hostent *host); - -CARES_EXTERN void ares_free_data(void *dataptr); - -CARES_EXTERN const char *ares_strerror(int code); - -struct ares_addr_node { - struct ares_addr_node *next; - int family; - - union { - struct in_addr addr4; - struct ares_in6_addr addr6; - } addr; -}; - -struct ares_addr_port_node { - struct ares_addr_port_node *next; - int family; - - union { - struct in_addr addr4; - struct ares_in6_addr addr6; - } addr; - - int udp_port; - int tcp_port; -}; - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_set_servers_csv) int ares_set_servers( - ares_channel_t *channel, const struct ares_addr_node *servers); - -CARES_EXTERN -CARES_DEPRECATED_FOR(ares_set_servers_ports_csv) -int ares_set_servers_ports(ares_channel_t *channel, - const struct ares_addr_port_node *servers); - -/* Incoming string format: host[:port][,host[:port]]... */ -CARES_EXTERN int ares_set_servers_csv(ares_channel_t *channel, - const char *servers); -CARES_EXTERN int ares_set_servers_ports_csv(ares_channel_t *channel, - const char *servers); -CARES_EXTERN char *ares_get_servers_csv(const ares_channel_t *channel); - -CARES_EXTERN CARES_DEPRECATED_FOR(ares_get_servers_csv) int ares_get_servers( - const ares_channel_t *channel, struct ares_addr_node **servers); - -CARES_EXTERN -CARES_DEPRECATED_FOR(ares_get_servers_csv) -int ares_get_servers_ports(const ares_channel_t *channel, - struct ares_addr_port_node **servers); - -CARES_EXTERN const char *ares_inet_ntop(int af, const void *src, char *dst, - ares_socklen_t size); - -CARES_EXTERN int ares_inet_pton(int af, const char *src, void *dst); - -/*! Whether or not the c-ares library was built with threadsafety - * - * \return ARES_TRUE if built with threadsafety, ARES_FALSE if not - */ -CARES_EXTERN ares_bool_t ares_threadsafety(void); - - -/*! Block until notified that there are no longer any queries in queue, or - * the specified timeout has expired. - * - * \param[in] channel Initialized ares channel - * \param[in] timeout_ms Number of milliseconds to wait for the queue to be - * empty. -1 for Infinite. - * \return ARES_ENOTIMP if not built with threading support, ARES_ETIMEOUT - * if requested timeout expires, ARES_SUCCESS when queue is empty. - */ -CARES_EXTERN ares_status_t ares_queue_wait_empty(ares_channel_t *channel, - int timeout_ms); - - -/*! Retrieve the total number of active queries pending answers from servers. - * Some c-ares requests may spawn multiple queries, such as ares_getaddrinfo() - * when using AF_UNSPEC, which will be reflected in this number. - * - * \param[in] channel Initialized ares channel - * \return Number of active queries to servers - */ -CARES_EXTERN size_t ares_queue_active_queries(const ares_channel_t *channel); - -#ifdef __cplusplus -} -#endif - -#endif /* ARES__H */ diff --git a/vendor/c-ares/include/ares_build.h.cmake b/vendor/c-ares/include/ares_build.h.cmake deleted file mode 100644 index 2263c6c87..000000000 --- a/vendor/c-ares/include/ares_build.h.cmake +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __CARES_BUILD_H -#define __CARES_BUILD_H -/* - * Copyright (C) The c-ares project and its contributors - * SPDX-License-Identifier: MIT - */ - -#define CARES_TYPEOF_ARES_SOCKLEN_T @CARES_TYPEOF_ARES_SOCKLEN_T@ -#define CARES_TYPEOF_ARES_SSIZE_T @CARES_TYPEOF_ARES_SSIZE_T@ - -/* Prefix names with CARES_ to make sure they don't conflict with other config.h - * files. We need to include some dependent headers that may be system specific - * for C-Ares */ -#cmakedefine CARES_HAVE_SYS_TYPES_H -#cmakedefine CARES_HAVE_SYS_SOCKET_H -#cmakedefine CARES_HAVE_SYS_SELECT_H -#cmakedefine CARES_HAVE_WINDOWS_H -#cmakedefine CARES_HAVE_WS2TCPIP_H -#cmakedefine CARES_HAVE_WINSOCK2_H -#cmakedefine CARES_HAVE_ARPA_NAMESER_H -#cmakedefine CARES_HAVE_ARPA_NAMESER_COMPAT_H - -#ifdef CARES_HAVE_SYS_TYPES_H -# include -#endif - -#ifdef CARES_HAVE_SYS_SOCKET_H -# include -#endif - -#ifdef CARES_HAVE_SYS_SELECT_H -# include -#endif - -#ifdef CARES_HAVE_WINSOCK2_H -# include -#endif - -#ifdef CARES_HAVE_WS2TCPIP_H -# include -#endif - -#ifdef CARES_HAVE_WINDOWS_H -# include -#endif - -#endif /* __CARES_BUILD_H */ diff --git a/vendor/c-ares/include/ares_dns.h b/vendor/c-ares/include/ares_dns.h deleted file mode 100644 index 46edbbbc5..000000000 --- a/vendor/c-ares/include/ares_dns.h +++ /dev/null @@ -1,127 +0,0 @@ -/* MIT License - * - * Copyright (c) Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef HEADER_CARES_DNS_H -#define HEADER_CARES_DNS_H - -/* - * NOTE TO INTEGRATORS: - * - * This header is made public due to legacy projects relying on it. - * Please do not use the macros within this header, or include this - * header in your project as it may be removed in the future. - */ - - -/* - * Macro DNS__16BIT reads a network short (16 bit) given in network - * byte order, and returns its value as an unsigned short. - */ -#define DNS__16BIT(p) \ - ((unsigned short)((unsigned int)0xffff & \ - (((unsigned int)((unsigned char)(p)[0]) << 8U) | \ - ((unsigned int)((unsigned char)(p)[1]))))) - -/* - * Macro DNS__32BIT reads a network long (32 bit) given in network - * byte order, and returns its value as an unsigned int. - */ -#define DNS__32BIT(p) \ - ((unsigned int)(((unsigned int)((unsigned char)(p)[0]) << 24U) | \ - ((unsigned int)((unsigned char)(p)[1]) << 16U) | \ - ((unsigned int)((unsigned char)(p)[2]) << 8U) | \ - ((unsigned int)((unsigned char)(p)[3])))) - -#define DNS__SET16BIT(p, v) \ - (((p)[0] = (unsigned char)(((v) >> 8) & 0xff)), \ - ((p)[1] = (unsigned char)((v) & 0xff))) -#define DNS__SET32BIT(p, v) \ - (((p)[0] = (unsigned char)(((v) >> 24) & 0xff)), \ - ((p)[1] = (unsigned char)(((v) >> 16) & 0xff)), \ - ((p)[2] = (unsigned char)(((v) >> 8) & 0xff)), \ - ((p)[3] = (unsigned char)((v) & 0xff))) - -#if 0 -/* we cannot use this approach on systems where we can't access 16/32 bit - data on un-aligned addresses */ -# define DNS__16BIT(p) ntohs(*(unsigned short *)(p)) -# define DNS__32BIT(p) ntohl(*(unsigned long *)(p)) -# define DNS__SET16BIT(p, v) *(unsigned short *)(p) = htons(v) -# define DNS__SET32BIT(p, v) *(unsigned long *)(p) = htonl(v) -#endif - -/* Macros for parsing a DNS header */ -#define DNS_HEADER_QID(h) DNS__16BIT(h) -#define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1) -#define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf) -#define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1) -#define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1) -#define DNS_HEADER_RD(h) ((h)[2] & 0x1) -#define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1) -#define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7) -#define DNS_HEADER_RCODE(h) ((h)[3] & 0xf) -#define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4) -#define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6) -#define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8) -#define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10) - -/* Macros for constructing a DNS header */ -#define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v) -#define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 7)) -#define DNS_HEADER_SET_OPCODE(h, v) \ - ((h)[2] |= (unsigned char)(((v) & 0xf) << 3)) -#define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 2)) -#define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 1)) -#define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (unsigned char)((v) & 0x1)) -#define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (unsigned char)(((v) & 0x1) << 7)) -#define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (unsigned char)(((v) & 0x7) << 4)) -#define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (unsigned char)((v) & 0xf)) -#define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v) -#define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v) -#define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v) -#define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v) - -/* Macros for parsing the fixed part of a DNS question */ -#define DNS_QUESTION_TYPE(q) DNS__16BIT(q) -#define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2) - -/* Macros for constructing the fixed part of a DNS question */ -#define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v) -#define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v) - -/* Macros for parsing the fixed part of a DNS resource record */ -#define DNS_RR_TYPE(r) DNS__16BIT(r) -#define DNS_RR_CLASS(r) DNS__16BIT((r) + 2) -#define DNS_RR_TTL(r) DNS__32BIT((r) + 4) -#define DNS_RR_LEN(r) DNS__16BIT((r) + 8) - -/* Macros for constructing the fixed part of a DNS resource record */ -#define DNS_RR_SET_TYPE(r, v) DNS__SET16BIT(r, v) -#define DNS_RR_SET_CLASS(r, v) DNS__SET16BIT((r) + 2, v) -#define DNS_RR_SET_TTL(r, v) DNS__SET32BIT((r) + 4, v) -#define DNS_RR_SET_LEN(r, v) DNS__SET16BIT((r) + 8, v) - -#endif /* HEADER_CARES_DNS_H */ diff --git a/vendor/c-ares/include/ares_dns_record.h b/vendor/c-ares/include/ares_dns_record.h deleted file mode 100644 index cec9f47f6..000000000 --- a/vendor/c-ares/include/ares_dns_record.h +++ /dev/null @@ -1,1118 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_DNS_RECORD_H -#define __ARES_DNS_RECORD_H - -/* Include ares.h, not this file directly */ - -#ifdef __cplusplus -extern "C" { -#endif - -/*! \addtogroup ares_dns_record DNS Record Handling - * - * This is a set of functions to create and manipulate DNS records. - * - * @{ - */ - -/*! DNS Record types handled by c-ares. Some record types may only be valid - * on requests (e.g. ARES_REC_TYPE_ANY), and some may only be valid on - * responses */ -typedef enum { - ARES_REC_TYPE_A = 1, /*!< Host address. */ - ARES_REC_TYPE_NS = 2, /*!< Authoritative server. */ - ARES_REC_TYPE_CNAME = 5, /*!< Canonical name. */ - ARES_REC_TYPE_SOA = 6, /*!< Start of authority zone. */ - ARES_REC_TYPE_PTR = 12, /*!< Domain name pointer. */ - ARES_REC_TYPE_HINFO = 13, /*!< Host information. */ - ARES_REC_TYPE_MX = 15, /*!< Mail routing information. */ - ARES_REC_TYPE_TXT = 16, /*!< Text strings. */ - ARES_REC_TYPE_SIG = 24, /*!< RFC 2535 / RFC 2931. SIG Record */ - ARES_REC_TYPE_AAAA = 28, /*!< RFC 3596. Ip6 Address. */ - ARES_REC_TYPE_SRV = 33, /*!< RFC 2782. Server Selection. */ - ARES_REC_TYPE_NAPTR = 35, /*!< RFC 3403. Naming Authority Pointer */ - ARES_REC_TYPE_OPT = 41, /*!< RFC 6891. EDNS0 option (meta-RR) */ - - ARES_REC_TYPE_TLSA = 52, /*!< RFC 6698. DNS-Based Authentication of Named - * Entities (DANE) Transport Layer Security - * (TLS) Protocol: TLSA */ - ARES_REC_TYPE_SVCB = 64, /*!< RFC 9460. General Purpose Service Binding */ - ARES_REC_TYPE_HTTPS = 65, /*!< RFC 9460. Service Binding type for use with - * HTTPS */ - ARES_REC_TYPE_ANY = 255, /*!< Wildcard match. Not response RR. */ - ARES_REC_TYPE_URI = 256, /*!< RFC 7553. Uniform Resource Identifier */ - ARES_REC_TYPE_CAA = 257, /*!< RFC 6844. Certification Authority - * Authorization. */ - ARES_REC_TYPE_RAW_RR = 65536 /*!< Used as an indicator that the RR record - * is not parsed, but provided in wire - * format */ -} ares_dns_rec_type_t; - -/*! DNS Classes for requests and responses. */ -typedef enum { - ARES_CLASS_IN = 1, /*!< Internet */ - ARES_CLASS_CHAOS = 3, /*!< CHAOS */ - ARES_CLASS_HESOID = 4, /*!< Hesoid [Dyer 87] */ - ARES_CLASS_NONE = 254, /*!< RFC 2136 */ - ARES_CLASS_ANY = 255 /*!< Any class (requests only) */ -} ares_dns_class_t; - -/*! DNS RR Section type */ -typedef enum { - ARES_SECTION_ANSWER = 1, /*!< Answer section */ - ARES_SECTION_AUTHORITY = 2, /*!< Authority section */ - ARES_SECTION_ADDITIONAL = 3 /*!< Additional information section */ -} ares_dns_section_t; - -/*! DNS Header opcodes */ -typedef enum { - ARES_OPCODE_QUERY = 0, /*!< Standard query */ - ARES_OPCODE_IQUERY = 1, /*!< Inverse query. Obsolete. */ - ARES_OPCODE_STATUS = 2, /*!< Name server status query */ - ARES_OPCODE_NOTIFY = 4, /*!< Zone change notification (RFC 1996) */ - ARES_OPCODE_UPDATE = 5 /*!< Zone update message (RFC2136) */ -} ares_dns_opcode_t; - -/*! DNS Header flags */ -typedef enum { - ARES_FLAG_QR = 1 << 0, /*!< QR. If set, is a response */ - ARES_FLAG_AA = 1 << 1, /*!< Authoritative Answer. If set, is authoritative */ - ARES_FLAG_TC = 1 << 2, /*!< Truncation. If set, is truncated response */ - ARES_FLAG_RD = 1 << 3, /*!< Recursion Desired. If set, recursion is desired */ - ARES_FLAG_RA = 1 << 4, /*!< Recursion Available. If set, server supports - * recursion */ - ARES_FLAG_AD = 1 << 5, /*!< RFC 2065. Authentic Data bit indicates in a - * response that the data included has been verified by - * the server providing it */ - ARES_FLAG_CD = 1 << 6 /*!< RFC 2065. Checking Disabled bit indicates in a - * query that non-verified data is acceptable to the - * resolver sending the query. */ -} ares_dns_flags_t; - -/*! DNS Response Codes from server */ -typedef enum { - ARES_RCODE_NOERROR = 0, /*!< Success */ - ARES_RCODE_FORMERR = 1, /*!< Format error. The name server was unable - * to interpret the query. */ - ARES_RCODE_SERVFAIL = 2, /*!< Server Failure. The name server was - * unable to process this query due to a - * problem with the nameserver */ - ARES_RCODE_NXDOMAIN = 3, /*!< Name Error. Meaningful only for - * responses from an authoritative name - * server, this code signifies that the - * domain name referenced in the query does - * not exist. */ - ARES_RCODE_NOTIMP = 4, /*!< Not implemented. The name server does - * not support the requested kind of - * query */ - ARES_RCODE_REFUSED = 5, /*!< Refused. The name server refuses to - * perform the specified operation for - * policy reasons. */ - ARES_RCODE_YXDOMAIN = 6, /*!< RFC 2136. Some name that ought not to - * exist, does exist. */ - ARES_RCODE_YXRRSET = 7, /*!< RFC 2136. Some RRset that ought to not - * exist, does exist. */ - ARES_RCODE_NXRRSET = 8, /*!< RFC 2136. Some RRset that ought to exist, - * does not exist. */ - ARES_RCODE_NOTAUTH = 9, /*!< RFC 2136. The server is not authoritative - * for the zone named in the Zone section. - */ - ARES_RCODE_NOTZONE = 10, /*!< RFC 2136. A name used in the Prerequisite - * or Update Section is not within the zone - * denoted by the Zone Section. */ - ARES_RCODE_DSOTYPEI = 11, /*!< RFC 8409. DSO-TYPE Not implemented */ - ARES_RCODE_BADSIG = 16, /*!< RFC 8945. TSIG Signature Failure */ - ARES_RCODE_BADKEY = 17, /*!< RFC 8945. Key not recognized. */ - ARES_RCODE_BADTIME = 18, /*!< RFC 8945. Signature out of time window. */ - ARES_RCODE_BADMODE = 19, /*!< RFC 2930. Bad TKEY Mode */ - ARES_RCODE_BADNAME = 20, /*!< RFC 2930. Duplicate Key Name */ - ARES_RCODE_BADALG = 21, /*!< RFC 2930. Algorithm not supported */ - ARES_RCODE_BADTRUNC = 22, /*!< RFC 8945. Bad Truncation */ - ARES_RCODE_BADCOOKIE = 23 /*!< RFC 7873. Bad/missing Server Cookie */ -} ares_dns_rcode_t; - -/*! Data types used */ -typedef enum { - ARES_DATATYPE_INADDR = 1, /*!< struct in_addr * type */ - ARES_DATATYPE_INADDR6 = 2, /*!< struct ares_in6_addr * type */ - ARES_DATATYPE_U8 = 3, /*!< 8bit unsigned integer */ - ARES_DATATYPE_U16 = 4, /*!< 16bit unsigned integer */ - ARES_DATATYPE_U32 = 5, /*!< 32bit unsigned integer */ - ARES_DATATYPE_NAME = 6, /*!< Null-terminated string of a domain name */ - ARES_DATATYPE_STR = 7, /*!< Null-terminated string */ - ARES_DATATYPE_BIN = 8, /*!< Binary data */ - ARES_DATATYPE_BINP = 9, /*!< Officially defined as binary data, but likely - * printable. Guaranteed to have a NULL - * terminator for convenience (not included in - * length) */ - ARES_DATATYPE_OPT = 10, /*!< Array of options. 16bit identifier, BIN - * data. */ - ARES_DATATYPE_ABINP = 11 /*!< Array of binary data, likely printable. - * Guaranteed to have a NULL terminator for - * convenience (not included in length) */ -} ares_dns_datatype_t; - -/*! Keys used for all RR Types. We take the record type and multiply by 100 - * to ensure we have a proper offset between keys so we can keep these sorted - */ -typedef enum { - /*! A Record. Address. Datatype: INADDR */ - ARES_RR_A_ADDR = (ARES_REC_TYPE_A * 100) + 1, - /*! NS Record. Name. Datatype: NAME */ - ARES_RR_NS_NSDNAME = (ARES_REC_TYPE_NS * 100) + 1, - /*! CNAME Record. CName. Datatype: NAME */ - ARES_RR_CNAME_CNAME = (ARES_REC_TYPE_CNAME * 100) + 1, - /*! SOA Record. MNAME, Primary Source of Data. Datatype: NAME */ - ARES_RR_SOA_MNAME = (ARES_REC_TYPE_SOA * 100) + 1, - /*! SOA Record. RNAME, Mailbox of person responsible. Datatype: NAME */ - ARES_RR_SOA_RNAME = (ARES_REC_TYPE_SOA * 100) + 2, - /*! SOA Record. Serial, version. Datatype: U32 */ - ARES_RR_SOA_SERIAL = (ARES_REC_TYPE_SOA * 100) + 3, - /*! SOA Record. Refresh, zone refersh interval. Datatype: U32 */ - ARES_RR_SOA_REFRESH = (ARES_REC_TYPE_SOA * 100) + 4, - /*! SOA Record. Retry, failed refresh retry interval. Datatype: U32 */ - ARES_RR_SOA_RETRY = (ARES_REC_TYPE_SOA * 100) + 5, - /*! SOA Record. Expire, upper limit on authority. Datatype: U32 */ - ARES_RR_SOA_EXPIRE = (ARES_REC_TYPE_SOA * 100) + 6, - /*! SOA Record. Minimum, RR TTL. Datatype: U32 */ - ARES_RR_SOA_MINIMUM = (ARES_REC_TYPE_SOA * 100) + 7, - /*! PTR Record. DNAME, pointer domain. Datatype: NAME */ - ARES_RR_PTR_DNAME = (ARES_REC_TYPE_PTR * 100) + 1, - /*! HINFO Record. CPU. Datatype: STR */ - ARES_RR_HINFO_CPU = (ARES_REC_TYPE_HINFO * 100) + 1, - /*! HINFO Record. OS. Datatype: STR */ - ARES_RR_HINFO_OS = (ARES_REC_TYPE_HINFO * 100) + 2, - /*! MX Record. Preference. Datatype: U16 */ - ARES_RR_MX_PREFERENCE = (ARES_REC_TYPE_MX * 100) + 1, - /*! MX Record. Exchange, domain. Datatype: NAME */ - ARES_RR_MX_EXCHANGE = (ARES_REC_TYPE_MX * 100) + 2, - /*! TXT Record. Data. Datatype: ABINP */ - ARES_RR_TXT_DATA = (ARES_REC_TYPE_TXT * 100) + 1, - /*! SIG Record. Type Covered. Datatype: U16 */ - ARES_RR_SIG_TYPE_COVERED = (ARES_REC_TYPE_SIG * 100) + 1, - /*! SIG Record. Algorithm. Datatype: U8 */ - ARES_RR_SIG_ALGORITHM = (ARES_REC_TYPE_SIG * 100) + 2, - /*! SIG Record. Labels. Datatype: U8 */ - ARES_RR_SIG_LABELS = (ARES_REC_TYPE_SIG * 100) + 3, - /*! SIG Record. Original TTL. Datatype: U32 */ - ARES_RR_SIG_ORIGINAL_TTL = (ARES_REC_TYPE_SIG * 100) + 4, - /*! SIG Record. Signature Expiration. Datatype: U32 */ - ARES_RR_SIG_EXPIRATION = (ARES_REC_TYPE_SIG * 100) + 5, - /*! SIG Record. Signature Inception. Datatype: U32 */ - ARES_RR_SIG_INCEPTION = (ARES_REC_TYPE_SIG * 100) + 6, - /*! SIG Record. Key Tag. Datatype: U16 */ - ARES_RR_SIG_KEY_TAG = (ARES_REC_TYPE_SIG * 100) + 7, - /*! SIG Record. Signers Name. Datatype: NAME */ - ARES_RR_SIG_SIGNERS_NAME = (ARES_REC_TYPE_SIG * 100) + 8, - /*! SIG Record. Signature. Datatype: BIN */ - ARES_RR_SIG_SIGNATURE = (ARES_REC_TYPE_SIG * 100) + 9, - /*! AAAA Record. Address. Datatype: INADDR6 */ - ARES_RR_AAAA_ADDR = (ARES_REC_TYPE_AAAA * 100) + 1, - /*! SRV Record. Priority. Datatype: U16 */ - ARES_RR_SRV_PRIORITY = (ARES_REC_TYPE_SRV * 100) + 2, - /*! SRV Record. Weight. Datatype: U16 */ - ARES_RR_SRV_WEIGHT = (ARES_REC_TYPE_SRV * 100) + 3, - /*! SRV Record. Port. Datatype: U16 */ - ARES_RR_SRV_PORT = (ARES_REC_TYPE_SRV * 100) + 4, - /*! SRV Record. Target domain. Datatype: NAME */ - ARES_RR_SRV_TARGET = (ARES_REC_TYPE_SRV * 100) + 5, - /*! NAPTR Record. Order. Datatype: U16 */ - ARES_RR_NAPTR_ORDER = (ARES_REC_TYPE_NAPTR * 100) + 1, - /*! NAPTR Record. Preference. Datatype: U16 */ - ARES_RR_NAPTR_PREFERENCE = (ARES_REC_TYPE_NAPTR * 100) + 2, - /*! NAPTR Record. Flags. Datatype: STR */ - ARES_RR_NAPTR_FLAGS = (ARES_REC_TYPE_NAPTR * 100) + 3, - /*! NAPTR Record. Services. Datatype: STR */ - ARES_RR_NAPTR_SERVICES = (ARES_REC_TYPE_NAPTR * 100) + 4, - /*! NAPTR Record. Regexp. Datatype: STR */ - ARES_RR_NAPTR_REGEXP = (ARES_REC_TYPE_NAPTR * 100) + 5, - /*! NAPTR Record. Replacement. Datatype: NAME */ - ARES_RR_NAPTR_REPLACEMENT = (ARES_REC_TYPE_NAPTR * 100) + 6, - /*! OPT Record. UDP Size. Datatype: U16 */ - ARES_RR_OPT_UDP_SIZE = (ARES_REC_TYPE_OPT * 100) + 1, - /*! OPT Record. Version. Datatype: U8 */ - ARES_RR_OPT_VERSION = (ARES_REC_TYPE_OPT * 100) + 3, - /*! OPT Record. Flags. Datatype: U16 */ - ARES_RR_OPT_FLAGS = (ARES_REC_TYPE_OPT * 100) + 4, - /*! OPT Record. Options. Datatype: OPT */ - ARES_RR_OPT_OPTIONS = (ARES_REC_TYPE_OPT * 100) + 5, - /*! TLSA Record. Certificate Usage. Datatype: U8 */ - ARES_RR_TLSA_CERT_USAGE = (ARES_REC_TYPE_TLSA * 100) + 1, - /*! TLSA Record. Selector. Datatype: U8 */ - ARES_RR_TLSA_SELECTOR = (ARES_REC_TYPE_TLSA * 100) + 2, - /*! TLSA Record. Matching Type. Datatype: U8 */ - ARES_RR_TLSA_MATCH = (ARES_REC_TYPE_TLSA * 100) + 3, - /*! TLSA Record. Certificate Association Data. Datatype: BIN */ - ARES_RR_TLSA_DATA = (ARES_REC_TYPE_TLSA * 100) + 4, - /*! SVCB Record. SvcPriority. Datatype: U16 */ - ARES_RR_SVCB_PRIORITY = (ARES_REC_TYPE_SVCB * 100) + 1, - /*! SVCB Record. TargetName. Datatype: NAME */ - ARES_RR_SVCB_TARGET = (ARES_REC_TYPE_SVCB * 100) + 2, - /*! SVCB Record. SvcParams. Datatype: OPT */ - ARES_RR_SVCB_PARAMS = (ARES_REC_TYPE_SVCB * 100) + 3, - /*! HTTPS Record. SvcPriority. Datatype: U16 */ - ARES_RR_HTTPS_PRIORITY = (ARES_REC_TYPE_HTTPS * 100) + 1, - /*! HTTPS Record. TargetName. Datatype: NAME */ - ARES_RR_HTTPS_TARGET = (ARES_REC_TYPE_HTTPS * 100) + 2, - /*! HTTPS Record. SvcParams. Datatype: OPT */ - ARES_RR_HTTPS_PARAMS = (ARES_REC_TYPE_HTTPS * 100) + 3, - /*! URI Record. Priority. Datatype: U16 */ - ARES_RR_URI_PRIORITY = (ARES_REC_TYPE_URI * 100) + 1, - /*! URI Record. Weight. Datatype: U16 */ - ARES_RR_URI_WEIGHT = (ARES_REC_TYPE_URI * 100) + 2, - /*! URI Record. Target domain. Datatype: NAME */ - ARES_RR_URI_TARGET = (ARES_REC_TYPE_URI * 100) + 3, - /*! CAA Record. Critical flag. Datatype: U8 */ - ARES_RR_CAA_CRITICAL = (ARES_REC_TYPE_CAA * 100) + 1, - /*! CAA Record. Tag/Property. Datatype: STR */ - ARES_RR_CAA_TAG = (ARES_REC_TYPE_CAA * 100) + 2, - /*! CAA Record. Value. Datatype: BINP */ - ARES_RR_CAA_VALUE = (ARES_REC_TYPE_CAA * 100) + 3, - /*! RAW Record. RR Type. Datatype: U16 */ - ARES_RR_RAW_RR_TYPE = (ARES_REC_TYPE_RAW_RR * 100) + 1, - /*! RAW Record. RR Data. Datatype: BIN */ - ARES_RR_RAW_RR_DATA = (ARES_REC_TYPE_RAW_RR * 100) + 2 -} ares_dns_rr_key_t; - -/*! TLSA Record ARES_RR_TLSA_CERT_USAGE known values */ -typedef enum { - /*! Certificate Usage 0. CA Constraint. */ - ARES_TLSA_USAGE_CA = 0, - /*! Certificate Usage 1. Service Certificate Constraint. */ - ARES_TLSA_USAGE_SERVICE = 1, - /*! Certificate Usage 2. Trust Anchor Assertion. */ - ARES_TLSA_USAGE_TRUSTANCHOR = 2, - /*! Certificate Usage 3. Domain-issued certificate. */ - ARES_TLSA_USAGE_DOMAIN = 3 -} ares_tlsa_usage_t; - -/*! TLSA Record ARES_RR_TLSA_SELECTOR known values */ -typedef enum { - /*! Full Certificate */ - ARES_TLSA_SELECTOR_FULL = 0, - /*! DER-encoded SubjectPublicKeyInfo */ - ARES_TLSA_SELECTOR_SUBJPUBKEYINFO = 1 -} ares_tlsa_selector_t; - -/*! TLSA Record ARES_RR_TLSA_MATCH known values */ -typedef enum { - /*! Exact match */ - ARES_TLSA_MATCH_EXACT = 0, - /*! Sha256 match */ - ARES_TLSA_MATCH_SHA256 = 1, - /*! Sha512 match */ - ARES_TLSA_MATCH_SHA512 = 2 -} ares_tlsa_match_t; - -/*! SVCB (and HTTPS) RR known parameters */ -typedef enum { - /*! Mandatory keys in this RR (RFC 9460 Section 8) */ - ARES_SVCB_PARAM_MANDATORY = 0, - /*! Additional supported protocols (RFC 9460 Section 7.1) */ - ARES_SVCB_PARAM_ALPN = 1, - /*! No support for default protocol (RFC 9460 Section 7.1) */ - ARES_SVCB_PARAM_NO_DEFAULT_ALPN = 2, - /*! Port for alternative endpoint (RFC 9460 Section 7.2) */ - ARES_SVCB_PARAM_PORT = 3, - /*! IPv4 address hints (RFC 9460 Section 7.3) */ - ARES_SVCB_PARAM_IPV4HINT = 4, - /*! RESERVED (held for Encrypted ClientHello) */ - ARES_SVCB_PARAM_ECH = 5, - /*! IPv6 address hints (RFC 9460 Section 7.3) */ - ARES_SVCB_PARAM_IPV6HINT = 6 -} ares_svcb_param_t; - -/*! OPT RR known parameters */ -typedef enum { - /*! RFC 8764. Apple's DNS Long-Lived Queries Protocol */ - ARES_OPT_PARAM_LLQ = 1, - /*! http://files.dns-sd.org/draft-sekar-dns-ul.txt: Update Lease */ - ARES_OPT_PARAM_UL = 2, - /*! RFC 5001. Name Server Identification */ - ARES_OPT_PARAM_NSID = 3, - /*! RFC 6975. DNSSEC Algorithm Understood */ - ARES_OPT_PARAM_DAU = 5, - /*! RFC 6975. DS Hash Understood */ - ARES_OPT_PARAM_DHU = 6, - /*! RFC 6975. NSEC3 Hash Understood */ - ARES_OPT_PARAM_N3U = 7, - /*! RFC 7871. Client Subnet */ - ARES_OPT_PARAM_EDNS_CLIENT_SUBNET = 8, - /*! RFC 7314. Expire Timer */ - ARES_OPT_PARAM_EDNS_EXPIRE = 9, - /*! RFC 7873. Client and Server Cookies */ - ARES_OPT_PARAM_COOKIE = 10, - /*! RFC 7828. TCP Keepalive timeout */ - ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE = 11, - /*! RFC 7830. Padding */ - ARES_OPT_PARAM_PADDING = 12, - /*! RFC 7901. Chain query requests */ - ARES_OPT_PARAM_CHAIN = 13, - /*! RFC 8145. Signaling Trust Anchor Knowledge in DNSSEC */ - ARES_OPT_PARAM_EDNS_KEY_TAG = 14, - /*! RFC 8914. Extended ERROR code and message */ - ARES_OPT_PARAM_EXTENDED_DNS_ERROR = 15 -} ares_opt_param_t; - -/*! Data type for option records for keys like ARES_RR_OPT_OPTIONS and - * ARES_RR_HTTPS_PARAMS returned by ares_dns_opt_get_datatype() */ -typedef enum { - /*! No value allowed for this option */ - ARES_OPT_DATATYPE_NONE = 1, - /*! List of strings, each prefixed with a single octet representing the length - */ - ARES_OPT_DATATYPE_STR_LIST = 2, - /*! List of 8bit integers, concatenated */ - ARES_OPT_DATATYPE_U8_LIST = 3, - /*! 16bit integer in network byte order */ - ARES_OPT_DATATYPE_U16 = 4, - /*! list of 16bit integer in network byte order, concatenated. */ - ARES_OPT_DATATYPE_U16_LIST = 5, - /*! 32bit integer in network byte order */ - ARES_OPT_DATATYPE_U32 = 6, - /*! list 32bit integer in network byte order, concatenated */ - ARES_OPT_DATATYPE_U32_LIST = 7, - /*! List of ipv4 addresses in network byte order, concatenated */ - ARES_OPT_DATATYPE_INADDR4_LIST = 8, - /*! List of ipv6 addresses in network byte order, concatenated */ - ARES_OPT_DATATYPE_INADDR6_LIST = 9, - /*! Binary Data */ - ARES_OPT_DATATYPE_BIN = 10, - /*! DNS Domain Name Format */ - ARES_OPT_DATATYPE_NAME = 11 -} ares_dns_opt_datatype_t; - -/*! Data type for flags to ares_dns_parse() */ -typedef enum { - /*! Parse Answers from RFC 1035 that allow name compression as RAW */ - ARES_DNS_PARSE_AN_BASE_RAW = 1 << 0, - /*! Parse Authority from RFC 1035 that allow name compression as RAW */ - ARES_DNS_PARSE_NS_BASE_RAW = 1 << 1, - /*! Parse Additional from RFC 1035 that allow name compression as RAW */ - ARES_DNS_PARSE_AR_BASE_RAW = 1 << 2, - /*! Parse Answers from later RFCs (no name compression) RAW */ - ARES_DNS_PARSE_AN_EXT_RAW = 1 << 3, - /*! Parse Authority from later RFCs (no name compression) as RAW */ - ARES_DNS_PARSE_NS_EXT_RAW = 1 << 4, - /*! Parse Additional from later RFCs (no name compression) as RAW */ - ARES_DNS_PARSE_AR_EXT_RAW = 1 << 5 -} ares_dns_parse_flags_t; - -/*! String representation of DNS Record Type - * - * \param[in] type DNS Record Type - * \return string - */ -CARES_EXTERN const char *ares_dns_rec_type_tostr(ares_dns_rec_type_t type); - -/*! String representation of DNS Class - * - * \param[in] qclass DNS Class - * \return string - */ -CARES_EXTERN const char *ares_dns_class_tostr(ares_dns_class_t qclass); - -/*! String representation of DNS OpCode - * - * \param[in] opcode DNS OpCode - * \return string - */ -CARES_EXTERN const char *ares_dns_opcode_tostr(ares_dns_opcode_t opcode); - -/*! String representation of DNS Resource Record Parameter - * - * \param[in] key DNS Resource Record parameter - * \return string - */ -CARES_EXTERN const char *ares_dns_rr_key_tostr(ares_dns_rr_key_t key); - -/*! String representation of DNS Resource Record section - * - * \param[in] section Section - * \return string - */ -CARES_EXTERN const char *ares_dns_section_tostr(ares_dns_section_t section); - -/*! Convert DNS class name as string to ares_dns_class_t - * - * \param[out] qclass Pointer passed by reference to write class - * \param[in] str String to convert - * \return ARES_TRUE on success - */ -CARES_EXTERN ares_bool_t ares_dns_class_fromstr(ares_dns_class_t *qclass, - const char *str); - -/*! Convert DNS record type as string to ares_dns_rec_type_t - * - * \param[out] qtype Pointer passed by reference to write record type - * \param[in] str String to convert - * \return ARES_TRUE on success - */ -CARES_EXTERN ares_bool_t ares_dns_rec_type_fromstr(ares_dns_rec_type_t *qtype, - const char *str); - - -/*! Convert DNS response code as string to from ares_dns_rcode_t - * - * \param[in] rcode Response code to convert - * \return ARES_TRUE on success - */ -CARES_EXTERN const char *ares_dns_rcode_tostr(ares_dns_rcode_t rcode); - -/*! Convert any valid ip address (ipv4 or ipv6) into struct ares_addr and - * return the starting pointer of the network byte order address and the - * length of the address (4 or 16). - * - * \param[in] ipaddr ASCII string form of the ip address - * \param[in,out] addr Must set "family" member to one of AF_UNSPEC, - * AF_INET, AF_INET6 on input. - * \param[out] out_len Length of binary form address - * \return Pointer to start of binary address or NULL on error. - */ -CARES_EXTERN const void *ares_dns_pton(const char *ipaddr, - struct ares_addr *addr, size_t *out_len); - -/*! Convert an ip address into the PTR format for in-addr.arpa or in6.arpa - * - * \param[in] addr properly filled address structure - * \return String representing PTR, use ares_free_string() to free - */ -CARES_EXTERN char *ares_dns_addr_to_ptr(const struct ares_addr *addr); - - -/*! The options/parameters extensions to some RRs can be somewhat opaque, this - * is a helper to return the best match for a datatype for interpreting the - * option record. - * - * \param[in] key Key associated with options/parameters - * \param[in] opt Option Key/Parameter - * \return Datatype - */ -CARES_EXTERN ares_dns_opt_datatype_t - ares_dns_opt_get_datatype(ares_dns_rr_key_t key, unsigned short opt); - -/*! The options/parameters extensions to some RRs can be somewhat opaque, this - * is a helper to return the name if the option is known. - * - * \param[in] key Key associated with options/parameters - * \param[in] opt Option Key/Parameter - * \return name, or NULL if not known. - */ -CARES_EXTERN const char *ares_dns_opt_get_name(ares_dns_rr_key_t key, - unsigned short opt); - - -/*! Retrieve a list of Resource Record keys that can be set or retrieved for - * the Resource record type. - * - * \param[in] type Record Type - * \param[out] cnt Number of keys returned - * \return array of keys associated with Resource Record - */ -CARES_EXTERN const ares_dns_rr_key_t * - ares_dns_rr_get_keys(ares_dns_rec_type_t type, size_t *cnt); - -/*! Retrieve the datatype associated with a Resource Record key. - * - * \param[in] key Resource Record Key - * \return datatype - */ -CARES_EXTERN ares_dns_datatype_t - ares_dns_rr_key_datatype(ares_dns_rr_key_t key); - -/*! Retrieve the DNS Resource Record type associated with a Resource Record key. - * - * \param[in] key Resource Record Key - * \return DNS Resource Record Type - */ -CARES_EXTERN ares_dns_rec_type_t - ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key); - -/*! Opaque data type representing a DNS RR (Resource Record) */ -struct ares_dns_rr; - -/*! Typedef for opaque data type representing a DNS RR (Resource Record) */ -typedef struct ares_dns_rr ares_dns_rr_t; - -/*! Opaque data type representing a DNS Query Data QD Packet */ -struct ares_dns_qd; - -/*! Typedef for opaque data type representing a DNS Query Data QD Packet */ -typedef struct ares_dns_qd ares_dns_qd_t; - -/*! Opaque data type representing a DNS Packet */ -struct ares_dns_record; - -/*! Typedef for opaque data type representing a DNS Packet */ -typedef struct ares_dns_record ares_dns_record_t; - - -/*! Create a new DNS record object - * - * \param[out] dnsrec Pointer passed by reference for a newly allocated - * record object. Must be ares_dns_record_destroy()'d by - * caller. - * \param[in] id DNS Query ID. If structuring a new query to be sent - * with ares_send(), this value should be zero. - * \param[in] flags DNS Flags from \ares_dns_flags_t - * \param[in] opcode DNS OpCode (typically ARES_OPCODE_QUERY) - * \param[in] rcode DNS RCode - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_record_create(ares_dns_record_t **dnsrec, - unsigned short id, - unsigned short flags, - ares_dns_opcode_t opcode, - ares_dns_rcode_t rcode); - -/*! Destroy a DNS record object - * - * \param[in] dnsrec Initialized record object - */ -CARES_EXTERN void ares_dns_record_destroy(ares_dns_record_t *dnsrec); - -/*! Get the DNS Query ID - * - * \param[in] dnsrec Initialized record object - * \return DNS query id - */ -CARES_EXTERN unsigned short - ares_dns_record_get_id(const ares_dns_record_t *dnsrec); - -/*! Overwrite the DNS query id - * - * \param[in] dnsrec Initialized record object - * \param[in] id DNS query id - * \return ARES_TRUE on success, ARES_FALSE on usage error - */ -CARES_EXTERN ares_bool_t ares_dns_record_set_id(ares_dns_record_t *dnsrec, - unsigned short id); - -/*! Get the DNS Record Flags - * - * \param[in] dnsrec Initialized record object - * \return One or more \ares_dns_flags_t - */ -CARES_EXTERN unsigned short - ares_dns_record_get_flags(const ares_dns_record_t *dnsrec); - -/*! Get the DNS Record OpCode - * - * \param[in] dnsrec Initialized record object - * \return opcode - */ -CARES_EXTERN ares_dns_opcode_t - ares_dns_record_get_opcode(const ares_dns_record_t *dnsrec); - -/*! Get the DNS Record RCode - * - * \param[in] dnsrec Initialized record object - * \return rcode - */ -CARES_EXTERN ares_dns_rcode_t - ares_dns_record_get_rcode(const ares_dns_record_t *dnsrec); - -/*! Add a query to the DNS Record. Typically a record will have only 1 - * query. Most DNS servers will reject queries with more than 1 question. - * - * \param[in] dnsrec Initialized record object - * \param[in] name Name/Hostname of request - * \param[in] qtype Type of query - * \param[in] qclass Class of query (typically ARES_CLASS_IN) - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_record_query_add(ares_dns_record_t *dnsrec, - const char *name, - ares_dns_rec_type_t qtype, - ares_dns_class_t qclass); - -/*! Replace the question name with a new name. This may be used when performing - * a search with aliases. - * - * Note that this will invalidate the name pointer returned from - * ares_dns_record_query_get(). - * - * \param[in] dnsrec Initialized record object - * \param[in] idx Index of question (typically 0) - * \param[in] name Name to use as replacement. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_record_query_set_name( - ares_dns_record_t *dnsrec, size_t idx, const char *name); - - -/*! Replace the question type with a different type. This may be used when - * needing to query more than one address class (e.g. A and AAAA) - * - * \param[in] dnsrec Initialized record object - * \param[in] idx Index of question (typically 0) - * \param[in] qtype Record Type to use as replacement. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_record_query_set_type( - ares_dns_record_t *dnsrec, size_t idx, ares_dns_rec_type_t qtype); - -/*! Get the count of queries in the DNS Record - * - * \param[in] dnsrec Initialized record object - * \return count of queries - */ -CARES_EXTERN size_t ares_dns_record_query_cnt(const ares_dns_record_t *dnsrec); - -/*! Get the data about the query at the provided index. - * - * \param[in] dnsrec Initialized record object - * \param[in] idx Index of query - * \param[out] name Optional. Returns name, may pass NULL if not desired. - * This pointer will be invalided by any call to - * ares_dns_record_query_set_name(). - * \param[out] qtype Optional. Returns record type, may pass NULL. - * \param[out] qclass Optional. Returns class, may pass NULL. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_record_query_get( - const ares_dns_record_t *dnsrec, size_t idx, const char **name, - ares_dns_rec_type_t *qtype, ares_dns_class_t *qclass); - -/*! Get the count of Resource Records in the provided section - * - * \param[in] dnsrec Initialized record object - * \param[in] sect Section. ARES_SECTION_ANSWER is most used. - * \return count of resource records. - */ -CARES_EXTERN size_t ares_dns_record_rr_cnt(const ares_dns_record_t *dnsrec, - ares_dns_section_t sect); - - -/*! Add a Resource Record to the DNS Record. - * - * \param[out] rr_out Pointer to created resource record. This pointer - * is owned by the DNS record itself, this is just made - * available to facilitate adding RR-specific fields. - * \param[in] dnsrec Initialized record object - * \param[in] sect Section to add resource record to - * \param[in] name Resource Record name/hostname - * \param[in] type Record Type - * \param[in] rclass Class - * \param[in] ttl TTL - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_record_rr_add( - ares_dns_rr_t **rr_out, ares_dns_record_t *dnsrec, ares_dns_section_t sect, - const char *name, ares_dns_rec_type_t type, ares_dns_class_t rclass, - unsigned int ttl); - -/*! Fetch a writable resource record based on the section and index. - * - * \param[in] dnsrec Initialized record object - * \param[in] sect Section for resource record - * \param[in] idx Index of resource record in section - * \return NULL on misuse, otherwise a writable pointer to the resource record - */ -CARES_EXTERN ares_dns_rr_t *ares_dns_record_rr_get(ares_dns_record_t *dnsrec, - ares_dns_section_t sect, - size_t idx); - -/*! Fetch a non-writeable resource record based on the section and index. - * - * \param[in] dnsrec Initialized record object - * \param[in] sect Section for resource record - * \param[in] idx Index of resource record in section - * \return NULL on misuse, otherwise a const pointer to the resource record - */ -CARES_EXTERN const ares_dns_rr_t * - ares_dns_record_rr_get_const(const ares_dns_record_t *dnsrec, - ares_dns_section_t sect, size_t idx); - - -/*! Remove the resource record based on the section and index - * - * \param[in] dnsrec Initialized record object - * \param[in] sect Section for resource record - * \param[in] idx Index of resource record in section - * \return ARES_SUCCESS on success, otherwise an error code. - */ -CARES_EXTERN ares_status_t ares_dns_record_rr_del(ares_dns_record_t *dnsrec, - ares_dns_section_t sect, - size_t idx); - - -/*! Retrieve the resource record Name/Hostname - * - * \param[in] rr Pointer to resource record - * \return Name - */ -CARES_EXTERN const char *ares_dns_rr_get_name(const ares_dns_rr_t *rr); - -/*! Retrieve the resource record type - * - * \param[in] rr Pointer to resource record - * \return type - */ -CARES_EXTERN ares_dns_rec_type_t ares_dns_rr_get_type(const ares_dns_rr_t *rr); - -/*! Retrieve the resource record class - * - * \param[in] rr Pointer to resource record - * \return class - */ -CARES_EXTERN ares_dns_class_t ares_dns_rr_get_class(const ares_dns_rr_t *rr); - -/*! Retrieve the resource record TTL - * - * \param[in] rr Pointer to resource record - * \return TTL - */ -CARES_EXTERN unsigned int ares_dns_rr_get_ttl(const ares_dns_rr_t *rr); - -/*! Set ipv4 address data type for specified resource record and key. Can - * only be used on keys with datatype ARES_DATATYPE_INADDR - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] addr Pointer to ipv4 address to use. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_set_addr(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - const struct in_addr *addr); - -/*! Set ipv6 address data type for specified resource record and key. Can - * only be used on keys with datatype ARES_DATATYPE_INADDR6 - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] addr Pointer to ipv6 address to use. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t - ares_dns_rr_set_addr6(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - const struct ares_in6_addr *addr); - -/*! Set string data for specified resource record and key. Can - * only be used on keys with datatype ARES_DATATYPE_STR or ARES_DATATYPE_NAME. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] val Pointer to string to set. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_set_str(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - const char *val); - -/*! Set 8bit unsigned integer for specified resource record and key. Can - * only be used on keys with datatype ARES_DATATYPE_U8 - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] val 8bit unsigned integer - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_set_u8(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - unsigned char val); - -/*! Set 16bit unsigned integer for specified resource record and key. Can - * only be used on keys with datatype ARES_DATATYPE_U16 - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] val 16bit unsigned integer - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_set_u16(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - unsigned short val); - -/*! Set 32bit unsigned integer for specified resource record and key. Can - * only be used on keys with datatype ARES_DATATYPE_U32 - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] val 32bit unsigned integer - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_set_u32(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - unsigned int val); - -/*! Set binary (BIN or BINP) data for specified resource record and key. Can - * only be used on keys with datatype ARES_DATATYPE_BIN or ARES_DATATYPE_BINP. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] val Pointer to binary data. - * \param[in] len Length of binary data - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_set_bin(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - const unsigned char *val, - size_t len); - -/*! Add binary array value (ABINP) data for specified resource record and key. - * Can only be used on keys with datatype ARES_DATATYPE_ABINP. The value will - * Be added as the last element in the array. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] val Pointer to binary data. - * \param[in] len Length of binary data - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_add_abin(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - const unsigned char *val, - size_t len); - -/*! Delete binary array value (ABINP) data for specified resource record and - * key by specified index. Can only be used on keys with datatype - * ARES_DATATYPE_ABINP. The value at the index will be deleted. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] idx Index to delete - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_del_abin(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - size_t idx); - -/*! Set the option for the RR - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] opt Option record key id. - * \param[out] val Optional. Value to associate with option. - * \param[out] val_len Length of value passed. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_rr_set_opt(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - unsigned short opt, - const unsigned char *val, - size_t val_len); - -/*! Delete the option for the RR by id - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] opt Option record key id. - * \return ARES_SUCCESS if removed, ARES_ENOTFOUND if not found - */ -CARES_EXTERN ares_status_t ares_dns_rr_del_opt_byid(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - unsigned short opt); - -/*! Retrieve a pointer to the ipv4 address. Can only be used on keys with - * datatype ARES_DATATYPE_INADDR. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return pointer to ipv4 address or NULL on error - */ -CARES_EXTERN const struct in_addr * - ares_dns_rr_get_addr(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key); - -/*! Retrieve a pointer to the ipv6 address. Can only be used on keys with - * datatype ARES_DATATYPE_INADDR6. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return pointer to ipv6 address or NULL on error - */ -CARES_EXTERN const struct ares_in6_addr * - ares_dns_rr_get_addr6(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key); - -/*! Retrieve a pointer to the string. Can only be used on keys with - * datatype ARES_DATATYPE_STR and ARES_DATATYPE_NAME. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return pointer string or NULL on error - */ -CARES_EXTERN const char *ares_dns_rr_get_str(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key); - -/*! Retrieve an 8bit unsigned integer. Can only be used on keys with - * datatype ARES_DATATYPE_U8. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return 8bit unsigned integer - */ -CARES_EXTERN unsigned char ares_dns_rr_get_u8(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key); - -/*! Retrieve an 16bit unsigned integer. Can only be used on keys with - * datatype ARES_DATATYPE_U16. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return 16bit unsigned integer - */ -CARES_EXTERN unsigned short ares_dns_rr_get_u16(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key); - -/*! Retrieve an 32bit unsigned integer. Can only be used on keys with - * datatype ARES_DATATYPE_U32. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return 32bit unsigned integer - */ -CARES_EXTERN unsigned int ares_dns_rr_get_u32(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key); - -/*! Retrieve a pointer to the binary data. Can only be used on keys with - * datatype ARES_DATATYPE_BIN, ARES_DATATYPE_BINP, or ARES_DATATYPE_ABINP. - * If BINP or ABINP, the data is guaranteed to have a NULL terminator which - * is NOT included in the length. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[out] len Length of binary data returned - * \return pointer binary data or NULL on error - */ -CARES_EXTERN const unsigned char * - ares_dns_rr_get_bin(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - size_t *len); - -/*! Retrieve the count of the array of stored binary values. Can only be used on - * keys with datatype ARES_DATATYPE_ABINP. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return count of values - */ -CARES_EXTERN size_t ares_dns_rr_get_abin_cnt(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key); - -/*! Retrieve a pointer to the binary array data from the specified index. Can - * only be used on keys with datatype ARES_DATATYPE_ABINP. If ABINP, the data - * is guaranteed to have a NULL terminator which is NOT included in the length. - * If want all array membersconcatenated, may use ares_dns_rr_get_bin() - * instead. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] idx Index of value to retrieve - * \param[out] len Length of binary data returned - * \return pointer binary data or NULL on error - */ -CARES_EXTERN const unsigned char * - ares_dns_rr_get_abin(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - size_t idx, size_t *len); - - -/*! Retrieve the number of options stored for the RR. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \return count, or 0 if none. - */ -CARES_EXTERN size_t ares_dns_rr_get_opt_cnt(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key); - -/*! Retrieve the option for the RR by index. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] idx Index of option record - * \param[out] val Optional. Pointer passed by reference to hold value. - * Options may not have values. Value if returned is - * guaranteed to be NULL terminated, however in most - * cases it is not printable. - * \param[out] val_len Optional. Pointer passed by reference to hold value - * length. - * \return option key/id on success, 65535 on misuse. - */ -CARES_EXTERN unsigned short - ares_dns_rr_get_opt(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - size_t idx, const unsigned char **val, size_t *val_len); - -/*! Retrieve the option for the RR by the option key/id. - * - * \param[in] dns_rr Pointer to resource record - * \param[in] key DNS Resource Record Key - * \param[in] opt Option record key id (this is not the index). - * \param[out] val Optional. Pointer passed by reference to hold value. - * Options may not have values. Value if returned is - * guaranteed to be NULL terminated, however in most cases - * it is not printable. - * \param[out] val_len Optional. Pointer passed by reference to hold value - * length. - * \return ARES_TRUE on success, ARES_FALSE on misuse. - */ -CARES_EXTERN ares_bool_t ares_dns_rr_get_opt_byid(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - unsigned short opt, - const unsigned char **val, - size_t *val_len); - -/*! Parse a complete DNS message. - * - * \param[in] buf pointer to bytes to be parsed - * \param[in] buf_len Length of buf provided - * \param[in] flags Flags dictating how the message should be parsed. - * \param[out] dnsrec Pointer passed by reference for a new DNS record object - * that must be ares_dns_record_destroy()'d by caller. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_parse(const unsigned char *buf, - size_t buf_len, unsigned int flags, - ares_dns_record_t **dnsrec); - -/*! Write a complete DNS message - * - * \param[in] dnsrec Pointer to initialized and filled DNS record object. - * \param[out] buf Pointer passed by reference to be filled in with with - * DNS message. Must be ares_free()'d by caller. - * \param[out] buf_len Length of returned buffer containing DNS message. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_dns_write(const ares_dns_record_t *dnsrec, - unsigned char **buf, size_t *buf_len); - - -/*! Duplicate a complete DNS message. This does not copy internal members - * (such as the ttl decrement capability). - * - * \param[in] dnsrec Pointer to initialized and filled DNS record object. - * \return duplicated DNS record object, or NULL on out of memory. - */ -CARES_EXTERN ares_dns_record_t * - ares_dns_record_duplicate(const ares_dns_record_t *dnsrec); - -/*! @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ARES_DNS_RECORD_H */ diff --git a/vendor/c-ares/include/ares_nameser.h b/vendor/c-ares/include/ares_nameser.h deleted file mode 100644 index cf0e3b2d8..000000000 --- a/vendor/c-ares/include/ares_nameser.h +++ /dev/null @@ -1,510 +0,0 @@ -/* MIT License - * - * Copyright (c) Massachusetts Institute of Technology - * Copyright (c) Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifndef ARES_NAMESER_H -#define ARES_NAMESER_H - -#include "ares_build.h" - -#ifdef CARES_HAVE_ARPA_NAMESER_H -# include -#endif -#ifdef CARES_HAVE_ARPA_NAMESER_COMPAT_H -# include -#endif - -/* ============================================================================ - * arpa/nameser.h may or may not provide ALL of the below defines, so check - * each one individually and set if not - * ============================================================================ - */ - -#ifndef NS_PACKETSZ -# define NS_PACKETSZ 512 /* maximum packet size */ -#endif - -#ifndef NS_MAXDNAME -# define NS_MAXDNAME 256 /* maximum domain name */ -#endif - -#ifndef NS_MAXCDNAME -# define NS_MAXCDNAME 255 /* maximum compressed domain name */ -#endif - -#ifndef NS_MAXLABEL -# define NS_MAXLABEL 63 -#endif - -#ifndef NS_HFIXEDSZ -# define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */ -#endif - -#ifndef NS_QFIXEDSZ -# define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */ -#endif - -#ifndef NS_RRFIXEDSZ -# define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ -#endif - -#ifndef NS_INT16SZ -# define NS_INT16SZ 2 -#endif - -#ifndef NS_INADDRSZ -# define NS_INADDRSZ 4 -#endif - -#ifndef NS_IN6ADDRSZ -# define NS_IN6ADDRSZ 16 -#endif - -#ifndef NS_CMPRSFLGS -# define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */ -#endif - -#ifndef NS_DEFAULTPORT -# define NS_DEFAULTPORT 53 /* For both TCP and UDP. */ -#endif - -/* ============================================================================ - * arpa/nameser.h should provide these enumerations always, so if not found, - * provide them - * ============================================================================ - */ -#ifndef CARES_HAVE_ARPA_NAMESER_H - -typedef enum __ns_class { - ns_c_invalid = 0, /* Cookie. */ - ns_c_in = 1, /* Internet. */ - ns_c_2 = 2, /* unallocated/unsupported. */ - ns_c_chaos = 3, /* MIT Chaos-net. */ - ns_c_hs = 4, /* MIT Hesiod. */ - /* Query class values which do not appear in resource records */ - ns_c_none = 254, /* for prereq. sections in update requests */ - ns_c_any = 255, /* Wildcard match. */ - ns_c_max = 65536 -} ns_class; - -typedef enum __ns_type { - ns_t_invalid = 0, /* Cookie. */ - ns_t_a = 1, /* Host address. */ - ns_t_ns = 2, /* Authoritative server. */ - ns_t_md = 3, /* Mail destination. */ - ns_t_mf = 4, /* Mail forwarder. */ - ns_t_cname = 5, /* Canonical name. */ - ns_t_soa = 6, /* Start of authority zone. */ - ns_t_mb = 7, /* Mailbox domain name. */ - ns_t_mg = 8, /* Mail group member. */ - ns_t_mr = 9, /* Mail rename name. */ - ns_t_null = 10, /* Null resource record. */ - ns_t_wks = 11, /* Well known service. */ - ns_t_ptr = 12, /* Domain name pointer. */ - ns_t_hinfo = 13, /* Host information. */ - ns_t_minfo = 14, /* Mailbox information. */ - ns_t_mx = 15, /* Mail routing information. */ - ns_t_txt = 16, /* Text strings. */ - ns_t_rp = 17, /* Responsible person. */ - ns_t_afsdb = 18, /* AFS cell database. */ - ns_t_x25 = 19, /* X_25 calling address. */ - ns_t_isdn = 20, /* ISDN calling address. */ - ns_t_rt = 21, /* Router. */ - ns_t_nsap = 22, /* NSAP address. */ - ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ - ns_t_sig = 24, /* Security signature. */ - ns_t_key = 25, /* Security key. */ - ns_t_px = 26, /* X.400 mail mapping. */ - ns_t_gpos = 27, /* Geographical position (withdrawn). */ - ns_t_aaaa = 28, /* Ip6 Address. */ - ns_t_loc = 29, /* Location Information. */ - ns_t_nxt = 30, /* Next domain (security). */ - ns_t_eid = 31, /* Endpoint identifier. */ - ns_t_nimloc = 32, /* Nimrod Locator. */ - ns_t_srv = 33, /* Server Selection. */ - ns_t_atma = 34, /* ATM Address */ - ns_t_naptr = 35, /* Naming Authority PoinTeR */ - ns_t_kx = 36, /* Key Exchange */ - ns_t_cert = 37, /* Certification record */ - ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */ - ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ - ns_t_sink = 40, /* Kitchen sink (experimental) */ - ns_t_opt = 41, /* EDNS0 option (meta-RR) */ - ns_t_apl = 42, /* Address prefix list (RFC3123) */ - ns_t_ds = 43, /* Delegation Signer (RFC4034) */ - ns_t_sshfp = 44, /* SSH Key Fingerprint (RFC4255) */ - ns_t_rrsig = 46, /* Resource Record Signature (RFC4034) */ - ns_t_nsec = 47, /* Next Secure (RFC4034) */ - ns_t_dnskey = 48, /* DNS Public Key (RFC4034) */ - ns_t_tkey = 249, /* Transaction key */ - ns_t_tsig = 250, /* Transaction signature. */ - ns_t_ixfr = 251, /* Incremental zone transfer. */ - ns_t_axfr = 252, /* Transfer zone of authority. */ - ns_t_mailb = 253, /* Transfer mailbox records. */ - ns_t_maila = 254, /* Transfer mail agent records. */ - ns_t_any = 255, /* Wildcard match. */ - ns_t_uri = 256, /* Uniform Resource Identifier (RFC7553) */ - ns_t_caa = 257, /* Certification Authority Authorization. */ - ns_t_max = 65536 -} ns_type; - -typedef enum __ns_opcode { - ns_o_query = 0, /* Standard query. */ - ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */ - ns_o_status = 2, /* Name server status query (unsupported). */ - /* Opcode 3 is undefined/reserved. */ - ns_o_notify = 4, /* Zone change notification. */ - ns_o_update = 5, /* Zone update message. */ - ns_o_max = 6 -} ns_opcode; - -typedef enum __ns_rcode { - ns_r_noerror = 0, /* No error occurred. */ - ns_r_formerr = 1, /* Format error. */ - ns_r_servfail = 2, /* Server failure. */ - ns_r_nxdomain = 3, /* Name error. */ - ns_r_notimpl = 4, /* Unimplemented. */ - ns_r_refused = 5, /* Operation refused. */ - /* these are for BIND_UPDATE */ - ns_r_yxdomain = 6, /* Name exists */ - ns_r_yxrrset = 7, /* RRset exists */ - ns_r_nxrrset = 8, /* RRset does not exist */ - ns_r_notauth = 9, /* Not authoritative for zone */ - ns_r_notzone = 10, /* Zone of record different from zone section */ - ns_r_max = 11, - /* The following are TSIG extended errors */ - ns_r_badsig = 16, - ns_r_badkey = 17, - ns_r_badtime = 18 -} ns_rcode; - -#endif /* CARES_HAVE_ARPA_NAMESER_H */ - - -/* ============================================================================ - * arpa/nameser_compat.h typically sets these. However on some systems - * arpa/nameser.h does, but may not set all of them. Lets conditionally - * define each - * ============================================================================ - */ - -#ifndef PACKETSZ -# define PACKETSZ NS_PACKETSZ -#endif - -#ifndef MAXDNAME -# define MAXDNAME NS_MAXDNAME -#endif - -#ifndef MAXCDNAME -# define MAXCDNAME NS_MAXCDNAME -#endif - -#ifndef MAXLABEL -# define MAXLABEL NS_MAXLABEL -#endif - -#ifndef HFIXEDSZ -# define HFIXEDSZ NS_HFIXEDSZ -#endif - -#ifndef QFIXEDSZ -# define QFIXEDSZ NS_QFIXEDSZ -#endif - -#ifndef RRFIXEDSZ -# define RRFIXEDSZ NS_RRFIXEDSZ -#endif - -#ifndef INDIR_MASK -# define INDIR_MASK NS_CMPRSFLGS -#endif - -#ifndef NAMESERVER_PORT -# define NAMESERVER_PORT NS_DEFAULTPORT -#endif - - -/* opcodes */ -#ifndef O_QUERY -# define O_QUERY 0 /* ns_o_query */ -#endif -#ifndef O_IQUERY -# define O_IQUERY 1 /* ns_o_iquery */ -#endif -#ifndef O_STATUS -# define O_STATUS 2 /* ns_o_status */ -#endif -#ifndef O_NOTIFY -# define O_NOTIFY 4 /* ns_o_notify */ -#endif -#ifndef O_UPDATE -# define O_UPDATE 5 /* ns_o_update */ -#endif - - -/* response codes */ -#ifndef SERVFAIL -# define SERVFAIL ns_r_servfail -#endif -#ifndef NOTIMP -# define NOTIMP ns_r_notimpl -#endif -#ifndef REFUSED -# define REFUSED ns_r_refused -#endif -#if defined(_WIN32) && !defined(HAVE_ARPA_NAMESER_COMPAT_H) && defined(NOERROR) -# undef NOERROR /* it seems this is already defined in winerror.h */ -#endif -#ifndef NOERROR -# define NOERROR ns_r_noerror -#endif -#ifndef FORMERR -# define FORMERR ns_r_formerr -#endif -#ifndef NXDOMAIN -# define NXDOMAIN ns_r_nxdomain -#endif -/* Non-standard response codes, use numeric values */ -#ifndef YXDOMAIN -# define YXDOMAIN 6 /* ns_r_yxdomain */ -#endif -#ifndef YXRRSET -# define YXRRSET 7 /* ns_r_yxrrset */ -#endif -#ifndef NXRRSET -# define NXRRSET 8 /* ns_r_nxrrset */ -#endif -#ifndef NOTAUTH -# define NOTAUTH 9 /* ns_r_notauth */ -#endif -#ifndef NOTZONE -# define NOTZONE 10 /* ns_r_notzone */ -#endif -#ifndef TSIG_BADSIG -# define TSIG_BADSIG 16 /* ns_r_badsig */ -#endif -#ifndef TSIG_BADKEY -# define TSIG_BADKEY 17 /* ns_r_badkey */ -#endif -#ifndef TSIG_BADTIME -# define TSIG_BADTIME 18 /* ns_r_badtime */ -#endif - - -/* classes */ -#ifndef C_IN -# define C_IN 1 /* ns_c_in */ -#endif -#ifndef C_CHAOS -# define C_CHAOS 3 /* ns_c_chaos */ -#endif -#ifndef C_HS -# define C_HS 4 /* ns_c_hs */ -#endif -#ifndef C_NONE -# define C_NONE 254 /* ns_c_none */ -#endif -#ifndef C_ANY -# define C_ANY 255 /* ns_c_any */ -#endif - - -/* types */ -#ifndef T_A -# define T_A 1 /* ns_t_a */ -#endif -#ifndef T_NS -# define T_NS 2 /* ns_t_ns */ -#endif -#ifndef T_MD -# define T_MD 3 /* ns_t_md */ -#endif -#ifndef T_MF -# define T_MF 4 /* ns_t_mf */ -#endif -#ifndef T_CNAME -# define T_CNAME 5 /* ns_t_cname */ -#endif -#ifndef T_SOA -# define T_SOA 6 /* ns_t_soa */ -#endif -#ifndef T_MB -# define T_MB 7 /* ns_t_mb */ -#endif -#ifndef T_MG -# define T_MG 8 /* ns_t_mg */ -#endif -#ifndef T_MR -# define T_MR 9 /* ns_t_mr */ -#endif -#ifndef T_NULL -# define T_NULL 10 /* ns_t_null */ -#endif -#ifndef T_WKS -# define T_WKS 11 /* ns_t_wks */ -#endif -#ifndef T_PTR -# define T_PTR 12 /* ns_t_ptr */ -#endif -#ifndef T_HINFO -# define T_HINFO 13 /* ns_t_hinfo */ -#endif -#ifndef T_MINFO -# define T_MINFO 14 /* ns_t_minfo */ -#endif -#ifndef T_MX -# define T_MX 15 /* ns_t_mx */ -#endif -#ifndef T_TXT -# define T_TXT 16 /* ns_t_txt */ -#endif -#ifndef T_RP -# define T_RP 17 /* ns_t_rp */ -#endif -#ifndef T_AFSDB -# define T_AFSDB 18 /* ns_t_afsdb */ -#endif -#ifndef T_X25 -# define T_X25 19 /* ns_t_x25 */ -#endif -#ifndef T_ISDN -# define T_ISDN 20 /* ns_t_isdn */ -#endif -#ifndef T_RT -# define T_RT 21 /* ns_t_rt */ -#endif -#ifndef T_NSAP -# define T_NSAP 22 /* ns_t_nsap */ -#endif -#ifndef T_NSAP_PTR -# define T_NSAP_PTR 23 /* ns_t_nsap_ptr */ -#endif -#ifndef T_SIG -# define T_SIG 24 /* ns_t_sig */ -#endif -#ifndef T_KEY -# define T_KEY 25 /* ns_t_key */ -#endif -#ifndef T_PX -# define T_PX 26 /* ns_t_px */ -#endif -#ifndef T_GPOS -# define T_GPOS 27 /* ns_t_gpos */ -#endif -#ifndef T_AAAA -# define T_AAAA 28 /* ns_t_aaaa */ -#endif -#ifndef T_LOC -# define T_LOC 29 /* ns_t_loc */ -#endif -#ifndef T_NXT -# define T_NXT 30 /* ns_t_nxt */ -#endif -#ifndef T_EID -# define T_EID 31 /* ns_t_eid */ -#endif -#ifndef T_NIMLOC -# define T_NIMLOC 32 /* ns_t_nimloc */ -#endif -#ifndef T_SRV -# define T_SRV 33 /* ns_t_srv */ -#endif -#ifndef T_ATMA -# define T_ATMA 34 /* ns_t_atma */ -#endif -#ifndef T_NAPTR -# define T_NAPTR 35 /* ns_t_naptr */ -#endif -#ifndef T_KX -# define T_KX 36 /* ns_t_kx */ -#endif -#ifndef T_CERT -# define T_CERT 37 /* ns_t_cert */ -#endif -#ifndef T_A6 -# define T_A6 38 /* ns_t_a6 */ -#endif -#ifndef T_DNAME -# define T_DNAME 39 /* ns_t_dname */ -#endif -#ifndef T_SINK -# define T_SINK 40 /* ns_t_sink */ -#endif -#ifndef T_OPT -# define T_OPT 41 /* ns_t_opt */ -#endif -#ifndef T_APL -# define T_APL 42 /* ns_t_apl */ -#endif -#ifndef T_DS -# define T_DS 43 /* ns_t_ds */ -#endif -#ifndef T_SSHFP -# define T_SSHFP 44 /* ns_t_sshfp */ -#endif -#ifndef T_RRSIG -# define T_RRSIG 46 /* ns_t_rrsig */ -#endif -#ifndef T_NSEC -# define T_NSEC 47 /* ns_t_nsec */ -#endif -#ifndef T_DNSKEY -# define T_DNSKEY 48 /* ns_t_dnskey */ -#endif -#ifndef T_TKEY -# define T_TKEY 249 /* ns_t_tkey */ -#endif -#ifndef T_TSIG -# define T_TSIG 250 /* ns_t_tsig */ -#endif -#ifndef T_IXFR -# define T_IXFR 251 /* ns_t_ixfr */ -#endif -#ifndef T_AXFR -# define T_AXFR 252 /* ns_t_axfr */ -#endif -#ifndef T_MAILB -# define T_MAILB 253 /* ns_t_mailb */ -#endif -#ifndef T_MAILA -# define T_MAILA 254 /* ns_t_maila */ -#endif -#ifndef T_ANY -# define T_ANY 255 /* ns_t_any */ -#endif -#ifndef T_URI -# define T_URI 256 /* ns_t_uri */ -#endif -#ifndef T_CAA -# define T_CAA 257 /* ns_t_caa */ -#endif -#ifndef T_MAX -# define T_MAX 65536 /* ns_t_max */ -#endif - - -#endif /* ARES_NAMESER_H */ diff --git a/vendor/c-ares/include/ares_version.h b/vendor/c-ares/include/ares_version.h deleted file mode 100644 index 7da82f2a1..000000000 --- a/vendor/c-ares/include/ares_version.h +++ /dev/null @@ -1,47 +0,0 @@ -/* MIT License - * - * Copyright (c) Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifndef ARES__VERSION_H -#define ARES__VERSION_H - -/* This is the global package copyright */ -#define ARES_COPYRIGHT "2004 - 2024 Daniel Stenberg, ." - -#define ARES_VERSION_MAJOR 1 -#define ARES_VERSION_MINOR 34 -#define ARES_VERSION_PATCH 5 -#define ARES_VERSION_STR "1.34.5" - -/* NOTE: We cannot make the version string a C preprocessor stringify operation - * due to assumptions made by integrators that aren't properly using - * pkgconf or cmake and are doing their own detection based on parsing - * this header */ - -#define ARES_VERSION \ - ((ARES_VERSION_MAJOR << 16) | (ARES_VERSION_MINOR << 8) | \ - (ARES_VERSION_PATCH)) - -#endif diff --git a/vendor/c-ares/src/lib/ares_addrinfo2hostent.c b/vendor/c-ares/src/lib/ares_addrinfo2hostent.c deleted file mode 100644 index 239ca5bce..000000000 --- a/vendor/c-ares/src/lib/ares_addrinfo2hostent.c +++ /dev/null @@ -1,305 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2005 Dominick Meglio - * Copyright (c) 2019 Andrew Selivanov - * Copyright (c) 2021 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -static size_t hostent_nalias(const struct hostent *host) -{ - size_t i; - for (i=0; host->h_aliases != NULL && host->h_aliases[i] != NULL; i++) - ; - - return i; -} - -static size_t ai_nalias(const struct ares_addrinfo *ai) -{ - const struct ares_addrinfo_cname *cname; - size_t i = 0; - - for (cname = ai->cnames; cname != NULL; cname=cname->next) { - i++; - } - - return i; -} - -static size_t hostent_naddr(const struct hostent *host) -{ - size_t i; - for (i=0; host->h_addr_list != NULL && host->h_addr_list[i] != NULL; i++) - ; - - return i; -} - -static size_t ai_naddr(const struct ares_addrinfo *ai, int af) -{ - const struct ares_addrinfo_node *node; - size_t i = 0; - - for (node = ai->nodes; node != NULL; node=node->ai_next) { - if (af != AF_UNSPEC && af != node->ai_family) - continue; - i++; - } - - return i; -} - -ares_status_t ares_addrinfo2hostent(const struct ares_addrinfo *ai, int family, - struct hostent **host) -{ - struct ares_addrinfo_node *next; - char **aliases = NULL; - char **addrs = NULL; - size_t naliases = 0; - size_t naddrs = 0; - size_t i; - size_t ealiases = 0; - size_t eaddrs = 0; - - if (ai == NULL || host == NULL) { - return ARES_EBADQUERY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Use either the host set in the passed in hosts to be filled in, or the - * first node of the response as the family, since hostent can only - * represent one family. We assume getaddrinfo() returned a sorted list if - * the user requested AF_UNSPEC. */ - if (family == AF_UNSPEC) { - if (*host != NULL && (*host)->h_addrtype != AF_UNSPEC) { - family = (*host)->h_addrtype; - } else if (ai->nodes != NULL) { - family = ai->nodes->ai_family; - } - } - - if (family != AF_INET && family != AF_INET6) { - return ARES_EBADQUERY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (*host == NULL) { - *host = ares_malloc_zero(sizeof(**host)); - if (!(*host)) { - goto enomem; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - (*host)->h_addrtype = (HOSTENT_ADDRTYPE_TYPE)family; - if (family == AF_INET) { - (*host)->h_length = sizeof(struct in_addr); - } else if (family == AF_INET6) { - (*host)->h_length = sizeof(struct ares_in6_addr); - } - - if ((*host)->h_name == NULL) { - if (ai->cnames) { - (*host)->h_name = ares_strdup(ai->cnames->name); - if ((*host)->h_name == NULL && ai->cnames->name) { - goto enomem; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } else { - (*host)->h_name = ares_strdup(ai->name); - if ((*host)->h_name == NULL && ai->name) { - goto enomem; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - naliases = ai_nalias(ai); - ealiases = hostent_nalias(*host); - aliases = ares_realloc_zero((*host)->h_aliases, - ealiases * sizeof(char *), - (naliases + ealiases + 1) * sizeof(char *)); - if (!aliases) { - goto enomem; /* LCOV_EXCL_LINE: OutOfMemory */ - } - (*host)->h_aliases = aliases; - - if (naliases) { - const struct ares_addrinfo_cname *cname; - i = ealiases; - for (cname = ai->cnames; cname != NULL; cname = cname->next) { - if (cname->alias == NULL) { - continue; - } - (*host)->h_aliases[i] = ares_strdup(cname->alias); - if ((*host)->h_aliases[i] == NULL) { - goto enomem; /* LCOV_EXCL_LINE: OutOfMemory */ - } - i++; - } - } - - naddrs = ai_naddr(ai, family); - eaddrs = hostent_naddr(*host); - addrs = ares_realloc_zero((*host)->h_addr_list, eaddrs * sizeof(char *), - (naddrs + eaddrs + 1) * sizeof(char *)); - if (addrs == NULL) { - goto enomem; /* LCOV_EXCL_LINE: OutOfMemory */ - } - (*host)->h_addr_list = addrs; - - if (naddrs) { - i = eaddrs; - for (next = ai->nodes; next != NULL; next = next->ai_next) { - if (next->ai_family != family) { - continue; - } - (*host)->h_addr_list[i] = ares_malloc_zero((size_t)(*host)->h_length); - if ((*host)->h_addr_list[i] == NULL) { - goto enomem; /* LCOV_EXCL_LINE: OutOfMemory */ - } - if (family == AF_INET6) { - memcpy((*host)->h_addr_list[i], - &(CARES_INADDR_CAST(const struct sockaddr_in6 *, next->ai_addr) - ->sin6_addr), - (size_t)(*host)->h_length); - } - if (family == AF_INET) { - memcpy((*host)->h_addr_list[i], - &(CARES_INADDR_CAST(const struct sockaddr_in *, next->ai_addr) - ->sin_addr), - (size_t)(*host)->h_length); - } - i++; - } - } - - if (naddrs + eaddrs == 0 && naliases + ealiases == 0) { - ares_free_hostent(*host); - *host = NULL; - return ARES_ENODATA; - } - - return ARES_SUCCESS; - -/* LCOV_EXCL_START: OutOfMemory */ -enomem: - ares_free_hostent(*host); - *host = NULL; - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ -} - -ares_status_t ares_addrinfo2addrttl(const struct ares_addrinfo *ai, int family, - size_t req_naddrttls, - struct ares_addrttl *addrttls, - struct ares_addr6ttl *addr6ttls, - size_t *naddrttls) -{ - struct ares_addrinfo_node *next; - struct ares_addrinfo_cname *next_cname; - int cname_ttl = INT_MAX; - - if (family != AF_INET && family != AF_INET6) { - return ARES_EBADQUERY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ai == NULL || naddrttls == NULL) { - return ARES_EBADQUERY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (family == AF_INET && addrttls == NULL) { - return ARES_EBADQUERY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (family == AF_INET6 && addr6ttls == NULL) { - return ARES_EBADQUERY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (req_naddrttls == 0) { - return ARES_EBADQUERY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *naddrttls = 0; - - next_cname = ai->cnames; - while (next_cname) { - if (next_cname->ttl < cname_ttl) { - cname_ttl = next_cname->ttl; - } - next_cname = next_cname->next; - } - - for (next = ai->nodes; next != NULL; next = next->ai_next) { - if (next->ai_family != family) { - continue; - } - - if (*naddrttls >= req_naddrttls) { - break; - } - - if (family == AF_INET6) { - if (next->ai_ttl > cname_ttl) { - addr6ttls[*naddrttls].ttl = cname_ttl; - } else { - addr6ttls[*naddrttls].ttl = next->ai_ttl; - } - - memcpy(&addr6ttls[*naddrttls].ip6addr, - &(CARES_INADDR_CAST(const struct sockaddr_in6 *, next->ai_addr) - ->sin6_addr), - sizeof(struct ares_in6_addr)); - } else { - if (next->ai_ttl > cname_ttl) { - addrttls[*naddrttls].ttl = cname_ttl; - } else { - addrttls[*naddrttls].ttl = next->ai_ttl; - } - memcpy(&addrttls[*naddrttls].ipaddr, - &(CARES_INADDR_CAST(const struct sockaddr_in *, next->ai_addr) - ->sin_addr), - sizeof(struct in_addr)); - } - (*naddrttls)++; - } - - return ARES_SUCCESS; -} diff --git a/vendor/c-ares/src/lib/ares_addrinfo_localhost.c b/vendor/c-ares/src/lib/ares_addrinfo_localhost.c deleted file mode 100644 index 2abb0c48a..000000000 --- a/vendor/c-ares/src/lib/ares_addrinfo_localhost.c +++ /dev/null @@ -1,245 +0,0 @@ -/* MIT License - * - * Copyright (c) Massachusetts Institute of Technology - * Copyright (c) Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#if defined(USE_WINSOCK) -# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 -# include -# endif -# if defined(HAVE_IPHLPAPI_H) -# include -# endif -# if defined(HAVE_NETIOAPI_H) -# include -# endif -#endif - -static ares_bool_t ares_ai_has_family(int aftype, - const struct ares_addrinfo_node *nodes) -{ - const struct ares_addrinfo_node *node; - - for (node = nodes; node != NULL; node = node->ai_next) { - if (node->ai_family == aftype) - return ARES_TRUE; - } - - return ARES_FALSE; -} - -ares_status_t ares_append_ai_node(int aftype, unsigned short port, - unsigned int ttl, const void *adata, - struct ares_addrinfo_node **nodes) -{ - struct ares_addrinfo_node *node; - - node = ares_append_addrinfo_node(nodes); - if (!node) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - memset(node, 0, sizeof(*node)); - - if (aftype == AF_INET) { - struct sockaddr_in *sin = ares_malloc(sizeof(*sin)); - if (!sin) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - memset(sin, 0, sizeof(*sin)); - memcpy(&sin->sin_addr.s_addr, adata, sizeof(sin->sin_addr.s_addr)); - sin->sin_family = AF_INET; - sin->sin_port = htons(port); - - node->ai_addr = (struct sockaddr *)sin; - node->ai_family = AF_INET; - node->ai_addrlen = sizeof(*sin); - node->ai_addr = (struct sockaddr *)sin; - node->ai_ttl = (int)ttl; - } - - if (aftype == AF_INET6) { - struct sockaddr_in6 *sin6 = ares_malloc(sizeof(*sin6)); - if (!sin6) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - memset(sin6, 0, sizeof(*sin6)); - memcpy(&sin6->sin6_addr.s6_addr, adata, sizeof(sin6->sin6_addr.s6_addr)); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons(port); - - node->ai_addr = (struct sockaddr *)sin6; - node->ai_family = AF_INET6; - node->ai_addrlen = sizeof(*sin6); - node->ai_addr = (struct sockaddr *)sin6; - node->ai_ttl = (int)ttl; - } - - return ARES_SUCCESS; -} - -static ares_status_t - ares_default_loopback_addrs(int aftype, unsigned short port, - struct ares_addrinfo_node **nodes) -{ - ares_status_t status = ARES_SUCCESS; - - if ((aftype == AF_UNSPEC || aftype == AF_INET6) && - !ares_ai_has_family(AF_INET6, *nodes)) { - struct ares_in6_addr addr6; - ares_inet_pton(AF_INET6, "::1", &addr6); - status = ares_append_ai_node(AF_INET6, port, 0, &addr6, nodes); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - if ((aftype == AF_UNSPEC || aftype == AF_INET) && - !ares_ai_has_family(AF_INET, *nodes)) { - struct in_addr addr4; - ares_inet_pton(AF_INET, "127.0.0.1", &addr4); - status = ares_append_ai_node(AF_INET, port, 0, &addr4, nodes); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return status; -} - -static ares_status_t - ares_system_loopback_addrs(int aftype, unsigned short port, - struct ares_addrinfo_node **nodes) -{ -#if defined(USE_WINSOCK) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && \ - !defined(__WATCOMC__) - PMIB_UNICASTIPADDRESS_TABLE table; - unsigned int i; - ares_status_t status = ARES_ENOTFOUND; - - *nodes = NULL; - - if (GetUnicastIpAddressTable((ADDRESS_FAMILY)aftype, &table) != NO_ERROR) { - return ARES_ENOTFOUND; - } - - for (i = 0; i < table->NumEntries; i++) { - if (table->Table[i].InterfaceLuid.Info.IfType != - IF_TYPE_SOFTWARE_LOOPBACK) { - continue; - } - - if (table->Table[i].Address.si_family == AF_INET && - !ares_ai_has_family(AF_INET, *nodes)) { - status = - ares_append_ai_node(table->Table[i].Address.si_family, port, 0, - &table->Table[i].Address.Ipv4.sin_addr, nodes); - } else if (table->Table[i].Address.si_family == AF_INET6 && - !ares_ai_has_family(AF_INET6, *nodes)) { - status = - ares_append_ai_node(table->Table[i].Address.si_family, port, 0, - &table->Table[i].Address.Ipv6.sin6_addr, nodes); - } else { - /* Ignore any others */ - continue; - } - - if (status != ARES_SUCCESS) { - goto fail; - } - } - - if (*nodes == NULL) { - status = ARES_ENOTFOUND; - } - -fail: - FreeMibTable(table); - - if (status != ARES_SUCCESS) { - ares_freeaddrinfo_nodes(*nodes); - *nodes = NULL; - } - - return status; - -#else - (void)aftype; - (void)port; - (void)nodes; - /* Not supported on any other OS at this time */ - return ARES_ENOTFOUND; -#endif -} - -ares_status_t ares_addrinfo_localhost(const char *name, unsigned short port, - const struct ares_addrinfo_hints *hints, - struct ares_addrinfo *ai) -{ - ares_status_t status; - - /* Validate family */ - switch (hints->ai_family) { - case AF_INET: - case AF_INET6: - case AF_UNSPEC: - break; - default: /* LCOV_EXCL_LINE: DefensiveCoding */ - return ARES_EBADFAMILY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ai->name != NULL) { - ares_free(ai->name); - } - ai->name = ares_strdup(name); - if (ai->name == NULL) { - status = ARES_ENOMEM; - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_system_loopback_addrs(hints->ai_family, port, &ai->nodes); - if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) { - goto done; - } - - status = ares_default_loopback_addrs(hints->ai_family, port, &ai->nodes); - -done: - return status; -} diff --git a/vendor/c-ares/src/lib/ares_android.c b/vendor/c-ares/src/lib/ares_android.c deleted file mode 100644 index a8284c1e5..000000000 --- a/vendor/c-ares/src/lib/ares_android.c +++ /dev/null @@ -1,496 +0,0 @@ -/* MIT License - * - * Copyright (c) John Schember - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#if defined(ANDROID) || defined(__ANDROID__) -# include "ares_private.h" -# include -# include -# include "ares_android.h" - -static JavaVM *android_jvm = NULL; -static jobject android_connectivity_manager = NULL; - -/* ConnectivityManager.getActiveNetwork */ -static jmethodID android_cm_active_net_mid = NULL; -/* ConnectivityManager.getLinkProperties */ -static jmethodID android_cm_link_props_mid = NULL; -/* LinkProperties.getDnsServers */ -static jmethodID android_lp_dns_servers_mid = NULL; -/* LinkProperties.getDomains */ -static jmethodID android_lp_domains_mid = NULL; -/* List.size */ -static jmethodID android_list_size_mid = NULL; -/* List.get */ -static jmethodID android_list_get_mid = NULL; -/* InetAddress.getHostAddress */ -static jmethodID android_ia_host_addr_mid = NULL; - -static jclass jni_get_class(JNIEnv *env, const char *path) -{ - jclass cls = NULL; - - if (env == NULL || path == NULL || *path == '\0') { - return NULL; - } - - cls = (*env)->FindClass(env, path); - if ((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - return NULL; - } - return cls; -} - -static jmethodID jni_get_method_id(JNIEnv *env, jclass cls, - const char *func_name, const char *signature) -{ - jmethodID mid = NULL; - - if (env == NULL || cls == NULL || func_name == NULL || *func_name == '\0' || - signature == NULL || *signature == '\0') { - return NULL; - } - - mid = (*env)->GetMethodID(env, cls, func_name, signature); - if ((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - return NULL; - } - - return mid; -} - -static int jvm_attach(JNIEnv **env) -{ - char name[17] = { 0 }; - - JavaVMAttachArgs args; - - args.version = JNI_VERSION_1_6; - if (prctl(PR_GET_NAME, name) == 0) { - args.name = name; - } else { - args.name = NULL; - } - args.group = NULL; - - return (*android_jvm)->AttachCurrentThread(android_jvm, env, &args); -} - -void ares_library_init_jvm(JavaVM *jvm) -{ - android_jvm = jvm; -} - -int ares_library_init_android(jobject connectivity_manager) -{ - JNIEnv *env = NULL; - int need_detatch = 0; - int res; - ares_status_t ret = ARES_ENOTINITIALIZED; - jclass obj_cls = NULL; - - if (android_jvm == NULL) { - goto cleanup; - } - - res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); - if (res == JNI_EDETACHED) { - env = NULL; - res = jvm_attach(&env); - need_detatch = 1; - } - if (res != JNI_OK || env == NULL) { - goto cleanup; - } - - android_connectivity_manager = - (*env)->NewGlobalRef(env, connectivity_manager); - if (android_connectivity_manager == NULL) { - goto cleanup; - } - - /* Initialization has succeeded. Now attempt to cache the methods that will be - * called by ares_get_android_server_list. */ - ret = ARES_SUCCESS; - - /* ConnectivityManager in API 1. */ - obj_cls = jni_get_class(env, "android/net/ConnectivityManager"); - if (obj_cls == NULL) { - goto cleanup; - } - - /* ConnectivityManager.getActiveNetwork in API 23. */ - android_cm_active_net_mid = jni_get_method_id( - env, obj_cls, "getActiveNetwork", "()Landroid/net/Network;"); - if (android_cm_active_net_mid == NULL) { - goto cleanup; - } - - /* ConnectivityManager.getLinkProperties in API 21. */ - android_cm_link_props_mid = - jni_get_method_id(env, obj_cls, "getLinkProperties", - "(Landroid/net/Network;)Landroid/net/LinkProperties;"); - if (android_cm_link_props_mid == NULL) { - goto cleanup; - } - - /* LinkProperties in API 21. */ - (*env)->DeleteLocalRef(env, obj_cls); - obj_cls = jni_get_class(env, "android/net/LinkProperties"); - if (obj_cls == NULL) { - goto cleanup; - } - - /* getDnsServers in API 21. */ - android_lp_dns_servers_mid = - jni_get_method_id(env, obj_cls, "getDnsServers", "()Ljava/util/List;"); - if (android_lp_dns_servers_mid == NULL) { - goto cleanup; - } - - /* getDomains in API 21. */ - android_lp_domains_mid = - jni_get_method_id(env, obj_cls, "getDomains", "()Ljava/lang/String;"); - if (android_lp_domains_mid == NULL) { - goto cleanup; - } - - (*env)->DeleteLocalRef(env, obj_cls); - obj_cls = jni_get_class(env, "java/util/List"); - if (obj_cls == NULL) { - goto cleanup; - } - - android_list_size_mid = jni_get_method_id(env, obj_cls, "size", "()I"); - if (android_list_size_mid == NULL) { - goto cleanup; - } - - android_list_get_mid = - jni_get_method_id(env, obj_cls, "get", "(I)Ljava/lang/Object;"); - if (android_list_get_mid == NULL) { - goto cleanup; - } - - (*env)->DeleteLocalRef(env, obj_cls); - obj_cls = jni_get_class(env, "java/net/InetAddress"); - if (obj_cls == NULL) { - goto cleanup; - } - - android_ia_host_addr_mid = - jni_get_method_id(env, obj_cls, "getHostAddress", "()Ljava/lang/String;"); - if (android_ia_host_addr_mid == NULL) { - goto cleanup; - } - - (*env)->DeleteLocalRef(env, obj_cls); - goto done; - -cleanup: - if (obj_cls != NULL) { - (*env)->DeleteLocalRef(env, obj_cls); - } - - android_cm_active_net_mid = NULL; - android_cm_link_props_mid = NULL; - android_lp_dns_servers_mid = NULL; - android_lp_domains_mid = NULL; - android_list_size_mid = NULL; - android_list_get_mid = NULL; - android_ia_host_addr_mid = NULL; - -done: - if (need_detatch) { - (*android_jvm)->DetachCurrentThread(android_jvm); - } - - return (int)ret; -} - -int ares_library_android_initialized(void) -{ - if (android_jvm == NULL || android_connectivity_manager == NULL) { - return ARES_ENOTINITIALIZED; - } - return ARES_SUCCESS; -} - -void ares_library_cleanup_android(void) -{ - JNIEnv *env = NULL; - int need_detatch = 0; - int res; - - if (android_jvm == NULL || android_connectivity_manager == NULL) { - return; - } - - res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); - if (res == JNI_EDETACHED) { - env = NULL; - res = jvm_attach(&env); - need_detatch = 1; - } - if (res != JNI_OK || env == NULL) { - return; - } - - android_cm_active_net_mid = NULL; - android_cm_link_props_mid = NULL; - android_lp_dns_servers_mid = NULL; - android_lp_domains_mid = NULL; - android_list_size_mid = NULL; - android_list_get_mid = NULL; - android_ia_host_addr_mid = NULL; - - (*env)->DeleteGlobalRef(env, android_connectivity_manager); - android_connectivity_manager = NULL; - - if (need_detatch) { - (*android_jvm)->DetachCurrentThread(android_jvm); - } -} - -char **ares_get_android_server_list(size_t max_servers, size_t *num_servers) -{ - JNIEnv *env = NULL; - jobject active_network = NULL; - jobject link_properties = NULL; - jobject server_list = NULL; - jobject server = NULL; - jstring str = NULL; - jint nserv; - const char *ch_server_address; - int res; - size_t i; - char **dns_list = NULL; - int need_detatch = 0; - - if (android_jvm == NULL || android_connectivity_manager == NULL || - max_servers == 0 || num_servers == NULL) { - return NULL; - } - - if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL || - android_lp_dns_servers_mid == NULL || android_list_size_mid == NULL || - android_list_get_mid == NULL || android_ia_host_addr_mid == NULL) { - return NULL; - } - - res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); - if (res == JNI_EDETACHED) { - env = NULL; - res = jvm_attach(&env); - need_detatch = 1; - } - if (res != JNI_OK || env == NULL) { - goto done; - } - - /* JNI below is equivalent to this Java code. - import android.content.Context; - import android.net.ConnectivityManager; - import android.net.LinkProperties; - import android.net.Network; - import java.net.InetAddress; - import java.util.List; - - ConnectivityManager cm = (ConnectivityManager)this.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - Network an = cm.getActiveNetwork(); - LinkProperties lp = cm.getLinkProperties(an); - List dns = lp.getDnsServers(); - for (InetAddress ia: dns) { - String ha = ia.getHostAddress(); - } - - Note: The JNI ConnectivityManager object and all method IDs were previously - initialized in ares_library_init_android. - */ - - active_network = (*env)->CallObjectMethod(env, android_connectivity_manager, - android_cm_active_net_mid); - if (active_network == NULL) { - goto done; - } - - link_properties = - (*env)->CallObjectMethod(env, android_connectivity_manager, - android_cm_link_props_mid, active_network); - if (link_properties == NULL) { - goto done; - } - - server_list = - (*env)->CallObjectMethod(env, link_properties, android_lp_dns_servers_mid); - if (server_list == NULL) { - goto done; - } - - nserv = (*env)->CallIntMethod(env, server_list, android_list_size_mid); - if (nserv > (jint)max_servers) { - nserv = (jint)max_servers; - } - if (nserv <= 0) { - goto done; - } - *num_servers = (size_t)nserv; - - dns_list = ares_malloc(sizeof(*dns_list) * (*num_servers)); - for (i = 0; i < *num_servers; i++) { - size_t len = 64; - server = - (*env)->CallObjectMethod(env, server_list, android_list_get_mid, (jint)i); - dns_list[i] = ares_malloc(len); - dns_list[i][0] = 0; - if (server == NULL) { - continue; - } - str = (*env)->CallObjectMethod(env, server, android_ia_host_addr_mid); - ch_server_address = (*env)->GetStringUTFChars(env, str, 0); - ares_strcpy(dns_list[i], ch_server_address, len); - (*env)->ReleaseStringUTFChars(env, str, ch_server_address); - (*env)->DeleteLocalRef(env, str); - (*env)->DeleteLocalRef(env, server); - } - -done: - if ((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - } - - if (server_list != NULL) { - (*env)->DeleteLocalRef(env, server_list); - } - if (link_properties != NULL) { - (*env)->DeleteLocalRef(env, link_properties); - } - if (active_network != NULL) { - (*env)->DeleteLocalRef(env, active_network); - } - - if (need_detatch) { - (*android_jvm)->DetachCurrentThread(android_jvm); - } - return dns_list; -} - -char *ares_get_android_search_domains_list(void) -{ - JNIEnv *env = NULL; - jobject active_network = NULL; - jobject link_properties = NULL; - jstring domains = NULL; - const char *domain; - int res; - char *domain_list = NULL; - int need_detatch = 0; - - if (android_jvm == NULL || android_connectivity_manager == NULL) { - return NULL; - } - - if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL || - android_lp_domains_mid == NULL) { - return NULL; - } - - res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); - if (res == JNI_EDETACHED) { - env = NULL; - res = jvm_attach(&env); - need_detatch = 1; - } - if (res != JNI_OK || env == NULL) { - goto done; - } - - /* JNI below is equivalent to this Java code. - import android.content.Context; - import android.net.ConnectivityManager; - import android.net.LinkProperties; - - ConnectivityManager cm = (ConnectivityManager)this.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE); - Network an = cm.getActiveNetwork(); - LinkProperties lp = cm.getLinkProperties(an); - String domains = lp.getDomains(); - for (String domain: domains.split(",")) { - String d = domain; - } - - Note: The JNI ConnectivityManager object and all method IDs were previously - initialized in ares_library_init_android. - */ - - active_network = (*env)->CallObjectMethod(env, android_connectivity_manager, - android_cm_active_net_mid); - if (active_network == NULL) { - goto done; - } - - link_properties = - (*env)->CallObjectMethod(env, android_connectivity_manager, - android_cm_link_props_mid, active_network); - if (link_properties == NULL) { - goto done; - } - - /* Get the domains. It is a common separated list of domains to search. */ - domains = - (*env)->CallObjectMethod(env, link_properties, android_lp_domains_mid); - if (domains == NULL) { - goto done; - } - - /* Split on , */ - domain = (*env)->GetStringUTFChars(env, domains, 0); - domain_list = ares_strdup(domain); - (*env)->ReleaseStringUTFChars(env, domains, domain); - (*env)->DeleteLocalRef(env, domains); - -done: - if ((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - } - - if (link_properties != NULL) { - (*env)->DeleteLocalRef(env, link_properties); - } - if (active_network != NULL) { - (*env)->DeleteLocalRef(env, active_network); - } - - if (need_detatch) { - (*android_jvm)->DetachCurrentThread(android_jvm); - } - return domain_list; -} -#else -/* warning: ISO C forbids an empty translation unit */ -typedef int dummy_make_iso_compilers_happy; -#endif diff --git a/vendor/c-ares/src/lib/ares_android.h b/vendor/c-ares/src/lib/ares_android.h deleted file mode 100644 index 5caadb4fe..000000000 --- a/vendor/c-ares/src/lib/ares_android.h +++ /dev/null @@ -1,38 +0,0 @@ -/* MIT License - * - * Copyright (c) John Schember - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __ARES_ANDROID_H__ -#define __ARES_ANDROID_H__ - -#if defined(ANDROID) || defined(__ANDROID__) - -char **ares_get_android_server_list(size_t max_servers, size_t *num_servers); -char *ares_get_android_search_domains_list(void); -void ares_library_cleanup_android(void); - -#endif - -#endif /* __ARES_ANDROID_H__ */ diff --git a/vendor/c-ares/src/lib/ares_cancel.c b/vendor/c-ares/src/lib/ares_cancel.c deleted file mode 100644 index 75600dea6..000000000 --- a/vendor/c-ares/src/lib/ares_cancel.c +++ /dev/null @@ -1,87 +0,0 @@ -/* MIT License - * - * Copyright (c) 2004 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -/* - * ares_cancel() cancels all ongoing requests/resolves that might be going on - * on the given channel. It does NOT kill the channel, use ares_destroy() for - * that. - */ -void ares_cancel(ares_channel_t *channel) -{ - if (channel == NULL) { - return; - } - - ares_channel_lock(channel); - - if (ares_llist_len(channel->all_queries) > 0) { - ares_llist_node_t *node = NULL; - ares_llist_node_t *next = NULL; - - /* Swap list heads, so that only those queries which were present on entry - * into this function are cancelled. New queries added by callbacks of - * queries being cancelled will not be cancelled themselves. - */ - ares_llist_t *list_copy = channel->all_queries; - channel->all_queries = ares_llist_create(NULL); - - /* Out of memory, this function doesn't return a result code though so we - * can't report to caller */ - if (channel->all_queries == NULL) { - channel->all_queries = list_copy; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - node = ares_llist_node_first(list_copy); - while (node != NULL) { - ares_query_t *query; - - /* Cache next since this node is being deleted */ - next = ares_llist_node_next(node); - - query = ares_llist_node_claim(node); - query->node_all_queries = NULL; - - /* NOTE: its possible this may enqueue new queries */ - query->callback(query->arg, ARES_ECANCELLED, 0, NULL); - ares_free_query(query); - - node = next; - } - - ares_llist_destroy(list_copy); - } - - /* See if the connections should be cleaned up */ - ares_check_cleanup_conns(channel); - - ares_queue_notify_empty(channel); - -done: - ares_channel_unlock(channel); -} diff --git a/vendor/c-ares/src/lib/ares_close_sockets.c b/vendor/c-ares/src/lib/ares_close_sockets.c deleted file mode 100644 index 347f43e6f..000000000 --- a/vendor/c-ares/src/lib/ares_close_sockets.c +++ /dev/null @@ -1,137 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include - -static void ares_requeue_queries(ares_conn_t *conn, - ares_status_t requeue_status) -{ - ares_query_t *query; - ares_timeval_t now; - - ares_tvnow(&now); - - while ((query = ares_llist_first_val(conn->queries_to_conn)) != NULL) { - ares_requeue_query(query, &now, requeue_status, ARES_TRUE, NULL, NULL); - } -} - -void ares_close_connection(ares_conn_t *conn, ares_status_t requeue_status) -{ - ares_server_t *server = conn->server; - ares_channel_t *channel = server->channel; - - /* Unlink */ - ares_llist_node_claim( - ares_htable_asvp_get_direct(channel->connnode_by_socket, conn->fd)); - ares_htable_asvp_remove(channel->connnode_by_socket, conn->fd); - - if (conn->flags & ARES_CONN_FLAG_TCP) { - server->tcp_conn = NULL; - } - - ares_buf_destroy(conn->in_buf); - ares_buf_destroy(conn->out_buf); - - /* Requeue queries to other connections */ - ares_requeue_queries(conn, requeue_status); - - ares_llist_destroy(conn->queries_to_conn); - - ares_conn_sock_state_cb_update(conn, ARES_CONN_STATE_NONE); - - ares_socket_close(channel, conn->fd); - - ares_free(conn); -} - -void ares_close_sockets(ares_server_t *server) -{ - ares_llist_node_t *node; - - while ((node = ares_llist_node_first(server->connections)) != NULL) { - ares_conn_t *conn = ares_llist_node_val(node); - ares_close_connection(conn, ARES_SUCCESS); - } -} - -void ares_check_cleanup_conns(const ares_channel_t *channel) -{ - ares_slist_node_t *snode; - - if (channel == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Iterate across each server */ - for (snode = ares_slist_node_first(channel->servers); snode != NULL; - snode = ares_slist_node_next(snode)) { - ares_server_t *server = ares_slist_node_val(snode); - ares_llist_node_t *cnode; - - /* Iterate across each connection */ - cnode = ares_llist_node_first(server->connections); - while (cnode != NULL) { - ares_llist_node_t *next = ares_llist_node_next(cnode); - ares_conn_t *conn = ares_llist_node_val(cnode); - ares_bool_t do_cleanup = ARES_FALSE; - cnode = next; - - /* Has connections, not eligible */ - if (ares_llist_len(conn->queries_to_conn)) { - continue; - } - - /* If we are configured not to stay open, close it out */ - if (!(channel->flags & ARES_FLAG_STAYOPEN)) { - do_cleanup = ARES_TRUE; - } - - /* If the associated server has failures, close it out. Resetting the - * connection (and specifically the source port number) can help resolve - * situations where packets are being dropped. - */ - if (conn->server->consec_failures > 0) { - do_cleanup = ARES_TRUE; - } - - /* If the udp connection hit its max queries, always close it */ - if (!(conn->flags & ARES_CONN_FLAG_TCP) && channel->udp_max_queries > 0 && - conn->total_queries >= channel->udp_max_queries) { - do_cleanup = ARES_TRUE; - } - - if (!do_cleanup) { - continue; - } - - /* Clean it up */ - ares_close_connection(conn, ARES_SUCCESS); - } - } -} diff --git a/vendor/c-ares/src/lib/ares_config.h.cmake b/vendor/c-ares/src/lib/ares_config.h.cmake deleted file mode 100644 index cff181872..000000000 --- a/vendor/c-ares/src/lib/ares_config.h.cmake +++ /dev/null @@ -1,493 +0,0 @@ -/* Copyright (C) The c-ares project and its contributors - * SPDX-License-Identifier: MIT - */ - -/* Generated from ares_config.h.cmake */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* Defined for build with symbol hiding. */ -#cmakedefine CARES_SYMBOL_HIDING - -/* Use resolver library to configure cares */ -#cmakedefine CARES_USE_LIBRESOLV - -/* if a /etc/inet dir is being used */ -#undef ETC_INET - -/* Define to the type of arg 2 for gethostname. */ -#define GETHOSTNAME_TYPE_ARG2 @GETHOSTNAME_TYPE_ARG2@ - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 @GETNAMEINFO_QUAL_ARG1@ - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 @GETNAMEINFO_TYPE_ARG1@ - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 @GETNAMEINFO_TYPE_ARG2@ - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 @GETNAMEINFO_TYPE_ARG46@ - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 @GETNAMEINFO_TYPE_ARG7@ - -/* Specifies the number of arguments to getservbyport_r */ -#define GETSERVBYPORT_R_ARGS @GETSERVBYPORT_R_ARGS@ - -/* Specifies the number of arguments to getservbyname_r */ -#define GETSERVBYNAME_R_ARGS @GETSERVBYNAME_R_ARGS@ - -/* Define to 1 if you have AF_INET6. */ -#cmakedefine HAVE_AF_INET6 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ARPA_NAMESER_COMPAT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ARPA_NAMESER_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ASSERT_H 1 - -/* Define to 1 if you have the clock_gettime function and monotonic timer. */ -#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1 - -/* Define to 1 if you have the closesocket function. */ -#cmakedefine HAVE_CLOSESOCKET 1 - -/* Define to 1 if you have the CloseSocket camel case function. */ -#cmakedefine HAVE_CLOSESOCKET_CAMEL 1 - -/* Define to 1 if you have the connect function. */ -#cmakedefine HAVE_CONNECT 1 - -/* Define to 1 if you have the connectx function. */ -#cmakedefine HAVE_CONNECTX 1 - -/* define if the compiler supports basic C++11 syntax */ -#cmakedefine HAVE_CXX11 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_POLL_H 1 - -/* Define to 1 if you have the memmem function. */ -#cmakedefine HAVE_MEMMEM 1 - -/* Define to 1 if you have the poll function. */ -#cmakedefine HAVE_POLL 1 - -/* Define to 1 if you have the pipe function. */ -#cmakedefine HAVE_PIPE 1 - -/* Define to 1 if you have the pipe2 function. */ -#cmakedefine HAVE_PIPE2 1 - -/* Define to 1 if you have the kqueue function. */ -#cmakedefine HAVE_KQUEUE 1 - -/* Define to 1 if you have the epoll{_create,ctl,wait} functions. */ -#cmakedefine HAVE_EPOLL 1 - -/* Define to 1 if you have the fcntl function. */ -#cmakedefine HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_FCNTL_H 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#cmakedefine HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the freeaddrinfo function. */ -#cmakedefine HAVE_FREEADDRINFO 1 - -/* Define to 1 if you have a working getaddrinfo function. */ -#cmakedefine HAVE_GETADDRINFO 1 - -/* Define to 1 if the getaddrinfo function is threadsafe. */ -#cmakedefine HAVE_GETADDRINFO_THREADSAFE 1 - -/* Define to 1 if you have the getenv function. */ -#cmakedefine HAVE_GETENV 1 - -/* Define to 1 if you have the gethostname function. */ -#cmakedefine HAVE_GETHOSTNAME 1 - -/* Define to 1 if you have the getnameinfo function. */ -#cmakedefine HAVE_GETNAMEINFO 1 - -/* Define to 1 if you have the getrandom function. */ -#cmakedefine HAVE_GETRANDOM 1 - -/* Define to 1 if you have the getservbyport_r function. */ -#cmakedefine HAVE_GETSERVBYPORT_R 1 - -/* Define to 1 if you have the getservbyname_r function. */ -#cmakedefine HAVE_GETSERVBYNAME_R 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#cmakedefine HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the `if_indextoname' function. */ -#cmakedefine HAVE_IF_INDEXTONAME 1 - -/* Define to 1 if you have the `if_nametoindex' function. */ -#cmakedefine HAVE_IF_NAMETOINDEX 1 - -/* Define to 1 if you have the `GetBestRoute2' function. */ -#cmakedefine HAVE_GETBESTROUTE2 1 - -/* Define to 1 if you have the `ConvertInterfaceIndexToLuid' function. */ -#cmakedefine HAVE_CONVERTINTERFACEINDEXTOLUID 1 - -/* Define to 1 if you have the `ConvertInterfaceLuidToNameA' function. */ -#cmakedefine HAVE_CONVERTINTERFACELUIDTONAMEA 1 - -/* Define to 1 if you have the `NotifyIpInterfaceChange' function. */ -#cmakedefine HAVE_NOTIFYIPINTERFACECHANGE 1 - -/* Define to 1 if you have the `RegisterWaitForSingleObject' function. */ -#cmakedefine HAVE_REGISTERWAITFORSINGLEOBJECT 1 - -/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */ -#cmakedefine HAVE_INET_NET_PTON 1 - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -#cmakedefine HAVE_INET_NTOP 1 - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -#cmakedefine HAVE_INET_PTON 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the ioctl function. */ -#cmakedefine HAVE_IOCTL 1 - -/* Define to 1 if you have the ioctlsocket function. */ -#cmakedefine HAVE_IOCTLSOCKET 1 - -/* Define to 1 if you have the IoctlSocket camel case function. */ -#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1 - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. - */ -#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1 - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#cmakedefine HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1 - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -#cmakedefine HAVE_LIBRESOLV 1 - -/* Define to 1 if you have iphlpapi.h */ -#cmakedefine HAVE_IPHLPAPI_H 1 - -/* Define to 1 if you have netioapi.h */ -#cmakedefine HAVE_NETIOAPI_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIMITS_H 1 - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#cmakedefine HAVE_LONGLONG 1 - -/* Define to 1 if you have the malloc.h header file. */ -#cmakedefine HAVE_MALLOC_H 1 - -/* Define to 1 if you have the memory.h header file. */ -#cmakedefine HAVE_MEMORY_H 1 - -/* Define to 1 if you have the AvailabilityMacros.h header file. */ -#cmakedefine HAVE_AVAILABILITYMACROS_H 1 - -/* Define to 1 if you have the MSG_NOSIGNAL flag. */ -#cmakedefine HAVE_MSG_NOSIGNAL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET6_IN6_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NET_IF_H 1 - -/* Define to 1 if you have PF_INET6. */ -#cmakedefine HAVE_PF_INET6 1 - -/* Define to 1 if you have the recv function. */ -#cmakedefine HAVE_RECV 1 - -/* Define to 1 if you have the recvfrom function. */ -#cmakedefine HAVE_RECVFROM 1 - -/* Define to 1 if you have the send function. */ -#cmakedefine HAVE_SEND 1 - -/* Define to 1 if you have the sendto function. */ -#cmakedefine HAVE_SENDTO 1 - -/* Define to 1 if you have the setsockopt function. */ -#cmakedefine HAVE_SETSOCKOPT 1 - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SIGNAL_H 1 - -/* Define to 1 if you have the strnlen function. */ -#cmakedefine HAVE_STRNLEN 1 - -/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ -#cmakedefine HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define to 1 if you have the socket function. */ -#cmakedefine HAVE_SOCKET 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDLIB_H 1 - -/* Define to 1 if you have the strcasecmp function. */ -#cmakedefine HAVE_STRCASECMP 1 - -/* Define to 1 if you have the strcmpi function. */ -#cmakedefine HAVE_STRCMPI 1 - -/* Define to 1 if you have the strdup function. */ -#cmakedefine HAVE_STRDUP 1 - -/* Define to 1 if you have the stricmp function. */ -#cmakedefine HAVE_STRICMP 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRING_H 1 - -/* Define to 1 if you have the strncasecmp function. */ -#cmakedefine HAVE_STRNCASECMP 1 - -/* Define to 1 if you have the strncmpi function. */ -#cmakedefine HAVE_STRNCMPI 1 - -/* Define to 1 if you have the strnicmp function. */ -#cmakedefine HAVE_STRNICMP 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STROPTS_H 1 - -/* Define to 1 if you have struct addrinfo. */ -#cmakedefine HAVE_STRUCT_ADDRINFO 1 - -/* Define to 1 if you have struct in6_addr. */ -#cmakedefine HAVE_STRUCT_IN6_ADDR 1 - -/* Define to 1 if you have struct sockaddr_in6. */ -#cmakedefine HAVE_STRUCT_SOCKADDR_IN6 1 - -/* if struct sockaddr_storage is defined */ -#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if you have the timeval struct. */ -#cmakedefine HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_RANDOM_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_EVENT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_EPOLL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_IFADDRS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H 1 - -/* Define to 1 if you have the windows.h header file. */ -#cmakedefine HAVE_WINDOWS_H 1 - -/* Define to 1 if you have the winsock2.h header file. */ -#cmakedefine HAVE_WINSOCK2_H 1 - -/* Define to 1 if you have the winsock.h header file. */ -#cmakedefine HAVE_WINSOCK_H 1 - -/* Define to 1 if you have the mswsock.h header file. */ -#cmakedefine HAVE_MSWSOCK_H 1 - -/* Define to 1 if you have the winternl.h header file. */ -#cmakedefine HAVE_WINTERNL_H 1 - -/* Define to 1 if you have the ntstatus.h header file. */ -#cmakedefine HAVE_NTSTATUS_H 1 - -/* Define to 1 if you have the ntdef.h header file. */ -#cmakedefine HAVE_NTDEF_H 1 - -/* Define to 1 if you have the writev function. */ -#cmakedefine HAVE_WRITEV 1 - -/* Define to 1 if you have the ws2tcpip.h header file. */ -#cmakedefine HAVE_WS2TCPIP_H 1 - -/* Define to 1 if you have the __system_property_get function */ -#cmakedefine HAVE___SYSTEM_PROPERTY_GET 1 - -/* Define if have arc4random_buf() */ -#cmakedefine HAVE_ARC4RANDOM_BUF 1 - -/* Define if have getifaddrs() */ -#cmakedefine HAVE_GETIFADDRS 1 - -/* Define if have stat() */ -#cmakedefine HAVE_STAT 1 - -/* a suitable file/device to read random data from */ -#cmakedefine CARES_RANDOM_FILE "@CARES_RANDOM_FILE@" - -/* Define to the type qualifier pointed by arg 5 for recvfrom. */ -#define RECVFROM_QUAL_ARG5 @RECVFROM_QUAL_ARG5@ - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 @RECVFROM_TYPE_ARG1@ - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 @RECVFROM_TYPE_ARG2@ - -/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ -#cmakedefine01 RECVFROM_TYPE_ARG2_IS_VOID - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 @RECVFROM_TYPE_ARG3@ - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 @RECVFROM_TYPE_ARG4@ - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 @RECVFROM_TYPE_ARG5@ - -/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ -#cmakedefine01 RECVFROM_TYPE_ARG5_IS_VOID - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 @RECVFROM_TYPE_ARG6@ - -/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ -#cmakedefine01 RECVFROM_TYPE_ARG6_IS_VOID - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV @RECVFROM_TYPE_RETV@ - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 @RECV_TYPE_ARG1@ - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 @RECV_TYPE_ARG2@ - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 @RECV_TYPE_ARG3@ - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 @RECV_TYPE_ARG4@ - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV @RECV_TYPE_RETV@ - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 @SEND_TYPE_ARG1@ - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 @SEND_TYPE_ARG2@ - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 @SEND_TYPE_ARG3@ - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 @SEND_TYPE_ARG4@ - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV @SEND_TYPE_RETV@ - -/* Define to disable non-blocking sockets. */ -#undef USE_BLOCKING_SOCKETS - -/* Define to avoid automatic inclusion of winsock.h */ -#undef WIN32_LEAN_AND_MEAN - -/* Define to 1 if you have the pthread.h header file. */ -#cmakedefine HAVE_PTHREAD_H 1 - -/* Define to 1 if you have the pthread_np.h header file. */ -#cmakedefine HAVE_PTHREAD_NP_H 1 - -/* Define to 1 if threads are enabled */ -#cmakedefine CARES_THREADS 1 - -/* Define to 1 if pthread_init() exists */ -#cmakedefine HAVE_PTHREAD_INIT 1 - diff --git a/vendor/c-ares/src/lib/ares_conn.c b/vendor/c-ares/src/lib/ares_conn.c deleted file mode 100644 index 6b315b054..000000000 --- a/vendor/c-ares/src/lib/ares_conn.c +++ /dev/null @@ -1,511 +0,0 @@ -/* MIT License - * - * Copyright (c) Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -void ares_conn_sock_state_cb_update(ares_conn_t *conn, - ares_conn_state_flags_t flags) -{ - ares_channel_t *channel = conn->server->channel; - - if ((conn->state_flags & ARES_CONN_STATE_CBFLAGS) != flags && - channel->sock_state_cb) { - channel->sock_state_cb(channel->sock_state_cb_data, conn->fd, - flags & ARES_CONN_STATE_READ ? 1 : 0, - flags & ARES_CONN_STATE_WRITE ? 1 : 0); - } - - conn->state_flags &= ~((unsigned int)ARES_CONN_STATE_CBFLAGS); - conn->state_flags |= flags; -} - -ares_conn_err_t ares_conn_read(ares_conn_t *conn, void *data, size_t len, - size_t *read_bytes) -{ - ares_channel_t *channel = conn->server->channel; - ares_conn_err_t err; - - if (!(conn->flags & ARES_CONN_FLAG_TCP)) { - struct sockaddr_storage sa_storage; - ares_socklen_t salen = sizeof(sa_storage); - - memset(&sa_storage, 0, sizeof(sa_storage)); - - err = - ares_socket_recvfrom(channel, conn->fd, ARES_FALSE, data, len, 0, - (struct sockaddr *)&sa_storage, &salen, read_bytes); - -#ifdef HAVE_RECVFROM - if (err == ARES_CONN_ERR_SUCCESS && - !ares_sockaddr_addr_eq((struct sockaddr *)&sa_storage, - &conn->server->addr)) { - err = ARES_CONN_ERR_WOULDBLOCK; - } -#endif - } else { - err = ares_socket_recv(channel, conn->fd, ARES_TRUE, data, len, read_bytes); - } - - /* Toggle connected state if needed */ - if (err == ARES_CONN_ERR_SUCCESS) { - conn->state_flags |= ARES_CONN_STATE_CONNECTED; - } - - return err; -} - -/* Use like: - * struct sockaddr_storage sa_storage; - * ares_socklen_t salen = sizeof(sa_storage); - * struct sockaddr *sa = (struct sockaddr *)&sa_storage; - * ares_conn_set_sockaddr(conn, sa, &salen); - */ -static ares_status_t ares_conn_set_sockaddr(const ares_conn_t *conn, - struct sockaddr *sa, - ares_socklen_t *salen) -{ - const ares_server_t *server = conn->server; - unsigned short port = - conn->flags & ARES_CONN_FLAG_TCP ? server->tcp_port : server->udp_port; - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; - - switch (server->addr.family) { - case AF_INET: - sin = (struct sockaddr_in *)(void *)sa; - if (*salen < (ares_socklen_t)sizeof(*sin)) { - return ARES_EFORMERR; - } - *salen = sizeof(*sin); - memset(sin, 0, sizeof(*sin)); - sin->sin_family = AF_INET; - sin->sin_port = htons(port); - memcpy(&sin->sin_addr, &server->addr.addr.addr4, sizeof(sin->sin_addr)); - return ARES_SUCCESS; - case AF_INET6: - sin6 = (struct sockaddr_in6 *)(void *)sa; - if (*salen < (ares_socklen_t)sizeof(*sin6)) { - return ARES_EFORMERR; - } - *salen = sizeof(*sin6); - memset(sin6, 0, sizeof(*sin6)); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons(port); - memcpy(&sin6->sin6_addr, &server->addr.addr.addr6, - sizeof(sin6->sin6_addr)); -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID - sin6->sin6_scope_id = server->ll_scope; -#endif - return ARES_SUCCESS; - default: - break; - } - - return ARES_EBADFAMILY; -} - -static ares_status_t ares_conn_set_self_ip(ares_conn_t *conn, ares_bool_t early) -{ - ares_channel_t *channel = conn->server->channel; - struct sockaddr_storage sa_storage; - int rv; - ares_socklen_t len = sizeof(sa_storage); - - /* We call this twice on TFO, if we already have the IP we can go ahead and - * skip processing */ - if (!early && conn->self_ip.family != AF_UNSPEC) { - return ARES_SUCCESS; - } - - memset(&sa_storage, 0, sizeof(sa_storage)); - - if (channel->sock_funcs.agetsockname == NULL) { - /* Not specified, we can still use cookies cooked with an empty self_ip */ - memset(&conn->self_ip, 0, sizeof(conn->self_ip)); - return ARES_SUCCESS; - } - rv = channel->sock_funcs.agetsockname(conn->fd, - (struct sockaddr *)(void *)&sa_storage, - &len, channel->sock_func_cb_data); - if (rv != 0) { - /* During TCP FastOpen, we can't get the IP this early since connect() - * may not be called. That's ok, we'll try again later */ - if (early && conn->flags & ARES_CONN_FLAG_TCP && - conn->flags & ARES_CONN_FLAG_TFO) { - memset(&conn->self_ip, 0, sizeof(conn->self_ip)); - return ARES_SUCCESS; - } - return ARES_ECONNREFUSED; - } - - if (!ares_sockaddr_to_ares_addr(&conn->self_ip, NULL, - (struct sockaddr *)(void *)&sa_storage)) { - return ARES_ECONNREFUSED; - } - - return ARES_SUCCESS; -} - -ares_conn_err_t ares_conn_write(ares_conn_t *conn, const void *data, size_t len, - size_t *written) -{ - ares_channel_t *channel = conn->server->channel; - ares_bool_t is_tfo = ARES_FALSE; - ares_conn_err_t err = ARES_CONN_ERR_SUCCESS; - struct sockaddr_storage sa_storage; - ares_socklen_t salen = 0; - struct sockaddr *sa = NULL; - - *written = 0; - - /* Don't try to write if not doing initial TFO and not connected */ - if (conn->flags & ARES_CONN_FLAG_TCP && - !(conn->state_flags & ARES_CONN_STATE_CONNECTED) && - !(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) { - return ARES_CONN_ERR_WOULDBLOCK; - } - - /* On initial write during TFO we need to send an address */ - if (conn->flags & ARES_CONN_FLAG_TFO_INITIAL) { - salen = sizeof(sa_storage); - sa = (struct sockaddr *)&sa_storage; - - conn->flags &= ~((unsigned int)ARES_CONN_FLAG_TFO_INITIAL); - is_tfo = ARES_TRUE; - - if (ares_conn_set_sockaddr(conn, sa, &salen) != ARES_SUCCESS) { - return ARES_CONN_ERR_FAILURE; - } - } - - err = ares_socket_write(channel, conn->fd, data, len, written, sa, salen); - if (err != ARES_CONN_ERR_SUCCESS) { - goto done; - } - - if (is_tfo) { - /* If using TFO, we might not have been able to get an IP earlier, since - * we hadn't informed the OS of the destination. When using sendto() - * now we have so we should be able to fetch it */ - ares_conn_set_self_ip(conn, ARES_FALSE); - goto done; - } - -done: - if (err == ARES_CONN_ERR_SUCCESS && len == *written) { - /* Wrote all data, make sure we're not listening for write events unless - * using TFO, in which case we'll need a write event to know when - * we're connected. */ - ares_conn_sock_state_cb_update( - conn, ARES_CONN_STATE_READ | - (is_tfo ? ARES_CONN_STATE_WRITE : ARES_CONN_STATE_NONE)); - } else if (err == ARES_CONN_ERR_WOULDBLOCK) { - /* Need to wait on more buffer space to write */ - ares_conn_sock_state_cb_update(conn, ARES_CONN_STATE_READ | - ARES_CONN_STATE_WRITE); - } - - return err; -} - -ares_status_t ares_conn_flush(ares_conn_t *conn) -{ - const unsigned char *data; - size_t data_len; - size_t count; - ares_conn_err_t err; - ares_status_t status; - ares_bool_t tfo = ARES_FALSE; - - if (conn == NULL) { - return ARES_EFORMERR; - } - - if (conn->flags & ARES_CONN_FLAG_TFO_INITIAL) { - tfo = ARES_TRUE; - } - - do { - if (ares_buf_len(conn->out_buf) == 0) { - status = ARES_SUCCESS; - goto done; - } - - if (conn->flags & ARES_CONN_FLAG_TCP) { - data = ares_buf_peek(conn->out_buf, &data_len); - } else { - unsigned short msg_len; - - /* Read length, then provide buffer without length */ - ares_buf_tag(conn->out_buf); - status = ares_buf_fetch_be16(conn->out_buf, &msg_len); - if (status != ARES_SUCCESS) { - return status; - } - ares_buf_tag_rollback(conn->out_buf); - - data = ares_buf_peek(conn->out_buf, &data_len); - if (data_len < (size_t)(msg_len + 2)) { - status = ARES_EFORMERR; - goto done; - } - data += 2; - data_len = msg_len; - } - - err = ares_conn_write(conn, data, data_len, &count); - if (err != ARES_CONN_ERR_SUCCESS) { - if (err != ARES_CONN_ERR_WOULDBLOCK) { - status = ARES_ECONNREFUSED; - goto done; - } - status = ARES_SUCCESS; - goto done; - } - - /* UDP didn't send the length prefix so augment that here */ - if (!(conn->flags & ARES_CONN_FLAG_TCP)) { - count += 2; - } - - /* Strip data written from the buffer */ - ares_buf_consume(conn->out_buf, count); - status = ARES_SUCCESS; - - /* Loop only for UDP since we have to send per-packet. We already - * sent everything we could if using tcp */ - } while (!(conn->flags & ARES_CONN_FLAG_TCP)); - -done: - if (status == ARES_SUCCESS) { - ares_conn_state_flags_t flags = ARES_CONN_STATE_READ; - - /* When using TFO, the we need to enabling waiting on a write event to - * be notified of when a connection is actually established */ - if (tfo) { - flags |= ARES_CONN_STATE_WRITE; - } - - /* If using TCP and not all data was written (partial write), that means - * we need to also wait on a write event */ - if (conn->flags & ARES_CONN_FLAG_TCP && ares_buf_len(conn->out_buf)) { - flags |= ARES_CONN_STATE_WRITE; - } - - ares_conn_sock_state_cb_update(conn, flags); - } - - return status; -} - -static ares_status_t ares_conn_connect(ares_conn_t *conn, - const struct sockaddr *sa, - ares_socklen_t salen) -{ - ares_conn_err_t err; - - err = ares_socket_connect( - conn->server->channel, conn->fd, - (conn->flags & ARES_CONN_FLAG_TFO) ? ARES_TRUE : ARES_FALSE, sa, salen); - - if (err != ARES_CONN_ERR_WOULDBLOCK && err != ARES_CONN_ERR_SUCCESS) { - return ARES_ECONNREFUSED; - } - return ARES_SUCCESS; -} - -ares_status_t ares_open_connection(ares_conn_t **conn_out, - ares_channel_t *channel, - ares_server_t *server, ares_bool_t is_tcp) -{ - ares_status_t status; - struct sockaddr_storage sa_storage; - ares_socklen_t salen = sizeof(sa_storage); - struct sockaddr *sa = (struct sockaddr *)&sa_storage; - ares_conn_t *conn; - ares_llist_node_t *node = NULL; - int stype = is_tcp ? SOCK_STREAM : SOCK_DGRAM; - ares_conn_state_flags_t state_flags; - - *conn_out = NULL; - - conn = ares_malloc(sizeof(*conn)); - if (conn == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - memset(conn, 0, sizeof(*conn)); - conn->fd = ARES_SOCKET_BAD; - conn->server = server; - conn->queries_to_conn = ares_llist_create(NULL); - conn->flags = is_tcp ? ARES_CONN_FLAG_TCP : ARES_CONN_FLAG_NONE; - conn->out_buf = ares_buf_create(); - conn->in_buf = ares_buf_create(); - - if (conn->queries_to_conn == NULL || conn->out_buf == NULL || - conn->in_buf == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - status = ARES_ENOMEM; - goto done; - /* LCOV_EXCL_STOP */ - } - - /* Try to enable TFO always if using TCP. it will fail later on if its - * really not supported when we try to enable it on the socket. */ - if (conn->flags & ARES_CONN_FLAG_TCP) { - conn->flags |= ARES_CONN_FLAG_TFO; - } - - /* Convert into the struct sockaddr structure needed by the OS */ - status = ares_conn_set_sockaddr(conn, sa, &salen); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Acquire a socket. */ - if (ares_socket_open(&conn->fd, channel, server->addr.family, stype, 0) != - ARES_CONN_ERR_SUCCESS) { - status = ARES_ECONNREFUSED; - goto done; - } - - /* Configure channel configured options */ - status = ares_socket_configure( - channel, server->addr.family, - (conn->flags & ARES_CONN_FLAG_TCP) ? ARES_TRUE : ARES_FALSE, conn->fd); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Enable TFO if possible */ - if (conn->flags & ARES_CONN_FLAG_TFO && - ares_socket_enable_tfo(channel, conn->fd) != ARES_CONN_ERR_SUCCESS) { - conn->flags &= ~((unsigned int)ARES_CONN_FLAG_TFO); - } - - if (channel->sock_config_cb) { - int err = - channel->sock_config_cb(conn->fd, stype, channel->sock_config_cb_data); - if (err < 0) { - status = ARES_ECONNREFUSED; - goto done; - } - } - - /* Connect */ - status = ares_conn_connect(conn, sa, salen); - if (status != ARES_SUCCESS) { - goto done; - } - - if (channel->sock_create_cb) { - int err = - channel->sock_create_cb(conn->fd, stype, channel->sock_create_cb_data); - if (err < 0) { - status = ARES_ECONNREFUSED; - goto done; - } - } - - /* Let the connection know we haven't written our first packet yet for TFO */ - if (conn->flags & ARES_CONN_FLAG_TFO) { - conn->flags |= ARES_CONN_FLAG_TFO_INITIAL; - } - - /* Need to store our own ip for DNS cookie support */ - status = ares_conn_set_self_ip(conn, ARES_TRUE); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: UntestablePath */ - } - - /* TCP connections are thrown to the end as we don't spawn multiple TCP - * connections. UDP connections are put on front where the newest connection - * can be quickly pulled */ - if (is_tcp) { - node = ares_llist_insert_last(server->connections, conn); - } else { - node = ares_llist_insert_first(server->connections, conn); - } - if (node == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - status = ARES_ENOMEM; - goto done; - /* LCOV_EXCL_STOP */ - } - - /* Register globally to quickly map event on file descriptor to connection - * node object */ - if (!ares_htable_asvp_insert(channel->connnode_by_socket, conn->fd, node)) { - /* LCOV_EXCL_START: OutOfMemory */ - status = ARES_ENOMEM; - goto done; - /* LCOV_EXCL_STOP */ - } - - state_flags = ARES_CONN_STATE_READ; - - /* Get notified on connect if using TCP */ - if (conn->flags & ARES_CONN_FLAG_TCP) { - state_flags |= ARES_CONN_STATE_WRITE; - } - - /* Dot no attempt to update sock state callbacks on TFO until *after* the - * initial write is performed. Due to the notification event, its possible - * an erroneous read can come in before the attempt to write the data which - * might be used to set the ip address */ - if (!(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) { - ares_conn_sock_state_cb_update(conn, state_flags); - } - - if (is_tcp) { - server->tcp_conn = conn; - } - -done: - if (status != ARES_SUCCESS) { - ares_llist_node_claim(node); - ares_llist_destroy(conn->queries_to_conn); - ares_socket_close(channel, conn->fd); - ares_buf_destroy(conn->out_buf); - ares_buf_destroy(conn->in_buf); - ares_free(conn); - } else { - *conn_out = conn; - } - return status; -} - -ares_conn_t *ares_conn_from_fd(const ares_channel_t *channel, ares_socket_t fd) -{ - ares_llist_node_t *node; - - node = ares_htable_asvp_get_direct(channel->connnode_by_socket, fd); - if (node == NULL) { - return NULL; - } - - return ares_llist_node_val(node); -} diff --git a/vendor/c-ares/src/lib/ares_conn.h b/vendor/c-ares/src/lib/ares_conn.h deleted file mode 100644 index 16ecefdd1..000000000 --- a/vendor/c-ares/src/lib/ares_conn.h +++ /dev/null @@ -1,196 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_CONN_H -#define __ARES_CONN_H - -#include "ares_socket.h" - -struct ares_conn; -typedef struct ares_conn ares_conn_t; - -struct ares_server; -typedef struct ares_server ares_server_t; - -typedef enum { - /*! No flags */ - ARES_CONN_FLAG_NONE = 0, - /*! TCP connection, not UDP */ - ARES_CONN_FLAG_TCP = 1 << 0, - /*! TCP Fast Open is enabled and being used if supported by the OS */ - ARES_CONN_FLAG_TFO = 1 << 1, - /*! TCP Fast Open has not yet sent its first packet. Gets unset on first - * write to a connection */ - ARES_CONN_FLAG_TFO_INITIAL = 1 << 2 -} ares_conn_flags_t; - -typedef enum { - ARES_CONN_STATE_NONE = 0, - ARES_CONN_STATE_READ = 1 << 0, - ARES_CONN_STATE_WRITE = 1 << 1, - ARES_CONN_STATE_CONNECTED = 1 << 2, /* This doesn't get a callback */ - ARES_CONN_STATE_CBFLAGS = ARES_CONN_STATE_READ | ARES_CONN_STATE_WRITE -} ares_conn_state_flags_t; - -struct ares_conn { - ares_server_t *server; - ares_socket_t fd; - struct ares_addr self_ip; - ares_conn_flags_t flags; - ares_conn_state_flags_t state_flags; - - /*! Outbound buffered data that is not yet sent. Exists as one contiguous - * stream in TCP format (big endian 16bit length prefix followed by DNS - * wire-format message). For TCP this can be sent as-is, UDP this must - * be sent per-packet (stripping the length prefix) */ - ares_buf_t *out_buf; - - /*! Inbound buffered data that is not yet parsed. Exists as one contiguous - * stream in TCP format (big endian 16bit length prefix followed by DNS - * wire-format message). TCP may have partial data and this needs to be - * handled gracefully, but UDP will always have a full message */ - ares_buf_t *in_buf; - - /* total number of queries run on this connection since it was established */ - size_t total_queries; - - /* list of outstanding queries to this connection */ - ares_llist_t *queries_to_conn; -}; - -/*! Various buckets for grouping history */ -typedef enum { - ARES_METRIC_1MINUTE = 0, /*!< Bucket for tracking over the last minute */ - ARES_METRIC_15MINUTES, /*!< Bucket for tracking over the last 15 minutes */ - ARES_METRIC_1HOUR, /*!< Bucket for tracking over the last hour */ - ARES_METRIC_1DAY, /*!< Bucket for tracking over the last day */ - ARES_METRIC_INCEPTION, /*!< Bucket for tracking since inception */ - ARES_METRIC_COUNT /*!< Count of buckets, not a real bucket */ -} ares_server_bucket_t; - -/*! Data metrics collected for each bucket */ -typedef struct { - time_t ts; /*!< Timestamp divided by bucket divisor */ - unsigned int latency_min_ms; /*!< Minimum latency for queries */ - unsigned int latency_max_ms; /*!< Maximum latency for queries */ - ares_uint64_t total_ms; /*!< Cumulative query time for bucket */ - ares_uint64_t total_count; /*!< Number of queries for bucket */ - - time_t prev_ts; /*!< Previous period bucket timestamp */ - ares_uint64_t - prev_total_ms; /*!< Previous period bucket cumulative query time */ - ares_uint64_t prev_total_count; /*!< Previous period bucket query count */ -} ares_server_metrics_t; - -typedef enum { - ARES_COOKIE_INITIAL = 0, - ARES_COOKIE_GENERATED = 1, - ARES_COOKIE_SUPPORTED = 2, - ARES_COOKIE_UNSUPPORTED = 3 -} ares_cookie_state_t; - -/*! Structure holding tracking data for RFC 7873/9018 DNS cookies. - * Implementation plan for this feature is here: - * https://github.com/c-ares/c-ares/issues/620 - */ -typedef struct { - /*! starts at INITIAL, transitions as needed. */ - ares_cookie_state_t state; - /*! randomly-generate client cookie */ - unsigned char client[8]; - /*! timestamp client cookie was generated, used for rotation purposes */ - ares_timeval_t client_ts; - /*! IP address last used for client to connect to server. If this changes - * The client cookie gets invalidated */ - struct ares_addr client_ip; - /*! Server Cookie last received, 8-32 bytes in length */ - unsigned char server[32]; - /*! Length of server cookie on file. */ - size_t server_len; - /*! Timestamp of last attempt to use cookies, but it was determined that the - * server didn't support them */ - ares_timeval_t unsupported_ts; -} ares_cookie_t; - -struct ares_server { - /* Configuration */ - size_t idx; /* index for server in system configuration */ - struct ares_addr addr; - unsigned short udp_port; /* host byte order */ - unsigned short tcp_port; /* host byte order */ - char ll_iface[64]; /* IPv6 Link Local Interface */ - unsigned int ll_scope; /* IPv6 Link Local Scope */ - - size_t consec_failures; /* Consecutive query failure count - * can be hard errors or timeouts - */ - ares_bool_t probe_pending; /* Whether a probe is pending for this - * server due to prior failures */ - ares_llist_t *connections; - ares_conn_t *tcp_conn; - - /* The next time when we will retry this server if it has hit failures */ - ares_timeval_t next_retry_time; - - /*! Buckets for collecting metrics about the server */ - ares_server_metrics_t metrics[ARES_METRIC_COUNT]; - - /*! RFC 7873/9018 DNS Cookies */ - ares_cookie_t cookie; - - /* Link back to owning channel */ - ares_channel_t *channel; -}; - -void ares_close_connection(ares_conn_t *conn, ares_status_t requeue_status); -void ares_close_sockets(ares_server_t *server); -void ares_check_cleanup_conns(const ares_channel_t *channel); - -void ares_destroy_servers_state(ares_channel_t *channel); -ares_status_t ares_open_connection(ares_conn_t **conn_out, - ares_channel_t *channel, - ares_server_t *server, ares_bool_t is_tcp); - -ares_conn_err_t ares_conn_write(ares_conn_t *conn, const void *data, size_t len, - size_t *written); -ares_status_t ares_conn_flush(ares_conn_t *conn); -ares_conn_err_t ares_conn_read(ares_conn_t *conn, void *data, size_t len, - size_t *read_bytes); -ares_conn_t *ares_conn_from_fd(const ares_channel_t *channel, ares_socket_t fd); -void ares_conn_sock_state_cb_update(ares_conn_t *conn, - ares_conn_state_flags_t flags); -ares_conn_err_t ares_socket_recv(ares_channel_t *channel, ares_socket_t s, - ares_bool_t is_tcp, void *data, - size_t data_len, size_t *read_bytes); -ares_conn_err_t ares_socket_recvfrom(ares_channel_t *channel, ares_socket_t s, - ares_bool_t is_tcp, void *data, - size_t data_len, int flags, - struct sockaddr *from, - ares_socklen_t *from_len, - size_t *read_bytes); - -void ares_destroy_server(ares_server_t *server); - -#endif diff --git a/vendor/c-ares/src/lib/ares_cookie.c b/vendor/c-ares/src/lib/ares_cookie.c deleted file mode 100644 index 509e12050..000000000 --- a/vendor/c-ares/src/lib/ares_cookie.c +++ /dev/null @@ -1,461 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -/* DNS cookies are a simple form of learned mutual authentication supported by - * most DNS server implementations these days and can help prevent DNS Cache - * Poisoning attacks for clients and DNS amplification attacks for servers. - * - * A good overview is here: - * https://www.dotmagazine.online/issues/digital-responsibility-and-sustainability/dns-cookies-transaction-mechanism - * - * RFCs used for implementation are - * [RFC7873](https://datatracker.ietf.org/doc/html/rfc7873) which is extended by - * [RFC9018](https://datatracker.ietf.org/doc/html/rfc9018). - * - * Though this could be used on TCP, the likelihood of it being useful is small - * and could cause some issues. TCP is better used as a fallback in case there - * are issues with DNS Cookie support in the upstream servers (e.g. AnyCast - * cluster issues). - * - * While most recursive DNS servers support DNS Cookies, public DNS servers like - * Google (8.8.8.8, 8.8.4.4) and CloudFlare (1.1.1.1, 1.0.0.1) don't seem to - * have this enabled yet for unknown reasons. - * - * The risk to having DNS Cookie support always enabled is nearly zero as there - * is built-in detection support and it will simply bypass using cookies if the - * remote server doesn't support it. The problem arises if a remote server - * supports DNS cookies, then stops supporting them (such as if an administrator - * reconfigured the server, or maybe there are different servers in a cluster - * with different configurations). We need to detect this behavior by tracking - * how much time has gone by since we received our last valid cookie reply, and - * if we exceed the threshold, reset all cookie parameters like we haven't - * attempted a request yet. - * - * ## Implementation Plan - * - * ### Constants: - * - `COOKIE_CLIENT_TIMEOUT`: 86400s (1 day) - * - How often to regenerate the per-server client cookie, even if our - * source ip address hasn't changed. - * - `COOKIE_UNSUPPORTED_TIMEOUT`: 300s (5 minutes) - * - If a server responds without a cookie in the reply, this is how long to - * wait before attempting to send a client cookie again. - * - `COOKIE_REGRESSION_TIMEOUT`: 120s (2 minutes) - * - If a server was once known to return cookies, and all of a sudden stops - * returning cookies (but the reply is otherwise valid), this is how long - * to continue to attempt to use cookies before giving up and resetting. - * Such an event would cause an outage for this duration, but since a - * cache poisoning attack should be dropping invalid replies we should be - * able to still get the valid reply and not assume it is a server - * regression just because we received replies without cookies. - * - `COOKIE_RESEND_MAX`: 3 - * - Maximum times to resend a query to a server due to the server responding - * with `BAD_COOKIE`, after this, we switch to TCP. - * - * ### Per-server variables: - * - `cookie.state`: Known state of cookie support, enumeration. - * - `INITIAL` (0): Initial state, not yet determined. Used during startup. - * - `GENERATED` (1): Cookie has been generated and sent to a server, but no - * validated response yet. - * - `SUPPORTED` (2): Server has been determined to properly support cookies - * - `UNSUPPORTED` (3): Server has been determined to not support cookies - * - `cookie.client` : 8 byte randomly generated client cookie - * - `cookie.client_ts`: Timestamp client cookie was generated - * - `cookie.client_ip`: IP address client used to connect to server - * - `cookie.server`: 8 to 32 byte server cookie - * - `cookie.server_len`: length of server cookie - * - `cookie.unsupported_ts`: Timestamp of last attempt to use a cookies, but - * it was determined that the server didn't support them. - * - * ### Per-query variables: - * - `query.client_cookie`: Duplicate of `cookie.client` at the point in time - * the query is put on the wire. This should be available in the - * `ares_dns_record_t` for the request for verification purposes so we don't - * actually need to duplicate this, just naming it here for the ease of - * documentation below. - * - `query.cookie_try_count`: Number of tries to send a cookie but receive - * `BAD_COOKIE` responses. Used to know when we need to switch to TCP. - * - * ### Procedure: - * **NOTE**: These steps will all be done after obtaining a connection handle as - * some of these steps depend on determining the source ip address for the - * connection. - * - * 1. If the query is not using EDNS, then **skip any remaining processing**. - * 2. If using TCP, ensure there is no EDNS cookie opt (10) set (there may have - * been if this is a resend after upgrade to TCP), then **skip any remaining - * processing**. - * 3. If `cookie.state == SUPPORTED`, `cookie.unsupported_ts` is non-zero, and - * evaluates greater than `COOKIE_REGRESSION_TIMEOUT`, then clear all cookie - * settings, set `cookie.state = INITIAL`. Continue to next step (4) - * 4. If `cookie.state == UNSUPPORTED` - * - If `cookie.unsupported_ts` evaluates less than - * `COOKIE_UNSUPPORTED_TIMEOUT` - * - Ensure there is no EDNS cookie opt (10) set (shouldn't be unless - * requester had put this themselves), then **skip any remaining - * processing** as we don't want to try to send cookies. - * - Otherwise: - * - clear all cookie settings, set `cookie.state = INITIAL`. - * - Continue to next step (5) which will send a new cookie. - * 5. If `cookie.state == INITIAL`: - * - randomly generate new `cookie.client` - * - set `cookie.client_ts` to the current timestamp. - * - set `cookie.state = GENERATED`. - * - set `cookie.client_ip` to the current source ip address. - * 6. If `cookie.state == GENERATED || cookie.state == SUPPORTED` and - * `cookie.client_ip` does not match the current source ip address: - * - clear `cookie.server` - * - randomly generate new `cookie.client` - * - set `cookie.client_ts` to the current timestamp. - * - set `cookie.client_ip` to the current source ip address. - * - do not change the `cookie.state` - * 7. If `cookie.state == SUPPORTED` and `cookie.client_ts` evaluation exceeds - * `COOKIE_CLIENT_TIMEOUT`: - * - clear `cookie.server` - * - randomly generate new `cookie.client` - * - set `cookie.client_ts` to the current timestamp. - * - set `cookie.client_ip` to the current source ip address. - * - do not change the `cookie.state` - * 8. Generate EDNS OPT record (10) for client cookie. The option value will be - * the `cookie.client` concatenated with the `cookie.server`. If there is no - * known server cookie, it will not be appended. Copy `cookie.client` to - * `query.client_cookie` to handle possible client cookie changes by other - * queries before a reply is received (technically this is in the cached - * `ares_dns_record_t` so no need to manually do this). Send request to - * server. - * 9. Evaluate response: - * 1. If invalid EDNS OPT cookie (10) length sent back in response (valid - * length is 16-40), or bad client cookie value (validate first 8 bytes - * against `query.client_cookie` not `cookie.client`), **drop response** - * as if it hadn't been received. This is likely a spoofing attack. - * Wait for valid response up to normal response timeout. - * 2. If a EDNS OPT cookie (10) server cookie is returned: - * - set `cookie.unsupported_ts` to zero and `cookie.state = SUPPORTED`. - * We can confirm this server supports cookies based on the existence - * of this record. - * - If a new EDNS OPT cookie (10) server cookie is in the response, and - * the `client.cookie` matches the `query.client_cookie` still (hasn't - * been rotated by some other parallel query), save it as - * `cookie.server`. - * 3. If dns response `rcode` is `BAD_COOKIE`: - * - Ensure a EDNS OPT cookie (10) is returned, otherwise **drop - * response**, this is completely invalid and likely an spoof of some - * sort. - * - Otherwise - * - Increment `query.cookie_try_count` - * - If `query.cookie_try_count >= COOKIE_RESEND_MAX`, set - * `query.using_tcp` to force the next attempt to use TCP. - * - **Requeue the query**, but do not increment the normal - * `try_count` as a `BAD_COOKIE` reply isn't a normal try failure. - * This should end up going all the way back to step 1 on the next - * attempt. - * 4. If EDNS OPT cookie (10) is **NOT** returned in the response: - * - If `cookie.state == SUPPORTED` - * - if `cookie.unsupported_ts` is zero, set to the current timestamp. - * - Drop the response, wait for a valid response to be returned - * - if `cookie.state == GENERATED` - * - clear all cookie settings - * - set `cookie.state = UNSUPPORTED` - * - set `cookie.unsupported_ts` to the current time - * - Accept response (state should be `UNSUPPORTED` if we're here) - */ - -#include "ares_private.h" - -/* 1 day */ -#define COOKIE_CLIENT_TIMEOUT_MS (86400 * 1000) - -/* 5 minutes */ -#define COOKIE_UNSUPPORTED_TIMEOUT_MS (300 * 1000) - -/* 2 minutes */ -#define COOKIE_REGRESSION_TIMEOUT_MS (120 * 1000) - -#define COOKIE_RESEND_MAX 3 - -static const unsigned char * - ares_dns_cookie_fetch(const ares_dns_record_t *dnsrec, size_t *len) -{ - const ares_dns_rr_t *rr = ares_dns_get_opt_rr_const(dnsrec); - const unsigned char *val = NULL; - *len = 0; - - if (rr == NULL) { - return NULL; - } - - if (!ares_dns_rr_get_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE, - &val, len)) { - return NULL; - } - - return val; -} - -static ares_bool_t timeval_is_set(const ares_timeval_t *tv) -{ - if (tv->sec != 0 && tv->usec != 0) { - return ARES_TRUE; - } - return ARES_FALSE; -} - -static ares_bool_t timeval_expired(const ares_timeval_t *tv, - const ares_timeval_t *now, - unsigned long millsecs) -{ - ares_int64_t tvdiff_ms; - ares_timeval_t tvdiff; - ares_timeval_diff(&tvdiff, tv, now); - - tvdiff_ms = tvdiff.sec * 1000 + tvdiff.usec / 1000; - if (tvdiff_ms >= (ares_int64_t)millsecs) { - return ARES_TRUE; - } - return ARES_FALSE; -} - -static void ares_cookie_clear(ares_cookie_t *cookie) -{ - memset(cookie, 0, sizeof(*cookie)); - cookie->state = ARES_COOKIE_INITIAL; -} - -static void ares_cookie_generate(ares_cookie_t *cookie, ares_conn_t *conn, - const ares_timeval_t *now) -{ - ares_channel_t *channel = conn->server->channel; - - ares_rand_bytes(channel->rand_state, cookie->client, sizeof(cookie->client)); - memcpy(&cookie->client_ts, now, sizeof(cookie->client_ts)); - memcpy(&cookie->client_ip, &conn->self_ip, sizeof(cookie->client_ip)); -} - -static void ares_cookie_clear_server(ares_cookie_t *cookie) -{ - memset(cookie->server, 0, sizeof(cookie->server)); - cookie->server_len = 0; -} - -static ares_bool_t ares_addr_equal(const struct ares_addr *addr1, - const struct ares_addr *addr2) -{ - if (addr1->family != addr2->family) { - return ARES_FALSE; - } - - switch (addr1->family) { - case AF_INET: - if (memcmp(&addr1->addr.addr4, &addr2->addr.addr4, - sizeof(addr1->addr.addr4)) == 0) { - return ARES_TRUE; - } - break; - case AF_INET6: - /* This structure is weird, and due to padding SonarCloud complains if - * you don't punch all the way down. At some point we should rework - * this structure */ - if (memcmp(&addr1->addr.addr6._S6_un._S6_u8, - &addr2->addr.addr6._S6_un._S6_u8, - sizeof(addr1->addr.addr6._S6_un._S6_u8)) == 0) { - return ARES_TRUE; - } - break; - default: - break; /* LCOV_EXCL_LINE */ - } - - return ARES_FALSE; -} - -ares_status_t ares_cookie_apply(ares_dns_record_t *dnsrec, ares_conn_t *conn, - const ares_timeval_t *now) -{ - ares_server_t *server = conn->server; - ares_cookie_t *cookie = &server->cookie; - ares_dns_rr_t *rr = ares_dns_get_opt_rr(dnsrec); - unsigned char c[40]; - size_t c_len; - - /* If there is no OPT record, then EDNS isn't supported, and therefore - * cookies can't be supported */ - if (rr == NULL) { - return ARES_SUCCESS; - } - - /* No cookies on TCP, make sure we remove one if one is present */ - if (conn->flags & ARES_CONN_FLAG_TCP) { - ares_dns_rr_del_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE); - return ARES_SUCCESS; - } - - /* Look for regression */ - if (cookie->state == ARES_COOKIE_SUPPORTED && - timeval_is_set(&cookie->unsupported_ts) && - timeval_expired(&cookie->unsupported_ts, now, - COOKIE_REGRESSION_TIMEOUT_MS)) { - ares_cookie_clear(cookie); - } - - /* Handle unsupported state */ - if (cookie->state == ARES_COOKIE_UNSUPPORTED) { - /* If timer hasn't expired, just delete any possible cookie and return */ - if (!timeval_expired(&cookie->unsupported_ts, now, - COOKIE_REGRESSION_TIMEOUT_MS)) { - ares_dns_rr_del_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE); - return ARES_SUCCESS; - } - - /* We want to try to "learn" again */ - ares_cookie_clear(cookie); - } - - /* Generate a new cookie */ - if (cookie->state == ARES_COOKIE_INITIAL) { - ares_cookie_generate(cookie, conn, now); - cookie->state = ARES_COOKIE_GENERATED; - } - - /* Regenerate the cookie and clear the server cookie if the client ip has - * changed */ - if ((cookie->state == ARES_COOKIE_GENERATED || - cookie->state == ARES_COOKIE_SUPPORTED) && - !ares_addr_equal(&conn->self_ip, &cookie->client_ip)) { - ares_cookie_clear_server(cookie); - ares_cookie_generate(cookie, conn, now); - } - - /* If the client cookie has reached its maximum time, refresh it */ - if (cookie->state == ARES_COOKIE_SUPPORTED && - timeval_expired(&cookie->client_ts, now, COOKIE_CLIENT_TIMEOUT_MS)) { - ares_cookie_clear_server(cookie); - ares_cookie_generate(cookie, conn, now); - } - - /* Generate the full cookie which is the client cookie concatenated with the - * server cookie (if there is one) and apply it. */ - memcpy(c, cookie->client, sizeof(cookie->client)); - if (cookie->server_len) { - memcpy(c + sizeof(cookie->client), cookie->server, cookie->server_len); - } - c_len = sizeof(cookie->client) + cookie->server_len; - - return ares_dns_rr_set_opt(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE, c, - c_len); -} - -ares_status_t ares_cookie_validate(ares_query_t *query, - const ares_dns_record_t *dnsresp, - ares_conn_t *conn, const ares_timeval_t *now, - ares_array_t **requeue) -{ - ares_server_t *server = conn->server; - ares_cookie_t *cookie = &server->cookie; - const ares_dns_record_t *dnsreq = query->query; - const unsigned char *resp_cookie; - size_t resp_cookie_len; - const unsigned char *req_cookie; - size_t req_cookie_len; - - resp_cookie = ares_dns_cookie_fetch(dnsresp, &resp_cookie_len); - - /* Invalid cookie length, drop */ - if (resp_cookie && (resp_cookie_len < 8 || resp_cookie_len > 40)) { - return ARES_EBADRESP; - } - - req_cookie = ares_dns_cookie_fetch(dnsreq, &req_cookie_len); - - /* Didn't request cookies, so we can stop evaluating */ - if (req_cookie == NULL) { - return ARES_SUCCESS; - } - - /* If 8-byte prefix for returned cookie doesn't match the requested cookie, - * drop for spoofing */ - if (resp_cookie && memcmp(req_cookie, resp_cookie, 8) != 0) { - return ARES_EBADRESP; - } - - if (resp_cookie && resp_cookie_len > 8) { - /* Make sure we record that we successfully received a cookie response */ - cookie->state = ARES_COOKIE_SUPPORTED; - memset(&cookie->unsupported_ts, 0, sizeof(cookie->unsupported_ts)); - - /* If client cookie hasn't been rotated, save the returned server cookie */ - if (memcmp(cookie->client, req_cookie, sizeof(cookie->client)) == 0) { - cookie->server_len = resp_cookie_len - 8; - memcpy(cookie->server, resp_cookie + 8, cookie->server_len); - } - } - - if (ares_dns_record_get_rcode(dnsresp) == ARES_RCODE_BADCOOKIE) { - /* Illegal to return BADCOOKIE but no cookie, drop */ - if (resp_cookie == NULL) { - return ARES_EBADRESP; - } - - /* If we have too many attempts to send a cookie, we need to requeue as - * tcp */ - query->cookie_try_count++; - if (query->cookie_try_count >= COOKIE_RESEND_MAX) { - query->using_tcp = ARES_TRUE; - } - - /* Resend the request, hopefully it will work the next time as we should - * have recorded a server cookie */ - ares_requeue_query(query, now, ARES_SUCCESS, - ARES_FALSE /* Don't increment try count */, NULL, - requeue); - - /* Parent needs to drop this response */ - return ARES_EBADRESP; - } - - /* We've got a response with a server cookie, and we've done all the - * evaluation we can, return success */ - if (resp_cookie_len > 8) { - return ARES_SUCCESS; - } - - if (cookie->state == ARES_COOKIE_SUPPORTED) { - /* If we're not currently tracking an error time yet, start */ - if (!timeval_is_set(&cookie->unsupported_ts)) { - memcpy(&cookie->unsupported_ts, now, sizeof(cookie->unsupported_ts)); - } - /* Drop it since we expected a cookie */ - return ARES_EBADRESP; - } - - if (cookie->state == ARES_COOKIE_GENERATED) { - ares_cookie_clear(cookie); - cookie->state = ARES_COOKIE_UNSUPPORTED; - memcpy(&cookie->unsupported_ts, now, sizeof(cookie->unsupported_ts)); - } - - /* Cookie state should be UNSUPPORTED if we're here */ - return ARES_SUCCESS; -} diff --git a/vendor/c-ares/src/lib/ares_data.c b/vendor/c-ares/src/lib/ares_data.c deleted file mode 100644 index d25c3faff..000000000 --- a/vendor/c-ares/src/lib/ares_data.c +++ /dev/null @@ -1,168 +0,0 @@ -/* MIT License - * - * Copyright (c) 2009 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include -#include -#include "ares_data.h" - -/* -** ares_free_data() - c-ares external API function. -** -** This function must be used by the application to free data memory that -** has been internally allocated by some c-ares function and for which a -** pointer has already been returned to the calling application. The list -** of c-ares functions returning pointers that must be free'ed using this -** function is: -** -** ares_get_servers() -** ares_parse_srv_reply() -** ares_parse_txt_reply() -*/ - -void ares_free_data(void *dataptr) -{ - while (dataptr != NULL) { - struct ares_data *ptr; - void *next_data = NULL; - -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable : 1684) - /* 1684: conversion from pointer to same-sized integral type */ -#endif - - ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif - - if (ptr->mark != ARES_DATATYPE_MARK) { - return; - } - - switch (ptr->type) { - case ARES_DATATYPE_MX_REPLY: - next_data = ptr->data.mx_reply.next; - ares_free(ptr->data.mx_reply.host); - break; - - case ARES_DATATYPE_SRV_REPLY: - next_data = ptr->data.srv_reply.next; - ares_free(ptr->data.srv_reply.host); - break; - - case ARES_DATATYPE_URI_REPLY: - next_data = ptr->data.uri_reply.next; - ares_free(ptr->data.uri_reply.uri); - break; - - case ARES_DATATYPE_TXT_REPLY: - case ARES_DATATYPE_TXT_EXT: - next_data = ptr->data.txt_reply.next; - ares_free(ptr->data.txt_reply.txt); - break; - - case ARES_DATATYPE_ADDR_NODE: - next_data = ptr->data.addr_node.next; - break; - - case ARES_DATATYPE_ADDR_PORT_NODE: - next_data = ptr->data.addr_port_node.next; - break; - - case ARES_DATATYPE_NAPTR_REPLY: - next_data = ptr->data.naptr_reply.next; - ares_free(ptr->data.naptr_reply.flags); - ares_free(ptr->data.naptr_reply.service); - ares_free(ptr->data.naptr_reply.regexp); - ares_free(ptr->data.naptr_reply.replacement); - break; - - case ARES_DATATYPE_SOA_REPLY: - ares_free(ptr->data.soa_reply.nsname); - ares_free(ptr->data.soa_reply.hostmaster); - break; - - case ARES_DATATYPE_CAA_REPLY: - next_data = ptr->data.caa_reply.next; - ares_free(ptr->data.caa_reply.property); - ares_free(ptr->data.caa_reply.value); - break; - - default: - return; - } - - ares_free(ptr); - dataptr = next_data; - } -} - -/* -** ares_malloc_data() - c-ares internal helper function. -** -** This function allocates memory for a c-ares private ares_data struct -** for the specified ares_datatype, initializes c-ares private fields -** and zero initializes those which later might be used from the public -** API. It returns an interior pointer which can be passed by c-ares -** functions to the calling application, and that must be free'ed using -** c-ares external API function ares_free_data(). -*/ - -void *ares_malloc_data(ares_datatype type) -{ - struct ares_data *ptr; - - ptr = ares_malloc_zero(sizeof(*ptr)); - if (!ptr) { - return NULL; - } - - switch (type) { - case ARES_DATATYPE_MX_REPLY: - case ARES_DATATYPE_SRV_REPLY: - case ARES_DATATYPE_URI_REPLY: - case ARES_DATATYPE_TXT_EXT: - case ARES_DATATYPE_TXT_REPLY: - case ARES_DATATYPE_CAA_REPLY: - case ARES_DATATYPE_ADDR_NODE: - case ARES_DATATYPE_ADDR_PORT_NODE: - case ARES_DATATYPE_NAPTR_REPLY: - case ARES_DATATYPE_SOA_REPLY: - break; - - default: - ares_free(ptr); - return NULL; - } - - ptr->mark = ARES_DATATYPE_MARK; - ptr->type = type; - - return &ptr->data; -} diff --git a/vendor/c-ares/src/lib/ares_data.h b/vendor/c-ares/src/lib/ares_data.h deleted file mode 100644 index b2c4d22b8..000000000 --- a/vendor/c-ares/src/lib/ares_data.h +++ /dev/null @@ -1,92 +0,0 @@ -/* MIT License - * - * Copyright (c) 2009 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_DATA_H -#define __ARES_DATA_H - -typedef enum { - ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */ - ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */ - ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */ - ARES_DATATYPE_TXT_EXT, /* struct ares_txt_ext - introduced in 1.11.0 */ - ARES_DATATYPE_ADDR_NODE, /* struct ares_addr_node - introduced in 1.7.1 */ - ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */ - ARES_DATATYPE_NAPTR_REPLY, /* struct ares_naptr_reply - introduced in 1.7.6 */ - ARES_DATATYPE_SOA_REPLY, /* struct ares_soa_reply - introduced in 1.9.0 */ - ARES_DATATYPE_URI_REPLY, /* struct ares_uri_reply */ -#if 0 - ARES_DATATYPE_ADDR6TTL, /* struct ares_addrttl */ - ARES_DATATYPE_ADDRTTL, /* struct ares_addr6ttl */ - ARES_DATATYPE_HOSTENT, /* struct hostent */ - ARES_DATATYPE_OPTIONS, /* struct ares_options */ -#endif - ARES_DATATYPE_ADDR_PORT_NODE, /* struct ares_addr_port_node - introduced - in 1.11.0 */ - ARES_DATATYPE_CAA_REPLY, /* struct ares_caa_reply - introduced in 1.17 */ - ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */ -} ares_datatype; - -#define ARES_DATATYPE_MARK 0xbead - -/* - * ares_data struct definition is internal to c-ares and shall not - * be exposed by the public API in order to allow future changes - * and extensions to it without breaking ABI. This will be used - * internally by c-ares as the container of multiple types of data - * dynamically allocated for which a reference will be returned - * to the calling application. - * - * c-ares API functions returning a pointer to c-ares internally - * allocated data will actually be returning an interior pointer - * into this ares_data struct. - * - * All this is 'invisible' to the calling application, the only - * requirement is that this kind of data must be free'ed by the - * calling application using ares_free_data() with the pointer - * it has received from a previous c-ares function call. - */ - -struct ares_data { - ares_datatype type; /* Actual data type identifier. */ - unsigned int mark; /* Private ares_data signature. */ - - union { - struct ares_txt_reply txt_reply; - struct ares_txt_ext txt_ext; - struct ares_srv_reply srv_reply; - struct ares_addr_node addr_node; - struct ares_addr_port_node addr_port_node; - struct ares_mx_reply mx_reply; - struct ares_naptr_reply naptr_reply; - struct ares_soa_reply soa_reply; - struct ares_caa_reply caa_reply; - struct ares_uri_reply uri_reply; - } data; -}; - -void *ares_malloc_data(ares_datatype type); - - -#endif /* __ARES_DATA_H */ diff --git a/vendor/c-ares/src/lib/ares_destroy.c b/vendor/c-ares/src/lib/ares_destroy.c deleted file mode 100644 index 1e5706e0e..000000000 --- a/vendor/c-ares/src/lib/ares_destroy.c +++ /dev/null @@ -1,159 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2004 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "event/ares_event.h" -#include - -void ares_destroy(ares_channel_t *channel) -{ - size_t i; - ares_llist_node_t *node = NULL; - - if (channel == NULL) { - return; - } - - /* Mark as being shutdown */ - ares_channel_lock(channel); - channel->sys_up = ARES_FALSE; - ares_channel_unlock(channel); - - /* Disable configuration change monitoring. We can't hold a lock because - * some cleanup routines, such as on Windows, are synchronous operations. - * What we've observed is a system config change event was triggered right - * at shutdown time and it tries to take the channel lock and the destruction - * waits for that event to complete before it continues so we get a channel - * lock deadlock at shutdown if we hold a lock during this process. */ - if (channel->optmask & ARES_OPT_EVENT_THREAD) { - ares_event_thread_t *e = channel->sock_state_cb_data; - if (e && e->configchg) { - ares_event_configchg_destroy(e->configchg); - e->configchg = NULL; - } - } - - /* Wait for reinit thread to exit if there was one pending, can't be - * holding a lock as the thread may take locks. */ - if (channel->reinit_thread != NULL) { - void *rv; - ares_thread_join(channel->reinit_thread, &rv); - channel->reinit_thread = NULL; - } - - /* Lock because callbacks will be triggered, and any system-generated - * callbacks need to hold a channel lock. */ - ares_channel_lock(channel); - - /* Destroy all queries */ - node = ares_llist_node_first(channel->all_queries); - while (node != NULL) { - ares_llist_node_t *next = ares_llist_node_next(node); - ares_query_t *query = ares_llist_node_claim(node); - - query->node_all_queries = NULL; - query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL); - ares_free_query(query); - - node = next; - } - - ares_queue_notify_empty(channel); - -#ifndef NDEBUG - /* Freeing the query should remove it from all the lists in which it sits, - * so all query lists should be empty now. - */ - assert(ares_llist_len(channel->all_queries) == 0); - assert(ares_htable_szvp_num_keys(channel->queries_by_qid) == 0); - assert(ares_slist_len(channel->queries_by_timeout) == 0); -#endif - - ares_destroy_servers_state(channel); - -#ifndef NDEBUG - assert(ares_htable_asvp_num_keys(channel->connnode_by_socket) == 0); -#endif - - /* No more callbacks will be triggered after this point, unlock */ - ares_channel_unlock(channel); - - /* Shut down the event thread */ - if (channel->optmask & ARES_OPT_EVENT_THREAD) { - ares_event_thread_destroy(channel); - } - - if (channel->domains) { - for (i = 0; i < channel->ndomains; i++) { - ares_free(channel->domains[i]); - } - ares_free(channel->domains); - } - - ares_llist_destroy(channel->all_queries); - ares_slist_destroy(channel->queries_by_timeout); - ares_htable_szvp_destroy(channel->queries_by_qid); - ares_htable_asvp_destroy(channel->connnode_by_socket); - - ares_free(channel->sortlist); - ares_free(channel->lookups); - ares_free(channel->resolvconf_path); - ares_free(channel->hosts_path); - ares_destroy_rand_state(channel->rand_state); - - ares_hosts_file_destroy(channel->hf); - - ares_qcache_destroy(channel->qcache); - - ares_channel_threading_destroy(channel); - - ares_free(channel); -} - -void ares_destroy_server(ares_server_t *server) -{ - if (server == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_close_sockets(server); - ares_llist_destroy(server->connections); - ares_free(server); -} - -void ares_destroy_servers_state(ares_channel_t *channel) -{ - ares_slist_node_t *node; - - while ((node = ares_slist_node_first(channel->servers)) != NULL) { - ares_server_t *server = ares_slist_node_claim(node); - ares_destroy_server(server); - } - - ares_slist_destroy(channel->servers); - channel->servers = NULL; -} diff --git a/vendor/c-ares/src/lib/ares_free_hostent.c b/vendor/c-ares/src/lib/ares_free_hostent.c deleted file mode 100644 index dfcbdf491..000000000 --- a/vendor/c-ares/src/lib/ares_free_hostent.c +++ /dev/null @@ -1,54 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -#ifdef HAVE_NETDB_H -# include -#endif - -void ares_free_hostent(struct hostent *host) -{ - char **p; - - if (!host) { - return; - } - - ares_free(host->h_name); - for (p = host->h_aliases; p && *p; p++) { - ares_free(*p); - } - ares_free(host->h_aliases); - if (host->h_addr_list) { - size_t i; - for (i=0; host->h_addr_list[i] != NULL; i++) { - ares_free(host->h_addr_list[i]); - } - ares_free(host->h_addr_list); - } - ares_free(host); -} diff --git a/vendor/c-ares/src/lib/ares_free_string.c b/vendor/c-ares/src/lib/ares_free_string.c deleted file mode 100644 index 048ad5d2a..000000000 --- a/vendor/c-ares/src/lib/ares_free_string.c +++ /dev/null @@ -1,33 +0,0 @@ -/* MIT License - * - * Copyright (c) 2000 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -void ares_free_string(void *str) -{ - ares_free(str); -} diff --git a/vendor/c-ares/src/lib/ares_freeaddrinfo.c b/vendor/c-ares/src/lib/ares_freeaddrinfo.c deleted file mode 100644 index c996df910..000000000 --- a/vendor/c-ares/src/lib/ares_freeaddrinfo.c +++ /dev/null @@ -1,67 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2019 Andrew Selivanov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETDB_H -# include -#endif - -void ares_freeaddrinfo_cnames(struct ares_addrinfo_cname *head) -{ - struct ares_addrinfo_cname *current; - while (head) { - current = head; - head = head->next; - ares_free(current->alias); - ares_free(current->name); - ares_free(current); - } -} - -void ares_freeaddrinfo_nodes(struct ares_addrinfo_node *head) -{ - struct ares_addrinfo_node *current; - while (head) { - current = head; - head = head->ai_next; - ares_free(current->ai_addr); - ares_free(current); - } -} - -void ares_freeaddrinfo(struct ares_addrinfo *ai) -{ - if (ai == NULL) { - return; - } - ares_freeaddrinfo_cnames(ai->cnames); - ares_freeaddrinfo_nodes(ai->nodes); - - ares_free(ai->name); - ares_free(ai); -} diff --git a/vendor/c-ares/src/lib/ares_getaddrinfo.c b/vendor/c-ares/src/lib/ares_getaddrinfo.c deleted file mode 100644 index eabd17fcb..000000000 --- a/vendor/c-ares/src/lib/ares_getaddrinfo.c +++ /dev/null @@ -1,736 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998, 2011, 2013 Massachusetts Institute of Technology - * Copyright (c) 2017 Christian Ammer - * Copyright (c) 2019 Andrew Selivanov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_GETSERVBYNAME_R -# if !defined(GETSERVBYNAME_R_ARGS) || (GETSERVBYNAME_R_ARGS < 4) || \ - (GETSERVBYNAME_R_ARGS > 6) -# error "you MUST specify a valid number of arguments for getservbyname_r" -# endif -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_nameser.h" - -#ifdef HAVE_STRINGS_H -# include -#endif -#include - -#ifdef HAVE_LIMITS_H -# include -#endif - -#include "ares_dns.h" - -struct host_query { - ares_channel_t *channel; - char *name; - unsigned short port; /* in host order */ - ares_addrinfo_callback callback; - void *arg; - struct ares_addrinfo_hints hints; - int sent_family; /* this family is what was is being used */ - size_t timeouts; /* number of timeouts we saw for this request */ - char *lookups; /* Duplicate memory from channel because of ares_reinit() */ - const char *remaining_lookups; /* types of lookup we need to perform ("fb" by - default, file and dns respectively) */ - - /* Search order for names */ - char **names; - size_t names_cnt; - size_t next_name_idx; /* next name index being attempted */ - - struct ares_addrinfo *ai; /* store results between lookups */ - unsigned short qid_a; /* qid for A request */ - unsigned short qid_aaaa; /* qid for AAAA request */ - - size_t remaining; /* number of DNS answers waiting for */ - - /* Track nodata responses to possibly override final result */ - size_t nodata_cnt; -}; - -static const struct ares_addrinfo_hints default_hints = { - 0, /* ai_flags */ - AF_UNSPEC, /* ai_family */ - 0, /* ai_socktype */ - 0, /* ai_protocol */ -}; - -/* forward declarations */ -static ares_bool_t next_dns_lookup(struct host_query *hquery); - -struct ares_addrinfo_cname * - ares_append_addrinfo_cname(struct ares_addrinfo_cname **head) -{ - struct ares_addrinfo_cname *tail = ares_malloc_zero(sizeof(*tail)); - struct ares_addrinfo_cname *last = *head; - - if (tail == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (!last) { - *head = tail; - return tail; - } - - while (last->next) { - last = last->next; - } - - last->next = tail; - return tail; -} - -void ares_addrinfo_cat_cnames(struct ares_addrinfo_cname **head, - struct ares_addrinfo_cname *tail) -{ - struct ares_addrinfo_cname *last = *head; - if (!last) { - *head = tail; - return; - } - - while (last->next) { - last = last->next; - } - - last->next = tail; -} - -/* Allocate new addrinfo and append to the tail. */ -struct ares_addrinfo_node * - ares_append_addrinfo_node(struct ares_addrinfo_node **head) -{ - struct ares_addrinfo_node *tail = ares_malloc_zero(sizeof(*tail)); - struct ares_addrinfo_node *last = *head; - - if (tail == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (!last) { - *head = tail; - return tail; - } - - while (last->ai_next) { - last = last->ai_next; - } - - last->ai_next = tail; - return tail; -} - -void ares_addrinfo_cat_nodes(struct ares_addrinfo_node **head, - struct ares_addrinfo_node *tail) -{ - struct ares_addrinfo_node *last = *head; - if (!last) { - *head = tail; - return; - } - - while (last->ai_next) { - last = last->ai_next; - } - - last->ai_next = tail; -} - -/* Resolve service name into port number given in host byte order. - * If not resolved, return 0. - */ -static unsigned short lookup_service(const char *service, int flags) -{ - const char *proto; - struct servent *sep; -#ifdef HAVE_GETSERVBYNAME_R - struct servent se; - char tmpbuf[4096]; -#endif - - if (service) { - if (flags & ARES_NI_UDP) { - proto = "udp"; - } else if (flags & ARES_NI_SCTP) { - proto = "sctp"; - } else if (flags & ARES_NI_DCCP) { - proto = "dccp"; - } else { - proto = "tcp"; - } -#ifdef HAVE_GETSERVBYNAME_R - memset(&se, 0, sizeof(se)); - sep = &se; - memset(tmpbuf, 0, sizeof(tmpbuf)); -# if GETSERVBYNAME_R_ARGS == 6 - if (getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf), - &sep) != 0) { - sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */ - } -# elif GETSERVBYNAME_R_ARGS == 5 - sep = getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf)); -# elif GETSERVBYNAME_R_ARGS == 4 - if (getservbyname_r(service, proto, &se, (void *)tmpbuf) != 0) { - sep = NULL; - } -# else - /* Lets just hope the OS uses TLS! */ - sep = getservbyname(service, proto); -# endif -#else - /* Lets just hope the OS uses TLS! */ -# if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) - sep = getservbyname(service, (char *)proto); -# else - sep = getservbyname(service, proto); -# endif -#endif - return (sep ? ntohs((unsigned short)sep->s_port) : 0); - } - return 0; -} - -/* If the name looks like an IP address or an error occurred, - * fake up a host entry, end the query immediately, and return true. - * Otherwise return false. - */ -static ares_bool_t fake_addrinfo(const char *name, unsigned short port, - const struct ares_addrinfo_hints *hints, - struct ares_addrinfo *ai, - ares_addrinfo_callback callback, void *arg) -{ - struct ares_addrinfo_cname *cname; - ares_status_t status = ARES_SUCCESS; - ares_bool_t result = ARES_FALSE; - int family = hints->ai_family; - if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC) { - /* It only looks like an IP address if it's all numbers and dots. */ - size_t numdots = 0; - ares_bool_t valid = ARES_TRUE; - const char *p; - for (p = name; *p; p++) { - if (!ares_isdigit(*p) && *p != '.') { - valid = ARES_FALSE; - break; - } else if (*p == '.') { - numdots++; - } - } - - /* if we don't have 3 dots, it is illegal - * (although inet_pton doesn't think so). - */ - if (numdots != 3 || !valid) { - result = ARES_FALSE; - } else { - struct in_addr addr4; - result = - ares_inet_pton(AF_INET, name, &addr4) < 1 ? ARES_FALSE : ARES_TRUE; - if (result) { - status = ares_append_ai_node(AF_INET, port, 0, &addr4, &ai->nodes); - if (status != ARES_SUCCESS) { - callback(arg, (int)status, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_TRUE; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - } - - if (!result && (family == AF_INET6 || family == AF_UNSPEC)) { - struct ares_in6_addr addr6; - result = - ares_inet_pton(AF_INET6, name, &addr6) < 1 ? ARES_FALSE : ARES_TRUE; - if (result) { - status = ares_append_ai_node(AF_INET6, port, 0, &addr6, &ai->nodes); - if (status != ARES_SUCCESS) { - callback(arg, (int)status, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_TRUE; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - if (!result) { - return ARES_FALSE; - } - - if (hints->ai_flags & ARES_AI_CANONNAME) { - cname = ares_append_addrinfo_cname(&ai->cnames); - if (!cname) { - /* LCOV_EXCL_START: OutOfMemory */ - ares_freeaddrinfo(ai); - callback(arg, ARES_ENOMEM, 0, NULL); - return ARES_TRUE; - /* LCOV_EXCL_STOP */ - } - - /* Duplicate the name, to avoid a constness violation. */ - cname->name = ares_strdup(name); - if (!cname->name) { - ares_freeaddrinfo(ai); - callback(arg, ARES_ENOMEM, 0, NULL); - return ARES_TRUE; - } - } - - ai->nodes->ai_socktype = hints->ai_socktype; - ai->nodes->ai_protocol = hints->ai_protocol; - - callback(arg, ARES_SUCCESS, 0, ai); - return ARES_TRUE; -} - -static void hquery_free(struct host_query *hquery, ares_bool_t cleanup_ai) -{ - if (cleanup_ai) { - ares_freeaddrinfo(hquery->ai); - } - ares_strsplit_free(hquery->names, hquery->names_cnt); - ares_free(hquery->name); - ares_free(hquery->lookups); - ares_free(hquery); -} - -static void end_hquery(struct host_query *hquery, ares_status_t status) -{ - struct ares_addrinfo_node sentinel; - struct ares_addrinfo_node *next; - - if (status == ARES_SUCCESS) { - if (!(hquery->hints.ai_flags & ARES_AI_NOSORT) && hquery->ai->nodes) { - sentinel.ai_next = hquery->ai->nodes; - ares_sortaddrinfo(hquery->channel, &sentinel); - hquery->ai->nodes = sentinel.ai_next; - } - next = hquery->ai->nodes; - - while (next) { - next->ai_socktype = hquery->hints.ai_socktype; - next->ai_protocol = hquery->hints.ai_protocol; - next = next->ai_next; - } - } else { - /* Clean up what we have collected by so far. */ - ares_freeaddrinfo(hquery->ai); - hquery->ai = NULL; - } - - hquery->callback(hquery->arg, (int)status, (int)hquery->timeouts, hquery->ai); - hquery_free(hquery, ARES_FALSE); -} - -ares_bool_t ares_is_localhost(const char *name) -{ - /* RFC6761 6.3 says : The domain "localhost." and any names falling within - * ".localhost." */ - size_t len; - - if (name == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_strcaseeq(name, "localhost")) { - return ARES_TRUE; - } - - len = ares_strlen(name); - if (len < 10 /* strlen(".localhost") */) { - return ARES_FALSE; - } - - if (ares_strcaseeq(name + (len - 10 /* strlen(".localhost") */), - ".localhost")) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -static ares_status_t file_lookup(struct host_query *hquery) -{ - const ares_hosts_entry_t *entry; - ares_status_t status; - - /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */ - if (ares_is_onion_domain(hquery->name)) { - return ARES_ENOTFOUND; - } - - status = ares_hosts_search_host( - hquery->channel, - (hquery->hints.ai_flags & ARES_AI_ENVHOSTS) ? ARES_TRUE : ARES_FALSE, - hquery->name, &entry); - - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_hosts_entry_to_addrinfo( - entry, hquery->name, hquery->hints.ai_family, hquery->port, - (hquery->hints.ai_flags & ARES_AI_CANONNAME) ? ARES_TRUE : ARES_FALSE, - hquery->ai); - - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - -done: - /* RFC6761 section 6.3 #3 states that "Name resolution APIs and libraries - * SHOULD recognize localhost names as special and SHOULD always return the - * IP loopback address for address queries". - * We will also ignore ALL errors when trying to resolve localhost, such - * as permissions errors reading /etc/hosts or a malformed /etc/hosts. - * - * Also, just because the query itself returned success from /etc/hosts - * lookup doesn't mean it returned everything it needed to for all requested - * address families. As long as we're not on a critical out of memory - * condition pass it through to fill in any other address classes. */ - if (status != ARES_ENOMEM && ares_is_localhost(hquery->name)) { - return ares_addrinfo_localhost(hquery->name, hquery->port, &hquery->hints, - hquery->ai); - } - - return status; -} - -static void next_lookup(struct host_query *hquery, ares_status_t status) -{ - switch (*hquery->remaining_lookups) { - case 'b': - /* RFC6761 section 6.3 #3 says "Name resolution APIs SHOULD NOT send - * queries for localhost names to their configured caching DNS - * server(s)." - * Otherwise, DNS lookup. */ - if (!ares_is_localhost(hquery->name) && next_dns_lookup(hquery)) { - break; - } - - hquery->remaining_lookups++; - next_lookup(hquery, status); - break; - - case 'f': - /* Host file lookup */ - if (file_lookup(hquery) == ARES_SUCCESS) { - end_hquery(hquery, ARES_SUCCESS); - break; - } - hquery->remaining_lookups++; - next_lookup(hquery, status); - break; - default: - /* No lookup left */ - end_hquery(hquery, status); - break; - } -} - -static void terminate_retries(const struct host_query *hquery, - unsigned short qid) -{ - unsigned short term_qid = - (qid == hquery->qid_a) ? hquery->qid_aaaa : hquery->qid_a; - const ares_channel_t *channel = hquery->channel; - ares_query_t *query = NULL; - - /* No other outstanding queries, nothing to do */ - if (!hquery->remaining) { - return; - } - - query = ares_htable_szvp_get_direct(channel->queries_by_qid, term_qid); - if (query == NULL) { - return; - } - - query->no_retries = ARES_TRUE; -} - -static ares_bool_t ai_has_ipv4(struct ares_addrinfo *ai) -{ - struct ares_addrinfo_node *node; - - for (node = ai->nodes; node != NULL; node = node->ai_next) { - if (node->ai_family == AF_INET) { - return ARES_TRUE; - } - } - return ARES_FALSE; -} - -static void host_callback(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - struct host_query *hquery = (struct host_query *)arg; - ares_status_t addinfostatus = ARES_SUCCESS; - hquery->timeouts += timeouts; - hquery->remaining--; - - if (status == ARES_SUCCESS) { - if (dnsrec == NULL) { - addinfostatus = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - } else { - addinfostatus = - ares_parse_into_addrinfo(dnsrec, ARES_TRUE, hquery->port, hquery->ai); - } - - /* We sent out ipv4 and ipv6 requests simultaneously. If we got a - * successful ipv4 response, we want to go ahead and tell the ipv6 request - * that if it fails or times out to not try again since we have the data - * we need. - * - * Our initial implementation of this would terminate retries if we got any - * successful response (ipv4 _or_ ipv6). But we did get some user-reported - * issues with this that had bad system configs and odd behavior: - * https://github.com/alpinelinux/docker-alpine/issues/366 - * - * Essentially the ipv6 query succeeded but the ipv4 query failed or timed - * out, and so we only returned the ipv6 address, but the host couldn't - * use ipv6. If we continued to allow ipv4 retries it would have found a - * server that worked and returned both address classes (this is clearly - * unexpected behavior). - * - * At some point down the road if ipv6 actually becomes required and - * reliable we can drop this ipv4 check. - */ - if (addinfostatus == ARES_SUCCESS && ai_has_ipv4(hquery->ai)) { - terminate_retries(hquery, ares_dns_record_get_id(dnsrec)); - } - } - - if (!hquery->remaining) { - if (status == ARES_EDESTRUCTION || status == ARES_ECANCELLED) { - /* must make sure we don't do next_lookup() on destroy or cancel, - * and return the appropriate status. We won't return a partial - * result in this case. */ - end_hquery(hquery, status); - } else if (addinfostatus != ARES_SUCCESS && addinfostatus != ARES_ENODATA) { - /* error in parsing result e.g. no memory */ - if (addinfostatus == ARES_EBADRESP && hquery->ai->nodes) { - /* We got a bad response from server, but at least one query - * ended with ARES_SUCCESS */ - end_hquery(hquery, ARES_SUCCESS); - } else { - end_hquery(hquery, addinfostatus); - } - } else if (hquery->ai->nodes) { - /* at least one query ended with ARES_SUCCESS */ - end_hquery(hquery, ARES_SUCCESS); - } else if (status == ARES_ENOTFOUND || status == ARES_ENODATA || - addinfostatus == ARES_ENODATA) { - if (status == ARES_ENODATA || addinfostatus == ARES_ENODATA) { - hquery->nodata_cnt++; - } - next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status); - } else if ((status == ARES_ESERVFAIL || status == ARES_EREFUSED) && - ares_name_label_cnt(hquery->names[hquery->next_name_idx - 1]) == - 1) { - /* Issue #852, systemd-resolved may return SERVFAIL or REFUSED on a - * single label domain name. */ - next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status); - } else { - end_hquery(hquery, status); - } - } - - /* at this point we keep on waiting for the next query to finish */ -} - -static void ares_getaddrinfo_int(ares_channel_t *channel, const char *name, - const char *service, - const struct ares_addrinfo_hints *hints, - ares_addrinfo_callback callback, void *arg) -{ - struct host_query *hquery; - unsigned short port = 0; - int family; - struct ares_addrinfo *ai; - ares_status_t status; - - if (!hints) { - hints = &default_hints; - } - - family = hints->ai_family; - - /* Right now we only know how to look up Internet addresses - and unspec means try both basically. */ - if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC) { - callback(arg, ARES_ENOTIMP, 0, NULL); - return; - } - - if (ares_is_onion_domain(name)) { - callback(arg, ARES_ENOTFOUND, 0, NULL); - return; - } - - if (service) { - if (hints->ai_flags & ARES_AI_NUMERICSERV) { - unsigned long val; - errno = 0; - val = strtoul(service, NULL, 0); - if ((val == 0 && errno != 0) || val > 65535) { - callback(arg, ARES_ESERVICE, 0, NULL); - return; - } - port = (unsigned short)val; - } else { - port = lookup_service(service, 0); - if (!port) { - unsigned long val; - errno = 0; - val = strtoul(service, NULL, 0); - if ((val == 0 && errno != 0) || val > 65535) { - callback(arg, ARES_ESERVICE, 0, NULL); - return; - } - port = (unsigned short)val; - } - } - } - - ai = ares_malloc_zero(sizeof(*ai)); - if (!ai) { - callback(arg, ARES_ENOMEM, 0, NULL); - return; - } - - if (fake_addrinfo(name, port, hints, ai, callback, arg)) { - return; - } - - /* Allocate and fill in the host query structure. */ - hquery = ares_malloc_zero(sizeof(*hquery)); - if (!hquery) { - ares_freeaddrinfo(ai); - callback(arg, ARES_ENOMEM, 0, NULL); - return; - } - - hquery->port = port; - hquery->channel = channel; - hquery->hints = *hints; - hquery->sent_family = -1; /* nothing is sent yet */ - hquery->callback = callback; - hquery->arg = arg; - hquery->ai = ai; - hquery->name = ares_strdup(name); - if (hquery->name == NULL) { - hquery_free(hquery, ARES_TRUE); - callback(arg, ARES_ENOMEM, 0, NULL); - return; - } - - status = - ares_search_name_list(channel, name, &hquery->names, &hquery->names_cnt); - if (status != ARES_SUCCESS) { - hquery_free(hquery, ARES_TRUE); - callback(arg, (int)status, 0, NULL); - return; - } - hquery->next_name_idx = 0; - - - hquery->lookups = ares_strdup(channel->lookups); - if (hquery->lookups == NULL) { - hquery_free(hquery, ARES_TRUE); - callback(arg, ARES_ENOMEM, 0, NULL); - return; - } - hquery->remaining_lookups = hquery->lookups; - - /* Start performing lookups according to channel->lookups. */ - next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */); -} - -void ares_getaddrinfo(ares_channel_t *channel, const char *name, - const char *service, - const struct ares_addrinfo_hints *hints, - ares_addrinfo_callback callback, void *arg) -{ - if (channel == NULL) { - return; - } - ares_channel_lock(channel); - ares_getaddrinfo_int(channel, name, service, hints, callback, arg); - ares_channel_unlock(channel); -} - -static ares_bool_t next_dns_lookup(struct host_query *hquery) -{ - const char *name = NULL; - - if (hquery->next_name_idx >= hquery->names_cnt) { - return ARES_FALSE; - } - - name = hquery->names[hquery->next_name_idx++]; - - /* NOTE: hquery may be invalidated during the call to ares_query_qid(), - * so should not be referenced after this point */ - switch (hquery->hints.ai_family) { - case AF_INET: - hquery->remaining += 1; - ares_query_nolock(hquery->channel, name, ARES_CLASS_IN, ARES_REC_TYPE_A, - host_callback, hquery, &hquery->qid_a); - break; - case AF_INET6: - hquery->remaining += 1; - ares_query_nolock(hquery->channel, name, ARES_CLASS_IN, - ARES_REC_TYPE_AAAA, host_callback, hquery, - &hquery->qid_aaaa); - break; - case AF_UNSPEC: - hquery->remaining += 2; - ares_query_nolock(hquery->channel, name, ARES_CLASS_IN, ARES_REC_TYPE_A, - host_callback, hquery, &hquery->qid_a); - ares_query_nolock(hquery->channel, name, ARES_CLASS_IN, - ARES_REC_TYPE_AAAA, host_callback, hquery, - &hquery->qid_aaaa); - break; - default: - break; - } - - return ARES_TRUE; -} diff --git a/vendor/c-ares/src/lib/ares_getenv.c b/vendor/c-ares/src/lib/ares_getenv.c deleted file mode 100644 index 4f471673b..000000000 --- a/vendor/c-ares/src/lib/ares_getenv.c +++ /dev/null @@ -1,38 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_getenv.h" - -#ifndef HAVE_GETENV - -char *ares_getenv(const char *name) -{ - return NULL; -} - -#endif diff --git a/vendor/c-ares/src/lib/ares_getenv.h b/vendor/c-ares/src/lib/ares_getenv.h deleted file mode 100644 index 490097fc8..000000000 --- a/vendor/c-ares/src/lib/ares_getenv.h +++ /dev/null @@ -1,34 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef HEADER_CARES_GETENV_H -#define HEADER_CARES_GETENV_H - -#ifndef HAVE_GETENV -extern char *ares_getenv(const char *name); -#endif - -#endif /* HEADER_CARES_GETENV_H */ diff --git a/vendor/c-ares/src/lib/ares_gethostbyaddr.c b/vendor/c-ares/src/lib/ares_gethostbyaddr.c deleted file mode 100644 index 69c509ab1..000000000 --- a/vendor/c-ares/src/lib/ares_gethostbyaddr.c +++ /dev/null @@ -1,229 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_nameser.h" -#include "ares_inet_net_pton.h" - -struct addr_query { - /* Arguments passed to ares_gethostbyaddr() */ - ares_channel_t *channel; - struct ares_addr addr; - ares_host_callback callback; - void *arg; - char *lookups; /* duplicate memory from channel for ares_reinit() */ - const char *remaining_lookups; - size_t timeouts; -}; - -static void next_lookup(struct addr_query *aquery); -static void addr_callback(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec); -static void end_aquery(struct addr_query *aquery, ares_status_t status, - struct hostent *host); -static ares_status_t file_lookup(ares_channel_t *channel, - const struct ares_addr *addr, - struct hostent **host); - -void ares_gethostbyaddr_nolock(ares_channel_t *channel, const void *addr, - int addrlen, int family, - ares_host_callback callback, void *arg) -{ - struct addr_query *aquery; - - if (family != AF_INET && family != AF_INET6) { - callback(arg, ARES_ENOTIMP, 0, NULL); - return; - } - - if ((family == AF_INET && addrlen != sizeof(aquery->addr.addr.addr4)) || - (family == AF_INET6 && addrlen != sizeof(aquery->addr.addr.addr6))) { - callback(arg, ARES_ENOTIMP, 0, NULL); - return; - } - - aquery = ares_malloc(sizeof(struct addr_query)); - if (!aquery) { - callback(arg, ARES_ENOMEM, 0, NULL); - return; - } - aquery->lookups = ares_strdup(channel->lookups); - if (aquery->lookups == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - ares_free(aquery); - callback(arg, ARES_ENOMEM, 0, NULL); - return; - /* LCOV_EXCL_STOP */ - } - aquery->channel = channel; - if (family == AF_INET) { - memcpy(&aquery->addr.addr.addr4, addr, sizeof(aquery->addr.addr.addr4)); - } else { - memcpy(&aquery->addr.addr.addr6, addr, sizeof(aquery->addr.addr.addr6)); - } - aquery->addr.family = family; - aquery->callback = callback; - aquery->arg = arg; - aquery->remaining_lookups = aquery->lookups; - aquery->timeouts = 0; - - next_lookup(aquery); -} - -void ares_gethostbyaddr(ares_channel_t *channel, const void *addr, int addrlen, - int family, ares_host_callback callback, void *arg) -{ - if (channel == NULL) { - return; - } - ares_channel_lock(channel); - ares_gethostbyaddr_nolock(channel, addr, addrlen, family, callback, arg); - ares_channel_unlock(channel); -} - -static void next_lookup(struct addr_query *aquery) -{ - const char *p; - ares_status_t status; - struct hostent *host = NULL; - char *name; - - for (p = aquery->remaining_lookups; *p; p++) { - switch (*p) { - case 'b': - name = ares_dns_addr_to_ptr(&aquery->addr); - if (name == NULL) { - end_aquery(aquery, ARES_ENOMEM, - NULL); /* LCOV_EXCL_LINE: OutOfMemory */ - return; /* LCOV_EXCL_LINE: OutOfMemory */ - } - aquery->remaining_lookups = p + 1; - ares_query_nolock(aquery->channel, name, ARES_CLASS_IN, - ARES_REC_TYPE_PTR, addr_callback, aquery, NULL); - ares_free(name); - return; - case 'f': - status = file_lookup(aquery->channel, &aquery->addr, &host); - - /* this status check below previously checked for !ARES_ENOTFOUND, - but we should not assume that this single error code is the one - that can occur, as that is in fact no longer the case */ - if (status == ARES_SUCCESS) { - end_aquery(aquery, status, host); - return; - } - break; - default: - break; - } - } - end_aquery(aquery, ARES_ENOTFOUND, NULL); -} - -static void addr_callback(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - struct addr_query *aquery = (struct addr_query *)arg; - struct hostent *host; - size_t addrlen; - - aquery->timeouts += timeouts; - if (status == ARES_SUCCESS) { - if (aquery->addr.family == AF_INET) { - addrlen = sizeof(aquery->addr.addr.addr4); - status = ares_parse_ptr_reply_dnsrec(dnsrec, &aquery->addr.addr.addr4, - (int)addrlen, AF_INET, &host); - } else { - addrlen = sizeof(aquery->addr.addr.addr6); - status = ares_parse_ptr_reply_dnsrec(dnsrec, &aquery->addr.addr.addr6, - (int)addrlen, AF_INET6, &host); - } - end_aquery(aquery, status, host); - } else if (status == ARES_EDESTRUCTION || status == ARES_ECANCELLED) { - end_aquery(aquery, status, NULL); - } else { - next_lookup(aquery); - } -} - -static void end_aquery(struct addr_query *aquery, ares_status_t status, - struct hostent *host) -{ - aquery->callback(aquery->arg, (int)status, (int)aquery->timeouts, host); - if (host) { - ares_free_hostent(host); - } - ares_free(aquery->lookups); - ares_free(aquery); -} - -static ares_status_t file_lookup(ares_channel_t *channel, - const struct ares_addr *addr, - struct hostent **host) -{ - char ipaddr[INET6_ADDRSTRLEN]; - const void *ptr = NULL; - const ares_hosts_entry_t *entry; - ares_status_t status; - - if (addr->family == AF_INET) { - ptr = &addr->addr.addr4; - } else if (addr->family == AF_INET6) { - ptr = &addr->addr.addr6; - } - - if (ptr == NULL) { - return ARES_ENOTFOUND; - } - - if (!ares_inet_ntop(addr->family, ptr, ipaddr, sizeof(ipaddr))) { - return ARES_ENOTFOUND; - } - - status = ares_hosts_search_ipaddr(channel, ARES_FALSE, ipaddr, &entry); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_hosts_entry_to_hostent(entry, addr->family, host); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; -} diff --git a/vendor/c-ares/src/lib/ares_gethostbyname.c b/vendor/c-ares/src/lib/ares_gethostbyname.c deleted file mode 100644 index d451b4685..000000000 --- a/vendor/c-ares/src/lib/ares_gethostbyname.c +++ /dev/null @@ -1,337 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998, 2011, 2013 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_nameser.h" - -#ifdef HAVE_STRINGS_H -# include -#endif - -#include "ares_inet_net_pton.h" - -static void sort_addresses(const struct hostent *host, - const struct apattern *sortlist, size_t nsort); -static void sort6_addresses(const struct hostent *host, - const struct apattern *sortlist, size_t nsort); -static size_t get_address_index(const struct in_addr *addr, - const struct apattern *sortlist, size_t nsort); -static size_t get6_address_index(const struct ares_in6_addr *addr, - const struct apattern *sortlist, size_t nsort); - -struct host_query { - ares_host_callback callback; - void *arg; - ares_channel_t *channel; -}; - -static void ares_gethostbyname_callback(void *arg, int status, int timeouts, - struct ares_addrinfo *result) -{ - struct hostent *hostent = NULL; - struct host_query *ghbn_arg = arg; - - if (status == ARES_SUCCESS) { - status = (int)ares_addrinfo2hostent(result, AF_UNSPEC, &hostent); - } - - /* addrinfo2hostent will only return ENODATA if there are no addresses _and_ - * no cname/aliases. However, gethostbyname will return ENODATA even if there - * is cname/alias data */ - if (status == ARES_SUCCESS && hostent && - (!hostent->h_addr_list || !hostent->h_addr_list[0])) { - status = ARES_ENODATA; - } - - if (status == ARES_SUCCESS && ghbn_arg->channel->nsort && hostent) { - if (hostent->h_addrtype == AF_INET6) { - sort6_addresses(hostent, ghbn_arg->channel->sortlist, - ghbn_arg->channel->nsort); - } - if (hostent->h_addrtype == AF_INET) { - sort_addresses(hostent, ghbn_arg->channel->sortlist, - ghbn_arg->channel->nsort); - } - } - - ghbn_arg->callback(ghbn_arg->arg, status, timeouts, hostent); - - ares_freeaddrinfo(result); - ares_free(ghbn_arg); - ares_free_hostent(hostent); -} - -void ares_gethostbyname(ares_channel_t *channel, const char *name, int family, - ares_host_callback callback, void *arg) -{ - struct ares_addrinfo_hints hints; - struct host_query *ghbn_arg; - - if (!callback) { - return; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = ARES_AI_CANONNAME; - hints.ai_family = family; - - ghbn_arg = ares_malloc(sizeof(*ghbn_arg)); - if (!ghbn_arg) { - callback(arg, ARES_ENOMEM, 0, NULL); - return; - } - - ghbn_arg->callback = callback; - ghbn_arg->arg = arg; - ghbn_arg->channel = channel; - - /* NOTE: ares_getaddrinfo() locks the channel, we don't use the channel - * outside so no need to lock */ - ares_getaddrinfo(channel, name, NULL, &hints, ares_gethostbyname_callback, - ghbn_arg); -} - -static void sort_addresses(const struct hostent *host, - const struct apattern *sortlist, size_t nsort) -{ - struct in_addr a1; - struct in_addr a2; - int i1; - int i2; - size_t ind1; - size_t ind2; - - /* This is a simple insertion sort, not optimized at all. i1 walks - * through the address list, with the loop invariant that everything - * to the left of i1 is sorted. In the loop body, the value at i1 is moved - * back through the list (via i2) until it is in sorted order. - */ - for (i1 = 0; host->h_addr_list[i1]; i1++) { - memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr)); - ind1 = get_address_index(&a1, sortlist, nsort); - for (i2 = i1 - 1; i2 >= 0; i2--) { - memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr)); - ind2 = get_address_index(&a2, sortlist, nsort); - if (ind2 <= ind1) { - break; - } - memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr)); - } - memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr)); - } -} - -/* Find the first entry in sortlist which matches addr. Return nsort - * if none of them match. - */ -static size_t get_address_index(const struct in_addr *addr, - const struct apattern *sortlist, size_t nsort) -{ - size_t i; - struct ares_addr aaddr; - - memset(&aaddr, 0, sizeof(aaddr)); - aaddr.family = AF_INET; - memcpy(&aaddr.addr.addr4, addr, 4); - - for (i = 0; i < nsort; i++) { - if (sortlist[i].addr.family != AF_INET) { - continue; - } - - if (ares_subnet_match(&aaddr, &sortlist[i].addr, sortlist[i].mask)) { - break; - } - } - - return i; -} - -static void sort6_addresses(const struct hostent *host, - const struct apattern *sortlist, size_t nsort) -{ - struct ares_in6_addr a1; - struct ares_in6_addr a2; - int i1; - int i2; - size_t ind1; - size_t ind2; - - /* This is a simple insertion sort, not optimized at all. i1 walks - * through the address list, with the loop invariant that everything - * to the left of i1 is sorted. In the loop body, the value at i1 is moved - * back through the list (via i2) until it is in sorted order. - */ - for (i1 = 0; host->h_addr_list[i1]; i1++) { - memcpy(&a1, host->h_addr_list[i1], sizeof(struct ares_in6_addr)); - ind1 = get6_address_index(&a1, sortlist, nsort); - for (i2 = i1 - 1; i2 >= 0; i2--) { - memcpy(&a2, host->h_addr_list[i2], sizeof(struct ares_in6_addr)); - ind2 = get6_address_index(&a2, sortlist, nsort); - if (ind2 <= ind1) { - break; - } - memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct ares_in6_addr)); - } - memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct ares_in6_addr)); - } -} - -/* Find the first entry in sortlist which matches addr. Return nsort - * if none of them match. - */ -static size_t get6_address_index(const struct ares_in6_addr *addr, - const struct apattern *sortlist, size_t nsort) -{ - size_t i; - struct ares_addr aaddr; - - memset(&aaddr, 0, sizeof(aaddr)); - aaddr.family = AF_INET6; - memcpy(&aaddr.addr.addr6, addr, 16); - - for (i = 0; i < nsort; i++) { - if (sortlist[i].addr.family != AF_INET6) { - continue; - } - - if (ares_subnet_match(&aaddr, &sortlist[i].addr, sortlist[i].mask)) { - break; - } - } - return i; -} - -static ares_status_t ares_hostent_localhost(const char *name, int family, - struct hostent **host_out) -{ - ares_status_t status; - struct ares_addrinfo *ai = NULL; - struct ares_addrinfo_hints hints; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - - ai = ares_malloc_zero(sizeof(*ai)); - if (ai == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_addrinfo_localhost(name, 0, &hints, ai); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_addrinfo2hostent(ai, family, host_out); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - -done: - ares_freeaddrinfo(ai); - return status; -} - -/* I really have no idea why this is exposed as a public function, but since - * it is, we can't kill this legacy function. */ -static ares_status_t ares_gethostbyname_file_int(ares_channel_t *channel, - const char *name, int family, - struct hostent **host) -{ - const ares_hosts_entry_t *entry; - ares_status_t status; - - /* We only take the channel to ensure that ares_init() been called. */ - if (channel == NULL || name == NULL || host == NULL) { - /* Anything will do, really. This seems fine, and is consistent with - other error cases. */ - if (host != NULL) { - *host = NULL; - } - return ARES_ENOTFOUND; - } - - *host = NULL; - - /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */ - if (ares_is_onion_domain(name)) { - return ARES_ENOTFOUND; - } - - status = ares_hosts_search_host(channel, ARES_FALSE, name, &entry); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_hosts_entry_to_hostent(entry, family, host); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - -done: - /* RFC6761 section 6.3 #3 states that "Name resolution APIs and libraries - * SHOULD recognize localhost names as special and SHOULD always return the - * IP loopback address for address queries". - * We will also ignore ALL errors when trying to resolve localhost, such - * as permissions errors reading /etc/hosts or a malformed /etc/hosts. - * - * Also, just because the query itself returned success from /etc/hosts - * lookup doesn't mean it returned everything it needed to for all requested - * address families. As long as we're not on a critical out of memory - * condition pass it through to fill in any other address classes. */ - if (status != ARES_ENOMEM && ares_is_localhost(name)) { - return ares_hostent_localhost(name, family, host); - } - - return status; -} - -int ares_gethostbyname_file(ares_channel_t *channel, const char *name, - int family, struct hostent **host) -{ - ares_status_t status; - if (channel == NULL) { - return ARES_ENOTFOUND; - } - - ares_channel_lock(channel); - status = ares_gethostbyname_file_int(channel, name, family, host); - ares_channel_unlock(channel); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/ares_getnameinfo.c b/vendor/c-ares/src/lib/ares_getnameinfo.c deleted file mode 100644 index 015935453..000000000 --- a/vendor/c-ares/src/lib/ares_getnameinfo.c +++ /dev/null @@ -1,437 +0,0 @@ -/* MIT License - * - * Copyright (c) 2005, 2013 Dominick Meglio - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -#ifdef HAVE_GETSERVBYPORT_R -# if !defined(GETSERVBYPORT_R_ARGS) || (GETSERVBYPORT_R_ARGS < 4) || \ - (GETSERVBYPORT_R_ARGS > 6) -# error "you MUST specify a valid number of arguments for getservbyport_r" -# endif -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_nameser.h" - -#ifdef HAVE_NET_IF_H -# include -#endif -#if defined(USE_WINSOCK) && defined(HAVE_IPHLPAPI_H) -# include -#endif - -#include "ares_ipv6.h" - -struct nameinfo_query { - ares_nameinfo_callback callback; - void *arg; - - union { - struct sockaddr_in addr4; - struct sockaddr_in6 addr6; - } addr; - - int family; - unsigned int flags; - size_t timeouts; -}; - -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID -# define IPBUFSIZ \ - (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") + IF_NAMESIZE) -#else -# define IPBUFSIZ (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")) -#endif - -static void nameinfo_callback(void *arg, int status, int timeouts, - struct hostent *host); -static char *lookup_service(unsigned short port, unsigned int flags, char *buf, - size_t buflen); -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID -static void append_scopeid(const struct sockaddr_in6 *addr6, unsigned int flags, - char *buf, size_t buflen); -#endif -static char *ares_striendstr(const char *s1, const char *s2); - -static void ares_getnameinfo_int(ares_channel_t *channel, - const struct sockaddr *sa, - ares_socklen_t salen, int flags_int, - ares_nameinfo_callback callback, void *arg) -{ - const struct sockaddr_in *addr = NULL; - const struct sockaddr_in6 *addr6 = NULL; - struct nameinfo_query *niquery; - unsigned short port = 0; - unsigned int flags = (unsigned int)flags_int; - - /* Validate socket address family and length */ - if (sa && sa->sa_family == AF_INET && - salen >= (ares_socklen_t)sizeof(struct sockaddr_in)) { - addr = CARES_INADDR_CAST(const struct sockaddr_in *, sa); - port = addr->sin_port; - } else if (sa && sa->sa_family == AF_INET6 && - salen >= (ares_socklen_t)sizeof(struct sockaddr_in6)) { - addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, sa); - port = addr6->sin6_port; - } else { - callback(arg, ARES_ENOTIMP, 0, NULL, NULL); - return; - } - - /* If neither, assume they want a host */ - if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST)) { - flags |= ARES_NI_LOOKUPHOST; - } - - /* All they want is a service, no need for DNS */ - if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST)) { - char buf[33]; - char *service; - - service = - lookup_service((unsigned short)(port & 0xffff), flags, buf, sizeof(buf)); - callback(arg, ARES_SUCCESS, 0, NULL, service); - return; - } - - /* They want a host lookup */ - if (flags & ARES_NI_LOOKUPHOST) { - /* A numeric host can be handled without DNS */ - if (flags & ARES_NI_NUMERICHOST) { - char ipbuf[IPBUFSIZ]; - char srvbuf[33]; - char *service = NULL; - ipbuf[0] = 0; - - /* Specifying not to lookup a host, but then saying a host - * is required has to be illegal. - */ - if (flags & ARES_NI_NAMEREQD) { - callback(arg, ARES_EBADFLAGS, 0, NULL, NULL); - return; - } - if (sa->sa_family == AF_INET6) { - ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ); - /* If the system supports scope IDs, use it */ -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID - append_scopeid(addr6, flags, ipbuf, sizeof(ipbuf)); -#endif - } else { - ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ); - } - /* They also want a service */ - if (flags & ARES_NI_LOOKUPSERVICE) { - service = lookup_service((unsigned short)(port & 0xffff), flags, srvbuf, - sizeof(srvbuf)); - } - callback(arg, ARES_SUCCESS, 0, ipbuf, service); - return; - } else { - /* This is where a DNS lookup becomes necessary */ - niquery = ares_malloc(sizeof(struct nameinfo_query)); - if (!niquery) { - callback(arg, ARES_ENOMEM, 0, NULL, NULL); - return; - } - niquery->callback = callback; - niquery->arg = arg; - niquery->flags = flags; - niquery->timeouts = 0; - if (sa->sa_family == AF_INET) { - niquery->family = AF_INET; - memcpy(&niquery->addr.addr4, addr, sizeof(niquery->addr.addr4)); - ares_gethostbyaddr_nolock(channel, &addr->sin_addr, - sizeof(struct in_addr), AF_INET, - nameinfo_callback, niquery); - } else { - niquery->family = AF_INET6; - memcpy(&niquery->addr.addr6, addr6, sizeof(niquery->addr.addr6)); - ares_gethostbyaddr_nolock(channel, &addr6->sin6_addr, - sizeof(struct ares_in6_addr), AF_INET6, - nameinfo_callback, niquery); - } - } - } -} - -void ares_getnameinfo(ares_channel_t *channel, const struct sockaddr *sa, - ares_socklen_t salen, int flags_int, - ares_nameinfo_callback callback, void *arg) -{ - if (channel == NULL) { - return; - } - - ares_channel_lock(channel); - ares_getnameinfo_int(channel, sa, salen, flags_int, callback, arg); - ares_channel_unlock(channel); -} - -static void nameinfo_callback(void *arg, int status, int timeouts, - struct hostent *host) -{ - struct nameinfo_query *niquery = (struct nameinfo_query *)arg; - char srvbuf[33]; - char *service = NULL; - - niquery->timeouts += (size_t)timeouts; - if (status == ARES_SUCCESS) { - /* They want a service too */ - if (niquery->flags & ARES_NI_LOOKUPSERVICE) { - if (niquery->family == AF_INET) { - service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, - srvbuf, sizeof(srvbuf)); - } else { - service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, - srvbuf, sizeof(srvbuf)); - } - } - /* NOFQDN means we have to strip off the domain name portion. We do - this by determining our own domain name, then searching the string - for this domain name and removing it. - */ -#ifdef HAVE_GETHOSTNAME - if (niquery->flags & ARES_NI_NOFQDN) { - char buf[255]; - const char *domain; - gethostname(buf, 255); - if ((domain = strchr(buf, '.')) != NULL) { - char *end = ares_striendstr(host->h_name, domain); - if (end) { - *end = 0; - } - } - } -#endif - niquery->callback(niquery->arg, ARES_SUCCESS, (int)niquery->timeouts, - host->h_name, service); - ares_free(niquery); - return; - } - /* We couldn't find the host, but it's OK, we can use the IP */ - else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD)) { - char ipbuf[IPBUFSIZ]; - if (niquery->family == AF_INET) { - ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf, IPBUFSIZ); - } else { - ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ); -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID - append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf, - sizeof(ipbuf)); -#endif - } - /* They want a service too */ - if (niquery->flags & ARES_NI_LOOKUPSERVICE) { - if (niquery->family == AF_INET) { - service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, - srvbuf, sizeof(srvbuf)); - } else { - service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, - srvbuf, sizeof(srvbuf)); - } - } - niquery->callback(niquery->arg, ARES_SUCCESS, (int)niquery->timeouts, ipbuf, - service); - ares_free(niquery); - return; - } - niquery->callback(niquery->arg, status, (int)niquery->timeouts, NULL, NULL); - ares_free(niquery); -} - -static char *lookup_service(unsigned short port, unsigned int flags, char *buf, - size_t buflen) -{ - const char *proto; - struct servent *sep; -#ifdef HAVE_GETSERVBYPORT_R - struct servent se; -#endif - char tmpbuf[4096]; - const char *name; - size_t name_len; - - if (port) { - if (flags & ARES_NI_NUMERICSERV) { - sep = NULL; - } else { - if (flags & ARES_NI_UDP) { - proto = "udp"; - } else if (flags & ARES_NI_SCTP) { - proto = "sctp"; - } else if (flags & ARES_NI_DCCP) { - proto = "dccp"; - } else { - proto = "tcp"; - } -#ifdef HAVE_GETSERVBYPORT_R - memset(&se, 0, sizeof(se)); - sep = &se; - memset(tmpbuf, 0, sizeof(tmpbuf)); -# if GETSERVBYPORT_R_ARGS == 6 - if (getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf), - &sep) != 0) { - sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */ - } -# elif GETSERVBYPORT_R_ARGS == 5 - sep = getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf)); -# elif GETSERVBYPORT_R_ARGS == 4 - if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0) { - sep = NULL; - } -# else - /* Lets just hope the OS uses TLS! */ - sep = getservbyport(port, proto); -# endif -#else - /* Lets just hope the OS uses TLS! */ -# if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) - sep = getservbyport(port, (char *)proto); -# else - sep = getservbyport(port, proto); -# endif -#endif - } - if (sep && sep->s_name) { - /* get service name */ - name = sep->s_name; - } else { - /* get port as a string */ - snprintf(tmpbuf, sizeof(tmpbuf), "%u", (unsigned int)ntohs(port)); - name = tmpbuf; - } - name_len = ares_strlen(name); - if (name_len < buflen) { - /* return it if buffer big enough */ - memcpy(buf, name, name_len + 1); - } else { - /* avoid reusing previous one */ - buf[0] = '\0'; /* LCOV_EXCL_LINE: no real service names are too big */ - } - return buf; - } - buf[0] = '\0'; - return NULL; -} - -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID -static void append_scopeid(const struct sockaddr_in6 *addr6, unsigned int flags, - char *buf, size_t buflen) -{ -# ifdef HAVE_IF_INDEXTONAME - int is_ll; - int is_mcll; -# endif - char tmpbuf[IF_NAMESIZE + 2]; - size_t bufl; - - tmpbuf[0] = '%'; - -# ifdef HAVE_IF_INDEXTONAME - is_ll = IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr); - is_mcll = IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr); - if ((flags & ARES_NI_NUMERICSCOPE) || (!is_ll && !is_mcll)) { - snprintf(&tmpbuf[1], sizeof(tmpbuf) - 1, "%lu", - (unsigned long)addr6->sin6_scope_id); - } else { - if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL) { - snprintf(&tmpbuf[1], sizeof(tmpbuf) - 1, "%lu", - (unsigned long)addr6->sin6_scope_id); - } - } -# else - snprintf(&tmpbuf[1], sizeof(tmpbuf) - 1, "%lu", - (unsigned long)addr6->sin6_scope_id); - (void)flags; -# endif - tmpbuf[IF_NAMESIZE + 1] = '\0'; - bufl = ares_strlen(buf); - - if (bufl + ares_strlen(tmpbuf) < buflen) { - /* only append the scopeid string if it fits in the target buffer */ - ares_strcpy(&buf[bufl], tmpbuf, buflen - bufl); - } -} -#endif - -/* Determines if s1 ends with the string in s2 (case-insensitive) */ -static char *ares_striendstr(const char *s1, const char *s2) -{ - const char *c1; - const char *c2; - const char *c1_begin; - int lo1; - int lo2; - size_t s1_len = ares_strlen(s1); - size_t s2_len = ares_strlen(s2); - - if (s1 == NULL || s2 == NULL) { - return NULL; - } - - /* If the substr is longer than the full str, it can't match */ - if (s2_len > s1_len) { - return NULL; - } - - /* Jump to the end of s1 minus the length of s2 */ - c1_begin = s1 + s1_len - s2_len; - c1 = c1_begin; - c2 = s2; - while (c2 < s2 + s2_len) { - lo1 = ares_tolower((unsigned char)*c1); - lo2 = ares_tolower((unsigned char)*c2); - if (lo1 != lo2) { - return NULL; - } else { - c1++; - c2++; - } - } - /* Cast off const */ - return (char *)((size_t)c1_begin); -} - -ares_bool_t ares_is_onion_domain(const char *name) -{ - if (ares_striendstr(name, ".onion")) { - return ARES_TRUE; - } - - if (ares_striendstr(name, ".onion.")) { - return ARES_TRUE; - } - - return ARES_FALSE; -} diff --git a/vendor/c-ares/src/lib/ares_hosts_file.c b/vendor/c-ares/src/lib/ares_hosts_file.c deleted file mode 100644 index d18863b8f..000000000 --- a/vendor/c-ares/src/lib/ares_hosts_file.c +++ /dev/null @@ -1,952 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#include - -/* HOSTS FILE PROCESSING OVERVIEW - * ============================== - * The hosts file on the system contains static entries to be processed locally - * rather than querying the nameserver. Each row is an IP address followed by - * a list of space delimited hostnames that match the ip address. This is used - * for both forward and reverse lookups. - * - * We are caching the entire parsed hosts file for performance reasons. Some - * files may be quite sizable and as per Issue #458 can approach 1/2MB in size, - * and the parse overhead on a rapid succession of queries can be quite large. - * The entries are stored in forwards and backwards hashtables so we can get - * O(1) performance on lookup. The file is cached until the file modification - * timestamp changes. - * - * The hosts file processing is quite unique. It has to merge all related hosts - * and ips into a single entry due to file formatting requirements. For - * instance take the below: - * - * 127.0.0.1 localhost.localdomain localhost - * ::1 localhost.localdomain localhost - * 192.168.1.1 host.example.com host - * 192.168.1.5 host.example.com host - * 2620:1234::1 host.example.com host6.example.com host6 host - * - * This will yield 2 entries. - * 1) ips: 127.0.0.1,::1 - * hosts: localhost.localdomain,localhost - * 2) ips: 192.168.1.1,192.168.1.5,2620:1234::1 - * hosts: host.example.com,host,host6.example.com,host6 - * - * It could be argued that if searching for 192.168.1.1 that the 'host6' - * hostnames should not be returned, but this implementation will return them - * since they are related. It is unlikely this will matter in the real world. - */ - -struct ares_hosts_file { - time_t ts; - /*! cache the filename so we know if the filename changes it automatically - * invalidates the cache */ - char *filename; - /*! iphash is the owner of the 'entry' object as there is only ever a single - * match to the object. */ - ares_htable_strvp_t *iphash; - /*! hosthash does not own the entry so won't free on destruction */ - ares_htable_strvp_t *hosthash; -}; - -struct ares_hosts_entry { - size_t refcnt; /*! If the entry is stored multiple times in the - * ip address hash, we have to reference count it */ - ares_llist_t *ips; - ares_llist_t *hosts; -}; - -const void *ares_dns_pton(const char *ipaddr, struct ares_addr *addr, - size_t *out_len) -{ - const void *ptr = NULL; - size_t ptr_len = 0; - - if (ipaddr == NULL || addr == NULL || out_len == NULL) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *out_len = 0; - - if (addr->family == AF_INET && - ares_inet_pton(AF_INET, ipaddr, &addr->addr.addr4) > 0) { - ptr = &addr->addr.addr4; - ptr_len = sizeof(addr->addr.addr4); - } else if (addr->family == AF_INET6 && - ares_inet_pton(AF_INET6, ipaddr, &addr->addr.addr6) > 0) { - ptr = &addr->addr.addr6; - ptr_len = sizeof(addr->addr.addr6); - } else if (addr->family == AF_UNSPEC) { - if (ares_inet_pton(AF_INET, ipaddr, &addr->addr.addr4) > 0) { - addr->family = AF_INET; - ptr = &addr->addr.addr4; - ptr_len = sizeof(addr->addr.addr4); - } else if (ares_inet_pton(AF_INET6, ipaddr, &addr->addr.addr6) > 0) { - addr->family = AF_INET6; - ptr = &addr->addr.addr6; - ptr_len = sizeof(addr->addr.addr6); - } - } - - *out_len = ptr_len; - return ptr; -} - -static ares_bool_t ares_normalize_ipaddr(const char *ipaddr, char *out, - size_t out_len) -{ - struct ares_addr data; - const void *addr; - size_t addr_len = 0; - - memset(&data, 0, sizeof(data)); - data.family = AF_UNSPEC; - - addr = ares_dns_pton(ipaddr, &data, &addr_len); - if (addr == NULL) { - return ARES_FALSE; - } - - if (!ares_inet_ntop(data.family, addr, out, (ares_socklen_t)out_len)) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - return ARES_TRUE; -} - -static void ares_hosts_entry_destroy(ares_hosts_entry_t *entry) -{ - if (entry == NULL) { - return; - } - - /* Honor reference counting */ - if (entry->refcnt != 0) { - entry->refcnt--; - } - - if (entry->refcnt > 0) { - return; - } - - ares_llist_destroy(entry->hosts); - ares_llist_destroy(entry->ips); - ares_free(entry); -} - -static void ares_hosts_entry_destroy_cb(void *entry) -{ - ares_hosts_entry_destroy(entry); -} - -void ares_hosts_file_destroy(ares_hosts_file_t *hf) -{ - if (hf == NULL) { - return; - } - - ares_free(hf->filename); - ares_htable_strvp_destroy(hf->hosthash); - ares_htable_strvp_destroy(hf->iphash); - ares_free(hf); -} - -static ares_hosts_file_t *ares_hosts_file_create(const char *filename) -{ - ares_hosts_file_t *hf = ares_malloc_zero(sizeof(*hf)); - if (hf == NULL) { - goto fail; - } - - hf->ts = time(NULL); - - hf->filename = ares_strdup(filename); - if (hf->filename == NULL) { - goto fail; - } - - hf->iphash = ares_htable_strvp_create(ares_hosts_entry_destroy_cb); - if (hf->iphash == NULL) { - goto fail; - } - - hf->hosthash = ares_htable_strvp_create(NULL); - if (hf->hosthash == NULL) { - goto fail; - } - - return hf; - -fail: - ares_hosts_file_destroy(hf); - return NULL; -} - -typedef enum { - ARES_MATCH_NONE = 0, - ARES_MATCH_IPADDR = 1, - ARES_MATCH_HOST = 2 -} ares_hosts_file_match_t; - -static ares_status_t ares_hosts_file_merge_entry( - const ares_hosts_file_t *hf, ares_hosts_entry_t *existing, - ares_hosts_entry_t *entry, ares_hosts_file_match_t matchtype) -{ - ares_llist_node_t *node; - - /* If we matched on IP address, we know there can only be 1, so there's no - * reason to do anything */ - if (matchtype != ARES_MATCH_IPADDR) { - while ((node = ares_llist_node_first(entry->ips)) != NULL) { - const char *ipaddr = ares_llist_node_val(node); - - if (ares_htable_strvp_get_direct(hf->iphash, ipaddr) != NULL) { - ares_llist_node_destroy(node); - continue; - } - - ares_llist_node_mvparent_last(node, existing->ips); - } - } - - - while ((node = ares_llist_node_first(entry->hosts)) != NULL) { - const char *hostname = ares_llist_node_val(node); - - if (ares_htable_strvp_get_direct(hf->hosthash, hostname) != NULL) { - ares_llist_node_destroy(node); - continue; - } - - ares_llist_node_mvparent_last(node, existing->hosts); - } - - ares_hosts_entry_destroy(entry); - return ARES_SUCCESS; -} - -static ares_hosts_file_match_t - ares_hosts_file_match(const ares_hosts_file_t *hf, ares_hosts_entry_t *entry, - ares_hosts_entry_t **match) -{ - ares_llist_node_t *node; - *match = NULL; - - for (node = ares_llist_node_first(entry->ips); node != NULL; - node = ares_llist_node_next(node)) { - const char *ipaddr = ares_llist_node_val(node); - *match = ares_htable_strvp_get_direct(hf->iphash, ipaddr); - if (*match != NULL) { - return ARES_MATCH_IPADDR; - } - } - - for (node = ares_llist_node_first(entry->hosts); node != NULL; - node = ares_llist_node_next(node)) { - const char *host = ares_llist_node_val(node); - *match = ares_htable_strvp_get_direct(hf->hosthash, host); - if (*match != NULL) { - return ARES_MATCH_HOST; - } - } - - return ARES_MATCH_NONE; -} - -/*! entry is invalidated upon calling this function, always, even on error */ -static ares_status_t ares_hosts_file_add(ares_hosts_file_t *hosts, - ares_hosts_entry_t *entry) -{ - ares_hosts_entry_t *match = NULL; - ares_status_t status = ARES_SUCCESS; - ares_llist_node_t *node; - ares_hosts_file_match_t matchtype; - size_t num_hostnames; - - /* Record the number of hostnames in this entry file. If we merge into an - * existing record, these will be *appended* to the entry, so we'll count - * backwards when adding to the hosts hashtable */ - num_hostnames = ares_llist_len(entry->hosts); - - matchtype = ares_hosts_file_match(hosts, entry, &match); - - if (matchtype != ARES_MATCH_NONE) { - status = ares_hosts_file_merge_entry(hosts, match, entry, matchtype); - if (status != ARES_SUCCESS) { - ares_hosts_entry_destroy(entry); /* LCOV_EXCL_LINE: DefensiveCoding */ - return status; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - /* entry was invalidated above by merging */ - entry = match; - } - - if (matchtype != ARES_MATCH_IPADDR) { - const char *ipaddr = ares_llist_last_val(entry->ips); - - if (!ares_htable_strvp_get(hosts->iphash, ipaddr, NULL)) { - if (!ares_htable_strvp_insert(hosts->iphash, ipaddr, entry)) { - ares_hosts_entry_destroy(entry); - return ARES_ENOMEM; - } - entry->refcnt++; - } - } - - /* Go backwards, on a merge, hostnames are appended. Breakout once we've - * consumed all the hosts that we appended */ - for (node = ares_llist_node_last(entry->hosts); node != NULL; - node = ares_llist_node_prev(node)) { - const char *val = ares_llist_node_val(node); - - if (num_hostnames == 0) { - break; - } - - num_hostnames--; - - /* first hostname match wins. If we detect a duplicate hostname for another - * ip it will automatically be added to the same entry */ - if (ares_htable_strvp_get(hosts->hosthash, val, NULL)) { - continue; - } - - if (!ares_htable_strvp_insert(hosts->hosthash, val, entry)) { - return ARES_ENOMEM; - } - } - - return ARES_SUCCESS; -} - -static ares_bool_t ares_hosts_entry_isdup(ares_hosts_entry_t *entry, - const char *host) -{ - ares_llist_node_t *node; - - for (node = ares_llist_node_first(entry->ips); node != NULL; - node = ares_llist_node_next(node)) { - const char *myhost = ares_llist_node_val(node); - if (ares_strcaseeq(myhost, host)) { - return ARES_TRUE; - } - } - - return ARES_FALSE; -} - -static ares_status_t ares_parse_hosts_hostnames(ares_buf_t *buf, - ares_hosts_entry_t *entry) -{ - entry->hosts = ares_llist_create(ares_free); - if (entry->hosts == NULL) { - return ARES_ENOMEM; - } - - /* Parse hostnames and aliases */ - while (ares_buf_len(buf)) { - char hostname[256]; - char *temp; - ares_status_t status; - unsigned char comment = '#'; - - ares_buf_consume_whitespace(buf, ARES_FALSE); - - if (ares_buf_len(buf) == 0) { - break; - } - - /* See if it is a comment, if so stop processing */ - if (ares_buf_begins_with(buf, &comment, 1)) { - break; - } - - ares_buf_tag(buf); - - /* Must be at end of line */ - if (ares_buf_consume_nonwhitespace(buf) == 0) { - break; - } - - status = ares_buf_tag_fetch_string(buf, hostname, sizeof(hostname)); - if (status != ARES_SUCCESS) { - /* Bad entry, just ignore as long as its not the first. If its the first, - * it must be valid */ - if (ares_llist_len(entry->hosts) == 0) { - return ARES_EBADSTR; - } - - continue; - } - - /* Validate it is a valid hostname characterset */ - if (!ares_is_hostname(hostname)) { - continue; - } - - /* Don't add a duplicate to the same entry */ - if (ares_hosts_entry_isdup(entry, hostname)) { - continue; - } - - /* Add to list */ - temp = ares_strdup(hostname); - if (temp == NULL) { - return ARES_ENOMEM; - } - - if (ares_llist_insert_last(entry->hosts, temp) == NULL) { - ares_free(temp); - return ARES_ENOMEM; - } - } - - /* Must have at least 1 entry */ - if (ares_llist_len(entry->hosts) == 0) { - return ARES_EBADSTR; - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_parse_hosts_ipaddr(ares_buf_t *buf, - ares_hosts_entry_t **entry_out) -{ - char addr[INET6_ADDRSTRLEN]; - char *temp; - ares_hosts_entry_t *entry = NULL; - ares_status_t status; - - *entry_out = NULL; - - ares_buf_tag(buf); - ares_buf_consume_nonwhitespace(buf); - status = ares_buf_tag_fetch_string(buf, addr, sizeof(addr)); - if (status != ARES_SUCCESS) { - return status; - } - - /* Validate and normalize the ip address format */ - if (!ares_normalize_ipaddr(addr, addr, sizeof(addr))) { - return ARES_EBADSTR; - } - - entry = ares_malloc_zero(sizeof(*entry)); - if (entry == NULL) { - return ARES_ENOMEM; - } - - entry->ips = ares_llist_create(ares_free); - if (entry->ips == NULL) { - ares_hosts_entry_destroy(entry); - return ARES_ENOMEM; - } - - temp = ares_strdup(addr); - if (temp == NULL) { - ares_hosts_entry_destroy(entry); - return ARES_ENOMEM; - } - - if (ares_llist_insert_first(entry->ips, temp) == NULL) { - ares_free(temp); - ares_hosts_entry_destroy(entry); - return ARES_ENOMEM; - } - - *entry_out = entry; - - return ARES_SUCCESS; -} - -static ares_status_t ares_parse_hosts(const char *filename, - ares_hosts_file_t **out) -{ - ares_buf_t *buf = NULL; - ares_status_t status = ARES_EBADRESP; - ares_hosts_file_t *hf = NULL; - ares_hosts_entry_t *entry = NULL; - - *out = NULL; - - buf = ares_buf_create(); - if (buf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_buf_load_file(filename, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - hf = ares_hosts_file_create(filename); - if (hf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - while (ares_buf_len(buf)) { - unsigned char comment = '#'; - - /* -- Start of new line here -- */ - - /* Consume any leading whitespace */ - ares_buf_consume_whitespace(buf, ARES_FALSE); - - if (ares_buf_len(buf) == 0) { - break; - } - - /* See if it is a comment, if so, consume remaining line */ - if (ares_buf_begins_with(buf, &comment, 1)) { - ares_buf_consume_line(buf, ARES_TRUE); - continue; - } - - /* Pull off ip address */ - status = ares_parse_hosts_ipaddr(buf, &entry); - if (status == ARES_ENOMEM) { - goto done; - } - if (status != ARES_SUCCESS) { - /* Bad line, consume and go onto next */ - ares_buf_consume_line(buf, ARES_TRUE); - continue; - } - - /* Parse of the hostnames */ - status = ares_parse_hosts_hostnames(buf, entry); - if (status == ARES_ENOMEM) { - goto done; - } else if (status != ARES_SUCCESS) { - /* Bad line, consume and go onto next */ - ares_hosts_entry_destroy(entry); - entry = NULL; - ares_buf_consume_line(buf, ARES_TRUE); - continue; - } - - /* Append the successful entry to the hosts file */ - status = ares_hosts_file_add(hf, entry); - entry = NULL; /* is always invalidated by this function, even on error */ - if (status != ARES_SUCCESS) { - goto done; - } - - /* Go to next line */ - ares_buf_consume_line(buf, ARES_TRUE); - } - - status = ARES_SUCCESS; - -done: - ares_hosts_entry_destroy(entry); - ares_buf_destroy(buf); - if (status != ARES_SUCCESS) { - ares_hosts_file_destroy(hf); - } else { - *out = hf; - } - return status; -} - -static ares_bool_t ares_hosts_expired(const char *filename, - const ares_hosts_file_t *hf) -{ - time_t mod_ts = 0; - -#ifdef HAVE_STAT - struct stat st; - if (stat(filename, &st) == 0) { - mod_ts = st.st_mtime; - } -#elif defined(_WIN32) - struct _stat st; - if (_stat(filename, &st) == 0) { - mod_ts = st.st_mtime; - } -#else - (void)filename; -#endif - - if (hf == NULL) { - return ARES_TRUE; - } - - /* Expire every 60s if we can't get a time */ - if (mod_ts == 0) { - mod_ts = - time(NULL) - 60; /* LCOV_EXCL_LINE: only on systems without stat() */ - } - - /* If filenames are different, its expired */ - if (!ares_strcaseeq(hf->filename, filename)) { - return ARES_TRUE; - } - - if (hf->ts <= mod_ts) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -static ares_status_t ares_hosts_path(const ares_channel_t *channel, - ares_bool_t use_env, char **path) -{ - char *path_hosts = NULL; - - *path = NULL; - - if (channel->hosts_path) { - path_hosts = ares_strdup(channel->hosts_path); - if (!path_hosts) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - if (use_env) { - if (path_hosts) { - ares_free(path_hosts); - } - - path_hosts = ares_strdup(getenv("CARES_HOSTS")); - if (!path_hosts) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - if (!path_hosts) { -#if defined(USE_WINSOCK) - char PATH_HOSTS[MAX_PATH] = ""; - char tmp[MAX_PATH]; - HKEY hkeyHosts; - DWORD dwLength = sizeof(tmp); - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, - &hkeyHosts) != ERROR_SUCCESS) { - return ARES_ENOTFOUND; - } - RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, - &dwLength); - ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH); - RegCloseKey(hkeyHosts); - strcat(PATH_HOSTS, WIN_PATH_HOSTS); -#elif defined(WATT32) - const char *PATH_HOSTS = _w32_GetHostsFile(); - - if (!PATH_HOSTS) { - return ARES_ENOTFOUND; - } -#endif - path_hosts = ares_strdup(PATH_HOSTS); - if (!path_hosts) { - return ARES_ENOMEM; - } - } - - *path = path_hosts; - return ARES_SUCCESS; -} - -static ares_status_t ares_hosts_update(ares_channel_t *channel, - ares_bool_t use_env) -{ - ares_status_t status; - char *filename = NULL; - - status = ares_hosts_path(channel, use_env, &filename); - if (status != ARES_SUCCESS) { - return status; - } - - if (!ares_hosts_expired(filename, channel->hf)) { - ares_free(filename); - return ARES_SUCCESS; - } - - ares_hosts_file_destroy(channel->hf); - channel->hf = NULL; - - status = ares_parse_hosts(filename, &channel->hf); - ares_free(filename); - return status; -} - -ares_status_t ares_hosts_search_ipaddr(ares_channel_t *channel, - ares_bool_t use_env, const char *ipaddr, - const ares_hosts_entry_t **entry) -{ - ares_status_t status; - char addr[INET6_ADDRSTRLEN]; - - *entry = NULL; - - status = ares_hosts_update(channel, use_env); - if (status != ARES_SUCCESS) { - return status; - } - - if (channel->hf == NULL) { - return ARES_ENOTFOUND; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (!ares_normalize_ipaddr(ipaddr, addr, sizeof(addr))) { - return ARES_EBADNAME; - } - - *entry = ares_htable_strvp_get_direct(channel->hf->iphash, addr); - if (*entry == NULL) { - return ARES_ENOTFOUND; - } - - return ARES_SUCCESS; -} - -ares_status_t ares_hosts_search_host(ares_channel_t *channel, - ares_bool_t use_env, const char *host, - const ares_hosts_entry_t **entry) -{ - ares_status_t status; - - *entry = NULL; - - status = ares_hosts_update(channel, use_env); - if (status != ARES_SUCCESS) { - return status; - } - - if (channel->hf == NULL) { - return ARES_ENOTFOUND; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *entry = ares_htable_strvp_get_direct(channel->hf->hosthash, host); - if (*entry == NULL) { - return ARES_ENOTFOUND; - } - - return ARES_SUCCESS; -} - -static ares_status_t - ares_hosts_ai_append_cnames(const ares_hosts_entry_t *entry, - struct ares_addrinfo_cname **cnames_out) -{ - struct ares_addrinfo_cname *cname = NULL; - struct ares_addrinfo_cname *cnames = NULL; - const char *primaryhost; - ares_llist_node_t *node; - ares_status_t status; - size_t cnt = 0; - - node = ares_llist_node_first(entry->hosts); - primaryhost = ares_llist_node_val(node); - /* Skip to next node to start with aliases */ - node = ares_llist_node_next(node); - - while (node != NULL) { - const char *host = ares_llist_node_val(node); - - /* Cap at 100 entries. , some people use - * https://github.com/StevenBlack/hosts and we don't need 200k+ aliases */ - cnt++; - if (cnt > 100) { - break; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - cname = ares_append_addrinfo_cname(&cnames); - if (cname == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - cname->alias = ares_strdup(host); - if (cname->alias == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - cname->name = ares_strdup(primaryhost); - if (cname->name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - node = ares_llist_node_next(node); - } - - /* No entries, add only primary */ - if (cnames == NULL) { - cname = ares_append_addrinfo_cname(&cnames); - if (cname == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - cname->name = ares_strdup(primaryhost); - if (cname->name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - status = ARES_SUCCESS; - -done: - if (status != ARES_SUCCESS) { - ares_freeaddrinfo_cnames(cnames); /* LCOV_EXCL_LINE: DefensiveCoding */ - return status; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *cnames_out = cnames; - return ARES_SUCCESS; -} - -ares_status_t ares_hosts_entry_to_addrinfo(const ares_hosts_entry_t *entry, - const char *name, int family, - unsigned short port, - ares_bool_t want_cnames, - struct ares_addrinfo *ai) -{ - ares_status_t status = ARES_ENOTFOUND; - struct ares_addrinfo_cname *cnames = NULL; - struct ares_addrinfo_node *ainodes = NULL; - ares_llist_node_t *node; - - switch (family) { - case AF_INET: - case AF_INET6: - case AF_UNSPEC: - break; - default: /* LCOV_EXCL_LINE: DefensiveCoding */ - return ARES_EBADFAMILY; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (name != NULL) { - ares_free(ai->name); - ai->name = ares_strdup(name); - if (ai->name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - for (node = ares_llist_node_first(entry->ips); node != NULL; - node = ares_llist_node_next(node)) { - struct ares_addr addr; - const void *ptr = NULL; - size_t ptr_len = 0; - const char *ipaddr = ares_llist_node_val(node); - - memset(&addr, 0, sizeof(addr)); - addr.family = family; - ptr = ares_dns_pton(ipaddr, &addr, &ptr_len); - - if (ptr == NULL) { - continue; - } - - status = ares_append_ai_node(addr.family, port, 0, ptr, &ainodes); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - } - - /* Might be ARES_ENOTFOUND here if no ips matched requested address family */ - if (status != ARES_SUCCESS) { - goto done; - } - - if (want_cnames) { - status = ares_hosts_ai_append_cnames(entry, &cnames); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - } - - status = ARES_SUCCESS; - -done: - if (status != ARES_SUCCESS) { - /* LCOV_EXCL_START: defensive coding */ - ares_freeaddrinfo_cnames(cnames); - ares_freeaddrinfo_nodes(ainodes); - ares_free(ai->name); - ai->name = NULL; - return status; - /* LCOV_EXCL_STOP */ - } - ares_addrinfo_cat_cnames(&ai->cnames, cnames); - ares_addrinfo_cat_nodes(&ai->nodes, ainodes); - - return status; -} - -ares_status_t ares_hosts_entry_to_hostent(const ares_hosts_entry_t *entry, - int family, struct hostent **hostent) -{ - ares_status_t status; - struct ares_addrinfo *ai = ares_malloc_zero(sizeof(*ai)); - - *hostent = NULL; - - if (ai == NULL) { - return ARES_ENOMEM; - } - - status = ares_hosts_entry_to_addrinfo(entry, NULL, family, 0, ARES_TRUE, ai); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_addrinfo2hostent(ai, family, hostent); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_freeaddrinfo(ai); - if (status != ARES_SUCCESS) { - ares_free_hostent(*hostent); - *hostent = NULL; - } - - return status; -} diff --git a/vendor/c-ares/src/lib/ares_inet_net_pton.h b/vendor/c-ares/src/lib/ares_inet_net_pton.h deleted file mode 100644 index e3ed83a3c..000000000 --- a/vendor/c-ares/src/lib/ares_inet_net_pton.h +++ /dev/null @@ -1,31 +0,0 @@ -/* MIT License - * - * Copyright (c) 2005 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef HEADER_CARES_INET_NET_PTON_H -#define HEADER_CARES_INET_NET_PTON_H - -int ares_inet_net_pton(int af, const char *src, void *dst, size_t size); - -#endif /* HEADER_CARES_INET_NET_PTON_H */ diff --git a/vendor/c-ares/src/lib/ares_init.c b/vendor/c-ares/src/lib/ares_init.c deleted file mode 100644 index ae78262a1..000000000 --- a/vendor/c-ares/src/lib/ares_init.c +++ /dev/null @@ -1,600 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2007 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_SYS_PARAM_H -# include -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_NETDB_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_nameser.h" - -#if defined(ANDROID) || defined(__ANDROID__) -# include -# include "ares_android.h" -/* From the Bionic sources */ -# define DNS_PROP_NAME_PREFIX "net.dns" -# define MAX_DNS_PROPERTIES 8 -#endif - -#if defined(CARES_USE_LIBRESOLV) -# include -#endif - -#if defined(USE_WINSOCK) && defined(HAVE_IPHLPAPI_H) -# include -#endif - -#include "ares_inet_net_pton.h" -#include "event/ares_event.h" - -int ares_init(ares_channel_t **channelptr) -{ - return ares_init_options(channelptr, NULL, 0); -} - -static int ares_query_timeout_cmp_cb(const void *arg1, const void *arg2) -{ - const ares_query_t *q1 = arg1; - const ares_query_t *q2 = arg2; - - if (q1->timeout.sec > q2->timeout.sec) { - return 1; - } - if (q1->timeout.sec < q2->timeout.sec) { - return -1; - } - - if (q1->timeout.usec > q2->timeout.usec) { - return 1; - } - if (q1->timeout.usec < q2->timeout.usec) { - return -1; - } - - return 0; -} - -static int server_sort_cb(const void *data1, const void *data2) -{ - const ares_server_t *s1 = data1; - const ares_server_t *s2 = data2; - - if (s1->consec_failures < s2->consec_failures) { - return -1; - } - if (s1->consec_failures > s2->consec_failures) { - return 1; - } - if (s1->idx < s2->idx) { - return -1; - } - if (s1->idx > s2->idx) { - return 1; - } - return 0; -} - -static void server_destroy_cb(void *data) -{ - if (data == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - ares_destroy_server(data); -} - -static ares_status_t init_by_defaults(ares_channel_t *channel) -{ - char *hostname = NULL; - ares_status_t rc = ARES_SUCCESS; -#ifdef HAVE_GETHOSTNAME - const char *dot; -#endif - struct ares_addr addr; - ares_llist_t *sconfig = NULL; - - /* Enable EDNS by default */ - if (!(channel->optmask & ARES_OPT_FLAGS)) { - channel->flags = ARES_FLAG_EDNS; - } - if (channel->ednspsz == 0) { - channel->ednspsz = EDNSPACKETSZ; - } - - if (channel->timeout == 0) { - channel->timeout = DEFAULT_TIMEOUT; - } - - if (channel->tries == 0) { - channel->tries = DEFAULT_TRIES; - } - - if (ares_slist_len(channel->servers) == 0) { - /* Add a default local named server to the channel unless configured not - * to (in which case return an error). - */ - if (channel->flags & ARES_FLAG_NO_DFLT_SVR) { - rc = ARES_ENOSERVER; - goto error; - } - - addr.family = AF_INET; - addr.addr.addr4.s_addr = htonl(INADDR_LOOPBACK); - - rc = ares_sconfig_append(channel, &sconfig, &addr, 0, 0, NULL); - if (rc != ARES_SUCCESS) { - goto error; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - rc = ares_servers_update(channel, sconfig, ARES_FALSE); - ares_llist_destroy(sconfig); - - if (rc != ARES_SUCCESS) { - goto error; - } - } - - if (channel->ndomains == 0) { - /* Derive a default domain search list from the kernel hostname, - * or set it to empty if the hostname isn't helpful. - */ -#ifndef HAVE_GETHOSTNAME - channel->ndomains = 0; /* default to none */ -#else - size_t len = 256; - channel->ndomains = 0; /* default to none */ - - hostname = ares_malloc(len); - if (!hostname) { - rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto error; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (gethostname(hostname, (GETHOSTNAME_TYPE_ARG2)len) != 0) { - /* Lets not treat a gethostname failure as critical, since we - * are ok if gethostname doesn't even exist */ - *hostname = '\0'; - } - - dot = strchr(hostname, '.'); - if (dot) { - /* a dot was found */ - channel->domains = ares_malloc(sizeof(char *)); - if (!channel->domains) { - rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto error; /* LCOV_EXCL_LINE: OutOfMemory */ - } - channel->domains[0] = ares_strdup(dot + 1); - if (!channel->domains[0]) { - rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto error; /* LCOV_EXCL_LINE: OutOfMemory */ - } - channel->ndomains = 1; - } -#endif - } - - if (channel->nsort == 0) { - channel->sortlist = NULL; - } - - if (!channel->lookups) { - channel->lookups = ares_strdup("fb"); - if (!channel->lookups) { - rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - /* Set default fields for server failover behavior */ - if (!(channel->optmask & ARES_OPT_SERVER_FAILOVER)) { - channel->server_retry_chance = DEFAULT_SERVER_RETRY_CHANCE; - channel->server_retry_delay = DEFAULT_SERVER_RETRY_DELAY; - } - -error: - if (hostname) { - ares_free(hostname); - } - - return rc; -} - -int ares_init_options(ares_channel_t **channelptr, - const struct ares_options *options, int optmask) -{ - ares_channel_t *channel; - ares_status_t status = ARES_SUCCESS; - - if (ares_library_initialized() != ARES_SUCCESS) { - return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ - } - - channel = ares_malloc_zero(sizeof(*channel)); - if (!channel) { - *channelptr = NULL; - return ARES_ENOMEM; - } - - /* We are in a good state */ - channel->sys_up = ARES_TRUE; - - /* One option where zero is valid, so set default value here */ - channel->ndots = 1; - - status = ares_channel_threading_init(channel); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Generate random key */ - channel->rand_state = ares_init_rand_state(); - if (channel->rand_state == NULL) { - status = ARES_ENOMEM; - DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", - ares_strerror(status))); - goto done; - } - - /* Initialize Server List */ - channel->servers = - ares_slist_create(channel->rand_state, server_sort_cb, server_destroy_cb); - if (channel->servers == NULL) { - status = ARES_ENOMEM; - goto done; - } - - /* Initialize our lists of queries */ - channel->all_queries = ares_llist_create(NULL); - if (channel->all_queries == NULL) { - status = ARES_ENOMEM; - goto done; - } - - channel->queries_by_qid = ares_htable_szvp_create(NULL); - if (channel->queries_by_qid == NULL) { - status = ARES_ENOMEM; - goto done; - } - - channel->queries_by_timeout = - ares_slist_create(channel->rand_state, ares_query_timeout_cmp_cb, NULL); - if (channel->queries_by_timeout == NULL) { - status = ARES_ENOMEM; - goto done; - } - - channel->connnode_by_socket = ares_htable_asvp_create(NULL); - if (channel->connnode_by_socket == NULL) { - status = ARES_ENOMEM; - goto done; - } - - /* Initialize configuration by each of the four sources, from highest - * precedence to lowest. - */ - - status = ares_init_by_options(channel, options, optmask); - if (status != ARES_SUCCESS) { - DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n", - ares_strerror(status))); - /* If we fail to apply user-specified options, fail the whole init process - */ - goto done; - } - - /* Go ahead and let it initialize the query cache even if the ttl is 0 and - * completely unused. This reduces the number of different code paths that - * might be followed even if there is a minor performance hit. */ - status = ares_qcache_create(channel->rand_state, channel->qcache_max_ttl, - &channel->qcache); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (status == ARES_SUCCESS) { - status = ares_init_by_sysconfig(channel); - if (status != ARES_SUCCESS) { - DEBUGF(fprintf(stderr, "Error: init_by_sysconfig failed: %s\n", - ares_strerror(status))); - } - } - - /* - * No matter what failed or succeeded, seed defaults to provide - * useful behavior for things that we missed. - */ - status = init_by_defaults(channel); - if (status != ARES_SUCCESS) { - DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", - ares_strerror(status))); - goto done; - } - - ares_set_socket_functions_def(channel); - - /* Initialize the event thread */ - if (channel->optmask & ARES_OPT_EVENT_THREAD) { - ares_event_thread_t *e = NULL; - - status = ares_event_thread_init(channel); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: UntestablePath */ - } - - /* Initialize monitor for configuration changes. In some rare cases, - * ARES_ENOTIMP may occur (OpenWatcom), ignore this. */ - e = channel->sock_state_cb_data; - status = ares_event_configchg_init(&e->configchg, e); - if (status != ARES_SUCCESS && status != ARES_ENOTIMP) { - goto done; /* LCOV_EXCL_LINE: UntestablePath */ - } - status = ARES_SUCCESS; - } - -done: - if (status != ARES_SUCCESS) { - ares_destroy(channel); - return (int)status; - } - - *channelptr = channel; - return ARES_SUCCESS; -} - -static void *ares_reinit_thread(void *arg) -{ - ares_channel_t *channel = arg; - ares_status_t status; - - /* ares_init_by_sysconfig() will lock when applying the config, but not - * when retrieving. */ - status = ares_init_by_sysconfig(channel); - if (status != ARES_SUCCESS) { - DEBUGF(fprintf(stderr, "Error: init_by_sysconfig failed: %s\n", - ares_strerror(status))); - } - - ares_channel_lock(channel); - - /* Flush cached queries on reinit */ - if (status == ARES_SUCCESS && channel->qcache) { - ares_qcache_flush(channel->qcache); - } - - channel->reinit_pending = ARES_FALSE; - ares_channel_unlock(channel); - - return NULL; -} - -ares_status_t ares_reinit(ares_channel_t *channel) -{ - ares_status_t status = ARES_SUCCESS; - - if (channel == NULL) { - return ARES_EFORMERR; - } - - ares_channel_lock(channel); - - /* If a reinit is already in process, lets not do it again. Or if we are - * shutting down, skip. */ - if (!channel->sys_up || channel->reinit_pending) { - ares_channel_unlock(channel); - return ARES_SUCCESS; - } - channel->reinit_pending = ARES_TRUE; - ares_channel_unlock(channel); - - if (ares_threadsafety()) { - /* clean up the prior reinit process's thread. We know the thread isn't - * running since reinit_pending was false */ - if (channel->reinit_thread != NULL) { - void *rv; - ares_thread_join(channel->reinit_thread, &rv); - channel->reinit_thread = NULL; - } - - /* Spawn a new thread */ - status = - ares_thread_create(&channel->reinit_thread, ares_reinit_thread, channel); - if (status != ARES_SUCCESS) { - /* LCOV_EXCL_START: UntestablePath */ - ares_channel_lock(channel); - channel->reinit_pending = ARES_FALSE; - ares_channel_unlock(channel); - /* LCOV_EXCL_STOP */ - } - } else { - /* Threading support not available, call directly */ - ares_reinit_thread(channel); - } - - return status; -} - -/* ares_dup() duplicates a channel handle with all its options and returns a - new channel handle */ -int ares_dup(ares_channel_t **dest, const ares_channel_t *src) -{ - struct ares_options opts; - ares_status_t rc; - int optmask; - - if (dest == NULL || src == NULL) { - return ARES_EFORMERR; - } - - *dest = NULL; /* in case of failure return NULL explicitly */ - - /* First get the options supported by the old ares_save_options() function, - which is most of them */ - rc = (ares_status_t)ares_save_options(src, &opts, &optmask); - if (rc != ARES_SUCCESS) { - ares_destroy_options(&opts); - goto done; - } - - /* Then create the new channel with those options */ - rc = (ares_status_t)ares_init_options(dest, &opts, optmask); - - /* destroy the options copy to not leak any memory */ - ares_destroy_options(&opts); - - if (rc != ARES_SUCCESS) { - goto done; - } - - ares_channel_lock(src); - /* Now clone the options that ares_save_options() doesn't support, but are - * user-provided */ - (*dest)->sock_create_cb = src->sock_create_cb; - (*dest)->sock_create_cb_data = src->sock_create_cb_data; - (*dest)->sock_config_cb = src->sock_config_cb; - (*dest)->sock_config_cb_data = src->sock_config_cb_data; - memcpy(&(*dest)->sock_funcs, &(src->sock_funcs), sizeof((*dest)->sock_funcs)); - (*dest)->sock_func_cb_data = src->sock_func_cb_data; - (*dest)->legacy_sock_funcs = src->legacy_sock_funcs; - (*dest)->legacy_sock_funcs_cb_data = src->legacy_sock_funcs_cb_data; - (*dest)->server_state_cb = src->server_state_cb; - (*dest)->server_state_cb_data = src->server_state_cb_data; - - ares_strcpy((*dest)->local_dev_name, src->local_dev_name, - sizeof((*dest)->local_dev_name)); - (*dest)->local_ip4 = src->local_ip4; - memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6)); - ares_channel_unlock(src); - - /* Servers are a bit unique as ares_init_options() only allows ipv4 servers - * and not a port per server, but there are other user specified ways, that - * too will toggle the optmask ARES_OPT_SERVERS to let us know. If that's - * the case, pull them in. - * - * We don't want to clone system-configuration servers though. - * - * We must use the "csv" format to get things like link-local address support - */ - - if (optmask & ARES_OPT_SERVERS) { - char *csv = ares_get_servers_csv(src); - if (csv == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - ares_destroy(*dest); - *dest = NULL; - rc = ARES_ENOMEM; - goto done; - /* LCOV_EXCL_STOP */ - } - - rc = (ares_status_t)ares_set_servers_ports_csv(*dest, csv); - ares_free_string(csv); - if (rc != ARES_SUCCESS) { - /* LCOV_EXCL_START: OutOfMemory */ - ares_destroy(*dest); - *dest = NULL; - goto done; - /* LCOV_EXCL_STOP */ - } - } - - rc = ARES_SUCCESS; -done: - return (int)rc; /* everything went fine */ -} - -void ares_set_local_ip4(ares_channel_t *channel, unsigned int local_ip) -{ - if (channel == NULL) { - return; - } - ares_channel_lock(channel); - channel->local_ip4 = local_ip; - ares_channel_unlock(channel); -} - -/* local_ip6 should be 16 bytes in length */ -void ares_set_local_ip6(ares_channel_t *channel, const unsigned char *local_ip6) -{ - if (channel == NULL) { - return; - } - ares_channel_lock(channel); - memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6)); - ares_channel_unlock(channel); -} - -/* local_dev_name should be null terminated. */ -void ares_set_local_dev(ares_channel_t *channel, const char *local_dev_name) -{ - if (channel == NULL) { - return; - } - - ares_channel_lock(channel); - ares_strcpy(channel->local_dev_name, local_dev_name, - sizeof(channel->local_dev_name)); - channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0; - ares_channel_unlock(channel); -} - -int ares_set_sortlist(ares_channel_t *channel, const char *sortstr) -{ - size_t nsort = 0; - struct apattern *sortlist = NULL; - ares_status_t status; - - if (!channel) { - return ARES_ENODATA; - } - ares_channel_lock(channel); - - status = ares_parse_sortlist(&sortlist, &nsort, sortstr); - if (status == ARES_SUCCESS && sortlist) { - if (channel->sortlist) { - ares_free(channel->sortlist); - } - channel->sortlist = sortlist; - channel->nsort = nsort; - - /* Save sortlist as if it was passed in as an option */ - channel->optmask |= ARES_OPT_SORTLIST; - } - ares_channel_unlock(channel); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/ares_ipv6.h b/vendor/c-ares/src/lib/ares_ipv6.h deleted file mode 100644 index d2007cc29..000000000 --- a/vendor/c-ares/src/lib/ares_ipv6.h +++ /dev/null @@ -1,115 +0,0 @@ -/* MIT License - * - * Copyright (c) 2005 Dominick Meglio - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifndef ARES_IPV6_H -#define ARES_IPV6_H - -#ifdef HAVE_NETINET6_IN6_H -# include -#endif - -#if defined(USE_WINSOCK) -# if defined(HAVE_IPHLPAPI_H) -# include -# endif -# if defined(HAVE_NETIOAPI_H) -# include -# endif -#endif - -#ifndef HAVE_PF_INET6 -# define PF_INET6 AF_INET6 -#endif - -#ifndef HAVE_STRUCT_SOCKADDR_IN6 -struct sockaddr_in6 { - unsigned short sin6_family; - unsigned short sin6_port; - unsigned long sin6_flowinfo; - struct ares_in6_addr sin6_addr; - unsigned int sin6_scope_id; -}; -#endif - -typedef union { - struct sockaddr sa; - struct sockaddr_in sa4; - struct sockaddr_in6 sa6; -} ares_sockaddr; - -#ifndef HAVE_STRUCT_ADDRINFO -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - ares_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */ - char *ai_canonname; - struct sockaddr *ai_addr; - struct addrinfo *ai_next; -}; -#endif - -#ifndef NS_IN6ADDRSZ -# ifndef HAVE_STRUCT_IN6_ADDR -/* We cannot have it set to zero, so we pick a fixed value here */ -# define NS_IN6ADDRSZ 16 -# else -# define NS_IN6ADDRSZ sizeof(struct in6_addr) -# endif -#endif - -#ifndef NS_INADDRSZ -# define NS_INADDRSZ sizeof(struct in_addr) -#endif - -#ifndef NS_INT16SZ -# define NS_INT16SZ 2 -#endif - -/* Windows XP Compatibility with later MSVC/Mingw versions */ -#if defined(_WIN32) -# if !defined(IF_MAX_STRING_SIZE) -# define IF_MAX_STRING_SIZE 256 /* =256 in */ -# endif -# if !defined(NDIS_IF_MAX_STRING_SIZE) -# define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE /* =256 in */ -# endif -#endif - -#ifndef IF_NAMESIZE -# ifdef IFNAMSIZ -# define IF_NAMESIZE IFNAMSIZ -# else -# define IF_NAMESIZE 32 -# endif -#endif - -/* Defined in inet_net_pton.c for no particular reason. */ -extern const struct ares_in6_addr ares_in6addr_any; /* :: */ - - -#endif /* ARES_IPV6_H */ diff --git a/vendor/c-ares/src/lib/ares_library_init.c b/vendor/c-ares/src/lib/ares_library_init.c deleted file mode 100644 index 2b91692ba..000000000 --- a/vendor/c-ares/src/lib/ares_library_init.c +++ /dev/null @@ -1,169 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2004 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -/* library-private global and unique instance vars */ - -#if defined(ANDROID) || defined(__ANDROID__) -# include "ares_android.h" -#endif - -/* library-private global vars with source visibility restricted to this file */ - -static unsigned int ares_initialized; -static int ares_init_flags; - -/* library-private global vars with visibility across the whole library */ - -/* Some systems may return either NULL or a valid pointer on malloc(0). c-ares - * should never call malloc(0) so lets return NULL so we're more likely to find - * an issue if it were to occur. */ - -static void *default_malloc(size_t size) -{ - if (size == 0) { - return NULL; - } - return malloc(size); -} - -static void *default_realloc(void *p, size_t size) -{ - return realloc(p, size); -} - -static void default_free(void *p) -{ - free(p); -} - -static void *(*__ares_malloc)(size_t size) = default_malloc; -static void *(*__ares_realloc)(void *ptr, size_t size) = default_realloc; -static void (*__ares_free)(void *ptr) = default_free; - -void *ares_malloc(size_t size) -{ - return __ares_malloc(size); -} - -void *ares_realloc(void *ptr, size_t size) -{ - return __ares_realloc(ptr, size); -} - -void ares_free(void *ptr) -{ - __ares_free(ptr); -} - -void *ares_malloc_zero(size_t size) -{ - void *ptr = ares_malloc(size); - if (ptr != NULL) { - memset(ptr, 0, size); - } - - return ptr; -} - -void *ares_realloc_zero(void *ptr, size_t orig_size, size_t new_size) -{ - void *p = ares_realloc(ptr, new_size); - if (p == NULL) { - return NULL; - } - - if (new_size > orig_size) { - memset((unsigned char *)p + orig_size, 0, new_size - orig_size); - } - - return p; -} - -int ares_library_init(int flags) -{ - if (ares_initialized) { - ares_initialized++; - return ARES_SUCCESS; - } - ares_initialized++; - - /* NOTE: ARES_LIB_INIT_WIN32 flag no longer used */ - - ares_init_flags = flags; - - return ARES_SUCCESS; -} - -int ares_library_init_mem(int flags, void *(*amalloc)(size_t size), - void (*afree)(void *ptr), - void *(*arealloc)(void *ptr, size_t size)) -{ - if (amalloc) { - __ares_malloc = amalloc; - } - if (arealloc) { - __ares_realloc = arealloc; - } - if (afree) { - __ares_free = afree; - } - return ares_library_init(flags); -} - -void ares_library_cleanup(void) -{ - if (!ares_initialized) { - return; - } - ares_initialized--; - if (ares_initialized) { - return; - } - - /* NOTE: ARES_LIB_INIT_WIN32 flag no longer used */ - -#if defined(ANDROID) || defined(__ANDROID__) - ares_library_cleanup_android(); -#endif - - ares_init_flags = ARES_LIB_INIT_NONE; - __ares_malloc = default_malloc; - __ares_realloc = default_realloc; - __ares_free = default_free; -} - -int ares_library_initialized(void) -{ -#ifdef USE_WINSOCK - if (!ares_initialized) { - return ARES_ENOTINITIALIZED; - } -#endif - return ARES_SUCCESS; -} diff --git a/vendor/c-ares/src/lib/ares_metrics.c b/vendor/c-ares/src/lib/ares_metrics.c deleted file mode 100644 index deb3b7feb..000000000 --- a/vendor/c-ares/src/lib/ares_metrics.c +++ /dev/null @@ -1,261 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - - -/* IMPLEMENTATION NOTES - * ==================== - * - * With very little effort we should be able to determine fairly proper timeouts - * we can use based on prior query history. We track in order to be able to - * auto-scale when network conditions change (e.g. maybe there is a provider - * failover and timings change due to that). Apple appears to do this within - * their system resolver in MacOS. Obviously we should have a minimum, maximum, - * and initial value to make sure the algorithm doesn't somehow go off the - * rails. - * - * Values: - * - Minimum Timeout: 250ms (approximate RTT half-way around the globe) - * - Maximum Timeout: 5000ms (Recommended timeout in RFC 1123), can be reduced - * by ARES_OPT_MAXTIMEOUTMS, but otherwise the bound specified by the option - * caps the retry timeout. - * - Initial Timeout: User-specified via configuration or ARES_OPT_TIMEOUTMS - * - Average latency multiplier: 5x (a local DNS server returning a cached value - * will be quicker than if it needs to recurse so we need to account for this) - * - Minimum Count for Average: 3. This is the minimum number of queries we - * need to form an average for the bucket. - * - * Per-server buckets for tracking latency over time (these are ephemeral - * meaning they don't persist once a channel is destroyed). We record both the - * current timespan for the bucket and the immediate preceding timespan in case - * of roll-overs we can still maintain recent metrics for calculations: - * - 1 minute - * - 15 minutes - * - 1 hr - * - 1 day - * - since inception - * - * Each bucket would contain: - * - timestamp (divided by interval) - * - minimum latency - * - maximum latency - * - total time - * - count - * NOTE: average latency is (total time / count), we will calculate this - * dynamically when needed - * - * Basic algorithm for calculating timeout to use would be: - * - Scan from most recent bucket to least recent - * - Check timestamp of bucket, if doesn't match current time, continue to next - * bucket - * - Check count of bucket, if its not at least the "Minimum Count for Average", - * check the previous bucket, otherwise continue to next bucket - * - If we reached the end with no bucket match, use "Initial Timeout" - * - If bucket is selected, take ("total time" / count) as Average latency, - * multiply by "Average Latency Multiplier", bound by "Minimum Timeout" and - * "Maximum Timeout" - * NOTE: The timeout calculated may not be the timeout used. If we are retrying - * the query on the same server another time, then it will use a larger value - * - * On each query reply where the response is legitimate (proper response or - * NXDOMAIN) and not something like a server error: - * - Cycle through each bucket in order - * - Check timestamp of bucket against current timestamp, if out of date - * overwrite previous entry with values, clear current values - * - Compare current minimum and maximum recorded latency against query time and - * adjust if necessary - * - Increment "count" by 1 and "total time" by the query time - * - * Other Notes: - * - This is always-on, the only user-configurable value is the initial - * timeout which will simply re-uses the current option. - * - Minimum and Maximum latencies for a bucket are currently unused but are - * there in case we find a need for them in the future. - */ - -#include "ares_private.h" - -/*! Minimum timeout value. Chosen due to it being approximately RTT half-way - * around the world */ -#define MIN_TIMEOUT_MS 250 - -/*! Multiplier to apply to average latency to come up with an initial timeout */ -#define AVG_TIMEOUT_MULTIPLIER 5 - -/*! Upper timeout bounds, only used if channel->maxtimeout not set */ -#define MAX_TIMEOUT_MS 5000 - -/*! Minimum queries required to form an average */ -#define MIN_COUNT_FOR_AVERAGE 3 - -static time_t ares_metric_timestamp(ares_server_bucket_t bucket, - const ares_timeval_t *now, - ares_bool_t is_previous) -{ - time_t divisor = 1; /* Silence bogus MSVC warning by setting default value */ - - switch (bucket) { - case ARES_METRIC_1MINUTE: - divisor = 60; - break; - case ARES_METRIC_15MINUTES: - divisor = 15 * 60; - break; - case ARES_METRIC_1HOUR: - divisor = 60 * 60; - break; - case ARES_METRIC_1DAY: - divisor = 24 * 60 * 60; - break; - case ARES_METRIC_INCEPTION: - return is_previous ? 0 : 1; - case ARES_METRIC_COUNT: - return 0; /* Invalid! */ - } - - if (is_previous) { - if (divisor >= now->sec) { - return 0; - } - return (time_t)((now->sec - divisor) / divisor); - } - - return (time_t)(now->sec / divisor); -} - -void ares_metrics_record(const ares_query_t *query, ares_server_t *server, - ares_status_t status, const ares_dns_record_t *dnsrec) -{ - ares_timeval_t now; - ares_timeval_t tvdiff; - unsigned int query_ms; - ares_dns_rcode_t rcode; - ares_server_bucket_t i; - - if (status != ARES_SUCCESS) { - return; - } - - if (server == NULL) { - return; - } - - ares_tvnow(&now); - - rcode = ares_dns_record_get_rcode(dnsrec); - if (rcode != ARES_RCODE_NOERROR && rcode != ARES_RCODE_NXDOMAIN) { - return; - } - - ares_timeval_diff(&tvdiff, &query->ts, &now); - query_ms = (unsigned int)((tvdiff.sec * 1000) + (tvdiff.usec / 1000)); - if (query_ms == 0) { - query_ms = 1; - } - - /* Place in each bucket */ - for (i = 0; i < ARES_METRIC_COUNT; i++) { - time_t ts = ares_metric_timestamp(i, &now, ARES_FALSE); - - /* Copy metrics to prev and clear */ - if (ts != server->metrics[i].ts) { - server->metrics[i].prev_ts = server->metrics[i].ts; - server->metrics[i].prev_total_ms = server->metrics[i].total_ms; - server->metrics[i].prev_total_count = server->metrics[i].total_count; - server->metrics[i].ts = ts; - server->metrics[i].latency_min_ms = 0; - server->metrics[i].latency_max_ms = 0; - server->metrics[i].total_ms = 0; - server->metrics[i].total_count = 0; - } - - if (server->metrics[i].latency_min_ms == 0 || - server->metrics[i].latency_min_ms > query_ms) { - server->metrics[i].latency_min_ms = query_ms; - } - - if (query_ms > server->metrics[i].latency_max_ms) { - server->metrics[i].latency_max_ms = query_ms; - } - - server->metrics[i].total_count++; - server->metrics[i].total_ms += (ares_uint64_t)query_ms; - } -} - -size_t ares_metrics_server_timeout(const ares_server_t *server, - const ares_timeval_t *now) -{ - const ares_channel_t *channel = server->channel; - ares_server_bucket_t i; - size_t timeout_ms = 0; - size_t max_timeout_ms; - - for (i = 0; i < ARES_METRIC_COUNT; i++) { - time_t ts = ares_metric_timestamp(i, now, ARES_FALSE); - - /* This ts has been invalidated, see if we should use the previous - * time period */ - if (ts != server->metrics[i].ts || - server->metrics[i].total_count < MIN_COUNT_FOR_AVERAGE) { - time_t prev_ts = ares_metric_timestamp(i, now, ARES_TRUE); - if (prev_ts != server->metrics[i].prev_ts || - server->metrics[i].prev_total_count < MIN_COUNT_FOR_AVERAGE) { - /* Move onto next bucket */ - continue; - } - /* Calculate average time for previous bucket */ - timeout_ms = (size_t)(server->metrics[i].prev_total_ms / - server->metrics[i].prev_total_count); - } else { - /* Calculate average time for current bucket*/ - timeout_ms = - (size_t)(server->metrics[i].total_ms / server->metrics[i].total_count); - } - - /* Multiply average by constant to get timeout value */ - timeout_ms *= AVG_TIMEOUT_MULTIPLIER; - break; - } - - /* If we're here, that means its the first query for the server, so we just - * use the initial default timeout */ - if (timeout_ms == 0) { - timeout_ms = channel->timeout; - } - - /* don't go below lower bounds */ - if (timeout_ms < MIN_TIMEOUT_MS) { - timeout_ms = MIN_TIMEOUT_MS; - } - - /* don't go above upper bounds */ - max_timeout_ms = channel->maxtimeout ? channel->maxtimeout : MAX_TIMEOUT_MS; - if (timeout_ms > max_timeout_ms) { - timeout_ms = max_timeout_ms; - } - - return timeout_ms; -} diff --git a/vendor/c-ares/src/lib/ares_options.c b/vendor/c-ares/src/lib/ares_options.c deleted file mode 100644 index 3082f3324..000000000 --- a/vendor/c-ares/src/lib/ares_options.c +++ /dev/null @@ -1,492 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2008 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_data.h" -#include "ares_inet_net_pton.h" - -void ares_destroy_options(struct ares_options *options) -{ - int i; - - ares_free(options->servers); - - for (i = 0; options->domains && i < options->ndomains; i++) { - ares_free(options->domains[i]); - } - - ares_free(options->domains); - ares_free(options->sortlist); - ares_free(options->lookups); - ares_free(options->resolvconf_path); - ares_free(options->hosts_path); -} - -static struct in_addr *ares_save_opt_servers(const ares_channel_t *channel, - int *nservers) -{ - ares_slist_node_t *snode; - struct in_addr *out = - ares_malloc_zero(ares_slist_len(channel->servers) * sizeof(*out)); - - *nservers = 0; - - if (out == NULL) { - return NULL; - } - - for (snode = ares_slist_node_first(channel->servers); snode != NULL; - snode = ares_slist_node_next(snode)) { - const ares_server_t *server = ares_slist_node_val(snode); - - if (server->addr.family != AF_INET) { - continue; - } - - memcpy(&out[*nservers], &server->addr.addr.addr4, sizeof(*out)); - (*nservers)++; - } - - return out; -} - -/* Save options from initialized channel */ -int ares_save_options(const ares_channel_t *channel, - struct ares_options *options, int *optmask) -{ - size_t i; - - /* NOTE: We can't zero the whole thing out, this is because the size of the - * struct ares_options changes over time, so if someone compiled - * with an older version, their struct size might be smaller and - * we might overwrite their memory! So using the optmask is critical - * here, as they could have only set options they knew about. - * - * Unfortunately ares_destroy_options() doesn't take an optmask, so - * there are a few pointers we *must* zero out otherwise we won't - * know if they were allocated or not - */ - options->servers = NULL; - options->domains = NULL; - options->sortlist = NULL; - options->lookups = NULL; - options->resolvconf_path = NULL; - options->hosts_path = NULL; - - if (!ARES_CONFIG_CHECK(channel)) { - return ARES_ENODATA; - } - - if (channel->optmask & ARES_OPT_FLAGS) { - options->flags = (int)channel->flags; - } - - /* We convert ARES_OPT_TIMEOUT to ARES_OPT_TIMEOUTMS in - * ares_init_by_options() */ - if (channel->optmask & ARES_OPT_TIMEOUTMS) { - options->timeout = (int)channel->timeout; - } - - if (channel->optmask & ARES_OPT_TRIES) { - options->tries = (int)channel->tries; - } - - if (channel->optmask & ARES_OPT_NDOTS) { - options->ndots = (int)channel->ndots; - } - - if (channel->optmask & ARES_OPT_MAXTIMEOUTMS) { - options->maxtimeout = (int)channel->maxtimeout; - } - - if (channel->optmask & ARES_OPT_UDP_PORT) { - options->udp_port = channel->udp_port; - } - if (channel->optmask & ARES_OPT_TCP_PORT) { - options->tcp_port = channel->tcp_port; - } - - if (channel->optmask & ARES_OPT_SOCK_STATE_CB) { - options->sock_state_cb = channel->sock_state_cb; - options->sock_state_cb_data = channel->sock_state_cb_data; - } - - if (channel->optmask & ARES_OPT_SERVERS) { - options->servers = ares_save_opt_servers(channel, &options->nservers); - if (options->servers == NULL) { - return ARES_ENOMEM; - } - } - - if (channel->optmask & ARES_OPT_DOMAINS) { - options->domains = NULL; - if (channel->ndomains) { - options->domains = ares_malloc(channel->ndomains * sizeof(char *)); - if (!options->domains) { - return ARES_ENOMEM; - } - - for (i = 0; i < channel->ndomains; i++) { - options->domains[i] = ares_strdup(channel->domains[i]); - if (!options->domains[i]) { - options->ndomains = (int)i; - return ARES_ENOMEM; - } - } - } - options->ndomains = (int)channel->ndomains; - } - - if (channel->optmask & ARES_OPT_LOOKUPS) { - options->lookups = ares_strdup(channel->lookups); - if (!options->lookups && channel->lookups) { - return ARES_ENOMEM; - } - } - - if (channel->optmask & ARES_OPT_SORTLIST) { - options->sortlist = NULL; - if (channel->nsort) { - options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern)); - if (!options->sortlist) { - return ARES_ENOMEM; - } - for (i = 0; i < channel->nsort; i++) { - options->sortlist[i] = channel->sortlist[i]; - } - } - options->nsort = (int)channel->nsort; - } - - if (channel->optmask & ARES_OPT_RESOLVCONF) { - options->resolvconf_path = ares_strdup(channel->resolvconf_path); - if (!options->resolvconf_path) { - return ARES_ENOMEM; - } - } - - if (channel->optmask & ARES_OPT_HOSTS_FILE) { - options->hosts_path = ares_strdup(channel->hosts_path); - if (!options->hosts_path) { - return ARES_ENOMEM; - } - } - - if (channel->optmask & ARES_OPT_SOCK_SNDBUF && - channel->socket_send_buffer_size > 0) { - options->socket_send_buffer_size = channel->socket_send_buffer_size; - } - - if (channel->optmask & ARES_OPT_SOCK_RCVBUF && - channel->socket_receive_buffer_size > 0) { - options->socket_receive_buffer_size = channel->socket_receive_buffer_size; - } - - if (channel->optmask & ARES_OPT_EDNSPSZ) { - options->ednspsz = (int)channel->ednspsz; - } - - if (channel->optmask & ARES_OPT_UDP_MAX_QUERIES) { - options->udp_max_queries = (int)channel->udp_max_queries; - } - - if (channel->optmask & ARES_OPT_QUERY_CACHE) { - options->qcache_max_ttl = channel->qcache_max_ttl; - } - - if (channel->optmask & ARES_OPT_EVENT_THREAD) { - options->evsys = channel->evsys; - } - - /* Set options for server failover behavior */ - if (channel->optmask & ARES_OPT_SERVER_FAILOVER) { - options->server_failover_opts.retry_chance = channel->server_retry_chance; - options->server_failover_opts.retry_delay = channel->server_retry_delay; - } - - *optmask = (int)channel->optmask; - - return ARES_SUCCESS; -} - -static ares_status_t ares_init_options_servers(ares_channel_t *channel, - const struct in_addr *servers, - size_t nservers) -{ - ares_llist_t *slist = NULL; - ares_status_t status; - - status = ares_in_addr_to_sconfig_llist(servers, nservers, &slist); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_servers_update(channel, slist, ARES_TRUE); - - ares_llist_destroy(slist); - - return status; -} - -ares_status_t ares_init_by_options(ares_channel_t *channel, - const struct ares_options *options, - int optmask) -{ - size_t i; - - if (channel == NULL) { - return ARES_ENODATA; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (options == NULL) { - if (optmask != 0) { - return ARES_ENODATA; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - return ARES_SUCCESS; - } - - /* Easy stuff. */ - - /* Event Thread requires threading support and is incompatible with socket - * state callbacks */ - if (optmask & ARES_OPT_EVENT_THREAD) { - if (!ares_threadsafety()) { - return ARES_ENOTIMP; - } - if (optmask & ARES_OPT_SOCK_STATE_CB) { - return ARES_EFORMERR; - } - channel->evsys = options->evsys; - } - - if (optmask & ARES_OPT_FLAGS) { - channel->flags = (unsigned int)options->flags; - } - - if (optmask & ARES_OPT_TIMEOUTMS) { - /* Apparently some integrations were passing -1 to tell c-ares to use - * the default instead of just omitting the optmask */ - if (options->timeout <= 0) { - optmask &= ~(ARES_OPT_TIMEOUTMS); - } else { - channel->timeout = (unsigned int)options->timeout; - } - } else if (optmask & ARES_OPT_TIMEOUT) { - optmask &= ~(ARES_OPT_TIMEOUT); - /* Apparently some integrations were passing -1 to tell c-ares to use - * the default instead of just omitting the optmask */ - if (options->timeout > 0) { - /* Convert to milliseconds */ - optmask |= ARES_OPT_TIMEOUTMS; - channel->timeout = (unsigned int)options->timeout * 1000; - } - } - - if (optmask & ARES_OPT_TRIES) { - if (options->tries <= 0) { - optmask &= ~(ARES_OPT_TRIES); - } else { - channel->tries = (size_t)options->tries; - } - } - - if (optmask & ARES_OPT_NDOTS) { - if (options->ndots < 0) { - optmask &= ~(ARES_OPT_NDOTS); - } else { - channel->ndots = (size_t)options->ndots; - } - } - - if (optmask & ARES_OPT_MAXTIMEOUTMS) { - if (options->maxtimeout <= 0) { - optmask &= ~(ARES_OPT_MAXTIMEOUTMS); - } else { - channel->maxtimeout = (size_t)options->maxtimeout; - } - } - - if (optmask & ARES_OPT_ROTATE) { - channel->rotate = ARES_TRUE; - } - - if (optmask & ARES_OPT_NOROTATE) { - channel->rotate = ARES_FALSE; - } - - if (optmask & ARES_OPT_UDP_PORT) { - channel->udp_port = options->udp_port; - } - - if (optmask & ARES_OPT_TCP_PORT) { - channel->tcp_port = options->tcp_port; - } - - if (optmask & ARES_OPT_SOCK_STATE_CB) { - channel->sock_state_cb = options->sock_state_cb; - channel->sock_state_cb_data = options->sock_state_cb_data; - } - - if (optmask & ARES_OPT_SOCK_SNDBUF) { - if (options->socket_send_buffer_size <= 0) { - optmask &= ~(ARES_OPT_SOCK_SNDBUF); - } else { - channel->socket_send_buffer_size = options->socket_send_buffer_size; - } - } - - if (optmask & ARES_OPT_SOCK_RCVBUF) { - if (options->socket_receive_buffer_size <= 0) { - optmask &= ~(ARES_OPT_SOCK_RCVBUF); - } else { - channel->socket_receive_buffer_size = options->socket_receive_buffer_size; - } - } - - if (optmask & ARES_OPT_EDNSPSZ) { - if (options->ednspsz <= 0) { - optmask &= ~(ARES_OPT_EDNSPSZ); - } else { - channel->ednspsz = (size_t)options->ednspsz; - } - } - - /* Copy the domains, if given. Keep channel->ndomains consistent so - * we can clean up in case of error. - */ - if (optmask & ARES_OPT_DOMAINS && options->ndomains > 0) { - channel->domains = - ares_malloc_zero((size_t)options->ndomains * sizeof(char *)); - if (!channel->domains) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - channel->ndomains = (size_t)options->ndomains; - for (i = 0; i < (size_t)options->ndomains; i++) { - channel->domains[i] = ares_strdup(options->domains[i]); - if (!channel->domains[i]) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - /* Set lookups, if given. */ - if (optmask & ARES_OPT_LOOKUPS) { - if (options->lookups == NULL) { - optmask &= ~(ARES_OPT_LOOKUPS); - } else { - channel->lookups = ares_strdup(options->lookups); - if (!channel->lookups) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - /* copy sortlist */ - if (optmask & ARES_OPT_SORTLIST && options->nsort > 0) { - channel->nsort = (size_t)options->nsort; - channel->sortlist = - ares_malloc((size_t)options->nsort * sizeof(struct apattern)); - if (!channel->sortlist) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - for (i = 0; i < (size_t)options->nsort; i++) { - channel->sortlist[i] = options->sortlist[i]; - } - } - - /* Set path for resolv.conf file, if given. */ - if (optmask & ARES_OPT_RESOLVCONF) { - if (options->resolvconf_path == NULL) { - optmask &= ~(ARES_OPT_RESOLVCONF); - } else { - channel->resolvconf_path = ares_strdup(options->resolvconf_path); - if (channel->resolvconf_path == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - /* Set path for hosts file, if given. */ - if (optmask & ARES_OPT_HOSTS_FILE) { - if (options->hosts_path == NULL) { - optmask &= ~(ARES_OPT_HOSTS_FILE); - } else { - channel->hosts_path = ares_strdup(options->hosts_path); - if (channel->hosts_path == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - if (optmask & ARES_OPT_UDP_MAX_QUERIES) { - if (options->udp_max_queries <= 0) { - optmask &= ~(ARES_OPT_UDP_MAX_QUERIES); - } else { - channel->udp_max_queries = (size_t)options->udp_max_queries; - } - } - - /* As of c-ares 1.31.0, the Query Cache is on by default. The only way to - * disable it is to set options->qcache_max_ttl = 0 while specifying the - * ARES_OPT_QUERY_CACHE which will actually disable it completely. */ - if (optmask & ARES_OPT_QUERY_CACHE) { - /* qcache_max_ttl is unsigned unlike the others */ - channel->qcache_max_ttl = options->qcache_max_ttl; - } else { - optmask |= ARES_OPT_QUERY_CACHE; - channel->qcache_max_ttl = 3600; - } - - /* Initialize the ipv4 servers if provided */ - if (optmask & ARES_OPT_SERVERS) { - if (options->nservers <= 0) { - optmask &= ~(ARES_OPT_SERVERS); - } else { - ares_status_t status; - status = ares_init_options_servers(channel, options->servers, - (size_t)options->nservers); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - /* Set fields for server failover behavior */ - if (optmask & ARES_OPT_SERVER_FAILOVER) { - channel->server_retry_chance = options->server_failover_opts.retry_chance; - channel->server_retry_delay = options->server_failover_opts.retry_delay; - } - - channel->optmask = (unsigned int)optmask; - - return ARES_SUCCESS; -} diff --git a/vendor/c-ares/src/lib/ares_parse_into_addrinfo.c b/vendor/c-ares/src/lib/ares_parse_into_addrinfo.c deleted file mode 100644 index 2108f9b86..000000000 --- a/vendor/c-ares/src/lib/ares_parse_into_addrinfo.c +++ /dev/null @@ -1,179 +0,0 @@ -/* MIT License - * - * Copyright (c) 2019 Andrew Selivanov - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - - -ares_status_t ares_parse_into_addrinfo(const ares_dns_record_t *dnsrec, - ares_bool_t cname_only_is_enodata, - unsigned short port, - struct ares_addrinfo *ai) -{ - ares_status_t status; - size_t i; - size_t ancount; - const char *hostname = NULL; - ares_bool_t got_a = ARES_FALSE; - ares_bool_t got_aaaa = ARES_FALSE; - ares_bool_t got_cname = ARES_FALSE; - struct ares_addrinfo_cname *cnames = NULL; - struct ares_addrinfo_node *nodes = NULL; - - /* Save question hostname */ - status = ares_dns_record_query_get(dnsrec, 0, &hostname, NULL, NULL); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - if (ancount == 0) { - status = ARES_ENODATA; - goto done; - } - - for (i = 0; i < ancount; i++) { - ares_dns_rec_type_t rtype; - const ares_dns_rr_t *rr = - ares_dns_record_rr_get_const(dnsrec, ARES_SECTION_ANSWER, i); - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN) { - continue; - } - - rtype = ares_dns_rr_get_type(rr); - - /* Issue #683 - * Old code did this hostname sanity check, however it appears this is - * flawed logic. Other resolvers don't do this sanity check. Leaving - * this code commented out for future reference. - * - * rname = ares_dns_rr_get_name(rr); - * if ((rtype == ARES_REC_TYPE_A || rtype == ARES_REC_TYPE_AAAA) && - * !ares_strcaseeq(rname, hostname)) { - * continue; - * } - */ - - if (rtype == ARES_REC_TYPE_CNAME) { - struct ares_addrinfo_cname *cname; - - got_cname = ARES_TRUE; - /* replace hostname with data from cname - * SA: Seems wrong as it introduces order dependency. */ - hostname = ares_dns_rr_get_str(rr, ARES_RR_CNAME_CNAME); - - cname = ares_append_addrinfo_cname(&cnames); - if (cname == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - cname->ttl = (int)ares_dns_rr_get_ttl(rr); - cname->alias = ares_strdup(ares_dns_rr_get_name(rr)); - if (cname->alias == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - cname->name = ares_strdup(hostname); - if (cname->name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } else if (rtype == ARES_REC_TYPE_A) { - got_a = ARES_TRUE; - status = - ares_append_ai_node(AF_INET, port, ares_dns_rr_get_ttl(rr), - ares_dns_rr_get_addr(rr, ARES_RR_A_ADDR), &nodes); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } else if (rtype == ARES_REC_TYPE_AAAA) { - got_aaaa = ARES_TRUE; - status = ares_append_ai_node(AF_INET6, port, ares_dns_rr_get_ttl(rr), - ares_dns_rr_get_addr6(rr, ARES_RR_AAAA_ADDR), - &nodes); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } else { - continue; - } - } - - if (!got_a && !got_aaaa && - (!got_cname || (got_cname && cname_only_is_enodata))) { - status = ARES_ENODATA; - goto done; - } - - /* save the hostname as ai->name */ - if (ai->name == NULL || !ares_strcaseeq(ai->name, hostname)) { - ares_free(ai->name); - ai->name = ares_strdup(hostname); - if (ai->name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - if (got_a || got_aaaa) { - ares_addrinfo_cat_nodes(&ai->nodes, nodes); - nodes = NULL; - } - - if (got_cname) { - ares_addrinfo_cat_cnames(&ai->cnames, cnames); - cnames = NULL; - } - -done: - ares_freeaddrinfo_cnames(cnames); - ares_freeaddrinfo_nodes(nodes); - - /* compatibility */ - if (status == ARES_EBADNAME) { - status = ARES_EBADRESP; - } - - return status; -} diff --git a/vendor/c-ares/src/lib/ares_private.h b/vendor/c-ares/src/lib/ares_private.h deleted file mode 100644 index 3d7cea3d3..000000000 --- a/vendor/c-ares/src/lib/ares_private.h +++ /dev/null @@ -1,639 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2010 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_PRIVATE_H -#define __ARES_PRIVATE_H - -/* ============================================================================ - * NOTE: All c-ares source files should include ares_private.h as the first - * header. - * ============================================================================ - */ - -#include "ares_setup.h" -#include "ares.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#include "ares_mem.h" -#include "ares_ipv6.h" -#include "util/ares_math.h" -#include "util/ares_time.h" -#include "util/ares_rand.h" -#include "ares_array.h" -#include "ares_llist.h" -#include "dsa/ares_slist.h" -#include "ares_htable_strvp.h" -#include "ares_htable_szvp.h" -#include "ares_htable_asvp.h" -#include "ares_htable_dict.h" -#include "ares_htable_vpvp.h" -#include "ares_htable_vpstr.h" -#include "record/ares_dns_multistring.h" -#include "ares_buf.h" -#include "record/ares_dns_private.h" -#include "util/ares_iface_ips.h" -#include "util/ares_threads.h" -#include "ares_socket.h" -#include "ares_conn.h" -#include "ares_str.h" -#include "str/ares_strsplit.h" -#include "util/ares_uri.h" - -#ifndef HAVE_GETENV -# include "ares_getenv.h" -# define getenv(ptr) ares_getenv(ptr) -#endif - -#define DEFAULT_TIMEOUT 2000 /* milliseconds */ -#define DEFAULT_TRIES 3 -#ifndef INADDR_NONE -# define INADDR_NONE 0xffffffff -#endif - -/* By using a double cast, we can get rid of the bogus warning of - * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' - * increases required alignment from 1 to 4 [-Wcast-align] - */ -#define CARES_INADDR_CAST(type, var) ((type)((const void *)var)) - -#if defined(USE_WINSOCK) - -# define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" -# define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" -# define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient" -# define WIN_NT_DNSCLIENT \ - "Software\\Policies\\Microsoft\\Windows NT\\DNSClient" -# define NAMESERVER "NameServer" -# define DHCPNAMESERVER "DhcpNameServer" -# define DATABASEPATH "DatabasePath" -# define WIN_PATH_HOSTS "\\hosts" -# define SEARCHLIST_KEY "SearchList" -# define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix" -# define INTERFACES_KEY "Interfaces" -# define DOMAIN_KEY "Domain" -# define DHCPDOMAIN_KEY "DhcpDomain" -# define PATH_RESOLV_CONF "" -#elif defined(WATT32) - -# define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf" -W32_FUNC const char *_w32_GetHostsFile(void); - -#elif defined(NETWARE) - -# define PATH_RESOLV_CONF "sys:/etc/resolv.cfg" -# define PATH_HOSTS "sys:/etc/hosts" - -#elif defined(__riscos__) - -# define PATH_RESOLV_CONF "" -# define PATH_HOSTS "InetDBase:Hosts" - -#elif defined(__HAIKU__) - -# define PATH_RESOLV_CONF "/system/settings/network/resolv.conf" -# define PATH_HOSTS "/system/settings/network/hosts" - -#else - -# define PATH_RESOLV_CONF "/etc/resolv.conf" -# ifdef ETC_INET -# define PATH_HOSTS "/etc/inet/hosts" -# else -# define PATH_HOSTS "/etc/hosts" -# endif - -#endif - -/********* EDNS defines section ******/ -#define EDNSPACKETSZ \ - 1232 /* Reasonable UDP payload size, as agreed by operators \ - https://www.dnsflagday.net/2020/#faq */ -#define MAXENDSSZ 4096 /* Maximum (local) limit for edns packet size */ -#define EDNSFIXEDSZ 11 /* Size of EDNS header */ - -/********* EDNS defines section ******/ - -/* Default values for server failover behavior. We retry failed servers with - * a 10% probability and a minimum delay of 5 seconds between retries. - */ -#define DEFAULT_SERVER_RETRY_CHANCE 10 -#define DEFAULT_SERVER_RETRY_DELAY 5000 - -struct ares_query; -typedef struct ares_query ares_query_t; - -/* State to represent a DNS query */ -struct ares_query { - /* Query ID from qbuf, for faster lookup, and current timeout */ - unsigned short qid; /* host byte order */ - ares_timeval_t ts; /*!< Timestamp query was sent */ - ares_timeval_t timeout; - ares_channel_t *channel; - - /* - * Node object for each list entry the query belongs to in order to - * make removal operations O(1). - */ - ares_slist_node_t *node_queries_by_timeout; - ares_llist_node_t *node_queries_to_conn; - ares_llist_node_t *node_all_queries; - - /* connection handle query is associated with */ - ares_conn_t *conn; - - /* Query */ - ares_dns_record_t *query; - - ares_callback_dnsrec callback; - void *arg; - - /* Query status */ - size_t try_count; /* Number of times we tried this query already. */ - size_t cookie_try_count; /* Attempt count for cookie resends */ - ares_bool_t using_tcp; - ares_status_t error_status; - size_t timeouts; /* number of timeouts we saw for this request */ - ares_bool_t no_retries; /* do not perform any additional retries, this is - * set when a query is to be canceled */ -}; - -struct apattern { - struct ares_addr addr; - unsigned char mask; -}; - -struct ares_qcache; -typedef struct ares_qcache ares_qcache_t; - -struct ares_hosts_file; -typedef struct ares_hosts_file ares_hosts_file_t; - -struct ares_channeldata { - /* Configuration data */ - unsigned int flags; - size_t timeout; /* in milliseconds */ - size_t tries; - size_t ndots; - size_t maxtimeout; /* in milliseconds */ - ares_bool_t rotate; - unsigned short udp_port; /* stored in network order */ - unsigned short tcp_port; /* stored in network order */ - int socket_send_buffer_size; /* setsockopt takes int */ - int socket_receive_buffer_size; /* setsockopt takes int */ - char **domains; - size_t ndomains; - struct apattern *sortlist; - size_t nsort; - char *lookups; - size_t ednspsz; - unsigned int qcache_max_ttl; - ares_evsys_t evsys; - unsigned int optmask; - - /* For binding to local devices and/or IP addresses. Leave - * them null/zero for no binding. - */ - char local_dev_name[32]; - unsigned int local_ip4; - unsigned char local_ip6[16]; - - /* Thread safety lock */ - ares_thread_mutex_t *lock; - - /* Conditional to wake waiters when queue is empty */ - ares_thread_cond_t *cond_empty; - - /* Server addresses and communications state. Sorted by least consecutive - * failures, followed by the configuration order if failures are equal. */ - ares_slist_t *servers; - - /* random state to use when generating new ids and generating retry penalties - */ - ares_rand_state *rand_state; - - /* All active queries in a single list */ - ares_llist_t *all_queries; - /* Queries bucketed by qid, for quickly dispatching DNS responses: */ - ares_htable_szvp_t *queries_by_qid; - - /* Queries bucketed by timeout, for quickly handling timeouts: */ - ares_slist_t *queries_by_timeout; - - /* Map linked list node member for connection to file descriptor. We use - * the node instead of the connection object itself so we can quickly look - * up a connection and remove it if necessary (as otherwise we'd have to - * scan all connections) */ - ares_htable_asvp_t *connnode_by_socket; - - ares_sock_state_cb sock_state_cb; - void *sock_state_cb_data; - - ares_sock_create_callback sock_create_cb; - void *sock_create_cb_data; - - ares_sock_config_callback sock_config_cb; - void *sock_config_cb_data; - - struct ares_socket_functions_ex sock_funcs; - void *sock_func_cb_data; - const struct ares_socket_functions *legacy_sock_funcs; - void *legacy_sock_funcs_cb_data; - - ares_pending_write_cb notify_pending_write_cb; - void *notify_pending_write_cb_data; - ares_bool_t notify_pending_write; - - /* Path for resolv.conf file, configurable via ares_options */ - char *resolvconf_path; - - /* Path for hosts file, configurable via ares_options */ - char *hosts_path; - - /* Maximum UDP queries per connection allowed */ - size_t udp_max_queries; - - /* Cache of local hosts file */ - ares_hosts_file_t *hf; - - /* Query Cache */ - ares_qcache_t *qcache; - - /* Fields controlling server failover behavior. - * The retry chance is the probability (1/N) by which we will retry a failed - * server instead of the best server when selecting a server to send queries - * to. - * The retry delay is the minimum time in milliseconds to wait between doing - * such retries (applied per-server). - */ - unsigned short server_retry_chance; - size_t server_retry_delay; - - /* Callback triggered when a server has a successful or failed response */ - ares_server_state_callback server_state_cb; - void *server_state_cb_data; - - /* TRUE if a reinit is pending. Reinit spawns a thread to read the system - * configuration and then apply the configuration since configuration - * reading may block. The thread handle is provided for waiting on thread - * exit. */ - ares_bool_t reinit_pending; - ares_thread_t *reinit_thread; - - /* Whether the system is up or not. This is mainly to prevent deadlocks - * and access violations during the cleanup process. Some things like - * system config changes might get triggered and we need a flag to make - * sure we don't take action. */ - ares_bool_t sys_up; -}; - -/* Does the domain end in ".onion" or ".onion."? Case-insensitive. */ -ares_bool_t ares_is_onion_domain(const char *name); - -/* Returns one of the normal ares status codes like ARES_SUCCESS */ -ares_status_t ares_send_query(ares_server_t *requested_server /* Optional */, - ares_query_t *query, const ares_timeval_t *now); -ares_status_t ares_requeue_query(ares_query_t *query, const ares_timeval_t *now, - ares_status_t status, - ares_bool_t inc_try_count, - const ares_dns_record_t *dnsrec, - ares_array_t **requeue); - -/*! Count the number of labels (dots+1) in a domain */ -size_t ares_name_label_cnt(const char *name); - -/*! Retrieve a list of names to use for searching. The first successful - * query in the list wins. This function also uses the HOSTSALIASES file - * as well as uses channel configuration to determine the search order. - * - * \param[in] channel initialized ares channel - * \param[in] name initial name being searched - * \param[out] names array of names to attempt, use ares_strsplit_free() - * when no longer needed. - * \param[out] names_len number of names in array - * \return ARES_SUCCESS on success, otherwise one of the other error codes. - */ -ares_status_t ares_search_name_list(const ares_channel_t *channel, - const char *name, char ***names, - size_t *names_len); - -/*! Function to create callback arg for converting from ares_callback_dnsrec - * to ares_calback */ -void *ares_dnsrec_convert_arg(ares_callback callback, void *arg); - -/*! Callback function used to convert from the ares_callback_dnsrec prototype to - * the ares_callback prototype, by writing the result and passing that to - * the inner callback. - */ -void ares_dnsrec_convert_cb(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec); - -void ares_free_query(ares_query_t *query); - -unsigned short ares_generate_new_id(ares_rand_state *state); -ares_status_t ares_expand_name_validated(const unsigned char *encoded, - const unsigned char *abuf, size_t alen, - char **s, size_t *enclen, - ares_bool_t is_hostname); -ares_status_t ares_expand_string_ex(const unsigned char *encoded, - const unsigned char *abuf, size_t alen, - unsigned char **s, size_t *enclen); -ares_status_t ares_init_servers_state(ares_channel_t *channel); -ares_status_t ares_init_by_options(ares_channel_t *channel, - const struct ares_options *options, - int optmask); -ares_status_t ares_init_by_sysconfig(ares_channel_t *channel); -void ares_set_socket_functions_def(ares_channel_t *channel); - -typedef struct { - ares_llist_t *sconfig; - struct apattern *sortlist; - size_t nsortlist; - char **domains; - size_t ndomains; - char *lookups; - size_t ndots; - size_t tries; - ares_bool_t rotate; - size_t timeout_ms; - ares_bool_t usevc; -} ares_sysconfig_t; - -ares_status_t ares_sysconfig_set_options(ares_sysconfig_t *sysconfig, - const char *str); - -ares_status_t ares_init_by_environment(ares_sysconfig_t *sysconfig); - - -typedef ares_status_t (*ares_sysconfig_line_cb_t)(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_buf_t *line); - -ares_status_t ares_sysconfig_parse_resolv_line(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_buf_t *line); - -ares_status_t ares_sysconfig_process_buf(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_buf_t *buf, - ares_sysconfig_line_cb_t cb); - -ares_status_t ares_init_sysconfig_files(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_bool_t process_resolvconf); -#ifdef __APPLE__ -ares_status_t ares_init_sysconfig_macos(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig); -#endif -#ifdef USE_WINSOCK -ares_status_t ares_init_sysconfig_windows(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig); -#endif - -ares_status_t ares_parse_sortlist(struct apattern **sortlist, size_t *nsort, - const char *str); - -/* Returns ARES_SUCCESS if alias found, alias is set. Returns ARES_ENOTFOUND - * if not alias found. Returns other errors on critical failure like - * ARES_ENOMEM */ -ares_status_t ares_lookup_hostaliases(const ares_channel_t *channel, - const char *name, char **alias); - -ares_status_t ares_cat_domain(const char *name, const char *domain, char **s); -ares_status_t ares_sortaddrinfo(ares_channel_t *channel, - struct ares_addrinfo_node *ai_node); - -void ares_freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node); -ares_bool_t ares_is_localhost(const char *name); - -struct ares_addrinfo_node * - ares_append_addrinfo_node(struct ares_addrinfo_node **ai_node); -void ares_addrinfo_cat_nodes(struct ares_addrinfo_node **head, - struct ares_addrinfo_node *tail); - -void ares_freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname); - -struct ares_addrinfo_cname * - ares_append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname); - -ares_status_t ares_append_ai_node(int aftype, unsigned short port, - unsigned int ttl, const void *adata, - struct ares_addrinfo_node **nodes); - -void ares_addrinfo_cat_cnames(struct ares_addrinfo_cname **head, - struct ares_addrinfo_cname *tail); - -ares_status_t ares_parse_into_addrinfo(const ares_dns_record_t *dnsrec, - ares_bool_t cname_only_is_enodata, - unsigned short port, - struct ares_addrinfo *ai); -ares_status_t ares_parse_ptr_reply_dnsrec(const ares_dns_record_t *dnsrec, - const void *addr, int addrlen, - int family, struct hostent **host); - -/* host address must be valid or NULL as will create or append */ -ares_status_t ares_addrinfo2hostent(const struct ares_addrinfo *ai, int family, - struct hostent **host); - -ares_status_t ares_addrinfo2addrttl(const struct ares_addrinfo *ai, int family, - size_t req_naddrttls, - struct ares_addrttl *addrttls, - struct ares_addr6ttl *addr6ttls, - size_t *naddrttls); -ares_status_t ares_addrinfo_localhost(const char *name, unsigned short port, - const struct ares_addrinfo_hints *hints, - struct ares_addrinfo *ai); - -ares_status_t ares_servers_update(ares_channel_t *channel, - ares_llist_t *server_list, - ares_bool_t user_specified); -ares_status_t - ares_sconfig_append(const ares_channel_t *channel, ares_llist_t **sconfig, - const struct ares_addr *addr, unsigned short udp_port, - unsigned short tcp_port, const char *ll_iface); -ares_status_t ares_sconfig_append_fromstr(const ares_channel_t *channel, - ares_llist_t **sconfig, - const char *str, - ares_bool_t ignore_invalid); -ares_status_t ares_in_addr_to_sconfig_llist(const struct in_addr *servers, - size_t nservers, - ares_llist_t **llist); -ares_status_t ares_get_server_addr(const ares_server_t *server, - ares_buf_t *buf); - -struct ares_hosts_entry; -typedef struct ares_hosts_entry ares_hosts_entry_t; - -void ares_hosts_file_destroy(ares_hosts_file_t *hf); -ares_status_t ares_hosts_search_ipaddr(ares_channel_t *channel, - ares_bool_t use_env, const char *ipaddr, - const ares_hosts_entry_t **entry); -ares_status_t ares_hosts_search_host(ares_channel_t *channel, - ares_bool_t use_env, const char *host, - const ares_hosts_entry_t **entry); -ares_status_t ares_hosts_entry_to_hostent(const ares_hosts_entry_t *entry, - int family, struct hostent **hostent); -ares_status_t ares_hosts_entry_to_addrinfo(const ares_hosts_entry_t *entry, - const char *name, int family, - unsigned short port, - ares_bool_t want_cnames, - struct ares_addrinfo *ai); - -/* Same as ares_query_dnsrec() except does not take a channel lock. Use this - * if a channel lock is already held */ -ares_status_t ares_query_nolock(ares_channel_t *channel, const char *name, - ares_dns_class_t dnsclass, - ares_dns_rec_type_t type, - ares_callback_dnsrec callback, void *arg, - unsigned short *qid); - -/*! Flags controlling behavior for ares_send_nolock() */ -typedef enum { - ARES_SEND_FLAG_NOCACHE = 1 << 0, /*!< Do not query the cache */ - ARES_SEND_FLAG_NORETRY = 1 << 1 /*!< Do not retry this query on error */ -} ares_send_flags_t; - -/* Similar to ares_send_dnsrec() except does not take a channel lock, allows - * specifying a particular server to use, and also flags controlling behavior. - */ -ares_status_t ares_send_nolock(ares_channel_t *channel, ares_server_t *server, - ares_send_flags_t flags, - const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, void *arg, - unsigned short *qid); - -/* Same as ares_gethostbyaddr() except does not take a channel lock. Use this - * if a channel lock is already held */ -void ares_gethostbyaddr_nolock(ares_channel_t *channel, const void *addr, - int addrlen, int family, - ares_host_callback callback, void *arg); - -/*! Parse a compressed DNS name as defined in RFC1035 starting at the current - * offset within the buffer. - * - * It is assumed that either a const buffer is being used, or before - * the message processing was started that ares_buf_reclaim() was called. - * - * \param[in] buf Initialized buffer object - * \param[out] name Pointer passed by reference to be filled in with - * allocated string of the parsed name that must be - * ares_free()'d by the caller. - * \param[in] is_hostname if ARES_TRUE, will validate the character set for - * a valid hostname or will return error. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_dns_name_parse(ares_buf_t *buf, char **name, - ares_bool_t is_hostname); - -/*! Write the DNS name to the buffer in the DNS domain-name syntax as a - * series of labels. The maximum domain name length is 255 characters with - * each label being a maximum of 63 characters. If the validate_hostname - * flag is set, it will strictly validate the character set. - * - * \param[in,out] buf Initialized buffer object to write name to - * \param[in,out] list Pointer passed by reference to maintain a list of - * domain name to indexes used for name compression. - * Pass NULL (not by reference) if name compression isn't - * desired. Otherwise the list will be automatically - * created upon first entry. - * \param[in] validate_hostname Validate the hostname character set. - * \param[in] name Name to write out, it may have escape - * sequences. - * \return ARES_SUCCESS on success, most likely ARES_EBADNAME if the name is - * bad. - */ -ares_status_t ares_dns_name_write(ares_buf_t *buf, ares_llist_t **list, - ares_bool_t validate_hostname, - const char *name); - -/*! Check if the queue is empty, if so, wake any waiters. This is only - * effective if built with threading support. - * - * Must be holding a channel lock when calling this function. - * - * \param[in] channel Initialized ares channel object - */ -void ares_queue_notify_empty(ares_channel_t *channel); - -#define ARES_CONFIG_CHECK(x) \ - (x && x->lookups && ares_slist_len(x->servers) > 0 && x->timeout > 0 && \ - x->tries > 0) - -ares_bool_t ares_subnet_match(const struct ares_addr *addr, - const struct ares_addr *subnet, - unsigned char netmask); -ares_bool_t ares_addr_is_linklocal(const struct ares_addr *addr); - -void ares_qcache_destroy(ares_qcache_t *cache); -ares_status_t ares_qcache_create(ares_rand_state *rand_state, - unsigned int max_ttl, - ares_qcache_t **cache_out); -void ares_qcache_flush(ares_qcache_t *cache); -ares_status_t ares_qcache_insert(ares_channel_t *channel, - const ares_timeval_t *now, - const ares_query_t *query, - ares_dns_record_t *dnsrec); -ares_status_t ares_qcache_fetch(ares_channel_t *channel, - const ares_timeval_t *now, - const ares_dns_record_t *dnsrec, - const ares_dns_record_t **dnsrec_resp); - -void ares_metrics_record(const ares_query_t *query, ares_server_t *server, - ares_status_t status, const ares_dns_record_t *dnsrec); -size_t ares_metrics_server_timeout(const ares_server_t *server, - const ares_timeval_t *now); - -ares_status_t ares_cookie_apply(ares_dns_record_t *dnsrec, ares_conn_t *conn, - const ares_timeval_t *now); -ares_status_t ares_cookie_validate(ares_query_t *query, - const ares_dns_record_t *dnsresp, - ares_conn_t *conn, - const ares_timeval_t *now, - ares_array_t **requeue); - -ares_status_t ares_channel_threading_init(ares_channel_t *channel); -void ares_channel_threading_destroy(ares_channel_t *channel); -void ares_channel_lock(const ares_channel_t *channel); -void ares_channel_unlock(const ares_channel_t *channel); - -struct ares_event_thread; -typedef struct ares_event_thread ares_event_thread_t; - -void ares_event_thread_destroy(ares_channel_t *channel); -ares_status_t ares_event_thread_init(ares_channel_t *channel); - - -#ifdef _WIN32 -# define HOSTENT_ADDRTYPE_TYPE short -# define HOSTENT_LENGTH_TYPE short -#else -# define HOSTENT_ADDRTYPE_TYPE int -# define HOSTENT_LENGTH_TYPE int -#endif - -#endif /* __ARES_PRIVATE_H */ diff --git a/vendor/c-ares/src/lib/ares_process.c b/vendor/c-ares/src/lib/ares_process.c deleted file mode 100644 index c5834fa10..000000000 --- a/vendor/c-ares/src/lib/ares_process.c +++ /dev/null @@ -1,1442 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2010 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef NETWARE -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif - -#include -#include -#include - - -static void timeadd(ares_timeval_t *now, size_t millisecs); -static ares_status_t process_write(ares_channel_t *channel, - ares_socket_t write_fd); -static ares_status_t process_read(ares_channel_t *channel, - ares_socket_t read_fd, - const ares_timeval_t *now); -static ares_status_t process_timeouts(ares_channel_t *channel, - const ares_timeval_t *now); -static ares_status_t process_answer(ares_channel_t *channel, - const unsigned char *abuf, size_t alen, - ares_conn_t *conn, - const ares_timeval_t *now, - ares_array_t **requeue); -static void handle_conn_error(ares_conn_t *conn, ares_bool_t critical_failure, - ares_status_t failure_status); -static ares_bool_t same_questions(const ares_query_t *query, - const ares_dns_record_t *arec); -static void end_query(ares_channel_t *channel, ares_server_t *server, - ares_query_t *query, ares_status_t status, - const ares_dns_record_t *dnsrec); - -static void ares_query_remove_from_conn(ares_query_t *query) -{ - /* If its not part of a connection, it can't be tracked for timeouts either */ - ares_slist_node_destroy(query->node_queries_by_timeout); - ares_llist_node_destroy(query->node_queries_to_conn); - query->node_queries_by_timeout = NULL; - query->node_queries_to_conn = NULL; - query->conn = NULL; -} - -/* Invoke the server state callback after a success or failure */ -static void invoke_server_state_cb(const ares_server_t *server, - ares_bool_t success, int flags) -{ - const ares_channel_t *channel = server->channel; - ares_buf_t *buf; - ares_status_t status; - char *server_string; - - if (channel->server_state_cb == NULL) { - return; - } - - buf = ares_buf_create(); - if (buf == NULL) { - return; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_get_server_addr(server, buf); - if (status != ARES_SUCCESS) { - ares_buf_destroy(buf); /* LCOV_EXCL_LINE: OutOfMemory */ - return; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - server_string = ares_buf_finish_str(buf, NULL); - buf = NULL; - if (server_string == NULL) { - return; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - channel->server_state_cb(server_string, success, flags, - channel->server_state_cb_data); - ares_free(server_string); -} - -static void server_increment_failures(ares_server_t *server, - ares_bool_t used_tcp) -{ - ares_slist_node_t *node; - const ares_channel_t *channel = server->channel; - ares_timeval_t next_retry_time; - - node = ares_slist_node_find(channel->servers, server); - if (node == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - server->consec_failures++; - ares_slist_node_reinsert(node); - - ares_tvnow(&next_retry_time); - timeadd(&next_retry_time, channel->server_retry_delay); - server->next_retry_time = next_retry_time; - - invoke_server_state_cb(server, ARES_FALSE, - used_tcp == ARES_TRUE ? ARES_SERV_STATE_TCP - : ARES_SERV_STATE_UDP); -} - -static void server_set_good(ares_server_t *server, ares_bool_t used_tcp) -{ - ares_slist_node_t *node; - const ares_channel_t *channel = server->channel; - - node = ares_slist_node_find(channel->servers, server); - if (node == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (server->consec_failures > 0) { - server->consec_failures = 0; - ares_slist_node_reinsert(node); - } - - server->next_retry_time.sec = 0; - server->next_retry_time.usec = 0; - - invoke_server_state_cb(server, ARES_TRUE, - used_tcp == ARES_TRUE ? ARES_SERV_STATE_TCP - : ARES_SERV_STATE_UDP); -} - -/* return true if now is exactly check time or later */ -ares_bool_t ares_timedout(const ares_timeval_t *now, - const ares_timeval_t *check) -{ - ares_int64_t secs = (now->sec - check->sec); - - if (secs > 0) { - return ARES_TRUE; /* yes, timed out */ - } - if (secs < 0) { - return ARES_FALSE; /* nope, not timed out */ - } - - /* if the full seconds were identical, check the sub second parts */ - return ((ares_int64_t)now->usec - (ares_int64_t)check->usec) >= 0 - ? ARES_TRUE - : ARES_FALSE; -} - -/* add the specific number of milliseconds to the time in the first argument */ -static void timeadd(ares_timeval_t *now, size_t millisecs) -{ - now->sec += (ares_int64_t)millisecs / 1000; - now->usec += (unsigned int)((millisecs % 1000) * 1000); - - if (now->usec >= 1000000) { - now->sec += now->usec / 1000000; - now->usec %= 1000000; - } -} - -static ares_status_t ares_process_fds_nolock(ares_channel_t *channel, - const ares_fd_events_t *events, - size_t nevents, unsigned int flags) -{ - ares_timeval_t now; - size_t i; - ares_status_t status = ARES_SUCCESS; - - if (channel == NULL || (events == NULL && nevents != 0)) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_tvnow(&now); - - /* Process write events */ - for (i = 0; i < nevents; i++) { - if (events[i].fd == ARES_SOCKET_BAD || - !(events[i].events & ARES_FD_EVENT_WRITE)) { - continue; - } - status = process_write(channel, events[i].fd); - /* We only care about ENOMEM, anything else is handled via connection - * retries, etc */ - if (status == ARES_ENOMEM) { - goto done; - } - } - - /* Process read events */ - for (i = 0; i < nevents; i++) { - if (events[i].fd == ARES_SOCKET_BAD || - !(events[i].events & ARES_FD_EVENT_READ)) { - continue; - } - status = process_read(channel, events[i].fd, &now); - if (status == ARES_ENOMEM) { - goto done; - } - } - - if (!(flags & ARES_PROCESS_FLAG_SKIP_NON_FD)) { - ares_check_cleanup_conns(channel); - status = process_timeouts(channel, &now); - if (status == ARES_ENOMEM) { - goto done; - } - } - -done: - if (status == ARES_ENOMEM) { - return ARES_ENOMEM; - } - return ARES_SUCCESS; -} - -ares_status_t ares_process_fds(ares_channel_t *channel, - const ares_fd_events_t *events, size_t nevents, - unsigned int flags) -{ - ares_status_t status; - - if (channel == NULL) { - return ARES_EFORMERR; - } - - ares_channel_lock(channel); - status = ares_process_fds_nolock(channel, events, nevents, flags); - ares_channel_unlock(channel); - return status; -} - -void ares_process_fd(ares_channel_t *channel, ares_socket_t read_fd, - ares_socket_t write_fd) -{ - ares_fd_events_t events[2]; - size_t nevents = 0; - - memset(events, 0, sizeof(events)); - - if (read_fd != ARES_SOCKET_BAD) { - nevents++; - events[nevents - 1].fd = read_fd; - events[nevents - 1].events |= ARES_FD_EVENT_READ; - } - - if (write_fd != ARES_SOCKET_BAD) { - if (write_fd != read_fd) { - nevents++; - } - events[nevents - 1].fd = write_fd; - events[nevents - 1].events |= ARES_FD_EVENT_WRITE; - } - - ares_process_fds(channel, events, nevents, ARES_PROCESS_FLAG_NONE); -} - -static ares_socket_t *channel_socket_list(const ares_channel_t *channel, - size_t *num) -{ - ares_slist_node_t *snode; - ares_array_t *arr = ares_array_create(sizeof(ares_socket_t), NULL); - - *num = 0; - - if (arr == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (snode = ares_slist_node_first(channel->servers); snode != NULL; - snode = ares_slist_node_next(snode)) { - ares_server_t *server = ares_slist_node_val(snode); - ares_llist_node_t *node; - - for (node = ares_llist_node_first(server->connections); node != NULL; - node = ares_llist_node_next(node)) { - const ares_conn_t *conn = ares_llist_node_val(node); - ares_socket_t *sptr; - ares_status_t status; - - if (conn->fd == ARES_SOCKET_BAD) { - continue; - } - - status = ares_array_insert_last((void **)&sptr, arr); - if (status != ARES_SUCCESS) { - ares_array_destroy(arr); /* LCOV_EXCL_LINE: OutOfMemory */ - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - *sptr = conn->fd; - } - } - - return ares_array_finish(arr, num); -} - -/* Something interesting happened on the wire, or there was a timeout. - * See what's up and respond accordingly. - */ -void ares_process(ares_channel_t *channel, fd_set *read_fds, fd_set *write_fds) -{ - size_t i; - size_t num_sockets; - ares_socket_t *socketlist; - ares_fd_events_t *events = NULL; - size_t nevents = 0; - - if (channel == NULL) { - return; - } - - ares_channel_lock(channel); - - /* There is no good way to iterate across an fd_set, instead we must pull a - * list of all known fds, and iterate across that checking against the fd_set. - */ - socketlist = channel_socket_list(channel, &num_sockets); - - /* Lets create an events array, maximum number is the number of sockets in - * the list, so we'll use that and just track entries with nevents */ - if (num_sockets) { - events = ares_malloc_zero(sizeof(*events) * num_sockets); - if (events == NULL) { - goto done; - } - } - - for (i = 0; i < num_sockets; i++) { - ares_bool_t had_read = ARES_FALSE; - if (read_fds && FD_ISSET(socketlist[i], read_fds)) { - nevents++; - events[nevents - 1].fd = socketlist[i]; - events[nevents - 1].events |= ARES_FD_EVENT_READ; - had_read = ARES_TRUE; - } - if (write_fds && FD_ISSET(socketlist[i], write_fds)) { - if (!had_read) { - nevents++; - } - events[nevents - 1].fd = socketlist[i]; - events[nevents - 1].events |= ARES_FD_EVENT_WRITE; - } - } - -done: - ares_process_fds_nolock(channel, events, nevents, ARES_PROCESS_FLAG_NONE); - ares_free(events); - ares_free(socketlist); - ares_channel_unlock(channel); -} - -static ares_status_t process_write(ares_channel_t *channel, - ares_socket_t write_fd) -{ - ares_conn_t *conn = ares_conn_from_fd(channel, write_fd); - ares_status_t status; - - if (conn == NULL) { - return ARES_SUCCESS; - } - - /* Mark as connected if we got here and TFO Initial not set */ - if (!(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) { - conn->state_flags |= ARES_CONN_STATE_CONNECTED; - } - - status = ares_conn_flush(conn); - if (status != ARES_SUCCESS) { - handle_conn_error(conn, ARES_TRUE, status); - } - return status; -} - -void ares_process_pending_write(ares_channel_t *channel) -{ - ares_slist_node_t *node; - - if (channel == NULL) { - return; - } - - ares_channel_lock(channel); - if (!channel->notify_pending_write) { - ares_channel_unlock(channel); - return; - } - - /* Set as untriggerd before calling into ares_conn_flush(), this is - * because its possible ares_conn_flush() might cause additional data to - * be enqueued if there is some form of exception so it will need to recurse. - */ - channel->notify_pending_write = ARES_FALSE; - - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - ares_server_t *server = ares_slist_node_val(node); - ares_conn_t *conn = server->tcp_conn; - ares_status_t status; - - if (conn == NULL) { - continue; - } - - /* Enqueue any pending data if there is any */ - status = ares_conn_flush(conn); - if (status != ARES_SUCCESS) { - handle_conn_error(conn, ARES_TRUE, status); - } - } - - ares_channel_unlock(channel); -} - -static ares_status_t read_conn_packets(ares_conn_t *conn) -{ - ares_bool_t read_again; - ares_conn_err_t err; - const ares_channel_t *channel = conn->server->channel; - - do { - size_t count; - size_t len = 65535; - unsigned char *ptr; - size_t start_len = ares_buf_len(conn->in_buf); - - /* If UDP, lets write out a placeholder for the length indicator */ - if (!(conn->flags & ARES_CONN_FLAG_TCP) && - ares_buf_append_be16(conn->in_buf, 0) != ARES_SUCCESS) { - handle_conn_error(conn, ARES_FALSE /* not critical to connection */, - ARES_SUCCESS); - return ARES_ENOMEM; - } - - /* Get a buffer of sufficient size */ - ptr = ares_buf_append_start(conn->in_buf, &len); - - if (ptr == NULL) { - handle_conn_error(conn, ARES_FALSE /* not critical to connection */, - ARES_SUCCESS); - return ARES_ENOMEM; - } - - /* Read from socket */ - err = ares_conn_read(conn, ptr, len, &count); - - if (err != ARES_CONN_ERR_SUCCESS) { - ares_buf_append_finish(conn->in_buf, 0); - if (!(conn->flags & ARES_CONN_FLAG_TCP)) { - ares_buf_set_length(conn->in_buf, start_len); - } - break; - } - - /* Record amount of data read */ - ares_buf_append_finish(conn->in_buf, count); - - /* Only loop if sockets support non-blocking operation, and are using UDP - * or are using TCP and read the maximum buffer size */ - read_again = ARES_FALSE; - if (channel->sock_funcs.flags & ARES_SOCKFUNC_FLAG_NONBLOCKING && - (!(conn->flags & ARES_CONN_FLAG_TCP) || count == len)) { - read_again = ARES_TRUE; - } - - /* If UDP, overwrite length */ - if (!(conn->flags & ARES_CONN_FLAG_TCP)) { - len = ares_buf_len(conn->in_buf); - ares_buf_set_length(conn->in_buf, start_len); - ares_buf_append_be16(conn->in_buf, (unsigned short)count); - ares_buf_set_length(conn->in_buf, len); - } - /* Try to read again only if *we* set up the socket, otherwise it may be - * a blocking socket and would cause recvfrom to hang. */ - } while (read_again); - - if (err != ARES_CONN_ERR_SUCCESS && err != ARES_CONN_ERR_WOULDBLOCK) { - handle_conn_error(conn, ARES_TRUE, ARES_ECONNREFUSED); - return ARES_ECONNREFUSED; - } - - return ARES_SUCCESS; -} - -/* Simple data structure to store a query that needs to be requeued with - * optional server */ -typedef struct { - unsigned short qid; - ares_server_t *server; /* optional */ -} ares_requeue_t; - -static ares_status_t ares_append_requeue(ares_array_t **requeue, - ares_query_t *query, - ares_server_t *server) -{ - ares_requeue_t entry; - - if (*requeue == NULL) { - *requeue = ares_array_create(sizeof(ares_requeue_t), NULL); - if (*requeue == NULL) { - return ARES_ENOMEM; - } - } - - ares_query_remove_from_conn(query); - - entry.qid = query->qid; - entry.server = server; - return ares_array_insertdata_last(*requeue, &entry); -} - -static ares_status_t read_answers(ares_conn_t *conn, const ares_timeval_t *now) -{ - ares_status_t status; - ares_channel_t *channel = conn->server->channel; - ares_array_t *requeue = NULL; - - /* Process all queued answers */ - while (1) { - unsigned short dns_len = 0; - const unsigned char *data = NULL; - size_t data_len = 0; - - /* Tag so we can roll back */ - ares_buf_tag(conn->in_buf); - - /* Read length indicator */ - status = ares_buf_fetch_be16(conn->in_buf, &dns_len); - if (status != ARES_SUCCESS) { - ares_buf_tag_rollback(conn->in_buf); - break; - } - - /* Not enough data for a full response yet */ - status = ares_buf_consume(conn->in_buf, dns_len); - if (status != ARES_SUCCESS) { - ares_buf_tag_rollback(conn->in_buf); - break; - } - - /* Can't fail except for misuse */ - data = ares_buf_tag_fetch(conn->in_buf, &data_len); - if (data == NULL || data_len < 2) { - ares_buf_tag_clear(conn->in_buf); - break; - } - - /* Strip off 2 bytes length */ - data += 2; - data_len -= 2; - - /* We finished reading this answer; process it */ - status = process_answer(channel, data, data_len, conn, now, &requeue); - if (status != ARES_SUCCESS) { - handle_conn_error(conn, ARES_TRUE, status); - goto cleanup; - } - - /* Since we processed the answer, clear the tag so space can be reclaimed */ - ares_buf_tag_clear(conn->in_buf); - } - -cleanup: - - /* Flush requeue */ - while (ares_array_len(requeue) > 0) { - ares_query_t *query; - ares_requeue_t entry; - ares_status_t internal_status; - - internal_status = ares_array_claim_at(&entry, sizeof(entry), requeue, 0); - if (internal_status != ARES_SUCCESS) { - break; - } - - /* Query disappeared */ - query = ares_htable_szvp_get_direct(channel->queries_by_qid, entry.qid); - if (query == NULL) { - continue; - } - - internal_status = ares_send_query(entry.server, query, now); - /* We only care about ARES_ENOMEM */ - if (internal_status == ARES_ENOMEM) { - status = ARES_ENOMEM; - } - } - ares_array_destroy(requeue); - - return status; -} - -static ares_status_t process_read(ares_channel_t *channel, - ares_socket_t read_fd, - const ares_timeval_t *now) -{ - ares_conn_t *conn = ares_conn_from_fd(channel, read_fd); - ares_status_t status; - - if (conn == NULL) { - return ARES_SUCCESS; - } - - /* TODO: There might be a potential issue here where there was a read that - * read some data, then looped and read again and got a disconnect. - * Right now, that would cause a resend instead of processing the data - * we have. This is fairly unlikely to occur due to only looping if - * a full buffer of 65535 bytes was read. */ - status = read_conn_packets(conn); - - if (status != ARES_SUCCESS) { - return status; - } - - return read_answers(conn, now); -} - -/* If any queries have timed out, note the timeout and move them on. */ -static ares_status_t process_timeouts(ares_channel_t *channel, - const ares_timeval_t *now) -{ - ares_slist_node_t *node; - ares_status_t status = ARES_SUCCESS; - - /* Just keep popping off the first as this list will re-sort as things come - * and go. We don't want to try to rely on 'next' as some operation might - * cause a cleanup of that pointer and would become invalid */ - while ((node = ares_slist_node_first(channel->queries_by_timeout)) != NULL) { - ares_query_t *query = ares_slist_node_val(node); - ares_conn_t *conn; - - /* Since this is sorted, as soon as we hit a query that isn't timed out, - * break */ - if (!ares_timedout(now, &query->timeout)) { - break; - } - - query->timeouts++; - - conn = query->conn; - server_increment_failures(conn->server, query->using_tcp); - status = ares_requeue_query(query, now, ARES_ETIMEOUT, ARES_TRUE, NULL, - NULL); - if (status == ARES_ENOMEM) { - goto done; - } - } -done: - if (status == ARES_ENOMEM) { - return ARES_ENOMEM; - } - return ARES_SUCCESS; -} - -static ares_status_t rewrite_without_edns(ares_query_t *query) -{ - ares_status_t status = ARES_SUCCESS; - size_t i; - ares_bool_t found_opt_rr = ARES_FALSE; - - /* Find and remove the OPT RR record */ - for (i = 0; i < ares_dns_record_rr_cnt(query->query, ARES_SECTION_ADDITIONAL); - i++) { - const ares_dns_rr_t *rr; - rr = ares_dns_record_rr_get(query->query, ARES_SECTION_ADDITIONAL, i); - if (ares_dns_rr_get_type(rr) == ARES_REC_TYPE_OPT) { - ares_dns_record_rr_del(query->query, ARES_SECTION_ADDITIONAL, i); - found_opt_rr = ARES_TRUE; - break; - } - } - - if (!found_opt_rr) { - status = ARES_EFORMERR; - goto done; - } - -done: - return status; -} - -static ares_bool_t issue_might_be_edns(const ares_dns_record_t *req, - const ares_dns_record_t *rsp) -{ - const ares_dns_rr_t *rr; - - /* If we use EDNS and server answers with FORMERR without an OPT RR, the - * protocol extension is not understood by the responder. We must retry the - * query without EDNS enabled. */ - if (ares_dns_record_get_rcode(rsp) != ARES_RCODE_FORMERR) { - return ARES_FALSE; - } - - rr = ares_dns_get_opt_rr_const(req); - if (rr == NULL) { - /* We didn't send EDNS */ - return ARES_FALSE; - } - - if (ares_dns_get_opt_rr_const(rsp) == NULL) { - /* Spec says EDNS won't be echo'd back on non-supporting servers, so - * retry without EDNS */ - return ARES_TRUE; - } - - /* As per issue #911 some non-compliant servers that do indeed support EDNS - * but don't support unrecognized option codes exist. At this point we - * expect them to have also returned an EDNS opt record, but we may remove - * that check in the future. Lets detect this situation if we're sending - * option codes */ - if (ares_dns_rr_get_opt_cnt(rr, ARES_RR_OPT_OPTIONS) == 0) { - /* We didn't send any option codes */ - return ARES_FALSE; - } - - if (ares_dns_get_opt_rr_const(rsp) != NULL) { - /* At this time we're requiring the server to respond with EDNS opt - * records since that's what has been observed in the field. We might - * find in the future we have to remove this, who knows. Lets go - * ahead and force a retry without EDNS*/ - return ARES_TRUE; - } - - return ARES_FALSE; -} - -/* Handle an answer from a server. This must NEVER cleanup the - * server connection! Return something other than ARES_SUCCESS to cause - * the connection to be terminated after this call. */ -static ares_status_t process_answer(ares_channel_t *channel, - const unsigned char *abuf, size_t alen, - ares_conn_t *conn, - const ares_timeval_t *now, - ares_array_t **requeue) -{ - ares_query_t *query; - /* Cache these as once ares_send_query() gets called, it may end up - * invalidating the connection all-together */ - ares_server_t *server = conn->server; - ares_dns_record_t *rdnsrec = NULL; - ares_status_t status; - ares_bool_t is_cached = ARES_FALSE; - - /* UDP can have 0-byte messages, drop them to the ground */ - if (alen == 0) { - return ARES_SUCCESS; - } - - /* Parse the response */ - status = ares_dns_parse(abuf, alen, 0, &rdnsrec); - if (status != ARES_SUCCESS) { - /* Malformations are never accepted */ - status = ARES_EBADRESP; - goto cleanup; - } - - /* Find the query corresponding to this packet. The queries are - * hashed/bucketed by query id, so this lookup should be quick. - */ - query = ares_htable_szvp_get_direct(channel->queries_by_qid, - ares_dns_record_get_id(rdnsrec)); - if (!query) { - /* We may have stopped listening for this query, that's ok */ - status = ARES_SUCCESS; - goto cleanup; - } - - /* Both the query id and the questions must be the same. We will drop any - * replies that aren't for the same query as this is considered invalid. */ - if (!same_questions(query, rdnsrec)) { - /* Possible qid conflict due to delayed response, that's ok */ - status = ARES_SUCCESS; - goto cleanup; - } - - /* Validate DNS cookie in response. This function may need to requeue the - * query. */ - if (ares_cookie_validate(query, rdnsrec, conn, now, requeue) - != ARES_SUCCESS) { - /* Drop response and return */ - status = ARES_SUCCESS; - goto cleanup; - } - - /* At this point we know we've received an answer for this query, so we should - * remove it from the connection's queue so we can possibly invalidate the - * connection. Delay cleaning up the connection though as we may enqueue - * something new. */ - ares_llist_node_destroy(query->node_queries_to_conn); - query->node_queries_to_conn = NULL; - - /* There are old servers that don't understand EDNS at all, then some servers - * that have non-compliant implementations. Lets try to detect this sort - * of thing. */ - if (issue_might_be_edns(query->query, rdnsrec)) { - status = rewrite_without_edns(query); - if (status != ARES_SUCCESS) { - end_query(channel, server, query, status, NULL); - goto cleanup; - } - - /* Requeue to same server */ - status = ares_append_requeue(requeue, query, server); - goto cleanup; - } - - /* If we got a truncated UDP packet and are not ignoring truncation, - * don't accept the packet, and switch the query to TCP if we hadn't - * done so already. - */ - if (ares_dns_record_get_flags(rdnsrec) & ARES_FLAG_TC && - !(conn->flags & ARES_CONN_FLAG_TCP) && - !(channel->flags & ARES_FLAG_IGNTC)) { - query->using_tcp = ARES_TRUE; - status = ares_append_requeue(requeue, query, NULL); - /* Status will reflect success except on memory error, which is good since - * requeuing to TCP is ok */ - goto cleanup; - } - - /* If we aren't passing through all error packets, discard packets - * with SERVFAIL, NOTIMP, or REFUSED response codes. - */ - if (!(channel->flags & ARES_FLAG_NOCHECKRESP)) { - ares_dns_rcode_t rcode = ares_dns_record_get_rcode(rdnsrec); - if (rcode == ARES_RCODE_SERVFAIL || rcode == ARES_RCODE_NOTIMP || - rcode == ARES_RCODE_REFUSED) { - switch (rcode) { - case ARES_RCODE_SERVFAIL: - status = ARES_ESERVFAIL; - break; - case ARES_RCODE_NOTIMP: - status = ARES_ENOTIMP; - break; - case ARES_RCODE_REFUSED: - status = ARES_EREFUSED; - break; - default: - break; - } - - server_increment_failures(server, query->using_tcp); - status = ares_requeue_query(query, now, status, ARES_TRUE, rdnsrec, requeue); - - if (status != ARES_ENOMEM) { - /* Should any of these cause a connection termination? - * Maybe SERVER_FAILURE? */ - status = ARES_SUCCESS; - } - goto cleanup; - } - } - - /* If cache insertion was successful, it took ownership. We ignore - * other cache insertion failures. */ - if (ares_qcache_insert(channel, now, query, rdnsrec) == ARES_SUCCESS) { - is_cached = ARES_TRUE; - } - - server_set_good(server, query->using_tcp); - end_query(channel, server, query, ARES_SUCCESS, rdnsrec); - - status = ARES_SUCCESS; - -cleanup: - /* Don't cleanup the cached pointer to the dns response */ - if (!is_cached) { - ares_dns_record_destroy(rdnsrec); - } - - return status; -} - -static void handle_conn_error(ares_conn_t *conn, ares_bool_t critical_failure, - ares_status_t failure_status) -{ - ares_server_t *server = conn->server; - - /* Increment failures first before requeue so it is unlikely to requeue - * to the same server */ - if (critical_failure) { - server_increment_failures( - server, (conn->flags & ARES_CONN_FLAG_TCP) ? ARES_TRUE : ARES_FALSE); - } - - /* This will requeue any connections automatically */ - ares_close_connection(conn, failure_status); -} - -/* Requeue query will normally call ares_send_query() but in some circumstances - * this needs to be delayed, so if requeue is not NULL, it will add the query - * to the queue instead */ -ares_status_t ares_requeue_query(ares_query_t *query, const ares_timeval_t *now, - ares_status_t status, - ares_bool_t inc_try_count, - const ares_dns_record_t *dnsrec, - ares_array_t **requeue) -{ - ares_channel_t *channel = query->channel; - size_t max_tries = ares_slist_len(channel->servers) * channel->tries; - - ares_query_remove_from_conn(query); - - if (status != ARES_SUCCESS) { - query->error_status = status; - } - - if (inc_try_count) { - query->try_count++; - } - - if (query->try_count < max_tries && !query->no_retries) { - if (requeue != NULL) { - return ares_append_requeue(requeue, query, NULL); - } - return ares_send_query(NULL, query, now); - } - - /* If we are here, all attempts to perform query failed. */ - if (query->error_status == ARES_SUCCESS) { - query->error_status = ARES_ETIMEOUT; - } - - end_query(channel, NULL, query, query->error_status, dnsrec); - return ARES_ETIMEOUT; -} - -/*! Count the number of servers that share the same highest priority (lowest - * consecutive failures). Since they are sorted in priority order, we just - * stop when the consecutive failure count changes. Used for random selection - * of good servers. */ -static size_t count_highest_prio_servers(const ares_channel_t *channel) -{ - ares_slist_node_t *node; - size_t cnt = 0; - size_t last_consec_failures = SIZE_MAX; - - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - const ares_server_t *server = ares_slist_node_val(node); - - if (last_consec_failures != SIZE_MAX && - last_consec_failures < server->consec_failures) { - break; - } - - last_consec_failures = server->consec_failures; - cnt++; - } - - return cnt; -} - -/* Pick a random *best* server from the list, we first get a random number in - * the range of the number of *best* servers, then scan until we find that - * server in the list */ -static ares_server_t *ares_random_server(ares_channel_t *channel) -{ - unsigned char c; - size_t cnt; - size_t idx; - ares_slist_node_t *node; - size_t num_servers = count_highest_prio_servers(channel); - - /* Silence coverity, not possible */ - if (num_servers == 0) { - return NULL; - } - - ares_rand_bytes(channel->rand_state, &c, 1); - - cnt = c; - idx = cnt % num_servers; - - cnt = 0; - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - if (cnt == idx) { - return ares_slist_node_val(node); - } - - cnt++; - } - - return NULL; -} - -static void server_probe_cb(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - (void)arg; - (void)status; - (void)timeouts; - (void)dnsrec; - /* Nothing to do, the logic internally will handle success/fail of this */ -} - -/* Determine if we should probe a downed server */ -static void ares_probe_failed_server(ares_channel_t *channel, - const ares_server_t *server, - const ares_query_t *query) -{ - const ares_server_t *last_server = ares_slist_last_val(channel->servers); - unsigned short r; - ares_timeval_t now; - ares_slist_node_t *node; - ares_server_t *probe_server = NULL; - - /* If no servers have failures, or we're not configured with a server retry - * chance, then nothing to probe */ - if ((last_server != NULL && last_server->consec_failures == 0) || - channel->server_retry_chance == 0) { - return; - } - - /* Generate a random value to decide whether to retry a failed server. The - * probability to use is 1/channel->server_retry_chance, rounded up to a - * precision of 1/2^B where B is the number of bits in the random value. - * We use an unsigned short for the random value for increased precision. - */ - ares_rand_bytes(channel->rand_state, (unsigned char *)&r, sizeof(r)); - if (r % channel->server_retry_chance != 0) { - return; - } - - /* Select the first server with failures to retry that has passed the retry - * timeout and doesn't already have a pending probe */ - ares_tvnow(&now); - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - ares_server_t *node_val = ares_slist_node_val(node); - if (node_val != NULL && node_val->consec_failures > 0 && - !node_val->probe_pending && - ares_timedout(&now, &node_val->next_retry_time)) { - probe_server = node_val; - break; - } - } - - /* Either nothing to probe or the query was enqueud to the same server - * we were going to probe. Do nothing. */ - if (probe_server == NULL || server == probe_server) { - return; - } - - /* Enqueue an identical query onto the specified server without honoring - * the cache or allowing retries. We want to make sure it only attempts to - * use the server in question */ - probe_server->probe_pending = ARES_TRUE; - ares_send_nolock(channel, probe_server, - ARES_SEND_FLAG_NOCACHE | ARES_SEND_FLAG_NORETRY, - query->query, server_probe_cb, NULL, NULL); -} - -static size_t ares_calc_query_timeout(const ares_query_t *query, - const ares_server_t *server, - const ares_timeval_t *now) -{ - const ares_channel_t *channel = query->channel; - size_t timeout = ares_metrics_server_timeout(server, now); - size_t timeplus = timeout; - size_t rounds; - size_t num_servers = ares_slist_len(channel->servers); - - if (num_servers == 0) { - return 0; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* For each trip through the entire server list, we want to double the - * retry from the last retry */ - rounds = (query->try_count / num_servers); - if (rounds > 0) { - timeplus <<= rounds; - } - - if (channel->maxtimeout && timeplus > channel->maxtimeout) { - timeplus = channel->maxtimeout; - } - - /* Add some jitter to the retry timeout. - * - * Jitter is needed in situation when resolve requests are performed - * simultaneously from multiple hosts and DNS server throttle these requests. - * Adding randomness allows to avoid synchronisation of retries. - * - * Value of timeplus adjusted randomly to the range [0.5 * timeplus, - * timeplus]. - */ - if (rounds > 0) { - unsigned short r; - float delta_multiplier; - - ares_rand_bytes(channel->rand_state, (unsigned char *)&r, sizeof(r)); - delta_multiplier = ((float)r / USHRT_MAX) * 0.5f; - timeplus -= (size_t)((float)timeplus * delta_multiplier); - } - - /* We want explicitly guarantee that timeplus is greater or equal to timeout - * specified in channel options. */ - if (timeplus < timeout) { - timeplus = timeout; - } - - return timeplus; -} - -static ares_conn_t *ares_fetch_connection(const ares_channel_t *channel, - ares_server_t *server, - const ares_query_t *query) -{ - ares_llist_node_t *node; - ares_conn_t *conn; - - if (query->using_tcp) { - return server->tcp_conn; - } - - /* Fetch existing UDP connection */ - node = ares_llist_node_first(server->connections); - if (node == NULL) { - return NULL; - } - - conn = ares_llist_node_val(node); - /* Not UDP, skip */ - if (conn->flags & ARES_CONN_FLAG_TCP) { - return NULL; - } - - /* Used too many times */ - if (channel->udp_max_queries > 0 && - conn->total_queries >= channel->udp_max_queries) { - return NULL; - } - - return conn; -} - -static ares_status_t ares_conn_query_write(ares_conn_t *conn, - ares_query_t *query, - const ares_timeval_t *now) -{ - ares_server_t *server = conn->server; - ares_channel_t *channel = server->channel; - ares_status_t status; - - status = ares_cookie_apply(query->query, conn, now); - if (status != ARES_SUCCESS) { - return status; - } - - /* We write using the TCP format even for UDP, we just strip the length - * before putting on the wire */ - status = ares_dns_write_buf_tcp(query->query, conn->out_buf); - if (status != ARES_SUCCESS) { - return status; - } - - /* Not pending a TFO write and not connected, so we can't even try to - * write until we get a signal */ - if (conn->flags & ARES_CONN_FLAG_TCP && - !(conn->state_flags & ARES_CONN_STATE_CONNECTED) && - !(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) { - return ARES_SUCCESS; - } - - /* Delay actual write if possible (TCP only, and only if callback - * configured) */ - if (channel->notify_pending_write_cb && !channel->notify_pending_write && - conn->flags & ARES_CONN_FLAG_TCP) { - channel->notify_pending_write = ARES_TRUE; - channel->notify_pending_write_cb(channel->notify_pending_write_cb_data); - return ARES_SUCCESS; - } - - /* Unfortunately we need to write right away and can't aggregate multiple - * queries into a single write. */ - return ares_conn_flush(conn); -} - -ares_status_t ares_send_query(ares_server_t *requested_server, - ares_query_t *query, const ares_timeval_t *now) -{ - ares_channel_t *channel = query->channel; - ares_server_t *server; - ares_conn_t *conn; - size_t timeplus; - ares_status_t status; - ares_bool_t probe_downed_server = ARES_TRUE; - - - /* Choose the server to send the query to */ - if (requested_server != NULL) { - server = requested_server; - } else { - /* If rotate is turned on, do a random selection */ - if (channel->rotate) { - server = ares_random_server(channel); - } else { - /* First server in list */ - server = ares_slist_first_val(channel->servers); - } - } - - if (server == NULL) { - end_query(channel, server, query, ARES_ENOSERVER /* ? */, NULL); - return ARES_ENOSERVER; - } - - /* If a query is directed to a specific query, or the server chosen has - * failures, or the query is being retried, don't probe for downed servers */ - if (requested_server != NULL || server->consec_failures > 0 || - query->try_count != 0) { - probe_downed_server = ARES_FALSE; - } - - conn = ares_fetch_connection(channel, server, query); - if (conn == NULL) { - status = ares_open_connection(&conn, channel, server, query->using_tcp); - switch (status) { - /* Good result, continue on */ - case ARES_SUCCESS: - break; - - /* These conditions are retryable as they are server-specific - * error codes */ - case ARES_ECONNREFUSED: - case ARES_EBADFAMILY: - server_increment_failures(server, query->using_tcp); - return ares_requeue_query(query, now, status, ARES_TRUE, NULL, NULL); - - /* Anything else is not retryable, likely ENOMEM */ - default: - end_query(channel, server, query, status, NULL); - return status; - } - } - - /* Write the query */ - status = ares_conn_query_write(conn, query, now); - switch (status) { - /* Good result, continue on */ - case ARES_SUCCESS: - break; - - case ARES_ENOMEM: - /* Not retryable */ - end_query(channel, server, query, status, NULL); - return status; - - /* These conditions are retryable as they are server-specific - * error codes */ - case ARES_ECONNREFUSED: - case ARES_EBADFAMILY: - handle_conn_error(conn, ARES_TRUE, status); - status = ares_requeue_query(query, now, status, ARES_TRUE, NULL, NULL); - if (status == ARES_ETIMEOUT) { - status = ARES_ECONNREFUSED; - } - return status; - - default: - server_increment_failures(server, query->using_tcp); - status = ares_requeue_query(query, now, status, ARES_TRUE, NULL, NULL); - return status; - } - - timeplus = ares_calc_query_timeout(query, server, now); - /* Keep track of queries bucketed by timeout, so we can process - * timeout events quickly. - */ - ares_slist_node_destroy(query->node_queries_by_timeout); - query->ts = *now; - query->timeout = *now; - timeadd(&query->timeout, timeplus); - query->node_queries_by_timeout = - ares_slist_insert(channel->queries_by_timeout, query); - if (!query->node_queries_by_timeout) { - /* LCOV_EXCL_START: OutOfMemory */ - end_query(channel, server, query, ARES_ENOMEM, NULL); - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ - } - - /* Keep track of queries bucketed by connection, so we can process errors - * quickly. */ - ares_llist_node_destroy(query->node_queries_to_conn); - query->node_queries_to_conn = - ares_llist_insert_last(conn->queries_to_conn, query); - - if (query->node_queries_to_conn == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - end_query(channel, server, query, ARES_ENOMEM, NULL); - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ - } - - query->conn = conn; - conn->total_queries++; - - /* We just successfully enqueud a query, see if we should probe downed - * servers. */ - if (probe_downed_server) { - ares_probe_failed_server(channel, server, query); - } - - return ARES_SUCCESS; -} - -static ares_bool_t same_questions(const ares_query_t *query, - const ares_dns_record_t *arec) -{ - size_t i; - ares_bool_t rv = ARES_FALSE; - const ares_dns_record_t *qrec = query->query; - const ares_channel_t *channel = query->channel; - - - if (ares_dns_record_query_cnt(qrec) != ares_dns_record_query_cnt(arec)) { - goto done; - } - - for (i = 0; i < ares_dns_record_query_cnt(qrec); i++) { - const char *qname = NULL; - const char *aname = NULL; - ares_dns_rec_type_t qtype; - ares_dns_rec_type_t atype; - ares_dns_class_t qclass; - ares_dns_class_t aclass; - - if (ares_dns_record_query_get(qrec, i, &qname, &qtype, &qclass) != - ARES_SUCCESS || - qname == NULL) { - goto done; - } - - if (ares_dns_record_query_get(arec, i, &aname, &atype, &aclass) != - ARES_SUCCESS || - aname == NULL) { - goto done; - } - - if (qtype != atype || qclass != aclass) { - goto done; - } - - if (channel->flags & ARES_FLAG_DNS0x20 && !query->using_tcp) { - /* NOTE: for DNS 0x20, part of the protection is to use a case-sensitive - * comparison of the DNS query name. This expects the upstream DNS - * server to preserve the case of the name in the response packet. - * https://datatracker.ietf.org/doc/html/draft-vixie-dnsext-dns0x20-00 - */ - if (!ares_streq(qname, aname)) { - goto done; - } - } else { - /* without DNS0x20 use case-insensitive matching */ - if (!ares_strcaseeq(qname, aname)) { - goto done; - } - } - } - - rv = ARES_TRUE; - -done: - return rv; -} - -static void ares_detach_query(ares_query_t *query) -{ - /* Remove the query from all the lists in which it is linked */ - ares_query_remove_from_conn(query); - ares_htable_szvp_remove(query->channel->queries_by_qid, query->qid); - ares_llist_node_destroy(query->node_all_queries); - query->node_all_queries = NULL; -} - -static void end_query(ares_channel_t *channel, ares_server_t *server, - ares_query_t *query, ares_status_t status, - const ares_dns_record_t *dnsrec) -{ - /* If we were probing for the server to come back online, lets mark it as - * no longer being probed */ - if (server != NULL) { - server->probe_pending = ARES_FALSE; - } - - ares_metrics_record(query, server, status, dnsrec); - - /* Invoke the callback. */ - query->callback(query->arg, status, query->timeouts, dnsrec); - ares_free_query(query); - - /* Check and notify if no other queries are enqueued on the channel. This - * must come after the callback and freeing the query for 2 reasons. - * 1) The callback itself may enqueue a new query - * 2) Technically the current query isn't detached until it is free()'d. - */ - ares_queue_notify_empty(channel); -} - -void ares_free_query(ares_query_t *query) -{ - ares_detach_query(query); - /* Zero out some important stuff, to help catch bugs */ - query->callback = NULL; - query->arg = NULL; - /* Deallocate the memory associated with the query */ - ares_dns_record_destroy(query->query); - - ares_free(query); -} diff --git a/vendor/c-ares/src/lib/ares_qcache.c b/vendor/c-ares/src/lib/ares_qcache.c deleted file mode 100644 index 97c0a9137..000000000 --- a/vendor/c-ares/src/lib/ares_qcache.c +++ /dev/null @@ -1,430 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -struct ares_qcache { - ares_htable_strvp_t *cache; - ares_slist_t *expire; - unsigned int max_ttl; -}; - -typedef struct { - char *key; - ares_dns_record_t *dnsrec; - time_t expire_ts; - time_t insert_ts; -} ares_qcache_entry_t; - -static char *ares_qcache_calc_key(const ares_dns_record_t *dnsrec) -{ - ares_buf_t *buf = ares_buf_create(); - size_t i; - ares_status_t status; - ares_dns_flags_t flags; - - if (dnsrec == NULL || buf == NULL) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Format is OPCODE|FLAGS[|QTYPE1|QCLASS1|QNAME1]... */ - - status = ares_buf_append_str( - buf, ares_dns_opcode_tostr(ares_dns_record_get_opcode(dnsrec))); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, '|'); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - flags = ares_dns_record_get_flags(dnsrec); - /* Only care about RD and CD */ - if (flags & ARES_FLAG_RD) { - status = ares_buf_append_str(buf, "rd"); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - if (flags & ARES_FLAG_CD) { - status = ares_buf_append_str(buf, "cd"); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - for (i = 0; i < ares_dns_record_query_cnt(dnsrec); i++) { - const char *name; - size_t name_len; - ares_dns_rec_type_t qtype; - ares_dns_class_t qclass; - - status = ares_dns_record_query_get(dnsrec, i, &name, &qtype, &qclass); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - status = ares_buf_append_byte(buf, '|'); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_str(buf, ares_dns_rec_type_tostr(qtype)); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, '|'); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_str(buf, ares_dns_class_tostr(qclass)); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, '|'); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* On queries, a '.' may be appended to the name to indicate an explicit - * name lookup without performing a search. Strip this since its not part - * of a cached response. */ - name_len = ares_strlen(name); - if (name_len && name[name_len - 1] == '.') { - name_len--; - } - - if (name_len > 0) { - status = ares_buf_append(buf, (const unsigned char *)name, name_len); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - return ares_buf_finish_str(buf, NULL); - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - ares_buf_destroy(buf); - return NULL; - /* LCOV_EXCL_STOP */ -} - -static void ares_qcache_expire(ares_qcache_t *cache, const ares_timeval_t *now) -{ - ares_slist_node_t *node; - - if (cache == NULL) { - return; - } - - while ((node = ares_slist_node_first(cache->expire)) != NULL) { - const ares_qcache_entry_t *entry = ares_slist_node_val(node); - - /* If now is NULL, we're flushing everything, so don't break */ - if (now != NULL && entry->expire_ts > now->sec) { - break; - } - - ares_htable_strvp_remove(cache->cache, entry->key); - ares_slist_node_destroy(node); - } -} - -void ares_qcache_flush(ares_qcache_t *cache) -{ - ares_qcache_expire(cache, NULL /* flush all */); -} - -void ares_qcache_destroy(ares_qcache_t *cache) -{ - if (cache == NULL) { - return; - } - - ares_htable_strvp_destroy(cache->cache); - ares_slist_destroy(cache->expire); - ares_free(cache); -} - -static int ares_qcache_entry_sort_cb(const void *arg1, const void *arg2) -{ - const ares_qcache_entry_t *entry1 = arg1; - const ares_qcache_entry_t *entry2 = arg2; - - if (entry1->expire_ts > entry2->expire_ts) { - return 1; - } - - if (entry1->expire_ts < entry2->expire_ts) { - return -1; - } - - return 0; -} - -static void ares_qcache_entry_destroy_cb(void *arg) -{ - ares_qcache_entry_t *entry = arg; - if (entry == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_free(entry->key); - ares_dns_record_destroy(entry->dnsrec); - ares_free(entry); -} - -ares_status_t ares_qcache_create(ares_rand_state *rand_state, - unsigned int max_ttl, - ares_qcache_t **cache_out) -{ - ares_status_t status = ARES_SUCCESS; - ares_qcache_t *cache; - - cache = ares_malloc_zero(sizeof(*cache)); - if (cache == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - cache->cache = ares_htable_strvp_create(NULL); - if (cache->cache == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - cache->expire = ares_slist_create(rand_state, ares_qcache_entry_sort_cb, - ares_qcache_entry_destroy_cb); - if (cache->expire == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - cache->max_ttl = max_ttl; - -done: - if (status != ARES_SUCCESS) { - *cache_out = NULL; - ares_qcache_destroy(cache); - return status; - } - - *cache_out = cache; - return status; -} - -static unsigned int ares_qcache_calc_minttl(ares_dns_record_t *dnsrec) -{ - unsigned int minttl = 0xFFFFFFFF; - size_t sect; - - for (sect = ARES_SECTION_ANSWER; sect <= ARES_SECTION_ADDITIONAL; sect++) { - size_t i; - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, (ares_dns_section_t)sect); - i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, (ares_dns_section_t)sect, i); - ares_dns_rec_type_t type = ares_dns_rr_get_type(rr); - unsigned int ttl = ares_dns_rr_get_ttl(rr); - - /* TTL is meaningless on these record types */ - if (type == ARES_REC_TYPE_OPT || type == ARES_REC_TYPE_SOA || - type == ARES_REC_TYPE_SIG) { - continue; - } - - if (ttl < minttl) { - minttl = ttl; - } - } - } - - return minttl; -} - -static unsigned int ares_qcache_soa_minimum(ares_dns_record_t *dnsrec) -{ - size_t i; - - /* RFC 2308 Section 5 says its the minimum of MINIMUM and the TTL of the - * record. */ - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_AUTHORITY); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_AUTHORITY, i); - ares_dns_rec_type_t type = ares_dns_rr_get_type(rr); - unsigned int ttl; - unsigned int minimum; - - if (type != ARES_REC_TYPE_SOA) { - continue; - } - - minimum = ares_dns_rr_get_u32(rr, ARES_RR_SOA_MINIMUM); - ttl = ares_dns_rr_get_ttl(rr); - - if (ttl > minimum) { - return minimum; - } - return ttl; - } - - return 0; -} - -/* On success, takes ownership of dnsrec */ -static ares_status_t ares_qcache_insert_int(ares_qcache_t *qcache, - ares_dns_record_t *qresp, - const ares_dns_record_t *qreq, - const ares_timeval_t *now) -{ - ares_qcache_entry_t *entry; - unsigned int ttl; - ares_dns_rcode_t rcode = ares_dns_record_get_rcode(qresp); - ares_dns_flags_t flags = ares_dns_record_get_flags(qresp); - - if (qcache == NULL || qresp == NULL) { - return ARES_EFORMERR; - } - - /* Only save NOERROR or NXDOMAIN */ - if (rcode != ARES_RCODE_NOERROR && rcode != ARES_RCODE_NXDOMAIN) { - return ARES_ENOTIMP; - } - - /* Don't save truncated queries */ - if (flags & ARES_FLAG_TC) { - return ARES_ENOTIMP; - } - - /* Look at SOA for NXDOMAIN for minimum */ - if (rcode == ARES_RCODE_NXDOMAIN) { - ttl = ares_qcache_soa_minimum(qresp); - } else { - ttl = ares_qcache_calc_minttl(qresp); - } - - if (ttl > qcache->max_ttl) { - ttl = qcache->max_ttl; - } - - /* Don't cache something that is already expired */ - if (ttl == 0) { - return ARES_EREFUSED; - } - - entry = ares_malloc_zero(sizeof(*entry)); - if (entry == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - entry->dnsrec = qresp; - entry->expire_ts = (time_t)now->sec + (time_t)ttl; - entry->insert_ts = (time_t)now->sec; - - /* We can't guarantee the server responded with the same flags as the - * request had, so we have to re-parse the request in order to generate the - * key for caching, but we'll only do this once we know for sure we really - * want to cache it */ - entry->key = ares_qcache_calc_key(qreq); - if (entry->key == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (!ares_htable_strvp_insert(qcache->cache, entry->key, entry)) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (ares_slist_insert(qcache->expire, entry) == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - if (entry != NULL && entry->key != NULL) { - ares_htable_strvp_remove(qcache->cache, entry->key); - ares_free(entry->key); - ares_free(entry); - } - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ -} - -ares_status_t ares_qcache_fetch(ares_channel_t *channel, - const ares_timeval_t *now, - const ares_dns_record_t *dnsrec, - const ares_dns_record_t **dnsrec_resp) -{ - char *key = NULL; - ares_qcache_entry_t *entry; - ares_status_t status = ARES_SUCCESS; - - if (channel == NULL || dnsrec == NULL || dnsrec_resp == NULL) { - return ARES_EFORMERR; - } - - if (channel->qcache == NULL) { - return ARES_ENOTFOUND; - } - - ares_qcache_expire(channel->qcache, now); - - key = ares_qcache_calc_key(dnsrec); - if (key == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - entry = ares_htable_strvp_get_direct(channel->qcache->cache, key); - if (entry == NULL) { - status = ARES_ENOTFOUND; - goto done; - } - - ares_dns_record_ttl_decrement(entry->dnsrec, - (unsigned int)(now->sec - entry->insert_ts)); - - *dnsrec_resp = entry->dnsrec; - -done: - ares_free(key); - return status; -} - -ares_status_t ares_qcache_insert(ares_channel_t *channel, - const ares_timeval_t *now, - const ares_query_t *query, - ares_dns_record_t *dnsrec) -{ - return ares_qcache_insert_int(channel->qcache, dnsrec, query->query, now); -} diff --git a/vendor/c-ares/src/lib/ares_query.c b/vendor/c-ares/src/lib/ares_query.c deleted file mode 100644 index ca3b6a9b7..000000000 --- a/vendor/c-ares/src/lib/ares_query.c +++ /dev/null @@ -1,151 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -typedef struct { - ares_callback_dnsrec callback; - void *arg; -} ares_query_dnsrec_arg_t; - -static void ares_query_dnsrec_cb(void *arg, ares_status_t status, - size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - ares_query_dnsrec_arg_t *qquery = arg; - - if (status != ARES_SUCCESS) { - qquery->callback(qquery->arg, status, timeouts, dnsrec); - } else { - size_t ancount; - ares_dns_rcode_t rcode; - /* Pull the response code and answer count from the packet and convert any - * errors. - */ - rcode = ares_dns_record_get_rcode(dnsrec); - ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - status = ares_dns_query_reply_tostatus(rcode, ancount); - qquery->callback(qquery->arg, status, timeouts, dnsrec); - } - ares_free(qquery); -} - -ares_status_t ares_query_nolock(ares_channel_t *channel, const char *name, - ares_dns_class_t dnsclass, - ares_dns_rec_type_t type, - ares_callback_dnsrec callback, void *arg, - unsigned short *qid) -{ - ares_status_t status; - ares_dns_record_t *dnsrec = NULL; - ares_dns_flags_t flags = 0; - ares_query_dnsrec_arg_t *qquery = NULL; - - if (channel == NULL || name == NULL || callback == NULL) { - /* LCOV_EXCL_START: DefensiveCoding */ - status = ARES_EFORMERR; - if (callback != NULL) { - callback(arg, status, 0, NULL); - } - return status; - /* LCOV_EXCL_STOP */ - } - - if (!(channel->flags & ARES_FLAG_NORECURSE)) { - flags |= ARES_FLAG_RD; - } - - status = ares_dns_record_create_query( - &dnsrec, name, dnsclass, type, 0, flags, - (size_t)(channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : 0); - if (status != ARES_SUCCESS) { - callback(arg, status, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */ - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - qquery = ares_malloc(sizeof(*qquery)); - if (qquery == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - status = ARES_ENOMEM; - callback(arg, status, 0, NULL); - ares_dns_record_destroy(dnsrec); - return status; - /* LCOV_EXCL_STOP */ - } - - qquery->callback = callback; - qquery->arg = arg; - - /* Send it off. qcallback will be called when we get an answer. */ - status = ares_send_nolock(channel, NULL, 0, dnsrec, ares_query_dnsrec_cb, - qquery, qid); - - ares_dns_record_destroy(dnsrec); - return status; -} - -ares_status_t ares_query_dnsrec(ares_channel_t *channel, const char *name, - ares_dns_class_t dnsclass, - ares_dns_rec_type_t type, - ares_callback_dnsrec callback, void *arg, - unsigned short *qid) -{ - ares_status_t status; - - if (channel == NULL) { - return ARES_EFORMERR; - } - - ares_channel_lock(channel); - status = ares_query_nolock(channel, name, dnsclass, type, callback, arg, qid); - ares_channel_unlock(channel); - return status; -} - -void ares_query(ares_channel_t *channel, const char *name, int dnsclass, - int type, ares_callback callback, void *arg) -{ - void *carg = NULL; - - if (channel == NULL) { - return; - } - - carg = ares_dnsrec_convert_arg(callback, arg); - if (carg == NULL) { - callback(arg, ARES_ENOMEM, 0, NULL, 0); /* LCOV_EXCL_LINE: OutOfMemory */ - return; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - ares_query_dnsrec(channel, name, (ares_dns_class_t)dnsclass, - (ares_dns_rec_type_t)type, ares_dnsrec_convert_cb, carg, - NULL); -} diff --git a/vendor/c-ares/src/lib/ares_search.c b/vendor/c-ares/src/lib/ares_search.c deleted file mode 100644 index c605caf42..000000000 --- a/vendor/c-ares/src/lib/ares_search.c +++ /dev/null @@ -1,623 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_STRINGS_H -# include -#endif - -struct search_query { - /* Arguments passed to ares_search_dnsrec() */ - ares_channel_t *channel; - ares_callback_dnsrec callback; - void *arg; - - /* Duplicate of DNS record passed to ares_search_dnsrec() */ - ares_dns_record_t *dnsrec; - - /* Search order for names */ - char **names; - size_t names_cnt; - - /* State tracking progress through the search query */ - size_t next_name_idx; /* next name index being attempted */ - size_t timeouts; /* number of timeouts we saw for this request */ - ares_bool_t ever_got_nodata; /* did we ever get ARES_ENODATA along the way? */ -}; - -static void squery_free(struct search_query *squery) -{ - if (squery == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - ares_strsplit_free(squery->names, squery->names_cnt); - ares_dns_record_destroy(squery->dnsrec); - ares_free(squery); -} - -/* End a search query by invoking the user callback and freeing the - * search_query structure. - */ -static void end_squery(struct search_query *squery, ares_status_t status, - const ares_dns_record_t *dnsrec) -{ - squery->callback(squery->arg, status, squery->timeouts, dnsrec); - squery_free(squery); -} - -static void search_callback(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec); - -static ares_status_t ares_search_next(ares_channel_t *channel, - struct search_query *squery, - ares_bool_t *skip_cleanup) -{ - ares_status_t status; - - *skip_cleanup = ARES_FALSE; - - /* Misuse check */ - if (squery->next_name_idx >= squery->names_cnt) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - status = ares_dns_record_query_set_name( - squery->dnsrec, 0, squery->names[squery->next_name_idx++]); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_send_nolock(channel, NULL, 0, squery->dnsrec, search_callback, - squery, NULL); - - if (status != ARES_EFORMERR) { - *skip_cleanup = ARES_TRUE; - } - - return status; -} - -static void search_callback(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - struct search_query *squery = (struct search_query *)arg; - ares_channel_t *channel = squery->channel; - - ares_status_t mystatus; - ares_bool_t skip_cleanup = ARES_FALSE; - - squery->timeouts += timeouts; - - if (dnsrec) { - ares_dns_rcode_t rcode = ares_dns_record_get_rcode(dnsrec); - size_t ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - mystatus = ares_dns_query_reply_tostatus(rcode, ancount); - } else { - mystatus = status; - } - - switch (mystatus) { - case ARES_ENODATA: - case ARES_ENOTFOUND: - break; - case ARES_ESERVFAIL: - case ARES_EREFUSED: - /* Issue #852, systemd-resolved may return SERVFAIL or REFUSED on a - * single label domain name. */ - if (ares_name_label_cnt(squery->names[squery->next_name_idx - 1]) != 1) { - end_squery(squery, mystatus, dnsrec); - return; - } - break; - default: - end_squery(squery, mystatus, dnsrec); - return; - } - - /* If we ever get ARES_ENODATA along the way, record that; if the search - * should run to the very end and we got at least one ARES_ENODATA, - * then callers like ares_gethostbyname() may want to try a T_A search - * even if the last domain we queried for T_AAAA resource records - * returned ARES_ENOTFOUND. - */ - if (mystatus == ARES_ENODATA) { - squery->ever_got_nodata = ARES_TRUE; - } - - if (squery->next_name_idx < squery->names_cnt) { - mystatus = ares_search_next(channel, squery, &skip_cleanup); - if (mystatus != ARES_SUCCESS && !skip_cleanup) { - end_squery(squery, mystatus, NULL); - } - return; - } - - /* We have no more domains to search, return an appropriate response. */ - if (mystatus == ARES_ENOTFOUND && squery->ever_got_nodata) { - end_squery(squery, ARES_ENODATA, NULL); - return; - } - - end_squery(squery, mystatus, NULL); -} - -/* Determine if the domain should be looked up as-is, or if it is eligible - * for search by appending domains */ -static ares_bool_t ares_search_eligible(const ares_channel_t *channel, - const char *name) -{ - size_t len = ares_strlen(name); - - /* Name ends in '.', cannot search */ - if (len && name[len - 1] == '.') { - return ARES_FALSE; - } - - if (channel->flags & ARES_FLAG_NOSEARCH) { - return ARES_FALSE; - } - - return ARES_TRUE; -} - -size_t ares_name_label_cnt(const char *name) -{ - const char *p; - size_t ndots = 0; - - if (name == NULL) { - return 0; - } - - for (p = name; p != NULL && *p != 0; p++) { - if (*p == '.') { - ndots++; - } - } - - /* Label count is 1 greater than ndots */ - return ndots + 1; -} - -ares_status_t ares_search_name_list(const ares_channel_t *channel, - const char *name, char ***names, - size_t *names_len) -{ - ares_status_t status; - char **list = NULL; - size_t list_len = 0; - char *alias = NULL; - size_t ndots = 0; - size_t idx = 0; - size_t i; - - /* Perform HOSTALIASES resolution */ - status = ares_lookup_hostaliases(channel, name, &alias); - if (status == ARES_SUCCESS) { - /* If hostalias succeeds, there is no searching, it is used as-is */ - list_len = 1; - list = ares_malloc_zero(sizeof(*list) * list_len); - if (list == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - list[0] = alias; - alias = NULL; - goto done; - } else if (status != ARES_ENOTFOUND) { - goto done; - } - - /* See if searching is eligible at all, if not, look up as-is only */ - if (!ares_search_eligible(channel, name)) { - list_len = 1; - list = ares_malloc_zero(sizeof(*list) * list_len); - if (list == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - list[0] = ares_strdup(name); - if (list[0] == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } else { - status = ARES_SUCCESS; - } - goto done; - } - - /* Count the number of dots in name, 1 less than label count */ - ndots = ares_name_label_cnt(name); - if (ndots > 0) { - ndots--; - } - - /* Allocate an entry for each search domain, plus one for as-is */ - list_len = channel->ndomains + 1; - list = ares_malloc_zero(sizeof(*list) * list_len); - if (list == NULL) { - status = ARES_ENOMEM; - goto done; - } - - /* Set status here, its possible there are no search domains at all, so - * status may be ARES_ENOTFOUND from ares_lookup_hostaliases(). */ - status = ARES_SUCCESS; - - /* Try as-is first */ - if (ndots >= channel->ndots) { - list[idx] = ares_strdup(name); - if (list[idx] == NULL) { - status = ARES_ENOMEM; - goto done; - } - idx++; - } - - /* Append each search suffix to the name */ - for (i = 0; i < channel->ndomains; i++) { - status = ares_cat_domain(name, channel->domains[i], &list[idx]); - if (status != ARES_SUCCESS) { - goto done; - } - idx++; - } - - /* Try as-is last */ - if (ndots < channel->ndots) { - list[idx] = ares_strdup(name); - if (list[idx] == NULL) { - status = ARES_ENOMEM; - goto done; - } - idx++; - } - - -done: - if (status == ARES_SUCCESS) { - *names = list; - *names_len = list_len; - } else { - ares_strsplit_free(list, list_len); - } - - ares_free(alias); - return status; -} - -static ares_status_t ares_search_int(ares_channel_t *channel, - const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, void *arg) -{ - struct search_query *squery = NULL; - const char *name; - ares_status_t status = ARES_SUCCESS; - ares_bool_t skip_cleanup = ARES_FALSE; - - /* Extract the name for the search. Note that searches are only supported for - * DNS records containing a single query. - */ - if (ares_dns_record_query_cnt(dnsrec) != 1) { - status = ARES_EBADQUERY; - goto fail; - } - - status = ares_dns_record_query_get(dnsrec, 0, &name, NULL, NULL); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */ - if (ares_is_onion_domain(name)) { - status = ARES_ENOTFOUND; - goto fail; - } - - /* Allocate a search_query structure to hold the state necessary for - * doing multiple lookups. - */ - squery = ares_malloc_zero(sizeof(*squery)); - if (squery == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - squery->channel = channel; - - /* Duplicate DNS record since, name will need to be rewritten */ - squery->dnsrec = ares_dns_record_duplicate(dnsrec); - if (squery->dnsrec == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - squery->callback = callback; - squery->arg = arg; - squery->timeouts = 0; - squery->ever_got_nodata = ARES_FALSE; - - status = - ares_search_name_list(channel, name, &squery->names, &squery->names_cnt); - if (status != ARES_SUCCESS) { - goto fail; - } - - status = ares_search_next(channel, squery, &skip_cleanup); - if (status != ARES_SUCCESS) { - goto fail; - } - - return status; - -fail: - if (!skip_cleanup) { - squery_free(squery); - callback(arg, status, 0, NULL); - } - return status; -} - -/* Callback argument structure passed to ares_dnsrec_convert_cb(). */ -typedef struct { - ares_callback callback; - void *arg; -} dnsrec_convert_arg_t; - -/*! Function to create callback arg for converting from ares_callback_dnsrec - * to ares_calback */ -void *ares_dnsrec_convert_arg(ares_callback callback, void *arg) -{ - dnsrec_convert_arg_t *carg = ares_malloc_zero(sizeof(*carg)); - if (carg == NULL) { - return NULL; - } - carg->callback = callback; - carg->arg = arg; - return carg; -} - -/*! Callback function used to convert from the ares_callback_dnsrec prototype to - * the ares_callback prototype, by writing the result and passing that to - * the inner callback. - */ -void ares_dnsrec_convert_cb(void *arg, ares_status_t status, size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - dnsrec_convert_arg_t *carg = arg; - unsigned char *abuf = NULL; - size_t alen = 0; - - if (dnsrec != NULL) { - ares_status_t mystatus = ares_dns_write(dnsrec, &abuf, &alen); - if (mystatus != ARES_SUCCESS) { - status = mystatus; - } - } - - carg->callback(carg->arg, (int)status, (int)timeouts, abuf, (int)alen); - - ares_free(abuf); - ares_free(carg); -} - -/* Search for a DNS name with given class and type. Wrapper around - * ares_search_int() where the DNS record to search is first constructed. - */ -void ares_search(ares_channel_t *channel, const char *name, int dnsclass, - int type, ares_callback callback, void *arg) -{ - ares_status_t status; - ares_dns_record_t *dnsrec = NULL; - size_t max_udp_size; - ares_dns_flags_t rd_flag; - void *carg = NULL; - if (channel == NULL || name == NULL) { - return; - } - - /* For now, ares_search_int() uses the ares_callback prototype. We need to - * wrap the callback passed to this function in ares_dnsrec_convert_cb, to - * convert from ares_callback_dnsrec to ares_callback. Allocate the convert - * arg structure here. - */ - carg = ares_dnsrec_convert_arg(callback, arg); - if (carg == NULL) { - callback(arg, ARES_ENOMEM, 0, NULL, 0); - return; - } - - rd_flag = !(channel->flags & ARES_FLAG_NORECURSE) ? ARES_FLAG_RD : 0; - max_udp_size = (channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : 0; - status = ares_dns_record_create_query( - &dnsrec, name, (ares_dns_class_t)dnsclass, (ares_dns_rec_type_t)type, 0, - rd_flag, max_udp_size); - if (status != ARES_SUCCESS) { - callback(arg, (int)status, 0, NULL, 0); - ares_free(carg); - return; - } - - ares_channel_lock(channel); - ares_search_int(channel, dnsrec, ares_dnsrec_convert_cb, carg); - ares_channel_unlock(channel); - - ares_dns_record_destroy(dnsrec); -} - -/* Search for a DNS record. Wrapper around ares_search_int(). */ -ares_status_t ares_search_dnsrec(ares_channel_t *channel, - const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, void *arg) -{ - ares_status_t status; - - if (channel == NULL || dnsrec == NULL || callback == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_channel_lock(channel); - status = ares_search_int(channel, dnsrec, callback, arg); - ares_channel_unlock(channel); - - return status; -} - -/* Concatenate two domains. */ -ares_status_t ares_cat_domain(const char *name, const char *domain, char **s) -{ - size_t nlen = ares_strlen(name); - size_t dlen = ares_strlen(domain); - - *s = ares_malloc(nlen + 1 + dlen + 1); - if (!*s) { - return ARES_ENOMEM; - } - memcpy(*s, name, nlen); - (*s)[nlen] = '.'; - if (ares_streq(domain, ".")) { - /* Avoid appending the root domain to the separator, which would set *s to - an ill-formed value (ending in two consecutive dots). */ - dlen = 0; - } - memcpy(*s + nlen + 1, domain, dlen); - (*s)[nlen + 1 + dlen] = 0; - return ARES_SUCCESS; -} - -ares_status_t ares_lookup_hostaliases(const ares_channel_t *channel, - const char *name, char **alias) -{ - ares_status_t status = ARES_SUCCESS; - const char *hostaliases = NULL; - ares_buf_t *buf = NULL; - ares_array_t *lines = NULL; - size_t num; - size_t i; - - if (channel == NULL || name == NULL || alias == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *alias = NULL; - - /* Configuration says to not perform alias lookup */ - if (channel->flags & ARES_FLAG_NOALIASES) { - return ARES_ENOTFOUND; - } - - /* If a domain has a '.', its not allowed to perform an alias lookup */ - if (strchr(name, '.') != NULL) { - return ARES_ENOTFOUND; - } - - hostaliases = getenv("HOSTALIASES"); - if (hostaliases == NULL) { - status = ARES_ENOTFOUND; - goto done; - } - - buf = ares_buf_create(); - if (buf == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_load_file(hostaliases, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - /* The HOSTALIASES file is structured as one alias per line. The first - * field in the line is the simple hostname with no periods, followed by - * whitespace, then the full domain name, e.g.: - * - * c-ares www.c-ares.org - * curl www.curl.se - */ - - status = ares_buf_split(buf, (const unsigned char *)"\n", 1, - ARES_BUF_SPLIT_TRIM, 0, &lines); - if (status != ARES_SUCCESS) { - goto done; - } - - num = ares_array_len(lines); - for (i = 0; i < num; i++) { - ares_buf_t **bufptr = ares_array_at(lines, i); - ares_buf_t *line = *bufptr; - char hostname[64] = ""; - char fqdn[256] = ""; - - /* Pull off hostname */ - ares_buf_tag(line); - ares_buf_consume_nonwhitespace(line); - if (ares_buf_tag_fetch_string(line, hostname, sizeof(hostname)) != - ARES_SUCCESS) { - continue; - } - - /* Match hostname */ - if (!ares_strcaseeq(hostname, name)) { - continue; - } - - /* consume whitespace */ - ares_buf_consume_whitespace(line, ARES_TRUE); - - /* pull off fqdn */ - ares_buf_tag(line); - ares_buf_consume_nonwhitespace(line); - if (ares_buf_tag_fetch_string(line, fqdn, sizeof(fqdn)) != ARES_SUCCESS || - ares_strlen(fqdn) == 0) { - continue; - } - - /* Validate characterset */ - if (!ares_is_hostname(fqdn)) { - continue; - } - - *alias = ares_strdup(fqdn); - if (*alias == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Good! */ - status = ARES_SUCCESS; - goto done; - } - - status = ARES_ENOTFOUND; - -done: - ares_buf_destroy(buf); - ares_array_destroy(lines); - - return status; -} diff --git a/vendor/c-ares/src/lib/ares_send.c b/vendor/c-ares/src/lib/ares_send.c deleted file mode 100644 index 6efa9580b..000000000 --- a/vendor/c-ares/src/lib/ares_send.c +++ /dev/null @@ -1,300 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#include "ares_nameser.h" - -static unsigned short generate_unique_qid(ares_channel_t *channel) -{ - unsigned short id; - - do { - id = ares_generate_new_id(channel->rand_state); - } while (ares_htable_szvp_get(channel->queries_by_qid, id, NULL)); - - return id; -} - -/* https://datatracker.ietf.org/doc/html/draft-vixie-dnsext-dns0x20-00 */ -static ares_status_t ares_apply_dns0x20(ares_channel_t *channel, - ares_dns_record_t *dnsrec) -{ - ares_status_t status = ARES_SUCCESS; - const char *name = NULL; - char dns0x20name[256]; - unsigned char randdata[256 / 8]; - size_t len; - size_t remaining_bits; - size_t total_bits; - size_t i; - - status = ares_dns_record_query_get(dnsrec, 0, &name, NULL, NULL); - if (status != ARES_SUCCESS) { - goto done; - } - - len = ares_strlen(name); - if (len == 0) { - return ARES_SUCCESS; - } - - if (len >= sizeof(dns0x20name)) { - status = ARES_EBADNAME; - goto done; - } - - memset(dns0x20name, 0, sizeof(dns0x20name)); - - /* Fetch the minimum amount of random data we'd need for the string, which - * is 1 bit per byte */ - total_bits = ((len + 7) / 8) * 8; - remaining_bits = total_bits; - ares_rand_bytes(channel->rand_state, randdata, total_bits / 8); - - /* Randomly apply 0x20 to name */ - for (i = 0; i < len; i++) { - size_t bit; - - /* Only apply 0x20 to alpha characters */ - if (!ares_isalpha(name[i])) { - dns0x20name[i] = name[i]; - continue; - } - - /* coin flip */ - bit = total_bits - remaining_bits; - if (randdata[bit / 8] & (1 << (bit % 8))) { - dns0x20name[i] = name[i] | 0x20; /* Set 0x20 */ - } else { - dns0x20name[i] = (char)(((unsigned char)name[i]) & 0xDF); /* Unset 0x20 */ - } - remaining_bits--; - } - - status = ares_dns_record_query_set_name(dnsrec, 0, dns0x20name); - -done: - return status; -} - -ares_status_t ares_send_nolock(ares_channel_t *channel, ares_server_t *server, - ares_send_flags_t flags, - const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, void *arg, - unsigned short *qid) -{ - ares_query_t *query; - ares_timeval_t now; - ares_status_t status; - unsigned short id = generate_unique_qid(channel); - const ares_dns_record_t *dnsrec_resp = NULL; - - ares_tvnow(&now); - - if (ares_slist_len(channel->servers) == 0) { - callback(arg, ARES_ENOSERVER, 0, NULL); - return ARES_ENOSERVER; - } - - if (!(flags & ARES_SEND_FLAG_NOCACHE)) { - /* Check query cache */ - status = ares_qcache_fetch(channel, &now, dnsrec, &dnsrec_resp); - if (status != ARES_ENOTFOUND) { - /* ARES_SUCCESS means we retrieved the cache, anything else is a critical - * failure, all result in termination */ - callback(arg, status, 0, dnsrec_resp); - return status; - } - } - - /* Allocate space for query and allocated fields. */ - query = ares_malloc(sizeof(ares_query_t)); - if (!query) { - callback(arg, ARES_ENOMEM, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - memset(query, 0, sizeof(*query)); - - query->channel = channel; - query->qid = id; - query->timeout.sec = 0; - query->timeout.usec = 0; - query->using_tcp = - (channel->flags & ARES_FLAG_USEVC) ? ARES_TRUE : ARES_FALSE; - - /* Duplicate Query */ - status = ares_dns_record_duplicate_ex(&query->query, dnsrec); - if (status != ARES_SUCCESS) { - /* Sometimes we might get a EBADRESP response from duplicate due to - * the way it works (write and parse), rewrite it to EBADQUERY. */ - if (status == ARES_EBADRESP) { - status = ARES_EBADQUERY; - } - ares_free(query); - callback(arg, status, 0, NULL); - return status; - } - - ares_dns_record_set_id(query->query, id); - - if (channel->flags & ARES_FLAG_DNS0x20 && !query->using_tcp) { - status = ares_apply_dns0x20(channel, query->query); - if (status != ARES_SUCCESS) { - /* LCOV_EXCL_START: OutOfMemory */ - callback(arg, status, 0, NULL); - ares_free_query(query); - return status; - /* LCOV_EXCL_STOP */ - } - } - - /* Fill in query arguments. */ - query->callback = callback; - query->arg = arg; - - /* Initialize query status. */ - query->try_count = 0; - - if (flags & ARES_SEND_FLAG_NORETRY) { - query->no_retries = ARES_TRUE; - } - - query->error_status = ARES_SUCCESS; - query->timeouts = 0; - - /* Initialize our list nodes. */ - query->node_queries_by_timeout = NULL; - query->node_queries_to_conn = NULL; - - /* Chain the query into the list of all queries. */ - query->node_all_queries = ares_llist_insert_last(channel->all_queries, query); - if (query->node_all_queries == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - callback(arg, ARES_ENOMEM, 0, NULL); - ares_free_query(query); - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ - } - - /* Keep track of queries bucketed by qid, so we can process DNS - * responses quickly. - */ - if (!ares_htable_szvp_insert(channel->queries_by_qid, query->qid, query)) { - /* LCOV_EXCL_START: OutOfMemory */ - callback(arg, ARES_ENOMEM, 0, NULL); - ares_free_query(query); - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ - } - - /* Perform the first query action. */ - - status = ares_send_query(server, query, &now); - if (status == ARES_SUCCESS && qid) { - *qid = id; - } - return status; -} - -ares_status_t ares_send_dnsrec(ares_channel_t *channel, - const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, void *arg, - unsigned short *qid) -{ - ares_status_t status; - - if (channel == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_channel_lock(channel); - - status = ares_send_nolock(channel, NULL, 0, dnsrec, callback, arg, qid); - - ares_channel_unlock(channel); - - return status; -} - -void ares_send(ares_channel_t *channel, const unsigned char *qbuf, int qlen, - ares_callback callback, void *arg) -{ - ares_dns_record_t *dnsrec = NULL; - ares_status_t status; - void *carg = NULL; - - if (channel == NULL) { - return; - } - - /* Verify that the query is at least long enough to hold the header. */ - if (qlen < HFIXEDSZ || qlen >= (1 << 16)) { - callback(arg, ARES_EBADQUERY, 0, NULL, 0); - return; - } - - status = ares_dns_parse(qbuf, (size_t)qlen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - callback(arg, (int)status, 0, NULL, 0); - return; - } - - carg = ares_dnsrec_convert_arg(callback, arg); - if (carg == NULL) { - /* LCOV_EXCL_START: OutOfMemory */ - status = ARES_ENOMEM; - ares_dns_record_destroy(dnsrec); - callback(arg, (int)status, 0, NULL, 0); - return; - /* LCOV_EXCL_STOP */ - } - - ares_send_dnsrec(channel, dnsrec, ares_dnsrec_convert_cb, carg, NULL); - - ares_dns_record_destroy(dnsrec); -} - -size_t ares_queue_active_queries(const ares_channel_t *channel) -{ - size_t len; - - if (channel == NULL) { - return 0; - } - - ares_channel_lock(channel); - - len = ares_llist_len(channel->all_queries); - - ares_channel_unlock(channel); - - return len; -} diff --git a/vendor/c-ares/src/lib/ares_set_socket_functions.c b/vendor/c-ares/src/lib/ares_set_socket_functions.c deleted file mode 100644 index 7216ffa93..000000000 --- a/vendor/c-ares/src/lib/ares_set_socket_functions.c +++ /dev/null @@ -1,588 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#ifdef HAVE_SYS_UIO_H -# include -#endif -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETINET_TCP_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef NETWARE -# include -#endif - -#include -#include -#include - - -#if defined(__linux__) && defined(TCP_FASTOPEN_CONNECT) -# define TFO_SUPPORTED 1 -# define TFO_SKIP_CONNECT 0 -# define TFO_USE_SENDTO 0 -# define TFO_USE_CONNECTX 0 -# define TFO_CLIENT_SOCKOPT TCP_FASTOPEN_CONNECT -#elif defined(__FreeBSD__) && defined(TCP_FASTOPEN) -# define TFO_SUPPORTED 1 -# define TFO_SKIP_CONNECT 1 -# define TFO_USE_SENDTO 1 -# define TFO_USE_CONNECTX 0 -# define TFO_CLIENT_SOCKOPT TCP_FASTOPEN -#elif defined(__APPLE__) && defined(HAVE_CONNECTX) -# define TFO_SUPPORTED 1 -# define TFO_SKIP_CONNECT 0 -# define TFO_USE_SENDTO 0 -# define TFO_USE_CONNECTX 1 -# undef TFO_CLIENT_SOCKOPT -#else -# define TFO_SUPPORTED 0 -#endif - -#ifndef HAVE_WRITEV -/* Structure for scatter/gather I/O. */ -struct iovec { - void *iov_base; /* Pointer to data. */ - size_t iov_len; /* Length of data. */ -}; -#endif - -ares_status_t - ares_set_socket_functions_ex(ares_channel_t *channel, - const struct ares_socket_functions_ex *funcs, - void *user_data) -{ - unsigned int known_versions[] = { 1 }; - size_t i; - - if (channel == NULL || funcs == NULL) { - return ARES_EFORMERR; - } - - /* Check to see if we know the version referenced */ - for (i = 0; i < sizeof(known_versions) / sizeof(*known_versions); i++) { - if (funcs->version == known_versions[i]) { - break; - } - } - if (i == sizeof(known_versions) / sizeof(*known_versions)) { - return ARES_EFORMERR; - } - - memset(&channel->sock_funcs, 0, sizeof(channel->sock_funcs)); - - /* Copy individually for ABI compliance. memcpy() with a sizeof would do - * invalid reads */ - if (funcs->version >= 1) { - if (funcs->asocket == NULL || funcs->aclose == NULL || - funcs->asetsockopt == NULL || funcs->aconnect == NULL || - funcs->arecvfrom == NULL || funcs->asendto == NULL) { - return ARES_EFORMERR; - } - channel->sock_funcs.version = funcs->version; - channel->sock_funcs.flags = funcs->flags; - channel->sock_funcs.asocket = funcs->asocket; - channel->sock_funcs.aclose = funcs->aclose; - channel->sock_funcs.asetsockopt = funcs->asetsockopt; - channel->sock_funcs.aconnect = funcs->aconnect; - channel->sock_funcs.arecvfrom = funcs->arecvfrom; - channel->sock_funcs.asendto = funcs->asendto; - channel->sock_funcs.agetsockname = funcs->agetsockname; - channel->sock_funcs.abind = funcs->abind; - } - - /* Implement newer versions here ...*/ - - - channel->sock_func_cb_data = user_data; - - return ARES_SUCCESS; -} - -static int setsocknonblock(ares_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */) -{ -#if defined(HAVE_FCNTL_O_NONBLOCK) - - /* most recent unix versions */ - int flags; - flags = fcntl(sockfd, F_GETFL, 0); - if (nonblock) { - return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); - } else { - return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); /* LCOV_EXCL_LINE */ - } - -#elif defined(HAVE_IOCTL_FIONBIO) - - /* older unix versions */ - int flags = nonblock ? 1 : 0; - return ioctl(sockfd, FIONBIO, &flags); - -#elif defined(HAVE_IOCTLSOCKET_FIONBIO) - -# ifdef WATT32 - char flags = nonblock ? 1 : 0; -# else - /* Windows */ - unsigned long flags = nonblock ? 1UL : 0UL; -# endif - return ioctlsocket(sockfd, (long)FIONBIO, &flags); - -#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO) - - /* Amiga */ - long flags = nonblock ? 1L : 0L; - return IoctlSocket(sockfd, FIONBIO, flags); - -#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK) - - /* BeOS */ - long b = nonblock ? 1L : 0L; - return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); - -#else -# error "no non-blocking method was found/used/set" -#endif -} - -static int default_aclose(ares_socket_t sock, void *user_data) -{ - (void)user_data; - -#if defined(HAVE_CLOSESOCKET) - return closesocket(sock); -#elif defined(HAVE_CLOSESOCKET_CAMEL) - return CloseSocket(sock); -#elif defined(HAVE_CLOSE_S) - return close_s(sock); -#else - return close(sock); -#endif -} - -static ares_socket_t default_asocket(int domain, int type, int protocol, - void *user_data) -{ - ares_socket_t s; - (void)user_data; - - s = socket(domain, type, protocol); - if (s == ARES_SOCKET_BAD) { - return s; - } - - if (setsocknonblock(s, 1) != 0) { - goto fail; /* LCOV_EXCL_LINE */ - } - -#if defined(FD_CLOEXEC) && !defined(MSDOS) - /* Configure the socket fd as close-on-exec. */ - if (fcntl(s, F_SETFD, FD_CLOEXEC) != 0) { - goto fail; /* LCOV_EXCL_LINE */ - } -#endif - - /* No need to emit SIGPIPE on socket errors */ -#if defined(SO_NOSIGPIPE) - { - int opt = 1; - (void)setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&opt, sizeof(opt)); - } -#endif - - - if (type == SOCK_STREAM) { - int opt = 1; - -#ifdef TCP_NODELAY - /* - * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not - * in configure_socket). In general, in DNS lookups we're pretty much - * interested in firing off a single request and then waiting for a reply, - * so batching isn't very interesting. - */ - if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)) != - 0) { - goto fail; - } -#endif - } - -#if defined(IPV6_V6ONLY) && defined(USE_WINSOCK) - /* Support for IPv4-mapped IPv6 addresses. - * Linux kernel, NetBSD, FreeBSD and Darwin: default is off; - * Windows Vista and later: default is on; - * DragonFly BSD: acts like off, and dummy setting; - * OpenBSD and earlier Windows: unsupported. - * Linux: controlled by /proc/sys/net/ipv6/bindv6only. - */ - if (domain == PF_INET6) { - int on = 0; - (void)setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, sizeof(on)); - } -#endif - - return s; - -fail: - default_aclose(s, user_data); - return ARES_SOCKET_BAD; -} - -static int default_asetsockopt(ares_socket_t sock, ares_socket_opt_t opt, - const void *val, ares_socklen_t val_size, - void *user_data) -{ - switch (opt) { - case ARES_SOCKET_OPT_SENDBUF_SIZE: - if (val_size != sizeof(int)) { - SET_SOCKERRNO(EINVAL); - return -1; - } - return setsockopt(sock, SOL_SOCKET, SO_SNDBUF, val, val_size); - - case ARES_SOCKET_OPT_RECVBUF_SIZE: - if (val_size != sizeof(int)) { - SET_SOCKERRNO(EINVAL); - return -1; - } - return setsockopt(sock, SOL_SOCKET, SO_RCVBUF, val, val_size); - - case ARES_SOCKET_OPT_BIND_DEVICE: - /* Count the number of characters before NULL terminator then - * validate those are all printable */ - if (!ares_str_isprint(val, ares_strnlen(val, (size_t)val_size))) { - SET_SOCKERRNO(EINVAL); - return -1; - } -#ifdef SO_BINDTODEVICE - return setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, val, val_size); -#else - SET_SOCKERRNO(ENOSYS); - return -1; -#endif - - case ARES_SOCKET_OPT_TCP_FASTOPEN: - if (val_size != sizeof(ares_bool_t)) { - SET_SOCKERRNO(EINVAL); - return -1; - } -#if defined(TFO_CLIENT_SOCKOPT) - { - int oval; - const ares_bool_t *pval = val; - oval = (int)*pval; - return setsockopt(sock, IPPROTO_TCP, TFO_CLIENT_SOCKOPT, (void *)&oval, - sizeof(oval)); - } -#elif TFO_SUPPORTED - return 0; -#else - SET_SOCKERRNO(ENOSYS); - return -1; -#endif - } - - (void)user_data; - SET_SOCKERRNO(ENOSYS); - return -1; -} - -static int default_aconnect(ares_socket_t sock, const struct sockaddr *address, - ares_socklen_t address_len, unsigned int flags, - void *user_data) -{ - (void)user_data; - -#if defined(TFO_SKIP_CONNECT) && TFO_SKIP_CONNECT - if (flags & ARES_SOCKET_CONN_TCP_FASTOPEN) { - return 0; - } - return connect(sock, address, address_len); -#elif defined(TFO_USE_CONNECTX) && TFO_USE_CONNECTX - if (flags & ARES_SOCKET_CONN_TCP_FASTOPEN) { - sa_endpoints_t endpoints; - - memset(&endpoints, 0, sizeof(endpoints)); - endpoints.sae_dstaddr = address; - endpoints.sae_dstaddrlen = address_len; - - return connectx(sock, &endpoints, SAE_ASSOCID_ANY, - CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE, - NULL, 0, NULL, NULL); - } else { - return connect(sock, address, address_len); - } -#else - (void)flags; - return connect(sock, address, address_len); -#endif -} - -static ares_ssize_t default_arecvfrom(ares_socket_t sock, void *buffer, - size_t length, int flags, - struct sockaddr *address, - ares_socklen_t *address_len, - void *user_data) -{ - (void)user_data; - -#ifdef HAVE_RECVFROM - return (ares_ssize_t)recvfrom(sock, buffer, (RECVFROM_TYPE_ARG3)length, flags, - address, address_len); -#else - if (address != NULL && address_len != NULL) { - memset(address, 0, (size_t)*address_len); - address->sa_family = AF_UNSPEC; - } - return (ares_ssize_t)recv(sock, buffer, (RECVFROM_TYPE_ARG3)length, flags); -#endif -} - -static ares_ssize_t default_asendto(ares_socket_t sock, const void *buffer, - size_t length, int flags, - const struct sockaddr *address, - ares_socklen_t address_len, void *user_data) -{ - (void)user_data; - - if (address != NULL) { -#ifdef HAVE_SENDTO - return (ares_ssize_t)sendto((SEND_TYPE_ARG1)sock, (SEND_TYPE_ARG2)buffer, - (SEND_TYPE_ARG3)length, (SEND_TYPE_ARG4)flags, - address, address_len); -#else - (void)address_len; -#endif - } - - return (ares_ssize_t)send((SEND_TYPE_ARG1)sock, (SEND_TYPE_ARG2)buffer, - (SEND_TYPE_ARG3)length, (SEND_TYPE_ARG4)flags); -} - -static int default_agetsockname(ares_socket_t sock, struct sockaddr *address, - ares_socklen_t *address_len, void *user_data) -{ - (void)user_data; - return getsockname(sock, address, address_len); -} - -static int default_abind(ares_socket_t sock, unsigned int flags, - const struct sockaddr *address, socklen_t address_len, - void *user_data) -{ - (void)user_data; - -#ifdef IP_BIND_ADDRESS_NO_PORT - if (flags & ARES_SOCKET_BIND_TCP && flags & ARES_SOCKET_BIND_CLIENT) { - int opt = 1; - (void)setsockopt(sock, SOL_IP, IP_BIND_ADDRESS_NO_PORT, &opt, sizeof(opt)); - } -#else - (void)flags; -#endif - - return bind(sock, address, address_len); -} - -static unsigned int default_aif_nametoindex(const char *ifname, void *user_data) -{ - (void)user_data; - return ares_os_if_nametoindex(ifname); -} - -static const char *default_aif_indextoname(unsigned int ifindex, - char *ifname_buf, - size_t ifname_buf_len, - void *user_data) -{ - (void)user_data; - return ares_os_if_indextoname(ifindex, ifname_buf, ifname_buf_len); -} - -static const struct ares_socket_functions_ex default_socket_functions = { - 1, - ARES_SOCKFUNC_FLAG_NONBLOCKING, - default_asocket, - default_aclose, - default_asetsockopt, - default_aconnect, - default_arecvfrom, - default_asendto, - default_agetsockname, - default_abind, - default_aif_nametoindex, - default_aif_indextoname -}; - -void ares_set_socket_functions_def(ares_channel_t *channel) -{ - ares_set_socket_functions_ex(channel, &default_socket_functions, NULL); -} - -static int legacycb_aclose(ares_socket_t sock, void *user_data) -{ - ares_channel_t *channel = user_data; - - if (channel->legacy_sock_funcs != NULL && - channel->legacy_sock_funcs->aclose != NULL) { - return channel->legacy_sock_funcs->aclose( - sock, channel->legacy_sock_funcs_cb_data); - } - - return default_aclose(sock, NULL); -} - -static ares_socket_t legacycb_asocket(int domain, int type, int protocol, - void *user_data) -{ - ares_channel_t *channel = user_data; - - if (channel->legacy_sock_funcs != NULL && - channel->legacy_sock_funcs->asocket != NULL) { - return channel->legacy_sock_funcs->asocket( - domain, type, protocol, channel->legacy_sock_funcs_cb_data); - } - - return default_asocket(domain, type, protocol, NULL); -} - -static int legacycb_asetsockopt(ares_socket_t sock, ares_socket_opt_t opt, - const void *val, ares_socklen_t val_size, - void *user_data) -{ - (void)sock; - (void)opt; - (void)val; - (void)val_size; - (void)user_data; - SET_SOCKERRNO(ENOSYS); - return -1; -} - -static int legacycb_aconnect(ares_socket_t sock, const struct sockaddr *address, - ares_socklen_t address_len, unsigned int flags, - void *user_data) -{ - ares_channel_t *channel = user_data; - - if (channel->legacy_sock_funcs != NULL && - channel->legacy_sock_funcs->aconnect != NULL) { - return channel->legacy_sock_funcs->aconnect( - sock, address, address_len, channel->legacy_sock_funcs_cb_data); - } - - return default_aconnect(sock, address, address_len, flags, NULL); -} - -static ares_ssize_t legacycb_arecvfrom(ares_socket_t sock, void *buffer, - size_t length, int flags, - struct sockaddr *address, - ares_socklen_t *address_len, - void *user_data) -{ - ares_channel_t *channel = user_data; - - if (channel->legacy_sock_funcs != NULL && - channel->legacy_sock_funcs->arecvfrom != NULL) { - if (address != NULL && address_len != NULL) { - memset(address, 0, (size_t)*address_len); - address->sa_family = AF_UNSPEC; - } - return channel->legacy_sock_funcs->arecvfrom( - sock, buffer, length, flags, address, address_len, - channel->legacy_sock_funcs_cb_data); - } - - return default_arecvfrom(sock, buffer, length, flags, address, address_len, - NULL); -} - -static ares_ssize_t legacycb_asendto(ares_socket_t sock, const void *buffer, - size_t length, int flags, - const struct sockaddr *address, - ares_socklen_t address_len, - void *user_data) -{ - ares_channel_t *channel = user_data; - - if (channel->legacy_sock_funcs != NULL && - channel->legacy_sock_funcs->asendv != NULL) { - struct iovec vec; - vec.iov_base = (void *)((size_t)buffer); /* Cast off const */ - vec.iov_len = length; - return channel->legacy_sock_funcs->asendv( - sock, &vec, 1, channel->legacy_sock_funcs_cb_data); - } - - return default_asendto(sock, buffer, length, flags, address, address_len, - NULL); -} - - -static const struct ares_socket_functions_ex legacy_socket_functions = { - 1, - 0, - legacycb_asocket, - legacycb_aclose, - legacycb_asetsockopt, - legacycb_aconnect, - legacycb_arecvfrom, - legacycb_asendto, - NULL, /* agetsockname */ - NULL, /* abind */ - NULL, /* aif_nametoindex */ - NULL /* aif_indextoname */ -}; - -void ares_set_socket_functions(ares_channel_t *channel, - const struct ares_socket_functions *funcs, - void *data) -{ - if (channel == NULL || channel->optmask & ARES_OPT_EVENT_THREAD) { - return; - } - - channel->legacy_sock_funcs = funcs; - channel->legacy_sock_funcs_cb_data = data; - ares_set_socket_functions_ex(channel, &legacy_socket_functions, channel); -} diff --git a/vendor/c-ares/src/lib/ares_setup.h b/vendor/c-ares/src/lib/ares_setup.h deleted file mode 100644 index 8890c3c33..000000000 --- a/vendor/c-ares/src/lib/ares_setup.h +++ /dev/null @@ -1,224 +0,0 @@ -/* MIT License - * - * Copyright (c) 2004 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_SETUP_H -#define __ARES_SETUP_H - -/* ============================================================================ - * NOTE: This file is automatically included by ares_private.h and should not - * typically be included directly. - * All c-ares source files should include ares_private.h as the - * first header. - * ============================================================================ - */ - -/* - * Include configuration script results or hand-crafted - * configuration file for platforms which lack config tool. - */ - -#ifdef HAVE_CONFIG_H -# include "ares_config.h" -#else -# ifdef _WIN32 -# include "config-win32.h" -# endif -#endif /* HAVE_CONFIG_H */ - -/* - * c-ares external interface definitions are also used internally, - * and might also include required system header files to define them. - */ - -#include "ares_build.h" - -/* ================================================================= */ -/* No system header file shall be included in this file before this */ -/* point. The only allowed ones are those included from ares_build.h */ -/* ================================================================= */ - -/* - * Include header files for windows builds before redefining anything. - * Use this preproessor block only to include or exclude windows.h, - * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs - * to any other further and independent block. Under Cygwin things work - * just as under linux (e.g. ) and the winsock headers should - * never be included when __CYGWIN__ is defined. configure script takes - * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H, - * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined. - */ - -#ifdef USE_WINSOCK -# undef USE_WINSOCK -#endif - -#ifdef HAVE_WINDOWS_H -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# ifdef HAVE_WINSOCK2_H -# include -# define USE_WINSOCK 2 -# ifdef HAVE_WS2TCPIP_H -# include -# endif -# else -# ifdef HAVE_WINSOCK_H -# include -# define USE_WINSOCK 1 -# endif -# endif -#endif - - -#include -#include -#include -#include -#include - -#ifdef HAVE_ERRNO_H -# include -#endif - -#ifdef HAVE_SYS_TYPES_H -# include -#endif - -#ifdef HAVE_MALLOC_H -# include -#endif - -#ifdef HAVE_SYS_STAT_H -# include -#endif - -#ifdef HAVE_SYS_TIME_H -# include -#endif - -#ifdef HAVE_TIME_H -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_SYS_SOCKET_H -# include -#endif - -/* - * Arg 2 type for gethostname in case it hasn't been defined in config file. - */ - -#ifndef GETHOSTNAME_TYPE_ARG2 -# ifdef USE_WINSOCK -# define GETHOSTNAME_TYPE_ARG2 int -# else -# define GETHOSTNAME_TYPE_ARG2 size_t -# endif -#endif - -#ifdef __POCC__ -# include -# include -# define ESRCH 3 -#endif - -/* - * Android does have the arpa/nameser.h header which is detected by configure - * but it appears to be empty with recent NDK r7b / r7c, so we undefine here. - * z/OS does have the arpa/nameser.h header which is detected by configure - * but it is not fully implemented and missing identifiers, so udefine here. - */ -#if (defined(ANDROID) || defined(__ANDROID__) || defined(__MVS__)) && \ - defined(HAVE_ARPA_NAMESER_H) -# undef HAVE_ARPA_NAMESER_H -#endif - -/* - * Recent autoconf versions define these symbols in ares_config.h. We don't - * want them (since they collide with the libcurl ones when we build - * --enable-debug) so we undef them again here. - */ - -#ifdef PACKAGE_STRING -# undef PACKAGE_STRING -#endif -#ifdef PACKAGE_TARNAME -# undef PACKAGE_TARNAME -#endif -#ifdef PACKAGE_VERSION -# undef PACKAGE_VERSION -#endif -#ifdef PACKAGE_BUGREPORT -# undef PACKAGE_BUGREPORT -#endif -#ifdef PACKAGE_NAME -# undef PACKAGE_NAME -#endif -#ifdef VERSION -# undef VERSION -#endif -#ifdef PACKAGE -# undef PACKAGE -#endif - -/* IPv6 compatibility */ -#if !defined(HAVE_AF_INET6) -# if defined(HAVE_PF_INET6) -# define AF_INET6 PF_INET6 -# else -# define AF_INET6 AF_MAX + 1 -# endif -#endif - - -/* Definition of timeval struct for platforms that don't have it. */ - -#ifndef HAVE_STRUCT_TIMEVAL -struct timeval { - ares_int64_t tv_sec; - long tv_usec; -}; -#endif - - -/* - * Macro used to include code only in debug builds. - */ - -#ifdef DEBUGBUILD -# define DEBUGF(x) x -#else -# define DEBUGF(x) \ - do { \ - } while (0) -#endif - -#endif /* __ARES_SETUP_H */ diff --git a/vendor/c-ares/src/lib/ares_socket.c b/vendor/c-ares/src/lib/ares_socket.c deleted file mode 100644 index 516852a84..000000000 --- a/vendor/c-ares/src/lib/ares_socket.c +++ /dev/null @@ -1,425 +0,0 @@ -/* MIT License - * - * Copyright (c) Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#ifdef HAVE_SYS_UIO_H -# include -#endif -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETINET_TCP_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef NETWARE -# include -#endif - -#include -#include -#include - -static ares_conn_err_t ares_socket_deref_error(int err) -{ - switch (err) { -#if defined(EWOULDBLOCK) - case EWOULDBLOCK: - return ARES_CONN_ERR_WOULDBLOCK; -#endif -#if defined(EAGAIN) && (!defined(EWOULDBLOCK) || EAGAIN != EWOULDBLOCK) - case EAGAIN: - return ARES_CONN_ERR_WOULDBLOCK; -#endif - case EINPROGRESS: - return ARES_CONN_ERR_WOULDBLOCK; - case ENETDOWN: - return ARES_CONN_ERR_NETDOWN; - case ENETUNREACH: - return ARES_CONN_ERR_NETUNREACH; - case ECONNABORTED: - return ARES_CONN_ERR_CONNABORTED; - case ECONNRESET: - return ARES_CONN_ERR_CONNRESET; - case ECONNREFUSED: - return ARES_CONN_ERR_CONNREFUSED; - case ETIMEDOUT: - return ARES_CONN_ERR_CONNTIMEDOUT; - case EHOSTDOWN: - return ARES_CONN_ERR_HOSTDOWN; - case EHOSTUNREACH: - return ARES_CONN_ERR_HOSTUNREACH; - case EINTR: - return ARES_CONN_ERR_INTERRUPT; - case EAFNOSUPPORT: - return ARES_CONN_ERR_AFNOSUPPORT; - case EADDRNOTAVAIL: - return ARES_CONN_ERR_BADADDR; - default: - break; - } - - return ARES_CONN_ERR_FAILURE; -} - -ares_bool_t ares_sockaddr_addr_eq(const struct sockaddr *sa, - const struct ares_addr *aa) -{ - const void *addr1; - const void *addr2; - - if (sa->sa_family == aa->family) { - switch (aa->family) { - case AF_INET: - addr1 = &aa->addr.addr4; - addr2 = &(CARES_INADDR_CAST(const struct sockaddr_in *, sa))->sin_addr; - if (memcmp(addr1, addr2, sizeof(aa->addr.addr4)) == 0) { - return ARES_TRUE; /* match */ - } - break; - case AF_INET6: - addr1 = &aa->addr.addr6; - addr2 = - &(CARES_INADDR_CAST(const struct sockaddr_in6 *, sa))->sin6_addr; - if (memcmp(addr1, addr2, sizeof(aa->addr.addr6)) == 0) { - return ARES_TRUE; /* match */ - } - break; - default: - break; /* LCOV_EXCL_LINE */ - } - } - return ARES_FALSE; /* different */ -} - -ares_conn_err_t ares_socket_write(ares_channel_t *channel, ares_socket_t fd, - const void *data, size_t len, size_t *written, - const struct sockaddr *sa, - ares_socklen_t salen) -{ - int flags = 0; - ares_ssize_t rv; - ares_conn_err_t err = ARES_CONN_ERR_SUCCESS; - -#ifdef HAVE_MSG_NOSIGNAL - flags |= MSG_NOSIGNAL; -#endif - - rv = channel->sock_funcs.asendto(fd, data, len, flags, sa, salen, - channel->sock_func_cb_data); - if (rv <= 0) { - err = ares_socket_deref_error(SOCKERRNO); - } else { - *written = (size_t)rv; - } - return err; -} - -ares_conn_err_t ares_socket_recv(ares_channel_t *channel, ares_socket_t s, - ares_bool_t is_tcp, void *data, - size_t data_len, size_t *read_bytes) -{ - ares_ssize_t rv; - - *read_bytes = 0; - - rv = channel->sock_funcs.arecvfrom(s, data, data_len, 0, NULL, 0, - channel->sock_func_cb_data); - - if (rv > 0) { - *read_bytes = (size_t)rv; - return ARES_CONN_ERR_SUCCESS; - } - - if (rv == 0) { - /* UDP allows 0-byte packets and is connectionless, so this is success */ - if (!is_tcp) { - return ARES_CONN_ERR_SUCCESS; - } else { - return ARES_CONN_ERR_CONNCLOSED; - } - } - - /* If we're here, rv<0 */ - return ares_socket_deref_error(SOCKERRNO); -} - -ares_conn_err_t ares_socket_recvfrom(ares_channel_t *channel, ares_socket_t s, - ares_bool_t is_tcp, void *data, - size_t data_len, int flags, - struct sockaddr *from, - ares_socklen_t *from_len, - size_t *read_bytes) -{ - ares_ssize_t rv; - - rv = channel->sock_funcs.arecvfrom(s, data, data_len, flags, from, from_len, - channel->sock_func_cb_data); - - if (rv > 0) { - *read_bytes = (size_t)rv; - return ARES_CONN_ERR_SUCCESS; - } - - if (rv == 0) { - /* UDP allows 0-byte packets and is connectionless, so this is success */ - if (!is_tcp) { - return ARES_CONN_ERR_SUCCESS; - } else { - return ARES_CONN_ERR_CONNCLOSED; - } - } - - /* If we're here, rv<0 */ - return ares_socket_deref_error(SOCKERRNO); -} - -ares_conn_err_t ares_socket_enable_tfo(const ares_channel_t *channel, - ares_socket_t fd) -{ - ares_bool_t opt = ARES_TRUE; - - if (channel->sock_funcs.asetsockopt(fd, ARES_SOCKET_OPT_TCP_FASTOPEN, - (void *)&opt, sizeof(opt), - channel->sock_func_cb_data) != 0) { - return ARES_CONN_ERR_NOTIMP; - } - - return ARES_CONN_ERR_SUCCESS; -} - -ares_status_t ares_socket_configure(ares_channel_t *channel, int family, - ares_bool_t is_tcp, ares_socket_t fd) -{ - union { - struct sockaddr sa; - struct sockaddr_in sa4; - struct sockaddr_in6 sa6; - } local; - - ares_socklen_t bindlen = 0; - int rv; - unsigned int bind_flags = 0; - - /* Set the socket's send and receive buffer sizes. */ - if (channel->socket_send_buffer_size > 0) { - rv = channel->sock_funcs.asetsockopt( - fd, ARES_SOCKET_OPT_SENDBUF_SIZE, - (void *)&channel->socket_send_buffer_size, - sizeof(channel->socket_send_buffer_size), channel->sock_func_cb_data); - if (rv != 0 && SOCKERRNO != ENOSYS) { - return ARES_ECONNREFUSED; /* LCOV_EXCL_LINE: UntestablePath */ - } - } - - if (channel->socket_receive_buffer_size > 0) { - rv = channel->sock_funcs.asetsockopt( - fd, ARES_SOCKET_OPT_RECVBUF_SIZE, - (void *)&channel->socket_receive_buffer_size, - sizeof(channel->socket_receive_buffer_size), channel->sock_func_cb_data); - if (rv != 0 && SOCKERRNO != ENOSYS) { - return ARES_ECONNREFUSED; /* LCOV_EXCL_LINE: UntestablePath */ - } - } - - /* Bind to network interface if configured */ - if (ares_strlen(channel->local_dev_name)) { - /* Prior versions silently ignored failure, so we need to maintain that - * compatibility */ - (void)channel->sock_funcs.asetsockopt( - fd, ARES_SOCKET_OPT_BIND_DEVICE, channel->local_dev_name, - (ares_socklen_t)ares_strlen(channel->local_dev_name), - channel->sock_func_cb_data); - } - - /* Bind to ip address if configured */ - if (family == AF_INET && channel->local_ip4) { - memset(&local.sa4, 0, sizeof(local.sa4)); - local.sa4.sin_family = AF_INET; - local.sa4.sin_addr.s_addr = htonl(channel->local_ip4); - bindlen = sizeof(local.sa4); - } else if (family == AF_INET6 && - memcmp(channel->local_ip6, ares_in6addr_any._S6_un._S6_u8, - sizeof(channel->local_ip6)) != 0) { - /* Only if not link-local and an ip other than "::" is specified */ - memset(&local.sa6, 0, sizeof(local.sa6)); - local.sa6.sin6_family = AF_INET6; - memcpy(&local.sa6.sin6_addr, channel->local_ip6, - sizeof(channel->local_ip6)); - bindlen = sizeof(local.sa6); - } - - - if (bindlen && channel->sock_funcs.abind != NULL) { - bind_flags |= ARES_SOCKET_BIND_CLIENT; - if (is_tcp) { - bind_flags |= ARES_SOCKET_BIND_TCP; - } - if (channel->sock_funcs.abind(fd, bind_flags, &local.sa, bindlen, - channel->sock_func_cb_data) != 0) { - return ARES_ECONNREFUSED; - } - } - - return ARES_SUCCESS; -} - -ares_bool_t ares_sockaddr_to_ares_addr(struct ares_addr *ares_addr, - unsigned short *port, - const struct sockaddr *sockaddr) -{ - if (sockaddr->sa_family == AF_INET) { - /* NOTE: memcpy sockaddr_in due to alignment issues found by UBSAN due to - * dnsinfo packing on MacOS */ - struct sockaddr_in sockaddr_in; - memcpy(&sockaddr_in, sockaddr, sizeof(sockaddr_in)); - - ares_addr->family = AF_INET; - memcpy(&ares_addr->addr.addr4, &(sockaddr_in.sin_addr), - sizeof(ares_addr->addr.addr4)); - - if (port) { - *port = ntohs(sockaddr_in.sin_port); - } - return ARES_TRUE; - } - - if (sockaddr->sa_family == AF_INET6) { - /* NOTE: memcpy sockaddr_in6 due to alignment issues found by UBSAN due to - * dnsinfo packing on MacOS */ - struct sockaddr_in6 sockaddr_in6; - memcpy(&sockaddr_in6, sockaddr, sizeof(sockaddr_in6)); - - ares_addr->family = AF_INET6; - memcpy(&ares_addr->addr.addr6, &(sockaddr_in6.sin6_addr), - sizeof(ares_addr->addr.addr6)); - if (port) { - *port = ntohs(sockaddr_in6.sin6_port); - } - return ARES_TRUE; - } - - return ARES_FALSE; -} - -ares_conn_err_t ares_socket_open(ares_socket_t *sock, ares_channel_t *channel, - int af, int type, int protocol) -{ - ares_socket_t s; - - *sock = ARES_SOCKET_BAD; - - s = - channel->sock_funcs.asocket(af, type, protocol, channel->sock_func_cb_data); - - if (s == ARES_SOCKET_BAD) { - return ares_socket_deref_error(SOCKERRNO); - } - - *sock = s; - - return ARES_CONN_ERR_SUCCESS; -} - -ares_conn_err_t ares_socket_connect(ares_channel_t *channel, - ares_socket_t sockfd, ares_bool_t is_tfo, - const struct sockaddr *addr, - ares_socklen_t addrlen) -{ - ares_conn_err_t err = ARES_CONN_ERR_SUCCESS; - unsigned int flags = 0; - - if (is_tfo) { - flags |= ARES_SOCKET_CONN_TCP_FASTOPEN; - } - - do { - int rv; - - rv = channel->sock_funcs.aconnect(sockfd, addr, addrlen, flags, - channel->sock_func_cb_data); - - if (rv < 0) { - err = ares_socket_deref_error(SOCKERRNO); - } else { - err = ARES_CONN_ERR_SUCCESS; - } - } while (err == ARES_CONN_ERR_INTERRUPT); - - return err; -} - -void ares_socket_close(ares_channel_t *channel, ares_socket_t s) -{ - if (channel == NULL || s == ARES_SOCKET_BAD) { - return; - } - - channel->sock_funcs.aclose(s, channel->sock_func_cb_data); -} - -void ares_set_socket_callback(ares_channel_t *channel, - ares_sock_create_callback cb, void *data) -{ - if (channel == NULL) { - return; - } - channel->sock_create_cb = cb; - channel->sock_create_cb_data = data; -} - -void ares_set_socket_configure_callback(ares_channel_t *channel, - ares_sock_config_callback cb, - void *data) -{ - if (channel == NULL || channel->optmask & ARES_OPT_EVENT_THREAD) { - return; - } - channel->sock_config_cb = cb; - channel->sock_config_cb_data = data; -} - -void ares_set_pending_write_cb(ares_channel_t *channel, - ares_pending_write_cb callback, void *user_data) -{ - if (channel == NULL || channel->optmask & ARES_OPT_EVENT_THREAD) { - return; - } - channel->notify_pending_write_cb = callback; - channel->notify_pending_write_cb_data = user_data; -} diff --git a/vendor/c-ares/src/lib/ares_socket.h b/vendor/c-ares/src/lib/ares_socket.h deleted file mode 100644 index 24a99ab33..000000000 --- a/vendor/c-ares/src/lib/ares_socket.h +++ /dev/null @@ -1,163 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __ARES_SOCKET_H -#define __ARES_SOCKET_H - -/* Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno - * (or equivalent) on this platform to hide platform details to code using it. - */ -#ifdef USE_WINSOCK -# define SOCKERRNO ((int)WSAGetLastError()) -# define SET_SOCKERRNO(x) (WSASetLastError((int)(x))) -#else -# define SOCKERRNO (errno) -# define SET_SOCKERRNO(x) (errno = (x)) -#endif - -/* Portable error number symbolic names defined to Winsock error codes. */ -#ifdef USE_WINSOCK -# undef EBADF /* override definition in errno.h */ -# define EBADF WSAEBADF -# undef EINTR /* override definition in errno.h */ -# define EINTR WSAEINTR -# undef EINVAL /* override definition in errno.h */ -# define EINVAL WSAEINVAL -# undef EWOULDBLOCK /* override definition in errno.h */ -# define EWOULDBLOCK WSAEWOULDBLOCK -# undef EINPROGRESS /* override definition in errno.h */ -# define EINPROGRESS WSAEINPROGRESS -# undef EALREADY /* override definition in errno.h */ -# define EALREADY WSAEALREADY -# undef ENOTSOCK /* override definition in errno.h */ -# define ENOTSOCK WSAENOTSOCK -# undef EDESTADDRREQ /* override definition in errno.h */ -# define EDESTADDRREQ WSAEDESTADDRREQ -# undef EMSGSIZE /* override definition in errno.h */ -# define EMSGSIZE WSAEMSGSIZE -# undef EPROTOTYPE /* override definition in errno.h */ -# define EPROTOTYPE WSAEPROTOTYPE -# undef ENOPROTOOPT /* override definition in errno.h */ -# define ENOPROTOOPT WSAENOPROTOOPT -# undef EPROTONOSUPPORT /* override definition in errno.h */ -# define EPROTONOSUPPORT WSAEPROTONOSUPPORT -# define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT -# undef EOPNOTSUPP /* override definition in errno.h */ -# define EOPNOTSUPP WSAEOPNOTSUPP -# undef ENOSYS /* override definition in errno.h */ -# define ENOSYS WSAEOPNOTSUPP -# define EPFNOSUPPORT WSAEPFNOSUPPORT -# undef EAFNOSUPPORT /* override definition in errno.h */ -# define EAFNOSUPPORT WSAEAFNOSUPPORT -# undef EADDRINUSE /* override definition in errno.h */ -# define EADDRINUSE WSAEADDRINUSE -# undef EADDRNOTAVAIL /* override definition in errno.h */ -# define EADDRNOTAVAIL WSAEADDRNOTAVAIL -# undef ENETDOWN /* override definition in errno.h */ -# define ENETDOWN WSAENETDOWN -# undef ENETUNREACH /* override definition in errno.h */ -# define ENETUNREACH WSAENETUNREACH -# undef ENETRESET /* override definition in errno.h */ -# define ENETRESET WSAENETRESET -# undef ECONNABORTED /* override definition in errno.h */ -# define ECONNABORTED WSAECONNABORTED -# undef ECONNRESET /* override definition in errno.h */ -# define ECONNRESET WSAECONNRESET -# undef ENOBUFS /* override definition in errno.h */ -# define ENOBUFS WSAENOBUFS -# undef EISCONN /* override definition in errno.h */ -# define EISCONN WSAEISCONN -# undef ENOTCONN /* override definition in errno.h */ -# define ENOTCONN WSAENOTCONN -# define ESHUTDOWN WSAESHUTDOWN -# define ETOOMANYREFS WSAETOOMANYREFS -# undef ETIMEDOUT /* override definition in errno.h */ -# define ETIMEDOUT WSAETIMEDOUT -# undef ECONNREFUSED /* override definition in errno.h */ -# define ECONNREFUSED WSAECONNREFUSED -# undef ELOOP /* override definition in errno.h */ -# define ELOOP WSAELOOP -# ifndef ENAMETOOLONG /* possible previous definition in errno.h */ -# define ENAMETOOLONG WSAENAMETOOLONG -# endif -# define EHOSTDOWN WSAEHOSTDOWN -# undef EHOSTUNREACH /* override definition in errno.h */ -# define EHOSTUNREACH WSAEHOSTUNREACH -# ifndef ENOTEMPTY /* possible previous definition in errno.h */ -# define ENOTEMPTY WSAENOTEMPTY -# endif -# define EPROCLIM WSAEPROCLIM -# define EUSERS WSAEUSERS -# define EDQUOT WSAEDQUOT -# define ESTALE WSAESTALE -# define EREMOTE WSAEREMOTE -#endif - -/*! Socket errors */ -typedef enum { - ARES_CONN_ERR_SUCCESS = 0, /*!< Success */ - ARES_CONN_ERR_WOULDBLOCK = 1, /*!< Operation would block */ - ARES_CONN_ERR_CONNCLOSED = 2, /*!< Connection closed (gracefully) */ - ARES_CONN_ERR_CONNABORTED = 3, /*!< Connection Aborted */ - ARES_CONN_ERR_CONNRESET = 4, /*!< Connection Reset */ - ARES_CONN_ERR_CONNREFUSED = 5, /*!< Connection Refused */ - ARES_CONN_ERR_CONNTIMEDOUT = 6, /*!< Connection Timed Out */ - ARES_CONN_ERR_HOSTDOWN = 7, /*!< Host Down */ - ARES_CONN_ERR_HOSTUNREACH = 8, /*!< Host Unreachable */ - ARES_CONN_ERR_NETDOWN = 9, /*!< Network Down */ - ARES_CONN_ERR_NETUNREACH = 10, /*!< Network Unreachable */ - ARES_CONN_ERR_INTERRUPT = 11, /*!< Call interrupted by signal, repeat */ - ARES_CONN_ERR_AFNOSUPPORT = 12, /*!< Address family not supported */ - ARES_CONN_ERR_BADADDR = 13, /*!< Bad Address / Unavailable */ - ARES_CONN_ERR_NOMEM = 14, /*!< Out of memory */ - ARES_CONN_ERR_INVALID = 15, /*!< Invalid Usage */ - ARES_CONN_ERR_TOOLARGE = 16, /*!< Request size too large */ - ARES_CONN_ERR_NOTIMP = 17, /*!< Not implemented */ - ARES_CONN_ERR_FAILURE = 99 /*!< Generic failure */ -} ares_conn_err_t; - -ares_bool_t ares_sockaddr_addr_eq(const struct sockaddr *sa, - const struct ares_addr *aa); -ares_status_t ares_socket_configure(ares_channel_t *channel, int family, - ares_bool_t is_tcp, ares_socket_t fd); -ares_conn_err_t ares_socket_enable_tfo(const ares_channel_t *channel, - ares_socket_t fd); -ares_conn_err_t ares_socket_open(ares_socket_t *sock, ares_channel_t *channel, - int af, int type, int protocol); -ares_bool_t ares_socket_try_again(int errnum); -void ares_socket_close(ares_channel_t *channel, ares_socket_t s); -ares_conn_err_t ares_socket_connect(ares_channel_t *channel, - ares_socket_t sockfd, ares_bool_t is_tfo, - const struct sockaddr *addr, - ares_socklen_t addrlen); -ares_bool_t ares_sockaddr_to_ares_addr(struct ares_addr *ares_addr, - unsigned short *port, - const struct sockaddr *sockaddr); -ares_conn_err_t ares_socket_write(ares_channel_t *channel, ares_socket_t fd, - const void *data, size_t len, size_t *written, - const struct sockaddr *sa, - ares_socklen_t salen); -#endif diff --git a/vendor/c-ares/src/lib/ares_sortaddrinfo.c b/vendor/c-ares/src/lib/ares_sortaddrinfo.c deleted file mode 100644 index e6c21ea0a..000000000 --- a/vendor/c-ares/src/lib/ares_sortaddrinfo.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Original file name getaddrinfo.c - * Lifted from the 'Android Bionic' project with the BSD license. - */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * Copyright (C) 2018 The Android Open Source Project - * Copyright (C) 2019 Andrew Selivanov - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#include -#include - -struct addrinfo_sort_elem { - struct ares_addrinfo_node *ai; - ares_bool_t has_src_addr; - ares_sockaddr src_addr; - size_t original_order; -}; - -#define ARES_IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f) - -#define ARES_IPV6_ADDR_SCOPE_NODELOCAL 0x01 -#define ARES_IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 -#define ARES_IPV6_ADDR_SCOPE_LINKLOCAL 0x02 -#define ARES_IPV6_ADDR_SCOPE_SITELOCAL 0x05 -#define ARES_IPV6_ADDR_SCOPE_ORGLOCAL 0x08 -#define ARES_IPV6_ADDR_SCOPE_GLOBAL 0x0e - -#define ARES_IN_LOOPBACK(a) \ - ((((long unsigned int)(a)) & 0xff000000) == 0x7f000000) - -/* RFC 4193. */ -#define ARES_IN6_IS_ADDR_ULA(a) (((a)->s6_addr[0] & 0xfe) == 0xfc) - -/* These macros are modelled after the ones in . */ -/* RFC 4380, section 2.6 */ -#define ARES_IN6_IS_ADDR_TEREDO(a) \ - ((*(const unsigned int *)(const void *)(&(a)->s6_addr[0]) == \ - ntohl(0x20010000))) -/* RFC 3056, section 2. */ -#define ARES_IN6_IS_ADDR_6TO4(a) \ - (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02)) -/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */ -#define ARES_IN6_IS_ADDR_6BONE(a) \ - (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe)) - -static int get_scope(const struct sockaddr *addr) -{ - if (addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *addr6 = - CARES_INADDR_CAST(const struct sockaddr_in6 *, addr); - if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)) { - return ARES_IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr); - } else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) || - IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) { - /* - * RFC 4291 section 2.5.3 says loopback is to be treated as having - * link-local scope. - */ - return ARES_IPV6_ADDR_SCOPE_LINKLOCAL; - } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) { - return ARES_IPV6_ADDR_SCOPE_SITELOCAL; - } else { - return ARES_IPV6_ADDR_SCOPE_GLOBAL; - } - } else if (addr->sa_family == AF_INET) { - const struct sockaddr_in *addr4 = - CARES_INADDR_CAST(const struct sockaddr_in *, addr); - unsigned long int na = ntohl(addr4->sin_addr.s_addr); - if (ARES_IN_LOOPBACK(na) || /* 127.0.0.0/8 */ - (na & 0xffff0000) == 0xa9fe0000) /* 169.254.0.0/16 */ - { - return ARES_IPV6_ADDR_SCOPE_LINKLOCAL; - } else { - /* - * RFC 6724 section 3.2. Other IPv4 addresses, including private - * addresses and shared addresses (100.64.0.0/10), are assigned global - * scope. - */ - return ARES_IPV6_ADDR_SCOPE_GLOBAL; - } - } else { - /* - * This should never happen. - * Return a scope with low priority as a last resort. - */ - return ARES_IPV6_ADDR_SCOPE_NODELOCAL; - } -} - -static int get_label(const struct sockaddr *addr) -{ - if (addr->sa_family == AF_INET) { - return 4; - } else if (addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *addr6 = - CARES_INADDR_CAST(const struct sockaddr_in6 *, addr); - if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) { - return 0; - } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { - return 4; - } else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { - return 2; - } else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) { - return 5; - } else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr)) { - return 13; - } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) { - return 3; - } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) { - return 11; - } else if (ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) { - return 12; - } else { - /* All other IPv6 addresses, including global unicast addresses. */ - return 1; - } - } else { - /* - * This should never happen. - * Return a semi-random label as a last resort. - */ - return 1; - } -} - -/* - * Get the precedence for a given IPv4/IPv6 address. - * RFC 6724, section 2.1. - */ -static int get_precedence(const struct sockaddr *addr) -{ - if (addr->sa_family == AF_INET) { - return 35; - } else if (addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *addr6 = - CARES_INADDR_CAST(const struct sockaddr_in6 *, addr); - if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) { - return 50; - } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { - return 35; - } else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) { - return 30; - } else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) { - return 5; - } else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr)) { - return 3; - } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) || - IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) || - ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) { - return 1; - } else { - /* All other IPv6 addresses, including global unicast addresses. */ - return 40; - } - } else { - return 1; - } -} - -/* - * Find number of matching initial bits between the two addresses a1 and a2. - */ -static size_t common_prefix_len(const struct in6_addr *a1, - const struct in6_addr *a2) -{ - const unsigned char *p1 = (const unsigned char *)a1; - const unsigned char *p2 = (const unsigned char *)a2; - size_t i; - for (i = 0; i < sizeof(*a1); ++i) { - unsigned char x; - size_t j; - if (p1[i] == p2[i]) { - continue; - } - x = p1[i] ^ p2[i]; - for (j = 0; j < CHAR_BIT; ++j) { - if (x & (1 << (CHAR_BIT - 1))) { - return i * CHAR_BIT + j; - } - x <<= 1; - } - } - return sizeof(*a1) * CHAR_BIT; -} - -/* - * Compare two source/destination address pairs. - * RFC 6724, section 6. - */ -static int rfc6724_compare(const void *ptr1, const void *ptr2) -{ - const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1; - const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2; - int scope_src1; - int scope_dst1; - int scope_match1; - int scope_src2; - int scope_dst2; - int scope_match2; - int label_src1; - int label_dst1; - int label_match1; - int label_src2; - int label_dst2; - int label_match2; - int precedence1; - int precedence2; - size_t prefixlen1; - size_t prefixlen2; - - /* Rule 1: Avoid unusable destinations. */ - if (a1->has_src_addr != a2->has_src_addr) { - return ((int)a2->has_src_addr) - ((int)a1->has_src_addr); - } - - /* Rule 2: Prefer matching scope. */ - scope_src1 = ARES_IPV6_ADDR_SCOPE_NODELOCAL; - if (a1->has_src_addr) { - scope_src1 = get_scope(&a1->src_addr.sa); - } - scope_dst1 = get_scope(a1->ai->ai_addr); - scope_match1 = (scope_src1 == scope_dst1); - - scope_src2 = ARES_IPV6_ADDR_SCOPE_NODELOCAL; - if (a2->has_src_addr) { - scope_src2 = get_scope(&a2->src_addr.sa); - } - scope_dst2 = get_scope(a2->ai->ai_addr); - scope_match2 = (scope_src2 == scope_dst2); - - if (scope_match1 != scope_match2) { - return scope_match2 - scope_match1; - } - - /* Rule 3: Avoid deprecated addresses. */ - - /* Rule 4: Prefer home addresses. */ - - /* Rule 5: Prefer matching label. */ - label_src1 = 1; - if (a1->has_src_addr) { - label_src1 = get_label(&a1->src_addr.sa); - } - label_dst1 = get_label(a1->ai->ai_addr); - label_match1 = (label_src1 == label_dst1); - - label_src2 = 1; - if (a2->has_src_addr) { - label_src2 = get_label(&a2->src_addr.sa); - } - label_dst2 = get_label(a2->ai->ai_addr); - label_match2 = (label_src2 == label_dst2); - - if (label_match1 != label_match2) { - return label_match2 - label_match1; - } - - /* Rule 6: Prefer higher precedence. */ - precedence1 = get_precedence(a1->ai->ai_addr); - precedence2 = get_precedence(a2->ai->ai_addr); - if (precedence1 != precedence2) { - return precedence2 - precedence1; - } - - /* Rule 7: Prefer native transport. */ - - /* Rule 8: Prefer smaller scope. */ - if (scope_dst1 != scope_dst2) { - return scope_dst1 - scope_dst2; - } - - /* Rule 9: Use longest matching prefix. */ - if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 && - a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *a1_src = &a1->src_addr.sa6; - const struct sockaddr_in6 *a1_dst = - CARES_INADDR_CAST(const struct sockaddr_in6 *, a1->ai->ai_addr); - const struct sockaddr_in6 *a2_src = &a2->src_addr.sa6; - const struct sockaddr_in6 *a2_dst = - CARES_INADDR_CAST(const struct sockaddr_in6 *, a2->ai->ai_addr); - prefixlen1 = common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr); - prefixlen2 = common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr); - if (prefixlen1 != prefixlen2) { - return (int)prefixlen2 - (int)prefixlen1; - } - } - - /* - * Rule 10: Leave the order unchanged. - * We need this since qsort() is not necessarily stable. - */ - return ((int)a1->original_order) - ((int)a2->original_order); -} - -/* - * Find the source address that will be used if trying to connect to the given - * address. - * - * Returns 1 if a source address was found, 0 if the address is unreachable - * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are - * undefined. - */ -static int find_src_addr(ares_channel_t *channel, const struct sockaddr *addr, - struct sockaddr *src_addr) -{ - ares_socket_t sock; - ares_socklen_t len; - ares_conn_err_t err; - - switch (addr->sa_family) { - case AF_INET: - len = sizeof(struct sockaddr_in); - break; - case AF_INET6: - len = sizeof(struct sockaddr_in6); - break; - default: - /* No known usable source address for non-INET families. */ - return 0; - } - - err = - ares_socket_open(&sock, channel, addr->sa_family, SOCK_DGRAM, IPPROTO_UDP); - if (err == ARES_CONN_ERR_AFNOSUPPORT) { - return 0; - } else if (err != ARES_CONN_ERR_SUCCESS) { - return -1; - } - - err = ares_socket_connect(channel, sock, ARES_FALSE, addr, len); - if (err != ARES_CONN_ERR_SUCCESS && err != ARES_CONN_ERR_WOULDBLOCK) { - ares_socket_close(channel, sock); - return 0; - } - - if (channel->sock_funcs.agetsockname == NULL || - channel->sock_funcs.agetsockname(sock, src_addr, &len, - channel->sock_func_cb_data) != 0) { - ares_socket_close(channel, sock); - return -1; - } - ares_socket_close(channel, sock); - return 1; -} - -/* - * Sort the linked list starting at sentinel->ai_next in RFC6724 order. - * Will leave the list unchanged if an error occurs. - */ -ares_status_t ares_sortaddrinfo(ares_channel_t *channel, - struct ares_addrinfo_node *list_sentinel) -{ - struct ares_addrinfo_node *cur; - size_t nelem = 0; - size_t i; - int has_src_addr; - struct addrinfo_sort_elem *elems; - - cur = list_sentinel->ai_next; - while (cur) { - ++nelem; - cur = cur->ai_next; - } - - if (!nelem) { - return ARES_ENODATA; - } - - elems = (struct addrinfo_sort_elem *)ares_malloc( - nelem * sizeof(struct addrinfo_sort_elem)); - if (!elems) { - return ARES_ENOMEM; - } - - /* - * Convert the linked list to an array that also contains the candidate - * source address for each destination address. - */ - for (i = 0, cur = list_sentinel->ai_next; i < nelem; - ++i, cur = cur->ai_next) { - assert(cur != NULL); - elems[i].ai = cur; - elems[i].original_order = i; - has_src_addr = find_src_addr(channel, cur->ai_addr, &elems[i].src_addr.sa); - if (has_src_addr == -1) { - ares_free(elems); - return ARES_ENOTFOUND; - } - elems[i].has_src_addr = (has_src_addr == 1) ? ARES_TRUE : ARES_FALSE; - } - - /* Sort the addresses, and rearrange the linked list so it matches the sorted - * order. */ - qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), - rfc6724_compare); - - list_sentinel->ai_next = elems[0].ai; - for (i = 0; i < nelem - 1; ++i) { - elems[i].ai->ai_next = elems[i + 1].ai; - } - elems[nelem - 1].ai->ai_next = NULL; - - ares_free(elems); - return ARES_SUCCESS; -} diff --git a/vendor/c-ares/src/lib/ares_strerror.c b/vendor/c-ares/src/lib/ares_strerror.c deleted file mode 100644 index d9f641162..000000000 --- a/vendor/c-ares/src/lib/ares_strerror.c +++ /dev/null @@ -1,91 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -const char *ares_strerror(int code) -{ - ares_status_t status = (ares_status_t)code; - switch (status) { - case ARES_SUCCESS: - return "Successful completion"; - case ARES_ENODATA: - return "DNS server returned answer with no data"; - case ARES_EFORMERR: - return "DNS server claims query was misformatted"; - case ARES_ESERVFAIL: - return "DNS server returned general failure"; - case ARES_ENOTFOUND: - return "Domain name not found"; - case ARES_ENOTIMP: - return "DNS server does not implement requested operation"; - case ARES_EREFUSED: - return "DNS server refused query"; - case ARES_EBADQUERY: - return "Misformatted DNS query"; - case ARES_EBADNAME: - return "Misformatted domain name"; - case ARES_EBADFAMILY: - return "Unsupported address family"; - case ARES_EBADRESP: - return "Misformatted DNS reply"; - case ARES_ECONNREFUSED: - return "Could not contact DNS servers"; - case ARES_ETIMEOUT: - return "Timeout while contacting DNS servers"; - case ARES_EOF: - return "End of file"; - case ARES_EFILE: - return "Error reading file"; - case ARES_ENOMEM: - return "Out of memory"; - case ARES_EDESTRUCTION: - return "Channel is being destroyed"; - case ARES_EBADSTR: - return "Misformatted string"; - case ARES_EBADFLAGS: - return "Illegal flags specified"; - case ARES_ENONAME: - return "Given hostname is not numeric"; - case ARES_EBADHINTS: - return "Illegal hints flags specified"; - case ARES_ENOTINITIALIZED: - return "c-ares library initialization not yet performed"; - case ARES_ELOADIPHLPAPI: - return "Error loading iphlpapi.dll"; - case ARES_EADDRGETNETWORKPARAMS: - return "Could not find GetNetworkParams function"; - case ARES_ECANCELLED: - return "DNS query cancelled"; - case ARES_ESERVICE: - return "Invalid service name or number"; - case ARES_ENOSERVER: - return "No DNS servers were configured"; - } - - return "unknown"; -} diff --git a/vendor/c-ares/src/lib/ares_sysconfig.c b/vendor/c-ares/src/lib/ares_sysconfig.c deleted file mode 100644 index 286db6032..000000000 --- a/vendor/c-ares/src/lib/ares_sysconfig.c +++ /dev/null @@ -1,639 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2007 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_SYS_PARAM_H -# include -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_NETDB_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#if defined(ANDROID) || defined(__ANDROID__) -# include -# include "ares_android.h" -/* From the Bionic sources */ -# define DNS_PROP_NAME_PREFIX "net.dns" -# define MAX_DNS_PROPERTIES 8 -#endif - -#if defined(CARES_USE_LIBRESOLV) -# include -#endif - -#include "ares_inet_net_pton.h" - - -#if defined(__MVS__) -static ares_status_t ares_init_sysconfig_mvs(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - struct __res_state *res = 0; - size_t count4; - size_t count6; - int i; - __STATEEXTIPV6 *v6; - arse__llist_t *sconfig = NULL; - ares_status_t status; - - if (0 == res) { - int rc = res_init(); - while (rc == -1 && h_errno == TRY_AGAIN) { - rc = res_init(); - } - if (rc == -1) { - return ARES_ENOMEM; - } - res = __res(); - } - - v6 = res->__res_extIPv6; - if (res->nscount > 0) { - count4 = (size_t)res->nscount; - } - - if (v6 && v6->__stat_nscount > 0) { - count6 = (size_t)v6->__stat_nscount; - } else { - count6 = 0; - } - - for (i = 0; i < count4; i++) { - struct sockaddr_in *addr_in = &(res->nsaddr_list[i]); - struct ares_addr addr; - - addr.addr.addr4.s_addr = addr_in->sin_addr.s_addr; - addr.family = AF_INET; - - status = ares_sconfig_append(channel, &sysconfig->sconfig, &addr, - htons(addr_in->sin_port), - htons(addr_in->sin_port), NULL); - - if (status != ARES_SUCCESS) { - return status; - } - } - - for (i = 0; i < count6; i++) { - struct sockaddr_in6 *addr_in = &(v6->__stat_nsaddr_list[i]); - struct ares_addr addr; - - addr.family = AF_INET6; - memcpy(&(addr.addr.addr6), &(addr_in->sin6_addr), - sizeof(addr_in->sin6_addr)); - - status = ares_sconfig_append(channel, &sysconfig->sconfig, &addr, - htons(addr_in->sin_port), - htons(addr_in->sin_port), NULL); - - if (status != ARES_SUCCESS) { - return status; - } - } - - return ARES_SUCCESS; -} -#endif - -#if defined(__riscos__) -static ares_status_t ares_init_sysconfig_riscos(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - char *line; - ares_status_t status = ARES_SUCCESS; - - /* Under RISC OS, name servers are listed in the - system variable Inet$Resolvers, space separated. */ - line = getenv("Inet$Resolvers"); - if (line) { - char *resolvers = ares_strdup(line); - char *pos; - char *space; - - if (!resolvers) { - return ARES_ENOMEM; - } - - pos = resolvers; - do { - space = strchr(pos, ' '); - if (space) { - *space = '\0'; - } - status = ares_sconfig_append_fromstr(channel, &sysconfig->sconfig, pos, - ARES_TRUE); - if (status != ARES_SUCCESS) { - break; - } - pos = space + 1; - } while (space); - - ares_free(resolvers); - } - - return status; -} -#endif - -#if defined(WATT32) -static ares_status_t ares_init_sysconfig_watt32(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - size_t i; - ares_status_t status; - - sock_init(); - - for (i = 0; def_nameservers[i]; i++) { - struct ares_addr addr; - - addr.family = AF_INET; - addr.addr.addr4.s_addr = htonl(def_nameservers[i]); - - status = - ares_sconfig_append(channel, &sysconfig->sconfig, &addr, 0, 0, NULL); - - if (status != ARES_SUCCESS) { - return status; - } - } - - return ARES_SUCCESS; -} -#endif - -#if defined(ANDROID) || defined(__ANDROID__) -static ares_status_t ares_init_sysconfig_android(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - size_t i; - char **dns_servers; - char *domains; - size_t num_servers; - ares_status_t status = ARES_EFILE; - - /* Use the Android connectivity manager to get a list - * of DNS servers. As of Android 8 (Oreo) net.dns# - * system properties are no longer available. Google claims this - * improves privacy. Apps now need the ACCESS_NETWORK_STATE - * permission and must use the ConnectivityManager which - * is Java only. */ - dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers); - if (dns_servers != NULL) { - for (i = 0; i < num_servers; i++) { - status = ares_sconfig_append_fromstr(channel, &sysconfig->sconfig, - dns_servers[i], ARES_TRUE); - if (status != ARES_SUCCESS) { - return status; - } - } - for (i = 0; i < num_servers; i++) { - ares_free(dns_servers[i]); - } - ares_free(dns_servers); - } - - domains = ares_get_android_search_domains_list(); - sysconfig->domains = ares_strsplit(domains, ", ", &sysconfig->ndomains); - ares_free(domains); - -# ifdef HAVE___SYSTEM_PROPERTY_GET - /* Old way using the system property still in place as - * a fallback. Older android versions can still use this. - * it's possible for older apps not not have added the new - * permission and we want to try to avoid breaking those. - * - * We'll only run this if we don't have any dns servers - * because this will get the same ones (if it works). */ - if (sysconfig->sconfig == NULL) { - char propname[PROP_NAME_MAX]; - char propvalue[PROP_VALUE_MAX] = ""; - for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { - snprintf(propname, sizeof(propname), "%s%zu", DNS_PROP_NAME_PREFIX, i); - if (__system_property_get(propname, propvalue) < 1) { - break; - } - status = ares_sconfig_append_fromstr(channel, &sysconfig->sconfig, - propvalue, ARES_TRUE); - if (status != ARES_SUCCESS) { - return status; - } - } - } -# endif /* HAVE___SYSTEM_PROPERTY_GET */ - - return status; -} -#endif - -#if defined(__QNX__) -static ares_status_t - ares_init_sysconfig_qnx(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - /* QNX: - * 1. use confstr(_CS_RESOLVE, ...) as primary resolv.conf data, replacing - * "_" with " ". If that is empty, then do normal /etc/resolv.conf - * processing. - * 2. We want to process /etc/nsswitch.conf as normal. - * 3. if confstr(_CS_DOMAIN, ...) this is the domain name. Use this as - * preference over anything else found. - */ - ares_buf_t *buf = ares_buf_create(); - unsigned char *data = NULL; - size_t data_size = 0; - ares_bool_t process_resolvconf = ARES_TRUE; - ares_status_t status = ARES_SUCCESS; - - /* Prefer confstr(_CS_RESOLVE, ...) */ - buf = ares_buf_create(); - if (buf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - data_size = 1024; - data = ares_buf_append_start(buf, &data_size); - if (data == NULL) { - status = ARES_ENOMEM; - goto done; - } - - data_size = confstr(_CS_RESOLVE, (char *)data, data_size); - if (data_size > 1) { - /* confstr returns byte for NULL terminator, strip */ - data_size--; - - ares_buf_append_finish(buf, data_size); - /* Its odd, this uses _ instead of " " between keywords, otherwise the - * format is the same as resolv.conf, replace. */ - ares_buf_replace(buf, (const unsigned char *)"_", 1, - (const unsigned char *)" ", 1); - - status = ares_sysconfig_process_buf(channel, sysconfig, buf, - ares_sysconfig_parse_resolv_line); - if (status != ARES_SUCCESS) { - /* ENOMEM is really the only error we'll get here */ - goto done; - } - - /* don't read resolv.conf if we processed *any* nameservers */ - if (ares_llist_len(sysconfig->sconfig) != 0) { - process_resolvconf = ARES_FALSE; - } - } - - /* Process files */ - status = ares_init_sysconfig_files(channel, sysconfig, process_resolvconf); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Read confstr(_CS_DOMAIN, ...), but if we had a search path specified with - * more than one domain, lets prefer that instead. Its not exactly clear - * the best way to handle this. */ - if (sysconfig->ndomains <= 1) { - char domain[256]; - size_t domain_len; - - domain_len = confstr(_CS_DOMAIN, domain, sizeof(domain_len)); - if (domain_len != 0) { - ares_strsplit_free(sysconfig->domains, sysconfig->ndomains); - sysconfig->domains = ares_strsplit(domain, ", ", &sysconfig->ndomains); - if (sysconfig->domains == NULL) { - status = ARES_ENOMEM; - goto done; - } - } - } - -done: - ares_buf_destroy(buf); - - return status; -} -#endif - -#if defined(CARES_USE_LIBRESOLV) -static ares_status_t - ares_init_sysconfig_libresolv(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - struct __res_state res; - ares_status_t status = ARES_SUCCESS; - union res_sockaddr_union addr[MAXNS]; - int nscount; - size_t i; - size_t entries = 0; - ares_buf_t *ipbuf = NULL; - - memset(&res, 0, sizeof(res)); - - if (res_ninit(&res) != 0 || !(res.options & RES_INIT)) { - return ARES_EFILE; - } - - nscount = res_getservers(&res, addr, MAXNS); - - for (i = 0; i < (size_t)nscount; ++i) { - char ipaddr[INET6_ADDRSTRLEN] = ""; - char *ipstr = NULL; - unsigned short port = 0; - unsigned int ll_scope = 0; - - sa_family_t family = addr[i].sin.sin_family; - if (family == AF_INET) { - ares_inet_ntop(family, &addr[i].sin.sin_addr, ipaddr, sizeof(ipaddr)); - port = ntohs(addr[i].sin.sin_port); - } else if (family == AF_INET6) { - ares_inet_ntop(family, &addr[i].sin6.sin6_addr, ipaddr, sizeof(ipaddr)); - port = ntohs(addr[i].sin6.sin6_port); - ll_scope = addr[i].sin6.sin6_scope_id; - } else { - continue; - } - - - /* [ip]:port%iface */ - ipbuf = ares_buf_create(); - if (ipbuf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_buf_append_str(ipbuf, "["); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_buf_append_str(ipbuf, ipaddr); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_buf_append_str(ipbuf, "]"); - if (status != ARES_SUCCESS) { - goto done; - } - - if (port) { - status = ares_buf_append_str(ipbuf, ":"); - if (status != ARES_SUCCESS) { - goto done; - } - status = ares_buf_append_num_dec(ipbuf, port, 0); - if (status != ARES_SUCCESS) { - goto done; - } - } - - if (ll_scope) { - status = ares_buf_append_str(ipbuf, "%"); - if (status != ARES_SUCCESS) { - goto done; - } - status = ares_buf_append_num_dec(ipbuf, ll_scope, 0); - if (status != ARES_SUCCESS) { - goto done; - } - } - - ipstr = ares_buf_finish_str(ipbuf, NULL); - ipbuf = NULL; - if (ipstr == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_sconfig_append_fromstr(channel, &sysconfig->sconfig, ipstr, - ARES_TRUE); - - ares_free(ipstr); - if (status != ARES_SUCCESS) { - goto done; - } - } - - while ((entries < MAXDNSRCH) && res.dnsrch[entries]) { - entries++; - } - - if (entries) { - sysconfig->domains = ares_malloc_zero(entries * sizeof(char *)); - if (sysconfig->domains == NULL) { - status = ARES_ENOMEM; - goto done; - } else { - sysconfig->ndomains = entries; - for (i = 0; i < sysconfig->ndomains; i++) { - sysconfig->domains[i] = ares_strdup(res.dnsrch[i]); - if (sysconfig->domains[i] == NULL) { - status = ARES_ENOMEM; - goto done; - } - } - } - } - - if (res.ndots >= 0) { - sysconfig->ndots = (size_t)res.ndots; - } -/* Apple does not allow configuration of retry, so this is a static dummy - * value, ignore */ -# ifndef __APPLE__ - if (res.retry > 0) { - sysconfig->tries = (size_t)res.retry; - } -# endif - if (res.options & RES_ROTATE) { - sysconfig->rotate = ARES_TRUE; - } - - if (res.retrans > 0) { -/* Apple does not allow configuration of retrans, so this is a dummy value - * that is extremely high (5s) */ -# ifndef __APPLE__ - if (res.retrans > 0) { - sysconfig->timeout_ms = (unsigned int)res.retrans * 1000; - } -# endif - } - -done: - ares_buf_destroy(ipbuf); - res_ndestroy(&res); - return status; -} -#endif - -static void ares_sysconfig_free(ares_sysconfig_t *sysconfig) -{ - ares_llist_destroy(sysconfig->sconfig); - ares_strsplit_free(sysconfig->domains, sysconfig->ndomains); - ares_free(sysconfig->sortlist); - ares_free(sysconfig->lookups); - memset(sysconfig, 0, sizeof(*sysconfig)); -} - -static ares_status_t ares_sysconfig_apply(ares_channel_t *channel, - const ares_sysconfig_t *sysconfig) -{ - ares_status_t status; - - if (sysconfig->sconfig && !(channel->optmask & ARES_OPT_SERVERS)) { - status = ares_servers_update(channel, sysconfig->sconfig, ARES_FALSE); - if (status != ARES_SUCCESS) { - return status; - } - } - - if (sysconfig->domains && !(channel->optmask & ARES_OPT_DOMAINS)) { - /* Make sure we duplicate first then replace so even if there is - * ARES_ENOMEM, the channel stays in a good state */ - char **temp = - ares_strsplit_duplicate(sysconfig->domains, sysconfig->ndomains); - if (temp == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - ares_strsplit_free(channel->domains, channel->ndomains); - channel->domains = temp; - channel->ndomains = sysconfig->ndomains; - } - - if (sysconfig->lookups && !(channel->optmask & ARES_OPT_LOOKUPS)) { - char *temp = ares_strdup(sysconfig->lookups); - if (temp == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - ares_free(channel->lookups); - channel->lookups = temp; - } - - if (sysconfig->sortlist && !(channel->optmask & ARES_OPT_SORTLIST)) { - struct apattern *temp = - ares_malloc(sizeof(*channel->sortlist) * sysconfig->nsortlist); - if (temp == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - memcpy(temp, sysconfig->sortlist, - sizeof(*channel->sortlist) * sysconfig->nsortlist); - - ares_free(channel->sortlist); - channel->sortlist = temp; - channel->nsort = sysconfig->nsortlist; - } - - if (!(channel->optmask & ARES_OPT_NDOTS)) { - channel->ndots = sysconfig->ndots; - } - - if (sysconfig->tries && !(channel->optmask & ARES_OPT_TRIES)) { - channel->tries = sysconfig->tries; - } - - if (sysconfig->timeout_ms && !(channel->optmask & ARES_OPT_TIMEOUTMS)) { - channel->timeout = sysconfig->timeout_ms; - } - - if (!(channel->optmask & (ARES_OPT_ROTATE | ARES_OPT_NOROTATE))) { - channel->rotate = sysconfig->rotate; - } - - if (sysconfig->usevc) { - channel->flags |= ARES_FLAG_USEVC; - } - - return ARES_SUCCESS; -} - -ares_status_t ares_init_by_sysconfig(ares_channel_t *channel) -{ - ares_status_t status; - ares_sysconfig_t sysconfig; - - memset(&sysconfig, 0, sizeof(sysconfig)); - sysconfig.ndots = 1; /* Default value if not otherwise set */ - -#if defined(USE_WINSOCK) - status = ares_init_sysconfig_windows(channel, &sysconfig); -#elif defined(__MVS__) - status = ares_init_sysconfig_mvs(channel, &sysconfig); -#elif defined(__riscos__) - status = ares_init_sysconfig_riscos(channel, &sysconfig); -#elif defined(WATT32) - status = ares_init_sysconfig_watt32(channel, &sysconfig); -#elif defined(ANDROID) || defined(__ANDROID__) - status = ares_init_sysconfig_android(channel, &sysconfig); -#elif defined(__APPLE__) - status = ares_init_sysconfig_macos(channel, &sysconfig); -#elif defined(CARES_USE_LIBRESOLV) - status = ares_init_sysconfig_libresolv(channel, &sysconfig); -#elif defined(__QNX__) - status = ares_init_sysconfig_qnx(channel, &sysconfig); -#else - status = ares_init_sysconfig_files(channel, &sysconfig, ARES_TRUE); -#endif - - if (status != ARES_SUCCESS) { - goto done; - } - - /* Environment is supposed to override sysconfig */ - status = ares_init_by_environment(&sysconfig); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Lock when applying the configuration to the channel. Don't need to - * lock prior to this. */ - - ares_channel_lock(channel); - - status = ares_sysconfig_apply(channel, &sysconfig); - ares_channel_unlock(channel); - - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_sysconfig_free(&sysconfig); - - return status; -} diff --git a/vendor/c-ares/src/lib/ares_sysconfig_files.c b/vendor/c-ares/src/lib/ares_sysconfig_files.c deleted file mode 100644 index a6c2a8e62..000000000 --- a/vendor/c-ares/src/lib/ares_sysconfig_files.c +++ /dev/null @@ -1,839 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2007 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_SYS_PARAM_H -# include -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_NETDB_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#if defined(ANDROID) || defined(__ANDROID__) -# include -# include "ares_android.h" -/* From the Bionic sources */ -# define DNS_PROP_NAME_PREFIX "net.dns" -# define MAX_DNS_PROPERTIES 8 -#endif - -#if defined(CARES_USE_LIBRESOLV) -# include -#endif - -#if defined(USE_WINSOCK) && defined(HAVE_IPHLPAPI_H) -# include -#endif - -#include "ares_inet_net_pton.h" - -static unsigned char ip_natural_mask(const struct ares_addr *addr) -{ - const unsigned char *ptr = NULL; - /* This is an odd one. If a raw ipv4 address is specified, then we take - * what is called a natural mask, which means we look at the first octet - * of the ip address and for values 0-127 we assume it is a class A (/8), - * for values 128-191 we assume it is a class B (/16), and for 192-223 - * we assume it is a class C (/24). 223-239 is Class D which and 240-255 is - * Class E, however, there is no pre-defined mask for this, so we'll use - * /24 as well as that's what the old code did. - * - * For IPv6, we'll use /64. - */ - - if (addr->family == AF_INET6) { - return 64; - } - - ptr = (const unsigned char *)&addr->addr.addr4; - if (*ptr < 128) { - return 8; - } - - if (*ptr < 192) { - return 16; - } - - return 24; -} - -static ares_bool_t sortlist_append(struct apattern **sortlist, size_t *nsort, - const struct apattern *pat) -{ - struct apattern *newsort; - - newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(*newsort)); - if (newsort == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - *sortlist = newsort; - - memcpy(&(*sortlist)[*nsort], pat, sizeof(**sortlist)); - (*nsort)++; - - return ARES_TRUE; -} - -static ares_status_t parse_sort(ares_buf_t *buf, struct apattern *pat) -{ - ares_status_t status; - const unsigned char ip_charset[] = "ABCDEFabcdef0123456789.:"; - char ipaddr[INET6_ADDRSTRLEN] = ""; - size_t addrlen; - - memset(pat, 0, sizeof(*pat)); - - /* Consume any leading whitespace */ - ares_buf_consume_whitespace(buf, ARES_TRUE); - - /* If no length, just ignore, return ENOTFOUND as an indicator */ - if (ares_buf_len(buf) == 0) { - return ARES_ENOTFOUND; - } - - ares_buf_tag(buf); - - /* Consume ip address */ - if (ares_buf_consume_charset(buf, ip_charset, sizeof(ip_charset) - 1) == 0) { - return ARES_EBADSTR; - } - - /* Fetch ip address */ - status = ares_buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr)); - if (status != ARES_SUCCESS) { - return status; - } - - /* Parse it to make sure its valid */ - pat->addr.family = AF_UNSPEC; - if (ares_dns_pton(ipaddr, &pat->addr, &addrlen) == NULL) { - return ARES_EBADSTR; - } - - /* See if there is a subnet mask */ - if (ares_buf_begins_with(buf, (const unsigned char *)"/", 1)) { - char maskstr[16]; - const unsigned char ipv4_charset[] = "0123456789."; - - - /* Consume / */ - ares_buf_consume(buf, 1); - - ares_buf_tag(buf); - - /* Consume mask */ - if (ares_buf_consume_charset(buf, ipv4_charset, sizeof(ipv4_charset) - 1) == - 0) { - return ARES_EBADSTR; - } - - /* Fetch mask */ - status = ares_buf_tag_fetch_string(buf, maskstr, sizeof(maskstr)); - if (status != ARES_SUCCESS) { - return status; - } - - if (ares_str_isnum(maskstr)) { - /* Numeric mask */ - int mask = atoi(maskstr); - if (mask < 0 || mask > 128) { - return ARES_EBADSTR; - } - if (pat->addr.family == AF_INET && mask > 32) { - return ARES_EBADSTR; - } - pat->mask = (unsigned char)mask; - } else { - /* Ipv4 subnet style mask */ - struct ares_addr maskaddr; - const unsigned char *ptr; - - memset(&maskaddr, 0, sizeof(maskaddr)); - maskaddr.family = AF_INET; - if (ares_dns_pton(maskstr, &maskaddr, &addrlen) == NULL) { - return ARES_EBADSTR; - } - ptr = (const unsigned char *)&maskaddr.addr.addr4; - pat->mask = (unsigned char)(ares_count_bits_u8(ptr[0]) + - ares_count_bits_u8(ptr[1]) + - ares_count_bits_u8(ptr[2]) + - ares_count_bits_u8(ptr[3])); - } - } else { - pat->mask = ip_natural_mask(&pat->addr); - } - - /* Consume any trailing whitespace */ - ares_buf_consume_whitespace(buf, ARES_TRUE); - - /* If we have any trailing bytes other than whitespace, its a parse failure */ - if (ares_buf_len(buf) != 0) { - return ARES_EBADSTR; - } - - return ARES_SUCCESS; -} - -ares_status_t ares_parse_sortlist(struct apattern **sortlist, size_t *nsort, - const char *str) -{ - ares_buf_t *buf = NULL; - ares_status_t status = ARES_SUCCESS; - ares_array_t *arr = NULL; - size_t num = 0; - size_t i; - - if (sortlist == NULL || nsort == NULL || str == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (*sortlist != NULL) { - ares_free(*sortlist); - } - - *sortlist = NULL; - *nsort = 0; - - buf = ares_buf_create_const((const unsigned char *)str, ares_strlen(str)); - if (buf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - /* Split on space or semicolon */ - status = ares_buf_split(buf, (const unsigned char *)" ;", 2, - ARES_BUF_SPLIT_NONE, 0, &arr); - if (status != ARES_SUCCESS) { - goto done; - } - - num = ares_array_len(arr); - for (i = 0; i < num; i++) { - ares_buf_t **bufptr = ares_array_at(arr, i); - ares_buf_t *entry = *bufptr; - - struct apattern pat; - - status = parse_sort(entry, &pat); - if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) { - goto done; - } - - if (status != ARES_SUCCESS) { - continue; - } - - if (!sortlist_append(sortlist, nsort, &pat)) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ARES_SUCCESS; - -done: - ares_buf_destroy(buf); - ares_array_destroy(arr); - - if (status != ARES_SUCCESS) { - ares_free(*sortlist); - *sortlist = NULL; - *nsort = 0; - } - - return status; -} - -static ares_status_t config_search(ares_sysconfig_t *sysconfig, const char *str, - size_t max_domains) -{ - if (sysconfig->domains && sysconfig->ndomains > 0) { - /* if we already have some domains present, free them first */ - ares_strsplit_free(sysconfig->domains, sysconfig->ndomains); - sysconfig->domains = NULL; - sysconfig->ndomains = 0; - } - - sysconfig->domains = ares_strsplit(str, ", ", &sysconfig->ndomains); - if (sysconfig->domains == NULL) { - return ARES_ENOMEM; - } - - /* Truncate if necessary */ - if (max_domains && sysconfig->ndomains > max_domains) { - size_t i; - for (i = max_domains; i < sysconfig->ndomains; i++) { - ares_free(sysconfig->domains[i]); - sysconfig->domains[i] = NULL; - } - sysconfig->ndomains = max_domains; - } - - return ARES_SUCCESS; -} - -static ares_status_t buf_fetch_string(ares_buf_t *buf, char *str, - size_t str_len) -{ - ares_status_t status; - ares_buf_tag(buf); - ares_buf_consume(buf, ares_buf_len(buf)); - - status = ares_buf_tag_fetch_string(buf, str, str_len); - return status; -} - -static ares_status_t config_lookup(ares_sysconfig_t *sysconfig, ares_buf_t *buf, - const char *separators) -{ - ares_status_t status; - char lookupstr[32]; - size_t lookupstr_cnt = 0; - char **lookups = NULL; - size_t num = 0; - size_t i; - size_t separators_len = ares_strlen(separators); - - status = - ares_buf_split_str(buf, (const unsigned char *)separators, separators_len, - ARES_BUF_SPLIT_TRIM, 0, &lookups, &num); - if (status != ARES_SUCCESS) { - goto done; - } - - for (i = 0; i < num; i++) { - const char *value = lookups[i]; - char ch; - - if (ares_strcaseeq(value, "dns") || ares_strcaseeq(value, "bind") || - ares_strcaseeq(value, "resolv") || ares_strcaseeq(value, "resolve")) { - ch = 'b'; - } else if (ares_strcaseeq(value, "files") || - ares_strcaseeq(value, "file") || - ares_strcaseeq(value, "local")) { - ch = 'f'; - } else { - continue; - } - - /* Look for a duplicate and ignore */ - if (memchr(lookupstr, ch, lookupstr_cnt) == NULL) { - lookupstr[lookupstr_cnt++] = ch; - } - } - - if (lookupstr_cnt) { - lookupstr[lookupstr_cnt] = 0; - ares_free(sysconfig->lookups); - sysconfig->lookups = ares_strdup(lookupstr); - if (sysconfig->lookups == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ARES_SUCCESS; - -done: - if (status != ARES_ENOMEM) { - status = ARES_SUCCESS; - } - ares_free_array(lookups, num, ares_free); - return status; -} - -static ares_status_t process_option(ares_sysconfig_t *sysconfig, - ares_buf_t *option) -{ - char **kv = NULL; - size_t num = 0; - const char *key; - const char *val; - unsigned int valint = 0; - ares_status_t status; - - /* Split on : */ - status = ares_buf_split_str(option, (const unsigned char *)":", 1, - ARES_BUF_SPLIT_TRIM, 2, &kv, &num); - if (status != ARES_SUCCESS) { - goto done; - } - - if (num < 1) { - status = ARES_EBADSTR; - goto done; - } - - key = kv[0]; - if (num == 2) { - val = kv[1]; - valint = (unsigned int)strtoul(val, NULL, 10); - } - - if (ares_streq(key, "ndots")) { - sysconfig->ndots = valint; - } else if (ares_streq(key, "retrans") || ares_streq(key, "timeout")) { - if (valint == 0) { - return ARES_EFORMERR; - } - sysconfig->timeout_ms = valint * 1000; - } else if (ares_streq(key, "retry") || ares_streq(key, "attempts")) { - if (valint == 0) { - return ARES_EFORMERR; - } - sysconfig->tries = valint; - } else if (ares_streq(key, "rotate")) { - sysconfig->rotate = ARES_TRUE; - } else if (ares_streq(key, "use-vc") || ares_streq(key, "usevc")) { - sysconfig->usevc = ARES_TRUE; - } - -done: - ares_free_array(kv, num, ares_free); - return status; -} - -ares_status_t ares_sysconfig_set_options(ares_sysconfig_t *sysconfig, - const char *str) -{ - ares_buf_t *buf = NULL; - ares_array_t *options = NULL; - size_t num; - size_t i; - ares_status_t status; - - buf = ares_buf_create_const((const unsigned char *)str, ares_strlen(str)); - if (buf == NULL) { - return ARES_ENOMEM; - } - - status = ares_buf_split(buf, (const unsigned char *)" \t", 2, - ARES_BUF_SPLIT_TRIM, 0, &options); - if (status != ARES_SUCCESS) { - goto done; - } - - num = ares_array_len(options); - for (i = 0; i < num; i++) { - ares_buf_t **bufptr = ares_array_at(options, i); - ares_buf_t *valbuf = *bufptr; - - status = process_option(sysconfig, valbuf); - /* Out of memory is the only fatal condition */ - if (status == ARES_ENOMEM) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ARES_SUCCESS; - -done: - ares_array_destroy(options); - ares_buf_destroy(buf); - return status; -} - -ares_status_t ares_init_by_environment(ares_sysconfig_t *sysconfig) -{ - const char *localdomain; - const char *res_options; - ares_status_t status; - - localdomain = getenv("LOCALDOMAIN"); - if (localdomain) { - char *temp = ares_strdup(localdomain); - if (temp == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - status = config_search(sysconfig, temp, 1); - ares_free(temp); - if (status != ARES_SUCCESS) { - return status; - } - } - - res_options = getenv("RES_OPTIONS"); - if (res_options) { - status = ares_sysconfig_set_options(sysconfig, res_options); - if (status != ARES_SUCCESS) { - return status; - } - } - - return ARES_SUCCESS; -} - -/* Configuration Files: - * /etc/resolv.conf - * - All Unix-like systems - * - Comments start with ; or # - * - Lines have a keyword followed by a value that is interpreted specific - * to the keyword: - * - Keywords: - * - nameserver - IP address of nameserver with optional port (using a : - * prefix). If using an ipv6 address and specifying a port, the ipv6 - * address must be encapsulated in brackets. For link-local ipv6 - * addresses, the interface can also be specified with a % prefix. e.g.: - * "nameserver [fe80::1]:1234%iface" - * This keyword may be specified multiple times. - * - search - whitespace separated list of domains - * - domain - obsolete, same as search except only a single domain - * - lookup / hostresorder - local, bind, file, files - * - sortlist - whitespace separated ip-address/netmask pairs - * - options - options controlling resolver variables - * - ndots:n - set ndots option - * - timeout:n (retrans:n) - timeout per query attempt in seconds - * - attempts:n (retry:n) - number of times resolver will send query - * - rotate - round-robin selection of name servers - * - use-vc / usevc - force tcp - * /etc/nsswitch.conf - * - Modern Linux, FreeBSD, HP-UX, Solaris - * - Search order set via: - * "hosts: files dns mdns4_minimal mdns4" - * - files is /etc/hosts - * - dns is dns - * - mdns4_minimal does mdns only if ending in .local - * - mdns4 does not limit to domains ending in .local - * /etc/netsvc.conf - * - AIX - * - Search order set via: - * "hosts = local , bind" - * - bind is dns - * - local is /etc/hosts - * /etc/svc.conf - * - Tru64 - * - Same format as /etc/netsvc.conf - * /etc/host.conf - * - Early FreeBSD, Early Linux - * - Not worth supporting, format varied based on system, FreeBSD used - * just a line per search order, Linux used "order " and a comma - * delimited list of "bind" and "hosts" - */ - - -/* This function will only return ARES_SUCCESS or ARES_ENOMEM. Any other - * conditions are ignored. Users may mess up config files, but we want to - * process anything we can. */ -ares_status_t ares_sysconfig_parse_resolv_line(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_buf_t *line) -{ - char option[32]; - char value[512]; - ares_status_t status = ARES_SUCCESS; - - /* Ignore lines beginning with a comment */ - if (ares_buf_begins_with(line, (const unsigned char *)"#", 1) || - ares_buf_begins_with(line, (const unsigned char *)";", 1)) { - return ARES_SUCCESS; - } - - ares_buf_tag(line); - - /* Shouldn't be possible, but if it happens, ignore the line. */ - if (ares_buf_consume_nonwhitespace(line) == 0) { - return ARES_SUCCESS; - } - - status = ares_buf_tag_fetch_string(line, option, sizeof(option)); - if (status != ARES_SUCCESS) { - return ARES_SUCCESS; - } - - ares_buf_consume_whitespace(line, ARES_TRUE); - - status = buf_fetch_string(line, value, sizeof(value)); - if (status != ARES_SUCCESS) { - return ARES_SUCCESS; - } - - ares_str_trim(value); - if (*value == 0) { - return ARES_SUCCESS; - } - - /* At this point we have a string option and a string value, both trimmed - * of leading and trailing whitespace. Lets try to evaluate them */ - if (ares_streq(option, "domain")) { - /* Domain is legacy, don't overwrite an existing config set by search */ - if (sysconfig->domains == NULL) { - status = config_search(sysconfig, value, 1); - } - } else if (ares_streq(option, "lookup") || - ares_streq(option, "hostresorder")) { - ares_buf_tag_rollback(line); - status = config_lookup(sysconfig, line, " \t"); - } else if (ares_streq(option, "search")) { - status = config_search(sysconfig, value, 0); - } else if (ares_streq(option, "nameserver")) { - status = ares_sconfig_append_fromstr(channel, &sysconfig->sconfig, value, - ARES_TRUE); - } else if (ares_streq(option, "sortlist")) { - /* Ignore all failures except ENOMEM. If the sysadmin set a bad - * sortlist, just ignore the sortlist, don't cause an inoperable - * channel */ - status = - ares_parse_sortlist(&sysconfig->sortlist, &sysconfig->nsortlist, value); - if (status != ARES_ENOMEM) { - status = ARES_SUCCESS; - } - } else if (ares_streq(option, "options")) { - status = ares_sysconfig_set_options(sysconfig, value); - } - - return status; -} - -/* This function will only return ARES_SUCCESS or ARES_ENOMEM. Any other - * conditions are ignored. Users may mess up config files, but we want to - * process anything we can. */ -static ares_status_t parse_nsswitch_line(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_buf_t *line) -{ - char option[32]; - ares_status_t status = ARES_SUCCESS; - ares_array_t *sects = NULL; - ares_buf_t **bufptr; - ares_buf_t *buf; - - (void)channel; - - /* Ignore lines beginning with a comment */ - if (ares_buf_begins_with(line, (const unsigned char *)"#", 1)) { - return ARES_SUCCESS; - } - - /* database : values (space delimited) */ - status = ares_buf_split(line, (const unsigned char *)":", 1, - ARES_BUF_SPLIT_TRIM, 2, §s); - - if (status != ARES_SUCCESS || ares_array_len(sects) != 2) { - goto done; - } - - bufptr = ares_array_at(sects, 0); - buf = *bufptr; - - status = buf_fetch_string(buf, option, sizeof(option)); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Only support "hosts:" */ - if (!ares_streq(option, "hosts")) { - goto done; - } - - /* Values are space separated */ - bufptr = ares_array_at(sects, 1); - buf = *bufptr; - status = config_lookup(sysconfig, buf, " \t"); - -done: - ares_array_destroy(sects); - if (status != ARES_ENOMEM) { - status = ARES_SUCCESS; - } - return status; -} - -/* This function will only return ARES_SUCCESS or ARES_ENOMEM. Any other - * conditions are ignored. Users may mess up config files, but we want to - * process anything we can. */ -static ares_status_t parse_svcconf_line(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_buf_t *line) -{ - char option[32]; - ares_buf_t **bufptr; - ares_buf_t *buf; - ares_status_t status = ARES_SUCCESS; - ares_array_t *sects = NULL; - - (void)channel; - - /* Ignore lines beginning with a comment */ - if (ares_buf_begins_with(line, (const unsigned char *)"#", 1)) { - return ARES_SUCCESS; - } - - /* database = values (comma delimited)*/ - status = ares_buf_split(line, (const unsigned char *)"=", 1, - ARES_BUF_SPLIT_TRIM, 2, §s); - - if (status != ARES_SUCCESS || ares_array_len(sects) != 2) { - goto done; - } - - bufptr = ares_array_at(sects, 0); - buf = *bufptr; - status = buf_fetch_string(buf, option, sizeof(option)); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Only support "hosts=" */ - if (!ares_streq(option, "hosts")) { - goto done; - } - - /* Values are comma separated */ - bufptr = ares_array_at(sects, 1); - buf = *bufptr; - status = config_lookup(sysconfig, buf, ","); - -done: - ares_array_destroy(sects); - if (status != ARES_ENOMEM) { - status = ARES_SUCCESS; - } - return status; -} - - -ares_status_t ares_sysconfig_process_buf(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_buf_t *buf, - ares_sysconfig_line_cb_t cb) -{ - ares_array_t *lines = NULL; - size_t num; - size_t i; - ares_status_t status; - - status = ares_buf_split(buf, (const unsigned char *)"\n", 1, - ARES_BUF_SPLIT_TRIM, 0, &lines); - if (status != ARES_SUCCESS) { - goto done; - } - - num = ares_array_len(lines); - for (i = 0; i < num; i++) { - ares_buf_t **bufptr = ares_array_at(lines, i); - ares_buf_t *line = *bufptr; - - status = cb(channel, sysconfig, line); - if (status != ARES_SUCCESS) { - goto done; - } - } - -done: - ares_array_destroy(lines); - return status; -} - -/* Should only return: - * ARES_ENOTFOUND - file not found - * ARES_EFILE - error reading file (perms) - * ARES_ENOMEM - out of memory - * ARES_SUCCESS - file processed, doesn't necessarily mean it was a good - * file, but we're not erroring out if we can't parse - * something (or anything at all) */ -static ares_status_t process_config_lines(const ares_channel_t *channel, - const char *filename, - ares_sysconfig_t *sysconfig, - ares_sysconfig_line_cb_t cb) -{ - ares_status_t status = ARES_SUCCESS; - ares_buf_t *buf = NULL; - - buf = ares_buf_create(); - if (buf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_buf_load_file(filename, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_sysconfig_process_buf(channel, sysconfig, buf, cb); - -done: - ares_buf_destroy(buf); - - return status; -} - -ares_status_t ares_init_sysconfig_files(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig, - ares_bool_t process_resolvconf) -{ - ares_status_t status = ARES_SUCCESS; - - /* Resolv.conf */ - if (process_resolvconf) { - status = process_config_lines(channel, - (channel->resolvconf_path != NULL) - ? channel->resolvconf_path - : PATH_RESOLV_CONF, - sysconfig, ares_sysconfig_parse_resolv_line); - if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) { - goto done; - } - } - - /* Nsswitch.conf */ - status = process_config_lines(channel, "/etc/nsswitch.conf", sysconfig, - parse_nsswitch_line); - if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) { - goto done; - } - - /* netsvc.conf */ - status = process_config_lines(channel, "/etc/netsvc.conf", sysconfig, - parse_svcconf_line); - if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) { - goto done; - } - - /* svc.conf */ - status = process_config_lines(channel, "/etc/svc.conf", sysconfig, - parse_svcconf_line); - if (status != ARES_SUCCESS && status != ARES_ENOTFOUND) { - goto done; - } - - status = ARES_SUCCESS; - -done: - return status; -} diff --git a/vendor/c-ares/src/lib/ares_sysconfig_mac.c b/vendor/c-ares/src/lib/ares_sysconfig_mac.c deleted file mode 100644 index 4d46ffd58..000000000 --- a/vendor/c-ares/src/lib/ares_sysconfig_mac.c +++ /dev/null @@ -1,373 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifdef __APPLE__ - -/* The DNS configuration for apple is stored in the system configuration - * database. Apple does provide an emulated `/etc/resolv.conf` on MacOS (but - * not iOS), it cannot, however, represent the entirety of the DNS - * configuration. Alternatively, libresolv could be used to also retrieve some - * system configuration, but it too is not capable of retrieving the entirety - * of the DNS configuration. - * - * Attempts to use the preferred public API of `SCDynamicStoreCreate()` and - * friends yielded incomplete DNS information. Instead, that leaves some apple - * "internal" symbols from `configd` that we need to access in order to get the - * entire configuration. We can see that we're not the only ones to do this as - * Google Chrome also does: - * https://chromium.googlesource.com/chromium/src/+/HEAD/net/dns/dns_config_watcher_mac.cc - * These internal functions are what `libresolv` and `scutil` use to retrieve - * the dns configuration. Since these symbols are not publicly available, we - * will dynamically load the symbols from `libSystem` and import the `dnsinfo.h` - * private header extracted from: - * https://opensource.apple.com/source/configd/configd-1109.140.1/dnsinfo/dnsinfo.h - */ - -/* The apple header uses anonymous unions which came with C11 */ -# if defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wc11-extensions" -# endif - -# include "ares_private.h" -# include -# include -# include -# include -# include -# include "thirdparty/apple/dnsinfo.h" -# include -# if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 /* MacOS 10.8 */ -# include -# endif - -typedef struct { - void *handle; - dns_config_t *(*dns_configuration_copy)(void); - void (*dns_configuration_free)(dns_config_t *config); -} dnsinfo_t; - -static void dnsinfo_destroy(dnsinfo_t *dnsinfo) -{ - if (dnsinfo == NULL) { - return; - } - - if (dnsinfo->handle) { - dlclose(dnsinfo->handle); - } - - ares_free(dnsinfo); -} - -static ares_status_t dnsinfo_init(dnsinfo_t **dnsinfo_out) -{ - dnsinfo_t *dnsinfo = NULL; - ares_status_t status = ARES_SUCCESS; - size_t i; - const char *searchlibs[] = { - "/usr/lib/libSystem.dylib", - "/System/Library/Frameworks/SystemConfiguration.framework/" - "SystemConfiguration", - NULL - }; - - if (dnsinfo_out == NULL) { - status = ARES_EFORMERR; - goto done; - } - - *dnsinfo_out = NULL; - - dnsinfo = ares_malloc_zero(sizeof(*dnsinfo)); - if (dnsinfo == NULL) { - status = ARES_ENOMEM; - goto done; - } - - for (i = 0; searchlibs[i] != NULL; i++) { - dnsinfo->handle = dlopen(searchlibs[i], RTLD_LAZY /* | RTLD_NOLOAD */); - if (dnsinfo->handle == NULL) { - /* Fail, loop */ - continue; - } - - dnsinfo->dns_configuration_copy = (dns_config_t * (*)(void)) - dlsym(dnsinfo->handle, "dns_configuration_copy"); - - dnsinfo->dns_configuration_free = (void (*)(dns_config_t *))dlsym( - dnsinfo->handle, "dns_configuration_free"); - - if (dnsinfo->dns_configuration_copy != NULL && - dnsinfo->dns_configuration_free != NULL) { - break; - } - - /* Fail, loop */ - dlclose(dnsinfo->handle); - dnsinfo->handle = NULL; - } - - - if (dnsinfo->dns_configuration_copy == NULL || - dnsinfo->dns_configuration_free == NULL) { - status = ARES_ESERVFAIL; - goto done; - } - - -done: - if (status == ARES_SUCCESS) { - *dnsinfo_out = dnsinfo; - } else { - dnsinfo_destroy(dnsinfo); - } - - return status; -} - -static ares_bool_t search_is_duplicate(const ares_sysconfig_t *sysconfig, - const char *name) -{ - size_t i; - for (i = 0; i < sysconfig->ndomains; i++) { - if (ares_strcaseeq(sysconfig->domains[i], name)) { - return ARES_TRUE; - } - } - return ARES_FALSE; -} - -static ares_status_t read_resolver(const ares_channel_t *channel, - const dns_resolver_t *resolver, - ares_sysconfig_t *sysconfig) -{ - int i; - unsigned short port = 0; - ares_status_t status = ARES_SUCCESS; - -# if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 /* MacOS 10.8 */ - /* XXX: resolver->domain is for domain-specific servers. When we implement - * this support, we'll want to use this. But for now, we're going to - * skip any servers which set this since we can't properly route. - * MacOS used to use this setting for a different purpose in the - * past however, so on versions of MacOS < 10.8 just ignore this - * completely. */ - if (resolver->domain != NULL) { - return ARES_SUCCESS; - } -# endif - -# if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 /* MacOS 10.8 */ - /* Check to see if DNS server should be used, base this on if the server is - * reachable or can be reachable automatically if we send traffic that - * direction. */ - if (!(resolver->reach_flags & - (kSCNetworkFlagsReachable | - kSCNetworkReachabilityFlagsConnectionOnTraffic))) { - return ARES_SUCCESS; - } -# endif - - /* NOTE: it doesn't look like resolver->flags is relevant */ - - /* If there's no nameservers, nothing to do */ - if (resolver->n_nameserver <= 0) { - return ARES_SUCCESS; - } - - /* Default port */ - port = resolver->port; - - /* Append search list */ - if (resolver->n_search > 0) { - char **new_domains = ares_realloc_zero( - sysconfig->domains, sizeof(*sysconfig->domains) * sysconfig->ndomains, - sizeof(*sysconfig->domains) * - (sysconfig->ndomains + (size_t)resolver->n_search)); - if (new_domains == NULL) { - return ARES_ENOMEM; - } - sysconfig->domains = new_domains; - - for (i = 0; i < resolver->n_search; i++) { - const char *search; - /* UBSAN: copy pointer using memcpy due to misalignment */ - memcpy(&search, resolver->search + i, sizeof(search)); - - /* Skip duplicates */ - if (search_is_duplicate(sysconfig, search)) { - continue; - } - sysconfig->domains[sysconfig->ndomains] = ares_strdup(search); - if (sysconfig->domains[sysconfig->ndomains] == NULL) { - return ARES_ENOMEM; - } - sysconfig->ndomains++; - } - } - - /* NOTE: we're going to skip importing the sort addresses for now. Its - * likely not used, its not obvious how to even configure such a thing. - */ -# if 0 - for (i=0; in_sortaddr; i++) { - char val[256]; - inet_ntop(AF_INET, &resolver->sortaddr[i]->address, val, sizeof(val)); - printf("\t\t%s/", val); - inet_ntop(AF_INET, &resolver->sortaddr[i]->mask, val, sizeof(val)); - printf("%s\n", val); - } -# endif - - if (resolver->options != NULL) { - status = ares_sysconfig_set_options(sysconfig, resolver->options); - if (status != ARES_SUCCESS) { - return status; - } - } - - /* NOTE: - * - resolver->timeout appears unused, always 0, so we ignore this - * - resolver->service_identifier doesn't appear relevant to us - * - resolver->cid also isn't relevant - * - resolver->if_name we won't use since it isn't available in MacOS 10.8 - * or earlier, use resolver->if_index instead to then lookup the name. - */ - - /* XXX: resolver->search_order appears like it might be relevant, we might - * need to sort the resulting list by this metric if we find in the future we - * need to. That said, due to the automatic re-sorting we do, I'm not sure it - * matters. Here's an article on this search order stuff: - * https://www.cnet.com/tech/computing/os-x-10-6-3-and-dns-server-priority-changes/ - */ - - for (i = 0; i < resolver->n_nameserver; i++) { - struct ares_addr addr; - unsigned short addrport; - const struct sockaddr *sockaddr; - char if_name_str[256] = ""; - const char *if_name = NULL; - - /* UBSAN alignment workaround to fetch memory address */ - memcpy(&sockaddr, resolver->nameserver + i, sizeof(sockaddr)); - - if (!ares_sockaddr_to_ares_addr(&addr, &addrport, sockaddr)) { - continue; - } - - if (addrport == 0) { - addrport = port; - } - - if (channel->sock_funcs.aif_indextoname != NULL) { - if_name = channel->sock_funcs.aif_indextoname( - resolver->if_index, if_name_str, sizeof(if_name_str), - channel->sock_func_cb_data); - } - - status = ares_sconfig_append(channel, &sysconfig->sconfig, &addr, addrport, - addrport, if_name); - if (status != ARES_SUCCESS) { - return status; - } - } - - return status; -} - -static ares_status_t read_resolvers(const ares_channel_t *channel, - dns_resolver_t **resolvers, int nresolvers, - ares_sysconfig_t *sysconfig) -{ - ares_status_t status = ARES_SUCCESS; - int i; - - for (i = 0; status == ARES_SUCCESS && i < nresolvers; i++) { - const dns_resolver_t *resolver_ptr; - - /* UBSAN doesn't like that this is unaligned, lets use memcpy to get the - * address. Equivalent to: - * resolver = resolvers[i] - */ - memcpy(&resolver_ptr, resolvers + i, sizeof(resolver_ptr)); - - status = read_resolver(channel, resolver_ptr, sysconfig); - } - - return status; -} - -ares_status_t ares_init_sysconfig_macos(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - dnsinfo_t *dnsinfo = NULL; - dns_config_t *sc_dns = NULL; - ares_status_t status = ARES_SUCCESS; - - status = dnsinfo_init(&dnsinfo); - - if (status != ARES_SUCCESS) { - goto done; - } - - sc_dns = dnsinfo->dns_configuration_copy(); - if (sc_dns == NULL) { - status = ARES_ESERVFAIL; - goto done; - } - - /* There are `resolver`, `scoped_resolver`, and `service_specific_resolver` - * settings. The `scoped_resolver` settings appear to be already available via - * the `resolver` settings and likely are only relevant to link-local dns - * servers which we can already detect via the address itself, so we'll ignore - * the `scoped_resolver` section. It isn't clear what the - * `service_specific_resolver` is used for, I haven't personally seen it - * in use so we'll ignore this until at some point where we find we need it. - * Likely this wasn't available via `/etc/resolv.conf` nor `libresolv` anyhow - * so its not worse to prior configuration methods, worst case. */ - - status = - read_resolvers(channel, sc_dns->resolver, sc_dns->n_resolver, sysconfig); - -done: - if (dnsinfo) { - dnsinfo->dns_configuration_free(sc_dns); - dnsinfo_destroy(dnsinfo); - } - return status; -} - -# if defined(__clang__) -# pragma GCC diagnostic pop -# endif - -#else - -/* Prevent compiler warnings due to empty translation unit */ -typedef int make_iso_compilers_happy; - -#endif diff --git a/vendor/c-ares/src/lib/ares_sysconfig_win.c b/vendor/c-ares/src/lib/ares_sysconfig_win.c deleted file mode 100644 index 01109a89b..000000000 --- a/vendor/c-ares/src/lib/ares_sysconfig_win.c +++ /dev/null @@ -1,621 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2007 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_SYS_PARAM_H -# include -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_NETDB_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#if defined(USE_WINSOCK) -# if defined(HAVE_IPHLPAPI_H) -# include -# endif -# if defined(HAVE_NETIOAPI_H) -# include -# endif -#endif - -#include "ares_inet_net_pton.h" - -#if defined(USE_WINSOCK) -/* - * get_REG_SZ() - * - * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer - * to the name of the registry leaf key to be queried, fetch it's string - * value and return a pointer in *outptr to a newly allocated memory area - * holding it as a null-terminated string. - * - * Returns 0 and nullifies *outptr upon inability to return a string value. - * - * Returns 1 and sets *outptr when returning a dynamically allocated string. - * - * Supported on Windows NT 3.5 and newer. - */ -static ares_bool_t get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) -{ - DWORD size = 0; - int res; - - *outptr = NULL; - - /* Find out size of string stored in registry */ - res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, NULL, &size); - if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size) { - return ARES_FALSE; - } - - /* Allocate buffer of indicated size plus one given that string - might have been stored without null termination */ - *outptr = ares_malloc(size + 1); - if (!*outptr) { - return ARES_FALSE; - } - - /* Get the value for real */ - res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, (unsigned char *)*outptr, - &size); - if ((res != ERROR_SUCCESS) || (size == 1)) { - ares_free(*outptr); - *outptr = NULL; - return ARES_FALSE; - } - - /* Null terminate buffer always */ - *(*outptr + size) = '\0'; - - return ARES_TRUE; -} - -static void commanjoin(char **dst, const char * const src, const size_t len) -{ - char *newbuf; - size_t newsize; - - /* 1 for terminating 0 and 2 for , and terminating 0 */ - newsize = len + (*dst ? (ares_strlen(*dst) + 2) : 1); - newbuf = ares_realloc(*dst, newsize); - if (!newbuf) { - return; - } - if (*dst == NULL) { - *newbuf = '\0'; - } - *dst = newbuf; - if (ares_strlen(*dst) != 0) { - strcat(*dst, ","); - } - strncat(*dst, src, len); -} - -/* - * commajoin() - * - * RTF code. - */ -static void commajoin(char **dst, const char *src) -{ - commanjoin(dst, src, ares_strlen(src)); -} - -/* A structure to hold the string form of IPv4 and IPv6 addresses so we can - * sort them by a metric. - */ -typedef struct { - /* The metric we sort them by. */ - ULONG metric; - - /* Original index of the item, used as a secondary sort parameter to make - * qsort() stable if the metrics are equal */ - size_t orig_idx; - - /* Room enough for the string form of any IPv4 or IPv6 address that - * ares_inet_ntop() will create. Based on the existing c-ares practice. - */ - char text[INET6_ADDRSTRLEN + 8 + 64]; /* [%s]:NNNNN%iface */ -} Address; - -/* Sort Address values \a left and \a right by metric, returning the usual - * indicators for qsort(). - */ -static int compareAddresses(const void *arg1, const void *arg2) -{ - const Address * const left = arg1; - const Address * const right = arg2; - /* Lower metric the more preferred */ - if (left->metric < right->metric) { - return -1; - } - if (left->metric > right->metric) { - return 1; - } - /* If metrics are equal, lower original index more preferred */ - if (left->orig_idx < right->orig_idx) { - return -1; - } - if (left->orig_idx > right->orig_idx) { - return 1; - } - return 0; -} - -#if defined(HAVE_GETBESTROUTE2) && !defined(__WATCOMC__) -/* There can be multiple routes to "the Internet". And there can be different - * DNS servers associated with each of the interfaces that offer those routes. - * We have to assume that any DNS server can serve any request. But, some DNS - * servers may only respond if requested over their associated interface. But - * we also want to use "the preferred route to the Internet" whenever possible - * (and not use DNS servers on a non-preferred route even by forcing request - * to go out on the associated non-preferred interface). i.e. We want to use - * the DNS servers associated with the same interface that we would use to - * make a general request to anything else. - * - * But, Windows won't sort the DNS servers by the metrics associated with the - * routes and interfaces _even_ though it obviously sends IP packets based on - * those same routes and metrics. So, we must do it ourselves. - * - * So, we sort the DNS servers by the same metric values used to determine how - * an outgoing IP packet will go, thus effectively using the DNS servers - * associated with the interface that the DNS requests themselves will - * travel. This gives us optimal routing and avoids issues where DNS servers - * won't respond to requests that don't arrive via some specific subnetwork - * (and thus some specific interface). - * - * This function computes the metric we use to sort. On the interface - * identified by \a luid, it determines the best route to \a dest and combines - * that route's metric with \a interfaceMetric to compute a metric for the - * destination address on that interface. This metric can be used as a weight - * to sort the DNS server addresses associated with each interface (lower is - * better). - * - * Note that by restricting the route search to the specific interface with - * which the DNS servers are associated, this function asks the question "What - * is the metric for sending IP packets to this DNS server?" which allows us - * to sort the DNS servers correctly. - */ -static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */ - const SOCKADDR_INET * const dest, - const ULONG interfaceMetric) -{ - MIB_IPFORWARD_ROW2 row; - SOCKADDR_INET ignored; - if (GetBestRoute2(/* The interface to use. The index is ignored since we are - * passing a LUID. - */ - luid, 0, - /* No specific source address. */ - NULL, - /* Our destination address. */ - dest, - /* No options. */ - 0, - /* The route row. */ - &row, - /* The best source address, which we don't need. */ - &ignored) != NO_ERROR - /* If the metric is "unused" (-1) or too large for us to add the two - * metrics, use the worst possible, thus sorting this last. - */ - || row.Metric == (ULONG)-1 || - row.Metric > ((ULONG)-1) - interfaceMetric) { - /* Return the worst possible metric. */ - return (ULONG)-1; - } - - /* Return the metric value from that row, plus the interface metric. - * - * See - * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx - * which describes the combination as a "sum". - */ - return row.Metric + interfaceMetric; -} -#endif - -/* - * get_DNS_Windows() - * - * Locates DNS info using GetAdaptersAddresses() function from the Internet - * Protocol Helper (IP Helper) API. When located, this returns a pointer - * in *outptr to a newly allocated memory area holding a null-terminated - * string with a space or comma separated list of DNS IP addresses. - * - * Returns 0 and nullifies *outptr upon inability to return DNSes string. - * - * Returns 1 and sets *outptr when returning a dynamically allocated string. - * - * Implementation supports Windows XP and newer. - */ -# define IPAA_INITIAL_BUF_SZ 15 * 1024 -# define IPAA_MAX_TRIES 3 - -static ares_bool_t get_DNS_Windows(char **outptr) -{ - IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr; - IP_ADAPTER_ADDRESSES *ipaa; - IP_ADAPTER_ADDRESSES *newipaa; - IP_ADAPTER_ADDRESSES *ipaaEntry; - ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ; - ULONG Bufsz = IPAA_INITIAL_BUF_SZ; - ULONG AddrFlags = 0; - int trying = IPAA_MAX_TRIES; - ULONG res; - - /* The capacity of addresses, in elements. */ - size_t addressesSize; - /* The number of elements in addresses. */ - size_t addressesIndex = 0; - /* The addresses we will sort. */ - Address *addresses; - - union { - struct sockaddr *sa; - struct sockaddr_in *sa4; - struct sockaddr_in6 *sa6; - } namesrvr; - - *outptr = NULL; - - ipaa = ares_malloc(Bufsz); - if (!ipaa) { - return ARES_FALSE; - } - - /* Start with enough room for a few DNS server addresses and we'll grow it - * as we encounter more. - */ - addressesSize = 4; - addresses = (Address *)ares_malloc(sizeof(Address) * addressesSize); - if (addresses == NULL) { - /* We need room for at least some addresses to function. */ - ares_free(ipaa); - return ARES_FALSE; - } - - /* Usually this call succeeds with initial buffer size */ - res = GetAdaptersAddresses(AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz); - if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS)) { - goto done; - } - - while ((res == ERROR_BUFFER_OVERFLOW) && (--trying)) { - if (Bufsz < ReqBufsz) { - newipaa = ares_realloc(ipaa, ReqBufsz); - if (!newipaa) { - goto done; - } - Bufsz = ReqBufsz; - ipaa = newipaa; - } - res = GetAdaptersAddresses(AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz); - if (res == ERROR_SUCCESS) { - break; - } - } - if (res != ERROR_SUCCESS) { - goto done; - } - - for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next) { - if (ipaaEntry->OperStatus != IfOperStatusUp) { - continue; - } - - /* For each interface, find any associated DNS servers as IPv4 or IPv6 - * addresses. For each found address, find the best route to that DNS - * server address _on_ _that_ _interface_ (at this moment in time) and - * compute the resulting total metric, just as Windows routing will do. - * Then, sort all the addresses found by the metric. - */ - for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress; ipaDNSAddr != NULL; - ipaDNSAddr = ipaDNSAddr->Next) { - char ipaddr[INET6_ADDRSTRLEN] = ""; - - namesrvr.sa = ipaDNSAddr->Address.lpSockaddr; - - if (namesrvr.sa->sa_family == AF_INET) { - if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) || - (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE)) { - continue; - } - - /* Allocate room for another address, if necessary, else skip. */ - if (addressesIndex == addressesSize) { - const size_t newSize = addressesSize + 4; - Address * const newMem = - (Address *)ares_realloc(addresses, sizeof(Address) * newSize); - if (newMem == NULL) { - continue; - } - addresses = newMem; - addressesSize = newSize; - } - -# if defined(HAVE_GETBESTROUTE2) && !defined(__WATCOMC__) - /* OpenWatcom's builtin Windows SDK does not have a definition for - * MIB_IPFORWARD_ROW2, and also does not allow the usage of SOCKADDR_INET - * as a variable. Let's work around this by returning the worst possible - * metric, but only when using the OpenWatcom compiler. - * It may be worth investigating using a different version of the Windows - * SDK with OpenWatcom in the future, though this may be fixed in OpenWatcom - * 2.0. - */ - addresses[addressesIndex].metric = getBestRouteMetric( - &ipaaEntry->Luid, (SOCKADDR_INET *)((void *)(namesrvr.sa)), - ipaaEntry->Ipv4Metric); -# else - addresses[addressesIndex].metric = (ULONG)-1; -# endif - - /* Record insertion index to make qsort stable */ - addresses[addressesIndex].orig_idx = addressesIndex; - - if (!ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr, ipaddr, - sizeof(ipaddr))) { - continue; - } - snprintf(addresses[addressesIndex].text, - sizeof(addresses[addressesIndex].text), "[%s]:%u", ipaddr, - ntohs(namesrvr.sa4->sin_port)); - ++addressesIndex; - } else if (namesrvr.sa->sa_family == AF_INET6) { - unsigned int ll_scope = 0; - struct ares_addr addr; - - if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any, - sizeof(namesrvr.sa6->sin6_addr)) == 0) { - continue; - } - - /* Allocate room for another address, if necessary, else skip. */ - if (addressesIndex == addressesSize) { - const size_t newSize = addressesSize + 4; - Address * const newMem = - (Address *)ares_realloc(addresses, sizeof(Address) * newSize); - if (newMem == NULL) { - continue; - } - addresses = newMem; - addressesSize = newSize; - } - - /* See if its link-local */ - memset(&addr, 0, sizeof(addr)); - addr.family = AF_INET6; - memcpy(&addr.addr.addr6, &namesrvr.sa6->sin6_addr, 16); - if (ares_addr_is_linklocal(&addr)) { - ll_scope = ipaaEntry->Ipv6IfIndex; - } - -# if defined(HAVE_GETBESTROUTE2) && !defined(__WATCOMC__) - addresses[addressesIndex].metric = getBestRouteMetric( - &ipaaEntry->Luid, (SOCKADDR_INET *)((void *)(namesrvr.sa)), - ipaaEntry->Ipv6Metric); -# else - addresses[addressesIndex].metric = (ULONG)-1; -# endif - - /* Record insertion index to make qsort stable */ - addresses[addressesIndex].orig_idx = addressesIndex; - - if (!ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr, ipaddr, - sizeof(ipaddr))) { - continue; - } - - if (ll_scope) { - snprintf(addresses[addressesIndex].text, - sizeof(addresses[addressesIndex].text), "[%s]:%u%%%u", - ipaddr, ntohs(namesrvr.sa6->sin6_port), ll_scope); - } else { - snprintf(addresses[addressesIndex].text, - sizeof(addresses[addressesIndex].text), "[%s]:%u", ipaddr, - ntohs(namesrvr.sa6->sin6_port)); - } - ++addressesIndex; - } else { - /* Skip non-IPv4/IPv6 addresses completely. */ - continue; - } - } - } - - /* Sort all of the textual addresses by their metric (and original index if - * metrics are equal). */ - qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses); - - /* Join them all into a single string, removing duplicates. */ - { - size_t i; - for (i = 0; i < addressesIndex; ++i) { - size_t j; - /* Look for this address text appearing previously in the results. */ - for (j = 0; j < i; ++j) { - if (strcmp(addresses[j].text, addresses[i].text) == 0) { - break; - } - } - /* Iff we didn't emit this address already, emit it now. */ - if (j == i) { - /* Add that to outptr (if we can). */ - commajoin(outptr, addresses[i].text); - } - } - } - -done: - ares_free(addresses); - - if (ipaa) { - ares_free(ipaa); - } - - if (!*outptr) { - return ARES_FALSE; - } - - return ARES_TRUE; -} - -/* - * get_SuffixList_Windows() - * - * Reads the "DNS Suffix Search List" from registry and writes the list items - * whitespace separated to outptr. If the Search List is empty, the - * "Primary Dns Suffix" is written to outptr. - * - * Returns 0 and nullifies *outptr upon inability to return the suffix list. - * - * Returns 1 and sets *outptr when returning a dynamically allocated string. - * - * Implementation supports Windows Server 2003 and newer - */ -static ares_bool_t get_SuffixList_Windows(char **outptr) -{ - HKEY hKey; - HKEY hKeyEnum; - char keyName[256]; - DWORD keyNameBuffSize; - DWORD keyIdx = 0; - char *p = NULL; - - *outptr = NULL; - - /* 1. Global DNS Suffix Search List */ - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hKey) == - ERROR_SUCCESS) { - get_REG_SZ(hKey, SEARCHLIST_KEY, outptr); - if (get_REG_SZ(hKey, DOMAIN_KEY, &p)) { - commajoin(outptr, p); - ares_free(p); - p = NULL; - } - RegCloseKey(hKey); - } - - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0, KEY_READ, &hKey) == - ERROR_SUCCESS) { - if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p)) { - commajoin(outptr, p); - ares_free(p); - p = NULL; - } - RegCloseKey(hKey); - } - - /* 2. Connection Specific Search List composed of: - * a. Primary DNS Suffix */ - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0, KEY_READ, &hKey) == - ERROR_SUCCESS) { - if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p)) { - commajoin(outptr, p); - ares_free(p); - p = NULL; - } - RegCloseKey(hKey); - } - - /* b. Interface SearchList, Domain, DhcpDomain */ - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0, - KEY_READ, &hKey) == ERROR_SUCCESS) { - for (;;) { - keyNameBuffSize = sizeof(keyName); - if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize, 0, NULL, - NULL, NULL) != ERROR_SUCCESS) { - break; - } - if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum) != - ERROR_SUCCESS) { - continue; - } - /* p can be comma separated (SearchList) */ - if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p)) { - commajoin(outptr, p); - ares_free(p); - p = NULL; - } - if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p)) { - commajoin(outptr, p); - ares_free(p); - p = NULL; - } - if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p)) { - commajoin(outptr, p); - ares_free(p); - p = NULL; - } - RegCloseKey(hKeyEnum); - } - RegCloseKey(hKey); - } - - return *outptr != NULL ? ARES_TRUE : ARES_FALSE; -} - -ares_status_t ares_init_sysconfig_windows(const ares_channel_t *channel, - ares_sysconfig_t *sysconfig) -{ - char *line = NULL; - ares_status_t status = ARES_SUCCESS; - - if (get_DNS_Windows(&line)) { - status = ares_sconfig_append_fromstr(channel, &sysconfig->sconfig, line, - ARES_TRUE); - ares_free(line); - if (status != ARES_SUCCESS) { - goto done; - } - } - - if (get_SuffixList_Windows(&line)) { - sysconfig->domains = ares_strsplit(line, ", ", &sysconfig->ndomains); - ares_free(line); - if (sysconfig->domains == NULL) { - status = ARES_EFILE; - } - if (status != ARES_SUCCESS) { - goto done; - } - } - -done: - return status; -} -#endif diff --git a/vendor/c-ares/src/lib/ares_timeout.c b/vendor/c-ares/src/lib/ares_timeout.c deleted file mode 100644 index 0d2fdcff2..000000000 --- a/vendor/c-ares/src/lib/ares_timeout.c +++ /dev/null @@ -1,151 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_LIMITS_H -# include -#endif - - -void ares_timeval_remaining(ares_timeval_t *remaining, - const ares_timeval_t *now, - const ares_timeval_t *tout) -{ - memset(remaining, 0, sizeof(*remaining)); - - /* Expired! */ - if (tout->sec < now->sec || - (tout->sec == now->sec && tout->usec < now->usec)) { - return; - } - - remaining->sec = tout->sec - now->sec; - if (tout->usec < now->usec) { - remaining->sec -= 1; - remaining->usec = (tout->usec + 1000000) - now->usec; - } else { - remaining->usec = tout->usec - now->usec; - } -} - -void ares_timeval_diff(ares_timeval_t *tvdiff, const ares_timeval_t *tvstart, - const ares_timeval_t *tvstop) -{ - tvdiff->sec = tvstop->sec - tvstart->sec; - if (tvstop->usec > tvstart->usec) { - tvdiff->usec = tvstop->usec - tvstart->usec; - } else { - tvdiff->sec -= 1; - tvdiff->usec = tvstop->usec + 1000000 - tvstart->usec; - } -} - -static void ares_timeval_to_struct_timeval(struct timeval *tv, - const ares_timeval_t *atv) -{ -#ifdef USE_WINSOCK - tv->tv_sec = (long)atv->sec; -#else - tv->tv_sec = (time_t)atv->sec; -#endif - - tv->tv_usec = (int)atv->usec; -} - -static void struct_timeval_to_ares_timeval(ares_timeval_t *atv, - const struct timeval *tv) -{ - atv->sec = (ares_int64_t)tv->tv_sec; - atv->usec = (unsigned int)tv->tv_usec; -} - -static struct timeval *ares_timeout_int(const ares_channel_t *channel, - struct timeval *maxtv, - struct timeval *tvbuf) -{ - const ares_query_t *query; - ares_slist_node_t *node; - ares_timeval_t now; - ares_timeval_t atvbuf; - ares_timeval_t amaxtv; - - /* The minimum timeout of all queries is always the first entry in - * channel->queries_by_timeout */ - node = ares_slist_node_first(channel->queries_by_timeout); - /* no queries/timeout */ - if (node == NULL) { - return maxtv; - } - - query = ares_slist_node_val(node); - - ares_tvnow(&now); - - ares_timeval_remaining(&atvbuf, &now, &query->timeout); - - ares_timeval_to_struct_timeval(tvbuf, &atvbuf); - - if (maxtv == NULL) { - return tvbuf; - } - - /* Return the minimum time between maxtv and tvbuf */ - struct_timeval_to_ares_timeval(&amaxtv, maxtv); - - if (atvbuf.sec > amaxtv.sec) { - return maxtv; - } - - if (atvbuf.sec < amaxtv.sec) { - return tvbuf; - } - - if (atvbuf.usec > amaxtv.usec) { - return maxtv; - } - - return tvbuf; -} - -struct timeval *ares_timeout(const ares_channel_t *channel, - struct timeval *maxtv, struct timeval *tvbuf) -{ - struct timeval *rv; - - if (channel == NULL || tvbuf == NULL) { - return NULL; - } - - ares_channel_lock(channel); - - rv = ares_timeout_int(channel, maxtv, tvbuf); - - ares_channel_unlock(channel); - - return rv; -} diff --git a/vendor/c-ares/src/lib/ares_update_servers.c b/vendor/c-ares/src/lib/ares_update_servers.c deleted file mode 100644 index 70a938149..000000000 --- a/vendor/c-ares/src/lib/ares_update_servers.c +++ /dev/null @@ -1,1362 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2008 Daniel Stenberg - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -#ifdef HAVE_NET_IF_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif - -#if defined(USE_WINSOCK) -# if defined(HAVE_IPHLPAPI_H) -# include -# endif -# if defined(HAVE_NETIOAPI_H) -# include -# endif -#endif - -#include "ares_data.h" -#include "ares_inet_net_pton.h" - -typedef struct { - struct ares_addr addr; - unsigned short tcp_port; - unsigned short udp_port; - - char ll_iface[IF_NAMESIZE]; - unsigned int ll_scope; -} ares_sconfig_t; - -static ares_bool_t ares_addr_match(const struct ares_addr *addr1, - const struct ares_addr *addr2) -{ - if (addr1 == NULL && addr2 == NULL) { - return ARES_TRUE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (addr1 == NULL || addr2 == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (addr1->family != addr2->family) { - return ARES_FALSE; - } - - if (addr1->family == AF_INET && memcmp(&addr1->addr.addr4, &addr2->addr.addr4, - sizeof(addr1->addr.addr4)) == 0) { - return ARES_TRUE; - } - - if (addr1->family == AF_INET6 && - memcmp(&addr1->addr.addr6._S6_un._S6_u8, &addr2->addr.addr6._S6_un._S6_u8, - sizeof(addr1->addr.addr6._S6_un._S6_u8)) == 0) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -ares_bool_t ares_subnet_match(const struct ares_addr *addr, - const struct ares_addr *subnet, - unsigned char netmask) -{ - const unsigned char *addr_ptr; - const unsigned char *subnet_ptr; - size_t len; - size_t i; - - if (addr == NULL || subnet == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (addr->family != subnet->family) { - return ARES_FALSE; - } - - if (addr->family == AF_INET) { - addr_ptr = (const unsigned char *)&addr->addr.addr4; - subnet_ptr = (const unsigned char *)&subnet->addr.addr4; - len = 4; - - if (netmask > 32) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - } else if (addr->family == AF_INET6) { - addr_ptr = (const unsigned char *)&addr->addr.addr6; - subnet_ptr = (const unsigned char *)&subnet->addr.addr6; - len = 16; - - if (netmask > 128) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - } else { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - for (i = 0; i < len && netmask > 0; i++) { - unsigned char mask = 0xff; - if (netmask < 8) { - mask <<= (8 - netmask); - netmask = 0; - } else { - netmask -= 8; - } - - if ((addr_ptr[i] & mask) != (subnet_ptr[i] & mask)) { - return ARES_FALSE; - } - } - - return ARES_TRUE; -} - -ares_bool_t ares_addr_is_linklocal(const struct ares_addr *addr) -{ - struct ares_addr subnet; - const unsigned char subnetaddr[16] = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - - /* fe80::/10 */ - subnet.family = AF_INET6; - memcpy(&subnet.addr.addr6, subnetaddr, 16); - - return ares_subnet_match(addr, &subnet, 10); -} - -static ares_bool_t ares_server_blacklisted(const struct ares_addr *addr) -{ - /* A list of blacklisted IPv6 subnets. */ - const struct { - const unsigned char netbase[16]; - unsigned char netmask; - } blacklist_v6[] = { - /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a - * Site-Local scoped address prefix. These are never valid DNS servers, - * but are known to be returned at least sometimes on Windows and Android. - */ - { { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - 10 } - }; - - size_t i; - - if (addr->family != AF_INET6) { - return ARES_FALSE; - } - - /* See if ipaddr matches any of the entries in the blacklist. */ - for (i = 0; i < sizeof(blacklist_v6) / sizeof(*blacklist_v6); i++) { - struct ares_addr subnet; - subnet.family = AF_INET6; - memcpy(&subnet.addr.addr6, blacklist_v6[i].netbase, 16); - if (ares_subnet_match(addr, &subnet, blacklist_v6[i].netmask)) { - return ARES_TRUE; - } - } - return ARES_FALSE; -} - -static ares_status_t parse_nameserver_uri(ares_buf_t *buf, - ares_sconfig_t *sconfig) -{ - ares_uri_t *uri = NULL; - ares_status_t status = ARES_SUCCESS; - const char *port; - char *ll_scope; - char hoststr[256]; - size_t addrlen; - - status = ares_uri_parse_buf(&uri, buf); - if (status != ARES_SUCCESS) { - return status; - } - - if (!ares_streq("dns", ares_uri_get_scheme(uri))) { - status = ARES_EBADSTR; - goto done; - } - - ares_strcpy(hoststr, ares_uri_get_host(uri), sizeof(hoststr)); - ll_scope = strchr(hoststr, '%'); - if (ll_scope != NULL) { - *ll_scope = 0; - ll_scope++; - ares_strcpy(sconfig->ll_iface, ll_scope, sizeof(sconfig->ll_iface)); - } - - /* Convert ip address from string to network byte order */ - sconfig->addr.family = AF_UNSPEC; - if (ares_dns_pton(hoststr, &sconfig->addr, &addrlen) == NULL) { - status = ARES_EBADSTR; - goto done; - } - - sconfig->udp_port = ares_uri_get_port(uri); - sconfig->tcp_port = sconfig->udp_port; - port = ares_uri_get_query_key(uri, "tcpport"); - if (port != NULL) { - sconfig->tcp_port = (unsigned short)atoi(port); - } - -done: - ares_uri_destroy(uri); - return status; -} - -/* Parse address and port in these formats, either ipv4 or ipv6 addresses - * are allowed: - * ipaddr - * ipv4addr:port - * [ipaddr] - * [ipaddr]:port - * - * Modifiers: %iface - * - * TODO: #domain modifier - * - * If a port is not specified, will set port to 0. - * - * Will fail if an IPv6 nameserver as detected by - * ares_ipv6_server_blacklisted() - * - * Returns an error code on failure, else ARES_SUCCESS - */ - -static ares_status_t parse_nameserver(ares_buf_t *buf, ares_sconfig_t *sconfig) -{ - ares_status_t status; - char ipaddr[INET6_ADDRSTRLEN] = ""; - size_t addrlen; - - memset(sconfig, 0, sizeof(*sconfig)); - - /* Consume any leading whitespace */ - ares_buf_consume_whitespace(buf, ARES_TRUE); - - /* pop off IP address. If it is in [ ] then it can be ipv4 or ipv6. If - * not, ipv4 only */ - if (ares_buf_begins_with(buf, (const unsigned char *)"[", 1)) { - /* Consume [ */ - ares_buf_consume(buf, 1); - - ares_buf_tag(buf); - - /* Consume until ] */ - if (ares_buf_consume_until_charset(buf, (const unsigned char *)"]", 1, - ARES_TRUE) == SIZE_MAX) { - return ARES_EBADSTR; - } - - status = ares_buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr)); - if (status != ARES_SUCCESS) { - return status; - } - - /* Skip over ] */ - ares_buf_consume(buf, 1); - } else { - size_t offset; - - /* Not in [ ], see if '.' is in first 4 characters, if it is, then its ipv4, - * otherwise treat as ipv6 */ - ares_buf_tag(buf); - - offset = ares_buf_consume_until_charset(buf, (const unsigned char *)".", 1, - ARES_TRUE); - ares_buf_tag_rollback(buf); - ares_buf_tag(buf); - - if (offset > 0 && offset < 4) { - /* IPv4 */ - if (ares_buf_consume_charset(buf, (const unsigned char *)"0123456789.", - 11) == 0) { - return ARES_EBADSTR; - } - } else { - /* IPv6 */ - const unsigned char ipv6_charset[] = "ABCDEFabcdef0123456789.:"; - if (ares_buf_consume_charset(buf, ipv6_charset, - sizeof(ipv6_charset) - 1) == 0) { - return ARES_EBADSTR; - } - } - - status = ares_buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr)); - if (status != ARES_SUCCESS) { - return status; - } - } - - /* Convert ip address from string to network byte order */ - sconfig->addr.family = AF_UNSPEC; - if (ares_dns_pton(ipaddr, &sconfig->addr, &addrlen) == NULL) { - return ARES_EBADSTR; - } - - /* Pull off port */ - if (ares_buf_begins_with(buf, (const unsigned char *)":", 1)) { - char portstr[6]; - - /* Consume : */ - ares_buf_consume(buf, 1); - - ares_buf_tag(buf); - - /* Read numbers */ - if (ares_buf_consume_charset(buf, (const unsigned char *)"0123456789", - 10) == 0) { - return ARES_EBADSTR; - } - - status = ares_buf_tag_fetch_string(buf, portstr, sizeof(portstr)); - if (status != ARES_SUCCESS) { - return status; - } - - sconfig->udp_port = (unsigned short)atoi(portstr); - sconfig->tcp_port = sconfig->udp_port; - } - - /* Pull off interface modifier */ - if (ares_buf_begins_with(buf, (const unsigned char *)"%", 1)) { - const unsigned char iface_charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789.-_\\:{}"; - /* Consume % */ - ares_buf_consume(buf, 1); - - ares_buf_tag(buf); - - if (ares_buf_consume_charset(buf, iface_charset, - sizeof(iface_charset) - 1) == 0) { - return ARES_EBADSTR; - } - - status = ares_buf_tag_fetch_string(buf, sconfig->ll_iface, - sizeof(sconfig->ll_iface)); - if (status != ARES_SUCCESS) { - return status; - } - } - - /* Consume any trailing whitespace so we can bail out if there is something - * after we didn't read */ - ares_buf_consume_whitespace(buf, ARES_TRUE); - - if (ares_buf_len(buf) != 0) { - return ARES_EBADSTR; - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_sconfig_linklocal(const ares_channel_t *channel, - ares_sconfig_t *s, - const char *ll_iface) -{ - unsigned int ll_scope = 0; - - - if (ares_str_isnum(ll_iface)) { - char ifname[IF_NAMESIZE] = ""; - ll_scope = (unsigned int)atoi(ll_iface); - if (channel->sock_funcs.aif_indextoname == NULL || - channel->sock_funcs.aif_indextoname(ll_scope, ifname, sizeof(ifname), - channel->sock_func_cb_data) == - NULL) { - DEBUGF(fprintf(stderr, "Interface %s for ipv6 Link Local not found\n", - ll_iface)); - return ARES_ENOTFOUND; - } - ares_strcpy(s->ll_iface, ifname, sizeof(s->ll_iface)); - s->ll_scope = ll_scope; - return ARES_SUCCESS; - } - - if (channel->sock_funcs.aif_nametoindex != NULL) { - ll_scope = - channel->sock_funcs.aif_nametoindex(ll_iface, channel->sock_func_cb_data); - } - if (ll_scope == 0) { - DEBUGF(fprintf(stderr, "Interface %s for ipv6 Link Local not found\n", - ll_iface)); - return ARES_ENOTFOUND; - } - ares_strcpy(s->ll_iface, ll_iface, sizeof(s->ll_iface)); - s->ll_scope = ll_scope; - return ARES_SUCCESS; -} - -ares_status_t ares_sconfig_append(const ares_channel_t *channel, - ares_llist_t **sconfig, - const struct ares_addr *addr, - unsigned short udp_port, - unsigned short tcp_port, const char *ll_iface) -{ - ares_sconfig_t *s; - ares_status_t status; - - if (sconfig == NULL || addr == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Silently skip blacklisted IPv6 servers. */ - if (ares_server_blacklisted(addr)) { - return ARES_SUCCESS; - } - - s = ares_malloc_zero(sizeof(*s)); - if (s == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (*sconfig == NULL) { - *sconfig = ares_llist_create(ares_free); - if (*sconfig == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - memcpy(&s->addr, addr, sizeof(s->addr)); - s->udp_port = udp_port; - s->tcp_port = tcp_port; - - /* Handle link-local enumeration. If an interface is specified on a - * non-link-local address, we'll simply end up ignoring that */ - if (ares_addr_is_linklocal(&s->addr)) { - if (ares_strlen(ll_iface) == 0) { - /* Silently ignore this entry, we require an interface */ - status = ARES_SUCCESS; - goto fail; - } - status = ares_sconfig_linklocal(channel, s, ll_iface); - /* Silently ignore this entry, we can't validate the interface */ - if (status != ARES_SUCCESS) { - status = ARES_SUCCESS; - goto fail; - } - } - - if (ares_llist_insert_last(*sconfig, s) == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; - -fail: - ares_free(s); - - return status; -} - -/* Add the IPv4 or IPv6 nameservers in str (separated by commas or spaces) to - * the servers list, updating servers and nservers as required. - * - * If a nameserver is encapsulated in [ ] it may optionally include a port - * suffix, e.g.: - * [127.0.0.1]:59591 - * - * The extended format is required to support OpenBSD's resolv.conf format: - * https://man.openbsd.org/OpenBSD-5.1/resolv.conf.5 - * As well as MacOS libresolv that may include a non-default port number. - * - * This will silently ignore blacklisted IPv6 nameservers as detected by - * ares_ipv6_server_blacklisted(). - * - * Returns an error code on failure, else ARES_SUCCESS. - */ -ares_status_t ares_sconfig_append_fromstr(const ares_channel_t *channel, - ares_llist_t **sconfig, - const char *str, - ares_bool_t ignore_invalid) -{ - ares_status_t status = ARES_SUCCESS; - ares_buf_t *buf = NULL; - ares_array_t *list = NULL; - size_t num; - size_t i; - - /* On Windows, there may be more than one nameserver specified in the same - * registry key, so we parse input as a space or comma separated list. - */ - buf = ares_buf_create_const((const unsigned char *)str, ares_strlen(str)); - if (buf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_buf_split(buf, (const unsigned char *)" ,", 2, - ARES_BUF_SPLIT_NONE, 0, &list); - if (status != ARES_SUCCESS) { - goto done; - } - - num = ares_array_len(list); - for (i = 0; i < num; i++) { - ares_buf_t **bufptr = ares_array_at(list, i); - ares_buf_t *entry = *bufptr; - ares_sconfig_t s; - - status = parse_nameserver_uri(entry, &s); - if (status != ARES_SUCCESS) { - status = parse_nameserver(entry, &s); - } - - if (status != ARES_SUCCESS) { - if (ignore_invalid) { - continue; - } else { - goto done; - } - } - - status = ares_sconfig_append(channel, sconfig, &s.addr, s.udp_port, - s.tcp_port, s.ll_iface); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ARES_SUCCESS; - -done: - ares_array_destroy(list); - ares_buf_destroy(buf); - return status; -} - -static unsigned short ares_sconfig_get_port(const ares_channel_t *channel, - const ares_sconfig_t *s, - ares_bool_t is_tcp) -{ - unsigned short port = is_tcp ? s->tcp_port : s->udp_port; - - if (port == 0) { - port = is_tcp ? channel->tcp_port : channel->udp_port; - } - - if (port == 0) { - port = 53; - } - - return port; -} - -static ares_slist_node_t *ares_server_find(const ares_channel_t *channel, - const ares_sconfig_t *s) -{ - ares_slist_node_t *node; - - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - const ares_server_t *server = ares_slist_node_val(node); - - if (!ares_addr_match(&server->addr, &s->addr)) { - continue; - } - - if (server->tcp_port != ares_sconfig_get_port(channel, s, ARES_TRUE)) { - continue; - } - - if (server->udp_port != ares_sconfig_get_port(channel, s, ARES_FALSE)) { - continue; - } - - return node; - } - return NULL; -} - -static ares_bool_t ares_server_isdup(const ares_channel_t *channel, - ares_llist_node_t *s) -{ - /* Scan backwards to see if this is a duplicate */ - ares_llist_node_t *prev; - const ares_sconfig_t *server = ares_llist_node_val(s); - - for (prev = ares_llist_node_prev(s); prev != NULL; - prev = ares_llist_node_prev(prev)) { - const ares_sconfig_t *p = ares_llist_node_val(prev); - - if (!ares_addr_match(&server->addr, &p->addr)) { - continue; - } - - if (ares_sconfig_get_port(channel, server, ARES_TRUE) != - ares_sconfig_get_port(channel, p, ARES_TRUE)) { - continue; - } - - if (ares_sconfig_get_port(channel, server, ARES_FALSE) != - ares_sconfig_get_port(channel, p, ARES_FALSE)) { - continue; - } - - return ARES_TRUE; - } - - return ARES_FALSE; -} - -static ares_status_t ares_server_create(ares_channel_t *channel, - const ares_sconfig_t *sconfig, - size_t idx) -{ - ares_status_t status; - ares_server_t *server = ares_malloc_zero(sizeof(*server)); - - if (server == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - server->idx = idx; - server->channel = channel; - server->udp_port = ares_sconfig_get_port(channel, sconfig, ARES_FALSE); - server->tcp_port = ares_sconfig_get_port(channel, sconfig, ARES_TRUE); - server->addr.family = sconfig->addr.family; - server->next_retry_time.sec = 0; - server->next_retry_time.usec = 0; - - if (sconfig->addr.family == AF_INET) { - memcpy(&server->addr.addr.addr4, &sconfig->addr.addr.addr4, - sizeof(server->addr.addr.addr4)); - } else if (sconfig->addr.family == AF_INET6) { - memcpy(&server->addr.addr.addr6, &sconfig->addr.addr.addr6, - sizeof(server->addr.addr.addr6)); - } - - /* Copy over link-local settings */ - if (ares_strlen(sconfig->ll_iface)) { - ares_strcpy(server->ll_iface, sconfig->ll_iface, sizeof(server->ll_iface)); - server->ll_scope = sconfig->ll_scope; - } - - server->connections = ares_llist_create(NULL); - if (server->connections == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (ares_slist_insert(channel->servers, server) == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ARES_SUCCESS; - -done: - if (status != ARES_SUCCESS) { - ares_destroy_server(server); /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return status; -} - -static ares_bool_t ares_server_in_newconfig(const ares_server_t *server, - ares_llist_t *srvlist) -{ - ares_llist_node_t *node; - const ares_channel_t *channel = server->channel; - - for (node = ares_llist_node_first(srvlist); node != NULL; - node = ares_llist_node_next(node)) { - const ares_sconfig_t *s = ares_llist_node_val(node); - - if (!ares_addr_match(&server->addr, &s->addr)) { - continue; - } - - if (server->tcp_port != ares_sconfig_get_port(channel, s, ARES_TRUE)) { - continue; - } - - if (server->udp_port != ares_sconfig_get_port(channel, s, ARES_FALSE)) { - continue; - } - - return ARES_TRUE; - } - - return ARES_FALSE; -} - -static ares_bool_t ares_servers_remove_stale(ares_channel_t *channel, - ares_llist_t *srvlist) -{ - ares_bool_t stale_removed = ARES_FALSE; - ares_slist_node_t *snode = ares_slist_node_first(channel->servers); - - while (snode != NULL) { - ares_slist_node_t *snext = ares_slist_node_next(snode); - const ares_server_t *server = ares_slist_node_val(snode); - if (!ares_server_in_newconfig(server, srvlist)) { - /* This will clean up all server state via the destruction callback and - * move any queries to new servers */ - ares_slist_node_destroy(snode); - stale_removed = ARES_TRUE; - } - snode = snext; - } - return stale_removed; -} - -static void ares_servers_trim_single(ares_channel_t *channel) -{ - while (ares_slist_len(channel->servers) > 1) { - ares_slist_node_destroy(ares_slist_node_last(channel->servers)); - } -} - -ares_status_t ares_servers_update(ares_channel_t *channel, - ares_llist_t *server_list, - ares_bool_t user_specified) -{ - ares_llist_node_t *node; - size_t idx = 0; - ares_status_t status; - ares_bool_t list_changed = ARES_FALSE; - - if (channel == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* NOTE: a NULL or zero entry server list is considered valid due to - * real-world people needing support for this for their test harnesses - */ - - /* Add new entries */ - for (node = ares_llist_node_first(server_list); node != NULL; - node = ares_llist_node_next(node)) { - const ares_sconfig_t *sconfig = ares_llist_node_val(node); - ares_slist_node_t *snode; - - /* If a server has already appeared in the list of new servers, skip it. */ - if (ares_server_isdup(channel, node)) { - continue; - } - - snode = ares_server_find(channel, sconfig); - if (snode != NULL) { - ares_server_t *server = ares_slist_node_val(snode); - - /* Copy over link-local settings. Its possible some of this data has - * changed, maybe ... */ - if (ares_strlen(sconfig->ll_iface)) { - ares_strcpy(server->ll_iface, sconfig->ll_iface, - sizeof(server->ll_iface)); - server->ll_scope = sconfig->ll_scope; - } - - if (server->idx != idx) { - server->idx = idx; - /* Index changed, reinsert node, doesn't require any memory - * allocations so can't fail. */ - ares_slist_node_reinsert(snode); - } - } else { - status = ares_server_create(channel, sconfig, idx); - if (status != ARES_SUCCESS) { - goto done; - } - - list_changed = ARES_TRUE; - } - - idx++; - } - - /* Remove any servers that don't exist in the current configuration */ - if (ares_servers_remove_stale(channel, server_list)) { - list_changed = ARES_TRUE; - } - - /* Trim to one server if ARES_FLAG_PRIMARY is set. */ - if (channel->flags & ARES_FLAG_PRIMARY) { - ares_servers_trim_single(channel); - } - - if (user_specified) { - /* Save servers as if they were passed in as an option */ - channel->optmask |= ARES_OPT_SERVERS; - } - - /* Clear any cached query results only if the server list changed */ - if (list_changed) { - ares_qcache_flush(channel->qcache); - } - - status = ARES_SUCCESS; - -done: - return status; -} - -static ares_status_t - ares_addr_node_to_sconfig_llist(const struct ares_addr_node *servers, - ares_llist_t **llist) -{ - const struct ares_addr_node *node; - ares_llist_t *s; - - *llist = NULL; - - s = ares_llist_create(ares_free); - if (s == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (node = servers; node != NULL; node = node->next) { - ares_sconfig_t *sconfig; - - /* Invalid entry */ - if (node->family != AF_INET && node->family != AF_INET6) { - continue; - } - - sconfig = ares_malloc_zero(sizeof(*sconfig)); - if (sconfig == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - sconfig->addr.family = node->family; - if (node->family == AF_INET) { - memcpy(&sconfig->addr.addr.addr4, &node->addr.addr4, - sizeof(sconfig->addr.addr.addr4)); - } else if (sconfig->addr.family == AF_INET6) { - memcpy(&sconfig->addr.addr.addr6, &node->addr.addr6, - sizeof(sconfig->addr.addr.addr6)); - } - - if (ares_llist_insert_last(s, sconfig) == NULL) { - ares_free(sconfig); /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - *llist = s; - return ARES_SUCCESS; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - ares_llist_destroy(s); - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ -} - -static ares_status_t - ares_addrpnode_to_sconfig_llist(const struct ares_addr_port_node *servers, - ares_llist_t **llist) -{ - const struct ares_addr_port_node *node; - ares_llist_t *s; - - *llist = NULL; - - s = ares_llist_create(ares_free); - if (s == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (node = servers; node != NULL; node = node->next) { - ares_sconfig_t *sconfig; - - /* Invalid entry */ - if (node->family != AF_INET && node->family != AF_INET6) { - continue; - } - - sconfig = ares_malloc_zero(sizeof(*sconfig)); - if (sconfig == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - sconfig->addr.family = node->family; - if (node->family == AF_INET) { - memcpy(&sconfig->addr.addr.addr4, &node->addr.addr4, - sizeof(sconfig->addr.addr.addr4)); - } else if (sconfig->addr.family == AF_INET6) { - memcpy(&sconfig->addr.addr.addr6, &node->addr.addr6, - sizeof(sconfig->addr.addr.addr6)); - } - - sconfig->tcp_port = (unsigned short)node->tcp_port; - sconfig->udp_port = (unsigned short)node->udp_port; - - if (ares_llist_insert_last(s, sconfig) == NULL) { - ares_free(sconfig); /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - *llist = s; - return ARES_SUCCESS; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - ares_llist_destroy(s); - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ -} - -ares_status_t ares_in_addr_to_sconfig_llist(const struct in_addr *servers, - size_t nservers, - ares_llist_t **llist) -{ - size_t i; - ares_llist_t *s; - - *llist = NULL; - - s = ares_llist_create(ares_free); - if (s == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (i = 0; servers != NULL && i < nservers; i++) { - ares_sconfig_t *sconfig; - - sconfig = ares_malloc_zero(sizeof(*sconfig)); - if (sconfig == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - sconfig->addr.family = AF_INET; - memcpy(&sconfig->addr.addr.addr4, &servers[i], - sizeof(sconfig->addr.addr.addr4)); - - if (ares_llist_insert_last(s, sconfig) == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - *llist = s; - return ARES_SUCCESS; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - ares_llist_destroy(s); - return ARES_ENOMEM; - /* LCOV_EXCL_STOP */ -} - -static ares_bool_t ares_server_use_uri(const ares_server_t *server) -{ - /* Currently only reason to use new format is if the ports for udp and tcp - * are different */ - if (server->tcp_port != server->udp_port) { - return ARES_TRUE; - } - return ARES_FALSE; -} - -static ares_status_t ares_get_server_addr_uri(const ares_server_t *server, - ares_buf_t *buf) -{ - ares_uri_t *uri = NULL; - ares_status_t status; - char addr[INET6_ADDRSTRLEN]; - - uri = ares_uri_create(); - if (uri == NULL) { - return ARES_ENOMEM; - } - - status = ares_uri_set_scheme(uri, "dns"); - if (status != ARES_SUCCESS) { - goto done; - } - - ares_inet_ntop(server->addr.family, &server->addr.addr, addr, sizeof(addr)); - - if (ares_strlen(server->ll_iface)) { - char addr_iface[256]; - - snprintf(addr_iface, sizeof(addr_iface), "%s%%%s", addr, server->ll_iface); - status = ares_uri_set_host(uri, addr_iface); - } else { - status = ares_uri_set_host(uri, addr); - } - - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_set_port(uri, server->udp_port); - if (status != ARES_SUCCESS) { - goto done; - } - - if (server->udp_port != server->tcp_port) { - char port[6]; - snprintf(port, sizeof(port), "%d", server->tcp_port); - status = ares_uri_set_query_key(uri, "tcpport", port); - if (status != ARES_SUCCESS) { - goto done; - } - } - - status = ares_uri_write_buf(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_uri_destroy(uri); - return status; -} - -/* Write out the details of a server to a buffer */ -ares_status_t ares_get_server_addr(const ares_server_t *server, ares_buf_t *buf) -{ - ares_status_t status; - char addr[INET6_ADDRSTRLEN]; - - if (ares_server_use_uri(server)) { - return ares_get_server_addr_uri(server, buf); - } - - /* ipv4addr or [ipv6addr] */ - if (server->addr.family == AF_INET6) { - status = ares_buf_append_byte(buf, '['); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - ares_inet_ntop(server->addr.family, &server->addr.addr, addr, sizeof(addr)); - - status = ares_buf_append_str(buf, addr); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (server->addr.family == AF_INET6) { - status = ares_buf_append_byte(buf, ']'); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - /* :port */ - status = ares_buf_append_byte(buf, ':'); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_num_dec(buf, server->udp_port, 0); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* %iface */ - if (ares_strlen(server->ll_iface)) { - status = ares_buf_append_byte(buf, '%'); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_str(buf, server->ll_iface); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return ARES_SUCCESS; -} - -int ares_get_servers(const ares_channel_t *channel, - struct ares_addr_node **servers) -{ - struct ares_addr_node *srvr_head = NULL; - struct ares_addr_node *srvr_last = NULL; - struct ares_addr_node *srvr_curr; - ares_status_t status = ARES_SUCCESS; - ares_slist_node_t *node; - - if (channel == NULL) { - return ARES_ENODATA; - } - - ares_channel_lock(channel); - - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - const ares_server_t *server = ares_slist_node_val(node); - - /* Allocate storage for this server node appending it to the list */ - srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_NODE); - if (!srvr_curr) { - status = ARES_ENOMEM; - break; - } - if (srvr_last) { - srvr_last->next = srvr_curr; - } else { - srvr_head = srvr_curr; - } - srvr_last = srvr_curr; - - /* Fill this server node data */ - srvr_curr->family = server->addr.family; - if (srvr_curr->family == AF_INET) { - memcpy(&srvr_curr->addr.addr4, &server->addr.addr.addr4, - sizeof(srvr_curr->addr.addr4)); - } else { - memcpy(&srvr_curr->addr.addr6, &server->addr.addr.addr6, - sizeof(srvr_curr->addr.addr6)); - } - } - - if (status != ARES_SUCCESS) { - ares_free_data(srvr_head); - srvr_head = NULL; - } - - *servers = srvr_head; - - ares_channel_unlock(channel); - - return (int)status; -} - -int ares_get_servers_ports(const ares_channel_t *channel, - struct ares_addr_port_node **servers) -{ - struct ares_addr_port_node *srvr_head = NULL; - struct ares_addr_port_node *srvr_last = NULL; - struct ares_addr_port_node *srvr_curr; - ares_status_t status = ARES_SUCCESS; - ares_slist_node_t *node; - - if (channel == NULL) { - return ARES_ENODATA; - } - - ares_channel_lock(channel); - - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - const ares_server_t *server = ares_slist_node_val(node); - - /* Allocate storage for this server node appending it to the list */ - srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_PORT_NODE); - if (!srvr_curr) { - status = ARES_ENOMEM; - break; - } - if (srvr_last) { - srvr_last->next = srvr_curr; - } else { - srvr_head = srvr_curr; - } - srvr_last = srvr_curr; - - /* Fill this server node data */ - srvr_curr->family = server->addr.family; - srvr_curr->udp_port = server->udp_port; - srvr_curr->tcp_port = server->tcp_port; - - if (srvr_curr->family == AF_INET) { - memcpy(&srvr_curr->addr.addr4, &server->addr.addr.addr4, - sizeof(srvr_curr->addr.addr4)); - } else { - memcpy(&srvr_curr->addr.addr6, &server->addr.addr.addr6, - sizeof(srvr_curr->addr.addr6)); - } - } - - if (status != ARES_SUCCESS) { - ares_free_data(srvr_head); - srvr_head = NULL; - } - - *servers = srvr_head; - - ares_channel_unlock(channel); - return (int)status; -} - -int ares_set_servers(ares_channel_t *channel, - const struct ares_addr_node *servers) -{ - ares_llist_t *slist; - ares_status_t status; - - if (channel == NULL) { - return ARES_ENODATA; - } - - status = ares_addr_node_to_sconfig_llist(servers, &slist); - if (status != ARES_SUCCESS) { - return (int)status; - } - - ares_channel_lock(channel); - status = ares_servers_update(channel, slist, ARES_TRUE); - ares_channel_unlock(channel); - - ares_llist_destroy(slist); - - return (int)status; -} - -int ares_set_servers_ports(ares_channel_t *channel, - const struct ares_addr_port_node *servers) -{ - ares_llist_t *slist; - ares_status_t status; - - if (channel == NULL) { - return ARES_ENODATA; - } - - status = ares_addrpnode_to_sconfig_llist(servers, &slist); - if (status != ARES_SUCCESS) { - return (int)status; - } - - ares_channel_lock(channel); - status = ares_servers_update(channel, slist, ARES_TRUE); - ares_channel_unlock(channel); - - ares_llist_destroy(slist); - - return (int)status; -} - -/* Incoming string format: host[:port][,host[:port]]... */ -/* IPv6 addresses with ports require square brackets [fe80::1]:53 */ -static ares_status_t set_servers_csv(ares_channel_t *channel, const char *_csv) -{ - ares_status_t status; - ares_llist_t *slist = NULL; - - if (channel == NULL) { - return ARES_ENODATA; - } - - if (ares_strlen(_csv) == 0) { - /* blank all servers */ - ares_channel_lock(channel); - status = ares_servers_update(channel, NULL, ARES_TRUE); - ares_channel_unlock(channel); - return status; - } - - status = ares_sconfig_append_fromstr(channel, &slist, _csv, ARES_FALSE); - if (status != ARES_SUCCESS) { - ares_llist_destroy(slist); - return status; - } - - ares_channel_lock(channel); - status = ares_servers_update(channel, slist, ARES_TRUE); - ares_channel_unlock(channel); - - ares_llist_destroy(slist); - - return status; -} - -/* We'll go ahead and honor ports anyhow */ -int ares_set_servers_csv(ares_channel_t *channel, const char *_csv) -{ - return (int)set_servers_csv(channel, _csv); -} - -int ares_set_servers_ports_csv(ares_channel_t *channel, const char *_csv) -{ - return (int)set_servers_csv(channel, _csv); -} - -char *ares_get_servers_csv(const ares_channel_t *channel) -{ - ares_buf_t *buf = NULL; - char *out = NULL; - ares_slist_node_t *node; - - ares_channel_lock(channel); - - buf = ares_buf_create(); - if (buf == NULL) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (node = ares_slist_node_first(channel->servers); node != NULL; - node = ares_slist_node_next(node)) { - ares_status_t status; - const ares_server_t *server = ares_slist_node_val(node); - - if (ares_buf_len(buf)) { - status = ares_buf_append_byte(buf, ','); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ares_get_server_addr(server, buf); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - out = ares_buf_finish_str(buf, NULL); - buf = NULL; - -done: - ares_channel_unlock(channel); - ares_buf_destroy(buf); - return out; -} - -void ares_set_server_state_callback(ares_channel_t *channel, - ares_server_state_callback cb, void *data) -{ - if (channel == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - channel->server_state_cb = cb; - channel->server_state_cb_data = data; -} diff --git a/vendor/c-ares/src/lib/ares_version.c b/vendor/c-ares/src/lib/ares_version.c deleted file mode 100644 index f50f65b0d..000000000 --- a/vendor/c-ares/src/lib/ares_version.c +++ /dev/null @@ -1,36 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -const char *ares_version(int *version) -{ - if (version) { - *version = ARES_VERSION; - } - - return ARES_VERSION_STR; -} diff --git a/vendor/c-ares/src/lib/dsa/ares_array.c b/vendor/c-ares/src/lib/dsa/ares_array.c deleted file mode 100644 index c421d5c5f..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_array.c +++ /dev/null @@ -1,394 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_array.h" - -#define ARES__ARRAY_MIN 4 - -struct ares_array { - ares_array_destructor_t destruct; - void *arr; - size_t member_size; - size_t cnt; - size_t offset; - size_t alloc_cnt; -}; - -ares_array_t *ares_array_create(size_t member_size, - ares_array_destructor_t destruct) -{ - ares_array_t *arr; - - if (member_size == 0) { - return NULL; - } - - arr = ares_malloc_zero(sizeof(*arr)); - if (arr == NULL) { - return NULL; - } - - arr->member_size = member_size; - arr->destruct = destruct; - return arr; -} - -size_t ares_array_len(const ares_array_t *arr) -{ - if (arr == NULL) { - return 0; - } - return arr->cnt; -} - -void *ares_array_at(ares_array_t *arr, size_t idx) -{ - if (arr == NULL || idx >= arr->cnt) { - return NULL; - } - return (unsigned char *)arr->arr + ((idx + arr->offset) * arr->member_size); -} - -const void *ares_array_at_const(const ares_array_t *arr, size_t idx) -{ - if (arr == NULL || idx >= arr->cnt) { - return NULL; - } - return (unsigned char *)arr->arr + ((idx + arr->offset) * arr->member_size); -} - -ares_status_t ares_array_sort(ares_array_t *arr, ares_array_cmp_t cmp) -{ - if (arr == NULL || cmp == NULL) { - return ARES_EFORMERR; - } - - /* Nothing to sort */ - if (arr->cnt < 2) { - return ARES_SUCCESS; - } - - qsort((unsigned char *)arr->arr + (arr->offset * arr->member_size), arr->cnt, - arr->member_size, cmp); - return ARES_SUCCESS; -} - -void ares_array_destroy(ares_array_t *arr) -{ - size_t i; - - if (arr == NULL) { - return; - } - - if (arr->destruct != NULL) { - for (i = 0; i < arr->cnt; i++) { - arr->destruct(ares_array_at(arr, i)); - } - } - - ares_free(arr->arr); - ares_free(arr); -} - -/* NOTE: this function operates on actual indexes, NOT indexes using the - * arr->offset */ -static ares_status_t ares_array_move(ares_array_t *arr, size_t dest_idx, - size_t src_idx) -{ - void *dest_ptr; - const void *src_ptr; - size_t nmembers; - - if (arr == NULL || dest_idx >= arr->alloc_cnt || src_idx >= arr->alloc_cnt) { - return ARES_EFORMERR; - } - - /* Nothing to do */ - if (dest_idx == src_idx) { - return ARES_SUCCESS; - } - - dest_ptr = (unsigned char *)arr->arr + (dest_idx * arr->member_size); - src_ptr = (unsigned char *)arr->arr + (src_idx * arr->member_size); - - /* Check to make sure shifting to the right won't overflow our allocation - * boundary */ - if (dest_idx > src_idx && arr->cnt + (dest_idx - src_idx) > arr->alloc_cnt) { - return ARES_EFORMERR; - } - - nmembers = arr->cnt - (src_idx - arr->offset); - memmove(dest_ptr, src_ptr, nmembers * arr->member_size); - - return ARES_SUCCESS; -} - -void *ares_array_finish(ares_array_t *arr, size_t *num_members) -{ - void *ptr; - - if (arr == NULL || num_members == NULL) { - return NULL; - } - - /* Make sure we move data to beginning of allocation */ - if (arr->offset != 0) { - if (ares_array_move(arr, 0, arr->offset) != ARES_SUCCESS) { - return NULL; - } - arr->offset = 0; - } - - ptr = arr->arr; - *num_members = arr->cnt; - ares_free(arr); - return ptr; -} - -ares_status_t ares_array_set_size(ares_array_t *arr, size_t size) -{ - void *temp; - - if (arr == NULL || size == 0 || size < arr->cnt) { - return ARES_EFORMERR; - } - - /* Always operate on powers of 2 */ - size = ares_round_up_pow2(size); - - if (size < ARES__ARRAY_MIN) { - size = ARES__ARRAY_MIN; - } - - /* If our allocation size is already large enough, skip */ - if (size <= arr->alloc_cnt) { - return ARES_SUCCESS; - } - - temp = ares_realloc_zero(arr->arr, arr->alloc_cnt * arr->member_size, - size * arr->member_size); - if (temp == NULL) { - return ARES_ENOMEM; - } - arr->alloc_cnt = size; - arr->arr = temp; - return ARES_SUCCESS; -} - -ares_status_t ares_array_insert_at(void **elem_ptr, ares_array_t *arr, - size_t idx) -{ - void *ptr; - ares_status_t status; - - if (arr == NULL) { - return ARES_EFORMERR; - } - - /* Not >= since we are allowed to append to the end */ - if (idx > arr->cnt) { - return ARES_EFORMERR; - } - - /* Allocate more if needed */ - status = ares_array_set_size(arr, arr->cnt + 1); - if (status != ARES_SUCCESS) { - return status; - } - - /* Shift if we have memory but not enough room at the end */ - if (arr->cnt + 1 + arr->offset > arr->alloc_cnt) { - status = ares_array_move(arr, 0, arr->offset); - if (status != ARES_SUCCESS) { - return status; - } - arr->offset = 0; - } - - /* If we're inserting anywhere other than the end, we need to move some - * elements out of the way */ - if (idx != arr->cnt) { - status = ares_array_move(arr, idx + arr->offset + 1, idx + arr->offset); - if (status != ARES_SUCCESS) { - return status; - } - } - - /* Ok, we're guaranteed to have a gap where we need it, lets zero it out, - * and return it */ - ptr = (unsigned char *)arr->arr + ((idx + arr->offset) * arr->member_size); - memset(ptr, 0, arr->member_size); - arr->cnt++; - - if (elem_ptr) { - *elem_ptr = ptr; - } - - return ARES_SUCCESS; -} - -ares_status_t ares_array_insert_last(void **elem_ptr, ares_array_t *arr) -{ - return ares_array_insert_at(elem_ptr, arr, ares_array_len(arr)); -} - -ares_status_t ares_array_insert_first(void **elem_ptr, ares_array_t *arr) -{ - return ares_array_insert_at(elem_ptr, arr, 0); -} - -ares_status_t ares_array_insertdata_at(ares_array_t *arr, size_t idx, - const void *data_ptr) -{ - ares_status_t status; - void *ptr = NULL; - - status = ares_array_insert_at(&ptr, arr, idx); - if (status != ARES_SUCCESS) { - return status; - } - memcpy(ptr, data_ptr, arr->member_size); - return ARES_SUCCESS; -} - -ares_status_t ares_array_insertdata_last(ares_array_t *arr, - const void *data_ptr) -{ - ares_status_t status; - void *ptr = NULL; - - status = ares_array_insert_last(&ptr, arr); - if (status != ARES_SUCCESS) { - return status; - } - memcpy(ptr, data_ptr, arr->member_size); - return ARES_SUCCESS; -} - -ares_status_t ares_array_insertdata_first(ares_array_t *arr, - const void *data_ptr) -{ - ares_status_t status; - void *ptr = NULL; - - status = ares_array_insert_last(&ptr, arr); - if (status != ARES_SUCCESS) { - return status; - } - memcpy(ptr, data_ptr, arr->member_size); - return ARES_SUCCESS; -} - -void *ares_array_first(ares_array_t *arr) -{ - return ares_array_at(arr, 0); -} - -void *ares_array_last(ares_array_t *arr) -{ - size_t cnt = ares_array_len(arr); - if (cnt == 0) { - return NULL; - } - return ares_array_at(arr, cnt - 1); -} - -const void *ares_array_first_const(const ares_array_t *arr) -{ - return ares_array_at_const(arr, 0); -} - -const void *ares_array_last_const(const ares_array_t *arr) -{ - size_t cnt = ares_array_len(arr); - if (cnt == 0) { - return NULL; - } - return ares_array_at_const(arr, cnt - 1); -} - -ares_status_t ares_array_claim_at(void *dest, size_t dest_size, - ares_array_t *arr, size_t idx) -{ - ares_status_t status; - - if (arr == NULL || idx >= arr->cnt) { - return ARES_EFORMERR; - } - - if (dest != NULL && dest_size < arr->member_size) { - return ARES_EFORMERR; - } - - if (dest) { - memcpy(dest, ares_array_at(arr, idx), arr->member_size); - } - - if (idx == 0) { - /* Optimization, if first element, just increment offset, makes removing a - * lot from the start quick */ - arr->offset++; - } else if (idx != arr->cnt - 1) { - /* Must shift entire array if removing an element from the middle. Does - * nothing if removing last element other than decrement count. */ - status = ares_array_move(arr, idx + arr->offset, idx + arr->offset + 1); - if (status != ARES_SUCCESS) { - return status; - } - } - - arr->cnt--; - return ARES_SUCCESS; -} - -ares_status_t ares_array_remove_at(ares_array_t *arr, size_t idx) -{ - void *ptr = ares_array_at(arr, idx); - if (arr == NULL || ptr == NULL) { - return ARES_EFORMERR; - } - - if (arr->destruct != NULL) { - arr->destruct(ptr); - } - - return ares_array_claim_at(NULL, 0, arr, idx); -} - -ares_status_t ares_array_remove_first(ares_array_t *arr) -{ - return ares_array_remove_at(arr, 0); -} - -ares_status_t ares_array_remove_last(ares_array_t *arr) -{ - size_t cnt = ares_array_len(arr); - if (cnt == 0) { - return ARES_EFORMERR; - } - return ares_array_remove_at(arr, cnt - 1); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_htable.c b/vendor/c-ares/src/lib/dsa/ares_htable.c deleted file mode 100644 index f76b67cae..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable.c +++ /dev/null @@ -1,447 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_llist.h" -#include "ares_htable.h" - -#define ARES__HTABLE_MAX_BUCKETS (1U << 24) -#define ARES__HTABLE_MIN_BUCKETS (1U << 4) -#define ARES__HTABLE_EXPAND_PERCENT 75 - -struct ares_htable { - ares_htable_hashfunc_t hash; - ares_htable_bucket_key_t bucket_key; - ares_htable_bucket_free_t bucket_free; - ares_htable_key_eq_t key_eq; - unsigned int seed; - unsigned int size; - size_t num_keys; - size_t num_collisions; - /* NOTE: if we converted buckets into ares_slist_t we could guarantee on - * hash collisions we would have O(log n) worst case insert and search - * performance. (We'd also need to make key_eq into a key_cmp to - * support sort). That said, risk with a random hash seed is near zero, - * and ares_slist_t is heavier weight, so I think using ares_llist_t - * is an overall win. */ - ares_llist_t **buckets; -}; - -static unsigned int ares_htable_generate_seed(ares_htable_t *htable) -{ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - /* Seed needs to be static for fuzzing */ - return 0; -#else - unsigned int seed = 0; - time_t t = time(NULL); - - /* Mix stack address, heap address, and time to generate a random seed, it - * doesn't have to be super secure, just quick. Likelihood of a hash - * collision attack is very low with a small amount of effort */ - seed |= (unsigned int)((size_t)htable & 0xFFFFFFFF); - seed |= (unsigned int)((size_t)&seed & 0xFFFFFFFF); - seed |= (unsigned int)(((ares_uint64_t)t) & 0xFFFFFFFF); - return seed; -#endif -} - -static void ares_htable_buckets_destroy(ares_llist_t **buckets, - unsigned int size, - ares_bool_t destroy_vals) -{ - unsigned int i; - - if (buckets == NULL) { - return; - } - - for (i = 0; i < size; i++) { - if (buckets[i] == NULL) { - continue; - } - - if (!destroy_vals) { - ares_llist_replace_destructor(buckets[i], NULL); - } - - ares_llist_destroy(buckets[i]); - } - - ares_free(buckets); -} - -void ares_htable_destroy(ares_htable_t *htable) -{ - if (htable == NULL) { - return; - } - ares_htable_buckets_destroy(htable->buckets, htable->size, ARES_TRUE); - ares_free(htable); -} - -ares_htable_t *ares_htable_create(ares_htable_hashfunc_t hash_func, - ares_htable_bucket_key_t bucket_key, - ares_htable_bucket_free_t bucket_free, - ares_htable_key_eq_t key_eq) -{ - ares_htable_t *htable = NULL; - - if (hash_func == NULL || bucket_key == NULL || bucket_free == NULL || - key_eq == NULL) { - goto fail; - } - - htable = ares_malloc_zero(sizeof(*htable)); - if (htable == NULL) { - goto fail; - } - - htable->hash = hash_func; - htable->bucket_key = bucket_key; - htable->bucket_free = bucket_free; - htable->key_eq = key_eq; - htable->seed = ares_htable_generate_seed(htable); - htable->size = ARES__HTABLE_MIN_BUCKETS; - htable->buckets = ares_malloc_zero(sizeof(*htable->buckets) * htable->size); - - if (htable->buckets == NULL) { - goto fail; - } - - return htable; - -fail: - ares_htable_destroy(htable); - return NULL; -} - -const void **ares_htable_all_buckets(const ares_htable_t *htable, size_t *num) -{ - const void **out = NULL; - size_t cnt = 0; - size_t i; - - if (htable == NULL || num == NULL) { - return NULL; /* LCOV_EXCL_LINE */ - } - - *num = 0; - - out = ares_malloc_zero(sizeof(*out) * htable->num_keys); - if (out == NULL) { - return NULL; /* LCOV_EXCL_LINE */ - } - - for (i = 0; i < htable->size; i++) { - ares_llist_node_t *node; - for (node = ares_llist_node_first(htable->buckets[i]); node != NULL; - node = ares_llist_node_next(node)) { - out[cnt++] = ares_llist_node_val(node); - } - } - - *num = cnt; - return out; -} - -/*! Grabs the Hashtable index from the key and length. The h index is - * the hash of the function reduced to the size of the bucket list. - * We are doing "hash & (size - 1)" since we are guaranteeing a power of - * 2 for size. This is equivalent to "hash % size", but should be more - * efficient */ -#define HASH_IDX(h, key) h->hash(key, h->seed) & (h->size - 1) - -static ares_llist_node_t *ares_htable_find(const ares_htable_t *htable, - unsigned int idx, const void *key) -{ - ares_llist_node_t *node = NULL; - - for (node = ares_llist_node_first(htable->buckets[idx]); node != NULL; - node = ares_llist_node_next(node)) { - if (htable->key_eq(key, htable->bucket_key(ares_llist_node_val(node)))) { - break; - } - } - - return node; -} - -static ares_bool_t ares_htable_expand(ares_htable_t *htable) -{ - ares_llist_t **buckets = NULL; - unsigned int old_size = htable->size; - size_t i; - ares_llist_t **prealloc_llist = NULL; - size_t prealloc_llist_len = 0; - ares_bool_t rv = ARES_FALSE; - - /* Not a failure, just won't expand */ - if (old_size == ARES__HTABLE_MAX_BUCKETS) { - return ARES_TRUE; /* LCOV_EXCL_LINE */ - } - - htable->size <<= 1; - - /* We must pre-allocate all memory we'll need before moving entries to the - * new hash array. Otherwise if there's a memory allocation failure in the - * middle, we wouldn't be able to recover. */ - buckets = ares_malloc_zero(sizeof(*buckets) * htable->size); - if (buckets == NULL) { - goto done; /* LCOV_EXCL_LINE */ - } - - /* The maximum number of new llists we'll need is the number of collisions - * that were recorded */ - prealloc_llist_len = htable->num_collisions; - if (prealloc_llist_len) { - prealloc_llist = - ares_malloc_zero(sizeof(*prealloc_llist) * prealloc_llist_len); - if (prealloc_llist == NULL) { - goto done; /* LCOV_EXCL_LINE */ - } - } - for (i = 0; i < prealloc_llist_len; i++) { - prealloc_llist[i] = ares_llist_create(htable->bucket_free); - if (prealloc_llist[i] == NULL) { - goto done; - } - } - - /* Iterate across all buckets and move the entries to the new buckets */ - htable->num_collisions = 0; - for (i = 0; i < old_size; i++) { - ares_llist_node_t *node; - - /* Nothing in this bucket */ - if (htable->buckets[i] == NULL) { - continue; - } - - /* Fast path optimization (most likely case), there is likely only a single - * entry in both the source and destination, check for this to confirm and - * if so, just move the bucket over */ - if (ares_llist_len(htable->buckets[i]) == 1) { - const void *val = ares_llist_first_val(htable->buckets[i]); - size_t idx = HASH_IDX(htable, htable->bucket_key(val)); - - if (buckets[idx] == NULL) { - /* Swap! */ - buckets[idx] = htable->buckets[i]; - htable->buckets[i] = NULL; - continue; - } - } - - /* Slow path, collisions */ - while ((node = ares_llist_node_first(htable->buckets[i])) != NULL) { - const void *val = ares_llist_node_val(node); - size_t idx = HASH_IDX(htable, htable->bucket_key(val)); - - /* Try fast path again as maybe we popped one collision off and the - * next we can reuse the llist parent */ - if (buckets[idx] == NULL && ares_llist_len(htable->buckets[i]) == 1) { - /* Swap! */ - buckets[idx] = htable->buckets[i]; - htable->buckets[i] = NULL; - break; - } - - /* Grab one off our preallocated list */ - if (buckets[idx] == NULL) { - /* Silence static analysis, this isn't possible but it doesn't know */ - if (prealloc_llist == NULL || prealloc_llist_len == 0) { - goto done; /* LCOV_EXCL_LINE */ - } - buckets[idx] = prealloc_llist[prealloc_llist_len - 1]; - prealloc_llist_len--; - } else { - /* Collision occurred since the bucket wasn't empty */ - htable->num_collisions++; - } - - ares_llist_node_mvparent_first(node, buckets[idx]); - } - - /* Abandoned bucket, destroy */ - if (htable->buckets[i] != NULL) { - ares_llist_destroy(htable->buckets[i]); - htable->buckets[i] = NULL; - } - } - - /* We have guaranteed all the buckets have either been moved or destroyed, - * so we just call ares_free() on the array and swap out the pointer */ - ares_free(htable->buckets); - htable->buckets = buckets; - buckets = NULL; - rv = ARES_TRUE; - -done: - ares_free(buckets); - /* destroy any unused preallocated buckets */ - ares_htable_buckets_destroy(prealloc_llist, (unsigned int)prealloc_llist_len, - ARES_FALSE); - - /* On failure, we need to restore the htable size */ - if (rv != ARES_TRUE) { - htable->size = old_size; /* LCOV_EXCL_LINE */ - } - - return rv; -} - -ares_bool_t ares_htable_insert(ares_htable_t *htable, void *bucket) -{ - unsigned int idx = 0; - ares_llist_node_t *node = NULL; - const void *key = NULL; - - if (htable == NULL || bucket == NULL) { - return ARES_FALSE; - } - - - key = htable->bucket_key(bucket); - idx = HASH_IDX(htable, key); - - /* See if we have a matching bucket already, if so, replace it */ - node = ares_htable_find(htable, idx, key); - if (node != NULL) { - ares_llist_node_replace(node, bucket); - return ARES_TRUE; - } - - /* Check to see if we should rehash because likelihood of collisions has - * increased beyond our threshold */ - if (htable->num_keys + 1 > - (htable->size * ARES__HTABLE_EXPAND_PERCENT) / 100) { - if (!ares_htable_expand(htable)) { - return ARES_FALSE; /* LCOV_EXCL_LINE */ - } - /* If we expanded, need to calculate a new index */ - idx = HASH_IDX(htable, key); - } - - /* We lazily allocate the linked list */ - if (htable->buckets[idx] == NULL) { - htable->buckets[idx] = ares_llist_create(htable->bucket_free); - if (htable->buckets[idx] == NULL) { - return ARES_FALSE; - } - } - - node = ares_llist_insert_first(htable->buckets[idx], bucket); - if (node == NULL) { - return ARES_FALSE; - } - - /* Track collisions for rehash stability */ - if (ares_llist_len(htable->buckets[idx]) > 1) { - htable->num_collisions++; - } - - htable->num_keys++; - - return ARES_TRUE; -} - -void *ares_htable_get(const ares_htable_t *htable, const void *key) -{ - unsigned int idx; - - if (htable == NULL || key == NULL) { - return NULL; - } - - idx = HASH_IDX(htable, key); - - return ares_llist_node_val(ares_htable_find(htable, idx, key)); -} - -ares_bool_t ares_htable_remove(ares_htable_t *htable, const void *key) -{ - ares_llist_node_t *node; - unsigned int idx; - - if (htable == NULL || key == NULL) { - return ARES_FALSE; - } - - idx = HASH_IDX(htable, key); - node = ares_htable_find(htable, idx, key); - if (node == NULL) { - return ARES_FALSE; - } - - htable->num_keys--; - - /* Reduce collisions */ - if (ares_llist_len(ares_llist_node_parent(node)) > 1) { - htable->num_collisions--; - } - - ares_llist_node_destroy(node); - return ARES_TRUE; -} - -size_t ares_htable_num_keys(const ares_htable_t *htable) -{ - if (htable == NULL) { - return 0; - } - return htable->num_keys; -} - -unsigned int ares_htable_hash_FNV1a(const unsigned char *key, size_t key_len, - unsigned int seed) -{ - unsigned int hv = seed ^ 2166136261U; - size_t i; - - for (i = 0; i < key_len; i++) { - hv ^= (unsigned int)key[i]; - /* hv *= 16777619 (0x01000193) */ - hv += (hv << 1) + (hv << 4) + (hv << 7) + (hv << 8) + (hv << 24); - } - - return hv; -} - -/* Case insensitive version, meant for ASCII strings */ -unsigned int ares_htable_hash_FNV1a_casecmp(const unsigned char *key, - size_t key_len, unsigned int seed) -{ - unsigned int hv = seed ^ 2166136261U; - size_t i; - - for (i = 0; i < key_len; i++) { - hv ^= (unsigned int)ares_tolower(key[i]); - /* hv *= 16777619 (0x01000193) */ - hv += (hv << 1) + (hv << 4) + (hv << 7) + (hv << 8) + (hv << 24); - } - - return hv; -} diff --git a/vendor/c-ares/src/lib/dsa/ares_htable.h b/vendor/c-ares/src/lib/dsa/ares_htable.h deleted file mode 100644 index 5700286eb..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable.h +++ /dev/null @@ -1,174 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__HTABLE_H -#define __ARES__HTABLE_H - - -/*! \addtogroup ares_htable Base HashTable Data Structure - * - * This is a basic hashtable data structure that is meant to be wrapped - * by a higher level implementation. This data structure is designed to - * be callback-based in order to facilitate wrapping without needing to - * worry about any underlying complexities of the hashtable implementation. - * - * This implementation supports automatic growing by powers of 2 when reaching - * 75% capacity. A rehash will be performed on the expanded bucket list. - * - * Average time complexity: - * - Insert: O(1) - * - Search: O(1) - * - Delete: O(1) - * - * @{ - */ - -struct ares_htable; - -/*! Opaque data type for generic hash table implementation */ -typedef struct ares_htable ares_htable_t; - -/*! Callback for generating a hash of the key. - * - * \param[in] key pointer to key to be hashed - * \param[in] seed randomly generated seed used by hash function. - * value is specific to the hashtable instance - * but otherwise will not change between calls. - * \return hash - */ -typedef unsigned int (*ares_htable_hashfunc_t)(const void *key, - unsigned int seed); - -/*! Callback to free the bucket - * - * \param[in] bucket user provided bucket - */ -typedef void (*ares_htable_bucket_free_t)(void *bucket); - -/*! Callback to extract the key from the user-provided bucket - * - * \param[in] bucket user provided bucket - * \return pointer to key held in bucket - */ -typedef const void *(*ares_htable_bucket_key_t)(const void *bucket); - -/*! Callback to compare two keys for equality - * - * \param[in] key1 first key - * \param[in] key2 second key - * \return ARES_TRUE if equal, ARES_FALSE if not - */ -typedef ares_bool_t (*ares_htable_key_eq_t)(const void *key1, const void *key2); - - -/*! Destroy the initialized hashtable - * - * \param[in] htable initialized hashtable - */ -void ares_htable_destroy(ares_htable_t *htable); - -/*! Create a new hashtable - * - * \param[in] hash_func Required. Callback for Hash function. - * \param[in] bucket_key Required. Callback to extract key from bucket. - * \param[in] bucket_free Required. Callback to free bucket. - * \param[in] key_eq Required. Callback to check for key equality. - * \return initialized hashtable. NULL if out of memory or misuse. - */ -ares_htable_t *ares_htable_create(ares_htable_hashfunc_t hash_func, - ares_htable_bucket_key_t bucket_key, - ares_htable_bucket_free_t bucket_free, - ares_htable_key_eq_t key_eq); - -/*! Count of keys from initialized hashtable - * - * \param[in] htable Initialized hashtable. - * \return count of keys - */ -size_t ares_htable_num_keys(const ares_htable_t *htable); - -/*! Retrieve an array of buckets from the hashtable. This is mainly used as - * a helper for retrieving an array of keys. - * - * \param[in] htable Initialized hashtable - * \param[out] num Count of returned buckets - * \return Array of pointers to the buckets. These are internal pointers - * to data within the hashtable, so if the key is removed, there - * will be a dangling pointer. It is expected wrappers will make - * such values safe by duplicating them. - */ -const void **ares_htable_all_buckets(const ares_htable_t *htable, size_t *num); - -/*! Insert bucket into hashtable - * - * \param[in] htable Initialized hashtable. - * \param[in] bucket User-provided bucket to insert. Takes "ownership". Not - * allowed to be NULL. - * \return ARES_TRUE on success, ARES_FALSE if out of memory - */ -ares_bool_t ares_htable_insert(ares_htable_t *htable, void *bucket); - -/*! Retrieve bucket from hashtable based on key. - * - * \param[in] htable Initialized hashtable - * \param[in] key Pointer to key to use for comparison. - * \return matching bucket, or NULL if not found. - */ -void *ares_htable_get(const ares_htable_t *htable, const void *key); - -/*! Remove bucket from hashtable by key - * - * \param[in] htable Initialized hashtable - * \param[in] key Pointer to key to use for comparison - * \return ARES_TRUE if found, ARES_FALSE if not found - */ -ares_bool_t ares_htable_remove(ares_htable_t *htable, const void *key); - -/*! FNV1a hash algorithm. Can be used as underlying primitive for building - * a wrapper hashtable. - * - * \param[in] key pointer to key - * \param[in] key_len Length of key - * \param[in] seed Seed for generating hash - * \return hash value - */ -unsigned int ares_htable_hash_FNV1a(const unsigned char *key, size_t key_len, - unsigned int seed); - -/*! FNV1a hash algorithm, but converts all characters to lowercase before - * hashing to make the hash case-insensitive. Can be used as underlying - * primitive for building a wrapper hashtable. Used on string-based keys. - * - * \param[in] key pointer to key - * \param[in] key_len Length of key - * \param[in] seed Seed for generating hash - * \return hash value - */ -unsigned int ares_htable_hash_FNV1a_casecmp(const unsigned char *key, - size_t key_len, unsigned int seed); - -/*! @} */ - -#endif /* __ARES__HTABLE_H */ diff --git a/vendor/c-ares/src/lib/dsa/ares_htable_asvp.c b/vendor/c-ares/src/lib/dsa/ares_htable_asvp.c deleted file mode 100644 index 32f4d2c99..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable_asvp.c +++ /dev/null @@ -1,224 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_htable.h" -#include "ares_htable_asvp.h" - -struct ares_htable_asvp { - ares_htable_asvp_val_free_t free_val; - ares_htable_t *hash; -}; - -typedef struct { - ares_socket_t key; - void *val; - ares_htable_asvp_t *parent; -} ares_htable_asvp_bucket_t; - -void ares_htable_asvp_destroy(ares_htable_asvp_t *htable) -{ - if (htable == NULL) { - return; - } - - ares_htable_destroy(htable->hash); - ares_free(htable); -} - -static unsigned int hash_func(const void *key, unsigned int seed) -{ - const ares_socket_t *arg = key; - return ares_htable_hash_FNV1a((const unsigned char *)arg, sizeof(*arg), seed); -} - -static const void *bucket_key(const void *bucket) -{ - const ares_htable_asvp_bucket_t *arg = bucket; - return &arg->key; -} - -static void bucket_free(void *bucket) -{ - ares_htable_asvp_bucket_t *arg = bucket; - - if (arg->parent->free_val) { - arg->parent->free_val(arg->val); - } - - ares_free(arg); -} - -static ares_bool_t key_eq(const void *key1, const void *key2) -{ - const ares_socket_t *k1 = key1; - const ares_socket_t *k2 = key2; - - if (*k1 == *k2) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -ares_htable_asvp_t * - ares_htable_asvp_create(ares_htable_asvp_val_free_t val_free) -{ - ares_htable_asvp_t *htable = ares_malloc(sizeof(*htable)); - if (htable == NULL) { - goto fail; - } - - htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq); - if (htable->hash == NULL) { - goto fail; - } - - htable->free_val = val_free; - - return htable; - -fail: - if (htable) { - ares_htable_destroy(htable->hash); - ares_free(htable); - } - return NULL; -} - -ares_socket_t *ares_htable_asvp_keys(const ares_htable_asvp_t *htable, - size_t *num) -{ - const void **buckets = NULL; - size_t cnt = 0; - ares_socket_t *out = NULL; - size_t i; - - if (htable == NULL || num == NULL) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *num = 0; - - buckets = ares_htable_all_buckets(htable->hash, &cnt); - if (buckets == NULL || cnt == 0) { - return NULL; - } - - out = ares_malloc_zero(sizeof(*out) * cnt); - if (out == NULL) { - ares_free(buckets); /* LCOV_EXCL_LINE: OutOfMemory */ - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (i = 0; i < cnt; i++) { - out[i] = ((const ares_htable_asvp_bucket_t *)buckets[i])->key; - } - - ares_free(buckets); - *num = cnt; - return out; -} - -ares_bool_t ares_htable_asvp_insert(ares_htable_asvp_t *htable, - ares_socket_t key, void *val) -{ - ares_htable_asvp_bucket_t *bucket = NULL; - - if (htable == NULL) { - goto fail; - } - - bucket = ares_malloc(sizeof(*bucket)); - if (bucket == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - bucket->parent = htable; - bucket->key = key; - bucket->val = val; - - if (!ares_htable_insert(htable->hash, bucket)) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_TRUE; - -fail: - if (bucket) { - ares_free(bucket); /* LCOV_EXCL_LINE: OutOfMemory */ - } - return ARES_FALSE; -} - -ares_bool_t ares_htable_asvp_get(const ares_htable_asvp_t *htable, - ares_socket_t key, void **val) -{ - ares_htable_asvp_bucket_t *bucket = NULL; - - if (val) { - *val = NULL; - } - - if (htable == NULL) { - return ARES_FALSE; - } - - bucket = ares_htable_get(htable->hash, &key); - if (bucket == NULL) { - return ARES_FALSE; - } - - if (val) { - *val = bucket->val; - } - return ARES_TRUE; -} - -void *ares_htable_asvp_get_direct(const ares_htable_asvp_t *htable, - ares_socket_t key) -{ - void *val = NULL; - ares_htable_asvp_get(htable, key, &val); - return val; -} - -ares_bool_t ares_htable_asvp_remove(ares_htable_asvp_t *htable, - ares_socket_t key) -{ - if (htable == NULL) { - return ARES_FALSE; - } - - return ares_htable_remove(htable->hash, &key); -} - -size_t ares_htable_asvp_num_keys(const ares_htable_asvp_t *htable) -{ - if (htable == NULL) { - return 0; - } - return ares_htable_num_keys(htable->hash); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_htable_dict.c b/vendor/c-ares/src/lib/dsa/ares_htable_dict.c deleted file mode 100644 index 93d7a2013..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable_dict.c +++ /dev/null @@ -1,228 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_htable.h" -#include "ares_htable_dict.h" - -struct ares_htable_dict { - ares_htable_t *hash; -}; - -typedef struct { - char *key; - char *val; - ares_htable_dict_t *parent; -} ares_htable_dict_bucket_t; - -void ares_htable_dict_destroy(ares_htable_dict_t *htable) -{ - if (htable == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_htable_destroy(htable->hash); - ares_free(htable); -} - -static unsigned int hash_func(const void *key, unsigned int seed) -{ - return ares_htable_hash_FNV1a_casecmp(key, ares_strlen(key), seed); -} - -static const void *bucket_key(const void *bucket) -{ - const ares_htable_dict_bucket_t *arg = bucket; - return arg->key; -} - -static void bucket_free(void *bucket) -{ - ares_htable_dict_bucket_t *arg = bucket; - - ares_free(arg->key); - ares_free(arg->val); - - ares_free(arg); -} - -static ares_bool_t key_eq(const void *key1, const void *key2) -{ - return ares_strcaseeq(key1, key2); -} - -ares_htable_dict_t *ares_htable_dict_create(void) -{ - ares_htable_dict_t *htable = ares_malloc(sizeof(*htable)); - if (htable == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq); - if (htable->hash == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return htable; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - if (htable) { - ares_htable_destroy(htable->hash); - ares_free(htable); - } - return NULL; - /* LCOV_EXCL_STOP */ -} - -ares_bool_t ares_htable_dict_insert(ares_htable_dict_t *htable, const char *key, - const char *val) -{ - ares_htable_dict_bucket_t *bucket = NULL; - - if (htable == NULL || ares_strlen(key) == 0) { - goto fail; - } - - bucket = ares_malloc_zero(sizeof(*bucket)); - if (bucket == NULL) { - goto fail; - } - - bucket->parent = htable; - bucket->key = ares_strdup(key); - if (bucket->key == NULL) { - goto fail; - } - - if (val != NULL) { - bucket->val = ares_strdup(val); - if (bucket->val == NULL) { - goto fail; - } - } - - if (!ares_htable_insert(htable->hash, bucket)) { - goto fail; - } - - return ARES_TRUE; - -fail: - if (bucket) { - ares_free(bucket->val); - ares_free(bucket); - } - return ARES_FALSE; -} - -ares_bool_t ares_htable_dict_get(const ares_htable_dict_t *htable, - const char *key, const char **val) -{ - const ares_htable_dict_bucket_t *bucket = NULL; - - if (val) { - *val = NULL; - } - - if (htable == NULL) { - return ARES_FALSE; - } - - bucket = ares_htable_get(htable->hash, key); - if (bucket == NULL) { - return ARES_FALSE; - } - - if (val) { - *val = bucket->val; - } - return ARES_TRUE; -} - -const char *ares_htable_dict_get_direct(const ares_htable_dict_t *htable, - const char *key) -{ - const char *val = NULL; - ares_htable_dict_get(htable, key, &val); - return val; -} - -ares_bool_t ares_htable_dict_remove(ares_htable_dict_t *htable, const char *key) -{ - if (htable == NULL) { - return ARES_FALSE; - } - - return ares_htable_remove(htable->hash, key); -} - -size_t ares_htable_dict_num_keys(const ares_htable_dict_t *htable) -{ - if (htable == NULL) { - return 0; - } - return ares_htable_num_keys(htable->hash); -} - -char **ares_htable_dict_keys(const ares_htable_dict_t *htable, size_t *num) -{ - const void **buckets = NULL; - size_t cnt = 0; - char **out = NULL; - size_t i; - - if (htable == NULL || num == NULL) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *num = 0; - - buckets = ares_htable_all_buckets(htable->hash, &cnt); - if (buckets == NULL || cnt == 0) { - return NULL; - } - - out = ares_malloc_zero(sizeof(*out) * cnt); - if (out == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (i = 0; i < cnt; i++) { - out[i] = ares_strdup(((const ares_htable_dict_bucket_t *)buckets[i])->key); - if (out[i] == NULL) { - goto fail; - } - } - - ares_free(buckets); - *num = cnt; - return out; - -fail: - *num = 0; - ares_free_array(out, cnt, ares_free); - return NULL; -} diff --git a/vendor/c-ares/src/lib/dsa/ares_htable_strvp.c b/vendor/c-ares/src/lib/dsa/ares_htable_strvp.c deleted file mode 100644 index daca117e8..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable_strvp.c +++ /dev/null @@ -1,210 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_htable.h" -#include "ares_htable_strvp.h" - -struct ares_htable_strvp { - ares_htable_strvp_val_free_t free_val; - ares_htable_t *hash; -}; - -typedef struct { - char *key; - void *val; - ares_htable_strvp_t *parent; -} ares_htable_strvp_bucket_t; - -void ares_htable_strvp_destroy(ares_htable_strvp_t *htable) -{ - if (htable == NULL) { - return; - } - - ares_htable_destroy(htable->hash); - ares_free(htable); -} - -static unsigned int hash_func(const void *key, unsigned int seed) -{ - const char *arg = key; - return ares_htable_hash_FNV1a_casecmp((const unsigned char *)arg, - ares_strlen(arg), seed); -} - -static const void *bucket_key(const void *bucket) -{ - const ares_htable_strvp_bucket_t *arg = bucket; - return arg->key; -} - -static void bucket_free(void *bucket) -{ - ares_htable_strvp_bucket_t *arg = bucket; - - if (arg->parent->free_val) { - arg->parent->free_val(arg->val); - } - ares_free(arg->key); - ares_free(arg); -} - -static ares_bool_t key_eq(const void *key1, const void *key2) -{ - return ares_strcaseeq(key1, key2); -} - -ares_htable_strvp_t * - ares_htable_strvp_create(ares_htable_strvp_val_free_t val_free) -{ - ares_htable_strvp_t *htable = ares_malloc(sizeof(*htable)); - if (htable == NULL) { - goto fail; - } - - htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq); - if (htable->hash == NULL) { - goto fail; - } - - htable->free_val = val_free; - - return htable; - -fail: - if (htable) { - ares_htable_destroy(htable->hash); - ares_free(htable); - } - return NULL; -} - -ares_bool_t ares_htable_strvp_insert(ares_htable_strvp_t *htable, - const char *key, void *val) -{ - ares_htable_strvp_bucket_t *bucket = NULL; - - if (htable == NULL || key == NULL) { - goto fail; - } - - bucket = ares_malloc(sizeof(*bucket)); - if (bucket == NULL) { - goto fail; - } - - bucket->parent = htable; - bucket->key = ares_strdup(key); - if (bucket->key == NULL) { - goto fail; - } - bucket->val = val; - - if (!ares_htable_insert(htable->hash, bucket)) { - goto fail; - } - - return ARES_TRUE; - -fail: - if (bucket) { - ares_free(bucket->key); - ares_free(bucket); - } - return ARES_FALSE; -} - -ares_bool_t ares_htable_strvp_get(const ares_htable_strvp_t *htable, - const char *key, void **val) -{ - ares_htable_strvp_bucket_t *bucket = NULL; - - if (val) { - *val = NULL; - } - - if (htable == NULL || key == NULL) { - return ARES_FALSE; - } - - bucket = ares_htable_get(htable->hash, key); - if (bucket == NULL) { - return ARES_FALSE; - } - - if (val) { - *val = bucket->val; - } - return ARES_TRUE; -} - -void *ares_htable_strvp_get_direct(const ares_htable_strvp_t *htable, - const char *key) -{ - void *val = NULL; - ares_htable_strvp_get(htable, key, &val); - return val; -} - -ares_bool_t ares_htable_strvp_remove(ares_htable_strvp_t *htable, - const char *key) -{ - if (htable == NULL) { - return ARES_FALSE; - } - - return ares_htable_remove(htable->hash, key); -} - -void *ares_htable_strvp_claim(ares_htable_strvp_t *htable, const char *key) -{ - ares_htable_strvp_bucket_t *bucket = NULL; - void *val; - - if (htable == NULL || key == NULL) { - return NULL; - } - - bucket = ares_htable_get(htable->hash, key); - if (bucket == NULL) { - return NULL; - } - - /* Unassociate value from bucket */ - val = bucket->val; - bucket->val = NULL; - - ares_htable_strvp_remove(htable, key); - return val; -} - -size_t ares_htable_strvp_num_keys(const ares_htable_strvp_t *htable) -{ - if (htable == NULL) { - return 0; - } - return ares_htable_num_keys(htable->hash); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_htable_szvp.c b/vendor/c-ares/src/lib/dsa/ares_htable_szvp.c deleted file mode 100644 index fdaae0a57..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable_szvp.c +++ /dev/null @@ -1,188 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_htable.h" -#include "ares_htable_szvp.h" - -struct ares_htable_szvp { - ares_htable_szvp_val_free_t free_val; - ares_htable_t *hash; -}; - -typedef struct { - size_t key; - void *val; - ares_htable_szvp_t *parent; -} ares_htable_szvp_bucket_t; - -void ares_htable_szvp_destroy(ares_htable_szvp_t *htable) -{ - if (htable == NULL) { - return; - } - - ares_htable_destroy(htable->hash); - ares_free(htable); -} - -static unsigned int hash_func(const void *key, unsigned int seed) -{ - const size_t *arg = key; - return ares_htable_hash_FNV1a((const unsigned char *)arg, sizeof(*arg), seed); -} - -static const void *bucket_key(const void *bucket) -{ - const ares_htable_szvp_bucket_t *arg = bucket; - return &arg->key; -} - -static void bucket_free(void *bucket) -{ - ares_htable_szvp_bucket_t *arg = bucket; - - if (arg->parent->free_val) { - arg->parent->free_val(arg->val); - } - - ares_free(arg); -} - -static ares_bool_t key_eq(const void *key1, const void *key2) -{ - const size_t *k1 = key1; - const size_t *k2 = key2; - - if (*k1 == *k2) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -ares_htable_szvp_t * - ares_htable_szvp_create(ares_htable_szvp_val_free_t val_free) -{ - ares_htable_szvp_t *htable = ares_malloc(sizeof(*htable)); - if (htable == NULL) { - goto fail; - } - - htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq); - if (htable->hash == NULL) { - goto fail; - } - - htable->free_val = val_free; - - return htable; - -fail: - if (htable) { - ares_htable_destroy(htable->hash); - ares_free(htable); - } - return NULL; -} - -ares_bool_t ares_htable_szvp_insert(ares_htable_szvp_t *htable, size_t key, - void *val) -{ - ares_htable_szvp_bucket_t *bucket = NULL; - - if (htable == NULL) { - goto fail; - } - - bucket = ares_malloc(sizeof(*bucket)); - if (bucket == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - bucket->parent = htable; - bucket->key = key; - bucket->val = val; - - if (!ares_htable_insert(htable->hash, bucket)) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_TRUE; - -fail: - if (bucket) { - ares_free(bucket); /* LCOV_EXCL_LINE: OutOfMemory */ - } - return ARES_FALSE; -} - -ares_bool_t ares_htable_szvp_get(const ares_htable_szvp_t *htable, size_t key, - void **val) -{ - ares_htable_szvp_bucket_t *bucket = NULL; - - if (val) { - *val = NULL; - } - - if (htable == NULL) { - return ARES_FALSE; - } - - bucket = ares_htable_get(htable->hash, &key); - if (bucket == NULL) { - return ARES_FALSE; - } - - if (val) { - *val = bucket->val; - } - return ARES_TRUE; -} - -void *ares_htable_szvp_get_direct(const ares_htable_szvp_t *htable, size_t key) -{ - void *val = NULL; - ares_htable_szvp_get(htable, key, &val); - return val; -} - -ares_bool_t ares_htable_szvp_remove(ares_htable_szvp_t *htable, size_t key) -{ - if (htable == NULL) { - return ARES_FALSE; - } - - return ares_htable_remove(htable->hash, &key); -} - -size_t ares_htable_szvp_num_keys(const ares_htable_szvp_t *htable) -{ - if (htable == NULL) { - return 0; - } - return ares_htable_num_keys(htable->hash); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_htable_vpstr.c b/vendor/c-ares/src/lib/dsa/ares_htable_vpstr.c deleted file mode 100644 index 86c881f76..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable_vpstr.c +++ /dev/null @@ -1,186 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_htable.h" -#include "ares_htable_vpstr.h" - -struct ares_htable_vpstr { - ares_htable_t *hash; -}; - -typedef struct { - void *key; - char *val; - ares_htable_vpstr_t *parent; -} ares_htable_vpstr_bucket_t; - -void ares_htable_vpstr_destroy(ares_htable_vpstr_t *htable) -{ - if (htable == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_htable_destroy(htable->hash); - ares_free(htable); -} - -static unsigned int hash_func(const void *key, unsigned int seed) -{ - return ares_htable_hash_FNV1a((const unsigned char *)&key, sizeof(key), seed); -} - -static const void *bucket_key(const void *bucket) -{ - const ares_htable_vpstr_bucket_t *arg = bucket; - return arg->key; -} - -static void bucket_free(void *bucket) -{ - ares_htable_vpstr_bucket_t *arg = bucket; - - ares_free(arg->val); - - ares_free(arg); -} - -static ares_bool_t key_eq(const void *key1, const void *key2) -{ - if (key1 == key2) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -ares_htable_vpstr_t *ares_htable_vpstr_create(void) -{ - ares_htable_vpstr_t *htable = ares_malloc(sizeof(*htable)); - if (htable == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq); - if (htable->hash == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return htable; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - if (htable) { - ares_htable_destroy(htable->hash); - ares_free(htable); - } - return NULL; - /* LCOV_EXCL_STOP */ -} - -ares_bool_t ares_htable_vpstr_insert(ares_htable_vpstr_t *htable, void *key, - const char *val) -{ - ares_htable_vpstr_bucket_t *bucket = NULL; - - if (htable == NULL) { - goto fail; - } - - bucket = ares_malloc(sizeof(*bucket)); - if (bucket == NULL) { - goto fail; - } - - bucket->parent = htable; - bucket->key = key; - bucket->val = ares_strdup(val); - if (bucket->val == NULL) { - goto fail; - } - - if (!ares_htable_insert(htable->hash, bucket)) { - goto fail; - } - - return ARES_TRUE; - -fail: - if (bucket) { - ares_free(bucket->val); - ares_free(bucket); - } - return ARES_FALSE; -} - -ares_bool_t ares_htable_vpstr_get(const ares_htable_vpstr_t *htable, - const void *key, const char **val) -{ - const ares_htable_vpstr_bucket_t *bucket = NULL; - - if (val) { - *val = NULL; - } - - if (htable == NULL) { - return ARES_FALSE; - } - - bucket = ares_htable_get(htable->hash, key); - if (bucket == NULL) { - return ARES_FALSE; - } - - if (val) { - *val = bucket->val; - } - return ARES_TRUE; -} - -const char *ares_htable_vpstr_get_direct(const ares_htable_vpstr_t *htable, - const void *key) -{ - const char *val = NULL; - ares_htable_vpstr_get(htable, key, &val); - return val; -} - -ares_bool_t ares_htable_vpstr_remove(ares_htable_vpstr_t *htable, - const void *key) -{ - if (htable == NULL) { - return ARES_FALSE; - } - - return ares_htable_remove(htable->hash, key); -} - -size_t ares_htable_vpstr_num_keys(const ares_htable_vpstr_t *htable) -{ - if (htable == NULL) { - return 0; - } - return ares_htable_num_keys(htable->hash); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_htable_vpvp.c b/vendor/c-ares/src/lib/dsa/ares_htable_vpvp.c deleted file mode 100644 index 14fd6e9da..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_htable_vpvp.c +++ /dev/null @@ -1,194 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_htable.h" -#include "ares_htable_vpvp.h" - -struct ares_htable_vpvp { - ares_htable_vpvp_key_free_t free_key; - ares_htable_vpvp_val_free_t free_val; - ares_htable_t *hash; -}; - -typedef struct { - void *key; - void *val; - ares_htable_vpvp_t *parent; -} ares_htable_vpvp_bucket_t; - -void ares_htable_vpvp_destroy(ares_htable_vpvp_t *htable) -{ - if (htable == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_htable_destroy(htable->hash); - ares_free(htable); -} - -static unsigned int hash_func(const void *key, unsigned int seed) -{ - return ares_htable_hash_FNV1a((const unsigned char *)&key, sizeof(key), seed); -} - -static const void *bucket_key(const void *bucket) -{ - const ares_htable_vpvp_bucket_t *arg = bucket; - return arg->key; -} - -static void bucket_free(void *bucket) -{ - ares_htable_vpvp_bucket_t *arg = bucket; - - if (arg->parent->free_key) { - arg->parent->free_key(arg->key); - } - - if (arg->parent->free_val) { - arg->parent->free_val(arg->val); - } - - ares_free(arg); -} - -static ares_bool_t key_eq(const void *key1, const void *key2) -{ - if (key1 == key2) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -ares_htable_vpvp_t * - ares_htable_vpvp_create(ares_htable_vpvp_key_free_t key_free, - ares_htable_vpvp_val_free_t val_free) -{ - ares_htable_vpvp_t *htable = ares_malloc(sizeof(*htable)); - if (htable == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq); - if (htable->hash == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - htable->free_key = key_free; - htable->free_val = val_free; - - return htable; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - if (htable) { - ares_htable_destroy(htable->hash); - ares_free(htable); - } - return NULL; - /* LCOV_EXCL_STOP */ -} - -ares_bool_t ares_htable_vpvp_insert(ares_htable_vpvp_t *htable, void *key, - void *val) -{ - ares_htable_vpvp_bucket_t *bucket = NULL; - - if (htable == NULL) { - goto fail; - } - - bucket = ares_malloc(sizeof(*bucket)); - if (bucket == NULL) { - goto fail; - } - - bucket->parent = htable; - bucket->key = key; - bucket->val = val; - - if (!ares_htable_insert(htable->hash, bucket)) { - goto fail; - } - - return ARES_TRUE; - -fail: - if (bucket) { - ares_free(bucket); - } - return ARES_FALSE; -} - -ares_bool_t ares_htable_vpvp_get(const ares_htable_vpvp_t *htable, - const void *key, void **val) -{ - ares_htable_vpvp_bucket_t *bucket = NULL; - - if (val) { - *val = NULL; - } - - if (htable == NULL) { - return ARES_FALSE; - } - - bucket = ares_htable_get(htable->hash, key); - if (bucket == NULL) { - return ARES_FALSE; - } - - if (val) { - *val = bucket->val; - } - return ARES_TRUE; -} - -void *ares_htable_vpvp_get_direct(const ares_htable_vpvp_t *htable, - const void *key) -{ - void *val = NULL; - ares_htable_vpvp_get(htable, key, &val); - return val; -} - -ares_bool_t ares_htable_vpvp_remove(ares_htable_vpvp_t *htable, const void *key) -{ - if (htable == NULL) { - return ARES_FALSE; - } - - return ares_htable_remove(htable->hash, key); -} - -size_t ares_htable_vpvp_num_keys(const ares_htable_vpvp_t *htable) -{ - if (htable == NULL) { - return 0; - } - return ares_htable_num_keys(htable->hash); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_llist.c b/vendor/c-ares/src/lib/dsa/ares_llist.c deleted file mode 100644 index 6bd7de269..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_llist.c +++ /dev/null @@ -1,382 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_llist.h" - -struct ares_llist { - ares_llist_node_t *head; - ares_llist_node_t *tail; - ares_llist_destructor_t destruct; - size_t cnt; -}; - -struct ares_llist_node { - void *data; - ares_llist_node_t *prev; - ares_llist_node_t *next; - ares_llist_t *parent; -}; - -ares_llist_t *ares_llist_create(ares_llist_destructor_t destruct) -{ - ares_llist_t *list = ares_malloc_zero(sizeof(*list)); - - if (list == NULL) { - return NULL; - } - - list->destruct = destruct; - - return list; -} - -void ares_llist_replace_destructor(ares_llist_t *list, - ares_llist_destructor_t destruct) -{ - if (list == NULL) { - return; - } - - list->destruct = destruct; -} - -typedef enum { - ARES__LLIST_INSERT_HEAD, - ARES__LLIST_INSERT_TAIL, - ARES__LLIST_INSERT_BEFORE -} ares_llist_insert_type_t; - -static void ares_llist_attach_at(ares_llist_t *list, - ares_llist_insert_type_t type, - ares_llist_node_t *at, ares_llist_node_t *node) -{ - if (list == NULL || node == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - node->parent = list; - - if (type == ARES__LLIST_INSERT_BEFORE && (at == list->head || at == NULL)) { - type = ARES__LLIST_INSERT_HEAD; - } - - switch (type) { - case ARES__LLIST_INSERT_HEAD: - node->next = list->head; - node->prev = NULL; - if (list->head) { - list->head->prev = node; - } - list->head = node; - break; - case ARES__LLIST_INSERT_TAIL: - node->next = NULL; - node->prev = list->tail; - if (list->tail) { - list->tail->next = node; - } - list->tail = node; - break; - case ARES__LLIST_INSERT_BEFORE: - node->next = at; - node->prev = at->prev; - at->prev = node; - break; - } - if (list->tail == NULL) { - list->tail = node; - } - if (list->head == NULL) { - list->head = node; - } - - list->cnt++; -} - -static ares_llist_node_t *ares_llist_insert_at(ares_llist_t *list, - ares_llist_insert_type_t type, - ares_llist_node_t *at, void *val) -{ - ares_llist_node_t *node = NULL; - - if (list == NULL || val == NULL) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - node = ares_malloc_zero(sizeof(*node)); - - if (node == NULL) { - return NULL; - } - - node->data = val; - ares_llist_attach_at(list, type, at, node); - - return node; -} - -ares_llist_node_t *ares_llist_insert_first(ares_llist_t *list, void *val) -{ - return ares_llist_insert_at(list, ARES__LLIST_INSERT_HEAD, NULL, val); -} - -ares_llist_node_t *ares_llist_insert_last(ares_llist_t *list, void *val) -{ - return ares_llist_insert_at(list, ARES__LLIST_INSERT_TAIL, NULL, val); -} - -ares_llist_node_t *ares_llist_insert_before(ares_llist_node_t *node, void *val) -{ - if (node == NULL) { - return NULL; - } - - return ares_llist_insert_at(node->parent, ARES__LLIST_INSERT_BEFORE, node, - val); -} - -ares_llist_node_t *ares_llist_insert_after(ares_llist_node_t *node, void *val) -{ - if (node == NULL) { - return NULL; - } - - if (node->next == NULL) { - return ares_llist_insert_last(node->parent, val); - } - - return ares_llist_insert_at(node->parent, ARES__LLIST_INSERT_BEFORE, - node->next, val); -} - -ares_llist_node_t *ares_llist_node_first(ares_llist_t *list) -{ - if (list == NULL) { - return NULL; - } - return list->head; -} - -ares_llist_node_t *ares_llist_node_idx(ares_llist_t *list, size_t idx) -{ - ares_llist_node_t *node; - size_t cnt; - - if (list == NULL) { - return NULL; - } - if (idx >= list->cnt) { - return NULL; - } - - node = list->head; - for (cnt = 0; node != NULL && cnt < idx; cnt++) { - node = node->next; - } - - return node; -} - -ares_llist_node_t *ares_llist_node_last(ares_llist_t *list) -{ - if (list == NULL) { - return NULL; - } - return list->tail; -} - -ares_llist_node_t *ares_llist_node_next(ares_llist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - return node->next; -} - -ares_llist_node_t *ares_llist_node_prev(ares_llist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - return node->prev; -} - -void *ares_llist_node_val(ares_llist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - - return node->data; -} - -size_t ares_llist_len(const ares_llist_t *list) -{ - if (list == NULL) { - return 0; - } - return list->cnt; -} - -ares_llist_t *ares_llist_node_parent(ares_llist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - return node->parent; -} - -void *ares_llist_first_val(ares_llist_t *list) -{ - return ares_llist_node_val(ares_llist_node_first(list)); -} - -void *ares_llist_last_val(ares_llist_t *list) -{ - return ares_llist_node_val(ares_llist_node_last(list)); -} - -static void ares_llist_node_detach(ares_llist_node_t *node) -{ - ares_llist_t *list; - - if (node == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - list = node->parent; - - if (node->prev) { - node->prev->next = node->next; - } - - if (node->next) { - node->next->prev = node->prev; - } - - if (node == list->head) { - list->head = node->next; - } - - if (node == list->tail) { - list->tail = node->prev; - } - - node->parent = NULL; - list->cnt--; -} - -void *ares_llist_node_claim(ares_llist_node_t *node) -{ - void *val; - - if (node == NULL) { - return NULL; - } - - val = node->data; - ares_llist_node_detach(node); - ares_free(node); - - return val; -} - -void ares_llist_node_destroy(ares_llist_node_t *node) -{ - ares_llist_destructor_t destruct; - void *val; - - if (node == NULL) { - return; - } - - destruct = node->parent->destruct; - - val = ares_llist_node_claim(node); - if (val != NULL && destruct != NULL) { - destruct(val); - } -} - -void ares_llist_node_replace(ares_llist_node_t *node, void *val) -{ - ares_llist_destructor_t destruct; - - if (node == NULL) { - return; - } - - destruct = node->parent->destruct; - if (destruct != NULL) { - destruct(node->data); - } - - node->data = val; -} - -void ares_llist_clear(ares_llist_t *list) -{ - ares_llist_node_t *node; - - if (list == NULL) { - return; - } - - while ((node = ares_llist_node_first(list)) != NULL) { - ares_llist_node_destroy(node); - } -} - -void ares_llist_destroy(ares_llist_t *list) -{ - if (list == NULL) { - return; - } - ares_llist_clear(list); - ares_free(list); -} - -void ares_llist_node_mvparent_last(ares_llist_node_t *node, - ares_llist_t *new_parent) -{ - if (node == NULL || new_parent == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_llist_node_detach(node); - ares_llist_attach_at(new_parent, ARES__LLIST_INSERT_TAIL, NULL, node); -} - -void ares_llist_node_mvparent_first(ares_llist_node_t *node, - ares_llist_t *new_parent) -{ - if (node == NULL || new_parent == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_llist_node_detach(node); - ares_llist_attach_at(new_parent, ARES__LLIST_INSERT_HEAD, NULL, node); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_slist.c b/vendor/c-ares/src/lib/dsa/ares_slist.c deleted file mode 100644 index 7e6834799..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_slist.c +++ /dev/null @@ -1,479 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_slist.h" - -/* SkipList implementation */ - -#define ARES__SLIST_START_LEVELS 4 - -struct ares_slist { - ares_rand_state *rand_state; - unsigned char rand_data[8]; - size_t rand_bits; - - ares_slist_node_t **head; - size_t levels; - ares_slist_node_t *tail; - - ares_slist_cmp_t cmp; - ares_slist_destructor_t destruct; - size_t cnt; -}; - -struct ares_slist_node { - void *data; - ares_slist_node_t **prev; - ares_slist_node_t **next; - size_t levels; - ares_slist_t *parent; -}; - -ares_slist_t *ares_slist_create(ares_rand_state *rand_state, - ares_slist_cmp_t cmp, - ares_slist_destructor_t destruct) -{ - ares_slist_t *list; - - if (rand_state == NULL || cmp == NULL) { - return NULL; - } - - list = ares_malloc_zero(sizeof(*list)); - - if (list == NULL) { - return NULL; - } - - list->rand_state = rand_state; - list->cmp = cmp; - list->destruct = destruct; - - list->levels = ARES__SLIST_START_LEVELS; - list->head = ares_malloc_zero(sizeof(*list->head) * list->levels); - if (list->head == NULL) { - ares_free(list); - return NULL; - } - - return list; -} - -static ares_bool_t ares_slist_coin_flip(ares_slist_t *list) -{ - size_t total_bits = sizeof(list->rand_data) * 8; - size_t bit; - - /* Refill random data used for coin flips. We pull this in 8 byte chunks. - * ares_rand_bytes() has some built-in caching of its own so we don't need - * to be excessive in caching ourselves. Prefer to require less memory per - * skiplist */ - if (list->rand_bits == 0) { - ares_rand_bytes(list->rand_state, list->rand_data, sizeof(list->rand_data)); - list->rand_bits = total_bits; - } - - bit = total_bits - list->rand_bits; - list->rand_bits--; - - return (list->rand_data[bit / 8] & (1 << (bit % 8))) ? ARES_TRUE : ARES_FALSE; -} - -void ares_slist_replace_destructor(ares_slist_t *list, - ares_slist_destructor_t destruct) -{ - if (list == NULL) { - return; - } - - list->destruct = destruct; -} - -static size_t ares_slist_max_level(const ares_slist_t *list) -{ - size_t max_level = 0; - - if (list->cnt + 1 <= (1 << ARES__SLIST_START_LEVELS)) { - max_level = ARES__SLIST_START_LEVELS; - } else { - max_level = ares_log2(ares_round_up_pow2(list->cnt + 1)); - } - - if (list->levels > max_level) { - max_level = list->levels; - } - - return max_level; -} - -static size_t ares_slist_calc_level(ares_slist_t *list) -{ - size_t max_level = ares_slist_max_level(list); - size_t level; - - for (level = 1; ares_slist_coin_flip(list) && level < max_level; level++) - ; - - return level; -} - -static void ares_slist_node_push(ares_slist_t *list, ares_slist_node_t *node) -{ - size_t i; - ares_slist_node_t *left = NULL; - - /* Scan from highest level in the slist, even if we're not using that number - * of levels for this entry as this is what makes it O(log n) */ - for (i = list->levels; i-- > 0;) { - /* set left if left is NULL and the current node value is greater than the - * head at this level */ - if (left == NULL && list->head[i] != NULL && - list->cmp(node->data, list->head[i]->data) > 0) { - left = list->head[i]; - } - - if (left != NULL) { - /* scan forward to find our insertion point */ - while (left->next[i] != NULL && - list->cmp(node->data, left->next[i]->data) > 0) { - left = left->next[i]; - } - } - - /* search only as we didn't randomly select this number of levels */ - if (i >= node->levels) { - continue; - } - - if (left == NULL) { - /* head insertion */ - node->next[i] = list->head[i]; - node->prev[i] = NULL; - list->head[i] = node; - } else { - /* Chain */ - node->next[i] = left->next[i]; - node->prev[i] = left; - left->next[i] = node; - } - - if (node->next[i] != NULL) { - /* chain prev */ - node->next[i]->prev[i] = node; - } else { - if (i == 0) { - /* update tail */ - list->tail = node; - } - } - } -} - -ares_slist_node_t *ares_slist_insert(ares_slist_t *list, void *val) -{ - ares_slist_node_t *node = NULL; - - if (list == NULL || val == NULL) { - return NULL; - } - - node = ares_malloc_zero(sizeof(*node)); - - if (node == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - node->data = val; - node->parent = list; - - /* Randomly determine the number of levels we want to use */ - node->levels = ares_slist_calc_level(list); - - /* Allocate array of next and prev nodes for linking each level */ - node->next = ares_malloc_zero(sizeof(*node->next) * node->levels); - if (node->next == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - node->prev = ares_malloc_zero(sizeof(*node->prev) * node->levels); - if (node->prev == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* If the number of levels is greater than we currently support in the slist, - * increase the count */ - if (list->levels < node->levels) { - void *ptr = - ares_realloc_zero(list->head, sizeof(*list->head) * list->levels, - sizeof(*list->head) * node->levels); - if (ptr == NULL) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - list->head = ptr; - list->levels = node->levels; - } - - ares_slist_node_push(list, node); - - list->cnt++; - - return node; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - if (node) { - ares_free(node->prev); - ares_free(node->next); - ares_free(node); - } - return NULL; - /* LCOV_EXCL_STOP */ -} - -static void ares_slist_node_pop(ares_slist_node_t *node) -{ - ares_slist_t *list = node->parent; - size_t i; - - /* relink each node at each level */ - for (i = node->levels; i-- > 0;) { - if (node->next[i] == NULL) { - if (i == 0) { - list->tail = node->prev[0]; - } - } else { - node->next[i]->prev[i] = node->prev[i]; - } - - if (node->prev[i] == NULL) { - list->head[i] = node->next[i]; - } else { - node->prev[i]->next[i] = node->next[i]; - } - } - - memset(node->next, 0, sizeof(*node->next) * node->levels); - memset(node->prev, 0, sizeof(*node->prev) * node->levels); -} - -void *ares_slist_node_claim(ares_slist_node_t *node) -{ - ares_slist_t *list; - void *val; - - if (node == NULL) { - return NULL; - } - - list = node->parent; - val = node->data; - - ares_slist_node_pop(node); - - ares_free(node->next); - ares_free(node->prev); - ares_free(node); - - list->cnt--; - - return val; -} - -void ares_slist_node_reinsert(ares_slist_node_t *node) -{ - ares_slist_t *list; - - if (node == NULL) { - return; - } - - list = node->parent; - - ares_slist_node_pop(node); - ares_slist_node_push(list, node); -} - -ares_slist_node_t *ares_slist_node_find(const ares_slist_t *list, - const void *val) -{ - size_t i; - ares_slist_node_t *node = NULL; - int rv = -1; - - if (list == NULL || val == NULL) { - return NULL; - } - - /* Scan nodes starting at the highest level. For each level scan forward - * until the value is between the prior and next node, or if equal quit - * as we found a match */ - for (i = list->levels; i-- > 0;) { - if (node == NULL) { - node = list->head[i]; - } - - if (node == NULL) { - continue; - } - - do { - rv = list->cmp(val, node->data); - - if (rv < 0) { - /* back off, our value is greater than current node reference */ - node = node->prev[i]; - } else if (rv > 0) { - /* move forward and try again. if it goes past, it will loop again and - * go to previous entry */ - node = node->next[i]; - } - - /* rv == 0 will terminate loop */ - - } while (node != NULL && rv > 0); - - /* Found a match, no need to continue */ - if (rv == 0) { - break; - } - } - - /* no match */ - if (rv != 0) { - return NULL; - } - - /* The list may have multiple entries that match. They're guaranteed to be - * in order, but we're not guaranteed to have selected the _first_ matching - * node. Lets scan backwards to find the first match */ - while (node->prev[0] != NULL && list->cmp(node->prev[0]->data, val) == 0) { - node = node->prev[0]; - } - - return node; -} - -ares_slist_node_t *ares_slist_node_first(const ares_slist_t *list) -{ - if (list == NULL) { - return NULL; - } - - return list->head[0]; -} - -ares_slist_node_t *ares_slist_node_last(const ares_slist_t *list) -{ - if (list == NULL) { - return NULL; - } - return list->tail; -} - -ares_slist_node_t *ares_slist_node_next(const ares_slist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - return node->next[0]; -} - -ares_slist_node_t *ares_slist_node_prev(const ares_slist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - return node->prev[0]; -} - -void *ares_slist_node_val(ares_slist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - - return node->data; -} - -size_t ares_slist_len(const ares_slist_t *list) -{ - if (list == NULL) { - return 0; - } - return list->cnt; -} - -ares_slist_t *ares_slist_node_parent(ares_slist_node_t *node) -{ - if (node == NULL) { - return NULL; - } - return node->parent; -} - -void *ares_slist_first_val(const ares_slist_t *list) -{ - return ares_slist_node_val(ares_slist_node_first(list)); -} - -void *ares_slist_last_val(const ares_slist_t *list) -{ - return ares_slist_node_val(ares_slist_node_last(list)); -} - -void ares_slist_node_destroy(ares_slist_node_t *node) -{ - ares_slist_destructor_t destruct; - void *val; - - if (node == NULL) { - return; - } - - destruct = node->parent->destruct; - val = ares_slist_node_claim(node); - - if (val != NULL && destruct != NULL) { - destruct(val); - } -} - -void ares_slist_destroy(ares_slist_t *list) -{ - ares_slist_node_t *node; - - if (list == NULL) { - return; - } - - while ((node = ares_slist_node_first(list)) != NULL) { - ares_slist_node_destroy(node); - } - - ares_free(list->head); - ares_free(list); -} diff --git a/vendor/c-ares/src/lib/dsa/ares_slist.h b/vendor/c-ares/src/lib/dsa/ares_slist.h deleted file mode 100644 index a89c2652f..000000000 --- a/vendor/c-ares/src/lib/dsa/ares_slist.h +++ /dev/null @@ -1,207 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__SLIST_H -#define __ARES__SLIST_H - - -/*! \addtogroup ares_slist SkipList Data Structure - * - * This data structure is known as a Skip List, which in essence is a sorted - * linked list with multiple levels of linkage to gain some algorithmic - * advantages. The usage symantecs are almost identical to what you'd expect - * with a linked list. - * - * Average time complexity: - * - Insert: O(log n) - * - Search: O(log n) - * - Delete: O(1) -- delete assumes you hold a node pointer - * - * It should be noted, however, that "effort" involved with an insert or - * remove operation is higher than a normal linked list. For very small - * lists this may be less efficient, but for any list with a moderate number - * of entries this will prove much more efficient. - * - * This data structure is often compared with a Binary Search Tree in - * functionality and usage. - * - * @{ - */ -struct ares_slist; - -/*! SkipList Object, opaque */ -typedef struct ares_slist ares_slist_t; - -struct ares_slist_node; - -/*! SkipList Node Object, opaque */ -typedef struct ares_slist_node ares_slist_node_t; - -/*! SkipList Node Value destructor callback - * - * \param[in] data User-defined data to destroy - */ -typedef void (*ares_slist_destructor_t)(void *data); - -/*! SkipList comparison function - * - * \param[in] data1 First user-defined data object - * \param[in] data2 Second user-defined data object - * \return < 0 if data1 < data1, > 0 if data1 > data2, 0 if data1 == data2 - */ -typedef int (*ares_slist_cmp_t)(const void *data1, const void *data2); - -/*! Create SkipList - * - * \param[in] rand_state Initialized ares random state. - * \param[in] cmp SkipList comparison function - * \param[in] destruct SkipList Node Value Destructor. Optional, use NULL. - * \return Initialized SkipList Object or NULL on misuse or ENOMEM - */ -ares_slist_t *ares_slist_create(ares_rand_state *rand_state, - ares_slist_cmp_t cmp, - ares_slist_destructor_t destruct); - -/*! Replace SkipList Node Value Destructor - * - * \param[in] list Initialized SkipList Object - * \param[in] destruct Replacement destructor. May be NULL. - */ -void ares_slist_replace_destructor(ares_slist_t *list, - ares_slist_destructor_t destruct); - -/*! Insert Value into SkipList - * - * \param[in] list Initialized SkipList Object - * \param[in] val Node Value. Must not be NULL. Function takes ownership - * and will have destructor called. - * \return SkipList Node Object or NULL on misuse or ENOMEM - */ -ares_slist_node_t *ares_slist_insert(ares_slist_t *list, void *val); - -/*! Fetch first node in SkipList - * - * \param[in] list Initialized SkipList Object - * \return SkipList Node Object or NULL if none - */ -ares_slist_node_t *ares_slist_node_first(const ares_slist_t *list); - -/*! Fetch last node in SkipList - * - * \param[in] list Initialized SkipList Object - * \return SkipList Node Object or NULL if none - */ -ares_slist_node_t *ares_slist_node_last(const ares_slist_t *list); - -/*! Fetch next node in SkipList - * - * \param[in] node SkipList Node Object - * \return SkipList Node Object or NULL if none - */ -ares_slist_node_t *ares_slist_node_next(const ares_slist_node_t *node); - -/*! Fetch previous node in SkipList - * - * \param[in] node SkipList Node Object - * \return SkipList Node Object or NULL if none - */ -ares_slist_node_t *ares_slist_node_prev(const ares_slist_node_t *node); - -/*! Fetch SkipList Node Object by Value - * - * \param[in] list Initialized SkipList Object - * \param[in] val Object to use for comparison - * \return SkipList Node Object or NULL if not found - */ -ares_slist_node_t *ares_slist_node_find(const ares_slist_t *list, - const void *val); - - -/*! Fetch Node Value - * - * \param[in] node SkipList Node Object - * \return user defined node value - */ -void *ares_slist_node_val(ares_slist_node_t *node); - -/*! Fetch number of entries in SkipList Object - * - * \param[in] list Initialized SkipList Object - * \return number of entries - */ -size_t ares_slist_len(const ares_slist_t *list); - -/*! Fetch SkipList Object from SkipList Node - * - * \param[in] node SkipList Node Object - * \return SkipList Object - */ -ares_slist_t *ares_slist_node_parent(ares_slist_node_t *node); - -/*! Fetch first Node Value in SkipList - * - * \param[in] list Initialized SkipList Object - * \return user defined node value or NULL if none - */ -void *ares_slist_first_val(const ares_slist_t *list); - -/*! Fetch last Node Value in SkipList - * - * \param[in] list Initialized SkipList Object - * \return user defined node value or NULL if none - */ -void *ares_slist_last_val(const ares_slist_t *list); - -/*! Take back ownership of Node Value in SkipList, remove from SkipList. - * - * \param[in] node SkipList Node Object - * \return user defined node value - */ -void *ares_slist_node_claim(ares_slist_node_t *node); - -/*! The internals of the node have changed, thus its position in the sorted - * list is no longer valid. This function will remove it and re-add it to - * the proper position without needing to perform any memory allocations - * and thus cannot fail. - * - * \param[in] node SkipList Node Object - */ -void ares_slist_node_reinsert(ares_slist_node_t *node); - -/*! Remove Node from SkipList, calling destructor for Node Value. - * - * \param[in] node SkipList Node Object - */ -void ares_slist_node_destroy(ares_slist_node_t *node); - -/*! Destroy SkipList Object. If there are any nodes, they will be destroyed. - * - * \param[in] list Initialized SkipList Object - */ -void ares_slist_destroy(ares_slist_t *list); - -/*! @} */ - -#endif /* __ARES__SLIST_H */ diff --git a/vendor/c-ares/src/lib/event/ares_event.h b/vendor/c-ares/src/lib/event/ares_event.h deleted file mode 100644 index bf298dfb6..000000000 --- a/vendor/c-ares/src/lib/event/ares_event.h +++ /dev/null @@ -1,191 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__EVENT_H -#define __ARES__EVENT_H - -struct ares_event; -typedef struct ares_event ares_event_t; - -typedef enum { - ARES_EVENT_FLAG_NONE = 0, - ARES_EVENT_FLAG_READ = 1 << 0, - ARES_EVENT_FLAG_WRITE = 1 << 1, - ARES_EVENT_FLAG_OTHER = 1 << 2 -} ares_event_flags_t; - -typedef void (*ares_event_cb_t)(ares_event_thread_t *e, ares_socket_t fd, - void *data, ares_event_flags_t flags); - -typedef void (*ares_event_free_data_t)(void *data); - -typedef void (*ares_event_signal_cb_t)(const ares_event_t *event); - -struct ares_event { - /*! Registered event thread this event is bound to */ - ares_event_thread_t *e; - /*! Flags to monitor. OTHER is only allowed if the socket is ARES_SOCKET_BAD. - */ - ares_event_flags_t flags; - /*! Callback to be called when event is triggered */ - ares_event_cb_t cb; - /*! Socket to monitor, allowed to be ARES_SOCKET_BAD if not monitoring a - * socket. */ - ares_socket_t fd; - /*! Data associated with event handle that will be passed to the callback. - * Typically OS/event subsystem specific data. - * Optional, may be NULL. */ - /*! Data to be passed to callback. Optional, may be NULL. */ - void *data; - /*! When cleaning up the registered event (either when removed or during - * shutdown), this function will be called to clean up the user-supplied - * data. Optional, May be NULL. */ - ares_event_free_data_t free_data_cb; - /*! Callback to call to trigger an event. */ - ares_event_signal_cb_t signal_cb; -}; - -typedef struct { - const char *name; - ares_bool_t (*init)(ares_event_thread_t *e); - void (*destroy)(ares_event_thread_t *e); - ares_bool_t (*event_add)(ares_event_t *event); - void (*event_del)(ares_event_t *event); - void (*event_mod)(ares_event_t *event, ares_event_flags_t new_flags); - size_t (*wait)(ares_event_thread_t *e, unsigned long timeout_ms); -} ares_event_sys_t; - -struct ares_event_configchg; -typedef struct ares_event_configchg ares_event_configchg_t; - -ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, - ares_event_thread_t *e); - -void ares_event_configchg_destroy(ares_event_configchg_t *configchg); - -struct ares_event_thread { - /*! Whether the event thread should be online or not. Checked on every wake - * event before sleeping. */ - ares_bool_t isup; - /*! Handle to the thread for joining during shutdown */ - ares_thread_t *thread; - /*! Lock to protect the data contained within the event thread itself */ - ares_thread_mutex_t *mutex; - /*! Reference to the ares channel, for being able to call things like - * ares_timeout() and ares_process_fd(). */ - ares_channel_t *channel; - /*! Whether or not on the next loop we should process a pending write */ - ares_bool_t process_pending_write; - /*! Not-yet-processed event handle updates. These will get enqueued by a - * thread other than the event thread itself. The event thread will then - * be woken then process these updates itself */ - ares_llist_t *ev_updates; - /*! Registered socket event handles */ - ares_htable_asvp_t *ev_sock_handles; - /*! Registered custom event handles. Typically used for external triggering. - */ - ares_htable_vpvp_t *ev_cust_handles; - /*! Pointer to the event handle which is used to signal and wake the event - * thread itself. This is needed to be able to do things like update the - * file descriptors being waited on and to wake the event subsystem during - * shutdown */ - ares_event_t *ev_signal; - /*! Handle for configuration change monitoring */ - ares_event_configchg_t *configchg; - /* Event subsystem callbacks */ - const ares_event_sys_t *ev_sys; - /* Event subsystem private data */ - void *ev_sys_data; -}; - -/*! Queue an update for the event handle. - * - * Will search by the fd passed if not ARES_SOCKET_BAD to find a match and - * perform an update or delete (depending on flags). Otherwise will add. - * Do not use the event handle returned if its not guaranteed to be an add - * operation. - * - * \param[out] event Event handle. Optional, can be NULL. This handle - * will be invalidate quickly if the result of the - * operation is not an ADD. - * \param[in] e pointer to event thread handle - * \param[in] flags flags for the event handle. Use - * ARES_EVENT_FLAG_NONE if removing a socket from - * queue (not valid if socket is ARES_SOCKET_BAD). - * Non-socket events cannot be removed, and must have - * ARES_EVENT_FLAG_OTHER set. - * \param[in] cb Callback to call when - * event is triggered. Required if flags is not - * ARES_EVENT_FLAG_NONE. Not allowed to be - * changed, ignored on modification. - * \param[in] fd File descriptor/socket to monitor. May - * be ARES_SOCKET_BAD if not monitoring file - * descriptor. - * \param[in] data Optional. Caller-supplied data to be passed to - * callback. Only allowed on initial add, cannot be - * modified later, ignored on modification. - * \param[in] free_data_cb Optional. Callback to clean up caller-supplied - * data. Only allowed on initial add, cannot be - * modified later, ignored on modification. - * \param[in] signal_cb Optional. Callback to call to trigger an event. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_event_update(ares_event_t **event, ares_event_thread_t *e, - ares_event_flags_t flags, ares_event_cb_t cb, - ares_socket_t fd, void *data, - ares_event_free_data_t free_data_cb, - ares_event_signal_cb_t signal_cb); - - -#ifdef CARES_THREADS -# ifdef HAVE_PIPE -ares_event_t *ares_pipeevent_create(ares_event_thread_t *e); -# endif - -# ifdef HAVE_POLL -extern const ares_event_sys_t ares_evsys_poll; -# endif - -# ifdef HAVE_KQUEUE -extern const ares_event_sys_t ares_evsys_kqueue; -# endif - -# ifdef HAVE_EPOLL -extern const ares_event_sys_t ares_evsys_epoll; -# endif - -# ifdef _WIN32 -extern const ares_event_sys_t ares_evsys_win32; -# endif - -/* All systems have select(), but not all have a way to wake, so we require - * pipe() to wake the select() */ -# ifdef HAVE_PIPE -extern const ares_event_sys_t ares_evsys_select; -# endif - -#endif - -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_configchg.c b/vendor/c-ares/src/lib/event/ares_event_configchg.c deleted file mode 100644 index 2a8c780c2..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_configchg.c +++ /dev/null @@ -1,743 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_event.h" - -#if defined(__ANDROID__) && defined(CARES_THREADS) - -ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, - ares_event_thread_t *e) -{ - (void)configchg; - (void)e; - /* No ability */ - return ARES_ENOTIMP; -} - -void ares_event_configchg_destroy(ares_event_configchg_t *configchg) -{ - /* No-op */ - (void)configchg; -} - -#elif defined(__linux__) && defined(CARES_THREADS) - -# include - -struct ares_event_configchg { - int inotify_fd; - ares_event_thread_t *e; -}; - -void ares_event_configchg_destroy(ares_event_configchg_t *configchg) -{ - if (configchg == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Tell event system to stop monitoring for changes. This will cause the - * cleanup to be called */ - ares_event_update(NULL, configchg->e, ARES_EVENT_FLAG_NONE, NULL, - configchg->inotify_fd, NULL, NULL, NULL); -} - -static void ares_event_configchg_free(void *data) -{ - ares_event_configchg_t *configchg = data; - if (configchg == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (configchg->inotify_fd >= 0) { - close(configchg->inotify_fd); - configchg->inotify_fd = -1; - } - - ares_free(configchg); -} - -static void ares_event_configchg_cb(ares_event_thread_t *e, ares_socket_t fd, - void *data, ares_event_flags_t flags) -{ - const ares_event_configchg_t *configchg = data; - - /* Some systems cannot read integer variables if they are not - * properly aligned. On other systems, incorrect alignment may - * decrease performance. Hence, the buffer used for reading from - * the inotify file descriptor should have the same alignment as - * struct inotify_event. */ - unsigned char buf[4096] - __attribute__((aligned(__alignof__(struct inotify_event)))); - const struct inotify_event *event; - ssize_t len; - ares_bool_t triggered = ARES_FALSE; - - (void)fd; - (void)flags; - - while (1) { - const unsigned char *ptr; - - len = read(configchg->inotify_fd, buf, sizeof(buf)); - if (len <= 0) { - break; - } - - /* Loop over all events in the buffer. Says kernel will check the buffer - * size provided, so I assume it won't ever return partial events. */ - for (ptr = buf; ptr < buf + len; - ptr += sizeof(struct inotify_event) + event->len) { - event = (const struct inotify_event *)((const void *)ptr); - - if (event->len == 0 || ares_strlen(event->name) == 0) { - continue; - } - - if (ares_strcaseeq(event->name, "resolv.conf") || - ares_strcaseeq(event->name, "nsswitch.conf")) { - triggered = ARES_TRUE; - } - } - } - - /* Only process after all events are read. No need to process more often as - * we don't want to reload the config back to back */ - if (triggered) { - ares_reinit(e->channel); - } -} - -ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, - ares_event_thread_t *e) -{ - ares_status_t status = ARES_SUCCESS; - ares_event_configchg_t *c; - - (void)e; - - /* Not used by this implementation */ - *configchg = NULL; - - c = ares_malloc_zero(sizeof(*c)); - if (c == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - c->e = e; - c->inotify_fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); - if (c->inotify_fd == -1) { - status = ARES_ESERVFAIL; /* LCOV_EXCL_LINE: UntestablePath */ - goto done; /* LCOV_EXCL_LINE: UntestablePath */ - } - - /* We need to monitor /etc/resolv.conf, /etc/nsswitch.conf */ - if (inotify_add_watch(c->inotify_fd, "/etc", - IN_CREATE | IN_MODIFY | IN_MOVED_TO | IN_ONLYDIR) == - -1) { - status = ARES_ESERVFAIL; /* LCOV_EXCL_LINE: UntestablePath */ - goto done; /* LCOV_EXCL_LINE: UntestablePath */ - } - - status = - ares_event_update(NULL, e, ARES_EVENT_FLAG_READ, ares_event_configchg_cb, - c->inotify_fd, c, ares_event_configchg_free, NULL); - -done: - if (status != ARES_SUCCESS) { - ares_event_configchg_free(c); - } else { - *configchg = c; - } - return status; -} - -#elif defined(USE_WINSOCK) && defined(CARES_THREADS) - -# include -# include -# include -# include - -struct ares_event_configchg { - HANDLE ifchg_hnd; - HKEY regip4; - HANDLE regip4_event; - HANDLE regip4_wait; - HKEY regip6; - HANDLE regip6_event; - HANDLE regip6_wait; - ares_event_thread_t *e; -}; - -void ares_event_configchg_destroy(ares_event_configchg_t *configchg) -{ - if (configchg == NULL) { - return; - } - -# ifdef HAVE_NOTIFYIPINTERFACECHANGE - if (configchg->ifchg_hnd != NULL) { - CancelMibChangeNotify2(configchg->ifchg_hnd); - configchg->ifchg_hnd = NULL; - } -# endif - -# ifdef HAVE_REGISTERWAITFORSINGLEOBJECT - if (configchg->regip4_wait != NULL) { - UnregisterWait(configchg->regip4_wait); - configchg->regip4_wait = NULL; - } - - if (configchg->regip6_wait != NULL) { - UnregisterWait(configchg->regip6_wait); - configchg->regip6_wait = NULL; - } - - if (configchg->regip4 != NULL) { - RegCloseKey(configchg->regip4); - configchg->regip4 = NULL; - } - - if (configchg->regip6 != NULL) { - RegCloseKey(configchg->regip6); - configchg->regip6 = NULL; - } - - if (configchg->regip4_event != NULL) { - CloseHandle(configchg->regip4_event); - configchg->regip4_event = NULL; - } - - if (configchg->regip6_event != NULL) { - CloseHandle(configchg->regip6_event); - configchg->regip6_event = NULL; - } -# endif - - ares_free(configchg); -} - - -# ifdef HAVE_NOTIFYIPINTERFACECHANGE -static void NETIOAPI_API_ - ares_event_configchg_ip_cb(PVOID CallerContext, PMIB_IPINTERFACE_ROW Row, - MIB_NOTIFICATION_TYPE NotificationType) -{ - ares_event_configchg_t *configchg = CallerContext; - (void)Row; - (void)NotificationType; - ares_reinit(configchg->e->channel); -} -# endif - -static ares_bool_t - ares_event_configchg_regnotify(ares_event_configchg_t *configchg) -{ -# ifdef HAVE_REGISTERWAITFORSINGLEOBJECT -# if defined(__WATCOMC__) && !defined(REG_NOTIFY_THREAD_AGNOSTIC) -# define REG_NOTIFY_THREAD_AGNOSTIC 0x10000000L -# endif - DWORD flags = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET | - REG_NOTIFY_THREAD_AGNOSTIC; - - if (RegNotifyChangeKeyValue(configchg->regip4, TRUE, flags, - configchg->regip4_event, TRUE) != ERROR_SUCCESS) { - return ARES_FALSE; - } - - if (RegNotifyChangeKeyValue(configchg->regip6, TRUE, flags, - configchg->regip6_event, TRUE) != ERROR_SUCCESS) { - return ARES_FALSE; - } -# else - (void)configchg; -# endif - return ARES_TRUE; -} - -static VOID CALLBACK ares_event_configchg_reg_cb(PVOID lpParameter, - BOOLEAN TimerOrWaitFired) -{ - ares_event_configchg_t *configchg = lpParameter; - (void)TimerOrWaitFired; - - ares_reinit(configchg->e->channel); - - /* Re-arm, as its single-shot. However, we don't know which one needs to - * be re-armed, so we just do both */ - ares_event_configchg_regnotify(configchg); -} - -ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, - ares_event_thread_t *e) -{ - ares_status_t status = ARES_SUCCESS; - ares_event_configchg_t *c = NULL; - - c = ares_malloc_zero(sizeof(**configchg)); - if (c == NULL) { - return ARES_ENOMEM; - } - - c->e = e; - -# ifdef HAVE_NOTIFYIPINTERFACECHANGE - /* NOTE: If a user goes into the control panel and changes the network - * adapter DNS addresses manually, this will NOT trigger a notification. - * We've also tried listening on NotifyUnicastIpAddressChange(), but - * that didn't get triggered either. - */ - if (NotifyIpInterfaceChange(AF_UNSPEC, ares_event_configchg_ip_cb, c, FALSE, - &c->ifchg_hnd) != NO_ERROR) { - status = ARES_ESERVFAIL; - goto done; - } -# endif - -# ifdef HAVE_REGISTERWAITFORSINGLEOBJECT - /* Monitor HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces - * and HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces - * for changes via RegNotifyChangeKeyValue() */ - if (RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", - 0, KEY_NOTIFY, &c->regip4) != ERROR_SUCCESS) { - status = ARES_ESERVFAIL; - goto done; - } - - if (RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\Interfaces", - 0, KEY_NOTIFY, &c->regip6) != ERROR_SUCCESS) { - status = ARES_ESERVFAIL; - goto done; - } - - c->regip4_event = CreateEvent(NULL, TRUE, FALSE, NULL); - if (c->regip4_event == NULL) { - status = ARES_ESERVFAIL; - goto done; - } - - c->regip6_event = CreateEvent(NULL, TRUE, FALSE, NULL); - if (c->regip6_event == NULL) { - status = ARES_ESERVFAIL; - goto done; - } - - if (!RegisterWaitForSingleObject(&c->regip4_wait, c->regip4_event, - ares_event_configchg_reg_cb, c, INFINITE, - WT_EXECUTEDEFAULT)) { - status = ARES_ESERVFAIL; - goto done; - } - - if (!RegisterWaitForSingleObject(&c->regip6_wait, c->regip6_event, - ares_event_configchg_reg_cb, c, INFINITE, - WT_EXECUTEDEFAULT)) { - status = ARES_ESERVFAIL; - goto done; - } -# endif - - if (!ares_event_configchg_regnotify(c)) { - status = ARES_ESERVFAIL; - goto done; - } - -done: - if (status != ARES_SUCCESS) { - ares_event_configchg_destroy(c); - } else { - *configchg = c; - } - - return status; -} - -#elif defined(__APPLE__) && defined(CARES_THREADS) - -# include -# include -# include -# include -# include - -struct ares_event_configchg { - int fd; - int token; -}; - -void ares_event_configchg_destroy(ares_event_configchg_t *configchg) -{ - (void)configchg; - - /* Cleanup happens automatically */ -} - -static void ares_event_configchg_free(void *data) -{ - ares_event_configchg_t *configchg = data; - if (configchg == NULL) { - return; - } - - if (configchg->fd >= 0) { - notify_cancel(configchg->token); - /* automatically closes fd */ - configchg->fd = -1; - } - - ares_free(configchg); -} - -static void ares_event_configchg_cb(ares_event_thread_t *e, ares_socket_t fd, - void *data, ares_event_flags_t flags) -{ - ares_event_configchg_t *configchg = data; - ares_bool_t triggered = ARES_FALSE; - - (void)fd; - (void)flags; - - while (1) { - int t = 0; - ssize_t len; - - len = read(configchg->fd, &t, sizeof(t)); - - if (len < (ssize_t)sizeof(t)) { - break; - } - - /* Token is read in network byte order (yeah, docs don't mention this) */ - t = (int)ntohl(t); - - if (t != configchg->token) { - continue; - } - - triggered = ARES_TRUE; - } - - /* Only process after all events are read. No need to process more often as - * we don't want to reload the config back to back */ - if (triggered) { - ares_reinit(e->channel); - } -} - -ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, - ares_event_thread_t *e) -{ - ares_status_t status = ARES_SUCCESS; - void *handle = NULL; - const char *(*pdns_configuration_notify_key)(void) = NULL; - const char *notify_key = NULL; - int flags; - size_t i; - const char *searchlibs[] = { - "/usr/lib/libSystem.dylib", - "/System/Library/Frameworks/SystemConfiguration.framework/" - "SystemConfiguration", - NULL - }; - - *configchg = ares_malloc_zero(sizeof(**configchg)); - if (*configchg == NULL) { - return ARES_ENOMEM; - } - - /* Load symbol as it isn't normally public */ - for (i = 0; searchlibs[i] != NULL; i++) { - handle = dlopen(searchlibs[i], RTLD_LAZY); - if (handle == NULL) { - /* Fail, loop! */ - continue; - } - - pdns_configuration_notify_key = - (const char *(*)(void))dlsym(handle, "dns_configuration_notify_key"); - if (pdns_configuration_notify_key != NULL) { - break; - } - - /* Fail, loop! */ - dlclose(handle); - handle = NULL; - } - - if (pdns_configuration_notify_key == NULL) { - status = ARES_ESERVFAIL; - goto done; - } - - notify_key = pdns_configuration_notify_key(); - if (notify_key == NULL) { - status = ARES_ESERVFAIL; - goto done; - } - - if (notify_register_file_descriptor(notify_key, &(*configchg)->fd, 0, - &(*configchg)->token) != - NOTIFY_STATUS_OK) { - status = ARES_ESERVFAIL; - goto done; - } - - /* Set file descriptor to non-blocking */ - flags = fcntl((*configchg)->fd, F_GETFL, 0); - fcntl((*configchg)->fd, F_SETFL, flags | O_NONBLOCK); - - /* Register file descriptor with event subsystem */ - status = ares_event_update(NULL, e, ARES_EVENT_FLAG_READ, - ares_event_configchg_cb, (*configchg)->fd, - *configchg, ares_event_configchg_free, NULL); - -done: - if (status != ARES_SUCCESS) { - ares_event_configchg_free(*configchg); - *configchg = NULL; - } - - if (handle) { - dlclose(handle); - } - - return status; -} - -#elif defined(HAVE_STAT) && !defined(_WIN32) && defined(CARES_THREADS) -# ifdef HAVE_SYS_TYPES_H -# include -# endif -# ifdef HAVE_SYS_STAT_H -# include -# endif - -typedef struct { - size_t size; - time_t mtime; -} fileinfo_t; - -struct ares_event_configchg { - ares_bool_t isup; - ares_thread_t *thread; - ares_htable_strvp_t *filestat; - ares_thread_mutex_t *lock; - ares_thread_cond_t *wake; - const char *resolvconf_path; - ares_event_thread_t *e; -}; - -static ares_status_t config_change_check(ares_htable_strvp_t *filestat, - const char *resolvconf_path) -{ - size_t i; - const char *configfiles[16]; - ares_bool_t changed = ARES_FALSE; - size_t cnt = 0; - - memset(configfiles, 0, sizeof(configfiles)); - - configfiles[cnt++] = resolvconf_path; - configfiles[cnt++] = "/etc/nsswitch.conf"; -#ifdef _AIX - configfiles[cnt++] = "/etc/netsvc.conf"; -#endif -#ifdef __osf /* Tru64 */ - configfiles[cnt++] = "/etc/svc.conf"; -#endif -#ifdef __QNX__ - configfiles[cnt++] = "/etc/net.cfg"; -#endif - configfiles[cnt++] = NULL; - - for (i = 0; configfiles[i] != NULL; i++) { - fileinfo_t *fi = ares_htable_strvp_get_direct(filestat, configfiles[i]); - struct stat st; - - if (stat(configfiles[i], &st) == 0) { - if (fi == NULL) { - fi = ares_malloc_zero(sizeof(*fi)); - if (fi == NULL) { - return ARES_ENOMEM; - } - if (!ares_htable_strvp_insert(filestat, configfiles[i], fi)) { - ares_free(fi); - return ARES_ENOMEM; - } - } - if (fi->size != (size_t)st.st_size || fi->mtime != (time_t)st.st_mtime) { - changed = ARES_TRUE; - } - fi->size = (size_t)st.st_size; - fi->mtime = (time_t)st.st_mtime; - } else if (fi != NULL) { - /* File no longer exists, remove */ - ares_htable_strvp_remove(filestat, configfiles[i]); - changed = ARES_TRUE; - } - } - - if (changed) { - return ARES_SUCCESS; - } - return ARES_ENOTFOUND; -} - -static void *ares_event_configchg_thread(void *arg) -{ - ares_event_configchg_t *c = arg; - - ares_thread_mutex_lock(c->lock); - while (c->isup) { - ares_status_t status; - - if (ares_thread_cond_timedwait(c->wake, c->lock, 30000) != ARES_ETIMEOUT) { - continue; - } - - /* make sure status didn't change even though we got a timeout */ - if (!c->isup) { - break; - } - - status = config_change_check(c->filestat, c->resolvconf_path); - if (status == ARES_SUCCESS) { - ares_reinit(c->e->channel); - } - } - - ares_thread_mutex_unlock(c->lock); - return NULL; -} - -ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, - ares_event_thread_t *e) -{ - ares_status_t status = ARES_SUCCESS; - ares_event_configchg_t *c = NULL; - - *configchg = NULL; - - c = ares_malloc_zero(sizeof(*c)); - if (c == NULL) { - status = ARES_ENOMEM; - goto done; - } - - c->e = e; - - c->filestat = ares_htable_strvp_create(ares_free); - if (c->filestat == NULL) { - status = ARES_ENOMEM; - goto done; - } - - c->wake = ares_thread_cond_create(); - if (c->wake == NULL) { - status = ARES_ENOMEM; - goto done; - } - - c->lock = ares_thread_mutex_create(); - if (c->lock == NULL) { - status = ARES_ENOMEM; - goto done; - } - - c->resolvconf_path = c->e->channel->resolvconf_path; - if (c->resolvconf_path == NULL) { - c->resolvconf_path = PATH_RESOLV_CONF; - } - - status = config_change_check(c->filestat, c->resolvconf_path); - if (status == ARES_ENOMEM) { - goto done; - } - - c->isup = ARES_TRUE; - status = ares_thread_create(&c->thread, ares_event_configchg_thread, c); - -done: - if (status != ARES_SUCCESS) { - ares_event_configchg_destroy(c); - } else { - *configchg = c; - } - return status; -} - -void ares_event_configchg_destroy(ares_event_configchg_t *configchg) -{ - if (configchg == NULL) { - return; - } - - if (configchg->lock) { - ares_thread_mutex_lock(configchg->lock); - } - - configchg->isup = ARES_FALSE; - if (configchg->wake) { - ares_thread_cond_signal(configchg->wake); - } - - if (configchg->lock) { - ares_thread_mutex_unlock(configchg->lock); - } - - if (configchg->thread) { - void *rv = NULL; - ares_thread_join(configchg->thread, &rv); - } - - ares_thread_mutex_destroy(configchg->lock); - ares_thread_cond_destroy(configchg->wake); - ares_htable_strvp_destroy(configchg->filestat); - ares_free(configchg); -} - -#else - -ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, - ares_event_thread_t *e) -{ - (void)configchg; - (void)e; - /* No ability */ - return ARES_ENOTIMP; -} - -void ares_event_configchg_destroy(ares_event_configchg_t *configchg) -{ - /* No-op */ - (void)configchg; -} - -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_epoll.c b/vendor/c-ares/src/lib/event/ares_event_epoll.c deleted file mode 100644 index d451c86a3..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_epoll.c +++ /dev/null @@ -1,192 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_event.h" - -#if defined(HAVE_EPOLL) && defined(CARES_THREADS) - -#ifdef HAVE_SYS_EPOLL_H -# include -#endif -#ifdef HAVE_FCNTL_H -# include -#endif - -typedef struct { - int epoll_fd; -} ares_evsys_epoll_t; - -static void ares_evsys_epoll_destroy(ares_event_thread_t *e) -{ - ares_evsys_epoll_t *ep = NULL; - - if (e == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ep = e->ev_sys_data; - if (ep == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ep->epoll_fd != -1) { - close(ep->epoll_fd); - } - - ares_free(ep); - e->ev_sys_data = NULL; -} - -static ares_bool_t ares_evsys_epoll_init(ares_event_thread_t *e) -{ - ares_evsys_epoll_t *ep = NULL; - - ep = ares_malloc_zero(sizeof(*ep)); - if (ep == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - e->ev_sys_data = ep; - - ep->epoll_fd = epoll_create1(EPOLL_CLOEXEC); - if (ep->epoll_fd == -1) { - ares_evsys_epoll_destroy(e); /* LCOV_EXCL_LINE: UntestablePath */ - return ARES_FALSE; /* LCOV_EXCL_LINE: UntestablePath */ - } - - e->ev_signal = ares_pipeevent_create(e); - if (e->ev_signal == NULL) { - ares_evsys_epoll_destroy(e); /* LCOV_EXCL_LINE: UntestablePath */ - return ARES_FALSE; /* LCOV_EXCL_LINE: UntestablePath */ - } - - return ARES_TRUE; -} - -static ares_bool_t ares_evsys_epoll_event_add(ares_event_t *event) -{ - const ares_event_thread_t *e = event->e; - const ares_evsys_epoll_t *ep = e->ev_sys_data; - struct epoll_event epev; - - memset(&epev, 0, sizeof(epev)); - epev.data.fd = event->fd; - epev.events = EPOLLRDHUP | EPOLLERR | EPOLLHUP; - if (event->flags & ARES_EVENT_FLAG_READ) { - epev.events |= EPOLLIN; - } - if (event->flags & ARES_EVENT_FLAG_WRITE) { - epev.events |= EPOLLOUT; - } - if (epoll_ctl(ep->epoll_fd, EPOLL_CTL_ADD, event->fd, &epev) != 0) { - return ARES_FALSE; /* LCOV_EXCL_LINE: UntestablePath */ - } - return ARES_TRUE; -} - -static void ares_evsys_epoll_event_del(ares_event_t *event) -{ - const ares_event_thread_t *e = event->e; - const ares_evsys_epoll_t *ep = e->ev_sys_data; - struct epoll_event epev; - - memset(&epev, 0, sizeof(epev)); - epev.data.fd = event->fd; - epoll_ctl(ep->epoll_fd, EPOLL_CTL_DEL, event->fd, &epev); -} - -static void ares_evsys_epoll_event_mod(ares_event_t *event, - ares_event_flags_t new_flags) -{ - const ares_event_thread_t *e = event->e; - const ares_evsys_epoll_t *ep = e->ev_sys_data; - struct epoll_event epev; - - memset(&epev, 0, sizeof(epev)); - epev.data.fd = event->fd; - epev.events = EPOLLRDHUP | EPOLLERR | EPOLLHUP; - if (new_flags & ARES_EVENT_FLAG_READ) { - epev.events |= EPOLLIN; - } - if (new_flags & ARES_EVENT_FLAG_WRITE) { - epev.events |= EPOLLOUT; - } - epoll_ctl(ep->epoll_fd, EPOLL_CTL_MOD, event->fd, &epev); -} - -static size_t ares_evsys_epoll_wait(ares_event_thread_t *e, - unsigned long timeout_ms) -{ - struct epoll_event events[8]; - size_t nevents = sizeof(events) / sizeof(*events); - const ares_evsys_epoll_t *ep = e->ev_sys_data; - int rv; - size_t i; - size_t cnt = 0; - - memset(events, 0, sizeof(events)); - - rv = epoll_wait(ep->epoll_fd, events, (int)nevents, - (timeout_ms == 0) ? -1 : (int)timeout_ms); - if (rv < 0) { - return 0; /* LCOV_EXCL_LINE: UntestablePath */ - } - - nevents = (size_t)rv; - - for (i = 0; i < nevents; i++) { - ares_event_t *ev; - ares_event_flags_t flags = 0; - - ev = ares_htable_asvp_get_direct(e->ev_sock_handles, - (ares_socket_t)events[i].data.fd); - if (ev == NULL || ev->cb == NULL) { - continue; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - cnt++; - - if (events[i].events & (EPOLLIN | EPOLLRDHUP | EPOLLHUP | EPOLLERR)) { - flags |= ARES_EVENT_FLAG_READ; - } - if (events[i].events & EPOLLOUT) { - flags |= ARES_EVENT_FLAG_WRITE; - } - - ev->cb(e, ev->fd, ev->data, flags); - } - - return cnt; -} - -const ares_event_sys_t ares_evsys_epoll = { "epoll", - ares_evsys_epoll_init, - ares_evsys_epoll_destroy, - ares_evsys_epoll_event_add, - ares_evsys_epoll_event_del, - ares_evsys_epoll_event_mod, - ares_evsys_epoll_wait }; -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_kqueue.c b/vendor/c-ares/src/lib/event/ares_event_kqueue.c deleted file mode 100644 index 00cdcbe9c..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_kqueue.c +++ /dev/null @@ -1,248 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_event.h" - -#if defined(HAVE_KQUEUE) && defined(CARES_THREADS) - -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_EVENT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif -#ifdef HAVE_FCNTL_H -# include -#endif - -typedef struct { - int kqueue_fd; - struct kevent *changelist; - size_t nchanges; - size_t nchanges_alloc; -} ares_evsys_kqueue_t; - -static void ares_evsys_kqueue_destroy(ares_event_thread_t *e) -{ - ares_evsys_kqueue_t *kq = NULL; - - if (e == NULL) { - return; - } - - kq = e->ev_sys_data; - if (kq == NULL) { - return; - } - - if (kq->kqueue_fd != -1) { - close(kq->kqueue_fd); - } - - ares_free(kq->changelist); - ares_free(kq); - e->ev_sys_data = NULL; -} - -static ares_bool_t ares_evsys_kqueue_init(ares_event_thread_t *e) -{ - ares_evsys_kqueue_t *kq = NULL; - - kq = ares_malloc_zero(sizeof(*kq)); - if (kq == NULL) { - return ARES_FALSE; - } - - e->ev_sys_data = kq; - - kq->kqueue_fd = kqueue(); - if (kq->kqueue_fd == -1) { - ares_evsys_kqueue_destroy(e); - return ARES_FALSE; - } - -# ifdef FD_CLOEXEC - fcntl(kq->kqueue_fd, F_SETFD, FD_CLOEXEC); -# endif - - kq->nchanges_alloc = 8; - kq->changelist = - ares_malloc_zero(kq->nchanges_alloc * sizeof(*kq->changelist)); - if (kq->changelist == NULL) { - ares_evsys_kqueue_destroy(e); - return ARES_FALSE; - } - - e->ev_signal = ares_pipeevent_create(e); - if (e->ev_signal == NULL) { - ares_evsys_kqueue_destroy(e); - return ARES_FALSE; - } - - return ARES_TRUE; -} - -static void ares_evsys_kqueue_enqueue(ares_evsys_kqueue_t *kq, int fd, - int16_t filter, uint16_t flags) -{ - size_t idx; - - if (kq == NULL) { - return; - } - - idx = kq->nchanges; - - kq->nchanges++; - - if (kq->nchanges > kq->nchanges_alloc) { - kq->nchanges_alloc <<= 1; - kq->changelist = ares_realloc_zero( - kq->changelist, (kq->nchanges_alloc >> 1) * sizeof(*kq->changelist), - kq->nchanges_alloc * sizeof(*kq->changelist)); - } - - EV_SET(&kq->changelist[idx], fd, filter, flags, 0, 0, 0); -} - -static void ares_evsys_kqueue_event_process(ares_event_t *event, - ares_event_flags_t old_flags, - ares_event_flags_t new_flags) -{ - ares_event_thread_t *e = event->e; - ares_evsys_kqueue_t *kq; - - if (e == NULL) { - return; - } - - kq = e->ev_sys_data; - if (kq == NULL) { - return; - } - - if (new_flags & ARES_EVENT_FLAG_READ && !(old_flags & ARES_EVENT_FLAG_READ)) { - ares_evsys_kqueue_enqueue(kq, event->fd, EVFILT_READ, EV_ADD | EV_ENABLE); - } - - if (!(new_flags & ARES_EVENT_FLAG_READ) && old_flags & ARES_EVENT_FLAG_READ) { - ares_evsys_kqueue_enqueue(kq, event->fd, EVFILT_READ, EV_DELETE); - } - - if (new_flags & ARES_EVENT_FLAG_WRITE && - !(old_flags & ARES_EVENT_FLAG_WRITE)) { - ares_evsys_kqueue_enqueue(kq, event->fd, EVFILT_WRITE, EV_ADD | EV_ENABLE); - } - - if (!(new_flags & ARES_EVENT_FLAG_WRITE) && - old_flags & ARES_EVENT_FLAG_WRITE) { - ares_evsys_kqueue_enqueue(kq, event->fd, EVFILT_WRITE, EV_DELETE); - } -} - -static ares_bool_t ares_evsys_kqueue_event_add(ares_event_t *event) -{ - ares_evsys_kqueue_event_process(event, 0, event->flags); - return ARES_TRUE; -} - -static void ares_evsys_kqueue_event_del(ares_event_t *event) -{ - ares_evsys_kqueue_event_process(event, event->flags, 0); -} - -static void ares_evsys_kqueue_event_mod(ares_event_t *event, - ares_event_flags_t new_flags) -{ - ares_evsys_kqueue_event_process(event, event->flags, new_flags); -} - -static size_t ares_evsys_kqueue_wait(ares_event_thread_t *e, - unsigned long timeout_ms) -{ - struct kevent events[8]; - size_t nevents = sizeof(events) / sizeof(*events); - ares_evsys_kqueue_t *kq = e->ev_sys_data; - int rv; - size_t i; - struct timespec ts; - struct timespec *timeout = NULL; - size_t cnt = 0; - - if (timeout_ms != 0) { - ts.tv_sec = (time_t)timeout_ms / 1000; - ts.tv_nsec = (timeout_ms % 1000) * 1000 * 1000; - timeout = &ts; - } - - memset(events, 0, sizeof(events)); - - rv = kevent(kq->kqueue_fd, kq->changelist, (int)kq->nchanges, events, - (int)nevents, timeout); - if (rv < 0) { - return 0; - } - - /* Changelist was consumed */ - kq->nchanges = 0; - nevents = (size_t)rv; - - for (i = 0; i < nevents; i++) { - ares_event_t *ev; - ares_event_flags_t flags = 0; - - ev = ares_htable_asvp_get_direct(e->ev_sock_handles, - (ares_socket_t)events[i].ident); - if (ev == NULL || ev->cb == NULL) { - continue; - } - - cnt++; - - if (events[i].filter == EVFILT_READ || - events[i].flags & (EV_EOF | EV_ERROR)) { - flags |= ARES_EVENT_FLAG_READ; - } else { - flags |= ARES_EVENT_FLAG_WRITE; - } - - ev->cb(e, ev->fd, ev->data, flags); - } - - return cnt; -} - -const ares_event_sys_t ares_evsys_kqueue = { "kqueue", - ares_evsys_kqueue_init, - ares_evsys_kqueue_destroy, - ares_evsys_kqueue_event_add, - ares_evsys_kqueue_event_del, - ares_evsys_kqueue_event_mod, - ares_evsys_kqueue_wait }; -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_poll.c b/vendor/c-ares/src/lib/event/ares_event_poll.c deleted file mode 100644 index 28e3c0965..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_poll.c +++ /dev/null @@ -1,140 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_event.h" - -#if defined(HAVE_POLL) && defined(CARES_THREADS) - -#ifdef HAVE_POLL_H -# include -#endif - -static ares_bool_t ares_evsys_poll_init(ares_event_thread_t *e) -{ - e->ev_signal = ares_pipeevent_create(e); - if (e->ev_signal == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: UntestablePath */ - } - return ARES_TRUE; -} - -static void ares_evsys_poll_destroy(ares_event_thread_t *e) -{ - (void)e; -} - -static ares_bool_t ares_evsys_poll_event_add(ares_event_t *event) -{ - (void)event; - return ARES_TRUE; -} - -static void ares_evsys_poll_event_del(ares_event_t *event) -{ - (void)event; -} - -static void ares_evsys_poll_event_mod(ares_event_t *event, - ares_event_flags_t new_flags) -{ - (void)event; - (void)new_flags; -} - -static size_t ares_evsys_poll_wait(ares_event_thread_t *e, - unsigned long timeout_ms) -{ - size_t num_fds = 0; - ares_socket_t *fdlist = ares_htable_asvp_keys(e->ev_sock_handles, &num_fds); - struct pollfd *pollfd = NULL; - int rv; - size_t cnt = 0; - size_t i; - - if (fdlist != NULL && num_fds) { - pollfd = ares_malloc_zero(sizeof(*pollfd) * num_fds); - if (pollfd == NULL) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - for (i = 0; i < num_fds; i++) { - const ares_event_t *ev = - ares_htable_asvp_get_direct(e->ev_sock_handles, fdlist[i]); - pollfd[i].fd = ev->fd; - if (ev->flags & ARES_EVENT_FLAG_READ) { - pollfd[i].events |= POLLIN; - } - if (ev->flags & ARES_EVENT_FLAG_WRITE) { - pollfd[i].events |= POLLOUT; - } - } - } - ares_free(fdlist); - - rv = poll(pollfd, (nfds_t)num_fds, (timeout_ms == 0) ? -1 : (int)timeout_ms); - if (rv <= 0) { - goto done; - } - - for (i = 0; pollfd != NULL && i < num_fds; i++) { - ares_event_t *ev; - ares_event_flags_t flags = 0; - - if (pollfd[i].revents == 0) { - continue; - } - - cnt++; - - ev = ares_htable_asvp_get_direct(e->ev_sock_handles, pollfd[i].fd); - if (ev == NULL || ev->cb == NULL) { - continue; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (pollfd[i].revents & (POLLERR | POLLHUP | POLLIN)) { - flags |= ARES_EVENT_FLAG_READ; - } - - if (pollfd[i].revents & POLLOUT) { - flags |= ARES_EVENT_FLAG_WRITE; - } - - ev->cb(e, pollfd[i].fd, ev->data, flags); - } - -done: - ares_free(pollfd); - return cnt; -} - -const ares_event_sys_t ares_evsys_poll = { "poll", - ares_evsys_poll_init, - ares_evsys_poll_destroy, /* NoOp */ - ares_evsys_poll_event_add, /* NoOp */ - ares_evsys_poll_event_del, /* NoOp */ - ares_evsys_poll_event_mod, /* NoOp */ - ares_evsys_poll_wait }; - -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_select.c b/vendor/c-ares/src/lib/event/ares_event_select.c deleted file mode 100644 index df758b5a1..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_select.c +++ /dev/null @@ -1,159 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -/* Some systems might default to something low like 256 (NetBSD), lets define - * this to assist. Really, no one should be using select, but lets be safe - * anyhow */ -#define FD_SETSIZE 4096 - -#include "ares_private.h" -#include "ares_event.h" - -/* All systems have select(), but not all have a way to wake, so we require - * pipe() to wake the select() */ -#if defined(HAVE_PIPE) && defined(CARES_THREADS) - -#ifdef HAVE_SYS_SELECT_H -# include -#endif - -static ares_bool_t ares_evsys_select_init(ares_event_thread_t *e) -{ - e->ev_signal = ares_pipeevent_create(e); - if (e->ev_signal == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: UntestablePath */ - } - return ARES_TRUE; -} - -static void ares_evsys_select_destroy(ares_event_thread_t *e) -{ - (void)e; -} - -static ares_bool_t ares_evsys_select_event_add(ares_event_t *event) -{ - (void)event; - return ARES_TRUE; -} - -static void ares_evsys_select_event_del(ares_event_t *event) -{ - (void)event; -} - -static void ares_evsys_select_event_mod(ares_event_t *event, - ares_event_flags_t new_flags) -{ - (void)event; - (void)new_flags; -} - -static size_t ares_evsys_select_wait(ares_event_thread_t *e, - unsigned long timeout_ms) -{ - size_t num_fds = 0; - ares_socket_t *fdlist = ares_htable_asvp_keys(e->ev_sock_handles, &num_fds); - int rv; - size_t cnt = 0; - size_t i; - fd_set read_fds; - fd_set write_fds; - fd_set except_fds; - int nfds = 0; - struct timeval tv; - struct timeval *tout = NULL; - - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - FD_ZERO(&except_fds); - - for (i = 0; i < num_fds; i++) { - const ares_event_t *ev = - ares_htable_asvp_get_direct(e->ev_sock_handles, fdlist[i]); - if (ev->flags & ARES_EVENT_FLAG_READ) { - FD_SET(ev->fd, &read_fds); - } - if (ev->flags & ARES_EVENT_FLAG_WRITE) { - FD_SET(ev->fd, &write_fds); - } - FD_SET(ev->fd, &except_fds); - if (ev->fd + 1 > nfds) { - nfds = ev->fd + 1; - } - } - - if (timeout_ms) { - tv.tv_sec = (int)(timeout_ms / 1000); - tv.tv_usec = (int)((timeout_ms % 1000) * 1000); - tout = &tv; - } - - rv = select(nfds, &read_fds, &write_fds, &except_fds, tout); - if (rv > 0) { - for (i = 0; i < num_fds; i++) { - ares_event_t *ev; - ares_event_flags_t flags = 0; - - ev = ares_htable_asvp_get_direct(e->ev_sock_handles, fdlist[i]); - if (ev == NULL || ev->cb == NULL) { - continue; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (FD_ISSET(fdlist[i], &read_fds) || FD_ISSET(fdlist[i], &except_fds)) { - flags |= ARES_EVENT_FLAG_READ; - } - - if (FD_ISSET(fdlist[i], &write_fds)) { - flags |= ARES_EVENT_FLAG_WRITE; - } - - if (flags == 0) { - continue; - } - - cnt++; - - ev->cb(e, fdlist[i], ev->data, flags); - } - } - - ares_free(fdlist); - - return cnt; -} - -const ares_event_sys_t ares_evsys_select = { - "select", - ares_evsys_select_init, - ares_evsys_select_destroy, /* NoOp */ - ares_evsys_select_event_add, /* NoOp */ - ares_evsys_select_event_del, /* NoOp */ - ares_evsys_select_event_mod, /* NoOp */ - ares_evsys_select_wait -}; - -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_thread.c b/vendor/c-ares/src/lib/event/ares_event_thread.c deleted file mode 100644 index c77514e02..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_thread.c +++ /dev/null @@ -1,567 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_event.h" - -#ifdef CARES_THREADS -static void ares_event_destroy_cb(void *arg) -{ - ares_event_t *event = arg; - if (event == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Unregister from the event thread if it was registered with one */ - if (event->e) { - const ares_event_thread_t *e = event->e; - e->ev_sys->event_del(event); - event->e = NULL; - } - - if (event->free_data_cb && event->data) { - event->free_data_cb(event->data); - } - - ares_free(event); -} - -static void ares_event_signal(const ares_event_t *event) -{ - if (event == NULL || event->signal_cb == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - event->signal_cb(event); -} - -static void ares_event_thread_wake(const ares_event_thread_t *e) -{ - if (e == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_event_signal(e->ev_signal); -} - -/* See if a pending update already exists. We don't want to enqueue multiple - * updates for the same event handle. Right now this is O(n) based on number - * of updates already enqueued. In the future, it might make sense to make - * this O(1) with a hashtable. - * NOTE: in some cases a delete then re-add of the same fd, but really pointing - * to a different destination can happen due to a quick close of a - * connection then creation of a new one. So we need to look at the - * flags and ignore any delete events when finding a match since we - * need to process the delete always, it can't be combined with other - * updates. */ -static ares_event_t *ares_event_update_find(ares_event_thread_t *e, - ares_socket_t fd, const void *data) -{ - ares_llist_node_t *node; - - for (node = ares_llist_node_first(e->ev_updates); node != NULL; - node = ares_llist_node_next(node)) { - ares_event_t *ev = ares_llist_node_val(node); - - if (fd != ARES_SOCKET_BAD && fd == ev->fd && ev->flags != 0) { - return ev; - } - - if (fd == ARES_SOCKET_BAD && ev->fd == ARES_SOCKET_BAD && - data == ev->data && ev->flags != 0) { - return ev; - } - } - - return NULL; -} - -ares_status_t ares_event_update(ares_event_t **event, ares_event_thread_t *e, - ares_event_flags_t flags, ares_event_cb_t cb, - ares_socket_t fd, void *data, - ares_event_free_data_t free_data_cb, - ares_event_signal_cb_t signal_cb) -{ - ares_event_t *ev = NULL; - ares_status_t status; - - if (e == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Callback must be specified if not a removal event. */ - if (flags != ARES_EVENT_FLAG_NONE && cb == NULL) { - return ARES_EFORMERR; - } - - if (event != NULL) { - *event = NULL; - } - - /* Validate flags */ - if (fd == ARES_SOCKET_BAD) { - if (flags & (ARES_EVENT_FLAG_READ | ARES_EVENT_FLAG_WRITE)) { - return ARES_EFORMERR; - } - if (!(flags & ARES_EVENT_FLAG_OTHER)) { - return ARES_EFORMERR; - } - } else { - if (flags & ARES_EVENT_FLAG_OTHER) { - return ARES_EFORMERR; - } - } - - /* That's all the validation we can really do */ - - ares_thread_mutex_lock(e->mutex); - - /* See if we have a queued update already */ - ev = ares_event_update_find(e, fd, data); - if (ev == NULL) { - /* Allocate a new one */ - ev = ares_malloc_zero(sizeof(*ev)); - if (ev == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (ares_llist_insert_last(e->ev_updates, ev) == NULL) { - ares_free(ev); /* LCOV_EXCL_LINE: OutOfMemory */ - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - ev->flags = flags; - ev->fd = fd; - if (ev->cb == NULL) { - ev->cb = cb; - } - if (ev->data == NULL) { - ev->data = data; - } - if (ev->free_data_cb == NULL) { - ev->free_data_cb = free_data_cb; - } - if (ev->signal_cb == NULL) { - ev->signal_cb = signal_cb; - } - - if (event != NULL) { - *event = ev; - } - - status = ARES_SUCCESS; - -done: - if (status == ARES_SUCCESS) { - /* Wake event thread if successful so it can pull the updates */ - ares_event_thread_wake(e); - } - - ares_thread_mutex_unlock(e->mutex); - - return status; -} - -static void ares_event_thread_process_fd(ares_event_thread_t *e, - ares_socket_t fd, void *data, - ares_event_flags_t flags) -{ - ares_fd_events_t event; - (void)data; - - event.fd = fd; - event.events = 0; - if (flags & ARES_EVENT_FLAG_READ) { - event.events |= ARES_FD_EVENT_READ; - } - if (flags & ARES_EVENT_FLAG_WRITE) { - event.events |= ARES_FD_EVENT_WRITE; - } - ares_process_fds(e->channel, &event, 1, ARES_PROCESS_FLAG_SKIP_NON_FD); -} - -static void ares_event_thread_sockstate_cb(void *data, ares_socket_t socket_fd, - int readable, int writable) -{ - ares_event_thread_t *e = data; - ares_event_flags_t flags = ARES_EVENT_FLAG_NONE; - - if (readable) { - flags |= ARES_EVENT_FLAG_READ; - } - - if (writable) { - flags |= ARES_EVENT_FLAG_WRITE; - } - - /* Update channel fd. This function will lock e->mutex and also wake the - * event thread to process the update */ - ares_event_update(NULL, e, flags, ares_event_thread_process_fd, socket_fd, - NULL, NULL, NULL); -} - -static void notifywrite_cb(void *data) -{ - ares_event_thread_t *e = data; - - ares_thread_mutex_lock(e->mutex); - e->process_pending_write = ARES_TRUE; - ares_thread_mutex_unlock(e->mutex); - - ares_event_thread_wake(e); -} - -static void ares_event_process_updates(ares_event_thread_t *e) -{ - ares_llist_node_t *node; - - /* Iterate across all updates and apply to internal list, removing from update - * list */ - while ((node = ares_llist_node_first(e->ev_updates)) != NULL) { - ares_event_t *newev = ares_llist_node_claim(node); - ares_event_t *oldev; - - if (newev->fd == ARES_SOCKET_BAD) { - oldev = ares_htable_vpvp_get_direct(e->ev_cust_handles, newev->data); - } else { - oldev = ares_htable_asvp_get_direct(e->ev_sock_handles, newev->fd); - } - - /* Adding new */ - if (oldev == NULL) { - newev->e = e; - /* Don't try to add a new event if all flags are cleared, that's basically - * someone trying to delete something already deleted. Also if it fails - * to add, cleanup. */ - if (newev->flags == ARES_EVENT_FLAG_NONE || - !e->ev_sys->event_add(newev)) { - newev->e = NULL; - ares_event_destroy_cb(newev); - } else { - if (newev->fd == ARES_SOCKET_BAD) { - ares_htable_vpvp_insert(e->ev_cust_handles, newev->data, newev); - } else { - ares_htable_asvp_insert(e->ev_sock_handles, newev->fd, newev); - } - } - continue; - } - - /* Removal request */ - if (newev->flags == ARES_EVENT_FLAG_NONE) { - /* the callback for the removal will call e->ev_sys->event_del(e, event) - */ - if (newev->fd == ARES_SOCKET_BAD) { - ares_htable_vpvp_remove(e->ev_cust_handles, newev->data); - } else { - ares_htable_asvp_remove(e->ev_sock_handles, newev->fd); - } - ares_free(newev); - continue; - } - - /* Modify request -- only flags can be changed */ - e->ev_sys->event_mod(oldev, newev->flags); - oldev->flags = newev->flags; - ares_free(newev); - } -} - -static void ares_event_thread_cleanup(ares_event_thread_t *e) -{ - /* Manually free any updates that weren't processed */ - if (e->ev_updates != NULL) { - ares_llist_node_t *node; - - while ((node = ares_llist_node_first(e->ev_updates)) != NULL) { - ares_event_destroy_cb(ares_llist_node_claim(node)); - } - ares_llist_destroy(e->ev_updates); - e->ev_updates = NULL; - } - - if (e->ev_sock_handles != NULL) { - ares_htable_asvp_destroy(e->ev_sock_handles); - e->ev_sock_handles = NULL; - } - - if (e->ev_cust_handles != NULL) { - ares_htable_vpvp_destroy(e->ev_cust_handles); - e->ev_cust_handles = NULL; - } - - if (e->ev_sys != NULL && e->ev_sys->destroy != NULL) { - e->ev_sys->destroy(e); - e->ev_sys = NULL; - } -} - -static void *ares_event_thread(void *arg) -{ - ares_event_thread_t *e = arg; - ares_thread_mutex_lock(e->mutex); - - while (e->isup) { - struct timeval tv; - const struct timeval *tvout; - unsigned long timeout_ms = 0; /* 0 = unlimited */ - ares_bool_t process_pending_write; - - ares_event_process_updates(e); - - /* Don't hold a mutex while waiting on events or calling into anything - * that might require a c-ares channel lock since a callback could be - * triggered cross-thread */ - ares_thread_mutex_unlock(e->mutex); - - tvout = ares_timeout(e->channel, NULL, &tv); - if (tvout != NULL) { - timeout_ms = - (unsigned long)((tvout->tv_sec * 1000) + (tvout->tv_usec / 1000) + 1); - } - - e->ev_sys->wait(e, timeout_ms); - - /* Process pending write operation */ - ares_thread_mutex_lock(e->mutex); - process_pending_write = e->process_pending_write; - e->process_pending_write = ARES_FALSE; - ares_thread_mutex_unlock(e->mutex); - if (process_pending_write) { - ares_process_pending_write(e->channel); - } - - /* Relock before we loop again */ - ares_thread_mutex_lock(e->mutex); - - /* Each iteration should do timeout processing and any other cleanup - * that may not have been performed */ - if (e->isup) { - ares_thread_mutex_unlock(e->mutex); - ares_process_fds(e->channel, NULL, 0, ARES_PROCESS_FLAG_NONE); - ares_thread_mutex_lock(e->mutex); - } - } - - /* Lets cleanup while we're in the thread itself */ - ares_event_thread_cleanup(e); - - ares_thread_mutex_unlock(e->mutex); - - return NULL; -} - -static void ares_event_thread_destroy_int(ares_event_thread_t *e) -{ - /* Wake thread and tell it to shutdown if it exists */ - ares_thread_mutex_lock(e->mutex); - if (e->isup) { - e->isup = ARES_FALSE; - ares_event_thread_wake(e); - } - ares_thread_mutex_unlock(e->mutex); - - /* Wait for thread to shutdown */ - if (e->thread) { - void *rv = NULL; - ares_thread_join(e->thread, &rv); - e->thread = NULL; - } - - /* If the event thread ever got to the point of starting, this is a no-op - * as it runs this same cleanup when it shuts down */ - ares_event_thread_cleanup(e); - - ares_thread_mutex_destroy(e->mutex); - e->mutex = NULL; - - ares_free(e); -} - -void ares_event_thread_destroy(ares_channel_t *channel) -{ - ares_event_thread_t *e = channel->sock_state_cb_data; - - if (e == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_event_thread_destroy_int(e); - channel->sock_state_cb_data = NULL; - channel->sock_state_cb = NULL; - channel->notify_pending_write_cb = NULL; - channel->notify_pending_write_cb_data = NULL; -} - -static const ares_event_sys_t *ares_event_fetch_sys(ares_evsys_t evsys) -{ - switch (evsys) { - case ARES_EVSYS_WIN32: -#if defined(USE_WINSOCK) - return &ares_evsys_win32; -#else - return NULL; -#endif - - case ARES_EVSYS_EPOLL: -#if defined(HAVE_EPOLL) - return &ares_evsys_epoll; -#else - return NULL; -#endif - - case ARES_EVSYS_KQUEUE: -#if defined(HAVE_KQUEUE) - return &ares_evsys_kqueue; -#else - return NULL; -#endif - - case ARES_EVSYS_POLL: -#if defined(HAVE_POLL) - return &ares_evsys_poll; -#else - return NULL; -#endif - - case ARES_EVSYS_SELECT: -#if defined(HAVE_PIPE) - return &ares_evsys_select; -#else - return NULL; -#endif - - /* case ARES_EVSYS_DEFAULT: */ - default: - break; - } - - /* default */ -#if defined(USE_WINSOCK) - return &ares_evsys_win32; -#elif defined(HAVE_KQUEUE) - return &ares_evsys_kqueue; -#elif defined(HAVE_EPOLL) - return &ares_evsys_epoll; -#elif defined(HAVE_POLL) - return &ares_evsys_poll; -#elif defined(HAVE_PIPE) - return &ares_evsys_select; -#else - return NULL; -#endif -} - -ares_status_t ares_event_thread_init(ares_channel_t *channel) -{ - ares_event_thread_t *e; - - e = ares_malloc_zero(sizeof(*e)); - if (e == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - e->mutex = ares_thread_mutex_create(); - if (e->mutex == NULL) { - ares_event_thread_destroy_int(e); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - e->ev_updates = ares_llist_create(NULL); - if (e->ev_updates == NULL) { - ares_event_thread_destroy_int(e); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - e->ev_sock_handles = ares_htable_asvp_create(ares_event_destroy_cb); - if (e->ev_sock_handles == NULL) { - ares_event_thread_destroy_int(e); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - e->ev_cust_handles = ares_htable_vpvp_create(NULL, ares_event_destroy_cb); - if (e->ev_cust_handles == NULL) { - ares_event_thread_destroy_int(e); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - e->channel = channel; - e->isup = ARES_TRUE; - e->ev_sys = ares_event_fetch_sys(channel->evsys); - if (e->ev_sys == NULL) { - ares_event_thread_destroy_int(e); /* LCOV_EXCL_LINE: UntestablePath */ - return ARES_ENOTIMP; /* LCOV_EXCL_LINE: UntestablePath */ - } - - channel->sock_state_cb = ares_event_thread_sockstate_cb; - channel->sock_state_cb_data = e; - channel->notify_pending_write_cb = notifywrite_cb; - channel->notify_pending_write_cb_data = e; - - if (!e->ev_sys->init(e)) { - /* LCOV_EXCL_START: UntestablePath */ - ares_event_thread_destroy_int(e); - channel->sock_state_cb = NULL; - channel->sock_state_cb_data = NULL; - return ARES_ESERVFAIL; - /* LCOV_EXCL_STOP */ - } - - /* Before starting the thread, process any possible events the initialization - * might have enqueued as we may actually depend on these being valid - * immediately upon return, which may mean before the thread is fully spawned - * and processed the list itself. We don't want any sort of race conditions - * (like the event system wake handle itself). */ - ares_event_process_updates(e); - - /* Start thread */ - if (ares_thread_create(&e->thread, ares_event_thread, e) != ARES_SUCCESS) { - /* LCOV_EXCL_START: UntestablePath */ - ares_event_thread_destroy_int(e); - channel->sock_state_cb = NULL; - channel->sock_state_cb_data = NULL; - return ARES_ESERVFAIL; - /* LCOV_EXCL_STOP */ - } - - return ARES_SUCCESS; -} - -#else - -ares_status_t ares_event_thread_init(ares_channel_t *channel) -{ - (void)channel; - return ARES_ENOTIMP; -} - -void ares_event_thread_destroy(ares_channel_t *channel) -{ - (void)channel; -} - -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_wake_pipe.c b/vendor/c-ares/src/lib/event/ares_event_wake_pipe.c deleted file mode 100644 index cd1534bbb..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_wake_pipe.c +++ /dev/null @@ -1,166 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_event.h" - -#if defined(HAVE_PIPE) && defined(CARES_THREADS) - -# ifdef HAVE_UNISTD_H -# include -# endif -# ifdef HAVE_FCNTL_H -# include -# endif - -typedef struct { - int filedes[2]; -} ares_pipeevent_t; - -static void ares_pipeevent_destroy(ares_pipeevent_t *p) -{ - if (p->filedes[0] != -1) { - close(p->filedes[0]); - } - if (p->filedes[1] != -1) { - close(p->filedes[1]); - } - - ares_free(p); -} - -static void ares_pipeevent_destroy_cb(void *arg) -{ - ares_pipeevent_destroy(arg); -} - -static ares_pipeevent_t *ares_pipeevent_init(void) -{ - ares_pipeevent_t *p = ares_malloc_zero(sizeof(*p)); - if (p == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - p->filedes[0] = -1; - p->filedes[1] = -1; - -# ifdef HAVE_PIPE2 - if (pipe2(p->filedes, O_NONBLOCK | O_CLOEXEC) != 0) { - ares_pipeevent_destroy(p); /* LCOV_EXCL_LINE: UntestablePath */ - return NULL; /* LCOV_EXCL_LINE: UntestablePath */ - } -# else - if (pipe(p->filedes) != 0) { - ares_pipeevent_destroy(p); - return NULL; - } - -# ifdef O_NONBLOCK - { - int val; - val = fcntl(p->filedes[0], F_GETFL, 0); - if (val >= 0) { - val |= O_NONBLOCK; - } - fcntl(p->filedes[0], F_SETFL, val); - - val = fcntl(p->filedes[1], F_GETFL, 0); - if (val >= 0) { - val |= O_NONBLOCK; - } - fcntl(p->filedes[1], F_SETFL, val); - } -# endif - -# ifdef FD_CLOEXEC - fcntl(p->filedes[0], F_SETFD, FD_CLOEXEC); - fcntl(p->filedes[1], F_SETFD, FD_CLOEXEC); -# endif -# endif - -# ifdef F_SETNOSIGPIPE - fcntl(p->filedes[0], F_SETNOSIGPIPE, 1); - fcntl(p->filedes[1], F_SETNOSIGPIPE, 1); -# endif - - return p; -} - -static void ares_pipeevent_signal(const ares_event_t *e) -{ - const ares_pipeevent_t *p; - - if (e == NULL || e->data == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - p = e->data; - (void)write(p->filedes[1], "1", 1); -} - -static void ares_pipeevent_cb(ares_event_thread_t *e, ares_socket_t fd, - void *data, ares_event_flags_t flags) -{ - unsigned char buf[32]; - const ares_pipeevent_t *p = NULL; - - (void)e; - (void)fd; - (void)flags; - - if (data == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - p = data; - - while (read(p->filedes[0], buf, sizeof(buf)) == sizeof(buf)) { - /* Do nothing */ - } -} - -ares_event_t *ares_pipeevent_create(ares_event_thread_t *e) -{ - ares_event_t *event = NULL; - ares_pipeevent_t *p = NULL; - ares_status_t status; - - p = ares_pipeevent_init(); - if (p == NULL) { - return NULL; - } - - status = ares_event_update(&event, e, ARES_EVENT_FLAG_READ, ares_pipeevent_cb, - p->filedes[0], p, ares_pipeevent_destroy_cb, - ares_pipeevent_signal); - if (status != ARES_SUCCESS) { - ares_pipeevent_destroy(p); /* LCOV_EXCL_LINE: DefensiveCoding */ - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - return event; -} - -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_win32.c b/vendor/c-ares/src/lib/event/ares_event_win32.c deleted file mode 100644 index d7d1d6573..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_win32.c +++ /dev/null @@ -1,978 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -/* Uses an anonymous union */ -#if defined(__clang__) || defined(__GNUC__) -# pragma GCC diagnostic push -# if defined(__clang__) -# pragma GCC diagnostic ignored "-Wc11-extensions" -# else -# pragma GCC diagnostic ignored "-Wpedantic" -# endif -#endif - -#include "ares_private.h" -#include "ares_event.h" -#include "ares_event_win32.h" - - -#if defined(USE_WINSOCK) && defined(CARES_THREADS) - -#ifdef HAVE_LIMITS_H -# include -#endif - -/* IMPLEMENTATION NOTES - * ==================== - * - * This implementation uses some undocumented functionality within Windows for - * monitoring sockets. The Ancillary Function Driver (AFD) is the low level - * implementation that Winsock2 sits on top of. Winsock2 unfortunately does - * not expose the equivalent of epoll() or kqueue(), but it is possible to - * access AFD directly and use along with IOCP to simulate the functionality. - * We want to use IOCP if possible as it gives us the ability to monitor more - * than just sockets (WSAPoll is not an option), and perform arbitrary callbacks - * which means we can hook in non-socket related events. - * - * The information for this implementation was gathered from "wepoll" and - * "libuv" which both use slight variants on this. We originally went with - * an implementation methodology more similar to "libuv", but we had a few - * user reports of crashes during shutdown and memory leaks due to some - * events not being delivered for cleanup of closed sockets. - * - * Initialization: - * 1. Dynamically load the NtDeviceIoControlFile, NtCreateFile, and - * NtCancelIoFileEx internal symbols from ntdll.dll. (Don't believe - * Microsoft's documentation for NtCancelIoFileEx as it documents an - * invalid prototype). These functions are to open a reference to the - * Ancillary Function Driver (AFD), and to submit and cancel POLL - * requests. - * 2. Create an IO Completion Port base handle via CreateIoCompletionPort() - * that all socket events will be delivered through. - * 3. Create a list of AFD Handles and track the number of poll requests - * per AFD handle. When we exceed a pre-determined limit of poll requests - * for a handle (128), we will automatically create a new handle. The - * reason behind this is NtCancelIoFileEx uses a horrible algorithm for - * issuing cancellations. See: - * https://github.com/python-trio/trio/issues/52#issuecomment-548215128 - * 4. Create a callback to be used to be able to interrupt waiting for IOCP - * events, this may be called for allowing enqueuing of additional socket - * events or removing socket events. PostQueuedCompletionStatus() is the - * obvious choice. We can use the same container format, the event - * delivered won't have an OVERLAPPED pointer so we can differentiate from - * socket events. Use the container as the completion key. - * - * Socket Add: - * 1. Create/Allocate a container for holding metadata about a socket - * including: - * - SOCKET base_socket; - * - IO_STATUS_BLOCK iosb; -- Used by AFD POLL, returned as OVERLAPPED - * - AFD_POLL_INFO afd_poll_info; -- Used by AFD POLL - * - afd list node -- for tracking which AFD handle a POLL request was - * submitted to. - * 2. Call WSAIoctl(..., SIO_BASE_HANDLE, ...) to unwrap the SOCKET and get - * the "base socket" we can use for polling. It appears this may fail so - * we should call WSAIoctl(..., SIO_BSP_HANDLE_POLL, ...) as a fallback. - * 3. Submit AFD POLL request (see "AFD POLL Request" section) - * 4. Record a mapping between the "IO Status Block" and the socket container - * so when events are delivered we can dereference. - * - * Socket Delete: - * 1. Call - * NtCancelIoFileEx(afd, iosb, &temp_iosb); - * to cancel any pending operations. - * 2. Tag the socket container as being queued for deletion - * 3. Wait for an event to be delivered for the socket (cancel isn't - * immediate, it delivers an event to know its complete). Delete only once - * that event has been delivered. If we don't do this we could try to - * access free()'d memory at a later point. - * - * Socket Modify: - * 1. Call - * NtCancelIoFileEx(afd, iosb, &temp_iosb) - * to cancel any pending operation. - * 2. When the event comes through that the cancel is complete, enqueue - * another "AFD Poll Request" for the desired events. - * - * Event Wait: - * 1. Call GetQueuedCompletionStatusEx() with the base IOCP handle, a - * stack allocated array of OVERLAPPED_ENTRY's, and an appropriate - * timeout. - * 2. Iterate across returned events, if the lpOverlapped is NULL, then the - * the CompletionKey is a pointer to the container registered via - * PostQueuedCompletionStatus(), otherwise it is the "IO Status Block" - * registered with the "AFD Poll Request" which needs to be dereferenced - * to the "socket container". - * 3. If it is a "socket container", disassociate it from the afd list node - * it was previously submitted to. - * 4. If it is a "socket container" check to see if we are cleaning up, if so, - * clean it up. - * 5. If it is a "socket container" that is still valid, Submit an - * AFD POLL Request (see "AFD POLL Request"). We must re-enable the request - * each time we receive a response, it is not persistent. - * 6. Notify of any events received as indicated in the AFD_POLL_INFO - * Handles[0].Events (NOTE: check NumberOfHandles > 0, and the status in - * the IO_STATUS_BLOCK. If we received an AFD_POLL_LOCAL_CLOSE, clean up - * the connection like the integrator requested it to be cleaned up. - * - * AFD Poll Request: - * 1. Find an afd poll handle in the list that has fewer pending requests than - * the limit. - * 2. If an afd poll handle was not associated (e.g. due to all being over - * limit), create a new afd poll handle by calling NtCreateFile() - * with path \Device\Afd , then add the AFD handle to the IO Completion - * Port. We can leave the completion key as blank since events for - * multiple sockets will be delivered through this and we need to - * differentiate via the OVERLAPPED member returned. Add the new AFD - * handle to the list of handles. - * 3. Initialize the AFD_POLL_INFO structure: - * Exclusive = FALSE; // allow multiple requests - * NumberOfHandles = 1; - * Timeout.QuadPart = LLONG_MAX; - * Handles[0].Handle = (HANDLE)base_socket; - * Handles[0].Status = 0; - * Handles[0].Events = AFD_POLL_LOCAL_CLOSE + additional events to wait for - * such as AFD_POLL_RECEIVE, etc; - * 4. Zero out the IO_STATUS_BLOCK structures - * 5. Set the "Status" member of IO_STATUS_BLOCK to STATUS_PENDING - * 6. Call - * NtDeviceIoControlFile(afd, NULL, NULL, &iosb, - * &iosb, IOCTL_AFD_POLL - * &afd_poll_info, sizeof(afd_poll_info), - * &afd_poll_info, sizeof(afd_poll_info)); - * - * - * References: - * - https://github.com/piscisaureus/wepoll/ - * - https://github.com/libuv/libuv/ - */ - -/* Cap the number of outstanding AFD poll requests per AFD handle due to known - * slowdowns with large lists and NtCancelIoFileEx() */ -# define AFD_POLL_PER_HANDLE 128 - -# include - -/* # define CARES_DEBUG 1 */ - -# ifdef __GNUC__ -# define CARES_PRINTF_LIKE(fmt, args) \ - __attribute__((format(printf, fmt, args))) -# else -# define CARES_PRINTF_LIKE(fmt, args) -# endif - -static void CARES_DEBUG_LOG(const char *fmt, ...) CARES_PRINTF_LIKE(1, 2); - -static void CARES_DEBUG_LOG(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); -# ifdef CARES_DEBUG - vfprintf(stderr, fmt, ap); - fflush(stderr); -# endif - va_end(ap); -} - -typedef struct { - /* Dynamically loaded symbols */ - NtCreateFile_t NtCreateFile; - NtDeviceIoControlFile_t NtDeviceIoControlFile; - NtCancelIoFileEx_t NtCancelIoFileEx; - - /* Implementation details */ - ares_slist_t *afd_handles; - HANDLE iocp_handle; - - /* IO_STATUS_BLOCK * -> ares_evsys_win32_eventdata_t * mapping. There is - * no completion key passed to IOCP with this method so we have to look - * up based on the lpOverlapped returned (which is mapped to IO_STATUS_BLOCK) - */ - ares_htable_vpvp_t *sockets; - - /* Flag about whether or not we are shutting down */ - ares_bool_t is_shutdown; -} ares_evsys_win32_t; - -typedef enum { - POLL_STATUS_NONE = 0, - POLL_STATUS_PENDING = 1, - POLL_STATUS_CANCEL = 2, - POLL_STATUS_DESTROY = 3 -} poll_status_t; - -typedef struct { - /*! Pointer to parent event container */ - ares_event_t *event; - /*! Socket passed in to monitor */ - SOCKET socket; - /*! Base socket derived from provided socket */ - SOCKET base_socket; - /*! Structure for submitting AFD POLL requests (Internals!) */ - AFD_POLL_INFO afd_poll_info; - /*! Status of current polling operation */ - poll_status_t poll_status; - /*! IO Status Block structure submitted with AFD POLL requests and returned - * with IOCP results as lpOverlapped (even though its a different structure) - */ - IO_STATUS_BLOCK iosb; - /*! AFD handle node an outstanding poll request is associated with */ - ares_slist_node_t *afd_handle_node; - /* Lock is only for PostQueuedCompletionStatus() to prevent multiple - * signals. Tracking via POLL_STATUS_PENDING/POLL_STATUS_NONE */ - ares_thread_mutex_t *lock; -} ares_evsys_win32_eventdata_t; - -static size_t ares_evsys_win32_wait(ares_event_thread_t *e, - unsigned long timeout_ms); - -static void ares_iocpevent_signal(const ares_event_t *event) -{ - ares_event_thread_t *e = event->e; - ares_evsys_win32_t *ew = e->ev_sys_data; - ares_evsys_win32_eventdata_t *ed = event->data; - ares_bool_t queue_event = ARES_FALSE; - - ares_thread_mutex_lock(ed->lock); - if (ed->poll_status != POLL_STATUS_PENDING) { - ed->poll_status = POLL_STATUS_PENDING; - queue_event = ARES_TRUE; - } - ares_thread_mutex_unlock(ed->lock); - - if (!queue_event) { - return; - } - - PostQueuedCompletionStatus(ew->iocp_handle, 0, (ULONG_PTR)event->data, NULL); -} - -static void ares_iocpevent_cb(ares_event_thread_t *e, ares_socket_t fd, - void *data, ares_event_flags_t flags) -{ - ares_evsys_win32_eventdata_t *ed = data; - (void)e; - (void)fd; - (void)flags; - ares_thread_mutex_lock(ed->lock); - ed->poll_status = POLL_STATUS_NONE; - ares_thread_mutex_unlock(ed->lock); -} - -static ares_event_t *ares_iocpevent_create(ares_event_thread_t *e) -{ - ares_event_t *event = NULL; - ares_status_t status; - - status = - ares_event_update(&event, e, ARES_EVENT_FLAG_OTHER, ares_iocpevent_cb, - ARES_SOCKET_BAD, NULL, NULL, ares_iocpevent_signal); - if (status != ARES_SUCCESS) { - return NULL; - } - - return event; -} - -static void ares_evsys_win32_destroy(ares_event_thread_t *e) -{ - ares_evsys_win32_t *ew = NULL; - - if (e == NULL) { - return; - } - - CARES_DEBUG_LOG("** Win32 Event Destroy\n"); - - ew = e->ev_sys_data; - if (ew == NULL) { - return; - } - - ew->is_shutdown = ARES_TRUE; - CARES_DEBUG_LOG(" ** waiting on %lu remaining sockets to be destroyed\n", - (unsigned long)ares_htable_vpvp_num_keys(ew->sockets)); - while (ares_htable_vpvp_num_keys(ew->sockets)) { - ares_evsys_win32_wait(e, 0); - } - CARES_DEBUG_LOG(" ** all sockets cleaned up\n"); - - - if (ew->iocp_handle != NULL) { - CloseHandle(ew->iocp_handle); - } - - ares_slist_destroy(ew->afd_handles); - - ares_htable_vpvp_destroy(ew->sockets); - - ares_free(ew); - e->ev_sys_data = NULL; -} - -typedef struct { - size_t poll_cnt; - HANDLE afd_handle; -} ares_afd_handle_t; - -static void ares_afd_handle_destroy(void *arg) -{ - ares_afd_handle_t *hnd = arg; - if (hnd != NULL && hnd->afd_handle != NULL) { - CloseHandle(hnd->afd_handle); - } - ares_free(hnd); -} - -static int ares_afd_handle_cmp(const void *data1, const void *data2) -{ - const ares_afd_handle_t *hnd1 = data1; - const ares_afd_handle_t *hnd2 = data2; - - if (hnd1->poll_cnt > hnd2->poll_cnt) { - return 1; - } - if (hnd1->poll_cnt < hnd2->poll_cnt) { - return -1; - } - return 0; -} - -static void fill_object_attributes(OBJECT_ATTRIBUTES *attr, - UNICODE_STRING *name, ULONG attributes) -{ - memset(attr, 0, sizeof(*attr)); - attr->Length = sizeof(*attr); - attr->ObjectName = name; - attr->Attributes = attributes; -} - -# define UNICODE_STRING_CONSTANT(s) \ - { (sizeof(s) - 1) * sizeof(wchar_t), sizeof(s) * sizeof(wchar_t), L##s } - -static ares_slist_node_t *ares_afd_handle_create(ares_evsys_win32_t *ew) -{ - UNICODE_STRING afd_device_name = UNICODE_STRING_CONSTANT("\\Device\\Afd"); - OBJECT_ATTRIBUTES afd_attributes; - NTSTATUS status; - IO_STATUS_BLOCK iosb; - ares_afd_handle_t *afd = ares_malloc_zero(sizeof(*afd)); - ares_slist_node_t *node = NULL; - if (afd == NULL) { - goto fail; - } - - /* Open a handle to the AFD subsystem */ - fill_object_attributes(&afd_attributes, &afd_device_name, 0); - memset(&iosb, 0, sizeof(iosb)); - iosb.Status = STATUS_PENDING; - status = ew->NtCreateFile(&afd->afd_handle, SYNCHRONIZE, &afd_attributes, - &iosb, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, - FILE_OPEN, 0, NULL, 0); - if (status != STATUS_SUCCESS) { - CARES_DEBUG_LOG("** Failed to create AFD endpoint\n"); - goto fail; - } - - if (CreateIoCompletionPort(afd->afd_handle, ew->iocp_handle, - 0 /* CompletionKey */, 0) == NULL) { - goto fail; - } - - if (!SetFileCompletionNotificationModes(afd->afd_handle, - FILE_SKIP_SET_EVENT_ON_HANDLE)) { - goto fail; - } - - node = ares_slist_insert(ew->afd_handles, afd); - if (node == NULL) { - goto fail; - } - - return node; - -fail: - - ares_afd_handle_destroy(afd); - return NULL; -} - -/* Fetch the lowest poll count entry, but if it exceeds the limit, create a - * new one and return that */ -static ares_slist_node_t *ares_afd_handle_fetch(ares_evsys_win32_t *ew) -{ - ares_slist_node_t *node = ares_slist_node_first(ew->afd_handles); - ares_afd_handle_t *afd = ares_slist_node_val(node); - - if (afd != NULL && afd->poll_cnt < AFD_POLL_PER_HANDLE) { - return node; - } - - return ares_afd_handle_create(ew); -} - -static ares_bool_t ares_evsys_win32_init(ares_event_thread_t *e) -{ - ares_evsys_win32_t *ew = NULL; - HMODULE ntdll; - - CARES_DEBUG_LOG("** Win32 Event Init\n"); - - ew = ares_malloc_zero(sizeof(*ew)); - if (ew == NULL) { - return ARES_FALSE; - } - - e->ev_sys_data = ew; - - /* All apps should have ntdll.dll already loaded, so just get a handle to - * this */ - ntdll = GetModuleHandleA("ntdll.dll"); - if (ntdll == NULL) { - goto fail; - } - -# ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpedantic" -/* Without the (void *) cast we get: - * warning: cast between incompatible function types from 'FARPROC' {aka 'long - * long int (*)()'} to 'NTSTATUS (*)(...)'} [-Wcast-function-type] but with it - * we get: warning: ISO C forbids conversion of function pointer to object - * pointer type [-Wpedantic] look unsolvable short of killing the warning. - */ -# endif - - /* Load Internal symbols not typically accessible */ - ew->NtCreateFile = - (NtCreateFile_t)(void *)GetProcAddress(ntdll, "NtCreateFile"); - ew->NtDeviceIoControlFile = (NtDeviceIoControlFile_t)(void *)GetProcAddress( - ntdll, "NtDeviceIoControlFile"); - ew->NtCancelIoFileEx = - (NtCancelIoFileEx_t)(void *)GetProcAddress(ntdll, "NtCancelIoFileEx"); - -# ifdef __GNUC__ -# pragma GCC diagnostic pop -# endif - - if (ew->NtCreateFile == NULL || ew->NtCancelIoFileEx == NULL || - ew->NtDeviceIoControlFile == NULL) { - goto fail; - } - - ew->iocp_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); - if (ew->iocp_handle == NULL) { - goto fail; - } - - ew->afd_handles = ares_slist_create( - e->channel->rand_state, ares_afd_handle_cmp, ares_afd_handle_destroy); - if (ew->afd_handles == NULL) { - goto fail; - } - - /* Create at least the first afd handle, so we know of any critical system - * issues during startup */ - if (ares_afd_handle_create(ew) == NULL) { - goto fail; - } - - e->ev_signal = ares_iocpevent_create(e); - if (e->ev_signal == NULL) { - goto fail; - } - - ew->sockets = ares_htable_vpvp_create(NULL, NULL); - if (ew->sockets == NULL) { - goto fail; - } - - return ARES_TRUE; - -fail: - ares_evsys_win32_destroy(e); - return ARES_FALSE; -} - -static ares_socket_t ares_evsys_win32_basesocket(ares_socket_t socket) -{ - while (1) { - DWORD bytes; /* Not used */ - ares_socket_t base_socket = ARES_SOCKET_BAD; - int rv; - - rv = WSAIoctl(socket, SIO_BASE_HANDLE, NULL, 0, &base_socket, - sizeof(base_socket), &bytes, NULL, NULL); - if (rv != SOCKET_ERROR && base_socket != ARES_SOCKET_BAD) { - socket = base_socket; - break; - } - - /* If we're here, an error occurred */ - if (GetLastError() == WSAENOTSOCK) { - /* This is critical, exit */ - return ARES_SOCKET_BAD; - } - - /* Work around known bug in Komodia based LSPs, use ARES_BSP_HANDLE_POLL - * to retrieve the underlying socket to then loop and get the base socket: - * https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls - * https://www.komodia.com/newwiki/index.php?title=Komodia%27s_Redirector_bug_fixes#Version_2.2.2.6 - */ - base_socket = ARES_SOCKET_BAD; - rv = WSAIoctl(socket, SIO_BSP_HANDLE_POLL, NULL, 0, &base_socket, - sizeof(base_socket), &bytes, NULL, NULL); - - if (rv != SOCKET_ERROR && base_socket != ARES_SOCKET_BAD && - base_socket != socket) { - socket = base_socket; - continue; /* loop! */ - } - - return ARES_SOCKET_BAD; - } - - return socket; -} - -static ares_bool_t ares_evsys_win32_afd_enqueue(ares_event_t *event, - ares_event_flags_t flags) -{ - ares_event_thread_t *e = event->e; - ares_evsys_win32_t *ew = e->ev_sys_data; - ares_evsys_win32_eventdata_t *ed = event->data; - ares_afd_handle_t *afd; - NTSTATUS status; - - if (e == NULL || ed == NULL || ew == NULL) { - return ARES_FALSE; - } - - /* Misuse */ - if (ed->poll_status != POLL_STATUS_NONE) { - return ARES_FALSE; - } - - ed->afd_handle_node = ares_afd_handle_fetch(ew); - /* System resource issue? */ - if (ed->afd_handle_node == NULL) { - return ARES_FALSE; - } - - afd = ares_slist_node_val(ed->afd_handle_node); - - /* Enqueue AFD Poll */ - ed->afd_poll_info.Exclusive = FALSE; - ed->afd_poll_info.NumberOfHandles = 1; - ed->afd_poll_info.Timeout.QuadPart = LLONG_MAX; - ed->afd_poll_info.Handles[0].Handle = (HANDLE)ed->base_socket; - ed->afd_poll_info.Handles[0].Status = 0; - ed->afd_poll_info.Handles[0].Events = AFD_POLL_LOCAL_CLOSE; - - if (flags & ARES_EVENT_FLAG_READ) { - ed->afd_poll_info.Handles[0].Events |= - (AFD_POLL_RECEIVE | AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | - AFD_POLL_ABORT); - } - if (flags & ARES_EVENT_FLAG_WRITE) { - ed->afd_poll_info.Handles[0].Events |= - (AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL); - } - if (flags == 0) { - ed->afd_poll_info.Handles[0].Events |= AFD_POLL_DISCONNECT; - } - - memset(&ed->iosb, 0, sizeof(ed->iosb)); - ed->iosb.Status = STATUS_PENDING; - - status = ew->NtDeviceIoControlFile( - afd->afd_handle, NULL, NULL, &ed->iosb, &ed->iosb, IOCTL_AFD_POLL, - &ed->afd_poll_info, sizeof(ed->afd_poll_info), &ed->afd_poll_info, - sizeof(ed->afd_poll_info)); - if (status != STATUS_SUCCESS && status != STATUS_PENDING) { - CARES_DEBUG_LOG("** afd_enqueue ed=%p FAILED\n", (void *)ed); - ed->afd_handle_node = NULL; - return ARES_FALSE; - } - - /* Record that we submitted a poll request to this handle and tell it to - * re-sort the node since we changed its sort value */ - afd->poll_cnt++; - ares_slist_node_reinsert(ed->afd_handle_node); - - ed->poll_status = POLL_STATUS_PENDING; - CARES_DEBUG_LOG("++ afd_enqueue ed=%p flags=%X\n", (void *)ed, - (unsigned int)flags); - return ARES_TRUE; -} - -static ares_bool_t ares_evsys_win32_afd_cancel(ares_evsys_win32_eventdata_t *ed) -{ - IO_STATUS_BLOCK cancel_iosb; - ares_evsys_win32_t *ew; - NTSTATUS status; - ares_afd_handle_t *afd; - - ew = ed->event->e->ev_sys_data; - - /* Misuse */ - if (ed->poll_status != POLL_STATUS_PENDING) { - return ARES_FALSE; - } - - afd = ares_slist_node_val(ed->afd_handle_node); - - /* Misuse */ - if (afd == NULL) { - return ARES_FALSE; - } - - ed->poll_status = POLL_STATUS_CANCEL; - - /* Not pending, nothing to do. Most likely that means there is a pending - * event that hasn't yet been delivered otherwise it would be re-armed - * already */ - if (ed->iosb.Status != STATUS_PENDING) { - CARES_DEBUG_LOG("** cancel not needed for ed=%p\n", (void *)ed); - return ARES_FALSE; - } - - status = ew->NtCancelIoFileEx(afd->afd_handle, &ed->iosb, &cancel_iosb); - - CARES_DEBUG_LOG("** Enqueued cancel for ed=%p, status = %lX\n", (void *)ed, - status); - - /* NtCancelIoFileEx() may return STATUS_NOT_FOUND if the operation completed - * just before calling NtCancelIoFileEx(), but we have not yet received the - * notification (but it should be queued for the next IOCP event). */ - if (status == STATUS_SUCCESS || status == STATUS_NOT_FOUND) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -static void ares_evsys_win32_eventdata_destroy(ares_evsys_win32_t *ew, - ares_evsys_win32_eventdata_t *ed) -{ - if (ew == NULL || ed == NULL) { - return; - } - CARES_DEBUG_LOG("-- deleting ed=%p (%s)\n", (void *)ed, - (ed->socket == ARES_SOCKET_BAD) ? "data" : "socket"); - /* These type of handles are deferred destroy. Update tracking. */ - if (ed->socket != ARES_SOCKET_BAD) { - ares_htable_vpvp_remove(ew->sockets, &ed->iosb); - } - - ares_thread_mutex_destroy(ed->lock); - - if (ed->event != NULL) { - ed->event->data = NULL; - } - - ares_free(ed); -} - -static ares_bool_t ares_evsys_win32_event_add(ares_event_t *event) -{ - ares_event_thread_t *e = event->e; - ares_evsys_win32_t *ew = e->ev_sys_data; - ares_evsys_win32_eventdata_t *ed; - ares_bool_t rc = ARES_FALSE; - - ed = ares_malloc_zero(sizeof(*ed)); - ed->event = event; - ed->socket = event->fd; - ed->base_socket = ARES_SOCKET_BAD; - event->data = ed; - - CARES_DEBUG_LOG("++ add ed=%p (%s) flags=%X\n", (void *)ed, - (ed->socket == ARES_SOCKET_BAD) ? "data" : "socket", - (unsigned int)event->flags); - - /* Likely a signal event, not something we will directly handle. We create - * the ares_evsys_win32_eventdata_t as the placeholder to use as the - * IOCP Completion Key */ - if (ed->socket == ARES_SOCKET_BAD) { - ed->lock = ares_thread_mutex_create(); - if (ed->lock == NULL) { - goto done; - } - rc = ARES_TRUE; - goto done; - } - - ed->base_socket = ares_evsys_win32_basesocket(ed->socket); - if (ed->base_socket == ARES_SOCKET_BAD) { - goto done; - } - - if (!ares_htable_vpvp_insert(ew->sockets, &ed->iosb, ed)) { - goto done; - } - - if (!ares_evsys_win32_afd_enqueue(event, event->flags)) { - goto done; - } - - rc = ARES_TRUE; - -done: - if (!rc) { - ares_evsys_win32_eventdata_destroy(ew, ed); - event->data = NULL; - } - return rc; -} - -static void ares_evsys_win32_event_del(ares_event_t *event) -{ - ares_evsys_win32_eventdata_t *ed = event->data; - - /* Already cleaned up, likely a LOCAL_CLOSE */ - if (ed == NULL) { - return; - } - - CARES_DEBUG_LOG("-- DELETE requested for ed=%p (%s)\n", (void *)ed, - (ed->socket != ARES_SOCKET_BAD) ? "socket" : "data"); - - /* - * Cancel pending AFD Poll operation. - */ - if (ed->socket != ARES_SOCKET_BAD) { - ares_evsys_win32_afd_cancel(ed); - ed->poll_status = POLL_STATUS_DESTROY; - ed->event = NULL; - } else { - ares_evsys_win32_eventdata_destroy(event->e->ev_sys_data, ed); - } - - event->data = NULL; -} - -static void ares_evsys_win32_event_mod(ares_event_t *event, - ares_event_flags_t new_flags) -{ - ares_evsys_win32_eventdata_t *ed = event->data; - - /* Not for us */ - if (event->fd == ARES_SOCKET_BAD || ed == NULL) { - return; - } - - CARES_DEBUG_LOG("** mod ed=%p new_flags=%X\n", (void *)ed, - (unsigned int)new_flags); - - /* All we need to do is cancel the pending operation. When the event gets - * delivered for the cancellation, it will automatically re-enqueue a new - * event */ - ares_evsys_win32_afd_cancel(ed); -} - -static ares_bool_t ares_evsys_win32_process_other_event( - ares_evsys_win32_t *ew, ares_evsys_win32_eventdata_t *ed, size_t i) -{ - ares_event_t *event; - - /* NOTE: do NOT dereference 'ed' if during shutdown as this could be an - * invalid pointer if the signal handle was cleaned up, but there was still a - * pending event! */ - - if (ew->is_shutdown) { - CARES_DEBUG_LOG("\t\t** i=%lu, skip non-socket handle during shutdown\n", - (unsigned long)i); - return ARES_FALSE; - } - - event = ed->event; - CARES_DEBUG_LOG("\t\t** i=%lu, ed=%p (data)\n", (unsigned long)i, (void *)ed); - - event->cb(event->e, event->fd, event->data, ARES_EVENT_FLAG_OTHER); - return ARES_TRUE; -} - -static ares_bool_t ares_evsys_win32_process_socket_event( - ares_evsys_win32_t *ew, ares_evsys_win32_eventdata_t *ed, size_t i) -{ - ares_event_flags_t flags = 0; - ares_event_t *event = NULL; - ares_afd_handle_t *afd = NULL; - - /* Shouldn't be possible */ - if (ed == NULL) { - CARES_DEBUG_LOG("\t\t** i=%lu, Invalid handle.\n", (unsigned long)i); - return ARES_FALSE; - } - - event = ed->event; - - CARES_DEBUG_LOG("\t\t** i=%lu, ed=%p (socket)\n", (unsigned long)i, - (void *)ed); - - /* Process events */ - if (ed->poll_status == POLL_STATUS_PENDING && - ed->iosb.Status == STATUS_SUCCESS && - ed->afd_poll_info.NumberOfHandles > 0) { - if (ed->afd_poll_info.Handles[0].Events & - (AFD_POLL_RECEIVE | AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | - AFD_POLL_ABORT)) { - flags |= ARES_EVENT_FLAG_READ; - } - if (ed->afd_poll_info.Handles[0].Events & - (AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL)) { - flags |= ARES_EVENT_FLAG_WRITE; - } - if (ed->afd_poll_info.Handles[0].Events & AFD_POLL_LOCAL_CLOSE) { - CARES_DEBUG_LOG("\t\t** ed=%p LOCAL CLOSE\n", (void *)ed); - ed->poll_status = POLL_STATUS_DESTROY; - } - } - - CARES_DEBUG_LOG("\t\t** ed=%p, iosb status=%lX, poll_status=%d, flags=%X\n", - (void *)ed, (unsigned long)ed->iosb.Status, - (int)ed->poll_status, (unsigned int)flags); - - /* Decrement poll count for AFD handle then resort, also disassociate - * with socket */ - afd = ares_slist_node_val(ed->afd_handle_node); - afd->poll_cnt--; - ares_slist_node_reinsert(ed->afd_handle_node); - ed->afd_handle_node = NULL; - - /* Pending destroy, go ahead and kill it */ - if (ed->poll_status == POLL_STATUS_DESTROY) { - ares_evsys_win32_eventdata_destroy(ew, ed); - return ARES_FALSE; - } - - ed->poll_status = POLL_STATUS_NONE; - - /* Mask flags against current desired flags. We could have an event - * queued that is outdated. */ - flags &= event->flags; - - /* Don't actually do anything with the event that was delivered as we are - * in a shutdown/cleanup process. Mostly just handling the delayed - * destruction of sockets */ - if (ew->is_shutdown) { - return ARES_FALSE; - } - - /* Re-enqueue so we can get more events on the socket, we either - * received a real event, or a cancellation notice. Both cases we - * re-queue using the current configured event flags. - * - * If we can't re-enqueue, that likely means the socket has been - * closed, so we want to kill our reference to it - */ - if (!ares_evsys_win32_afd_enqueue(event, event->flags)) { - ares_evsys_win32_eventdata_destroy(ew, ed); - return ARES_FALSE; - } - - /* No events we recognize to deliver */ - if (flags == 0) { - return ARES_FALSE; - } - - event->cb(event->e, event->fd, event->data, flags); - return ARES_TRUE; -} - -static size_t ares_evsys_win32_wait(ares_event_thread_t *e, - unsigned long timeout_ms) -{ - ares_evsys_win32_t *ew = e->ev_sys_data; - OVERLAPPED_ENTRY entries[16]; - ULONG maxentries = sizeof(entries) / sizeof(*entries); - ULONG nentries; - BOOL status; - size_t i; - size_t cnt = 0; - DWORD tout = (timeout_ms == 0) ? INFINITE : (DWORD)timeout_ms; - - CARES_DEBUG_LOG("** Wait Enter\n"); - /* Process in a loop for as long as it fills the entire entries buffer, and - * on subsequent attempts, ensure the timeout is 0 */ - do { - nentries = maxentries; - status = GetQueuedCompletionStatusEx(ew->iocp_handle, entries, nentries, - &nentries, tout, FALSE); - - /* Next loop around, we want to return instantly if there are no events to - * be processed */ - tout = 0; - - if (!status) { - break; - } - - CARES_DEBUG_LOG("\t** GetQueuedCompletionStatusEx returned %lu entries\n", - (unsigned long)nentries); - for (i = 0; i < (size_t)nentries; i++) { - ares_evsys_win32_eventdata_t *ed = NULL; - ares_bool_t rc; - - /* For things triggered via PostQueuedCompletionStatus() we have an - * lpCompletionKey we can just use. Otherwise we need to dereference the - * pointer returned in lpOverlapped to determine the referenced - * socket */ - if (entries[i].lpCompletionKey) { - ed = (ares_evsys_win32_eventdata_t *)entries[i].lpCompletionKey; - rc = ares_evsys_win32_process_other_event(ew, ed, i); - } else { - ed = ares_htable_vpvp_get_direct(ew->sockets, entries[i].lpOverlapped); - rc = ares_evsys_win32_process_socket_event(ew, ed, i); - } - - /* We processed actual events */ - if (rc) { - cnt++; - } - } - } while (nentries == maxentries); - - CARES_DEBUG_LOG("** Wait Exit\n"); - - return cnt; -} - -const ares_event_sys_t ares_evsys_win32 = { "win32", - ares_evsys_win32_init, - ares_evsys_win32_destroy, - ares_evsys_win32_event_add, - ares_evsys_win32_event_del, - ares_evsys_win32_event_mod, - ares_evsys_win32_wait }; -#endif - -#if defined(__clang__) || defined(__GNUC__) -# pragma GCC diagnostic pop -#endif diff --git a/vendor/c-ares/src/lib/event/ares_event_win32.h b/vendor/c-ares/src/lib/event/ares_event_win32.h deleted file mode 100644 index 5d0274cd8..000000000 --- a/vendor/c-ares/src/lib/event/ares_event_win32.h +++ /dev/null @@ -1,161 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_EVENT_WIN32_H -#define __ARES_EVENT_WIN32_H - -#ifdef _WIN32 -# ifdef HAVE_WINSOCK2_H -# include -# endif -# ifdef HAVE_WS2TCPIP_H -# include -# endif -# ifdef HAVE_MSWSOCK_H -# include -# endif -# ifdef HAVE_WINDOWS_H -# include -# endif - -/* From winternl.h */ - -/* If WDK is not installed and not using MinGW, provide the needed definitions - */ -typedef LONG NTSTATUS; - -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - }; - - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -typedef VOID(NTAPI *PIO_APC_ROUTINE)(PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG Reserved); - -/* From ntstatus.h */ -# define STATUS_SUCCESS ((NTSTATUS)0x00000000) -# ifndef STATUS_PENDING -# define STATUS_PENDING ((NTSTATUS)0x00000103L) -# endif -# define STATUS_CANCELLED ((NTSTATUS)0xC0000120L) -# define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L) - -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - LPCWSTR Buffer; -} UNICODE_STRING, *PUNICODE_STRING; - -typedef struct _OBJECT_ATTRIBUTES { - ULONG Length; - HANDLE RootDirectory; - PUNICODE_STRING ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; - -# ifndef FILE_OPEN -# define FILE_OPEN 0x00000001UL -# endif - -/* Not sure what headers might have these */ -# define IOCTL_AFD_POLL 0x00012024 - -# define AFD_POLL_RECEIVE_BIT 0 -# define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT) -# define AFD_POLL_RECEIVE_EXPEDITED_BIT 1 -# define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT) -# define AFD_POLL_SEND_BIT 2 -# define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT) -# define AFD_POLL_DISCONNECT_BIT 3 -# define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT) -# define AFD_POLL_ABORT_BIT 4 -# define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT) -# define AFD_POLL_LOCAL_CLOSE_BIT 5 -# define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT) -# define AFD_POLL_CONNECT_BIT 6 -# define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT) -# define AFD_POLL_ACCEPT_BIT 7 -# define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT) -# define AFD_POLL_CONNECT_FAIL_BIT 8 -# define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT) -# define AFD_POLL_QOS_BIT 9 -# define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT) -# define AFD_POLL_GROUP_QOS_BIT 10 -# define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT) - -# define AFD_NUM_POLL_EVENTS 11 -# define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1) - -typedef struct _AFD_POLL_HANDLE_INFO { - HANDLE Handle; - ULONG Events; - NTSTATUS Status; -} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO; - -typedef struct _AFD_POLL_INFO { - LARGE_INTEGER Timeout; - ULONG NumberOfHandles; - ULONG Exclusive; - AFD_POLL_HANDLE_INFO Handles[1]; -} AFD_POLL_INFO, *PAFD_POLL_INFO; - -/* Prototypes for dynamically loaded functions from ntdll.dll */ -typedef NTSTATUS(NTAPI *NtCancelIoFileEx_t)(HANDLE FileHandle, - PIO_STATUS_BLOCK IoRequestToCancel, - PIO_STATUS_BLOCK IoStatusBlock); -typedef NTSTATUS(NTAPI *NtDeviceIoControlFile_t)( - HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode, PVOID InputBuffer, - ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength); - -typedef NTSTATUS(NTAPI *NtCreateFile_t)( - PHANDLE FileHandle, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, - PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, - ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength); - -/* On UWP/Windows Store, these definitions aren't there for some reason */ -# ifndef SIO_BSP_HANDLE_POLL -# define SIO_BSP_HANDLE_POLL 0x4800001D -# endif - -# ifndef SIO_BASE_HANDLE -# define SIO_BASE_HANDLE 0x48000022 -# endif - -# ifndef HANDLE_FLAG_INHERIT -# define HANDLE_FLAG_INHERIT 0x00000001 -# endif - -#endif /* _WIN32 */ - -#endif /* __ARES_EVENT_WIN32_H */ diff --git a/vendor/c-ares/src/lib/include/ares_array.h b/vendor/c-ares/src/lib/include/ares_array.h deleted file mode 100644 index f1a2e155f..000000000 --- a/vendor/c-ares/src/lib/include/ares_array.h +++ /dev/null @@ -1,276 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__ARRAY_H -#define __ARES__ARRAY_H - -#include "ares.h" - -/*! \addtogroup ares_array Array Data Structure - * - * This is an array with helpers. It is meant to have as little overhead - * as possible over direct array management by applications but to provide - * safety and some optimization features. It can also return the array in - * native form once all manipulation has been performed. - * - * @{ - */ - -struct ares_array; - -/*! Opaque data structure for array */ -typedef struct ares_array ares_array_t; - -/*! Callback to free user-defined member data - * - * \param[in] data pointer to member of array to be destroyed. The pointer - * itself must not be destroyed, just the data it contains. - */ -typedef void (*ares_array_destructor_t)(void *data); - -/*! Callback to compare two array elements used for sorting - * - * \param[in] data1 array member 1 - * \param[in] data2 array member 2 - * \return < 0 if data1 < data2, > 0 if data1 > data2, 0 if data1 == data2 - */ -typedef int (*ares_array_cmp_t)(const void *data1, const void *data2); - -/*! Create an array object - * - * NOTE: members of the array are typically going to be an going to be a - * struct with compiler/ABI specific padding to ensure proper alignment. - * Care needs to be taken if using primitive types, especially floating - * point numbers which size may not indicate the required alignment. - * For example, a double may be 80 bits (10 bytes), but required - * alignment of 16 bytes. In such a case, a member_size of 16 would be - * required to be used. - * - * \param[in] destruct Optional. Destructor to call on a removed member - * \param[in] member_size Size of array member, usually determined using - * sizeof() for the member such as a struct. - * - * \return array object or NULL on out of memory - */ -CARES_EXTERN ares_array_t *ares_array_create(size_t member_size, - ares_array_destructor_t destruct); - - -/*! Request the array be at least the requested size. Useful if the desired - * array size is known prior to populating the array to prevent reallocations. - * - * \param[in] arr Initialized array object. - * \param[in] size Minimum number of members - * \return ARES_SUCCESS on success, ARES_EFORMERR on misuse, - * ARES_ENOMEM on out of memory */ -CARES_EXTERN ares_status_t ares_array_set_size(ares_array_t *arr, size_t size); - -/*! Sort the array using the given comparison function. This is not - * persistent, any future elements inserted will not maintain this sort. - * - * \param[in] arr Initialized array object. - * \param[in] cb Sort callback - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_array_sort(ares_array_t *arr, - ares_array_cmp_t cmp); - -/*! Destroy an array object. If a destructor is set, will be called on each - * member of the array. - * - * \param[in] arr Initialized array object. - */ -CARES_EXTERN void ares_array_destroy(ares_array_t *arr); - -/*! Retrieve the array in the native format. This will also destroy the - * container. It is the responsibility of the caller to free the returned - * pointer and also any data within each array element. - * - * \param[in] arr Initialized array object - * \param[out] num_members the number of members in the returned array - * \return pointer to native array on success, NULL on failure. - */ -CARES_EXTERN void *ares_array_finish(ares_array_t *arr, size_t *num_members); - -/*! Retrieve the number of members in the array - * - * \param[in] arr Initialized array object. - * \return numbrer of members - */ -CARES_EXTERN size_t ares_array_len(const ares_array_t *arr); - -/*! Insert a new array member at the given index - * - * \param[out] elem_ptr Optional. Pointer to the returned array element. - * \param[in] arr Initialized array object. - * \param[in] idx Index in array to place new element, will shift any - * elements down that exist after this point. - * \return ARES_SUCCESS on success, ARES_EFORMERR on bad index, - * ARES_ENOMEM on out of memory. - */ -CARES_EXTERN ares_status_t ares_array_insert_at(void **elem_ptr, - ares_array_t *arr, size_t idx); - -/*! Insert a new array member at the end of the array - * - * \param[out] elem_ptr Optional. Pointer to the returned array element. - * \param[in] arr Initialized array object. - * \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory. - */ -CARES_EXTERN ares_status_t ares_array_insert_last(void **elem_ptr, - ares_array_t *arr); - -/*! Insert a new array member at the beginning of the array - * - * \param[out] elem_ptr Optional. Pointer to the returned array element. - * \param[in] arr Initialized array object. - * \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory. - */ -CARES_EXTERN ares_status_t ares_array_insert_first(void **elem_ptr, - ares_array_t *arr); - - -/*! Insert a new array member at the given index and copy the data pointed - * to by the data pointer into the array. This will copy member_size bytes - * from the provided pointer, this may not be safe for some data types - * that may have a smaller size than the provided member_size which includes - * padding as discussed in ares_array_create(). - * - * \param[in] arr Initialized array object. - * \param[in] idx Index in array to place new element, will shift any - * elements down that exist after this point. - * \param[in] data_ptr Pointer to data to copy into array. - * \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data - * ptr, ARES_ENOMEM on out of memory. - */ -CARES_EXTERN ares_status_t ares_array_insertdata_at(ares_array_t *arr, - size_t idx, - const void *data_ptr); - -/*! Insert a new array member at the end of the array and copy the data pointed - * to by the data pointer into the array. This will copy member_size bytes - * from the provided pointer, this may not be safe for some data types - * that may have a smaller size than the provided member_size which includes - * padding as discussed in ares_array_create(). - * - * \param[in] arr Initialized array object. - * \param[in] data_ptr Pointer to data to copy into array. - * \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data - * ptr, ARES_ENOMEM on out of memory. - */ -CARES_EXTERN ares_status_t ares_array_insertdata_last(ares_array_t *arr, - const void *data_ptr); - -/*! Insert a new array member at the beginning of the array and copy the data - * pointed to by the data pointer into the array. This will copy member_size - * bytes from the provided pointer, this may not be safe for some data types - * that may have a smaller size than the provided member_size which includes - * padding as discussed in ares_array_create(). - * - * \param[in] arr Initialized array object. - * \param[in] data_ptr Pointer to data to copy into array. - * \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data - * ptr, ARES_ENOMEM on out of memory. - */ -CARES_EXTERN ares_status_t ares_array_insertdata_first(ares_array_t *arr, - const void *data_ptr); - -/*! Fetch a pointer to the given element in the array - * \param[in] array Initialized array object - * \param[in] idx Index to fetch - * \return pointer on success, NULL on failure */ -CARES_EXTERN void *ares_array_at(ares_array_t *arr, size_t idx); - -/*! Fetch a pointer to the first element in the array - * \param[in] array Initialized array object - * \return pointer on success, NULL on failure */ -CARES_EXTERN void *ares_array_first(ares_array_t *arr); - -/*! Fetch a pointer to the last element in the array - * \param[in] array Initialized array object - * \return pointer on success, NULL on failure */ -CARES_EXTERN void *ares_array_last(ares_array_t *arr); - -/*! Fetch a constant pointer to the given element in the array - * \param[in] array Initialized array object - * \param[in] idx Index to fetch - * \return pointer on success, NULL on failure */ -CARES_EXTERN const void *ares_array_at_const(const ares_array_t *arr, - size_t idx); - -/*! Fetch a constant pointer to the first element in the array - * \param[in] array Initialized array object - * \return pointer on success, NULL on failure */ -CARES_EXTERN const void *ares_array_first_const(const ares_array_t *arr); - -/*! Fetch a constant pointer to the last element in the array - * \param[in] array Initialized array object - * \return pointer on success, NULL on failure */ -CARES_EXTERN const void *ares_array_last_const(const ares_array_t *arr); - -/*! Claim the data from the specified array index, copying it to the buffer - * provided by the caller. The index specified in the array will then be - * removed (without calling any possible destructor) - * - * \param[in,out] dest Optional. Buffer to hold array member. Pass NULL - * if not needed. This could leak memory if array - * member needs destructor if not provided. - * \param[in] dest_size Size of buffer provided, used as a sanity check. - * Must match member_size provided to - * ares_array_create() if dest_size specified. - * \param[in] arr Initialized array object - * \param[in] idx Index to claim - * \return ARES_SUCCESS on success, ARES_EFORMERR on usage failure. - */ -CARES_EXTERN ares_status_t ares_array_claim_at(void *dest, size_t dest_size, - ares_array_t *arr, size_t idx); - -/*! Remove the member at the specified array index. The destructor will be - * called. - * - * \param[in] arr Initialized array object - * \param[in] idx Index to remove - * \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use - */ -CARES_EXTERN ares_status_t ares_array_remove_at(ares_array_t *arr, size_t idx); - -/*! Remove the first member of the array. - * - * \param[in] arr Initialized array object - * \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use - */ -CARES_EXTERN ares_status_t ares_array_remove_first(ares_array_t *arr); - -/*! Remove the last member of the array. - * - * \param[in] arr Initialized array object - * \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use - */ -CARES_EXTERN ares_status_t ares_array_remove_last(ares_array_t *arr); - - -/*! @} */ - -#endif /* __ARES__ARRAY_H */ diff --git a/vendor/c-ares/src/lib/include/ares_buf.h b/vendor/c-ares/src/lib/include/ares_buf.h deleted file mode 100644 index 10d29eaf8..000000000 --- a/vendor/c-ares/src/lib/include/ares_buf.h +++ /dev/null @@ -1,732 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__BUF_H -#define __ARES__BUF_H - -#include "ares.h" -#include "ares_array.h" - -/*! \addtogroup ares_buf Safe Data Builder and buffer - * - * This is a buffer building and parsing framework with a focus on security over - * performance. All data to be read from the buffer will perform explicit length - * validation and return a success/fail result. There are also various helpers - * for writing data to the buffer which dynamically grows. - * - * All operations that fetch or consume data from the buffer will move forward - * the internal pointer, thus marking the data as processed which may no longer - * be accessible after certain operations (such as append). - * - * The helpers for this object are meant to be added as needed. If you can't - * find it, write it! - * - * @{ - */ -struct ares_buf; - -/*! Opaque data type for generic hash table implementation */ -typedef struct ares_buf ares_buf_t; - -/*! Create a new buffer object that dynamically allocates buffers for data. - * - * \return initialized buffer object or NULL if out of memory. - */ -CARES_EXTERN ares_buf_t *ares_buf_create(void); - -/*! Create a new buffer object that uses a user-provided data pointer. The - * data provided will not be manipulated, and cannot be appended to. This - * is strictly used for parsing. - * - * \param[in] data Data to provide to buffer, must not be NULL. - * \param[in] data_len Size of buffer provided, must be > 0 - * - * \return initialized buffer object or NULL if out of memory or misuse. - */ -CARES_EXTERN ares_buf_t *ares_buf_create_const(const unsigned char *data, - size_t data_len); - - -/*! Destroy an initialized buffer object. - * - * \param[in] buf Initialized buf object - */ -CARES_EXTERN void ares_buf_destroy(ares_buf_t *buf); - - -/*! Append multiple bytes to a dynamic buffer object - * - * \param[in] buf Initialized buffer object - * \param[in] data Data to copy to buffer object - * \param[in] data_len Length of data to copy to buffer object. - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_append(ares_buf_t *buf, - const unsigned char *data, - size_t data_len); - -/*! Append a single byte to the dynamic buffer object - * - * \param[in] buf Initialized buffer object - * \param[in] b Single byte to append to buffer object. - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_append_byte(ares_buf_t *buf, - unsigned char b); - -/*! Append a null-terminated string to the dynamic buffer object - * - * \param[in] buf Initialized buffer object - * \param[in] str String to append to buffer object. - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_append_str(ares_buf_t *buf, - const char *str); - -/*! Append a 16bit Big Endian number to the buffer. - * - * \param[in] buf Initialized buffer object - * \param[out] u16 16bit integer - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_append_be16(ares_buf_t *buf, - unsigned short u16); - -/*! Append a 32bit Big Endian number to the buffer. - * - * \param[in] buf Initialized buffer object - * \param[out] u32 32bit integer - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_append_be32(ares_buf_t *buf, - unsigned int u32); - -/*! Append a number in ASCII decimal form. - * - * \param[in] buf Initialized buffer object - * \param[in] num Number to print - * \param[in] len Length to output, use 0 for no padding - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_buf_append_num_dec(ares_buf_t *buf, size_t num, - size_t len); - -/*! Append a number in ASCII hexadecimal form. - * - * \param[in] buf Initialized buffer object - * \param[in] num Number to print - * \param[in] len Length to output, use 0 for no padding - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_buf_append_num_hex(ares_buf_t *buf, size_t num, - size_t len); - -/*! Sets the current buffer length. This *may* be used if there is a need to - * override a prior position in the buffer, such as if there is a length - * prefix that isn't easily predictable, and you must go back and overwrite - * that position. - * - * Only valid on non-const buffers. Length provided must not exceed current - * allocated buffer size, but otherwise there are very few protections on - * this function. Use cautiously. - * - * \param[in] buf Initialized buffer object - * \param[in] len Length to set - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_set_length(ares_buf_t *buf, size_t len); - - -/*! Start a dynamic append operation that returns a buffer suitable for - * writing. A desired minimum length is passed in, and the actual allocated - * buffer size is returned which may be greater than the requested size. - * No operation other than ares_buf_append_finish() is allowed on the - * buffer after this request. - * - * \param[in] buf Initialized buffer object - * \param[in,out] len Desired non-zero length passed in, actual buffer size - * returned. - * \return Pointer to writable buffer or NULL on failure (usage, out of mem) - */ -CARES_EXTERN unsigned char *ares_buf_append_start(ares_buf_t *buf, size_t *len); - -/*! Finish a dynamic append operation. Called after - * ares_buf_append_start() once desired data is written. - * - * \param[in] buf Initialized buffer object. - * \param[in] len Length of data written. May be zero to terminate - * operation. Must not be greater than returned from - * ares_buf_append_start(). - */ -CARES_EXTERN void ares_buf_append_finish(ares_buf_t *buf, size_t len); - -/*! Write the data provided to the buffer in a hexdump format. - * - * \param[in] buf Initialized buffer object. - * \param[in] data Data to hex dump - * \param[in] len Length of data to hexdump - * \return ARES_SUCCESS on success. - */ -CARES_EXTERN ares_status_t ares_buf_hexdump(ares_buf_t *buf, - const unsigned char *data, - size_t len); - -/*! Clean up ares_buf_t and return allocated pointer to unprocessed data. It - * is the responsibility of the caller to ares_free() the returned buffer. - * The passed in buf parameter is invalidated by this call. - * - * \param[in] buf Initialized buffer object. Can not be a "const" buffer. - * \param[out] len Length of data returned - * \return pointer to unprocessed data (may be zero length) or NULL on error. - */ -CARES_EXTERN unsigned char *ares_buf_finish_bin(ares_buf_t *buf, size_t *len); - -/*! Clean up ares_buf_t and return allocated pointer to unprocessed data and - * return it as a string (null terminated). It is the responsibility of the - * caller to ares_free() the returned buffer. The passed in buf parameter is - * invalidated by this call. - * - * This function in no way validates the data in this buffer is actually - * a string, that characters are printable, or that there aren't multiple - * NULL terminators. It is assumed that the caller will either validate that - * themselves or has built this buffer with only a valid character set. - * - * \param[in] buf Initialized buffer object. Can not be a "const" buffer. - * \param[out] len Optional. Length of data returned, or NULL if not needed. - * \return pointer to unprocessed data or NULL on error. - */ -CARES_EXTERN char *ares_buf_finish_str(ares_buf_t *buf, size_t *len); - -/*! Replace the given search byte sequence with the replacement byte sequence. - * This is only valid for allocated buffers, not const buffers. Will replace - * all byte sequences starting at the current offset to the end of the buffer. - * - * \param[in] buf Initialized buffer object. Can not be a "const" buffer. - * \param[in] srch Search byte sequence, must not be NULL. - * \param[in] srch_size Size of byte sequence, must not be zero. - * \param[in] rplc Byte sequence to use as replacement. May be NULL if - * rplc_size is zero. - * \param[in] rplc_size Size of replacement byte sequence, may be 0. - * \return ARES_SUCCESS on success, otherwise on may return failure only on - * memory allocation failure or misuse. Will not return indication - * if any replacements occurred - */ -CARES_EXTERN ares_status_t ares_buf_replace(ares_buf_t *buf, - const unsigned char *srch, - size_t srch_size, - const unsigned char *rplc, - size_t rplc_size); - -/*! Tag a position to save in the buffer in case parsing needs to rollback, - * such as if insufficient data is available, but more data may be added in - * the future. Only a single tag can be set per buffer object. Setting a - * tag will override any pre-existing tag. - * - * \param[in] buf Initialized buffer object - */ -CARES_EXTERN void ares_buf_tag(ares_buf_t *buf); - -/*! Rollback to a tagged position. Will automatically clear the tag. - * - * \param[in] buf Initialized buffer object - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_tag_rollback(ares_buf_t *buf); - -/*! Clear the tagged position without rolling back. You should do this any - * time a tag is no longer needed as future append operations can reclaim - * buffer space. - * - * \param[in] buf Initialized buffer object - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_tag_clear(ares_buf_t *buf); - -/*! Fetch the buffer and length of data starting from the tagged position up - * to the _current_ position. It will not unset the tagged position. The - * data may be invalidated by any future ares_buf_*() calls. - * - * \param[in] buf Initialized buffer object - * \param[out] len Length between tag and current offset in buffer - * \return NULL on failure (such as no tag), otherwise pointer to start of - * buffer - */ -CARES_EXTERN const unsigned char *ares_buf_tag_fetch(const ares_buf_t *buf, - size_t *len); - -/*! Get the length of the current tag offset to the current position. - * - * \param[in] buf Initialized buffer object - * \return length - */ -CARES_EXTERN size_t ares_buf_tag_length(const ares_buf_t *buf); - -/*! Fetch the bytes starting from the tagged position up to the _current_ - * position using the provided buffer. It will not unset the tagged position. - * - * \param[in] buf Initialized buffer object - * \param[in,out] bytes Buffer to hold data - * \param[in,out] len On input, buffer size, on output, bytes place in - * buffer. - * \return ARES_SUCCESS if fetched, ARES_EFORMERR if insufficient buffer size - */ -CARES_EXTERN ares_status_t ares_buf_tag_fetch_bytes(const ares_buf_t *buf, - unsigned char *bytes, - size_t *len); - -/*! Fetch the bytes starting from the tagged position up to the _current_ - * position as a NULL-terminated string using the provided buffer. The data - * is validated to be ASCII-printable data. It will not unset the tagged - * position. - * - * \param[in] buf Initialized buffer object - * \param[in,out] str Buffer to hold data - * \param[in] len buffer size - * \return ARES_SUCCESS if fetched, ARES_EFORMERR if insufficient buffer size, - * ARES_EBADSTR if not printable ASCII - */ -CARES_EXTERN ares_status_t ares_buf_tag_fetch_string(const ares_buf_t *buf, - char *str, size_t len); - -/*! Fetch the bytes starting from the tagged position up to the _current_ - * position as a NULL-terminated string and placed into a newly allocated - * buffer. The data is validated to be ASCII-printable data. It will not - * unset the tagged position. - * - * \param[in] buf Initialized buffer object - * \param[out] str New buffer to hold output, free with ares_free() - * - * \return ARES_SUCCESS if fetched, ARES_EFORMERR if insufficient buffer size, - * ARES_EBADSTR if not printable ASCII - */ -CARES_EXTERN ares_status_t ares_buf_tag_fetch_strdup(const ares_buf_t *buf, - char **str); - -/*! Fetch the bytes starting from the tagged position up to the _current_ - * position as const buffer. Care must be taken to not append or destroy the - * passed in buffer until the newly fetched buffer is no longer needed since - * it points to memory inside the passed in buffer which could be invalidated. - * - * \param[in] buf Initialized buffer object - * \param[out] newbuf New const buffer object, must be destroyed when done. - - * \return ARES_SUCCESS if fetched - */ -CARES_EXTERN ares_status_t ares_buf_tag_fetch_constbuf(const ares_buf_t *buf, - ares_buf_t **newbuf); - -/*! Consume the given number of bytes without reading them. - * - * \param[in] buf Initialized buffer object - * \param[in] len Length to consume - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_consume(ares_buf_t *buf, size_t len); - -/*! Fetch a 16bit Big Endian number from the buffer. - * - * \param[in] buf Initialized buffer object - * \param[out] u16 Buffer to hold 16bit integer - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_fetch_be16(ares_buf_t *buf, - unsigned short *u16); - -/*! Fetch a 32bit Big Endian number from the buffer. - * - * \param[in] buf Initialized buffer object - * \param[out] u32 Buffer to hold 32bit integer - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_fetch_be32(ares_buf_t *buf, - unsigned int *u32); - - -/*! Fetch the requested number of bytes into the provided buffer - * - * \param[in] buf Initialized buffer object - * \param[out] bytes Buffer to hold data - * \param[in] len Requested number of bytes (must be > 0) - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_fetch_bytes(ares_buf_t *buf, - unsigned char *bytes, - size_t len); - - -/*! Fetch the requested number of bytes and return a new buffer that must be - * ares_free()'d by the caller. - * - * \param[in] buf Initialized buffer object - * \param[in] len Requested number of bytes (must be > 0) - * \param[in] null_term Even though this is considered binary data, the user - * knows it may be a vald string, so add a null - * terminator. - * \param[out] bytes Pointer passed by reference. Will be allocated. - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_fetch_bytes_dup(ares_buf_t *buf, size_t len, - ares_bool_t null_term, - unsigned char **bytes); - -/*! Fetch the requested number of bytes and place them into the provided - * dest buffer object. - * - * \param[in] buf Initialized buffer object - * \param[out] dest Buffer object to append bytes. - * \param[in] len Requested number of bytes (must be > 0) - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_fetch_bytes_into_buf(ares_buf_t *buf, - ares_buf_t *dest, - size_t len); - -/*! Fetch the requested number of bytes and return a new buffer that must be - * ares_free()'d by the caller. The returned buffer is a null terminated - * string. The data is validated to be ASCII-printable. - * - * \param[in] buf Initialized buffer object - * \param[in] len Requested number of bytes (must be > 0) - * \param[out] str Pointer passed by reference. Will be allocated. - * \return ARES_SUCCESS or one of the c-ares error codes - */ -CARES_EXTERN ares_status_t ares_buf_fetch_str_dup(ares_buf_t *buf, size_t len, - char **str); - -/*! Consume whitespace characters (0x09, 0x0B, 0x0C, 0x0D, 0x20, and optionally - * 0x0A). - * - * \param[in] buf Initialized buffer object - * \param[in] include_linefeed ARES_TRUE to include consuming 0x0A, - * ARES_FALSE otherwise. - * \return number of whitespace characters consumed - */ -CARES_EXTERN size_t ares_buf_consume_whitespace(ares_buf_t *buf, - ares_bool_t include_linefeed); - - -/*! Consume any non-whitespace character (anything other than 0x09, 0x0B, 0x0C, - * 0x0D, 0x20, and 0x0A). - * - * \param[in] buf Initialized buffer object - * \return number of characters consumed - */ -CARES_EXTERN size_t ares_buf_consume_nonwhitespace(ares_buf_t *buf); - - -/*! Consume until a character in the character set provided is reached. Does - * not include the character from the charset at the end. - * - * \param[in] buf Initialized buffer object - * \param[in] charset character set - * \param[in] len length of character set - * \param[in] require_charset require we find a character from the charset. - * if ARES_FALSE it will simply consume the - * rest of the buffer. If ARES_TRUE will return - * SIZE_MAX if not found. - * \return number of characters consumed - */ -CARES_EXTERN size_t ares_buf_consume_until_charset(ares_buf_t *buf, - const unsigned char *charset, - size_t len, - ares_bool_t require_charset); - - -/*! Consume until a sequence of bytes is encountered. Does not include the - * sequence of characters itself. - * - * \param[in] buf Initialized buffer object - * \param[in] seq sequence of bytes - * \param[in] len length of sequence - * \param[in] require_charset require we find the sequence. - * if ARES_FALSE it will simply consume the - * rest of the buffer. If ARES_TRUE will return - * SIZE_MAX if not found. - * \return number of characters consumed - */ -CARES_EXTERN size_t ares_buf_consume_until_seq(ares_buf_t *buf, - const unsigned char *seq, - size_t len, - ares_bool_t require_seq); - -/*! Consume while the characters match the characters in the provided set. - * - * \param[in] buf Initialized buffer object - * \param[in] charset character set - * \param[in] len length of character set - * \return number of characters consumed - */ -CARES_EXTERN size_t ares_buf_consume_charset(ares_buf_t *buf, - const unsigned char *charset, - size_t len); - - -/*! Consume from the current position until the end of the line, and optionally - * the end of line character (0x0A) itself. - * - * \param[in] buf Initialized buffer object - * \param[in] include_linefeed ARES_TRUE to include consuming 0x0A, - * ARES_FALSE otherwise. - * \return number of characters consumed - */ -CARES_EXTERN size_t ares_buf_consume_line(ares_buf_t *buf, - ares_bool_t include_linefeed); - -typedef enum { - /*! No flags */ - ARES_BUF_SPLIT_NONE = 0, - /*! The delimiter will be the first character in the buffer, except the - * first buffer since the start doesn't have a delimiter. This option is - * incompatible with ARES_BUF_SPLIT_LTRIM since the delimiter is always - * the first character. - */ - ARES_BUF_SPLIT_KEEP_DELIMS = 1 << 0, - /*! Allow blank sections, by default blank sections are not emitted. If using - * ARES_BUF_SPLIT_KEEP_DELIMS, the delimiter is not counted as part - * of the section */ - ARES_BUF_SPLIT_ALLOW_BLANK = 1 << 1, - /*! Remove duplicate entries */ - ARES_BUF_SPLIT_NO_DUPLICATES = 1 << 2, - /*! Perform case-insensitive matching when comparing values */ - ARES_BUF_SPLIT_CASE_INSENSITIVE = 1 << 3, - /*! Trim leading whitespace from buffer */ - ARES_BUF_SPLIT_LTRIM = 1 << 4, - /*! Trim trailing whitespace from buffer */ - ARES_BUF_SPLIT_RTRIM = 1 << 5, - /*! Trim leading and trailing whitespace from buffer */ - ARES_BUF_SPLIT_TRIM = (ARES_BUF_SPLIT_LTRIM | ARES_BUF_SPLIT_RTRIM) -} ares_buf_split_t; - -/*! Split the provided buffer into multiple sub-buffers stored in the variable - * pointed to by the linked list. The sub buffers are const buffers pointing - * into the buf provided. - * - * \param[in] buf Initialized buffer object - * \param[in] delims Possible delimiters - * \param[in] delims_len Length of possible delimiters - * \param[in] flags One more more flags - * \param[in] max_sections Maximum number of sections. Use 0 for - * unlimited. Useful for splitting key/value - * pairs where the delimiter may be a valid - * character in the value. A value of 1 would - * have little usefulness and would effectively - * ignore the delimiter itself. - * \param[out] arr Result. Depending on flags, this may be a - * valid array with no elements. Use - * ares_array_destroy() to free the memory which - * will also free the contained ares_buf_t * - * objects. Each buf object returned by - * ares_array_at() or similar is a pointer to - * an ares_buf_t * object, meaning you need to - * accept it as "ares_buf_t **" then dereference. - * \return ARES_SUCCESS on success, or error like ARES_ENOMEM. - */ -CARES_EXTERN ares_status_t ares_buf_split( - ares_buf_t *buf, const unsigned char *delims, size_t delims_len, - ares_buf_split_t flags, size_t max_sections, ares_array_t **arr); - -/*! Split the provided buffer into an ares_array_t of C strings. - * - * \param[in] buf Initialized buffer object - * \param[in] delims Possible delimiters - * \param[in] delims_len Length of possible delimiters - * \param[in] flags One more more flags - * \param[in] max_sections Maximum number of sections. Use 0 for - * unlimited. Useful for splitting key/value - * pairs where the delimiter may be a valid - * character in the value. A value of 1 would - * have little usefulness and would effectively - * ignore the delimiter itself. - * \param[out] arr Array of strings. Free using - * ares_array_destroy(). - * \return ARES_SUCCESS on success, or error like ARES_ENOMEM. - */ -CARES_EXTERN ares_status_t ares_buf_split_str_array( - ares_buf_t *buf, const unsigned char *delims, size_t delims_len, - ares_buf_split_t flags, size_t max_sections, ares_array_t **arr); - -/*! Split the provided buffer into a C array of C strings. - * - * \param[in] buf Initialized buffer object - * \param[in] delims Possible delimiters - * \param[in] delims_len Length of possible delimiters - * \param[in] flags One more more flags - * \param[in] max_sections Maximum number of sections. Use 0 for - * unlimited. Useful for splitting key/value - * pairs where the delimiter may be a valid - * character in the value. A value of 1 would - * have little usefulness and would effectively - * ignore the delimiter itself. - * \param[out] strs Array of strings. Free using - * ares_free_array(strs, nstrs, ares_free) - * \param[out] nstrs Number of elements in the array. - * \return ARES_SUCCESS on success, or error like ARES_ENOMEM. - */ -CARES_EXTERN ares_status_t ares_buf_split_str( - ares_buf_t *buf, const unsigned char *delims, size_t delims_len, - ares_buf_split_t flags, size_t max_sections, char ***strs, size_t *nstrs); - -/*! Check the unprocessed buffer to see if it begins with the sequence of - * characters provided. - * - * \param[in] buf Initialized buffer object - * \param[in] data Bytes of data to compare. - * \param[in] data_len Length of data to compare. - * \return ARES_TRUE on match, ARES_FALSE otherwise. - */ -CARES_EXTERN ares_bool_t ares_buf_begins_with(const ares_buf_t *buf, - const unsigned char *data, - size_t data_len); - - -/*! Size of unprocessed remaining data length - * - * \param[in] buf Initialized buffer object - * \return length remaining - */ -CARES_EXTERN size_t ares_buf_len(const ares_buf_t *buf); - -/*! Retrieve a pointer to the currently unprocessed data. Generally this isn't - * recommended to be used in practice. The returned pointer may be invalidated - * by any future ares_buf_*() calls. - * - * \param[in] buf Initialized buffer object - * \param[out] len Length of available data - * \return Pointer to buffer of unprocessed data - */ -CARES_EXTERN const unsigned char *ares_buf_peek(const ares_buf_t *buf, - size_t *len); - -/*! Retrieve the next byte in the buffer without moving forward. - * - * \param[in] buf Initialized buffer object - * \param[out] b Single byte - * \return \return ARES_SUCCESS on success, or error - */ -CARES_EXTERN ares_status_t ares_buf_peek_byte(const ares_buf_t *buf, - unsigned char *b); - -/*! Wipe any processed data from the beginning of the buffer. This will - * move any remaining data to the front of the internally allocated buffer. - * - * Can not be used on const buffer objects. - * - * Typically not needed to call, as any new append operation will automatically - * call this function if there is insufficient space to append the data in - * order to try to avoid another memory allocation. - * - * It may be useful to call in order to ensure the current message being - * processed is in the beginning of the buffer if there is an intent to use - * ares_buf_set_position() and ares_buf_get_position() as may be necessary - * when processing DNS compressed names. - * - * If there is an active tag, it will NOT clear the tag, it will use the tag - * as the start of the unprocessed data rather than the current offset. If - * a prior tag is no longer needed, may be wise to call ares_buf_tag_clear(). - * - * \param[in] buf Initialized buffer object - */ -CARES_EXTERN void ares_buf_reclaim(ares_buf_t *buf); - -/*! Set the current offset within the internal buffer. - * - * Typically this should not be used, if possible, use the ares_buf_tag*() - * operations instead. - * - * One exception is DNS name compression which may backwards reference to - * an index in the message. It may be necessary in such a case to call - * ares_buf_reclaim() if using a dynamic (non-const) buffer before processing - * such a message. - * - * \param[in] buf Initialized buffer object - * \param[in] idx Index to set position - * \return ARES_SUCCESS if valid index - */ -CARES_EXTERN ares_status_t ares_buf_set_position(ares_buf_t *buf, size_t idx); - -/*! Get the current offset within the internal buffer. - * - * Typically this should not be used, if possible, use the ares_buf_tag*() - * operations instead. - * - * This can be used to get the current position, useful for saving if a - * jump via ares_buf_set_position() is performed and need to restore the - * current position for future operations. - * - * \param[in] buf Initialized buffer object - * \return index of current position - */ -CARES_EXTERN size_t ares_buf_get_position(const ares_buf_t *buf); - -/*! Parse a character-string as defined in RFC1035, as a null-terminated - * string. - * - * \param[in] buf initialized buffer object - * \param[in] remaining_len maximum length that should be used for parsing - * the string, this is often less than the remaining - * buffer and is based on the RR record length. - * \param[out] name Pointer passed by reference to be filled in with - * allocated string of the parsed that must be - * ares_free()'d by the caller. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_buf_parse_dns_str(ares_buf_t *buf, - size_t remaining_len, - char **name); - -/*! Parse a character-string as defined in RFC1035, as binary, however for - * convenience this does guarantee a NULL terminator (that is not included - * in the returned length). - * - * \param[in] buf initialized buffer object - * \param[in] remaining_len maximum length that should be used for parsing - * the string, this is often less than the remaining - * buffer and is based on the RR record length. - * \param[out] bin Pointer passed by reference to be filled in with - * allocated string of the parsed that must be - * ares_free()'d by the caller. - * \param[out] bin_len Length of returned string. - * \return ARES_SUCCESS on success - */ -CARES_EXTERN ares_status_t ares_buf_parse_dns_binstr(ares_buf_t *buf, - size_t remaining_len, - unsigned char **bin, - size_t *bin_len); - -/*! Load data from specified file path into provided buffer. The entire file - * is loaded into memory. - * - * \param[in] filename complete path to file - * \param[in,out] buf Initialized (non-const) buffer object to load data - * into - * \return ARES_ENOTFOUND if file not found, ARES_EFILE if issues reading - * file, ARES_ENOMEM if out of memory, ARES_SUCCESS on success. - */ -CARES_EXTERN ares_status_t ares_buf_load_file(const char *filename, - ares_buf_t *buf); - -/*! @} */ - -#endif /* __ARES__BUF_H */ diff --git a/vendor/c-ares/src/lib/include/ares_htable_asvp.h b/vendor/c-ares/src/lib/include/ares_htable_asvp.h deleted file mode 100644 index 89a99fc9e..000000000 --- a/vendor/c-ares/src/lib/include/ares_htable_asvp.h +++ /dev/null @@ -1,130 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__HTABLE_ASVP_H -#define __ARES__HTABLE_ASVP_H - -/*! \addtogroup ares_htable_asvp HashTable with ares_socket_t Key and - * void pointer Value - * - * This data structure wraps the base ares_htable data structure in order to - * split the key and value data types as ares_socket_t and void pointer, - * respectively. - * - * Average time complexity: - * - Insert: O(1) - * - Search: O(1) - * - Delete: O(1) - * - * @{ - */ - -struct ares_htable_asvp; - -/*! Opaque data type for ares_socket_t key, void pointer hash table - * implementation */ -typedef struct ares_htable_asvp ares_htable_asvp_t; - -/*! Callback to free value stored in hashtable - * - * \param[in] val user-supplied value - */ -typedef void (*ares_htable_asvp_val_free_t)(void *val); - -/*! Destroy hashtable - * - * \param[in] htable Initialized hashtable - */ -CARES_EXTERN void ares_htable_asvp_destroy(ares_htable_asvp_t *htable); - -/*! Create size_t key, void pointer value hash table - * - * \param[in] val_free Optional. Call back to free user-supplied value. If - * NULL it is expected the caller will clean up any user - * supplied values. - */ -CARES_EXTERN ares_htable_asvp_t * - ares_htable_asvp_create(ares_htable_asvp_val_free_t val_free); - -/*! Retrieve an array of keys from the hashtable. - * - * \param[in] htable Initialized hashtable - * \param[out] num Count of returned keys - * \return Array of keys in the hashtable. Must be free'd with ares_free(). - */ -CARES_EXTERN ares_socket_t * - ares_htable_asvp_keys(const ares_htable_asvp_t *htable, size_t *num); - - -/*! Insert key/value into hash table - * - * \param[in] htable Initialized hash table - * \param[in] key key to associate with value - * \param[in] val value to store (takes ownership). May be NULL. - * \return ARES_TRUE on success, ARES_FALSE on out of memory or misuse - */ -CARES_EXTERN ares_bool_t ares_htable_asvp_insert(ares_htable_asvp_t *htable, - ares_socket_t key, void *val); - -/*! Retrieve value from hashtable based on key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \param[out] val Optional. Pointer to store value. - * \return ARES_TRUE on success, ARES_FALSE on failure - */ -CARES_EXTERN ares_bool_t ares_htable_asvp_get(const ares_htable_asvp_t *htable, - ares_socket_t key, void **val); - -/*! Retrieve value from hashtable directly as return value. Caveat to this - * function over ares_htable_asvp_get() is that if a NULL value is stored - * you cannot determine if the key is not found or the value is NULL. - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return value associated with key in hashtable or NULL - */ -CARES_EXTERN void *ares_htable_asvp_get_direct(const ares_htable_asvp_t *htable, - ares_socket_t key); - -/*! Remove a value from the hashtable by key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return ARES_TRUE if found, ARES_FALSE if not found - */ -CARES_EXTERN ares_bool_t ares_htable_asvp_remove(ares_htable_asvp_t *htable, - ares_socket_t key); - -/*! Retrieve the number of keys stored in the hash table - * - * \param[in] htable Initialized hash table - * \return count - */ -CARES_EXTERN size_t ares_htable_asvp_num_keys(const ares_htable_asvp_t *htable); - -/*! @} */ - -#endif /* __ARES__HTABLE_ASVP_H */ diff --git a/vendor/c-ares/src/lib/include/ares_htable_dict.h b/vendor/c-ares/src/lib/include/ares_htable_dict.h deleted file mode 100644 index cb6f1f048..000000000 --- a/vendor/c-ares/src/lib/include/ares_htable_dict.h +++ /dev/null @@ -1,123 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__HTABLE_DICT_H -#define __ARES__HTABLE_DICT_H - -/*! \addtogroup ares_htable_dict HashTable with case-insensitive string Key and - * string value - * - * This data structure wraps the base ares_htable data structure in order to - * split the key and value data types as string and string, respectively. - * - * Average time complexity: - * - Insert: O(1) - * - Search: O(1) - * - Delete: O(1) - * - * @{ - */ - -struct ares_htable_dict; - -/*! Opaque data type for string key, string value hash table - * implementation */ -typedef struct ares_htable_dict ares_htable_dict_t; - -/*! Destroy hashtable - * - * \param[in] htable Initialized hashtable - */ -CARES_EXTERN void ares_htable_dict_destroy(ares_htable_dict_t *htable); - -/*! Create void pointer key, string value hash table - * - */ -CARES_EXTERN ares_htable_dict_t *ares_htable_dict_create(void); - -/*! Insert key/value into hash table - * - * \param[in] htable Initialized hash table - * \param[in] key key to associate with value - * \param[in] val value to store (duplicates). - * \return ARES_TRUE on success, ARES_FALSE on failure or out of memory - */ -CARES_EXTERN ares_bool_t ares_htable_dict_insert(ares_htable_dict_t *htable, - const char *key, - const char *val); - -/*! Retrieve value from hashtable based on key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \param[out] val Optional. Pointer to store value. - * \return ARES_TRUE on success, ARES_FALSE on failure - */ -CARES_EXTERN ares_bool_t ares_htable_dict_get(const ares_htable_dict_t *htable, - const char *key, - const char **val); - -/*! Retrieve value from hashtable directly as return value. Caveat to this - * function over ares_htable_dict_get() is that if a NULL value is stored - * you cannot determine if the key is not found or the value is NULL. - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return value associated with key in hashtable or NULL - */ -CARES_EXTERN const char * - ares_htable_dict_get_direct(const ares_htable_dict_t *htable, - const char *key); - -/*! Remove a value from the hashtable by key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return ARES_TRUE if found, ARES_FALSE if not - */ -CARES_EXTERN ares_bool_t ares_htable_dict_remove(ares_htable_dict_t *htable, - const char *key); - -/*! Retrieve the number of keys stored in the hash table - * - * \param[in] htable Initialized hash table - * \return count - */ -CARES_EXTERN size_t ares_htable_dict_num_keys(const ares_htable_dict_t *htable); - -/*! Retrieve an array of keys from the hashtable. - * - * \param[in] htable Initialized hashtable - * \param[out] num Count of returned keys - * \return Array of keys in the hashtable. Must be free'd with - * ares_free_array(strs, num, ares_free); - */ -CARES_EXTERN char **ares_htable_dict_keys(const ares_htable_dict_t *htable, - size_t *num); - - -/*! @} */ - -#endif /* __ARES__HTABLE_DICT_H */ diff --git a/vendor/c-ares/src/lib/include/ares_htable_strvp.h b/vendor/c-ares/src/lib/include/ares_htable_strvp.h deleted file mode 100644 index eaaf6d3be..000000000 --- a/vendor/c-ares/src/lib/include/ares_htable_strvp.h +++ /dev/null @@ -1,130 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__HTABLE_STRVP_H -#define __ARES__HTABLE_STRVP_H - -/*! \addtogroup ares_htable_strvp HashTable with string Key and void pointer - * Value - * - * This data structure wraps the base ares_htable data structure in order to - * split the key and value data types as string and void pointer, respectively. - * - * Average time complexity: - * - Insert: O(1) - * - Search: O(1) - * - Delete: O(1) - * - * @{ - */ - -struct ares_htable_strvp; - -/*! Opaque data type for size_t key, void pointer hash table implementation */ -typedef struct ares_htable_strvp ares_htable_strvp_t; - -/*! Callback to free value stored in hashtable - * - * \param[in] val user-supplied value - */ -typedef void (*ares_htable_strvp_val_free_t)(void *val); - -/*! Destroy hashtable - * - * \param[in] htable Initialized hashtable - */ -CARES_EXTERN void ares_htable_strvp_destroy(ares_htable_strvp_t *htable); - -/*! Create string, void pointer value hash table - * - * \param[in] val_free Optional. Call back to free user-supplied value. If - * NULL it is expected the caller will clean up any user - * supplied values. - */ -CARES_EXTERN ares_htable_strvp_t * - ares_htable_strvp_create(ares_htable_strvp_val_free_t val_free); - -/*! Insert key/value into hash table - * - * \param[in] htable Initialized hash table - * \param[in] key key to associate with value - * \param[in] val value to store (takes ownership). May be NULL. - * \return ARES_TRUE on success, ARES_FALSE on failure or out of memory - */ -CARES_EXTERN ares_bool_t ares_htable_strvp_insert(ares_htable_strvp_t *htable, - const char *key, void *val); - -/*! Retrieve value from hashtable based on key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \param[out] val Optional. Pointer to store value. - * \return ARES_TRUE on success, ARES_FALSE on failure - */ -CARES_EXTERN ares_bool_t ares_htable_strvp_get( - const ares_htable_strvp_t *htable, const char *key, void **val); - -/*! Retrieve value from hashtable directly as return value. Caveat to this - * function over ares_htable_strvp_get() is that if a NULL value is stored - * you cannot determine if the key is not found or the value is NULL. - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return value associated with key in hashtable or NULL - */ -CARES_EXTERN void * - ares_htable_strvp_get_direct(const ares_htable_strvp_t *htable, - const char *key); - -/*! Remove a value from the hashtable by key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return ARES_TRUE if found, ARES_FALSE if not - */ -CARES_EXTERN ares_bool_t ares_htable_strvp_remove(ares_htable_strvp_t *htable, - const char *key); - -/*! Remove the value from the hashtable, and return the value instead of - * calling the val_free passed to ares_htable_strvp_create(). - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return value in hashtable or NULL on error - */ -CARES_EXTERN void *ares_htable_strvp_claim(ares_htable_strvp_t *htable, - const char *key); - -/*! Retrieve the number of keys stored in the hash table - * - * \param[in] htable Initialized hash table - * \return count - */ -CARES_EXTERN size_t - ares_htable_strvp_num_keys(const ares_htable_strvp_t *htable); - -/*! @} */ - -#endif /* __ARES__HTABLE_STRVP_H */ diff --git a/vendor/c-ares/src/lib/include/ares_htable_szvp.h b/vendor/c-ares/src/lib/include/ares_htable_szvp.h deleted file mode 100644 index 927b9a5ec..000000000 --- a/vendor/c-ares/src/lib/include/ares_htable_szvp.h +++ /dev/null @@ -1,118 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__HTABLE_STVP_H -#define __ARES__HTABLE_STVP_H - -/*! \addtogroup ares_htable_szvp HashTable with size_t Key and void pointer - * Value - * - * This data structure wraps the base ares_htable data structure in order to - * split the key and value data types as size_t and void pointer, respectively. - * - * Average time complexity: - * - Insert: O(1) - * - Search: O(1) - * - Delete: O(1) - * - * @{ - */ - -struct ares_htable_szvp; - -/*! Opaque data type for size_t key, void pointer hash table implementation */ -typedef struct ares_htable_szvp ares_htable_szvp_t; - -/*! Callback to free value stored in hashtable - * - * \param[in] val user-supplied value - */ -typedef void (*ares_htable_szvp_val_free_t)(void *val); - -/*! Destroy hashtable - * - * \param[in] htable Initialized hashtable - */ -CARES_EXTERN void ares_htable_szvp_destroy(ares_htable_szvp_t *htable); - -/*! Create size_t key, void pointer value hash table - * - * \param[in] val_free Optional. Call back to free user-supplied value. If - * NULL it is expected the caller will clean up any user - * supplied values. - */ -CARES_EXTERN ares_htable_szvp_t * - ares_htable_szvp_create(ares_htable_szvp_val_free_t val_free); - -/*! Insert key/value into hash table - * - * \param[in] htable Initialized hash table - * \param[in] key key to associate with value - * \param[in] val value to store (takes ownership). May be NULL. - * \return ARES_TRUE on success, ARES_FALSE on failure or out of memory - */ -CARES_EXTERN ares_bool_t ares_htable_szvp_insert(ares_htable_szvp_t *htable, - size_t key, void *val); - -/*! Retrieve value from hashtable based on key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \param[out] val Optional. Pointer to store value. - * \return ARES_TRUE on success, ARES_FALSE on failure - */ -CARES_EXTERN ares_bool_t ares_htable_szvp_get(const ares_htable_szvp_t *htable, - size_t key, void **val); - -/*! Retrieve value from hashtable directly as return value. Caveat to this - * function over ares_htable_szvp_get() is that if a NULL value is stored - * you cannot determine if the key is not found or the value is NULL. - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return value associated with key in hashtable or NULL - */ -CARES_EXTERN void *ares_htable_szvp_get_direct(const ares_htable_szvp_t *htable, - size_t key); - -/*! Remove a value from the hashtable by key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return ARES_TRUE if found, ARES_FALSE if not - */ -CARES_EXTERN ares_bool_t ares_htable_szvp_remove(ares_htable_szvp_t *htable, - size_t key); - -/*! Retrieve the number of keys stored in the hash table - * - * \param[in] htable Initialized hash table - * \return count - */ -CARES_EXTERN size_t ares_htable_szvp_num_keys(const ares_htable_szvp_t *htable); - -/*! @} */ - -#endif /* __ARES__HTABLE_STVP_H */ diff --git a/vendor/c-ares/src/lib/include/ares_htable_vpstr.h b/vendor/c-ares/src/lib/include/ares_htable_vpstr.h deleted file mode 100644 index 9f51b8774..000000000 --- a/vendor/c-ares/src/lib/include/ares_htable_vpstr.h +++ /dev/null @@ -1,111 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__HTABLE_VPSTR_H -#define __ARES__HTABLE_VPSTR_H - -/*! \addtogroup ares_htable_vpstr HashTable with void pointer Key and string - * value - * - * This data structure wraps the base ares_htable data structure in order to - * split the key and value data types as void pointer and string, respectively. - * - * Average time complexity: - * - Insert: O(1) - * - Search: O(1) - * - Delete: O(1) - * - * @{ - */ - -struct ares_htable_vpstr; - -/*! Opaque data type for void pointer key, string value hash table - * implementation */ -typedef struct ares_htable_vpstr ares_htable_vpstr_t; - -/*! Destroy hashtable - * - * \param[in] htable Initialized hashtable - */ -CARES_EXTERN void ares_htable_vpstr_destroy(ares_htable_vpstr_t *htable); - -/*! Create void pointer key, string value hash table - * - */ -CARES_EXTERN ares_htable_vpstr_t *ares_htable_vpstr_create(void); - -/*! Insert key/value into hash table - * - * \param[in] htable Initialized hash table - * \param[in] key key to associate with value - * \param[in] val value to store (duplicates). - * \return ARES_TRUE on success, ARES_FALSE on failure or out of memory - */ -CARES_EXTERN ares_bool_t ares_htable_vpstr_insert(ares_htable_vpstr_t *htable, - void *key, const char *val); - -/*! Retrieve value from hashtable based on key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \param[out] val Optional. Pointer to store value. - * \return ARES_TRUE on success, ARES_FALSE on failure - */ -CARES_EXTERN ares_bool_t ares_htable_vpstr_get( - const ares_htable_vpstr_t *htable, const void *key, const char **val); - -/*! Retrieve value from hashtable directly as return value. Caveat to this - * function over ares_htable_vpstr_get() is that if a NULL value is stored - * you cannot determine if the key is not found or the value is NULL. - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return value associated with key in hashtable or NULL - */ -CARES_EXTERN const char * - ares_htable_vpstr_get_direct(const ares_htable_vpstr_t *htable, - const void *key); - -/*! Remove a value from the hashtable by key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return ARES_TRUE if found, ARES_FALSE if not - */ -CARES_EXTERN ares_bool_t ares_htable_vpstr_remove(ares_htable_vpstr_t *htable, - const void *key); - -/*! Retrieve the number of keys stored in the hash table - * - * \param[in] htable Initialized hash table - * \return count - */ -CARES_EXTERN size_t - ares_htable_vpstr_num_keys(const ares_htable_vpstr_t *htable); - -/*! @} */ - -#endif /* __ARES__HTABLE_VPSTR_H */ diff --git a/vendor/c-ares/src/lib/include/ares_htable_vpvp.h b/vendor/c-ares/src/lib/include/ares_htable_vpvp.h deleted file mode 100644 index 1ebe61457..000000000 --- a/vendor/c-ares/src/lib/include/ares_htable_vpvp.h +++ /dev/null @@ -1,128 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__HTABLE_VPVP_H -#define __ARES__HTABLE_VPVP_H - -/*! \addtogroup ares_htable_vpvp HashTable with void pointer Key and void - * pointer Value - * - * This data structure wraps the base ares_htable data structure in order to - * split the key and value data types as size_t and void pointer, respectively. - * - * Average time complexity: - * - Insert: O(1) - * - Search: O(1) - * - Delete: O(1) - * - * @{ - */ - -struct ares_htable_vpvp; - -/*! Opaque data type for size_t key, void pointer hash table implementation */ -typedef struct ares_htable_vpvp ares_htable_vpvp_t; - -/*! Callback to free key stored in hashtable - * - * \param[in] key user-supplied key - */ -typedef void (*ares_htable_vpvp_key_free_t)(void *key); - -/*! Callback to free value stored in hashtable - * - * \param[in] val user-supplied value - */ -typedef void (*ares_htable_vpvp_val_free_t)(void *val); - -/*! Destroy hashtable - * - * \param[in] htable Initialized hashtable - */ -CARES_EXTERN void ares_htable_vpvp_destroy(ares_htable_vpvp_t *htable); - -/*! Create size_t key, void pointer value hash table - * - * \param[in] key_free Optional. Call back to free user-supplied key. If - * NULL it is expected the caller will clean up any user - * supplied keys. - * \param[in] val_free Optional. Call back to free user-supplied value. If - * NULL it is expected the caller will clean up any user - * supplied values. - */ -CARES_EXTERN ares_htable_vpvp_t * - ares_htable_vpvp_create(ares_htable_vpvp_key_free_t key_free, - ares_htable_vpvp_val_free_t val_free); - -/*! Insert key/value into hash table - * - * \param[in] htable Initialized hash table - * \param[in] key key to associate with value - * \param[in] val value to store (takes ownership). May be NULL. - * \return ARES_TRUE on success, ARES_FALSE on failure or out of memory - */ -CARES_EXTERN ares_bool_t ares_htable_vpvp_insert(ares_htable_vpvp_t *htable, - void *key, void *val); - -/*! Retrieve value from hashtable based on key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \param[out] val Optional. Pointer to store value. - * \return ARES_TRUE on success, ARES_FALSE on failure - */ -CARES_EXTERN ares_bool_t ares_htable_vpvp_get(const ares_htable_vpvp_t *htable, - const void *key, void **val); - -/*! Retrieve value from hashtable directly as return value. Caveat to this - * function over ares_htable_vpvp_get() is that if a NULL value is stored - * you cannot determine if the key is not found or the value is NULL. - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return value associated with key in hashtable or NULL - */ -CARES_EXTERN void *ares_htable_vpvp_get_direct(const ares_htable_vpvp_t *htable, - const void *key); - -/*! Remove a value from the hashtable by key - * - * \param[in] htable Initialized hash table - * \param[in] key key to use to search - * \return ARES_TRUE if found, ARES_FALSE if not - */ -CARES_EXTERN ares_bool_t ares_htable_vpvp_remove(ares_htable_vpvp_t *htable, - const void *key); - -/*! Retrieve the number of keys stored in the hash table - * - * \param[in] htable Initialized hash table - * \return count - */ -CARES_EXTERN size_t ares_htable_vpvp_num_keys(const ares_htable_vpvp_t *htable); - -/*! @} */ - -#endif /* __ARES__HTABLE_VPVP_H */ diff --git a/vendor/c-ares/src/lib/include/ares_llist.h b/vendor/c-ares/src/lib/include/ares_llist.h deleted file mode 100644 index 6aa0c7837..000000000 --- a/vendor/c-ares/src/lib/include/ares_llist.h +++ /dev/null @@ -1,239 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__LLIST_H -#define __ARES__LLIST_H - -/*! \addtogroup ares_llist LinkedList Data Structure - * - * This is a doubly-linked list data structure. - * - * Average time complexity: - * - Insert: O(1) -- head or tail - * - Search: O(n) - * - Delete: O(1) -- delete assumes you hold a node pointer - * - * @{ - */ - -struct ares_llist; - -/*! Opaque data structure for linked list */ -typedef struct ares_llist ares_llist_t; - -struct ares_llist_node; - -/*! Opaque data structure for a node in a linked list */ -typedef struct ares_llist_node ares_llist_node_t; - -/*! Callback to free user-defined node data - * - * \param[in] data user supplied data - */ -typedef void (*ares_llist_destructor_t)(void *data); - -/*! Create a linked list object - * - * \param[in] destruct Optional. Destructor to call on all removed nodes - * \return linked list object or NULL on out of memory - */ -CARES_EXTERN ares_llist_t *ares_llist_create(ares_llist_destructor_t destruct); - -/*! Replace destructor for linked list nodes. Typically this is used - * when wanting to disable the destructor by using NULL. - * - * \param[in] list Initialized linked list object - * \param[in] destruct replacement destructor, NULL is allowed - */ -CARES_EXTERN void - ares_llist_replace_destructor(ares_llist_t *list, - ares_llist_destructor_t destruct); - -/*! Insert value as the first node in the linked list - * - * \param[in] list Initialized linked list object - * \param[in] val user-supplied value. - * \return node object referencing place in list, or null if out of memory or - * misuse - */ -CARES_EXTERN ares_llist_node_t *ares_llist_insert_first(ares_llist_t *list, - void *val); - -/*! Insert value as the last node in the linked list - * - * \param[in] list Initialized linked list object - * \param[in] val user-supplied value. - * \return node object referencing place in list, or null if out of memory or - * misuse - */ -CARES_EXTERN ares_llist_node_t *ares_llist_insert_last(ares_llist_t *list, - void *val); - -/*! Insert value before specified node in the linked list - * - * \param[in] node node referenced to insert before - * \param[in] val user-supplied value. - * \return node object referencing place in list, or null if out of memory or - * misuse - */ -CARES_EXTERN ares_llist_node_t * - ares_llist_insert_before(ares_llist_node_t *node, void *val); - -/*! Insert value after specified node in the linked list - * - * \param[in] node node referenced to insert after - * \param[in] val user-supplied value. - * \return node object referencing place in list, or null if out of memory or - * misuse - */ -CARES_EXTERN ares_llist_node_t *ares_llist_insert_after(ares_llist_node_t *node, - void *val); - -/*! Obtain first node in list - * - * \param[in] list Initialized list object - * \return first node in list or NULL if none - */ -CARES_EXTERN ares_llist_node_t *ares_llist_node_first(ares_llist_t *list); - -/*! Obtain last node in list - * - * \param[in] list Initialized list object - * \return last node in list or NULL if none - */ -CARES_EXTERN ares_llist_node_t *ares_llist_node_last(ares_llist_t *list); - -/*! Obtain a node based on its index. This is an O(n) operation. - * - * \param[in] list Initialized list object - * \param[in] idx Index of node to retrieve - * \return node at index or NULL if invalid index - */ -CARES_EXTERN ares_llist_node_t *ares_llist_node_idx(ares_llist_t *list, - size_t idx); - -/*! Obtain next node in respect to specified node - * - * \param[in] node Node referenced - * \return node or NULL if none - */ -CARES_EXTERN ares_llist_node_t *ares_llist_node_next(ares_llist_node_t *node); - -/*! Obtain previous node in respect to specified node - * - * \param[in] node Node referenced - * \return node or NULL if none - */ -CARES_EXTERN ares_llist_node_t *ares_llist_node_prev(ares_llist_node_t *node); - - -/*! Obtain value from node - * - * \param[in] node Node referenced - * \return user provided value from node - */ -CARES_EXTERN void *ares_llist_node_val(ares_llist_node_t *node); - -/*! Obtain the number of entries in the list - * - * \param[in] list Initialized list object - * \return count - */ -CARES_EXTERN size_t ares_llist_len(const ares_llist_t *list); - -/*! Clear all entries in the list, but don't destroy the list object. - * - * \param[in] list Initialized list object - */ -CARES_EXTERN void ares_llist_clear(ares_llist_t *list); - -/*! Obtain list object from referenced node - * - * \param[in] node Node referenced - * \return list object node belongs to - */ -CARES_EXTERN ares_llist_t *ares_llist_node_parent(ares_llist_node_t *node); - -/*! Obtain the first user-supplied value in the list - * - * \param[in] list Initialized list object - * \return first user supplied value or NULL if none - */ -CARES_EXTERN void *ares_llist_first_val(ares_llist_t *list); - -/*! Obtain the last user-supplied value in the list - * - * \param[in] list Initialized list object - * \return last user supplied value or NULL if none - */ -CARES_EXTERN void *ares_llist_last_val(ares_llist_t *list); - -/*! Take ownership of user-supplied value in list without calling destructor. - * Will unchain entry from list. - * - * \param[in] node Node referenced - * \return user supplied value - */ -CARES_EXTERN void *ares_llist_node_claim(ares_llist_node_t *node); - -/*! Replace user-supplied value for node - * - * \param[in] node Node referenced - * \param[in] val new user-supplied value - */ -CARES_EXTERN void ares_llist_node_replace(ares_llist_node_t *node, void *val); - -/*! Destroy the node, removing it from the list and calling destructor. - * - * \param[in] node Node referenced - */ -CARES_EXTERN void ares_llist_node_destroy(ares_llist_node_t *node); - -/*! Destroy the list object and all nodes in the list. - * - * \param[in] list Initialized list object - */ -CARES_EXTERN void ares_llist_destroy(ares_llist_t *list); - -/*! Detach node from the current list and re-attach it to the new list as the - * last entry. - * - * \param[in] node node to move - * \param[in] new_parent new list - */ -CARES_EXTERN void ares_llist_node_mvparent_last(ares_llist_node_t *node, - ares_llist_t *new_parent); - -/*! Detach node from the current list and re-attach it to the new list as the - * first entry. - * - * \param[in] node node to move - * \param[in] new_parent new list - */ -CARES_EXTERN void ares_llist_node_mvparent_first(ares_llist_node_t *node, - ares_llist_t *new_parent); -/*! @} */ - -#endif /* __ARES__LLIST_H */ diff --git a/vendor/c-ares/src/lib/include/ares_mem.h b/vendor/c-ares/src/lib/include/ares_mem.h deleted file mode 100644 index 371cd4266..000000000 --- a/vendor/c-ares/src/lib/include/ares_mem.h +++ /dev/null @@ -1,38 +0,0 @@ -/* MIT License - * - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __ARES_MEM_H -#define __ARES_MEM_H - -/* Memory management functions */ -CARES_EXTERN void *ares_malloc(size_t size); -CARES_EXTERN void *ares_realloc(void *ptr, size_t size); -CARES_EXTERN void ares_free(void *ptr); -CARES_EXTERN void *ares_malloc_zero(size_t size); -CARES_EXTERN void *ares_realloc_zero(void *ptr, size_t orig_size, - size_t new_size); - -#endif diff --git a/vendor/c-ares/src/lib/include/ares_str.h b/vendor/c-ares/src/lib/include/ares_str.h deleted file mode 100644 index 4ee339510..000000000 --- a/vendor/c-ares/src/lib/include/ares_str.h +++ /dev/null @@ -1,244 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_STR_H -#define __ARES_STR_H - -CARES_EXTERN char *ares_strdup(const char *s1); - -/*! Scan up to maxlen bytes for the first NULL character and return - * its index, or maxlen if not found. The function only returns - * maxlen if the first maxlen bytes were not NULL characters; it - * makes no guarantee for what \c str[maxlen] (if defined) is, and - * does not access it. It is behaving like the POSIX \c strnlen() - * function, except that it returns 0 if the \p str pointer is \c - * NULL. - * - * \param[in] str The string to scan for the NULL character - * \param[in] maxlen The maximum number of bytes to scan - * \return Index of first NULL byte. Between 0 and maxlen (inclusive). - */ -CARES_EXTERN size_t ares_strnlen(const char *str, size_t maxlen); - -CARES_EXTERN size_t ares_strlen(const char *str); - -/*! Copy string from source to destination with destination buffer size - * provided. The destination is guaranteed to be null terminated, if the - * provided buffer isn't large enough, only those bytes from the source that - * will fit will be copied. - * - * \param[out] dest Destination buffer - * \param[in] src Source to copy - * \param[in] dest_size Size of destination buffer - * \return String length. Will be at most dest_size-1 - */ -CARES_EXTERN size_t ares_strcpy(char *dest, const char *src, size_t dest_size); - -CARES_EXTERN ares_bool_t ares_str_isnum(const char *str); -CARES_EXTERN ares_bool_t ares_str_isalnum(const char *str); - -CARES_EXTERN void ares_str_ltrim(char *str); -CARES_EXTERN void ares_str_rtrim(char *str); -CARES_EXTERN void ares_str_trim(char *str); -CARES_EXTERN void ares_str_lower(char *str); - -CARES_EXTERN unsigned char ares_tolower(unsigned char c); -CARES_EXTERN unsigned char *ares_memmem(const unsigned char *big, - size_t big_len, - const unsigned char *little, - size_t little_len); -CARES_EXTERN ares_bool_t ares_memeq(const unsigned char *ptr, - const unsigned char *val, size_t len); -CARES_EXTERN ares_bool_t ares_memeq_ci(const unsigned char *ptr, - const unsigned char *val, size_t len); -CARES_EXTERN ares_bool_t ares_is_hostname(const char *str); - -/*! Validate the string provided is printable. The length specified must be - * at least the size of the buffer provided. If a NULL-terminator is hit - * before the length provided is hit, this will not be considered a valid - * printable string. This does not validate that the string is actually - * NULL terminated. - * - * \param[in] str Buffer containing string to evaluate. - * \param[in] len Number of characters to evaluate within provided buffer. - * If 0, will return TRUE since it did not hit an exception. - * \return ARES_TRUE if the entire string is printable, ARES_FALSE if not. - */ -CARES_EXTERN ares_bool_t ares_str_isprint(const char *str, size_t len); - -/* We only care about ASCII rules */ -#define ares_isascii(x) (((unsigned char)x) <= 127) - -#define ares_isdigit(x) (((unsigned char)x) >= '0' && ((unsigned char)x) <= '9') - -#define ares_isxdigit(x) \ - (ares_isdigit(x) || \ - (((unsigned char)x) >= 'a' && ((unsigned char)x) <= 'f') || \ - (((unsigned char)x) >= 'A' && ((unsigned char)x) <= 'F')) - -#define ares_isupper(x) (((unsigned char)x) >= 'A' && ((unsigned char)x) <= 'Z') - -#define ares_islower(x) (((unsigned char)x) >= 'a' && ((unsigned char)x) <= 'z') - -#define ares_isalpha(x) (ares_islower(x) || ares_isupper(x)) - -#define ares_isspace(x) \ - (((unsigned char)(x)) == '\r' || ((unsigned char)(x)) == '\t' || \ - ((unsigned char)(x)) == ' ' || ((unsigned char)(x)) == '\v' || \ - ((unsigned char)(x)) == '\f' || ((unsigned char)(x)) == '\n') - -#define ares_isprint(x) \ - (((unsigned char)(x)) >= 0x20 && ((unsigned char)(x)) <= 0x7E) - -/* Character set allowed by hostnames. This is to include the normal - * domain name character set plus: - * - underscores which are used in SRV records. - * - Forward slashes such as are used for classless in-addr.arpa - * delegation (CNAMEs) - * - Asterisks may be used for wildcard domains in CNAMEs as seen in the - * real world. - * While RFC 2181 section 11 does state not to do validation, - * that applies to servers, not clients. Vulnerabilities have been - * reported when this validation is not performed. Security is more - * important than edge-case compatibility (which is probably invalid - * anyhow). - * [A-Za-z0-9-*._/] - */ -#define ares_is_hostnamech(x) \ - (ares_isalpha(x) || ares_isdigit(x) || ((unsigned char)(x)) == '-' || \ - ((unsigned char)(x)) == '.' || ((unsigned char)(x)) == '_' || \ - ((unsigned char)(x)) == '/' || ((unsigned char)(x)) == '*') - - -/*! Compare two strings (for sorting) - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \return < 0 if First String less than Second String, - * 0 if First String equal to Second String, - * > 0 if First String greater than Second String - */ -CARES_EXTERN int ares_strcmp(const char *a, const char *b); - -/*! Compare two strings up to specified length (for sorting) - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \param[in] n Length - * \return < 0 if First String less than Second String, - * 0 if First String equal to Second String, - * > 0 if First String greater than Second String - */ -CARES_EXTERN int ares_strncmp(const char *a, const char *b, size_t n); - - -/*! Compare two strings in a case-insensitive manner (for sorting) - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \return < 0 if First String less than Second String, - * 0 if First String equal to Second String, - * > 0 if First String greater than Second String - */ -CARES_EXTERN int ares_strcasecmp(const char *a, const char *b); - -/*! Compare two strings in a case-insensitive manner up to specified length - * (for sorting) - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \param[in] n Length - * \return < 0 if First String less than Second String, - * 0 if First String equal to Second String, - * > 0 if First String greater than Second String - */ -CARES_EXTERN int ares_strncasecmp(const char *a, const char *b, size_t n); - -/*! Compare two strings for equality - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \return ARES_TRUE on match, or ARES_FALSE if no match - */ -CARES_EXTERN ares_bool_t ares_streq(const char *a, const char *b); - -/*! Compare two strings for equality up to specified length - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \param[in] n Length - * \return ARES_TRUE on match, or ARES_FALSE if no match - */ -CARES_EXTERN ares_bool_t ares_streq_max(const char *a, const char *b, size_t n); - -/*! Compare two strings for equality in a case insensitive manner - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \return ARES_TRUE on match, or ARES_FALSE if no match - */ -CARES_EXTERN ares_bool_t ares_strcaseeq(const char *a, const char *b); - -/*! Compare two strings for equality up to specified length in a case - * insensitive manner - * - * Treats NULL and "" strings as equivalent - * - * \param[in] a First String - * \param[in] b Second String - * \param[in] n Length - * \return ARES_TRUE on match, or ARES_FALSE if no match - */ -CARES_EXTERN ares_bool_t ares_strcaseeq_max(const char *a, const char *b, - size_t n); - -/*! Free a C array, each element in the array will be freed by the provided - * free function. Both NULL-terminated arrays and known length arrays are - * supported. - * - * \param[in] arr Array to be freed. - * \param[in] nmembers Number of members in the array, or SIZE_MAX for - * NULL-terminated arrays - * \param[in] freefunc Function to call on each array member (e.g. ares_free) - */ -CARES_EXTERN void ares_free_array(void *arr, size_t nmembers, - void (*freefunc)(void *)); - -#endif /* __ARES_STR_H */ diff --git a/vendor/c-ares/src/lib/inet_net_pton.c b/vendor/c-ares/src/lib/inet_net_pton.c deleted file mode 100644 index e1f76ef83..000000000 --- a/vendor/c-ares/src/lib/inet_net_pton.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (c) 2012 by Gilles Chehade - * Copyright (c) 1996,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_nameser.h" - -#include "ares_ipv6.h" -#include "ares_inet_net_pton.h" - -#ifdef USE_WINSOCK -# define SOCKERRNO ((int)WSAGetLastError()) -# define SET_SOCKERRNO(x) (WSASetLastError((int)(x))) -# undef EMSGSIZE -# define EMSGSIZE WSAEMSGSIZE -# undef ENOENT -# define ENOENT WSA_INVALID_PARAMETER -# undef EAFNOSUPPORT -# define EAFNOSUPPORT WSAEAFNOSUPPORT -#else -# define SOCKERRNO (errno) -# define SET_SOCKERRNO(x) (errno = (x)) -#endif - -const struct ares_in6_addr ares_in6addr_any = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 } } }; - -/* - * static int - * inet_net_pton_ipv4(src, dst, size) - * convert IPv4 network number from presentation to network format. - * accepts hex octets, hex strings, decimal octets, and /CIDR. - * "size" is in bytes and describes "dst". - * return: - * number of bits, either imputed classfully or specified with /CIDR, - * or -1 if some failure occurred (check errno). ENOENT means it was - * not an IPv4 network specification. - * note: - * network byte order assumed. this means 192.5.5.240/28 has - * 0b11110000 in its fourth octet. - * note: - * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid losing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this function sets when returning (-1), not SOCKERRNO. - * author: - * Paul Vixie (ISC), June 1996 - */ -static int ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, - size_t size) -{ - static const char xdigits[] = "0123456789abcdef"; - static const char digits[] = "0123456789"; - int n; - int ch; - int tmp = 0; - int dirty; - int bits; - const unsigned char *odst = dst; - - ch = *src++; - if (ch == '0' && (src[0] == 'x' || src[0] == 'X') && ares_isascii(src[1]) && - ares_isxdigit(src[1])) { - /* Hexadecimal: Eat nybble string. */ - if (!size) { - goto emsgsize; - } - dirty = 0; - src++; /* skip x or X. */ - while ((ch = *src++) != '\0' && ares_isascii(ch) && ares_isxdigit(ch)) { - if (ares_isupper(ch)) { - ch = ares_tolower((unsigned char)ch); - } - n = (int)(strchr(xdigits, ch) - xdigits); - if (dirty == 0) { - tmp = n; - } else { - tmp = (tmp << 4) | n; - } - if (++dirty == 2) { - if (!size--) { - goto emsgsize; - } - *dst++ = (unsigned char)tmp; - dirty = 0; - } - } - if (dirty) { /* Odd trailing nybble? */ - if (!size--) { - goto emsgsize; - } - *dst++ = (unsigned char)(tmp << 4); - } - } else if (ares_isascii(ch) && ares_isdigit(ch)) { - /* Decimal: eat dotted digit string. */ - for (;;) { - tmp = 0; - do { - n = (int)(strchr(digits, ch) - digits); - tmp *= 10; - tmp += n; - if (tmp > 255) { - goto enoent; - } - } while ((ch = *src++) != '\0' && ares_isascii(ch) && ares_isdigit(ch)); - if (!size--) { - goto emsgsize; - } - *dst++ = (unsigned char)tmp; - if (ch == '\0' || ch == '/') { - break; - } - if (ch != '.') { - goto enoent; - } - ch = *src++; - if (!ares_isascii(ch) || !ares_isdigit(ch)) { - goto enoent; - } - } - } else { - goto enoent; - } - - bits = -1; - if (ch == '/' && ares_isascii(src[0]) && ares_isdigit(src[0]) && dst > odst) { - /* CIDR width specifier. Nothing can follow it. */ - ch = *src++; /* Skip over the /. */ - bits = 0; - do { - n = (int)(strchr(digits, ch) - digits); - bits *= 10; - bits += n; - if (bits > 32) { - goto enoent; - } - } while ((ch = *src++) != '\0' && ares_isascii(ch) && ares_isdigit(ch)); - if (ch != '\0') { - goto enoent; - } - } - - /* Firey death and destruction unless we prefetched EOS. */ - if (ch != '\0') { - goto enoent; - } - - /* If nothing was written to the destination, we found no address. */ - if (dst == odst) { - goto enoent; /* LCOV_EXCL_LINE: all valid paths above increment dst */ - } - /* If no CIDR spec was given, infer width from net class. */ - if (bits == -1) { - if (*odst >= 240) { /* Class E */ - bits = 32; - } else if (*odst >= 224) { /* Class D */ - bits = 8; - } else if (*odst >= 192) { /* Class C */ - bits = 24; - } else if (*odst >= 128) { /* Class B */ - bits = 16; - } else { /* Class A */ - bits = 8; - } - /* If imputed mask is narrower than specified octets, widen. */ - if (bits < ((dst - odst) * 8)) { - bits = (int)(dst - odst) * 8; - } - /* - * If there are no additional bits specified for a class D - * address adjust bits to 4. - */ - if (bits == 8 && *odst == 224) { - bits = 4; - } - } - /* Extend network to cover the actual mask. */ - while (bits > ((dst - odst) * 8)) { - if (!size--) { - goto emsgsize; - } - *dst++ = '\0'; - } - return bits; - -enoent: - SET_SOCKERRNO(ENOENT); - return -1; - -emsgsize: - SET_SOCKERRNO(EMSGSIZE); - return -1; -} - -static int getbits(const char *src, size_t *bitsp) -{ - static const char digits[] = "0123456789"; - size_t n; - size_t val; - char ch; - - val = 0; - n = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - pch = strchr(digits, ch); - if (pch != NULL) { - if (n++ != 0 && val == 0) { /* no leading zeros */ - return 0; - } - val *= 10; - val += (size_t)(pch - digits); - if (val > 128) { /* range */ - return 0; - } - continue; - } - return 0; - } - if (n == 0) { - return 0; - } - *bitsp = val; - return 1; -} - -static int ares_inet_pton6(const char *src, unsigned char *dst) -{ - static const char xdigits_l[] = "0123456789abcdef"; - static const char xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[NS_IN6ADDRSZ]; - unsigned char *tp; - unsigned char *endp; - unsigned char *colonp; - const char *xdigits; - const char *curtok; - int ch; - int saw_xdigit; - int count_xdigit; - unsigned int val; - - memset((tp = tmp), '\0', NS_IN6ADDRSZ); - endp = tp + NS_IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') { - if (*++src != ':') { - goto enoent; - } - } - curtok = src; - saw_xdigit = count_xdigit = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) { - pch = strchr((xdigits = xdigits_u), ch); - } - if (pch != NULL) { - if (count_xdigit >= 4) { - goto enoent; - } - val <<= 4; - val |= (unsigned int)(pch - xdigits); - if (val > 0xffff) { - goto enoent; - } - saw_xdigit = 1; - count_xdigit++; - continue; - } - if (ch == ':') { - curtok = src; - if (!saw_xdigit) { - if (colonp) { - goto enoent; - } - colonp = tp; - continue; - } else if (*src == '\0') { - goto enoent; - } - if (tp + NS_INT16SZ > endp) { - goto enoent; - } - *tp++ = (unsigned char)(val >> 8) & 0xff; - *tp++ = (unsigned char)val & 0xff; - saw_xdigit = 0; - count_xdigit = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && - ares_inet_net_pton_ipv4(curtok, tp, NS_INADDRSZ) > 0) { - tp += NS_INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - goto enoent; - } - if (saw_xdigit) { - if (tp + NS_INT16SZ > endp) { - goto enoent; - } - *tp++ = (unsigned char)(val >> 8) & 0xff; - *tp++ = (unsigned char)val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = (int)(tp - colonp); - int i; - - if (tp == endp) { - goto enoent; - } - for (i = 1; i <= n; i++) { - endp[-i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) { - goto enoent; - } - - memcpy(dst, tmp, NS_IN6ADDRSZ); - return 1; - -enoent: - SET_SOCKERRNO(ENOENT); - return -1; -} - -static int ares_inet_net_pton_ipv6(const char *src, unsigned char *dst, - size_t size) -{ - struct ares_in6_addr in6; - int ret; - size_t bits; - size_t bytes; - char buf[INET6_ADDRSTRLEN + sizeof("/128")]; - char *sep; - - if (ares_strlen(src) >= sizeof buf) { - SET_SOCKERRNO(EMSGSIZE); - return -1; - } - ares_strcpy(buf, src, sizeof buf); - - sep = strchr(buf, '/'); - if (sep != NULL) { - *sep++ = '\0'; - } - - ret = ares_inet_pton6(buf, (unsigned char *)&in6); - if (ret != 1) { - return -1; - } - - if (sep == NULL) { - bits = 128; - } else { - if (!getbits(sep, &bits)) { - SET_SOCKERRNO(ENOENT); - return -1; - } - } - - bytes = (bits + 7) / 8; - if (bytes > size) { - SET_SOCKERRNO(EMSGSIZE); - return -1; - } - memcpy(dst, &in6, bytes); - return (int)bits; -} - -/* - * int - * inet_net_pton(af, src, dst, size) - * convert network number from presentation to network format. - * accepts hex octets, hex strings, decimal octets, and /CIDR. - * "size" is in bytes and describes "dst". - * return: - * number of bits, either imputed classfully or specified with /CIDR, - * or -1 if some failure occurred (check errno). ENOENT means it was - * not a valid network specification. - * author: - * Paul Vixie (ISC), June 1996 - * - */ -int ares_inet_net_pton(int af, const char *src, void *dst, size_t size) -{ - switch (af) { - case AF_INET: - return ares_inet_net_pton_ipv4(src, dst, size); - case AF_INET6: - return ares_inet_net_pton_ipv6(src, dst, size); - default: - return -1; - } -} - -int ares_inet_pton(int af, const char *src, void *dst) -{ - int result; - size_t size; - - if (af == AF_INET) { - size = sizeof(struct in_addr); - } else if (af == AF_INET6) { - size = sizeof(struct ares_in6_addr); - } else { - SET_SOCKERRNO(EAFNOSUPPORT); - return -1; - } - result = ares_inet_net_pton(af, src, dst, size); - if (result == -1 && SOCKERRNO == ENOENT) { - return 0; - } - return (result > -1) ? 1 : -1; -} diff --git a/vendor/c-ares/src/lib/inet_ntop.c b/vendor/c-ares/src/lib/inet_ntop.c deleted file mode 100644 index 79b6c0fa9..000000000 --- a/vendor/c-ares/src/lib/inet_ntop.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include "ares_nameser.h" -#include "ares_ipv6.h" - -#ifdef USE_WINSOCK -# define SOCKERRNO ((int)WSAGetLastError()) -# define SET_SOCKERRNO(x) (WSASetLastError((int)(x))) -# undef EMSGSIZE -# define EMSGSIZE WSAEMSGSIZE -# undef ENOENT -# define ENOENT WSA_INVALID_PARAMETER -# undef EAFNOSUPPORT -# define EAFNOSUPPORT WSAEAFNOSUPPORT -# undef ENOSPC -# define ENOSPC WSA_INVALID_PARAMETER -#else -# define SOCKERRNO (errno) -# define SET_SOCKERRNO(x) (errno = (x)) -#endif - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size); -static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); - -/* char * - * inet_ntop(af, src, dst, size) - * convert a network format address to presentation format. - * return: - * pointer to presentation format address (`dst'), or NULL (see errno). - * author: - * Paul Vixie, 1996. - */ -const char *ares_inet_ntop(int af, const void *src, char *dst, - ares_socklen_t size) -{ - switch (af) { - case AF_INET: - return inet_ntop4(src, dst, (size_t)size); - case AF_INET6: - return inet_ntop6(src, dst, (size_t)size); - default: - break; - } - SET_SOCKERRNO(EAFNOSUPPORT); - return NULL; -} - -/* const char * - * inet_ntop4(src, dst, size) - * format an IPv4 address - * return: - * `dst' (as a const) - * notes: - * (1) uses no statics - * (2) takes a unsigned char* not an in_addr as input - * author: - * Paul Vixie, 1996. - */ -static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size) -{ - static const char fmt[] = "%u.%u.%u.%u"; - char tmp[sizeof("255.255.255.255")]; - - if (size < sizeof(tmp)) { - SET_SOCKERRNO(ENOSPC); - return NULL; - } - - if ((size_t)snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]) >= - size) { - SET_SOCKERRNO(ENOSPC); - return NULL; - } - ares_strcpy(dst, tmp, size); - return dst; -} - -/* const char * - * inet_ntop6(src, dst, size) - * convert IPv6 binary address into presentation (printable) format - * author: - * Paul Vixie, 1996. - */ -static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - char *tp; - - struct { - ares_ssize_t base; - size_t len; - } best, cur; - - unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; - size_t i; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof(words)); - for (i = 0; i < NS_IN6ADDRSZ; i++) { - words[i / 2] |= (unsigned int)(src[i] << ((1 - (i % 2)) << 3)); - } - best.base = -1; - best.len = 0; - cur.base = -1; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - if (words[i] == 0) { - if (cur.base == -1) { - cur.base = (ares_ssize_t)i; - cur.len = 1; - } else { - cur.len++; - } - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) { - best = cur; - } - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) { - best = cur; - } - } - if (best.base != -1 && best.len < 2) { - best.base = -1; - } - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= (size_t)best.base && - i < ((size_t)best.base + best.len)) { - if (i == (size_t)best.base) { - *tp++ = ':'; - } - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) { - *tp++ = ':'; - } - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src + 12, tp, sizeof(tmp) - (size_t)(tp - tmp))) { - return (NULL); - } - tp += ares_strlen(tp); - break; - } - tp += snprintf(tp, sizeof(tmp) - (size_t)(tp - tmp), "%x", words[i]); - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && - ((size_t)best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) { - *tp++ = ':'; - } - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { - SET_SOCKERRNO(ENOSPC); - return NULL; - } - ares_strcpy(dst, tmp, size); - return dst; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_create_query.c b/vendor/c-ares/src/lib/legacy/ares_create_query.c deleted file mode 100644 index f71a71c95..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_create_query.c +++ /dev/null @@ -1,78 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -static int ares_create_query_int(const char *name, int dnsclass, int type, - unsigned short id, int rd, - unsigned char **bufp, int *buflenp, - int max_udp_size) -{ - ares_status_t status; - ares_dns_record_t *dnsrec = NULL; - size_t len; - ares_dns_flags_t rd_flag = rd ? ARES_FLAG_RD : 0; - - if (name == NULL || bufp == NULL || buflenp == NULL) { - status = ARES_EFORMERR; - goto done; - } - - *bufp = NULL; - *buflenp = 0; - - status = ares_dns_record_create_query( - &dnsrec, name, (ares_dns_class_t)dnsclass, (ares_dns_rec_type_t)type, id, - rd_flag, (size_t)max_udp_size); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_write(dnsrec, bufp, &len); - if (status != ARES_SUCCESS) { - goto done; - } - - *buflenp = (int)len; - -done: - ares_dns_record_destroy(dnsrec); - return (int)status; -} - -int ares_create_query(const char *name, int dnsclass, int type, - unsigned short id, int rd, unsigned char **bufp, - int *buflenp, int max_udp_size) -{ - return ares_create_query_int(name, dnsclass, type, id, rd, bufp, buflenp, - max_udp_size); -} - -int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, - int rd, unsigned char **buf, int *buflen) -{ - return ares_create_query_int(name, dnsclass, type, id, rd, buf, buflen, 0); -} diff --git a/vendor/c-ares/src/lib/legacy/ares_expand_name.c b/vendor/c-ares/src/lib/legacy/ares_expand_name.c deleted file mode 100644 index 72668f4cb..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_expand_name.c +++ /dev/null @@ -1,99 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998, 2011 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#include "ares_nameser.h" - -ares_status_t ares_expand_name_validated(const unsigned char *encoded, - const unsigned char *abuf, size_t alen, - char **s, size_t *enclen, - ares_bool_t is_hostname) -{ - ares_status_t status; - ares_buf_t *buf = NULL; - size_t start_len; - - if (encoded == NULL || abuf == NULL || alen == 0 || enclen == NULL) { - return ARES_EBADNAME; /* EFORMERR would be better */ - } - - if (encoded < abuf || encoded >= abuf + alen) { - return ARES_EBADNAME; /* EFORMERR would be better */ - } - - *enclen = 0; - - /* NOTE: we allow 's' to be NULL to skip it */ - if (s) { - *s = NULL; - } - - buf = ares_buf_create_const(abuf, alen); - - if (buf == NULL) { - return ARES_ENOMEM; - } - - status = ares_buf_set_position(buf, (size_t)(encoded - abuf)); - if (status != ARES_SUCCESS) { - goto done; - } - - start_len = ares_buf_len(buf); - status = ares_dns_name_parse(buf, s, is_hostname); - if (status != ARES_SUCCESS) { - goto done; - } - - *enclen = start_len - ares_buf_len(buf); - -done: - ares_buf_destroy(buf); - return status; -} - -int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, - int alen, char **s, long *enclen) -{ - /* Keep public API compatible */ - size_t enclen_temp = 0; - ares_status_t status; - - if (encoded == NULL || abuf == NULL || alen <= 0 || enclen == NULL) { - return ARES_EBADNAME; - } - - status = ares_expand_name_validated(encoded, abuf, (size_t)alen, s, - &enclen_temp, ARES_FALSE); - *enclen = (long)enclen_temp; - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_expand_string.c b/vendor/c-ares/src/lib/legacy/ares_expand_string.c deleted file mode 100644 index e1deb1932..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_expand_string.c +++ /dev/null @@ -1,107 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#include "ares_nameser.h" - -/* Simply decodes a length-encoded character string. The first byte of the - * input is the length of the string to be returned and the bytes thereafter - * are the characters of the string. The returned result will be NULL - * terminated. - */ -ares_status_t ares_expand_string_ex(const unsigned char *encoded, - const unsigned char *abuf, size_t alen, - unsigned char **s, size_t *enclen) -{ - ares_status_t status; - ares_buf_t *buf = NULL; - size_t start_len; - size_t len = 0; - - if (encoded == NULL || abuf == NULL || alen == 0 || enclen == NULL) { - return ARES_EBADSTR; /* EFORMERR would be better */ - } - - if (encoded < abuf || encoded >= abuf + alen) { - return ARES_EBADSTR; /* EFORMERR would be better */ - } - - *enclen = 0; - - /* NOTE: we allow 's' to be NULL to skip it */ - if (s) { - *s = NULL; - } - - buf = ares_buf_create_const(abuf, alen); - - if (buf == NULL) { - return ARES_ENOMEM; - } - - status = ares_buf_set_position(buf, (size_t)(encoded - abuf)); - if (status != ARES_SUCCESS) { - goto done; - } - - start_len = ares_buf_len(buf); - status = ares_buf_parse_dns_binstr(buf, ares_buf_len(buf), s, &len); - /* hrm, no way to pass back 'len' with the prototype */ - if (status != ARES_SUCCESS) { - goto done; - } - - *enclen = start_len - ares_buf_len(buf); - -done: - ares_buf_destroy(buf); - if (status == ARES_EBADNAME || status == ARES_EBADRESP) { - status = ARES_EBADSTR; - } - return status; -} - -int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, - int alen, unsigned char **s, long *enclen) -{ - ares_status_t status; - size_t temp_enclen = 0; - - if (encoded == NULL || abuf == NULL || alen <= 0 || enclen == NULL) { - return ARES_EBADRESP; - } - - status = ares_expand_string_ex(encoded, abuf, (size_t)alen, s, &temp_enclen); - - *enclen = (long)temp_enclen; - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_fds.c b/vendor/c-ares/src/lib/legacy/ares_fds.c deleted file mode 100644 index 112ebac60..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_fds.c +++ /dev/null @@ -1,80 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -int ares_fds(const ares_channel_t *channel, fd_set *read_fds, fd_set *write_fds) -{ - ares_socket_t nfds; - ares_slist_node_t *snode; - /* Are there any active queries? */ - size_t active_queries; - - if (channel == NULL || read_fds == NULL || write_fds == NULL) { - return 0; - } - - ares_channel_lock(channel); - - active_queries = ares_llist_len(channel->all_queries); - - nfds = 0; - for (snode = ares_slist_node_first(channel->servers); snode != NULL; - snode = ares_slist_node_next(snode)) { - ares_server_t *server = ares_slist_node_val(snode); - ares_llist_node_t *node; - - for (node = ares_llist_node_first(server->connections); node != NULL; - node = ares_llist_node_next(node)) { - const ares_conn_t *conn = ares_llist_node_val(node); - - if (!active_queries && !(conn->flags & ARES_CONN_FLAG_TCP)) { - continue; - } - - /* Silence coverity, shouldn't be possible */ - if (conn->fd == ARES_SOCKET_BAD) { - continue; - } - - /* Always wait on read */ - FD_SET(conn->fd, read_fds); - - if (conn->fd >= nfds) { - nfds = conn->fd + 1; - } - - /* TCP only wait on write if we have the flag set */ - if (conn->state_flags & ARES_CONN_STATE_WRITE) { - FD_SET(conn->fd, write_fds); - } - } - } - - ares_channel_unlock(channel); - return (int)nfds; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_getsock.c b/vendor/c-ares/src/lib/legacy/ares_getsock.c deleted file mode 100644 index cec9258ab..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_getsock.c +++ /dev/null @@ -1,85 +0,0 @@ -/* MIT License - * - * Copyright (c) 2005 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -int ares_getsock(const ares_channel_t *channel, ares_socket_t *socks, - int numsocks) /* size of the 'socks' array */ -{ - ares_slist_node_t *snode; - size_t sockindex = 0; - unsigned int bitmap = 0; - unsigned int setbits = 0xffffffff; - - /* Are there any active queries? */ - size_t active_queries; - - if (channel == NULL || numsocks <= 0) { - return 0; - } - - ares_channel_lock(channel); - - active_queries = ares_llist_len(channel->all_queries); - - for (snode = ares_slist_node_first(channel->servers); snode != NULL; - snode = ares_slist_node_next(snode)) { - ares_server_t *server = ares_slist_node_val(snode); - ares_llist_node_t *node; - - for (node = ares_llist_node_first(server->connections); node != NULL; - node = ares_llist_node_next(node)) { - const ares_conn_t *conn = ares_llist_node_val(node); - - if (sockindex >= (size_t)numsocks || sockindex >= ARES_GETSOCK_MAXNUM) { - break; - } - - /* We only need to register interest in UDP sockets if we have - * outstanding queries. - */ - if (!active_queries && !(conn->flags & ARES_CONN_FLAG_TCP)) { - continue; - } - - socks[sockindex] = conn->fd; - - if (active_queries || conn->flags & ARES_CONN_FLAG_TCP) { - bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); - } - - if (conn->state_flags & ARES_CONN_STATE_WRITE) { - /* then the tcp socket is also writable! */ - bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); - } - - sockindex++; - } - } - - ares_channel_unlock(channel); - return (int)bitmap; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_a_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_a_reply.c deleted file mode 100644 index 9fd4a07ac..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_a_reply.c +++ /dev/null @@ -1,107 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2019 Andrew Selivanov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -int ares_parse_a_reply(const unsigned char *abuf, int alen, - struct hostent **host, struct ares_addrttl *addrttls, - int *naddrttls) -{ - struct ares_addrinfo ai; - char *question_hostname = NULL; - ares_status_t status; - size_t req_naddrttls = 0; - ares_dns_record_t *dnsrec = NULL; - - if (alen < 0) { - return ARES_EBADRESP; - } - - if (naddrttls) { - req_naddrttls = (size_t)*naddrttls; - *naddrttls = 0; - } - - memset(&ai, 0, sizeof(ai)); - - status = ares_dns_parse(abuf, (size_t)alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto fail; - } - - status = ares_parse_into_addrinfo(dnsrec, 0, 0, &ai); - if (status != ARES_SUCCESS && status != ARES_ENODATA) { - goto fail; - } - - if (host != NULL) { - *host = NULL; - status = ares_addrinfo2hostent(&ai, AF_INET, host); - if (status != ARES_SUCCESS && status != ARES_ENODATA) { - goto fail; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - } - - if (addrttls != NULL && req_naddrttls) { - size_t temp_naddrttls = 0; - ares_addrinfo2addrttl(&ai, AF_INET, req_naddrttls, addrttls, NULL, - &temp_naddrttls); - *naddrttls = (int)temp_naddrttls; - } - - -fail: - ares_freeaddrinfo_cnames(ai.cnames); - ares_freeaddrinfo_nodes(ai.nodes); - ares_free(ai.name); - ares_free(question_hostname); - ares_dns_record_destroy(dnsrec); - - if (status == ARES_EBADNAME) { - status = ARES_EBADRESP; - } - - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c deleted file mode 100644 index 4c177ec9c..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +++ /dev/null @@ -1,109 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) 2005 Dominick Meglio - * Copyright (c) 2019 Andrew Selivanov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -#include "ares_inet_net_pton.h" - -int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, - struct hostent **host, struct ares_addr6ttl *addrttls, - int *naddrttls) -{ - struct ares_addrinfo ai; - char *question_hostname = NULL; - ares_status_t status; - size_t req_naddrttls = 0; - ares_dns_record_t *dnsrec = NULL; - - if (alen < 0) { - return ARES_EBADRESP; - } - - if (naddrttls) { - req_naddrttls = (size_t)*naddrttls; - *naddrttls = 0; - } - - memset(&ai, 0, sizeof(ai)); - - status = ares_dns_parse(abuf, (size_t)alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto fail; - } - - status = ares_parse_into_addrinfo(dnsrec, 0, 0, &ai); - if (status != ARES_SUCCESS && status != ARES_ENODATA) { - goto fail; - } - - if (host != NULL) { - *host = NULL; - status = ares_addrinfo2hostent(&ai, AF_INET6, host); - if (status != ARES_SUCCESS && status != ARES_ENODATA) { - goto fail; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - } - - if (addrttls != NULL && req_naddrttls) { - size_t temp_naddrttls = 0; - ares_addrinfo2addrttl(&ai, AF_INET6, req_naddrttls, NULL, addrttls, - &temp_naddrttls); - *naddrttls = (int)temp_naddrttls; - } - -fail: - ares_freeaddrinfo_cnames(ai.cnames); - ares_freeaddrinfo_nodes(ai.nodes); - ares_free(question_hostname); - ares_free(ai.name); - ares_dns_record_destroy(dnsrec); - - if (status == ARES_EBADNAME) { - status = ARES_EBADRESP; - } - - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_caa_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_caa_reply.c deleted file mode 100644 index f74358f45..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_caa_reply.c +++ /dev/null @@ -1,137 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_data.h" - -int ares_parse_caa_reply(const unsigned char *abuf, int alen_int, - struct ares_caa_reply **caa_out) -{ - ares_status_t status; - size_t alen; - struct ares_caa_reply *caa_head = NULL; - struct ares_caa_reply *caa_last = NULL; - struct ares_caa_reply *caa_curr; - ares_dns_record_t *dnsrec = NULL; - size_t i; - - *caa_out = NULL; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) { - status = ARES_ENODATA; - goto done; - } - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const unsigned char *ptr; - size_t ptr_len; - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* XXX: Why do we allow Chaos class? */ - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN && - ares_dns_rr_get_class(rr) != ARES_CLASS_CHAOS) { - continue; - } - - /* Only looking for CAA records */ - if (ares_dns_rr_get_type(rr) != ARES_REC_TYPE_CAA) { - continue; - } - - /* Allocate storage for this CAA answer appending it to the list */ - caa_curr = ares_malloc_data(ARES_DATATYPE_CAA_REPLY); - if (caa_curr == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Link in the record */ - if (caa_last) { - caa_last->next = caa_curr; - } else { - caa_head = caa_curr; - } - caa_last = caa_curr; - - caa_curr->critical = ares_dns_rr_get_u8(rr, ARES_RR_CAA_CRITICAL); - caa_curr->property = - (unsigned char *)ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_CAA_TAG)); - if (caa_curr->property == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - break; /* LCOV_EXCL_LINE: OutOfMemory */ - } - /* RFC6844 says this can only be ascii, so not sure why we're recording a - * length */ - caa_curr->plength = ares_strlen((const char *)caa_curr->property); - - ptr = ares_dns_rr_get_bin(rr, ARES_RR_CAA_VALUE, &ptr_len); - if (ptr == NULL) { - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Wants NULL termination for some reason */ - caa_curr->value = ares_malloc(ptr_len + 1); - if (caa_curr->value == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - memcpy(caa_curr->value, ptr, ptr_len); - caa_curr->value[ptr_len] = 0; - caa_curr->length = ptr_len; - } - -done: - /* clean up on error */ - if (status != ARES_SUCCESS) { - if (caa_head) { - ares_free_data(caa_head); - } - } else { - /* everything looks fine, return the data */ - *caa_out = caa_head; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_mx_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_mx_reply.c deleted file mode 100644 index 480074f67..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_mx_reply.c +++ /dev/null @@ -1,110 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_data.h" - -int ares_parse_mx_reply(const unsigned char *abuf, int alen_int, - struct ares_mx_reply **mx_out) -{ - ares_status_t status; - size_t alen; - struct ares_mx_reply *mx_head = NULL; - struct ares_mx_reply *mx_last = NULL; - struct ares_mx_reply *mx_curr; - ares_dns_record_t *dnsrec = NULL; - size_t i; - - *mx_out = NULL; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) { - status = ARES_ENODATA; - goto done; - } - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN || - ares_dns_rr_get_type(rr) != ARES_REC_TYPE_MX) { - continue; - } - - /* Allocate storage for this MX answer appending it to the list */ - mx_curr = ares_malloc_data(ARES_DATATYPE_MX_REPLY); - if (mx_curr == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Link in the record */ - if (mx_last) { - mx_last->next = mx_curr; - } else { - mx_head = mx_curr; - } - mx_last = mx_curr; - - mx_curr->priority = ares_dns_rr_get_u16(rr, ARES_RR_MX_PREFERENCE); - mx_curr->host = ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_MX_EXCHANGE)); - - if (mx_curr->host == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - -done: - /* clean up on error */ - if (status != ARES_SUCCESS) { - if (mx_head) { - ares_free_data(mx_head); - } - } else { - /* everything looks fine, return the data */ - *mx_out = mx_head; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_naptr_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_naptr_reply.c deleted file mode 100644 index c00ce7106..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +++ /dev/null @@ -1,132 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_data.h" - -int ares_parse_naptr_reply(const unsigned char *abuf, int alen_int, - struct ares_naptr_reply **naptr_out) -{ - ares_status_t status; - size_t alen; - struct ares_naptr_reply *naptr_head = NULL; - struct ares_naptr_reply *naptr_last = NULL; - struct ares_naptr_reply *naptr_curr; - ares_dns_record_t *dnsrec = NULL; - size_t i; - - *naptr_out = NULL; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) { - status = ARES_ENODATA; - goto done; - } - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN || - ares_dns_rr_get_type(rr) != ARES_REC_TYPE_NAPTR) { - continue; - } - - /* Allocate storage for this NAPTR answer appending it to the list */ - naptr_curr = ares_malloc_data(ARES_DATATYPE_NAPTR_REPLY); - if (naptr_curr == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Link in the record */ - if (naptr_last) { - naptr_last->next = naptr_curr; - } else { - naptr_head = naptr_curr; - } - naptr_last = naptr_curr; - - naptr_curr->order = ares_dns_rr_get_u16(rr, ARES_RR_NAPTR_ORDER); - naptr_curr->preference = ares_dns_rr_get_u16(rr, ARES_RR_NAPTR_PREFERENCE); - - /* XXX: Why is this unsigned char * ? */ - naptr_curr->flags = (unsigned char *)ares_strdup( - ares_dns_rr_get_str(rr, ARES_RR_NAPTR_FLAGS)); - if (naptr_curr->flags == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - /* XXX: Why is this unsigned char * ? */ - naptr_curr->service = (unsigned char *)ares_strdup( - ares_dns_rr_get_str(rr, ARES_RR_NAPTR_SERVICES)); - if (naptr_curr->service == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - /* XXX: Why is this unsigned char * ? */ - naptr_curr->regexp = (unsigned char *)ares_strdup( - ares_dns_rr_get_str(rr, ARES_RR_NAPTR_REGEXP)); - if (naptr_curr->regexp == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - naptr_curr->replacement = - ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_NAPTR_REPLACEMENT)); - if (naptr_curr->replacement == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - -done: - /* clean up on error */ - if (status != ARES_SUCCESS) { - if (naptr_head) { - ares_free_data(naptr_head); - } - } else { - /* everything looks fine, return the data */ - *naptr_out = naptr_head; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_ns_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_ns_reply.c deleted file mode 100644 index fc9ab9219..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_ns_reply.c +++ /dev/null @@ -1,154 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -int ares_parse_ns_reply(const unsigned char *abuf, int alen_int, - struct hostent **host) -{ - ares_status_t status; - size_t alen; - size_t nscount = 0; - struct hostent *hostent = NULL; - const char *hostname = NULL; - ares_dns_record_t *dnsrec = NULL; - size_t i; - size_t ancount; - - *host = NULL; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - if (ancount == 0) { - status = ARES_ENODATA; - goto done; - } - - /* Response structure */ - hostent = ares_malloc(sizeof(*hostent)); - if (hostent == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - memset(hostent, 0, sizeof(*hostent)); - - hostent->h_addr_list = ares_malloc(sizeof(*hostent->h_addr_list)); - if (hostent->h_addr_list == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - hostent->h_addr_list[0] = NULL; - hostent->h_addrtype = AF_INET; - hostent->h_length = sizeof(struct in_addr); - - /* Fill in hostname */ - status = ares_dns_record_query_get(dnsrec, 0, &hostname, NULL, NULL); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - hostent->h_name = ares_strdup(hostname); - if (hostent->h_name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Preallocate the maximum number + 1 */ - hostent->h_aliases = ares_malloc((ancount + 1) * sizeof(*hostent->h_aliases)); - if (hostent->h_aliases == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - memset(hostent->h_aliases, 0, (ancount + 1) * sizeof(*hostent->h_aliases)); - - for (i = 0; i < ancount; i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN || - ares_dns_rr_get_type(rr) != ARES_REC_TYPE_NS) { - continue; - } - - hostname = ares_dns_rr_get_str(rr, ARES_RR_NS_NSDNAME); - if (hostname == NULL) { - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - hostent->h_aliases[nscount] = ares_strdup(hostname); - if (hostent->h_aliases[nscount] == NULL) { - status = ARES_ENOMEM; - goto done; - } - nscount++; - } - - if (nscount == 0) { - status = ARES_ENODATA; - } else { - status = ARES_SUCCESS; - } - -done: - if (status != ARES_SUCCESS) { - ares_free_hostent(hostent); - /* Compatibility */ - if (status == ARES_EBADNAME) { - status = ARES_EBADRESP; - } - } else { - *host = hostent; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_ptr_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_ptr_reply.c deleted file mode 100644 index 0e52f9db0..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +++ /dev/null @@ -1,213 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif - - -ares_status_t ares_parse_ptr_reply_dnsrec(const ares_dns_record_t *dnsrec, - const void *addr, int addrlen, - int family, struct hostent **host) -{ - ares_status_t status; - size_t ptrcount = 0; - struct hostent *hostent = NULL; - const char *hostname = NULL; - const char *ptrname = NULL; - size_t i; - size_t ancount; - - *host = NULL; - - /* Fetch name from query as we will use it to compare later on. Old code - * did this check, so we'll retain it. */ - status = ares_dns_record_query_get(dnsrec, 0, &ptrname, NULL, NULL); - if (status != ARES_SUCCESS) { - goto done; - } - - ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - if (ancount == 0) { - status = ARES_ENODATA; - goto done; - } - - /* Response structure */ - hostent = ares_malloc(sizeof(*hostent)); - if (hostent == NULL) { - status = ARES_ENOMEM; - goto done; - } - - memset(hostent, 0, sizeof(*hostent)); - - hostent->h_addr_list = ares_malloc(2 * sizeof(*hostent->h_addr_list)); - if (hostent->h_addr_list == NULL) { - status = ARES_ENOMEM; - goto done; - } - memset(hostent->h_addr_list, 0, 2 * sizeof(*hostent->h_addr_list)); - if (addr != NULL && addrlen > 0) { - hostent->h_addr_list[0] = ares_malloc((size_t)addrlen); - if (hostent->h_addr_list[0] == NULL) { - status = ARES_ENOMEM; - goto done; - } - memcpy(hostent->h_addr_list[0], addr, (size_t)addrlen); - } - hostent->h_addrtype = (HOSTENT_ADDRTYPE_TYPE)family; - hostent->h_length = (HOSTENT_LENGTH_TYPE)addrlen; - - /* Preallocate the maximum number + 1 */ - hostent->h_aliases = ares_malloc((ancount + 1) * sizeof(*hostent->h_aliases)); - if (hostent->h_aliases == NULL) { - status = ARES_ENOMEM; - goto done; - } - memset(hostent->h_aliases, 0, (ancount + 1) * sizeof(*hostent->h_aliases)); - - - /* Cycle through answers */ - for (i = 0; i < ancount; i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get_const(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN) { - continue; - } - - /* Any time we see a CNAME, replace our ptrname with its value */ - if (ares_dns_rr_get_type(rr) == ARES_REC_TYPE_CNAME) { - ptrname = ares_dns_rr_get_str(rr, ARES_RR_CNAME_CNAME); - if (ptrname == NULL) { - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - } - - /* Handling for PTR records below this, otherwise skip */ - if (ares_dns_rr_get_type(rr) != ARES_REC_TYPE_PTR) { - continue; - } - - /* Issue #683 - * Old code compared the name in the rr to the ptrname, but I think this - * is wrong since it was proven wrong for A & AAAA records. Leaving - * this code commented out for future reference - * - * rname = ares_dns_rr_get_name(rr); - * if (rname == NULL) { - * status = ARES_EBADRESP; - * goto done; - * } - * if (!ares_strcaseeq(ptrname, rname)) { - * continue; - * } - */ - - /* Save most recent PTR record as the hostname */ - hostname = ares_dns_rr_get_str(rr, ARES_RR_PTR_DNAME); - if (hostname == NULL) { - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Append as an alias */ - hostent->h_aliases[ptrcount] = ares_strdup(hostname); - if (hostent->h_aliases[ptrcount] == NULL) { - status = ARES_ENOMEM; - goto done; - } - ptrcount++; - } - - if (ptrcount == 0) { - status = ARES_ENODATA; - goto done; - } else { - status = ARES_SUCCESS; - } - - /* Fill in hostname */ - hostent->h_name = ares_strdup(hostname); - if (hostent->h_name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - -done: - if (status != ARES_SUCCESS) { - ares_free_hostent(hostent); - /* Compatibility */ - if (status == ARES_EBADNAME) { - status = ARES_EBADRESP; - } - } else { - *host = hostent; - } - return status; -} - -int ares_parse_ptr_reply(const unsigned char *abuf, int alen_int, - const void *addr, int addrlen, int family, - struct hostent **host) -{ - size_t alen; - ares_dns_record_t *dnsrec = NULL; - ares_status_t status; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_parse_ptr_reply_dnsrec(dnsrec, addr, addrlen, family, host); - -done: - ares_dns_record_destroy(dnsrec); - if (status == ARES_EBADNAME) { - status = ARES_EBADRESP; - } - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_soa_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_soa_reply.c deleted file mode 100644 index 46b40dedc..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_soa_reply.c +++ /dev/null @@ -1,115 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_data.h" - -int ares_parse_soa_reply(const unsigned char *abuf, int alen_int, - struct ares_soa_reply **soa_out) -{ - ares_status_t status; - size_t alen; - struct ares_soa_reply *soa = NULL; - ares_dns_record_t *dnsrec = NULL; - size_t i; - - *soa_out = NULL; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) { - status = ARES_EBADRESP; /* ENODATA might make more sense */ - goto done; - } - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN || - ares_dns_rr_get_type(rr) != ARES_REC_TYPE_SOA) { - continue; - } - - /* allocate result struct */ - soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY); - if (soa == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - soa->serial = ares_dns_rr_get_u32(rr, ARES_RR_SOA_SERIAL); - soa->refresh = ares_dns_rr_get_u32(rr, ARES_RR_SOA_REFRESH); - soa->retry = ares_dns_rr_get_u32(rr, ARES_RR_SOA_RETRY); - soa->expire = ares_dns_rr_get_u32(rr, ARES_RR_SOA_EXPIRE); - soa->minttl = ares_dns_rr_get_u32(rr, ARES_RR_SOA_MINIMUM); - soa->nsname = ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_SOA_MNAME)); - if (soa->nsname == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - soa->hostmaster = ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_SOA_RNAME)); - if (soa->hostmaster == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - break; - } - - if (soa == NULL) { - status = ARES_EBADRESP; - } - -done: - /* clean up on error */ - if (status != ARES_SUCCESS) { - ares_free_data(soa); - /* Compatibility */ - if (status == ARES_EBADNAME) { - status = ARES_EBADRESP; - } - } else { - /* everything looks fine, return the data */ - *soa_out = soa; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_srv_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_srv_reply.c deleted file mode 100644 index 3f9fd95eb..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_srv_reply.c +++ /dev/null @@ -1,114 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_data.h" - -int ares_parse_srv_reply(const unsigned char *abuf, int alen_int, - struct ares_srv_reply **srv_out) -{ - ares_status_t status; - size_t alen; - struct ares_srv_reply *srv_head = NULL; - struct ares_srv_reply *srv_last = NULL; - struct ares_srv_reply *srv_curr; - ares_dns_record_t *dnsrec = NULL; - size_t i; - - *srv_out = NULL; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) { - status = ARES_ENODATA; - goto done; - } - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN || - ares_dns_rr_get_type(rr) != ARES_REC_TYPE_SRV) { - continue; - } - - /* Allocate storage for this SRV answer appending it to the list */ - srv_curr = ares_malloc_data(ARES_DATATYPE_SRV_REPLY); - if (srv_curr == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Link in the record */ - if (srv_last) { - srv_last->next = srv_curr; - } else { - srv_head = srv_curr; - } - srv_last = srv_curr; - - - srv_curr->priority = ares_dns_rr_get_u16(rr, ARES_RR_SRV_PRIORITY); - srv_curr->weight = ares_dns_rr_get_u16(rr, ARES_RR_SRV_WEIGHT); - srv_curr->port = ares_dns_rr_get_u16(rr, ARES_RR_SRV_PORT); - - srv_curr->host = ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_SRV_TARGET)); - - if (srv_curr->host == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - -done: - /* clean up on error */ - if (status != ARES_SUCCESS) { - if (srv_head) { - ares_free_data(srv_head); - } - } else { - /* everything looks fine, return the data */ - *srv_out = srv_head; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_txt_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_txt_reply.c deleted file mode 100644 index d276f6ab3..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_txt_reply.c +++ /dev/null @@ -1,144 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_data.h" - -static int ares_parse_txt_reply_int(const unsigned char *abuf, size_t alen, - ares_bool_t ex, void **txt_out) -{ - ares_status_t status; - struct ares_txt_ext *txt_head = NULL; - struct ares_txt_ext *txt_last = NULL; - struct ares_txt_ext *txt_curr; - ares_dns_record_t *dnsrec = NULL; - size_t i; - - *txt_out = NULL; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) { - status = ARES_ENODATA; - goto done; - } - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - size_t j; - size_t cnt; - - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* XXX: Why Chaos? */ - if ((ares_dns_rr_get_class(rr) != ARES_CLASS_IN && - ares_dns_rr_get_class(rr) != ARES_CLASS_CHAOS) || - ares_dns_rr_get_type(rr) != ARES_REC_TYPE_TXT) { - continue; - } - - cnt = ares_dns_rr_get_abin_cnt(rr, ARES_RR_TXT_DATA); - - for (j = 0; j < cnt; j++) { - const unsigned char *ptr; - size_t ptr_len; - - /* Allocate storage for this TXT answer appending it to the list */ - txt_curr = - ares_malloc_data(ex ? ARES_DATATYPE_TXT_EXT : ARES_DATATYPE_TXT_REPLY); - if (txt_curr == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Link in the record */ - if (txt_last) { - txt_last->next = txt_curr; - } else { - txt_head = txt_curr; - } - txt_last = txt_curr; - - /* Tag start on first for each TXT record */ - if (ex && j == 0) { - txt_curr->record_start = 1; - } - - ptr = ares_dns_rr_get_abin(rr, ARES_RR_TXT_DATA, j, &ptr_len); - - txt_curr->txt = ares_malloc(ptr_len + 1); - if (txt_curr->txt == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - memcpy(txt_curr->txt, ptr, ptr_len); - txt_curr->txt[ptr_len] = 0; - txt_curr->length = ptr_len; - } - } - -done: - /* clean up on error */ - if (status != ARES_SUCCESS) { - if (txt_head) { - ares_free_data(txt_head); - } - } else { - /* everything looks fine, return the data */ - *txt_out = txt_head; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} - -int ares_parse_txt_reply(const unsigned char *abuf, int alen, - struct ares_txt_reply **txt_out) -{ - if (alen < 0) { - return ARES_EBADRESP; - } - return ares_parse_txt_reply_int(abuf, (size_t)alen, ARES_FALSE, - (void **)txt_out); -} - -int ares_parse_txt_reply_ext(const unsigned char *abuf, int alen, - struct ares_txt_ext **txt_out) -{ - if (alen < 0) { - return ARES_EBADRESP; - } - return ares_parse_txt_reply_int(abuf, (size_t)alen, ARES_TRUE, - (void **)txt_out); -} diff --git a/vendor/c-ares/src/lib/legacy/ares_parse_uri_reply.c b/vendor/c-ares/src/lib/legacy/ares_parse_uri_reply.c deleted file mode 100644 index 317e204d5..000000000 --- a/vendor/c-ares/src/lib/legacy/ares_parse_uri_reply.c +++ /dev/null @@ -1,113 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_data.h" - -int ares_parse_uri_reply(const unsigned char *abuf, int alen_int, - struct ares_uri_reply **uri_out) -{ - ares_status_t status; - size_t alen; - struct ares_uri_reply *uri_head = NULL; - struct ares_uri_reply *uri_last = NULL; - struct ares_uri_reply *uri_curr; - ares_dns_record_t *dnsrec = NULL; - size_t i; - - *uri_out = NULL; - - if (alen_int < 0) { - return ARES_EBADRESP; - } - - alen = (size_t)alen_int; - - status = ares_dns_parse(abuf, alen, 0, &dnsrec); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) { - status = ARES_ENODATA; - goto done; - } - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i); - - if (rr == NULL) { - /* Shouldn't be possible */ - status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN || - ares_dns_rr_get_type(rr) != ARES_REC_TYPE_URI) { - continue; - } - - /* Allocate storage for this URI answer appending it to the list */ - uri_curr = ares_malloc_data(ARES_DATATYPE_URI_REPLY); - if (uri_curr == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Link in the record */ - if (uri_last) { - uri_last->next = uri_curr; - } else { - uri_head = uri_curr; - } - uri_last = uri_curr; - - - uri_curr->priority = ares_dns_rr_get_u16(rr, ARES_RR_URI_PRIORITY); - uri_curr->weight = ares_dns_rr_get_u16(rr, ARES_RR_URI_WEIGHT); - uri_curr->uri = ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_URI_TARGET)); - uri_curr->ttl = (int)ares_dns_rr_get_ttl(rr); - - if (uri_curr->uri == NULL) { - status = ARES_ENOMEM; - goto done; - } - } - -done: - /* clean up on error */ - if (status != ARES_SUCCESS) { - if (uri_head) { - ares_free_data(uri_head); - } - } else { - /* everything looks fine, return the data */ - *uri_out = uri_head; - } - ares_dns_record_destroy(dnsrec); - return (int)status; -} diff --git a/vendor/c-ares/src/lib/record/ares_dns_mapping.c b/vendor/c-ares/src/lib/record/ares_dns_mapping.c deleted file mode 100644 index 5a3ec28ab..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_mapping.c +++ /dev/null @@ -1,982 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode) -{ - switch (opcode) { - case ARES_OPCODE_QUERY: - case ARES_OPCODE_IQUERY: - case ARES_OPCODE_STATUS: - case ARES_OPCODE_NOTIFY: - case ARES_OPCODE_UPDATE: - return ARES_TRUE; - } - return ARES_FALSE; -} - -ares_bool_t ares_dns_rcode_isvalid(ares_dns_rcode_t rcode) -{ - switch (rcode) { - case ARES_RCODE_NOERROR: - case ARES_RCODE_FORMERR: - case ARES_RCODE_SERVFAIL: - case ARES_RCODE_NXDOMAIN: - case ARES_RCODE_NOTIMP: - case ARES_RCODE_REFUSED: - case ARES_RCODE_YXDOMAIN: - case ARES_RCODE_YXRRSET: - case ARES_RCODE_NXRRSET: - case ARES_RCODE_NOTAUTH: - case ARES_RCODE_NOTZONE: - case ARES_RCODE_DSOTYPEI: - case ARES_RCODE_BADSIG: - case ARES_RCODE_BADKEY: - case ARES_RCODE_BADTIME: - case ARES_RCODE_BADMODE: - case ARES_RCODE_BADNAME: - case ARES_RCODE_BADALG: - case ARES_RCODE_BADTRUNC: - case ARES_RCODE_BADCOOKIE: - return ARES_TRUE; - } - return ARES_FALSE; -} - -ares_bool_t ares_dns_flags_arevalid(unsigned short flags) -{ - unsigned short allflags = ARES_FLAG_QR | ARES_FLAG_AA | ARES_FLAG_TC | - ARES_FLAG_RD | ARES_FLAG_RA | ARES_FLAG_AD | - ARES_FLAG_CD; - - if (flags & ~allflags) { - return ARES_FALSE; - } - - return ARES_TRUE; -} - -ares_bool_t ares_dns_rec_type_isvalid(ares_dns_rec_type_t type, - ares_bool_t is_query) -{ - switch (type) { - case ARES_REC_TYPE_A: - case ARES_REC_TYPE_NS: - case ARES_REC_TYPE_CNAME: - case ARES_REC_TYPE_SOA: - case ARES_REC_TYPE_PTR: - case ARES_REC_TYPE_HINFO: - case ARES_REC_TYPE_MX: - case ARES_REC_TYPE_TXT: - case ARES_REC_TYPE_SIG: - case ARES_REC_TYPE_AAAA: - case ARES_REC_TYPE_SRV: - case ARES_REC_TYPE_NAPTR: - case ARES_REC_TYPE_OPT: - case ARES_REC_TYPE_TLSA: - case ARES_REC_TYPE_SVCB: - case ARES_REC_TYPE_HTTPS: - case ARES_REC_TYPE_ANY: - case ARES_REC_TYPE_URI: - case ARES_REC_TYPE_CAA: - return ARES_TRUE; - case ARES_REC_TYPE_RAW_RR: - return is_query ? ARES_FALSE : ARES_TRUE; - default: - break; - } - return is_query ? ARES_TRUE : ARES_FALSE; -} - -ares_bool_t ares_dns_rec_allow_name_comp(ares_dns_rec_type_t type) -{ - /* Only record types defined in RFC1035 allow name compression within the - * RDATA. Otherwise nameservers that don't understand an RR may not be - * able to pass along the RR in a proper manner */ - switch (type) { - case ARES_REC_TYPE_A: - case ARES_REC_TYPE_NS: - case ARES_REC_TYPE_CNAME: - case ARES_REC_TYPE_SOA: - case ARES_REC_TYPE_PTR: - case ARES_REC_TYPE_HINFO: - case ARES_REC_TYPE_MX: - case ARES_REC_TYPE_TXT: - return ARES_TRUE; - default: - break; - } - return ARES_FALSE; -} - -ares_bool_t ares_dns_class_isvalid(ares_dns_class_t qclass, - ares_dns_rec_type_t type, - ares_bool_t is_query) -{ - /* If we don't understand the record type, we shouldn't validate the class - * as there are some instances like on RFC 2391 (SIG RR) the class is - * meaningless, but since we didn't support that record type, we didn't - * know it shouldn't be validated */ - if (type == ARES_REC_TYPE_RAW_RR) { - return ARES_TRUE; - } - - switch (qclass) { - case ARES_CLASS_IN: - case ARES_CLASS_CHAOS: - case ARES_CLASS_HESOID: - case ARES_CLASS_NONE: - return ARES_TRUE; - case ARES_CLASS_ANY: - if (type == ARES_REC_TYPE_SIG) { - return ARES_TRUE; - } - if (is_query) { - return ARES_TRUE; - } - return ARES_FALSE; - } - return ARES_FALSE; -} - -ares_bool_t ares_dns_section_isvalid(ares_dns_section_t sect) -{ - switch (sect) { - case ARES_SECTION_ANSWER: - case ARES_SECTION_AUTHORITY: - case ARES_SECTION_ADDITIONAL: - return ARES_TRUE; - } - return ARES_FALSE; -} - -ares_dns_rec_type_t ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key) -{ - /* NOTE: due to the way we've numerated the keys, we can simply divide by - * 100 to get the type rather than having to do a huge switch - * statement. That said, we do then validate the type returned is - * valid in case something completely bogus is passed in */ - ares_dns_rec_type_t type = key / 100; - if (!ares_dns_rec_type_isvalid(type, ARES_FALSE)) { - return 0; - } - return type; -} - -const char *ares_dns_rec_type_tostr(ares_dns_rec_type_t type) -{ - switch (type) { - case ARES_REC_TYPE_A: - return "A"; - case ARES_REC_TYPE_NS: - return "NS"; - case ARES_REC_TYPE_CNAME: - return "CNAME"; - case ARES_REC_TYPE_SOA: - return "SOA"; - case ARES_REC_TYPE_PTR: - return "PTR"; - case ARES_REC_TYPE_HINFO: - return "HINFO"; - case ARES_REC_TYPE_MX: - return "MX"; - case ARES_REC_TYPE_TXT: - return "TXT"; - case ARES_REC_TYPE_SIG: - return "SIG"; - case ARES_REC_TYPE_AAAA: - return "AAAA"; - case ARES_REC_TYPE_SRV: - return "SRV"; - case ARES_REC_TYPE_NAPTR: - return "NAPTR"; - case ARES_REC_TYPE_OPT: - return "OPT"; - case ARES_REC_TYPE_TLSA: - return "TLSA"; - case ARES_REC_TYPE_SVCB: - return "SVCB"; - case ARES_REC_TYPE_HTTPS: - return "HTTPS"; - case ARES_REC_TYPE_ANY: - return "ANY"; - case ARES_REC_TYPE_URI: - return "URI"; - case ARES_REC_TYPE_CAA: - return "CAA"; - case ARES_REC_TYPE_RAW_RR: - return "RAWRR"; - } - return "UNKNOWN"; -} - -const char *ares_dns_class_tostr(ares_dns_class_t qclass) -{ - switch (qclass) { - case ARES_CLASS_IN: - return "IN"; - case ARES_CLASS_CHAOS: - return "CH"; - case ARES_CLASS_HESOID: - return "HS"; - case ARES_CLASS_ANY: - return "ANY"; - case ARES_CLASS_NONE: - return "NONE"; - } - return "UNKNOWN"; -} - -const char *ares_dns_opcode_tostr(ares_dns_opcode_t opcode) -{ - switch (opcode) { - case ARES_OPCODE_QUERY: - return "QUERY"; - case ARES_OPCODE_IQUERY: - return "IQUERY"; - case ARES_OPCODE_STATUS: - return "STATUS"; - case ARES_OPCODE_NOTIFY: - return "NOTIFY"; - case ARES_OPCODE_UPDATE: - return "UPDATE"; - } - return "UNKNOWN"; -} - -const char *ares_dns_rr_key_tostr(ares_dns_rr_key_t key) -{ - switch (key) { - case ARES_RR_A_ADDR: - return "ADDR"; - - case ARES_RR_NS_NSDNAME: - return "NSDNAME"; - - case ARES_RR_CNAME_CNAME: - return "CNAME"; - - case ARES_RR_SOA_MNAME: - return "MNAME"; - - case ARES_RR_SOA_RNAME: - return "RNAME"; - - case ARES_RR_SOA_SERIAL: - return "SERIAL"; - - case ARES_RR_SOA_REFRESH: - return "REFRESH"; - - case ARES_RR_SOA_RETRY: - return "RETRY"; - - case ARES_RR_SOA_EXPIRE: - return "EXPIRE"; - - case ARES_RR_SOA_MINIMUM: - return "MINIMUM"; - - case ARES_RR_PTR_DNAME: - return "DNAME"; - - case ARES_RR_AAAA_ADDR: - return "ADDR"; - - case ARES_RR_HINFO_CPU: - return "CPU"; - - case ARES_RR_HINFO_OS: - return "OS"; - - case ARES_RR_MX_PREFERENCE: - return "PREFERENCE"; - - case ARES_RR_MX_EXCHANGE: - return "EXCHANGE"; - - case ARES_RR_TXT_DATA: - return "DATA"; - - case ARES_RR_SIG_TYPE_COVERED: - return "TYPE_COVERED"; - - case ARES_RR_SIG_ALGORITHM: - return "ALGORITHM"; - - case ARES_RR_SIG_LABELS: - return "LABELS"; - - case ARES_RR_SIG_ORIGINAL_TTL: - return "ORIGINAL_TTL"; - - case ARES_RR_SIG_EXPIRATION: - return "EXPIRATION"; - - case ARES_RR_SIG_INCEPTION: - return "INCEPTION"; - - case ARES_RR_SIG_KEY_TAG: - return "KEY_TAG"; - - case ARES_RR_SIG_SIGNERS_NAME: - return "SIGNERS_NAME"; - - case ARES_RR_SIG_SIGNATURE: - return "SIGNATURE"; - - case ARES_RR_SRV_PRIORITY: - return "PRIORITY"; - - case ARES_RR_SRV_WEIGHT: - return "WEIGHT"; - - case ARES_RR_SRV_PORT: - return "PORT"; - - case ARES_RR_SRV_TARGET: - return "TARGET"; - - case ARES_RR_NAPTR_ORDER: - return "ORDER"; - - case ARES_RR_NAPTR_PREFERENCE: - return "PREFERENCE"; - - case ARES_RR_NAPTR_FLAGS: - return "FLAGS"; - - case ARES_RR_NAPTR_SERVICES: - return "SERVICES"; - - case ARES_RR_NAPTR_REGEXP: - return "REGEXP"; - - case ARES_RR_NAPTR_REPLACEMENT: - return "REPLACEMENT"; - - case ARES_RR_OPT_UDP_SIZE: - return "UDP_SIZE"; - - case ARES_RR_OPT_VERSION: - return "VERSION"; - - case ARES_RR_OPT_FLAGS: - return "FLAGS"; - - case ARES_RR_OPT_OPTIONS: - return "OPTIONS"; - - case ARES_RR_TLSA_CERT_USAGE: - return "CERT_USAGE"; - - case ARES_RR_TLSA_SELECTOR: - return "SELECTOR"; - - case ARES_RR_TLSA_MATCH: - return "MATCH"; - - case ARES_RR_TLSA_DATA: - return "DATA"; - - case ARES_RR_SVCB_PRIORITY: - return "PRIORITY"; - - case ARES_RR_SVCB_TARGET: - return "TARGET"; - - case ARES_RR_SVCB_PARAMS: - return "PARAMS"; - - case ARES_RR_HTTPS_PRIORITY: - return "PRIORITY"; - - case ARES_RR_HTTPS_TARGET: - return "TARGET"; - - case ARES_RR_HTTPS_PARAMS: - return "PARAMS"; - - case ARES_RR_URI_PRIORITY: - return "PRIORITY"; - - case ARES_RR_URI_WEIGHT: - return "WEIGHT"; - - case ARES_RR_URI_TARGET: - return "TARGET"; - - case ARES_RR_CAA_CRITICAL: - return "CRITICAL"; - - case ARES_RR_CAA_TAG: - return "TAG"; - - case ARES_RR_CAA_VALUE: - return "VALUE"; - - case ARES_RR_RAW_RR_TYPE: - return "TYPE"; - - case ARES_RR_RAW_RR_DATA: - return "DATA"; - } - - return "UNKNOWN"; -} - -ares_dns_datatype_t ares_dns_rr_key_datatype(ares_dns_rr_key_t key) -{ - switch (key) { - case ARES_RR_A_ADDR: - return ARES_DATATYPE_INADDR; - - case ARES_RR_AAAA_ADDR: - return ARES_DATATYPE_INADDR6; - - case ARES_RR_NS_NSDNAME: - case ARES_RR_CNAME_CNAME: - case ARES_RR_SOA_MNAME: - case ARES_RR_SOA_RNAME: - case ARES_RR_PTR_DNAME: - case ARES_RR_MX_EXCHANGE: - case ARES_RR_SIG_SIGNERS_NAME: - case ARES_RR_SRV_TARGET: - case ARES_RR_SVCB_TARGET: - case ARES_RR_HTTPS_TARGET: - case ARES_RR_NAPTR_REPLACEMENT: - case ARES_RR_URI_TARGET: - return ARES_DATATYPE_NAME; - - case ARES_RR_HINFO_CPU: - case ARES_RR_HINFO_OS: - case ARES_RR_NAPTR_FLAGS: - case ARES_RR_NAPTR_SERVICES: - case ARES_RR_NAPTR_REGEXP: - case ARES_RR_CAA_TAG: - return ARES_DATATYPE_STR; - - case ARES_RR_SOA_SERIAL: - case ARES_RR_SOA_REFRESH: - case ARES_RR_SOA_RETRY: - case ARES_RR_SOA_EXPIRE: - case ARES_RR_SOA_MINIMUM: - case ARES_RR_SIG_ORIGINAL_TTL: - case ARES_RR_SIG_EXPIRATION: - case ARES_RR_SIG_INCEPTION: - return ARES_DATATYPE_U32; - - case ARES_RR_MX_PREFERENCE: - case ARES_RR_SIG_TYPE_COVERED: - case ARES_RR_SIG_KEY_TAG: - case ARES_RR_SRV_PRIORITY: - case ARES_RR_SRV_WEIGHT: - case ARES_RR_SRV_PORT: - case ARES_RR_NAPTR_ORDER: - case ARES_RR_NAPTR_PREFERENCE: - case ARES_RR_OPT_UDP_SIZE: - case ARES_RR_OPT_FLAGS: - case ARES_RR_SVCB_PRIORITY: - case ARES_RR_HTTPS_PRIORITY: - case ARES_RR_URI_PRIORITY: - case ARES_RR_URI_WEIGHT: - case ARES_RR_RAW_RR_TYPE: - return ARES_DATATYPE_U16; - - case ARES_RR_SIG_ALGORITHM: - case ARES_RR_SIG_LABELS: - case ARES_RR_OPT_VERSION: - case ARES_RR_TLSA_CERT_USAGE: - case ARES_RR_TLSA_SELECTOR: - case ARES_RR_TLSA_MATCH: - case ARES_RR_CAA_CRITICAL: - return ARES_DATATYPE_U8; - - case ARES_RR_CAA_VALUE: - return ARES_DATATYPE_BINP; - - case ARES_RR_TXT_DATA: - return ARES_DATATYPE_ABINP; - - case ARES_RR_SIG_SIGNATURE: - case ARES_RR_TLSA_DATA: - case ARES_RR_RAW_RR_DATA: - return ARES_DATATYPE_BIN; - - case ARES_RR_OPT_OPTIONS: - case ARES_RR_SVCB_PARAMS: - case ARES_RR_HTTPS_PARAMS: - return ARES_DATATYPE_OPT; - } - - return 0; -} - -static const ares_dns_rr_key_t rr_a_keys[] = { ARES_RR_A_ADDR }; -static const ares_dns_rr_key_t rr_ns_keys[] = { ARES_RR_NS_NSDNAME }; -static const ares_dns_rr_key_t rr_cname_keys[] = { ARES_RR_CNAME_CNAME }; -static const ares_dns_rr_key_t rr_soa_keys[] = { - ARES_RR_SOA_MNAME, ARES_RR_SOA_RNAME, ARES_RR_SOA_SERIAL, - ARES_RR_SOA_REFRESH, ARES_RR_SOA_RETRY, ARES_RR_SOA_EXPIRE, - ARES_RR_SOA_MINIMUM -}; -static const ares_dns_rr_key_t rr_ptr_keys[] = { ARES_RR_PTR_DNAME }; -static const ares_dns_rr_key_t rr_hinfo_keys[] = { ARES_RR_HINFO_CPU, - ARES_RR_HINFO_OS }; -static const ares_dns_rr_key_t rr_mx_keys[] = { ARES_RR_MX_PREFERENCE, - ARES_RR_MX_EXCHANGE }; -static const ares_dns_rr_key_t rr_sig_keys[] = { - ARES_RR_SIG_TYPE_COVERED, ARES_RR_SIG_ALGORITHM, ARES_RR_SIG_LABELS, - ARES_RR_SIG_ORIGINAL_TTL, ARES_RR_SIG_EXPIRATION, ARES_RR_SIG_INCEPTION, - ARES_RR_SIG_KEY_TAG, ARES_RR_SIG_SIGNERS_NAME, ARES_RR_SIG_SIGNATURE -}; -static const ares_dns_rr_key_t rr_txt_keys[] = { ARES_RR_TXT_DATA }; -static const ares_dns_rr_key_t rr_aaaa_keys[] = { ARES_RR_AAAA_ADDR }; -static const ares_dns_rr_key_t rr_srv_keys[] = { - ARES_RR_SRV_PRIORITY, ARES_RR_SRV_WEIGHT, ARES_RR_SRV_PORT, ARES_RR_SRV_TARGET -}; -static const ares_dns_rr_key_t rr_naptr_keys[] = { - ARES_RR_NAPTR_ORDER, ARES_RR_NAPTR_PREFERENCE, ARES_RR_NAPTR_FLAGS, - ARES_RR_NAPTR_SERVICES, ARES_RR_NAPTR_REGEXP, ARES_RR_NAPTR_REPLACEMENT -}; -static const ares_dns_rr_key_t rr_opt_keys[] = { ARES_RR_OPT_UDP_SIZE, - ARES_RR_OPT_VERSION, - ARES_RR_OPT_FLAGS, - ARES_RR_OPT_OPTIONS }; -static const ares_dns_rr_key_t rr_tlsa_keys[] = { ARES_RR_TLSA_CERT_USAGE, - ARES_RR_TLSA_SELECTOR, - ARES_RR_TLSA_MATCH, - ARES_RR_TLSA_DATA }; -static const ares_dns_rr_key_t rr_svcb_keys[] = { ARES_RR_SVCB_PRIORITY, - ARES_RR_SVCB_TARGET, - ARES_RR_SVCB_PARAMS }; -static const ares_dns_rr_key_t rr_https_keys[] = { ARES_RR_HTTPS_PRIORITY, - ARES_RR_HTTPS_TARGET, - ARES_RR_HTTPS_PARAMS }; -static const ares_dns_rr_key_t rr_uri_keys[] = { ARES_RR_URI_PRIORITY, - ARES_RR_URI_WEIGHT, - ARES_RR_URI_TARGET }; -static const ares_dns_rr_key_t rr_caa_keys[] = { ARES_RR_CAA_CRITICAL, - ARES_RR_CAA_TAG, - ARES_RR_CAA_VALUE }; -static const ares_dns_rr_key_t rr_raw_rr_keys[] = { ARES_RR_RAW_RR_TYPE, - ARES_RR_RAW_RR_DATA }; - -const ares_dns_rr_key_t *ares_dns_rr_get_keys(ares_dns_rec_type_t type, - size_t *cnt) -{ - if (cnt == NULL) { - return NULL; - } - - *cnt = 0; - - switch (type) { - case ARES_REC_TYPE_A: - *cnt = sizeof(rr_a_keys) / sizeof(*rr_a_keys); - return rr_a_keys; - case ARES_REC_TYPE_NS: - *cnt = sizeof(rr_ns_keys) / sizeof(*rr_ns_keys); - return rr_ns_keys; - case ARES_REC_TYPE_CNAME: - *cnt = sizeof(rr_cname_keys) / sizeof(*rr_cname_keys); - return rr_cname_keys; - case ARES_REC_TYPE_SOA: - *cnt = sizeof(rr_soa_keys) / sizeof(*rr_soa_keys); - return rr_soa_keys; - case ARES_REC_TYPE_PTR: - *cnt = sizeof(rr_ptr_keys) / sizeof(*rr_ptr_keys); - return rr_ptr_keys; - case ARES_REC_TYPE_HINFO: - *cnt = sizeof(rr_hinfo_keys) / sizeof(*rr_hinfo_keys); - return rr_hinfo_keys; - case ARES_REC_TYPE_MX: - *cnt = sizeof(rr_mx_keys) / sizeof(*rr_mx_keys); - return rr_mx_keys; - case ARES_REC_TYPE_TXT: - *cnt = sizeof(rr_txt_keys) / sizeof(*rr_txt_keys); - return rr_txt_keys; - case ARES_REC_TYPE_SIG: - *cnt = sizeof(rr_sig_keys) / sizeof(*rr_sig_keys); - return rr_sig_keys; - case ARES_REC_TYPE_AAAA: - *cnt = sizeof(rr_aaaa_keys) / sizeof(*rr_aaaa_keys); - return rr_aaaa_keys; - case ARES_REC_TYPE_SRV: - *cnt = sizeof(rr_srv_keys) / sizeof(*rr_srv_keys); - return rr_srv_keys; - case ARES_REC_TYPE_NAPTR: - *cnt = sizeof(rr_naptr_keys) / sizeof(*rr_naptr_keys); - return rr_naptr_keys; - case ARES_REC_TYPE_OPT: - *cnt = sizeof(rr_opt_keys) / sizeof(*rr_opt_keys); - return rr_opt_keys; - case ARES_REC_TYPE_TLSA: - *cnt = sizeof(rr_tlsa_keys) / sizeof(*rr_tlsa_keys); - return rr_tlsa_keys; - case ARES_REC_TYPE_SVCB: - *cnt = sizeof(rr_svcb_keys) / sizeof(*rr_svcb_keys); - return rr_svcb_keys; - case ARES_REC_TYPE_HTTPS: - *cnt = sizeof(rr_https_keys) / sizeof(*rr_https_keys); - return rr_https_keys; - case ARES_REC_TYPE_ANY: - /* Not real */ - break; - case ARES_REC_TYPE_URI: - *cnt = sizeof(rr_uri_keys) / sizeof(*rr_uri_keys); - return rr_uri_keys; - case ARES_REC_TYPE_CAA: - *cnt = sizeof(rr_caa_keys) / sizeof(*rr_caa_keys); - return rr_caa_keys; - case ARES_REC_TYPE_RAW_RR: - *cnt = sizeof(rr_raw_rr_keys) / sizeof(*rr_raw_rr_keys); - return rr_raw_rr_keys; - } - - return NULL; -} - -ares_bool_t ares_dns_class_fromstr(ares_dns_class_t *qclass, const char *str) -{ - size_t i; - - static const struct { - const char *name; - ares_dns_class_t qclass; - } list[] = { - { "IN", ARES_CLASS_IN }, - { "CH", ARES_CLASS_CHAOS }, - { "HS", ARES_CLASS_HESOID }, - { "NONE", ARES_CLASS_NONE }, - { "ANY", ARES_CLASS_ANY }, - { NULL, 0 } - }; - - if (qclass == NULL || str == NULL) { - return ARES_FALSE; - } - - for (i = 0; list[i].name != NULL; i++) { - if (ares_strcaseeq(list[i].name, str)) { - *qclass = list[i].qclass; - return ARES_TRUE; - } - } - return ARES_FALSE; -} - -ares_bool_t ares_dns_rec_type_fromstr(ares_dns_rec_type_t *qtype, - const char *str) -{ - size_t i; - - static const struct { - const char *name; - ares_dns_rec_type_t type; - } list[] = { - { "A", ARES_REC_TYPE_A }, - { "NS", ARES_REC_TYPE_NS }, - { "CNAME", ARES_REC_TYPE_CNAME }, - { "SOA", ARES_REC_TYPE_SOA }, - { "PTR", ARES_REC_TYPE_PTR }, - { "HINFO", ARES_REC_TYPE_HINFO }, - { "MX", ARES_REC_TYPE_MX }, - { "TXT", ARES_REC_TYPE_TXT }, - { "SIG", ARES_REC_TYPE_SIG }, - { "AAAA", ARES_REC_TYPE_AAAA }, - { "SRV", ARES_REC_TYPE_SRV }, - { "NAPTR", ARES_REC_TYPE_NAPTR }, - { "OPT", ARES_REC_TYPE_OPT }, - { "TLSA", ARES_REC_TYPE_TLSA }, - { "SVCB", ARES_REC_TYPE_SVCB }, - { "HTTPS", ARES_REC_TYPE_HTTPS }, - { "ANY", ARES_REC_TYPE_ANY }, - { "URI", ARES_REC_TYPE_URI }, - { "CAA", ARES_REC_TYPE_CAA }, - { "RAW_RR", ARES_REC_TYPE_RAW_RR }, - { NULL, 0 } - }; - - if (qtype == NULL || str == NULL) { - return ARES_FALSE; - } - - for (i = 0; list[i].name != NULL; i++) { - if (ares_strcaseeq(list[i].name, str)) { - *qtype = list[i].type; - return ARES_TRUE; - } - } - return ARES_FALSE; -} - -const char *ares_dns_section_tostr(ares_dns_section_t section) -{ - switch (section) { - case ARES_SECTION_ANSWER: - return "ANSWER"; - case ARES_SECTION_AUTHORITY: - return "AUTHORITY"; - case ARES_SECTION_ADDITIONAL: - return "ADDITIONAL"; - } - return "UNKNOWN"; -} - -static ares_dns_opt_datatype_t ares_dns_opt_get_type_opt(unsigned short opt) -{ - ares_opt_param_t param = (ares_opt_param_t)opt; - switch (param) { - case ARES_OPT_PARAM_LLQ: - /* Really it is u16 version, u16 opcode, u16 error, u64 id, u32 lease */ - return ARES_OPT_DATATYPE_BIN; - case ARES_OPT_PARAM_UL: - return ARES_OPT_DATATYPE_U32; - case ARES_OPT_PARAM_NSID: - return ARES_OPT_DATATYPE_BIN; - case ARES_OPT_PARAM_DAU: - return ARES_OPT_DATATYPE_U8_LIST; - case ARES_OPT_PARAM_DHU: - return ARES_OPT_DATATYPE_U8_LIST; - case ARES_OPT_PARAM_N3U: - return ARES_OPT_DATATYPE_U8_LIST; - case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET: - /* Really it is a u16 address family, u8 source prefix length, - * u8 scope prefix length, address */ - return ARES_OPT_DATATYPE_BIN; - case ARES_OPT_PARAM_EDNS_EXPIRE: - return ARES_OPT_DATATYPE_U32; - case ARES_OPT_PARAM_COOKIE: - /* 8 bytes for client, 16-40 bytes for server */ - return ARES_OPT_DATATYPE_BIN; - case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE: - /* Timeout in 100ms intervals */ - return ARES_OPT_DATATYPE_U16; - case ARES_OPT_PARAM_PADDING: - /* Arbitrary padding */ - return ARES_OPT_DATATYPE_BIN; - case ARES_OPT_PARAM_CHAIN: - return ARES_OPT_DATATYPE_NAME; - case ARES_OPT_PARAM_EDNS_KEY_TAG: - return ARES_OPT_DATATYPE_U16_LIST; - case ARES_OPT_PARAM_EXTENDED_DNS_ERROR: - /* Really 16bit code followed by textual message */ - return ARES_OPT_DATATYPE_BIN; - } - return ARES_OPT_DATATYPE_BIN; -} - -static ares_dns_opt_datatype_t ares_dns_opt_get_type_svcb(unsigned short opt) -{ - ares_svcb_param_t param = (ares_svcb_param_t)opt; - switch (param) { - case ARES_SVCB_PARAM_NO_DEFAULT_ALPN: - return ARES_OPT_DATATYPE_NONE; - case ARES_SVCB_PARAM_ECH: - return ARES_OPT_DATATYPE_BIN; - case ARES_SVCB_PARAM_MANDATORY: - return ARES_OPT_DATATYPE_U16_LIST; - case ARES_SVCB_PARAM_ALPN: - return ARES_OPT_DATATYPE_STR_LIST; - case ARES_SVCB_PARAM_PORT: - return ARES_OPT_DATATYPE_U16; - case ARES_SVCB_PARAM_IPV4HINT: - return ARES_OPT_DATATYPE_INADDR4_LIST; - case ARES_SVCB_PARAM_IPV6HINT: - return ARES_OPT_DATATYPE_INADDR6_LIST; - } - return ARES_OPT_DATATYPE_BIN; -} - -ares_dns_opt_datatype_t ares_dns_opt_get_datatype(ares_dns_rr_key_t key, - unsigned short opt) -{ - switch (key) { - case ARES_RR_OPT_OPTIONS: - return ares_dns_opt_get_type_opt(opt); - case ARES_RR_SVCB_PARAMS: - case ARES_RR_HTTPS_PARAMS: - return ares_dns_opt_get_type_svcb(opt); - default: - break; - } - return ARES_OPT_DATATYPE_BIN; -} - -static const char *ares_dns_opt_get_name_opt(unsigned short opt) -{ - ares_opt_param_t param = (ares_opt_param_t)opt; - switch (param) { - case ARES_OPT_PARAM_LLQ: - return "LLQ"; - case ARES_OPT_PARAM_UL: - return "UL"; - case ARES_OPT_PARAM_NSID: - return "NSID"; - case ARES_OPT_PARAM_DAU: - return "DAU"; - case ARES_OPT_PARAM_DHU: - return "DHU"; - case ARES_OPT_PARAM_N3U: - return "N3U"; - case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET: - return "edns-client-subnet"; - case ARES_OPT_PARAM_EDNS_EXPIRE: - return "edns-expire"; - case ARES_OPT_PARAM_COOKIE: - return "COOKIE"; - case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE: - return "edns-tcp-keepalive"; - case ARES_OPT_PARAM_PADDING: - return "Padding"; - case ARES_OPT_PARAM_CHAIN: - return "CHAIN"; - case ARES_OPT_PARAM_EDNS_KEY_TAG: - return "edns-key-tag"; - case ARES_OPT_PARAM_EXTENDED_DNS_ERROR: - return "extended-dns-error"; - } - return NULL; -} - -static const char *ares_dns_opt_get_name_svcb(unsigned short opt) -{ - ares_svcb_param_t param = (ares_svcb_param_t)opt; - switch (param) { - case ARES_SVCB_PARAM_NO_DEFAULT_ALPN: - return "no-default-alpn"; - case ARES_SVCB_PARAM_ECH: - return "ech"; - case ARES_SVCB_PARAM_MANDATORY: - return "mandatory"; - case ARES_SVCB_PARAM_ALPN: - return "alpn"; - case ARES_SVCB_PARAM_PORT: - return "port"; - case ARES_SVCB_PARAM_IPV4HINT: - return "ipv4hint"; - case ARES_SVCB_PARAM_IPV6HINT: - return "ipv6hint"; - } - return NULL; -} - -const char *ares_dns_opt_get_name(ares_dns_rr_key_t key, unsigned short opt) -{ - switch (key) { - case ARES_RR_OPT_OPTIONS: - return ares_dns_opt_get_name_opt(opt); - case ARES_RR_SVCB_PARAMS: - case ARES_RR_HTTPS_PARAMS: - return ares_dns_opt_get_name_svcb(opt); - default: - break; - } - return NULL; -} - -const char *ares_dns_rcode_tostr(ares_dns_rcode_t rcode) -{ - switch (rcode) { - case ARES_RCODE_NOERROR: - return "NOERROR"; - case ARES_RCODE_FORMERR: - return "FORMERR"; - case ARES_RCODE_SERVFAIL: - return "SERVFAIL"; - case ARES_RCODE_NXDOMAIN: - return "NXDOMAIN"; - case ARES_RCODE_NOTIMP: - return "NOTIMP"; - case ARES_RCODE_REFUSED: - return "REFUSED"; - case ARES_RCODE_YXDOMAIN: - return "YXDOMAIN"; - case ARES_RCODE_YXRRSET: - return "YXRRSET"; - case ARES_RCODE_NXRRSET: - return "NXRRSET"; - case ARES_RCODE_NOTAUTH: - return "NOTAUTH"; - case ARES_RCODE_NOTZONE: - return "NOTZONE"; - case ARES_RCODE_DSOTYPEI: - return "DSOTYPEI"; - case ARES_RCODE_BADSIG: - return "BADSIG"; - case ARES_RCODE_BADKEY: - return "BADKEY"; - case ARES_RCODE_BADTIME: - return "BADTIME"; - case ARES_RCODE_BADMODE: - return "BADMODE"; - case ARES_RCODE_BADNAME: - return "BADNAME"; - case ARES_RCODE_BADALG: - return "BADALG"; - case ARES_RCODE_BADTRUNC: - return "BADTRUNC"; - case ARES_RCODE_BADCOOKIE: - return "BADCOOKIE"; - } - - return "UNKNOWN"; -} - -/* Convert an rcode and ancount from a query reply into an ares_status_t - * value. Used internally by ares_search() and ares_query(). - */ -ares_status_t ares_dns_query_reply_tostatus(ares_dns_rcode_t rcode, - size_t ancount) -{ - ares_status_t status = ARES_SUCCESS; - - switch (rcode) { - case ARES_RCODE_NOERROR: - status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA; - break; - case ARES_RCODE_FORMERR: - status = ARES_EFORMERR; - break; - case ARES_RCODE_SERVFAIL: - status = ARES_ESERVFAIL; - break; - case ARES_RCODE_NXDOMAIN: - status = ARES_ENOTFOUND; - break; - case ARES_RCODE_NOTIMP: - status = ARES_ENOTIMP; - break; - case ARES_RCODE_REFUSED: - status = ARES_EREFUSED; - break; - default: - break; - } - - return status; -} diff --git a/vendor/c-ares/src/lib/record/ares_dns_multistring.c b/vendor/c-ares/src/lib/record/ares_dns_multistring.c deleted file mode 100644 index 44fcaccd6..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_multistring.c +++ /dev/null @@ -1,307 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_dns_private.h" - -typedef struct { - unsigned char *data; - size_t len; -} multistring_data_t; - -struct ares_dns_multistring { - /*! whether or not cached concatenated string is valid */ - ares_bool_t cache_invalidated; - /*! combined/concatenated string cache */ - unsigned char *cache_str; - /*! length of combined/concatenated string */ - size_t cache_str_len; - /*! Data making up strings */ - ares_array_t *strs; /*!< multistring_data_t type */ -}; - -static void ares_dns_multistring_free_cb(void *arg) -{ - multistring_data_t *data = arg; - if (data == NULL) { - return; - } - ares_free(data->data); -} - -ares_dns_multistring_t *ares_dns_multistring_create(void) -{ - ares_dns_multistring_t *strs = ares_malloc_zero(sizeof(*strs)); - if (strs == NULL) { - return NULL; - } - - strs->strs = - ares_array_create(sizeof(multistring_data_t), ares_dns_multistring_free_cb); - if (strs->strs == NULL) { - ares_free(strs); - return NULL; - } - - return strs; -} - -void ares_dns_multistring_clear(ares_dns_multistring_t *strs) -{ - if (strs == NULL) { - return; - } - - while (ares_array_len(strs->strs)) { - ares_array_remove_last(strs->strs); - } -} - -void ares_dns_multistring_destroy(ares_dns_multistring_t *strs) -{ - if (strs == NULL) { - return; - } - ares_dns_multistring_clear(strs); - ares_array_destroy(strs->strs); - ares_free(strs->cache_str); - ares_free(strs); -} - -ares_status_t ares_dns_multistring_swap_own(ares_dns_multistring_t *strs, - size_t idx, unsigned char *str, - size_t len) -{ - multistring_data_t *data; - - if (strs == NULL || str == NULL || len == 0) { - return ARES_EFORMERR; - } - - strs->cache_invalidated = ARES_TRUE; - - data = ares_array_at(strs->strs, idx); - if (data == NULL) { - return ARES_EFORMERR; - } - - ares_free(data->data); - data->data = str; - data->len = len; - return ARES_SUCCESS; -} - -ares_status_t ares_dns_multistring_del(ares_dns_multistring_t *strs, size_t idx) -{ - if (strs == NULL) { - return ARES_EFORMERR; - } - - strs->cache_invalidated = ARES_TRUE; - - return ares_array_remove_at(strs->strs, idx); -} - -ares_status_t ares_dns_multistring_add_own(ares_dns_multistring_t *strs, - unsigned char *str, size_t len) -{ - multistring_data_t *data; - ares_status_t status; - - if (strs == NULL) { - return ARES_EFORMERR; - } - - strs->cache_invalidated = ARES_TRUE; - - /* NOTE: its ok to have an empty string added */ - if (str == NULL && len != 0) { - return ARES_EFORMERR; - } - - status = ares_array_insert_last((void **)&data, strs->strs); - if (status != ARES_SUCCESS) { - return status; - } - - /* Issue #921, ares_dns_multistring_get() doesn't have a way to indicate - * success or fail on a zero-length string which is actually valid. So we - * are going to allocate a 1-byte buffer to use as a placeholder in this - * case */ - if (str == NULL) { - str = ares_malloc_zero(1); - if (str == NULL) { - ares_array_remove_last(strs->strs); - return ARES_ENOMEM; - } - } - - data->data = str; - data->len = len; - - return ARES_SUCCESS; -} - -size_t ares_dns_multistring_cnt(const ares_dns_multistring_t *strs) -{ - if (strs == NULL) { - return 0; - } - return ares_array_len(strs->strs); -} - -const unsigned char * - ares_dns_multistring_get(const ares_dns_multistring_t *strs, size_t idx, - size_t *len) -{ - const multistring_data_t *data; - - if (strs == NULL || len == NULL) { - return NULL; - } - - data = ares_array_at_const(strs->strs, idx); - if (data == NULL) { - return NULL; - } - - *len = data->len; - return data->data; -} - -const unsigned char *ares_dns_multistring_combined(ares_dns_multistring_t *strs, - size_t *len) -{ - ares_buf_t *buf = NULL; - size_t i; - - if (strs == NULL || len == NULL) { - return NULL; - } - - *len = 0; - - /* Return cache if possible */ - if (!strs->cache_invalidated) { - *len = strs->cache_str_len; - return strs->cache_str; - } - - /* Clear cache */ - ares_free(strs->cache_str); - strs->cache_str = NULL; - strs->cache_str_len = 0; - - buf = ares_buf_create(); - - for (i = 0; i < ares_array_len(strs->strs); i++) { - const multistring_data_t *data = ares_array_at_const(strs->strs, i); - if (data == NULL || - ares_buf_append(buf, data->data, data->len) != ARES_SUCCESS) { - ares_buf_destroy(buf); - return NULL; - } - } - - strs->cache_str = - (unsigned char *)ares_buf_finish_str(buf, &strs->cache_str_len); - if (strs->cache_str != NULL) { - strs->cache_invalidated = ARES_FALSE; - } - *len = strs->cache_str_len; - return strs->cache_str; -} - -ares_status_t ares_dns_multistring_parse_buf(ares_buf_t *buf, - size_t remaining_len, - ares_dns_multistring_t **strs, - ares_bool_t validate_printable) -{ - unsigned char len; - ares_status_t status = ARES_EBADRESP; - size_t orig_len = ares_buf_len(buf); - - if (buf == NULL) { - return ARES_EFORMERR; - } - - if (remaining_len == 0) { - return ARES_EBADRESP; - } - - if (strs != NULL) { - *strs = ares_dns_multistring_create(); - if (*strs == NULL) { - return ARES_ENOMEM; - } - } - - while (orig_len - ares_buf_len(buf) < remaining_len) { - status = ares_buf_fetch_bytes(buf, &len, 1); - if (status != ARES_SUCCESS) { - break; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - - /* When used by the _str() parser, it really needs to be validated to - * be a valid printable ascii string. Do that here */ - if (len && validate_printable && ares_buf_len(buf) >= len) { - size_t mylen; - const char *data = (const char *)ares_buf_peek(buf, &mylen); - if (!ares_str_isprint(data, len)) { - status = ARES_EBADSTR; - break; - } - } - - if (strs != NULL) { - unsigned char *data = NULL; - if (len) { - status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &data); - if (status != ARES_SUCCESS) { - break; - } - } - status = ares_dns_multistring_add_own(*strs, data, len); - if (status != ARES_SUCCESS) { - ares_free(data); - break; - } - } else { - status = ares_buf_consume(buf, len); - if (status != ARES_SUCCESS) { - break; - } - } - - } - - if (status != ARES_SUCCESS && strs != NULL) { - ares_dns_multistring_destroy(*strs); - *strs = NULL; - } - - return status; -} diff --git a/vendor/c-ares/src/lib/record/ares_dns_multistring.h b/vendor/c-ares/src/lib/record/ares_dns_multistring.h deleted file mode 100644 index 70834491b..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_multistring.h +++ /dev/null @@ -1,72 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_DNS_MULTISTRING_H -#define __ARES_DNS_MULTISTRING_H - -#include "ares_buf.h" - -struct ares_dns_multistring; -typedef struct ares_dns_multistring ares_dns_multistring_t; - -ares_dns_multistring_t *ares_dns_multistring_create(void); -void ares_dns_multistring_clear(ares_dns_multistring_t *strs); -void ares_dns_multistring_destroy(ares_dns_multistring_t *strs); -ares_status_t ares_dns_multistring_swap_own(ares_dns_multistring_t *strs, - size_t idx, unsigned char *str, - size_t len); -ares_status_t ares_dns_multistring_del(ares_dns_multistring_t *strs, - size_t idx); -ares_status_t ares_dns_multistring_add_own(ares_dns_multistring_t *strs, - unsigned char *str, size_t len); -size_t ares_dns_multistring_cnt(const ares_dns_multistring_t *strs); -const unsigned char * - ares_dns_multistring_get(const ares_dns_multistring_t *strs, size_t idx, - size_t *len); -const unsigned char *ares_dns_multistring_combined(ares_dns_multistring_t *strs, - size_t *len); - -/*! Parse an array of character strings as defined in RFC1035, as binary, - * however, for convenience this does guarantee a NULL terminator (that is - * not included in the length for each value). - * - * \param[in] buf initialized buffer object - * \param[in] remaining_len maximum length that should be used for - * parsing the string, this is often less than - * the remaining buffer and is based on the RR - * record length. - * \param[out] strs Pointer passed by reference to be filled in - * with - * the array of values. - * \param[out] validate_printable Validate the strings contain only printable - * data. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_dns_multistring_parse_buf(ares_buf_t *buf, - size_t remaining_len, - ares_dns_multistring_t **strs, - ares_bool_t validate_printable); - -#endif diff --git a/vendor/c-ares/src/lib/record/ares_dns_name.c b/vendor/c-ares/src/lib/record/ares_dns_name.c deleted file mode 100644 index a9b92e03c..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_name.c +++ /dev/null @@ -1,673 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -typedef struct { - char *name; - size_t name_len; - size_t idx; -} ares_nameoffset_t; - -static void ares_nameoffset_free(void *arg) -{ - ares_nameoffset_t *off = arg; - if (off == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - ares_free(off->name); - ares_free(off); -} - -static ares_status_t ares_nameoffset_create(ares_llist_t **list, - const char *name, size_t idx) -{ - ares_status_t status; - ares_nameoffset_t *off = NULL; - - if (list == NULL || name == NULL || ares_strlen(name) == 0 || - ares_strlen(name) > 255) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (*list == NULL) { - *list = ares_llist_create(ares_nameoffset_free); - } - if (*list == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - off = ares_malloc_zero(sizeof(*off)); - if (off == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - off->name = ares_strdup(name); - off->name_len = ares_strlen(off->name); - off->idx = idx; - - if (ares_llist_insert_last(*list, off) == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; - -/* LCOV_EXCL_START: OutOfMemory */ -fail: - ares_nameoffset_free(off); - return status; - /* LCOV_EXCL_STOP */ -} - -static const ares_nameoffset_t *ares_nameoffset_find(ares_llist_t *list, - const char *name) -{ - size_t name_len = ares_strlen(name); - ares_llist_node_t *node; - const ares_nameoffset_t *longest_match = NULL; - - if (list == NULL || name == NULL || name_len == 0) { - return NULL; - } - - for (node = ares_llist_node_first(list); node != NULL; - node = ares_llist_node_next(node)) { - const ares_nameoffset_t *val = ares_llist_node_val(node); - size_t prefix_len; - - /* Can't be a match if the stored name is longer */ - if (val->name_len > name_len) { - continue; - } - - /* Can't be the longest match if our existing longest match is longer */ - if (longest_match != NULL && longest_match->name_len > val->name_len) { - continue; - } - - prefix_len = name_len - val->name_len; - - /* Due to DNS 0x20, lets not inadvertently mangle things, use case-sensitive - * matching instead of case-insensitive. This may result in slightly - * larger DNS queries overall. */ - if (!ares_streq(val->name, name + prefix_len)) { - continue; - } - - /* We need to make sure if `val->name` is "example.com" that name is - * is separated by a label, e.g. "myexample.com" is not ok, however - * "my.example.com" is, so we look for the preceding "." */ - if (prefix_len != 0 && name[prefix_len - 1] != '.') { - continue; - } - - longest_match = val; - } - - return longest_match; -} - -static void ares_dns_labels_free_cb(void *arg) -{ - ares_buf_t **buf = arg; - if (buf == NULL) { - return; - } - - ares_buf_destroy(*buf); -} - -static ares_buf_t *ares_dns_labels_add(ares_array_t *labels) -{ - ares_buf_t **buf; - - if (labels == NULL) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (ares_array_insert_last((void **)&buf, labels) != ARES_SUCCESS) { - return NULL; - } - - *buf = ares_buf_create(); - if (*buf == NULL) { - ares_array_remove_last(labels); - return NULL; - } - - return *buf; -} - -static ares_buf_t *ares_dns_labels_get_last(ares_array_t *labels) -{ - ares_buf_t **buf = ares_array_last(labels); - - if (buf == NULL) { - return NULL; - } - - return *buf; -} - -static ares_buf_t *ares_dns_labels_get_at(ares_array_t *labels, size_t idx) -{ - ares_buf_t **buf = ares_array_at(labels, idx); - - if (buf == NULL) { - return NULL; - } - - return *buf; -} - -static void ares_dns_name_labels_del_last(ares_array_t *labels) -{ - ares_array_remove_last(labels); -} - -static ares_status_t ares_parse_dns_name_escape(ares_buf_t *namebuf, - ares_buf_t *label, - ares_bool_t validate_hostname) -{ - ares_status_t status; - unsigned char c; - - status = ares_buf_fetch_bytes(namebuf, &c, 1); - if (status != ARES_SUCCESS) { - return ARES_EBADNAME; - } - - /* If next character is a digit, read 2 more digits */ - if (ares_isdigit(c)) { - size_t i; - unsigned int val = 0; - - val = c - '0'; - - for (i = 0; i < 2; i++) { - status = ares_buf_fetch_bytes(namebuf, &c, 1); - if (status != ARES_SUCCESS) { - return ARES_EBADNAME; - } - - if (!ares_isdigit(c)) { - return ARES_EBADNAME; - } - val *= 10; - val += c - '0'; - } - - /* Out of range */ - if (val > 255) { - return ARES_EBADNAME; - } - - if (validate_hostname && !ares_is_hostnamech((unsigned char)val)) { - return ARES_EBADNAME; - } - - return ares_buf_append_byte(label, (unsigned char)val); - } - - /* We can just output the character */ - if (validate_hostname && !ares_is_hostnamech(c)) { - return ARES_EBADNAME; - } - - return ares_buf_append_byte(label, c); -} - -static ares_status_t ares_split_dns_name(ares_array_t *labels, - ares_bool_t validate_hostname, - const char *name) -{ - ares_status_t status; - ares_buf_t *label = NULL; - ares_buf_t *namebuf = NULL; - size_t i; - size_t total_len = 0; - unsigned char c; - - if (name == NULL || labels == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Put name into a buffer for parsing */ - namebuf = ares_buf_create(); - if (namebuf == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (*name != '\0') { - status = - ares_buf_append(namebuf, (const unsigned char *)name, ares_strlen(name)); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - /* Start with 1 label */ - label = ares_dns_labels_add(labels); - if (label == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - while (ares_buf_fetch_bytes(namebuf, &c, 1) == ARES_SUCCESS) { - /* New label */ - if (c == '.') { - label = ares_dns_labels_add(labels); - if (label == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - continue; - } - - /* Escape */ - if (c == '\\') { - status = ares_parse_dns_name_escape(namebuf, label, validate_hostname); - if (status != ARES_SUCCESS) { - goto done; - } - continue; - } - - /* Output direct character */ - if (validate_hostname && !ares_is_hostnamech(c)) { - status = ARES_EBADNAME; - goto done; - } - - status = ares_buf_append_byte(label, c); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - /* Remove trailing blank label */ - if (ares_buf_len(ares_dns_labels_get_last(labels)) == 0) { - ares_dns_name_labels_del_last(labels); - } - - /* If someone passed in "." there could have been 2 blank labels, check for - * that */ - if (ares_array_len(labels) == 1 && - ares_buf_len(ares_dns_labels_get_last(labels)) == 0) { - ares_dns_name_labels_del_last(labels); - } - - /* Scan to make sure label lengths are valid */ - for (i = 0; i < ares_array_len(labels); i++) { - const ares_buf_t *buf = ares_dns_labels_get_at(labels, i); - size_t len = ares_buf_len(buf); - /* No 0-length labels, and no labels over 63 bytes */ - if (len == 0 || len > 63) { - status = ARES_EBADNAME; - goto done; - } - total_len += len; - } - - /* Can't exceed maximum (unescaped) length */ - if (ares_array_len(labels) && total_len + ares_array_len(labels) - 1 > 255) { - status = ARES_EBADNAME; - goto done; - } - - status = ARES_SUCCESS; - -done: - ares_buf_destroy(namebuf); - return status; -} - -ares_status_t ares_dns_name_write(ares_buf_t *buf, ares_llist_t **list, - ares_bool_t validate_hostname, - const char *name) -{ - const ares_nameoffset_t *off = NULL; - size_t name_len; - size_t orig_name_len; - size_t pos = ares_buf_len(buf); - ares_array_t *labels = NULL; - char name_copy[512]; - ares_status_t status; - - if (buf == NULL || name == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - labels = ares_array_create(sizeof(ares_buf_t *), ares_dns_labels_free_cb); - if (labels == NULL) { - return ARES_ENOMEM; - } - - /* NOTE: due to possible escaping, name_copy buffer is > 256 to allow for - * this */ - name_len = ares_strcpy(name_copy, name, sizeof(name_copy)); - orig_name_len = name_len; - - /* Find longest match */ - if (list != NULL) { - off = ares_nameoffset_find(*list, name_copy); - if (off != NULL && off->name_len != name_len) { - /* truncate */ - name_len -= (off->name_len + 1); - name_copy[name_len] = 0; - } - } - - /* Output labels */ - if (off == NULL || off->name_len != orig_name_len) { - size_t i; - - status = ares_split_dns_name(labels, validate_hostname, name_copy); - if (status != ARES_SUCCESS) { - goto done; - } - - for (i = 0; i < ares_array_len(labels); i++) { - size_t len = 0; - const ares_buf_t *lbuf = ares_dns_labels_get_at(labels, i); - const unsigned char *ptr = ares_buf_peek(lbuf, &len); - - status = ares_buf_append_byte(buf, (unsigned char)(len & 0xFF)); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append(buf, ptr, len); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - /* If we are NOT jumping to another label, output terminator */ - if (off == NULL) { - status = ares_buf_append_byte(buf, 0); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - /* Output name compression offset jump */ - if (off != NULL) { - unsigned short u16 = - (unsigned short)0xC000 | (unsigned short)(off->idx & 0x3FFF); - status = ares_buf_append_be16(buf, u16); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - /* Store pointer for future jumps as long as its not an exact match for - * a prior entry */ - if (list != NULL && (off == NULL || off->name_len != orig_name_len) && - name_len > 0) { - status = ares_nameoffset_create(list, name /* not truncated copy! */, pos); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ARES_SUCCESS; - -done: - ares_array_destroy(labels); - return status; -} - -/* Reserved characters for names that need to be escaped */ -static ares_bool_t is_reservedch(int ch) -{ - switch (ch) { - case '"': - case '.': - case ';': - case '\\': - case '(': - case ')': - case '@': - case '$': - return ARES_TRUE; - default: - break; - } - - return ARES_FALSE; -} - -static ares_status_t ares_fetch_dnsname_into_buf(ares_buf_t *buf, - ares_buf_t *dest, size_t len, - ares_bool_t is_hostname) -{ - size_t remaining_len; - const unsigned char *ptr = ares_buf_peek(buf, &remaining_len); - ares_status_t status; - size_t i; - - if (buf == NULL || len == 0 || remaining_len < len) { - return ARES_EBADRESP; - } - - for (i = 0; i < len; i++) { - unsigned char c = ptr[i]; - - /* Hostnames have a very specific allowed character set. Anything outside - * of that (non-printable and reserved included) are disallowed */ - if (is_hostname && !ares_is_hostnamech(c)) { - status = ARES_EBADRESP; - goto fail; - } - - /* NOTE: dest may be NULL if the user is trying to skip the name. validation - * still occurs above. */ - if (dest == NULL) { - continue; - } - - /* Non-printable characters need to be output as \DDD */ - if (!ares_isprint(c)) { - unsigned char escape[4]; - - escape[0] = '\\'; - escape[1] = '0' + (c / 100); - escape[2] = '0' + ((c % 100) / 10); - escape[3] = '0' + (c % 10); - - status = ares_buf_append(dest, escape, sizeof(escape)); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - continue; - } - - /* Reserved characters need to be escaped, otherwise normal */ - if (is_reservedch(c)) { - status = ares_buf_append_byte(dest, '\\'); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ares_buf_append_byte(dest, c); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return ares_buf_consume(buf, len); - -fail: - return status; -} - -ares_status_t ares_dns_name_parse(ares_buf_t *buf, char **name, - ares_bool_t is_hostname) -{ - size_t save_offset = 0; - unsigned char c; - ares_status_t status; - ares_buf_t *namebuf = NULL; - size_t label_start = ares_buf_get_position(buf); - - if (buf == NULL) { - return ARES_EFORMERR; - } - - if (name != NULL) { - namebuf = ares_buf_create(); - if (namebuf == NULL) { - status = ARES_ENOMEM; - goto fail; - } - } - - /* The compression scheme allows a domain name in a message to be - * represented as either: - * - * - a sequence of labels ending in a zero octet - * - a pointer - * - a sequence of labels ending with a pointer - */ - while (1) { - /* Keep track of the minimum label starting position to prevent forward - * jumping */ - if (label_start > ares_buf_get_position(buf)) { - label_start = ares_buf_get_position(buf); - } - - status = ares_buf_fetch_bytes(buf, &c, 1); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* Pointer/Redirect */ - if ((c & 0xc0) == 0xc0) { - /* The pointer takes the form of a two octet sequence: - * - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | 1 1| OFFSET | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * - * The first two bits are ones. This allows a pointer to be distinguished - * from a label, since the label must begin with two zero bits because - * labels are restricted to 63 octets or less. (The 10 and 01 - * combinations are reserved for future use.) The OFFSET field specifies - * an offset from the start of the message (i.e., the first octet of the - * ID field in the domain header). A zero offset specifies the first byte - * of the ID field, etc. - */ - size_t offset = (size_t)((c & 0x3F) << 8); - - /* Fetch second byte of the redirect length */ - status = ares_buf_fetch_bytes(buf, &c, 1); - if (status != ARES_SUCCESS) { - goto fail; - } - - offset |= ((size_t)c); - - /* According to RFC 1035 4.1.4: - * In this scheme, an entire domain name or a list of labels at - * the end of a domain name is replaced with a pointer to a prior - * occurrence of the same name. - * Note the word "prior", meaning it must go backwards. This was - * confirmed via the ISC BIND code that it also prevents forward - * pointers. - */ - if (offset >= label_start) { - status = ARES_EBADNAME; - goto fail; - } - - /* First time we make a jump, save the current position */ - if (save_offset == 0) { - save_offset = ares_buf_get_position(buf); - } - - status = ares_buf_set_position(buf, offset); - if (status != ARES_SUCCESS) { - status = ARES_EBADNAME; - goto fail; - } - - continue; - } else if ((c & 0xc0) != 0) { - /* 10 and 01 are reserved */ - status = ARES_EBADNAME; - goto fail; - } else if (c == 0) { - /* termination via zero octet*/ - break; - } - - /* New label */ - - /* Labels are separated by periods */ - if (ares_buf_len(namebuf) != 0 && name != NULL) { - status = ares_buf_append_byte(namebuf, '.'); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - status = ares_fetch_dnsname_into_buf(buf, namebuf, c, is_hostname); - if (status != ARES_SUCCESS) { - goto fail; - } - } - - /* Restore offset read after first redirect/pointer as this is where the DNS - * message continues */ - if (save_offset) { - ares_buf_set_position(buf, save_offset); - } - - if (name != NULL) { - *name = ares_buf_finish_str(namebuf, NULL); - if (*name == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return ARES_SUCCESS; - -fail: - /* We want badname response if we couldn't parse */ - if (status == ARES_EBADRESP) { - status = ARES_EBADNAME; - } - - ares_buf_destroy(namebuf); - return status; -} diff --git a/vendor/c-ares/src/lib/record/ares_dns_parse.c b/vendor/c-ares/src/lib/record/ares_dns_parse.c deleted file mode 100644 index 0c545d7aa..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_parse.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include -#ifdef HAVE_STDINT_H -# include -#endif - -static size_t ares_dns_rr_remaining_len(const ares_buf_t *buf, size_t orig_len, - size_t rdlength) -{ - size_t used_len = orig_len - ares_buf_len(buf); - if (used_len >= rdlength) { - return 0; - } - return rdlength - used_len; -} - -static ares_status_t ares_dns_parse_and_set_dns_name(ares_buf_t *buf, - ares_bool_t is_hostname, - ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - ares_status_t status; - char *name = NULL; - - status = ares_dns_name_parse(buf, &name, is_hostname); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_rr_set_str_own(rr, key, name); - if (status != ARES_SUCCESS) { - ares_free(name); - return status; - } - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_and_set_dns_str(ares_buf_t *buf, - size_t max_len, - ares_dns_rr_t *rr, - ares_dns_rr_key_t key, - ares_bool_t blank_allowed) -{ - ares_status_t status; - char *str = NULL; - - status = ares_buf_parse_dns_str(buf, max_len, &str); - if (status != ARES_SUCCESS) { - return status; - } - - if (!blank_allowed && ares_strlen(str) == 0) { - ares_free(str); - return ARES_EBADRESP; - } - - status = ares_dns_rr_set_str_own(rr, key, str); - if (status != ARES_SUCCESS) { - ares_free(str); - return status; - } - return ARES_SUCCESS; -} - -static ares_status_t - ares_dns_parse_and_set_dns_abin(ares_buf_t *buf, size_t max_len, - ares_dns_rr_t *rr, ares_dns_rr_key_t key, - ares_bool_t validate_printable) -{ - ares_status_t status; - ares_dns_multistring_t *strs = NULL; - - status = - ares_dns_multistring_parse_buf(buf, max_len, &strs, validate_printable); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_rr_set_abin_own(rr, key, strs); - if (status != ARES_SUCCESS) { - ares_dns_multistring_destroy(strs); - return status; - } - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_and_set_be32(ares_buf_t *buf, - ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - ares_status_t status; - unsigned int u32; - - status = ares_buf_fetch_be32(buf, &u32); - if (status != ARES_SUCCESS) { - return status; - } - - return ares_dns_rr_set_u32(rr, key, u32); -} - -static ares_status_t ares_dns_parse_and_set_be16(ares_buf_t *buf, - ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - ares_status_t status; - unsigned short u16; - - status = ares_buf_fetch_be16(buf, &u16); - if (status != ARES_SUCCESS) { - return status; - } - - return ares_dns_rr_set_u16(rr, key, u16); -} - -static ares_status_t ares_dns_parse_and_set_u8(ares_buf_t *buf, - ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - ares_status_t status; - unsigned char u8; - - status = ares_buf_fetch_bytes(buf, &u8, 1); - if (status != ARES_SUCCESS) { - return status; - } - - return ares_dns_rr_set_u8(rr, key, u8); -} - -static ares_status_t ares_dns_parse_rr_a(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - struct in_addr addr; - ares_status_t status; - - (void)rdlength; /* Not needed */ - - status = ares_buf_fetch_bytes(buf, (unsigned char *)&addr, sizeof(addr)); - if (status != ARES_SUCCESS) { - return status; - } - - return ares_dns_rr_set_addr(rr, ARES_RR_A_ADDR, &addr); -} - -static ares_status_t ares_dns_parse_rr_ns(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - (void)rdlength; /* Not needed */ - - return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, - ARES_RR_NS_NSDNAME); -} - -static ares_status_t ares_dns_parse_rr_cname(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - (void)rdlength; /* Not needed */ - - return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, - ARES_RR_CNAME_CNAME); -} - -static ares_status_t ares_dns_parse_rr_soa(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - - (void)rdlength; /* Not needed */ - - /* MNAME */ - status = - ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_SOA_MNAME); - if (status != ARES_SUCCESS) { - return status; - } - - /* RNAME */ - status = - ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_SOA_RNAME); - if (status != ARES_SUCCESS) { - return status; - } - - /* SERIAL */ - status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_SERIAL); - if (status != ARES_SUCCESS) { - return status; - } - - /* REFRESH */ - status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_REFRESH); - if (status != ARES_SUCCESS) { - return status; - } - - /* RETRY */ - status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_RETRY); - if (status != ARES_SUCCESS) { - return status; - } - - /* EXPIRE */ - status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_EXPIRE); - if (status != ARES_SUCCESS) { - return status; - } - - /* MINIMUM */ - return ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_MINIMUM); -} - -static ares_status_t ares_dns_parse_rr_ptr(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - (void)rdlength; /* Not needed */ - - return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, - ARES_RR_PTR_DNAME); -} - -static ares_status_t ares_dns_parse_rr_hinfo(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - - (void)rdlength; /* Not needed */ - - /* CPU */ - status = ares_dns_parse_and_set_dns_str( - buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, - ARES_RR_HINFO_CPU, ARES_TRUE); - if (status != ARES_SUCCESS) { - return status; - } - - /* OS */ - status = ares_dns_parse_and_set_dns_str( - buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, - ARES_RR_HINFO_OS, ARES_TRUE); - - return status; -} - -static ares_status_t ares_dns_parse_rr_mx(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - - (void)rdlength; /* Not needed */ - - /* PREFERENCE */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_MX_PREFERENCE); - if (status != ARES_SUCCESS) { - return status; - } - - /* EXCHANGE */ - return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, - ARES_RR_MX_EXCHANGE); -} - -static ares_status_t ares_dns_parse_rr_txt(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - return ares_dns_parse_and_set_dns_abin(buf, rdlength, rr, ARES_RR_TXT_DATA, - ARES_FALSE); -} - -static ares_status_t ares_dns_parse_rr_sig(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - size_t len; - unsigned char *data; - - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SIG_TYPE_COVERED); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_SIG_ALGORITHM); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_SIG_LABELS); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SIG_ORIGINAL_TTL); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SIG_EXPIRATION); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SIG_INCEPTION); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SIG_KEY_TAG); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, - ARES_RR_SIG_SIGNERS_NAME); - if (status != ARES_SUCCESS) { - return status; - } - - len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); - if (len == 0) { - return ARES_EBADRESP; - } - - status = ares_buf_fetch_bytes_dup(buf, len, ARES_FALSE, &data); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_rr_set_bin_own(rr, ARES_RR_SIG_SIGNATURE, data, len); - if (status != ARES_SUCCESS) { - ares_free(data); - return status; - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_rr_aaaa(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - struct ares_in6_addr addr; - ares_status_t status; - - (void)rdlength; /* Not needed */ - - status = ares_buf_fetch_bytes(buf, (unsigned char *)&addr, sizeof(addr)); - if (status != ARES_SUCCESS) { - return status; - } - - return ares_dns_rr_set_addr6(rr, ARES_RR_AAAA_ADDR, &addr); -} - -static ares_status_t ares_dns_parse_rr_srv(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - - (void)rdlength; /* Not needed */ - - /* PRIORITY */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SRV_PRIORITY); - if (status != ARES_SUCCESS) { - return status; - } - - /* WEIGHT */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SRV_WEIGHT); - if (status != ARES_SUCCESS) { - return status; - } - - /* PORT */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SRV_PORT); - if (status != ARES_SUCCESS) { - return status; - } - - /* TARGET */ - return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, - ARES_RR_SRV_TARGET); -} - -static ares_status_t ares_dns_parse_rr_naptr(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - - /* ORDER */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_NAPTR_ORDER); - if (status != ARES_SUCCESS) { - return status; - } - - /* PREFERENCE */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_NAPTR_PREFERENCE); - if (status != ARES_SUCCESS) { - return status; - } - - /* FLAGS */ - status = ares_dns_parse_and_set_dns_str( - buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, - ARES_RR_NAPTR_FLAGS, ARES_TRUE); - if (status != ARES_SUCCESS) { - return status; - } - - /* SERVICES */ - status = ares_dns_parse_and_set_dns_str( - buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, - ARES_RR_NAPTR_SERVICES, ARES_TRUE); - if (status != ARES_SUCCESS) { - return status; - } - - /* REGEXP */ - status = ares_dns_parse_and_set_dns_str( - buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, - ARES_RR_NAPTR_REGEXP, ARES_TRUE); - if (status != ARES_SUCCESS) { - return status; - } - - /* REPLACEMENT */ - return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, - ARES_RR_NAPTR_REPLACEMENT); -} - -static ares_status_t ares_dns_parse_rr_opt(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength, - unsigned short raw_class, - unsigned int raw_ttl) -{ - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - unsigned short rcode_high; - - status = ares_dns_rr_set_u16(rr, ARES_RR_OPT_UDP_SIZE, raw_class); - if (status != ARES_SUCCESS) { - return status; - } - - /* First 8 bits of TTL are an extended RCODE, and they go in the higher order - * after the original 4-bit rcode */ - rcode_high = (unsigned short)((raw_ttl >> 20) & 0x0FF0); - rr->parent->raw_rcode |= rcode_high; - - status = ares_dns_rr_set_u8(rr, ARES_RR_OPT_VERSION, - (unsigned char)(raw_ttl >> 16) & 0xFF); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_rr_set_u16(rr, ARES_RR_OPT_FLAGS, - (unsigned short)(raw_ttl & 0xFFFF)); - if (status != ARES_SUCCESS) { - return status; - } - - /* Parse options */ - while (ares_dns_rr_remaining_len(buf, orig_len, rdlength)) { - unsigned short opt = 0; - unsigned short len = 0; - unsigned char *val = NULL; - - /* Fetch be16 option */ - status = ares_buf_fetch_be16(buf, &opt); - if (status != ARES_SUCCESS) { - return status; - } - - /* Fetch be16 length */ - status = ares_buf_fetch_be16(buf, &len); - if (status != ARES_SUCCESS) { - return status; - } - - if (len) { - status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &val); - if (status != ARES_SUCCESS) { - return status; - } - } - - status = ares_dns_rr_set_opt_own(rr, ARES_RR_OPT_OPTIONS, opt, val, len); - if (status != ARES_SUCCESS) { - return status; - } - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_rr_tlsa(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - size_t len; - unsigned char *data; - - status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_TLSA_CERT_USAGE); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_TLSA_SELECTOR); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_TLSA_MATCH); - if (status != ARES_SUCCESS) { - return status; - } - - len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); - if (len == 0) { - return ARES_EBADRESP; - } - - status = ares_buf_fetch_bytes_dup(buf, len, ARES_FALSE, &data); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_rr_set_bin_own(rr, ARES_RR_TLSA_DATA, data, len); - if (status != ARES_SUCCESS) { - ares_free(data); - return status; - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_rr_svcb(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SVCB_PRIORITY); - if (status != ARES_SUCCESS) { - return status; - } - - status = - ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_SVCB_TARGET); - if (status != ARES_SUCCESS) { - return status; - } - - /* Parse params */ - while (ares_dns_rr_remaining_len(buf, orig_len, rdlength)) { - unsigned short opt = 0; - unsigned short len = 0; - unsigned char *val = NULL; - - /* Fetch be16 option */ - status = ares_buf_fetch_be16(buf, &opt); - if (status != ARES_SUCCESS) { - return status; - } - - /* Fetch be16 length */ - status = ares_buf_fetch_be16(buf, &len); - if (status != ARES_SUCCESS) { - return status; - } - - if (len) { - status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &val); - if (status != ARES_SUCCESS) { - return status; - } - } - - status = ares_dns_rr_set_opt_own(rr, ARES_RR_SVCB_PARAMS, opt, val, len); - if (status != ARES_SUCCESS) { - return status; - } - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_rr_https(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_HTTPS_PRIORITY); - if (status != ARES_SUCCESS) { - return status; - } - - status = - ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_HTTPS_TARGET); - if (status != ARES_SUCCESS) { - return status; - } - - /* Parse params */ - while (ares_dns_rr_remaining_len(buf, orig_len, rdlength)) { - unsigned short opt = 0; - unsigned short len = 0; - unsigned char *val = NULL; - - /* Fetch be16 option */ - status = ares_buf_fetch_be16(buf, &opt); - if (status != ARES_SUCCESS) { - return status; - } - - /* Fetch be16 length */ - status = ares_buf_fetch_be16(buf, &len); - if (status != ARES_SUCCESS) { - return status; - } - - if (len) { - status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &val); - if (status != ARES_SUCCESS) { - return status; - } - } - - status = ares_dns_rr_set_opt_own(rr, ARES_RR_HTTPS_PARAMS, opt, val, len); - if (status != ARES_SUCCESS) { - return status; - } - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_rr_uri(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - char *name = NULL; - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - size_t remaining_len; - - /* PRIORITY */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_URI_PRIORITY); - if (status != ARES_SUCCESS) { - return status; - } - - /* WEIGHT */ - status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_URI_WEIGHT); - if (status != ARES_SUCCESS) { - return status; - } - - /* TARGET -- not in string format, rest of buffer, required to be - * non-zero length */ - remaining_len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); - if (remaining_len == 0) { - status = ARES_EBADRESP; - return status; - } - - /* NOTE: Not in DNS string format */ - status = ares_buf_fetch_str_dup(buf, remaining_len, &name); - if (status != ARES_SUCCESS) { - return status; - } - - if (!ares_str_isprint(name, remaining_len)) { - ares_free(name); - return ARES_EBADRESP; - } - - status = ares_dns_rr_set_str_own(rr, ARES_RR_URI_TARGET, name); - if (status != ARES_SUCCESS) { - ares_free(name); - return status; - } - name = NULL; - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_rr_caa(ares_buf_t *buf, ares_dns_rr_t *rr, - size_t rdlength) -{ - unsigned char *data = NULL; - size_t data_len = 0; - ares_status_t status; - size_t orig_len = ares_buf_len(buf); - - /* CRITICAL */ - status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_CAA_CRITICAL); - if (status != ARES_SUCCESS) { - return status; - } - - /* Tag */ - status = ares_dns_parse_and_set_dns_str( - buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, - ARES_RR_CAA_TAG, ARES_FALSE); - if (status != ARES_SUCCESS) { - return status; - } - - /* Value - binary! (remaining buffer */ - data_len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); - if (data_len == 0) { - status = ARES_EBADRESP; - return status; - } - status = ares_buf_fetch_bytes_dup(buf, data_len, ARES_TRUE, &data); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_rr_set_bin_own(rr, ARES_RR_CAA_VALUE, data, data_len); - if (status != ARES_SUCCESS) { - ares_free(data); - return status; - } - data = NULL; - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_rr_raw_rr(ares_buf_t *buf, - ares_dns_rr_t *rr, - size_t rdlength, - unsigned short raw_type) -{ - ares_status_t status; - unsigned char *bytes = NULL; - - if (rdlength == 0) { - return ARES_SUCCESS; - } - - status = ares_buf_fetch_bytes_dup(buf, rdlength, ARES_FALSE, &bytes); - if (status != ARES_SUCCESS) { - return status; - } - - /* Can't fail */ - status = ares_dns_rr_set_u16(rr, ARES_RR_RAW_RR_TYPE, raw_type); - if (status != ARES_SUCCESS) { - ares_free(bytes); - return status; - } - - status = ares_dns_rr_set_bin_own(rr, ARES_RR_RAW_RR_DATA, bytes, rdlength); - if (status != ARES_SUCCESS) { - ares_free(bytes); - return status; - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_parse_header(ares_buf_t *buf, unsigned int flags, - ares_dns_record_t **dnsrec, - unsigned short *qdcount, - unsigned short *ancount, - unsigned short *nscount, - unsigned short *arcount) -{ - ares_status_t status = ARES_EBADRESP; - unsigned short u16; - unsigned short id; - unsigned short dns_flags = 0; - ares_dns_opcode_t opcode; - unsigned short rcode; - - (void)flags; /* currently unused */ - - if (buf == NULL || dnsrec == NULL || qdcount == NULL || ancount == NULL || - nscount == NULL || arcount == NULL) { - return ARES_EFORMERR; - } - - *dnsrec = NULL; - - /* - * RFC 1035 4.1.1. Header section format. - * and Updated by RFC 2065 to add AD and CD bits. - * 1 1 1 1 1 1 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | ID | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | QDCOUNT | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | ANCOUNT | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | NSCOUNT | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | ARCOUNT | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - */ - - /* ID */ - status = ares_buf_fetch_be16(buf, &id); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* Flags */ - status = ares_buf_fetch_be16(buf, &u16); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* QR */ - if (u16 & 0x8000) { - dns_flags |= ARES_FLAG_QR; - } - - /* OPCODE */ - opcode = (u16 >> 11) & 0xf; - - /* AA */ - if (u16 & 0x400) { - dns_flags |= ARES_FLAG_AA; - } - - /* TC */ - if (u16 & 0x200) { - dns_flags |= ARES_FLAG_TC; - } - - /* RD */ - if (u16 & 0x100) { - dns_flags |= ARES_FLAG_RD; - } - - /* RA */ - if (u16 & 0x80) { - dns_flags |= ARES_FLAG_RA; - } - - /* Z -- unused */ - - /* AD */ - if (u16 & 0x20) { - dns_flags |= ARES_FLAG_AD; - } - - /* CD */ - if (u16 & 0x10) { - dns_flags |= ARES_FLAG_CD; - } - - /* RCODE */ - rcode = u16 & 0xf; - - /* QDCOUNT */ - status = ares_buf_fetch_be16(buf, qdcount); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* ANCOUNT */ - status = ares_buf_fetch_be16(buf, ancount); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* NSCOUNT */ - status = ares_buf_fetch_be16(buf, nscount); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* ARCOUNT */ - status = ares_buf_fetch_be16(buf, arcount); - if (status != ARES_SUCCESS) { - goto fail; - } - - status = ares_dns_record_create(dnsrec, id, dns_flags, opcode, - ARES_RCODE_NOERROR /* Temporary */); - if (status != ARES_SUCCESS) { - goto fail; - } - - (*dnsrec)->raw_rcode = rcode; - - if (*ancount > 0) { - status = - ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ANSWER, *ancount); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - if (*nscount > 0) { - status = - ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_AUTHORITY, *nscount); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - if (*arcount > 0) { - status = - ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ADDITIONAL, *arcount); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return ARES_SUCCESS; - -fail: - ares_dns_record_destroy(*dnsrec); - *dnsrec = NULL; - *qdcount = 0; - *ancount = 0; - *nscount = 0; - *arcount = 0; - - return status; -} - -static ares_status_t - ares_dns_parse_rr_data(ares_buf_t *buf, size_t rdlength, ares_dns_rr_t *rr, - ares_dns_rec_type_t type, unsigned short raw_type, - unsigned short raw_class, unsigned int raw_ttl) -{ - switch (type) { - case ARES_REC_TYPE_A: - return ares_dns_parse_rr_a(buf, rr, rdlength); - case ARES_REC_TYPE_NS: - return ares_dns_parse_rr_ns(buf, rr, rdlength); - case ARES_REC_TYPE_CNAME: - return ares_dns_parse_rr_cname(buf, rr, rdlength); - case ARES_REC_TYPE_SOA: - return ares_dns_parse_rr_soa(buf, rr, rdlength); - case ARES_REC_TYPE_PTR: - return ares_dns_parse_rr_ptr(buf, rr, rdlength); - case ARES_REC_TYPE_HINFO: - return ares_dns_parse_rr_hinfo(buf, rr, rdlength); - case ARES_REC_TYPE_MX: - return ares_dns_parse_rr_mx(buf, rr, rdlength); - case ARES_REC_TYPE_TXT: - return ares_dns_parse_rr_txt(buf, rr, rdlength); - case ARES_REC_TYPE_SIG: - return ares_dns_parse_rr_sig(buf, rr, rdlength); - case ARES_REC_TYPE_AAAA: - return ares_dns_parse_rr_aaaa(buf, rr, rdlength); - case ARES_REC_TYPE_SRV: - return ares_dns_parse_rr_srv(buf, rr, rdlength); - case ARES_REC_TYPE_NAPTR: - return ares_dns_parse_rr_naptr(buf, rr, rdlength); - case ARES_REC_TYPE_ANY: - return ARES_EBADRESP; - case ARES_REC_TYPE_OPT: - return ares_dns_parse_rr_opt(buf, rr, rdlength, raw_class, raw_ttl); - case ARES_REC_TYPE_TLSA: - return ares_dns_parse_rr_tlsa(buf, rr, rdlength); - case ARES_REC_TYPE_SVCB: - return ares_dns_parse_rr_svcb(buf, rr, rdlength); - case ARES_REC_TYPE_HTTPS: - return ares_dns_parse_rr_https(buf, rr, rdlength); - case ARES_REC_TYPE_URI: - return ares_dns_parse_rr_uri(buf, rr, rdlength); - case ARES_REC_TYPE_CAA: - return ares_dns_parse_rr_caa(buf, rr, rdlength); - case ARES_REC_TYPE_RAW_RR: - return ares_dns_parse_rr_raw_rr(buf, rr, rdlength, raw_type); - } - return ARES_EFORMERR; -} - -static ares_status_t ares_dns_parse_qd(ares_buf_t *buf, - ares_dns_record_t *dnsrec) -{ - char *name = NULL; - unsigned short u16; - ares_status_t status; - ares_dns_rec_type_t type; - ares_dns_class_t qclass; - /* The question section is used to carry the "question" in most queries, - * i.e., the parameters that define what is being asked. The section - * contains QDCOUNT (usually 1) entries, each of the following format: - * 1 1 1 1 1 1 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | | - * / QNAME / - * / / - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | QTYPE | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | QCLASS | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - */ - - /* Name */ - status = ares_dns_name_parse(buf, &name, ARES_FALSE); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Type */ - status = ares_buf_fetch_be16(buf, &u16); - if (status != ARES_SUCCESS) { - goto done; - } - type = u16; - - /* Class */ - status = ares_buf_fetch_be16(buf, &u16); - if (status != ARES_SUCCESS) { - goto done; - } - qclass = u16; - - /* Add question */ - status = ares_dns_record_query_add(dnsrec, name, type, qclass); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_free(name); - return status; -} - -static ares_status_t ares_dns_parse_rr(ares_buf_t *buf, unsigned int flags, - ares_dns_section_t sect, - ares_dns_record_t *dnsrec) -{ - char *name = NULL; - unsigned short u16; - unsigned short raw_type; - ares_status_t status; - ares_dns_rec_type_t type; - ares_dns_class_t qclass; - unsigned int ttl; - size_t rdlength; - ares_dns_rr_t *rr = NULL; - size_t remaining_len = 0; - size_t processed_len = 0; - ares_bool_t namecomp; - - /* All RRs have the same top level format shown below: - * 1 1 1 1 1 1 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | | - * / / - * / NAME / - * | | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | TYPE | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | CLASS | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | TTL | - * | | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | RDLENGTH | - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| - * / RDATA / - * / / - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - */ - - /* Name */ - status = ares_dns_name_parse(buf, &name, ARES_FALSE); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Type */ - status = ares_buf_fetch_be16(buf, &u16); - if (status != ARES_SUCCESS) { - goto done; - } - type = u16; - raw_type = u16; /* Only used for raw rr data */ - - /* Class */ - status = ares_buf_fetch_be16(buf, &u16); - if (status != ARES_SUCCESS) { - goto done; - } - qclass = u16; - - /* TTL */ - status = ares_buf_fetch_be32(buf, &ttl); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Length */ - status = ares_buf_fetch_be16(buf, &u16); - if (status != ARES_SUCCESS) { - goto done; - } - rdlength = u16; - - if (!ares_dns_rec_type_isvalid(type, ARES_FALSE)) { - type = ARES_REC_TYPE_RAW_RR; - } - - namecomp = ares_dns_rec_allow_name_comp(type); - if (sect == ARES_SECTION_ANSWER && - (flags & - (namecomp ? ARES_DNS_PARSE_AN_BASE_RAW : ARES_DNS_PARSE_AN_EXT_RAW))) { - type = ARES_REC_TYPE_RAW_RR; - } - if (sect == ARES_SECTION_AUTHORITY && - (flags & - (namecomp ? ARES_DNS_PARSE_NS_BASE_RAW : ARES_DNS_PARSE_NS_EXT_RAW))) { - type = ARES_REC_TYPE_RAW_RR; - } - if (sect == ARES_SECTION_ADDITIONAL && - (flags & - (namecomp ? ARES_DNS_PARSE_AR_BASE_RAW : ARES_DNS_PARSE_AR_EXT_RAW))) { - type = ARES_REC_TYPE_RAW_RR; - } - - /* Pull into another buffer for safety */ - if (rdlength > ares_buf_len(buf)) { - status = ARES_EBADRESP; - goto done; - } - - /* Add the base rr */ - status = - ares_dns_record_rr_add(&rr, dnsrec, sect, name, type, - type == ARES_REC_TYPE_OPT ? ARES_CLASS_IN : qclass, - type == ARES_REC_TYPE_OPT ? 0 : ttl); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Record the current remaining length in the buffer so we can tell how - * much was processed */ - remaining_len = ares_buf_len(buf); - - /* Fill in the data for the rr */ - status = ares_dns_parse_rr_data(buf, rdlength, rr, type, raw_type, - (unsigned short)qclass, ttl); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Determine how many bytes were processed */ - processed_len = remaining_len - ares_buf_len(buf); - - /* If too many bytes were processed, error! */ - if (processed_len > rdlength) { - status = ARES_EBADRESP; - goto done; - } - - /* If too few bytes were processed, consume the unprocessed data for this - * record as the parser may not have wanted/needed to use it */ - if (processed_len < rdlength) { - ares_buf_consume(buf, rdlength - processed_len); - } - - -done: - ares_free(name); - return status; -} - -static ares_status_t ares_dns_parse_buf(ares_buf_t *buf, unsigned int flags, - ares_dns_record_t **dnsrec) -{ - ares_status_t status; - unsigned short qdcount; - unsigned short ancount; - unsigned short nscount; - unsigned short arcount; - unsigned short i; - - if (buf == NULL || dnsrec == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Maximum DNS packet size is 64k, even over TCP */ - if (ares_buf_len(buf) > 0xFFFF) { - return ARES_EFORMERR; - } - - /* All communications inside of the domain protocol are carried in a single - * format called a message. The top level format of message is divided - * into 5 sections (some of which are empty in certain cases) shown below: - * - * +---------------------+ - * | Header | - * +---------------------+ - * | Question | the question for the name server - * +---------------------+ - * | Answer | RRs answering the question - * +---------------------+ - * | Authority | RRs pointing toward an authority - * +---------------------+ - * | Additional | RRs holding additional information - * +---------------------+ - */ - - /* Parse header */ - status = ares_dns_parse_header(buf, flags, dnsrec, &qdcount, &ancount, - &nscount, &arcount); - if (status != ARES_SUCCESS) { - goto fail; - } - - /* Must have questions */ - if (qdcount == 0) { - status = ARES_EBADRESP; - goto fail; - } - - /* XXX: this should be controlled by a flag in case we want to allow - * multiple questions. I think mDNS allows this */ - if (qdcount > 1) { - status = ARES_EBADRESP; - goto fail; - } - - /* Parse questions */ - for (i = 0; i < qdcount; i++) { - status = ares_dns_parse_qd(buf, *dnsrec); - if (status != ARES_SUCCESS) { - goto fail; - } - } - - /* Parse Answers */ - for (i = 0; i < ancount; i++) { - status = ares_dns_parse_rr(buf, flags, ARES_SECTION_ANSWER, *dnsrec); - if (status != ARES_SUCCESS) { - goto fail; - } - } - - /* Parse Authority */ - for (i = 0; i < nscount; i++) { - status = ares_dns_parse_rr(buf, flags, ARES_SECTION_AUTHORITY, *dnsrec); - if (status != ARES_SUCCESS) { - goto fail; - } - } - - /* Parse Additional */ - for (i = 0; i < arcount; i++) { - status = ares_dns_parse_rr(buf, flags, ARES_SECTION_ADDITIONAL, *dnsrec); - if (status != ARES_SUCCESS) { - goto fail; - } - } - - /* Finalize rcode now that if we have OPT it is processed */ - if (!ares_dns_rcode_isvalid((*dnsrec)->raw_rcode)) { - (*dnsrec)->rcode = ARES_RCODE_SERVFAIL; - } else { - (*dnsrec)->rcode = (ares_dns_rcode_t)(*dnsrec)->raw_rcode; - } - - return ARES_SUCCESS; - -fail: - ares_dns_record_destroy(*dnsrec); - *dnsrec = NULL; - return status; -} - -ares_status_t ares_dns_parse(const unsigned char *buf, size_t buf_len, - unsigned int flags, ares_dns_record_t **dnsrec) -{ - ares_buf_t *parser = NULL; - ares_status_t status; - - if (buf == NULL || buf_len == 0 || dnsrec == NULL) { - return ARES_EFORMERR; - } - - parser = ares_buf_create_const(buf, buf_len); - if (parser == NULL) { - return ARES_ENOMEM; - } - - status = ares_dns_parse_buf(parser, flags, dnsrec); - ares_buf_destroy(parser); - - return status; -} diff --git a/vendor/c-ares/src/lib/record/ares_dns_private.h b/vendor/c-ares/src/lib/record/ares_dns_private.h deleted file mode 100644 index e8fd600d1..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_private.h +++ /dev/null @@ -1,273 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_DNS_PRIVATE_H -#define __ARES_DNS_PRIVATE_H - -ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest, - const ares_dns_record_t *src); -ares_bool_t ares_dns_rec_allow_name_comp(ares_dns_rec_type_t type); -ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode); -ares_bool_t ares_dns_rcode_isvalid(ares_dns_rcode_t rcode); -ares_bool_t ares_dns_flags_arevalid(unsigned short flags); -ares_bool_t ares_dns_rec_type_isvalid(ares_dns_rec_type_t type, - ares_bool_t is_query); -ares_bool_t ares_dns_class_isvalid(ares_dns_class_t qclass, - ares_dns_rec_type_t type, - ares_bool_t is_query); -ares_bool_t ares_dns_section_isvalid(ares_dns_section_t sect); -ares_status_t ares_dns_rr_set_str_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, char *val); -ares_status_t ares_dns_rr_set_bin_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, unsigned char *val, - size_t len); -ares_status_t ares_dns_rr_set_abin_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - ares_dns_multistring_t *strs); -ares_status_t ares_dns_rr_set_opt_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, unsigned short opt, - unsigned char *val, size_t val_len); -ares_status_t ares_dns_record_rr_prealloc(ares_dns_record_t *dnsrec, - ares_dns_section_t sect, size_t cnt); -ares_dns_rr_t *ares_dns_get_opt_rr(ares_dns_record_t *rec); -const ares_dns_rr_t *ares_dns_get_opt_rr_const(const ares_dns_record_t *rec); -void ares_dns_record_ttl_decrement(ares_dns_record_t *dnsrec, - unsigned int ttl_decrement); - -/* Same as ares_dns_write() but appends to an existing buffer object */ -ares_status_t ares_dns_write_buf(const ares_dns_record_t *dnsrec, - ares_buf_t *buf); - -/* Same as ares_dns_write_buf(), but prepends a 16bit length */ -ares_status_t ares_dns_write_buf_tcp(const ares_dns_record_t *dnsrec, - ares_buf_t *buf); - -/*! Create a DNS record object for a query. The arguments are the same as - * those for ares_create_query(). - * - * \param[out] dnsrec DNS record object to create. - * \param[in] name NUL-terminated name for the query. - * \param[in] dnsclass Class for the query. - * \param[in] type Type for the query. - * \param[in] id Identifier for the query. - * \param[in] flags Flags for the query. - * \param[in] max_udp_size Maximum size of a UDP packet for EDNS. - * \return ARES_SUCCESS on success, otherwise an error code. - */ -ares_status_t - ares_dns_record_create_query(ares_dns_record_t **dnsrec, const char *name, - ares_dns_class_t dnsclass, - ares_dns_rec_type_t type, unsigned short id, - ares_dns_flags_t flags, size_t max_udp_size); - -/*! Convert the RCODE and ANCOUNT from a DNS query reply into a status code. - * - * \param[in] rcode The RCODE from the reply. - * \param[in] ancount The ANCOUNT from the reply. - * \return An appropriate status code. - */ -ares_status_t ares_dns_query_reply_tostatus(ares_dns_rcode_t rcode, - size_t ancount); - -struct ares_dns_qd { - char *name; - ares_dns_rec_type_t qtype; - ares_dns_class_t qclass; -}; - -typedef struct { - struct in_addr addr; -} ares_dns_a_t; - -typedef struct { - char *nsdname; -} ares_dns_ns_t; - -typedef struct { - char *cname; -} ares_dns_cname_t; - -typedef struct { - char *mname; - char *rname; - unsigned int serial; - unsigned int refresh; - unsigned int retry; - unsigned int expire; - unsigned int minimum; -} ares_dns_soa_t; - -typedef struct { - char *dname; -} ares_dns_ptr_t; - -typedef struct { - char *cpu; - char *os; -} ares_dns_hinfo_t; - -typedef struct { - unsigned short preference; - char *exchange; -} ares_dns_mx_t; - -typedef struct { - ares_dns_multistring_t *strs; -} ares_dns_txt_t; - -typedef struct { - unsigned short type_covered; - unsigned char algorithm; - unsigned char labels; - unsigned int original_ttl; - unsigned int expiration; - unsigned int inception; - unsigned short key_tag; - char *signers_name; - unsigned char *signature; - size_t signature_len; -} ares_dns_sig_t; - -typedef struct { - struct ares_in6_addr addr; -} ares_dns_aaaa_t; - -typedef struct { - unsigned short priority; - unsigned short weight; - unsigned short port; - char *target; -} ares_dns_srv_t; - -typedef struct { - unsigned short order; - unsigned short preference; - char *flags; - char *services; - char *regexp; - char *replacement; -} ares_dns_naptr_t; - -typedef struct { - unsigned short opt; - unsigned char *val; - size_t val_len; -} ares_dns_optval_t; - -typedef struct { - unsigned short udp_size; /*!< taken from class */ - unsigned char version; /*!< taken from bits 8-16 of ttl */ - unsigned short flags; /*!< Flags, remaining 16 bits, though only - * 1 currently defined */ - ares_array_t *options; /*!< Type is ares_dns_optval_t */ -} ares_dns_opt_t; - -typedef struct { - unsigned char cert_usage; - unsigned char selector; - unsigned char match; - unsigned char *data; - size_t data_len; -} ares_dns_tlsa_t; - -typedef struct { - unsigned short priority; - char *target; - ares_array_t *params; /*!< Type is ares_dns_optval_t */ -} ares_dns_svcb_t; - -typedef struct { - unsigned short priority; - unsigned short weight; - char *target; -} ares_dns_uri_t; - -typedef struct { - unsigned char critical; - char *tag; - unsigned char *value; - size_t value_len; -} ares_dns_caa_t; - -/*! Raw, unparsed RR data */ -typedef struct { - unsigned short type; /*!< Not ares_rec_type_t because it likely isn't one - * of those values since it wasn't parsed */ - unsigned char *data; /*!< Raw RR data */ - size_t length; /*!< Length of raw RR data */ -} ares_dns_raw_rr_t; - -/*! DNS RR data structure */ -struct ares_dns_rr { - ares_dns_record_t *parent; - char *name; - ares_dns_rec_type_t type; - ares_dns_class_t rclass; - unsigned int ttl; - - union { - ares_dns_a_t a; - ares_dns_ns_t ns; - ares_dns_cname_t cname; - ares_dns_soa_t soa; - ares_dns_ptr_t ptr; - ares_dns_hinfo_t hinfo; - ares_dns_mx_t mx; - ares_dns_txt_t txt; - ares_dns_sig_t sig; - ares_dns_aaaa_t aaaa; - ares_dns_srv_t srv; - ares_dns_naptr_t naptr; - ares_dns_opt_t opt; - ares_dns_tlsa_t tlsa; - ares_dns_svcb_t svcb; - ares_dns_svcb_t https; /*!< https is a type of svcb, so this is right */ - ares_dns_uri_t uri; - ares_dns_caa_t caa; - ares_dns_raw_rr_t raw_rr; - } r; -}; - -/*! DNS data structure */ -struct ares_dns_record { - unsigned short id; /*!< DNS query id */ - unsigned short flags; /*!< One or more ares_dns_flags_t */ - ares_dns_opcode_t opcode; /*!< DNS Opcode */ - ares_dns_rcode_t rcode; /*!< DNS RCODE */ - unsigned short raw_rcode; /*!< Raw rcode, used to ultimately form real - * rcode after reading OPT record if it - * exists */ - unsigned int ttl_decrement; /*!< Special case to apply to writing out - * this record, where it will decrement - * the ttl of any resource records by - * this amount. Used for cache */ - - ares_array_t *qd; /*!< Type is ares_dns_qd_t */ - ares_array_t *an; /*!< Type is ares_dns_rr_t */ - ares_array_t *ns; /*!< Type is ares_dns_rr_t */ - ares_array_t *ar; /*!< Type is ares_dns_rr_t */ -}; - -#endif diff --git a/vendor/c-ares/src/lib/record/ares_dns_record.c b/vendor/c-ares/src/lib/record/ares_dns_record.c deleted file mode 100644 index ec0dfbd13..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_record.c +++ /dev/null @@ -1,1661 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include -#ifdef HAVE_STDINT_H -# include -#endif - -static void ares_dns_rr_free(ares_dns_rr_t *rr); - -static void ares_dns_qd_free_cb(void *arg) -{ - ares_dns_qd_t *qd = arg; - if (qd == NULL) { - return; - } - ares_free(qd->name); -} - -static void ares_dns_rr_free_cb(void *arg) -{ - ares_dns_rr_t *rr = arg; - if (rr == NULL) { - return; - } - ares_dns_rr_free(rr); -} - -ares_status_t ares_dns_record_create(ares_dns_record_t **dnsrec, - unsigned short id, unsigned short flags, - ares_dns_opcode_t opcode, - ares_dns_rcode_t rcode) -{ - if (dnsrec == NULL) { - return ARES_EFORMERR; - } - - *dnsrec = NULL; - - if (!ares_dns_opcode_isvalid(opcode) || !ares_dns_rcode_isvalid(rcode) || - !ares_dns_flags_arevalid(flags)) { - return ARES_EFORMERR; - } - - *dnsrec = ares_malloc_zero(sizeof(**dnsrec)); - if (*dnsrec == NULL) { - return ARES_ENOMEM; - } - - (*dnsrec)->id = id; - (*dnsrec)->flags = flags; - (*dnsrec)->opcode = opcode; - (*dnsrec)->rcode = rcode; - (*dnsrec)->qd = ares_array_create(sizeof(ares_dns_qd_t), ares_dns_qd_free_cb); - (*dnsrec)->an = ares_array_create(sizeof(ares_dns_rr_t), ares_dns_rr_free_cb); - (*dnsrec)->ns = ares_array_create(sizeof(ares_dns_rr_t), ares_dns_rr_free_cb); - (*dnsrec)->ar = ares_array_create(sizeof(ares_dns_rr_t), ares_dns_rr_free_cb); - - if ((*dnsrec)->qd == NULL || (*dnsrec)->an == NULL || (*dnsrec)->ns == NULL || - (*dnsrec)->ar == NULL) { - ares_dns_record_destroy(*dnsrec); - *dnsrec = NULL; - return ARES_ENOMEM; - } - - return ARES_SUCCESS; -} - -unsigned short ares_dns_record_get_id(const ares_dns_record_t *dnsrec) -{ - if (dnsrec == NULL) { - return 0; - } - return dnsrec->id; -} - -ares_bool_t ares_dns_record_set_id(ares_dns_record_t *dnsrec, unsigned short id) -{ - if (dnsrec == NULL) { - return ARES_FALSE; - } - dnsrec->id = id; - return ARES_TRUE; -} - -unsigned short ares_dns_record_get_flags(const ares_dns_record_t *dnsrec) -{ - if (dnsrec == NULL) { - return 0; - } - return dnsrec->flags; -} - -ares_dns_opcode_t ares_dns_record_get_opcode(const ares_dns_record_t *dnsrec) -{ - if (dnsrec == NULL) { - return 0; - } - return dnsrec->opcode; -} - -ares_dns_rcode_t ares_dns_record_get_rcode(const ares_dns_record_t *dnsrec) -{ - if (dnsrec == NULL) { - return 0; - } - return dnsrec->rcode; -} - -static void ares_dns_rr_free(ares_dns_rr_t *rr) -{ - ares_free(rr->name); - - switch (rr->type) { - case ARES_REC_TYPE_A: - case ARES_REC_TYPE_AAAA: - case ARES_REC_TYPE_ANY: - /* Nothing to free */ - break; - - case ARES_REC_TYPE_NS: - ares_free(rr->r.ns.nsdname); - break; - - case ARES_REC_TYPE_CNAME: - ares_free(rr->r.cname.cname); - break; - - case ARES_REC_TYPE_SOA: - ares_free(rr->r.soa.mname); - ares_free(rr->r.soa.rname); - break; - - case ARES_REC_TYPE_PTR: - ares_free(rr->r.ptr.dname); - break; - - case ARES_REC_TYPE_HINFO: - ares_free(rr->r.hinfo.cpu); - ares_free(rr->r.hinfo.os); - break; - - case ARES_REC_TYPE_MX: - ares_free(rr->r.mx.exchange); - break; - - case ARES_REC_TYPE_TXT: - ares_dns_multistring_destroy(rr->r.txt.strs); - break; - - case ARES_REC_TYPE_SIG: - ares_free(rr->r.sig.signers_name); - ares_free(rr->r.sig.signature); - break; - - case ARES_REC_TYPE_SRV: - ares_free(rr->r.srv.target); - break; - - case ARES_REC_TYPE_NAPTR: - ares_free(rr->r.naptr.flags); - ares_free(rr->r.naptr.services); - ares_free(rr->r.naptr.regexp); - ares_free(rr->r.naptr.replacement); - break; - - case ARES_REC_TYPE_OPT: - ares_array_destroy(rr->r.opt.options); - break; - - case ARES_REC_TYPE_TLSA: - ares_free(rr->r.tlsa.data); - break; - - case ARES_REC_TYPE_SVCB: - ares_free(rr->r.svcb.target); - ares_array_destroy(rr->r.svcb.params); - break; - - case ARES_REC_TYPE_HTTPS: - ares_free(rr->r.https.target); - ares_array_destroy(rr->r.https.params); - break; - - case ARES_REC_TYPE_URI: - ares_free(rr->r.uri.target); - break; - - case ARES_REC_TYPE_CAA: - ares_free(rr->r.caa.tag); - ares_free(rr->r.caa.value); - break; - - case ARES_REC_TYPE_RAW_RR: - ares_free(rr->r.raw_rr.data); - break; - } -} - -void ares_dns_record_destroy(ares_dns_record_t *dnsrec) -{ - if (dnsrec == NULL) { - return; - } - - /* Free questions */ - ares_array_destroy(dnsrec->qd); - - /* Free answers */ - ares_array_destroy(dnsrec->an); - - /* Free authority */ - ares_array_destroy(dnsrec->ns); - - /* Free additional */ - ares_array_destroy(dnsrec->ar); - - ares_free(dnsrec); -} - -size_t ares_dns_record_query_cnt(const ares_dns_record_t *dnsrec) -{ - if (dnsrec == NULL) { - return 0; - } - return ares_array_len(dnsrec->qd); -} - -ares_status_t ares_dns_record_query_add(ares_dns_record_t *dnsrec, - const char *name, - ares_dns_rec_type_t qtype, - ares_dns_class_t qclass) -{ - size_t idx; - ares_dns_qd_t *qd; - ares_status_t status; - - if (dnsrec == NULL || name == NULL || - !ares_dns_rec_type_isvalid(qtype, ARES_TRUE) || - !ares_dns_class_isvalid(qclass, qtype, ARES_TRUE)) { - return ARES_EFORMERR; - } - - idx = ares_array_len(dnsrec->qd); - status = ares_array_insert_last((void **)&qd, dnsrec->qd); - if (status != ARES_SUCCESS) { - return status; - } - - qd->name = ares_strdup(name); - if (qd->name == NULL) { - ares_array_remove_at(dnsrec->qd, idx); - return ARES_ENOMEM; - } - qd->qtype = qtype; - qd->qclass = qclass; - return ARES_SUCCESS; -} - -ares_status_t ares_dns_record_query_set_name(ares_dns_record_t *dnsrec, - size_t idx, const char *name) -{ - char *orig_name = NULL; - ares_dns_qd_t *qd; - - if (dnsrec == NULL || idx >= ares_array_len(dnsrec->qd) || name == NULL) { - return ARES_EFORMERR; - } - - qd = ares_array_at(dnsrec->qd, idx); - - orig_name = qd->name; - qd->name = ares_strdup(name); - if (qd->name == NULL) { - qd->name = orig_name; /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - ares_free(orig_name); - return ARES_SUCCESS; -} - -ares_status_t ares_dns_record_query_set_type(ares_dns_record_t *dnsrec, - size_t idx, - ares_dns_rec_type_t qtype) -{ - ares_dns_qd_t *qd; - - if (dnsrec == NULL || idx >= ares_array_len(dnsrec->qd) || - !ares_dns_rec_type_isvalid(qtype, ARES_TRUE)) { - return ARES_EFORMERR; - } - - qd = ares_array_at(dnsrec->qd, idx); - qd->qtype = qtype; - - return ARES_SUCCESS; -} - -ares_status_t ares_dns_record_query_get(const ares_dns_record_t *dnsrec, - size_t idx, const char **name, - ares_dns_rec_type_t *qtype, - ares_dns_class_t *qclass) -{ - const ares_dns_qd_t *qd; - if (dnsrec == NULL || idx >= ares_array_len(dnsrec->qd)) { - return ARES_EFORMERR; - } - - qd = ares_array_at(dnsrec->qd, idx); - if (name != NULL) { - *name = qd->name; - } - - if (qtype != NULL) { - *qtype = qd->qtype; - } - - if (qclass != NULL) { - *qclass = qd->qclass; - } - - return ARES_SUCCESS; -} - -size_t ares_dns_record_rr_cnt(const ares_dns_record_t *dnsrec, - ares_dns_section_t sect) -{ - if (dnsrec == NULL || !ares_dns_section_isvalid(sect)) { - return 0; - } - - switch (sect) { - case ARES_SECTION_ANSWER: - return ares_array_len(dnsrec->an); - case ARES_SECTION_AUTHORITY: - return ares_array_len(dnsrec->ns); - case ARES_SECTION_ADDITIONAL: - return ares_array_len(dnsrec->ar); - } - - return 0; /* LCOV_EXCL_LINE: DefensiveCoding */ -} - -ares_status_t ares_dns_record_rr_prealloc(ares_dns_record_t *dnsrec, - ares_dns_section_t sect, size_t cnt) -{ - ares_array_t *arr = NULL; - - if (dnsrec == NULL || !ares_dns_section_isvalid(sect)) { - return ARES_EFORMERR; - } - - switch (sect) { - case ARES_SECTION_ANSWER: - arr = dnsrec->an; - break; - case ARES_SECTION_AUTHORITY: - arr = dnsrec->ns; - break; - case ARES_SECTION_ADDITIONAL: - arr = dnsrec->ar; - break; - } - - if (cnt < ares_array_len(arr)) { - return ARES_EFORMERR; - } - - return ares_array_set_size(arr, cnt); -} - -ares_status_t ares_dns_record_rr_add(ares_dns_rr_t **rr_out, - ares_dns_record_t *dnsrec, - ares_dns_section_t sect, const char *name, - ares_dns_rec_type_t type, - ares_dns_class_t rclass, unsigned int ttl) -{ - ares_dns_rr_t *rr = NULL; - ares_array_t *arr = NULL; - ares_status_t status; - size_t idx; - - if (dnsrec == NULL || name == NULL || rr_out == NULL || - !ares_dns_section_isvalid(sect) || - !ares_dns_rec_type_isvalid(type, ARES_FALSE) || - !ares_dns_class_isvalid(rclass, type, ARES_FALSE)) { - return ARES_EFORMERR; - } - - *rr_out = NULL; - - switch (sect) { - case ARES_SECTION_ANSWER: - arr = dnsrec->an; - break; - case ARES_SECTION_AUTHORITY: - arr = dnsrec->ns; - break; - case ARES_SECTION_ADDITIONAL: - arr = dnsrec->ar; - break; - } - - idx = ares_array_len(arr); - status = ares_array_insert_last((void **)&rr, arr); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - rr->name = ares_strdup(name); - if (rr->name == NULL) { - ares_array_remove_at(arr, idx); - return ARES_ENOMEM; - } - - rr->parent = dnsrec; - rr->type = type; - rr->rclass = rclass; - rr->ttl = ttl; - - *rr_out = rr; - - return ARES_SUCCESS; -} - -ares_status_t ares_dns_record_rr_del(ares_dns_record_t *dnsrec, - ares_dns_section_t sect, size_t idx) -{ - ares_array_t *arr = NULL; - - if (dnsrec == NULL || !ares_dns_section_isvalid(sect)) { - return ARES_EFORMERR; - } - - switch (sect) { - case ARES_SECTION_ANSWER: - arr = dnsrec->an; - break; - case ARES_SECTION_AUTHORITY: - arr = dnsrec->ns; - break; - case ARES_SECTION_ADDITIONAL: - arr = dnsrec->ar; - break; - } - - return ares_array_remove_at(arr, idx); -} - -ares_dns_rr_t *ares_dns_record_rr_get(ares_dns_record_t *dnsrec, - ares_dns_section_t sect, size_t idx) -{ - ares_array_t *arr = NULL; - - if (dnsrec == NULL || !ares_dns_section_isvalid(sect)) { - return NULL; - } - - switch (sect) { - case ARES_SECTION_ANSWER: - arr = dnsrec->an; - break; - case ARES_SECTION_AUTHORITY: - arr = dnsrec->ns; - break; - case ARES_SECTION_ADDITIONAL: - arr = dnsrec->ar; - break; - } - - return ares_array_at(arr, idx); -} - -const ares_dns_rr_t * - ares_dns_record_rr_get_const(const ares_dns_record_t *dnsrec, - ares_dns_section_t sect, size_t idx) -{ - return ares_dns_record_rr_get((void *)((size_t)dnsrec), sect, idx); -} - -const char *ares_dns_rr_get_name(const ares_dns_rr_t *rr) -{ - if (rr == NULL) { - return NULL; - } - return rr->name; -} - -ares_dns_rec_type_t ares_dns_rr_get_type(const ares_dns_rr_t *rr) -{ - if (rr == NULL) { - return 0; - } - return rr->type; -} - -ares_dns_class_t ares_dns_rr_get_class(const ares_dns_rr_t *rr) -{ - if (rr == NULL) { - return 0; - } - return rr->rclass; -} - -unsigned int ares_dns_rr_get_ttl(const ares_dns_rr_t *rr) -{ - if (rr == NULL) { - return 0; - } - return rr->ttl; -} - -static void *ares_dns_rr_data_ptr(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - size_t **lenptr) -{ - if (dns_rr == NULL || dns_rr->type != ares_dns_rr_key_to_rec_type(key)) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - switch (key) { - case ARES_RR_A_ADDR: - return &dns_rr->r.a.addr; - - case ARES_RR_NS_NSDNAME: - return &dns_rr->r.ns.nsdname; - - case ARES_RR_CNAME_CNAME: - return &dns_rr->r.cname.cname; - - case ARES_RR_SOA_MNAME: - return &dns_rr->r.soa.mname; - - case ARES_RR_SOA_RNAME: - return &dns_rr->r.soa.rname; - - case ARES_RR_SOA_SERIAL: - return &dns_rr->r.soa.serial; - - case ARES_RR_SOA_REFRESH: - return &dns_rr->r.soa.refresh; - - case ARES_RR_SOA_RETRY: - return &dns_rr->r.soa.retry; - - case ARES_RR_SOA_EXPIRE: - return &dns_rr->r.soa.expire; - - case ARES_RR_SOA_MINIMUM: - return &dns_rr->r.soa.minimum; - - case ARES_RR_PTR_DNAME: - return &dns_rr->r.ptr.dname; - - case ARES_RR_AAAA_ADDR: - return &dns_rr->r.aaaa.addr; - - case ARES_RR_HINFO_CPU: - return &dns_rr->r.hinfo.cpu; - - case ARES_RR_HINFO_OS: - return &dns_rr->r.hinfo.os; - - case ARES_RR_MX_PREFERENCE: - return &dns_rr->r.mx.preference; - - case ARES_RR_MX_EXCHANGE: - return &dns_rr->r.mx.exchange; - - case ARES_RR_SIG_TYPE_COVERED: - return &dns_rr->r.sig.type_covered; - - case ARES_RR_SIG_ALGORITHM: - return &dns_rr->r.sig.algorithm; - - case ARES_RR_SIG_LABELS: - return &dns_rr->r.sig.labels; - - case ARES_RR_SIG_ORIGINAL_TTL: - return &dns_rr->r.sig.original_ttl; - - case ARES_RR_SIG_EXPIRATION: - return &dns_rr->r.sig.expiration; - - case ARES_RR_SIG_INCEPTION: - return &dns_rr->r.sig.inception; - - case ARES_RR_SIG_KEY_TAG: - return &dns_rr->r.sig.key_tag; - - case ARES_RR_SIG_SIGNERS_NAME: - return &dns_rr->r.sig.signers_name; - - case ARES_RR_SIG_SIGNATURE: - if (lenptr == NULL) { - return NULL; - } - *lenptr = &dns_rr->r.sig.signature_len; - return &dns_rr->r.sig.signature; - - case ARES_RR_TXT_DATA: - return &dns_rr->r.txt.strs; - - case ARES_RR_SRV_PRIORITY: - return &dns_rr->r.srv.priority; - - case ARES_RR_SRV_WEIGHT: - return &dns_rr->r.srv.weight; - - case ARES_RR_SRV_PORT: - return &dns_rr->r.srv.port; - - case ARES_RR_SRV_TARGET: - return &dns_rr->r.srv.target; - - case ARES_RR_NAPTR_ORDER: - return &dns_rr->r.naptr.order; - - case ARES_RR_NAPTR_PREFERENCE: - return &dns_rr->r.naptr.preference; - - case ARES_RR_NAPTR_FLAGS: - return &dns_rr->r.naptr.flags; - - case ARES_RR_NAPTR_SERVICES: - return &dns_rr->r.naptr.services; - - case ARES_RR_NAPTR_REGEXP: - return &dns_rr->r.naptr.regexp; - - case ARES_RR_NAPTR_REPLACEMENT: - return &dns_rr->r.naptr.replacement; - - case ARES_RR_OPT_UDP_SIZE: - return &dns_rr->r.opt.udp_size; - - case ARES_RR_OPT_VERSION: - return &dns_rr->r.opt.version; - - case ARES_RR_OPT_FLAGS: - return &dns_rr->r.opt.flags; - - case ARES_RR_OPT_OPTIONS: - return &dns_rr->r.opt.options; - - case ARES_RR_TLSA_CERT_USAGE: - return &dns_rr->r.tlsa.cert_usage; - - case ARES_RR_TLSA_SELECTOR: - return &dns_rr->r.tlsa.selector; - - case ARES_RR_TLSA_MATCH: - return &dns_rr->r.tlsa.match; - - case ARES_RR_TLSA_DATA: - if (lenptr == NULL) { - return NULL; - } - *lenptr = &dns_rr->r.tlsa.data_len; - return &dns_rr->r.tlsa.data; - - case ARES_RR_SVCB_PRIORITY: - return &dns_rr->r.svcb.priority; - - case ARES_RR_SVCB_TARGET: - return &dns_rr->r.svcb.target; - - case ARES_RR_SVCB_PARAMS: - return &dns_rr->r.svcb.params; - - case ARES_RR_HTTPS_PRIORITY: - return &dns_rr->r.https.priority; - - case ARES_RR_HTTPS_TARGET: - return &dns_rr->r.https.target; - - case ARES_RR_HTTPS_PARAMS: - return &dns_rr->r.https.params; - - case ARES_RR_URI_PRIORITY: - return &dns_rr->r.uri.priority; - - case ARES_RR_URI_WEIGHT: - return &dns_rr->r.uri.weight; - - case ARES_RR_URI_TARGET: - return &dns_rr->r.uri.target; - - case ARES_RR_CAA_CRITICAL: - return &dns_rr->r.caa.critical; - - case ARES_RR_CAA_TAG: - return &dns_rr->r.caa.tag; - - case ARES_RR_CAA_VALUE: - if (lenptr == NULL) { - return NULL; - } - *lenptr = &dns_rr->r.caa.value_len; - return &dns_rr->r.caa.value; - - case ARES_RR_RAW_RR_TYPE: - return &dns_rr->r.raw_rr.type; - - case ARES_RR_RAW_RR_DATA: - if (lenptr == NULL) { - return NULL; - } - *lenptr = &dns_rr->r.raw_rr.length; - return &dns_rr->r.raw_rr.data; - } - - return NULL; -} - -static const void *ares_dns_rr_data_ptr_const(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - const size_t **lenptr) -{ - /* We're going to cast off the const */ - return ares_dns_rr_data_ptr((void *)((size_t)dns_rr), key, - (void *)((size_t)lenptr)); -} - -const struct in_addr *ares_dns_rr_get_addr(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - const struct in_addr *addr; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_INADDR) { - return NULL; - } - - addr = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (addr == NULL) { - return NULL; - } - - return addr; -} - -const struct ares_in6_addr *ares_dns_rr_get_addr6(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - const struct ares_in6_addr *addr; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_INADDR6) { - return NULL; - } - - addr = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (addr == NULL) { - return NULL; - } - - return addr; -} - -unsigned char ares_dns_rr_get_u8(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - const unsigned char *u8; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U8) { - return 0; - } - - u8 = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (u8 == NULL) { - return 0; - } - - return *u8; -} - -unsigned short ares_dns_rr_get_u16(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - const unsigned short *u16; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U16) { - return 0; - } - - u16 = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (u16 == NULL) { - return 0; - } - - return *u16; -} - -unsigned int ares_dns_rr_get_u32(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - const unsigned int *u32; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U32) { - return 0; - } - - u32 = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (u32 == NULL) { - return 0; - } - - return *u32; -} - -const unsigned char *ares_dns_rr_get_bin(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, size_t *len) -{ - unsigned char * const *bin = NULL; - size_t const *bin_len = NULL; - - if ((ares_dns_rr_key_datatype(key) != ARES_DATATYPE_BIN && - ares_dns_rr_key_datatype(key) != ARES_DATATYPE_BINP && - ares_dns_rr_key_datatype(key) != ARES_DATATYPE_ABINP) || - len == NULL) { - return NULL; - } - - /* Array of strings, return concatenated version */ - if (ares_dns_rr_key_datatype(key) == ARES_DATATYPE_ABINP) { - ares_dns_multistring_t * const *strs = - ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - - if (strs == NULL) { - return NULL; - } - - return ares_dns_multistring_combined(*strs, len); - } - - /* Not a multi-string, just straight binary data */ - bin = ares_dns_rr_data_ptr_const(dns_rr, key, &bin_len); - if (bin == NULL) { - return NULL; - } - - /* Shouldn't be possible */ - if (bin_len == NULL) { - return NULL; - } - *len = *bin_len; - - return *bin; -} - -size_t ares_dns_rr_get_abin_cnt(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - ares_dns_multistring_t * const *strs; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_ABINP) { - return 0; - } - - strs = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (strs == NULL) { - return 0; - } - - return ares_dns_multistring_cnt(*strs); -} - -const unsigned char *ares_dns_rr_get_abin(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, size_t idx, - size_t *len) -{ - ares_dns_multistring_t * const *strs; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_ABINP) { - return NULL; - } - - strs = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (strs == NULL) { - return NULL; - } - - return ares_dns_multistring_get(*strs, idx, len); -} - -ares_status_t ares_dns_rr_del_abin(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - size_t idx) -{ - ares_dns_multistring_t **strs; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_ABINP) { - return ARES_EFORMERR; - } - - strs = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (strs == NULL) { - return ARES_EFORMERR; - } - - return ares_dns_multistring_del(*strs, idx); -} - -ares_status_t ares_dns_rr_add_abin(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - const unsigned char *val, size_t len) -{ - ares_status_t status; - ares_dns_datatype_t datatype = ares_dns_rr_key_datatype(key); - ares_bool_t is_nullterm = - (datatype == ARES_DATATYPE_ABINP) ? ARES_TRUE : ARES_FALSE; - size_t alloclen = is_nullterm ? len + 1 : len; - unsigned char *temp; - ares_dns_multistring_t **strs; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_ABINP) { - return ARES_EFORMERR; - } - - strs = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (strs == NULL) { - return ARES_EFORMERR; - } - - if (*strs == NULL) { - *strs = ares_dns_multistring_create(); - if (*strs == NULL) { - return ARES_ENOMEM; - } - } - - temp = ares_malloc(alloclen); - if (temp == NULL) { - return ARES_ENOMEM; - } - - memcpy(temp, val, len); - - /* NULL-term ABINP */ - if (is_nullterm) { - temp[len] = 0; - } - - status = ares_dns_multistring_add_own(*strs, temp, len); - if (status != ARES_SUCCESS) { - ares_free(temp); - } - - return status; -} - -const char *ares_dns_rr_get_str(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - char * const *str; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_STR && - ares_dns_rr_key_datatype(key) != ARES_DATATYPE_NAME) { - return NULL; - } - - str = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (str == NULL) { - return NULL; - } - - return *str; -} - -size_t ares_dns_rr_get_opt_cnt(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key) -{ - ares_array_t * const *opts; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { - return 0; - } - - opts = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (opts == NULL || *opts == NULL) { - return 0; - } - - return ares_array_len(*opts); -} - -unsigned short ares_dns_rr_get_opt(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, size_t idx, - const unsigned char **val, size_t *val_len) -{ - ares_array_t * const *opts; - const ares_dns_optval_t *opt; - - if (val) { - *val = NULL; - } - if (val_len) { - *val_len = 0; - } - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { - return 65535; - } - - opts = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (opts == NULL || *opts == NULL) { - return 65535; - } - - opt = ares_array_at(*opts, idx); - if (opt == NULL) { - return 65535; - } - - if (val) { - *val = opt->val; - } - if (val_len) { - *val_len = opt->val_len; - } - - return opt->opt; -} - -ares_bool_t ares_dns_rr_get_opt_byid(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, unsigned short opt, - const unsigned char **val, size_t *val_len) -{ - ares_array_t * const *opts; - size_t i; - size_t cnt; - const ares_dns_optval_t *optptr = NULL; - - if (val) { - *val = NULL; - } - if (val_len) { - *val_len = 0; - } - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { - return ARES_FALSE; - } - - opts = ares_dns_rr_data_ptr_const(dns_rr, key, NULL); - if (opts == NULL || *opts == NULL) { - return ARES_FALSE; - } - - cnt = ares_array_len(*opts); - for (i = 0; i < cnt; i++) { - optptr = ares_array_at(*opts, i); - if (optptr == NULL) { - return ARES_FALSE; - } - if (optptr->opt == opt) { - break; - } - } - - if (i >= cnt || optptr == NULL) { - return ARES_FALSE; - } - - if (val) { - *val = optptr->val; - } - if (val_len) { - *val_len = optptr->val_len; - } - return ARES_TRUE; -} - -ares_status_t ares_dns_rr_set_addr(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - const struct in_addr *addr) -{ - struct in_addr *a; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_INADDR || addr == NULL) { - return ARES_EFORMERR; - } - - a = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (a == NULL) { - return ARES_EFORMERR; - } - - memcpy(a, addr, sizeof(*a)); - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_addr6(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - const struct ares_in6_addr *addr) -{ - struct ares_in6_addr *a; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_INADDR6 || addr == NULL) { - return ARES_EFORMERR; - } - - a = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (a == NULL) { - return ARES_EFORMERR; - } - - memcpy(a, addr, sizeof(*a)); - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_u8(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - unsigned char val) -{ - unsigned char *u8; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U8) { - return ARES_EFORMERR; - } - - u8 = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (u8 == NULL) { - return ARES_EFORMERR; - } - - *u8 = val; - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_u16(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - unsigned short val) -{ - unsigned short *u16; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U16) { - return ARES_EFORMERR; - } - - u16 = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (u16 == NULL) { - return ARES_EFORMERR; - } - - *u16 = val; - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_u32(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - unsigned int val) -{ - unsigned int *u32; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U32) { - return ARES_EFORMERR; - } - - u32 = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (u32 == NULL) { - return ARES_EFORMERR; - } - - *u32 = val; - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_bin_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, unsigned char *val, - size_t len) -{ - unsigned char **bin; - size_t *bin_len = NULL; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_BIN && - ares_dns_rr_key_datatype(key) != ARES_DATATYPE_BINP && - ares_dns_rr_key_datatype(key) != ARES_DATATYPE_ABINP) { - return ARES_EFORMERR; - } - - if (ares_dns_rr_key_datatype(key) == ARES_DATATYPE_ABINP) { - ares_dns_multistring_t **strs = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (strs == NULL) { - return ARES_EFORMERR; - } - - if (*strs == NULL) { - *strs = ares_dns_multistring_create(); - if (*strs == NULL) { - return ARES_ENOMEM; - } - } - - /* Clear all existing entries as this is an override */ - ares_dns_multistring_clear(*strs); - - return ares_dns_multistring_add_own(*strs, val, len); - } - - bin = ares_dns_rr_data_ptr(dns_rr, key, &bin_len); - if (bin == NULL || bin_len == NULL) { - return ARES_EFORMERR; - } - - if (*bin) { - ares_free(*bin); - } - *bin = val; - *bin_len = len; - - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_bin(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - const unsigned char *val, size_t len) -{ - ares_status_t status; - ares_dns_datatype_t datatype = ares_dns_rr_key_datatype(key); - ares_bool_t is_nullterm = - (datatype == ARES_DATATYPE_BINP || datatype == ARES_DATATYPE_ABINP) - ? ARES_TRUE - : ARES_FALSE; - size_t alloclen = is_nullterm ? len + 1 : len; - unsigned char *temp = ares_malloc(alloclen); - - if (temp == NULL) { - return ARES_ENOMEM; - } - - memcpy(temp, val, len); - - /* NULL-term BINP */ - if (is_nullterm) { - temp[len] = 0; - } - - status = ares_dns_rr_set_bin_own(dns_rr, key, temp, len); - if (status != ARES_SUCCESS) { - ares_free(temp); - } - - return status; -} - -ares_status_t ares_dns_rr_set_str_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, char *val) -{ - char **str; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_STR && - ares_dns_rr_key_datatype(key) != ARES_DATATYPE_NAME) { - return ARES_EFORMERR; - } - - str = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (str == NULL) { - return ARES_EFORMERR; - } - - if (*str) { - ares_free(*str); - } - *str = val; - - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_str(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - const char *val) -{ - ares_status_t status; - char *temp = NULL; - - if (val != NULL) { - temp = ares_strdup(val); - if (temp == NULL) { - return ARES_ENOMEM; - } - } - - status = ares_dns_rr_set_str_own(dns_rr, key, temp); - if (status != ARES_SUCCESS) { - ares_free(temp); - } - - return status; -} - -ares_status_t ares_dns_rr_set_abin_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - ares_dns_multistring_t *strs) -{ - ares_dns_multistring_t **strs_ptr; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_ABINP) { - return ARES_EFORMERR; - } - - strs_ptr = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (strs_ptr == NULL) { - return ARES_EFORMERR; - } - - if (*strs_ptr != NULL) { - ares_dns_multistring_destroy(*strs_ptr); - } - *strs_ptr = strs; - - return ARES_SUCCESS; -} - -static void ares_dns_opt_free_cb(void *arg) -{ - ares_dns_optval_t *opt = arg; - if (opt == NULL) { - return; - } - ares_free(opt->val); -} - -ares_status_t ares_dns_rr_set_opt_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, unsigned short opt, - unsigned char *val, size_t val_len) -{ - ares_array_t **options; - ares_dns_optval_t *optptr = NULL; - size_t idx; - size_t cnt; - ares_status_t status; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { - return ARES_EFORMERR; - } - - options = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (options == NULL) { - return ARES_EFORMERR; - } - - if (*options == NULL) { - *options = - ares_array_create(sizeof(ares_dns_optval_t), ares_dns_opt_free_cb); - } - if (*options == NULL) { - return ARES_ENOMEM; - } - - cnt = ares_array_len(*options); - for (idx = 0; idx < cnt; idx++) { - optptr = ares_array_at(*options, idx); - if (optptr == NULL) { - return ARES_EFORMERR; - } - if (optptr->opt == opt) { - break; - } - } - - /* Duplicate entry, replace */ - if (idx != cnt && optptr != NULL) { - goto done; - } - - status = ares_array_insert_last((void **)&optptr, *options); - if (status != ARES_SUCCESS) { - return status; - } - -done: - ares_free(optptr->val); - optptr->opt = opt; - optptr->val = val; - optptr->val_len = val_len; - - return ARES_SUCCESS; -} - -ares_status_t ares_dns_rr_set_opt(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - unsigned short opt, const unsigned char *val, - size_t val_len) -{ - unsigned char *temp = NULL; - ares_status_t status; - - if (val != NULL) { - temp = ares_malloc(val_len + 1); - if (temp == NULL) { - return ARES_ENOMEM; - } - memcpy(temp, val, val_len); - temp[val_len] = 0; - } - - status = ares_dns_rr_set_opt_own(dns_rr, key, opt, temp, val_len); - if (status != ARES_SUCCESS) { - ares_free(temp); - } - - return status; -} - -ares_status_t ares_dns_rr_del_opt_byid(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - unsigned short opt) -{ - ares_array_t **options; - const ares_dns_optval_t *optptr; - size_t idx; - size_t cnt; - - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { - return ARES_EFORMERR; - } - - options = ares_dns_rr_data_ptr(dns_rr, key, NULL); - if (options == NULL) { - return ARES_EFORMERR; - } - - /* No options */ - if (*options == NULL) { - return ARES_SUCCESS; - } - - cnt = ares_array_len(*options); - for (idx = 0; idx < cnt; idx++) { - optptr = ares_array_at_const(*options, idx); - if (optptr == NULL) { - return ARES_ENOTFOUND; - } - if (optptr->opt == opt) { - return ares_array_remove_at(*options, idx); - } - } - - return ARES_ENOTFOUND; -} - -char *ares_dns_addr_to_ptr(const struct ares_addr *addr) -{ - ares_buf_t *buf = NULL; - const unsigned char *ptr = NULL; - size_t ptr_len = 0; - size_t i; - ares_status_t status; - static const unsigned char hexbytes[] = "0123456789abcdef"; - - if (addr->family != AF_INET && addr->family != AF_INET6) { - goto fail; - } - - buf = ares_buf_create(); - if (buf == NULL) { - goto fail; - } - - if (addr->family == AF_INET) { - ptr = (const unsigned char *)&addr->addr.addr4; - ptr_len = 4; - } else { - ptr = (const unsigned char *)&addr->addr.addr6; - ptr_len = 16; - } - - for (i = ptr_len; i > 0; i--) { - if (addr->family == AF_INET) { - status = ares_buf_append_num_dec(buf, (size_t)ptr[i - 1], 0); - } else { - unsigned char c; - - c = ptr[i - 1] & 0xF; - status = ares_buf_append_byte(buf, hexbytes[c]); - if (status != ARES_SUCCESS) { - goto fail; - } - - status = ares_buf_append_byte(buf, '.'); - if (status != ARES_SUCCESS) { - goto fail; - } - - c = (ptr[i - 1] >> 4) & 0xF; - status = ares_buf_append_byte(buf, hexbytes[c]); - } - if (status != ARES_SUCCESS) { - goto fail; - } - - status = ares_buf_append_byte(buf, '.'); - if (status != ARES_SUCCESS) { - goto fail; - } - } - - if (addr->family == AF_INET) { - status = ares_buf_append(buf, (const unsigned char *)"in-addr.arpa", 12); - } else { - status = ares_buf_append(buf, (const unsigned char *)"ip6.arpa", 8); - } - if (status != ARES_SUCCESS) { - goto fail; - } - - return ares_buf_finish_str(buf, NULL); - -fail: - ares_buf_destroy(buf); - return NULL; -} - -ares_dns_rr_t *ares_dns_get_opt_rr(ares_dns_record_t *rec) -{ - size_t i; - for (i = 0; i < ares_dns_record_rr_cnt(rec, ARES_SECTION_ADDITIONAL); i++) { - ares_dns_rr_t *rr = ares_dns_record_rr_get(rec, ARES_SECTION_ADDITIONAL, i); - - if (ares_dns_rr_get_type(rr) == ARES_REC_TYPE_OPT) { - return rr; - } - } - return NULL; -} - -const ares_dns_rr_t *ares_dns_get_opt_rr_const(const ares_dns_record_t *rec) -{ - size_t i; - for (i = 0; i < ares_dns_record_rr_cnt(rec, ARES_SECTION_ADDITIONAL); i++) { - const ares_dns_rr_t *rr = - ares_dns_record_rr_get_const(rec, ARES_SECTION_ADDITIONAL, i); - - if (ares_dns_rr_get_type(rr) == ARES_REC_TYPE_OPT) { - return rr; - } - } - return NULL; -} - -/* Construct a DNS record for a name with given class and type. Used internally - * by ares_search() and ares_create_query(). - */ -ares_status_t - ares_dns_record_create_query(ares_dns_record_t **dnsrec, const char *name, - ares_dns_class_t dnsclass, - ares_dns_rec_type_t type, unsigned short id, - ares_dns_flags_t flags, size_t max_udp_size) -{ - ares_status_t status; - ares_dns_rr_t *rr = NULL; - - if (dnsrec == NULL) { - return ARES_EFORMERR; - } - - *dnsrec = NULL; - - /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN */ - if (ares_is_onion_domain(name)) { - status = ARES_ENOTFOUND; - goto done; - } - - status = ares_dns_record_create(dnsrec, id, (unsigned short)flags, - ARES_OPCODE_QUERY, ARES_RCODE_NOERROR); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_record_query_add(*dnsrec, name, type, dnsclass); - if (status != ARES_SUCCESS) { - goto done; - } - - /* max_udp_size > 0 indicates EDNS, so send OPT RR as an additional record */ - if (max_udp_size > 0) { - /* max_udp_size must fit into a 16 bit unsigned integer field on the OPT - * RR, so check here that it fits - */ - if (max_udp_size > 65535) { - status = ARES_EFORMERR; - goto done; - } - - status = ares_dns_record_rr_add(&rr, *dnsrec, ARES_SECTION_ADDITIONAL, "", - ARES_REC_TYPE_OPT, ARES_CLASS_IN, 0); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_rr_set_u16(rr, ARES_RR_OPT_UDP_SIZE, - (unsigned short)max_udp_size); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_rr_set_u8(rr, ARES_RR_OPT_VERSION, 0); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_rr_set_u16(rr, ARES_RR_OPT_FLAGS, 0); - if (status != ARES_SUCCESS) { - goto done; - } - } - -done: - if (status != ARES_SUCCESS) { - ares_dns_record_destroy(*dnsrec); - *dnsrec = NULL; - } - return status; -} - -ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest, - const ares_dns_record_t *src) -{ - unsigned char *data = NULL; - size_t data_len = 0; - ares_status_t status; - - if (dest == NULL || src == NULL) { - return ARES_EFORMERR; - } - - *dest = NULL; - - status = ares_dns_write(src, &data, &data_len); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_parse(data, data_len, 0, dest); - ares_free(data); - - return status; -} - -ares_dns_record_t *ares_dns_record_duplicate(const ares_dns_record_t *dnsrec) -{ - ares_dns_record_t *dest = NULL; - - ares_dns_record_duplicate_ex(&dest, dnsrec); - return dest; -} diff --git a/vendor/c-ares/src/lib/record/ares_dns_write.c b/vendor/c-ares/src/lib/record/ares_dns_write.c deleted file mode 100644 index 549017ffb..000000000 --- a/vendor/c-ares/src/lib/record/ares_dns_write.c +++ /dev/null @@ -1,1229 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include -#ifdef HAVE_STDINT_H -# include -#endif - - -static ares_status_t ares_dns_write_header(const ares_dns_record_t *dnsrec, - ares_buf_t *buf) -{ - unsigned short u16; - unsigned short opcode; - unsigned short rcode; - - ares_status_t status; - - /* ID */ - status = ares_buf_append_be16(buf, dnsrec->id); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Flags */ - u16 = 0; - - /* QR */ - if (dnsrec->flags & ARES_FLAG_QR) { - u16 |= 0x8000; - } - - /* OPCODE */ - opcode = (unsigned short)(dnsrec->opcode & 0xF); - opcode <<= 11; - u16 |= opcode; - - /* AA */ - if (dnsrec->flags & ARES_FLAG_AA) { - u16 |= 0x400; - } - - /* TC */ - if (dnsrec->flags & ARES_FLAG_TC) { - u16 |= 0x200; - } - - /* RD */ - if (dnsrec->flags & ARES_FLAG_RD) { - u16 |= 0x100; - } - - /* RA */ - if (dnsrec->flags & ARES_FLAG_RA) { - u16 |= 0x80; - } - - /* Z -- unused */ - - /* AD */ - if (dnsrec->flags & ARES_FLAG_AD) { - u16 |= 0x20; - } - - /* CD */ - if (dnsrec->flags & ARES_FLAG_CD) { - u16 |= 0x10; - } - - /* RCODE */ - if (dnsrec->rcode > 15 && ares_dns_get_opt_rr_const(dnsrec) == NULL) { - /* Must have OPT RR in order to write extended error codes */ - rcode = ARES_RCODE_SERVFAIL; - } else { - rcode = (unsigned short)(dnsrec->rcode & 0xF); - } - u16 |= rcode; - - status = ares_buf_append_be16(buf, u16); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* QDCOUNT */ - status = ares_buf_append_be16( - buf, (unsigned short)ares_dns_record_query_cnt(dnsrec)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* ANCOUNT */ - status = ares_buf_append_be16( - buf, (unsigned short)ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* NSCOUNT */ - status = ares_buf_append_be16(buf, (unsigned short)ares_dns_record_rr_cnt( - dnsrec, ARES_SECTION_AUTHORITY)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* ARCOUNT */ - status = ares_buf_append_be16(buf, (unsigned short)ares_dns_record_rr_cnt( - dnsrec, ARES_SECTION_ADDITIONAL)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_write_questions(const ares_dns_record_t *dnsrec, - ares_llist_t **namelist, - ares_buf_t *buf) -{ - size_t i; - - for (i = 0; i < ares_dns_record_query_cnt(dnsrec); i++) { - ares_status_t status; - const char *name = NULL; - ares_dns_rec_type_t qtype; - ares_dns_class_t qclass; - - status = ares_dns_record_query_get(dnsrec, i, &name, &qtype, &qclass); - if (status != ARES_SUCCESS) { - return status; - } - - /* Name */ - status = ares_dns_name_write(buf, namelist, ARES_TRUE, name); - if (status != ARES_SUCCESS) { - return status; - } - - /* Type */ - status = ares_buf_append_be16(buf, (unsigned short)qtype); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Class */ - status = ares_buf_append_be16(buf, (unsigned short)qclass); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_write_rr_name(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist, - ares_bool_t validate_hostname, - ares_dns_rr_key_t key) -{ - const char *name; - - name = ares_dns_rr_get_str(rr, key); - if (name == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - return ares_dns_name_write(buf, namelist, validate_hostname, name); -} - -static ares_status_t ares_dns_write_rr_str(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - const char *str; - size_t len; - ares_status_t status; - - str = ares_dns_rr_get_str(rr, key); - if (str == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - len = ares_strlen(str); - if (len > 255) { - return ARES_EFORMERR; - } - - /* Write 1 byte length */ - status = ares_buf_append_byte(buf, (unsigned char)(len & 0xFF)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - if (len == 0) { - return ARES_SUCCESS; - } - - /* Write string */ - return ares_buf_append(buf, (const unsigned char *)str, len); -} - -static ares_status_t ares_dns_write_binstr(ares_buf_t *buf, - const unsigned char *bin, - size_t bin_len) -{ - const unsigned char *ptr; - size_t ptr_len; - ares_status_t status; - - /* split into possible multiple 255-byte or less length strings */ - ptr = bin; - ptr_len = bin_len; - do { - size_t len = ptr_len; - if (len > 255) { - len = 255; - } - - /* Length */ - status = ares_buf_append_byte(buf, (unsigned char)(len & 0xFF)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* String */ - if (len) { - status = ares_buf_append(buf, ptr, len); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - ptr += len; - ptr_len -= len; - } while (ptr_len > 0); - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_write_rr_abin(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - ares_status_t status = ARES_EFORMERR; - size_t i; - size_t cnt = ares_dns_rr_get_abin_cnt(rr, key); - - if (cnt == 0) { - return ARES_EFORMERR; - } - - for (i = 0; i < cnt; i++) { - const unsigned char *bin; - size_t bin_len; - - bin = ares_dns_rr_get_abin(rr, key, i, &bin_len); - - status = ares_dns_write_binstr(buf, bin, bin_len); - if (status != ARES_SUCCESS) { - break; - } - } - - return status; -} - -static ares_status_t ares_dns_write_rr_be32(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U32) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - return ares_buf_append_be32(buf, ares_dns_rr_get_u32(rr, key)); -} - -static ares_status_t ares_dns_write_rr_be16(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U16) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - return ares_buf_append_be16(buf, ares_dns_rr_get_u16(rr, key)); -} - -static ares_status_t ares_dns_write_rr_u8(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_dns_rr_key_t key) -{ - if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_U8) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - return ares_buf_append_byte(buf, ares_dns_rr_get_u8(rr, key)); -} - -static ares_status_t ares_dns_write_rr_a(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - const struct in_addr *addr; - (void)namelist; - - addr = ares_dns_rr_get_addr(rr, ARES_RR_A_ADDR); - if (addr == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - return ares_buf_append(buf, (const unsigned char *)addr, sizeof(*addr)); -} - -static ares_status_t ares_dns_write_rr_ns(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - return ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, - ARES_RR_NS_NSDNAME); -} - -static ares_status_t ares_dns_write_rr_cname(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - return ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, - ARES_RR_CNAME_CNAME); -} - -static ares_status_t ares_dns_write_rr_soa(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - - /* MNAME */ - status = - ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, ARES_RR_SOA_MNAME); - if (status != ARES_SUCCESS) { - return status; - } - - /* RNAME */ - status = - ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, ARES_RR_SOA_RNAME); - if (status != ARES_SUCCESS) { - return status; - } - - /* SERIAL */ - status = ares_dns_write_rr_be32(buf, rr, ARES_RR_SOA_SERIAL); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* REFRESH */ - status = ares_dns_write_rr_be32(buf, rr, ARES_RR_SOA_REFRESH); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* RETRY */ - status = ares_dns_write_rr_be32(buf, rr, ARES_RR_SOA_RETRY); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* EXPIRE */ - status = ares_dns_write_rr_be32(buf, rr, ARES_RR_SOA_EXPIRE); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* MINIMUM */ - return ares_dns_write_rr_be32(buf, rr, ARES_RR_SOA_MINIMUM); -} - -static ares_status_t ares_dns_write_rr_ptr(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - return ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, - ARES_RR_PTR_DNAME); -} - -static ares_status_t ares_dns_write_rr_hinfo(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - - (void)namelist; - - /* CPU */ - status = ares_dns_write_rr_str(buf, rr, ARES_RR_HINFO_CPU); - if (status != ARES_SUCCESS) { - return status; - } - - /* OS */ - return ares_dns_write_rr_str(buf, rr, ARES_RR_HINFO_OS); -} - -static ares_status_t ares_dns_write_rr_mx(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - - /* PREFERENCE */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_MX_PREFERENCE); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* EXCHANGE */ - return ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, - ARES_RR_MX_EXCHANGE); -} - -static ares_status_t ares_dns_write_rr_txt(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - (void)namelist; - return ares_dns_write_rr_abin(buf, rr, ARES_RR_TXT_DATA); -} - -static ares_status_t ares_dns_write_rr_sig(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - const unsigned char *data; - size_t len = 0; - - (void)namelist; - - /* TYPE COVERED */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_SIG_TYPE_COVERED); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* ALGORITHM */ - status = ares_dns_write_rr_u8(buf, rr, ARES_RR_SIG_ALGORITHM); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* LABELS */ - status = ares_dns_write_rr_u8(buf, rr, ARES_RR_SIG_LABELS); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* ORIGINAL TTL */ - status = ares_dns_write_rr_be32(buf, rr, ARES_RR_SIG_ORIGINAL_TTL); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* EXPIRATION */ - status = ares_dns_write_rr_be32(buf, rr, ARES_RR_SIG_EXPIRATION); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* INCEPTION */ - status = ares_dns_write_rr_be32(buf, rr, ARES_RR_SIG_INCEPTION); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* KEY TAG */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_SIG_KEY_TAG); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* SIGNERS NAME */ - status = ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, - ARES_RR_SIG_SIGNERS_NAME); - if (status != ARES_SUCCESS) { - return status; - } - - /* SIGNATURE -- binary, rest of buffer, required to be non-zero length */ - data = ares_dns_rr_get_bin(rr, ARES_RR_SIG_SIGNATURE, &len); - if (data == NULL || len == 0) { - return ARES_EFORMERR; - } - - return ares_buf_append(buf, data, len); -} - -static ares_status_t ares_dns_write_rr_aaaa(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - const struct ares_in6_addr *addr; - (void)namelist; - - addr = ares_dns_rr_get_addr6(rr, ARES_RR_AAAA_ADDR); - if (addr == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - return ares_buf_append(buf, (const unsigned char *)addr, sizeof(*addr)); -} - -static ares_status_t ares_dns_write_rr_srv(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - - /* PRIORITY */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_SRV_PRIORITY); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* WEIGHT */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_SRV_WEIGHT); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* PORT */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_SRV_PORT); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* TARGET */ - return ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, - ARES_RR_SRV_TARGET); -} - -static ares_status_t ares_dns_write_rr_naptr(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - - /* ORDER */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_NAPTR_ORDER); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* PREFERENCE */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_NAPTR_PREFERENCE); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* FLAGS */ - status = ares_dns_write_rr_str(buf, rr, ARES_RR_NAPTR_FLAGS); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* SERVICES */ - status = ares_dns_write_rr_str(buf, rr, ARES_RR_NAPTR_SERVICES); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* REGEXP */ - status = ares_dns_write_rr_str(buf, rr, ARES_RR_NAPTR_REGEXP); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* REPLACEMENT */ - return ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, - ARES_RR_NAPTR_REPLACEMENT); -} - -static ares_status_t ares_dns_write_rr_opt(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - size_t len = ares_buf_len(buf); - ares_status_t status; - unsigned int ttl = 0; - size_t i; - unsigned short rcode = (unsigned short)((rr->parent->rcode >> 4) & 0xFF); - - (void)namelist; - - /* Coverity reports on this even though its not possible when taken - * into context */ - if (len == 0) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* We need to go back and overwrite the class and ttl that were emitted as - * the OPT record overloads them for its own use (yes, very strange!) */ - status = ares_buf_set_length(buf, len - 2 /* RDLENGTH */ - - 4 /* TTL */ - - 2 /* CLASS */); - if (status != ARES_SUCCESS) { - return status; - } - - /* Class -> UDP Size */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_OPT_UDP_SIZE); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* TTL -> rcode (u8) << 24 | version (u8) << 16 | flags (u16) */ - ttl |= (unsigned int)rcode << 24; - ttl |= (unsigned int)ares_dns_rr_get_u8(rr, ARES_RR_OPT_VERSION) << 16; - ttl |= (unsigned int)ares_dns_rr_get_u16(rr, ARES_RR_OPT_FLAGS); - - status = ares_buf_append_be32(buf, ttl); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Now go back to real end */ - status = ares_buf_set_length(buf, len); - if (status != ARES_SUCCESS) { - return status; - } - - /* Append Options */ - for (i = 0; i < ares_dns_rr_get_opt_cnt(rr, ARES_RR_OPT_OPTIONS); i++) { - unsigned short opt; - size_t val_len; - const unsigned char *val; - - opt = ares_dns_rr_get_opt(rr, ARES_RR_OPT_OPTIONS, i, &val, &val_len); - - /* BE16 option */ - status = ares_buf_append_be16(buf, opt); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* BE16 length */ - status = ares_buf_append_be16(buf, (unsigned short)(val_len & 0xFFFF)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Value */ - if (val && val_len) { - status = ares_buf_append(buf, val, val_len); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_write_rr_tlsa(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - const unsigned char *data; - size_t len = 0; - - (void)namelist; - - /* CERT_USAGE */ - status = ares_dns_write_rr_u8(buf, rr, ARES_RR_TLSA_CERT_USAGE); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* SELECTOR */ - status = ares_dns_write_rr_u8(buf, rr, ARES_RR_TLSA_SELECTOR); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* MATCH */ - status = ares_dns_write_rr_u8(buf, rr, ARES_RR_TLSA_MATCH); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* DATA -- binary, rest of buffer, required to be non-zero length */ - data = ares_dns_rr_get_bin(rr, ARES_RR_TLSA_DATA, &len); - if (data == NULL || len == 0) { - return ARES_EFORMERR; - } - - return ares_buf_append(buf, data, len); -} - -static ares_status_t ares_dns_write_rr_svcb(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - size_t i; - - /* PRIORITY */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_SVCB_PRIORITY); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* TARGET */ - status = - ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, ARES_RR_SVCB_TARGET); - if (status != ARES_SUCCESS) { - return status; - } - - /* Append Params */ - for (i = 0; i < ares_dns_rr_get_opt_cnt(rr, ARES_RR_SVCB_PARAMS); i++) { - unsigned short opt; - size_t val_len; - const unsigned char *val; - - opt = ares_dns_rr_get_opt(rr, ARES_RR_SVCB_PARAMS, i, &val, &val_len); - - /* BE16 option */ - status = ares_buf_append_be16(buf, opt); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* BE16 length */ - status = ares_buf_append_be16(buf, (unsigned short)(val_len & 0xFFFF)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Value */ - if (val && val_len) { - status = ares_buf_append(buf, val, val_len); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_write_rr_https(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - size_t i; - - /* PRIORITY */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_HTTPS_PRIORITY); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* TARGET */ - status = - ares_dns_write_rr_name(buf, rr, namelist, ARES_FALSE, ARES_RR_HTTPS_TARGET); - if (status != ARES_SUCCESS) { - return status; - } - - /* Append Params */ - for (i = 0; i < ares_dns_rr_get_opt_cnt(rr, ARES_RR_HTTPS_PARAMS); i++) { - unsigned short opt; - size_t val_len; - const unsigned char *val; - - opt = ares_dns_rr_get_opt(rr, ARES_RR_HTTPS_PARAMS, i, &val, &val_len); - - /* BE16 option */ - status = ares_buf_append_be16(buf, opt); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* BE16 length */ - status = ares_buf_append_be16(buf, (unsigned short)(val_len & 0xFFFF)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Value */ - if (val && val_len) { - status = ares_buf_append(buf, val, val_len); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - } - return ARES_SUCCESS; -} - -static ares_status_t ares_dns_write_rr_uri(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - ares_status_t status; - const char *target; - - (void)namelist; - - /* PRIORITY */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_URI_PRIORITY); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* WEIGHT */ - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_URI_WEIGHT); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* TARGET -- not in DNS string format, rest of buffer, required to be - * non-zero length */ - target = ares_dns_rr_get_str(rr, ARES_RR_URI_TARGET); - if (target == NULL || ares_strlen(target) == 0) { - return ARES_EFORMERR; - } - - return ares_buf_append(buf, (const unsigned char *)target, - ares_strlen(target)); -} - -static ares_status_t ares_dns_write_rr_caa(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - const unsigned char *data = NULL; - size_t data_len = 0; - ares_status_t status; - - (void)namelist; - - /* CRITICAL */ - status = ares_dns_write_rr_u8(buf, rr, ARES_RR_CAA_CRITICAL); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Tag */ - status = ares_dns_write_rr_str(buf, rr, ARES_RR_CAA_TAG); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Value - binary! (remaining buffer */ - data = ares_dns_rr_get_bin(rr, ARES_RR_CAA_VALUE, &data_len); - if (data == NULL || data_len == 0) { - return ARES_EFORMERR; - } - - return ares_buf_append(buf, data, data_len); -} - -static ares_status_t ares_dns_write_rr_raw_rr(ares_buf_t *buf, - const ares_dns_rr_t *rr, - ares_llist_t **namelist) -{ - size_t len = ares_buf_len(buf); - ares_status_t status; - const unsigned char *data = NULL; - size_t data_len = 0; - - (void)namelist; - - /* Coverity reports on this even though its not possible when taken - * into context */ - if (len == 0) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* We need to go back and overwrite the type that was emitted by the parent - * function */ - status = ares_buf_set_length(buf, len - 2 /* RDLENGTH */ - - 4 /* TTL */ - - 2 /* CLASS */ - - 2 /* TYPE */); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_dns_write_rr_be16(buf, rr, ARES_RR_RAW_RR_TYPE); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Now go back to real end */ - status = ares_buf_set_length(buf, len); - if (status != ARES_SUCCESS) { - return status; - } - - /* Output raw data */ - data = ares_dns_rr_get_bin(rr, ARES_RR_RAW_RR_DATA, &data_len); - if (data == NULL) { - return ARES_EFORMERR; - } - - if (data_len == 0) { - return ARES_SUCCESS; - } - - return ares_buf_append(buf, data, data_len); -} - -static ares_status_t ares_dns_write_rr(const ares_dns_record_t *dnsrec, - ares_llist_t **namelist, - ares_dns_section_t section, - ares_buf_t *buf) -{ - size_t i; - - for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, section); i++) { - const ares_dns_rr_t *rr; - ares_dns_rec_type_t type; - ares_bool_t allow_compress; - ares_llist_t **namelistptr = NULL; - size_t pos_len; - ares_status_t status; - size_t rdlength; - size_t end_length; - unsigned int ttl; - - rr = ares_dns_record_rr_get_const(dnsrec, section, i); - if (rr == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - type = ares_dns_rr_get_type(rr); - allow_compress = ares_dns_rec_allow_name_comp(type); - if (allow_compress) { - namelistptr = namelist; - } - - /* Name */ - status = - ares_dns_name_write(buf, namelist, ARES_TRUE, ares_dns_rr_get_name(rr)); - if (status != ARES_SUCCESS) { - return status; - } - - /* Type */ - status = ares_buf_append_be16(buf, (unsigned short)type); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Class */ - status = - ares_buf_append_be16(buf, (unsigned short)ares_dns_rr_get_class(rr)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* TTL */ - ttl = ares_dns_rr_get_ttl(rr); - if (rr->parent->ttl_decrement > ttl) { - ttl = 0; - } else { - ttl -= rr->parent->ttl_decrement; - } - status = ares_buf_append_be32(buf, ttl); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Length */ - pos_len = ares_buf_len(buf); /* Save to write real length later */ - status = ares_buf_append_be16(buf, 0); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Data */ - switch (type) { - case ARES_REC_TYPE_A: - status = ares_dns_write_rr_a(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_NS: - status = ares_dns_write_rr_ns(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_CNAME: - status = ares_dns_write_rr_cname(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_SOA: - status = ares_dns_write_rr_soa(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_PTR: - status = ares_dns_write_rr_ptr(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_HINFO: - status = ares_dns_write_rr_hinfo(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_MX: - status = ares_dns_write_rr_mx(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_TXT: - status = ares_dns_write_rr_txt(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_SIG: - status = ares_dns_write_rr_sig(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_AAAA: - status = ares_dns_write_rr_aaaa(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_SRV: - status = ares_dns_write_rr_srv(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_NAPTR: - status = ares_dns_write_rr_naptr(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_ANY: - status = ARES_EFORMERR; - break; - case ARES_REC_TYPE_OPT: - status = ares_dns_write_rr_opt(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_TLSA: - status = ares_dns_write_rr_tlsa(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_SVCB: - status = ares_dns_write_rr_svcb(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_HTTPS: - status = ares_dns_write_rr_https(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_URI: - status = ares_dns_write_rr_uri(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_CAA: - status = ares_dns_write_rr_caa(buf, rr, namelistptr); - break; - case ARES_REC_TYPE_RAW_RR: - status = ares_dns_write_rr_raw_rr(buf, rr, namelistptr); - break; - } - - if (status != ARES_SUCCESS) { - return status; - } - - /* Back off write pointer, write real length, then go back to proper - * position */ - end_length = ares_buf_len(buf); - rdlength = end_length - pos_len - 2; - - status = ares_buf_set_length(buf, pos_len); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_buf_append_be16(buf, (unsigned short)(rdlength & 0xFFFF)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_set_length(buf, end_length); - if (status != ARES_SUCCESS) { - return status; - } - } - - return ARES_SUCCESS; -} - -ares_status_t ares_dns_write_buf(const ares_dns_record_t *dnsrec, - ares_buf_t *buf) -{ - ares_llist_t *namelist = NULL; - size_t orig_len; - ares_status_t status; - - if (dnsrec == NULL || buf == NULL) { - return ARES_EFORMERR; - } - - orig_len = ares_buf_len(buf); - - status = ares_dns_write_header(dnsrec, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_write_questions(dnsrec, &namelist, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_ANSWER, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_AUTHORITY, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_ADDITIONAL, buf); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_llist_destroy(namelist); - if (status != ARES_SUCCESS) { - ares_buf_set_length(buf, orig_len); - } - - return status; -} - -ares_status_t ares_dns_write_buf_tcp(const ares_dns_record_t *dnsrec, - ares_buf_t *buf) -{ - ares_status_t status; - size_t orig_len; - size_t msg_len; - size_t len; - - if (dnsrec == NULL || buf == NULL) { - return ARES_EFORMERR; - } - - orig_len = ares_buf_len(buf); - - /* Write placeholder for length */ - status = ares_buf_append_be16(buf, 0); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* Write message */ - status = ares_dns_write_buf(dnsrec, buf); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - len = ares_buf_len(buf); - msg_len = len - orig_len - 2; - if (msg_len > 65535) { - status = ARES_EBADQUERY; - goto done; - } - - /* Now we need to overwrite the length, so we jump back to the original - * message length, overwrite the section and jump back */ - ares_buf_set_length(buf, orig_len); - status = ares_buf_append_be16(buf, (unsigned short)(msg_len & 0xFFFF)); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: UntestablePath */ - } - ares_buf_set_length(buf, len); - -done: - if (status != ARES_SUCCESS) { - ares_buf_set_length(buf, orig_len); - } - return status; -} - -ares_status_t ares_dns_write(const ares_dns_record_t *dnsrec, - unsigned char **buf, size_t *buf_len) -{ - ares_buf_t *b = NULL; - ares_status_t status; - - if (buf == NULL || buf_len == NULL || dnsrec == NULL) { - return ARES_EFORMERR; - } - - *buf = NULL; - *buf_len = 0; - - b = ares_buf_create(); - if (b == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_dns_write_buf(dnsrec, b); - - if (status != ARES_SUCCESS) { - ares_buf_destroy(b); - return status; - } - - *buf = ares_buf_finish_bin(b, buf_len); - return status; -} - -void ares_dns_record_ttl_decrement(ares_dns_record_t *dnsrec, - unsigned int ttl_decrement) -{ - if (dnsrec == NULL) { - return; - } - dnsrec->ttl_decrement = ttl_decrement; -} diff --git a/vendor/c-ares/src/lib/str/ares_buf.c b/vendor/c-ares/src/lib/str/ares_buf.c deleted file mode 100644 index 63acc6cf7..000000000 --- a/vendor/c-ares/src/lib/str/ares_buf.c +++ /dev/null @@ -1,1498 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" -#include "ares_buf.h" -#include -#ifdef HAVE_STDINT_H -# include -#endif - -struct ares_buf { - const unsigned char *data; /*!< pointer to start of data buffer */ - size_t data_len; /*!< total size of data in buffer */ - - unsigned char *alloc_buf; /*!< Pointer to allocated data buffer, - * not used for const buffers */ - size_t alloc_buf_len; /*!< Size of allocated data buffer */ - - size_t offset; /*!< Current working offset in buffer */ - size_t tag_offset; /*!< Tagged offset in buffer. Uses - * SIZE_MAX if not set. */ -}; - -ares_buf_t *ares_buf_create(void) -{ - ares_buf_t *buf = ares_malloc_zero(sizeof(*buf)); - if (buf == NULL) { - return NULL; - } - - buf->tag_offset = SIZE_MAX; - return buf; -} - -ares_buf_t *ares_buf_create_const(const unsigned char *data, size_t data_len) -{ - ares_buf_t *buf; - - if (data == NULL || data_len == 0) { - return NULL; - } - - buf = ares_buf_create(); - if (buf == NULL) { - return NULL; - } - - buf->data = data; - buf->data_len = data_len; - - return buf; -} - -void ares_buf_destroy(ares_buf_t *buf) -{ - if (buf == NULL) { - return; - } - ares_free(buf->alloc_buf); - ares_free(buf); -} - -static ares_bool_t ares_buf_is_const(const ares_buf_t *buf) -{ - if (buf == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (buf->data != NULL && buf->alloc_buf == NULL) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -void ares_buf_reclaim(ares_buf_t *buf) -{ - size_t prefix_size; - size_t data_size; - - if (buf == NULL) { - return; - } - - if (ares_buf_is_const(buf)) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Silence coverity. All lengths are zero so would bail out later but - * coverity doesn't know this */ - if (buf->alloc_buf == NULL) { - return; - } - - if (buf->tag_offset != SIZE_MAX && buf->tag_offset < buf->offset) { - prefix_size = buf->tag_offset; - } else { - prefix_size = buf->offset; - } - - if (prefix_size == 0) { - return; - } - - data_size = buf->data_len - prefix_size; - - memmove(buf->alloc_buf, buf->alloc_buf + prefix_size, data_size); - buf->data = buf->alloc_buf; - buf->data_len = data_size; - buf->offset -= prefix_size; - if (buf->tag_offset != SIZE_MAX) { - buf->tag_offset -= prefix_size; - } -} - -static ares_status_t ares_buf_ensure_space(ares_buf_t *buf, size_t needed_size) -{ - size_t remaining_size; - size_t alloc_size; - unsigned char *ptr; - - if (buf == NULL) { - return ARES_EFORMERR; - } - - if (ares_buf_is_const(buf)) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* When calling ares_buf_finish_str() we end up adding a null terminator, - * so we want to ensure the size is always sufficient for this as we don't - * want an ARES_ENOMEM at that point */ - needed_size++; - - /* No need to do an expensive move operation, we have enough to just append */ - remaining_size = buf->alloc_buf_len - buf->data_len; - if (remaining_size >= needed_size) { - return ARES_SUCCESS; - } - - /* See if just moving consumed data frees up enough space */ - ares_buf_reclaim(buf); - - remaining_size = buf->alloc_buf_len - buf->data_len; - if (remaining_size >= needed_size) { - return ARES_SUCCESS; - } - - alloc_size = buf->alloc_buf_len; - - /* Not yet started */ - if (alloc_size == 0) { - alloc_size = 16; /* Always shifts 1, so ends up being 32 minimum */ - } - - /* Increase allocation by powers of 2 */ - do { - alloc_size <<= 1; - remaining_size = alloc_size - buf->data_len; - } while (remaining_size < needed_size); - - ptr = ares_realloc(buf->alloc_buf, alloc_size); - if (ptr == NULL) { - return ARES_ENOMEM; - } - - buf->alloc_buf = ptr; - buf->alloc_buf_len = alloc_size; - buf->data = ptr; - - return ARES_SUCCESS; -} - -ares_status_t ares_buf_set_length(ares_buf_t *buf, size_t len) -{ - if (buf == NULL || ares_buf_is_const(buf)) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (len >= buf->alloc_buf_len - buf->offset) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - buf->data_len = len + buf->offset; - return ARES_SUCCESS; -} - -ares_status_t ares_buf_append(ares_buf_t *buf, const unsigned char *data, - size_t data_len) -{ - ares_status_t status; - - if (data == NULL && data_len != 0) { - return ARES_EFORMERR; - } - - if (data_len == 0) { - return ARES_SUCCESS; - } - - status = ares_buf_ensure_space(buf, data_len); - if (status != ARES_SUCCESS) { - return status; - } - - memcpy(buf->alloc_buf + buf->data_len, data, data_len); - buf->data_len += data_len; - return ARES_SUCCESS; -} - -ares_status_t ares_buf_append_byte(ares_buf_t *buf, unsigned char b) -{ - return ares_buf_append(buf, &b, 1); -} - -ares_status_t ares_buf_append_be16(ares_buf_t *buf, unsigned short u16) -{ - ares_status_t status; - - status = ares_buf_append_byte(buf, (unsigned char)((u16 >> 8) & 0xff)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, (unsigned char)(u16 & 0xff)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; -} - -ares_status_t ares_buf_append_be32(ares_buf_t *buf, unsigned int u32) -{ - ares_status_t status; - - status = ares_buf_append_byte(buf, ((unsigned char)(u32 >> 24) & 0xff)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, ((unsigned char)(u32 >> 16) & 0xff)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, ((unsigned char)(u32 >> 8) & 0xff)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, ((unsigned char)u32 & 0xff)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; -} - -unsigned char *ares_buf_append_start(ares_buf_t *buf, size_t *len) -{ - ares_status_t status; - - if (len == NULL || *len == 0) { - return NULL; - } - - status = ares_buf_ensure_space(buf, *len); - if (status != ARES_SUCCESS) { - return NULL; - } - - /* -1 for possible null terminator for ares_buf_finish_str() */ - *len = buf->alloc_buf_len - buf->data_len - 1; - return buf->alloc_buf + buf->data_len; -} - -void ares_buf_append_finish(ares_buf_t *buf, size_t len) -{ - if (buf == NULL) { - return; - } - - buf->data_len += len; -} - -unsigned char *ares_buf_finish_bin(ares_buf_t *buf, size_t *len) -{ - unsigned char *ptr = NULL; - if (buf == NULL || len == NULL || ares_buf_is_const(buf)) { - return NULL; - } - - ares_buf_reclaim(buf); - - /* We don't want to return NULL except on failure, may be zero-length */ - if (buf->alloc_buf == NULL && ares_buf_ensure_space(buf, 1) != ARES_SUCCESS) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - ptr = buf->alloc_buf; - *len = buf->data_len; - ares_free(buf); - return ptr; -} - -char *ares_buf_finish_str(ares_buf_t *buf, size_t *len) -{ - char *ptr; - size_t mylen; - - ptr = (char *)ares_buf_finish_bin(buf, &mylen); - if (ptr == NULL) { - return NULL; - } - - if (len != NULL) { - *len = mylen; - } - - /* NOTE: ensured via ares_buf_ensure_space() that there is always at least - * 1 extra byte available for this specific use-case */ - ptr[mylen] = 0; - - return ptr; -} - -void ares_buf_tag(ares_buf_t *buf) -{ - if (buf == NULL) { - return; - } - - buf->tag_offset = buf->offset; -} - -ares_status_t ares_buf_tag_rollback(ares_buf_t *buf) -{ - if (buf == NULL || buf->tag_offset == SIZE_MAX) { - return ARES_EFORMERR; - } - - buf->offset = buf->tag_offset; - buf->tag_offset = SIZE_MAX; - return ARES_SUCCESS; -} - -ares_status_t ares_buf_tag_clear(ares_buf_t *buf) -{ - if (buf == NULL || buf->tag_offset == SIZE_MAX) { - return ARES_EFORMERR; - } - - buf->tag_offset = SIZE_MAX; - return ARES_SUCCESS; -} - -const unsigned char *ares_buf_tag_fetch(const ares_buf_t *buf, size_t *len) -{ - if (buf == NULL || buf->tag_offset == SIZE_MAX || len == NULL) { - return NULL; - } - - *len = buf->offset - buf->tag_offset; - return buf->data + buf->tag_offset; -} - -size_t ares_buf_tag_length(const ares_buf_t *buf) -{ - if (buf == NULL || buf->tag_offset == SIZE_MAX) { - return 0; - } - return buf->offset - buf->tag_offset; -} - -ares_status_t ares_buf_tag_fetch_bytes(const ares_buf_t *buf, - unsigned char *bytes, size_t *len) -{ - size_t ptr_len = 0; - const unsigned char *ptr = ares_buf_tag_fetch(buf, &ptr_len); - - if (ptr == NULL || bytes == NULL || len == NULL) { - return ARES_EFORMERR; - } - - if (*len < ptr_len) { - return ARES_EFORMERR; - } - - *len = ptr_len; - - if (ptr_len > 0) { - memcpy(bytes, ptr, ptr_len); - } - return ARES_SUCCESS; -} - -ares_status_t ares_buf_tag_fetch_constbuf(const ares_buf_t *buf, - ares_buf_t **newbuf) -{ - size_t ptr_len = 0; - const unsigned char *ptr = ares_buf_tag_fetch(buf, &ptr_len); - - if (ptr == NULL || newbuf == NULL) { - return ARES_EFORMERR; - } - - *newbuf = ares_buf_create_const(ptr, ptr_len); - if (*newbuf == NULL) { - return ARES_ENOMEM; - } - return ARES_SUCCESS; -} - -ares_status_t ares_buf_tag_fetch_string(const ares_buf_t *buf, char *str, - size_t len) -{ - size_t out_len; - ares_status_t status; - size_t i; - - if (str == NULL || len == 0) { - return ARES_EFORMERR; - } - - /* Space for NULL terminator */ - out_len = len - 1; - - status = ares_buf_tag_fetch_bytes(buf, (unsigned char *)str, &out_len); - if (status != ARES_SUCCESS) { - return status; - } - - /* NULL terminate */ - str[out_len] = 0; - - /* Validate string is printable */ - for (i = 0; i < out_len; i++) { - if (!ares_isprint(str[i])) { - return ARES_EBADSTR; - } - } - - return ARES_SUCCESS; -} - -ares_status_t ares_buf_tag_fetch_strdup(const ares_buf_t *buf, char **str) -{ - size_t ptr_len = 0; - const unsigned char *ptr = ares_buf_tag_fetch(buf, &ptr_len); - - if (ptr == NULL || str == NULL) { - return ARES_EFORMERR; - } - - if (!ares_str_isprint((const char *)ptr, ptr_len)) { - return ARES_EBADSTR; - } - - *str = ares_malloc(ptr_len + 1); - if (*str == NULL) { - return ARES_ENOMEM; - } - - if (ptr_len > 0) { - memcpy(*str, ptr, ptr_len); - } - (*str)[ptr_len] = 0; - return ARES_SUCCESS; -} - -static const unsigned char *ares_buf_fetch(const ares_buf_t *buf, size_t *len) -{ - if (len != NULL) { - *len = 0; - } - - if (buf == NULL || len == NULL || buf->data == NULL) { - return NULL; - } - - *len = buf->data_len - buf->offset; - if (*len == 0) { - return NULL; - } - - return buf->data + buf->offset; -} - -ares_status_t ares_buf_consume(ares_buf_t *buf, size_t len) -{ - size_t remaining_len = ares_buf_len(buf); - - if (remaining_len < len) { - return ARES_EBADRESP; - } - - buf->offset += len; - return ARES_SUCCESS; -} - -ares_status_t ares_buf_fetch_be16(ares_buf_t *buf, unsigned short *u16) -{ - size_t remaining_len; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - unsigned int u32; - - if (buf == NULL || u16 == NULL || remaining_len < sizeof(*u16)) { - return ARES_EBADRESP; - } - - /* Do math in an unsigned int in order to prevent warnings due to automatic - * conversion by the compiler from short to int during shifts */ - u32 = ((unsigned int)(ptr[0]) << 8 | (unsigned int)ptr[1]); - *u16 = (unsigned short)(u32 & 0xFFFF); - - return ares_buf_consume(buf, sizeof(*u16)); -} - -ares_status_t ares_buf_fetch_be32(ares_buf_t *buf, unsigned int *u32) -{ - size_t remaining_len; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - - if (buf == NULL || u32 == NULL || remaining_len < sizeof(*u32)) { - return ARES_EBADRESP; - } - - *u32 = ((unsigned int)(ptr[0]) << 24 | (unsigned int)(ptr[1]) << 16 | - (unsigned int)(ptr[2]) << 8 | (unsigned int)(ptr[3])); - - return ares_buf_consume(buf, sizeof(*u32)); -} - -ares_status_t ares_buf_fetch_bytes(ares_buf_t *buf, unsigned char *bytes, - size_t len) -{ - size_t remaining_len; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - - if (buf == NULL || bytes == NULL || len == 0 || remaining_len < len) { - return ARES_EBADRESP; - } - - memcpy(bytes, ptr, len); - return ares_buf_consume(buf, len); -} - -ares_status_t ares_buf_fetch_bytes_dup(ares_buf_t *buf, size_t len, - ares_bool_t null_term, - unsigned char **bytes) -{ - size_t remaining_len; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - - if (buf == NULL || bytes == NULL || len == 0 || remaining_len < len) { - return ARES_EBADRESP; - } - - *bytes = ares_malloc(null_term ? len + 1 : len); - if (*bytes == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - memcpy(*bytes, ptr, len); - if (null_term) { - (*bytes)[len] = 0; - } - return ares_buf_consume(buf, len); -} - -ares_status_t ares_buf_fetch_str_dup(ares_buf_t *buf, size_t len, char **str) -{ - size_t remaining_len; - size_t i; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - - if (buf == NULL || str == NULL || len == 0 || remaining_len < len) { - return ARES_EBADRESP; - } - - /* Validate string is printable */ - for (i = 0; i < len; i++) { - if (!ares_isprint(ptr[i])) { - return ARES_EBADSTR; - } - } - - *str = ares_malloc(len + 1); - if (*str == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - memcpy(*str, ptr, len); - (*str)[len] = 0; - - return ares_buf_consume(buf, len); -} - -ares_status_t ares_buf_fetch_bytes_into_buf(ares_buf_t *buf, ares_buf_t *dest, - size_t len) -{ - size_t remaining_len; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - ares_status_t status; - - if (buf == NULL || dest == NULL || len == 0 || remaining_len < len) { - return ARES_EBADRESP; - } - - status = ares_buf_append(dest, ptr, len); - if (status != ARES_SUCCESS) { - return status; - } - - return ares_buf_consume(buf, len); -} - -static ares_bool_t ares_is_whitespace(unsigned char c, - ares_bool_t include_linefeed) -{ - switch (c) { - case '\r': - case '\t': - case ' ': - case '\v': - case '\f': - return ARES_TRUE; - case '\n': - return include_linefeed; - default: - break; - } - return ARES_FALSE; -} - -size_t ares_buf_consume_whitespace(ares_buf_t *buf, - ares_bool_t include_linefeed) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - size_t i; - - if (ptr == NULL) { - return 0; - } - - for (i = 0; i < remaining_len; i++) { - if (!ares_is_whitespace(ptr[i], include_linefeed)) { - break; - } - } - - if (i > 0) { - ares_buf_consume(buf, i); - } - return i; -} - -size_t ares_buf_consume_nonwhitespace(ares_buf_t *buf) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - size_t i; - - if (ptr == NULL) { - return 0; - } - - for (i = 0; i < remaining_len; i++) { - if (ares_is_whitespace(ptr[i], ARES_TRUE)) { - break; - } - } - - if (i > 0) { - ares_buf_consume(buf, i); - } - return i; -} - -size_t ares_buf_consume_line(ares_buf_t *buf, ares_bool_t include_linefeed) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - size_t i; - - if (ptr == NULL) { - return 0; - } - - for (i = 0; i < remaining_len; i++) { - if (ptr[i] == '\n') { - goto done; - } - } - -done: - if (include_linefeed && i < remaining_len && ptr[i] == '\n') { - i++; - } - - if (i > 0) { - ares_buf_consume(buf, i); - } - return i; -} - -size_t ares_buf_consume_until_charset(ares_buf_t *buf, - const unsigned char *charset, size_t len, - ares_bool_t require_charset) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - size_t pos; - ares_bool_t found = ARES_FALSE; - - if (ptr == NULL || charset == NULL || len == 0) { - return 0; - } - - /* Optimize for single character searches */ - if (len == 1) { - const unsigned char *p = memchr(ptr, charset[0], remaining_len); - if (p != NULL) { - found = ARES_TRUE; - pos = (size_t)(p - ptr); - } else { - pos = remaining_len; - } - goto done; - } - - for (pos = 0; pos < remaining_len; pos++) { - size_t j; - for (j = 0; j < len; j++) { - if (ptr[pos] == charset[j]) { - found = ARES_TRUE; - goto done; - } - } - } - -done: - if (require_charset && !found) { - return SIZE_MAX; - } - - if (pos > 0) { - ares_buf_consume(buf, pos); - } - return pos; -} - -size_t ares_buf_consume_until_seq(ares_buf_t *buf, const unsigned char *seq, - size_t len, ares_bool_t require_seq) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - const unsigned char *p; - size_t consume_len = 0; - - if (ptr == NULL || seq == NULL || len == 0) { - return 0; - } - - p = ares_memmem(ptr, remaining_len, seq, len); - if (require_seq && p == NULL) { - return SIZE_MAX; - } - - if (p != NULL) { - consume_len = (size_t)(p - ptr); - } else { - consume_len = remaining_len; - } - - if (consume_len > 0) { - ares_buf_consume(buf, consume_len); - } - - return consume_len; -} - -size_t ares_buf_consume_charset(ares_buf_t *buf, const unsigned char *charset, - size_t len) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - size_t i; - - if (ptr == NULL || charset == NULL || len == 0) { - return 0; - } - - for (i = 0; i < remaining_len; i++) { - size_t j; - for (j = 0; j < len; j++) { - if (ptr[i] == charset[j]) { - break; - } - } - /* Not found */ - if (j == len) { - break; - } - } - - if (i > 0) { - ares_buf_consume(buf, i); - } - return i; -} - -static void ares_buf_destroy_cb(void *arg) -{ - ares_buf_t **buf = arg; - ares_buf_destroy(*buf); -} - -static ares_bool_t ares_buf_split_isduplicate(ares_array_t *arr, - const unsigned char *val, - size_t len, - ares_buf_split_t flags) -{ - size_t i; - size_t num = ares_array_len(arr); - - for (i = 0; i < num; i++) { - ares_buf_t **bufptr = ares_array_at(arr, i); - const ares_buf_t *buf = *bufptr; - size_t plen = 0; - const unsigned char *ptr = ares_buf_peek(buf, &plen); - - /* Can't be duplicate if lengths mismatch */ - if (plen != len) { - continue; - } - - if (flags & ARES_BUF_SPLIT_CASE_INSENSITIVE) { - if (ares_memeq_ci(ptr, val, len)) { - return ARES_TRUE; - } - } else { - if (ares_memeq(ptr, val, len)) { - return ARES_TRUE; - } - } - } - - return ARES_FALSE; -} - -ares_status_t ares_buf_split(ares_buf_t *buf, const unsigned char *delims, - size_t delims_len, ares_buf_split_t flags, - size_t max_sections, ares_array_t **arr) -{ - ares_status_t status = ARES_SUCCESS; - ares_bool_t first = ARES_TRUE; - - if (buf == NULL || delims == NULL || delims_len == 0 || arr == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *arr = ares_array_create(sizeof(ares_buf_t *), ares_buf_destroy_cb); - if (*arr == NULL) { - status = ARES_ENOMEM; - goto done; - } - - while (ares_buf_len(buf)) { - size_t len = 0; - const unsigned char *ptr; - - if (first) { - /* No delimiter yet, just tag the start */ - ares_buf_tag(buf); - } else { - if (flags & ARES_BUF_SPLIT_KEEP_DELIMS) { - /* tag then eat delimiter so its first byte in buffer */ - ares_buf_tag(buf); - ares_buf_consume(buf, 1); - } else { - /* throw away delimiter */ - ares_buf_consume(buf, 1); - ares_buf_tag(buf); - } - } - - if (max_sections && ares_array_len(*arr) >= max_sections - 1) { - ares_buf_consume(buf, ares_buf_len(buf)); - } else { - ares_buf_consume_until_charset(buf, delims, delims_len, ARES_FALSE); - } - - ptr = ares_buf_tag_fetch(buf, &len); - - /* Shouldn't be possible */ - if (ptr == NULL) { - status = ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; - } - - if (flags & ARES_BUF_SPLIT_LTRIM) { - size_t i; - for (i = 0; i < len; i++) { - if (!ares_is_whitespace(ptr[i], ARES_TRUE)) { - break; - } - } - ptr += i; - len -= i; - } - - if (flags & ARES_BUF_SPLIT_RTRIM) { - while (len > 0 && ares_is_whitespace(ptr[len - 1], ARES_TRUE)) { - len--; - } - } - - if (len != 0 || flags & ARES_BUF_SPLIT_ALLOW_BLANK) { - ares_buf_t *data; - - if (!(flags & ARES_BUF_SPLIT_NO_DUPLICATES) || - !ares_buf_split_isduplicate(*arr, ptr, len, flags)) { - /* Since we don't allow const buffers of 0 length, and user wants - * 0-length buffers, swap what we do here */ - if (len) { - data = ares_buf_create_const(ptr, len); - } else { - data = ares_buf_create(); - } - - if (data == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_array_insertdata_last(*arr, &data); - if (status != ARES_SUCCESS) { - ares_buf_destroy(data); - goto done; - } - } - } - - first = ARES_FALSE; - } - -done: - if (status != ARES_SUCCESS) { - ares_array_destroy(*arr); - *arr = NULL; - } - - return status; -} - -static void ares_free_split_array(void *arg) -{ - void **ptr = arg; - ares_free(*ptr); -} - -ares_status_t ares_buf_split_str_array(ares_buf_t *buf, - const unsigned char *delims, - size_t delims_len, - ares_buf_split_t flags, - size_t max_sections, ares_array_t **arr) -{ - ares_status_t status; - ares_array_t *split = NULL; - size_t i; - size_t len; - - if (arr == NULL) { - return ARES_EFORMERR; - } - - *arr = NULL; - - status = ares_buf_split(buf, delims, delims_len, flags, max_sections, &split); - if (status != ARES_SUCCESS) { - goto done; - } - - *arr = ares_array_create(sizeof(char *), ares_free_split_array); - if (*arr == NULL) { - status = ARES_ENOMEM; - goto done; - } - - len = ares_array_len(split); - for (i = 0; i < len; i++) { - ares_buf_t **bufptr = ares_array_at(split, i); - ares_buf_t *lbuf = *bufptr; - char *str = NULL; - - status = ares_buf_fetch_str_dup(lbuf, ares_buf_len(lbuf), &str); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_array_insertdata_last(*arr, &str); - if (status != ARES_SUCCESS) { - ares_free(str); - goto done; - } - } - -done: - ares_array_destroy(split); - if (status != ARES_SUCCESS) { - ares_array_destroy(*arr); - *arr = NULL; - } - return status; -} - -ares_status_t ares_buf_split_str(ares_buf_t *buf, const unsigned char *delims, - size_t delims_len, ares_buf_split_t flags, - size_t max_sections, char ***strs, - size_t *nstrs) -{ - ares_status_t status; - ares_array_t *arr = NULL; - - if (strs == NULL || nstrs == NULL) { - return ARES_EFORMERR; - } - - *strs = NULL; - *nstrs = 0; - - status = ares_buf_split_str_array(buf, delims, delims_len, flags, - max_sections, &arr); - - if (status != ARES_SUCCESS) { - goto done; - } - -done: - if (status == ARES_SUCCESS) { - *strs = ares_array_finish(arr, nstrs); - } else { - ares_array_destroy(arr); - } - return status; -} - -ares_bool_t ares_buf_begins_with(const ares_buf_t *buf, - const unsigned char *data, size_t data_len) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - - if (ptr == NULL || data == NULL || data_len == 0) { - return ARES_FALSE; - } - - if (data_len > remaining_len) { - return ARES_FALSE; - } - - if (memcmp(ptr, data, data_len) != 0) { - return ARES_FALSE; - } - - return ARES_TRUE; -} - -size_t ares_buf_len(const ares_buf_t *buf) -{ - if (buf == NULL) { - return 0; - } - - return buf->data_len - buf->offset; -} - -const unsigned char *ares_buf_peek(const ares_buf_t *buf, size_t *len) -{ - return ares_buf_fetch(buf, len); -} - -ares_status_t ares_buf_replace(ares_buf_t *buf, const unsigned char *srch, - size_t srch_size, const unsigned char *rplc, - size_t rplc_size) -{ - size_t processed_len = 0; - ares_status_t status; - - if (buf->alloc_buf == NULL || srch == NULL || srch_size == 0 || - (rplc == NULL && rplc_size != 0)) { - return ARES_EFORMERR; - } - - while (1) { - unsigned char *ptr = buf->alloc_buf + buf->offset + processed_len; - size_t remaining_len = buf->data_len - buf->offset - processed_len; - size_t found_offset = 0; - size_t move_data_len; - - /* Find pattern */ - ptr = ares_memmem(ptr, remaining_len, srch, srch_size); - if (ptr == NULL) { - break; - } - - /* Store the offset this was found because our actual pointer might be - * switched out from under us by the call to ensure_space() if the - * replacement pattern is larger than the search pattern */ - found_offset = (size_t)(ptr - (size_t)(buf->alloc_buf + buf->offset)); - if (rplc_size > srch_size) { - status = ares_buf_ensure_space(buf, rplc_size - srch_size); - if (status != ARES_SUCCESS) { - return status; - } - } - - /* Impossible, but silence clang */ - if (buf->alloc_buf == NULL) { - return ARES_ENOMEM; - } - - /* Recalculate actual pointer */ - ptr = buf->alloc_buf + buf->offset + found_offset; - - /* Move the data */ - move_data_len = buf->data_len - buf->offset - found_offset - srch_size; - memmove(ptr + rplc_size, - ptr + srch_size, - move_data_len); - - /* Copy in the replacement data */ - if (rplc != NULL && rplc_size > 0) { - memcpy(ptr, rplc, rplc_size); - } - - if (rplc_size > srch_size) { - buf->data_len += rplc_size - srch_size; - } else { - buf->data_len -= srch_size - rplc_size; - } - - processed_len = found_offset + rplc_size; - } - - return ARES_SUCCESS; -} - -ares_status_t ares_buf_peek_byte(const ares_buf_t *buf, unsigned char *b) -{ - size_t remaining_len = 0; - const unsigned char *ptr = ares_buf_fetch(buf, &remaining_len); - - if (buf == NULL || b == NULL) { - return ARES_EFORMERR; - } - - if (remaining_len == 0) { - return ARES_EBADRESP; - } - *b = ptr[0]; - return ARES_SUCCESS; -} - -size_t ares_buf_get_position(const ares_buf_t *buf) -{ - if (buf == NULL) { - return 0; - } - return buf->offset; -} - -ares_status_t ares_buf_set_position(ares_buf_t *buf, size_t idx) -{ - if (buf == NULL) { - return ARES_EFORMERR; - } - - if (idx > buf->data_len) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - buf->offset = idx; - return ARES_SUCCESS; -} - -static ares_status_t - ares_buf_parse_dns_binstr_int(ares_buf_t *buf, size_t remaining_len, - unsigned char **bin, size_t *bin_len, - ares_bool_t validate_printable) -{ - unsigned char len; - ares_status_t status = ARES_EBADRESP; - ares_buf_t *binbuf = NULL; - - if (buf == NULL) { - return ARES_EFORMERR; - } - - if (remaining_len == 0) { - return ARES_EBADRESP; - } - - binbuf = ares_buf_create(); - if (binbuf == NULL) { - return ARES_ENOMEM; - } - - status = ares_buf_fetch_bytes(buf, &len, 1); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - remaining_len--; - - if (len > remaining_len) { - status = ARES_EBADRESP; - goto done; - } - - if (len) { - /* When used by the _str() parser, it really needs to be validated to - * be a valid printable ascii string. Do that here */ - if (validate_printable && ares_buf_len(buf) >= len) { - size_t mylen; - const char *data = (const char *)ares_buf_peek(buf, &mylen); - if (!ares_str_isprint(data, len)) { - status = ARES_EBADSTR; - goto done; - } - } - - if (bin != NULL) { - status = ares_buf_fetch_bytes_into_buf(buf, binbuf, len); - } else { - status = ares_buf_consume(buf, len); - } - } - -done: - if (status != ARES_SUCCESS) { - ares_buf_destroy(binbuf); - } else { - if (bin != NULL) { - size_t mylen = 0; - /* NOTE: we use ares_buf_finish_str() here as we guarantee NULL - * Termination even though we are technically returning binary data. - */ - *bin = (unsigned char *)ares_buf_finish_str(binbuf, &mylen); - *bin_len = mylen; - } - } - - return status; -} - -ares_status_t ares_buf_parse_dns_binstr(ares_buf_t *buf, size_t remaining_len, - unsigned char **bin, size_t *bin_len) -{ - return ares_buf_parse_dns_binstr_int(buf, remaining_len, bin, bin_len, - ARES_FALSE); -} - -ares_status_t ares_buf_parse_dns_str(ares_buf_t *buf, size_t remaining_len, - char **str) -{ - size_t len; - - return ares_buf_parse_dns_binstr_int(buf, remaining_len, - (unsigned char **)str, &len, ARES_TRUE); -} - -ares_status_t ares_buf_append_num_dec(ares_buf_t *buf, size_t num, size_t len) -{ - size_t i; - size_t mod; - - if (len == 0) { - len = ares_count_digits(num); - } - - mod = ares_pow(10, len); - - for (i = len; i > 0; i--) { - size_t digit = (num % mod); - ares_status_t status; - - mod /= 10; - - /* Silence coverity. Shouldn't be possible since we calculate it above */ - if (mod == 0) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - digit /= mod; - status = ares_buf_append_byte(buf, '0' + (unsigned char)(digit & 0xFF)); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - return ARES_SUCCESS; -} - -ares_status_t ares_buf_append_num_hex(ares_buf_t *buf, size_t num, size_t len) -{ - size_t i; - static const unsigned char hexbytes[] = "0123456789ABCDEF"; - - if (len == 0) { - len = ares_count_hexdigits(num); - } - - for (i = len; i > 0; i--) { - ares_status_t status; - status = ares_buf_append_byte(buf, hexbytes[(num >> ((i - 1) * 4)) & 0xF]); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - return ARES_SUCCESS; -} - -ares_status_t ares_buf_append_str(ares_buf_t *buf, const char *str) -{ - return ares_buf_append(buf, (const unsigned char *)str, ares_strlen(str)); -} - -static ares_status_t ares_buf_hexdump_line(ares_buf_t *buf, size_t idx, - const unsigned char *data, - size_t len) -{ - size_t i; - ares_status_t status; - - /* Address */ - status = ares_buf_append_num_hex(buf, idx, 6); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - /* | */ - status = ares_buf_append_str(buf, " | "); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (i = 0; i < 16; i++) { - if (i >= len) { - status = ares_buf_append_str(buf, " "); - } else { - status = ares_buf_append_num_hex(buf, data[i], 2); - } - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_buf_append_byte(buf, ' '); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - /* | */ - status = ares_buf_append_str(buf, " | "); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (i = 0; i < 16; i++) { - if (i >= len) { - break; - } - status = ares_buf_append_byte(buf, ares_isprint(data[i]) ? data[i] : '.'); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return ares_buf_append_byte(buf, '\n'); -} - -ares_status_t ares_buf_hexdump(ares_buf_t *buf, const unsigned char *data, - size_t len) -{ - size_t i; - - /* Each line is 16 bytes */ - for (i = 0; i < len; i += 16) { - ares_status_t status; - status = ares_buf_hexdump_line(buf, i, data + i, len - i); - if (status != ARES_SUCCESS) { - return status; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return ARES_SUCCESS; -} - -ares_status_t ares_buf_load_file(const char *filename, ares_buf_t *buf) -{ - FILE *fp = NULL; - unsigned char *ptr = NULL; - size_t len = 0; - size_t ptr_len = 0; - long ftell_len = 0; - ares_status_t status; - - if (filename == NULL || buf == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - fp = fopen(filename, "rb"); - if (fp == NULL) { - int error = errno; - switch (error) { - case ENOENT: - case ESRCH: - status = ARES_ENOTFOUND; - goto done; - default: - DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, - strerror(error))); - DEBUGF(fprintf(stderr, "Error opening file: %s\n", filename)); - status = ARES_EFILE; - goto done; - } - } - - /* Get length portably, fstat() is POSIX, not C */ - if (fseek(fp, 0, SEEK_END) != 0) { - status = ARES_EFILE; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ftell_len = ftell(fp); - if (ftell_len < 0) { - status = ARES_EFILE; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - len = (size_t)ftell_len; - - if (fseek(fp, 0, SEEK_SET) != 0) { - status = ARES_EFILE; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - if (len == 0) { - status = ARES_SUCCESS; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Read entire data into buffer */ - ptr_len = len; - ptr = ares_buf_append_start(buf, &ptr_len); - if (ptr == NULL) { - status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - ptr_len = fread(ptr, 1, len, fp); - if (ptr_len != len) { - status = ARES_EFILE; /* LCOV_EXCL_LINE: DefensiveCoding */ - goto done; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - ares_buf_append_finish(buf, len); - status = ARES_SUCCESS; - -done: - if (fp != NULL) { - fclose(fp); - } - return status; -} diff --git a/vendor/c-ares/src/lib/str/ares_str.c b/vendor/c-ares/src/lib/str/ares_str.c deleted file mode 100644 index 0eda1ab9f..000000000 --- a/vendor/c-ares/src/lib/str/ares_str.c +++ /dev/null @@ -1,508 +0,0 @@ -/* MIT License - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (c) The c-ares project and its contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include "ares_str.h" - -#ifdef HAVE_STDINT_H -# include -#endif - -size_t ares_strnlen(const char *str, size_t maxlen) { - const char *p = NULL; - if (str == NULL) { - return 0; - } -#ifdef HAVE_STRNLEN - (void)p; - return strnlen(str, maxlen); -#else - if ((p = memchr(str, 0, maxlen)) == NULL) { - return maxlen; - } else { - return (size_t)(p - str); - } -#endif /* HAVE_STRNLEN */ -} - -size_t ares_strlen(const char *str) -{ - if (str == NULL) { - return 0; - } - - return strlen(str); -} - -char *ares_strdup(const char *s1) -{ - size_t len; - char *out; - - if (s1 == NULL) { - return NULL; - } - - len = ares_strlen(s1); - - /* Don't see how this is possible */ - if (len == SIZE_MAX) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - out = ares_malloc(len + 1); - if (out == NULL) { - return NULL; - } - - if (len) { - memcpy(out, s1, len); - } - - out[len] = 0; - return out; -} - -size_t ares_strcpy(char *dest, const char *src, size_t dest_size) -{ - size_t len = 0; - - if (dest == NULL || dest_size == 0) { - return 0; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - len = ares_strlen(src); - - if (len >= dest_size) { - len = dest_size - 1; - } - - if (len) { - memcpy(dest, src, len); - } - - dest[len] = 0; - return len; -} - -ares_bool_t ares_str_isnum(const char *str) -{ - size_t i; - - if (str == NULL || *str == 0) { - return ARES_FALSE; - } - - for (i = 0; str[i] != 0; i++) { - if (!ares_isdigit(str[i])) { - return ARES_FALSE; - } - } - return ARES_TRUE; -} - -ares_bool_t ares_str_isalnum(const char *str) -{ - size_t i; - - if (str == NULL || *str == 0) { - return ARES_FALSE; - } - - for (i = 0; str[i] != 0; i++) { - if (!ares_isdigit(str[i]) && !ares_isalpha(str[i])) { - return ARES_FALSE; - } - } - return ARES_TRUE; -} - -void ares_str_rtrim(char *str) -{ - size_t len; - size_t i; - - if (str == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - len = ares_strlen(str); - for (i = len; i > 0; i--) { - if (!ares_isspace(str[i - 1])) { - break; - } - } - str[i] = 0; -} - -void ares_str_ltrim(char *str) -{ - size_t i; - size_t len; - - if (str == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - for (i = 0; str[i] != 0 && ares_isspace(str[i]); i++) { - /* Do nothing */ - } - - if (i == 0) { - return; - } - - len = ares_strlen(str); - if (i != len) { - memmove(str, str + i, len - i); - } - str[len - i] = 0; -} - -void ares_str_trim(char *str) -{ - ares_str_ltrim(str); - ares_str_rtrim(str); -} - -/* tolower() is locale-specific. Use a lookup table fast conversion that only - * operates on ASCII */ -static const unsigned char ares_tolower_lookup[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, - 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, - 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, - 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, - 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, - 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, - 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, - 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, - 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, - 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF -}; - -unsigned char ares_tolower(unsigned char c) -{ - return ares_tolower_lookup[c]; -} - -void ares_str_lower(char *str) -{ - size_t i; - - if (str == NULL) { - return; - } - - for (i = 0; str[i] != 0; i++) { - str[i] = (char)ares_tolower((unsigned char)str[i]); - } -} - -unsigned char *ares_memmem(const unsigned char *big, size_t big_len, - const unsigned char *little, size_t little_len) -{ - unsigned char *ptr; - - if (big == NULL || little == NULL || big_len == 0 || little_len == 0) { - return NULL; - } - -#ifdef HAVE_MEMMEM - ptr = memmem(big, big_len, little, little_len); - return ptr; -#else - while (1) { - ptr = memchr(big, little[0], big_len); - if (ptr == NULL) { - break; - } - - big_len -= (size_t)(ptr - big); - big = ptr; - if (big_len < little_len) { - break; - } - - if (memcmp(big, little, little_len) == 0) { - return ptr; - } - - big++; - big_len--; - } - - return NULL; -#endif -} - -ares_bool_t ares_memeq(const unsigned char *ptr, const unsigned char *val, - size_t len) -{ - return memcmp(ptr, val, len) == 0 ? ARES_TRUE : ARES_FALSE; -} - -ares_bool_t ares_memeq_ci(const unsigned char *ptr, const unsigned char *val, - size_t len) -{ - size_t i; - for (i = 0; i < len; i++) { - if (ares_tolower_lookup[ptr[i]] != ares_tolower_lookup[val[i]]) { - return ARES_FALSE; - } - } - return ARES_TRUE; -} - -ares_bool_t ares_is_hostname(const char *str) -{ - size_t i; - - if (str == NULL) { - return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - for (i = 0; str[i] != 0; i++) { - if (!ares_is_hostnamech(str[i])) { - return ARES_FALSE; - } - } - return ARES_TRUE; -} - -ares_bool_t ares_str_isprint(const char *str, size_t len) -{ - size_t i; - - if (str == NULL && len != 0) { - return ARES_FALSE; - } - - for (i = 0; i < len; i++) { - if (!ares_isprint(str[i])) { - return ARES_FALSE; - } - } - return ARES_TRUE; -} - -int ares_strcmp(const char *a, const char *b) -{ - if (a == NULL && b == NULL) { - return 0; - } - - if (a != NULL && b == NULL) { - if (*a == 0) { - return 0; - } - return 1; - } - - if (a == NULL && b != NULL) { - if (*b == 0) { - return 0; - } - return -1; - } - - return strcmp(a, b); -} - -int ares_strncmp(const char *a, const char *b, size_t n) -{ - if (n == 0) { - return 0; - } - - if (a == NULL && b == NULL) { - return 0; - } - - if (a != NULL && b == NULL) { - if (*a == 0) { - return 0; - } - return 1; - } - - if (a == NULL && b != NULL) { - if (*b == 0) { - return 0; - } - return -1; - } - - return strncmp(a, b, n); -} - -int ares_strcasecmp(const char *a, const char *b) -{ - if (a == NULL && b == NULL) { - return 0; - } - - if (a != NULL && b == NULL) { - if (*a == 0) { - return 0; - } - return 1; - } - - if (a == NULL && b != NULL) { - if (*b == 0) { - return 0; - } - return -1; - } - -#if defined(HAVE_STRCASECMP) - return strcasecmp(a, b); -#elif defined(HAVE_STRCMPI) - return strcmpi(a, b); -#elif defined(HAVE_STRICMP) - return stricmp(a, b); -#else - { - size_t i; - - for (i = 0; i < (size_t)-1; i++) { - int c1 = ares_tolower(a[i]); - int c2 = ares_tolower(b[i]); - if (c1 != c2) { - return c1 - c2; - } - if (!c1) { - break; - } - } - } - return 0; -#endif -} - -int ares_strncasecmp(const char *a, const char *b, size_t n) -{ - if (n == 0) { - return 0; - } - - if (a == NULL && b == NULL) { - return 0; - } - - if (a != NULL && b == NULL) { - if (*a == 0) { - return 0; - } - return 1; - } - - if (a == NULL && b != NULL) { - if (*b == 0) { - return 0; - } - return -1; - } - -#if defined(HAVE_STRNCASECMP) - return strncasecmp(a, b, n); -#elif defined(HAVE_STRNCMPI) - return strncmpi(a, b, n); -#elif defined(HAVE_STRNICMP) - return strnicmp(a, b, n); -#else - { - size_t i; - - for (i = 0; i < n; i++) { - int c1 = ares_tolower(a[i]); - int c2 = ares_tolower(b[i]); - if (c1 != c2) { - return c1 - c2; - } - if (!c1) { - break; - } - } - } - return 0; -#endif -} - -ares_bool_t ares_strcaseeq(const char *a, const char *b) -{ - return ares_strcasecmp(a, b) == 0 ? ARES_TRUE : ARES_FALSE; -} - -ares_bool_t ares_strcaseeq_max(const char *a, const char *b, size_t n) -{ - return ares_strncasecmp(a, b, n) == 0 ? ARES_TRUE : ARES_FALSE; -} - -ares_bool_t ares_streq(const char *a, const char *b) -{ - return ares_strcmp(a, b) == 0 ? ARES_TRUE : ARES_FALSE; -} - -ares_bool_t ares_streq_max(const char *a, const char *b, size_t n) -{ - return ares_strncmp(a, b, n) == 0 ? ARES_TRUE : ARES_FALSE; -} - -void ares_free_array(void *arrp, size_t nmembers, void (*freefunc)(void *)) -{ - size_t i; - void **arr = arrp; - - if (arr == NULL) { - return; - } - - if (freefunc != NULL) { - if (nmembers == SIZE_MAX) { - for (i = 0; arr[i] != NULL; i++) { - freefunc(arr[i]); - } - } else { - for (i = 0; i < nmembers; i++) { - freefunc(arr[i]); - } - } - } - - ares_free(arr); -} diff --git a/vendor/c-ares/src/lib/str/ares_strsplit.c b/vendor/c-ares/src/lib/str/ares_strsplit.c deleted file mode 100644 index 4431c5044..000000000 --- a/vendor/c-ares/src/lib/str/ares_strsplit.c +++ /dev/null @@ -1,90 +0,0 @@ -/* MIT License - * - * Copyright (c) 2018 John Schember - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -void ares_strsplit_free(char **elms, size_t num_elm) -{ - ares_free_array(elms, num_elm, ares_free); -} - -char **ares_strsplit_duplicate(char **elms, size_t num_elm) -{ - size_t i; - char **out; - - if (elms == NULL || num_elm == 0) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - out = ares_malloc_zero(sizeof(*elms) * num_elm); - if (out == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - for (i = 0; i < num_elm; i++) { - out[i] = ares_strdup(elms[i]); - if (out[i] == NULL) { - ares_strsplit_free(out, num_elm); /* LCOV_EXCL_LINE: OutOfMemory */ - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - } - - return out; -} - -char **ares_strsplit(const char *in, const char *delms, size_t *num_elm) -{ - ares_status_t status; - ares_buf_t *buf = NULL; - char **out = NULL; - - if (in == NULL || delms == NULL || num_elm == NULL) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - *num_elm = 0; - - buf = ares_buf_create_const((const unsigned char *)in, ares_strlen(in)); - if (buf == NULL) { - return NULL; - } - - status = ares_buf_split_str( - buf, (const unsigned char *)delms, ares_strlen(delms), - ARES_BUF_SPLIT_NO_DUPLICATES | ARES_BUF_SPLIT_CASE_INSENSITIVE, 0, &out, - num_elm); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_buf_destroy(buf); - if (status != ARES_SUCCESS) { - out = NULL; - } - - return out; -} diff --git a/vendor/c-ares/src/lib/str/ares_strsplit.h b/vendor/c-ares/src/lib/str/ares_strsplit.h deleted file mode 100644 index 0da090263..000000000 --- a/vendor/c-ares/src/lib/str/ares_strsplit.h +++ /dev/null @@ -1,51 +0,0 @@ -/* MIT License - * - * Copyright (c) 2018 John Schember - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef HEADER_CARES_STRSPLIT_H -#define HEADER_CARES_STRSPLIT_H - -/* Split a string on delms skipping empty or duplicate elements. - * - * param in String to split. - * param delms String of characters to treat as a delimiter. - * Each character in the string is a delimiter so - * there can be multiple delimiters to split on. - * E.g. ", " will split on all comma's and spaces. - * Duplicate (case-insensitive) entries are removed. - * param num_elm Return parameter of the number of elements - * in the result array. - * - * returns an allocated array of allocated string elements. - * - */ -char **ares_strsplit(const char *in, const char *delms, size_t *num_elm); - -/* Frees the result returned from ares_strsplit(). */ -void ares_strsplit_free(char **elms, size_t num_elm); - -/* Duplicate the array */ -char **ares_strsplit_duplicate(char **elms, size_t num_elm); - -#endif /* HEADER_CARES_STRSPLIT_H */ diff --git a/vendor/c-ares/src/lib/thirdparty/apple/dnsinfo.h b/vendor/c-ares/src/lib/thirdparty/apple/dnsinfo.h deleted file mode 100644 index d92a1d803..000000000 --- a/vendor/c-ares/src/lib/thirdparty/apple/dnsinfo.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2004-2006, 2008, 2009, 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __DNSINFO_H__ -#define __DNSINFO_H__ - -/* - * These routines provide access to the systems DNS configuration - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DNSINFO_VERSION 20111104 - -#define DEFAULT_SEARCH_ORDER 200000 /* search order for the "default" resolver domain name */ - -#define DNS_PTR(type, name) \ - union { \ - type name; \ - uint64_t _ ## name ## _p; \ - } - -#define DNS_VAR(type, name) \ - type name - - -#pragma pack(4) -typedef struct { - struct in_addr address; - struct in_addr mask; -} dns_sortaddr_t; -#pragma pack() - - -#pragma pack(4) -typedef struct { - DNS_PTR(char *, domain); /* domain */ - DNS_VAR(int32_t, n_nameserver); /* # nameserver */ - DNS_PTR(struct sockaddr **, nameserver); - DNS_VAR(uint16_t, port); /* port (in host byte order) */ - DNS_VAR(int32_t, n_search); /* # search */ - DNS_PTR(char **, search); - DNS_VAR(int32_t, n_sortaddr); /* # sortaddr */ - DNS_PTR(dns_sortaddr_t **, sortaddr); - DNS_PTR(char *, options); /* options */ - DNS_VAR(uint32_t, timeout); /* timeout */ - DNS_VAR(uint32_t, search_order); /* search_order */ - DNS_VAR(uint32_t, if_index); - DNS_VAR(uint32_t, flags); -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 /* MacOS 10.8 */ - DNS_VAR(uint32_t, reserved[6]); -#else - DNS_VAR(uint32_t, reach_flags); /* SCNetworkReachabilityFlags */ - DNS_VAR(uint32_t, reserved[5]); -#endif -} dns_resolver_t; -#pragma pack() - - -#define DNS_RESOLVER_FLAGS_SCOPED 1 /* configuration is for scoped questions */ - - -#pragma pack(4) -typedef struct { - DNS_VAR(int32_t, n_resolver); /* resolver configurations */ - DNS_PTR(dns_resolver_t **, resolver); - DNS_VAR(int32_t, n_scoped_resolver); /* "scoped" resolver configurations */ - DNS_PTR(dns_resolver_t **, scoped_resolver); - DNS_VAR(uint32_t, reserved[5]); -} dns_config_t; -#pragma pack() - - -__BEGIN_DECLS - -/* - * DNS configuration access APIs - */ -const char * -dns_configuration_notify_key (void) __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0); - -dns_config_t * -dns_configuration_copy (void) __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0); - -void -dns_configuration_free (dns_config_t *config) __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_2_0); - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 -void -_dns_configuration_ack (dns_config_t *config, - const char *bundle_id) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); -#endif - -__END_DECLS - -#endif /* __DNSINFO_H__ */ diff --git a/vendor/c-ares/src/lib/util/ares_iface_ips.c b/vendor/c-ares/src/lib/util/ares_iface_ips.c deleted file mode 100644 index c5f507f87..000000000 --- a/vendor/c-ares/src/lib/util/ares_iface_ips.c +++ /dev/null @@ -1,628 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -#ifdef USE_WINSOCK -# include -# include -# if defined(HAVE_IPHLPAPI_H) -# include -# endif -# if defined(HAVE_NETIOAPI_H) -# include -# endif -#endif - -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -#ifdef HAVE_NET_IF_H -# include -#endif -#ifdef HAVE_IFADDRS_H -# include -#endif -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif - - -static ares_status_t ares_iface_ips_enumerate(ares_iface_ips_t *ips, - const char *name); - -typedef struct { - char *name; - struct ares_addr addr; - unsigned char netmask; - unsigned int ll_scope; - ares_iface_ip_flags_t flags; -} ares_iface_ip_t; - -struct ares_iface_ips { - ares_array_t *ips; /*!< Type is ares_iface_ip_t */ - ares_iface_ip_flags_t enum_flags; -}; - -static void ares_iface_ip_free_cb(void *arg) -{ - ares_iface_ip_t *ip = arg; - if (ip == NULL) { - return; - } - ares_free(ip->name); -} - -static ares_iface_ips_t *ares_iface_ips_alloc(ares_iface_ip_flags_t flags) -{ - ares_iface_ips_t *ips = ares_malloc_zero(sizeof(*ips)); - if (ips == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - ips->enum_flags = flags; - ips->ips = ares_array_create(sizeof(ares_iface_ip_t), ares_iface_ip_free_cb); - if (ips->ips == NULL) { - ares_free(ips); /* LCOV_EXCL_LINE: OutOfMemory */ - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ - } - return ips; -} - -void ares_iface_ips_destroy(ares_iface_ips_t *ips) -{ - if (ips == NULL) { - return; - } - - ares_array_destroy(ips->ips); - ares_free(ips); -} - -ares_status_t ares_iface_ips(ares_iface_ips_t **ips, - ares_iface_ip_flags_t flags, const char *name) -{ - ares_status_t status; - - if (ips == NULL) { - return ARES_EFORMERR; - } - - *ips = ares_iface_ips_alloc(flags); - if (*ips == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares_iface_ips_enumerate(*ips, name); - if (status != ARES_SUCCESS) { - /* LCOV_EXCL_START: UntestablePath */ - ares_iface_ips_destroy(*ips); - *ips = NULL; - return status; - /* LCOV_EXCL_STOP */ - } - - return ARES_SUCCESS; -} - -static ares_status_t - ares_iface_ips_add(ares_iface_ips_t *ips, ares_iface_ip_flags_t flags, - const char *name, const struct ares_addr *addr, - unsigned char netmask, unsigned int ll_scope) -{ - ares_iface_ip_t *ip; - ares_status_t status; - - if (ips == NULL || name == NULL || addr == NULL) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - /* Don't want loopback */ - if (flags & ARES_IFACE_IP_LOOPBACK && - !(ips->enum_flags & ARES_IFACE_IP_LOOPBACK)) { - return ARES_SUCCESS; - } - - /* Don't want offline */ - if (flags & ARES_IFACE_IP_OFFLINE && - !(ips->enum_flags & ARES_IFACE_IP_OFFLINE)) { - return ARES_SUCCESS; - } - - /* Check for link-local */ - if (ares_addr_is_linklocal(addr)) { - flags |= ARES_IFACE_IP_LINKLOCAL; - } - if (flags & ARES_IFACE_IP_LINKLOCAL && - !(ips->enum_flags & ARES_IFACE_IP_LINKLOCAL)) { - return ARES_SUCCESS; - } - - /* Set address flag based on address provided */ - if (addr->family == AF_INET) { - flags |= ARES_IFACE_IP_V4; - } - - if (addr->family == AF_INET6) { - flags |= ARES_IFACE_IP_V6; - } - - /* If they specified either v4 or v6 validate flags otherwise assume they - * want to enumerate both */ - if (ips->enum_flags & (ARES_IFACE_IP_V4 | ARES_IFACE_IP_V6)) { - if (flags & ARES_IFACE_IP_V4 && !(ips->enum_flags & ARES_IFACE_IP_V4)) { - return ARES_SUCCESS; - } - if (flags & ARES_IFACE_IP_V6 && !(ips->enum_flags & ARES_IFACE_IP_V6)) { - return ARES_SUCCESS; - } - } - - status = ares_array_insert_last((void **)&ip, ips->ips); - if (status != ARES_SUCCESS) { - return status; - } - - ip->flags = flags; - ip->netmask = netmask; - if (flags & ARES_IFACE_IP_LINKLOCAL) { - ip->ll_scope = ll_scope; - } - memcpy(&ip->addr, addr, sizeof(*addr)); - ip->name = ares_strdup(name); - if (ip->name == NULL) { - ares_array_remove_last(ips->ips); - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - return ARES_SUCCESS; -} - -size_t ares_iface_ips_cnt(const ares_iface_ips_t *ips) -{ - if (ips == NULL) { - return 0; - } - return ares_array_len(ips->ips); -} - -const char *ares_iface_ips_get_name(const ares_iface_ips_t *ips, size_t idx) -{ - const ares_iface_ip_t *ip; - - if (ips == NULL) { - return NULL; - } - - ip = ares_array_at_const(ips->ips, idx); - if (ip == NULL) { - return NULL; - } - - return ip->name; -} - -const struct ares_addr *ares_iface_ips_get_addr(const ares_iface_ips_t *ips, - size_t idx) -{ - const ares_iface_ip_t *ip; - - if (ips == NULL) { - return NULL; - } - - ip = ares_array_at_const(ips->ips, idx); - if (ip == NULL) { - return NULL; - } - - return &ip->addr; -} - -ares_iface_ip_flags_t ares_iface_ips_get_flags(const ares_iface_ips_t *ips, - size_t idx) -{ - const ares_iface_ip_t *ip; - - if (ips == NULL) { - return 0; - } - - ip = ares_array_at_const(ips->ips, idx); - if (ip == NULL) { - return 0; - } - - return ip->flags; -} - -unsigned char ares_iface_ips_get_netmask(const ares_iface_ips_t *ips, - size_t idx) -{ - const ares_iface_ip_t *ip; - - if (ips == NULL) { - return 0; - } - - ip = ares_array_at_const(ips->ips, idx); - if (ip == NULL) { - return 0; - } - - return ip->netmask; -} - -unsigned int ares_iface_ips_get_ll_scope(const ares_iface_ips_t *ips, - size_t idx) -{ - const ares_iface_ip_t *ip; - - if (ips == NULL) { - return 0; - } - - ip = ares_array_at_const(ips->ips, idx); - if (ip == NULL) { - return 0; - } - - return ip->ll_scope; -} - - -#ifdef USE_WINSOCK - -# if 0 -static char *wcharp_to_charp(const wchar_t *in) -{ - char *out; - int len; - - len = WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, NULL, NULL); - if (len == -1) { - return NULL; - } - - out = ares_malloc_zero((size_t)len + 1); - - if (WideCharToMultiByte(CP_UTF8, 0, in, -1, out, len, NULL, NULL) == -1) { - ares_free(out); - return NULL; - } - - return out; -} -# endif - -static ares_bool_t name_match(const char *name, const char *adapter_name, - unsigned int ll_scope) -{ - if (name == NULL || *name == 0) { - return ARES_TRUE; - } - - if (ares_strcaseeq(name, adapter_name)) { - return ARES_TRUE; - } - - if (ares_str_isnum(name) && (unsigned int)atoi(name) == ll_scope) { - return ARES_TRUE; - } - - return ARES_FALSE; -} - -static ares_status_t ares_iface_ips_enumerate(ares_iface_ips_t *ips, - const char *name) -{ - ULONG myflags = GAA_FLAG_INCLUDE_PREFIX /*|GAA_FLAG_INCLUDE_ALL_INTERFACES */; - ULONG outBufLen = 0; - DWORD retval; - IP_ADAPTER_ADDRESSES *addresses = NULL; - IP_ADAPTER_ADDRESSES *address = NULL; - ares_status_t status = ARES_SUCCESS; - - /* Get necessary buffer size */ - GetAdaptersAddresses(AF_UNSPEC, myflags, NULL, NULL, &outBufLen); - if (outBufLen == 0) { - status = ARES_EFILE; - goto done; - } - - addresses = ares_malloc_zero(outBufLen); - if (addresses == NULL) { - status = ARES_ENOMEM; - goto done; - } - - retval = - GetAdaptersAddresses(AF_UNSPEC, myflags, NULL, addresses, &outBufLen); - if (retval != ERROR_SUCCESS) { - status = ARES_EFILE; - goto done; - } - - for (address = addresses; address != NULL; address = address->Next) { - IP_ADAPTER_UNICAST_ADDRESS *ipaddr = NULL; - ares_iface_ip_flags_t addrflag = 0; - char ifname[64] = ""; - -# if defined(HAVE_CONVERTINTERFACEINDEXTOLUID) && \ - defined(HAVE_CONVERTINTERFACELUIDTONAMEA) - /* Retrieve name from interface index. - * address->AdapterName appears to be a GUID/UUID of some sort, not a name. - * address->FriendlyName is user-changeable. - * That said, this doesn't appear to help us out on systems that don't - * have if_nametoindex() or if_indextoname() as they don't have these - * functions either! */ - NET_LUID luid; - ConvertInterfaceIndexToLuid(address->IfIndex, &luid); - ConvertInterfaceLuidToNameA(&luid, ifname, sizeof(ifname)); -# else - ares_strcpy(ifname, address->AdapterName, sizeof(ifname)); -# endif - - if (address->OperStatus != IfOperStatusUp) { - addrflag |= ARES_IFACE_IP_OFFLINE; - } - - if (address->IfType == IF_TYPE_SOFTWARE_LOOPBACK) { - addrflag |= ARES_IFACE_IP_LOOPBACK; - } - - for (ipaddr = address->FirstUnicastAddress; ipaddr != NULL; - ipaddr = ipaddr->Next) { - struct ares_addr addr; - - if (ipaddr->Address.lpSockaddr->sa_family == AF_INET) { - const struct sockaddr_in *sockaddr_in = - (const struct sockaddr_in *)((void *)ipaddr->Address.lpSockaddr); - addr.family = AF_INET; - memcpy(&addr.addr.addr4, &sockaddr_in->sin_addr, - sizeof(addr.addr.addr4)); - } else if (ipaddr->Address.lpSockaddr->sa_family == AF_INET6) { - const struct sockaddr_in6 *sockaddr_in6 = - (const struct sockaddr_in6 *)((void *)ipaddr->Address.lpSockaddr); - addr.family = AF_INET6; - memcpy(&addr.addr.addr6, &sockaddr_in6->sin6_addr, - sizeof(addr.addr.addr6)); - } else { - /* Unknown */ - continue; - } - - /* Sometimes windows may use numerics to indicate a DNS server's adapter, - * which corresponds to the index rather than the name. Check and - * validate both. */ - if (!name_match(name, ifname, address->Ipv6IfIndex)) { - continue; - } - - status = ares_iface_ips_add(ips, addrflag, ifname, &addr, -#if _WIN32_WINNT >= 0x0600 - ipaddr->OnLinkPrefixLength /* netmask */, -#else - ipaddr->Address.lpSockaddr->sa_family - == AF_INET?32:128, -#endif - address->Ipv6IfIndex /* ll_scope */ - ); - - if (status != ARES_SUCCESS) { - goto done; - } - } - } - -done: - ares_free(addresses); - return status; -} - -#elif defined(HAVE_GETIFADDRS) - -static unsigned char count_addr_bits(const unsigned char *addr, size_t addr_len) -{ - size_t i; - unsigned char count = 0; - - for (i = 0; i < addr_len; i++) { - count += ares_count_bits_u8(addr[i]); - } - return count; -} - -static ares_status_t ares_iface_ips_enumerate(ares_iface_ips_t *ips, - const char *name) -{ - struct ifaddrs *ifap = NULL; - struct ifaddrs *ifa = NULL; - ares_status_t status = ARES_SUCCESS; - - if (getifaddrs(&ifap) != 0) { - status = ARES_EFILE; - goto done; - } - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - ares_iface_ip_flags_t addrflag = 0; - struct ares_addr addr; - unsigned char netmask = 0; - unsigned int ll_scope = 0; - - if (ifa->ifa_addr == NULL) { - continue; - } - - if (!(ifa->ifa_flags & IFF_UP)) { - addrflag |= ARES_IFACE_IP_OFFLINE; - } - - if (ifa->ifa_flags & IFF_LOOPBACK) { - addrflag |= ARES_IFACE_IP_LOOPBACK; - } - - if (ifa->ifa_addr->sa_family == AF_INET) { - const struct sockaddr_in *sockaddr_in = - (const struct sockaddr_in *)((void *)ifa->ifa_addr); - addr.family = AF_INET; - memcpy(&addr.addr.addr4, &sockaddr_in->sin_addr, sizeof(addr.addr.addr4)); - /* netmask */ - sockaddr_in = (struct sockaddr_in *)((void *)ifa->ifa_netmask); - netmask = count_addr_bits((const void *)&sockaddr_in->sin_addr, 4); - } else if (ifa->ifa_addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *sockaddr_in6 = - (const struct sockaddr_in6 *)((void *)ifa->ifa_addr); - addr.family = AF_INET6; - memcpy(&addr.addr.addr6, &sockaddr_in6->sin6_addr, - sizeof(addr.addr.addr6)); - /* netmask */ - sockaddr_in6 = (struct sockaddr_in6 *)((void *)ifa->ifa_netmask); - netmask = count_addr_bits((const void *)&sockaddr_in6->sin6_addr, 16); -# ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID - ll_scope = sockaddr_in6->sin6_scope_id; -# endif - } else { - /* unknown */ - continue; - } - - /* Name mismatch */ - if (name != NULL && !ares_strcaseeq(ifa->ifa_name, name)) { - continue; - } - - status = ares_iface_ips_add(ips, addrflag, ifa->ifa_name, &addr, netmask, - ll_scope); - if (status != ARES_SUCCESS) { - goto done; - } - } - -done: - freeifaddrs(ifap); - return status; -} - -#else - -static ares_status_t ares_iface_ips_enumerate(ares_iface_ips_t *ips, - const char *name) -{ - (void)ips; - (void)name; - return ARES_ENOTIMP; -} - -#endif - - -unsigned int ares_os_if_nametoindex(const char *name) -{ -#ifdef HAVE_IF_NAMETOINDEX - if (name == NULL) { - return 0; - } - return if_nametoindex(name); -#else - ares_status_t status; - ares_iface_ips_t *ips = NULL; - size_t i; - unsigned int index = 0; - - if (name == NULL) { - return 0; - } - - status = - ares_iface_ips(&ips, ARES_IFACE_IP_V6 | ARES_IFACE_IP_LINKLOCAL, name); - if (status != ARES_SUCCESS) { - goto done; - } - - for (i = 0; i < ares_iface_ips_cnt(ips); i++) { - if (ares_iface_ips_get_flags(ips, i) & ARES_IFACE_IP_LINKLOCAL) { - index = ares_iface_ips_get_ll_scope(ips, i); - goto done; - } - } - -done: - ares_iface_ips_destroy(ips); - return index; -#endif -} - -const char *ares_os_if_indextoname(unsigned int index, char *name, size_t name_len) -{ -#ifdef HAVE_IF_INDEXTONAME - if (name_len < IF_NAMESIZE) { - return NULL; - } - return if_indextoname(index, name); -#else - ares_status_t status; - ares_iface_ips_t *ips = NULL; - size_t i; - const char *ptr = NULL; - - if (name == NULL || name_len < IF_NAMESIZE) { - goto done; - } - - if (index == 0) { - goto done; - } - - status = - ares_iface_ips(&ips, ARES_IFACE_IP_V6 | ARES_IFACE_IP_LINKLOCAL, NULL); - if (status != ARES_SUCCESS) { - goto done; - } - - for (i = 0; i < ares_iface_ips_cnt(ips); i++) { - if (ares_iface_ips_get_flags(ips, i) & ARES_IFACE_IP_LINKLOCAL && - ares_iface_ips_get_ll_scope(ips, i) == index) { - ares_strcpy(name, ares_iface_ips_get_name(ips, i), name_len); - ptr = name; - goto done; - } - } - -done: - ares_iface_ips_destroy(ips); - return ptr; -#endif -} diff --git a/vendor/c-ares/src/lib/util/ares_iface_ips.h b/vendor/c-ares/src/lib/util/ares_iface_ips.h deleted file mode 100644 index f22e09046..000000000 --- a/vendor/c-ares/src/lib/util/ares_iface_ips.h +++ /dev/null @@ -1,139 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__IFACE_IPS_H -#define __ARES__IFACE_IPS_H - -/*! Flags for interface ip addresses. */ -typedef enum { - ARES_IFACE_IP_V4 = 1 << 0, /*!< IPv4 address. During enumeration if - * this flag is set ARES_IFACE_IP_V6 - * is not, will only enumerate v4 - * addresses. */ - ARES_IFACE_IP_V6 = 1 << 1, /*!< IPv6 address. During enumeration if - * this flag is set ARES_IFACE_IP_V4 - * is not, will only enumerate v6 - * addresses. */ - ARES_IFACE_IP_LOOPBACK = 1 << 2, /*!< Loopback adapter */ - ARES_IFACE_IP_OFFLINE = 1 << 3, /*!< Adapter offline */ - ARES_IFACE_IP_LINKLOCAL = 1 << 4, /*!< Link-local ip address */ - /*! Default, enumerate all ips for online interfaces, including loopback */ - ARES_IFACE_IP_DEFAULT = (ARES_IFACE_IP_V4 | ARES_IFACE_IP_V6 | - ARES_IFACE_IP_LOOPBACK | ARES_IFACE_IP_LINKLOCAL) -} ares_iface_ip_flags_t; - -struct ares_iface_ips; - -/*! Opaque pointer for holding enumerated interface ip addresses */ -typedef struct ares_iface_ips ares_iface_ips_t; - -/*! Destroy ip address enumeration created by ares_iface_ips(). - * - * \param[in] ips Initialized IP address enumeration structure - */ -void ares_iface_ips_destroy(ares_iface_ips_t *ips); - -/*! Enumerate ip addresses on interfaces - * - * \param[out] ips Returns initialized ip address structure - * \param[in] flags Flags for enumeration - * \param[in] name Interface name to enumerate, or NULL to enumerate all - * \return ARES_ENOMEM on out of memory, ARES_ENOTIMP if not supported on - * the system, ARES_SUCCESS on success - */ -ares_status_t ares_iface_ips(ares_iface_ips_t **ips, - ares_iface_ip_flags_t flags, const char *name); - -/*! Count of ips enumerated - * - * \param[in] ips Initialized IP address enumeration structure - * \return count - */ -size_t ares_iface_ips_cnt(const ares_iface_ips_t *ips); - -/*! Retrieve interface name - * - * \param[in] ips Initialized IP address enumeration structure - * \param[in] idx Index of entry to pull - * \return interface name - */ -const char *ares_iface_ips_get_name(const ares_iface_ips_t *ips, size_t idx); - -/*! Retrieve interface address - * - * \param[in] ips Initialized IP address enumeration structure - * \param[in] idx Index of entry to pull - * \return interface address - */ -const struct ares_addr *ares_iface_ips_get_addr(const ares_iface_ips_t *ips, - size_t idx); - -/*! Retrieve interface address flags - * - * \param[in] ips Initialized IP address enumeration structure - * \param[in] idx Index of entry to pull - * \return interface address flags - */ -ares_iface_ip_flags_t ares_iface_ips_get_flags(const ares_iface_ips_t *ips, - size_t idx); - -/*! Retrieve interface address netmask - * - * \param[in] ips Initialized IP address enumeration structure - * \param[in] idx Index of entry to pull - * \return interface address netmask - */ -unsigned char ares_iface_ips_get_netmask(const ares_iface_ips_t *ips, - size_t idx); - -/*! Retrieve interface ipv6 link local scope - * - * \param[in] ips Initialized IP address enumeration structure - * \param[in] idx Index of entry to pull - * \return interface ipv6 link local scope - */ -unsigned int ares_iface_ips_get_ll_scope(const ares_iface_ips_t *ips, - size_t idx); - - -/*! Retrieve the interface index (aka link local scope) from the interface - * name. - * - * \param[in] name Interface name - * \return 0 on failure, index otherwise - */ -unsigned int ares_os_if_nametoindex(const char *name); - -/*! Retrieves the interface name from the index (aka link local scope) - * - * \param[in] index Interface index (> 0) - * \param[in] name Buffer to hold name - * \param[in] name_len Length of provided buffer, must be at least IF_NAMESIZE - * \return NULL on failure, or pointer to name on success - */ -const char *ares_os_if_indextoname(unsigned int index, char *name, - size_t name_len); - -#endif diff --git a/vendor/c-ares/src/lib/util/ares_math.c b/vendor/c-ares/src/lib/util/ares_math.c deleted file mode 100644 index 1106bf6bf..000000000 --- a/vendor/c-ares/src/lib/util/ares_math.c +++ /dev/null @@ -1,158 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -/* Uses public domain code snippets from - * http://graphics.stanford.edu/~seander/bithacks.html */ - -static unsigned int ares_round_up_pow2_u32(unsigned int n) -{ - /* NOTE: if already a power of 2, will return itself, not the next */ - n--; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - n++; - return n; -} - -static ares_int64_t ares_round_up_pow2_u64(ares_int64_t n) -{ - /* NOTE: if already a power of 2, will return itself, not the next */ - n--; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - n |= n >> 32; - n++; - return n; -} - -ares_bool_t ares_is_64bit(void) -{ -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4127) -#endif - - return (sizeof(size_t) == 4) ? ARES_FALSE : ARES_TRUE; - -#ifdef _MSC_VER -# pragma warning(pop) -#endif -} - -size_t ares_round_up_pow2(size_t n) -{ - if (ares_is_64bit()) { - return (size_t)ares_round_up_pow2_u64((ares_int64_t)n); - } - - return (size_t)ares_round_up_pow2_u32((unsigned int)n); -} - -size_t ares_log2(size_t n) -{ - static const unsigned char tab32[32] = { 0, 1, 28, 2, 29, 14, 24, 3, - 30, 22, 20, 15, 25, 17, 4, 8, - 31, 27, 13, 23, 21, 19, 16, 7, - 26, 12, 18, 6, 11, 5, 10, 9 }; - static const unsigned char tab64[64] = { - 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, - 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, - 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, - 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5 - }; - - if (!ares_is_64bit()) { - return tab32[(n * 0x077CB531) >> 27]; - } - - return tab64[(n * 0x07EDD5E59A4E28C2) >> 58]; -} - -/* x^y */ -size_t ares_pow(size_t x, size_t y) -{ - size_t res = 1; - - while (y > 0) { - /* If y is odd, multiply x with result */ - if (y & 1) { - res = res * x; - } - - /* y must be even now */ - y = y >> 1; /* y /= 2; */ - x = x * x; /* x^2 */ - } - - return res; -} - -size_t ares_count_digits(size_t n) -{ - size_t digits; - - for (digits = 0; n > 0; digits++) { - n /= 10; - } - if (digits == 0) { - digits = 1; - } - - return digits; -} - -size_t ares_count_hexdigits(size_t n) -{ - size_t digits; - - for (digits = 0; n > 0; digits++) { - n /= 16; - } - if (digits == 0) { - digits = 1; - } - - return digits; -} - -unsigned char ares_count_bits_u8(unsigned char x) -{ - /* Implementation obtained from: - * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable */ -#define B2(n) n, n + 1, n + 1, n + 2 -#define B4(n) B2(n), B2(n + 1), B2(n + 1), B2(n + 2) -#define B6(n) B4(n), B4(n + 1), B4(n + 1), B4(n + 2) - static const unsigned char lookup[256] = { B6(0), B6(1), B6(1), B6(2) }; - return lookup[x]; -} diff --git a/vendor/c-ares/src/lib/util/ares_math.h b/vendor/c-ares/src/lib/util/ares_math.h deleted file mode 100644 index 52fa1facf..000000000 --- a/vendor/c-ares/src/lib/util/ares_math.h +++ /dev/null @@ -1,45 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_MATH_H -#define __ARES_MATH_H - -#ifdef _MSC_VER -typedef __int64 ares_int64_t; -typedef unsigned __int64 ares_uint64_t; -#else -typedef long long ares_int64_t; -typedef unsigned long long ares_uint64_t; -#endif - -ares_bool_t ares_is_64bit(void); -size_t ares_round_up_pow2(size_t n); -size_t ares_log2(size_t n); -size_t ares_pow(size_t x, size_t y); -size_t ares_count_digits(size_t n); -size_t ares_count_hexdigits(size_t n); -unsigned char ares_count_bits_u8(unsigned char x); - -#endif diff --git a/vendor/c-ares/src/lib/util/ares_rand.c b/vendor/c-ares/src/lib/util/ares_rand.c deleted file mode 100644 index 408999951..000000000 --- a/vendor/c-ares/src/lib/util/ares_rand.c +++ /dev/null @@ -1,389 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" -#include - -/* Older MacOS versions require including AvailabilityMacros.h before - * sys/random.h */ -#ifdef HAVE_AVAILABILITYMACROS_H -# include -#endif - -#ifdef HAVE_SYS_RANDOM_H -# include -#endif - - -typedef enum { - ARES_RAND_OS = 1 << 0, /* OS-provided such as RtlGenRandom or arc4random */ - ARES_RAND_FILE = 1 << 1, /* OS file-backed random number generator */ - ARES_RAND_RC4 = 1 << 2 /* Internal RC4 based PRNG */ -} ares_rand_backend; - -#define ARES_RC4_KEY_LEN 32 /* 256 bits */ - -typedef struct ares_rand_rc4 { - unsigned char S[256]; - size_t i; - size_t j; -} ares_rand_rc4; - -static unsigned int ares_u32_from_ptr(void *addr) -{ - /* LCOV_EXCL_START: FallbackCode */ - if (ares_is_64bit()) { - return (unsigned int)((((ares_uint64_t)addr >> 32) & 0xFFFFFFFF) | - ((ares_uint64_t)addr & 0xFFFFFFFF)); - } - return (unsigned int)((size_t)addr & 0xFFFFFFFF); - /* LCOV_EXCL_STOP */ -} - -/* initialize an rc4 key as the last possible fallback. */ -static void ares_rc4_generate_key(ares_rand_rc4 *rc4_state, unsigned char *key, - size_t key_len) -{ - /* LCOV_EXCL_START: FallbackCode */ - size_t i; - size_t len = 0; - unsigned int data; - ares_timeval_t tv; - - if (key_len != ARES_RC4_KEY_LEN) { - return; - } - -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - /* For fuzzing, random should be deterministic */ - srand(0); -#else - /* Randomness is hard to come by. Maybe the system randomizes heap and stack - * addresses. Maybe the current timestamp give us some randomness. Use - * rc4_state (heap), &i (stack), and ares_tvnow() - */ - data = ares_u32_from_ptr(rc4_state); - memcpy(key + len, &data, sizeof(data)); - len += sizeof(data); - - data = ares_u32_from_ptr(&i); - memcpy(key + len, &data, sizeof(data)); - len += sizeof(data); - - ares_tvnow(&tv); - data = (unsigned int)((tv.sec | tv.usec) & 0xFFFFFFFF); - memcpy(key + len, &data, sizeof(data)); - len += sizeof(data); - - srand(ares_u32_from_ptr(rc4_state) | ares_u32_from_ptr(&i) | - (unsigned int)((tv.sec | tv.usec) & 0xFFFFFFFF)); -#endif - - for (i = len; i < key_len; i++) { - key[i] = (unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */ - } - /* LCOV_EXCL_STOP */ -} - -#define ARES_SWAP_BYTE(a, b) \ - do { \ - unsigned char swapByte = *(a); \ - *(a) = *(b); \ - *(b) = swapByte; \ - } while (0) - -static void ares_rc4_init(ares_rand_rc4 *rc4_state) -{ - /* LCOV_EXCL_START: FallbackCode */ - unsigned char key[ARES_RC4_KEY_LEN]; - size_t i; - size_t j; - - ares_rc4_generate_key(rc4_state, key, sizeof(key)); - - for (i = 0; i < sizeof(rc4_state->S); i++) { - rc4_state->S[i] = i & 0xFF; - } - - for (i = 0, j = 0; i < 256; i++) { - j = (j + rc4_state->S[i] + key[i % sizeof(key)]) % 256; - ARES_SWAP_BYTE(&rc4_state->S[i], &rc4_state->S[j]); - } - - rc4_state->i = 0; - rc4_state->j = 0; - /* LCOV_EXCL_STOP */ -} - -/* Just outputs the key schedule, no need to XOR with any data since we have - * none */ -static void ares_rc4_prng(ares_rand_rc4 *rc4_state, unsigned char *buf, - size_t len) -{ - /* LCOV_EXCL_START: FallbackCode */ - unsigned char *S = rc4_state->S; - size_t i = rc4_state->i; - size_t j = rc4_state->j; - size_t cnt; - - for (cnt = 0; cnt < len; cnt++) { - i = (i + 1) % 256; - j = (j + S[i]) % 256; - - ARES_SWAP_BYTE(&S[i], &S[j]); - buf[cnt] = S[(S[i] + S[j]) % 256]; - } - - rc4_state->i = i; - rc4_state->j = j; - /* LCOV_EXCL_STOP */ -} - -struct ares_rand_state { - ares_rand_backend type; - ares_rand_backend bad_backends; - - union { - FILE *rand_file; - ares_rand_rc4 rc4; - } state; - - /* Since except for RC4, random data will likely result in a syscall, lets - * pre-pull 256 bytes at a time. Every query will pull 2 bytes off this so - * that means we should only need a syscall every 128 queries. 256bytes - * appears to be a sweet spot that may be able to be served without - * interruption */ - unsigned char cache[256]; - size_t cache_remaining; -}; - -/* Define RtlGenRandom = SystemFunction036. This is in advapi32.dll. There is - * no need to dynamically load this, other software used widely does not. - * http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx - * https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom - */ -#ifdef _WIN32 -BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength); -# ifndef RtlGenRandom -# define RtlGenRandom(a, b) SystemFunction036(a, b) -# endif -#endif - - -static ares_bool_t ares_init_rand_engine(ares_rand_state *state) -{ - state->cache_remaining = 0; - -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - /* For fuzzing, random should be deterministic */ - state->bad_backends |= ARES_RAND_OS | ARES_RAND_FILE; -#endif - -#if defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_GETRANDOM) || defined(_WIN32) - if (!(state->bad_backends & ARES_RAND_OS)) { - state->type = ARES_RAND_OS; - return ARES_TRUE; - } -#endif - -#if defined(CARES_RANDOM_FILE) - /* LCOV_EXCL_START: FallbackCode */ - if (!(state->bad_backends & ARES_RAND_FILE)) { - state->type = ARES_RAND_FILE; - state->state.rand_file = fopen(CARES_RANDOM_FILE, "rb"); - if (state->state.rand_file) { - setvbuf(state->state.rand_file, NULL, _IONBF, 0); - return ARES_TRUE; - } - } - /* LCOV_EXCL_STOP */ - - /* Fall-Thru on failure to RC4 */ -#endif - - /* LCOV_EXCL_START: FallbackCode */ - state->type = ARES_RAND_RC4; - ares_rc4_init(&state->state.rc4); - /* LCOV_EXCL_STOP */ - - /* Currently cannot fail */ - return ARES_TRUE; /* LCOV_EXCL_LINE: UntestablePath */ -} - -ares_rand_state *ares_init_rand_state(void) -{ - ares_rand_state *state = NULL; - - state = ares_malloc_zero(sizeof(*state)); - if (!state) { - return NULL; - } - - if (!ares_init_rand_engine(state)) { - ares_free(state); /* LCOV_EXCL_LINE: UntestablePath */ - return NULL; /* LCOV_EXCL_LINE: UntestablePath */ - } - - return state; -} - -static void ares_clear_rand_state(ares_rand_state *state) -{ - if (!state) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - - switch (state->type) { - case ARES_RAND_OS: - break; - /* LCOV_EXCL_START: FallbackCode */ - case ARES_RAND_FILE: - fclose(state->state.rand_file); - break; - case ARES_RAND_RC4: - break; - /* LCOV_EXCL_STOP */ - } -} - -static void ares_reinit_rand(ares_rand_state *state) -{ - /* LCOV_EXCL_START: UntestablePath */ - ares_clear_rand_state(state); - ares_init_rand_engine(state); - /* LCOV_EXCL_STOP */ -} - -void ares_destroy_rand_state(ares_rand_state *state) -{ - if (!state) { - return; - } - - ares_clear_rand_state(state); - ares_free(state); -} - -static void ares_rand_bytes_fetch(ares_rand_state *state, unsigned char *buf, - size_t len) -{ - while (1) { - size_t bytes_read = 0; - - switch (state->type) { - case ARES_RAND_OS: -#ifdef _WIN32 - RtlGenRandom(buf, (ULONG)len); - return; -#elif defined(HAVE_ARC4RANDOM_BUF) - arc4random_buf(buf, len); - return; -#elif defined(HAVE_GETRANDOM) - while (1) { - size_t n = len - bytes_read; - /* getrandom() on Linux always succeeds and is never - * interrupted by a signal when requesting <= 256 bytes. - */ - ssize_t rv = getrandom(buf + bytes_read, n > 256 ? 256 : n, 0); - if (rv <= 0) { - /* We need to fall back to another backend */ - if (errno == ENOSYS) { - state->bad_backends |= ARES_RAND_OS; - break; - } - continue; /* Just retry. */ - } - - bytes_read += (size_t)rv; - if (bytes_read == len) { - return; - } - } - break; -#else - /* Shouldn't be possible to be here */ - break; -#endif - - /* LCOV_EXCL_START: FallbackCode */ - - case ARES_RAND_FILE: - while (1) { - size_t rv = fread(buf + bytes_read, 1, len - bytes_read, - state->state.rand_file); - if (rv == 0) { - break; /* critical error, will reinit rand state */ - } - - bytes_read += rv; - if (bytes_read == len) { - return; - } - } - break; - - case ARES_RAND_RC4: - ares_rc4_prng(&state->state.rc4, buf, len); - return; - - /* LCOV_EXCL_STOP */ - } - - /* If we didn't return before we got here, that means we had a critical rand - * failure and need to reinitialized */ - ares_reinit_rand(state); /* LCOV_EXCL_LINE: UntestablePath */ - } -} - -void ares_rand_bytes(ares_rand_state *state, unsigned char *buf, size_t len) -{ - /* See if we need to refill the cache to serve the request, but if len is - * excessive, we're not going to update our cache or serve from cache */ - if (len > state->cache_remaining && len < sizeof(state->cache)) { - size_t fetch_size = sizeof(state->cache) - state->cache_remaining; - ares_rand_bytes_fetch(state, state->cache, fetch_size); - state->cache_remaining = sizeof(state->cache); - } - - /* Serve from cache */ - if (len <= state->cache_remaining) { - size_t offset = sizeof(state->cache) - state->cache_remaining; - memcpy(buf, state->cache + offset, len); - state->cache_remaining -= len; - return; - } - - /* Serve direct due to excess size of request */ - ares_rand_bytes_fetch(state, buf, len); -} - -unsigned short ares_generate_new_id(ares_rand_state *state) -{ - unsigned short r = 0; - - ares_rand_bytes(state, (unsigned char *)&r, sizeof(r)); - return r; -} diff --git a/vendor/c-ares/src/lib/util/ares_rand.h b/vendor/c-ares/src/lib/util/ares_rand.h deleted file mode 100644 index 81c61bf46..000000000 --- a/vendor/c-ares/src/lib/util/ares_rand.h +++ /dev/null @@ -1,36 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_RAND_H -#define __ARES_RAND_H - -struct ares_rand_state; -typedef struct ares_rand_state ares_rand_state; - -ares_rand_state *ares_init_rand_state(void); -void ares_destroy_rand_state(ares_rand_state *state); -void ares_rand_bytes(ares_rand_state *state, unsigned char *buf, size_t len); - -#endif diff --git a/vendor/c-ares/src/lib/util/ares_threads.c b/vendor/c-ares/src/lib/util/ares_threads.c deleted file mode 100644 index ab0b51afb..000000000 --- a/vendor/c-ares/src/lib/util/ares_threads.c +++ /dev/null @@ -1,614 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#include "ares_private.h" - -#ifdef CARES_THREADS -# ifdef _WIN32 - -struct ares_thread_mutex { - CRITICAL_SECTION mutex; -}; - -ares_thread_mutex_t *ares_thread_mutex_create(void) -{ - ares_thread_mutex_t *mut = ares_malloc_zero(sizeof(*mut)); - if (mut == NULL) { - return NULL; - } - - InitializeCriticalSection(&mut->mutex); - return mut; -} - -void ares_thread_mutex_destroy(ares_thread_mutex_t *mut) -{ - if (mut == NULL) { - return; - } - DeleteCriticalSection(&mut->mutex); - ares_free(mut); -} - -void ares_thread_mutex_lock(ares_thread_mutex_t *mut) -{ - if (mut == NULL) { - return; - } - EnterCriticalSection(&mut->mutex); -} - -void ares_thread_mutex_unlock(ares_thread_mutex_t *mut) -{ - if (mut == NULL) { - return; - } - LeaveCriticalSection(&mut->mutex); -} - -struct ares_thread_cond { - CONDITION_VARIABLE cond; -}; - -ares_thread_cond_t *ares_thread_cond_create(void) -{ - ares_thread_cond_t *cond = ares_malloc_zero(sizeof(*cond)); - if (cond == NULL) { - return NULL; - } - InitializeConditionVariable(&cond->cond); - return cond; -} - -void ares_thread_cond_destroy(ares_thread_cond_t *cond) -{ - if (cond == NULL) { - return; - } - ares_free(cond); -} - -void ares_thread_cond_signal(ares_thread_cond_t *cond) -{ - if (cond == NULL) { - return; - } - WakeConditionVariable(&cond->cond); -} - -void ares_thread_cond_broadcast(ares_thread_cond_t *cond) -{ - if (cond == NULL) { - return; - } - WakeAllConditionVariable(&cond->cond); -} - -ares_status_t ares_thread_cond_wait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut) -{ - if (cond == NULL || mut == NULL) { - return ARES_EFORMERR; - } - - SleepConditionVariableCS(&cond->cond, &mut->mutex, INFINITE); - return ARES_SUCCESS; -} - -ares_status_t ares_thread_cond_timedwait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut, - unsigned long timeout_ms) -{ - if (cond == NULL || mut == NULL) { - return ARES_EFORMERR; - } - - if (!SleepConditionVariableCS(&cond->cond, &mut->mutex, timeout_ms)) { - return ARES_ETIMEOUT; - } - - return ARES_SUCCESS; -} - -struct ares_thread { - HANDLE thread; - DWORD id; - - void *(*func)(void *arg); - void *arg; - void *rv; -}; - -/* Wrap for pthread compatibility */ -static DWORD WINAPI ares_thread_func(LPVOID lpParameter) -{ - ares_thread_t *thread = lpParameter; - - thread->rv = thread->func(thread->arg); - return 0; -} - -ares_status_t ares_thread_create(ares_thread_t **thread, - ares_thread_func_t func, void *arg) -{ - ares_thread_t *thr = NULL; - - if (func == NULL || thread == NULL) { - return ARES_EFORMERR; - } - - thr = ares_malloc_zero(sizeof(*thr)); - if (thr == NULL) { - return ARES_ENOMEM; - } - - thr->func = func; - thr->arg = arg; - thr->thread = CreateThread(NULL, 0, ares_thread_func, thr, 0, &thr->id); - if (thr->thread == NULL) { - ares_free(thr); - return ARES_ESERVFAIL; - } - - *thread = thr; - return ARES_SUCCESS; -} - -ares_status_t ares_thread_join(ares_thread_t *thread, void **rv) -{ - ares_status_t status = ARES_SUCCESS; - - if (thread == NULL) { - return ARES_EFORMERR; - } - - if (WaitForSingleObject(thread->thread, INFINITE) != WAIT_OBJECT_0) { - status = ARES_ENOTFOUND; - } else { - CloseHandle(thread->thread); - } - - if (status == ARES_SUCCESS && rv != NULL) { - *rv = thread->rv; - } - ares_free(thread); - - return status; -} - -# else /* !WIN32 == PTHREAD */ -# include - -/* for clock_gettime() */ -# ifdef HAVE_TIME_H -# include -# endif - -/* for gettimeofday() */ -# ifdef HAVE_SYS_TIME_H -# include -# endif - -struct ares_thread_mutex { - pthread_mutex_t mutex; -}; - -ares_thread_mutex_t *ares_thread_mutex_create(void) -{ - pthread_mutexattr_t attr; - ares_thread_mutex_t *mut = ares_malloc_zero(sizeof(*mut)); - if (mut == NULL) { - return NULL; - } - - if (pthread_mutexattr_init(&attr) != 0) { - ares_free(mut); /* LCOV_EXCL_LINE: UntestablePath */ - return NULL; /* LCOV_EXCL_LINE: UntestablePath */ - } - - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) { - goto fail; /* LCOV_EXCL_LINE: UntestablePath */ - } - - if (pthread_mutex_init(&mut->mutex, &attr) != 0) { - goto fail; /* LCOV_EXCL_LINE: UntestablePath */ - } - - pthread_mutexattr_destroy(&attr); - return mut; - -/* LCOV_EXCL_START: UntestablePath */ -fail: - pthread_mutexattr_destroy(&attr); - ares_free(mut); - return NULL; - /* LCOV_EXCL_STOP */ -} - -void ares_thread_mutex_destroy(ares_thread_mutex_t *mut) -{ - if (mut == NULL) { - return; - } - pthread_mutex_destroy(&mut->mutex); - ares_free(mut); -} - -void ares_thread_mutex_lock(ares_thread_mutex_t *mut) -{ - if (mut == NULL) { - return; - } - pthread_mutex_lock(&mut->mutex); -} - -void ares_thread_mutex_unlock(ares_thread_mutex_t *mut) -{ - if (mut == NULL) { - return; - } - pthread_mutex_unlock(&mut->mutex); -} - -struct ares_thread_cond { - pthread_cond_t cond; -}; - -ares_thread_cond_t *ares_thread_cond_create(void) -{ - ares_thread_cond_t *cond = ares_malloc_zero(sizeof(*cond)); - if (cond == NULL) { - return NULL; - } - pthread_cond_init(&cond->cond, NULL); - return cond; -} - -void ares_thread_cond_destroy(ares_thread_cond_t *cond) -{ - if (cond == NULL) { - return; - } - pthread_cond_destroy(&cond->cond); - ares_free(cond); -} - -void ares_thread_cond_signal(ares_thread_cond_t *cond) -{ - if (cond == NULL) { - return; - } - pthread_cond_signal(&cond->cond); -} - -void ares_thread_cond_broadcast(ares_thread_cond_t *cond) -{ - if (cond == NULL) { - return; - } - pthread_cond_broadcast(&cond->cond); -} - -ares_status_t ares_thread_cond_wait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut) -{ - if (cond == NULL || mut == NULL) { - return ARES_EFORMERR; - } - - pthread_cond_wait(&cond->cond, &mut->mutex); - return ARES_SUCCESS; -} - -static void ares_timespec_timeout(struct timespec *ts, unsigned long add_ms) -{ -# if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) - clock_gettime(CLOCK_REALTIME, ts); -# elif defined(HAVE_GETTIMEOFDAY) - struct timeval tv; - gettimeofday(&tv, NULL); - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; -# else -# error cannot determine current system time -# endif - - ts->tv_sec += (time_t)(add_ms / 1000); - ts->tv_nsec += (long)((add_ms % 1000) * 1000000); - - /* Normalize if needed */ - if (ts->tv_nsec >= 1000000000) { - ts->tv_sec += ts->tv_nsec / 1000000000; - ts->tv_nsec %= 1000000000; - } -} - -ares_status_t ares_thread_cond_timedwait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut, - unsigned long timeout_ms) -{ - struct timespec ts; - - if (cond == NULL || mut == NULL) { - return ARES_EFORMERR; - } - - ares_timespec_timeout(&ts, timeout_ms); - - if (pthread_cond_timedwait(&cond->cond, &mut->mutex, &ts) != 0) { - return ARES_ETIMEOUT; - } - - return ARES_SUCCESS; -} - -struct ares_thread { - pthread_t thread; -}; - -ares_status_t ares_thread_create(ares_thread_t **thread, - ares_thread_func_t func, void *arg) -{ - ares_thread_t *thr = NULL; - - if (func == NULL || thread == NULL) { - return ARES_EFORMERR; - } - - thr = ares_malloc_zero(sizeof(*thr)); - if (thr == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - if (pthread_create(&thr->thread, NULL, func, arg) != 0) { - ares_free(thr); /* LCOV_EXCL_LINE: UntestablePath */ - return ARES_ESERVFAIL; /* LCOV_EXCL_LINE: UntestablePath */ - } - - *thread = thr; - return ARES_SUCCESS; -} - -ares_status_t ares_thread_join(ares_thread_t *thread, void **rv) -{ - void *ret = NULL; - ares_status_t status = ARES_SUCCESS; - - if (thread == NULL) { - return ARES_EFORMERR; - } - - if (pthread_join(thread->thread, &ret) != 0) { - status = ARES_ENOTFOUND; - } - ares_free(thread); - - if (status == ARES_SUCCESS && rv != NULL) { - *rv = ret; - } - return status; -} - -# endif - -ares_bool_t ares_threadsafety(void) -{ - return ARES_TRUE; -} - -#else /* !CARES_THREADS */ - -/* NoOp */ -ares_thread_mutex_t *ares_thread_mutex_create(void) -{ - return NULL; -} - -void ares_thread_mutex_destroy(ares_thread_mutex_t *mut) -{ - (void)mut; -} - -void ares_thread_mutex_lock(ares_thread_mutex_t *mut) -{ - (void)mut; -} - -void ares_thread_mutex_unlock(ares_thread_mutex_t *mut) -{ - (void)mut; -} - -ares_thread_cond_t *ares_thread_cond_create(void) -{ - return NULL; -} - -void ares_thread_cond_destroy(ares_thread_cond_t *cond) -{ - (void)cond; -} - -void ares_thread_cond_signal(ares_thread_cond_t *cond) -{ - (void)cond; -} - -void ares_thread_cond_broadcast(ares_thread_cond_t *cond) -{ - (void)cond; -} - -ares_status_t ares_thread_cond_wait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut) -{ - (void)cond; - (void)mut; - return ARES_ENOTIMP; -} - -ares_status_t ares_thread_cond_timedwait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut, - unsigned long timeout_ms) -{ - (void)cond; - (void)mut; - (void)timeout_ms; - return ARES_ENOTIMP; -} - -ares_status_t ares_thread_create(ares_thread_t **thread, - ares_thread_func_t func, void *arg) -{ - (void)thread; - (void)func; - (void)arg; - return ARES_ENOTIMP; -} - -ares_status_t ares_thread_join(ares_thread_t *thread, void **rv) -{ - (void)thread; - (void)rv; - return ARES_ENOTIMP; -} - -ares_bool_t ares_threadsafety(void) -{ - return ARES_FALSE; -} -#endif - - -ares_status_t ares_channel_threading_init(ares_channel_t *channel) -{ - ares_status_t status = ARES_SUCCESS; - - /* Threading is optional! */ - if (!ares_threadsafety()) { - return ARES_SUCCESS; - } - - channel->lock = ares_thread_mutex_create(); - if (channel->lock == NULL) { - status = ARES_ENOMEM; - goto done; - } - - channel->cond_empty = ares_thread_cond_create(); - if (channel->cond_empty == NULL) { - status = ARES_ENOMEM; - goto done; - } - -done: - if (status != ARES_SUCCESS) { - ares_channel_threading_destroy(channel); - } - return status; -} - -void ares_channel_threading_destroy(ares_channel_t *channel) -{ - ares_thread_mutex_destroy(channel->lock); - channel->lock = NULL; - ares_thread_cond_destroy(channel->cond_empty); - channel->cond_empty = NULL; -} - -void ares_channel_lock(const ares_channel_t *channel) -{ - ares_thread_mutex_lock(channel->lock); -} - -void ares_channel_unlock(const ares_channel_t *channel) -{ - ares_thread_mutex_unlock(channel->lock); -} - -/* Must not be holding a channel lock already, public function only */ -ares_status_t ares_queue_wait_empty(ares_channel_t *channel, int timeout_ms) -{ - ares_status_t status = ARES_SUCCESS; - ares_timeval_t tout; - - if (!ares_threadsafety()) { - return ARES_ENOTIMP; - } - - if (channel == NULL) { - return ARES_EFORMERR; - } - - if (timeout_ms >= 0) { - ares_tvnow(&tout); - tout.sec += (ares_int64_t)(timeout_ms / 1000); - tout.usec += (unsigned int)(timeout_ms % 1000) * 1000; - } - - ares_thread_mutex_lock(channel->lock); - while (ares_llist_len(channel->all_queries)) { - if (timeout_ms < 0) { - ares_thread_cond_wait(channel->cond_empty, channel->lock); - } else { - ares_timeval_t tv_remaining; - ares_timeval_t tv_now; - unsigned long tms; - - ares_tvnow(&tv_now); - ares_timeval_remaining(&tv_remaining, &tv_now, &tout); - tms = - (unsigned long)((tv_remaining.sec * 1000) + (tv_remaining.usec / 1000)); - if (tms == 0) { - status = ARES_ETIMEOUT; - } else { - status = - ares_thread_cond_timedwait(channel->cond_empty, channel->lock, tms); - } - - /* If there was a timeout, don't loop. Otherwise, make sure this wasn't - * a spurious wakeup by looping and checking the condition. */ - if (status == ARES_ETIMEOUT) { - break; - } - } - } - ares_thread_mutex_unlock(channel->lock); - return status; -} - -void ares_queue_notify_empty(ares_channel_t *channel) -{ - if (channel == NULL) { - return; - } - - /* We are guaranteed to be holding a channel lock already */ - if (ares_llist_len(channel->all_queries)) { - return; - } - - /* Notify all waiters of the conditional */ - ares_thread_cond_broadcast(channel->cond_empty); -} diff --git a/vendor/c-ares/src/lib/util/ares_threads.h b/vendor/c-ares/src/lib/util/ares_threads.h deleted file mode 100644 index 95c543e6e..000000000 --- a/vendor/c-ares/src/lib/util/ares_threads.h +++ /dev/null @@ -1,60 +0,0 @@ -/* MIT License - * - * Copyright (c) 2023 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES__THREADS_H -#define __ARES__THREADS_H - -struct ares_thread_mutex; -typedef struct ares_thread_mutex ares_thread_mutex_t; - -ares_thread_mutex_t *ares_thread_mutex_create(void); -void ares_thread_mutex_destroy(ares_thread_mutex_t *mut); -void ares_thread_mutex_lock(ares_thread_mutex_t *mut); -void ares_thread_mutex_unlock(ares_thread_mutex_t *mut); - - -struct ares_thread_cond; -typedef struct ares_thread_cond ares_thread_cond_t; - -ares_thread_cond_t *ares_thread_cond_create(void); -void ares_thread_cond_destroy(ares_thread_cond_t *cond); -void ares_thread_cond_signal(ares_thread_cond_t *cond); -void ares_thread_cond_broadcast(ares_thread_cond_t *cond); -ares_status_t ares_thread_cond_wait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut); -ares_status_t ares_thread_cond_timedwait(ares_thread_cond_t *cond, - ares_thread_mutex_t *mut, - unsigned long timeout_ms); - - -struct ares_thread; -typedef struct ares_thread ares_thread_t; - -typedef void *(*ares_thread_func_t)(void *arg); -ares_status_t ares_thread_create(ares_thread_t **thread, - ares_thread_func_t func, void *arg); -ares_status_t ares_thread_join(ares_thread_t *thread, void **rv); - -#endif diff --git a/vendor/c-ares/src/lib/util/ares_time.h b/vendor/c-ares/src/lib/util/ares_time.h deleted file mode 100644 index c6eaf9736..000000000 --- a/vendor/c-ares/src/lib/util/ares_time.h +++ /dev/null @@ -1,48 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_TIME_H -#define __ARES_TIME_H - -/*! struct timeval on some systems like Windows doesn't support 64bit time so - * therefore can't be used due to Y2K38 issues. Make our own that does have - * 64bit time. */ -typedef struct { - ares_int64_t sec; /*!< Seconds */ - unsigned int usec; /*!< Microseconds. Can't be negative. */ -} ares_timeval_t; - -/* return true if now is exactly check time or later */ -ares_bool_t ares_timedout(const ares_timeval_t *now, - const ares_timeval_t *check); - -void ares_tvnow(ares_timeval_t *now); -void ares_timeval_remaining(ares_timeval_t *remaining, - const ares_timeval_t *now, - const ares_timeval_t *tout); -void ares_timeval_diff(ares_timeval_t *tvdiff, const ares_timeval_t *tvstart, - const ares_timeval_t *tvstop); - -#endif diff --git a/vendor/c-ares/src/lib/util/ares_timeval.c b/vendor/c-ares/src/lib/util/ares_timeval.c deleted file mode 100644 index 0b0845b6f..000000000 --- a/vendor/c-ares/src/lib/util/ares_timeval.c +++ /dev/null @@ -1,95 +0,0 @@ -/* MIT License - * - * Copyright (c) 2008 Daniel Stenberg - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - -#include "ares_private.h" - -#if defined(_WIN32) && !defined(MSDOS) - -void ares_tvnow(ares_timeval_t *now) -{ - /* QueryPerformanceCounters() has been around since Windows 2000, though - * significant fixes were made in later versions. Documentation states - * 1 microsecond or better resolution with a rollover not less than 100 years. - * This differs from GetTickCount{64}() which has a resolution between 10 and - * 16 ms. */ - LARGE_INTEGER freq; - LARGE_INTEGER current; - - /* Not sure how long it takes to get the frequency, I see it recommended to - * cache it */ - QueryPerformanceFrequency(&freq); - QueryPerformanceCounter(¤t); - - now->sec = current.QuadPart / freq.QuadPart; - /* We want to prevent overflows so we get the remainder, then multiply to - * microseconds before dividing */ - now->usec = (unsigned int)(((current.QuadPart % freq.QuadPart) * 1000000) / - freq.QuadPart); -} - -#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) - -void ares_tvnow(ares_timeval_t *now) -{ - /* clock_gettime() is guaranteed to be increased monotonically when the - * monotonic clock is queried. Time starting point is unspecified, it - * could be the system start-up time, the Epoch, or something else, - * in any case the time starting point does not change once that the - * system has started up. */ - struct timespec tsnow; - - if (clock_gettime(CLOCK_MONOTONIC, &tsnow) == 0) { - now->sec = (ares_int64_t)tsnow.tv_sec; - now->usec = (unsigned int)(tsnow.tv_nsec / 1000); - } else { - /* LCOV_EXCL_START: FallbackCode */ - struct timeval tv; - (void)gettimeofday(&tv, NULL); - now->sec = (ares_int64_t)tv.tv_sec; - now->usec = (unsigned int)tv.tv_usec; - /* LCOV_EXCL_STOP */ - } -} - -#elif defined(HAVE_GETTIMEOFDAY) - -void ares_tvnow(ares_timeval_t *now) -{ - /* gettimeofday() is not granted to be increased monotonically, due to - * clock drifting and external source time synchronization it can jump - * forward or backward in time. */ - struct timeval tv; - - (void)gettimeofday(&tv, NULL); - now->sec = (ares_int64_t)tv.tv_sec; - now->usec = (unsigned int)tv.tv_usec; -} - -#else - -# error missing sub-second time retrieval function - -#endif diff --git a/vendor/c-ares/src/lib/util/ares_uri.c b/vendor/c-ares/src/lib/util/ares_uri.c deleted file mode 100644 index d656f8347..000000000 --- a/vendor/c-ares/src/lib/util/ares_uri.c +++ /dev/null @@ -1,1626 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad house - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ - - -#include "ares_private.h" -#include "ares_uri.h" -#ifdef HAVE_STDINT_H -# include -#endif - -struct ares_uri { - char scheme[16]; - char *username; - char *password; - unsigned short port; - char host[256]; - char *path; - ares_htable_dict_t *query; - char *fragment; -}; - -/* RFC3986 character set notes: - * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - * reserved = gen-delims / sub-delims - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - * authority = [ userinfo "@" ] host [ ":" port ] - * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) - * NOTE: Use of the format "user:password" in the userinfo field is - * deprecated. Applications should not render as clear text any data - * after the first colon (":") character found within a userinfo - * subcomponent unless the data after the colon is the empty string - * (indicating no password). - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * query = *( pchar / "/" / "?" ) - * fragment = *( pchar / "/" / "?" ) - * - * NOTE: Due to ambiguity, "+" in a query must be percent-encoded, as old - * URLs used that for spaces. - */ - - -static ares_bool_t ares_uri_chis_subdelim(char x) -{ - switch (x) { - case '!': - return ARES_TRUE; - case '$': - return ARES_TRUE; - case '&': - return ARES_TRUE; - case '\'': - return ARES_TRUE; - case '(': - return ARES_TRUE; - case ')': - return ARES_TRUE; - case '*': - return ARES_TRUE; - case '+': - return ARES_TRUE; - case ',': - return ARES_TRUE; - case ';': - return ARES_TRUE; - case '=': - return ARES_TRUE; - default: - break; - } - return ARES_FALSE; -} - -/* These don't actually appear to be referenced in any logic */ -#if 0 -static ares_bool_t ares_uri_chis_gendelim(char x) -{ - switch (x) { - case ':': - return ARES_TRUE; - case '/': - return ARES_TRUE; - case '?': - return ARES_TRUE; - case '#': - return ARES_TRUE; - case '[': - return ARES_TRUE; - case ']': - return ARES_TRUE; - case '@': - return ARES_TRUE; - default: - break; - } - return ARES_FALSE; -} - - -static ares_bool_t ares_uri_chis_reserved(char x) -{ - return ares_uri_chis_gendelim(x) || ares_uri_chis_subdelim(x); -} -#endif - -static ares_bool_t ares_uri_chis_unreserved(char x) -{ - switch (x) { - case '-': - return ARES_TRUE; - case '.': - return ARES_TRUE; - case '_': - return ARES_TRUE; - case '~': - return ARES_TRUE; - default: - break; - } - return ares_isalpha(x) || ares_isdigit(x); -} - -static ares_bool_t ares_uri_chis_scheme(char x) -{ - switch (x) { - case '+': - return ARES_TRUE; - case '-': - return ARES_TRUE; - case '.': - return ARES_TRUE; - default: - break; - } - return ares_isalpha(x) || ares_isdigit(x); -} - -static ares_bool_t ares_uri_chis_authority(char x) -{ - /* This one here isn't well defined. We are going to include the valid - * characters of the subfields plus known delimiters */ - return ares_uri_chis_unreserved(x) || ares_uri_chis_subdelim(x) || x == '%' || - x == '[' || x == ']' || x == '@' || x == ':'; -} - -static ares_bool_t ares_uri_chis_userinfo(char x) -{ - /* NOTE: we don't include ':' here since we are using that as our - * username/password delimiter */ - return ares_uri_chis_unreserved(x) || ares_uri_chis_subdelim(x); -} - -static ares_bool_t ares_uri_chis_path(char x) -{ - switch (x) { - case ':': - return ARES_TRUE; - case '@': - return ARES_TRUE; - /* '/' isn't in the spec as a path character since its technically a - * delimiter but we're not splitting on '/' so we accept it as valid */ - case '/': - return ARES_TRUE; - default: - break; - } - return ares_uri_chis_unreserved(x) || ares_uri_chis_subdelim(x); -} - -static ares_bool_t ares_uri_chis_path_enc(char x) -{ - return ares_uri_chis_path(x) || x == '%'; -} - -static ares_bool_t ares_uri_chis_query(char x) -{ - switch (x) { - case '/': - return ARES_TRUE; - case '?': - return ARES_TRUE; - default: - break; - } - - /* Exclude & and = used as delimiters, they're valid characters in the - * set, just not for the individual pieces */ - return ares_uri_chis_path(x) && x != '&' && x != '='; -} - -static ares_bool_t ares_uri_chis_query_enc(char x) -{ - return ares_uri_chis_query(x) || x == '%'; -} - -static ares_bool_t ares_uri_chis_fragment(char x) -{ - switch (x) { - case '/': - return ARES_TRUE; - case '?': - return ARES_TRUE; - default: - break; - } - return ares_uri_chis_path(x); -} - -static ares_bool_t ares_uri_chis_fragment_enc(char x) -{ - return ares_uri_chis_fragment(x) || x == '%'; -} - -ares_uri_t *ares_uri_create(void) -{ - ares_uri_t *uri = ares_malloc_zero(sizeof(*uri)); - - if (uri == NULL) { - return NULL; - } - - uri->query = ares_htable_dict_create(); - if (uri->query == NULL) { - ares_free(uri); - return NULL; - } - - return uri; -} - -void ares_uri_destroy(ares_uri_t *uri) -{ - if (uri == NULL) { - return; - } - - ares_free(uri->username); - ares_free(uri->password); - ares_free(uri->path); - ares_free(uri->fragment); - ares_htable_dict_destroy(uri->query); - ares_free(uri); -} - -static ares_bool_t ares_uri_scheme_is_valid(const char *uri) -{ - size_t i; - - if (ares_strlen(uri) == 0) { - return ARES_FALSE; - } - - if (!ares_isalpha(*uri)) { - return ARES_FALSE; - } - - for (i = 0; uri[i] != 0; i++) { - if (!ares_uri_chis_scheme(uri[i])) { - return ARES_FALSE; - } - } - return ARES_TRUE; -} - -static ares_bool_t ares_uri_str_isvalid(const char *str, size_t max_len, - ares_bool_t (*ischr)(char)) -{ - size_t i; - - if (str == NULL) { - return ARES_FALSE; - } - - for (i = 0; i != max_len && str[i] != 0; i++) { - if (!ischr(str[i])) { - return ARES_FALSE; - } - } - return ARES_TRUE; -} - -ares_status_t ares_uri_set_scheme(ares_uri_t *uri, const char *scheme) -{ - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (!ares_uri_scheme_is_valid(scheme)) { - return ARES_EBADSTR; - } - - ares_strcpy(uri->scheme, scheme, sizeof(uri->scheme)); - ares_str_lower(uri->scheme); - - return ARES_SUCCESS; -} - -const char *ares_uri_get_scheme(const ares_uri_t *uri) -{ - if (uri == NULL) { - return NULL; - } - - return uri->scheme; -} - -static ares_status_t ares_uri_set_username_own(ares_uri_t *uri, char *username) -{ - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (username != NULL && (!ares_str_isprint(username, ares_strlen(username)) || - ares_strlen(username) == 0)) { - return ARES_EBADSTR; - } - - - ares_free(uri->username); - uri->username = username; - return ARES_SUCCESS; -} - -ares_status_t ares_uri_set_username(ares_uri_t *uri, const char *username) -{ - ares_status_t status; - char *temp = NULL; - - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (username != NULL) { - temp = ares_strdup(username); - if (temp == NULL) { - return ARES_ENOMEM; - } - } - - status = ares_uri_set_username_own(uri, temp); - if (status != ARES_SUCCESS) { - ares_free(temp); - } - - return status; -} - -const char *ares_uri_get_username(const ares_uri_t *uri) -{ - if (uri == NULL) { - return NULL; - } - - return uri->username; -} - -static ares_status_t ares_uri_set_password_own(ares_uri_t *uri, char *password) -{ - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (password != NULL && !ares_str_isprint(password, ares_strlen(password))) { - return ARES_EBADSTR; - } - - ares_free(uri->password); - uri->password = password; - return ARES_SUCCESS; -} - -ares_status_t ares_uri_set_password(ares_uri_t *uri, const char *password) -{ - ares_status_t status; - char *temp = NULL; - - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (password != NULL) { - temp = ares_strdup(password); - if (temp == NULL) { - return ARES_ENOMEM; - } - } - - status = ares_uri_set_password_own(uri, temp); - if (status != ARES_SUCCESS) { - ares_free(temp); - } - - return status; -} - -const char *ares_uri_get_password(const ares_uri_t *uri) -{ - if (uri == NULL) { - return NULL; - } - - return uri->password; -} - -ares_status_t ares_uri_set_host(ares_uri_t *uri, const char *host) -{ - struct ares_addr addr; - size_t addrlen; - char hoststr[256]; - char *ll_scope; - - if (uri == NULL || ares_strlen(host) == 0 || - ares_strlen(host) >= sizeof(hoststr)) { - return ARES_EFORMERR; - } - - ares_strcpy(hoststr, host, sizeof(hoststr)); - - /* Look for '%' which could be a link-local scope for ipv6 addresses and - * parse it off */ - ll_scope = strchr(hoststr, '%'); - if (ll_scope != NULL) { - *ll_scope = 0; - ll_scope++; - if (!ares_str_isalnum(ll_scope)) { - return ARES_EBADNAME; - } - } - - /* If its an IP address, normalize it */ - memset(&addr, 0, sizeof(addr)); - addr.family = AF_UNSPEC; - if (ares_dns_pton(hoststr, &addr, &addrlen) != NULL) { - char ipaddr[INET6_ADDRSTRLEN]; - ares_inet_ntop(addr.family, &addr.addr, ipaddr, sizeof(ipaddr)); - /* Only IPv6 is allowed to have a scope */ - if (ll_scope != NULL && addr.family != AF_INET6) { - return ARES_EBADNAME; - } - - if (ll_scope != NULL) { - snprintf(uri->host, sizeof(uri->host), "%s%%%s", ipaddr, ll_scope); - } else { - ares_strcpy(uri->host, ipaddr, sizeof(uri->host)); - } - return ARES_SUCCESS; - } - - /* If its a hostname, make sure its a valid charset */ - if (!ares_is_hostname(host)) { - return ARES_EBADNAME; - } - - ares_strcpy(uri->host, host, sizeof(uri->host)); - return ARES_SUCCESS; -} - -const char *ares_uri_get_host(const ares_uri_t *uri) -{ - if (uri == NULL) { - return NULL; - } - - return uri->host; -} - -ares_status_t ares_uri_set_port(ares_uri_t *uri, unsigned short port) -{ - if (uri == NULL) { - return ARES_EFORMERR; - } - uri->port = port; - return ARES_SUCCESS; -} - -unsigned short ares_uri_get_port(const ares_uri_t *uri) -{ - if (uri == NULL) { - return 0; - } - return uri->port; -} - -/* URI spec says path normalization is a requirement */ -static char *ares_uri_path_normalize(const char *path) -{ - ares_status_t status; - ares_array_t *arr = NULL; - ares_buf_t *outpath = NULL; - ares_buf_t *inpath = NULL; - ares_ssize_t i; - size_t j; - size_t len; - - inpath = - ares_buf_create_const((const unsigned char *)path, ares_strlen(path)); - if (inpath == NULL) { - status = ARES_ENOMEM; - goto done; - } - - outpath = ares_buf_create(); - if (outpath == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_buf_split_str_array(inpath, (const unsigned char *)"/", 1, - ARES_BUF_SPLIT_TRIM, 0, &arr); - if (status != ARES_SUCCESS) { - return NULL; - } - - for (i = 0; i < (ares_ssize_t)ares_array_len(arr); i++) { - const char **strptr = ares_array_at(arr, (size_t)i); - const char *str = *strptr; - - if (ares_streq(str, ".")) { - ares_array_remove_at(arr, (size_t)i); - i--; - } else if (ares_streq(str, "..")) { - if (i != 0) { - ares_array_remove_at(arr, (size_t)i - 1); - i--; - } - ares_array_remove_at(arr, (size_t)i); - i--; - } - } - - status = ares_buf_append_byte(outpath, '/'); - if (status != ARES_SUCCESS) { - goto done; - } - - len = ares_array_len(arr); - for (j = 0; j < len; j++) { - const char **strptr = ares_array_at(arr, j); - const char *str = *strptr; - status = ares_buf_append_str(outpath, str); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Path separator, but on the last entry, we need to check if it was - * originally terminated or not because they have different meanings */ - if (j != len - 1 || path[ares_strlen(path) - 1] == '/') { - status = ares_buf_append_byte(outpath, '/'); - if (status != ARES_SUCCESS) { - goto done; - } - } - } - -done: - ares_array_destroy(arr); - ares_buf_destroy(inpath); - if (status != ARES_SUCCESS) { - ares_buf_destroy(outpath); - return NULL; - } - - return ares_buf_finish_str(outpath, NULL); -} - -ares_status_t ares_uri_set_path(ares_uri_t *uri, const char *path) -{ - char *temp = NULL; - - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (path != NULL && !ares_str_isprint(path, ares_strlen(path))) { - return ARES_EBADSTR; - } - - if (path != NULL) { - temp = ares_uri_path_normalize(path); - if (temp == NULL) { - return ARES_ENOMEM; - } - } - - ares_free(uri->path); - uri->path = temp; - - return ARES_SUCCESS; -} - -const char *ares_uri_get_path(const ares_uri_t *uri) -{ - if (uri == NULL) { - return NULL; - } - - return uri->path; -} - -ares_status_t ares_uri_set_query_key(ares_uri_t *uri, const char *key, - const char *val) -{ - if (uri == NULL || key == NULL || *key == 0) { - return ARES_EFORMERR; - } - - if (!ares_str_isprint(key, ares_strlen(key)) || - (val != NULL && !ares_str_isprint(val, ares_strlen(val)))) { - return ARES_EBADSTR; - } - - if (!ares_htable_dict_insert(uri->query, key, val)) { - return ARES_ENOMEM; - } - return ARES_SUCCESS; -} - -ares_status_t ares_uri_del_query_key(ares_uri_t *uri, const char *key) -{ - if (uri == NULL || key == NULL || *key == 0 || - !ares_str_isprint(key, ares_strlen(key))) { - return ARES_EFORMERR; - } - - if (!ares_htable_dict_remove(uri->query, key)) { - return ARES_ENOTFOUND; - } - - return ARES_SUCCESS; -} - -const char *ares_uri_get_query_key(const ares_uri_t *uri, const char *key) -{ - if (uri == NULL || key == NULL || *key == 0 || - !ares_str_isprint(key, ares_strlen(key))) { - return NULL; - } - - return ares_htable_dict_get_direct(uri->query, key); -} - -char **ares_uri_get_query_keys(const ares_uri_t *uri, size_t *num) -{ - if (uri == NULL || num == NULL) { - return NULL; - } - - return ares_htable_dict_keys(uri->query, num); -} - -static ares_status_t ares_uri_set_fragment_own(ares_uri_t *uri, char *fragment) -{ - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (fragment != NULL && !ares_str_isprint(fragment, ares_strlen(fragment))) { - return ARES_EBADSTR; - } - - ares_free(uri->fragment); - uri->fragment = fragment; - return ARES_SUCCESS; -} - -ares_status_t ares_uri_set_fragment(ares_uri_t *uri, const char *fragment) -{ - ares_status_t status; - char *temp = NULL; - - if (uri == NULL) { - return ARES_EFORMERR; - } - - if (fragment != NULL) { - temp = ares_strdup(fragment); - if (temp == NULL) { - return ARES_ENOMEM; - } - } - - status = ares_uri_set_fragment_own(uri, temp); - if (status != ARES_SUCCESS) { - ares_free(temp); - } - - return status; -} - -const char *ares_uri_get_fragment(const ares_uri_t *uri) -{ - if (uri == NULL) { - return NULL; - } - return uri->fragment; -} - -static ares_status_t ares_uri_encode_buf(ares_buf_t *buf, const char *str, - ares_bool_t (*ischr)(char)) -{ - size_t i; - - if (buf == NULL || str == NULL) { - return ARES_EFORMERR; - } - - for (i = 0; str[i] != 0; i++) { - if (ischr(str[i])) { - if (ares_buf_append_byte(buf, (unsigned char)str[i]) != ARES_SUCCESS) { - return ARES_ENOMEM; - } - } else { - if (ares_buf_append_byte(buf, '%') != ARES_SUCCESS) { - return ARES_ENOMEM; - } - if (ares_buf_append_num_hex(buf, (size_t)str[i], 2) != ARES_SUCCESS) { - return ARES_ENOMEM; - } - } - } - return ARES_SUCCESS; -} - -static ares_status_t ares_uri_write_scheme(const ares_uri_t *uri, - ares_buf_t *buf) -{ - ares_status_t status; - - status = ares_buf_append_str(buf, uri->scheme); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_buf_append_str(buf, "://"); - - return status; -} - -static ares_status_t ares_uri_write_authority(const ares_uri_t *uri, - ares_buf_t *buf) -{ - ares_status_t status; - ares_bool_t is_ipv6 = ARES_FALSE; - - if (ares_strlen(uri->username)) { - status = ares_uri_encode_buf(buf, uri->username, ares_uri_chis_userinfo); - if (status != ARES_SUCCESS) { - return status; - } - } - - if (ares_strlen(uri->password)) { - status = ares_buf_append_byte(buf, ':'); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_uri_encode_buf(buf, uri->password, ares_uri_chis_userinfo); - if (status != ARES_SUCCESS) { - return status; - } - } - - if (ares_strlen(uri->username) || ares_strlen(uri->password)) { - status = ares_buf_append_byte(buf, '@'); - if (status != ARES_SUCCESS) { - return status; - } - } - - /* We need to write ipv6 addresses with [ ] */ - if (strchr(uri->host, '%') != NULL) { - /* If we have a % in the name, it must be ipv6 link local scope, so we - * don't need to check anything else */ - is_ipv6 = ARES_TRUE; - } else { - /* Parse the host to see if it is an ipv6 address */ - struct ares_addr addr; - size_t addrlen; - memset(&addr, 0, sizeof(addr)); - addr.family = AF_INET6; - if (ares_dns_pton(uri->host, &addr, &addrlen) != NULL) { - is_ipv6 = ARES_TRUE; - } - } - - if (is_ipv6) { - status = ares_buf_append_byte(buf, '['); - if (status != ARES_SUCCESS) { - return status; - } - } - - status = ares_buf_append_str(buf, uri->host); - if (status != ARES_SUCCESS) { - return status; - } - - if (is_ipv6) { - status = ares_buf_append_byte(buf, ']'); - if (status != ARES_SUCCESS) { - return status; - } - } - - if (uri->port > 0) { - status = ares_buf_append_byte(buf, ':'); - if (status != ARES_SUCCESS) { - return status; - } - status = ares_buf_append_num_dec(buf, uri->port, 0); - if (status != ARES_SUCCESS) { - return status; - } - } - - return status; -} - -static ares_status_t ares_uri_write_path(const ares_uri_t *uri, ares_buf_t *buf) -{ - ares_status_t status; - - if (ares_strlen(uri->path) == 0) { - return ARES_SUCCESS; - } - - if (*uri->path != '/') { - status = ares_buf_append_byte(buf, '/'); - if (status != ARES_SUCCESS) { - return status; - } - } - - status = ares_uri_encode_buf(buf, uri->path, ares_uri_chis_path); - if (status != ARES_SUCCESS) { - return status; - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_uri_write_query(const ares_uri_t *uri, - ares_buf_t *buf) -{ - ares_status_t status; - char **keys; - size_t num_keys = 0; - size_t i; - - if (ares_htable_dict_num_keys(uri->query) == 0) { - return ARES_SUCCESS; - } - - keys = ares_uri_get_query_keys(uri, &num_keys); - if (keys == NULL || num_keys == 0) { - return ARES_ENOMEM; - } - - status = ares_buf_append_byte(buf, '?'); - if (status != ARES_SUCCESS) { - goto done; - } - - for (i = 0; i < num_keys; i++) { - const char *val; - - if (i != 0) { - status = ares_buf_append_byte(buf, '&'); - if (status != ARES_SUCCESS) { - goto done; - } - } - - status = ares_uri_encode_buf(buf, keys[i], ares_uri_chis_query); - if (status != ARES_SUCCESS) { - goto done; - } - - val = ares_uri_get_query_key(uri, keys[i]); - if (val != NULL) { - status = ares_buf_append_byte(buf, '='); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_encode_buf(buf, val, ares_uri_chis_query); - if (status != ARES_SUCCESS) { - goto done; - } - } - } - -done: - ares_free_array(keys, num_keys, ares_free); - return status; -} - -static ares_status_t ares_uri_write_fragment(const ares_uri_t *uri, - ares_buf_t *buf) -{ - ares_status_t status; - - if (!ares_strlen(uri->fragment)) { - return ARES_SUCCESS; - } - - status = ares_buf_append_byte(buf, '#'); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_uri_encode_buf(buf, uri->fragment, ares_uri_chis_fragment); - if (status != ARES_SUCCESS) { - return status; - } - - return ARES_SUCCESS; -} - -ares_status_t ares_uri_write_buf(const ares_uri_t *uri, ares_buf_t *buf) -{ - ares_status_t status; - size_t orig_len; - - if (uri == NULL || buf == NULL) { - return ARES_EFORMERR; - } - - if (ares_strlen(uri->scheme) == 0 || ares_strlen(uri->host) == 0) { - return ARES_ENODATA; - } - - orig_len = ares_buf_len(buf); - - status = ares_uri_write_scheme(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_write_authority(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_write_path(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_write_query(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_write_fragment(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - if (status != ARES_SUCCESS) { - ares_buf_set_length(buf, orig_len); - } - return status; -} - -ares_status_t ares_uri_write(char **out, const ares_uri_t *uri) -{ - ares_buf_t *buf; - ares_status_t status; - - if (out == NULL || uri == NULL) { - return ARES_EFORMERR; - } - - *out = NULL; - - buf = ares_buf_create(); - if (buf == NULL) { - return ARES_ENOMEM; - } - - status = ares_uri_write_buf(uri, buf); - if (status != ARES_SUCCESS) { - ares_buf_destroy(buf); - return status; - } - - *out = ares_buf_finish_str(buf, NULL); - return ARES_SUCCESS; -} - -#define xdigit_val(x) \ - ((x >= '0' && x <= '9') \ - ? (x - '0') \ - : ((x >= 'A' && x <= 'F') ? (x - 'A' + 10) : (x - 'a' + 10))) - -static ares_status_t ares_uri_decode_inplace(char *str, ares_bool_t is_query, - ares_bool_t must_be_printable, - size_t *out_len) -{ - size_t i; - size_t len = 0; - - for (i = 0; str[i] != 0; i++) { - if (is_query && str[i] == '+') { - str[len++] = ' '; - continue; - } - - if (str[i] != '%') { - str[len++] = str[i]; - continue; - } - - if (!ares_isxdigit(str[i + 1]) || !ares_isxdigit(str[i + 2])) { - return ARES_EBADSTR; - } - - str[len] = (char)(xdigit_val(str[i + 1]) << 4 | xdigit_val(str[i + 2])); - - if (must_be_printable && !ares_isprint(str[len])) { - return ARES_EBADSTR; - } - - len++; - - i += 2; - } - - str[len] = 0; - - *out_len = len; - return ARES_SUCCESS; -} - -static ares_status_t ares_uri_parse_scheme(ares_uri_t *uri, ares_buf_t *buf) -{ - ares_status_t status; - size_t bytes; - char scheme[sizeof(uri->scheme)]; - - ares_buf_tag(buf); - - bytes = - ares_buf_consume_until_seq(buf, (const unsigned char *)"://", 3, ARES_TRUE); - if (bytes == SIZE_MAX || bytes > sizeof(uri->scheme)) { - return ARES_EBADSTR; - } - - status = ares_buf_tag_fetch_string(buf, scheme, sizeof(scheme)); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_uri_set_scheme(uri, scheme); - if (status != ARES_SUCCESS) { - return status; - } - - /* Consume :// */ - ares_buf_consume(buf, 3); - - return ARES_SUCCESS; -} - -static ares_status_t ares_uri_parse_userinfo(ares_uri_t *uri, ares_buf_t *buf) -{ - size_t userinfo_len; - size_t username_len; - ares_bool_t has_password = ARES_FALSE; - char *temp = NULL; - ares_status_t status; - size_t len; - - ares_buf_tag(buf); - - /* Search for @, if its not found, return */ - userinfo_len = ares_buf_consume_until_charset(buf, (const unsigned char *)"@", - 1, ARES_TRUE); - - if (userinfo_len == SIZE_MAX) { - return ARES_SUCCESS; - } - - /* Rollback since now we know there really is userinfo */ - ares_buf_tag_rollback(buf); - - /* Search for ':', if it isn't found or its past the '@' then we only have - * a username and no password */ - ares_buf_tag(buf); - username_len = ares_buf_consume_until_charset(buf, (const unsigned char *)":", - 1, ARES_TRUE); - if (username_len < userinfo_len) { - has_password = ARES_TRUE; - status = ares_buf_tag_fetch_strdup(buf, &temp); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_decode_inplace(temp, ARES_FALSE, ARES_TRUE, &len); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_set_username_own(uri, temp); - if (status != ARES_SUCCESS) { - goto done; - } - temp = NULL; - - /* Consume : */ - ares_buf_consume(buf, 1); - } - - ares_buf_tag(buf); - ares_buf_consume_until_charset(buf, (const unsigned char *)"@", 1, ARES_TRUE); - status = ares_buf_tag_fetch_strdup(buf, &temp); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_decode_inplace(temp, ARES_FALSE, ARES_TRUE, &len); - if (status != ARES_SUCCESS) { - goto done; - } - - if (has_password) { - status = ares_uri_set_password_own(uri, temp); - } else { - status = ares_uri_set_username_own(uri, temp); - } - if (status != ARES_SUCCESS) { - goto done; - } - temp = NULL; - - /* Consume @ */ - ares_buf_consume(buf, 1); - -done: - ares_free(temp); - return status; -} - -static ares_status_t ares_uri_parse_hostport(ares_uri_t *uri, ares_buf_t *buf) -{ - unsigned char b; - char host[256]; - char port[6]; - size_t len; - ares_status_t status; - - status = ares_buf_peek_byte(buf, &b); - if (status != ARES_SUCCESS) { - return status; - } - - /* Bracketed syntax for ipv6 addresses */ - if (b == '[') { - ares_buf_consume(buf, 1); - ares_buf_tag(buf); - len = ares_buf_consume_until_charset(buf, (const unsigned char *)"]", 1, - ARES_TRUE); - if (len == SIZE_MAX) { - return ARES_EBADSTR; - } - - status = ares_buf_tag_fetch_string(buf, host, sizeof(host)); - if (status != ARES_SUCCESS) { - return status; - } - /* Consume ']' */ - ares_buf_consume(buf, 1); - } else { - /* Either ipv4 or hostname */ - ares_buf_tag(buf); - ares_buf_consume_until_charset(buf, (const unsigned char *)":", 1, - ARES_FALSE); - - status = ares_buf_tag_fetch_string(buf, host, sizeof(host)); - if (status != ARES_SUCCESS) { - return status; - } - } - - status = ares_uri_set_host(uri, host); - if (status != ARES_SUCCESS) { - return status; - } - - /* No port if nothing left to consume */ - if (!ares_buf_len(buf)) { - return status; - } - - status = ares_buf_peek_byte(buf, &b); - if (status != ARES_SUCCESS) { - return status; - } - - /* Only valid extra character at this point is ':' */ - if (b != ':') { - return ARES_EBADSTR; - } - ares_buf_consume(buf, 1); - - len = ares_buf_len(buf); - if (len == 0 || len > sizeof(port) - 1) { - return ARES_EBADSTR; - } - - status = ares_buf_fetch_bytes(buf, (unsigned char *)port, len); - if (status != ARES_SUCCESS) { - return status; - } - port[len] = 0; - - if (!ares_str_isnum(port)) { - return ARES_EBADSTR; - } - - status = ares_uri_set_port(uri, (unsigned short)atoi(port)); - if (status != ARES_SUCCESS) { - return status; - } - - return ARES_SUCCESS; -} - -static ares_status_t ares_uri_parse_authority(ares_uri_t *uri, ares_buf_t *buf) -{ - ares_status_t status; - size_t bytes; - ares_buf_t *auth = NULL; - const unsigned char *ptr; - size_t ptr_len; - - ares_buf_tag(buf); - - bytes = ares_buf_consume_until_charset(buf, (const unsigned char *)"/?#", 3, - ARES_FALSE); - if (bytes == 0) { - return ARES_EBADSTR; - } - - status = ares_buf_tag_fetch_constbuf(buf, &auth); - if (status != ARES_SUCCESS) { - goto done; - } - - ptr = ares_buf_peek(auth, &ptr_len); - if (!ares_uri_str_isvalid((const char *)ptr, ptr_len, - ares_uri_chis_authority)) { - status = ARES_EBADSTR; - goto done; - } - - status = ares_uri_parse_userinfo(uri, auth); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_parse_hostport(uri, auth); - if (status != ARES_SUCCESS) { - goto done; - } - - /* NOTE: the /, ?, or # is still in the buffer at this point so it can - * be used to determine what parser should be called next */ - -done: - ares_buf_destroy(auth); - return status; -} - -static ares_status_t ares_uri_parse_path(ares_uri_t *uri, ares_buf_t *buf) -{ - unsigned char b; - char *path = NULL; - ares_status_t status; - size_t len; - - if (ares_buf_len(buf) == 0) { - return ARES_SUCCESS; - } - - status = ares_buf_peek_byte(buf, &b); - if (status != ARES_SUCCESS) { - return status; - } - - /* Not a path, must be one of the others */ - if (b != '/') { - return ARES_SUCCESS; - } - - ares_buf_tag(buf); - ares_buf_consume_until_charset(buf, (const unsigned char *)"?#", 2, - ARES_FALSE); - status = ares_buf_tag_fetch_strdup(buf, &path); - if (status != ARES_SUCCESS) { - goto done; - } - - if (!ares_uri_str_isvalid(path, SIZE_MAX, ares_uri_chis_path_enc)) { - status = ARES_EBADSTR; - goto done; - } - - status = ares_uri_decode_inplace(path, ARES_FALSE, ARES_TRUE, &len); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_set_path(uri, path); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_free(path); - return status; -} - -static ares_status_t ares_uri_parse_query_buf(ares_uri_t *uri, ares_buf_t *buf) -{ - ares_status_t status = ARES_SUCCESS; - char *key = NULL; - char *val = NULL; - - while (ares_buf_len(buf) > 0) { - unsigned char b = 0; - size_t len; - - ares_buf_tag(buf); - - /* Its valid to have only a key with no value, so we search for both - * delims */ - len = ares_buf_consume_until_charset(buf, (const unsigned char *)"&=", 2, - ARES_FALSE); - if (len == 0) { - /* If we're here, we have a zero length key which is invalid */ - status = ARES_EBADSTR; - goto done; - } - - if (ares_buf_len(buf) > 0) { - /* Determine if we stopped on & or = */ - status = ares_buf_peek_byte(buf, &b); - if (status != ARES_SUCCESS) { - goto done; - } - } - - status = ares_buf_tag_fetch_strdup(buf, &key); - if (status != ARES_SUCCESS) { - goto done; - } - - if (!ares_uri_str_isvalid(key, SIZE_MAX, ares_uri_chis_query_enc)) { - status = ARES_EBADSTR; - goto done; - } - - status = ares_uri_decode_inplace(key, ARES_TRUE, ARES_TRUE, &len); - if (status != ARES_SUCCESS) { - goto done; - } - - /* Fetch Value */ - if (b == '=') { - /* Skip delimiter */ - ares_buf_consume(buf, 1); - ares_buf_tag(buf); - len = ares_buf_consume_until_charset(buf, (const unsigned char *)"&", 1, - ARES_FALSE); - if (len > 0) { - status = ares_buf_tag_fetch_strdup(buf, &val); - if (status != ARES_SUCCESS) { - goto done; - } - - if (!ares_uri_str_isvalid(val, SIZE_MAX, ares_uri_chis_query_enc)) { - status = ARES_EBADSTR; - goto done; - } - - status = ares_uri_decode_inplace(val, ARES_TRUE, ARES_TRUE, &len); - if (status != ARES_SUCCESS) { - goto done; - } - } - } - - if (b != 0) { - /* Consume '&' */ - ares_buf_consume(buf, 1); - } - - status = ares_uri_set_query_key(uri, key, val); - if (status != ARES_SUCCESS) { - goto done; - } - - ares_free(key); - key = NULL; - ares_free(val); - val = NULL; - } - -done: - ares_free(key); - ares_free(val); - return status; -} - -static ares_status_t ares_uri_parse_query(ares_uri_t *uri, ares_buf_t *buf) -{ - unsigned char b; - ares_status_t status; - ares_buf_t *query = NULL; - size_t len; - - if (ares_buf_len(buf) == 0) { - return ARES_SUCCESS; - } - - status = ares_buf_peek_byte(buf, &b); - if (status != ARES_SUCCESS) { - return status; - } - - /* Not a query, must be one of the others */ - if (b != '?') { - return ARES_SUCCESS; - } - - /* Only possible terminator is fragment indicator of '#' */ - ares_buf_consume(buf, 1); - ares_buf_tag(buf); - len = ares_buf_consume_until_charset(buf, (const unsigned char *)"#", 1, - ARES_FALSE); - if (len == 0) { - /* No data, return */ - return ARES_SUCCESS; - } - - status = ares_buf_tag_fetch_constbuf(buf, &query); - if (status != ARES_SUCCESS) { - return status; - } - - status = ares_uri_parse_query_buf(uri, query); - ares_buf_destroy(query); - - return status; -} - -static ares_status_t ares_uri_parse_fragment(ares_uri_t *uri, ares_buf_t *buf) -{ - unsigned char b; - char *fragment = NULL; - ares_status_t status; - size_t len; - - if (ares_buf_len(buf) == 0) { - return ARES_SUCCESS; - } - - status = ares_buf_peek_byte(buf, &b); - if (status != ARES_SUCCESS) { - return status; - } - - /* Not a fragment, must be one of the others */ - if (b != '#') { - return ARES_SUCCESS; - } - - ares_buf_consume(buf, 1); - - if (ares_buf_len(buf) == 0) { - return ARES_SUCCESS; - } - - /* Rest of the buffer is the fragment */ - status = ares_buf_fetch_str_dup(buf, ares_buf_len(buf), &fragment); - if (status != ARES_SUCCESS) { - goto done; - } - - if (!ares_uri_str_isvalid(fragment, SIZE_MAX, ares_uri_chis_fragment_enc)) { - status = ARES_EBADSTR; - goto done; - } - - status = ares_uri_decode_inplace(fragment, ARES_FALSE, ARES_TRUE, &len); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_set_fragment_own(uri, fragment); - if (status != ARES_SUCCESS) { - goto done; - } - fragment = NULL; - -done: - ares_free(fragment); - return status; -} - -ares_status_t ares_uri_parse_buf(ares_uri_t **out, ares_buf_t *buf) -{ - ares_status_t status; - ares_uri_t *uri = NULL; - size_t orig_pos; - - if (out == NULL || buf == NULL) { - return ARES_EFORMERR; - } - - *out = NULL; - - orig_pos = ares_buf_get_position(buf); - - uri = ares_uri_create(); - if (uri == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_uri_parse_scheme(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_parse_authority(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_parse_path(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_parse_query(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_parse_fragment(uri, buf); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - if (status != ARES_SUCCESS) { - ares_buf_set_position(buf, orig_pos); - ares_uri_destroy(uri); - } else { - *out = uri; - } - return status; -} - -ares_status_t ares_uri_parse(ares_uri_t **out, const char *str) -{ - ares_status_t status; - ares_buf_t *buf = NULL; - - if (out == NULL || str == NULL) { - return ARES_EFORMERR; - } - - *out = NULL; - - buf = ares_buf_create(); - if (buf == NULL) { - status = ARES_ENOMEM; - goto done; - } - - status = ares_buf_append_str(buf, str); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares_uri_parse_buf(out, buf); - if (status != ARES_SUCCESS) { - goto done; - } - -done: - ares_buf_destroy(buf); - - return status; -} diff --git a/vendor/c-ares/src/lib/util/ares_uri.h b/vendor/c-ares/src/lib/util/ares_uri.h deleted file mode 100644 index 2d8138fdc..000000000 --- a/vendor/c-ares/src/lib/util/ares_uri.h +++ /dev/null @@ -1,252 +0,0 @@ -/* MIT License - * - * Copyright (c) 2024 Brad House - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - */ -#ifndef __ARES_URI_H -#define __ARES_URI_H - -/*! \addtogroup ares_uri URI parser and writer implementation - * - * This is a fairly complete URI parser and writer implementation (RFC 3986) for - * schemes which use the :// syntax. Does not currently support URIs without an - * authority section, such as "mailto:person@example.com". - * - * Its implementation is overkill for our current needs to be able to express - * DNS server configuration, but there was really no reason not to support - * a greater subset of the specification. - * - * @{ - */ - - -struct ares_uri; - -/*! URI object */ -typedef struct ares_uri ares_uri_t; - -/*! Create a new URI object - * - * \return new ares_uri_t, must be freed with ares_uri_destroy() - */ -ares_uri_t *ares_uri_create(void); - -/*! Destroy an initialized URI object - * - * \param[in] uri Initialized URI object - */ -void ares_uri_destroy(ares_uri_t *uri); - -/*! Set the URI scheme. Automatically lower-cases the scheme provided. - * Only allows Alpha, Digit, +, -, and . characters. Maximum length is - * 15 characters. This is required to be set to write a URI. - * - * \param[in] uri Initialized URI object - * \param[in] scheme Scheme to set the object to use - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_scheme(ares_uri_t *uri, const char *scheme); - -/*! Retrieve the currently configured URI scheme. - * - * \param[in] uri Initialized URI object - * \return string containing URI scheme - */ -const char *ares_uri_get_scheme(const ares_uri_t *uri); - -/*! Set the username in the URI object - * - * \param[in] uri Initialized URI object - * \param[in] username Username to set. May be NULL to unset existing username. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_username(ares_uri_t *uri, const char *username); - -/*! Retrieve the currently configured username. - * - * \param[in] uri Initialized URI object - * \return string containing username, maybe NULL if not set. - */ -const char *ares_uri_get_username(const ares_uri_t *uri); - -/*! Set the password in the URI object - * - * \param[in] uri Initialized URI object - * \param[in] password Password to set. May be NULL to unset existing password. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_password(ares_uri_t *uri, const char *password); - -/*! Retrieve the currently configured password. - * - * \param[in] uri Initialized URI object - * \return string containing password, maybe NULL if not set. - */ -const char *ares_uri_get_password(const ares_uri_t *uri); - -/*! Set the host or ip address in the URI object. This is required to be - * set to write a URI. The character set is strictly validated. - * - * \param[in] uri Initialized URI object - * \param[in] host IPv4, IPv6, or hostname to set. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_host(ares_uri_t *uri, const char *host); - -/*! Retrieve the currently configured host (or ip address). IPv6 addresses - * May include a link-local scope (e.g. fe80::b542:84df:1719:65e3%en0). - * - * \param[in] uri Initialized URI object - * \return string containing host, maybe NULL if not set. - */ -const char *ares_uri_get_host(const ares_uri_t *uri); - -/*! Set the port to use in the URI object. A port value of 0 will omit - * the port from the URI when written, thus using the scheme's default. - * - * \param[in] uri Initialized URI object - * \param[in] port Port to set. Use 0 to unset. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_port(ares_uri_t *uri, unsigned short port); - -/*! Retrieve the currently configured port - * - * \param[in] uri Initialized URI object - * \return port number, or 0 if not set. - */ -unsigned short ares_uri_get_port(const ares_uri_t *uri); - -/*! Set the path in the URI object. Unsupported characters will be URI-encoded - * when written. - * - * \param[in] uri Initialized URI object - * \param[in] path Path to set. May be NULL to unset existing path. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_path(ares_uri_t *uri, const char *path); - -/*! Retrieves the path in the URI object. If retrieved after parse, this - * value will be URI-decoded already. - * - * \param[in] uri Initialized URI object - * \return path string, or NULL if not set. - */ -const char *ares_uri_get_path(const ares_uri_t *uri); - -/*! Set a new query key/value pair. There is no set order for query keys - * when output in the URI, they will be emitted in a random order. Keys are - * case-insensitive. Query keys and values will be automatically URI-encoded - * when written. - * - * \param[in] uri Initialized URI object - * \param[in] key Query key to use, must be non-zero length. - * \param[in] val Query value to use, may be NULL. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_query_key(ares_uri_t *uri, const char *key, - const char *val); - -/*! Delete a specific query key. - * - * \param[in] uri Initialized URI object - * \param[in] key Key to delete. - * \return ARES_SUCCESS if deleted, ARES_ENOTFOUND if not found - */ -ares_status_t ares_uri_del_query_key(ares_uri_t *uri, const char *key); - -/*! Retrieve the value associated with a query key. Keys are case-insensitive. - * - * \param[in] uri Initialized URI object - * \param[in] key Key to retrieve. - * \return string representing value, may be NULL if either not found or - * NULL value set. There is currently no way to indicate the - * difference. - */ -const char *ares_uri_get_query_key(const ares_uri_t *uri, const char *key); - -/*! Retrieve a complete list of query keys. - * - * \param[in] uri Initialized URI object - * \param[out] num Number of keys. - * \return NULL on failure or no keys. Use - * ares_free_array(keys, num, ares_free) when done with array. - */ -char **ares_uri_get_query_keys(const ares_uri_t *uri, size_t *num); - -/*! Set the fragment in the URI object. Unsupported characters will be - * URI-encoded when written. - * - * \param[in] uri Initialized URI object - * \param[in] fragment Fragment to set. May be NULL to unset existing fragment. - * \return ARES_SUCCESS on success - */ -ares_status_t ares_uri_set_fragment(ares_uri_t *uri, const char *fragment); - -/*! Retrieves the fragment in the URI object. If retrieved after parse, this - * value will be URI-decoded already. - * - * \param[in] uri Initialized URI object - * \return fragment string, or NULL if not set. - */ -const char *ares_uri_get_fragment(const ares_uri_t *uri); - -/*! Parse the provided URI buffer into a new URI object. - * - * \param[out] out Returned new URI object. free with ares_uri_destroy(). - * \param[in] buf Buffer object containing the URI - * \return ARES_SUCCESS on successful parse. On failure the 'buf' object will - * be restored to its initial state in case another parser needs to - * be attempted. - */ -ares_status_t ares_uri_parse_buf(ares_uri_t **out, ares_buf_t *buf); - -/*! Parse the provided URI string into a new URI object. - * - * \param[out] out Returned new URI object. free with ares_uri_destroy(). - * \param[in] uri URI string to parse - * \return ARES_SUCCESS on successful parse - */ -ares_status_t ares_uri_parse(ares_uri_t **out, const char *uri); - -/*! Write URI object to a new string buffer. Requires at least the scheme - * and host to be set for this to succeed. - * - * \param[out] out Returned new URI string. Free with ares_free(). - * \param[in] uri Initialized URI object. - * \return ARES_SUCCESS on successful write. - */ -ares_status_t ares_uri_write(char **out, const ares_uri_t *uri); - -/*! Write URI object to an existing ares_buf_t object. Requires at least the - * scheme and host to be set for this to succeed. - * - * \param[in] uri Initialized URI object. - * \param[in,out] buf Destination buf object. - * \return ARES_SUCCESS on successful write. - */ -ares_status_t ares_uri_write_buf(const ares_uri_t *uri, ares_buf_t *buf); - -/*! @} */ - -#endif /* __ARES_URI_H */ diff --git a/vendor/c-ares/src/lib/windows_port.c b/vendor/c-ares/src/lib/windows_port.c deleted file mode 100644 index 22f0dc020..000000000 --- a/vendor/c-ares/src/lib/windows_port.c +++ /dev/null @@ -1,29 +0,0 @@ -/********************************************************************** - * - * Copyright (c) 1998 Massachusetts Institute of Technology - * Copyright (C) Daniel Stenberg - * - * SPDX-License-Identifier: MIT - * - */ -#include "ares_private.h" - - -/* only do the following on windows - */ -#if defined(_WIN32) && !defined(MSDOS) - -# ifdef __WATCOMC__ -/* - * Watcom needs a DllMain() in order to initialise the clib startup code. - */ -BOOL WINAPI DllMain(HINSTANCE hnd, DWORD reason, LPVOID reserved) -{ - (void)hnd; - (void)reason; - (void)reserved; - return (TRUE); -} -# endif - -#endif /* WIN32 builds only */ diff --git a/vendor/curl.mask b/vendor/curl.mask deleted file mode 100644 index 721ec1341..000000000 --- a/vendor/curl.mask +++ /dev/null @@ -1,69 +0,0 @@ -CMakeLists.txt -CMake -.circleci -.reuse -docs -tests -m4 -packages -plan9 -projects -winbuild -src -scripts -LICENSES -GIT-INFO.md -appveyor.sh -.azure-pipelines.yml -.cirrus.yml -.dcignore -.dir-locals.el -.git-blame-ignore-revs -.mailmap -acinclude.m4 -appveyor.yml -buildconf -buildconf.bat -CHANGES -configure.ac -curl-config.in -GIT-INFO -libcurl.def -libcurl.pc.in -MacOSX-Framework -Makefile.am -Makefile.dist -maketgz -README -README.md -RELEASE-NOTES -SECURITY.md -include/Makefile.am -include/README.md -include/curl/Makefile.am -include/curl/.gitignore -lib/.checksrc -lib/.gitattributes -lib/.gitignore -lib/CMakeLists.txt -lib/libcurl.plist.in -lib/libcurl.rc -lib/libcurl.vers.in -lib/optiontable.pl -lib/Makefile.am -lib/Makefile.inc -lib/Makefile.mk -lib/Makefile.soname -lib/curl_config.h.cmake -Dockerfile -lib/dllmain.c -renovate.json -REUSE.toml -CHANGES.md -lib/libcurl.def -lib/vauth/.checksrc -lib/vquic/.checksrc -lib/vssh/.checksrc -lib/vtls/.checksrc -.editorconfig -.clang-tidy.yml diff --git a/vendor/curl/COPYING b/vendor/curl/COPYING deleted file mode 100644 index 2f71d999a..000000000 --- a/vendor/curl/COPYING +++ /dev/null @@ -1,22 +0,0 @@ -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1996 - 2026, Daniel Stenberg, , and many -contributors, see the THANKS file. - -All rights reserved. - -Permission to use, copy, modify, and distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright -notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. diff --git a/vendor/curl/include/curl/curl.h b/vendor/curl/include/curl/curl.h deleted file mode 100644 index 6961a6c4c..000000000 --- a/vendor/curl/include/curl/curl.h +++ /dev/null @@ -1,3343 +0,0 @@ -#ifndef CURLINC_CURL_H -#define CURLINC_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* - * If you have libcurl problems, all docs and details are found here: - * https://curl.se/libcurl/ - */ - -#ifdef CURL_NO_OLDIES -#define CURL_STRICTER /* not used since 8.11.0 */ -#endif - -/* Compile-time deprecation macros. */ -#if (defined(__GNUC__) && \ - ((__GNUC__ > 12) || ((__GNUC__ == 12) && (__GNUC_MINOR__ >= 1))) || \ - (defined(__clang__) && __clang_major__ >= 3) || \ - defined(__IAR_SYSTEMS_ICC__)) && \ - !defined(__INTEL_COMPILER) && \ - !defined(CURL_DISABLE_DEPRECATION) && !defined(BUILDING_LIBCURL) -#define CURL_DEPRECATED(version, message) \ - __attribute__((deprecated("since " # version ". " message))) -#ifdef __IAR_SYSTEMS_ICC__ -#define CURL_IGNORE_DEPRECATION(statements) \ - _Pragma("diag_suppress=Pe1444") \ - statements \ - _Pragma("diag_default=Pe1444") -#else -#define CURL_IGNORE_DEPRECATION(statements) \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ - statements \ - _Pragma("GCC diagnostic pop") -#endif -#else -#define CURL_DEPRECATED(version, message) -#define CURL_IGNORE_DEPRECATION(statements) statements -#endif - -#include "curlver.h" /* libcurl version defines */ -#include "system.h" /* determine things runtime */ - -#include -#include - -#if defined(__FreeBSD__) || defined(__MidnightBSD__) -/* Needed for __FreeBSD_version or __MidnightBSD_version symbol definition */ -#include -#endif - -/* The include stuff here below is mainly for time_t! */ -#include -#include - -#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ - defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) -/* The check above prevents the winsock2.h inclusion if winsock.h already was - included, since they cannot co-exist without problems */ -#include -#include -#endif -#endif - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on systems that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__INTEGRITY) || \ - defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ - defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \ - (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \ - defined(__sun__) || defined(__serenity__) || defined(__vxworks__) -#include -#endif - -#ifndef _WIN32 -#include -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURL; -typedef void CURLSH; - -/* - * libcurl external API function linkage decorations. - */ - -#ifdef __has_declspec_attribute -#define CURL_HAS_DECLSPEC_ATTRIBUTE(x) __has_declspec_attribute(x) -#else -#define CURL_HAS_DECLSPEC_ATTRIBUTE(x) 0 -#endif - -#ifdef CURL_STATICLIB -# define CURL_EXTERN -#elif defined(_WIN32) || \ - (CURL_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \ - CURL_HAS_DECLSPEC_ATTRIBUTE(dllimport)) -# ifdef BUILDING_LIBCURL -# define CURL_EXTERN __declspec(dllexport) -# else -# define CURL_EXTERN __declspec(dllimport) -# endif -#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) -# define CURL_EXTERN CURL_EXTERN_SYMBOL -#else -# define CURL_EXTERN -#endif - -#ifndef curl_socket_typedef -/* socket typedef */ -#if defined(_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD (-1) -#endif -#define curl_socket_typedef -#endif /* curl_socket_typedef */ - -/* enum for the different supported SSL backends */ -typedef enum { - CURLSSLBACKEND_NONE = 0, - CURLSSLBACKEND_OPENSSL = 1, - CURLSSLBACKEND_GNUTLS = 2, - CURLSSLBACKEND_NSS CURL_DEPRECATED(8.3.0, "") = 3, - CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ - CURLSSLBACKEND_GSKIT CURL_DEPRECATED(8.3.0, "") = 5, - CURLSSLBACKEND_POLARSSL CURL_DEPRECATED(7.69.0, "") = 6, - CURLSSLBACKEND_WOLFSSL = 7, - CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_SECURETRANSPORT CURL_DEPRECATED(8.15.0, "") = 9, - CURLSSLBACKEND_AXTLS CURL_DEPRECATED(7.61.0, "") = 10, - CURLSSLBACKEND_MBEDTLS = 11, - CURLSSLBACKEND_MESALINK CURL_DEPRECATED(7.82.0, "") = 12, - CURLSSLBACKEND_BEARSSL CURL_DEPRECATED(8.15.0, "") = 13, - CURLSSLBACKEND_RUSTLS = 14 -} curl_sslbackend; - -/* aliases for library clones and renames */ -#define CURLSSLBACKEND_AWSLC CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL - -/* deprecated names: */ -#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL -#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT - -/* bits for the CURLOPT_FOLLOWLOCATION option */ -#define CURLFOLLOW_ALL 1L /* generic follow redirects */ - -/* Do not use the custom method in the follow-up request if the HTTP code - instructs so (301, 302, 303). */ -#define CURLFOLLOW_OBEYCODE 2L - -/* Only use the custom method in the first request, always reset in the next */ -#define CURLFOLLOW_FIRSTONLY 3L - -struct curl_httppost { - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field, see also - CURL_HTTPPOST_LARGE */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist *contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ - -/* specified content is a filename */ -#define CURL_HTTPPOST_FILENAME (1 << 0) -/* specified content is a filename */ -#define CURL_HTTPPOST_READFILE (1 << 1) -/* name is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRNAME (1 << 2) -/* contents is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRCONTENTS (1 << 3) -/* upload file from buffer */ -#define CURL_HTTPPOST_BUFFER (1 << 4) -/* upload file from pointer contents */ -#define CURL_HTTPPOST_PTRBUFFER (1 << 5) -/* upload file contents by using the regular read callback to get the data and - pass the given pointer as custom pointer */ -#define CURL_HTTPPOST_CALLBACK (1 << 6) -/* use size in 'contentlen', added in 7.46.0 */ -#define CURL_HTTPPOST_LARGE (1 << 7) - - char *showfilename; /* The filename to show. If not set, the - actual filename is used (if this is - a file part) */ - void *userp; /* custom pointer used for - HTTPPOST_CALLBACK posts */ - curl_off_t contentlen; /* alternative length of contents - field. Used if CURL_HTTPPOST_LARGE is - set. Added in 7.46.0 */ -}; - -/* This is a return code for the progress callback that, when returned, - signals libcurl to continue executing the default progress function */ -#define CURL_PROGRESSFUNC_CONTINUE 0x10000001 - -/* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now - considered deprecated but was the only choice up until 7.31.0 */ -typedef int (*curl_progress_callback)(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - -/* This is the CURLOPT_XFERINFOFUNCTION callback prototype. It was introduced - in 7.32.0, avoids the use of floating point numbers and provides more - detailed information. */ -typedef int (*curl_xferinfo_callback)(void *clientp, - curl_off_t dltotal, - curl_off_t dlnow, - curl_off_t ultotal, - curl_off_t ulnow); - -#ifndef CURL_MAX_READ_SIZE - /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ -#define CURL_MAX_READ_SIZE (10*1024*1024) -#endif - -#ifndef CURL_MAX_WRITE_SIZE - /* Tests have proven that 20K is a bad buffer size for uploads on Windows, - while 16K for some odd reason performed a lot better. We do the ifndef - check to allow this value to easier be changed at build time for those - who feel adventurous. The practical minimum is about 400 bytes since - libcurl uses a buffer of this size as a scratch area (unrelated to - network send operations). */ -#define CURL_MAX_WRITE_SIZE 16384 -#endif - -#ifndef CURL_MAX_HTTP_HEADER -/* The only reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that causes reallocs - infinitely */ -#define CURL_MAX_HTTP_HEADER (100*1024) -#endif - -/* This is a magic return code for the write callback that, when returned, - signals libcurl to pause receiving on the current transfer. */ -#define CURL_WRITEFUNC_PAUSE 0x10000001 - -/* This is a magic return code for the write callback that, when returned, - signals an error from the callback. */ -#define CURL_WRITEFUNC_ERROR 0xFFFFFFFF - -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - -/* This callback is called when a new resolver request is made */ -typedef int (*curl_resolver_start_callback)(void *resolver_state, - void *reserved, void *userdata); - -/* enumeration of file types */ -typedef enum { - CURLFILETYPE_FILE = 0, - CURLFILETYPE_DIRECTORY, - CURLFILETYPE_SYMLINK, - CURLFILETYPE_DEVICE_BLOCK, - CURLFILETYPE_DEVICE_CHAR, - CURLFILETYPE_NAMEDPIPE, - CURLFILETYPE_SOCKET, - CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ - - CURLFILETYPE_UNKNOWN /* should never occur */ -} curlfiletype; - -#define CURLFINFOFLAG_KNOWN_FILENAME (1 << 0) -#define CURLFINFOFLAG_KNOWN_FILETYPE (1 << 1) -#define CURLFINFOFLAG_KNOWN_TIME (1 << 2) -#define CURLFINFOFLAG_KNOWN_PERM (1 << 3) -#define CURLFINFOFLAG_KNOWN_UID (1 << 4) -#define CURLFINFOFLAG_KNOWN_GID (1 << 5) -#define CURLFINFOFLAG_KNOWN_SIZE (1 << 6) -#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1 << 7) - -/* Information about a single file, used when doing FTP wildcard matching */ -struct curl_fileinfo { - char *filename; - curlfiletype filetype; - time_t time; /* always zero! */ - unsigned int perm; - int uid; - int gid; - curl_off_t size; - long int hardlinks; - - struct { - /* If some of these fields is not NULL, it is a pointer to b_data. */ - char *time; - char *perm; - char *user; - char *group; - char *target; /* pointer to the target filename of a symlink */ - } strings; - - unsigned int flags; - - /* These are libcurl private struct fields. Previously used by libcurl, so - they must never be interfered with. */ - char *b_data; - size_t b_size; - size_t b_used; -}; - -/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ -#define CURL_CHUNK_BGN_FUNC_OK 0 -#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ -#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ - -/* if splitting of data transfer is enabled, this callback is called before - download of an individual chunk started. Note that parameter "remains" works - only for FTP wildcard downloading (for now), otherwise is not used */ -typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, - void *ptr, - int remains); - -/* return codes for CURLOPT_CHUNK_END_FUNCTION */ -#define CURL_CHUNK_END_FUNC_OK 0 -#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ - -/* If splitting of data transfer is enabled this callback is called after - download of an individual chunk finished. - Note! After this callback was set then it have to be called FOR ALL chunks. - Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. - This is the reason why we do not need "transfer_info" parameter in this - callback and we are not interested in "remains" parameter too. */ -typedef long (*curl_chunk_end_callback)(void *ptr); - -/* return codes for FNMATCHFUNCTION */ -#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ -#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern does not match the string */ -#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ - -/* callback type for wildcard downloading pattern matching. If the - string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ -typedef int (*curl_fnmatch_callback)(void *ptr, - const char *pattern, - const char *string); - -/* These are the return codes for the seek callbacks */ -#define CURL_SEEKFUNC_OK 0 -#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ -#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking cannot be done, so - libcurl might try other means instead */ -typedef int (*curl_seek_callback)(void *instream, - curl_off_t offset, - int origin); /* 'whence' */ - -/* This is a return code for the read callback that, when returned, - signals libcurl to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -/* This is a return code for the read callback that, when returned, - signals libcurl to pause sending data on the current transfer. */ -#define CURL_READFUNC_PAUSE 0x10000001 - -/* Return code for when the trailing headers' callback has terminated - without any errors */ -#define CURL_TRAILERFUNC_OK 0 -/* Return code for when was an error in the trailing header's list and we - want to abort the request */ -#define CURL_TRAILERFUNC_ABORT 1 - -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - -typedef int (*curl_trailer_callback)(struct curl_slist **list, - void *userdata); - -typedef enum { - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ - CURLSOCKTYPE_LAST /* never use */ -} curlsocktype; - -/* The return code from the sockopt_callback can signal information back - to libcurl: */ -#define CURL_SOCKOPT_OK 0 -#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return - CURLE_ABORTED_BY_CALLBACK */ -#define CURL_SOCKOPT_ALREADY_CONNECTED 2 - -typedef int (*curl_sockopt_callback)(void *clientp, - curl_socket_t curlfd, - curlsocktype purpose); - -struct curl_sockaddr { - int family; - int socktype; - int protocol; - unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it - turned really ugly and painful on the systems that - lack this type */ - struct sockaddr addr; -}; - -typedef curl_socket_t -(*curl_opensocket_callback)(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *address); - -typedef int -(*curl_closesocket_callback)(void *clientp, curl_socket_t item); - -typedef enum { - CURLIOE_OK, /* I/O operation successful */ - CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ - CURLIOE_FAILRESTART, /* failed to restart the read */ - CURLIOE_LAST /* never use */ -} curlioerr; - -typedef enum { - CURLIOCMD_NOP, /* no operation */ - CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ - CURLIOCMD_LAST /* never use */ -} curliocmd; - -typedef curlioerr (*curl_ioctl_callback)(CURL *handle, - int cmd, - void *clientp); - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -#define CURL_DID_MEMORY_FUNC_TYPEDEFS -#endif - -/* the kind of data that is passed to information_callback */ -typedef enum { - CURLINFO_TEXT = 0, - CURLINFO_HEADER_IN, /* 1 */ - CURLINFO_HEADER_OUT, /* 2 */ - CURLINFO_DATA_IN, /* 3 */ - CURLINFO_DATA_OUT, /* 4 */ - CURLINFO_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - CURLINFO_END -} curl_infotype; - -typedef int (*curl_debug_callback) - (CURL *handle, /* the handle/transfer this concerns */ - curl_infotype type, /* what kind of data */ - char *data, /* points to the data */ - size_t size, /* size of the data pointed to */ - void *userptr); /* whatever the user please */ - -/* This is the CURLOPT_PREREQFUNCTION callback prototype. */ -typedef int (*curl_prereq_callback)(void *clientp, - char *conn_primary_ip, - char *conn_local_ip, - int conn_primary_port, - int conn_local_port); - -/* Return code for when the pre-request callback has terminated without - any errors */ -#define CURL_PREREQFUNC_OK 0 -/* Return code for when the pre-request callback wants to abort the - request */ -#define CURL_PREREQFUNC_ABORT 1 - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum { - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for - 7.17.0, reused in April 2011 for 7.21.5] */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server - due to lack of access - when login fails - this is not returned. */ - CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for - 7.15.4, reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server - [was obsoleted in August 2007 for 7.17.0, - reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. - [was obsoleted in August 2007 for 7.17.0, - reused in July 2014 for 7.38.0] */ - CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_OBSOLETE20, /* 20 - NOT USED */ - CURLE_QUOTE_ERROR, /* 21 - quote command failure */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_OBSOLETE24, /* 24 - NOT USED */ - CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ - CURLE_READ_ERROR, /* 26 - could not open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ - CURLE_OBSOLETE29, /* 29 - NOT USED */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_OBSOLETE32, /* 32 - NOT USED */ - CURLE_RANGE_ERROR, /* 33 - RANGE "command" did not work */ - CURLE_OBSOLETE34, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - could not resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_OBSOLETE41, /* 41 - NOT USED starting with 7.53.0 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_OBSOLETE44, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_SETOPT_OPTION_SYNTAX, /* 49 - Malformed setopt option */ - CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_OBSOLETE51, /* 51 - NOT USED */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_SEND_ERROR, /* 55 - failed sending network data */ - CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - CURLE_OBSOLETE57, /* 57 - NOT IN USE */ - CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ - CURLE_SSL_CIPHER, /* 59 - could not use specified cipher */ - CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint - was not verified fine */ - CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ - CURLE_OBSOLETE62, /* 62 - NOT IN USE since 7.82.0 */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind - that failed */ - CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ - CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not - accepted and we failed to login */ - CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ - CURLE_TFTP_PERM, /* 69 - permission problem on server */ - CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ - CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ - CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ - CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ - CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_OBSOLETE75, /* 75 - NOT IN USE since 7.82.0 */ - CURLE_OBSOLETE76, /* 76 - NOT IN USE since 7.82.0 */ - CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing - or wrong format */ - CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ - CURLE_SSH, /* 79 - error from the SSH layer, somewhat - generic so the error message is of - interest when this has happened */ - - CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL - connection */ - CURLE_AGAIN, /* 81 - socket is not ready for send/recv, - wait till it is ready and try again (Added - in 7.18.2) */ - CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or - wrong format (Added in 7.19.0) */ - CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in - 7.19.0) */ - CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ - CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ - CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ - CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ - CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ - CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the - session is queued */ - CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not - match */ - CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ - CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer - */ - CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from - inside a callback */ - CURLE_AUTH_ERROR, /* 94 - an authentication function returned an - error */ - CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */ - CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */ - CURLE_PROXY, /* 97 - proxy handshake error */ - CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */ - CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */ - CURLE_TOO_LARGE, /* 100 - a value/data met its maximum */ - CURLE_ECH_REQUIRED, /* 101 - ECH tried but failed */ - CURL_LAST /* never use! */ -} CURLcode; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* removed in 7.53.0 */ -#define CURLE_FUNCTION_NOT_FOUND CURLE_OBSOLETE41 - -/* removed in 7.56.0 */ -#define CURLE_HTTP_POST_ERROR CURLE_OBSOLETE34 - -/* Previously obsolete error code reused in 7.38.0 */ -#define CURLE_OBSOLETE16 CURLE_HTTP2 - -/* Previously obsolete error codes reused in 7.24.0 */ -#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED -#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT - -/* compatibility with older names */ -#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING -#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY - -/* The following were added in 7.62.0 */ -#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.21.5, April 2011 */ -#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION - -/* Added for 7.78.0 */ -#define CURLE_TELNET_OPTION_SYNTAX CURLE_SETOPT_OPTION_SYNTAX - -/* The following were added in 7.17.1 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.17.0 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ -#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 -#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 -#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 -#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 -#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 -#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 -#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 -#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 -#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 -#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 -#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 -#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN - -#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED -#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE -#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR -#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL -#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS -#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR -#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED - -/* The following were added earlier */ - -#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED -#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME -#define CURLE_LDAP_INVALID_URL CURLE_OBSOLETE62 -#define CURLE_CONV_REQD CURLE_OBSOLETE76 -#define CURLE_CONV_FAILED CURLE_OBSOLETE75 - -/* This was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -/* Provide defines for really old option names */ -#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ -#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ -#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA - -/* Since long deprecated options with no code in the lib that does anything - with them. */ -#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 -#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 -#define CURLOPT_OBSOLETE72 9999 -#define CURLOPT_OBSOLETE40 9999 - -#endif /* !CURL_NO_OLDIES */ - -/* - * Proxy error codes. Returned in CURLINFO_PROXY_ERROR if CURLE_PROXY was - * return for the transfers. - */ -typedef enum { - CURLPX_OK, - CURLPX_BAD_ADDRESS_TYPE, - CURLPX_BAD_VERSION, - CURLPX_CLOSED, - CURLPX_GSSAPI, - CURLPX_GSSAPI_PERMSG, - CURLPX_GSSAPI_PROTECTION, - CURLPX_IDENTD, - CURLPX_IDENTD_DIFFER, - CURLPX_LONG_HOSTNAME, - CURLPX_LONG_PASSWD, - CURLPX_LONG_USER, - CURLPX_NO_AUTH, - CURLPX_RECV_ADDRESS, - CURLPX_RECV_AUTH, - CURLPX_RECV_CONNECT, - CURLPX_RECV_REQACK, - CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED, - CURLPX_REPLY_COMMAND_NOT_SUPPORTED, - CURLPX_REPLY_CONNECTION_REFUSED, - CURLPX_REPLY_GENERAL_SERVER_FAILURE, - CURLPX_REPLY_HOST_UNREACHABLE, - CURLPX_REPLY_NETWORK_UNREACHABLE, - CURLPX_REPLY_NOT_ALLOWED, - CURLPX_REPLY_TTL_EXPIRED, - CURLPX_REPLY_UNASSIGNED, - CURLPX_REQUEST_FAILED, - CURLPX_RESOLVE_HOST, - CURLPX_SEND_AUTH, - CURLPX_SEND_CONNECT, - CURLPX_SEND_REQUEST, - CURLPX_UNKNOWN_FAIL, - CURLPX_UNKNOWN_MODE, - CURLPX_USER_REJECTED, - CURLPX_LAST /* never use */ -} CURLproxycode; - -/* This prototype applies to all conversion callbacks */ -typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an OpenSSL - or wolfSSL SSL_CTX, - or an mbedTLS - mbedtls_ssl_config */ - void *userptr); - -#define CURLPROXY_HTTP 0L /* added in 7.10, new in 7.19.4 default is - to use CONNECT HTTP/1.1 */ -#define CURLPROXY_HTTP_1_0 1L /* force to use CONNECT HTTP/1.0 - added in 7.19.4 */ -#define CURLPROXY_HTTPS 2L /* HTTPS but stick to HTTP/1 - added in 7.52.0 */ -#define CURLPROXY_HTTPS2 3L /* HTTPS and attempt HTTP/2 - added in 8.2.0 */ -#define CURLPROXY_SOCKS4 4L /* support added in 7.15.2, enum existed - already in 7.10 */ -#define CURLPROXY_SOCKS5 5L /* added in 7.10 */ -#define CURLPROXY_SOCKS4A 6L /* added in 7.18.0 */ -#define CURLPROXY_SOCKS5_HOSTNAME 7L /* Use the SOCKS5 protocol but pass along - the hostname rather than the IP - address. added in 7.18.0 */ - -typedef enum { - CURLPROXY_LAST = 8 /* never use */ -} curl_proxytype; /* this enum was added in 7.10 */ - -/* - * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: - * - * CURLAUTH_NONE - No HTTP authentication - * CURLAUTH_BASIC - HTTP Basic authentication (default) - * CURLAUTH_DIGEST - HTTP Digest authentication - * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication - * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) - * CURLAUTH_NTLM - HTTP NTLM authentication - * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour - * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper - * CURLAUTH_BEARER - HTTP Bearer token authentication - * CURLAUTH_ONLY - Use together with a single other type to force no - * authentication or that single type - * CURLAUTH_ANY - All fine types set - * CURLAUTH_ANYSAFE - All fine types except Basic - */ - -#define CURLAUTH_NONE ((unsigned long)0) -#define CURLAUTH_BASIC (((unsigned long)1) << 0) -#define CURLAUTH_DIGEST (((unsigned long)1) << 1) -#define CURLAUTH_NEGOTIATE (((unsigned long)1) << 2) -/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ -#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE -/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ -#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE -#define CURLAUTH_NTLM (((unsigned long)1) << 3) -#define CURLAUTH_DIGEST_IE (((unsigned long)1) << 4) -#ifndef CURL_NO_OLDIES - /* functionality removed since 8.8.0 */ -#define CURLAUTH_NTLM_WB (((unsigned long)1) << 5) -#endif -#define CURLAUTH_BEARER (((unsigned long)1) << 6) -#define CURLAUTH_AWS_SIGV4 (((unsigned long)1) << 7) -#define CURLAUTH_ONLY (((unsigned long)1) << 31) -#define CURLAUTH_ANY ((~CURLAUTH_DIGEST_IE) & \ - ((unsigned long)0xffffffff)) -#define CURLAUTH_ANYSAFE ((~(CURLAUTH_BASIC | CURLAUTH_DIGEST_IE)) & \ - ((unsigned long)0xffffffff)) - -/* all types supported by server */ -#define CURLSSH_AUTH_ANY ((unsigned long)0xffffffff) -#define CURLSSH_AUTH_NONE 0L /* none allowed, silly but complete */ -#define CURLSSH_AUTH_PUBLICKEY (1L << 0) /* public/private key files */ -#define CURLSSH_AUTH_PASSWORD (1L << 1) /* password */ -#define CURLSSH_AUTH_HOST (1L << 2) /* host key files */ -#define CURLSSH_AUTH_KEYBOARD (1L << 3) /* keyboard interactive */ -#define CURLSSH_AUTH_AGENT (1L << 4) /* agent (ssh-agent, pageant...) */ -#define CURLSSH_AUTH_GSSAPI (1L << 5) /* gssapi (kerberos, ...) */ -#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY - -#define CURLGSSAPI_DELEGATION_NONE 0L /* no delegation (default) */ -#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1L<<0) /* if permitted by policy */ -#define CURLGSSAPI_DELEGATION_FLAG (1L<<1) /* delegate always */ - -#define CURL_ERROR_SIZE 256 - -enum curl_khtype { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS, - CURLKHTYPE_ECDSA, - CURLKHTYPE_ED25519 -}; - -struct curl_khkey { - const char *key; /* points to a null-terminated string encoded with base64 - if len is zero, otherwise to the "raw" data */ - size_t len; - enum curl_khtype keytype; -}; - -/* this is the set of return values expected from the curl_sshkeycallback - callback */ -enum curl_khstat { - CURLKHSTAT_FINE_ADD_TO_FILE, - CURLKHSTAT_FINE, - CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we cannot answer right now. - Causes a CURLE_PEER_FAILED_VERIFICATION error but the - connection is left intact etc */ - CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key */ - CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ -}; - -/* this is the set of status codes pass in to the callback */ -enum curl_khmatch { - CURLKHMATCH_OK, /* match */ - CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ - CURLKHMATCH_MISSING, /* no matching host/key found */ - CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ -}; - -typedef int - (*curl_sshkeycallback) (CURL *easy, /* easy handle */ - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch, /* libcurl's view on the keys */ - void *clientp); /* custom pointer passed with */ - /* CURLOPT_SSH_KEYDATA */ - -typedef int - (*curl_sshhostkeycallback) (void *clientp,/* custom pointer passed */ - /* with CURLOPT_SSH_HOSTKEYDATA */ - int keytype, /* CURLKHTYPE */ - const char *key, /* hostkey to check */ - size_t keylen); /* length of the key */ - /* return CURLE_OK to accept */ - /* or something else to refuse */ - -/* parameter for the CURLOPT_USE_SSL option */ -#define CURLUSESSL_NONE 0L /* do not attempt to use SSL */ -#define CURLUSESSL_TRY 1L /* try using SSL, proceed anyway otherwise */ -#define CURLUSESSL_CONTROL 2L /* SSL for the control connection or fail */ -#define CURLUSESSL_ALL 3L /* SSL for all communication or fail */ - -typedef enum { - CURLUSESSL_LAST = 4 /* not an option, never use */ -} curl_usessl; - -/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ - -/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the - name of improving interoperability with older servers. Some SSL libraries - have introduced work-arounds for this flaw but those work-arounds sometimes - make the SSL communication fail. To regain functionality with those broken - servers, a user can this way allow the vulnerability back. */ -#define CURLSSLOPT_ALLOW_BEAST (1L << 0) - -/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those - SSL backends where such behavior is present. */ -#define CURLSSLOPT_NO_REVOKE (1L << 1) - -/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain - if possible. The OpenSSL backend has this ability. */ -#define CURLSSLOPT_NO_PARTIALCHAIN (1L << 2) - -/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline - checks and ignore missing revocation list for those SSL backends where such - behavior is present. */ -#define CURLSSLOPT_REVOKE_BEST_EFFORT (1L << 3) - -/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of - operating system. Currently implemented under MS-Windows. */ -#define CURLSSLOPT_NATIVE_CA (1L << 4) - -/* - CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl to automatically locate and use - a client certificate for authentication. (Schannel) */ -#define CURLSSLOPT_AUTO_CLIENT_CERT (1L << 5) - -/* If possible, send data using TLS 1.3 early data */ -#define CURLSSLOPT_EARLYDATA (1L << 6) - -/* The default connection attempt delay in milliseconds for happy eyeballs. - CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document - this value, keep them in sync. */ -#define CURL_HET_DEFAULT 200L - -/* The default connection upkeep interval in milliseconds. */ -#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2009 */ - -#define CURLFTPSSL_NONE CURLUSESSL_NONE -#define CURLFTPSSL_TRY CURLUSESSL_TRY -#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL -#define CURLFTPSSL_ALL CURLUSESSL_ALL -#define CURLFTPSSL_LAST CURLUSESSL_LAST -#define curl_ftpssl curl_usessl -#endif /* !CURL_NO_OLDIES */ - -/* parameter for the CURLOPT_FTP_SSL_CCC option */ -#define CURLFTPSSL_CCC_NONE 0L /* do not send CCC */ -#define CURLFTPSSL_CCC_PASSIVE 1L /* Let the server initiate the shutdown */ -#define CURLFTPSSL_CCC_ACTIVE 2L /* Initiate the shutdown */ - -typedef enum { - CURLFTPSSL_CCC_LAST = 3 /* not an option, never use */ -} curl_ftpccc; - -/* parameter for the CURLOPT_FTPSSLAUTH option */ -#define CURLFTPAUTH_DEFAULT 0L /* let libcurl decide */ -#define CURLFTPAUTH_SSL 1L /* use "AUTH SSL" */ -#define CURLFTPAUTH_TLS 2L /* use "AUTH TLS" */ - -typedef enum { - CURLFTPAUTH_LAST = 3 /* not an option, never use */ -} curl_ftpauth; - -/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ -#define CURLFTP_CREATE_DIR_NONE 0L /* do NOT create missing dirs! */ -#define CURLFTP_CREATE_DIR 1L /* (FTP/SFTP) if CWD fails, try MKD and - then CWD again if MKD succeeded, for - SFTP this does similar magic */ -#define CURLFTP_CREATE_DIR_RETRY 2L /* (FTP only) if CWD fails, try MKD and - then CWD again even if MKD failed! */ - -typedef enum { - CURLFTP_CREATE_DIR_LAST = 3 /* not an option, never use */ -} curl_ftpcreatedir; - -/* parameter for the CURLOPT_FTP_FILEMETHOD option */ -#define CURLFTPMETHOD_DEFAULT 0L /* let libcurl pick */ -#define CURLFTPMETHOD_MULTICWD 1L /* single CWD operation for each path - part */ -#define CURLFTPMETHOD_NOCWD 2L /* no CWD at all */ -#define CURLFTPMETHOD_SINGLECWD 3L /* one CWD to full dir, then work on file */ - -typedef enum { - CURLFTPMETHOD_LAST = 4 /* not an option, never use */ -} curl_ftpmethod; - -/* bitmask defines for CURLOPT_HEADEROPT */ -#define CURLHEADER_UNIFIED 0L -#define CURLHEADER_SEPARATE (1L << 0) - -/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */ -#define CURLALTSVC_READONLYFILE (1L << 2) -#define CURLALTSVC_H1 (1L << 3) -#define CURLALTSVC_H2 (1L << 4) -#define CURLALTSVC_H3 (1L << 5) - -/* bitmask values for CURLOPT_UPLOAD_FLAGS */ -#define CURLULFLAG_ANSWERED (1L << 0) -#define CURLULFLAG_DELETED (1L << 1) -#define CURLULFLAG_DRAFT (1L << 2) -#define CURLULFLAG_FLAGGED (1L << 3) -#define CURLULFLAG_SEEN (1L << 4) - -struct curl_hstsentry { - char *name; - size_t namelen; - unsigned int includeSubDomains:1; - char expire[18]; /* YYYYMMDD HH:MM:SS [null-terminated] */ -}; - -struct curl_index { - size_t index; /* the provided entry's "index" or count */ - size_t total; /* total number of entries to save */ -}; - -typedef enum { - CURLSTS_OK, - CURLSTS_DONE, - CURLSTS_FAIL -} CURLSTScode; - -typedef CURLSTScode (*curl_hstsread_callback)(CURL *easy, - struct curl_hstsentry *e, - void *userp); -typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy, - struct curl_hstsentry *e, - struct curl_index *i, - void *userp); - -/* CURLHSTS_* are bits for the CURLOPT_HSTS option */ -#define CURLHSTS_ENABLE (1L << 0) -#define CURLHSTS_READONLYFILE (1L << 1) - -/* The CURLPROTO_ defines below are for the **deprecated** CURLOPT_*PROTOCOLS - options. Do not use. */ -#define CURLPROTO_HTTP (1L << 0) -#define CURLPROTO_HTTPS (1L << 1) -#define CURLPROTO_FTP (1L << 2) -#define CURLPROTO_FTPS (1L << 3) -#define CURLPROTO_SCP (1L << 4) -#define CURLPROTO_SFTP (1L << 5) -#define CURLPROTO_TELNET (1L << 6) -#define CURLPROTO_LDAP (1L << 7) -#define CURLPROTO_LDAPS (1L << 8) -#define CURLPROTO_DICT (1L << 9) -#define CURLPROTO_FILE (1L << 10) -#define CURLPROTO_TFTP (1L << 11) -#define CURLPROTO_IMAP (1L << 12) -#define CURLPROTO_IMAPS (1L << 13) -#define CURLPROTO_POP3 (1L << 14) -#define CURLPROTO_POP3S (1L << 15) -#define CURLPROTO_SMTP (1L << 16) -#define CURLPROTO_SMTPS (1L << 17) -#define CURLPROTO_RTSP (1L << 18) -#define CURLPROTO_RTMP (1L << 19) -#define CURLPROTO_RTMPT (1L << 20) -#define CURLPROTO_RTMPE (1L << 21) -#define CURLPROTO_RTMPTE (1L << 22) -#define CURLPROTO_RTMPS (1L << 23) -#define CURLPROTO_RTMPTS (1L << 24) -#define CURLPROTO_GOPHER (1L << 25) -#define CURLPROTO_SMB (1L << 26) -#define CURLPROTO_SMBS (1L << 27) -#define CURLPROTO_MQTT (1L << 28) -#define CURLPROTO_GOPHERS (1L << 29) -#define CURLPROTO_ALL ((unsigned long)0xffffffff) /* old-style enable - "everything" */ - -/* long may be 32 or 64 bits, but we should never depend on anything else - but 32 */ -#define CURLOPTTYPE_LONG 0 -#define CURLOPTTYPE_OBJECTPOINT 10000 -#define CURLOPTTYPE_FUNCTIONPOINT 20000 -#define CURLOPTTYPE_OFF_T 30000 -#define CURLOPTTYPE_BLOB 40000 - -/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the - string options from the header file */ - -#define CURLOPT(na, t, nu) na = ((t) + (nu)) -#define CURLOPTDEPRECATED(na, t, nu, v, m) na CURL_DEPRECATED(v, m) \ - = ((t) + (nu)) - -/* CURLOPT aliases that make no runtime difference */ - -/* 'char *' argument to a string with a trailing zero */ -#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT - -/* 'struct curl_slist *' argument */ -#define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT - -/* 'void *' argument passed untouched to callback */ -#define CURLOPTTYPE_CBPOINT CURLOPTTYPE_OBJECTPOINT - -/* 'long' argument with a set of values/bitmask */ -#define CURLOPTTYPE_VALUES CURLOPTTYPE_LONG - -/* - * All CURLOPT_* values. - */ - -typedef enum { - /* This is the FILE * or void * the regular output should be written to. */ - CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_CBPOINT, 1), - - /* The full URL to get/put */ - CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2), - - /* Port number to connect to, if other than default. */ - CURLOPT(CURLOPT_PORT, CURLOPTTYPE_LONG, 3), - - /* Name of proxy to use. */ - CURLOPT(CURLOPT_PROXY, CURLOPTTYPE_STRINGPOINT, 4), - - /* "user:password;options" to use when fetching. */ - CURLOPT(CURLOPT_USERPWD, CURLOPTTYPE_STRINGPOINT, 5), - - /* "user:password" to use with proxy. */ - CURLOPT(CURLOPT_PROXYUSERPWD, CURLOPTTYPE_STRINGPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CURLOPT(CURLOPT_RANGE, CURLOPTTYPE_STRINGPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_CBPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. */ - CURLOPT(CURLOPT_ERRORBUFFER, CURLOPTTYPE_OBJECTPOINT, 10), - - /* Function that is called to store the output (instead of fwrite). The - * parameters use fwrite() syntax, make sure to follow them. */ - CURLOPT(CURLOPT_WRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 11), - - /* Function that is called to read the input (instead of fread). The - * parameters use fread() syntax, make sure to follow them. */ - CURLOPT(CURLOPT_READFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CURLOPT(CURLOPT_TIMEOUT, CURLOPTTYPE_LONG, 13), - - /* If CURLOPT_READDATA is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was successful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CURLOPT(CURLOPT_INFILESIZE, CURLOPTTYPE_LONG, 14), - - /* POST static input fields. */ - CURLOPT(CURLOPT_POSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 15), - - /* Set the referrer page (needed by some CGIs) */ - CURLOPT(CURLOPT_REFERER, CURLOPTTYPE_STRINGPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CURLOPT(CURLOPT_FTPPORT, CURLOPTTYPE_STRINGPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CURLOPT(CURLOPT_USERAGENT, CURLOPTTYPE_STRINGPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CURLOPT(CURLOPT_LOW_SPEED_LIMIT, CURLOPTTYPE_LONG, 19), - - /* Set the "low speed time" */ - CURLOPT(CURLOPT_LOW_SPEED_TIME, CURLOPTTYPE_LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CURLOPT(CURLOPT_RESUME_FROM, CURLOPTTYPE_LONG, 21), - - /* Set cookie in request: */ - CURLOPT(CURLOPT_COOKIE, CURLOPTTYPE_STRINGPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind. This - list is also used for RTSP (in spite of its name) */ - CURLOPT(CURLOPT_HTTPHEADER, CURLOPTTYPE_SLISTPOINT, 23), - - /* This points to a linked list of post entries, struct curl_httppost */ - CURLOPTDEPRECATED(CURLOPT_HTTPPOST, CURLOPTTYPE_OBJECTPOINT, 24, - 7.56.0, "Use CURLOPT_MIMEPOST"), - - /* name of the file keeping your private SSL-certificate */ - CURLOPT(CURLOPT_SSLCERT, CURLOPTTYPE_STRINGPOINT, 25), - - /* password for the SSL or SSH private key */ - CURLOPT(CURLOPT_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 26), - - /* send TYPE parameter? */ - CURLOPT(CURLOPT_CRLF, CURLOPTTYPE_LONG, 27), - - /* send linked-list of QUOTE commands */ - CURLOPT(CURLOPT_QUOTE, CURLOPTTYPE_SLISTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is passed to the callback unmodified */ - CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_CBPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CURLOPT(CURLOPT_COOKIEFILE, CURLOPTTYPE_STRINGPOINT, 31), - - /* What version to specifically try to use. - See CURL_SSLVERSION defines below. */ - CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_VALUES, 32), - - /* What kind of HTTP time condition to use, see defines */ - CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_VALUES, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CURLOPT(CURLOPT_TIMEVALUE, CURLOPTTYPE_LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CURLOPT(CURLOPT_CUSTOMREQUEST, CURLOPTTYPE_STRINGPOINT, 36), - - /* FILE handle to use instead of stderr */ - CURLOPT(CURLOPT_STDERR, CURLOPTTYPE_OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CURLOPT(CURLOPT_POSTQUOTE, CURLOPTTYPE_SLISTPOINT, 39), - - /* 40 is not used */ - - /* talk a lot */ - CURLOPT(CURLOPT_VERBOSE, CURLOPTTYPE_LONG, 41), - - /* throw the header out too */ - CURLOPT(CURLOPT_HEADER, CURLOPTTYPE_LONG, 42), - - /* shut off the progress meter */ - CURLOPT(CURLOPT_NOPROGRESS, CURLOPTTYPE_LONG, 43), - - /* use HEAD to get http document */ - CURLOPT(CURLOPT_NOBODY, CURLOPTTYPE_LONG, 44), - - /* no output on http error codes >= 400 */ - CURLOPT(CURLOPT_FAILONERROR, CURLOPTTYPE_LONG, 45), - - /* this is an upload */ - CURLOPT(CURLOPT_UPLOAD, CURLOPTTYPE_LONG, 46), - - /* HTTP POST method */ - CURLOPT(CURLOPT_POST, CURLOPTTYPE_LONG, 47), - - /* bare names when listing directories */ - CURLOPT(CURLOPT_DIRLISTONLY, CURLOPTTYPE_LONG, 48), - - /* Append instead of overwrite on upload! */ - CURLOPT(CURLOPT_APPEND, CURLOPTTYPE_LONG, 50), - - /* Specify whether to read the user+password from the .netrc or the URL. - * This must be one of the CURL_NETRC_* enums below. */ - CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_VALUES, 51), - - /* use Location: Luke! */ - CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52), - - /* transfer data in text/ASCII format */ - CURLOPT(CURLOPT_TRANSFERTEXT, CURLOPTTYPE_LONG, 53), - - /* HTTP PUT */ - CURLOPTDEPRECATED(CURLOPT_PUT, CURLOPTTYPE_LONG, 54, - 7.12.1, "Use CURLOPT_UPLOAD"), - - /* 55 = OBSOLETE */ - - /* DEPRECATED - * Function that is called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CURLOPTDEPRECATED(CURLOPT_PROGRESSFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 56, - 7.32.0, "Use CURLOPT_XFERINFOFUNCTION"), - - /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION - callbacks */ - CURLOPT(CURLOPT_XFERINFODATA, CURLOPTTYPE_CBPOINT, 57), -#define CURLOPT_PROGRESSDATA CURLOPT_XFERINFODATA - - /* We want the referrer field set automatically when following locations */ - CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CURLOPT(CURLOPT_PROXYPORT, CURLOPTTYPE_LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CURLOPT(CURLOPT_POSTFIELDSIZE, CURLOPTTYPE_LONG, 60), - - /* tunnel non-http operations through an HTTP proxy */ - CURLOPT(CURLOPT_HTTPPROXYTUNNEL, CURLOPTTYPE_LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CURLOPT(CURLOPT_INTERFACE, CURLOPTTYPE_STRINGPOINT, 62), - - /* Set the krb4/5 security level, this also enables krb4/5 awareness. This - * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string - * is set but does not match one of these, 'private' is used. */ - CURLOPTDEPRECATED(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63, - 8.17.0, "removed"), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_CAINFO, CURLOPTTYPE_STRINGPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CURLOPT(CURLOPT_MAXREDIRS, CURLOPTTYPE_LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CURLOPT(CURLOPT_FILETIME, CURLOPTTYPE_LONG, 69), - - /* This points to a linked list of telnet options */ - CURLOPT(CURLOPT_TELNETOPTIONS, CURLOPTTYPE_SLISTPOINT, 70), - - /* Max amount of cached alive connections */ - CURLOPT(CURLOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 71), - - /* 72 = OBSOLETE */ - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you are absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CURLOPT(CURLOPT_FRESH_CONNECT, CURLOPTTYPE_LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be reused - when done. Do not use this unless you are absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CURLOPT(CURLOPT_FORBID_REUSE, CURLOPTTYPE_LONG, 75), - - /* Set to a filename that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CURLOPTDEPRECATED(CURLOPT_RANDOM_FILE, CURLOPTTYPE_STRINGPOINT, 76, - 7.84.0, "Serves no purpose anymore"), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CURLOPTDEPRECATED(CURLOPT_EGDSOCKET, CURLOPTTYPE_STRINGPOINT, 77, - 7.84.0, "Serves no purpose anymore"), - - /* Time-out connect operations after this amount of seconds, if connects are - OK within this time, then fine... This only aborts the connect phase. */ - CURLOPT(CURLOPT_CONNECTTIMEOUT, CURLOPTTYPE_LONG, 78), - - /* Function that is called to store headers (instead of fwrite). The - * parameters use fwrite() syntax, make sure to follow them. */ - CURLOPT(CURLOPT_HEADERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CURLOPT(CURLOPT_HTTPGET, CURLOPTTYPE_LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CURLOPT(CURLOPT_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 81), - - /* Specify which filename to write all known cookies in after completed - operation. Set filename to "-" (dash) to make it go to stdout. */ - CURLOPT(CURLOPT_COOKIEJAR, CURLOPTTYPE_STRINGPOINT, 82), - - /* Specify which TLS 1.2 (1.1, 1.0) ciphers to use */ - CURLOPT(CURLOPT_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_VALUES, 84), - - /* Specifically switch on or off the FTP engine's use of the EPSV command. By - default, that one is always attempted before the more traditional - PASV command. */ - CURLOPT(CURLOPT_FTP_USE_EPSV, CURLOPTTYPE_LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CURLOPT(CURLOPT_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CURLOPT(CURLOPT_SSLKEY, CURLOPTTYPE_STRINGPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CURLOPT(CURLOPT_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CURLOPT(CURLOPT_SSLENGINE, CURLOPTTYPE_STRINGPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CURLOPT(CURLOPT_SSLENGINE_DEFAULT, CURLOPTTYPE_LONG, 90), - - /* Non-zero value means to use the global dns cache */ - /* DEPRECATED, do not use! */ - CURLOPTDEPRECATED(CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPTTYPE_LONG, 91, - 7.11.1, "Use CURLOPT_SHARE"), - - /* DNS cache timeout */ - CURLOPT(CURLOPT_DNS_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands */ - CURLOPT(CURLOPT_PREQUOTE, CURLOPTTYPE_SLISTPOINT, 93), - - /* set the debug function */ - CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_CBPOINT, 95), - - /* mark this as start of a cookie session */ - CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_CAPATH, CURLOPTTYPE_STRINGPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CURLOPT(CURLOPT_BUFFERSIZE, CURLOPTTYPE_LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CURLOPT(CURLOPT_NOSIGNAL, CURLOPTTYPE_LONG, 99), - - /* Provide a CURLShare for mutexing non-ts data */ - CURLOPT(CURLOPT_SHARE, CURLOPTTYPE_OBJECTPOINT, 100), - - /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and - CURLPROXY_SOCKS5. */ - CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_VALUES, 101), - - /* Set the Accept-Encoding string. Use this to tell a server you would like - the response to be compressed. Before 7.21.6, this was known as - CURLOPT_ENCODING */ - CURLOPT(CURLOPT_ACCEPT_ENCODING, CURLOPTTYPE_STRINGPOINT, 102), - - /* Set pointer to private data */ - CURLOPT(CURLOPT_PRIVATE, CURLOPTTYPE_OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CURLOPT(CURLOPT_HTTP200ALIASES, CURLOPTTYPE_SLISTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentially send off the name - and password to whatever host the server decides. */ - CURLOPT(CURLOPT_UNRESTRICTED_AUTH, CURLOPTTYPE_LONG, 105), - - /* Specifically switch on or off the FTP engine's use of the EPRT command ( - it also disables the LPRT attempt). By default, those ones are always - attempted before the good old traditional PORT command. */ - CURLOPT(CURLOPT_FTP_USE_EPRT, CURLOPTTYPE_LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_VALUES, 107), - - /* Set the ssl context callback function, currently only for OpenSSL or - wolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument. - The function must match the curl_ssl_ctx_callback prototype. */ - CURLOPT(CURLOPT_SSL_CTX_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_CBPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server. - In 7.19.4 we introduced the convenience enums for this option using the - CURLFTP_CREATE_DIR prefix. - */ - CURLOPT(CURLOPT_FTP_CREATE_MISSING_DIRS, CURLOPTTYPE_LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111), - - /* Option that changes the timeout, in seconds, associated with getting a - response. This is different from transfer timeout time and essentially - places a demand on the server to acknowledge commands in a timely - manner. For FTP, SMTP, IMAP and POP3. */ - CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112), - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to use those IP versions only. This only has effect on - systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113), - - /* Set this option to limit the size of a file that is to be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CURLOPT(CURLOPT_MAXFILESIZE, CURLOPTTYPE_LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CURLOPT(CURLOPT_INFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 115), - - /* Sets the continuation offset. There is also a CURLOPTTYPE_LONG version - * of this; look above for RESUME_FROM. - */ - CURLOPT(CURLOPT_RESUME_FROM_LARGE, CURLOPTTYPE_OFF_T, 116), - - /* Sets the maximum size of data that is to be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CURLOPT(CURLOPT_MAXFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 117), - - /* Set this option to the filename of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl does - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CURLOPT(CURLOPT_NETRC_FILE, CURLOPTTYPE_STRINGPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLUSESSL_TRY - try using SSL, proceed anyway otherwise - CURLUSESSL_CONTROL - SSL for the control connection or fail - CURLUSESSL_ALL - SSL for all communication or fail - */ - CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CURLOPT(CURLOPT_TCP_NODELAY, CURLOPTTYPE_LONG, 121), - - /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 123 OBSOLETE. Gone in 7.16.0 */ - /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 127 OBSOLETE. Gone in 7.16.0 */ - /* 128 OBSOLETE. Gone in 7.16.0 */ - - /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option - can be used to change libcurl's default action which is to first try - "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK - response has been received. - - Available parameters are: - CURLFTPAUTH_DEFAULT - let libcurl decide - CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS - CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL - */ - CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_VALUES, 129), - - CURLOPTDEPRECATED(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130, - 7.18.0, "Use CURLOPT_SEEKFUNCTION"), - CURLOPTDEPRECATED(CURLOPT_IOCTLDATA, CURLOPTTYPE_CBPOINT, 131, - 7.18.0, "Use CURLOPT_SEEKDATA"), - - /* 132 OBSOLETE. Gone in 7.16.0 */ - /* 133 OBSOLETE. Gone in 7.16.0 */ - - /* null-terminated string for pass on to the FTP server when asked for - "account" info */ - CURLOPT(CURLOPT_FTP_ACCOUNT, CURLOPTTYPE_STRINGPOINT, 134), - - /* feed cookie into cookie engine */ - CURLOPT(CURLOPT_COOKIELIST, CURLOPTTYPE_STRINGPOINT, 135), - - /* ignore Content-Length */ - CURLOPT(CURLOPT_IGNORE_CONTENT_LENGTH, CURLOPTTYPE_LONG, 136), - - /* Set to non-zero to skip the IP address received in a 227 PASV FTP server - response. Typically used for FTP-SSL purposes but is not restricted to - that. libcurl is then instead using the same IP address it used for the - control connection. */ - CURLOPT(CURLOPT_FTP_SKIP_PASV_IP, CURLOPTTYPE_LONG, 137), - - /* Select "file method" to use when doing FTP, see the curl_ftpmethod - above. */ - CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_VALUES, 138), - - /* Local port number to bind the socket to */ - CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139), - - /* Number of ports to try, including the first one set with LOCALPORT. - Thus, setting it to 1 makes no additional attempts but the first. - */ - CURLOPT(CURLOPT_LOCALPORTRANGE, CURLOPTTYPE_LONG, 140), - - /* no transfer, set up connection and let application use the socket by - extracting it with CURLINFO_LASTSOCKET */ - CURLOPT(CURLOPT_CONNECT_ONLY, CURLOPTTYPE_LONG, 141), - - /* Function that is called to convert from the - network encoding (instead of using the iconv calls in libcurl) */ - CURLOPTDEPRECATED(CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOPTTYPE_FUNCTIONPOINT, 142, - 7.82.0, "Serves no purpose anymore"), - - /* Function that is called to convert to the - network encoding (instead of using the iconv calls in libcurl) */ - CURLOPTDEPRECATED(CURLOPT_CONV_TO_NETWORK_FUNCTION, - CURLOPTTYPE_FUNCTIONPOINT, 143, - 7.82.0, "Serves no purpose anymore"), - - /* Function that is called to convert from UTF8 - (instead of using the iconv calls in libcurl) - Note that this is used only for SSL certificate processing */ - CURLOPTDEPRECATED(CURLOPT_CONV_FROM_UTF8_FUNCTION, - CURLOPTTYPE_FUNCTIONPOINT, 144, - 7.82.0, "Serves no purpose anymore"), - - /* if the connection proceeds too quickly then need to slow it down */ - /* limit-rate: maximum number of bytes per second to send or receive */ - CURLOPT(CURLOPT_MAX_SEND_SPEED_LARGE, CURLOPTTYPE_OFF_T, 145), - CURLOPT(CURLOPT_MAX_RECV_SPEED_LARGE, CURLOPTTYPE_OFF_T, 146), - - /* Pointer to command string to send if USER/PASS fails. */ - CURLOPT(CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPTTYPE_STRINGPOINT, 147), - - /* callback function for setting socket options */ - CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148), - CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_CBPOINT, 149), - - /* set to 0 to disable session ID reuse for this transfer, default is - enabled (== 1) */ - CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150), - - /* allowed SSH authentication methods */ - CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_VALUES, 151), - - /* Used by scp/sftp to do public/private key authentication */ - CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152), - CURLOPT(CURLOPT_SSH_PRIVATE_KEYFILE, CURLOPTTYPE_STRINGPOINT, 153), - - /* Send CCC (Clear Command Channel) after authentication */ - CURLOPT(CURLOPT_FTP_SSL_CCC, CURLOPTTYPE_LONG, 154), - - /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CURLOPT(CURLOPT_TIMEOUT_MS, CURLOPTTYPE_LONG, 155), - CURLOPT(CURLOPT_CONNECTTIMEOUT_MS, CURLOPTTYPE_LONG, 156), - - /* set to zero to disable the libcurl's decoding and thus pass the raw body - data to the application even when it is encoded/compressed */ - CURLOPT(CURLOPT_HTTP_TRANSFER_DECODING, CURLOPTTYPE_LONG, 157), - CURLOPT(CURLOPT_HTTP_CONTENT_DECODING, CURLOPTTYPE_LONG, 158), - - /* Permission used when creating new files and directories on the remote - server for protocols that support it, SFTP/SCP/FILE */ - CURLOPT(CURLOPT_NEW_FILE_PERMS, CURLOPTTYPE_LONG, 159), - CURLOPT(CURLOPT_NEW_DIRECTORY_PERMS, CURLOPTTYPE_LONG, 160), - - /* Set the behavior of POST when redirecting. Values must be set to one - of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_VALUES, 161), - - /* used by scp/sftp to verify the host's public key */ - CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162), - - /* Callback function for opening socket (instead of socket(2)). Optionally, - callback is able change the address or refuse to connect returning - CURL_SOCKET_BAD. The callback should have type - curl_opensocket_callback */ - CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163), - CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_CBPOINT, 164), - - /* POST volatile input fields. */ - CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165), - - /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CURLOPT(CURLOPT_PROXY_TRANSFER_MODE, CURLOPTTYPE_LONG, 166), - - /* Callback function for seeking in the input stream */ - CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167), - CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_CBPOINT, 168), - - /* CRL file */ - CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169), - - /* Issuer certificate */ - CURLOPT(CURLOPT_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 170), - - /* (IPv6) Address scope */ - CURLOPT(CURLOPT_ADDRESS_SCOPE, CURLOPTTYPE_LONG, 171), - - /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. */ - CURLOPT(CURLOPT_CERTINFO, CURLOPTTYPE_LONG, 172), - - /* "name" and "pwd" to use when fetching. */ - CURLOPT(CURLOPT_USERNAME, CURLOPTTYPE_STRINGPOINT, 173), - CURLOPT(CURLOPT_PASSWORD, CURLOPTTYPE_STRINGPOINT, 174), - - /* "name" and "pwd" to use with Proxy when fetching. */ - CURLOPT(CURLOPT_PROXYUSERNAME, CURLOPTTYPE_STRINGPOINT, 175), - CURLOPT(CURLOPT_PROXYPASSWORD, CURLOPTTYPE_STRINGPOINT, 176), - - /* Comma separated list of hostnames defining no-proxy zones. These should - match both hostnames directly, and hostnames within a domain. For - example, local.com matches local.com and www.local.com, but NOT - notlocal.com or www.notlocal.com. For compatibility with other - implementations of this, .local.com is considered to be the same as - local.com. A single * is the only valid wildcard, and effectively - disables the use of proxy. */ - CURLOPT(CURLOPT_NOPROXY, CURLOPTTYPE_STRINGPOINT, 177), - - /* block size for TFTP transfers */ - CURLOPT(CURLOPT_TFTP_BLKSIZE, CURLOPTTYPE_LONG, 178), - - /* Socks Service */ - /* DEPRECATED, do not use! */ - CURLOPTDEPRECATED(CURLOPT_SOCKS5_GSSAPI_SERVICE, - CURLOPTTYPE_STRINGPOINT, 179, - 7.49.0, "Use CURLOPT_PROXY_SERVICE_NAME"), - - /* Socks Service */ - CURLOPT(CURLOPT_SOCKS5_GSSAPI_NEC, CURLOPTTYPE_LONG, 180), - - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - CURLOPTDEPRECATED(CURLOPT_PROTOCOLS, CURLOPTTYPE_LONG, 181, - 7.85.0, "Use CURLOPT_PROTOCOLS_STR"), - - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. */ - CURLOPTDEPRECATED(CURLOPT_REDIR_PROTOCOLS, CURLOPTTYPE_LONG, 182, - 7.85.0, "Use CURLOPT_REDIR_PROTOCOLS_STR"), - - /* set the SSH knownhost filename to use */ - CURLOPT(CURLOPT_SSH_KNOWNHOSTS, CURLOPTTYPE_STRINGPOINT, 183), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184), - - /* set the SSH host key callback custom pointer */ - CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_CBPOINT, 185), - - /* set the SMTP mail originator */ - CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186), - - /* set the list of SMTP mail receiver(s) */ - CURLOPT(CURLOPT_MAIL_RCPT, CURLOPTTYPE_SLISTPOINT, 187), - - /* FTP: send PRET before PASV */ - CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188), - - /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_VALUES, 189), - - /* The RTSP session identifier */ - CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190), - - /* The RTSP stream URI */ - CURLOPT(CURLOPT_RTSP_STREAM_URI, CURLOPTTYPE_STRINGPOINT, 191), - - /* The Transport: header to use in RTSP requests */ - CURLOPT(CURLOPT_RTSP_TRANSPORT, CURLOPTTYPE_STRINGPOINT, 192), - - /* Manually initialize the client RTSP CSeq for this handle */ - CURLOPT(CURLOPT_RTSP_CLIENT_CSEQ, CURLOPTTYPE_LONG, 193), - - /* Manually initialize the server RTSP CSeq for this handle */ - CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194), - - /* The stream to pass to INTERLEAVEFUNCTION. */ - CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_CBPOINT, 195), - - /* Let the application define a custom write method for RTP data */ - CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196), - - /* Turn on wildcard matching */ - CURLOPT(CURLOPT_WILDCARDMATCH, CURLOPTTYPE_LONG, 197), - - /* Directory matching callback called before downloading of an - individual file (chunk) started */ - CURLOPT(CURLOPT_CHUNK_BGN_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 198), - - /* Directory matching callback called after the file (chunk) - was downloaded, or skipped */ - CURLOPT(CURLOPT_CHUNK_END_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 199), - - /* Change match (fnmatch-like) callback for wildcard matching */ - CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200), - - /* Let the application define custom chunk data pointer */ - CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_CBPOINT, 201), - - /* FNMATCH_FUNCTION user pointer */ - CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_CBPOINT, 202), - - /* send linked-list of name:port:address sets */ - CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203), - - /* Set a username for authenticated TLS */ - CURLOPT(CURLOPT_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 204), - - /* Set a password for authenticated TLS */ - CURLOPT(CURLOPT_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 205), - - /* Set authentication type for authenticated TLS */ - CURLOPT(CURLOPT_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 206), - - /* Set to 1 to enable the "TE:" header in HTTP requests to ask for - compressed transfer-encoded responses. Set to 0 to disable the use of TE: - in outgoing requests. The current default is 0, but it might change in a - future libcurl release. - - libcurl asks for the compressed methods it knows of, and if that - is not any, it does not ask for transfer-encoding at all even if this - option is set to 1. */ - CURLOPT(CURLOPT_TRANSFER_ENCODING, CURLOPTTYPE_LONG, 207), - - /* Callback function for closing socket (instead of close(2)). The callback - should have type curl_closesocket_callback */ - CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208), - CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_CBPOINT, 209), - - /* allow GSSAPI credential delegation */ - CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_VALUES, 210), - - /* Set the name servers to use for DNS resolution. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211), - - /* Time-out accept operations (currently for FTP only) after this amount - of milliseconds. */ - CURLOPT(CURLOPT_ACCEPTTIMEOUT_MS, CURLOPTTYPE_LONG, 212), - - /* Set TCP keepalive */ - CURLOPT(CURLOPT_TCP_KEEPALIVE, CURLOPTTYPE_LONG, 213), - - /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ - CURLOPT(CURLOPT_TCP_KEEPIDLE, CURLOPTTYPE_LONG, 214), - CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215), - - /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ - CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_VALUES, 216), - - /* Set the SMTP auth originator */ - CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217), - - /* Enable/disable SASL initial response */ - CURLOPT(CURLOPT_SASL_IR, CURLOPTTYPE_LONG, 218), - - /* Function that is called instead of the internal progress display - * function. This function should be defined as the curl_xferinfo_callback - * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ - CURLOPT(CURLOPT_XFERINFOFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 219), - - /* The XOAUTH2 bearer token */ - CURLOPT(CURLOPT_XOAUTH2_BEARER, CURLOPTTYPE_STRINGPOINT, 220), - - /* Set the interface string to use as outgoing network - * interface for DNS requests. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_INTERFACE, CURLOPTTYPE_STRINGPOINT, 221), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_LOCAL_IP4, CURLOPTTYPE_STRINGPOINT, 222), - - /* Set the local IPv6 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CURLOPT(CURLOPT_DNS_LOCAL_IP6, CURLOPTTYPE_STRINGPOINT, 223), - - /* Set authentication options directly */ - CURLOPT(CURLOPT_LOGIN_OPTIONS, CURLOPTTYPE_STRINGPOINT, 224), - - /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ - CURLOPTDEPRECATED(CURLOPT_SSL_ENABLE_NPN, CURLOPTTYPE_LONG, 225, - 7.86.0, "Has no function"), - - /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ - CURLOPT(CURLOPT_SSL_ENABLE_ALPN, CURLOPTTYPE_LONG, 226), - - /* Time to wait for a response to an HTTP request containing an - * Expect: 100-continue header before sending the data anyway. */ - CURLOPT(CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOPTTYPE_LONG, 227), - - /* This points to a linked list of headers used for proxy requests only, - struct curl_slist kind */ - CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228), - - /* Pass in a bitmask of "header options" */ - CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229), - - /* The public key used to validate the peer public key */ - CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230), - - /* Path to Unix domain socket */ - CURLOPT(CURLOPT_UNIX_SOCKET_PATH, CURLOPTTYPE_STRINGPOINT, 231), - - /* Set if we should verify the certificate status. */ - CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232), - - /* Set if we should enable TLS false start. */ - CURLOPTDEPRECATED(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233, - 8.15.0, "Has no function"), - - /* Do not squash dot-dot sequences */ - CURLOPT(CURLOPT_PATH_AS_IS, CURLOPTTYPE_LONG, 234), - - /* Proxy Service Name */ - CURLOPT(CURLOPT_PROXY_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 235), - - /* Service Name */ - CURLOPT(CURLOPT_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 236), - - /* Wait/do not wait for pipe/mutex to clarify */ - CURLOPT(CURLOPT_PIPEWAIT, CURLOPTTYPE_LONG, 237), - - /* Set the protocol used when curl is given a URL without a protocol */ - CURLOPT(CURLOPT_DEFAULT_PROTOCOL, CURLOPTTYPE_STRINGPOINT, 238), - - /* Set stream weight, 1 - 256 (default is 16) */ - CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239), - - /* Set stream dependency on another curl handle */ - CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240), - - /* Set E-xclusive stream dependency on another curl handle */ - CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241), - - /* Do not send any tftp option requests to the server */ - CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242), - - /* Linked-list of host:port:connect-to-host:connect-to-port, - overrides the URL's host:port (only for the network layer) */ - CURLOPT(CURLOPT_CONNECT_TO, CURLOPTTYPE_SLISTPOINT, 243), - - /* Set TCP Fast Open */ - CURLOPT(CURLOPT_TCP_FASTOPEN, CURLOPTTYPE_LONG, 244), - - /* Continue to send data if the server responds early with an - * HTTP status code >= 300 */ - CURLOPT(CURLOPT_KEEP_SENDING_ON_ERROR, CURLOPTTYPE_LONG, 245), - - /* The CApath or CAfile used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_CAINFO, CURLOPTTYPE_STRINGPOINT, 246), - - /* The CApath directory used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_CAPATH, CURLOPTTYPE_STRINGPOINT, 247), - - /* Set if we should verify the proxy in ssl handshake, - set 1 to verify. */ - CURLOPT(CURLOPT_PROXY_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 248), - - /* Set if we should verify the Common name from the proxy certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches - * the provided hostname. */ - CURLOPT(CURLOPT_PROXY_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 249), - - /* What version to specifically try to use for proxy. - See CURL_SSLVERSION defines below. */ - CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_VALUES, 250), - - /* Set a username for authenticated TLS for proxy */ - CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251), - - /* Set a password for authenticated TLS for proxy */ - CURLOPT(CURLOPT_PROXY_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 252), - - /* Set authentication type for authenticated TLS for proxy */ - CURLOPT(CURLOPT_PROXY_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 253), - - /* name of the file keeping your private SSL-certificate for proxy */ - CURLOPT(CURLOPT_PROXY_SSLCERT, CURLOPTTYPE_STRINGPOINT, 254), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for - proxy */ - CURLOPT(CURLOPT_PROXY_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 255), - - /* name of the file keeping your private SSL-key for proxy */ - CURLOPT(CURLOPT_PROXY_SSLKEY, CURLOPTTYPE_STRINGPOINT, 256), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for - proxy */ - CURLOPT(CURLOPT_PROXY_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 257), - - /* password for the SSL private key for proxy */ - CURLOPT(CURLOPT_PROXY_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 258), - - /* Specify which TLS 1.2 (1.1, 1.0) ciphers to use for proxy */ - CURLOPT(CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 259), - - /* CRL file for proxy */ - CURLOPT(CURLOPT_PROXY_CRLFILE, CURLOPTTYPE_STRINGPOINT, 260), - - /* Enable/disable specific SSL features with a bitmask for proxy, see - CURLSSLOPT_* */ - CURLOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLOPTTYPE_LONG, 261), - - /* Name of pre proxy to use. */ - CURLOPT(CURLOPT_PRE_PROXY, CURLOPTTYPE_STRINGPOINT, 262), - - /* The public key in DER form used to validate the proxy public key - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 263), - - /* Path to an abstract Unix domain socket */ - CURLOPT(CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOPTTYPE_STRINGPOINT, 264), - - /* Suppress proxy CONNECT response headers from user callbacks */ - CURLOPT(CURLOPT_SUPPRESS_CONNECT_HEADERS, CURLOPTTYPE_LONG, 265), - - /* The request target, instead of extracted from the URL */ - CURLOPT(CURLOPT_REQUEST_TARGET, CURLOPTTYPE_STRINGPOINT, 266), - - /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ - CURLOPT(CURLOPT_SOCKS5_AUTH, CURLOPTTYPE_LONG, 267), - - /* Enable/disable SSH compression */ - CURLOPT(CURLOPT_SSH_COMPRESSION, CURLOPTTYPE_LONG, 268), - - /* Post MIME data. */ - CURLOPT(CURLOPT_MIMEPOST, CURLOPTTYPE_OBJECTPOINT, 269), - - /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of - seconds since 1 Jan 1970. */ - CURLOPT(CURLOPT_TIMEVALUE_LARGE, CURLOPTTYPE_OFF_T, 270), - - /* Head start in milliseconds to give happy eyeballs. */ - CURLOPT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, CURLOPTTYPE_LONG, 271), - - /* Function that is called before a resolver request is made */ - CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272), - - /* User data to pass to the resolver start callback. */ - CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_CBPOINT, 273), - - /* send HAProxy PROXY protocol header? */ - CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274), - - /* shuffle addresses before use when DNS returns multiple */ - CURLOPT(CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOPTTYPE_LONG, 275), - - /* Specify which TLS 1.3 ciphers suites to use */ - CURLOPT(CURLOPT_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 276), - CURLOPT(CURLOPT_PROXY_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 277), - - /* Disallow specifying username/login in URL. */ - CURLOPT(CURLOPT_DISALLOW_USERNAME_IN_URL, CURLOPTTYPE_LONG, 278), - - /* DNS-over-HTTPS URL */ - CURLOPT(CURLOPT_DOH_URL, CURLOPTTYPE_STRINGPOINT, 279), - - /* Preferred buffer size to use for uploads */ - CURLOPT(CURLOPT_UPLOAD_BUFFERSIZE, CURLOPTTYPE_LONG, 280), - - /* Time in ms between connection upkeep calls for long-lived connections. */ - CURLOPT(CURLOPT_UPKEEP_INTERVAL_MS, CURLOPTTYPE_LONG, 281), - - /* Specify URL using CURL URL API. */ - CURLOPT(CURLOPT_CURLU, CURLOPTTYPE_OBJECTPOINT, 282), - - /* add trailing data after no more data is available */ - CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283), - - /* pointer to be passed to HTTP_TRAILER_FUNCTION */ - CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_CBPOINT, 284), - - /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */ - CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285), - - /* alt-svc control bitmask */ - CURLOPT(CURLOPT_ALTSVC_CTRL, CURLOPTTYPE_LONG, 286), - - /* alt-svc cache filename to possibly read from/write to */ - CURLOPT(CURLOPT_ALTSVC, CURLOPTTYPE_STRINGPOINT, 287), - - /* maximum age (idle time) of a connection to consider it for reuse - * (in seconds) */ - CURLOPT(CURLOPT_MAXAGE_CONN, CURLOPTTYPE_LONG, 288), - - /* SASL authorization identity */ - CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289), - - /* allow RCPT TO command to fail for some recipients */ - CURLOPT(CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOPTTYPE_LONG, 290), - - /* the private SSL-certificate as a "blob" */ - CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291), - CURLOPT(CURLOPT_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 292), - CURLOPT(CURLOPT_PROXY_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 293), - CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294), - CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295), - - /* Issuer certificate for proxy */ - CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296), - CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297), - - /* the EC curves requested by the TLS client (RFC 8422, 5.1); - * OpenSSL support via 'set_groups'/'set_curves': - * https://docs.openssl.org/master/man3/SSL_CTX_set1_curves/ - */ - CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298), - - /* HSTS bitmask */ - CURLOPT(CURLOPT_HSTS_CTRL, CURLOPTTYPE_LONG, 299), - /* HSTS filename */ - CURLOPT(CURLOPT_HSTS, CURLOPTTYPE_STRINGPOINT, 300), - - /* HSTS read callback */ - CURLOPT(CURLOPT_HSTSREADFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 301), - CURLOPT(CURLOPT_HSTSREADDATA, CURLOPTTYPE_CBPOINT, 302), - - /* HSTS write callback */ - CURLOPT(CURLOPT_HSTSWRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 303), - CURLOPT(CURLOPT_HSTSWRITEDATA, CURLOPTTYPE_CBPOINT, 304), - - /* Parameters for V4 signature */ - CURLOPT(CURLOPT_AWS_SIGV4, CURLOPTTYPE_STRINGPOINT, 305), - - /* Same as CURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. */ - CURLOPT(CURLOPT_DOH_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 306), - - /* Same as CURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. */ - CURLOPT(CURLOPT_DOH_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 307), - - /* Same as CURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. */ - CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308), - - /* The CA certificates as "blob" used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_CAINFO_BLOB, CURLOPTTYPE_BLOB, 309), - - /* The CA certificates as "blob" used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CURLOPT(CURLOPT_PROXY_CAINFO_BLOB, CURLOPTTYPE_BLOB, 310), - - /* used by scp/sftp to verify the host's public key */ - CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, CURLOPTTYPE_STRINGPOINT, 311), - - /* Function that is called immediately before the initial request - is made on a connection (after any protocol negotiation step). */ - CURLOPT(CURLOPT_PREREQFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 312), - - /* Data passed to the CURLOPT_PREREQFUNCTION callback */ - CURLOPT(CURLOPT_PREREQDATA, CURLOPTTYPE_CBPOINT, 313), - - /* maximum age (since creation) of a connection to consider it for reuse - * (in seconds) */ - CURLOPT(CURLOPT_MAXLIFETIME_CONN, CURLOPTTYPE_LONG, 314), - - /* Set MIME option flags. */ - CURLOPT(CURLOPT_MIME_OPTIONS, CURLOPTTYPE_LONG, 315), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CURLOPT(CURLOPT_SSH_HOSTKEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 316), - - /* set the SSH host key callback custom pointer */ - CURLOPT(CURLOPT_SSH_HOSTKEYDATA, CURLOPTTYPE_CBPOINT, 317), - - /* specify which protocols that are allowed to be used for the transfer, - which thus helps the app which takes URLs from users or other external - inputs and want to restrict what protocol(s) to deal with. Defaults to - all built-in protocols. */ - CURLOPT(CURLOPT_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 318), - - /* specify which protocols that libcurl is allowed to follow directs to */ - CURLOPT(CURLOPT_REDIR_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 319), - - /* WebSockets options */ - CURLOPT(CURLOPT_WS_OPTIONS, CURLOPTTYPE_LONG, 320), - - /* CA cache timeout */ - CURLOPT(CURLOPT_CA_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 321), - - /* Can leak things, gonna exit() soon */ - CURLOPT(CURLOPT_QUICK_EXIT, CURLOPTTYPE_LONG, 322), - - /* set a specific client IP for HAProxy PROXY protocol header? */ - CURLOPT(CURLOPT_HAPROXY_CLIENT_IP, CURLOPTTYPE_STRINGPOINT, 323), - - /* millisecond version */ - CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT_MS, CURLOPTTYPE_LONG, 324), - - /* set ECH configuration */ - CURLOPT(CURLOPT_ECH, CURLOPTTYPE_STRINGPOINT, 325), - - /* maximum number of keepalive probes (Linux, *BSD, macOS, etc.) */ - CURLOPT(CURLOPT_TCP_KEEPCNT, CURLOPTTYPE_LONG, 326), - - CURLOPT(CURLOPT_UPLOAD_FLAGS, CURLOPTTYPE_LONG, 327), - - /* set TLS supported signature algorithms */ - CURLOPT(CURLOPT_SSL_SIGNATURE_ALGORITHMS, CURLOPTTYPE_STRINGPOINT, 328), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2011 */ - -/* This was added in version 7.19.1 */ -#define CURLOPT_POST301 CURLOPT_POSTREDIR - -/* These are scheduled to disappear by 2009 */ - -/* The following were added in 7.17.0 */ -#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_FTPAPPEND CURLOPT_APPEND -#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY -#define CURLOPT_FTP_SSL CURLOPT_USE_SSL - -/* The following were added earlier */ - -#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL - -#define CURLOPT_FTP_RESPONSE_TIMEOUT CURLOPT_SERVER_RESPONSE_TIMEOUT - -/* Added in 8.2.0 */ -#define CURLOPT_MAIL_RCPT_ALLLOWFAILS CURLOPT_MAIL_RCPT_ALLOWFAILS - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - -/* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0L /* default, uses addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1L /* uses only IPv4 addresses/connections */ -#define CURL_IPRESOLVE_V6 2L /* uses only IPv6 addresses/connections */ - - /* Convenient "aliases" */ -#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER - -/* These constants are for use with the CURLOPT_HTTP_VERSION option. */ -#define CURL_HTTP_VERSION_NONE 0L /* setting this means we do not care, and - that we would like the library to choose - the best possible for us! */ -#define CURL_HTTP_VERSION_1_0 1L /* please use HTTP 1.0 in the request */ -#define CURL_HTTP_VERSION_1_1 2L /* please use HTTP 1.1 in the request */ -#define CURL_HTTP_VERSION_2_0 3L /* please use HTTP 2 in the request */ -#define CURL_HTTP_VERSION_2TLS 4L /* use version 2 for HTTPS, version 1.1 for - HTTP */ -#define CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE 5L /* please use HTTP 2 without - HTTP/1.1 Upgrade */ -#define CURL_HTTP_VERSION_3 30L /* Use HTTP/3, fallback to HTTP/2 or - HTTP/1 if needed. For HTTPS only. For - HTTP, this option makes libcurl - return error. */ -#define CURL_HTTP_VERSION_3ONLY 31L /* Use HTTP/3 without fallback. For - HTTPS only. For HTTP, this makes - libcurl return error. */ -#define CURL_HTTP_VERSION_LAST 32L /* *ILLEGAL* http version */ - -/* Convenience definition simple because the name of the version is HTTP/2 and - not 2.0. The 2_0 version of the enum name was set while the version was - still planned to be 2.0 and we stick to it for compatibility. */ -#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 - -/* - * Public API enums for RTSP requests - */ - -#define CURL_RTSPREQ_NONE 0L -#define CURL_RTSPREQ_OPTIONS 1L -#define CURL_RTSPREQ_DESCRIBE 2L -#define CURL_RTSPREQ_ANNOUNCE 3L -#define CURL_RTSPREQ_SETUP 4L -#define CURL_RTSPREQ_PLAY 5L -#define CURL_RTSPREQ_PAUSE 6L -#define CURL_RTSPREQ_TEARDOWN 7L -#define CURL_RTSPREQ_GET_PARAMETER 8L -#define CURL_RTSPREQ_SET_PARAMETER 9L -#define CURL_RTSPREQ_RECORD 10L -#define CURL_RTSPREQ_RECEIVE 11L -#define CURL_RTSPREQ_LAST 12L /* not used */ - - /* These enums are for use with the CURLOPT_NETRC option. */ -#define CURL_NETRC_IGNORED 0L /* The .netrc is never read. - This is the default. */ -#define CURL_NETRC_OPTIONAL 1L /* A user:password in the URL is preferred - to one in the .netrc. */ -#define CURL_NETRC_REQUIRED 2L /* A user:password in the URL is ignored. - Unless one is set programmatically, the - .netrc is queried. */ -enum CURL_NETRC_OPTION { - /* we set a single member here, to make sure we still provide the enum, but - the values to use are defined above with L suffixes */ - CURL_NETRC_LAST = 3 -}; - -#define CURL_SSLVERSION_DEFAULT 0L -#define CURL_SSLVERSION_TLSv1 1L /* TLS 1.x */ -#define CURL_SSLVERSION_SSLv2 2L -#define CURL_SSLVERSION_SSLv3 3L -#define CURL_SSLVERSION_TLSv1_0 4L -#define CURL_SSLVERSION_TLSv1_1 5L -#define CURL_SSLVERSION_TLSv1_2 6L -#define CURL_SSLVERSION_TLSv1_3 7L - -#define CURL_SSLVERSION_LAST 8L /* never use, keep last */ - -#define CURL_SSLVERSION_MAX_NONE 0L -#define CURL_SSLVERSION_MAX_DEFAULT (CURL_SSLVERSION_TLSv1 << 16) -#define CURL_SSLVERSION_MAX_TLSv1_0 (CURL_SSLVERSION_TLSv1_0 << 16) -#define CURL_SSLVERSION_MAX_TLSv1_1 (CURL_SSLVERSION_TLSv1_1 << 16) -#define CURL_SSLVERSION_MAX_TLSv1_2 (CURL_SSLVERSION_TLSv1_2 << 16) -#define CURL_SSLVERSION_MAX_TLSv1_3 (CURL_SSLVERSION_TLSv1_3 << 16) - -/* never use, keep last */ -#define CURL_SSLVERSION_MAX_LAST (CURL_SSLVERSION_LAST << 16) - -#define CURL_TLSAUTH_NONE 0L -#define CURL_TLSAUTH_SRP 1L - -enum CURL_TLSAUTH { - /* we set a single member here, to make sure we still provide the enum, - but the values to use are defined above with L suffixes */ - CURL_TLSAUTH_LAST = 2 -}; - -/* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 - can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 - | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ - -#define CURL_REDIR_GET_ALL 0L -#define CURL_REDIR_POST_301 1L -#define CURL_REDIR_POST_302 2L -#define CURL_REDIR_POST_303 4L -#define CURL_REDIR_POST_ALL \ - (CURL_REDIR_POST_301 | CURL_REDIR_POST_302 | CURL_REDIR_POST_303) - -#define CURL_TIMECOND_NONE 0L -#define CURL_TIMECOND_IFMODSINCE 1L -#define CURL_TIMECOND_IFUNMODSINCE 2L -#define CURL_TIMECOND_LASTMOD 3L - -typedef enum { - /* we set a single member here, to make sure we still provide - the enum typedef, but the values to use are defined above with L - suffixes */ - CURL_TIMECOND_LAST = 4 -} curl_TimeCond; - -/* Special size_t value signaling a null-terminated string. */ -#define CURL_ZERO_TERMINATED ((size_t)-1) - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - release */ -CURL_EXTERN int curl_strequal(const char *s1, const char *s2); -CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n); - -/* Mime/form handling support. */ -typedef struct curl_mime curl_mime; /* Mime context. */ -typedef struct curl_mimepart curl_mimepart; /* Mime part context. */ - -/* CURLMIMEOPT_ defines are for the CURLOPT_MIME_OPTIONS option. */ -#define CURLMIMEOPT_FORMESCAPE (1L << 0) /* Use backslash-escaping for forms */ - -/* - * NAME curl_mime_init() - * - * DESCRIPTION - * - * Create a mime context and return its handle. The easy parameter is the - * target handle. - */ -CURL_EXTERN curl_mime *curl_mime_init(CURL *easy); - -/* - * NAME curl_mime_free() - * - * DESCRIPTION - * - * release a mime handle and its substructures. - */ -CURL_EXTERN void curl_mime_free(curl_mime *mime); - -/* - * NAME curl_mime_addpart() - * - * DESCRIPTION - * - * Append a new empty part to the given mime context and return a handle to - * the created part. - */ -CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime); - -/* - * NAME curl_mime_name() - * - * DESCRIPTION - * - * Set mime/form part name. - */ -CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name); - -/* - * NAME curl_mime_filename() - * - * DESCRIPTION - * - * Set mime part remote filename. - */ -CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_type() - * - * DESCRIPTION - * - * Set mime part type. - */ -CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); - -/* - * NAME curl_mime_encoder() - * - * DESCRIPTION - * - * Set mime data transfer encoder. - */ -CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part, - const char *encoding); - -/* - * NAME curl_mime_data() - * - * DESCRIPTION - * - * Set mime part data source from memory data, - */ -CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part, - const char *data, size_t datasize); - -/* - * NAME curl_mime_filedata() - * - * DESCRIPTION - * - * Set mime part data source from named file. - */ -CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_data_cb() - * - * DESCRIPTION - * - * Set mime part data source from callback function. - */ -CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part, - curl_off_t datasize, - curl_read_callback readfunc, - curl_seek_callback seekfunc, - curl_free_callback freefunc, - void *arg); - -/* - * NAME curl_mime_subparts() - * - * DESCRIPTION - * - * Set mime part data source from subparts. - */ -CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, - curl_mime *subparts); -/* - * NAME curl_mime_headers() - * - * DESCRIPTION - * - * Set mime part headers. - */ -CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, - struct curl_slist *headers, - int take_ownership); - -typedef enum { - /********* the first one is unused ************/ - CURLFORM_NOTHING CURL_DEPRECATED(7.56.0, ""), - CURLFORM_COPYNAME CURL_DEPRECATED(7.56.0, "Use curl_mime_name()"), - CURLFORM_PTRNAME CURL_DEPRECATED(7.56.0, "Use curl_mime_name()"), - CURLFORM_NAMELENGTH CURL_DEPRECATED(7.56.0, ""), - CURLFORM_COPYCONTENTS CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_PTRCONTENTS CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_CONTENTSLENGTH CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_FILECONTENT CURL_DEPRECATED(7.56.0, "Use curl_mime_data_cb()"), - CURLFORM_ARRAY CURL_DEPRECATED(7.56.0, ""), - CURLFORM_OBSOLETE, - CURLFORM_FILE CURL_DEPRECATED(7.56.0, "Use curl_mime_filedata()"), - - CURLFORM_BUFFER CURL_DEPRECATED(7.56.0, "Use curl_mime_filename()"), - CURLFORM_BUFFERPTR CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - CURLFORM_BUFFERLENGTH CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - - CURLFORM_CONTENTTYPE CURL_DEPRECATED(7.56.0, "Use curl_mime_type()"), - CURLFORM_CONTENTHEADER CURL_DEPRECATED(7.56.0, "Use curl_mime_headers()"), - CURLFORM_FILENAME CURL_DEPRECATED(7.56.0, "Use curl_mime_filename()"), - CURLFORM_END, - CURLFORM_OBSOLETE2, - - CURLFORM_STREAM CURL_DEPRECATED(7.56.0, "Use curl_mime_data_cb()"), - CURLFORM_CONTENTLEN /* added in 7.46.0, provide a curl_off_t length */ - CURL_DEPRECATED(7.56.0, "Use curl_mime_data()"), - - CURLFORM_LASTENTRY /* the last unused */ -} CURLformoption; - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms { - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum { - CURL_FORMADD_OK CURL_DEPRECATED(7.56.0, ""), /* 1st, no error */ - - CURL_FORMADD_MEMORY CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_OPTION_TWICE CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_NULL CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_UNKNOWN_OPTION CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_INCOMPLETE CURL_DEPRECATED(7.56.0, ""), - CURL_FORMADD_ILLEGAL_ARRAY CURL_DEPRECATED(7.56.0, ""), - /* libcurl was built with form api disabled */ - CURL_FORMADD_DISABLED CURL_DEPRECATED(7.56.0, ""), - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanced function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURL_EXTERN CURLFORMcode CURL_DEPRECATED(7.56.0, "Use curl_mime_init()") -curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * callback function for curl_formget() - * The void *arg pointer is the one passed as second argument to - * curl_formget(). - * The character buffer passed to it must not be freed. - * Should return the buffer length passed to it as the argument "len" on - * success. - */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, - size_t len); - -/* - * NAME curl_formget() - * - * DESCRIPTION - * - * Serialize a curl_httppost struct built with curl_formadd(). - * Accepts a void pointer as second argument which is passed to - * the curl_formget_callback function. - * Returns 0 on success. - */ -CURL_EXTERN int CURL_DEPRECATED(7.56.0, "") -curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append); -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -CURL_EXTERN void CURL_DEPRECATED(7.56.0, "Use curl_mime_free()") -curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -CURL_EXTERN char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ASCII string of the libcurl version. - */ -CURL_EXTERN char *curl_version(void); - -/* - * NAME curl_easy_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -CURL_EXTERN char *curl_easy_escape(CURL *curl, - const char *string, - int length); - -/* the previous version: */ -CURL_EXTERN char *curl_escape(const char *string, - int length); - -/* - * NAME curl_easy_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8-bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - * Conversion Note: On non-ASCII platforms the ASCII %XX codes are - * converted into the host encoding. - */ -CURL_EXTERN char *curl_easy_unescape(CURL *curl, - const char *string, - int inlength, - int *outlength); - -/* the previous version */ -CURL_EXTERN char *curl_unescape(const char *string, - int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -CURL_EXTERN void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl and before any call of other libcurl functions. - * - * This function is thread-safe if CURL_VERSION_THREADSAFE is set in the - * curl_version_info_data.features flag (fetch by curl_version_info()). - */ -CURL_EXTERN CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for misuse of the curl library etc. User registered - * callback routines is invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURL_EXTERN CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -CURL_EXTERN void curl_global_cleanup(void); - -/* - * NAME curl_global_trace() - * - * DESCRIPTION - * - * curl_global_trace() can be invoked at application start to - * configure which components in curl should participate in tracing. - * - * This function is thread-safe if CURL_VERSION_THREADSAFE is set in the - * curl_version_info_data.features flag (fetch by curl_version_info()). - */ -CURL_EXTERN CURLcode curl_global_trace(const char *config); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist { - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_global_sslset() - * - * DESCRIPTION - * - * When built with multiple SSL backends, curl_global_sslset() allows to - * choose one. This function can only be called once, and it must be called - * *before* curl_global_init(). - * - * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The - * backend can also be specified via the name parameter (passing -1 as id). If - * both id and name are specified, the name is ignored. If neither id nor - * name are specified, the function fails with CURLSSLSET_UNKNOWN_BACKEND - * and set the "avail" pointer to the NULL-terminated list of available - * backends. - * - * Upon success, the function returns CURLSSLSET_OK. - * - * If the specified SSL backend is not available, the function returns - * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a - * NULL-terminated list of available SSL backends. - * - * The SSL backend can be set only once. If it has already been set, a - * subsequent attempt to change it results in a CURLSSLSET_TOO_LATE. - */ - -struct curl_ssl_backend { - curl_sslbackend id; - const char *name; -}; -typedef struct curl_ssl_backend curl_ssl_backend; - -typedef enum { - CURLSSLSET_OK = 0, - CURLSSLSET_UNKNOWN_BACKEND, - CURLSSLSET_TOO_LATE, - CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */ -} CURLsslset; - -CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail); - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it is created first. - * Returns the new list, after appending. - */ -CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *list, - const char *data); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -CURL_EXTERN void curl_slist_free_all(struct curl_slist *list); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is unused - * and should be set to NULL. - */ -CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); - -/* info about the certificate chain, for SSL backends that support it. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -struct curl_certinfo { - int num_of_certs; /* number of certificates with information */ - struct curl_slist **certinfo; /* for each index in this array, there is a - linked list with textual information for a - certificate in the format "name:content". - eg "Subject:foo", "Issuer:bar", etc. */ -}; - -/* Information about the SSL library used and the respective internal SSL - handle, which can be used to obtain further information regarding the - connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ -struct curl_tlssessioninfo { - curl_sslbackend backend; - void *internals; -}; - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_SLIST 0x400000 -#define CURLINFO_PTR 0x400000 /* same as SLIST */ -#define CURLINFO_SOCKET 0x500000 -#define CURLINFO_OFF_T 0x600000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum { - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD CURL_DEPRECATED(7.55.0, "Use CURLINFO_SIZE_UPLOAD_T") - = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, - CURLINFO_SIZE_DOWNLOAD - CURL_DEPRECATED(7.55.0, "Use CURLINFO_SIZE_DOWNLOAD_T") - = CURLINFO_DOUBLE + 8, - CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, - CURLINFO_SPEED_DOWNLOAD - CURL_DEPRECATED(7.55.0, "Use CURLINFO_SPEED_DOWNLOAD_T") - = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, - CURLINFO_SPEED_UPLOAD - CURL_DEPRECATED(7.55.0, "Use CURLINFO_SPEED_UPLOAD_T") - = CURLINFO_DOUBLE + 10, - CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD - CURL_DEPRECATED(7.55.0, - "Use CURLINFO_CONTENT_LENGTH_DOWNLOAD_T") - = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD - CURL_DEPRECATED(7.55.0, - "Use CURLINFO_CONTENT_LENGTH_UPLOAD_T") - = CURLINFO_DOUBLE + 16, - CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, - CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, - CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, - CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, - CURLINFO_LASTSOCKET CURL_DEPRECATED(7.45.0, "Use CURLINFO_ACTIVESOCKET") - = CURLINFO_LONG + 29, - CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, - CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, - CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, - CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_PTR + 34, - CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, - CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, - CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, - CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, - CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, - CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, - CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, - CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, - CURLINFO_TLS_SESSION CURL_DEPRECATED(7.48.0, "Use CURLINFO_TLS_SSL_PTR") - = CURLINFO_PTR + 43, - CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, - CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, - CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, - CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, - CURLINFO_PROTOCOL CURL_DEPRECATED(7.85.0, "Use CURLINFO_SCHEME") - = CURLINFO_LONG + 48, - CURLINFO_SCHEME = CURLINFO_STRING + 49, - CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50, - CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51, - CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52, - CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53, - CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54, - CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55, - CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56, - CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57, - CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58, - CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59, - CURLINFO_REFERER = CURLINFO_STRING + 60, - CURLINFO_CAINFO = CURLINFO_STRING + 61, - CURLINFO_CAPATH = CURLINFO_STRING + 62, - CURLINFO_XFER_ID = CURLINFO_OFF_T + 63, - CURLINFO_CONN_ID = CURLINFO_OFF_T + 64, - CURLINFO_QUEUE_TIME_T = CURLINFO_OFF_T + 65, - CURLINFO_USED_PROXY = CURLINFO_LONG + 66, - CURLINFO_POSTTRANSFER_TIME_T = CURLINFO_OFF_T + 67, - CURLINFO_EARLYDATA_SENT_T = CURLINFO_OFF_T + 68, - CURLINFO_HTTPAUTH_USED = CURLINFO_LONG + 69, - CURLINFO_PROXYAUTH_USED = CURLINFO_LONG + 70, - CURLINFO_SIZE_DELIVERED = CURLINFO_OFF_T + 71, - CURLINFO_LASTONE = 71 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum { - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1 << 0) /* no purpose since 7.57.0 */ -#define CURL_GLOBAL_WIN32 (1 << 1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL | CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL -#define CURL_GLOBAL_ACK_EINTR (1 << 2) - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum { - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internally to say that the locking is made - * to change the internal state of the share itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_PSL, - CURL_LOCK_DATA_HSTS, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum { - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - -typedef enum { - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* 4 out of memory */ - CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum { - CURLSHOPT_NONE, /* do not use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURL_EXTERN CURLSH *curl_share_init(void); -CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *sh, CURLSHoption option, ...); -CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *sh); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum { - CURLVERSION_FIRST, /* 7.10 */ - CURLVERSION_SECOND, /* 7.11.1 */ - CURLVERSION_THIRD, /* 7.12.0 */ - CURLVERSION_FOURTH, /* 7.16.1 */ - CURLVERSION_FIFTH, /* 7.57.0 */ - CURLVERSION_SIXTH, /* 7.66.0 */ - CURLVERSION_SEVENTH, /* 7.70.0 */ - CURLVERSION_EIGHTH, /* 7.72.0 */ - CURLVERSION_NINTH, /* 7.75.0 */ - CURLVERSION_TENTH, /* 7.77.0 */ - CURLVERSION_ELEVENTH, /* 7.87.0 */ - CURLVERSION_TWELFTH, /* 8.8.0 */ - CURLVERSION_LAST /* never actually use this */ -} CURLversion; - -/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by programs - that want to get version information. It is meant to be a built-in - version number for what kind of struct the caller expects. If the struct - ever changes, we redefine the NOW to another enum from above. */ -#define CURLVERSION_NOW CURLVERSION_TWELFTH - -struct curl_version_info_data { - CURLversion age; /* age of the returned struct */ - const char *version; /* LIBCURL_VERSION */ - unsigned int version_num; /* LIBCURL_VERSION_NUM */ - const char *host; /* OS/host/cpu/machine when configured */ - int features; /* bitmask, see defines below */ - const char *ssl_version; /* human readable string */ - long ssl_version_num; /* not used anymore, always 0 */ - const char *libz_version; /* human readable string */ - /* protocols is terminated by an entry with a NULL protoname */ - const char * const *protocols; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was added in CURLVERSION_THIRD */ - const char *libidn; - - /* These field were added in CURLVERSION_FOURTH */ - - /* Same as '_libiconv_version' if built with HAVE_ICONV */ - int iconv_ver_num; - - const char *libssh_version; /* human readable string */ - - /* These fields were added in CURLVERSION_FIFTH */ - unsigned int brotli_ver_num; /* Numeric Brotli version - (MAJOR << 24) | (MINOR << 12) | PATCH */ - const char *brotli_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_SIXTH */ - unsigned int nghttp2_ver_num; /* Numeric nghttp2 version - (MAJOR << 16) | (MINOR << 8) | PATCH */ - const char *nghttp2_version; /* human readable string. */ - const char *quic_version; /* human readable quic (+ HTTP/3) library + - version or NULL */ - - /* These fields were added in CURLVERSION_SEVENTH */ - const char *cainfo; /* the built-in default CURLOPT_CAINFO, might - be NULL */ - const char *capath; /* the built-in default CURLOPT_CAPATH, might - be NULL */ - - /* These fields were added in CURLVERSION_EIGHTH */ - unsigned int zstd_ver_num; /* Numeric Zstd version - (MAJOR << 24) | (MINOR << 12) | PATCH */ - const char *zstd_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_NINTH */ - const char *hyper_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_TENTH */ - const char *gsasl_version; /* human readable string. */ - - /* These fields were added in CURLVERSION_ELEVENTH */ - /* feature_names is terminated by an entry with a NULL feature name */ - const char * const *feature_names; - - /* These fields were added in CURLVERSION_TWELFTH */ - const char *rtmp_version; /* human readable string. */ -}; -typedef struct curl_version_info_data curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported - (deprecated) */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported - (deprecated) */ -#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ -#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are - supported */ -#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ -#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported - (deprecated) */ -#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ -#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper - is supported */ -#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ -#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ -#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ -#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ -#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used - for cookie domain verification */ -#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ -#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ -#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ -#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */ -#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */ -#define CURL_VERSION_ZSTD (1<<26) /* zstd features are present */ -#define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */ -#define CURL_VERSION_HSTS (1<<28) /* HSTS is supported */ -#define CURL_VERSION_GSASL (1<<29) /* libgsasl is supported */ -#define CURL_VERSION_THREADSAFE (1<<30) /* libcurl API is thread-safe */ - -/* - * NAME curl_version_info() - * - * DESCRIPTION - * - * This function returns a pointer to a static copy of the version info - * struct. See above. - */ -CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion stamp); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_easy_strerror(CURLcode error); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_share_strerror(CURLSHcode error); - -/* - * NAME curl_easy_pause() - * - * DESCRIPTION - * - * The curl_easy_pause function pauses or unpauses transfers. Select the new - * state by setting the action bitmask, use the convenience defines below. - * - */ -CURL_EXTERN CURLcode curl_easy_pause(CURL *curl, int action); - -#define CURLPAUSE_RECV (1 << 0) -#define CURLPAUSE_RECV_CONT 0 - -#define CURLPAUSE_SEND (1 << 2) -#define CURLPAUSE_SEND_CONT 0 - -#define CURLPAUSE_ALL (CURLPAUSE_RECV | CURLPAUSE_SEND) -#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT | CURLPAUSE_SEND_CONT) - -/* - * NAME curl_easy_ssls_import() - * - * DESCRIPTION - * - * The curl_easy_ssls_import function adds a previously exported SSL session - * to the SSL session cache of the easy handle (or the underlying share). - */ -CURL_EXTERN CURLcode curl_easy_ssls_import(CURL *curl, - const char *session_key, - const unsigned char *shmac, - size_t shmac_len, - const unsigned char *sdata, - size_t sdata_len); - -/* This is the curl_ssls_export_cb callback prototype. It - * is passed to curl_easy_ssls_export() to extract SSL sessions/tickets. */ -typedef CURLcode curl_ssls_export_cb(CURL *curl, - void *userptr, - const char *session_key, - const unsigned char *shmac, - size_t shmac_len, - const unsigned char *sdata, - size_t sdata_len, - curl_off_t valid_until, - int ietf_tls_id, - const char *alpn, - size_t earlydata_max); - -/* - * NAME curl_easy_ssls_export() - * - * DESCRIPTION - * - * The curl_easy_ssls_export function iterates over all SSL sessions stored - * in the easy handle (or underlying share) and invokes the passed - * callback. - * - */ -CURL_EXTERN CURLcode curl_easy_ssls_export(CURL *curl, - curl_ssls_export_cb *export_fn, - void *userptr); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" -#include "urlapi.h" -#include "options.h" -#include "header.h" -#include "websockets.h" -#include "mprintf.h" - -/* the typechecker does not work in C++ (yet) */ -#if ((defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \ - (defined(__clang__) && __clang_major__ >= 14)) && \ - !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) -#include "typecheck-gcc.h" -#else -#if defined(__STDC__) && (__STDC__ >= 1) -/* This preprocessor magic ensures that application authors pass exactly three - arguments to these functions. For compatibility with C++ global namespace - '::' and reusing these symbols as method names, while also avoiding - recursive macros, use a two-stage solution. */ -#define curl_exactly_three_arguments(a, b, c) (a, b, c) -#define curl_easy_setopt(handle, opt, param) \ - curl_easy_setopt curl_exactly_three_arguments(handle, opt, param) -#define curl_easy_getinfo(handle, info, arg) \ - curl_easy_getinfo curl_exactly_three_arguments(handle, info, arg) -#define curl_share_setopt(share, opt, param) \ - curl_share_setopt curl_exactly_three_arguments(share, opt, param) -#define curl_multi_setopt(handle, opt, param) \ - curl_multi_setopt curl_exactly_three_arguments(handle, opt, param) -#endif /* __STDC__ >= 1 */ -#endif /* gcc >= 4.3 && !__cplusplus && !CURL_DISABLE_TYPECHECK */ - -#endif /* CURLINC_CURL_H */ diff --git a/vendor/curl/include/curl/curlver.h b/vendor/curl/include/curl/curlver.h deleted file mode 100644 index 144f5fea1..000000000 --- a/vendor/curl/include/curl/curlver.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef CURLINC_CURLVER_H -#define CURLINC_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "Daniel Stenberg, ." - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "8.20.0-DEV" - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 8 -#define LIBCURL_VERSION_MINOR 20 -#define LIBCURL_VERSION_PATCH 0 -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparisons by programs. The LIBCURL_VERSION_NUM define always - follows this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal (using 8 bits each). All three numbers are always represented - using two digits. 1.2 would appear as "0x010200" while version 9.11.7 - appears as "0x090b07". - - This 6-digit (24 bits) hexadecimal number does not show pre-release number, - and it is always a greater number in a more recent release. It makes - comparisons with greater than and less than work. - - Note: This define is the full hex number and _does not_ use the - CURL_VERSION_BITS() macro since curl's own configure script greps for it - and needs it to contain the full number. -*/ -#define LIBCURL_VERSION_NUM 0x081400 - -/* - * This is the date and time when the full source package was created. The - * timestamp is not stored in git, as the timestamp is properly set in the - * tarballs by the maketgz script. - * - * The format of the date follows this template: - * - * "2007-11-23" - */ -#define LIBCURL_TIMESTAMP "[unreleased]" - -#define CURL_VERSION_BITS(x, y, z) ((x) << 16 | (y) << 8 | (z)) -#define CURL_AT_LEAST_VERSION(x, y, z) \ - (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) - -#endif /* CURLINC_CURLVER_H */ diff --git a/vendor/curl/include/curl/easy.h b/vendor/curl/include/curl/easy.h deleted file mode 100644 index 197e6e7b9..000000000 --- a/vendor/curl/include/curl/easy.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef CURLINC_EASY_H -#define CURLINC_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/* Flag bits in the curl_blob struct: */ -#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */ -#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */ - -struct curl_blob { - void *data; - size_t len; - unsigned int flags; /* bit 0 is defined, the rest are reserved and should be - left zeroes */ -}; - -CURL_EXTERN CURL *curl_easy_init(void); -CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); -CURL_EXTERN void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. - * The third argument MUST be pointing to the specific type of the used option - * which is documented in each man page of the option. The data pointed to - * is filled in accordingly and can be relied upon only if the function - * returns CURLE_OK. This function is intended to get used *AFTER* a performed - * transfer, all results from this function are undefined until the transfer - * is completed. - */ -CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistent connections cannot - * be transferred. It is useful in multi-threaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a curl handle to the default values. This puts back the - * handle to the same state as it was in when it was created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -CURL_EXTERN void curl_easy_reset(CURL *curl); - -/* - * NAME curl_easy_recv() - * - * DESCRIPTION - * - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, - size_t *n); - -/* - * NAME curl_easy_send() - * - * DESCRIPTION - * - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, - size_t buflen, size_t *n); - -/* - * NAME curl_easy_upkeep() - * - * DESCRIPTION - * - * Performs connection upkeep for the given session handle. - */ -CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/vendor/curl/include/curl/header.h b/vendor/curl/include/curl/header.h deleted file mode 100644 index 5c3281a53..000000000 --- a/vendor/curl/include/curl/header.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef CURLINC_HEADER_H -#define CURLINC_HEADER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -struct curl_header { - char *name; /* this might not use the same case */ - char *value; - size_t amount; /* number of headers using this name */ - size_t index; /* ... of this instance, 0 or higher */ - unsigned int origin; /* see bits below */ - void *anchor; /* handle privately used by libcurl */ -}; - -/* 'origin' bits */ -#define CURLH_HEADER (1 << 0) /* plain server header */ -#define CURLH_TRAILER (1 << 1) /* trailers */ -#define CURLH_CONNECT (1 << 2) /* CONNECT headers */ -#define CURLH_1XX (1 << 3) /* 1xx headers */ -#define CURLH_PSEUDO (1 << 4) /* pseudo headers */ - -typedef enum { - CURLHE_OK, - CURLHE_BADINDEX, /* header exists but not with this index */ - CURLHE_MISSING, /* no such header exists */ - CURLHE_NOHEADERS, /* no headers at all exist (yet) */ - CURLHE_NOREQUEST, /* no request with this number was used */ - CURLHE_OUT_OF_MEMORY, /* out of memory while processing */ - CURLHE_BAD_ARGUMENT, /* a function argument was not okay */ - CURLHE_NOT_BUILT_IN /* if API was disabled in the build */ -} CURLHcode; - -CURL_EXTERN CURLHcode curl_easy_header(CURL *curl, - const char *name, - size_t nameindex, - unsigned int origin, - int request, - struct curl_header **hout); - -CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *curl, - unsigned int origin, - int request, - struct curl_header *prev); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif /* CURLINC_HEADER_H */ diff --git a/vendor/curl/include/curl/mprintf.h b/vendor/curl/include/curl/mprintf.h deleted file mode 100644 index 9272e7489..000000000 --- a/vendor/curl/include/curl/mprintf.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef CURLINC_MPRINTF_H -#define CURLINC_MPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#include -#include /* needed for FILE */ -#include "curl.h" /* for CURL_EXTERN */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CURL_TEMP_PRINTF -#if (defined(__GNUC__) || defined(__clang__) || \ - defined(__IAR_SYSTEMS_ICC__)) && \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(CURL_NO_FMT_CHECKS) -#if defined(__MINGW32__) && !defined(__clang__) -#ifdef __MINGW_PRINTF_FORMAT /* mingw-w64 3.0.0+. Needs stdio.h. */ -#define CURL_TEMP_PRINTF(fmt, arg) \ - __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, arg))) -#else -#define CURL_TEMP_PRINTF(fmt, arg) -#endif -#else -#define CURL_TEMP_PRINTF(fmt, arg) \ - __attribute__((format(printf, fmt, arg))) -#endif -#else -#define CURL_TEMP_PRINTF(fmt, arg) -#endif -#endif - -CURL_EXTERN int curl_mprintf(const char *format, ...) - CURL_TEMP_PRINTF(1, 2); -CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...) - CURL_TEMP_PRINTF(2, 3); -CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...) - CURL_TEMP_PRINTF(2, 3); -CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, - const char *format, ...) - CURL_TEMP_PRINTF(3, 4); -CURL_EXTERN int curl_mvprintf(const char *format, va_list args) - CURL_TEMP_PRINTF(1, 0); -CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args) - CURL_TEMP_PRINTF(2, 0); -CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args) - CURL_TEMP_PRINTF(2, 0); -CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, - const char *format, va_list args) - CURL_TEMP_PRINTF(3, 0); -CURL_EXTERN char *curl_maprintf(const char *format, ...) - CURL_TEMP_PRINTF(1, 2); -CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args) - CURL_TEMP_PRINTF(1, 0); - -#undef CURL_TEMP_PRINTF - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif /* CURLINC_MPRINTF_H */ diff --git a/vendor/curl/include/curl/multi.h b/vendor/curl/include/curl/multi.h deleted file mode 100644 index 060b73eee..000000000 --- a/vendor/curl/include/curl/multi.h +++ /dev/null @@ -1,560 +0,0 @@ -#ifndef CURLINC_MULTI_H -#define CURLINC_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - This is an "external" header file. Do not give away any internals here! - - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ - -/* - * This header file should not really need to include "curl.h" since curl.h - * itself includes this file and we expect user applications to do #include - * without the need for especially including multi.h. - * - * For some reason we added this include here at one point, and rather than to - * break existing (wrongly written) libcurl applications, we leave it as-is - * but with this warning attached. - */ -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURLM; - -typedef enum { - CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or - curl_multi_socket*() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you are in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ - CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ - CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was - attempted to get added - again */ - CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a - callback */ - CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */ - CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */ - CURLM_ABORTED_BY_CALLBACK, - CURLM_UNRECOVERABLE_POLL, - CURLM_LAST -} CURLMcode; - -/* You can check for CURLM_CALL_MULTI_SOCKET too in the same style it works - for curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ -#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM - -/* bitmask bits for CURLMOPT_PIPELINING */ -#define CURLPIPE_NOTHING 0L -#define CURLPIPE_HTTP1 1L -#define CURLPIPE_MULTIPLEX 2L - -typedef enum { - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg { - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* Based on poll(2) structure and values. - * We do not use pollfd and POLL* constants explicitly - * to cover platforms without poll(). */ -#define CURL_WAIT_POLLIN 0x0001 -#define CURL_WAIT_POLLPRI 0x0002 -#define CURL_WAIT_POLLOUT 0x0004 - -struct curl_waitfd { - curl_socket_t fd; - short events; - short revents; -}; - -/* - * Name: curl_multi_init() - * - * Desc: initialize multi-style curl usage - * - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURL_EXTERN CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *m, - CURL *curl); - -/* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *m, - CURL *curl); - -/* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *m, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - -/* - * Name: curl_multi_wait() - * - * Desc: Poll on all fds within a CURLM set as well as any - * additional fds passed to the function. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_wait(CURLM *m, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret); - -/* - * Name: curl_multi_poll() - * - * Desc: Poll on all fds within a CURLM set as well as any - * additional fds passed to the function. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_poll(CURLM *m, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret); - -/* - * Name: curl_multi_wakeup() - * - * Desc: wakes up a sleeping curl_multi_poll call. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *m); - -/* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there is data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called. It returns the number of - * handles that still transfer data in the second argument's - * integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on individual transfers even when - * this returns OK. - */ -CURL_EXTERN CURLMcode curl_multi_perform(CURLM *m, - int *running_handles); - -/* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles are going to be if this function is - * called in the middle of a transfer. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *m); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there is any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function return a new struct each time, - * until a special "end of msgs" struct is returned as a signal that - * there is no more to get at this point. - * - * The data the returned pointer points to does not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be simple and only contain basic - * information. If more involved information is wanted, we provide - * the particular "transfer handle" in that struct and that - * should/could/would be used in subsequent curl_easy_getinfo() calls - * (or similar). The point being that we must never expose complex - * structs to applications, as then we undoubtably get backwards - * compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *m, - int *msgs_in_queue); - -/* - * Name: curl_multi_strerror() - * - * Desc: The curl_multi_strerror function may be used to turn a CURLMcode - * value into the equivalent human readable error string. This is - * useful for printing meaningful error messages. - * - * Returns: A pointer to a null-terminated error message. - */ -CURL_EXTERN const char *curl_multi_strerror(CURLMcode error); - -/* - * Name: curl_multi_socket() and - * curl_multi_socket_all() - * - * Desc: An alternative version of curl_multi_perform() that allows the - * application to pass in one of the file descriptors that have been - * detected to have "action" on them and let libcurl perform. - * See man page for details. - */ -#define CURL_POLL_NONE 0 -#define CURL_POLL_IN 1 -#define CURL_POLL_OUT 2 -#define CURL_POLL_INOUT 3 -#define CURL_POLL_REMOVE 4 - -#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD - -#define CURL_CSELECT_IN 0x01 -#define CURL_CSELECT_OUT 0x02 -#define CURL_CSELECT_ERR 0x04 - -typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp); /* private socket - pointer */ -/* - * Name: curl_multi_timer_callback - * - * Desc: Called by libcurl whenever the library detects a change in the - * maximum number of milliseconds the app is allowed to wait before - * curl_multi_socket() or curl_multi_perform() must be called - * (to allow libcurl's timed events to take place). - * - * Returns: The callback should return zero. - */ -typedef int (*curl_multi_timer_callback)(CURLM *m, /* multi handle */ - long timeout_ms, /* see above */ - void *userp); /* private callback - pointer */ - -CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()") -curl_multi_socket(CURLM *m, curl_socket_t s, int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *m, - curl_socket_t s, - int ev_bitmask, - int *running_handles); - -CURL_EXTERN CURLMcode CURL_DEPRECATED(7.19.5, "Use curl_multi_socket_action()") -curl_multi_socket_all(CURLM *m, int *running_handles); - -#ifndef CURL_ALLOW_OLD_MULTI_SOCKET -/* This macro below was added in 7.16.3 to push users who recompile to use - * the new curl_multi_socket_action() instead of the old curl_multi_socket() - */ -#define curl_multi_socket(x, y, z) curl_multi_socket_action(x, y, 0, z) -#endif - -/* - * Name: curl_multi_timeout() - * - * Desc: Returns the maximum number of milliseconds the app is allowed to - * wait before curl_multi_socket() or curl_multi_perform() must be - * called (to allow libcurl's timed events to take place). - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *m, - long *timeout_ms); - -typedef enum { - /* This is the socket callback function pointer */ - CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1), - - /* This is the argument passed to the socket callback */ - CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2), - - /* set to 1 to enable pipelining for this multi handle */ - CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3), - - /* This is the timer callback function pointer */ - CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4), - - /* This is the argument passed to the timer callback */ - CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5), - - /* maximum number of entries in the connection cache */ - CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6), - - /* maximum number of (pipelining) connections to one host */ - CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7), - - /* maximum number of requests in a pipeline */ - CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8), - - /* a connection with a content-length longer than this - is not considered for pipelining */ - CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9), - - /* a connection with a chunk length longer than this - is not considered for pipelining */ - CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10), - - /* a list of site names(+port) that are blocked from pipelining */ - CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11), - - /* a list of server types that are blocked from pipelining */ - CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12), - - /* maximum number of open connections in total */ - CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13), - - /* This is the server push callback function pointer */ - CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14), - - /* This is the argument passed to the server push callback */ - CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15), - - /* maximum number of concurrent streams to support on a connection */ - CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16), - - /* network has changed, adjust caches/connection reuse */ - CURLOPT(CURLMOPT_NETWORK_CHANGED, CURLOPTTYPE_LONG, 17), - - /* This is the notify callback function pointer */ - CURLOPT(CURLMOPT_NOTIFYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 18), - - /* This is the argument passed to the notify callback */ - CURLOPT(CURLMOPT_NOTIFYDATA, CURLOPTTYPE_OBJECTPOINT, 19), - - /* maximum number of threads used with threaded DNS resolver */ - CURLOPT(CURLMOPT_RESOLVE_THREADS_MAX, CURLOPTTYPE_LONG, 20), - - /* set to 1L for not joining threads when multi is cleaned up */ - CURLOPT(CURLMOPT_QUICK_EXIT, CURLOPTTYPE_LONG, 21), - - CURLMOPT_LASTENTRY /* the last unused */ -} CURLMoption; - -/* Definition of bits for the CURLMOPT_NETWORK_CHANGED argument: */ - -/* - CURLMNWC_CLEAR_ALL tells libcurl to clear "everything" that could be - associated with this network, including both connections and DNS data. */ -#define CURLMNWC_CLEAR_ALL (1L << 0) - -/* - CURLMNWC_CLEAR_CONNS tells libcurl to prevent further reuse of existing - connections. Connections that are idle are closed. Ongoing transfers do - continue with the connection they have. */ -#define CURLMNWC_CLEAR_CONNS (1L << 1) - -/* - CURLMNWC_CLEAR_DNS tells libcurl to clear the DNS cache associated with - this multi handle. Ongoing transfers keep using their already resolved - addresses, but future name resolutions are performed again. */ -#define CURLMNWC_CLEAR_DNS (1L << 2) - -/* - * Name: curl_multi_setopt() - * - * Desc: Sets options for the multi handle. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *m, - CURLMoption option, ...); - -/* - * Name: curl_multi_assign() - * - * Desc: This function sets an association in the multi handle between the - * given socket and a private pointer of the application. This is - * (only) useful for curl_multi_socket uses. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_assign(CURLM *m, - curl_socket_t sockfd, void *sockp); - -/* - * Name: curl_multi_get_handles() - * - * Desc: Returns an allocated array holding all handles currently added to - * the multi handle. Marks the final entry with a NULL pointer. If - * there is no easy handle added to the multi handle, this function - * returns an array with the first entry as a NULL pointer. - * - * Returns: NULL on failure, otherwise a CURL **array pointer - */ -CURL_EXTERN CURL **curl_multi_get_handles(CURLM *m); - -typedef enum { - CURLMINFO_NONE, /* first, never use this */ - /* The number of easy handles currently managed by the multi handle, - * e.g. have been added but not yet removed. */ - CURLMINFO_XFERS_CURRENT = 1, - /* The number of easy handles running, e.g. not done and not queueing. */ - CURLMINFO_XFERS_RUNNING = 2, - /* The number of easy handles waiting to start, e.g. for a connection - * to become available due to limits on parallelism, max connections - * or other factors. */ - CURLMINFO_XFERS_PENDING = 3, - /* The number of easy handles finished, waiting for their results to - * be read via `curl_multi_info_read()`. */ - CURLMINFO_XFERS_DONE = 4, - /* The total number of easy handles added to the multi handle, ever. */ - CURLMINFO_XFERS_ADDED = 5, - - CURLMINFO_LASTENTRY /* the last unused */ -} CURLMinfo_offt; - -/* - * Name: curl_multi_get_offt() - * - * Desc: Retrieves a numeric value for the `CURLMINFO_*` enums. - * - * Returns: CULRM_OK or error when value could not be obtained. - */ -CURL_EXTERN CURLMcode curl_multi_get_offt(CURLM *m, - CURLMinfo_offt info, - curl_off_t *pvalue); - -/* - * Name: curl_push_callback - * - * Desc: This callback gets called when a new stream is being pushed by the - * server. It approves or denies the new stream. It can also decide - * to completely fail the connection. - * - * Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT - */ -#define CURL_PUSH_OK 0 -#define CURL_PUSH_DENY 1 -#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */ - -struct curl_pushheaders; /* forward declaration only */ - -CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, - size_t num); -CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, - const char *name); - -typedef int (*curl_push_callback)(CURL *parent, - CURL *easy, - size_t num_headers, - struct curl_pushheaders *headers, - void *userp); - -/* - * Name: curl_multi_waitfds() - * - * Desc: Ask curl for fds for polling. The app can use these to poll on. - * We want curl_multi_perform() called as soon as one of them are - * ready. Passing zero size allows to get a number of fds. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_waitfds(CURLM *m, - struct curl_waitfd *ufds, - unsigned int size, - unsigned int *fd_count); - -/* - * Notifications dispatched by a multi handle, when enabled. - */ -#define CURLMNOTIFY_INFO_READ 0 -#define CURLMNOTIFY_EASY_DONE 1 - -/* - * Callback to install via CURLMOPT_NOTIFYFUNCTION. - */ -typedef void (*curl_notify_callback)(CURLM *m, - unsigned int notification, - CURL *easy, - void *user_data); - -CURL_EXTERN CURLMcode curl_multi_notify_disable(CURLM *m, - unsigned int notification); - -CURL_EXTERN CURLMcode curl_multi_notify_enable(CURLM *m, - unsigned int notification); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/vendor/curl/include/curl/options.h b/vendor/curl/include/curl/options.h deleted file mode 100644 index 835a722e9..000000000 --- a/vendor/curl/include/curl/options.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CURLINC_OPTIONS_H -#define CURLINC_OPTIONS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - CURLOT_LONG, /* long (a range of values) */ - CURLOT_VALUES, /* (a defined set or bitmask) */ - CURLOT_OFF_T, /* curl_off_t (a range of values) */ - CURLOT_OBJECT, /* pointer (void *) */ - CURLOT_STRING, /* (char * to null-terminated buffer) */ - CURLOT_SLIST, /* (struct curl_slist *) */ - CURLOT_CBPTR, /* (void * passed as-is to a callback) */ - CURLOT_BLOB, /* blob (struct curl_blob *) */ - CURLOT_FUNCTION /* function pointer */ -} curl_easytype; - -/* Flag bits */ - -/* "alias" means it is provided for old programs to remain functional, - we prefer another name */ -#define CURLOT_FLAG_ALIAS (1 << 0) - -/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size - to use for curl_easy_setopt() for the given id */ -struct curl_easyoption { - const char *name; - CURLoption id; - curl_easytype type; - unsigned int flags; -}; - -CURL_EXTERN const struct curl_easyoption * -curl_easy_option_by_name(const char *name); - -CURL_EXTERN const struct curl_easyoption * -curl_easy_option_by_id(CURLoption id); - -CURL_EXTERN const struct curl_easyoption * -curl_easy_option_next(const struct curl_easyoption *prev); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif -#endif /* CURLINC_OPTIONS_H */ diff --git a/vendor/curl/include/curl/stdcheaders.h b/vendor/curl/include/curl/stdcheaders.h deleted file mode 100644 index 7451aa305..000000000 --- a/vendor/curl/include/curl/stdcheaders.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef CURLINC_STDCHEADERS_H -#define CURLINC_STDCHEADERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#include - -size_t fread(void *, size_t, size_t, FILE *); -size_t fwrite(const void *, size_t, size_t, FILE *); - -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); - -#endif /* CURLINC_STDCHEADERS_H */ diff --git a/vendor/curl/include/curl/system.h b/vendor/curl/include/curl/system.h deleted file mode 100644 index c2dbab56e..000000000 --- a/vendor/curl/include/curl/system.h +++ /dev/null @@ -1,399 +0,0 @@ -#ifndef CURLINC_SYSTEM_H -#define CURLINC_SYSTEM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* - * Try to keep one section per platform, compiler and architecture, otherwise, - * if an existing section is reused for a different one and later on the - * original is adjusted, probably the piggybacking one can be adversely - * changed. - * - * In order to differentiate between platforms/compilers/architectures use - * only compiler built-in predefined preprocessor symbols. - * - * curl_off_t - * ---------- - * - * For any given platform/compiler curl_off_t MUST be typedef'ed to a 64-bit - * wide signed integral data type. The width of this data type must remain - * constant and independent of any possible large file support settings. - * - * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall - * only be violated if off_t is the only 64-bit data type available and the - * size of off_t is independent of large file support settings. Keep your - * build on the safe side avoiding an off_t gating. If you have a 64-bit - * off_t then take for sure that another 64-bit data type exists, dig deeper - * to find it. - * - */ - -#ifdef __DJGPP__ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__BORLANDC__) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__POCC__) -# ifdef _MSC_VER -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__LCC__) -# ifdef __MCST__ /* MCST eLbrus Compiler Collection */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# else /* Local (or Little) C Compiler */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# endif - -#elif defined(macintosh) -# include -# if TYPE_LONGLONG -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__TANDEM) -# ifndef __LP64 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int -# endif - -#elif defined(UNDER_CE) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__MINGW32__) -# include -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T PRId64 -# define CURL_FORMAT_CURL_OFF_TU PRIu64 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_PULL_SYS_TYPES_H 1 - -#elif defined(__VMS) -# ifdef __VAX -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__OS400__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__MVS__) -# ifdef _LONG_LONG -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else /* _LP64 and default */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__370__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# ifdef _LONG_LONG -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else /* _LP64 and default */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(TPF) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__TINYC__) /* also known as tcc */ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */ -# if !defined(__LP64) && (defined(__ILP32) || \ - defined(__i386) || \ - defined(__sparcv8) || \ - defined(__sparcv8plus)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64) || \ - defined(__amd64) || defined(__sparcv9) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__xlc__) /* IBM xlc compiler */ -# ifndef _LP64 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__hpux) /* HP aCC compiler */ -# ifndef _LP64 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -/* ===================================== */ -/* KEEP MSVC THE PENULTIMATE ENTRY */ -/* ===================================== */ - -#elif defined(_MSC_VER) -# if (_MSC_VER >= 1800) -# include -# define CURL_FORMAT_CURL_OFF_T PRId64 -# define CURL_FORMAT_CURL_OFF_TU PRIu64 -# else -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# endif -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -/* ===================================== */ -/* KEEP GENERIC GCC THE LAST ENTRY */ -/* ===================================== */ - -#elif defined(__GNUC__) && !defined(_SCO_DS) -# if !defined(__LP64__) && \ - (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \ - defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ - defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ - defined(__XTENSA__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# if (__GNUC__ >= 4) || \ - ((__GNUC__ == 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 4)) -# define CURL_POPCOUNT64(x) __builtin_popcountll(x) -# define CURL_CTZ64(x) __builtin_ctzll(x) -# endif -# elif defined(__LP64__) || \ - defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ - defined(__e2k__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# if (__GNUC__ >= 4) || \ - ((__GNUC__ == 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 4)) -# define CURL_POPCOUNT64(x) __builtin_popcountl(x) -# define CURL_CTZ64(x) __builtin_ctzl(x) -# endif -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#else -/* generic "safe guess" on old 32-bit style */ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -#endif - -#ifdef _AIX -/* AIX needs */ -#define CURL_PULL_SYS_POLL_H -#endif - -/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file - sys/types.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file - sys/socket.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file - sys/poll.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_POLL_H -# include -#endif - -/* Data type definition of curl_socklen_t. */ -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T - typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; -#endif - -/* Data type definition of curl_off_t. */ - -#ifdef CURL_TYPEOF_CURL_OFF_T - typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; -#endif - -#endif /* CURLINC_SYSTEM_H */ diff --git a/vendor/curl/include/curl/typecheck-gcc.h b/vendor/curl/include/curl/typecheck-gcc.h deleted file mode 100644 index d600c73cd..000000000 --- a/vendor/curl/include/curl/typecheck-gcc.h +++ /dev/null @@ -1,960 +0,0 @@ -#ifndef CURLINC_TYPECHECK_GCC_H -#define CURLINC_TYPECHECK_GCC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* wraps curl_easy_setopt() with type checking */ - -/* To add a new kind of warning, add an - * if(curlcheck_sometype_option(_curl_opt)) - * if(!curlcheck_sometype(value)) - * Wcurl_easy_setopt_err_sometype(); - * block and define curlcheck_sometype_option, curlcheck_sometype and - * Wcurl_easy_setopt_err_sometype below - * - * NOTE: We use two nested 'if' statements here instead of the && operator, in - * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x - * when compiling with -Wlogical-op. - * - * To add an option that uses the same type as an existing option, you need - * to extend the appropriate _curl_*_option macro - */ - -#define curl_easy_setopt(handle, option, value) \ - __extension__({ \ - if(__builtin_constant_p(option)) { \ - CURL_IGNORE_DEPRECATION( \ - if(curlcheck_long_option(option)) \ - if(!curlcheck_long(value)) \ - Wcurl_easy_setopt_err_long(); \ - if(curlcheck_off_t_option(option)) \ - if(!curlcheck_off_t(value)) \ - Wcurl_easy_setopt_err_curl_off_t(); \ - if(curlcheck_string_option(option)) \ - if(!curlcheck_string(value)) \ - Wcurl_easy_setopt_err_string(); \ - if((option) == CURLOPT_PRIVATE) { } \ - if(curlcheck_write_cb_option(option)) \ - if(!curlcheck_write_cb(value)) \ - Wcurl_easy_setopt_err_write_callback(); \ - if(curlcheck_curl_option(option)) \ - if(!curlcheck_curl(value)) \ - Wcurl_easy_setopt_err_curl(); \ - if((option) == CURLOPT_RESOLVER_START_FUNCTION) \ - if(!curlcheck_resolver_start_callback(value)) \ - Wcurl_easy_setopt_err_resolver_start_callback(); \ - if((option) == CURLOPT_READFUNCTION) \ - if(!curlcheck_read_cb(value)) \ - Wcurl_easy_setopt_err_read_cb(); \ - if((option) == CURLOPT_IOCTLFUNCTION) \ - if(!curlcheck_ioctl_cb(value)) \ - Wcurl_easy_setopt_err_ioctl_cb(); \ - if((option) == CURLOPT_SOCKOPTFUNCTION) \ - if(!curlcheck_sockopt_cb(value)) \ - Wcurl_easy_setopt_err_sockopt_cb(); \ - if((option) == CURLOPT_OPENSOCKETFUNCTION) \ - if(!curlcheck_opensocket_cb(value)) \ - Wcurl_easy_setopt_err_opensocket_cb(); \ - if((option) == CURLOPT_PROGRESSFUNCTION) \ - if(!curlcheck_progress_cb(value)) \ - Wcurl_easy_setopt_err_progress_cb(); \ - if((option) == CURLOPT_XFERINFOFUNCTION) \ - if(!curlcheck_xferinfo_cb(value)) \ - Wcurl_easy_setopt_err_xferinfo_cb(); \ - if((option) == CURLOPT_DEBUGFUNCTION) \ - if(!curlcheck_debug_cb(value)) \ - Wcurl_easy_setopt_err_debug_cb(); \ - if((option) == CURLOPT_SSL_CTX_FUNCTION) \ - if(!curlcheck_ssl_ctx_cb(value)) \ - Wcurl_easy_setopt_err_ssl_ctx_cb(); \ - if(curlcheck_conv_cb_option(option)) \ - if(!curlcheck_conv_cb(value)) \ - Wcurl_easy_setopt_err_conv_cb(); \ - if((option) == CURLOPT_SEEKFUNCTION) \ - if(!curlcheck_seek_cb(value)) \ - Wcurl_easy_setopt_err_seek_cb(); \ - if((option) == CURLOPT_CHUNK_BGN_FUNCTION) \ - if(!curlcheck_chunk_bgn_cb(value)) \ - Wcurl_easy_setopt_err_chunk_bgn_cb(); \ - if((option) == CURLOPT_CHUNK_END_FUNCTION) \ - if(!curlcheck_chunk_end_cb(value)) \ - Wcurl_easy_setopt_err_chunk_end_cb(); \ - if((option) == CURLOPT_CLOSESOCKETFUNCTION) \ - if(!curlcheck_close_socket_cb(value)) \ - Wcurl_easy_setopt_err_close_socket_cb(); \ - if((option) == CURLOPT_FNMATCH_FUNCTION) \ - if(!curlcheck_fnmatch_cb(value)) \ - Wcurl_easy_setopt_err_fnmatch_cb(); \ - if((option) == CURLOPT_HSTSREADFUNCTION) \ - if(!curlcheck_hstsread_cb(value)) \ - Wcurl_easy_setopt_err_hstsread_cb(); \ - if((option) == CURLOPT_HSTSWRITEFUNCTION) \ - if(!curlcheck_hstswrite_cb(value)) \ - Wcurl_easy_setopt_err_hstswrite_cb(); \ - if((option) == CURLOPT_SSH_HOSTKEYFUNCTION) \ - if(!curlcheck_ssh_hostkey_cb(value)) \ - Wcurl_easy_setopt_err_ssh_hostkey_cb(); \ - if((option) == CURLOPT_SSH_KEYFUNCTION) \ - if(!curlcheck_ssh_key_cb(value)) \ - Wcurl_easy_setopt_err_ssh_key_cb(); \ - if((option) == CURLOPT_INTERLEAVEFUNCTION) \ - if(!curlcheck_interleave_cb(value)) \ - Wcurl_easy_setopt_err_interleave_cb(); \ - if((option) == CURLOPT_PREREQFUNCTION) \ - if(!curlcheck_prereq_cb(value)) \ - Wcurl_easy_setopt_err_prereq_cb(); \ - if((option) == CURLOPT_TRAILERFUNCTION) \ - if(!curlcheck_trailer_cb(value)) \ - Wcurl_easy_setopt_err_trailer_cb(); \ - if(curlcheck_cb_data_option(option)) \ - if(!curlcheck_cb_data(value)) \ - Wcurl_easy_setopt_err_cb_data(); \ - if((option) == CURLOPT_ERRORBUFFER) \ - if(!curlcheck_error_buffer(value)) \ - Wcurl_easy_setopt_err_error_buffer(); \ - if((option) == CURLOPT_CURLU) \ - if(!curlcheck_ptr((value), CURLU)) \ - Wcurl_easy_setopt_err_curlu(); \ - if((option) == CURLOPT_STDERR) \ - if(!curlcheck_FILE(value)) \ - Wcurl_easy_setopt_err_FILE(); \ - if(curlcheck_postfields_option(option)) \ - if(!curlcheck_postfields(value)) \ - Wcurl_easy_setopt_err_postfields(); \ - if((option) == CURLOPT_HTTPPOST) \ - if(!curlcheck_arr((value), struct curl_httppost)) \ - Wcurl_easy_setopt_err_curl_httpost(); \ - if((option) == CURLOPT_MIMEPOST) \ - if(!curlcheck_ptr((value), curl_mime)) \ - Wcurl_easy_setopt_err_curl_mimepost(); \ - if(curlcheck_slist_option(option)) \ - if(!curlcheck_arr((value), struct curl_slist)) \ - Wcurl_easy_setopt_err_curl_slist(); \ - if((option) == CURLOPT_SHARE) \ - if(!curlcheck_ptr((value), CURLSH)) \ - Wcurl_easy_setopt_err_CURLSH(); \ - ) \ - } \ - (curl_easy_setopt)(handle, option, value); \ - }) - -/* wraps curl_easy_getinfo() with type checking */ -#define curl_easy_getinfo(handle, info, arg) \ - __extension__({ \ - if(__builtin_constant_p(info)) { \ - CURL_IGNORE_DEPRECATION( \ - if(curlcheck_string_info(info)) \ - if(!curlcheck_arr((arg), char *)) \ - Wcurl_easy_getinfo_err_string(); \ - if(curlcheck_long_info(info)) \ - if(!curlcheck_arr((arg), long)) \ - Wcurl_easy_getinfo_err_long(); \ - if(curlcheck_double_info(info)) \ - if(!curlcheck_arr((arg), double)) \ - Wcurl_easy_getinfo_err_double(); \ - if(curlcheck_slist_info(info)) \ - if(!curlcheck_arr((arg), struct curl_slist *)) \ - Wcurl_easy_getinfo_err_curl_slist(); \ - if(curlcheck_tlssessioninfo_info(info)) \ - if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \ - Wcurl_easy_getinfo_err_curl_tlssessioninfo(); \ - if(curlcheck_certinfo_info(info)) \ - if(!curlcheck_arr((arg), struct curl_certinfo *)) \ - Wcurl_easy_getinfo_err_curl_certinfo(); \ - if(curlcheck_socket_info(info)) \ - if(!curlcheck_arr((arg), curl_socket_t)) \ - Wcurl_easy_getinfo_err_curl_socket(); \ - if(curlcheck_off_t_info(info)) \ - if(!curlcheck_arr((arg), curl_off_t)) \ - Wcurl_easy_getinfo_err_curl_off_t(); \ - ) \ - } \ - (curl_easy_getinfo)(handle, info, arg); \ - }) - -#define curl_multi_setopt(handle, option, value) \ - __extension__({ \ - if(__builtin_constant_p(option)) { \ - if(curlcheck_long_option(option)) \ - if(!curlcheck_long(value)) \ - Wcurl_multi_setopt_err_long(); \ - if(curlcheck_off_t_option(option)) \ - if(!curlcheck_off_t(value)) \ - Wcurl_multi_setopt_err_curl_off_t(); \ - if(curlcheck_multicb_data_option(option)) \ - if(!curlcheck_cb_data(value)) \ - Wcurl_multi_setopt_err_cb_data(); \ - if(curlcheck_charpp_option(option)) \ - if(!curlcheck_ptrptr(value, char)) \ - Wcurl_multi_setopt_err_charpp(); \ - if((option) == CURLMOPT_NOTIFYFUNCTION) \ - if(!curlcheck_multinotify_cb(value)) \ - Wcurl_multi_setopt_err_notifycb(); \ - if((option) == CURLMOPT_PUSHFUNCTION) \ - if(!curlcheck_multipush_cb(value)) \ - Wcurl_multi_setopt_err_pushcb(); \ - if((option) == CURLMOPT_SOCKETFUNCTION) \ - if(!curlcheck_multisocket_cb(value)) \ - Wcurl_multi_setopt_err_socketcb(); \ - if((option) == CURLMOPT_TIMERFUNCTION) \ - if(!curlcheck_multitimer_cb(value)) \ - Wcurl_multi_setopt_err_timercb(); \ - } \ - (curl_multi_setopt)(handle, option, value); \ - }) - -/* evaluates to true if the option takes a data argument to pass to a - callback */ -#define curlcheck_multicb_data_option(option) \ - ((option) == CURLMOPT_NOTIFYDATA || \ - (option) == CURLMOPT_PUSHDATA || \ - (option) == CURLMOPT_SOCKETDATA || \ - (option) == CURLMOPT_TIMERDATA || \ - 0) - -/* evaluates to true if the option takes a char ** argument */ -#define curlcheck_charpp_option(option) \ - ((option) == CURLMOPT_PIPELINING_SERVER_BL || \ - (option) == CURLMOPT_PIPELINING_SITE_BL || \ - 0) - -/* evaluates to true if expr is of type curl_multi_timer_callback */ -#define curlcheck_multitimer_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_multi_timer_callback)) - -/* evaluates to true if expr is of type curl_socket_callback */ -#define curlcheck_multisocket_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_socket_callback)) - -/* evaluates to true if expr is of type curl_push_callback */ -#define curlcheck_multipush_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_push_callback)) - -/* evaluates to true if expr is of type curl_push_callback */ -#define curlcheck_multinotify_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_notify_callback)) - -/* - * Make sure that the functions are called with three arguments - */ -#define curl_share_setopt(share, opt, param) \ - (curl_share_setopt)(share, opt, param) - -/* the actual warnings, triggered by calling the Wcurl_easy_setopt_err* - * functions */ - -/* To define a new warning, use _CURL_WARNING(identifier, "message") */ -#define CURLWARNING(id, message) \ - static void __attribute__((__warning__(message))) \ - __attribute__((__unused__)) __attribute__((__noinline__)) \ - id(void) { __asm__(""); } - -CURLWARNING(Wcurl_multi_setopt_err_long, - "curl_multi_setopt expects a long argument") -CURLWARNING(Wcurl_multi_setopt_err_curl_off_t, - "curl_multi_setopt expects a curl_off_t argument") -CURLWARNING(Wcurl_multi_setopt_err_cb_data, - "curl_multi_setopt expects a 'void *' argument") -CURLWARNING(Wcurl_multi_setopt_err_charpp, - "curl_multi_setopt expects a 'char **' argument") -CURLWARNING(Wcurl_multi_setopt_err_pushcb, - "curl_multi_setopt expects a curl_push_callback argument") -CURLWARNING(Wcurl_multi_setopt_err_notifycb, - "curl_multi_setopt expects a curl_notify_callback argument") -CURLWARNING(Wcurl_multi_setopt_err_socketcb, - "curl_multi_setopt expects a curl_socket_callback argument") -CURLWARNING(Wcurl_multi_setopt_err_timercb, - "curl_multi_setopt expects a curl_multi_timer_callback argument") - -CURLWARNING(Wcurl_easy_setopt_err_long, - "curl_easy_setopt expects a long argument") -CURLWARNING(Wcurl_easy_setopt_err_curl_off_t, - "curl_easy_setopt expects a curl_off_t argument") -CURLWARNING(Wcurl_easy_setopt_err_string, - "curl_easy_setopt expects a " - "string ('char *' or char[]) argument") -CURLWARNING(Wcurl_easy_setopt_err_write_callback, - "curl_easy_setopt expects a curl_write_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_resolver_start_callback, - "curl_easy_setopt expects a " - "curl_resolver_start_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_read_cb, - "curl_easy_setopt expects a curl_read_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_ioctl_cb, - "curl_easy_setopt expects a curl_ioctl_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_sockopt_cb, - "curl_easy_setopt expects a curl_sockopt_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_opensocket_cb, - "curl_easy_setopt expects a " - "curl_opensocket_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_progress_cb, - "curl_easy_setopt expects a curl_progress_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_xferinfo_cb, - "curl_easy_setopt expects a curl_xferinfo_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_debug_cb, - "curl_easy_setopt expects a curl_debug_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_ssl_ctx_cb, - "curl_easy_setopt expects a curl_ssl_ctx_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_conv_cb, - "curl_easy_setopt expects a curl_conv_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_seek_cb, - "curl_easy_setopt expects a curl_seek_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_cb_data, - "curl_easy_setopt expects a " - "private data pointer as argument") -CURLWARNING(Wcurl_easy_setopt_err_chunk_bgn_cb, - "curl_easy_setopt expects a curl_chunk_bgn_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_chunk_end_cb, - "curl_easy_setopt expects a curl_chunk_end_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_close_socket_cb, - "curl_easy_setopt expects a curl_closesocket_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_fnmatch_cb, - "curl_easy_setopt expects a curl_fnmatch_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_hstsread_cb, - "curl_easy_setopt expects a curl_hstsread_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_hstswrite_cb, - "curl_easy_setopt expects a curl_hstswrite_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_ssh_key_cb, - "curl_easy_setopt expects a curl_sshkeycallback argument") -CURLWARNING(Wcurl_easy_setopt_err_ssh_hostkey_cb, - "curl_easy_setopt expects a curl_sshhostkeycallback argument") -CURLWARNING(Wcurl_easy_setopt_err_interleave_cb, - "curl_easy_setopt expects a curl_interleave_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_prereq_cb, - "curl_easy_setopt expects a curl_prereq_callback argument") -CURLWARNING(Wcurl_easy_setopt_err_trailer_cb, - "curl_easy_setopt expects a curl_trailerfunc_ok argument") -CURLWARNING(Wcurl_easy_setopt_err_error_buffer, - "curl_easy_setopt expects a " - "char buffer of CURL_ERROR_SIZE as argument") -CURLWARNING(Wcurl_easy_setopt_err_curlu, - "curl_easy_setopt expects a 'CURLU *' argument") -CURLWARNING(Wcurl_easy_setopt_err_curl, - "curl_easy_setopt expects a 'CURL *' argument") -CURLWARNING(Wcurl_easy_setopt_err_FILE, - "curl_easy_setopt expects a 'FILE *' argument") -CURLWARNING(Wcurl_easy_setopt_err_postfields, - "curl_easy_setopt expects a 'void *' or 'char *' argument") -CURLWARNING(Wcurl_easy_setopt_err_curl_httpost, - "curl_easy_setopt expects a 'struct curl_httppost *' " - "argument") -CURLWARNING(Wcurl_easy_setopt_err_curl_mimepost, - "curl_easy_setopt expects a 'curl_mime *' " - "argument") -CURLWARNING(Wcurl_easy_setopt_err_curl_slist, - "curl_easy_setopt expects a 'struct curl_slist *' argument") -CURLWARNING(Wcurl_easy_setopt_err_CURLSH, - "curl_easy_setopt expects a CURLSH* argument") -CURLWARNING(Wcurl_easy_getinfo_err_string, - "curl_easy_getinfo expects a pointer to 'char *'") -CURLWARNING(Wcurl_easy_getinfo_err_long, - "curl_easy_getinfo expects a pointer to long") -CURLWARNING(Wcurl_easy_getinfo_err_double, - "curl_easy_getinfo expects a pointer to double") -CURLWARNING(Wcurl_easy_getinfo_err_curl_slist, - "curl_easy_getinfo expects a pointer to 'struct curl_slist *'") -CURLWARNING(Wcurl_easy_getinfo_err_curl_tlssessioninfo, - "curl_easy_getinfo expects a pointer to " - "'struct curl_tlssessioninfo *'") -CURLWARNING(Wcurl_easy_getinfo_err_curl_certinfo, - "curl_easy_getinfo expects a pointer to " - "'struct curl_certinfo *'") -CURLWARNING(Wcurl_easy_getinfo_err_curl_socket, - "curl_easy_getinfo expects a pointer to curl_socket_t") -CURLWARNING(Wcurl_easy_getinfo_err_curl_off_t, - "curl_easy_getinfo expects a pointer to curl_off_t") - -/* groups of curl_easy_setops options that take the same type of argument */ - -/* evaluates to true if option takes a long argument */ -#define curlcheck_long_option(option) \ - (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) - -#define curlcheck_off_t_option(option) \ - (((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB)) - -/* option takes a CURL * argument */ -#define curlcheck_curl_option(option) \ - ((option) == CURLOPT_STREAM_DEPENDS || \ - (option) == CURLOPT_STREAM_DEPENDS_E || \ - 0) - -/* evaluates to true if option takes a char* argument */ -#define curlcheck_string_option(option) \ - ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ - (option) == CURLOPT_ACCEPT_ENCODING || \ - (option) == CURLOPT_ALTSVC || \ - (option) == CURLOPT_CAINFO || \ - (option) == CURLOPT_CAPATH || \ - (option) == CURLOPT_COOKIE || \ - (option) == CURLOPT_COOKIEFILE || \ - (option) == CURLOPT_COOKIEJAR || \ - (option) == CURLOPT_COOKIELIST || \ - (option) == CURLOPT_CRLFILE || \ - (option) == CURLOPT_CUSTOMREQUEST || \ - (option) == CURLOPT_DEFAULT_PROTOCOL || \ - (option) == CURLOPT_DNS_INTERFACE || \ - (option) == CURLOPT_DNS_LOCAL_IP4 || \ - (option) == CURLOPT_DNS_LOCAL_IP6 || \ - (option) == CURLOPT_DNS_SERVERS || \ - (option) == CURLOPT_DOH_URL || \ - (option) == CURLOPT_ECH || \ - (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_FTP_ACCOUNT || \ - (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ - (option) == CURLOPT_FTPPORT || \ - (option) == CURLOPT_HAPROXY_CLIENT_IP || \ - (option) == CURLOPT_HSTS || \ - (option) == CURLOPT_INTERFACE || \ - (option) == CURLOPT_ISSUERCERT || \ - (option) == CURLOPT_KEYPASSWD || \ - (option) == CURLOPT_KRBLEVEL || \ - (option) == CURLOPT_LOGIN_OPTIONS || \ - (option) == CURLOPT_MAIL_AUTH || \ - (option) == CURLOPT_MAIL_FROM || \ - (option) == CURLOPT_NETRC_FILE || \ - (option) == CURLOPT_NOPROXY || \ - (option) == CURLOPT_PASSWORD || \ - (option) == CURLOPT_PINNEDPUBLICKEY || \ - (option) == CURLOPT_PRE_PROXY || \ - (option) == CURLOPT_PROTOCOLS_STR || \ - (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_PROXY_CAINFO || \ - (option) == CURLOPT_PROXY_CAPATH || \ - (option) == CURLOPT_PROXY_CRLFILE || \ - (option) == CURLOPT_PROXY_ISSUERCERT || \ - (option) == CURLOPT_PROXY_KEYPASSWD || \ - (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \ - (option) == CURLOPT_PROXY_SERVICE_NAME || \ - (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ - (option) == CURLOPT_PROXY_SSLCERT || \ - (option) == CURLOPT_PROXY_SSLCERTTYPE || \ - (option) == CURLOPT_PROXY_SSLKEY || \ - (option) == CURLOPT_PROXY_SSLKEYTYPE || \ - (option) == CURLOPT_PROXY_TLS13_CIPHERS || \ - (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \ - (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \ - (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYUSERPWD || \ - (option) == CURLOPT_RANDOM_FILE || \ - (option) == CURLOPT_RANGE || \ - (option) == CURLOPT_REDIR_PROTOCOLS_STR || \ - (option) == CURLOPT_REFERER || \ - (option) == CURLOPT_REQUEST_TARGET || \ - (option) == CURLOPT_RTSP_SESSION_ID || \ - (option) == CURLOPT_RTSP_STREAM_URI || \ - (option) == CURLOPT_RTSP_TRANSPORT || \ - (option) == CURLOPT_SASL_AUTHZID || \ - (option) == CURLOPT_SERVICE_NAME || \ - (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 || \ - (option) == CURLOPT_SSH_KNOWNHOSTS || \ - (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ - (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ - (option) == CURLOPT_SSLCERT || \ - (option) == CURLOPT_SSLCERTTYPE || \ - (option) == CURLOPT_SSLENGINE || \ - (option) == CURLOPT_SSLKEY || \ - (option) == CURLOPT_SSLKEYTYPE || \ - (option) == CURLOPT_SSL_CIPHER_LIST || \ - (option) == CURLOPT_SSL_EC_CURVES || \ - (option) == CURLOPT_SSL_SIGNATURE_ALGORITHMS || \ - (option) == CURLOPT_TLS13_CIPHERS || \ - (option) == CURLOPT_TLSAUTH_PASSWORD || \ - (option) == CURLOPT_TLSAUTH_TYPE || \ - (option) == CURLOPT_TLSAUTH_USERNAME || \ - (option) == CURLOPT_UNIX_SOCKET_PATH || \ - (option) == CURLOPT_URL || \ - (option) == CURLOPT_USERAGENT || \ - (option) == CURLOPT_USERNAME || \ - (option) == CURLOPT_AWS_SIGV4 || \ - (option) == CURLOPT_USERPWD || \ - (option) == CURLOPT_XOAUTH2_BEARER || \ - 0) - -/* evaluates to true if option takes a curl_write_callback argument */ -#define curlcheck_write_cb_option(option) \ - ((option) == CURLOPT_HEADERFUNCTION || \ - (option) == CURLOPT_WRITEFUNCTION) - -/* evaluates to true if option takes a curl_conv_callback argument */ -#define curlcheck_conv_cb_option(option) \ - ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) - -/* evaluates to true if option takes a data argument to pass to a callback */ -#define curlcheck_cb_data_option(option) \ - ((option) == CURLOPT_CHUNK_DATA || \ - (option) == CURLOPT_CLOSESOCKETDATA || \ - (option) == CURLOPT_DEBUGDATA || \ - (option) == CURLOPT_FNMATCH_DATA || \ - (option) == CURLOPT_HEADERDATA || \ - (option) == CURLOPT_HSTSREADDATA || \ - (option) == CURLOPT_HSTSWRITEDATA || \ - (option) == CURLOPT_INTERLEAVEDATA || \ - (option) == CURLOPT_IOCTLDATA || \ - (option) == CURLOPT_OPENSOCKETDATA || \ - (option) == CURLOPT_PREREQDATA || \ - (option) == CURLOPT_XFERINFODATA || \ - (option) == CURLOPT_READDATA || \ - (option) == CURLOPT_SEEKDATA || \ - (option) == CURLOPT_SOCKOPTDATA || \ - (option) == CURLOPT_SSH_KEYDATA || \ - (option) == CURLOPT_SSL_CTX_DATA || \ - (option) == CURLOPT_WRITEDATA || \ - (option) == CURLOPT_RESOLVER_START_DATA || \ - (option) == CURLOPT_TRAILERDATA || \ - (option) == CURLOPT_SSH_HOSTKEYDATA || \ - 0) - -/* evaluates to true if option takes a POST data argument (void* or char*) */ -#define curlcheck_postfields_option(option) \ - ((option) == CURLOPT_POSTFIELDS || \ - (option) == CURLOPT_COPYPOSTFIELDS || \ - 0) - -/* evaluates to true if option takes a struct curl_slist * argument */ -#define curlcheck_slist_option(option) \ - ((option) == CURLOPT_HTTP200ALIASES || \ - (option) == CURLOPT_HTTPHEADER || \ - (option) == CURLOPT_MAIL_RCPT || \ - (option) == CURLOPT_POSTQUOTE || \ - (option) == CURLOPT_PREQUOTE || \ - (option) == CURLOPT_PROXYHEADER || \ - (option) == CURLOPT_QUOTE || \ - (option) == CURLOPT_RESOLVE || \ - (option) == CURLOPT_TELNETOPTIONS || \ - (option) == CURLOPT_CONNECT_TO || \ - 0) - -/* groups of curl_easy_getinfo infos that take the same type of argument */ - -/* evaluates to true if info expects a pointer to char * argument */ -#define curlcheck_string_info(info) \ - (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \ - (info) != CURLINFO_PRIVATE) - -/* evaluates to true if info expects a pointer to long argument */ -#define curlcheck_long_info(info) \ - (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) - -/* evaluates to true if info expects a pointer to double argument */ -#define curlcheck_double_info(info) \ - (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) - -/* true if info expects a pointer to struct curl_slist * argument */ -#define curlcheck_slist_info(info) \ - (((info) == CURLINFO_SSL_ENGINES) || \ - ((info) == CURLINFO_COOKIELIST)) - -/* true if info expects a pointer to struct curl_tlssessioninfo * argument */ -#define curlcheck_tlssessioninfo_info(info) \ - (((info) == CURLINFO_TLS_SSL_PTR) || \ - ((info) == CURLINFO_TLS_SESSION)) - -/* true if info expects a pointer to struct curl_certinfo * argument */ -#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO) - -/* true if info expects a pointer to struct curl_socket_t argument */ -#define curlcheck_socket_info(info) \ - (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T) - -/* true if info expects a pointer to curl_off_t argument */ -#define curlcheck_off_t_info(info) \ - (CURLINFO_OFF_T < (info)) - -/* - * typecheck helpers -- check whether given expression has requested type - */ - -/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros, - * otherwise define a new macro. Search for __builtin_types_compatible_p - * in the GCC manual. - * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is - * the actual expression passed to the curl_easy_setopt macro. This - * means that you can only apply the sizeof and __typeof__ operators, no - * == or whatsoever. - */ - -/* XXX: should evaluate to true if expr is a pointer */ -#define curlcheck_any_ptr(expr) \ - (sizeof(expr) == sizeof(void *)) - -/* evaluates to true if expr is NULL */ -/* XXX: must not evaluate expr, so this check is not accurate */ -#define curlcheck_NULL(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) - -/* evaluates to true if expr is type*, const type* or NULL */ -#define curlcheck_ptr(expr, type) \ - (curlcheck_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type *) || \ - __builtin_types_compatible_p(__typeof__(expr), const type *)) - -/* evaluates to true if expr is type**, const type** or NULL */ -#define curlcheck_ptrptr(expr, type) \ - (curlcheck_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type **) || \ - __builtin_types_compatible_p(__typeof__(expr), type *[]) || \ - __builtin_types_compatible_p(__typeof__(expr), const type *[]) || \ - __builtin_types_compatible_p(__typeof__(expr), const type **)) - -/* evaluates to true if expr is one of type[], type*, NULL or const type* */ -#define curlcheck_arr(expr, type) \ - (curlcheck_ptr((expr), type) || \ - __builtin_types_compatible_p(__typeof__(expr), type [])) - -/* evaluates to true if expr is a string */ -#define curlcheck_string(expr) \ - (curlcheck_arr((expr), char) || \ - curlcheck_arr((expr), signed char) || \ - curlcheck_arr((expr), unsigned char)) - -/* evaluates to true if expr is a CURL * */ -#define curlcheck_curl(expr) \ - (curlcheck_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), CURL *)) - -/* evaluates to true if expr is a long (no matter the signedness) - * XXX: for now, int is also accepted (and therefore short and char, which - * are promoted to int when passed to a variadic function) */ -#define curlcheck_long(expr) \ - ( \ - ((sizeof(long) != sizeof(int)) && \ - (__builtin_types_compatible_p(__typeof__(expr), long) || \ - __builtin_types_compatible_p(__typeof__(expr), signed long) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned long))) \ - || \ - ((sizeof(long) == sizeof(int)) && \ - (__builtin_types_compatible_p(__typeof__(expr), long) || \ - __builtin_types_compatible_p(__typeof__(expr), signed long) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ - __builtin_types_compatible_p(__typeof__(expr), int) || \ - __builtin_types_compatible_p(__typeof__(expr), signed int) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ - __builtin_types_compatible_p(__typeof__(expr), short) || \ - __builtin_types_compatible_p(__typeof__(expr), signed short) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ - __builtin_types_compatible_p(__typeof__(expr), char) || \ - __builtin_types_compatible_p(__typeof__(expr), signed char) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned char))) \ - ) - -/* evaluates to true if expr is of type curl_off_t */ -#define curlcheck_off_t(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) - -/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ -/* XXX: also check size of an char[] array? */ -#define curlcheck_error_buffer(expr) \ - (curlcheck_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), char *) || \ - __builtin_types_compatible_p(__typeof__(expr), char[])) - -/* evaluates to true if expr is of type (const) void* or (const) FILE* */ -#if 0 -#define curlcheck_cb_data(expr) \ - (curlcheck_ptr((expr), void) || \ - curlcheck_ptr((expr), FILE)) -#else /* be less strict */ -#define curlcheck_cb_data(expr) \ - curlcheck_any_ptr(expr) -#endif - -/* evaluates to true if expr is of type FILE* */ -#define curlcheck_FILE(expr) \ - (curlcheck_NULL(expr) || \ - (__builtin_types_compatible_p(__typeof__(expr), FILE *))) - -/* evaluates to true if expr can be passed as POST data (void* or char*) */ -#define curlcheck_postfields(expr) \ - (curlcheck_ptr((expr), void) || \ - curlcheck_arr((expr), char) || \ - curlcheck_arr((expr), unsigned char)) - -/* helper: __builtin_types_compatible_p distinguishes between functions and - * function pointers, hide it */ -#define curlcheck_cb_compatible(func, type) \ - (__builtin_types_compatible_p(__typeof__(func), type) || \ - __builtin_types_compatible_p(__typeof__(func) *, type)) - -/* evaluates to true if expr is of type curl_resolver_start_callback */ -#define curlcheck_resolver_start_callback(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_resolver_start_callback)) - -/* evaluates to true if expr is of type curl_read_callback or "similar" */ -#define curlcheck_read_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), __typeof__(fread) *) || \ - curlcheck_cb_compatible((expr), curl_read_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_read_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_read_callback2) || \ - curlcheck_cb_compatible((expr), Wcurl_read_callback3) || \ - curlcheck_cb_compatible((expr), Wcurl_read_callback4) || \ - curlcheck_cb_compatible((expr), Wcurl_read_callback5) || \ - curlcheck_cb_compatible((expr), Wcurl_read_callback6)) -typedef size_t (*Wcurl_read_callback1)(char *, size_t, size_t, void *); -typedef size_t (*Wcurl_read_callback2)(char *, size_t, size_t, const void *); -typedef size_t (*Wcurl_read_callback3)(char *, size_t, size_t, FILE *); -typedef size_t (*Wcurl_read_callback4)(void *, size_t, size_t, void *); -typedef size_t (*Wcurl_read_callback5)(void *, size_t, size_t, const void *); -typedef size_t (*Wcurl_read_callback6)(void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_write_callback or "similar" */ -#define curlcheck_write_cb(expr) \ - (curlcheck_read_cb(expr) || \ - curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \ - curlcheck_cb_compatible((expr), curl_write_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_write_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_write_callback2) || \ - curlcheck_cb_compatible((expr), Wcurl_write_callback3) || \ - curlcheck_cb_compatible((expr), Wcurl_write_callback4) || \ - curlcheck_cb_compatible((expr), Wcurl_write_callback5) || \ - curlcheck_cb_compatible((expr), Wcurl_write_callback6)) -typedef size_t (*Wcurl_write_callback1)(const char *, size_t, size_t, void *); -typedef size_t (*Wcurl_write_callback2)(const char *, size_t, size_t, - const void *); -typedef size_t (*Wcurl_write_callback3)(const char *, size_t, size_t, FILE *); -typedef size_t (*Wcurl_write_callback4)(const void *, size_t, size_t, void *); -typedef size_t (*Wcurl_write_callback5)(const void *, size_t, size_t, - const void *); -typedef size_t (*Wcurl_write_callback6)(const void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ -#define curlcheck_ioctl_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_ioctl_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_ioctl_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_ioctl_callback2) || \ - curlcheck_cb_compatible((expr), Wcurl_ioctl_callback3) || \ - curlcheck_cb_compatible((expr), Wcurl_ioctl_callback4)) -typedef curlioerr (*Wcurl_ioctl_callback1)(CURL *, int, void *); -typedef curlioerr (*Wcurl_ioctl_callback2)(CURL *, int, const void *); -typedef curlioerr (*Wcurl_ioctl_callback3)(CURL *, curliocmd, void *); -typedef curlioerr (*Wcurl_ioctl_callback4)(CURL *, curliocmd, const void *); - -/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ -#define curlcheck_sockopt_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_sockopt_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_sockopt_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_sockopt_callback2)) -typedef int (*Wcurl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); -typedef int (*Wcurl_sockopt_callback2)(const void *, curl_socket_t, - curlsocktype); - -/* evaluates to true if expr is of type curl_opensocket_callback or - "similar" */ -#define curlcheck_opensocket_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_opensocket_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_opensocket_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_opensocket_callback2) || \ - curlcheck_cb_compatible((expr), Wcurl_opensocket_callback3) || \ - curlcheck_cb_compatible((expr), Wcurl_opensocket_callback4)) -typedef curl_socket_t (*Wcurl_opensocket_callback1) - (void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (*Wcurl_opensocket_callback2) - (void *, curlsocktype, const struct curl_sockaddr *); -typedef curl_socket_t (*Wcurl_opensocket_callback3) - (const void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (*Wcurl_opensocket_callback4) - (const void *, curlsocktype, const struct curl_sockaddr *); - -/* evaluates to true if expr is of type curl_progress_callback or "similar" */ -#define curlcheck_progress_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_progress_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_progress_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_progress_callback2)) -typedef int (*Wcurl_progress_callback1)(void *, - double, double, double, double); -typedef int (*Wcurl_progress_callback2)(const void *, - double, double, double, double); - -/* evaluates to true if expr is of type curl_xferinfo_callback */ -#define curlcheck_xferinfo_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_xferinfo_callback)) - -/* evaluates to true if expr is of type curl_debug_callback or "similar" */ -#define curlcheck_debug_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_debug_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback2) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback3) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback4) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback5) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback6) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback7) || \ - curlcheck_cb_compatible((expr), Wcurl_debug_callback8)) -typedef int (*Wcurl_debug_callback1)(CURL *, - curl_infotype, char *, size_t, void *); -typedef int (*Wcurl_debug_callback2)(CURL *, - curl_infotype, char *, size_t, const void *); -typedef int (*Wcurl_debug_callback3)(CURL *, - curl_infotype, const char *, size_t, void *); -typedef int (*Wcurl_debug_callback4)(CURL *, - curl_infotype, const char *, size_t, const void *); -typedef int (*Wcurl_debug_callback5)(CURL *, - curl_infotype, unsigned char *, size_t, void *); -typedef int (*Wcurl_debug_callback6)(CURL *, - curl_infotype, unsigned char *, size_t, const void *); -typedef int (*Wcurl_debug_callback7)(CURL *, - curl_infotype, const unsigned char *, size_t, void *); -typedef int (*Wcurl_debug_callback8)(CURL *, - curl_infotype, const unsigned char *, size_t, const void *); - -/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ -/* this is getting even messier... */ -#define curlcheck_ssl_ctx_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback2) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback3) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback4) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback5) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback6) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback7) || \ - curlcheck_cb_compatible((expr), Wcurl_ssl_ctx_callback8)) -typedef CURLcode (*Wcurl_ssl_ctx_callback1)(CURL *, void *, void *); -typedef CURLcode (*Wcurl_ssl_ctx_callback2)(CURL *, void *, const void *); -typedef CURLcode (*Wcurl_ssl_ctx_callback3)(CURL *, const void *, void *); -typedef CURLcode (*Wcurl_ssl_ctx_callback4)(CURL *, const void *, - const void *); -#ifdef HEADER_SSL_H -/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX - * this of course breaks if we are included before OpenSSL headers... - */ -typedef CURLcode (*Wcurl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *); -typedef CURLcode (*Wcurl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *); -typedef CURLcode (*Wcurl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *); -typedef CURLcode (*Wcurl_ssl_ctx_callback8)(CURL *, const SSL_CTX *, - const void *); -#else -typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback5; -typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback6; -typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback7; -typedef Wcurl_ssl_ctx_callback1 Wcurl_ssl_ctx_callback8; -#endif - -/* evaluates to true if expr is of type curl_conv_callback or "similar" */ -#define curlcheck_conv_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_conv_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_conv_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_conv_callback2) || \ - curlcheck_cb_compatible((expr), Wcurl_conv_callback3) || \ - curlcheck_cb_compatible((expr), Wcurl_conv_callback4)) -typedef CURLcode (*Wcurl_conv_callback1)(char *, size_t length); -typedef CURLcode (*Wcurl_conv_callback2)(const char *, size_t length); -typedef CURLcode (*Wcurl_conv_callback3)(void *, size_t length); -typedef CURLcode (*Wcurl_conv_callback4)(const void *, size_t length); - -/* evaluates to true if expr is of type curl_seek_callback or "similar" */ -#define curlcheck_seek_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_seek_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_seek_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_seek_callback2)) -typedef CURLcode (*Wcurl_seek_callback1)(void *, curl_off_t, int); -typedef CURLcode (*Wcurl_seek_callback2)(const void *, curl_off_t, int); - -/* evaluates to true if expr is of type curl_chunk_bgn_callback */ -#define curlcheck_chunk_bgn_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_chunk_bgn_callback) || \ - curlcheck_cb_compatible((expr), Wcurl_chunk_bgn_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_chunk_bgn_callback2)) -typedef long (*Wcurl_chunk_bgn_callback1)(struct curl_fileinfo *, - void *, int); -typedef long (*Wcurl_chunk_bgn_callback2)(void *, void *, int); - -/* evaluates to true if expr is of type curl_chunk_end_callback */ -#define curlcheck_chunk_end_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_chunk_end_callback)) - -/* evaluates to true if expr is of type curl_closesocket_callback */ -#define curlcheck_close_socket_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_closesocket_callback)) - -/* evaluates to true if expr is of type curl_fnmatch_callback */ -#define curlcheck_fnmatch_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_fnmatch_callback)) - -/* evaluates to true if expr is of type curl_hstsread_callback */ -#define curlcheck_hstsread_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_hstsread_callback)) - -/* evaluates to true if expr is of type curl_hstswrite_callback */ -#define curlcheck_hstswrite_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_hstswrite_callback)) - -/* evaluates to true if expr is of type curl_sshhostkeycallback */ -#define curlcheck_ssh_hostkey_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_sshhostkeycallback)) - -/* evaluates to true if expr is of type curl_sshkeycallback */ -#define curlcheck_ssh_key_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_sshkeycallback)) - -/* evaluates to true if expr is of type curl_interleave_callback */ -#define curlcheck_interleave_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), Wcurl_interleave_callback1) || \ - curlcheck_cb_compatible((expr), Wcurl_interleave_callback2)) -typedef size_t (*Wcurl_interleave_callback1)(void *p, size_t s, - size_t n, void *u); -typedef size_t (*Wcurl_interleave_callback2)(char *p, size_t s, - size_t n, void *u); - -/* evaluates to true if expr is of type curl_prereq_callback */ -#define curlcheck_prereq_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_prereq_callback)) - -/* evaluates to true if expr is of type curl_trailer_callback */ -#define curlcheck_trailer_cb(expr) \ - (curlcheck_NULL(expr) || \ - curlcheck_cb_compatible((expr), curl_trailer_callback)) - -#endif /* CURLINC_TYPECHECK_GCC_H */ diff --git a/vendor/curl/include/curl/urlapi.h b/vendor/curl/include/curl/urlapi.h deleted file mode 100644 index b1f3a2316..000000000 --- a/vendor/curl/include/curl/urlapi.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef CURLINC_URLAPI_H -#define CURLINC_URLAPI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* the error codes for the URL API */ -typedef enum { - CURLUE_OK, - CURLUE_BAD_HANDLE, /* 1 */ - CURLUE_BAD_PARTPOINTER, /* 2 */ - CURLUE_MALFORMED_INPUT, /* 3 */ - CURLUE_BAD_PORT_NUMBER, /* 4 */ - CURLUE_UNSUPPORTED_SCHEME, /* 5 */ - CURLUE_URLDECODE, /* 6 */ - CURLUE_OUT_OF_MEMORY, /* 7 */ - CURLUE_USER_NOT_ALLOWED, /* 8 */ - CURLUE_UNKNOWN_PART, /* 9 */ - CURLUE_NO_SCHEME, /* 10 */ - CURLUE_NO_USER, /* 11 */ - CURLUE_NO_PASSWORD, /* 12 */ - CURLUE_NO_OPTIONS, /* 13 */ - CURLUE_NO_HOST, /* 14 */ - CURLUE_NO_PORT, /* 15 */ - CURLUE_NO_QUERY, /* 16 */ - CURLUE_NO_FRAGMENT, /* 17 */ - CURLUE_NO_ZONEID, /* 18 */ - CURLUE_BAD_FILE_URL, /* 19 */ - CURLUE_BAD_FRAGMENT, /* 20 */ - CURLUE_BAD_HOSTNAME, /* 21 */ - CURLUE_BAD_IPV6, /* 22 */ - CURLUE_BAD_LOGIN, /* 23 */ - CURLUE_BAD_PASSWORD, /* 24 */ - CURLUE_BAD_PATH, /* 25 */ - CURLUE_BAD_QUERY, /* 26 */ - CURLUE_BAD_SCHEME, /* 27 */ - CURLUE_BAD_SLASHES, /* 28 */ - CURLUE_BAD_USER, /* 29 */ - CURLUE_LACKS_IDN, /* 30 */ - CURLUE_TOO_LARGE, /* 31 */ - CURLUE_LAST -} CURLUcode; - -typedef enum { - CURLUPART_URL, - CURLUPART_SCHEME, - CURLUPART_USER, - CURLUPART_PASSWORD, - CURLUPART_OPTIONS, - CURLUPART_HOST, - CURLUPART_PORT, - CURLUPART_PATH, - CURLUPART_QUERY, - CURLUPART_FRAGMENT, - CURLUPART_ZONEID /* added in 7.65.0 */ -} CURLUPart; - -#define CURLU_DEFAULT_PORT (1 << 0) /* return default port number */ -#define CURLU_NO_DEFAULT_PORT (1 << 1) /* act as if no port number was set, - if the port number matches the - default for the scheme */ -#define CURLU_DEFAULT_SCHEME (1 << 2) /* return default scheme if - missing */ -#define CURLU_NON_SUPPORT_SCHEME (1 << 3) /* allow non-supported scheme */ -#define CURLU_PATH_AS_IS (1 << 4) /* leave dot sequences */ -#define CURLU_DISALLOW_USER (1 << 5) /* no user+password allowed */ -#define CURLU_URLDECODE (1 << 6) /* URL decode on get */ -#define CURLU_URLENCODE (1 << 7) /* URL encode on set */ -#define CURLU_APPENDQUERY (1 << 8) /* append a form style part */ -#define CURLU_GUESS_SCHEME (1 << 9) /* legacy curl-style guessing */ -#define CURLU_NO_AUTHORITY (1 << 10) /* Allow empty authority when the - scheme is unknown. */ -#define CURLU_ALLOW_SPACE (1 << 11) /* Allow spaces in the URL */ -#define CURLU_PUNYCODE (1 << 12) /* get the hostname in punycode */ -#define CURLU_PUNY2IDN (1 << 13) /* punycode => IDN conversion */ -#define CURLU_GET_EMPTY (1 << 14) /* allow empty queries and fragments - when extracting the URL or the - components */ -#define CURLU_NO_GUESS_SCHEME (1 << 15) /* for get, do not accept a guess */ - -typedef struct Curl_URL CURLU; - -/* - * curl_url() creates a new CURLU handle and returns a pointer to it. - * Must be freed with curl_url_cleanup(). - */ -CURL_EXTERN CURLU *curl_url(void); - -/* - * curl_url_cleanup() frees the CURLU handle and related resources used for - * the URL parsing. It does not free strings previously returned with the URL - * API. - */ -CURL_EXTERN void curl_url_cleanup(CURLU *u); - -/* - * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new - * handle must also be freed with curl_url_cleanup(). - */ -CURL_EXTERN CURLU *curl_url_dup(const CURLU *in); - -/* - * curl_url_get() extracts a specific part of the URL from a CURLU - * handle. Returns error code. The returned pointer MUST be freed with - * curl_free() afterwards. - */ -CURL_EXTERN CURLUcode curl_url_get(const CURLU *u, CURLUPart what, - char **part, unsigned int flags); - -/* - * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns - * error code. The passed in string is copied. Passing a NULL instead of - * a part string, clears that part. - */ -CURL_EXTERN CURLUcode curl_url_set(CURLU *u, CURLUPart what, - const char *part, unsigned int flags); - -/* - * curl_url_strerror() turns a CURLUcode value into the equivalent human - * readable error string. This is useful for printing meaningful error - * messages. - */ -CURL_EXTERN const char *curl_url_strerror(CURLUcode error); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif /* CURLINC_URLAPI_H */ diff --git a/vendor/curl/include/curl/websockets.h b/vendor/curl/include/curl/websockets.h deleted file mode 100644 index bf93715ab..000000000 --- a/vendor/curl/include/curl/websockets.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef CURLINC_WEBSOCKETS_H -#define CURLINC_WEBSOCKETS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -struct curl_ws_frame { - int age; /* zero */ - int flags; /* See the CURLWS_* defines */ - curl_off_t offset; /* the offset of this data into the frame */ - curl_off_t bytesleft; /* number of pending bytes left of the payload */ - size_t len; /* size of the current data chunk */ -}; - -/* flag bits */ -#define CURLWS_TEXT (1 << 0) -#define CURLWS_BINARY (1 << 1) -#define CURLWS_CONT (1 << 2) -#define CURLWS_CLOSE (1 << 3) -#define CURLWS_PING (1 << 4) -#define CURLWS_OFFSET (1 << 5) - -/* - * NAME curl_ws_recv() - * - * DESCRIPTION - * - * Receives data from the websocket connection. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, - size_t *recv, - const struct curl_ws_frame **metap); - -/* flags for curl_ws_send() */ -#define CURLWS_PONG (1 << 6) - -/* - * NAME curl_ws_send() - * - * DESCRIPTION - * - * Sends data over the websocket connection. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer_arg, - size_t buflen, size_t *sent, - curl_off_t fragsize, - unsigned int flags); - -/* - * NAME curl_ws_start_frame() - * - * DESCRIPTION - * - * Buffers a websocket frame header with the given flags and length. - * Errors when a previous frame is not complete, e.g. not all its - * payload has been added. - */ -CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl, - unsigned int flags, - curl_off_t frame_len); - -/* bits for the CURLOPT_WS_OPTIONS bitmask: */ -#define CURLWS_RAW_MODE (1L << 0) -#define CURLWS_NOAUTOPONG (1L << 1) - -CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl); - -#ifdef __cplusplus -} -#endif - -#endif /* CURLINC_WEBSOCKETS_H */ diff --git a/vendor/curl/lib/altsvc.c b/vendor/curl/lib/altsvc.c deleted file mode 100644 index 81b5379ad..000000000 --- a/vendor/curl/lib/altsvc.c +++ /dev/null @@ -1,684 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * The Alt-Svc: header is defined in RFC 7838: - * https://datatracker.ietf.org/doc/html/rfc7838 - */ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC) -#include "urldata.h" -#include "altsvc.h" -#include "curl_fopen.h" -#include "curl_get_line.h" -#include "parsedate.h" -#include "curl_trc.h" -#include "curlx/inet_pton.h" -#include "curlx/strparse.h" -#include "connect.h" - -#define MAX_ALTSVC_LINE 4095 -#define MAX_ALTSVC_DATELEN 17 -#define MAX_ALTSVC_HOSTLEN 2048 -#define MAX_ALTSVC_ALPNLEN 10 - -#define H3VERSION "h3" - -#if defined(DEBUGBUILD) || defined(UNITTESTS) -/* to play well with debug builds, we can *set* a fixed time this will - return */ -static time_t altsvc_debugtime(void *unused) -{ - const char *timestr = getenv("CURL_TIME"); - (void)unused; - if(timestr) { - curl_off_t val; - curlx_str_number(×tr, &val, TIME_T_MAX); - return (time_t)val; - } - return time(NULL); -} -#undef time -#define time(x) altsvc_debugtime(x) -#endif - -/* Given the ALPN ID, return the name */ -const char *Curl_alpnid2str(enum alpnid id) -{ - switch(id) { - case ALPN_h1: - return "h1"; - case ALPN_h2: - return "h2"; - case ALPN_h3: - return H3VERSION; - default: - return ""; /* bad */ - } -} - -#define altsvc_free(x) curlx_free(x) - -static struct altsvc *altsvc_createid(const char *srchost, - size_t hlen, - const char *dsthost, - size_t dlen, /* dsthost length */ - enum alpnid srcalpnid, - enum alpnid dstalpnid, - size_t srcport, - size_t dstport) -{ - struct altsvc *as; - if((hlen > 2) && srchost[0] == '[') { - /* IPv6 address, strip off brackets */ - srchost++; - hlen -= 2; - } - else if(hlen && (srchost[hlen - 1] == '.')) { - /* strip off trailing dot */ - hlen--; - } - if((dlen > 2) && dsthost[0] == '[') { - /* IPv6 address, strip off brackets */ - dsthost++; - dlen -= 2; - } - if(!hlen || !dlen) - /* bad input */ - return NULL; - /* struct size plus both strings */ - as = curlx_calloc(1, sizeof(struct altsvc) + (hlen + 1) + (dlen + 1)); - if(!as) - return NULL; - as->src.host = (char *)as + sizeof(struct altsvc); - memcpy(as->src.host, srchost, hlen); - /* the null terminator is already there */ - - as->dst.host = (char *)as + sizeof(struct altsvc) + hlen + 1; - memcpy(as->dst.host, dsthost, dlen); - /* the null terminator is already there */ - - as->src.alpnid = srcalpnid; - as->dst.alpnid = dstalpnid; - as->src.port = (unsigned short)srcport; - as->dst.port = (unsigned short)dstport; - - return as; -} - -static struct altsvc *altsvc_create(struct Curl_str *srchost, - struct Curl_str *dsthost, - struct Curl_str *srcalpn, - struct Curl_str *dstalpn, - size_t srcport, - size_t dstport) -{ - enum alpnid dstalpnid = Curl_str2alpnid(dstalpn); - enum alpnid srcalpnid = Curl_str2alpnid(srcalpn); - if(!srcalpnid || !dstalpnid) - return NULL; - return altsvc_createid(curlx_str(srchost), curlx_strlen(srchost), - curlx_str(dsthost), curlx_strlen(dsthost), - srcalpnid, dstalpnid, - srcport, dstport); -} - -/* append the new entry to the list after possibly removing an old entry - first */ -static void altsvc_append(struct altsvcinfo *asi, struct altsvc *as) -{ - while(Curl_llist_count(&asi->list) >= MAX_ALTSVC_ENTRIES) { - /* It's full. Remove the first entry in the list */ - struct Curl_llist_node *e = Curl_llist_head(&asi->list); - struct altsvc *oldas = Curl_node_elem(e); - Curl_node_remove(e); - altsvc_free(oldas); - } - Curl_llist_append(&asi->list, as, &as->node); -} - -/* only returns SERIOUS errors */ -static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line) -{ - /* Example line: - h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1 - */ - struct Curl_str srchost; - struct Curl_str dsthost; - struct Curl_str srcalpn; - struct Curl_str dstalpn; - struct Curl_str date; - curl_off_t srcport; - curl_off_t dstport; - curl_off_t persist; - curl_off_t prio; - - if(curlx_str_word(&line, &srcalpn, MAX_ALTSVC_ALPNLEN) || - curlx_str_singlespace(&line) || - curlx_str_word(&line, &srchost, MAX_ALTSVC_HOSTLEN) || - curlx_str_singlespace(&line) || - curlx_str_number(&line, &srcport, 65535) || - curlx_str_singlespace(&line) || - curlx_str_word(&line, &dstalpn, MAX_ALTSVC_ALPNLEN) || - curlx_str_singlespace(&line) || - curlx_str_word(&line, &dsthost, MAX_ALTSVC_HOSTLEN) || - curlx_str_singlespace(&line) || - curlx_str_number(&line, &dstport, 65535) || - curlx_str_singlespace(&line) || - curlx_str_quotedword(&line, &date, MAX_ALTSVC_DATELEN) || - curlx_str_singlespace(&line) || - curlx_str_number(&line, &persist, 1) || - curlx_str_singlespace(&line) || - curlx_str_number(&line, &prio, 0) || - curlx_str_newline(&line)) - ; - else { - char dbuf[MAX_ALTSVC_DATELEN + 1]; - time_t expires = 0; - time_t now = time(NULL); - - /* The date parser works on a null-terminated string. The maximum length - is upheld by curlx_str_quotedword(). */ - memcpy(dbuf, curlx_str(&date), curlx_strlen(&date)); - dbuf[curlx_strlen(&date)] = 0; - Curl_getdate_capped(dbuf, &expires); - - if(now < expires) { - struct altsvc *as = altsvc_create(&srchost, &dsthost, &srcalpn, &dstalpn, - (size_t)srcport, (size_t)dstport); - if(as) { - as->expires = expires; - as->persist = persist ? 1 : 0; - altsvc_append(asi, as); - } - else - return CURLE_OUT_OF_MEMORY; - } - } - - return CURLE_OK; -} - -/* - * Load alt-svc entries from the given file. The text based line-oriented file - * format is documented here: https://curl.se/docs/alt-svc.html - * - * This function only returns error on major problems that prevent alt-svc - * handling to work completely. It will ignore individual syntactical errors - * etc. - */ -static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) -{ - CURLcode result = CURLE_OK; - FILE *fp; - - /* we need a private copy of the filename so that the altsvc cache file - name survives an easy handle reset */ - curlx_free(asi->filename); - asi->filename = curlx_strdup(file); - if(!asi->filename) - return CURLE_OUT_OF_MEMORY; - - fp = curlx_fopen(file, FOPEN_READTEXT); - if(fp) { - curlx_struct_stat stat; - if((curlx_fstat(fileno(fp), &stat) == -1) || !S_ISDIR(stat.st_mode)) { - bool eof = FALSE; - struct dynbuf buf; - curlx_dyn_init(&buf, MAX_ALTSVC_LINE); - do { - result = Curl_get_line(&buf, fp, &eof); - if(!result) { - const char *lineptr = curlx_dyn_ptr(&buf); - curlx_str_passblanks(&lineptr); - if(curlx_str_single(&lineptr, '#')) - altsvc_add(asi, lineptr); - } - } while(!result && !eof); - curlx_dyn_free(&buf); /* free the line buffer */ - } - curlx_fclose(fp); - } - return result; -} - -/* - * Write this single altsvc entry to a single output line - */ -static CURLcode altsvc_out(struct altsvc *as, FILE *fp) -{ - struct tm stamp; - const char *dst6_pre = ""; - const char *dst6_post = ""; - const char *src6_pre = ""; - const char *src6_post = ""; - CURLcode result = curlx_gmtime(as->expires, &stamp); - if(result) - return result; -#ifdef USE_IPV6 - else { - char ipv6_unused[16]; - if(curlx_inet_pton(AF_INET6, as->dst.host, ipv6_unused) == 1) { - dst6_pre = "["; - dst6_post = "]"; - } - if(curlx_inet_pton(AF_INET6, as->src.host, ipv6_unused) == 1) { - src6_pre = "["; - src6_post = "]"; - } - } -#endif - curl_mfprintf(fp, - "%s %s%s%s %u " - "%s %s%s%s %u " - "\"%d%02d%02d " - "%02d:%02d:%02d\" " - "%d 0\n", /* prio still always zero */ - Curl_alpnid2str(as->src.alpnid), - src6_pre, as->src.host, src6_post, - as->src.port, - - Curl_alpnid2str(as->dst.alpnid), - dst6_pre, as->dst.host, dst6_post, - as->dst.port, - - stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, - stamp.tm_hour, stamp.tm_min, stamp.tm_sec, - as->persist); - return CURLE_OK; -} - -/* ---- library-wide functions below ---- */ - -/* - * Curl_altsvc_init() creates a new altsvc cache. - * It returns the new instance or NULL if something goes wrong. - */ -struct altsvcinfo *Curl_altsvc_init(void) -{ - struct altsvcinfo *asi = curlx_calloc(1, sizeof(struct altsvcinfo)); - if(!asi) - return NULL; - Curl_llist_init(&asi->list, NULL); - - /* set default behavior */ - asi->flags = CURLALTSVC_H1 -#ifdef USE_HTTP2 - | CURLALTSVC_H2 -#endif -#ifdef USE_HTTP3 - | CURLALTSVC_H3 -#endif - ; - return asi; -} - -/* - * Curl_altsvc_load() loads alt-svc from file. - */ -CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file) -{ - DEBUGASSERT(asi); - return altsvc_load(asi, file); -} - -/* - * Curl_altsvc_ctrl() passes on the external bitmask. - */ -CURLcode Curl_altsvc_ctrl(struct Curl_easy *data, const long ctrl) -{ - DEBUGASSERT(data); - if(!ctrl) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(!data->asi) { - data->asi = Curl_altsvc_init(); - if(!data->asi) - return CURLE_OUT_OF_MEMORY; - } - data->asi->flags = ctrl; - return CURLE_OK; -} - -/* - * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated - * resources. - */ -void Curl_altsvc_cleanup(struct altsvcinfo **asi) -{ - if(*asi) { - struct Curl_llist_node *e; - struct Curl_llist_node *n; - struct altsvcinfo *altsvc = *asi; - for(e = Curl_llist_head(&altsvc->list); e; e = n) { - struct altsvc *as = Curl_node_elem(e); - n = Curl_node_next(e); - altsvc_free(as); - } - curlx_free(altsvc->filename); - curlx_free(altsvc); - *asi = NULL; /* clear the pointer */ - } -} - -/* - * Curl_altsvc_save() writes the altsvc cache to a file. - */ -CURLcode Curl_altsvc_save(struct Curl_easy *data, - struct altsvcinfo *asi, const char *file) -{ - CURLcode result = CURLE_OK; - FILE *out; - char *tempstore = NULL; - - if(!asi) - /* no cache activated */ - return CURLE_OK; - - /* if not new name is given, use the one we stored from the load */ - if(!file && asi->filename) - file = asi->filename; - - if((asi->flags & CURLALTSVC_READONLYFILE) || !file || !file[0]) - /* marked as read-only, no file or zero length filename */ - return CURLE_OK; - - result = Curl_fopen(data, file, &out, &tempstore); - if(!result) { - struct Curl_llist_node *e; - struct Curl_llist_node *n; - fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n" - "# This file was generated by libcurl! Edit at your own risk.\n", - out); - for(e = Curl_llist_head(&asi->list); e; e = n) { - struct altsvc *as = Curl_node_elem(e); - n = Curl_node_next(e); - result = altsvc_out(as, out); - if(result) - break; - } - curlx_fclose(out); - if(!result && tempstore && curlx_rename(tempstore, file)) - result = CURLE_WRITE_ERROR; - - if(result && tempstore) - unlink(tempstore); - } - curlx_free(tempstore); - return result; -} - -/* hostcompare() returns true if 'host' matches 'check'. The first host - * argument may have a trailing dot present that will be ignored. - */ -static bool hostcompare(const char *host, const char *check) -{ - size_t hlen = strlen(host); - size_t clen = strlen(check); - - if(hlen && (host[hlen - 1] == '.')) - hlen--; - if(hlen != clen) - /* they cannot match if they have different lengths */ - return FALSE; - return curl_strnequal(host, check, hlen); -} - -/* altsvc_flush() removes all alternatives for this source origin from the - list */ -static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, - const char *srchost, unsigned short srcport) -{ - struct Curl_llist_node *e; - struct Curl_llist_node *n; - for(e = Curl_llist_head(&asi->list); e; e = n) { - struct altsvc *as = Curl_node_elem(e); - n = Curl_node_next(e); - if((srcalpnid == as->src.alpnid) && - (srcport == as->src.port) && - hostcompare(srchost, as->src.host)) { - Curl_node_remove(e); - altsvc_free(as); - } - } -} - -/* - * Curl_altsvc_parse() takes an incoming alt-svc response header and stores - * the data correctly in the cache. - * - * 'value' points to the header *value*. That is contents to the right of the - * header name. - * - * Currently this function rejects invalid data without returning an error. - * Invalid hostname, port number will result in the specific alternative - * being rejected. Unknown protocols are skipped. - */ -CURLcode Curl_altsvc_parse(struct Curl_easy *data, - struct altsvcinfo *asi, const char *value, - enum alpnid srcalpnid, const char *srchost, - unsigned short srcport) -{ - const char *p = value; - struct altsvc *as; - unsigned short dstport = srcport; /* the same by default */ - size_t entries = 0; - struct Curl_str alpn; - - DEBUGASSERT(asi); - - /* initial check for "clear" */ - if(!curlx_str_cspn(&p, &alpn, ";\n\r")) { - curlx_str_trimblanks(&alpn); - /* "clear" is a magic keyword */ - if(curlx_str_casecompare(&alpn, "clear")) { - /* Flush cached alternatives for this source origin */ - altsvc_flush(asi, srcalpnid, srchost, srcport); - return CURLE_OK; - } - } - - p = value; - - if(curlx_str_until(&p, &alpn, MAX_ALTSVC_LINE, '=')) - return CURLE_OK; /* strange line */ - - curlx_str_trimblanks(&alpn); - - do { - if(!curlx_str_single(&p, '=')) { - time_t maxage = 24 * 3600; /* default is 24 hours */ - bool persist = FALSE; - /* [protocol]="[host][:port], [protocol]="[host][:port]" */ - enum alpnid dstalpnid = Curl_str2alpnid(&alpn); - if(!curlx_str_single(&p, '\"')) { - struct Curl_str dsthost; - curl_off_t port = 0; - if(curlx_str_single(&p, ':')) { - /* hostname starts here */ - if(curlx_str_single(&p, '[')) { - if(curlx_str_until(&p, &dsthost, MAX_ALTSVC_HOSTLEN, ':')) { - infof(data, "Bad alt-svc hostname, ignoring."); - break; - } - } - else { - /* IPv6 hostname */ - if(curlx_str_until(&p, &dsthost, MAX_IPADR_LEN, ']') || - curlx_str_single(&p, ']')) { - infof(data, "Bad alt-svc IPv6 hostname, ignoring."); - break; - } - } - if(curlx_str_single(&p, ':')) - break; - } - else - /* no destination name, use source host */ - curlx_str_assign(&dsthost, srchost, strlen(srchost)); - - if(curlx_str_number(&p, &port, 0xffff)) { - infof(data, "Unknown alt-svc port number, ignoring."); - break; - } - - dstport = (unsigned short)port; - - if(curlx_str_single(&p, '\"')) - break; - - /* Handle the optional 'ma' and 'persist' flags. Unknown flags are - skipped. */ - curlx_str_passblanks(&p); - if(!curlx_str_single(&p, ';')) { - for(;;) { - struct Curl_str name; - struct Curl_str val; - const char *vp; - curl_off_t num; - bool quoted; - /* allow some extra whitespaces around name and value */ - if(curlx_str_until(&p, &name, 20, '=') || - curlx_str_single(&p, '=') || - curlx_str_cspn(&p, &val, ",;")) - break; - curlx_str_trimblanks(&name); - curlx_str_trimblanks(&val); - /* the value might be quoted */ - vp = curlx_str(&val); - quoted = (*vp == '\"'); - if(quoted) - vp++; - if(!curlx_str_number(&vp, &num, TIME_T_MAX)) { - if(curlx_str_casecompare(&name, "ma")) - maxage = (time_t)num; - else if(curlx_str_casecompare(&name, "persist") && (num == 1)) - persist = TRUE; - } - else - break; - p = vp; /* point to the byte ending the value */ - curlx_str_passblanks(&p); - if(quoted && curlx_str_single(&p, '\"')) - break; - curlx_str_passblanks(&p); - if(curlx_str_single(&p, ';')) - break; - } - } - if(dstalpnid) { - if(!entries++) - /* Flush cached alternatives for this source origin, if any - when - this is the first entry of the line. */ - altsvc_flush(asi, srcalpnid, srchost, srcport); - - as = altsvc_createid(srchost, strlen(srchost), - curlx_str(&dsthost), - curlx_strlen(&dsthost), - srcalpnid, dstalpnid, - srcport, dstport); - if(as) { - time_t secs = time(NULL); - /* The expires time also needs to take the Age: value (if any) - into account. [See RFC 7838 section 3.1] */ - if(maxage > (TIME_T_MAX - secs)) - as->expires = TIME_T_MAX; - else - as->expires = maxage + secs; - as->persist = persist; - altsvc_append(asi, as); - infof(data, "Added alt-svc: %.*s:%d over %s", - (int)curlx_strlen(&dsthost), curlx_str(&dsthost), - dstport, Curl_alpnid2str(dstalpnid)); - } - else - return CURLE_OUT_OF_MEMORY; - } - } - else - break; - - /* after the double quote there can be a comma if there is another - string or a semicolon if no more */ - if(curlx_str_single(&p, ',')) - break; - - /* comma means another alternative is present */ - if(curlx_str_until(&p, &alpn, MAX_ALTSVC_LINE, '=')) - break; - curlx_str_trimblanks(&alpn); - } - else - break; - } while(1); - - return CURLE_OK; -} - -/* - * Return TRUE on a match - */ -bool Curl_altsvc_lookup(struct altsvcinfo *asi, - enum alpnid srcalpnid, const char *srchost, - int srcport, - struct altsvc **dstentry, - const int versions, /* one or more bits */ - bool *psame_destination) -{ - struct Curl_llist_node *e; - struct Curl_llist_node *n; - time_t now = time(NULL); - DEBUGASSERT(asi); - DEBUGASSERT(srchost); - DEBUGASSERT(dstentry); - - *psame_destination = FALSE; - for(e = Curl_llist_head(&asi->list); e; e = n) { - struct altsvc *as = Curl_node_elem(e); - n = Curl_node_next(e); - if(as->expires < now) { - /* an expired entry, remove */ - Curl_node_remove(e); - altsvc_free(as); - continue; - } - if((as->src.alpnid == srcalpnid) && - hostcompare(srchost, as->src.host) && - (as->src.port == srcport) && - (versions & (int)as->dst.alpnid)) { - /* match */ - *dstentry = as; - *psame_destination = (srcport == as->dst.port) && - hostcompare(srchost, as->dst.host); - return TRUE; - } - } - return FALSE; -} - -#if defined(DEBUGBUILD) || defined(UNITTESTS) -#undef time -#endif - -#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */ diff --git a/vendor/curl/lib/altsvc.h b/vendor/curl/lib/altsvc.h deleted file mode 100644 index dc1740bce..000000000 --- a/vendor/curl/lib/altsvc.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef HEADER_CURL_ALTSVC_H -#define HEADER_CURL_ALTSVC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC) -#include "llist.h" - -/* the maximum number of alt-svc entries kept in a single cache */ -#define MAX_ALTSVC_ENTRIES 5000 - -struct althost { - char *host; - uint16_t port; - enum alpnid alpnid; -}; - -struct altsvc { - struct althost src; - struct althost dst; - time_t expires; - struct Curl_llist_node node; - BIT(persist); -}; - -struct altsvcinfo { - char *filename; - struct Curl_llist list; /* list of entries */ - long flags; /* the publicly set bitmask */ -}; - -const char *Curl_alpnid2str(enum alpnid id); -struct altsvcinfo *Curl_altsvc_init(void); -CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file); -CURLcode Curl_altsvc_save(struct Curl_easy *data, - struct altsvcinfo *asi, const char *file); -CURLcode Curl_altsvc_ctrl(struct Curl_easy *data, const long ctrl); -void Curl_altsvc_cleanup(struct altsvcinfo **asi); -CURLcode Curl_altsvc_parse(struct Curl_easy *data, - struct altsvcinfo *asi, const char *value, - enum alpnid srcalpnid, const char *srchost, - unsigned short srcport); -bool Curl_altsvc_lookup(struct altsvcinfo *asi, - enum alpnid srcalpnid, const char *srchost, - int srcport, - struct altsvc **dstentry, - const int versions, /* CURLALTSVC_H* bits */ - bool *psame_destination); -#else -/* disabled */ -#define Curl_altsvc_save(a, b, c) -#define Curl_altsvc_cleanup(x) -#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */ -#endif /* HEADER_CURL_ALTSVC_H */ diff --git a/vendor/curl/lib/amigaos.c b/vendor/curl/lib/amigaos.c deleted file mode 100644 index e4f3bfb77..000000000 --- a/vendor/curl/lib/amigaos.c +++ /dev/null @@ -1,239 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef __AMIGA__ - -#include "hostip.h" -#include "curl_addrinfo.h" -#include "amigaos.h" - -#ifdef HAVE_PROTO_BSDSOCKET_H -# ifdef __amigaos4__ -# include -# elif !defined(USE_AMISSL) -# include -# endif -# ifdef __libnix__ -# include -# endif -#endif - -#ifdef HAVE_PROTO_BSDSOCKET_H - -#ifdef __amigaos4__ -/* - * AmigaOS 4.x specific code - */ - -/* - * hostip4.c - Curl_ipv4_resolve_r() replacement code - * - * Logic that needs to be considered are the following build cases: - * - newlib networking - * - clib2 networking - * - direct bsdsocket.library networking (usually AmiSSL builds) - * Each with the threaded resolver enabled or not. - * - * With the threaded resolver enabled, try to use gethostbyname_r() where - * available, otherwise (re)open bsdsocket.library and fallback to - * gethostbyname(). - */ - -#include - -static struct SocketIFace *__CurlISocket = NULL; -static uint32 SocketFeatures = 0; - -#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01 -#define HAVE_BSDSOCKET_GETADDRINFO 0x02 - -CURLcode Curl_amiga_init(void) -{ - struct SocketIFace *ISocket; - struct Library *base = OpenLibrary("bsdsocket.library", 4); - - if(base) { - ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); - if(ISocket) { - ULONG enabled = 0; - - SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE, - SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled, - TAG_DONE); - - if(enabled) { - SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R; - } - - __CurlISocket = ISocket; - - atexit(Curl_amiga_cleanup); - - return CURLE_OK; - } - CloseLibrary(base); - } - - return CURLE_FAILED_INIT; -} - -void Curl_amiga_cleanup(void) -{ - if(__CurlISocket) { - struct Library *base = __CurlISocket->Data.LibBase; - DropInterface((struct Interface *)__CurlISocket); - CloseLibrary(base); - __CurlISocket = NULL; - } -} - -#ifdef CURLRES_AMIGA -/* - * Because we need to handle the different cases in hostip4.c at runtime, - * not at compile-time, based on what was detected in Curl_amiga_init(), - * we replace it completely with our own as to not complicate the baseline - * code. Assumes malloc/calloc/free are thread-safe because Curl_he2ai() - * allocates memory also. - */ - -struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, uint16_t port) -{ - struct Curl_addrinfo *ai = NULL; - struct hostent *h; - struct SocketIFace *ISocket = __CurlISocket; - - if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) { - LONG h_errnop = 0; - struct hostent *buf; - - buf = curlx_calloc(1, CURL_HOSTENT_SIZE); - if(buf) { - h = gethostbyname_r((STRPTR)hostname, buf, - (char *)buf + sizeof(struct hostent), - CURL_HOSTENT_SIZE - sizeof(struct hostent), - &h_errnop); - if(h) { - ai = Curl_he2ai(h, port); - } - curlx_free(buf); - } - } - else { -#ifdef USE_RESOLV_THREADED - /* gethostbyname() is not thread-safe, so we need to reopen bsdsocket - * on the thread's context - */ - struct Library *base = OpenLibrary("bsdsocket.library", 4); - if(base) { - ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); - if(ISocket) { - h = gethostbyname((STRPTR)hostname); - if(h) { - ai = Curl_he2ai(h, port); - } - DropInterface((struct Interface *)ISocket); - } - CloseLibrary(base); - } -#else - /* not using threaded resolver - safe to use this as-is */ - h = gethostbyname(hostname); - if(h) { - ai = Curl_he2ai(h, port); - } -#endif - } - - return ai; -} -#endif /* CURLRES_AMIGA */ - -#ifdef USE_AMISSL -#include -int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *errorfds, struct timeval *timeout) -{ - int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0); - /* Ensure Ctrl-C signal is actioned */ - if((r == -1) && (SOCKERRNO == SOCKEINTR)) - raise(SIGINT); - return r; -} -#endif /* USE_AMISSL */ - -#elif !defined(USE_AMISSL) /* __amigaos4__ */ -/* - * Amiga OS3 specific code - */ - -struct Library *SocketBase = NULL; - -#ifdef __libnix__ -void __request(const char *msg); -#define CURL_AMIGA_REQUEST(msg) __request(msg) -#else -#define CURL_AMIGA_REQUEST(msg) Printf((const unsigned char *)(msg "\n\a"), 0) -#endif - -void Curl_amiga_cleanup(void) -{ - if(SocketBase) { - CloseLibrary(SocketBase); - SocketBase = NULL; - } -} - -CURLcode Curl_amiga_init(void) -{ - if(!SocketBase) - SocketBase = OpenLibrary((const unsigned char *)"bsdsocket.library", 4); - - if(!SocketBase) { - CURL_AMIGA_REQUEST("No TCP/IP Stack running!"); - return CURLE_FAILED_INIT; - } - - if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG)&errno, - SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG)"curl", TAG_DONE)) { - CURL_AMIGA_REQUEST("SocketBaseTags ERROR"); - return CURLE_FAILED_INIT; - } - -#ifndef __libnix__ - atexit(Curl_amiga_cleanup); -#endif - - return CURLE_OK; -} - -#ifdef __libnix__ -ADD2EXIT(Curl_amiga_cleanup, -50); -#endif - -#endif /* !USE_AMISSL */ - -#endif /* HAVE_PROTO_BSDSOCKET_H */ - -#endif /* __AMIGA__ */ diff --git a/vendor/curl/lib/amigaos.h b/vendor/curl/lib/amigaos.h deleted file mode 100644 index 58278f093..000000000 --- a/vendor/curl/lib/amigaos.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef HEADER_CURL_AMIGAOS_H -#define HEADER_CURL_AMIGAOS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(__AMIGA__) && defined(HAVE_PROTO_BSDSOCKET_H) && \ - (!defined(USE_AMISSL) || defined(__amigaos4__)) - -CURLcode Curl_amiga_init(void); -void Curl_amiga_cleanup(void); - -#else - -#define Curl_amiga_init() CURLE_OK -#define Curl_amiga_cleanup() Curl_nop_stmt - -#endif - -#endif /* HEADER_CURL_AMIGAOS_H */ diff --git a/vendor/curl/lib/arpa_telnet.h b/vendor/curl/lib/arpa_telnet.h deleted file mode 100644 index b5faab419..000000000 --- a/vendor/curl/lib/arpa_telnet.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef HEADER_CURL_ARPA_TELNET_H -#define HEADER_CURL_ARPA_TELNET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_TELNET -/* - * Telnet option defines. Add more here if in need. - */ -#define CURL_TELOPT_BINARY 0 /* binary 8-bit data */ -#define CURL_TELOPT_ECHO 1 /* echo */ -#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */ -#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */ -#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */ -#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */ -#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */ -#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */ -#define CURL_NEW_ENV_VAR 0 -#define CURL_NEW_ENV_VALUE 1 - -#ifdef CURLVERBOSE -/* - * The telnet options represented as strings - */ -static const char * const telnetoptions[] = { - "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", - "NAME", "STATUS", "TIMING MARK", "RCTE", - "NAOL", "NAOP", "NAOCRD", "NAOHTS", - "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD", - "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", - "DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION", - "TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING", - "TTYLOC", "3270 REGIME", "X3 PAD", "NAWS", - "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC", - "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON" -}; -#define CURL_TELOPT(x) telnetoptions[x] -#else -#define CURL_TELOPT(x) "" -#endif - -#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON - -#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM) - -#define CURL_NTELOPTS 40 - -/* - * First some defines - */ -#define CURL_xEOF 236 /* End Of File */ -#define CURL_SE 240 /* Sub negotiation End */ -#define CURL_NOP 241 /* No OPeration */ -#define CURL_DM 242 /* Data Mark */ -#define CURL_GA 249 /* Go Ahead, reverse the line */ -#define CURL_SB 250 /* SuBnegotiation */ -#define CURL_WILL 251 /* Our side WILL use this option */ -#define CURL_WONT 252 /* Our side will not use this option */ -#define CURL_DO 253 /* DO use this option! */ -#define CURL_DONT 254 /* DO NOT use this option! */ -#define CURL_IAC 255 /* Interpret As Command */ - -#ifdef CURLVERBOSE -/* - * Then those numbers represented as strings: - */ -static const char * const telnetcmds[] = { - "EOF", "SUSP", "ABORT", "EOR", "SE", - "NOP", "DMARK", "BRK", "IP", "AO", - "AYT", "EC", "EL", "GA", "SB", - "WILL", "WONT", "DO", "DONT", "IAC" -}; -#endif - -#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */ -#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */ - -#define CURL_TELQUAL_IS 0 -#define CURL_TELQUAL_SEND 1 -#define CURL_TELQUAL_INFO 2 -#define CURL_TELQUAL_NAME 3 - -#define CURL_TELCMD_OK(x) \ - (((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \ - ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM)) - -#ifdef CURLVERBOSE -#define CURL_TELCMD(x) telnetcmds[(x) - CURL_TELCMD_MINIMUM] -#else -#define CURL_TELCMD(x) "" -#endif - -#endif /* CURL_DISABLE_TELNET */ - -#endif /* HEADER_CURL_ARPA_TELNET_H */ diff --git a/vendor/curl/lib/asyn-ares.c b/vendor/curl/lib/asyn-ares.c deleted file mode 100644 index a4a746428..000000000 --- a/vendor/curl/lib/asyn-ares.c +++ /dev/null @@ -1,828 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_RESOLV_ARES - -/*********************************************************************** - * Only for ares-enabled builds and only for functions that fulfill - * the asynch resolver backend API as defined in asyn.h, - * nothing else belongs in this file! - **********************************************************************/ - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "cfilters.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "hostip.h" -#include "url.h" -#include "multiif.h" -#include "curlx/inet_pton.h" -#include "connect.h" -#include "select.h" -#include "progress.h" -#include "curlx/timediff.h" -#include "httpsrr.h" -#include - -#if ARES_VERSION < 0x011000 -#error "requires c-ares 1.16.0 or newer" -#endif - -#ifdef USE_HTTPSRR -#if ARES_VERSION < 0x011c00 -#error "requires c-ares 1.28.0 or newer for HTTPSRR" -#endif -#define HTTPSRR_WORKS -#endif - -#define CARES_TIMEOUT_PER_ATTEMPT 2000 - -static int ares_ver = 0; - -static CURLcode async_ares_set_dns_servers(struct Curl_easy *data, - struct Curl_resolv_async *async); -static CURLcode async_ares_set_dns_interface(struct Curl_easy *data, - struct Curl_resolv_async *async); -static CURLcode async_ares_set_dns_local_ip4(struct Curl_easy *data, - struct Curl_resolv_async *async); -static CURLcode async_ares_set_dns_local_ip6(struct Curl_easy *data, - struct Curl_resolv_async *async); - -/* - * Curl_async_global_init() - the generic low-level asynchronous name - * resolve API. Called from curl_global_init() to initialize global resolver - * environment. Initializes ares library. - */ -int Curl_async_global_init(void) -{ -#ifdef CARES_HAVE_ARES_LIBRARY_INIT - if(ares_library_init(ARES_LIB_INIT_ALL)) { - return CURLE_FAILED_INIT; - } -#endif - ares_version(&ares_ver); - return CURLE_OK; -} - -/* - * Curl_async_global_cleanup() - * - * Called from curl_global_cleanup() to destroy global resolver environment. - * Deinitializes ares library. - */ -void Curl_async_global_cleanup(void) -{ -#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP - ares_library_cleanup(); -#endif -} - -static void sock_state_cb(void *data, ares_socket_t socket_fd, - int readable, int writable) -{ - struct Curl_easy *easy = data; - if(!readable && !writable) { - DEBUGASSERT(easy); - Curl_multi_will_close(easy, socket_fd); - } -} - -static CURLcode async_ares_init(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct async_ares_ctx *ares = &async->ares; - int status; - struct ares_options options; - int optmask = ARES_OPT_SOCK_STATE_CB; - CURLcode result = CURLE_OK; - - /* initial status - failed */ - ares->ares_status = ARES_ENOTFOUND; - async->queries_ongoing = 0; - - options.sock_state_cb = sock_state_cb; - options.sock_state_cb_data = data; - - DEBUGASSERT(!ares->channel); - /* - if c ares < 1.20.0: curl set timeout to CARES_TIMEOUT_PER_ATTEMPT (2s) - - if c-ares >= 1.20.0 it already has the timeout to 2s, curl does not need - to set the timeout value; - - if c-ares >= 1.24.0, user can set the timeout via /etc/resolv.conf to - overwrite c-ares' timeout. - */ - DEBUGASSERT(ares_ver); - if(ares_ver < 0x011400) { - options.timeout = CARES_TIMEOUT_PER_ATTEMPT; - optmask |= ARES_OPT_TIMEOUTMS; - } - - status = ares_init_options(&ares->channel, &options, optmask); - if(status != ARES_SUCCESS) { - ares->channel = NULL; - result = (status == ARES_ENOMEM) ? CURLE_OUT_OF_MEMORY : CURLE_FAILED_INIT; - goto out; - } - - result = async_ares_set_dns_servers(data, async); - if(result && result != CURLE_NOT_BUILT_IN) - goto out; - - result = async_ares_set_dns_interface(data, async); - if(result && result != CURLE_NOT_BUILT_IN) - goto out; - - result = async_ares_set_dns_local_ip4(data, async); - if(result && result != CURLE_NOT_BUILT_IN) - goto out; - - result = async_ares_set_dns_local_ip6(data, async); - if(result && result != CURLE_NOT_BUILT_IN) - goto out; - - result = CURLE_OK; - -out: - if(result && ares->channel) { - ares_destroy(ares->channel); - ares->channel = NULL; - } - return result; -} - -/* - * async_ares_cleanup() cleans up async resolver data. - */ -static void async_ares_cleanup(struct Curl_resolv_async *async) -{ - struct async_ares_ctx *ares = &async->ares; - if(ares->res_A) { - Curl_freeaddrinfo(ares->res_A); - ares->res_A = NULL; - } - if(ares->res_AAAA) { - Curl_freeaddrinfo(ares->res_AAAA); - ares->res_AAAA = NULL; - } -#ifdef USE_HTTPSRR - Curl_httpsrr_cleanup(&ares->hinfo); -#endif -} - -void Curl_async_ares_shutdown(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - /* c-ares has a method to "cancel" operations on a channel, but - * as reported in #18216, this does not totally reset the channel - * and ares may get stuck. - * We need to destroy the channel and on demand create a new - * one to avoid that. */ - Curl_async_ares_destroy(data, async); -} - -void Curl_async_ares_destroy(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct async_ares_ctx *ares = &async->ares; - (void)data; - if(ares->channel) { - ares_destroy(ares->channel); - ares->channel = NULL; - } - async_ares_cleanup(async); -} - -CURLcode Curl_async_pollset(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct easy_pollset *ps) -{ - struct async_ares_ctx *ares = &async->ares; - CURLcode result = CURLE_OK; - - if(ares->channel) { - result = Curl_ares_pollset(data, ares->channel, ps); - if(!result) { - timediff_t ms = Curl_ares_timeout_ms(data, async, ares->channel); - Curl_expire(data, ms, EXPIRE_ASYNC_NAME); - } - } - return result; -} - -/* - * Curl_async_take_result() is called repeatedly to check if a previous - * name resolve request has completed. It should also make sure to time-out if - * the operation seems to take too long. - * - * Returns normal CURLcode errors. - */ -CURLcode Curl_async_take_result(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct Curl_dns_entry **pdns) -{ - struct async_ares_ctx *ares = &async->ares; - CURLcode result = CURLE_OK; - - DEBUGASSERT(pdns); - *pdns = NULL; - if(!ares) - return CURLE_FAILED_INIT; - - if(Curl_ares_perform(ares->channel, 0) < 0) { - result = CURLE_UNRECOVERABLE_POLL; - goto out; - } - - if(async->queries_ongoing) { - result = CURLE_AGAIN; - goto out; - } - - /* all c-ares operations done, what is the result to report? */ - result = ares->result; - if(ares->ares_status == ARES_SUCCESS && !result) { - struct Curl_dns_entry *dns = - Curl_dnscache_mk_entry2(data, async->dns_queries, - &ares->res_AAAA, &ares->res_A, - async->hostname, async->port); - if(!dns) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } -#ifdef HTTPSRR_WORKS - if(async->dns_queries & CURL_DNSQ_HTTPS) { - if(ares->hinfo.complete) { - struct Curl_https_rrinfo *lhrr = Curl_httpsrr_dup_move(&ares->hinfo); - if(!lhrr) - result = CURLE_OUT_OF_MEMORY; - else - Curl_dns_entry_set_https_rr(dns, lhrr); - } - else - Curl_dns_entry_set_https_rr(dns, NULL); - } -#endif - if(!result) { - *pdns = dns; - } - } - /* if we have not found anything, report the proper - * CURLE_COULDNT_RESOLVE_* code */ - if(!result && !*pdns) { - const char *msg = NULL; - if(ares->ares_status != ARES_SUCCESS) - msg = ares_strerror(ares->ares_status); - result = Curl_async_failed(data, async, msg); - } - - CURL_TRC_DNS(data, "ares: is_resolved() result=%d, dns=%sfound", - result, *pdns ? "" : "not "); - async_ares_cleanup(async); - -out: - if(result != CURLE_AGAIN) - ares->result = result; - return result; -} - -static timediff_t async_ares_poll_timeout(struct async_ares_ctx *ares, - timediff_t timeout_ms) -{ - struct timeval *ares_calced, time_buf, max_timeout; - int itimeout_ms; - -#if TIMEDIFF_T_MAX > INT_MAX - itimeout_ms = (timeout_ms > INT_MAX) ? INT_MAX : - ((timeout_ms < 0) ? -1 : (int)timeout_ms); -#else - itimeout_ms = (int)timeout_ms; -#endif - max_timeout.tv_sec = itimeout_ms / 1000; - max_timeout.tv_usec = (itimeout_ms % 1000) * 1000; - - /* c-ares tells us the shortest timeout of any operation on channel */ - ares_calced = ares_timeout(ares->channel, &max_timeout, &time_buf); - /* use the timeout period ares returned to us above if less than one - second is left, otherwise use 1000ms to make sure the progress callback - gets called frequent enough */ - if(!ares_calced->tv_sec) - return (timediff_t)(ares_calced->tv_usec / 1000); - else - return 1000; -} - -static const struct Curl_addrinfo *async_ares_get_ai( - const struct Curl_addrinfo *ai, - int ai_family, - unsigned int index) -{ - unsigned int i = 0; - for(i = 0; ai; ai = ai->ai_next) { - if(ai->ai_family == ai_family) { - if(i == index) - return ai; - ++i; - } - } - return NULL; -} - -const struct Curl_addrinfo *Curl_async_get_ai(struct Curl_easy *data, - struct Curl_resolv_async *async, - int ai_family, - unsigned int index) -{ - struct async_ares_ctx *ares = &async->ares; - - (void)data; - switch(ai_family) { - case AF_INET: - if(ares->res_A) - return async_ares_get_ai(ares->res_A, ai_family, index); - break; - case AF_INET6: - if(ares->res_AAAA) - return async_ares_get_ai(ares->res_AAAA, ai_family, index); - break; - default: - break; - } - return NULL; -} - -#ifdef USE_HTTPSRR -const struct Curl_https_rrinfo *Curl_async_get_https( - struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - if(Curl_async_knows_https(data, async)) - return &async->ares.hinfo; - return NULL; -} - -bool Curl_async_knows_https(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - (void)data; - if(async->dns_queries & CURL_DNSQ_HTTPS) - return ((async->dns_responses & CURL_DNSQ_HTTPS) || - !async->queries_ongoing); - return TRUE; /* we know it will never come */ -} - -#endif /* USE_HTTPSRR */ - -/* - * Curl_async_await() - * - * Waits for a resolve to finish. This function should be avoided since using - * this risk getting the multi interface to "hang". - * - * 'pdns' MUST be non-NULL. - * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, - * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. - */ -CURLcode Curl_async_await(struct Curl_easy *data, uint32_t resolv_id, - struct Curl_dns_entry **pdns) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - struct async_ares_ctx *ares = async ? &async->ares : NULL; - struct curltime start = *Curl_pgrs_now(data); - CURLcode result = CURLE_OK; - - DEBUGASSERT(pdns); - *pdns = NULL; /* clear on entry */ - - if(!ares) - return CURLE_FAILED_INIT; - - /* Wait for the name resolve query to complete or time out. */ - while(!result) { - timediff_t timeout_ms; - - timeout_ms = Curl_timeleft_ms(data); - if(!timeout_ms) { /* no applicable timeout from `data`*/ - timediff_t elapsed_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &start); - if(elapsed_ms < CURL_TIMEOUT_RESOLVE_MS) - timeout_ms = CURL_TIMEOUT_RESOLVE_MS - elapsed_ms; - else - timeout_ms = -1; - } - - if(timeout_ms < 0) { - result = CURLE_OPERATION_TIMEDOUT; - break; - } - - if(Curl_ares_perform(ares->channel, - async_ares_poll_timeout(ares, timeout_ms)) < 0) { - result = CURLE_UNRECOVERABLE_POLL; - break; - } - - result = Curl_async_take_result(data, async, pdns); - if(result == CURLE_AGAIN) - result = CURLE_OK; - else if(result || *pdns) - break; - - if(Curl_pgrsUpdate(data)) { - result = CURLE_ABORTED_BY_CALLBACK; - break; - } - } - - if(result) - ares_cancel(ares->channel); - return result; -} - -/* - * async_ares_node2addr() converts an address list provided by c-ares - * to an internal libcurl compatible list. - */ -static struct Curl_addrinfo *async_ares_node2addr( - struct ares_addrinfo_node *node) -{ - /* traverse the ares_addrinfo_node list */ - struct ares_addrinfo_node *ai; - struct Curl_addrinfo *cafirst = NULL; - struct Curl_addrinfo *calast = NULL; - int error = 0; - - for(ai = node; ai != NULL; ai = ai->ai_next) { - size_t ss_size; - struct Curl_addrinfo *ca; - /* ignore elements with unsupported address family, - settle family-specific sockaddr structure size. */ - if(ai->ai_family == AF_INET) - ss_size = sizeof(struct sockaddr_in); -#ifdef USE_IPV6 - else if(ai->ai_family == AF_INET6) - ss_size = sizeof(struct sockaddr_in6); -#endif - else - continue; - - /* ignore elements without required address info */ - if(!ai->ai_addr || !(ai->ai_addrlen > 0)) - continue; - - /* ignore elements with bogus address size */ - if((size_t)ai->ai_addrlen < ss_size) - continue; - - ca = curlx_malloc(sizeof(struct Curl_addrinfo) + ss_size); - if(!ca) { - error = EAI_MEMORY; - break; - } - - /* copy each structure member individually, member ordering, - size, or padding might be different for each platform. */ - - ca->ai_flags = ai->ai_flags; - ca->ai_family = ai->ai_family; - ca->ai_socktype = ai->ai_socktype; - ca->ai_protocol = ai->ai_protocol; - ca->ai_addrlen = (curl_socklen_t)ss_size; - ca->ai_addr = NULL; - ca->ai_canonname = NULL; - ca->ai_next = NULL; - - ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); - memcpy(ca->ai_addr, ai->ai_addr, ss_size); - - /* if the return list is empty, this becomes the first element */ - if(!cafirst) - cafirst = ca; - - /* add this element last in the return list */ - if(calast) - calast->ai_next = ca; - calast = ca; - } - - /* if we failed, destroy the Curl_addrinfo list */ - if(error) { - Curl_freeaddrinfo(cafirst); - cafirst = NULL; - } - - return cafirst; -} - -static void async_ares_A_cb(void *user_data, int status, int timeouts, - struct ares_addrinfo *ares_ai) -{ - struct Curl_resolv_async *async = user_data; - struct async_ares_ctx *ares = async ? &async->ares : NULL; - - (void)timeouts; - if(!async) - return; - - async->dns_responses |= CURL_DNSQ_A; - async->queries_ongoing--; - async->done = !async->queries_ongoing; - if(status == ARES_SUCCESS) { - ares->ares_status = ARES_SUCCESS; - ares->res_A = async_ares_node2addr(ares_ai->nodes); - ares_freeaddrinfo(ares_ai); - } - else if(ares->ares_status != ARES_SUCCESS) /* do not overwrite success */ - ares->ares_status = status; -} - -#ifdef CURLRES_IPV6 -static void async_ares_AAAA_cb(void *user_data, int status, int timeouts, - struct ares_addrinfo *ares_ai) -{ - struct Curl_resolv_async *async = user_data; - struct async_ares_ctx *ares = async ? &async->ares : NULL; - - (void)timeouts; - if(!async) - return; - - async->dns_responses |= CURL_DNSQ_AAAA; - async->queries_ongoing--; - async->done = !async->queries_ongoing; - if(status == ARES_SUCCESS) { - ares->ares_status = ARES_SUCCESS; - ares->res_AAAA = async_ares_node2addr(ares_ai->nodes); - ares_freeaddrinfo(ares_ai); - } - else if(ares->ares_status != ARES_SUCCESS) /* do not overwrite success */ - ares->ares_status = status; -} -#endif /* CURLRES_IPV6 */ - -#ifdef USE_HTTPSRR -static void async_ares_rr_done(void *user_data, ares_status_t status, - size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - struct Curl_resolv_async *async = user_data; - struct async_ares_ctx *ares = async ? &async->ares : NULL; - - if(!async) - return; - - (void)timeouts; - async->dns_responses |= CURL_DNSQ_HTTPS; - async->queries_ongoing--; - async->done = !async->queries_ongoing; - if((ARES_SUCCESS != status) || !dnsrec) - return; - ares->result = Curl_httpsrr_from_ares(dnsrec, &ares->hinfo); -} -#endif /* USE_HTTPSRR */ - -/* - * Curl_async_getaddrinfo() - when using ares - * - * Starts a name resolve for the given hostname and port number. - */ -CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct async_ares_ctx *ares = &async->ares; - char service[12]; - int socktype; - CURLcode result = CURLE_OK; - - if(ares->channel) { - DEBUGASSERT(0); - result = CURLE_FAILED_INIT; - goto out; - } - - result = async_ares_init(data, async); - if(result) - goto out; - - result = Curl_resolv_announce_start(data, ares->channel); - if(result) - goto out; - -#if defined(CURLVERBOSE) && ARES_VERSION >= 0x011800 /* >= v1.24.0 */ - if(CURL_TRC_DNS_is_verbose(data)) { - char *csv = ares_get_servers_csv(ares->channel); - CURL_TRC_DNS(data, "ares: servers=%s", csv); - ares_free_string(csv); - } -#endif - - curl_msnprintf(service, sizeof(service), "%d", async->port); - socktype = - (Curl_conn_get_transport(data, data->conn) == TRNSPRT_TCP) ? - SOCK_STREAM : SOCK_DGRAM; - -#ifdef CURLRES_IPV6 - if(async->dns_queries & CURL_DNSQ_AAAA) { - struct ares_addrinfo_hints hints; - - memset(&hints, 0, sizeof(hints)); - CURL_TRC_DNS(data, "ares: query AAAA records for %s", async->hostname); - hints.ai_family = PF_INET6; - hints.ai_socktype = socktype; - hints.ai_flags = ARES_AI_NUMERICSERV; - async->queries_ongoing++; - ares_getaddrinfo(ares->channel, async->hostname, - service, &hints, async_ares_AAAA_cb, async); - } -#endif /* CURLRES_IPV6 */ - - if(async->dns_queries & CURL_DNSQ_A) { - struct ares_addrinfo_hints hints; - - memset(&hints, 0, sizeof(hints)); - CURL_TRC_DNS(data, "ares: query A records for %s", async->hostname); - hints.ai_family = PF_INET; - hints.ai_socktype = socktype; - hints.ai_flags = ARES_AI_NUMERICSERV; - async->queries_ongoing++; - ares_getaddrinfo(ares->channel, async->hostname, - service, &hints, async_ares_A_cb, async); - } - -#ifdef USE_HTTPSRR - memset(&ares->hinfo, 0, sizeof(ares->hinfo)); - if(async->dns_queries & CURL_DNSQ_HTTPS) { - char *rrname = NULL; - if(async->port != 443) { - rrname = curl_maprintf("_%d._https.%s", async->port, async->hostname); - if(!rrname) - return CURLE_OUT_OF_MEMORY; - } - CURL_TRC_DNS(data, "ares: query HTTPS records for %s", - rrname ? rrname : async->hostname); - ares->hinfo.rrname = rrname; - async->queries_ongoing++; - ares_query_dnsrec(ares->channel, - rrname ? rrname : async->hostname, - ARES_CLASS_IN, ARES_REC_TYPE_HTTPS, - async_ares_rr_done, async, NULL); - } -#endif /* USE_HTTPSRR */ - -out: - ares->result = result; - return result ? result : (async->queries_ongoing ? CURLE_AGAIN : CURLE_OK); -} - -/* Set what DNS server are is to use. This is called in 2 situations: - * 1. when the application does 'CURLOPT_DNS_SERVERS' and passing NULL - * means any previous set value should be unset. Which means - * we need to destroy and create the are channel anew, if there is one. - * 2. When we lazy init the ares channel and NULL means that there - * are no preferences and we do not reset any existing channel. */ -static CURLcode async_ares_set_dns_servers(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct async_ares_ctx *ares = async ? &async->ares : NULL; - CURLcode result = CURLE_NOT_BUILT_IN; - const char *servers = data->set.str[STRING_DNS_SERVERS]; - int ares_result = ARES_SUCCESS; - -#ifdef DEBUGBUILD - if(getenv("CURL_DNS_SERVER")) - servers = getenv("CURL_DNS_SERVER"); -#endif - - if(!servers) - return CURLE_OK; - - /* if channel is not there, this is a parameter check */ - if(ares && ares->channel) - ares_result = ares_set_servers_ports_csv(ares->channel, servers); - switch(ares_result) { - case ARES_SUCCESS: - result = CURLE_OK; - break; - case ARES_ENOMEM: - result = CURLE_OUT_OF_MEMORY; - break; - case ARES_ENOTINITIALIZED: - case ARES_ENODATA: - case ARES_EBADSTR: - default: - DEBUGF(infof(data, "bad servers set")); - result = CURLE_BAD_FUNCTION_ARGUMENT; - break; - } - return result; -} - -static CURLcode async_ares_set_dns_interface(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct async_ares_ctx *ares = async ? &async->ares : NULL; - const char *interf = data->set.str[STRING_DNS_INTERFACE]; - - if(!interf) - interf = ""; - - /* if channel is not there, this is a parameter check */ - if(ares && ares->channel) - ares_set_local_dev(ares->channel, interf); - - return CURLE_OK; -} - -static CURLcode async_ares_set_dns_local_ip4(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct async_ares_ctx *ares = async ? &async->ares : NULL; - struct in_addr a4; - const char *local_ip4 = data->set.str[STRING_DNS_LOCAL_IP4]; - - if(!local_ip4 || (local_ip4[0] == 0)) { - a4.s_addr = 0; /* disabled: do not bind to a specific address */ - } - else { - if(curlx_inet_pton(AF_INET, local_ip4, &a4) != 1) { - DEBUGF(infof(data, "bad DNS IPv4 address")); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - - /* if channel is not there yet, this is a parameter check */ - if(ares && ares->channel) - ares_set_local_ip4(ares->channel, ntohl(a4.s_addr)); - - return CURLE_OK; -} - -static CURLcode async_ares_set_dns_local_ip6(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ -#ifdef USE_IPV6 - struct async_ares_ctx *ares = async ? &async->ares : NULL; - unsigned char a6[INET6_ADDRSTRLEN]; - const char *local_ip6 = data->set.str[STRING_DNS_LOCAL_IP6]; - - if(!local_ip6 || (local_ip6[0] == 0)) { - /* disabled: do not bind to a specific address */ - memset(a6, 0, sizeof(a6)); - } - else { - if(curlx_inet_pton(AF_INET6, local_ip6, a6) != 1) { - DEBUGF(infof(data, "bad DNS IPv6 address")); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - - /* if channel is not there, this is a parameter check */ - if(ares && ares->channel) - ares_set_local_ip6(ares->channel, a6); - - return CURLE_OK; -#else /* no IPv6 support */ - (void)data; - (void)async; - return CURLE_NOT_BUILT_IN; -#endif -} - -#endif /* USE_RESOLV_ARES */ diff --git a/vendor/curl/lib/asyn-base.c b/vendor/curl/lib/asyn-base.c deleted file mode 100644 index 62cb0effe..000000000 --- a/vendor/curl/lib/asyn-base.c +++ /dev/null @@ -1,265 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef USE_ARES -#include -#endif - -#include "urldata.h" -#include "connect.h" -#include "curl_trc.h" -#include "hostip.h" -#include "multiif.h" -#include "progress.h" -#include "select.h" -#include "url.h" - -/*********************************************************************** - * Only for builds using asynchronous name resolves - **********************************************************************/ -#ifdef CURLRES_ASYNCH - -timediff_t Curl_async_timeleft_ms(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - if(async->timeout_ms) { - timediff_t elapsed_ms = - curlx_ptimediff_ms(Curl_pgrs_now(data), &async->start); - return async->timeout_ms - elapsed_ms; - } - return Curl_timeleft_ms(data); -} - -#ifdef USE_ARES - -#if ARES_VERSION < 0x011000 -#error "requires c-ares 1.16.0 or newer" -#endif - -/* - * Curl_ares_pollset() is called when the outside world (using - * curl_multi_fdset()) wants to get our fd_set setup and we are talking with - * ares. The caller must make sure that this function is only called when we - * have a working ares channel. - * - * Returns: sockets-in-use-bitmap - */ -CURLcode Curl_ares_pollset(struct Curl_easy *data, - ares_channel channel, - struct easy_pollset *ps) -{ - curl_socket_t sockets[16]; /* ARES documented limit */ - unsigned int bitmap, i; - CURLcode result = CURLE_OK; - - DEBUGASSERT(channel); - if(!channel) - return CURLE_FAILED_INIT; - - bitmap = ares_getsock(channel, (ares_socket_t *)sockets, - CURL_ARRAYSIZE(sockets)); - for(i = 0; i < CURL_ARRAYSIZE(sockets); ++i) { - int flags = 0; - if(ARES_GETSOCK_READABLE(bitmap, i)) - flags |= CURL_POLL_IN; - if(ARES_GETSOCK_WRITABLE(bitmap, i)) - flags |= CURL_POLL_OUT; - if(!flags) - break; - result = Curl_pollset_change(data, ps, sockets[i], flags, 0); - if(result) - return result; - } - return result; -} - -timediff_t Curl_ares_timeout_ms(struct Curl_easy *data, - struct Curl_resolv_async *async, - ares_channel channel) -{ - timediff_t async_timeout_ms; - - DEBUGASSERT(channel); - if(!channel) - return -1; - - async_timeout_ms = Curl_async_timeleft_ms(data, async); - if((async_timeout_ms > 0) && (async_timeout_ms < INT_MAX)) { - struct timeval timebuf; - struct timeval *timeout; - struct timeval end = { (int)async_timeout_ms / 1000, - ((int)async_timeout_ms % 1000) * 1000 }; - - timeout = ares_timeout(channel, &end, &timebuf); - if(timeout) - return curlx_tvtoms(timeout); - } - return async_timeout_ms; -} - -/* - * Curl_ares_perform() - * - * 1) Ask ares what sockets it currently plays with, then - * 2) wait for the timeout period to check for action on ares' sockets. - * 3) tell ares to act on all the sockets marked as "with action" - * - * return number of sockets it worked on, or -1 on error - */ -int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms) -{ - int nfds; - int bitmask; - ares_socket_t socks[ARES_GETSOCK_MAXNUM]; - struct pollfd pfd[ARES_GETSOCK_MAXNUM]; - int i; - int num = 0; - - if(!channel) - return 0; - - bitmask = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM); - - for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) { - pfd[i].events = 0; - pfd[i].revents = 0; - if(ARES_GETSOCK_READABLE(bitmask, i)) { - pfd[i].fd = socks[i]; - pfd[i].events |= POLLRDNORM | POLLIN; - } - if(ARES_GETSOCK_WRITABLE(bitmask, i)) { - pfd[i].fd = socks[i]; - pfd[i].events |= POLLWRNORM | POLLOUT; - } - if(pfd[i].events) - num++; - else - break; - } - - if(num) { - nfds = Curl_poll(pfd, (unsigned int)num, timeout_ms); - if(nfds < 0) - return -1; - } - else - nfds = 0; - - if(!nfds) - /* Call ares_process() unconditionally here, even if we timed out - above, as otherwise the ares name resolve will not timeout! */ - ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); - else { - /* move through the descriptors and ask for processing on them */ - for(i = 0; i < num; i++) - ares_process_fd(channel, - (pfd[i].revents & (POLLRDNORM | POLLIN)) ? - pfd[i].fd : ARES_SOCKET_BAD, - (pfd[i].revents & (POLLWRNORM | POLLOUT)) ? - pfd[i].fd : ARES_SOCKET_BAD); - } - return nfds; -} - -#endif /* USE_ARES */ - -#endif /* CURLRES_ASYNCH */ - -#ifdef USE_CURL_ASYNC - -#include "doh.h" - -void Curl_async_shutdown(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - if(async) { - CURL_TRC_DNS(data, "[%u] shutdown async", async->id); - async->shutdown = TRUE; -#ifdef USE_RESOLV_ARES - Curl_async_ares_shutdown(data, async); -#endif -#ifdef USE_RESOLV_THREADED - Curl_async_thrdd_shutdown(data, async); -#endif -#ifndef CURL_DISABLE_DOH - Curl_doh_cleanup(data, async); -#endif - } -} - -void Curl_async_destroy(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - if(async) { - CURL_TRC_DNS(data, "[%u] destroy async", async->id); - async->shutdown = TRUE; -#ifdef USE_RESOLV_ARES - Curl_async_ares_destroy(data, async); -#endif -#ifdef USE_RESOLV_THREADED - Curl_async_thrdd_destroy(data, async); -#endif -#ifndef CURL_DISABLE_DOH - Curl_doh_cleanup(data, async); -#endif - curlx_safefree(async); - } -} - -CURLcode Curl_async_failed(struct Curl_easy *data, - struct Curl_resolv_async *async, - const char *detail) -{ - const char *host_or_proxy = "host"; - CURLcode result = CURLE_COULDNT_RESOLVE_HOST; - -#ifndef CURL_DISABLE_PROXY - if(async->for_proxy) { - host_or_proxy = "proxy"; - result = CURLE_COULDNT_RESOLVE_PROXY; - } -#endif - - failf(data, "Could not resolve %s: %s%s%s%s", - host_or_proxy, async->hostname, - detail ? " (" : "", detail ? detail : "", detail ? ")" : ""); - return result; -} - -#endif /* USE_CURL_ASYNC */ diff --git a/vendor/curl/lib/asyn-thrdd.c b/vendor/curl/lib/asyn-thrdd.c deleted file mode 100644 index 90f055c2a..000000000 --- a/vendor/curl/lib/asyn-thrdd.c +++ /dev/null @@ -1,828 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/*********************************************************************** - * Only for threaded name resolves builds - **********************************************************************/ -#ifdef USE_RESOLV_THREADED - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_GETADDRINFO -#define RESOLVER_ENOMEM EAI_MEMORY /* = WSA_NOT_ENOUGH_MEMORY on Windows */ -#else -#define RESOLVER_ENOMEM SOCKENOMEM -#endif - -#include "urldata.h" -#include "cfilters.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "hostip.h" -#include "httpsrr.h" -#include "url.h" -#include "multiif.h" -#include "curl_threads.h" -#include "progress.h" -#include "rand.h" -#include "select.h" -#include "thrdqueue.h" -#include "curlx/strparse.h" -#include "curlx/wait.h" - -#ifdef USE_ARES -#include -#ifdef USE_HTTPSRR -#define USE_HTTPSRR_ARES /* the combo */ -#endif -#endif - - -/* - * Curl_async_global_init() - * Called from curl_global_init() to initialize global resolver environment. - * Does nothing here. - */ -int Curl_async_global_init(void) -{ -#if defined(USE_ARES) && defined(CARES_HAVE_ARES_LIBRARY_INIT) - if(ares_library_init(ARES_LIB_INIT_ALL)) { - return CURLE_FAILED_INIT; - } -#endif - return CURLE_OK; -} - -/* - * Curl_async_global_cleanup() - * Called from curl_global_cleanup() to destroy global resolver environment. - * Does nothing here. - */ -void Curl_async_global_cleanup(void) -{ -#if defined(USE_ARES) && defined(CARES_HAVE_ARES_LIBRARY_INIT) - ares_library_cleanup(); -#endif -} - -#ifdef CURLVERBOSE -#define CURL_ASYN_ITEM_DESC_LEN 64 -#define async_item_description(x) (x)->description -#else -#define async_item_description(x) NULL -#endif - -struct async_thrdd_item { - struct Curl_addrinfo *res; -#ifdef CURLVERBOSE - char description[CURL_ASYN_ITEM_DESC_LEN]; -#endif - int sock_error; - uint32_t mid; - uint32_t resolv_id; - uint16_t port; - uint8_t transport; - uint8_t dns_queries; -#ifdef DEBUGBUILD - uint32_t delay_ms; - uint32_t delay_fail_ms; -#endif - char hostname[1]; -}; - -/* Give up reference to add_ctx */ -static void async_thrdd_item_destroy(struct async_thrdd_item *item) -{ - if(item) { - if(item->res) - Curl_freeaddrinfo(item->res); - curlx_free(item); - } -} - -/* Initialize context for threaded resolver */ -static struct async_thrdd_item *async_thrdd_item_create( - struct Curl_easy *data, - uint32_t resolv_id, uint8_t dns_queries, - const char *hostname, uint16_t port, - uint8_t transport) -{ - size_t hostlen = strlen(hostname); - struct async_thrdd_item *item; - - item = curlx_calloc(1, sizeof(*item) + hostlen); - if(!item) - return NULL; - - if(hostlen) /* NUL byte of name already in struct size */ - memcpy(item->hostname, hostname, hostlen); - item->mid = data->mid; - item->resolv_id = resolv_id; - item->dns_queries = dns_queries; - item->port = port; - item->transport = transport; - -#ifdef CURLVERBOSE - curl_msnprintf(item->description, sizeof(item->description), - "[%" FMT_OFF_T "/%u] %s %s:%u", - data->id, item->resolv_id, - Curl_resolv_query_str(dns_queries), - item->hostname, item->port); -#endif - -#ifdef DEBUGBUILD - { - const char *p = getenv("CURL_DBG_RESOLV_DELAY"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, UINT32_MAX)) { - item->delay_ms = (uint32_t)l; - } - } - p = getenv("CURL_DBG_RESOLV_FAIL_DELAY"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, UINT32_MAX)) { - unsigned char c = 0; - Curl_rand_bytes(data, FALSE, &c, 1); - item->delay_fail_ms = (uint32_t)l + c; - } - } - } -#endif - - return item; -} - -#ifdef USE_HTTPSRR_ARES - -static void async_thrdd_rr_done(void *user_data, ares_status_t status, - size_t timeouts, - const ares_dns_record_t *dnsrec) -{ - struct Curl_resolv_async *async = user_data; - struct async_thrdd_ctx *thrdd = async ? &async->thrdd : NULL; - - (void)timeouts; - if(!thrdd) - return; - - async->dns_responses |= CURL_DNSQ_HTTPS; - async->queries_ongoing--; - async->done = !async->queries_ongoing; - if((ARES_SUCCESS == status) && dnsrec) - async->result = Curl_httpsrr_from_ares(dnsrec, &thrdd->rr.hinfo); -} - -static CURLcode async_rr_start(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct async_thrdd_ctx *thrdd = &async->thrdd; - int status; - char *rrname = NULL; - - DEBUGASSERT(!thrdd->rr.channel); - if(async->port != 443) { - rrname = curl_maprintf("_%d_.https.%s", async->port, async->hostname); - if(!rrname) - return CURLE_OUT_OF_MEMORY; - } - status = ares_init_options(&thrdd->rr.channel, NULL, 0); - if(status != ARES_SUCCESS) { - thrdd->rr.channel = NULL; - curlx_free(rrname); - return CURLE_FAILED_INIT; - } -#ifdef DEBUGBUILD - if(getenv("CURL_DNS_SERVER")) { - const char *servers = getenv("CURL_DNS_SERVER"); - status = ares_set_servers_ports_csv(thrdd->rr.channel, servers); - if(status) { - curlx_free(rrname); - return CURLE_FAILED_INIT; - } - } -#endif - - memset(&thrdd->rr.hinfo, 0, sizeof(thrdd->rr.hinfo)); - thrdd->rr.hinfo.rrname = rrname; - async->queries_ongoing++; - ares_query_dnsrec(thrdd->rr.channel, - rrname ? rrname : async->hostname, ARES_CLASS_IN, - ARES_REC_TYPE_HTTPS, - async_thrdd_rr_done, async, NULL); - CURL_TRC_DNS(data, "[HTTPS-RR] initiated request for %s", - rrname ? rrname : async->hostname); - return CURLE_OK; -} -#endif - -void Curl_async_thrdd_shutdown(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - Curl_async_thrdd_destroy(data, async); -} - -struct async_thrdd_match_ctx { - uint32_t mid; - uint32_t resolv_id; -}; - -static bool async_thrdd_match_item(void *qitem, void *match_data) -{ - const struct async_thrdd_match_ctx *ctx = match_data; - struct async_thrdd_item *item = qitem; - return (item->mid == ctx->mid) && (item->resolv_id == ctx->resolv_id); -} - -void Curl_async_thrdd_destroy(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - (void)data; - if(async->queries_ongoing && !async->done && - data->multi && data->multi->resolv_thrdq) { - /* Remove any resolve items still queued */ - struct async_thrdd_match_ctx mctx; - mctx.mid = data->mid; - mctx.resolv_id = async->id; - Curl_thrdq_clear(data->multi->resolv_thrdq, - async_thrdd_match_item, &mctx); - } -#ifdef USE_HTTPSRR_ARES - if(async->thrdd.rr.channel) { - ares_destroy(async->thrdd.rr.channel); - async->thrdd.rr.channel = NULL; - } - Curl_httpsrr_cleanup(&async->thrdd.rr.hinfo); -#endif - async_thrdd_item_destroy(async->thrdd.res_A); - async->thrdd.res_A = NULL; - async_thrdd_item_destroy(async->thrdd.res_AAAA); - async->thrdd.res_AAAA = NULL; -} - -/* - * Waits for a resolve to finish. This function should be avoided since using - * this risk getting the multi interface to "hang". - */ -CURLcode Curl_async_await(struct Curl_easy *data, uint32_t resolv_id, - struct Curl_dns_entry **pdns) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - struct async_thrdd_ctx *thrdd = async ? &async->thrdd : NULL; - timediff_t milli, ms; - - if(!thrdd) - return CURLE_FAILED_INIT; - - while(async->queries_ongoing && !async->done) { - Curl_async_thrdd_multi_process(data->multi); - if(async->done) - break; - - ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &async->start); - if(ms < 3) - milli = 0; - else if(ms <= 50) - milli = ms / 3; - else if(ms <= 250) - milli = 50; - else - milli = 200; - CURL_TRC_DNS(data, "await, waiting %" FMT_TIMEDIFF_T "ms", milli); - curlx_wait_ms(milli); - } - return Curl_async_take_result(data, async, pdns); -} - -#ifdef HAVE_GETADDRINFO - -/* Process the item, using Curl_getaddrinfo_ex() */ -static void async_thrdd_item_process(void *arg) -{ - struct async_thrdd_item *item = arg; - struct addrinfo hints; - char service[12]; - int pf = PF_INET; - int rc; - -#ifdef DEBUGBUILD - if(item->delay_ms) { - curlx_wait_ms(item->delay_ms); - } - if(item->delay_fail_ms) { - curlx_wait_ms(item->delay_fail_ms); - return; - } -#endif - - memset(&hints, 0, sizeof(hints)); -#ifdef CURLRES_IPV6 - if(item->dns_queries & CURL_DNSQ_AAAA) { - pf = (item->dns_queries & CURL_DNSQ_A) ? PF_UNSPEC : PF_INET6; - } -#endif - hints.ai_family = pf; - hints.ai_socktype = Curl_socktype_for_transport(item->transport); - hints.ai_protocol = Curl_protocol_for_transport(item->transport); -#ifdef __APPLE__ - /* If we leave `ai_flags == 0` then macOS is looking for IPV4MAPPED - * when doing AAAA queries. We do not want this "help". */ - hints.ai_flags = AI_ADDRCONFIG; -#endif - - curl_msnprintf(service, sizeof(service), "%u", item->port); -#ifdef AI_NUMERICSERV - hints.ai_flags |= AI_NUMERICSERV; -#endif - - rc = Curl_getaddrinfo_ex(item->hostname, service, &hints, &item->res); - if(rc) { - item->sock_error = SOCKERRNO ? SOCKERRNO : rc; - if(item->sock_error == 0) - item->sock_error = RESOLVER_ENOMEM; - } - else { - Curl_addrinfo_set_port(item->res, item->port); - } -} - -#else /* HAVE_GETADDRINFO */ - -/* Process the item, using Curl_ipv4_resolve_r() */ -static void async_thrdd_item_process(void *arg) -{ - struct async_thrdd_item *item = arg; - -#ifdef DEBUGBUILD - if(item->delay_ms) { - curlx_wait_ms(item->delay_ms); - } - if(item->delay_fail_ms) { - curlx_wait_ms(item->delay_fail_ms); - return; - } -#endif - item->res = Curl_ipv4_resolve_r(item->hostname, item->port); - if(!item->res) { - item->sock_error = SOCKERRNO; - if(item->sock_error == 0) - item->sock_error = RESOLVER_ENOMEM; - } -} - -#endif /* HAVE_GETADDRINFO */ - -#ifdef ENABLE_WAKEUP -static void async_thrdd_event(const struct curl_thrdq *tqueue, - Curl_thrdq_event ev, - void *user_data) -{ - struct Curl_multi *multi = user_data; - (void)tqueue; - switch(ev) { - case CURL_THRDQ_EV_ITEM_DONE: - (void)curl_multi_wakeup(multi); - break; - default: - break; - } -} -#else -#define async_thrdd_event NULL -#endif - -static void async_thrdd_item_free(void *item) -{ - async_thrdd_item_destroy(item); -} - -/* Create a thread queue for processing resolv items */ -CURLcode Curl_async_thrdd_multi_init(struct Curl_multi *multi, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms) -{ - CURLcode result; - DEBUGASSERT(!multi->resolv_thrdq); - result = Curl_thrdq_create(&multi->resolv_thrdq, "DNS", 0, - min_threads, max_threads, idle_time_ms, - async_thrdd_item_free, - async_thrdd_item_process, - async_thrdd_event, - multi); -#ifdef DEBUGBUILD - if(!result) { - const char *p = getenv("CURL_DBG_RESOLV_MAX_THREADS"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, UINT32_MAX)) { - result = Curl_async_thrdd_multi_set_props( - multi, min_threads, (uint32_t)l, idle_time_ms); - } - } - } -#endif - return result; -} - -/* Tear down the thread queue, joining active threads or detaching them */ -void Curl_async_thrdd_multi_destroy(struct Curl_multi *multi, bool join) -{ - if(multi->resolv_thrdq) { -#ifdef CURLVERBOSE - CURL_TRC_DNS(multi->admin, "destroy thread queue+pool, join=%d", join); - Curl_thrdq_trace(multi->resolv_thrdq, multi->admin); -#endif - Curl_thrdq_destroy(multi->resolv_thrdq, join); - multi->resolv_thrdq = NULL; - } -} - -#ifdef CURLVERBOSE -static void async_thrdd_report_item(struct Curl_easy *data, - struct async_thrdd_item *item) -{ - char buf[MAX_IPADR_LEN]; - struct dynbuf tmp; - const char *sep = ""; - const struct Curl_addrinfo *ai = item->res; - int ai_family = (item->dns_queries & CURL_DNSQ_AAAA) ? AF_INET6 : AF_INET; - CURLcode result; - - if(!CURL_TRC_DNS_is_verbose(data)) - return; - - curlx_dyn_init(&tmp, 1024); - for(; ai; ai = ai->ai_next) { - if(ai->ai_family == ai_family) { - Curl_printable_address(ai, buf, sizeof(buf)); - result = curlx_dyn_addf(&tmp, "%s%s", sep, buf); - if(result) { - CURL_TRC_DNS(data, "too many IP, cannot show"); - goto out; - } - sep = ", "; - } - } - - CURL_TRC_DNS(data, "Host %s:%u resolved IPv%c: %s", - item->hostname, item->port, - (item->dns_queries & CURL_DNSQ_AAAA) ? '6' : '4', - (curlx_dyn_len(&tmp) ? curlx_dyn_ptr(&tmp) : "(none)")); -out: - curlx_dyn_free(&tmp); -} -#endif /* CURLVERBOSE */ - -/* Process the receiving end of the thread queue, dispatching - * processed items to their transfer when it can still be found - * and has an `async` state present. Otherwise, destroy the item. */ -void Curl_async_thrdd_multi_process(struct Curl_multi *multi) -{ - struct Curl_easy *data; - void *qitem; - - while(!Curl_thrdq_recv(multi->resolv_thrdq, &qitem)) { - /* dispatch resolve result */ - struct async_thrdd_item *item = qitem; - struct Curl_resolv_async *async = NULL; - - data = Curl_multi_get_easy(multi, item->mid); - if(data) - async = Curl_async_get(data, item->resolv_id); - if(async) { - struct async_thrdd_item **pdest = &async->thrdd.res_A; - - async->dns_responses |= item->dns_queries; - --async->queries_ongoing; - async->done = !async->queries_ongoing; - -#ifdef CURLRES_IPV6 - if(item->dns_queries & CURL_DNSQ_AAAA) - pdest = &async->thrdd.res_AAAA; -#endif - if(!*pdest) { - VERBOSE(async_thrdd_report_item(data, item)); - *pdest = item; - item = NULL; - } - else - DEBUGASSERT(0); /* should not receive duplicates here */ - Curl_multi_mark_dirty(data); - } - async_thrdd_item_free(item); - } -#ifdef CURLVERBOSE - Curl_thrdq_trace(multi->resolv_thrdq, multi->admin); -#endif -} - -CURLcode Curl_async_thrdd_multi_set_props(struct Curl_multi *multi, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms) -{ - return Curl_thrdq_set_props(multi->resolv_thrdq, 0, - min_threads, max_threads, idle_time_ms); -} - -static CURLcode async_thrdd_query(struct Curl_easy *data, - struct Curl_resolv_async *async, - uint8_t dns_queries) -{ - struct async_thrdd_item *item; - CURLcode result; - - item = async_thrdd_item_create(data, async->id, dns_queries, - async->hostname, async->port, - async->transport); - if(!item) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - CURL_TRC_DNS(data, "queueing query %s", item->description); - result = Curl_thrdq_send(data->multi->resolv_thrdq, item, - async_item_description(item), async->timeout_ms); - if(result) - goto out; - item = NULL; - async->queries_ongoing++; - -out: - if(item) - async_thrdd_item_free(item); - return result; -} - -CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - CURLcode result = CURLE_FAILED_INIT; - void *resolver = NULL; - - if(async->queries_ongoing || async->done) - return CURLE_FAILED_INIT; - -#ifdef USE_HTTPSRR_ARES - DEBUGASSERT(!async->thrdd.rr.channel); - if((async->dns_queries & CURL_DNSQ_HTTPS) && !async->is_ipaddr) { - result = async_rr_start(data, async); - if(result) - goto out; - resolver = async->thrdd.rr.channel; - } -#endif - - result = Curl_resolv_announce_start(data, resolver); - if(result) - return result; - -#ifdef CURLRES_IPV6 - /* Do not start an AAAA query for an ipv4 address when - * we will start an A query for it. */ - if((async->dns_queries & CURL_DNSQ_AAAA) && - !(async->is_ipv4addr && (async->dns_queries & CURL_DNSQ_A))) { - result = async_thrdd_query(data, async, CURL_DNSQ_AAAA); - if(result) - goto out; - } -#endif - if(async->dns_queries & CURL_DNSQ_A) { - result = async_thrdd_query(data, async, CURL_DNSQ_A); - if(result) - goto out; - } - -#ifdef CURLVERBOSE - Curl_thrdq_trace(data->multi->resolv_thrdq, data); -#endif - -out: - if(result) - CURL_TRC_DNS(data, "error queueing query %s:%d -> %d", - async->hostname, async->port, result); - return result; -} - -CURLcode Curl_async_pollset(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct easy_pollset *ps) -{ - timediff_t timeout_ms; - - timeout_ms = Curl_async_timeleft_ms(data, async); -#ifdef USE_HTTPSRR_ARES - if(async->thrdd.rr.channel) { - CURLcode result = Curl_ares_pollset(data, async->thrdd.rr.channel, ps); - if(result) - return result; - timeout_ms = Curl_ares_timeout_ms(data, async, async->thrdd.rr.channel); - } -#else - (void)ps; -#endif - - if(!async->done) { -#ifndef ENABLE_WAKEUP - timediff_t stutter_ms, elapsed_ms; - elapsed_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &async->start); - if(elapsed_ms < 3) - stutter_ms = 1; - else if(elapsed_ms <= 50) - stutter_ms = elapsed_ms / 3; - else if(elapsed_ms <= 250) - stutter_ms = 50; - else - stutter_ms = 200; - timeout_ms = CURLMIN(stutter_ms, timeout_ms); -#endif - Curl_expire(data, timeout_ms, EXPIRE_ASYNC_NAME); - } - return CURLE_OK; -} - -/* - * Curl_async_take_result() is called repeatedly to check if a previous - * name resolve request has completed. It should also make sure to time-out if - * the operation seems to take too long. - */ -CURLcode Curl_async_take_result(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct Curl_dns_entry **pdns) -{ - struct async_thrdd_ctx *thrdd = &async->thrdd; - struct Curl_dns_entry *dns = NULL; - CURLcode result = CURLE_OK; - - DEBUGASSERT(pdns); - *pdns = NULL; - if(!async->queries_ongoing && !async->done) { - DEBUGASSERT(0); - return CURLE_FAILED_INIT; - } - -#ifdef USE_HTTPSRR_ARES - /* best effort, ignore errors */ - if(thrdd->rr.channel) - (void)Curl_ares_perform(thrdd->rr.channel, 0); -#endif - - if(!async->done) - return CURLE_AGAIN; - - Curl_expire_done(data, EXPIRE_ASYNC_NAME); - if(async->result) { - result = async->result; - goto out; - } - - if((thrdd->res_A && thrdd->res_A->res) || - (thrdd->res_AAAA && thrdd->res_AAAA->res)) { - dns = Curl_dnscache_mk_entry2( - data, async->dns_queries, - thrdd->res_A ? &thrdd->res_A->res : NULL, - thrdd->res_AAAA ? &thrdd->res_AAAA->res : NULL, - async->hostname, async->port); - if(!dns) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - -#ifdef USE_HTTPSRR_ARES - if(thrdd->rr.channel) { - struct Curl_https_rrinfo *lhrr = NULL; - if(thrdd->rr.hinfo.complete) { - lhrr = Curl_httpsrr_dup_move(&thrdd->rr.hinfo); - if(!lhrr) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - Curl_httpsrr_trace(data, lhrr); - Curl_dns_entry_set_https_rr(dns, lhrr); - } -#endif - } - - if(dns) { - *pdns = dns; - dns = NULL; - } -#ifdef CURLVERBOSE - Curl_thrdq_trace(data->multi->resolv_thrdq, data); -#endif - -out: - Curl_dns_entry_unlink(data, &dns); - Curl_async_thrdd_shutdown(data, async); - if(!result && !*pdns) - result = Curl_async_failed(data, async, NULL); - if(result && - (result != CURLE_COULDNT_RESOLVE_HOST) && - (result != CURLE_COULDNT_RESOLVE_PROXY)) { - CURL_TRC_DNS(data, "Error %d resolving %s:%d", - result, async->hostname, async->port); - } - return result; -} - -static const struct Curl_addrinfo *async_thrdd_get_ai( - const struct Curl_addrinfo *ai, - int ai_family, unsigned int index) -{ - unsigned int i = 0; - for(i = 0; ai; ai = ai->ai_next) { - if(ai->ai_family == ai_family) { - if(i == index) - return ai; - ++i; - } - } - return NULL; -} - -const struct Curl_addrinfo *Curl_async_get_ai(struct Curl_easy *data, - struct Curl_resolv_async *async, - int ai_family, - unsigned int index) -{ - struct async_thrdd_ctx *thrdd = &async->thrdd; - - (void)data; - switch(ai_family) { - case AF_INET: - if(thrdd->res_A) - return async_thrdd_get_ai(thrdd->res_A->res, ai_family, index); - break; - case AF_INET6: - if(thrdd->res_AAAA) - return async_thrdd_get_ai(thrdd->res_AAAA->res, ai_family, index); - break; - default: - break; - } - return NULL; -} - -#ifdef USE_HTTPSRR -const struct Curl_https_rrinfo *Curl_async_get_https( - struct Curl_easy *data, - struct Curl_resolv_async *async) -{ -#ifdef USE_HTTPSRR_ARES - if(Curl_async_knows_https(data, async)) - return &async->thrdd.rr.hinfo; -#else - (void)data; - (void)async; -#endif - return NULL; -} - -bool Curl_async_knows_https(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - (void)data; - if(async->dns_queries & CURL_DNSQ_HTTPS) - return ((async->dns_responses & CURL_DNSQ_HTTPS) || async->done); - return TRUE; /* we know it will never come */ -} - -#endif /* USE_HTTPSRR */ - -#endif /* USE_RESOLV_THREADED */ diff --git a/vendor/curl/lib/asyn.h b/vendor/curl/lib/asyn.h deleted file mode 100644 index ed5093365..000000000 --- a/vendor/curl/lib/asyn.h +++ /dev/null @@ -1,277 +0,0 @@ -#ifndef HEADER_CURL_ASYN_H -#define HEADER_CURL_ASYN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_HTTPSRR) && defined(USE_ARES) -#include "httpsrr.h" -#endif - -struct Curl_easy; -struct Curl_dns_entry; -struct Curl_resolv_async; -struct Curl_multi; -struct easy_pollset; - -#ifdef CURLRES_ASYNCH - -#include "curl_addrinfo.h" - -struct hostent; -struct connectdata; -struct easy_pollset; - -#if defined(USE_RESOLV_ARES) && defined(USE_RESOLV_THREADED) -#error cannot have both USE_RESOLV_ARES and USE_RESOLV_THREADED defined -#endif - -/* - * This header defines all functions in the internal asynch resolver interface. - * All asynch resolvers need to provide these functions. - * asyn-ares.c and asyn-thread.c are the current implementations of asynch - * resolver backends. - */ - -/* - * Curl_async_global_init() - * - * Called from curl_global_init() to initialize global resolver environment. - * Returning anything else than CURLE_OK fails curl_global_init(). - */ -int Curl_async_global_init(void); - -/* - * Curl_async_global_cleanup() - * Called from curl_global_cleanup() to destroy global resolver environment. - */ -void Curl_async_global_cleanup(void); - -/* - * Curl_async_getaddrinfo() - when using this resolver - * - * Returns name information about the given hostname and port number. If - * successful, the 'hostent' is returned and the fourth argument will point to - * memory we need to free after use. That memory *MUST* be freed with - * Curl_freeaddrinfo(), nothing else. - * - * Each resolver backend must of course make sure to return data in the - * correct format to comply with this. - */ -CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, - struct Curl_resolv_async *async); - -const struct Curl_addrinfo *Curl_async_get_ai(struct Curl_easy *data, - struct Curl_resolv_async *async, - int ai_family, - unsigned int index); - -#ifdef USE_HTTPSRR -const struct Curl_https_rrinfo *Curl_async_get_https( - struct Curl_easy *data, - struct Curl_resolv_async *async); -bool Curl_async_knows_https(struct Curl_easy *data, - struct Curl_resolv_async *async); -#endif /* USE_HTTPSRR */ - -#ifdef USE_ARES -/* common functions for c-ares and threaded resolver with HTTPSRR */ -#include - -CURLcode Curl_ares_pollset(struct Curl_easy *data, - ares_channel channel, - struct easy_pollset *ps); - -timediff_t Curl_ares_timeout_ms(struct Curl_easy *data, - struct Curl_resolv_async *async, - ares_channel channel); - -int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms); -#endif - -#ifdef USE_RESOLV_ARES -/* async resolving implementation using c-ares alone */ -struct async_ares_ctx { - ares_channel channel; - struct Curl_addrinfo *res_A; - struct Curl_addrinfo *res_AAAA; - int ares_status; /* ARES_SUCCESS, ARES_ENOTFOUND, etc. */ - CURLcode result; /* CURLE_OK or error handling response */ - struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */ -#ifdef USE_HTTPSRR - struct Curl_https_rrinfo hinfo; -#endif -}; - -void Curl_async_ares_shutdown(struct Curl_easy *data, - struct Curl_resolv_async *async); -void Curl_async_ares_destroy(struct Curl_easy *data, - struct Curl_resolv_async *async); - -#endif /* USE_RESOLV_ARES */ - -#ifdef USE_RESOLV_THREADED - -struct async_thrdd_item; - -/* Context for threaded resolver */ -struct async_thrdd_ctx { - struct async_thrdd_item *res_A; /* ipv4 result */ - struct async_thrdd_item *res_AAAA; /* ipv6 result */ -#if defined(USE_HTTPSRR) && defined(USE_ARES) - struct { - ares_channel channel; - struct Curl_https_rrinfo hinfo; - } rr; -#endif -}; - -void Curl_async_thrdd_shutdown(struct Curl_easy *data, - struct Curl_resolv_async *async); -void Curl_async_thrdd_destroy(struct Curl_easy *data, - struct Curl_resolv_async *async); - -CURLcode Curl_async_thrdd_multi_init(struct Curl_multi *multi, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms); -void Curl_async_thrdd_multi_destroy(struct Curl_multi *multi, bool join); -void Curl_async_thrdd_multi_process(struct Curl_multi *multi); - -CURLcode Curl_async_thrdd_multi_set_props(struct Curl_multi *multi, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms); - -#endif /* USE_RESOLV_THREADED */ - -#ifndef CURL_DISABLE_DOH -struct doh_probes; -#endif - -/* - * Curl_async_await() - * - * Waits for a resolve to finish. This function should be avoided since using - * this risk getting the multi interface to "hang". - * - * On return 'dns' is assigned the resolved dns (CURLE_OK or NULL otherwise. - * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, - * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. - */ -CURLcode Curl_async_await(struct Curl_easy *data, uint32_t resolv_id, - struct Curl_dns_entry **pdns); - -/* - * Take the result of an async resolve operation. - * Returns CURLE_OK with `*pdns` != NULL, CURLE_AGAIN while still - * ongoing or an error code for a failed resolve. - */ -CURLcode Curl_async_take_result(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct Curl_dns_entry **pdns); - -/* Curl_async_pollset() - * - * This function is called from the Curl_multi_pollset() function. 'sock' is a - * pointer to an array to hold the file descriptors, with 'numsock' being the - * size of that array (in number of entries). This function is supposed to - * return bitmask indicating what file descriptors (referring to array indexes - * in the 'sock' array) to wait for, read/write. - */ -CURLcode Curl_async_pollset(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct easy_pollset *ps); - -#else /* CURLRES_ASYNCH */ - -/* convert these functions if an asynch resolver is not used */ -#define Curl_async_global_init() CURLE_OK -#define Curl_async_global_cleanup() Curl_nop_stmt -#define Curl_async_get_ai(a, b, c, d) NULL -#define Curl_async_await(a, b, c) CURLE_COULDNT_RESOLVE_HOST -#define Curl_async_take_result(x, y, z) CURLE_COULDNT_RESOLVE_HOST -#define Curl_async_pollset(x, y, z) CURLE_OK -#define Curl_async_get_https(x, y) NULL -#define Curl_async_knows_https(x, y) TRUE -#endif /* !CURLRES_ASYNCH */ - -#if defined(CURLRES_ASYNCH) || !defined(CURL_DISABLE_DOH) -#define USE_CURL_ASYNC -#endif - -#ifdef USE_CURL_ASYNC - -struct Curl_resolv_async { - struct Curl_resolv_async *next; -#ifdef USE_RESOLV_ARES - struct async_ares_ctx ares; -#elif defined(USE_RESOLV_THREADED) - struct async_thrdd_ctx thrdd; -#endif -#ifndef CURL_DISABLE_DOH - struct doh_probes *doh; /* DoH specific data for this request */ -#endif - struct curltime start; - timediff_t interval_end; - timediff_t timeout_ms; - CURLcode result; - uint32_t poll_interval; - uint32_t id; /* unique id per easy handle of the resolve operation */ - /* what is being resolved */ - uint16_t port; - uint8_t dns_queries; /* what queries are being performed */ - uint8_t dns_responses; /* what queries had responses so far. */ - uint8_t transport; - uint8_t queries_ongoing; - BIT(is_ipaddr); - BIT(is_ipv4addr); - BIT(for_proxy); - BIT(done); - BIT(shutdown); - char hostname[1]; -}; - -timediff_t Curl_async_timeleft_ms(struct Curl_easy *data, - struct Curl_resolv_async *async); - -/* Shut down the given async resolve. */ -void Curl_async_shutdown(struct Curl_easy *data, - struct Curl_resolv_async *async); - -/* Frees the resources of the given async resolve and the struct itself. */ -void Curl_async_destroy(struct Curl_easy *data, - struct Curl_resolv_async *async); - -CURLcode Curl_async_failed(struct Curl_easy *data, - struct Curl_resolv_async *async, - const char *detail); - -#else /* !USE_CURL_ASYNC */ -#define Curl_async_shutdown(x, y) Curl_nop_stmt -#endif /* USE_CURL_ASYNC */ - -/********** end of generic resolver interface functions *****************/ -#endif /* HEADER_CURL_ASYN_H */ diff --git a/vendor/curl/lib/bufq.c b/vendor/curl/lib/bufq.c deleted file mode 100644 index 750d86888..000000000 --- a/vendor/curl/lib/bufq.c +++ /dev/null @@ -1,619 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "bufq.h" - -static bool chunk_is_empty(const struct buf_chunk *chunk) -{ - return chunk->r_offset >= chunk->w_offset; -} - -static bool chunk_is_full(const struct buf_chunk *chunk) -{ - return chunk->w_offset >= chunk->dlen; -} - -static size_t chunk_len(const struct buf_chunk *chunk) -{ - return chunk->w_offset - chunk->r_offset; -} - -static void chunk_reset(struct buf_chunk *chunk) -{ - chunk->next = NULL; - chunk->r_offset = chunk->w_offset = 0; -} - -static size_t chunk_append(struct buf_chunk *chunk, - const uint8_t *buf, size_t len) -{ - uint8_t *p = &chunk->x.data[chunk->w_offset]; - size_t n = chunk->dlen - chunk->w_offset; - DEBUGASSERT(chunk->dlen >= chunk->w_offset); - if(n) { - n = CURLMIN(n, len); - memcpy(p, buf, n); - chunk->w_offset += n; - } - return n; -} - -static size_t chunk_read(struct buf_chunk *chunk, - uint8_t *buf, size_t len) -{ - uint8_t *p = &chunk->x.data[chunk->r_offset]; - size_t n = chunk->w_offset - chunk->r_offset; - DEBUGASSERT(chunk->w_offset >= chunk->r_offset); - if(!n) { - return 0; - } - else if(n <= len) { - memcpy(buf, p, n); - chunk->r_offset = chunk->w_offset = 0; - return n; - } - else { - memcpy(buf, p, len); - chunk->r_offset += len; - return len; - } -} - -static CURLcode chunk_slurpn(struct buf_chunk *chunk, size_t max_len, - Curl_bufq_reader *reader, - void *reader_ctx, size_t *pnread) -{ - uint8_t *p = &chunk->x.data[chunk->w_offset]; - size_t n = chunk->dlen - chunk->w_offset; /* free amount */ - CURLcode result; - - *pnread = 0; - DEBUGASSERT(chunk->dlen >= chunk->w_offset); - if(!n) - return CURLE_AGAIN; - if(max_len && n > max_len) - n = max_len; - result = reader(reader_ctx, p, n, pnread); - if(!result) { - DEBUGASSERT(*pnread <= n); - chunk->w_offset += *pnread; - } - return result; -} - -static void chunk_peek(const struct buf_chunk *chunk, - const uint8_t **pbuf, size_t *plen) -{ - DEBUGASSERT(chunk->w_offset >= chunk->r_offset); - *pbuf = &chunk->x.data[chunk->r_offset]; - *plen = chunk->w_offset - chunk->r_offset; -} - -static void chunk_peek_at(const struct buf_chunk *chunk, size_t offset, - const uint8_t **pbuf, size_t *plen) -{ - offset += chunk->r_offset; - DEBUGASSERT(chunk->w_offset >= offset); - *pbuf = &chunk->x.data[offset]; - *plen = chunk->w_offset - offset; -} - -static size_t chunk_skip(struct buf_chunk *chunk, size_t amount) -{ - size_t n = chunk->w_offset - chunk->r_offset; - DEBUGASSERT(chunk->w_offset >= chunk->r_offset); - if(n) { - n = CURLMIN(n, amount); - chunk->r_offset += n; - if(chunk->r_offset == chunk->w_offset) - chunk->r_offset = chunk->w_offset = 0; - } - return n; -} - -static void chunk_list_free(struct buf_chunk **anchor) -{ - struct buf_chunk *chunk; - while(*anchor) { - chunk = *anchor; - *anchor = chunk->next; - curlx_free(chunk); - } -} - -void Curl_bufcp_init(struct bufc_pool *pool, - size_t chunk_size, size_t spare_max) -{ - DEBUGASSERT(chunk_size > 0); - DEBUGASSERT(spare_max > 0); - memset(pool, 0, sizeof(*pool)); - pool->chunk_size = chunk_size; - pool->spare_max = spare_max; -} - -static CURLcode bufcp_take(struct bufc_pool *pool, - struct buf_chunk **pchunk) -{ - struct buf_chunk *chunk = NULL; - - if(pool->spare) { - chunk = pool->spare; - pool->spare = chunk->next; - --pool->spare_count; - chunk_reset(chunk); - *pchunk = chunk; - return CURLE_OK; - } - - /* Check for integer overflow before allocation */ - if(pool->chunk_size > SIZE_MAX - sizeof(*chunk)) { - *pchunk = NULL; - return CURLE_OUT_OF_MEMORY; - } - - chunk = curlx_calloc(1, sizeof(*chunk) + pool->chunk_size); - if(!chunk) { - *pchunk = NULL; - return CURLE_OUT_OF_MEMORY; - } - chunk->dlen = pool->chunk_size; - *pchunk = chunk; - return CURLE_OK; -} - -static void bufcp_put(struct bufc_pool *pool, - struct buf_chunk *chunk) -{ - if(pool->spare_count >= pool->spare_max) { - curlx_free(chunk); - } - else { - chunk_reset(chunk); - chunk->next = pool->spare; - pool->spare = chunk; - ++pool->spare_count; - } -} - -void Curl_bufcp_free(struct bufc_pool *pool) -{ - chunk_list_free(&pool->spare); - pool->spare_count = 0; -} - -static void bufq_init(struct bufq *q, struct bufc_pool *pool, - size_t chunk_size, size_t max_chunks, int opts) -{ - DEBUGASSERT(chunk_size > 0); - DEBUGASSERT(max_chunks > 0); - memset(q, 0, sizeof(*q)); - q->chunk_size = chunk_size; - q->max_chunks = max_chunks; - q->pool = pool; - q->opts = opts; -} - -void Curl_bufq_init2(struct bufq *q, size_t chunk_size, size_t max_chunks, - int opts) -{ - bufq_init(q, NULL, chunk_size, max_chunks, opts); -} - -void Curl_bufq_init(struct bufq *q, size_t chunk_size, size_t max_chunks) -{ - bufq_init(q, NULL, chunk_size, max_chunks, BUFQ_OPT_NONE); -} - -void Curl_bufq_initp(struct bufq *q, struct bufc_pool *pool, - size_t max_chunks, int opts) -{ - bufq_init(q, pool, pool->chunk_size, max_chunks, opts); -} - -void Curl_bufq_free(struct bufq *q) -{ - chunk_list_free(&q->head); - chunk_list_free(&q->spare); - q->tail = NULL; - q->chunk_count = 0; -} - -void Curl_bufq_reset(struct bufq *q) -{ - struct buf_chunk *chunk; - while(q->head) { - chunk = q->head; - q->head = chunk->next; - chunk->next = q->spare; - q->spare = chunk; - } - q->tail = NULL; -} - -size_t Curl_bufq_len(const struct bufq *q) -{ - const struct buf_chunk *chunk = q->head; - size_t len = 0; - while(chunk) { - len += chunk_len(chunk); - chunk = chunk->next; - } - return len; -} - -bool Curl_bufq_is_empty(const struct bufq *q) -{ - return !q->head || chunk_is_empty(q->head); -} - -bool Curl_bufq_is_full(const struct bufq *q) -{ - if(!q->tail || q->spare) - return FALSE; - if(q->chunk_count < q->max_chunks) - return FALSE; - if(q->chunk_count > q->max_chunks) - return TRUE; - /* we have no spares and cannot make more, is the tail full? */ - return chunk_is_full(q->tail); -} - -static struct buf_chunk *get_spare(struct bufq *q) -{ - struct buf_chunk *chunk = NULL; - - if(q->spare) { - chunk = q->spare; - q->spare = chunk->next; - chunk_reset(chunk); - return chunk; - } - - if(q->chunk_count >= q->max_chunks && (!(q->opts & BUFQ_OPT_SOFT_LIMIT))) - return NULL; - - if(q->pool) { - if(bufcp_take(q->pool, &chunk)) - return NULL; - ++q->chunk_count; - return chunk; - } - else { - /* Check for integer overflow before allocation */ - if(q->chunk_size > SIZE_MAX - sizeof(*chunk)) { - return NULL; - } - - chunk = curlx_calloc(1, sizeof(*chunk) + q->chunk_size); - if(!chunk) - return NULL; - chunk->dlen = q->chunk_size; - ++q->chunk_count; - return chunk; - } -} - -static void prune_head(struct bufq *q) -{ - struct buf_chunk *chunk; - - while(q->head && chunk_is_empty(q->head)) { - chunk = q->head; - q->head = chunk->next; - if(q->tail == chunk) - q->tail = q->head; - if(q->pool) { - bufcp_put(q->pool, chunk); - --q->chunk_count; - } - else if((q->chunk_count > q->max_chunks) || - (q->opts & BUFQ_OPT_NO_SPARES)) { - /* SOFT_LIMIT allowed us more than max. free spares until - * we are at max again. Or free them if we are configured - * to not use spares. */ - curlx_free(chunk); - --q->chunk_count; - } - else { - chunk->next = q->spare; - q->spare = chunk; - } - } -} - -static struct buf_chunk *get_non_full_tail(struct bufq *q) -{ - struct buf_chunk *chunk; - - if(q->tail && !chunk_is_full(q->tail)) - return q->tail; - chunk = get_spare(q); - if(chunk) { - /* new tail, and possibly new head */ - if(q->tail) { - q->tail->next = chunk; - q->tail = chunk; - } - else { - DEBUGASSERT(!q->head); - q->head = q->tail = chunk; - } - } - return chunk; -} - -CURLcode Curl_bufq_write(struct bufq *q, - const uint8_t *buf, size_t len, - size_t *pnwritten) -{ - struct buf_chunk *tail; - size_t n; - - DEBUGASSERT(q->max_chunks > 0); - *pnwritten = 0; - while(len) { - tail = get_non_full_tail(q); - if(!tail) { - if((q->chunk_count < q->max_chunks) || (q->opts & BUFQ_OPT_SOFT_LIMIT)) - /* should have gotten a tail, but did not */ - return CURLE_OUT_OF_MEMORY; - break; - } - n = chunk_append(tail, buf, len); - if(!n) - break; - *pnwritten += n; - buf += n; - len -= n; - } - return (!*pnwritten && len) ? CURLE_AGAIN : CURLE_OK; -} - -CURLcode Curl_bufq_cwrite(struct bufq *q, - const char *buf, size_t len, - size_t *pnwritten) -{ - return Curl_bufq_write(q, (const uint8_t *)buf, len, pnwritten); -} - -CURLcode Curl_bufq_read(struct bufq *q, uint8_t *buf, size_t len, - size_t *pnread) -{ - *pnread = 0; - while(len && q->head) { - size_t n = chunk_read(q->head, buf, len); - if(n) { - *pnread += n; - buf += n; - len -= n; - } - prune_head(q); - } - return (!*pnread) ? CURLE_AGAIN : CURLE_OK; -} - -CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len, - size_t *pnread) -{ - return Curl_bufq_read(q, (uint8_t *)buf, len, pnread); -} - -bool Curl_bufq_peek(struct bufq *q, - const uint8_t **pbuf, size_t *plen) -{ - if(q->head && chunk_is_empty(q->head)) { - prune_head(q); - } - if(q->head && !chunk_is_empty(q->head)) { - chunk_peek(q->head, pbuf, plen); - return TRUE; - } - *pbuf = NULL; - *plen = 0; - return FALSE; -} - -bool Curl_bufq_peek_at(struct bufq *q, size_t offset, - const uint8_t **pbuf, size_t *plen) -{ - struct buf_chunk *c = q->head; - size_t clen; - - while(c) { - clen = chunk_len(c); - if(!clen) - break; - if(offset >= clen) { - offset -= clen; - c = c->next; - continue; - } - chunk_peek_at(c, offset, pbuf, plen); - return TRUE; - } - *pbuf = NULL; - *plen = 0; - return FALSE; -} - -void Curl_bufq_skip(struct bufq *q, size_t amount) -{ - size_t n; - - while(amount && q->head) { - n = chunk_skip(q->head, amount); - amount -= n; - prune_head(q); - } -} - -CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer, - void *writer_ctx, size_t *pwritten) -{ - const uint8_t *buf; - size_t blen; - CURLcode result = CURLE_OK; - - *pwritten = 0; - while(Curl_bufq_peek(q, &buf, &blen)) { - size_t chunk_written; - - result = writer(writer_ctx, buf, blen, &chunk_written); - if(result) { - if((result == CURLE_AGAIN) && *pwritten) { - /* blocked on subsequent write, report success */ - result = CURLE_OK; - } - break; - } - if(!chunk_written) { - if(!*pwritten) { - /* treat as blocked */ - result = CURLE_AGAIN; - } - break; - } - *pwritten += chunk_written; - Curl_bufq_skip(q, chunk_written); - } - return result; -} - -CURLcode Curl_bufq_write_pass(struct bufq *q, - const uint8_t *buf, size_t len, - Curl_bufq_writer *writer, void *writer_ctx, - size_t *pwritten) -{ - CURLcode result = CURLE_OK; - size_t n; - - *pwritten = 0; - while(len) { - if(Curl_bufq_is_full(q)) { - /* try to make room in case we are full */ - result = Curl_bufq_pass(q, writer, writer_ctx, &n); - if(result) { - if(result != CURLE_AGAIN) { - /* real error, fail */ - return result; - } - /* would block, bufq is full, give up */ - break; - } - } - - /* Add to bufq as much as there is room for */ - result = Curl_bufq_write(q, buf, len, &n); - if(result) { - if(result != CURLE_AGAIN) - /* real error, fail */ - return result; - /* result == CURLE_AGAIN */ - if(*pwritten) - /* we did write successfully before */ - result = CURLE_OK; - return result; - } - else if(n == 0) - /* edge case of writer returning 0 (and len is >0) - * break or we might enter an infinite loop here */ - break; - - /* Track what we added to bufq */ - buf += n; - len -= n; - *pwritten += n; - } - - return (!*pwritten && len) ? CURLE_AGAIN : CURLE_OK; -} - -CURLcode Curl_bufq_sipn(struct bufq *q, size_t max_len, - Curl_bufq_reader *reader, void *reader_ctx, - size_t *pnread) -{ - struct buf_chunk *tail = NULL; - - *pnread = 0; - tail = get_non_full_tail(q); - if(!tail) { - if(q->chunk_count < q->max_chunks) - return CURLE_OUT_OF_MEMORY; - /* full, blocked */ - return CURLE_AGAIN; - } - - return chunk_slurpn(tail, max_len, reader, reader_ctx, pnread); -} - -/** - * Read up to `max_len` bytes and append it to the end of the buffer queue. - * if `max_len` is 0, no limit is imposed and the call behaves exactly - * the same as `Curl_bufq_slurp()`. - * Returns the total amount of buf read (may be 0) in `pnread` or error - * Note that even in case of an error chunks may have been read and - * the buffer queue will have different length than before. - */ -static CURLcode bufq_slurpn(struct bufq *q, size_t max_len, - Curl_bufq_reader *reader, void *reader_ctx, - size_t *pnread) -{ - CURLcode result; - - *pnread = 0; - while(1) { - size_t n; - result = Curl_bufq_sipn(q, max_len, reader, reader_ctx, &n); - if(result) { - if(!*pnread || result != CURLE_AGAIN) { - /* blocked on first read or real error, fail */ - return result; - } - result = CURLE_OK; - break; - } - else if(n == 0) { - /* eof, result remains CURLE_OK */ - break; - } - *pnread += n; - if(max_len) { - DEBUGASSERT(n <= max_len); - max_len -= n; - if(!max_len) - break; - } - /* give up slurping when we get less bytes than we asked for */ - if(q->tail && !chunk_is_full(q->tail)) - break; - } - return result; -} - -CURLcode Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader, - void *reader_ctx, size_t *pnread) -{ - return bufq_slurpn(q, 0, reader, reader_ctx, pnread); -} diff --git a/vendor/curl/lib/bufq.h b/vendor/curl/lib/bufq.h deleted file mode 100644 index da411b586..000000000 --- a/vendor/curl/lib/bufq.h +++ /dev/null @@ -1,256 +0,0 @@ -#ifndef HEADER_CURL_BUFQ_H -#define HEADER_CURL_BUFQ_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/** - * A chunk of bytes for reading and writing. - * The size is fixed a creation with read and write offset - * for where unread content is. - */ -struct buf_chunk { - struct buf_chunk *next; /* to keep it in a list */ - size_t dlen; /* the amount of allocated x.data[] */ - size_t r_offset; /* first unread bytes */ - size_t w_offset; /* one after last written byte */ - union { - uint8_t data[1]; /* the buffer for `dlen` bytes */ - void *dummy; /* alignment */ - } x; -}; - -/** - * A pool for providing/keeping a number of chunks of the same size - * - * The same pool can be shared by many `bufq` instances. A pool is not thread - * safe. All bufqs using it are supposed to operate in the same thread. - */ -struct bufc_pool { - struct buf_chunk *spare; /* list of available spare chunks */ - size_t chunk_size; /* the size of chunks in this pool */ - size_t spare_count; /* current number of spare chunks in list */ - size_t spare_max; /* max number of spares to keep */ -}; - -void Curl_bufcp_init(struct bufc_pool *pool, - size_t chunk_size, size_t spare_max); - -void Curl_bufcp_free(struct bufc_pool *pool); - -/** - * A queue of byte chunks for reading and writing. - * Reading is done from `head`, writing is done to `tail`. - * - * `bufq`s can be empty or full or neither. Its `len` is the number - * of bytes that can be read. For an empty bufq, `len` will be 0. - * - * By default, a bufq can hold up to `max_chunks * chunk_size` number - * of bytes. When `max_chunks` are used (in the `head` list) and the - * `tail` chunk is full, the bufq will report that it is full. - * - * On a full bufq, `len` may be less than the maximum number of bytes, - * e.g. when the head chunk is partially read. `len` may also become - * larger than the max when option `BUFQ_OPT_SOFT_LIMIT` is used. - * - * By default, writing to a full bufq will return (-1, CURLE_AGAIN). Same - * as reading from an empty bufq. - * With `BUFQ_OPT_SOFT_LIMIT` set, a bufq will allow writing beyond this limit - * and use more than `max_chunks`. It will report that it is full - * nevertheless. This is provided for situation where writes preferably never - * fail (except for memory exhaustion). - * - * By default and without a pool, a bufq will keep chunks that read - * empty in its `spare` list. Option `BUFQ_OPT_NO_SPARES` will - * disable that and free chunks once they become empty. - * - * When providing a pool to a bufq, all chunk creation and spare handling - * will be delegated to that pool. - */ -struct bufq { - struct buf_chunk *head; /* chunk with bytes to read from */ - struct buf_chunk *tail; /* chunk to write to */ - struct buf_chunk *spare; /* list of free chunks, unless `pool` */ - struct bufc_pool *pool; /* optional pool for free chunks */ - size_t chunk_count; /* current number of chunks in `head+spare` */ - size_t max_chunks; /* max `head` chunks to use */ - size_t chunk_size; /* size of chunks to manage */ - int opts; /* options for handling queue, see below */ -}; - -/** - * Default behaviour: chunk limit is "hard", meaning attempts to write - * more bytes than can be hold in `max_chunks` is refused and will return - * -1, CURLE_AGAIN. */ -#define BUFQ_OPT_NONE 0 -/** - * Make `max_chunks` a "soft" limit. A bufq will report that it is "full" - * when `max_chunks` are used, but allows writing beyond this limit. - */ -#define BUFQ_OPT_SOFT_LIMIT (1 << 0) -/** - * Do not keep spare chunks. - */ -#define BUFQ_OPT_NO_SPARES (1 << 1) - -/** - * Initialize a buffer queue that can hold up to `max_chunks` buffers - * each of size `chunk_size`. The bufq will not allow writing of - * more bytes than can be held in `max_chunks`. - */ -void Curl_bufq_init(struct bufq *q, size_t chunk_size, size_t max_chunks); - -/** - * Initialize a buffer queue that can hold up to `max_chunks` buffers - * each of size `chunk_size` with the given options. See `BUFQ_OPT_*`. - */ -void Curl_bufq_init2(struct bufq *q, size_t chunk_size, - size_t max_chunks, int opts); - -void Curl_bufq_initp(struct bufq *q, struct bufc_pool *pool, - size_t max_chunks, int opts); - -/** - * Reset the buffer queue to be empty. Keep any allocated buffer chunks - * around. - */ -void Curl_bufq_reset(struct bufq *q); - -/** - * Free all resources held by the buffer queue. - */ -void Curl_bufq_free(struct bufq *q); - -/** - * Return the total amount of data in the queue. - */ -size_t Curl_bufq_len(const struct bufq *q); - -/** - * Returns TRUE iff there is no data in the buffer queue. - */ -bool Curl_bufq_is_empty(const struct bufq *q); - -/** - * Returns TRUE iff there is no space left in the buffer queue. - */ -bool Curl_bufq_is_full(const struct bufq *q); - -/** - * Write buf to the end of the buffer queue. The buf is copied - * and the amount of copied bytes is returned. - * CURLE_AGAIN is returned if the buffer queue is full. - */ -CURLcode Curl_bufq_write(struct bufq *q, - const uint8_t *buf, size_t len, - size_t *pnwritten); - -CURLcode Curl_bufq_cwrite(struct bufq *q, - const char *buf, size_t len, - size_t *pnwritten); - -/** - * Read buf from the start of the buffer queue. The buf is copied - * and the amount of copied bytes is returned. - */ -CURLcode Curl_bufq_read(struct bufq *q, uint8_t *buf, size_t len, - size_t *pnread); - -CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len, - size_t *pnread); - -/** - * Peek at the head chunk in the buffer queue. Returns a pointer to - * the chunk buf (at the current offset) and its length. Does not - * modify the buffer queue. - * Returns TRUE iff bytes are available. Sets `pbuf` to NULL and `plen` - * to 0 when no bytes are available. - * Repeated calls return the same information until the buffer queue - * is modified, see `Curl_bufq_skip()`` - */ -bool Curl_bufq_peek(struct bufq *q, - const uint8_t **pbuf, size_t *plen); - -bool Curl_bufq_peek_at(struct bufq *q, size_t offset, - const uint8_t **pbuf, size_t *plen); - -/** - * Tell the buffer queue to discard `amount` buf bytes at the head of the - * queue. Skipping more buf than is currently buffered will empty the queue. - */ -void Curl_bufq_skip(struct bufq *q, size_t amount); - -typedef CURLcode Curl_bufq_writer(void *writer_ctx, - const uint8_t *buf, size_t len, - size_t *pwritten); -/** - * Passes the chunks in the buffer queue to the writer and returns - * the amount of buf written. A writer may return -1 and CURLE_AGAIN - * to indicate blocking at which point the queue will stop and return - * the amount of buf passed so far. - * -1 is returned on any other errors reported by the writer. - * Note that in case of a -1 chunks may have been written and - * the buffer queue will have different length than before. - */ -CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer, - void *writer_ctx, size_t *pwritten); - -typedef CURLcode Curl_bufq_reader(void *reader_ctx, - uint8_t *buf, size_t len, - size_t *pnread); - -/** - * Read bytes and append them to the end of the buffer queue until the - * reader returns blocking or the queue is full. A reader returns - * CURLE_AGAIN to indicate blocking. - * Returns the total amount of buf read (may be 0) in `pnread` on success. - * Note that in case of an error chunks may have been read and - * the buffer queue will have different length than before. - */ -CURLcode Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader, - void *reader_ctx, size_t *pnread); - -/** - * Read *once* up to `max_len` bytes and append it to the buffer. - * if `max_len` is 0, no limit is imposed besides the chunk space. - * Returns the total amount of buf read (may be 0) or -1 on other - * reader errors. - */ -CURLcode Curl_bufq_sipn(struct bufq *q, size_t max_len, - Curl_bufq_reader *reader, void *reader_ctx, - size_t *pnread); - -/** - * Write buf to the end of the buffer queue. - * Write bufq content or passed `buf` directly using the `writer` - * callback when it sees fit. 'buf' might get passed directly - * on or is placed into the buffer, depending on `len` and current - * amount buffered, chunk size, etc. - */ -CURLcode Curl_bufq_write_pass(struct bufq *q, - const uint8_t *buf, size_t len, - Curl_bufq_writer *writer, void *writer_ctx, - size_t *pwritten); - -#endif /* HEADER_CURL_BUFQ_H */ diff --git a/vendor/curl/lib/bufref.c b/vendor/curl/lib/bufref.c deleted file mode 100644 index 50fafdac0..000000000 --- a/vendor/curl/lib/bufref.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "bufref.h" -#include "curlx/strdup.h" - -#ifdef DEBUGBUILD -#define SIGNATURE 0x5c48e9b2 /* Random pattern. */ -#endif - -/* - * Init a bufref struct. - */ -void Curl_bufref_init(struct bufref *br) -{ - DEBUGASSERT(br); - br->dtor = NULL; - br->ptr = NULL; - br->len = 0; - -#ifdef DEBUGBUILD - br->signature = SIGNATURE; -#endif -} - -/* - * Free the buffer and re-init the necessary fields. It does not touch the - * 'signature' field and thus this buffer reference can be reused. - */ - -void Curl_bufref_free(struct bufref *br) -{ - DEBUGASSERT(br); - DEBUGASSERT(br->signature == SIGNATURE); - DEBUGASSERT(br->ptr || !br->len); - - if(br->ptr && br->dtor) - br->dtor(CURL_UNCONST(br->ptr)); - - br->dtor = NULL; - br->ptr = NULL; - br->len = 0; -} - -/* - * Set the buffer reference to new values. The previously referenced buffer - * is released before assignment. - */ -void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len, - void (*dtor)(void *)) -{ - DEBUGASSERT(ptr || !len); - DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH); - - Curl_bufref_free(br); - br->ptr = (const unsigned char *)ptr; - br->len = len; - br->dtor = dtor; -} - -/* - * Get a pointer to the referenced buffer. - */ -const unsigned char *Curl_bufref_uptr(const struct bufref *br) -{ - DEBUGASSERT(br); - DEBUGASSERT(br->signature == SIGNATURE); - DEBUGASSERT(br->ptr || !br->len); - - return br->ptr; -} - -/* - * Get a pointer to the referenced string. - */ -const char *Curl_bufref_ptr(const struct bufref *br) -{ - DEBUGASSERT(br); - DEBUGASSERT(br->signature == SIGNATURE); - DEBUGASSERT(br->ptr || !br->len); - - return (const char *)br->ptr; -} - -/* - * Get the length of the referenced buffer data. - */ -size_t Curl_bufref_len(const struct bufref *br) -{ - DEBUGASSERT(br); - DEBUGASSERT(br->signature == SIGNATURE); - DEBUGASSERT(br->ptr || !br->len); - - return br->len; -} - -CURLcode Curl_bufref_memdup0(struct bufref *br, const void *ptr, size_t len) -{ - unsigned char *cpy = NULL; - - DEBUGASSERT(br); - DEBUGASSERT(br->signature == SIGNATURE); - DEBUGASSERT(br->ptr || !br->len); - DEBUGASSERT(ptr || !len); - DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH); - - if(ptr) { - cpy = curlx_memdup0(ptr, len); - if(!cpy) - return CURLE_OUT_OF_MEMORY; - } - - Curl_bufref_set(br, cpy, len, curl_free); - return CURLE_OK; -} diff --git a/vendor/curl/lib/bufref.h b/vendor/curl/lib/bufref.h deleted file mode 100644 index 5d331adbd..000000000 --- a/vendor/curl/lib/bufref.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef HEADER_CURL_BUFREF_H -#define HEADER_CURL_BUFREF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* - * Generic buffer reference. - */ -struct bufref { - void (*dtor)(void *); /* Associated destructor. */ - const unsigned char *ptr; /* Referenced data buffer. */ - size_t len; /* The data size in bytes. */ -#ifdef DEBUGBUILD - int signature; /* Detect API use mistakes. */ -#endif -}; - -void Curl_bufref_init(struct bufref *br); -void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len, - void (*dtor)(void *)); -const char *Curl_bufref_ptr(const struct bufref *br); -const unsigned char *Curl_bufref_uptr(const struct bufref *br); -size_t Curl_bufref_len(const struct bufref *br); -CURLcode Curl_bufref_memdup0(struct bufref *br, const void *ptr, size_t len); -void Curl_bufref_free(struct bufref *br); - -/* return a strdup() version of the buffer */ -#define Curl_bufref_dup(x) curlx_strdup(Curl_bufref_ptr(x)) - -#endif diff --git a/vendor/curl/lib/cf-dns.c b/vendor/curl/lib/cf-dns.c deleted file mode 100644 index e763b8ed3..000000000 --- a/vendor/curl/lib/cf-dns.c +++ /dev/null @@ -1,667 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "curl_addrinfo.h" -#include "cfilters.h" -#include "connect.h" -#include "dnscache.h" -#include "httpsrr.h" -#include "curl_trc.h" -#include "progress.h" -#include "url.h" -#include "cf-dns.h" - - -struct cf_dns_ctx { - struct Curl_dns_entry *dns; - CURLcode resolv_result; - uint32_t resolv_id; - uint16_t port; - uint8_t dns_queries; - uint8_t transport; - BIT(started); - BIT(announced); - BIT(abstract_unix_socket); - BIT(complete_resolve); - BIT(for_proxy); - char hostname[1]; -}; - -static struct cf_dns_ctx *cf_dns_ctx_create(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, uint8_t transport, - bool abstract_unix_socket, - bool for_proxy, - bool complete_resolve, - struct Curl_dns_entry *dns) -{ - struct cf_dns_ctx *ctx; - size_t hlen = strlen(hostname); - - ctx = curlx_calloc(1, sizeof(*ctx) + hlen); - if(!ctx) - return NULL; - - ctx->port = port; - ctx->dns_queries = dns_queries; - ctx->transport = transport; - ctx->abstract_unix_socket = abstract_unix_socket; - ctx->for_proxy = for_proxy; - ctx->complete_resolve = complete_resolve; - ctx->dns = Curl_dns_entry_link(data, dns); - ctx->started = !!ctx->dns; - if(hlen) - memcpy(ctx->hostname, hostname, hlen); - - CURL_TRC_DNS(data, "created DNS filter for %s:%u, transport=%x, queries=%x", - ctx->hostname, ctx->port, ctx->transport, ctx->dns_queries); - return ctx; -} - -static void cf_dns_ctx_destroy(struct Curl_easy *data, - struct cf_dns_ctx *ctx) -{ - if(ctx) { - Curl_dns_entry_unlink(data, &ctx->dns); - curlx_free(ctx); - } -} - -#ifdef CURLVERBOSE -static void cf_dns_report_addr(struct Curl_easy *data, - struct dynbuf *tmp, - const char *label, - int ai_family, - const struct Curl_addrinfo *ai) -{ - char buf[MAX_IPADR_LEN]; - const char *sep = ""; - CURLcode result; - - curlx_dyn_reset(tmp); - for(; ai; ai = ai->ai_next) { - if(ai->ai_family == ai_family) { - Curl_printable_address(ai, buf, sizeof(buf)); - result = curlx_dyn_addf(tmp, "%s%s", sep, buf); - if(result) { - infof(data, "too many IP, cannot show"); - return; - } - sep = ", "; - } - } - - infof(data, "%s%s", label, - (curlx_dyn_len(tmp) ? curlx_dyn_ptr(tmp) : "(none)")); -} - -static void cf_dns_report(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct Curl_dns_entry *dns) -{ - struct cf_dns_ctx *ctx = cf->ctx; - struct dynbuf tmp; - - if(!Curl_trc_is_verbose(data) || - /* ignore no name or numerical IP addresses */ - !dns->hostname[0] || Curl_host_is_ipnum(dns->hostname)) - return; - - switch(ctx->transport) { - case TRNSPRT_UNIX: -#ifdef USE_UNIX_SOCKETS - CURL_TRC_CF(data, cf, "resolved unix domain %s", - Curl_conn_get_unix_path(data->conn)); -#else - DEBUGASSERT(0); -#endif - break; - default: - curlx_dyn_init(&tmp, 1024); - infof(data, "Host %s:%u was resolved.", dns->hostname, dns->port); -#ifdef CURLRES_IPV6 - cf_dns_report_addr(data, &tmp, "IPv6: ", AF_INET6, dns->addr); -#endif - cf_dns_report_addr(data, &tmp, "IPv4: ", AF_INET, dns->addr); -#ifdef USE_HTTPSRR - if(!dns->hinfo) - infof(data, "HTTPS-RR: -"); - else if(!Curl_httpsrr_applicable(data, dns->hinfo)) - infof(data, "HTTPS-RR: not applicable"); - else { - CURLcode result = Curl_httpsrr_print(&tmp, dns->hinfo); - if(!result) - infof(data, "HTTPS-RR: %s", curlx_dyn_ptr(&tmp)); - else - infof(data, "Error printing HTTPS-RR information"); - } -#endif - curlx_dyn_free(&tmp); - break; - } -} -#else -#define cf_dns_report(x, y, z) Curl_nop_stmt -#endif - -/************************************************************* - * Resolve the address of the server or proxy - *************************************************************/ -static CURLcode cf_dns_start(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct Curl_dns_entry **pdns) -{ - struct cf_dns_ctx *ctx = cf->ctx; - timediff_t timeout_ms = Curl_timeleft_ms(data); - CURLcode result; - - *pdns = NULL; - -#ifdef USE_UNIX_SOCKETS - if(ctx->transport == TRNSPRT_UNIX) { - CURL_TRC_CF(data, cf, "resolve unix socket %s", ctx->hostname); - return Curl_resolv_unix(data, ctx->hostname, - (bool)cf->conn->bits.abstract_unix_socket, pdns); - } -#endif - - /* Resolve target host right on */ - CURL_TRC_CF(data, cf, "cf_dns_start host %s:%u", ctx->hostname, ctx->port); - if(Curl_is_ipv4addr(ctx->hostname)) - ctx->dns_queries |= CURL_DNSQ_A; -#ifdef USE_IPV6 - else if(Curl_is_ipaddr(ctx->hostname)) /* not ipv4, must be ipv6 then */ - ctx->dns_queries |= CURL_DNSQ_AAAA; -#endif - result = Curl_resolv(data, ctx->dns_queries, - ctx->hostname, ctx->port, ctx->transport, - (bool)ctx->for_proxy, timeout_ms, - &ctx->resolv_id, pdns); - DEBUGASSERT(!result || !*pdns); - if(!result) { /* resolved right away, either sync or from dnscache */ - DEBUGASSERT(*pdns); - return CURLE_OK; - } - else if(result == CURLE_AGAIN) { /* async resolv in progress */ - return CURLE_OK; - } - else if(result == CURLE_OPERATION_TIMEDOUT) { /* took too long */ - failf(data, "Failed to resolve '%s' with timeout after %" - FMT_TIMEDIFF_T " ms", ctx->hostname, - curlx_ptimediff_ms(Curl_pgrs_now(data), - &data->progress.t_startsingle)); - return CURLE_OPERATION_TIMEDOUT; - } - else { - DEBUGASSERT(result); - failf(data, "Could not resolve: %s", ctx->hostname); - return result; - } -} - -#define CURL_HEV3_RESOLVE_DELAY_MS 50 - -static bool cf_dns_ready_to_connect(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_dns_ctx *ctx = cf->ctx; - - if(ctx->resolv_result) - return TRUE; - else if(ctx->dns) - return TRUE; -#ifdef USE_CURL_ASYNC - else { - /* We want AAAA answer as we prefer ipv6. If a sub-filter desires - * HTTPS-RR, we check for that query as well. */ - uint8_t wanted_answers = CURL_DNSQ_AAAA; - if(Curl_conn_cf_wants_httpsrr(cf, data)) - wanted_answers |= CURL_DNSQ_HTTPS; - - /* Note: if a query was never started, it is considered to have - * an answer (e.g. a negative one). */ - if(Curl_resolv_has_answers(data, ctx->resolv_id, wanted_answers)) - return TRUE; - /* If the wanted answers are not available after a delay, - * we let the connect attempts start anyway. */ - return Curl_resolv_elapsed_ms(data, ctx->resolv_id) >= - CURL_HEV3_RESOLVE_DELAY_MS; - } -#else - (void)data; - DEBUGASSERT(0); /* We should not come here */ - return FALSE; -#endif /* USE_CURL_ASYNC */ -} - -static CURLcode cf_dns_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_dns_ctx *ctx = cf->ctx; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - if(!ctx->started) { - ctx->started = TRUE; - ctx->resolv_result = cf_dns_start(cf, data, &ctx->dns); - } - - if(!ctx->dns && !ctx->resolv_result) { - ctx->resolv_result = - Curl_resolv_take_result(data, ctx->resolv_id, &ctx->dns); - } - - if(ctx->resolv_result) { - CURL_TRC_CF(data, cf, "error resolving: %d", ctx->resolv_result); - return ctx->resolv_result; - } - - if(ctx->dns && !ctx->announced) { - ctx->announced = TRUE; - if(cf->sockindex == FIRSTSOCKET) { - cf->conn->bits.dns_resolved = TRUE; - Curl_pgrsTime(data, TIMER_NAMELOOKUP); - } - cf_dns_report(cf, data, ctx->dns); - } - - if(!cf_dns_ready_to_connect(cf, data)) { - return CURLE_OK; - } - - if(cf->next && !cf->next->connected) { - bool sub_done; - CURLcode result = Curl_conn_cf_connect(cf->next, data, &sub_done); - if(result || !sub_done) - return result; - DEBUGASSERT(sub_done); - } - - /* sub filter chain is connected */ - CURL_TRC_CF(data, cf, "connected filter chain below"); - if(ctx->complete_resolve && !ctx->dns && !ctx->resolv_result) { - /* This filter only connects when it has resolved everything. */ - CURL_TRC_CF(data, cf, "delay connect until resolve complete"); - return CURLE_OK; - } - *done = TRUE; - cf->connected = TRUE; - Curl_resolv_destroy(data, ctx->resolv_id); - return CURLE_OK; -} - -static void cf_dns_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_dns_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "destroy"); - cf_dns_ctx_destroy(data, ctx); -} - -static void cf_dns_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - cf->connected = FALSE; - if(cf->next) - cf->next->cft->do_close(cf->next, data); -} - -static CURLcode cf_dns_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ -#ifdef USE_CURL_ASYNC - if(!cf->connected) - return Curl_resolv_pollset(data, ps); -#else - (void)cf; - (void)data; - (void)ps; -#endif - return CURLE_OK; -} - -static CURLcode cf_dns_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - struct cf_dns_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - (void)arg1; - (void)arg2; - switch(event) { - case CF_CTRL_DATA_DONE: - if(ctx->dns) { - /* Should only come here when the connect attempt failed and - * `data` is giving up on it. On a successful connect, we already - * unlinked the DNS entry. */ - Curl_dns_entry_unlink(data, &ctx->dns); - } - break; - default: - break; - } - return result; -} - -struct Curl_cftype Curl_cft_dns = { - "DNS", - CF_TYPE_SETUP, - CURL_LOG_LVL_NONE, - cf_dns_destroy, - cf_dns_connect, - cf_dns_close, - Curl_cf_def_shutdown, - cf_dns_adjust_pollset, - Curl_cf_def_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - cf_dns_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, -}; - -static CURLcode cf_dns_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool abstract_unix_socket, - bool for_proxy, - bool complete_resolve, - struct Curl_dns_entry *dns) -{ - struct Curl_cfilter *cf = NULL; - struct cf_dns_ctx *ctx; - CURLcode result = CURLE_OK; - - (void)data; - ctx = cf_dns_ctx_create(data, dns_queries, hostname, port, transport, - abstract_unix_socket, for_proxy, - complete_resolve, dns); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = Curl_cf_create(&cf, &Curl_cft_dns, ctx); - -out: - *pcf = result ? NULL : cf; - if(result) - cf_dns_ctx_destroy(data, ctx); - return result; -} - -/* Create a "resolv" filter for the transfer's connection. Figures - * out the hostname/path and port where to connect to. */ -static CURLcode cf_dns_conn_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - uint8_t dns_queries, - uint8_t transport, - bool complete_resolve, - struct Curl_dns_entry *dns) -{ - struct connectdata *conn = data->conn; - const char *hostname = NULL; - uint16_t port = 0; - bool abstract_unix_socket = FALSE, for_proxy = FALSE; - -#ifdef USE_UNIX_SOCKETS - { - const char *unix_path = Curl_conn_get_unix_path(conn); - if(unix_path) { - DEBUGASSERT(transport == TRNSPRT_UNIX); - hostname = unix_path; - abstract_unix_socket = (bool)conn->bits.abstract_unix_socket; - } - } -#endif - -#ifndef CURL_DISABLE_PROXY - if(!hostname && conn->bits.proxy) { - for_proxy = TRUE; - hostname = conn->bits.socksproxy ? - conn->socks_proxy.host.name : conn->http_proxy.host.name; - port = conn->bits.socksproxy ? - conn->socks_proxy.port : conn->http_proxy.port; - } -#endif - if(!hostname) { - struct hostname *ehost; - ehost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host; - /* If not connecting via a proxy, extract the port from the URL, if it is - * there, thus overriding any defaults that might have been set above. */ - hostname = ehost->name; - port = conn->bits.conn_to_port ? - conn->conn_to_port : (uint16_t)conn->remote_port; - } - - if(!hostname) { - DEBUGASSERT(0); - return CURLE_FAILED_INIT; - } - return cf_dns_create(pcf, data, dns_queries, - hostname, port, transport, - abstract_unix_socket, for_proxy, - complete_resolve, dns); -} - -/* Adds a "resolv" filter at the top of the connection's filter chain. - * For FIRSTSOCKET, the `dns` parameter may be NULL. The filter will - * figure out hostname and port to connect to and start the DNS resolve - * on the first connect attempt. - * For SECONDARYSOCKET, the `dns` parameter must be given. - */ -CURLcode Curl_cf_dns_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - uint8_t dns_queries, - uint8_t transport, - struct Curl_dns_entry *dns) -{ - struct Curl_cfilter *cf = NULL; - CURLcode result; - - DEBUGASSERT(data); - if(sockindex == FIRSTSOCKET) - result = cf_dns_conn_create(&cf, data, dns_queries, transport, FALSE, dns); - else if(dns) { - result = cf_dns_create(&cf, data, dns_queries, - dns->hostname, dns->port, transport, - FALSE, FALSE, FALSE, dns); - } - else { - DEBUGASSERT(0); - result = CURLE_FAILED_INIT; - } - if(result) - goto out; - Curl_conn_cf_add(data, conn, sockindex, cf); -out: - return result; -} - -/* Insert a new "resolv" filter directly after `cf`. It will - * start a DNS resolve for the given hostnmae and port on the - * first connect attempt. - * See socks.c on how this is used to make a non-blocking DNS - * resolve during connect. - */ -CURLcode Curl_cf_dns_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool complete_resolve) -{ - struct Curl_cfilter *cf; - CURLcode result; - - result = cf_dns_create(&cf, data, dns_queries, - hostname, port, transport, - FALSE, FALSE, complete_resolve, NULL); - if(result) - return result; - - Curl_conn_cf_insert_after(cf_at, cf); - return CURLE_OK; -} - -/* Return the resolv result from the first "resolv" filter, starting - * the given filter `cf` downwards. - */ -static CURLcode cf_dns_result(struct Curl_cfilter *cf) -{ - for(; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_dns) { - struct cf_dns_ctx *ctx = cf->ctx; - if(ctx->dns || ctx->resolv_result) - return ctx->resolv_result; - return CURLE_AGAIN; - } - } - return CURLE_FAILED_INIT; -} - -/* Return the result of the DNS resolution. Searches for a "resolv" - * filter from the top of the filter chain down. Returns - * - CURLE_AGAIN when not done yet - * - CURLE_OK when DNS was successfully resolved - * - CURLR_FAILED_INIT when no resolv filter was found - * - error returned by the DNS resolv - */ -CURLcode Curl_conn_dns_result(struct connectdata *conn, int sockindex) -{ - return cf_dns_result(conn->cfilter[sockindex]); -} - -static const struct Curl_addrinfo *cf_dns_get_nth_ai( - struct Curl_cfilter *cf, - const struct Curl_addrinfo *ai, - int ai_family, unsigned int index) -{ - struct cf_dns_ctx *ctx = cf->ctx; - unsigned int i = 0; - - if((ai_family == AF_INET) && !(ctx->dns_queries & CURL_DNSQ_A)) - return NULL; -#ifdef USE_IPV6 - if((ai_family == AF_INET6) && !(ctx->dns_queries & CURL_DNSQ_AAAA)) - return NULL; -#endif - for(i = 0; ai; ai = ai->ai_next) { - if(ai->ai_family == ai_family) { - if(i == index) - return ai; - ++i; - } - } - return NULL; -} - -/* Return the addrinfo at `index` for the given `family` from the - * first "resolve" filter underneath `cf`. If the DNS resolving is - * not done yet or if no address for the family exists, returns NULL. - */ -const struct Curl_addrinfo *Curl_cf_dns_get_ai(struct Curl_cfilter *cf, - struct Curl_easy *data, - int ai_family, - unsigned int index) -{ - (void)data; - for(; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_dns) { - struct cf_dns_ctx *ctx = cf->ctx; - if(ctx->resolv_result) - return NULL; - else if(ctx->dns) - return cf_dns_get_nth_ai(cf, ctx->dns->addr, ai_family, index); - else - return Curl_resolv_get_ai(data, ctx->resolv_id, ai_family, index); - } - } - return NULL; -} - -/* Return the addrinfo at `index` for the given `family` from the - * first "resolve" filter at the connection. If the DNS resolving is - * not done yet or if no address for the family exists, returns NULL. - */ -const struct Curl_addrinfo *Curl_conn_dns_get_ai(struct Curl_easy *data, - int sockindex, int ai_family, - unsigned int index) -{ - struct connectdata *conn = data->conn; - return Curl_cf_dns_get_ai(conn->cfilter[sockindex], data, ai_family, index); -} - -#ifdef USE_HTTPSRR -/* Return the HTTPS-RR info from the first "resolve" filter at the - * connection. If the DNS resolving is not done yet or if there - * is no HTTPS-RR info, returns NULL. - */ -const struct Curl_https_rrinfo *Curl_conn_dns_get_https(struct Curl_easy *data, - int sockindex) -{ - struct Curl_cfilter *cf = data->conn->cfilter[sockindex]; - for(; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_dns) { - struct cf_dns_ctx *ctx = cf->ctx; - if(ctx->dns) - return ctx->dns->hinfo; - else - return Curl_resolv_get_https(data, ctx->resolv_id); - } - } - return NULL; -} - -bool Curl_conn_dns_resolved_https(struct Curl_easy *data, int sockindex) -{ - struct Curl_cfilter *cf = data->conn->cfilter[sockindex]; - for(; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_dns) { - struct cf_dns_ctx *ctx = cf->ctx; - if(ctx->dns) - return TRUE; - else - return Curl_resolv_knows_https(data, ctx->resolv_id); - } - } - return FALSE; -} - -#endif /* USE_HTTPSRR */ diff --git a/vendor/curl/lib/cf-dns.h b/vendor/curl/lib/cf-dns.h deleted file mode 100644 index 3c46b1bf3..000000000 --- a/vendor/curl/lib/cf-dns.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef HEADER_CURL_CF_DNS_H -#define HEADER_CURL_CF_DNS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_easy; -struct connectdata; -struct Curl_dns_entry; -struct Curl_addrinfo; - -CURLcode Curl_cf_dns_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - uint8_t dns_queries, - uint8_t transport, - struct Curl_dns_entry *dns); - -CURLcode Curl_cf_dns_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool complete_resolve); - -CURLcode Curl_conn_dns_result(struct connectdata *conn, int sockindex); - -const struct Curl_addrinfo *Curl_conn_dns_get_ai(struct Curl_easy *data, - int sockindex, - int ai_family, - unsigned int index); - -const struct Curl_addrinfo *Curl_cf_dns_get_ai(struct Curl_cfilter *cf, - struct Curl_easy *data, - int ai_family, - unsigned int index); - -#ifdef USE_HTTPSRR -const struct Curl_https_rrinfo *Curl_conn_dns_get_https(struct Curl_easy *data, - int sockindex); -bool Curl_conn_dns_resolved_https(struct Curl_easy *data, int sockindex); -#else -#define Curl_conn_dns_get_https(a, b) NULL -#define Curl_conn_dns_resolved_https(a, b) TRUE -#endif - -extern struct Curl_cftype Curl_cft_dns; - -#endif /* HEADER_CURL_CF_DNS_H */ diff --git a/vendor/curl/lib/cf-h1-proxy.c b/vendor/curl/lib/cf-h1-proxy.c deleted file mode 100644 index 3c2c8374d..000000000 --- a/vendor/curl/lib/cf-h1-proxy.c +++ /dev/null @@ -1,788 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP) - -#include "urldata.h" -#include "curlx/dynbuf.h" -#include "sendf.h" -#include "http.h" -#include "http1.h" -#include "http_proxy.h" -#include "select.h" -#include "progress.h" -#include "cfilters.h" -#include "cf-h1-proxy.h" -#include "connect.h" -#include "curl_trc.h" -#include "strcase.h" -#include "curlx/strparse.h" - - -typedef enum { - H1_TUNNEL_INIT, /* init/default/no tunnel state */ - H1_TUNNEL_CONNECT, /* CONNECT request is being send */ - H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */ - H1_TUNNEL_RESPONSE, /* CONNECT response received completely */ - H1_TUNNEL_ESTABLISHED, - H1_TUNNEL_FAILED -} h1_tunnel_state; - -/* struct for HTTP CONNECT tunneling */ -struct h1_tunnel_state { - struct dynbuf rcvbuf; - struct dynbuf request_data; - size_t nsent; - size_t headerlines; - struct Curl_chunker ch; - enum keeponval { - KEEPON_DONE, - KEEPON_CONNECT, - KEEPON_IGNORE - } keepon; - curl_off_t cl; /* size of content to read and ignore */ - h1_tunnel_state tunnel_state; - BIT(chunked_encoding); - BIT(close_connection); - BIT(maybe_folded); - BIT(leading_unfold); -}; - -static bool tunnel_is_established(struct h1_tunnel_state *ts) -{ - return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED); -} - -static bool tunnel_is_failed(struct h1_tunnel_state *ts) -{ - return ts && (ts->tunnel_state == H1_TUNNEL_FAILED); -} - -static CURLcode tunnel_reinit(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state *ts) -{ - (void)data; - (void)cf; - DEBUGASSERT(ts); - curlx_dyn_reset(&ts->rcvbuf); - curlx_dyn_reset(&ts->request_data); - ts->tunnel_state = H1_TUNNEL_INIT; - ts->keepon = KEEPON_CONNECT; - ts->cl = 0; - ts->close_connection = FALSE; - ts->maybe_folded = FALSE; - ts->leading_unfold = FALSE; - return CURLE_OK; -} - -static CURLcode tunnel_init(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state **pts) -{ - struct h1_tunnel_state *ts; - - if(cf->conn->scheme->flags & PROTOPT_NOTCPPROXY) { - failf(data, "%s cannot be done over CONNECT", cf->conn->scheme->name); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - ts = curlx_calloc(1, sizeof(*ts)); - if(!ts) - return CURLE_OUT_OF_MEMORY; - - infof(data, "allocate connect buffer"); - - curlx_dyn_init(&ts->rcvbuf, DYN_PROXY_CONNECT_HEADERS); - curlx_dyn_init(&ts->request_data, DYN_HTTP_REQUEST); - Curl_httpchunk_init(data, &ts->ch, TRUE); - - *pts = ts; - return tunnel_reinit(cf, data, ts); -} - -static void h1_tunnel_go_state(struct Curl_cfilter *cf, - struct h1_tunnel_state *ts, - h1_tunnel_state new_state, - struct Curl_easy *data) -{ - if(ts->tunnel_state == new_state) - return; - /* entering this one */ - switch(new_state) { - case H1_TUNNEL_INIT: - CURL_TRC_CF(data, cf, "new tunnel state 'init'"); - tunnel_reinit(cf, data, ts); - break; - - case H1_TUNNEL_CONNECT: - CURL_TRC_CF(data, cf, "new tunnel state 'connect'"); - ts->tunnel_state = H1_TUNNEL_CONNECT; - ts->keepon = KEEPON_CONNECT; - curlx_dyn_reset(&ts->rcvbuf); - break; - - case H1_TUNNEL_RECEIVE: - CURL_TRC_CF(data, cf, "new tunnel state 'receive'"); - ts->tunnel_state = H1_TUNNEL_RECEIVE; - break; - - case H1_TUNNEL_RESPONSE: - CURL_TRC_CF(data, cf, "new tunnel state 'response'"); - ts->tunnel_state = H1_TUNNEL_RESPONSE; - break; - - case H1_TUNNEL_ESTABLISHED: - CURL_TRC_CF(data, cf, "new tunnel state 'established'"); - infof(data, "CONNECT phase completed"); - data->state.authproxy.done = TRUE; - data->state.authproxy.multipass = FALSE; - FALLTHROUGH(); - case H1_TUNNEL_FAILED: - if(new_state == H1_TUNNEL_FAILED) - CURL_TRC_CF(data, cf, "new tunnel state 'failed'"); - ts->tunnel_state = new_state; - curlx_dyn_reset(&ts->rcvbuf); - curlx_dyn_reset(&ts->request_data); - /* restore the protocol pointer */ - data->info.httpcode = 0; /* clear it as it might have been used for the - proxy */ - /* If a proxy-authorization header was used for the proxy, then we should - make sure that it is not accidentally used for the document request - after we have connected. Let's thus free and clear it here. */ - curlx_safefree(data->req.proxyuserpwd); - break; - } -} - -static void tunnel_free(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - if(cf) { - struct h1_tunnel_state *ts = cf->ctx; - if(ts) { - h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data); - curlx_dyn_free(&ts->rcvbuf); - curlx_dyn_free(&ts->request_data); - Curl_httpchunk_free(data, &ts->ch); - curlx_free(ts); - cf->ctx = NULL; - } - } -} - -static bool tunnel_want_send(struct h1_tunnel_state *ts) -{ - return ts->tunnel_state == H1_TUNNEL_CONNECT; -} - -static CURLcode start_CONNECT(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state *ts) -{ - struct httpreq *req = NULL; - int http_minor; - CURLcode result; - - /* This only happens if we have looped here due to authentication reasons, - and we do not really use the newly cloned URL here then. Free it. */ - curlx_safefree(data->req.newurl); - - result = Curl_http_proxy_create_CONNECT(&req, cf, data, 1); - if(result) - goto out; - - infof(data, "Establish HTTP proxy tunnel to %s", req->authority); - - curlx_dyn_reset(&ts->request_data); - ts->nsent = 0; - ts->headerlines = 0; - http_minor = (cf->conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? 0 : 1; - - result = Curl_h1_req_write_head(req, http_minor, &ts->request_data); - if(!result) - result = Curl_creader_set_null(data); - -out: - if(result) - failf(data, "Failed sending CONNECT to proxy"); - if(req) - Curl_http_req_free(req); - return result; -} - -static CURLcode send_CONNECT(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state *ts, - bool *done) -{ - const uint8_t *buf = curlx_dyn_uptr(&ts->request_data); - size_t request_len = curlx_dyn_len(&ts->request_data); - size_t blen = request_len; - CURLcode result = CURLE_OK; - size_t nwritten; - - if(blen <= ts->nsent) - goto out; /* we are done */ - - blen -= ts->nsent; - buf += ts->nsent; - - result = cf->next->cft->do_send(cf->next, data, buf, blen, FALSE, &nwritten); - if(result) { - if(result == CURLE_AGAIN) - result = CURLE_OK; - goto out; - } - - DEBUGASSERT(blen >= nwritten); - ts->nsent += nwritten; - Curl_debug(data, CURLINFO_HEADER_OUT, (const char *)buf, nwritten); - -out: - if(result) - failf(data, "Failed sending CONNECT to proxy"); - *done = (!result && (ts->nsent >= request_len)); - return result; -} - -static CURLcode on_resp_header(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state *ts, - const char *header) -{ - CURLcode result = CURLE_OK; - struct SingleRequest *k = &data->req; - (void)cf; - - if((checkprefix("WWW-Authenticate:", header) && (401 == k->httpcode)) || - (checkprefix("Proxy-authenticate:", header) && (407 == k->httpcode))) { - - bool proxy = (k->httpcode == 407); - char *auth = Curl_copy_header_value(header); - if(!auth) - return CURLE_OUT_OF_MEMORY; - - CURL_TRC_CF(data, cf, "CONNECT: fwd auth header '%s'", header); - result = Curl_http_input_auth(data, proxy, auth); - - curlx_free(auth); - - if(result) - return result; - } - else if(checkprefix("Content-Length:", header)) { - if(k->httpcode / 100 == 2) { - /* A client MUST ignore any Content-Length or Transfer-Encoding - header fields received in a successful response to CONNECT. - "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - infof(data, "Ignoring Content-Length in CONNECT %03d response", - k->httpcode); - } - else { - const char *p = header + strlen("Content-Length:"); - if(curlx_str_numblanks(&p, &ts->cl)) { - failf(data, "Unsupported Content-Length value"); - return CURLE_WEIRD_SERVER_REPLY; - } - } - } - else if(Curl_compareheader(header, - STRCONST("Connection:"), STRCONST("close"))) - ts->close_connection = TRUE; - else if(checkprefix("Transfer-Encoding:", header)) { - if(k->httpcode / 100 == 2) { - /* A client MUST ignore any Content-Length or Transfer-Encoding - header fields received in a successful response to CONNECT. - "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - infof(data, "Ignoring Transfer-Encoding in " - "CONNECT %03d response", k->httpcode); - } - else if(Curl_compareheader(header, - STRCONST("Transfer-Encoding:"), - STRCONST("chunked"))) { - infof(data, "CONNECT responded chunked"); - ts->chunked_encoding = TRUE; - /* reset our chunky engine */ - Curl_httpchunk_reset(data, &ts->ch, TRUE); - } - } - else if(Curl_compareheader(header, - STRCONST("Proxy-Connection:"), - STRCONST("close"))) - ts->close_connection = TRUE; - else if(!strncmp(header, "HTTP/1.", 7) && - ((header[7] == '0') || (header[7] == '1')) && - (header[8] == ' ') && - ISDIGIT(header[9]) && ISDIGIT(header[10]) && ISDIGIT(header[11]) && - !ISDIGIT(header[12])) { - /* store the HTTP code from the proxy */ - data->info.httpproxycode = k->httpcode = ((header[9] - '0') * 100) + - ((header[10] - '0') * 10) + (header[11] - '0'); - } - return result; -} - -static CURLcode single_header(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state *ts) -{ - CURLcode result = CURLE_OK; - const char *linep = curlx_dyn_ptr(&ts->rcvbuf); - size_t line_len = curlx_dyn_len(&ts->rcvbuf); /* bytes in this line */ - const struct SingleRequest *k = &data->req; - int writetype; - ts->headerlines++; - - /* output debug if that is requested */ - Curl_debug(data, CURLINFO_HEADER_IN, linep, line_len); - - /* send the header to the callback */ - writetype = CLIENTWRITE_HEADER | CLIENTWRITE_CONNECT | - (ts->headerlines == 1 ? CLIENTWRITE_STATUS : 0); - result = Curl_client_write(data, writetype, linep, line_len); - if(result) - return result; - - result = Curl_bump_headersize(data, line_len, TRUE); - if(result) - return result; - - /* Newlines are CRLF, so the CR is ignored as the line is not - really terminated until the LF comes. Treat a following CR - as end-of-headers as well.*/ - - if(ISNEWLINE(linep[0])) { - /* end of response-headers from the proxy */ - - if((407 == k->httpcode) && !data->state.authproblem) { - /* If we get a 407 response code with content length - when we have no auth problem, we must ignore the - whole response-body */ - ts->keepon = KEEPON_IGNORE; - - if(ts->cl) { - infof(data, "Ignore %" FMT_OFF_T " bytes of response-body", ts->cl); - } - else if(ts->chunked_encoding) { - infof(data, "Ignore chunked response-body"); - } - else { - /* without content-length or chunked encoding, we - cannot keep the connection alive since the close is - the end signal so we bail out at once instead */ - CURL_TRC_CF(data, cf, "CONNECT: no content-length or chunked"); - ts->keepon = KEEPON_DONE; - } - } - else { - ts->keepon = KEEPON_DONE; - } - - DEBUGASSERT(ts->keepon == KEEPON_IGNORE || - ts->keepon == KEEPON_DONE); - return result; - } - - result = on_resp_header(cf, data, ts, linep); - if(result) - return result; - - curlx_dyn_reset(&ts->rcvbuf); - return result; -} - -static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state *ts, - bool *done) -{ - CURLcode result = CURLE_OK; - int error; - -#define SELECT_OK 0 -#define SELECT_ERROR 1 - - error = SELECT_OK; - *done = FALSE; - - while(ts->keepon) { - size_t nread; - char byte; - - /* Read one byte at a time to avoid a race condition. Wait at most one - second before looping to ensure continuous pgrsUpdates. */ - result = Curl_conn_recv(data, cf->sockindex, &byte, 1, &nread); - if(result == CURLE_AGAIN) - /* socket buffer drained, return */ - return CURLE_OK; - - if(!result) - result = Curl_pgrsUpdate(data); - - if(result) { - ts->keepon = KEEPON_DONE; - break; - } - - if(!nread) { - if(data->set.proxyauth && data->state.authproxy.avail && - data->req.proxyuserpwd) { - /* proxy auth was requested and there was proxy auth available, - then deem this as "mere" proxy disconnect */ - ts->close_connection = TRUE; - infof(data, "Proxy CONNECT connection closed"); - } - else { - error = SELECT_ERROR; - failf(data, "Proxy CONNECT aborted"); - } - ts->keepon = KEEPON_DONE; - break; - } - - if(ts->keepon == KEEPON_IGNORE) { - /* This means we are currently ignoring a response-body */ - if(ts->chunked_encoding) { - /* chunked-encoded body, so we need to do the chunked dance - properly to know when the end of the body is reached */ - size_t consumed = 0; - - /* now parse the chunked piece of data so that we can - properly tell when the stream ends */ - result = Curl_httpchunk_read(data, &ts->ch, &byte, 1, &consumed); - if(result) - return result; - if(Curl_httpchunk_is_done(data, &ts->ch)) { - /* we are done reading chunks! */ - infof(data, "chunk reading DONE"); - ts->keepon = KEEPON_DONE; - } - } - else if(ts->cl) { - /* A Content-Length based body: count down the counter - and make sure to break out of the loop when we are done! */ - ts->cl--; - if(ts->cl <= 0) { - ts->keepon = KEEPON_DONE; - break; - } - } - continue; - } - - if(ts->maybe_folded) { - if(ISBLANK(byte)) { - Curl_http_to_fold(&ts->rcvbuf); - ts->leading_unfold = TRUE; - } - else { - result = single_header(cf, data, ts); - if(result) - return result; - /* now handle the new byte */ - } - ts->maybe_folded = FALSE; - } - - if(ts->leading_unfold) { - if(ISBLANK(byte)) - /* skip a bit brother */ - continue; - /* non-blank, insert a space then continue the unfolding */ - if(curlx_dyn_addn(&ts->rcvbuf, " ", 1)) { - failf(data, "CONNECT response too large"); - return CURLE_RECV_ERROR; - } - ts->leading_unfold = FALSE; - } - if(curlx_dyn_addn(&ts->rcvbuf, &byte, 1)) { - failf(data, "CONNECT response too large"); - return CURLE_RECV_ERROR; - } - - /* if this is not the end of a header line then continue */ - if(byte != 0x0a) - continue; - else { - const char *linep = curlx_dyn_ptr(&ts->rcvbuf); - size_t hlen = curlx_dyn_len(&ts->rcvbuf); - if(hlen && ISNEWLINE(linep[0])) { - /* end of headers */ - result = single_header(cf, data, ts); - if(result) - return result; - } - else - ts->maybe_folded = TRUE; - } - - } /* while there is buffer left and loop is requested */ - - if(error) - result = CURLE_RECV_ERROR; - *done = (ts->keepon == KEEPON_DONE); - if(!result && *done && data->info.httpproxycode / 100 != 2) { - /* Deal with the possibly already received authenticate - headers. 'newurl' is set to a new URL if we must loop. */ - result = Curl_http_auth_act(data); - } - return result; -} - -static CURLcode H1_CONNECT(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h1_tunnel_state *ts) -{ - struct connectdata *conn = cf->conn; - CURLcode result; - bool done; - - if(tunnel_is_established(ts)) - return CURLE_OK; - if(tunnel_is_failed(ts)) - return CURLE_RECV_ERROR; /* Need a cfilter close and new bootstrap */ - - do { - - if(Curl_timeleft_ms(data) < 0) { - failf(data, "Proxy CONNECT aborted due to timeout"); - result = CURLE_OPERATION_TIMEDOUT; - goto out; - } - - switch(ts->tunnel_state) { - case H1_TUNNEL_INIT: - /* Prepare the CONNECT request and make a first attempt to send. */ - CURL_TRC_CF(data, cf, "CONNECT start"); - result = start_CONNECT(cf, data, ts); - if(result) - goto out; - h1_tunnel_go_state(cf, ts, H1_TUNNEL_CONNECT, data); - FALLTHROUGH(); - - case H1_TUNNEL_CONNECT: - /* see that the request is completely sent */ - CURL_TRC_CF(data, cf, "CONNECT send"); - result = send_CONNECT(cf, data, ts, &done); - if(result || !done) - goto out; - h1_tunnel_go_state(cf, ts, H1_TUNNEL_RECEIVE, data); - FALLTHROUGH(); - - case H1_TUNNEL_RECEIVE: - /* read what is there */ - CURL_TRC_CF(data, cf, "CONNECT receive"); - result = recv_CONNECT_resp(cf, data, ts, &done); - if(result) - CURL_TRC_CF(data, cf, "error receiving CONNECT response: %d", result); - if(!result) - result = Curl_pgrsUpdate(data); - /* error or not complete yet. return for more multi-multi */ - if(result || !done) - goto out; - /* got it */ - h1_tunnel_go_state(cf, ts, H1_TUNNEL_RESPONSE, data); - FALLTHROUGH(); - - case H1_TUNNEL_RESPONSE: - CURL_TRC_CF(data, cf, "CONNECT response"); - if(data->req.newurl) { - /* not the "final" response, we need to do a follow up request. - * If the other side indicated a connection close, or if someone - * else told us to close this connection, do so now. - */ - Curl_req_soft_reset(&data->req, data); - if(ts->close_connection || conn->bits.close) { - /* Close this filter and the sub-chain, re-connect the - * sub-chain and continue. Closing this filter will - * reset our tunnel state. To avoid recursion, we return - * and expect to be called again. - */ - CURL_TRC_CF(data, cf, "CONNECT need to close+open"); - infof(data, "Connect me again please"); - Curl_conn_cf_close(cf, data); - result = Curl_conn_cf_connect(cf->next, data, &done); - goto out; - } - else { - /* staying on this connection, reset state */ - h1_tunnel_go_state(cf, ts, H1_TUNNEL_INIT, data); - } - } - break; - - default: - break; - } - - } while(data->req.newurl); - - DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE); - if(data->info.httpproxycode / 100 != 2) { - /* a non-2xx response and we have no next URL to try. */ - curlx_safefree(data->req.newurl); - h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data); - failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode); - return CURLE_COULDNT_CONNECT; - } - /* 2xx response, SUCCESS! */ - h1_tunnel_go_state(cf, ts, H1_TUNNEL_ESTABLISHED, data); - infof(data, "CONNECT tunnel established, response %d", - data->info.httpproxycode); - result = CURLE_OK; - -out: - if(result) - h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data); - return result; -} - -static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - CURLcode result; - struct h1_tunnel_state *ts = cf->ctx; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - CURL_TRC_CF(data, cf, "connect"); - result = cf->next->cft->do_connect(cf->next, data, done); - if(result || !*done) - return result; - - *done = FALSE; - if(!ts) { - result = tunnel_init(cf, data, &ts); - if(result) - return result; - cf->ctx = ts; - } - - /* We want "seamless" operations through HTTP proxy tunnel */ - - result = H1_CONNECT(cf, data, ts); - if(result) - goto out; - curlx_safefree(data->req.proxyuserpwd); - -out: - *done = (result == CURLE_OK) && tunnel_is_established(cf->ctx); - if(*done) { - cf->connected = TRUE; - /* The real request will follow the CONNECT, reset request partially */ - Curl_req_soft_reset(&data->req, data); - Curl_client_reset(data); - Curl_pgrsReset(data); - - tunnel_free(cf, data); - } - return result; -} - -static CURLcode cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct h1_tunnel_state *ts = cf->ctx; - CURLcode result = CURLE_OK; - - if(!cf->connected) { - /* If we are not connected, but the filter "below" is - * and not waiting on something, we are tunneling. */ - curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); - if(ts) { - /* when we have sent a CONNECT to a proxy, we should rather either - wait for the socket to become readable to be able to get the - response headers or if we are still sending the request, wait - for write. */ - if(tunnel_want_send(ts)) - result = Curl_pollset_set_out_only(data, ps, sock); - else - result = Curl_pollset_set_in_only(data, ps, sock); - } - else - result = Curl_pollset_set_out_only(data, ps, sock); - } - return result; -} - -static void cf_h1_proxy_destroy(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURL_TRC_CF(data, cf, "destroy"); - tunnel_free(cf, data); -} - -static void cf_h1_proxy_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURL_TRC_CF(data, cf, "close"); - if(cf) { - cf->connected = FALSE; - if(cf->ctx) { - h1_tunnel_go_state(cf, cf->ctx, H1_TUNNEL_INIT, data); - } - if(cf->next) - cf->next->cft->do_close(cf->next, data); - } -} - -struct Curl_cftype Curl_cft_h1_proxy = { - "H1-PROXY", - CF_TYPE_IP_CONNECT | CF_TYPE_PROXY, - 0, - cf_h1_proxy_destroy, - cf_h1_proxy_connect, - cf_h1_proxy_close, - Curl_cf_def_shutdown, - cf_h1_proxy_adjust_pollset, - Curl_cf_def_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - Curl_cf_def_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - Curl_cf_http_proxy_query, -}; - -CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf; - CURLcode result; - - (void)data; - result = Curl_cf_create(&cf, &Curl_cft_h1_proxy, NULL); - if(!result) - Curl_conn_cf_insert_after(cf_at, cf); - return result; -} - -#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */ diff --git a/vendor/curl/lib/cf-h1-proxy.h b/vendor/curl/lib/cf-h1-proxy.h deleted file mode 100644 index 6544ec58d..000000000 --- a/vendor/curl/lib/cf-h1-proxy.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADER_CURL_H1_PROXY_H -#define HEADER_CURL_H1_PROXY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP) - -CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data); - -extern struct Curl_cftype Curl_cft_h1_proxy; - -#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */ - -#endif /* HEADER_CURL_H1_PROXY_H */ diff --git a/vendor/curl/lib/cf-h2-proxy.c b/vendor/curl/lib/cf-h2-proxy.c deleted file mode 100644 index 2f8cc41dd..000000000 --- a/vendor/curl/lib/cf-h2-proxy.c +++ /dev/null @@ -1,1504 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) && \ - defined(USE_NGHTTP2) - -#include - -#include "urldata.h" -#include "url.h" -#include "cfilters.h" -#include "connect.h" -#include "curl_trc.h" -#include "bufq.h" -#include "curlx/dynbuf.h" -#include "dynhds.h" -#include "http2.h" -#include "http_proxy.h" -#include "multiif.h" -#include "sendf.h" -#include "select.h" -#include "cf-h2-proxy.h" - -#define PROXY_H2_CHUNK_SIZE (16 * 1024) - -#define PROXY_HTTP2_HUGE_WINDOW_SIZE (100 * 1024 * 1024) -#define H2_TUNNEL_WINDOW_SIZE (10 * 1024 * 1024) - -#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE) -#define PROXY_H2_NW_SEND_CHUNKS 1 - -#define H2_TUNNEL_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE) -#define H2_TUNNEL_SEND_CHUNKS ((128 * 1024) / PROXY_H2_CHUNK_SIZE) - - -typedef enum { - H2_TUNNEL_INIT, /* init/default/no tunnel state */ - H2_TUNNEL_CONNECT, /* CONNECT request is being send */ - H2_TUNNEL_RESPONSE, /* CONNECT response received completely */ - H2_TUNNEL_ESTABLISHED, - H2_TUNNEL_FAILED -} h2_tunnel_state; - -struct tunnel_stream { - struct http_resp *resp; - struct bufq recvbuf; - struct bufq sendbuf; - char *authority; - int32_t stream_id; - uint32_t error; - h2_tunnel_state state; - BIT(has_final_response); - BIT(closed); - BIT(reset); -}; - -static CURLcode tunnel_stream_init(struct Curl_cfilter *cf, - struct tunnel_stream *ts) -{ - const char *hostname; - uint16_t port; - bool ipv6_ip; - - ts->state = H2_TUNNEL_INIT; - ts->stream_id = -1; - Curl_bufq_init2(&ts->recvbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS, - BUFQ_OPT_SOFT_LIMIT); - Curl_bufq_init(&ts->sendbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS); - - Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip); - - /* host:port with IPv6 support */ - ts->authority = curl_maprintf("%s%s%s:%u", ipv6_ip ? "[" : "", hostname, - ipv6_ip ? "]" : "", port); - if(!ts->authority) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static void tunnel_stream_clear(struct tunnel_stream *ts) -{ - Curl_http_resp_free(ts->resp); - Curl_bufq_free(&ts->recvbuf); - Curl_bufq_free(&ts->sendbuf); - curlx_safefree(ts->authority); - memset(ts, 0, sizeof(*ts)); - ts->state = H2_TUNNEL_INIT; -} - -static void h2_tunnel_go_state(struct Curl_cfilter *cf, - struct tunnel_stream *ts, - h2_tunnel_state new_state, - struct Curl_easy *data) -{ - (void)cf; - - if(ts->state == new_state) - return; - /* leaving this one */ - switch(ts->state) { - case H2_TUNNEL_CONNECT: - data->req.ignorebody = FALSE; - break; - default: - break; - } - /* entering this one */ - switch(new_state) { - case H2_TUNNEL_INIT: - CURL_TRC_CF(data, cf, "[%d] new tunnel state 'init'", ts->stream_id); - tunnel_stream_clear(ts); - break; - - case H2_TUNNEL_CONNECT: - CURL_TRC_CF(data, cf, "[%d] new tunnel state 'connect'", ts->stream_id); - ts->state = H2_TUNNEL_CONNECT; - break; - - case H2_TUNNEL_RESPONSE: - CURL_TRC_CF(data, cf, "[%d] new tunnel state 'response'", ts->stream_id); - ts->state = H2_TUNNEL_RESPONSE; - break; - - case H2_TUNNEL_ESTABLISHED: - CURL_TRC_CF(data, cf, "[%d] new tunnel state 'established'", - ts->stream_id); - infof(data, "CONNECT phase completed"); - data->state.authproxy.done = TRUE; - data->state.authproxy.multipass = FALSE; - FALLTHROUGH(); - case H2_TUNNEL_FAILED: - if(new_state == H2_TUNNEL_FAILED) - CURL_TRC_CF(data, cf, "[%d] new tunnel state 'failed'", ts->stream_id); - ts->state = new_state; - /* If a proxy-authorization header was used for the proxy, then we should - make sure that it is not accidentally used for the document request - after we have connected. Let's thus free and clear it here. */ - curlx_safefree(data->req.proxyuserpwd); - break; - } -} - -struct cf_h2_proxy_ctx { - nghttp2_session *h2; - /* The easy handle used in the current filter call, cleared at return */ - struct cf_call_data call_data; - - struct bufq inbufq; /* network receive buffer */ - struct bufq outbufq; /* network send buffer */ - - struct tunnel_stream tunnel; /* our tunnel CONNECT stream */ - int32_t goaway_error; - int32_t last_stream_id; - BIT(conn_closed); - BIT(rcvd_goaway); - BIT(sent_goaway); - BIT(nw_out_blocked); -}; - -/* How to access `call_data` from a cf_h2 filter */ -#undef CF_CTX_CALL_DATA -#define CF_CTX_CALL_DATA(cf) ((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data - -static void cf_h2_proxy_ctx_clear(struct cf_h2_proxy_ctx *ctx) -{ - struct cf_call_data save = ctx->call_data; - - if(ctx->h2) { - nghttp2_session_del(ctx->h2); - } - Curl_bufq_free(&ctx->inbufq); - Curl_bufq_free(&ctx->outbufq); - tunnel_stream_clear(&ctx->tunnel); - memset(ctx, 0, sizeof(*ctx)); - ctx->call_data = save; -} - -static void cf_h2_proxy_ctx_free(struct cf_h2_proxy_ctx *ctx) -{ - if(ctx) { - cf_h2_proxy_ctx_clear(ctx); - curlx_free(ctx); - } -} - -static void drain_tunnel(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct tunnel_stream *tunnel) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - (void)cf; - if(!tunnel->closed && !tunnel->reset && - !Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) - Curl_multi_mark_dirty(data); -} - -static CURLcode proxy_h2_nw_out_writer(void *writer_ctx, - const uint8_t *buf, size_t buflen, - size_t *pnwritten) -{ - struct Curl_cfilter *cf = writer_ctx; - *pnwritten = 0; - if(cf) { - struct Curl_easy *data = CF_DATA_CURRENT(cf); - CURLcode result; - result = Curl_conn_cf_send(cf->next, data, buf, buflen, FALSE, pnwritten); - CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %d, %zu", - buflen, result, *pnwritten); - return result; - } - return CURLE_FAILED_INIT; -} - -static int proxy_h2_client_new(struct Curl_cfilter *cf, - nghttp2_session_callbacks *cbs) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - nghttp2_option *o; - nghttp2_mem mem = { NULL, Curl_nghttp2_malloc, Curl_nghttp2_free, - Curl_nghttp2_calloc, Curl_nghttp2_realloc }; - - int rc = nghttp2_option_new(&o); - if(rc) - return rc; - /* We handle window updates ourself to enforce buffer limits */ - nghttp2_option_set_no_auto_window_update(o, 1); -#if NGHTTP2_VERSION_NUM >= 0x013200 - /* with 1.50.0 */ - /* turn off RFC 9113 leading and trailing white spaces validation against - HTTP field value. */ - nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1); -#endif - rc = nghttp2_session_client_new3(&ctx->h2, cbs, cf, o, &mem); - nghttp2_option_del(o); - return rc; -} - -static int proxy_h2_should_close_session(struct cf_h2_proxy_ctx *ctx) -{ - return !nghttp2_session_want_read(ctx->h2) && - !nghttp2_session_want_write(ctx->h2); -} - -static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - size_t nwritten; - CURLcode result; - - if(Curl_bufq_is_empty(&ctx->outbufq)) - return CURLE_OK; - - result = Curl_bufq_pass(&ctx->outbufq, proxy_h2_nw_out_writer, cf, - &nwritten); - if(result) { - if(result == CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "[0] flush nw send buffer(%zu) -> EAGAIN", - Curl_bufq_len(&ctx->outbufq)); - ctx->nw_out_blocked = 1; - } - return result; - } - CURL_TRC_CF(data, cf, "[0] nw send buffer flushed"); - return Curl_bufq_is_empty(&ctx->outbufq) ? CURLE_OK : CURLE_AGAIN; -} - -/* - * Processes pending input left in network input buffer. - * This function returns 0 if it succeeds, or -1 and error code will - * be assigned to *err. - */ -static CURLcode proxy_h2_process_pending_input(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - const unsigned char *buf; - size_t blen, nread; - ssize_t rv; - - while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) { - - rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen); - CURL_TRC_CF(data, cf, "[0] %zu bytes to nghttp2 -> %zd", blen, rv); - if(!curlx_sztouz(rv, &nread)) { - failf(data, - "process_pending_input: nghttp2_session_mem_recv() returned " - "%zd:%s", rv, nghttp2_strerror((int)rv)); - return CURLE_RECV_ERROR; - } - else if(!nread) { - /* nghttp2 does not want to process more, but has no error. This - * probably cannot happen, but be safe. */ - break; - } - Curl_bufq_skip(&ctx->inbufq, nread); - if(Curl_bufq_is_empty(&ctx->inbufq)) { - CURL_TRC_CF(data, cf, "[0] all data in connection buffer processed"); - break; - } - else { - CURL_TRC_CF(data, cf, "[0] process_pending_input: %zu bytes left " - "in connection buffer", Curl_bufq_len(&ctx->inbufq)); - } - } - return CURLE_OK; -} - -static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - size_t nread; - - /* Process network input buffer first */ - if(!Curl_bufq_is_empty(&ctx->inbufq)) { - CURL_TRC_CF(data, cf, "[0] process %zu bytes in connection buffer", - Curl_bufq_len(&ctx->inbufq)); - result = proxy_h2_process_pending_input(cf, data); - if(result) - return result; - } - - /* Receive data from the "lower" filters, e.g. network until - * it is time to stop or we have enough data for this stream */ - while(!ctx->conn_closed && /* not closed the connection */ - !ctx->tunnel.closed && /* nor the tunnel */ - Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */ - !Curl_bufq_is_full(&ctx->tunnel.recvbuf)) { - - result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); - CURL_TRC_CF(data, cf, "[0] read %zu bytes nw data -> %d, %zu", - Curl_bufq_len(&ctx->inbufq), result, nread); - if(result) { - if(result != CURLE_AGAIN) { - failf(data, "Failed receiving HTTP2 proxy data"); - return result; - } - break; - } - else if(nread == 0) { - ctx->conn_closed = TRUE; - break; - } - - result = proxy_h2_process_pending_input(cf, data); - if(result) - return result; - } - - return CURLE_OK; -} - -static CURLcode proxy_h2_progress_egress(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - int rv = 0; - - ctx->nw_out_blocked = 0; - while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2)) - rv = nghttp2_session_send(ctx->h2); - - if(nghttp2_is_fatal(rv)) { - CURL_TRC_CF(data, cf, "[0] nghttp2_session_send error (%s)%d", - nghttp2_strerror(rv), rv); - return CURLE_SEND_ERROR; - } - return proxy_h2_nw_out_flush(cf, data); -} - -static ssize_t on_session_send(nghttp2_session *h2, - const uint8_t *buf, size_t blen, int flags, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nwritten; - CURLcode result = CURLE_OK; - - (void)h2; - (void)flags; - DEBUGASSERT(data); - - result = Curl_bufq_write_pass(&ctx->outbufq, buf, blen, - proxy_h2_nw_out_writer, cf, &nwritten); - if(result) { - if(result == CURLE_AGAIN) { - ctx->nw_out_blocked = 1; - return NGHTTP2_ERR_WOULDBLOCK; - } - failf(data, "Failed sending HTTP2 data"); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - if(!nwritten) - return NGHTTP2_ERR_WOULDBLOCK; - - return (nwritten > SSIZE_MAX) ? - NGHTTP2_ERR_CALLBACK_FAILURE : (ssize_t)nwritten; -} - -#ifdef CURLVERBOSE -static int proxy_h2_on_frame_send(nghttp2_session *session, - const nghttp2_frame *frame, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - - (void)session; - DEBUGASSERT(data); - if(Curl_trc_cf_is_verbose(cf, data)) { - char buffer[256]; - int len; - len = Curl_nghttp2_fr_print(frame, buffer, sizeof(buffer) - 1); - buffer[len] = 0; - CURL_TRC_CF(data, cf, "[%d] -> %s", frame->hd.stream_id, buffer); - } - return 0; -} -#endif /* CURLVERBOSE */ - -static int proxy_h2_on_frame_recv(nghttp2_session *session, - const nghttp2_frame *frame, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - int32_t stream_id = frame->hd.stream_id; - - (void)session; - DEBUGASSERT(data); -#ifdef CURLVERBOSE - if(Curl_trc_cf_is_verbose(cf, data)) { - char buffer[256]; - int len; - len = Curl_nghttp2_fr_print(frame, buffer, sizeof(buffer) - 1); - buffer[len] = 0; - CURL_TRC_CF(data, cf, "[%d] <- %s", frame->hd.stream_id, buffer); - } -#endif /* CURLVERBOSE */ - - if(!stream_id) { - /* stream ID zero is for connection-oriented stuff */ - DEBUGASSERT(data); - switch(frame->hd.type) { - case NGHTTP2_SETTINGS: - /* Since the initial stream window is 64K, a request might be on HOLD, - * due to exhaustion. The (initial) SETTINGS may announce a much larger - * window and *assume* that we treat this like a WINDOW_UPDATE. Some - * servers send an explicit WINDOW_UPDATE, but not all seem to do that. - * To be safe, we UNHOLD a stream in order not to stall. */ - if(CURL_REQ_WANT_SEND(data)) { - drain_tunnel(cf, data, &ctx->tunnel); - } - break; - case NGHTTP2_GOAWAY: - ctx->rcvd_goaway = TRUE; - break; - default: - break; - } - return 0; - } - - if(stream_id != ctx->tunnel.stream_id) { - CURL_TRC_CF(data, cf, "[%d] rcvd FRAME not for tunnel", stream_id); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - switch(frame->hd.type) { - case NGHTTP2_HEADERS: - /* nghttp2 guarantees that :status is received, and we store it to - stream->status_code. Fuzzing has proven this can still be reached - without status code having been set. */ - if(!ctx->tunnel.resp) - return NGHTTP2_ERR_CALLBACK_FAILURE; - /* Only final status code signals the end of header */ - CURL_TRC_CF(data, cf, "[%d] got http status: %d", - stream_id, ctx->tunnel.resp->status); - if(!ctx->tunnel.has_final_response) { - if(ctx->tunnel.resp->status / 100 != 1) { - ctx->tunnel.has_final_response = TRUE; - } - } - break; - case NGHTTP2_WINDOW_UPDATE: - if(CURL_REQ_WANT_SEND(data)) { - drain_tunnel(cf, data, &ctx->tunnel); - } - break; - case NGHTTP2_RST_STREAM: - if(frame->rst_stream.error_code) - ctx->tunnel.reset = TRUE; - break; - default: - break; - } - return 0; -} - -static int proxy_h2_on_header(nghttp2_session *session, - const nghttp2_frame *frame, - const uint8_t *name, size_t namelen, - const uint8_t *value, size_t valuelen, - uint8_t flags, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - int32_t stream_id = frame->hd.stream_id; - CURLcode result; - - (void)flags; - (void)session; - DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ - if(stream_id != ctx->tunnel.stream_id) { - CURL_TRC_CF(data, cf, "[%d] header for non-tunnel stream: " - "%.*s: %.*s", stream_id, - (int)namelen, name, (int)valuelen, value); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - if(frame->hd.type == NGHTTP2_PUSH_PROMISE) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - if(ctx->tunnel.has_final_response) { - /* we do not do anything with trailers for tunnel streams */ - return 0; - } - - if(namelen == sizeof(HTTP_PSEUDO_STATUS) - 1 && - memcmp(HTTP_PSEUDO_STATUS, name, namelen) == 0) { - int http_status; - struct http_resp *resp; - - /* status: always comes first, we might get more than one response, - * link the previous ones for keepers */ - result = Curl_http_decode_status(&http_status, - (const char *)value, valuelen); - if(result) - return NGHTTP2_ERR_CALLBACK_FAILURE; - result = Curl_http_resp_make(&resp, http_status, NULL); - if(result) - return NGHTTP2_ERR_CALLBACK_FAILURE; - resp->prev = ctx->tunnel.resp; - ctx->tunnel.resp = resp; - CURL_TRC_CF(data, cf, "[%d] status: HTTP/2 %03d", - stream_id, ctx->tunnel.resp->status); - return 0; - } - - if(!ctx->tunnel.resp) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - result = Curl_dynhds_add(&ctx->tunnel.resp->headers, - (const char *)name, namelen, - (const char *)value, valuelen); - if(result) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - CURL_TRC_CF(data, cf, "[%d] header: %.*s: %.*s", - stream_id, (int)namelen, name, (int)valuelen, value); - - return 0; /* 0 is successful */ -} - -static ssize_t tunnel_send_callback(nghttp2_session *session, - int32_t stream_id, - uint8_t *buf, size_t length, - uint32_t *data_flags, - nghttp2_data_source *source, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - struct tunnel_stream *ts; - CURLcode result; - size_t nread; - - (void)source; - (void)ctx; - - if(!stream_id) - return NGHTTP2_ERR_INVALID_ARGUMENT; - - ts = nghttp2_session_get_stream_user_data(session, stream_id); - if(!ts) - return NGHTTP2_ERR_CALLBACK_FAILURE; - DEBUGASSERT(ts == &ctx->tunnel); - - result = Curl_bufq_read(&ts->sendbuf, buf, length, &nread); - if(result) { - if(result != CURLE_AGAIN) - return NGHTTP2_ERR_CALLBACK_FAILURE; - return NGHTTP2_ERR_DEFERRED; - } - if(ts->closed && Curl_bufq_is_empty(&ts->sendbuf)) - *data_flags = NGHTTP2_DATA_FLAG_EOF; - - CURL_TRC_CF(data, cf, "[%d] tunnel_send_callback -> %zu", - ts->stream_id, nread); - return (nread > SSIZE_MAX) ? - NGHTTP2_ERR_CALLBACK_FAILURE : (ssize_t)nread; -} - -static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const uint8_t *mem, size_t len, void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_proxy_ctx *ctx = cf->ctx; - size_t nwritten; - CURLcode result; - - (void)flags; - (void)session; - DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ - - if(stream_id != ctx->tunnel.stream_id) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - result = Curl_bufq_write(&ctx->tunnel.recvbuf, mem, len, &nwritten); - if(result) { - if(result != CURLE_AGAIN) - return NGHTTP2_ERR_CALLBACK_FAILURE; -#ifdef DEBUGBUILD - nwritten = 0; -#endif - } - /* tunnel.recbuf has soft limit, any success MUST add all data */ - DEBUGASSERT(nwritten == len); - return 0; -} - -static int proxy_h2_on_stream_close(nghttp2_session *session, - int32_t stream_id, - uint32_t error_code, void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - - (void)session; - - if(stream_id != ctx->tunnel.stream_id) - return 0; - - CURL_TRC_CF(data, cf, "[%d] proxy_h2_on_stream_close, %s (err %u)", - stream_id, nghttp2_http2_strerror(error_code), error_code); - ctx->tunnel.closed = TRUE; - ctx->tunnel.error = error_code; - if(error_code) - ctx->tunnel.reset = TRUE; - - return 0; -} - -static CURLcode proxy_h2_submit( - int32_t *pstream_id, - struct Curl_cfilter *cf, - struct Curl_easy *data, - nghttp2_session *h2, - struct httpreq *req, - const nghttp2_priority_spec *pri_spec, - void *stream_user_data, - nghttp2_data_source_read_callback read_callback, - void *read_ctx) -{ - struct dynhds h2_headers; - nghttp2_nv *nva = NULL; - int32_t stream_id = -1; - size_t nheader; - CURLcode result; - - (void)cf; - Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); - result = Curl_http_req_to_h2(&h2_headers, req, data); - if(result) - goto out; - - nva = Curl_dynhds_to_nva(&h2_headers, &nheader); - if(!nva) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - if(read_callback) { - nghttp2_data_provider data_prd; - - data_prd.read_callback = read_callback; - data_prd.source.ptr = read_ctx; - stream_id = nghttp2_submit_request(h2, pri_spec, nva, nheader, - &data_prd, stream_user_data); - } - else { - stream_id = nghttp2_submit_request(h2, pri_spec, nva, nheader, - NULL, stream_user_data); - } - - if(stream_id < 0) { - failf(data, "nghttp2_session_upgrade2() failed: %s(%d)", - nghttp2_strerror(stream_id), stream_id); - result = CURLE_SEND_ERROR; - goto out; - } - result = CURLE_OK; - -out: - curlx_free(nva); - Curl_dynhds_free(&h2_headers); - *pstream_id = stream_id; - return result; -} - -static CURLcode submit_CONNECT(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct tunnel_stream *ts) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - CURLcode result; - struct httpreq *req = NULL; - - result = Curl_http_proxy_create_CONNECT(&req, cf, data, 2); - if(result) - goto out; - result = Curl_creader_set_null(data); - if(result) - goto out; - - infof(data, "Establish HTTP/2 proxy tunnel to %s", req->authority); - - result = proxy_h2_submit(&ts->stream_id, cf, data, ctx->h2, req, - NULL, ts, tunnel_send_callback, cf); - if(result) { - CURL_TRC_CF(data, cf, "[%d] send, nghttp2_submit_request error: %s", - ts->stream_id, nghttp2_strerror(ts->stream_id)); - } - -out: - if(req) - Curl_http_req_free(req); - if(result) - failf(data, "Failed sending CONNECT to proxy"); - return result; -} - -static CURLcode inspect_response(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct tunnel_stream *ts) -{ - CURLcode result = CURLE_OK; - struct dynhds_entry *auth_reply = NULL; - (void)cf; - - DEBUGASSERT(ts->resp); - if(ts->resp->status / 100 == 2) { - infof(data, "CONNECT tunnel established, response %d", ts->resp->status); - h2_tunnel_go_state(cf, ts, H2_TUNNEL_ESTABLISHED, data); - return CURLE_OK; - } - - if(ts->resp->status == 401) { - auth_reply = Curl_dynhds_cget(&ts->resp->headers, "WWW-Authenticate"); - } - else if(ts->resp->status == 407) { - auth_reply = Curl_dynhds_cget(&ts->resp->headers, "Proxy-Authenticate"); - } - - if(auth_reply) { - CURL_TRC_CF(data, cf, "[0] CONNECT: fwd auth header '%s'", - auth_reply->value); - result = Curl_http_input_auth(data, ts->resp->status == 407, - auth_reply->value); - if(result) - return result; - if(data->req.newurl) { - /* Indicator that we should try again */ - curlx_safefree(data->req.newurl); - h2_tunnel_go_state(cf, ts, H2_TUNNEL_INIT, data); - return CURLE_OK; - } - } - - /* Seems to have failed */ - return CURLE_COULDNT_CONNECT; -} - -static CURLcode H2_CONNECT(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct tunnel_stream *ts) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - DEBUGASSERT(ts); - DEBUGASSERT(ts->authority); - do { - switch(ts->state) { - case H2_TUNNEL_INIT: - /* Prepare the CONNECT request and make a first attempt to send. */ - CURL_TRC_CF(data, cf, "[0] CONNECT start for %s", ts->authority); - result = submit_CONNECT(cf, data, ts); - if(result) - goto out; - h2_tunnel_go_state(cf, ts, H2_TUNNEL_CONNECT, data); - FALLTHROUGH(); - - case H2_TUNNEL_CONNECT: - /* see that the request is completely sent */ - result = proxy_h2_progress_ingress(cf, data); - if(!result) - result = proxy_h2_progress_egress(cf, data); - if(result && result != CURLE_AGAIN) { - h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data); - break; - } - - if(ts->has_final_response) { - h2_tunnel_go_state(cf, ts, H2_TUNNEL_RESPONSE, data); - } - else { - result = CURLE_OK; - goto out; - } - FALLTHROUGH(); - - case H2_TUNNEL_RESPONSE: - DEBUGASSERT(ts->has_final_response); - result = inspect_response(cf, data, ts); - if(result) - goto out; - break; - - case H2_TUNNEL_ESTABLISHED: - return CURLE_OK; - - case H2_TUNNEL_FAILED: - return CURLE_RECV_ERROR; - - default: - break; - } - - } while(ts->state == H2_TUNNEL_INIT); - -out: - if((result && (result != CURLE_AGAIN)) || ctx->tunnel.closed) - h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data); - return result; -} - -/* - * Initialize the cfilter context - */ -static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OUT_OF_MEMORY; - nghttp2_session_callbacks *cbs = NULL; - int rc; - - DEBUGASSERT(!ctx->h2); - memset(&ctx->tunnel, 0, sizeof(ctx->tunnel)); - - Curl_bufq_init(&ctx->inbufq, PROXY_H2_CHUNK_SIZE, PROXY_H2_NW_RECV_CHUNKS); - Curl_bufq_init(&ctx->outbufq, PROXY_H2_CHUNK_SIZE, PROXY_H2_NW_SEND_CHUNKS); - - if(tunnel_stream_init(cf, &ctx->tunnel)) - goto out; - - rc = nghttp2_session_callbacks_new(&cbs); - if(rc) { - failf(data, "Could not initialize nghttp2 callbacks"); - goto out; - } - - nghttp2_session_callbacks_set_send_callback(cbs, on_session_send); - nghttp2_session_callbacks_set_on_frame_recv_callback( - cbs, proxy_h2_on_frame_recv); -#ifdef CURLVERBOSE - nghttp2_session_callbacks_set_on_frame_send_callback(cbs, - proxy_h2_on_frame_send); -#endif - nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - cbs, tunnel_recv_callback); - nghttp2_session_callbacks_set_on_stream_close_callback( - cbs, proxy_h2_on_stream_close); - nghttp2_session_callbacks_set_on_header_callback(cbs, proxy_h2_on_header); - - /* The nghttp2 session is not yet setup, do it */ - rc = proxy_h2_client_new(cf, cbs); - if(rc) { - failf(data, "Could not initialize nghttp2"); - goto out; - } - - { - nghttp2_settings_entry iv[3]; - - iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; - iv[0].value = Curl_multi_max_concurrent_streams(data->multi); - iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; - iv[1].value = H2_TUNNEL_WINDOW_SIZE; - iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; - iv[2].value = 0; - rc = nghttp2_submit_settings(ctx->h2, NGHTTP2_FLAG_NONE, iv, 3); - if(rc) { - failf(data, "nghttp2_submit_settings() failed: %s(%d)", - nghttp2_strerror(rc), rc); - result = CURLE_HTTP2; - goto out; - } - } - - rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0, - PROXY_HTTP2_HUGE_WINDOW_SIZE); - if(rc) { - failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)", - nghttp2_strerror(rc), rc); - result = CURLE_HTTP2; - goto out; - } - - /* all set, traffic will be send on connect */ - result = CURLE_OK; - -out: - if(cbs) - nghttp2_session_callbacks_del(cbs); - CURL_TRC_CF(data, cf, "[0] init proxy ctx -> %d", result); - return result; -} - -static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - struct cf_call_data save; - struct tunnel_stream *ts = &ctx->tunnel; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* Connect the lower filters first */ - if(!cf->next->connected) { - result = Curl_conn_cf_connect(cf->next, data, done); - if(result || !*done) - return result; - } - - *done = FALSE; - - CF_DATA_SAVE(save, cf, data); - if(!ctx->h2) { - result = cf_h2_proxy_ctx_init(cf, data); - if(result) - goto out; - } - DEBUGASSERT(ts->authority); - - if(Curl_timeleft_ms(data) < 0) { - failf(data, "Proxy CONNECT aborted due to timeout"); - result = CURLE_OPERATION_TIMEDOUT; - goto out; - } - - /* for the secondary socket (FTP), use the "connect to host" - * but ignore the "connect to port" (use the secondary port) - */ - result = H2_CONNECT(cf, data, ts); - -out: - *done = (result == CURLE_OK) && (ts->state == H2_TUNNEL_ESTABLISHED); - if(*done) { - cf->connected = TRUE; - /* The real request will follow the CONNECT, reset request partially */ - Curl_req_soft_reset(&data->req, data); - Curl_client_reset(data); - } - CF_DATA_RESTORE(cf, save); - return result; -} - -static void cf_h2_proxy_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - - if(ctx) { - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - cf_h2_proxy_ctx_clear(ctx); - CF_DATA_RESTORE(cf, save); - } - if(cf->next) - cf->next->cft->do_close(cf->next, data); -} - -static void cf_h2_proxy_destroy(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - - (void)data; - if(ctx) { - cf_h2_proxy_ctx_free(ctx); - cf->ctx = NULL; - } -} - -static CURLcode cf_h2_proxy_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct cf_call_data save; - CURLcode result; - int rv; - - if(!cf->connected || !ctx->h2 || cf->shutdown || ctx->conn_closed) { - *done = TRUE; - return CURLE_OK; - } - - CF_DATA_SAVE(save, cf, data); - - if(!ctx->sent_goaway) { - rv = nghttp2_submit_goaway(ctx->h2, NGHTTP2_FLAG_NONE, - 0, 0, - (const uint8_t *)"shutdown", - sizeof("shutdown")); - if(rv) { - failf(data, "nghttp2_submit_goaway() failed: %s(%d)", - nghttp2_strerror(rv), rv); - result = CURLE_SEND_ERROR; - goto out; - } - ctx->sent_goaway = TRUE; - } - /* GOAWAY submitted, process egress and ingress until nghttp2 is done. */ - result = CURLE_OK; - if(nghttp2_session_want_write(ctx->h2)) - result = proxy_h2_progress_egress(cf, data); - if(!result && nghttp2_session_want_read(ctx->h2)) - result = proxy_h2_progress_ingress(cf, data); - - *done = (ctx->conn_closed || - (!result && !nghttp2_session_want_write(ctx->h2) && - !nghttp2_session_want_read(ctx->h2))); -out: - CF_DATA_RESTORE(cf, save); - cf->shutdown = (result || *done); - return result; -} - -static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - if((ctx && !Curl_bufq_is_empty(&ctx->inbufq)) || - (ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED && - !Curl_bufq_is_empty(&ctx->tunnel.recvbuf))) - return TRUE; - return cf->next ? cf->next->cft->has_data_pending(cf->next, data) : FALSE; -} - -static CURLcode cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct cf_call_data save; - curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); - bool want_recv, want_send; - CURLcode result = CURLE_OK; - - if(!cf->connected && ctx->h2) { - want_send = nghttp2_session_want_write(ctx->h2) || - !Curl_bufq_is_empty(&ctx->outbufq) || - !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); - want_recv = nghttp2_session_want_read(ctx->h2); - } - else - Curl_pollset_check(data, ps, sock, &want_recv, &want_send); - - if(ctx->h2 && (want_recv || want_send)) { - bool c_exhaust, s_exhaust; - - CF_DATA_SAVE(save, cf, data); - c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2); - s_exhaust = ctx->tunnel.stream_id >= 0 && - !nghttp2_session_get_stream_remote_window_size( - ctx->h2, ctx->tunnel.stream_id); - want_recv = (want_recv || c_exhaust || s_exhaust); - want_send = (!s_exhaust && want_send) || - (!c_exhaust && nghttp2_session_want_write(ctx->h2)) || - !Curl_bufq_is_empty(&ctx->outbufq) || - !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); - - result = Curl_pollset_set(data, ps, sock, want_recv, want_send); - CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d -> %d", - want_recv, want_send, result); - CF_DATA_RESTORE(cf, save); - } - else if(ctx->sent_goaway && !cf->shutdown) { - /* shutdown in progress */ - CF_DATA_SAVE(save, cf, data); - want_send = nghttp2_session_want_write(ctx->h2) || - !Curl_bufq_is_empty(&ctx->outbufq) || - !Curl_bufq_is_empty(&ctx->tunnel.sendbuf); - want_recv = nghttp2_session_want_read(ctx->h2); - result = Curl_pollset_set(data, ps, sock, want_recv, want_send); - CURL_TRC_CF(data, cf, "adjust_pollset, want_recv=%d want_send=%d -> %d", - want_recv, want_send, result); - CF_DATA_RESTORE(cf, save); - } - return result; -} - -static CURLcode h2_handle_tunnel_close(struct Curl_cfilter *cf, - struct Curl_easy *data, - size_t *pnread) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - - *pnread = 0; - if(ctx->tunnel.error) { - failf(data, "HTTP/2 stream %d reset by %s (error 0x%x %s)", - ctx->tunnel.stream_id, ctx->tunnel.reset ? "server" : "curl", - ctx->tunnel.error, nghttp2_http2_strerror(ctx->tunnel.error)); - return CURLE_RECV_ERROR; - } - - CURL_TRC_CF(data, cf, "[%d] handle_tunnel_close -> 0", - ctx->tunnel.stream_id); - return CURLE_OK; -} - -static CURLcode tunnel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_AGAIN; - - *pnread = 0; - if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) - result = Curl_bufq_cread(&ctx->tunnel.recvbuf, buf, len, pnread); - else { - if(ctx->tunnel.closed) { - result = h2_handle_tunnel_close(cf, data, pnread); - } - else if(ctx->tunnel.reset || - (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) || - (ctx->rcvd_goaway && - ctx->last_stream_id < ctx->tunnel.stream_id)) { - result = CURLE_RECV_ERROR; - } - else - result = CURLE_AGAIN; - } - - CURL_TRC_CF(data, cf, "[%d] tunnel_recv(len=%zu) -> %d, %zu", - ctx->tunnel.stream_id, len, result, *pnread); - return result; -} - -static CURLcode cf_h2_proxy_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, size_t len, - size_t *pnread) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct cf_call_data save; - CURLcode result; - - *pnread = 0; - CF_DATA_SAVE(save, cf, data); - - if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { - result = CURLE_RECV_ERROR; - goto out; - } - - if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) { - result = proxy_h2_progress_ingress(cf, data); - if(result) - goto out; - } - - result = tunnel_recv(cf, data, buf, len, pnread); - - if(!result) { - CURL_TRC_CF(data, cf, "[%d] increase window by %zu", - ctx->tunnel.stream_id, *pnread); - nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, *pnread); - } - - result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data)); - -out: - if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) && - (!result || (result == CURLE_AGAIN))) { - /* data pending and no fatal error to report. Need to trigger - * draining to avoid stalling when no socket events happen. */ - drain_tunnel(cf, data, &ctx->tunnel); - } - CURL_TRC_CF(data, cf, "[%d] cf_recv(len=%zu) -> %d, %zu", - ctx->tunnel.stream_id, len, result, *pnread); - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode cf_h2_proxy_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct cf_call_data save; - int rv; - CURLcode result; - - (void)eos; - *pnwritten = 0; - CF_DATA_SAVE(save, cf, data); - - if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { - result = CURLE_SEND_ERROR; - goto out; - } - - if(ctx->tunnel.closed) { - result = CURLE_SEND_ERROR; - goto out; - } - - result = Curl_bufq_write(&ctx->tunnel.sendbuf, buf, len, pnwritten); - CURL_TRC_CF(data, cf, "cf_send(), bufq_write %d, %zu", result, *pnwritten); - if(result && (result != CURLE_AGAIN)) - goto out; - - if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { - /* req body data is buffered, resume the potentially suspended stream */ - rv = nghttp2_session_resume_data(ctx->h2, ctx->tunnel.stream_id); - if(nghttp2_is_fatal(rv)) { - result = CURLE_SEND_ERROR; - goto out; - } - } - - result = Curl_1st_fatal(result, proxy_h2_progress_ingress(cf, data)); - result = Curl_1st_fatal(result, proxy_h2_progress_egress(cf, data)); - - if(!result && proxy_h2_should_close_session(ctx)) { - /* nghttp2 thinks this session is done. If the stream has not been - * closed, this is an error state for out transfer */ - if(ctx->tunnel.closed) { - result = CURLE_SEND_ERROR; - } - else { - CURL_TRC_CF(data, cf, "[0] send: nothing to do in this session"); - result = CURLE_HTTP2; - } - } - -out: - if(!Curl_bufq_is_empty(&ctx->tunnel.recvbuf) && - (!result || (result == CURLE_AGAIN))) { - /* data pending and no fatal error to report. Need to trigger - * draining to avoid stalling when no socket events happen. */ - drain_tunnel(cf, data, &ctx->tunnel); - } - CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %d, %zu, " - "h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)", - ctx->tunnel.stream_id, len, result, *pnwritten, - nghttp2_session_get_stream_remote_window_size( - ctx->h2, ctx->tunnel.stream_id), - nghttp2_session_get_remote_window_size(ctx->h2), - Curl_bufq_len(&ctx->tunnel.sendbuf), - Curl_bufq_len(&ctx->outbufq)); - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode cf_h2_proxy_flush(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - struct cf_call_data save; - CURLcode result = CURLE_OK; - - CF_DATA_SAVE(save, cf, data); - if(!Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { - /* resume the potentially suspended tunnel */ - int rv = nghttp2_session_resume_data(ctx->h2, ctx->tunnel.stream_id); - if(nghttp2_is_fatal(rv)) { - result = CURLE_SEND_ERROR; - goto out; - } - } - - result = proxy_h2_progress_egress(cf, data); - -out: - CURL_TRC_CF(data, cf, "[%d] flush -> %d, " - "h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)", - ctx->tunnel.stream_id, result, - nghttp2_session_get_stream_remote_window_size( - ctx->h2, ctx->tunnel.stream_id), - nghttp2_session_get_remote_window_size(ctx->h2), - Curl_bufq_len(&ctx->tunnel.sendbuf), - Curl_bufq_len(&ctx->outbufq)); - CF_DATA_RESTORE(cf, save); - return result; -} - -static bool proxy_h2_connisalive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - bool alive = TRUE; - - *input_pending = FALSE; - if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending)) - return FALSE; - - if(*input_pending) { - /* This happens before we have sent off a request and the connection is - not in use by any other transfer, there should not be any data here, - only "protocol frames" */ - CURLcode result; - size_t nread; - - *input_pending = FALSE; - result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); - if(!result) { - if(proxy_h2_process_pending_input(cf, data)) - /* immediate error, considered dead */ - alive = FALSE; - else { - alive = !proxy_h2_should_close_session(ctx); - } - } - else if(result != CURLE_AGAIN) { - /* the read failed so let's say this is dead anyway */ - alive = FALSE; - } - } - - return alive; -} - -static bool cf_h2_proxy_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - bool alive; - struct cf_call_data save; - - *input_pending = FALSE; - CF_DATA_SAVE(save, cf, data); - alive = (ctx && ctx->h2 && proxy_h2_connisalive(cf, data, input_pending)); - CURL_TRC_CF(data, cf, "[0] conn alive -> %d, input_pending=%d", - alive, *input_pending); - CF_DATA_RESTORE(cf, save); - return alive; -} - -static CURLcode cf_h2_proxy_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_h2_proxy_ctx *ctx = cf->ctx; - - switch(query) { - case CF_QUERY_HOST_PORT: - *pres1 = (int)cf->conn->http_proxy.port; - *((const char **)pres2) = cf->conn->http_proxy.host.name; - return CURLE_OK; - case CF_QUERY_NEED_FLUSH: { - if(!Curl_bufq_is_empty(&ctx->outbufq) || - !Curl_bufq_is_empty(&ctx->tunnel.sendbuf)) { - CURL_TRC_CF(data, cf, "needs flush"); - *pres1 = TRUE; - return CURLE_OK; - } - break; - } - case CF_QUERY_ALPN_NEGOTIATED: { - const char **palpn = pres2; - DEBUGASSERT(palpn); - *palpn = NULL; - return CURLE_OK; - } - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -static CURLcode cf_h2_proxy_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - CURLcode result = CURLE_OK; - struct cf_call_data save; - - (void)arg1; - (void)arg2; - - switch(event) { - case CF_CTRL_FLUSH: - CF_DATA_SAVE(save, cf, data); - result = cf_h2_proxy_flush(cf, data); - CF_DATA_RESTORE(cf, save); - break; - default: - break; - } - return result; -} - -struct Curl_cftype Curl_cft_h2_proxy = { - "H2-PROXY", - CF_TYPE_IP_CONNECT | CF_TYPE_PROXY, - CURL_LOG_LVL_NONE, - cf_h2_proxy_destroy, - cf_h2_proxy_connect, - cf_h2_proxy_close, - cf_h2_proxy_shutdown, - cf_h2_proxy_adjust_pollset, - cf_h2_proxy_data_pending, - cf_h2_proxy_send, - cf_h2_proxy_recv, - cf_h2_proxy_cntrl, - cf_h2_proxy_is_alive, - Curl_cf_def_conn_keep_alive, - cf_h2_proxy_query, -}; - -CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf_h2_proxy = NULL; - struct cf_h2_proxy_ctx *ctx; - CURLcode result = CURLE_OUT_OF_MEMORY; - - (void)data; - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) - goto out; - - result = Curl_cf_create(&cf_h2_proxy, &Curl_cft_h2_proxy, ctx); - if(result) - goto out; - - Curl_conn_cf_insert_after(cf, cf_h2_proxy); - result = CURLE_OK; - -out: - if(result) - cf_h2_proxy_ctx_free(ctx); - return result; -} - -#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY && USE_NGHTTP2 */ diff --git a/vendor/curl/lib/cf-h2-proxy.h b/vendor/curl/lib/cf-h2-proxy.h deleted file mode 100644 index 318ce1973..000000000 --- a/vendor/curl/lib/cf-h2-proxy.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADER_CURL_H2_PROXY_H -#define HEADER_CURL_H2_PROXY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY) - -CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf, - struct Curl_easy *data); - -extern struct Curl_cftype Curl_cft_h2_proxy; - -#endif /* USE_NGHTTP2 && !CURL_DISABLE_PROXY */ - -#endif /* HEADER_CURL_H2_PROXY_H */ diff --git a/vendor/curl/lib/cf-haproxy.c b/vendor/curl/lib/cf-haproxy.c deleted file mode 100644 index 9ee5e790e..000000000 --- a/vendor/curl/lib/cf-haproxy.c +++ /dev/null @@ -1,258 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_PROXY - -#include "urldata.h" -#include "cfilters.h" -#include "cf-haproxy.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "select.h" - - -typedef enum { - HAPROXY_INIT, /* init/default/no tunnel state */ - HAPROXY_SEND, /* data_out being sent */ - HAPROXY_DONE /* all work done */ -} haproxy_state; - -struct cf_haproxy_ctx { - int state; - struct dynbuf data_out; -}; - -static void cf_haproxy_ctx_reset(struct cf_haproxy_ctx *ctx) -{ - DEBUGASSERT(ctx); - ctx->state = HAPROXY_INIT; - curlx_dyn_reset(&ctx->data_out); -} - -static void cf_haproxy_ctx_free(struct cf_haproxy_ctx *ctx) -{ - if(ctx) { - curlx_dyn_free(&ctx->data_out); - curlx_free(ctx); - } -} - -static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - /* We fake a client connection report to the upstream server - * with the HAProxy protocol, reporting the client's source - * and destination IP addresses and ports. - * addresses: either the ones used to talk to the upstream - * OR the value supplied by the user - * ports: the ports used in the upstream connection */ - const char *client_source_ip; - const char *client_dest_ip; - struct cf_haproxy_ctx *ctx = cf->ctx; - CURLcode result; - struct ip_quadruple ipquad; - bool is_ipv6; - - DEBUGASSERT(ctx); - DEBUGASSERT(ctx->state == HAPROXY_INIT); -#ifdef USE_UNIX_SOCKETS - if(cf->conn->unix_domain_socket) - /* the buffer is large enough to hold this! */ - result = curlx_dyn_addn(&ctx->data_out, STRCONST("PROXY UNKNOWN\r\n")); - else { -#endif /* USE_UNIX_SOCKETS */ - result = Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad); - if(result) - return result; - - if(data->set.str[STRING_HAPROXY_CLIENT_IP]) { - client_source_ip = data->set.str[STRING_HAPROXY_CLIENT_IP]; - client_dest_ip = client_source_ip; - is_ipv6 = !Curl_is_ipv4addr(client_source_ip); - } - else { - client_source_ip = ipquad.local_ip; - client_dest_ip = ipquad.remote_ip; - } - - result = curlx_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n", - is_ipv6 ? "TCP6" : "TCP4", - client_source_ip, client_dest_ip, - ipquad.local_port, ipquad.remote_port); - -#ifdef USE_UNIX_SOCKETS - } -#endif /* USE_UNIX_SOCKETS */ - return result; -} - -static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_haproxy_ctx *ctx = cf->ctx; - CURLcode result; - size_t len; - - DEBUGASSERT(ctx); - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - result = cf->next->cft->do_connect(cf->next, data, done); - if(result || !*done) - return result; - - switch(ctx->state) { - case HAPROXY_INIT: - result = cf_haproxy_date_out_set(cf, data); - if(result) - goto out; - ctx->state = HAPROXY_SEND; - FALLTHROUGH(); - case HAPROXY_SEND: - len = curlx_dyn_len(&ctx->data_out); - if(len > 0) { - size_t nwritten; - result = Curl_conn_cf_send(cf->next, data, - curlx_dyn_uptr(&ctx->data_out), len, FALSE, - &nwritten); - if(result) { - if(result != CURLE_AGAIN) - goto out; - result = CURLE_OK; - nwritten = 0; - } - curlx_dyn_tail(&ctx->data_out, len - nwritten); - if(curlx_dyn_len(&ctx->data_out) > 0) { - result = CURLE_OK; - goto out; - } - } - ctx->state = HAPROXY_DONE; - FALLTHROUGH(); - default: - curlx_dyn_free(&ctx->data_out); - break; - } - -out: - *done = (!result) && (ctx->state == HAPROXY_DONE); - cf->connected = *done; - return result; -} - -static void cf_haproxy_destroy(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURL_TRC_CF(data, cf, "destroy"); - cf_haproxy_ctx_free(cf->ctx); -} - -static void cf_haproxy_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURL_TRC_CF(data, cf, "close"); - cf->connected = FALSE; - cf_haproxy_ctx_reset(cf->ctx); - if(cf->next) - cf->next->cft->do_close(cf->next, data); -} - -static CURLcode cf_haproxy_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - if(cf->next->connected && !cf->connected) { - /* If we are not connected, but the filter "below" is - * and not waiting on something, we are sending. */ - return Curl_pollset_set_out_only( - data, ps, Curl_conn_cf_get_socket(cf, data)); - } - return CURLE_OK; -} - -struct Curl_cftype Curl_cft_haproxy = { - "HAPROXY", - CF_TYPE_PROXY | CF_TYPE_SETUP, - 0, - cf_haproxy_destroy, - cf_haproxy_connect, - cf_haproxy_close, - Curl_cf_def_shutdown, - cf_haproxy_adjust_pollset, - Curl_cf_def_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - Curl_cf_def_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, -}; - -static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf = NULL; - struct cf_haproxy_ctx *ctx; - CURLcode result; - - (void)data; - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - ctx->state = HAPROXY_INIT; - curlx_dyn_init(&ctx->data_out, DYN_HAXPROXY); - - result = Curl_cf_create(&cf, &Curl_cft_haproxy, ctx); - if(result) - goto out; - ctx = NULL; - -out: - cf_haproxy_ctx_free(ctx); - *pcf = result ? NULL : cf; - return result; -} - -CURLcode Curl_cf_haproxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf; - CURLcode result; - - result = cf_haproxy_create(&cf, data); - if(result) - goto out; - Curl_conn_cf_insert_after(cf_at, cf); - -out: - return result; -} - -#endif /* !CURL_DISABLE_PROXY */ diff --git a/vendor/curl/lib/cf-haproxy.h b/vendor/curl/lib/cf-haproxy.h deleted file mode 100644 index 6d67597cd..000000000 --- a/vendor/curl/lib/cf-haproxy.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_CF_HAPROXY_H -#define HEADER_CURL_CF_HAPROXY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" - -#ifndef CURL_DISABLE_PROXY - -CURLcode Curl_cf_haproxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data); - -extern struct Curl_cftype Curl_cft_haproxy; - -#endif /* !CURL_DISABLE_PROXY */ - -#endif /* HEADER_CURL_CF_HAPROXY_H */ diff --git a/vendor/curl/lib/cf-https-connect.c b/vendor/curl/lib/cf-https-connect.c deleted file mode 100644 index d1d8f5107..000000000 --- a/vendor/curl/lib/cf-https-connect.c +++ /dev/null @@ -1,835 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -#include "urldata.h" -#include "curl_trc.h" -#include "cfilters.h" -#include "cf-dns.h" -#include "connect.h" -#include "hostip.h" -#include "httpsrr.h" -#include "multiif.h" -#include "cf-https-connect.h" -#include "http2.h" -#include "progress.h" -#include "select.h" -#include "vquic/vquic.h" - -typedef enum { - CF_HC_RESOLV, - CF_HC_INIT, - CF_HC_CONNECT, - CF_HC_SUCCESS, - CF_HC_FAILURE -} cf_hc_state; - -struct cf_hc_baller { - const char *name; - struct Curl_cfilter *cf; - CURLcode result; - struct curltime started; - int reply_ms; - uint8_t transport; - enum alpnid alpn_id; - BIT(shutdown); -}; - -static void cf_hc_baller_discard(struct cf_hc_baller *b, - struct Curl_easy *data) -{ - if(b->cf) { - Curl_conn_cf_close(b->cf, data); - Curl_conn_cf_discard_chain(&b->cf, data); - b->cf = NULL; - } -} - -static bool cf_hc_baller_is_connecting(struct cf_hc_baller *b) -{ - return b->cf && !b->result; -} - -static bool cf_hc_baller_has_started(struct cf_hc_baller *b) -{ - return !!b->cf; -} - -static int cf_hc_baller_reply_ms(struct cf_hc_baller *b, - struct Curl_easy *data) -{ - if(b->cf && (b->reply_ms < 0)) - b->cf->cft->query(b->cf, data, CF_QUERY_CONNECT_REPLY_MS, - &b->reply_ms, NULL); - return b->reply_ms; -} - -static bool cf_hc_baller_data_pending(struct cf_hc_baller *b, - const struct Curl_easy *data) -{ - return b->cf && !b->result && b->cf->cft->has_data_pending(b->cf, data); -} - -static bool cf_hc_baller_needs_flush(struct cf_hc_baller *b, - struct Curl_easy *data) -{ - return b->cf && !b->result && Curl_conn_cf_needs_flush(b->cf, data); -} - -static CURLcode cf_hc_baller_cntrl(struct cf_hc_baller *b, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - if(b->cf && !b->result) - return Curl_conn_cf_cntrl(b->cf, data, FALSE, event, arg1, arg2); - return CURLE_OK; -} - -struct cf_hc_ctx { - cf_hc_state state; - struct curltime started; /* when connect started */ - CURLcode result; /* overall result */ - CURLcode check_h3_result; - struct cf_hc_baller ballers[2]; - size_t baller_count; - timediff_t soft_eyeballs_timeout_ms; - timediff_t hard_eyeballs_timeout_ms; - uint8_t def_transport; - BIT(httpsrr_resolved); - BIT(checked_h3); - BIT(ballers_complete); -}; - -static void cf_hc_ctx_close(struct Curl_easy *data, - struct cf_hc_ctx *ctx) -{ - if(ctx) { - size_t i; - for(i = 0; i < ctx->baller_count; ++i) - cf_hc_baller_discard(&ctx->ballers[i], data); - } -} - -static void cf_hc_ctx_destroy(struct Curl_easy *data, - struct cf_hc_ctx *ctx) -{ - if(ctx) { - cf_hc_ctx_close(data, ctx); - curlx_free(ctx); - } -} - -static void cf_hc_baller_assign(struct cf_hc_baller *b, - enum alpnid alpn_id, - uint8_t def_transport) -{ - b->alpn_id = alpn_id; - b->transport = def_transport; - b->cf = NULL; - b->result = CURLE_OK; - b->reply_ms = -1; - b->shutdown = FALSE; - switch(b->alpn_id) { - case ALPN_h3: - b->name = "h3"; - b->transport = TRNSPRT_QUIC; - break; - case ALPN_h2: - b->name = "h2"; - break; - case ALPN_h1: - b->name = "h1"; - break; - case ALPN_none: - b->name = "no-alpn"; - break; - default: - b->result = CURLE_FAILED_INIT; - break; - } -} - -static void cf_hc_baller_init(struct cf_hc_baller *b, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct Curl_cfilter *save = cf->next; - - cf->next = NULL; - b->started = *Curl_pgrs_now(data); - b->result = Curl_cf_setup_insert_after(cf, data, b->transport, - CURL_CF_SSL_ENABLE); - b->cf = cf->next; - cf->next = save; -} - -static CURLcode cf_hc_baller_connect(struct cf_hc_baller *b, - struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct Curl_cfilter *save = cf->next; - - cf->next = b->cf; - b->result = Curl_conn_cf_connect(cf->next, data, done); - b->cf = cf->next; /* it might mutate */ - cf->next = save; - return b->result; -} - -static CURLcode baller_connected(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_hc_baller *winner) -{ - struct cf_hc_ctx *ctx = cf->ctx; - - /* Make the winner's connection filter out own sub-filter, check, move, - * close all remaining. */ - if(cf->next) { - DEBUGASSERT(0); - return CURLE_FAILED_INIT; - } - if(!winner->cf) { - DEBUGASSERT(0); - return CURLE_FAILED_INIT; - } - - cf->next = winner->cf; - winner->cf = NULL; - ctx->state = CF_HC_SUCCESS; - cf->connected = TRUE; - - cf_hc_ctx_close(data, ctx); - /* ballers may have failf()'d, the winner resets it, so our - * errorbuf is clean again. */ - Curl_reset_fail(data); - -#ifdef USE_NGHTTP2 - { - /* For a negotiated HTTP/2 connection insert the h2 filter. */ - const char *alpn = Curl_conn_cf_get_alpn_negotiated(cf->next, data); - if(alpn && !strcmp("h2", alpn)) { - CURLcode result = Curl_http2_switch_at(cf, data); - if(result) { - ctx->state = CF_HC_FAILURE; - ctx->result = result; - return result; - } - } - } -#endif - return CURLE_OK; -} - -static bool time_to_start_baller2(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_hc_ctx *ctx = cf->ctx; - timediff_t elapsed_ms; - - if(ctx->baller_count < 2) - return FALSE; - else if(cf_hc_baller_has_started(&ctx->ballers[1])) - return FALSE; - else if(ctx->ballers[0].result) { - CURL_TRC_CF(data, cf, "%s baller failed, starting %s", - ctx->ballers[0].name, ctx->ballers[1].name); - return TRUE; - } - - elapsed_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &ctx->started); - if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) { - CURL_TRC_CF(data, cf, "%s inconclusive after %" FMT_TIMEDIFF_T ", " - "starting %s", ctx->ballers[0].name, - ctx->hard_eyeballs_timeout_ms, ctx->ballers[1].name); - return TRUE; - } - else if(elapsed_ms >= ctx->soft_eyeballs_timeout_ms) { - if(cf_hc_baller_reply_ms(&ctx->ballers[0], data) < 0) { - CURL_TRC_CF(data, cf, "%s has not seen any data after %" - FMT_TIMEDIFF_T "ms, starting %s", - ctx->ballers[0].name, ctx->soft_eyeballs_timeout_ms, - ctx->ballers[1].name); - return TRUE; - } - } - return FALSE; -} - -static bool cf_hc_may_h3(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_hc_ctx *ctx = cf->ctx; - if(!ctx->checked_h3) { - ctx->check_h3_result = - Curl_conn_may_http3(data, cf->conn, ctx->def_transport); - ctx->checked_h3 = TRUE; - } - return !ctx->check_h3_result; -} - -static enum alpnid cf_hc_get_httpsrr_alpn(struct Curl_cfilter *cf, - struct Curl_easy *data, - enum alpnid not_this_one) -{ -#ifdef USE_HTTPSRR - /* Is there an HTTPSRR use its ALPNs here. - * We are here after having selected a connection to a host+port and - * can no longer change that. Any HTTPSRR advice for other hosts and ports - * we need to ignore. */ - const struct Curl_https_rrinfo *rr; - size_t i; - - /* Do we have HTTPS-RR information? */ - rr = Curl_conn_dns_get_https(data, cf->sockindex); - - /* We do not support `rr->no_def_alpn`. */ - if(Curl_httpsrr_applicable(data, rr) && !rr->no_def_alpn) { - for(i = 0; i < CURL_ARRAYSIZE(rr->alpns); ++i) { - enum alpnid alpn_rr = (enum alpnid)rr->alpns[i]; - if(alpn_rr == not_this_one) /* don't want this one */ - continue; - switch(alpn_rr) { - case ALPN_h3: - if((data->state.http_neg.allowed & CURL_HTTP_V3x) && - cf_hc_may_h3(cf, data)) { - return alpn_rr; - } - break; - case ALPN_h2: - if(data->state.http_neg.allowed & CURL_HTTP_V2x) { - return alpn_rr; - } - break; - case ALPN_h1: - if(data->state.http_neg.allowed & CURL_HTTP_V1x) { - return alpn_rr; - } - break; - default: /* ignore */ - break; - } - } - } -#else - (void)cf; - (void)data; - (void)not_this_one; -#endif - return ALPN_none; -} - -static enum alpnid cf_hc_get_pref_alpn(struct Curl_cfilter *cf, - struct Curl_easy *data, - enum alpnid not_this_one) -{ - if((data->state.http_neg.preferred & data->state.http_neg.allowed)) { - switch(data->state.http_neg.preferred) { - case CURL_HTTP_V3x: - if(cf_hc_may_h3(cf, data) && (ALPN_h3 != not_this_one)) - return ALPN_h3; - break; - case CURL_HTTP_V2x: - if(ALPN_h2 != not_this_one) - return ALPN_h2; - break; - case CURL_HTTP_V1x: - /* If we are trying h2 already, h1 is already used as fallback */ - if((ALPN_h1 != not_this_one) && (ALPN_h2 != not_this_one)) - return ALPN_h1; - break; - default: - break; - } - } - return ALPN_none; -} - -static enum alpnid cf_hc_get_first_alpn(struct Curl_cfilter *cf, - struct Curl_easy *data, - http_majors choices, - enum alpnid not_this_one) -{ - /* When told to not try h2, we also do not try h1 and vice versa */ - bool allow_h1_or_h2 = (not_this_one != ALPN_h1) && - (not_this_one != ALPN_h2); - if((ALPN_h3 != not_this_one) && (choices & CURL_HTTP_V3x) && - cf_hc_may_h3(cf, data)) { - return ALPN_h3; - } - if(allow_h1_or_h2 && (choices & CURL_HTTP_V2x)) { - return ALPN_h2; - } - if(allow_h1_or_h2 && (choices & CURL_HTTP_V1x)) { - return ALPN_h1; - } - return ALPN_none; -} - -static CURLcode cf_hc_set_baller1(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_hc_ctx *ctx = cf->ctx; - enum alpnid alpn1 = ALPN_none; - VERBOSE(const char *source = "HTTPS-RR"); - - DEBUGASSERT(cf->conn->bits.tls_enable_alpn); - - alpn1 = cf_hc_get_httpsrr_alpn(cf, data, ALPN_none); - if(alpn1 == ALPN_none) { - /* preference is configured and allowed, can we use it? */ - VERBOSE(source = "preferred version"); - alpn1 = cf_hc_get_pref_alpn(cf, data, ALPN_none); - } - if(alpn1 == ALPN_none) { - VERBOSE(source = "wanted versions"); - alpn1 = cf_hc_get_first_alpn(cf, data, - data->state.http_neg.wanted, - ALPN_none); - } - if(alpn1 == ALPN_none) { - VERBOSE(source = "allowed versions"); - alpn1 = cf_hc_get_first_alpn(cf, data, - data->state.http_neg.allowed, - ALPN_none); - } - - if(alpn1 == ALPN_none) { - /* None of the wanted/allowed HTTP versions could be chosen */ - if(ctx->check_h3_result) { - CURL_TRC_CF(data, cf, "unable to use HTTP/3"); - return ctx->check_h3_result; - } - CURL_TRC_CF(data, cf, "unable to select HTTP version"); - return CURLE_FAILED_INIT; - } - - cf_hc_baller_assign(&ctx->ballers[0], alpn1, ctx->def_transport); - ctx->baller_count = 1; - CURL_TRC_CF(data, cf, "1st attempt uses %s from %s", - ctx->ballers[0].name, source); - - switch(alpn1) { - case ALPN_h1: - /* We really want h1, switch off h2 to make it disappear in ALPN */ - data->state.http_neg.wanted &= (uint8_t)~CURL_HTTP_V2x; - break; - default: - break; - } - - return CURLE_OK; -} - -static void cf_hc_set_baller2(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_hc_ctx *ctx = cf->ctx; - enum alpnid alpn2 = ALPN_none, alpn1 = ctx->ballers[0].alpn_id; - VERBOSE(const char *source = "HTTPS-RR"); - - if(ctx->ballers_complete) - return; /* already done */ - if(!ctx->httpsrr_resolved) - return; /* HTTPS-RR pending */ - - alpn2 = cf_hc_get_httpsrr_alpn(cf, data, alpn1); - if(alpn2 == ALPN_none) { - /* preference is configured and allowed, can we use it? */ - VERBOSE(source = "preferred version"); - alpn2 = cf_hc_get_pref_alpn(cf, data, alpn1); - } - if(alpn2 == ALPN_none) { - VERBOSE(source = "wanted versions"); - alpn2 = cf_hc_get_first_alpn(cf, data, - data->state.http_neg.wanted, - alpn1); - } - - if(alpn2 != ALPN_none) { - cf_hc_baller_assign(&ctx->ballers[1], alpn2, ctx->def_transport); - ctx->baller_count = 2; - CURL_TRC_CF(data, cf, "2nd attempt uses %s from %s", - ctx->ballers[1].name, source); - } - ctx->ballers_complete = TRUE; -} - -static CURLcode cf_hc_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_hc_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - - if(!ctx->httpsrr_resolved) { - ctx->httpsrr_resolved = Curl_conn_dns_resolved_https(data, cf->sockindex); -#ifdef DEBUGBUILD - if(!ctx->httpsrr_resolved && getenv("CURL_DBG_AWAIT_HTTPSRR")) { - CURL_TRC_CF(data, cf, "awaiting HTTPS-RR"); - return CURLE_OK; - } -#endif - } - - switch(ctx->state) { - case CF_HC_RESOLV: - ctx->state = CF_HC_INIT; - FALLTHROUGH(); - - case CF_HC_INIT: - DEBUGASSERT(!cf->next); - CURL_TRC_CF(data, cf, "connect, init"); - result = cf_hc_set_baller1(cf, data); - if(result) { - ctx->result = result; - ctx->state = CF_HC_FAILURE; - goto out; - } - cf_hc_set_baller2(cf, data); - ctx->started = *Curl_pgrs_now(data); - cf_hc_baller_init(&ctx->ballers[0], cf, data); - if((ctx->baller_count > 1) || !ctx->ballers_complete) { - Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS); - } - ctx->state = CF_HC_CONNECT; - FALLTHROUGH(); - - case CF_HC_CONNECT: - if(!ctx->ballers_complete) - cf_hc_set_baller2(cf, data); - - if(cf_hc_baller_is_connecting(&ctx->ballers[0])) { - result = cf_hc_baller_connect(&ctx->ballers[0], cf, data, done); - if(!result && *done) { - result = baller_connected(cf, data, &ctx->ballers[0]); - goto out; - } - } - - if(time_to_start_baller2(cf, data)) { - cf_hc_baller_init(&ctx->ballers[1], cf, data); - } - - if(cf_hc_baller_is_connecting(&ctx->ballers[1])) { - result = cf_hc_baller_connect(&ctx->ballers[1], cf, data, done); - if(!result && *done) { - result = baller_connected(cf, data, &ctx->ballers[1]); - goto out; - } - } - - if(ctx->ballers[0].result && - (ctx->ballers[1].result || - (ctx->ballers_complete && (ctx->baller_count < 2)))) { - /* all have failed. we give up */ - CURL_TRC_CF(data, cf, "connect, all attempts failed"); - ctx->result = result = ctx->ballers[0].result; - ctx->state = CF_HC_FAILURE; - goto out; - } - result = CURLE_OK; - *done = FALSE; - break; - - case CF_HC_FAILURE: - result = ctx->result; - cf->connected = FALSE; - *done = FALSE; - break; - - case CF_HC_SUCCESS: - result = CURLE_OK; - cf->connected = TRUE; - *done = TRUE; - break; - } - -out: - CURL_TRC_CF(data, cf, "connect -> %d, done=%d", result, *done); - return result; -} - -static CURLcode cf_hc_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - struct cf_hc_ctx *ctx = cf->ctx; - size_t i; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* shutdown all ballers that have not done so already. If one fails, - * continue shutting down others until all are shutdown. */ - for(i = 0; i < ctx->baller_count; i++) { - struct cf_hc_baller *b = &ctx->ballers[i]; - bool bdone = FALSE; - if(!cf_hc_baller_is_connecting(b) || b->shutdown) - continue; - b->result = b->cf->cft->do_shutdown(b->cf, data, &bdone); - if(b->result || bdone) - b->shutdown = TRUE; /* treat a failed shutdown as done */ - } - - *done = TRUE; - for(i = 0; i < ctx->baller_count; i++) { - if(!ctx->ballers[i].shutdown) - *done = FALSE; - } - if(*done) { - for(i = 0; i < ctx->baller_count; i++) { - if(ctx->ballers[i].result) - result = ctx->ballers[i].result; - } - } - CURL_TRC_CF(data, cf, "shutdown -> %d, done=%d", result, *done); - return result; -} - -static CURLcode cf_hc_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - CURLcode result = CURLE_OK; - if(!cf->connected) { - struct cf_hc_ctx *ctx = cf->ctx; - size_t i; - - for(i = 0; (i < ctx->baller_count) && !result; i++) { - struct cf_hc_baller *b = &ctx->ballers[i]; - if(!cf_hc_baller_is_connecting(b)) - continue; - result = Curl_conn_cf_adjust_pollset(b->cf, data, ps); - } - CURL_TRC_CF(data, cf, "adjust_pollset -> %d, %u socks", result, ps->n); - } - return result; -} - -static bool cf_hc_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct cf_hc_ctx *ctx = cf->ctx; - size_t i; - - if(cf->connected) - return cf->next->cft->has_data_pending(cf->next, data); - - for(i = 0; i < ctx->baller_count; i++) - if(cf_hc_baller_data_pending(&ctx->ballers[i], data)) - return TRUE; - return FALSE; -} - -static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query) -{ - struct cf_hc_ctx *ctx = cf->ctx; - struct curltime t, tmax; - size_t i; - - memset(&tmax, 0, sizeof(tmax)); - for(i = 0; i < ctx->baller_count; i++) { - struct Curl_cfilter *cfb = ctx->ballers[i].cf; - memset(&t, 0, sizeof(t)); - if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) { - if((t.tv_sec || t.tv_usec) && curlx_ptimediff_us(&t, &tmax) > 0) - tmax = t; - } - } - return tmax; -} - -static CURLcode cf_hc_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_hc_ctx *ctx = cf->ctx; - size_t i; - - if(!cf->connected) { - switch(query) { - case CF_QUERY_TIMER_CONNECT: { - struct curltime *when = pres2; - *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT); - return CURLE_OK; - } - case CF_QUERY_TIMER_APPCONNECT: { - struct curltime *when = pres2; - *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT); - return CURLE_OK; - } - case CF_QUERY_NEED_FLUSH: { - for(i = 0; i < ctx->baller_count; i++) - if(cf_hc_baller_needs_flush(&ctx->ballers[i], data)) { - *pres1 = TRUE; - return CURLE_OK; - } - break; - } - default: - break; - } - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -static CURLcode cf_hc_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - struct cf_hc_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - size_t i; - - if(!cf->connected) { - for(i = 0; i < ctx->baller_count; i++) { - result = cf_hc_baller_cntrl(&ctx->ballers[i], data, event, arg1, arg2); - if(result && (result != CURLE_AGAIN)) - goto out; - } - result = CURLE_OK; - } -out: - return result; -} - -static void cf_hc_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - CURL_TRC_CF(data, cf, "close"); - cf_hc_ctx_close(data, cf->ctx); - cf->connected = FALSE; - - if(cf->next) { - cf->next->cft->do_close(cf->next, data); - Curl_conn_cf_discard_chain(&cf->next, data); - } -} - -static void cf_hc_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_hc_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "destroy"); - cf_hc_ctx_destroy(data, ctx); -} - -struct Curl_cftype Curl_cft_http_connect = { - "HTTPS-CONNECT", - CF_TYPE_SETUP | CF_TYPE_HTTPSRR, - CURL_LOG_LVL_NONE, - cf_hc_destroy, - cf_hc_connect, - cf_hc_close, - cf_hc_shutdown, - cf_hc_adjust_pollset, - cf_hc_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - cf_hc_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_hc_query, -}; - -static CURLcode cf_hc_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - uint8_t def_transport) -{ - struct Curl_cfilter *cf = NULL; - struct cf_hc_ctx *ctx; - CURLcode result = CURLE_OK; - - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - ctx->def_transport = def_transport; - ctx->hard_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout; - ctx->soft_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout / 2; - - result = Curl_cf_create(&cf, &Curl_cft_http_connect, ctx); - if(result) - goto out; - ctx = NULL; - -out: - *pcf = result ? NULL : cf; - cf_hc_ctx_destroy(data, ctx); - return result; -} - -static CURLcode cf_hc_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - uint8_t def_transport) -{ - struct Curl_cfilter *cf; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - result = cf_hc_create(&cf, data, def_transport); - if(result) - goto out; - Curl_conn_cf_add(data, conn, sockindex, cf); -out: - return result; -} - -CURLcode Curl_cf_https_setup(struct Curl_easy *data, - struct connectdata *conn, - int sockindex) -{ - CURLcode result = CURLE_OK; - - DEBUGASSERT(conn->scheme->protocol == CURLPROTO_HTTPS); - - if((conn->scheme->protocol != CURLPROTO_HTTPS) || - !conn->bits.tls_enable_alpn) - goto out; - - result = cf_hc_add(data, conn, sockindex, conn->transport_wanted); - -out: - return result; -} - -#endif /* !CURL_DISABLE_HTTP */ diff --git a/vendor/curl/lib/cf-https-connect.h b/vendor/curl/lib/cf-https-connect.h deleted file mode 100644 index 3160c0382..000000000 --- a/vendor/curl/lib/cf-https-connect.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef HEADER_CURL_CF_HTTP_H -#define HEADER_CURL_CF_HTTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -struct Curl_cfilter; -struct Curl_easy; -struct connectdata; -struct Curl_cftype; - -extern struct Curl_cftype Curl_cft_http_connect; - -CURLcode Curl_cf_https_setup(struct Curl_easy *data, - struct connectdata *conn, - int sockindex); - -#endif /* !CURL_DISABLE_HTTP */ -#endif /* HEADER_CURL_CF_HTTP_H */ diff --git a/vendor/curl/lib/cf-ip-happy.c b/vendor/curl/lib/cf-ip-happy.c deleted file mode 100644 index f67273e48..000000000 --- a/vendor/curl/lib/cf-ip-happy.c +++ /dev/null @@ -1,1027 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include /* may need it */ -#endif -#ifdef HAVE_LINUX_TCP_H -#include -#elif defined(HAVE_NETINET_TCP_H) -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "connect.h" -#include "cfilters.h" -#include "cf-dns.h" -#include "cf-ip-happy.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "multiif.h" -#include "progress.h" -#include "select.h" -#include "vquic/vquic.h" /* for quic cfilters */ - - -struct transport_provider { - uint8_t transport; - cf_ip_connect_create *cf_create; -}; - -static -#ifndef UNITTESTS -const -#endif -struct transport_provider transport_providers[] = { - { TRNSPRT_TCP, Curl_cf_tcp_create }, -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) - { TRNSPRT_QUIC, Curl_cf_quic_create }, -#endif -#ifndef CURL_DISABLE_TFTP - { TRNSPRT_UDP, Curl_cf_udp_create }, -#endif -#ifdef USE_UNIX_SOCKETS - { TRNSPRT_UNIX, Curl_cf_unix_create }, -#endif -}; - -static cf_ip_connect_create *get_cf_create(uint8_t transport) -{ - size_t i; - for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { - if(transport == transport_providers[i].transport) - return transport_providers[i].cf_create; - } - return NULL; -} - -#ifdef UNITTESTS -/* @unittest 2600 */ -UNITTEST void debug_set_transport_provider( - uint8_t transport, cf_ip_connect_create *cf_create); -UNITTEST void debug_set_transport_provider( - uint8_t transport, cf_ip_connect_create *cf_create) -{ - size_t i; - for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { - if(transport == transport_providers[i].transport) { - transport_providers[i].cf_create = cf_create; - return; - } - } -} -#endif /* UNITTESTS */ - -struct cf_ai_iter { - struct Curl_cfilter *cf; - int ai_family; - unsigned int n; -}; - -static void cf_ai_iter_init(struct cf_ai_iter *iter, - struct Curl_cfilter *cf, - int ai_family) -{ - iter->cf = cf; - iter->ai_family = ai_family; - iter->n = 0; -} - -static const struct Curl_addrinfo *cf_ai_iter_next(struct cf_ai_iter *iter, - struct Curl_easy *data) -{ - const struct Curl_addrinfo *addr; - - if(!iter->cf) - return NULL; - - addr = Curl_conn_dns_get_ai(data, iter->cf->sockindex, - iter->ai_family, iter->n); - if(addr) - iter->n++; - return addr; -} - -static bool cf_ai_iter_has_more(struct cf_ai_iter *iter, - struct Curl_easy *data) -{ - return (iter->cf && - !!Curl_conn_dns_get_ai(data, iter->cf->sockindex, - iter->ai_family, iter->n)); -} - -struct cf_ip_attempt { - struct cf_ip_attempt *next; - struct Curl_sockaddr_ex addr; - struct Curl_cfilter *cf; /* current sub-cfilter connecting */ - cf_ip_connect_create *cf_create; - struct curltime started; /* start of current attempt */ - CURLcode result; - int ai_family; - uint8_t transport; - int error; - BIT(connected); /* cf has connected */ - BIT(shutdown); /* cf has shutdown */ - BIT(inconclusive); /* connect was not a hard failure, we - * might talk to a restarting server */ -}; - -static void cf_ip_attempt_free(struct cf_ip_attempt *a, - struct Curl_easy *data) -{ - if(a) { - if(a->cf) - Curl_conn_cf_discard_chain(&a->cf, data); - curlx_free(a); - } -} - -static CURLcode cf_ip_attempt_new(struct cf_ip_attempt **pa, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct Curl_sockaddr_ex *addr, - int ai_family, - uint8_t transport, - cf_ip_connect_create *cf_create) -{ - struct Curl_cfilter *wcf; - struct cf_ip_attempt *a; - CURLcode result = CURLE_OK; - - *pa = NULL; - a = curlx_calloc(1, sizeof(*a)); - if(!a) - return CURLE_OUT_OF_MEMORY; - - a->addr = *addr; - a->ai_family = ai_family; - a->transport = transport; - a->result = CURLE_OK; - a->cf_create = cf_create; - *pa = a; - - result = a->cf_create(&a->cf, data, cf->conn, &a->addr, a->transport); - if(result) - goto out; - - /* the new filter might have sub-filters */ - for(wcf = a->cf; wcf; wcf = wcf->next) { - wcf->conn = cf->conn; - wcf->sockindex = cf->sockindex; - } - -out: - if(result) { - cf_ip_attempt_free(a, data); - *pa = NULL; - } - return result; -} - -static CURLcode cf_ip_attempt_connect(struct cf_ip_attempt *a, - struct Curl_easy *data, - bool *connected) -{ - *connected = (bool)a->connected; - if(!a->result && !*connected) { - /* evaluate again */ - a->result = Curl_conn_cf_connect(a->cf, data, connected); - - if(!a->result) { - if(*connected) { - a->connected = TRUE; - } - } - else { - if(a->result == CURLE_WEIRD_SERVER_REPLY) - a->inconclusive = TRUE; - if(a->cf) - Curl_conn_cf_discard_chain(&a->cf, data); - } - } - return a->result; -} - -struct cf_ip_ballers { - struct cf_ip_attempt *running; - struct cf_ip_attempt *winner; - struct cf_ai_iter addr_iter; -#ifdef USE_IPV6 - struct cf_ai_iter ipv6_iter; -#endif - cf_ip_connect_create *cf_create; /* for creating cf */ - struct curltime started; - struct curltime last_attempt_started; - timediff_t attempt_delay_ms; - int last_attempt_ai_family; - uint32_t max_concurrent; - uint8_t transport; -}; - -static CURLcode cf_ip_attempt_restart(struct cf_ip_attempt *a, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct Curl_cfilter *wcf; - CURLcode result; - - if(a->cf) - Curl_conn_cf_discard_chain(&a->cf, data); - - a->result = CURLE_OK; - a->connected = FALSE; - a->inconclusive = FALSE; - a->cf = NULL; - - result = a->cf_create(&a->cf, data, cf->conn, &a->addr, a->transport); - if(!result) { - bool dummy; - /* the new filter might have sub-filters */ - for(wcf = a->cf; wcf; wcf = wcf->next) { - wcf->conn = cf->conn; - wcf->sockindex = cf->sockindex; - } - a->result = cf_ip_attempt_connect(a, data, &dummy); - } - return result; -} - -static void cf_ip_ballers_clear(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_ip_ballers *bs) -{ - (void)cf; - while(bs->running) { - struct cf_ip_attempt *a = bs->running; - bs->running = a->next; - cf_ip_attempt_free(a, data); - } - cf_ip_attempt_free(bs->winner, data); - bs->winner = NULL; -} - -static CURLcode cf_ip_ballers_init(struct cf_ip_ballers *bs, - struct Curl_cfilter *cf, - cf_ip_connect_create *cf_create, - uint8_t transport, - timediff_t attempt_delay_ms, - uint32_t max_concurrent) -{ - memset(bs, 0, sizeof(*bs)); - bs->cf_create = cf_create; - bs->transport = transport; - bs->attempt_delay_ms = attempt_delay_ms; - bs->max_concurrent = max_concurrent; - bs->last_attempt_ai_family = AF_INET; /* so AF_INET6 is next */ - - if(transport == TRNSPRT_UNIX) { -#ifdef USE_UNIX_SOCKETS - cf_ai_iter_init(&bs->addr_iter, cf, AF_UNIX); -#else - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - else { /* TCP/UDP/QUIC */ -#ifdef USE_IPV6 - cf_ai_iter_init(&bs->ipv6_iter, cf, AF_INET6); -#endif - cf_ai_iter_init(&bs->addr_iter, cf, AF_INET); - } - return CURLE_OK; -} - -static void cf_ip_ballers_prune(struct cf_ip_ballers *bs, - struct Curl_cfilter *cf, - struct Curl_easy *data, - uint32_t max_concurrent) -{ - struct cf_ip_attempt *a = NULL, **panchor; - uint32_t ongoing = 0; - - for(a = bs->running; a; a = a->next) { - if(!a->result && !a->connected) - ++ongoing; - } - - panchor = &bs->running; - while(*panchor && (ongoing > max_concurrent)) { - a = *panchor; - if(!a->result && !a->connected) { - *panchor = a->next; - a->next = NULL; - cf_ip_attempt_free(a, data); - --ongoing; - CURL_TRC_CF(data, cf, "discarding oldest attempt to keep limit"); - } - else { - panchor = &a->next; - } - } -} - -static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs, - struct Curl_cfilter *cf, - struct Curl_easy *data, - bool dns_resolved, - bool *connected) -{ - CURLcode result = CURLE_OK; - struct cf_ip_attempt *a = NULL, **panchor; - bool do_more; - timediff_t next_expire_ms; - uint32_t inconclusive, ongoing; - VERBOSE(int i); - - if(bs->winner) - return CURLE_OK; - -evaluate: - ongoing = inconclusive = 0; - - /* check if a running baller connects now */ - VERBOSE(i = -1); - for(panchor = &bs->running; *panchor; panchor = &((*panchor)->next)) { - VERBOSE(++i); - a = *panchor; - a->result = cf_ip_attempt_connect(a, data, connected); - if(!a->result) { - if(*connected) { - /* connected, declare the winner, remove from running, - * clear remaining running list. */ - CURL_TRC_CF(data, cf, "connect attempt #%d successful", i); - bs->winner = a; - *panchor = a->next; - a->next = NULL; - while(bs->running) { - a = bs->running; - bs->running = a->next; - cf_ip_attempt_free(a, data); - } - return CURLE_OK; - } - /* still running */ - ++ongoing; - } - else if(a->inconclusive) /* failed, but inconclusive */ - ++inconclusive; - } - if(bs->running) - CURL_TRC_CF(data, cf, "checked connect attempts: " - "%u ongoing, %u inconclusive", ongoing, inconclusive); - - /* no attempt connected yet, start another one? */ - if(!ongoing) { - if(!bs->started.tv_sec && !bs->started.tv_usec) - bs->started = *Curl_pgrs_now(data); - do_more = TRUE; - } - else { - bool more_possible = cf_ai_iter_has_more(&bs->addr_iter, data); -#ifdef USE_IPV6 - if(!more_possible) - more_possible = cf_ai_iter_has_more(&bs->ipv6_iter, data); -#endif - do_more = more_possible && - (curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started) >= - bs->attempt_delay_ms); - if(do_more) - CURL_TRC_CF(data, cf, "happy eyeballs timeout expired, " - "start next attempt"); - } - - if(do_more) { - /* start the next attempt if there is another ip address to try. - * Alternate between address families when possible. */ - const struct Curl_addrinfo *ai = NULL; - int ai_family = 0; - CURL_TRC_CF(data, cf, "want to do more"); -#ifdef USE_IPV6 - if((bs->last_attempt_ai_family == AF_INET) || - !cf_ai_iter_has_more(&bs->addr_iter, data)) { - ai = cf_ai_iter_next(&bs->ipv6_iter, data); - ai_family = bs->ipv6_iter.ai_family; - CURL_TRC_CF(data, cf, "check for next AAAA address: %s", - ai ? "found" : "none"); - } -#endif - if(!ai) { - ai = cf_ai_iter_next(&bs->addr_iter, data); - ai_family = bs->addr_iter.ai_family; - CURL_TRC_CF(data, cf, "check for next A address: %s", - ai ? "found" : "none"); - } - /* We are (re-)starting attempts. We are not interested in - * keeping old failure information. The new attempt will either - * succeed or persist new failure. */ - Curl_reset_fail(data); - - if(ai) { /* try another address */ - struct Curl_sockaddr_ex addr; - - /* Discard oldest to make room for new attempt */ - if(bs->max_concurrent) - cf_ip_ballers_prune(bs, cf, data, bs->max_concurrent - 1); - - result = Curl_socket_addr_from_ai(&addr, ai, bs->transport); - if(result) - goto out; - - result = cf_ip_attempt_new(&a, cf, data, &addr, ai_family, - bs->transport, bs->cf_create); - CURL_TRC_CF(data, cf, "starting %s attempt for ipv%s -> %d", - bs->running ? "next" : "first", - (ai_family == AF_INET) ? "4" : "6", result); - if(result) - goto out; - DEBUGASSERT(a); - - /* append to running list */ - panchor = &bs->running; - while(*panchor) - panchor = &((*panchor)->next); - *panchor = a; - bs->last_attempt_started = *Curl_pgrs_now(data); - bs->last_attempt_ai_family = ai_family; - /* and run everything again */ - goto evaluate; - } - else if(inconclusive) { - /* tried all addresses, no success but some where inconclusive. - * Let's restart the inconclusive ones. */ - timediff_t since_ms = - curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started); - timediff_t delay_ms = bs->attempt_delay_ms - since_ms; - if(delay_ms <= 0) { - CURL_TRC_CF(data, cf, "all attempts inconclusive, restarting one"); - VERBOSE(i = -1); - for(a = bs->running; a; a = a->next) { - VERBOSE(++i); - if(!a->inconclusive) - continue; - result = cf_ip_attempt_restart(a, cf, data); - CURL_TRC_CF(data, cf, "restarted baller %d -> %d", i, result); - if(result) /* serious failure */ - goto out; - bs->last_attempt_started = *Curl_pgrs_now(data); - goto evaluate; - } - DEBUGASSERT(0); /* should not come here */ - } - else { - /* let's wait some more before restarting */ - infof(data, "connect attempts inconclusive, retrying " - "in %" FMT_TIMEDIFF_T "ms", delay_ms); - Curl_expire(data, delay_ms, EXPIRE_HAPPY_EYEBALLS); - } - /* attempt timeout for restart has not expired yet */ - goto out; - } - else if(!ongoing && dns_resolved) { - /* no more addresses, no inconclusive attempts */ - CURL_TRC_CF(data, cf, "no more attempts to try"); - result = CURLE_COULDNT_CONNECT; - VERBOSE(i = 0); - for(a = bs->running; a; a = a->next) { - CURL_TRC_CF(data, cf, "baller %d: result=%d", i, a->result); - if(a->result) - result = a->result; - } - } - } - -out: - if(!result) { - bool more_possible; - - /* when do we need to be called again? */ - next_expire_ms = Curl_timeleft_ms(data); - if(next_expire_ms < 0) { - failf(data, "Connection timeout after %" FMT_OFF_T " ms", - curlx_ptimediff_ms(Curl_pgrs_now(data), - &data->progress.t_startsingle)); - return CURLE_OPERATION_TIMEDOUT; - } - - more_possible = cf_ai_iter_has_more(&bs->addr_iter, data); -#ifdef USE_IPV6 - if(!more_possible) - more_possible = cf_ai_iter_has_more(&bs->ipv6_iter, data); -#endif - if(more_possible) { - timediff_t expire_ms, elapsed_ms; - elapsed_ms = - curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started); - expire_ms = CURLMAX(bs->attempt_delay_ms - elapsed_ms, 0); - next_expire_ms = CURLMIN(next_expire_ms, expire_ms); - if(next_expire_ms <= 0) { - CURL_TRC_CF(data, cf, "HAPPY_EYEBALLS timeout due, re-evaluate"); - goto evaluate; - } - CURL_TRC_CF(data, cf, "next HAPPY_EYEBALLS timeout in %" FMT_TIMEDIFF_T - "ms", next_expire_ms); - Curl_expire(data, next_expire_ms, EXPIRE_HAPPY_EYEBALLS); - } - } - return result; -} - -static CURLcode cf_ip_ballers_shutdown(struct cf_ip_ballers *bs, - struct Curl_easy *data, - bool *done) -{ - struct cf_ip_attempt *a; - - /* shutdown all ballers that have not done so already. If one fails, - * continue shutting down others until all are shutdown. */ - *done = TRUE; - for(a = bs->running; a; a = a->next) { - bool bdone = FALSE; - if(a->shutdown || !a->cf) - continue; - a->result = a->cf->cft->do_shutdown(a->cf, data, &bdone); - if(a->result || bdone) - a->shutdown = TRUE; /* treat a failed shutdown as done */ - else - *done = FALSE; - } - return CURLE_OK; -} - -static CURLcode cf_ip_ballers_pollset(struct cf_ip_ballers *bs, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_ip_attempt *a; - CURLcode result = CURLE_OK; - for(a = bs->running; a && !result; a = a->next) { - if(a->result) - continue; - result = Curl_conn_cf_adjust_pollset(a->cf, data, ps); - } - return result; -} - -static bool cf_ip_ballers_pending(struct cf_ip_ballers *bs, - const struct Curl_easy *data) -{ - struct cf_ip_attempt *a; - - for(a = bs->running; a; a = a->next) { - if(a->result) - continue; - if(a->cf && a->cf->cft->has_data_pending(a->cf, data)) - return TRUE; - } - return FALSE; -} - -static struct curltime cf_ip_ballers_max_time(struct cf_ip_ballers *bs, - struct Curl_easy *data, - int query) -{ - struct curltime t, tmax; - struct cf_ip_attempt *a; - - memset(&tmax, 0, sizeof(tmax)); - for(a = bs->running; a; a = a->next) { - memset(&t, 0, sizeof(t)); - if(a->cf && !a->cf->cft->query(a->cf, data, query, NULL, &t)) { - if((t.tv_sec || t.tv_usec) && curlx_ptimediff_us(&t, &tmax) > 0) - tmax = t; - } - } - return tmax; -} - -static int cf_ip_ballers_min_reply_ms(struct cf_ip_ballers *bs, - struct Curl_easy *data) -{ - int reply_ms = -1, breply_ms; - struct cf_ip_attempt *a; - - for(a = bs->running; a; a = a->next) { - if(a->cf && !a->cf->cft->query(a->cf, data, CF_QUERY_CONNECT_REPLY_MS, - &breply_ms, NULL)) { - if(breply_ms >= 0 && (reply_ms < 0 || breply_ms < reply_ms)) - reply_ms = breply_ms; - } - } - return reply_ms; -} - -typedef enum { - SCFST_INIT, - SCFST_WAITING, - SCFST_DONE -} cf_connect_state; - -struct cf_ip_happy_ctx { - uint8_t transport; - cf_ip_connect_create *cf_create; - cf_connect_state state; - struct cf_ip_ballers ballers; - struct curltime started; - BIT(dns_resolved); -}; - -static CURLcode is_connected(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *connected) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - struct connectdata *conn = cf->conn; - CURLcode result; - - result = cf_ip_ballers_run(&ctx->ballers, cf, data, - (bool)ctx->dns_resolved, connected); - - if(!result) - return CURLE_OK; - else { - const char *hostname, *proxy_name = NULL; - char viamsg[160]; -#ifndef CURL_DISABLE_PROXY - if(conn->bits.socksproxy) - proxy_name = conn->socks_proxy.host.name; - else if(conn->bits.httpproxy) - proxy_name = conn->http_proxy.host.name; -#endif - hostname = conn->bits.conn_to_host ? conn->conn_to_host.name : - conn->host.name; - -#ifdef USE_UNIX_SOCKETS - if(conn->unix_domain_socket) - curl_msnprintf(viamsg, sizeof(viamsg), "over %s", - conn->unix_domain_socket); - else -#endif - { - uint16_t port; - if(cf->sockindex == SECONDARYSOCKET) - port = conn->secondary_port; - else if(cf->conn->bits.conn_to_port) - port = conn->conn_to_port; - else - port = conn->remote_port; - curl_msnprintf(viamsg, sizeof(viamsg), "port %d", port); - } - - failf(data, "Failed to connect to %s %s %s%s%safter " - "%" FMT_TIMEDIFF_T " ms: %s", - hostname, viamsg, - proxy_name ? "via " : "", - proxy_name ? proxy_name : "", - proxy_name ? " " : "", - curlx_ptimediff_ms(Curl_pgrs_now(data), - &data->progress.t_startsingle), - curl_easy_strerror(result)); - -#ifdef SOCKETIMEDOUT - if(SOCKETIMEDOUT == data->state.os_errno) - result = CURLE_OPERATION_TIMEDOUT; -#endif - - return result; - } -} - -#define IP_HE_MAX_CONCURRENT_ATTEMPTS 6 - -static CURLcode cf_ip_happy_init(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - - if(Curl_timeleft_ms(data) < 0) { - /* a precaution, no need to continue if time already is up */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - CURL_TRC_CF(data, cf, "init ip ballers for transport %u", ctx->transport); - ctx->started = *Curl_pgrs_now(data); - return cf_ip_ballers_init(&ctx->ballers, cf, - ctx->cf_create, ctx->transport, - data->set.happy_eyeballs_timeout, - IP_HE_MAX_CONCURRENT_ATTEMPTS); -} - -static void cf_ip_happy_ctx_clear(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - - DEBUGASSERT(ctx); - DEBUGASSERT(data); - cf_ip_ballers_clear(cf, data, &ctx->ballers); -} - -static void cf_ip_happy_ctx_destroy(struct cf_ip_happy_ctx *ctx) -{ - if(ctx) - curlx_free(ctx); -} - -static CURLcode cf_ip_happy_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - result = cf_ip_ballers_shutdown(&ctx->ballers, data, done); - CURL_TRC_CF(data, cf, "shutdown -> %d, done=%d", result, *done); - return result; -} - -static CURLcode cf_ip_happy_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(!cf->connected) { - result = cf_ip_ballers_pollset(&ctx->ballers, data, ps); - CURL_TRC_CF(data, cf, "adjust_pollset -> %d, %u socks", result, ps->n); - } - return result; -} - -static CURLcode cf_ip_happy_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - /* -Werror=null-dereference finds false positives suddenly. */ - if(!data) - return CURLE_FAILED_INIT; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - DEBUGASSERT(ctx); - *done = FALSE; - - if(!ctx->dns_resolved) { - result = Curl_conn_dns_result(cf->conn, cf->sockindex); - if(!result) - ctx->dns_resolved = TRUE; - else if(result == CURLE_AGAIN) { - result = CURLE_OK; - } - else /* real error */ - goto out; - } - - switch(ctx->state) { - case SCFST_INIT: - DEBUGASSERT(CURL_SOCKET_BAD == Curl_conn_cf_get_socket(cf, data)); - DEBUGASSERT(!cf->connected); - result = cf_ip_happy_init(cf, data); - if(result) - goto out; - ctx->state = SCFST_WAITING; - FALLTHROUGH(); - case SCFST_WAITING: - result = is_connected(cf, data, done); - if(!result && *done) { - DEBUGASSERT(ctx->ballers.winner); - DEBUGASSERT(ctx->ballers.winner->cf); - DEBUGASSERT(ctx->ballers.winner->cf->connected); - /* we have a winner. Install and activate it. - * close/free all others. */ - ctx->state = SCFST_DONE; - cf->connected = TRUE; - cf->next = ctx->ballers.winner->cf; - ctx->ballers.winner->cf = NULL; - cf_ip_happy_ctx_clear(cf, data); - Curl_expire_done(data, EXPIRE_HAPPY_EYEBALLS); - /* whatever errors where reported by ballers, clear our errorbuf */ - Curl_reset_fail(data); - - if(cf->conn->scheme->protocol & PROTO_FAMILY_SSH) - Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */ -#ifdef CURLVERBOSE - if(Curl_trc_cf_is_verbose(cf, data)) { - struct ip_quadruple ipquad; - bool is_ipv6; - if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) { - const char *host; - Curl_conn_get_current_host(data, cf->sockindex, &host, NULL); - CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u", - host, ipquad.remote_ip, ipquad.remote_port); - } - } -#endif - data->info.numconnects++; /* to track the # of connections made */ - } - break; - case SCFST_DONE: - *done = TRUE; - break; - } -out: - return result; -} - -static void cf_ip_happy_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "close"); - cf_ip_happy_ctx_clear(cf, data); - cf->connected = FALSE; - ctx->state = SCFST_INIT; - - if(cf->next) { - cf->next->cft->do_close(cf->next, data); - Curl_conn_cf_discard_chain(&cf->next, data); - } -} - -static bool cf_ip_happy_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - - if(!cf->connected) { - return cf_ip_ballers_pending(&ctx->ballers, data); - } - return cf->next->cft->has_data_pending(cf->next, data); -} - -static CURLcode cf_ip_happy_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - - if(!cf->connected) { - switch(query) { - case CF_QUERY_CONNECT_REPLY_MS: { - *pres1 = cf_ip_ballers_min_reply_ms(&ctx->ballers, data); - CURL_TRC_CF(data, cf, "query connect reply: %dms", *pres1); - return CURLE_OK; - } - case CF_QUERY_TIMER_CONNECT: { - struct curltime *when = pres2; - *when = cf_ip_ballers_max_time(&ctx->ballers, data, - CF_QUERY_TIMER_CONNECT); - return CURLE_OK; - } - case CF_QUERY_TIMER_APPCONNECT: { - struct curltime *when = pres2; - *when = cf_ip_ballers_max_time(&ctx->ballers, data, - CF_QUERY_TIMER_APPCONNECT); - return CURLE_OK; - } - default: - break; - } - } - - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -static void cf_ip_happy_destroy(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ip_happy_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "destroy"); - if(ctx) { - cf_ip_happy_ctx_clear(cf, data); - cf_ip_happy_ctx_destroy(ctx); - } -} - -struct Curl_cftype Curl_cft_ip_happy = { - "HAPPY-EYEBALLS", - CF_TYPE_SETUP, - CURL_LOG_LVL_NONE, - cf_ip_happy_destroy, - cf_ip_happy_connect, - cf_ip_happy_close, - cf_ip_happy_shutdown, - cf_ip_happy_adjust_pollset, - cf_ip_happy_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - Curl_cf_def_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_ip_happy_query, -}; - -/** - * Create an IP happy eyeball connection filter that uses the, once resolved, - * address information to connect on ip families based on connection - * configuration. - * @param pcf output, the created cfilter - * @param data easy handle used in creation - * @param conn connection the filter is created for - * @param cf_create method to create the sub-filters performing the - * actual connects. - */ -static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - cf_ip_connect_create *cf_create, - uint8_t transport) -{ - struct cf_ip_happy_ctx *ctx = NULL; - CURLcode result; - - (void)data; - (void)conn; - *pcf = NULL; - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - ctx->transport = transport; - ctx->cf_create = cf_create; - - result = Curl_cf_create(pcf, &Curl_cft_ip_happy, ctx); - -out: - if(result) { - curlx_safefree(*pcf); - cf_ip_happy_ctx_destroy(ctx); - } - return result; -} - -CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - uint8_t transport) -{ - cf_ip_connect_create *cf_create; - struct Curl_cfilter *cf; - CURLcode result; - - /* Need to be first */ - DEBUGASSERT(cf_at); - cf_create = get_cf_create(transport); - if(!cf_create) { - CURL_TRC_CF(data, cf_at, "unsupported transport type %u", transport); - return CURLE_UNSUPPORTED_PROTOCOL; - } - result = cf_ip_happy_create(&cf, data, cf_at->conn, cf_create, transport); - if(result) - return result; - - Curl_conn_cf_insert_after(cf_at, cf); - return CURLE_OK; -} diff --git a/vendor/curl/lib/cf-ip-happy.h b/vendor/curl/lib/cf-ip-happy.h deleted file mode 100644 index 547ee4b4a..000000000 --- a/vendor/curl/lib/cf-ip-happy.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef HEADER_CURL_IP_HAPPY_H -#define HEADER_CURL_IP_HAPPY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct connectdata; -struct Curl_addrinfo; -struct Curl_cfilter; -struct Curl_easy; -struct Curl_sockaddr_ex; - -/** - * Create a cfilter for making an "ip" connection to the - * given address, using parameters from `conn`. The "ip" connection - * can be a TCP socket, a UDP socket or even a QUIC connection. - * - * It MUST use only the supplied `ai` for its connection attempt. - * - * Such a filter may be used in "happy eyeball" scenarios, and its - * `connect` implementation needs to support non-blocking. Once connected, - * it MAY be installed in the connection filter chain to serve transfers. - */ -typedef CURLcode cf_ip_connect_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport); - -CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - uint8_t transport); - -extern struct Curl_cftype Curl_cft_ip_happy; - -#endif /* HEADER_CURL_IP_HAPPY_H */ diff --git a/vendor/curl/lib/cf-socket.c b/vendor/curl/lib/cf-socket.c deleted file mode 100644 index b99bcdef5..000000000 --- a/vendor/curl/lib/cf-socket.c +++ /dev/null @@ -1,2244 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include /* may need it */ -#endif -#ifdef HAVE_LINUX_TCP_H -#include -#elif defined(HAVE_NETINET_TCP_H) -#include -#endif -#ifdef HAVE_NETINET_UDP_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef __VMS -#include -#include -#endif - -#ifdef __DragonFly__ -/* Required for __DragonFly_version */ -#include -#endif - -#include "urldata.h" -#include "curl_trc.h" -#include "if2ip.h" -#include "cfilters.h" -#include "cf-socket.h" -#include "connect.h" -#include "curl_addrinfo.h" -#include "select.h" -#include "multiif.h" -#include "curlx/inet_pton.h" -#include "progress.h" -#include "conncache.h" -#include "multihandle.h" -#include "rand.h" -#include "curlx/strdup.h" -#include "system_win32.h" -#include "curlx/nonblock.h" -#include "curlx/strcopy.h" -#include "curlx/version_win32.h" -#include "curlx/strerr.h" -#include "curlx/strparse.h" - - -static void tcpnodelay(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t sockfd) -{ -#if defined(TCP_NODELAY) && defined(CURL_TCP_NODELAY_SUPPORTED) - curl_socklen_t onoff = (curl_socklen_t)1; - int level = IPPROTO_TCP; - VERBOSE(char buffer[STRERROR_LEN]); - - if(setsockopt(sockfd, level, TCP_NODELAY, - (void *)&onoff, sizeof(onoff)) < 0) - CURL_TRC_CF(data, cf, "Could not set TCP_NODELAY: %s", - curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); -#else - (void)cf; - (void)data; - (void)sockfd; -#endif -} - -#if defined(USE_WINSOCK) || defined(TCP_KEEPIDLE) || \ - defined(TCP_KEEPALIVE) || defined(TCP_KEEPALIVE_THRESHOLD) || \ - defined(TCP_KEEPINTVL) || defined(TCP_KEEPALIVE_ABORT_THRESHOLD) -#if defined(USE_WINSOCK) || \ - (defined(__sun) && !defined(TCP_KEEPIDLE)) || \ - (defined(__DragonFly__) && __DragonFly_version < 500702) || \ - (defined(_WIN32) && !defined(TCP_KEEPIDLE)) -/* Solaris < 11.4, DragonFlyBSD < 500702 and Windows < 10.0.16299 - * use millisecond units. */ -#define KEEPALIVE_FACTOR(x) ((x) *= 1000) -#else -#define KEEPALIVE_FACTOR(x) -#endif -#endif - -static void tcpkeepalive(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t sockfd) -{ - int optval = data->set.tcp_keepalive ? 1 : 0; - - /* only set IDLE and INTVL if setting KEEPALIVE is successful */ - if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, - (void *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set SO_KEEPALIVE on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } - else { -#ifdef USE_WINSOCK - /* Windows 10, version 1709 (10.0.16299) and later versions can use - setsockopt() TCP_KEEP*. Older versions return with failure. */ - if(curlx_verify_windows_version(10, 0, 16299, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { - CURL_TRC_CF(data, cf, "Set TCP_KEEP* on fd=%" FMT_SOCKET_T, sockfd); - optval = curlx_sltosi(data->set.tcp_keepidle); -/* Offered by mingw-w64 v12+. MS SDK 6.0A+. */ -#ifndef TCP_KEEPALIVE -#define TCP_KEEPALIVE 3 -#endif -/* Offered by mingw-w64 v12+. MS SDK ~10+/~VS2017+. */ -#ifndef TCP_KEEPCNT -#define TCP_KEEPCNT 16 -#endif -#ifndef TCP_KEEPIDLE -#define TCP_KEEPIDLE TCP_KEEPALIVE -#endif -#ifndef TCP_KEEPINTVL -#define TCP_KEEPINTVL 17 -#endif - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, - (const char *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPIDLE on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } - optval = curlx_sltosi(data->set.tcp_keepintvl); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, - (const char *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPINTVL on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } - optval = curlx_sltosi(data->set.tcp_keepcnt); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, - (const char *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPCNT on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } - } - else { -/* Offered by mingw-w64 and MS SDK. Latter only when targeting Win7+. */ -#ifndef SIO_KEEPALIVE_VALS -#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR, 4) - struct tcp_keepalive { - u_long onoff; - u_long keepalivetime; - u_long keepaliveinterval; - }; -#endif - struct tcp_keepalive vals; - DWORD dummy; - vals.onoff = 1; - optval = curlx_sltosi(data->set.tcp_keepidle); - KEEPALIVE_FACTOR(optval); - vals.keepalivetime = (u_long)optval; - optval = curlx_sltosi(data->set.tcp_keepintvl); - KEEPALIVE_FACTOR(optval); - vals.keepaliveinterval = (u_long)optval; - if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID)&vals, sizeof(vals), - NULL, 0, &dummy, NULL, NULL) != 0) { - CURL_TRC_CF(data, cf, "Failed to set SIO_KEEPALIVE_VALS on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } - } -#else /* !USE_WINSOCK */ -#ifdef TCP_KEEPIDLE - optval = curlx_sltosi(data->set.tcp_keepidle); - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, - (void *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPIDLE on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } -#elif defined(TCP_KEEPALIVE) - /* macOS style */ - optval = curlx_sltosi(data->set.tcp_keepidle); - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, - (void *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPALIVE on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } -#elif defined(TCP_KEEPALIVE_THRESHOLD) - /* Solaris <11.4 style */ - optval = curlx_sltosi(data->set.tcp_keepidle); - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, - (void *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPALIVE_THRESHOLD on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } -#endif -#ifdef TCP_KEEPINTVL - optval = curlx_sltosi(data->set.tcp_keepintvl); - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, - (void *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPINTVL on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } -#elif defined(TCP_KEEPALIVE_ABORT_THRESHOLD) - /* Solaris <11.4 style */ - /* TCP_KEEPALIVE_ABORT_THRESHOLD should equal to - * TCP_KEEPCNT * TCP_KEEPINTVL on other platforms. - * The default value of TCP_KEEPCNT is 9 on Linux, - * 8 on *BSD/macOS, 5 or 10 on Windows. We use the - * default config for Solaris <11.4 because there is - * no default value for TCP_KEEPCNT on Solaris 11.4. - * - * Note that the consequent probes will not be sent - * at equal intervals on Solaris, but will be sent - * using the exponential backoff algorithm. */ - { - int keepcnt = curlx_sltosi(data->set.tcp_keepcnt); - int keepintvl = curlx_sltosi(data->set.tcp_keepintvl); - - if(keepcnt > 0 && keepintvl > (INT_MAX / keepcnt)) - optval = INT_MAX; - else - optval = keepcnt * keepintvl; - } - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, - (void *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPALIVE_ABORT_THRESHOLD" - " on fd %" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } -#endif -#ifdef TCP_KEEPCNT - optval = curlx_sltosi(data->set.tcp_keepcnt); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, - (void *)&optval, sizeof(optval)) < 0) { - CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPCNT on fd " - "%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO); - } -#endif -#endif /* USE_WINSOCK */ - } -} - -/** - * Assign the addrinfo `ai` to the Curl_sockaddr_ex `addr` with - * transport determining socktype and protocol. - */ -CURLcode Curl_socket_addr_from_ai(struct Curl_sockaddr_ex *addr, - const struct Curl_addrinfo *ai, - uint8_t transport) -{ - /* - * The Curl_sockaddr_ex structure is libcurl's external API - * curl_sockaddr structure with enough space available to directly hold - * any protocol-specific address structures. The variable declared here - * will be used to pass / receive data to/from the fopensocket callback - * if this has been set, before that, it is initialized from parameters. - */ - addr->family = ai->ai_family; - addr->socktype = Curl_socktype_for_transport(transport); - addr->protocol = Curl_protocol_for_transport(transport); - addr->addrlen = (unsigned int)ai->ai_addrlen; - - DEBUGASSERT(addr->addrlen <= sizeof(addr->curl_sa_addrbuf)); - if(addr->addrlen > sizeof(addr->curl_sa_addrbuf)) - return CURLE_TOO_LARGE; - - memcpy(&addr->curl_sa_addrbuf, ai->ai_addr, addr->addrlen); - return CURLE_OK; -} - -#ifdef USE_SO_NOSIGPIPE -int Curl_sock_nosigpipe(curl_socket_t sockfd) -{ - int onoff = 1; - return setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, - (void *)&onoff, sizeof(onoff)); -} -#endif /* USE_SO_NOSIGPIPE */ - -static CURLcode socket_open(struct Curl_easy *data, - struct Curl_sockaddr_ex *addr, - curl_socket_t *sockfd) -{ - char errbuf[STRERROR_LEN]; - -#ifdef SOCK_CLOEXEC - addr->socktype |= SOCK_CLOEXEC; -#endif - - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - if(data->set.fopensocket) { - /* - * If the opensocket callback is set, all the destination address - * information is passed to the callback. Depending on this information the - * callback may opt to abort the connection, this is indicated returning - * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When - * the callback returns a valid socket the destination address information - * might have been changed and this 'new' address will actually be used - * here to connect. - */ - Curl_set_in_callback(data, TRUE); - *sockfd = data->set.fopensocket(data->set.opensocket_client, - CURLSOCKTYPE_IPCXN, - (struct curl_sockaddr *)addr); - Curl_set_in_callback(data, FALSE); - } - else { - /* opensocket callback not set, so create the socket now */ -#ifdef DEBUGBUILD - if((addr->family == AF_INET6) && getenv("CURL_DBG_SOCK_FAIL_IPV6")) { - failf(data, "CURL_DBG_SOCK_FAIL_IPV6: failed to open socket"); - return CURLE_COULDNT_CONNECT; - } -#endif - *sockfd = CURL_SOCKET(addr->family, addr->socktype, addr->protocol); - if((*sockfd == CURL_SOCKET_BAD) && (SOCKERRNO == SOCKENOMEM)) - return CURLE_OUT_OF_MEMORY; - } - - if(*sockfd == CURL_SOCKET_BAD) { - /* no socket, no connection */ - failf(data, "failed to open socket: %s", - curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); - return CURLE_COULDNT_CONNECT; - } - -#ifdef USE_SO_NOSIGPIPE - if(Curl_sock_nosigpipe(*sockfd) < 0) { - failf(data, "setsockopt enable SO_NOSIGPIPE: %s", - curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); - sclose(*sockfd); - *sockfd = CURL_SOCKET_BAD; - return CURLE_COULDNT_CONNECT; - } -#endif /* USE_SO_NOSIGPIPE */ - -#if defined(HAVE_FCNTL) && !defined(SOCK_CLOEXEC) - if(fcntl(*sockfd, F_SETFD, FD_CLOEXEC) < 0) { - failf(data, "fcntl set CLOEXEC: %s", - curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); - sclose(*sockfd); - *sockfd = CURL_SOCKET_BAD; - return CURLE_COULDNT_CONNECT; - } -#endif - -#if defined(USE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) - if(data->conn->scope_id && (addr->family == AF_INET6)) { - struct sockaddr_in6 * const sa6 = (void *)&addr->curl_sa_addr; - sa6->sin6_scope_id = data->conn->scope_id; - } -#endif - return CURLE_OK; -} - -/* - * Create a socket based on info from 'conn' and 'ai'. - * - * 'addr' should be a pointer to the correct struct to get data back, or NULL. - * 'sockfd' must be a pointer to a socket descriptor. - * - * If the open socket callback is set, used that! - * - */ -CURLcode Curl_socket_open(struct Curl_easy *data, - const struct Curl_addrinfo *ai, - struct Curl_sockaddr_ex *addr, - uint8_t transport, - curl_socket_t *sockfd) -{ - struct Curl_sockaddr_ex dummy; - CURLcode result; - - if(!addr) - /* if the caller does not want info back, use a local temp copy */ - addr = &dummy; - - result = Curl_socket_addr_from_ai(addr, ai, transport); - if(result) - return result; - - return socket_open(data, addr, sockfd); -} - -static int socket_close(struct Curl_easy *data, struct connectdata *conn, - int use_callback, curl_socket_t sock) -{ - if(sock == CURL_SOCKET_BAD) - return 0; - - if(use_callback && conn && conn->fclosesocket) { - int rc; - Curl_multi_will_close(data, sock); - Curl_set_in_callback(data, TRUE); - rc = conn->fclosesocket(conn->closesocket_client, sock); - Curl_set_in_callback(data, FALSE); - return rc; - } - - if(conn) - /* tell the multi-socket code about this */ - Curl_multi_will_close(data, sock); - - sclose(sock); - - return 0; -} - -/* - * Close a socket. - * - * 'conn' can be NULL, beware! - */ -int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t sock) -{ - return socket_close(data, conn, FALSE, sock); -} - -/* - * Curl_parse_interface() - * - * This is used to parse interface argument in the following formats. - * In all the examples, `host` can be an IP address or a hostname. - * - * - can be either an interface name or a host. - * if! - interface name. - * host! - hostname. - * ifhost!! - interface name and hostname. - * - * Parameters: - * - * input [in] - input string. - * len [in] - length of the input string. - * dev [in/out] - address where a pointer to newly allocated memory - * holding the interface-or-host will be stored upon - * completion. - * iface [in/out] - address where a pointer to newly allocated memory - * holding the interface will be stored upon completion. - * host [in/out] - address where a pointer to newly allocated memory - * holding the host will be stored upon completion. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_parse_interface(const char *input, - char **dev, char **iface, char **host) -{ - static const char if_prefix[] = "if!"; - static const char host_prefix[] = "host!"; - static const char if_host_prefix[] = "ifhost!"; - size_t len; - - DEBUGASSERT(dev); - DEBUGASSERT(iface); - DEBUGASSERT(host); - - len = strlen(input); - if(len > 512) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(!strncmp(if_prefix, input, strlen(if_prefix))) { - input += strlen(if_prefix); - if(!*input) - return CURLE_BAD_FUNCTION_ARGUMENT; - *iface = curlx_memdup0(input, len - strlen(if_prefix)); - return *iface ? CURLE_OK : CURLE_OUT_OF_MEMORY; - } - else if(!strncmp(host_prefix, input, strlen(host_prefix))) { - input += strlen(host_prefix); - if(!*input) - return CURLE_BAD_FUNCTION_ARGUMENT; - *host = curlx_memdup0(input, len - strlen(host_prefix)); - return *host ? CURLE_OK : CURLE_OUT_OF_MEMORY; - } - else if(!strncmp(if_host_prefix, input, strlen(if_host_prefix))) { - const char *host_part; - input += strlen(if_host_prefix); - len -= strlen(if_host_prefix); - host_part = memchr(input, '!', len); - if(!host_part || !*(host_part + 1)) - return CURLE_BAD_FUNCTION_ARGUMENT; - *iface = curlx_memdup0(input, host_part - input); - if(!*iface) - return CURLE_OUT_OF_MEMORY; - ++host_part; - *host = curlx_memdup0(host_part, len - (host_part - input)); - if(!*host) { - curlx_free(*iface); - *iface = NULL; - return CURLE_OUT_OF_MEMORY; - } - return CURLE_OK; - } - - if(!*input) - return CURLE_BAD_FUNCTION_ARGUMENT; - *dev = curlx_memdup0(input, len); - return *dev ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} - -#ifndef CURL_DISABLE_BINDLOCAL -static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t sockfd, int af, unsigned int scope, - uint8_t transport) -{ - struct Curl_sockaddr_storage sa; - struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */ - curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */ - struct sockaddr_in *si4 = (struct sockaddr_in *)&sa; -#ifdef USE_IPV6 - struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa; -#endif - - struct Curl_dns_entry *h = NULL; - unsigned short port = data->set.localport; /* use this port number, 0 for - "random" */ - /* how many port numbers to try to bind to, increasing one at a time */ - int portnum = data->set.localportrange; - const char *dev = data->set.str[STRING_DEVICE]; - const char *iface_input = data->set.str[STRING_INTERFACE]; - const char *host_input = data->set.str[STRING_BINDHOST]; - const char *iface = iface_input ? iface_input : dev; - const char *host = host_input ? host_input : dev; - int error; -#ifdef IP_BIND_ADDRESS_NO_PORT - int on = 1; -#endif -#ifndef USE_IPV6 - (void)scope; -#endif - - /************************************************************* - * Select device to bind socket to - *************************************************************/ - if(!iface && !host && !port) - /* no local kind of binding was requested */ - return CURLE_OK; - else if(iface && (strlen(iface) >= 255)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - memset(&sa, 0, sizeof(struct Curl_sockaddr_storage)); - - if(iface || host) { - char myhost[256] = ""; - int done = 0; /* -1 for error, 1 for address found */ - if2ip_result_t if2ip_result = IF2IP_NOT_FOUND; - -#ifdef SO_BINDTODEVICE - if(iface) { - /* - * This binds the local socket to a particular interface. This will - * force even requests to other local interfaces to go out the external - * interface. Only bind to the interface when specified as interface, - * not as a hostname or ip address. - * - * The interface might be a VRF, eg: vrf-blue, which means it cannot be - * converted to an IP address and would fail Curl_if2ip. Try to - * use it straight away. - */ - if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, - iface, (curl_socklen_t)strlen(iface) + 1) == 0) { - /* This is often "errno 1, error: Operation not permitted" if you are - * not running as root or another suitable privileged user. If it - * succeeds it means the parameter was a valid interface and not an IP - * address. Return immediately. - */ - if(!host_input) { - infof(data, "socket successfully bound to interface '%s'", iface); - return CURLE_OK; - } - } - } -#endif - if(!host_input) { - /* Discover IP from input device, then bind to it */ - if2ip_result = Curl_if2ip(af, -#ifdef USE_IPV6 - scope, conn->scope_id, -#endif - iface, myhost, sizeof(myhost)); - } - switch(if2ip_result) { - case IF2IP_NOT_FOUND: - if(iface_input && !host_input) { - /* Do not fall back to treating it as a hostname */ - char buffer[STRERROR_LEN]; - data->state.os_errno = error = SOCKERRNO; - failf(data, "Could not bind to interface '%s' with errno %d: %s", - iface, error, curlx_strerror(error, buffer, sizeof(buffer))); - return CURLE_INTERFACE_FAILED; - } - break; - case IF2IP_AF_NOT_SUPPORTED: - /* Signal the caller to try another address family if available */ - return CURLE_UNSUPPORTED_PROTOCOL; - case IF2IP_FOUND: - /* - * We now have the numerical IP address in the 'myhost' buffer - */ - host = myhost; - infof(data, "Local Interface %s is ip %s using address family %i", - iface, host, af); - done = 1; - break; - } - if(!iface_input || host_input) { - /* - * This was not an interface, resolve the name as a hostname - * or IP number - * - * Temporarily force name resolution to use only the address type - * of the connection. The resolve functions should really be changed - * to take a type parameter instead. - */ - uint8_t dns_queries = (af == AF_INET) ? - CURL_DNSQ_A : (CURL_DNSQ_A | CURL_DNSQ_AAAA); -#ifdef USE_IPV6 - if(af == AF_INET6) - dns_queries = CURL_DNSQ_AAAA; -#endif - - (void)Curl_resolv_blocking(data, dns_queries, host, 80, transport, &h); - if(h) { - int h_af = h->addr->ai_family; - /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */ - Curl_printable_address(h->addr, myhost, sizeof(myhost)); - infof(data, "Name '%s' family %i resolved to '%s' family %i", - host, af, myhost, h_af); - Curl_dns_entry_unlink(data, &h); /* this will NULL, potential free h */ - if(af != h_af) { - /* bad IP version combo, signal the caller to try another address - family if available */ - return CURLE_UNSUPPORTED_PROTOCOL; - } - done = 1; - } - else { - /* - * provided dev was no interface (or interfaces are not supported - * e.g. Solaris) no ip address and no domain we fail here - */ - done = -1; - } - } - - if(done > 0) { -#ifdef USE_IPV6 - /* IPv6 address */ - if(af == AF_INET6) { -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - char *scope_ptr = strchr(myhost, '%'); - if(scope_ptr) - *(scope_ptr++) = '\0'; -#endif - if(curlx_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) { - si6->sin6_family = AF_INET6; - si6->sin6_port = htons(port); -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - if(scope_ptr) { - /* The "myhost" string either comes from Curl_if2ip or from - Curl_printable_address. The latter returns only numeric scope - IDs and the former returns none at all. Making the scope ID, - if present, known to be numeric */ - curl_off_t scope_id; - if(curlx_str_number((const char **)CURL_UNCONST(&scope_ptr), - &scope_id, UINT_MAX)) - return CURLE_UNSUPPORTED_PROTOCOL; - si6->sin6_scope_id = (unsigned int)scope_id; - } -#endif - } - sizeof_sa = sizeof(struct sockaddr_in6); - } - else -#endif - /* IPv4 address */ - if((af == AF_INET) && - (curlx_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) { - si4->sin_family = AF_INET; - si4->sin_port = htons(port); - sizeof_sa = sizeof(struct sockaddr_in); - } - } - - if(done < 1) { - /* errorbuf is set false so failf will overwrite any message already in - the error buffer, so the user receives this error message instead of a - generic resolve error. */ - char buffer[STRERROR_LEN]; - data->state.errorbuf = FALSE; - data->state.os_errno = error = SOCKERRNO; - failf(data, "Could not bind to '%s' with errno %d: %s", host, - error, curlx_strerror(error, buffer, sizeof(buffer))); - return CURLE_INTERFACE_FAILED; - } - } - else { - /* no device was given, prepare sa to match af's needs */ -#ifdef USE_IPV6 - if(af == AF_INET6) { - si6->sin6_family = AF_INET6; - si6->sin6_port = htons(port); - sizeof_sa = sizeof(struct sockaddr_in6); - } - else -#endif - if(af == AF_INET) { - si4->sin_family = AF_INET; - si4->sin_port = htons(port); - sizeof_sa = sizeof(struct sockaddr_in); - } - } -#ifdef IP_BIND_ADDRESS_NO_PORT - (void)setsockopt(sockfd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, &on, sizeof(on)); -#endif - for(;;) { - if(bind(sockfd, sock, sizeof_sa) >= 0) { - /* we succeeded to bind */ - infof(data, "Local port: %hu", port); - conn->bits.bound = TRUE; - return CURLE_OK; - } - - if(--portnum > 0) { - port++; /* try next port */ - if(port == 0) - break; - infof(data, "Bind to local port %d failed, trying next", port - 1); - /* We reuse/clobber the port variable here below */ - if(sock->sa_family == AF_INET) - si4->sin_port = htons(port); -#ifdef USE_IPV6 - else - si6->sin6_port = htons(port); -#endif - } - else - break; - } - { - char buffer[STRERROR_LEN]; - data->state.os_errno = error = SOCKERRNO; - failf(data, "bind failed with errno %d: %s", - error, curlx_strerror(error, buffer, sizeof(buffer))); - } - - return CURLE_INTERFACE_FAILED; -} -#endif - -/* - * verifyconnect() returns TRUE if the connect really has happened. - */ -static bool verifyconnect(curl_socket_t sockfd, int *error) -{ - bool rc = TRUE; -#ifdef SO_ERROR - int err = 0; - curl_socklen_t errSize = sizeof(err); - -#ifdef _WIN32 - /* - * In October 2003 we effectively nullified this function on Windows due to - * problems with it using all CPU in multi-threaded cases. - * - * In May 2004, we brought it back to offer more info back on connect - * failures. We could reproduce the former problems with this function, but - * could avoid them by adding this SleepEx() call below: - * - * "I do not have Rational Quantify, but the hint from his post was - * ntdll::NtRemoveIoCompletion(). I would assume the SleepEx (or maybe - * Sleep(0) would be enough?) would release whatever - * mutex/critical-section the ntdll call is waiting on. - * - * Someone got to verify this on Win-NT 4.0, 2000." - */ - SleepEx(0, FALSE); -#endif - - if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize)) - err = SOCKERRNO; -#if defined(EBADIOCTL) && defined(__minix) - /* Minix 3.1.x does not support getsockopt on UDP sockets */ - if(EBADIOCTL == err) { - SET_SOCKERRNO(0); - err = 0; - } -#endif - if((err == 0) || (SOCKEISCONN == err)) - /* we are connected, awesome! */ - rc = TRUE; - else - /* This was not a successful connect */ - rc = FALSE; - if(error) - *error = err; -#else - (void)sockfd; - if(error) - *error = SOCKERRNO; -#endif - return rc; -} - -/** - * Determine the curl code for a socket connect() == -1 with errno. - */ -static CURLcode socket_connect_result(struct Curl_easy *data, - const char *ipaddress, int error) -{ - switch(error) { - case SOCKEINPROGRESS: - case SOCKEWOULDBLOCK: -#ifdef EAGAIN -#if (EAGAIN) != (SOCKEWOULDBLOCK) - /* On some platforms EAGAIN and EWOULDBLOCK are the - * same value, and on others they are different, hence - * the odd #if - */ - case EAGAIN: -#endif -#endif - return CURLE_OK; - - default: - /* unknown error, fallthrough and try another address! */ - { - VERBOSE(char buffer[STRERROR_LEN]); - infof(data, "Immediate connect fail for %s: %s", ipaddress, - curlx_strerror(error, buffer, sizeof(buffer))); - NOVERBOSE((void)ipaddress); - } - data->state.os_errno = error; - /* connect failed */ - return CURLE_COULDNT_CONNECT; - } -} - -struct cf_socket_ctx { - uint8_t transport; - struct Curl_sockaddr_ex addr; /* address to connect to */ - curl_socket_t sock; /* current attempt socket */ - struct ip_quadruple ip; /* The IP quadruple 2x(addr+port) */ - struct curltime started_at; /* when socket was created */ - struct curltime connected_at; /* when socket connected/got first byte */ - struct curltime first_byte_at; /* when first byte was recvd */ -#ifdef USE_WINSOCK - struct curltime last_sndbuf_query_at; /* when SO_SNDBUF last queried */ - ULONG sndbuf_size; /* the last set SO_SNDBUF size */ -#endif - int error; /* errno of last failure or 0 */ -#ifdef DEBUGBUILD - int wblock_percent; /* percent of writes doing EAGAIN */ - int wpartial_percent; /* percent of bytes written in send */ - int rblock_percent; /* percent of reads doing EAGAIN */ - size_t recv_max; /* max enforced read size */ -#endif - BIT(got_first_byte); /* if first byte was received */ - BIT(listening); /* socket is listening */ - BIT(accepted); /* socket was accepted, not connected */ - BIT(sock_connected); /* socket is "connected", e.g. in UDP */ - BIT(active); -}; - -static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx, - struct Curl_sockaddr_ex *addr, - uint8_t transport) -{ - memset(ctx, 0, sizeof(*ctx)); - ctx->sock = CURL_SOCKET_BAD; - ctx->transport = transport; - ctx->addr = *addr; - -#ifdef DEBUGBUILD - { - const char *p = getenv("CURL_DBG_SOCK_WBLOCK"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, 100)) - ctx->wblock_percent = (int)l; - } - p = getenv("CURL_DBG_SOCK_WPARTIAL"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, 100)) - ctx->wpartial_percent = (int)l; - } - p = getenv("CURL_DBG_SOCK_RBLOCK"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, 100)) - ctx->rblock_percent = (int)l; - } - p = getenv("CURL_DBG_SOCK_RMAX"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, CURL_OFF_T_MAX)) - ctx->recv_max = (size_t)l; - } - } -#endif - - return CURLE_OK; -} - -static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - - if(ctx && ctx->sock != CURL_SOCKET_BAD) { - CURL_TRC_CF(data, cf, "cf_socket_close, fd=%" FMT_SOCKET_T, ctx->sock); - if(ctx->sock == cf->conn->sock[cf->sockindex]) - cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD; - socket_close(data, cf->conn, !ctx->accepted, ctx->sock); - ctx->sock = CURL_SOCKET_BAD; - ctx->active = FALSE; - memset(&ctx->started_at, 0, sizeof(ctx->started_at)); - memset(&ctx->connected_at, 0, sizeof(ctx->connected_at)); - } - - cf->connected = FALSE; -} - -static CURLcode cf_socket_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - if(cf->connected) { - struct cf_socket_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "cf_socket_shutdown, fd=%" FMT_SOCKET_T, ctx->sock); - /* On TCP, and when the socket looks well and non-blocking mode - * can be enabled, receive dangling bytes before close to avoid - * entering RST states unnecessarily. */ - if(ctx->sock != CURL_SOCKET_BAD && - ctx->transport == TRNSPRT_TCP && - (curlx_nonblock(ctx->sock, TRUE) >= 0)) { - unsigned char buf[1024]; - (void)sread(ctx->sock, buf, sizeof(buf)); - } - } - *done = TRUE; - return CURLE_OK; -} - -static void cf_socket_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - - cf_socket_close(cf, data); - CURL_TRC_CF(data, cf, "destroy"); - curlx_free(ctx); - cf->ctx = NULL; -} - -static void set_local_ip(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - ctx->ip.local_ip[0] = 0; - ctx->ip.local_port = 0; - -#ifdef HAVE_GETSOCKNAME - if((ctx->sock != CURL_SOCKET_BAD) && - !(data->conn->scheme->protocol & CURLPROTO_TFTP)) { - /* TFTP does not connect, so it cannot get the IP like this */ - struct Curl_sockaddr_storage ssloc; - curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage); - VERBOSE(char buffer[STRERROR_LEN]); - - memset(&ssloc, 0, sizeof(ssloc)); - if(getsockname(ctx->sock, (struct sockaddr *)&ssloc, &slen)) { - VERBOSE(int error = SOCKERRNO); - infof(data, "getsockname() failed with errno %d: %s", - error, curlx_strerror(error, buffer, sizeof(buffer))); - } - else if(!Curl_addr2string((struct sockaddr *)&ssloc, slen, - ctx->ip.local_ip, &ctx->ip.local_port)) { - infof(data, "ssloc inet_ntop() failed with errno %d: %s", - errno, curlx_strerror(errno, buffer, sizeof(buffer))); - } - } -#else - (void)data; -#endif -} - -static CURLcode set_remote_ip(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - - /* store remote address and port used in this connection attempt */ - ctx->ip.transport = ctx->transport; - if(!Curl_addr2string(&ctx->addr.curl_sa_addr, - (curl_socklen_t)ctx->addr.addrlen, - ctx->ip.remote_ip, &ctx->ip.remote_port)) { - char buffer[STRERROR_LEN]; - - ctx->error = errno; - /* malformed address or bug in inet_ntop, try next address */ - failf(data, "curl_sa_addr inet_ntop() failed with errno %d: %s", - errno, curlx_strerror(errno, buffer, sizeof(buffer))); - return CURLE_FAILED_INIT; - } - return CURLE_OK; -} - -/* to figure out the type of the socket safely, remove the possibly ORed - bits before comparing */ -static int cf_socktype(int x) -{ -#ifdef SOCK_CLOEXEC - x &= ~SOCK_CLOEXEC; -#endif -#ifdef SOCK_NONBLOCK - x &= ~SOCK_NONBLOCK; -#endif - return x; -} - -static CURLcode cf_socket_open(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - int error = 0; - bool isconnected = FALSE; - CURLcode result = CURLE_COULDNT_CONNECT; - bool is_tcp; - - DEBUGASSERT(ctx->sock == CURL_SOCKET_BAD); - ctx->started_at = *Curl_pgrs_now(data); -#ifdef SOCK_NONBLOCK - /* Do not tuck SOCK_NONBLOCK into socktype when opensocket callback is set - * because we would not know how socketype is about to be used in the - * callback, SOCK_NONBLOCK might get factored out before calling socket(). - */ - if(!data->set.fopensocket) - ctx->addr.socktype |= SOCK_NONBLOCK; -#endif - result = socket_open(data, &ctx->addr, &ctx->sock); -#ifdef SOCK_NONBLOCK - /* Restore the socktype after the socket is created. */ - if(!data->set.fopensocket) - ctx->addr.socktype &= ~SOCK_NONBLOCK; -#endif - if(result) - goto out; - - result = set_remote_ip(cf, data); - if(result) - goto out; - -#ifdef USE_IPV6 - if(ctx->addr.family == AF_INET6) { -#ifdef USE_WINSOCK - /* Turn on support for IPv4-mapped IPv6 addresses. - * Linux kernel, NetBSD, FreeBSD, Darwin, lwIP: default is off; - * Windows Vista and later: default is on; - * DragonFly BSD: acts like off, and dummy setting; - * OpenBSD and earlier Windows: unsupported. - * Linux: controlled by /proc/sys/net/ipv6/bindv6only. - */ - int on = 0; - (void)setsockopt(ctx->sock, IPPROTO_IPV6, IPV6_V6ONLY, - (void *)&on, sizeof(on)); -#endif - infof(data, " Trying [%s]:%d...", ctx->ip.remote_ip, ctx->ip.remote_port); - } - else -#endif - infof(data, " Trying %s:%d...", ctx->ip.remote_ip, ctx->ip.remote_port); - -#ifdef USE_IPV6 - is_tcp = (ctx->addr.family == AF_INET || - ctx->addr.family == AF_INET6) && - cf_socktype(ctx->addr.socktype) == SOCK_STREAM; -#else - is_tcp = (ctx->addr.family == AF_INET) && - cf_socktype(ctx->addr.socktype) == SOCK_STREAM; -#endif - if(is_tcp && data->set.tcp_nodelay) - tcpnodelay(cf, data, ctx->sock); - - if(is_tcp && data->set.tcp_keepalive) - tcpkeepalive(cf, data, ctx->sock); - - if(data->set.fsockopt) { - /* activate callback for setting socket options */ - Curl_set_in_callback(data, TRUE); - error = data->set.fsockopt(data->set.sockopt_client, - ctx->sock, - CURLSOCKTYPE_IPCXN); - Curl_set_in_callback(data, FALSE); - - if(error == CURL_SOCKOPT_ALREADY_CONNECTED) - isconnected = TRUE; - else if(error) { - result = CURLE_ABORTED_BY_CALLBACK; - goto out; - } - } - -#ifndef CURL_DISABLE_BINDLOCAL - /* possibly bind the local end to an IP, interface or port */ - if(ctx->addr.family == AF_INET -#ifdef USE_IPV6 - || ctx->addr.family == AF_INET6 -#endif - ) { - result = bindlocal(data, cf->conn, ctx->sock, ctx->addr.family, - Curl_ipv6_scope(&ctx->addr.curl_sa_addr), - ctx->transport); - if(result) { - if(result == CURLE_UNSUPPORTED_PROTOCOL) { - /* The address family is not supported on this interface. - We can continue trying addresses */ - result = CURLE_COULDNT_CONNECT; - } - goto out; - } - } -#endif - -#ifndef SOCK_NONBLOCK - /* Set socket non-blocking, must be a non-blocking socket for - * a non-blocking connect. */ - error = curlx_nonblock(ctx->sock, TRUE); - if(error < 0) { - result = CURLE_UNSUPPORTED_PROTOCOL; - ctx->error = SOCKERRNO; - goto out; - } -#else - if(data->set.fopensocket) { - /* Set socket non-blocking, must be a non-blocking socket for - * a non-blocking connect. */ - error = curlx_nonblock(ctx->sock, TRUE); - if(error < 0) { - result = CURLE_UNSUPPORTED_PROTOCOL; - ctx->error = SOCKERRNO; - goto out; - } - } -#endif - ctx->sock_connected = (cf_socktype(ctx->addr.socktype) != SOCK_DGRAM); -out: - if(result) { - if(ctx->sock != CURL_SOCKET_BAD) { - socket_close(data, cf->conn, TRUE, ctx->sock); - ctx->sock = CURL_SOCKET_BAD; - } - } - else if(isconnected) { - set_local_ip(cf, data); - ctx->connected_at = *Curl_pgrs_now(data); - cf->connected = TRUE; - } - CURL_TRC_CF(data, cf, "cf_socket_open() -> %d, fd=%" FMT_SOCKET_T, - result, ctx->sock); - return result; -} - -static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data, - bool is_tcp_fastopen) -{ - struct cf_socket_ctx *ctx = cf->ctx; -#ifdef TCP_FASTOPEN_CONNECT - int optval = 1; -#endif - int rc = -1; - - (void)data; - if(is_tcp_fastopen) { -#ifdef CONNECT_DATA_IDEMPOTENT /* Darwin */ -# ifdef HAVE_BUILTIN_AVAILABLE - /* while connectx function is available since macOS 10.11 / iOS 9, - it did not have the interface declared correctly until - Xcode 9 / macOS SDK 10.13 */ - if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) { - sa_endpoints_t endpoints; - endpoints.sae_srcif = 0; - endpoints.sae_srcaddr = NULL; - endpoints.sae_srcaddrlen = 0; - endpoints.sae_dstaddr = &ctx->addr.curl_sa_addr; - endpoints.sae_dstaddrlen = ctx->addr.addrlen; - - rc = connectx(ctx->sock, &endpoints, SAE_ASSOCID_ANY, - CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT, - NULL, 0, NULL, NULL); - } - else { - rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen); - } -# else - rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen); -# endif /* HAVE_BUILTIN_AVAILABLE */ -#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */ - if(setsockopt(ctx->sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, - (void *)&optval, sizeof(optval)) < 0) - CURL_TRC_CF(data, cf, "Failed to enable TCP Fast Open on fd %" - FMT_SOCKET_T, ctx->sock); - - rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen); -#elif defined(MSG_FASTOPEN) /* old Linux */ - if(Curl_conn_is_ssl(cf->conn, cf->sockindex)) - rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen); - else - rc = 0; /* Do nothing */ -#endif - } - else { - rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, - (curl_socklen_t)ctx->addr.addrlen); - } - return rc; -} - -static CURLcode cf_tcp_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_socket_ctx *ctx = cf->ctx; - CURLcode result = CURLE_COULDNT_CONNECT; - int rc = 0; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; /* a negative world view is best */ - if(ctx->sock == CURL_SOCKET_BAD) { - int error; - - result = cf_socket_open(cf, data); - if(result) - goto out; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* Connect TCP socket */ - rc = do_connect(cf, data, (bool)cf->conn->bits.tcp_fastopen); - error = SOCKERRNO; - set_local_ip(cf, data); - CURL_TRC_CF(data, cf, "local address %s port %d...", - ctx->ip.local_ip, ctx->ip.local_port); - if(rc == -1) { - result = socket_connect_result(data, ctx->ip.remote_ip, error); - goto out; - } - } - -#ifdef mpeix - /* Call this function once now, and ignore the results. We do this to - "clear" the error state on the socket so that we can later read it - reliably. This is reported necessary on the MPE/iX operating - system. */ - (void)verifyconnect(ctx->sock, NULL); -#endif - /* check socket for connect */ - rc = SOCKET_WRITABLE(ctx->sock, 0); - - if(rc == 0) { /* no connection yet */ - CURL_TRC_CF(data, cf, "not connected yet on fd=%" FMT_SOCKET_T, ctx->sock); - return CURLE_OK; - } - else if(rc == CURL_CSELECT_OUT || cf->conn->bits.tcp_fastopen) { - if(verifyconnect(ctx->sock, &ctx->error)) { - /* we are connected with TCP, awesome! */ - ctx->connected_at = *Curl_pgrs_now(data); - set_local_ip(cf, data); - *done = TRUE; - cf->connected = TRUE; - CURL_TRC_CF(data, cf, "connected on fd=%" FMT_SOCKET_T, ctx->sock); - return CURLE_OK; - } - } - else if(rc & CURL_CSELECT_ERR) { - CURL_TRC_CF(data, cf, "poll/select error on fd=%" FMT_SOCKET_T, ctx->sock); - (void)verifyconnect(ctx->sock, &ctx->error); - result = CURLE_COULDNT_CONNECT; - } - -out: - if(result) { - VERBOSE(char buffer[STRERROR_LEN]); - set_local_ip(cf, data); - if(ctx->error) { - data->state.os_errno = ctx->error; - SET_SOCKERRNO(ctx->error); - VERBOSE(curlx_strerror(ctx->error, buffer, sizeof(buffer))); - } - else { - VERBOSE(curlx_strcopy(buffer, sizeof(buffer), STRCONST("peer closed"))); - } - if(ctx->sock != CURL_SOCKET_BAD) { - socket_close(data, cf->conn, TRUE, ctx->sock); - ctx->sock = CURL_SOCKET_BAD; - } - infof(data, "connect to %s port %u from %s port %d failed: %s", - ctx->ip.remote_ip, ctx->ip.remote_port, - ctx->ip.local_ip, ctx->ip.local_port, - curlx_strerror(ctx->error, buffer, sizeof(buffer))); - *done = FALSE; - } - return result; -} - -static CURLcode cf_socket_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_socket_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(ctx->sock != CURL_SOCKET_BAD) { - /* A listening socket filter needs to be connected before the accept - * for some weird FTP interaction. This should be rewritten, so that - * FTP no longer does the socket checks and accept calls and delegates - * all that to the filter. */ - if(ctx->listening) { - result = Curl_pollset_set_in_only(data, ps, ctx->sock); - CURL_TRC_CF(data, cf, "adjust_pollset, listening, POLLIN fd=%" - FMT_SOCKET_T, ctx->sock); - } - else if(!cf->connected) { - result = Curl_pollset_set_out_only(data, ps, ctx->sock); - CURL_TRC_CF(data, cf, "adjust_pollset, !connected, POLLOUT fd=%" - FMT_SOCKET_T, ctx->sock); - } - else if(!ctx->active) { - result = Curl_pollset_add_in(data, ps, ctx->sock); - CURL_TRC_CF(data, cf, "adjust_pollset, !active, POLLIN fd=%" - FMT_SOCKET_T, ctx->sock); - } - } - return result; -} - -#ifdef USE_WINSOCK - -/* Offered by mingw-w64 v13+. MS SDK 7.0A+. */ -#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY -#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B -#endif - -static void win_update_sndbuf_size(struct Curl_easy *data, - struct cf_socket_ctx *ctx) -{ - ULONG ideal; - DWORD ideallen; - - if(curlx_ptimediff_ms(Curl_pgrs_now(data), - &ctx->last_sndbuf_query_at) > 1000) { - if(!WSAIoctl(ctx->sock, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0, - &ideal, sizeof(ideal), &ideallen, 0, 0) && - ideal != ctx->sndbuf_size && - !setsockopt(ctx->sock, SOL_SOCKET, SO_SNDBUF, - (const char *)&ideal, sizeof(ideal))) { - ctx->sndbuf_size = ideal; - } - ctx->last_sndbuf_query_at = *Curl_pgrs_now(data); - } -} - -#endif /* USE_WINSOCK */ - -static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - struct cf_socket_ctx *ctx = cf->ctx; - curl_socket_t fdsave; - ssize_t rv; - CURLcode result = CURLE_OK; - VERBOSE(size_t orig_len = len); - - (void)eos; - *pnwritten = 0; - fdsave = cf->conn->sock[cf->sockindex]; - cf->conn->sock[cf->sockindex] = ctx->sock; - -#ifdef DEBUGBUILD - /* simulate network blocking/partial writes */ - if(ctx->wblock_percent > 0) { - unsigned char c = 0; - Curl_rand_bytes(data, FALSE, &c, 1); - if(c >= ((100 - ctx->wblock_percent) * 256 / 100)) { - CURL_TRC_CF(data, cf, "send(len=%zu) SIMULATE EWOULDBLOCK", orig_len); - cf->conn->sock[cf->sockindex] = fdsave; - return CURLE_AGAIN; - } - } - if(cf->cft != &Curl_cft_udp && ctx->wpartial_percent > 0 && len > 8) { - len = len * ctx->wpartial_percent / 100; - if(!len) - len = 1; - CURL_TRC_CF(data, cf, "send(len=%zu) SIMULATE partial write of %zu bytes", - orig_len, len); - } -#endif - -#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */ - if(cf->conn->bits.tcp_fastopen) { - rv = sendto(ctx->sock, buf, len, MSG_FASTOPEN, - &ctx->addr.curl_sa_addr, ctx->addr.addrlen); - cf->conn->bits.tcp_fastopen = FALSE; - } - else -#endif - rv = swrite(ctx->sock, buf, len); - - if(!curlx_sztouz(rv, pnwritten)) { - int sockerr = SOCKERRNO; - - if( -#ifdef USE_WINSOCK - /* This is how Windows does it */ - (SOCKEWOULDBLOCK == sockerr) -#else - /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We therefore - treat both error codes the same here */ - (SOCKEWOULDBLOCK == sockerr) || - (EAGAIN == sockerr) || (SOCKEINTR == sockerr) || - (SOCKEINPROGRESS == sockerr) -#endif - ) { - /* EWOULDBLOCK */ - result = CURLE_AGAIN; - } - else { - char buffer[STRERROR_LEN]; - failf(data, "Send failure: %s", - curlx_strerror(sockerr, buffer, sizeof(buffer))); - data->state.os_errno = sockerr; - result = CURLE_SEND_ERROR; - } - } - -#ifdef USE_WINSOCK - if(!result) - win_update_sndbuf_size(data, ctx); -#endif - - CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, %zu", - orig_len, result, *pnwritten); - cf->conn->sock[cf->sockindex] = fdsave; - return result; -} - -static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread) -{ - struct cf_socket_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - ssize_t rv; - - *pnread = 0; -#ifdef DEBUGBUILD - /* simulate network blocking/partial reads */ - if(cf->cft != &Curl_cft_udp && ctx->rblock_percent > 0) { - unsigned char c = 0; - Curl_rand(data, &c, 1); - if(c >= ((100 - ctx->rblock_percent) * 256 / 100)) { - CURL_TRC_CF(data, cf, "recv(len=%zu) SIMULATE EWOULDBLOCK", len); - return CURLE_AGAIN; - } - } - if(cf->cft != &Curl_cft_udp && ctx->recv_max && ctx->recv_max < len) { - CURL_TRC_CF(data, cf, "recv(len=%zu) SIMULATE max read of %zu bytes", - len, ctx->recv_max); - len = ctx->recv_max; - } -#endif - - rv = sread(ctx->sock, buf, len); - - if(!curlx_sztouz(rv, pnread)) { - int sockerr = SOCKERRNO; - - if( -#ifdef USE_WINSOCK - /* This is how Windows does it */ - (SOCKEWOULDBLOCK == sockerr) -#else - /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We therefore - treat both error codes the same here */ - (SOCKEWOULDBLOCK == sockerr) || - (EAGAIN == sockerr) || (SOCKEINTR == sockerr) -#endif - ) { - /* EWOULDBLOCK */ - result = CURLE_AGAIN; - } - else { - char buffer[STRERROR_LEN]; - failf(data, "Recv failure: %s", - curlx_strerror(sockerr, buffer, sizeof(buffer))); - data->state.os_errno = sockerr; - result = CURLE_RECV_ERROR; - } - } - - CURL_TRC_CF(data, cf, "recv(len=%zu) -> %d, %zu", len, result, *pnread); - if(!result && !ctx->got_first_byte) { - ctx->first_byte_at = *Curl_pgrs_now(data); - ctx->got_first_byte = TRUE; - } - return result; -} - -static void cf_socket_update_data(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - /* Update the IP info held in the transfer, if we have that. */ - if(cf->connected && (cf->sockindex == FIRSTSOCKET)) { - struct cf_socket_ctx *ctx = cf->ctx; - data->info.primary = ctx->ip; - /* not sure if this is redundant... */ - data->info.conn_remote_port = cf->conn->remote_port; - } -} - -static void cf_socket_active(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - - /* use this socket from now on */ - cf->conn->sock[cf->sockindex] = ctx->sock; - set_local_ip(cf, data); -#ifdef USE_IPV6 - if(cf->sockindex == FIRSTSOCKET) - cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6); -#endif - ctx->active = TRUE; -} - -static CURLcode cf_socket_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - struct cf_socket_ctx *ctx = cf->ctx; - - (void)arg1; - (void)arg2; - switch(event) { - case CF_CTRL_CONN_INFO_UPDATE: - cf_socket_active(cf, data); - cf_socket_update_data(cf, data); - break; - case CF_CTRL_DATA_SETUP: - cf_socket_update_data(cf, data); - break; - case CF_CTRL_FORGET_SOCKET: - ctx->sock = CURL_SOCKET_BAD; - break; - } - return CURLE_OK; -} - -static bool cf_socket_conn_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending) -{ - struct cf_socket_ctx *ctx = cf->ctx; - struct pollfd pfd[1]; - int r; - - *input_pending = FALSE; - - if(!ctx || ctx->sock == CURL_SOCKET_BAD) - return FALSE; - - /* Check with 0 timeout if there are any events pending on the socket */ - pfd[0].fd = ctx->sock; - pfd[0].events = POLLRDNORM | POLLIN | POLLRDBAND | POLLPRI; - pfd[0].revents = 0; - - r = Curl_poll(pfd, 1, 0); - if(r < 0) { - CURL_TRC_CF(data, cf, "is_alive: poll error, assume dead"); - return FALSE; - } - else if(r == 0) { - CURL_TRC_CF(data, cf, "is_alive: poll timeout, assume alive"); - return TRUE; - } - else if(pfd[0].revents & (POLLERR | POLLHUP | POLLPRI | POLLNVAL)) { - CURL_TRC_CF(data, cf, "is_alive: err/hup/etc events, assume dead"); - return FALSE; - } - - CURL_TRC_CF(data, cf, "is_alive: valid events, looks alive"); - *input_pending = TRUE; - return TRUE; -} - -static CURLcode cf_socket_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_socket_ctx *ctx = cf->ctx; - - switch(query) { - case CF_QUERY_SOCKET: - DEBUGASSERT(pres2); - *((curl_socket_t *)pres2) = ctx->sock; - return CURLE_OK; - case CF_QUERY_TRANSPORT: - DEBUGASSERT(pres1); - *pres1 = ctx->transport; - return CURLE_OK; - case CF_QUERY_REMOTE_ADDR: - DEBUGASSERT(pres2); - *((const struct Curl_sockaddr_ex **)pres2) = cf->connected ? - &ctx->addr : NULL; - return CURLE_OK; - case CF_QUERY_CONNECT_REPLY_MS: - if(ctx->got_first_byte) { - timediff_t ms = curlx_ptimediff_ms(&ctx->first_byte_at, - &ctx->started_at); - *pres1 = (ms < INT_MAX) ? (int)ms : INT_MAX; - } - else - *pres1 = -1; - return CURLE_OK; - case CF_QUERY_TIMER_CONNECT: { - struct curltime *when = pres2; - switch(ctx->transport) { - case TRNSPRT_UDP: - case TRNSPRT_QUIC: - /* Since UDP connected sockets work different from TCP, we use the - * time of the first byte from the peer as the "connect" time. */ - if(ctx->got_first_byte) { - *when = ctx->first_byte_at; - break; - } - FALLTHROUGH(); - default: - *when = ctx->connected_at; - break; - } - return CURLE_OK; - } - case CF_QUERY_IP_INFO: -#ifdef USE_IPV6 - *pres1 = (ctx->addr.family == AF_INET6); -#else - *pres1 = FALSE; -#endif - *(struct ip_quadruple *)pres2 = ctx->ip; - return CURLE_OK; - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -struct Curl_cftype Curl_cft_tcp = { - "TCP", - CF_TYPE_IP_CONNECT, - CURL_LOG_LVL_NONE, - cf_socket_destroy, - cf_tcp_connect, - cf_socket_close, - cf_socket_shutdown, - cf_socket_adjust_pollset, - Curl_cf_def_data_pending, - cf_socket_send, - cf_socket_recv, - cf_socket_cntrl, - cf_socket_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_socket_query, -}; - -CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport) -{ - struct cf_socket_ctx *ctx = NULL; - struct Curl_cfilter *cf = NULL; - CURLcode result; - - (void)data; - (void)conn; - DEBUGASSERT(transport == TRNSPRT_TCP); - if(!addr) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = cf_socket_ctx_init(ctx, addr, transport); - if(result) - goto out; - - result = Curl_cf_create(&cf, &Curl_cft_tcp, ctx); - -out: - *pcf = (!result) ? cf : NULL; - if(result) { - curlx_safefree(cf); - curlx_safefree(ctx); - } - - return result; -} - -#ifdef __linux__ -static void linux_quic_mtu(struct cf_socket_ctx *ctx) -{ - int val; - switch(ctx->addr.family) { -#ifdef IP_MTU_DISCOVER - case AF_INET: - val = IP_PMTUDISC_DO; - (void)setsockopt(ctx->sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, - sizeof(val)); - break; -#endif -#ifdef IPV6_MTU_DISCOVER - case AF_INET6: - val = IPV6_PMTUDISC_DO; - (void)setsockopt(ctx->sock, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, - sizeof(val)); - break; -#endif - } -} -#else -#define linux_quic_mtu(x) -#endif - -#if defined(UDP_GRO) && \ - (defined(HAVE_SENDMMSG) || defined(HAVE_SENDMSG)) && \ - ((defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || defined(USE_QUICHE)) -static void linux_quic_gro(struct cf_socket_ctx *ctx) -{ - int one = 1; - (void)setsockopt(ctx->sock, IPPROTO_UDP, UDP_GRO, &one, - (socklen_t)sizeof(one)); -} -#else -#define linux_quic_gro(x) -#endif - -static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - int rc; - - /* QUIC needs a connected socket, nonblocking */ - DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD); - - /* error: The 1st argument to 'connect' is -1 but should be >= 0 - NOLINTNEXTLINE(clang-analyzer-unix.StdCLibraryFunctions) */ - rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, - (curl_socklen_t)ctx->addr.addrlen); - if(rc == -1) { - return socket_connect_result(data, ctx->ip.remote_ip, SOCKERRNO); - } - ctx->sock_connected = TRUE; - set_local_ip(cf, data); - CURL_TRC_CF(data, cf, "%s socket %" FMT_SOCKET_T - " connected: [%s:%d] -> [%s:%d]", - (ctx->transport == TRNSPRT_QUIC) ? "QUIC" : "UDP", - ctx->sock, ctx->ip.local_ip, ctx->ip.local_port, - ctx->ip.remote_ip, ctx->ip.remote_port); - - /* Currently, cf->ctx->sock is always non-blocking because the only - * caller to cf_udp_setup_quic() is cf_udp_connect() that passes the - * non-blocking socket created by cf_socket_open() to it. Thus, we - * do not need to call curlx_nonblock() in cf_udp_setup_quic() anymore. - */ - linux_quic_mtu(ctx); - linux_quic_gro(ctx); - - return CURLE_OK; -} - -static CURLcode cf_udp_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_socket_ctx *ctx = cf->ctx; - CURLcode result = CURLE_COULDNT_CONNECT; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - if(ctx->sock == CURL_SOCKET_BAD) { - result = cf_socket_open(cf, data); - if(result) { - CURL_TRC_CF(data, cf, "cf_udp_connect(), open failed -> %d", result); - goto out; - } - - if(ctx->transport == TRNSPRT_QUIC) { - result = cf_udp_setup_quic(cf, data); - if(result) - goto out; - CURL_TRC_CF(data, cf, "cf_udp_connect(), opened socket=%" - FMT_SOCKET_T " (%s:%d)", - ctx->sock, ctx->ip.local_ip, ctx->ip.local_port); - } - *done = TRUE; - cf->connected = TRUE; - } -out: - return result; -} - -struct Curl_cftype Curl_cft_udp = { - "UDP", - CF_TYPE_IP_CONNECT, - CURL_LOG_LVL_NONE, - cf_socket_destroy, - cf_udp_connect, - cf_socket_close, - cf_socket_shutdown, - cf_socket_adjust_pollset, - Curl_cf_def_data_pending, - cf_socket_send, - cf_socket_recv, - cf_socket_cntrl, - cf_socket_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_socket_query, -}; - -CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport) -{ - struct cf_socket_ctx *ctx = NULL; - struct Curl_cfilter *cf = NULL; - CURLcode result; - - (void)data; - (void)conn; - DEBUGASSERT(transport == TRNSPRT_UDP || transport == TRNSPRT_QUIC); - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = cf_socket_ctx_init(ctx, addr, transport); - if(result) - goto out; - - result = Curl_cf_create(&cf, &Curl_cft_udp, ctx); - -out: - *pcf = (!result) ? cf : NULL; - if(result) { - curlx_safefree(cf); - curlx_safefree(ctx); - } - - return result; -} - -/* this is the TCP filter which can also handle this case */ -struct Curl_cftype Curl_cft_unix = { - "UNIX", - CF_TYPE_IP_CONNECT, - CURL_LOG_LVL_NONE, - cf_socket_destroy, - cf_tcp_connect, - cf_socket_close, - cf_socket_shutdown, - cf_socket_adjust_pollset, - Curl_cf_def_data_pending, - cf_socket_send, - cf_socket_recv, - cf_socket_cntrl, - cf_socket_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_socket_query, -}; - -CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport) -{ - struct cf_socket_ctx *ctx = NULL; - struct Curl_cfilter *cf = NULL; - CURLcode result; - - (void)data; - (void)conn; - DEBUGASSERT(transport == TRNSPRT_UNIX); - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = cf_socket_ctx_init(ctx, addr, transport); - if(result) - goto out; - - result = Curl_cf_create(&cf, &Curl_cft_unix, ctx); - -out: - *pcf = (!result) ? cf : NULL; - if(result) { - curlx_safefree(cf); - curlx_safefree(ctx); - } - - return result; -} - -static timediff_t cf_tcp_accept_timeleft(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; - timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT; - timediff_t other_ms; - -#ifndef CURL_DISABLE_FTP - if(data->set.accepttimeout > 0) - timeout_ms = data->set.accepttimeout; -#endif - - /* check if the generic timeout possibly is set shorter */ - other_ms = Curl_timeleft_ms(data); - if(other_ms && (other_ms < timeout_ms)) - /* note that this also works fine for when other_ms happens to be negative - due to it already having elapsed */ - timeout_ms = other_ms; - else { - /* subtract elapsed time */ - timeout_ms -= curlx_ptimediff_ms(Curl_pgrs_now(data), &ctx->started_at); - if(!timeout_ms) - /* avoid returning 0 as that means no timeout! */ - timeout_ms = -1; - } - return timeout_ms; -} - -static void cf_tcp_set_accepted_remote_ip(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_socket_ctx *ctx = cf->ctx; -#ifdef HAVE_GETPEERNAME - char buffer[STRERROR_LEN]; - struct Curl_sockaddr_storage ssrem; - curl_socklen_t plen; - - ctx->ip.remote_ip[0] = 0; - ctx->ip.remote_port = 0; - plen = sizeof(ssrem); - memset(&ssrem, 0, plen); - if(getpeername(ctx->sock, (struct sockaddr *)&ssrem, &plen)) { - int error = SOCKERRNO; - failf(data, "getpeername() failed with errno %d: %s", - error, curlx_strerror(error, buffer, sizeof(buffer))); - return; - } - if(!Curl_addr2string((struct sockaddr *)&ssrem, plen, - ctx->ip.remote_ip, &ctx->ip.remote_port)) { - failf(data, "ssrem inet_ntop() failed with errno %d: %s", - errno, curlx_strerror(errno, buffer, sizeof(buffer))); - return; - } -#else - ctx->ip.remote_ip[0] = 0; - ctx->ip.remote_port = 0; - (void)data; -#endif -} - -static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_socket_ctx *ctx = cf->ctx; - char errbuf[STRERROR_LEN]; -#ifdef USE_IPV6 - struct Curl_sockaddr_storage add; -#else - struct sockaddr_in add; -#endif - curl_socklen_t size = (curl_socklen_t)sizeof(add); - curl_socket_t s_accepted = CURL_SOCKET_BAD; - timediff_t timeout_ms; - int socketstate = 0; - bool incoming = FALSE; - - /* we start accepted, if we ever close, we cannot go on */ - (void)data; - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - timeout_ms = cf_tcp_accept_timeleft(cf, data); - if(timeout_ms < 0) { - /* if a timeout was already reached, bail out */ - failf(data, "Accept timeout occurred while waiting server connect"); - return CURLE_FTP_ACCEPT_TIMEOUT; - } - - CURL_TRC_CF(data, cf, "Checking for incoming on fd=%" FMT_SOCKET_T - " ip=%s:%d", ctx->sock, ctx->ip.local_ip, ctx->ip.local_port); - socketstate = SOCKET_READABLE(ctx->sock, 0); - CURL_TRC_CF(data, cf, "socket_check -> %x", socketstate); - switch(socketstate) { - case -1: /* error */ - /* let's die here */ - failf(data, "Error while waiting for server connect"); - return CURLE_FTP_ACCEPT_FAILED; - default: - if(socketstate & CURL_CSELECT_IN) { - infof(data, "Ready to accept data connection from server"); - incoming = TRUE; - } - break; - } - - if(!incoming) { - CURL_TRC_CF(data, cf, "nothing heard from the server yet"); - return CURLE_OK; - } - - size = sizeof(add); -#ifdef HAVE_ACCEPT4 - s_accepted = CURL_ACCEPT4(ctx->sock, (struct sockaddr *)&add, &size, - SOCK_NONBLOCK | SOCK_CLOEXEC); -#else - s_accepted = CURL_ACCEPT(ctx->sock, (struct sockaddr *)&add, &size); -#endif - - if(s_accepted == CURL_SOCKET_BAD) { - failf(data, "Error accept()ing server connect: %s", - curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); - return CURLE_FTP_ACCEPT_FAILED; - } -#ifndef HAVE_ACCEPT4 -#ifdef HAVE_FCNTL - if(fcntl(s_accepted, F_SETFD, FD_CLOEXEC) < 0) { - failf(data, "fcntl set CLOEXEC: %s", - curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); - Curl_socket_close(data, cf->conn, s_accepted); - return CURLE_FTP_ACCEPT_FAILED; - } -#endif /* HAVE_FCNTL */ - if(curlx_nonblock(s_accepted, TRUE) < 0) { - failf(data, "set socket NONBLOCK: %s", - curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); - Curl_socket_close(data, cf->conn, s_accepted); - return CURLE_FTP_ACCEPT_FAILED; - } -#endif /* !HAVE_ACCEPT4 */ - infof(data, "Connection accepted from server"); - - /* Replace any filter on SECONDARY with one listening on this socket */ - ctx->listening = FALSE; - ctx->accepted = TRUE; - socket_close(data, cf->conn, TRUE, ctx->sock); - ctx->sock = s_accepted; - - cf->conn->sock[cf->sockindex] = ctx->sock; - cf_tcp_set_accepted_remote_ip(cf, data); - set_local_ip(cf, data); - ctx->active = TRUE; - ctx->connected_at = *Curl_pgrs_now(data); - cf->connected = TRUE; - CURL_TRC_CF(data, cf, "accepted_set(sock=%" FMT_SOCKET_T - ", remote=%s port=%d)", - ctx->sock, ctx->ip.remote_ip, ctx->ip.remote_port); - - if(data->set.fsockopt) { - int error = 0; - - /* activate callback for setting socket options */ - Curl_set_in_callback(data, true); - error = data->set.fsockopt(data->set.sockopt_client, - ctx->sock, CURLSOCKTYPE_ACCEPT); - Curl_set_in_callback(data, false); - - if(error) - return CURLE_ABORTED_BY_CALLBACK; - } - *done = TRUE; - return CURLE_OK; -} - -struct Curl_cftype Curl_cft_tcp_accept = { - "TCP-ACCEPT", - CF_TYPE_IP_CONNECT, - CURL_LOG_LVL_NONE, - cf_socket_destroy, - cf_tcp_accept_connect, - cf_socket_close, - cf_socket_shutdown, - cf_socket_adjust_pollset, - Curl_cf_def_data_pending, - cf_socket_send, - cf_socket_recv, - cf_socket_cntrl, - cf_socket_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_socket_query, -}; - -CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, curl_socket_t *s) -{ - CURLcode result; - struct Curl_cfilter *cf = NULL; - struct cf_socket_ctx *ctx = NULL; - - /* replace any existing */ - Curl_conn_cf_discard_all(data, conn, sockindex); - DEBUGASSERT(conn->sock[sockindex] == CURL_SOCKET_BAD); - - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - ctx->transport = TRNSPRT_TCP; - ctx->sock = *s; - ctx->listening = TRUE; - ctx->accepted = FALSE; - result = Curl_cf_create(&cf, &Curl_cft_tcp_accept, ctx); - if(result) - goto out; - Curl_conn_cf_add(data, conn, sockindex, cf); - - ctx->started_at = *Curl_pgrs_now(data); - conn->sock[sockindex] = ctx->sock; - set_local_ip(cf, data); - CURL_TRC_CF(data, cf, "set filter for listen socket fd=%" FMT_SOCKET_T - " ip=%s:%d", ctx->sock, - ctx->ip.local_ip, ctx->ip.local_port); - -out: - if(result) { - curlx_safefree(cf); - curlx_safefree(ctx); - } - return result; -} - -bool Curl_conn_is_tcp_listen(struct Curl_easy *data, - int sockindex) -{ - struct Curl_cfilter *cf = data->conn->cfilter[sockindex]; - while(cf) { - if(cf->cft == &Curl_cft_tcp_accept) - return TRUE; - cf = cf->next; - } - return FALSE; -} - -/** - * Return TRUE iff `cf` is a socket filter. - */ -static bool cf_is_socket(struct Curl_cfilter *cf) -{ - return cf && (cf->cft == &Curl_cft_tcp || - cf->cft == &Curl_cft_udp || - cf->cft == &Curl_cft_unix || - cf->cft == &Curl_cft_tcp_accept); -} - -CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *psock, - const struct Curl_sockaddr_ex **paddr, - struct ip_quadruple *pip) -{ - (void)data; - if(cf_is_socket(cf) && cf->ctx) { - struct cf_socket_ctx *ctx = cf->ctx; - - if(psock) - *psock = ctx->sock; - if(paddr) - *paddr = &ctx->addr; - if(pip) - *pip = ctx->ip; - return CURLE_OK; - } - return CURLE_FAILED_INIT; -} diff --git a/vendor/curl/lib/cf-socket.h b/vendor/curl/lib/cf-socket.h deleted file mode 100644 index 40c001cc1..000000000 --- a/vendor/curl/lib/cf-socket.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef HEADER_CURL_CF_SOCKET_H -#define HEADER_CURL_CF_SOCKET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ - -struct Curl_addrinfo; -struct Curl_cfilter; -struct Curl_easy; -struct connectdata; -struct Curl_sockaddr_ex; -struct ip_quadruple; - -/* - * The Curl_sockaddr_ex structure is libcurl's external API curl_sockaddr - * structure with enough space available to directly hold any - * protocol-specific address structures. The variable declared here will be - * used to pass / receive data to/from the fopensocket callback if this has - * been set, before that, it is initialized from parameters. - */ -struct Curl_sockaddr_ex { - int family; - int socktype; - int protocol; - unsigned int addrlen; - union { - struct sockaddr sa; - struct Curl_sockaddr_storage buf; - } addr; -}; -#define curl_sa_addr addr.sa -#define curl_sa_addrbuf addr.buf - -/* - * Parse interface option, and return the interface name and the host part. - */ -CURLcode Curl_parse_interface(const char *input, - char **dev, char **iface, char **host); - -CURLcode Curl_socket_addr_from_ai(struct Curl_sockaddr_ex *addr, - const struct Curl_addrinfo *ai, - uint8_t transport); - -/* - * Create a socket based on info from 'conn' and 'ai'. - * - * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open - * socket callback is set, used that! - * - */ -CURLcode Curl_socket_open(struct Curl_easy *data, - const struct Curl_addrinfo *ai, - struct Curl_sockaddr_ex *addr, - uint8_t transport, - curl_socket_t *sockfd); - -#ifdef USE_SO_NOSIGPIPE -/* Set SO_NOSIGPIPE on socket, return < 0 on error. */ -int Curl_sock_nosigpipe(curl_socket_t sockfd); -#endif - -int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn, - curl_socket_t sock); - -/** - * Creates a cfilter that opens a TCP socket to the given address - * when calling its `connect` implementation. - * The filter will not touch any connection/data flags and can be - * used in happy eyeballing. Once selected for use, its `_active()` - * method needs to be called. - */ -CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport); - -/** - * Creates a cfilter that opens a UDP socket to the given address - * when calling its `connect` implementation. - * The filter will not touch any connection/data flags and can be - * used in happy eyeballing. Once selected for use, its `_active()` - * method needs to be called. - */ -CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport); - -/** - * Creates a cfilter that opens a UNIX socket to the given address - * when calling its `connect` implementation. - * The filter will not touch any connection/data flags and can be - * used in happy eyeballing. Once selected for use, its `_active()` - * method needs to be called. - */ -CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport); - -/** - * Creates a cfilter that keeps a listening socket. - */ -CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - curl_socket_t *s); - -/** - * Return TRUE iff the last filter at `sockindex` was set via - * Curl_conn_tcp_listen_set(). - */ -bool Curl_conn_is_tcp_listen(struct Curl_easy *data, - int sockindex); - -/** - * Peek at the socket and remote ip/port the socket filter is using. - * The filter owns all returned values. - * @param psock pointer to hold socket descriptor or NULL - * @param paddr pointer to hold addr reference or NULL - * @param pip pointer to get IP quadruple or NULL - * Returns error if the filter is of invalid type. - */ -CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *psock, - const struct Curl_sockaddr_ex **paddr, - struct ip_quadruple *pip) WARN_UNUSED_RESULT; - -extern struct Curl_cftype Curl_cft_tcp; -extern struct Curl_cftype Curl_cft_udp; -extern struct Curl_cftype Curl_cft_unix; -extern struct Curl_cftype Curl_cft_tcp_accept; - -#endif /* HEADER_CURL_CF_SOCKET_H */ diff --git a/vendor/curl/lib/cfilters.c b/vendor/curl/lib/cfilters.c deleted file mode 100644 index 6d7d8ef73..000000000 --- a/vendor/curl/lib/cfilters.c +++ /dev/null @@ -1,1214 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "strerror.h" -#include "cfilters.h" -#include "connect.h" -#include "url.h" -#include "curl_trc.h" -#include "progress.h" -#include "select.h" -#include "curlx/strparse.h" - -#ifdef UNITTESTS -/* @unittest 2600 */ -UNITTEST void cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data); -UNITTEST void cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - cf->connected = FALSE; - if(cf->next) - cf->next->cft->do_close(cf->next, data); -} -#endif - -CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - (void)cf; - (void)data; - *done = TRUE; - return CURLE_OK; -} - -CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - /* NOP */ - (void)cf; - (void)data; - (void)ps; - return CURLE_OK; -} - -bool Curl_cf_def_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - return cf->next ? - cf->next->cft->has_data_pending(cf->next, data) : FALSE; -} - -CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - if(cf->next) - return cf->next->cft->do_send(cf->next, data, buf, len, eos, pnwritten); - *pnwritten = 0; - return CURLE_RECV_ERROR; -} - -CURLcode Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread) -{ - if(cf->next) - return cf->next->cft->do_recv(cf->next, data, buf, len, pnread); - *pnread = 0; - return CURLE_SEND_ERROR; -} - -bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending) -{ - return cf->next ? - cf->next->cft->is_alive(cf->next, data, input_pending) : - FALSE; /* pessimistic in absence of data */ -} - -CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - return cf->next ? - cf->next->cft->keep_alive(cf->next, data) : - CURLE_OK; -} - -CURLcode Curl_cf_def_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -#ifdef CURLVERBOSE -static void conn_trc_filters(struct Curl_easy *data, - int sockindex, - const char *info) -{ - if(CURL_TRC_M_is_verbose(data) && data->conn) { - struct Curl_cfilter *cf = data->conn->cfilter[sockindex]; - - if(cf) { - struct dynbuf msg; - CURLcode result = CURLE_OK; - - curlx_dyn_init(&msg, 1024); - result = curlx_dyn_addf(&msg, "%s [%d]", info, sockindex); - for(; cf && !result; cf = cf->next) { - result = curlx_dyn_addf(&msg, "[%s%s]", - cf->connected ? "" : "!", cf->cft->name); - } - if(!result) - CURL_TRC_M(data, "%s", curlx_dyn_ptr(&msg)); - else - CURL_TRC_M(data, "%s [%d] error %d tracing chain", - info, sockindex, result); - curlx_dyn_free(&msg); - } - else - CURL_TRC_M(data, "%s [%d][-]", info, sockindex); - } -} -#endif /* CURLVERBOSE */ - -void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf, - struct Curl_easy *data) -{ - struct Curl_cfilter *cfn, *cf = *pcf; - - if(cf) { - *pcf = NULL; - while(cf) { - cfn = cf->next; - /* prevent destroying filter to mess with its sub-chain, since - * we have the reference now and will call destroy on it. - */ - cf->next = NULL; - cf->cft->destroy(cf, data); - curlx_free(cf); - cf = cfn; - } - } -} - -void Curl_conn_cf_discard_all(struct Curl_easy *data, - struct connectdata *conn, int sockindex) -{ - Curl_conn_cf_discard_chain(&conn->cfilter[sockindex], data); -} - -void Curl_conn_close(struct Curl_easy *data, int sockindex) -{ - struct Curl_cfilter *cf; - - DEBUGASSERT(data->conn); - /* it is valid to call that without filters being present */ - cf = data->conn->cfilter[sockindex]; - if(cf) { - cf->cft->do_close(cf, data); - } - Curl_shutdown_clear(data, sockindex); -} - -CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done) -{ - struct Curl_cfilter *cf; - CURLcode result = CURLE_OK; - timediff_t timeout_ms; - - DEBUGASSERT(data->conn); - - if(!CONN_SOCK_IDX_VALID(sockindex)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* Get the first connected filter that is not shut down already. */ - cf = data->conn->cfilter[sockindex]; - while(cf && (!cf->connected || cf->shutdown)) - cf = cf->next; - - if(!cf) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - if(!Curl_shutdown_started(data, sockindex)) { - Curl_shutdown_start(data, sockindex, 0); - } - else { - timeout_ms = Curl_shutdown_timeleft(data, data->conn, sockindex); - if(timeout_ms < 0) { - /* info message, since this might be regarded as acceptable */ - infof(data, "shutdown timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - - while(cf) { - if(!cf->shutdown) { - bool cfdone = FALSE; - result = cf->cft->do_shutdown(cf, data, &cfdone); - if(result) { - CURL_TRC_CF(data, cf, "shut down failed with %d", result); - return result; - } - else if(!cfdone) { - CURL_TRC_CF(data, cf, "shut down not done yet"); - return CURLE_OK; - } - CURL_TRC_CF(data, cf, "shut down successfully"); - cf->shutdown = TRUE; - } - cf = cf->next; - } - *done = (!result); - return result; -} - -CURLcode Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf, - size_t len, size_t *pnread) -{ - struct Curl_cfilter *cf; - - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - cf = data->conn->cfilter[sockindex]; - while(cf && !cf->connected) - cf = cf->next; - if(cf) - return cf->cft->do_recv(cf, data, buf, len, pnread); - failf(data, "recv: no filter connected"); - DEBUGASSERT(0); - *pnread = 0; - return CURLE_FAILED_INIT; -} - -CURLcode Curl_cf_send(struct Curl_easy *data, int sockindex, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - struct Curl_cfilter *cf; - - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - cf = data->conn->cfilter[sockindex]; - while(cf && !cf->connected) - cf = cf->next; - if(cf) { - return cf->cft->do_send(cf, data, buf, len, eos, pnwritten); - } - failf(data, "send: no filter connected"); - DEBUGASSERT(0); - *pnwritten = 0; - return CURLE_FAILED_INIT; -} - -struct cf_io_ctx { - struct Curl_easy *data; - struct Curl_cfilter *cf; -}; - -static CURLcode cf_bufq_reader(void *writer_ctx, - unsigned char *buf, size_t blen, - size_t *pnread) -{ - struct cf_io_ctx *io = writer_ctx; - return Curl_conn_cf_recv(io->cf, io->data, (char *)buf, blen, pnread); -} - -CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct bufq *bufq, - size_t maxlen, - size_t *pnread) -{ - struct cf_io_ctx io; - - if(!cf || !data) { - *pnread = 0; - return CURLE_BAD_FUNCTION_ARGUMENT; - } - io.data = data; - io.cf = cf; - return Curl_bufq_sipn(bufq, maxlen, cf_bufq_reader, &io, pnread); -} - -static CURLcode cf_bufq_writer(void *writer_ctx, - const uint8_t *buf, size_t buflen, - size_t *pnwritten) -{ - struct cf_io_ctx *io = writer_ctx; - return Curl_conn_cf_send(io->cf, io->data, buf, buflen, FALSE, pnwritten); -} - -CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct bufq *bufq, - const unsigned char *buf, size_t blen, - size_t *pnwritten) -{ - struct cf_io_ctx io; - - if(!cf || !data) { - *pnwritten = 0; - return CURLE_BAD_FUNCTION_ARGUMENT; - } - io.data = data; - io.cf = cf; - if(buf && blen) - return Curl_bufq_write_pass(bufq, buf, blen, cf_bufq_writer, &io, - pnwritten); - else - return Curl_bufq_pass(bufq, cf_bufq_writer, &io, pnwritten); -} - -CURLcode Curl_cf_create(struct Curl_cfilter **pcf, - const struct Curl_cftype *cft, - void *ctx) -{ - struct Curl_cfilter *cf; - CURLcode result = CURLE_OUT_OF_MEMORY; - - DEBUGASSERT(cft); - cf = curlx_calloc(1, sizeof(*cf)); - if(!cf) - goto out; - - cf->cft = cft; - cf->ctx = ctx; - result = CURLE_OK; -out: - *pcf = cf; - return result; -} - -void Curl_conn_cf_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - struct Curl_cfilter *cf) -{ - DEBUGASSERT(conn); - DEBUGASSERT(!cf->conn); - DEBUGASSERT(!cf->next); - - cf->next = conn->cfilter[sockindex]; - cf->conn = conn; - cf->sockindex = sockindex; - conn->cfilter[sockindex] = cf; - CURL_TRC_CF(data, cf, "added"); -} - -void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at, - struct Curl_cfilter *cf_new) -{ - struct Curl_cfilter *tail, **pnext; - - DEBUGASSERT(cf_at); - DEBUGASSERT(cf_new); - DEBUGASSERT(!cf_new->conn); - - tail = cf_at->next; - cf_at->next = cf_new; - do { - cf_new->conn = cf_at->conn; - cf_new->sockindex = cf_at->sockindex; - pnext = &cf_new->next; - cf_new = cf_new->next; - } while(cf_new); - *pnext = tail; -} - -bool Curl_conn_cf_discard(struct Curl_cfilter **pcf, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf = pcf ? *pcf : NULL; - bool found = FALSE; - if(cf) { - if(cf->conn) { - /* unlink if present in connection filter chain */ - struct Curl_cfilter **pprev = &cf->conn->cfilter[cf->sockindex]; - while(*pprev) { - if(*pprev == *pcf) { - *pprev = (*pcf)->next; - cf->next = NULL; - found = TRUE; - break; - } - pprev = &((*pprev)->next); - } - } - Curl_conn_cf_discard_chain(pcf, data); - } - return found; -} - -CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - if(cf) - return cf->cft->do_connect(cf, data, done); - return CURLE_FAILED_INIT; -} - -void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - if(cf) - cf->cft->do_close(cf, data); -} - -CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - if(cf) - return cf->cft->do_send(cf, data, buf, len, eos, pnwritten); - *pnwritten = 0; - return CURLE_SEND_ERROR; -} - -CURLcode Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread) -{ - if(cf) - return cf->cft->do_recv(cf, data, buf, len, pnread); - *pnread = 0; - return CURLE_RECV_ERROR; -} - -#ifdef CURLVERBOSE -static CURLcode cf_verboseconnect(struct Curl_easy *data, - struct Curl_cfilter *cf) -{ - if(Curl_trc_is_verbose(data)) { - struct ip_quadruple ipquad; - bool is_ipv6; - CURLcode result; - - result = Curl_conn_cf_get_ip_info(cf, data, &is_ipv6, &ipquad); - if(result) - return result; - - infof(data, "Established %sconnection to %s (%s port %u) from %s port %u ", - (cf->sockindex == SECONDARYSOCKET) ? "2nd " : "", - CURL_CONN_HOST_DISPNAME(data->conn), - ipquad.remote_ip, ipquad.remote_port, - ipquad.local_ip, ipquad.local_port); - } - return CURLE_OK; -} -#endif - -static CURLcode cf_cntrl_all(struct connectdata *conn, - struct Curl_easy *data, - bool ignore_result, - int event, int arg1, void *arg2) -{ - CURLcode result = CURLE_OK; - size_t i; - - for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) { - result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result, - event, arg1, arg2); - if(!ignore_result && result) - break; - } - return result; -} - -static void cf_cntrl_update_info(struct Curl_easy *data, - struct connectdata *conn) -{ - cf_cntrl_all(conn, data, TRUE, CF_CTRL_CONN_INFO_UPDATE, 0, NULL); -} - -/** - * Update connection statistics - */ -static void conn_report_connect_stats(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - if(cf) { - struct curltime connected; - struct curltime appconnected; - - memset(&connected, 0, sizeof(connected)); - cf->cft->query(cf, data, CF_QUERY_TIMER_CONNECT, NULL, &connected); - if(connected.tv_sec || connected.tv_usec) - Curl_pgrsTimeWas(data, TIMER_CONNECT, connected); - - memset(&appconnected, 0, sizeof(appconnected)); - cf->cft->query(cf, data, CF_QUERY_TIMER_APPCONNECT, NULL, &appconnected); - if(appconnected.tv_sec || appconnected.tv_usec) - Curl_pgrsTimeWas(data, TIMER_APPCONNECT, appconnected); - } -} - -static void conn_remove_setup_filters(struct Curl_easy *data, - int sockindex) -{ - struct Curl_cfilter **anchor = &data->conn->cfilter[sockindex]; - while(*anchor) { - struct Curl_cfilter *cf = *anchor; - if(cf->connected && (cf->cft->flags & CF_TYPE_SETUP)) { - *anchor = cf->next; - cf->next = NULL; - CURL_TRC_CF(data, cf, "removing connected setup filter"); - cf->cft->destroy(cf, data); - curlx_free(cf); - } - else - anchor = &cf->next; - } -} - -CURLcode Curl_conn_connect(struct Curl_easy *data, - int sockindex, - bool blocking, - bool *done) -{ -#define CF_CONN_NUM_POLLS_ON_STACK 5 - struct pollfd a_few_on_stack[CF_CONN_NUM_POLLS_ON_STACK]; - struct easy_pollset ps; - struct curl_pollfds cpfds; - struct Curl_cfilter *cf; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - if(!CONN_SOCK_IDX_VALID(sockindex)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(data->conn->scheme->flags & PROTOPT_NONETWORK) { - *done = TRUE; - return CURLE_OK; - } - - cf = data->conn->cfilter[sockindex]; - if(!cf) { - *done = FALSE; - return CURLE_FAILED_INIT; - } - - *done = (bool)cf->connected; - if(*done) - return CURLE_OK; - - Curl_pollset_init(&ps); - Curl_pollfds_init(&cpfds, a_few_on_stack, CF_CONN_NUM_POLLS_ON_STACK); - while(!*done) { - if(Curl_conn_needs_flush(data, sockindex)) { - DEBUGF(infof(data, "Curl_conn_connect(index=%d), flush", sockindex)); - result = Curl_conn_flush(data, sockindex); - if(result && (result != CURLE_AGAIN)) - return result; - } - - result = cf->cft->do_connect(cf, data, done); - CURL_TRC_CF(data, cf, "Curl_conn_connect(block=%d) -> %d, done=%d", - blocking, result, *done); - if(!result && *done) { - /* Now that the complete filter chain is connected, let all filters - * persist information at the connection. E.g. cf-socket sets the - * socket and ip related information. */ - cf_cntrl_update_info(data, data->conn); - conn_report_connect_stats(cf, data); - data->conn->keepalive = *Curl_pgrs_now(data); - VERBOSE(result = cf_verboseconnect(data, cf)); - VERBOSE(conn_trc_filters(data, sockindex, "connected")); - conn_remove_setup_filters(data, sockindex); - VERBOSE(conn_trc_filters(data, sockindex, "reduced to")); - goto out; - } - else if(result) { - CURL_TRC_CF(data, cf, "Curl_conn_connect(), filter returned %d", result); - VERBOSE(conn_trc_filters(data, sockindex, "failed to connect")); - conn_report_connect_stats(cf, data); - goto out; - } - - if(!blocking) - goto out; - else { - /* check allowed time left */ - const timediff_t timeout_ms = Curl_timeleft_ms(data); - curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); - int rc; - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "connect timeout"); - result = CURLE_OPERATION_TIMEDOUT; - goto out; - } - - CURL_TRC_CF(data, cf, "Curl_conn_connect(block=1), do poll"); - Curl_pollset_reset(&ps); - Curl_pollfds_reset(&cpfds); - /* In general, we want to send after connect, wait on that. */ - if(sockfd != CURL_SOCKET_BAD) - result = Curl_pollset_set_out_only(data, &ps, sockfd); - if(!result) - result = Curl_conn_adjust_pollset(data, data->conn, &ps); - if(result) - goto out; - result = Curl_pollfds_add_ps(&cpfds, &ps); - if(result) - goto out; - - rc = Curl_poll(cpfds.pfds, cpfds.n, - CURLMIN(timeout_ms, (cpfds.n ? 1000 : 10))); - CURL_TRC_CF(data, cf, "Curl_conn_connect(block=1), Curl_poll() -> %d", - rc); - if(rc < 0) { - result = CURLE_COULDNT_CONNECT; - goto out; - } - /* continue iterating */ - } - } - -out: - Curl_pollset_cleanup(&ps); - Curl_pollfds_cleanup(&cpfds); - return result; -} - -bool Curl_conn_is_setup(struct connectdata *conn, int sockindex) -{ - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - return (conn->cfilter[sockindex] != NULL); -} - -bool Curl_conn_is_connected(struct connectdata *conn, int sockindex) -{ - struct Curl_cfilter *cf; - - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - cf = conn->cfilter[sockindex]; - if(cf) - return (bool)cf->connected; - else if(conn->scheme->flags & PROTOPT_NONETWORK) - return TRUE; - return FALSE; -} - -bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex) -{ - struct Curl_cfilter *cf; - - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - cf = data->conn->cfilter[sockindex]; - while(cf) { - if(cf->connected) - return TRUE; - if(cf->cft->flags & CF_TYPE_IP_CONNECT) - return FALSE; - cf = cf->next; - } - return FALSE; -} - -static bool cf_is_ssl(struct Curl_cfilter *cf) -{ - for(; cf; cf = cf->next) { - if(cf->cft->flags & CF_TYPE_SSL) - return TRUE; - if(cf->cft->flags & CF_TYPE_IP_CONNECT) - return FALSE; - } - return FALSE; -} - -bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex) -{ - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - return conn ? cf_is_ssl(conn->cfilter[sockindex]) : FALSE; -} - -bool Curl_conn_get_ssl_info(struct Curl_easy *data, - struct connectdata *conn, int sockindex, - int query, - struct curl_tlssessioninfo *info) -{ - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - if(Curl_conn_is_ssl(conn, sockindex)) { - struct Curl_cfilter *cf = conn->cfilter[sockindex]; - CURLcode result = cf ? - cf->cft->query(cf, data, query, NULL, (void *)info) : - CURLE_UNKNOWN_OPTION; - return !result; - } - return FALSE; -} - -CURLcode Curl_conn_get_ip_info(struct Curl_easy *data, - struct connectdata *conn, int sockindex, - bool *is_ipv6, struct ip_quadruple *ipquad) -{ - struct Curl_cfilter *cf; - if(!CONN_SOCK_IDX_VALID(sockindex)) - return CURLE_BAD_FUNCTION_ARGUMENT; - cf = conn ? conn->cfilter[sockindex] : NULL; - return Curl_conn_cf_get_ip_info(cf, data, is_ipv6, ipquad); -} - -bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex) -{ - struct Curl_cfilter *cf; - - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - cf = conn ? conn->cfilter[sockindex] : NULL; - - for(; cf; cf = cf->next) { - if(cf->cft->flags & CF_TYPE_MULTIPLEX) - return TRUE; - if(cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_SSL)) - return FALSE; - } - return FALSE; -} - -unsigned char Curl_conn_get_transport(struct Curl_easy *data, - struct connectdata *conn) -{ - struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET]; - return Curl_conn_cf_get_transport(cf, data); -} - -int Curl_socktype_for_transport(uint8_t transport) -{ - switch(transport) { - case TRNSPRT_TCP: - return SOCK_STREAM; - case TRNSPRT_UNIX: - return SOCK_STREAM; - default: /* UDP and QUIC */ - return SOCK_DGRAM; - } -} - -int Curl_protocol_for_transport(uint8_t transport) -{ - switch(transport) { - case TRNSPRT_TCP: - return IPPROTO_TCP; - case TRNSPRT_UNIX: - return IPPROTO_IP; - default: /* UDP and QUIC */ - return IPPROTO_UDP; - } -} - -bool Curl_conn_cf_wants_httpsrr(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - (void)data; - for(; cf; cf = cf->next) { - if(cf->cft->flags & CF_TYPE_HTTPSRR) - return TRUE; - } - return FALSE; -} - -const char *Curl_conn_get_alpn_negotiated(struct Curl_easy *data, - struct connectdata *conn) -{ - struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET]; - return Curl_conn_cf_get_alpn_negotiated(cf, data); -} - -unsigned char Curl_conn_http_version(struct Curl_easy *data, - struct connectdata *conn) -{ - struct Curl_cfilter *cf; - CURLcode result = CURLE_UNKNOWN_OPTION; - unsigned char v = 0; - - cf = conn->cfilter[FIRSTSOCKET]; - for(; cf; cf = cf->next) { - if(cf->cft->flags & CF_TYPE_HTTP) { - int value = 0; - result = cf->cft->query(cf, data, CF_QUERY_HTTP_VERSION, &value, NULL); - if(!result && ((value < 0) || (value > 255))) - result = CURLE_FAILED_INIT; - else - v = (unsigned char)value; - break; - } - if(cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_SSL)) - break; - } - return (unsigned char)(result ? 0 : v); -} - -bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex) -{ - struct Curl_cfilter *cf; - - (void)data; - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - - cf = data->conn->cfilter[sockindex]; - while(cf && !cf->connected) { - cf = cf->next; - } - if(cf) { - return cf->cft->has_data_pending(cf, data); - } - return FALSE; -} - -bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURLcode result; - int pending = 0; - result = cf ? cf->cft->query(cf, data, CF_QUERY_NEED_FLUSH, - &pending, NULL) : CURLE_UNKNOWN_OPTION; - return (result || !pending) ? FALSE : TRUE; -} - -bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex) -{ - if(!CONN_SOCK_IDX_VALID(sockindex)) - return FALSE; - return Curl_conn_cf_needs_flush(data->conn->cfilter[sockindex], data); -} - -CURLcode Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - CURLcode result = CURLE_OK; - /* Get the lowest not-connected filter, if there are any */ - while(cf && !cf->connected && cf->next && !cf->next->connected) - cf = cf->next; - /* Skip all filters that have already shut down */ - while(cf && cf->shutdown) - cf = cf->next; - /* From there on, give all filters a chance to adjust the pollset. - * Lower filters are called later, so they may override */ - while(cf && !result) { - result = cf->cft->adjust_pollset(cf, data, ps); - cf = cf->next; - } - return result; -} - -CURLcode Curl_conn_adjust_pollset(struct Curl_easy *data, - struct connectdata *conn, - struct easy_pollset *ps) -{ - CURLcode result = CURLE_OK; - int i; - - DEBUGASSERT(data); - DEBUGASSERT(conn); - for(i = 0; (i < 2) && !result; ++i) { - result = Curl_conn_cf_adjust_pollset(conn->cfilter[i], data, ps); - } - return result; -} - -/* - * Return values: - * -1 = error - * 0 = timeout - * N = number of structures with non zero revent fields - */ -int Curl_conn_cf_poll(struct Curl_cfilter *cf, - struct Curl_easy *data, - timediff_t timeout_ms) -{ - struct easy_pollset ps; - int rc; - CURLcode result; - - DEBUGASSERT(cf); - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - Curl_pollset_init(&ps); - - result = Curl_conn_cf_adjust_pollset(cf, data, &ps); - if(!result) - rc = Curl_pollset_poll(data, &ps, timeout_ms); - else - rc = -1; - Curl_pollset_cleanup(&ps); - return rc; -} - -void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex, - const char **phost, int *pport) -{ - struct Curl_cfilter *cf, *cf_proxy = NULL; - int portarg = -1; - - if(!data->conn) { - DEBUGASSERT(0); - *phost = ""; - if(pport) - *pport = -1; - return; - } - - cf = CONN_SOCK_IDX_VALID(sockindex) ? data->conn->cfilter[sockindex] : NULL; - /* Find the "lowest" tunneling proxy filter that has not connected yet. */ - while(cf && !cf->connected) { - if((cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_PROXY)) == - (CF_TYPE_IP_CONNECT | CF_TYPE_PROXY)) - cf_proxy = cf; - cf = cf->next; - } - /* cf_proxy (!= NULL) is not connected yet. It is talking - * to an interim host and any authentication or other things apply - * to this interim host and port. */ - if(!cf_proxy || cf_proxy->cft->query(cf_proxy, data, CF_QUERY_HOST_PORT, - &portarg, CURL_UNCONST(phost))) { - /* Everything connected or query unsuccessful, the overall - * connection's destination is the answer */ - *phost = data->conn->host.name; - portarg = data->conn->remote_port; - } - if(pport) - *pport = portarg; -} - -CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - (void)cf; - (void)data; - (void)event; - (void)arg1; - (void)arg2; - return CURLE_OK; -} - -CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool ignore_result, - int event, int arg1, void *arg2) -{ - CURLcode result = CURLE_OK; - - for(; cf; cf = cf->next) { - if(cf->cft->cntrl == Curl_cf_def_cntrl) - continue; - result = cf->cft->cntrl(cf, data, event, arg1, arg2); - if(!ignore_result && result) - break; - } - return result; -} - -curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - curl_socket_t sock; - if(cf && !cf->cft->query(cf, data, CF_QUERY_SOCKET, NULL, &sock)) - return sock; - return CURL_SOCKET_BAD; -} - -unsigned char Curl_conn_cf_get_transport(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - int transport = 0; - if(cf && !cf->cft->query(cf, data, CF_QUERY_TRANSPORT, &transport, NULL)) - return (unsigned char)transport; - return (unsigned char)(data->conn ? data->conn->transport_wanted : 0); -} - -const char *Curl_conn_cf_get_alpn_negotiated(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - const char *alpn = NULL; - CURL_TRC_CF(data, cf, "query ALPN"); - if(cf && !cf->cft->query(cf, data, CF_QUERY_ALPN_NEGOTIATED, NULL, - CURL_UNCONST(&alpn))) - return alpn; - return NULL; -} - -static const struct Curl_sockaddr_ex * -cf_get_remote_addr(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - const struct Curl_sockaddr_ex *remote_addr = NULL; - if(cf && - !cf->cft->query(cf, data, CF_QUERY_REMOTE_ADDR, NULL, - CURL_UNCONST(&remote_addr))) - return remote_addr; - return NULL; -} - -CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *is_ipv6, struct ip_quadruple *ipquad) -{ - CURLcode result = CURLE_UNKNOWN_OPTION; - if(cf) { - int ipv6 = 0; - result = cf->cft->query(cf, data, CF_QUERY_IP_INFO, &ipv6, ipquad); - *is_ipv6 = !!ipv6; - } - return result; -} - -curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data) -{ - struct Curl_cfilter *cf; - - if(!data->conn) - return CURL_SOCKET_BAD; - - cf = data->conn->cfilter[FIRSTSOCKET]; - /* if the top filter has not connected, ask it (and its sub-filters) - * for the socket. Otherwise conn->sock[sockindex] should have it. */ - if(cf && !cf->connected) - return Curl_conn_cf_get_socket(cf, data); - return data->conn->sock[FIRSTSOCKET]; -} - -const struct Curl_sockaddr_ex * -Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex) -{ - struct Curl_cfilter *cf = - (data->conn && CONN_SOCK_IDX_VALID(sockindex)) ? - data->conn->cfilter[sockindex] : NULL; - return cf ? cf_get_remote_addr(cf, data) : NULL; -} - -CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data) -{ - return cf_cntrl_all(data->conn, data, FALSE, CF_CTRL_DATA_SETUP, 0, NULL); -} - -CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex) -{ - if(!CONN_SOCK_IDX_VALID(sockindex)) - return CURLE_BAD_FUNCTION_ARGUMENT; - return Curl_conn_cf_cntrl(data->conn->cfilter[sockindex], data, FALSE, - CF_CTRL_FLUSH, 0, NULL); -} - -/** - * Notify connection filters that the transfer represented by `data` - * is done with sending data (e.g. has uploaded everything). - */ -void Curl_conn_ev_data_done_send(struct Curl_easy *data) -{ - cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE_SEND, 0, NULL); -} - -/** - * Notify connection filters that the transfer represented by `data` - * is finished - eventually premature, e.g. before being complete. - */ -void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature) -{ - cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE, premature, NULL); -} - -CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause) -{ - return cf_cntrl_all(data->conn, data, FALSE, - CF_CTRL_DATA_PAUSE, do_pause, NULL); -} - -bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn, - bool *input_pending) -{ - struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET]; - return cf && !cf->conn->bits.close && - cf->cft->is_alive(cf, data, input_pending); -} - -CURLcode Curl_conn_keep_alive(struct Curl_easy *data, - struct connectdata *conn, - int sockindex) -{ - struct Curl_cfilter *cf; - - if(!CONN_SOCK_IDX_VALID(sockindex)) - return CURLE_BAD_FUNCTION_ARGUMENT; - cf = conn->cfilter[sockindex]; - return cf ? cf->cft->keep_alive(cf, data) : CURLE_OK; -} - -size_t Curl_conn_get_max_concurrent(struct Curl_easy *data, - struct connectdata *conn, - int sockindex) -{ - struct Curl_cfilter *cf; - CURLcode result; - int n = -1; - - if(!CONN_SOCK_IDX_VALID(sockindex)) - return 0; - - cf = conn->cfilter[sockindex]; - result = cf ? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT, - &n, NULL) : CURLE_UNKNOWN_OPTION; - /* If no filter answered the query, the default is a non-multiplexed - * connection with limit 1. Otherwise, the query may return 0 - * for connections that are in shutdown, e.g. server HTTP/2 GOAWAY. */ - return (result || n < 0) ? 1 : (size_t)n; -} - -int Curl_conn_get_stream_error(struct Curl_easy *data, - struct connectdata *conn, - int sockindex) -{ - struct Curl_cfilter *cf; - CURLcode result; - int n = 0; - - if(!CONN_SOCK_IDX_VALID(sockindex)) - return 0; - - cf = conn->cfilter[sockindex]; - result = cf ? cf->cft->query(cf, data, CF_QUERY_STREAM_ERROR, - &n, NULL) : CURLE_UNKNOWN_OPTION; - return (result || n < 0) ? 0 : n; -} - -int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd) -{ - if(data && data->conn && - sockfd != CURL_SOCKET_BAD && sockfd == data->conn->sock[SECONDARYSOCKET]) - return SECONDARYSOCKET; - return FIRSTSOCKET; -} - -CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex, - char *buf, size_t len, size_t *pnread) -{ - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - if(!CONN_SOCK_IDX_VALID(sockindex)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(data && data->conn && data->conn->recv[sockindex]) - return data->conn->recv[sockindex](data, sockindex, buf, len, pnread); - *pnread = 0; - return CURLE_FAILED_INIT; -} - -CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t len, bool eos, - size_t *pnwritten) -{ - size_t write_len = len; - - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - DEBUGASSERT(CONN_SOCK_IDX_VALID(sockindex)); - if(!CONN_SOCK_IDX_VALID(sockindex)) - return CURLE_BAD_FUNCTION_ARGUMENT; -#ifdef DEBUGBUILD - if(write_len) { - /* Allow debug builds to override this logic to force short sends */ - const char *p = getenv("CURL_SMALLSENDS"); - if(p) { - curl_off_t altsize; - if(!curlx_str_number(&p, &altsize, write_len)) { - write_len = (size_t)altsize; - if(write_len != len) - eos = FALSE; - } - } - } -#endif - if(data && data->conn && data->conn->send[sockindex]) - return data->conn->send[sockindex](data, sockindex, buf, write_len, eos, - pnwritten); - *pnwritten = 0; - return CURLE_FAILED_INIT; -} diff --git a/vendor/curl/lib/cfilters.h b/vendor/curl/lib/cfilters.h deleted file mode 100644 index ac56737cc..000000000 --- a/vendor/curl/lib/cfilters.h +++ /dev/null @@ -1,696 +0,0 @@ -#ifndef HEADER_CURL_CFILTERS_H -#define HEADER_CURL_CFILTERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/timediff.h" - -struct bufq; -struct Curl_cfilter; -struct Curl_easy; -struct Curl_dns_entry; -struct connectdata; -struct ip_quadruple; -struct curl_tlssessioninfo; - -/* Callback to destroy resources held by this filter instance. - * Implementations MUST NOT chain calls to cf->next. - */ -typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/* Callback to close the connection immediately. */ -typedef void Curl_cft_close(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/* Callback to close the connection filter gracefully, non-blocking. - * Implementations MUST NOT chain calls to cf->next. - */ -typedef CURLcode Curl_cft_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done); - -typedef CURLcode Curl_cft_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done); - -struct easy_pollset; - -/* Passing in an easy_pollset for monitoring of sockets, let - * filters add or remove sockets actions (CURL_POLL_OUT, CURL_POLL_IN). - * This may add a socket or, in case no actions remain, remove - * a socket from the set. - * - * Filter implementations need to call filters "below" *after* they have - * made their adjustments. This allows lower filters to override "upper" - * actions. If a "lower" filter is unable to write, it needs to be able - * to disallow POLL_OUT. - * - * A filter without own restrictions/preferences should not modify - * the pollset. Filters, whose filter "below" is not connected, should - * also do no adjustments. - * - * Examples: a TLS handshake, while ongoing, might remove POLL_IN when it - * needs to write, or vice versa. An HTTP/2 filter might remove POLL_OUT when - * a stream window is exhausted and a WINDOW_UPDATE needs to be received first - * and add instead POLL_IN. - * - * @param cf the filter to ask - * @param data the easy handle the pollset is about - * @param ps the pollset (inout) for the easy handle - */ -typedef CURLcode Curl_cft_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps); - -typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data); - -typedef CURLcode Curl_cft_send(struct Curl_cfilter *cf, - struct Curl_easy *data, /* transfer */ - const uint8_t *buf, /* data to write */ - size_t len, /* amount to write */ - bool eos, /* last chunk */ - size_t *pnwritten); /* how much sent */ - -typedef CURLcode Curl_cft_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, /* transfer */ - char *buf, /* store data here */ - size_t len, /* amount to read */ - size_t *pnread); /* how much received */ - -typedef bool Curl_cft_conn_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending); - -typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/** - * Events/controls for connection filters, their arguments and - * return code handling. Filter callbacks are invoked "top down". - * Return code handling: - * "first fail" meaning that the first filter returning != CURLE_OK, will - * abort further event distribution and determine the result. - * "ignored" meaning return values are ignored and the event is distributed - * to all filters in the chain. Overall result is always CURLE_OK. - */ -/* data event arg1 arg2 return */ -#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */ -/* unused now 5 */ -#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */ -#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */ -#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */ -/* update conn info at connection and data */ -#define CF_CTRL_CONN_INFO_UPDATE (256 + 0) /* 0 NULL ignored */ -#define CF_CTRL_FORGET_SOCKET (256 + 1) /* 0 NULL ignored */ -#define CF_CTRL_FLUSH (256 + 2) /* 0 NULL first fail */ - -/** - * Handle event/control for the filter. - * Implementations MUST NOT chain calls to cf->next. - */ -typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2); - -/** - * Queries to ask via a `Curl_cft_query *query` method on a cfilter chain. - * - MAX_CONCURRENT: the maximum number of parallel transfers the filter - * chain expects to handle at the same time. - * default: 1 if no filter overrides. - * - CONNECT_REPLY_MS: milliseconds until the first indication of a server - * response was received on a connect. For TCP, this - * reflects the time until the socket connected. On UDP - * this gives the time the first bytes from the server - * were received. - * -1 if not determined yet. - * - CF_QUERY_SOCKET: the socket used by the filter chain - * - CF_QUERY_NEED_FLUSH: TRUE iff any of the filters have unsent data - * - CF_QUERY_IP_INFO: res1 says if connection used IPv6, res2 is the - * ip quadruple - * - CF_QUERY_HOST_PORT: the remote hostname and port a filter talks to - * - CF_QUERY_SSL_INFO: fill out the passed curl_tlssessioninfo with the - * internal from the SSL secured connection when - * available. - * - CF_QUERY_SSL_CTX_INFO: same as CF_QUERY_SSL_INFO, but give the SSL_CTX - * when available, or the same internal pointer - * when the TLS stack does not differentiate. - * - CF_QUERY_ALPN_NEGOTIATED: The ALPN selected by the server as - null-terminated string or NULL if none - selected/handshake not done. Implemented by filter - types CF_TYPE_SSL or CF_TYPE_IP_CONNECT. - */ -/* query res1 res2 */ -#define CF_QUERY_MAX_CONCURRENT 1 /* number - */ -#define CF_QUERY_CONNECT_REPLY_MS 2 /* number - */ -#define CF_QUERY_SOCKET 3 /* - curl_socket_t */ -#define CF_QUERY_TIMER_CONNECT 4 /* - struct curltime */ -#define CF_QUERY_TIMER_APPCONNECT 5 /* - struct curltime */ -#define CF_QUERY_STREAM_ERROR 6 /* error code - */ -#define CF_QUERY_NEED_FLUSH 7 /* TRUE/FALSE - */ -#define CF_QUERY_IP_INFO 8 /* TRUE/FALSE struct ip_quadruple */ -#define CF_QUERY_HTTP_VERSION 9 /* number (10/11/20/30) - */ -/* pass in a `const struct Curl_sockaddr_ex **` as `pres2`. Gets set - * to NULL when not connected. */ -#define CF_QUERY_REMOTE_ADDR 10 /* - `Curl_sockaddr_ex *` */ -#define CF_QUERY_HOST_PORT 11 /* port const char * */ -#define CF_QUERY_SSL_INFO 12 /* - struct curl_tlssessioninfo * */ -#define CF_QUERY_SSL_CTX_INFO 13 /* - struct curl_tlssessioninfo * */ -#define CF_QUERY_TRANSPORT 14 /* TRNSPRT_* - * */ -#define CF_QUERY_ALPN_NEGOTIATED 15 /* - const char * */ - -/** - * Query the cfilter for properties. Filters ignorant of a query will - * pass it "down" the filter chain. - */ -typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2); - -/** - * Type flags for connection filters. A filter can have none, one or - * many of those. Use to evaluate state/capabilities of a filter chain. - * - * CF_TYPE_IP_CONNECT: provides an IP connection or sth equivalent, like - * a CONNECT tunnel, a UNIX domain socket, a QUIC - * connection, etc. - * CF_TYPE_SSL: provide SSL/TLS - * CF_TYPE_MULTIPLEX: provides multiplexing of easy handles - * CF_TYPE_PROXY provides proxying - * CF_TYPE_HTTP implement a version of the HTTP protocol - * CF_TYPE_SETUP filter is only needed for connection setup and - * can be removed once connected - * CF_TYPE_HTTPSRR filter that wants HTTPS-RR information - */ -#define CF_TYPE_IP_CONNECT (1 << 0) -#define CF_TYPE_SSL (1 << 1) -#define CF_TYPE_MULTIPLEX (1 << 2) -#define CF_TYPE_PROXY (1 << 3) -#define CF_TYPE_HTTP (1 << 4) -#define CF_TYPE_SETUP (1 << 5) -#define CF_TYPE_HTTPSRR (1 << 6) - -/* A connection filter type, e.g. specific implementation. */ -struct Curl_cftype { - const char *name; /* name of the filter type */ - int flags; /* flags of filter type */ - int log_level; /* log level for such filters */ - Curl_cft_destroy_this *destroy; /* destroy resources of this cf */ - Curl_cft_connect *do_connect; /* establish connection */ - Curl_cft_close *do_close; /* close conn */ - Curl_cft_shutdown *do_shutdown; /* shutdown conn */ - Curl_cft_adjust_pollset *adjust_pollset; /* adjust transfer poll set */ - Curl_cft_data_pending *has_data_pending; /* conn has data pending */ - Curl_cft_send *do_send; /* send data */ - Curl_cft_recv *do_recv; /* receive data */ - Curl_cft_cntrl *cntrl; /* events/control */ - Curl_cft_conn_is_alive *is_alive; /* FALSE if conn is dead, Jim! */ - Curl_cft_conn_keep_alive *keep_alive; /* try to keep it alive */ - Curl_cft_query *query; /* query filter chain */ -}; - -/* A connection filter instance, e.g. registered at a connection */ -struct Curl_cfilter { - const struct Curl_cftype *cft; /* the type providing implementation */ - struct Curl_cfilter *next; /* next filter in chain */ - void *ctx; /* filter type specific settings */ - struct connectdata *conn; /* the connection this filter belongs to */ - int sockindex; /* the index the filter is installed at */ - BIT(connected); /* != 0 iff this filter is connected */ - BIT(shutdown); /* != 0 iff this filter has shut down */ -}; - -/* Default implementations for the type functions, implementing nop. */ -void Curl_cf_def_destroy_this(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/* Default implementations for the type functions, implementing pass-through - * the filter chain. */ -CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps); -bool Curl_cf_def_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data); -CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten); -CURLcode Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread); -CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2); -bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending); -CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf, - struct Curl_easy *data); -CURLcode Curl_cf_def_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2); -CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done); - -/** - * Create a new filter instance, unattached to the filter chain. - * Use Curl_conn_cf_add() to add it to the chain. - * @param pcf on success holds the created instance - * @param cft the filter type - * @param ctx the type specific context to use - */ -CURLcode Curl_cf_create(struct Curl_cfilter **pcf, - const struct Curl_cftype *cft, - void *ctx); - -/** - * Add a filter instance to the `sockindex` filter chain at connection - * `conn`. The filter must not already be attached. It is inserted at - * the start of the chain (top). - */ -void Curl_conn_cf_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - struct Curl_cfilter *cf); - -/** - * Insert a filter (chain) after `cf_at`. - * `cf_new` must not already be attached. - */ -void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at, - struct Curl_cfilter *cf_new); - -/** - * Extract filter `*pcf` from its connection filter chain. - * Destroy `*pcf`, even if it was not part of the chain and NULL it. - * Returns TRUE of cf has been part of chain. - */ -bool Curl_conn_cf_discard(struct Curl_cfilter **pcf, - struct Curl_easy *data); - -/** - * Discard all cfilters starting with `*pcf` and clearing it afterwards. - */ -void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf, - struct Curl_easy *data); - -/** - * Remove and destroy all filters at chain `sockindex` on connection `conn`. - */ -void Curl_conn_cf_discard_all(struct Curl_easy *data, - struct connectdata *conn, int sockindex); - -CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done); -void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data); -CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten); -CURLcode Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread); -CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool ignore_result, - int event, int arg1, void *arg2); - -/** - * Get the socket used by the filter chain starting at `cf`. - * Returns CURL_SOCKET_BAD if not available. - */ -curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf, - struct Curl_easy *data); - -CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *is_ipv6, struct ip_quadruple *ipquad); - -bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf, - struct Curl_easy *data); - -unsigned char Curl_conn_cf_get_transport(struct Curl_cfilter *cf, - struct Curl_easy *data); - -int Curl_socktype_for_transport(uint8_t transport); -int Curl_protocol_for_transport(uint8_t transport); - -const char *Curl_conn_cf_get_alpn_negotiated(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/* The filter (or one of its sub-filters) wants HTTPS-RR information. */ -bool Curl_conn_cf_wants_httpsrr(struct Curl_cfilter *cf, - struct Curl_easy *data); - -#define CURL_CF_SSL_DEFAULT (-1) -#define CURL_CF_SSL_DISABLE 0 -#define CURL_CF_SSL_ENABLE 1 - -/** - * Bring the filter chain at `sockindex` for connection `data->conn` into - * connected state. Which will set `*done` to TRUE. - * This can be called on an already connected chain with no side effects. - * When not `blocking`, calls may return without error and `*done != TRUE`, - * while the individual filters negotiated the connection. - */ -CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex, - bool blocking, bool *done); - -/** - * Check if a filter chain at `sockindex` for connection `conn` exists. - */ -bool Curl_conn_is_setup(struct connectdata *conn, int sockindex); - -/** - * Check if the filter chain at `sockindex` for connection `conn` is - * completely connected. - */ -bool Curl_conn_is_connected(struct connectdata *conn, int sockindex); - -/** - * Determine if we have reached the remote host on IP level, e.g. - * have a TCP connection. This turns TRUE before a possible SSL - * handshake has been started/done. - */ -bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex); - -/** - * Determine if the connection is using SSL to the remote host - * (or will be once connected). This will return FALSE, if SSL - * is only used in proxying and not for the tunnel itself. - */ -bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex); - -/* - * Fill `info` with information about the TLS instance securing the connection - * when available, otherwise e.g. when Curl_conn_is_ssl() is FALSE, return - * FALSE. 'query' should be CF_QUERY_SSL_INFO or CF_QUERY_SSL_CTX_INFO. - */ -bool Curl_conn_get_ssl_info(struct Curl_easy *data, - struct connectdata *conn, int sockindex, - int query, - struct curl_tlssessioninfo *info); - -CURLcode Curl_conn_get_ip_info(struct Curl_easy *data, - struct connectdata *conn, int sockindex, - bool *is_ipv6, struct ip_quadruple *ipquad); - -/** - * Connection provides multiplexing of easy handles at `socketindex`. - */ -bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex); - -/** - * Return the HTTP version used on the FIRSTSOCKET connection filters - * or 0 if unknown. Value otherwise is 09, 10, 11, etc. - */ -unsigned char Curl_conn_http_version(struct Curl_easy *data, - struct connectdata *conn); - -/* Get the TRNSPRT_* the connection is using */ -unsigned char Curl_conn_get_transport(struct Curl_easy *data, - struct connectdata *conn); - -/* Get the negotiated ALPN protocol or NULL if none in play */ -const char *Curl_conn_get_alpn_negotiated(struct Curl_easy *data, - struct connectdata *conn); - -/** - * Close the filter chain at `sockindex` for connection `data->conn`. - * Filters remain in place and may be connected again afterwards. - */ -void Curl_conn_close(struct Curl_easy *data, int sockindex); - -/** - * Shutdown the connection at `sockindex` non-blocking, using timeout - * from `data->set.shutdowntimeout`, default DEFAULT_SHUTDOWN_TIMEOUT_MS. - * Return CURLE_OK and *done == FALSE if not finished. - */ -CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done); - -/** - * Return if data is pending in some connection filter at chain - * `sockindex` for connection `data->conn`. - */ -bool Curl_conn_data_pending(struct Curl_easy *data, - int sockindex); - -/** - * Return TRUE if any of the connection filters at chain `sockindex` - * have data still to send. - */ -bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex); - -/** - * Flush any pending data on the connection filters at chain `sockindex`. - */ -CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex); - -/** - * Return the socket used on data's connection for FIRSTSOCKET, - * querying filters if the whole chain has not connected yet. - * Returns CURL_SOCKET_BAD if not available. - */ -curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data); - -/* Return a pointer to the connected socket address or NULL. */ -const struct Curl_sockaddr_ex * -Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex); - -/** - * Tell filters to forget about the socket at sockindex. - */ -void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex); - -/** - * Adjust the pollset for the filter chain starting at `cf`. - */ -CURLcode Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps); - -/** - * Adjust pollset from filters installed at transfer's connection. - */ -CURLcode Curl_conn_adjust_pollset(struct Curl_easy *data, - struct connectdata *conn, - struct easy_pollset *ps); - -/** - * Curl_poll() the filter chain at `cf` with timeout `timeout_ms`. - * Returns 0 on timeout, negative on error or number of sockets - * with requested poll events. - */ -int Curl_conn_cf_poll(struct Curl_cfilter *cf, - struct Curl_easy *data, - timediff_t timeout_ms); - -/** - * Receive data through the filter chain at `sockindex` for connection - * `data->conn`. Copy at most `len` bytes into `buf`. Return the - * actual number of bytes copied in `*pnread`or an error. - */ -CURLcode Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf, - size_t len, size_t *pnread); - -/** - * Send `len` bytes of data from `buf` through the filter chain `sockindex` - * at connection `data->conn`. Return the actual number of bytes written - * in `*pnwritten` or on error. - */ -CURLcode Curl_cf_send(struct Curl_easy *data, int sockindex, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten); - -/** - * Receive bytes from connection filter `cf` into `bufq`. - * Convenience wrapper around `Curl_bufq_sipn()`, - * so users do not have to implement a callback. - */ -CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct bufq *bufq, - size_t maxlen, - size_t *pnread); - -/** - * Send bytes in `bufq` using connection filter `cf`. - * A convenience wrapper around `Curl_bufq_write_pass()`, - * so users do not have to implement a callback. - */ -CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct bufq *bufq, - const unsigned char *buf, size_t blen, - size_t *pnwritten); - -/** - * Notify connection filters that they need to setup data for - * a transfer. - */ -CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data); - -/** - * Notify connection filters that the transfer represented by `data` - * is done with sending data (e.g. has uploaded everything). - */ -void Curl_conn_ev_data_done_send(struct Curl_easy *data); - -/** - * Notify connection filters that the transfer represented by `data` - * is finished - eventually premature, e.g. before being complete. - */ -void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature); - -/** - * Notify connection filters that the transfer of data is paused/unpaused. - */ -CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause); - -/** - * Check if FIRSTSOCKET's cfilter chain deems connection alive. - */ -bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn, - bool *input_pending); - -/** - * Try to upkeep the connection filters at sockindex. - */ -CURLcode Curl_conn_keep_alive(struct Curl_easy *data, - struct connectdata *conn, - int sockindex); - -/** - * Get the remote hostname and port that the connection is currently - * talking to (or will talk to). - * Once connected or before connect starts, - * it is `conn->host.name` and `conn->remote_port`. - * During connect, when tunneling proxies are involved (http or socks), - * it will be the name and port the proxy currently negotiates with. - */ -void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex, - const char **phost, int *pport); - -/** - * Get the maximum number of parallel transfers the connection - * expects to be able to handle at `sockindex`. - */ -size_t Curl_conn_get_max_concurrent(struct Curl_easy *data, - struct connectdata *conn, - int sockindex); - -/** - * Get the underlying error code for a transfer stream or 0 if not known. - */ -int Curl_conn_get_stream_error(struct Curl_easy *data, - struct connectdata *conn, - int sockindex); - -/** - * Get the index of the given socket in the connection's sockets. - * Useful in calling `Curl_conn_send()/Curl_conn_recv()` with the - * correct socket index. - */ -int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd); - -/* - * Receive data on the connection, using FIRSTSOCKET/SECONDARYSOCKET. - * Return CURLE_AGAIN iff blocked on receiving. - */ -CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex, - char *buf, size_t len, size_t *pnread); - -/* - * Send data on the connection, using FIRSTSOCKET/SECONDARYSOCKET. - * Return CURLE_AGAIN iff blocked on sending. - */ -CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex, - const void *buf, size_t len, bool eos, - size_t *pnwritten); - -/** - * Types and macros used to keep the current easy handle in filter calls, - * allowing for nested invocations. See #10336. - * - * `cf_call_data` is intended to be a member of the cfilter's `ctx` type. - * A filter defines the macro `CF_CTX_CALL_DATA` to give access to that. - * - * With all values 0, the default, this indicates that there is no cfilter - * call with `data` ongoing. - * Macro `CF_DATA_SAVE` preserves the current `cf_call_data` in a local - * variable and sets the `data` given, incrementing the `depth` counter. - * - * Macro `CF_DATA_RESTORE` restores the old values from the local variable, - * while checking that `depth` values are as expected (debug build), catching - * cases where a "lower" RESTORE was not called. - * - * Finally, macro `CF_DATA_CURRENT` gives the easy handle of the current - * invocation. - */ -struct cf_call_data { - struct Curl_easy *data; -#ifdef DEBUGBUILD - int depth; -#endif -}; - -/** - * define to access the `struct cf_call_data for a cfilter. Normally - * a member in the cfilter's `ctx`. - * - * #define CF_CTX_CALL_DATA(cf) -> struct cf_call_data instance - */ - -#ifdef DEBUGBUILD - -#define CF_DATA_SAVE(save, cf, data) \ - do { \ - (save) = CF_CTX_CALL_DATA(cf); \ - DEBUGASSERT((save).data == NULL || (save).depth > 0); \ - CF_CTX_CALL_DATA(cf).depth++; \ - CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)CURL_UNCONST(data); \ - } while(0) - -#define CF_DATA_RESTORE(cf, save) \ - do { \ - DEBUGASSERT(CF_CTX_CALL_DATA(cf).depth == (save).depth + 1); \ - DEBUGASSERT((save).data == NULL || (save).depth > 0); \ - CF_CTX_CALL_DATA(cf) = (save); \ - } while(0) - -#else /* DEBUGBUILD */ - -#define CF_DATA_SAVE(save, cf, data) \ - do { \ - (save) = CF_CTX_CALL_DATA(cf); \ - CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)CURL_UNCONST(data); \ - } while(0) - -#define CF_DATA_RESTORE(cf, save) \ - do { \ - CF_CTX_CALL_DATA(cf) = (save); \ - } while(0) - -#endif /* !DEBUGBUILD */ - -#define CF_DATA_CURRENT(cf) ((cf) ? (CF_CTX_CALL_DATA(cf).data) : NULL) - -#endif /* HEADER_CURL_CFILTERS_H */ diff --git a/vendor/curl/lib/config-mac.h b/vendor/curl/lib/config-mac.h deleted file mode 100644 index fd9d3e7b6..000000000 --- a/vendor/curl/lib/config-mac.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_MAC_H -#define HEADER_CURL_CONFIG_MAC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* =================================================================== */ -/* Hand crafted config file for Mac OS 9 */ -/* =================================================================== */ -/* On macOS you must run configure to generate curl_config.h file */ -/* =================================================================== */ - -#ifndef CURL_OS -#define CURL_OS "mac" -#endif - -#include - -/* Define if you want the built-in manual */ -#define USE_MANUAL 1 - -#define HAVE_NETINET_IN_H 1 -#define HAVE_NETDB_H 1 -#define HAVE_ARPA_INET_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_NET_IF_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_GETTIMEOFDAY 1 -#define HAVE_FCNTL_H 1 -#define HAVE_UTIME_H 1 -#define HAVE_SYS_UTIME_H 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_ALARM 1 -#define HAVE_UTIME 1 -#define HAVE_SELECT 1 -#define HAVE_SOCKET 1 -#define HAVE_STRUCT_TIMEVAL 1 - -#define HAVE_SIGACTION 1 - -#define CURL_DISABLE_LDAP - -#define HAVE_IOCTL_FIONBIO 1 - -#define SIZEOF_INT 4 -#define SIZEOF_LONG 4 -#define SIZEOF_SIZE_T 4 -#define SIZEOF_CURL_OFF_T 8 - -#define HAVE_RECV 1 -#define RECV_TYPE_ARG1 int -#define RECV_TYPE_ARG2 void * -#define RECV_TYPE_ARG3 size_t -#define RECV_TYPE_ARG4 int -#define RECV_TYPE_RETV ssize_t - -#define HAVE_SEND 1 -#define SEND_TYPE_ARG1 int -#define SEND_TYPE_ARG2 void * -#define SEND_TYPE_ARG3 size_t -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV ssize_t - -#endif /* HEADER_CURL_CONFIG_MAC_H */ diff --git a/vendor/curl/lib/config-os400.h b/vendor/curl/lib/config-os400.h deleted file mode 100644 index 3d8d59c97..000000000 --- a/vendor/curl/lib/config-os400.h +++ /dev/null @@ -1,298 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_OS400_H -#define HEADER_CURL_CONFIG_OS400_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for OS/400 */ -/* ================================================================ */ - -#pragma enum(int) - -/* ---------------------------------------------------------------- */ -/* Global configuration parameters: normally generated by autoconf. */ -/* ---------------------------------------------------------------- */ - -/* Location of default ca bundle */ -/* Use the system keyring as the default CA bundle. */ -#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB" - - -/* Definition to make a library symbol externally visible. */ -#define CURL_EXTERN_SYMBOL - -/* cpu-machine-OS */ -#ifndef CURL_OS -#define CURL_OS "OS/400" -#endif - -/* Define to 1 if you have the alarm function. */ -#define HAVE_ALARM 1 - -/* Define if you have the header file. */ -#define HAVE_ARPA_INET_H 1 - -/* if you have */ -#define HAVE_DIRENT_H - -/* Define to 1 if you have the fcntl function. */ -#define HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#define HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the freeaddrinfo function. */ -#define HAVE_FREEADDRINFO 1 - -/* Define to 1 if you have a working getaddrinfo function. */ -#define HAVE_GETADDRINFO 1 - -/* Define to 1 if the getaddrinfo function is thread-safe. */ -#define HAVE_GETADDRINFO_THREADSAFE 1 - -/* Define to 1 if you have the 'geteuid' function. */ -#define HAVE_GETEUID 1 - -/* Define to 1 if you have the gethostname function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define to 1 if you have the getpeername function. */ -#define HAVE_GETPEERNAME 1 - -/* Define to 1 if you have the 'getppid' function. */ -#define HAVE_GETPPID 1 - -/* Define to 1 if you have the 'getpwuid' function. */ -#define HAVE_GETPWUID 1 - -/* Define to 1 if you have the getsockname function. */ -#define HAVE_GETSOCKNAME 1 - -/* Define to 1 if you have the 'gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* if you have GSS-API libraries */ -#define HAVE_GSSAPI - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#define HAVE_IOCTL_SIOCGIFADDR 1 - -/* Define to 1 if you have the lber.h header file. */ -#define HAVE_LBER_H 1 - -/* Define to 1 if you have the ldap.h header file. */ -#define HAVE_LDAP_H 1 - -/* Define to 1 if you have a working localtime_r function. */ -#define HAVE_LOCALTIME_R 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_UDP_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NET_IF_H 1 - -/* if you have opendir */ -#define HAVE_OPENDIR - -/* Define to 1 if you have the 'pipe' function. */ -#define HAVE_PIPE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_PWD_H 1 - -/* Define to 1 if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to 1 if symbol `sa_family_t' exists */ -#define HAVE_SA_FAMILY_T 1 - -/* Define to 1 if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to 1 if you have the 'sendmsg' function. */ -#define HAVE_SENDMSG 1 - -/* Define to 1 if you have the sigaction function. */ -#define HAVE_SIGACTION 1 - -/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define to 1 if you have the socketpair function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the stricmp function. */ -#define HAVE_STRICMP 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* if struct sockaddr_storage is defined */ -#define HAVE_STRUCT_SOCKADDR_STORAGE - -/* Define to 1 if you have the timeval struct. */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNICODE_UIDNA_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the 'utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Size of curl_off_t in number of bytes */ -#define SIZEOF_CURL_OFF_T 8 - -/* Size of curl_socket_t in number of bytes */ -#define SIZEOF_CURL_SOCKET_T 4 - -/* Size of int in number of bytes */ -#define SIZEOF_INT 4 - -/* Size of long in number of bytes */ -#define SIZEOF_LONG 4 - -/* Size of off_t in number of bytes */ -#define SIZEOF_OFF_T 8 /* _LARGE_FILES (*IFS64IO) version. */ - -/* Size of size_t in number of bytes */ -#define SIZEOF_SIZE_T 4 - -/* Size of time_t in number of bytes */ -#define SIZEOF_TIME_T 4 - -/* Define to 1 if all of the C89 standard headers exist (not just the ones - required in a freestanding environment). This macro is provided for - backward compatibility; new code need not use it. */ -#define STDC_HEADERS 1 - -/* Define if you want to enable IPv6 support */ -#define USE_IPV6 - -/* Use Unix domain sockets */ -#define USE_UNIX_SOCKETS - -/* Define to 1 if OS is AIX. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif - -/* ---------------------------------------------------------------- */ -/* recv/send parameter types (see lib/functypes.h) */ -/* ---------------------------------------------------------------- */ - -/* int recv(int, char *, int, int); */ -#define RECV_TYPE_ARG1 int -#define RECV_TYPE_ARG2 char * -#define RECV_TYPE_ARG3 int -#define RECV_TYPE_ARG4 int -#define RECV_TYPE_RETV int - -/* int send(int, char *, int, int); */ -#define SEND_TYPE_ARG1 int -#define SEND_NONCONST_ARG2 -#define SEND_TYPE_ARG2 char * -#define SEND_TYPE_ARG3 int -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV int - -/* ---------------------------------------------------------------- */ -/* Additional definitions specific to OS/400 */ -/* ---------------------------------------------------------------- */ - -/* The header file is in the main system include directory. */ -#define HAVE_GSSAPI_H - -/* Define to use the OS/400 crypto library. */ -#define USE_OS400CRYPTO - -/* The following definition is required on OS/400 to enable strcmpi(), - stricmp() and strdup(). */ -#define __cplusplus__strings__ - -/* The following must be defined BEFORE system header files inclusion. */ - -#define __ptr128 /* No teraspace. */ -#define qadrt_use_fputc_inline /* Generate fputc() wrapper inline. */ -#define qadrt_use_fread_inline /* Generate fread() wrapper inline. */ -#define qadrt_use_fwrite_inline /* Generate fwrite() wrapper inline. */ - -#endif /* HEADER_CURL_CONFIG_OS400_H */ diff --git a/vendor/curl/lib/config-riscos.h b/vendor/curl/lib/config-riscos.h deleted file mode 100644 index afff218a7..000000000 --- a/vendor/curl/lib/config-riscos.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_RISCOS_H -#define HEADER_CURL_CONFIG_RISCOS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for RISC OS */ -/* ================================================================ */ - -/* Define cpu-machine-OS */ -#ifndef CURL_OS -#define CURL_OS "ARM-RISC OS" -#endif - -/* Define if you want the built-in manual */ -#define USE_MANUAL - -/* Define if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define if you have the alarm function. */ -#define HAVE_ALARM - -/* Define if you have the header file. */ -#define HAVE_ARPA_INET_H - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H - -/* Define if getaddrinfo exists and works */ -#define HAVE_GETADDRINFO - -/* Define if you have the `gethostname' function. */ -#define HAVE_GETHOSTNAME - -/* Define if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY - -/* Define if you have the `timeval' struct. */ -#define HAVE_STRUCT_TIMEVAL - -/* Define if you have the header file. */ -#define HAVE_NETDB_H - -/* Define if you have the header file. */ -#define HAVE_NETINET_IN_H - -/* Define if you have the header file. */ -#define HAVE_NET_IF_H - -/* Define if you have the `select' function. */ -#define HAVE_SELECT - -/* Define if you have the `signal' function. */ -#define HAVE_SIGNAL - -/* Define if you have the `socket' function. */ -#define HAVE_SOCKET - -/* Define if you have the `stricmp' function. */ -#define HAVE_STRICMP - -/* Define if you have the header file. */ -#define HAVE_SYS_TYPES_H - -/* Define if you have the header file. */ -#define HAVE_TERMIOS_H - -/* Define if you have the header file. */ -#define HAVE_UNISTD_H - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 4 - -/* Define if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO - -/* to disable LDAP */ -#define CURL_DISABLE_LDAP - -/* Define if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 int - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 void * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV ssize_t - -/* Define if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 int - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 void * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV ssize_t - -#endif /* HEADER_CURL_CONFIG_RISCOS_H */ diff --git a/vendor/curl/lib/config-win32.h b/vendor/curl/lib/config-win32.h deleted file mode 100644 index b1fc10220..000000000 --- a/vendor/curl/lib/config-win32.h +++ /dev/null @@ -1,309 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_WIN32_H -#define HEADER_CURL_CONFIG_WIN32_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for Windows */ -/* ================================================================ */ - -/* ---------------------------------------------------------------- */ -/* HEADER FILES */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define if you have the header file. */ -#define HAVE_IO_H 1 - -/* Define if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the header file. */ -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__) -#define HAVE_STDBOOL_H 1 -#endif - -/* Define if you have the header file. */ -#ifdef __MINGW32__ -#define HAVE_SYS_PARAM_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_UTIME_H 1 - -/* Define if you have the header file. */ -#ifdef __MINGW32__ -#define HAVE_UNISTD_H 1 -#endif - -/* Define to 1 if you have the header file. */ -#ifdef __MINGW32__ -#define HAVE_LIBGEN_H 1 -#endif - -/* ---------------------------------------------------------------- */ -/* OTHER HEADER INFO */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if bool is an available type. */ -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__) -#define HAVE_BOOL_T 1 -#endif - -/* ---------------------------------------------------------------- */ -/* FUNCTIONS */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the closesocket function. */ -#define HAVE_CLOSESOCKET 1 - -/* Define to 1 if you have the `getpeername' function. */ -#define HAVE_GETPEERNAME 1 - -/* Define to 1 if you have the getsockname function. */ -#define HAVE_GETSOCKNAME 1 - -/* Define if you have the gethostname function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define if you have the gettimeofday function. */ -#ifdef __MINGW32__ -#define HAVE_GETTIMEOFDAY 1 -#endif - -/* Define if you have the ioctlsocket function. */ -#define HAVE_IOCTLSOCKET 1 - -/* Define if you have a working ioctlsocket FIONBIO function. */ -#define HAVE_IOCTLSOCKET_FIONBIO 1 - -/* Define if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define if you have the setlocale function. */ -#define HAVE_SETLOCALE 1 - -/* Define if you have the socket function. */ -#define HAVE_SOCKET 1 - -/* Define if you have the utime function. */ -#define HAVE_UTIME 1 - -/* Define if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 SOCKET - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 char * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int - -/* Define if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 SOCKET - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 char * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 int - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV int - -/* Must always use local implementations on Windows. */ -/* Define to 1 if you have an IPv6 capable working inet_ntop function. */ -/* #undef HAVE_INET_NTOP */ -/* Define to 1 if you have an IPv6 capable working inet_pton function. */ -/* #undef HAVE_INET_PTON */ - -/* Define to 1 if you have the `basename' function. */ -#ifdef __MINGW32__ -#define HAVE_BASENAME 1 -#endif - -/* Define to 1 if you have the signal function. */ -#define HAVE_SIGNAL 1 - -/* ---------------------------------------------------------------- */ -/* TYPEDEF REPLACEMENTS */ -/* ---------------------------------------------------------------- */ - -/* Define if ssize_t is not an available 'typedefed' type. */ -#ifndef _SSIZE_T_DEFINED -# ifdef __MINGW32__ -# elif defined(_WIN64) -# define _SSIZE_T_DEFINED -# define ssize_t __int64 -# else -# define _SSIZE_T_DEFINED -# define ssize_t int -# endif -#endif - -/* ---------------------------------------------------------------- */ -/* TYPE SIZES */ -/* ---------------------------------------------------------------- */ - -/* Define to the size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* Define to the size of `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - -/* Define to the size of `size_t', as computed by sizeof. */ -#ifdef _WIN64 -# define SIZEOF_SIZE_T 8 -#else -# define SIZEOF_SIZE_T 4 -#endif - -/* Define to the size of `curl_off_t', as computed by sizeof. */ -#define SIZEOF_CURL_OFF_T 8 - -/* ---------------------------------------------------------------- */ -/* COMPILER SPECIFIC */ -/* ---------------------------------------------------------------- */ - -/* Default to 64-bit time_t unless _USE_32BIT_TIME_T is defined */ -#if defined(_MSC_VER) || defined(__MINGW32__) -# ifndef _USE_32BIT_TIME_T -# define SIZEOF_TIME_T 8 -# else -# define SIZEOF_TIME_T 4 -# endif -#endif - -/* Windows XP is required for freeaddrinfo, getaddrinfo */ -#define HAVE_FREEADDRINFO 1 -#define HAVE_GETADDRINFO 1 -#define HAVE_GETADDRINFO_THREADSAFE 1 - -/* ---------------------------------------------------------------- */ -/* STRUCT RELATED */ -/* ---------------------------------------------------------------- */ - -/* Define if you have struct sockaddr_storage. */ -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define if you have struct timeval. */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define if struct sockaddr_in6 has the sin6_scope_id member. */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* ---------------------------------------------------------------- */ -/* LARGE FILE SUPPORT */ -/* ---------------------------------------------------------------- */ - -/* Number of bits in a file offset, on hosts where this is settable. */ -#ifdef __MINGW32__ -# undef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -#endif - -/* Define to the size of `off_t', as computed by sizeof. */ -#ifdef __MINGW32__ -# define SIZEOF_OFF_T 8 -#else -# define SIZEOF_OFF_T 4 -#endif - -/* ---------------------------------------------------------------- */ -/* DNS RESOLVER SPECIALTY */ -/* ---------------------------------------------------------------- */ - -/* - * Undefine both USE_ARES and USE_RESOLV_THREADED for synchronous DNS. - */ - -/* Default define to enable threaded asynchronous DNS lookups. */ -#if !defined(USE_SYNC_DNS) && !defined(USE_ARES) && \ - !defined(USE_RESOLV_THREADED) -# define USE_RESOLV_THREADED 1 -#endif - -#if defined(USE_ARES) && defined(USE_RESOLV_THREADED) -# error "Only one DNS lookup specialty may be defined at most" -#endif - -/* ---------------------------------------------------------------- */ -/* LDAP SUPPORT */ -/* ---------------------------------------------------------------- */ - -#ifndef CURL_WINDOWS_UWP -#define HAVE_LDAP_SSL 1 -#define USE_WIN32_LDAP 1 - -/* Define to use the Windows crypto library. */ -#define USE_WIN32_CRYPTO -#endif /* CURL_WINDOWS_UWP */ - -/* Define to use Unix sockets. */ -#define USE_UNIX_SOCKETS - -/* ---------------------------------------------------------------- */ -/* ADDITIONAL DEFINITIONS */ -/* ---------------------------------------------------------------- */ - -/* Define cpu-machine-OS */ -#ifndef CURL_OS -# if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */ -# define CURL_OS "i386-pc-win32" -# elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (VS2005+ or gcc) */ -# define CURL_OS "x86_64-pc-win32" -# elif defined(_M_IA64) || defined(__ia64__) /* Itanium */ -# define CURL_OS "ia64-pc-win32" -# elif defined(_M_ARM_NT) || defined(__arm__) /* ARMv7-Thumb2 */ -# define CURL_OS "thumbv7a-pc-win32" -# elif defined(_M_ARM64) || defined(__aarch64__) /* ARM64 (Windows 10) */ -# define CURL_OS "aarch64-pc-win32" -# else -# define CURL_OS "unknown-pc-win32" -# endif -#endif /* !CURL_OS */ - -#endif /* HEADER_CURL_CONFIG_WIN32_H */ diff --git a/vendor/curl/lib/conncache.c b/vendor/curl/lib/conncache.c deleted file mode 100644 index 33fb68b12..000000000 --- a/vendor/curl/lib/conncache.c +++ /dev/null @@ -1,910 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Linus Nielsen Feltzing, - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "url.h" -#include "cfilters.h" -#include "progress.h" -#include "multiif.h" -#include "curl_trc.h" -#include "cshutdn.h" -#include "conncache.h" -#include "curl_share.h" -#include "sigpipe.h" - - -#define CPOOL_IS_LOCKED(c) ((c) && (c)->locked) - -#define CPOOL_LOCK(c, d) \ - do { \ - if(c) { \ - if(CURL_SHARE_KEEP_CONNECT((c)->share)) \ - Curl_share_lock((d), CURL_LOCK_DATA_CONNECT, \ - CURL_LOCK_ACCESS_SINGLE); \ - DEBUGASSERT(!(c)->locked); \ - (c)->locked = TRUE; \ - } \ - } while(0) - -#define CPOOL_UNLOCK(c, d) \ - do { \ - if(c) { \ - DEBUGASSERT((c)->locked); \ - (c)->locked = FALSE; \ - if(CURL_SHARE_KEEP_CONNECT((c)->share)) \ - Curl_share_unlock((d), CURL_LOCK_DATA_CONNECT); \ - } \ - } while(0) - -/* A list of connections to the same destination. */ -struct cpool_bundle { - struct Curl_llist conns; /* connections in the bundle */ - size_t dest_len; /* total length of destination, including NUL */ - char dest[1]; /* destination of bundle, allocated to keep dest_len bytes */ -}; - -static struct cpool_bundle *cpool_bundle_create(const char *dest) -{ - struct cpool_bundle *bundle; - size_t dest_len = strlen(dest) + 1; - - bundle = curlx_calloc(1, sizeof(*bundle) + dest_len - 1); - if(!bundle) - return NULL; - Curl_llist_init(&bundle->conns, NULL); - bundle->dest_len = dest_len; - memcpy(bundle->dest, dest, bundle->dest_len); - return bundle; -} - -static void cpool_bundle_destroy(struct cpool_bundle *bundle) -{ - DEBUGASSERT(!Curl_llist_count(&bundle->conns)); - curlx_free(bundle); -} - -/* Add a connection to a bundle */ -static void cpool_bundle_add(struct cpool_bundle *bundle, - struct connectdata *conn) -{ - DEBUGASSERT(!Curl_node_llist(&conn->cpool_node)); - Curl_llist_append(&bundle->conns, conn, &conn->cpool_node); - conn->bits.in_cpool = TRUE; -} - -/* Remove a connection from a bundle */ -static void cpool_bundle_remove(struct cpool_bundle *bundle, - struct connectdata *conn) -{ - (void)bundle; - DEBUGASSERT(Curl_node_llist(&conn->cpool_node) == &bundle->conns); - Curl_node_remove(&conn->cpool_node); - conn->bits.in_cpool = FALSE; -} - -static void cpool_bundle_free_entry(void *freethis) -{ - cpool_bundle_destroy((struct cpool_bundle *)freethis); -} - -void Curl_cpool_init(struct cpool *cpool, - struct Curl_easy *idata, - struct Curl_share *share, - size_t size) -{ - Curl_hash_init(&cpool->dest2bundle, size, Curl_hash_str, - curlx_str_key_compare, cpool_bundle_free_entry); - - DEBUGASSERT(idata); - - cpool->idata = idata; - cpool->share = share; - cpool->initialised = TRUE; -} - -/* Return the "first" connection in the pool or NULL. */ -static struct connectdata *cpool_get_first(struct cpool *cpool) -{ - struct Curl_hash_iterator iter; - struct Curl_hash_element *he; - struct cpool_bundle *bundle; - struct Curl_llist_node *conn_node; - - Curl_hash_start_iterate(&cpool->dest2bundle, &iter); - for(he = Curl_hash_next_element(&iter); he; - he = Curl_hash_next_element(&iter)) { - bundle = he->ptr; - conn_node = Curl_llist_head(&bundle->conns); - if(conn_node) - return Curl_node_elem(conn_node); - } - return NULL; -} - -static struct cpool_bundle *cpool_find_bundle(struct cpool *cpool, - struct connectdata *conn) -{ - return Curl_hash_pick(&cpool->dest2bundle, - conn->destination, strlen(conn->destination) + 1); -} - -static void cpool_remove_bundle(struct cpool *cpool, - struct cpool_bundle *bundle) -{ - if(!cpool) - return; - Curl_hash_delete(&cpool->dest2bundle, bundle->dest, bundle->dest_len); -} - -static void cpool_remove_conn(struct cpool *cpool, - struct connectdata *conn) -{ - struct Curl_llist *list = Curl_node_llist(&conn->cpool_node); - DEBUGASSERT(cpool); - if(list) { - /* The connection is certainly in the pool, but where? */ - struct cpool_bundle *bundle = cpool_find_bundle(cpool, conn); - if(bundle && (list == &bundle->conns)) { - cpool_bundle_remove(bundle, conn); - if(!Curl_llist_count(&bundle->conns)) - cpool_remove_bundle(cpool, bundle); - conn->bits.in_cpool = FALSE; - cpool->num_conn--; - } - else { - /* Should have been in the bundle list */ - DEBUGASSERT(NULL); - } - } -} - -static void cpool_discard_conn(struct cpool *cpool, - struct Curl_easy *data, - struct connectdata *conn, - bool aborted) -{ - bool done = FALSE; - - DEBUGASSERT(data); - DEBUGASSERT(!data->conn); - DEBUGASSERT(cpool); - DEBUGASSERT(!conn->bits.in_cpool); - - /* - * If this connection is not marked to force-close, leave it open if there - * are other users of it - */ - if(CONN_INUSE(conn) && !aborted) { - CURL_TRC_M(data, "[CPOOL] not discarding #%" FMT_OFF_T - " still in use by %u transfers", conn->connection_id, - conn->attached_xfers); - return; - } - - /* treat the connection as aborted in CONNECT_ONLY situations, we do - * not know what the APP did with it. */ - if(conn->bits.connect_only) - aborted = TRUE; - conn->bits.aborted = aborted; - - /* We do not shutdown dead connections. The term 'dead' can be misleading - * here, as we also mark errored connections/transfers as 'dead'. - * If we do a shutdown for an aborted transfer, the server might think - * it was successful otherwise (for example an ftps: upload). This is - * not what we want. */ - if(aborted) - done = TRUE; - if(!done) { - /* Attempt to shutdown the connection right away. */ - Curl_cshutdn_run_once(cpool->idata, conn, &done); - } - - if(done || !data->multi) - Curl_cshutdn_terminate(cpool->idata, conn, FALSE); - else - Curl_cshutdn_add(&data->multi->cshutdn, conn, cpool->num_conn); -} - -void Curl_cpool_destroy(struct cpool *cpool) -{ - if(cpool && cpool->initialised && cpool->idata) { - struct connectdata *conn; - struct Curl_sigpipe_ctx pipe_ctx; - - CURL_TRC_M(cpool->idata, "%s[CPOOL] destroy, %zu connections", - cpool->share ? "[SHARE] " : "", cpool->num_conn); - /* Move all connections to the shutdown list */ - sigpipe_init(&pipe_ctx); - CPOOL_LOCK(cpool, cpool->idata); - conn = cpool_get_first(cpool); - if(conn) - sigpipe_apply(cpool->idata, &pipe_ctx); - while(conn) { - cpool_remove_conn(cpool, conn); - cpool_discard_conn(cpool, cpool->idata, conn, FALSE); - conn = cpool_get_first(cpool); - } - CPOOL_UNLOCK(cpool, cpool->idata); - sigpipe_restore(&pipe_ctx); - Curl_hash_destroy(&cpool->dest2bundle); - } -} - -static struct cpool *cpool_get_instance(struct Curl_easy *data) -{ - if(data) { - if(CURL_SHARE_KEEP_CONNECT(data->share)) - return &data->share->cpool; - else if(data->multi_easy) - return &data->multi_easy->cpool; - else if(data->multi) - return &data->multi->cpool; - } - return NULL; -} - -void Curl_cpool_xfer_init(struct Curl_easy *data) -{ - struct cpool *cpool = cpool_get_instance(data); - - DEBUGASSERT(cpool); - if(cpool) { - CPOOL_LOCK(cpool, data); - /* the identifier inside the connection cache */ - data->id = cpool->next_easy_id++; - if(cpool->next_easy_id <= 0) - cpool->next_easy_id = 0; - data->state.lastconnect_id = -1; - - CPOOL_UNLOCK(cpool, data); - } - else { - /* We should not get here, but in a non-debug build, do something */ - data->id = 0; - data->state.lastconnect_id = -1; - } -} - -static struct cpool_bundle *cpool_add_bundle(struct cpool *cpool, - struct connectdata *conn) -{ - struct cpool_bundle *bundle; - - bundle = cpool_bundle_create(conn->destination); - if(!bundle) - return NULL; - - if(!Curl_hash_add(&cpool->dest2bundle, - bundle->dest, bundle->dest_len, bundle)) { - cpool_bundle_destroy(bundle); - return NULL; - } - return bundle; -} - -static struct connectdata * -cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle, - const struct curltime *pnow) -{ - struct Curl_llist_node *curr; - timediff_t highscore = -1; - timediff_t score; - struct connectdata *oldest_idle = NULL; - struct connectdata *conn; - - curr = Curl_llist_head(&bundle->conns); - while(curr) { - conn = Curl_node_elem(curr); - - if(!CONN_INUSE(conn)) { - /* Set higher score for the age passed since the connection was used */ - score = curlx_ptimediff_ms(pnow, &conn->lastused); - - if(score > highscore) { - highscore = score; - oldest_idle = conn; - } - } - curr = Curl_node_next(curr); - } - return oldest_idle; -} - -static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool, - const struct curltime *pnow) -{ - struct Curl_hash_iterator iter; - struct Curl_llist_node *curr; - struct Curl_hash_element *he; - struct connectdata *oldest_idle = NULL; - struct cpool_bundle *bundle; - timediff_t highscore = -1; - timediff_t score; - - Curl_hash_start_iterate(&cpool->dest2bundle, &iter); - - for(he = Curl_hash_next_element(&iter); he; - he = Curl_hash_next_element(&iter)) { - struct connectdata *conn; - bundle = he->ptr; - - for(curr = Curl_llist_head(&bundle->conns); curr; - curr = Curl_node_next(curr)) { - conn = Curl_node_elem(curr); - if(CONN_INUSE(conn) || conn->bits.close || conn->bits.connect_only) - continue; - /* Set higher score for the age passed since the connection was used */ - score = curlx_ptimediff_ms(pnow, &conn->lastused); - if(score > highscore) { - highscore = score; - oldest_idle = conn; - } - } - } - return oldest_idle; -} - -int Curl_cpool_check_limits(struct Curl_easy *data, - struct connectdata *conn) -{ - struct cpool *cpool = cpool_get_instance(data); - struct cpool_bundle *bundle; - size_t dest_limit = 0; - size_t total_limit = 0; - size_t shutdowns; - int res = CPOOL_LIMIT_OK; - - if(!cpool) - return CPOOL_LIMIT_OK; - - if(cpool->idata->multi) { - dest_limit = cpool->idata->multi->max_host_connections; - total_limit = cpool->idata->multi->max_total_connections; - } - - if(!dest_limit && !total_limit) - return CPOOL_LIMIT_OK; - - CPOOL_LOCK(cpool, cpool->idata); - if(dest_limit) { - size_t live; - - bundle = cpool_find_bundle(cpool, conn); - live = bundle ? Curl_llist_count(&bundle->conns) : 0; - shutdowns = Curl_cshutdn_dest_count(data, conn->destination); - while((live + shutdowns) >= dest_limit) { - if(shutdowns) { - /* close one connection in shutdown right away, if we can */ - if(!Curl_cshutdn_close_oldest(data, conn->destination)) - break; - } - else if(!bundle) - break; - else { - struct connectdata *oldest_idle = NULL; - /* The bundle is full. Extract the oldest connection that may - * be removed now, if there is one. */ - oldest_idle = cpool_bundle_get_oldest_idle(bundle, - Curl_pgrs_now(data)); - if(!oldest_idle) - break; - /* disconnect the old conn and continue */ - CURL_TRC_M(data, "Discarding connection #%" FMT_OFF_T - " from %zu to reach destination limit of %zu", - oldest_idle->connection_id, - Curl_llist_count(&bundle->conns), dest_limit); - Curl_conn_terminate(cpool->idata, oldest_idle, FALSE); - - /* in case the bundle was destroyed in disconnect, look it up again */ - bundle = cpool_find_bundle(cpool, conn); - live = bundle ? Curl_llist_count(&bundle->conns) : 0; - } - shutdowns = Curl_cshutdn_dest_count(cpool->idata, conn->destination); - } - if((live + shutdowns) >= dest_limit) { - res = CPOOL_LIMIT_DEST; - goto out; - } - } - - if(total_limit) { - shutdowns = Curl_cshutdn_count(cpool->idata); - while((cpool->num_conn + shutdowns) >= total_limit) { - if(shutdowns) { - /* close one connection in shutdown right away, if we can */ - if(!Curl_cshutdn_close_oldest(data, NULL)) - break; - } - else { - struct connectdata *oldest_idle = - cpool_get_oldest_idle(cpool, Curl_pgrs_now(data)); - if(!oldest_idle) - break; - /* disconnect the old conn and continue */ - CURL_TRC_M(data, "Discarding connection #%" - FMT_OFF_T " from %zu to reach total " - "limit of %zu", - oldest_idle->connection_id, cpool->num_conn, total_limit); - Curl_conn_terminate(cpool->idata, oldest_idle, FALSE); - } - shutdowns = Curl_cshutdn_count(cpool->idata); - } - if((cpool->num_conn + shutdowns) >= total_limit) { - res = CPOOL_LIMIT_TOTAL; - goto out; - } - } - -out: - CPOOL_UNLOCK(cpool, cpool->idata); - return res; -} - -CURLcode Curl_cpool_add(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct cpool_bundle *bundle = NULL; - struct cpool *cpool = cpool_get_instance(data); - DEBUGASSERT(conn); - - DEBUGASSERT(cpool); - if(!cpool) - return CURLE_FAILED_INIT; - - CPOOL_LOCK(cpool, data); - bundle = cpool_find_bundle(cpool, conn); - if(!bundle) { - bundle = cpool_add_bundle(cpool, conn); - if(!bundle) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - cpool_bundle_add(bundle, conn); - conn->connection_id = cpool->next_connection_id++; - cpool->num_conn++; - CURL_TRC_M(data, "[CPOOL] added connection %" FMT_OFF_T ". " - "The cache now contains %zu members", - conn->connection_id, cpool->num_conn); -out: - CPOOL_UNLOCK(cpool, data); - - return result; -} - -/* This function iterates the entire connection pool and calls the function - func() with the connection pointer as the first argument and the supplied - 'param' argument as the other. - - The cpool lock is still held when the callback is called. It needs it, - so that it can safely continue traversing the lists once the callback - returns. - - Returns TRUE if the loop was aborted due to the callback's return code. - - Return 0 from func() to continue the loop, return 1 to abort it. - */ -static bool cpool_foreach(struct Curl_easy *data, - struct cpool *cpool, - void *param, - int (*func)(struct Curl_easy *data, - struct connectdata *conn, void *param)) -{ - struct Curl_hash_iterator iter; - struct Curl_hash_element *he; - - if(!cpool) - return FALSE; - - Curl_hash_start_iterate(&cpool->dest2bundle, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - struct Curl_llist_node *curr; - struct cpool_bundle *bundle = he->ptr; - he = Curl_hash_next_element(&iter); - - curr = Curl_llist_head(&bundle->conns); - while(curr) { - /* Yes, we need to update curr before calling func(), because func() - might decide to remove the connection */ - struct connectdata *conn = Curl_node_elem(curr); - curr = Curl_node_next(curr); - - if(func(data, conn, param) == 1) { - return TRUE; - } - } - } - return FALSE; -} - -/* - * A connection (already in the pool) has become idle. Do any - * cleanups in regard to the pool's limits. - * - * Return TRUE if idle connection kept in pool, FALSE if closed. - */ -bool Curl_cpool_conn_now_idle(struct Curl_easy *data, - struct connectdata *conn) -{ - unsigned int maxconnects; - struct connectdata *oldest_idle = NULL; - struct cpool *cpool = cpool_get_instance(data); - bool kept = TRUE; - - if(!data || !data->multi) - return kept; - - if(!data->multi->maxconnects) { - unsigned int running = Curl_multi_xfers_running(data->multi); - maxconnects = (running <= UINT_MAX / 4) ? running * 4 : UINT_MAX; - } - else { - maxconnects = data->multi->maxconnects; - } - - conn->lastused = *Curl_pgrs_now(data); /* it was used up until now */ - if(cpool && maxconnects) { - /* may be called form a callback already under lock */ - bool do_lock = !CPOOL_IS_LOCKED(cpool); - if(do_lock) - CPOOL_LOCK(cpool, data); - if(cpool->num_conn > maxconnects) { - infof(data, "Connection pool is full, closing the oldest of %zu/%u", - cpool->num_conn, maxconnects); - - oldest_idle = cpool_get_oldest_idle(cpool, Curl_pgrs_now(data)); - kept = (oldest_idle != conn); - if(oldest_idle) { - Curl_conn_terminate(data, oldest_idle, FALSE); - } - } - if(do_lock) - CPOOL_UNLOCK(cpool, data); - } - - return kept; -} - -bool Curl_cpool_find(struct Curl_easy *data, - const char *destination, - Curl_cpool_conn_match_cb *conn_cb, - Curl_cpool_done_match_cb *done_cb, - void *userdata) -{ - struct cpool *cpool = cpool_get_instance(data); - struct cpool_bundle *bundle; - bool found = FALSE; - - DEBUGASSERT(cpool); - DEBUGASSERT(conn_cb); - if(!cpool) - return FALSE; - - CPOOL_LOCK(cpool, data); - bundle = Curl_hash_pick(&cpool->dest2bundle, - CURL_UNCONST(destination), - strlen(destination) + 1); - if(bundle) { - struct Curl_llist_node *curr = Curl_llist_head(&bundle->conns); - while(curr) { - struct connectdata *conn = Curl_node_elem(curr); - /* Get next node now. callback might discard current */ - curr = Curl_node_next(curr); - - if(conn_cb(conn, userdata)) { - found = TRUE; - break; - } - } - } - - if(done_cb) { - found = done_cb(userdata); - } - CPOOL_UNLOCK(cpool, data); - return found; -} - -void Curl_conn_terminate(struct Curl_easy *data, - struct connectdata *conn, - bool aborted) -{ - struct cpool *cpool = cpool_get_instance(data); - bool do_lock; - - DEBUGASSERT(cpool); - DEBUGASSERT(data && !data->conn); - if(!cpool) - return; - - /* If this connection is not marked to force-close, leave it open if there - * are other users of it */ - if(CONN_INUSE(conn) && !aborted) { - DEBUGASSERT(0); /* does this ever happen? */ - DEBUGF(infof(data, "conn terminate when inuse: %u", conn->attached_xfers)); - return; - } - - /* This method may be called while we are under lock, e.g. from a - * user callback in find. */ - do_lock = !CPOOL_IS_LOCKED(cpool); - if(do_lock) - CPOOL_LOCK(cpool, data); - - if(conn->bits.in_cpool) { - cpool_remove_conn(cpool, conn); - DEBUGASSERT(!conn->bits.in_cpool); - } - - /* treat the connection as aborted in CONNECT_ONLY situations, - * so no graceful shutdown is attempted. */ - if(conn->bits.connect_only) - aborted = TRUE; - - if(data->multi) { - /* Add it to the multi's cpool for shutdown handling */ - infof(data, "%s connection #%" FMT_OFF_T, - aborted ? "closing" : "shutting down", conn->connection_id); - cpool_discard_conn(&data->multi->cpool, data, conn, aborted); - } - else { - /* No multi available, terminate */ - infof(data, "closing connection #%" FMT_OFF_T, conn->connection_id); - Curl_cshutdn_terminate(cpool->idata, conn, !aborted); - } - - if(do_lock) - CPOOL_UNLOCK(cpool, data); -} - -struct cpool_reaper_ctx { - size_t checked; - size_t reaped; -}; - -static int cpool_reap_dead_cb(struct Curl_easy *data, - struct connectdata *conn, void *param) -{ - struct cpool_reaper_ctx *reaper = param; - bool terminate = !CONN_INUSE(conn) && conn->bits.no_reuse; - - if(!terminate) { - reaper->checked++; - terminate = Curl_conn_seems_dead(conn, data); - } - if(terminate) { - /* stop the iteration here, pass back the connection that was pruned */ - reaper->reaped++; - Curl_conn_terminate(data, conn, FALSE); - return 1; - } - return 0; /* continue iteration */ -} - -/* - * This function scans the data's connection pool for half-open/dead - * connections, closes and removes them. - * The cleanup is done at most once per second. - * - * When called, this transfer has no connection attached. - */ -void Curl_cpool_prune_dead(struct Curl_easy *data) -{ - struct cpool *cpool = cpool_get_instance(data); - struct cpool_reaper_ctx reaper; - timediff_t elapsed; - - if(!cpool) - return; - - memset(&reaper, 0, sizeof(reaper)); - CPOOL_LOCK(cpool, data); - elapsed = curlx_ptimediff_ms(Curl_pgrs_now(data), &cpool->last_cleanup); - - if(elapsed >= 1000L) { - while(cpool_foreach(data, cpool, &reaper, cpool_reap_dead_cb)) - ; - cpool->last_cleanup = *Curl_pgrs_now(data); - } - CPOOL_UNLOCK(cpool, data); -} - -static int conn_upkeep(struct Curl_easy *data, - struct connectdata *conn, - void *param) -{ - (void)param; - Curl_conn_upkeep(data, conn); - return 0; /* continue iteration */ -} - -CURLcode Curl_cpool_upkeep(struct Curl_easy *data) -{ - struct cpool *cpool = cpool_get_instance(data); - - if(!cpool) - return CURLE_OK; - - CPOOL_LOCK(cpool, data); - cpool_foreach(data, cpool, NULL, conn_upkeep); - CPOOL_UNLOCK(cpool, data); - return CURLE_OK; -} - -struct cpool_find_ctx { - curl_off_t id; - struct connectdata *conn; -}; - -static int cpool_find_conn(struct Curl_easy *data, - struct connectdata *conn, void *param) -{ - struct cpool_find_ctx *fctx = param; - (void)data; - if(conn->connection_id == fctx->id) { - fctx->conn = conn; - return 1; - } - return 0; -} - -struct connectdata *Curl_cpool_get_conn(struct Curl_easy *data, - curl_off_t conn_id) -{ - struct cpool *cpool = cpool_get_instance(data); - struct cpool_find_ctx fctx; - - if(!cpool) - return NULL; - fctx.id = conn_id; - fctx.conn = NULL; - CPOOL_LOCK(cpool, data); - cpool_foreach(data, cpool, &fctx, cpool_find_conn); - CPOOL_UNLOCK(cpool, data); - return fctx.conn; -} - -struct cpool_do_conn_ctx { - curl_off_t id; - Curl_cpool_conn_do_cb *cb; - void *cbdata; -}; - -static int cpool_do_conn(struct Curl_easy *data, - struct connectdata *conn, void *param) -{ - struct cpool_do_conn_ctx *dctx = param; - - if(conn->connection_id == dctx->id) { - dctx->cb(conn, data, dctx->cbdata); - return 1; - } - return 0; -} - -void Curl_cpool_do_by_id(struct Curl_easy *data, curl_off_t conn_id, - Curl_cpool_conn_do_cb *cb, void *cbdata) -{ - struct cpool *cpool = cpool_get_instance(data); - struct cpool_do_conn_ctx dctx; - - if(!cpool) - return; - dctx.id = conn_id; - dctx.cb = cb; - dctx.cbdata = cbdata; - CPOOL_LOCK(cpool, data); - cpool_foreach(data, cpool, &dctx, cpool_do_conn); - CPOOL_UNLOCK(cpool, data); -} - -void Curl_cpool_do_locked(struct Curl_easy *data, - struct connectdata *conn, - Curl_cpool_conn_do_cb *cb, void *cbdata) -{ - struct cpool *cpool = cpool_get_instance(data); - if(cpool) { - CPOOL_LOCK(cpool, data); - cb(conn, data, cbdata); - CPOOL_UNLOCK(cpool, data); - } - else - cb(conn, data, cbdata); -} - -static int cpool_mark_stale(struct Curl_easy *data, - struct connectdata *conn, void *param) -{ - (void)data; - (void)param; - conn->bits.no_reuse = TRUE; - return 0; -} - -static int cpool_reap_no_reuse(struct Curl_easy *data, - struct connectdata *conn, void *param) -{ - (void)param; - if(!CONN_INUSE(conn) && conn->bits.no_reuse) { - Curl_conn_terminate(data, conn, FALSE); - return 1; - } - return 0; /* continue iteration */ -} - -void Curl_cpool_nw_changed(struct Curl_easy *data) -{ - struct cpool *cpool = cpool_get_instance(data); - - if(cpool) { - CPOOL_LOCK(cpool, data); - cpool_foreach(data, cpool, NULL, cpool_mark_stale); - while(cpool_foreach(data, cpool, NULL, cpool_reap_no_reuse)) - ; - CPOOL_UNLOCK(cpool, data); - } -} - -#if 0 -/* Useful for debugging the connection pool */ -void Curl_cpool_print(struct cpool *cpool) -{ - struct Curl_hash_iterator iter; - struct Curl_llist_node *curr; - struct Curl_hash_element *he; - - if(!cpool) - return; - - curl_mfprintf(stderr, "=Bundle cache=\n"); - - Curl_hash_start_iterate(cpool->dest2bundle, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - struct cpool_bundle *bundle; - struct connectdata *conn; - - bundle = he->ptr; - - curl_mfprintf(stderr, "%s -", he->key); - curr = Curl_llist_head(bundle->conns); - while(curr) { - conn = Curl_node_elem(curr); - - curl_mfprintf(stderr, " [%p %d]", (void *)conn, conn->refcount); - curr = Curl_node_next(curr); - } - curl_mfprintf(stderr, "\n"); - - he = Curl_hash_next_element(&iter); - } -} -#endif diff --git a/vendor/curl/lib/conncache.h b/vendor/curl/lib/conncache.h deleted file mode 100644 index 7cee4d472..000000000 --- a/vendor/curl/lib/conncache.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef HEADER_CURL_CONNCACHE_H -#define HEADER_CURL_CONNCACHE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Linus Nielsen Feltzing, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/timeval.h" - -struct connectdata; -struct Curl_easy; -struct curl_pollfds; -struct Curl_waitfds; -struct Curl_multi; -struct Curl_share; - -/** - * Terminate the connection, e.g. close and destroy. - * If the connection is in a cpool, remove it. - * If a `cshutdn` is available (e.g. data has a multi handle), - * pass the connection to that for controlled shutdown. - * Otherwise terminate it right away. - * Takes ownership of `conn`. - * `data` should not be attached to a connection. - */ -void Curl_conn_terminate(struct Curl_easy *data, - struct connectdata *conn, - bool aborted); - -struct cpool { - /* the pooled connections, bundled per destination */ - struct Curl_hash dest2bundle; - size_t num_conn; - curl_off_t next_connection_id; - curl_off_t next_easy_id; - struct curltime last_cleanup; - struct Curl_easy *idata; /* internal handle for maintenance */ - struct Curl_share *share; /* != NULL if pool belongs to share */ - BIT(locked); - BIT(initialised); -}; - -/* Init the pool, pass multi only if pool is owned by it. - * Cannot fail. - */ -void Curl_cpool_init(struct cpool *cpool, - struct Curl_easy *idata, - struct Curl_share *share, - size_t size); - -/* Destroy all connections and free all members */ -void Curl_cpool_destroy(struct cpool *cpool); - -/* Init the transfer to be used within its connection pool. - * Assigns `data->id`. */ -void Curl_cpool_xfer_init(struct Curl_easy *data); - -/* Get the connection with the given id from `data`'s conn pool. */ -struct connectdata *Curl_cpool_get_conn(struct Curl_easy *data, - curl_off_t conn_id); - -/* Add the connection to the pool. */ -CURLcode Curl_cpool_add(struct Curl_easy *data, - struct connectdata *conn) WARN_UNUSED_RESULT; - -/** - * Return if the pool has reached its configured limits for adding - * the given connection. Try to discard the oldest, idle connections - * to make space. - */ -#define CPOOL_LIMIT_OK 0 -#define CPOOL_LIMIT_DEST 1 -#define CPOOL_LIMIT_TOTAL 2 -int Curl_cpool_check_limits(struct Curl_easy *data, - struct connectdata *conn); - -/* Return of conn is suitable. If so, stops iteration. */ -typedef bool Curl_cpool_conn_match_cb(struct connectdata *conn, - void *userdata); - -/* Act on the result of the find, may override it. */ -typedef bool Curl_cpool_done_match_cb(void *userdata); - -/** - * Find a connection in the pool matching `destination`. - * All callbacks are invoked while the pool's lock is held. - * @param data current transfer - * @param destination match against `conn->destination` in pool - * @param conn_cb must be present, called for each connection in the - * bundle until it returns TRUE - * @return combined result of last conn_db and result_cb or FALSE if no - connections were present. - */ -bool Curl_cpool_find(struct Curl_easy *data, - const char *destination, - Curl_cpool_conn_match_cb *conn_cb, - Curl_cpool_done_match_cb *done_cb, - void *userdata); - -/* - * A connection (already in the pool) is now idle. Do any - * cleanups in regard to the pool's limits. - * - * Return TRUE if idle connection kept in pool, FALSE if closed. - */ -bool Curl_cpool_conn_now_idle(struct Curl_easy *data, - struct connectdata *conn); - -/** - * This function scans the data's connection pool for half-open/dead - * connections, closes and removes them. - * The cleanup is done at most once per second. - * - * When called, this transfer has no connection attached. - */ -void Curl_cpool_prune_dead(struct Curl_easy *data); - -/** - * Perform upkeep actions on connections in the transfer's pool. - */ -CURLcode Curl_cpool_upkeep(struct Curl_easy *data); - -typedef void Curl_cpool_conn_do_cb(struct connectdata *conn, - struct Curl_easy *data, - void *cbdata); - -/** - * Invoke the callback on the pool's connection with the - * given connection id (if it exists). - */ -void Curl_cpool_do_by_id(struct Curl_easy *data, - curl_off_t conn_id, - Curl_cpool_conn_do_cb *cb, void *cbdata); - -/** - * Invoked the callback for the given data + connection under the - * connection pool's lock. - * The callback is always invoked, even if the transfer has no connection - * pool associated. - */ -void Curl_cpool_do_locked(struct Curl_easy *data, - struct connectdata *conn, - Curl_cpool_conn_do_cb *cb, void *cbdata); - -/* Close all unused connections, prevent reuse of existing ones. */ -void Curl_cpool_nw_changed(struct Curl_easy *data); - -#endif /* HEADER_CURL_CONNCACHE_H */ diff --git a/vendor/curl/lib/connect.c b/vendor/curl/lib/connect.c deleted file mode 100644 index b13d49684..000000000 --- a/vendor/curl/lib/connect.c +++ /dev/null @@ -1,643 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include /* may need it */ -#endif -#ifdef HAVE_SYS_UN_H -#include /* for sockaddr_un */ -#endif -#ifdef HAVE_LINUX_TCP_H -#include -#elif defined(HAVE_NETINET_TCP_H) -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "curl_trc.h" -#include "strerror.h" -#include "cfilters.h" -#include "connect.h" -#include "cf-dns.h" -#include "cf-haproxy.h" -#include "cf-https-connect.h" -#include "cf-ip-happy.h" -#include "cf-socket.h" -#include "multiif.h" -#include "curlx/inet_ntop.h" -#include "curlx/strparse.h" -#include "vtls/vtls.h" /* for vtls cfilters */ -#include "progress.h" -#include "conncache.h" -#include "multihandle.h" -#include "http_proxy.h" -#include "socks.h" - -#if !defined(CURL_DISABLE_ALTSVC) || defined(USE_HTTPSRR) - -enum alpnid Curl_alpn2alpnid(const unsigned char *name, size_t len) -{ - if(len == 2) { - if(!memcmp(name, "h1", 2)) - return ALPN_h1; - if(!memcmp(name, "h2", 2)) - return ALPN_h2; - if(!memcmp(name, "h3", 2)) - return ALPN_h3; - } - else if(len == 8) { - if(!memcmp(name, "http/1.1", 8)) - return ALPN_h1; - } - return ALPN_none; /* unknown, probably rubbish input */ -} - -enum alpnid Curl_str2alpnid(const struct Curl_str *cstr) -{ - return Curl_alpn2alpnid((const unsigned char *)curlx_str(cstr), - curlx_strlen(cstr)); -} - -#endif - -/* - * timeleft_now_ms() returns the amount of milliseconds left allowed for the - * transfer/connection. If the value is 0, there is no timeout (ie there is - * infinite time left). If the value is negative, the timeout time has already - * elapsed. - * - * @unittest 1303 - */ -UNITTEST timediff_t timeleft_now_ms(struct Curl_easy *data, - const struct curltime *pnow); -UNITTEST timediff_t timeleft_now_ms(struct Curl_easy *data, - const struct curltime *pnow) -{ - timediff_t timeleft_ms = 0; - timediff_t ctimeleft_ms = 0; - - if(Curl_shutdown_started(data, FIRSTSOCKET)) - return Curl_shutdown_timeleft(data, data->conn, FIRSTSOCKET); - else if(Curl_is_connecting(data)) { - timediff_t ctimeout_ms = (data->set.connecttimeout > 0) ? - data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT; - ctimeleft_ms = ctimeout_ms - - curlx_ptimediff_ms(pnow, &data->progress.t_startsingle); - if(!ctimeleft_ms) - ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */ - } - else if(!data->set.timeout || data->set.connect_only) { - return 0; /* no timeout in place or checked, return "no limit" */ - } - - if(data->set.timeout) { - timeleft_ms = data->set.timeout - - curlx_ptimediff_ms(pnow, &data->progress.t_startop); - if(!timeleft_ms) - timeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */ - } - - if(!ctimeleft_ms) - return timeleft_ms; - else if(!timeleft_ms) - return ctimeleft_ms; - return CURLMIN(ctimeleft_ms, timeleft_ms); -} - -timediff_t Curl_timeleft_ms(struct Curl_easy *data) -{ - return timeleft_now_ms(data, Curl_pgrs_now(data)); -} - -void Curl_shutdown_start(struct Curl_easy *data, int sockindex, - int timeout_ms) -{ - struct connectdata *conn = data->conn; - - DEBUGASSERT(conn); - conn->shutdown.start[sockindex] = *Curl_pgrs_now(data); - conn->shutdown.timeout_ms = (timeout_ms > 0) ? - (timediff_t)timeout_ms : - ((data->set.shutdowntimeout > 0) ? - data->set.shutdowntimeout : DEFAULT_SHUTDOWN_TIMEOUT_MS); - /* Set a timer, unless we operate on the admin handle */ - if(data->mid) - Curl_expire_ex(data, conn->shutdown.timeout_ms, EXPIRE_SHUTDOWN); - CURL_TRC_M(data, "shutdown start on%s connection", - sockindex ? " secondary" : ""); -} - -timediff_t Curl_shutdown_timeleft(struct Curl_easy *data, - struct connectdata *conn, - int sockindex) -{ - timediff_t left_ms; - - if(!conn->shutdown.start[sockindex].tv_sec || - (conn->shutdown.timeout_ms <= 0)) - return 0; /* not started or no limits */ - - left_ms = conn->shutdown.timeout_ms - - curlx_ptimediff_ms(Curl_pgrs_now(data), - &conn->shutdown.start[sockindex]); - return left_ms ? left_ms : -1; -} - -timediff_t Curl_conn_shutdown_timeleft(struct Curl_easy *data, - struct connectdata *conn) -{ - timediff_t left_ms = 0, ms; - int i; - - for(i = 0; conn->shutdown.timeout_ms && (i < 2); ++i) { - if(!conn->shutdown.start[i].tv_sec) - continue; - ms = Curl_shutdown_timeleft(data, conn, i); - if(ms && (!left_ms || ms < left_ms)) - left_ms = ms; - } - return left_ms; -} - -void Curl_shutdown_clear(struct Curl_easy *data, int sockindex) -{ - struct curltime *pt = &data->conn->shutdown.start[sockindex]; - memset(pt, 0, sizeof(*pt)); -} - -bool Curl_shutdown_started(struct Curl_easy *data, int sockindex) -{ - if(data->conn) { - struct curltime *pt = &data->conn->shutdown.start[sockindex]; - return (pt->tv_sec > 0) || (pt->tv_usec > 0); - } - return FALSE; -} - -/* retrieves ip address and port from a sockaddr structure. note it calls - curlx_inet_ntop which sets errno on fail, not SOCKERRNO. */ -bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, uint16_t *port) -{ - struct sockaddr_in *si = NULL; -#ifdef USE_IPV6 - struct sockaddr_in6 *si6 = NULL; -#endif -#ifdef USE_UNIX_SOCKETS - struct sockaddr_un *su = NULL; -#else - (void)salen; -#endif - - switch(sa->sa_family) { - case AF_INET: - si = (struct sockaddr_in *)(void *)sa; - if(curlx_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) { - *port = ntohs(si->sin_port); - return TRUE; - } - break; -#ifdef USE_IPV6 - case AF_INET6: - si6 = (struct sockaddr_in6 *)(void *)sa; - if(curlx_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, MAX_IPADR_LEN)) { - *port = ntohs(si6->sin6_port); - return TRUE; - } - break; -#endif -#ifdef USE_UNIX_SOCKETS - case AF_UNIX: - if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) { - su = (struct sockaddr_un *)sa; - curl_msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); - } - else - addr[0] = 0; /* socket with no name */ - *port = 0; - return TRUE; -#endif - default: - break; - } - - addr[0] = '\0'; - *port = 0; - errno = SOCKEAFNOSUPPORT; - return FALSE; -} - -/* - * Used to extract socket and connectdata struct for the most recent - * transfer on the given Curl_easy. - * - * The returned socket will be CURL_SOCKET_BAD in case of failure! - */ -curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, - struct connectdata **connp) -{ - DEBUGASSERT(data); - - /* this works for an easy handle: - * - that has been used for curl_easy_perform() - * - that is associated with a multi handle, and whose connection - * was detached with CURLOPT_CONNECT_ONLY - */ - if(data->state.lastconnect_id != -1) { - struct connectdata *conn; - - conn = Curl_cpool_get_conn(data, data->state.lastconnect_id); - if(!conn) { - data->state.lastconnect_id = -1; - return CURL_SOCKET_BAD; - } - - if(connp) - /* only store this if the caller cares for it */ - *connp = conn; - return conn->sock[FIRSTSOCKET]; - } - return CURL_SOCKET_BAD; -} - -/* - * Curl_conncontrol() marks streams or connection for closure. - */ -void Curl_conncontrol(struct connectdata *conn, - int ctrl /* see defines in header */ -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - , const char *reason -#endif - ) -{ - /* close if a connection, or a stream that is not multiplexed. */ - /* This function will be called both before and after this connection is - associated with a transfer. */ - bool closeit, is_multiplex; - DEBUGASSERT(conn); -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - (void)reason; /* useful for debugging */ -#endif - is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET); - closeit = (ctrl == CONNCTRL_CONNECTION) || - ((ctrl == CONNCTRL_STREAM) && !is_multiplex); - if((ctrl == CONNCTRL_STREAM) && is_multiplex) - ; /* stream signal on multiplex conn never affects close state */ - else if((curl_bit)closeit != conn->bits.close) { - conn->bits.close = closeit; /* the only place in the source code that - should assign this bit */ - } -} - -typedef enum { - CF_SETUP_INIT, - CF_SETUP_CNNCT_EYEBALLS, - CF_SETUP_CNNCT_SOCKS, - CF_SETUP_CNNCT_HTTP_PROXY, - CF_SETUP_CNNCT_HAPROXY, - CF_SETUP_CNNCT_SSL, - CF_SETUP_DONE -} cf_setup_state; - -struct cf_setup_ctx { - cf_setup_state state; - int ssl_mode; - uint8_t transport; -}; - -static CURLcode cf_setup_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_setup_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* connect current sub-chain */ -connect_sub_chain: - - if(cf->next && !cf->next->connected) { - result = Curl_conn_cf_connect(cf->next, data, done); - if(result || !*done) - return result; - } - - if(ctx->state < CF_SETUP_CNNCT_EYEBALLS) { - result = cf_ip_happy_insert_after(cf, data, ctx->transport); - if(result) - return result; - ctx->state = CF_SETUP_CNNCT_EYEBALLS; - if(!cf->next || !cf->next->connected) - goto connect_sub_chain; - } - - /* sub-chain connected, do we need to add more? */ -#ifndef CURL_DISABLE_PROXY - if(ctx->state < CF_SETUP_CNNCT_SOCKS && cf->conn->bits.socksproxy) { - /* for the secondary socket (FTP), use the "connect to host" - * but ignore the "connect to port" (use the secondary port) - */ - const char *hostname = - cf->conn->bits.httpproxy ? - cf->conn->http_proxy.host.name : - cf->conn->bits.conn_to_host ? - cf->conn->conn_to_host.name : - cf->sockindex == SECONDARYSOCKET ? - cf->conn->secondaryhostname : cf->conn->host.name; - uint16_t port = - cf->conn->bits.httpproxy ? cf->conn->http_proxy.port : - cf->sockindex == SECONDARYSOCKET ? cf->conn->secondary_port : - cf->conn->bits.conn_to_port ? cf->conn->conn_to_port : - cf->conn->remote_port; - const char *user = cf->conn->socks_proxy.user; - const char *passwd = cf->conn->socks_proxy.passwd; - - result = Curl_cf_socks_proxy_insert_after( - cf, data, hostname, port, cf->conn->ip_version, - cf->conn->socks_proxy.proxytype, user, passwd); - if(result) - return result; - ctx->state = CF_SETUP_CNNCT_SOCKS; - if(!cf->next || !cf->next->connected) - goto connect_sub_chain; - } - - if(ctx->state < CF_SETUP_CNNCT_HTTP_PROXY && cf->conn->bits.httpproxy) { -#ifdef USE_SSL - if(IS_HTTPS_PROXY(cf->conn->http_proxy.proxytype) && - !Curl_conn_is_ssl(cf->conn, cf->sockindex)) { - result = Curl_cf_ssl_proxy_insert_after(cf, data); - if(result) - return result; - } -#endif /* USE_SSL */ - -#ifndef CURL_DISABLE_HTTP - if(cf->conn->bits.tunnel_proxy) { - result = Curl_cf_http_proxy_insert_after(cf, data); - if(result) - return result; - } -#endif /* !CURL_DISABLE_HTTP */ - ctx->state = CF_SETUP_CNNCT_HTTP_PROXY; - if(!cf->next || !cf->next->connected) - goto connect_sub_chain; - } -#endif /* !CURL_DISABLE_PROXY */ - - if(ctx->state < CF_SETUP_CNNCT_HAPROXY) { -#ifndef CURL_DISABLE_PROXY - if(data->set.haproxyprotocol) { - if(Curl_conn_is_ssl(cf->conn, cf->sockindex)) { - failf(data, "haproxy protocol not supported with SSL " - "encryption in place (QUIC?)"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - result = Curl_cf_haproxy_insert_after(cf, data); - if(result) - return result; - } -#endif /* !CURL_DISABLE_PROXY */ - ctx->state = CF_SETUP_CNNCT_HAPROXY; - if(!cf->next || !cf->next->connected) - goto connect_sub_chain; - } - - if(ctx->state < CF_SETUP_CNNCT_SSL) { -#ifdef USE_SSL - if((ctx->ssl_mode == CURL_CF_SSL_ENABLE || - (ctx->ssl_mode != CURL_CF_SSL_DISABLE && - cf->conn->scheme->flags & PROTOPT_SSL)) && /* we want SSL */ - !Curl_conn_is_ssl(cf->conn, cf->sockindex)) { /* it is missing */ - result = Curl_cf_ssl_insert_after(cf, data); - if(result) - return result; - } -#endif /* USE_SSL */ - ctx->state = CF_SETUP_CNNCT_SSL; - if(!cf->next || !cf->next->connected) - goto connect_sub_chain; - } - - ctx->state = CF_SETUP_DONE; - cf->connected = TRUE; - *done = TRUE; - return CURLE_OK; -} - -static void cf_setup_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_setup_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "close"); - cf->connected = FALSE; - ctx->state = CF_SETUP_INIT; - - if(cf->next) { - cf->next->cft->do_close(cf->next, data); - Curl_conn_cf_discard_chain(&cf->next, data); - } -} - -static void cf_setup_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_setup_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "destroy"); - curlx_safefree(ctx); -} - -struct Curl_cftype Curl_cft_setup = { - "SETUP", - CF_TYPE_SETUP, - CURL_LOG_LVL_NONE, - cf_setup_destroy, - cf_setup_connect, - cf_setup_close, - Curl_cf_def_shutdown, - Curl_cf_def_adjust_pollset, - Curl_cf_def_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - Curl_cf_def_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - Curl_cf_def_query, -}; - -static CURLcode cf_setup_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - uint8_t transport, - int ssl_mode) -{ - struct Curl_cfilter *cf = NULL; - struct cf_setup_ctx *ctx; - CURLcode result = CURLE_OK; - - (void)data; - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - ctx->state = CF_SETUP_INIT; - ctx->ssl_mode = ssl_mode; - ctx->transport = transport; - - result = Curl_cf_create(&cf, &Curl_cft_setup, ctx); - if(result) - goto out; - ctx = NULL; - -out: - *pcf = result ? NULL : cf; - if(ctx) { - curlx_free(ctx); - } - return result; -} - -static CURLcode cf_setup_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - uint8_t transport, - int ssl_mode) -{ - struct Curl_cfilter *cf; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - result = cf_setup_create(&cf, data, transport, ssl_mode); - if(result) - goto out; - Curl_conn_cf_add(data, conn, sockindex, cf); -out: - return result; -} - -CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - uint8_t transport, - int ssl_mode) -{ - struct Curl_cfilter *cf; - CURLcode result; - - DEBUGASSERT(data); - result = cf_setup_create(&cf, data, transport, ssl_mode); - if(result) - goto out; - Curl_conn_cf_insert_after(cf_at, cf); -out: - return result; -} - -CURLcode Curl_conn_setup(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - struct Curl_dns_entry *dns, - int ssl_mode) -{ - CURLcode result = CURLE_OK; - uint8_t dns_queries; - - DEBUGASSERT(data); - DEBUGASSERT(conn->scheme); - DEBUGASSERT(!conn->cfilter[sockindex]); - -#ifndef CURL_DISABLE_HTTP - if(!conn->cfilter[sockindex] && - conn->scheme->protocol == CURLPROTO_HTTPS) { - DEBUGASSERT(ssl_mode != CURL_CF_SSL_DISABLE); - result = Curl_cf_https_setup(data, conn, sockindex); - if(result) - goto out; - } -#endif /* !CURL_DISABLE_HTTP */ - - /* Still no cfilter set, apply default. */ - if(!conn->cfilter[sockindex]) { - result = cf_setup_add(data, conn, sockindex, - conn->transport_wanted, ssl_mode); - if(result) - goto out; - } - - dns_queries = Curl_resolv_dns_queries(data, conn->ip_version); -#ifdef USE_HTTPSRR - if(sockindex == FIRSTSOCKET) - dns_queries |= CURL_DNSQ_HTTPS; -#endif - result = Curl_cf_dns_add(data, conn, sockindex, dns_queries, - conn->transport_wanted, dns); - DEBUGASSERT(conn->cfilter[sockindex]); -out: - return result; -} - -#ifdef USE_UNIX_SOCKETS -const char *Curl_conn_get_unix_path(struct connectdata *conn) -{ - const char *unix_path = conn->unix_domain_socket; - -#ifndef CURL_DISABLE_PROXY - if(!unix_path && conn->bits.proxy && conn->socks_proxy.host.name && - !strncmp(UNIX_SOCKET_PREFIX "/", - conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX))) - unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1; -#endif - - return unix_path; -} -#endif /* USE_UNIX_SOCKETS */ - -void Curl_conn_set_multiplex(struct connectdata *conn) -{ - if(!conn->bits.multiplex) { - conn->bits.multiplex = TRUE; - if(conn->attached_multi) { - Curl_multi_connchanged(conn->attached_multi); - } - } -} diff --git a/vendor/curl/lib/connect.h b/vendor/curl/lib/connect.h deleted file mode 100644 index 40f1c9c57..000000000 --- a/vendor/curl/lib/connect.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef HEADER_CURL_CONNECT_H -#define HEADER_CURL_CONNECT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "hostip.h" -#include "curlx/timeval.h" - -struct Curl_dns_entry; -struct ip_quadruple; -struct Curl_str; - -enum alpnid Curl_alpn2alpnid(const unsigned char *name, size_t len); -enum alpnid Curl_str2alpnid(const struct Curl_str *cstr); - -/* generic function that returns how much time there is left to run, according - to the timeouts set */ -timediff_t Curl_timeleft_ms(struct Curl_easy *data); - -#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */ - -#define DEFAULT_SHUTDOWN_TIMEOUT_MS (2 * 1000) - -void Curl_shutdown_start(struct Curl_easy *data, int sockindex, - int timeout_ms); - -/* return how much time there is left to shutdown the connection at - * sockindex. Returns 0 if there is no limit or shutdown has not started. */ -timediff_t Curl_shutdown_timeleft(struct Curl_easy *data, - struct connectdata *conn, - int sockindex); - -/* return how much time there is left to shutdown the connection. - * Returns 0 if there is no limit or shutdown has not started. */ -timediff_t Curl_conn_shutdown_timeleft(struct Curl_easy *data, - struct connectdata *conn); - -void Curl_shutdown_clear(struct Curl_easy *data, int sockindex); - -/* TRUE iff shutdown has been started */ -bool Curl_shutdown_started(struct Curl_easy *data, int sockindex); - -/* - * Used to extract socket and connectdata struct for the most recent - * transfer on the given Curl_easy. - * - * The returned socket will be CURL_SOCKET_BAD in case of failure! - */ -curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, - struct connectdata **connp); - -bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, uint16_t *port); - -/* - * Curl_conncontrol() marks the end of a connection/stream. The 'ctrl' - * argument specifies if it is the end of a connection or a stream. - * - * For stream-based protocols (such as HTTP/2), a stream close will not cause - * a connection close. Other protocols will close the connection for both - * cases. - * - * It sets the bit.close bit to TRUE (with an explanation for debug builds), - * when the connection will close. - */ - -#define CONNCTRL_KEEP 0 /* undo a marked closure */ -#define CONNCTRL_CONNECTION 1 -#define CONNCTRL_STREAM 2 - -void Curl_conncontrol(struct connectdata *conn, - int ctrl -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - , const char *reason -#endif - ); - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) -#define streamclose(x, y) Curl_conncontrol(x, CONNCTRL_STREAM, y) -#define connclose(x, y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y) -#define connkeep(x, y) Curl_conncontrol(x, CONNCTRL_KEEP, y) -#else /* !DEBUGBUILD || !CURLVERBOSE */ -#define streamclose(x, y) Curl_conncontrol(x, CONNCTRL_STREAM) -#define connclose(x, y) Curl_conncontrol(x, CONNCTRL_CONNECTION) -#define connkeep(x, y) Curl_conncontrol(x, CONNCTRL_KEEP) -#endif - -CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - uint8_t transport, - int ssl_mode); - -/** - * Setup the cfilters at `sockindex` in connection `conn`. - * If no filter chain is installed yet, inspects the configuration - * in `data` and `conn? to install a suitable filter chain. - */ -CURLcode Curl_conn_setup(struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - struct Curl_dns_entry *dns, - int ssl_mode); - -/* Set conn to allow multiplexing. */ -void Curl_conn_set_multiplex(struct connectdata *conn); - -#ifdef USE_UNIX_SOCKETS -#ifndef CURL_DISABLE_PROXY -#define UNIX_SOCKET_PREFIX "localhost" -#endif -const char *Curl_conn_get_unix_path(struct connectdata *conn); -#else -#define Curl_conn_get_unix_path(c) NULL -#endif - -extern struct Curl_cftype Curl_cft_setup; - -#endif /* HEADER_CURL_CONNECT_H */ diff --git a/vendor/curl/lib/content_encoding.c b/vendor/curl/lib/content_encoding.c deleted file mode 100644 index 0224a8bfe..000000000 --- a/vendor/curl/lib/content_encoding.c +++ /dev/null @@ -1,824 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "curlx/dynbuf.h" - -#ifdef HAVE_LIBZ -#include -#endif - -#ifdef HAVE_BROTLI -#ifdef CURL_HAVE_DIAG -/* Ignore -Wvla warnings in brotli headers */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wvla" -#endif -#include -#ifdef CURL_HAVE_DIAG -#pragma GCC diagnostic pop -#endif -#endif - -#ifdef HAVE_ZSTD -#include -#endif - -#include "sendf.h" -#include "curl_trc.h" -#include "content_encoding.h" - -#define CONTENT_ENCODING_DEFAULT "identity" - -#ifndef CURL_DISABLE_HTTP - -/* allow no more than 5 "chained" compression steps */ -#define MAX_ENCODE_STACK 5 - -#if defined(HAVE_LIBZ) || defined(HAVE_BROTLI) || defined(HAVE_ZSTD) -#define DECOMPRESS_BUFFER_SIZE 16384 /* buffer size for decompressed data */ -#endif - -#ifdef HAVE_LIBZ - -#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1252) -#error "requires zlib 1.2.5.2 or newer" -#endif - -typedef enum { - ZLIB_UNINIT, /* uninitialized */ - ZLIB_INIT, /* initialized */ - ZLIB_INFLATING, /* inflating started. */ - ZLIB_EXTERNAL_TRAILER, /* reading external trailer */ - ZLIB_INIT_GZIP /* initialized in transparent gzip mode */ -} zlibInitState; - -/* Deflate and gzip writer. */ -struct zlib_writer { - struct Curl_cwriter super; - zlibInitState zlib_init; /* zlib init state */ - char buffer[DECOMPRESS_BUFFER_SIZE]; /* Put the decompressed data here. */ - uInt trailerlen; /* Remaining trailer byte count. */ - z_stream z; /* State structure for zlib. */ -}; - -static voidpf zalloc_cb(voidpf opaque, unsigned int items, unsigned int size) -{ - (void)opaque; - /* not a typo, keep it curlx_calloc() */ - return (voidpf)curlx_calloc(items, size); -} - -static void zfree_cb(voidpf opaque, voidpf ptr) -{ - (void)opaque; - curlx_free(ptr); -} - -static CURLcode process_zlib_error(struct Curl_easy *data, z_stream *z) -{ - if(z->msg) - failf(data, "Error while processing content unencoding: %s", - z->msg); - else - failf(data, "Error while processing content unencoding: " - "Unknown failure within decompression software."); - - return CURLE_BAD_CONTENT_ENCODING; -} - -static CURLcode exit_zlib(struct Curl_easy *data, z_stream *z, - zlibInitState *zlib_init, CURLcode result) -{ - if(*zlib_init != ZLIB_UNINIT) { - if(inflateEnd(z) != Z_OK && result == CURLE_OK) - result = process_zlib_error(data, z); - *zlib_init = ZLIB_UNINIT; - } - - return result; -} - -static CURLcode process_trailer(struct Curl_easy *data, struct zlib_writer *zp) -{ - z_stream *z = &zp->z; - CURLcode result = CURLE_OK; - uInt len = z->avail_in < zp->trailerlen ? z->avail_in : zp->trailerlen; - - /* Consume expected trailer bytes. Terminate stream if exhausted. - Issue an error if unexpected bytes follow. */ - - zp->trailerlen -= len; - z->avail_in -= len; - z->next_in += len; - if(z->avail_in) - result = CURLE_WRITE_ERROR; - if(result || !zp->trailerlen) - result = exit_zlib(data, z, &zp->zlib_init, result); - else { - /* Only occurs for gzip with zlib < 1.2.0.4 or raw deflate. */ - zp->zlib_init = ZLIB_EXTERNAL_TRAILER; - } - return result; -} - -static CURLcode inflate_stream(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - zlibInitState started) -{ - struct zlib_writer *zp = (struct zlib_writer *)writer; - z_stream *z = &zp->z; /* zlib state structure */ - uInt nread = z->avail_in; - z_const Bytef *orig_in = z->next_in; - bool done = FALSE; - CURLcode result = CURLE_OK; /* Curl_client_write status */ - - /* Check state. */ - if(zp->zlib_init != ZLIB_INIT && - zp->zlib_init != ZLIB_INFLATING && - zp->zlib_init != ZLIB_INIT_GZIP) - return exit_zlib(data, z, &zp->zlib_init, CURLE_WRITE_ERROR); - - /* because the buffer size is fixed, iteratively decompress and transfer to - the client via next_write function. */ - while(!done) { - int status; /* zlib status */ - done = TRUE; - - /* (re)set buffer for decompressed output for every iteration */ - z->next_out = (Bytef *)zp->buffer; - z->avail_out = DECOMPRESS_BUFFER_SIZE; - - status = inflate(z, Z_BLOCK); - - /* Flush output data if some. */ - if(z->avail_out != DECOMPRESS_BUFFER_SIZE) { - if(status == Z_OK || status == Z_STREAM_END) { - zp->zlib_init = started; /* Data started. */ - result = Curl_cwriter_write(data, writer->next, type, zp->buffer, - DECOMPRESS_BUFFER_SIZE - z->avail_out); - if(result) { - exit_zlib(data, z, &zp->zlib_init, result); - break; - } - } - } - - /* Dispatch by inflate() status. */ - switch(status) { - case Z_OK: - /* Always loop: there may be unflushed latched data in zlib state. */ - done = FALSE; - break; - case Z_BUF_ERROR: - /* No more data to flush: exit loop. */ - break; - case Z_STREAM_END: - result = process_trailer(data, zp); - break; - case Z_DATA_ERROR: - /* some servers seem to not generate zlib headers, so this is an attempt - to fix and continue anyway */ - if(zp->zlib_init == ZLIB_INIT) { - if(inflateReset2(z, -MAX_WBITS) == Z_OK) { - z->next_in = orig_in; - z->avail_in = nread; - zp->zlib_init = ZLIB_INFLATING; - zp->trailerlen = 4; /* Tolerate up to 4 unknown trailer bytes. */ - done = FALSE; - break; - } - zp->zlib_init = ZLIB_UNINIT; /* inflateEnd() already called. */ - } - result = exit_zlib(data, z, &zp->zlib_init, process_zlib_error(data, z)); - break; - default: - result = exit_zlib(data, z, &zp->zlib_init, process_zlib_error(data, z)); - break; - } - } - - /* We are about to leave this call so the `nread' data bytes will not be seen - again. If we are in a state that would wrongly allow restart in raw mode - at the next call, assume output has already started. */ - if(nread && zp->zlib_init == ZLIB_INIT) - zp->zlib_init = started; /* Cannot restart anymore. */ - - return result; -} - -/* Deflate handler. */ -static CURLcode deflate_do_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct zlib_writer *zp = (struct zlib_writer *)writer; - z_stream *z = &zp->z; /* zlib state structure */ - - /* Initialize zlib */ - z->zalloc = (alloc_func)zalloc_cb; - z->zfree = (free_func)zfree_cb; - - if(inflateInit(z) != Z_OK) - return process_zlib_error(data, z); - zp->zlib_init = ZLIB_INIT; - return CURLE_OK; -} - -static CURLcode deflate_do_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - struct zlib_writer *zp = (struct zlib_writer *)writer; - z_stream *z = &zp->z; /* zlib state structure */ - - if(!(type & CLIENTWRITE_BODY) || !nbytes) - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - - /* Set the compressed input when this function is called */ - z->next_in = (z_const Bytef *)buf; - z->avail_in = (uInt)nbytes; - - if(zp->zlib_init == ZLIB_EXTERNAL_TRAILER) - return process_trailer(data, zp); - - /* Now uncompress the data */ - return inflate_stream(data, writer, type, ZLIB_INFLATING); -} - -static void deflate_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct zlib_writer *zp = (struct zlib_writer *)writer; - z_stream *z = &zp->z; /* zlib state structure */ - - exit_zlib(data, z, &zp->zlib_init, CURLE_OK); -} - -static const struct Curl_cwtype deflate_encoding = { - "deflate", - NULL, - deflate_do_init, - deflate_do_write, - deflate_do_close, - sizeof(struct zlib_writer) -}; - -/* - * Gzip handler. - */ - -static CURLcode gzip_do_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct zlib_writer *zp = (struct zlib_writer *)writer; - z_stream *z = &zp->z; /* zlib state structure */ - - /* Initialize zlib */ - z->zalloc = (alloc_func)zalloc_cb; - z->zfree = (free_func)zfree_cb; - - if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) - return process_zlib_error(data, z); - - zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ - return CURLE_OK; -} - -static CURLcode gzip_do_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - struct zlib_writer *zp = (struct zlib_writer *)writer; - z_stream *z = &zp->z; /* zlib state structure */ - - if(!(type & CLIENTWRITE_BODY) || !nbytes) - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - - if(zp->zlib_init == ZLIB_INIT_GZIP) { - /* Let zlib handle the gzip decompression entirely */ - z->next_in = (z_const Bytef *)buf; - z->avail_in = (uInt)nbytes; - /* Now uncompress the data */ - return inflate_stream(data, writer, type, ZLIB_INIT_GZIP); - } - - /* We are running with an old version: return error. */ - return exit_zlib(data, z, &zp->zlib_init, CURLE_WRITE_ERROR); -} - -static void gzip_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct zlib_writer *zp = (struct zlib_writer *)writer; - z_stream *z = &zp->z; /* zlib state structure */ - - exit_zlib(data, z, &zp->zlib_init, CURLE_OK); -} - -static const struct Curl_cwtype gzip_encoding = { - "gzip", - "x-gzip", - gzip_do_init, - gzip_do_write, - gzip_do_close, - sizeof(struct zlib_writer) -}; - -#endif /* HAVE_LIBZ */ - -#ifdef HAVE_BROTLI -/* Brotli writer. */ -struct brotli_writer { - struct Curl_cwriter super; - char buffer[DECOMPRESS_BUFFER_SIZE]; - BrotliDecoderState *br; /* State structure for brotli. */ -}; - -static CURLcode brotli_map_error(BrotliDecoderErrorCode be) -{ - switch(be) { - case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: - case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: - case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: - case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: - case BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: - case BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: - case BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: - case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: - case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: - case BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: - case BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: - case BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: - case BROTLI_DECODER_ERROR_FORMAT_PADDING_1: - case BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -#ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY /* brotli v1.1.0+ */ - case BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY: -#endif - case BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: - case BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: - return CURLE_BAD_CONTENT_ENCODING; - case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: - case BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: - case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: - case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: - case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: - case BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: - return CURLE_OUT_OF_MEMORY; - default: - break; - } - return CURLE_WRITE_ERROR; -} - -static CURLcode brotli_do_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct brotli_writer *bp = (struct brotli_writer *)writer; - (void)data; - - bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL); - return bp->br ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} - -static CURLcode brotli_do_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - struct brotli_writer *bp = (struct brotli_writer *)writer; - const uint8_t *src = (const uint8_t *)buf; - uint8_t *dst; - size_t dstleft; - CURLcode result = CURLE_OK; - BrotliDecoderResult r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; - - if(!(type & CLIENTWRITE_BODY) || !nbytes) - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - - if(!bp->br) - return CURLE_WRITE_ERROR; /* Stream already ended. */ - - while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) && - result == CURLE_OK) { - dst = (uint8_t *)bp->buffer; - dstleft = DECOMPRESS_BUFFER_SIZE; - r = BrotliDecoderDecompressStream(bp->br, - &nbytes, &src, &dstleft, &dst, NULL); - result = Curl_cwriter_write(data, writer->next, type, - bp->buffer, DECOMPRESS_BUFFER_SIZE - dstleft); - if(result) - break; - switch(r) { - case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: - case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: - break; - case BROTLI_DECODER_RESULT_SUCCESS: - BrotliDecoderDestroyInstance(bp->br); - bp->br = NULL; - if(nbytes) - result = CURLE_WRITE_ERROR; - break; - default: - result = brotli_map_error(BrotliDecoderGetErrorCode(bp->br)); - break; - } - } - return result; -} - -static void brotli_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct brotli_writer *bp = (struct brotli_writer *)writer; - (void)data; - - if(bp->br) { - BrotliDecoderDestroyInstance(bp->br); - bp->br = NULL; - } -} - -static const struct Curl_cwtype brotli_encoding = { - "br", - NULL, - brotli_do_init, - brotli_do_write, - brotli_do_close, - sizeof(struct brotli_writer) -}; -#endif - -#ifdef HAVE_ZSTD -/* Zstd writer. */ -struct zstd_writer { - struct Curl_cwriter super; - ZSTD_DStream *zds; /* State structure for zstd. */ - char buffer[DECOMPRESS_BUFFER_SIZE]; -}; - -#ifdef ZSTD_STATIC_LINKING_ONLY -static void *Curl_zstd_alloc(void *opaque, size_t size) -{ - (void)opaque; - return Curl_cmalloc(size); -} - -static void Curl_zstd_free(void *opaque, void *address) -{ - (void)opaque; - Curl_cfree(address); -} -#endif - -static CURLcode zstd_do_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct zstd_writer *zp = (struct zstd_writer *)writer; - - (void)data; - -#ifdef ZSTD_STATIC_LINKING_ONLY - zp->zds = ZSTD_createDStream_advanced((ZSTD_customMem) { - .customAlloc = Curl_zstd_alloc, - .customFree = Curl_zstd_free, - .opaque = NULL - }); -#else - zp->zds = ZSTD_createDStream(); -#endif - - return zp->zds ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} - -static CURLcode zstd_do_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - CURLcode result = CURLE_OK; - struct zstd_writer *zp = (struct zstd_writer *)writer; - ZSTD_inBuffer in; - ZSTD_outBuffer out; - size_t errorCode; - - if(!(type & CLIENTWRITE_BODY) || !nbytes) - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - - in.pos = 0; - in.src = buf; - in.size = nbytes; - - for(;;) { - out.pos = 0; - out.dst = zp->buffer; - out.size = DECOMPRESS_BUFFER_SIZE; - - errorCode = ZSTD_decompressStream(zp->zds, &out, &in); - if(ZSTD_isError(errorCode)) { - return CURLE_BAD_CONTENT_ENCODING; - } - if(out.pos > 0) { - result = Curl_cwriter_write(data, writer->next, type, - zp->buffer, out.pos); - if(result) - break; - } - if((in.pos == nbytes) && (out.pos < out.size)) - break; - } - - return result; -} - -static void zstd_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct zstd_writer *zp = (struct zstd_writer *)writer; - (void)data; - - if(zp->zds) { - ZSTD_freeDStream(zp->zds); - zp->zds = NULL; - } -} - -static const struct Curl_cwtype zstd_encoding = { - "zstd", - NULL, - zstd_do_init, - zstd_do_write, - zstd_do_close, - sizeof(struct zstd_writer) -}; -#endif - -/* Identity handler. */ -static const struct Curl_cwtype identity_encoding = { - "identity", - "none", - Curl_cwriter_def_init, - Curl_cwriter_def_write, - Curl_cwriter_def_close, - sizeof(struct Curl_cwriter) -}; - -/* supported general content decoders. */ -static const struct Curl_cwtype * const general_unencoders[] = { - &identity_encoding, -#ifdef HAVE_LIBZ - &deflate_encoding, - &gzip_encoding, -#endif -#ifdef HAVE_BROTLI - &brotli_encoding, -#endif -#ifdef HAVE_ZSTD - &zstd_encoding, -#endif - NULL -}; - -/* supported content decoders only for transfer encodings */ -static const struct Curl_cwtype * const transfer_unencoders[] = { - &Curl_httpchunk_unencoder, - NULL -}; - -/* Return the list of comma-separated names of supported encodings. - */ -char *Curl_get_content_encodings(void) -{ - struct dynbuf enc; - const struct Curl_cwtype * const *cep; - CURLcode result = CURLE_OK; - curlx_dyn_init(&enc, 255); - - for(cep = general_unencoders; *cep && !result; cep++) { - const struct Curl_cwtype *ce = *cep; - if(!curl_strequal(ce->name, CONTENT_ENCODING_DEFAULT)) { - if(curlx_dyn_len(&enc)) - result = curlx_dyn_addn(&enc, ", ", 2); - if(!result) - result = curlx_dyn_add(&enc, ce->name); - } - } - if(!result && !curlx_dyn_len(&enc)) - result = curlx_dyn_add(&enc, CONTENT_ENCODING_DEFAULT); - - if(!result) - return curlx_dyn_ptr(&enc); - return NULL; -} - -/* Deferred error dummy writer. */ -static CURLcode error_do_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - (void)data; - (void)writer; - return CURLE_OK; -} - -static CURLcode error_do_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - (void)writer; - (void)buf; - (void)nbytes; - - if(!(type & CLIENTWRITE_BODY) || !nbytes) - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - failf(data, "Unrecognized content encoding type"); - return CURLE_BAD_CONTENT_ENCODING; -} - -static void error_do_close(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - (void)data; - (void)writer; -} - -static const struct Curl_cwtype error_writer = { - "ce-error", - NULL, - error_do_init, - error_do_write, - error_do_close, - sizeof(struct Curl_cwriter) -}; - -/* Find the content encoding by name. */ -static const struct Curl_cwtype *find_unencode_writer(const char *name, - size_t len, - Curl_cwriter_phase phase) -{ - const struct Curl_cwtype * const *cep; - - if(phase == CURL_CW_TRANSFER_DECODE) { - for(cep = transfer_unencoders; *cep; cep++) { - const struct Curl_cwtype *ce = *cep; - if((curl_strnequal(name, ce->name, len) && !ce->name[len]) || - (ce->alias && curl_strnequal(name, ce->alias, len) && - !ce->alias[len])) - return ce; - } - } - /* look among the general decoders */ - for(cep = general_unencoders; *cep; cep++) { - const struct Curl_cwtype *ce = *cep; - if((curl_strnequal(name, ce->name, len) && !ce->name[len]) || - (ce->alias && curl_strnequal(name, ce->alias, len) && !ce->alias[len])) - return ce; - } - return NULL; -} - -/* Setup the unencoding stack from the Content-Encoding header value. - * See RFC 7231 section 3.1.2.2. */ -CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, - const char *enclist, int is_transfer) -{ - Curl_cwriter_phase phase = is_transfer ? - CURL_CW_TRANSFER_DECODE : CURL_CW_CONTENT_DECODE; - CURLcode result; - bool has_chunked = FALSE; - - do { - const char *name; - size_t namelen; - bool is_chunked = FALSE; - - /* Parse a single encoding name. */ - while(ISBLANK(*enclist) || *enclist == ',') - enclist++; - - name = enclist; - - for(namelen = 0; *enclist && *enclist != ','; enclist++) - if(*enclist > ' ') - namelen = enclist - name + 1; - - if(namelen) { - const struct Curl_cwtype *cwt; - struct Curl_cwriter *writer; - - CURL_TRC_WRITE(data, "looking for %s decoder: %.*s", - is_transfer ? "transfer" : "content", (int)namelen, name); - is_chunked = (is_transfer && (namelen == 7) && - curl_strnequal(name, "chunked", 7)); - /* if we skip the decoding in this phase, do not look further. - * Exception is "chunked" transfer-encoding which always must happen */ - if((is_transfer && !data->set.http_transfer_encoding && !is_chunked) || - (!is_transfer && data->set.http_ce_skip)) { - bool is_identity = curl_strnequal(name, "identity", 8); - /* not requested, ignore */ - CURL_TRC_WRITE(data, "decoder not requested, ignored: %.*s", - (int)namelen, name); - if(is_transfer && !data->set.http_te_skip) { - if(has_chunked) - failf(data, "A Transfer-Encoding (%.*s) was listed after chunked", - (int)namelen, name); - else if(is_identity) - continue; - else - failf(data, "Unsolicited Transfer-Encoding (%.*s) found", - (int)namelen, name); - return CURLE_BAD_CONTENT_ENCODING; - } - return CURLE_OK; - } - - if(Curl_cwriter_count(data, phase) + 1 >= MAX_ENCODE_STACK) { - failf(data, "Reject response due to more than %d content encodings", - MAX_ENCODE_STACK); - return CURLE_BAD_CONTENT_ENCODING; - } - - cwt = find_unencode_writer(name, namelen, phase); - if(cwt && is_chunked && Curl_cwriter_get_by_type(data, cwt)) { - /* A 'chunked' transfer encoding has already been added. - * Ignore duplicates. See #13451. - * Also RFC 9112, ch. 6.1: - * "A sender MUST NOT apply the chunked transfer coding more than - * once to a message body." - */ - CURL_TRC_WRITE(data, "ignoring duplicate 'chunked' decoder"); - return CURLE_OK; - } - - if(is_transfer && !is_chunked && - Curl_cwriter_get_by_name(data, "chunked")) { - /* RFC 9112, ch. 6.1: - * "If any transfer coding other than chunked is applied to a - * response's content, the sender MUST either apply chunked as the - * final transfer coding or terminate the message by closing the - * connection." - * "chunked" must be the last added to be the first in its phase, - * reject this. - */ - failf(data, "Reject response due to 'chunked' not being the last " - "Transfer-Encoding"); - return CURLE_BAD_CONTENT_ENCODING; - } - - if(!cwt) - cwt = &error_writer; /* Defer error at use. */ - - result = Curl_cwriter_create(&writer, data, cwt, phase); - CURL_TRC_WRITE(data, "added %s decoder %s -> %d", - is_transfer ? "transfer" : "content", cwt->name, result); - if(result) - return result; - - result = Curl_cwriter_add(data, writer); - if(result) { - Curl_cwriter_free(data, writer); - return result; - } - if(is_chunked) - has_chunked = TRUE; - } - } while(*enclist); - - return CURLE_OK; -} - -#else -/* Stubs for builds without HTTP. */ -CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, - const char *enclist, int is_transfer) -{ - (void)data; - (void)enclist; - (void)is_transfer; - return CURLE_NOT_BUILT_IN; -} - -char *Curl_get_content_encodings(void) -{ - return curlx_strdup(CONTENT_ENCODING_DEFAULT); -} - -#endif /* CURL_DISABLE_HTTP */ diff --git a/vendor/curl/lib/content_encoding.h b/vendor/curl/lib/content_encoding.h deleted file mode 100644 index e84a73976..000000000 --- a/vendor/curl/lib/content_encoding.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HEADER_CURL_CONTENT_ENCODING_H -#define HEADER_CURL_CONTENT_ENCODING_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_cwriter; - -/* returns an allocated string or NULL */ -char *Curl_get_content_encodings(void); - -CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, - const char *enclist, int is_transfer); -#endif /* HEADER_CURL_CONTENT_ENCODING_H */ diff --git a/vendor/curl/lib/cookie.c b/vendor/curl/lib/cookie.c deleted file mode 100644 index 0f822ea7c..000000000 --- a/vendor/curl/lib/cookie.c +++ /dev/null @@ -1,1644 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - -#include "urldata.h" -#include "cookie.h" -#include "psl.h" -#include "curl_trc.h" -#include "slist.h" -#include "curl_share.h" -#include "strcase.h" -#include "curl_fopen.h" -#include "curl_get_line.h" -#include "curl_memrchr.h" -#include "parsedate.h" -#include "curlx/strdup.h" -#include "llist.h" -#include "curlx/strparse.h" - -/* number of seconds in 400 days */ -#define COOKIES_MAXAGE (400 * 24 * 3600) - -/* Make sure cookies never expire further away in time than 400 days into the - future. (from RFC6265bis draft-19) - - For the sake of easier testing, align the capped time to an even 60 second - boundary. -*/ -static void cap_expires(time_t now, struct Cookie *co) -{ - if(co->expires && (TIME_T_MAX - COOKIES_MAXAGE - 30) > now) { - timediff_t cap = now + COOKIES_MAXAGE; - if(co->expires > cap) { - cap += 30; - co->expires = (cap / 60) * 60; - } - } -} - -static void freecookie(struct Cookie *co, bool maintoo) -{ - curlx_free(co->domain); - curlx_free(co->path); - curlx_free(co->name); - curlx_free(co->value); - if(maintoo) - curlx_free(co); -} - -static bool cookie_tailmatch(const char *cookie_domain, - size_t cookie_domain_len, - const char *hostname) -{ - size_t hostname_len = strlen(hostname); - - if(hostname_len < cookie_domain_len) - return FALSE; - - if(!curl_strnequal(cookie_domain, - hostname + hostname_len - cookie_domain_len, - cookie_domain_len)) - return FALSE; - - /* - * A lead char of cookie_domain is not '.'. - * RFC6265 4.1.2.3. The Domain Attribute says: - * For example, if the value of the Domain attribute is - * "example.com", the user agent will include the cookie in the Cookie - * header when making HTTP requests to example.com, www.example.com, and - * www.corp.example.com. - */ - if(hostname_len == cookie_domain_len) - return TRUE; - if('.' == *(hostname + hostname_len - cookie_domain_len - 1)) - return TRUE; - return FALSE; -} - -/* - * matching cookie path and URL path - * RFC6265 5.1.4 Paths and Path-Match - */ -static bool pathmatch(const char *cookie_path, const char *uri_path) -{ - size_t cookie_path_len; - size_t uri_path_len; - bool ret = FALSE; - - /* cookie_path must not have last '/' separator. ex: /sample */ - cookie_path_len = strlen(cookie_path); - if(cookie_path_len == 1) { - /* cookie_path must be '/' */ - return TRUE; - } - - /* #-fragments are already cut off! */ - if(strlen(uri_path) == 0 || uri_path[0] != '/') - uri_path = "/"; - - /* - * here, RFC6265 5.1.4 says - * 4. Output the characters of the uri-path from the first character up - * to, but not including, the right-most %x2F ("/"). - * but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site - * without redirect. - * Ignore this algorithm because /hoge is uri path for this case - * (uri path is not /). - */ - - uri_path_len = strlen(uri_path); - - if(uri_path_len < cookie_path_len) - goto pathmatched; - - /* not using checkprefix() because matching should be case-sensitive */ - if(strncmp(cookie_path, uri_path, cookie_path_len)) - goto pathmatched; - - /* The cookie-path and the uri-path are identical. */ - if(cookie_path_len == uri_path_len) { - ret = TRUE; - goto pathmatched; - } - - /* here, cookie_path_len < uri_path_len */ - if(uri_path[cookie_path_len] == '/') { - ret = TRUE; - goto pathmatched; - } - -pathmatched: - return ret; -} - -/* - * Return the top-level domain, for optimal hashing. - */ -static const char *get_top_domain(const char * const domain, size_t *outlen) -{ - size_t len = 0; - const char *first = NULL, *last; - - if(domain) { - len = strlen(domain); - last = memrchr(domain, '.', len); - if(last) { - first = memrchr(domain, '.', (last - domain)); - if(first) - len -= (++first - domain); - } - } - - if(outlen) - *outlen = len; - - return first ? first : domain; -} - -/* Avoid C1001, an "internal error" with MSVC14 */ -#if defined(_MSC_VER) && (_MSC_VER == 1900) -#pragma optimize("", off) -#endif - -/* - * A case-insensitive hash for the cookie domains. - */ -static size_t cookie_hash_domain(const char *domain, const size_t len) -{ - const char *end = domain + len; - size_t h = 5381; - - while(domain < end) { - size_t j = (size_t)Curl_raw_toupper(*domain++); - h += h << 5; - h ^= j; - } - - return (h % COOKIE_HASH_SIZE); -} - -#if defined(_MSC_VER) && (_MSC_VER == 1900) -#pragma optimize("", on) -#endif - -/* - * Hash this domain. - */ -static size_t cookiehash(const char * const domain) -{ - const char *top; - size_t len; - - if(!domain || Curl_host_is_ipnum(domain)) - return 0; - - top = get_top_domain(domain, &len); - return cookie_hash_domain(top, len); -} - -/* - * cookie path sanitize - */ -static char *sanitize_cookie_path(const char *cookie_path, size_t len) -{ - /* some sites send path attribute within '"'. */ - if(len && (cookie_path[0] == '\"')) { - cookie_path++; - len--; - - if(len && (cookie_path[len - 1] == '\"')) - len--; - } - - /* RFC6265 5.2.4 The Path Attribute */ - if(!len || (cookie_path[0] != '/')) - /* Let cookie-path be the default-path. */ - return curlx_strdup("/"); - - /* remove trailing slash when path is non-empty */ - /* convert /hoge/ to /hoge */ - if(len > 1 && cookie_path[len - 1] == '/') - len--; - - return curlx_memdup0(cookie_path, len); -} - -/* - * strstore - * - * A thin wrapper around strdup which ensures that any memory allocated at - * *str will be freed before the string allocated by strdup is stored there. - * The intended usecase is repeated assignments to the same variable during - * parsing in a last-wins scenario. The caller is responsible for checking - * for OOM errors. - */ -static CURLcode strstore(char **str, const char *newstr, size_t len) -{ - DEBUGASSERT(str); - if(!len) { - len++; - newstr = ""; - } - *str = curlx_memdup0(newstr, len); - if(!*str) - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -} - -/* - * remove_expired - * - * Remove expired cookies from the hash by inspecting the expires timestamp on - * each cookie in the hash, freeing and deleting any where the timestamp is in - * the past. If the cookiejar has recorded the next timestamp at which one or - * more cookies expire, then processing will exit early in case this timestamp - * is in the future. - */ -static void remove_expired(struct CookieInfo *ci) -{ - struct Cookie *co; - curl_off_t now = (curl_off_t)time(NULL); - unsigned int i; - - /* - * If the earliest expiration timestamp in the jar is in the future we can - * skip scanning the whole jar and instead exit early as there will not be - * any cookies to evict. If we need to evict, reset the next_expiration - * counter in order to track the next one. In case the recorded first - * expiration is the max offset, then perform the safe fallback of checking - * all cookies. - */ - if(now < ci->next_expiration && - ci->next_expiration != CURL_OFF_T_MAX) - return; - else - ci->next_expiration = CURL_OFF_T_MAX; - - for(i = 0; i < COOKIE_HASH_SIZE; i++) { - struct Curl_llist_node *n; - struct Curl_llist_node *e = NULL; - - for(n = Curl_llist_head(&ci->cookielist[i]); n; n = e) { - co = Curl_node_elem(n); - e = Curl_node_next(n); - if(co->expires) { - if(co->expires < now) { - Curl_node_remove(n); - freecookie(co, TRUE); - ci->numcookies--; - } - else if(co->expires < ci->next_expiration) - /* - * If this cookie has an expiration timestamp earlier than what we - * have seen so far then record it for the next round of expirations. - */ - ci->next_expiration = co->expires; - } - } - } -} - -#ifndef USE_LIBPSL -/* Make sure domain contains a dot or is localhost. */ -static bool bad_domain(const char *domain, size_t len) -{ - if((len == 9) && curl_strnequal(domain, "localhost", 9)) - return FALSE; - else { - /* there must be a dot present, but that dot must not be a trailing dot */ - const char *dot = memchr(domain, '.', len); - if(dot) { - size_t i = dot - domain; - if((len - i) > 1) - /* the dot is not the last byte */ - return FALSE; - } - } - return TRUE; -} -#endif - -/* - RFC 6265 section 4.1.1 says a server should accept this range: - - cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - - Yet, Firefox and Chrome as of June 2022 accept space, comma and double-quotes - fine. The prime reason for filtering out control bytes is that some HTTP - servers return 400 for requests that contain such. -*/ -static bool invalid_octets(const char *ptr, size_t len) -{ - const unsigned char *p = (const unsigned char *)ptr; - /* Reject all bytes \x01 - \x1f (*except* \x09, TAB) + \x7f */ - while(len && *p) { - if(((*p != 9) && (*p < 0x20)) || (*p == 0x7f)) - return TRUE; - p++; - len--; - } - return FALSE; -} - -/* The maximum length we accept a date string for the 'expire' keyword. The - standard date formats are within the 30 bytes range. This adds an extra - margin to make sure it realistically works with what is used out there. -*/ -#define MAX_DATE_LENGTH 80 - -#define COOKIE_NAME 0 -#define COOKIE_VALUE 1 -#define COOKIE_DOMAIN 2 -#define COOKIE_PATH 3 - -#define COOKIE_PIECES 4 /* the list above */ - -static CURLcode storecookie(struct Cookie *co, struct Curl_str *cp, - const char *path, const char *domain) -{ - CURLcode result; - result = strstore(&co->name, curlx_str(&cp[COOKIE_NAME]), - curlx_strlen(&cp[COOKIE_NAME])); - if(!result) - result = strstore(&co->value, curlx_str(&cp[COOKIE_VALUE]), - curlx_strlen(&cp[COOKIE_VALUE])); - if(!result) { - size_t plen = 0; - if(curlx_strlen(&cp[COOKIE_PATH])) { - path = curlx_str(&cp[COOKIE_PATH]); - plen = curlx_strlen(&cp[COOKIE_PATH]); - } - else if(path) { - /* No path was given in the header line, set the default */ - const char *endslash = strrchr(path, '/'); - if(endslash) - plen = endslash - path + 1; /* include end slash */ - else - plen = strlen(path); - } - - if(path) { - co->path = sanitize_cookie_path(path, plen); - if(!co->path) - result = CURLE_OUT_OF_MEMORY; - } - } - if(!result) { - if(curlx_strlen(&cp[COOKIE_DOMAIN])) - result = strstore(&co->domain, curlx_str(&cp[COOKIE_DOMAIN]), - curlx_strlen(&cp[COOKIE_DOMAIN])); - else if(domain) { - /* no domain was given in the header line, set the default */ - co->domain = curlx_strdup(domain); - if(!co->domain) - result = CURLE_OUT_OF_MEMORY; - } - } - return result; -} - -/* this function return errors on OOM etc, not on plain cookie format - problems */ -static CURLcode parse_cookie_header( - struct Curl_easy *data, - struct Cookie *co, - struct CookieInfo *ci, - bool *okay, /* if the cookie was fine */ - const char *ptr, - const char *domain, /* default domain */ - const char *path, /* full path used when this cookie is - set, used to get default path for - the cookie unless set */ - bool secure) /* TRUE if connection is over secure origin */ -{ - /* This line was read off an HTTP-header */ - time_t now = 0; - size_t linelength = strlen(ptr); - CURLcode result = CURLE_OK; - struct Curl_str cookie[COOKIE_PIECES]; - *okay = FALSE; - if(linelength > MAX_COOKIE_LINE) - /* discard overly long lines at once */ - return CURLE_OK; - - /* memset instead of initializer because gcc 4.8.1 is silly */ - memset(cookie, 0, sizeof(cookie)); - do { - struct Curl_str name; - struct Curl_str val; - - /* we have a = pair or a stand-alone word here */ - if(!curlx_str_cspn(&ptr, &name, ";\t\r\n=")) { - bool sep = FALSE; - curlx_str_trimblanks(&name); - - if(!curlx_str_single(&ptr, '=')) { - sep = TRUE; /* a '=' was used */ - if(!curlx_str_cspn(&ptr, &val, ";\r\n")) - curlx_str_trimblanks(&val); - - /* Reject cookies with a TAB inside the value */ - if(curlx_strlen(&val) && - memchr(curlx_str(&val), '\t', curlx_strlen(&val))) { - infof(data, "cookie contains TAB, dropping"); - return CURLE_OK; - } - } - else - curlx_str_init(&val); - - if(!curlx_strlen(&cookie[COOKIE_NAME])) { - /* The first name/value pair is the actual cookie name */ - if(!sep || - /* Bad name/value pair. */ - invalid_octets(curlx_str(&name), curlx_strlen(&name)) || - invalid_octets(curlx_str(&val), curlx_strlen(&val)) || - !curlx_strlen(&name)) { - infof(data, "invalid octets in name/value, cookie dropped"); - return CURLE_OK; - } - - /* - * Check for too long individual name or contents, or too long - * combination of name + contents. Chrome and Firefox support 4095 or - * 4096 bytes combo - */ - if(curlx_strlen(&name) >= (MAX_NAME - 1) || - curlx_strlen(&val) >= (MAX_NAME - 1) || - ((curlx_strlen(&name) + curlx_strlen(&val)) > MAX_NAME)) { - infof(data, "oversized cookie dropped, name/val %zu + %zu bytes", - curlx_strlen(&name), curlx_strlen(&val)); - return CURLE_OK; - } - - /* Check if we have a reserved prefix set. */ - if(!strncmp("__Secure-", curlx_str(&name), 9)) - co->prefix_secure = TRUE; - else if(!strncmp("__Host-", curlx_str(&name), 7)) - co->prefix_host = TRUE; - - cookie[COOKIE_NAME] = name; - cookie[COOKIE_VALUE] = val; - } - else if(!sep) { - /* - * this is a "" with no content - */ - - /* - * secure cookies are only allowed to be set when the connection is - * using a secure protocol, or when the cookie is being set by - * reading from file - */ - if(curlx_str_casecompare(&name, "secure")) { - if(secure || !ci->running) - co->secure = TRUE; - else { - infof(data, "skipped cookie because not 'secure'"); - return CURLE_OK; - } - } - else if(curlx_str_casecompare(&name, "httponly")) - co->httponly = TRUE; - } - else if(curlx_str_casecompare(&name, "path")) { - cookie[COOKIE_PATH] = val; - } - else if(curlx_str_casecompare(&name, "domain") && curlx_strlen(&val)) { - bool is_ip; - const char *v = curlx_str(&val); - /* - * Now, we make sure that our host is within the given domain, or - * the given domain is not valid and thus cannot be set. - */ - - if('.' == *v) - curlx_str_nudge(&val, 1); - -#ifndef USE_LIBPSL - /* - * Without PSL we do not know when the incoming cookie is set on a - * TLD or otherwise "protected" suffix. To reduce risk, we require a - * dot OR the exact hostname being "localhost". - */ - if(bad_domain(curlx_str(&val), curlx_strlen(&val))) - domain = ":"; -#endif - - is_ip = Curl_host_is_ipnum(domain ? domain : curlx_str(&val)); - - if(!domain || - (is_ip && - !strncmp(curlx_str(&val), domain, curlx_strlen(&val)) && - (curlx_strlen(&val) == strlen(domain))) || - (!is_ip && cookie_tailmatch(curlx_str(&val), - curlx_strlen(&val), domain))) { - cookie[COOKIE_DOMAIN] = val; - if(!is_ip) - co->tailmatch = TRUE; /* we always do that if the domain name was - given */ - } - else { - /* - * We did not get a tailmatch and then the attempted set domain is - * not a domain to which the current host belongs. Mark as bad. - */ - infof(data, "skipped cookie with bad tailmatch domain: %s", - curlx_str(&val)); - return CURLE_OK; - } - } - else if(curlx_str_casecompare(&name, "max-age") && curlx_strlen(&val)) { - /* - * Defined in RFC2109: - * - * Optional. The Max-Age attribute defines the lifetime of the - * cookie, in seconds. The delta-seconds value is a decimal non- - * negative integer. After delta-seconds seconds elapse, the - * client should discard the cookie. A value of zero means the - * cookie should be discarded immediately. - */ - int rc; - const char *maxage = curlx_str(&val); - if(*maxage == '\"') - maxage++; - rc = curlx_str_number(&maxage, &co->expires, CURL_OFF_T_MAX); - if(!now) - now = time(NULL); - switch(rc) { - case STRE_OVERFLOW: - /* overflow, used max value */ - co->expires = CURL_OFF_T_MAX; - break; - default: - /* negative or otherwise bad, expire */ - co->expires = 1; - break; - case STRE_OK: - if(!co->expires) - co->expires = 1; /* expire now */ - else if(CURL_OFF_T_MAX - now < co->expires) - /* would overflow */ - co->expires = CURL_OFF_T_MAX; - else - co->expires += now; - break; - } - cap_expires(now, co); - } - else if(curlx_str_casecompare(&name, "expires") && curlx_strlen(&val) && - !co->expires && (curlx_strlen(&val) < MAX_DATE_LENGTH)) { - /* - * Let max-age have priority. - * - * If the date cannot get parsed for whatever reason, the cookie - * will be treated as a session cookie - */ - char dbuf[MAX_DATE_LENGTH + 1]; - time_t date = 0; - memcpy(dbuf, curlx_str(&val), curlx_strlen(&val)); - dbuf[curlx_strlen(&val)] = 0; - if(!Curl_getdate_capped(dbuf, &date)) { - if(!date) - date++; - co->expires = (curl_off_t)date; - } - else - co->expires = 0; - if(!now) - now = time(NULL); - cap_expires(now, co); - } - } - } while(!curlx_str_single(&ptr, ';')); - - if(curlx_strlen(&cookie[COOKIE_NAME])) { - /* the header was fine, now store the data */ - result = storecookie(co, &cookie[0], path, domain); - if(!result) - *okay = TRUE; - } - return result; -} - -static CURLcode parse_netscape(struct Cookie *co, - struct CookieInfo *ci, - bool *okay, - const char *lineptr, - bool secure) /* TRUE if connection is over - secure origin */ -{ - /* - * This line is NOT an HTTP header style line, we do offer support for - * reading the odd netscape cookies-file format here - */ - const char *ptr, *next; - int fields; - size_t len; - *okay = FALSE; - - /* - * In 2008, Internet Explorer introduced HTTP-only cookies to prevent XSS - * attacks. Cookies marked httpOnly are not accessible to JavaScript. In - * Firefox's cookie files, they are prefixed #HttpOnly_ and the rest - * remains as usual, so we skip 10 characters of the line. - */ - if(strncmp(lineptr, "#HttpOnly_", 10) == 0) { - lineptr += 10; - co->httponly = TRUE; - } - - if(lineptr[0] == '#') - /* do not even try the comments */ - return CURLE_OK; - - /* - * Now loop through the fields and init the struct we already have - * allocated - */ - fields = 0; - for(next = lineptr; next; fields++) { - ptr = next; - len = strcspn(ptr, "\t\r\n"); - next = (ptr[len] == '\t' ? &ptr[len + 1] : NULL); - switch(fields) { - case 0: - if(ptr[0] == '.') { /* skip preceding dots */ - ptr++; - len--; - } - co->domain = curlx_memdup0(ptr, len); - if(!co->domain) - return CURLE_OUT_OF_MEMORY; - break; - case 1: - /* - * flag: A TRUE/FALSE value indicating if all machines within a given - * domain can access the variable. Set TRUE when the cookie says - * .example.com and to false when the domain is complete www.example.com - */ - co->tailmatch = !!curl_strnequal(ptr, "TRUE", len); - break; - case 2: - /* The file format allows the path field to remain not filled in */ - if(strncmp("TRUE", ptr, len) && strncmp("FALSE", ptr, len)) { - /* only if the path does not look like a boolean option! */ - co->path = sanitize_cookie_path(ptr, len); - if(!co->path) - return CURLE_OUT_OF_MEMORY; - break; - } - else { - /* this does not look like a path, make one up! */ - co->path = curlx_strdup("/"); - if(!co->path) - return CURLE_OUT_OF_MEMORY; - } - fields++; /* add a field and fall down to secure */ - FALLTHROUGH(); - case 3: - co->secure = FALSE; - if(curl_strnequal(ptr, "TRUE", len)) { - if(secure || ci->running) - co->secure = TRUE; - else - return CURLE_OK; - } - break; - case 4: - if(curlx_str_number(&ptr, &co->expires, CURL_OFF_T_MAX)) - return CURLE_OK; - break; - case 5: - co->name = curlx_memdup0(ptr, len); - if(!co->name) - return CURLE_OUT_OF_MEMORY; - else { - /* For Netscape file format cookies we check prefix on the name */ - if(curl_strnequal("__Secure-", co->name, 9)) - co->prefix_secure = TRUE; - else if(curl_strnequal("__Host-", co->name, 7)) - co->prefix_host = TRUE; - } - break; - case 6: - co->value = curlx_memdup0(ptr, len); - if(!co->value) - return CURLE_OUT_OF_MEMORY; - break; - } - } - if(fields == 6) { - /* we got a cookie with blank contents, fix it */ - co->value = curlx_strdup(""); - if(!co->value) - return CURLE_OUT_OF_MEMORY; - else - fields++; - } - - if(fields != 7) - /* we did not find the sufficient number of fields */ - return CURLE_OK; - - *okay = TRUE; - return CURLE_OK; -} - -static bool is_public_suffix(struct Curl_easy *data, - struct Cookie *co, - const char *domain) -{ -#ifdef USE_LIBPSL - /* - * Check if the domain is a Public Suffix and if yes, ignore the cookie. We - * must also check that the data handle is not NULL since the psl code will - * dereference it. - */ - DEBUGF(infof(data, "PSL check set-cookie '%s' for domain=%s in %s", - co->name, co->domain, domain)); - if(data && (domain && co->domain && !Curl_host_is_ipnum(co->domain))) { - bool acceptable = FALSE; - char lcase[256]; - char lcookie[256]; - size_t dlen = strlen(domain); - size_t clen = strlen(co->domain); - if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) { - const psl_ctx_t *psl = Curl_psl_use(data); - if(psl) { - /* the PSL check requires lowercase domain name and pattern */ - Curl_strntolower(lcase, domain, dlen + 1); - Curl_strntolower(lcookie, co->domain, clen + 1); - acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie); - Curl_psl_release(data); - } - else - infof(data, "libpsl problem, rejecting cookie for safety"); - } - - if(!acceptable) { - infof(data, "cookie '%s' dropped, domain '%s' must not " - "set cookies for '%s'", co->name, domain, co->domain); - return TRUE; - } - } -#else - (void)data; - (void)co; - (void)domain; - DEBUGF(infof(data, "NO PSL to check set-cookie '%s' for domain=%s in %s", - co->name, co->domain, domain)); -#endif - return FALSE; -} - -/* returns TRUE when replaced */ -static bool replace_existing(struct Curl_easy *data, - struct Cookie *co, - struct CookieInfo *ci, - bool secure, - bool *replacep) -{ - bool replace_old = FALSE; - struct Curl_llist_node *replace_n = NULL; - struct Curl_llist_node *n; - size_t myhash = cookiehash(co->domain); - for(n = Curl_llist_head(&ci->cookielist[myhash]); n; n = Curl_node_next(n)) { - struct Cookie *clist = Curl_node_elem(n); - if(!strcmp(clist->name, co->name)) { - /* the names are identical */ - bool matching_domains = FALSE; - - if(clist->domain && co->domain) { - if(curl_strequal(clist->domain, co->domain)) - /* The domains are identical */ - matching_domains = TRUE; - } - else if(!clist->domain && !co->domain) - matching_domains = TRUE; - - if(matching_domains && /* the domains were identical */ - clist->path && co->path && /* both have paths */ - clist->secure && !co->secure && !secure) { - size_t cllen; - const char *sep = NULL; - - /* - * A non-secure cookie may not overlay an existing secure cookie. - * For an existing cookie "a" with path "/login", refuse a new - * cookie "a" with for example path "/login/en", while the path - * "/loginhelper" is ok. - */ - - DEBUGASSERT(clist->path[0]); - if(clist->path[0]) - sep = strchr(clist->path + 1, '/'); - if(sep) - cllen = sep - clist->path; - else - cllen = strlen(clist->path); - - if(curl_strnequal(clist->path, co->path, cllen)) { - infof(data, "cookie '%s' for domain '%s' dropped, would " - "overlay an existing cookie", co->name, co->domain); - return FALSE; - } - } - } - - if(!replace_n && !strcmp(clist->name, co->name)) { - /* the names are identical */ - - if(clist->domain && co->domain) { - if(curl_strequal(clist->domain, co->domain) && - (clist->tailmatch == co->tailmatch)) - /* The domains are identical */ - replace_old = TRUE; - } - else if(!clist->domain && !co->domain) - replace_old = TRUE; - - if(replace_old) { - /* the domains were identical */ - - if(clist->path && co->path && - !curl_strequal(clist->path, co->path)) - replace_old = FALSE; - else if(!clist->path != !co->path) - replace_old = FALSE; - } - - if(replace_old && !co->livecookie && clist->livecookie) { - /* - * Both cookies matched fine, except that the already present cookie - * is "live", which means it was set from a header, while the new one - * was read from a file and thus is not "live". "live" cookies are - * preferred so the new cookie is freed. - */ - return FALSE; - } - if(replace_old) - replace_n = n; - } - } - if(replace_n) { - struct Cookie *repl = Curl_node_elem(replace_n); - - /* when replacing, creationtime is kept from old */ - co->creationtime = repl->creationtime; - - /* unlink the old */ - Curl_node_remove(replace_n); - - /* free the old cookie */ - freecookie(repl, TRUE); - } - *replacep = replace_old; - return TRUE; -} - -/* - * Curl_cookie_add - * - * Add a single cookie line to the cookie keeping object. Be aware that - * sometimes we get an IP-only hostname, and that might also be a numerical - * IPv6 address. - * - */ -CURLcode Curl_cookie_add( - struct Curl_easy *data, - struct CookieInfo *ci, - bool httpheader, /* TRUE if HTTP header-style line */ - bool noexpire, /* if TRUE, skip remove_expired() */ - const char *lineptr, /* first character of the line */ - const char *domain, /* default domain */ - const char *path, /* full path used when this cookie is set, used - to get default path for the cookie unless set */ - bool secure) /* TRUE if connection is over secure origin */ -{ - struct Cookie comem; - struct Cookie *co; - size_t myhash; - CURLcode result; - bool replaces = FALSE; - bool okay; - - DEBUGASSERT(data); - DEBUGASSERT(MAX_SET_COOKIE_AMOUNT <= 255); /* counter is an unsigned char */ - if(data->req.setcookies >= MAX_SET_COOKIE_AMOUNT) - return CURLE_OK; /* silently ignore */ - - co = &comem; - memset(co, 0, sizeof(comem)); - - if(httpheader) - result = parse_cookie_header(data, co, ci, &okay, - lineptr, domain, path, secure); - else - result = parse_netscape(co, ci, &okay, lineptr, secure); - - if(result || !okay) - goto fail; - - if(co->prefix_secure && !co->secure) - /* The __Secure- prefix only requires that the cookie be set secure */ - goto fail; - - if(co->prefix_host) { - /* - * The __Host- prefix requires the cookie to be secure, have a "/" path - * and not have a domain set. - */ - if(co->secure && co->path && !strcmp(co->path, "/") && !co->tailmatch) - ; - else - goto fail; - } - - if(!ci->running && /* read from a file */ - ci->newsession && /* clean session cookies */ - !co->expires) /* this is a session cookie */ - goto fail; - - co->livecookie = ci->running; - co->creationtime = ++ci->lastct; - - /* - * Now we have parsed the incoming line, we must now check if this supersedes - * an already existing cookie, which it may if the previous have the same - * domain and path as this. - */ - - /* remove expired cookies */ - if(!noexpire) - remove_expired(ci); - - if(is_public_suffix(data, co, domain)) - goto fail; - - if(!replace_existing(data, co, ci, secure, &replaces)) - goto fail; - - /* clone the stack struct into heap */ - co = curlx_memdup(&comem, sizeof(comem)); - if(!co) { - co = &comem; - result = CURLE_OUT_OF_MEMORY; - goto fail; /* bail out if we are this low on memory */ - } - - /* add this cookie to the list */ - myhash = cookiehash(co->domain); - Curl_llist_append(&ci->cookielist[myhash], co, &co->node); - - if(ci->running) - /* Only show this when NOT reading the cookies from a file */ - infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, " - "expire %" FMT_OFF_T, - replaces ? "Replaced" : "Added", co->name, co->value, - co->domain, co->path, co->expires); - - if(!replaces) - ci->numcookies++; /* one more cookie in the jar */ - - /* - * Now that we have added a new cookie to the jar, update the expiration - * tracker in case it is the next one to expire. - */ - if(co->expires && (co->expires < ci->next_expiration)) - ci->next_expiration = co->expires; - - if(httpheader) - data->req.setcookies++; - - return result; -fail: - freecookie(co, FALSE); - return result; -} - -/* - * Curl_cookie_init() - * - * Inits a cookie struct to read data from a local file. This is always - * called before any cookies are set. File may be NULL in which case only the - * struct is initialized. Is file is "-" then STDIN is read. - * - * If 'newsession' is TRUE, discard all "session cookies" on read from file. - * - * Note that 'data' might be called as NULL pointer. If data is NULL, 'file' - * will be ignored. - * - * Returns NULL on out of memory. - */ -struct CookieInfo *Curl_cookie_init(void) -{ - int i; - struct CookieInfo *ci = curlx_calloc(1, sizeof(struct CookieInfo)); - if(!ci) - return NULL; - - /* This does not use the destructor callback since we want to add - and remove to lists while keeping the cookie struct intact */ - for(i = 0; i < COOKIE_HASH_SIZE; i++) - Curl_llist_init(&ci->cookielist[i], NULL); - /* - * Initialize the next_expiration time to signal that we do not have enough - * information yet. - */ - ci->next_expiration = CURL_OFF_T_MAX; - - return ci; -} - -/* - * cookie_load() - * - * Reads cookies from a local file. This is always called before any cookies - * are set. If file is "-" then STDIN is read. - * - * If 'newsession' is TRUE, discard all "session cookies" on read from file. - * - */ -static CURLcode cookie_load(struct Curl_easy *data, const char *file, - struct CookieInfo *ci, bool newsession) -{ - FILE *handle = NULL; - CURLcode result = CURLE_OK; - FILE *fp = NULL; - DEBUGASSERT(ci); - DEBUGASSERT(data); - DEBUGASSERT(file); - - ci->newsession = newsession; /* new session? */ - ci->running = FALSE; /* this is not running, this is init */ - - if(file && *file) { - if(!strcmp(file, "-")) - fp = stdin; - else { - fp = curlx_fopen(file, "rb"); - if(!fp) - infof(data, "WARNING: failed to open cookie file \"%s\"", file); - else { - curlx_struct_stat stat; - if((curlx_fstat(fileno(fp), &stat) != -1) && S_ISDIR(stat.st_mode)) { - curlx_fclose(fp); - fp = NULL; - infof(data, "WARNING: cookie filename points to a directory: \"%s\"", - file); - } - else - handle = fp; - } - } - } - - if(fp) { - struct dynbuf buf; - bool eof = FALSE; - curlx_dyn_init(&buf, MAX_COOKIE_LINE); - do { - result = Curl_get_line(&buf, fp, &eof); - if(!result) { - const char *lineptr = curlx_dyn_ptr(&buf); - bool headerline = FALSE; - if(checkprefix("Set-Cookie:", lineptr)) { - /* This is a cookie line, get it! */ - lineptr += 11; - headerline = TRUE; - curlx_str_passblanks(&lineptr); - } - - result = Curl_cookie_add(data, ci, headerline, TRUE, lineptr, NULL, - NULL, TRUE); - /* File reading cookie failures are not propagated back to the - caller because there is no way to do that */ - } - } while(!result && !eof); - curlx_dyn_free(&buf); /* free the line buffer */ - - /* - * Remove expired cookies from the hash. We must make sure to run this - * after reading the file, and not on every cookie. - */ - remove_expired(ci); - - if(handle) - curlx_fclose(handle); - } - data->state.cookie_engine = TRUE; - ci->running = TRUE; /* now, we are running */ - - return result; -} - -/* - * Load cookies from all given cookie files (CURLOPT_COOKIEFILE). - */ -CURLcode Curl_cookie_loadfiles(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - struct curl_slist *list = data->state.cookielist; - if(list) { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(!data->cookies) - data->cookies = Curl_cookie_init(); - if(!data->cookies) - result = CURLE_OUT_OF_MEMORY; - else { - data->state.cookie_engine = TRUE; - while(list) { - result = cookie_load(data, list->data, data->cookies, - (bool)data->set.cookiesession); - if(result) - break; - list = list->next; - } - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - return result; -} - -/* - * cookie_sort - * - * Helper function to sort cookies such that the longest path gets before the - * shorter path. Path, domain and name lengths are considered in that order, - * with the creationtime as the tiebreaker. The creationtime is guaranteed to - * be unique per cookie, so we know we will get an ordering at that point. - */ -static int cookie_sort(const void *p1, const void *p2) -{ - const struct Cookie *c1 = *(const struct Cookie * const *)p1; - const struct Cookie *c2 = *(const struct Cookie * const *)p2; - size_t l1, l2; - - /* 1 - compare cookie path lengths */ - l1 = c1->path ? strlen(c1->path) : 0; - l2 = c2->path ? strlen(c2->path) : 0; - - if(l1 != l2) - return (l2 > l1) ? 1 : -1; /* avoid size_t <=> int conversions */ - - /* 2 - compare cookie domain lengths */ - l1 = c1->domain ? strlen(c1->domain) : 0; - l2 = c2->domain ? strlen(c2->domain) : 0; - - if(l1 != l2) - return (l2 > l1) ? 1 : -1; /* avoid size_t <=> int conversions */ - - /* 3 - compare cookie name lengths */ - l1 = c1->name ? strlen(c1->name) : 0; - l2 = c2->name ? strlen(c2->name) : 0; - - if(l1 != l2) - return (l2 > l1) ? 1 : -1; - - /* 4 - compare cookie creation time */ - return (c2->creationtime > c1->creationtime) ? 1 : -1; -} - -/* - * cookie_sort_ct - * - * Helper function to sort cookies according to creation time. - */ -static int cookie_sort_ct(const void *p1, const void *p2) -{ - const struct Cookie *c1 = *(const struct Cookie * const *)p1; - const struct Cookie *c2 = *(const struct Cookie * const *)p2; - - return (c2->creationtime > c1->creationtime) ? 1 : -1; -} - -bool Curl_secure_context(struct connectdata *conn, const char *host) -{ - return conn->scheme->protocol & (CURLPROTO_HTTPS | CURLPROTO_WSS) || - curl_strequal("localhost", host) || - !strcmp(host, "127.0.0.1") || - !strcmp(host, "::1"); -} - -/* - * Curl_cookie_getlist - * - * For a given host and path, return a linked list of cookies that the client - * should send to the server if used now. The secure boolean informs the cookie - * if a secure connection is achieved or not. - * - * It shall only return cookies that have not expired. - * - * 'okay' is TRUE when there is a list returned. - */ -CURLcode Curl_cookie_getlist(struct Curl_easy *data, - struct connectdata *conn, - bool *okay, - const char *host, - struct Curl_llist *list) -{ - size_t matches = 0; - const bool is_ip = Curl_host_is_ipnum(host); - const size_t myhash = cookiehash(host); - struct Curl_llist_node *n; - const bool secure = Curl_secure_context(conn, host); - struct CookieInfo *ci = data->cookies; - const char *path = data->state.up.path; - CURLcode result = CURLE_OK; - *okay = FALSE; - - Curl_llist_init(list, NULL); - - if(!ci || !Curl_llist_count(&ci->cookielist[myhash])) - return CURLE_OK; /* no cookie struct or no cookies in the struct */ - - /* at first, remove expired cookies */ - remove_expired(ci); - - for(n = Curl_llist_head(&ci->cookielist[myhash]); n; n = Curl_node_next(n)) { - struct Cookie *co = Curl_node_elem(n); - - /* if the cookie requires we are secure we must only continue if we are! */ - if(co->secure ? secure : TRUE) { - - /* now check if the domain is correct */ - if(!co->domain || - (co->tailmatch && !is_ip && - cookie_tailmatch(co->domain, strlen(co->domain), host)) || - ((!co->tailmatch || is_ip) && curl_strequal(host, co->domain))) { - /* - * the right part of the host matches the domain stuff in the - * cookie data - */ - - /* - * now check the left part of the path with the cookies path - * requirement - */ - if(!co->path || pathmatch(co->path, path)) { - - /* - * This is a match and we add it to the return-linked-list - */ - Curl_llist_append(list, co, &co->getnode); - matches++; - if(matches >= MAX_COOKIE_SEND_AMOUNT) { - infof(data, "Included max number of cookies (%zu) in request!", - matches); - break; - } - } - } - } - } - - if(matches) { - /* - * Now we need to make sure that if there is a name appearing more than - * once, the longest specified path version comes first. To make this the - * swiftest way, we sort them all based on path length. - */ - struct Cookie **array; - size_t i; - - /* alloc an array and store all cookie pointers */ - array = curlx_malloc(sizeof(struct Cookie *) * matches); - if(!array) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - n = Curl_llist_head(list); - - for(i = 0; n; n = Curl_node_next(n)) - array[i++] = Curl_node_elem(n); - - /* now sort the cookie pointers in path length order */ - qsort(array, matches, sizeof(struct Cookie *), cookie_sort); - - /* remake the linked list order according to the new order */ - Curl_llist_destroy(list, NULL); - - for(i = 0; i < matches; i++) - Curl_llist_append(list, array[i], &array[i]->getnode); - - curlx_free(array); /* remove the temporary data again */ - } - - *okay = TRUE; - return CURLE_OK; /* success */ - -fail: - /* failure, clear up the allocated chain and return NULL */ - Curl_llist_destroy(list, NULL); - return result; /* error */ -} - -/* - * Curl_cookie_clearall - * - * Clear all existing cookies and reset the counter. - */ -void Curl_cookie_clearall(struct CookieInfo *ci) -{ - if(ci) { - unsigned int i; - for(i = 0; i < COOKIE_HASH_SIZE; i++) { - struct Curl_llist_node *n; - for(n = Curl_llist_head(&ci->cookielist[i]); n;) { - struct Cookie *c = Curl_node_elem(n); - struct Curl_llist_node *e = Curl_node_next(n); - Curl_node_remove(n); - freecookie(c, TRUE); - n = e; - } - } - ci->numcookies = 0; - } -} - -/* - * Curl_cookie_clearsess - * - * Free all session cookies in the cookies list. - */ -void Curl_cookie_clearsess(struct CookieInfo *ci) -{ - unsigned int i; - - if(!ci) - return; - - for(i = 0; i < COOKIE_HASH_SIZE; i++) { - struct Curl_llist_node *n = Curl_llist_head(&ci->cookielist[i]); - struct Curl_llist_node *e = NULL; - - for(; n; n = e) { - struct Cookie *curr = Curl_node_elem(n); - e = Curl_node_next(n); /* in case the node is removed, get it early */ - if(!curr->expires) { - Curl_node_remove(n); - freecookie(curr, TRUE); - ci->numcookies--; - } - } - } -} - -/* - * Curl_cookie_cleanup() - * - * Free a "cookie object" previous created with Curl_cookie_init(). - */ -void Curl_cookie_cleanup(struct CookieInfo *ci) -{ - if(ci) { - Curl_cookie_clearall(ci); - curlx_free(ci); /* free the base struct as well */ - } -} - -/* - * get_netscape_format() - * - * Formats a string for Netscape output file, w/o a newline at the end. - * Function returns a char * to a formatted line. The caller is responsible - * for freeing the returned pointer. - */ -static char *get_netscape_format(const struct Cookie *co) -{ - return curl_maprintf( - "%s" /* httponly preamble */ - "%s%s\t" /* domain */ - "%s\t" /* tailmatch */ - "%s\t" /* path */ - "%s\t" /* secure */ - "%" FMT_OFF_T "\t" /* expires */ - "%s\t" /* name */ - "%s", /* value */ - co->httponly ? "#HttpOnly_" : "", - /* - * Make sure all domains are prefixed with a dot if they allow - * tailmatching. This is Mozilla-style. - */ - (co->tailmatch && co->domain && co->domain[0] != '.') ? "." : "", - co->domain ? co->domain : "unknown", - co->tailmatch ? "TRUE" : "FALSE", - co->path ? co->path : "/", - co->secure ? "TRUE" : "FALSE", - co->expires, - co->name, - co->value ? co->value : ""); -} - -/* - * cookie_output() - * - * Writes all internally known cookies to the specified file. Specify - * "-" as filename to write to stdout. - * - * The function returns non-zero on write failure. - */ -static CURLcode cookie_output(struct Curl_easy *data, - struct CookieInfo *ci, - const char *filename) -{ - FILE *out = NULL; - bool use_stdout = FALSE; - char *tempstore = NULL; - CURLcode result = CURLE_OK; - - if(!ci) - /* no cookie engine alive */ - return CURLE_OK; - - /* at first, remove expired cookies */ - remove_expired(ci); - - if(!strcmp("-", filename)) { - /* use stdout */ - out = stdout; - use_stdout = TRUE; - } - else { - result = Curl_fopen(data, filename, &out, &tempstore); - if(result) - goto error; - } - - fputs("# Netscape HTTP Cookie File\n" - "# https://curl.se/docs/http-cookies.html\n" - "# This file was generated by libcurl! Edit at your own risk.\n\n", - out); - - if(ci->numcookies) { - unsigned int i; - size_t nvalid = 0; - struct Cookie **array; - struct Curl_llist_node *n; - - array = curlx_calloc(1, sizeof(struct Cookie *) * ci->numcookies); - if(!array) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - /* only sort the cookies with a domain property */ - for(i = 0; i < COOKIE_HASH_SIZE; i++) { - for(n = Curl_llist_head(&ci->cookielist[i]); n; n = Curl_node_next(n)) { - struct Cookie *co = Curl_node_elem(n); - if(!co->domain) - continue; - array[nvalid++] = co; - } - } - - qsort(array, nvalid, sizeof(struct Cookie *), cookie_sort_ct); - - for(i = 0; i < nvalid; i++) { - char *format_ptr = get_netscape_format(array[i]); - if(!format_ptr) { - curlx_free(array); - result = CURLE_OUT_OF_MEMORY; - goto error; - } - curl_mfprintf(out, "%s\n", format_ptr); - curlx_free(format_ptr); - } - - curlx_free(array); - } - - if(!use_stdout) { - curlx_fclose(out); - out = NULL; - if(tempstore && curlx_rename(tempstore, filename)) { - result = CURLE_WRITE_ERROR; - goto error; - } - } - - /* - * If we reach here we have successfully written a cookie file so there is - * no need to inspect the error, any error case should have jumped into the - * error block below. - */ - curlx_free(tempstore); - return CURLE_OK; - -error: - if(out && !use_stdout) - curlx_fclose(out); - if(tempstore) { - unlink(tempstore); - curlx_free(tempstore); - } - return result; -} - -static struct curl_slist *cookie_list(struct Curl_easy *data) -{ - struct curl_slist *list = NULL; - struct curl_slist *beg; - unsigned int i; - struct Curl_llist_node *n; - - if(!data->cookies || (data->cookies->numcookies == 0)) - return NULL; - - /* at first, remove expired cookies */ - remove_expired(data->cookies); - - for(i = 0; i < COOKIE_HASH_SIZE; i++) { - for(n = Curl_llist_head(&data->cookies->cookielist[i]); n; - n = Curl_node_next(n)) { - struct Cookie *c = Curl_node_elem(n); - char *line; - if(!c->domain) - continue; - line = get_netscape_format(c); - if(!line) { - curl_slist_free_all(list); - return NULL; - } - beg = Curl_slist_append_nodup(list, line); - if(!beg) { - curlx_free(line); - curl_slist_free_all(list); - return NULL; - } - list = beg; - } - } - - return list; -} - -struct curl_slist *Curl_cookie_list(struct Curl_easy *data) -{ - struct curl_slist *list; - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - list = cookie_list(data); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - return list; -} - -void Curl_flush_cookies(struct Curl_easy *data, bool cleanup) -{ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - /* only save the cookie file if a transfer was started (cookies->running is - set), as otherwise the cookies were not completely initialized and there - might be cookie files that were not loaded so saving the file is the - wrong thing. */ - if(data->cookies) { - if(data->set.str[STRING_COOKIEJAR] && data->cookies->running) { - /* if we have a destination file for all the cookies to get dumped to */ - CURLcode result = cookie_output(data, data->cookies, - data->set.str[STRING_COOKIEJAR]); - if(result) - infof(data, "WARNING: failed to save cookies in %s: %s", - data->set.str[STRING_COOKIEJAR], curl_easy_strerror(result)); - } - - if(cleanup && (!data->share || (data->cookies != data->share->cookies))) { - Curl_cookie_cleanup(data->cookies); - data->cookies = NULL; - } - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); -} - -void Curl_cookie_run(struct Curl_easy *data) -{ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(data->cookies) - data->cookies->running = TRUE; - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); -} - -#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */ diff --git a/vendor/curl/lib/cookie.h b/vendor/curl/lib/cookie.h deleted file mode 100644 index f66e0ef59..000000000 --- a/vendor/curl/lib/cookie.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef HEADER_CURL_COOKIE_H -#define HEADER_CURL_COOKIE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "llist.h" - -struct Cookie { - struct Curl_llist_node node; /* for the main cookie list */ - struct Curl_llist_node getnode; /* for getlist */ - char *name; /* = value */ - char *value; /* name = */ - char *path; /* canonical path */ - char *domain; /* domain = */ - curl_off_t expires; /* expires = */ - unsigned int creationtime; /* time when the cookie was written */ - BIT(tailmatch); /* tail-match the domain name */ - BIT(secure); /* the 'secure' keyword was used */ - BIT(livecookie); /* updated from server, not a stored file */ - BIT(httponly); /* the httponly directive is present */ - BIT(prefix_secure); /* secure prefix is set */ - BIT(prefix_host); /* host prefix is set */ -}; - -/* - * Available cookie prefixes, as defined in - * draft-ietf-httpbis-rfc6265bis-02 - */ -#define COOKIE_PREFIX__SECURE (1 << 0) -#define COOKIE_PREFIX__HOST (1 << 1) - -#define COOKIE_HASH_SIZE 63 - -struct CookieInfo { - /* linked lists of cookies we know of */ - struct Curl_llist cookielist[COOKIE_HASH_SIZE]; - curl_off_t next_expiration; /* the next time at which expiration happens */ - unsigned int numcookies; /* number of cookies in the "jar" */ - unsigned int lastct; /* last creation-time used in the jar */ - BIT(running); /* state info, for cookie adding information */ - BIT(newsession); /* new session, discard session cookies on load */ -}; - -/* The maximum sizes we accept for cookies. RFC 6265 section 6.1 says - "general-use user agents SHOULD provide each of the following minimum - capabilities": - - - At least 4096 bytes per cookie (as measured by the sum of the length of - the cookie's name, value, and attributes). - In the 6265bis draft document section 5.4 it is phrased even stronger: "If - the sum of the lengths of the name string and the value string is more than - 4096 octets, abort these steps and ignore the set-cookie-string entirely." -*/ - -/** Limits for INCOMING cookies **/ - -/* The longest we allow a line to be when reading a cookie from an HTTP header - or from a cookie jar */ -#define MAX_COOKIE_LINE 5000 - -/* Maximum length of an incoming cookie name or content we deal with. Longer - cookies are ignored. */ -#define MAX_NAME 4096 - -/* Maximum number of Set-Cookie: lines accepted in a single response. If more - such header lines are received, they are ignored. This value must be less - than 256 since an unsigned char is used to count. */ -#define MAX_SET_COOKIE_AMOUNT 50 - -/** Limits for OUTGOING cookies **/ - -/* Maximum size for an outgoing cookie line libcurl will use in an http - request. This is the default maximum length used in some versions of Apache - httpd. */ -#define MAX_COOKIE_HEADER_LEN 8190 - -/* Maximum number of cookies libcurl will send in a single request, even if - there might be more cookies that match. One reason to cap the number is to - keep the maximum HTTP request within the maximum allowed size. */ -#define MAX_COOKIE_SEND_AMOUNT 150 - -struct Curl_easy; -struct connectdata; - -/* - * Add a cookie to the internal list of cookies. The domain and path arguments - * are only used if the header boolean is TRUE. - */ - -bool Curl_secure_context(struct connectdata *conn, const char *host); -CURLcode Curl_cookie_add(struct Curl_easy *data, - struct CookieInfo *ci, - bool httpheader, - bool noexpire, - const char *lineptr, - const char *domain, - const char *path, - bool secure) WARN_UNUSED_RESULT; -CURLcode Curl_cookie_getlist(struct Curl_easy *data, struct connectdata *conn, - bool *okay, const char *host, - struct Curl_llist *list) WARN_UNUSED_RESULT; -void Curl_cookie_clearall(struct CookieInfo *ci); -void Curl_cookie_clearsess(struct CookieInfo *ci); - -#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES) -#define Curl_cookie_list(x) NULL -#define Curl_cookie_loadfiles(x) CURLE_OK -#define Curl_cookie_init() NULL -#define Curl_cookie_run(x) Curl_nop_stmt -#define Curl_cookie_cleanup(x) Curl_nop_stmt -#define Curl_flush_cookies(x, y) Curl_nop_stmt -#else -void Curl_flush_cookies(struct Curl_easy *data, bool cleanup); -void Curl_cookie_cleanup(struct CookieInfo *ci); -struct CookieInfo *Curl_cookie_init(void); -struct curl_slist *Curl_cookie_list(struct Curl_easy *data); -CURLcode Curl_cookie_loadfiles(struct Curl_easy *data) WARN_UNUSED_RESULT; -void Curl_cookie_run(struct Curl_easy *data); -#endif - -#endif /* HEADER_CURL_COOKIE_H */ diff --git a/vendor/curl/lib/cshutdn.c b/vendor/curl/lib/cshutdn.c deleted file mode 100644 index 27b4a9f0d..000000000 --- a/vendor/curl/lib/cshutdn.c +++ /dev/null @@ -1,534 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Linus Nielsen Feltzing, - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "url.h" -#include "cfilters.h" -#include "progress.h" -#include "multiif.h" -#include "multi_ev.h" -#include "curl_trc.h" -#include "cshutdn.h" -#include "sigpipe.h" -#include "connect.h" -#include "select.h" -#include "curlx/strparse.h" - - -static void cshutdn_run_conn_handler(struct Curl_easy *data, - struct connectdata *conn) -{ - if(!conn->bits.shutdown_handler) { - - if(conn->scheme && conn->scheme->run->disconnect) { - /* Some disconnect handlers do a blocking wait on server responses. - * FTP/IMAP/SMTP and SFTP are among them. When using the internal - * handle, set an overall short timeout so we do not hang for the - * default 120 seconds. */ - if(data->state.internal) { - data->set.timeout = DEFAULT_SHUTDOWN_TIMEOUT_MS; - Curl_pgrsTime(data, TIMER_STARTOP); - } - - /* This is set if protocol-specific cleanups should be made */ - DEBUGF(infof(data, "connection #%" FMT_OFF_T - ", shutdown protocol handler (aborted=%d)", - conn->connection_id, conn->bits.aborted)); - /* There are protocol handlers that block on retrieving - * server responses here (FTP). Set a short timeout. */ - conn->scheme->run->disconnect(data, conn, (bool)conn->bits.aborted); - } - - conn->bits.shutdown_handler = TRUE; - } -} - -static void cshutdn_run_once(struct Curl_easy *data, - struct connectdata *conn, - bool *done) -{ - CURLcode r1, r2; - bool done1, done2; - - /* We expect to be attached when called */ - DEBUGASSERT(data->conn == conn); - - if(!Curl_shutdown_started(data, FIRSTSOCKET)) { - Curl_shutdown_start(data, FIRSTSOCKET, 0); - } - - cshutdn_run_conn_handler(data, conn); - - if(conn->bits.shutdown_filters) { - *done = TRUE; - return; - } - - if(!conn->bits.connect_only && Curl_conn_is_connected(conn, FIRSTSOCKET)) - r1 = Curl_conn_shutdown(data, FIRSTSOCKET, &done1); - else { - r1 = CURLE_OK; - done1 = TRUE; - } - - if(!conn->bits.connect_only && Curl_conn_is_connected(conn, SECONDARYSOCKET)) - r2 = Curl_conn_shutdown(data, SECONDARYSOCKET, &done2); - else { - r2 = CURLE_OK; - done2 = TRUE; - } - - /* we are done when any failed or both report success */ - *done = (r1 || r2 || (done1 && done2)); - if(*done) - conn->bits.shutdown_filters = TRUE; -} - -void Curl_cshutdn_run_once(struct Curl_easy *data, - struct connectdata *conn, - bool *done) -{ - DEBUGASSERT(!data->conn); - Curl_attach_connection(data, conn); - cshutdn_run_once(data, conn, done); - CURL_TRC_M(data, "[SHUTDOWN] shutdown, done=%d", *done); - Curl_detach_connection(data); -} - -void Curl_cshutdn_terminate(struct Curl_easy *data, - struct connectdata *conn, - bool do_shutdown) -{ - struct Curl_easy *admin = data; - bool done; - - /* there must be a connection to close */ - DEBUGASSERT(conn); - /* it must be removed from the connection pool */ - DEBUGASSERT(!conn->bits.in_cpool); - /* the transfer must be detached from the connection */ - DEBUGASSERT(data && !data->conn); - - /* If we can obtain an internal admin handle, use that to attach - * and terminate the connection. Some protocol will try to mess with - * `data` during shutdown and we do not want that with a `data` from - * the application. */ - if(data->multi && data->multi->admin) - admin = data->multi->admin; - - Curl_attach_connection(admin, conn); - - cshutdn_run_conn_handler(admin, conn); - if(do_shutdown) { - /* Make a last attempt to shutdown handlers and filters, if - * not done so already. */ - cshutdn_run_once(admin, conn, &done); - } - CURL_TRC_M(admin, "[SHUTDOWN] %sclosing connection #%" FMT_OFF_T, - conn->bits.shutdown_filters ? "" : "force ", - conn->connection_id); - Curl_conn_close(admin, SECONDARYSOCKET); - Curl_conn_close(admin, FIRSTSOCKET); - Curl_detach_connection(admin); - - if(data->multi) - Curl_multi_ev_conn_done(data->multi, data, conn); - Curl_conn_free(admin, conn); - - if(data->multi) { - CURL_TRC_M(data, "[SHUTDOWN] trigger multi connchanged"); - Curl_multi_connchanged(data->multi); - } -} - -static bool cshutdn_destroy_oldest(struct cshutdn *cshutdn, - struct Curl_easy *data, - const char *destination) -{ - struct Curl_llist_node *e; - struct connectdata *conn; - - e = Curl_llist_head(&cshutdn->list); - while(e) { - conn = Curl_node_elem(e); - if(!destination || !strcmp(destination, conn->destination)) - break; - e = Curl_node_next(e); - } - - if(e) { - struct Curl_sigpipe_ctx sigpipe_ctx; - conn = Curl_node_elem(e); - Curl_node_remove(e); - sigpipe_init(&sigpipe_ctx); - sigpipe_apply(data, &sigpipe_ctx); - Curl_cshutdn_terminate(data, conn, FALSE); - sigpipe_restore(&sigpipe_ctx); - return TRUE; - } - return FALSE; -} - -bool Curl_cshutdn_close_oldest(struct Curl_easy *data, - const char *destination) -{ - if(data && data->multi) { - struct cshutdn *csd = &data->multi->cshutdn; - return cshutdn_destroy_oldest(csd, data, destination); - } - return FALSE; -} - -#define NUM_POLLS_ON_STACK 10 - -static CURLcode cshutdn_wait(struct cshutdn *cshutdn, - struct Curl_easy *data, - int timeout_ms) -{ - struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; - struct curl_pollfds cpfds; - CURLcode result; - - Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK); - - result = Curl_cshutdn_add_pollfds(cshutdn, data, &cpfds); - if(result) - goto out; - - Curl_poll(cpfds.pfds, cpfds.n, CURLMIN(timeout_ms, 1000)); - -out: - Curl_pollfds_cleanup(&cpfds); - return result; -} - -static void cshutdn_perform(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct Curl_sigpipe_ctx *sigpipe_ctx) -{ - struct Curl_llist_node *e = Curl_llist_head(&cshutdn->list); - struct Curl_llist_node *enext; - struct connectdata *conn; - timediff_t next_expire_ms = 0, ms; - bool done; - - if(!e) - return; - - CURL_TRC_M(data, "[SHUTDOWN] perform on %zu connections", - Curl_llist_count(&cshutdn->list)); - sigpipe_apply(data, sigpipe_ctx); - while(e) { - enext = Curl_node_next(e); - conn = Curl_node_elem(e); - Curl_cshutdn_run_once(data, conn, &done); - if(done) { - Curl_node_remove(e); - Curl_cshutdn_terminate(data, conn, FALSE); - } - else { - /* idata has one timer list, but maybe more than one connection. - * Set EXPIRE_SHUTDOWN to the smallest time left for all. */ - ms = Curl_conn_shutdown_timeleft(data, conn); - if(ms && ms < next_expire_ms) - next_expire_ms = ms; - } - e = enext; - } - - if(next_expire_ms) - Curl_expire_ex(data, next_expire_ms, EXPIRE_SHUTDOWN); -} - -static void cshutdn_terminate_all(struct cshutdn *cshutdn, - struct Curl_easy *data, - int timeout_ms) -{ - struct curltime started = *Curl_pgrs_now(data); - struct Curl_llist_node *e; - struct Curl_sigpipe_ctx sigpipe_ctx; - - DEBUGASSERT(cshutdn); - DEBUGASSERT(data); - - CURL_TRC_M(data, "[SHUTDOWN] shutdown all"); - sigpipe_init(&sigpipe_ctx); - - while(Curl_llist_head(&cshutdn->list)) { - timediff_t spent_ms; - int remain_ms; - - cshutdn_perform(cshutdn, data, &sigpipe_ctx); - - if(!Curl_llist_head(&cshutdn->list)) { - CURL_TRC_M(data, "[SHUTDOWN] shutdown finished cleanly"); - break; - } - - /* wait for activity, timeout or "nothing" */ - spent_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &started); - if(spent_ms >= (timediff_t)timeout_ms) { - CURL_TRC_M(data, "[SHUTDOWN] shutdown finished, %s", - (timeout_ms > 0) ? "timeout" : "best effort done"); - break; - } - - remain_ms = timeout_ms - (int)spent_ms; - if(cshutdn_wait(cshutdn, data, remain_ms)) { - CURL_TRC_M(data, "[SHUTDOWN] shutdown finished, aborted"); - break; - } - } - - /* Terminate any remaining. */ - e = Curl_llist_head(&cshutdn->list); - while(e) { - struct connectdata *conn = Curl_node_elem(e); - Curl_node_remove(e); - Curl_cshutdn_terminate(data, conn, FALSE); - e = Curl_llist_head(&cshutdn->list); - } - DEBUGASSERT(!Curl_llist_count(&cshutdn->list)); - - sigpipe_restore(&sigpipe_ctx); -} - -int Curl_cshutdn_init(struct cshutdn *cshutdn, - struct Curl_multi *multi) -{ - DEBUGASSERT(multi); - cshutdn->multi = multi; - Curl_llist_init(&cshutdn->list, NULL); - cshutdn->initialised = TRUE; - return 0; /* good */ -} - -void Curl_cshutdn_destroy(struct cshutdn *cshutdn, - struct Curl_easy *data) -{ - if(cshutdn->initialised && data) { - int timeout_ms = 0; - /* for testing, run graceful shutdown */ -#ifdef DEBUGBUILD - { - const char *p = getenv("CURL_GRACEFUL_SHUTDOWN"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, INT_MAX)) - timeout_ms = (int)l; - } - } -#endif - - CURL_TRC_M(data, "[SHUTDOWN] destroy, %zu connections, timeout=%dms", - Curl_llist_count(&cshutdn->list), timeout_ms); - cshutdn_terminate_all(cshutdn, data, timeout_ms); - } - cshutdn->multi = NULL; -} - -size_t Curl_cshutdn_count(struct Curl_easy *data) -{ - if(data && data->multi) { - struct cshutdn *csd = &data->multi->cshutdn; - return Curl_llist_count(&csd->list); - } - return 0; -} - -size_t Curl_cshutdn_dest_count(struct Curl_easy *data, - const char *destination) -{ - if(data && data->multi) { - struct cshutdn *csd = &data->multi->cshutdn; - size_t n = 0; - struct Curl_llist_node *e = Curl_llist_head(&csd->list); - while(e) { - struct connectdata *conn = Curl_node_elem(e); - if(!strcmp(destination, conn->destination)) - ++n; - e = Curl_node_next(e); - } - return n; - } - return 0; -} - -static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct connectdata *conn) -{ - CURLMcode mresult; - - DEBUGASSERT(cshutdn); - DEBUGASSERT(cshutdn->multi->socket_cb); - - Curl_attach_connection(data, conn); - mresult = Curl_multi_ev_assess_conn(cshutdn->multi, data, conn); - Curl_detach_connection(data); - return mresult; -} - -void Curl_cshutdn_add(struct cshutdn *cshutdn, - struct connectdata *conn, - size_t conns_in_pool) -{ - struct Curl_easy *data = cshutdn->multi->admin; - size_t max_total = cshutdn->multi->max_total_connections; - - /* Add the connection to our shutdown list for non-blocking shutdown - * during multi processing. */ - if(max_total > 0 && - (max_total <= (conns_in_pool + Curl_llist_count(&cshutdn->list)))) { - CURL_TRC_M(data, "[SHUTDOWN] discarding oldest shutdown connection " - "due to connection limit of %zu", max_total); - cshutdn_destroy_oldest(cshutdn, data, NULL); - } - - if(cshutdn->multi->socket_cb) { - if(cshutdn_update_ev(cshutdn, data, conn)) { - CURL_TRC_M(data, "[SHUTDOWN] update events failed, discarding #%" - FMT_OFF_T, conn->connection_id); - Curl_cshutdn_terminate(data, conn, FALSE); - return; - } - } - - Curl_llist_append(&cshutdn->list, conn, &conn->cshutdn_node); - CURL_TRC_M(data, "[SHUTDOWN] added #%" FMT_OFF_T - " to shutdowns, now %zu conns in shutdown", - conn->connection_id, Curl_llist_count(&cshutdn->list)); -} - -void Curl_cshutdn_perform(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct Curl_sigpipe_ctx *sigpipe_ctx) -{ - cshutdn_perform(cshutdn, data, sigpipe_ctx); -} - -/* return fd_set info about the shutdown connections */ -void Curl_cshutdn_setfds(struct cshutdn *cshutdn, - struct Curl_easy *data, - fd_set *read_fd_set, fd_set *write_fd_set, - int *maxfd) -{ - if(Curl_llist_head(&cshutdn->list)) { - struct Curl_llist_node *e; - struct easy_pollset ps; - - Curl_pollset_init(&ps); - for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) { - unsigned int i; - struct connectdata *conn = Curl_node_elem(e); - CURLcode result; - - Curl_pollset_reset(&ps); - Curl_attach_connection(data, conn); - result = Curl_conn_adjust_pollset(data, conn, &ps); - Curl_detach_connection(data); - - if(result) - continue; - - for(i = 0; i < ps.n; i++) { - curl_socket_t sock = ps.sockets[i]; - if(!FDSET_SOCK(sock)) - continue; - if(ps.actions[i] & CURL_POLL_IN) - FD_SET(sock, read_fd_set); - if(ps.actions[i] & CURL_POLL_OUT) - FD_SET(sock, write_fd_set); - if((ps.actions[i] & (CURL_POLL_OUT | CURL_POLL_IN)) && - ((int)sock > *maxfd)) - *maxfd = (int)sock; - } - } - Curl_pollset_cleanup(&ps); - } -} - -/* return information about the shutdown connections */ -unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct Curl_waitfds *cwfds) -{ - unsigned int need = 0; - - if(Curl_llist_head(&cshutdn->list)) { - struct Curl_llist_node *e; - struct easy_pollset ps; - struct connectdata *conn; - CURLcode result; - - Curl_pollset_init(&ps); - for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) { - conn = Curl_node_elem(e); - Curl_pollset_reset(&ps); - Curl_attach_connection(data, conn); - result = Curl_conn_adjust_pollset(data, conn, &ps); - Curl_detach_connection(data); - - if(!result) - need += Curl_waitfds_add_ps(cwfds, &ps); - } - Curl_pollset_cleanup(&ps); - } - return need; -} - -CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct curl_pollfds *cpfds) -{ - CURLcode result = CURLE_OK; - - if(Curl_llist_head(&cshutdn->list)) { - struct Curl_llist_node *e; - struct easy_pollset ps; - struct connectdata *conn; - - Curl_pollset_init(&ps); - for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) { - conn = Curl_node_elem(e); - Curl_pollset_reset(&ps); - Curl_attach_connection(data, conn); - result = Curl_conn_adjust_pollset(data, conn, &ps); - Curl_detach_connection(data); - - if(!result) - result = Curl_pollfds_add_ps(cpfds, &ps); - if(result) { - Curl_pollset_cleanup(&ps); - Curl_pollfds_cleanup(cpfds); - goto out; - } - } - Curl_pollset_cleanup(&ps); - } -out: - return result; -} diff --git a/vendor/curl/lib/cshutdn.h b/vendor/curl/lib/cshutdn.h deleted file mode 100644 index b2e83f3d1..000000000 --- a/vendor/curl/lib/cshutdn.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef HEADER_CURL_CSHUTDN_H -#define HEADER_CURL_CSHUTDN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Linus Nielsen Feltzing, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -struct connectdata; -struct Curl_easy; -struct curl_pollfds; -struct Curl_waitfds; -struct Curl_multi; -struct Curl_share; -struct Curl_sigpipe_ctx; - -/* Run the shutdown of the connection once. - * Shortly attach/detach `data` to `conn` while doing so. - * `done` will be set TRUE if any error was encountered or if - * the connection was shut down completely. */ -void Curl_cshutdn_run_once(struct Curl_easy *data, - struct connectdata *conn, - bool *done); - -/* Terminates the connection, e.g. closes and destroys it. - * If `do_shutdown` is TRUE, the shutdown will be run once before - * terminating it. - * Takes ownership of `conn`. */ -void Curl_cshutdn_terminate(struct Curl_easy *data, - struct connectdata *conn, - bool do_shutdown); - -/* A `cshutdown` is always owned by a multi handle to maintain - * the connections to be shut down. It registers timers and - * sockets to monitor via the multi handle. */ -struct cshutdn { - struct Curl_llist list; /* connections being shut down */ - struct Curl_multi *multi; /* the multi owning this */ - BIT(initialised); -}; - -/* Init as part of the given multi handle. */ -int Curl_cshutdn_init(struct cshutdn *cshutdn, - struct Curl_multi *multi); - -/* Terminate all remaining connections and free resources. */ -void Curl_cshutdn_destroy(struct cshutdn *cshutdn, - struct Curl_easy *data); - -/* Number of connections being shut down. */ -size_t Curl_cshutdn_count(struct Curl_easy *data); - -/* Number of connections to the destination being shut down. */ -size_t Curl_cshutdn_dest_count(struct Curl_easy *data, - const char *destination); - -/* Close the oldest connection in shutdown to destination or, - * when destination is NULL for any destination. - * Return TRUE if a connection has been closed. */ -bool Curl_cshutdn_close_oldest(struct Curl_easy *data, - const char *destination); - -/* Add a connection to have it shut down. Terminate the oldest - * connection when total connection limit of multi is being reached. */ -void Curl_cshutdn_add(struct cshutdn *cshutdn, - struct connectdata *conn, - size_t conns_in_pool); - -/* Add sockets and POLLIN/OUT flags for connections being shut down. */ -CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct curl_pollfds *cpfds); - -unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct Curl_waitfds *cwfds); - -void Curl_cshutdn_setfds(struct cshutdn *cshutdn, - struct Curl_easy *data, - fd_set *read_fd_set, fd_set *write_fd_set, - int *maxfd); - -/* Run maintenance on all connections. */ -void Curl_cshutdn_perform(struct cshutdn *cshutdn, - struct Curl_easy *data, - struct Curl_sigpipe_ctx *sigpipe_ctx); - -#endif /* HEADER_CURL_CSHUTDN_H */ diff --git a/vendor/curl/lib/curl_addrinfo.c b/vendor/curl/lib/curl_addrinfo.c deleted file mode 100644 index fd26c5f0b..000000000 --- a/vendor/curl/lib/curl_addrinfo.c +++ /dev/null @@ -1,589 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETINET_IN6_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_SYS_UN_H -# include -#endif - -#ifdef __VMS -# include -# include -#endif - -#include /* for offsetof() */ - -#include "curl_addrinfo.h" -#include "fake_addrinfo.h" -#include "curlx/inet_pton.h" - -/* - * Curl_freeaddrinfo() - * - * This is used to free a linked list of Curl_addrinfo structs along - * with all its associated allocated storage. This function should be - * called once for each successful call to Curl_getaddrinfo_ex() or to - * any function call which actually allocates a Curl_addrinfo struct. - */ - -#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \ - defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__) - /* workaround icc 9.1 optimizer issue */ -# define vqualifier volatile -#else -# define vqualifier -#endif - -void Curl_freeaddrinfo(struct Curl_addrinfo *cahead) -{ - struct Curl_addrinfo *vqualifier canext; - struct Curl_addrinfo *ca; - - for(ca = cahead; ca; ca = canext) { - canext = ca->ai_next; - curlx_free(ca); - } -} - -#ifdef HAVE_GETADDRINFO -/* - * Curl_getaddrinfo_ex() - * - * This is a wrapper function around system's getaddrinfo(), with - * the only difference that instead of returning a linked list of - * addrinfo structs this one returns a linked list of Curl_addrinfo - * ones. The memory allocated by this function *MUST* be free'd with - * Curl_freeaddrinfo(). For each successful call to this function - * there must be an associated call later to Curl_freeaddrinfo(). - * - * There should be no single call to system's getaddrinfo() in the - * whole library, any such call should be 'routed' through this one. - */ -int Curl_getaddrinfo_ex(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct Curl_addrinfo **result) -{ - const struct addrinfo *ai; - struct addrinfo *aihead; - struct Curl_addrinfo *cafirst = NULL; - struct Curl_addrinfo *calast = NULL; - struct Curl_addrinfo *ca; - size_t ss_size; - int error; - - *result = NULL; /* assume failure */ - - error = CURL_GETADDRINFO(nodename, servname, hints, &aihead); - if(error) - return error; - - /* traverse the addrinfo list */ - - for(ai = aihead; ai != NULL; ai = ai->ai_next) { - size_t namelen = ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0; - /* ignore elements with unsupported address family, - settle family-specific sockaddr structure size. */ - if(ai->ai_family == AF_INET) - ss_size = sizeof(struct sockaddr_in); -#ifdef USE_IPV6 - else if(ai->ai_family == AF_INET6) - ss_size = sizeof(struct sockaddr_in6); -#endif - else - continue; - - /* ignore elements without required address info */ - if(!ai->ai_addr || !(ai->ai_addrlen > 0)) - continue; - - /* ignore elements with bogus address size */ - if((size_t)ai->ai_addrlen < ss_size) - continue; - - ca = curlx_malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen); - if(!ca) { - error = EAI_MEMORY; - break; - } - - /* copy each structure member individually, member ordering, - size, or padding might be different for each platform. */ - - ca->ai_flags = ai->ai_flags; - ca->ai_family = ai->ai_family; - ca->ai_socktype = ai->ai_socktype; - ca->ai_protocol = ai->ai_protocol; - ca->ai_addrlen = (curl_socklen_t)ss_size; - ca->ai_addr = NULL; - ca->ai_canonname = NULL; - ca->ai_next = NULL; - - ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); - memcpy(ca->ai_addr, ai->ai_addr, ss_size); - - if(namelen) { - ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size); - memcpy(ca->ai_canonname, ai->ai_canonname, namelen); - } - - /* if the return list is empty, this becomes the first element */ - if(!cafirst) - cafirst = ca; - - /* add this element last in the return list */ - if(calast) - calast->ai_next = ca; - calast = ca; - } - - /* destroy the addrinfo list */ - if(aihead) - CURL_FREEADDRINFO(aihead); - - /* if we failed, also destroy the Curl_addrinfo list */ - if(error) { - Curl_freeaddrinfo(cafirst); - cafirst = NULL; - } - else if(!cafirst) { -#ifdef EAI_NONAME - /* rfc3493 conformant */ - error = EAI_NONAME; -#else - /* rfc3493 obsoleted */ - error = EAI_NODATA; -#endif -#ifdef USE_WINSOCK - SET_SOCKERRNO(error); -#endif - } - - *result = cafirst; - - /* This is not a CURLcode */ - return error; -} -#endif /* HAVE_GETADDRINFO */ - -/* - * Curl_he2ai() - * - * This function returns a pointer to the first element of a newly allocated - * Curl_addrinfo struct linked list filled with the data of a given hostent. - * Curl_addrinfo is meant to work like the addrinfo struct does for an IPv6 - * stack, but usable also for IPv4, all hosts and environments. - * - * The memory allocated by this function *MUST* be free'd later on calling - * Curl_freeaddrinfo(). For each successful call to this function there - * must be an associated call later to Curl_freeaddrinfo(). - * - * Curl_addrinfo defined in "lib/curl_addrinfo.h" - * - * struct Curl_addrinfo { - * int ai_flags; - * int ai_family; - * int ai_socktype; - * int ai_protocol; - * curl_socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo * - * char *ai_canonname; - * struct sockaddr *ai_addr; - * struct Curl_addrinfo *ai_next; - * }; - * - * hostent defined in - * - * struct hostent { - * char *h_name; - * char **h_aliases; - * int h_addrtype; - * int h_length; - * char **h_addr_list; - * }; - * - * for backward compatibility: - * - * #define h_addr h_addr_list[0] - */ -#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)) -struct Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port) -{ - struct Curl_addrinfo *ai; - struct Curl_addrinfo *prevai = NULL; - struct Curl_addrinfo *firstai = NULL; - struct sockaddr_in *addr; -#ifdef USE_IPV6 - struct sockaddr_in6 *addr6; -#endif - CURLcode result = CURLE_OK; - int i; - char *curr; - - if(!he) - /* no input == no output! */ - return NULL; - - DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL)); - - for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) { - size_t ss_size; - size_t namelen = strlen(he->h_name) + 1; /* include null-terminator */ -#ifdef USE_IPV6 - if(he->h_addrtype == AF_INET6) - ss_size = sizeof(struct sockaddr_in6); - else -#endif - ss_size = sizeof(struct sockaddr_in); - - /* allocate memory to hold the struct, the address and the name */ - ai = curlx_calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen); - if(!ai) { - result = CURLE_OUT_OF_MEMORY; - break; - } - /* put the address after the struct */ - ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo)); - /* then put the name after the address */ - ai->ai_canonname = (char *)ai->ai_addr + ss_size; - memcpy(ai->ai_canonname, he->h_name, namelen); - - if(!firstai) - /* store the pointer we want to return from this function */ - firstai = ai; - - if(prevai) - /* make the previous entry point to this */ - prevai->ai_next = ai; - - ai->ai_family = he->h_addrtype; - - /* we return all names as STREAM, so when using this address for TFTP - the type must be ignored and conn->socktype be used instead! */ - ai->ai_socktype = SOCK_STREAM; - - ai->ai_addrlen = (curl_socklen_t)ss_size; - - /* leave the rest of the struct filled with zero */ - - switch(ai->ai_family) { - case AF_INET: - addr = (void *)ai->ai_addr; /* storage area for this info */ - - memcpy(&addr->sin_addr, curr, sizeof(struct in_addr)); - addr->sin_family = (CURL_SA_FAMILY_T)(he->h_addrtype); - addr->sin_port = htons((unsigned short)port); - break; - -#ifdef USE_IPV6 - case AF_INET6: - addr6 = (void *)ai->ai_addr; /* storage area for this info */ - - memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr)); - addr6->sin6_family = (CURL_SA_FAMILY_T)(he->h_addrtype); - addr6->sin6_port = htons((unsigned short)port); - break; -#endif - } - - prevai = ai; - } - - if(result) { - Curl_freeaddrinfo(firstai); - firstai = NULL; - } - - return firstai; -} -#endif - -/* - * ip2addr() - * - * This function takes an Internet address, in binary form, as input parameter - * along with its address family and the string version of the address, and it - * returns a Curl_addrinfo chain filled in correctly with information for the - * given address/host - */ -static CURLcode ip2addr(struct Curl_addrinfo **addrp, int af, - const void *inaddr, const char *hostname, int port) -{ - struct Curl_addrinfo *ai; - size_t addrsize; - size_t namelen; - struct sockaddr_in *addr; -#ifdef USE_IPV6 - struct sockaddr_in6 *addr6; -#endif - - DEBUGASSERT(inaddr && hostname); - - namelen = strlen(hostname) + 1; - *addrp = NULL; - - if(af == AF_INET) - addrsize = sizeof(struct sockaddr_in); -#ifdef USE_IPV6 - else if(af == AF_INET6) - addrsize = sizeof(struct sockaddr_in6); -#endif - else - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* allocate memory to hold the struct, the address and the name */ - ai = curlx_calloc(1, sizeof(struct Curl_addrinfo) + addrsize + namelen); - if(!ai) - return CURLE_OUT_OF_MEMORY; - /* put the address after the struct */ - ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo)); - /* then put the name after the address */ - ai->ai_canonname = (char *)ai->ai_addr + addrsize; - memcpy(ai->ai_canonname, hostname, namelen); - ai->ai_family = af; - ai->ai_socktype = SOCK_STREAM; - ai->ai_addrlen = (curl_socklen_t)addrsize; - /* leave the rest of the struct filled with zero */ - - switch(af) { - case AF_INET: - addr = (void *)ai->ai_addr; /* storage area for this info */ - - memcpy(&addr->sin_addr, inaddr, sizeof(struct in_addr)); - addr->sin_family = (CURL_SA_FAMILY_T)af; - addr->sin_port = htons((unsigned short)port); - break; - -#ifdef USE_IPV6 - case AF_INET6: - addr6 = (void *)ai->ai_addr; /* storage area for this info */ - - memcpy(&addr6->sin6_addr, inaddr, sizeof(struct in6_addr)); - addr6->sin6_family = (CURL_SA_FAMILY_T)af; - addr6->sin6_port = htons((unsigned short)port); - break; -#endif - } - *addrp = ai; - return CURLE_OK; -} - -/* - * Given an IPv4 or IPv6 dotted string address, this converts it to a proper - * allocated Curl_addrinfo struct and returns it. - */ -CURLcode Curl_str2addr(const char *dotted, uint16_t port, - struct Curl_addrinfo **addrp) -{ - struct in_addr in; - if(curlx_inet_pton(AF_INET, dotted, &in) > 0) - /* This is a dotted IP address 123.123.123.123-style */ - return ip2addr(addrp, AF_INET, &in, dotted, port); -#ifdef USE_IPV6 - { - struct in6_addr in6; - if(curlx_inet_pton(AF_INET6, dotted, &in6) > 0) - /* This is a dotted IPv6 address ::1-style */ - return ip2addr(addrp, AF_INET6, &in6, dotted, port); - } -#endif - return CURLE_BAD_FUNCTION_ARGUMENT; /* bad input format */ -} - -bool Curl_is_ipv4addr(const char *address) -{ - struct in_addr in; - return (curlx_inet_pton(AF_INET, address, &in) > 0); -} - -bool Curl_is_ipaddr(const char *address) -{ - if(Curl_is_ipv4addr(address)) - return TRUE; -#ifdef USE_IPV6 - { - struct in6_addr in6; - if(curlx_inet_pton(AF_INET6, address, &in6) > 0) - /* This is a dotted IPv6 address ::1-style */ - return TRUE; - } -#endif - return FALSE; -} - -#ifdef USE_UNIX_SOCKETS -/** - * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo - * struct initialized with this path. - * Returns CURLE_TOO_LARGE when path is too long. - */ -CURLcode Curl_unix2addr(const char *path, bool abstract, - struct Curl_addrinfo **paddr) -{ - struct Curl_addrinfo *ai; - struct sockaddr_un *sa_un; - size_t path_len; - - *paddr = NULL; - - /* sun_path must be able to store the null-terminated path */ - path_len = strlen(path) + 1; - if(path_len > sizeof(sa_un->sun_path)) - return CURLE_TOO_LARGE; - - ai = curlx_calloc(1, - sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un)); - if(!ai) - return CURLE_OUT_OF_MEMORY; - - ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo)); - sa_un = (void *)ai->ai_addr; - sa_un->sun_family = AF_UNIX; - - ai->ai_family = AF_UNIX; - ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */ - ai->ai_addrlen = (curl_socklen_t) - ((offsetof(struct sockaddr_un, sun_path) + path_len) & 0x7FFFFFFF); - - /* Abstract Unix domain socket have NULL prefix instead of suffix */ - if(abstract) - memcpy(sa_un->sun_path + 1, path, path_len - 1); - else - memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */ - - *paddr = ai; - return CURLE_OK; -} -#endif - -#if defined(CURL_MEMDEBUG) && defined(HAVE_GETADDRINFO) && \ - defined(HAVE_FREEADDRINFO) -/* - * curl_dbg_freeaddrinfo() - * - * This is strictly for memory tracing and are using the same style as the - * family otherwise present in memdebug.c. I put these ones here since they - * require a bunch of structs I did not want to include in memdebug.c - */ -void curl_dbg_freeaddrinfo(struct addrinfo *freethis, - int line, const char *source) -{ - curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n", - source, line, (void *)freethis); -#ifdef USE_LWIPSOCK - lwip_freeaddrinfo(freethis); -#elif defined(USE_FAKE_GETADDRINFO) - { - const char *env = getenv("CURL_DNS_SERVER"); - if(env) - r_freeaddrinfo(freethis); - else - /* !checksrc! disable BANNEDFUNC 1 */ - freeaddrinfo(freethis); - } -#else - /* !checksrc! disable BANNEDFUNC 1 */ - freeaddrinfo(freethis); -#endif -} -#endif /* CURL_MEMDEBUG && HAVE_FREEADDRINFO */ - -#if defined(CURL_MEMDEBUG) && defined(HAVE_GETADDRINFO) -/* - * curl_dbg_getaddrinfo() - * - * This is strictly for memory tracing and are using the same style as the - * family otherwise present in memdebug.c. I put these ones here since they - * require a bunch of structs I did not want to include in memdebug.c - */ -int curl_dbg_getaddrinfo(const char *hostname, - const char *service, - const struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source) -{ -#ifdef USE_LWIPSOCK - int res = lwip_getaddrinfo(hostname, service, hints, result); -#elif defined(USE_FAKE_GETADDRINFO) - int res; - const char *env = getenv("CURL_DNS_SERVER"); - if(env) - res = r_getaddrinfo(hostname, service, hints, result); - else - /* !checksrc! disable BANNEDFUNC 1 */ - res = getaddrinfo(hostname, service, hints, result); -#else - /* !checksrc! disable BANNEDFUNC 1 */ - int res = getaddrinfo(hostname, service, hints, result); -#endif - if(res == 0) - /* success */ - curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n", source, line, - (void *)*result); - else - curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n", source, line); - return res; -} -#endif /* CURL_MEMDEBUG && HAVE_GETADDRINFO */ - -#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS) -/* - * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and macOS - * 10.11.5. - */ -void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port) -{ - struct Curl_addrinfo *ca; - struct sockaddr_in *addr; -#ifdef USE_IPV6 - struct sockaddr_in6 *addr6; -#endif - for(ca = addrinfo; ca != NULL; ca = ca->ai_next) { - switch(ca->ai_family) { - case AF_INET: - addr = (void *)ca->ai_addr; /* storage area for this info */ - addr->sin_port = htons((unsigned short)port); - break; - -#ifdef USE_IPV6 - case AF_INET6: - addr6 = (void *)ca->ai_addr; /* storage area for this info */ - addr6->sin6_port = htons((unsigned short)port); - break; -#endif - } - } -} -#endif diff --git a/vendor/curl/lib/curl_addrinfo.h b/vendor/curl/lib/curl_addrinfo.h deleted file mode 100644 index da2da872c..000000000 --- a/vendor/curl/lib/curl_addrinfo.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef HEADER_CURL_ADDRINFO_H -#define HEADER_CURL_ADDRINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef __VMS -# include -# include -#endif - -/* - * Curl_addrinfo is our internal struct definition that we use to allow - * consistent internal handling of this data. We use this even when the system - * provides an addrinfo structure definition. We use this for all sorts of - * IPv4 and IPV6 builds. - */ - -struct Curl_addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - curl_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */ - char *ai_canonname; - struct sockaddr *ai_addr; - struct Curl_addrinfo *ai_next; -}; - -void Curl_freeaddrinfo(struct Curl_addrinfo *cahead); - -#ifdef HAVE_GETADDRINFO -int Curl_getaddrinfo_ex(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct Curl_addrinfo **result); -#endif - -#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)) -struct Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port); -#endif - -bool Curl_is_ipv4addr(const char *address); -bool Curl_is_ipaddr(const char *address); -CURLcode Curl_str2addr(const char *dotted, uint16_t port, - struct Curl_addrinfo **addrp); - -#ifdef USE_UNIX_SOCKETS -CURLcode Curl_unix2addr(const char *path, bool abstract, - struct Curl_addrinfo **paddr); -#endif - -#if defined(CURL_MEMDEBUG) && defined(HAVE_GETADDRINFO) && \ - defined(HAVE_FREEADDRINFO) -void curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, - const char *source); -#endif - -#if defined(CURL_MEMDEBUG) && defined(HAVE_GETADDRINFO) -int curl_dbg_getaddrinfo(const char *hostname, const char *service, - const struct addrinfo *hints, - struct addrinfo **result, int line, - const char *source); -#endif - -#ifdef HAVE_GETADDRINFO -#ifdef USE_RESOLVE_ON_IPS -void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port); -#else -#define Curl_addrinfo_set_port(x, y) -#endif -#endif - -#endif /* HEADER_CURL_ADDRINFO_H */ diff --git a/vendor/curl/lib/curl_config-cmake.h.in b/vendor/curl/lib/curl_config-cmake.h.in deleted file mode 100644 index 41b0ddf07..000000000 --- a/vendor/curl/lib/curl_config-cmake.h.in +++ /dev/null @@ -1,792 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* Location of default ca bundle */ -#cmakedefine CURL_CA_BUNDLE "${CURL_CA_BUNDLE}" - -/* define "1" to use built-in ca store of TLS backend */ -#cmakedefine CURL_CA_FALLBACK 1 - -/* Location of default ca path */ -#cmakedefine CURL_CA_PATH "${CURL_CA_PATH}" - -/* Default SSL backend */ -#cmakedefine CURL_DEFAULT_SSL_BACKEND "${CURL_DEFAULT_SSL_BACKEND}" - -/* Use native CA store */ -#cmakedefine CURL_CA_NATIVE 1 - -/* disables alt-svc */ -#cmakedefine CURL_DISABLE_ALTSVC 1 - -/* disables cookies support */ -#cmakedefine CURL_DISABLE_COOKIES 1 - -/* disables Basic authentication */ -#cmakedefine CURL_DISABLE_BASIC_AUTH 1 - -/* disables Bearer authentication */ -#cmakedefine CURL_DISABLE_BEARER_AUTH 1 - -/* disables Digest authentication */ -#cmakedefine CURL_DISABLE_DIGEST_AUTH 1 - -/* disables Kerberos authentication */ -#cmakedefine CURL_DISABLE_KERBEROS_AUTH 1 - -/* disables negotiate authentication */ -#cmakedefine CURL_DISABLE_NEGOTIATE_AUTH 1 - -/* disables aws-sigv4 */ -#cmakedefine CURL_DISABLE_AWS 1 - -/* disables DICT */ -#cmakedefine CURL_DISABLE_DICT 1 - -/* disables DNS-over-HTTPS */ -#cmakedefine CURL_DISABLE_DOH 1 - -/* disables FILE */ -#cmakedefine CURL_DISABLE_FILE 1 - -/* disables form api */ -#cmakedefine CURL_DISABLE_FORM_API 1 - -/* disables FTP */ -#cmakedefine CURL_DISABLE_FTP 1 - -/* disables curl_easy_options API for existing options to curl_easy_setopt */ -#cmakedefine CURL_DISABLE_GETOPTIONS 1 - -/* disables GOPHER */ -#cmakedefine CURL_DISABLE_GOPHER 1 - -/* disables headers-api support */ -#cmakedefine CURL_DISABLE_HEADERS_API 1 - -/* disables HSTS support */ -#cmakedefine CURL_DISABLE_HSTS 1 - -/* disables HTTP */ -#cmakedefine CURL_DISABLE_HTTP 1 - -/* disabled all HTTP authentication methods */ -#cmakedefine CURL_DISABLE_HTTP_AUTH 1 - -/* disables IMAP */ -#cmakedefine CURL_DISABLE_IMAP 1 - -/* disables LDAP */ -#cmakedefine CURL_DISABLE_LDAP 1 - -/* disables LDAPS */ -#cmakedefine CURL_DISABLE_LDAPS 1 - -/* disables --libcurl option from the curl tool */ -#cmakedefine CURL_DISABLE_LIBCURL_OPTION 1 - -/* disables MIME support */ -#cmakedefine CURL_DISABLE_MIME 1 - -/* disables local binding support */ -#cmakedefine CURL_DISABLE_BINDLOCAL 1 - -/* disables MQTT */ -#cmakedefine CURL_DISABLE_MQTT 1 - -/* disables netrc parser */ -#cmakedefine CURL_DISABLE_NETRC 1 - -/* enables NTLM support */ -#cmakedefine CURL_ENABLE_NTLM 1 - -/* disables date parsing */ -#cmakedefine CURL_DISABLE_PARSEDATE 1 - -/* disables POP3 */ -#cmakedefine CURL_DISABLE_POP3 1 - -/* disables built-in progress meter */ -#cmakedefine CURL_DISABLE_PROGRESS_METER 1 - -/* disables proxies */ -#cmakedefine CURL_DISABLE_PROXY 1 - -/* disables IPFS from the curl tool */ -#cmakedefine CURL_DISABLE_IPFS 1 - -/* disables RTSP */ -#cmakedefine CURL_DISABLE_RTSP 1 - -/* disables SHA-512/256 hash algorithm */ -#cmakedefine CURL_DISABLE_SHA512_256 1 - -/* disabled shuffle DNS feature */ -#cmakedefine CURL_DISABLE_SHUFFLE_DNS 1 - -/* disables SMB */ -#cmakedefine CURL_ENABLE_SMB 1 - -/* disables SMTP */ -#cmakedefine CURL_DISABLE_SMTP 1 - -/* disabled WebSocket */ -#cmakedefine CURL_DISABLE_WEBSOCKETS 1 - -/* disables use of socketpair for curl_multi_poll() */ -#cmakedefine CURL_DISABLE_SOCKETPAIR 1 - -/* disables TELNET */ -#cmakedefine CURL_DISABLE_TELNET 1 - -/* disables TFTP */ -#cmakedefine CURL_DISABLE_TFTP 1 - -/* disables verbose strings */ -#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1 - -/* disables unsafe CA bundle search on Windows from the curl tool */ -#cmakedefine CURL_DISABLE_CA_SEARCH 1 - -/* safe CA bundle search (within the curl tool directory) on Windows */ -#cmakedefine CURL_CA_SEARCH_SAFE 1 - -/* to make a symbol visible */ -#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL} -/* Ensure using CURL_EXTERN_SYMBOL is possible */ -#ifndef CURL_EXTERN_SYMBOL -#define CURL_EXTERN_SYMBOL -#endif - -/* Allow SMB to work on Windows */ -#cmakedefine USE_WIN32_CRYPTO 1 - -/* Use Windows LDAP implementation */ -#cmakedefine USE_WIN32_LDAP 1 - -/* Define if you want to enable IPv6 support */ -#cmakedefine USE_IPV6 1 - -/* Define to 1 if you have the alarm function. */ -#cmakedefine HAVE_ALARM 1 - -/* Define to 1 if you have the arc4random function. */ -#cmakedefine HAVE_ARC4RANDOM 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have _Atomic support. */ -#cmakedefine HAVE_ATOMIC 1 - -/* Define to 1 if you have the `accept4' function. */ -#cmakedefine HAVE_ACCEPT4 1 - -/* Define to 1 if you have the `fnmatch' function. */ -#cmakedefine HAVE_FNMATCH 1 - -/* Define to 1 if you have the `basename' function. */ -#cmakedefine HAVE_BASENAME 1 - -/* Define to 1 if bool is an available type. */ -#cmakedefine HAVE_BOOL_T 1 - -/* Define to 1 if you have the __builtin_available function. */ -#cmakedefine HAVE_BUILTIN_AVAILABLE 1 - -/* Define to 1 if you have the clock_gettime function and monotonic timer. */ -#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1 - -/* Define to 1 if you have the clock_gettime function and raw monotonic timer. - */ -#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC_RAW 1 - -/* Define to 1 if you have the `closesocket' function. */ -#cmakedefine HAVE_CLOSESOCKET 1 - -/* Define to 1 if you have the `CloseSocket' function. */ -#cmakedefine HAVE_CLOSESOCKET_CAMEL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DIRENT_H 1 - -/* Define to 1 if you have the `opendir' function. */ -#cmakedefine HAVE_OPENDIR 1 - -/* Define to 1 if you have the fcntl function. */ -#cmakedefine HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_FCNTL_H 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#cmakedefine HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the freeaddrinfo function. */ -#cmakedefine HAVE_FREEADDRINFO 1 - -/* Define to 1 if you have the fseeko function. */ -#cmakedefine HAVE_FSEEKO 1 - -/* Define to 1 if you have the fseeko declaration. */ -#cmakedefine HAVE_DECL_FSEEKO 1 - -/* Define to 1 if you have a working getaddrinfo function. */ -#cmakedefine HAVE_GETADDRINFO 1 - -/* Define to 1 if the getaddrinfo function is threadsafe. */ -#cmakedefine HAVE_GETADDRINFO_THREADSAFE 1 - -/* Define to 1 if you have the `geteuid' function. */ -#cmakedefine HAVE_GETEUID 1 - -/* Define to 1 if you have the `getppid' function. */ -#cmakedefine HAVE_GETPPID 1 - -/* Define to 1 if you have the gethostbyname_r function. */ -#cmakedefine HAVE_GETHOSTBYNAME_R 1 - -/* gethostbyname_r() takes 3 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_3 1 - -/* gethostbyname_r() takes 5 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_5 1 - -/* gethostbyname_r() takes 6 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_6 1 - -/* Define to 1 if you have the gethostname function. */ -#cmakedefine HAVE_GETHOSTNAME 1 - -/* Define to 1 if you have a working getifaddrs function. */ -#cmakedefine HAVE_GETIFADDRS 1 - -/* Define to 1 if you have the `getpass_r' function. */ -#cmakedefine HAVE_GETPASS_R 1 - -/* Define to 1 if you have the `getpeername' function. */ -#cmakedefine HAVE_GETPEERNAME 1 - -/* Define to 1 if you have the `getsockname' function. */ -#cmakedefine HAVE_GETSOCKNAME 1 - -/* Define to 1 if you have the `if_nametoindex' function. */ -#cmakedefine HAVE_IF_NAMETOINDEX 1 - -/* Define to 1 if you have the `getpwuid' function. */ -#cmakedefine HAVE_GETPWUID 1 - -/* Define to 1 if you have the `getpwuid_r' function. */ -#cmakedefine HAVE_GETPWUID_R 1 - -/* Define to 1 if you have the `getrlimit' function. */ -#cmakedefine HAVE_GETRLIMIT 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#cmakedefine HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have a working glibc-style strerror_r function. */ -#cmakedefine HAVE_GLIBC_STRERROR_R 1 - -/* Define to 1 if you have a working gmtime_r function. */ -#cmakedefine HAVE_GMTIME_R 1 - -/* if you have the gssapi libraries */ -#cmakedefine HAVE_GSSAPI 1 - -/* if you have the GNU gssapi libraries */ -#cmakedefine HAVE_GSSGNU 1 - -/* MIT Kerberos version */ -#cmakedefine CURL_KRB5_VERSION ${CURL_KRB5_VERSION} - -/* BoringSSL version */ -#cmakedefine CURL_BORINGSSL_VERSION ${CURL_BORINGSSL_VERSION} - -/* Patch stamp */ -#cmakedefine CURL_PATCHSTAMP ${CURL_PATCHSTAMP} - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_IFADDRS_H 1 - -/* Define to 1 if you have an IPv6 capable working inet_ntop function. */ -#cmakedefine HAVE_INET_NTOP 1 - -/* Define to 1 if you have an IPv6 capable working inet_pton function. */ -#cmakedefine HAVE_INET_PTON 1 - -/* Define to 1 if symbol `sa_family_t' exists */ -#cmakedefine HAVE_SA_FAMILY_T 1 - -/* Define to 1 if you have the ioctlsocket function. */ -#cmakedefine HAVE_IOCTLSOCKET 1 - -/* Define to 1 if you have the IoctlSocket camel case function. */ -#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1 - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. - */ -#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1 - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#cmakedefine HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_IO_H 1 - -/* Define to 1 if you have the lber.h header file. */ -#cmakedefine HAVE_LBER_H 1 - -/* Use LDAPS implementation */ -#cmakedefine HAVE_LDAP_SSL 1 - -/* Define to 1 if you have the ldap_ssl.h header file. */ -#cmakedefine HAVE_LDAP_SSL_H 1 - -/* Define to 1 if you have the `ldap_url_parse' function. */ -#cmakedefine HAVE_LDAP_URL_PARSE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBGEN_H 1 - -/* Define to 1 if you have the `idn2' library (-lidn2). */ -#cmakedefine HAVE_LIBIDN2 1 - -/* Define to 1 if you have the idn2.h header file. */ -#cmakedefine HAVE_IDN2_H 1 - -/* if zlib is available */ -#cmakedefine HAVE_LIBZ 1 - -/* if brotli is available */ -#cmakedefine HAVE_BROTLI 1 - -/* if zstd is available */ -#cmakedefine HAVE_ZSTD 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LOCALE_H 1 - -/* Define to 1 if you have a working localtime_r function. */ -#cmakedefine HAVE_LOCALTIME_R 1 - -/* Define to 1 if you have the 'suseconds_t' data type. */ -#cmakedefine HAVE_SUSECONDS_T 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_IN6_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_UDP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LINUX_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NET_IF_H 1 - -/* Define to 1 if you have the `pipe' function. */ -#cmakedefine HAVE_PIPE 1 - -/* Define to 1 if you have the `pipe2' function. */ -#cmakedefine HAVE_PIPE2 1 - -/* Define to 1 if you have the `eventfd' function. */ -#cmakedefine HAVE_EVENTFD 1 - -/* If you have poll */ -#cmakedefine HAVE_POLL 1 - -/* If you have realpath */ -#cmakedefine HAVE_REALPATH 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_POLL_H 1 - -/* Define to 1 if you have a working POSIX-style strerror_r function. */ -#cmakedefine HAVE_POSIX_STRERROR_R 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PWD_H 1 - -/* Define to 1 if OpenSSL has the `SSL_set0_wbio` function. */ -#cmakedefine HAVE_SSL_SET0_WBIO 1 - -/* Define to 1 if you have the recv function. */ -#cmakedefine HAVE_RECV 1 - -/* Define to 1 if you have the select function. */ -#cmakedefine HAVE_SELECT 1 - -/* Define to 1 if you have the sched_yield function. */ -#cmakedefine HAVE_SCHED_YIELD 1 - -/* Define to 1 if you have the send function. */ -#cmakedefine HAVE_SEND 1 - -/* Define to 1 if you have the sendmsg function. */ -#cmakedefine HAVE_SENDMSG 1 - -/* Define to 1 if you have the sendmmsg function. */ -#cmakedefine HAVE_SENDMMSG 1 - -/* Define to 1 if you have the 'fsetxattr' function. */ -#cmakedefine HAVE_FSETXATTR 1 - -/* fsetxattr() takes 5 args */ -#cmakedefine HAVE_FSETXATTR_5 1 - -/* fsetxattr() takes 6 args */ -#cmakedefine HAVE_FSETXATTR_6 1 - -/* Define to 1 if you have the `setlocale' function. */ -#cmakedefine HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `setrlimit' function. */ -#cmakedefine HAVE_SETRLIMIT 1 - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1 - -/* Define to 1 if you have the sigaction function. */ -#cmakedefine HAVE_SIGACTION 1 - -/* Define to 1 if you have the siginterrupt function. */ -#cmakedefine HAVE_SIGINTERRUPT 1 - -/* Define to 1 if you have the signal function. */ -#cmakedefine HAVE_SIGNAL 1 - -/* Define to 1 if you have the sigsetjmp function or macro. */ -#cmakedefine HAVE_SIGSETJMP 1 - -/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ -#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define to 1 if you have the `socket' function. */ -#cmakedefine HAVE_SOCKET 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PROTO_BSDSOCKET_H 1 - -/* Define to 1 if you have the socketpair function. */ -#cmakedefine HAVE_SOCKETPAIR 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDATOMIC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the strcasecmp function. */ -#cmakedefine HAVE_STRCASECMP 1 - -/* Define to 1 if you have the strcmpi function. */ -#cmakedefine HAVE_STRCMPI 1 - -/* Define to 1 if you have the strerror_r function. */ -#cmakedefine HAVE_STRERROR_R 1 - -/* Define to 1 if you have the stricmp function. */ -#cmakedefine HAVE_STRICMP 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STROPTS_H 1 - -/* Define to 1 if you have the memrchr function. */ -#cmakedefine HAVE_MEMRCHR 1 - -/* if struct sockaddr_storage is defined */ -#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if you have the timeval struct. */ -#cmakedefine HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_EVENTFD_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_FILIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_POLL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SOCKIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UTIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TERMIOS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TERMIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#cmakedefine HAVE_UTIME 1 - -/* Define to 1 if you have the `utimes' function. */ -#cmakedefine HAVE_UTIMES 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UTIME_H 1 - -/* Define this symbol if your OS supports changing the contents of argv */ -#cmakedefine HAVE_WRITABLE_ARGV 1 - -/* Define this if time_t is unsigned */ -#cmakedefine HAVE_TIME_T_UNSIGNED 1 - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -#cmakedefine NEED_REENTRANT 1 - -/* cpu-machine-OS */ -#cmakedefine CURL_OS ${CURL_OS} - -/* - Note: SIZEOF_* variables are fetched with CMake through check_type_size(). - As per CMake documentation on CheckTypeSize, C preprocessor code is - generated by CMake into SIZEOF_*_CODE. This is what we use in the - following statements. - - Reference: https://cmake.org/cmake/help/latest/module/CheckTypeSize.html -*/ - -/* The size of `int', as computed by sizeof. */ -${SIZEOF_INT_CODE} - -/* The size of `long', as computed by sizeof. */ -${SIZEOF_LONG_CODE} - -/* The size of `off_t', as computed by sizeof. */ -${SIZEOF_OFF_T_CODE} - -/* The size of `curl_off_t', as computed by sizeof. */ -${SIZEOF_CURL_OFF_T_CODE} - -/* The size of `curl_socket_t', as computed by sizeof. */ -${SIZEOF_CURL_SOCKET_T_CODE} - -/* The size of `size_t', as computed by sizeof. */ -${SIZEOF_SIZE_T_CODE} - -/* The size of `time_t', as computed by sizeof. */ -${SIZEOF_TIME_T_CODE} - -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine STDC_HEADERS 1 - -/* Define if you have POSIX pthreads */ -#cmakedefine HAVE_THREADS_POSIX 1 - -/* Define if you want to enable c-ares support */ -#cmakedefine USE_ARES 1 - -/* Define if you want to enable c-ares DNS lookup */ -#cmakedefine USE_RESOLV_ARES 1 - -/* Define if you want to enable threaded DNS lookup */ -#cmakedefine USE_RESOLV_THREADED 1 - -/* if GnuTLS is enabled */ -#cmakedefine USE_GNUTLS 1 - -/* if SSL session export support is available */ -#cmakedefine USE_SSLS_EXPORT 1 - -/* if mbedTLS is enabled */ -#cmakedefine USE_MBEDTLS 1 - -/* if mbedTLS <4 has the mbedtls_des_crypt_ecb function. */ -#cmakedefine HAVE_MBEDTLS_DES_CRYPT_ECB 1 - -/* if Rustls is enabled */ -#cmakedefine USE_RUSTLS 1 - -/* if wolfSSL is enabled */ -#cmakedefine USE_WOLFSSL 1 - -/* if wolfSSL has the wolfSSL_get_peer_certificate function. */ -#cmakedefine HAVE_WOLFSSL_GET_PEER_CERTIFICATE 1 - -/* if wolfSSL has the wolfSSL_UseALPN function. */ -#cmakedefine HAVE_WOLFSSL_USEALPN 1 - -/* if wolfSSL has the wolfSSL_BIO_new function. */ -#cmakedefine HAVE_WOLFSSL_BIO_NEW 1 - -/* if wolfSSL has the wolfSSL_BIO_set_shutdown function. */ -#cmakedefine HAVE_WOLFSSL_BIO_SET_SHUTDOWN 1 - -/* if wolfSSL has the wc_Des_EcbEncrypt function. */ -#cmakedefine HAVE_WC_DES_ECBENCRYPT 1 - -/* if libssh is in use */ -#cmakedefine USE_LIBSSH 1 - -/* if libssh2 is in use */ -#cmakedefine USE_LIBSSH2 1 - -/* if libpsl is in use */ -#cmakedefine USE_LIBPSL 1 - -/* if you want to use OpenLDAP code instead of legacy ldap implementation */ -#cmakedefine USE_OPENLDAP 1 - -/* if OpenSSL is in use */ -#cmakedefine USE_OPENSSL 1 - -/* if AmiSSL is in use */ -#cmakedefine USE_AMISSL 1 - -/* if GSASL is in use */ -#cmakedefine USE_GSASL 1 - -/* if libuv is in use */ -#cmakedefine USE_LIBUV 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UV_H 1 - -/* if libbacktrace is in use */ -#cmakedefine USE_BACKTRACE 1 - -/* Define to 1 if you do not want the OpenSSL configuration to be loaded - automatically */ -#cmakedefine CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG 1 - -/* to enable NGHTTP2 */ -#cmakedefine USE_NGHTTP2 1 - -/* to enable NGTCP2 */ -#cmakedefine USE_NGTCP2 1 - -/* to enable NGHTTP3 */ -#cmakedefine USE_NGHTTP3 1 - -/* to enable quiche */ -#cmakedefine USE_QUICHE 1 - -/* to enable openssl + ngtcp2 + nghttp3 */ -#cmakedefine OPENSSL_QUIC_API2 1 - -/* Define to 1 if you have the quiche_conn_set_qlog_fd function. */ -#cmakedefine HAVE_QUICHE_CONN_SET_QLOG_FD 1 - -/* if Unix domain sockets are enabled */ -#cmakedefine USE_UNIX_SOCKETS 1 - -/* to enable SSPI support */ -#cmakedefine USE_WINDOWS_SSPI 1 - -/* to enable Windows SSL */ -#cmakedefine USE_SCHANNEL 1 - -/* if Watt-32 is in use */ -#cmakedefine USE_WATT32 1 - -/* enable multiple SSL backends */ -#cmakedefine CURL_WITH_MULTI_SSL 1 - -/* Number of bits in a file offset, on hosts where this is settable. */ -#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} - -/* the signed version of size_t */ -#cmakedefine ssize_t ${ssize_t} - -/* Define to 1 if you have the mach_absolute_time function. */ -#cmakedefine HAVE_MACH_ABSOLUTE_TIME 1 - -/* to enable Windows IDN */ -#cmakedefine USE_WIN32_IDN 1 - -/* to enable Apple IDN */ -#cmakedefine USE_APPLE_IDN 1 - -/* to enable Apple OS-native certificate verification */ -#cmakedefine USE_APPLE_SECTRUST 1 - -/* Define to 1 if OpenSSL has the SSL_CTX_set_srp_username function. */ -#cmakedefine HAVE_OPENSSL_SRP 1 - -/* Define to 1 if GnuTLS has the gnutls_srp_verifier function. */ -#cmakedefine HAVE_GNUTLS_SRP 1 - -/* Define to 1 to enable TLS-SRP support. */ -#cmakedefine USE_TLS_SRP 1 - -/* Define to 1 to query for HTTPSRR when using DoH */ -#cmakedefine USE_HTTPSRR 1 - -/* if ECH support is available */ -#cmakedefine USE_ECH 1 - -/* Define to 1 if you have the wolfSSL_CTX_GenerateEchConfig function. */ -#cmakedefine HAVE_WOLFSSL_CTX_GENERATEECHCONFIG 1 - -/* Define to 1 if you have the SSL_set1_ech_config_list function. */ -#cmakedefine HAVE_SSL_SET1_ECH_CONFIG_LIST 1 - -/* Define to 1 if OpenSSL has the DES_ecb_encrypt function. */ -#cmakedefine HAVE_DES_ECB_ENCRYPT 1 diff --git a/vendor/curl/lib/curl_ctype.h b/vendor/curl/lib/curl_ctype.h deleted file mode 100644 index f3291ad81..000000000 --- a/vendor/curl/lib/curl_ctype.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef HEADER_CURL_CTYPE_H -#define HEADER_CURL_CTYPE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#define ISLOWHEXALPHA(x) (((x) >= 'a') && ((x) <= 'f')) -#define ISUPHEXALPHA(x) (((x) >= 'A') && ((x) <= 'F')) - -#define ISLOWCNTRL(x) ((unsigned char)(x) <= 0x1f) -#define IS7F(x) ((x) == 0x7f) - -#define ISLOWPRINT(x) (((x) >= 9) && ((x) <= 0x0d)) - -#define ISPRINT(x) (ISLOWPRINT(x) || (((x) >= ' ') && ((x) <= 0x7e))) -#define ISGRAPH(x) (ISLOWPRINT(x) || (((x) > ' ') && ((x) <= 0x7e))) -#define ISCNTRL(x) (ISLOWCNTRL(x) || IS7F(x)) -#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x)) -#define ISXDIGIT(x) (ISDIGIT(x) || ISLOWHEXALPHA(x) || ISUPHEXALPHA(x)) -#define ISODIGIT(x) (((x) >= '0') && ((x) <= '7')) -#define ISALNUM(x) (ISDIGIT(x) || ISLOWER(x) || ISUPPER(x)) -#define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z')) -#define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z')) -#define ISDIGIT(x) (((x) >= '0') && ((x) <= '9')) -#define ISBLANK(x) (((x) == ' ') || ((x) == '\t')) -#define ISSPACE(x) (ISBLANK(x) || (((x) >= 0xa) && ((x) <= 0x0d))) -#define ISURLPUNTCS(x) \ - (((x) == '-') || ((x) == '.') || ((x) == '_') || ((x) == '~')) -#define ISUNRESERVED(x) (ISALNUM(x) || ISURLPUNTCS(x)) -#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r') - -#endif /* HEADER_CURL_CTYPE_H */ diff --git a/vendor/curl/lib/curl_endian.c b/vendor/curl/lib/curl_endian.c deleted file mode 100644 index 864b411b6..000000000 --- a/vendor/curl/lib/curl_endian.c +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curl_endian.h" - -/* - * Curl_read16_le() - * - * This function converts a 16-bit integer from the little endian format, as - * used in the incoming package to whatever endian format we are using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 2 byte buffer. - * - * Returns the integer. - */ -unsigned short Curl_read16_le(const unsigned char *buf) -{ - return (unsigned short)(((unsigned short)buf[0]) | - ((unsigned short)buf[1] << 8)); -} - -/* - * Curl_read32_le() - * - * This function converts a 32-bit integer from the little endian format, as - * used in the incoming package to whatever endian format we are using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 4 byte buffer. - * - * Returns the integer. - */ -unsigned int Curl_read32_le(const unsigned char *buf) -{ - return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) | - ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24); -} - -/* - * Curl_read16_be() - * - * This function converts a 16-bit integer from the big endian format, as - * used in the incoming package to whatever endian format we are using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 2 byte buffer. - * - * Returns the integer. - */ -unsigned short Curl_read16_be(const unsigned char *buf) -{ - return (unsigned short)(((unsigned short)buf[0] << 8) | - ((unsigned short)buf[1])); -} diff --git a/vendor/curl/lib/curl_endian.h b/vendor/curl/lib/curl_endian.h deleted file mode 100644 index fa283214b..000000000 --- a/vendor/curl/lib/curl_endian.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HEADER_CURL_ENDIAN_H -#define HEADER_CURL_ENDIAN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* Converts a 16-bit integer from little endian */ -unsigned short Curl_read16_le(const unsigned char *buf); - -/* Converts a 32-bit integer from little endian */ -unsigned int Curl_read32_le(const unsigned char *buf); - -/* Converts a 16-bit integer from big endian */ -unsigned short Curl_read16_be(const unsigned char *buf); - -#endif /* HEADER_CURL_ENDIAN_H */ diff --git a/vendor/curl/lib/curl_fnmatch.c b/vendor/curl/lib/curl_fnmatch.c deleted file mode 100644 index dde956c3a..000000000 --- a/vendor/curl/lib/curl_fnmatch.c +++ /dev/null @@ -1,385 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP - -#include "curl_fnmatch.h" - -#ifndef HAVE_FNMATCH - -#define CURLFNM_CHARSET_LEN (sizeof(char) * 256) -#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15) - -#define CURLFNM_NEGATE CURLFNM_CHARSET_LEN - -#define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1) -#define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2) -#define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3) -#define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4) -#define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5) -#define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6) -#define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7) -#define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8) -#define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9) -#define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10) - -typedef enum { - CURLFNM_SCHS_DEFAULT = 0, - CURLFNM_SCHS_RIGHTBR, - CURLFNM_SCHS_RIGHTBRLEFTBR -} setcharset_state; - -typedef enum { - CURLFNM_PKW_INIT = 0, - CURLFNM_PKW_DDOT -} parsekey_state; - -typedef enum { - CCLASS_OTHER = 0, - CCLASS_DIGIT, - CCLASS_UPPER, - CCLASS_LOWER -} char_class; - -#define SETCHARSET_OK 1 -#define SETCHARSET_FAIL 0 - -static int parsekeyword(const unsigned char **pattern, unsigned char *charset) -{ - parsekey_state state = CURLFNM_PKW_INIT; - char keyword[10] = { 0 }; - size_t i; - const unsigned char *p = *pattern; - bool found = FALSE; - for(i = 0; !found; i++) { - char c = (char)*p++; - if(i >= sizeof(keyword)) - return SETCHARSET_FAIL; - switch(state) { - case CURLFNM_PKW_INIT: - if(ISLOWER(c)) - keyword[i] = c; - else if(c == ':') - state = CURLFNM_PKW_DDOT; - else - return SETCHARSET_FAIL; - break; - case CURLFNM_PKW_DDOT: - if(c == ']') - found = TRUE; - else - return SETCHARSET_FAIL; - } - } -#undef KEYLEN - - *pattern = p; /* move caller's pattern pointer */ - if(strcmp(keyword, "digit") == 0) - charset[CURLFNM_DIGIT] = 1; - else if(strcmp(keyword, "alnum") == 0) - charset[CURLFNM_ALNUM] = 1; - else if(strcmp(keyword, "alpha") == 0) - charset[CURLFNM_ALPHA] = 1; - else if(strcmp(keyword, "xdigit") == 0) - charset[CURLFNM_XDIGIT] = 1; - else if(strcmp(keyword, "print") == 0) - charset[CURLFNM_PRINT] = 1; - else if(strcmp(keyword, "graph") == 0) - charset[CURLFNM_GRAPH] = 1; - else if(strcmp(keyword, "space") == 0) - charset[CURLFNM_SPACE] = 1; - else if(strcmp(keyword, "blank") == 0) - charset[CURLFNM_BLANK] = 1; - else if(strcmp(keyword, "upper") == 0) - charset[CURLFNM_UPPER] = 1; - else if(strcmp(keyword, "lower") == 0) - charset[CURLFNM_LOWER] = 1; - else - return SETCHARSET_FAIL; - return SETCHARSET_OK; -} - -/* Return the character class. */ -static char_class charclass(unsigned char c) -{ - if(ISUPPER(c)) - return CCLASS_UPPER; - if(ISLOWER(c)) - return CCLASS_LOWER; - if(ISDIGIT(c)) - return CCLASS_DIGIT; - return CCLASS_OTHER; -} - -/* Include a character or a range in set. */ -static void setcharorrange(const unsigned char **pp, unsigned char *charset) -{ - const unsigned char *p = (*pp)++; - unsigned char c = *p++; - - charset[c] = 1; - if(ISALNUM(c) && *p++ == '-') { - char_class cc = charclass(c); - unsigned char endrange = *p++; - - if(endrange == '\\') - endrange = *p++; - if(endrange >= c && charclass(endrange) == cc) { - while(c++ != endrange) - if(charclass(c) == cc) /* Chars in class may be not consecutive. */ - charset[c] = 1; - *pp = p; - } - } -} - -/* returns 1 (TRUE) if pattern is OK, 0 if is bad ("p" is pattern pointer) */ -static int setcharset(const unsigned char **p, unsigned char *charset) -{ - setcharset_state state = CURLFNM_SCHS_DEFAULT; - bool something_found = FALSE; - unsigned char c; - - memset(charset, 0, CURLFNM_CHSET_SIZE); - for(;;) { - c = **p; - if(!c) - return SETCHARSET_FAIL; - - switch(state) { - case CURLFNM_SCHS_DEFAULT: - if(c == ']') { - if(something_found) - return SETCHARSET_OK; - something_found = TRUE; - state = CURLFNM_SCHS_RIGHTBR; - charset[c] = 1; - (*p)++; - } - else if(c == '[') { - const unsigned char *pp = *p + 1; - - if(*pp++ == ':' && parsekeyword(&pp, charset)) - *p = pp; - else { - charset[c] = 1; - (*p)++; - } - something_found = TRUE; - } - else if(c == '^' || c == '!') { - if(!something_found) { - if(charset[CURLFNM_NEGATE]) { - charset[c] = 1; - something_found = TRUE; - } - else - charset[CURLFNM_NEGATE] = 1; /* negate charset */ - } - else - charset[c] = 1; - (*p)++; - } - else if(c == '\\') { - c = *(++(*p)); - if(c) - setcharorrange(p, charset); - else - charset['\\'] = 1; - something_found = TRUE; - } - else { - setcharorrange(p, charset); - something_found = TRUE; - } - break; - case CURLFNM_SCHS_RIGHTBR: - if(c == '[') { - state = CURLFNM_SCHS_RIGHTBRLEFTBR; - charset[c] = 1; - (*p)++; - } - else if(c == ']') { - return SETCHARSET_OK; - } - else if(ISPRINT(c)) { - charset[c] = 1; - (*p)++; - state = CURLFNM_SCHS_DEFAULT; - } - else - /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a - * nonsense warning 'statement not reached' at end of the fnc when - * compiling on Solaris */ - goto fail; - break; - case CURLFNM_SCHS_RIGHTBRLEFTBR: - if(c == ']') - return SETCHARSET_OK; - state = CURLFNM_SCHS_DEFAULT; - charset[c] = 1; - (*p)++; - break; - } - } -fail: - return SETCHARSET_FAIL; -} - -static int loop(const unsigned char *pattern, const unsigned char *string, - int maxstars) -{ - const unsigned char *p = pattern; - const unsigned char *s = string; - unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 }; - - for(;;) { - const unsigned char *pp; - - switch(*p) { - case '*': - if(!maxstars) - return CURL_FNMATCH_NOMATCH; - /* Regroup consecutive stars and question marks. This can be done because - '*?*?*' can be expressed as '??*'. */ - for(;;) { - if(*++p == '\0') - return CURL_FNMATCH_MATCH; - if(*p == '?') { - if(!*s++) - return CURL_FNMATCH_NOMATCH; - } - else if(*p != '*') - break; - } - /* Skip string characters until we find a match with pattern suffix. */ - for(maxstars--; *s; s++) { - if(loop(p, s, maxstars) == CURL_FNMATCH_MATCH) - return CURL_FNMATCH_MATCH; - } - return CURL_FNMATCH_NOMATCH; - case '?': - if(!*s) - return CURL_FNMATCH_NOMATCH; - s++; - p++; - break; - case '\0': - return *s ? CURL_FNMATCH_NOMATCH : CURL_FNMATCH_MATCH; - case '\\': - if(p[1]) - p++; - if(*s++ != *p++) - return CURL_FNMATCH_NOMATCH; - break; - case '[': - pp = p + 1; /* Copy in case of syntax error in set. */ - if(setcharset(&pp, charset)) { - bool found = FALSE; - if(!*s) - return CURL_FNMATCH_NOMATCH; - if(charset[(unsigned int)*s]) - found = TRUE; - else if(charset[CURLFNM_ALNUM]) - found = ISALNUM(*s); - else if(charset[CURLFNM_ALPHA]) - found = ISALPHA(*s); - else if(charset[CURLFNM_DIGIT]) - found = ISDIGIT(*s); - else if(charset[CURLFNM_XDIGIT]) - found = ISXDIGIT(*s); - else if(charset[CURLFNM_PRINT]) - found = ISPRINT(*s); - else if(charset[CURLFNM_SPACE]) - found = ISBLANK(*s); - else if(charset[CURLFNM_UPPER]) - found = ISUPPER(*s); - else if(charset[CURLFNM_LOWER]) - found = ISLOWER(*s); - else if(charset[CURLFNM_BLANK]) - found = ISBLANK(*s); - else if(charset[CURLFNM_GRAPH]) - found = ISGRAPH(*s); - - if(charset[CURLFNM_NEGATE]) - found = !found; - - if(!found) - return CURL_FNMATCH_NOMATCH; - p = pp + 1; - s++; - break; - } - /* Syntax error in set; mismatch! */ - return CURL_FNMATCH_NOMATCH; - - default: - if(*p++ != *s++) - return CURL_FNMATCH_NOMATCH; - break; - } - } -} - -/* - * @unittest: 1307 - */ -int Curl_fnmatch(void *ptr, const char *pattern, const char *string) -{ - (void)ptr; /* the argument is specified by the curl_fnmatch_callback - prototype, but not used by Curl_fnmatch() */ - if(!pattern || !string) { - return CURL_FNMATCH_FAIL; - } - return loop((const unsigned char *)pattern, - (const unsigned char *)string, 2); -} -#else /* HAVE_FNMATCH */ - -#include -/* - * @unittest: 1307 - */ -int Curl_fnmatch(void *ptr, const char *pattern, const char *string) -{ - (void)ptr; /* the argument is specified by the curl_fnmatch_callback - prototype, but not used by Curl_fnmatch() */ - if(!pattern || !string) { - return CURL_FNMATCH_FAIL; - } - - switch(fnmatch(pattern, string, 0)) { - case 0: - return CURL_FNMATCH_MATCH; - case FNM_NOMATCH: - return CURL_FNMATCH_NOMATCH; - default: - return CURL_FNMATCH_FAIL; - } - /* not reached */ -} -#endif /* !HAVE_FNMATCH */ - -#endif /* !CURL_DISABLE_FTP */ diff --git a/vendor/curl/lib/curl_fnmatch.h b/vendor/curl/lib/curl_fnmatch.h deleted file mode 100644 index 61d2a0c4e..000000000 --- a/vendor/curl/lib/curl_fnmatch.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HEADER_CURL_FNMATCH_H -#define HEADER_CURL_FNMATCH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#define CURL_FNMATCH_MATCH 0 -#define CURL_FNMATCH_NOMATCH 1 -#define CURL_FNMATCH_FAIL 2 - -/* default pattern matching function - * ================================= - * Implemented with recursive backtracking, if you want to use Curl_fnmatch, - * please note that there is not implemented UTF/Unicode support. - * - * Implemented features: - * '?' notation, does not match UTF characters - * '*' can also work with UTF string - * [a-zA-Z0-9] enumeration support - * - * keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space - * and upper (use as "[[:alnum:]]") - */ -int Curl_fnmatch(void *ptr, const char *pattern, const char *string); - -#endif /* HEADER_CURL_FNMATCH_H */ diff --git a/vendor/curl/lib/curl_fopen.c b/vendor/curl/lib/curl_fopen.c deleted file mode 100644 index cc888f761..000000000 --- a/vendor/curl/lib/curl_fopen.c +++ /dev/null @@ -1,165 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \ - !defined(CURL_DISABLE_HSTS) - -#include "urldata.h" -#include "rand.h" -#include "curl_fopen.h" - -/* - The dirslash() function breaks a null-terminated pathname string into - directory and filename components then returns the directory component up - to, *AND INCLUDING*, a final '/'. If there is no directory in the path, - this instead returns a "" string. - - This function returns a pointer to malloc'ed memory. - - The input path to this function is expected to have a filename part. -*/ - -#ifdef _WIN32 -#define PATHSEP "\\" -#define IS_SEP(x) (((x) == '/') || ((x) == '\\')) -#elif defined(MSDOS) || defined(OS2) -#define PATHSEP "\\" -#define IS_SEP(x) ((x) == '\\') -#else -#define PATHSEP "/" -#define IS_SEP(x) ((x) == '/') -#endif - -static char *dirslash(const char *path) -{ - size_t n; - struct dynbuf out; - DEBUGASSERT(path); - curlx_dyn_init(&out, CURL_MAX_INPUT_LENGTH); - n = strlen(path); - if(n) { - /* find the rightmost path separator, if any */ - while(n && !IS_SEP(path[n - 1])) - --n; - /* skip over all the path separators, if any */ - while(n && IS_SEP(path[n - 1])) - --n; - } - if(curlx_dyn_addn(&out, path, n)) - return NULL; - /* if there was a directory, append a single trailing slash */ - if(n && curlx_dyn_addn(&out, PATHSEP, 1)) - return NULL; - return curlx_dyn_ptr(&out); -} - -/* - * Curl_fopen() opens a file for writing with a temp name, to be renamed - * to the final name when completed. If there is an existing file using this - * name at the time of the open, this function will clone the mode from that - * file. if 'tempname' is non-NULL, it needs a rename after the file is - * written. - */ -CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, - FILE **fh, char **tempname) -{ - CURLcode result = CURLE_WRITE_ERROR; - unsigned char randbuf[41]; - char *tempstore = NULL; -#ifndef _WIN32 - curlx_struct_stat sb; -#endif - int fd = -1; - char *dir = NULL; - *tempname = NULL; - -#ifndef _WIN32 - *fh = curlx_fopen(filename, FOPEN_WRITETEXT); - if(!*fh) - goto fail; - if(curlx_fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) { - return CURLE_OK; - } - curlx_fclose(*fh); -#ifdef HAVE_GETEUID - /* If the existing file is not owned by the user, do not inherit - * its permissions at the temp file created below. The permissions - * might be unsuitable for holding user private data. */ - if(sb.st_uid != geteuid()) - sb.st_mode = 0; -#endif -#endif /* !_WIN32 */ - *fh = NULL; - - result = Curl_rand_alnum(data, randbuf, sizeof(randbuf)); - if(result) - goto fail; - - dir = dirslash(filename); - if(dir) { - /* The temp filename should not end up too long for the target file - system */ - tempstore = curl_maprintf("%s%s.tmp", dir, randbuf); - curlx_free(dir); - } - - if(!tempstore) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - result = CURLE_WRITE_ERROR; -#ifdef _WIN32 - fd = curlx_open(tempstore, _O_WRONLY | _O_CREAT | _O_EXCL, - _S_IREAD | _S_IWRITE); -#elif (defined(ANDROID) || defined(__ANDROID__)) && \ - (defined(__i386__) || defined(__arm__)) - fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL, - (mode_t)(S_IRUSR | S_IWUSR | sb.st_mode)); -#else - fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR | sb.st_mode); -#endif - if(fd == -1) - goto fail; - - *fh = curlx_fdopen(fd, FOPEN_WRITETEXT); - if(!*fh) - goto fail; - - *tempname = tempstore; - return CURLE_OK; - -fail: - if(fd != -1) { - curlx_close(fd); - unlink(tempstore); - } - - curlx_free(tempstore); - return result; -} - -#endif /* !disabled */ diff --git a/vendor/curl/lib/curl_fopen.h b/vendor/curl/lib/curl_fopen.h deleted file mode 100644 index bd402d448..000000000 --- a/vendor/curl/lib/curl_fopen.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_FOPEN_H -#define HEADER_CURL_FOPEN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/fopen.h" - -CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, - FILE **fh, char **tempname); - -#endif diff --git a/vendor/curl/lib/curl_get_line.c b/vendor/curl/lib/curl_get_line.c deleted file mode 100644 index 6fcd043c9..000000000 --- a/vendor/curl/lib/curl_get_line.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \ - !defined(CURL_DISABLE_HSTS) || !defined(CURL_DISABLE_NETRC) - -#include "curl_get_line.h" - -/* - * Curl_get_line() returns only complete whole lines that end with newline. - * When 'eof' is set TRUE, the last line has been read. - */ -CURLcode Curl_get_line(struct dynbuf *buf, FILE *input, bool *eof) -{ - CURLcode result; - char buffer[128]; - curlx_dyn_reset(buf); - while(1) { - size_t rlen; - const char *b = fgets(buffer, sizeof(buffer), input); - if(!b && ferror(input)) - return CURLE_READ_ERROR; - - *eof = feof(input); - - rlen = b ? strlen(b) : 0; - if(rlen) { - result = curlx_dyn_addn(buf, b, rlen); - if(result) - /* too long line or out of memory */ - return result; - } - /* now check the full line */ - rlen = curlx_dyn_len(buf); - b = curlx_dyn_ptr(buf); - if(rlen && (b[rlen - 1] == '\n')) - /* LF at end of the line */ - return CURLE_OK; /* all good */ - if(*eof) - /* append a newline */ - return curlx_dyn_addn(buf, "\n", 1); - /* otherwise get next line to append */ - } - /* UNREACHABLE */ -} - -#endif /* if not disabled */ diff --git a/vendor/curl/lib/curl_get_line.h b/vendor/curl/lib/curl_get_line.h deleted file mode 100644 index 6b90ac472..000000000 --- a/vendor/curl/lib/curl_get_line.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_GET_LINE_H -#define HEADER_CURL_GET_LINE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/dynbuf.h" - -/* Curl_get_line() returns complete lines that end with a newline. */ -CURLcode Curl_get_line(struct dynbuf *buf, FILE *input, bool *eof); - -#endif /* HEADER_CURL_GET_LINE_H */ diff --git a/vendor/curl/lib/curl_gethostname.c b/vendor/curl/lib/curl_gethostname.c deleted file mode 100644 index f154c837f..000000000 --- a/vendor/curl/lib/curl_gethostname.c +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curl_gethostname.h" -#include "curlx/strcopy.h" - -/* - * Curl_gethostname() is a wrapper around gethostname() which allows - * overriding the hostname that the function would normally return. - * This capability is used by the test suite to verify exact matching - * of NTLM authentication, which exercises libcurl's MD4 and DES code - * as well as by the SMTP module when a hostname is not provided. - * - * For libcurl debug enabled builds hostname overriding takes place - * when environment variable CURL_GETHOSTNAME is set, using the value - * held by the variable to override returned hostname. - * - * Note: The function always returns the un-qualified hostname rather - * than being provider dependent. - */ - -int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen) -{ -#ifndef HAVE_GETHOSTNAME - - /* Allow compilation and return failure when unavailable */ - (void)name; - (void)namelen; - return -1; - -#else - int err; - char *dot; - -#ifdef DEBUGBUILD - - /* Override hostname when environment variable CURL_GETHOSTNAME is set */ - const char *force_hostname = getenv("CURL_GETHOSTNAME"); - if(force_hostname) { - if(strlen(force_hostname) < (size_t)namelen) - curlx_strcopy(name, namelen, force_hostname, strlen(force_hostname)); - else - return 1; /* cannot do it */ - err = 0; - } - else { - name[0] = '\0'; - err = gethostname(name, namelen); - } - -#else /* DEBUGBUILD */ - - name[0] = '\0'; -#ifdef __AMIGA__ - err = gethostname((unsigned char *)name, namelen); -#else - err = gethostname(name, namelen); -#endif - -#endif - - name[namelen - 1] = '\0'; - - if(err) - return err; - - /* Truncate domain, leave only machine name */ - dot = strchr(name, '.'); - if(dot) - *dot = '\0'; - - return 0; -#endif -} diff --git a/vendor/curl/lib/curl_gethostname.h b/vendor/curl/lib/curl_gethostname.h deleted file mode 100644 index 9281d9c24..000000000 --- a/vendor/curl/lib/curl_gethostname.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_GETHOSTNAME_H -#define HEADER_CURL_GETHOSTNAME_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* Hostname buffer size */ -#define HOSTNAME_MAX 1024 - -/* This returns the local machine's un-qualified hostname */ -int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen); - -#endif /* HEADER_CURL_GETHOSTNAME_H */ diff --git a/vendor/curl/lib/curl_gssapi.c b/vendor/curl/lib/curl_gssapi.c deleted file mode 100644 index 650d1908d..000000000 --- a/vendor/curl/lib/curl_gssapi.c +++ /dev/null @@ -1,448 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_GSSAPI - -#include "curl_gssapi.h" -#include "curl_trc.h" -#include "curlx/strcopy.h" - -#ifdef DEBUGBUILD -#if defined(HAVE_GSSGNU) || !defined(_WIN32) -#define Curl_gss_alloc malloc /* freed via the GSS API gss_release_buffer() */ -#define Curl_gss_free free /* pair of the above */ -#define CURL_GSS_STUB -/* For correctness this would be required for all platforms, not only Windows, - but, as of v1.22.1, MIT Kerberos uses a special allocator only for Windows, - and the availability of 'gssapi/gssapi_alloc.h' is difficult to detect, - because GSS headers are not versioned, and there is also no other macro to - indicate 1.18+ vs. previous versions. On Windows we can use 'GSS_S_BAD_MIC'. - */ -#elif defined(_WIN32) && defined(GSS_S_BAD_MIC) /* MIT Kerberos 1.15+ */ -/* MIT Kerberos 1.10+ (Windows), 1.18+ (all platforms), missing from GNU GSS */ -#include -#define Curl_gss_alloc gssalloc_malloc -#define Curl_gss_free gssalloc_free -#define CURL_GSS_STUB -#endif -#endif /* DEBUGBUILD */ - -#ifdef __GNUC__ -#define CURL_ALIGN8 __attribute__((aligned(8))) -#else -#define CURL_ALIGN8 -#endif - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -gss_OID_desc Curl_spnego_mech_oid CURL_ALIGN8 = { - 6, CURL_UNCONST("\x2b\x06\x01\x05\x05\x02") -}; -gss_OID_desc Curl_krb5_mech_oid CURL_ALIGN8 = { - 9, CURL_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") -}; - -#ifdef CURL_GSS_STUB -enum min_err_code { - STUB_GSS_OK = 0, - STUB_GSS_NO_MEMORY, - STUB_GSS_INVALID_ARGS, - STUB_GSS_INVALID_CREDS, - STUB_GSS_INVALID_CTX, - STUB_GSS_SERVER_ERR, - STUB_GSS_NO_MECH, - STUB_GSS_LAST -}; - -/* libcurl is also passing this struct to these functions, which are not yet - * stubbed: - * gss_inquire_context() - * gss_unwrap() - * gss_wrap() - */ -struct stub_gss_ctx_id_t_desc { - enum { STUB_GSS_NONE, STUB_GSS_KRB5, STUB_GSS_NTLM1, STUB_GSS_NTLM3 } sent; - int have_krb5; - int have_ntlm; - OM_uint32 flags; - char creds[250]; -}; - -static OM_uint32 stub_gss_init_sec_context( - OM_uint32 *min, - gss_cred_id_t initiator_cred_handle, - struct stub_gss_ctx_id_t_desc **context, - gss_name_t target_name, - const gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - const gss_channel_bindings_t input_chan_bindings, - gss_buffer_desc *input_token, - gss_OID *actual_mech_type, - gss_buffer_desc *output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec) -{ - struct stub_gss_ctx_id_t_desc *ctx = NULL; - - /* The token will be encoded in base64 */ - size_t length = sizeof(ctx->creds) * 3 / 4; - size_t used = 0; - char *token = NULL; - const char *creds = NULL; - - (void)initiator_cred_handle; - (void)mech_type; - (void)time_req; - (void)input_chan_bindings; - (void)actual_mech_type; - - if(!min) - return GSS_S_FAILURE; - - *min = 0; - - if(!context || !target_name || !output_token) { - *min = STUB_GSS_INVALID_ARGS; - return GSS_S_FAILURE; - } - - creds = getenv("CURL_STUB_GSS_CREDS"); - if(!creds || strlen(creds) >= sizeof(ctx->creds)) { - *min = STUB_GSS_INVALID_CREDS; - return GSS_S_FAILURE; - } - - ctx = *context; - if(ctx && strcmp(ctx->creds, creds)) { - *min = STUB_GSS_INVALID_CREDS; - return GSS_S_FAILURE; - } - - output_token->length = 0; - output_token->value = NULL; - - if(input_token && input_token->length) { - if(!ctx) { - *min = STUB_GSS_INVALID_CTX; - return GSS_S_FAILURE; - } - - /* Server response, either D (RA==) or C (Qw==) */ - if(((char *)input_token->value)[0] == 'D') { - /* Done */ - switch(ctx->sent) { - case STUB_GSS_KRB5: - case STUB_GSS_NTLM3: - if(ret_flags) - *ret_flags = ctx->flags; - if(time_rec) - *time_rec = GSS_C_INDEFINITE; - return GSS_S_COMPLETE; - default: - *min = STUB_GSS_SERVER_ERR; - return GSS_S_FAILURE; - } - } - - if(((char *)input_token->value)[0] != 'C') { - /* We only support Done or Continue */ - *min = STUB_GSS_SERVER_ERR; - return GSS_S_FAILURE; - } - - /* Continue */ - switch(ctx->sent) { - case STUB_GSS_KRB5: - /* We sent KRB5 and it failed, let's try NTLM */ - if(ctx->have_ntlm) { - ctx->sent = STUB_GSS_NTLM1; - break; - } - else { - *min = STUB_GSS_SERVER_ERR; - return GSS_S_FAILURE; - } - case STUB_GSS_NTLM1: - ctx->sent = STUB_GSS_NTLM3; - break; - default: - *min = STUB_GSS_SERVER_ERR; - return GSS_S_FAILURE; - } - } - else { - if(ctx) { - *min = STUB_GSS_INVALID_CTX; - return GSS_S_FAILURE; - } - - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - *min = STUB_GSS_NO_MEMORY; - return GSS_S_FAILURE; - } - - if(strstr(creds, "KRB5")) - ctx->have_krb5 = 1; - - if(strstr(creds, "NTLM")) - ctx->have_ntlm = 1; - - if(ctx->have_krb5) - ctx->sent = STUB_GSS_KRB5; - else if(ctx->have_ntlm) - ctx->sent = STUB_GSS_NTLM1; - else { - curlx_free(ctx); - *min = STUB_GSS_NO_MECH; - return GSS_S_FAILURE; - } - - curlx_strcopy(ctx->creds, sizeof(ctx->creds), creds, strlen(creds)); - ctx->flags = req_flags; - } - - token = Curl_gss_alloc(length); - if(!token) { - curlx_free(ctx); - *min = STUB_GSS_NO_MEMORY; - return GSS_S_FAILURE; - } - - { - gss_buffer_desc target_desc; - gss_OID name_type = GSS_C_NO_OID; - OM_uint32 minor_status; - OM_uint32 major_status; - major_status = gss_display_name(&minor_status, target_name, - &target_desc, &name_type); - if(GSS_ERROR(major_status)) { - Curl_gss_free(token); - curlx_free(ctx); - *min = STUB_GSS_NO_MEMORY; - return GSS_S_FAILURE; - } - - if(strlen(creds) + target_desc.length + 5 >= sizeof(ctx->creds)) { - Curl_gss_free(token); - curlx_free(ctx); - *min = STUB_GSS_NO_MEMORY; - return GSS_S_FAILURE; - } - - /* Token format: creds:target:type:padding */ - used = curl_msnprintf(token, length, "%s:%.*s:%d:", creds, - (int)target_desc.length, - (const char *)target_desc.value, - ctx->sent); - - gss_release_buffer(&minor_status, &target_desc); - } - - if(used >= length) { - Curl_gss_free(token); - curlx_free(ctx); - *min = STUB_GSS_NO_MEMORY; - return GSS_S_FAILURE; - } - - /* Overwrite null-terminator */ - memset(token + used, 'A', length - used); - - *context = ctx; - - output_token->value = token; - output_token->length = length; - - return GSS_S_CONTINUE_NEEDED; -} - -static OM_uint32 stub_gss_delete_sec_context( - OM_uint32 *min, - struct stub_gss_ctx_id_t_desc **context, - gss_buffer_t output_token) -{ - (void)output_token; - - if(!min) - return GSS_S_FAILURE; - - if(!context) { - *min = STUB_GSS_INVALID_CTX; - return GSS_S_FAILURE; - } - if(!*context) { - *min = STUB_GSS_INVALID_CTX; - return GSS_S_FAILURE; - } - - curlx_free(*context); - *context = NULL; - *min = 0; - - return GSS_S_COMPLETE; -} -#endif /* CURL_GSS_STUB */ - -OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data, - OM_uint32 *minor_status, - gss_ctx_id_t *context, - gss_name_t target_name, - gss_OID mech_type, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_buffer_t output_token, - const bool mutual_auth, - OM_uint32 *ret_flags) -{ - OM_uint32 req_flags = GSS_C_REPLAY_FLAG; - - if(mutual_auth) - req_flags |= GSS_C_MUTUAL_FLAG; - - if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) { -#ifdef GSS_C_DELEG_POLICY_FLAG /* MIT Kerberos 1.8+, missing from GNU GSS */ - req_flags |= GSS_C_DELEG_POLICY_FLAG; -#else - infof(data, "WARNING: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not " - "compiled in"); -#endif - } - - if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG) - req_flags |= GSS_C_DELEG_FLAG; - -#ifdef CURL_GSS_STUB - if(getenv("CURL_STUB_GSS_CREDS")) - return stub_gss_init_sec_context(minor_status, - GSS_C_NO_CREDENTIAL, /* cred_handle */ - (struct stub_gss_ctx_id_t_desc **)context, - target_name, - mech_type, - req_flags, - 0, /* time_req */ - input_chan_bindings, - input_token, - NULL, /* actual_mech_type */ - output_token, - ret_flags, - NULL /* time_rec */); -#endif /* CURL_GSS_STUB */ - - return gss_init_sec_context(minor_status, - GSS_C_NO_CREDENTIAL, /* cred_handle */ - context, - target_name, - mech_type, - req_flags, - 0, /* time_req */ - input_chan_bindings, - input_token, - NULL, /* actual_mech_type */ - output_token, - ret_flags, - NULL /* time_rec */); -} - -OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min, - gss_ctx_id_t *context, - gss_buffer_t output_token) -{ -#ifdef CURL_GSS_STUB - if(getenv("CURL_STUB_GSS_CREDS")) - return stub_gss_delete_sec_context(min, - (struct stub_gss_ctx_id_t_desc **)context, - output_token); -#endif /* CURL_GSS_STUB */ - - return gss_delete_sec_context(min, context, output_token); -} - -#ifdef CURLVERBOSE -#define GSS_LOG_BUFFER_LEN 1024 -static size_t display_gss_error(OM_uint32 status, int type, - char *buf, size_t len) -{ - OM_uint32 maj_stat; - OM_uint32 min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status_string = GSS_C_EMPTY_BUFFER; - - do { - maj_stat = gss_display_status(&min_stat, - status, - type, - GSS_C_NO_OID, - &msg_ctx, - &status_string); - if(maj_stat == GSS_S_COMPLETE && status_string.length > 0) { - if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) { - len += curl_msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len, - "%.*s. ", (int)status_string.length, - (char *)status_string.value); - } - } - gss_release_buffer(&min_stat, &status_string); - } while(!GSS_ERROR(maj_stat) && msg_ctx); - - return len; -} - -/* - * Curl_gss_log_error() - * - * This is used to log a GSS-API error status. - * - * Parameters: - * - * data [in] - The session handle. - * prefix [in] - The prefix of the log message. - * major [in] - The major status code. - * minor [in] - The minor status code. - */ -void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, - OM_uint32 major, OM_uint32 minor) -{ - char buf[GSS_LOG_BUFFER_LEN] = ""; - size_t len = 0; - - if(major != GSS_S_FAILURE) - len = display_gss_error(major, GSS_C_GSS_CODE, buf, len); - - display_gss_error(minor, GSS_C_MECH_CODE, buf, len); - - infof(data, "%s%s", prefix, buf); -} -#endif /* CURLVERBOSE */ - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic pop -#endif - -#endif /* HAVE_GSSAPI */ diff --git a/vendor/curl/lib/curl_gssapi.h b/vendor/curl/lib/curl_gssapi.h deleted file mode 100644 index fc3759ebc..000000000 --- a/vendor/curl/lib/curl_gssapi.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef HEADER_CURL_GSSAPI_H -#define HEADER_CURL_GSSAPI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" - -#ifdef HAVE_GSSAPI -extern gss_OID_desc Curl_spnego_mech_oid; -extern gss_OID_desc Curl_krb5_mech_oid; - -/* Common method for using GSS-API */ -OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data, - OM_uint32 *minor_status, - gss_ctx_id_t *context, - gss_name_t target_name, - gss_OID mech_type, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_buffer_t output_token, - const bool mutual_auth, - OM_uint32 *ret_flags); - -OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min, - gss_ctx_id_t *context, - gss_buffer_t output_token); - -#ifdef CURLVERBOSE -/* Helper to log a GSS-API error status */ -void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, - OM_uint32 major, OM_uint32 minor); -#else -#define Curl_gss_log_error(data, prefix, major, minor) \ - do { \ - (void)(data); \ - (void)(prefix); \ - (void)(major); \ - (void)(minor); \ - } while(0) -#endif - -/* Define our privacy and integrity protection values */ -#define GSSAUTH_P_NONE 1 -#define GSSAUTH_P_INTEGRITY 2 -#define GSSAUTH_P_PRIVACY 4 - -#endif /* HAVE_GSSAPI */ -#endif /* HEADER_CURL_GSSAPI_H */ diff --git a/vendor/curl/lib/curl_hmac.h b/vendor/curl/lib/curl_hmac.h deleted file mode 100644 index 301d44fee..000000000 --- a/vendor/curl/lib/curl_hmac.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef HEADER_CURL_HMAC_H -#define HEADER_CURL_HMAC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ - !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ - defined(USE_LIBSSH2) || defined(USE_SSL) - -#define HMAC_MD5_LENGTH 16 - -typedef CURLcode (*HMAC_hinit)(void *context); -typedef void (*HMAC_hupdate)(void *context, - const unsigned char *data, - unsigned int len); -typedef void (*HMAC_hfinal)(unsigned char *result, void *context); - -/* Per-hash function HMAC parameters. */ -struct HMAC_params { - HMAC_hinit hinit; /* Initialize context procedure. */ - HMAC_hupdate hupdate; /* Update context with data. */ - HMAC_hfinal hfinal; /* Get final result procedure. */ - unsigned int ctxtsize; /* Context structure size. */ - unsigned int maxkeylen; /* Maximum key length (bytes). */ - unsigned int resultlen; /* Result length (bytes). */ -}; - -/* HMAC computation context. */ -struct HMAC_context { - const struct HMAC_params *hash; /* Hash function definition. */ - void *hashctxt1; /* Hash function context 1. */ - void *hashctxt2; /* Hash function context 2. */ -}; - -/* Prototypes. */ -struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams, - const unsigned char *key, - unsigned int keylen); -void Curl_HMAC_update(struct HMAC_context *ctxt, - const unsigned char *data, - unsigned int len); -int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output); - -CURLcode Curl_hmacit(const struct HMAC_params *hashparams, - const unsigned char *key, const size_t keylen, - const unsigned char *data, size_t datalen, - unsigned char *output); - -#endif - -#endif /* HEADER_CURL_HMAC_H */ diff --git a/vendor/curl/lib/curl_ldap.h b/vendor/curl/lib/curl_ldap.h deleted file mode 100644 index 0ccc1289e..000000000 --- a/vendor/curl/lib/curl_ldap.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_LDAP_H -#define HEADER_CURL_LDAP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -extern const struct Curl_protocol Curl_protocol_ldap; - -void Curl_ldap_version(char *buf, size_t bufsz); - -#endif /* HEADER_CURL_LDAP_H */ diff --git a/vendor/curl/lib/curl_md4.h b/vendor/curl/lib/curl_md4.h deleted file mode 100644 index 05d162497..000000000 --- a/vendor/curl/lib/curl_md4.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADER_CURL_MD4_H -#define HEADER_CURL_MD4_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_CURL_NTLM_CORE - -#define MD4_DIGEST_LENGTH 16 - -CURLcode Curl_md4it(unsigned char *output, const unsigned char *input, - const size_t len); - -#endif /* USE_CURL_NTLM_CORE */ - -#endif /* HEADER_CURL_MD4_H */ diff --git a/vendor/curl/lib/curl_md5.h b/vendor/curl/lib/curl_md5.h deleted file mode 100644 index 8a0cc2623..000000000 --- a/vendor/curl/lib/curl_md5.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef HEADER_CURL_MD5_H -#define HEADER_CURL_MD5_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ - !defined(CURL_DISABLE_DIGEST_AUTH) - -#include "curl_hmac.h" - -#define MD5_DIGEST_LEN 16 - -typedef CURLcode (*Curl_MD5_init_func)(void *context); -typedef void (*Curl_MD5_update_func)(void *context, - const unsigned char *data, - unsigned int len); -typedef void (*Curl_MD5_final_func)(unsigned char *result, void *context); - -struct MD5_params { - Curl_MD5_init_func md5_init_func; /* Initialize context procedure */ - Curl_MD5_update_func md5_update_func; /* Update context with data */ - Curl_MD5_final_func md5_final_func; /* Get final result procedure */ - unsigned int md5_ctxtsize; /* Context structure size */ - unsigned int md5_resultlen; /* Result length (bytes) */ -}; - -struct MD5_context { - const struct MD5_params *md5_hash; /* Hash function definition */ - void *md5_hashctx; /* Hash function context */ -}; - -extern const struct MD5_params Curl_DIGEST_MD5; -extern const struct HMAC_params Curl_HMAC_MD5; - -CURLcode Curl_md5it(unsigned char *output, const unsigned char *input, - size_t len); - -struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params); -CURLcode Curl_MD5_update(struct MD5_context *context, - const unsigned char *input, - unsigned int len); -CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result); - -#endif - -#endif /* HEADER_CURL_MD5_H */ diff --git a/vendor/curl/lib/curl_memrchr.c b/vendor/curl/lib/curl_memrchr.c deleted file mode 100644 index 59ee176bc..000000000 --- a/vendor/curl/lib/curl_memrchr.c +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curl_memrchr.h" - -#ifndef HAVE_MEMRCHR -/* - * Curl_memrchr() - * - * Our memrchr() function clone for systems which lack this function. The - * memrchr() function is like the memchr() function, except that it searches - * backwards from the end of the n bytes pointed to by s instead of forward - * from the beginning. - */ -void *Curl_memrchr(const void *s, int c, size_t n) -{ - if(n > 0) { - const unsigned char *p = s; - const unsigned char *q = s; - - p += n - 1; - - while(p >= q) { - if(*p == (unsigned char)c) - return CURL_UNCONST(p); - p--; - } - } - return NULL; -} -#endif /* HAVE_MEMRCHR */ diff --git a/vendor/curl/lib/curl_memrchr.h b/vendor/curl/lib/curl_memrchr.h deleted file mode 100644 index 248368b25..000000000 --- a/vendor/curl/lib/curl_memrchr.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_MEMRCHR_H -#define HEADER_CURL_MEMRCHR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_MEMRCHR - -#ifdef HAVE_STRINGS_H -# include -#endif - -#else /* HAVE_MEMRCHR */ -void *Curl_memrchr(const void *s, int c, size_t n); -#define memrchr(x, y, z) Curl_memrchr(x, y, z) - -#endif /* HAVE_MEMRCHR */ - -#endif /* HEADER_CURL_MEMRCHR_H */ diff --git a/vendor/curl/lib/curl_ntlm_core.c b/vendor/curl/lib/curl_ntlm_core.c deleted file mode 100644 index 4b2007bba..000000000 --- a/vendor/curl/lib/curl_ntlm_core.c +++ /dev/null @@ -1,659 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_CURL_NTLM_CORE - -/* - * NTLM details: - * - * https://davenport.sourceforge.net/ntlm.html - * https://www.innovation.ch/java/ntlm.html - */ - -/* Please keep the SSL backend-specific #if branches in this order: - - 1. USE_OPENSSL - 2. USE_WOLFSSL - 3. USE_GNUTLS - 4. USE_MBEDTLS - 5. USE_OS400CRYPTO - 6. USE_WIN32_CRYPTO - - This ensures that: - - the same SSL branch gets activated throughout this source - file even if multiple backends are enabled at the same time. - - OpenSSL has higher priority than Windows Crypt, due - to issues with the latter supporting NTLM2Session responses - in NTLM type-3 messages. - */ - -#if defined(USE_OPENSSL) && defined(HAVE_DES_ECB_ENCRYPT) - -# include -# ifdef OPENSSL_IS_AWSLC /* for versions 1.2.0 to 1.30.1 */ -# define DES_set_key_unchecked (void)DES_set_key -# endif -# define USE_OPENSSL_DES - -#elif defined(USE_WOLFSSL) && defined(HAVE_WC_DES_ECBENCRYPT) - -# include -# include -# define USE_WOLFSSL_DES - -#elif defined(USE_GNUTLS) -# include -# define USE_CURL_DES_SET_ODD_PARITY -#elif defined(USE_MBEDTLS) && defined(HAVE_MBEDTLS_DES_CRYPT_ECB) -# include -# if MBEDTLS_VERSION_NUMBER < 0x03020000 -# error "mbedTLS 3.2.0 or later required" -# endif -# include -# define USE_MBEDTLS_DES -#elif defined(USE_OS400CRYPTO) -# include "cipher.mih" /* mih/cipher */ -# define USE_CURL_DES_SET_ODD_PARITY -#elif defined(USE_WIN32_CRYPTO) -# include -# define USE_CURL_DES_SET_ODD_PARITY -#else -# error "cannot compile NTLM support without a crypto library with DES." -#endif - -#include "urldata.h" -#include "strcase.h" -#include "curl_ntlm_core.h" -#include "curl_md5.h" -#include "curl_hmac.h" -#include "curl_md4.h" -#include "vauth/vauth.h" - -#ifdef USE_CURL_DES_SET_ODD_PARITY -/* - * curl_des_set_odd_parity() - * - * Copyright (C) Steve Holme, - * - * This is used to apply odd parity to the given byte array. It is typically - * used by when a cryptography engine does not have its own version. - * - * The function is a port of the Java based oddParity() function over at: - * - * https://davenport.sourceforge.net/ntlm.html - * - * Parameters: - * - * bytes [in/out] - The data whose parity bits are to be adjusted for - * odd parity. - * len [in] - The length of the data. - */ -static void curl_des_set_odd_parity(unsigned char *bytes, size_t len) -{ - size_t i; - - for(i = 0; i < len; i++) { - unsigned char b = bytes[i]; - - bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ - (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ - (b >> 1)) & 0x01) == 0; - - if(needs_parity) - bytes[i] |= 0x01; - else - bytes[i] &= 0xfe; - } -} -#endif /* USE_CURL_DES_SET_ODD_PARITY */ - -/* - * Turns a 56-bit key into being 64-bit wide. - */ -static void extend_key_56_to_64(const unsigned char *key_56, char *key) -{ - key[0] = (char)key_56[0]; - key[1] = (char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1)); - key[2] = (char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2)); - key[3] = (char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3)); - key[4] = (char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4)); - key[5] = (char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5)); - key[6] = (char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6)); - key[7] = (char)((key_56[6] << 1) & 0xFF); -} - -#ifdef USE_OPENSSL_DES -/* - * Turns a 56-bit key into a 64-bit, odd parity key and sets the key. The - * key schedule ks is also set. - */ -static void setup_des_key(const unsigned char *key_56, DES_key_schedule *ks) -{ - DES_cblock key; - - /* Expand the 56-bit key to 64 bits */ - extend_key_56_to_64(key_56, (char *)&key); - - /* Set the key parity to odd */ - DES_set_odd_parity(&key); - - /* Set the key */ - DES_set_key_unchecked(&key, ks); -} - -#elif defined(USE_WOLFSSL_DES) -static void setup_des_key(const unsigned char *key_56, Des *des) -{ - byte key[8]; - - /* Expand the 56-bit key to 64 bits */ - extend_key_56_to_64(key_56, (char *)key); - - /* Set the key */ - wc_Des_SetKey(des, key, NULL, 0); -} - -#elif defined(USE_GNUTLS) -static void setup_des_key(const unsigned char *key_56, struct des_ctx *des) -{ - char key[8]; - - /* Expand the 56-bit key to 64 bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - curl_des_set_odd_parity((unsigned char *)key, sizeof(key)); - - /* Set the key */ - des_set_key(des, (const uint8_t *)key); -} - -#elif defined(USE_MBEDTLS_DES) -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - mbedtls_des_context ctx; - char key[8]; - - /* Expand the 56-bit key to 64 bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - mbedtls_des_key_set_parity((unsigned char *)key); - - /* Perform the encryption */ - mbedtls_des_init(&ctx); - mbedtls_des_setkey_enc(&ctx, (unsigned char *)key); - return mbedtls_des_crypt_ecb(&ctx, in, out) == 0; -} - -#elif defined(USE_OS400CRYPTO) -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - char key[8]; - _CIPHER_Control_T ctl; - - /* Setup the cipher control structure */ - ctl.Func_ID = ENCRYPT_ONLY; - ctl.Data_Len = sizeof(key); - - /* Expand the 56-bit key to 64 bits */ - extend_key_56_to_64(key_56, ctl.Crypto_Key); - - /* Set the key parity to odd */ - curl_des_set_odd_parity((unsigned char *)ctl.Crypto_Key, ctl.Data_Len); - - /* Perform the encryption */ - _CIPHER((_SPCPTR *)&out, &ctl, (_SPCPTR *)&in); - - return TRUE; -} - -#elif defined(USE_WIN32_CRYPTO) -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - HCRYPTPROV hprov; - HCRYPTKEY hkey; - struct { - BLOBHEADER hdr; - unsigned int len; - char key[8]; - } blob; - DWORD len = 8; - - /* Acquire the crypto provider */ - if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return FALSE; - - /* Setup the key blob structure */ - memset(&blob, 0, sizeof(blob)); - blob.hdr.bType = PLAINTEXTKEYBLOB; - blob.hdr.bVersion = 2; - blob.hdr.aiKeyAlg = CALG_DES; - blob.len = sizeof(blob.key); - - /* Expand the 56-bit key to 64 bits */ - extend_key_56_to_64(key_56, blob.key); - - /* Set the key parity to odd */ - curl_des_set_odd_parity((unsigned char *)blob.key, sizeof(blob.key)); - - /* Import the key */ - if(!CryptImportKey(hprov, (BYTE *)&blob, sizeof(blob), 0, 0, &hkey)) { - CryptReleaseContext(hprov, 0); - - return FALSE; - } - - memcpy(out, in, 8); - - /* Perform the encryption */ - CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len); - - CryptDestroyKey(hkey); - CryptReleaseContext(hprov, 0); - - return TRUE; -} - -#endif /* crypto backends */ - -/* - * takes a 21 byte array and treats it as 3 56-bit DES keys. The - * 8 byte plaintext is encrypted with each key and the resulting 24 - * bytes are stored in the results array. - */ -void Curl_ntlm_core_lm_resp(const unsigned char *keys, - const unsigned char *plaintext, - unsigned char *results) -{ -#ifdef USE_OPENSSL_DES - DES_key_schedule ks; - - setup_des_key(keys, &ks); - DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(plaintext), - (DES_cblock *)results, &ks, DES_ENCRYPT); - - setup_des_key(keys + 7, &ks); - DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(plaintext), - (DES_cblock *)(results + 8), &ks, DES_ENCRYPT); - - setup_des_key(keys + 14, &ks); - DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(plaintext), - (DES_cblock *)(results + 16), &ks, DES_ENCRYPT); -#elif defined(USE_WOLFSSL_DES) - Des des; - setup_des_key(keys, &des); - wc_Des_EcbEncrypt(&des, results, plaintext, DES_KEY_SIZE); - setup_des_key(keys + 7, &des); - wc_Des_EcbEncrypt(&des, results + 8, plaintext, DES_KEY_SIZE); - setup_des_key(keys + 14, &des); - wc_Des_EcbEncrypt(&des, results + 16, plaintext, DES_KEY_SIZE); -#elif defined(USE_GNUTLS) - struct des_ctx des; - setup_des_key(keys, &des); - des_encrypt(&des, 8, results, plaintext); - setup_des_key(keys + 7, &des); - des_encrypt(&des, 8, results + 8, plaintext); - setup_des_key(keys + 14, &des); - des_encrypt(&des, 8, results + 16, plaintext); -#elif defined(USE_MBEDTLS_DES) || defined(USE_OS400CRYPTO) || \ - defined(USE_WIN32_CRYPTO) - encrypt_des(plaintext, results, keys); - encrypt_des(plaintext, results + 8, keys + 7); - encrypt_des(plaintext, results + 16, keys + 14); -#else - (void)keys; - (void)plaintext; - (void)results; -#endif -} - -/* - * Set up lanmanager hashed password - */ -CURLcode Curl_ntlm_core_mk_lm_hash(const char *password, - unsigned char *lmbuffer /* 21 bytes */) -{ - unsigned char pw[14]; - static const unsigned char magic[] = { - 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */ - }; - size_t len = CURLMIN(strlen(password), 14); - - Curl_strntoupper((char *)pw, password, len); - memset(&pw[len], 0, 14 - len); - - { - /* Create LanManager hashed password. */ -#ifdef USE_OPENSSL_DES - DES_key_schedule ks; - - setup_des_key(pw, &ks); - DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(magic), - (DES_cblock *)lmbuffer, &ks, DES_ENCRYPT); - - setup_des_key(pw + 7, &ks); - DES_ecb_encrypt((DES_cblock *)CURL_UNCONST(magic), - (DES_cblock *)(lmbuffer + 8), &ks, DES_ENCRYPT); -#elif defined(USE_WOLFSSL_DES) - Des des; - setup_des_key(pw, &des); - wc_Des_EcbEncrypt(&des, lmbuffer, magic, DES_KEY_SIZE); - setup_des_key(pw + 7, &des); - wc_Des_EcbEncrypt(&des, lmbuffer + 8, magic, DES_KEY_SIZE); -#elif defined(USE_GNUTLS) - struct des_ctx des; - setup_des_key(pw, &des); - des_encrypt(&des, 8, lmbuffer, magic); - setup_des_key(pw + 7, &des); - des_encrypt(&des, 8, lmbuffer + 8, magic); -#elif defined(USE_MBEDTLS_DES) || defined(USE_OS400CRYPTO) || \ - defined(USE_WIN32_CRYPTO) - encrypt_des(magic, lmbuffer, pw); - encrypt_des(magic, lmbuffer + 8, pw + 7); -#endif - - memset(lmbuffer + 16, 0, 21 - 16); - } - - return CURLE_OK; -} - -static void ascii_to_unicode_le(unsigned char *dest, const char *src, - size_t srclen) -{ - size_t i; - for(i = 0; i < srclen; i++) { - dest[2 * i] = (unsigned char)src[i]; - dest[(2 * i) + 1] = '\0'; - } -} - -/* - * Set up nt hashed passwords - * @unittest: 1600 - */ -CURLcode Curl_ntlm_core_mk_nt_hash(const char *password, - unsigned char *ntbuffer /* 21 bytes */) -{ - size_t len = strlen(password); - unsigned char *pw; - CURLcode result; - if(len > SIZE_MAX / 2) /* avoid integer overflow */ - return CURLE_OUT_OF_MEMORY; - pw = len ? curlx_malloc(len * 2) : (unsigned char *)curlx_strdup(""); - if(!pw) - return CURLE_OUT_OF_MEMORY; - - ascii_to_unicode_le(pw, password, len); - - /* Create NT hashed password. */ - result = Curl_md4it(ntbuffer, pw, 2 * len); - if(!result) - memset(ntbuffer + 16, 0, 21 - 16); - - curlx_free(pw); - - return result; -} - -#ifndef USE_WINDOWS_SSPI - -#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00" -#define NTLMv2_BLOB_LEN (44 - 16 + ntlm->target_info_len + 4) - -/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */ -struct ms_filetime { - unsigned int dwLowDateTime; - unsigned int dwHighDateTime; -}; - -/* Convert a time_t to an MS FILETIME (MS-DTYP section 2.3.3). */ -static void time2filetime(struct ms_filetime *ft, time_t t) -{ -#if SIZEOF_TIME_T > 4 - t = (t + (curl_off_t)11644473600) * 10000000; - ft->dwLowDateTime = (unsigned int)(t & 0xFFFFFFFF); - ft->dwHighDateTime = (unsigned int)(t >> 32); -#else - unsigned int r, s; - unsigned int i; - - ft->dwLowDateTime = (unsigned int)(t & 0xFFFFFFFF); - ft->dwHighDateTime = 0; - -#ifndef HAVE_TIME_T_UNSIGNED - /* Extend sign if needed. */ - if(ft->dwLowDateTime & 0x80000000) - ft->dwHighDateTime = ~(unsigned int)0; -#endif - - /* Bias seconds to Jan 1, 1601. - 134774 days = 11644473600 seconds = 0x2B6109100 */ - r = ft->dwLowDateTime; - ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF; - ft->dwHighDateTime += ft->dwLowDateTime < r ? 0x03 : 0x02; - - /* Convert to tenths of microseconds. */ - ft->dwHighDateTime *= 10000000; - i = 32; - do { - i -= 8; - s = ((ft->dwLowDateTime >> i) & 0xFF) * (10000000 - 1); - r = (s << i) & 0xFFFFFFFF; - s >>= 1; /* Split shift to avoid width overflow. */ - s >>= 31 - i; - ft->dwLowDateTime = (ft->dwLowDateTime + r) & 0xFFFFFFFF; - if(ft->dwLowDateTime < r) - s++; - ft->dwHighDateTime += s; - } while(i); - ft->dwHighDateTime &= 0xFFFFFFFF; -#endif -} - -static void ascii_uppercase_to_unicode_le(unsigned char *dest, - const char *src, size_t srclen) -{ - size_t i; - for(i = 0; i < srclen; i++) { - dest[2 * i] = (unsigned char)(Curl_raw_toupper(src[i])); - dest[(2 * i) + 1] = '\0'; - } -} - -/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode - * (uppercase UserName + Domain) as the data - */ -CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, - const char *domain, size_t domlen, - unsigned char *ntlmhash, - unsigned char *ntlmv2hash) -{ - /* Unicode representation */ - size_t identity_len; - unsigned char *identity; - CURLcode result = CURLE_OK; - - if((userlen > CURL_MAX_INPUT_LENGTH) || (domlen > CURL_MAX_INPUT_LENGTH)) - return CURLE_OUT_OF_MEMORY; - - identity_len = (userlen + domlen) * 2; - identity = curlx_malloc(identity_len + 1); - - if(!identity) - return CURLE_OUT_OF_MEMORY; - - ascii_uppercase_to_unicode_le(identity, user, userlen); - ascii_to_unicode_le(identity + (userlen << 1), domain, domlen); - - result = Curl_hmacit(&Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len, - ntlmv2hash); - curlx_free(identity); - - return result; -} - -/* - * Curl_ntlm_core_mk_ntlmv2_resp() - * - * This creates the NTLMv2 response as set in the NTLM type-3 message. - * - * Parameters: - * - * ntlmv2hash [in] - The NTLMv2 hash (16 bytes) - * challenge_client [in] - The client nonce (8 bytes) - * ntlm [in] - The NTLM data struct being used to read TargetInfo - and Server challenge received in the type-2 message - * ntresp [out] - The address where a pointer to newly allocated - * memory holding the NTLMv2 response. - * ntresp_len [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_ntlm_core_mk_ntlmv2_resp(const unsigned char *ntlmv2hash, - const unsigned char *challenge_client, - const struct ntlmdata *ntlm, - unsigned char **ntresp, - unsigned int *ntresp_len) -{ - /* NTLMv2 response structure : - ----------------------------------------------------------------------------- - 0 HMAC MD5 16 bytes - ------BLOB------------------------------------------------------------------- - 16 Signature 0x01010000 - 20 Reserved long (0x00000000) - 24 Timestamp LE, 64-bit signed value representing the number of - tenths of a microsecond since January 1, 1601. - 32 Client Nonce 8 bytes - 40 Unknown 4 bytes - 44 Target Info N bytes (from the type-2 message) - 44+N Unknown 4 bytes - ----------------------------------------------------------------------------- - */ - - unsigned int len = 0; - unsigned char *ptr = NULL; - unsigned char hmac_output[HMAC_MD5_LENGTH]; - struct ms_filetime tw; - - CURLcode result = CURLE_OK; - - /* Calculate the timestamp */ -#ifdef DEBUGBUILD - char *force_timestamp = getenv("CURL_FORCETIME"); - if(force_timestamp) - time2filetime(&tw, (time_t)0); - else -#endif - time2filetime(&tw, time(NULL)); - - /* Calculate the response len */ - len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN; - - /* Allocate the response */ - ptr = curlx_calloc(1, len); - if(!ptr) - return CURLE_OUT_OF_MEMORY; - - /* Create the BLOB structure */ - curl_msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN, - "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */ - "%c%c%c%c" /* Reserved = 0 */ - "%c%c%c%c%c%c%c%c", /* Timestamp */ - NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1], - NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3], - 0, 0, 0, 0, - LONGQUARTET(tw.dwLowDateTime), - LONGQUARTET(tw.dwHighDateTime)); - - memcpy(ptr + 32, challenge_client, 8); - if(ntlm->target_info_len) - memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len); - - /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */ - memcpy(ptr + 8, &ntlm->nonce[0], 8); - result = Curl_hmacit(&Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8, - NTLMv2_BLOB_LEN + 8, hmac_output); - if(result) { - curlx_free(ptr); - return result; - } - - /* Concatenate the HMAC MD5 output with the BLOB */ - memcpy(ptr, hmac_output, HMAC_MD5_LENGTH); - - /* Return the response */ - *ntresp = ptr; - *ntresp_len = len; - - return result; -} - -/* - * Curl_ntlm_core_mk_lmv2_resp() - * - * This creates the LMv2 response as used in the NTLM type-3 message. - * - * Parameters: - * - * ntlmv2hash [in] - The NTLMv2 hash (16 bytes) - * challenge_client [in] - The client nonce (8 bytes) - * challenge_client [in] - The server challenge (8 bytes) - * lmresp [out] - The LMv2 response (24 bytes) - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_ntlm_core_mk_lmv2_resp(const unsigned char *ntlmv2hash, - const unsigned char *challenge_client, - const unsigned char *challenge_server, - unsigned char *lmresp) -{ - unsigned char data[16]; - unsigned char hmac_output[16]; - CURLcode result = CURLE_OK; - - memcpy(&data[0], challenge_server, 8); - memcpy(&data[8], challenge_client, 8); - - result = Curl_hmacit(&Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16, - hmac_output); - if(result) - return result; - - /* Concatenate the HMAC MD5 output with the client nonce */ - memcpy(lmresp, hmac_output, 16); - memcpy(lmresp + 16, challenge_client, 8); - - return result; -} - -#endif /* !USE_WINDOWS_SSPI */ - -#endif /* USE_CURL_NTLM_CORE */ diff --git a/vendor/curl/lib/curl_ntlm_core.h b/vendor/curl/lib/curl_ntlm_core.h deleted file mode 100644 index f96bf0ada..000000000 --- a/vendor/curl/lib/curl_ntlm_core.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef HEADER_CURL_NTLM_CORE_H -#define HEADER_CURL_NTLM_CORE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_CURL_NTLM_CORE - -struct ntlmdata; - -/* Helpers to generate function byte arguments in little endian order */ -#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)) -#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \ - ((int)(((x) >> 16) & 0xff)), ((int)(((x) >> 24) & 0xff)) - -void Curl_ntlm_core_lm_resp(const unsigned char *keys, - const unsigned char *plaintext, - unsigned char *results); - -CURLcode Curl_ntlm_core_mk_lm_hash(const char *password, - unsigned char *lmbuffer /* 21 bytes */); - -CURLcode Curl_ntlm_core_mk_nt_hash(const char *password, - unsigned char *ntbuffer /* 21 bytes */); - -#ifndef USE_WINDOWS_SSPI - -CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen, - const unsigned char *data, unsigned int datalen, - unsigned char *output); - -CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, - const char *domain, size_t domlen, - unsigned char *ntlmhash, - unsigned char *ntlmv2hash); - -CURLcode Curl_ntlm_core_mk_ntlmv2_resp(const unsigned char *ntlmv2hash, - const unsigned char *challenge_client, - const struct ntlmdata *ntlm, - unsigned char **ntresp, - unsigned int *ntresp_len); - -CURLcode Curl_ntlm_core_mk_lmv2_resp(const unsigned char *ntlmv2hash, - const unsigned char *challenge_client, - const unsigned char *challenge_server, - unsigned char *lmresp); - -#endif /* !USE_WINDOWS_SSPI */ - -#endif /* USE_CURL_NTLM_CORE */ - -#endif /* HEADER_CURL_NTLM_CORE_H */ diff --git a/vendor/curl/lib/curl_printf.h b/vendor/curl/lib/curl_printf.h deleted file mode 100644 index 3b1a5af3b..000000000 --- a/vendor/curl/lib/curl_printf.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADER_CURL_PRINTF_H -#define HEADER_CURL_PRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#define MERR_OK 0 -#define MERR_MEM 1 -#define MERR_TOO_LARGE 2 - -/* Lower-case digits. */ -extern const unsigned char Curl_ldigits[]; - -/* Upper-case digits. */ -extern const unsigned char Curl_udigits[]; - -#endif /* HEADER_CURL_PRINTF_H */ diff --git a/vendor/curl/lib/curl_range.c b/vendor/curl/lib/curl_range.c deleted file mode 100644 index 9bbafa40c..000000000 --- a/vendor/curl/lib/curl_range.c +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curl_range.h" -#include "curl_trc.h" -#include "curlx/strparse.h" - -/* Only include this function if one or more of FTP, FILE are enabled. */ -#if !defined(CURL_DISABLE_FTP) || !defined(CURL_DISABLE_FILE) - -/* Check if this is a range download, and if so, set the internal variables - properly. */ -CURLcode Curl_range(struct Curl_easy *data) -{ - if(data->state.use_range && data->state.range) { - curl_off_t from, to; - bool first_num = TRUE; - const char *p = data->state.range; - if(curlx_str_number(&p, &from, CURL_OFF_T_MAX)) - first_num = FALSE; - - if(curlx_str_single(&p, '-')) - /* no leading dash or after the first number is an error */ - return CURLE_RANGE_ERROR; - - if(curlx_str_number(&p, &to, CURL_OFF_T_MAX)) { - /* no second number */ - /* X - */ - data->state.resume_from = from; - DEBUGF(infof(data, "RANGE %" FMT_OFF_T " to end of file", from)); - } - else if(!first_num) { - /* -Y */ - if(!to) - /* "-0" is wrong */ - return CURLE_RANGE_ERROR; - - data->req.maxdownload = to; - data->state.resume_from = -to; - DEBUGF(infof(data, "RANGE the last %" FMT_OFF_T " bytes", to)); - } - else { - /* X-Y */ - curl_off_t totalsize; - - /* Ensure the range is sensible - to should follow from. */ - if(from > to) - return CURLE_RANGE_ERROR; - - totalsize = to - from; - if(totalsize == CURL_OFF_T_MAX) - return CURLE_RANGE_ERROR; - - data->req.maxdownload = totalsize + 1; /* include last byte */ - data->state.resume_from = from; - DEBUGF(infof(data, "RANGE from %" FMT_OFF_T - " getting %" FMT_OFF_T " bytes", - from, data->req.maxdownload)); - } - DEBUGF(infof(data, "range-download from %" FMT_OFF_T - " to %" FMT_OFF_T ", totally %" FMT_OFF_T " bytes", - from, to, data->req.maxdownload)); - } - else - data->req.maxdownload = -1; - return CURLE_OK; -} - -#endif diff --git a/vendor/curl/lib/curl_range.h b/vendor/curl/lib/curl_range.h deleted file mode 100644 index 97354677c..000000000 --- a/vendor/curl/lib/curl_range.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_RANGE_H -#define HEADER_CURL_RANGE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" - -CURLcode Curl_range(struct Curl_easy *data); -#endif /* HEADER_CURL_RANGE_H */ diff --git a/vendor/curl/lib/curl_sasl.c b/vendor/curl/lib/curl_sasl.c deleted file mode 100644 index 60f085901..000000000 --- a/vendor/curl/lib/curl_sasl.c +++ /dev/null @@ -1,933 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC2195 CRAM-MD5 authentication - * RFC2617 Basic and Digest Access Authentication - * RFC2831 DIGEST-MD5 authentication - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC5802 SCRAM-SHA-1 authentication - * RFC7677 SCRAM-SHA-256 authentication - * RFC6749 OAuth 2.0 Authorization Framework - * RFC7628 A Set of SASL Mechanisms for OAuth - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_POP3) || \ - (!defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)) - -#include "urldata.h" -#include "curlx/base64.h" -#include "vauth/vauth.h" -#include "cfilters.h" -#include "curl_sasl.h" -#include "curl_trc.h" - -/* Supported mechanisms */ -static const struct { - const char *name; /* Name */ - size_t len; /* Name length */ - unsigned short bit; /* Flag bit */ -} mechtable[] = { - { "LOGIN", 5, SASL_MECH_LOGIN }, - { "PLAIN", 5, SASL_MECH_PLAIN }, - { "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 }, - { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 }, - { "GSSAPI", 6, SASL_MECH_GSSAPI }, - { "EXTERNAL", 8, SASL_MECH_EXTERNAL }, - { "NTLM", 4, SASL_MECH_NTLM }, - { "XOAUTH2", 7, SASL_MECH_XOAUTH2 }, - { "OAUTHBEARER", 11, SASL_MECH_OAUTHBEARER }, - { "SCRAM-SHA-1", 11, SASL_MECH_SCRAM_SHA_1 }, - { "SCRAM-SHA-256",13, SASL_MECH_SCRAM_SHA_256 }, - { ZERO_NULL, 0, 0 } -}; - -/* - * Curl_sasl_decode_mech() - * - * Convert a SASL mechanism name into a token. - * - * Parameters: - * - * ptr [in] - The mechanism string. - * maxlen [in] - Maximum mechanism string length. - * len [out] - If not NULL, effective name length. - * - * Returns the SASL mechanism token or 0 if no match. - */ -unsigned short Curl_sasl_decode_mech(const char *ptr, size_t maxlen, - size_t *len) -{ - unsigned int i; - char c; - - for(i = 0; mechtable[i].name; i++) { - if(maxlen >= mechtable[i].len && - curl_strnequal(ptr, mechtable[i].name, mechtable[i].len)) { - if(len) - *len = mechtable[i].len; - - if(maxlen == mechtable[i].len) - return mechtable[i].bit; - - c = ptr[mechtable[i].len]; - if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_') - return mechtable[i].bit; - } - } - - return 0; -} - -/* - * Curl_sasl_parse_url_auth_option() - * - * Parse the URL login options. - */ -CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, - const char *value, size_t len) -{ - CURLcode result = CURLE_OK; - size_t mechlen; - - if(!len) - return CURLE_URL_MALFORMAT; - - if(sasl->resetprefs) { - sasl->resetprefs = FALSE; - sasl->prefmech = SASL_AUTH_NONE; - } - - if(!strncmp(value, "*", len)) - sasl->prefmech = SASL_AUTH_DEFAULT; - else { - unsigned short mechbit = Curl_sasl_decode_mech(value, len, &mechlen); - if(mechbit && mechlen == len) - sasl->prefmech |= mechbit; - else - result = CURLE_URL_MALFORMAT; - } - - return result; -} - -/* - * Curl_sasl_init() - * - * Initializes the SASL structure. - */ -void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data, - const struct SASLproto *params) -{ - unsigned long auth = data->set.httpauth; - - sasl->params = params; /* Set protocol dependent parameters */ - sasl->state = SASL_STOP; /* Not yet running */ - sasl->curmech = NULL; /* No mechanism yet. */ - sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */ - sasl->prefmech = params->defmechs; /* Default preferred mechanisms */ - sasl->authused = SASL_AUTH_NONE; /* The authentication mechanism used */ - sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */ - sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */ - sasl->force_ir = FALSE; /* Respect external option */ - - if(auth != CURLAUTH_BASIC) { - unsigned short mechs = SASL_AUTH_NONE; - - /* If some usable http authentication options have been set, determine - new defaults from them. */ - if(auth & CURLAUTH_BASIC) - mechs |= SASL_MECH_PLAIN | SASL_MECH_LOGIN; - if(auth & CURLAUTH_DIGEST) - mechs |= SASL_MECH_DIGEST_MD5; - if(auth & CURLAUTH_NTLM) - mechs |= SASL_MECH_NTLM; - if(auth & CURLAUTH_BEARER) - mechs |= SASL_MECH_OAUTHBEARER | SASL_MECH_XOAUTH2; - if(auth & CURLAUTH_GSSAPI) - mechs |= SASL_MECH_GSSAPI; - - if(mechs != SASL_AUTH_NONE) - sasl->prefmech = mechs; - } -} - -/* - * sasl_state() - * - * This is the ONLY way to change SASL state! - */ -static void sasl_state(struct SASL *sasl, struct Curl_easy *data, - saslstate newstate) -{ -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - /* for debug purposes */ - static const char * const names[] = { - "STOP", - "PLAIN", - "LOGIN", - "LOGIN_PASSWD", - "EXTERNAL", - "CRAMMD5", - "DIGESTMD5", - "DIGESTMD5_RESP", - "NTLM", - "NTLM_TYPE2MSG", - "GSSAPI", - "GSSAPI_TOKEN", - "GSSAPI_NO_DATA", - "OAUTH2", - "OAUTH2_RESP", - "GSASL", - "CANCEL", - "FINAL", - /* LAST */ - }; - - if(sasl->state != newstate) - infof(data, "SASL %p state change from %s to %s", - (void *)sasl, names[sasl->state], names[newstate]); -#else - (void)data; -#endif - - sasl->state = newstate; -} - -#if defined(USE_NTLM) || defined(USE_GSASL) || defined(USE_KERBEROS5) || \ - !defined(CURL_DISABLE_DIGEST_AUTH) -/* Get the SASL server message and convert it to binary. */ -static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data, - struct bufref *out) -{ - CURLcode result = CURLE_OK; - - result = sasl->params->getmessage(data, out); - if(!result && (sasl->params->flags & SASL_FLAG_BASE64)) { - const char *serverdata = Curl_bufref_ptr(out); - - if(!*serverdata || *serverdata == '=') - Curl_bufref_set(out, NULL, 0, NULL); - else { - unsigned char *msg; - size_t msglen; - - result = curlx_base64_decode(serverdata, &msg, &msglen); - if(!result) - Curl_bufref_set(out, msg, msglen, curl_free); - } - } - return result; -} -#endif - -/* Encode the outgoing SASL message. */ -static CURLcode build_message(struct SASL *sasl, struct bufref *msg) -{ - CURLcode result = CURLE_OK; - - if(sasl->params->flags & SASL_FLAG_BASE64) { - if(!Curl_bufref_ptr(msg)) /* Empty message. */ - Curl_bufref_set(msg, "", 0, NULL); - else if(!Curl_bufref_len(msg)) /* Explicit empty response. */ - Curl_bufref_set(msg, "=", 1, NULL); - else { - char *base64; - size_t base64len; - - result = curlx_base64_encode(Curl_bufref_uptr(msg), - Curl_bufref_len(msg), &base64, &base64len); - if(!result) - Curl_bufref_set(msg, base64, base64len, curl_free); - } - } - - return result; -} - -/* - * Curl_sasl_can_authenticate() - * - * Check if we have enough auth data and capabilities to authenticate. - */ -bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data) -{ - /* Have credentials been provided? */ - if(data->conn->user[0]) - return TRUE; - - /* EXTERNAL can authenticate without a username and/or password */ - if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL) - return TRUE; - - return FALSE; -} - -struct sasl_ctx { - struct SASL *sasl; - struct connectdata *conn; - unsigned short enabledmechs; - const char *mech; - saslstate state1; - saslstate state2; - struct bufref resp; - CURLcode result; -}; - -static bool sasl_choose_external(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - if((sctx->enabledmechs & SASL_MECH_EXTERNAL) && !sctx->conn->passwd[0]) { - sctx->mech = SASL_MECH_STRING_EXTERNAL; - sctx->state1 = SASL_EXTERNAL; - sctx->sasl->authused = SASL_MECH_EXTERNAL; - - if(sctx->sasl->force_ir || data->set.sasl_ir) - Curl_auth_create_external_message(sctx->conn->user, &sctx->resp); - return TRUE; - } - return FALSE; -} - -#ifdef USE_KERBEROS5 -static bool sasl_choose_krb5(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - if((sctx->enabledmechs & SASL_MECH_GSSAPI) && - Curl_auth_is_gssapi_supported() && - Curl_auth_user_contains_domain(sctx->conn->user)) { - const char *service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : - sctx->sasl->params->service; - - sctx->sasl->mutual_auth = FALSE; - sctx->mech = SASL_MECH_STRING_GSSAPI; - sctx->state1 = SASL_GSSAPI; - sctx->state2 = SASL_GSSAPI_TOKEN; - sctx->sasl->authused = SASL_MECH_GSSAPI; - - if(sctx->sasl->force_ir || data->set.sasl_ir) { - struct kerberos5data *krb5 = Curl_auth_krb5_get(sctx->conn); - sctx->result = !krb5 ? CURLE_OUT_OF_MEMORY : - Curl_auth_create_gssapi_user_message(data, sctx->conn->user, - sctx->conn->passwd, - service, sctx->conn->host.name, - (bool)sctx->sasl->mutual_auth, - NULL, krb5, &sctx->resp); - } - return TRUE; - } - return FALSE; -} -#endif /* USE_KERBEROS5 */ - -#ifdef USE_GSASL -static bool sasl_choose_gsasl(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - struct gsasldata *gsasl; - struct bufref nullmsg; - - if((sctx->enabledmechs & - (SASL_MECH_SCRAM_SHA_256 | SASL_MECH_SCRAM_SHA_1))) { - gsasl = Curl_auth_gsasl_get(sctx->conn); - if(!gsasl) { - sctx->result = CURLE_OUT_OF_MEMORY; - return TRUE; /* attempted, but failed */ - } - - if((sctx->enabledmechs & SASL_MECH_SCRAM_SHA_256) && - Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256, - gsasl)) { - sctx->mech = SASL_MECH_STRING_SCRAM_SHA_256; - sctx->sasl->authused = SASL_MECH_SCRAM_SHA_256; - } - else if((sctx->enabledmechs & SASL_MECH_SCRAM_SHA_1) && - Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1, - gsasl)) { - sctx->mech = SASL_MECH_STRING_SCRAM_SHA_1; - sctx->sasl->authused = SASL_MECH_SCRAM_SHA_1; - } - else - return FALSE; - - Curl_bufref_init(&nullmsg); - sctx->state1 = SASL_GSASL; - sctx->state2 = SASL_GSASL; - sctx->result = Curl_auth_gsasl_start(data, sctx->conn->user, - sctx->conn->passwd, gsasl); - if(!sctx->result && (sctx->sasl->force_ir || data->set.sasl_ir)) - sctx->result = Curl_auth_gsasl_token(data, &nullmsg, gsasl, &sctx->resp); - return TRUE; - } - return FALSE; -} - -#endif /* USE_GSASL */ - -#ifndef CURL_DISABLE_DIGEST_AUTH -static bool sasl_choose_digest(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - (void)data; - if((sctx->enabledmechs & SASL_MECH_DIGEST_MD5) && - Curl_auth_is_digest_supported()) { - sctx->mech = SASL_MECH_STRING_DIGEST_MD5; - sctx->state1 = SASL_DIGESTMD5; - sctx->sasl->authused = SASL_MECH_DIGEST_MD5; - return TRUE; - } - else if(sctx->enabledmechs & SASL_MECH_CRAM_MD5) { - sctx->mech = SASL_MECH_STRING_CRAM_MD5; - sctx->state1 = SASL_CRAMMD5; - sctx->sasl->authused = SASL_MECH_CRAM_MD5; - return TRUE; - } - return FALSE; -} -#endif /* !CURL_DISABLE_DIGEST_AUTH */ - -#ifdef USE_NTLM -static bool sasl_choose_ntlm(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - if((sctx->enabledmechs & SASL_MECH_NTLM) && - Curl_auth_is_ntlm_supported()) { - const char *service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : - sctx->sasl->params->service; - const char *hostname; - - Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, NULL); - - sctx->mech = SASL_MECH_STRING_NTLM; - sctx->state1 = SASL_NTLM; - sctx->state2 = SASL_NTLM_TYPE2MSG; - sctx->sasl->authused = SASL_MECH_NTLM; - - if(sctx->sasl->force_ir || data->set.sasl_ir) { - struct ntlmdata *ntlm = Curl_auth_ntlm_get(sctx->conn, FALSE); - sctx->result = !ntlm ? CURLE_OUT_OF_MEMORY : - Curl_auth_create_ntlm_type1_message(data, - sctx->conn->user, - sctx->conn->passwd, - service, hostname, - ntlm, &sctx->resp); - } - return TRUE; - } - return FALSE; -} -#endif /* USE_NTLM */ - -static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - const char *oauth_bearer = - (!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ? - data->set.str[STRING_BEARER] : NULL; - - if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) { - const char *hostname; - int port; - Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port); - - sctx->mech = SASL_MECH_STRING_OAUTHBEARER; - sctx->state1 = SASL_OAUTH2; - sctx->state2 = SASL_OAUTH2_RESP; - sctx->sasl->authused = SASL_MECH_OAUTHBEARER; - - if(sctx->sasl->force_ir || data->set.sasl_ir) - sctx->result = - Curl_auth_create_oauth_bearer_message(sctx->conn->user, - hostname, port, - oauth_bearer, &sctx->resp); - return TRUE; - } - return FALSE; -} - -static bool sasl_choose_oauth2(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - const char *oauth_bearer = - (!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ? - data->set.str[STRING_BEARER] : NULL; - - if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_XOAUTH2)) { - sctx->mech = SASL_MECH_STRING_XOAUTH2; - sctx->state1 = SASL_OAUTH2; - sctx->sasl->authused = SASL_MECH_XOAUTH2; - - if(sctx->sasl->force_ir || data->set.sasl_ir) - sctx->result = Curl_auth_create_xoauth_bearer_message(sctx->conn->user, - oauth_bearer, - &sctx->resp); - return TRUE; - } - return FALSE; -} - -static bool sasl_choose_plain(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - if(sctx->enabledmechs & SASL_MECH_PLAIN) { - sctx->mech = SASL_MECH_STRING_PLAIN; - sctx->state1 = SASL_PLAIN; - sctx->sasl->authused = SASL_MECH_PLAIN; - - if(sctx->sasl->force_ir || data->set.sasl_ir) - sctx->result = - Curl_auth_create_plain_message(sctx->conn->sasl_authzid, - sctx->conn->user, sctx->conn->passwd, - &sctx->resp); - return TRUE; - } - return FALSE; -} - -static bool sasl_choose_login(struct Curl_easy *data, struct sasl_ctx *sctx) -{ - if(sctx->enabledmechs & SASL_MECH_LOGIN) { - sctx->mech = SASL_MECH_STRING_LOGIN; - sctx->state1 = SASL_LOGIN; - sctx->state2 = SASL_LOGIN_PASSWD; - sctx->sasl->authused = SASL_MECH_LOGIN; - - if(sctx->sasl->force_ir || data->set.sasl_ir) - Curl_auth_create_login_message(sctx->conn->user, &sctx->resp); - return TRUE; - } - return FALSE; -} - -/* - * Curl_sasl_start() - * - * Calculate the required login details for SASL authentication. - */ -CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, - bool force_ir, saslprogress *progress) -{ - struct sasl_ctx sctx; - - sasl->force_ir = force_ir; /* Latch for future use */ - sasl->authused = 0; /* No mechanism used yet */ - *progress = SASL_IDLE; - - memset(&sctx, 0, sizeof(sctx)); - sctx.sasl = sasl; - sctx.conn = data->conn; - Curl_bufref_init(&sctx.resp); - sctx.enabledmechs = sasl->authmechs & sasl->prefmech; - sctx.state1 = SASL_STOP; - sctx.state2 = SASL_FINAL; - - /* Calculate the supported authentication mechanism, by decreasing order of - security, as well as the initial response where appropriate */ - if(sasl_choose_external(data, &sctx) || -#ifdef USE_KERBEROS5 - sasl_choose_krb5(data, &sctx) || -#endif -#ifdef USE_GSASL - sasl_choose_gsasl(data, &sctx) || -#endif -#ifndef CURL_DISABLE_DIGEST_AUTH - sasl_choose_digest(data, &sctx) || -#endif -#ifdef USE_NTLM - sasl_choose_ntlm(data, &sctx) || -#endif - sasl_choose_oauth(data, &sctx) || - sasl_choose_oauth2(data, &sctx) || - sasl_choose_plain(data, &sctx) || - sasl_choose_login(data, &sctx)) { - /* selected, either we have a mechanism or a failure */ - DEBUGASSERT(sctx.mech || sctx.result); - } - - if(!sctx.result && sctx.mech) { - sasl->curmech = sctx.mech; - if(Curl_bufref_ptr(&sctx.resp)) - sctx.result = build_message(sasl, &sctx.resp); - - if(sasl->params->maxirlen && - strlen(sctx.mech) + Curl_bufref_len(&sctx.resp) > - sasl->params->maxirlen) - Curl_bufref_free(&sctx.resp); - - if(!sctx.result) - sctx.result = sasl->params->sendauth(data, sctx.mech, &sctx.resp); - - if(!sctx.result) { - *progress = SASL_INPROGRESS; - sasl_state(sasl, data, Curl_bufref_ptr(&sctx.resp) ? - sctx.state2 : sctx.state1); - } - } - - Curl_bufref_free(&sctx.resp); - return sctx.result; -} - -/* - * Curl_sasl_continue() - * - * Continue the authentication. - */ -CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, - int code, saslprogress *progress) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - saslstate newstate = SASL_FINAL; - struct bufref resp; - const char *hostname; - int port; -#if defined(USE_KERBEROS5) || defined(USE_NTLM) || \ - !defined(CURL_DISABLE_DIGEST_AUTH) - const char *service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : - sasl->params->service; -#endif - const char *oauth_bearer = data->set.str[STRING_BEARER]; - struct bufref serverdata; - - Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port); - Curl_bufref_init(&serverdata); - Curl_bufref_init(&resp); - *progress = SASL_INPROGRESS; - - if(sasl->state == SASL_FINAL) { - if(code != sasl->params->finalcode) - result = CURLE_LOGIN_DENIED; - *progress = SASL_DONE; - sasl_state(sasl, data, SASL_STOP); - return result; - } - - if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP && - code != sasl->params->contcode) { - *progress = SASL_DONE; - sasl_state(sasl, data, SASL_STOP); - return CURLE_LOGIN_DENIED; - } - - switch(sasl->state) { - case SASL_STOP: - *progress = SASL_DONE; - return result; - case SASL_PLAIN: - result = Curl_auth_create_plain_message(conn->sasl_authzid, - conn->user, conn->passwd, &resp); - break; - case SASL_LOGIN: - Curl_auth_create_login_message(conn->user, &resp); - newstate = SASL_LOGIN_PASSWD; - break; - case SASL_LOGIN_PASSWD: - Curl_auth_create_login_message(conn->passwd, &resp); - break; - case SASL_EXTERNAL: - Curl_auth_create_external_message(conn->user, &resp); - break; -#ifdef USE_GSASL - case SASL_GSASL: - result = get_server_message(sasl, data, &serverdata); - if(!result) { - struct gsasldata *gsasl = Curl_auth_gsasl_get(conn); - result = !gsasl ? CURLE_OUT_OF_MEMORY : - Curl_auth_gsasl_token(data, &serverdata, gsasl, &resp); - } - if(!result && Curl_bufref_len(&resp) > 0) - newstate = SASL_GSASL; - break; -#endif -#ifndef CURL_DISABLE_DIGEST_AUTH - case SASL_CRAMMD5: - result = get_server_message(sasl, data, &serverdata); - if(!result) - result = Curl_auth_create_cram_md5_message(&serverdata, conn->user, - conn->passwd, &resp); - break; - case SASL_DIGESTMD5: - result = get_server_message(sasl, data, &serverdata); - if(!result) - result = Curl_auth_create_digest_md5_message(data, &serverdata, - conn->user, conn->passwd, - service, &resp); - if(!result && (sasl->params->flags & SASL_FLAG_BASE64)) - newstate = SASL_DIGESTMD5_RESP; - break; - case SASL_DIGESTMD5_RESP: - /* Keep response NULL to output an empty line. */ - break; -#endif - -#ifdef USE_NTLM - case SASL_NTLM: { - /* Create the type-1 message */ - struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE); - result = !ntlm ? CURLE_OUT_OF_MEMORY : - Curl_auth_create_ntlm_type1_message(data, - conn->user, conn->passwd, - service, hostname, - ntlm, &resp); - newstate = SASL_NTLM_TYPE2MSG; - break; - } - case SASL_NTLM_TYPE2MSG: { - /* Decode the type-2 message */ - struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE); - result = !ntlm ? CURLE_OUT_OF_MEMORY : - get_server_message(sasl, data, &serverdata); - if(!result) - result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, ntlm); - if(!result) - result = Curl_auth_create_ntlm_type3_message(data, conn->user, - conn->passwd, ntlm, - &resp); - break; - } -#endif - -#ifdef USE_KERBEROS5 - case SASL_GSSAPI: { - struct kerberos5data *krb5 = Curl_auth_krb5_get(conn); - result = !krb5 ? CURLE_OUT_OF_MEMORY : - Curl_auth_create_gssapi_user_message(data, conn->user, conn->passwd, - service, conn->host.name, - (bool)sasl->mutual_auth, NULL, - krb5, &resp); - newstate = SASL_GSSAPI_TOKEN; - break; - } - case SASL_GSSAPI_TOKEN: - result = get_server_message(sasl, data, &serverdata); - if(!result) { - struct kerberos5data *krb5 = Curl_auth_krb5_get(conn); - if(!krb5) - result = CURLE_OUT_OF_MEMORY; - else if(sasl->mutual_auth) { - /* Decode the user token challenge and create the optional response - message */ - result = Curl_auth_create_gssapi_user_message(data, NULL, NULL, - NULL, NULL, - (bool)sasl->mutual_auth, - &serverdata, - krb5, &resp); - newstate = SASL_GSSAPI_NO_DATA; - } - else - /* Decode the security challenge and create the response message */ - result = Curl_auth_create_gssapi_security_message(data, - conn->sasl_authzid, - &serverdata, - krb5, &resp); - } - break; - case SASL_GSSAPI_NO_DATA: - /* Decode the security challenge and create the response message */ - result = get_server_message(sasl, data, &serverdata); - if(!result) { - struct kerberos5data *krb5 = Curl_auth_krb5_get(conn); - if(!krb5) - result = CURLE_OUT_OF_MEMORY; - else - result = Curl_auth_create_gssapi_security_message(data, - conn->sasl_authzid, - &serverdata, - krb5, &resp); - } - break; -#endif - - case SASL_OAUTH2: - /* Create the authorization message */ - if(sasl->authused == SASL_MECH_OAUTHBEARER) { - result = Curl_auth_create_oauth_bearer_message(conn->user, - hostname, - port, - oauth_bearer, - &resp); - - /* Failures maybe sent by the server as continuations for OAUTHBEARER */ - newstate = SASL_OAUTH2_RESP; - } - else - result = Curl_auth_create_xoauth_bearer_message(conn->user, - oauth_bearer, - &resp); - break; - - case SASL_OAUTH2_RESP: - /* The continuation is optional so check the response code */ - if(code == sasl->params->finalcode) { - /* Final response was received so we are done */ - *progress = SASL_DONE; - sasl_state(sasl, data, SASL_STOP); - return result; - } - else if(code == sasl->params->contcode) { - /* Acknowledge the continuation by sending a 0x01 response. */ - Curl_bufref_set(&resp, "\x01", 1, NULL); - break; - } - else { - *progress = SASL_DONE; - sasl_state(sasl, data, SASL_STOP); - return CURLE_LOGIN_DENIED; - } - - case SASL_CANCEL: - /* Remove the offending mechanism from the supported list */ - sasl->authmechs &= (unsigned short)~sasl->authused; - sasl->authused = SASL_AUTH_NONE; - sasl->curmech = NULL; - - /* Start an alternative SASL authentication */ - return Curl_sasl_start(sasl, data, (bool)sasl->force_ir, progress); - default: - failf(data, "Unsupported SASL authentication mechanism"); - result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */ - break; - } - - Curl_bufref_free(&serverdata); - - switch(result) { - case CURLE_BAD_CONTENT_ENCODING: - /* Cancel dialog */ - result = sasl->params->cancelauth(data, sasl->curmech); - newstate = SASL_CANCEL; - break; - case CURLE_OK: - result = build_message(sasl, &resp); - if(!result) - result = sasl->params->contauth(data, sasl->curmech, &resp); - break; - default: - newstate = SASL_STOP; /* Stop on error */ - *progress = SASL_DONE; - break; - } - - Curl_bufref_free(&resp); - - sasl_state(sasl, data, newstate); - - return result; -} - -#ifdef CURLVERBOSE -static void sasl_unchosen(struct Curl_easy *data, unsigned short mech, - unsigned short enabledmechs, - bool built_in, bool platform, - const char *param_missing) -{ - const char *mname = NULL; - size_t i; - - if(!(enabledmechs & mech)) - return; - - for(i = 0; mechtable[i].name; ++i) { - if(mechtable[i].bit == mech) { - mname = mechtable[i].name; - break; - } - } - if(!mname) /* should not happen */ - return; - if(!built_in) - infof(data, "SASL: %s not builtin", mname); - else if(!platform) - infof(data, "SASL: %s not supported by the platform/libraries", mname); - else { - if(param_missing) - infof(data, "SASL: %s is missing %s", mname, param_missing); - if(!data->conn->user[0]) - infof(data, "SASL: %s is missing username", mname); - } -} -#endif /* CURLVERBOSE */ - -CURLcode Curl_sasl_is_blocked(struct SASL *sasl, struct Curl_easy *data) -{ -#ifdef CURLVERBOSE -#ifdef USE_KERBEROS5 -#define CURL_SASL_KERBEROS5 TRUE -#else -#define CURL_SASL_KERBEROS5 FALSE -#endif -#ifdef USE_GSASL -#define CURL_SASL_GASL TRUE -#else -#define CURL_SASL_GASL FALSE -#endif -#ifdef CURL_DISABLE_DIGEST_AUTH -#define CURL_SASL_DIGEST TRUE -#else -#define CURL_SASL_DIGEST FALSE -#endif -#ifndef USE_NTLM -#define CURL_SASL_NTLM TRUE -#else -#define CURL_SASL_NTLM FALSE -#endif - /* Failing SASL authentication is a pain. Give a helping hand if - * we were unable to select an AUTH mechanism. - * `sasl->authmechs` are mechanisms offered by the peer - * `sasl->prefmech` are mechanisms preferred by us */ - unsigned short enabledmechs = sasl->authmechs & sasl->prefmech; - - if(!sasl->authmechs) - infof(data, "SASL: no auth mechanism was offered or recognized"); - else if(!enabledmechs) - infof(data, "SASL: no overlap between offered and configured " - "auth mechanisms"); - else { - infof(data, "SASL: no auth mechanism offered could be selected"); - if((enabledmechs & SASL_MECH_EXTERNAL) && data->conn->passwd[0]) - infof(data, "SASL: auth EXTERNAL not chosen with password"); - sasl_unchosen(data, SASL_MECH_GSSAPI, enabledmechs, - CURL_SASL_KERBEROS5, Curl_auth_is_gssapi_supported(), NULL); - sasl_unchosen(data, SASL_MECH_SCRAM_SHA_256, enabledmechs, - CURL_SASL_GASL, FALSE, NULL); - sasl_unchosen(data, SASL_MECH_SCRAM_SHA_1, enabledmechs, - CURL_SASL_GASL, FALSE, NULL); - sasl_unchosen(data, SASL_MECH_DIGEST_MD5, enabledmechs, - CURL_SASL_DIGEST, Curl_auth_is_digest_supported(), NULL); - sasl_unchosen(data, SASL_MECH_CRAM_MD5, enabledmechs, - CURL_SASL_DIGEST, TRUE, NULL); - sasl_unchosen(data, SASL_MECH_NTLM, enabledmechs, - CURL_SASL_NTLM, Curl_auth_is_ntlm_supported(), NULL); - sasl_unchosen(data, SASL_MECH_OAUTHBEARER, enabledmechs, TRUE, TRUE, - data->set.str[STRING_BEARER] ? - NULL : "CURLOPT_XOAUTH2_BEARER"); - sasl_unchosen(data, SASL_MECH_XOAUTH2, enabledmechs, TRUE, TRUE, - data->set.str[STRING_BEARER] ? - NULL : "CURLOPT_XOAUTH2_BEARER"); - } -#endif /* CURLVERBOSE */ - (void)sasl; - (void)data; - return CURLE_LOGIN_DENIED; -} - -#endif /* protocols are enabled that use SASL */ diff --git a/vendor/curl/lib/curl_sasl.h b/vendor/curl/lib/curl_sasl.h deleted file mode 100644 index 8a97f52ad..000000000 --- a/vendor/curl/lib/curl_sasl.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef HEADER_CURL_SASL_H -#define HEADER_CURL_SASL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "bufref.h" - -struct Curl_easy; -struct connectdata; - -/* Authentication mechanism flags */ -#define SASL_MECH_LOGIN (1 << 0) -#define SASL_MECH_PLAIN (1 << 1) -#define SASL_MECH_CRAM_MD5 (1 << 2) -#define SASL_MECH_DIGEST_MD5 (1 << 3) -#define SASL_MECH_GSSAPI (1 << 4) -#define SASL_MECH_EXTERNAL (1 << 5) -#define SASL_MECH_NTLM (1 << 6) -#define SASL_MECH_XOAUTH2 (1 << 7) -#define SASL_MECH_OAUTHBEARER (1 << 8) -#define SASL_MECH_SCRAM_SHA_1 (1 << 9) -#define SASL_MECH_SCRAM_SHA_256 (1 << 10) - -/* Authentication mechanism values */ -#define SASL_AUTH_NONE 0 -#define SASL_AUTH_ANY 0xffff -#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL) - -/* Authentication mechanism strings */ -#define SASL_MECH_STRING_LOGIN "LOGIN" -#define SASL_MECH_STRING_PLAIN "PLAIN" -#define SASL_MECH_STRING_CRAM_MD5 "CRAM-MD5" -#define SASL_MECH_STRING_DIGEST_MD5 "DIGEST-MD5" -#define SASL_MECH_STRING_GSSAPI "GSSAPI" -#define SASL_MECH_STRING_EXTERNAL "EXTERNAL" -#define SASL_MECH_STRING_NTLM "NTLM" -#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2" -#define SASL_MECH_STRING_OAUTHBEARER "OAUTHBEARER" -#define SASL_MECH_STRING_SCRAM_SHA_1 "SCRAM-SHA-1" -#define SASL_MECH_STRING_SCRAM_SHA_256 "SCRAM-SHA-256" - -/* SASL flags */ -#define SASL_FLAG_BASE64 0x0001 /* Messages are base64-encoded */ - -/* SASL machine states */ -typedef enum { - SASL_STOP, - SASL_PLAIN, - SASL_LOGIN, - SASL_LOGIN_PASSWD, - SASL_EXTERNAL, - SASL_CRAMMD5, - SASL_DIGESTMD5, - SASL_DIGESTMD5_RESP, - SASL_NTLM, - SASL_NTLM_TYPE2MSG, - SASL_GSSAPI, - SASL_GSSAPI_TOKEN, - SASL_GSSAPI_NO_DATA, - SASL_OAUTH2, - SASL_OAUTH2_RESP, - SASL_GSASL, - SASL_CANCEL, - SASL_FINAL -} saslstate; - -/* Progress indicator */ -typedef enum { - SASL_IDLE, - SASL_INPROGRESS, - SASL_DONE -} saslprogress; - -/* Protocol dependent SASL parameters */ -struct SASLproto { - const char *service; /* The service name */ - CURLcode (*sendauth)(struct Curl_easy *data, const char *mech, - const struct bufref *ir); - /* Send authentication command */ - CURLcode (*contauth)(struct Curl_easy *data, const char *mech, - const struct bufref *contauth); - /* Send authentication continuation */ - CURLcode (*cancelauth)(struct Curl_easy *data, const char *mech); - /* Cancel authentication. */ - CURLcode (*getmessage)(struct Curl_easy *data, struct bufref *out); - /* Get SASL response message */ - size_t maxirlen; /* Maximum initial response + mechanism length, - or zero if no max. This is normally the max - command length - other characters count. - This has to be zero for non-base64 protocols. */ - int contcode; /* Code to receive when continuation is expected */ - int finalcode; /* Code to receive upon authentication success */ - unsigned short defmechs; /* Mechanisms enabled by default */ - unsigned short flags; /* Configuration flags. */ -}; - -/* Per-connection parameters */ -struct SASL { - const struct SASLproto *params; /* Protocol dependent parameters */ - saslstate state; /* Current machine state */ - const char *curmech; /* Current mechanism id. */ - unsigned short authmechs; /* Accepted authentication mechanisms */ - unsigned short prefmech; /* Preferred authentication mechanism */ - unsigned short authused; /* Auth mechanism used for the connection */ - BIT(resetprefs); /* For URL auth option parsing. */ - BIT(mutual_auth); /* Mutual authentication enabled (GSSAPI only) */ - BIT(force_ir); /* Protocol always supports initial response */ -}; - -/* This is used to test whether the line starts with the given mechanism */ -#define sasl_mech_equal(line, wordlen, mech) \ - ((wordlen) == (sizeof(mech) - 1) / sizeof(char) && \ - !memcmp(line, mech, wordlen)) - -/* Convert a mechanism name to a token */ -unsigned short Curl_sasl_decode_mech(const char *ptr, - size_t maxlen, size_t *len); - -/* Parse the URL login options */ -CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, - const char *value, size_t len); - -/* Initializes an SASL structure */ -void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data, - const struct SASLproto *params); - -/* Check if we have enough auth data and capabilities to authenticate */ -bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data); - -/* Calculate the required login details for SASL authentication */ -CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, - bool force_ir, saslprogress *progress); - -/* Continue an SASL authentication */ -CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, - int code, saslprogress *progress); - -CURLcode Curl_sasl_is_blocked(struct SASL *sasl, struct Curl_easy *data); - -#endif /* HEADER_CURL_SASL_H */ diff --git a/vendor/curl/lib/curl_setup.h b/vendor/curl/lib/curl_setup.h deleted file mode 100644 index 0d4a8fa57..000000000 --- a/vendor/curl/lib/curl_setup.h +++ /dev/null @@ -1,1611 +0,0 @@ -#ifndef HEADER_CURL_SETUP_H -#define HEADER_CURL_SETUP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES) -#define CURL_NO_OLDIES -#endif - -/* Set default _WIN32_WINNT */ -#ifdef __MINGW32__ -#include <_mingw.h> -#endif - -/* Workaround for Homebrew gcc 12.4.0, 13.3.0, 14.1.0, 14.2.0 (initial build) - that started advertising the `availability` attribute, which then gets used - by Apple SDK, but, in a way incompatible with gcc, resulting in misc errors - inside SDK headers, e.g.: - error: attributes should be specified before the declarator in a function - definition - error: expected ',' or '}' before - Followed by missing declarations. - Work it around by overriding the built-in feature-check macro used by the - headers to enable the problematic attributes. This makes the feature check - fail. Fixed in 14.2.0_1. Disable the workaround if the fix is detected. */ -#if defined(__APPLE__) && !defined(__clang__) && defined(__GNUC__) && \ - defined(__has_attribute) -# if !defined(__has_feature) /* Keep this PP check separate from others */ -# define availability curl_pp_attribute_disabled -# elif !__has_feature(attribute_availability) -# define availability curl_pp_attribute_disabled -# endif -#endif - -#ifdef __APPLE__ -#include -#include -/* Fixup faulty target macro initialization in macOS SDK since v14.4 (as of - 15.0 beta). The SDK target detection in `TargetConditionals.h` correctly - detects macOS, but fails to set the macro's old name `TARGET_OS_OSX`, then - continues to set it to a default value of 0. Other parts of the SDK still - rely on the old name, and with this inconsistency our builds fail due to - missing declarations. It happens when using mainline llvm older than v18. - Later versions fixed it by predefining these target macros, avoiding the - faulty dynamic detection. gcc is not affected (for now) because it lacks - the necessary dynamic detection features, so the SDK falls back to - a codepath that sets both the old and new macro to 1. */ -#if defined(TARGET_OS_MAC) && TARGET_OS_MAC && \ - defined(TARGET_OS_OSX) && !TARGET_OS_OSX && \ - (!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) && \ - (!defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR) -#undef TARGET_OS_OSX -#define TARGET_OS_OSX TARGET_OS_MAC -#endif -#endif - -#if defined(__MINGW32__) && \ - (!defined(__MINGW64_VERSION_MAJOR) || (__MINGW64_VERSION_MAJOR < 3)) -#error "Building curl requires mingw-w64 3.0 or later" -#endif - -/* Visual Studio 2010 is the minimum Visual Studio version we support. - Workarounds for older versions of Visual Studio have been removed. */ -#if defined(_MSC_VER) && (_MSC_VER < 1600) -#error "Ancient versions of Visual Studio are no longer supported due to bugs." -#endif - -#ifdef _MSC_VER -/* Disable Visual Studio warnings: 4127 "conditional expression is constant" */ -#pragma warning(disable:4127) -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS /* for getenv(), sscanf() */ -#endif -#endif /* _MSC_VER */ - -#ifdef _WIN32 -/* - * Do not include unneeded stuff in Windows headers to avoid compiler - * warnings and macro clashes. - * Make sure to define this macro before including any Windows headers. - */ -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# ifndef NOGDI -# define NOGDI -# endif - -/* Detect Windows App environment which has a restricted access - * to the Win32 APIs. */ -# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ - defined(WINAPI_FAMILY) -# include -# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ - !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -# define CURL_WINDOWS_UWP -# endif -# endif - -/* Mandatory to define SECURITY_WIN32 or SECURITY_KERNEL to indicating who is - compiling the code. */ -#undef SECURITY_KERNEL -#undef SECURITY_WIN32 -#define SECURITY_WIN32 /* for */ -#endif - -/* Compatibility */ -#ifdef ENABLE_IPV6 -#define USE_IPV6 1 -#endif - -/* - * Include configuration script results or hand-crafted - * configuration file for platforms which lack config tool. - */ - -#ifdef HAVE_CONFIG_H - -#include "curl_config.h" - -#else /* HAVE_CONFIG_H */ - -#ifdef _WIN32 -# include "config-win32.h" -#endif - -#ifdef macintosh -# include "config-mac.h" -#endif - -#ifdef __riscos__ -# include "config-riscos.h" -#endif - -#ifdef __OS400__ -# include "config-os400.h" -#endif - -#endif /* HAVE_CONFIG_H */ - -#ifdef _WIN32 -# if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) -# error The minimum build target is Windows Vista (0x0600) -# endif - -# if !defined(CURL_WINDOWS_UWP) && (defined(_MSC_VER) || defined(__MINGW32__)) -# ifndef HAVE_IF_NAMETOINDEX -# define HAVE_IF_NAMETOINDEX -# endif -# endif -#endif - -/* ================================================================ */ -/* Definition of preprocessor macros/symbols which modify compiler */ -/* behavior or generated code characteristics must be done here, */ -/* as appropriate, before any system header file is included. It is */ -/* also possible to have them defined in the config file included */ -/* before this point. As a result of all this we frown inclusion of */ -/* system header files in our config files, avoid this at any cost. */ -/* ================================================================ */ - -#ifdef HAVE_LIBZ -# ifndef ZLIB_CONST -# define ZLIB_CONST /* Use z_const. Supported by v1.2.5.2 and upper. */ -# endif -#endif - -/* - * AIX 4.3 and newer needs _THREAD_SAFE defined to build - * proper reentrant code. Others may also need it. - */ -#ifdef NEED_THREAD_SAFE -# ifndef _THREAD_SAFE -# define _THREAD_SAFE -# endif -#endif - -/* - * Tru64 needs _REENTRANT set for a few function prototypes and - * things to appear in the system header files. Unixware needs it - * to build proper reentrant code. Others may also need it. - */ -#ifdef NEED_REENTRANT -# ifndef _REENTRANT -# define _REENTRANT -# endif -#endif - -/* Solaris needs this to get a POSIX-conformant getpwuid_r */ -#if defined(sun) || defined(__sun) -# ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -# endif -#endif - -/* ================================================================ */ -/* If you need to include a system header file for your platform, */ -/* please, do it beyond the point further indicated in this file. */ -/* ================================================================ */ - -/* Give calloc a chance to be dragging in early, so we do not redefine */ -#ifdef HAVE_THREADS_POSIX -# include -#endif - -/* - * Disable other protocols when http is the only one desired. - */ -#ifdef HTTP_ONLY -# ifndef CURL_DISABLE_DICT -# define CURL_DISABLE_DICT -# endif -# ifndef CURL_DISABLE_FILE -# define CURL_DISABLE_FILE -# endif -# ifndef CURL_DISABLE_FTP -# define CURL_DISABLE_FTP -# endif -# ifndef CURL_DISABLE_GOPHER -# define CURL_DISABLE_GOPHER -# endif -# ifndef CURL_DISABLE_IMAP -# define CURL_DISABLE_IMAP -# endif -# ifndef CURL_DISABLE_LDAP -# define CURL_DISABLE_LDAP -# endif -# ifndef CURL_DISABLE_LDAPS -# define CURL_DISABLE_LDAPS -# endif -# ifndef CURL_DISABLE_MQTT -# define CURL_DISABLE_MQTT -# endif -# ifndef CURL_DISABLE_POP3 -# define CURL_DISABLE_POP3 -# endif -# ifndef CURL_DISABLE_RTSP -# define CURL_DISABLE_RTSP -# endif -# ifndef CURL_DISABLE_SMTP -# define CURL_DISABLE_SMTP -# endif -# ifndef CURL_DISABLE_TELNET -# define CURL_DISABLE_TELNET -# endif -# ifndef CURL_DISABLE_TFTP -# define CURL_DISABLE_TFTP -# endif -# ifndef CURL_DISABLE_WEBSOCKETS -# define CURL_DISABLE_WEBSOCKETS -# endif -#endif - -/* - * When http is disabled rtsp is not supported. - */ -#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP) -# define CURL_DISABLE_RTSP -#endif - -/* - * When HTTP is disabled, disable HTTP-only features - */ -#ifdef CURL_DISABLE_HTTP -# ifndef CURL_DISABLE_ALTSVC -# define CURL_DISABLE_ALTSVC -# endif -# ifndef CURL_DISABLE_COOKIES -# define CURL_DISABLE_COOKIES -# endif -# ifndef CURL_DISABLE_BASIC_AUTH -# define CURL_DISABLE_BASIC_AUTH -# endif -# ifndef CURL_DISABLE_BEARER_AUTH -# define CURL_DISABLE_BEARER_AUTH -# endif -# ifndef CURL_DISABLE_AWS -# define CURL_DISABLE_AWS -# endif -# ifndef CURL_DISABLE_DOH -# define CURL_DISABLE_DOH -# endif -# ifndef CURL_DISABLE_FORM_API -# define CURL_DISABLE_FORM_API -# endif -# ifndef CURL_DISABLE_HEADERS_API -# define CURL_DISABLE_HEADERS_API -# endif -# ifndef CURL_DISABLE_HSTS -# define CURL_DISABLE_HSTS -# endif -# ifndef CURL_DISABLE_HTTP_AUTH -# define CURL_DISABLE_HTTP_AUTH -# endif -# ifndef CURL_DISABLE_WEBSOCKETS -# define CURL_DISABLE_WEBSOCKETS /* no WebSockets without HTTP present */ -# endif -#endif - -/* ================================================================ */ -/* No system header file shall be included in this file before this */ -/* point. */ -/* ================================================================ */ - -/* - * OS/400 setup file includes some system headers. - */ -#ifdef __OS400__ -# include "setup-os400.h" -#endif - -/* - * VMS setup file includes some system headers. - */ -#ifdef __VMS -# include "setup-vms.h" -#endif - -/* - * Windows setup file includes some system headers. - */ -#ifdef _WIN32 -# include "setup-win32.h" -#endif - -#include - -/* Helper macro to expand and concatenate two macros. - * Direct macros concatenation does not work because macros - * are not expanded before direct concatenation. - */ -#define CURL_CONC_MACROS_(A, B) A ## B -#define CURL_CONC_MACROS(A, B) CURL_CONC_MACROS_(A, B) - -/* curl uses its own printf() function internally. It understands the GNU - * format. Use this format, so that it matches the GNU format attribute we - * use with the MinGW compiler, allowing it to verify them at compile-time. - */ -#ifdef __MINGW32__ -# undef CURL_FORMAT_CURL_OFF_T -# undef CURL_FORMAT_CURL_OFF_TU -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -#endif - -/* based on logic in "curl/mprintf.h" */ -#if (defined(__GNUC__) || defined(__clang__) || \ - defined(__IAR_SYSTEMS_ICC__)) && \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(CURL_NO_FMT_CHECKS) -#if defined(__MINGW32__) && !defined(__clang__) -#define CURL_PRINTF(fmt, arg) __attribute__((format(gnu_printf, fmt, arg))) -#else -#define CURL_PRINTF(fmt, arg) __attribute__((format(__printf__, fmt, arg))) -#endif -#else -#define CURL_PRINTF(fmt, arg) -#endif - -/* Override default printf mask check rules in "curl/mprintf.h" */ -#define CURL_TEMP_PRINTF CURL_PRINTF - -/* Workaround for mainline llvm v16 and earlier missing a built-in macro - expected by macOS SDK v14 / Xcode v15 (2023) and newer. - gcc (as of v14) is also missing it. */ -#if defined(__APPLE__) && \ - ((!defined(__apple_build_version__) && \ - defined(__clang__) && __clang_major__ < 17) || \ - (defined(__GNUC__) && __GNUC__ <= 14)) && \ - defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ - !defined(__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__) -#define __ENVIRONMENT_OS_VERSION_MIN_REQUIRED__ \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ -#endif - -/* - * Use getaddrinfo to resolve the IPv4 address literal. If the current network - * interface does not support IPv4, but supports IPv6, NAT64, and DNS64, - * performing this task will result in a synthesized IPv6 address. - */ -#if defined(__APPLE__) && !defined(USE_ARES) -# define USE_RESOLVE_ON_IPS 1 -# if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && \ - defined(USE_IPV6) -# define CURL_MACOS_CALL_COPYPROXIES 1 -# endif -#endif - -#ifdef USE_ARES -# ifndef CARES_NO_DEPRECATED -# define CARES_NO_DEPRECATED /* for ares_getsock() */ -# endif -# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && defined(_WIN32) -# define CARES_STATICLIB /* define it before including ares.h */ -# endif -#endif - -#ifdef USE_LWIPSOCK -# include -# include -# include -#endif - -#ifdef macintosh -# include -# include -#endif - -#ifdef __AMIGA__ -# ifdef __amigaos4__ -# define __USE_INLINE__ - /* use our own resolver which uses runtime feature detection */ -# define CURLRES_AMIGA - /* getaddrinfo() currently crashes bsdsocket.library, so disable */ -# undef HAVE_GETADDRINFO -# if !(defined(__NEWLIB__) || \ - (defined(__CLIB2__) && defined(__THREAD_SAFE))) - /* disable threaded resolver with clib2 - requires newlib or clib-ts */ -# undef USE_RESOLV_THREADED -# endif -# endif -# include -# include -# include -# include -# include -# if defined(HAVE_PROTO_BSDSOCKET_H) && \ - (!defined(__amigaos4__) || defined(USE_AMISSL)) - /* use bsdsocket.library directly, instead of libc networking functions */ -# define _SYS_MBUF_H /* m_len define clashes with curl */ -# include -# ifdef __amigaos4__ - int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *errorfds, struct timeval *timeout); -# define select(a, b, c, d, e) Curl_amiga_select(a, b, c, d, e) -# else -# define select(a, b, c, d, e) WaitSelect(a, b, c, d, e, 0) -# endif - /* must not use libc's fcntl() on bsdsocket.library sockfds! */ -# undef HAVE_FCNTL -# undef HAVE_FCNTL_O_NONBLOCK -# else - /* use libc networking and hence close() and fnctl() */ -# undef HAVE_CLOSESOCKET_CAMEL -# undef HAVE_IOCTLSOCKET_CAMEL -# endif -/* - * In clib2 arpa/inet.h warns that some prototypes may clash - * with bsdsocket.library. This avoids the definition of those. - */ -# define __NO_NET_API -#endif - -/* Whether to use eventfd() */ -#if defined(HAVE_EVENTFD) && defined(HAVE_SYS_EVENTFD_H) -#define USE_EVENTFD -#endif - -#ifdef SO_NOSIGPIPE -#define USE_SO_NOSIGPIPE -#endif - -#include -#include - -#ifdef __TANDEM /* for ns*-tandem-nsk systems */ -# ifndef __LP64 -# include /* FLOSS is only used for 32-bit builds. */ -# endif -#endif - -#ifndef STDC_HEADERS /* no standard C headers! */ -#include -#endif - -#include -#define HAVE_UINTPTR_T /* assume uintptr_t is provided by stdint.h */ - -#ifdef __DJGPP__ -/* By default, DJGPP provides this type as a version of 'unsigned long' which - forces us to use a define use it in printf() format strings without - warnings. long and int are both 32 bits for this platform. */ -#define uint32_t unsigned int -#endif - -/* Disable uintptr_t for targets known to miss it from stdint.h */ -#ifdef __OS400__ -#undef HAVE_UINTPTR_T -#endif - -#include - -#ifdef _WIN32 -# ifdef HAVE_IO_H -# include -# endif -# include -# include - /* Large file (>2Gb) support using Win32 functions. */ -# define curl_lseek _lseeki64 -# define LSEEK_ERROR ((__int64)-1) -#elif defined(__DJGPP__) - /* Requires DJGPP 2.04 */ -# include -# define curl_lseek llseek -# define LSEEK_ERROR ((offset_t)-1) -#elif defined(__AMIGA__) -# define curl_lseek(fd, offset, whence) lseek(fd, (off_t)(offset), whence) -# define LSEEK_ERROR ((off_t)-1) -#else -# define curl_lseek lseek -# define LSEEK_ERROR ((off_t)-1) -#endif - -#ifndef SIZEOF_TIME_T -/* assume default size of time_t to be 32 bits */ -#define SIZEOF_TIME_T 4 -#endif - -#ifndef SIZEOF_CURL_SOCKET_T -/* configure and cmake check and set the define */ -# if defined(USE_WINSOCK) && defined(_WIN64) -# define SIZEOF_CURL_SOCKET_T 8 -# else -/* default guess */ -# define SIZEOF_CURL_SOCKET_T 4 -# endif -#endif - -#if SIZEOF_CURL_SOCKET_T < 8 -#ifdef USE_WINSOCK -# define FMT_SOCKET_T "u" -#else -# define FMT_SOCKET_T "d" -#endif -#elif defined(USE_WINSOCK) -# define FMT_SOCKET_T "zu" -#else -# define FMT_SOCKET_T "qd" -#endif - -/* - * Default sizeof(off_t) in case it has not been defined in config file. - */ - -#ifndef SIZEOF_OFF_T -# if defined(__VMS) && !defined(__VAX) -# ifdef _LARGEFILE -# define SIZEOF_OFF_T 8 -# endif -# elif defined(__OS400__) && defined(__ILEC400__) -# ifdef _LARGE_FILES -# define SIZEOF_OFF_T 8 -# endif -# elif defined(__MVS__) && defined(__IBMC__) -# if defined(_LP64) || defined(_LARGE_FILES) -# define SIZEOF_OFF_T 8 -# endif -# elif defined(__370__) && defined(__IBMC__) -# if defined(_LP64) || defined(_LARGE_FILES) -# define SIZEOF_OFF_T 8 -# endif -# endif -# ifndef SIZEOF_OFF_T -# define SIZEOF_OFF_T 4 -# endif -#endif - -#if (SIZEOF_CURL_OFF_T < 8) -#error "too small curl_off_t" -#else - /* assume SIZEOF_CURL_OFF_T == 8 */ -# define CURL_OFF_T_MAX 0x7FFFFFFFFFFFFFFF -#endif -#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - 1) - -#define FMT_OFF_T CURL_FORMAT_CURL_OFF_T -#define FMT_OFF_TU CURL_FORMAT_CURL_OFF_TU - -#if (SIZEOF_TIME_T == 4) -# ifdef HAVE_TIME_T_UNSIGNED -# define TIME_T_MAX UINT_MAX -# define TIME_T_MIN 0 -# else -# define TIME_T_MAX INT_MAX -# define TIME_T_MIN INT_MIN -# endif -#else -# ifdef HAVE_TIME_T_UNSIGNED -# define TIME_T_MAX 0xFFFFFFFFFFFFFFFF -# define TIME_T_MIN 0 -# else -# define TIME_T_MAX 0x7FFFFFFFFFFFFFFF -# define TIME_T_MIN (-TIME_T_MAX - 1) -# endif -#endif - -#ifndef SIZE_MAX -/* some limits.h headers have this defined, some do not */ -#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) -#define SIZE_MAX 18446744073709551615U -#else -#define SIZE_MAX 4294967295U -#endif -#endif - -#ifndef SSIZE_MAX -/* some limits.h headers have this defined, some do not */ -#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) -#define SSIZE_MAX 9223372036854775807 -#else -#define SSIZE_MAX 2147483647 -#endif -#endif - -#if SIZEOF_LONG > SIZEOF_SIZE_T -#error "unexpected: 'long' is larger than 'size_t'" -#endif - -/* - * Arg 2 type for gethostname in case it has not been defined in config file. - */ -#ifndef GETHOSTNAME_TYPE_ARG2 -# ifdef USE_WINSOCK -# define GETHOSTNAME_TYPE_ARG2 int -# else -# define GETHOSTNAME_TYPE_ARG2 size_t -# endif -#endif - -/* Below we define some functions. They should - 4. set the SIGALRM signal timeout - 5. set dir/file naming defines - */ - -#ifdef _WIN32 - -# define DIR_CHAR "\\" - -#else /* _WIN32 */ - -# ifdef MSDOS /* Watt-32 */ - -# include -# define select(n, r, w, x, t) select_s(n, r, w, x, t) -# define ioctl(x, y, z) ioctlsocket(x, y, (char *)(z)) -# include -# undef word -# undef byte - -# endif /* MSDOS */ - -# ifdef __minix - /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */ - extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp); -# endif - -# define DIR_CHAR "/" - -#endif /* _WIN32 */ - -/* We want to use mutex when available. */ -#if defined(HAVE_THREADS_POSIX) || defined(_WIN32) -#define USE_MUTEX -#endif - -/* threaded resolver is the only feature requiring threads. */ -#ifdef USE_RESOLV_THREADED -#define USE_THREADS -#endif - -/* ---------------------------------------------------------------- */ -/* resolver specialty compile-time defines */ -/* CURLRES_* defines to use in the host*.c sources */ -/* ---------------------------------------------------------------- */ - -/* - * Mutually exclusive CURLRES_* definitions. - */ -#if defined(USE_IPV6) && defined(HAVE_GETADDRINFO) -# define CURLRES_IPV6 -#elif defined(USE_IPV6) && (defined(_WIN32) || defined(__CYGWIN__)) -/* assume on Windows that IPv6 without getaddrinfo is a broken build */ -# error "Unexpected build: IPv6 is enabled but getaddrinfo was not found." -#else -# define CURLRES_IPV4 -#endif - -#ifdef USE_RESOLV_THREADED -# define CURLRES_ASYNCH -#elif defined(USE_RESOLV_ARES) -# define CURLRES_ASYNCH -/* now undef the stock libc functions to avoid them being used */ -# undef HAVE_GETADDRINFO -# undef HAVE_FREEADDRINFO -#else -# define CURLRES_SYNCH -#endif - -/* ---------------------------------------------------------------- */ - -#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && \ - !defined(USE_WIN32_IDN) && !defined(USE_APPLE_IDN) -/* The lib and header are present */ -#define USE_LIBIDN2 -#endif - -#if defined(USE_LIBIDN2) && (defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN)) -#error "libidn2 cannot be enabled with WinIDN or AppleIDN, choose one." -#endif - -#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \ - defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_RUSTLS) -#define USE_SSL /* SSL support has been enabled */ -#endif - -#if defined(USE_OPENSSL) && defined(USE_WOLFSSL) -#ifndef OPENSSL_COEXIST -#define OPENSSL_COEXIST -#endif -#endif - -#if defined(USE_WOLFSSL) && defined(USE_GNUTLS) -/* Avoid defining unprefixed wolfSSL SHA macros colliding with nettle ones */ -#define NO_OLD_WC_NAMES -#endif - -/* Single point where USE_SPNEGO definition might be defined */ -#if !defined(CURL_DISABLE_NEGOTIATE_AUTH) && \ - (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) -#define USE_SPNEGO -#endif - -/* Single point where USE_KERBEROS5 definition might be defined */ -#if !defined(CURL_DISABLE_KERBEROS_AUTH) && \ - (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) -#define USE_KERBEROS5 -#endif - -/* Single point where USE_NTLM definition might be defined */ -#ifdef CURL_ENABLE_NTLM -# if (defined(USE_OPENSSL) && defined(HAVE_DES_ECB_ENCRYPT)) || \ - defined(USE_GNUTLS) || \ - (defined(USE_MBEDTLS) && defined(HAVE_MBEDTLS_DES_CRYPT_ECB)) || \ - defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ - (defined(USE_WOLFSSL) && defined(HAVE_WC_DES_ECBENCRYPT)) -# define USE_CURL_NTLM_CORE -# endif -# if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI) -# define USE_NTLM -# endif -#endif - -#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) -#define USE_SSH -#endif - -/* GCC <4.6 does not support '#pragma GCC diagnostic push' and does not support - 'pragma GCC diagnostic' inside functions. - Use CURL_HAVE_DIAG to guard the above in the curl codebase, instead of - defined(__GNUC__) || defined(__clang__). - */ -#if defined(__clang__) || (defined(__GNUC__) && \ - ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)))) -#define CURL_HAVE_DIAG -#endif - -/* - * Provide a mechanism to silence picky compilers, such as gcc 4.6+. - * Parameters should of course normally not be unused, but for example when - * we have multiple implementations of the same interface it may happen. - */ -#if defined(__GNUC__) && ((__GNUC__ >= 3) || \ - ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7))) -# define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#elif defined(__IAR_SYSTEMS_ICC__) && (__VER__ >= 9040001) -# define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -# define WARN_UNUSED_RESULT -#endif - -/* noreturn attribute */ - -#ifndef CURL_NORETURN -#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) || \ - defined(__IAR_SYSTEMS_ICC__) -# define CURL_NORETURN __attribute__((__noreturn__)) -#elif defined(_MSC_VER) -# define CURL_NORETURN __declspec(noreturn) -#else -# define CURL_NORETURN -#endif -#endif - -/* fallthrough attribute */ - -#ifndef FALLTHROUGH -#if (defined(__GNUC__) && __GNUC__ >= 7) || \ - (defined(__clang__) && __clang_major__ >= 10) -# define FALLTHROUGH() __attribute__((fallthrough)) -#else -# define FALLTHROUGH() do {} while(0) -#endif -#endif - -/* - * Inclusion of common header files. - */ - -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include - -#if !defined(_WIN32) || defined(__MINGW32__) -#include -#endif - -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif - -#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -/* Macro to strip 'const' without triggering a compiler warning. - Use it for APIs that do not or cannot support the const qualifier. */ -#ifdef HAVE_UINTPTR_T -#define CURL_UNCONST(p) ((void *)(uintptr_t)(const void *)(p)) -#else -#define CURL_UNCONST(p) ((void *)(p)) /* Fall back to simple cast */ -#endif - -#ifdef USE_SCHANNEL -/* Must set this before is included directly or indirectly by - another Windows header. */ -# define SCHANNEL_USE_BLACKLISTS /* for SCH_CREDENTIALS */ -# include /* for [P]UNICODE_STRING in SCH_CREDENTIALS */ -#endif - -#ifdef __hpux -# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) -# ifdef _APP32_64BIT_OFF_T -# define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T -# undef _APP32_64BIT_OFF_T -# else -# undef OLD_APP32_64BIT_OFF_T -# endif -# endif -#endif - -#ifndef _WIN32 -#include /* also for MSG_NOSIGNAL */ -#endif - -#include "functypes.h" - -#ifdef __hpux -# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) -# ifdef OLD_APP32_64BIT_OFF_T -# define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T -# undef OLD_APP32_64BIT_OFF_T -# endif -# endif -#endif - -/* - * Definition of timeval struct for platforms that do not have it. - */ -#ifndef HAVE_STRUCT_TIMEVAL -struct timeval { - long tv_sec; - long tv_usec; -}; -#endif - -/* - * If we have the MSG_NOSIGNAL define, make sure we use - * it as the fourth argument of function send() - */ -#ifdef MSG_NOSIGNAL -#define SEND_4TH_ARG MSG_NOSIGNAL -#else -#define SEND_4TH_ARG 0 -#endif - -#ifdef __minix -/* Minix does not support recv on TCP sockets */ -#define sread(x, y, z) (ssize_t)read((RECV_TYPE_ARG1)(x), \ - (RECV_TYPE_ARG2)(y), \ - (RECV_TYPE_ARG3)(z)) - -#elif defined(HAVE_RECV) -/* - * The definitions for the return type and arguments types - * of functions recv() and send() belong and come from the - * configuration file. Do not define them in any other place. - * - * HAVE_RECV is defined if you have a function named recv() - * which is used to read incoming data from sockets. If your - * function has another name then do not define HAVE_RECV. - * - * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2, - * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also - * be defined. - * - * HAVE_SEND is defined if you have a function named send() - * which is used to write outgoing data on a connected socket. - * If yours has another name then do not define HAVE_SEND. - * - * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_TYPE_ARG2, - * SEND_TYPE_ARG3, SEND_TYPE_ARG4 and SEND_TYPE_RETV must also - * be defined. SEND_NONCONST_ARG2 must also be defined if ARG2 - * does not accept const. - */ - -#define sread(x, y, z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \ - (RECV_TYPE_ARG2)(y), \ - (RECV_TYPE_ARG3)(z), \ - (RECV_TYPE_ARG4)(0)) -#else /* HAVE_RECV */ -#ifndef sread -#error "Missing definition of macro sread!" -#endif -#endif /* HAVE_RECV */ - -#ifdef __minix -/* Minix does not support send on TCP sockets */ -#define swrite(x, y, z) (ssize_t)write((SEND_TYPE_ARG1)(x), \ - (SEND_TYPE_ARG2)CURL_UNCONST(y), \ - (SEND_TYPE_ARG3)(z)) -#elif defined(HAVE_SEND) -#ifdef SEND_NONCONST_ARG2 -#define swrite(x, y, z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ - (SEND_TYPE_ARG2)CURL_UNCONST(y), \ - (SEND_TYPE_ARG3)(z), \ - (SEND_TYPE_ARG4)(SEND_4TH_ARG)) -#else -#define swrite(x, y, z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ - (const SEND_TYPE_ARG2)(y), \ - (SEND_TYPE_ARG3)(z), \ - (SEND_TYPE_ARG4)(SEND_4TH_ARG)) -#endif /* SEND_NONCONST_ARG2 */ -#else /* HAVE_SEND */ -#ifndef swrite -#error "Missing definition of macro swrite!" -#endif -#endif /* HAVE_SEND */ - -/* - * Function-like macro definition used to close a socket. - */ -#ifdef HAVE_CLOSESOCKET -# define CURL_SCLOSE(x) closesocket(x) -#elif defined(HAVE_CLOSESOCKET_CAMEL) -# define CURL_SCLOSE(x) CloseSocket(x) -#elif defined(MSDOS) /* Watt-32 */ -# define CURL_SCLOSE(x) close_s(x) -#elif defined(USE_LWIPSOCK) -# define CURL_SCLOSE(x) lwip_close(x) -#else -# define CURL_SCLOSE(x) close(x) -#endif - -/* - * Stack-independent version of fcntl() on sockets: - */ -#ifdef USE_LWIPSOCK -# define sfcntl lwip_fcntl -#else -# define sfcntl fcntl -#endif - -/* - * 'bool' stuff compatible with HP-UX headers. - */ -#if defined(__hpux) && !defined(HAVE_BOOL_T) -typedef int bool; -# define false 0 -# define true 1 -# define HAVE_BOOL_T -#endif - -/* - * 'bool' exists on platforms with , i.e. C99 platforms. - * On non-C99 platforms there is no bool, so define an enum for that. - * On C99 platforms 'false' and 'true' also exist. Enum uses a - * global namespace though, so use bool_false and bool_true. - */ -#ifndef HAVE_BOOL_T -typedef enum { - bool_false = 0, - bool_true = 1 -} bool; - -/* - * Use a define to let 'true' and 'false' use those enums. There - * are currently no use of true and false in libcurl proper, but - * there are some in the examples. This will cater for any later - * code happening to use true and false. - */ -# define false bool_false -# define true bool_true -# define HAVE_BOOL_T -#endif - -/* the type we use for storing a single boolean bit */ -typedef unsigned int curl_bit; -#define BIT(x) curl_bit x:1 - -/* - * Redefine TRUE and FALSE too, to catch current use. With this - * change, 'bool found = 1' will give a warning on MIPSPro, but - * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro, - * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too. - */ -#ifndef TRUE -#define TRUE true -#endif -#ifndef FALSE -#define FALSE false -#endif - -#include "curl_ctype.h" - -/* - * Macro used to include code only in debug builds. - */ -#ifdef DEBUGBUILD -#define DEBUGF(x) x -#else -#define DEBUGF(x) do {} while(0) -#endif - -/* - * Macro used to include assertion code only in debug builds. - */ -#undef DEBUGASSERT -#ifdef DEBUGBUILD -#ifdef CURL_DEBUGASSERT -/* External assertion handler for custom integrations */ -#define DEBUGASSERT(x) CURL_DEBUGASSERT(x) -#else -#define DEBUGASSERT(x) assert(x) -#endif -#else -#define DEBUGASSERT(x) do {} while(0) -#endif - -/* - * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno - * (or equivalent) on this platform to hide platform details to code using it. - */ -#ifdef USE_WINSOCK -#define SOCKERRNO ((int)WSAGetLastError()) -#define SET_SOCKERRNO(x) WSASetLastError((int)(x)) -#else -#define SOCKERRNO errno -#define SET_SOCKERRNO(x) (errno = (x)) -#endif - -/* - * Portable error number symbolic names defined to Winsock error codes. - */ -#ifdef USE_WINSOCK -#define SOCKEACCES WSAEACCES -#define SOCKEADDRINUSE WSAEADDRINUSE -#define SOCKEADDRNOTAVAIL WSAEADDRNOTAVAIL -#define SOCKEAFNOSUPPORT WSAEAFNOSUPPORT -#define SOCKEBADF WSAEBADF -#define SOCKECONNREFUSED WSAECONNREFUSED -#define SOCKECONNRESET WSAECONNRESET -#define SOCKEINPROGRESS WSAEINPROGRESS -#define SOCKEINTR WSAEINTR -#define SOCKEINVAL WSAEINVAL -#define SOCKEISCONN WSAEISCONN -#define SOCKEMSGSIZE WSAEMSGSIZE -/* Use literal value to work around clang-tidy <=20 misreporting - 'readability-uppercase-literal-suffix' with mingw-w64 headers */ -#define SOCKENOMEM 8L /* WSA_NOT_ENOUGH_MEMORY */ -#define SOCKETIMEDOUT WSAETIMEDOUT -#define SOCKEWOULDBLOCK WSAEWOULDBLOCK -#else -#define SOCKEACCES EACCES -#define SOCKEADDRINUSE EADDRINUSE -#define SOCKEADDRNOTAVAIL EADDRNOTAVAIL -#define SOCKEAFNOSUPPORT EAFNOSUPPORT -#define SOCKEBADF EBADF -#define SOCKECONNREFUSED ECONNREFUSED -#define SOCKECONNRESET ECONNRESET -#define SOCKEINPROGRESS EINPROGRESS -#define SOCKEINTR EINTR -#define SOCKEINVAL EINVAL -#define SOCKEISCONN EISCONN -#define SOCKEMSGSIZE EMSGSIZE -#define SOCKENOMEM ENOMEM -#ifdef ETIMEDOUT -#define SOCKETIMEDOUT ETIMEDOUT -#endif -#define SOCKEWOULDBLOCK EWOULDBLOCK -#endif - -/* - * Macro argv_item_t hides platform details to code using it. - */ -#ifdef __VMS -#define argv_item_t __char_ptr32 -#elif defined(_UNICODE) -#define argv_item_t wchar_t * -#else -#define argv_item_t char * -#endif - -/* - * We use this ZERO_NULL to avoid picky compiler warnings, - * when assigning a NULL pointer to a function pointer var. - */ -#define ZERO_NULL 0 - -/* - * Macros and functions to safely suppress warnings - */ -#include "curlx/warnless.h" - -#ifdef _WIN32 -# undef read -# define read(fd, buf, count) (ssize_t)_read(fd, buf, curlx_uztoui(count)) -# undef write -# define write(fd, buf, count) (ssize_t)_write(fd, buf, curlx_uztoui(count)) -/* Avoid VS2005+ _CRT_NONSTDC_NO_DEPRECATE warnings about non-portable funcs */ -# undef fileno -# define fileno(fh) _fileno(fh) -# undef unlink -# define unlink(fn) _unlink(fn) -# undef isatty -# define isatty(fd) _isatty(fd) -#endif - -/* - * Definition of our NOP statement Object-like macro - */ -#ifndef Curl_nop_stmt -#define Curl_nop_stmt do {} while(0) -#endif - -/* - * Ensure that Winsock and lwIP TCP/IP stacks are not mixed. - */ -#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H) -# if defined(SOCKET) || defined(USE_WINSOCK) -# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!" -# endif -#endif - -/* - * shutdown() flags for systems that do not define them - */ -#ifndef SHUT_RD -#define SHUT_RD 0x00 -#endif - -#ifndef SHUT_WR -#define SHUT_WR 0x01 -#endif - -#ifndef SHUT_RDWR -#define SHUT_RDWR 0x02 -#endif - -/* Define S_ISREG if not defined by system headers, e.g. MSVC */ -#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -/* Define S_ISDIR if not defined by system headers, e.g. MSVC */ -#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - -/* For MSVC (all versions as of VS2022) */ -#ifndef STDIN_FILENO -#define STDIN_FILENO fileno(stdin) -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO fileno(stdout) -#endif -#ifndef STDERR_FILENO -#define STDERR_FILENO fileno(stderr) -#endif - -/* Since O_BINARY is used in bitmasks, setting it to zero makes it usable in - source code but yet it does not ruin anything */ -#ifdef _O_BINARY /* for _WIN32 || MSDOS */ -#define CURL_O_BINARY _O_BINARY -#elif defined(O_BINARY) /* __CYGWIN__ */ -#define CURL_O_BINARY O_BINARY -#else -#define CURL_O_BINARY 0 -#endif - -/* Requires io.h when available */ -#ifdef MSDOS -#define CURL_BINMODE(stream) (void)setmode(fileno(stream), CURL_O_BINARY) -#elif defined(_WIN32) || defined(__CYGWIN__) -#define CURL_BINMODE(stream) (void)_setmode(fileno(stream), CURL_O_BINARY) -#else -#define CURL_BINMODE(stream) (void)(stream) -#endif - -/* In Windows the default file mode is text but an application can override it. -Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 -*/ -#if defined(_WIN32) || defined(MSDOS) -#define FOPEN_READTEXT "rt" -#define FOPEN_WRITETEXT "wt" -#define FOPEN_APPENDTEXT "at" -#elif defined(__CYGWIN__) -/* Cygwin has specific behavior we need to address when _WIN32 is not defined. -https://cygwin.com/cygwin-ug-net/using-textbinary.html -For write we want our output to have line endings of LF and be compatible with -other Cygwin utilities. For read we want to handle input that may have line -endings either CRLF or LF so 't' is appropriate. -*/ -#define FOPEN_READTEXT "rt" -#define FOPEN_WRITETEXT "w" -#define FOPEN_APPENDTEXT "a" -#else -#define FOPEN_READTEXT "r" -#define FOPEN_WRITETEXT "w" -#define FOPEN_APPENDTEXT "a" -#endif - -/* for systems that do not detect this in configure */ -#ifndef CURL_SA_FAMILY_T -# ifdef USE_WINSOCK -# define CURL_SA_FAMILY_T ADDRESS_FAMILY -# elif defined(HAVE_SA_FAMILY_T) -# define CURL_SA_FAMILY_T sa_family_t -# elif defined(__AMIGA__) -# define CURL_SA_FAMILY_T unsigned char -# else -/* use a sensible default */ -# define CURL_SA_FAMILY_T unsigned short -# endif -#endif - -/* Some convenience macros to get the larger/smaller value out of two given. - We prefix with CURL to prevent name collisions. */ -#define CURLMAX(x, y) ((x) > (y) ? (x) : (y)) -#define CURLMIN(x, y) ((x) < (y) ? (x) : (y)) - -/* A convenience macro to provide both the string literal and the length of - the string literal in one go, useful for functions that take "string,len" - as their argument */ -#define STRCONST(x) x, sizeof(x) - 1 - -#define CURL_ARRAYSIZE(A) (sizeof(A) / sizeof((A)[0])) - -/* Buffer size for error messages retrieved via - curlx_strerror() and Curl_sspi_strerror() */ -#define STRERROR_LEN 256 - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */ -/* - * The following memory function replacement typedef's are COPIED from - * curl/curl.h and MUST match the originals. We copy them to avoid having to - * include curl/curl.h here. We avoid that include since it includes stdio.h - * and other headers that may get messed up with defines done here. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); -#define CURL_DID_MEMORY_FUNC_TYPEDEFS -#endif - -extern curl_malloc_callback Curl_cmalloc; -extern curl_free_callback Curl_cfree; -extern curl_realloc_callback Curl_crealloc; -extern curl_strdup_callback Curl_cstrdup; -extern curl_calloc_callback Curl_ccalloc; - -/* - * curlx_safefree() defined as a macro to allow MemoryTracking feature - * to log free() calls at same location where curlx_safefree() is used. - * This macro also assigns NULL to given pointer when free'd. - */ -#define curlx_safefree(ptr) \ - do { \ - curlx_free(ptr); \ - (ptr) = NULL; \ - } while(0) - -#include /* for CURL_EXTERN, curl_socket_t, mprintf.h */ - -#ifdef DEBUGBUILD -#define CURL_MEMDEBUG -#endif - -#ifdef CURL_MEMDEBUG -#ifdef __clang__ -# define ALLOC_FUNC __attribute__((__malloc__)) -# if __clang_major__ >= 4 -# define ALLOC_SIZE(s) __attribute__((__alloc_size__(s))) -# define ALLOC_SIZE2(n, s) __attribute__((__alloc_size__(n, s))) -# else -# define ALLOC_SIZE(s) -# define ALLOC_SIZE2(n, s) -# endif -#elif defined(__GNUC__) && __GNUC__ >= 3 -# define ALLOC_FUNC __attribute__((__malloc__)) -# define ALLOC_SIZE(s) __attribute__((__alloc_size__(s))) -# define ALLOC_SIZE2(n, s) __attribute__((__alloc_size__(n, s))) -#elif defined(_MSC_VER) -# define ALLOC_FUNC __declspec(restrict) -# define ALLOC_SIZE(s) -# define ALLOC_SIZE2(n, s) -#else -# define ALLOC_FUNC -# define ALLOC_SIZE(s) -# define ALLOC_SIZE2(n, s) -#endif - -extern FILE *curl_dbg_logfile; - -/* memory functions */ -CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); -CURL_EXTERN ALLOC_FUNC ALLOC_SIZE(1) - void *curl_dbg_malloc(size_t size, int line, const char *source); -CURL_EXTERN ALLOC_FUNC ALLOC_SIZE2(1, 2) - void *curl_dbg_calloc(size_t n, size_t size, int line, const char *source); -CURL_EXTERN ALLOC_SIZE(2) - void *curl_dbg_realloc(void *ptr, size_t size, int line, const char *source); -CURL_EXTERN ALLOC_FUNC - char *curl_dbg_strdup(const char *str, int line, const char *src); -#if defined(_WIN32) && defined(UNICODE) -CURL_EXTERN ALLOC_FUNC - wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source); -#endif - -CURL_EXTERN void curl_dbg_memdebug(const char *logname); -CURL_EXTERN void curl_dbg_memlimit(long limit); -CURL_EXTERN void curl_dbg_log(const char *format, ...) CURL_PRINTF(1, 2); - -/* file descriptor manipulators */ -CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol, - int line, const char *source); -CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, - void *saddr, void *saddrlen, - int line, const char *source); -#ifdef HAVE_ACCEPT4 -CURL_EXTERN curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr, - void *saddrlen, int flags, - int line, const char *source); -#endif -#ifdef HAVE_SOCKETPAIR -CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source); -#endif - -/* FILE functions */ -CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); -CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode, - int line, const char *source); -CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_freopen(const char *file, - const char *mode, FILE *fh, - int line, const char *source); -CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode, - int line, const char *source); - -#define sclose(sockfd) curl_dbg_sclose(sockfd, __LINE__, __FILE__) -#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd, __LINE__, __FILE__) - -#define CURL_GETADDRINFO(host, serv, hint, res) \ - curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) -#define CURL_FREEADDRINFO(data) \ - curl_dbg_freeaddrinfo(data, __LINE__, __FILE__) -#define CURL_SOCKET(domain, type, protocol) \ - curl_dbg_socket((int)(domain), type, protocol, __LINE__, __FILE__) -#ifdef HAVE_SOCKETPAIR -#define CURL_SOCKETPAIR(domain, type, protocol, socket_vector) \ - curl_dbg_socketpair((int)(domain), type, protocol, socket_vector, \ - __LINE__, __FILE__) -#endif -#define CURL_ACCEPT(sock, addr, len) \ - curl_dbg_accept(sock, addr, len, __LINE__, __FILE__) -#ifdef HAVE_ACCEPT4 -#define CURL_ACCEPT4(sock, addr, len, flags) \ - curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__) -#endif - -#else /* !CURL_MEMDEBUG */ - -#define sclose(x) CURL_SCLOSE(x) -#define fake_sclose(x) Curl_nop_stmt - -#define CURL_GETADDRINFO getaddrinfo -#define CURL_FREEADDRINFO freeaddrinfo -#define CURL_SOCKET socket -#ifdef HAVE_SOCKETPAIR -#define CURL_SOCKETPAIR socketpair -#endif -#define CURL_ACCEPT accept -#ifdef HAVE_ACCEPT4 -#define CURL_ACCEPT4 accept4 -#endif - -#endif /* CURL_MEMDEBUG */ - -/* Allocator macros */ - -#ifdef _WIN32 -#define CURLX_STRDUP_LOW _strdup -#else -#define CURLX_STRDUP_LOW strdup -#endif - -#ifdef CURL_MEMDEBUG - -#define curlx_strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) -#define curlx_malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__) -#define curlx_calloc(nbelem, size) \ - curl_dbg_calloc(nbelem, size, __LINE__, __FILE__) -#define curlx_realloc(ptr, size) \ - curl_dbg_realloc(ptr, size, __LINE__, __FILE__) -#define curlx_free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__) - -#ifdef _WIN32 -#ifdef UNICODE -#define curlx_tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) -#else -#define curlx_tcsdup curlx_strdup -#endif -#endif /* _WIN32 */ - -#else /* !CURL_MEMDEBUG */ - -#ifdef BUILDING_LIBCURL -#define curlx_strdup Curl_cstrdup -#define curlx_malloc Curl_cmalloc -#define curlx_calloc Curl_ccalloc -#define curlx_realloc Curl_crealloc -#define curlx_free Curl_cfree -#else /* !BUILDING_LIBCURL */ -#define curlx_strdup CURLX_STRDUP_LOW -#define curlx_malloc malloc -#define curlx_calloc calloc -#define curlx_realloc realloc -#define curlx_free free -#endif /* BUILDING_LIBCURL */ - -#ifdef _WIN32 -#ifdef UNICODE -#define curlx_tcsdup curlx_wcsdup -#else -#define curlx_tcsdup curlx_strdup -#endif -#endif /* _WIN32 */ - -#endif /* CURL_MEMDEBUG */ - -/* Some versions of the Android NDK is missing the declaration */ -#if defined(HAVE_GETPWUID_R) && \ - defined(__ANDROID_API__) && (__ANDROID_API__ < 21) -struct passwd; -int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, - size_t buflen, struct passwd **result); -#endif - -#ifdef UNITTESTS -#define UNITTEST -#else -#define UNITTEST static -#endif - -#ifdef USE_NGHTTP2 -#define USE_HTTP2 -#endif - -#if (defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || defined(USE_QUICHE) - -#ifdef CURL_WITH_MULTI_SSL -#error "MultiSSL combined with QUIC is not supported" -#endif - -#define USE_HTTP3 -#endif - -/* WebAssembly builds have TCP_NODELAY, but runtime support is missing. */ -#ifndef __EMSCRIPTEN__ -#define CURL_TCP_NODELAY_SUPPORTED -#endif - -/* Certain Windows implementations are not aligned with what curl expects, - so always use the local one on this platform. E.g. the mingw-w64 - implementation can return wrong results for non-ASCII inputs. */ -#if defined(HAVE_BASENAME) && defined(_WIN32) -#undef HAVE_BASENAME -#endif - -#if defined(USE_UNIX_SOCKETS) && defined(_WIN32) -/* Offered by mingw-w64 v10+. MS SDK 10.17763/~VS2017+. */ -#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR >= 10) -# include -#elif !defined(UNIX_PATH_MAX) /* Replicate logic present in afunix.h */ -# define UNIX_PATH_MAX 108 -/* !checksrc! disable TYPEDEFSTRUCT 1 */ -typedef struct sockaddr_un { - CURL_SA_FAMILY_T sun_family; - char sun_path[UNIX_PATH_MAX]; -} SOCKADDR_UN, *PSOCKADDR_UN; -#endif -#endif - -#ifdef USE_OPENSSL -/* OpenSSL 3 marks these functions deprecated but we have no replacements (yet) - so tell the compiler to not warn for them: - - DES_* (for NTLM), SSL_CTX_set_srp_* (for TLS-SRP) - - EVP_PKEY_get1_RSA, MD5_*, RSA_flags, RSA_free (auto-skipped for OpenSSL - built with no-deprecated) */ -# define OPENSSL_SUPPRESS_DEPRECATED -# ifdef _WIN32 -/* Silence LibreSSL warnings about wincrypt.h collision. Works in 3.8.2+ */ -# ifndef LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING -# define LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING -# endif -# endif -#endif - -#ifdef CURL_INLINE -/* 'CURL_INLINE' defined, use as-is */ -#elif defined(inline) -# define CURL_INLINE inline /* 'inline' defined, assumed correct */ -#elif defined(__cplusplus) -/* The code is compiled with C++ compiler. - C++ always supports 'inline'. */ -# define CURL_INLINE inline /* 'inline' keyword supported */ -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901 -/* C99 (and later) supports 'inline' keyword */ -# define CURL_INLINE inline /* 'inline' keyword supported */ -#elif defined(__GNUC__) && __GNUC__ >= 3 -/* GCC supports '__inline__' as an extension */ -# define CURL_INLINE __inline__ -#elif defined(_MSC_VER) -# define CURL_INLINE __inline -#else -/* Probably 'inline' is not supported by compiler. - Define to the empty string to be on the safe side. */ -# define CURL_INLINE /* empty */ -#endif - -/* Detect if compiler supports C99 variadic macros */ -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ - defined(_MSC_VER) -#define CURL_HAVE_MACRO_VARARG -#endif - -#if !defined(CURL_HAVE_MACRO_VARARG) || \ - (defined(CURL_HAVE_MACRO_VARARG) && !defined(CURL_DISABLE_VERBOSE_STRINGS)) -#define CURLVERBOSE -#define VERBOSE(x) x -#define NOVERBOSE(x) Curl_nop_stmt -#else -#define VERBOSE(x) Curl_nop_stmt -#define NOVERBOSE(x) x -#endif - -#endif /* HEADER_CURL_SETUP_H */ diff --git a/vendor/curl/lib/curl_sha256.h b/vendor/curl/lib/curl_sha256.h deleted file mode 100644 index 6c48a8e17..000000000 --- a/vendor/curl/lib/curl_sha256.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HEADER_CURL_SHA256_H -#define HEADER_CURL_SHA256_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Florin Petriuc, - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ - defined(USE_LIBSSH2) || defined(USE_SSL) - -#include "curl_hmac.h" - -extern const struct HMAC_params Curl_HMAC_SHA256; - -#ifndef CURL_SHA256_DIGEST_LENGTH -#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */ -#endif - -CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input, - size_t len); - -#endif - -#endif /* HEADER_CURL_SHA256_H */ diff --git a/vendor/curl/lib/curl_sha512_256.c b/vendor/curl/lib/curl_sha512_256.c deleted file mode 100644 index 73b959c91..000000000 --- a/vendor/curl/lib/curl_sha512_256.c +++ /dev/null @@ -1,847 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Evgeny Grin (Karlson2k), . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256) - -#include "curl_sha512_256.h" - -/* The recommended order of the TLS backends: - * 1. USE_OPENSSL - * 2. USE_WOLFSSL - * 3. USE_GNUTLS - * 4. USE_MBEDTLS (TBD) - * 5. USE_RUSTLS (TBD) - * 6. USE_WIN32_CRYPTO (TBD) - * Skip the backend if it does not support the required algorithm */ - -#ifdef USE_OPENSSL -# include -# if !defined(LIBRESSL_VERSION_NUMBER) || \ - (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3080000fL) -# include -# define USE_OPENSSL_SHA512_256 1 -# define HAS_SHA512_256_IMPLEMENTATION 1 -# ifdef __NetBSD__ -/* Some NetBSD versions has a bug in SHA-512/256. - * See https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 - * The problematic versions: - * - NetBSD before 9.4 - * - NetBSD 9 all development versions (9.99.x) - * - NetBSD 10 development versions (10.99.x) before 10.99.11 - * The bug was fixed in NetBSD 9.4 release, NetBSD 10.0 release, - * NetBSD 10.99.11 development. - * It is safe to apply the workaround even if the bug is not present, as - * the workaround reduces performance slightly. */ -# include -# if __NetBSD_Version__ < 904000000 || \ - (__NetBSD_Version__ >= 999000000 && \ - __NetBSD_Version__ < 1000000000) || \ - (__NetBSD_Version__ >= 1099000000 && \ - __NetBSD_Version__ < 1099001100) -# define NEED_NETBSD_SHA512_256_WORKAROUND 1 -# endif -# endif -# endif -#endif /* USE_OPENSSL */ - -#if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_WOLFSSL) -# include -# ifndef WOLFSSL_NOSHA512_256 -# define USE_WOLFSSL_SHA512_256 1 -# define HAS_SHA512_256_IMPLEMENTATION 1 -# endif -#endif - -#if !defined(HAS_SHA512_256_IMPLEMENTATION) && defined(USE_GNUTLS) -# include -# ifdef SHA512_256_DIGEST_SIZE -# define USE_GNUTLS_SHA512_256 1 -# endif -#endif /* !HAS_SHA512_256_IMPLEMENTATION && USE_GNUTLS */ - -#ifdef USE_OPENSSL_SHA512_256 - -/* OpenSSL does not provide macros for SHA-512/256 sizes */ - -/** - * Size of the SHA-512/256 single processing block in bytes. - */ -#define CURL_SHA512_256_BLOCK_SIZE 128 - -/** - * Size of the SHA-512/256 resulting digest in bytes. - * This is the final digest size, not intermediate hash. - */ -#define CURL_SHA512_256_DIGEST_SIZE CURL_SHA512_256_DIGEST_LENGTH - -/** - * Context type used for SHA-512/256 calculations - */ -typedef EVP_MD_CTX *Curl_sha512_256_ctx; - -/** - * Initialise structure for SHA-512/256 calculation. - * - * @param context the calculation context - * @return CURLE_OK if succeed, - * error code otherwise - */ -static CURLcode Curl_sha512_256_init(void *context) -{ - Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context; - - *ctx = EVP_MD_CTX_create(); - if(!*ctx) - return CURLE_OUT_OF_MEMORY; - - if(EVP_DigestInit_ex(*ctx, EVP_sha512_256(), NULL)) { - /* Check whether the header and this file use the same numbers */ - DEBUGASSERT(EVP_MD_CTX_size(*ctx) == CURL_SHA512_256_DIGEST_SIZE); - /* Check whether the block size is correct */ - DEBUGASSERT(EVP_MD_CTX_block_size(*ctx) == CURL_SHA512_256_BLOCK_SIZE); - - return CURLE_OK; /* Success */ - } - - /* Cleanup */ - EVP_MD_CTX_destroy(*ctx); - return CURLE_FAILED_INIT; -} - -/** - * Process portion of bytes. - * - * @param context the calculation context - * @param data bytes to add to hash - * @return CURLE_OK if succeed, - * error code otherwise - */ -static CURLcode Curl_sha512_256_update(void *context, - const unsigned char *data, - size_t length) -{ - Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context; - - if(!EVP_DigestUpdate(*ctx, data, length)) - return CURLE_SSL_CIPHER; - - return CURLE_OK; -} - -/** - * Finalise SHA-512/256 calculation, return digest. - * - * @param context the calculation context - * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE - * bytes - * @return CURLE_OK if succeed, - * error code otherwise - */ -static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context) -{ - CURLcode result; - Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context; - -#ifdef NEED_NETBSD_SHA512_256_WORKAROUND - /* Use a larger buffer to work around a bug in NetBSD: - https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=58039 */ - unsigned char tmp_digest[CURL_SHA512_256_DIGEST_SIZE * 2]; - result = EVP_DigestFinal_ex(*ctx, - tmp_digest, NULL) ? CURLE_OK : CURLE_SSL_CIPHER; - if(result == CURLE_OK) - memcpy(digest, tmp_digest, CURL_SHA512_256_DIGEST_SIZE); - explicit_memset(tmp_digest, 0, sizeof(tmp_digest)); -#else /* !NEED_NETBSD_SHA512_256_WORKAROUND */ - result = EVP_DigestFinal_ex(*ctx, digest, NULL) ? - CURLE_OK : CURLE_SSL_CIPHER; -#endif /* NEED_NETBSD_SHA512_256_WORKAROUND */ - - EVP_MD_CTX_destroy(*ctx); - *ctx = NULL; - - return result; -} - -#elif defined(USE_WOLFSSL_SHA512_256) -#include - -#define CURL_SHA512_256_DIGEST_SIZE WC_SHA512_256_DIGEST_SIZE -#define CURL_SHA512_256_BLOCK_SIZE WC_SHA512_256_BLOCK_SIZE - -typedef struct wc_Sha512 Curl_sha512_256_ctx; - -static CURLcode Curl_sha512_256_init(void *ctx) -{ - if(wc_InitSha512_256(ctx)) - return CURLE_FAILED_INIT; - return CURLE_OK; -} - -static CURLcode Curl_sha512_256_update(void *ctx, - const unsigned char *data, - size_t length) -{ - do { - word32 ilen = (word32)CURLMIN(length, UINT_MAX); - if(wc_Sha512_256Update(ctx, data, ilen)) - return CURLE_SSL_CIPHER; - length -= ilen; - data += ilen; - } while(length); - return CURLE_OK; -} - -static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *ctx) -{ - if(wc_Sha512_256Final(ctx, digest)) - return CURLE_SSL_CIPHER; - return CURLE_OK; -} - -#elif defined(USE_GNUTLS_SHA512_256) - -#define CURL_SHA512_256_BLOCK_SIZE SHA512_256_BLOCK_SIZE -#define CURL_SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_SIZE - -/** - * Context type used for SHA-512/256 calculations - */ -typedef struct sha512_256_ctx Curl_sha512_256_ctx; - -/** - * Initialise structure for SHA-512/256 calculation. - * - * @param context the calculation context - * @return always CURLE_OK - */ -static CURLcode Curl_sha512_256_init(void *context) -{ - Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context; - - /* Check whether the header and this file use the same numbers */ - DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE); - - sha512_256_init(ctx); - - return CURLE_OK; -} - -/** - * Process portion of bytes. - * - * @param context the calculation context - * @param data bytes to add to hash - * @param length number of bytes in @a data - * @return always CURLE_OK - */ -static CURLcode Curl_sha512_256_update(void *context, - const unsigned char *data, - size_t length) -{ - Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context; - - DEBUGASSERT((data != NULL) || (length == 0)); - - sha512_256_update(ctx, length, (const uint8_t *)data); - - return CURLE_OK; -} - -/** - * Finalise SHA-512/256 calculation, return digest. - * - * @param context the calculation context - * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE - * bytes - * @return always CURLE_OK - */ -static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context) -{ - Curl_sha512_256_ctx * const ctx = (Curl_sha512_256_ctx *)context; - - sha512_256_digest(ctx, - (size_t)CURL_SHA512_256_DIGEST_SIZE, (uint8_t *)digest); - - return CURLE_OK; -} - -#else /* No system or TLS backend SHA-512/256 implementation available */ - -/* ** This implementation of SHA-512/256 hash calculation was originally ** * - * ** written by Evgeny Grin (Karlson2k) for GNU libmicrohttpd. ** * - * ** The author ported the code to libcurl. The ported code is provided ** * - * ** under curl license. ** */ - -#ifdef __GNUC__ -# if defined(__has_attribute) && defined(__STDC_VERSION__) -# if __has_attribute(always_inline) && __STDC_VERSION__ >= 199901 -# define CURL_FORCEINLINE CURL_INLINE __attribute__((always_inline)) -# endif -# endif -#endif - -#if !defined(CURL_FORCEINLINE) && \ - defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__) -#define CURL_FORCEINLINE __forceinline -#endif - -/* Assume that 'CURL_INLINE' keyword works or the - * macro was already defined correctly. */ -#ifndef CURL_FORCEINLINE -#define CURL_FORCEINLINE CURL_INLINE -#endif - -/* Bits manipulation macros and functions. - Can be moved to other headers to reuse. */ - -#define CURL_GET_64BIT_BE(ptr) \ - (((uint64_t)(((const uint8_t *)(ptr))[0]) << 56) | \ - ((uint64_t)(((const uint8_t *)(ptr))[1]) << 48) | \ - ((uint64_t)(((const uint8_t *)(ptr))[2]) << 40) | \ - ((uint64_t)(((const uint8_t *)(ptr))[3]) << 32) | \ - ((uint64_t)(((const uint8_t *)(ptr))[4]) << 24) | \ - ((uint64_t)(((const uint8_t *)(ptr))[5]) << 16) | \ - ((uint64_t)(((const uint8_t *)(ptr))[6]) << 8) | \ - (uint64_t)(((const uint8_t *)(ptr))[7])) - -#define CURL_PUT_64BIT_BE(ptr, val) \ - do { \ - ((uint8_t *)(ptr))[7] = (uint8_t)((uint64_t)(val)); \ - ((uint8_t *)(ptr))[6] = (uint8_t)(((uint64_t)(val)) >> 8); \ - ((uint8_t *)(ptr))[5] = (uint8_t)(((uint64_t)(val)) >> 16); \ - ((uint8_t *)(ptr))[4] = (uint8_t)(((uint64_t)(val)) >> 24); \ - ((uint8_t *)(ptr))[3] = (uint8_t)(((uint64_t)(val)) >> 32); \ - ((uint8_t *)(ptr))[2] = (uint8_t)(((uint64_t)(val)) >> 40); \ - ((uint8_t *)(ptr))[1] = (uint8_t)(((uint64_t)(val)) >> 48); \ - ((uint8_t *)(ptr))[0] = (uint8_t)(((uint64_t)(val)) >> 56); \ - } while(0) - -/* Defined as a function. The macro version may duplicate the binary code - * size as each argument is used twice, so if any calculation is used - * as an argument, the calculation could be done twice. */ -static CURL_FORCEINLINE uint64_t Curl_rotr64(uint64_t value, unsigned int bits) -{ - bits %= 64; - if(bits == 0) - return value; - /* Defined in a form which modern compiler could optimize. */ - return (value >> bits) | (value << (64 - bits)); -} - -/* SHA-512/256 specific data */ - -/** - * Number of bits in a single SHA-512/256 word. - */ -#define SHA512_256_WORD_SIZE_BITS 64 - -/** - * Number of bytes in a single SHA-512/256 word. - */ -#define SHA512_256_BYTES_IN_WORD (SHA512_256_WORD_SIZE_BITS / 8) - -/** - * Hash is kept internally as 8 64-bit words. - * This is the intermediate hash size, used during computing the final digest. - */ -#define SHA512_256_HASH_SIZE_WORDS 8 - -/** - * Size of the SHA-512/256 resulting digest in words. - * This is the final digest size, not intermediate hash. - */ -#define SHA512_256_DIGEST_SIZE_WORDS (SHA512_256_HASH_SIZE_WORDS / 2) - -/** - * Size of the SHA-512/256 resulting digest in bytes - * This is the final digest size, not intermediate hash. - */ -#define CURL_SHA512_256_DIGEST_SIZE \ - (SHA512_256_DIGEST_SIZE_WORDS * SHA512_256_BYTES_IN_WORD) - -/** - * Size of the SHA-512/256 single processing block in bits. - */ -#define SHA512_256_BLOCK_SIZE_BITS 1024 - -/** - * Size of the SHA-512/256 single processing block in bytes. - */ -#define CURL_SHA512_256_BLOCK_SIZE (SHA512_256_BLOCK_SIZE_BITS / 8) - -/** - * Size of the SHA-512/256 single processing block in words. - */ -#define SHA512_256_BLOCK_SIZE_WORDS \ - (SHA512_256_BLOCK_SIZE_BITS / SHA512_256_WORD_SIZE_BITS) - -/** - * SHA-512/256 calculation context - */ -struct Curl_sha512_256ctx { - /** - * Intermediate hash value. The variable is properly aligned. Smart - * compilers may automatically use fast load/store instruction for big - * endian data on little endian machine. - */ - uint64_t H[SHA512_256_HASH_SIZE_WORDS]; - /** - * SHA-512/256 input data buffer. The buffer is properly aligned. Smart - * compilers may automatically use fast load/store instruction for big - * endian data on little endian machine. - */ - uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS]; - /** - * The number of bytes, lower part - */ - uint64_t count; - /** - * The number of bits, high part. Unlike lower part, this counts the number - * of bits, not bytes. - */ - uint64_t count_bits_hi; -}; - -/** - * Context type used for SHA-512/256 calculations - */ -typedef struct Curl_sha512_256ctx Curl_sha512_256_ctx; - -/** - * Initialise structure for SHA-512/256 calculation. - * - * @param context the calculation context - * @return always CURLE_OK - */ -static CURLcode Curl_sha512_256_init(void *context) -{ - struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context; - - /* Check whether the header and this file use the same numbers */ - DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE); - - DEBUGASSERT(sizeof(uint64_t) == 8); - - /* Initial hash values, see FIPS PUB 180-4 section 5.3.6.2 */ - /* Values generated by "IV Generation Function" as described in - * section 5.3.6 */ - ctx->H[0] = UINT64_C(0x22312194FC2BF72C); - ctx->H[1] = UINT64_C(0x9F555FA3C84C64C2); - ctx->H[2] = UINT64_C(0x2393B86B6F53B151); - ctx->H[3] = UINT64_C(0x963877195940EABD); - ctx->H[4] = UINT64_C(0x96283EE2A88EFFE3); - ctx->H[5] = UINT64_C(0xBE5E1E2553863992); - ctx->H[6] = UINT64_C(0x2B0199FC2C85B8AA); - ctx->H[7] = UINT64_C(0x0EB72DDC81C52CA2); - - /* Initialise number of bytes and high part of number of bits. */ - ctx->count = UINT64_C(0); - ctx->count_bits_hi = UINT64_C(0); - - return CURLE_OK; -} - -/** - * Base of the SHA-512/256 transformation. - * Gets a full 128 bytes block of data and updates hash values; - * @param H hash values - * @param data the data buffer with #CURL_SHA512_256_BLOCK_SIZE bytes block - */ -static void Curl_sha512_256_transform(uint64_t H[SHA512_256_HASH_SIZE_WORDS], - const void *data) -{ - /* Working variables, - see FIPS PUB 180-4 section 6.7, 6.4. */ - uint64_t a = H[0]; - uint64_t b = H[1]; - uint64_t c = H[2]; - uint64_t d = H[3]; - uint64_t e = H[4]; - uint64_t f = H[5]; - uint64_t g = H[6]; - uint64_t h = H[7]; - - /* Data buffer, used as a cyclic buffer. - See FIPS PUB 180-4 section 5.2.2, 6.7, 6.4. */ - uint64_t W[16]; - - /* 'Ch' and 'Maj' macro functions are defined with widely-used optimization. - See FIPS PUB 180-4 formulae 4.8, 4.9. */ -#define Sha512_Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define Sha512_Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y)))) - - /* Four 'Sigma' macro functions. - See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */ -#define SIG0(x) \ - (Curl_rotr64(x, 28) ^ Curl_rotr64(x, 34) ^ Curl_rotr64(x, 39)) -#define SIG1(x) \ - (Curl_rotr64(x, 14) ^ Curl_rotr64(x, 18) ^ Curl_rotr64(x, 41)) -#define sig0(x) \ - (Curl_rotr64(x, 1) ^ Curl_rotr64(x, 8) ^ ((x) >> 7)) -#define sig1(x) \ - (Curl_rotr64(x, 19) ^ Curl_rotr64(x, 61) ^ ((x) >> 6)) - - if(1) { - unsigned int t; - /* K constants array. - See FIPS PUB 180-4 section 4.2.3 for K values. */ - static const uint64_t K[80] = { - UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), - UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), - UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), - UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), - UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), - UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), - UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), - UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), - UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), - UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), - UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), - UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), - UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), - UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), - UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), - UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), - UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), - UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), - UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), - UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), - UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), - UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), - UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), - UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), - UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), - UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), - UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), - UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), - UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), - UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), - UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), - UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), - UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), - UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), - UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), - UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), - UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), - UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), - UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), - UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) - }; - - /* One step of SHA-512/256 computation, - see FIPS PUB 180-4 section 6.4.2 step 3. - * Note: this macro updates working variables in-place, without rotation. - * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in - FIPS PUB 180-4 section 6.4.2 step 3. - the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in - FIPS PUB 180-4 section 6.4.2 step 3. - * Note: 'wt' must be used exactly one time in this macro as macro for - 'wt' calculation may change other data as well every time when - used. */ -#define SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt) \ - do { \ - (vD) += ((vH) += SIG1(vE) + Sha512_Ch(vE, vF, vG) + (kt) + (wt)); \ - (vH) += SIG0(vA) + Sha512_Maj(vA, vB, vC); \ - } while(0) - - /* One step of SHA-512/256 computation with working variables rotation, - see FIPS PUB 180-4 section 6.4.2 step 3. This macro version reassigns - all working variables on each step. */ -#define SHA2STEP64RV(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt) \ - do { \ - uint64_t tmp_h_ = (vH); \ - SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, tmp_h_, kt, wt); \ - (vH) = (vG); \ - (vG) = (vF); \ - (vF) = (vE); \ - (vE) = (vD); \ - (vD) = (vC); \ - (vC) = (vB); \ - (vB) = (vA); \ - (vA) = tmp_h_; \ - } while(0) - - /* Get value of W(t) from input data buffer for 0 <= t <= 15, - See FIPS PUB 180-4 section 6.2. - Input data must be read in big-endian bytes order, - see FIPS PUB 180-4 section 3.1.2. */ -#define SHA512_GET_W_FROM_DATA(buf, t) \ - CURL_GET_64BIT_BE((const uint8_t *)(buf) + ((t) * SHA512_256_BYTES_IN_WORD)) - - /* During first 16 steps, before making any calculation on each step, the - W element is read from the input data buffer as a big-endian value and - stored in the array of W elements. */ - for(t = 0; t < 16; ++t) { - SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], - W[t] = SHA512_GET_W_FROM_DATA(data, t)); - } - - /* 'W' generation and assignment for 16 <= t <= 79. - See FIPS PUB 180-4 section 6.4.2. - As only the last 16 'W' are used in calculations, it is possible to - use 16 elements array of W as a cyclic buffer. - Note: ((t-16) & 15) have same value as (t & 15) */ -#define Wgen(w, t) \ - (uint64_t)((w)[((t) - 16) & 15] + sig1((w)[((t) - 2) & 15]) + \ - (w)[((t) - 7) & 15] + sig0((w)[((t) - 15) & 15])) - - /* During the last 64 steps, before making any calculation on each step, - current W element is generated from other W elements of the cyclic - buffer and the generated value is stored back in the cyclic buffer. */ - for(t = 16; t < 80; ++t) { - SHA2STEP64RV(a, b, c, d, e, f, g, h, K[t], - W[t & 15] = Wgen(W, t)); - } - } - - /* Compute and store the intermediate hash. - See FIPS PUB 180-4 section 6.4.2 step 4. */ - H[0] += a; - H[1] += b; - H[2] += c; - H[3] += d; - H[4] += e; - H[5] += f; - H[6] += g; - H[7] += h; -} - -/** - * Process portion of bytes. - * - * @param context the calculation context - * @param data bytes to add to hash - * @param length number of bytes in @a data - * @return always CURLE_OK - */ -static CURLcode Curl_sha512_256_update(void *context, - const unsigned char *data, - size_t length) -{ - unsigned int bytes_have; /* Number of bytes in the context buffer */ - struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context; - /* the void pointer here is required to mute Intel compiler warning */ - void * const ctx_buf = ctx->buffer; - - DEBUGASSERT((data != NULL) || (length == 0)); - - if(length == 0) - return CURLE_OK; /* Shortcut, do nothing */ - - /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1)) - equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */ - bytes_have = (unsigned int)(ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1)); - ctx->count += length; - if(length > ctx->count) - ctx->count_bits_hi += 1U << 3; /* Value wrap */ - ctx->count_bits_hi += ctx->count >> 61; - ctx->count &= UINT64_C(0x1FFFFFFFFFFFFFFF); - - if(bytes_have) { - unsigned int bytes_left = CURL_SHA512_256_BLOCK_SIZE - bytes_have; - if(length >= bytes_left) { - /* Combine new data with data in the buffer and process the full - block. */ - memcpy((unsigned char *)ctx_buf + bytes_have, data, bytes_left); - data += bytes_left; - length -= bytes_left; - Curl_sha512_256_transform(ctx->H, ctx->buffer); - bytes_have = 0; - } - } - - while(CURL_SHA512_256_BLOCK_SIZE <= length) { - /* Process any full blocks of new data directly, - without copying to the buffer. */ - Curl_sha512_256_transform(ctx->H, data); - data += CURL_SHA512_256_BLOCK_SIZE; - length -= CURL_SHA512_256_BLOCK_SIZE; - } - - if(length) { - /* Copy incomplete block of new data (if any) - to the buffer. */ - memcpy((unsigned char *)ctx_buf + bytes_have, data, length); - } - - return CURLE_OK; -} - -/** - * Size of "length" insertion in bits. - * See FIPS PUB 180-4 section 5.1.2. - */ -#define SHA512_256_SIZE_OF_LEN_ADD_BITS 128 - -/** - * Size of "length" insertion in bytes. - */ -#define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8) - -/** - * Finalise SHA-512/256 calculation, return digest. - * - * @param context the calculation context - * @param[out] digest set to the hash, must be #CURL_SHA512_256_DIGEST_SIZE - * bytes - * @return always CURLE_OK - */ -static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context) -{ - struct Curl_sha512_256ctx * const ctx = (struct Curl_sha512_256ctx *)context; - uint64_t num_bits; /* Number of processed bits */ - unsigned int bytes_have; /* Number of bytes in the context buffer */ - /* the void pointer here is required to mute Intel compiler warning */ - void * const ctx_buf = ctx->buffer; - - /* Memorise the number of processed bits. - The padding and other data added here during the postprocessing must - not change the amount of hashed data. */ - num_bits = ctx->count << 3; - - /* Note: (count & (CURL_SHA512_256_BLOCK_SIZE-1)) - equals (count % CURL_SHA512_256_BLOCK_SIZE) for this block size. */ - bytes_have = (unsigned int)(ctx->count & (CURL_SHA512_256_BLOCK_SIZE - 1)); - - /* Input data must be padded with a single bit "1", then with zeros and - the finally the length of data in bits must be added as the final bytes - of the last block. - See FIPS PUB 180-4 section 5.1.2. */ - - /* Data is always processed in form of bytes (not by individual bits), - therefore position of the first padding bit in byte is always - predefined (0x80). */ - /* Buffer always have space at least for one byte (as full buffers are - processed when formed). */ - ((unsigned char *)ctx_buf)[bytes_have++] = 0x80U; - - if(CURL_SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) { - /* No space in the current block to put the total length of message. - Pad the current block with zeros and process it. */ - if(bytes_have < CURL_SHA512_256_BLOCK_SIZE) - memset((unsigned char *)ctx_buf + bytes_have, 0, - CURL_SHA512_256_BLOCK_SIZE - bytes_have); - /* Process the full block. */ - Curl_sha512_256_transform(ctx->H, ctx->buffer); - /* Start the new block. */ - bytes_have = 0; - } - - /* Pad the rest of the buffer with zeros. */ - memset((unsigned char *)ctx_buf + bytes_have, 0, - CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have); - /* Put high part of number of bits in processed message and then lower - part of number of bits as big-endian values. - See FIPS PUB 180-4 section 5.1.2. */ - /* Note: the target location is predefined and buffer is always aligned */ - CURL_PUT_64BIT_BE((unsigned char *)ctx_buf + - CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD, - ctx->count_bits_hi); - CURL_PUT_64BIT_BE((unsigned char *)ctx_buf + - CURL_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD + - SHA512_256_BYTES_IN_WORD, - num_bits); - /* Process the full final block. */ - Curl_sha512_256_transform(ctx->H, ctx->buffer); - - /* Put in BE mode the leftmost part of the hash as the final digest. - See FIPS PUB 180-4 section 6.7. */ - - CURL_PUT_64BIT_BE(digest + (0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]); - CURL_PUT_64BIT_BE(digest + (1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]); - CURL_PUT_64BIT_BE(digest + (2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]); - CURL_PUT_64BIT_BE(digest + (3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]); - - /* Erase potentially sensitive data. */ - memset(ctx, 0, sizeof(struct Curl_sha512_256ctx)); - - return CURLE_OK; -} - -#endif /* Local SHA-512/256 code */ - -/** - * Compute SHA-512/256 hash for the given data in one function call - * @param[out] output the pointer to put the hash - * @param[in] input the pointer to the data to process - * @param input_size the size of the data pointed by @a input - * @return always #CURLE_OK - */ -CURLcode Curl_sha512_256it(unsigned char *output, const unsigned char *input, - size_t input_size) -{ - Curl_sha512_256_ctx ctx; - CURLcode result; - - result = Curl_sha512_256_init(&ctx); - if(result != CURLE_OK) - return result; - - result = Curl_sha512_256_update(&ctx, (const void *)input, input_size); - - if(result != CURLE_OK) { - (void)Curl_sha512_256_finish(output, &ctx); - return result; - } - - return Curl_sha512_256_finish(output, &ctx); -} - -/* Wrapper function, takes 'unsigned int' as length type, returns void */ -static void Curl_sha512_256_update_i(void *context, - const unsigned char *data, - unsigned int length) -{ - /* Hypothetically the function may fail, but assume it does not */ - (void)Curl_sha512_256_update(context, data, length); -} - -/* Wrapper function, returns void */ -static void Curl_sha512_256_finish_v(unsigned char *result, void *context) -{ - /* Hypothetically the function may fail, but assume it does not */ - (void)Curl_sha512_256_finish(result, context); -} - -/* Wrapper function, takes 'unsigned int' as length type, returns void */ - -const struct HMAC_params Curl_HMAC_SHA512_256[] = { - { - /* Initialize context procedure. */ - Curl_sha512_256_init, - /* Update context with data. */ - Curl_sha512_256_update_i, - /* Get final result procedure. */ - Curl_sha512_256_finish_v, - /* Context structure size. */ - sizeof(Curl_sha512_256_ctx), - /* Maximum key length (bytes). */ - CURL_SHA512_256_BLOCK_SIZE, - /* Result length (bytes). */ - CURL_SHA512_256_DIGEST_SIZE - } -}; - -#endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */ diff --git a/vendor/curl/lib/curl_sha512_256.h b/vendor/curl/lib/curl_sha512_256.h deleted file mode 100644 index ddaf8be91..000000000 --- a/vendor/curl/lib/curl_sha512_256.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef HEADER_CURL_SHA512_256_H -#define HEADER_CURL_SHA512_256_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Evgeny Grin (Karlson2k), . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_DIGEST_AUTH) && !defined(CURL_DISABLE_SHA512_256) - -#include "curl_hmac.h" - -#define CURL_HAVE_SHA512_256 - -extern const struct HMAC_params Curl_HMAC_SHA512_256[1]; - -#define CURL_SHA512_256_DIGEST_LENGTH 32 - -CURLcode Curl_sha512_256it(unsigned char *output, const unsigned char *input, - size_t input_size); - -#endif /* !CURL_DISABLE_DIGEST_AUTH && !CURL_DISABLE_SHA512_256 */ - -#endif /* HEADER_CURL_SHA256_H */ diff --git a/vendor/curl/lib/curl_share.c b/vendor/curl/lib/curl_share.c deleted file mode 100644 index 386a2b547..000000000 --- a/vendor/curl/lib/curl_share.c +++ /dev/null @@ -1,472 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "multiif.h" -#include "curl_threads.h" -#include "curl_share.h" -#include "vtls/vtls.h" -#include "vtls/vtls_scache.h" -#include "hsts.h" -#include "url.h" - -static void share_destroy(struct Curl_share *share) -{ - if(share->specifier & (1 << CURL_LOCK_DATA_CONNECT)) { - Curl_cpool_destroy(&share->cpool); - } - - Curl_dnscache_destroy(&share->dnscache); - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - Curl_cookie_cleanup(share->cookies); -#endif - -#ifndef CURL_DISABLE_HSTS - Curl_hsts_cleanup(&share->hsts); -#endif - -#ifdef USE_SSL - if(share->ssl_scache) { - Curl_ssl_scache_destroy(share->ssl_scache); - share->ssl_scache = NULL; - } -#endif - - Curl_psl_destroy(&share->psl); - Curl_close(&share->admin); - -#ifdef USE_MUTEX - Curl_mutex_destroy(&share->lock); -#endif - share->magic = 0; - curlx_free(share); -} - -CURLSH *curl_share_init(void) -{ - struct Curl_share *share = curlx_calloc(1, sizeof(struct Curl_share)); - if(share) { - share->magic = CURL_GOOD_SHARE; - share->specifier |= (1 << CURL_LOCK_DATA_SHARE); -#ifdef USE_MUTEX - Curl_mutex_init(&share->lock); -#endif - share->ref_count = 1; - Curl_dnscache_init(&share->dnscache, 23); - share->admin = curl_easy_init(); - if(!share->admin) { - share_destroy(share); - return NULL; - } - /* admin handles have mid 0 */ - share->admin->mid = 0; - share->admin->state.internal = TRUE; -#ifdef DEBUGBUILD - if(getenv("CURL_DEBUG")) - share->admin->set.verbose = TRUE; -#endif - } - return share; -} - -static uint32_t share_ref_inc(struct Curl_share *share) -{ - uint32_t n; -#ifdef USE_MUTEX - Curl_mutex_acquire(&share->lock); - n = ++(share->ref_count); - share->has_been_shared = TRUE; - Curl_mutex_release(&share->lock); -#else - n = ++(share->ref_count); - share->has_been_shared = TRUE; -#endif - return n; -} - -static uint32_t share_ref_dec(struct Curl_share *share) -{ - uint32_t n; -#ifdef USE_MUTEX - Curl_mutex_acquire(&share->lock); - DEBUGASSERT(share->ref_count); - n = --(share->ref_count); - Curl_mutex_release(&share->lock); -#else - n = --(share->ref_count); -#endif - return n; -} - -static bool share_has_been_shared(struct Curl_share *share) -{ - bool was_shared; -#ifdef USE_MUTEX - Curl_mutex_acquire(&share->lock); - was_shared = share->has_been_shared; - Curl_mutex_release(&share->lock); -#else - was_shared = share->has_been_shared; -#endif - return was_shared; -} - -static bool share_lock_acquire(struct Curl_share *share, - struct Curl_easy *data) -{ - if(share->lockfunc && share->unlockfunc && - (data || share_has_been_shared(share))) { - share->lockfunc(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE, - share->clientdata); - return TRUE; - } - return FALSE; -} - -static void share_lock_release(struct Curl_share *share, - struct Curl_easy *data, - bool locked) -{ - if(locked) { - DEBUGASSERT(share->unlockfunc); - if(share->unlockfunc) - share->unlockfunc(data, CURL_LOCK_DATA_SHARE, share->clientdata); - } -} - -static bool share_in_use(struct Curl_share *share) -{ - bool in_use; -#ifdef USE_MUTEX - Curl_mutex_acquire(&share->lock); - in_use = (share->ref_count > 1); - Curl_mutex_release(&share->lock); -#else - bool locked = share_lock_acquire(share, NULL); - in_use = (share->ref_count > 1); - share_lock_release(share, NULL, locked); -#endif - return in_use; -} - -static void share_unlink(struct Curl_share **pshare, - struct Curl_easy *data, - bool locked) -{ - struct Curl_share *share = *pshare; - uint32_t n; - - *pshare = NULL; - n = share_ref_dec(share); - if(locked) - share_lock_release(share, data, locked); - if(!n) /* last reference gone */ - share_destroy(share); -} - -#undef curl_share_setopt -CURLSHcode curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) -{ - va_list param; - int type; - curl_lock_function lockfunc; - curl_unlock_function unlockfunc; - void *ptr; - CURLSHcode res = CURLSHE_OK; - struct Curl_share *share = sh; - - if(!GOOD_SHARE_HANDLE(share)) - return CURLSHE_INVALID; - - if(share_in_use(share)) { - /* do not allow setting options while one or more handles are already - using this share */ - return CURLSHE_IN_USE; - } - - va_start(param, option); - - switch(option) { - case CURLSHOPT_SHARE: - /* this is a type this share will share */ - type = va_arg(param, int); - - switch(type) { - case CURL_LOCK_DATA_DNS: - break; - - case CURL_LOCK_DATA_COOKIE: -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(!share->cookies) { - share->cookies = Curl_cookie_init(); - if(!share->cookies) - res = CURLSHE_NOMEM; - } -#else /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */ - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_HSTS: -#ifndef CURL_DISABLE_HSTS - if(!share->hsts) { - share->hsts = Curl_hsts_init(); - if(!share->hsts) - res = CURLSHE_NOMEM; - } -#else /* CURL_DISABLE_HSTS */ - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_SSL_SESSION: -#ifdef USE_SSL - if(!share->ssl_scache) { - /* There is no way (yet) for the application to configure the - * session cache size, shared between many transfers. As for curl - * itself, a high session count will impact startup time. Also, the - * scache is not optimized for several hundreds of peers. - * Keep it at a reasonable level. */ - if(Curl_ssl_scache_create(25, 2, &share->ssl_scache)) - res = CURLSHE_NOMEM; - } -#else - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_CONNECT: - /* It is safe to set this option several times on a share. */ - if(!share->cpool.initialised) { - Curl_cpool_init(&share->cpool, share->admin, share, 103); - } - break; - - case CURL_LOCK_DATA_PSL: -#ifndef USE_LIBPSL - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - default: - res = CURLSHE_BAD_OPTION; - } - if(!res) - share->specifier |= (unsigned int)(1 << type); - break; - - case CURLSHOPT_UNSHARE: - /* this is a type this share will no longer share */ - type = va_arg(param, int); - switch(type) { - case CURL_LOCK_DATA_DNS: - break; - - case CURL_LOCK_DATA_COOKIE: -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(share->cookies) { - Curl_cookie_cleanup(share->cookies); - share->cookies = NULL; - } -#else /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */ - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_HSTS: -#ifndef CURL_DISABLE_HSTS - if(share->hsts) { - Curl_hsts_cleanup(&share->hsts); - } -#else /* CURL_DISABLE_HSTS */ - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_SSL_SESSION: -#ifdef USE_SSL - if(share->ssl_scache) { - Curl_ssl_scache_destroy(share->ssl_scache); - share->ssl_scache = NULL; - } -#else - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_CONNECT: - break; - - default: - res = CURLSHE_BAD_OPTION; - break; - } - if(!res) - share->specifier &= ~(unsigned int)(1 << type); - break; - - case CURLSHOPT_LOCKFUNC: - lockfunc = va_arg(param, curl_lock_function); - share->lockfunc = lockfunc; - break; - - case CURLSHOPT_UNLOCKFUNC: - unlockfunc = va_arg(param, curl_unlock_function); - share->unlockfunc = unlockfunc; - break; - - case CURLSHOPT_USERDATA: - ptr = va_arg(param, void *); - share->clientdata = ptr; - break; - - default: - res = CURLSHE_BAD_OPTION; - break; - } - - va_end(param); - - return res; -} - -CURLSHcode curl_share_cleanup(CURLSH *sh) -{ - struct Curl_share *share = sh; - bool locked; - if(!GOOD_SHARE_HANDLE(share)) - return CURLSHE_INVALID; - - if(share_in_use(share)) - return CURLSHE_IN_USE; - - locked = share_lock_acquire(share, NULL); - share_unlink(&share, NULL, locked); - return CURLSHE_OK; -} - -CURLSHcode Curl_share_lock(struct Curl_easy *data, curl_lock_data type, - curl_lock_access accesstype) -{ - struct Curl_share *share = data->share; - - if(!share) - return CURLSHE_INVALID; - - if(share->specifier & (unsigned int)(1 << type)) { - if(share->lockfunc) /* only call this if set! */ - share->lockfunc(data, type, accesstype, share->clientdata); - } - /* else if we do not share this, pretend successful lock */ - - return CURLSHE_OK; -} - -CURLSHcode Curl_share_unlock(struct Curl_easy *data, curl_lock_data type) -{ - struct Curl_share *share = data->share; - - if(!share) - return CURLSHE_INVALID; - - if(share->specifier & (unsigned int)(1 << type)) { - if(share->unlockfunc) /* only call this if set! */ - share->unlockfunc(data, type, share->clientdata); - } - - return CURLSHE_OK; -} - -CURLcode Curl_share_easy_unlink(struct Curl_easy *data) -{ - struct Curl_share *share = data->share; - - if(share) { - bool locked = share_lock_acquire(share, data); - - /* If data has a connection from this share, detach it. */ - if(data->conn && (share->specifier & (1 << CURL_LOCK_DATA_CONNECT))) - Curl_detach_connection(data); - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(share->cookies == data->cookies) - data->cookies = NULL; -#endif - -#ifndef CURL_DISABLE_HSTS - if(share->hsts == data->hsts) - data->hsts = NULL; -#endif -#ifdef USE_LIBPSL - if(&share->psl == data->psl) - data->psl = data->multi ? &data->multi->psl : NULL; -#endif - - share_unlink(&data->share, data, locked); - } - return CURLE_OK; -} - -CURLcode Curl_share_easy_link(struct Curl_easy *data, - struct Curl_share *share) -{ - if(data->share) { - DEBUGASSERT(0); - return CURLE_FAILED_INIT; - } - - if(share) { - bool locked = share_lock_acquire(share, data); - - share_ref_inc(share); - data->share = share; - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(share->cookies) { - /* use shared cookie list, first free own one if any */ - Curl_cookie_cleanup(data->cookies); - /* enable cookies since we now use a share that uses cookies! */ - data->cookies = share->cookies; - } -#endif /* CURL_DISABLE_HTTP */ -#ifndef CURL_DISABLE_HSTS - if(share->hsts) { - /* first free the private one if any */ - Curl_hsts_cleanup(&data->hsts); - data->hsts = share->hsts; - } -#endif -#ifdef USE_LIBPSL - if(share->specifier & (1 << CURL_LOCK_DATA_PSL)) - data->psl = &share->psl; -#endif - - /* check for host cache not needed, - * it will be done by curl_easy_perform */ - share_lock_release(share, data, locked); - } - return CURLE_OK; -} diff --git a/vendor/curl/lib/curl_share.h b/vendor/curl/lib/curl_share.h deleted file mode 100644 index 69001be70..000000000 --- a/vendor/curl/lib/curl_share.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef HEADER_CURL_SHARE_H -#define HEADER_CURL_SHARE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curl_threads.h" -#include "cookie.h" -#include "psl.h" -#include "urldata.h" -#include "conncache.h" - -struct Curl_easy; -struct Curl_ssl_scache; - -#define CURL_GOOD_SHARE 0x7e117a1e -#define GOOD_SHARE_HANDLE(x) ((x) && (x)->magic == CURL_GOOD_SHARE) - -#define CURL_SHARE_KEEP_CONNECT(s) \ - ((s) && ((s)->specifier & (1 << CURL_LOCK_DATA_CONNECT))) - -/* this struct is libcurl-private, do not export details */ -struct Curl_share { - unsigned int magic; /* CURL_GOOD_SHARE */ - unsigned int specifier; - - uint32_t ref_count; -#ifdef USE_MUTEX - /* do `ref_count` and `has_been_shared` checks using this mutex. */ - curl_mutex_t lock; - int has_been_shared; -#else - /* this only ever goes from FALSE -> TRUE once. We need to check - * this without being able to use the `lockfunc`. */ - volatile int has_been_shared; -#endif - curl_lock_function lockfunc; - curl_unlock_function unlockfunc; - void *clientdata; - struct Curl_easy *admin; - - struct cpool cpool; - struct Curl_dnscache dnscache; /* DNS cache */ -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - struct CookieInfo *cookies; -#endif -#ifdef USE_LIBPSL - struct PslCache psl; -#endif -#ifndef CURL_DISABLE_HSTS - struct hsts *hsts; -#endif -#ifdef USE_SSL - struct Curl_ssl_scache *ssl_scache; -#endif -}; - -CURLSHcode Curl_share_lock(struct Curl_easy *data, curl_lock_data type, - curl_lock_access accesstype); -CURLSHcode Curl_share_unlock(struct Curl_easy *data, curl_lock_data type); - -/* convenience macro to check if this handle is using a shared SSL spool */ -#define CURL_SHARE_ssl_scache(data) ((data)->share && \ - ((data)->share->specifier & \ - (1 << CURL_LOCK_DATA_SSL_SESSION))) - -CURLcode Curl_share_easy_unlink(struct Curl_easy *data); -CURLcode Curl_share_easy_link(struct Curl_easy *data, - struct Curl_share *share); - -#endif /* HEADER_CURL_SHARE_H */ diff --git a/vendor/curl/lib/curl_sspi.c b/vendor/curl/lib/curl_sspi.c deleted file mode 100644 index 3ea17621b..000000000 --- a/vendor/curl/lib/curl_sspi.c +++ /dev/null @@ -1,207 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_WINDOWS_SSPI - -#include "curl_sspi.h" -#include "curlx/strdup.h" -#include "curlx/multibyte.h" - -/* Pointer to SSPI dispatch table */ -PSecurityFunctionTable Curl_pSecFn = NULL; - -/* - * Curl_sspi_global_init() - * - * This is used to load the Security Service Provider Interface (SSPI) - * dynamic link library portably across all Windows versions, without - * the need to directly link libcurl, nor the application using it, at - * build time. - * - * Once this function has been executed, Windows SSPI functions can be - * called through the Security Service Provider Interface dispatch table. - * - * Parameters: - * - * None. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_sspi_global_init(void) -{ - /* If security interface is not yet initialized try to do this */ - if(!Curl_pSecFn) { - /* Get pointer to Security Service Provider Interface dispatch table */ - Curl_pSecFn = InitSecurityInterface(); - if(!Curl_pSecFn) - return CURLE_FAILED_INIT; - } - - return CURLE_OK; -} - -/* - * Curl_sspi_global_cleanup() - * - * This deinitializes the Security Service Provider Interface from libcurl. - * - * Parameters: - * - * None. - */ -void Curl_sspi_global_cleanup(void) -{ - if(Curl_pSecFn) { - Curl_pSecFn = NULL; - } -} - -/* - * Curl_create_sspi_identity() - * - * This is used to populate an SSPI identity structure based on the supplied - * username and password. - * - * Parameters: - * - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * identity [in/out] - The identity structure. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, - SEC_WINNT_AUTH_IDENTITY *identity) -{ - xcharp_u useranddomain; - xcharp_u user, dup_user; - xcharp_u domain, dup_domain; - xcharp_u passwd, dup_passwd; - size_t domlen = 0; - - domain.const_tchar_ptr = TEXT(""); - - /* Initialize the identity */ - memset(identity, 0, sizeof(*identity)); - - useranddomain.tchar_ptr = curlx_convert_UTF8_to_tchar(userp); - if(!useranddomain.tchar_ptr) - return CURLE_OUT_OF_MEMORY; - - user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\')); - if(!user.const_tchar_ptr) - user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/')); - - if(user.tchar_ptr) { - domain.tchar_ptr = useranddomain.tchar_ptr; - domlen = user.tchar_ptr - useranddomain.tchar_ptr; - user.tchar_ptr++; - } - else { - user.tchar_ptr = useranddomain.tchar_ptr; - domain.const_tchar_ptr = TEXT(""); - domlen = 0; - } - - /* Setup the identity's user and length */ - dup_user.tchar_ptr = curlx_tcsdup(user.tchar_ptr); - if(!dup_user.tchar_ptr) { - curlx_free(useranddomain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - - /* Setup the identity's domain and length */ - dup_domain.tchar_ptr = curlx_malloc(sizeof(TCHAR) * (domlen + 1)); - if(!dup_domain.tchar_ptr) { - curlx_free(dup_user.tchar_ptr); - curlx_free(useranddomain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - if(_tcsncpy_s(dup_domain.tchar_ptr, domlen + 1, domain.tchar_ptr, domlen)) { - curlx_free(dup_user.tchar_ptr); - curlx_free(dup_domain.tchar_ptr); - curlx_free(useranddomain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - - curlx_free(useranddomain.tchar_ptr); - - /* Setup the identity's password and length */ - passwd.tchar_ptr = curlx_convert_UTF8_to_tchar(passwdp); - if(!passwd.tchar_ptr) { - curlx_free(dup_user.tchar_ptr); - curlx_free(dup_domain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - dup_passwd.tchar_ptr = curlx_tcsdup(passwd.tchar_ptr); - if(!dup_passwd.tchar_ptr) { - curlx_free(dup_user.tchar_ptr); - curlx_free(dup_domain.tchar_ptr); - curlx_free(passwd.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - identity->Password = dup_passwd.tbyte_ptr; - identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); - dup_passwd.tchar_ptr = NULL; - - curlx_free(passwd.tchar_ptr); - - identity->User = dup_user.tbyte_ptr; - identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr)); - dup_user.tchar_ptr = NULL; - identity->Domain = dup_domain.tbyte_ptr; - identity->DomainLength = curlx_uztoul(domlen); - dup_domain.tchar_ptr = NULL; - - /* Setup the identity's flags */ - identity->Flags = (unsigned long) -#ifdef UNICODE - SEC_WINNT_AUTH_IDENTITY_UNICODE; -#else - SEC_WINNT_AUTH_IDENTITY_ANSI; -#endif - - return CURLE_OK; -} - -/* - * Curl_sspi_free_identity() - * - * This is used to free the contents of an SSPI identifier structure. - * - * Parameters: - * - * identity [in/out] - The identity structure. - */ -void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity) -{ - if(identity) { - curlx_safefree(identity->User); - curlx_safefree(identity->Password); - curlx_safefree(identity->Domain); - } -} - -#endif /* USE_WINDOWS_SSPI */ diff --git a/vendor/curl/lib/curl_sspi.h b/vendor/curl/lib/curl_sspi.h deleted file mode 100644 index 3779d5175..000000000 --- a/vendor/curl/lib/curl_sspi.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef HEADER_CURL_SSPI_H -#define HEADER_CURL_SSPI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_WINDOWS_SSPI - -#include - -CURLcode Curl_sspi_global_init(void); -void Curl_sspi_global_cleanup(void); - -/* This is used to populate the domain in an SSPI identity structure */ -CURLcode Curl_override_sspi_http_realm(const char *chlg, - SEC_WINNT_AUTH_IDENTITY *identity); - -/* This is used to generate an SSPI identity structure */ -CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, - SEC_WINNT_AUTH_IDENTITY *identity); - -/* This is used to free an SSPI identity structure */ -void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity); - -/* Forward-declaration of global variables defined in curl_sspi.c */ -extern PSecurityFunctionTable Curl_pSecFn; - -/* Provide Service Principal names as macros */ -#define SP_NAME_DIGEST "WDigest" -#define SP_NAME_NTLM "NTLM" -#define SP_NAME_NEGOTIATE "Negotiate" -#define SP_NAME_KERBEROS "Kerberos" - -/* Offered by mingw-w64 v9+. MS SDK 7.0A+. */ -#ifndef ISC_REQ_USE_HTTP_STYLE -#define ISC_REQ_USE_HTTP_STYLE 0x01000000 -#endif - -/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ -#ifndef SEC_E_INVALID_PARAMETER -#define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL) -#endif -/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ -#ifndef SEC_E_DELEGATION_POLICY -#define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL) -#endif -/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ -#ifndef SEC_E_POLICY_NLTM_ONLY -#define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL) -#endif - -/* Offered by mingw-w64 v8+. MS SDK 6.0A+. */ -#ifndef SEC_I_SIGNATURE_NEEDED -#define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL) -#endif - -/* - * Definitions required from ntsecapi.h are directly provided below this point - * to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h - */ -#define KERB_WRAP_NO_ENCRYPT 0x80000001 - -#endif /* USE_WINDOWS_SSPI */ - -#endif /* HEADER_CURL_SSPI_H */ diff --git a/vendor/curl/lib/curl_threads.c b/vendor/curl/lib/curl_threads.c deleted file mode 100644 index 01041f63c..000000000 --- a/vendor/curl/lib/curl_threads.c +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "curl_threads.h" -#include "curlx/timeval.h" - -#ifdef USE_THREADS - -#ifdef HAVE_THREADS_POSIX - -struct Curl_actual_call { - unsigned int (*func)(void *); - void *arg; -}; - -static void *curl_thread_create_thunk(void *arg) -{ - struct Curl_actual_call *ac = arg; - unsigned int (*func)(void *) = ac->func; - void *real_arg = ac->arg; - - curlx_free(ac); - - (*func)(real_arg); - - return 0; -} - -curl_thread_t Curl_thread_create( - CURL_THREAD_RETURN_T(CURL_STDCALL *func)(void *), void *arg) -{ - curl_thread_t t = curlx_malloc(sizeof(pthread_t)); - struct Curl_actual_call *ac = NULL; - int rc; - - if(t) - ac = curlx_malloc(sizeof(struct Curl_actual_call)); - if(!(ac && t)) - goto err; - - ac->func = func; - ac->arg = arg; - - rc = pthread_create(t, NULL, curl_thread_create_thunk, ac); - if(rc) { - errno = rc; - goto err; - } - - return t; - -err: - curlx_free(t); - curlx_free(ac); - return curl_thread_t_null; -} - -void Curl_thread_destroy(curl_thread_t *hnd) -{ - if(*hnd != curl_thread_t_null) { - pthread_detach(**hnd); - curlx_free(*hnd); - *hnd = curl_thread_t_null; - } -} - -int Curl_thread_join(curl_thread_t *hnd) -{ - int ret = (pthread_join(**hnd, NULL) == 0); - - curlx_free(*hnd); - *hnd = curl_thread_t_null; - - return ret; -} - -#elif defined(_WIN32) - -curl_thread_t Curl_thread_create( - CURL_THREAD_RETURN_T(CURL_STDCALL *func)(void *), void *arg) -{ - curl_thread_t t = CreateThread(NULL, 0, func, arg, 0, NULL); - if(!t) { - DWORD gle = GetLastError(); - /* !checksrc! disable ERRNOVAR 1 */ - errno = (gle == ERROR_ACCESS_DENIED || - gle == ERROR_NOT_ENOUGH_MEMORY) ? - EACCES : EINVAL; - return curl_thread_t_null; - } - return t; -} - -void Curl_thread_destroy(curl_thread_t *hnd) -{ - if(*hnd != curl_thread_t_null) { - CloseHandle(*hnd); - *hnd = curl_thread_t_null; - } -} - -int Curl_thread_join(curl_thread_t *hnd) -{ - int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0); - - Curl_thread_destroy(hnd); - - return ret; -} - -#else -#error neither HAVE_THREADS_POSIX nor _WIN32 defined -#endif -#endif /* USE_THREADS */ - -#ifdef USE_MUTEX - -#ifdef HAVE_THREADS_POSIX - -void Curl_cond_signal(pthread_cond_t *c) -{ - /* return code defined as always 0 */ - (void)pthread_cond_signal(c); -} - -void Curl_cond_wait(pthread_cond_t *c, pthread_mutex_t *m) -{ - /* return code defined as always 0 */ - (void)pthread_cond_wait(c, m); -} - -CURLcode Curl_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, - uint32_t timeout_ms) -{ - struct curltime now; - struct timespec ts; - timediff_t usec; - int rc; - - /* POSIX expects an "absolute" time until the condition wait ends. - * We cannot use `curlx_now()` here that may run on some monotonic clock - * that will be most likely in the past, as far as POSIX abstime is - * concerned. */ -#ifdef HAVE_GETTIMEOFDAY - struct timeval tv; - (void)gettimeofday(&tv, NULL); - now.tv_sec = tv.tv_sec; - now.tv_usec = (int)tv.tv_usec; -#else - now.tv_sec = time(NULL); - now.tv_usec = 0; -#endif - - ts.tv_sec = now.tv_sec + (timeout_ms / 1000); - usec = now.tv_usec + ((timeout_ms % 1000) * 1000); - if(usec >= 1000000) { - ++ts.tv_sec; - usec %= 1000000; - } - ts.tv_nsec = (long)usec * 1000; - - rc = pthread_cond_timedwait(c, m, &ts); - if(rc == SOCKETIMEDOUT) - return CURLE_OPERATION_TIMEDOUT; - return rc ? CURLE_UNRECOVERABLE_POLL : CURLE_OK; -} - -#elif defined(_WIN32) - -void Curl_cond_signal(CONDITION_VARIABLE *c) -{ - WakeConditionVariable(c); -} - -void Curl_cond_wait(CONDITION_VARIABLE *c, CRITICAL_SECTION *m) -{ - SleepConditionVariableCS(c, m, INFINITE); -} - -CURLcode Curl_cond_timedwait(CONDITION_VARIABLE *c, CRITICAL_SECTION *m, - uint32_t timeout_ms) -{ - if(!SleepConditionVariableCS(c, m, (DWORD)timeout_ms)) { - DWORD err = GetLastError(); - return (err == ERROR_TIMEOUT) ? - CURLE_OPERATION_TIMEDOUT : CURLE_UNRECOVERABLE_POLL; - } - return CURLE_OK; -} -#else -#error neither HAVE_THREADS_POSIX nor _WIN32 defined -#endif -#endif /* USE_MUTEX */ diff --git a/vendor/curl/lib/curl_threads.h b/vendor/curl/lib/curl_threads.h deleted file mode 100644 index 081d15569..000000000 --- a/vendor/curl/lib/curl_threads.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef HEADER_CURL_THREADS_H -#define HEADER_CURL_THREADS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_MUTEX -#ifdef HAVE_THREADS_POSIX -# define CURL_THREAD_RETURN_T unsigned int -# define CURL_STDCALL -# define curl_mutex_t pthread_mutex_t -# define curl_thread_t pthread_t * -# define curl_thread_t_null (pthread_t *)0 -# define Curl_mutex_init(m) pthread_mutex_init(m, NULL) -# define Curl_mutex_acquire(m) pthread_mutex_lock(m) -# define Curl_mutex_release(m) pthread_mutex_unlock(m) -# define Curl_mutex_destroy(m) pthread_mutex_destroy(m) -# define curl_cond_t pthread_cond_t -# define Curl_cond_init(c) pthread_cond_init(c, NULL) -# define Curl_cond_destroy(c) pthread_cond_destroy(c) -#elif defined(_WIN32) -# define CURL_THREAD_RETURN_T DWORD -# define CURL_STDCALL WINAPI -# define curl_mutex_t CRITICAL_SECTION -# define curl_thread_t HANDLE -# define curl_thread_t_null (HANDLE)0 -# define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1) -# define Curl_mutex_acquire(m) EnterCriticalSection(m) -# define Curl_mutex_release(m) LeaveCriticalSection(m) -# define Curl_mutex_destroy(m) DeleteCriticalSection(m) -# define curl_cond_t CONDITION_VARIABLE -# define Curl_cond_init(c) InitializeConditionVariable(c) -# define Curl_cond_destroy(c) (void)(c) -#else -#error neither HAVE_THREADS_POSIX nor _WIN32 defined -#endif - -void Curl_cond_signal(curl_cond_t *c); -void Curl_cond_wait(curl_cond_t *c, curl_mutex_t *m); -/* Returns CURLE_OPERATION_TIMEDOUT on timeout */ -CURLcode Curl_cond_timedwait(curl_cond_t *c, curl_mutex_t *m, - uint32_t timeout_ms); -#endif /* USE_MUTEX */ - -#ifdef USE_THREADS - -curl_thread_t Curl_thread_create( - CURL_THREAD_RETURN_T(CURL_STDCALL *func)(void *), void *arg); - -void Curl_thread_destroy(curl_thread_t *hnd); - -int Curl_thread_join(curl_thread_t *hnd); - -#endif /* USE_THREADS */ - -#endif /* HEADER_CURL_THREADS_H */ diff --git a/vendor/curl/lib/curl_trc.c b/vendor/curl/lib/curl_trc.c deleted file mode 100644 index c6115cf7f..000000000 --- a/vendor/curl/lib/curl_trc.c +++ /dev/null @@ -1,773 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curl_trc.h" -#include "urldata.h" -#include "cfilters.h" -#include "multiif.h" - -#include "cf-dns.h" -#include "cf-socket.h" -#include "connect.h" -#include "http2.h" -#include "http_proxy.h" -#include "cf-h1-proxy.h" -#include "cf-h2-proxy.h" -#include "cf-haproxy.h" -#include "cf-https-connect.h" -#include "cf-ip-happy.h" -#include "progress.h" -#include "socks.h" -#include "curlx/strparse.h" -#include "vtls/vtls.h" -#include "vquic/vquic.h" -#include "curlx/strcopy.h" - -static void trc_write(struct Curl_easy *data, curl_infotype type, - const char *ptr, size_t size) -{ - if(data->set.verbose) { - if(data->set.fdebug) { - bool inCallback = Curl_is_in_callback(data); - Curl_set_in_callback(data, TRUE); - (void)(*data->set.fdebug)(data, type, CURL_UNCONST(ptr), size, - data->set.debugdata); - Curl_set_in_callback(data, inCallback); - } - else { - static const char s_infotype[CURLINFO_END][3] = { - "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; - switch(type) { - case CURLINFO_TEXT: - case CURLINFO_HEADER_OUT: - case CURLINFO_HEADER_IN: - fwrite(s_infotype[type], 2, 1, data->set.err); - fwrite(ptr, size, 1, data->set.err); - break; - default: /* nada */ - break; - } - } - } -} - -/* max length we trace before ending in '...' */ -#define TRC_LINE_MAX 2048 - -#define CURL_TRC_FMT_IDSC "[x-%" CURL_FORMAT_CURL_OFF_T "] " -#define CURL_TRC_FMT_IDSD "[%" CURL_FORMAT_CURL_OFF_T "-x] " -#define CURL_TRC_FMT_IDSDC "[%" CURL_FORMAT_CURL_OFF_T "-%" \ - CURL_FORMAT_CURL_OFF_T "] " - -static struct curl_trc_feat Curl_trc_feat_ids = { - "LIB-IDS", - CURL_LOG_LVL_NONE, -}; -#define CURL_TRC_IDS(data) \ - (Curl_trc_is_verbose(data) && \ - Curl_trc_feat_ids.log_level >= CURL_LOG_LVL_INFO) - -static size_t trc_print_ids(struct Curl_easy *data, char *buf, size_t maxlen) -{ - curl_off_t cid = data->conn ? - data->conn->connection_id : data->state.recent_conn_id; - if(data->id >= 0) { - if(cid >= 0) - return curl_msnprintf(buf, maxlen, CURL_TRC_FMT_IDSDC, data->id, cid); - else - return curl_msnprintf(buf, maxlen, CURL_TRC_FMT_IDSD, data->id); - } - else if(cid >= 0) - return curl_msnprintf(buf, maxlen, CURL_TRC_FMT_IDSC, cid); - else { - return curl_msnprintf(buf, maxlen, "[x-x] "); - } -} - -static size_t trc_end_buf(char *buf, size_t len, size_t maxlen, bool addnl) -{ - /* make sure we end the trace line in `buf` properly. It needs - * to end with a terminating '\0' or '\n\0' */ - if(len >= (maxlen - (addnl ? 2 : 1))) { - len = maxlen - 5; - buf[len++] = '.'; - buf[len++] = '.'; - buf[len++] = '.'; - buf[len++] = '\n'; - } - else if(addnl) - buf[len++] = '\n'; - buf[len] = '\0'; - return len; -} - -void Curl_debug(struct Curl_easy *data, curl_infotype type, - const char *ptr, size_t size) -{ - if(data->set.verbose) { - static const char s_infotype[CURLINFO_END][3] = { - "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; - char buf[TRC_LINE_MAX]; - size_t len; - if(data->set.fdebug) { - bool inCallback = Curl_is_in_callback(data); - - if(CURL_TRC_IDS(data) && (size < TRC_LINE_MAX)) { - len = trc_print_ids(data, buf, TRC_LINE_MAX); - len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "%.*s", - (int)size, ptr); - len = trc_end_buf(buf, len, TRC_LINE_MAX, FALSE); - Curl_set_in_callback(data, TRUE); - (void)(*data->set.fdebug)(data, type, buf, len, data->set.debugdata); - Curl_set_in_callback(data, inCallback); - } - else { - Curl_set_in_callback(data, TRUE); - (void)(*data->set.fdebug)(data, type, CURL_UNCONST(ptr), - size, data->set.debugdata); - Curl_set_in_callback(data, inCallback); - } - } - else { - switch(type) { - case CURLINFO_TEXT: - case CURLINFO_HEADER_OUT: - case CURLINFO_HEADER_IN: -#ifndef CURL_DISABLE_VERBOSE_STRINGS - if(CURL_TRC_IDS(data)) { - len = trc_print_ids(data, buf, TRC_LINE_MAX); - fwrite(buf, len, 1, data->set.err); - } -#endif - fwrite(s_infotype[type], 2, 1, data->set.err); - fwrite(ptr, size, 1, data->set.err); - break; - default: /* nada */ - break; - } - } - } -} - -/* Curl_failf() is for messages stating why we failed. - * The message SHALL NOT include any LF or CR. - */ -void Curl_failf(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(data->set.verbose || data->set.errorbuffer) { - va_list ap; - size_t len; - char error[CURL_ERROR_SIZE + 2]; - va_start(ap, fmt); - len = curl_mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap); - - if(data->set.errorbuffer && !data->state.errorbuf) { - curlx_strcopy(data->set.errorbuffer, CURL_ERROR_SIZE, error, len); - data->state.errorbuf = TRUE; /* wrote error string */ - } - error[len++] = '\n'; - error[len] = '\0'; - trc_write(data, CURLINFO_TEXT, error, len); - va_end(ap); - } -} - -void Curl_reset_fail(struct Curl_easy *data) -{ - if(data->set.errorbuffer) - data->set.errorbuffer[0] = 0; - data->state.errorbuf = FALSE; -} - -#ifdef CURLVERBOSE -struct curl_trc_feat Curl_trc_feat_multi = { - "MULTI", - CURL_LOG_LVL_NONE, -}; -struct curl_trc_feat Curl_trc_feat_read = { - "READ", - CURL_LOG_LVL_NONE, -}; -struct curl_trc_feat Curl_trc_feat_write = { - "WRITE", - CURL_LOG_LVL_NONE, -}; -struct curl_trc_feat Curl_trc_feat_dns = { - "DNS", - CURL_LOG_LVL_NONE, -}; -struct curl_trc_feat Curl_trc_feat_timer = { - "TIMER", - CURL_LOG_LVL_NONE, -}; -#ifdef USE_THREADS -struct curl_trc_feat Curl_trc_feat_threads = { - "THREADS", - CURL_LOG_LVL_NONE, -}; -#endif -#endif - -#ifndef CURL_DISABLE_VERBOSE_STRINGS - -static void trc_infof(struct Curl_easy *data, - struct curl_trc_feat *feat, - const char *opt_id, int opt_id_idx, - const char * const fmt, va_list ap) CURL_PRINTF(5, 0); - -static void trc_infof(struct Curl_easy *data, - struct curl_trc_feat *feat, - const char *opt_id, int opt_id_idx, - const char * const fmt, va_list ap) -{ - size_t len = 0; - char buf[TRC_LINE_MAX]; - - if(CURL_TRC_IDS(data)) - len += trc_print_ids(data, buf + len, TRC_LINE_MAX - len); - if(feat) - len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", feat->name); - if(opt_id) { - if(opt_id_idx > 0) - len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "[%s-%d] ", - opt_id, opt_id_idx); - else - len += curl_msnprintf(buf + len, TRC_LINE_MAX - len, "[%s] ", opt_id); - } - len += curl_mvsnprintf(buf + len, TRC_LINE_MAX - len, fmt, ap); - len = trc_end_buf(buf, len, TRC_LINE_MAX, TRUE); - trc_write(data, CURLINFO_TEXT, buf, len); -} - -void Curl_infof(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_is_verbose(data)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, data->state.feat, NULL, 0, fmt, ap); - va_end(ap); - } -} - -void Curl_trc_cf_infof(struct Curl_easy *data, const struct Curl_cfilter *cf, - const char *fmt, ...) -{ - DEBUGASSERT(cf); - if(Curl_trc_cf_is_verbose(cf, data)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, data->state.feat, cf->cft->name, cf->sockindex, fmt, ap); - va_end(ap); - } -} - -void Curl_trc_feat_infof(struct Curl_easy *data, - struct curl_trc_feat *feat, - const char *fmt, ...) -{ - DEBUGASSERT(feat); - if(Curl_trc_ft_is_verbose(data, feat)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, feat, NULL, 0, fmt, ap); - va_end(ap); - } -} - -static const char * const Curl_trc_timer_names[] = { - "100_TIMEOUT", - "ASYNC_NAME", - "CONNECTTIMEOUT", - "DNS_PER_NAME", - "DNS_PER_NAME2", - "HAPPY_EYEBALLS_DNS", - "HAPPY_EYEBALLS", - "MULTI_PENDING", - "SPEEDCHECK", - "TIMEOUT", - "TOOFAST", - "QUIC", - "FTP_ACCEPT", - "ALPN_EYEBALLS", - "SHUTDOWN", -}; - -static const char *trc_timer_name(int tid) -{ - if((tid >= 0) && ((size_t)tid < CURL_ARRAYSIZE(Curl_trc_timer_names))) - return Curl_trc_timer_names[(size_t)tid]; - return "UNKNOWN?"; -} - -void Curl_trc_timer(struct Curl_easy *data, int tid, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_timer)) { - const char *tname = trc_timer_name(tid); - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_timer, tname, 0, fmt, ap); - va_end(ap); - } -} - -void Curl_trc_easy_timers(struct Curl_easy *data) -{ - if(CURL_TRC_TIMER_is_verbose(data)) { - struct Curl_llist_node *e = Curl_llist_head(&data->state.timeoutlist); - if(e) { - const struct curltime *pnow = Curl_pgrs_now(data); - while(e) { - struct time_node *n = Curl_node_elem(e); - e = Curl_node_next(e); - CURL_TRC_TIMER(data, n->eid, "expires in %" FMT_TIMEDIFF_T "ns", - curlx_ptimediff_us(&n->time, pnow)); - } - } - } -} - -static const char * const Curl_trc_mstate_names[] = { - "INIT", - "PENDING", - "SETUP", - "CONNECT", - "CONNECTING", - "PROTOCONNECT", - "PROTOCONNECTING", - "DO", - "DOING", - "DOING_MORE", - "DID", - "PERFORMING", - "RATELIMITING", - "DONE", - "COMPLETED", - "MSGSENT", -}; - -const char *Curl_trc_mstate_name(int state) -{ - if((state >= 0) && ((size_t)state < CURL_ARRAYSIZE(Curl_trc_mstate_names))) - return Curl_trc_mstate_names[(size_t)state]; - return "?"; -} - -void Curl_trc_multi(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_multi)) { - const char *sname = (data->id >= 0) ? - Curl_trc_mstate_name(data->mstate) : NULL; - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_multi, sname, 0, fmt, ap); - va_end(ap); - } -} - -void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_read)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_read, NULL, 0, fmt, ap); - va_end(ap); - } -} - -void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_write)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_write, NULL, 0, fmt, ap); - va_end(ap); - } -} - -void Curl_trc_dns(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_dns, NULL, 0, fmt, ap); - va_end(ap); - } -} - -#ifndef CURL_DISABLE_FTP -struct curl_trc_feat Curl_trc_feat_ftp = { - "FTP", - CURL_LOG_LVL_NONE, -}; - -void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ftp)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_ftp, NULL, 0, fmt, ap); - va_end(ap); - } -} -#endif /* !CURL_DISABLE_FTP */ - -#ifndef CURL_DISABLE_SMTP -struct curl_trc_feat Curl_trc_feat_smtp = { - "SMTP", - CURL_LOG_LVL_NONE, -}; - -void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_smtp, NULL, 0, fmt, ap); - va_end(ap); - } -} -#endif /* !CURL_DISABLE_SMTP */ - -#ifdef USE_SSL -struct curl_trc_feat Curl_trc_feat_ssls = { - "SSLS", - CURL_LOG_LVL_NONE, -}; - -void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssls)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_ssls, NULL, 0, fmt, ap); - va_end(ap); - } -} -#endif /* USE_SSL */ - -#ifdef USE_SSH -struct curl_trc_feat Curl_trc_feat_ssh = { - "SSH", - CURL_LOG_LVL_NONE, -}; - -void Curl_trc_ssh(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssh)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_ssh, NULL, 0, fmt, ap); - va_end(ap); - } -} -#endif /* USE_SSH */ - -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) -struct curl_trc_feat Curl_trc_feat_ws = { - "WS", - CURL_LOG_LVL_NONE, -}; - -void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...) -{ - DEBUGASSERT(!strchr(fmt, '\n')); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) { - va_list ap; - va_start(ap, fmt); - trc_infof(data, &Curl_trc_feat_ws, NULL, 0, fmt, ap); - va_end(ap); - } -} -#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */ - -#define TRC_CT_NONE 0 -#define TRC_CT_PROTOCOL (1 << 0) -#define TRC_CT_NETWORK (1 << 1) -#define TRC_CT_PROXY (1 << 2) -#define TRC_CT_INTERNALS (1 << 3) - -struct trc_feat_def { - struct curl_trc_feat *feat; - unsigned int category; -}; - -static struct trc_feat_def trc_feats[] = { - { &Curl_trc_feat_ids, TRC_CT_INTERNALS }, - { &Curl_trc_feat_multi, TRC_CT_NETWORK }, - { &Curl_trc_feat_read, TRC_CT_NONE }, - { &Curl_trc_feat_write, TRC_CT_NONE }, - { &Curl_trc_feat_dns, TRC_CT_NETWORK }, - { &Curl_trc_feat_timer, TRC_CT_NETWORK }, -#ifdef USE_THREADS - { &Curl_trc_feat_threads, TRC_CT_NONE }, -#endif -#ifndef CURL_DISABLE_FTP - { &Curl_trc_feat_ftp, TRC_CT_PROTOCOL }, -#endif -#ifndef CURL_DISABLE_SMTP - { &Curl_trc_feat_smtp, TRC_CT_PROTOCOL }, -#endif -#ifdef USE_SSL - { &Curl_trc_feat_ssls, TRC_CT_NETWORK }, -#endif -#ifdef USE_SSH - { &Curl_trc_feat_ssh, TRC_CT_PROTOCOL }, -#endif -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) - { &Curl_trc_feat_ws, TRC_CT_PROTOCOL }, -#endif -}; - -struct trc_cft_def { - struct Curl_cftype *cft; - unsigned int category; -}; - -static struct trc_cft_def trc_cfts[] = { - { &Curl_cft_dns, TRC_CT_NETWORK }, - { &Curl_cft_tcp, TRC_CT_NETWORK }, - { &Curl_cft_udp, TRC_CT_NETWORK }, - { &Curl_cft_unix, TRC_CT_NETWORK }, - { &Curl_cft_tcp_accept, TRC_CT_NETWORK }, - { &Curl_cft_ip_happy, TRC_CT_NETWORK }, - { &Curl_cft_setup, TRC_CT_PROTOCOL }, -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) - { &Curl_cft_nghttp2, TRC_CT_PROTOCOL }, -#endif -#ifdef USE_SSL - { &Curl_cft_ssl, TRC_CT_NETWORK }, -#ifndef CURL_DISABLE_PROXY - { &Curl_cft_ssl_proxy, TRC_CT_PROXY }, -#endif -#endif -#ifndef CURL_DISABLE_PROXY -#ifndef CURL_DISABLE_HTTP - { &Curl_cft_h1_proxy, TRC_CT_PROXY }, -#ifdef USE_NGHTTP2 - { &Curl_cft_h2_proxy, TRC_CT_PROXY }, -#endif - { &Curl_cft_http_proxy, TRC_CT_PROXY }, -#endif /* !CURL_DISABLE_HTTP */ - { &Curl_cft_haproxy, TRC_CT_PROXY }, - { &Curl_cft_socks_proxy, TRC_CT_PROXY }, -#endif /* !CURL_DISABLE_PROXY */ -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) - { &Curl_cft_http3, TRC_CT_PROTOCOL }, -#endif -#ifndef CURL_DISABLE_HTTP - { &Curl_cft_http_connect, TRC_CT_PROTOCOL }, -#endif -}; - -static void trc_apply_level_by_name(struct Curl_str *token, int lvl) -{ - size_t i; - - for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) { - if(curlx_str_casecompare(token, trc_cfts[i].cft->name)) { - trc_cfts[i].cft->log_level = lvl; - break; - } - } - for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) { - if(curlx_str_casecompare(token, trc_feats[i].feat->name)) { - trc_feats[i].feat->log_level = lvl; - break; - } - } -} - -static void trc_apply_level_by_category(unsigned int category, int lvl) -{ - size_t i; - - for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) { - if(!category || (trc_cfts[i].category & category)) - trc_cfts[i].cft->log_level = lvl; - } - for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) { - if(!category || (trc_feats[i].category & category)) - trc_feats[i].feat->log_level = lvl; - } -} - -static CURLcode trc_opt(const char *config) -{ - struct Curl_str out; - while(!curlx_str_until(&config, &out, 32, ',')) { - int lvl = CURL_LOG_LVL_INFO; - const char *token = curlx_str(&out); - - if(*token == '-') { - lvl = CURL_LOG_LVL_NONE; - curlx_str_nudge(&out, 1); - } - else if(*token == '+') - curlx_str_nudge(&out, 1); - - if(curlx_str_casecompare(&out, "all")) - trc_apply_level_by_category(TRC_CT_NONE, lvl); - else if(curlx_str_casecompare(&out, "protocol")) - trc_apply_level_by_category(TRC_CT_PROTOCOL, lvl); - else if(curlx_str_casecompare(&out, "network")) - trc_apply_level_by_category(TRC_CT_NETWORK, lvl); - else if(curlx_str_casecompare(&out, "proxy")) - trc_apply_level_by_category(TRC_CT_PROXY, lvl); - else if(curlx_str_casecompare(&out, "doh")) { - struct Curl_str dns = { "dns", 3 }; - trc_apply_level_by_name(&dns, lvl); - } - else - trc_apply_level_by_name(&out, lvl); - - if(curlx_str_single(&config, ',')) - break; - } - return CURLE_OK; -} - -CURLcode Curl_trc_opt(const char *config) -{ - CURLcode result = config ? trc_opt(config) : CURLE_OK; -#ifdef DEBUGBUILD - /* CURL_DEBUG can override anything */ - if(!result) { - const char *dbg_config = getenv("CURL_DEBUG"); - if(dbg_config) - result = trc_opt(dbg_config); - } -#endif /* DEBUGBUILD */ - return result; -} - -CURLcode Curl_trc_init(void) -{ -#ifdef DEBUGBUILD - return Curl_trc_opt(NULL); -#else - return CURLE_OK; -#endif -} - -#else /* CURL_DISABLE_VERBOSE_STRINGS */ - -CURLcode Curl_trc_init(void) -{ - return CURLE_OK; -} - -void Curl_infof(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} - -void Curl_trc_cf_infof(struct Curl_easy *data, const struct Curl_cfilter *cf, - const char *fmt, ...) -{ - (void)data; - (void)cf; - (void)fmt; -} - -void Curl_trc_multi(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} - -void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} - -void Curl_trc_dns(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} - -void Curl_trc_timer(struct Curl_easy *data, int tid, const char *fmt, ...) -{ - (void)data; - (void)tid; - (void)fmt; -} - -void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} - -#ifndef CURL_DISABLE_FTP -void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} -#endif -#ifndef CURL_DISABLE_SMTP -void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} -#endif -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) -void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} -#endif -#ifdef USE_SSH -void Curl_trc_ssh(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} -#endif -#ifdef USE_SSL -void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...) -{ - (void)data; - (void)fmt; -} -#endif - -#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ diff --git a/vendor/curl/lib/curl_trc.h b/vendor/curl/lib/curl_trc.h deleted file mode 100644 index b4ae8e531..000000000 --- a/vendor/curl/lib/curl_trc.h +++ /dev/null @@ -1,344 +0,0 @@ -#ifndef HEADER_CURL_TRC_H -#define HEADER_CURL_TRC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -struct Curl_easy; -struct Curl_cfilter; - -/** - * Init logging, return != 0 on failure. - */ -CURLcode Curl_trc_init(void); - -/** - * Configure tracing. May be called several times during global - * initialization. Later calls may not take effect. - * - * Configuration format supported: - * - comma-separated list of component names to enable logging on. - * E.g. 'http/2,ssl'. Unknown names are ignored. Names are compared - * case-insensitive. - * - component 'all' applies to all known log components - * - prefixing a component with '+' or '-' will en-/disable logging for - * that component - * Example: 'all,-ssl' would enable logging for all components but the - * SSL filters. - * - * @param config configuration string - */ -CURLcode Curl_trc_opt(const char *config); - -/* the function used to output verbose information */ -void Curl_debug(struct Curl_easy *data, curl_infotype type, - const char *ptr, size_t size); - -/** - * Output a failure message on registered callbacks for transfer. - */ -void Curl_failf(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); - -#define failf Curl_failf - -/* In case failf() reported into the errorbuf, clear it again. - * This is used to clear information from happy eyeballing attempts - * when ultimately a successful attempt was made. */ -void Curl_reset_fail(struct Curl_easy *data); - -#define CURL_LOG_LVL_NONE 0 -#define CURL_LOG_LVL_INFO 1 - -/** - * Output an informational message when transfer's verbose logging is enabled. - */ -void Curl_infof(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); - -/** - * Output an informational message when both transfer's verbose logging - * and connection filters verbose logging are enabled. - */ -void Curl_trc_cf_infof(struct Curl_easy *data, const struct Curl_cfilter *cf, - const char *fmt, ...) CURL_PRINTF(3, 4); -void Curl_trc_multi(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -const char *Curl_trc_mstate_name(int state); -const char *Curl_trc_timer_name(int tid); -void Curl_trc_easy_timers(struct Curl_easy *data); - -void Curl_trc_write(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -void Curl_trc_read(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -void Curl_trc_dns(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -void Curl_trc_timer(struct Curl_easy *data, int tid, - const char *fmt, ...) CURL_PRINTF(3, 4); - -struct curl_trc_feat { - const char *name; - int log_level; -}; - -void Curl_trc_feat_infof(struct Curl_easy *data, - struct curl_trc_feat *feat, - const char *fmt, ...) CURL_PRINTF(3, 4); - -#ifndef CURL_DISABLE_FTP -extern struct curl_trc_feat Curl_trc_feat_ftp; -void Curl_trc_ftp(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -#endif -#ifndef CURL_DISABLE_SMTP -extern struct curl_trc_feat Curl_trc_feat_smtp; -void Curl_trc_smtp(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -#endif -#ifdef USE_SSL -extern struct curl_trc_feat Curl_trc_feat_ssls; -void Curl_trc_ssls(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -#endif -#ifdef USE_SSH -extern struct curl_trc_feat Curl_trc_feat_ssh; -void Curl_trc_ssh(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -#endif -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) -extern struct curl_trc_feat Curl_trc_feat_ws; -void Curl_trc_ws(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); -#endif - -#define CURL_TRC_M_is_verbose(data) \ - Curl_trc_ft_is_verbose(data, &Curl_trc_feat_multi) -#define CURL_TRC_DNS_is_verbose(data) \ - Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns) -#define CURL_TRC_TIMER_is_verbose(data) \ - Curl_trc_ft_is_verbose(data, &Curl_trc_feat_timer) - -#if defined(CURL_HAVE_MACRO_VARARG) && !defined(CURL_DISABLE_VERBOSE_STRINGS) -#define infof(data, ...) \ - do { \ - if(Curl_trc_is_verbose(data)) \ - Curl_infof(data, __VA_ARGS__); \ - } while(0) -#define CURL_TRC_M(data, ...) \ - do { \ - if(CURL_TRC_M_is_verbose(data)) \ - Curl_trc_multi(data, __VA_ARGS__); \ - } while(0) -#define CURL_TRC_CF(data, cf, ...) \ - do { \ - if(Curl_trc_cf_is_verbose(cf, data)) \ - Curl_trc_cf_infof(data, cf, __VA_ARGS__); \ - } while(0) -#define CURL_TRC_WRITE(data, ...) \ - do { \ - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_write)) \ - Curl_trc_write(data, __VA_ARGS__); \ - } while(0) -#define CURL_TRC_READ(data, ...) \ - do { \ - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_read)) \ - Curl_trc_read(data, __VA_ARGS__); \ - } while(0) -#define CURL_TRC_DNS(data, ...) \ - do { \ - if(CURL_TRC_DNS_is_verbose(data)) \ - Curl_trc_dns(data, __VA_ARGS__); \ - } while(0) -#define CURL_TRC_TIMER(data, tid, ...) \ - do { \ - if(CURL_TRC_TIMER_is_verbose(data)) \ - Curl_trc_timer(data, tid, __VA_ARGS__); \ - } while(0) - -#ifndef CURL_DISABLE_FTP -#define CURL_TRC_FTP(data, ...) \ - do { \ - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ftp)) \ - Curl_trc_ftp(data, __VA_ARGS__); \ - } while(0) -#endif /* !CURL_DISABLE_FTP */ -#ifndef CURL_DISABLE_SMTP -#define CURL_TRC_SMTP(data, ...) \ - do { \ - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) \ - Curl_trc_smtp(data, __VA_ARGS__); \ - } while(0) -#endif /* !CURL_DISABLE_SMTP */ -#ifdef USE_SSL -#define CURL_TRC_SSLS(data, ...) \ - do { \ - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssls)) \ - Curl_trc_ssls(data, __VA_ARGS__); \ - } while(0) -#endif /* USE_SSL */ -#ifdef USE_SSH -#define CURL_TRC_SSH(data, ...) \ - do { \ - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssh)) \ - Curl_trc_ssh(data, __VA_ARGS__); \ - } while(0) -#endif /* USE_SSH */ -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) -#define CURL_TRC_WS(data, ...) \ - do { \ - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) \ - Curl_trc_ws(data, __VA_ARGS__); \ - } while(0) -#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */ - -#elif defined(CURL_HAVE_MACRO_VARARG) && defined(CURL_DISABLE_VERBOSE_STRINGS) - -#define infof(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#define CURL_TRC_M(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#define CURL_TRC_CF(data, cf, ...) \ - do { \ - (void)(data); \ - (void)(cf); \ - } while(0) -#define CURL_TRC_WRITE(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#define CURL_TRC_READ(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#define CURL_TRC_DNS(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#define CURL_TRC_TIMER(data, tid, ...) \ - do { \ - (void)(data); \ - (void)(tid); \ - } while(0) -#ifndef CURL_DISABLE_FTP -#define CURL_TRC_FTP(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#endif /* !CURL_DISABLE_FTP */ -#ifndef CURL_DISABLE_SMTP -#define CURL_TRC_SMTP(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#endif /* !CURL_DISABLE_SMTP */ -#ifdef USE_SSL -#define CURL_TRC_SSLS(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#endif /* USE_SSL */ -#ifdef USE_SSH -#define CURL_TRC_SSH(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#endif /* USE_SSH */ -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) -#define CURL_TRC_WS(data, ...) \ - do { \ - (void)(data); \ - } while(0) -#endif - -#else /* !CURL_HAVE_MACRO_VARARG */ - -#define infof Curl_infof -#define CURL_TRC_M Curl_trc_multi -#define CURL_TRC_CF Curl_trc_cf_infof -#define CURL_TRC_WRITE Curl_trc_write -#define CURL_TRC_READ Curl_trc_read -#define CURL_TRC_DNS Curl_trc_dns -#define CURL_TRC_TIMER Curl_trc_timer - -#ifndef CURL_DISABLE_FTP -#define CURL_TRC_FTP Curl_trc_ftp -#endif -#ifndef CURL_DISABLE_SMTP -#define CURL_TRC_SMTP Curl_trc_smtp -#endif -#ifdef USE_SSL -#define CURL_TRC_SSLS Curl_trc_ssls -#endif -#ifdef USE_SSH -#define CURL_TRC_SSH Curl_trc_ssh -#endif -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) -#define CURL_TRC_WS Curl_trc_ws -#endif - -#endif /* CURL_HAVE_MACRO_VARARG */ - -#ifdef CURLVERBOSE -extern struct curl_trc_feat Curl_trc_feat_multi; -extern struct curl_trc_feat Curl_trc_feat_read; -extern struct curl_trc_feat Curl_trc_feat_write; -extern struct curl_trc_feat Curl_trc_feat_dns; -extern struct curl_trc_feat Curl_trc_feat_timer; -#ifdef USE_THREADS -extern struct curl_trc_feat Curl_trc_feat_threads; -#endif -#endif - -#ifndef CURL_DISABLE_VERBOSE_STRINGS -/* informational messages enabled */ -#define Curl_trc_is_verbose(data) \ - ((data) && (data)->set.verbose && \ - (!(data)->state.feat || \ - ((data)->state.feat->log_level >= CURL_LOG_LVL_INFO))) -#define Curl_trc_cf_is_verbose(cf, data) \ - (Curl_trc_is_verbose(data) && \ - (cf) && (cf)->cft->log_level >= CURL_LOG_LVL_INFO) -#define Curl_trc_ft_is_verbose(data, ft) \ - (Curl_trc_is_verbose(data) && \ - (ft)->log_level >= CURL_LOG_LVL_INFO) -#define CURL_MSTATE_NAME(s) Curl_trc_mstate_name((int)(s)) -#define CURL_TRC_EASY_TIMERS(data) \ - do { \ - if(CURL_TRC_TIMER_is_verbose(data)) \ - Curl_trc_easy_timers(data); \ - } while(0) - -#else /* CURL_DISABLE_VERBOSE_STRINGS */ -/* All informational messages are not compiled in for size savings */ -#define Curl_trc_is_verbose(d) FALSE -#define Curl_trc_cf_is_verbose(x, y) FALSE -#define Curl_trc_ft_is_verbose(x, y) FALSE -#define CURL_MSTATE_NAME(x) ((void)(x), "-") -#define CURL_TRC_EASY_TIMERS(x) Curl_nop_stmt -#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ - -#endif /* HEADER_CURL_TRC_H */ diff --git a/vendor/curl/lib/curlx/base64.c b/vendor/curl/lib/curlx/base64.c deleted file mode 100644 index 7f51576f5..000000000 --- a/vendor/curl/lib/curlx/base64.c +++ /dev/null @@ -1,267 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* Base64 encoding/decoding */ - -#include "curl_setup.h" - -#include "curlx/base64.h" - -/* ---- Base64 Encoding/Decoding Table --- */ -const char curlx_base64encdec[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648 - section 5 */ -static const char base64url[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - -static const unsigned char decodetable[] = { - 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, - 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 -}; -/* - * curlx_base64_decode() - * - * Given a base64 null-terminated string at src, decode it and return a - * pointer in *outptr to a newly allocated memory area holding decoded data. - * Size of decoded data is returned in variable pointed by outlen. - * - * Returns CURLE_OK on success, otherwise specific error code. Function - * output shall not be considered valid unless CURLE_OK is returned. - * - * When decoded data length is 0, returns NULL in *outptr. - * - * @unittest: 1302 - */ -CURLcode curlx_base64_decode(const char *src, - uint8_t **outptr, size_t *outlen) -{ - size_t srclen = 0; - size_t padding = 0; - size_t i; - size_t numQuantums; - size_t fullQuantums; - size_t rawlen = 0; - unsigned char *pos; - unsigned char *newstr; - unsigned char lookup[256]; - - *outptr = NULL; - *outlen = 0; - srclen = strlen(src); - - /* Check the length of the input string is valid */ - if(!srclen || srclen % 4) - return CURLE_BAD_CONTENT_ENCODING; - - /* srclen is at least 4 here */ - while(src[srclen - 1 - padding] == '=') { - /* count padding characters */ - padding++; - /* A maximum of two = padding characters is allowed */ - if(padding > 2) - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Calculate the number of quantums */ - numQuantums = srclen / 4; - fullQuantums = numQuantums - (padding ? 1 : 0); - - /* Calculate the size of the decoded string */ - rawlen = (numQuantums * 3) - padding; - - /* Allocate our buffer including room for a null-terminator */ - newstr = curlx_malloc(rawlen + 1); - if(!newstr) - return CURLE_OUT_OF_MEMORY; - - pos = newstr; - - memset(lookup, 0xff, sizeof(lookup)); - memcpy(&lookup['+'], decodetable, sizeof(decodetable)); - - /* Decode the complete quantums first */ - for(i = 0; i < fullQuantums; i++) { - unsigned char val; - unsigned int x = 0; - int j; - - for(j = 0; j < 4; j++) { - val = lookup[(unsigned char)*src++]; - if(val == 0xff) /* bad symbol */ - goto bad; - x = (x << 6) | val; - } - pos[2] = x & 0xff; - pos[1] = (x >> 8) & 0xff; - pos[0] = (x >> 16) & 0xff; - pos += 3; - } - if(padding) { - /* this means either 8 or 16 bits output */ - unsigned char val; - unsigned int x = 0; - int j; - size_t padc = 0; - for(j = 0; j < 4; j++) { - if(*src == '=') { - x <<= 6; - src++; - if(++padc > padding) - /* this is a badly placed '=' symbol! */ - goto bad; - } - else { - val = lookup[(unsigned char)*src++]; - if(val == 0xff) /* bad symbol */ - goto bad; - x = (x << 6) | val; - } - } - if(padding == 1) - pos[1] = (x >> 8) & 0xff; - pos[0] = (x >> 16) & 0xff; - pos += 3 - padding; - } - - /* Null-terminate */ - *pos = '\0'; - - /* Return the decoded data */ - *outptr = newstr; - *outlen = rawlen; - - return CURLE_OK; -bad: - curlx_free(newstr); - return CURLE_BAD_CONTENT_ENCODING; -} - -static CURLcode base64_encode(const char *table64, - uint8_t padbyte, - const uint8_t *inputbuff, size_t insize, - char **outptr, size_t *outlen) -{ - char *output; - char *base64data; - const unsigned char *in = (const unsigned char *)inputbuff; - - *outptr = NULL; - *outlen = 0; - - if(!insize) - return CURLE_OK; - - /* safety precaution */ - DEBUGASSERT(insize <= CURL_MAX_BASE64_INPUT); - if(insize > CURL_MAX_BASE64_INPUT) - return CURLE_TOO_LARGE; - - base64data = output = curlx_malloc(((insize + 2) / 3 * 4) + 1); - if(!output) - return CURLE_OUT_OF_MEMORY; - - while(insize >= 3) { - *output++ = table64[in[0] >> 2]; - *output++ = table64[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *output++ = table64[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)]; - *output++ = table64[in[2] & 0x3F]; - insize -= 3; - in += 3; - } - if(insize) { - /* this is only one or two bytes now */ - *output++ = table64[in[0] >> 2]; - if(insize == 1) { - *output++ = table64[((in[0] & 0x03) << 4)]; - if(padbyte) { - *output++ = padbyte; - *output++ = padbyte; - } - } - else { - /* insize == 2 */ - *output++ = table64[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)]; - *output++ = table64[((in[1] & 0x0F) << 2)]; - if(padbyte) - *output++ = padbyte; - } - } - - /* Null-terminate */ - *output = '\0'; - - /* Return the pointer to the new data (allocated memory) */ - *outptr = base64data; - - /* Return the length of the new data */ - *outlen = (size_t)(output - base64data); - - return CURLE_OK; -} - -/* - * curlx_base64_encode() - * - * Given a pointer to an input buffer and an input size, encode it and - * return a pointer in *outptr to a newly allocated memory area holding - * encoded data. Size of encoded data is returned in variable pointed by - * outlen. - * - * Returns CURLE_OK on success, otherwise specific error code. Function - * output shall not be considered valid unless CURLE_OK is returned. - * - * @unittest: 1302 - */ -CURLcode curlx_base64_encode(const uint8_t *inputbuff, size_t insize, - char **outptr, size_t *outlen) -{ - return base64_encode(curlx_base64encdec, '=', - inputbuff, insize, outptr, outlen); -} - -/* - * curlx_base64url_encode() - * - * Given a pointer to an input buffer and an input size, encode it and - * return a pointer in *outptr to a newly allocated memory area holding - * encoded data. Size of encoded data is returned in variable pointed by - * outlen. - * - * Input length of 0 indicates input buffer holds a null-terminated string. - * - * Returns CURLE_OK on success, otherwise specific error code. Function - * output shall not be considered valid unless CURLE_OK is returned. - * - * @unittest: 1302 - */ -CURLcode curlx_base64url_encode(const uint8_t *inputbuff, size_t insize, - char **outptr, size_t *outlen) -{ - return base64_encode(base64url, 0, inputbuff, insize, outptr, outlen); -} diff --git a/vendor/curl/lib/curlx/base64.h b/vendor/curl/lib/curlx/base64.h deleted file mode 100644 index 2e7781482..000000000 --- a/vendor/curl/lib/curlx/base64.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_BASE64_H -#define HEADER_CURL_BASE64_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -CURLcode curlx_base64_encode(const uint8_t *inputbuff, size_t insize, - char **outptr, size_t *outlen); -CURLcode curlx_base64url_encode(const uint8_t *inputbuff, size_t insize, - char **outptr, size_t *outlen); -CURLcode curlx_base64_decode(const char *src, - uint8_t **outptr, size_t *outlen); - -extern const char curlx_base64encdec[]; - -/* maximum input length acceptable to base64 encode, here to catch and prevent - mistakes */ -#define CURL_MAX_BASE64_INPUT 16000000 - -#endif /* HEADER_CURL_BASE64_H */ diff --git a/vendor/curl/lib/curlx/basename.c b/vendor/curl/lib/curlx/basename.c deleted file mode 100644 index d2fd160ff..000000000 --- a/vendor/curl/lib/curlx/basename.c +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef HAVE_BASENAME - -#include "curlx/basename.h" - -/* - (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 - Edition) - - The basename() function shall take the pathname pointed to by path and - return a pointer to the final component of the pathname, deleting any - trailing '/' characters. - - If the string pointed to by path consists entirely of the '/' character, - basename() shall return a pointer to the string "/". If the string pointed - to by path is exactly "//", it is implementation-defined whether '/' or "//" - is returned. - - If path is a null pointer or points to an empty string, basename() shall - return a pointer to the string ".". - - The basename() function may modify the string pointed to by path, and may - return a pointer to static storage that may then be overwritten by a - subsequent call to basename(). - - The basename() function need not be reentrant. A function that is not - required to be reentrant is not required to be thread-safe. - -*/ -char *curlx_basename(char *path) -{ - /* Ignore all the details above for now and make a quick and simple - implementation here */ - char *s1; - char *s2; - - s1 = strrchr(path, '/'); - s2 = strrchr(path, '\\'); - - if(s1 && s2) - path = ((s1 > s2) ? s1 : s2) + 1; - else if(s1) - path = s1 + 1; - else if(s2) - path = s2 + 1; - - return path; -} - -#endif /* !HAVE_BASENAME */ diff --git a/vendor/curl/lib/curlx/basename.h b/vendor/curl/lib/curlx/basename.h deleted file mode 100644 index fb79fed80..000000000 --- a/vendor/curl/lib/curlx/basename.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURLX_BASENAME_H -#define HEADER_CURLX_BASENAME_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef HAVE_BASENAME -char *curlx_basename(char *path); -#else - -#ifdef HAVE_LIBGEN_H -#include -#endif - -#define curlx_basename(x) basename(x) -#endif /* !HAVE_BASENAME */ - -#endif /* HEADER_CURLX_BASENAME_H */ diff --git a/vendor/curl/lib/curlx/dynbuf.c b/vendor/curl/lib/curlx/dynbuf.c deleted file mode 100644 index 1e5ea5177..000000000 --- a/vendor/curl/lib/curlx/dynbuf.c +++ /dev/null @@ -1,292 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/dynbuf.h" -#include "curl_printf.h" - -#define MIN_FIRST_ALLOC 32 - -#ifdef DEBUGBUILD -#define DYNINIT 0xbee51da /* random pattern */ -#endif - -/* - * Init a dynbuf struct. - */ -void curlx_dyn_init(struct dynbuf *s, size_t toobig) -{ - DEBUGASSERT(s); - DEBUGASSERT(toobig); - DEBUGASSERT(toobig <= MAX_DYNBUF_SIZE); /* catch crazy mistakes */ - s->bufr = NULL; - s->leng = 0; - s->allc = 0; - s->toobig = toobig; -#ifdef DEBUGBUILD - s->init = DYNINIT; -#endif -} - -/* - * free the buffer and re-init the necessary fields. It does not touch the - * 'init' field and thus this buffer can be reused to add data to again. - */ -void curlx_dyn_free(struct dynbuf *s) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - curlx_safefree(s->bufr); - s->leng = s->allc = 0; -} - -/* - * Store/append an chunk of memory to the dynbuf. - */ -static CURLcode dyn_nappend(struct dynbuf *s, - const unsigned char *mem, size_t len) -{ - size_t idx = s->leng; - size_t a = s->allc; - size_t fit = len + idx + 1; /* new string + old string + zero byte */ - - /* try to detect if there is rubbish in the struct */ - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(s->toobig); - DEBUGASSERT(idx < s->toobig); - DEBUGASSERT(!s->leng || s->bufr); - DEBUGASSERT(a <= s->toobig); - DEBUGASSERT(!len || mem); - - if(fit > s->toobig) { - curlx_dyn_free(s); - return CURLE_TOO_LARGE; - } - else if(!a) { - DEBUGASSERT(!idx); - /* first invoke */ - if(MIN_FIRST_ALLOC > s->toobig) - a = s->toobig; - else if(fit < MIN_FIRST_ALLOC) - a = MIN_FIRST_ALLOC; - else - a = fit; - } - else { - while(a < fit) - a *= 2; - if(a > s->toobig) - /* no point in allocating a larger buffer than this is allowed to use */ - a = s->toobig; - } - - if(a != s->allc) { - void *p = curlx_realloc(s->bufr, a); - if(!p) { - curlx_dyn_free(s); - return CURLE_OUT_OF_MEMORY; - } - s->bufr = p; - s->allc = a; - } - - if(len) - memcpy(&s->bufr[idx], mem, len); - s->leng = idx + len; - s->bufr[s->leng] = 0; - return CURLE_OK; -} - -/* - * Clears the string, keeps the allocation. This can also be called on a - * buffer that already was freed. - */ -void curlx_dyn_reset(struct dynbuf *s) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - if(s->leng) - s->bufr[0] = 0; - s->leng = 0; -} - -/* - * Specify the size of the tail to keep (number of bytes from the end of the - * buffer). The rest is dropped. - */ -CURLcode curlx_dyn_tail(struct dynbuf *s, size_t trail) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - if(trail > s->leng) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if(trail == s->leng) - return CURLE_OK; - else if(!trail) { - curlx_dyn_reset(s); - } - else { - memmove(&s->bufr[0], &s->bufr[s->leng - trail], trail); - s->leng = trail; - s->bufr[s->leng] = 0; - } - return CURLE_OK; -} - -/* - * Appends a buffer with length. - */ -CURLcode curlx_dyn_addn(struct dynbuf *s, const void *mem, size_t len) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - return dyn_nappend(s, mem, len); -} - -/* - * Append a null-terminated string at the end. - */ -CURLcode curlx_dyn_add(struct dynbuf *s, const char *str) -{ - size_t n; - DEBUGASSERT(str); - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - n = strlen(str); - return dyn_nappend(s, (const unsigned char *)str, n); -} - -/* - * Append a string vprintf()-style - */ -CURLcode curlx_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap) -{ -#ifdef BUILDING_LIBCURL - int rc; - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - DEBUGASSERT(fmt); - rc = curlx_dyn_vprintf(s, fmt, ap); - - if(!rc) - return CURLE_OK; - else if(rc == MERR_TOO_LARGE) - return CURLE_TOO_LARGE; - return CURLE_OUT_OF_MEMORY; -#else - char *str; - str = curl_mvaprintf(fmt, ap); /* this allocs a new string to append */ - - if(str) { - CURLcode result = dyn_nappend(s, (const unsigned char *)str, strlen(str)); - curl_free(str); - return result; - } - /* If we failed, we cleanup the whole buffer and return error */ - curlx_dyn_free(s); - return CURLE_OUT_OF_MEMORY; -#endif -} - -/* - * Append a string printf()-style - */ -CURLcode curlx_dyn_addf(struct dynbuf *s, const char *fmt, ...) -{ - CURLcode result; - va_list ap; - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - DEBUGASSERT(strcmp(fmt, "%s")); /* use curlx_dyn_add instead */ - va_start(ap, fmt); - result = curlx_dyn_vaddf(s, fmt, ap); - va_end(ap); - return result; -} - -/* - * Returns a pointer to the buffer. - */ -char *curlx_dyn_ptr(const struct dynbuf *s) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - return s->bufr; -} - -char *curlx_dyn_take(struct dynbuf *s, size_t *plen) -{ - char *ptr = s->bufr; - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - *plen = s->leng; - s->bufr = NULL; - s->leng = 0; - s->allc = 0; - return ptr; -} - -/* - * Returns an unsigned pointer to the buffer. - */ -unsigned char *curlx_dyn_uptr(const struct dynbuf *s) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - return (unsigned char *)s->bufr; -} - -/* - * Returns the length of the buffer. - */ -size_t curlx_dyn_len(const struct dynbuf *s) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - return s->leng; -} - -/* - * Set a new (smaller) length. - */ -CURLcode curlx_dyn_setlen(struct dynbuf *s, size_t set) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->init == DYNINIT); - DEBUGASSERT(!s->leng || s->bufr); - if(set > s->leng) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->leng = set; - s->bufr[s->leng] = 0; - return CURLE_OK; -} diff --git a/vendor/curl/lib/curlx/dynbuf.h b/vendor/curl/lib/curlx/dynbuf.h deleted file mode 100644 index 0cf4a2c57..000000000 --- a/vendor/curl/lib/curlx/dynbuf.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef HEADER_CURL_DYNBUF_H -#define HEADER_CURL_DYNBUF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -struct dynbuf { - char *bufr; /* point to a null-terminated allocated buffer */ - size_t leng; /* number of bytes *EXCLUDING* the null-terminator */ - size_t allc; /* size of the current allocation */ - size_t toobig; /* size limit for the buffer */ -#ifdef DEBUGBUILD - int init; /* detect API usage mistakes */ -#endif -}; - -void curlx_dyn_init(struct dynbuf *s, size_t toobig); -void curlx_dyn_free(struct dynbuf *s); -CURLcode curlx_dyn_addn(struct dynbuf *s, const void *mem, size_t len) - WARN_UNUSED_RESULT; -CURLcode curlx_dyn_add(struct dynbuf *s, const char *str) - WARN_UNUSED_RESULT; -CURLcode curlx_dyn_addf(struct dynbuf *s, const char *fmt, ...) - WARN_UNUSED_RESULT CURL_PRINTF(2, 3); -CURLcode curlx_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap) - WARN_UNUSED_RESULT CURL_PRINTF(2, 0); -void curlx_dyn_reset(struct dynbuf *s); -CURLcode curlx_dyn_tail(struct dynbuf *s, size_t trail); -CURLcode curlx_dyn_setlen(struct dynbuf *s, size_t set); -char *curlx_dyn_ptr(const struct dynbuf *s); -unsigned char *curlx_dyn_uptr(const struct dynbuf *s); -size_t curlx_dyn_len(const struct dynbuf *s); - -/* returns 0 on success, -1 on error */ -/* The implementation of this function exists in mprintf.c */ -int curlx_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list args); - -/* Take the buffer out of the dynbuf. Caller has ownership and - * dynbuf resets to initial state. */ -char *curlx_dyn_take(struct dynbuf *s, size_t *plen); - -/* Dynamic buffer max sizes */ -#define MAX_DYNBUF_SIZE (SIZE_MAX / 2) - -#define DYN_DOH_RESPONSE 3000 -#define DYN_DOH_CNAME 256 -#define DYN_PAUSE_BUFFER (64 * 1024 * 1024) -#define DYN_HAXPROXY 2048 -#define DYN_HTTP_REQUEST (1024 * 1024) -#define DYN_APRINTF 8000000 -#define DYN_RTSP_REQ_HEADER (64 * 1024) -#define DYN_TRAILERS (64 * 1024) -#define DYN_PROXY_CONNECT_HEADERS 16384 -#define DYN_QLOG_NAME 1024 -#define DYN_H1_TRAILER 4096 -#define DYN_PINGPPONG_CMD (64 * 1024) -#define DYN_IMAP_CMD (64 * 1024) -#define DYN_MQTT_RECV (64 * 1024) -#define DYN_MQTT_SEND 0xFFFFFFF -#define DYN_CRLFILE_SIZE (400 * 1024 * 1024) /* 400MiB */ -#define DYN_CERTFILE_SIZE (100 * 1024) /* 100KiB */ -#define DYN_KEYFILE_SIZE (100 * 1024) /* 100KiB */ -#endif diff --git a/vendor/curl/lib/curlx/fopen.c b/vendor/curl/lib/curlx/fopen.c deleted file mode 100644 index 673301046..000000000 --- a/vendor/curl/lib/curlx/fopen.c +++ /dev/null @@ -1,508 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/fopen.h" - -int curlx_fseek(void *stream, curl_off_t offset, int whence) -{ -#ifdef _WIN32 - return _fseeki64(stream, (__int64)offset, whence); -#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO) - return fseeko(stream, (off_t)offset, whence); -#else - if(offset > LONG_MAX) - return -1; - return fseek(stream, (long)offset, whence); -#endif -} - -#ifdef _WIN32 - -#include /* for _SH_DENYNO */ - -#include "curlx/multibyte.h" -#include "curlx/timeval.h" - -#ifdef CURL_MEMDEBUG -/* - * Use system allocators to avoid infinite recursion when called by curl's - * memory tracker memdebug functions. - */ -#define CURLX_MALLOC(x) malloc(x) -#define CURLX_FREE(x) free(x) -#else -#define CURLX_MALLOC(x) curlx_malloc(x) -#define CURLX_FREE(x) curlx_free(x) -#endif - -#ifdef _UNICODE -static wchar_t *fn_convert_UTF8_to_wchar(const char *str_utf8) -{ - wchar_t *str_w = NULL; - - if(str_utf8) { - int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - str_utf8, -1, NULL, 0); - if(str_w_len > 0) { - str_w = CURLX_MALLOC(str_w_len * sizeof(wchar_t)); - if(str_w) { - if(MultiByteToWideChar(CP_UTF8, 0, - str_utf8, -1, str_w, str_w_len) == 0) { - CURLX_FREE(str_w); - return NULL; - } - } - } - } - return str_w; -} -#endif - -/* declare GetFullPathNameW for mingw-w64 UWP builds targeting old windows */ -#if defined(CURL_WINDOWS_UWP) && defined(__MINGW32__) && \ - (_WIN32_WINNT < _WIN32_WINNT_WIN10) -WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR *); -#endif - -/* Fix excessive paths (paths that exceed MAX_PATH length of 260). - * - * This is a helper function to fix paths that would exceed the MAX_PATH - * limitation check done by Windows APIs. It does so by normalizing the passed - * in filename or path 'in' to its full canonical path, and if that path is - * longer than MAX_PATH then setting 'out' to "\\?\" prefix + that full path. - * - * For example 'in' filename255chars in current directory C:\foo\bar is - * fixed as \\?\C:\foo\bar\filename255chars for 'out' which tells Windows - * it is ok to access that filename even though the actual full path is longer - * than 260 chars. - * - * For non-Unicode builds this function may fail sometimes because only the - * Unicode versions of some Windows API functions can access paths longer than - * MAX_PATH, for example GetFullPathNameW which is used in this function. When - * the full path is then converted from Unicode to multibyte that fails if any - * directories in the path contain characters not in the current codepage. - */ -static bool fix_excessive_path(const TCHAR *in, TCHAR **out) -{ - size_t needed, count; - const wchar_t *in_w; - wchar_t *fbuf = NULL; - - /* MS documented "approximate" limit for the maximum path length */ - const size_t max_path_len = 32767; - -#ifndef _UNICODE - wchar_t *ibuf = NULL; - char *obuf = NULL; -#endif - - *out = NULL; - - /* skip paths already normalized */ - if(!_tcsncmp(in, _T("\\\\?\\"), 4)) - goto cleanup; - -#ifndef _UNICODE - /* convert multibyte input to unicode */ - if(mbstowcs_s(&needed, NULL, 0, in, 0)) - goto cleanup; - if(!needed || needed >= max_path_len) - goto cleanup; - ibuf = CURLX_MALLOC(needed * sizeof(wchar_t)); - if(!ibuf) - goto cleanup; - if(mbstowcs_s(&count, ibuf, needed, in, needed - 1)) - goto cleanup; - if(count != needed) - goto cleanup; - in_w = ibuf; -#else - in_w = in; -#endif - - /* GetFullPathNameW returns the normalized full path in unicode. It converts - forward slashes to backslashes, processes .. to remove directory segments, - etc. Unlike GetFullPathNameA it can process paths that exceed MAX_PATH. */ - needed = (size_t)GetFullPathNameW(in_w, 0, NULL, NULL); - if(!needed || needed > max_path_len) - goto cleanup; - /* skip paths that are not excessive and do not need modification */ - if(needed <= MAX_PATH) - goto cleanup; - fbuf = CURLX_MALLOC(needed * sizeof(wchar_t)); - if(!fbuf) - goto cleanup; - count = (size_t)GetFullPathNameW(in_w, (DWORD)needed, fbuf, NULL); - if(!count || count >= needed) - goto cleanup; - - /* prepend \\?\ or \\?\UNC\ to the excessively long path. - * - * c:\longpath ---> \\?\c:\longpath - * \\.\c:\longpath ---> \\?\c:\longpath - * \\?\c:\longpath ---> \\?\c:\longpath (unchanged) - * \\server\c$\longpath ---> \\?\UNC\server\c$\longpath - * - * https://learn.microsoft.com/dotnet/standard/io/file-path-formats - */ - if(!wcsncmp(fbuf, L"\\\\?\\", 4)) - ; /* do nothing */ - else if(!wcsncmp(fbuf, L"\\\\.\\", 4)) - fbuf[2] = '?'; - else if(!wcsncmp(fbuf, L"\\\\.", 3) || !wcsncmp(fbuf, L"\\\\?", 3)) { - /* Unexpected, not UNC. The formatting doc does not allow this AFAICT. */ - goto cleanup; - } - else { - wchar_t *temp; - - if(!wcsncmp(fbuf, L"\\\\", 2)) { - /* "\\?\UNC\" + full path without "\\" + null */ - needed = 8 + (count - 2) + 1; - if(needed > max_path_len) - goto cleanup; - - temp = CURLX_MALLOC(needed * sizeof(wchar_t)); - if(!temp) - goto cleanup; - - if(wcsncpy_s(temp, needed, L"\\\\?\\UNC\\", 8)) { - CURLX_FREE(temp); - goto cleanup; - } - if(wcscpy_s(temp + 8, needed, fbuf + 2)) { - CURLX_FREE(temp); - goto cleanup; - } - } - else { - /* "\\?\" + full path + null */ - needed = 4 + count + 1; - if(needed > max_path_len) - goto cleanup; - - temp = CURLX_MALLOC(needed * sizeof(wchar_t)); - if(!temp) - goto cleanup; - - if(wcsncpy_s(temp, needed, L"\\\\?\\", 4)) { - CURLX_FREE(temp); - goto cleanup; - } - if(wcscpy_s(temp + 4, needed, fbuf)) { - CURLX_FREE(temp); - goto cleanup; - } - } - - CURLX_FREE(fbuf); - fbuf = temp; - } - -#ifndef _UNICODE - /* convert unicode full path to multibyte output */ - if(wcstombs_s(&needed, NULL, 0, fbuf, 0)) - goto cleanup; - if(!needed || needed >= max_path_len) - goto cleanup; - obuf = CURLX_MALLOC(needed); - if(!obuf) - goto cleanup; - if(wcstombs_s(&count, obuf, needed, fbuf, needed - 1)) - goto cleanup; - if(count != needed) - goto cleanup; - *out = obuf; - obuf = NULL; -#else - *out = fbuf; - fbuf = NULL; -#endif - -cleanup: - CURLX_FREE(fbuf); -#ifndef _UNICODE - CURLX_FREE(ibuf); - CURLX_FREE(obuf); -#endif - return *out ? true : false; -} - -#ifndef CURL_WINDOWS_UWP -HANDLE curlx_CreateFile(const char *filename, - DWORD dwDesiredAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile) -{ - HANDLE handle = INVALID_HANDLE_VALUE; - -#ifdef UNICODE - TCHAR *filename_t = curlx_convert_UTF8_to_wchar(filename); -#else - const TCHAR *filename_t = filename; -#endif - - if(filename_t) { - TCHAR *fixed = NULL; - const TCHAR *target = NULL; - - if(fix_excessive_path(filename_t, &fixed)) - target = fixed; - else - target = filename_t; - /* !checksrc! disable BANNEDFUNC 1 */ - handle = CreateFile(target, - dwDesiredAccess, - dwShareMode, - lpSecurityAttributes, - dwCreationDisposition, - dwFlagsAndAttributes, - hTemplateFile); - CURLX_FREE(fixed); -#ifdef UNICODE - curlx_free(filename_t); -#endif - } - - return handle; -} -#endif /* !CURL_WINDOWS_UWP */ - -int curlx_win32_open(const char *filename, int oflag, ...) -{ - int pmode = 0; - int res = -1; - TCHAR *fixed = NULL; - const TCHAR *target = NULL; - -#ifdef _UNICODE - wchar_t *filename_w = fn_convert_UTF8_to_wchar(filename); -#endif - - va_list param; - va_start(param, oflag); - if(oflag & O_CREAT) - pmode = va_arg(param, int); - va_end(param); - -#ifdef _UNICODE - if(filename_w) { - if(fix_excessive_path(filename_w, &fixed)) - target = fixed; - else - target = filename_w; - errno = _wsopen_s(&res, target, oflag, _SH_DENYNO, pmode); - CURLX_FREE(filename_w); - } - else - /* !checksrc! disable ERRNOVAR 1 */ - errno = EINVAL; -#else - if(fix_excessive_path(filename, &fixed)) - target = fixed; - else - target = filename; - errno = _sopen_s(&res, target, oflag, _SH_DENYNO, pmode); -#endif - - CURLX_FREE(fixed); - return res; -} - -FILE *curlx_win32_fopen(const char *filename, const char *mode) -{ - FILE *file = NULL; - TCHAR *fixed = NULL; - const TCHAR *target = NULL; - -#ifdef _UNICODE - wchar_t *filename_w = fn_convert_UTF8_to_wchar(filename); - wchar_t *mode_w = fn_convert_UTF8_to_wchar(mode); - if(filename_w && mode_w) { - if(fix_excessive_path(filename_w, &fixed)) - target = fixed; - else - target = filename_w; - file = _wfsopen(target, mode_w, _SH_DENYNO); - } - else - /* !checksrc! disable ERRNOVAR 1 */ - errno = EINVAL; - CURLX_FREE(filename_w); - CURLX_FREE(mode_w); -#else - if(fix_excessive_path(filename, &fixed)) - target = fixed; - else - target = filename; - file = _fsopen(target, mode, _SH_DENYNO); -#endif - - CURLX_FREE(fixed); - return file; -} - -#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR < 5) -_CRTIMP errno_t __cdecl freopen_s(FILE **file, const char *filename, - const char *mode, FILE *stream); -#endif - -FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp) -{ - FILE *file = NULL; - TCHAR *fixed = NULL; - const TCHAR *target = NULL; - -#ifdef _UNICODE - wchar_t *filename_w = fn_convert_UTF8_to_wchar(filename); - wchar_t *mode_w = fn_convert_UTF8_to_wchar(mode); - if(filename_w && mode_w) { - if(fix_excessive_path(filename_w, &fixed)) - target = fixed; - else - target = filename_w; - errno = _wfreopen_s(&file, target, mode_w, fp); - } - else - /* !checksrc! disable ERRNOVAR 1 */ - errno = EINVAL; - CURLX_FREE(filename_w); - CURLX_FREE(mode_w); -#else - if(fix_excessive_path(filename, &fixed)) - target = fixed; - else - target = filename; - errno = freopen_s(&file, target, mode, fp); -#endif - - CURLX_FREE(fixed); - return file; -} - -int curlx_win32_stat(const char *path, curlx_struct_stat *buffer) -{ - int res = -1; - TCHAR *fixed = NULL; - const TCHAR *target = NULL; - -#ifdef _UNICODE - wchar_t *path_w = curlx_convert_UTF8_to_wchar(path); - if(path_w) { - if(fix_excessive_path(path_w, &fixed)) - target = fixed; - else - target = path_w; - res = _wstati64(target, buffer); - curlx_free(path_w); - } - else - /* !checksrc! disable ERRNOVAR 1 */ - errno = EINVAL; -#else - if(fix_excessive_path(path, &fixed)) - target = fixed; - else - target = path; - res = _stati64(target, buffer); -#endif - - CURLX_FREE(fixed); - return res; -} - -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_COOKIES) || \ - !defined(CURL_DISABLE_ALTSVC) -/* rename() on Windows does not overwrite, so we cannot use it here. - MoveFileEx() does overwrite and is usually atomic but fails when there are - open handles to the file. */ -int curlx_win32_rename(const char *oldpath, const char *newpath) -{ - int res = -1; /* fail */ - -#ifdef UNICODE - TCHAR *tchar_oldpath = curlx_convert_UTF8_to_wchar(oldpath); - TCHAR *tchar_newpath = curlx_convert_UTF8_to_wchar(newpath); -#else - const TCHAR *tchar_oldpath = oldpath; - const TCHAR *tchar_newpath = newpath; -#endif - - if(tchar_oldpath && tchar_newpath) { - const int max_wait_ms = 1000; - struct curltime start; - - TCHAR *oldpath_fixed = NULL; - TCHAR *newpath_fixed = NULL; - const TCHAR *target_oldpath; - const TCHAR *target_newpath; - - if(fix_excessive_path(tchar_oldpath, &oldpath_fixed)) - target_oldpath = oldpath_fixed; - else - target_oldpath = tchar_oldpath; - - if(fix_excessive_path(tchar_newpath, &newpath_fixed)) - target_newpath = newpath_fixed; - else - target_newpath = tchar_newpath; - - start = curlx_now(); - - for(;;) { - timediff_t diff; - /* !checksrc! disable BANNEDFUNC 1 */ - if(MoveFileEx(target_oldpath, target_newpath, - MOVEFILE_REPLACE_EXISTING)) { - res = 0; /* success */ - break; - } - diff = curlx_timediff_ms(curlx_now(), start); - if(diff < 0 || diff > max_wait_ms) { - break; - } - Sleep(1); - } - - CURLX_FREE(oldpath_fixed); - CURLX_FREE(newpath_fixed); - } - -#ifdef UNICODE - curlx_free(tchar_oldpath); - curlx_free(tchar_newpath); -#endif - - return res; -} -#endif - -#undef CURLX_MALLOC -#undef CURLX_FREE - -#endif /* _WIN32 */ diff --git a/vendor/curl/lib/curlx/fopen.h b/vendor/curl/lib/curlx/fopen.h deleted file mode 100644 index b64fbf651..000000000 --- a/vendor/curl/lib/curlx/fopen.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef HEADER_CURLX_FOPEN_H -#define HEADER_CURLX_FOPEN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/multibyte.h" - -#ifdef HAVE_FCNTL_H -#include /* for open() and attributes */ -#endif - -int curlx_fseek(void *stream, curl_off_t offset, int whence); - -#ifdef _WIN32 -#include /* for _fstati64(), struct _stati64 */ -#ifndef CURL_WINDOWS_UWP -HANDLE curlx_CreateFile(const char *filename, - DWORD dwDesiredAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile); -#endif /* !CURL_WINDOWS_UWP */ -#define curlx_fstat _fstati64 -#define curlx_struct_stat struct _stati64 -FILE *curlx_win32_fopen(const char *filename, const char *mode); -FILE *curlx_win32_freopen(const char *filename, const char *mode, FILE *fp); -int curlx_win32_stat(const char *path, curlx_struct_stat *buffer); -int curlx_win32_open(const char *filename, int oflag, ...); -int curlx_win32_rename(const char *oldpath, const char *newpath); -#define CURLX_FOPEN_LOW curlx_win32_fopen -#define CURLX_FREOPEN_LOW curlx_win32_freopen -#define CURLX_FDOPEN_LOW _fdopen -#define curlx_stat curlx_win32_stat -#define curlx_open curlx_win32_open -#define curlx_close _close -#define curlx_rename curlx_win32_rename -#else -#define curlx_fstat fstat -#define curlx_struct_stat struct stat -#define CURLX_FOPEN_LOW fopen -#define CURLX_FREOPEN_LOW freopen -#define CURLX_FDOPEN_LOW fdopen -#define curlx_stat stat -#define curlx_open open -#define curlx_close close -#define curlx_rename rename -#endif - -#ifdef CURL_MEMDEBUG -#define curlx_fopen(file, mode) curl_dbg_fopen(file, mode, __LINE__, __FILE__) -#define curlx_freopen(file, mode, fh) \ - curl_dbg_freopen(file, mode, fh, __LINE__, __FILE__) -#define curlx_fdopen(file, mode) \ - curl_dbg_fdopen(file, mode, __LINE__, __FILE__) -#define curlx_fclose(file) curl_dbg_fclose(file, __LINE__, __FILE__) -#else -#define curlx_fopen CURLX_FOPEN_LOW -#define curlx_freopen CURLX_FREOPEN_LOW -#define curlx_fdopen CURLX_FDOPEN_LOW -#define curlx_fclose fclose -#endif - -#endif /* HEADER_CURLX_FOPEN_H */ diff --git a/vendor/curl/lib/curlx/inet_ntop.c b/vendor/curl/lib/curlx/inet_ntop.c deleted file mode 100644 index 803b9887a..000000000 --- a/vendor/curl/lib/curlx/inet_ntop.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 1996-2022 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * SPDX-License-Identifier: ISC - */ -#include "curl_setup.h" - -#ifndef HAVE_INET_NTOP - -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "curlx/inet_ntop.h" -#include "curlx/snprintf.h" -#include "curlx/strcopy.h" - -#define IN6ADDRSZ 16 -/* #define INADDRSZ 4 */ -#define INT16SZ 2 - -/* - * If USE_IPV6 is disabled, we still want to parse IPv6 addresses, so make - * sure we have _some_ value for AF_INET6 without polluting our fake value - * everywhere. - */ -#if !defined(USE_IPV6) && !defined(AF_INET6) -#define AF_INET6 (AF_INET + 1) -#endif - -/* - * Format an IPv4 address, more or less like inet_ntop(). - * - * Returns `dst' (as a const) - * Note: - * - uses no static variables - * - takes an unsigned char* not an in_addr as input - */ -static char *inet_ntop4(const unsigned char *src, char *dst, size_t size) -{ - char tmp[sizeof("255.255.255.255")]; - size_t len; - - DEBUGASSERT(size >= 16); - - /* this snprintf() does not overflow the buffer. */ - SNPRINTF(tmp, sizeof(tmp), "%d.%d.%d.%d", - ((int)((unsigned char)src[0])) & 0xff, - ((int)((unsigned char)src[1])) & 0xff, - ((int)((unsigned char)src[2])) & 0xff, - ((int)((unsigned char)src[3])) & 0xff); - - len = strlen(tmp); - if(len == 0 || len >= size) { -#ifdef USE_WINSOCK - errno = WSAEINVAL; -#else - errno = ENOSPC; -#endif - return NULL; - } - curlx_strcopy(dst, size, tmp, len); - return dst; -} - -/* - * Convert IPv6 binary address into presentation (printable) format. - */ -static char *inet_ntop6(const unsigned char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - char *tp; - struct { - int base; - int len; - } best, cur; - unsigned int words[IN6ADDRSZ / INT16SZ]; - int i; - - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof(words)); - for(i = 0; i < IN6ADDRSZ; i++) - words[i / 2] |= ((unsigned int)src[i] << ((1 - (i % 2)) << 3)); - - best.base = -1; - cur.base = -1; - best.len = 0; - cur.len = 0; - - for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { - if(words[i] == 0) { - if(cur.base == -1) { - cur.base = i; - cur.len = 1; - } - else - cur.len++; - } - else if(cur.base != -1) { - if(best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if(best.base != -1 && best.len < 2) - best.base = -1; - /* Format the result. */ - tp = tmp; - for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { - /* Are we inside the best run of 0x00's? */ - if(best.base != -1 && i >= best.base && i < (best.base + best.len)) { - if(i == best.base) - *tp++ = ':'; - continue; - } - - /* Are we following an initial run of 0x00s or any real hex? - */ - if(i) - *tp++ = ':'; - - /* Is this address an encapsulated IPv4? - */ - if(i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp))) { - return NULL; - } - tp += strlen(tp); - break; - } - else { - /* Lower-case digits. Cannot use the set from mprintf.c since this - needs to work as a curlx function */ - static const unsigned char ldigits[] = "0123456789abcdef"; - - unsigned int w = words[i]; - /* output lowercase 16-bit hex number but ignore leading zeroes */ - if(w & 0xf000) - *tp++ = ldigits[(w & 0xf000) >> 12]; - if(w & 0xff00) - *tp++ = ldigits[(w & 0x0f00) >> 8]; - if(w & 0xfff0) - *tp++ = ldigits[(w & 0x00f0) >> 4]; - *tp++ = ldigits[(w & 0x000f)]; - } - } - - /* Was it a trailing run of 0x00's? - */ - if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - - /* Check for overflow, copy, and we are done. */ - if((size_t)(tp - tmp) >= size) { -#ifdef USE_WINSOCK - errno = WSAEINVAL; -#else - errno = ENOSPC; -#endif - return NULL; - } - - curlx_strcopy(dst, size, tmp, tp - tmp); - return dst; -} - -/* - * Convert a network format address to presentation format. - * - * Returns pointer to presentation format address (`buf'). - * Returns NULL on error and errno set with the specific - * error, EAFNOSUPPORT or ENOSPC. - * - * On Windows we store the error in the thread errno, not in the Winsock error - * code. This is to avoid losing the actual last Winsock error. When this - * function returns NULL, check errno not SOCKERRNO. - */ -char *curlx_inet_ntop(int af, const void *src, char *buf, size_t size) -{ - switch(af) { - case AF_INET: - return inet_ntop4((const unsigned char *)src, buf, size); - case AF_INET6: - return inet_ntop6((const unsigned char *)src, buf, size); - default: - errno = SOCKEAFNOSUPPORT; - return NULL; - } -} -#endif /* HAVE_INET_NTOP */ diff --git a/vendor/curl/lib/curlx/inet_ntop.h b/vendor/curl/lib/curlx/inet_ntop.h deleted file mode 100644 index ba8299fe4..000000000 --- a/vendor/curl/lib/curlx/inet_ntop.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef HEADER_CURL_INET_NTOP_H -#define HEADER_CURL_INET_NTOP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_INET_NTOP -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifndef _WIN32 -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __AMIGA__ -#define curlx_inet_ntop(af, src, buf, size) \ - (char *)inet_ntop(af, CURL_UNCONST(src), (unsigned char *)(buf), \ - (curl_socklen_t)(size)) -#else -#define curlx_inet_ntop(af, src, buf, size) \ - inet_ntop(af, src, buf, (curl_socklen_t)(size)) -#endif -#else -char *curlx_inet_ntop(int af, const void *src, char *buf, size_t size); -#endif /* HAVE_INET_NTOP */ - -#endif /* HEADER_CURL_INET_NTOP_H */ diff --git a/vendor/curl/lib/curlx/inet_pton.c b/vendor/curl/lib/curlx/inet_pton.c deleted file mode 100644 index 7994f258f..000000000 --- a/vendor/curl/lib/curlx/inet_pton.c +++ /dev/null @@ -1,221 +0,0 @@ -/* This is from the BIND 4.9.4 release, modified to compile by itself */ - -/* Copyright (c) Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * SPDX-License-Identifier: ISC - */ -#include "curl_setup.h" - -#ifndef HAVE_INET_PTON - -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "curlx/inet_pton.h" -#include "curlx/strparse.h" - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -/* - * If USE_IPV6 is disabled, we still want to parse IPv6 addresses, so make - * sure we have _some_ value for AF_INET6 without polluting our fake value - * everywhere. - */ -#if !defined(USE_IPV6) && !defined(AF_INET6) -#define AF_INET6 (AF_INET + 1) -#endif - -/* - * WARNING: Do not even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -/* int inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it is returning 1. - * author: - * Paul Vixie, 1996. - */ -static int inet_pton4(const char *src, unsigned char *dst) -{ - int saw_digit, octets, ch; - unsigned char tmp[INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - tp = tmp; - *tp = 0; - while((ch = (unsigned char)*src++) != '\0') { - if(ISDIGIT(ch)) { - unsigned int val = (*tp * 10) + (ch - '0'); - - if(saw_digit && *tp == 0) - return 0; - if(val > 255) - return 0; - *tp = (unsigned char)val; - if(!saw_digit) { - if(++octets > 4) - return 0; - saw_digit = 1; - } - } - else if(ch == '.' && saw_digit) { - if(octets == 4) - return 0; - *++tp = 0; - saw_digit = 0; - } - else - return 0; - } - if(octets < 4) - return 0; - memcpy(dst, tmp, INADDRSZ); - return 1; -} - -/* int inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it is returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -static int inet_pton6(const char *src, unsigned char *dst) -{ - unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; - const char *curtok; - int ch, saw_xdigit; - size_t val; - - memset((tp = tmp), 0, IN6ADDRSZ); - endp = tp + IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if(*src == ':') - if(*++src != ':') - return 0; - curtok = src; - saw_xdigit = 0; - val = 0; - while((ch = (unsigned char)*src++) != '\0') { - if(ISXDIGIT(ch)) { - val <<= 4; - val |= curlx_hexval(ch); - if(++saw_xdigit > 4) - return 0; - continue; - } - if(ch == ':') { - curtok = src; - if(!saw_xdigit) { - if(colonp) - return 0; - colonp = tp; - continue; - } - if(tp + INT16SZ > endp) - return 0; - *tp++ = (unsigned char)((val >> 8) & 0xff); - *tp++ = (unsigned char)(val & 0xff); - saw_xdigit = 0; - val = 0; - continue; - } - if(ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return 0; - } - if(saw_xdigit) { - if(tp + INT16SZ > endp) - return 0; - *tp++ = (unsigned char)((val >> 8) & 0xff); - *tp++ = (unsigned char)(val & 0xff); - } - if(colonp) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we do the shift by hand. - */ - const ssize_t n = tp - colonp; - ssize_t i; - - if(tp == endp) - return 0; - for(i = 1; i <= n; i++) { - *(endp - i) = *(colonp + n - i); - *(colonp + n - i) = 0; - } - tp = endp; - } - if(tp != endp) - return 0; - memcpy(dst, tmp, IN6ADDRSZ); - return 1; -} - -/* int inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address was not valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * notice: - * On Windows we store the error in the thread errno, not - * in the Winsock error code. This is to avoid losing the - * actual last Winsock error. When this function returns - * -1, check errno not SOCKERRNO. - * author: - * Paul Vixie, 1996. - */ -int curlx_inet_pton(int af, const char *src, void *dst) -{ - switch(af) { - case AF_INET: - return inet_pton4(src, (unsigned char *)dst); - case AF_INET6: - return inet_pton6(src, (unsigned char *)dst); - default: - errno = SOCKEAFNOSUPPORT; - return -1; - } - /* NOTREACHED */ -} - -#endif /* HAVE_INET_PTON */ diff --git a/vendor/curl/lib/curlx/inet_pton.h b/vendor/curl/lib/curlx/inet_pton.h deleted file mode 100644 index 02ae7f226..000000000 --- a/vendor/curl/lib/curlx/inet_pton.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef HEADER_CURL_INET_PTON_H -#define HEADER_CURL_INET_PTON_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_INET_PTON -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifndef _WIN32 -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __AMIGA__ -#define curlx_inet_pton(x, y, z) \ - inet_pton(x, (unsigned char *)CURL_UNCONST(y), z) -#else -#define curlx_inet_pton(x, y, z) \ - inet_pton(x, y, z) -#endif -#else -int curlx_inet_pton(int af, const char *src, void *dst); -#endif /* HAVE_INET_PTON */ - -#endif /* HEADER_CURL_INET_PTON_H */ diff --git a/vendor/curl/lib/curlx/multibyte.c b/vendor/curl/lib/curlx/multibyte.c deleted file mode 100644 index 715d2b8dc..000000000 --- a/vendor/curl/lib/curlx/multibyte.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(_WIN32) && defined(UNICODE) - -#include "curlx/multibyte.h" - -/* - * MultiByte conversions using Windows kernel32 library. - */ - -wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8) -{ - wchar_t *str_w = NULL; - - if(str_utf8) { - int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - str_utf8, -1, NULL, 0); - if(str_w_len > 0) { - str_w = curlx_malloc(str_w_len * sizeof(wchar_t)); - if(str_w) { - if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w, - str_w_len) == 0) { - curlx_free(str_w); - return NULL; - } - } - } - } - - return str_w; -} - -char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w) -{ - char *str_utf8 = NULL; - - if(str_w) { - int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, - NULL, 0, NULL, NULL); - if(bytes > 0) { - str_utf8 = curlx_malloc(bytes); - if(str_utf8) { - if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes, - NULL, NULL) == 0) { - curlx_free(str_utf8); - return NULL; - } - } - } - } - - return str_utf8; -} - -#endif /* _WIN32 && UNICODE */ diff --git a/vendor/curl/lib/curlx/multibyte.h b/vendor/curl/lib/curlx/multibyte.h deleted file mode 100644 index 8863fb024..000000000 --- a/vendor/curl/lib/curlx/multibyte.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef HEADER_CURL_MULTIBYTE_H -#define HEADER_CURL_MULTIBYTE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef _WIN32 - -/* - * Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8() - * main purpose is to minimize the number of preprocessor conditional - * directives needed by code using these to differentiate Unicode from - * non-Unicode builds. - * - * In the case of a non-Unicode build the tchar strings are char strings that - * are duplicated via strdup and remain in whatever the passed in encoding is, - * which is assumed to be UTF-8 but may be other encoding. Therefore the - * significance of the conversion functions is primarily for Unicode builds. - */ - -#ifdef UNICODE - -/* MultiByte conversions using Windows kernel32 library. */ -wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8); -char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w); - -#define curlx_convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar(ptr) -#define curlx_convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8(ptr) - -typedef union { - unsigned short *tchar_ptr; - const unsigned short *const_tchar_ptr; - unsigned short *tbyte_ptr; - const unsigned short *const_tbyte_ptr; -} xcharp_u; - -#else /* !UNICODE */ - -#define curlx_convert_UTF8_to_tchar(ptr) curlx_strdup(ptr) -#define curlx_convert_tchar_to_UTF8(ptr) curlx_strdup(ptr) - -typedef union { - char *tchar_ptr; - const char *const_tchar_ptr; - unsigned char *tbyte_ptr; - const unsigned char *const_tbyte_ptr; -} xcharp_u; - -#endif /* UNICODE */ -#endif /* _WIN32 */ - -#endif /* HEADER_CURL_MULTIBYTE_H */ diff --git a/vendor/curl/lib/curlx/nonblock.c b/vendor/curl/lib/curlx/nonblock.c deleted file mode 100644 index 6f6458f2b..000000000 --- a/vendor/curl/lib/curlx/nonblock.c +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifdef __VMS -#include -#include -#endif - -#include "curlx/nonblock.h" - -/* - * curlx_nonblock() set the given socket to either blocking or non-blocking - * mode based on the 'nonblock' boolean argument. This function is highly - * portable. - */ -int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */) -{ -#ifdef HAVE_FCNTL_O_NONBLOCK - /* most recent Unix versions */ - int flags; - flags = sfcntl(sockfd, F_GETFL, 0); - if(flags < 0) - return -1; - /* Check if the current file status flags have already satisfied - * the request, if so, it is no need to call fcntl() to replicate it. - */ - if(!!(flags & O_NONBLOCK) == !!nonblock) - return 0; - if(nonblock) - flags |= O_NONBLOCK; - else - flags &= ~O_NONBLOCK; - return sfcntl(sockfd, F_SETFL, flags); - -#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO) - - /* Amiga */ - long flags = nonblock ? 1L : 0L; - return IoctlSocket(sockfd, FIONBIO, (char *)&flags); - -#elif defined(HAVE_IOCTL_FIONBIO) - - /* older Unix versions */ - int flags = nonblock ? 1 : 0; - return ioctl(sockfd, FIONBIO, &flags); - -#elif defined(HAVE_IOCTLSOCKET_FIONBIO) - - /* Windows */ - unsigned long flags = nonblock ? 1UL : 0UL; - return ioctlsocket(sockfd, (long)FIONBIO, &flags); - -#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK) - - /* Orbis OS */ - long b = nonblock ? 1L : 0L; - return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); - -#else -#error "no non-blocking method was found/used/set" -#endif -} diff --git a/vendor/curl/lib/curlx/nonblock.h b/vendor/curl/lib/curlx/nonblock.h deleted file mode 100644 index ee2cd286a..000000000 --- a/vendor/curl/lib/curlx/nonblock.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_NONBLOCK_H -#define HEADER_CURL_NONBLOCK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */); - -#endif /* HEADER_CURL_NONBLOCK_H */ diff --git a/vendor/curl/lib/curlx/snprintf.c b/vendor/curl/lib/curlx/snprintf.c deleted file mode 100644 index 911c42e6a..000000000 --- a/vendor/curl/lib/curlx/snprintf.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/snprintf.h" - -#ifdef _WIN32 -#include - -/* Simplified wrapper for the Windows platform to use the correct symbol and - ensuring null-termination. Omit returning a length to keep it simple. */ -void curlx_win32_snprintf(char *buf, size_t maxlen, const char *fmt, ...) -{ - va_list ap; - if(!maxlen) - return; - va_start(ap, fmt); -#ifdef CURL_HAVE_DIAG -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" -#endif - /* !checksrc! disable BANNEDFUNC 1 */ - (void)vsnprintf(buf, maxlen, fmt, ap); -#ifdef CURL_HAVE_DIAG -#pragma GCC diagnostic pop -#endif - buf[maxlen - 1] = 0; - va_end(ap); -} -#endif /* _WIN32 */ diff --git a/vendor/curl/lib/curlx/snprintf.h b/vendor/curl/lib/curlx/snprintf.h deleted file mode 100644 index d6260e4e3..000000000 --- a/vendor/curl/lib/curlx/snprintf.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HEADER_CURLX_SNPRINTF_H -#define HEADER_CURLX_SNPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* Raw snprintf() for curlx */ - -#ifdef _WIN32 -void curlx_win32_snprintf(char *buf, size_t maxlen, const char *fmt, ...) - CURL_PRINTF(3, 4); -#endif - -#ifdef WITHOUT_LIBCURL /* when built for the test servers */ -#ifdef _WIN32 -#define SNPRINTF curlx_win32_snprintf -#else -#define SNPRINTF snprintf -#endif -#else /* !WITHOUT_LIBCURL */ -#include -#define SNPRINTF curl_msnprintf -#endif /* WITHOUT_LIBCURL */ -#endif /* HEADER_CURLX_SNPRINTF_H */ diff --git a/vendor/curl/lib/curlx/strcopy.c b/vendor/curl/lib/curlx/strcopy.c deleted file mode 100644 index 3e58ea24f..000000000 --- a/vendor/curl/lib/curlx/strcopy.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/strcopy.h" - -/* - * curlx_strcopy() is a replacement for strcpy. - * - * Provide the target buffer @dest and size of the target buffer @dsize, If - * the source string @src with its *string length* @slen fits in the target - * buffer it is copied there - including storing a null terminator. - * - * If the target buffer is too small, the copy is not performed but if the - * target buffer has a non-zero size it gets a null terminator stored. - */ -void curlx_strcopy(char *dest, /* destination buffer */ - size_t dsize, /* size of target buffer */ - const char *src, /* source string */ - size_t slen) /* length of source string to copy */ -{ - DEBUGASSERT(slen < dsize); - if(slen < dsize) { - memcpy(dest, src, slen); - dest[slen] = 0; - } - else if(dsize) - dest[0] = 0; -} diff --git a/vendor/curl/lib/curlx/strcopy.h b/vendor/curl/lib/curlx/strcopy.h deleted file mode 100644 index d671149cb..000000000 --- a/vendor/curl/lib/curlx/strcopy.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef HEADER_CURLX_STRCOPY_H -#define HEADER_CURLX_STRCOPY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -void curlx_strcopy(char *dest, - size_t dsize, /* size of target buffer */ - const char *src, - size_t slen); /* length of string to copy */ - -#endif /* HEADER_CURLX_STRCOPY_H */ diff --git a/vendor/curl/lib/curlx/strdup.c b/vendor/curl/lib/curlx/strdup.c deleted file mode 100644 index 3c967dbe0..000000000 --- a/vendor/curl/lib/curlx/strdup.c +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef _WIN32 -#include -#endif - -#include "curlx/strdup.h" - -#ifdef _WIN32 -/*************************************************************************** - * - * curlx_wcsdup(source) - * - * Copies the 'source' wchar string to a newly allocated buffer (that is - * returned). Used by macro curlx_tcsdup(). - * - * Returns the new pointer or NULL on failure. - * - ***************************************************************************/ -wchar_t *curlx_wcsdup(const wchar_t *src) -{ - size_t length = wcslen(src); - - if(length > (SIZE_MAX / sizeof(wchar_t)) - 1) - return (wchar_t *)NULL; /* integer overflow */ - - return (wchar_t *)curlx_memdup(src, (length + 1) * sizeof(wchar_t)); -} -#endif - -/*************************************************************************** - * - * curlx_memdup(source, length) - * - * Copies the 'source' data to a newly allocated buffer (that is - * returned). Copies 'length' bytes. - * - * Returns the new pointer or NULL on failure. - * - ***************************************************************************/ -void *curlx_memdup(const void *src, size_t length) -{ - void *buffer = curlx_malloc(length); - if(!buffer) - return NULL; /* fail */ - - memcpy(buffer, src, length); - - return buffer; -} - -/*************************************************************************** - * - * curlx_memdup0(source, length) - * - * Copies the 'source' string to a newly allocated buffer (that is returned). - * Copies 'length' bytes then adds a null-terminator. - * - * Returns the new pointer or NULL on failure. - * - ***************************************************************************/ -void *curlx_memdup0(const char *src, size_t length) -{ - char *buf = (length < SIZE_MAX) ? curlx_malloc(length + 1) : NULL; - if(!buf) - return NULL; - if(length) { - DEBUGASSERT(src); /* must never be NULL */ - memcpy(buf, src, length); - } - buf[length] = 0; - return buf; -} diff --git a/vendor/curl/lib/curlx/strdup.h b/vendor/curl/lib/curlx/strdup.h deleted file mode 100644 index 0c4b14161..000000000 --- a/vendor/curl/lib/curlx/strdup.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURLX_STRDUP_H -#define HEADER_CURLX_STRDUP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef _WIN32 -wchar_t *curlx_wcsdup(const wchar_t *src); /* for curlx_tcsdup() */ -#endif -void *curlx_memdup(const void *src, size_t length); -void *curlx_memdup0(const char *src, size_t length); -#endif /* HEADER_CURLX_STRDUP_H */ diff --git a/vendor/curl/lib/curlx/strerr.c b/vendor/curl/lib/curlx/strerr.c deleted file mode 100644 index b53173c57..000000000 --- a/vendor/curl/lib/curlx/strerr.c +++ /dev/null @@ -1,329 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_STRERROR_R -# if (!defined(HAVE_POSIX_STRERROR_R) && \ - !defined(HAVE_GLIBC_STRERROR_R)) || \ - (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)) -# error "strerror_r MUST be either POSIX, glibc style" -# endif -#endif - -#include "curlx/winapi.h" -#include "curlx/snprintf.h" -#include "curlx/strerr.h" -#include "curlx/strcopy.h" - -#ifdef USE_WINSOCK -/* This is a helper function for curlx_strerror that converts Winsock error - * codes (WSAGetLastError) to error messages. - * Returns NULL if no error message was found for error code. - */ -static const char *get_winsock_error(int err, char *buf, size_t len) -{ - VERBOSE(const char *p); - - if(!len) - return NULL; - - *buf = '\0'; - -#ifndef CURLVERBOSE - (void)err; - return NULL; -#else - switch(err) { - case WSAEINTR: - p = "Call interrupted"; - break; - case WSAEBADF: - p = "Bad file"; - break; - case WSAEACCES: - p = "Bad access"; - break; - case WSAEFAULT: - p = "Bad argument"; - break; - case WSAEINVAL: - p = "Invalid arguments"; - break; - case WSAEMFILE: - p = "Out of file descriptors"; - break; - case WSAEWOULDBLOCK: - p = "Call would block"; - break; - case WSAEINPROGRESS: - case WSAEALREADY: - p = "Blocking call in progress"; - break; - case WSAENOTSOCK: - p = "Descriptor is not a socket"; - break; - case WSAEDESTADDRREQ: - p = "Need destination address"; - break; - case WSAEMSGSIZE: - p = "Bad message size"; - break; - case WSAEPROTOTYPE: - p = "Bad protocol"; - break; - case WSAENOPROTOOPT: - p = "Protocol option is unsupported"; - break; - case WSAEPROTONOSUPPORT: - p = "Protocol is unsupported"; - break; - case WSAESOCKTNOSUPPORT: - p = "Socket is unsupported"; - break; - case WSAEOPNOTSUPP: - p = "Operation not supported"; - break; - case WSAEAFNOSUPPORT: - p = "Address family not supported"; - break; - case WSAEPFNOSUPPORT: - p = "Protocol family not supported"; - break; - case WSAEADDRINUSE: - p = "Address already in use"; - break; - case WSAEADDRNOTAVAIL: - p = "Address not available"; - break; - case WSAENETDOWN: - p = "Network down"; - break; - case WSAENETUNREACH: - p = "Network unreachable"; - break; - case WSAENETRESET: - p = "Network has been reset"; - break; - case WSAECONNABORTED: - p = "Connection was aborted"; - break; - case WSAECONNRESET: - p = "Connection was reset"; - break; - case WSAENOBUFS: - p = "No buffer space"; - break; - case WSAEISCONN: - p = "Socket is already connected"; - break; - case WSAENOTCONN: - p = "Socket is not connected"; - break; - case WSAESHUTDOWN: - p = "Socket has been shut down"; - break; - case WSAETOOMANYREFS: - p = "Too many references"; - break; - case WSAETIMEDOUT: - p = "Timed out"; - break; - case WSAECONNREFUSED: - p = "Connection refused"; - break; - case WSAELOOP: - p = "Loop??"; - break; - case WSAENAMETOOLONG: - p = "Name too long"; - break; - case WSAEHOSTDOWN: - p = "Host down"; - break; - case WSAEHOSTUNREACH: - p = "Host unreachable"; - break; - case WSAENOTEMPTY: - p = "Not empty"; - break; - case WSAEPROCLIM: - p = "Process limit reached"; - break; - case WSAEUSERS: - p = "Too many users"; - break; - case WSAEDQUOT: - p = "Bad quota"; - break; - case WSAESTALE: - p = "Something is stale"; - break; - case WSAEREMOTE: - p = "Remote error"; - break; - case WSAEDISCON: - p = "Disconnected"; - break; - /* Extended Winsock errors */ - case WSASYSNOTREADY: - p = "Winsock library is not ready"; - break; - case WSANOTINITIALISED: - p = "Winsock library not initialised"; - break; - case WSAVERNOTSUPPORTED: - p = "Winsock version not supported"; - break; - - /* getXbyY() errors (already handled in herrmsg): - * Authoritative Answer: Host not found */ - case WSAHOST_NOT_FOUND: - p = "Host not found"; - break; - - /* Non-Authoritative: Host not found, or SERVERFAIL */ - case WSATRY_AGAIN: - p = "Host not found, try again"; - break; - - /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ - case WSANO_RECOVERY: - p = "Unrecoverable error in call to nameserver"; - break; - - /* Valid name, no data record of requested type */ - case WSANO_DATA: - p = "No data record of requested type"; - break; - - default: - return NULL; - } - curlx_strcopy(buf, len, p, strlen(p)); - return buf; -#endif -} -#endif /* USE_WINSOCK */ - -/* - * Our thread-safe and smart strerror() replacement. - * - * The 'err' argument passed in to this function MUST be a true errno number - * as reported on this system. We do no range checking on the number before - * we pass it to the "number-to-message" conversion function and there might - * be systems that do not do proper range checking in there themselves. - * - * We do not do range checking (on systems other than Windows) since there is - * no good reliable and portable way to do it. - * - * On Windows different types of error codes overlap. This function has an - * order of preference when trying to match error codes: - * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError). - * - * It may be more correct to call one of the variant functions instead: - * Call Curl_sspi_strerror if the error code is definitely Windows SSPI. - * Call curlx_winapi_strerror if the error code is definitely Windows API. - */ -const char *curlx_strerror(int err, char *buf, size_t buflen) -{ -#ifdef _WIN32 - DWORD old_win_err = GetLastError(); -#endif - int old_errno = errno; - char *p; - - if(!buflen) - return NULL; - -#ifndef _WIN32 - DEBUGASSERT(err >= 0); -#endif - - *buf = '\0'; - -#ifdef _WIN32 - if((strerror_s(buf, buflen, err) || !strcmp(buf, "Unknown error")) && -#ifdef USE_WINSOCK - !get_winsock_error(err, buf, buflen) && -#endif - !curlx_get_winapi_error((DWORD)err, buf, buflen)) - SNPRINTF(buf, buflen, "Unknown error %d (%#x)", err, err); -#else /* !_WIN32 */ - -#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) - /* - * The POSIX-style strerror_r() may set errno to ERANGE if insufficient - * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated - * message string, or EINVAL if 'errnum' is not a valid error number. - */ - if(strerror_r(err, buf, buflen) && - buflen > sizeof("Unknown error ") + 20) { - if(buf[0] == '\0') - SNPRINTF(buf, buflen, "Unknown error %d", err); - } -#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R) - /* - * The glibc-style strerror_r() only *might* use the buffer we pass to - * the function, but it always returns the error message as a pointer, - * so we must copy that string unconditionally (if non-NULL). - */ - { - char buffer[256]; - const char *msg = strerror_r(err, buffer, sizeof(buffer)); - if(msg && buflen > 1) - SNPRINTF(buf, buflen, "%s", msg); - else if(buflen > sizeof("Unknown error ") + 20) - SNPRINTF(buf, buflen, "Unknown error %d", err); - } -#else - { - /* !checksrc! disable BANNEDFUNC 1 */ - const char *msg = strerror(err); - if(msg && buflen > 1) - SNPRINTF(buf, buflen, "%s", msg); - else if(buflen > sizeof("Unknown error ") + 20) - SNPRINTF(buf, buflen, "Unknown error %d", err); - } -#endif - -#endif /* _WIN32 */ - - /* strip trailing '\r\n' or '\n'. */ - p = strrchr(buf, '\n'); - if(p && (p - buf) >= 2) - *p = '\0'; - p = strrchr(buf, '\r'); - if(p && (p - buf) >= 1) - *p = '\0'; - - if(errno != old_errno) - errno = old_errno; - -#ifdef _WIN32 - if(old_win_err != GetLastError()) - SetLastError(old_win_err); -#endif - - return buf; -} diff --git a/vendor/curl/lib/curlx/strerr.h b/vendor/curl/lib/curlx/strerr.h deleted file mode 100644 index 4413e6738..000000000 --- a/vendor/curl/lib/curlx/strerr.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HEADER_CURL_STRERR_H -#define HEADER_CURL_STRERR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -const char *curlx_strerror(int err, char *buf, size_t buflen); - -#endif /* HEADER_CURL_STRERR_H */ diff --git a/vendor/curl/lib/curlx/strparse.c b/vendor/curl/lib/curlx/strparse.c deleted file mode 100644 index 7866b2087..000000000 --- a/vendor/curl/lib/curlx/strparse.c +++ /dev/null @@ -1,313 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/strparse.h" - -void curlx_str_init(struct Curl_str *out) -{ - out->str = NULL; - out->len = 0; -} - -void curlx_str_assign(struct Curl_str *out, const char *str, size_t len) -{ - out->str = str; - out->len = len; -} - -/* remove bytes from the end of the string, never remove more bytes than what - the string holds! */ -void curlx_str_trim(struct Curl_str *out, size_t len) -{ - DEBUGASSERT(out); - DEBUGASSERT(out->len >= len); - out->len -= len; -} - -/* Get a word until the first DELIM or end of string. At least one byte long. - return non-zero on error */ -int curlx_str_until(const char **linep, struct Curl_str *out, - const size_t max, char delim) -{ - const char *s = *linep; - size_t len = 0; - DEBUGASSERT(linep && *linep && out && max && delim); - - curlx_str_init(out); - while(*s && (*s != delim)) { - s++; - if(++len > max) { - return STRE_BIG; - } - } - if(!len) - return STRE_SHORT; - out->str = *linep; - out->len = len; - *linep = s; /* point to the first byte after the word */ - return STRE_OK; -} - -/* Get a word until the first space or end of string. At least one byte long. - return non-zero on error */ -int curlx_str_word(const char **linep, struct Curl_str *out, const size_t max) -{ - return curlx_str_until(linep, out, max, ' '); -} - -/* Get a word until a newline byte or end of string. At least one byte long. - return non-zero on error */ -int curlx_str_untilnl(const char **linep, struct Curl_str *out, - const size_t max) -{ - const char *s = *linep; - size_t len = 0; - DEBUGASSERT(linep && *linep && out && max); - - curlx_str_init(out); - while(*s && !ISNEWLINE(*s)) { - s++; - if(++len > max) - return STRE_BIG; - } - if(!len) - return STRE_SHORT; - out->str = *linep; - out->len = len; - *linep = s; /* point to the first byte after the word */ - return STRE_OK; -} - -/* Get a "quoted" word. Escaped quotes are supported. - return non-zero on error */ -int curlx_str_quotedword(const char **linep, struct Curl_str *out, - const size_t max) -{ - const char *s = *linep; - size_t len = 0; - DEBUGASSERT(linep && *linep && out && max); - - curlx_str_init(out); - if(*s != '\"') - return STRE_BEGQUOTE; - s++; - while(*s && (*s != '\"')) { - if(*s == '\\' && s[1]) { - s++; - if(++len > max) - return STRE_BIG; - } - s++; - if(++len > max) - return STRE_BIG; - } - if(*s != '\"') - return STRE_ENDQUOTE; - out->str = (*linep) + 1; - out->len = len; - *linep = s + 1; - return STRE_OK; -} - -/* Advance over a single character. - return non-zero on error */ -int curlx_str_single(const char **linep, char byte) -{ - DEBUGASSERT(linep && *linep); - if(**linep != byte) - return STRE_BYTE; - (*linep)++; /* move over it */ - return STRE_OK; -} - -/* Advance over a single space. - return non-zero on error */ -int curlx_str_singlespace(const char **linep) -{ - return curlx_str_single(linep, ' '); -} - -/* given an ASCII character and max ascii, return TRUE if valid */ -#define valid_digit(x, m) \ - (((x) >= '0') && ((x) <= (m)) && curlx_hexasciitable[(x) - '0']) - -/* We use 16 for the zero index (and the necessary bitwise AND in the loop) - to be able to have a non-zero value there to make valid_digit() able to - use the info */ -const unsigned char curlx_hexasciitable[] = { - 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 0x30: 0 - 9 */ - 0, 0, 0, 0, 0, 0, 0, - 10, 11, 12, 13, 14, 15, /* 0x41: A - F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10, 11, 12, 13, 14, 15 /* 0x61: a - f */ -}; - -/* no support for 0x prefix nor leading spaces */ -static int str_num_base(const char **linep, curl_off_t *nump, curl_off_t max, - int base) /* 8, 10 or 16, nothing else */ -{ - curl_off_t num = 0; - const char *p; - int m = (base == 10) ? '9' : /* the largest digit possible */ - (base == 16) ? 'f' : '7'; - DEBUGASSERT(linep && *linep && nump); - DEBUGASSERT((base == 8) || (base == 10) || (base == 16)); - DEBUGASSERT(max >= 0); /* mostly to catch SIZE_MAX, which is too large */ - *nump = 0; - p = *linep; - if(!valid_digit(*p, m)) - return STRE_NO_NUM; - if(max < base) { - /* special-case low max scenario because check needs to be different */ - do { - int n = curlx_hexval(*p++); - num = (num * base) + n; - if(num > max) - return STRE_OVERFLOW; - } while(valid_digit(*p, m)); - } - else { - do { - int n = curlx_hexval(*p++); - if(num > ((max - n) / base)) - return STRE_OVERFLOW; - num = (num * base) + n; - } while(valid_digit(*p, m)); - } - *nump = num; - *linep = p; - return STRE_OK; -} - -/* Get an unsigned decimal number with no leading space or minus. Leading - zeroes are accepted. return non-zero on error */ -int curlx_str_number(const char **linep, curl_off_t *nump, curl_off_t max) -{ - return str_num_base(linep, nump, max, 10); -} - -/* Get an unsigned hexadecimal number with no leading space or minus and no - "0x" support. Leading zeroes are accepted. return non-zero on error */ -int curlx_str_hex(const char **linep, curl_off_t *nump, curl_off_t max) -{ - return str_num_base(linep, nump, max, 16); -} - -/* Get an unsigned octal number with no leading space or minus and no "0" - prefix support. Leading zeroes are accepted. return non-zero on error */ -int curlx_str_octal(const char **linep, curl_off_t *nump, curl_off_t max) -{ - return str_num_base(linep, nump, max, 8); -} - -/* - * Parse a positive number up to 63-bit number written in ASCII. Skip leading - * blanks. No support for prefixes. - */ -int curlx_str_numblanks(const char **str, curl_off_t *num) -{ - curlx_str_passblanks(str); - return curlx_str_number(str, num, CURL_OFF_T_MAX); -} - -/* CR or LF - return non-zero on error */ -int curlx_str_newline(const char **linep) -{ - DEBUGASSERT(linep && *linep); - if(ISNEWLINE(**linep)) { - (*linep)++; - return STRE_OK; /* yessir */ - } - return STRE_NEWLINE; -} - -#ifndef WITHOUT_LIBCURL -/* case insensitive compare that the parsed string matches the given string. - Returns non-zero on match. */ -int curlx_str_casecompare(struct Curl_str *str, const char *check) -{ - size_t clen = check ? strlen(check) : 0; - return ((str->len == clen) && curl_strnequal(str->str, check, clen)); -} -#endif - -/* case sensitive string compare. Returns non-zero on match. */ -int curlx_str_cmp(struct Curl_str *str, const char *check) -{ - if(check) { - size_t clen = strlen(check); - return ((str->len == clen) && !strncmp(str->str, check, clen)); - } - return !!(str->len); -} - -/* Trim off 'num' number of bytes from the beginning (left side) of the - string. If 'num' is larger than the string, return error. */ -int curlx_str_nudge(struct Curl_str *str, size_t num) -{ - if(num <= str->len) { - str->str += num; - str->len -= num; - return STRE_OK; - } - return STRE_OVERFLOW; -} - -/* Get the following character sequence that consists only of bytes not - present in the 'reject' string. Like strcspn(). */ -int curlx_str_cspn(const char **linep, struct Curl_str *out, - const char *reject) -{ - const char *s = *linep; - size_t len; - DEBUGASSERT(linep && *linep); - - len = strcspn(s, reject); - if(len) { - out->str = s; - out->len = len; - *linep = &s[len]; - return STRE_OK; - } - curlx_str_init(out); - return STRE_SHORT; -} - -/* remove ISBLANK()s from both ends of the string */ -void curlx_str_trimblanks(struct Curl_str *out) -{ - while(out->len && ISBLANK(*out->str)) - curlx_str_nudge(out, 1); - - /* trim trailing spaces and tabs */ - while(out->len && ISBLANK(out->str[out->len - 1])) - out->len--; -} - -/* increase the pointer until it has moved over all blanks */ -void curlx_str_passblanks(const char **linep) -{ - while(ISBLANK(**linep)) - (*linep)++; /* move over it */ -} diff --git a/vendor/curl/lib/curlx/strparse.h b/vendor/curl/lib/curlx/strparse.h deleted file mode 100644 index c7801b2cb..000000000 --- a/vendor/curl/lib/curlx/strparse.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef HEADER_CURL_STRPARSE_H -#define HEADER_CURL_STRPARSE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#define STRE_OK 0 -#define STRE_BIG 1 -#define STRE_SHORT 2 -#define STRE_BEGQUOTE 3 -#define STRE_ENDQUOTE 4 -#define STRE_BYTE 5 -#define STRE_NEWLINE 6 -#define STRE_OVERFLOW 7 -#define STRE_NO_NUM 8 - -/* public struct, but all accesses should be done using the provided - functions */ -struct Curl_str { - const char *str; - size_t len; -}; - -void curlx_str_init(struct Curl_str *out); -void curlx_str_assign(struct Curl_str *out, const char *str, size_t len); -void curlx_str_trim(struct Curl_str *out, size_t len); - -#define curlx_str(x) ((x)->str) -#define curlx_strlen(x) ((x)->len) - -/* Get a word until the first space - return non-zero on error */ -int curlx_str_word(const char **linep, struct Curl_str *out, const size_t max); - -/* Get a word until the first DELIM or end of string - return non-zero on error */ -int curlx_str_until(const char **linep, struct Curl_str *out, const size_t max, - char delim); - -/* Get a word until a newline byte or end of string. At least one byte long. - return non-zero on error */ -int curlx_str_untilnl(const char **linep, struct Curl_str *out, - const size_t max); - -/* Get a "quoted" word. Escaped quotes are supported. - return non-zero on error */ -int curlx_str_quotedword(const char **linep, struct Curl_str *out, - const size_t max); - -/* Advance over a single character. - return non-zero on error */ -int curlx_str_single(const char **linep, char byte); - -/* Advance over a single space. - return non-zero on error */ -int curlx_str_singlespace(const char **linep); - -/* Get an unsigned decimal number. Return non-zero on error */ -int curlx_str_number(const char **linep, curl_off_t *nump, curl_off_t max); - -/* As above with CURL_OFF_T_MAX but also pass leading blanks */ -int curlx_str_numblanks(const char **str, curl_off_t *num); - -/* Get an unsigned hexadecimal number. Return non-zero on error */ -int curlx_str_hex(const char **linep, curl_off_t *nump, curl_off_t max); - -/* Get an unsigned octal number. Return non-zero on error */ -int curlx_str_octal(const char **linep, curl_off_t *nump, curl_off_t max); - -/* Check for CR or LF - return non-zero on error */ -int curlx_str_newline(const char **linep); - -/* case insensitive compare that the parsed string matches the - given string. */ -int curlx_str_casecompare(struct Curl_str *str, const char *check); -int curlx_str_cmp(struct Curl_str *str, const char *check); - -int curlx_str_nudge(struct Curl_str *str, size_t num); - -int curlx_str_cspn(const char **linep, struct Curl_str *out, - const char *reject); -void curlx_str_trimblanks(struct Curl_str *out); -void curlx_str_passblanks(const char **linep); - -/* given a hexadecimal letter, return the binary value. '0' returns 0, 'a' - returns 10. THIS ONLY WORKS ON VALID HEXADECIMAL LETTER INPUT. Verify - before calling this! -*/ -extern const unsigned char curlx_hexasciitable[]; -#define curlx_hexval(x) (unsigned char)(curlx_hexasciitable[(x) - '0'] & 0x0f) - -#endif /* HEADER_CURL_STRPARSE_H */ diff --git a/vendor/curl/lib/curlx/timediff.c b/vendor/curl/lib/curlx/timediff.c deleted file mode 100644 index 2bf786941..000000000 --- a/vendor/curl/lib/curlx/timediff.c +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/timediff.h" - -/* - * Converts number of milliseconds into a timeval structure. - * - * Return values: - * NULL IF tv is NULL or ms < 0 (eg. no timeout -> blocking select) - * tv with 0 in both fields IF ms == 0 (eg. 0ms timeout -> polling select) - * tv with converted fields IF ms > 0 (eg. >0ms timeout -> waiting select) - */ -struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms) -{ - if(!tv) - return NULL; - - if(ms < 0) - return NULL; - - if(ms > 0) { - timediff_t tv_sec = ms / 1000; - timediff_t tv_usec = (ms % 1000) * 1000; /* max=999000 */ -#ifdef HAVE_SUSECONDS_T -#if TIMEDIFF_T_MAX > TIME_T_MAX - /* tv_sec overflow check in case time_t is signed */ - if(tv_sec > TIME_T_MAX) - tv_sec = TIME_T_MAX; -#endif - tv->tv_sec = (time_t)tv_sec; - tv->tv_usec = (suseconds_t)tv_usec; -#elif defined(_WIN32) /* maybe also others in the future */ -#if TIMEDIFF_T_MAX > LONG_MAX - /* tv_sec overflow check on Windows there we know it is long */ - if(tv_sec > LONG_MAX) - tv_sec = LONG_MAX; -#endif - tv->tv_sec = (long)tv_sec; - tv->tv_usec = (long)tv_usec; -#else -#if TIMEDIFF_T_MAX > INT_MAX - /* tv_sec overflow check in case time_t is signed */ - if(tv_sec > INT_MAX) - tv_sec = INT_MAX; -#endif - tv->tv_sec = (int)tv_sec; - tv->tv_usec = (int)tv_usec; -#endif - } - else { - tv->tv_sec = 0; - tv->tv_usec = 0; - } - - return tv; -} - -/* - * Converts a timeval structure into number of milliseconds. - */ -timediff_t curlx_tvtoms(struct timeval *tv) -{ - return (tv->tv_sec * 1000) + (timediff_t)(tv->tv_usec / 1000); -} diff --git a/vendor/curl/lib/curlx/timediff.h b/vendor/curl/lib/curlx/timediff.h deleted file mode 100644 index 1081c75d1..000000000 --- a/vendor/curl/lib/curlx/timediff.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef HEADER_CURL_TIMEDIFF_H -#define HEADER_CURL_TIMEDIFF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* Use a larger type even for 32-bit time_t systems so that we can keep - microsecond accuracy in it */ -typedef curl_off_t timediff_t; -#define FMT_TIMEDIFF_T FMT_OFF_T - -#define TIMEDIFF_T_MAX CURL_OFF_T_MAX -#define TIMEDIFF_T_MIN CURL_OFF_T_MIN - -/* - * Converts number of milliseconds into a timeval structure. - * - * Return values: - * NULL IF tv is NULL or ms < 0 (eg. no timeout -> blocking select) - * tv with 0 in both fields IF ms == 0 (eg. 0ms timeout -> polling select) - * tv with converted fields IF ms > 0 (eg. >0ms timeout -> waiting select) - */ -struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms); - -/* - * Converts a timeval structure into number of milliseconds. - */ -timediff_t curlx_tvtoms(struct timeval *tv); - -#endif /* HEADER_CURL_TIMEDIFF_H */ diff --git a/vendor/curl/lib/curlx/timeval.c b/vendor/curl/lib/curlx/timeval.c deleted file mode 100644 index 2363e6083..000000000 --- a/vendor/curl/lib/curlx/timeval.c +++ /dev/null @@ -1,273 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/timeval.h" - -#ifdef _WIN32 - -#include "system_win32.h" - -LARGE_INTEGER Curl_freq; - -/* For tool or tests, we must initialize before calling curlx_now(). - Providing this function here is wrong. */ -void curlx_now_init(void) -{ - QueryPerformanceFrequency(&Curl_freq); -} - -/* In case of bug fix this function has a counterpart in tool_util.c */ -void curlx_pnow(struct curltime *pnow) -{ - LARGE_INTEGER count; - DEBUGASSERT(Curl_freq.QuadPart); - QueryPerformanceCounter(&count); - pnow->tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart); - pnow->tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 / - Curl_freq.QuadPart); -} - -#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) || \ - defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW) - -void curlx_pnow(struct curltime *pnow) -{ - /* - * clock_gettime() is granted to be increased monotonically when the - * monotonic clock is queried. Time starting point is unspecified, it - * could be the system start-up time, the Epoch, or something else, - * in any case the time starting point does not change once that the - * system has started up. - */ - struct timespec tsnow; - - /* - * clock_gettime() may be defined by Apple's SDK as weak symbol thus - * code compiles but fails during runtime if clock_gettime() is - * called on unsupported OS version. - */ -#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \ - (HAVE_BUILTIN_AVAILABLE == 1) - bool have_clock_gettime = FALSE; - if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) - have_clock_gettime = TRUE; -#endif - -#ifdef HAVE_CLOCK_GETTIME_MONOTONIC_RAW - if( -#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \ - (HAVE_BUILTIN_AVAILABLE == 1) - have_clock_gettime && -#endif - (clock_gettime(CLOCK_MONOTONIC_RAW, &tsnow) == 0)) { - pnow->tv_sec = tsnow.tv_sec; - pnow->tv_usec = (int)(tsnow.tv_nsec / 1000); - } - else -#endif - - if( -#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \ - (HAVE_BUILTIN_AVAILABLE == 1) - have_clock_gettime && -#endif - (clock_gettime(CLOCK_MONOTONIC, &tsnow) == 0)) { - pnow->tv_sec = tsnow.tv_sec; - pnow->tv_usec = (int)(tsnow.tv_nsec / 1000); - } - /* - * Even when the configure process has truly detected monotonic clock - * availability, it might happen that it is not actually available at - * runtime. When this occurs, fallback to other time source. - */ -#ifdef HAVE_GETTIMEOFDAY - else { - struct timeval now; - (void)gettimeofday(&now, NULL); - pnow->tv_sec = now.tv_sec; - pnow->tv_usec = (int)now.tv_usec; - } -#else - else { - pnow->tv_sec = time(NULL); - pnow->tv_usec = 0; - } -#endif -} - -#elif defined(HAVE_MACH_ABSOLUTE_TIME) - -#include - -void curlx_pnow(struct curltime *pnow) -{ - /* - * Monotonic timer on macOS is provided by mach_absolute_time(), which - * returns time in Mach "absolute time units," which are platform-dependent. - * To convert to nanoseconds, one must use conversion factors specified by - * mach_timebase_info(). - */ - static mach_timebase_info_data_t timebase; - uint64_t usecs; - - if(timebase.denom == 0) - (void)mach_timebase_info(&timebase); - - usecs = mach_absolute_time(); - usecs *= timebase.numer; /* spellchecker:disable-line */ - usecs /= timebase.denom; - usecs /= 1000; - - pnow->tv_sec = usecs / 1000000; - pnow->tv_usec = (int)(usecs % 1000000); -} - -#elif defined(HAVE_GETTIMEOFDAY) - -void curlx_pnow(struct curltime *pnow) -{ - /* - * gettimeofday() is not granted to be increased monotonically, due to - * clock drifting and external source time synchronization it can jump - * forward or backward in time. - */ - struct timeval now; - (void)gettimeofday(&now, NULL); - pnow->tv_sec = now.tv_sec; - pnow->tv_usec = (int)now.tv_usec; -} - -#else - -void curlx_pnow(struct curltime *pnow) -{ - /* - * time() returns the value of time in seconds since the Epoch. - */ - pnow->tv_sec = time(NULL); - pnow->tv_usec = 0; - if(!pnow->tv_sec) /* avoid a `now` fully zero */ - pnow->tv_usec = 1; -} - -#endif - -struct curltime curlx_now(void) -{ - struct curltime now; - curlx_pnow(&now); - return now; -} - -/* - * Returns: time difference in number of milliseconds. For too large diffs it - * returns max value. - * - * @unittest: 1323 - */ -timediff_t curlx_ptimediff_ms(const struct curltime *newer, - const struct curltime *older) -{ - timediff_t diff = (timediff_t)newer->tv_sec - older->tv_sec; - if(diff >= (TIMEDIFF_T_MAX / 1000)) - return TIMEDIFF_T_MAX; - else if(diff <= (TIMEDIFF_T_MIN / 1000)) - return TIMEDIFF_T_MIN; - return (diff * 1000) + ((newer->tv_usec - older->tv_usec) / 1000); -} - -timediff_t curlx_timediff_ms(struct curltime newer, struct curltime older) -{ - return curlx_ptimediff_ms(&newer, &older); -} - -/* - * Returns: time difference in number of milliseconds, rounded up. - * For too large diffs it returns max value. - */ -timediff_t curlx_timediff_ceil_ms(struct curltime newer, - struct curltime older) -{ - timediff_t diff = (timediff_t)newer.tv_sec - older.tv_sec; - if(diff >= (TIMEDIFF_T_MAX / 1000)) - return TIMEDIFF_T_MAX; - else if(diff <= (TIMEDIFF_T_MIN / 1000)) - return TIMEDIFF_T_MIN; - return (diff * 1000) + ((newer.tv_usec - older.tv_usec + 999) / 1000); -} - -/* - * Returns: time difference in number of microseconds. For too large diffs it - * returns max value. - */ -timediff_t curlx_ptimediff_us(const struct curltime *newer, - const struct curltime *older) -{ - timediff_t diff = (timediff_t)newer->tv_sec - older->tv_sec; - if(diff >= (TIMEDIFF_T_MAX / 1000000)) - return TIMEDIFF_T_MAX; - else if(diff <= (TIMEDIFF_T_MIN / 1000000)) - return TIMEDIFF_T_MIN; - return (diff * 1000000) + newer->tv_usec - older->tv_usec; -} - -timediff_t curlx_timediff_us(struct curltime newer, struct curltime older) -{ - return curlx_ptimediff_us(&newer, &older); -} - -#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR <= 3) -#include /* for _gmtime32_s(), _gmtime64_s() */ -#ifdef _USE_32BIT_TIME_T -#define gmtime_s _gmtime32_s -#else -#define gmtime_s _gmtime64_s -#endif -#endif - -/* - * curlx_gmtime() is a gmtime() replacement for portability. Do not use - * the gmtime_s(), gmtime_r() or gmtime() functions anywhere else but here. - */ -CURLcode curlx_gmtime(time_t intime, struct tm *store) -{ -#ifdef _WIN32 - if(gmtime_s(store, &intime)) /* thread-safe */ - return CURLE_BAD_FUNCTION_ARGUMENT; -#elif defined(HAVE_GMTIME_R) - const struct tm *tm; - tm = gmtime_r(&intime, store); /* thread-safe */ - if(!tm) - return CURLE_BAD_FUNCTION_ARGUMENT; -#else - const struct tm *tm; - /* !checksrc! disable BANNEDFUNC 1 */ - tm = gmtime(&intime); /* not thread-safe */ - if(tm) - *store = *tm; /* copy the pointed struct to the local copy */ - else - return CURLE_BAD_FUNCTION_ARGUMENT; -#endif - - return CURLE_OK; -} diff --git a/vendor/curl/lib/curlx/timeval.h b/vendor/curl/lib/curlx/timeval.h deleted file mode 100644 index c01f95d87..000000000 --- a/vendor/curl/lib/curlx/timeval.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef HEADER_CURL_TIMEVAL_H -#define HEADER_CURL_TIMEVAL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/timediff.h" - -struct curltime { - time_t tv_sec; /* seconds */ - int tv_usec; /* microseconds */ -}; - -#ifdef _WIN32 -/* For tool or tests, we must initialize before calling curlx_now() */ -void curlx_now_init(void); -#endif - -struct curltime curlx_now(void); -void curlx_pnow(struct curltime *pnow); - -/* - * Make sure that the first argument (newer) is the more recent time and older - * is the older time, as otherwise you get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds. - */ -timediff_t curlx_timediff_ms(struct curltime newer, struct curltime older); -timediff_t curlx_ptimediff_ms(const struct curltime *newer, - const struct curltime *older); - -/* - * Make sure that the first argument (newer) is the more recent time and older - * is the older time, as otherwise you get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds, rounded up. - */ -timediff_t curlx_timediff_ceil_ms(struct curltime newer, - struct curltime older); - -/* - * Make sure that the first argument (newer) is the more recent time and older - * is the older time, as otherwise you get a weird negative time-diff back... - * - * Returns: the time difference in number of microseconds. - */ -timediff_t curlx_timediff_us(struct curltime newer, struct curltime older); -timediff_t curlx_ptimediff_us(const struct curltime *newer, - const struct curltime *older); - -CURLcode curlx_gmtime(time_t intime, struct tm *store); - -#endif /* HEADER_CURL_TIMEVAL_H */ diff --git a/vendor/curl/lib/curlx/version_win32.c b/vendor/curl/lib/curlx/version_win32.c deleted file mode 100644 index 296a38d92..000000000 --- a/vendor/curl/lib/curlx/version_win32.c +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef _WIN32 - -#include "curlx/version_win32.h" - -#ifndef CURL_WINDOWS_UWP -/* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW) - and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */ -struct OUR_OSVERSIONINFOEXW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; - USHORT wServicePackMajor; - USHORT wServicePackMinor; - USHORT wSuiteMask; - UCHAR wProductType; - UCHAR wReserved; -}; - -typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN) - (struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG); -static RTLVERIFYVERSIONINFO_FN s_pRtlVerifyVersionInfo; - -void curlx_verify_windows_init(void) -{ -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - s_pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN, - GetProcAddress(GetModuleHandle(TEXT("ntdll")), "RtlVerifyVersionInfo")); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif -} -#endif /* !CURL_WINDOWS_UWP */ - -/* - * curlx_verify_windows_version() - * - * This is used to verify if we are running on a specific Windows version. - * - * Parameters: - * - * majorVersion [in] - The major version number. - * minorVersion [in] - The minor version number. - * buildVersion [in] - The build version number. If 0, this parameter is - * ignored. - * platform [in] - The optional platform identifier. - * condition [in] - The test condition used to specifier whether we are - * checking a version less than, equal to or greater than - * what is specified in the major and minor version - * numbers. - * - * Returns TRUE if matched; otherwise FALSE. - */ -bool curlx_verify_windows_version(const unsigned int majorVersion, - const unsigned int minorVersion, - const unsigned int buildVersion, - const PlatformIdentifier platform, - const VersionCondition condition) -{ - bool matched = FALSE; - -#ifdef CURL_WINDOWS_UWP - /* We have no way to determine the Windows version from Windows apps, - so let's assume we are running on the target Windows version. */ - const WORD fullVersion = MAKEWORD(minorVersion, majorVersion); - const WORD targetVersion = (WORD)_WIN32_WINNT; - - (void)buildVersion; - - switch(condition) { - case VERSION_LESS_THAN: - matched = targetVersion < fullVersion; - break; - - case VERSION_LESS_THAN_EQUAL: - matched = targetVersion <= fullVersion; - break; - - case VERSION_EQUAL: - matched = targetVersion == fullVersion; - break; - - case VERSION_GREATER_THAN_EQUAL: - matched = targetVersion >= fullVersion; - break; - - case VERSION_GREATER_THAN: - matched = targetVersion > fullVersion; - break; - } - - if(matched && (platform == PLATFORM_WINDOWS)) { - /* we are always running on PLATFORM_WINNT */ - matched = FALSE; - } -#else - ULONGLONG cm = 0; - struct OUR_OSVERSIONINFOEXW osver; - BYTE majorCondition; - BYTE minorCondition; - BYTE buildCondition; - BYTE spMajorCondition; - BYTE spMinorCondition; - DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR; - - switch(condition) { - case VERSION_LESS_THAN: - majorCondition = VER_LESS; - minorCondition = VER_LESS; - buildCondition = VER_LESS; - spMajorCondition = VER_LESS_EQUAL; - spMinorCondition = VER_LESS_EQUAL; - break; - - case VERSION_LESS_THAN_EQUAL: - majorCondition = VER_LESS_EQUAL; - minorCondition = VER_LESS_EQUAL; - buildCondition = VER_LESS_EQUAL; - spMajorCondition = VER_LESS_EQUAL; - spMinorCondition = VER_LESS_EQUAL; - break; - - case VERSION_EQUAL: - majorCondition = VER_EQUAL; - minorCondition = VER_EQUAL; - buildCondition = VER_EQUAL; - spMajorCondition = VER_GREATER_EQUAL; - spMinorCondition = VER_GREATER_EQUAL; - break; - - case VERSION_GREATER_THAN_EQUAL: - majorCondition = VER_GREATER_EQUAL; - minorCondition = VER_GREATER_EQUAL; - buildCondition = VER_GREATER_EQUAL; - spMajorCondition = VER_GREATER_EQUAL; - spMinorCondition = VER_GREATER_EQUAL; - break; - - case VERSION_GREATER_THAN: - majorCondition = VER_GREATER; - minorCondition = VER_GREATER; - buildCondition = VER_GREATER; - spMajorCondition = VER_GREATER_EQUAL; - spMinorCondition = VER_GREATER_EQUAL; - break; - - default: - return FALSE; - } - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwMajorVersion = majorVersion; - osver.dwMinorVersion = minorVersion; - osver.dwBuildNumber = buildVersion; - if(platform == PLATFORM_WINDOWS) - osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; - else if(platform == PLATFORM_WINNT) - osver.dwPlatformId = VER_PLATFORM_WIN32_NT; - - cm = VerSetConditionMask(cm, VER_MAJORVERSION, majorCondition); - cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition); - - if(platform != PLATFORM_DONT_CARE) { - cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL); - dwTypeMask |= VER_PLATFORMID; - } - - /* Later versions of Windows have version functions that may not return the - real version of Windows unless the application is so manifested. We prefer - the real version always, so we use the Rtl variant of the function when - possible. Note though the function signatures have underlying fundamental - types that are the same, the return values are different. */ - if(s_pRtlVerifyVersionInfo) - matched = !s_pRtlVerifyVersionInfo(&osver, dwTypeMask, cm); - else - matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, dwTypeMask, cm); - - /* Compare the build number separately. VerifyVersionInfo normally compares - major.minor in hierarchical order (eg 1.9 is less than 2.0) but does not - do the same for build (eg 1.9 build 222 is not less than 2.0 build 111). - Build comparison is only needed when build numbers are equal (eg 1.9 is - always less than 2.0 so build comparison is not needed). */ - if(matched && buildVersion && - (condition == VERSION_EQUAL || - ((condition == VERSION_GREATER_THAN_EQUAL || - condition == VERSION_LESS_THAN_EQUAL) && - curlx_verify_windows_version(majorVersion, minorVersion, 0, - platform, VERSION_EQUAL)))) { - - cm = VerSetConditionMask(0, VER_BUILDNUMBER, buildCondition); - dwTypeMask = VER_BUILDNUMBER; - if(s_pRtlVerifyVersionInfo) - matched = !s_pRtlVerifyVersionInfo(&osver, dwTypeMask, cm); - else - matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, - dwTypeMask, cm); - } - -#endif - - return matched; -} - -#endif /* _WIN32 */ diff --git a/vendor/curl/lib/curlx/version_win32.h b/vendor/curl/lib/curlx/version_win32.h deleted file mode 100644 index c4a1c0f75..000000000 --- a/vendor/curl/lib/curlx/version_win32.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef HEADER_CURL_VERSION_WIN32_H -#define HEADER_CURL_VERSION_WIN32_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef _WIN32 - -/* Version condition */ -typedef enum { - VERSION_LESS_THAN, - VERSION_LESS_THAN_EQUAL, - VERSION_EQUAL, - VERSION_GREATER_THAN_EQUAL, - VERSION_GREATER_THAN -} VersionCondition; - -/* Platform identifier */ -typedef enum { - PLATFORM_DONT_CARE, - PLATFORM_WINDOWS, - PLATFORM_WINNT -} PlatformIdentifier; - -#ifdef CURL_WINDOWS_UWP -#define curlx_verify_windows_init() Curl_nop_stmt -#else -void curlx_verify_windows_init(void); -#endif -/* This is used to verify if we are running on a specific Windows version */ -bool curlx_verify_windows_version(const unsigned int majorVersion, - const unsigned int minorVersion, - const unsigned int buildVersion, - const PlatformIdentifier platform, - const VersionCondition condition); - -#endif /* _WIN32 */ - -#endif /* HEADER_CURL_VERSION_WIN32_H */ diff --git a/vendor/curl/lib/curlx/wait.c b/vendor/curl/lib/curlx/wait.c deleted file mode 100644 index e50a0f0af..000000000 --- a/vendor/curl/lib/curlx/wait.c +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef HAVE_SELECT -#error "We cannot compile without select() support." -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#elif defined(HAVE_UNISTD_H) -#include -#endif - -#ifdef MSDOS -#include /* delay() */ -#endif - -#include "curlx/timediff.h" -#include "curlx/wait.h" - -/* - * Internal function used for waiting a specific amount of ms in - * Curl_socket_check() and Curl_poll() when no file descriptor is provided to - * wait on, being used to delay execution. Winsock select() and poll() timeout - * mechanisms need a valid socket descriptor in a not null file descriptor set - * to work. Waiting indefinitely with this function is not allowed, a zero or - * negative timeout value is returned immediately. Timeout resolution, - * accuracy, as well as maximum supported value is system dependent, neither - * factor is a critical issue for the intended use of this function in the - * library. - * - * Return values: - * -1 = system call error, or invalid timeout value - * 0 = specified timeout has elapsed, or interrupted - */ -int curlx_wait_ms(timediff_t timeout_ms) -{ - int r = 0; - - if(!timeout_ms) - return 0; - if(timeout_ms < 0) { - SET_SOCKERRNO(SOCKEINVAL); - return -1; - } -#ifdef MSDOS - delay((unsigned int)timeout_ms); -#elif defined(_WIN32) - /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */ -#if TIMEDIFF_T_MAX >= ULONG_MAX - if(timeout_ms >= ULONG_MAX) - timeout_ms = ULONG_MAX - 1; - /* do not use ULONG_MAX, because that is equal to INFINITE */ -#endif - Sleep((DWORD)timeout_ms); -#else - /* avoid using poll() for this since it behaves incorrectly with no sockets - on Apple operating systems */ - { - struct timeval pending_tv; - r = select(0, NULL, NULL, NULL, curlx_mstotv(&pending_tv, timeout_ms)); - } -#endif /* _WIN32 */ - if(r) { - if((r == -1) && (SOCKERRNO == SOCKEINTR)) - /* make EINTR from select or poll not a "lethal" error */ - r = 0; - else - r = -1; - } - return r; -} diff --git a/vendor/curl/lib/curlx/wait.h b/vendor/curl/lib/curlx/wait.h deleted file mode 100644 index 9b9c27386..000000000 --- a/vendor/curl/lib/curlx/wait.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_WAIT_H -#define HEADER_CURL_WAIT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -int curlx_wait_ms(timediff_t timeout_ms); - -#endif /* HEADER_CURL_WAIT_H */ diff --git a/vendor/curl/lib/curlx/warnless.c b/vendor/curl/lib/curlx/warnless.c deleted file mode 100644 index 5fc36ac9a..000000000 --- a/vendor/curl/lib/curlx/warnless.c +++ /dev/null @@ -1,341 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/warnless.h" - -#if defined(__INTEL_COMPILER) && defined(__unix__) - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#endif /* __INTEL_COMPILER && __unix__ */ - -#define CURL_MASK_UCHAR ((unsigned char)~0) - -#define CURL_MASK_USHORT ((unsigned short)~0) - -#define CURL_MASK_UINT ((unsigned int)~0) -#define CURL_MASK_SINT (CURL_MASK_UINT >> 1) - -#define CURL_MASK_ULONG ((unsigned long)~0) - -#define CURL_MASK_USIZE_T ((size_t)~0) -#define CURL_MASK_SSIZE_T (CURL_MASK_USIZE_T >> 1) - -/* - * unsigned long to unsigned char - */ -unsigned char curlx_ultouc(unsigned long ulnum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(ulnum <= (unsigned long)CURL_MASK_UCHAR); - return (unsigned char)(ulnum & (unsigned long)CURL_MASK_UCHAR); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * unsigned size_t to signed int - */ -int curlx_uztosi(size_t uznum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uznum <= (size_t)CURL_MASK_SINT); - return (int)(uznum & (size_t)CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * unsigned size_t to unsigned long - */ -unsigned long curlx_uztoul(size_t uznum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - -#if ULONG_MAX < SIZE_MAX - DEBUGASSERT(uznum <= (size_t)CURL_MASK_ULONG); -#endif - return (unsigned long)(uznum & (size_t)CURL_MASK_ULONG); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * unsigned size_t to unsigned int - */ -unsigned int curlx_uztoui(size_t uznum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - -#if UINT_MAX < SIZE_MAX - DEBUGASSERT(uznum <= (size_t)CURL_MASK_UINT); -#endif - return (unsigned int)(uznum & (size_t)CURL_MASK_UINT); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * signed long to signed int - */ -int curlx_sltosi(long slnum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(slnum >= 0); -#if INT_MAX < LONG_MAX - DEBUGASSERT((unsigned long)slnum <= (unsigned long)CURL_MASK_SINT); -#endif - return (int)(slnum & (long)CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * signed long to unsigned int - */ -unsigned int curlx_sltoui(long slnum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(slnum >= 0); -#if UINT_MAX < LONG_MAX - DEBUGASSERT((unsigned long)slnum <= (unsigned long)CURL_MASK_UINT); -#endif - return (unsigned int)(slnum & (long)CURL_MASK_UINT); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * signed long to unsigned short - */ -unsigned short curlx_sltous(long slnum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(slnum >= 0); - DEBUGASSERT((unsigned long)slnum <= (unsigned long)CURL_MASK_USHORT); - return (unsigned short)(slnum & (long)CURL_MASK_USHORT); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * unsigned size_t to signed ssize_t - */ -ssize_t curlx_uztosz(size_t uznum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uznum <= (size_t)CURL_MASK_SSIZE_T); - return (ssize_t)(uznum & (size_t)CURL_MASK_SSIZE_T); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * signed curl_off_t to unsigned size_t - */ -size_t curlx_sotouz(curl_off_t sonum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(sonum >= 0); - return (size_t)(sonum & (curl_off_t)CURL_MASK_USIZE_T); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * signed ssize_t to signed int - */ -int curlx_sztosi(ssize_t sznum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(sznum >= 0); -#if INT_MAX < SSIZE_MAX - DEBUGASSERT((size_t)sznum <= (size_t)CURL_MASK_SINT); -#endif - return (int)(sznum & (ssize_t)CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * unsigned int to unsigned short - */ -unsigned short curlx_uitous(unsigned int uinum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uinum <= (unsigned int)CURL_MASK_USHORT); - return (unsigned short)(uinum & (unsigned int)CURL_MASK_USHORT); - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -/* - * signed int to unsigned size_t - */ -size_t curlx_sitouz(int sinum) -{ -#ifdef __INTEL_COMPILER -#pragma warning(push) -#pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(sinum >= 0); - return (size_t)sinum; - -#ifdef __INTEL_COMPILER -#pragma warning(pop) -#endif -} - -size_t curlx_uitouz(unsigned int uinum) -{ - return (size_t)uinum; -} - -size_t curlx_sotouz_range(curl_off_t sonum, size_t uzmin, size_t uzmax) -{ - if(sonum < 0) - return uzmin; -#if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T - if(sonum > SIZE_MAX) - return uzmax; -#endif - return CURLMIN(CURLMAX((size_t)sonum, uzmin), uzmax); -} - -bool curlx_sztouz(ssize_t sznum, size_t *puznum) -{ - if(sznum < 0) { - *puznum = 0; - return FALSE; - } - *puznum = (size_t)sznum; - return TRUE; -} - -bool curlx_sotouz_fits(curl_off_t sonum, size_t *puznum) -{ - if(sonum < 0) { - *puznum = 0; - return FALSE; - } -#if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T - if(sonum > SIZE_MAX) { - *puznum = 0; - return FALSE; - } -#endif - *puznum = (size_t)sonum; - return TRUE; -} - -bool curlx_sltouz(long slnum, size_t *puznum) -{ - if(slnum < 0) { - *puznum = 0; - return FALSE; - } - /* We error in curl_setup.h if SIZEOF_LONG > SIZEOF_SIZE_T */ - *puznum = (size_t)slnum; - return TRUE; -} - -curl_off_t curlx_uztoso(size_t uznum) -{ -#if SIZEOF_SIZE_T >= SIZEOF_CURL_OFF_T - if(uznum > (size_t)CURL_OFF_T_MAX) - return CURL_OFF_T_MAX; -#endif - return (curl_off_t)uznum; -} diff --git a/vendor/curl/lib/curlx/warnless.h b/vendor/curl/lib/curlx/warnless.h deleted file mode 100644 index 3d0341e41..000000000 --- a/vendor/curl/lib/curlx/warnless.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef HEADER_CURL_WARNLESS_H -#define HEADER_CURL_WARNLESS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#define CURLX_FUNCTION_CAST(target_type, func) \ - (target_type)(void (*)(void))(func) - -unsigned char curlx_ultouc(unsigned long ulnum); - -int curlx_uztosi(size_t uznum); - -unsigned long curlx_uztoul(size_t uznum); - -unsigned int curlx_uztoui(size_t uznum); - -int curlx_sltosi(long slnum); - -unsigned int curlx_sltoui(long slnum); - -unsigned short curlx_sltous(long slnum); - -ssize_t curlx_uztosz(size_t uznum); - -size_t curlx_sotouz(curl_off_t sonum); - -int curlx_sztosi(ssize_t sznum); - -unsigned short curlx_uitous(unsigned int uinum); - -size_t curlx_sitouz(int sinum); - -size_t curlx_uitouz(unsigned int uinum); - -/* Convert a curl_off_t to fit into size_t interval [uzmin, uzmax]. - * values outside this interval give the lower/upper bound. */ -size_t curlx_sotouz_range(curl_off_t sonum, size_t uzmin, size_t uzmax); - -/* Convert a size_t to curl_off_t, return CURL_OFF_T_MAX if too large. */ -curl_off_t curlx_uztoso(size_t uznum); - -/* Convert a ssize_t to size_t, return FALSE if negative and set 0 */ -bool curlx_sztouz(ssize_t sznum, size_t *puznum); - -/* Convert a curl_off_t to size_t, return FALSE if negative or - * too large and set 0 */ -bool curlx_sotouz_fits(curl_off_t sonum, size_t *puznum); - -/* Convert a long to size_t, return FALSE if negative or too large - * and set 0 */ -bool curlx_sltouz(long slnum, size_t *puznum); - -#endif /* HEADER_CURL_WARNLESS_H */ diff --git a/vendor/curl/lib/curlx/winapi.c b/vendor/curl/lib/curlx/winapi.c deleted file mode 100644 index f025ca48c..000000000 --- a/vendor/curl/lib/curlx/winapi.c +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* - * curlx_winapi_strerror: - * Variant of curlx_strerror if the error code is definitely Windows API. - */ -#ifdef _WIN32 -#include "curlx/winapi.h" -#include "curlx/snprintf.h" -#include "curlx/strcopy.h" - -/* This is a helper function for curlx_strerror that converts Windows API error - * codes (GetLastError) to error messages. - * Returns NULL if no error message was found for error code. - */ -const char *curlx_get_winapi_error(DWORD err, char *buf, size_t buflen) -{ - char *p; - - if(!buflen) - return NULL; - - /* We return the local codepage version of the error string because if it is - output to the user's terminal, it is likely done with functions which - expect the local codepage (eg fprintf, failf, infof). */ - if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, - LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) { - *buf = '\0'; - return NULL; - } - - /* Truncate multiple lines */ - p = strchr(buf, '\n'); - if(p) { - if(p > buf && *(p - 1) == '\r') - *(p - 1) = '\0'; - else - *p = '\0'; - } - - return *buf ? buf : NULL; -} - -const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen) -{ - DWORD old_win_err = GetLastError(); - int old_errno = errno; - - if(!buflen) - return NULL; - - *buf = '\0'; - -#ifdef CURLVERBOSE - if(!curlx_get_winapi_error(err, buf, buflen)) { -#if defined(__GNUC__) && __GNUC__ >= 7 -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wformat-truncation=1" -#endif - /* some GCC compilers cause false positive warnings if we allow this - warning */ - SNPRINTF(buf, buflen, "Unknown error %lu (0x%08lx)", err, err); -#if defined(__GNUC__) && __GNUC__ >= 7 -#pragma GCC diagnostic pop -#endif - } -#else - { - const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error"; - curlx_strcopy(buf, buflen, txt, strlen(txt)); - } -#endif - - if(errno != old_errno) - errno = old_errno; - - if(old_win_err != GetLastError()) - SetLastError(old_win_err); - - return buf; -} -#endif /* _WIN32 */ diff --git a/vendor/curl/lib/curlx/winapi.h b/vendor/curl/lib/curlx/winapi.h deleted file mode 100644 index d30f5efa1..000000000 --- a/vendor/curl/lib/curlx/winapi.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURLX_WINAPI_H -#define HEADER_CURLX_WINAPI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef _WIN32 -#define WINAPI_ERROR_LEN 100 -const char *curlx_get_winapi_error(DWORD err, char *buf, size_t buflen); -const char *curlx_winapi_strerror(DWORD err, char *buf, size_t buflen); -#endif - -#endif /* HEADER_CURLX_WINAPI_H */ diff --git a/vendor/curl/lib/cw-out.c b/vendor/curl/lib/cw-out.c deleted file mode 100644 index 2af074e58..000000000 --- a/vendor/curl/lib/cw-out.c +++ /dev/null @@ -1,522 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "cfilters.h" -#include "multiif.h" -#include "sendf.h" -#include "curl_trc.h" -#include "transfer.h" -#include "cw-out.h" -#include "cw-pause.h" -#include "progress.h" - -/** - * OVERALL DESIGN of this client writer - * - * The 'cw-out' writer is supposed to be the last writer in a transfer's - * stack. It is always added when that stack is initialized. Its purpose - * is to pass BODY and HEADER bytes to the client-installed callback - * functions. - * - * These callback may return `CURL_WRITEFUNC_PAUSE` to indicate that the - * data had not been written and the whole transfer should stop receiving - * new data. Or at least, stop calling the functions. When the transfer - * is "unpaused" by the client, the previous data shall be passed as - * if nothing happened. - * - * The `cw-out` writer therefore manages buffers for bytes that could - * not be written. Data that was already in flight from the server also - * needs buffering on paused transfer when it arrives. - * - * In addition, the writer allows buffering of "small" body writes, - * so client functions are called less often. That is only enabled on a - * number of conditions. - * - * HEADER and BODY data may arrive in any order. For paused transfers, - * a list of `struct cw_out_buf` is kept for `cw_out_type` types. The - * list may be: [BODY]->[HEADER]->[BODY]->[HEADER].... - * When unpausing, this list is "played back" to the client callbacks. - * - * The amount of bytes being buffered is limited by `DYN_PAUSE_BUFFER` - * and when that is exceeded `CURLE_TOO_LARGE` is returned as error. - */ -typedef enum { - CW_OUT_NONE, - CW_OUT_BODY, - CW_OUT_BODY_0LEN, - CW_OUT_HDS -} cw_out_type; - -struct cw_out_buf { - struct cw_out_buf *next; - struct dynbuf b; - cw_out_type type; -}; - -static struct cw_out_buf *cw_out_buf_create(cw_out_type otype) -{ - struct cw_out_buf *cwbuf = curlx_calloc(1, sizeof(*cwbuf)); - if(cwbuf) { - cwbuf->type = otype; - curlx_dyn_init(&cwbuf->b, DYN_PAUSE_BUFFER); - } - return cwbuf; -} - -static void cw_out_buf_free(struct cw_out_buf *cwbuf) -{ - if(cwbuf) { - curlx_dyn_free(&cwbuf->b); - curlx_free(cwbuf); - } -} - -struct cw_out_ctx { - struct Curl_cwriter super; - struct cw_out_buf *buf; - BIT(paused); - BIT(errored); -}; - -static CURLcode cw_out_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct cw_out_ctx *ctx = writer->ctx; - (void)data; - ctx->buf = NULL; - return CURLE_OK; -} - -static void cw_out_bufs_free(struct cw_out_ctx *ctx) -{ - while(ctx->buf) { - struct cw_out_buf *next = ctx->buf->next; - cw_out_buf_free(ctx->buf); - ctx->buf = next; - } -} - -static size_t cw_out_bufs_len(struct cw_out_ctx *ctx) -{ - struct cw_out_buf *cwbuf = ctx->buf; - size_t len = 0; - while(cwbuf) { - len += curlx_dyn_len(&cwbuf->b); - cwbuf = cwbuf->next; - } - return len; -} - -static void cw_out_close(struct Curl_easy *data, struct Curl_cwriter *writer) -{ - struct cw_out_ctx *ctx = writer->ctx; - - (void)data; - cw_out_bufs_free(ctx); -} - -/** - * Return the current curl_write_callback and user_data for the buf type - */ -static void cw_get_writefunc(struct Curl_easy *data, cw_out_type otype, - curl_write_callback *pwcb, void **pwcb_data, - size_t *pmax_write, size_t *pmin_write) -{ - switch(otype) { - case CW_OUT_BODY: - case CW_OUT_BODY_0LEN: - *pwcb = data->set.fwrite_func; - *pwcb_data = data->set.out; - *pmax_write = CURL_MAX_WRITE_SIZE; - /* if we ever want buffering of BODY output, we can set `min_write` - * the preferred size. The default should always be to pass data - * to the client as it comes without delay */ - *pmin_write = 0; - break; - case CW_OUT_HDS: - *pwcb = data->set.fwrite_header ? data->set.fwrite_header : - (data->set.writeheader ? data->set.fwrite_func : NULL); - *pwcb_data = data->set.writeheader; - *pmax_write = 0; /* do not chunk-write headers, write them as they are */ - *pmin_write = 0; - break; - default: - *pwcb = NULL; - *pwcb_data = NULL; - *pmax_write = CURL_MAX_WRITE_SIZE; - *pmin_write = 0; - } -} - -static CURLcode cw_out_cb_write(struct cw_out_ctx *ctx, - struct Curl_easy *data, - curl_write_callback wcb, - void *wcb_data, - cw_out_type otype, - const char *buf, size_t blen, - size_t *pnwritten) -{ - size_t nwritten; - CURLcode result; - - NOVERBOSE((void)otype); - - DEBUGASSERT(data->conn); - *pnwritten = 0; - Curl_set_in_callback(data, TRUE); - nwritten = wcb((char *)CURL_UNCONST(buf), 1, blen, wcb_data); - Curl_set_in_callback(data, FALSE); - CURL_TRC_WRITE(data, "[OUT] wrote %zu %s bytes -> %zu", - blen, (otype == CW_OUT_HDS) ? "header" : "body", - nwritten); - if(nwritten == CURL_WRITEFUNC_PAUSE) { - if(data->conn->scheme->flags & PROTOPT_NONETWORK) { - /* Protocols that work without network cannot be paused. This is - actually only FILE:// now, and it cannot pause since the transfer is - not done using the "normal" procedure. */ - failf(data, "Write callback asked for PAUSE when not supported"); - return CURLE_WRITE_ERROR; - } - ctx->paused = TRUE; - CURL_TRC_WRITE(data, "[OUT] PAUSE requested by client"); - result = Curl_xfer_pause_recv(data, TRUE); - return result ? result : CURLE_AGAIN; - } - else if(nwritten == CURL_WRITEFUNC_ERROR) { - failf(data, "client returned ERROR on write of %zu bytes", blen); - return CURLE_WRITE_ERROR; - } - else if(nwritten != blen) { - failf(data, "Failure writing output to destination, " - "passed %zu returned %zu", blen, nwritten); - return CURLE_WRITE_ERROR; - } - *pnwritten = nwritten; - return CURLE_OK; -} - -static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx, - struct Curl_easy *data, - cw_out_type otype, - bool flush_all, - const char *buf, size_t blen, - size_t *pconsumed) -{ - curl_write_callback wcb = NULL; - void *wcb_data; - size_t max_write, min_write; - size_t wlen, nwritten = 0; - CURLcode result = CURLE_OK; - - /* If we errored once, we do not invoke the client callback again */ - if(ctx->errored) - return CURLE_WRITE_ERROR; - - /* write callbacks may get NULLed by the client between calls. */ - cw_get_writefunc(data, otype, &wcb, &wcb_data, &max_write, &min_write); - if(!wcb) { - *pconsumed = blen; - return CURLE_OK; - } - - *pconsumed = 0; - if(otype == CW_OUT_BODY_0LEN) { - DEBUGASSERT(!blen); - return cw_out_cb_write(ctx, data, wcb, wcb_data, otype, - buf, blen, &nwritten); - } - else { - while(blen && !ctx->paused) { - if(!flush_all && blen < min_write) - break; - wlen = max_write ? CURLMIN(blen, max_write) : blen; - if(otype == CW_OUT_BODY) - result = Curl_pgrs_deliver_check(data, wlen); - if(!result) - result = cw_out_cb_write(ctx, data, wcb, wcb_data, otype, - buf, wlen, &nwritten); - if(result) - return result; - if(otype == CW_OUT_BODY) - Curl_pgrs_deliver_inc(data, nwritten); - *pconsumed += nwritten; - blen -= nwritten; - buf += nwritten; - } - } - return CURLE_OK; -} - -static CURLcode cw_out_buf_flush(struct cw_out_ctx *ctx, - struct Curl_easy *data, - struct cw_out_buf *cwbuf, - bool flush_all) -{ - CURLcode result = CURLE_OK; - - if(curlx_dyn_len(&cwbuf->b) || (cwbuf->type == CW_OUT_BODY_0LEN)) { - size_t consumed; - - result = cw_out_ptr_flush(ctx, data, cwbuf->type, flush_all, - curlx_dyn_ptr(&cwbuf->b), - curlx_dyn_len(&cwbuf->b), - &consumed); - if(result && (result != CURLE_AGAIN)) - return result; - result = CURLE_OK; - - if(consumed) { - if(consumed == curlx_dyn_len(&cwbuf->b)) { - curlx_dyn_free(&cwbuf->b); - } - else { - DEBUGASSERT(consumed < curlx_dyn_len(&cwbuf->b)); - result = curlx_dyn_tail(&cwbuf->b, - curlx_dyn_len(&cwbuf->b) - consumed); - if(result) - return result; - } - } - } - return result; -} - -static CURLcode cw_out_flush_chain(struct cw_out_ctx *ctx, - struct Curl_easy *data, - struct cw_out_buf **pcwbuf, - bool flush_all) -{ - struct cw_out_buf *cwbuf = *pcwbuf; - CURLcode result; - - if(!cwbuf) - return CURLE_OK; - if(ctx->paused) - return CURLE_OK; - - /* write the end of the chain until it blocks or gets empty */ - while(cwbuf->next) { - struct cw_out_buf **plast = &cwbuf->next; - while((*plast)->next) - plast = &(*plast)->next; - result = cw_out_flush_chain(ctx, data, plast, flush_all); - if(result) - return result; - if(*plast) { - /* could not write last, paused again? */ - DEBUGASSERT(ctx->paused); - return CURLE_OK; - } - } - - result = cw_out_buf_flush(ctx, data, cwbuf, flush_all); - if(result) - return result; - if(!curlx_dyn_len(&cwbuf->b)) { - cw_out_buf_free(cwbuf); - *pcwbuf = NULL; - } - return CURLE_OK; -} - -static CURLcode cw_out_append(struct cw_out_ctx *ctx, - struct Curl_easy *data, - cw_out_type otype, - const char *buf, size_t blen) -{ - CURL_TRC_WRITE(data, "[OUT] paused, buffering %zu more bytes (%zu/%d)", - blen, cw_out_bufs_len(ctx), DYN_PAUSE_BUFFER); - if(cw_out_bufs_len(ctx) + blen > DYN_PAUSE_BUFFER) { - failf(data, "pause buffer not large enough -> CURLE_TOO_LARGE"); - return CURLE_TOO_LARGE; - } - - /* if we do not have a buffer, or it is of another type, make a new one. - * For CW_OUT_HDS always make a new one, so we "replay" headers exactly - * as they came in */ - if(!ctx->buf || (ctx->buf->type != otype) || (otype == CW_OUT_HDS)) { - struct cw_out_buf *cwbuf = cw_out_buf_create(otype); - if(!cwbuf) - return CURLE_OUT_OF_MEMORY; - cwbuf->next = ctx->buf; - ctx->buf = cwbuf; - } - DEBUGASSERT(ctx->buf && (ctx->buf->type == otype)); - return curlx_dyn_addn(&ctx->buf->b, buf, blen); -} - -static CURLcode cw_out_do_write(struct cw_out_ctx *ctx, - struct Curl_easy *data, - cw_out_type otype, - bool flush_all, - const char *buf, size_t blen) -{ - CURLcode result = CURLE_OK; - - /* if we have buffered data and it is a different type than what - * we are writing now, try to flush all */ - if(ctx->buf && ctx->buf->type != otype) { - result = cw_out_flush_chain(ctx, data, &ctx->buf, TRUE); - if(result) - goto out; - } - - if(ctx->buf) { - /* still have buffered data, append and flush */ - result = cw_out_append(ctx, data, otype, buf, blen); - if(result) - goto out; - result = cw_out_flush_chain(ctx, data, &ctx->buf, flush_all); - if(result) - goto out; - } - else { - /* nothing buffered, try direct write */ - size_t consumed; - result = cw_out_ptr_flush(ctx, data, otype, flush_all, - buf, blen, &consumed); - if(result && (result != CURLE_AGAIN)) - return result; - result = CURLE_OK; - if(consumed < blen) { - /* did not write all, append the rest */ - result = cw_out_append(ctx, data, otype, - buf + consumed, blen - consumed); - if(result) - goto out; - } - } - -out: - if(result) { - /* We do not want to invoked client callbacks a second time after - * encountering an error. See issue #13337 */ - ctx->errored = TRUE; - cw_out_bufs_free(ctx); - } - return result; -} - -static CURLcode cw_out_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t blen) -{ - struct cw_out_ctx *ctx = writer->ctx; - CURLcode result; - bool flush_all = !!(type & CLIENTWRITE_EOS); - - if((type & CLIENTWRITE_BODY) || - ((type & CLIENTWRITE_HEADER) && data->set.include_header)) { - cw_out_type otype = (!blen && (type & CLIENTWRITE_0LEN)) ? - CW_OUT_BODY_0LEN : CW_OUT_BODY; - result = cw_out_do_write(ctx, data, otype, flush_all, buf, blen); - if(result) - return result; - } - - if(type & (CLIENTWRITE_HEADER | CLIENTWRITE_INFO)) { - result = cw_out_do_write(ctx, data, CW_OUT_HDS, flush_all, buf, blen); - if(result) - return result; - } - - return CURLE_OK; -} - -const struct Curl_cwtype Curl_cwt_out = { - "cw-out", - NULL, - cw_out_init, - cw_out_write, - cw_out_close, - sizeof(struct cw_out_ctx) -}; - -bool Curl_cw_out_is_paused(struct Curl_easy *data) -{ - struct Curl_cwriter *cw_out; - struct cw_out_ctx *ctx; - - cw_out = Curl_cwriter_get_by_type(data, &Curl_cwt_out); - if(!cw_out) - return FALSE; - - ctx = (struct cw_out_ctx *)cw_out; - return (bool)ctx->paused; -} - -static CURLcode cw_out_flush(struct Curl_easy *data, - struct Curl_cwriter *cw_out, - bool flush_all) -{ - struct cw_out_ctx *ctx = (struct cw_out_ctx *)cw_out; - CURLcode result = CURLE_OK; - - if(ctx->errored) - return CURLE_WRITE_ERROR; - if(ctx->paused) - return CURLE_OK; /* not doing it */ - - result = cw_out_flush_chain(ctx, data, &ctx->buf, flush_all); - if(result) { - ctx->errored = TRUE; - cw_out_bufs_free(ctx); - return result; - } - return result; -} - -CURLcode Curl_cw_out_unpause(struct Curl_easy *data) -{ - struct Curl_cwriter *cw_out; - CURLcode result = CURLE_OK; - - cw_out = Curl_cwriter_get_by_type(data, &Curl_cwt_out); - if(cw_out) { - struct cw_out_ctx *ctx = (struct cw_out_ctx *)cw_out; - CURL_TRC_WRITE(data, "[OUT] unpause"); - ctx->paused = FALSE; - result = Curl_cw_pause_flush(data); - if(!result) - result = cw_out_flush(data, cw_out, FALSE); - } - return result; -} - -CURLcode Curl_cw_out_done(struct Curl_easy *data) -{ - struct Curl_cwriter *cw_out; - CURLcode result = CURLE_OK; - - cw_out = Curl_cwriter_get_by_type(data, &Curl_cwt_out); - if(cw_out) { - CURL_TRC_WRITE(data, "[OUT] done"); - result = Curl_cw_pause_flush(data); - if(!result) - result = cw_out_flush(data, cw_out, TRUE); - } - return result; -} diff --git a/vendor/curl/lib/cw-out.h b/vendor/curl/lib/cw-out.h deleted file mode 100644 index 7de6524bc..000000000 --- a/vendor/curl/lib/cw-out.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef HEADER_CURL_CW_OUT_H -#define HEADER_CURL_CW_OUT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_easy; - -/** - * The client writer type "cw-out" that does the actual writing to - * the client callbacks. Intended to be the last installed in the - * client writer stack of a transfer. - */ -extern const struct Curl_cwtype Curl_cwt_out; - -/** - * Return TRUE iff 'cw-out' client write has paused data. - */ -bool Curl_cw_out_is_paused(struct Curl_easy *data); - -/** - * Flush any buffered date to the client, chunk collation still applies. - */ -CURLcode Curl_cw_out_unpause(struct Curl_easy *data); - -/** - * Mark EndOfStream reached and flush ALL data to the client. - */ -CURLcode Curl_cw_out_done(struct Curl_easy *data); - -#endif /* HEADER_CURL_CW_OUT_H */ diff --git a/vendor/curl/lib/cw-pause.c b/vendor/curl/lib/cw-pause.c deleted file mode 100644 index ec611879d..000000000 --- a/vendor/curl/lib/cw-pause.c +++ /dev/null @@ -1,225 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "bufq.h" -#include "cfilters.h" -#include "sendf.h" -#include "curl_trc.h" -#include "cw-pause.h" - - -/* body dynbuf sizes */ -#define CW_PAUSE_BUF_CHUNK (16 * 1024) -/* when content decoding, write data in chunks */ -#define CW_PAUSE_DEC_WRITE_CHUNK 4096 - -struct cw_pause_buf { - struct cw_pause_buf *next; - struct bufq b; - int type; -}; - -static struct cw_pause_buf *cw_pause_buf_create(int type, size_t buflen) -{ - struct cw_pause_buf *cwbuf = curlx_calloc(1, sizeof(*cwbuf)); - if(cwbuf) { - cwbuf->type = type; - if(type & CLIENTWRITE_BODY) - Curl_bufq_init2(&cwbuf->b, CW_PAUSE_BUF_CHUNK, 1, - (BUFQ_OPT_SOFT_LIMIT | BUFQ_OPT_NO_SPARES)); - else - Curl_bufq_init(&cwbuf->b, buflen, 1); - } - return cwbuf; -} - -static void cw_pause_buf_free(struct cw_pause_buf *cwbuf) -{ - if(cwbuf) { - Curl_bufq_free(&cwbuf->b); - curlx_free(cwbuf); - } -} - -struct cw_pause_ctx { - struct Curl_cwriter super; - struct cw_pause_buf *buf; - size_t buf_total; -}; - -static CURLcode cw_pause_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct cw_pause_ctx *ctx = writer->ctx; - (void)data; - ctx->buf = NULL; - return CURLE_OK; -} - -static void cw_pause_bufs_free(struct cw_pause_ctx *ctx) -{ - while(ctx->buf) { - struct cw_pause_buf *next = ctx->buf->next; - cw_pause_buf_free(ctx->buf); - ctx->buf = next; - } -} - -static void cw_pause_close(struct Curl_easy *data, struct Curl_cwriter *writer) -{ - struct cw_pause_ctx *ctx = writer->ctx; - - (void)data; - cw_pause_bufs_free(ctx); -} - -static CURLcode cw_pause_flush(struct Curl_easy *data, - struct Curl_cwriter *cw_pause) -{ - struct cw_pause_ctx *ctx = (struct cw_pause_ctx *)cw_pause; - bool decoding = Curl_cwriter_is_content_decoding(data); - CURLcode result = CURLE_OK; - - /* write the end of the chain until it blocks or gets empty */ - while(ctx->buf && !Curl_cwriter_is_paused(data)) { - struct cw_pause_buf **plast = &ctx->buf; - size_t blen, wlen = 0; - const unsigned char *buf = NULL; - - while((*plast)->next) /* got to last in list */ - plast = &(*plast)->next; - if(Curl_bufq_peek(&(*plast)->b, &buf, &blen)) { - wlen = (decoding && ((*plast)->type & CLIENTWRITE_BODY)) ? - CURLMIN(blen, CW_PAUSE_DEC_WRITE_CHUNK) : blen; - result = Curl_cwriter_write(data, cw_pause->next, (*plast)->type, - (const char *)buf, wlen); - CURL_TRC_WRITE(data, "[PAUSE] flushed %zu/%zu bytes, type=%x -> %d", - wlen, ctx->buf_total, (*plast)->type, result); - Curl_bufq_skip(&(*plast)->b, wlen); - DEBUGASSERT(ctx->buf_total >= wlen); - ctx->buf_total -= wlen; - if(result) - return result; - } - else if((*plast)->type & CLIENTWRITE_EOS) { - result = Curl_cwriter_write(data, cw_pause->next, (*plast)->type, - (const char *)buf, 0); - CURL_TRC_WRITE(data, "[PAUSE] flushed 0/%zu bytes, type=%x -> %d", - ctx->buf_total, (*plast)->type, result); - } - - if(Curl_bufq_is_empty(&(*plast)->b)) { - cw_pause_buf_free(*plast); - *plast = NULL; - } - } - return result; -} - -static CURLcode cw_pause_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t blen) -{ - struct cw_pause_ctx *ctx = writer->ctx; - CURLcode result = CURLE_OK; - size_t wlen = 0; - bool decoding = Curl_cwriter_is_content_decoding(data); - - if(ctx->buf && !Curl_cwriter_is_paused(data)) { - result = cw_pause_flush(data, writer); - if(result) - return result; - } - - while(!ctx->buf && !Curl_cwriter_is_paused(data)) { - int wtype = type; - DEBUGASSERT(!ctx->buf); - /* content decoding might blow up size considerably, write smaller - * chunks to make pausing need buffer less. */ - wlen = (decoding && (type & CLIENTWRITE_BODY)) ? - CURLMIN(blen, CW_PAUSE_DEC_WRITE_CHUNK) : blen; - if(wlen < blen) - wtype &= ~CLIENTWRITE_EOS; - result = Curl_cwriter_write(data, writer->next, wtype, buf, wlen); - CURL_TRC_WRITE(data, "[PAUSE] writing %zu/%zu bytes of type %x -> %d", - wlen, blen, wtype, result); - if(result) - return result; - buf += wlen; - blen -= wlen; - if(!blen) - return result; - } - - do { - size_t nwritten = 0; - if(ctx->buf && (ctx->buf->type == type) && (type & CLIENTWRITE_BODY)) { - /* same type and body, append to current buffer which has a soft - * limit and should take everything up to OOM. */ - result = Curl_bufq_cwrite(&ctx->buf->b, buf, blen, &nwritten); - } - else { - /* Need a new buf, type changed */ - struct cw_pause_buf *cwbuf = cw_pause_buf_create(type, blen); - if(!cwbuf) - return CURLE_OUT_OF_MEMORY; - cwbuf->next = ctx->buf; - ctx->buf = cwbuf; - result = Curl_bufq_cwrite(&ctx->buf->b, buf, blen, &nwritten); - } - CURL_TRC_WRITE(data, "[PAUSE] buffer %zu more bytes of type %x, " - "total=%zu -> %d", nwritten, type, ctx->buf_total + wlen, - result); - if(result) - return result; - buf += nwritten; - blen -= nwritten; - ctx->buf_total += nwritten; - } while(blen); - - return result; -} - -const struct Curl_cwtype Curl_cwt_pause = { - "cw-pause", - NULL, - cw_pause_init, - cw_pause_write, - cw_pause_close, - sizeof(struct cw_pause_ctx) -}; - -CURLcode Curl_cw_pause_flush(struct Curl_easy *data) -{ - struct Curl_cwriter *cw_pause; - CURLcode result = CURLE_OK; - - cw_pause = Curl_cwriter_get_by_type(data, &Curl_cwt_pause); - if(cw_pause) - result = cw_pause_flush(data, cw_pause); - - return result; -} diff --git a/vendor/curl/lib/cw-pause.h b/vendor/curl/lib/cw-pause.h deleted file mode 100644 index 544cbfa57..000000000 --- a/vendor/curl/lib/cw-pause.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef HEADER_CURL_CW_PAUSE_H -#define HEADER_CURL_CW_PAUSE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_easy; - -/** - * The client writer type "cw-pause" that buffers writes for - * paused transfer writes. - */ -extern const struct Curl_cwtype Curl_cwt_pause; - -CURLcode Curl_cw_pause_flush(struct Curl_easy *data); - -#endif /* HEADER_CURL_CW_PAUSE_H */ diff --git a/vendor/curl/lib/dict.c b/vendor/curl/lib/dict.c deleted file mode 100644 index 7b83c6cff..000000000 --- a/vendor/curl/lib/dict.c +++ /dev/null @@ -1,297 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "dict.h" - -#ifndef CURL_DISABLE_DICT - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#elif defined(HAVE_UNISTD_H) -#include -#endif - -#include "transfer.h" -#include "curl_trc.h" -#include "escape.h" - -#define DICT_MATCH "/MATCH:" -#define DICT_MATCH2 "/M:" -#define DICT_MATCH3 "/FIND:" -#define DICT_DEFINE "/DEFINE:" -#define DICT_DEFINE2 "/D:" -#define DICT_DEFINE3 "/LOOKUP:" - -#define DYN_DICT_WORD 10000 -static char *unescape_word(const char *input) -{ - struct dynbuf out; - const char *ptr; - CURLcode result = CURLE_OK; - curlx_dyn_init(&out, DYN_DICT_WORD); - - /* According to RFC2229 section 2.2, these letters need to be escaped with - \[letter] */ - for(ptr = input; *ptr; ptr++) { - char ch = *ptr; - if((ch <= 32) || (ch == 127) || - (ch == '\'') || (ch == '\"') || (ch == '\\')) - result = curlx_dyn_addn(&out, "\\", 1); - if(!result) - result = curlx_dyn_addn(&out, ptr, 1); - if(result) - return NULL; - } - return curlx_dyn_ptr(&out); -} - -/* sendf() sends formatted data to the server */ -static CURLcode sendf(struct Curl_easy *data, - const char *fmt, ...) CURL_PRINTF(2, 3); - -static CURLcode sendf(struct Curl_easy *data, const char *fmt, ...) -{ - size_t bytes_written; - size_t write_len; - CURLcode result = CURLE_OK; - char *s; - char *sptr; - va_list ap; - va_start(ap, fmt); - s = curl_mvaprintf(fmt, ap); /* returns an allocated string */ - va_end(ap); - if(!s) - return CURLE_OUT_OF_MEMORY; /* failure */ - - bytes_written = 0; - write_len = strlen(s); - sptr = s; - - for(;;) { - /* Write the buffer to the socket */ - result = Curl_xfer_send(data, sptr, write_len, FALSE, &bytes_written); - - if(result) - break; - - Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written); - - if(bytes_written != write_len) { - /* if not all was written at once, we must advance the pointer, decrease - the size left and try again! */ - write_len -= bytes_written; - sptr += bytes_written; - } - else - break; - } - - curlx_free(s); /* free the output string */ - - return result; -} - -static CURLcode dict_do(struct Curl_easy *data, bool *done) -{ - char *word; - char *eword = NULL; - char *ppath; - char *database = NULL; - char *strategy = NULL; - char *nthdef = NULL; /* This is not part of the protocol, but required - by RFC 2229 */ - CURLcode result; - - char *path; - - *done = TRUE; /* unconditionally */ - - /* url-decode path before further evaluation */ - result = Curl_urldecode(data->state.up.path, 0, &path, NULL, REJECT_CTRL); - if(result) - return result; - - if(curl_strnequal(path, DICT_MATCH, sizeof(DICT_MATCH) - 1) || - curl_strnequal(path, DICT_MATCH2, sizeof(DICT_MATCH2) - 1) || - curl_strnequal(path, DICT_MATCH3, sizeof(DICT_MATCH3) - 1)) { - - word = strchr(path, ':'); - if(word) { - word++; - database = strchr(word, ':'); - if(database) { - *database++ = (char)0; - strategy = strchr(database, ':'); - if(strategy) { - *strategy++ = (char)0; - nthdef = strchr(strategy, ':'); - if(nthdef) { - *nthdef = (char)0; - } - } - } - } - - if(!word || (*word == (char)0)) { - infof(data, "lookup word is missing"); - } - eword = unescape_word((!word || (*word == (char)0)) ? "default" : word); - if(!eword) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - result = sendf(data, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "MATCH " - "%s " /* database */ - "%s " /* strategy */ - "%s\r\n" /* word */ - "QUIT\r\n", - (!database || (*database == (char)0)) ? "!" : database, - (!strategy || (*strategy == (char)0)) ? "." : strategy, - eword); - - if(result) { - failf(data, "Failed sending DICT request"); - goto error; - } - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); - } - else if(curl_strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE) - 1) || - curl_strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2) - 1) || - curl_strnequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3) - 1)) { - - word = strchr(path, ':'); - if(word) { - word++; - database = strchr(word, ':'); - if(database) { - *database++ = (char)0; - nthdef = strchr(database, ':'); - if(nthdef) { - *nthdef = (char)0; - } - } - } - - if(!word || (*word == (char)0)) { - infof(data, "lookup word is missing"); - } - eword = unescape_word((!word || (*word == (char)0)) ? "default" : word); - if(!eword) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - result = sendf(data, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "DEFINE " - "%s " /* database */ - "%s\r\n" /* word */ - "QUIT\r\n", - (!database || (*database == (char)0)) ? "!" : database, - eword); - - if(result) { - failf(data, "Failed sending DICT request"); - goto error; - } - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); - } - else { - - ppath = strchr(path, '/'); - if(ppath) { - int i; - - ppath++; - for(i = 0; ppath[i]; i++) { - if(ppath[i] == ':') - ppath[i] = ' '; - } - result = sendf(data, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "%s\r\n" - "QUIT\r\n", ppath); - if(result) { - failf(data, "Failed sending DICT request"); - goto error; - } - - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); - } - } - -error: - curlx_free(eword); - curlx_free(path); - return result; -} - -/* - * DICT protocol - */ -const struct Curl_protocol Curl_protocol_dict = { - ZERO_NULL, /* setup_connection */ - dict_do, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - ZERO_NULL, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* CURL_DISABLE_DICT */ diff --git a/vendor/curl/lib/dict.h b/vendor/curl/lib/dict.h deleted file mode 100644 index 5bdfcff81..000000000 --- a/vendor/curl/lib/dict.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_DICT_H -#define HEADER_CURL_DICT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_DICT -extern const struct Curl_protocol Curl_protocol_dict; -#endif - -#endif /* HEADER_CURL_DICT_H */ diff --git a/vendor/curl/lib/dnscache.c b/vendor/curl/lib/dnscache.c deleted file mode 100644 index 20f6b2171..000000000 --- a/vendor/curl/lib/dnscache.c +++ /dev/null @@ -1,873 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "curl_addrinfo.h" -#include "curl_share.h" -#include "curl_trc.h" -#include "dnscache.h" -#include "hash.h" -#include "hostip.h" -#include "httpsrr.h" -#include "progress.h" -#include "rand.h" -#include "strcase.h" -#include "curlx/inet_ntop.h" -#include "curlx/inet_pton.h" -#include "curlx/strcopy.h" -#include "curlx/strparse.h" - -#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */ - -#define MAX_DNS_CACHE_SIZE 29999 - -static void dnscache_entry_free(struct Curl_dns_entry *dns) -{ - Curl_freeaddrinfo(dns->addr); -#ifdef USE_HTTPSRR - if(dns->hinfo) { - Curl_httpsrr_cleanup(dns->hinfo); - curlx_free(dns->hinfo); - } -#endif - curlx_free(dns); -} - -/* - * Create a hostcache id string for the provided host + port, to be used by - * the DNS caching. Without alloc. Return length of the id string. - */ -static size_t create_dnscache_id(const char *name, - size_t nlen, /* 0 or actual name length */ - uint16_t port, char *ptr, size_t buflen) -{ - size_t len = nlen ? nlen : strlen(name); - DEBUGASSERT(buflen >= MAX_HOSTCACHE_LEN); - if(len > (buflen - 7)) - len = buflen - 7; - /* store and lower case the name */ - Curl_strntolower(ptr, name, len); - return curl_msnprintf(&ptr[len], 7, ":%u", port) + len; -} - -struct dnscache_prune_data { - struct curltime now; - timediff_t oldest_ms; /* oldest time in cache not pruned. */ - timediff_t max_age_ms; -}; - -/* - * This function is set as a callback to be called for every entry in the DNS - * cache when we want to prune old unused entries. - * - * Returning non-zero means remove the entry, return 0 to keep it in the - * cache. - */ -static int dnscache_entry_is_stale(void *datap, void *hc) -{ - struct dnscache_prune_data *prune = (struct dnscache_prune_data *)datap; - struct Curl_dns_entry *dns = (struct Curl_dns_entry *)hc; - - if(dns->timestamp.tv_sec || dns->timestamp.tv_usec) { - /* get age in milliseconds */ - timediff_t age = curlx_ptimediff_ms(&prune->now, &dns->timestamp); - if(!dns->addr) - age *= 2; /* negative entries age twice as fast */ - if(age >= prune->max_age_ms) - return TRUE; - if(age > prune->oldest_ms) - prune->oldest_ms = age; - } - return FALSE; -} - -/* - * Prune the DNS cache. This assumes that a lock has already been taken. - * Returns the 'age' of the oldest still kept entry - in milliseconds. - */ -static timediff_t dnscache_prune(struct Curl_hash *hostcache, - timediff_t cache_timeout_ms, - struct curltime now) -{ - struct dnscache_prune_data user; - - user.max_age_ms = cache_timeout_ms; - user.now = now; - user.oldest_ms = 0; - - Curl_hash_clean_with_criterium(hostcache, - (void *)&user, - dnscache_entry_is_stale); - - return user.oldest_ms; -} - -static struct Curl_dnscache *dnscache_get(struct Curl_easy *data) -{ - if(data->share && data->share->specifier & (1 << CURL_LOCK_DATA_DNS)) - return &data->share->dnscache; - if(data->multi) - return &data->multi->dnscache; - return NULL; -} - -static void dnscache_lock(struct Curl_easy *data, - struct Curl_dnscache *dnscache) -{ - if(data->share && dnscache == &data->share->dnscache) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); -} - -static void dnscache_unlock(struct Curl_easy *data, - struct Curl_dnscache *dnscache) -{ - if(data->share && dnscache == &data->share->dnscache) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); -} - -/* - * Library-wide function for pruning the DNS cache. This function takes and - * returns the appropriate locks. - */ -void Curl_dnscache_prune(struct Curl_easy *data) -{ - struct Curl_dnscache *dnscache = dnscache_get(data); - /* the timeout may be set -1 (forever) */ - timediff_t timeout_ms = data->set.dns_cache_timeout_ms; - - if(!dnscache || (timeout_ms == -1)) - /* NULL hostcache means we cannot do it */ - return; - - dnscache_lock(data, dnscache); - - do { - /* Remove outdated and unused entries from the hostcache */ - timediff_t oldest_ms = - dnscache_prune(&dnscache->entries, timeout_ms, *Curl_pgrs_now(data)); - - if(Curl_hash_count(&dnscache->entries) > MAX_DNS_CACHE_SIZE) - /* prune the ones over half this age */ - timeout_ms = oldest_ms / 2; - else - break; - - /* if the cache size is still too big, use the oldest age as new prune - limit */ - } while(timeout_ms); - - dnscache_unlock(data, dnscache); -} - -void Curl_dnscache_clear(struct Curl_easy *data) -{ - struct Curl_dnscache *dnscache = dnscache_get(data); - if(dnscache) { - dnscache_lock(data, dnscache); - Curl_hash_clean(&dnscache->entries); - dnscache_unlock(data, dnscache); - } -} - -/* lookup address, returns entry if found and not stale */ -static CURLcode fetch_addr(struct Curl_easy *data, - struct Curl_dnscache *dnscache, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - struct Curl_dns_entry **pdns) -{ - struct Curl_dns_entry *dns = NULL; - char entry_id[MAX_HOSTCACHE_LEN]; - size_t entry_len; - CURLcode result = CURLE_OK; - - *pdns = NULL; - if(!dnscache) - return CURLE_OK; - - /* Create an entry id, based upon the hostname and port */ - entry_len = create_dnscache_id(hostname, 0, port, - entry_id, sizeof(entry_id)); - - /* See if it is already in our dns cache */ - dns = Curl_hash_pick(&dnscache->entries, entry_id, entry_len + 1); - - /* No entry found in cache, check if we might have a wildcard entry */ - if(!dns && data->state.wildcard_resolve) { - entry_len = create_dnscache_id("*", 1, port, entry_id, sizeof(entry_id)); - - /* See if it is already in our dns cache */ - dns = Curl_hash_pick(&dnscache->entries, entry_id, entry_len + 1); - } - - if(dns && (data->set.dns_cache_timeout_ms != -1)) { - /* See whether the returned entry is stale. Done before we release lock */ - struct dnscache_prune_data user; - - user.now = *Curl_pgrs_now(data); - user.max_age_ms = data->set.dns_cache_timeout_ms; - user.oldest_ms = 0; - - if(dnscache_entry_is_stale(&user, dns)) { - infof(data, "Hostname in DNS cache was stale, zapped"); - dns = NULL; /* the memory deallocation is being handled by the hash */ - Curl_hash_delete(&dnscache->entries, entry_id, entry_len + 1); - } - } - - if(dns) { - if((dns->dns_queries & dns_queries) != dns_queries) { - /* The entry does not cover all wanted DNS queries, a miss. */ - dns = NULL; - } - else if(!(dns->dns_responses & dns_queries)) { - /* The entry has no responses for the wanted DNS queries. */ - CURL_TRC_DNS(data, "cache entry does not have type=%s addresses", - Curl_resolv_query_str(dns_queries)); - dns = NULL; - result = CURLE_COULDNT_RESOLVE_HOST; - } - } - - if(dns && !dns->addr) { /* negative entry */ - dns = NULL; - result = CURLE_COULDNT_RESOLVE_HOST; - } - *pdns = dns; - return result; -} - -/* - * Curl_dnscache_get() fetches a 'Curl_dns_entry' already in the DNS cache. - * - * Curl_resolv() checks initially and multi_runsingle() checks each time - * it discovers the handle in the state WAITRESOLVE whether the hostname - * has already been resolved and the address has already been stored in - * the DNS cache. This short circuits waiting for a lot of pending - * lookups for the same hostname requested by different handles. - * - * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. - * - * The returned data *MUST* be "released" with Curl_dns_entry_unlink() after - * use, or we will leak memory! - */ -CURLcode Curl_dnscache_get(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - struct Curl_dns_entry **pentry) -{ - struct Curl_dnscache *dnscache = dnscache_get(data); - struct Curl_dns_entry *dns = NULL; - CURLcode result = CURLE_OK; - - dnscache_lock(data, dnscache); - result = fetch_addr(data, dnscache, dns_queries, hostname, port, &dns); - if(!result && dns) - dns->refcount++; /* we pass out a reference */ - else if(result) { - DEBUGASSERT(!dns); - dns = NULL; - } - dnscache_unlock(data, dnscache); - - *pentry = dns; - return result; -} - -#ifndef CURL_DISABLE_SHUFFLE_DNS -/* - * Return # of addresses in a Curl_addrinfo struct - */ -static int num_addresses(const struct Curl_addrinfo *addr) -{ - int i = 0; - while(addr) { - addr = addr->ai_next; - i++; - } - return i; -} - -/* - * dns_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo' - * struct by re-linking its linked list. - * - * The addr argument should be the address of a pointer to the head node of a - * `Curl_addrinfo` list and it will be modified to point to the new head after - * shuffling. - * - * Not declared static only to make it easy to use in a unit test! - * - * @unittest 1608 - */ -UNITTEST CURLcode dns_shuffle_addr(struct Curl_easy *data, - struct Curl_addrinfo **addr); -UNITTEST CURLcode dns_shuffle_addr(struct Curl_easy *data, - struct Curl_addrinfo **addr) -{ - CURLcode result = CURLE_OK; - const int num_addrs = num_addresses(*addr); - - if(num_addrs > 1) { - struct Curl_addrinfo **nodes; - CURL_TRC_DNS(data, "Shuffling %i addresses", num_addrs); - - nodes = curlx_malloc(num_addrs * sizeof(*nodes)); - if(nodes) { - int i; - unsigned int *rnd; - const size_t rnd_size = num_addrs * sizeof(*rnd); - - /* build a plain array of Curl_addrinfo pointers */ - nodes[0] = *addr; - for(i = 1; i < num_addrs; i++) { - nodes[i] = nodes[i - 1]->ai_next; - } - - rnd = curlx_malloc(rnd_size); - if(rnd) { - /* Fisher-Yates shuffle */ - if(Curl_rand(data, (unsigned char *)rnd, rnd_size) == CURLE_OK) { - struct Curl_addrinfo *swap_tmp; - for(i = num_addrs - 1; i > 0; i--) { - swap_tmp = nodes[rnd[i] % (unsigned int)(i + 1)]; - nodes[rnd[i] % (unsigned int)(i + 1)] = nodes[i]; - nodes[i] = swap_tmp; - } - - /* relink list in the new order */ - for(i = 1; i < num_addrs; i++) { - nodes[i - 1]->ai_next = nodes[i]; - } - - nodes[num_addrs - 1]->ai_next = NULL; - *addr = nodes[0]; - } - curlx_free(rnd); - } - else - result = CURLE_OUT_OF_MEMORY; - curlx_free(nodes); - } - else - result = CURLE_OUT_OF_MEMORY; - } - return result; -} -#endif - -static bool dnscache_ai_has_family(struct Curl_addrinfo *ai, - int ai_family) -{ - for(; ai; ai = ai->ai_next) { - if(ai->ai_family == ai_family) - return TRUE; - } - return FALSE; -} - -static struct Curl_dns_entry *dnscache_entry_create( - struct Curl_easy *data, - uint8_t dns_queries, - struct Curl_addrinfo **paddr1, - struct Curl_addrinfo **paddr2, - const char *hostname, - size_t hostlen, - uint16_t port, - bool permanent) -{ - struct Curl_dns_entry *dns = NULL; - - /* Create a new cache entry, struct already has the hostname NUL */ - dns = curlx_calloc(1, sizeof(struct Curl_dns_entry) + hostlen); - if(!dns) - goto out; - - dns->refcount = 1; /* the cache has the first reference */ - dns->dns_queries = dns_queries; - dns->port = port; - if(hostlen) - memcpy(dns->hostname, hostname, hostlen); - - if(permanent) { - dns->timestamp.tv_sec = 0; /* an entry that never goes stale */ - dns->timestamp.tv_usec = 0; /* an entry that never goes stale */ - } - else { - dns->timestamp = *Curl_pgrs_now(data); - } - - /* Take the given address lists into the entry */ - if(paddr1 && *paddr1) { - dns->addr = *paddr1; - *paddr1 = NULL; - } - if(paddr2 && *paddr2) { - struct Curl_addrinfo **phead = &dns->addr; - while(*phead) - phead = &(*phead)->ai_next; - *phead = *paddr2; - *paddr2 = NULL; - } - - if((dns_queries & CURL_DNSQ_A) && - dnscache_ai_has_family(dns->addr, PF_INET)) - dns->dns_responses |= CURL_DNSQ_A; - -#ifdef USE_IPV6 - if((dns_queries & CURL_DNSQ_AAAA) && - dnscache_ai_has_family(dns->addr, PF_INET6)) - dns->dns_responses |= CURL_DNSQ_AAAA; -#endif /* USE_IPV6 */ - -#ifndef CURL_DISABLE_SHUFFLE_DNS - /* shuffle addresses if requested */ - if(data->set.dns_shuffle_addresses && dns->addr) { - CURLcode result = dns_shuffle_addr(data, &dns->addr); - if(result) { - /* free without lock, we are the sole owner */ - dnscache_entry_free(dns); - dns = NULL; - goto out; - } - } -#else - (void)data; -#endif - -out: - if(paddr1 && *paddr1) { - Curl_freeaddrinfo(*paddr1); - *paddr1 = NULL; - } - if(paddr2 && *paddr2) { - Curl_freeaddrinfo(*paddr2); - *paddr2 = NULL; - } - return dns; -} - -struct Curl_dns_entry *Curl_dnscache_mk_entry(struct Curl_easy *data, - uint8_t dns_queries, - struct Curl_addrinfo **paddr, - const char *hostname, - uint16_t port) -{ - return dnscache_entry_create(data, dns_queries, paddr, NULL, hostname, - hostname ? strlen(hostname) : 0, - port, FALSE); -} - -struct Curl_dns_entry *Curl_dnscache_mk_entry2(struct Curl_easy *data, - uint8_t dns_queries, - struct Curl_addrinfo **paddr1, - struct Curl_addrinfo **paddr2, - const char *hostname, - uint16_t port) -{ - return dnscache_entry_create(data, dns_queries, paddr1, paddr2, hostname, - hostname ? strlen(hostname) : 0, - port, FALSE); -} - -#ifdef USE_HTTPSRR -void Curl_dns_entry_set_https_rr(struct Curl_dns_entry *dns, - struct Curl_https_rrinfo *hinfo) -{ - /* only do this when this is the only reference */ - DEBUGASSERT(dns->refcount == 1); - /* it should have been in the queries */ - DEBUGASSERT(dns->dns_queries & CURL_DNSQ_HTTPS); - if(dns->hinfo) { - Curl_httpsrr_cleanup(dns->hinfo); - curlx_free(dns->hinfo); - } - dns->hinfo = hinfo; - dns->dns_responses |= CURL_DNSQ_HTTPS; -} -#endif /* USE_HTTPSRR */ - -static struct Curl_dns_entry *dnscache_add_addr(struct Curl_easy *data, - struct Curl_dnscache *dnscache, - uint8_t dns_queries, - struct Curl_addrinfo **paddr, - const char *hostname, - size_t hlen, - uint16_t port, - bool permanent) -{ - char entry_id[MAX_HOSTCACHE_LEN]; - size_t entry_len; - struct Curl_dns_entry *dns; - struct Curl_dns_entry *dns2; - - dns = dnscache_entry_create(data, dns_queries, paddr, NULL, - hostname, hlen, port, permanent); - if(!dns) - return NULL; - - /* Create an entry id, based upon the hostname and port */ - entry_len = create_dnscache_id(hostname, hlen, port, - entry_id, sizeof(entry_id)); - - /* Store the resolved data in our DNS cache. */ - dns2 = Curl_hash_add(&dnscache->entries, entry_id, entry_len + 1, - (void *)dns); - if(!dns2) { - dnscache_entry_free(dns); - return NULL; - } - - dns = dns2; - dns->refcount++; /* mark entry as in-use */ - return dns; -} - -CURLcode Curl_dnscache_add(struct Curl_easy *data, - struct Curl_dns_entry *entry) -{ - struct Curl_dnscache *dnscache = dnscache_get(data); - char id[MAX_HOSTCACHE_LEN]; - size_t idlen; - - if(!dnscache) - return CURLE_FAILED_INIT; - /* Create an entry id, based upon the hostname and port */ - idlen = create_dnscache_id(entry->hostname, 0, entry->port, id, sizeof(id)); - - /* Store the resolved data in our DNS cache and up ref count */ - dnscache_lock(data, dnscache); - if(!Curl_hash_add(&dnscache->entries, id, idlen + 1, (void *)entry)) { - dnscache_unlock(data, dnscache); - return CURLE_OUT_OF_MEMORY; - } - entry->refcount++; - dnscache_unlock(data, dnscache); - return CURLE_OK; -} - -CURLcode Curl_dnscache_add_negative(struct Curl_easy *data, - uint8_t dns_queries, - const char *host, - uint16_t port) -{ - struct Curl_dnscache *dnscache = dnscache_get(data); - struct Curl_dns_entry *dns; - DEBUGASSERT(dnscache); - if(!dnscache) - return CURLE_FAILED_INIT; - - dnscache_lock(data, dnscache); - - /* put this new host in the cache */ - dns = dnscache_add_addr(data, dnscache, dns_queries, NULL, - host, strlen(host), port, FALSE); - if(dns) { - /* release the returned reference; the cache itself will keep the - * entry alive: */ - dns->refcount--; - dnscache_unlock(data, dnscache); - CURL_TRC_DNS(data, "cache negative name resolve for %s:%d type=%s", - host, port, Curl_resolv_query_str(dns_queries)); - return CURLE_OK; - } - dnscache_unlock(data, dnscache); - return CURLE_OUT_OF_MEMORY; -} - -struct Curl_dns_entry *Curl_dns_entry_link(struct Curl_easy *data, - struct Curl_dns_entry *dns) -{ - if(!dns) - return NULL; - else { - struct Curl_dnscache *dnscache = dnscache_get(data); - dnscache_lock(data, dnscache); - dns->refcount++; - dnscache_unlock(data, dnscache); - return dns; - } -} - -/* - * Curl_dns_entry_unlink() releases a reference to the given cached DNS entry. - * When the reference count reaches 0, the entry is destroyed. It is important - * that only one unlink is made for each Curl_resolv() call. - * - * May be called with 'data' == NULL for global cache. - */ -void Curl_dns_entry_unlink(struct Curl_easy *data, - struct Curl_dns_entry **pdns) -{ - if(*pdns) { - struct Curl_dnscache *dnscache = dnscache_get(data); - struct Curl_dns_entry *dns = *pdns; - *pdns = NULL; - dnscache_lock(data, dnscache); - dns->refcount--; - if(dns->refcount == 0) - dnscache_entry_free(dns); - dnscache_unlock(data, dnscache); - } -} - -static void dnscache_entry_dtor(void *entry) -{ - struct Curl_dns_entry *dns = (struct Curl_dns_entry *)entry; - DEBUGASSERT(dns && (dns->refcount > 0)); - dns->refcount--; - if(dns->refcount == 0) - dnscache_entry_free(dns); -} - -/* - * Curl_dnscache_init() inits a new DNS cache. - */ -void Curl_dnscache_init(struct Curl_dnscache *dns, size_t size) -{ - Curl_hash_init(&dns->entries, size, Curl_hash_str, curlx_str_key_compare, - dnscache_entry_dtor); -} - -void Curl_dnscache_destroy(struct Curl_dnscache *dns) -{ - Curl_hash_destroy(&dns->entries); -} - -CURLcode Curl_loadhostpairs(struct Curl_easy *data) -{ - struct Curl_dnscache *dnscache = dnscache_get(data); - struct curl_slist *hostp; - - if(!dnscache) - return CURLE_FAILED_INIT; - - /* Default is no wildcard found */ - data->state.wildcard_resolve = FALSE; - - for(hostp = data->state.resolve; hostp; hostp = hostp->next) { - char entry_id[MAX_HOSTCACHE_LEN]; - const char *host = hostp->data; - struct Curl_str source; - if(!host) - continue; - if(*host == '-') { - curl_off_t num = 0; - size_t entry_len; - host++; - if(!curlx_str_single(&host, '[')) { - if(curlx_str_until(&host, &source, MAX_IPADR_LEN, ']') || - curlx_str_single(&host, ']') || - curlx_str_single(&host, ':')) - continue; - } - else { - if(curlx_str_until(&host, &source, 4096, ':') || - curlx_str_single(&host, ':')) { - continue; - } - } - - if(!curlx_str_number(&host, &num, 0xffff)) { - /* Create an entry id, based upon the hostname and port */ - entry_len = create_dnscache_id(curlx_str(&source), - curlx_strlen(&source), (uint16_t)num, - entry_id, sizeof(entry_id)); - dnscache_lock(data, dnscache); - /* delete entry, ignore if it did not exist */ - Curl_hash_delete(&dnscache->entries, entry_id, entry_len + 1); - dnscache_unlock(data, dnscache); - } - } - else { - struct Curl_dns_entry *dns; - struct Curl_addrinfo *head = NULL, *tail = NULL; - size_t entry_len; - char address[64]; - curl_off_t tmpofft = 0; - uint16_t port = 0; - bool permanent = TRUE; - bool error = TRUE; - VERBOSE(const char *addresses = NULL); - - if(*host == '+') { - host++; - permanent = FALSE; - } - if(!curlx_str_single(&host, '[')) { - if(curlx_str_until(&host, &source, MAX_IPADR_LEN, ']') || - curlx_str_single(&host, ']')) - continue; - } - else { - if(curlx_str_until(&host, &source, 4096, ':')) - continue; - } - if(curlx_str_single(&host, ':') || - curlx_str_number(&host, &tmpofft, 0xffff) || - curlx_str_single(&host, ':')) - goto err; - port = (uint16_t)tmpofft; - - VERBOSE(addresses = host); - - /* start the address section */ - while(*host) { - struct Curl_str target; - struct Curl_addrinfo *ai; - CURLcode result; - - if(!curlx_str_single(&host, '[')) { - if(curlx_str_until(&host, &target, MAX_IPADR_LEN, ']') || - curlx_str_single(&host, ']')) - goto err; - } - else { - if(curlx_str_until(&host, &target, 4096, ',')) { - if(curlx_str_single(&host, ',')) - goto err; - /* survive nothing but a comma */ - continue; - } - } -#ifndef USE_IPV6 - if(memchr(curlx_str(&target), ':', curlx_strlen(&target))) { - infof(data, "Ignoring resolve address '%.*s', missing IPv6 support.", - (int)curlx_strlen(&target), curlx_str(&target)); - if(curlx_str_single(&host, ',')) - goto err; - continue; - } -#endif - - if(curlx_strlen(&target) >= sizeof(address)) - goto err; - - memcpy(address, curlx_str(&target), curlx_strlen(&target)); - address[curlx_strlen(&target)] = '\0'; - - result = Curl_str2addr(address, port, &ai); - if(result) { - infof(data, "Resolve address '%s' found illegal", address); - goto err; - } - - if(tail) { - tail->ai_next = ai; - tail = tail->ai_next; - } - else { - head = tail = ai; - } - if(curlx_str_single(&host, ',')) - break; - } - - if(!head) - goto err; - - error = FALSE; -err: - if(error) { - failf(data, "Could not parse CURLOPT_RESOLVE entry '%s'", hostp->data); - Curl_freeaddrinfo(head); - return CURLE_SETOPT_OPTION_SYNTAX; - } - - /* Create an entry id, based upon the hostname and port */ - entry_len = create_dnscache_id(curlx_str(&source), curlx_strlen(&source), - port, entry_id, sizeof(entry_id)); - - dnscache_lock(data, dnscache); - - /* See if it is already in our dns cache */ - dns = Curl_hash_pick(&dnscache->entries, entry_id, entry_len + 1); - - if(dns) { - infof(data, "RESOLVE %.*s:%u - old addresses discarded", - (int)curlx_strlen(&source), - curlx_str(&source), port); - /* delete old entry, there are two reasons for this - 1. old entry may have different addresses. - 2. even if entry with correct addresses is already in the cache, - but if it is close to expire, then by the time next http - request is made, it can get expired and pruned because old - entry is not necessarily marked as permanent. - 3. when adding a non-permanent entry, we want it to remove and - replace an existing permanent entry. - 4. when adding a non-permanent entry, we want it to get a "fresh" - timeout that starts _now_. */ - - Curl_hash_delete(&dnscache->entries, entry_id, entry_len + 1); - } - - /* put this new host in the cache, an overridy for ALL dns queries */ - dns = dnscache_add_addr(data, dnscache, CURL_DNSQ_ALL, - &head, curlx_str(&source), - curlx_strlen(&source), port, permanent); - if(dns) - /* release the returned reference; the cache itself will keep the - * entry alive: */ - dns->refcount--; - - dnscache_unlock(data, dnscache); - - if(!dns) - return CURLE_OUT_OF_MEMORY; - - infof(data, "Added %.*s:%u:%s to DNS cache%s", - (int)curlx_strlen(&source), curlx_str(&source), port, addresses, - permanent ? "" : " (non-permanent)"); - - /* Wildcard hostname */ - if(curlx_str_casecompare(&source, "*")) { - infof(data, "RESOLVE *:%u using wildcard", port); - data->state.wildcard_resolve = TRUE; - } - } - } - data->state.resolve = NULL; /* dealt with now */ - - return CURLE_OK; -} diff --git a/vendor/curl/lib/dnscache.h b/vendor/curl/lib/dnscache.h deleted file mode 100644 index ebe25f6dd..000000000 --- a/vendor/curl/lib/dnscache.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef HEADER_CURL_DNSCACHE_H -#define HEADER_CURL_DNSCACHE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "hash.h" -#include "curlx/timeval.h" - -struct addrinfo; -struct hostent; -struct Curl_easy; -struct connectdata; -struct easy_pollset; -struct Curl_https_rrinfo; -struct Curl_multi; - -struct Curl_dns_entry { - struct Curl_addrinfo *addr; -#ifdef USE_HTTPSRR - struct Curl_https_rrinfo *hinfo; -#endif - /* timestamp == 0 -- permanent CURLOPT_RESOLVE entry (does not time out) */ - struct curltime timestamp; - /* reference counter, entry is freed on reaching 0 */ - uint32_t refcount; - /* hostname port number that resolved to addr. */ - uint16_t port; - uint8_t dns_queries; /* CURL_DNSQ_* type of queries performed for this */ - uint8_t dns_responses; /* CURL_DNSQ_* type this entry has responses for */ - /* hostname that resolved to addr. may be NULL (Unix domain sockets). */ - char hostname[1]; -}; - -/* - * Create a `Curl_dns_entry` with a reference count of 1. - * Use `Curl_dns_entry_unlink()` to release your hold on it. - * - * The call takes ownership of `paddr`, even in case of failure, and always - * clears `*paddr`. It makes a copy of `hostname`. - * - * Returns entry or NULL on OOM. - */ -struct Curl_dns_entry *Curl_dnscache_mk_entry(struct Curl_easy *data, - uint8_t dns_queries, - struct Curl_addrinfo **paddr, - const char *hostname, - uint16_t port); - -struct Curl_dns_entry *Curl_dnscache_mk_entry2(struct Curl_easy *data, - uint8_t dns_queries, - struct Curl_addrinfo **paddr1, - struct Curl_addrinfo **paddr2, - const char *hostname, - uint16_t port); - -#ifdef USE_HTTPSRR -void Curl_dns_entry_set_https_rr(struct Curl_dns_entry *dns, - struct Curl_https_rrinfo *hinfo); -#endif /* USE_HTTPSRR */ - -/* Increase the ref counter and return it for storing in another place. - * May be called with NULL, in which case it returns NULL. */ -struct Curl_dns_entry *Curl_dns_entry_link(struct Curl_easy *data, - struct Curl_dns_entry *dns); - -/* unlink a dns entry, frees all resources if it was the last reference. - * Always clears `*pdns`` */ -void Curl_dns_entry_unlink(struct Curl_easy *data, - struct Curl_dns_entry **pdns); - -struct Curl_dnscache { - struct Curl_hash entries; -}; - -/* init a new dns cache */ -void Curl_dnscache_init(struct Curl_dnscache *dns, size_t size); - -void Curl_dnscache_destroy(struct Curl_dnscache *dns); - -/* prune old entries from the DNS cache */ -void Curl_dnscache_prune(struct Curl_easy *data); - -/* clear the DNS cache */ -void Curl_dnscache_clear(struct Curl_easy *data); - -/* - * Curl_dnscache_get() fetches a 'Curl_dns_entry' already in the DNS cache. - * - * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. - * - * The returned data *MUST* be "released" with Curl_dns_entry_unlink() after - * use, or we will leak memory! - * Returns CURLE_OK or CURLE_COULDNT_RESOLVE_HOST when a negative - * entry was in the cache. - */ -CURLcode Curl_dnscache_get(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - struct Curl_dns_entry **pentry); - -/* - * Curl_dnscache_addr() adds `entry` to the cache, increasing its - * reference count on success. - */ -CURLcode Curl_dnscache_add(struct Curl_easy *data, - struct Curl_dns_entry *entry); - -/* Store a "negative" entry for host:port, e.g. remember that - * it could not be resolved. */ -CURLcode Curl_dnscache_add_negative(struct Curl_easy *data, - uint8_t dns_queries, - const char *host, - uint16_t port); - -/* - * Populate the cache with specified entries from CURLOPT_RESOLVE. - */ -CURLcode Curl_loadhostpairs(struct Curl_easy *data); - -#endif /* HEADER_CURL_DNSCACHE_H */ diff --git a/vendor/curl/lib/doh.c b/vendor/curl/lib/doh.c deleted file mode 100644 index 30441358c..000000000 --- a/vendor/curl/lib/doh.c +++ /dev/null @@ -1,1362 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_DOH - -#include "urldata.h" -#include "curl_addrinfo.h" -#include "doh.h" -#include "curl_trc.h" -#include "httpsrr.h" -#include "multiif.h" -#include "url.h" -#include "connect.h" -#include "curlx/strdup.h" -#include "curlx/dynbuf.h" -#include "escape.h" /* for Curl_hexencode() */ -#include "urlapi-int.h" - -#define DNS_CLASS_IN 0x01 - -static void doh_close(struct Curl_easy *data, - struct Curl_resolv_async *async); - -#ifdef CURLVERBOSE -static const char * const errors[] = { - "", - "Bad label", - "Out of range", - "Label loop", - "Too small", - "Out of memory", - "RDATA length", - "Malformat", - "Bad RCODE", - "Unexpected TYPE", - "Unexpected CLASS", - "No content", - "Bad ID", - "Name too long" -}; - -static const char *doh_strerror(DOHcode code) -{ - if((code >= DOH_OK) && (code <= DOH_DNS_NAME_TOO_LONG)) - return errors[code]; - return "bad error code"; -} - -#endif /* CURLVERBOSE */ - -/* @unittest 1655 - */ -UNITTEST DOHcode doh_req_encode(const char *host, - DNStype dnstype, - unsigned char *dnsp, /* buffer */ - size_t len, /* buffer size */ - size_t *olen); /* output length */ -UNITTEST DOHcode doh_req_encode(const char *host, - DNStype dnstype, - unsigned char *dnsp, /* buffer */ - size_t len, /* buffer size */ - size_t *olen) /* output length */ -{ - const size_t hostlen = strlen(host); - unsigned char *orig = dnsp; - const char *hostp = host; - - /* The expected output length is 16 bytes more than the length of - * the QNAME-encoding of the hostname. - * - * A valid DNS name may not contain a zero-length label, except at - * the end. For this reason, a name beginning with a dot, or - * containing a sequence of two or more consecutive dots, is invalid - * and cannot be encoded as a QNAME. - * - * If the hostname ends with a trailing dot, the corresponding - * QNAME-encoding is one byte longer than the hostname. If (as is - * also valid) the hostname is shortened by the omission of the - * trailing dot, then its QNAME-encoding will be two bytes longer - * than the hostname. - * - * Each [ label, dot ] pair is encoded as [ length, label ], - * preserving overall length. A final [ label ] without a dot is - * also encoded as [ length, label ], increasing overall length - * by one. The encoding is completed by appending a zero byte, - * representing the zero-length root label, again increasing - * the overall length by one. - */ - - size_t expected_len; - DEBUGASSERT(hostlen); - expected_len = 12 + 1 + hostlen + 4; - if(host[hostlen - 1] != '.') - expected_len++; - - if(expected_len > DOH_MAX_DNSREQ_SIZE) - return DOH_DNS_NAME_TOO_LONG; - - if(len < expected_len) - return DOH_TOO_SMALL_BUFFER; - - *dnsp++ = 0; /* 16-bit id */ - *dnsp++ = 0; - *dnsp++ = 0x01; /* |QR| Opcode |AA|TC|RD| Set the RD bit */ - *dnsp++ = '\0'; /* |RA| Z | RCODE | */ - *dnsp++ = '\0'; - *dnsp++ = 1; /* QDCOUNT (number of entries in the question section) */ - *dnsp++ = '\0'; - *dnsp++ = '\0'; /* ANCOUNT */ - *dnsp++ = '\0'; - *dnsp++ = '\0'; /* NSCOUNT */ - *dnsp++ = '\0'; - *dnsp++ = '\0'; /* ARCOUNT */ - - /* encode each label and store it in the QNAME */ - while(*hostp) { - size_t labellen; - const char *dot = strchr(hostp, '.'); - if(dot) - labellen = dot - hostp; - else - labellen = strlen(hostp); - if((labellen > 63) || (!labellen)) { - /* label is too long or too short, error out */ - *olen = 0; - return DOH_DNS_BAD_LABEL; - } - /* label is non-empty, process it */ - *dnsp++ = (unsigned char)labellen; - memcpy(dnsp, hostp, labellen); - dnsp += labellen; - hostp += labellen; - /* advance past dot, but only if there is one */ - if(dot) - hostp++; - } /* next label */ - - *dnsp++ = 0; /* append zero-length label for root */ - - /* There are assigned TYPE codes beyond 255: use range [1..65535] */ - *dnsp++ = (unsigned char)(255 & (dnstype >> 8)); /* upper 8-bit TYPE */ - *dnsp++ = (unsigned char)(255 & dnstype); /* lower 8-bit TYPE */ - - *dnsp++ = '\0'; /* upper 8-bit CLASS */ - *dnsp++ = DNS_CLASS_IN; /* IN - "the Internet" */ - - *olen = dnsp - orig; - - /* verify that our estimation of length is valid, since - * this has led to buffer overflows in this function */ - DEBUGASSERT(*olen == expected_len); - return DOH_OK; -} - -static size_t doh_probe_write_cb(char *contents, size_t size, size_t nmemb, - void *userp) -{ - size_t realsize = size * nmemb; - struct Curl_easy *data = userp; - struct doh_request *doh_req = Curl_meta_get(data, CURL_EZM_DOH_PROBE); - if(!doh_req) - return CURL_WRITEFUNC_ERROR; - - if(curlx_dyn_addn(&doh_req->resp_body, contents, realsize)) - return 0; - - return realsize; -} - -#if defined(USE_HTTPSRR) && defined(DEBUGBUILD) && defined(CURLVERBOSE) - -/* doh_print_buf truncates if the hex string will be more than this */ -#define LOCAL_PB_HEXMAX 400 - -static void doh_print_buf(struct Curl_easy *data, - const char *prefix, - unsigned char *buf, size_t len) -{ - unsigned char hexstr[LOCAL_PB_HEXMAX]; - size_t hlen = LOCAL_PB_HEXMAX; - bool truncated = FALSE; - - if(len > (LOCAL_PB_HEXMAX / 2)) - truncated = TRUE; - Curl_hexencode(buf, len, hexstr, hlen); - if(!truncated) - infof(data, "%s: len=%d, val=%s", prefix, (int)len, hexstr); - else - infof(data, "%s: len=%d (truncated)val=%s", prefix, (int)len, hexstr); -} -#endif - -/* called from multi when a sub transfer, e.g. doh probe, is done. - * This looks up the probe response at its meta CURL_EZM_DOH_PROBE - * and copies the response body over to the struct at the master's - * meta at CURL_EZM_DOH_MASTER. */ -static void doh_probe_done(struct Curl_easy *data, - struct Curl_easy *doh, CURLcode result) -{ - struct Curl_resolv_async *async = NULL; - struct doh_probes *dohp = NULL; - struct doh_request *doh_req = NULL; - int i; - - doh_req = Curl_meta_get(doh, CURL_EZM_DOH_PROBE); - if(!doh_req) { - DEBUGASSERT(0); - return; - } - - async = Curl_async_get(data, doh_req->resolv_id); - if(!async) { - CURL_TRC_DNS(data, "[%u] ignoring outdated DoH response", - doh_req->resolv_id); - return; - } - dohp = async->doh; - - for(i = 0; i < DOH_SLOT_COUNT; ++i) { - if(dohp->probe_resp[i].probe_mid == doh->mid) - break; - } - /* We really should have found the slot where to store the response */ - if(i >= DOH_SLOT_COUNT) { - DEBUGASSERT(0); - failf(data, "DoH: unknown sub request done"); - return; - } - - dohp->pending--; - infof(doh, "a DoH request is completed, %u to go", dohp->pending); - dohp->probe_resp[i].result = result; - /* We expect either the meta data still to exist or the sub request - * to have already failed. */ - if(!result) { - dohp->probe_resp[i].dnstype = doh_req->dnstype; - result = curlx_dyn_addn(&dohp->probe_resp[i].body, - curlx_dyn_ptr(&doh_req->resp_body), - curlx_dyn_len(&doh_req->resp_body)); - curlx_dyn_free(&doh_req->resp_body); - } - Curl_meta_remove(doh, CURL_EZM_DOH_PROBE); - - if(result) - infof(doh, "DoH request %s", curl_easy_strerror(result)); - - if(!dohp->pending) { - /* DoH completed, run the transfer picking up the results */ - Curl_multi_mark_dirty(data); - } -} - -static void doh_probe_dtor(void *key, size_t klen, void *e) -{ - (void)key; - (void)klen; - if(e) { - struct doh_request *doh_req = e; - curl_slist_free_all(doh_req->req_hds); - curlx_dyn_free(&doh_req->resp_body); - curlx_free(e); - } -} - -#define ERROR_CHECK_SETOPT(x, y) \ - do { \ - result = curl_easy_setopt((CURL *)doh, x, y); \ - if(result && \ - result != CURLE_NOT_BUILT_IN && \ - result != CURLE_UNKNOWN_OPTION) \ - goto error; \ - } while(0) - -static CURLcode doh_probe_run(struct Curl_easy *data, - DNStype dnstype, - const char *host, - const char *url, CURLM *multi, - uint32_t resolv_id, - uint32_t *pmid) -{ - struct Curl_easy *doh = NULL; - CURLcode result = CURLE_OK; - timediff_t timeout_ms; - struct doh_request *doh_req; - DOHcode d; - - *pmid = UINT32_MAX; - - doh_req = curlx_calloc(1, sizeof(*doh_req)); - if(!doh_req) - return CURLE_OUT_OF_MEMORY; - doh_req->resolv_id = resolv_id; - doh_req->dnstype = dnstype; - curlx_dyn_init(&doh_req->resp_body, DYN_DOH_RESPONSE); - - d = doh_req_encode(host, dnstype, doh_req->req_body, - sizeof(doh_req->req_body), - &doh_req->req_body_len); - if(d) { - failf(data, "Failed to encode DoH packet [%d]", d); - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - timeout_ms = Curl_timeleft_ms(data); - if(timeout_ms < 0) { - result = CURLE_OPERATION_TIMEDOUT; - goto error; - } - - doh_req->req_hds = - curl_slist_append(NULL, "Content-Type: application/dns-message"); - if(!doh_req->req_hds) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - /* Curl_open() is the internal version of curl_easy_init() */ - result = Curl_open(&doh); - if(result) - goto error; - - /* pass in the struct pointer via a local variable to please coverity and - the gcc typecheck helpers */ - VERBOSE(doh->state.feat = &Curl_trc_feat_dns); - ERROR_CHECK_SETOPT(CURLOPT_URL, url); - ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https"); - ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_probe_write_cb); - ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, doh); - ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, doh_req->req_body); - ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)doh_req->req_body_len); - ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, doh_req->req_hds); -#ifdef USE_HTTP2 - ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); - ERROR_CHECK_SETOPT(CURLOPT_PIPEWAIT, 1L); -#endif -#ifndef DEBUGBUILD - /* enforce HTTPS if not debug */ - ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); -#else - /* in debug mode, also allow http */ - ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); -#endif - ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); - ERROR_CHECK_SETOPT(CURLOPT_SHARE, (CURLSH *)data->share); - if(data->set.err && data->set.err != stderr) - ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err); - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) - ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); - if(data->set.no_signal) - ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); - - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, - data->set.doh_verifyhost ? 2L : 0L); - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, - data->set.doh_verifypeer ? 1L : 0L); - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, - data->set.doh_verifystatus ? 1L : 0L); - - /* Inherit *some* SSL options from the user's transfer. This is a - best-guess as to which options are needed for compatibility. #3661 - - Note DoH does not inherit the user's proxy server so proxy SSL settings - have no effect and are not inherited. If that changes then two new - options should be added to check doh proxy insecure separately, - CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER. - */ - doh->set.ssl.custom_cafile = data->set.ssl.custom_cafile; - doh->set.ssl.custom_capath = data->set.ssl.custom_capath; - doh->set.ssl.custom_cablob = data->set.ssl.custom_cablob; - if(data->set.str[STRING_SSL_CAFILE]) { - ERROR_CHECK_SETOPT(CURLOPT_CAINFO, data->set.str[STRING_SSL_CAFILE]); - } - if(data->set.blobs[BLOB_CAINFO]) { - ERROR_CHECK_SETOPT(CURLOPT_CAINFO_BLOB, data->set.blobs[BLOB_CAINFO]); - } - if(data->set.str[STRING_SSL_CAPATH]) { - ERROR_CHECK_SETOPT(CURLOPT_CAPATH, data->set.str[STRING_SSL_CAPATH]); - } - if(data->set.str[STRING_SSL_CRLFILE]) { - ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, data->set.str[STRING_SSL_CRLFILE]); - } - if(data->set.ssl.certinfo) - ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); - if(data->set.ssl.fsslctx) - ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); - if(data->set.ssl.fsslctxp) - ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); - if(data->set.fdebug) - ERROR_CHECK_SETOPT(CURLOPT_DEBUGFUNCTION, data->set.fdebug); - if(data->set.debugdata) - ERROR_CHECK_SETOPT(CURLOPT_DEBUGDATA, data->set.debugdata); - if(data->set.str[STRING_SSL_EC_CURVES]) { - ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES, - data->set.str[STRING_SSL_EC_CURVES]); - } - - (void)curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, - (long)data->set.ssl.primary.ssl_options); - - doh->state.internal = TRUE; - doh->master_mid = data->mid; /* master transfer of this one */ - - result = Curl_meta_set(doh, CURL_EZM_DOH_PROBE, doh_req, doh_probe_dtor); - doh_req = NULL; /* call took ownership */ - if(result) - goto error; - - /* DoH handles must not inherit private_data. The handles may be passed to - the user via callbacks and the user will be able to identify them as - internal handles because private data is not set. The user can then set - private_data via CURLOPT_PRIVATE if they so choose. */ - DEBUGASSERT(!doh->set.private_data); - - if(curl_multi_add_handle(multi, doh)) - goto error; - - *pmid = doh->mid; - return CURLE_OK; - -error: - Curl_close(&doh); - if(doh_req) - doh_probe_dtor(NULL, 0, doh_req); - return result; -} - -/* - * Curl_doh() starts a name resolve using DoH. It resolves a name and returns - * a 'Curl_addrinfo *' with the address information. - */ - -CURLcode Curl_doh(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - CURLcode result = CURLE_OK; - struct doh_probes *dohp = NULL; - size_t i; - - DEBUGASSERT(!async->doh); - DEBUGASSERT(async->hostname[0]); - if(async->doh) { - DEBUGASSERT(0); /* should not happen */ - Curl_doh_cleanup(data, async); - } - - /* start clean, consider allocating this struct on demand */ - async->doh = dohp = curlx_calloc(1, sizeof(struct doh_probes)); - if(!dohp) - return CURLE_OUT_OF_MEMORY; - - for(i = 0; i < DOH_SLOT_COUNT; ++i) { - dohp->probe_resp[i].probe_mid = UINT32_MAX; - curlx_dyn_init(&dohp->probe_resp[i].body, DYN_DOH_RESPONSE); - } - - dohp->host = async->hostname; - dohp->port = async->port; - /* We are making sub easy handles and want to be called back when - * one is done. */ - data->sub_xfer_done = doh_probe_done; - - /* create IPv4 DoH request */ - if(async->dns_queries & CURL_DNSQ_A) { - result = doh_probe_run(data, CURL_DNS_TYPE_A, - async->hostname, data->set.str[STRING_DOH], - data->multi, async->id, - &dohp->probe_resp[DOH_SLOT_IPV4].probe_mid); - if(result) - goto error; - dohp->pending++; - } - -#ifdef USE_IPV6 - if(async->dns_queries & CURL_DNSQ_AAAA) { - /* create IPv6 DoH request */ - result = doh_probe_run(data, CURL_DNS_TYPE_AAAA, - async->hostname, data->set.str[STRING_DOH], - data->multi, async->id, - &dohp->probe_resp[DOH_SLOT_IPV6].probe_mid); - if(result) - goto error; - dohp->pending++; - } -#endif - -#ifdef USE_HTTPSRR - if(async->dns_queries & CURL_DNSQ_HTTPS) { - char *qname = NULL; - if(async->port != PORT_HTTPS) { - qname = curl_maprintf("_%d._https.%s", async->port, async->hostname); - if(!qname) - goto error; - } - result = doh_probe_run(data, CURL_DNS_TYPE_HTTPS, - qname ? qname : async->hostname, - data->set.str[STRING_DOH], data->multi, - async->id, - &dohp->probe_resp[DOH_SLOT_HTTPS_RR].probe_mid); - curlx_free(qname); - if(result) - goto error; - dohp->pending++; - } -#endif - return CURLE_OK; - -error: - Curl_doh_cleanup(data, async); - return result; -} - -static DOHcode doh_skipqname(const unsigned char *doh, size_t dohlen, - unsigned int *indexp) -{ - unsigned char length; - do { - if(dohlen < (*indexp + 1)) - return DOH_DNS_OUT_OF_RANGE; - length = doh[*indexp]; - if((length & 0xc0) == 0xc0) { - /* name pointer, advance over it and be done */ - if(dohlen < (*indexp + 2)) - return DOH_DNS_OUT_OF_RANGE; - *indexp += 2; - break; - } - if(length & 0xc0) - return DOH_DNS_BAD_LABEL; - if(dohlen < (*indexp + 1 + length)) - return DOH_DNS_OUT_OF_RANGE; - *indexp += (unsigned int)(1 + length); - } while(length); - return DOH_OK; -} - -static unsigned short doh_get16bit(const unsigned char *doh, - unsigned int index) -{ - return (unsigned short)((doh[index] << 8) | doh[index + 1]); -} - -static unsigned int doh_get32bit(const unsigned char *doh, unsigned int index) -{ - /* make clang and gcc optimize this to bswap by incrementing - the pointer first. */ - doh += index; - - /* avoid undefined behavior by casting to unsigned before shifting - 24 bits, possibly into the sign bit. codegen is same, but - ub sanitizer will not be upset */ - return ((unsigned)doh[0] << 24) | ((unsigned)doh[1] << 16) | - ((unsigned)doh[2] << 8) | doh[3]; -} - -static void doh_store_a(const unsigned char *doh, int index, - struct dohentry *d) -{ - /* silently ignore addresses over the limit */ - if(d->numaddr < DOH_MAX_ADDR) { - struct dohaddr *a = &d->addr[d->numaddr]; - a->type = CURL_DNS_TYPE_A; - memcpy(&a->ip.v4, &doh[index], 4); - d->numaddr++; - } -} - -static void doh_store_aaaa(const unsigned char *doh, int index, - struct dohentry *d) -{ - /* silently ignore addresses over the limit */ - if(d->numaddr < DOH_MAX_ADDR) { - struct dohaddr *a = &d->addr[d->numaddr]; - a->type = CURL_DNS_TYPE_AAAA; - memcpy(&a->ip.v6, &doh[index], 16); - d->numaddr++; - } -} - -#ifdef USE_HTTPSRR -static DOHcode doh_store_https(const unsigned char *doh, int index, - struct dohentry *d, uint16_t len) -{ - /* silently ignore RRs over the limit */ - if(d->numhttps_rrs < DOH_MAX_HTTPS) { - struct dohhttps_rr *h = &d->https_rrs[d->numhttps_rrs]; - h->val = curlx_memdup(&doh[index], len); - if(!h->val) - return DOH_OUT_OF_MEM; - h->len = len; - d->numhttps_rrs++; - } - return DOH_OK; -} -#endif - -static DOHcode doh_store_cname(const unsigned char *doh, size_t dohlen, - unsigned int index, struct dohentry *d) -{ - struct dynbuf *c; - unsigned int loop = 128; /* a valid DNS name can never loop this much */ - unsigned char length; - - if(d->numcname == DOH_MAX_CNAME) - return DOH_OK; /* skip! */ - - c = &d->cname[d->numcname++]; - do { - if(index >= dohlen) - return DOH_DNS_OUT_OF_RANGE; - length = doh[index]; - if((length & 0xc0) == 0xc0) { - int newpos; - /* name pointer, get the new offset (14 bits) */ - if((index + 1) >= dohlen) - return DOH_DNS_OUT_OF_RANGE; - - /* move to the new index */ - newpos = (length & 0x3f) << 8 | doh[index + 1]; - index = (unsigned int)newpos; - continue; - } - else if(length & 0xc0) - return DOH_DNS_BAD_LABEL; /* bad input */ - else - index++; - - if(length) { - if(curlx_dyn_len(c)) { - if(curlx_dyn_addn(c, STRCONST("."))) - return DOH_OUT_OF_MEM; - } - if((index + length) > dohlen) - return DOH_DNS_BAD_LABEL; - - if(curlx_dyn_addn(c, &doh[index], length)) - return DOH_OUT_OF_MEM; - index += length; - } - } while(length && --loop); - - if(!loop) - return DOH_DNS_LABEL_LOOP; - return DOH_OK; -} - -static DOHcode doh_rdata(const unsigned char *doh, - size_t dohlen, - unsigned short rdlength, - unsigned short type, - int index, - struct dohentry *d) -{ - /* RDATA - - A (TYPE 1): 4 bytes - - AAAA (TYPE 28): 16 bytes - - NS (TYPE 2): N bytes - - HTTPS (TYPE 65): N bytes */ - DOHcode rc; - - switch(type) { - case CURL_DNS_TYPE_A: - if(rdlength != 4) - return DOH_DNS_RDATA_LEN; - doh_store_a(doh, index, d); - break; - case CURL_DNS_TYPE_AAAA: - if(rdlength != 16) - return DOH_DNS_RDATA_LEN; - doh_store_aaaa(doh, index, d); - break; -#ifdef USE_HTTPSRR - case CURL_DNS_TYPE_HTTPS: - rc = doh_store_https(doh, index, d, rdlength); - if(rc) - return rc; - break; -#endif - case CURL_DNS_TYPE_CNAME: - rc = doh_store_cname(doh, dohlen, (unsigned int)index, d); - if(rc) - return rc; - break; - case CURL_DNS_TYPE_DNAME: - /* explicit for clarity; skip; rely on synthesized CNAME */ - break; - default: - /* unsupported type, skip it */ - break; - } - return DOH_OK; -} - -/* @unittest 1655 */ -UNITTEST void de_init(struct dohentry *de); -UNITTEST void de_init(struct dohentry *de) -{ - int i; - memset(de, 0, sizeof(*de)); - de->ttl = INT_MAX; - for(i = 0; i < DOH_MAX_CNAME; i++) - curlx_dyn_init(&de->cname[i], DYN_DOH_CNAME); -} - -/* @unittest 1655 */ -UNITTEST DOHcode doh_resp_decode(const unsigned char *doh, - size_t dohlen, - DNStype dnstype, - struct dohentry *d); -UNITTEST DOHcode doh_resp_decode(const unsigned char *doh, - size_t dohlen, - DNStype dnstype, - struct dohentry *d) -{ - unsigned char rcode; - unsigned short qdcount; - unsigned short ancount; - unsigned short type = 0; - unsigned short rdlength; - unsigned short nscount; - unsigned short arcount; - unsigned int index = 12; - DOHcode rc; - - if(dohlen < 12) - return DOH_TOO_SMALL_BUFFER; /* too small */ - if(!doh || doh[0] || doh[1]) - return DOH_DNS_BAD_ID; /* bad ID */ - rcode = doh[3] & 0x0f; - if(rcode) - return DOH_DNS_BAD_RCODE; /* bad rcode */ - - qdcount = doh_get16bit(doh, 4); - while(qdcount) { - rc = doh_skipqname(doh, dohlen, &index); - if(rc) - return rc; /* bad qname */ - if(dohlen < (index + 4)) - return DOH_DNS_OUT_OF_RANGE; - index += 4; /* skip question's type and class */ - qdcount--; - } - - ancount = doh_get16bit(doh, 6); - while(ancount) { - unsigned short dnsclass; - unsigned int ttl; - - rc = doh_skipqname(doh, dohlen, &index); - if(rc) - return rc; /* bad qname */ - - if(dohlen < (index + 2)) - return DOH_DNS_OUT_OF_RANGE; - - type = doh_get16bit(doh, index); - if((type != CURL_DNS_TYPE_CNAME) && /* may be synthesized from DNAME */ - (type != CURL_DNS_TYPE_DNAME) && /* if present, accept and ignore */ - (type != dnstype)) - /* Not the same type as was asked for nor CNAME nor DNAME */ - return DOH_DNS_UNEXPECTED_TYPE; - index += 2; - - if(dohlen < (index + 2)) - return DOH_DNS_OUT_OF_RANGE; - dnsclass = doh_get16bit(doh, index); - if(DNS_CLASS_IN != dnsclass) - return DOH_DNS_UNEXPECTED_CLASS; /* unsupported */ - index += 2; - - if(dohlen < (index + 4)) - return DOH_DNS_OUT_OF_RANGE; - - ttl = doh_get32bit(doh, index); - if(ttl < d->ttl) - d->ttl = ttl; - index += 4; - - if(dohlen < (index + 2)) - return DOH_DNS_OUT_OF_RANGE; - - rdlength = doh_get16bit(doh, index); - index += 2; - if(dohlen < (index + rdlength)) - return DOH_DNS_OUT_OF_RANGE; - - rc = doh_rdata(doh, dohlen, rdlength, type, (int)index, d); - if(rc) - return rc; /* bad doh_rdata */ - index += rdlength; - ancount--; - } - - nscount = doh_get16bit(doh, 8); - while(nscount) { - rc = doh_skipqname(doh, dohlen, &index); - if(rc) - return rc; /* bad qname */ - - if(dohlen < (index + 8)) - return DOH_DNS_OUT_OF_RANGE; - - index += 2 + 2 + 4; /* type, dnsclass and ttl */ - - if(dohlen < (index + 2)) - return DOH_DNS_OUT_OF_RANGE; - - rdlength = doh_get16bit(doh, index); - index += 2; - if(dohlen < (index + rdlength)) - return DOH_DNS_OUT_OF_RANGE; - index += rdlength; - nscount--; - } - - arcount = doh_get16bit(doh, 10); - while(arcount) { - rc = doh_skipqname(doh, dohlen, &index); - if(rc) - return rc; /* bad qname */ - - if(dohlen < (index + 8)) - return DOH_DNS_OUT_OF_RANGE; - - index += 2 + 2 + 4; /* type, dnsclass and ttl */ - - if(dohlen < (index + 2)) - return DOH_DNS_OUT_OF_RANGE; - - rdlength = doh_get16bit(doh, index); - index += 2; - if(dohlen < (index + rdlength)) - return DOH_DNS_OUT_OF_RANGE; - index += rdlength; - arcount--; - } - - if(index != dohlen) - return DOH_DNS_MALFORMAT; /* something is wrong */ - -#ifdef USE_HTTPSRR - if((type != CURL_DNS_TYPE_NS) && !d->numcname && !d->numaddr && - !d->numhttps_rrs) -#else - if((type != CURL_DNS_TYPE_NS) && !d->numcname && !d->numaddr) -#endif - /* nothing stored! */ - return DOH_NO_CONTENT; - - return DOH_OK; /* ok */ -} - -#ifdef CURLVERBOSE -static void doh_show(struct Curl_easy *data, - const struct dohentry *d) -{ - int i; - infof(data, "[DoH] TTL: %u seconds", d->ttl); - for(i = 0; i < d->numaddr; i++) { - const struct dohaddr *a = &d->addr[i]; - if(a->type == CURL_DNS_TYPE_A) { - infof(data, "[DoH] A: %u.%u.%u.%u", - a->ip.v4[0], a->ip.v4[1], - a->ip.v4[2], a->ip.v4[3]); - } - else if(a->type == CURL_DNS_TYPE_AAAA) { - int j; - char buffer[128] = "[DoH] AAAA: "; - size_t len = strlen(buffer); - char *ptr = &buffer[len]; - len = sizeof(buffer) - len; - for(j = 0; j < 16; j += 2) { - size_t l; - curl_msnprintf(ptr, len, "%s%02x%02x", j ? ":" : "", - d->addr[i].ip.v6[j], - d->addr[i].ip.v6[j + 1]); - l = strlen(ptr); - len -= l; - ptr += l; - } - infof(data, "%s", buffer); - } - } -#ifdef USE_HTTPSRR - for(i = 0; i < d->numhttps_rrs; i++) { -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - doh_print_buf(data, "DoH HTTPS", d->https_rrs[i].val, d->https_rrs[i].len); -#else - infof(data, "DoH HTTPS RR: length %d", d->https_rrs[i].len); -#endif - } -#endif /* USE_HTTPSRR */ - for(i = 0; i < d->numcname; i++) { - infof(data, "CNAME: %s", curlx_dyn_ptr(&d->cname[i])); - } -} -#else -#define doh_show(x, y) -#endif - -/* - * doh2ai() - * - * This function returns a pointer to the first element of a newly allocated - * Curl_addrinfo struct linked list filled with the data from a set of DoH - * lookups. Curl_addrinfo is meant to work like the addrinfo struct does for - * an IPv6 stack, but usable also for IPv4, all hosts and environments. - * - * The memory allocated by this function *MUST* be free'd later on calling - * Curl_freeaddrinfo(). For each successful call to this function there - * must be an associated call later to Curl_freeaddrinfo(). - */ - -static CURLcode doh2ai(const struct dohentry *de, const char *hostname, - int port, struct Curl_addrinfo **aip) -{ - struct Curl_addrinfo *ai; - struct Curl_addrinfo *prevai = NULL; - struct Curl_addrinfo *firstai = NULL; - struct sockaddr_in *addr; -#ifdef USE_IPV6 - struct sockaddr_in6 *addr6; -#endif - CURLcode result = CURLE_OK; - int i; - size_t hostlen = strlen(hostname) + 1; /* include null-terminator */ - - DEBUGASSERT(de); - - if(!de->numaddr) - return CURLE_COULDNT_RESOLVE_HOST; - - for(i = 0; i < de->numaddr; i++) { - size_t ss_size; - CURL_SA_FAMILY_T addrtype; - if(de->addr[i].type == CURL_DNS_TYPE_AAAA) { -#ifndef USE_IPV6 - /* we cannot handle IPv6 addresses */ - continue; -#else - ss_size = sizeof(struct sockaddr_in6); - addrtype = AF_INET6; -#endif - } - else { - ss_size = sizeof(struct sockaddr_in); - addrtype = AF_INET; - } - - ai = curlx_calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen); - if(!ai) { - result = CURLE_OUT_OF_MEMORY; - break; - } - ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo)); - ai->ai_canonname = (void *)((char *)ai->ai_addr + ss_size); - memcpy(ai->ai_canonname, hostname, hostlen); - - if(!firstai) - /* store the pointer we want to return from this function */ - firstai = ai; - - if(prevai) - /* make the previous entry point to this */ - prevai->ai_next = ai; - - ai->ai_family = addrtype; - - /* we return all names as STREAM, so when using this address for TFTP - the type must be ignored and conn->socktype be used instead! */ - ai->ai_socktype = SOCK_STREAM; - - ai->ai_addrlen = (curl_socklen_t)ss_size; - - /* leave the rest of the struct filled with zero */ - - switch(ai->ai_family) { - case AF_INET: - addr = (void *)ai->ai_addr; /* storage area for this info */ - DEBUGASSERT(sizeof(struct in_addr) == sizeof(de->addr[i].ip.v4)); - memcpy(&addr->sin_addr, &de->addr[i].ip.v4, sizeof(struct in_addr)); - addr->sin_family = addrtype; - addr->sin_port = htons((unsigned short)port); - break; - -#ifdef USE_IPV6 - case AF_INET6: - addr6 = (void *)ai->ai_addr; /* storage area for this info */ - DEBUGASSERT(sizeof(struct in6_addr) == sizeof(de->addr[i].ip.v6)); - memcpy(&addr6->sin6_addr, &de->addr[i].ip.v6, sizeof(struct in6_addr)); - addr6->sin6_family = addrtype; - addr6->sin6_port = htons((unsigned short)port); - break; -#endif - } - - prevai = ai; - } - - if(result) { - Curl_freeaddrinfo(firstai); - firstai = NULL; - } - *aip = firstai; - - return result; -} - -#ifdef CURLVERBOSE -static const char *doh_type2name(DNStype dnstype) -{ - switch(dnstype) { - case CURL_DNS_TYPE_A: - return "A"; - case CURL_DNS_TYPE_AAAA: - return "AAAA"; -#ifdef USE_HTTPSRR - case CURL_DNS_TYPE_HTTPS: - return "HTTPS"; -#endif - default: - return "unknown"; - } -} -#endif - -/* @unittest 1655 */ -UNITTEST void de_cleanup(struct dohentry *d); -UNITTEST void de_cleanup(struct dohentry *d) -{ - int i = 0; - for(i = 0; i < d->numcname; i++) { - curlx_dyn_free(&d->cname[i]); - } -#ifdef USE_HTTPSRR - for(i = 0; i < d->numhttps_rrs; i++) - curlx_safefree(d->https_rrs[i].val); -#endif -} - -#ifdef USE_HTTPSRR - -/* - * @brief decode the DNS name in a binary RRData - * @param buf points to the buffer (in/out) - * @param remaining points to the remaining buffer length (in/out) - * @param dnsname returns the string form name on success - * @return is 1 for success, error otherwise - * - * The encoding here is defined in - * https://datatracker.ietf.org/doc/html/rfc1035#section-3.1 - * - * The input buffer pointer will be modified so it points to after the end of - * the DNS name encoding on output. (that is why it is an "unsigned char - * **" :-) - */ -static CURLcode doh_decode_rdata_name(const unsigned char **buf, - size_t *remaining, char **dnsname) -{ - const unsigned char *cp = NULL; - size_t rem = 0; - unsigned char clen = 0; /* chunk len */ - struct dynbuf thename; - - DEBUGASSERT(buf && remaining && dnsname); - if(!buf || !remaining || !dnsname || !*remaining) - return CURLE_OUT_OF_MEMORY; - curlx_dyn_init(&thename, CURL_MAXLEN_host_name); - rem = *remaining; - cp = *buf; - clen = *cp++; - if(clen == 0) { - /* special case - return "." as name */ - if(curlx_dyn_addn(&thename, ".", 1)) - return CURLE_OUT_OF_MEMORY; - } - while(clen) { - if(clen >= rem) { - curlx_dyn_free(&thename); - return CURLE_OUT_OF_MEMORY; - } - if(curlx_dyn_addn(&thename, cp, clen) || - curlx_dyn_addn(&thename, ".", 1)) - return CURLE_TOO_LARGE; - - cp += clen; - rem -= (clen + 1); - if(rem <= 0) { - curlx_dyn_free(&thename); - return CURLE_OUT_OF_MEMORY; - } - clen = *cp++; - } - *buf = cp; - *remaining = rem - 1; - *dnsname = curlx_dyn_ptr(&thename); - return CURLE_OK; -} - -/* @unittest 1658 */ -UNITTEST CURLcode doh_resp_decode_httpsrr(struct Curl_easy *data, - const unsigned char *cp, size_t len, - struct Curl_https_rrinfo **hrr); -UNITTEST CURLcode doh_resp_decode_httpsrr(struct Curl_easy *data, - const unsigned char *cp, size_t len, - struct Curl_https_rrinfo **hrr) -{ - uint16_t pcode = 0, plen = 0; - uint32_t expected_min_pcode = 0; - struct Curl_https_rrinfo *lhrr = NULL; - char *dnsname = NULL; - CURLcode result = CURLE_OUT_OF_MEMORY; - size_t olen; - - (void)data; - *hrr = NULL; - if(len <= 2) - return CURLE_BAD_FUNCTION_ARGUMENT; - lhrr = curlx_calloc(1, sizeof(struct Curl_https_rrinfo)); - if(!lhrr) - return CURLE_OUT_OF_MEMORY; - lhrr->priority = doh_get16bit(cp, 0); - cp += 2; - len -= 2; - if(doh_decode_rdata_name(&cp, &len, &dnsname) != CURLE_OK) - goto err; - lhrr->target = dnsname; - if(Curl_junkscan(dnsname, &olen, FALSE)) { - /* unacceptable hostname content */ - result = CURLE_WEIRD_SERVER_REPLY; - goto err; - } - while(len >= 4) { - pcode = doh_get16bit(cp, 0); - plen = doh_get16bit(cp, 2); - cp += 4; - len -= 4; - if(pcode < expected_min_pcode || plen > len) { - result = CURLE_WEIRD_SERVER_REPLY; - goto err; - } - result = Curl_httpsrr_set(lhrr, pcode, cp, plen); - if(result) - goto err; - Curl_httpsrr_trace(data, lhrr); - cp += plen; - len -= plen; - expected_min_pcode = pcode + 1; - } - DEBUGASSERT(!len); - *hrr = lhrr; - return CURLE_OK; -err: - Curl_httpsrr_cleanup(lhrr); - curlx_safefree(lhrr); - return result; -} - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) -static void doh_print_httpsrr(struct Curl_easy *data, - struct Curl_https_rrinfo *hrr) -{ - DEBUGASSERT(hrr); - infof(data, "HTTPS RR: priority %d, target: %s", hrr->priority, hrr->target); - if(hrr->alpns[0] != ALPN_none) - infof(data, "HTTPS RR: alpns %u %u %u %u", - hrr->alpns[0], hrr->alpns[1], hrr->alpns[2], hrr->alpns[3]); - else - infof(data, "HTTPS RR: no alpns"); - if(hrr->no_def_alpn) - infof(data, "HTTPS RR: no_def_alpn set"); - else - infof(data, "HTTPS RR: no_def_alpn not set"); - if(hrr->ipv4hints) { - doh_print_buf(data, "HTTPS RR: ipv4hints", - hrr->ipv4hints, hrr->ipv4hints_len); - } - else - infof(data, "HTTPS RR: no ipv4hints"); - if(hrr->echconfiglist) { - doh_print_buf(data, "HTTPS RR: ECHConfigList", - hrr->echconfiglist, hrr->echconfiglist_len); - } - else - infof(data, "HTTPS RR: no ECHConfigList"); - if(hrr->ipv6hints) { - doh_print_buf(data, "HTTPS RR: ipv6hint", - hrr->ipv6hints, hrr->ipv6hints_len); - } - else - infof(data, "HTTPS RR: no ipv6hints"); -} -# endif -#endif - -CURLcode Curl_doh_take_result(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct Curl_dns_entry **pdns) -{ - struct doh_probes *dohp = async->doh; - CURLcode result = CURLE_OK; - struct dohentry de; - - *pdns = NULL; /* defaults to no response */ - if(!dohp) - return CURLE_OUT_OF_MEMORY; - - if(dohp->probe_resp[DOH_SLOT_IPV4].probe_mid == UINT32_MAX && - dohp->probe_resp[DOH_SLOT_IPV6].probe_mid == UINT32_MAX) { - failf(data, "Could not DoH-resolve: %s", dohp->host); - return async->for_proxy ? - CURLE_COULDNT_RESOLVE_PROXY : CURLE_COULDNT_RESOLVE_HOST; - } - else if(!dohp->pending) { - DOHcode rc[DOH_SLOT_COUNT]; - int slot; - - memset(rc, 0, sizeof(rc)); - /* remove DoH handles from multi handle and close them */ - doh_close(data, async); - /* parse the responses, create the struct and return it! */ - de_init(&de); - for(slot = 0; slot < DOH_SLOT_COUNT; slot++) { - struct doh_response *p = &dohp->probe_resp[slot]; - if(!p->dnstype) - continue; - rc[slot] = doh_resp_decode(curlx_dyn_uptr(&p->body), - curlx_dyn_len(&p->body), - p->dnstype, &de); - if(rc[slot]) { - CURL_TRC_DNS(data, "DoH: %s type %s for %s", doh_strerror(rc[slot]), - doh_type2name(p->dnstype), dohp->host); - } - } /* next slot */ - - if(!rc[DOH_SLOT_IPV4] || !rc[DOH_SLOT_IPV6]) { - /* we have an address, of one kind or other */ - struct Curl_dns_entry *dns; - struct Curl_addrinfo *ai; - - if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) { - CURL_TRC_DNS(data, "hostname: %s", dohp->host); - doh_show(data, &de); - } - - result = doh2ai(&de, dohp->host, dohp->port, &ai); - if(result) - goto error; - - /* we got a response, create a dns entry. */ - dns = Curl_dnscache_mk_entry(data, async->dns_queries, - &ai, dohp->host, dohp->port); - if(!dns) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - /* Now add and HTTPSRR information if we have */ -#ifdef USE_HTTPSRR - if(de.numhttps_rrs > 0 && result == CURLE_OK) { - struct Curl_https_rrinfo *hrr = NULL; - result = doh_resp_decode_httpsrr(data, de.https_rrs->val, - de.https_rrs->len, &hrr); - if(result) { - infof(data, "Failed to decode HTTPS RR"); - Curl_dns_entry_unlink(data, &dns); - goto error; - } - infof(data, "Some HTTPS RR to process"); -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - doh_print_httpsrr(data, hrr); -#endif - Curl_dns_entry_set_https_rr(dns, hrr); - } -#endif /* USE_HTTPSRR */ - - /* and add the entry to the cache */ - result = Curl_dnscache_add(data, dns); - *pdns = dns; - } /* address processing done */ - else { - result = async->for_proxy ? - CURLE_COULDNT_RESOLVE_PROXY : CURLE_COULDNT_RESOLVE_HOST; - } - - } /* !dohp->pending */ - else - /* wait for pending DoH transactions to complete */ - return CURLE_AGAIN; - -error: - de_cleanup(&de); - Curl_doh_cleanup(data, async); - return result; -} - -static void doh_close(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct doh_probes *doh = async ? async->doh : NULL; - if(doh && data->multi) { - struct Curl_easy *probe_data; - uint32_t mid; - size_t slot; - for(slot = 0; slot < DOH_SLOT_COUNT; slot++) { - mid = doh->probe_resp[slot].probe_mid; - if(mid == UINT32_MAX) - continue; - doh->probe_resp[slot].probe_mid = UINT32_MAX; - /* should have been called before data is removed from multi handle */ - DEBUGASSERT(data->multi); - probe_data = data->multi ? Curl_multi_get_easy(data->multi, mid) : NULL; - if(!probe_data) { - DEBUGF(infof(data, "Curl_doh_close: xfer for mid=%u not found!", - doh->probe_resp[slot].probe_mid)); - continue; - } - /* data->multi might already be reset at this time */ - curl_multi_remove_handle(data->multi, probe_data); - Curl_close(&probe_data); - } - data->sub_xfer_done = NULL; - } -} - -void Curl_doh_cleanup(struct Curl_easy *data, - struct Curl_resolv_async *async) -{ - struct doh_probes *dohp = async->doh; - if(dohp) { - int i; - doh_close(data, async); - for(i = 0; i < DOH_SLOT_COUNT; ++i) { - curlx_dyn_free(&dohp->probe_resp[i].body); - } - curlx_safefree(async->doh); - } -} - -#endif /* CURL_DISABLE_DOH */ diff --git a/vendor/curl/lib/doh.h b/vendor/curl/lib/doh.h deleted file mode 100644 index 428b230a5..000000000 --- a/vendor/curl/lib/doh.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef HEADER_CURL_DOH_H -#define HEADER_CURL_DOH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "urldata.h" - -/* enums outside of the #ifdef to make the types work in unitprotos.h even on - builds without DoH support */ - -struct Curl_resolv_async; - -typedef enum { - DOH_OK, - DOH_DNS_BAD_LABEL, /* 1 */ - DOH_DNS_OUT_OF_RANGE, /* 2 */ - DOH_DNS_LABEL_LOOP, /* 3 */ - DOH_TOO_SMALL_BUFFER, /* 4 */ - DOH_OUT_OF_MEM, /* 5 */ - DOH_DNS_RDATA_LEN, /* 6 */ - DOH_DNS_MALFORMAT, /* 7 */ - DOH_DNS_BAD_RCODE, /* 8 - no such name */ - DOH_DNS_UNEXPECTED_TYPE, /* 9 */ - DOH_DNS_UNEXPECTED_CLASS, /* 10 */ - DOH_NO_CONTENT, /* 11 */ - DOH_DNS_BAD_ID, /* 12 */ - DOH_DNS_NAME_TOO_LONG /* 13 */ -} DOHcode; - -typedef enum { - CURL_DNS_TYPE_A = 1, - CURL_DNS_TYPE_NS = 2, - CURL_DNS_TYPE_CNAME = 5, - CURL_DNS_TYPE_AAAA = 28, - CURL_DNS_TYPE_DNAME = 39, /* RFC6672 */ - CURL_DNS_TYPE_HTTPS = 65 -} DNStype; - -struct dohentry; /* forward-declare for non-DoH builds */ - -#ifndef CURL_DISABLE_DOH - -enum doh_slot_num { - /* Explicit values for first two symbols so as to match hard-coded - * constants in existing code - */ - DOH_SLOT_IPV4 = 0, /* make 'V4' stand out for readability */ - DOH_SLOT_IPV6 = 1, /* 'V6' likewise */ - - /* Space here for (possibly build-specific) additional slot definitions */ -#ifdef USE_HTTPSRR - DOH_SLOT_HTTPS_RR = 2, /* for HTTPS RR */ -#endif - - /* for example */ - /* #ifdef WANT_DOH_FOOBAR_TXT */ - /* DOH_PROBE_SLOT_FOOBAR_TXT, */ - /* #endif */ - - /* AFTER all slot definitions, establish how many we have */ - DOH_SLOT_COUNT -}; - -#define CURL_EZM_DOH_PROBE "ezm:doh-p" - -/* the largest one we can make, based on RFCs 1034, 1035 */ -#define DOH_MAX_DNSREQ_SIZE (256 + 16) - -/* each DoH probe request has this - * as easy meta for CURL_EZM_DOH_PROBE */ -struct doh_request { - unsigned char req_body[DOH_MAX_DNSREQ_SIZE]; - struct curl_slist *req_hds; - struct dynbuf resp_body; - size_t req_body_len; - uint32_t resolv_id; /* id of the resolve operation */ - DNStype dnstype; -}; - -struct doh_response { - uint32_t probe_mid; - struct dynbuf body; - DNStype dnstype; - CURLcode result; -}; - -/* each transfer firing off DoH requests has this - * as easy meta for CURL_EZM_DOH_MASTER */ -struct doh_probes { - struct doh_response probe_resp[DOH_SLOT_COUNT]; - unsigned int pending; /* still outstanding probes */ - uint16_t port; - const char *host; -}; - -/* - * Curl_doh() starts a name resolve using DoH (DNS-over-HTTPS). It resolves a - * name and returns a 'Curl_addrinfo *' with the address information. - */ -CURLcode Curl_doh(struct Curl_easy *data, - struct Curl_resolv_async *async); - -CURLcode Curl_doh_take_result(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct Curl_dns_entry **pdns); - -#define DOH_MAX_ADDR 24 -#define DOH_MAX_CNAME 4 -#define DOH_MAX_HTTPS 4 - -struct dohaddr { - int type; - union { - unsigned char v4[4]; /* network byte order */ - unsigned char v6[16]; - } ip; -}; - -#ifdef USE_HTTPSRR - -/* - * These may need escaping when found within an ALPN string - * value. - */ -#define COMMA_CHAR ',' -#define BACKSLASH_CHAR '\\' - -struct dohhttps_rr { - uint16_t len; /* raw encoded length */ - unsigned char *val; /* raw encoded octets */ -}; -#endif - -struct dohentry { - struct dynbuf cname[DOH_MAX_CNAME]; - struct dohaddr addr[DOH_MAX_ADDR]; - int numaddr; - unsigned int ttl; - int numcname; -#ifdef USE_HTTPSRR - struct dohhttps_rr https_rrs[DOH_MAX_HTTPS]; - int numhttps_rrs; -#endif -}; - -void Curl_doh_cleanup(struct Curl_easy *data, - struct Curl_resolv_async *async); -#define Curl_doh_wanted(d) (!!(d)->set.doh) - - -#else /* CURL_DISABLE_DOH */ -#define Curl_doh(a, b) NULL -#define Curl_doh_take_result(x, y, z) CURLE_COULDNT_RESOLVE_HOST -#define Curl_doh_wanted(d) FALSE -#endif /* !CURL_DISABLE_DOH */ - -#endif /* HEADER_CURL_DOH_H */ diff --git a/vendor/curl/lib/dynhds.c b/vendor/curl/lib/dynhds.c deleted file mode 100644 index 097306cec..000000000 --- a/vendor/curl/lib/dynhds.c +++ /dev/null @@ -1,385 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "dynhds.h" -#include "strcase.h" - -static struct dynhds_entry *entry_new(const char *name, size_t namelen, - const char *value, size_t valuelen, - int opts) -{ - struct dynhds_entry *e; - char *p; - - DEBUGASSERT(name); - DEBUGASSERT(value); - e = curlx_calloc(1, sizeof(*e) + namelen + valuelen + 2); - if(!e) - return NULL; - e->name = p = (char *)e + sizeof(*e); - memcpy(p, name, namelen); - e->namelen = namelen; - e->value = p += namelen + 1; /* leave a \0 at the end of name */ - memcpy(p, value, valuelen); - e->valuelen = valuelen; - if(opts & DYNHDS_OPT_LOWERCASE) - Curl_strntolower(e->name, e->name, e->namelen); - return e; -} - -static void entry_free(struct dynhds_entry *e) -{ - curlx_free(e); -} - -void Curl_dynhds_init(struct dynhds *dynhds, size_t max_entries, - size_t max_strs_size) -{ - DEBUGASSERT(dynhds); - DEBUGASSERT(max_strs_size); - dynhds->hds = NULL; - dynhds->hds_len = dynhds->hds_allc = dynhds->strs_len = 0; - dynhds->max_entries = max_entries; - dynhds->max_strs_size = max_strs_size; - dynhds->opts = 0; -} - -void Curl_dynhds_free(struct dynhds *dynhds) -{ - DEBUGASSERT(dynhds); - if(dynhds->hds && dynhds->hds_len) { - size_t i; - DEBUGASSERT(dynhds->hds); - for(i = 0; i < dynhds->hds_len; ++i) { - entry_free(dynhds->hds[i]); - } - } - curlx_safefree(dynhds->hds); - dynhds->hds_len = dynhds->hds_allc = dynhds->strs_len = 0; -} - -void Curl_dynhds_reset(struct dynhds *dynhds) -{ - DEBUGASSERT(dynhds); - if(dynhds->hds_len) { - size_t i; - DEBUGASSERT(dynhds->hds); - for(i = 0; i < dynhds->hds_len; ++i) { - entry_free(dynhds->hds[i]); - dynhds->hds[i] = NULL; - } - } - dynhds->hds_len = dynhds->strs_len = 0; -} - -size_t Curl_dynhds_count(struct dynhds *dynhds) -{ - return dynhds->hds_len; -} - -void Curl_dynhds_set_opts(struct dynhds *dynhds, int opts) -{ - dynhds->opts = opts; -} - -struct dynhds_entry *Curl_dynhds_getn(struct dynhds *dynhds, size_t n) -{ - DEBUGASSERT(dynhds); - return (n < dynhds->hds_len) ? dynhds->hds[n] : NULL; -} - -struct dynhds_entry *Curl_dynhds_get(struct dynhds *dynhds, const char *name, - size_t namelen) -{ - size_t i; - for(i = 0; i < dynhds->hds_len; ++i) { - if(dynhds->hds[i]->namelen == namelen && - curl_strnequal(dynhds->hds[i]->name, name, namelen)) { - return dynhds->hds[i]; - } - } - return NULL; -} - -struct dynhds_entry *Curl_dynhds_cget(struct dynhds *dynhds, const char *name) -{ - return Curl_dynhds_get(dynhds, name, strlen(name)); -} - -CURLcode Curl_dynhds_add(struct dynhds *dynhds, - const char *name, size_t namelen, - const char *value, size_t valuelen) -{ - struct dynhds_entry *entry = NULL; - CURLcode result = CURLE_OUT_OF_MEMORY; - - DEBUGASSERT(dynhds); - if(dynhds->max_entries && dynhds->hds_len >= dynhds->max_entries) - return CURLE_OUT_OF_MEMORY; - if(dynhds->strs_len + namelen + valuelen > dynhds->max_strs_size) - return CURLE_OUT_OF_MEMORY; - - entry = entry_new(name, namelen, value, valuelen, dynhds->opts); - if(!entry) - goto out; - - if(dynhds->hds_len + 1 >= dynhds->hds_allc) { - size_t nallc = dynhds->hds_len + 16; - struct dynhds_entry **nhds; - - if(dynhds->max_entries && nallc > dynhds->max_entries) - nallc = dynhds->max_entries; - - nhds = curlx_calloc(nallc, sizeof(struct dynhds_entry *)); - if(!nhds) - goto out; - if(dynhds->hds) { - memcpy(nhds, dynhds->hds, - dynhds->hds_len * sizeof(struct dynhds_entry *)); - curlx_safefree(dynhds->hds); - } - dynhds->hds = nhds; - dynhds->hds_allc = nallc; - } - dynhds->hds[dynhds->hds_len++] = entry; - entry = NULL; - dynhds->strs_len += namelen + valuelen; - result = CURLE_OK; - -out: - if(entry) - entry_free(entry); - return result; -} - -CURLcode Curl_dynhds_cadd(struct dynhds *dynhds, - const char *name, const char *value) -{ - return Curl_dynhds_add(dynhds, name, strlen(name), value, strlen(value)); -} - -CURLcode Curl_dynhds_h1_add_line(struct dynhds *dynhds, - const char *line, size_t line_len) -{ - const char *p; - const char *name; - size_t namelen; - const char *value; - size_t valuelen, i; - - if(!line || !line_len) - return CURLE_OK; - - p = memchr(line, ':', line_len); - if(!p) - return CURLE_BAD_FUNCTION_ARGUMENT; - name = line; - namelen = p - line; - p++; /* move past the colon */ - for(i = namelen + 1; i < line_len; ++i, ++p) { - if(!ISBLANK(*p)) - break; - } - value = p; - valuelen = line_len - i; - - p = memchr(value, '\r', valuelen); - if(!p) - p = memchr(value, '\n', valuelen); - if(p) - valuelen = (size_t)(p - value); - - return Curl_dynhds_add(dynhds, name, namelen, value, valuelen); -} - -CURLcode Curl_dynhds_h1_cadd_line(struct dynhds *dynhds, const char *line) -{ - return Curl_dynhds_h1_add_line(dynhds, line, line ? strlen(line) : 0); -} - -#ifdef UNITTESTS -/* @unittest 2602 */ - -/** - * Return TRUE iff one or more headers with the given name exist. - */ -UNITTEST bool dynhds_contains(struct dynhds *dynhds, - const char *name, size_t namelen); -UNITTEST bool dynhds_contains(struct dynhds *dynhds, - const char *name, size_t namelen) -{ - return !!Curl_dynhds_get(dynhds, name, namelen); -} - -/* @unittest 2602 */ -UNITTEST bool dynhds_ccontains(struct dynhds *dynhds, const char *name); -UNITTEST bool dynhds_ccontains(struct dynhds *dynhds, const char *name) -{ - return dynhds_contains(dynhds, name, strlen(name)); -} - -/** - * Return how often the given name appears in `dynhds`. - * Names are case-insensitive. - * - * @unittest 2602 - */ -UNITTEST size_t dynhds_count_name(struct dynhds *dynhds, - const char *name, size_t namelen); -UNITTEST size_t dynhds_count_name(struct dynhds *dynhds, - const char *name, size_t namelen) -{ - size_t n = 0; - if(dynhds->hds_len) { - size_t i; - for(i = 0; i < dynhds->hds_len; ++i) { - if((namelen == dynhds->hds[i]->namelen) && - curl_strnequal(name, dynhds->hds[i]->name, namelen)) - ++n; - } - } - return n; -} - -/** - * Return how often the given null-terminated name appears in `dynhds`. - * Names are case-insensitive. - * - * @unittest 2602 - */ -UNITTEST size_t dynhds_ccount_name(struct dynhds *dynhds, - const char *name); -UNITTEST size_t dynhds_ccount_name(struct dynhds *dynhds, - const char *name) -{ - return dynhds_count_name(dynhds, name, strlen(name)); -} - -/** - * Remove all entries with the given name. - * Returns number of entries removed. - * - * @unittest 2602 - */ -UNITTEST size_t dynhds_remove(struct dynhds *dynhds, - const char *name, size_t namelen); -UNITTEST size_t dynhds_remove(struct dynhds *dynhds, - const char *name, size_t namelen) -{ - size_t n = 0; - if(dynhds->hds_len) { - size_t i, len; - for(i = 0; i < dynhds->hds_len; ++i) { - if((namelen == dynhds->hds[i]->namelen) && - curl_strnequal(name, dynhds->hds[i]->name, namelen)) { - ++n; - --dynhds->hds_len; - dynhds->strs_len -= (dynhds->hds[i]->namelen + - dynhds->hds[i]->valuelen); - entry_free(dynhds->hds[i]); - len = dynhds->hds_len - i; /* remaining entries */ - if(len) { - memmove(&dynhds->hds[i], &dynhds->hds[i + 1], - len * sizeof(dynhds->hds[i])); - } - --i; /* do this index again */ - } - } - } - return n; -} - -/** - * Set the give header name and value, replacing any entries with - * the same name. The header is added at the end of all (remaining) - * entries. - * - * @unittest 2602 - */ -UNITTEST CURLcode dynhds_set(struct dynhds *dynhds, - const char *name, size_t namelen, - const char *value, size_t valuelen); -UNITTEST CURLcode dynhds_set(struct dynhds *dynhds, - const char *name, size_t namelen, - const char *value, size_t valuelen) -{ - dynhds_remove(dynhds, name, namelen); - return Curl_dynhds_add(dynhds, name, namelen, value, valuelen); -} - -/* @unittest 2602 */ -UNITTEST size_t dynhds_cremove(struct dynhds *dynhds, const char *name); -UNITTEST size_t dynhds_cremove(struct dynhds *dynhds, const char *name) -{ - return dynhds_remove(dynhds, name, strlen(name)); -} - -#endif /* UNITTESTS */ - -CURLcode Curl_dynhds_h1_dprint(struct dynhds *dynhds, struct dynbuf *dbuf) -{ - CURLcode result = CURLE_OK; - size_t i; - - if(!dynhds->hds_len) - return result; - - for(i = 0; i < dynhds->hds_len; ++i) { - result = curlx_dyn_addf(dbuf, "%.*s: %.*s\r\n", - (int)dynhds->hds[i]->namelen, dynhds->hds[i]->name, - (int)dynhds->hds[i]->valuelen, - dynhds->hds[i]->value); - if(result) - break; - } - - return result; -} - -#ifdef USE_NGHTTP2 - -nghttp2_nv *Curl_dynhds_to_nva(struct dynhds *dynhds, size_t *pcount) -{ - nghttp2_nv *nva = curlx_calloc(1, sizeof(nghttp2_nv) * dynhds->hds_len); - size_t i; - - *pcount = 0; - if(!nva) - return NULL; - - for(i = 0; i < dynhds->hds_len; ++i) { - struct dynhds_entry *e = dynhds->hds[i]; - DEBUGASSERT(e); - nva[i].name = (unsigned char *)e->name; - nva[i].namelen = e->namelen; - nva[i].value = (unsigned char *)e->value; - nva[i].valuelen = e->valuelen; - nva[i].flags = NGHTTP2_NV_FLAG_NONE; - } - *pcount = dynhds->hds_len; - return nva; -} - -#endif /* USE_NGHTTP2 */ diff --git a/vendor/curl/lib/dynhds.h b/vendor/curl/lib/dynhds.h deleted file mode 100644 index d5337eb35..000000000 --- a/vendor/curl/lib/dynhds.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef HEADER_CURL_DYNHDS_H -#define HEADER_CURL_DYNHDS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/dynbuf.h" - -struct dynbuf; - -/** - * A single header entry. - * `name` and `value` are non-NULL and always null-terminated. - */ -struct dynhds_entry { - char *name; - char *value; - size_t namelen; - size_t valuelen; -}; - -struct dynhds { - struct dynhds_entry **hds; - size_t hds_len; /* number of entries in hds */ - size_t hds_allc; /* size of hds allocation */ - size_t max_entries; /* size limit number of entries */ - size_t strs_len; /* length of all strings */ - size_t max_strs_size; /* max length of all strings */ - int opts; -}; - -#define DYNHDS_OPT_NONE 0 -#define DYNHDS_OPT_LOWERCASE (1 << 0) - -/** - * Init for use on first time or after a reset. - * Allow `max_entries` headers to be added, 0 for unlimited. - * Allow size of all name and values added to not exceed `max_strs_size`` - */ -void Curl_dynhds_init(struct dynhds *dynhds, size_t max_entries, - size_t max_strs_size); -/** - * Frees all data held in `dynhds`, but not the struct itself. - */ -void Curl_dynhds_free(struct dynhds *dynhds); - -/** - * Reset `dyndns` to the initial init state. May keep allocations - * around. - */ -void Curl_dynhds_reset(struct dynhds *dynhds); - -/** - * Return the number of header entries. - */ -size_t Curl_dynhds_count(struct dynhds *dynhds); - -/** - * Set the options to use, replacing any existing ones. - * This will not have an effect on already existing headers. - */ -void Curl_dynhds_set_opts(struct dynhds *dynhds, int opts); - -/** - * Return the n-th header entry or NULL if it does not exist. - */ -struct dynhds_entry *Curl_dynhds_getn(struct dynhds *dynhds, size_t n); - -/** - * Return the 1st header entry of the name or NULL if none exists. - */ -struct dynhds_entry *Curl_dynhds_get(struct dynhds *dynhds, - const char *name, size_t namelen); -struct dynhds_entry *Curl_dynhds_cget(struct dynhds *dynhds, const char *name); - -CURLcode Curl_dynhds_cset(struct dynhds *dynhds, - const char *name, const char *value); - -/** - * Add a header, name + value, to `dynhds` at the end. Does *not* - * check for duplicate names. - */ -CURLcode Curl_dynhds_add(struct dynhds *dynhds, - const char *name, size_t namelen, - const char *value, size_t valuelen); - -/** - * Add a header, c-string name + value, to `dynhds` at the end. - */ -CURLcode Curl_dynhds_cadd(struct dynhds *dynhds, - const char *name, const char *value); - -/** - * Add a single header from an HTTP/1.1 formatted line at the end. Line may - * contain a delimiting CRLF or LF. Any characters after that will be ignored. - */ -CURLcode Curl_dynhds_h1_cadd_line(struct dynhds *dynhds, const char *line); - -/** - * Add a single header from an HTTP/1.1 formatted line at the end. Line may - * contain a delimiting CRLF or LF. Any characters after that will be ignored. - */ -CURLcode Curl_dynhds_h1_add_line(struct dynhds *dynhds, - const char *line, size_t line_len); - -/** - * Add the headers to the given `dynbuf` in HTTP/1.1 format with - * CR+LF line endings. Does NOT output a last empty line. - */ -CURLcode Curl_dynhds_h1_dprint(struct dynhds *dynhds, struct dynbuf *dbuf); - -#ifdef USE_NGHTTP2 - -#include - -nghttp2_nv *Curl_dynhds_to_nva(struct dynhds *dynhds, size_t *pcount); - -#endif /* USE_NGHTTP2 */ - -#endif /* HEADER_CURL_DYNHDS_H */ diff --git a/vendor/curl/lib/easy.c b/vendor/curl/lib/easy.c deleted file mode 100644 index 82ea2d0a1..000000000 --- a/vendor/curl/lib/easy.c +++ /dev/null @@ -1,1401 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "urldata.h" -#include "transfer.h" -#include "vtls/vtls.h" -#include "vtls/vtls_scache.h" -#include "vquic/vquic.h" -#include "url.h" -#include "getinfo.h" -#include "hostip.h" -#include "curlx/strdup.h" -#include "easyif.h" -#include "multiif.h" -#include "multi_ev.h" -#include "select.h" -#include "cfilters.h" -#include "sendf.h" -#include "curl_trc.h" -#include "connect.h" /* for Curl_getconnectinfo */ -#include "slist.h" -#include "mime.h" -#include "amigaos.h" -#include "macos.h" -#include "curlx/wait.h" -#include "sigpipe.h" -#include "vssh/ssh.h" -#include "setopt.h" -#include "http_digest.h" -#include "system_win32.h" -#include "curlx/dynbuf.h" -#include "bufref.h" -#include "altsvc.h" -#include "hsts.h" - -#include "easy_lock.h" - -/* true globals -- for curl_global_init() and curl_global_cleanup() */ -static unsigned int initialized; -static long easy_init_flags; - -#ifdef GLOBAL_INIT_IS_THREADSAFE - -static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT; -#define global_init_lock() curl_simple_lock_lock(&s_lock) -#define global_init_unlock() curl_simple_lock_unlock(&s_lock) - -#else - -#define global_init_lock() -#define global_init_unlock() - -#endif - -#if defined(_MSC_VER) && defined(_DLL) -# pragma warning(push) -# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ -#endif - -/* - * If a memory-using function (like curl_getenv) is used before - * curl_global_init() is called, we need to have these pointers set already. - */ -curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; -curl_free_callback Curl_cfree = (curl_free_callback)free; -curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; -curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)CURLX_STRDUP_LOW; -curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; - -#if defined(_MSC_VER) && defined(_DLL) -# pragma warning(pop) -#endif - -#ifdef DEBUGBUILD -static char *leakpointer; -#endif - -/** - * curl_global_init() globally initializes curl given a bitwise set of the - * different features of what to initialize. - */ -static CURLcode global_init(long flags, bool memoryfuncs) -{ - if(initialized++) - return CURLE_OK; - - if(memoryfuncs) { - /* Setup the default memory functions here (again) */ - Curl_cmalloc = (curl_malloc_callback)malloc; - Curl_cfree = (curl_free_callback)free; - Curl_crealloc = (curl_realloc_callback)realloc; - Curl_cstrdup = (curl_strdup_callback)CURLX_STRDUP_LOW; - Curl_ccalloc = (curl_calloc_callback)calloc; - } - - if(Curl_trc_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_trc_init failed\n")); - goto fail; - } - - if(Curl_win32_init(flags)) { - DEBUGF(curl_mfprintf(stderr, "Error: win32_init failed\n")); - goto fail; - } - - if(!Curl_ssl_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_ssl_init failed\n")); - goto fail; - } - - if(!Curl_vquic_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_vquic_init failed\n")); - goto fail; - } - - if(Curl_amiga_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_amiga_init failed\n")); - goto fail; - } - - if(Curl_macos_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_macos_init failed\n")); - goto fail; - } - - if(Curl_async_global_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: resolver_global_init failed\n")); - goto fail; - } - - if(Curl_ssh_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_ssh_init failed\n")); - goto fail; - } - - easy_init_flags = flags; - -#ifdef DEBUGBUILD - if(getenv("CURL_GLOBAL_INIT")) - /* alloc data that will leak if *cleanup() is not called! */ - leakpointer = curlx_malloc(1); -#endif - - return CURLE_OK; - -fail: - initialized--; /* undo the increase */ - return CURLE_FAILED_INIT; -} - -/** - * curl_global_init() globally initializes curl given a bitwise set of the - * different features of what to initialize. - */ -CURLcode curl_global_init(long flags) -{ - CURLcode result; - global_init_lock(); - - result = global_init(flags, TRUE); - - global_init_unlock(); - - return result; -} - -/* - * curl_global_init_mem() globally initializes curl and also registers the - * user provided callback routines. - */ -CURLcode curl_global_init_mem(long flags, curl_malloc_callback m, - curl_free_callback f, curl_realloc_callback r, - curl_strdup_callback s, curl_calloc_callback c) -{ - CURLcode result; - - /* Invalid input, return immediately */ - if(!m || !f || !r || !s || !c) - return CURLE_FAILED_INIT; - - global_init_lock(); - - if(initialized) { - /* Already initialized, do not do it again, but bump the variable anyway to - work like curl_global_init() and require the same amount of cleanup - calls. */ - initialized++; - global_init_unlock(); - return CURLE_OK; - } - - /* set memory functions before global_init() in case it wants memory - functions */ - Curl_cmalloc = m; - Curl_cfree = f; - Curl_cstrdup = s; - Curl_crealloc = r; - Curl_ccalloc = c; - - /* Call the actual init function, but without setting */ - result = global_init(flags, FALSE); - - global_init_unlock(); - - return result; -} - -/** - * curl_global_cleanup() globally cleanups curl, uses the value of - * "easy_init_flags" to determine what needs to be cleaned up and what does - * not. - */ -void curl_global_cleanup(void) -{ - global_init_lock(); - - if(!initialized) { - global_init_unlock(); - return; - } - - if(--initialized) { - global_init_unlock(); - return; - } - - Curl_ssl_cleanup(); - Curl_async_global_cleanup(); - -#ifdef _WIN32 - Curl_win32_cleanup(easy_init_flags); -#endif - - Curl_amiga_cleanup(); - - Curl_ssh_cleanup(); - -#ifdef DEBUGBUILD - curlx_free(leakpointer); -#endif - - easy_init_flags = 0; - - global_init_unlock(); -} - -/** - * curl_global_trace() globally initializes curl logging. - */ -CURLcode curl_global_trace(const char *config) -{ -#ifndef CURL_DISABLE_VERBOSE_STRINGS - CURLcode result; - global_init_lock(); - - result = Curl_trc_opt(config); - - global_init_unlock(); - - return result; -#else - (void)config; - return CURLE_OK; -#endif -} - -/* - * curl_global_sslset() globally initializes the SSL backend to use. - */ -CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail) -{ - CURLsslset rc; - - global_init_lock(); - - rc = Curl_init_sslset_nolock(id, name, avail); - - global_init_unlock(); - - return rc; -} - -/* - * curl_easy_init() is the external interface to alloc, setup and init an - * easy handle that is returned. If anything goes wrong, NULL is returned. - */ -CURL *curl_easy_init(void) -{ - CURLcode result; - struct Curl_easy *data; - - /* Make sure we inited the global SSL stuff */ - global_init_lock(); - - if(!initialized) { - result = global_init(CURL_GLOBAL_DEFAULT, TRUE); - if(result) { - /* something in the global init failed, return nothing */ - DEBUGF(curl_mfprintf(stderr, "Error: curl_global_init failed\n")); - global_init_unlock(); - return NULL; - } - } - global_init_unlock(); - - /* We use Curl_open() with undefined URL so far */ - result = Curl_open(&data); - if(result) { - DEBUGF(curl_mfprintf(stderr, "Error: Curl_open failed\n")); - return NULL; - } - - return data; -} - -#ifdef DEBUGBUILD - -struct socketmonitor { - struct socketmonitor *next; /* the next node in the list or NULL */ - struct pollfd socket; /* socket info of what to monitor */ -}; - -struct events { - long ms; /* timeout, run the timeout function when reached */ - bool msbump; /* set TRUE when timeout is set by callback */ - int num_sockets; /* number of nodes in the monitor list */ - struct socketmonitor *list; /* list of sockets to monitor */ - int running_handles; /* store the returned number */ -}; - -#define DEBUG_EV_POLL 0 - -/* events_timer - * - * Callback that gets called with a new value when the timeout should be - * updated. - */ -static int events_timer(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp) /* private callback pointer */ -{ - struct events *ev = userp; - (void)multi; -#if DEBUG_EV_POLL - curl_mfprintf(stderr, "events_timer: set timeout %ldms\n", timeout_ms); -#endif - ev->ms = timeout_ms; - ev->msbump = TRUE; - return 0; -} - -/* poll2cselect - * - * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones - */ -static int poll2cselect(int pollmask) -{ - int omask = 0; - if(pollmask & POLLIN) - omask |= CURL_CSELECT_IN; - if(pollmask & POLLOUT) - omask |= CURL_CSELECT_OUT; - if(pollmask & POLLERR) - omask |= CURL_CSELECT_ERR; - return omask; -} - -/* socketcb2poll - * - * convert from libcurl' CURL_POLL_* bit definitions to poll()'s - */ -static short socketcb2poll(int pollmask) -{ - short omask = 0; - if(pollmask & CURL_POLL_IN) - omask |= POLLIN; - if(pollmask & CURL_POLL_OUT) - omask |= POLLOUT; - return omask; -} - -/* events_socket - * - * Callback that gets called with information about socket activity to - * monitor. - */ -static int events_socket(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp) /* private socket - pointer */ -{ - struct events *ev = userp; - struct socketmonitor *m; - struct socketmonitor *prev = NULL; - bool found = FALSE; - struct Curl_easy *data = easy; - -#ifdef CURL_DISABLE_VERBOSE_STRINGS - (void)easy; -#endif - (void)socketp; - - m = ev->list; - while(m) { - if(m->socket.fd == s) { - found = TRUE; - if(what == CURL_POLL_REMOVE) { - struct socketmonitor *nxt = m->next; - /* remove this node from the list of monitored sockets */ - if(prev) - prev->next = nxt; - else - ev->list = nxt; - curlx_free(m); - infof(data, "socket cb: socket %" FMT_SOCKET_T " REMOVED", s); - } - else { - /* The socket 's' is already being monitored, update the activity - mask. Convert from libcurl bitmask to the poll one. */ - m->socket.events = socketcb2poll(what); - infof(data, "socket cb: socket %" FMT_SOCKET_T " UPDATED as %s%s", s, - (what & CURL_POLL_IN) ? "IN" : "", - (what & CURL_POLL_OUT) ? "OUT" : ""); - } - break; - } - prev = m; - m = m->next; /* move to next node */ - } - - if(!found) { - if(what == CURL_POLL_REMOVE) { - /* should not happen if our logic is correct, but is no drama. */ - DEBUGF(infof(data, "socket cb: asked to REMOVE socket %" - FMT_SOCKET_T "but not present!", s)); - DEBUGASSERT(0); - } - else { - m = curlx_malloc(sizeof(struct socketmonitor)); - if(m) { - m->next = ev->list; - m->socket.fd = s; - m->socket.events = socketcb2poll(what); - m->socket.revents = 0; - ev->list = m; - infof(data, "socket cb: socket %" FMT_SOCKET_T " ADDED as %s%s", s, - (what & CURL_POLL_IN) ? "IN" : "", - (what & CURL_POLL_OUT) ? "OUT" : ""); - } - else - return CURLE_OUT_OF_MEMORY; - } - } - - return 0; -} - -/* - * events_setup() - * - * Do the multi handle setups that only event-based transfers need. - */ -static void events_setup(struct Curl_multi *multi, struct events *ev) -{ - /* timer callback */ - curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer); - curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev); - - /* socket callback */ - curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket); - curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev); -} - -/* populate_fds() - * - * populate the fds[] array - */ -static unsigned int populate_fds(struct pollfd *fds, struct events *ev) -{ - unsigned int numfds = 0; - struct pollfd *f; - struct socketmonitor *m; - - f = &fds[0]; - for(m = ev->list; m; m = m->next) { - f->fd = m->socket.fd; - f->events = m->socket.events; - f->revents = 0; -#if DEBUG_EV_POLL - curl_mfprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); -#endif - f++; - numfds++; - } - return numfds; -} - -/* poll_fds() - * - * poll the fds[] array - */ -static CURLcode poll_fds(struct events *ev, - struct pollfd *fds, - const unsigned int numfds, - int *pollrc) -{ - if(numfds) { - /* wait for activity or timeout */ -#if DEBUG_EV_POLL - curl_mfprintf(stderr, "poll(numfds=%u, timeout=%ldms)\n", numfds, ev->ms); -#endif - *pollrc = Curl_poll(fds, numfds, ev->ms); -#if DEBUG_EV_POLL - curl_mfprintf(stderr, "poll(numfds=%u, timeout=%ldms) -> %d\n", - numfds, ev->ms, *pollrc); -#endif - if(*pollrc < 0) - return CURLE_UNRECOVERABLE_POLL; - } - else { -#if DEBUG_EV_POLL - curl_mfprintf(stderr, "poll, but no fds, wait timeout=%ldms\n", ev->ms); -#endif - *pollrc = 0; - if(ev->ms > 0) - curlx_wait_ms(ev->ms); - } - return CURLE_OK; -} - -/* wait_or_timeout() - * - * waits for activity on any of the given sockets, or the timeout to trigger. - */ -static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) -{ - bool done = FALSE; - CURLMcode mresult = CURLM_OK; - CURLcode result = CURLE_OK; - - while(!done) { - CURLMsg *msg; - struct pollfd fds[4]; - int pollrc; - struct curltime start; - const unsigned int numfds = populate_fds(fds, ev); - - /* get the time stamp to use to figure out how long poll takes */ - curlx_pnow(&start); - - result = poll_fds(ev, fds, numfds, &pollrc); - if(result) - return result; - - ev->msbump = FALSE; /* reset here */ - - if(!pollrc) { - /* timeout! */ - ev->ms = 0; -#if 0 - curl_mfprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); -#endif - mresult = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, - &ev->running_handles); - } - else { - /* here pollrc is > 0 */ - /* loop over the monitored sockets to see which ones had activity */ - unsigned int i; - for(i = 0; i < numfds; i++) { - if(fds[i].revents) { - /* socket activity, tell libcurl */ - int act = poll2cselect(fds[i].revents); /* convert */ - - /* sending infof "randomly" to the first easy handle */ - infof(multi->admin, "call curl_multi_socket_action(socket " - "%" FMT_SOCKET_T ")", (curl_socket_t)fds[i].fd); - mresult = curl_multi_socket_action(multi, fds[i].fd, act, - &ev->running_handles); - } - } - - if(!ev->msbump && ev->ms >= 0) { - /* If nothing updated the timeout, we decrease it by the spent time. - * If it was updated, it has the new timeout time stored already. - */ - timediff_t spent_ms = curlx_timediff_ms(curlx_now(), start); - if(spent_ms > 0) { -#if DEBUG_EV_POLL - curl_mfprintf(stderr, "poll timeout %ldms not updated, decrease by " - "time spent %ldms\n", ev->ms, (long)spent_ms); -#endif - if(spent_ms > ev->ms) - ev->ms = 0; - else - ev->ms -= (long)spent_ms; - } - } - } - - if(mresult) - return CURLE_URL_MALFORMAT; - - /* we do not really care about the "msgs_in_queue" value returned in the - second argument */ - msg = curl_multi_info_read(multi, &pollrc); - if(msg) { - result = msg->data.result; - done = TRUE; - } - } - - return result; -} - -/* easy_events() - * - * Runs a transfer in a blocking manner using the events-based API - */ -static CURLcode easy_events(struct Curl_multi *multi) -{ - /* this struct is made static to allow it to be used after this function - returns and curl_multi_remove_handle() is called */ - static struct events evs = { -1, FALSE, 0, NULL, 0 }; - - /* if running event-based, do some further multi inits */ - events_setup(multi, &evs); - - return wait_or_timeout(multi, &evs); -} -#else /* DEBUGBUILD */ -/* when not built with debug, this function does not exist */ -#define easy_events(x) CURLE_NOT_BUILT_IN -#endif - -static CURLcode easy_transfer(struct Curl_multi *multi) -{ - bool done = FALSE; - CURLMcode mresult = CURLM_OK; - CURLcode result = CURLE_OK; - - while(!done && !mresult) { - int still_running = 0; - - mresult = curl_multi_poll(multi, NULL, 0, 1000, NULL); - - if(!mresult) - mresult = curl_multi_perform(multi, &still_running); - - /* only read 'still_running' if curl_multi_perform() return OK */ - if(!mresult && !still_running) { - int rc; - CURLMsg *msg = curl_multi_info_read(multi, &rc); - if(msg) { - result = msg->data.result; - done = TRUE; - } - } - } - - /* Make sure to return some kind of error if there was a multi problem */ - if(mresult) { - result = (mresult == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : - /* The other multi errors should never happen, so return - something suitably generic */ - CURLE_BAD_FUNCTION_ARGUMENT; - } - - return result; -} - -/* - * easy_perform() is the internal interface that performs a blocking - * transfer as previously setup. - * - * CONCEPT: This function creates a multi handle, adds the easy handle to it, - * runs curl_multi_perform() until the transfer is done, then detaches the - * easy handle, destroys the multi handle and returns the easy handle's return - * code. - * - * REALITY: it cannot create and destroy the multi handle that easily. It - * needs to keep it around since if this easy handle is used again by this - * function, the same multi handle must be reused so that the same pools and - * caches can be used. - * - * DEBUG: if 'events' is set TRUE, this function will use a replacement engine - * instead of curl_multi_perform() and use curl_multi_socket_action(). - */ -static CURLcode easy_perform(struct Curl_easy *data, bool events) -{ - struct Curl_multi *multi; - CURLMcode mresult; - CURLcode result = CURLE_OK; - struct Curl_sigpipe_ctx sigpipe_ctx; - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(data->set.errorbuffer) - /* clear this as early as possible */ - data->set.errorbuffer[0] = 0; - - data->state.os_errno = 0; - - if(data->multi) { - failf(data, "easy handle already used in multi handle"); - return CURLE_FAILED_INIT; - } - - /* if the handle has a connection still attached (it is/was a connect-only - handle) then disconnect before performing */ - if(data->conn) { - struct connectdata *c; - curl_socket_t s; - Curl_detach_connection(data); - s = Curl_getconnectinfo(data, &c); - if((s != CURL_SOCKET_BAD) && c) { - Curl_conn_terminate(data, c, TRUE); - } - DEBUGASSERT(!data->conn); - } - - if(data->multi_easy) - multi = data->multi_easy; - else { - /* this multi handle will only ever have a single easy handle attached to - it, so make it use minimal hash sizes */ - multi = Curl_multi_handle(16, 1, 3, 7, 3); - if(!multi) - return CURLE_OUT_OF_MEMORY; - } - - if(multi->in_callback) - return CURLE_RECURSIVE_API_CALL; - - /* Copy relevant easy options to the multi handle */ - curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, (long)data->set.maxconnects); - curl_multi_setopt(multi, CURLMOPT_QUICK_EXIT, (long)data->set.quick_exit); - - data->multi_easy = NULL; /* pretend it does not exist */ - mresult = curl_multi_add_handle(multi, data); - if(mresult) { - curl_multi_cleanup(multi); - if(mresult == CURLM_OUT_OF_MEMORY) - return CURLE_OUT_OF_MEMORY; - return CURLE_FAILED_INIT; - } - - /* assign this after curl_multi_add_handle() */ - data->multi_easy = multi; - - sigpipe_init(&sigpipe_ctx); - sigpipe_apply(data, &sigpipe_ctx); - - /* run the transfer */ - result = events ? easy_events(multi) : easy_transfer(multi); - - /* ignoring the return code is not nice, but atm we cannot really handle - a failure here, room for future improvement! */ - (void)curl_multi_remove_handle(multi, data); - - sigpipe_restore(&sigpipe_ctx); - - /* The multi handle is kept alive, owned by the easy handle */ - return result; -} - -/* - * curl_easy_perform() is the external interface that performs a blocking - * transfer as previously setup. - */ -CURLcode curl_easy_perform(CURL *curl) -{ - return easy_perform(curl, FALSE); -} - -#ifdef DEBUGBUILD -/* - * curl_easy_perform_ev() is the external interface that performs a blocking - * transfer using the event-based API internally. - */ -CURLcode curl_easy_perform_ev(struct Curl_easy *easy) -{ - return easy_perform(easy, TRUE); -} -#endif - -/* - * curl_easy_cleanup() is the external interface to cleaning/freeing the given - * easy handle. - */ -void curl_easy_cleanup(CURL *curl) -{ - struct Curl_easy *data = curl; - if(GOOD_EASY_HANDLE(data)) { - struct Curl_sigpipe_ctx sigpipe_ctx; - sigpipe_ignore(data, &sigpipe_ctx); - Curl_close(&data); - sigpipe_restore(&sigpipe_ctx); - } -} - -/* - * curl_easy_getinfo() is an external interface that allows an app to retrieve - * information from a performed transfer and similar. - */ -#undef curl_easy_getinfo -CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...) -{ - struct Curl_easy *data = curl; - va_list arg; - void *paramp; - CURLcode result; - - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - va_start(arg, info); - paramp = va_arg(arg, void *); - - result = Curl_getinfo(data, info, paramp); - - va_end(arg); - return result; -} - -static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) -{ - CURLcode result = CURLE_OK; - enum dupstring i; - enum dupblob j; - - /* Copy src->set into dst->set first, then deal with the strings - afterwards */ - dst->set = src->set; -#if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) - dst->set.mimepostp = NULL; -#endif - /* clear all dest string and blob pointers first, in case we error out - mid-function */ - memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); - memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *)); - - /* duplicate all strings */ - for(i = (enum dupstring)0; i < STRING_LASTZEROTERMINATED; i++) { - result = Curl_setstropt(&dst->set.str[i], src->set.str[i]); - if(result) - return result; - } - - /* duplicate all blobs */ - for(j = (enum dupblob)0; j < BLOB_LAST; j++) { - result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]); - if(result) - return result; - } - - /* duplicate memory areas pointed to */ - i = STRING_COPYPOSTFIELDS; - if(src->set.str[i]) { - if(src->set.postfieldsize == -1) - dst->set.str[i] = curlx_strdup(src->set.str[i]); - else - /* postfieldsize is curl_off_t, curlx_memdup() takes a size_t ... */ - dst->set.str[i] = curlx_memdup(src->set.str[i], - curlx_sotouz(src->set.postfieldsize)); - if(!dst->set.str[i]) - return CURLE_OUT_OF_MEMORY; - /* point to the new copy */ - dst->set.postfields = dst->set.str[i]; - } - -#if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) - if(src->set.mimepostp) { - /* Duplicate mime data. Get a mimepost struct for the clone as well */ - dst->set.mimepostp = curlx_malloc(sizeof(*dst->set.mimepostp)); - if(!dst->set.mimepostp) - return CURLE_OUT_OF_MEMORY; - - Curl_mime_initpart(dst->set.mimepostp); - result = Curl_mime_duppart(dst, dst->set.mimepostp, src->set.mimepostp); - if(result) - return result; - } -#endif - - if(src->set.resolve) - dst->state.resolve = dst->set.resolve; - - return result; -} - -static void dupeasy_meta_freeentry(void *p) -{ - (void)p; - /* Always FALSE. Cannot use a 0 assert here since compilers - * are not in agreement if they then want a NORETURN attribute or - * not. *sigh* */ - DEBUGASSERT(p == NULL); -} - -/* - * curl_easy_duphandle() is an external interface to allow duplication of a - * given input easy handle. The returned handle will be a new working handle - * with all options set exactly as the input source handle. - */ -CURL *curl_easy_duphandle(CURL *curl) -{ - struct Curl_easy *data = curl; - struct Curl_easy *outcurl = NULL; - - if(!GOOD_EASY_HANDLE(data)) - goto fail; - outcurl = curlx_calloc(1, sizeof(struct Curl_easy)); - if(!outcurl) - goto fail; - - /* - * We setup a few buffers we need. We should probably make them - * get setup on-demand in the code, as that would probably decrease - * the likeliness of us forgetting to init a buffer here in the future. - */ - outcurl->set.buffer_size = data->set.buffer_size; - - Curl_hash_init(&outcurl->meta_hash, 23, - Curl_hash_str, curlx_str_key_compare, dupeasy_meta_freeentry); - curlx_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER); - Curl_bufref_init(&outcurl->state.url); - Curl_bufref_init(&outcurl->state.referer); - Curl_netrc_init(&outcurl->state.netrc); - - /* the connection pool is setup on demand */ - outcurl->state.lastconnect_id = -1; - outcurl->state.recent_conn_id = -1; - outcurl->id = -1; - outcurl->mid = UINT32_MAX; - outcurl->master_mid = UINT32_MAX; - -#ifndef CURL_DISABLE_HTTP - Curl_llist_init(&outcurl->state.httphdrs, NULL); -#endif - Curl_initinfo(outcurl); - - /* copy all userdefined values */ - if(dupset(outcurl, data)) - goto fail; - - outcurl->progress.hide = data->progress.hide; - outcurl->progress.callback = data->progress.callback; - -#ifndef CURL_DISABLE_COOKIES - outcurl->state.cookielist = NULL; - if(data->cookies && data->state.cookie_engine) { - /* If cookies are enabled in the parent handle, we enable them - in the clone as well! */ - outcurl->cookies = Curl_cookie_init(); - if(!outcurl->cookies) - goto fail; - outcurl->state.cookie_engine = TRUE; - } - - if(data->state.cookielist) { - outcurl->state.cookielist = Curl_slist_duplicate(data->state.cookielist); - if(!outcurl->state.cookielist) - goto fail; - } -#endif - - if(Curl_bufref_ptr(&data->state.url)) { - Curl_bufref_set(&outcurl->state.url, - Curl_bufref_dup(&data->state.url), 0, - curl_free); - if(!Curl_bufref_ptr(&outcurl->state.url)) - goto fail; - } - if(Curl_bufref_ptr(&data->state.referer)) { - Curl_bufref_set(&outcurl->state.referer, - Curl_bufref_dup(&data->state.referer), 0, - curl_free); - if(!Curl_bufref_ptr(&outcurl->state.referer)) - goto fail; - } - - /* Reinitialize an SSL engine for the new handle - * note: the engine name has already been copied by dupset */ - if(outcurl->set.str[STRING_SSL_ENGINE]) { - if(Curl_ssl_set_engine(outcurl, outcurl->set.str[STRING_SSL_ENGINE])) - goto fail; - } - -#ifndef CURL_DISABLE_ALTSVC - if(data->asi) { - outcurl->asi = Curl_altsvc_init(); - if(!outcurl->asi) - goto fail; - if(outcurl->set.str[STRING_ALTSVC]) - (void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]); - } -#endif -#ifndef CURL_DISABLE_HSTS - if(data->hsts) { - outcurl->hsts = Curl_hsts_init(); - if(!outcurl->hsts) - goto fail; - if(outcurl->set.str[STRING_HSTS]) - (void)Curl_hsts_loadfile(outcurl, - outcurl->hsts, outcurl->set.str[STRING_HSTS]); - (void)Curl_hsts_loadcb(outcurl, outcurl->hsts); - } -#endif - - outcurl->magic = CURLEASY_MAGIC_NUMBER; - - /* we reach this point and thus we are OK */ - - return outcurl; - -fail: - - if(outcurl) { -#ifndef CURL_DISABLE_COOKIES - curlx_free(outcurl->cookies); -#endif - curlx_dyn_free(&outcurl->state.headerb); - Curl_altsvc_cleanup(&outcurl->asi); - Curl_hsts_cleanup(&outcurl->hsts); - Curl_freeset(outcurl); - curlx_free(outcurl); - } - - return NULL; -} - -/* - * curl_easy_reset() is an external interface that allows an app to re- - * initialize a session handle to the default values. - */ -void curl_easy_reset(CURL *curl) -{ - struct Curl_easy *data = curl; - if(!GOOD_EASY_HANDLE(data)) - return; - - Curl_req_hard_reset(&data->req, data); - Curl_hash_clean(&data->meta_hash); - - /* clear all meta data */ - Curl_meta_reset(data); - /* zero out UserDefined data: */ - Curl_freeset(data); - memset(&data->set, 0, sizeof(struct UserDefined)); - Curl_init_userdefined(data); - - /* zero out Progress data: */ - memset(&data->progress, 0, sizeof(struct Progress)); - - /* zero out PureInfo data: */ - Curl_initinfo(data); - - data->progress.hide = TRUE; - data->state.current_speed = -1; /* init to negative == impossible */ - data->state.recent_conn_id = -1; /* clear remembered connection id */ - - /* zero out authentication data: */ - memset(&data->state.authhost, 0, sizeof(struct auth)); - memset(&data->state.authproxy, 0, sizeof(struct auth)); - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) - Curl_http_auth_cleanup_digest(data); -#endif - data->master_mid = UINT32_MAX; -} - -/* - * curl_easy_pause() allows an application to pause or unpause a specific - * transfer and direction. This function sets the full new state for the - * current connection this easy handle operates on. - * - * NOTE: if you have the receiving paused and you call this function to remove - * the pausing, you may get your write callback called at this point. - * - * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h - * - * NOTE: This is one of few API functions that are allowed to be called from - * within a callback. - */ -CURLcode curl_easy_pause(CURL *curl, int action) -{ - CURLcode result = CURLE_OK; - bool recursive = FALSE; - bool changed = FALSE; - struct Curl_easy *data = curl; - bool recv_paused, recv_paused_new; - bool send_paused, send_paused_new; - - if(!GOOD_EASY_HANDLE(data) || !data->conn) - /* crazy input, do not continue */ - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(Curl_is_in_callback(data)) - recursive = TRUE; - - recv_paused = Curl_xfer_recv_is_paused(data); - recv_paused_new = (action & CURLPAUSE_RECV); - send_paused = Curl_xfer_send_is_paused(data); - send_paused_new = (action & CURLPAUSE_SEND); - - if((send_paused != send_paused_new) || - (send_paused_new != Curl_creader_is_paused(data))) { - changed = TRUE; - result = Curl_1st_fatal( - result, Curl_xfer_pause_send(data, send_paused_new)); - } - - if(recv_paused != recv_paused_new) { - changed = TRUE; - result = Curl_1st_fatal( - result, Curl_xfer_pause_recv(data, recv_paused_new)); - } - - /* If not completely pausing both directions now, run again in any case. */ - if(!Curl_xfer_is_blocked(data)) { - /* reset the too-slow time keeper */ - data->state.keeps_speed.tv_sec = 0; - if(data->multi) { - Curl_multi_mark_dirty(data); /* make it run */ - /* On changes, tell application to update its timers. */ - if(changed) { - if(Curl_update_timer(data->multi) && !result) - result = CURLE_ABORTED_BY_CALLBACK; - } - } - } - - if(!result && changed && !data->state.done && data->multi) - /* pause/unpausing may result in multi event changes */ - if(Curl_multi_ev_assess_xfer(data->multi, data) && !result) - result = CURLE_ABORTED_BY_CALLBACK; - - if(recursive) - /* this might have called a callback recursively which might have set this - to false again on exit */ - Curl_set_in_callback(data, TRUE); - - return result; -} - -static CURLcode easy_connection(struct Curl_easy *data, - struct connectdata **connp) -{ - curl_socket_t sfd; - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */ - if(!data->set.connect_only) { - failf(data, "CONNECT_ONLY is required"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - sfd = Curl_getconnectinfo(data, connp); - - if(sfd == CURL_SOCKET_BAD) { - failf(data, "Failed to get recent socket"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - return CURLE_OK; -} - -/* - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - * Returns CURLE_OK on success, error code on error. - */ -CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n) -{ - CURLcode result; - struct connectdata *c; - struct Curl_easy *data = curl; - - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(Curl_is_in_callback(data)) - return CURLE_RECURSIVE_API_CALL; - - result = easy_connection(data, &c); - if(result) - return result; - - if(!data->conn) - /* on first invoke, the transfer has been detached from the connection and - needs to be reattached */ - Curl_attach_connection(data, c); - - *n = 0; - return Curl_conn_recv(data, FIRSTSOCKET, buffer, buflen, n); -} - -#ifndef CURL_DISABLE_WEBSOCKETS -CURLcode Curl_connect_only_attach(struct Curl_easy *data) -{ - CURLcode result; - struct connectdata *c = NULL; - - result = easy_connection(data, &c); - if(result) - return result; - - if(!data->conn) - /* on first invoke, the transfer has been detached from the connection and - needs to be reattached */ - Curl_attach_connection(data, c); - - return CURLE_OK; -} -#endif /* !CURL_DISABLE_WEBSOCKETS */ - -/* - * Sends data over the connected socket. - * - * This is the private internal version of curl_easy_send() - */ -CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer, - size_t buflen, size_t *n) -{ - CURLcode result; - struct connectdata *c = NULL; - struct Curl_sigpipe_ctx sigpipe_ctx; - - *n = 0; - result = easy_connection(data, &c); - if(result) - return result; - - if(!data->conn) - /* on first invoke, the transfer has been detached from the connection and - needs to be reattached */ - Curl_attach_connection(data, c); - - sigpipe_ignore(data, &sigpipe_ctx); - result = Curl_conn_send(data, FIRSTSOCKET, buffer, buflen, FALSE, n); - sigpipe_restore(&sigpipe_ctx); - - if(result && result != CURLE_AGAIN) - return CURLE_SEND_ERROR; - return result; -} - -/* - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen, - size_t *n) -{ - size_t written = 0; - CURLcode result; - struct Curl_easy *data = curl; - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(Curl_is_in_callback(data)) - return CURLE_RECURSIVE_API_CALL; - - result = Curl_senddata(data, buffer, buflen, &written); - *n = written; - return result; -} - -/* - * Performs connection upkeep for the given session handle. - */ -CURLcode curl_easy_upkeep(CURL *curl) -{ - struct Curl_easy *data = curl; - /* Verify that we got an easy handle we can work with. */ - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(Curl_is_in_callback(data)) - return CURLE_RECURSIVE_API_CALL; - - /* Use the common function to keep connections alive. */ - return Curl_cpool_upkeep(data); -} - -CURLcode curl_easy_ssls_import(CURL *curl, const char *session_key, - const unsigned char *shmac, size_t shmac_len, - const unsigned char *sdata, size_t sdata_len) -{ -#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) - struct Curl_easy *data = curl; - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(Curl_is_in_callback(data) || Curl_ssl_scache_is_locked(data)) - return CURLE_RECURSIVE_API_CALL; - return Curl_ssl_session_import(data, session_key, - shmac, shmac_len, sdata, sdata_len); -#else - (void)curl; - (void)session_key; - (void)shmac; - (void)shmac_len; - (void)sdata; - (void)sdata_len; - return CURLE_NOT_BUILT_IN; -#endif -} - -CURLcode curl_easy_ssls_export(CURL *curl, - curl_ssls_export_cb *export_fn, - void *userptr) -{ -#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) - struct Curl_easy *data = curl; - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(Curl_is_in_callback(data) || Curl_ssl_scache_is_locked(data)) - return CURLE_RECURSIVE_API_CALL; - return Curl_ssl_session_export(data, export_fn, userptr); -#else - (void)curl; - (void)export_fn; - (void)userptr; - return CURLE_NOT_BUILT_IN; -#endif -} - -CURLcode Curl_meta_set(struct Curl_easy *data, const char *key, - void *meta_data, Curl_meta_dtor *meta_dtor) -{ - DEBUGASSERT(meta_data); /* never set to NULL */ - if(!Curl_hash_add2(&data->meta_hash, CURL_UNCONST(key), strlen(key) + 1, - meta_data, meta_dtor)) { - meta_dtor(CURL_UNCONST(key), strlen(key) + 1, meta_data); - return CURLE_OUT_OF_MEMORY; - } - return CURLE_OK; -} - -void Curl_meta_remove(struct Curl_easy *data, const char *key) -{ - Curl_hash_delete(&data->meta_hash, CURL_UNCONST(key), strlen(key) + 1); -} - -void *Curl_meta_get(struct Curl_easy *data, const char *key) -{ - return Curl_hash_pick(&data->meta_hash, CURL_UNCONST(key), strlen(key) + 1); -} - -void Curl_meta_reset(struct Curl_easy *data) -{ - Curl_hash_clean(&data->meta_hash); -} diff --git a/vendor/curl/lib/easy_lock.h b/vendor/curl/lib/easy_lock.h deleted file mode 100644 index b8f916ff6..000000000 --- a/vendor/curl/lib/easy_lock.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef HEADER_CURL_EASY_LOCK_H -#define HEADER_CURL_EASY_LOCK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#define GLOBAL_INIT_IS_THREADSAFE - -#ifdef _WIN32 - -#define curl_simple_lock SRWLOCK -#define CURL_SIMPLE_LOCK_INIT SRWLOCK_INIT - -#define curl_simple_lock_lock(m) AcquireSRWLockExclusive(m) -#define curl_simple_lock_unlock(m) ReleaseSRWLockExclusive(m) - -#elif defined(HAVE_ATOMIC) && defined(HAVE_STDATOMIC_H) -#include -#ifdef HAVE_SCHED_YIELD -#include -#endif - -#define curl_simple_lock atomic_int -#define CURL_SIMPLE_LOCK_INIT 0 - -#ifndef __INTEL_COMPILER -/* The Intel compiler tries to look like GCC *and* clang *and* lies in its - __has_builtin() function, so override it. */ - -/* if GCC on i386/x86_64 or if the built-in is present */ -#if (defined(__GNUC__) && !defined(__clang__)) && \ - (defined(__i386__) || defined(__x86_64__)) -#define HAVE_BUILTIN_IA32_PAUSE -#elif defined(__has_builtin) /* Keep this PP check separate from others */ -#if __has_builtin(__builtin_ia32_pause) -#define HAVE_BUILTIN_IA32_PAUSE -#endif -#endif - -#endif /* !__INTEL_COMPILER */ - -static CURL_INLINE void curl_simple_lock_lock(curl_simple_lock *lock) -{ - for(;;) { - if(!atomic_exchange_explicit(lock, true, memory_order_acquire)) - break; - /* Reduce cache coherency traffic */ - while(atomic_load_explicit(lock, memory_order_relaxed)) { - /* Reduce load (not mandatory) */ -#ifdef HAVE_BUILTIN_IA32_PAUSE - __builtin_ia32_pause(); -#elif defined(__aarch64__) - __asm__ volatile("yield" ::: "memory"); -#elif defined(HAVE_SCHED_YIELD) - sched_yield(); -#endif - } - } -} - -static CURL_INLINE void curl_simple_lock_unlock(curl_simple_lock *lock) -{ - atomic_store_explicit(lock, false, memory_order_release); -} - -#elif defined(HAVE_THREADS_POSIX) - -#define curl_simple_lock pthread_mutex_t -#define CURL_SIMPLE_LOCK_INIT PTHREAD_MUTEX_INITIALIZER -#define curl_simple_lock_lock(m) pthread_mutex_lock(m) -#define curl_simple_lock_unlock(m) pthread_mutex_unlock(m) - -#else - -#undef GLOBAL_INIT_IS_THREADSAFE - -#endif - -#endif /* HEADER_CURL_EASY_LOCK_H */ diff --git a/vendor/curl/lib/easygetopt.c b/vendor/curl/lib/easygetopt.c deleted file mode 100644 index 533d7e367..000000000 --- a/vendor/curl/lib/easygetopt.c +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "easyoptions.h" - -#ifndef CURL_DISABLE_GETOPTIONS - -/* Lookups easy options at runtime */ -static const struct curl_easyoption *lookup(const char *name, CURLoption id) -{ - DEBUGASSERT(name || id); - DEBUGASSERT(!Curl_easyopts_check()); - if(name || id) { - const struct curl_easyoption *o = &Curl_easyopts[0]; - do { - if(name) { - if(curl_strequal(o->name, name)) - return o; - } - else { - if((o->id == id) && !(o->flags & CURLOT_FLAG_ALIAS)) - /* do not match alias options */ - return o; - } - o++; - } while(o->name); - } - return NULL; -} - -const struct curl_easyoption *curl_easy_option_by_name(const char *name) -{ - /* when name is used, the id argument is ignored */ - return lookup(name, CURLOPT_LASTENTRY); -} - -const struct curl_easyoption *curl_easy_option_by_id(CURLoption id) -{ - return lookup(NULL, id); -} - -/* Iterates over available options */ -const struct curl_easyoption *curl_easy_option_next( - const struct curl_easyoption *prev) -{ - if(prev && prev->name) { - prev++; - if(prev->name) - return prev; - } - else if(!prev) - return &Curl_easyopts[0]; - return NULL; -} - -#else -const struct curl_easyoption *curl_easy_option_by_name(const char *name) -{ - (void)name; - return NULL; -} - -const struct curl_easyoption *curl_easy_option_by_id(CURLoption id) -{ - (void)id; - return NULL; -} - -const struct curl_easyoption *curl_easy_option_next( - const struct curl_easyoption *prev) -{ - (void)prev; - return NULL; -} -#endif diff --git a/vendor/curl/lib/easyif.h b/vendor/curl/lib/easyif.h deleted file mode 100644 index 213fd027d..000000000 --- a/vendor/curl/lib/easyif.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_EASYIF_H -#define HEADER_CURL_EASYIF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Prototypes for library-wide functions provided by easy.c - */ -CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer, - size_t buflen, size_t *n); - -#ifndef CURL_DISABLE_WEBSOCKETS -CURLcode Curl_connect_only_attach(struct Curl_easy *data); -#endif - -#ifdef DEBUGBUILD -CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy); -#endif - -#endif /* HEADER_CURL_EASYIF_H */ diff --git a/vendor/curl/lib/easyoptions.c b/vendor/curl/lib/easyoptions.c deleted file mode 100644 index 4c0b4f0ce..000000000 --- a/vendor/curl/lib/easyoptions.c +++ /dev/null @@ -1,390 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */ - -#include "curl_setup.h" - -#include "easyoptions.h" - -/* all easy setopt options listed in alphabetical order */ -const struct curl_easyoption Curl_easyopts[] = { - { "ABSTRACT_UNIX_SOCKET", CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOT_STRING, 0 }, - { "ACCEPTTIMEOUT_MS", CURLOPT_ACCEPTTIMEOUT_MS, CURLOT_LONG, 0 }, - { "ACCEPT_ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, 0 }, - { "ADDRESS_SCOPE", CURLOPT_ADDRESS_SCOPE, CURLOT_LONG, 0 }, - { "ALTSVC", CURLOPT_ALTSVC, CURLOT_STRING, 0 }, - { "ALTSVC_CTRL", CURLOPT_ALTSVC_CTRL, CURLOT_LONG, 0 }, - { "APPEND", CURLOPT_APPEND, CURLOT_LONG, 0 }, - { "AUTOREFERER", CURLOPT_AUTOREFERER, CURLOT_LONG, 0 }, - { "AWS_SIGV4", CURLOPT_AWS_SIGV4, CURLOT_STRING, 0 }, - { "BUFFERSIZE", CURLOPT_BUFFERSIZE, CURLOT_LONG, 0 }, - { "CAINFO", CURLOPT_CAINFO, CURLOT_STRING, 0 }, - { "CAINFO_BLOB", CURLOPT_CAINFO_BLOB, CURLOT_BLOB, 0 }, - { "CAPATH", CURLOPT_CAPATH, CURLOT_STRING, 0 }, - { "CA_CACHE_TIMEOUT", CURLOPT_CA_CACHE_TIMEOUT, CURLOT_LONG, 0 }, - { "CERTINFO", CURLOPT_CERTINFO, CURLOT_LONG, 0 }, - { "CHUNK_BGN_FUNCTION", CURLOPT_CHUNK_BGN_FUNCTION, CURLOT_FUNCTION, 0 }, - { "CHUNK_DATA", CURLOPT_CHUNK_DATA, CURLOT_CBPTR, 0 }, - { "CHUNK_END_FUNCTION", CURLOPT_CHUNK_END_FUNCTION, CURLOT_FUNCTION, 0 }, - { "CLOSESOCKETDATA", CURLOPT_CLOSESOCKETDATA, CURLOT_CBPTR, 0 }, - { "CLOSESOCKETFUNCTION", CURLOPT_CLOSESOCKETFUNCTION, CURLOT_FUNCTION, 0 }, - { "CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT, CURLOT_LONG, 0 }, - { "CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS, CURLOT_LONG, 0 }, - { "CONNECT_ONLY", CURLOPT_CONNECT_ONLY, CURLOT_LONG, 0 }, - { "CONNECT_TO", CURLOPT_CONNECT_TO, CURLOT_SLIST, 0 }, - { "CONV_FROM_NETWORK_FUNCTION", CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOT_FUNCTION, 0 }, - { "CONV_FROM_UTF8_FUNCTION", CURLOPT_CONV_FROM_UTF8_FUNCTION, - CURLOT_FUNCTION, 0 }, - { "CONV_TO_NETWORK_FUNCTION", CURLOPT_CONV_TO_NETWORK_FUNCTION, - CURLOT_FUNCTION, 0 }, - { "COOKIE", CURLOPT_COOKIE, CURLOT_STRING, 0 }, - { "COOKIEFILE", CURLOPT_COOKIEFILE, CURLOT_STRING, 0 }, - { "COOKIEJAR", CURLOPT_COOKIEJAR, CURLOT_STRING, 0 }, - { "COOKIELIST", CURLOPT_COOKIELIST, CURLOT_STRING, 0 }, - { "COOKIESESSION", CURLOPT_COOKIESESSION, CURLOT_LONG, 0 }, - { "COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS, CURLOT_OBJECT, 0 }, - { "CRLF", CURLOPT_CRLF, CURLOT_LONG, 0 }, - { "CRLFILE", CURLOPT_CRLFILE, CURLOT_STRING, 0 }, - { "CURLU", CURLOPT_CURLU, CURLOT_OBJECT, 0 }, - { "CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST, CURLOT_STRING, 0 }, - { "DEBUGDATA", CURLOPT_DEBUGDATA, CURLOT_CBPTR, 0 }, - { "DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION, CURLOT_FUNCTION, 0 }, - { "DEFAULT_PROTOCOL", CURLOPT_DEFAULT_PROTOCOL, CURLOT_STRING, 0 }, - { "DIRLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, 0 }, - { "DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL, - CURLOT_LONG, 0 }, - { "DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT, CURLOT_LONG, 0 }, - { "DNS_INTERFACE", CURLOPT_DNS_INTERFACE, CURLOT_STRING, 0 }, - { "DNS_LOCAL_IP4", CURLOPT_DNS_LOCAL_IP4, CURLOT_STRING, 0 }, - { "DNS_LOCAL_IP6", CURLOPT_DNS_LOCAL_IP6, CURLOT_STRING, 0 }, - { "DNS_SERVERS", CURLOPT_DNS_SERVERS, CURLOT_STRING, 0 }, - { "DNS_SHUFFLE_ADDRESSES", CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOT_LONG, 0 }, - { "DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOT_LONG, 0 }, - { "DOH_SSL_VERIFYHOST", CURLOPT_DOH_SSL_VERIFYHOST, CURLOT_LONG, 0 }, - { "DOH_SSL_VERIFYPEER", CURLOPT_DOH_SSL_VERIFYPEER, CURLOT_LONG, 0 }, - { "DOH_SSL_VERIFYSTATUS", CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOT_LONG, 0 }, - { "DOH_URL", CURLOPT_DOH_URL, CURLOT_STRING, 0 }, - { "ECH", CURLOPT_ECH, CURLOT_STRING, 0 }, - { "EGDSOCKET", CURLOPT_EGDSOCKET, CURLOT_STRING, 0 }, - { "ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, CURLOT_FLAG_ALIAS }, - { "ERRORBUFFER", CURLOPT_ERRORBUFFER, CURLOT_OBJECT, 0 }, - { "EXPECT_100_TIMEOUT_MS", CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOT_LONG, 0 }, - { "FAILONERROR", CURLOPT_FAILONERROR, CURLOT_LONG, 0 }, - { "FILE", CURLOPT_WRITEDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS }, - { "FILETIME", CURLOPT_FILETIME, CURLOT_LONG, 0 }, - { "FNMATCH_DATA", CURLOPT_FNMATCH_DATA, CURLOT_CBPTR, 0 }, - { "FNMATCH_FUNCTION", CURLOPT_FNMATCH_FUNCTION, CURLOT_FUNCTION, 0 }, - { "FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION, CURLOT_LONG, 0 }, - { "FORBID_REUSE", CURLOPT_FORBID_REUSE, CURLOT_LONG, 0 }, - { "FRESH_CONNECT", CURLOPT_FRESH_CONNECT, CURLOT_LONG, 0 }, - { "FTPAPPEND", CURLOPT_APPEND, CURLOT_LONG, CURLOT_FLAG_ALIAS }, - { "FTPLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, CURLOT_FLAG_ALIAS }, - { "FTPPORT", CURLOPT_FTPPORT, CURLOT_STRING, 0 }, - { "FTPSSLAUTH", CURLOPT_FTPSSLAUTH, CURLOT_VALUES, 0 }, - { "FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT, CURLOT_STRING, 0 }, - { "FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER, - CURLOT_STRING, 0 }, - { "FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS, - CURLOT_LONG, 0 }, - { "FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD, CURLOT_VALUES, 0 }, - { "FTP_RESPONSE_TIMEOUT", CURLOPT_SERVER_RESPONSE_TIMEOUT, - CURLOT_LONG, CURLOT_FLAG_ALIAS }, - { "FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP, CURLOT_LONG, 0 }, - { "FTP_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, CURLOT_FLAG_ALIAS }, - { "FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC, CURLOT_LONG, 0 }, - { "FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT, CURLOT_LONG, 0 }, - { "FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV, CURLOT_LONG, 0 }, - { "FTP_USE_PRET", CURLOPT_FTP_USE_PRET, CURLOT_LONG, 0 }, - { "GSSAPI_DELEGATION", CURLOPT_GSSAPI_DELEGATION, CURLOT_VALUES, 0 }, - { "HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, - CURLOT_LONG, 0 }, - { "HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CURLOT_LONG, 0 }, - { "HAPROXY_CLIENT_IP", CURLOPT_HAPROXY_CLIENT_IP, CURLOT_STRING, 0 }, - { "HEADER", CURLOPT_HEADER, CURLOT_LONG, 0 }, - { "HEADERDATA", CURLOPT_HEADERDATA, CURLOT_CBPTR, 0 }, - { "HEADERFUNCTION", CURLOPT_HEADERFUNCTION, CURLOT_FUNCTION, 0 }, - { "HEADEROPT", CURLOPT_HEADEROPT, CURLOT_VALUES, 0 }, - { "HSTS", CURLOPT_HSTS, CURLOT_STRING, 0 }, - { "HSTSREADDATA", CURLOPT_HSTSREADDATA, CURLOT_CBPTR, 0 }, - { "HSTSREADFUNCTION", CURLOPT_HSTSREADFUNCTION, CURLOT_FUNCTION, 0 }, - { "HSTSWRITEDATA", CURLOPT_HSTSWRITEDATA, CURLOT_CBPTR, 0 }, - { "HSTSWRITEFUNCTION", CURLOPT_HSTSWRITEFUNCTION, CURLOT_FUNCTION, 0 }, - { "HSTS_CTRL", CURLOPT_HSTS_CTRL, CURLOT_LONG, 0 }, - { "HTTP09_ALLOWED", CURLOPT_HTTP09_ALLOWED, CURLOT_LONG, 0 }, - { "HTTP200ALIASES", CURLOPT_HTTP200ALIASES, CURLOT_SLIST, 0 }, - { "HTTPAUTH", CURLOPT_HTTPAUTH, CURLOT_VALUES, 0 }, - { "HTTPGET", CURLOPT_HTTPGET, CURLOT_LONG, 0 }, - { "HTTPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, 0 }, - { "HTTPPOST", CURLOPT_HTTPPOST, CURLOT_OBJECT, 0 }, - { "HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL, CURLOT_LONG, 0 }, - { "HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING, CURLOT_LONG, 0 }, - { "HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING, - CURLOT_LONG, 0 }, - { "HTTP_VERSION", CURLOPT_HTTP_VERSION, CURLOT_VALUES, 0 }, - { "IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH, CURLOT_LONG, 0 }, - { "INFILE", CURLOPT_READDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS }, - { "INFILESIZE", CURLOPT_INFILESIZE, CURLOT_LONG, 0 }, - { "INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE, CURLOT_OFF_T, 0 }, - { "INTERFACE", CURLOPT_INTERFACE, CURLOT_STRING, 0 }, - { "INTERLEAVEDATA", CURLOPT_INTERLEAVEDATA, CURLOT_CBPTR, 0 }, - { "INTERLEAVEFUNCTION", CURLOPT_INTERLEAVEFUNCTION, CURLOT_FUNCTION, 0 }, - { "IOCTLDATA", CURLOPT_IOCTLDATA, CURLOT_CBPTR, 0 }, - { "IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION, CURLOT_FUNCTION, 0 }, - { "IPRESOLVE", CURLOPT_IPRESOLVE, CURLOT_VALUES, 0 }, - { "ISSUERCERT", CURLOPT_ISSUERCERT, CURLOT_STRING, 0 }, - { "ISSUERCERT_BLOB", CURLOPT_ISSUERCERT_BLOB, CURLOT_BLOB, 0 }, - { "KEEP_SENDING_ON_ERROR", CURLOPT_KEEP_SENDING_ON_ERROR, CURLOT_LONG, 0 }, - { "KEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, 0 }, - { "KRB4LEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, CURLOT_FLAG_ALIAS }, - { "KRBLEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, 0 }, - { "LOCALPORT", CURLOPT_LOCALPORT, CURLOT_LONG, 0 }, - { "LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE, CURLOT_LONG, 0 }, - { "LOGIN_OPTIONS", CURLOPT_LOGIN_OPTIONS, CURLOT_STRING, 0 }, - { "LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT, CURLOT_LONG, 0 }, - { "LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME, CURLOT_LONG, 0 }, - { "MAIL_AUTH", CURLOPT_MAIL_AUTH, CURLOT_STRING, 0 }, - { "MAIL_FROM", CURLOPT_MAIL_FROM, CURLOT_STRING, 0 }, - { "MAIL_RCPT", CURLOPT_MAIL_RCPT, CURLOT_SLIST, 0 }, - { "MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLOWFAILS, - CURLOT_LONG, CURLOT_FLAG_ALIAS }, - { "MAIL_RCPT_ALLOWFAILS", CURLOPT_MAIL_RCPT_ALLOWFAILS, CURLOT_LONG, 0 }, - { "MAXAGE_CONN", CURLOPT_MAXAGE_CONN, CURLOT_LONG, 0 }, - { "MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0 }, - { "MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0 }, - { "MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE, CURLOT_OFF_T, 0 }, - { "MAXLIFETIME_CONN", CURLOPT_MAXLIFETIME_CONN, CURLOT_LONG, 0 }, - { "MAXREDIRS", CURLOPT_MAXREDIRS, CURLOT_LONG, 0 }, - { "MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0 }, - { "MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0 }, - { "MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0 }, - { "MIME_OPTIONS", CURLOPT_MIME_OPTIONS, CURLOT_LONG, 0 }, - { "NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0 }, - { "NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0 }, - { "NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0 }, - { "NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS, CURLOT_LONG, 0 }, - { "NOBODY", CURLOPT_NOBODY, CURLOT_LONG, 0 }, - { "NOPROGRESS", CURLOPT_NOPROGRESS, CURLOT_LONG, 0 }, - { "NOPROXY", CURLOPT_NOPROXY, CURLOT_STRING, 0 }, - { "NOSIGNAL", CURLOPT_NOSIGNAL, CURLOT_LONG, 0 }, - { "OPENSOCKETDATA", CURLOPT_OPENSOCKETDATA, CURLOT_CBPTR, 0 }, - { "OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION, CURLOT_FUNCTION, 0 }, - { "PASSWORD", CURLOPT_PASSWORD, CURLOT_STRING, 0 }, - { "PATH_AS_IS", CURLOPT_PATH_AS_IS, CURLOT_LONG, 0 }, - { "PINNEDPUBLICKEY", CURLOPT_PINNEDPUBLICKEY, CURLOT_STRING, 0 }, - { "PIPEWAIT", CURLOPT_PIPEWAIT, CURLOT_LONG, 0 }, - { "PORT", CURLOPT_PORT, CURLOT_LONG, 0 }, - { "POST", CURLOPT_POST, CURLOT_LONG, 0 }, - { "POST301", CURLOPT_POSTREDIR, CURLOT_VALUES, CURLOT_FLAG_ALIAS }, - { "POSTFIELDS", CURLOPT_POSTFIELDS, CURLOT_OBJECT, 0 }, - { "POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE, CURLOT_LONG, 0 }, - { "POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE, CURLOT_OFF_T, 0 }, - { "POSTQUOTE", CURLOPT_POSTQUOTE, CURLOT_SLIST, 0 }, - { "POSTREDIR", CURLOPT_POSTREDIR, CURLOT_VALUES, 0 }, - { "PREQUOTE", CURLOPT_PREQUOTE, CURLOT_SLIST, 0 }, - { "PREREQDATA", CURLOPT_PREREQDATA, CURLOT_CBPTR, 0 }, - { "PREREQFUNCTION", CURLOPT_PREREQFUNCTION, CURLOT_FUNCTION, 0 }, - { "PRE_PROXY", CURLOPT_PRE_PROXY, CURLOT_STRING, 0 }, - { "PRIVATE", CURLOPT_PRIVATE, CURLOT_OBJECT, 0 }, - { "PROGRESSDATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS }, - { "PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION, CURLOT_FUNCTION, 0 }, - { "PROTOCOLS", CURLOPT_PROTOCOLS, CURLOT_LONG, 0 }, - { "PROTOCOLS_STR", CURLOPT_PROTOCOLS_STR, CURLOT_STRING, 0 }, - { "PROXY", CURLOPT_PROXY, CURLOT_STRING, 0 }, - { "PROXYAUTH", CURLOPT_PROXYAUTH, CURLOT_VALUES, 0 }, - { "PROXYHEADER", CURLOPT_PROXYHEADER, CURLOT_SLIST, 0 }, - { "PROXYPASSWORD", CURLOPT_PROXYPASSWORD, CURLOT_STRING, 0 }, - { "PROXYPORT", CURLOPT_PROXYPORT, CURLOT_LONG, 0 }, - { "PROXYTYPE", CURLOPT_PROXYTYPE, CURLOT_VALUES, 0 }, - { "PROXYUSERNAME", CURLOPT_PROXYUSERNAME, CURLOT_STRING, 0 }, - { "PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CURLOT_STRING, 0 }, - { "PROXY_CAINFO", CURLOPT_PROXY_CAINFO, CURLOT_STRING, 0 }, - { "PROXY_CAINFO_BLOB", CURLOPT_PROXY_CAINFO_BLOB, CURLOT_BLOB, 0 }, - { "PROXY_CAPATH", CURLOPT_PROXY_CAPATH, CURLOT_STRING, 0 }, - { "PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE, CURLOT_STRING, 0 }, - { "PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT, CURLOT_STRING, 0 }, - { "PROXY_ISSUERCERT_BLOB", CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOT_BLOB, 0 }, - { "PROXY_KEYPASSWD", CURLOPT_PROXY_KEYPASSWD, CURLOT_STRING, 0 }, - { "PROXY_PINNEDPUBLICKEY", CURLOPT_PROXY_PINNEDPUBLICKEY, - CURLOT_STRING, 0 }, - { "PROXY_SERVICE_NAME", CURLOPT_PROXY_SERVICE_NAME, CURLOT_STRING, 0 }, - { "PROXY_SSLCERT", CURLOPT_PROXY_SSLCERT, CURLOT_STRING, 0 }, - { "PROXY_SSLCERTTYPE", CURLOPT_PROXY_SSLCERTTYPE, CURLOT_STRING, 0 }, - { "PROXY_SSLCERT_BLOB", CURLOPT_PROXY_SSLCERT_BLOB, CURLOT_BLOB, 0 }, - { "PROXY_SSLKEY", CURLOPT_PROXY_SSLKEY, CURLOT_STRING, 0 }, - { "PROXY_SSLKEYTYPE", CURLOPT_PROXY_SSLKEYTYPE, CURLOT_STRING, 0 }, - { "PROXY_SSLKEY_BLOB", CURLOPT_PROXY_SSLKEY_BLOB, CURLOT_BLOB, 0 }, - { "PROXY_SSLVERSION", CURLOPT_PROXY_SSLVERSION, CURLOT_VALUES, 0 }, - { "PROXY_SSL_CIPHER_LIST", CURLOPT_PROXY_SSL_CIPHER_LIST, - CURLOT_STRING, 0 }, - { "PROXY_SSL_OPTIONS", CURLOPT_PROXY_SSL_OPTIONS, CURLOT_LONG, 0 }, - { "PROXY_SSL_VERIFYHOST", CURLOPT_PROXY_SSL_VERIFYHOST, CURLOT_LONG, 0 }, - { "PROXY_SSL_VERIFYPEER", CURLOPT_PROXY_SSL_VERIFYPEER, CURLOT_LONG, 0 }, - { "PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CURLOT_STRING, 0 }, - { "PROXY_TLSAUTH_PASSWORD", CURLOPT_PROXY_TLSAUTH_PASSWORD, - CURLOT_STRING, 0 }, - { "PROXY_TLSAUTH_TYPE", CURLOPT_PROXY_TLSAUTH_TYPE, CURLOT_STRING, 0 }, - { "PROXY_TLSAUTH_USERNAME", CURLOPT_PROXY_TLSAUTH_USERNAME, - CURLOT_STRING, 0 }, - { "PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE, CURLOT_LONG, 0 }, - { "PUT", CURLOPT_PUT, CURLOT_LONG, 0 }, - { "QUICK_EXIT", CURLOPT_QUICK_EXIT, CURLOT_LONG, 0 }, - { "QUOTE", CURLOPT_QUOTE, CURLOT_SLIST, 0 }, - { "RANDOM_FILE", CURLOPT_RANDOM_FILE, CURLOT_STRING, 0 }, - { "RANGE", CURLOPT_RANGE, CURLOT_STRING, 0 }, - { "READDATA", CURLOPT_READDATA, CURLOT_CBPTR, 0 }, - { "READFUNCTION", CURLOPT_READFUNCTION, CURLOT_FUNCTION, 0 }, - { "REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS, CURLOT_LONG, 0 }, - { "REDIR_PROTOCOLS_STR", CURLOPT_REDIR_PROTOCOLS_STR, CURLOT_STRING, 0 }, - { "REFERER", CURLOPT_REFERER, CURLOT_STRING, 0 }, - { "REQUEST_TARGET", CURLOPT_REQUEST_TARGET, CURLOT_STRING, 0 }, - { "RESOLVE", CURLOPT_RESOLVE, CURLOT_SLIST, 0 }, - { "RESOLVER_START_DATA", CURLOPT_RESOLVER_START_DATA, CURLOT_CBPTR, 0 }, - { "RESOLVER_START_FUNCTION", CURLOPT_RESOLVER_START_FUNCTION, - CURLOT_FUNCTION, 0 }, - { "RESUME_FROM", CURLOPT_RESUME_FROM, CURLOT_LONG, 0 }, - { "RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE, CURLOT_OFF_T, 0 }, - { "RTSPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, CURLOT_FLAG_ALIAS }, - { "RTSP_CLIENT_CSEQ", CURLOPT_RTSP_CLIENT_CSEQ, CURLOT_LONG, 0 }, - { "RTSP_REQUEST", CURLOPT_RTSP_REQUEST, CURLOT_VALUES, 0 }, - { "RTSP_SERVER_CSEQ", CURLOPT_RTSP_SERVER_CSEQ, CURLOT_LONG, 0 }, - { "RTSP_SESSION_ID", CURLOPT_RTSP_SESSION_ID, CURLOT_STRING, 0 }, - { "RTSP_STREAM_URI", CURLOPT_RTSP_STREAM_URI, CURLOT_STRING, 0 }, - { "RTSP_TRANSPORT", CURLOPT_RTSP_TRANSPORT, CURLOT_STRING, 0 }, - { "SASL_AUTHZID", CURLOPT_SASL_AUTHZID, CURLOT_STRING, 0 }, - { "SASL_IR", CURLOPT_SASL_IR, CURLOT_LONG, 0 }, - { "SEEKDATA", CURLOPT_SEEKDATA, CURLOT_CBPTR, 0 }, - { "SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CURLOT_FUNCTION, 0 }, - { "SERVER_RESPONSE_TIMEOUT", CURLOPT_SERVER_RESPONSE_TIMEOUT, - CURLOT_LONG, 0 }, - { "SERVER_RESPONSE_TIMEOUT_MS", CURLOPT_SERVER_RESPONSE_TIMEOUT_MS, - CURLOT_LONG, 0 }, - { "SERVICE_NAME", CURLOPT_SERVICE_NAME, CURLOT_STRING, 0 }, - { "SHARE", CURLOPT_SHARE, CURLOT_OBJECT, 0 }, - { "SOCKOPTDATA", CURLOPT_SOCKOPTDATA, CURLOT_CBPTR, 0 }, - { "SOCKOPTFUNCTION", CURLOPT_SOCKOPTFUNCTION, CURLOT_FUNCTION, 0 }, - { "SOCKS5_AUTH", CURLOPT_SOCKS5_AUTH, CURLOT_LONG, 0 }, - { "SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC, CURLOT_LONG, 0 }, - { "SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE, - CURLOT_STRING, 0 }, - { "SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES, CURLOT_VALUES, 0 }, - { "SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION, CURLOT_LONG, 0 }, - { "SSH_HOSTKEYDATA", CURLOPT_SSH_HOSTKEYDATA, CURLOT_CBPTR, 0 }, - { "SSH_HOSTKEYFUNCTION", CURLOPT_SSH_HOSTKEYFUNCTION, CURLOT_FUNCTION, 0 }, - { "SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, - CURLOT_STRING, 0 }, - { "SSH_HOST_PUBLIC_KEY_SHA256", CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, - CURLOT_STRING, 0 }, - { "SSH_KEYDATA", CURLOPT_SSH_KEYDATA, CURLOT_CBPTR, 0 }, - { "SSH_KEYFUNCTION", CURLOPT_SSH_KEYFUNCTION, CURLOT_FUNCTION, 0 }, - { "SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS, CURLOT_STRING, 0 }, - { "SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE, CURLOT_STRING, 0 }, - { "SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE, CURLOT_STRING, 0 }, - { "SSLCERT", CURLOPT_SSLCERT, CURLOT_STRING, 0 }, - { "SSLCERTPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS }, - { "SSLCERTTYPE", CURLOPT_SSLCERTTYPE, CURLOT_STRING, 0 }, - { "SSLCERT_BLOB", CURLOPT_SSLCERT_BLOB, CURLOT_BLOB, 0 }, - { "SSLENGINE", CURLOPT_SSLENGINE, CURLOT_STRING, 0 }, - { "SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT, CURLOT_LONG, 0 }, - { "SSLKEY", CURLOPT_SSLKEY, CURLOT_STRING, 0 }, - { "SSLKEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS }, - { "SSLKEYTYPE", CURLOPT_SSLKEYTYPE, CURLOT_STRING, 0 }, - { "SSLKEY_BLOB", CURLOPT_SSLKEY_BLOB, CURLOT_BLOB, 0 }, - { "SSLVERSION", CURLOPT_SSLVERSION, CURLOT_VALUES, 0 }, - { "SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST, CURLOT_STRING, 0 }, - { "SSL_CTX_DATA", CURLOPT_SSL_CTX_DATA, CURLOT_CBPTR, 0 }, - { "SSL_CTX_FUNCTION", CURLOPT_SSL_CTX_FUNCTION, CURLOT_FUNCTION, 0 }, - { "SSL_EC_CURVES", CURLOPT_SSL_EC_CURVES, CURLOT_STRING, 0 }, - { "SSL_ENABLE_ALPN", CURLOPT_SSL_ENABLE_ALPN, CURLOT_LONG, 0 }, - { "SSL_ENABLE_NPN", CURLOPT_SSL_ENABLE_NPN, CURLOT_LONG, 0 }, - { "SSL_FALSESTART", CURLOPT_SSL_FALSESTART, CURLOT_LONG, 0 }, - { "SSL_OPTIONS", CURLOPT_SSL_OPTIONS, CURLOT_VALUES, 0 }, - { "SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE, CURLOT_LONG, 0 }, - { "SSL_SIGNATURE_ALGORITHMS", CURLOPT_SSL_SIGNATURE_ALGORITHMS, - CURLOT_STRING, 0 }, - { "SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST, CURLOT_LONG, 0 }, - { "SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER, CURLOT_LONG, 0 }, - { "SSL_VERIFYSTATUS", CURLOPT_SSL_VERIFYSTATUS, CURLOT_LONG, 0 }, - { "STDERR", CURLOPT_STDERR, CURLOT_OBJECT, 0 }, - { "STREAM_DEPENDS", CURLOPT_STREAM_DEPENDS, CURLOT_OBJECT, 0 }, - { "STREAM_DEPENDS_E", CURLOPT_STREAM_DEPENDS_E, CURLOT_OBJECT, 0 }, - { "STREAM_WEIGHT", CURLOPT_STREAM_WEIGHT, CURLOT_LONG, 0 }, - { "SUPPRESS_CONNECT_HEADERS", CURLOPT_SUPPRESS_CONNECT_HEADERS, - CURLOT_LONG, 0 }, - { "TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN, CURLOT_LONG, 0 }, - { "TCP_KEEPALIVE", CURLOPT_TCP_KEEPALIVE, CURLOT_LONG, 0 }, - { "TCP_KEEPCNT", CURLOPT_TCP_KEEPCNT, CURLOT_LONG, 0 }, - { "TCP_KEEPIDLE", CURLOPT_TCP_KEEPIDLE, CURLOT_LONG, 0 }, - { "TCP_KEEPINTVL", CURLOPT_TCP_KEEPINTVL, CURLOT_LONG, 0 }, - { "TCP_NODELAY", CURLOPT_TCP_NODELAY, CURLOT_LONG, 0 }, - { "TELNETOPTIONS", CURLOPT_TELNETOPTIONS, CURLOT_SLIST, 0 }, - { "TFTP_BLKSIZE", CURLOPT_TFTP_BLKSIZE, CURLOT_LONG, 0 }, - { "TFTP_NO_OPTIONS", CURLOPT_TFTP_NO_OPTIONS, CURLOT_LONG, 0 }, - { "TIMECONDITION", CURLOPT_TIMECONDITION, CURLOT_VALUES, 0 }, - { "TIMEOUT", CURLOPT_TIMEOUT, CURLOT_LONG, 0 }, - { "TIMEOUT_MS", CURLOPT_TIMEOUT_MS, CURLOT_LONG, 0 }, - { "TIMEVALUE", CURLOPT_TIMEVALUE, CURLOT_LONG, 0 }, - { "TIMEVALUE_LARGE", CURLOPT_TIMEVALUE_LARGE, CURLOT_OFF_T, 0 }, - { "TLS13_CIPHERS", CURLOPT_TLS13_CIPHERS, CURLOT_STRING, 0 }, - { "TLSAUTH_PASSWORD", CURLOPT_TLSAUTH_PASSWORD, CURLOT_STRING, 0 }, - { "TLSAUTH_TYPE", CURLOPT_TLSAUTH_TYPE, CURLOT_STRING, 0 }, - { "TLSAUTH_USERNAME", CURLOPT_TLSAUTH_USERNAME, CURLOT_STRING, 0 }, - { "TRAILERDATA", CURLOPT_TRAILERDATA, CURLOT_CBPTR, 0 }, - { "TRAILERFUNCTION", CURLOPT_TRAILERFUNCTION, CURLOT_FUNCTION, 0 }, - { "TRANSFERTEXT", CURLOPT_TRANSFERTEXT, CURLOT_LONG, 0 }, - { "TRANSFER_ENCODING", CURLOPT_TRANSFER_ENCODING, CURLOT_LONG, 0 }, - { "UNIX_SOCKET_PATH", CURLOPT_UNIX_SOCKET_PATH, CURLOT_STRING, 0 }, - { "UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH, CURLOT_LONG, 0 }, - { "UPKEEP_INTERVAL_MS", CURLOPT_UPKEEP_INTERVAL_MS, CURLOT_LONG, 0 }, - { "UPLOAD", CURLOPT_UPLOAD, CURLOT_LONG, 0 }, - { "UPLOAD_BUFFERSIZE", CURLOPT_UPLOAD_BUFFERSIZE, CURLOT_LONG, 0 }, - { "UPLOAD_FLAGS", CURLOPT_UPLOAD_FLAGS, CURLOT_LONG, 0 }, - { "URL", CURLOPT_URL, CURLOT_STRING, 0 }, - { "USERAGENT", CURLOPT_USERAGENT, CURLOT_STRING, 0 }, - { "USERNAME", CURLOPT_USERNAME, CURLOT_STRING, 0 }, - { "USERPWD", CURLOPT_USERPWD, CURLOT_STRING, 0 }, - { "USE_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, 0 }, - { "VERBOSE", CURLOPT_VERBOSE, CURLOT_LONG, 0 }, - { "WILDCARDMATCH", CURLOPT_WILDCARDMATCH, CURLOT_LONG, 0 }, - { "WRITEDATA", CURLOPT_WRITEDATA, CURLOT_CBPTR, 0 }, - { "WRITEFUNCTION", CURLOPT_WRITEFUNCTION, CURLOT_FUNCTION, 0 }, - { "WRITEHEADER", CURLOPT_HEADERDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS }, - { "WS_OPTIONS", CURLOPT_WS_OPTIONS, CURLOT_LONG, 0 }, - { "XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0 }, - { "XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0 }, - { "XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0 }, - { NULL, CURLOPT_LASTENTRY, CURLOT_LONG, 0 } /* end of table */ -}; - -#ifdef DEBUGBUILD -/* - * Curl_easyopts_check() is a debug-only function that returns non-zero - * if this source file is not in sync with the options listed in curl/curl.h - */ -int Curl_easyopts_check(void) -{ - return (CURLOPT_LASTENTRY % 10000) != (328 + 1); -} -#endif diff --git a/vendor/curl/lib/easyoptions.h b/vendor/curl/lib/easyoptions.h deleted file mode 100644 index d895653ce..000000000 --- a/vendor/curl/lib/easyoptions.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HEADER_CURL_EASYOPTIONS_H -#define HEADER_CURL_EASYOPTIONS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* should probably go into the public header */ - -/* generated table with all easy options */ -extern const struct curl_easyoption Curl_easyopts[]; - -#ifdef DEBUGBUILD -int Curl_easyopts_check(void); -#endif - -#endif /* HEADER_CURL_EASYOPTIONS_H */ diff --git a/vendor/curl/lib/escape.c b/vendor/curl/lib/escape.c deleted file mode 100644 index 4aff583de..000000000 --- a/vendor/curl/lib/escape.c +++ /dev/null @@ -1,228 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* Escape and unescape URL encoding in strings. The functions return a new - * allocated string or NULL if an error occurred. */ -#include "curl_setup.h" - -struct Curl_easy; - -#include "urldata.h" -#include "escape.h" -#include "curlx/strparse.h" -#include "curl_printf.h" - -/* for ABI-compatibility with previous versions */ -char *curl_escape(const char *string, int length) -{ - return curl_easy_escape(NULL, string, length); -} - -/* for ABI-compatibility with previous versions */ -char *curl_unescape(const char *string, int length) -{ - return curl_easy_unescape(NULL, string, length, NULL); -} - -/* Escapes for URL the given unescaped string of given length. - * 'data' is ignored since 7.82.0. - */ -char *curl_easy_escape(CURL *curl, const char *string, int length) -{ - size_t len; - struct dynbuf d; - (void)curl; - - if(!string || (length < 0)) - return NULL; - - len = (length ? (size_t)length : strlen(string)); - if(!len) - return curlx_strdup(""); - - if(len > SIZE_MAX / 16) - return NULL; - - curlx_dyn_init(&d, (len * 3) + 1); - - while(len--) { - /* treat the characters unsigned */ - unsigned char in = (unsigned char)*string++; - - if(ISUNRESERVED(in)) { - /* append this */ - if(curlx_dyn_addn(&d, &in, 1)) - return NULL; - } - else { - /* encode it */ - unsigned char out[3] = { '%' }; - Curl_hexbyte(&out[1], in); - if(curlx_dyn_addn(&d, out, 3)) - return NULL; - } - } - - return curlx_dyn_ptr(&d); -} - -/* - * Curl_urldecode() URL decodes the given string. - * - * Returns a pointer to a malloced string in *ostring with length given in - * *olen. If length == 0, the length is assumed to be strlen(string). - * - * ctrl options: - * - REJECT_NADA: accept everything - * - REJECT_CTRL: rejects control characters (byte codes lower than 32) in - * the data - * - REJECT_ZERO: rejects decoded zero bytes - * - * The values for the enum starts at 2, to make the assert detect legacy - * invokes that used TRUE/FALSE (0 and 1). - */ - -CURLcode Curl_urldecode(const char *string, size_t length, - char **ostring, size_t *olen, - enum urlreject ctrl) -{ - size_t alloc; - char *ns; - - DEBUGASSERT(string); - DEBUGASSERT(ctrl >= REJECT_NADA); /* crash on TRUE/FALSE */ - - alloc = (length ? length : strlen(string)); - ns = curlx_malloc(alloc + 1); - - if(!ns) - return CURLE_OUT_OF_MEMORY; - - /* store output string */ - *ostring = ns; - - while(alloc) { - unsigned char in = (unsigned char)*string; - if(('%' == in) && (alloc > 2) && - ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { - /* this is two hexadecimal digits following a '%' */ - in = (unsigned char)((curlx_hexval(string[1]) << 4) | - curlx_hexval(string[2])); - string += 3; - alloc -= 3; - } - else { - string++; - alloc--; - } - - if(((ctrl == REJECT_CTRL) && (in < 0x20)) || - ((ctrl == REJECT_ZERO) && (in == 0))) { - curlx_safefree(*ostring); - return CURLE_URL_MALFORMAT; - } - - *ns++ = (char)in; - } - *ns = 0; /* terminate it */ - - if(olen) - /* store output size */ - *olen = ns - *ostring; - - return CURLE_OK; -} - -/* - * Unescapes the given URL escaped string of given length. Returns a - * pointer to a malloced string with length given in *olen. - * If length == 0, the length is assumed to be strlen(string). - * If olen == NULL, no output length is stored. - * 'data' is ignored since 7.82.0. - */ -char *curl_easy_unescape(CURL *curl, const char *string, int inlength, - int *outlength) -{ - char *str = NULL; - (void)curl; - if(string && (inlength >= 0)) { - size_t inputlen = (size_t)inlength; - size_t outputlen; - CURLcode res = Curl_urldecode(string, inputlen, &str, &outputlen, - REJECT_NADA); - if(res) - return NULL; - - if(outlength) { - if(outputlen <= (size_t)INT_MAX) - *outlength = curlx_uztosi(outputlen); - else - /* too large to return in an int, fail! */ - curlx_safefree(str); - } - } - return str; -} - -/* For operating systems/environments that use different malloc/free - systems for the app and for this library, we provide a free that uses - the library's memory system */ -void curl_free(void *p) -{ - curlx_free(p); -} - -/* - * Curl_hexencode() - * - * Converts binary input to lowercase hex-encoded ASCII output. - * Null-terminated. - */ -void Curl_hexencode(const unsigned char *src, size_t len, /* input length */ - unsigned char *out, size_t olen) /* output buffer size */ -{ - DEBUGASSERT(src && len && (olen >= 3)); - if(src && len && (olen >= 3)) { - while(len-- && (olen >= 3)) { - out[0] = Curl_ldigits[*src >> 4]; - out[1] = Curl_ldigits[*src & 0x0F]; - ++src; - out += 2; - olen -= 2; - } - *out = 0; - } - else if(olen) - *out = 0; -} - -/* Curl_hexbyte - * - * Output a single unsigned char as a two-digit UPPERCASE hex number. - */ -void Curl_hexbyte(unsigned char *dest, /* must fit two bytes */ - unsigned char val) -{ - dest[0] = Curl_udigits[val >> 4]; - dest[1] = Curl_udigits[val & 0x0F]; -} diff --git a/vendor/curl/lib/escape.h b/vendor/curl/lib/escape.h deleted file mode 100644 index 9f9a89e40..000000000 --- a/vendor/curl/lib/escape.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HEADER_CURL_ESCAPE_H -#define HEADER_CURL_ESCAPE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* Escape and unescape URL encoding in strings. The functions return a new - * allocated string or NULL if an error occurred. */ - -enum urlreject { - REJECT_NADA = 2, - REJECT_CTRL, - REJECT_ZERO -}; - -CURLcode Curl_urldecode(const char *string, size_t length, - char **ostring, size_t *olen, - enum urlreject ctrl); - -void Curl_hexencode(const unsigned char *src, size_t len, /* input length */ - unsigned char *out, size_t olen); /* output buffer size */ - -void Curl_hexbyte(unsigned char *dest, /* must fit two bytes */ - unsigned char val); - -#endif /* HEADER_CURL_ESCAPE_H */ diff --git a/vendor/curl/lib/fake_addrinfo.c b/vendor/curl/lib/fake_addrinfo.c deleted file mode 100644 index 5a8920206..000000000 --- a/vendor/curl/lib/fake_addrinfo.c +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "fake_addrinfo.h" - -#ifdef USE_FAKE_GETADDRINFO - -#include - -void r_freeaddrinfo(struct addrinfo *cahead) -{ - struct addrinfo *canext; - struct addrinfo *ca; - - for(ca = cahead; ca; ca = canext) { - canext = ca->ai_next; - curlx_free(ca); - } -} - -struct context { - struct ares_addrinfo *addr; -}; - -static void async_addrinfo_cb(void *userp, int status, int timeouts, - struct ares_addrinfo *addr) -{ - struct context *ctx = (struct context *)userp; - (void)timeouts; - if(ARES_SUCCESS == status) { - ctx->addr = addr; - } -} - -/* convert the c-ares version into the "native" version */ -static struct addrinfo *mk_getaddrinfo(const struct ares_addrinfo *aihead) -{ - const struct ares_addrinfo_node *ai; - struct addrinfo *ca; - struct addrinfo *cafirst = NULL; - struct addrinfo *calast = NULL; - const char *name = aihead->name; - - /* traverse the addrinfo list */ - for(ai = aihead->nodes; ai != NULL; ai = ai->ai_next) { - size_t ss_size; - size_t namelen = name ? strlen(name) + 1 : 0; - /* ignore elements with unsupported address family, - settle family-specific sockaddr structure size. */ - if(ai->ai_family == AF_INET) - ss_size = sizeof(struct sockaddr_in); - else if(ai->ai_family == AF_INET6) - ss_size = sizeof(struct sockaddr_in6); - else - continue; - - /* ignore elements without required address info */ - if(!ai->ai_addr || !(ai->ai_addrlen > 0)) - continue; - - /* ignore elements with bogus address size */ - if((size_t)ai->ai_addrlen < ss_size) - continue; - - ca = curlx_malloc(sizeof(struct addrinfo) + ss_size + namelen); - if(!ca) { - r_freeaddrinfo(cafirst); - return NULL; - } - - /* copy each structure member individually, member ordering, - size, or padding might be different for each platform. */ - - ca->ai_flags = ai->ai_flags; - ca->ai_family = ai->ai_family; - ca->ai_socktype = ai->ai_socktype; - ca->ai_protocol = ai->ai_protocol; - ca->ai_addrlen = (curl_socklen_t)ss_size; - ca->ai_addr = NULL; - ca->ai_canonname = NULL; - ca->ai_next = NULL; - - ca->ai_addr = (void *)((char *)ca + sizeof(struct addrinfo)); - memcpy(ca->ai_addr, ai->ai_addr, ss_size); - - if(namelen) { - ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size); - memcpy(ca->ai_canonname, name, namelen); - - /* the name is only pointed to by the first entry in the "real" - addrinfo chain, so stop now */ - name = NULL; - } - - /* if the return list is empty, this becomes the first element */ - if(!cafirst) - cafirst = ca; - - /* add this element last in the return list */ - if(calast) - calast->ai_next = ca; - calast = ca; - } - - return cafirst; -} - -/* - RETURN VALUE - - getaddrinfo() returns 0 if it succeeds, or one of the following nonzero - error codes: - - ... -*/ -int r_getaddrinfo(const char *node, - const char *service, - const struct addrinfo *hints, - struct addrinfo **res) -{ - int status; - struct context ctx; - struct ares_options options; - int optmask = 0; - struct ares_addrinfo_hints ahints; - ares_channel channel; - int rc = 0; - - memset(&options, 0, sizeof(options)); - optmask |= ARES_OPT_EVENT_THREAD; - options.evsys = ARES_EVSYS_DEFAULT; - - memset(&ahints, 0, sizeof(ahints)); - memset(&ctx, 0, sizeof(ctx)); - - if(hints) { - ahints.ai_flags = hints->ai_flags; - ahints.ai_family = hints->ai_family; - ahints.ai_socktype = hints->ai_socktype; - ahints.ai_protocol = hints->ai_protocol; - } - - status = ares_init_options(&channel, &options, optmask); - if(status) - return EAI_MEMORY; /* major problem */ - - else { - const char *env = getenv("CURL_DNS_SERVER"); - if(env) { - rc = ares_set_servers_ports_csv(channel, env); - if(rc) { - curl_mfprintf(stderr, "ares_set_servers_ports_csv failed: %d", rc); - /* Cleanup */ - ares_destroy(channel); - return EAI_MEMORY; /* we cannot run */ - } - } - } - - ares_getaddrinfo(channel, node, service, &ahints, async_addrinfo_cb, &ctx); - - /* Wait until no more requests are left to be processed */ - ares_queue_wait_empty(channel, -1); - - if(ctx.addr) { - /* convert the c-ares version */ - *res = mk_getaddrinfo(ctx.addr); - /* free the old */ - ares_freeaddrinfo(ctx.addr); - } - else - rc = EAI_NONAME; /* got nothing */ - - /* Cleanup */ - ares_destroy(channel); - - return rc; -} - -#endif /* USE_FAKE_GETADDRINFO */ diff --git a/vendor/curl/lib/fake_addrinfo.h b/vendor/curl/lib/fake_addrinfo.h deleted file mode 100644 index 07d5b6da8..000000000 --- a/vendor/curl/lib/fake_addrinfo.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef HEADER_FAKE_ADDRINFO_H -#define HEADER_FAKE_ADDRINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_ARES -#include -#endif - -#if defined(CURL_MEMDEBUG) && defined(HAVE_GETADDRINFO) && \ - defined(USE_ARES) && (ARES_VERSION >= 0x011a00) /* >= 1.26.0 */ -#define USE_FAKE_GETADDRINFO 1 -#endif - -#ifdef USE_FAKE_GETADDRINFO - -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -void r_freeaddrinfo(struct addrinfo *res); -int r_getaddrinfo(const char *node, - const char *service, - const struct addrinfo *hints, - struct addrinfo **res); -#endif /* USE_FAKE_GETADDRINFO */ - -#endif /* HEADER_FAKE_ADDRINFO_H */ diff --git a/vendor/curl/lib/file.c b/vendor/curl/lib/file.c deleted file mode 100644 index fff8feeb9..000000000 --- a/vendor/curl/lib/file.c +++ /dev/null @@ -1,623 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "file.h" - -#ifndef CURL_DISABLE_FILE - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_DIRENT_H -#include -#endif - -#include "progress.h" -#include "sendf.h" -#include "curl_trc.h" -#include "escape.h" -#include "multiif.h" -#include "transfer.h" -#include "url.h" -#include "parsedate.h" /* for the week day and month names */ -#include "curlx/fopen.h" -#include "curl_range.h" - -#if defined(_WIN32) || defined(MSDOS) -#define DOS_FILESYSTEM 1 -#elif defined(__amigaos4__) -#define AMIGA_FILESYSTEM 1 -#endif - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_FILE_EASY "meta:proto:file:easy" - -struct FILEPROTO { - char *path; /* the path we operate on */ - char *freepath; /* pointer to the allocated block we must free, this might - differ from the 'path' pointer */ - int fd; /* open file descriptor to read from! */ -}; - -static void file_cleanup(struct FILEPROTO *file) -{ - curlx_safefree(file->freepath); - file->path = NULL; - if(file->fd != -1) { - curlx_close(file->fd); - file->fd = -1; - } -} - -static void file_easy_dtor(void *key, size_t klen, void *entry) -{ - struct FILEPROTO *file = entry; - (void)key; - (void)klen; - file_cleanup(file); - curlx_free(file); -} - -static CURLcode file_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct FILEPROTO *filep; - (void)conn; - /* allocate the FILE specific struct */ - filep = curlx_calloc(1, sizeof(*filep)); - if(filep) - filep->fd = -1; - if(!filep || - Curl_meta_set(data, CURL_META_FILE_EASY, filep, file_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static CURLcode file_done(struct Curl_easy *data, - CURLcode status, bool premature) -{ - struct FILEPROTO *file = Curl_meta_get(data, CURL_META_FILE_EASY); - (void)status; - (void)premature; - - if(file) - file_cleanup(file); - - return CURLE_OK; -} - -/* - * file_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. We emulate a - * connect-then-transfer protocol and "connect" to the file here - */ -static CURLcode file_connect(struct Curl_easy *data, bool *done) -{ - char *real_path; - struct FILEPROTO *file = Curl_meta_get(data, CURL_META_FILE_EASY); - int fd; -#ifdef DOS_FILESYSTEM - size_t i; - char *actual_path; -#endif - size_t real_path_len; - CURLcode result; - - if(!file) - return CURLE_FAILED_INIT; - - if(file->path) { - /* already connected. - * the handler->connect_it() is normally only called once, but - * FILE does a special check on setting up the connection which - * calls this explicitly. */ - *done = TRUE; - return CURLE_OK; - } - - result = Curl_urldecode(data->state.up.path, 0, &real_path, - &real_path_len, REJECT_ZERO); - if(result) - return result; - -#ifdef DOS_FILESYSTEM - /* If the first character is a slash, and there is - something that looks like a drive at the beginning of - the path, skip the slash. If we remove the initial - slash in all cases, paths without drive letters end up - relative to the current directory which is not how - browsers work. - - Some browsers accept | instead of : as the drive letter - separator, so we do too. - - On other platforms, we need the slash to indicate an - absolute pathname. On Windows, absolute paths start - with a drive letter. - */ - actual_path = real_path; - if((actual_path[0] == '/') && - actual_path[1] && - (actual_path[2] == ':' || actual_path[2] == '|')) { - actual_path[2] = ':'; - actual_path++; - real_path_len--; - } - - /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */ - for(i = 0; i < real_path_len; ++i) - if(actual_path[i] == '/') - actual_path[i] = '\\'; - else if(!actual_path[i]) { /* binary zero */ - curlx_safefree(real_path); - return CURLE_URL_MALFORMAT; - } - - fd = curlx_open(actual_path, O_RDONLY | CURL_O_BINARY); - file->path = actual_path; -#else - if(memchr(real_path, 0, real_path_len)) { - /* binary zeroes indicate foul play */ - curlx_safefree(real_path); - return CURLE_URL_MALFORMAT; - } - -#ifdef AMIGA_FILESYSTEM - /* - * A leading slash in an AmigaDOS path denotes the parent - * directory, and hence we block this as it is relative. - * Absolute paths start with 'volumename:', so we check for - * this first. Failing that, we treat the path as a real Unix - * path, but only if the application was compiled with -lunix. - */ - fd = -1; - file->path = real_path; - - if(real_path[0] == '/') { - extern int __unix_path_semantics; - if(strchr(real_path + 1, ':')) { - /* Amiga absolute path */ - fd = curlx_open(real_path + 1, O_RDONLY); - file->path++; - } - else if(__unix_path_semantics) { - /* -lunix fallback */ - fd = curlx_open(real_path, O_RDONLY); - } - } -#else - fd = curlx_open(real_path, O_RDONLY); - file->path = real_path; -#endif -#endif - curlx_free(file->freepath); - file->freepath = real_path; /* free this when done */ - - file->fd = fd; - if(!data->state.upload && (fd == -1)) { - failf(data, "Could not open file %s", data->state.up.path); - file_done(data, CURLE_FILE_COULDNT_READ_FILE, FALSE); - return CURLE_FILE_COULDNT_READ_FILE; - } - *done = TRUE; - - return CURLE_OK; -} - -static CURLcode file_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection) -{ - (void)dead_connection; - (void)conn; - return file_done(data, CURLE_OK, FALSE); -} - -#ifdef DOS_FILESYSTEM -#define DIRSEP '\\' -#else -#define DIRSEP '/' -#endif - -static CURLcode file_upload(struct Curl_easy *data, - struct FILEPROTO *file) -{ - const char *dir = strchr(file->path, DIRSEP); - int fd; - int mode; - CURLcode result = CURLE_OK; - char *xfer_ulbuf; - size_t xfer_ulblen; - curlx_struct_stat file_stat; - const char *sendbuf; - bool eos = FALSE; - - /* - * Since FILE: does not do the full init, we need to provide some extra - * assignments here. - */ - - if(!dir) - return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ - - if(!dir[1]) - return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ - - mode = O_WRONLY | O_CREAT | CURL_O_BINARY; - if(data->state.resume_from) - mode |= O_APPEND; - else - mode |= O_TRUNC; - -#ifdef _WIN32 - fd = curlx_open(file->path, mode, - data->set.new_file_perms & (_S_IREAD | _S_IWRITE)); -#elif (defined(ANDROID) || defined(__ANDROID__)) && \ - (defined(__i386__) || defined(__arm__)) - fd = curlx_open(file->path, mode, (mode_t)data->set.new_file_perms); -#else - fd = curlx_open(file->path, mode, data->set.new_file_perms); -#endif - if(fd < 0) { - failf(data, "cannot open %s for writing", file->path); - return CURLE_WRITE_ERROR; - } - - if(data->state.infilesize != -1) - /* known size of data to "upload" */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* treat the negative resume offset value as the case of "-" */ - if(data->state.resume_from < 0) { - if(curlx_fstat(fd, &file_stat)) { - curlx_close(fd); - failf(data, "cannot get the size of %s", file->path); - return CURLE_WRITE_ERROR; - } - data->state.resume_from = (curl_off_t)file_stat.st_size; - } - - result = Curl_multi_xfer_ulbuf_borrow(data, &xfer_ulbuf, &xfer_ulblen); - if(result) - goto out; - - while(!result && !eos) { - size_t nread, nwritten; - ssize_t rv; - size_t readcount; - - result = Curl_client_read(data, xfer_ulbuf, xfer_ulblen, &readcount, &eos); - if(result) - break; - - if(!readcount) - break; - - nread = readcount; - - /* skip bytes before resume point */ - if(data->state.resume_from) { - if((curl_off_t)nread <= data->state.resume_from) { - data->state.resume_from -= nread; - nread = 0; - sendbuf = xfer_ulbuf; - } - else { - sendbuf = xfer_ulbuf + data->state.resume_from; - nread -= (size_t)data->state.resume_from; - data->state.resume_from = 0; - } - } - else - sendbuf = xfer_ulbuf; - - /* write the data to the target */ - rv = write(fd, sendbuf, nread); - if(!curlx_sztouz(rv, &nwritten) || (nwritten != nread)) { - result = CURLE_SEND_ERROR; - break; - } - Curl_pgrs_upload_inc(data, nwritten); - - result = Curl_pgrsCheck(data); - } - if(!result) - result = Curl_pgrsUpdate(data); - -out: - curlx_close(fd); - Curl_multi_xfer_ulbuf_release(data, xfer_ulbuf); - - return result; -} - -/* - * file_do() is the protocol-specific function for the do-phase, separated - * from the connect-phase above. Other protocols merely setup the transfer in - * the do-phase, to have it done in the main transfer loop but since some - * platforms we support do not allow select()ing etc on file handles (as - * opposed to sockets) we instead perform the whole do-operation in this - * function. - */ -static CURLcode file_do(struct Curl_easy *data, bool *done) -{ - /* This implementation ignores the hostname in conformance with - RFC 1738. Only local files (reachable via the standard file system) - are supported. This means that files on remotely mounted directories - (via NFS, Samba, NT sharing) can be accessed through a file:// URL - */ - struct FILEPROTO *file = Curl_meta_get(data, CURL_META_FILE_EASY); - CURLcode result = CURLE_OK; - curlx_struct_stat statbuf; - curl_off_t expected_size = -1; - bool size_known; - bool fstated = FALSE; - int fd; - char *xfer_buf; - size_t xfer_blen; - - *done = TRUE; /* unconditionally */ - if(!file) - return CURLE_FAILED_INIT; - - if(data->state.upload) - return file_upload(data, file); - - /* get the fd from the connection phase */ - fd = file->fd; - - /* VMS: This only works reliable for STREAMLF files */ - if(curlx_fstat(fd, &statbuf) != -1) { - if(!S_ISDIR(statbuf.st_mode)) - expected_size = statbuf.st_size; - /* and store the modification time */ - data->info.filetime = statbuf.st_mtime; - fstated = TRUE; - } - - if(fstated && !data->state.range && data->set.timecondition && - !Curl_meets_timecondition(data, data->info.filetime)) - return CURLE_OK; - - if(fstated) { - time_t filetime; - struct tm buffer; - const struct tm *tm = &buffer; - char header[80]; - int headerlen; - static const char accept_ranges[] = { "Accept-ranges: bytes\r\n" }; - if(expected_size >= 0) { - headerlen = - curl_msnprintf(header, sizeof(header), - "Content-Length: %" FMT_OFF_T "\r\n", expected_size); - result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen); - if(result) - return result; - - result = Curl_client_write(data, CLIENTWRITE_HEADER, - accept_ranges, sizeof(accept_ranges) - 1); - if(result != CURLE_OK) - return result; - } - - filetime = (time_t)statbuf.st_mtime; - result = curlx_gmtime(filetime, &buffer); - if(result) - return result; - - /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - headerlen = - curl_msnprintf(header, sizeof(header), - "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", - Curl_wkday[tm->tm_wday ? tm->tm_wday - 1 : 6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen); - if(!result) - /* end of headers */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, "\r\n", 2); - if(result) - return result; - /* set the file size to make it available post transfer */ - Curl_pgrsSetDownloadSize(data, expected_size); - if(data->req.no_body) - return CURLE_OK; - } - - /* Check whether file range has been specified */ - result = Curl_range(data); - if(result) - return result; - - /* Adjust the start offset in case we want to get the N last bytes - * of the stream if the filesize could be determined */ - if(data->state.resume_from < 0) { - if(!fstated) { - failf(data, "cannot get the size of file."); - return CURLE_READ_ERROR; - } - data->state.resume_from += (curl_off_t)statbuf.st_size; - } - - if(data->state.resume_from > 0) { - /* We check explicitly if we have a start offset, because - * expected_size may be -1 if we do not know how large the file is, - * in which case we should not adjust it. */ - if(data->state.resume_from <= expected_size) - expected_size -= data->state.resume_from; - else { - failf(data, "failed to resume file:// transfer"); - return CURLE_BAD_DOWNLOAD_RESUME; - } - } - - /* A high water mark has been specified so we obey... */ - if(data->req.maxdownload > 0) - expected_size = data->req.maxdownload; - - if(!fstated || (expected_size <= 0)) - size_known = FALSE; - else - size_known = TRUE; - - /* The following is a shortcut implementation of file reading - this is both more efficient than the former call to download() and - it avoids problems with select() and recv() on file descriptors - in Winsock */ - if(size_known) - Curl_pgrsSetDownloadSize(data, expected_size); - - if(data->state.resume_from) { - if(!S_ISDIR(statbuf.st_mode)) { - if(data->state.resume_from != - curl_lseek(fd, data->state.resume_from, SEEK_SET)) - return CURLE_BAD_DOWNLOAD_RESUME; - } - else { - return CURLE_BAD_DOWNLOAD_RESUME; - } - } - - result = Curl_multi_xfer_buf_borrow(data, &xfer_buf, &xfer_blen); - if(result) - goto out; - - if(!S_ISDIR(statbuf.st_mode)) { - while(!result) { - ssize_t nread; - /* Do not fill a whole buffer if we want less than all data */ - size_t bytestoread; - - if(size_known) { - bytestoread = (expected_size < (curl_off_t)(xfer_blen - 1)) ? - curlx_sotouz(expected_size) : (xfer_blen - 1); - } - else - bytestoread = xfer_blen - 1; - - nread = read(fd, xfer_buf, bytestoread); - - if(nread > 0) - xfer_buf[nread] = 0; - - if(nread <= 0 || (size_known && (expected_size == 0))) - break; - - if(size_known) - expected_size -= nread; - - result = Curl_client_write(data, CLIENTWRITE_BODY, xfer_buf, nread); - if(result) - goto out; - - result = Curl_pgrsCheck(data); - if(result) - goto out; - } - } - else { -#ifdef HAVE_OPENDIR - DIR *dir = opendir(file->path); - struct dirent *entry; - - if(!dir) { - result = CURLE_READ_ERROR; - goto out; - } - else { - while((entry = readdir(dir))) { - if(entry->d_name[0] != '.') { - result = Curl_client_write(data, CLIENTWRITE_BODY, - entry->d_name, strlen(entry->d_name)); - if(result) - break; - result = Curl_client_write(data, CLIENTWRITE_BODY, "\n", 1); - if(result) - break; - } - } - closedir(dir); - } -#else - failf(data, "Directory listing not yet implemented on this platform."); - result = CURLE_READ_ERROR; -#endif - } - - if(!result) - result = Curl_pgrsUpdate(data); - -out: - Curl_multi_xfer_buf_release(data, xfer_buf); - return result; -} - -const struct Curl_protocol Curl_protocol_file = { - file_setup_connection, /* setup_connection */ - file_do, /* do_it */ - file_done, /* done */ - ZERO_NULL, /* do_more */ - file_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - ZERO_NULL, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - file_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif diff --git a/vendor/curl/lib/file.h b/vendor/curl/lib/file.h deleted file mode 100644 index 0aa411b19..000000000 --- a/vendor/curl/lib/file.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_FILE_H -#define HEADER_CURL_FILE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_FILE -extern const struct Curl_protocol Curl_protocol_file; -#endif - -#endif /* HEADER_CURL_FILE_H */ diff --git a/vendor/curl/lib/fileinfo.c b/vendor/curl/lib/fileinfo.c deleted file mode 100644 index 33e5acde0..000000000 --- a/vendor/curl/lib/fileinfo.c +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP - -#include "fileinfo.h" - -struct fileinfo *Curl_fileinfo_alloc(void) -{ - return curlx_calloc(1, sizeof(struct fileinfo)); -} - -void Curl_fileinfo_cleanup(struct fileinfo *finfo) -{ - if(!finfo) - return; - - curlx_dyn_free(&finfo->buf); - curlx_free(finfo); -} - -#endif /* !CURL_DISABLE_FTP */ diff --git a/vendor/curl/lib/fileinfo.h b/vendor/curl/lib/fileinfo.h deleted file mode 100644 index 737966788..000000000 --- a/vendor/curl/lib/fileinfo.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_FILEINFO_H -#define HEADER_CURL_FILEINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "llist.h" -#include "curlx/dynbuf.h" - -struct fileinfo { - struct curl_fileinfo info; - struct Curl_llist_node list; - struct dynbuf buf; -}; - -struct fileinfo *Curl_fileinfo_alloc(void); -void Curl_fileinfo_cleanup(struct fileinfo *finfo); - -#endif /* HEADER_CURL_FILEINFO_H */ diff --git a/vendor/curl/lib/formdata.c b/vendor/curl/lib/formdata.c deleted file mode 100644 index 3619c15bb..000000000 --- a/vendor/curl/lib/formdata.c +++ /dev/null @@ -1,866 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_easy; - -#include "formdata.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API) - -#include "urldata.h" /* for struct Curl_easy */ -#include "mime.h" -#include "curlx/strdup.h" -#include "bufref.h" -#include "curlx/fopen.h" - - -#define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME -#define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME -#define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS -#define HTTPPOST_READFILE CURL_HTTPPOST_READFILE -#define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER -#define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK -#define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER - -/*************************************************************************** - * - * AddHttpPost() - * - * Adds an HttpPost structure to the list, if parent_post is given becomes - * a subpost of parent_post instead of a direct list element. - * - * Returns newly allocated HttpPost on success and NULL if malloc failed. - * - ***************************************************************************/ -static struct curl_httppost *AddHttpPost(struct FormInfo *src, - struct curl_httppost *parent_post, - struct curl_httppost **httppost, - struct curl_httppost **last_post) -{ - struct curl_httppost *post; - size_t namelength = src->namelength; - if(!namelength && Curl_bufref_ptr(&src->name)) - namelength = strlen(Curl_bufref_ptr(&src->name)); - if((src->bufferlength > LONG_MAX) || (namelength > LONG_MAX)) - /* avoid overflow in typecasts below */ - return NULL; - post = curlx_calloc(1, sizeof(struct curl_httppost)); - if(post) { - post->name = CURL_UNCONST(Curl_bufref_ptr(&src->name)); - post->namelength = (long)namelength; - post->contents = CURL_UNCONST(Curl_bufref_ptr(&src->value)); - post->contentlen = src->contentslength; - post->buffer = src->buffer; - post->bufferlength = (long)src->bufferlength; - post->contenttype = CURL_UNCONST(Curl_bufref_ptr(&src->contenttype)); - post->flags = src->flags | CURL_HTTPPOST_LARGE; - post->contentheader = src->contentheader; - post->showfilename = CURL_UNCONST(Curl_bufref_ptr(&src->showfilename)); - post->userp = src->userp; - } - else - return NULL; - - if(parent_post) { - /* now, point our 'more' to the original 'more' */ - post->more = parent_post->more; - - /* then move the original 'more' to point to ourselves */ - parent_post->more = post; - } - else { - /* make the previous point to this */ - if(*last_post) - (*last_post)->next = post; - else - (*httppost) = post; - - (*last_post) = post; - } - return post; -} - -/* Allocate and initialize a new FormInfo structure. */ -static struct FormInfo *NewFormInfo(void) -{ - struct FormInfo *form_info = curlx_calloc(1, sizeof(struct FormInfo)); - - if(form_info) { - Curl_bufref_init(&form_info->name); - Curl_bufref_init(&form_info->value); - Curl_bufref_init(&form_info->contenttype); - Curl_bufref_init(&form_info->showfilename); - } - - return form_info; -} - -/* Replace the target field data by a dynamic copy of it. */ -static CURLcode FormInfoCopyField(struct bufref *field, size_t len) -{ - const char *value = Curl_bufref_ptr(field); - CURLcode result = CURLE_OK; - - if(value) { - if(!len) - len = strlen(value); - result = Curl_bufref_memdup0(field, value, len); - } - - return result; -} - -/*************************************************************************** - * - * AddFormInfo() - * - * Adds a FormInfo structure to the list presented by parent. - * - ***************************************************************************/ -static void AddFormInfo(struct FormInfo *form_info, struct FormInfo *parent) -{ - form_info->flags |= HTTPPOST_FILENAME; - - if(parent) { - /* now, point our 'more' to the original 'more' */ - form_info->more = parent->more; - - /* then move the original 'more' to point to ourselves */ - parent->more = form_info; - } -} - -static void free_formlist(struct FormInfo *ptr) -{ - for(; ptr != NULL; ptr = ptr->more) { - Curl_bufref_free(&ptr->name); - Curl_bufref_free(&ptr->value); - Curl_bufref_free(&ptr->contenttype); - Curl_bufref_free(&ptr->showfilename); - } -} - -/*************************************************************************** - * - * FormAdd() - * - * Stores a formpost parameter and builds the appropriate linked list. - * - * Has two principal functionalities: using files and byte arrays as post - * parts. Byte arrays are either copied or the pointer is stored (as the user - * requests) while for files only the filename and not the content is stored. - * - * While you may have only one byte array for each name, multiple filenames - * are allowed (and because of this feature CURLFORM_END is needed after - * using CURLFORM_FILE). - * - * Examples: - * - * Simple name/value pair with copied contents: - * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); - * - * name/value pair where only the content pointer is remembered: - * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, - * CURLFORM_END); - * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) - * - * storing a filename (CONTENTTYPE is optional!): - * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text", - * CURLFORM_END); - * - * storing multiple filenames: - * curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", - * CURLFORM_END); - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if an HttpPost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ - -static CURLFORMcode FormAddCheck(struct FormInfo *first_form, - struct curl_httppost **httppost, - struct curl_httppost **last_post) -{ - const char *prevtype = NULL; - struct FormInfo *form = NULL; - struct curl_httppost *post = NULL; - - /* go through the list, check for completeness and if everything is - * alright add the HttpPost item otherwise set retval accordingly */ - - for(form = first_form; form != NULL; form = form->more) { - const char *name = Curl_bufref_ptr(&form->name); - - if(((!name || !Curl_bufref_ptr(&form->value)) && !post) || - (form->contentslength && - (form->flags & HTTPPOST_FILENAME)) || - ((form->flags & HTTPPOST_FILENAME) && - (form->flags & HTTPPOST_PTRCONTENTS)) || - - (!form->buffer && - (form->flags & HTTPPOST_BUFFER) && - (form->flags & HTTPPOST_PTRBUFFER)) || - - ((form->flags & HTTPPOST_READFILE) && - (form->flags & HTTPPOST_PTRCONTENTS)) - ) { - return CURL_FORMADD_INCOMPLETE; - } - if(((form->flags & HTTPPOST_FILENAME) || - (form->flags & HTTPPOST_BUFFER)) && - !Curl_bufref_ptr(&form->contenttype)) { - const char *f = Curl_bufref_ptr((form->flags & HTTPPOST_BUFFER) ? - &form->showfilename : &form->value); - const char *type = Curl_mime_contenttype(f); - if(!type) - type = prevtype; - if(!type) - type = FILE_CONTENTTYPE_DEFAULT; - - /* our contenttype is missing */ - if(Curl_bufref_memdup0(&form->contenttype, type, strlen(type))) - return CURL_FORMADD_MEMORY; - } - if(name && form->namelength) { - if(memchr(name, 0, form->namelength)) - return CURL_FORMADD_NULL; - } - if(!(form->flags & HTTPPOST_PTRNAME)) { - /* Note that there is small risk that form->name is NULL here if the app - passed in a bad combo, so we check for that. */ - if(FormInfoCopyField(&form->name, form->namelength)) - return CURL_FORMADD_MEMORY; - } - if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE | - HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | - HTTPPOST_CALLBACK))) { - if(FormInfoCopyField(&form->value, (size_t)form->contentslength)) - return CURL_FORMADD_MEMORY; - } - post = AddHttpPost(form, post, httppost, last_post); - - if(!post) - return CURL_FORMADD_MEMORY; - - if(Curl_bufref_ptr(&form->contenttype)) - prevtype = Curl_bufref_ptr(&form->contenttype); - } - - return CURL_FORMADD_OK; -} - -/* Shallow cleanup. Remove the newly created chain, the structs only and not - the content they point to */ -static void free_chain(struct curl_httppost *c) -{ - while(c) { - struct curl_httppost *next = c->next; - if(c->more) - free_chain(c->more); - curlx_free(c); - c = next; - } -} - -static CURLFORMcode FormAdd(struct curl_httppost **httppost, - struct curl_httppost **last_post, va_list params) -{ - struct FormInfo *first_form, *curr, *form = NULL; - CURLFORMcode retval = CURL_FORMADD_OK; - CURLformoption option; - const struct curl_forms *forms = NULL; - char *avalue = NULL; - struct curl_httppost *newchain = NULL; - struct curl_httppost *lastnode = NULL; - -#define form_ptr_arg(t) (forms ? (t)(void *)avalue : va_arg(params, t)) -#ifdef HAVE_UINTPTR_T -#define form_int_arg(t) (forms ? (t)(uintptr_t)avalue : va_arg(params, t)) -#else -#define form_int_arg(t) (forms ? (t)(void *)avalue : va_arg(params, t)) -#endif - - /* - * We need to allocate the first struct to fill in. - */ - first_form = NewFormInfo(); - if(!first_form) - return CURL_FORMADD_MEMORY; - - curr = first_form; - - /* - * Loop through all the options set. Break if we have an error to report. - */ - while(retval == CURL_FORMADD_OK) { - - /* first see if we have more parts of the array param */ - if(forms) { - /* get the upcoming option from the given array */ - option = forms->option; - avalue = (char *)CURL_UNCONST(forms->value); - - forms++; /* advance this to next entry */ - if(CURLFORM_END == option) { - /* end of array state */ - forms = NULL; - continue; - } - } - else { - /* This is not array-state, get next option. This gets an 'int' with - va_arg() because CURLformoption might be a smaller type than int and - might cause compiler warnings and wrong behavior. */ - option = (CURLformoption)va_arg(params, int); - if(CURLFORM_END == option) - break; - } - - switch(option) { - case CURLFORM_ARRAY: - if(forms) - /* we do not support an array from within an array */ - retval = CURL_FORMADD_ILLEGAL_ARRAY; - else { - forms = va_arg(params, struct curl_forms *); - if(!forms) - retval = CURL_FORMADD_NULL; - } - break; - - /* - * Set the Name property. - */ - case CURLFORM_PTRNAME: - curr->flags |= HTTPPOST_PTRNAME; - FALLTHROUGH(); - case CURLFORM_COPYNAME: - if(Curl_bufref_ptr(&curr->name)) - retval = CURL_FORMADD_OPTION_TWICE; - else { - avalue = form_ptr_arg(char *); - if(avalue) - Curl_bufref_set(&curr->name, avalue, 0, NULL); /* No copy yet. */ - else - retval = CURL_FORMADD_NULL; - } - break; - case CURLFORM_NAMELENGTH: - if(curr->namelength) - retval = CURL_FORMADD_OPTION_TWICE; - else - curr->namelength = (size_t)form_int_arg(long); - break; - - /* - * Set the contents property. - */ - case CURLFORM_PTRCONTENTS: - curr->flags |= HTTPPOST_PTRCONTENTS; - FALLTHROUGH(); - case CURLFORM_COPYCONTENTS: - if(Curl_bufref_ptr(&curr->value)) - retval = CURL_FORMADD_OPTION_TWICE; - else { - avalue = form_ptr_arg(char *); - if(avalue) - Curl_bufref_set(&curr->value, avalue, 0, NULL); /* No copy yet. */ - else - retval = CURL_FORMADD_NULL; - } - break; - case CURLFORM_CONTENTSLENGTH: - curr->contentslength = (curl_off_t)(size_t)form_int_arg(long); - break; - - case CURLFORM_CONTENTLEN: - curr->flags |= CURL_HTTPPOST_LARGE; - curr->contentslength = form_int_arg(curl_off_t); - break; - - /* Get contents from a given filename */ - case CURLFORM_FILECONTENT: - if(curr->flags & (HTTPPOST_PTRCONTENTS | HTTPPOST_READFILE)) - retval = CURL_FORMADD_OPTION_TWICE; - else { - avalue = form_ptr_arg(char *); - if(avalue) { - if(Curl_bufref_memdup0(&curr->value, avalue, strlen(avalue))) - retval = CURL_FORMADD_MEMORY; - else - curr->flags |= HTTPPOST_READFILE; - } - else - retval = CURL_FORMADD_NULL; - } - break; - - /* We upload a file */ - case CURLFORM_FILE: - avalue = form_ptr_arg(char *); - if(Curl_bufref_ptr(&curr->value)) { - if(curr->flags & HTTPPOST_FILENAME) { - if(avalue) { - form = NewFormInfo(); - if(!form || - Curl_bufref_memdup0(&form->value, avalue, strlen(avalue))) { - curlx_free(form); - retval = CURL_FORMADD_MEMORY; - } - else { - AddFormInfo(form, curr); - curr = form; - form = NULL; - } - } - else - retval = CURL_FORMADD_NULL; - } - else - retval = CURL_FORMADD_OPTION_TWICE; - } - else { - if(avalue) { - if(Curl_bufref_memdup0(&curr->value, avalue, strlen(avalue))) - retval = CURL_FORMADD_MEMORY; - else - curr->flags |= HTTPPOST_FILENAME; - } - else - retval = CURL_FORMADD_NULL; - } - break; - - case CURLFORM_BUFFERPTR: - curr->flags |= HTTPPOST_PTRBUFFER | HTTPPOST_BUFFER; - if(curr->buffer) - retval = CURL_FORMADD_OPTION_TWICE; - else { - avalue = form_ptr_arg(char *); - if(avalue) { - curr->buffer = avalue; /* store for the moment */ - /* Make value non-NULL to be accepted as fine */ - Curl_bufref_set(&curr->value, avalue, 0, NULL); - } - else - retval = CURL_FORMADD_NULL; - } - break; - - case CURLFORM_BUFFERLENGTH: - if(curr->bufferlength) - retval = CURL_FORMADD_OPTION_TWICE; - else - curr->bufferlength = (size_t)form_int_arg(long); - break; - - case CURLFORM_STREAM: - curr->flags |= HTTPPOST_CALLBACK; - if(curr->userp) - retval = CURL_FORMADD_OPTION_TWICE; - else { - avalue = form_ptr_arg(char *); - if(avalue) { - curr->userp = avalue; - /* The following line is not strictly true but we derive a value - from this later on and we need this non-NULL to be accepted as - a fine form part */ - Curl_bufref_set(&curr->value, avalue, 0, NULL); - } - else - retval = CURL_FORMADD_NULL; - } - break; - - case CURLFORM_CONTENTTYPE: - avalue = form_ptr_arg(char *); - if(Curl_bufref_ptr(&curr->contenttype)) { - if(curr->flags & HTTPPOST_FILENAME) { - if(avalue) { - form = NewFormInfo(); - if(!form || Curl_bufref_memdup0(&form->contenttype, avalue, - strlen(avalue))) { - curlx_free(form); - retval = CURL_FORMADD_MEMORY; - } - else { - AddFormInfo(form, curr); - curr = form; - form = NULL; - } - } - else - retval = CURL_FORMADD_NULL; - } - else - retval = CURL_FORMADD_OPTION_TWICE; - } - else if(avalue) { - if(Curl_bufref_memdup0(&curr->contenttype, avalue, strlen(avalue))) - retval = CURL_FORMADD_MEMORY; - } - else - retval = CURL_FORMADD_NULL; - break; - - case CURLFORM_CONTENTHEADER: { - /* this "cast increases required alignment of target type" but - we consider it OK anyway */ - struct curl_slist *list = form_ptr_arg(struct curl_slist *); - - if(curr->contentheader) - retval = CURL_FORMADD_OPTION_TWICE; - else - curr->contentheader = list; - - break; - } - case CURLFORM_FILENAME: - case CURLFORM_BUFFER: - avalue = form_ptr_arg(char *); - if(Curl_bufref_ptr(&curr->showfilename)) - retval = CURL_FORMADD_OPTION_TWICE; - else if(Curl_bufref_memdup0(&curr->showfilename, avalue, strlen(avalue))) - retval = CURL_FORMADD_MEMORY; - break; - - default: - retval = CURL_FORMADD_UNKNOWN_OPTION; - break; - } - } - - if(!retval) - retval = FormAddCheck(first_form, &newchain, &lastnode); - - if(retval) - /* On error, free allocated fields for all nodes of the FormInfo linked - list without deallocating nodes. List nodes are deallocated later on */ - free_formlist(first_form); - - /* Always deallocate FormInfo linked list nodes without touching node - fields given that these have either been deallocated or are owned - now by the httppost linked list */ - while(first_form) { - struct FormInfo *ptr = first_form->more; - curlx_free(first_form); - first_form = ptr; - } - - if(!retval) { - /* Only if all is fine, link the new chain into the provided list */ - if(*last_post) - (*last_post)->next = newchain; - else - (*httppost) = newchain; - - (*last_post) = lastnode; - } - else - free_chain(newchain); - - return retval; -#undef form_ptr_arg -#undef form_int_arg -} - -/* - * curl_formadd() is a public API to add a section to the multipart formpost. - * - * @unittest: 1308 - */ - -CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, ...) -{ - va_list arg; - CURLFORMcode form; - va_start(arg, last_post); - form = FormAdd(httppost, last_post, arg); - va_end(arg); - return form; -} - -/* - * curl_formget() - * Serialize a curl_httppost struct. - * Returns 0 on success. - * - * @unittest: 1308 - */ -int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append) -{ - CURLcode result; - curl_mimepart toppart; - - /* Validate callback is provided */ - if(!append) - return (int)CURLE_BAD_FUNCTION_ARGUMENT; - - Curl_mime_initpart(&toppart); /* default form is empty */ - result = Curl_getformdata(NULL, &toppart, form, NULL); - if(!result) - result = Curl_mime_prepare_headers(NULL, &toppart, "multipart/form-data", - NULL, MIMESTRATEGY_FORM); - - while(!result) { - char buffer[8192]; - size_t nread = Curl_mime_read(buffer, 1, sizeof(buffer), &toppart); - - if(!nread) - break; - - if(nread > sizeof(buffer) || append(arg, buffer, nread) != nread) { - result = CURLE_READ_ERROR; - if(nread == CURL_READFUNC_ABORT) - result = CURLE_ABORTED_BY_CALLBACK; - } - } - - Curl_mime_cleanpart(&toppart); - return (int)result; -} - -/* - * curl_formfree() is an external function to free up a whole form post - * chain - */ -void curl_formfree(struct curl_httppost *form) -{ - struct curl_httppost *next; - - if(!form) - /* no form to free, get out of this */ - return; - - do { - next = form->next; /* the following form line */ - - /* recurse to sub-contents */ - curl_formfree(form->more); - - if(!(form->flags & HTTPPOST_PTRNAME)) - curlx_free(form->name); /* free the name */ - if(!(form->flags & - (HTTPPOST_PTRCONTENTS | HTTPPOST_BUFFER | HTTPPOST_CALLBACK))) - curlx_free(form->contents); /* free the contents */ - curlx_free(form->contenttype); /* free the content type */ - curlx_free(form->showfilename); /* free the faked filename */ - curlx_free(form); /* free the struct */ - form = next; - } while(form); /* continue */ -} - -/* Set mime part name, taking care of non null-terminated name string. */ -static CURLcode setname(curl_mimepart *part, const char *name, size_t len) -{ - char *zname; - CURLcode result; - - if(!name || !len) - return curl_mime_name(part, name); - zname = curlx_memdup0(name, len); - if(!zname) - return CURLE_OUT_OF_MEMORY; - result = curl_mime_name(part, zname); - curlx_free(zname); - return result; -} - -/* - * Curl_getformdata() converts a linked list of "meta data" into a mime - * structure. The input list is in 'post', while the output is stored in - * mime part at '*finalform'. - * - * This function will not do a failf() for the potential memory failures but - * should for all other errors it spots. Note that this function MAY get a - * NULL pointer in the 'data' argument. - */ - -CURLcode Curl_getformdata(CURL *data, - curl_mimepart *finalform, - struct curl_httppost *post, - curl_read_callback fread_func) -{ - CURLcode result = CURLE_OK; - curl_mime *form = NULL; - curl_mimepart *part; - struct curl_httppost *file; - - Curl_mime_cleanpart(finalform); /* default form is empty */ - - if(!post) - return result; /* no input => no output! */ - - form = curl_mime_init(data); - if(!form) - result = CURLE_OUT_OF_MEMORY; - - if(!result) - result = curl_mime_subparts(finalform, form); - - /* Process each top part. */ - for(; !result && post; post = post->next) { - /* If we have more than a file here, create a mime subpart and fill it. */ - curl_mime *multipart = form; - if(post->more) { - part = curl_mime_addpart(form); - if(!part) - result = CURLE_OUT_OF_MEMORY; - if(!result) - result = setname(part, post->name, post->namelength); - if(!result) { - multipart = curl_mime_init(data); - if(!multipart) - result = CURLE_OUT_OF_MEMORY; - } - if(!result) - result = curl_mime_subparts(part, multipart); - } - - /* Generate all the part contents. */ - for(file = post; !result && file; file = file->more) { - /* Create the part. */ - part = curl_mime_addpart(multipart); - if(!part) - result = CURLE_OUT_OF_MEMORY; - - /* Set the headers. */ - if(!result) - result = curl_mime_headers(part, file->contentheader, 0); - - /* Set the content type. */ - if(!result && file->contenttype) - result = curl_mime_type(part, file->contenttype); - - /* Set field name. */ - if(!result && !post->more) - result = setname(part, post->name, post->namelength); - - /* Process contents. */ - if(!result) { - curl_off_t clen = post->contentslength; - - if(post->flags & CURL_HTTPPOST_LARGE) - clen = post->contentlen; - - if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) { - if(!strcmp(file->contents, "-")) { - /* There are a few cases where the code below will not work; in - particular, freopen(stdin) by the caller is not guaranteed - to result as expected. This feature has been kept for backward - compatibility: use of "-" pseudo filename should be avoided. */ -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - result = curl_mime_data_cb(part, (curl_off_t)-1, - (curl_read_callback)fread, - curlx_fseek, - NULL, (void *)stdin); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - } - else - result = curl_mime_filedata(part, file->contents); - if(!result && (post->flags & HTTPPOST_READFILE)) - result = curl_mime_filename(part, NULL); - } - else if(post->flags & HTTPPOST_BUFFER) - result = curl_mime_data(part, post->buffer, - post->bufferlength ? - post->bufferlength : -1); - else if(post->flags & HTTPPOST_CALLBACK) { - /* the contents should be read with the callback and the size is set - with the contentslength */ - if(!clen) - clen = -1; - result = curl_mime_data_cb(part, clen, - fread_func, NULL, NULL, post->userp); - } - else { - size_t uclen; - if(!clen) - uclen = CURL_ZERO_TERMINATED; - else - uclen = (size_t)clen; - result = curl_mime_data(part, post->contents, uclen); - } - } - - /* Set fake filename. */ - if(!result && post->showfilename) - if(post->more || (post->flags & (HTTPPOST_FILENAME | HTTPPOST_BUFFER | - HTTPPOST_CALLBACK))) - result = curl_mime_filename(part, post->showfilename); - } - } - - if(result) - Curl_mime_cleanpart(finalform); - - return result; -} - -#else /* if disabled */ -CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, ...) -{ - (void)httppost; - (void)last_post; - return CURL_FORMADD_DISABLED; -} - -int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append) -{ - (void)form; - (void)arg; - (void)append; - return CURL_FORMADD_DISABLED; -} - -void curl_formfree(struct curl_httppost *form) -{ - (void)form; - /* Nothing to do. */ -} - -#endif /* if disabled */ diff --git a/vendor/curl/lib/formdata.h b/vendor/curl/lib/formdata.h deleted file mode 100644 index 33d7d0ae3..000000000 --- a/vendor/curl/lib/formdata.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef HEADER_CURL_FORMDATA_H -#define HEADER_CURL_FORMDATA_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FORM_API - -#include "bufref.h" - -/* used by FormAdd for temporary storage */ -struct FormInfo { - struct bufref name; - struct bufref value; - struct bufref contenttype; - struct bufref showfilename; /* The filename to show. If not set, the actual - filename will be used */ - char *buffer; /* pointer to existing buffer used for file upload */ - char *userp; /* pointer for the read callback */ - struct FormInfo *more; - struct curl_slist *contentheader; - curl_off_t contentslength; - size_t namelength; - size_t bufferlength; - unsigned char flags; -}; - -CURLcode Curl_getformdata(CURL *data, - curl_mimepart *finalform, - struct curl_httppost *post, - curl_read_callback fread_func); -#endif /* CURL_DISABLE_FORM_API */ - -#endif /* HEADER_CURL_FORMDATA_H */ diff --git a/vendor/curl/lib/ftp-int.h b/vendor/curl/lib/ftp-int.h deleted file mode 100644 index 68d26f332..000000000 --- a/vendor/curl/lib/ftp-int.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef HEADER_CURL_FTP_INT_H -#define HEADER_CURL_FTP_INT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "pingpong.h" - -#ifndef CURL_DISABLE_FTP - -/**************************************************************************** - * FTP unique setup - ***************************************************************************/ -enum { - FTP_STOP, /* do nothing state, stops the state machine */ - FTP_WAIT220, /* waiting for the initial 220 response immediately after - a connect */ - FTP_AUTH, - FTP_USER, - FTP_PASS, - FTP_ACCT, - FTP_PBSZ, - FTP_PROT, - FTP_CCC, - FTP_PWD, - FTP_SYST, - FTP_NAMEFMT, - FTP_QUOTE, /* waiting for a response to a command sent in a quote list */ - FTP_RETR_PREQUOTE, - FTP_STOR_PREQUOTE, - FTP_LIST_PREQUOTE, - FTP_POSTQUOTE, - FTP_CWD, /* change directory */ - FTP_MKD, /* if the directory did not exist */ - FTP_MDTM, /* to figure out the datestamp */ - FTP_TYPE, /* to set type when doing a head-like request */ - FTP_LIST_TYPE, /* set type when about to do a directory list */ - FTP_RETR_LIST_TYPE, - FTP_RETR_TYPE, /* set type when about to RETR a file */ - FTP_STOR_TYPE, /* set type when about to STOR a file */ - FTP_SIZE, /* get the remote file's size for head-like request */ - FTP_RETR_SIZE, /* get the remote file's size for RETR */ - FTP_STOR_SIZE, /* get the size for STOR */ - FTP_REST, /* when used to check if the server supports it in head-like */ - FTP_RETR_REST, /* when asking for "resume" in for RETR */ - FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */ - FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */ - FTP_PASV, /* generic state for PASV and EPSV, check count1 */ - FTP_LIST, /* generic state for LIST, NLST or a custom list command */ - FTP_RETR, - FTP_STOR, /* generic state for STOR and APPE */ - FTP_QUIT, - FTP_LAST /* never used */ -}; -typedef unsigned char ftpstate; /* use the enum values */ - -struct ftp_parselist_data; /* defined later in ftplistparser.c */ - -struct ftp_wc { - struct ftp_parselist_data *parser; - - struct { - curl_write_callback write_function; - FILE *file_descriptor; - } backup; -}; - -/* This FTP struct is used in the Curl_easy. All FTP data that is - connection-oriented must be in FTP_conn to properly deal with the fact that - perhaps the Curl_easy is changed between the times the connection is - used. */ -struct FTP { - char *path; /* points to the urlpieces struct field */ - char *pathalloc; /* if non-NULL a pointer to an allocated path */ - - /* transfer a file/body or not, done as a typedefed enum to make debuggers - display the full symbol and not the numerical value */ - curl_pp_transfer transfer; - curl_off_t downloadsize; -}; - -/* one struct entry for each path component (of 'rawpath') */ -struct pathcomp { - int start; /* start column */ - int len; /* length in bytes */ -}; - -/* ftp_conn is used for struct connection-oriented data in the connectdata - struct */ -struct ftp_conn { - struct pingpong pp; - char *account; - char *alternative_to_user; - char *entrypath; /* the PWD reply when we logged on */ - const char *file; /* url-decoded filename (or path), points into rawpath */ - char *rawpath; /* URL decoded, allocated, version of the path */ - struct pathcomp *dirs; /* allocated array for path components */ - char *prevpath; /* url-decoded conn->path from the previous transfer */ - char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a - and others (A/I or zero) */ - char *server_os; /* The target server operating system. */ - curl_off_t known_filesize; /* file size is different from -1, if wildcard - LIST parsing was done and wc_statemach set - it */ - int count1; /* general purpose counter for the state machine */ - int count2; /* general purpose counter for the state machine */ - int count3; /* general purpose counter for the state machine */ - unsigned short dirdepth; /* number of entries used in the 'dirs' array, - < FTP_MAX_DIR_DEPTH */ - unsigned short cwdcount; /* number of CWD commands issued, - < FTP_MAX_DIR_DEPTH */ - unsigned char state; /* (ftpstate enum) always use ftp.c:state() to change - state! */ - unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or - IMAP or POP3 or others! (type: curl_usessl)*/ - unsigned char ccc; /* ccc level for this connection */ - BIT(ftp_trying_alternative); - BIT(dont_check); /* Set to TRUE to prevent the final (post-transfer) - file size and 226/250 status check. It should still - read the line, ignore the result. */ - BIT(ctl_valid); /* Tells Curl_ftp_quit() whether or not to do anything. If - the connection has timed out or been closed, this - should be FALSE when it gets to Curl_ftp_quit() */ - BIT(cwddone); /* if it has been determined that the proper CWD combo - already has been done */ - BIT(cwdfail); /* set TRUE if a CWD command fails, as then we must prevent - caching the current directory */ - BIT(wait_data_conn); /* this is set TRUE if data connection is waited */ - BIT(shutdown); /* connection is being shutdown, e.g. QUIT */ -}; - -/* meta key for storing `struct FTP` as easy meta data */ -#define CURL_META_FTP_EASY "meta:proto:ftp:easy" -/* meta key for storing `struct ftp_conn` as connection meta data */ -#define CURL_META_FTP_CONN "meta:proto:ftp:conn" - -#endif /* CURL_DISABLE_FTP */ - -#endif /* HEADER_CURL_FTP_INT_H */ diff --git a/vendor/curl/lib/ftp.c b/vendor/curl/lib/ftp.c deleted file mode 100644 index 9d3700df5..000000000 --- a/vendor/curl/lib/ftp.c +++ /dev/null @@ -1,4499 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" - -#ifndef CURL_DISABLE_FTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "sendf.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "if2ip.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "ftp.h" -#include "ftp-int.h" -#include "ftplistparser.h" -#include "curl_range.h" -#include "strcase.h" -#include "vtls/vtls.h" -#include "cfilters.h" -#include "cf-socket.h" -#include "connect.h" -#include "curlx/inet_ntop.h" -#include "curlx/inet_pton.h" -#include "select.h" -#include "parsedate.h" /* for the week day and month names */ -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "multiif.h" -#include "url.h" -#include "http_proxy.h" -#include "curlx/strdup.h" -#include "curlx/strerr.h" -#include "curlx/strparse.h" -#include "curl_ctype.h" - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - -/* macro to check for a three-digit ftp status code at the start of the - given string */ -#define STATUSCODE(line) \ - (ISDIGIT((line)[0]) && ISDIGIT((line)[1]) && ISDIGIT((line)[2])) - -/* macro to check for the last line in an FTP server response */ -#define LASTLINE(line) (STATUSCODE(line) && (' ' == (line)[3])) - -#ifdef CURLVERBOSE -/* for tracing purposes */ -static const char * const ftp_state_names[] = { - "STOP", - "WAIT220", - "AUTH", - "USER", - "PASS", - "ACCT", - "PBSZ", - "PROT", - "CCC", - "PWD", - "SYST", - "NAMEFMT", - "QUOTE", - "RETR_PREQUOTE", - "STOR_PREQUOTE", - "LIST_PREQUOTE", - "POSTQUOTE", - "CWD", - "MKD", - "MDTM", - "TYPE", - "LIST_TYPE", - "RETR_LIST_TYPE", - "RETR_TYPE", - "STOR_TYPE", - "SIZE", - "RETR_SIZE", - "STOR_SIZE", - "REST", - "RETR_REST", - "PORT", - "PRET", - "PASV", - "LIST", - "RETR", - "STOR", - "QUIT" -}; -#define FTP_CSTATE(ftpc) ((ftpc) ? ftp_state_names[(ftpc)->state] : "???") - -#endif /* CURLVERBOSE */ - -/* This is the ONLY way to change FTP state! */ -static void ftp_state_low(struct Curl_easy *data, - struct ftp_conn *ftpc, - ftpstate newstate -#ifdef DEBUGBUILD - , int lineno -#endif - ) -{ - if(ftpc->state != newstate) { -#ifdef DEBUGBUILD - NOVERBOSE((void)lineno); - CURL_TRC_FTP(data, "[%s] -> [%s] (line %d)", FTP_CSTATE(ftpc), - ftp_state_names[newstate], lineno); -#else - CURL_TRC_FTP(data, "[%s] -> [%s]", FTP_CSTATE(ftpc), - ftp_state_names[newstate]); -#endif - } - ftpc->state = newstate; -} - -/* Local API functions */ -#ifndef DEBUGBUILD -#define ftp_state(x, y, z) ftp_state_low(x, y, z) -#else /* !DEBUGBUILD */ -#define ftp_state(x, y, z) ftp_state_low(x, y, z, __LINE__) -#endif /* DEBUGBUILD */ - -static CURLcode ftp_state_mdtm(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp); -static CURLcode ftp_state_quote(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool init, ftpstate instate); -static CURLcode ftp_nb_type(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool ascii, ftpstate newstate); -static CURLcode getftpresponse(struct Curl_easy *data, size_t *nreadp, - int *ftpcodep); - -static void freedirs(struct ftp_conn *ftpc) -{ - curlx_safefree(ftpc->dirs); - ftpc->dirdepth = 0; - curlx_safefree(ftpc->rawpath); - ftpc->file = NULL; -} - -static size_t numof_slashes(const char *str) -{ - const char *slashPos; - size_t num = 0; - do { - slashPos = strchr(str, '/'); - if(slashPos) { - ++num; - str = slashPos + 1; - } - } while(slashPos); - return num; -} - -#define FTP_MAX_DIR_DEPTH 1000 - -/*********************************************************************** - * - * ftp_parse_url_path() - * - * Parse the URL path into separate path components. - * - */ -static CURLcode ftp_parse_url_path(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - const char *slashPos = NULL; - const char *fileName = NULL; - CURLcode result = CURLE_OK; - const char *rawPath = NULL; /* URL-decoded "raw" path */ - size_t pathLen = 0; - - ftpc->ctl_valid = FALSE; - ftpc->cwdfail = FALSE; - - if(ftpc->rawpath) - freedirs(ftpc); - /* URL-decode ftp path before further evaluation */ - result = Curl_urldecode(ftp->path, 0, &ftpc->rawpath, &pathLen, REJECT_CTRL); - if(result) { - failf(data, "path contains control characters"); - return result; - } - rawPath = ftpc->rawpath; - - switch(data->set.ftp_filemethod) { - case FTPFILE_NOCWD: /* fastest, but less standard-compliant */ - - if((pathLen > 0) && (rawPath[pathLen - 1] != '/')) - fileName = rawPath; /* this is a full file path */ - /* - else: ftpc->file is not used anywhere other than for operations on - a file. In other words, never for directory operations, - so we can safely leave filename as NULL here and use it as a - argument in dir/file decisions. - */ - break; - - case FTPFILE_SINGLECWD: - slashPos = strrchr(rawPath, '/'); - if(slashPos) { - /* get path before last slash, except for / */ - size_t dirlen = slashPos - rawPath; - if(dirlen == 0) - dirlen = 1; - - ftpc->dirs = curlx_calloc(1, sizeof(ftpc->dirs[0])); - if(!ftpc->dirs) - return CURLE_OUT_OF_MEMORY; - - ftpc->dirs[0].start = 0; - ftpc->dirs[0].len = (int)dirlen; - ftpc->dirdepth = 1; /* we consider it to be a single directory */ - fileName = slashPos + 1; /* rest is filename */ - } - else - fileName = rawPath; /* filename only (or empty) */ - break; - - default: /* allow pretty much anything */ - case FTPFILE_MULTICWD: { - /* current position: begin of next path component */ - const char *curPos = rawPath; - - /* number of entries to allocate for the 'dirs' array */ - size_t dirAlloc = numof_slashes(rawPath); - - if(dirAlloc >= FTP_MAX_DIR_DEPTH) - /* suspiciously deep directory hierarchy */ - return CURLE_URL_MALFORMAT; - - if(dirAlloc) { - ftpc->dirs = curlx_calloc(dirAlloc, sizeof(ftpc->dirs[0])); - if(!ftpc->dirs) - return CURLE_OUT_OF_MEMORY; - - /* parse the URL path into separate path components */ - while(dirAlloc--) { - const char *spos = strchr(curPos, '/'); - size_t clen = spos - curPos; - - /* path starts with a slash: add that as a directory */ - if(!clen && (ftpc->dirdepth == 0)) - ++clen; - - /* we skip empty path components, like "x//y" since the FTP command - CWD requires a parameter and a non-existent parameter a) does not - work on many servers and b) has no effect on the others. */ - if(clen) { - ftpc->dirs[ftpc->dirdepth].start = (int)(curPos - rawPath); - ftpc->dirs[ftpc->dirdepth].len = (int)clen; - ftpc->dirdepth++; - } - curPos = spos + 1; - } - } - fileName = curPos; /* the rest is the filename (or empty) */ - } - break; - } /* switch */ - - if(fileName && *fileName) - ftpc->file = fileName; - else - ftpc->file = NULL; /* instead of point to a zero byte, - we make it a NULL pointer */ - - if(data->state.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) { - /* We need a filename when uploading. Return error! */ - failf(data, "Uploading to a URL without a filename"); - return CURLE_URL_MALFORMAT; - } - - ftpc->cwddone = FALSE; /* default to not done */ - - if((data->set.ftp_filemethod == FTPFILE_NOCWD) && (rawPath[0] == '/')) - ftpc->cwddone = TRUE; /* skip CWD for absolute paths */ - else { /* newly created FTP connections are already in entry path */ - const char *oldPath = data->conn->bits.reuse ? ftpc->prevpath : ""; - if(oldPath) { - size_t n = pathLen; - if(data->set.ftp_filemethod == FTPFILE_NOCWD) - n = 0; /* CWD to entry for relative paths */ - else - n -= ftpc->file ? strlen(ftpc->file) : 0; - - if((strlen(oldPath) == n) && rawPath && !strncmp(rawPath, oldPath, n)) { - infof(data, "Request has same path as previous transfer"); - ftpc->cwddone = TRUE; - } - } - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_need_type() - * - * Returns TRUE if we in the current situation should send TYPE - */ -static int ftp_need_type(struct ftp_conn *ftpc, - bool ascii_wanted) -{ - return ftpc->transfertype != (ascii_wanted ? 'A' : 'I'); -} - -static void close_secondarysocket(struct Curl_easy *data, - struct ftp_conn *ftpc) -{ - (void)ftpc; - CURL_TRC_FTP(data, "[%s] closing DATA connection", FTP_CSTATE(ftpc)); - Curl_conn_close(data, SECONDARYSOCKET); - Curl_conn_cf_discard_all(data, data->conn, SECONDARYSOCKET); -} - -#ifdef CURL_PREFER_LF_LINEENDS -/* - * Lineend Conversions - * On ASCII transfers, e.g. directory listings, we might get lines - * ending in '\r\n' and we prefer '\n'. - * We might also get a lonely '\r' which we convert into a '\n'. - */ -struct ftp_cw_lc_ctx { - struct Curl_cwriter super; - bool newline_pending; -}; - -static CURLcode ftp_cw_lc_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t blen) -{ - static const char nl = '\n'; - struct ftp_cw_lc_ctx *ctx = writer->ctx; - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - - if(!ftpc) - return CURLE_FAILED_INIT; - - if(!(type & CLIENTWRITE_BODY) || ftpc->transfertype != 'A') - return Curl_cwriter_write(data, writer->next, type, buf, blen); - - /* ASCII mode BODY data, convert lineends */ - while(blen) { - /* do not pass EOS when writing parts */ - int chunk_type = (type & ~CLIENTWRITE_EOS); - const char *cp; - size_t chunk_len; - CURLcode result; - - if(ctx->newline_pending) { - if(buf[0] != '\n') { - /* previous chunk ended in '\r' and we do not see a '\n' in this one, - * need to write a newline. */ - result = Curl_cwriter_write(data, writer->next, chunk_type, &nl, 1); - if(result) - return result; - } - /* either we wrote the newline or it is part of the next chunk of bytes - * we write. */ - ctx->newline_pending = FALSE; - } - - cp = memchr(buf, '\r', blen); - if(!cp) - break; - - /* write the bytes before the '\r', excluding the '\r' */ - chunk_len = cp - buf; - if(chunk_len) { - result = Curl_cwriter_write(data, writer->next, chunk_type, - buf, chunk_len); - if(result) - return result; - } - /* skip the '\r', we now have a newline pending */ - buf = cp + 1; - blen = blen - chunk_len - 1; - ctx->newline_pending = TRUE; - } - - /* Any remaining data does not contain a '\r' */ - if(blen) { - DEBUGASSERT(!ctx->newline_pending); - return Curl_cwriter_write(data, writer->next, type, buf, blen); - } - else if(type & CLIENTWRITE_EOS) { - /* EndOfStream, if we have a trailing cr, now is the time to write it */ - if(ctx->newline_pending) { - ctx->newline_pending = FALSE; - return Curl_cwriter_write(data, writer->next, type, &nl, 1); - } - /* Always pass on the EOS type indicator */ - return Curl_cwriter_write(data, writer->next, type, buf, 0); - } - return CURLE_OK; -} - -static const struct Curl_cwtype ftp_cw_lc = { - "ftp-lineconv", - NULL, - Curl_cwriter_def_init, - ftp_cw_lc_write, - Curl_cwriter_def_close, - sizeof(struct ftp_cw_lc_ctx) -}; - -#endif /* CURL_PREFER_LF_LINEENDS */ - -/*********************************************************************** - * - * ftp_check_ctrl_on_data_wait() - * - */ -static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data, - struct ftp_conn *ftpc) -{ - struct connectdata *conn = data->conn; - curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET]; - struct pingpong *pp = &ftpc->pp; - size_t nread; - int ftpcode; - bool response = FALSE; - - /* First check whether there is a cached response from server */ - if(curlx_dyn_len(&pp->recvbuf)) { - const char *l = curlx_dyn_ptr(&pp->recvbuf); - if(!ISDIGIT(*l) || (*l > '3')) { - /* Data connection could not be established, let's return */ - infof(data, "There is negative response in cache while serv connect"); - (void)getftpresponse(data, &nread, &ftpcode); - return CURLE_FTP_ACCEPT_FAILED; - } - } - - if(pp->overflow) - /* there is pending control data still in the buffer to read */ - response = TRUE; - else { - int socketstate = SOCKET_READABLE(ctrl_sock, 0); - /* see if the connection request is already here */ - switch(socketstate) { - case -1: /* error */ - /* let's die here */ - failf(data, "Error while waiting for server connect"); - return CURLE_FTP_ACCEPT_FAILED; - default: - if(socketstate & CURL_CSELECT_IN) - response = TRUE; - break; - } - } - - if(response) { - infof(data, "Ctrl conn has data while waiting for data conn"); - if(pp->overflow > 3) { - const char *r = curlx_dyn_ptr(&pp->recvbuf); - size_t len = curlx_dyn_len(&pp->recvbuf); - - DEBUGASSERT((pp->overflow + pp->nfinal) <= curlx_dyn_len(&pp->recvbuf)); - /* move over the most recently handled response line */ - r += pp->nfinal; - len -= pp->nfinal; - - if((len > 3) && LASTLINE(r)) { - curl_off_t status; - if(!curlx_str_number(&r, &status, 999) && (status == 226)) { - /* funny timing situation where we get the final message on the - control connection before traffic on the data connection has been - noticed. Leave the 226 in there and use this as a trigger to read - the data socket. */ - infof(data, "Got 226 before data activity"); - return CURLE_OK; - } - } - } - - (void)getftpresponse(data, &nread, &ftpcode); - - infof(data, "FTP code: %03d", ftpcode); - - if(ftpcode / 100 > 3) - return CURLE_FTP_ACCEPT_FAILED; - - return CURLE_WEIRD_SERVER_REPLY; - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_initiate_transfer() - * - * After connection from server is accepted this function is called to - * setup transfer parameters and initiate the data transfer. - * - */ -static CURLcode ftp_initiate_transfer(struct Curl_easy *data, - struct ftp_conn *ftpc) -{ - CURLcode result = CURLE_OK; - bool connected; - - CURL_TRC_FTP(data, "ftp_initiate_transfer()"); - result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &connected); - if(result || !connected) - return result; - - if(data->state.upload) { - /* When we know we are uploading a specified file, we can get the file - size prior to the actual upload. */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* FTP upload, shutdown DATA, ignore shutdown errors, as we rely - * on the server response on the CONTROL connection. */ - Curl_xfer_setup_send(data, SECONDARYSOCKET); - Curl_xfer_set_shutdown(data, TRUE, TRUE); - } - else { - /* FTP download, shutdown, do not ignore errors */ - Curl_xfer_setup_recv(data, SECONDARYSOCKET, data->req.size); - Curl_xfer_set_shutdown(data, TRUE, FALSE); - } - - ftpc->pp.pending_resp = TRUE; /* expect server response */ - ftp_state(data, ftpc, FTP_STOP); - - return CURLE_OK; -} - -static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn, - const char *line, size_t len, int *code) -{ - curl_off_t status; - (void)data; - (void)conn; - - if((len > 3) && LASTLINE(line) && !curlx_str_number(&line, &status, 999)) { - *code = (int)status; - return TRUE; - } - - return FALSE; -} - -static CURLcode ftp_readresp(struct Curl_easy *data, - struct ftp_conn *ftpc, - int sockindex, - struct pingpong *pp, - int *ftpcodep, /* return the ftp-code if done */ - size_t *size) /* size of the response */ -{ - int code; - CURLcode result = Curl_pp_readresp(data, sockindex, pp, &code, size); - DEBUGASSERT(ftpcodep); - - /* store the latest code for later retrieval, except during shutdown */ - if(!ftpc->shutdown) - data->info.httpcode = code; - - *ftpcodep = code; - - if(code == 421) { - /* 421 means "Service not available, closing control connection." and FTP - * servers use it to signal that idle session timeout has been exceeded. - * If we ignored the response, it could end up hanging in some cases. - * - * This response code can come at any point so having it treated - * generically is a good idea. - */ - infof(data, "We got a 421 - timeout"); - ftp_state(data, ftpc, FTP_STOP); - return CURLE_OPERATION_TIMEDOUT; - } - - return result; -} - -/* --- parse FTP server responses --- */ - -/* - * getftpresponse() is a BLOCKING function to read the full response from a - * server after a command. - * - */ -static CURLcode getftpresponse(struct Curl_easy *data, - size_t *nreadp, /* return number of bytes - read */ - int *ftpcodep) /* return the ftp-code */ -{ - /* - * We cannot read one byte per read() and then go back to select() as the - * OpenSSL read() does not grok that properly. - * - * Alas, read as much as possible, split up into lines, use the ending - * line in a response or continue reading. */ - - struct connectdata *conn = data->conn; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - struct pingpong *pp = &ftpc->pp; - size_t nread; - int cache_skip = 0; - DEBUGASSERT(ftpcodep); - - CURL_TRC_FTP(data, "getftpresponse start"); - *nreadp = 0; - *ftpcodep = 0; /* 0 for errors */ - - if(!ftpc) - return CURLE_FAILED_INIT; - - while(!*ftpcodep && !result) { - /* check and reset timeout value every lap */ - timediff_t timeout = Curl_pp_state_timeleft_ms(data, pp); - timediff_t interval_ms; - - if(timeout <= 0) { - failf(data, "FTP response timeout"); - return CURLE_OPERATION_TIMEDOUT; /* already too little time */ - } - - interval_ms = 1000; /* use 1 second timeout intervals */ - if(timeout < interval_ms) - interval_ms = timeout; - - /* - * Since this function is blocking, we need to wait here for input on the - * connection and only then we call the response reading function. We do - * timeout at least every second to make the timeout check run. - * - * A caution here is that the ftp_readresp() function has a cache that may - * contain pieces of a response from the previous invoke and we need to - * make sure we do not wait for input while there is unhandled data in - * that cache. Also, if the cache is there, we call ftp_readresp() and - * the cache was not good enough to continue we must not busy-loop around - * this function. - * - */ - - if(curlx_dyn_len(&pp->recvbuf) && (cache_skip < 2)) { - /* - * There is a cache left since before. We then skipping the wait for - * socket action, unless this is the same cache like the previous round - * as then the cache was deemed not enough to act on and we then need to - * wait for more data anyway. - */ - } - else if(!Curl_conn_data_pending(data, FIRSTSOCKET)) { - curl_socket_t wsock = Curl_pp_needs_flush(data, pp) ? - sockfd : CURL_SOCKET_BAD; - int ev = Curl_socket_check(sockfd, CURL_SOCKET_BAD, wsock, interval_ms); - if(ev < 0) { - failf(data, "FTP response aborted due to select/poll error: %d", - SOCKERRNO); - return CURLE_RECV_ERROR; - } - else if(ev == 0) { - result = Curl_pgrsUpdate(data); - continue; /* continue in our loop for the timeout duration */ - } - } - - if(Curl_pp_needs_flush(data, pp)) { - result = Curl_pp_flushsend(data, pp); - if(result) - break; - } - - result = ftp_readresp(data, ftpc, FIRSTSOCKET, pp, ftpcodep, &nread); - if(result) - break; - - if(!nread && curlx_dyn_len(&pp->recvbuf)) - /* bump cache skip counter as on repeated skips we must wait for more - data */ - cache_skip++; - else - /* when we got data or there is no cache left, we reset the cache skip - counter */ - cache_skip = 0; - - *nreadp += nread; - - } /* while there is buffer left and loop is requested */ - - pp->pending_resp = FALSE; - CURL_TRC_FTP(data, "getftpresponse -> result=%d, nread=%zu, ftpcode=%d", - result, *nreadp, *ftpcodep); - - return result; -} - -static CURLcode ftp_state_user(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct connectdata *conn) -{ - CURLcode result = Curl_pp_sendf(data, &ftpc->pp, "USER %s", - conn->user ? conn->user : ""); - if(!result) { - ftpc->ftp_trying_alternative = FALSE; - ftp_state(data, ftpc, FTP_USER); - } - return result; -} - -static CURLcode ftp_state_pwd(struct Curl_easy *data, - struct ftp_conn *ftpc) -{ - CURLcode result; -#ifdef DEBUGBUILD - if(!data->id && getenv("CURL_FTP_PWD_STOP")) - return CURLE_OK; -#endif - result = Curl_pp_sendf(data, &ftpc->pp, "%s", "PWD"); - if(!result) - ftp_state(data, ftpc, FTP_PWD); - - return result; -} - -/* For the FTP "protocol connect" and "doing" phases only */ -static CURLcode ftp_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - return ftpc ? Curl_pp_pollset(data, &ftpc->pp, ps) : CURLE_OK; -} - -/* For the FTP "DO_MORE" phase only */ -static CURLcode ftp_domore_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - - if(!ftpc) - return CURLE_OK; - - /* When in DO_MORE state, we could be either waiting for us to connect to a - * remote site, or we could wait for that site to connect to us. Or handle - * ordinary commands. - */ - CURL_TRC_FTP(data, "[%s] ftp_domore_pollset()", FTP_CSTATE(ftpc)); - - if(FTP_STOP == ftpc->state) { - /* if stopped and still in this state, then we are also waiting for a - connect on the secondary connection */ - DEBUGASSERT(data->conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD || - (data->conn->cfilter[SECONDARYSOCKET] && - !Curl_conn_is_connected(data->conn, SECONDARYSOCKET))); - /* An unconnected SECONDARY will add its socket by itself - * via its adjust_pollset() */ - return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]); - } - return Curl_pp_pollset(data, &ftpc->pp, ps); -} - -static int pathlen(struct ftp_conn *ftpc, int num) -{ - DEBUGASSERT(ftpc->dirs); - DEBUGASSERT(ftpc->dirdepth > num); - return ftpc->dirs[num].len; -} - -static const char *pathpiece(struct ftp_conn *ftpc, int num) -{ - DEBUGASSERT(ftpc->dirs); - DEBUGASSERT(ftpc->dirdepth > num); - return &ftpc->rawpath[ftpc->dirs[num].start]; -} - -/* This is called after the FTP_QUOTE state is passed. - - ftp_state_cwd() sends the range of CWD commands to the server to change to - the correct directory. It may also need to send MKD commands to create - missing ones, if that option is enabled. -*/ -static CURLcode ftp_state_cwd(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - CURLcode result = CURLE_OK; - - if(ftpc->cwddone) - /* already done and fine */ - result = ftp_state_mdtm(data, ftpc, ftp); - else { - /* FTPFILE_NOCWD with full path: expect ftpc->cwddone! */ - DEBUGASSERT((data->set.ftp_filemethod != FTPFILE_NOCWD) || - !(ftpc->dirdepth && ftpc->rawpath[0] == '/')); - - ftpc->count2 = 0; /* count2 counts failed CWDs */ - - if(data->conn->bits.reuse && ftpc->entrypath && - /* no need to go to entrypath when we have an absolute path */ - !(ftpc->dirdepth && ftpc->rawpath[0] == '/')) { - /* This is a reused connection. Since we change directory to where the - transfer is taking place, we must first get back to the original dir - where we ended up after login: */ - ftpc->cwdcount = 0; /* we count this as the first path, then we add one - for all upcoming ones in the ftp->dirs[] array */ - result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", ftpc->entrypath); - if(!result) - ftp_state(data, ftpc, FTP_CWD); - } - else { - if(ftpc->dirdepth) { - ftpc->cwdcount = 1; - /* issue the first CWD, the rest is sent when the CWD responses are - received... */ - result = Curl_pp_sendf(data, &ftpc->pp, "CWD %.*s", - pathlen(ftpc, 0), pathpiece(ftpc, 0)); - if(!result) - ftp_state(data, ftpc, FTP_CWD); - } - else { - /* No CWD necessary */ - result = ftp_state_mdtm(data, ftpc, ftp); - } - } - } - return result; -} - -typedef enum { - EPRT, - PORT, - DONE -} ftpport; - -/* - * Parse the CURLOPT_FTPPORT string - * "(ipv4|ipv6|domain|interface)?(:port(-range)?)?" - * and extract addr/addrlen and port_min/port_max. - */ -static CURLcode ftp_port_parse_string(struct Curl_easy *data, - struct connectdata *conn, - const char *string_ftpport, - struct Curl_sockaddr_storage *ss, - unsigned short *port_minp, - unsigned short *port_maxp, - const char **hostp, - char *hbuf, size_t hbuflen) -{ - const char *ip_end = NULL; - const char *addr = NULL; - size_t addrlen = 0; - unsigned short port_min = 0; - unsigned short port_max = 0; - char ipstr[50]; -#ifndef USE_IPV6 - (void)conn; - (void)ss; -#endif - - /* default to nothing */ - *hostp = NULL; - *port_minp = *port_maxp = 0; - - if(!string_ftpport || (strlen(string_ftpport) <= 1)) - goto done; - -#ifdef USE_IPV6 - if(*string_ftpport == '[') { - /* [ipv6]:port(-range) */ - const char *ip_start = string_ftpport + 1; - ip_end = strchr(ip_start, ']'); - if(ip_end) { - addrlen = ip_end - ip_start; - addr = ip_start; - } - } - else -#endif - if(*string_ftpport == ':') { - /* :port */ - ip_end = string_ftpport; - } - else { - ip_end = strchr(string_ftpport, ':'); - addr = string_ftpport; - if(ip_end) { -#ifdef USE_IPV6 - struct sockaddr_in6 * const sa6 = (void *)ss; -#endif - /* either ipv6 or (ipv4|domain|interface):port(-range) */ - addrlen = ip_end - string_ftpport; -#ifdef USE_IPV6 - if(curlx_inet_pton(AF_INET6, string_ftpport, &sa6->sin6_addr) == 1) { - /* ipv6 */ - addrlen = strlen(string_ftpport); - ip_end = NULL; /* this got no port ! */ - } -#endif - } - else - /* ipv4|interface */ - addrlen = strlen(string_ftpport); - } - - /* parse the port */ - if(ip_end) { - const char *portp = strchr(ip_end, ':'); - if(portp) { - curl_off_t start; - curl_off_t end; - portp++; - if(!curlx_str_number(&portp, &start, 0xffff)) { - port_min = (unsigned short)start; - if(!curlx_str_single(&portp, '-') && - !curlx_str_number(&portp, &end, 0xffff)) - port_max = (unsigned short)end; - else - port_max = port_min; - } - } - } - - /* correct errors like :1234-1230 or :-4711 */ - if(port_min > port_max) - port_min = port_max = 0; - - if(addrlen) { - const struct Curl_sockaddr_ex *remote_addr = - Curl_conn_get_remote_addr(data, FIRSTSOCKET); - - DEBUGASSERT(remote_addr); - DEBUGASSERT(addr); - if(!remote_addr || (addrlen >= sizeof(ipstr)) || (addrlen >= hbuflen)) - return CURLE_FTP_PORT_FAILED; - memcpy(ipstr, addr, addrlen); - ipstr[addrlen] = 0; - - /* attempt to get the address of the given interface name */ - switch(Curl_if2ip(remote_addr->family, -#ifdef USE_IPV6 - Curl_ipv6_scope(&remote_addr->curl_sa_addr), - conn->scope_id, -#endif - ipstr, hbuf, hbuflen)) { - case IF2IP_NOT_FOUND: - /* not an interface, use the string as hostname instead */ - memcpy(hbuf, addr, addrlen); - hbuf[addrlen] = 0; - *hostp = hbuf; - break; - case IF2IP_AF_NOT_SUPPORTED: - return CURLE_FTP_PORT_FAILED; - case IF2IP_FOUND: - *hostp = hbuf; /* use the hbuf for hostname */ - break; - } - } - /* else: only a port(-range) given, leave host as NULL */ - -done: - *port_minp = port_min; - *port_maxp = port_max; - return CURLE_OK; -} - -/* - * If no host was derived from the FTPPORT string, fall back to the IP address - * of the control connection's local socket. - */ -static CURLcode ftp_port_default_host(struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_storage *ss, - curl_socklen_t *sslenp, - const char **hostp, - char *hbuf, size_t hbuflen, - bool *non_localp) -{ - struct sockaddr *sa = (struct sockaddr *)ss; - struct sockaddr_in * const sa4 = (void *)sa; -#ifdef USE_IPV6 - struct sockaddr_in6 * const sa6 = (void *)sa; -#endif - char buffer[STRERROR_LEN]; - const char *r; - - *sslenp = sizeof(*ss); - if(getsockname(conn->sock[FIRSTSOCKET], sa, sslenp)) { - failf(data, "getsockname() failed: %s", - curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_FTP_PORT_FAILED; - } - switch(sa->sa_family) { -#ifdef USE_IPV6 - case AF_INET6: - r = curlx_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, hbuflen); - break; -#endif - default: - r = curlx_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, hbuflen); - break; - } - if(!r) - return CURLE_FTP_PORT_FAILED; - - *hostp = hbuf; - *non_localp = FALSE; /* we know it is local now */ - return CURLE_OK; -} - -/* - * Resolve the host string to a list of addresses. - */ -static CURLcode ftp_port_resolve_host(struct Curl_easy *data, - struct connectdata *conn, - const char *host, - struct Curl_dns_entry **dns_entryp, - const struct Curl_addrinfo **resp) -{ - CURLcode result; - - *resp = NULL; - result = Curl_resolv_blocking( - data, Curl_resolv_dns_queries(data, conn->ip_version), - host, 0, Curl_conn_get_transport(data, conn), dns_entryp); - if(result) - failf(data, "failed to resolve the address provided to PORT: %s", host); - else { - DEBUGASSERT(*dns_entryp); - *resp = (*dns_entryp)->addr; - } - return result; -} - -/* - * Open a TCP socket for the resolved address family. - */ -static CURLcode ftp_port_open_socket(struct Curl_easy *data, - struct connectdata *conn, - const struct Curl_addrinfo *res, - const struct Curl_addrinfo **aip, - curl_socket_t *portsockp) -{ - char buffer[STRERROR_LEN]; - int error = 0; - const struct Curl_addrinfo *ai; - CURLcode result = CURLE_FTP_PORT_FAILED; - - for(ai = res; ai; ai = ai->ai_next) { - result = - Curl_socket_open(data, ai, NULL, - Curl_conn_get_transport(data, conn), portsockp); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - return result; - result = CURLE_FTP_PORT_FAILED; - error = SOCKERRNO; - continue; - } - break; - } - if(!ai) { - failf(data, "socket failure: %s", - curlx_strerror(error, buffer, sizeof(buffer))); - return CURLE_FTP_PORT_FAILED; - } - *aip = ai; - return result; -} - -/* - * Bind the socket to a local address and port within the requested range. - * Falls back to the control-connection address if the user-requested address - * is non-local. - */ -static CURLcode ftp_port_bind_socket(struct Curl_easy *data, - struct connectdata *conn, - curl_socket_t portsock, - const struct Curl_addrinfo *ai, - struct Curl_sockaddr_storage *ss, - curl_socklen_t *sslen_io, - unsigned short port_min, - unsigned short port_max, - bool non_local) -{ - struct sockaddr *sa = (struct sockaddr *)ss; - struct sockaddr_in * const sa4 = (void *)sa; -#ifdef USE_IPV6 - struct sockaddr_in6 * const sa6 = (void *)sa; -#endif - char buffer[STRERROR_LEN]; - unsigned short port; - int error; - - memcpy(sa, ai->ai_addr, ai->ai_addrlen); - *sslen_io = ai->ai_addrlen; - - for(port = port_min; port <= port_max;) { - if(sa->sa_family == AF_INET) - sa4->sin_port = htons(port); -#ifdef USE_IPV6 - else - sa6->sin6_port = htons(port); -#endif - if(bind(portsock, sa, *sslen_io)) { - error = SOCKERRNO; - if(non_local && (error == SOCKEADDRNOTAVAIL)) { - /* The requested bind address is not local. Use the address used for - * the control connection instead and restart the port loop. - */ - infof(data, "bind(port=%hu) on non-local address failed: %s", port, - curlx_strerror(error, buffer, sizeof(buffer))); - - *sslen_io = sizeof(*ss); - if(getsockname(conn->sock[FIRSTSOCKET], sa, sslen_io)) { - failf(data, "getsockname() failed: %s", - curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_FTP_PORT_FAILED; - } - port = port_min; - non_local = FALSE; /* do not try this again */ - continue; - } - if(error != SOCKEADDRINUSE && error != SOCKEACCES) { - failf(data, "bind(port=%hu) failed: %s", port, - curlx_strerror(error, buffer, sizeof(buffer))); - return CURLE_FTP_PORT_FAILED; - } - } - else - break; - - /* check if port is the maximum value here, because it might be 0xffff - and then the increment below will wrap the 16-bit counter */ - if(port == port_max) { - failf(data, "bind() failed, ran out of ports"); - return CURLE_FTP_PORT_FAILED; - } - port++; - } - - /* re-read the name so we can extract the actual port chosen */ - *sslen_io = sizeof(*ss); - if(getsockname(portsock, sa, sslen_io)) { - failf(data, "getsockname() failed: %s", - curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_FTP_PORT_FAILED; - } - CURL_TRC_FTP(data, "ftp_port_bind_socket(), socket bound to port %d", - port); - return CURLE_OK; -} - -/* - * Start listening on the data socket. - */ -static CURLcode ftp_port_listen(struct Curl_easy *data, curl_socket_t portsock) -{ - char buffer[STRERROR_LEN]; - - if(listen(portsock, 1)) { - failf(data, "socket failure: %s", - curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_FTP_PORT_FAILED; - } - CURL_TRC_FTP(data, "ftp_port_listen(), listening on port"); - return CURLE_OK; -} - -/* - * Send the EPRT or PORT command to the server. - */ -static CURLcode ftp_port_send_command(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct connectdata *conn, - struct Curl_sockaddr_storage *ss, - const struct Curl_addrinfo *ai, - ftpport fcmd) -{ - static const char mode[][5] = { "EPRT", "PORT" }; - struct sockaddr *sa = (struct sockaddr *)ss; - struct sockaddr_in * const sa4 = (void *)sa; -#ifdef USE_IPV6 - struct sockaddr_in6 * const sa6 = (void *)sa; -#endif - char myhost[MAX_IPADR_LEN + 1] = ""; - unsigned short port; - CURLcode result; - - /* Get a plain printable version of the numerical address to work with. This - logic uses the address provided by the FTPPORT option, which at times - might differ from the address in 'ss' used to bind to: when a user asks - the server to connect to a specific address knowing that it works, but - curl instead selects to listen to the local address because it cannot use - the provided address. FTP is strange. */ - Curl_printable_address(ai, myhost, sizeof(myhost)); - -#ifdef USE_IPV6 - if(!conn->bits.ftp_use_eprt && conn->bits.ipv6) - /* EPRT is disabled but we are connected to an IPv6 host, so we ignore the - request and enable EPRT again! */ - conn->bits.ftp_use_eprt = TRUE; -#endif - - for(; fcmd != DONE; fcmd++) { - - if(!conn->bits.ftp_use_eprt && (EPRT == fcmd)) - /* if disabled, goto next */ - continue; - - if((PORT == fcmd) && sa->sa_family != AF_INET) - /* PORT is IPv4 only */ - continue; - - switch(sa->sa_family) { - case AF_INET: - port = ntohs(sa4->sin_port); - break; -#ifdef USE_IPV6 - case AF_INET6: - port = ntohs(sa6->sin6_port); - break; -#endif - default: - continue; /* might as well skip this */ - } - - if(EPRT == fcmd) { - /* - * Two fine examples from RFC2428; - * - * EPRT |1|132.235.1.2|6275| - * - * EPRT |2|1080::8:800:200C:417A|5282| - */ - result = Curl_pp_sendf(data, &ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd], - sa->sa_family == AF_INET ? 1 : 2, - myhost, port); - if(result) { - failf(data, "Failure sending EPRT command: %s", - curl_easy_strerror(result)); - return result; - } - break; - } - if(PORT == fcmd) { - /* large enough for [IP address],[num],[num] */ - char target[sizeof(myhost) + 20]; - const char *source = myhost; - char *dest = target; - - /* translate x.x.x.x to x,x,x,x */ - while(*source) { - if(*source == '.') - *dest = ','; - else - *dest = *source; - dest++; - source++; - } - *dest = 0; - curl_msnprintf(dest, 20, ",%d,%d", (int)(port >> 8), (int)(port & 0xff)); - - result = Curl_pp_sendf(data, &ftpc->pp, "%s %s", mode[fcmd], target); - if(result) { - failf(data, "Failure sending PORT command: %s", - curl_easy_strerror(result)); - return result; - } - break; - } - } - - /* store which command was sent */ - ftpc->count1 = fcmd; - ftp_state(data, ftpc, FTP_PORT); - return CURLE_OK; -} - -/* - * ftp_state_use_port() - * - * Set up an active-mode FTP data connection (using PORT or EPRT) and start - * listening for the server's incoming connection on SECONDARYSOCKET. - */ -static CURLcode ftp_state_use_port(struct Curl_easy *data, - struct ftp_conn *ftpc, - ftpport fcmd) /* start with this */ -{ - CURLcode result = CURLE_FTP_PORT_FAILED; - struct connectdata *conn = data->conn; - curl_socket_t portsock = CURL_SOCKET_BAD; - - struct Curl_sockaddr_storage ss; - curl_socklen_t sslen; - char hbuf[NI_MAXHOST]; - const char *host = NULL; - const char *string_ftpport = data->set.str[STRING_FTPPORT]; - struct Curl_dns_entry *dns_entry = NULL; - const struct Curl_addrinfo *res = NULL; - const struct Curl_addrinfo *ai = NULL; - unsigned short port_min = 0; - unsigned short port_max = 0; - bool non_local = TRUE; - - /* parse the FTPPORT string for address and port range */ - result = ftp_port_parse_string(data, conn, string_ftpport, - &ss, &port_min, &port_max, - &host, hbuf, sizeof(hbuf)); - if(!result && !host) - /* if no host was specified, use the control connection's local IP */ - result = ftp_port_default_host(data, conn, &ss, &sslen, &host, - hbuf, sizeof(hbuf), &non_local); - - /* resolve host string to address list */ - if(!result) - result = ftp_port_resolve_host(data, conn, host, &dns_entry, &res); - - /* Open a TCP socket for the data connection */ - if(!result) - result = ftp_port_open_socket(data, conn, res, &ai, &portsock); - if(!result) { - CURL_TRC_FTP(data, "[%s] ftp_state_use_port(), opened socket", - FTP_CSTATE(ftpc)); - - /* bind to a suitable local address / port */ - result = ftp_port_bind_socket(data, conn, portsock, ai, &ss, &sslen, - port_min, port_max, non_local); - } - - /* listen */ - if(!result) - result = ftp_port_listen(data, portsock); - - /* send the PORT / EPRT command */ - if(!result) - result = ftp_port_send_command(data, ftpc, conn, &ss, ai, fcmd); - - /* replace any filter on SECONDARY with one listening on this socket */ - if(!result) - result = Curl_conn_tcp_listen_set(data, conn, SECONDARYSOCKET, &portsock); - - if(!result) - portsock = CURL_SOCKET_BAD; /* now held in filter */ - - /* cleanup */ - - if(dns_entry) - Curl_dns_entry_unlink(data, &dns_entry); - if(result) { - ftp_state(data, ftpc, FTP_STOP); - } - else { - /* successfully set up the listen socket filter. SSL needed? */ - if(conn->bits.ftp_use_data_ssl && data->set.ftp_use_port && - !Curl_conn_is_ssl(conn, SECONDARYSOCKET)) { - result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET); - } - conn->bits.do_more = FALSE; - Curl_pgrsTime(data, TIMER_STARTACCEPT); - Curl_expire(data, (data->set.accepttimeout > 0) ? - data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, - EXPIRE_FTP_ACCEPT); - } - if(portsock != CURL_SOCKET_BAD) - Curl_socket_close(data, conn, portsock); - return result; -} - -static CURLcode ftp_state_use_pasv(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - /* - Here's the executive summary on what to do: - - PASV is RFC959, expect: - 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2) - - LPSV is RFC1639, expect: - 228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2) - - EPSV is RFC2428, expect: - 229 Entering Extended Passive Mode (|||port|) - - */ - - static const char mode[][5] = { "EPSV", "PASV" }; - int modeoff; - -#ifdef PF_INET6 - if(!conn->bits.ftp_use_epsv && conn->bits.ipv6) - /* EPSV is disabled but we are connected to an IPv6 host, so we ignore the - request and enable EPSV again! */ - conn->bits.ftp_use_epsv = TRUE; -#endif - - modeoff = conn->bits.ftp_use_epsv ? 0 : 1; - - result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]); - if(!result) { - ftpc->count1 = modeoff; - ftp_state(data, ftpc, FTP_PASV); - infof(data, "Connect data stream passively"); - } - return result; -} - -/* - * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc. - * - * REST is the last command in the chain of commands when a "head"-like - * request is made. Thus, if an actual transfer is to be made this is where we - * take off for real. - */ -static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - - if(ftp->transfer != PPTRANSFER_BODY) { - /* does not transfer any data */ - - /* still possibly do PRE QUOTE jobs */ - ftp_state(data, ftpc, FTP_RETR_PREQUOTE); - result = ftp_state_quote(data, ftpc, ftp, TRUE, FTP_RETR_PREQUOTE); - } - else if(data->set.ftp_use_port) { - /* We have chosen to use the PORT (or similar) command */ - result = ftp_state_use_port(data, ftpc, EPRT); - } - else { - /* We have chosen (this is default) to use the PASV (or similar) command */ - if(data->set.ftp_use_pret) { - /* The user has requested that we send a PRET command - to prepare the server for the upcoming PASV */ - if(!ftpc->file) - result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s", - data->set.str[STRING_CUSTOMREQUEST] ? - data->set.str[STRING_CUSTOMREQUEST] : - (data->state.list_only ? "NLST" : "LIST")); - else if(data->state.upload) - result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s", ftpc->file); - else - result = Curl_pp_sendf(data, &ftpc->pp, "PRET RETR %s", ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_PRET); - } - else - result = ftp_state_use_pasv(data, ftpc, conn); - } - return result; -} - -static CURLcode ftp_state_rest(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - CURLcode result = CURLE_OK; - - if((ftp->transfer != PPTRANSFER_BODY) && ftpc->file) { - /* if a "head"-like request is being made (on a file) */ - - /* Determine if server can respond to REST command and therefore - whether it supports range */ - result = Curl_pp_sendf(data, &ftpc->pp, "REST %d", 0); - if(!result) - ftp_state(data, ftpc, FTP_REST); - } - else - result = ftp_state_prepare_transfer(data, ftpc, ftp); - - return result; -} - -static CURLcode ftp_state_size(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - CURLcode result = CURLE_OK; - - if((ftp->transfer == PPTRANSFER_INFO) && ftpc->file) { - /* if a "head"-like request is being made (on a file) */ - - /* we know ftpc->file is a valid pointer to a filename */ - result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_SIZE); - } - else - result = ftp_state_rest(data, ftpc, ftp); - - return result; -} - -static CURLcode ftp_state_list(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - CURLcode result = CURLE_OK; - - /* If this output is to be machine-parsed, the NLST command might be better - to use, since the LIST command output is not specified or standard in any - way. It has turned out that the NLST list output is not the same on all - servers either... */ - - /* - if FTPFILE_NOCWD was specified, we should add the path - as argument for the LIST / NLST / or custom command. - Whether the server will support this, is uncertain. - - The other ftp_filemethods will CWD into dir/dir/ first and - then do LIST (in that case: nothing to do here) - */ - const char *lstArg = NULL; - int lstArglen = 0; - char *cmd; - - if((data->set.ftp_filemethod == FTPFILE_NOCWD) && ftp->path) { - /* URL-decode before evaluation: e.g. paths starting/ending with %2f */ - const char *rawPath = ftpc->rawpath; - const char *slashPos = strrchr(rawPath, '/'); - if(slashPos) { - /* chop off the file part if format is dir/file otherwise remove - the trailing slash for dir/dir/ except for absolute path / */ - size_t n = slashPos - rawPath; - if(n == 0) - ++n; - - lstArg = rawPath; - lstArglen = (int)n; - } - } - - cmd = curl_maprintf("%s%s%.*s", - data->set.str[STRING_CUSTOMREQUEST] ? - data->set.str[STRING_CUSTOMREQUEST] : - (data->state.list_only ? "NLST" : "LIST"), - lstArg ? " " : "", - lstArglen, lstArg ? lstArg : ""); - - if(!cmd) - return CURLE_OUT_OF_MEMORY; - - result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd); - curlx_free(cmd); - - if(!result) - ftp_state(data, ftpc, FTP_LIST); - - return result; -} - -static CURLcode ftp_state_list_prequote(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - /* We have sent the TYPE, now we must send the list of prequote strings */ - return ftp_state_quote(data, ftpc, ftp, TRUE, FTP_LIST_PREQUOTE); -} - -static CURLcode ftp_state_retr_prequote(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - /* We have sent the TYPE, now we must send the list of prequote strings */ - return ftp_state_quote(data, ftpc, ftp, TRUE, FTP_RETR_PREQUOTE); -} - -static CURLcode ftp_state_stor_prequote(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - /* We have sent the TYPE, now we must send the list of prequote strings */ - return ftp_state_quote(data, ftpc, ftp, TRUE, FTP_STOR_PREQUOTE); -} - -static CURLcode ftp_state_type(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - CURLcode result = CURLE_OK; - - /* If we have selected NOBODY and HEADER, it means that we only want file - information. Which in FTP cannot be much more than the file size and - date. */ - if(data->req.no_body && ftpc->file && - ftp_need_type(ftpc, (bool)data->state.prefer_ascii)) { - /* The SIZE command is _not_ RFC 959 specified, and therefore many servers - may not support it! It is however the only way we have to get a file's - size! */ - - ftp->transfer = PPTRANSFER_INFO; - /* this means no actual transfer will be made */ - - /* Some servers return different sizes for different modes, and thus we - must set the proper type before we check the size */ - result = ftp_nb_type(data, ftpc, ftp, (bool)data->state.prefer_ascii, - FTP_TYPE); - if(result) - return result; - } - else - result = ftp_state_size(data, ftpc, ftp); - - return result; -} - -/* This is called after the CWD commands have been done in the beginning of - the DO phase */ -static CURLcode ftp_state_mdtm(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - CURLcode result = CURLE_OK; - - /* Requested time of file or time-depended transfer? */ - if((data->set.get_filetime || data->set.timecondition) && ftpc->file) { - - /* we have requested to get the modified-time of the file, this is a white - spot as the MDTM is not mentioned in RFC959 */ - result = Curl_pp_sendf(data, &ftpc->pp, "MDTM %s", ftpc->file); - - if(!result) - ftp_state(data, ftpc, FTP_MDTM); - } - else - result = ftp_state_type(data, ftpc, ftp); - - return result; -} - -/* This is called after the TYPE and possible quote commands have been sent */ -static CURLcode ftp_state_ul_setup(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool sizechecked) -{ - CURLcode result = CURLE_OK; - curl_bit append = data->set.remote_append; - - if((data->state.resume_from && !sizechecked) || - ((data->state.resume_from > 0) && sizechecked)) { - /* we are about to continue the uploading of a file - 1. get already existing file's size. We use the SIZE command for this - which may not exist in the server! The SIZE command is not in - RFC959. - - 2. This used to set REST, but since we can do append, we issue no - another ftp command. Skip the source file offset and APPEND the rest - on the file instead - - 3. pass file-size number of bytes in the source file - 4. lower the infilesize counter */ - /* => transfer as usual */ - int seekerr = CURL_SEEKFUNC_OK; - - if(data->state.resume_from < 0) { - /* Got no given size to start from, figure it out */ - result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_STOR_SIZE); - return result; - } - - /* enable append */ - append = TRUE; - - /* Let's read off the proper amount of bytes from the input. */ - if(data->set.seek_func) { - Curl_set_in_callback(data, TRUE); - seekerr = data->set.seek_func(data->set.seek_client, - data->state.resume_from, SEEK_SET); - Curl_set_in_callback(data, FALSE); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - curl_off_t passed = 0; - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_FTP_COULDNT_USE_REST; - } - /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */ - do { - char scratch[4 * 1024]; - size_t readthisamountnow = - (data->state.resume_from - passed > (curl_off_t)sizeof(scratch)) ? - sizeof(scratch) : - curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread = - data->state.fread_func(scratch, 1, readthisamountnow, - data->state.in); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Failed to read data"); - return CURLE_FTP_COULDNT_USE_REST; - } - } while(passed < data->state.resume_from); - } - /* now, decrease the size of the read */ - if(data->state.infilesize > 0) { - data->state.infilesize -= data->state.resume_from; - - if(data->state.infilesize <= 0) { - infof(data, "File already completely uploaded"); - - /* no data to transfer */ - Curl_xfer_setup_nop(data); - - /* Set ->transfer so that we will not get any error in - * ftp_done() because we did not transfer anything! */ - ftp->transfer = PPTRANSFER_NONE; - - ftp_state(data, ftpc, FTP_STOP); - return CURLE_OK; - } - } - /* we have passed, proceed as normal */ - } /* resume_from */ - - result = Curl_pp_sendf(data, &ftpc->pp, append ? "APPE %s" : "STOR %s", - ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_STOR); - - return result; -} - -static CURLcode ftp_state_retr(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - curl_off_t filesize) -{ - CURLcode result = CURLE_OK; - - CURL_TRC_FTP(data, "[%s] ftp_state_retr()", FTP_CSTATE(ftpc)); - if(data->set.max_filesize && (filesize > data->set.max_filesize)) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - ftp->downloadsize = filesize; - - if(data->state.resume_from) { - /* We always (attempt to) get the size of downloads, so it is done before - this even when not doing resumes. */ - if(filesize == -1) { - infof(data, "ftp server does not support SIZE"); - /* We could not get the size and therefore we cannot know if there - really is a part of the file left to get, although the server will - close the connection when we start the connection so it will not - cause us any harm, not make us exit as nicely. */ - } - else { - /* We got a file size report, so we check that there actually is a - part of the file left to get, or else we go home. */ - if(data->state.resume_from < 0) { - /* We are supposed to download the last abs(from) bytes */ - if(filesize < -data->state.resume_from) { - failf(data, "Offset (%" FMT_OFF_T - ") was beyond file size (%" FMT_OFF_T ")", - data->state.resume_from, filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* convert to size to download */ - ftp->downloadsize = -data->state.resume_from; - /* download from where? */ - data->state.resume_from = filesize - ftp->downloadsize; - } - else { - if(filesize < data->state.resume_from) { - failf(data, "Offset (%" FMT_OFF_T - ") was beyond file size (%" FMT_OFF_T ")", - data->state.resume_from, filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* Now store the number of bytes we are expected to download */ - ftp->downloadsize = filesize - data->state.resume_from; - } - } - - if(ftp->downloadsize == 0) { - /* no data to transfer */ - Curl_xfer_setup_nop(data); - infof(data, "File already completely downloaded"); - - /* Set ->transfer so that we will not get any error in ftp_done() - * because we did not transfer the any file */ - ftp->transfer = PPTRANSFER_NONE; - ftp_state(data, ftpc, FTP_STOP); - return CURLE_OK; - } - - /* Set resume file transfer offset */ - infof(data, "Instructs server to resume from offset %" FMT_OFF_T, - data->state.resume_from); - - result = Curl_pp_sendf(data, &ftpc->pp, "REST %" FMT_OFF_T, - data->state.resume_from); - if(!result) - ftp_state(data, ftpc, FTP_RETR_REST); - } - else { - /* no resume */ - result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_RETR); - } - - return result; -} - -static CURLcode ftp_state_quote(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool init, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - bool quote = FALSE; - struct curl_slist *item; - - switch(instate) { - case FTP_QUOTE: - default: - item = data->set.quote; - break; - case FTP_RETR_PREQUOTE: - case FTP_STOR_PREQUOTE: - case FTP_LIST_PREQUOTE: - item = data->set.prequote; - break; - case FTP_POSTQUOTE: - item = data->set.postquote; - break; - } - - /* - * This state uses: - * 'count1' to iterate over the commands to send - * 'count2' to store whether to allow commands to fail - */ - - if(init) - ftpc->count1 = 0; - else - ftpc->count1++; - - if(item) { - int i = 0; - - /* Skip count1 items in the linked list */ - while((i < ftpc->count1) && item) { - item = item->next; - i++; - } - if(item) { - const char *cmd = item->data; - if(cmd[0] == '*') { - cmd++; - ftpc->count2 = 1; /* the sent command is allowed to fail */ - } - else - ftpc->count2 = 0; /* failure means cancel operation */ - - result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd); - if(result) - return result; - ftp_state(data, ftpc, instate); - quote = TRUE; - } - } - - if(!quote) { - /* No more quote to send, continue to ... */ - switch(instate) { - case FTP_QUOTE: - default: - result = ftp_state_cwd(data, ftpc, ftp); - break; - case FTP_RETR_PREQUOTE: - if(ftp->transfer != PPTRANSFER_BODY) - ftp_state(data, ftpc, FTP_STOP); - else { - if(ftpc->known_filesize != -1) { - Curl_pgrsSetDownloadSize(data, ftpc->known_filesize); - result = ftp_state_retr(data, ftpc, ftp, ftpc->known_filesize); - } - else { - if(data->set.ignorecl || data->state.prefer_ascii) { - /* 'ignorecl' is used to support download of growing files. It - prevents the state machine from requesting the file size from - the server. With an unknown file size the download continues - until the server terminates it, otherwise the client stops if - the received byte count exceeds the reported file size. Set - option CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this - behavior. - - In addition: asking for the size for 'TYPE A' transfers is not - constructive since servers do not report the converted size. - Thus, skip it. - */ - result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_RETR); - } - else { - result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_RETR_SIZE); - } - } - } - break; - case FTP_STOR_PREQUOTE: - result = ftp_state_ul_setup(data, ftpc, ftp, FALSE); - break; - case FTP_POSTQUOTE: - break; - case FTP_LIST_PREQUOTE: - ftp_state(data, ftpc, FTP_LIST_TYPE); - result = ftp_state_list(data, ftpc, ftp); - break; - } - } - - return result; -} - -/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV - problems */ -static CURLcode ftp_epsv_disable(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - if(conn->bits.ipv6 -#ifndef CURL_DISABLE_PROXY - && !(conn->bits.tunnel_proxy || conn->bits.socksproxy) -#endif - ) { - /* We cannot disable EPSV when doing IPv6, so this is instead a fail */ - failf(data, "Failed EPSV attempt, exiting"); - return CURLE_WEIRD_SERVER_REPLY; - } - - infof(data, "Failed EPSV attempt. Disabling EPSV"); - /* disable it for next transfer */ - conn->bits.ftp_use_epsv = FALSE; - close_secondarysocket(data, ftpc); - data->state.errorbuf = FALSE; /* allow error message to get - rewritten */ - result = Curl_pp_sendf(data, &ftpc->pp, "%s", "PASV"); - if(!result) { - ftpc->count1++; - /* remain in/go to the FTP_PASV state */ - ftp_state(data, ftpc, FTP_PASV); - } - return result; -} - -static CURLcode ftp_control_addr_dup(struct Curl_easy *data, char **newhostp) -{ - struct connectdata *conn = data->conn; - struct ip_quadruple ipquad; - bool is_ipv6; - - /* Returns the control connection IP address. - If a proxy tunnel is used, returns the original hostname instead, because - the effective control connection address is the proxy address, - not the ftp host. */ -#ifndef CURL_DISABLE_PROXY - if(conn->bits.tunnel_proxy || conn->bits.socksproxy) - *newhostp = curlx_strdup(conn->host.name); - else -#endif - if(!Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad) && - *ipquad.remote_ip) - *newhostp = curlx_strdup(ipquad.remote_ip); - else { - /* failed to get the remote_ip of the DATA connection */ - failf(data, "unable to get peername of DATA connection"); - *newhostp = NULL; - return CURLE_FTP_CANT_GET_HOST; - } - return *newhostp ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} - -static bool match_pasv_6nums(const char *p, - unsigned int *array) /* 6 numbers */ -{ - int i; - for(i = 0; i < 6; i++) { - curl_off_t num; - if(i) { - if(*p != ',') - return FALSE; - p++; - } - if(curlx_str_number(&p, &num, 0xff)) - return FALSE; - array[i] = (unsigned int)num; - } - return TRUE; -} - -static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - int ftpcode) -{ - struct connectdata *conn = data->conn; - CURLcode result; - struct Curl_dns_entry *dns = NULL; - unsigned short connectport; /* the local port connect() should use! */ - const struct pingpong *pp = &ftpc->pp; - char *newhost = NULL; - unsigned short newport = 0; - const char *str = curlx_dyn_ptr(&pp->recvbuf) + 4; /* start on the first - letter */ - if((ftpc->count1 == 0) && - (ftpcode == 229)) { - /* positive EPSV response */ - const char *ptr = strchr(str, '('); - if(ptr) { - char sep; - ptr++; - /* |||12345| */ - sep = ptr[0]; - if((ptr[1] == sep) && (ptr[2] == sep) && ISDIGIT(ptr[3])) { - const char *p = &ptr[3]; - curl_off_t num; - if(curlx_str_number(&p, &num, 0xffff) || (*p != sep)) { - failf(data, "Illegal port number in EPSV reply"); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - newport = (unsigned short)num; - result = ftp_control_addr_dup(data, &newhost); - if(result) - return result; - } - else - ptr = NULL; - } - if(!ptr) { - failf(data, "Weirdly formatted EPSV reply"); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - } - else if((ftpc->count1 == 1) && - (ftpcode == 227)) { - /* positive PASV response */ - unsigned int ip[6]; - - /* - * Scan for a sequence of six comma-separated numbers and use them as - * IP+port indicators. - * - * Found reply-strings include: - * "227 Entering Passive Mode (127,0,0,1,4,51)" - * "227 Data transfer will passively listen to 127,0,0,1,4,51" - * "227 Entering passive mode. 127,0,0,1,4,51" - */ - while(*str) { - if(match_pasv_6nums(str, ip)) - break; - str++; - } - - if(!*str) { - failf(data, "Could not interpret the 227-response"); - return CURLE_FTP_WEIRD_227_FORMAT; - } - - /* we got OK from server */ - if(data->set.ftp_skip_ip) { - /* told to ignore the remotely given IP but instead use the host we used - for the control connection */ - infof(data, "Skip %u.%u.%u.%u for data connection, reuse %s instead", - ip[0], ip[1], ip[2], ip[3], conn->host.name); - result = ftp_control_addr_dup(data, &newhost); - if(result) - return result; - } - else - newhost = curl_maprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); - - if(!newhost) - return CURLE_OUT_OF_MEMORY; - - newport = (unsigned short)(((ip[4] << 8) + ip[5]) & 0xffff); - } - else if(ftpc->count1 == 0) { - /* EPSV failed, move on to PASV */ - return ftp_epsv_disable(data, ftpc, conn); - } - else { - failf(data, "Bad PASV/EPSV response: %03d", ftpcode); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - -#ifndef CURL_DISABLE_PROXY - if(conn->bits.proxy) { - /* This connection uses a proxy and we need to connect to the proxy again - * here. We do not want to rely on a former host lookup that might have - * expired now, instead we remake the lookup here and now! */ - struct ip_quadruple ipquad; - bool is_ipv6; - const char * const host_name = conn->bits.socksproxy ? - conn->socks_proxy.host.name : conn->http_proxy.host.name; - - result = Curl_conn_get_ip_info(data, data->conn, FIRSTSOCKET, - &is_ipv6, &ipquad); - if(result) - goto error; - - (void)Curl_resolv_blocking( - data, is_ipv6 ? CURL_DNSQ_AAAA : CURL_DNSQ_A, - host_name, ipquad.remote_port, Curl_conn_get_transport(data, conn), - &dns); - /* we connect to the proxy's port */ - connectport = (unsigned short)ipquad.remote_port; - - if(!dns) { - failf(data, "cannot resolve proxy host %s:%hu", host_name, connectport); - result = CURLE_COULDNT_RESOLVE_PROXY; - goto error; - } - } - else -#endif - { - /* normal, direct, ftp connection */ - DEBUGASSERT(newhost); - - /* postponed address resolution in case of tcp fastopen */ - if(conn->bits.tcp_fastopen && !conn->bits.reuse && !newhost[0]) { - curlx_free(newhost); - result = ftp_control_addr_dup(data, &newhost); - if(result) - goto error; - } - - (void)Curl_resolv_blocking( - data, Curl_resolv_dns_queries(data, conn->ip_version), - newhost, newport, Curl_conn_get_transport(data, conn), &dns); - connectport = newport; /* we connect to the remote port */ - - if(!dns) { - failf(data, "cannot resolve new host %s:%hu", newhost, connectport); - result = CURLE_FTP_CANT_GET_HOST; - goto error; - } - } - - DEBUGASSERT(newhost); - curlx_free(conn->secondaryhostname); - conn->secondary_port = newport; - conn->secondaryhostname = newhost; - newhost = NULL; - - result = Curl_conn_setup(data, conn, SECONDARYSOCKET, dns, - conn->bits.ftp_use_data_ssl ? - CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE); - - if(result) { - if((result != CURLE_OUT_OF_MEMORY) && - (ftpc->count1 == 0) && (ftpcode == 229)) { - result = ftp_epsv_disable(data, ftpc, conn); - } - goto error; - } - - /* - * When this is used from the multi interface, this might have returned with - * the 'connected' set to FALSE and thus we are now awaiting a non-blocking - * connect to connect. - */ - -#ifdef CURLVERBOSE - if(data->set.verbose) { - /* Dump information about this second connection when we have issued a PASV - * command before and thus we have connected to a possibly new IP address. - */ - char buf[256]; - Curl_printable_address(dns->addr, buf, sizeof(buf)); - infof(data, "Connecting to %s (%s) port %d", - conn->secondaryhostname, buf, connectport); - } -#endif - - conn->bits.do_more = TRUE; - ftp_state(data, ftpc, FTP_STOP); /* this phase is completed */ - -error: - Curl_dns_entry_unlink(data, &dns); - curlx_free(newhost); - return result; -} - -/* called repeatedly until done from multi.c */ -static CURLcode ftp_statemach(struct Curl_easy *data, - struct ftp_conn *ftpc, - bool *done) -{ - CURLcode result = Curl_pp_statemach(data, &ftpc->pp, FALSE, FALSE); - - /* Check for the state outside of the Curl_socket_check() return code checks - since at times we are in fact already in this state when this function - gets called. */ - *done = (ftpc->state == FTP_STOP); - - return result; -} - -/* - * ftp_do_more() - * - * This function shall be called when the second FTP (data) connection is - * connected. - * - * 'complete' can return 0 for incomplete, 1 for done and -1 for go back - * (which is for when PASV is being sent to retry a failed EPSV). - */ -static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) -{ - struct connectdata *conn = data->conn; - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - struct FTP *ftp = Curl_meta_get(data, CURL_META_FTP_EASY); - CURLcode result = CURLE_OK; - bool connected = FALSE; - bool complete = FALSE; - /* the ftp struct is inited in ftp_connect(). If we are connecting to an HTTP - * proxy then the state will not be valid until after that connection is - * complete */ - - if(!ftpc || !ftp) - return CURLE_FAILED_INIT; - - *completep = 0; /* default to stay in the state */ - - /* if the second connection has been set up, try to connect it fully - * to the remote host. This may not complete at this time, for several - * reasons: - * - we do EPTR and the server will not connect to our listen socket - * until we send more FTP commands - * - an SSL filter is in place and the server will not start the TLS - * handshake until we send more FTP commands - */ - if(conn->cfilter[SECONDARYSOCKET]) { - bool is_eptr = Curl_conn_is_tcp_listen(data, SECONDARYSOCKET); - result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected); - if(result == CURLE_OUT_OF_MEMORY) - return result; - if(result || (!connected && !is_eptr && - !Curl_conn_is_ip_connected(data, SECONDARYSOCKET))) { - if(result && !is_eptr && (ftpc->count1 == 0)) { - *completep = -1; /* go back to DOING please */ - /* this is a EPSV connect failing, try PASV instead */ - return ftp_epsv_disable(data, ftpc, conn); - } - return result; - } - } - - if(ftpc->state) { - /* already in a state so skip the initial commands. - They are only done to kickstart the do_more state */ - result = ftp_statemach(data, ftpc, &complete); - - *completep = (int)complete; - - /* if we got an error or if we do not wait for a data connection return - immediately */ - if(result || !ftpc->wait_data_conn) - return result; - - /* if we reach the end of the FTP state machine here, *complete will be - TRUE but so is ftpc->wait_data_conn, which says we need to wait for the - data connection and therefore we are not actually complete */ - *completep = 0; - } - - if(ftp->transfer <= PPTRANSFER_INFO) { - /* a transfer is about to take place, or if not a filename was given so we - will do a SIZE on it later and then we need the right TYPE first */ - - if(ftpc->wait_data_conn) { - bool serv_conned; - - result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &serv_conned); - if(result) - return result; /* Failed to accept data connection */ - - if(serv_conned) { - /* It looks data connection is established */ - ftpc->wait_data_conn = FALSE; - result = ftp_initiate_transfer(data, ftpc); - - if(result) - return result; - - *completep = 1; /* this state is now complete when the server has - connected back to us */ - } - else { - result = ftp_check_ctrl_on_data_wait(data, ftpc); - if(result) - return result; - } - } - else if(data->state.upload) { - result = ftp_nb_type(data, ftpc, ftp, (bool)data->state.prefer_ascii, - FTP_STOR_TYPE); - if(result) - return result; - - result = ftp_statemach(data, ftpc, &complete); - /* ftp_nb_type() might have skipped sending `TYPE A|I` when not - * deemed necessary and directly sent `STORE name`. If this was - * then complete, but we are still waiting on the data connection, - * the transfer has not been initiated yet. */ - *completep = (int)(ftpc->wait_data_conn ? 0 : complete); - } - else { - /* download */ - ftp->downloadsize = -1; /* unknown as of yet */ - - result = Curl_range(data); - - if(result == CURLE_OK && data->req.maxdownload >= 0) { - /* Do not check for successful transfer */ - ftpc->dont_check = TRUE; - } - - if(result) - ; - else if((data->state.list_only || !ftpc->file) && - !(data->set.prequote)) { - /* The specified path ends with a slash, and therefore we think this - is a directory that is requested, use LIST. Before that, we also - need to set ASCII transfer mode. */ - - /* Only if a body transfer was requested. */ - if(ftp->transfer == PPTRANSFER_BODY) { - result = ftp_nb_type(data, ftpc, ftp, TRUE, FTP_LIST_TYPE); - if(result) - return result; - } - /* otherwise fall through */ - } - else { - if(data->set.prequote && !ftpc->file) { - result = ftp_nb_type(data, ftpc, ftp, TRUE, - FTP_RETR_LIST_TYPE); - } - else { - result = ftp_nb_type(data, ftpc, ftp, (bool)data->state.prefer_ascii, - FTP_RETR_TYPE); - } - if(result) - return result; - } - - result = ftp_statemach(data, ftpc, &complete); - *completep = (int)complete; - } - return result; - } - - /* no data to transfer */ - Curl_xfer_setup_nop(data); - - if(!ftpc->wait_data_conn) { - /* no waiting for the data connection so this is now complete */ - *completep = 1; - CURL_TRC_FTP(data, "[%s] DO-MORE phase ends with %d", FTP_CSTATE(ftpc), - (int)result); - } - - return result; -} - -/* call this when the DO phase has completed */ -static CURLcode ftp_dophase_done(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool connected) -{ - if(connected) { - int completed; - CURLcode result = ftp_do_more(data, &completed); - - if(result) { - close_secondarysocket(data, ftpc); - return result; - } - } - - if(ftp->transfer != PPTRANSFER_BODY) - /* no data to transfer */ - Curl_xfer_setup_nop(data); - else if(!connected) - /* since we did not connect now, we want do_more to get called */ - data->conn->bits.do_more = TRUE; - - ftpc->ctl_valid = TRUE; /* seems good */ - - return CURLE_OK; -} - -static CURLcode ftp_state_port_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - int ftpcode) -{ - struct connectdata *conn = data->conn; - ftpport fcmd = (ftpport)ftpc->count1; - CURLcode result = CURLE_OK; - - /* The FTP spec tells a positive response should have code 200. - Be more permissive here to tolerate deviant servers. */ - if(ftpcode / 100 != 2) { - /* the command failed */ - - if(EPRT == fcmd) { - infof(data, "disabling EPRT usage"); - conn->bits.ftp_use_eprt = FALSE; - } - fcmd++; - - if(fcmd == DONE) { - failf(data, "Failed to do PORT"); - result = CURLE_FTP_PORT_FAILED; - } - else - /* try next */ - result = ftp_state_use_port(data, ftpc, fcmd); - } - else { - infof(data, "Connect data stream actively"); - ftp_state(data, ftpc, FTP_STOP); /* end of DO phase */ - result = ftp_dophase_done(data, ftpc, ftp, FALSE); - } - - return result; -} - -/* return TRUE on error, FALSE on success */ -static bool twodigit(const char *p, int *val) -{ - if(!ISDIGIT(p[0]) || !ISDIGIT(p[1])) - return TRUE; - /* curlx_hexval() works fine here since we make sure it is decimal above */ - *val = (curlx_hexval(p[0]) * 10) + curlx_hexval(p[1]); - return FALSE; -} - -/* - * @unittest 1668 - */ -UNITTEST bool ftp_213_date(const char *p, int *year, int *month, int *day, - int *hour, int *minute, int *second); -UNITTEST bool ftp_213_date(const char *p, int *year, int *month, int *day, - int *hour, int *minute, int *second) -{ - int century; - if((strlen(p) < 14) || twodigit(&p[0], ¢ury) || twodigit(&p[2], year) || - twodigit(&p[4], month) || twodigit(&p[6], day) || - twodigit(&p[8], hour) || twodigit(&p[10], minute) || - twodigit(&p[12], second)) - return FALSE; - - *year += century * 100; - if((*month > 12) || (*day > 31) || (*hour > 23) || (*minute > 59) || - (*second > 60)) - return FALSE; - return TRUE; -} - -static CURLcode client_write_header(struct Curl_easy *data, - char *buf, size_t blen) -{ - /* Some replies from an FTP server are written to the client - * as CLIENTWRITE_HEADER, formatted as if they came from a - * HTTP conversation. - * In all protocols, CLIENTWRITE_HEADER data is only passed to - * the body write callback when data->set.include_header is set - * via CURLOPT_HEADER. - * For historic reasons, FTP never played this game and expects - * all its headers to do that always. Set that flag during the - * call to Curl_client_write() so it does the right thing. - * - * Notice that we cannot enable this flag for FTP in general, - * as an FTP transfer might involve an HTTP proxy connection and - * headers from CONNECT should not automatically be part of the - * output. */ - CURLcode result; - bool save = (bool)data->set.include_header; - data->set.include_header = TRUE; - result = Curl_client_write(data, CLIENTWRITE_HEADER, buf, blen); - data->set.include_header = save; - return result; -} - -static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - int ftpcode) -{ - CURLcode result = CURLE_OK; - - switch(ftpcode) { - case 213: { - /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the - last .sss part is optional and means fractions of a second */ - int year, month, day, hour, minute, second; - struct pingpong *pp = &ftpc->pp; - const char *resp = curlx_dyn_ptr(&pp->recvbuf) + 4; - bool showtime = FALSE; - if(ftp_213_date(resp, &year, &month, &day, &hour, &minute, &second)) { - /* we have a time, reformat it */ - char timebuf[24]; - curl_msnprintf(timebuf, sizeof(timebuf), - "%04d%02d%02d %02d:%02d:%02d GMT", - year, month, day, hour, minute, second); - /* now, convert this into a time() value: */ - if(!Curl_getdate_capped(timebuf, &data->info.filetime)) - showtime = TRUE; - } - - /* If we asked for a time of the file and we actually got one as well, - we "emulate" an HTTP-style header in our output. */ - -#if defined(CURL_HAVE_DIAG) && (defined(__DJGPP__) || defined(__AMIGA__)) -#pragma GCC diagnostic push -/* 'time_t' is unsigned in MSDOS and AmigaOS. Silence: - warning: comparison of unsigned expression in '>= 0' is always true */ -#pragma GCC diagnostic ignored "-Wtype-limits" -#endif - if(data->req.no_body && ftpc->file && - data->set.get_filetime && showtime) { -#if defined(CURL_HAVE_DIAG) && (defined(__DJGPP__) || defined(__AMIGA__)) -#pragma GCC diagnostic pop -#endif - char headerbuf[128]; - int headerbuflen; - time_t filetime = data->info.filetime; - struct tm buffer; - const struct tm *tm = &buffer; - - result = curlx_gmtime(filetime, &buffer); - if(result) - return result; - - /* format: "Tue, 15 Nov 1994 12:45:26" */ - headerbuflen = - curl_msnprintf(headerbuf, sizeof(headerbuf), - "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d " - "GMT\r\n", - Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - result = client_write_header(data, headerbuf, headerbuflen); - if(result) - return result; - } /* end of a ridiculous amount of conditionals */ - } - break; - default: - infof(data, "unsupported MDTM reply format"); - break; - case 550: /* 550 is used for several different problems, e.g. - "No such file or directory" or "Permission denied". - It does not mean that the file does not exist at all. */ - infof(data, "MDTM failed: file does not exist or permission problem," - " continuing"); - break; - } - - if(data->set.timecondition) { - if((data->info.filetime > 0) && (data->set.timevalue > 0)) { - switch(data->set.timecondition) { - case CURL_TIMECOND_IFMODSINCE: - default: - if(data->info.filetime <= data->set.timevalue) { - infof(data, "The requested document is not new enough"); - ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */ - data->info.timecond = TRUE; - ftp_state(data, ftpc, FTP_STOP); - return CURLE_OK; - } - break; - case CURL_TIMECOND_IFUNMODSINCE: - if(data->info.filetime > data->set.timevalue) { - infof(data, "The requested document is not old enough"); - ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */ - data->info.timecond = TRUE; - ftp_state(data, ftpc, FTP_STOP); - return CURLE_OK; - } - break; - } /* switch */ - } - else { - infof(data, "Skipping time comparison"); - } - } - - if(!result) - result = ftp_state_type(data, ftpc, ftp); - - return result; -} - -static CURLcode ftp_state_type_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - - if(ftpcode / 100 != 2) { - /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a - successful 'TYPE I'. While that is not as RFC959 says, it is still a - positive response code and we allow that. */ - failf(data, "Could not set desired mode"); - return CURLE_FTP_COULDNT_SET_TYPE; - } - if(ftpcode != 200) - infof(data, "Got a %03d response code instead of the assumed 200", - ftpcode); - - if(instate == FTP_TYPE) - result = ftp_state_size(data, ftpc, ftp); - else if(instate == FTP_LIST_TYPE) - result = ftp_state_list(data, ftpc, ftp); - else if(instate == FTP_RETR_TYPE) - result = ftp_state_retr_prequote(data, ftpc, ftp); - else if(instate == FTP_STOR_TYPE) - result = ftp_state_stor_prequote(data, ftpc, ftp); - else if(instate == FTP_RETR_LIST_TYPE) - result = ftp_state_list_prequote(data, ftpc, ftp); - - return result; -} - -static CURLcode ftp_state_size_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - curl_off_t filesize = -1; - const char *buf = curlx_dyn_ptr(&ftpc->pp.recvbuf); - size_t len = ftpc->pp.nfinal; - - /* get the size from the ascii string: */ - if(ftpcode == 213) { - /* To allow servers to prepend "rubbish" in the response string, we scan - for all the digits at the end of the response and parse only those as a - number. */ - const char *start = &buf[4]; - const char *fdigit = memchr(start, '\r', len - 4); - if(fdigit) { - fdigit--; - if(*fdigit == '\n') - fdigit--; - while(ISDIGIT(fdigit[-1]) && (fdigit > start)) - fdigit--; - } - else - fdigit = start; - if(curlx_str_number(&fdigit, &filesize, CURL_OFF_T_MAX)) - filesize = -1; /* size remain unknown */ - } - else if(ftpcode == 550) { /* "No such file or directory" */ - /* allow a SIZE failure for (resumed) uploads, when probing what command - to use */ - if(instate != FTP_STOR_SIZE) { - failf(data, "The file does not exist"); - return CURLE_REMOTE_FILE_NOT_FOUND; - } - } - - if(instate == FTP_SIZE) { - if(filesize != -1) { - char clbuf[128]; - int clbuflen = curl_msnprintf(clbuf, sizeof(clbuf), - "Content-Length: %" FMT_OFF_T "\r\n", - filesize); - result = client_write_header(data, clbuf, clbuflen); - if(result) - return result; - } - Curl_pgrsSetDownloadSize(data, filesize); - result = ftp_state_rest(data, ftpc, ftp); - } - else if(instate == FTP_RETR_SIZE) { - Curl_pgrsSetDownloadSize(data, filesize); - result = ftp_state_retr(data, ftpc, ftp, filesize); - } - else if(instate == FTP_STOR_SIZE) { - data->state.resume_from = filesize; - result = ftp_state_ul_setup(data, ftpc, ftp, TRUE); - } - - return result; -} - -static CURLcode ftp_state_rest_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - - switch(instate) { - case FTP_REST: - default: - if(ftpcode == 350) { - char buffer[24] = { "Accept-ranges: bytes\r\n" }; - result = client_write_header(data, buffer, strlen(buffer)); - if(result) - return result; - } - result = ftp_state_prepare_transfer(data, ftpc, ftp); - break; - - case FTP_RETR_REST: - if(ftpcode != 350) { - failf(data, "Could not use REST"); - result = CURLE_FTP_COULDNT_USE_REST; - } - else { - result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file); - if(!result) - ftp_state(data, ftpc, FTP_RETR); - } - break; - } - - return result; -} - -static CURLcode ftp_state_stor_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - int ftpcode) -{ - CURLcode result = CURLE_OK; - - if(ftpcode >= 400) { - failf(data, "Failed FTP upload: %0d", ftpcode); - ftp_state(data, ftpc, FTP_STOP); - return CURLE_UPLOAD_FAILED; - } - - /* PORT means we are now awaiting the server to connect to us. */ - if(data->set.ftp_use_port) { - bool connected; - - ftp_state(data, ftpc, FTP_STOP); /* no longer in STOR state */ - - result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected); - if(result) - return result; - - if(!connected) { - infof(data, "Data conn was not available immediately"); - ftpc->wait_data_conn = TRUE; - return ftp_check_ctrl_on_data_wait(data, ftpc); - } - ftpc->wait_data_conn = FALSE; - } - return ftp_initiate_transfer(data, ftpc); -} - -/* for LIST and RETR responses */ -static CURLcode ftp_state_get_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - - if((ftpcode == 150) || (ftpcode == 125)) { - - /* - A; - 150 Opening BINARY mode data connection for /etc/passwd (2241 - bytes). (ok, the file is being transferred) - - B: - 150 Opening ASCII mode data connection for /bin/ls - - C: - 150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes). - - D: - 150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes) - - E: - 125 Data connection already open; Transfer starting. */ - - data->req.size = -1; /* default unknown size */ - - /* - * It appears that there are FTP-servers that return size 0 for files when - * SIZE is used on the file while being in BINARY mode. To work around - * that (stupid) behavior, we attempt to parse the RETR response even if - * the SIZE returned size zero. - * - * Debugging help from Salvatore Sorrentino on February 26, 2003. - */ - - if((instate != FTP_LIST) && - !data->state.prefer_ascii && - !data->set.ignorecl && - (ftp->downloadsize < 1)) { - /* - * It seems directory listings either do not show the size or often uses - * size 0 anyway. ASCII transfers may cause that the transferred amount - * of data is not the same as this line tells, why using this number in - * those cases only confuses us. - * - * Example D above makes this parsing a little tricky */ - size_t len = curlx_dyn_len(&ftpc->pp.recvbuf); - if(len >= 7) { /* "1 bytes" is 7 characters */ - size_t i; - for(i = 0; i < len - 7; i++) { - curl_off_t what; - const char *buf = curlx_dyn_ptr(&ftpc->pp.recvbuf); - const char *c = &buf[i]; - if(!curlx_str_number(&c, &what, CURL_OFF_T_MAX) && - !curlx_str_single(&c, ' ') && - !strncmp(c, "bytes", 5)) { - data->req.size = what; - break; - } - } - } - } - else if(ftp->downloadsize > -1) - data->req.size = ftp->downloadsize; - - if(data->req.size > data->req.maxdownload && data->req.maxdownload > 0) - data->req.size = data->req.maxdownload; - else if((instate != FTP_LIST) && (data->state.prefer_ascii)) - data->req.size = -1; /* for servers that understate ASCII mode file - size */ - - infof(data, "Maxdownload = %" FMT_OFF_T, data->req.maxdownload); - - if(instate != FTP_LIST) - infof(data, "Getting file with size: %" FMT_OFF_T, data->req.size); - - if(data->set.ftp_use_port) { - bool connected; - - result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected); - if(result) - return result; - - if(!connected) { - infof(data, "Data conn was not available immediately"); - ftp_state(data, ftpc, FTP_STOP); - ftpc->wait_data_conn = TRUE; - return ftp_check_ctrl_on_data_wait(data, ftpc); - } - ftpc->wait_data_conn = FALSE; - } - return ftp_initiate_transfer(data, ftpc); - } - else { - if((instate == FTP_LIST) && (ftpcode == 450)) { - /* no matching files in the directory listing */ - ftp->transfer = PPTRANSFER_NONE; /* do not download anything */ - ftp_state(data, ftpc, FTP_STOP); /* this phase is over */ - } - else { - failf(data, "RETR response: %03d", ftpcode); - return instate == FTP_RETR && ftpcode == 550 ? - CURLE_REMOTE_FILE_NOT_FOUND : - CURLE_FTP_COULDNT_RETR_FILE; - } - } - - return result; -} - -/* after USER, PASS and ACCT */ -static CURLcode ftp_state_loggedin(struct Curl_easy *data, - struct ftp_conn *ftpc) -{ - CURLcode result = CURLE_OK; - - if(data->conn->bits.ftp_use_control_ssl) { - /* PBSZ = PROTECTION BUFFER SIZE. - - The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says: - - Specifically, the PROT command MUST be preceded by a PBSZ - command and a PBSZ command MUST be preceded by a successful - security data exchange (the TLS negotiation in this case) - - ... (and on page 8): - - Thus the PBSZ command must still be issued, but must have a - parameter of '0' to indicate that no buffering is taking place - and the data connection should not be encapsulated. - */ - result = Curl_pp_sendf(data, &ftpc->pp, "PBSZ %d", 0); - if(!result) - ftp_state(data, ftpc, FTP_PBSZ); - } - else { - result = ftp_state_pwd(data, ftpc); - } - return result; -} - -/* for USER and PASS responses */ -static CURLcode ftp_state_user_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - int ftpcode) -{ - CURLcode result = CURLE_OK; - - /* some need password anyway, and others return 2xx ignored */ - if((ftpcode == 331) && (ftpc->state == FTP_USER)) { - /* 331 Password required for ... - (the server requires to send the user's password too) */ - result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s", data->conn->passwd); - if(!result) - ftp_state(data, ftpc, FTP_PASS); - } - else if(ftpcode / 100 == 2) { - /* 230 User ... logged in. - (the user logged in with or without password) */ - result = ftp_state_loggedin(data, ftpc); - } - else if(ftpcode == 332) { - if(data->set.str[STRING_FTP_ACCOUNT]) { - result = Curl_pp_sendf(data, &ftpc->pp, "ACCT %s", - data->set.str[STRING_FTP_ACCOUNT]); - if(!result) - ftp_state(data, ftpc, FTP_ACCT); - } - else { - failf(data, "ACCT requested but none available"); - result = CURLE_LOGIN_DENIED; - } - } - else { - /* All other response codes, like: - - 530 User ... access denied - (the server denies to log the specified user) */ - - if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] && - !ftpc->ftp_trying_alternative) { - /* Ok, USER failed. Let's try the supplied command. */ - result = Curl_pp_sendf(data, &ftpc->pp, "%s", - data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); - if(!result) { - ftpc->ftp_trying_alternative = TRUE; - ftp_state(data, ftpc, FTP_USER); - } - } - else { - failf(data, "Access denied: %03d", ftpcode); - result = CURLE_LOGIN_DENIED; - } - } - return result; -} - -/* for ACCT response */ -static CURLcode ftp_state_acct_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - int ftpcode) -{ - CURLcode result = CURLE_OK; - if(ftpcode != 230) { - failf(data, "ACCT rejected by server: %03d", ftpcode); - result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */ - } - else - result = ftp_state_loggedin(data, ftpc); - - return result; -} - -static CURLcode ftp_pwd_resp(struct Curl_easy *data, - struct ftp_conn *ftpc, - int ftpcode) -{ - struct pingpong *pp = &ftpc->pp; - CURLcode result; - - if(ftpcode == 257) { - const char *ptr = curlx_dyn_ptr(&pp->recvbuf) + 4; /* start on the first - letter */ - bool entry_extracted = FALSE; - struct dynbuf out; - curlx_dyn_init(&out, 1000); - - /* Reply format is like - 257[rubbish]"" and the - RFC959 says - - The directory name can contain any character; embedded - double-quotes should be escaped by double-quotes (the - "quote-doubling" convention). - */ - - /* scan for the first double-quote for non-standard responses */ - while(*ptr != '\n' && *ptr != '\0' && *ptr != '"') - ptr++; - - if('\"' == *ptr) { - /* it started good */ - for(ptr++; *ptr; ptr++) { - if('\"' == *ptr) { - if('\"' == ptr[1]) { - /* "quote-doubling" */ - result = curlx_dyn_addn(&out, &ptr[1], 1); - ptr++; - } - else { - /* end of path */ - if(curlx_dyn_len(&out)) - entry_extracted = TRUE; - break; /* get out of this loop */ - } - } - else { - if(ISCNTRL(*ptr)) { - /* control characters have no business in a path */ - curlx_dyn_free(&out); - return CURLE_WEIRD_SERVER_REPLY; - } - result = curlx_dyn_addn(&out, ptr, 1); - } - if(result) { - curlx_dyn_free(&out); - return result; - } - } - } - if(entry_extracted) { - /* If the path name does not look like an absolute path (i.e.: it - does not start with a '/'), we probably need some server-dependent - adjustments. For example, this is the case when connecting to - an OS400 FTP server: this server supports two name syntaxes, - the default one being incompatible with standard paths. In - addition, this server switches automatically to the regular path - syntax when one is encountered in a command: this results in - having an entrypath in the wrong syntax when later used in CWD. - The method used here is to check the server OS: we do it only - if the path name looks strange to minimize overhead on other - systems. */ - char *dir = curlx_dyn_ptr(&out); - - if(!ftpc->server_os && dir[0] != '/') { - result = Curl_pp_sendf(data, &ftpc->pp, "%s", "SYST"); - if(result) { - curlx_dyn_free(&out); - return result; - } - } - - curlx_free(ftpc->entrypath); - ftpc->entrypath = dir; /* remember this */ - infof(data, "Entry path is '%s'", ftpc->entrypath); - /* also save it where getinfo can access it: */ - curlx_free(data->state.most_recent_ftp_entrypath); - data->state.most_recent_ftp_entrypath = curlx_strdup(ftpc->entrypath); - if(!data->state.most_recent_ftp_entrypath) - return CURLE_OUT_OF_MEMORY; - - if(!ftpc->server_os && dir[0] != '/') { - ftp_state(data, ftpc, FTP_SYST); - return CURLE_OK; - } - } - else { - /* could not get the path */ - curlx_dyn_free(&out); - infof(data, "Failed to figure out path"); - } - } - ftp_state(data, ftpc, FTP_STOP); /* we are done with CONNECT phase! */ - CURL_TRC_FTP(data, "[%s] protocol connect phase DONE", FTP_CSTATE(ftpc)); - return CURLE_OK; -} - -static const char * const ftpauth[] = { "SSL", "TLS" }; - -static CURLcode ftp_wait_resp(struct Curl_easy *data, - struct connectdata *conn, - struct ftp_conn *ftpc, - int ftpcode) -{ - CURLcode result = CURLE_OK; - if(ftpcode == 230) { - /* 230 User logged in - already! Take as 220 if TLS required. */ - if(data->set.use_ssl <= CURLUSESSL_TRY || - conn->bits.ftp_use_control_ssl) - return ftp_state_user_resp(data, ftpc, ftpcode); - } - else if(ftpcode != 220) { - failf(data, "Got a %03d ftp-server response when 220 was expected", - ftpcode); - return CURLE_WEIRD_SERVER_REPLY; - } - - if(data->set.use_ssl && !conn->bits.ftp_use_control_ssl) { - /* We do not have an SSL/TLS control connection yet, but FTPS is - requested. Try an FTPS connection now */ - - ftpc->count3 = 0; - switch((long)data->set.ftpsslauth) { - case CURLFTPAUTH_DEFAULT: - case CURLFTPAUTH_SSL: - ftpc->count2 = 1; /* add one to get next */ - ftpc->count1 = 0; - break; - case CURLFTPAUTH_TLS: - ftpc->count2 = -1; /* subtract one to get next */ - ftpc->count1 = 1; - break; - default: - failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d", - (int)data->set.ftpsslauth); - return CURLE_UNKNOWN_OPTION; /* we do not know what to do */ - } - result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); - if(!result) - ftp_state(data, ftpc, FTP_AUTH); - } - else - result = ftp_state_user(data, ftpc, conn); - return result; -} - -static CURLcode ftp_pp_statemachine(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result; - int ftpcode; - struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); - struct FTP *ftp = Curl_meta_get(data, CURL_META_FTP_EASY); - struct pingpong *pp; - size_t nread = 0; - - if(!ftpc || !ftp) - return CURLE_FAILED_INIT; - pp = &ftpc->pp; - if(pp->sendleft) - return Curl_pp_flushsend(data, pp); - - result = ftp_readresp(data, ftpc, FIRSTSOCKET, pp, &ftpcode, &nread); - if(result || !ftpcode) - return result; - - /* we have now received a full FTP server response */ - switch(ftpc->state) { - case FTP_WAIT220: - result = ftp_wait_resp(data, conn, ftpc, ftpcode); - break; - - case FTP_AUTH: - /* we have gotten the response to a previous AUTH command */ - - if(pp->overflow) - return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */ - - /* RFC2228 (page 5) says: - * - * If the server is willing to accept the named security mechanism, - * and does not require any security data, it must respond with - * reply code 234/334. - */ - - if((ftpcode == 234) || (ftpcode == 334)) { - /* this was BLOCKING, keep it so for now */ - bool done; - if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); - if(result) { - /* we failed and bail out */ - return CURLE_USE_SSL_FAILED; - } - } - result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, &done); - if(!result) { - conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */ - conn->bits.ftp_use_control_ssl = TRUE; /* SSL on control */ - result = ftp_state_user(data, ftpc, conn); - } - } - else if(ftpc->count3 < 1) { - ftpc->count3++; - ftpc->count1 += ftpc->count2; /* get next attempt */ - result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s", - ftpauth[ftpc->count1]); - /* remain in this same state */ - } - else { - if(data->set.use_ssl > CURLUSESSL_TRY) - /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */ - result = CURLE_USE_SSL_FAILED; - else - /* ignore the failure and continue */ - result = ftp_state_user(data, ftpc, conn); - } - break; - - case FTP_USER: - case FTP_PASS: - result = ftp_state_user_resp(data, ftpc, ftpcode); - break; - - case FTP_ACCT: - result = ftp_state_acct_resp(data, ftpc, ftpcode); - break; - - case FTP_PBSZ: - result = - Curl_pp_sendf(data, &ftpc->pp, "PROT %c", - data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); - if(!result) - ftp_state(data, ftpc, FTP_PROT); - break; - - case FTP_PROT: - if(ftpcode / 100 == 2) - /* We have enabled SSL for the data connection! */ - conn->bits.ftp_use_data_ssl = (data->set.use_ssl != CURLUSESSL_CONTROL); - /* FTP servers typically responds with 500 if they decide to reject - our 'P' request */ - else if(data->set.use_ssl > CURLUSESSL_CONTROL) - /* we failed and bails out */ - return CURLE_USE_SSL_FAILED; - - if(data->set.ftp_ccc) { - /* CCC - Clear Command Channel - */ - result = Curl_pp_sendf(data, &ftpc->pp, "%s", "CCC"); - if(!result) - ftp_state(data, ftpc, FTP_CCC); - } - else - result = ftp_state_pwd(data, ftpc); - break; - - case FTP_CCC: - if(ftpcode < 500) { - /* First shut down the SSL layer (note: this call will block) */ - /* This has only been tested on the proftpd server, and the mod_tls - * code sends a close notify alert without waiting for a close notify - * alert in response. Thus we wait for a close notify alert from the - * server, but we do not send one. Let's hope other servers do - * the same... */ - result = Curl_ssl_cfilter_remove(data, FIRSTSOCKET, - (data->set.ftp_ccc == - (unsigned char)CURLFTPSSL_CCC_ACTIVE)); - if(result) - failf(data, "Failed to clear the command channel (CCC)"); - } - if(!result) - /* Then continue as normal */ - result = ftp_state_pwd(data, ftpc); - break; - - case FTP_PWD: - result = ftp_pwd_resp(data, ftpc, ftpcode); - break; - - case FTP_SYST: - if(ftpcode == 215) { - const char *ptr = curlx_dyn_ptr(&pp->recvbuf) + 4; /* start on the first - letter */ - const char *start; - char *os; - - /* Reply format is like - 215 - */ - while(*ptr == ' ') - ptr++; - for(start = ptr; *ptr && *ptr != ' '; ptr++) - ; - os = curlx_memdup0(start, ptr - start); - if(!os) - return CURLE_OUT_OF_MEMORY; - - /* Check for special servers here. */ - if(curl_strequal(os, "OS/400")) { - /* Force OS400 name format 1. */ - result = Curl_pp_sendf(data, &ftpc->pp, "%s", "SITE NAMEFMT 1"); - if(result) { - curlx_free(os); - return result; - } - /* remember target server OS */ - curlx_free(ftpc->server_os); - ftpc->server_os = os; - ftp_state(data, ftpc, FTP_NAMEFMT); - break; - } - /* Nothing special for the target server. */ - /* remember target server OS */ - curlx_free(ftpc->server_os); - ftpc->server_os = os; - } - else { - /* Cannot identify server OS. Continue anyway and cross fingers. */ - } - - ftp_state(data, ftpc, FTP_STOP); /* we are done with CONNECT phase! */ - CURL_TRC_FTP(data, "[%s] protocol connect phase DONE", FTP_CSTATE(ftpc)); - break; - - case FTP_NAMEFMT: - if(ftpcode == 250) { - /* Name format change successful: reload initial path. */ - ftp_state_pwd(data, ftpc); - break; - } - - ftp_state(data, ftpc, FTP_STOP); /* we are done with CONNECT phase! */ - CURL_TRC_FTP(data, "[%s] protocol connect phase DONE", FTP_CSTATE(ftpc)); - break; - - case FTP_QUOTE: - case FTP_POSTQUOTE: - case FTP_RETR_PREQUOTE: - case FTP_STOR_PREQUOTE: - case FTP_LIST_PREQUOTE: - if((ftpcode >= 400) && !ftpc->count2) { - /* failure response code, and not allowed to fail */ - failf(data, "QUOT command failed with %03d", ftpcode); - result = CURLE_QUOTE_ERROR; - } - else - result = ftp_state_quote(data, ftpc, ftp, FALSE, ftpc->state); - break; - - case FTP_CWD: - if(ftpcode / 100 != 2) { - /* failure to CWD there */ - if(data->set.ftp_create_missing_dirs && - ftpc->cwdcount && !ftpc->count2) { - /* try making it */ - ftpc->count2++; /* counter to prevent CWD-MKD loops */ - - /* count3 is set to allow MKD to fail once per dir. In the case when - CWD fails and then MKD fails (due to another session raced it to - create the dir) this then allows for a second try to CWD to it. */ - ftpc->count3 = (data->set.ftp_create_missing_dirs == 2) ? 1 : 0; - - result = Curl_pp_sendf(data, &ftpc->pp, "MKD %.*s", - pathlen(ftpc, ftpc->cwdcount - 1), - pathpiece(ftpc, ftpc->cwdcount - 1)); - if(!result) - ftp_state(data, ftpc, FTP_MKD); - } - else { - /* return failure */ - failf(data, "Server denied you to change to the given directory"); - ftpc->cwdfail = TRUE; /* do not remember this path as we failed - to enter it */ - result = CURLE_REMOTE_ACCESS_DENIED; - } - } - else { - /* success */ - ftpc->count2 = 0; - if(ftpc->cwdcount >= ftpc->dirdepth) - result = ftp_state_mdtm(data, ftpc, ftp); - else { - ftpc->cwdcount++; - /* send next CWD */ - result = Curl_pp_sendf(data, &ftpc->pp, "CWD %.*s", - pathlen(ftpc, ftpc->cwdcount - 1), - pathpiece(ftpc, ftpc->cwdcount - 1)); - } - } - break; - - case FTP_MKD: - if((ftpcode / 100 != 2) && !ftpc->count3--) { - /* failure to MKD the directory */ - failf(data, "Failed to MKD dir: %03d", ftpcode); - result = CURLE_REMOTE_ACCESS_DENIED; - } - else { - ftp_state(data, ftpc, FTP_CWD); - /* send CWD */ - result = Curl_pp_sendf(data, &ftpc->pp, "CWD %.*s", - pathlen(ftpc, ftpc->cwdcount - 1), - pathpiece(ftpc, ftpc->cwdcount - 1)); - } - break; - - case FTP_MDTM: - result = ftp_state_mdtm_resp(data, ftpc, ftp, ftpcode); - break; - - case FTP_TYPE: - case FTP_LIST_TYPE: - case FTP_RETR_TYPE: - case FTP_STOR_TYPE: - case FTP_RETR_LIST_TYPE: - result = ftp_state_type_resp(data, ftpc, ftp, ftpcode, ftpc->state); - break; - - case FTP_SIZE: - case FTP_RETR_SIZE: - case FTP_STOR_SIZE: - result = ftp_state_size_resp(data, ftpc, ftp, ftpcode, ftpc->state); - break; - - case FTP_REST: - case FTP_RETR_REST: - result = ftp_state_rest_resp(data, ftpc, ftp, ftpcode, ftpc->state); - break; - - case FTP_PRET: - if(ftpcode != 200) { - /* there only is this one standard OK return code. */ - failf(data, "PRET command not accepted: %03d", ftpcode); - return CURLE_FTP_PRET_FAILED; - } - result = ftp_state_use_pasv(data, ftpc, conn); - break; - - case FTP_PASV: - result = ftp_state_pasv_resp(data, ftpc, ftpcode); - break; - - case FTP_PORT: - result = ftp_state_port_resp(data, ftpc, ftp, ftpcode); - break; - - case FTP_LIST: - case FTP_RETR: - result = ftp_state_get_resp(data, ftpc, ftp, ftpcode, ftpc->state); - break; - - case FTP_STOR: - result = ftp_state_stor_resp(data, ftpc, ftpcode); - break; - - case FTP_QUIT: - default: - /* internal error */ - ftp_state(data, ftpc, FTP_STOP); - break; - } - - return result; -} - -/* called repeatedly until done from multi.c */ -static CURLcode ftp_multi_statemach(struct Curl_easy *data, - bool *done) -{ - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - return ftpc ? ftp_statemach(data, ftpc, done) : CURLE_FAILED_INIT; -} - -static CURLcode ftp_block_statemach(struct Curl_easy *data, - struct ftp_conn *ftpc) -{ - struct pingpong *pp = &ftpc->pp; - CURLcode result = CURLE_OK; - - while(ftpc->state != FTP_STOP) { - if(ftpc->shutdown) - CURL_TRC_FTP(data, "in shutdown, waiting for server response"); - result = Curl_pp_statemach(data, pp, TRUE, TRUE /* disconnecting */); - if(result) - break; - } - - return result; -} - -/* - * ftp_connect() should do everything that is to be considered a part of - * the connection phase. - * - * The variable 'done' points to will be TRUE if the protocol-layer connect - * phase is done when this function returns, or FALSE if not. - * - */ -static CURLcode ftp_connect(struct Curl_easy *data, - bool *done) /* see description above */ -{ - CURLcode result; - struct connectdata *conn = data->conn; - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - struct pingpong *pp; - - *done = FALSE; /* default to not done yet */ - if(!ftpc) - return CURLE_FAILED_INIT; - pp = &ftpc->pp; - PINGPONG_SETUP(pp, ftp_pp_statemachine, ftp_endofresp); - - if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - /* BLOCKING */ - result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done); - if(result) - return result; - conn->bits.ftp_use_control_ssl = TRUE; - } - - Curl_pp_init(pp, Curl_pgrs_now(data)); /* once per transfer */ - - /* When we connect, we start in the state where we await the 220 - response */ - ftp_state(data, ftpc, FTP_WAIT220); - - result = ftp_statemach(data, ftpc, done); - - return result; -} - -/*********************************************************************** - * - * ftp_sendquote() - * - * Where a 'quote' means a list of custom commands to send to the server. - * The quote list is passed as an argument. - * - * BLOCKING - */ -static CURLcode ftp_sendquote(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct curl_slist *quote) -{ - struct curl_slist *item; - struct pingpong *pp = &ftpc->pp; - - item = quote; - while(item) { - if(item->data) { - size_t nread; - const char *cmd = item->data; - bool acceptfail = FALSE; - CURLcode result; - int ftpcode = 0; - - /* if a command starts with an asterisk, which a legal FTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server responds. */ - - if(cmd[0] == '*') { - cmd++; - acceptfail = TRUE; - } - - result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd); - if(!result) { - pp->response = *Curl_pgrs_now(data); /* timeout relative now */ - result = getftpresponse(data, &nread, &ftpcode); - } - if(result) - return result; - - if(!acceptfail && (ftpcode >= 400)) { - failf(data, "QUOT string not accepted: %s", cmd); - return CURLE_QUOTE_ERROR; - } - } - - item = item->next; - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - struct connectdata *conn = data->conn; - struct FTP *ftp = Curl_meta_get(data, CURL_META_FTP_EASY); - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - struct pingpong *pp; - size_t nread; - int ftpcode; - CURLcode result = CURLE_OK; - - if(!ftp || !ftpc) - return CURLE_OK; - - pp = &ftpc->pp; - switch(status) { - case CURLE_BAD_DOWNLOAD_RESUME: - case CURLE_FTP_WEIRD_PASV_REPLY: - case CURLE_FTP_PORT_FAILED: - case CURLE_FTP_ACCEPT_FAILED: - case CURLE_FTP_ACCEPT_TIMEOUT: - case CURLE_FTP_COULDNT_SET_TYPE: - case CURLE_FTP_COULDNT_RETR_FILE: - case CURLE_PARTIAL_FILE: - case CURLE_UPLOAD_FAILED: - case CURLE_REMOTE_ACCESS_DENIED: - case CURLE_FILESIZE_EXCEEDED: - case CURLE_REMOTE_FILE_NOT_FOUND: - case CURLE_WRITE_ERROR: - /* the connection stays alive fine even though this happened */ - case CURLE_OK: /* does not affect the control connection's status */ - if(!premature) - break; - - /* until we cope better with prematurely ended requests, let them - * fallback as if in complete failure */ - FALLTHROUGH(); - default: /* by default, an error means the control connection is - wedged and should not be used anymore */ - ftpc->ctl_valid = FALSE; - ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the - current path, as this connection is going */ - connclose(conn, "FTP ended with bad error code"); - result = status; /* use the already set error code */ - break; - } - - if(data->state.wildcardmatch) { - if(data->set.chunk_end && ftpc->file) { - Curl_set_in_callback(data, TRUE); - data->set.chunk_end(data->set.wildcardptr); - Curl_set_in_callback(data, FALSE); - freedirs(ftpc); - } - ftpc->known_filesize = -1; - } - - if(result) { - /* We can limp along anyway (and should try to since we may already be in - * the error path) */ - ftpc->ctl_valid = FALSE; /* mark control connection as bad */ - connclose(conn, "FTP: out of memory!"); /* mark for connection closure */ - curlx_free(ftpc->prevpath); - ftpc->prevpath = NULL; /* no path remembering */ - } - else { /* remember working directory for connection reuse */ - const char *rawPath = ftpc->rawpath; - if(rawPath) { - if((data->set.ftp_filemethod == FTPFILE_NOCWD) && (rawPath[0] == '/')) - ; /* full path => no CWDs happened => keep ftpc->prevpath */ - else { - size_t pathLen = strlen(ftpc->rawpath); - - curlx_free(ftpc->prevpath); - - if(!ftpc->cwdfail) { - if(data->set.ftp_filemethod == FTPFILE_NOCWD) - pathLen = 0; /* relative path => working directory is FTP home */ - else - /* file is URL-decoded */ - pathLen -= ftpc->file ? strlen(ftpc->file) : 0; - ftpc->prevpath = curlx_memdup0(rawPath, pathLen); - } - else - ftpc->prevpath = NULL; /* no path */ - } - } - if(ftpc->prevpath) - infof(data, "Remembering we are in directory \"%s\"", ftpc->prevpath); - } - - /* shut down the socket to inform the server we are done */ - - if(Curl_conn_is_setup(conn, SECONDARYSOCKET)) { - if(!result && ftpc->dont_check && data->req.maxdownload > 0) { - /* partial download completed */ - result = Curl_pp_sendf(data, pp, "%s", "ABOR"); - if(result) { - failf(data, "Failure sending ABOR command: %s", - curl_easy_strerror(result)); - ftpc->ctl_valid = FALSE; /* mark control connection as bad */ - connclose(conn, "ABOR command failed"); /* connection closure */ - } - } - - close_secondarysocket(data, ftpc); - } - - if(!result && (ftp->transfer == PPTRANSFER_BODY) && ftpc->ctl_valid && - pp->pending_resp && !premature) { - /* - * Let's see what the server says about the transfer we performed, but - * lower the timeout as sometimes this connection has died while the data - * has been transferred. This happens when doing through NATs etc that - * abandon old silent connections. - */ - pp->response = *Curl_pgrs_now(data); /* timeout relative now */ - result = getftpresponse(data, &nread, &ftpcode); - - if(!nread && (result == CURLE_OPERATION_TIMEDOUT)) { - failf(data, "control connection looks dead"); - ftpc->ctl_valid = FALSE; /* mark control connection as bad */ - connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */ - } - - if(result) - return result; - - if(ftpc->dont_check && data->req.maxdownload > 0) { - /* we have sent ABOR and there is no reliable way to check if it was - * successful or not; we have to close the connection now */ - infof(data, "partial download completed, closing connection"); - connclose(conn, "Partial download with no ability to check"); - return result; - } - - if(!ftpc->dont_check) { - /* 226 Transfer complete, 250 Requested file action okay, completed. */ - switch(ftpcode) { - case 226: - case 250: - break; - case 552: - failf(data, "Exceeded storage allocation"); - result = CURLE_REMOTE_DISK_FULL; - break; - default: - failf(data, "server did not report OK, got %d", ftpcode); - result = CURLE_PARTIAL_FILE; - break; - } - } - } - - if(result || premature) - /* the response code from the transfer showed an error already so no - use checking further */ - ; - else if(data->state.upload) { - if((ftp->transfer == PPTRANSFER_BODY) && - (data->state.infilesize != -1) && /* upload with known size */ - ((!data->set.crlf && !data->state.prefer_ascii && /* no conversion */ - (data->state.infilesize != data->req.writebytecount)) || - ((data->set.crlf || data->state.prefer_ascii) && /* maybe crlf conv */ - (data->state.infilesize > data->req.writebytecount)) - )) { - failf(data, "Uploaded unaligned file size (%" FMT_OFF_T - " out of %" FMT_OFF_T " bytes)", - data->req.writebytecount, data->state.infilesize); - result = CURLE_PARTIAL_FILE; - } - } - else { - if((data->req.size != -1) && - (data->req.size != data->req.bytecount) && - (data->req.maxdownload != data->req.bytecount)) { - failf(data, "Received only partial file: %" FMT_OFF_T " bytes", - data->req.bytecount); - result = CURLE_PARTIAL_FILE; - } - else if(!ftpc->dont_check && - !data->req.bytecount && - (data->req.size > 0)) { - failf(data, "No data was received"); - result = CURLE_FTP_COULDNT_RETR_FILE; - } - } - - /* clear these for next connection */ - ftp->transfer = PPTRANSFER_BODY; - ftpc->dont_check = FALSE; - - /* Send any post-transfer QUOTE strings? */ - if(!status && !result && !premature && data->set.postquote) - result = ftp_sendquote(data, ftpc, data->set.postquote); - CURL_TRC_FTP(data, "[%s] done, result=%d", FTP_CSTATE(ftpc), result); - return result; -} - -/*********************************************************************** - * - * ftp_nb_type() - * - * Set TYPE. We only deal with ASCII or BINARY so this function - * sets one of them. - * If the transfer type is not sent, simulate on OK response in newstate - */ -static CURLcode ftp_nb_type(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool ascii, ftpstate newstate) -{ - CURLcode result; - char want = (char)(ascii ? 'A' : 'I'); - - if(ftpc->transfertype == want) { - ftp_state(data, ftpc, newstate); - return ftp_state_type_resp(data, ftpc, ftp, 200, newstate); - } - - result = Curl_pp_sendf(data, &ftpc->pp, "TYPE %c", want); - if(!result) { - ftp_state(data, ftpc, newstate); - - /* keep track of our current transfer type */ - ftpc->transfertype = want; - } - return result; -} - -/*********************************************************************** - * - * ftp_perform() - * - * This is the actual DO function for FTP. Get a file/directory according to - * the options previously setup. - */ -static CURLcode ftp_perform( - struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool *connected, /* connect status after PASV / PORT */ - bool *dophase_done) -{ - /* this is FTP and no proxy */ - CURLcode result = CURLE_OK; - - CURL_TRC_FTP(data, "[%s] DO phase starts", FTP_CSTATE(ftpc)); - - if(data->req.no_body) { - /* requested no body means no transfer... */ - ftp->transfer = PPTRANSFER_INFO; - } - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - result = ftp_state_quote(data, ftpc, ftp, TRUE, FTP_QUOTE); - if(result) - return result; - - /* run the state-machine */ - result = ftp_statemach(data, ftpc, dophase_done); - - *connected = Curl_conn_is_connected(data->conn, SECONDARYSOCKET); - - if(*connected) - infof(data, "[FTP] [%s] perform, DATA connection established", - FTP_CSTATE(ftpc)); - else - CURL_TRC_FTP(data, "[%s] perform, awaiting DATA connect", - FTP_CSTATE(ftpc)); - - if(*dophase_done) - CURL_TRC_FTP(data, "[%s] DO phase is complete1", FTP_CSTATE(ftpc)); - - return result; -} - -static void wc_data_dtor(void *ptr) -{ - struct ftp_wc *ftpwc = ptr; - if(ftpwc && ftpwc->parser) - Curl_ftp_parselist_data_free(&ftpwc->parser); - curlx_free(ftpwc); -} - -static CURLcode init_wc_data(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - char *last_slash; - char *path = ftp->path; - struct WildcardData *wildcard = data->wildcard; - CURLcode result = CURLE_OK; - struct ftp_wc *ftpwc = NULL; - - last_slash = strrchr(ftp->path, '/'); - if(last_slash) { - last_slash++; - if(last_slash[0] == '\0') { - wildcard->state = CURLWC_CLEAN; - return ftp_parse_url_path(data, ftpc, ftp); - } - wildcard->pattern = curlx_strdup(last_slash); - if(!wildcard->pattern) - return CURLE_OUT_OF_MEMORY; - last_slash[0] = '\0'; /* cut file from path */ - } - else { /* there is only 'wildcard pattern' or nothing */ - if(path[0]) { - wildcard->pattern = curlx_strdup(path); - if(!wildcard->pattern) - return CURLE_OUT_OF_MEMORY; - path[0] = '\0'; - } - else { /* only list */ - wildcard->state = CURLWC_CLEAN; - return ftp_parse_url_path(data, ftpc, ftp); - } - } - - /* program continues only if URL is not ending with slash, allocate needed - resources for wildcard transfer */ - - /* allocate ftp protocol specific wildcard data */ - ftpwc = curlx_calloc(1, sizeof(struct ftp_wc)); - if(!ftpwc) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - /* INITIALIZE parselist structure */ - ftpwc->parser = Curl_ftp_parselist_data_alloc(); - if(!ftpwc->parser) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - wildcard->ftpwc = ftpwc; /* put it to the WildcardData tmp pointer */ - wildcard->dtor = wc_data_dtor; - - /* wildcard does not support NOCWD option (assert it?) */ - if(data->set.ftp_filemethod == FTPFILE_NOCWD) - data->set.ftp_filemethod = FTPFILE_MULTICWD; - - /* try to parse ftp URL */ - result = ftp_parse_url_path(data, ftpc, ftp); - if(result) { - goto fail; - } - - wildcard->path = curlx_strdup(ftp->path); - if(!wildcard->path) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - /* backup old write_function */ - ftpwc->backup.write_function = data->set.fwrite_func; - /* parsing write function */ - data->set.fwrite_func = Curl_ftp_parselist; - /* backup old file descriptor */ - ftpwc->backup.file_descriptor = data->set.out; - /* let the writefunc callback know the transfer */ - data->set.out = data; - - infof(data, "Wildcard - Parsing started"); - return CURLE_OK; - -fail: - if(ftpwc) { - Curl_ftp_parselist_data_free(&ftpwc->parser); - curlx_free(ftpwc); - } - curlx_safefree(wildcard->pattern); - wildcard->dtor = ZERO_NULL; - wildcard->ftpwc = NULL; - return result; -} - -static CURLcode wc_statemach(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp) -{ - struct WildcardData * const wildcard = data->wildcard; - CURLcode result = CURLE_OK; - - for(;;) { - switch(wildcard->state) { - case CURLWC_INIT: - result = init_wc_data(data, ftpc, ftp); - if(wildcard->state == CURLWC_CLEAN) - /* only listing! */ - return result; - wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; - return result; - - case CURLWC_MATCHING: { - /* In this state is LIST response successfully parsed, so lets restore - previous WRITEFUNCTION callback and WRITEDATA pointer */ - struct ftp_wc *ftpwc = wildcard->ftpwc; - data->set.fwrite_func = ftpwc->backup.write_function; - data->set.out = ftpwc->backup.file_descriptor; - ftpwc->backup.write_function = ZERO_NULL; - ftpwc->backup.file_descriptor = NULL; - wildcard->state = CURLWC_DOWNLOADING; - - if(Curl_ftp_parselist_geterror(ftpwc->parser)) { - /* error found in LIST parsing */ - wildcard->state = CURLWC_CLEAN; - continue; - } - if(Curl_llist_count(&wildcard->filelist) == 0) { - /* no corresponding file */ - wildcard->state = CURLWC_CLEAN; - return CURLE_REMOTE_FILE_NOT_FOUND; - } - continue; - } - - case CURLWC_DOWNLOADING: { - /* filelist has at least one file, lets get first one */ - struct Curl_llist_node *head = Curl_llist_head(&wildcard->filelist); - struct curl_fileinfo *finfo = Curl_node_elem(head); - - char *tmp_path = curl_maprintf("%s%s", wildcard->path, finfo->filename); - if(!tmp_path) - return CURLE_OUT_OF_MEMORY; - - /* switch default ftp->path and tmp_path */ - curlx_free(ftp->pathalloc); - ftp->pathalloc = ftp->path = tmp_path; - - infof(data, "Wildcard - START of \"%s\"", finfo->filename); - if(data->set.chunk_bgn) { - long userresponse; - Curl_set_in_callback(data, TRUE); - userresponse = data->set.chunk_bgn( - finfo, data->set.wildcardptr, - (int)Curl_llist_count(&wildcard->filelist)); - Curl_set_in_callback(data, FALSE); - switch(userresponse) { - case CURL_CHUNK_BGN_FUNC_SKIP: - infof(data, "Wildcard - \"%s\" skipped by user", finfo->filename); - wildcard->state = CURLWC_SKIP; - continue; - case CURL_CHUNK_BGN_FUNC_FAIL: - return CURLE_CHUNK_FAILED; - } - } - - if(finfo->filetype != CURLFILETYPE_FILE) { - wildcard->state = CURLWC_SKIP; - continue; - } - - if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) - ftpc->known_filesize = finfo->size; - - result = ftp_parse_url_path(data, ftpc, ftp); - if(result) - return result; - - /* we do not need the Curl_fileinfo of first file anymore */ - Curl_node_remove(Curl_llist_head(&wildcard->filelist)); - - if(Curl_llist_count(&wildcard->filelist) == 0) { - /* remains only one file to down. */ - wildcard->state = CURLWC_CLEAN; - /* after that will be ftp_do called once again and no transfer - will be done because of CURLWC_CLEAN state */ - return CURLE_OK; - } - return result; - } - - case CURLWC_SKIP: { - if(data->set.chunk_end) { - Curl_set_in_callback(data, TRUE); - data->set.chunk_end(data->set.wildcardptr); - Curl_set_in_callback(data, FALSE); - } - Curl_node_remove(Curl_llist_head(&wildcard->filelist)); - wildcard->state = (Curl_llist_count(&wildcard->filelist) == 0) ? - CURLWC_CLEAN : CURLWC_DOWNLOADING; - continue; - } - - case CURLWC_CLEAN: { - struct ftp_wc *ftpwc = wildcard->ftpwc; - result = CURLE_OK; - if(ftpwc) - result = Curl_ftp_parselist_geterror(ftpwc->parser); - - wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; - return result; - } - - case CURLWC_DONE: - case CURLWC_ERROR: - case CURLWC_CLEAR: - if(wildcard->dtor) { - wildcard->dtor(wildcard->ftpwc); - wildcard->ftpwc = NULL; - } - return result; - } - } - /* UNREACHABLE */ -} - -/*********************************************************************** - * - * ftp_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - * - * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the - * ftp_done() function without finding any major problem. - */ -static CURLcode ftp_regular_transfer(struct Curl_easy *data, - struct ftp_conn *ftpc, - struct FTP *ftp, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - bool connected = FALSE; - data->req.size = -1; /* make sure this is unknown at this point */ - - Curl_pgrsReset(data); - - ftpc->ctl_valid = TRUE; /* starts good */ - - result = ftp_perform(data, ftpc, ftp, - &connected, /* have we connected after PASV/PORT */ - dophase_done); /* all commands in the DO-phase done? */ - - if(!result) { - - if(!*dophase_done) - /* the DO phase has not completed yet */ - return CURLE_OK; - - result = ftp_dophase_done(data, ftpc, ftp, connected); - - if(result) - return result; - } - else - freedirs(ftpc); - - return result; -} - -/*********************************************************************** - * - * ftp_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (ftp_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode ftp_do(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - struct FTP *ftp = Curl_meta_get(data, CURL_META_FTP_EASY); - - *done = FALSE; /* default to false */ - if(!ftpc || !ftp) - return CURLE_FAILED_INIT; - ftpc->wait_data_conn = FALSE; /* default to no such wait */ - -#ifdef CURL_PREFER_LF_LINEENDS - { - /* FTP data may need conversion. */ - struct Curl_cwriter *ftp_lc_writer; - - result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc, - CURL_CW_CONTENT_DECODE); - if(result) - return result; - - result = Curl_cwriter_add(data, ftp_lc_writer); - if(result) { - Curl_cwriter_free(data, ftp_lc_writer); - return result; - } - } -#endif /* CURL_PREFER_LF_LINEENDS */ - - if(data->state.wildcardmatch) { - result = wc_statemach(data, ftpc, ftp); - if(data->wildcard->state == CURLWC_SKIP || - data->wildcard->state == CURLWC_DONE) { - /* do not call ftp_regular_transfer */ - return CURLE_OK; - } - if(result) /* error, loop or skipping the file */ - return result; - } - else { /* no wildcard FSM needed */ - result = ftp_parse_url_path(data, ftpc, ftp); - if(result) - return result; - } - - result = ftp_regular_transfer(data, ftpc, ftp, done); - - return result; -} - -/*********************************************************************** - * - * ftp_quit() - * - * This should be called before calling sclose() on an ftp control connection - * (not data connections). We should then wait for the response from the - * server before returning. The calling code should then try to close the - * connection. - * - */ -static CURLcode ftp_quit(struct Curl_easy *data, - struct ftp_conn *ftpc) -{ - CURLcode result = CURLE_OK; - - if(ftpc->ctl_valid) { - CURL_TRC_FTP(data, "sending QUIT to close session"); - result = Curl_pp_sendf(data, &ftpc->pp, "%s", "QUIT"); - if(result) { - failf(data, "Failure sending QUIT command: %s", - curl_easy_strerror(result)); - ftpc->ctl_valid = FALSE; /* mark control connection as bad */ - connclose(data->conn, "QUIT command failed"); /* mark for closure */ - ftp_state(data, ftpc, FTP_STOP); - return result; - } - - ftp_state(data, ftpc, FTP_QUIT); - - result = ftp_block_statemach(data, ftpc); - } - - return result; -} - -/*********************************************************************** - * - * ftp_disconnect() - * - * Disconnect from an FTP server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode ftp_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection) -{ - struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); - - if(!ftpc) - return CURLE_FAILED_INIT; - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. - - ftp_quit() will check the state of ftp->ctl_valid. If it is ok it - will try to send the QUIT command, otherwise it will return. - */ - ftpc->shutdown = TRUE; - if(dead_connection || Curl_pp_needs_flush(data, &ftpc->pp)) - ftpc->ctl_valid = FALSE; - - /* The FTP session may or may not have been allocated/setup at this point! */ - (void)ftp_quit(data, ftpc); /* ignore errors on the QUIT */ - return CURLE_OK; -} - -/* called from multi.c while DOing */ -static CURLcode ftp_doing(struct Curl_easy *data, - bool *dophase_done) -{ - struct ftp_conn *ftpc = Curl_conn_meta_get(data->conn, CURL_META_FTP_CONN); - struct FTP *ftp = Curl_meta_get(data, CURL_META_FTP_EASY); - CURLcode result; - - if(!ftpc || !ftp) - return CURLE_FAILED_INIT; - result = ftp_statemach(data, ftpc, dophase_done); - - if(result) - CURL_TRC_FTP(data, "[%s] DO phase failed", FTP_CSTATE(ftpc)); - else if(*dophase_done) { - result = ftp_dophase_done(data, ftpc, ftp, FALSE /* not connected */); - - CURL_TRC_FTP(data, "[%s] DO phase is complete2", FTP_CSTATE(ftpc)); - } - return result; -} - -static void ftp_easy_dtor(void *key, size_t klen, void *entry) -{ - struct FTP *ftp = entry; - (void)key; - (void)klen; - curlx_safefree(ftp->pathalloc); - curlx_free(ftp); -} - -static void ftp_conn_dtor(void *key, size_t klen, void *entry) -{ - struct ftp_conn *ftpc = entry; - (void)key; - (void)klen; - freedirs(ftpc); - curlx_safefree(ftpc->account); - curlx_safefree(ftpc->alternative_to_user); - curlx_safefree(ftpc->entrypath); - curlx_safefree(ftpc->prevpath); - curlx_safefree(ftpc->server_os); - Curl_pp_disconnect(&ftpc->pp); - curlx_free(ftpc); -} - -static void type_url_check(struct Curl_easy *data, struct FTP *ftp) -{ - size_t len = strlen(ftp->path); - /* FTP URLs support an extension like ";type=" that - * we will try to get now! */ - if((len >= 7) && !memcmp(&ftp->path[len - 7], ";type=", 6)) { - char *type = &ftp->path[len - 7]; - char command = Curl_raw_toupper(type[6]); - - *type = 0; /* cut it off */ - - switch(command) { - case 'A': /* ASCII mode */ - data->state.prefer_ascii = TRUE; - break; - - case 'D': /* directory mode */ - data->state.list_only = TRUE; - break; - - case 'I': /* binary mode */ - default: - /* switch off ASCII */ - data->state.prefer_ascii = FALSE; - break; - } - } -} - -static CURLcode ftp_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct FTP *ftp; - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc; - - ftp = curlx_calloc(1, sizeof(*ftp)); - if(!ftp || - Curl_meta_set(data, CURL_META_FTP_EASY, ftp, ftp_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - ftpc = curlx_calloc(1, sizeof(*ftpc)); - if(!ftpc || - Curl_conn_meta_set(conn, CURL_META_FTP_CONN, ftpc, ftp_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - /* clone connection related data that is FTP specific */ - if(data->set.str[STRING_FTP_ACCOUNT]) { - ftpc->account = curlx_strdup(data->set.str[STRING_FTP_ACCOUNT]); - if(!ftpc->account) { - Curl_conn_meta_remove(conn, CURL_META_FTP_CONN); - return CURLE_OUT_OF_MEMORY; - } - } - if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]) { - ftpc->alternative_to_user = - curlx_strdup(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); - if(!ftpc->alternative_to_user) { - curlx_safefree(ftpc->account); - Curl_conn_meta_remove(conn, CURL_META_FTP_CONN); - return CURLE_OUT_OF_MEMORY; - } - } - - ftp->path = &data->state.up.path[1]; /* do not include the initial slash */ - - type_url_check(data, ftp); - - /* get some initial data into the ftp struct */ - ftp->transfer = PPTRANSFER_BODY; - ftp->downloadsize = 0; - ftpc->known_filesize = -1; /* unknown size for now */ - ftpc->use_ssl = data->set.use_ssl; - ftpc->ccc = data->set.ftp_ccc; - - CURL_TRC_FTP(data, "[%s] setup connection -> %d", FTP_CSTATE(ftpc), result); - return result; -} - -bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn) -{ - struct ftp_conn *nftpc = Curl_conn_meta_get(needle, CURL_META_FTP_CONN); - struct ftp_conn *cftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN); - /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */ - if(!nftpc || !cftpc || - Curl_timestrcmp(nftpc->account, cftpc->account) || - Curl_timestrcmp(nftpc->alternative_to_user, - cftpc->alternative_to_user) || - (nftpc->use_ssl != cftpc->use_ssl) || - (nftpc->ccc != cftpc->ccc)) - return FALSE; - return TRUE; -} - -/* - * FTP protocol. - */ -const struct Curl_protocol Curl_protocol_ftp = { - ftp_setup_connection, /* setup_connection */ - ftp_do, /* do_it */ - ftp_done, /* done */ - ftp_do_more, /* do_more */ - ftp_connect, /* connect_it */ - ftp_multi_statemach, /* connecting */ - ftp_doing, /* doing */ - ftp_pollset, /* proto_pollset */ - ftp_pollset, /* doing_pollset */ - ftp_domore_pollset, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ftp_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* CURL_DISABLE_FTP */ diff --git a/vendor/curl/lib/ftp.h b/vendor/curl/lib/ftp.h deleted file mode 100644 index 257f59582..000000000 --- a/vendor/curl/lib/ftp.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef HEADER_CURL_FTP_H -#define HEADER_CURL_FTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP -extern const struct Curl_protocol Curl_protocol_ftp; - -bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn); - -typedef enum { - FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */ - FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */ - FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the - file */ -} curl_ftpfile; - -#endif /* CURL_DISABLE_FTP */ - -#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */ - -#endif /* HEADER_CURL_FTP_H */ diff --git a/vendor/curl/lib/ftplistparser.c b/vendor/curl/lib/ftplistparser.c deleted file mode 100644 index b5d9338c1..000000000 --- a/vendor/curl/lib/ftplistparser.c +++ /dev/null @@ -1,1091 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP - -/** - * Now implemented: - * - * 1) Unix version 1 - * drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog - * 2) Unix version 2 - * drwxr-xr-x 1 user01 ftp 512 Jan 29 1997 prog - * 3) Unix version 3 - * drwxr-xr-x 1 1 1 512 Jan 29 23:32 prog - * 4) Unix symlink - * lrwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog -> prog2000 - * 5) DOS style - * 01-29-97 11:32PM prog - */ - -#include "urldata.h" -#include "fileinfo.h" -#include "llist.h" -#include "ftp.h" -#include "ftp-int.h" -#include "ftplistparser.h" -#include "curl_fnmatch.h" -#include "multiif.h" -#include "curlx/strparse.h" - -typedef enum { - PL_UNIX_TOTALSIZE = 0, - PL_UNIX_FILETYPE, - PL_UNIX_PERMISSION, - PL_UNIX_HLINKS, - PL_UNIX_USER, - PL_UNIX_GROUP, - PL_UNIX_SIZE, - PL_UNIX_TIME, - PL_UNIX_FILENAME, - PL_UNIX_SYMLINK -} pl_unix_mainstate; - -typedef union { - enum { - PL_UNIX_TOTALSIZE_INIT = 0, - PL_UNIX_TOTALSIZE_READING - } total_dirsize; - - enum { - PL_UNIX_HLINKS_PRESPACE = 0, - PL_UNIX_HLINKS_NUMBER - } hlinks; - - enum { - PL_UNIX_USER_PRESPACE = 0, - PL_UNIX_USER_PARSING - } user; - - enum { - PL_UNIX_GROUP_PRESPACE = 0, - PL_UNIX_GROUP_NAME - } group; - - enum { - PL_UNIX_SIZE_PRESPACE = 0, - PL_UNIX_SIZE_NUMBER - } size; - - enum { - PL_UNIX_TIME_PREPART1 = 0, - PL_UNIX_TIME_PART1, - PL_UNIX_TIME_PREPART2, - PL_UNIX_TIME_PART2, - PL_UNIX_TIME_PREPART3, - PL_UNIX_TIME_PART3 - } time; - - enum { - PL_UNIX_FILENAME_PRESPACE = 0, - PL_UNIX_FILENAME_NAME, - PL_UNIX_FILENAME_WINDOWSEOL - } filename; - - enum { - PL_UNIX_SYMLINK_PRESPACE = 0, - PL_UNIX_SYMLINK_NAME, - PL_UNIX_SYMLINK_PRETARGET1, - PL_UNIX_SYMLINK_PRETARGET2, - PL_UNIX_SYMLINK_PRETARGET3, - PL_UNIX_SYMLINK_PRETARGET4, - PL_UNIX_SYMLINK_TARGET, - PL_UNIX_SYMLINK_WINDOWSEOL - } symlink; -} pl_unix_substate; - -typedef enum { - PL_WINNT_DATE = 0, - PL_WINNT_TIME, - PL_WINNT_DIRORSIZE, - PL_WINNT_FILENAME -} pl_winNT_mainstate; - -typedef union { - enum { - PL_WINNT_TIME_PRESPACE = 0, - PL_WINNT_TIME_TIME - } time; - enum { - PL_WINNT_DIRORSIZE_PRESPACE = 0, - PL_WINNT_DIRORSIZE_CONTENT - } dirorsize; - enum { - PL_WINNT_FILENAME_PRESPACE = 0, - PL_WINNT_FILENAME_CONTENT, - PL_WINNT_FILENAME_WINEOL - } filename; -} pl_winNT_substate; - -/* This struct is used in wildcard downloading - for parsing LIST response */ -struct ftp_parselist_data { - enum { - OS_TYPE_UNKNOWN = 0, - OS_TYPE_UNIX, - OS_TYPE_WIN_NT - } os_type; - - union { - struct { - pl_unix_mainstate main; - pl_unix_substate sub; - } UNIX; - - struct { - pl_winNT_mainstate main; - pl_winNT_substate sub; - } NT; - } state; - - CURLcode error; - struct fileinfo *file_data; - unsigned int item_length; - size_t item_offset; - struct { - size_t filename; - size_t user; - size_t group; - size_t time; - size_t perm; - size_t symlink_target; - } offsets; -}; - -static void fileinfo_dtor(void *user, void *element) -{ - (void)user; - Curl_fileinfo_cleanup(element); -} - -void Curl_wildcard_init(struct WildcardData *wc) -{ - Curl_llist_init(&wc->filelist, fileinfo_dtor); - wc->state = CURLWC_INIT; -} - -void Curl_wildcard_dtor(struct WildcardData **wcp) -{ - struct WildcardData *wc = *wcp; - if(!wc) - return; - - if(wc->dtor) { - wc->dtor(wc->ftpwc); - wc->dtor = ZERO_NULL; - wc->ftpwc = NULL; - } - DEBUGASSERT(wc->ftpwc == NULL); - - Curl_llist_destroy(&wc->filelist, NULL); - curlx_free(wc->path); - wc->path = NULL; - curlx_free(wc->pattern); - wc->pattern = NULL; - wc->state = CURLWC_INIT; - curlx_free(wc); - *wcp = NULL; -} - -struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void) -{ - return curlx_calloc(1, sizeof(struct ftp_parselist_data)); -} - -void Curl_ftp_parselist_data_free(struct ftp_parselist_data **parserp) -{ - struct ftp_parselist_data *parser = *parserp; - if(parser) - Curl_fileinfo_cleanup(parser->file_data); - curlx_free(parser); - *parserp = NULL; -} - -CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data) -{ - return pl_data->error; -} - -#define FTP_LP_MALFORMATED_PERM 0x01000000 - -static unsigned int ftp_pl_get_permission(const char *str) -{ - unsigned int permissions = 0; - /* USER */ - if(str[0] == 'r') - permissions |= 1 << 8; - else if(str[0] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[1] == 'w') - permissions |= 1 << 7; - else if(str[1] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - - if(str[2] == 'x') - permissions |= 1 << 6; - else if(str[2] == 's') { - permissions |= 1 << 6; - permissions |= 1 << 11; - } - else if(str[2] == 'S') - permissions |= 1 << 11; - else if(str[2] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - /* GROUP */ - if(str[3] == 'r') - permissions |= 1 << 5; - else if(str[3] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[4] == 'w') - permissions |= 1 << 4; - else if(str[4] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[5] == 'x') - permissions |= 1 << 3; - else if(str[5] == 's') { - permissions |= 1 << 3; - permissions |= 1 << 10; - } - else if(str[5] == 'S') - permissions |= 1 << 10; - else if(str[5] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - /* others */ - if(str[6] == 'r') - permissions |= 1 << 2; - else if(str[6] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[7] == 'w') - permissions |= 1 << 1; - else if(str[7] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[8] == 'x') - permissions |= 1; - else if(str[8] == 't') { - permissions |= 1; - permissions |= 1 << 9; - } - else if(str[8] == 'T') - permissions |= 1 << 9; - else if(str[8] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - - return permissions; -} - -static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data, - struct fileinfo *infop) -{ - curl_fnmatch_callback compare; - struct WildcardData *wc = data->wildcard; - struct ftp_wc *ftpwc = wc->ftpwc; - struct Curl_llist *llist = &wc->filelist; - struct ftp_parselist_data *parser = ftpwc->parser; - bool add = TRUE; - struct curl_fileinfo *finfo = &infop->info; - - /* set the finfo pointers */ - char *str = curlx_dyn_ptr(&infop->buf); - finfo->filename = str + parser->offsets.filename; - finfo->strings.group = parser->offsets.group ? - str + parser->offsets.group : NULL; - finfo->strings.perm = parser->offsets.perm ? - str + parser->offsets.perm : NULL; - finfo->strings.target = parser->offsets.symlink_target ? - str + parser->offsets.symlink_target : NULL; - finfo->strings.time = str + parser->offsets.time; - finfo->strings.user = parser->offsets.user ? - str + parser->offsets.user : NULL; - - /* get correct fnmatch callback */ - compare = data->set.fnmatch; - if(!compare) - compare = Curl_fnmatch; - - /* filter pattern-corresponding filenames */ - Curl_set_in_callback(data, TRUE); - if(compare(data->set.fnmatch_data, wc->pattern, finfo->filename) == 0) { - /* discard symlink which is containing multiple " -> " */ - if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target && - (strstr(finfo->strings.target, " -> "))) { - add = FALSE; - } - } - else { - add = FALSE; - } - Curl_set_in_callback(data, FALSE); - - if(add) { - Curl_llist_append(llist, finfo, &infop->list); - } - else { - Curl_fileinfo_cleanup(infop); - } - - ftpwc->parser->file_data = NULL; - return CURLE_OK; -} - -#define MAX_FTPLIST_BUFFER 10000 /* arbitrarily set */ - -static CURLcode unix_filetype(const char c, curlfiletype *t) -{ - switch(c) { - case '-': - *t = CURLFILETYPE_FILE; - break; - case 'd': - *t = CURLFILETYPE_DIRECTORY; - break; - case 'l': - *t = CURLFILETYPE_SYMLINK; - break; - case 'p': - *t = CURLFILETYPE_NAMEDPIPE; - break; - case 's': - *t = CURLFILETYPE_SOCKET; - break; - case 'c': - *t = CURLFILETYPE_DEVICE_CHAR; - break; - case 'b': - *t = CURLFILETYPE_DEVICE_BLOCK; - break; - case 'D': - *t = CURLFILETYPE_DOOR; - break; - default: - return CURLE_FTP_BAD_FILE_LIST; - } - return CURLE_OK; -} - -static CURLcode parse_unix_totalsize(struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - switch(parser->state.UNIX.sub.total_dirsize) { - case PL_UNIX_TOTALSIZE_INIT: - if(c == 't') { - parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING; - parser->item_length++; - } - else { - parser->state.UNIX.main = PL_UNIX_FILETYPE; - /* continue to fall through */ - } - break; - case PL_UNIX_TOTALSIZE_READING: - parser->item_length++; - if(c == '\r') { - parser->item_length--; - if(len) - curlx_dyn_setlen(&infop->buf, --len); - } - else if(c == '\n') { - mem[parser->item_length - 1] = 0; - if(!strncmp("total ", mem, 6)) { - const char *endptr = mem + 6; - /* here we can deal with directory size, pass the leading - whitespace and then the digits */ - curlx_str_passblanks(&endptr); - while(ISDIGIT(*endptr)) - endptr++; - if(*endptr) { - return CURLE_FTP_BAD_FILE_LIST; - } - parser->state.UNIX.main = PL_UNIX_FILETYPE; - curlx_dyn_reset(&infop->buf); - } - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - } - return CURLE_OK; -} - -static CURLcode parse_unix_permission(struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - char *mem = curlx_dyn_ptr(&infop->buf); - parser->item_length++; - if((parser->item_length <= 9) && !strchr("rwx-tTsS", c)) - return CURLE_FTP_BAD_FILE_LIST; - - else if(parser->item_length == 10) { - unsigned int perm; - if(c != ' ') - return CURLE_FTP_BAD_FILE_LIST; - - mem[10] = 0; /* terminate permissions */ - perm = ftp_pl_get_permission(mem + parser->item_offset); - if(perm & FTP_LP_MALFORMATED_PERM) - return CURLE_FTP_BAD_FILE_LIST; - - parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_PERM; - parser->file_data->info.perm = perm; - parser->offsets.perm = parser->item_offset; - - parser->item_length = 0; - parser->state.UNIX.main = PL_UNIX_HLINKS; - parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE; - } - return CURLE_OK; -} - -static CURLcode parse_unix_hlinks(struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - - switch(parser->state.UNIX.sub.hlinks) { - case PL_UNIX_HLINKS_PRESPACE: - if(c != ' ') { - if(ISDIGIT(c) && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER; - } - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_HLINKS_NUMBER: - parser->item_length++; - if(c == ' ') { - const char *p = &mem[parser->item_offset]; - curl_off_t hlinks; - mem[parser->item_offset + parser->item_length - 1] = 0; - - if(!curlx_str_number(&p, &hlinks, LONG_MAX)) { - parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT; - parser->file_data->info.hardlinks = (long)hlinks; - } - parser->item_length = 0; - parser->item_offset = 0; - parser->state.UNIX.main = PL_UNIX_USER; - parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE; - } - else if(!ISDIGIT(c)) - return CURLE_FTP_BAD_FILE_LIST; - - break; - } - return CURLE_OK; -} - -static CURLcode parse_unix_user(struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - switch(parser->state.UNIX.sub.user) { - case PL_UNIX_USER_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING; - } - break; - case PL_UNIX_USER_PARSING: - parser->item_length++; - if(c == ' ') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.user = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_GROUP; - parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE; - parser->item_offset = 0; - parser->item_length = 0; - } - break; - } - return CURLE_OK; -} - -static CURLcode parse_unix_group(struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - switch(parser->state.UNIX.sub.group) { - case PL_UNIX_GROUP_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME; - } - break; - case PL_UNIX_GROUP_NAME: - parser->item_length++; - if(c == ' ') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.group = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_SIZE; - parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE; - parser->item_offset = 0; - parser->item_length = 0; - } - break; - } - return CURLE_OK; -} - -static CURLcode parse_unix_size(struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - switch(parser->state.UNIX.sub.size) { - case PL_UNIX_SIZE_PRESPACE: - if(c != ' ') { - if(ISDIGIT(c) && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER; - } - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_SIZE_NUMBER: - parser->item_length++; - if(c == ' ') { - const char *p = mem + parser->item_offset; - curl_off_t fsize; - mem[parser->item_offset + parser->item_length - 1] = 0; - if(!curlx_str_numblanks(&p, &fsize)) { - if(p[0] == '\0' && fsize != CURL_OFF_T_MAX) { - parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE; - parser->file_data->info.size = fsize; - } - parser->item_length = 0; - parser->item_offset = 0; - parser->state.UNIX.main = PL_UNIX_TIME; - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1; - } - } - else if(!ISDIGIT(c)) - return CURLE_FTP_BAD_FILE_LIST; - - break; - } - return CURLE_OK; -} - -static CURLcode parse_unix_time(struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - struct curl_fileinfo *finfo = &infop->info; - - switch(parser->state.UNIX.sub.time) { - case PL_UNIX_TIME_PREPART1: - if(c != ' ') { - if(ISALNUM(c) && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1; - } - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_TIME_PART1: - parser->item_length++; - if(c == ' ') - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2; - - else if(!ISALNUM(c) && c != '.') - return CURLE_FTP_BAD_FILE_LIST; - - break; - case PL_UNIX_TIME_PREPART2: - parser->item_length++; - if(c != ' ') { - if(ISALNUM(c)) - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2; - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_TIME_PART2: - parser->item_length++; - if(c == ' ') - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3; - else if(!ISALNUM(c) && c != '.') - return CURLE_FTP_BAD_FILE_LIST; - break; - case PL_UNIX_TIME_PREPART3: - parser->item_length++; - if(c != ' ') { - if(ISALNUM(c)) - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3; - else - return CURLE_FTP_BAD_FILE_LIST; - } - break; - case PL_UNIX_TIME_PART3: - parser->item_length++; - if(c == ' ') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.time = parser->item_offset; - if(finfo->filetype == CURLFILETYPE_SYMLINK) { - parser->state.UNIX.main = PL_UNIX_SYMLINK; - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE; - } - else { - parser->state.UNIX.main = PL_UNIX_FILENAME; - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE; - } - } - else if(!ISALNUM(c) && c != '.' && c != ':') - return CURLE_FTP_BAD_FILE_LIST; - break; - } - return CURLE_OK; -} - -static CURLcode parse_unix_filename(struct Curl_easy *data, - struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - CURLcode result = CURLE_OK; - - switch(parser->state.UNIX.sub.filename) { - case PL_UNIX_FILENAME_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME; - } - break; - case PL_UNIX_FILENAME_NAME: - parser->item_length++; - if(c == '\r') - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL; - - else if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.filename = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(data, infop); - } - break; - case PL_UNIX_FILENAME_WINDOWSEOL: - if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.filename = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(data, infop); - } - else - result = CURLE_FTP_BAD_FILE_LIST; - break; - } - return result; -} - -static CURLcode parse_unix_symlink(struct Curl_easy *data, - struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - CURLcode result = CURLE_OK; - - switch(parser->state.UNIX.sub.symlink) { - case PL_UNIX_SYMLINK_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - break; - case PL_UNIX_SYMLINK_NAME: - parser->item_length++; - if(c == ' ') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1; - - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; - - break; - case PL_UNIX_SYMLINK_PRETARGET1: - parser->item_length++; - if(c == '-') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2; - - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; - else - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - break; - case PL_UNIX_SYMLINK_PRETARGET2: - parser->item_length++; - if(c == '>') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3; - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; - else - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - - break; - case PL_UNIX_SYMLINK_PRETARGET3: - parser->item_length++; - if(c == ' ') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4; - /* now place where is symlink following */ - mem[parser->item_offset + parser->item_length - 4] = 0; - parser->offsets.filename = parser->item_offset; - parser->item_length = 0; - parser->item_offset = 0; - } - else if(c == '\r' || c == '\n') - return CURLE_FTP_BAD_FILE_LIST; - else - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - break; - case PL_UNIX_SYMLINK_PRETARGET4: - if(c != '\r' && c != '\n' && len) { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET; - parser->item_offset = len - 1; - parser->item_length = 1; - } - else - return CURLE_FTP_BAD_FILE_LIST; - - break; - case PL_UNIX_SYMLINK_TARGET: - parser->item_length++; - if(c == '\r') - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL; - - else if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.symlink_target = parser->item_offset; - result = ftp_pl_insert_finfo(data, infop); - if(result) - break; - - parser->state.UNIX.main = PL_UNIX_FILETYPE; - } - break; - case PL_UNIX_SYMLINK_WINDOWSEOL: - if(c == '\n') { - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.symlink_target = parser->item_offset; - result = ftp_pl_insert_finfo(data, infop); - if(result) - break; - - parser->state.UNIX.main = PL_UNIX_FILETYPE; - } - else - result = CURLE_FTP_BAD_FILE_LIST; - - break; - } - return result; -} - -static CURLcode parse_unix(struct Curl_easy *data, - struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - struct curl_fileinfo *finfo = &infop->info; - CURLcode result = CURLE_OK; - - switch(parser->state.UNIX.main) { - case PL_UNIX_TOTALSIZE: - result = parse_unix_totalsize(parser, infop, c); - if(result) - break; - if(parser->state.UNIX.main != PL_UNIX_FILETYPE) - break; - FALLTHROUGH(); - case PL_UNIX_FILETYPE: - result = unix_filetype(c, &finfo->filetype); - if(!result) { - parser->state.UNIX.main = PL_UNIX_PERMISSION; - parser->item_length = 0; - parser->item_offset = 1; - } - break; - case PL_UNIX_PERMISSION: - result = parse_unix_permission(parser, infop, c); - break; - case PL_UNIX_HLINKS: - result = parse_unix_hlinks(parser, infop, c); - break; - case PL_UNIX_USER: - result = parse_unix_user(parser, infop, c); - break; - case PL_UNIX_GROUP: - result = parse_unix_group(parser, infop, c); - break; - case PL_UNIX_SIZE: - result = parse_unix_size(parser, infop, c); - break; - case PL_UNIX_TIME: - result = parse_unix_time(parser, infop, c); - break; - case PL_UNIX_FILENAME: - result = parse_unix_filename(data, parser, infop, c); - break; - case PL_UNIX_SYMLINK: - result = parse_unix_symlink(data, parser, infop, c); - break; - } - return result; -} - -static CURLcode parse_winnt(struct Curl_easy *data, - struct ftp_parselist_data *parser, - struct fileinfo *infop, - const char c) -{ - struct curl_fileinfo *finfo = &infop->info; - size_t len = curlx_dyn_len(&infop->buf); - char *mem = curlx_dyn_ptr(&infop->buf); - CURLcode result = CURLE_OK; - - switch(parser->state.NT.main) { - case PL_WINNT_DATE: - parser->item_length++; - if(parser->item_length < 9) { - if(!strchr("0123456789-", c)) { /* only simple control */ - return CURLE_FTP_BAD_FILE_LIST; - } - } - else if(parser->item_length == 9) { - if(c == ' ') { - parser->state.NT.main = PL_WINNT_TIME; - parser->state.NT.sub.time = PL_WINNT_TIME_PRESPACE; - } - else - return CURLE_FTP_BAD_FILE_LIST; - } - else - return CURLE_FTP_BAD_FILE_LIST; - break; - case PL_WINNT_TIME: - parser->item_length++; - switch(parser->state.NT.sub.time) { - case PL_WINNT_TIME_PRESPACE: - if(!ISBLANK(c)) - parser->state.NT.sub.time = PL_WINNT_TIME_TIME; - break; - case PL_WINNT_TIME_TIME: - if(c == ' ') { - parser->offsets.time = parser->item_offset; - mem[parser->item_offset + parser->item_length - 1] = 0; - parser->state.NT.main = PL_WINNT_DIRORSIZE; - parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_PRESPACE; - parser->item_length = 0; - } - else if(!strchr("APM0123456789:", c)) - return CURLE_FTP_BAD_FILE_LIST; - break; - } - break; - case PL_WINNT_DIRORSIZE: - switch(parser->state.NT.sub.dirorsize) { - case PL_WINNT_DIRORSIZE_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT; - } - break; - case PL_WINNT_DIRORSIZE_CONTENT: - parser->item_length++; - if(c == ' ') { - mem[parser->item_offset + parser->item_length - 1] = 0; - if(strcmp("", mem + parser->item_offset) == 0) { - finfo->filetype = CURLFILETYPE_DIRECTORY; - finfo->size = 0; - } - else { - const char *p = mem + parser->item_offset; - if(curlx_str_numblanks(&p, &finfo->size)) { - return CURLE_FTP_BAD_FILE_LIST; - } - /* correct file type */ - parser->file_data->info.filetype = CURLFILETYPE_FILE; - } - - parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE; - parser->item_length = 0; - parser->state.NT.main = PL_WINNT_FILENAME; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; - } - break; - } - break; - case PL_WINNT_FILENAME: - switch(parser->state.NT.sub.filename) { - case PL_WINNT_FILENAME_PRESPACE: - if(c != ' ' && len) { - parser->item_offset = len - 1; - parser->item_length = 1; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT; - } - break; - case PL_WINNT_FILENAME_CONTENT: - parser->item_length++; - if(!len) - return CURLE_FTP_BAD_FILE_LIST; - if(c == '\r') { - parser->state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL; - mem[len - 1] = 0; - } - else if(c == '\n') { - parser->offsets.filename = parser->item_offset; - mem[len - 1] = 0; - result = ftp_pl_insert_finfo(data, infop); - if(result) - return result; - - parser->state.NT.main = PL_WINNT_DATE; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; - } - break; - case PL_WINNT_FILENAME_WINEOL: - if(c == '\n') { - parser->offsets.filename = parser->item_offset; - result = ftp_pl_insert_finfo(data, infop); - if(result) - return result; - - parser->state.NT.main = PL_WINNT_DATE; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; - } - else - return CURLE_FTP_BAD_FILE_LIST; - - break; - } - break; - } - - return CURLE_OK; -} - -size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, - void *connptr) -{ - size_t bufflen = size * nmemb; - struct Curl_easy *data = (struct Curl_easy *)connptr; - struct ftp_wc *ftpwc = data->wildcard->ftpwc; - struct ftp_parselist_data *parser = ftpwc->parser; - size_t i = 0; - CURLcode result; - size_t retsize = bufflen; - - if(parser->error) { /* error in previous call */ - /* scenario: - * 1. call => OK.. - * 2. call => OUT_OF_MEMORY (or other error) - * 3. (last) call => is skipped RIGHT HERE and the error is handled later - * in wc_statemach() - */ - goto fail; - } - - if(parser->os_type == OS_TYPE_UNKNOWN && bufflen > 0) { - /* considering info about FILE response format */ - parser->os_type = ISDIGIT(buffer[0]) ? OS_TYPE_WIN_NT : OS_TYPE_UNIX; - } - - while(i < bufflen) { /* FSM */ - char c = buffer[i]; - struct fileinfo *infop; - if(!parser->file_data) { /* tmp file data is not allocated yet */ - parser->file_data = Curl_fileinfo_alloc(); - if(!parser->file_data) { - parser->error = CURLE_OUT_OF_MEMORY; - goto fail; - } - parser->item_offset = 0; - parser->item_length = 0; - curlx_dyn_init(&parser->file_data->buf, MAX_FTPLIST_BUFFER); - } - - infop = parser->file_data; - - if(curlx_dyn_addn(&infop->buf, &c, 1)) { - parser->error = CURLE_OUT_OF_MEMORY; - goto fail; - } - - switch(parser->os_type) { - case OS_TYPE_UNIX: - result = parse_unix(data, parser, infop, c); - break; - case OS_TYPE_WIN_NT: - result = parse_winnt(data, parser, infop, c); - break; - default: - retsize = bufflen + 1; - goto fail; - } - if(result) { - parser->error = result; - goto fail; - } - - i++; - } - return retsize; - -fail: - - /* Clean up any allocated memory. */ - if(parser->file_data) { - Curl_fileinfo_cleanup(parser->file_data); - parser->file_data = NULL; - } - - return retsize; -} - -#endif /* !CURL_DISABLE_FTP */ diff --git a/vendor/curl/lib/ftplistparser.h b/vendor/curl/lib/ftplistparser.h deleted file mode 100644 index 5d7aa492b..000000000 --- a/vendor/curl/lib/ftplistparser.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef HEADER_CURL_FTPLISTPARSER_H -#define HEADER_CURL_FTPLISTPARSER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP - -/* WRITEFUNCTION callback for parsing LIST responses */ -size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, - void *connptr); - -struct ftp_parselist_data; /* defined inside ftplibparser.c */ - -CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data); - -struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void); - -void Curl_ftp_parselist_data_free(struct ftp_parselist_data **parserp); - -/* list of wildcard process states */ -typedef enum { - CURLWC_CLEAR = 0, - CURLWC_INIT = 1, - CURLWC_MATCHING, /* library is trying to get list of addresses for - downloading */ - CURLWC_DOWNLOADING, - CURLWC_CLEAN, /* deallocate resources and reset settings */ - CURLWC_SKIP, /* skip over concrete file */ - CURLWC_ERROR, /* error cases */ - CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop - will end */ -} wildcard_states; - -typedef void (*wildcard_dtor)(void *ptr); - -/* struct keeping information about wildcard download process */ -struct WildcardData { - char *path; /* path to the directory, where we trying wildcard-match */ - char *pattern; /* wildcard pattern */ - struct Curl_llist filelist; /* llist with struct Curl_fileinfo */ - struct ftp_wc *ftpwc; /* pointer to FTP wildcard data */ - wildcard_dtor dtor; - unsigned char state; /* wildcard_states */ -}; - -void Curl_wildcard_init(struct WildcardData *wc); -void Curl_wildcard_dtor(struct WildcardData **wcp); - -struct Curl_easy; - -#else /* CURL_DISABLE_FTP */ -#define Curl_wildcard_dtor(x) -#endif /* !CURL_DISABLE_FTP */ - -#endif /* HEADER_CURL_FTPLISTPARSER_H */ diff --git a/vendor/curl/lib/functypes.h b/vendor/curl/lib/functypes.h deleted file mode 100644 index 887c2612e..000000000 --- a/vendor/curl/lib/functypes.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef HEADER_CURL_FUNCTYPES_H -#define HEADER_CURL_FUNCTYPES_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* defaults: - - ssize_t recv(int, void *, size_t, int); - ssize_t send(int, const void *, size_t, int); - - If other argument or return types are needed: - - 1. For systems that run configure or cmake, the alternatives are provided - here. - 2. For systems with config-*.h files, define them there. -*/ - -#ifdef USE_WINSOCK -/* int recv(SOCKET, char *, int, int) */ -#define RECV_TYPE_ARG1 SOCKET -#define RECV_TYPE_ARG2 char * -#define RECV_TYPE_ARG3 int -#define RECV_TYPE_RETV int - -/* int send(SOCKET, const char *, int, int); */ -#define SEND_TYPE_ARG1 SOCKET -#define SEND_TYPE_ARG2 char * -#define SEND_TYPE_ARG3 int -#define SEND_TYPE_RETV int - -#elif defined(__AMIGA__) /* Any AmigaOS flavour */ - -/* long recv(long, char *, long, long); */ -#define RECV_TYPE_ARG1 long -#define RECV_TYPE_ARG2 char * -#define RECV_TYPE_ARG3 long -#define RECV_TYPE_ARG4 long -#define RECV_TYPE_RETV long - -/* int send(int, char *, int, int); */ -#define SEND_TYPE_ARG1 int -#define SEND_NONCONST_ARG2 -#define SEND_TYPE_ARG2 char * -#define SEND_TYPE_ARG3 int -#define SEND_TYPE_RETV int -#endif - -#ifndef RECV_TYPE_ARG1 -#define RECV_TYPE_ARG1 int -#endif - -#ifndef RECV_TYPE_ARG2 -#define RECV_TYPE_ARG2 void * -#endif - -#ifndef RECV_TYPE_ARG3 -#define RECV_TYPE_ARG3 size_t -#endif - -#ifndef RECV_TYPE_ARG4 -#define RECV_TYPE_ARG4 int -#endif - -#ifndef RECV_TYPE_RETV -#define RECV_TYPE_RETV ssize_t -#endif - -#ifndef SEND_TYPE_ARG1 -#define SEND_TYPE_ARG1 int -#endif - -#ifndef SEND_TYPE_ARG2 -#define SEND_TYPE_ARG2 void * -#endif - -#ifndef SEND_TYPE_ARG3 -#define SEND_TYPE_ARG3 size_t -#endif - -#ifndef SEND_TYPE_ARG4 -#define SEND_TYPE_ARG4 int -#endif - -#ifndef SEND_TYPE_RETV -#define SEND_TYPE_RETV ssize_t -#endif - -#endif /* HEADER_CURL_FUNCTYPES_H */ diff --git a/vendor/curl/lib/getenv.c b/vendor/curl/lib/getenv.c deleted file mode 100644 index a957e6e80..000000000 --- a/vendor/curl/lib/getenv.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -char *curl_getenv(const char *variable) -{ -#if defined(CURL_WINDOWS_UWP) || \ - defined(__ORBIS__) || defined(__PROSPERO__) /* PlayStation 4 and 5 */ - (void)variable; - return NULL; -#elif defined(_WIN32) - /* This uses Windows API instead of C runtime getenv() to get the environment - variable since some changes are not always visible to the latter. #4774 */ - char *buf = NULL; - char *tmp; - DWORD bufsize; - DWORD rc = 1; - const DWORD max = 32768; /* max env var size from MSCRT source */ - - for(;;) { - tmp = curlx_realloc(buf, rc); - if(!tmp) { - curlx_free(buf); - return NULL; - } - - buf = tmp; - bufsize = rc; - - /* it is possible for rc to be 0 if the variable was found but empty. - Since getenv does not make that distinction we ignore it as well. */ - rc = GetEnvironmentVariableA(variable, buf, bufsize); - if(!rc || rc == bufsize || rc > max) { - curlx_free(buf); - return NULL; - } - - /* if rc < bufsize then rc is bytes written not including null */ - if(rc < bufsize) - return buf; - - /* else rc is bytes needed, try again */ - } -#else - char *env = getenv(variable); - return (env && env[0]) ? curlx_strdup(env) : NULL; -#endif -} diff --git a/vendor/curl/lib/getinfo.c b/vendor/curl/lib/getinfo.c deleted file mode 100644 index fab63e669..000000000 --- a/vendor/curl/lib/getinfo.c +++ /dev/null @@ -1,682 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "getinfo.h" -#include "cfilters.h" -#include "vtls/vtls.h" -#include "connect.h" /* Curl_getconnectinfo() */ -#include "bufref.h" -#include "curlx/strparse.h" - -/* - * Initialize statistical and informational data. - * - * This function is called in curl_easy_reset, curl_easy_duphandle and at the - * beginning of a perform session. It must reset the session-info variables, - * in particular all variables in struct PureInfo. - */ -void Curl_initinfo(struct Curl_easy *data) -{ - struct Progress *pro = &data->progress; - struct PureInfo *info = &data->info; - - pro->t_nslookup = 0; - pro->t_connect = 0; - pro->t_appconnect = 0; - pro->t_pretransfer = 0; - pro->t_posttransfer = 0; - pro->t_starttransfer = 0; - pro->timespent = 0; - pro->t_redirect = 0; - pro->is_t_startransfer_set = FALSE; - - info->httpcode = 0; - info->httpproxycode = 0; - info->httpversion = 0; - info->filetime = -1; /* -1 is an illegal time and thus means unknown */ - info->timecond = FALSE; - - info->header_size = 0; - info->request_size = 0; - info->proxyauthavail = 0; - info->httpauthavail = 0; - info->proxyauthpicked = 0; - info->httpauthpicked = 0; - info->numconnects = 0; - - curlx_free(info->contenttype); - info->contenttype = NULL; - - curlx_free(info->wouldredirect); - info->wouldredirect = NULL; - - memset(&info->primary, 0, sizeof(info->primary)); - info->retry_after = 0; - - info->conn_scheme = 0; - info->conn_protocol = 0; - info->used_proxy = 0; - -#ifdef USE_SSL - Curl_ssl_free_certinfo(data); -#endif -} - -static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info, - const char **param_charp) -{ - switch(info) { - case CURLINFO_EFFECTIVE_URL: { - const char *s = Curl_bufref_ptr(&data->state.url); - *param_charp = s ? s : ""; - } - break; - case CURLINFO_EFFECTIVE_METHOD: { - const char *m = data->set.str[STRING_CUSTOMREQUEST]; - if(!m) { - if(data->set.opt_no_body) - m = "HEAD"; -#ifndef CURL_DISABLE_HTTP - else { - switch(data->state.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - m = "POST"; - break; - case HTTPREQ_PUT: - m = "PUT"; - break; - default: /* this should never happen */ - case HTTPREQ_GET: - m = "GET"; - break; - case HTTPREQ_HEAD: - m = "HEAD"; - break; - } - } -#endif - } - *param_charp = m; - } - break; - case CURLINFO_CONTENT_TYPE: - *param_charp = data->info.contenttype; - break; - case CURLINFO_PRIVATE: - *param_charp = (const char *)data->set.private_data; - break; - case CURLINFO_FTP_ENTRY_PATH: - /* Return the entrypath string from the most recent connection. - This pointer was copied from the connectdata structure by FTP. - The actual string may be freed by subsequent libcurl calls so - it must be copied to a safer area before the next libcurl call. - Callers must never free it themselves. */ - *param_charp = data->state.most_recent_ftp_entrypath; - break; - case CURLINFO_REDIRECT_URL: - /* Return the URL this request would have been redirected to if that - option had been enabled! */ - *param_charp = data->info.wouldredirect; - break; - case CURLINFO_REFERER: - /* Return the referrer header for this request, or NULL if unset */ - *param_charp = Curl_bufref_ptr(&data->state.referer); - break; - case CURLINFO_PRIMARY_IP: - /* Return the ip address of the most recent (primary) connection */ - *param_charp = data->info.primary.remote_ip; - break; - case CURLINFO_LOCAL_IP: - /* Return the source/local ip address of the most recent (primary) - connection */ - *param_charp = data->info.primary.local_ip; - break; - case CURLINFO_RTSP_SESSION_ID: -#ifndef CURL_DISABLE_RTSP - *param_charp = data->set.str[STRING_RTSP_SESSION_ID]; -#else - *param_charp = NULL; -#endif - break; - case CURLINFO_SCHEME: - *param_charp = data->info.conn_scheme; - break; - case CURLINFO_CAPATH: -#ifdef CURL_CA_PATH - *param_charp = CURL_CA_PATH; -#else - *param_charp = NULL; -#endif - break; - case CURLINFO_CAINFO: -#ifdef CURL_CA_BUNDLE - *param_charp = CURL_CA_BUNDLE; -#else - *param_charp = NULL; -#endif - break; - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, - long *param_longp) -{ - curl_socket_t sockfd; - - union { - unsigned long *to_ulong; - long *to_long; - } lptr; - -#ifdef DEBUGBUILD - const char *envstr; - - /* use another variable for this to allow different values */ - switch(info) { - case CURLINFO_LOCAL_PORT: - envstr = getenv("CURL_TIME"); - if(envstr) { - curl_off_t val; - curlx_str_number(&envstr, &val, TIME_T_MAX); - *param_longp = (long)val; - return CURLE_OK; - } - break; - case CURLINFO_HEADER_SIZE: - case CURLINFO_REQUEST_SIZE: - envstr = getenv("CURL_DEBUG_SIZE"); - if(envstr) { - curl_off_t val; - curlx_str_number(&envstr, &val, LONG_MAX); - *param_longp = (long)val; - return CURLE_OK; - } - break; - default: - break; - } -#endif - - switch(info) { - case CURLINFO_RESPONSE_CODE: - *param_longp = data->info.httpcode; - break; - case CURLINFO_HTTP_CONNECTCODE: - *param_longp = data->info.httpproxycode; - break; - case CURLINFO_FILETIME: - if(data->info.filetime > LONG_MAX) - *param_longp = LONG_MAX; -#if !defined(MSDOS) && !defined(__AMIGA__) - else if(data->info.filetime < LONG_MIN) - *param_longp = LONG_MIN; -#endif - else - *param_longp = (long)data->info.filetime; - break; - case CURLINFO_HEADER_SIZE: - *param_longp = (long)data->info.header_size; - break; - case CURLINFO_REQUEST_SIZE: - *param_longp = (long)data->info.request_size; - break; - case CURLINFO_SSL_VERIFYRESULT: - *param_longp = data->set.ssl.certverifyresult; - break; - case CURLINFO_PROXY_SSL_VERIFYRESULT: -#ifndef CURL_DISABLE_PROXY - *param_longp = data->set.proxy_ssl.certverifyresult; -#else - *param_longp = 0; -#endif - break; - case CURLINFO_REDIRECT_COUNT: - *param_longp = data->state.followlocation; - break; - case CURLINFO_HTTPAUTH_AVAIL: - lptr.to_long = param_longp; - *lptr.to_ulong = data->info.httpauthavail; - break; - case CURLINFO_PROXYAUTH_AVAIL: - lptr.to_long = param_longp; - *lptr.to_ulong = data->info.proxyauthavail; - break; - case CURLINFO_HTTPAUTH_USED: - lptr.to_long = param_longp; - *lptr.to_ulong = data->info.httpauthpicked; - break; - case CURLINFO_PROXYAUTH_USED: - lptr.to_long = param_longp; - *lptr.to_ulong = data->info.proxyauthpicked; - break; - case CURLINFO_OS_ERRNO: - *param_longp = data->state.os_errno; - break; - case CURLINFO_NUM_CONNECTS: -#if SIZEOF_LONG < SIZEOF_CURL_OFF_T - if(data->info.numconnects > LONG_MAX) - *param_longp = LONG_MAX; - else -#endif - *param_longp = (long)data->info.numconnects; - break; - case CURLINFO_LASTSOCKET: - sockfd = Curl_getconnectinfo(data, NULL); - - /* note: this is not a good conversion for systems with 64-bit sockets and - 32-bit longs */ - if(sockfd != CURL_SOCKET_BAD) - *param_longp = (long)sockfd; - else - /* this interface is documented to return -1 in case of badness, which - may not be the same as the CURL_SOCKET_BAD value */ - *param_longp = -1; - break; - case CURLINFO_PRIMARY_PORT: - /* Return the (remote) port of the most recent (primary) connection */ - if(CUR_IP_QUAD_HAS_PORTS(&data->info.primary)) - *param_longp = data->info.primary.remote_port; - else - *param_longp = -1; - break; - case CURLINFO_LOCAL_PORT: - /* Return the local port of the most recent (primary) connection */ - if(CUR_IP_QUAD_HAS_PORTS(&data->info.primary)) - *param_longp = data->info.primary.local_port; - else - *param_longp = -1; - break; - case CURLINFO_PROXY_ERROR: - *param_longp = (long)data->info.pxcode; - break; - case CURLINFO_CONDITION_UNMET: - if(data->info.httpcode == 304) - *param_longp = 1L; - else - /* return if the condition prevented the document to get transferred */ - *param_longp = data->info.timecond ? 1L : 0L; - break; -#ifndef CURL_DISABLE_RTSP - case CURLINFO_RTSP_CLIENT_CSEQ: - *param_longp = data->state.rtsp_next_client_CSeq; - break; - case CURLINFO_RTSP_SERVER_CSEQ: - *param_longp = data->state.rtsp_next_server_CSeq; - break; - case CURLINFO_RTSP_CSEQ_RECV: - *param_longp = data->state.rtsp_CSeq_recv; - break; -#else - case CURLINFO_RTSP_CLIENT_CSEQ: - case CURLINFO_RTSP_SERVER_CSEQ: - case CURLINFO_RTSP_CSEQ_RECV: - *param_longp = 0; - break; -#endif - case CURLINFO_HTTP_VERSION: - switch(data->info.httpversion) { - case 10: - *param_longp = CURL_HTTP_VERSION_1_0; - break; - case 11: - *param_longp = CURL_HTTP_VERSION_1_1; - break; - case 20: - *param_longp = CURL_HTTP_VERSION_2_0; - break; - case 30: - *param_longp = CURL_HTTP_VERSION_3; - break; - default: - *param_longp = CURL_HTTP_VERSION_NONE; - break; - } - break; - case CURLINFO_PROTOCOL: - *param_longp = (long)data->info.conn_protocol; - break; - case CURLINFO_USED_PROXY: - *param_longp = -#ifdef CURL_DISABLE_PROXY - 0 -#else - data->info.used_proxy -#endif - ; - break; - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -#define DOUBLE_SECS(x) ((double)(x) / 1000000) - -static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, - curl_off_t *param_offt) -{ -#ifdef DEBUGBUILD - const char *envstr; - switch(info) { - case CURLINFO_TOTAL_TIME_T: - case CURLINFO_NAMELOOKUP_TIME_T: - case CURLINFO_CONNECT_TIME_T: - case CURLINFO_APPCONNECT_TIME_T: - case CURLINFO_PRETRANSFER_TIME_T: - case CURLINFO_POSTTRANSFER_TIME_T: - case CURLINFO_QUEUE_TIME_T: - case CURLINFO_STARTTRANSFER_TIME_T: - case CURLINFO_REDIRECT_TIME_T: - case CURLINFO_SPEED_DOWNLOAD_T: - case CURLINFO_SPEED_UPLOAD_T: - envstr = getenv("CURL_TIME"); - if(envstr) { - curl_off_t val; - curlx_str_number(&envstr, &val, CURL_OFF_T_MAX); - *param_offt = (curl_off_t)val; - return CURLE_OK; - } - break; - default: - break; - } -#endif - switch(info) { - case CURLINFO_FILETIME_T: - *param_offt = (curl_off_t)data->info.filetime; - break; - case CURLINFO_SIZE_DELIVERED: - *param_offt = data->progress.deliver; - break; - case CURLINFO_SIZE_UPLOAD_T: - *param_offt = data->progress.ul.cur_size; - break; - case CURLINFO_SIZE_DOWNLOAD_T: - *param_offt = data->progress.dl.cur_size; - break; - case CURLINFO_SPEED_DOWNLOAD_T: - *param_offt = data->progress.dl.speed; - break; - case CURLINFO_SPEED_UPLOAD_T: - *param_offt = data->progress.ul.speed; - break; - case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T: - *param_offt = data->progress.dl_size_known ? - data->progress.dl.total_size : -1; - break; - case CURLINFO_CONTENT_LENGTH_UPLOAD_T: - *param_offt = data->progress.ul_size_known ? - data->progress.ul.total_size : -1; - break; - case CURLINFO_TOTAL_TIME_T: - *param_offt = data->progress.timespent; - break; - case CURLINFO_NAMELOOKUP_TIME_T: - *param_offt = data->progress.t_nslookup; - break; - case CURLINFO_CONNECT_TIME_T: - *param_offt = data->progress.t_connect; - break; - case CURLINFO_APPCONNECT_TIME_T: - *param_offt = data->progress.t_appconnect; - break; - case CURLINFO_PRETRANSFER_TIME_T: - *param_offt = data->progress.t_pretransfer; - break; - case CURLINFO_POSTTRANSFER_TIME_T: - *param_offt = data->progress.t_posttransfer; - break; - case CURLINFO_STARTTRANSFER_TIME_T: - *param_offt = data->progress.t_starttransfer; - break; - case CURLINFO_QUEUE_TIME_T: - *param_offt = data->progress.t_postqueue; - break; - case CURLINFO_REDIRECT_TIME_T: - *param_offt = data->progress.t_redirect; - break; - case CURLINFO_RETRY_AFTER: - *param_offt = data->info.retry_after; - break; - case CURLINFO_XFER_ID: - *param_offt = data->id; - break; - case CURLINFO_CONN_ID: - *param_offt = data->conn ? - data->conn->connection_id : data->state.recent_conn_id; - break; - case CURLINFO_EARLYDATA_SENT_T: - *param_offt = data->progress.earlydata_sent; - break; - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info, - double *param_doublep) -{ -#ifdef DEBUGBUILD - const char *envstr; - - switch(info) { - case CURLINFO_TOTAL_TIME: - case CURLINFO_NAMELOOKUP_TIME: - case CURLINFO_CONNECT_TIME: - case CURLINFO_APPCONNECT_TIME: - case CURLINFO_PRETRANSFER_TIME: - case CURLINFO_STARTTRANSFER_TIME: - case CURLINFO_REDIRECT_TIME: - case CURLINFO_SPEED_DOWNLOAD: - case CURLINFO_SPEED_UPLOAD: - envstr = getenv("CURL_TIME"); - if(envstr) { - curl_off_t val; - curlx_str_number(&envstr, &val, CURL_OFF_T_MAX); - *param_doublep = (double)val; - return CURLE_OK; - } - break; - default: - break; - } -#endif - switch(info) { - case CURLINFO_TOTAL_TIME: - *param_doublep = DOUBLE_SECS(data->progress.timespent); - break; - case CURLINFO_NAMELOOKUP_TIME: - *param_doublep = DOUBLE_SECS(data->progress.t_nslookup); - break; - case CURLINFO_CONNECT_TIME: - *param_doublep = DOUBLE_SECS(data->progress.t_connect); - break; - case CURLINFO_APPCONNECT_TIME: - *param_doublep = DOUBLE_SECS(data->progress.t_appconnect); - break; - case CURLINFO_PRETRANSFER_TIME: - *param_doublep = DOUBLE_SECS(data->progress.t_pretransfer); - break; - case CURLINFO_STARTTRANSFER_TIME: - *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer); - break; - case CURLINFO_SIZE_UPLOAD: - *param_doublep = (double)data->progress.ul.cur_size; - break; - case CURLINFO_SIZE_DOWNLOAD: - *param_doublep = (double)data->progress.dl.cur_size; - break; - case CURLINFO_SPEED_DOWNLOAD: - *param_doublep = (double)data->progress.dl.speed; - break; - case CURLINFO_SPEED_UPLOAD: - *param_doublep = (double)data->progress.ul.speed; - break; - case CURLINFO_CONTENT_LENGTH_DOWNLOAD: - *param_doublep = data->progress.dl_size_known ? - (double)data->progress.dl.total_size : -1; - break; - case CURLINFO_CONTENT_LENGTH_UPLOAD: - *param_doublep = data->progress.ul_size_known ? - (double)data->progress.ul.total_size : -1; - break; - case CURLINFO_REDIRECT_TIME: - *param_doublep = DOUBLE_SECS(data->progress.t_redirect); - break; - - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info, - struct curl_slist **param_slistp) -{ - union { - struct curl_certinfo *to_certinfo; - struct curl_slist *to_slist; - } ptr; - - switch(info) { - case CURLINFO_SSL_ENGINES: - *param_slistp = Curl_ssl_engines_list(data); - break; - case CURLINFO_COOKIELIST: - *param_slistp = Curl_cookie_list(data); - break; - case CURLINFO_CERTINFO: - /* Return the a pointer to the certinfo struct. Not really an slist - pointer but we can pretend it is here */ - ptr.to_certinfo = &data->info.certs; - *param_slistp = ptr.to_slist; - break; - case CURLINFO_TLS_SESSION: - case CURLINFO_TLS_SSL_PTR: { - int query = (info == CURLINFO_TLS_SSL_PTR) ? - CF_QUERY_SSL_INFO : CF_QUERY_SSL_CTX_INFO; - struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **) - param_slistp; - struct curl_tlssessioninfo *tsi = &data->tsi; - - /* we are exposing a pointer to internal memory with unknown - * lifetime here. */ - *tsip = tsi; - if(!Curl_conn_get_ssl_info(data, data->conn, FIRSTSOCKET, query, tsi)) { - tsi->backend = Curl_ssl_backend(); - tsi->internals = NULL; - } - } - break; - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info, - curl_socket_t *param_socketp) -{ - switch(info) { - case CURLINFO_ACTIVESOCKET: - *param_socketp = Curl_getconnectinfo(data, NULL); - break; - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...) -{ - va_list arg; - long *param_longp = NULL; - double *param_doublep = NULL; - curl_off_t *param_offt = NULL; - const char **param_charp = NULL; - struct curl_slist **param_slistp = NULL; - curl_socket_t *param_socketp = NULL; - int type; - CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - va_start(arg, info); - - type = CURLINFO_TYPEMASK & (int)info; - switch(type) { - case CURLINFO_STRING: - param_charp = va_arg(arg, const char **); - if(param_charp) - result = getinfo_char(data, info, param_charp); - break; - case CURLINFO_LONG: - param_longp = va_arg(arg, long *); - if(param_longp) - result = getinfo_long(data, info, param_longp); - break; - case CURLINFO_DOUBLE: - param_doublep = va_arg(arg, double *); - if(param_doublep) - result = getinfo_double(data, info, param_doublep); - break; - case CURLINFO_OFF_T: - param_offt = va_arg(arg, curl_off_t *); - if(param_offt) - result = getinfo_offt(data, info, param_offt); - break; - case CURLINFO_SLIST: - param_slistp = va_arg(arg, struct curl_slist **); - if(param_slistp) - result = getinfo_slist(data, info, param_slistp); - break; - case CURLINFO_SOCKET: - param_socketp = va_arg(arg, curl_socket_t *); - if(param_socketp) - result = getinfo_socket(data, info, param_socketp); - break; - default: - result = CURLE_UNKNOWN_OPTION; - break; - } - - va_end(arg); - - return result; -} diff --git a/vendor/curl/lib/getinfo.h b/vendor/curl/lib/getinfo.h deleted file mode 100644 index f5efe4185..000000000 --- a/vendor/curl/lib/getinfo.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HEADER_CURL_GETINFO_H -#define HEADER_CURL_GETINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...); -void Curl_initinfo(struct Curl_easy *data); - -#endif /* HEADER_CURL_GETINFO_H */ diff --git a/vendor/curl/lib/gopher.c b/vendor/curl/lib/gopher.c deleted file mode 100644 index f087121d0..000000000 --- a/vendor/curl/lib/gopher.c +++ /dev/null @@ -1,217 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "gopher.h" - -#ifndef CURL_DISABLE_GOPHER - -#include "transfer.h" -#include "sendf.h" -#include "curl_trc.h" -#include "cfilters.h" -#include "connect.h" -#include "select.h" -#include "url.h" -#include "escape.h" - -#ifdef USE_SSL -static CURLcode gopher_connect(struct Curl_easy *data, bool *done) -{ - (void)data; - (void)done; - return CURLE_OK; -} - -static CURLcode gopher_connecting(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - CURLcode result; - - result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done); - if(result) - connclose(conn, "Failed TLS connection"); - *done = TRUE; - return result; -} -#endif - -static CURLcode gopher_do(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - char *gopherpath; - const char *path = data->state.up.path; - const char *query = data->state.up.query; - const char *buf = NULL; - char *buf_alloc = NULL; - size_t nwritten, buf_len; - timediff_t timeout_ms; - int what; - - *done = TRUE; /* unconditionally */ - - /* path is guaranteed non-NULL */ - DEBUGASSERT(path); - - if(query) - gopherpath = curl_maprintf("%s?%s", path, query); - else - gopherpath = curlx_strdup(path); - - if(!gopherpath) - return CURLE_OUT_OF_MEMORY; - - /* Create selector. Degenerate cases: / and /1 => convert to "" */ - if(strlen(gopherpath) <= 2) { - buf = ""; - buf_len = 0; - curlx_free(gopherpath); - } - else { - const char *newp; - - /* Otherwise, drop / and the first character (i.e., item type) ... */ - newp = gopherpath; - newp += 2; - - /* ... and finally unescape */ - result = Curl_urldecode(newp, 0, &buf_alloc, &buf_len, REJECT_ZERO); - curlx_free(gopherpath); - if(result) - return result; - buf = buf_alloc; - } - - for(; buf_len;) { - - result = Curl_xfer_send(data, buf, buf_len, FALSE, &nwritten); - if(!result) { /* Which may not have written it all! */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, buf, nwritten); - if(result) - break; - - if(nwritten > buf_len) { - DEBUGASSERT(0); - break; - } - buf_len -= nwritten; - buf += nwritten; - if(!buf_len) - break; /* but it did write it all */ - } - else - break; - - timeout_ms = Curl_timeleft_ms(data); - if(timeout_ms < 0) { - result = CURLE_OPERATION_TIMEDOUT; - break; - } - if(!timeout_ms) - timeout_ms = TIMEDIFF_T_MAX; - - /* Do not busyloop. The entire loop thing is a work-around as it causes a - BLOCKING behavior which is a NO-NO. This function should rather be - split up in a do and a doing piece where the pieces that are not - possible to send now will be sent in the doing function repeatedly - until the entire request is sent. - */ - what = SOCKET_WRITABLE(sockfd, timeout_ms); - if(what < 0) { - result = CURLE_SEND_ERROR; - break; - } - else if(!what) { - result = CURLE_OPERATION_TIMEDOUT; - break; - } - } - - curlx_free(buf_alloc); - - if(!result) - result = Curl_xfer_send(data, "\r\n", 2, FALSE, &nwritten); - if(result) { - failf(data, "Failed sending Gopher request"); - return result; - } - result = Curl_client_write(data, CLIENTWRITE_HEADER, "\r\n", 2); - if(result) - return result; - - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); - return CURLE_OK; -} - -/* - * Gopher protocol handler. - * This is also a nice simple template to build off for simple - * connect-command-download protocols. - */ - -const struct Curl_protocol Curl_protocol_gopher = { - ZERO_NULL, /* setup_connection */ - gopher_do, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - ZERO_NULL, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#ifdef USE_SSL -const struct Curl_protocol Curl_protocol_gophers = { - ZERO_NULL, /* setup_connection */ - gopher_do, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - gopher_connect, /* connect_it */ - gopher_connecting, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - ZERO_NULL, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; -#endif - -#endif /* CURL_DISABLE_GOPHER */ diff --git a/vendor/curl/lib/gopher.h b/vendor/curl/lib/gopher.h deleted file mode 100644 index 1c126be16..000000000 --- a/vendor/curl/lib/gopher.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_GOPHER_H -#define HEADER_CURL_GOPHER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_GOPHER -extern const struct Curl_protocol Curl_protocol_gopher; -extern const struct Curl_protocol Curl_protocol_gophers; -#endif - -#endif /* HEADER_CURL_GOPHER_H */ diff --git a/vendor/curl/lib/hash.c b/vendor/curl/lib/hash.c deleted file mode 100644 index 3eae1d26a..000000000 --- a/vendor/curl/lib/hash.c +++ /dev/null @@ -1,388 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "hash.h" - -/* random patterns for API verification */ -#ifdef DEBUGBUILD -#define HASHINIT 0x7017e781 -#define ITERINIT 0x5FEDCBA9 -#endif - -#if 0 /* useful function for debugging hashes and their contents */ -void Curl_hash_print(struct Curl_hash *h, void (*func)(void *)) -{ - struct Curl_hash_iterator iter; - struct Curl_hash_element *he; - size_t last_index = UINT_MAX; - - if(!h) - return; - - curl_mfprintf(stderr, "=Hash dump=\n"); - - Curl_hash_start_iterate(h, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - if(iter.slot_index != last_index) { - curl_mfprintf(stderr, "index %d:", (int)iter.slot_index); - if(last_index != UINT_MAX) { - curl_mfprintf(stderr, "\n"); - } - last_index = iter.slot_index; - } - - if(func) - func(he->ptr); - else - curl_mfprintf(stderr, " [key=%.*s, he=%p, ptr=%p]", - (int)he->key_len, (char *)he->key, - (void *)he, (void *)he->ptr); - - he = Curl_hash_next_element(&iter); - } - curl_mfprintf(stderr, "\n"); -} -#endif - -/* Initializes a hash structure. - * Return 1 on error, 0 is fine. - * - * @unittest: 1602 - * @unittest: 1603 - */ -void Curl_hash_init(struct Curl_hash *h, - size_t slots, - hash_function hfunc, - comp_function comparator, - Curl_hash_dtor dtor) -{ - DEBUGASSERT(h); - DEBUGASSERT(slots); - DEBUGASSERT(hfunc); - DEBUGASSERT(comparator); - DEBUGASSERT(dtor); - - h->table = NULL; - h->hash_func = hfunc; - h->comp_func = comparator; - h->dtor = dtor; - h->size = 0; - h->slots = slots; -#ifdef DEBUGBUILD - h->init = HASHINIT; -#endif -} - -static struct Curl_hash_element *hash_elem_create(const void *key, - size_t key_len, - const void *p, - Curl_hash_elem_dtor dtor) -{ - struct Curl_hash_element *he; - - /* allocate the struct plus memory after it to store the key */ - he = curlx_malloc(sizeof(struct Curl_hash_element) + key_len); - if(he) { - he->next = NULL; - /* copy the key */ - memcpy(he->key, key, key_len); - he->key_len = key_len; - he->ptr = CURL_UNCONST(p); - he->dtor = dtor; - } - return he; -} - -static void hash_elem_clear_ptr(struct Curl_hash *h, - struct Curl_hash_element *he) -{ - DEBUGASSERT(h); - DEBUGASSERT(he); - if(he->ptr) { - if(he->dtor) - he->dtor(he->key, he->key_len, he->ptr); - else - h->dtor(he->ptr); - he->ptr = NULL; - } -} - -static void hash_elem_destroy(struct Curl_hash *h, - struct Curl_hash_element *he) -{ - hash_elem_clear_ptr(h, he); - curlx_free(he); -} - -static void hash_elem_unlink(struct Curl_hash *h, - struct Curl_hash_element **he_anchor, - struct Curl_hash_element *he) -{ - *he_anchor = he->next; - --h->size; -} - -static void hash_elem_link(struct Curl_hash *h, - struct Curl_hash_element **he_anchor, - struct Curl_hash_element *he) -{ - he->next = *he_anchor; - *he_anchor = he; - ++h->size; -} - -#define CURL_HASH_SLOT(x, y, z) x->table[(x)->hash_func(y, z, (x)->slots)] -#define CURL_HASH_SLOT_ADDR(x, y, z) &CURL_HASH_SLOT(x, y, z) - -void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p, - Curl_hash_elem_dtor dtor) -{ - struct Curl_hash_element *he, **slot; - - DEBUGASSERT(h); - DEBUGASSERT(h->slots); - DEBUGASSERT(h->init == HASHINIT); - if(!h->table) { - h->table = curlx_calloc(h->slots, sizeof(struct Curl_hash_element *)); - if(!h->table) - return NULL; /* OOM */ - } - - slot = CURL_HASH_SLOT_ADDR(h, key, key_len); - for(he = *slot; he; he = he->next) { - if(h->comp_func(he->key, he->key_len, key, key_len)) { - /* existing key entry, overwrite by clearing old pointer */ - hash_elem_clear_ptr(h, he); - he->ptr = p; - he->dtor = dtor; - return p; - } - } - - he = hash_elem_create(key, key_len, p, dtor); - if(!he) - return NULL; /* OOM */ - - hash_elem_link(h, slot, he); - return p; /* return the new entry */ -} - -/* Insert the data in the hash. If there already was a match in the hash, that - * data is replaced. This function also "lazily" allocates the table if - * needed, as it is not done in the _init function (anymore). - * - * @unittest: 1305 - * @unittest: 1602 - * @unittest: 1603 - */ -void *Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p) -{ - return Curl_hash_add2(h, key, key_len, p, NULL); -} - -/* Remove the identified hash entry. - * Returns non-zero on failure. - * - * @unittest: 1603 - */ -int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len) -{ - DEBUGASSERT(h); - DEBUGASSERT(h->slots); - DEBUGASSERT(h->init == HASHINIT); - if(h->table) { - struct Curl_hash_element *he, **he_anchor; - - he_anchor = CURL_HASH_SLOT_ADDR(h, key, key_len); - while(*he_anchor) { - he = *he_anchor; - if(h->comp_func(he->key, he->key_len, key, key_len)) { - hash_elem_unlink(h, he_anchor, he); - hash_elem_destroy(h, he); - return 0; - } - he_anchor = &he->next; - } - } - return 1; -} - -/* Retrieves a hash element. - * - * @unittest: 1603 - */ -void *Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len) -{ - DEBUGASSERT(h); - DEBUGASSERT(h->init == HASHINIT); - if(h->table) { - struct Curl_hash_element *he; - DEBUGASSERT(h->slots); - he = CURL_HASH_SLOT(h, key, key_len); - while(he) { - if(h->comp_func(he->key, he->key_len, key, key_len)) { - return he->ptr; - } - he = he->next; - } - } - return NULL; -} - -/* Destroys all the entries in the given hash and resets its attributes, - * prepping the given hash for [static|dynamic] deallocation. - * - * @unittest: 1305 - * @unittest: 1602 - * @unittest: 1603 - */ -void Curl_hash_destroy(struct Curl_hash *h) -{ - DEBUGASSERT(h->init == HASHINIT); - if(h->table) { - Curl_hash_clean(h); - curlx_safefree(h->table); - } - DEBUGASSERT(h->size == 0); - h->slots = 0; -} - -/* Removes all the entries in the given hash. - * - * @unittest: 1602 - */ -void Curl_hash_clean(struct Curl_hash *h) -{ - if(h && h->table) { - struct Curl_hash_element *he, **he_anchor; - size_t i; - DEBUGASSERT(h->init == HASHINIT); - for(i = 0; i < h->slots; ++i) { - he_anchor = &h->table[i]; - while(*he_anchor) { - he = *he_anchor; - hash_elem_unlink(h, he_anchor, he); - hash_elem_destroy(h, he); - } - } - } -} - -size_t Curl_hash_count(struct Curl_hash *h) -{ - DEBUGASSERT(h->init == HASHINIT); - return h->size; -} - -/* Cleans all entries that pass the comp function criteria. */ -void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, - int (*comp)(void *, void *)) -{ - size_t i; - - if(!h || !h->table) - return; - - DEBUGASSERT(h->init == HASHINIT); - for(i = 0; i < h->slots; ++i) { - struct Curl_hash_element *he, **he_anchor = &h->table[i]; - while(*he_anchor) { - /* ask the callback function if we shall remove this entry or not */ - if(!comp || comp(user, (*he_anchor)->ptr)) { - he = *he_anchor; - hash_elem_unlink(h, he_anchor, he); - hash_elem_destroy(h, he); - } - else - he_anchor = &(*he_anchor)->next; - } - } -} - -size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num) -{ - const char *key_str = (const char *)key; - const char *end = key_str + key_length; - size_t h = 5381; - - while(key_str < end) { - size_t j = (size_t)*key_str++; - h += h << 5; - h ^= j; - } - - return (h % slots_num); -} - -size_t curlx_str_key_compare(void *k1, size_t key1_len, - void *k2, size_t key2_len) -{ - if((key1_len == key2_len) && !memcmp(k1, k2, key1_len)) - return 1; - - return 0; -} - -void Curl_hash_start_iterate(struct Curl_hash *hash, - struct Curl_hash_iterator *iter) -{ - DEBUGASSERT(hash->init == HASHINIT); - iter->hash = hash; - iter->slot_index = 0; - iter->current = NULL; -#ifdef DEBUGBUILD - iter->init = ITERINIT; -#endif -} - -struct Curl_hash_element *Curl_hash_next_element( - struct Curl_hash_iterator *iter) -{ - struct Curl_hash *h; - DEBUGASSERT(iter->init == ITERINIT); - h = iter->hash; - if(!h->table) - return NULL; /* empty hash, nothing to return */ - - /* Get the next element in the current list, if any */ - if(iter->current) - iter->current = iter->current->next; - - /* If we have reached the end of the list, find the next one */ - if(!iter->current) { - size_t i; - for(i = iter->slot_index; i < h->slots; i++) { - if(h->table[i]) { - iter->current = h->table[i]; - iter->slot_index = i + 1; - break; - } - } - } - - return iter->current; -} diff --git a/vendor/curl/lib/hash.h b/vendor/curl/lib/hash.h deleted file mode 100644 index 1d7d3de8c..000000000 --- a/vendor/curl/lib/hash.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef HEADER_CURL_HASH_H -#define HEADER_CURL_HASH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* Hash function prototype */ -typedef size_t (*hash_function)(void *key, - size_t key_length, - size_t slots_num); - -/* - Comparator function prototype. Compares two keys. -*/ -typedef size_t (*comp_function)(void *key1, - size_t key1_len, - void *key2, - size_t key2_len); - -typedef void (*Curl_hash_dtor)(void *); - -typedef void (*Curl_hash_elem_dtor)(void *key, size_t key_len, void *p); - -struct Curl_hash_element { - struct Curl_hash_element *next; - void *ptr; - Curl_hash_elem_dtor dtor; - size_t key_len; - char key[1]; /* allocated memory following the struct */ -}; - -struct Curl_hash { - struct Curl_hash_element **table; - - /* Hash function to be used for this hash table */ - hash_function hash_func; - /* Comparator function to compare keys */ - comp_function comp_func; - /* General element construct, unless element itself carries one */ - Curl_hash_dtor dtor; - size_t slots; - size_t size; -#ifdef DEBUGBUILD - int init; -#endif -}; - -struct Curl_hash_iterator { - struct Curl_hash *hash; - size_t slot_index; - struct Curl_hash_element *current; -#ifdef DEBUGBUILD - int init; -#endif -}; - -void Curl_hash_init(struct Curl_hash *h, - size_t slots, - hash_function hfunc, - comp_function comparator, - Curl_hash_dtor dtor); - -void *Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p); -void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p, - Curl_hash_elem_dtor dtor); -int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len); -void *Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len); - -void Curl_hash_destroy(struct Curl_hash *h); -size_t Curl_hash_count(struct Curl_hash *h); -void Curl_hash_clean(struct Curl_hash *h); -void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, - int (*comp)(void *, void *)); -size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num); -size_t curlx_str_key_compare(void *k1, size_t key1_len, void *k2, - size_t key2_len); -void Curl_hash_start_iterate(struct Curl_hash *hash, - struct Curl_hash_iterator *iter); -struct Curl_hash_element *Curl_hash_next_element( - struct Curl_hash_iterator *iter); - -void Curl_hash_print(struct Curl_hash *h, void (*func)(void *)); - -#endif /* HEADER_CURL_HASH_H */ diff --git a/vendor/curl/lib/headers.c b/vendor/curl/lib/headers.c deleted file mode 100644 index 195e12b37..000000000 --- a/vendor/curl/lib/headers.c +++ /dev/null @@ -1,394 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "sendf.h" -#include "curl_trc.h" -#include "headers.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HEADERS_API) - -/* Generate the curl_header struct for the user. This function MUST assign all - struct fields in the output struct. */ -static void copy_header_external(struct Curl_header_store *hs, - size_t index, - size_t amount, - struct Curl_llist_node *e, - struct curl_header *hout) -{ - struct curl_header *h = hout; - h->name = hs->name; - h->value = hs->value; - h->amount = amount; - h->index = index; - /* this will randomly OR a reserved bit for the sole purpose of making it - impossible for applications to do == comparisons, as that would otherwise - be tempting and then lead to the reserved bits not being reserved - anymore. */ - h->origin = (unsigned int)(hs->type | (1 << 27)); - h->anchor = e; -} - -/* public API */ -CURLHcode curl_easy_header(CURL *curl, - const char *name, - size_t nameindex, - unsigned int origin, - int request, - struct curl_header **hout) -{ - struct Curl_llist_node *e; - struct Curl_llist_node *e_pick = NULL; - struct Curl_easy *data = curl; - size_t match = 0; - size_t amount = 0; - struct Curl_header_store *hs = NULL; - struct Curl_header_store *pick = NULL; - if(!name || !hout || !data || - (origin > (CURLH_HEADER | CURLH_TRAILER | CURLH_CONNECT | CURLH_1XX | - CURLH_PSEUDO)) || !origin || (request < -1)) - return CURLHE_BAD_ARGUMENT; - if(!Curl_llist_count(&data->state.httphdrs)) - return CURLHE_NOHEADERS; /* no headers available */ - if(request > data->state.requests) - return CURLHE_NOREQUEST; - if(request == -1) - request = data->state.requests; - - /* we need a first round to count amount of this header */ - for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { - hs = Curl_node_elem(e); - if(curl_strequal(hs->name, name) && - (hs->type & origin) && - (hs->request == request)) { - amount++; - pick = hs; - e_pick = e; - } - } - if(!amount) - return CURLHE_MISSING; - else if(nameindex >= amount) - return CURLHE_BADINDEX; - - if(nameindex == amount - 1) - /* if the last or only occurrence is what's asked for, then we know it */ - hs = pick; - else { - for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { - hs = Curl_node_elem(e); - if(curl_strequal(hs->name, name) && - (hs->type & origin) && - (hs->request == request) && - (match++ == nameindex)) { - e_pick = e; - break; - } - } - if(!e) /* this should not happen */ - return CURLHE_MISSING; - } - /* this is the name we want */ - copy_header_external(hs, nameindex, amount, e_pick, - &data->state.headerout[0]); - *hout = &data->state.headerout[0]; - return CURLHE_OK; -} - -/* public API */ -struct curl_header *curl_easy_nextheader(CURL *curl, - unsigned int origin, - int request, - struct curl_header *prev) -{ - struct Curl_easy *data = curl; - struct Curl_llist_node *pick; - struct Curl_llist_node *e; - struct Curl_header_store *hs; - size_t amount = 0; - size_t index = 0; - - if(request > data->state.requests) - return NULL; - if(request == -1) - request = data->state.requests; - - if(prev) { - pick = prev->anchor; - if(!pick) - /* something is wrong */ - return NULL; - pick = Curl_node_next(pick); - } - else - pick = Curl_llist_head(&data->state.httphdrs); - - if(pick) { - /* make sure it is the next header of the desired type */ - do { - hs = Curl_node_elem(pick); - if((hs->type & origin) && (hs->request == request)) - break; - pick = Curl_node_next(pick); - } while(pick); - } - - if(!pick) - /* no more headers available */ - return NULL; - - hs = Curl_node_elem(pick); - - /* count number of occurrences of this name within the mask and figure out - the index for the currently selected entry */ - for(e = Curl_llist_head(&data->state.httphdrs); e; e = Curl_node_next(e)) { - struct Curl_header_store *check = Curl_node_elem(e); - if(curl_strequal(hs->name, check->name) && - (check->request == request) && - (check->type & origin)) - amount++; - if(e == pick) - index = amount - 1; - } - - copy_header_external(hs, index, amount, pick, - &data->state.headerout[1]); - return &data->state.headerout[1]; -} - -static CURLcode namevalue(char *header, size_t hlen, unsigned int type, - char **name, char **value) -{ - char *end = header + hlen - 1; /* point to the last byte */ - DEBUGASSERT(hlen); - *name = header; - - if(type == CURLH_PSEUDO) { - if(*header != ':') - return CURLE_BAD_FUNCTION_ARGUMENT; - header++; - } - - /* Find the end of the header name */ - while(*header && (*header != ':')) - ++header; - - if(*header) - /* Skip over colon, null it */ - *header++ = 0; - else - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* skip all leading blank letters */ - while(ISBLANK(*header)) - header++; - - *value = header; - - /* skip all trailing space letters */ - while((end > header) && ISBLANK(*end)) - *end-- = 0; /* null-terminate */ - return CURLE_OK; -} - -/* - * Curl_headers_push() gets passed a full HTTP header to store. It gets called - * immediately before the header callback. The header is CRLF, CR or LF - * terminated. - */ -CURLcode Curl_headers_push(struct Curl_easy *data, const char *header, - size_t hlen, /* length of header */ - unsigned char type) -{ - char *value = NULL; - char *name = NULL; - struct Curl_header_store *hs; - CURLcode result = CURLE_OUT_OF_MEMORY; - const size_t ilen = hlen; - - if((header[0] == '\r') || (header[0] == '\n')) - /* ignore the body separator */ - return CURLE_OK; - - /* trim off newline characters */ - if(hlen && (header[hlen - 1] == '\n')) - hlen--; - if(hlen && (header[hlen - 1] == '\r')) - hlen--; - if(hlen == ilen) - /* neither CR nor LF as terminator is not a valid header */ - return CURLE_WEIRD_SERVER_REPLY; - - if(ISBLANK(header[0])) { - /* pass leading blanks */ - while(hlen && ISBLANK(*header)) { - header++; - hlen--; - } - if(!hlen) - return CURLE_WEIRD_SERVER_REPLY; - } - if(Curl_llist_count(&data->state.httphdrs) >= MAX_HTTP_RESP_HEADER_COUNT) { - failf(data, "Too many response headers, %d is max", - MAX_HTTP_RESP_HEADER_COUNT); - return CURLE_TOO_LARGE; - } - - hs = curlx_calloc(1, sizeof(*hs) + hlen); - if(!hs) - return CURLE_OUT_OF_MEMORY; - memcpy(hs->buffer, header, hlen); - hs->buffer[hlen] = 0; /* null-terminate */ - - result = namevalue(hs->buffer, hlen, type, &name, &value); - if(!result) { - hs->name = name; - hs->value = value; - hs->type = type; - hs->request = data->state.requests; - - /* insert this node into the list of headers */ - Curl_llist_append(&data->state.httphdrs, hs, &hs->node); - data->state.prevhead = hs; - } - else { - failf(data, "Invalid response header"); - curlx_free(hs); - } - return result; -} - -/* - * Curl_headers_reset(). Reset the headers subsystem. - */ -static void headers_reset(struct Curl_easy *data) -{ - Curl_llist_init(&data->state.httphdrs, NULL); - data->state.prevhead = NULL; -} - -struct hds_cw_collect_ctx { - struct Curl_cwriter super; -}; - -static CURLcode hds_cw_collect_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t blen) -{ - if((type & CLIENTWRITE_HEADER) && !(type & CLIENTWRITE_STATUS)) { - unsigned char htype = (unsigned char) - (type & CLIENTWRITE_CONNECT ? CURLH_CONNECT : - (type & CLIENTWRITE_1XX ? CURLH_1XX : - (type & CLIENTWRITE_TRAILER ? CURLH_TRAILER : - CURLH_HEADER))); - CURLcode result = Curl_headers_push(data, buf, blen, htype); - CURL_TRC_WRITE(data, "header_collect pushed(type=%x, len=%zu) -> %d", - htype, blen, result); - if(result) - return result; - } - return Curl_cwriter_write(data, writer->next, type, buf, blen); -} - -static const struct Curl_cwtype hds_cw_collect = { - "hds-collect", - NULL, - Curl_cwriter_def_init, - hds_cw_collect_write, - Curl_cwriter_def_close, - sizeof(struct hds_cw_collect_ctx) -}; - -CURLcode Curl_headers_init(struct Curl_easy *data) -{ - struct Curl_cwriter *writer; - CURLcode result; - - if(data->conn && (data->conn->scheme->protocol & PROTO_FAMILY_HTTP)) { - /* avoid installing it twice */ - if(Curl_cwriter_get_by_name(data, hds_cw_collect.name)) - return CURLE_OK; - - result = Curl_cwriter_create(&writer, data, &hds_cw_collect, - CURL_CW_PROTOCOL); - if(result) - return result; - - result = Curl_cwriter_add(data, writer); - if(result) { - Curl_cwriter_free(data, writer); - return result; - } - } - return CURLE_OK; -} - -/* - * Curl_headers_cleanup(). Free all stored headers and associated memory. - */ -CURLcode Curl_headers_cleanup(struct Curl_easy *data) -{ - struct Curl_llist_node *e; - struct Curl_llist_node *n; - - for(e = Curl_llist_head(&data->state.httphdrs); e; e = n) { - struct Curl_header_store *hs = Curl_node_elem(e); - n = Curl_node_next(e); - curlx_free(hs); - } - headers_reset(data); - return CURLE_OK; -} - -#else /* HTTP-disabled builds below */ - -CURLHcode curl_easy_header(CURL *easy, - const char *name, - size_t index, - unsigned int origin, - int request, - struct curl_header **hout) -{ - (void)easy; - (void)name; - (void)index; - (void)origin; - (void)request; - (void)hout; - return CURLHE_NOT_BUILT_IN; -} - -struct curl_header *curl_easy_nextheader(CURL *easy, - unsigned int type, - int request, - struct curl_header *prev) -{ - (void)easy; - (void)type; - (void)request; - (void)prev; - return NULL; -} -#endif diff --git a/vendor/curl/lib/headers.h b/vendor/curl/lib/headers.h deleted file mode 100644 index 283179acd..000000000 --- a/vendor/curl/lib/headers.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef HEADER_CURL_HEADER_H -#define HEADER_CURL_HEADER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HEADERS_API) - -struct Curl_header_store { - struct Curl_llist_node node; - char *name; /* points into 'buffer' */ - char *value; /* points into 'buffer' */ - int request; /* 0 is the first request, then 1.. 2.. */ - unsigned char type; /* CURLH_* defines */ - char buffer[1]; /* this is the raw header blob */ -}; - -/* - * Initialize header collecting for a transfer. - * Add a client writer that catches CLIENTWRITE_HEADER writes. - */ -CURLcode Curl_headers_init(struct Curl_easy *data); - -/* - * Curl_headers_push() gets passed a full header to store. - */ -CURLcode Curl_headers_push(struct Curl_easy *data, const char *header, - size_t hlen, unsigned char type); - -/* - * Curl_headers_cleanup(). Free all stored headers and associated memory. - */ -CURLcode Curl_headers_cleanup(struct Curl_easy *data); - -#else -#define Curl_headers_init(x) CURLE_OK -#define Curl_headers_push(x, y, z, a) \ - ((void)(x), (void)(y), (void)(z), (void)(a), CURLE_OK) -#define Curl_headers_cleanup(x) Curl_nop_stmt -#endif - -#endif /* HEADER_CURL_HEADER_H */ diff --git a/vendor/curl/lib/hmac.c b/vendor/curl/lib/hmac.c deleted file mode 100644 index a4d6ebdd8..000000000 --- a/vendor/curl/lib/hmac.c +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC2104 Keyed-Hashing for Message Authentication - * - ***************************************************************************/ -#include "curl_setup.h" - -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ - !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ - defined(USE_SSL) - -#include "curl_hmac.h" - -/* - * Generic HMAC algorithm. - * - * This module computes HMAC digests based on any hash function. Parameters - * and computing procedures are setup dynamically at HMAC computation context - * initialization. - */ - -static const unsigned char hmac_ipad = 0x36; -static const unsigned char hmac_opad = 0x5C; - -struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams, - const unsigned char *key, - unsigned int keylen) -{ - size_t i; - struct HMAC_context *ctxt; - unsigned char *hkey; - unsigned char b; - - /* Create HMAC context. */ - i = sizeof(*ctxt) + (2 * hashparams->ctxtsize) + hashparams->resultlen; - ctxt = curlx_malloc(i); - - if(!ctxt) - return ctxt; - - ctxt->hash = hashparams; - ctxt->hashctxt1 = (void *)(ctxt + 1); - ctxt->hashctxt2 = (void *)((char *)ctxt->hashctxt1 + hashparams->ctxtsize); - - /* If the key is too long, replace it by its hash digest. */ - if(keylen > hashparams->maxkeylen) { - if(hashparams->hinit(ctxt->hashctxt1)) - goto fail; - hashparams->hupdate(ctxt->hashctxt1, key, keylen); - hkey = (unsigned char *)ctxt->hashctxt2 + hashparams->ctxtsize; - hashparams->hfinal(hkey, ctxt->hashctxt1); - key = hkey; - keylen = hashparams->resultlen; - } - - /* Prime the two hash contexts with the modified key. */ - if(hashparams->hinit(ctxt->hashctxt1) || - hashparams->hinit(ctxt->hashctxt2)) - goto fail; - - for(i = 0; i < keylen; i++) { - b = (unsigned char)(*key ^ hmac_ipad); - hashparams->hupdate(ctxt->hashctxt1, &b, 1); - b = (unsigned char)(*key++ ^ hmac_opad); - hashparams->hupdate(ctxt->hashctxt2, &b, 1); - } - - for(; i < hashparams->maxkeylen; i++) { - hashparams->hupdate(ctxt->hashctxt1, &hmac_ipad, 1); - hashparams->hupdate(ctxt->hashctxt2, &hmac_opad, 1); - } - - /* Done, return pointer to HMAC context. */ - return ctxt; - -fail: - curlx_free(ctxt); - return NULL; -} - -void Curl_HMAC_update(struct HMAC_context *ctxt, - const unsigned char *data, - unsigned int len) -{ - /* Update first hash calculation. */ - ctxt->hash->hupdate(ctxt->hashctxt1, data, len); -} - -int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output) -{ - const struct HMAC_params *hashparams = ctxt->hash; - - /* Do not get output if called with a null parameter: only release - storage. */ - - if(!output) - output = (unsigned char *)ctxt->hashctxt2 + ctxt->hash->ctxtsize; - - hashparams->hfinal(output, ctxt->hashctxt1); - hashparams->hupdate(ctxt->hashctxt2, output, hashparams->resultlen); - hashparams->hfinal(output, ctxt->hashctxt2); - curlx_free(ctxt); - return 0; -} - -/* - * Curl_hmacit() - * - * This is used to generate a HMAC hash, for the specified input data, given - * the specified hash function and key. - * - * Parameters: - * - * hashparams [in] - The hash function (Curl_HMAC_MD5). - * key [in] - The key to use. - * keylen [in] - The length of the key. - * buf [in] - The data to encrypt. - * buflen [in] - The length of the data. - * output [in/out] - The output buffer. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_hmacit(const struct HMAC_params *hashparams, - const unsigned char *key, const size_t keylen, - const unsigned char *data, size_t datalen, - unsigned char *output) -{ - struct HMAC_context *ctxt; - if(keylen > UINT_MAX) /* unlikely to ever happen */ - return CURLE_BAD_FUNCTION_ARGUMENT; - ctxt = Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen)); - - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - /* Update the digest with the given challenge */ - do { - unsigned int ilen = (unsigned int)CURLMIN(datalen, UINT_MAX); - Curl_HMAC_update(ctxt, data, ilen); - datalen -= ilen; - data += ilen; - } while(datalen); - - /* Finalise the digest */ - Curl_HMAC_final(ctxt, output); - - return CURLE_OK; -} - -#endif /* Using NTLM (without SSPI) or AWS */ diff --git a/vendor/curl/lib/hostip.c b/vendor/curl/lib/hostip.c deleted file mode 100644 index 85f53c4ef..000000000 --- a/vendor/curl/lib/hostip.c +++ /dev/null @@ -1,1130 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include /* for sigjmp_buf, sigsetjmp() */ -#include - -#include "urldata.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "dnscache.h" -#include "hostip.h" -#include "httpsrr.h" -#include "url.h" -#include "multiif.h" -#include "progress.h" -#include "doh.h" -#include "select.h" -#include "strcase.h" -#include "easy_lock.h" -#include "curlx/inet_ntop.h" -#include "curlx/inet_pton.h" -#include "curlx/strcopy.h" -#include "curlx/strparse.h" - -#if defined(CURLRES_SYNCH) && \ - defined(HAVE_ALARM) && \ - defined(SIGALRM) && \ - defined(HAVE_SIGSETJMP) && \ - defined(GLOBAL_INIT_IS_THREADSAFE) -/* alarm-based timeouts can only be used with all the dependencies satisfied */ -#define USE_ALARM_TIMEOUT -#endif - -#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */ - -#define MAX_DNS_CACHE_SIZE 29999 - -#define RESOLV_FAIL(for_proxy) \ - ((for_proxy) ? CURLE_COULDNT_RESOLVE_PROXY : CURLE_COULDNT_RESOLVE_HOST) - -#define IS_RESOLV_FAIL(result) \ - (((result) == CURLE_COULDNT_RESOLVE_HOST) || \ - ((result) == CURLE_COULDNT_RESOLVE_PROXY)) -/* - * ipv6works() returns TRUE if IPv6 seems to work. - */ -#ifdef USE_IPV6 -static bool ipv6works(struct Curl_easy *data); -#else -#define ipv6works(x) FALSE -#endif - -/* - * hostip.c explained - * ================== - * - * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c - * source file are these: - * - * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use - * that. The host may not be able to resolve IPv6, but we do not really have to - * take that into account. Hosts that are not IPv6-enabled have CURLRES_IPV4 - * defined. - * - * USE_RESOLV_ARES - is defined if libcurl is built to use c-ares for - * asynchronous name resolves. This can be Windows or *nix. - * - * USE_RESOLV_THREADED - is defined if libcurl is built to run under (native) - * Windows, and then the name resolve will be done in a new thread, and the - * supported API will be the same as for ares-builds. - * - * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If - * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is - * defined. - * - * The host*.c sources files are split up like this: - * - * hostip.c - method-independent resolver functions and utility functions - * hostip4.c - IPv4 specific functions - * hostip6.c - IPv6 specific functions - * asyn.h - common functions for all async resolvers - * The two asynchronous name resolver backends are implemented in: - * asyn-ares.c - async resolver using c-ares - * asyn-thread.c - async resolver using POSIX threads - * - * The hostip.h is the united header file for all this. It defines the - * CURLRES_* defines based on the config*.h and curl_setup.h defines. - */ - -uint8_t Curl_resolv_dns_queries(struct Curl_easy *data, uint8_t ip_version) -{ - (void)data; - switch(ip_version) { - case CURL_IPRESOLVE_V6: - return CURL_DNSQ_AAAA; - case CURL_IPRESOLVE_V4: - return CURL_DNSQ_A; - default: - if(ipv6works(data)) - return (CURL_DNSQ_A | CURL_DNSQ_AAAA); - else - return CURL_DNSQ_A; - } -} - -#ifdef CURLVERBOSE -const char *Curl_resolv_query_str(uint8_t dns_queries) -{ - switch(dns_queries) { - case (CURL_DNSQ_A | CURL_DNSQ_AAAA | CURL_DNSQ_HTTPS): - return "A+AAAA+HTTPS"; - case (CURL_DNSQ_A | CURL_DNSQ_AAAA): - return "A+AAAA"; - case (CURL_DNSQ_AAAA | CURL_DNSQ_HTTPS): - return "AAAA+HTTPS"; - case (CURL_DNSQ_AAAA): - return "AAAA"; - case (CURL_DNSQ_A | CURL_DNSQ_HTTPS): - return "A+HTTPS"; - case (CURL_DNSQ_A): - return "A"; - case (CURL_DNSQ_HTTPS): - return "HTTPS"; - case 0: - return "-"; - default: - DEBUGASSERT(0); - return "???"; - } -} -#endif - -/* - * Curl_printable_address() stores a printable version of the 1st address - * given in the 'ai' argument. The result will be stored in the buf that is - * bufsize bytes big. - * - * If the conversion fails, the target buffer is empty. - */ -void Curl_printable_address(const struct Curl_addrinfo *ai, char *buf, - size_t bufsize) -{ - DEBUGASSERT(bufsize); - buf[0] = 0; - - switch(ai->ai_family) { - case AF_INET: { - const struct sockaddr_in *sa4 = (const void *)ai->ai_addr; - const struct in_addr *ipaddr4 = &sa4->sin_addr; - (void)curlx_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, bufsize); - break; - } -#ifdef USE_IPV6 - case AF_INET6: { - const struct sockaddr_in6 *sa6 = (const void *)ai->ai_addr; - const struct in6_addr *ipaddr6 = &sa6->sin6_addr; - (void)curlx_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, bufsize); - break; - } -#endif - default: - break; - } -} - -#ifdef USE_ALARM_TIMEOUT -/* Beware this is a global and unique instance. This is used to store the - return address that we can jump back to from inside a signal handler. This - is not thread-safe stuff. */ -static sigjmp_buf curl_jmpenv; -static curl_simple_lock curl_jmpenv_lock = CURL_SIMPLE_LOCK_INIT; -#endif - -#ifdef USE_IPV6 -/* return a static IPv6 ::1 for the name */ -static struct Curl_addrinfo *get_localhost6(uint16_t port, const char *name) -{ - struct Curl_addrinfo *ca; - const size_t ss_size = sizeof(struct sockaddr_in6); - const size_t hostlen = strlen(name); - struct sockaddr_in6 sa6; - unsigned char ipv6[16]; - unsigned short port16 = (unsigned short)(port & 0xffff); - ca = curlx_calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1); - if(!ca) - return NULL; - - memset(&sa6, 0, sizeof(sa6)); - sa6.sin6_family = AF_INET6; - sa6.sin6_port = htons(port16); - - (void)curlx_inet_pton(AF_INET6, "::1", ipv6); - memcpy(&sa6.sin6_addr, ipv6, sizeof(ipv6)); - - ca->ai_flags = 0; - ca->ai_family = AF_INET6; - ca->ai_socktype = SOCK_STREAM; - ca->ai_protocol = IPPROTO_TCP; - ca->ai_addrlen = (curl_socklen_t)ss_size; - ca->ai_next = NULL; - ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); - memcpy(ca->ai_addr, &sa6, ss_size); - ca->ai_canonname = (char *)ca->ai_addr + ss_size; - curlx_strcopy(ca->ai_canonname, hostlen + 1, name, hostlen); - return ca; -} -#else -#define get_localhost6(x, y) NULL -#endif - -/* return a static IPv4 127.0.0.1 for the given name */ -static struct Curl_addrinfo *get_localhost(uint16_t port, const char *name) -{ - struct Curl_addrinfo *ca; - struct Curl_addrinfo *ca6; - const size_t ss_size = sizeof(struct sockaddr_in); - const size_t hostlen = strlen(name); - struct sockaddr_in sa; - unsigned int ipv4; - unsigned short port16 = (unsigned short)(port & 0xffff); - - /* memset to clear the sa.sin_zero field */ - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = htons(port16); - if(curlx_inet_pton(AF_INET, "127.0.0.1", (char *)&ipv4) < 1) - return NULL; - memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4)); - - ca = curlx_calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1); - if(!ca) - return NULL; - ca->ai_flags = 0; - ca->ai_family = AF_INET; - ca->ai_socktype = SOCK_STREAM; - ca->ai_protocol = IPPROTO_TCP; - ca->ai_addrlen = (curl_socklen_t)ss_size; - ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); - memcpy(ca->ai_addr, &sa, ss_size); - ca->ai_canonname = (char *)ca->ai_addr + ss_size; - curlx_strcopy(ca->ai_canonname, hostlen + 1, name, hostlen); - - ca6 = get_localhost6(port, name); - if(!ca6) - return ca; - ca6->ai_next = ca; - return ca6; -} - -#ifdef USE_IPV6 -/* the nature of most systems is that IPv6 status does not come and go during a - program's lifetime so we only probe the first time and then we have the - info kept for fast reuse */ -CURLcode Curl_probeipv6(struct Curl_multi *multi) -{ - /* probe to see if we have a working IPv6 stack */ - curl_socket_t s = CURL_SOCKET(PF_INET6, SOCK_DGRAM, 0); - multi->ipv6_works = FALSE; - if(s == CURL_SOCKET_BAD) { - if(SOCKERRNO == SOCKENOMEM) - return CURLE_OUT_OF_MEMORY; - } - else { - multi->ipv6_works = TRUE; - sclose(s); - } - return CURLE_OK; -} - -/* - * ipv6works() returns TRUE if IPv6 seems to work. - */ -static bool ipv6works(struct Curl_easy *data) -{ - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - return data ? data->multi->ipv6_works : FALSE; -} -#endif /* USE_IPV6 */ - -/* - * Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4 - * (or IPv6 if supported) address. - */ -bool Curl_host_is_ipnum(const char *hostname) -{ - struct in_addr in; -#ifdef USE_IPV6 - struct in6_addr in6; -#endif - if(curlx_inet_pton(AF_INET, hostname, &in) > 0 -#ifdef USE_IPV6 - || curlx_inet_pton(AF_INET6, hostname, &in6) > 0 -#endif - ) - return TRUE; - return FALSE; -} - -/* return TRUE if 'part' is a case insensitive tail of 'full' */ -static bool tailmatch(const char *full, size_t flen, - const char *part, size_t plen) -{ - if(plen > flen) - return FALSE; - return curl_strnequal(part, &full[flen - plen], plen); -} - -static CURLcode hostip_resolv_failed(struct Curl_easy *data, - const char *hostname, - bool for_proxy) -{ - failf(data, "Could not resolve %s: %s", - for_proxy ? "proxy" : "host", hostname); - return RESOLV_FAIL(for_proxy); -} - -static bool can_resolve_dns_queries(struct Curl_easy *data, - uint8_t dns_queries) -{ - (void)data; - if((CURL_DNSQ_IP(dns_queries) == CURL_DNSQ_AAAA) && !ipv6works(data)) - return FALSE; - return TRUE; -} - -CURLcode Curl_resolv_announce_start(struct Curl_easy *data, - void *resolver) -{ - if(data->set.resolver_start) { - int rc; - - CURL_TRC_DNS(data, "announcing resolve to application"); - Curl_set_in_callback(data, TRUE); - rc = data->set.resolver_start(resolver, NULL, - data->set.resolver_start_client); - Curl_set_in_callback(data, FALSE); - if(rc) { - CURL_TRC_DNS(data, "application aborted resolve"); - return CURLE_ABORTED_BY_CALLBACK; - } - } - return CURLE_OK; -} - -#ifdef USE_CURL_ASYNC - -static struct Curl_resolv_async *hostip_async_new(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool for_proxy, - timediff_t timeout_ms) -{ - struct Curl_resolv_async *async; - size_t hostlen = strlen(hostname); - - if(!data->multi) { - DEBUGASSERT(0); - return NULL; - } - - /* struct size already includes the NUL for hostname */ - async = curlx_calloc(1, sizeof(*async) + hostlen); - if(!async) - return NULL; - - /* Give every async resolve operation a "unique" id. This may - * wrap around after a long time, making collisions highly unlikely. - * As we keep the async structs at the easy handle, chances of - * easy `mid plus resolv->id` colliding should be astronomical. - * `resolv_id == 0` is never used. */ - if(data->multi->last_resolv_id == UINT32_MAX) - data->multi->last_resolv_id = 1; /* wrap around */ - else - data->multi->last_resolv_id++; - async->id = data->multi->last_resolv_id; - async->dns_queries = dns_queries; - async->port = port; - async->transport = transport; - async->for_proxy = for_proxy; - async->start = *Curl_pgrs_now(data); - async->timeout_ms = timeout_ms; - if(hostlen) { - memcpy(async->hostname, hostname, hostlen); - async->is_ipaddr = Curl_is_ipaddr(async->hostname); - if(async->is_ipaddr) - async->is_ipv4addr = Curl_is_ipv4addr(async->hostname); - } - - return async; -} - -static CURLcode hostip_resolv_take_result(struct Curl_easy *data, - struct Curl_resolv_async *async, - struct Curl_dns_entry **pdns) -{ - CURLcode result; - - /* If async resolving is ongoing, this must be set */ - if(!async) - return CURLE_FAILED_INIT; - -#ifndef CURL_DISABLE_DOH - if(async->doh) - result = Curl_doh_take_result(data, async, pdns); - else -#endif - result = Curl_async_take_result(data, async, pdns); - - if(result == CURLE_AGAIN) { - CURL_TRC_DNS(data, "resolve incomplete, queries=%s, responses=%s, " - "ongoing=%d for %s:%d", - Curl_resolv_query_str(async->dns_queries), - Curl_resolv_query_str(async->dns_responses), - async->queries_ongoing, async->hostname, async->port); - result = CURLE_OK; - } - else if(result) { - result = Curl_async_failed(data, async, NULL); - } - else { - CURL_TRC_DNS(data, "resolve complete for %s:%u", - async->hostname, async->port); - DEBUGASSERT(*pdns); - } - - return result; -} - -timediff_t Curl_resolv_elapsed_ms(struct Curl_easy *data, - uint32_t resolv_id) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - if(!async) - return CURL_TIMEOUT_RESOLVE_MS; - return curlx_ptimediff_ms(Curl_pgrs_now(data), &async->start); -} - -bool Curl_resolv_has_answers(struct Curl_easy *data, - uint32_t resolv_id, uint8_t dns_queries) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - uint8_t check_queries; - /* a no longer existing/running resolve has all answers. */ - if(!async || async->done) - return TRUE; - /* Relevant are only queries undertaken. Others are considered answered. */ - check_queries = (dns_queries & async->dns_queries); - if((check_queries & async->dns_responses) != check_queries) { - return FALSE; - } - return TRUE; -} - -const struct Curl_addrinfo *Curl_resolv_get_ai(struct Curl_easy *data, - uint32_t resolv_id, - int ai_family, - unsigned int index) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - (void)index; - if(!async) - return NULL; - if((ai_family == AF_INET) && !(async->dns_queries & CURL_DNSQ_A)) - return NULL; -#ifdef USE_IPV6 - if((ai_family == AF_INET6) && !(async->dns_queries & CURL_DNSQ_AAAA)) - return NULL; -#endif - return Curl_async_get_ai(data, async, ai_family, index); -} - - -#ifdef USE_HTTPSRR -const struct Curl_https_rrinfo * -Curl_resolv_get_https(struct Curl_easy *data, uint32_t resolv_id) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - if(!async) - return NULL; - return Curl_async_get_https(data, async); -} - -bool Curl_resolv_knows_https(struct Curl_easy *data, uint32_t resolv_id) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - if(!async) - return TRUE; - return Curl_async_knows_https(data, async); -} - -#endif /* USE_HTTPSRR */ - -#endif /* USE_CURL_ASYNC */ - -static CURLcode hostip_resolv_start(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool for_proxy, - timediff_t timeout_ms, - bool allowDOH, - uint32_t *presolv_id, - struct Curl_dns_entry **pdns) -{ -#ifdef USE_CURL_ASYNC - struct Curl_resolv_async *async = NULL; -#endif - struct Curl_addrinfo *addr = NULL; - size_t hostname_len; - CURLcode result = CURLE_OK; - - (void)timeout_ms; /* not in all ifdefs */ - *presolv_id = 0; - *pdns = NULL; - - /* Check for "known" things to resolve ourselves. */ -#ifndef USE_RESOLVE_ON_IPS - if(Curl_is_ipaddr(hostname)) { - /* test655 verifies that the announce is done, even though there - * is no real resolving. So, keep doing this. */ - result = Curl_resolv_announce_start(data, NULL); - if(result) - goto out; - /* shortcut literal IP addresses, if we are not told to resolve them. */ - result = Curl_str2addr(hostname, port, &addr); - goto out; - } -#endif - - hostname_len = strlen(hostname); - if(curl_strequal(hostname, "localhost") || - curl_strequal(hostname, "localhost.") || - tailmatch(hostname, hostname_len, STRCONST(".localhost")) || - tailmatch(hostname, hostname_len, STRCONST(".localhost."))) { - result = Curl_resolv_announce_start(data, NULL); - if(result) - goto out; - addr = get_localhost(port, hostname); - if(!addr) - result = CURLE_OUT_OF_MEMORY; - goto out; - } - -#ifndef CURL_DISABLE_DOH - if(!Curl_is_ipaddr(hostname) && allowDOH && data->set.doh) { - result = Curl_resolv_announce_start(data, NULL); - if(result) - goto out; - if(!async) { - async = hostip_async_new(data, dns_queries, hostname, port, - transport, for_proxy, timeout_ms); - if(!async) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - result = Curl_doh(data, async); - goto out; - } -#else - (void)allowDOH; -#endif - - /* Can we provide the requested IP specifics in resolving? */ - if(!can_resolve_dns_queries(data, dns_queries)) { - result = RESOLV_FAIL(for_proxy); - goto out; - } - -#ifdef CURLRES_ASYNCH - (void)addr; - if(!async) { - async = hostip_async_new(data, dns_queries, hostname, port, - transport, for_proxy, timeout_ms); - if(!async) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - result = Curl_async_getaddrinfo(data, async); - if(result == CURLE_AGAIN) { - /* the answer might be there already. Check. */ - CURLcode r2 = hostip_resolv_take_result(data, async, pdns); - if(r2) - result = r2; - else if(*pdns) - result = CURLE_OK; - } -#else - result = Curl_resolv_announce_start(data, NULL); - if(result) - goto out; - addr = Curl_sync_getaddrinfo(data, dns_queries, hostname, port, transport); - if(!addr) - result = RESOLV_FAIL(for_proxy); -#endif - -out: - if(!result) { - if(addr) { - /* we got a response, create a dns entry, add to cache, return */ - DEBUGASSERT(!*pdns); - *pdns = Curl_dnscache_mk_entry(data, dns_queries, &addr, hostname, port); - if(!*pdns) - result = CURLE_OUT_OF_MEMORY; - } - else if(!*pdns) - result = CURLE_AGAIN; - } - else if(*pdns) - Curl_dns_entry_unlink(data, pdns); - else if(addr) - Curl_freeaddrinfo(addr); - -#ifdef USE_CURL_ASYNC - if(async) { - if(result == CURLE_AGAIN) { /* still need it, link, return id. */ - *presolv_id = async->id; - async->next = data->state.async; - data->state.async = async; - } - else { - Curl_async_destroy(data, async); - } - } -#endif - return result; -} - -static CURLcode hostip_resolv(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool for_proxy, - timediff_t timeout_ms, - bool allowDOH, - uint32_t *presolv_id, - struct Curl_dns_entry **pdns) -{ - size_t hostname_len; - CURLcode result = RESOLV_FAIL(for_proxy); - bool cache_dns = FALSE; - - (void)timeout_ms; /* not used in all ifdefs */ - *presolv_id = 0; - *pdns = NULL; - -#ifdef CURL_DISABLE_DOH - (void)allowDOH; -#endif - - /* We should intentionally error and not resolve .onion TLDs */ - hostname_len = strlen(hostname); - DEBUGASSERT(hostname_len); - if(hostname_len >= 7 && - (curl_strequal(&hostname[hostname_len - 6], ".onion") || - curl_strequal(&hostname[hostname_len - 7], ".onion."))) { - failf(data, "Not resolving .onion address (RFC 7686)"); - goto out; - } - -#ifdef DEBUGBUILD - CURL_TRC_DNS(data, "hostip_resolv(%s:%u, queries=%s)", - hostname, port, Curl_resolv_query_str(dns_queries)); - if((CURL_DNSQ_IP(dns_queries) == CURL_DNSQ_AAAA) && - getenv("CURL_DBG_RESOLV_FAIL_IPV6")) { - infof(data, "DEBUG fail ipv6 resolve"); - result = hostip_resolv_failed(data, hostname, for_proxy); - goto out; - } -#endif - /* Let's check our DNS cache first */ - result = Curl_dnscache_get(data, dns_queries, hostname, port, pdns); - if(*pdns) { - infof(data, "Hostname %s was found in DNS cache", hostname); - result = CURLE_OK; - } - else if(result) { - infof(data, "Negative DNS entry"); - result = hostip_resolv_failed(data, hostname, for_proxy); - } - else { - /* No luck, we need to start resolving. */ - cache_dns = TRUE; - result = hostip_resolv_start(data, dns_queries, hostname, port, - transport, for_proxy, timeout_ms, allowDOH, - presolv_id, pdns); - } - -out: - if(result && (result != CURLE_AGAIN)) { - Curl_dns_entry_unlink(data, pdns); - if(IS_RESOLV_FAIL(result)) { - if(cache_dns) - Curl_dnscache_add_negative(data, dns_queries, hostname, port); - failf(data, "Could not resolve: %s:%u", hostname, port); - } - else { - failf(data, "Error %d resolving %s:%u", result, hostname, port); - } - } - else if(cache_dns && *pdns) { - result = Curl_dnscache_add(data, *pdns); - if(result) - Curl_dns_entry_unlink(data, pdns); - } - - return result; -} - -CURLcode Curl_resolv_blocking(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - struct Curl_dns_entry **pdns) -{ - CURLcode result; - uint32_t resolv_id; - DEBUGASSERT(hostname && *hostname); - *pdns = NULL; - /* We cannot do a blocking resolve using DoH currently */ - result = hostip_resolv(data, dns_queries, - hostname, port, transport, FALSE, 0, FALSE, - &resolv_id, pdns); - switch(result) { - case CURLE_OK: - DEBUGASSERT(*pdns); - break; -#ifdef USE_CURL_ASYNC - case CURLE_AGAIN: - DEBUGASSERT(!*pdns); - result = Curl_async_await(data, resolv_id, pdns); - Curl_resolv_destroy(data, resolv_id); - break; -#endif - default: - break; - } - return result; -} - -#ifdef USE_ALARM_TIMEOUT -/* - * This signal handler jumps back into the main libcurl code and continues - * execution. This effectively causes the remainder of the application to run - * within a signal handler which is nonportable and could lead to problems. - */ -CURL_NORETURN static void alarmfunc(int sig) -{ - (void)sig; - siglongjmp(curl_jmpenv, 1); -} -#endif /* USE_ALARM_TIMEOUT */ - -#ifdef USE_ALARM_TIMEOUT - -static CURLcode resolv_alarm_timeout(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool for_proxy, - timediff_t timeout_ms, - uint32_t *presolv_id, - struct Curl_dns_entry **entry) -{ -#ifdef HAVE_SIGACTION - struct sigaction keep_sigact; /* store the old struct here */ - volatile bool keep_copysig = FALSE; /* whether old sigact has been saved */ - struct sigaction sigact; -#else -#ifdef HAVE_SIGNAL - void (*keep_sigact)(int); /* store the old handler here */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ - volatile long timeout; - volatile unsigned int prev_alarm = 0; - CURLcode result; - - DEBUGASSERT(hostname && *hostname); - DEBUGASSERT(timeout_ms > 0); - DEBUGASSERT(!data->set.no_signal); -#ifndef CURL_DISABLE_DOH - DEBUGASSERT(!data->set.doh); -#endif - - *entry = NULL; - timeout = (timeout_ms > LONG_MAX) ? LONG_MAX : (long)timeout_ms; - if(timeout < 1000) { - /* The alarm() function only provides integer second resolution, so if - we want to wait less than one second we must bail out already now. */ - failf(data, - "remaining timeout of %ld too small to resolve via SIGALRM method", - timeout); - return CURLE_OPERATION_TIMEDOUT; - } - /* This allows us to time-out from the name resolver, as the timeout - will generate a signal and we will siglongjmp() from that here. - This technique has problems (see alarmfunc). - This should be the last thing we do before calling Curl_resolv(), - as otherwise we would have to worry about variables that get modified - before we invoke Curl_resolv() (and thus use "volatile"). */ - curl_simple_lock_lock(&curl_jmpenv_lock); - - if(sigsetjmp(curl_jmpenv, 1)) { - /* this is coming from a siglongjmp() after an alarm signal */ - failf(data, "name lookup timed out"); - result = CURLE_OPERATION_TIMEDOUT; - goto clean_up; - } - else { - /************************************************************* - * Set signal handler to catch SIGALRM - * Store the old value to be able to set it back later! - *************************************************************/ -#ifdef HAVE_SIGACTION - sigaction(SIGALRM, NULL, &sigact); - keep_sigact = sigact; - keep_copysig = TRUE; /* yes, we have a copy */ - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HP-UX does not have SA_RESTART but defaults to that behavior! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - /* now set the new struct */ - sigaction(SIGALRM, &sigact, NULL); -#else /* HAVE_SIGACTION */ - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - keep_sigact = signal(SIGALRM, alarmfunc); -#endif -#endif /* HAVE_SIGACTION */ - - /* alarm() makes a signal get sent when the timeout fires off, and that - will abort system calls */ - prev_alarm = alarm(curlx_sltoui(timeout / 1000L)); - } - - /* Perform the actual name resolution. This might be interrupted by an - * alarm if it takes too long. */ - result = hostip_resolv(data, dns_queries, hostname, port, transport, - for_proxy, timeout_ms, FALSE, presolv_id, entry); - -clean_up: - if(!prev_alarm) - /* deactivate a possibly active alarm before uninstalling the handler */ - alarm(0); - -#ifdef HAVE_SIGACTION - if(keep_copysig) { - /* we got a struct as it looked before, now put that one back nice - and clean */ - sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ - } -#else -#ifdef HAVE_SIGNAL - /* restore the previous SIGALRM handler */ - signal(SIGALRM, keep_sigact); -#endif -#endif /* HAVE_SIGACTION */ - - curl_simple_lock_unlock(&curl_jmpenv_lock); - - /* switch back the alarm() to either zero or to what it was before minus - the time we spent until now! */ - if(prev_alarm) { - /* there was an alarm() set before us, now put it back */ - timediff_t elapsed_secs = curlx_ptimediff_ms(Curl_pgrs_now(data), - &data->conn->created) / 1000; - - /* the alarm period is counted in even number of seconds */ - unsigned long alarm_set = (unsigned long)(prev_alarm - elapsed_secs); - - if(!alarm_set || - ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000))) { - /* if the alarm time-left reached zero or turned "negative" (counted - with unsigned values), we should fire off a SIGALRM here, but we - will not, and zero would be to switch it off so we never set it to - less than 1! */ - alarm(1); - result = CURLE_OPERATION_TIMEDOUT; - failf(data, "Previous alarm fired off"); - } - else - alarm((unsigned int)alarm_set); - } - - return result; -} - -#endif /* USE_ALARM_TIMEOUT */ - -/* - * Curl_resolv() is the main name resolve function within libcurl. It resolves - * a name and returns a pointer to the entry in the 'entry' argument. This - * function might return immediately if we are using asynch resolves. See the - * return codes. - * - * The cache entry we return will get its 'inuse' counter increased when this - * function is used. You MUST call Curl_dns_entry_unlink() later (when you are - * done using this struct) to decrease the reference counter again. - * - * If built with a synchronous resolver and use of signals is not - * disabled by the application, then a nonzero timeout will cause a - * timeout after the specified number of milliseconds. Otherwise, timeout - * is ignored. - * - * Return codes: - * CURLE_OK = success, *pdns set to non-NULL - * CURLE_AGAIN = resolving in progress, *pdns == NULL - * any other CURLcode error, *pdns == NULL - */ -CURLcode Curl_resolv(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool for_proxy, - timediff_t timeout_ms, - uint32_t *presolv_id, - struct Curl_dns_entry **pdns) -{ - DEBUGASSERT(hostname && *hostname); - *presolv_id = 0; - *pdns = NULL; - - if(timeout_ms < 0) - /* got an already expired timeout */ - return CURLE_OPERATION_TIMEDOUT; - else if(!timeout_ms) - timeout_ms = CURL_TIMEOUT_RESOLVE_MS; - -#ifdef USE_ALARM_TIMEOUT - if(timeout_ms && data->set.no_signal) { - /* Cannot use ALARM when signals are disabled */ - timeout_ms = 0; - } - if(timeout_ms && !Curl_doh_wanted(data)) { - return resolv_alarm_timeout(data, dns_queries, hostname, port, transport, - for_proxy, timeout_ms, presolv_id, pdns); - } -#endif /* !USE_ALARM_TIMEOUT */ - -#ifndef CURLRES_ASYNCH - if(timeout_ms) - infof(data, "timeout on name lookup is not supported"); -#endif - - return hostip_resolv(data, dns_queries, hostname, port, transport, - for_proxy, timeout_ms, TRUE, presolv_id, pdns); -} - -#ifdef USE_CURL_ASYNC - -struct Curl_resolv_async *Curl_async_get(struct Curl_easy *data, - uint32_t resolv_id) -{ - struct Curl_resolv_async *async = data->state.async; - for(; async; async = async->next) { - if(async->id == resolv_id) - return async; - } - return NULL; -} - -CURLcode Curl_resolv_take_result(struct Curl_easy *data, uint32_t resolv_id, - struct Curl_dns_entry **pdns) -{ - struct Curl_resolv_async *async = Curl_async_get(data, resolv_id); - CURLcode result; - - /* If async resolving is ongoing, this must be set */ - if(!async) - return CURLE_FAILED_INIT; - - /* check if we have the name resolved by now (from someone else) */ - result = Curl_dnscache_get(data, async->dns_queries, - async->hostname, async->port, pdns); - if(*pdns) { - /* Tell a possibly async resolver we no longer need the results. */ - infof(data, "Hostname '%s' was found in DNS cache", async->hostname); - Curl_async_shutdown(data, async); - return CURLE_OK; - } - else if(result) { - Curl_async_shutdown(data, async); - return Curl_async_failed(data, async, NULL); - } - - result = hostip_resolv_take_result(data, async, pdns); - - if(*pdns) { - /* Add to cache */ - result = Curl_dnscache_add(data, *pdns); - if(result) - Curl_dns_entry_unlink(data, pdns); - } - else if(IS_RESOLV_FAIL(result)) { - Curl_dnscache_add_negative(data, async->dns_queries, - async->hostname, async->port); - failf(data, "Could not resolve: %s:%u", async->hostname, async->port); - } - else if(result) { - failf(data, "Error %d resolving %s:%u", - result, async->hostname, async->port); - } - return result; -} - -CURLcode Curl_resolv_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct Curl_resolv_async *async = data->state.async; - CURLcode result = CURLE_OK; - - (void)ps; - for(; async && !result; async = async->next) { -#ifndef CURL_DISABLE_DOH - if(async->doh) /* DoH has nothing for the pollset */ - continue; -#endif - result = Curl_async_pollset(data, async, ps); - } - return result; -} - -void Curl_resolv_destroy(struct Curl_easy *data, uint32_t resolv_id) -{ - struct Curl_resolv_async **panchor = &data->state.async; - - for(; *panchor; panchor = &(*panchor)->next) { - struct Curl_resolv_async *async = *panchor; - if(async->id == resolv_id) { - *panchor = async->next; - Curl_async_destroy(data, async); - break; - } - } -} - -void Curl_resolv_shutdown_all(struct Curl_easy *data) -{ - struct Curl_resolv_async *async = data->state.async; - for(; async; async = async->next) { - Curl_async_shutdown(data, async); - } -} - -void Curl_resolv_destroy_all(struct Curl_easy *data) -{ - while(data->state.async) { - struct Curl_resolv_async *async = data->state.async; - data->state.async = async->next; - Curl_async_destroy(data, async); - } -} - -#endif /* USE_CURL_ASYNC */ - -#ifdef USE_UNIX_SOCKETS -CURLcode Curl_resolv_unix(struct Curl_easy *data, - const char *unix_path, - bool abstract_path, - struct Curl_dns_entry **pdns) -{ - struct Curl_addrinfo *addr; - CURLcode result; - - DEBUGASSERT(unix_path); - *pdns = NULL; - - result = Curl_unix2addr(unix_path, abstract_path, &addr); - if(result) { - if(result == CURLE_TOO_LARGE) { - /* Long paths are not supported for now */ - failf(data, "Unix socket path too long: '%s'", unix_path); - result = CURLE_COULDNT_RESOLVE_HOST; - } - return result; - } - - *pdns = Curl_dnscache_mk_entry(data, 0, &addr, NULL, 0); - return *pdns ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} -#endif /* USE_UNIX_SOCKETS */ diff --git a/vendor/curl/lib/hostip.h b/vendor/curl/lib/hostip.h deleted file mode 100644 index 780fb4dc1..000000000 --- a/vendor/curl/lib/hostip.h +++ /dev/null @@ -1,194 +0,0 @@ -#ifndef HEADER_CURL_HOSTIP_H -#define HEADER_CURL_HOSTIP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "hash.h" -#include "curlx/timeval.h" /* for curltime, timediff_t */ - -/* Allocate enough memory to hold the full name information structs and - * everything. OSF1 is known to require at least 8872 bytes. The buffer - * required for storing all possible aliases and IP numbers is according to - * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes! - */ -#define CURL_HOSTENT_SIZE 9000 - -#define CURL_TIMEOUT_RESOLVE_MS (300 * 1000) - -struct addrinfo; -struct hostent; -struct Curl_easy; -struct connectdata; -struct easy_pollset; -struct Curl_https_rrinfo; -struct Curl_multi; -struct Curl_dns_entry; - -/* DNS query types */ -#define CURL_DNSQ_A (1U << 0) -#define CURL_DNSQ_AAAA (1U << 1) -#define CURL_DNSQ_HTTPS (1U << 2) - -#define CURL_DNSQ_ALL (CURL_DNSQ_A | CURL_DNSQ_AAAA | CURL_DNSQ_HTTPS) -#define CURL_DNSQ_IP(x) (uint8_t)((x)&(CURL_DNSQ_A | CURL_DNSQ_AAAA)) - -#ifdef CURLVERBOSE -const char *Curl_resolv_query_str(uint8_t dns_queries); -#endif - -/* Return CURL_DNSQ_* bits for the transfer and ip_version. */ -uint8_t Curl_resolv_dns_queries(struct Curl_easy *data, uint8_t ip_version); - -enum alpnid { - ALPN_none = 0, - ALPN_h1 = CURLALTSVC_H1, - ALPN_h2 = CURLALTSVC_H2, - ALPN_h3 = CURLALTSVC_H3 -}; - -bool Curl_host_is_ipnum(const char *hostname); - -#ifdef USE_IPV6 -/* probe if it seems to work */ -CURLcode Curl_probeipv6(struct Curl_multi *multi); -#else -#define Curl_probeipv6(x) CURLE_OK -#endif - -/* IPv4 thread-safe resolve function used for synch and asynch builds */ -struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, uint16_t port); - -/* - * Curl_printable_address() returns a printable version of the 1st address - * given in the 'ai' argument. The result will be stored in the buf that is - * bufsize bytes big. - */ -void Curl_printable_address(const struct Curl_addrinfo *ai, - char *buf, size_t bufsize); - -/* Start DNS resolving for the given parameters. Returns - * - CURLE_OK: `*pdns` is the resolved DNS entry (needs to be unlinked). - * `*presolv_id` is 0. - * - CURLE_AGAIN: resolve is asynchronous and not finished yet. - * `presolv_id` is the identifier for querying results later. - * - other: the operation failed, `*pdns` is NULL, `*presolv_id` is 0. - */ -CURLcode Curl_resolv(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - bool for_proxy, - timediff_t timeout_ms, - uint32_t *presolv_id, - struct Curl_dns_entry **pdns); - -CURLcode Curl_resolv_blocking(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport, - struct Curl_dns_entry **pdns); - -/* Announce start of a resolve operation to application callback, - * passing the resolver implementation (maybe NULL). */ -CURLcode Curl_resolv_announce_start(struct Curl_easy *data, - void *resolver); - -#ifdef USE_CURL_ASYNC - -CURLcode Curl_resolv_pollset(struct Curl_easy *data, - struct easy_pollset *ps); - -/* Get the `async` struct for the given `resolv_id`, if it exists. */ -struct Curl_resolv_async *Curl_async_get(struct Curl_easy *data, - uint32_t resolv_id); - -/* Shut down all resolves of the given easy handle. */ -void Curl_resolv_shutdown_all(struct Curl_easy *data); - -/* Destroy all resolve resources of the given easy handle. */ -void Curl_resolv_destroy_all(struct Curl_easy *data); - -CURLcode Curl_resolv_take_result(struct Curl_easy *data, uint32_t resolv_id, - struct Curl_dns_entry **pdns); - -void Curl_resolv_destroy(struct Curl_easy *data, uint32_t resolv_id); - -/* How much time has gone by since start of resolve. - * Returns CURL_TIMEOUT_RESOLVE_MS if `resolv_id` is no longer valid. */ -timediff_t Curl_resolv_elapsed_ms(struct Curl_easy *data, - uint32_t resolv_id); - -/* Return TRUE if `resolv_id` has answers (positive or negative) to - * all queries in `dns_queries`. - * Queries not requested are considered answered. */ -bool Curl_resolv_has_answers(struct Curl_easy *data, - uint32_t resolv_id, uint8_t dns_queries); - -const struct Curl_addrinfo *Curl_resolv_get_ai(struct Curl_easy *data, - uint32_t resolv_id, - int ai_family, - unsigned int index); -#ifdef USE_HTTPSRR -const struct Curl_https_rrinfo *Curl_resolv_get_https(struct Curl_easy *data, - uint32_t resolv_id); -bool Curl_resolv_knows_https(struct Curl_easy *data, uint32_t resolv_id); -#endif /* USE_HTTPSRR */ - -#else /* !USE_CURL_ASYNC */ -#define Curl_resolv_shutdown_all(x) Curl_nop_stmt -#define Curl_resolv_destroy_all(x) Curl_nop_stmt -#define Curl_resolv_take_result(x, y, z) CURLE_NOT_BUILT_IN -#define Curl_resolv_elapsed_ms(x, y) CURL_TIMEOUT_RESOLVE_MS -#define Curl_resolv_has_answers(x, y, z) TRUE -#define Curl_resolv_get_ai(x, y, z, a) NULL -#define Curl_resolv_get_https(x, y) NULL -#define Curl_resolv_knows_https(x, y) TRUE -#define Curl_resolv_pollset(x, y) CURLE_OK -#define Curl_resolv_destroy(x, y) Curl_nop_stmt -#endif /* USE_CURL_ASYNC */ - -#ifdef CURLRES_SYNCH -/* - * Curl_sync_getaddrinfo() is the non-async low-level name resolve API. - * There are several versions of this function - depending on IPV6 - * support and platform. - */ -struct Curl_addrinfo *Curl_sync_getaddrinfo(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport); -#endif - -#ifdef USE_UNIX_SOCKETS -CURLcode Curl_resolv_unix(struct Curl_easy *data, - const char *unix_path, - bool abstract_path, - struct Curl_dns_entry **pdns); -#endif - -#endif /* HEADER_CURL_HOSTIP_H */ diff --git a/vendor/curl/lib/hostip4.c b/vendor/curl/lib/hostip4.c deleted file mode 100644 index fb35e3992..000000000 --- a/vendor/curl/lib/hostip4.c +++ /dev/null @@ -1,283 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/*********************************************************************** - * Only for plain IPv4 builds - **********************************************************************/ -#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */ - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "hostip.h" -#include "url.h" - - -#ifdef CURLRES_SYNCH - -/* - * Curl_sync_getaddrinfo() - the IPv4 synchronous version. - * - * The original code to this function was from the Dancer source code, written - * by Bjorn Reese, it has since been patched and modified considerably. - * - * gethostbyname_r() is the thread-safe version of the gethostbyname() - * function. When we build for plain IPv4, we attempt to use this - * function. There are _three_ different gethostbyname_r() versions, and we - * detect which one this platform supports in the configure script and set up - * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or - * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME - * has the corresponding rules. This is primarily on *nix. Note that some Unix - * flavours have thread-safe versions of the plain gethostbyname() etc. - * - */ -struct Curl_addrinfo *Curl_sync_getaddrinfo(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport) -{ - struct Curl_addrinfo *ai = NULL; - - (void)dns_queries; - (void)transport; - - ai = Curl_ipv4_resolve_r(hostname, port); - if(!ai) - infof(data, "Curl_ipv4_resolve_r failed for %s", hostname); - - return ai; -} -#endif /* CURLRES_SYNCH */ -#endif /* CURLRES_IPV4 */ - -#if defined(CURLRES_IPV4) && !defined(USE_RESOLV_ARES) && \ - !defined(CURLRES_AMIGA) - -/* - * Curl_ipv4_resolve_r() - ipv4 thread-safe resolver function. - * - * This is used for both synchronous and asynchronous resolver builds, - * implying that only thread-safe code and function calls may be used. - * - */ -struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, - uint16_t port) -{ -#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)) && \ - defined(HAVE_GETHOSTBYNAME_R_3) - int res; -#endif - struct Curl_addrinfo *ai = NULL; -#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)) - struct hostent *h = NULL; - struct hostent *buf = NULL; -#endif - -#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE) - struct addrinfo hints; - char sbuf[12]; - char *sbufptr = NULL; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_INET; - hints.ai_socktype = SOCK_STREAM; - if(port) { - curl_msnprintf(sbuf, sizeof(sbuf), "%d", port); - sbufptr = sbuf; - } - - (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai); - -#elif defined(HAVE_GETHOSTBYNAME_R) - /* - * gethostbyname_r() is the preferred resolve function for many platforms. - * Since there are three different versions of it, the following code is - * somewhat #ifdef-ridden. - */ - int h_errnop; - - buf = curlx_calloc(1, CURL_HOSTENT_SIZE); - if(!buf) - return NULL; /* major failure */ - /* - * The clearing of the buffer is a workaround for a gethostbyname_r bug in - * QNX Neutrino and it is also _required_ for some of these functions on some - * platforms. - */ - -#ifdef HAVE_GETHOSTBYNAME_R_5 - /* Solaris, IRIX and more */ - h = gethostbyname_r(hostname, - (struct hostent *)buf, - (char *)buf + sizeof(struct hostent), - CURL_HOSTENT_SIZE - sizeof(struct hostent), - &h_errnop); - - /* If the buffer is too small, it returns NULL and sets errno to - * ERANGE. The errno is thread-safe if this is compiled with - * -D_REENTRANT as then the 'errno' variable is a macro defined to get - * used properly for threads. - */ - - if(h) { - ; - } - else -#elif defined(HAVE_GETHOSTBYNAME_R_6) - /* Linux */ - - (void)gethostbyname_r(hostname, - (struct hostent *)buf, - (char *)buf + sizeof(struct hostent), - CURL_HOSTENT_SIZE - sizeof(struct hostent), - &h, /* DIFFERENCE */ - &h_errnop); - /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a - * sudden this function returns EAGAIN if the given buffer size is too - * small. Previous versions are known to return ERANGE for the same - * problem. - * - * This would not be such a big problem if older versions would not - * sometimes return EAGAIN on a common failure case. Alas, we cannot - * assume that EAGAIN *or* ERANGE means ERANGE for any given version of - * glibc. - * - * For now, we do that and thus we may call the function repeatedly and - * fail for older glibc versions that return EAGAIN, until we run out of - * buffer size (step_size grows beyond CURL_HOSTENT_SIZE). - * - * If anyone has a better fix, please tell us! - * - * ------------------------------------------------------------------- - * - * On October 23rd 2003, Dan C dug up more details on the mysteries of - * gethostbyname_r() in glibc: - * - * In glibc 2.2.5 the interface is different (this has also been - * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I cannot - * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32 - * (shipped/upgraded by Redhat 7.2) do not show this behavior! - * - * In this "buggy" version, the return code is -1 on error and 'errno' - * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a - * thread-safe variable. - */ - - if(!h) /* failure */ -#elif defined(HAVE_GETHOSTBYNAME_R_3) - /* AIX, Digital UNIX/Tru64, HP-UX 10, more? */ - - /* For AIX 4.3 or later, we do not use gethostbyname_r() at all, because of - * the plain fact that it does not return unique full buffers on each - * call, but instead several of the pointers in the hostent structs will - * point to the same actual data! This have the unfortunate down-side that - * our caching system breaks down horribly. Luckily for us though, AIX 4.3 - * and more recent versions have a "completely thread-safe"[*] libc where - * all the data is stored in thread-specific memory areas making calls to - * the plain old gethostbyname() work fine even for multi-threaded - * programs. - * - * This AIX 4.3 or later detection is all made in the configure script. - * - * Troels Walsted Hansen helped us work this out on March 3rd, 2003. - * - * [*] = much later we have found out that it is not at all "completely - * thread-safe", but at least the gethostbyname() function is. - */ - - if(CURL_HOSTENT_SIZE >= - (sizeof(struct hostent) + sizeof(struct hostent_data))) { - - /* August 22nd, 2000: Albert Chin-A-Young brought an updated version - * that should work! September 20: Richard Prescott worked on the buffer - * size dilemma. - */ - - res = gethostbyname_r(hostname, - (struct hostent *)buf, - (struct hostent_data *)((char *)buf + - sizeof(struct hostent))); - h_errnop = SOCKERRNO; /* we do not deal with this, but set it anyway */ - } - else - res = -1; /* failure, too smallish buffer size */ - - if(!res) { /* success */ - - h = buf; /* result expected in h */ - - /* This is the worst kind of the different gethostbyname_r() interfaces. - * Since we do not know how big buffer this particular lookup required, - * we cannot realloc down the huge alloc without doing closer analysis of - * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every - * name lookup. Fixing this would require an extra allocation and then - * calling Curl_addrinfo_copy() that subsequent reallocation down the new - * memory area to the actually used amount. - */ - } - else -#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */ - { - h = NULL; /* set return code to NULL */ - curlx_free(buf); - } -#else /* (HAVE_GETADDRINFO && HAVE_GETADDRINFO_THREADSAFE) || - HAVE_GETHOSTBYNAME_R */ - /* - * Here is code for platforms that do not have a thread-safe - * getaddrinfo() nor gethostbyname_r() function or for which - * gethostbyname() is the preferred one. - */ - h = gethostbyname(CURL_UNCONST(hostname)); -#endif /* (HAVE_GETADDRINFO && HAVE_GETADDRINFO_THREADSAFE) || - HAVE_GETHOSTBYNAME_R */ - -#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)) - if(h) { - ai = Curl_he2ai(h, port); - - if(buf) /* used a *_r() function */ - curlx_free(buf); - } -#endif - - return ai; -} -#endif /* CURLRES_IPV4 && !USE_RESOLV_ARES && !CURLRES_AMIGA */ diff --git a/vendor/curl/lib/hostip6.c b/vendor/curl/lib/hostip6.c deleted file mode 100644 index 7412f428a..000000000 --- a/vendor/curl/lib/hostip6.c +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/*********************************************************************** - * Only for IPv6-enabled builds - **********************************************************************/ -#ifdef CURLRES_IPV6 - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "cfilters.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "hostip.h" -#include "url.h" -#include "curlx/inet_pton.h" -#include "connect.h" - -#ifdef CURLRES_SYNCH - -/* - * Curl_sync_getaddrinfo() when built IPv6-enabled (non-threading and - * non-ares version). - * - * Returns name information about the given hostname and port number. If - * successful, the 'addrinfo' is returned and the fourth argument will point - * to memory we need to free after use. That memory *MUST* be freed with - * Curl_freeaddrinfo(), nothing else. - */ -struct Curl_addrinfo *Curl_sync_getaddrinfo(struct Curl_easy *data, - uint8_t dns_queries, - const char *hostname, - uint16_t port, - uint8_t transport) -{ - struct addrinfo hints; - struct Curl_addrinfo *res; - int error; - char sbuf[12]; - char *sbufptr = NULL; -#ifndef USE_RESOLVE_ON_IPS - char addrbuf[128]; -#endif - int pf = PF_INET; - - if(dns_queries & CURL_DNSQ_AAAA) - pf = PF_UNSPEC; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = pf; - hints.ai_socktype = (transport == TRNSPRT_TCP) ? - SOCK_STREAM : SOCK_DGRAM; - -#ifndef USE_RESOLVE_ON_IPS - /* - * The AI_NUMERICHOST must not be set to get synthesized IPv6 address from - * an IPv4 address on iOS and macOS. - */ - if((curlx_inet_pton(AF_INET, hostname, addrbuf) == 1) || - (curlx_inet_pton(AF_INET6, hostname, addrbuf) == 1)) { - /* the given address is numerical only, prevent a reverse lookup */ - hints.ai_flags = AI_NUMERICHOST; - } -#endif - - if(port) { - curl_msnprintf(sbuf, sizeof(sbuf), "%d", port); - sbufptr = sbuf; - } - - error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res); - if(error) { - infof(data, "getaddrinfo(3) failed for %s:%d", hostname, port); - return NULL; - } - - if(port) { - Curl_addrinfo_set_port(res, port); - } - - return res; -} -#endif /* CURLRES_SYNCH */ - -#endif /* CURLRES_IPV6 */ diff --git a/vendor/curl/lib/hsts.c b/vendor/curl/lib/hsts.c deleted file mode 100644 index 400b4423d..000000000 --- a/vendor/curl/lib/hsts.c +++ /dev/null @@ -1,617 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * The Strict-Transport-Security header is defined in RFC 6797: - * https://datatracker.ietf.org/doc/html/rfc6797 - */ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS) -#include "urldata.h" -#include "llist.h" -#include "hsts.h" -#include "curl_fopen.h" -#include "curl_get_line.h" -#include "parsedate.h" -#include "curl_share.h" -#include "curlx/strparse.h" -#include "curlx/strcopy.h" - -#define MAX_HSTS_LINE 4095 -#define MAX_HSTS_HOSTLEN 2048 -#define MAX_HSTS_DATELEN 17 -#define UNLIMITED "unlimited" - -#if defined(DEBUGBUILD) || defined(UNITTESTS) -/* to play well with debug builds, we can *set* a fixed time this will - return */ -time_t deltatime; /* allow for "adjustments" for unit test purposes */ -static time_t hsts_debugtime(void *unused) -{ - const char *timestr = getenv("CURL_TIME"); - (void)unused; - if(timestr) { - curl_off_t val; - if(!curlx_str_number(×tr, &val, TIME_T_MAX)) - val += (curl_off_t)deltatime; - return (time_t)val; - } - return time(NULL); -} -#undef time -#define time(x) hsts_debugtime(x) -#endif - -struct hsts *Curl_hsts_init(void) -{ - struct hsts *h = curlx_calloc(1, sizeof(struct hsts)); - if(h) { - Curl_llist_init(&h->list, NULL); - } - return h; -} - -#define hsts_free(x) curlx_free(x) - -void Curl_hsts_cleanup(struct hsts **hp) -{ - struct hsts *h = *hp; - if(h) { - struct Curl_llist_node *e; - struct Curl_llist_node *n; - for(e = Curl_llist_head(&h->list); e; e = n) { - struct stsentry *sts = Curl_node_elem(e); - n = Curl_node_next(e); - hsts_free(sts); - } - curlx_free(h->filename); - curlx_free(h); - *hp = NULL; - } -} - -/* append the new entry to the list after possibly removing an old entry - first */ -static void hsts_append(struct hsts *h, struct stsentry *sts) -{ - if(Curl_llist_count(&h->list) == MAX_HSTS_ENTRIES) { - /* It's full. Remove the first entry in the list */ - struct Curl_llist_node *e = Curl_llist_head(&h->list); - struct stsentry *oldsts = Curl_node_elem(e); - Curl_node_remove(e); - hsts_free(oldsts); - } - Curl_llist_append(&h->list, sts, &sts->node); -} - -static CURLcode hsts_create(struct hsts *h, - const char *hostname, - size_t hlen, - bool subdomains, - curl_off_t expires) -{ - DEBUGASSERT(h); - DEBUGASSERT(hostname); - - if(hlen && (hostname[hlen - 1] == '.')) - /* strip off any trailing dot */ - --hlen; - if(hlen) { - struct stsentry *sts = curlx_calloc(1, sizeof(struct stsentry) + hlen); - if(!sts) - return CURLE_OUT_OF_MEMORY; - /* the null terminator is already there */ - memcpy(sts->host, hostname, hlen); - sts->expires = expires; - sts->includeSubDomains = subdomains; - hsts_append(h, sts); - } - return CURLE_OK; -} - -CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, - const char *header) -{ - const char *p = header; - curl_off_t expires = 0; - bool gotma = FALSE; - bool gotinc = FALSE; - bool subdomains = FALSE; - struct stsentry *sts; - time_t now = time(NULL); - size_t hlen = strlen(hostname); - - if(Curl_host_is_ipnum(hostname)) - /* "explicit IP address identification of all forms is excluded." - / RFC 6797 */ - return CURLE_OK; - - do { - curlx_str_passblanks(&p); - if(curl_strnequal("max-age", p, 7)) { - bool quoted = FALSE; - int rc; - - if(gotma) - return CURLE_BAD_FUNCTION_ARGUMENT; - - p += 7; - curlx_str_passblanks(&p); - if(curlx_str_single(&p, '=')) - return CURLE_BAD_FUNCTION_ARGUMENT; - curlx_str_passblanks(&p); - - if(!curlx_str_single(&p, '\"')) - quoted = TRUE; - - rc = curlx_str_number(&p, &expires, TIME_T_MAX); - if(rc == STRE_OVERFLOW) - expires = CURL_OFF_T_MAX; - else if(rc) - /* invalid max-age */ - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(quoted) { - if(*p != '\"') - return CURLE_BAD_FUNCTION_ARGUMENT; - p++; - } - gotma = TRUE; - } - else if(curl_strnequal("includesubdomains", p, 17)) { - if(gotinc) - return CURLE_BAD_FUNCTION_ARGUMENT; - subdomains = TRUE; - p += 17; - gotinc = TRUE; - } - else { - /* unknown directive, do a lame attempt to skip */ - while(*p && (*p != ';')) - p++; - } - - curlx_str_passblanks(&p); - if(*p == ';') - p++; - } while(*p); - - if(!gotma) - /* max-age is mandatory */ - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(!expires) { - /* remove the entry if present verbatim (without subdomain match) */ - sts = Curl_hsts(h, hostname, hlen, FALSE); - if(sts) { - Curl_node_remove(&sts->node); - hsts_free(sts); - } - return CURLE_OK; - } - - if(CURL_OFF_T_MAX - now < expires) - /* would overflow, use maximum value */ - expires = CURL_OFF_T_MAX; - else - expires += now; - - /* check if it already exists */ - sts = Curl_hsts(h, hostname, hlen, FALSE); - if(sts) { - /* update these fields */ - sts->expires = expires; - sts->includeSubDomains = subdomains; - } - else - return hsts_create(h, hostname, hlen, subdomains, expires); - - return CURLE_OK; -} - -/* - * Return TRUE if the given hostname is currently an HSTS one. - * - * The 'subdomain' argument tells the function if subdomain matching should be - * attempted. - */ -struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, - size_t hlen, bool subdomain) -{ - struct stsentry *bestsub = NULL; - if(h) { - time_t now = time(NULL); - struct Curl_llist_node *e; - struct Curl_llist_node *n; - size_t blen = 0; - - if((hlen > MAX_HSTS_HOSTLEN) || !hlen) - return NULL; - if(hostname[hlen - 1] == '.') - /* remove the trailing dot */ - --hlen; - - for(e = Curl_llist_head(&h->list); e; e = n) { - struct stsentry *sts = Curl_node_elem(e); - size_t ntail; - n = Curl_node_next(e); - if(sts->expires <= now) { - /* remove expired entries */ - Curl_node_remove(&sts->node); - hsts_free(sts); - continue; - } - ntail = strlen(sts->host); - if((subdomain && sts->includeSubDomains) && (ntail < hlen)) { - size_t offs = hlen - ntail; - if((hostname[offs - 1] == '.') && - curl_strnequal(&hostname[offs], sts->host, ntail) && - (ntail > blen)) { - /* save the tail match with the longest tail */ - bestsub = sts; - blen = ntail; - } - } - /* avoid curl_strequal because the hostname is not null-terminated */ - if((hlen == ntail) && curl_strnequal(hostname, sts->host, hlen)) - return sts; - } - } - return bestsub; -} - -/* - * Send this HSTS entry to the write callback. - */ -static CURLcode hsts_push(struct Curl_easy *data, - struct curl_index *i, - struct stsentry *sts, - bool *stop) -{ - struct curl_hstsentry e; - CURLSTScode sc; - struct tm stamp; - CURLcode result; - - e.name = (char *)sts->host; - e.namelen = strlen(sts->host); - e.includeSubDomains = sts->includeSubDomains; - - if(sts->expires != TIME_T_MAX) { - result = curlx_gmtime((time_t)sts->expires, &stamp); - if(result) - return result; - - curl_msnprintf(e.expire, sizeof(e.expire), "%d%02d%02d %02d:%02d:%02d", - stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, - stamp.tm_hour, stamp.tm_min, stamp.tm_sec); - } - else - curlx_strcopy(e.expire, sizeof(e.expire), STRCONST(UNLIMITED)); - - sc = data->set.hsts_write(data, &e, i, data->set.hsts_write_userp); - *stop = (sc != CURLSTS_OK); - return sc == CURLSTS_FAIL ? CURLE_BAD_FUNCTION_ARGUMENT : CURLE_OK; -} - -/* - * Write this single hsts entry to a single output line - */ -static CURLcode hsts_out(struct stsentry *sts, FILE *fp) -{ - struct tm stamp; - if(sts->expires != TIME_T_MAX) { - CURLcode result = curlx_gmtime((time_t)sts->expires, &stamp); - if(result) - return result; - curl_mfprintf(fp, "%s%s \"%d%02d%02d %02d:%02d:%02d\"\n", - sts->includeSubDomains ? "." : "", sts->host, - stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, - stamp.tm_hour, stamp.tm_min, stamp.tm_sec); - } - else - curl_mfprintf(fp, "%s%s \"%s\"\n", - sts->includeSubDomains ? "." : "", sts->host, UNLIMITED); - return CURLE_OK; -} - -/* - * Curl_https_save() writes the HSTS cache to file and callback. - */ -CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, - const char *file) -{ - struct Curl_llist_node *e; - struct Curl_llist_node *n; - CURLcode result = CURLE_OK; - FILE *out; - char *tempstore = NULL; - - if(!h) - /* no cache activated */ - return CURLE_OK; - - /* if no new name is given, use the one we stored from the load */ - if(!file && h->filename) - file = h->filename; - - if((h->flags & CURLHSTS_READONLYFILE) || !file || !file[0]) - /* marked as read-only, no file or zero length filename */ - goto skipsave; - - result = Curl_fopen(data, file, &out, &tempstore); - if(!result) { - fputs("# Your HSTS cache. https://curl.se/docs/hsts.html\n" - "# This file was generated by libcurl! Edit at your own risk.\n", - out); - for(e = Curl_llist_head(&h->list); e; e = n) { - struct stsentry *sts = Curl_node_elem(e); - n = Curl_node_next(e); - result = hsts_out(sts, out); - if(result) - break; - } - curlx_fclose(out); - if(!result && tempstore && curlx_rename(tempstore, file)) - result = CURLE_WRITE_ERROR; - - if(result && tempstore) - unlink(tempstore); - } - curlx_free(tempstore); -skipsave: - if(data->set.hsts_write) { - /* if there is a write callback */ - struct curl_index i; /* count */ - i.total = Curl_llist_count(&h->list); - i.index = 0; - for(e = Curl_llist_head(&h->list); e; e = n) { - struct stsentry *sts = Curl_node_elem(e); - bool stop; - n = Curl_node_next(e); - result = hsts_push(data, &i, sts, &stop); - if(result || stop) - break; - i.index++; - } - } - return result; -} - -/* only returns SERIOUS errors */ -static CURLcode hsts_add_host_expire(struct hsts *h, - const char *host, size_t hostlen, - const char *expire, size_t explen, - bool subdomain) /* default */ -{ - CURLcode result = CURLE_OK; - struct stsentry *e; - char dbuf[MAX_HSTS_DATELEN + 1]; - time_t expires = 0; - time_t now = time(NULL); - - /* The date parser works on a null-terminated string. */ - if(explen > MAX_HSTS_DATELEN) - return CURLE_BAD_FUNCTION_ARGUMENT; - memcpy(dbuf, expire, explen); - dbuf[explen] = 0; - - if(!strcmp(dbuf, UNLIMITED)) - expires = TIME_T_MAX; - else - Curl_getdate_capped(dbuf, &expires); - - if(expires <= now) - /* this entry already expired */ - return CURLE_OK; - - if(host[0] == '.') { - host++; - hostlen--; - subdomain = TRUE; - } - if(hostlen && (host[hostlen - 1] == '.')) - /* strip off any trailing dot */ - hostlen--; - - if(hostlen) { - /* only add it if not already present */ - e = Curl_hsts(h, host, hostlen, subdomain); - if(!e) - result = hsts_create(h, host, hostlen, subdomain, expires); - /* 'host' is not necessarily null terminated */ - else if((hostlen == strlen(e->host) && - curl_strnequal(host, e->host, hostlen))) { - /* the same hostname, use the largest expire time and keep the strictest - subdomain policy */ - if(expires > e->expires) - e->expires = expires; - if(subdomain) - e->includeSubDomains = TRUE; - } - } - return result; -} - -/* only returns SERIOUS errors */ -static CURLcode hsts_add(struct hsts *h, const char *line) -{ - /* Example lines: - example.com "20191231 10:00:00" - .example.net "20191231 10:00:00" - */ - struct Curl_str host; - struct Curl_str date; - - if(curlx_str_word(&line, &host, MAX_HSTS_HOSTLEN) || - curlx_str_singlespace(&line) || - curlx_str_quotedword(&line, &date, MAX_HSTS_DATELEN) || - curlx_str_newline(&line)) - ; - else { - return hsts_add_host_expire(h, curlx_str(&host), curlx_strlen(&host), - curlx_str(&date), curlx_strlen(&date), - FALSE); - } - - return CURLE_OK; -} - -/* - * Load HSTS data from callback. - * - */ -static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h) -{ - /* if the HSTS read callback is set, use it */ - if(data->set.hsts_read) { - CURLSTScode sc; - DEBUGASSERT(h); - do { - char buffer[MAX_HSTS_HOSTLEN + 1]; - struct curl_hstsentry e; - e.name = buffer; - e.namelen = sizeof(buffer) - 1; - e.includeSubDomains = FALSE; /* default */ - e.expire[0] = 0; - e.expire[MAX_HSTS_DATELEN] = 0; - e.name[0] = 0; /* to make it clean */ - e.name[MAX_HSTS_HOSTLEN] = 0; - sc = data->set.hsts_read(data, &e, data->set.hsts_read_userp); - if(sc == CURLSTS_OK) { - CURLcode result; - const char *date = e.expire; - if(!e.name[0] || e.expire[MAX_HSTS_DATELEN] || - e.name[MAX_HSTS_HOSTLEN]) - /* bail out if no name was stored or if a null terminator is gone */ - return CURLE_BAD_FUNCTION_ARGUMENT; - if(!date[0]) - date = UNLIMITED; - result = hsts_add_host_expire(h, e.name, strlen(e.name), - date, strlen(date), - /* bitfield to bool conversion: */ - e.includeSubDomains ? TRUE : FALSE); - if(result) - return result; - } - else if(sc == CURLSTS_FAIL) - return CURLE_ABORTED_BY_CALLBACK; - } while(sc == CURLSTS_OK); - } - return CURLE_OK; -} - -/* - * Load the HSTS cache from the given file. The text based line-oriented file - * format is documented here: https://curl.se/docs/hsts.html - * - * This function only returns error on major problems that prevent hsts - * handling to work completely. It will ignore individual syntactical errors - * etc. - */ -static CURLcode hsts_load(struct hsts *h, const char *file) -{ - CURLcode result = CURLE_OK; - FILE *fp; - - /* we need a private copy of the filename so that the hsts cache file - name survives an easy handle reset */ - curlx_free(h->filename); - h->filename = curlx_strdup(file); - if(!h->filename) - return CURLE_OUT_OF_MEMORY; - - fp = curlx_fopen(file, FOPEN_READTEXT); - if(fp) { - curlx_struct_stat stat; - if((curlx_fstat(fileno(fp), &stat) == -1) || !S_ISDIR(stat.st_mode)) { - struct dynbuf buf; - bool eof = FALSE; - curlx_dyn_init(&buf, MAX_HSTS_LINE); - do { - result = Curl_get_line(&buf, fp, &eof); - if(!result) { - const char *lineptr = curlx_dyn_ptr(&buf); - curlx_str_passblanks(&lineptr); - - /* Skip empty or commented lines, since we know the line will have - a trailing newline from Curl_get_line we can treat length 1 as - empty. */ - if((*lineptr == '#') || strlen(lineptr) <= 1) - continue; - - hsts_add(h, lineptr); - } - } while(!result && !eof); - curlx_dyn_free(&buf); /* free the line buffer */ - } - curlx_fclose(fp); - } - return result; -} - -/* - * Curl_hsts_loadfile() loads HSTS from file - */ -CURLcode Curl_hsts_loadfile(struct Curl_easy *data, - struct hsts *h, const char *file) -{ - DEBUGASSERT(h); - (void)data; - return hsts_load(h, file); -} - -/* - * Curl_hsts_loadcb() loads HSTS from callback - */ -CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h) -{ - if(h) - return hsts_pull(data, h); - return CURLE_OK; -} - -CURLcode Curl_hsts_loadfiles(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - struct curl_slist *l = data->state.hstslist; - if(l) { - Curl_share_lock(data, CURL_LOCK_DATA_HSTS, CURL_LOCK_ACCESS_SINGLE); - - while(l) { - result = Curl_hsts_loadfile(data, data->hsts, l->data); - if(result) - break; - l = l->next; - } - Curl_share_unlock(data, CURL_LOCK_DATA_HSTS); - } - return result; -} - -#if defined(DEBUGBUILD) || defined(UNITTESTS) -#undef time -#endif - -#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ diff --git a/vendor/curl/lib/hsts.h b/vendor/curl/lib/hsts.h deleted file mode 100644 index 0e6585f11..000000000 --- a/vendor/curl/lib/hsts.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef HEADER_CURL_HSTS_H -#define HEADER_CURL_HSTS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS) -#include "llist.h" - -#define MAX_HSTS_ENTRIES 10000 - -#if defined(DEBUGBUILD) || defined(UNITTESTS) -extern time_t deltatime; -#endif - -struct stsentry { - struct Curl_llist_node node; - curl_off_t expires; /* the timestamp of this entry's expiry */ - BIT(includeSubDomains); - char host[1]; -}; - -/* The HSTS cache. Needs to be able to tailmatch hostnames. */ -struct hsts { - struct Curl_llist list; - char *filename; - unsigned int flags; -}; - -struct hsts *Curl_hsts_init(void); -void Curl_hsts_cleanup(struct hsts **hp); -CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, - const char *header); -struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, - size_t hlen, bool subdomain); -CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, - const char *file); -CURLcode Curl_hsts_loadfile(struct Curl_easy *data, - struct hsts *h, const char *file); -CURLcode Curl_hsts_loadcb(struct Curl_easy *data, - struct hsts *h); -CURLcode Curl_hsts_loadfiles(struct Curl_easy *data); -#else -#define Curl_hsts_cleanup(x) -#define Curl_hsts_loadcb(x, y) CURLE_OK -#define Curl_hsts_save(x, y, z) -#define Curl_hsts_loadfiles(x) CURLE_OK -#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ -#endif /* HEADER_CURL_HSTS_H */ diff --git a/vendor/curl/lib/http.c b/vendor/curl/lib/http.c deleted file mode 100644 index 9118c7e71..000000000 --- a/vendor/curl/lib/http.c +++ /dev/null @@ -1,5063 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" - -#ifndef CURL_DISABLE_HTTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "transfer.h" -#include "sendf.h" -#include "curl_trc.h" -#include "formdata.h" -#include "mime.h" -#include "progress.h" -#include "curlx/base64.h" -#include "cookie.h" -#include "vauth/vauth.h" -#include "vquic/vquic.h" -#include "http_digest.h" -#include "http_ntlm.h" -#include "http_negotiate.h" -#include "http_aws_sigv4.h" -#include "url.h" -#include "urlapi-int.h" -#include "curl_share.h" -#include "hostip.h" -#include "dynhds.h" -#include "http.h" -#include "headers.h" -#include "select.h" -#include "parsedate.h" /* for the week day and month names */ -#include "multiif.h" -#include "strcase.h" -#include "content_encoding.h" -#include "http_proxy.h" -#include "http2.h" -#include "cfilters.h" -#include "connect.h" -#include "curlx/strdup.h" -#include "altsvc.h" -#include "hsts.h" -#include "rtsp.h" -#include "ws.h" -#include "bufref.h" -#include "curlx/strparse.h" - -void Curl_http_neg_init(struct Curl_easy *data, struct http_negotiation *neg) -{ - memset(neg, 0, sizeof(*neg)); - neg->accept_09 = data->set.http09_allowed; - switch(data->set.httpwant) { - case CURL_HTTP_VERSION_1_0: - neg->wanted = neg->allowed = (CURL_HTTP_V1x); - neg->only_10 = TRUE; - break; - case CURL_HTTP_VERSION_1_1: - neg->wanted = neg->allowed = (CURL_HTTP_V1x); - break; - case CURL_HTTP_VERSION_2_0: - neg->wanted = neg->allowed = (CURL_HTTP_V1x | CURL_HTTP_V2x); - neg->h2_upgrade = TRUE; - break; - case CURL_HTTP_VERSION_2TLS: - neg->wanted = neg->allowed = (CURL_HTTP_V1x | CURL_HTTP_V2x); - break; - case CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE: - neg->wanted = neg->allowed = (CURL_HTTP_V2x); - data->state.http_neg.h2_prior_knowledge = TRUE; - break; - case CURL_HTTP_VERSION_3: - neg->wanted = (CURL_HTTP_V1x | CURL_HTTP_V2x | CURL_HTTP_V3x); - neg->allowed = neg->wanted; - break; - case CURL_HTTP_VERSION_3ONLY: - neg->wanted = neg->allowed = (CURL_HTTP_V3x); - break; - case CURL_HTTP_VERSION_NONE: - default: - neg->wanted = (CURL_HTTP_V1x | CURL_HTTP_V2x); - neg->allowed = (CURL_HTTP_V1x | CURL_HTTP_V2x | CURL_HTTP_V3x); - break; - } -} - -CURLcode Curl_http_setup_conn(struct Curl_easy *data, - struct connectdata *conn) -{ - /* allocate the HTTP-specific struct for the Curl_easy, only to survive - during this request */ - if(data->state.http_neg.wanted == CURL_HTTP_V3x) { - /* only HTTP/3, needs to work */ - CURLcode result = Curl_conn_may_http3(data, conn, conn->transport_wanted); - if(result) - return result; - } - return CURLE_OK; -} - -#ifndef CURL_DISABLE_PROXY -/* - * checkProxyHeaders() checks the linked list of custom proxy headers - * if proxy headers are not available, then it will lookup into http header - * link list - * - * It takes a connectdata struct as input to see if this is a proxy request or - * not, as it then might check a different header list. Provide the header - * prefix without colon! - */ -char *Curl_checkProxyheaders(struct Curl_easy *data, - const struct connectdata *conn, - const char *thisheader, - const size_t thislen) -{ - struct curl_slist *head; - - for(head = (conn->bits.proxy && data->set.sep_headers) ? - data->set.proxyheaders : data->set.headers; - head; head = head->next) { - if(curl_strnequal(head->data, thisheader, thislen) && - Curl_headersep(head->data[thislen])) - return head->data; - } - - return NULL; -} -#endif - -/* If the header has a value, this function returns TRUE and the value is in - 'outp' with blanks trimmed off. -*/ -static bool header_has_value(const char **headerp, struct Curl_str *outp) -{ - bool value = !curlx_str_cspn(headerp, outp, ";:") && - (!curlx_str_single(headerp, ':') || !curlx_str_single(headerp, ';')); - - if(value) { - curlx_str_untilnl(headerp, outp, MAX_HTTP_RESP_HEADER_SIZE); - curlx_str_trimblanks(outp); - } - return value; -} - -static bool http_header_is_empty(const char *header) -{ - struct Curl_str out; - - if(header_has_value(&header, &out)) { - return curlx_strlen(&out) == 0; - } - return TRUE; /* invalid header format, treat as empty */ -} - -/* - * Strip off leading and trailing whitespace from the value in the given HTTP - * header line and return a strdup-ed copy in 'valp' - returns an empty - * string if the header value consists entirely of whitespace. - * - * If the header is provided as "name;", ending with a semicolon, it returns a - * blank string. - */ -static CURLcode copy_custom_value(const char *header, char **valp) -{ - struct Curl_str out; - - /* find the end of the header name */ - if(header_has_value(&header, &out)) { - *valp = curlx_memdup0(curlx_str(&out), curlx_strlen(&out)); - if(*valp) - return CURLE_OK; - return CURLE_OUT_OF_MEMORY; - } - /* bad input */ - *valp = NULL; - return CURLE_BAD_FUNCTION_ARGUMENT; -} - -/* - * Strip off leading and trailing whitespace from the value in the given HTTP - * header line and return a strdup-ed copy in 'valp' - returns an empty - * string if the header value consists entirely of whitespace. - * - * This function MUST be used after the header has already been confirmed to - * lead with "word:". - * - * @unittest: 1626 - */ -char *Curl_copy_header_value(const char *header) -{ - struct Curl_str out; - - /* find the end of the header name */ - if(!curlx_str_until(&header, &out, MAX_HTTP_RESP_HEADER_SIZE, ':') && - !curlx_str_single(&header, ':')) { - curlx_str_untilnl(&header, &out, MAX_HTTP_RESP_HEADER_SIZE); - curlx_str_trimblanks(&out); - return curlx_memdup0(curlx_str(&out), curlx_strlen(&out)); - } - /* bad input, should never happen */ - DEBUGASSERT(0); - return NULL; -} - -#ifndef CURL_DISABLE_HTTP_AUTH - -#ifndef CURL_DISABLE_BASIC_AUTH -/* - * http_output_basic() sets up an Authorization: header (or the proxy version) - * for HTTP Basic authentication. - * - * Returns CURLcode. - */ -static CURLcode http_output_basic(struct Curl_easy *data, bool proxy) -{ - size_t size = 0; - char *authorization = NULL; - char **userp; - const char *user; - const char *pwd; - CURLcode result; - char *out; - - /* credentials are unique per transfer for HTTP, do not use the ones for the - connection */ - if(proxy) { -#ifndef CURL_DISABLE_PROXY - userp = &data->req.proxyuserpwd; - user = data->state.aptr.proxyuser; - pwd = data->state.aptr.proxypasswd; -#else - return CURLE_NOT_BUILT_IN; -#endif - } - else { - userp = &data->req.userpwd; - user = data->state.aptr.user; - pwd = data->state.aptr.passwd; - } - - out = curl_maprintf("%s:%s", user ? user : "", pwd ? pwd : ""); - if(!out) - return CURLE_OUT_OF_MEMORY; - - result = curlx_base64_encode((uint8_t *)out, strlen(out), - &authorization, &size); - if(result) - goto fail; - - if(!authorization) { - result = CURLE_REMOTE_ACCESS_DENIED; - goto fail; - } - - curlx_free(*userp); - *userp = curl_maprintf("%sAuthorization: Basic %s\r\n", - proxy ? "Proxy-" : "", - authorization); - curlx_free(authorization); - if(!*userp) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - -fail: - curlx_free(out); - return result; -} - -#endif - -#ifndef CURL_DISABLE_BEARER_AUTH -/* - * http_output_bearer() sets up an Authorization: header - * for HTTP Bearer authentication. - * - * Returns CURLcode. - */ -static CURLcode http_output_bearer(struct Curl_easy *data) -{ - char **userp; - CURLcode result = CURLE_OK; - - userp = &data->req.userpwd; - curlx_free(*userp); - *userp = curl_maprintf("Authorization: Bearer %s\r\n", - data->set.str[STRING_BEARER]); - - if(!*userp) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - -fail: - return result; -} - -#endif - -#endif - -/* pickoneauth() selects the most favorable authentication method from the - * ones available and the ones we want. - * - * return TRUE if one was picked - */ -static bool pickoneauth(struct auth *pick, unsigned long mask) -{ - bool picked; - /* only deal with authentication we want */ - unsigned long avail = pick->avail & pick->want & mask; - picked = TRUE; - - /* The order of these checks is highly relevant, as this will be the order - of preference in case of the existence of multiple accepted types. */ - if(avail & CURLAUTH_NEGOTIATE) - pick->picked = CURLAUTH_NEGOTIATE; -#ifndef CURL_DISABLE_BEARER_AUTH - else if(avail & CURLAUTH_BEARER) - pick->picked = CURLAUTH_BEARER; -#endif -#ifndef CURL_DISABLE_DIGEST_AUTH - else if(avail & CURLAUTH_DIGEST) - pick->picked = CURLAUTH_DIGEST; -#endif - else if(avail & CURLAUTH_NTLM) - pick->picked = CURLAUTH_NTLM; -#ifndef CURL_DISABLE_BASIC_AUTH - else if(avail & CURLAUTH_BASIC) - pick->picked = CURLAUTH_BASIC; -#endif -#ifndef CURL_DISABLE_AWS - else if(avail & CURLAUTH_AWS_SIGV4) - pick->picked = CURLAUTH_AWS_SIGV4; -#endif - else { - pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */ - picked = FALSE; - } - pick->avail = CURLAUTH_NONE; /* clear it here */ - - return picked; -} - -/* - * http_perhapsrewind() - * - * The current request needs to be done again - maybe due to a follow - * or authentication negotiation. Check if: - * 1) a rewind of the data sent to the server is necessary - * 2) the current transfer should continue or be stopped early - */ -static CURLcode http_perhapsrewind(struct Curl_easy *data, - struct connectdata *conn) -{ - curl_off_t bytessent = data->req.writebytecount; - curl_off_t expectsend = Curl_creader_total_length(data); - curl_off_t upload_remain = (expectsend >= 0) ? (expectsend - bytessent) : -1; - bool little_upload_remains = (upload_remain >= 0 && upload_remain < 2000); - bool needs_rewind = Curl_creader_needs_rewind(data); - /* By default, we would like to abort the transfer when little or unknown - * amount remains. This may be overridden by authentications further - * below! */ - bool abort_upload = (!data->req.upload_done && !little_upload_remains); - VERBOSE(const char *ongoing_auth = NULL); - - /* We need a rewind before uploading client read data again. The - * checks below influence of the upload is to be continued - * or aborted early. - * This depends on how much remains to be sent and in what state - * the authentication is. Some auth schemes such as NTLM do not work - * for a new connection. */ - if(needs_rewind) { - infof(data, "Need to rewind upload for next request"); - Curl_creader_set_rewind(data, TRUE); - } - - if(conn->bits.close) - /* If we already decided to close this connection, we cannot veto. */ - return CURLE_OK; - - if(abort_upload) { - /* We would like to abort the upload - but should we? */ -#ifdef USE_NTLM - if((data->state.authproxy.picked == CURLAUTH_NTLM) || - (data->state.authhost.picked == CURLAUTH_NTLM)) { - VERBOSE(ongoing_auth = "NTLM"); - if((conn->http_ntlm_state != NTLMSTATE_NONE) || - (conn->proxy_ntlm_state != NTLMSTATE_NONE)) { - /* The NTLM-negotiation has started, keep on sending. - * Need to do further work on same connection */ - abort_upload = FALSE; - } - } -#endif -#ifdef USE_SPNEGO - /* There is still data left to send */ - if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) || - (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) { - VERBOSE(ongoing_auth = "NEGOTIATE"); - if((conn->http_negotiate_state != GSS_AUTHNONE) || - (conn->proxy_negotiate_state != GSS_AUTHNONE)) { - /* The NEGOTIATE-negotiation has started, keep on sending. - * Need to do further work on same connection */ - abort_upload = FALSE; - } - } -#endif - } - - if(abort_upload) { - if(upload_remain >= 0) - infof(data, "%s%sclose instead of sending %" FMT_OFF_T " more bytes", - ongoing_auth ? ongoing_auth : "", - ongoing_auth ? " send, " : "", - upload_remain); - else - infof(data, "%s%sclose instead of sending unknown amount " - "of more bytes", - ongoing_auth ? ongoing_auth : "", - ongoing_auth ? " send, " : ""); - /* We decided to abort the ongoing transfer */ - streamclose(conn, "Mid-auth HTTP and much data left to send"); - data->req.size = 0; /* do not download any more than 0 bytes */ - data->req.http_bodyless = TRUE; - } - return CURLE_OK; -} - -/** - * http_should_fail() determines whether an HTTP response code has gotten us - * into an error state or not. - * - * @retval FALSE communications should continue - * - * @retval TRUE communications should not continue - */ -static bool http_should_fail(struct Curl_easy *data, int httpcode) -{ - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - - /* - * If we have not been asked to fail on error, - * do not fail. - */ - if(!data->set.http_fail_on_error) - return FALSE; - - /* - * Any code < 400 is never terminal. - */ - if(httpcode < 400) - return FALSE; - - /* - * A 416 response to a resume request is presumably because the file is - * already completely downloaded and thus not actually a fail. - */ - if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET && - httpcode == 416) - return FALSE; - - /* - * Any code >= 400 that is not 401 or 407 is always - * a terminal error - */ - if((httpcode != 401) && (httpcode != 407)) - return TRUE; - - /* - * All we have left to deal with is 401 and 407 - */ - DEBUGASSERT((httpcode == 401) || (httpcode == 407)); - - /* - * Examine the current authentication state to see if this is an error. The - * idea is for this function to get called after processing all the headers - * in a response message. If we have been to asked to authenticate - * a particular stage, and we have done it, we are OK. If we are already - * completely authenticated, it is not OK to get another 401 or 407. - * - * It is possible for authentication to go stale such that the client needs - * to reauthenticate. Once that info is available, use it here. - */ - - /* - * Either we are not authenticating, or we are supposed to be authenticating - * something else. This is an error. - */ - if((httpcode == 401) && !data->state.aptr.user) - return TRUE; -#ifndef CURL_DISABLE_PROXY - if((httpcode == 407) && !data->conn->bits.proxy_user_passwd) - return TRUE; -#endif - - return (bool)data->state.authproblem; -} - -/* - * Curl_http_auth_act() gets called when all HTTP headers have been received - * and it checks what authentication methods that are available and decides - * which one (if any) to use. It will set 'newurl' if an auth method was - * picked. - */ -CURLcode Curl_http_auth_act(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - bool pickhost = FALSE; - bool pickproxy = FALSE; - CURLcode result = CURLE_OK; - unsigned long authmask = ~0UL; - - if(!data->set.str[STRING_BEARER]) - authmask &= (unsigned long)~CURLAUTH_BEARER; - - if(100 <= data->req.httpcode && data->req.httpcode <= 199) - /* this is a transient response code, ignore */ - return CURLE_OK; - - if(data->state.authproblem) - return data->set.http_fail_on_error ? CURLE_HTTP_RETURNED_ERROR : CURLE_OK; - - if((data->state.aptr.user || data->set.str[STRING_BEARER]) && - ((data->req.httpcode == 401) || - (data->req.authneg && data->req.httpcode < 300))) { - pickhost = pickoneauth(&data->state.authhost, authmask); - if(!pickhost) - data->state.authproblem = TRUE; - else - data->info.httpauthpicked = data->state.authhost.picked; - if(data->state.authhost.picked == CURLAUTH_NTLM && - (data->req.httpversion_sent > 11)) { - infof(data, "Forcing HTTP/1.1 for NTLM"); - connclose(conn, "Force HTTP/1.1 connection"); - data->state.http_neg.wanted = CURL_HTTP_V1x; - data->state.http_neg.allowed = CURL_HTTP_V1x; - } - } -#ifndef CURL_DISABLE_PROXY - if(conn->bits.proxy_user_passwd && - ((data->req.httpcode == 407) || - (data->req.authneg && data->req.httpcode < 300))) { - pickproxy = pickoneauth(&data->state.authproxy, - authmask & ~CURLAUTH_BEARER); - if(!pickproxy) - data->state.authproblem = TRUE; - else - data->info.proxyauthpicked = data->state.authproxy.picked; - } -#endif - - if(pickhost || pickproxy) { - result = http_perhapsrewind(data, conn); - if(result) - return result; - - /* In case this is GSS auth, the newurl field is already allocated so - we must make sure to free it before allocating a new one. As figured - out in bug #2284386 */ - curlx_free(data->req.newurl); - /* clone URL */ - data->req.newurl = Curl_bufref_dup(&data->state.url); - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - } - else if((data->req.httpcode < 300) && - !data->state.authhost.done && - data->req.authneg) { - /* no (known) authentication available, - authentication is not "done" yet and - no authentication seems to be required and - we did not try HEAD or GET */ - if((data->state.httpreq != HTTPREQ_GET) && - (data->state.httpreq != HTTPREQ_HEAD)) { - /* clone URL */ - data->req.newurl = Curl_bufref_dup(&data->state.url); - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - data->state.authhost.done = TRUE; - } - } - if(http_should_fail(data, data->req.httpcode)) { - failf(data, "The requested URL returned error: %d", - data->req.httpcode); - result = CURLE_HTTP_RETURNED_ERROR; - } - - return result; -} - -#ifndef CURL_DISABLE_HTTP_AUTH -/* - * Output the correct authentication header depending on the auth type - * and whether or not it is to a proxy. - */ -static CURLcode output_auth_headers(struct Curl_easy *data, - struct connectdata *conn, - struct auth *authstatus, - const char *request, - const char *path, - bool proxy) -{ - const char *auth = NULL; - CURLcode result = CURLE_OK; - (void)conn; - -#ifdef CURL_DISABLE_DIGEST_AUTH - (void)request; - (void)path; -#endif -#ifndef CURL_DISABLE_AWS - if((authstatus->picked == CURLAUTH_AWS_SIGV4) && !proxy) { - /* this method is never for proxy */ - auth = "AWS_SIGV4"; - result = Curl_output_aws_sigv4(data); - if(result) - return result; - } - else -#endif -#ifdef USE_SPNEGO - if(authstatus->picked == CURLAUTH_NEGOTIATE) { - auth = "Negotiate"; - result = Curl_output_negotiate(data, conn, proxy); - if(result) - return result; - } - else -#endif -#ifdef USE_NTLM - if(authstatus->picked == CURLAUTH_NTLM) { - auth = "NTLM"; - result = Curl_output_ntlm(data, proxy); - if(result) - return result; - } - else -#endif -#ifndef CURL_DISABLE_DIGEST_AUTH - if(authstatus->picked == CURLAUTH_DIGEST) { - auth = "Digest"; - result = Curl_output_digest(data, - proxy, - (const unsigned char *)request, - (const unsigned char *)path); - if(result) - return result; - } - else -#endif -#ifndef CURL_DISABLE_BASIC_AUTH - if(authstatus->picked == CURLAUTH_BASIC) { - /* Basic */ - if( -#ifndef CURL_DISABLE_PROXY - (proxy && conn->bits.proxy_user_passwd && - !Curl_checkProxyheaders(data, conn, - STRCONST("Proxy-authorization"))) || -#endif - (!proxy && data->state.aptr.user && - !Curl_checkheaders(data, STRCONST("Authorization")))) { - auth = "Basic"; - result = http_output_basic(data, proxy); - if(result) - return result; - } - - /* NOTE: this function should set 'done' TRUE, as the other auth - functions work that way */ - authstatus->done = TRUE; - } -#endif -#ifndef CURL_DISABLE_BEARER_AUTH - if(authstatus->picked == CURLAUTH_BEARER) { - /* Bearer */ - if(!proxy && data->set.str[STRING_BEARER] && - Curl_auth_allowed_to_host(data) && - !Curl_checkheaders(data, STRCONST("Authorization"))) { - auth = "Bearer"; - result = http_output_bearer(data); - if(result) - return result; - } - - /* NOTE: this function should set 'done' TRUE, as the other auth - functions work that way */ - authstatus->done = TRUE; - } -#endif - - if(auth) { -#ifndef CURL_DISABLE_PROXY - if(proxy) - data->info.proxyauthpicked = authstatus->picked; - else - data->info.httpauthpicked = authstatus->picked; - infof(data, "%s auth using %s with user '%s'", - proxy ? "Proxy" : "Server", auth, - proxy ? (data->state.aptr.proxyuser ? - data->state.aptr.proxyuser : "") : - (data->state.aptr.user ? - data->state.aptr.user : "")); -#else - (void)proxy; - infof(data, "Server auth using %s with user '%s'", - auth, data->state.aptr.user ? - data->state.aptr.user : ""); -#endif - authstatus->multipass = !authstatus->done; - } - else { - authstatus->multipass = FALSE; - if(proxy) - data->info.proxyauthpicked = 0; - else - data->info.httpauthpicked = 0; - } - - return result; -} - -/** - * Curl_http_output_auth() setups the authentication headers for the - * host/proxy and the correct authentication - * method. data->state.authdone is set to TRUE when authentication is - * done. - * - * @param conn all information about the current connection - * @param request pointer to the request keyword - * @param path pointer to the requested path; should include query part - * @param proxytunnel boolean if this is the request setting up a "proxy - * tunnel" - * - * @returns CURLcode - */ -CURLcode Curl_http_output_auth(struct Curl_easy *data, - struct connectdata *conn, - const char *request, - Curl_HttpReq httpreq, - const char *path, - bool proxytunnel) /* TRUE if this is - the request setting up - the proxy tunnel */ -{ - CURLcode result = CURLE_OK; - struct auth *authhost; - struct auth *authproxy; - - DEBUGASSERT(data); - - authhost = &data->state.authhost; - authproxy = &data->state.authproxy; - - if( -#ifndef CURL_DISABLE_PROXY - (conn->bits.httpproxy && conn->bits.proxy_user_passwd) || -#endif - data->state.aptr.user || -#ifdef USE_SPNEGO - authhost->want & CURLAUTH_NEGOTIATE || - authproxy->want & CURLAUTH_NEGOTIATE || -#endif - data->set.str[STRING_BEARER]) - /* continue please */; - else { - authhost->done = TRUE; - authproxy->done = TRUE; - return CURLE_OK; /* no authentication with no user or password */ - } - - if(authhost->want && !authhost->picked) - /* The app has selected one or more methods, but none has been picked - so far by a server round-trip. Then we set the picked one to the - want one, and if this is one single bit it will be used instantly. */ - authhost->picked = authhost->want; - - if(authproxy->want && !authproxy->picked) - /* The app has selected one or more methods, but none has been picked so - far by a proxy round-trip. Then we set the picked one to the want one, - and if this is one single bit it will be used instantly. */ - authproxy->picked = authproxy->want; - -#ifndef CURL_DISABLE_PROXY - /* Send proxy authentication header if needed */ - if(conn->bits.httpproxy && - (conn->bits.tunnel_proxy == (curl_bit)proxytunnel)) { - result = output_auth_headers(data, conn, authproxy, request, path, TRUE); - if(result) - return result; - } - else -#else - (void)proxytunnel; -#endif /* CURL_DISABLE_PROXY */ - /* we have no proxy so let's pretend we are done authenticating - with it */ - authproxy->done = TRUE; - - /* To prevent the user+password to get sent to other than the original host - due to a location-follow */ - if(Curl_auth_allowed_to_host(data) -#ifndef CURL_DISABLE_NETRC - || conn->bits.netrc -#endif - ) - result = output_auth_headers(data, conn, authhost, request, path, FALSE); - else - authhost->done = TRUE; - - if(((authhost->multipass && !authhost->done) || - (authproxy->multipass && !authproxy->done)) && - (httpreq != HTTPREQ_GET) && - (httpreq != HTTPREQ_HEAD)) { - /* Auth is required and we are not authenticated yet. Make a PUT or POST - with content-length zero as a "probe". */ - data->req.authneg = TRUE; - } - else - data->req.authneg = FALSE; - - return result; -} - -#else -/* when disabled */ -CURLcode Curl_http_output_auth(struct Curl_easy *data, - struct connectdata *conn, - const char *request, - Curl_HttpReq httpreq, - const char *path, - bool proxytunnel) -{ - (void)data; - (void)conn; - (void)request; - (void)httpreq; - (void)path; - (void)proxytunnel; - return CURLE_OK; -} -#endif - -#if defined(USE_SPNEGO) || defined(USE_NTLM) || \ - !defined(CURL_DISABLE_DIGEST_AUTH) || \ - !defined(CURL_DISABLE_BASIC_AUTH) || \ - !defined(CURL_DISABLE_BEARER_AUTH) -static bool authcmp(const char *auth, const char *line) -{ - /* the auth string must not have an alnum following */ - size_t n = strlen(auth); - return curl_strnequal(auth, line, n) && !ISALNUM(line[n]); -} -#endif - -#ifdef USE_SPNEGO -static CURLcode auth_spnego(struct Curl_easy *data, - bool proxy, - const char *auth, - struct auth *authp, - uint32_t *availp) -{ - if((authp->avail & CURLAUTH_NEGOTIATE) || Curl_auth_is_spnego_supported()) { - *availp |= CURLAUTH_NEGOTIATE; - authp->avail |= CURLAUTH_NEGOTIATE; - - if(authp->picked == CURLAUTH_NEGOTIATE) { - struct connectdata *conn = data->conn; - CURLcode result = Curl_input_negotiate(data, conn, proxy, auth); - curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state : - &conn->http_negotiate_state; - if(!result) { - curlx_free(data->req.newurl); - data->req.newurl = Curl_bufref_dup(&data->state.url); - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - data->state.authproblem = FALSE; - /* we received a GSS auth token and we dealt with it fine */ - *negstate = GSS_AUTHRECV; - } - else - data->state.authproblem = TRUE; - } - } - return CURLE_OK; -} -#endif - -#ifdef USE_NTLM -static CURLcode auth_ntlm(struct Curl_easy *data, - bool proxy, - const char *auth, - struct auth *authp, - uint32_t *availp) -{ - /* NTLM support requires the SSL crypto libs */ - if((authp->avail & CURLAUTH_NTLM) || Curl_auth_is_ntlm_supported()) { - *availp |= CURLAUTH_NTLM; - authp->avail |= CURLAUTH_NTLM; - - if(authp->picked == CURLAUTH_NTLM) { - /* NTLM authentication is picked and activated */ - CURLcode result = Curl_input_ntlm(data, proxy, auth); - if(!result) - data->state.authproblem = FALSE; - else { - if(result == CURLE_OUT_OF_MEMORY) - return result; - infof(data, "NTLM authentication problem, ignoring."); - data->state.authproblem = TRUE; - } - } - } - return CURLE_OK; -} -#endif - -#ifndef CURL_DISABLE_DIGEST_AUTH -static CURLcode auth_digest(struct Curl_easy *data, - bool proxy, - const char *auth, - struct auth *authp, - uint32_t *availp) -{ - if(authp->avail & CURLAUTH_DIGEST) { - *availp |= CURLAUTH_DIGEST; - infof(data, "Ignoring duplicate digest auth header."); - } - else if(Curl_auth_is_digest_supported()) { - CURLcode result; - - *availp |= CURLAUTH_DIGEST; - authp->avail |= CURLAUTH_DIGEST; - - /* We call this function on input Digest headers even if Digest - * authentication is not activated yet, as we need to store the - * incoming data from this header in case we are going to use - * Digest */ - result = Curl_input_digest(data, proxy, auth); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - return result; - infof(data, "Digest authentication problem, ignoring."); - data->state.authproblem = TRUE; - } - } - return CURLE_OK; -} -#endif - -#ifndef CURL_DISABLE_BASIC_AUTH -static CURLcode auth_basic(struct Curl_easy *data, - struct auth *authp, - uint32_t *availp) -{ - *availp |= CURLAUTH_BASIC; - authp->avail |= CURLAUTH_BASIC; - if(authp->picked == CURLAUTH_BASIC) { - /* We asked for Basic authentication but got a 40X back anyway, which - means our name+password is not valid. */ - authp->avail = CURLAUTH_NONE; - infof(data, "Basic authentication problem, ignoring."); - data->state.authproblem = TRUE; - } - return CURLE_OK; -} -#endif - -#ifndef CURL_DISABLE_BEARER_AUTH -static CURLcode auth_bearer(struct Curl_easy *data, - struct auth *authp, - uint32_t *availp) -{ - *availp |= CURLAUTH_BEARER; - authp->avail |= CURLAUTH_BEARER; - if(authp->picked == CURLAUTH_BEARER) { - /* We asked for Bearer authentication but got a 40X back anyway, which - means our token is not valid. */ - authp->avail = CURLAUTH_NONE; - infof(data, "Bearer authentication problem, ignoring."); - data->state.authproblem = TRUE; - } - return CURLE_OK; -} -#endif - -/* - * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: - * headers. They are dealt with both in the transfer.c main loop and in the - * proxy CONNECT loop. - * - * The 'auth' line ends with a null byte without CR or LF present. - */ -CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, - const char *auth) /* the first non-space */ -{ - /* - * This resource requires authentication - */ -#if defined(USE_SPNEGO) || \ - defined(USE_NTLM) || \ - !defined(CURL_DISABLE_DIGEST_AUTH) || \ - !defined(CURL_DISABLE_BASIC_AUTH) || \ - !defined(CURL_DISABLE_BEARER_AUTH) - - uint32_t *availp; - struct auth *authp; - CURLcode result = CURLE_OK; - DEBUGASSERT(auth); - DEBUGASSERT(data); - - if(proxy) { - availp = &data->info.proxyauthavail; - authp = &data->state.authproxy; - } - else { - availp = &data->info.httpauthavail; - authp = &data->state.authhost; - } - - /* - * Here we check if we want the specific single authentication (using ==) and - * if we do, we initiate usage of it. - * - * If the provided authentication is wanted as one out of several accepted - * types (using &), we OR this authentication type to the authavail - * variable. - * - * Note: - * - * ->picked is first set to the 'want' value (one or more bits) before the - * request is sent, and then it is again set _after_ all response 401/407 - * headers have been received but then only to a single preferred method - * (bit). - */ - - while(*auth) { -#ifdef USE_SPNEGO - if(authcmp("Negotiate", auth)) - result = auth_spnego(data, proxy, auth, authp, availp); -#endif -#ifdef USE_NTLM - if(!result && authcmp("NTLM", auth)) - result = auth_ntlm(data, proxy, auth, authp, availp); -#endif -#ifndef CURL_DISABLE_DIGEST_AUTH - if(!result && authcmp("Digest", auth)) - result = auth_digest(data, proxy, auth, authp, availp); -#endif -#ifndef CURL_DISABLE_BASIC_AUTH - if(!result && authcmp("Basic", auth)) - result = auth_basic(data, authp, availp); -#endif -#ifndef CURL_DISABLE_BEARER_AUTH - if(authcmp("Bearer", auth)) - result = auth_bearer(data, authp, availp); -#endif - - if(result) - break; - - /* there may be multiple methods on one line, so keep reading */ - auth = strchr(auth, ','); - if(auth) /* if we are on a comma, skip it */ - auth++; - else - break; - curlx_str_passblanks(&auth); - } - return result; -#else - (void)data; - (void)proxy; - (void)auth; - /* nothing to do when disabled */ - return CURLE_OK; -#endif -} - -static void http_switch_to_get(struct Curl_easy *data, int code) -{ - const char *req = data->set.str[STRING_CUSTOMREQUEST]; - - if((req || data->state.httpreq != HTTPREQ_GET) && - (data->set.http_follow_mode == CURLFOLLOW_OBEYCODE)) { - NOVERBOSE((void)code); - infof(data, "Switch to GET because of %d response", code); - data->state.http_ignorecustom = TRUE; - } - else if(req && (data->set.http_follow_mode != CURLFOLLOW_FIRSTONLY)) - infof(data, "Stick to %s instead of GET", req); - - data->state.httpreq = HTTPREQ_GET; - Curl_creader_set_rewind(data, FALSE); -} - -#define HTTPREQ_IS_POST(data) \ - ((data)->state.httpreq == HTTPREQ_POST || \ - (data)->state.httpreq == HTTPREQ_POST_FORM || \ - (data)->state.httpreq == HTTPREQ_POST_MIME) - -CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl, - followtype type) -{ - bool disallowport = FALSE; - bool reachedmax = FALSE; - char *follow_url = NULL; - CURLUcode uc; - CURLcode rewind_result; - bool switch_to_get = FALSE; - - DEBUGASSERT(type != FOLLOW_NONE); - - if(type != FOLLOW_FAKE) - data->state.requests++; /* count all real follows */ - if(type == FOLLOW_REDIR) { - if((data->set.maxredirs != -1) && - (data->state.followlocation >= data->set.maxredirs)) { - reachedmax = TRUE; - type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected - to URL */ - } - else { - data->state.followlocation++; /* count redirect-followings, including - auth reloads */ - - if(data->set.http_auto_referer) { - CURLU *u; - char *referer = NULL; - - /* We are asked to automatically set the previous URL as the referer - when we get the next URL. We pick the ->url field, which may or may - not be 100% correct */ - Curl_bufref_free(&data->state.referer); - - /* Make a copy of the URL without credentials and fragment */ - u = curl_url(); - if(!u) - return CURLE_OUT_OF_MEMORY; - - uc = curl_url_set(u, CURLUPART_URL, - Curl_bufref_ptr(&data->state.url), 0); - if(!uc) - uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0); - if(!uc) - uc = curl_url_set(u, CURLUPART_USER, NULL, 0); - if(!uc) - uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0); - if(!uc) - uc = curl_url_get(u, CURLUPART_URL, &referer, 0); - - curl_url_cleanup(u); - - if(uc || !referer) - return CURLE_OUT_OF_MEMORY; - - Curl_bufref_set(&data->state.referer, referer, 0, curl_free); - } - } - } - - if((type != FOLLOW_RETRY) && - (data->req.httpcode != 401) && (data->req.httpcode != 407) && - Curl_is_absolute_url(newurl, NULL, 0, FALSE)) { - /* If this is not redirect due to a 401 or 407 response and an absolute - URL: do not allow a custom port number */ - disallowport = TRUE; - } - - DEBUGASSERT(data->state.uh); - uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, (unsigned int) - ((type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME : - ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) | - CURLU_ALLOW_SPACE | - (data->set.path_as_is ? CURLU_PATH_AS_IS : 0))); - if(uc) { - if((uc == CURLUE_OUT_OF_MEMORY) || (type != FOLLOW_FAKE)) { - failf(data, "The redirect target URL could not be parsed: %s", - curl_url_strerror(uc)); - return Curl_uc_to_curlcode(uc); - } - - /* the URL could not be parsed for some reason, but since this is FAKE - mode, duplicate the field as-is */ - follow_url = curlx_strdup(newurl); - if(!follow_url) - return CURLE_OUT_OF_MEMORY; - } - else { - bool same_origin; - CURLcode result; - CURLU *u = curl_url(); - if(!u) - return CURLE_OUT_OF_MEMORY; - uc = curl_url_set(u, CURLUPART_URL, - Curl_bufref_ptr(&data->state.url), - CURLU_URLENCODE | CURLU_ALLOW_SPACE); - if(!uc) - uc = curl_url_get(data->state.uh, CURLUPART_URL, &follow_url, 0); - if(uc) { - curl_url_cleanup(u); - return Curl_uc_to_curlcode(uc); - } - - same_origin = Curl_url_same_origin(u, data->state.uh); - curl_url_cleanup(u); - -#ifndef CURL_DISABLE_DIGEST_AUTH - if(!same_origin) - Curl_auth_digest_cleanup(&data->state.digest); -#endif - - if((!same_origin && !data->set.allow_auth_to_other_hosts) || - !data->set.str[STRING_USERNAME]) { - result = Curl_reset_userpwd(data); - if(result) { - curlx_free(follow_url); - return result; - } - curlx_safefree(data->state.aptr.user); - curlx_safefree(data->state.aptr.passwd); - } - result = Curl_reset_proxypwd(data); - if(result) { - curlx_free(follow_url); - return result; - } - } - DEBUGASSERT(follow_url); - - if(type == FOLLOW_FAKE) { - /* we are only figuring out the new URL if we would have followed locations - but now we are done so we can get out! */ - data->info.wouldredirect = follow_url; - - if(reachedmax) { - failf(data, "Maximum (%d) redirects followed", data->set.maxredirs); - return CURLE_TOO_MANY_REDIRECTS; - } - return CURLE_OK; - } - - if(disallowport) - data->state.allow_port = FALSE; - - Curl_bufref_set(&data->state.url, follow_url, 0, curl_free); - rewind_result = Curl_req_soft_reset(&data->req, data); - infof(data, "Issue another request to this URL: '%s'", follow_url); - if((data->set.http_follow_mode == CURLFOLLOW_FIRSTONLY) && - data->set.str[STRING_CUSTOMREQUEST] && - !data->state.http_ignorecustom) { - data->state.http_ignorecustom = TRUE; - infof(data, "Drop custom request method for next request"); - } - - /* - * We get here when the HTTP code is 300-399 (and 401). We need to perform - * differently based on exactly what return code there was. - * - * News from 7.10.6: we can also get here on a 401 or 407, in case we act on - * an HTTP (proxy-) authentication scheme other than Basic. - */ - switch(data->info.httpcode) { - /* 401 - Act on a WWW-Authenticate, we keep on moving and do the - Authorization: XXXX header in the HTTP request code snippet */ - /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the - Proxy-Authorization: XXXX header in the HTTP request code snippet */ - /* 300 - Multiple Choices */ - /* 306 - Not used */ - /* 307 - Temporary Redirect */ - default: /* for all above (and the unknown ones) */ - /* Some codes are explicitly mentioned since I have checked RFC2616 and - * they seem to be OK to POST to. - */ - break; - case 301: /* Moved Permanently */ - /* (quote from RFC7231, section 6.4.2) - * - * Note: For historical reasons, a user agent MAY change the request - * method from POST to GET for the subsequent request. If this - * behavior is undesired, the 307 (Temporary Redirect) status code - * can be used instead. - * - * ---- - * - * Many webservers expect this, so these servers often answers to a POST - * request with an error page. To be sure that libcurl gets the page that - * most user agents would get, libcurl has to force GET. - * - * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and - * can be overridden with CURLOPT_POSTREDIR. - */ - if(HTTPREQ_IS_POST(data) && !data->set.post301) { - http_switch_to_get(data, 301); - switch_to_get = TRUE; - } - break; - case 302: /* Found */ - /* (quote from RFC7231, section 6.4.3) - * - * Note: For historical reasons, a user agent MAY change the request - * method from POST to GET for the subsequent request. If this - * behavior is undesired, the 307 (Temporary Redirect) status code - * can be used instead. - * - * ---- - * - * Many webservers expect this, so these servers often answers to a POST - * request with an error page. To be sure that libcurl gets the page that - * most user agents would get, libcurl has to force GET. - * - * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and - * can be overridden with CURLOPT_POSTREDIR. - */ - if(HTTPREQ_IS_POST(data) && !data->set.post302) { - http_switch_to_get(data, 302); - switch_to_get = TRUE; - } - break; - - case 303: /* See Other */ - /* 'See Other' location is not the resource but a substitute for the - * resource. In this case we switch the method to GET/HEAD, unless the - * method is POST and the user specified to keep it as POST. - */ - if(!HTTPREQ_IS_POST(data) || !data->set.post303) { - http_switch_to_get(data, 303); - switch_to_get = TRUE; - } - break; - case 304: /* Not Modified */ - /* 304 means we did a conditional request and it was "Not modified". - * We should not get any Location: header in this response! - */ - break; - case 305: /* Use Proxy */ - /* (quote from RFC2616, section 10.3.6): - * "The requested resource MUST be accessed through the proxy given - * by the Location field. The Location field gives the URI of the - * proxy. The recipient is expected to repeat this single request - * via the proxy. 305 responses MUST only be generated by origin - * servers." - */ - break; - } - - /* When rewind of upload data failed and we are not switching to GET, - * we need to fail the follow, as we cannot send the data again. */ - if(rewind_result && !switch_to_get) - return rewind_result; - - Curl_pgrsTime(data, TIMER_REDIRECT); - Curl_pgrsResetTransferSizes(data); - - return CURLE_OK; -} - -/* - * Curl_compareheader() - * - * Returns TRUE if 'headerline' contains the 'header' with given 'content' - * (within a comma-separated list of tokens). Pass 'header' WITH the colon. - * - * @unittest: 1625 - */ -bool Curl_compareheader(const char *headerline, /* line to check */ - const char *header, /* header keyword _with_ colon */ - const size_t hlen, /* len of the keyword in bytes */ - const char *content, /* content string to find */ - const size_t clen) /* len of the content in bytes */ -{ - /* RFC2616, section 4.2 says: "Each header field consists of a name followed - * by a colon (":") and the field value. Field names are case-insensitive. - * The field value MAY be preceded by any amount of LWS, though a single SP - * is preferred." */ - - const char *p; - struct Curl_str val; - DEBUGASSERT(hlen); - DEBUGASSERT(clen); - DEBUGASSERT(header); - DEBUGASSERT(content); - - if(!curl_strnequal(headerline, header, hlen)) - return FALSE; /* does not start with header */ - - /* pass the header */ - p = &headerline[hlen]; - - if(curlx_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE)) - return FALSE; - curlx_str_trimblanks(&val); - - /* find the content string in the rest of the line */ - if(curlx_strlen(&val) >= clen) { - size_t len; - p = curlx_str(&val); - for(len = curlx_strlen(&val); len >= clen;) { - struct Curl_str next; - const char *o = p; - /* after a match there must be a comma, space, newline or null byte */ - if(curl_strnequal(p, content, clen) && - ((p[clen] == ',') || ISBLANK(p[clen]) || ISNEWLINE(p[clen]) || - !p[clen])) - return TRUE; /* match! */ - /* advance to the next comma */ - if(curlx_str_until(&p, &next, MAX_HTTP_RESP_HEADER_SIZE, ',') || - curlx_str_single(&p, ',')) - break; /* no comma, get out */ - - /* if there are more dummy commas, move over them as well */ - do - curlx_str_passblanks(&p); - while(!curlx_str_single(&p, ',')); - len -= (p - o); - } - } - return FALSE; /* no match */ -} - -struct cr_exp100_ctx { - struct Curl_creader super; - struct curltime start; /* time started waiting */ - enum expect100 state; -}; - -/* Expect: 100-continue client reader, blocking uploads */ - -static void http_exp100_continue(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_exp100_ctx *ctx = reader->ctx; - if(ctx->state > EXP100_SEND_DATA) { - ctx->state = EXP100_SEND_DATA; - Curl_expire_done(data, EXPIRE_100_TIMEOUT); - } -} - -static CURLcode cr_exp100_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *nread, bool *eos) -{ - struct cr_exp100_ctx *ctx = reader->ctx; - timediff_t ms; - - switch(ctx->state) { - case EXP100_SENDING_REQUEST: - if(!Curl_req_sendbuf_empty(data)) { - /* The initial request data has not been fully sent yet. Do - * not start the timer yet. */ - DEBUGF(infof(data, "cr_exp100_read, request not full sent yet")); - *nread = 0; - *eos = FALSE; - return CURLE_OK; - } - /* We are now waiting for a reply from the server or - * a timeout on our side IFF the request has been fully sent. */ - DEBUGF(infof(data, "cr_exp100_read, start AWAITING_CONTINUE, " - "timeout %dms", data->set.expect_100_timeout)); - ctx->state = EXP100_AWAITING_CONTINUE; - ctx->start = *Curl_pgrs_now(data); - Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); - *nread = 0; - *eos = FALSE; - return CURLE_OK; - case EXP100_FAILED: - DEBUGF(infof(data, "cr_exp100_read, expectation failed, error")); - *nread = 0; - *eos = FALSE; - return CURLE_READ_ERROR; - case EXP100_AWAITING_CONTINUE: - ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &ctx->start); - if(ms < data->set.expect_100_timeout) { - DEBUGF(infof(data, "cr_exp100_read, AWAITING_CONTINUE, not expired")); - *nread = 0; - *eos = FALSE; - return CURLE_OK; - } - /* we have waited long enough, continue anyway */ - http_exp100_continue(data, reader); - infof(data, "Done waiting for 100-continue"); - FALLTHROUGH(); - default: - DEBUGF(infof(data, "cr_exp100_read, pass through")); - return Curl_creader_read(data, reader->next, buf, blen, nread, eos); - } -} - -static void cr_exp100_done(struct Curl_easy *data, - struct Curl_creader *reader, int premature) -{ - struct cr_exp100_ctx *ctx = reader->ctx; - ctx->state = premature ? EXP100_FAILED : EXP100_SEND_DATA; - Curl_expire_done(data, EXPIRE_100_TIMEOUT); -} - -static const struct Curl_crtype cr_exp100 = { - "cr-exp100", - Curl_creader_def_init, - cr_exp100_read, - Curl_creader_def_close, - Curl_creader_def_needs_rewind, - Curl_creader_def_total_length, - Curl_creader_def_resume_from, - Curl_creader_def_cntrl, - Curl_creader_def_is_paused, - cr_exp100_done, - sizeof(struct cr_exp100_ctx) -}; - -static CURLcode http_exp100_add_reader(struct Curl_easy *data) -{ - struct Curl_creader *reader = NULL; - CURLcode result; - - result = Curl_creader_create(&reader, data, &cr_exp100, CURL_CR_PROTOCOL); - if(!result) - result = Curl_creader_add(data, reader); - if(!result) { - struct cr_exp100_ctx *ctx = reader->ctx; - ctx->state = EXP100_SENDING_REQUEST; - } - - if(result && reader) - Curl_creader_free(data, reader); - return result; -} - -static void http_exp100_got100(struct Curl_easy *data) -{ - struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100); - if(r) - http_exp100_continue(data, r); -} - -static bool http_exp100_is_waiting(struct Curl_easy *data) -{ - struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100); - if(r) { - struct cr_exp100_ctx *ctx = r->ctx; - return ctx->state == EXP100_AWAITING_CONTINUE; - } - return FALSE; -} - -static void http_exp100_send_anyway(struct Curl_easy *data) -{ - struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100); - if(r) - http_exp100_continue(data, r); -} - -static bool http_exp100_is_selected(struct Curl_easy *data) -{ - struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100); - return !!r; -} - -/* this returns the socket to wait for in the DO and DOING state for the multi - interface and then we are always _sending_ a request and thus we wait for - the single socket to become writable only */ -CURLcode Curl_http_doing_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - /* write mode */ - return Curl_pollset_add_out(data, ps, data->conn->sock[FIRSTSOCKET]); -} - -CURLcode Curl_http_perform_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - - if(CURL_REQ_WANT_RECV(data)) { - result = Curl_pollset_add_in(data, ps, conn->sock[FIRSTSOCKET]); - } - - /* on a "Expect: 100-continue" timed wait, do not poll for outgoing */ - if(!result && Curl_req_want_send(data) && !http_exp100_is_waiting(data)) { - result = Curl_pollset_add_out(data, ps, conn->sock[FIRSTSOCKET]); - } - return result; -} - -static CURLcode http_write_header(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - CURLcode result; - int writetype; - - /* now, only output this if the header AND body are requested: - */ - Curl_debug(data, CURLINFO_HEADER_IN, hd, hdlen); - - writetype = CLIENTWRITE_HEADER | - ((data->req.httpcode / 100 == 1) ? CLIENTWRITE_1XX : 0); - - result = Curl_client_write(data, writetype, hd, hdlen); - if(result) - return result; - - result = Curl_bump_headersize(data, hdlen, FALSE); - if(result) - return result; - - data->req.deductheadercount = (100 <= data->req.httpcode && - 199 >= data->req.httpcode) ? - data->req.headerbytecount : 0; - return result; -} - -/* - * Curl_http_done() gets called after a single HTTP request has been - * performed. - */ - -CURLcode Curl_http_done(struct Curl_easy *data, - CURLcode status, bool premature) -{ - struct connectdata *conn = data->conn; - - /* Clear multipass flag. If authentication is not done yet, then it will get - * a chance to be set back to true when we output the next auth header */ - data->state.authhost.multipass = FALSE; - data->state.authproxy.multipass = FALSE; - - if(curlx_dyn_len(&data->state.headerb)) { - (void)http_write_header(data, curlx_dyn_ptr(&data->state.headerb), - curlx_dyn_len(&data->state.headerb)); - } - curlx_dyn_reset(&data->state.headerb); - - if(status) - return status; - - if(!premature && /* this check is pointless when DONE is called before the - entire operation is complete */ - !conn->bits.retry && - !data->set.connect_only && - (data->req.bytecount + - data->req.headerbytecount - - data->req.deductheadercount) <= 0) { - /* If this connection is not closed to be retried, AND nothing was - read from the HTTP server (that counts), this cannot be right so we - return an error here */ - failf(data, "Empty reply from server"); - /* Mark it as closed to avoid the "left intact" message */ - streamclose(conn, "Empty reply from server"); - return CURLE_GOT_NOTHING; - } - - return CURLE_OK; -} - -/* Determine if we may use HTTP 1.1 for this request. */ -static bool http_may_use_1_1(const struct Curl_easy *data) -{ - const struct connectdata *conn = data->conn; - /* We have seen a previous response for *this* transfer with 1.0, - * on another connection or the same one. */ - if(data->state.http_neg.rcvd_min == 10) - return FALSE; - /* We have seen a previous response on *this* connection with 1.0. */ - if(conn && conn->httpversion_seen == 10) - return FALSE; - /* We want 1.0 and have seen no previous response on *this* connection - with a higher version (maybe no response at all yet). */ - if((data->state.http_neg.only_10) && - (!conn || conn->httpversion_seen <= 10)) - return FALSE; - /* We are not restricted to use 1.0 only. */ - return !data->state.http_neg.only_10; -} - -static unsigned char http_request_version(struct Curl_easy *data) -{ - unsigned char v = Curl_conn_http_version(data, data->conn); - if(!v) { - /* No specific HTTP connection filter installed. */ - v = http_may_use_1_1(data) ? 11 : 10; - } - return v; -} - -static const char *get_http_string(int httpversion) -{ - switch(httpversion) { - case 30: - return "3"; - case 20: - return "2"; - case 11: - return "1.1"; - default: - return "1.0"; - } -} - -CURLcode Curl_add_custom_headers(struct Curl_easy *data, - bool is_connect, int httpversion, - struct dynbuf *req) -{ - struct curl_slist *h[2]; - struct curl_slist *headers; - int numlists = 1; /* by default */ - int i; - -#ifndef CURL_DISABLE_PROXY - enum Curl_proxy_use proxy; - - if(is_connect) - proxy = HEADER_CONNECT; - else - proxy = data->conn->bits.httpproxy && !data->conn->bits.tunnel_proxy ? - HEADER_PROXY : HEADER_SERVER; - - switch(proxy) { - case HEADER_SERVER: - h[0] = data->set.headers; - break; - case HEADER_PROXY: - h[0] = data->set.headers; - if(data->set.sep_headers) { - h[1] = data->set.proxyheaders; - numlists++; - } - break; - case HEADER_CONNECT: - if(data->set.sep_headers) - h[0] = data->set.proxyheaders; - else - h[0] = data->set.headers; - break; - } -#else - (void)is_connect; - h[0] = data->set.headers; -#endif - - /* loop through one or two lists */ - for(i = 0; i < numlists; i++) { - for(headers = h[i]; headers; headers = headers->next) { - CURLcode result = CURLE_OK; - bool blankheader = FALSE; - struct Curl_str name; - const char *p = headers->data; - const char *origp = p; - - /* explicitly asked to send header without content is done by a header - that ends with a semicolon, but there must be no colon present in the - name */ - if(!curlx_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ';') && - !curlx_str_single(&p, ';') && - !curlx_str_single(&p, '\0') && - !memchr(curlx_str(&name), ':', curlx_strlen(&name))) - blankheader = TRUE; - else { - p = origp; - if(!curlx_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ':') && - !curlx_str_single(&p, ':')) { - struct Curl_str val; - curlx_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE); - curlx_str_trimblanks(&val); - if(!curlx_strlen(&val)) - /* no content, do not send this */ - continue; - } - else - /* no colon */ - continue; - } - - /* only send this if the contents was non-blank or done special */ - - if(data->state.aptr.host && - /* a Host: header was sent already, do not pass on any custom - Host: header as that will produce *two* in the same - request! */ - curlx_str_casecompare(&name, "Host")) - ; - else if(data->state.httpreq == HTTPREQ_POST_FORM && - /* this header (extended by formdata.c) is sent later */ - curlx_str_casecompare(&name, "Content-Type")) - ; - else if(data->state.httpreq == HTTPREQ_POST_MIME && - /* this header is sent later */ - curlx_str_casecompare(&name, "Content-Type")) - ; - else if(data->req.authneg && - /* while doing auth neg, do not allow the custom length since - we will force length zero then */ - curlx_str_casecompare(&name, "Content-Length")) - ; - else if(curlx_str_casecompare(&name, "Connection")) - /* Connection headers are handled specially */ - ; - else if((httpversion >= 20) && - curlx_str_casecompare(&name, "Transfer-Encoding")) - /* HTTP/2 does not support chunked requests */ - ; - else if((curlx_str_casecompare(&name, "Authorization") || - curlx_str_casecompare(&name, "Cookie")) && - /* be careful of sending this potentially sensitive header to - other hosts */ - !Curl_auth_allowed_to_host(data)) - ; - else if(blankheader) - result = curlx_dyn_addf(req, "%.*s:\r\n", (int)curlx_strlen(&name), - curlx_str(&name)); - else - result = curlx_dyn_addf(req, "%s\r\n", origp); - - if(result) - return result; - } - } - - return CURLE_OK; -} - -#ifndef CURL_DISABLE_PARSEDATE -CURLcode Curl_add_timecondition(struct Curl_easy *data, - struct dynbuf *req) -{ - const struct tm *tm; - struct tm keeptime; - CURLcode result; - char datestr[80]; - const char *condp; - size_t len; - - if(data->set.timecondition == CURL_TIMECOND_NONE) - /* no condition was asked for */ - return CURLE_OK; - - result = curlx_gmtime(data->set.timevalue, &keeptime); - if(result) { - failf(data, "Invalid TIMEVALUE"); - return result; - } - tm = &keeptime; - - switch(data->set.timecondition) { - default: - DEBUGF(infof(data, "invalid time condition")); - return CURLE_BAD_FUNCTION_ARGUMENT; - - case CURL_TIMECOND_IFMODSINCE: - condp = "If-Modified-Since"; - len = 17; - break; - case CURL_TIMECOND_IFUNMODSINCE: - condp = "If-Unmodified-Since"; - len = 19; - break; - case CURL_TIMECOND_LASTMOD: - condp = "Last-Modified"; - len = 13; - break; - } - - if(Curl_checkheaders(data, condp, len)) { - /* A custom header was specified; it will be sent instead. */ - return CURLE_OK; - } - - /* The If-Modified-Since header family should have their times set in - * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be - * represented in Greenwich Mean Time (GMT), without exception. For the - * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal - * Time)." (see page 20 of RFC2616). - */ - - /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - curl_msnprintf(datestr, sizeof(datestr), - "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", - condp, - Curl_wkday[tm->tm_wday ? tm->tm_wday - 1 : 6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - - result = curlx_dyn_add(req, datestr); - return result; -} -#else -/* disabled */ -CURLcode Curl_add_timecondition(struct Curl_easy *data, - struct dynbuf *req) -{ - (void)data; - (void)req; - return CURLE_OK; -} -#endif - -void Curl_http_method(struct Curl_easy *data, - const char **method, Curl_HttpReq *reqp) -{ - Curl_HttpReq httpreq = (Curl_HttpReq)data->state.httpreq; - const char *request; -#ifndef CURL_DISABLE_WEBSOCKETS - if(data->conn->scheme->protocol & (CURLPROTO_WS | CURLPROTO_WSS)) - httpreq = HTTPREQ_GET; - else -#endif - if((data->conn->scheme->protocol & (PROTO_FAMILY_HTTP | CURLPROTO_FTP)) && - data->state.upload) - httpreq = HTTPREQ_PUT; - - /* Now set the 'request' pointer to the proper request string */ - if(data->set.str[STRING_CUSTOMREQUEST] && - !data->state.http_ignorecustom) { - request = data->set.str[STRING_CUSTOMREQUEST]; - } - else { - if(data->req.no_body) - request = "HEAD"; - else { - DEBUGASSERT((httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD)); - switch(httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - request = "POST"; - break; - case HTTPREQ_PUT: - request = "PUT"; - break; - default: /* this should never happen */ - case HTTPREQ_GET: - request = "GET"; - break; - case HTTPREQ_HEAD: - request = "HEAD"; - break; - } - } - } - *method = request; - *reqp = httpreq; -} - -static CURLcode http_useragent(struct Curl_easy *data) -{ - /* The User-Agent string might have been allocated already, because - it might have been used in the proxy connect, but if we have got a header - with the user-agent string specified, we erase the previously made string - here. */ - if(Curl_checkheaders(data, STRCONST("User-Agent"))) { - curlx_free(data->state.aptr.uagent); - data->state.aptr.uagent = NULL; - } - return CURLE_OK; -} - -static CURLcode http_set_aptr_host(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - struct dynamically_allocated_data *aptr = &data->state.aptr; - const char *ptr; - - if(!data->state.this_is_a_follow) { - /* Free to avoid leaking memory on multiple requests */ - curlx_free(data->state.first_host); - - data->state.first_host = curlx_strdup(conn->host.name); - if(!data->state.first_host) - return CURLE_OUT_OF_MEMORY; - - data->state.first_remote_port = conn->remote_port; - data->state.first_remote_protocol = conn->scheme->protocol; - } - curlx_safefree(aptr->host); -#ifndef CURL_DISABLE_COOKIES - curlx_safefree(data->req.cookiehost); -#endif - - ptr = Curl_checkheaders(data, STRCONST("Host")); - if(ptr && (!data->state.this_is_a_follow || - curl_strequal(data->state.first_host, conn->host.name))) { -#ifndef CURL_DISABLE_COOKIES - /* If we have a given custom Host: header, we extract the hostname in - order to possibly use it for cookie reasons later on. We only allow the - custom Host: header if this is NOT a redirect, as setting Host: in the - redirected request is being out on thin ice. Except if the hostname - is the same as the first one! */ - char *cookiehost; - CURLcode result = copy_custom_value(ptr, &cookiehost); - if(result) - return result; - if(!*cookiehost) - /* ignore empty data */ - curlx_free(cookiehost); - else { - /* If the host begins with '[', we start searching for the port after - the bracket has been closed */ - if(*cookiehost == '[') { - char *closingbracket; - /* since the 'cookiehost' is an allocated memory area that will be - freed later we cannot increment the pointer */ - memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1); - closingbracket = strchr(cookiehost, ']'); - if(closingbracket) - *closingbracket = 0; - } - else { - int startsearch = 0; - char *colon = strchr(cookiehost + startsearch, ':'); - if(colon) - *colon = 0; /* The host must not include an embedded port number */ - } - data->req.cookiehost = cookiehost; - } -#endif - - if(!curl_strequal("Host:", ptr)) { - aptr->host = curl_maprintf("Host:%s\r\n", &ptr[5]); - if(!aptr->host) - return CURLE_OUT_OF_MEMORY; - } - } - else { - /* Use the hostname as present in the URL if it was IPv6. */ - char *host = (data->state.up.hostname[0] == '[') ? - data->state.up.hostname : conn->host.name; - - if(((conn->given->protocol & (CURLPROTO_HTTPS | CURLPROTO_WSS)) && - (conn->remote_port == PORT_HTTPS)) || - ((conn->given->protocol & (CURLPROTO_HTTP | CURLPROTO_WS)) && - (conn->remote_port == PORT_HTTP))) - /* if(HTTPS on port 443) OR (HTTP on port 80) then do not include - the port number in the host string */ - aptr->host = curl_maprintf("Host: %s\r\n", host); - else - aptr->host = curl_maprintf("Host: %s:%d\r\n", host, conn->remote_port); - - if(!aptr->host) - /* without Host: we cannot make a nice request */ - return CURLE_OUT_OF_MEMORY; - } - return CURLE_OK; -} - -/* - * Append the request-target to the HTTP request - */ -static CURLcode http_target(struct Curl_easy *data, - struct dynbuf *r) -{ - CURLcode result = CURLE_OK; - const char *path = data->state.up.path; - const char *query = data->state.up.query; -#ifndef CURL_DISABLE_PROXY - struct connectdata *conn = data->conn; -#endif - - if(data->set.str[STRING_TARGET]) { - path = data->set.str[STRING_TARGET]; - query = NULL; - } - -#ifndef CURL_DISABLE_PROXY - if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { - /* Using a proxy but does not tunnel through it */ - - /* The path sent to the proxy is in fact the entire URL, but if the remote - host is a IDN-name, we must make sure that the request we produce only - uses the encoded hostname! */ - - /* and no fragment part */ - CURLUcode uc; - char *url; - CURLU *h = curl_url_dup(data->state.uh); - if(!h) - return CURLE_OUT_OF_MEMORY; - - if(conn->host.dispname != conn->host.name) { - uc = curl_url_set(h, CURLUPART_HOST, conn->host.name, 0); - if(uc) { - curl_url_cleanup(h); - return CURLE_OUT_OF_MEMORY; - } - } - uc = curl_url_set(h, CURLUPART_FRAGMENT, NULL, 0); - if(uc) { - curl_url_cleanup(h); - return CURLE_OUT_OF_MEMORY; - } - - if(curl_strequal("http", data->state.up.scheme)) { - /* when getting HTTP, we do not want the userinfo the URL */ - uc = curl_url_set(h, CURLUPART_USER, NULL, 0); - if(uc) { - curl_url_cleanup(h); - return CURLE_OUT_OF_MEMORY; - } - uc = curl_url_set(h, CURLUPART_PASSWORD, NULL, 0); - if(uc) { - curl_url_cleanup(h); - return CURLE_OUT_OF_MEMORY; - } - } - /* Extract the URL to use in the request. */ - uc = curl_url_get(h, CURLUPART_URL, &url, CURLU_NO_DEFAULT_PORT); - if(uc) { - curl_url_cleanup(h); - return CURLE_OUT_OF_MEMORY; - } - - curl_url_cleanup(h); - - /* target or URL */ - result = curlx_dyn_add(r, data->set.str[STRING_TARGET] ? - data->set.str[STRING_TARGET] : url); - curlx_free(url); - if(result) - return result; - - if(curl_strequal("ftp", data->state.up.scheme) && - data->set.proxy_transfer_mode) { - /* when doing ftp, append ;type= if not present */ - size_t len = strlen(path); - bool type_present = FALSE; - if((len >= 7) && !memcmp(&path[len - 7], ";type=", 6)) { - switch(Curl_raw_toupper(path[len - 1])) { - case 'A': - case 'D': - case 'I': - type_present = TRUE; - break; - } - } - if(!type_present) { - result = curlx_dyn_addf(r, ";type=%c", - data->state.prefer_ascii ? 'a' : 'i'); - if(result) - return result; - } - } - } - - else -#endif - { - result = curlx_dyn_add(r, path); - if(result) - return result; - if(query) - result = curlx_dyn_addf(r, "?%s", query); - } - - return result; -} - -#if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) -static CURLcode set_post_reader(struct Curl_easy *data, Curl_HttpReq httpreq) -{ - CURLcode result; - - switch(httpreq) { -#ifndef CURL_DISABLE_MIME - case HTTPREQ_POST_MIME: - data->state.mimepost = data->set.mimepostp; - break; -#endif -#ifndef CURL_DISABLE_FORM_API - case HTTPREQ_POST_FORM: - /* Convert the form structure into a mime structure, then keep - the conversion */ - if(!data->state.formp) { - data->state.formp = curlx_calloc(1, sizeof(curl_mimepart)); - if(!data->state.formp) - return CURLE_OUT_OF_MEMORY; - Curl_mime_cleanpart(data->state.formp); - result = Curl_getformdata(data, data->state.formp, data->set.httppost, - data->state.fread_func); - if(result) { - curlx_safefree(data->state.formp); - return result; - } - data->state.mimepost = data->state.formp; - } - break; -#endif - default: - data->state.mimepost = NULL; - break; - } - - switch(httpreq) { - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - /* This is form posting using mime data. */ -#ifndef CURL_DISABLE_MIME - if(data->state.mimepost) { - const char *cthdr = Curl_checkheaders(data, STRCONST("Content-Type")); - - /* Read and seek body only. */ - data->state.mimepost->flags |= MIME_BODY_ONLY; - - /* Prepare the mime structure headers & set content type. */ - - if(cthdr) - for(cthdr += 13; *cthdr == ' '; cthdr++) - ; - else if(data->state.mimepost->kind == MIMEKIND_MULTIPART) - cthdr = "multipart/form-data"; - - curl_mime_headers(data->state.mimepost, data->set.headers, 0); - result = Curl_mime_prepare_headers(data, data->state.mimepost, cthdr, - NULL, MIMESTRATEGY_FORM); - if(result) - return result; - curl_mime_headers(data->state.mimepost, NULL, 0); - result = Curl_creader_set_mime(data, data->state.mimepost); - if(result) - return result; - } - else -#endif - { - result = Curl_creader_set_null(data); - } - data->state.infilesize = Curl_creader_total_length(data); - return result; - - default: - return Curl_creader_set_null(data); - } - /* never reached */ -} -#endif - -static CURLcode set_reader(struct Curl_easy *data, Curl_HttpReq httpreq) -{ - CURLcode result = CURLE_OK; - curl_off_t postsize = data->state.infilesize; - - DEBUGASSERT(data->conn); - - if(data->req.authneg) { - return Curl_creader_set_null(data); - } - - switch(httpreq) { - case HTTPREQ_PUT: /* Let's PUT the data to the server! */ - return postsize ? Curl_creader_set_fread(data, postsize) : - Curl_creader_set_null(data); - -#if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - return set_post_reader(data, httpreq); -#endif - - case HTTPREQ_POST: - /* this is the simple POST, using x-www-form-urlencoded style */ - /* the size of the post body */ - if(!postsize) { - result = Curl_creader_set_null(data); - } - else if(data->set.postfields) { - size_t plen = curlx_sotouz_range(postsize, 0, SIZE_MAX); - if(plen == SIZE_MAX) - return CURLE_OUT_OF_MEMORY; - else if(plen) - result = Curl_creader_set_buf(data, data->set.postfields, plen); - else - result = Curl_creader_set_null(data); - } - else { - /* we read the bytes from the callback. In case "chunked" encoding - * is forced by the application, we disregard `postsize`. This is - * a backward compatibility decision to earlier versions where - * chunking disregarded this. See issue #13229. */ - bool chunked = FALSE; - char *ptr = Curl_checkheaders(data, STRCONST("Transfer-Encoding")); - if(ptr) { - /* Some kind of TE is requested, check if 'chunked' is chosen */ - chunked = Curl_compareheader(ptr, STRCONST("Transfer-Encoding:"), - STRCONST("chunked")); - } - result = Curl_creader_set_fread(data, chunked ? -1 : postsize); - } - return result; - - default: - /* HTTP GET/HEAD download, has no body, needs no Content-Length */ - data->state.infilesize = 0; - return Curl_creader_set_null(data); - } - /* not reached */ -} - -static CURLcode http_resume(struct Curl_easy *data, Curl_HttpReq httpreq) -{ - if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) && - data->state.resume_from) { - /********************************************************************** - * Resuming upload in HTTP means that we PUT or POST and that we have - * got a resume_from value set. The resume value has already created - * a Range: header that will be passed along. We need to "fast forward" - * the file the given number of bytes and decrease the assume upload - * file size before we continue this venture in the dark lands of HTTP. - * Resuming mime/form posting at an offset > 0 has no sense and is ignored. - *********************************************************************/ - - if(data->state.resume_from < 0) { - /* - * This is meant to get the size of the present remote-file by itself. - * We do not support this now. Bail out! - */ - data->state.resume_from = 0; - } - - if(data->state.resume_from && !data->req.authneg) { - /* only act on the first request */ - CURLcode result; - result = Curl_creader_resume_from(data, data->state.resume_from); - if(result) { - failf(data, "Unable to resume from offset %" FMT_OFF_T, - data->state.resume_from); - return result; - } - } - } - return CURLE_OK; -} - -static CURLcode http_req_set_TE(struct Curl_easy *data, - struct dynbuf *req, - int httpversion) -{ - CURLcode result = CURLE_OK; - const char *ptr; - - ptr = Curl_checkheaders(data, STRCONST("Transfer-Encoding")); - if(ptr) { - /* Some kind of TE is requested, check if 'chunked' is chosen */ - data->req.upload_chunky = - Curl_compareheader(ptr, - STRCONST("Transfer-Encoding:"), STRCONST("chunked")); - if(data->req.upload_chunky && (httpversion >= 20)) { - infof(data, "suppressing chunked transfer encoding on connection " - "using HTTP version 2 or higher"); - data->req.upload_chunky = FALSE; - } - } - else { - curl_off_t req_clen = Curl_creader_total_length(data); - - if(req_clen < 0) { - /* indeterminate request content length */ - if(httpversion > 10) { - /* On HTTP/1.1, enable chunked, on HTTP/2 and later we do not - * need it */ - data->req.upload_chunky = (httpversion < 20); - } - else { - failf(data, "Chunky upload is not supported by HTTP 1.0"); - return CURLE_UPLOAD_FAILED; - } - } - else { - /* else, no chunky upload */ - data->req.upload_chunky = FALSE; - } - - if(data->req.upload_chunky) - result = curlx_dyn_add(req, "Transfer-Encoding: chunked\r\n"); - } - return result; -} - -static CURLcode addexpect(struct Curl_easy *data, struct dynbuf *r, - int httpversion, bool *announced_exp100) -{ - CURLcode result; - char *ptr; - - *announced_exp100 = FALSE; - /* Avoid Expect: 100-continue if Upgrade: is used */ - if(data->req.upgr101 != UPGR101_NONE) - return CURLE_OK; - - /* For really small puts we do not use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Make - sure that the expect100header is always set to the preferred value - here. */ - ptr = Curl_checkheaders(data, STRCONST("Expect")); - if(ptr) { - *announced_exp100 = - Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); - } - else if(!data->state.disableexpect && (httpversion == 11)) { - /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an - Expect: 100-continue to the headers which actually speeds up post - operations (as there is one packet coming back from the web server) */ - curl_off_t client_len = Curl_creader_client_length(data); - if(client_len > EXPECT_100_THRESHOLD || client_len < 0) { - result = curlx_dyn_addn(r, STRCONST("Expect: 100-continue\r\n")); - if(result) - return result; - *announced_exp100 = TRUE; - } - } - return CURLE_OK; -} - -static CURLcode http_add_content_hds(struct Curl_easy *data, - struct dynbuf *r, - int httpversion, - Curl_HttpReq httpreq) -{ - CURLcode result = CURLE_OK; - curl_off_t req_clen; - bool announced_exp100 = FALSE; - - DEBUGASSERT(data->conn); - if(data->req.upload_chunky) { - result = Curl_httpchunk_add_reader(data); - if(result) - return result; - } - - /* Get the request body length that has been set up */ - req_clen = Curl_creader_total_length(data); - switch(httpreq) { - case HTTPREQ_PUT: - case HTTPREQ_POST: -#if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: -#endif - /* We only set Content-Length and allow a custom Content-Length if - we do not upload data chunked, as RFC2616 forbids us to set both - kinds of headers (Transfer-Encoding: chunked and Content-Length). - We do not override a custom "Content-Length" header, but during - authentication negotiation that header is suppressed. - */ - if(req_clen >= 0 && !data->req.upload_chunky && - (data->req.authneg || - !Curl_checkheaders(data, STRCONST("Content-Length")))) { - /* we allow replacing this header if not during auth negotiation, - although it is not wise to actually set your own */ - result = curlx_dyn_addf(r, "Content-Length: %" FMT_OFF_T "\r\n", - req_clen); - } - if(result) - goto out; - -#ifndef CURL_DISABLE_MIME - /* Output mime-generated headers. */ - if(data->state.mimepost && - ((httpreq == HTTPREQ_POST_FORM) || (httpreq == HTTPREQ_POST_MIME))) { - struct curl_slist *hdr; - - for(hdr = data->state.mimepost->curlheaders; hdr; hdr = hdr->next) { - result = curlx_dyn_addf(r, "%s\r\n", hdr->data); - if(result) - goto out; - } - } -#endif - if(httpreq == HTTPREQ_POST) { - if(!Curl_checkheaders(data, STRCONST("Content-Type"))) { - result = curlx_dyn_addn(r, STRCONST("Content-Type: application/" - "x-www-form-urlencoded\r\n")); - if(result) - goto out; - } - } - result = addexpect(data, r, httpversion, &announced_exp100); - if(result) - goto out; - break; - default: - break; - } - - Curl_pgrsSetUploadSize(data, req_clen); - if(announced_exp100) - result = http_exp100_add_reader(data); - -out: - return result; -} - -#ifndef CURL_DISABLE_COOKIES - -static CURLcode http_cookies(struct Curl_easy *data, - struct dynbuf *r) -{ - CURLcode result = CURLE_OK; - char *addcookies = NULL; - bool linecap = FALSE; - if(data->set.str[STRING_COOKIE] && - !Curl_checkheaders(data, STRCONST("Cookie"))) - addcookies = data->set.str[STRING_COOKIE]; - - if(data->cookies || addcookies) { - struct Curl_llist list; - int count = 0; - - if(data->cookies && data->state.cookie_engine) { - bool okay; - const char *host = data->req.cookiehost ? - data->req.cookiehost : data->conn->host.name; - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - result = Curl_cookie_getlist(data, data->conn, &okay, host, &list); - if(!result && okay) { - struct Curl_llist_node *n; - size_t clen = 8; /* hold the size of the generated Cookie: header */ - - /* loop through all cookies that matched */ - for(n = Curl_llist_head(&list); n; n = Curl_node_next(n)) { - struct Cookie *co = Curl_node_elem(n); - if(co->value) { - size_t add; - if(!count) { - result = curlx_dyn_addn(r, STRCONST("Cookie: ")); - if(result) - break; - } - add = strlen(co->name) + strlen(co->value) + 1; - if(clen + add >= MAX_COOKIE_HEADER_LEN) { - infof(data, "Restricted outgoing cookies due to header size, " - "'%s' not sent", co->name); - linecap = TRUE; - break; - } - result = curlx_dyn_addf(r, "%s%s=%s", count ? "; " : "", - co->name, co->value); - if(result) - break; - clen += add + (count ? 2 : 0); - count++; - } - } - Curl_llist_destroy(&list, NULL); - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - if(addcookies && !result && !linecap) { - if(!count) - result = curlx_dyn_addn(r, STRCONST("Cookie: ")); - if(!result) { - result = curlx_dyn_addf(r, "%s%s", count ? "; " : "", addcookies); - count++; - } - } - if(count && !result) - result = curlx_dyn_addn(r, STRCONST("\r\n")); - - if(result) - return result; - } - return result; -} -#else -#define http_cookies(a, b) CURLE_OK -#endif - -static CURLcode http_range(struct Curl_easy *data, - Curl_HttpReq httpreq) -{ - if(data->state.use_range) { - /* - * A range is selected. We use different headers whether we are downloading - * or uploading and we always let customized headers override our internal - * ones if any such are specified. - */ - if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) && - !Curl_checkheaders(data, STRCONST("Range"))) { - /* if a line like this was already allocated, free the previous one */ - curlx_free(data->state.aptr.rangeline); - data->state.aptr.rangeline = curl_maprintf("Range: bytes=%s\r\n", - data->state.range); - if(!data->state.aptr.rangeline) - return CURLE_OUT_OF_MEMORY; - } - else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) && - !Curl_checkheaders(data, STRCONST("Content-Range"))) { - curl_off_t req_clen = Curl_creader_total_length(data); - /* if a line like this was already allocated, free the previous one */ - curlx_free(data->state.aptr.rangeline); - - if(data->set.set_resume_from < 0) { - /* Upload resume was asked for, but we do not know the size of the - remote part so we tell the server (and act accordingly) that we - upload the whole file (again) */ - data->state.aptr.rangeline = - curl_maprintf("Content-Range: bytes 0-%" FMT_OFF_T "/" - "%" FMT_OFF_T "\r\n", req_clen - 1, req_clen); - } - else if(data->state.resume_from) { - /* This is because "resume" was selected */ - /* Not sure if we want to send this header during authentication - * negotiation, but test1084 checks for it. In which case we have a - * "null" client reader installed that gives an unexpected length. */ - curl_off_t total_len = data->req.authneg ? - data->state.infilesize : - (data->state.resume_from + req_clen); - data->state.aptr.rangeline = - curl_maprintf("Content-Range: bytes %s%" FMT_OFF_T "/" - "%" FMT_OFF_T "\r\n", - data->state.range, total_len - 1, total_len); - } - else { - /* Range was selected and then we pass the incoming range and append - total size */ - data->state.aptr.rangeline = - curl_maprintf("Content-Range: bytes %s/%" FMT_OFF_T "\r\n", - data->state.range, req_clen); - } - if(!data->state.aptr.rangeline) - return CURLE_OUT_OF_MEMORY; - } - } - return CURLE_OK; -} - -static CURLcode http_firstwrite(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - struct SingleRequest *k = &data->req; - - if(data->req.newurl) { - if(conn->bits.close) { - /* Abort after the headers if "follow Location" is set - and we are set to close anyway. */ - CURL_REQ_CLEAR_RECV(data); - k->done = TRUE; - return CURLE_OK; - } - /* We have a new URL to load, but since we want to be able to reuse this - connection properly, we read the full response in "ignore more" */ - k->ignorebody = TRUE; - infof(data, "Ignoring the response-body"); - } - if(data->state.resume_from && !k->content_range && - (data->state.httpreq == HTTPREQ_GET) && - !k->ignorebody) { - - if(k->size == data->state.resume_from) { - /* The resume point is at the end of file, consider this fine even if it - does not allow resume from here. */ - infof(data, "The entire document is already downloaded"); - streamclose(conn, "already downloaded"); - /* Abort download */ - CURL_REQ_CLEAR_RECV(data); - k->done = TRUE; - return CURLE_OK; - } - - /* we wanted to resume a download, although the server does not seem to - * support this and we did this with a GET (if it was not a GET we did a - * POST or PUT resume) */ - failf(data, "HTTP server does not seem to support " - "byte ranges. Cannot resume."); - return CURLE_RANGE_ERROR; - } - - if(data->set.timecondition && !data->state.range) { - /* A time condition has been set AND no ranges have been requested. This - seems to be what chapter 13.3.4 of RFC 2616 defines to be the correct - action for an HTTP/1.1 client */ - - if(!Curl_meets_timecondition(data, k->timeofdoc)) { - k->done = TRUE; - /* We are simulating an HTTP 304 from server so we return - what should have been returned from the server */ - data->info.httpcode = 304; - infof(data, "Simulate an HTTP 304 response"); - /* we abort the transfer before it is completed == we ruin the - reuse ability. Close the connection */ - streamclose(conn, "Simulated 304 handling"); - return CURLE_OK; - } - } /* we have a time condition */ - - return CURLE_OK; -} - -static CURLcode http_check_new_conn(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - const char *info_version = NULL; - const char *alpn; - CURLcode result; - - alpn = Curl_conn_get_alpn_negotiated(data, conn); - if(alpn && !strcmp("h3", alpn)) { - DEBUGASSERT(Curl_conn_http_version(data, conn) == 30); - info_version = "HTTP/3"; - } - else if(alpn && !strcmp("h2", alpn)) { -#ifndef CURL_DISABLE_PROXY - if((Curl_conn_http_version(data, conn) != 20) && - conn->bits.proxy && !conn->bits.tunnel_proxy) { - result = Curl_http2_switch(data); - if(result) - return result; - } - else -#endif - DEBUGASSERT(Curl_conn_http_version(data, conn) == 20); - info_version = "HTTP/2"; - } - else { - /* Check if user wants to use HTTP/2 with clear TCP */ - if(Curl_http2_may_switch(data)) { - DEBUGF(infof(data, "HTTP/2 over clean TCP")); - result = Curl_http2_switch(data); - if(result) - return result; - info_version = "HTTP/2"; - /* There is no ALPN here, but the connection is now definitely h2 */ - conn->httpversion_seen = 20; - Curl_conn_set_multiplex(conn); - } - else - info_version = "HTTP/1.x"; - } - - if(info_version) - infof(data, "using %s", info_version); - return CURLE_OK; -} - -static CURLcode http_add_connection_hd(struct Curl_easy *data, - struct dynbuf *req) -{ - struct curl_slist *head; - const char *sep = "Connection: "; - CURLcode result = CURLE_OK; - size_t rlen = curlx_dyn_len(req); - bool skip; - - /* Add the 1st custom "Connection: " header, if there is one */ - for(head = data->set.headers; head; head = head->next) { - if(curl_strnequal(head->data, "Connection", 10) && - Curl_headersep(head->data[10]) && - !http_header_is_empty(head->data)) { - char *value; - result = copy_custom_value(head->data, &value); - if(result) - return result; - result = curlx_dyn_addf(req, "%s%s", sep, value); - sep = ", "; - curlx_free(value); - break; /* leave, having added 1st one */ - } - } - - /* add our internal Connection: header values, if we have any */ - if(!result && data->state.http_hd_te) { - result = curlx_dyn_addf(req, "%s%s", sep, "TE"); - sep = ", "; - } - if(!result && data->state.http_hd_upgrade) { - result = curlx_dyn_addf(req, "%s%s", sep, "Upgrade"); - sep = ", "; - } - if(!result && data->state.http_hd_h2_settings) { - result = curlx_dyn_addf(req, "%s%s", sep, "HTTP2-Settings"); - } - if(!result && (rlen < curlx_dyn_len(req))) - result = curlx_dyn_addn(req, STRCONST("\r\n")); - if(result) - return result; - - /* Add all user-defined Connection: headers after the first */ - skip = TRUE; - for(head = data->set.headers; head; head = head->next) { - if(curl_strnequal(head->data, "Connection", 10) && - Curl_headersep(head->data[10]) && - !http_header_is_empty(head->data)) { - if(skip) { - skip = FALSE; - continue; - } - result = curlx_dyn_addf(req, "%s\r\n", head->data); - if(result) - return result; - } - } - - return CURLE_OK; -} - -/* Header identifier in order we send them by default */ -typedef enum { - H1_HD_REQUEST, - H1_HD_HOST, -#ifndef CURL_DISABLE_PROXY - H1_HD_PROXY_AUTH, -#endif - H1_HD_USER_AUTH, - H1_HD_RANGE, - H1_HD_USER_AGENT, - H1_HD_ACCEPT, - H1_HD_TE, - H1_HD_ACCEPT_ENCODING, - H1_HD_REFERER, -#ifndef CURL_DISABLE_PROXY - H1_HD_PROXY_CONNECTION, -#endif - H1_HD_TRANSFER_ENCODING, -#ifndef CURL_DISABLE_ALTSVC - H1_HD_ALT_USED, -#endif - H1_HD_UPGRADE, - H1_HD_COOKIES, - H1_HD_CONDITIONALS, - H1_HD_CUSTOM, - H1_HD_CONTENT, - H1_HD_CONNECTION, - H1_HD_LAST /* the last, empty header line */ -} http_hd_t; - -static CURLcode http_add_hd(struct Curl_easy *data, - struct dynbuf *req, - http_hd_t id, - unsigned char httpversion, - const char *method, - Curl_HttpReq httpreq) -{ - CURLcode result = CURLE_OK; -#if !defined(CURL_DISABLE_ALTSVC) || \ - !defined(CURL_DISABLE_PROXY) || \ - !defined(CURL_DISABLE_WEBSOCKETS) - struct connectdata *conn = data->conn; -#endif - switch(id) { - case H1_HD_REQUEST: - /* add the main request stuff */ - /* GET/HEAD/POST/PUT */ - result = curlx_dyn_addf(req, "%s ", method); - if(!result) - result = http_target(data, req); - if(!result) - result = curlx_dyn_addf(req, " HTTP/%s\r\n", - get_http_string(httpversion)); - break; - - case H1_HD_HOST: - if(data->state.aptr.host) - result = curlx_dyn_add(req, data->state.aptr.host); - break; - -#ifndef CURL_DISABLE_PROXY - case H1_HD_PROXY_AUTH: - if(data->req.proxyuserpwd) - result = curlx_dyn_add(req, data->req.proxyuserpwd); - break; -#endif - - case H1_HD_USER_AUTH: - if(data->req.userpwd) - result = curlx_dyn_add(req, data->req.userpwd); - break; - - case H1_HD_RANGE: - if(data->state.use_range && data->state.aptr.rangeline) - result = curlx_dyn_add(req, data->state.aptr.rangeline); - break; - - case H1_HD_USER_AGENT: - if(data->set.str[STRING_USERAGENT] && /* User-Agent: */ - *data->set.str[STRING_USERAGENT] && - data->state.aptr.uagent) - result = curlx_dyn_add(req, data->state.aptr.uagent); - break; - - case H1_HD_ACCEPT: - if(!Curl_checkheaders(data, STRCONST("Accept"))) - result = curlx_dyn_add(req, "Accept: */*\r\n"); - break; - - case H1_HD_TE: -#ifdef HAVE_LIBZ - if(!Curl_checkheaders(data, STRCONST("TE")) && - data->set.http_transfer_encoding) { - data->state.http_hd_te = TRUE; - result = curlx_dyn_add(req, "TE: gzip\r\n"); - } -#endif - break; - - case H1_HD_ACCEPT_ENCODING: - curlx_safefree(data->state.aptr.accept_encoding); - if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) && - data->set.str[STRING_ENCODING]) - result = curlx_dyn_addf(req, "Accept-Encoding: %s\r\n", - data->set.str[STRING_ENCODING]); - break; - - case H1_HD_REFERER: - curlx_safefree(data->state.aptr.ref); - if(Curl_bufref_ptr(&data->state.referer) && - !Curl_checkheaders(data, STRCONST("Referer"))) - result = curlx_dyn_addf(req, "Referer: %s\r\n", - Curl_bufref_ptr(&data->state.referer)); - break; - -#ifndef CURL_DISABLE_PROXY - case H1_HD_PROXY_CONNECTION: - if(conn->bits.httpproxy && - !conn->bits.tunnel_proxy && - !Curl_checkheaders(data, STRCONST("Proxy-Connection")) && - !Curl_checkProxyheaders(data, data->conn, STRCONST("Proxy-Connection"))) - result = curlx_dyn_add(req, "Proxy-Connection: Keep-Alive\r\n"); - break; -#endif - - case H1_HD_TRANSFER_ENCODING: - result = http_req_set_TE(data, req, httpversion); - break; - -#ifndef CURL_DISABLE_ALTSVC - case H1_HD_ALT_USED: - if(conn->bits.altused && !Curl_checkheaders(data, STRCONST("Alt-Used"))) - result = curlx_dyn_addf(req, "Alt-Used: %s:%u\r\n", - conn->conn_to_host.name, - conn->conn_to_port); - break; -#endif - - case H1_HD_UPGRADE: - if(!Curl_conn_is_ssl(data->conn, FIRSTSOCKET) && (httpversion < 20) && - (data->state.http_neg.wanted & CURL_HTTP_V2x) && - data->state.http_neg.h2_upgrade) { - /* append HTTP2 upgrade magic stuff to the HTTP request if it is not done - over SSL */ - result = Curl_http2_request_upgrade(req, data); - } -#ifndef CURL_DISABLE_WEBSOCKETS - if(!result && conn->scheme->protocol & (CURLPROTO_WS | CURLPROTO_WSS)) - result = Curl_ws_request(data, req); -#endif - break; - - case H1_HD_COOKIES: - result = http_cookies(data, req); - break; - - case H1_HD_CONDITIONALS: - result = Curl_add_timecondition(data, req); - break; - - case H1_HD_CUSTOM: - result = Curl_add_custom_headers(data, FALSE, httpversion, req); - break; - - case H1_HD_CONTENT: - result = http_add_content_hds(data, req, httpversion, httpreq); - break; - - case H1_HD_CONNECTION: { - result = http_add_connection_hd(data, req); - break; - } - - case H1_HD_LAST: - result = curlx_dyn_addn(req, STRCONST("\r\n")); - break; - } - return result; -} - -/* - * Curl_http() gets called from the generic multi_do() function when an HTTP - * request is to be performed. This creates and sends a properly constructed - * HTTP request. - */ -CURLcode Curl_http(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - Curl_HttpReq httpreq; - const char *method; - struct dynbuf req; - unsigned char httpversion; - size_t hd_id; - - /* Always consider the DO phase done after this function call, even if there - may be parts of the request that are not yet sent, since we can deal with - the rest of the request in the PERFORM phase. */ - *done = TRUE; - /* initialize a dynamic send-buffer */ - curlx_dyn_init(&req, DYN_HTTP_REQUEST); - /* make sure the header buffer is reset - if there are leftovers from a - previous transfer */ - curlx_dyn_reset(&data->state.headerb); - data->state.maybe_folded = FALSE; - - if(!data->conn->bits.reuse) { - result = http_check_new_conn(data); - if(result) - goto out; - } - - /* Add collecting of headers written to client. For a new connection, - * we might have done that already, but reuse - * or multiplex needs it here as well. */ - result = Curl_headers_init(data); - if(result) - goto out; - - data->state.http_hd_te = FALSE; - data->state.http_hd_upgrade = FALSE; - data->state.http_hd_h2_settings = FALSE; - - /* what kind of request do we need to send? */ - Curl_http_method(data, &method, &httpreq); - - /* select host to send */ - result = http_set_aptr_host(data); - if(!result) { - /* setup the authentication headers, how that method and host are known */ - char *pq = NULL; - if(data->state.up.query) { - pq = curl_maprintf("%s?%s", data->state.up.path, data->state.up.query); - if(!pq) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - result = Curl_http_output_auth(data, data->conn, method, httpreq, - (pq ? pq : data->state.up.path), FALSE); - curlx_free(pq); - } - if(result) - goto out; - - result = http_useragent(data); - if(result) - goto out; - - /* Setup input reader, resume information and ranges */ - result = set_reader(data, httpreq); - if(!result) - result = http_resume(data, httpreq); - if(!result) - result = http_range(data, httpreq); - if(result) - goto out; - - httpversion = http_request_version(data); - /* Add request line and all headers to `req` */ - for(hd_id = 0; hd_id <= H1_HD_LAST; ++hd_id) { - result = http_add_hd(data, &req, (http_hd_t)hd_id, - httpversion, method, httpreq); - if(result) - goto out; - } - - /* setup variables for the upcoming transfer and send */ - Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); - result = Curl_req_send(data, &req, httpversion); - - if((httpversion >= 20) && data->req.upload_chunky) - /* upload_chunky was set above to set up the request in a chunky fashion, - but is disabled here again to avoid that the chunked encoded version is - actually used when sending the request body over h2 */ - data->req.upload_chunky = FALSE; - -out: - if(result == CURLE_TOO_LARGE) - failf(data, "HTTP request too large"); - - curlx_dyn_free(&req); - return result; -} - -typedef enum { - STATUS_UNKNOWN, /* not enough data to tell yet */ - STATUS_DONE, /* a status line was read */ - STATUS_BAD /* not a status line */ -} statusline; - -/* Check a string for a prefix. Check no more than 'len' bytes */ -static bool checkprefixmax(const char *prefix, const char *buffer, size_t len) -{ - size_t ch = CURLMIN(strlen(prefix), len); - return curl_strnequal(prefix, buffer, ch); -} - -/* - * checkhttpprefix() - * - * Returns TRUE if member of the list matches prefix of string - */ -static statusline checkhttpprefix(struct Curl_easy *data, - const char *s, size_t len) -{ - struct curl_slist *head = data->set.http200aliases; - statusline rc = STATUS_BAD; - statusline onmatch = len >= 5 ? STATUS_DONE : STATUS_UNKNOWN; - - while(head) { - if(checkprefixmax(head->data, s, len)) { - rc = onmatch; - break; - } - head = head->next; - } - - if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len))) - rc = onmatch; - - return rc; -} - -#ifndef CURL_DISABLE_RTSP -static statusline checkrtspprefix(struct Curl_easy *data, - const char *s, size_t len) -{ - statusline status = STATUS_BAD; - statusline onmatch = len >= 5 ? STATUS_DONE : STATUS_UNKNOWN; - (void)data; - if(checkprefixmax("RTSP/", s, len)) - status = onmatch; - - return status; -} -#endif /* CURL_DISABLE_RTSP */ - -static statusline checkprotoprefix(struct Curl_easy *data, - struct connectdata *conn, - const char *s, size_t len) -{ -#ifndef CURL_DISABLE_RTSP - if(conn->scheme->protocol & CURLPROTO_RTSP) - return checkrtspprefix(data, s, len); -#else - (void)conn; -#endif /* CURL_DISABLE_RTSP */ - - return checkhttpprefix(data, s, len); -} - -/* HTTP header has field name `n` (a string constant) */ -#define HD_IS(hd, hdlen, n) \ - (((hdlen) >= (sizeof(n) - 1)) && curl_strnequal(n, hd, sizeof(n) - 1)) - -#define HD_VAL(hd, hdlen, n) \ - ((((hdlen) >= (sizeof(n) - 1)) && (hd) && \ - curl_strnequal(n, hd, sizeof(n) - 1)) ? ((hd) + (sizeof(n) - 1)) : NULL) - -/* HTTP header has field name `n` (a string constant) and contains `v` - * (a string constant) in its value(s) */ -#define HD_IS_AND_SAYS(hd, hdlen, n, v) \ - (HD_IS(hd, hdlen, n) && \ - ((hdlen) > ((sizeof(n) - 1) + (sizeof(v) - 1))) && \ - Curl_compareheader(hd, STRCONST(n), STRCONST(v))) - -/* - * http_header_a() parses a single response header starting with A. - */ -static CURLcode http_header_a(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ -#ifndef CURL_DISABLE_ALTSVC - const char *v; - struct connectdata *conn = data->conn; - v = (data->asi && - (Curl_xfer_is_secure(data) || -#ifdef DEBUGBUILD - /* allow debug builds to circumvent the HTTPS restriction */ - getenv("CURL_ALTSVC_HTTP") -#else - 0 -#endif - )) ? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL; - if(v) { - /* the ALPN of the current request */ - struct SingleRequest *k = &data->req; - enum alpnid id = (k->httpversion == 30) ? ALPN_h3 : - (k->httpversion == 20) ? ALPN_h2 : ALPN_h1; - return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name, - curlx_uitous((unsigned int)conn->remote_port)); - } -#else - (void)data; - (void)hd; - (void)hdlen; -#endif - return CURLE_OK; -} - -/* - * http_header_c() parses a single response header starting with C. - */ -static CURLcode http_header_c(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - struct connectdata *conn = data->conn; - struct SingleRequest *k = &data->req; - const char *v; - - /* Check for Content-Length: header lines to get size. Browsers insist we - should accept multiple Content-Length headers and that a comma separated - list also is fine and then we should accept them all as long as they are - the same value. Different values trigger error. - */ - v = (!k->http_bodyless && !data->set.ignorecl) ? - HD_VAL(hd, hdlen, "Content-Length:") : NULL; - if(v) { - do { - curl_off_t contentlength; - int offt = curlx_str_numblanks(&v, &contentlength); - - if(offt == STRE_OVERFLOW) { - /* out of range */ - if(data->set.max_filesize) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - streamclose(conn, "overflow content-length"); - infof(data, "Overflow Content-Length: value"); - return CURLE_OK; - } - else { - if((offt == STRE_OK) && - ((k->size == -1) || /* not set to something before */ - (k->size == contentlength))) { /* or the same value */ - - k->size = contentlength; - curlx_str_passblanks(&v); - - /* on a comma, loop and get the next instead */ - if(!curlx_str_single(&v, ',')) - continue; - - if(!curlx_str_newline(&v)) { - k->maxdownload = k->size; - return CURLE_OK; - } - } - /* negative, different value or rubbish - bad HTTP */ - failf(data, "Invalid Content-Length: value"); - return CURLE_WEIRD_SERVER_REPLY; - } - } while(1); - } - v = (!k->http_bodyless && data->set.str[STRING_ENCODING]) ? - HD_VAL(hd, hdlen, "Content-Encoding:") : NULL; - if(v) { - /* - * Process Content-Encoding. Look for the values: identity, gzip, deflate, - * compress, x-gzip and x-compress. x-gzip and x-compress are the same as - * gzip and compress. (Sec 3.5 RFC 2616). zlib cannot handle compress. - * Errors are handled further down when the response body is processed - */ - return Curl_build_unencoding_stack(data, v, FALSE); - } - /* check for Content-Type: header lines to get the MIME-type */ - v = HD_VAL(hd, hdlen, "Content-Type:"); - if(v) { - char *contenttype = Curl_copy_header_value(hd); - if(!contenttype) - return CURLE_OUT_OF_MEMORY; - if(!*contenttype) - /* ignore empty data */ - curlx_free(contenttype); - else { - curlx_free(data->info.contenttype); - data->info.contenttype = contenttype; - } - return CURLE_OK; - } - if((k->httpversion < 20) && - HD_IS_AND_SAYS(hd, hdlen, "Connection:", "close")) { - /* - * [RFC 2616, section 8.1.2.1] - * "Connection: close" is HTTP/1.1 language and means that - * the connection will close when this request has been - * served. - */ - connclose(conn, "Connection: close used"); - return CURLE_OK; - } - if((k->httpversion == 10) && - HD_IS_AND_SAYS(hd, hdlen, "Connection:", "keep-alive")) { - /* - * An HTTP/1.0 reply with the 'Connection: keep-alive' line - * tells us the connection will be kept alive for our - * pleasure. Default action for 1.0 is to close. - * - * [RFC2068, section 19.7.1] */ - connkeep(conn, "Connection keep-alive"); - infof(data, "HTTP/1.0 connection set to keep alive"); - return CURLE_OK; - } - v = !k->http_bodyless ? HD_VAL(hd, hdlen, "Content-Range:") : NULL; - if(v) { - /* Content-Range: bytes [num]- - Content-Range: bytes: [num]- - Content-Range: [num]- - Content-Range: [asterisk]/[total] - - The second format was added since Sun's webserver - JavaWebServer/1.1.1 obviously sends the header this way! - The third added since some servers use that! - The fourth means the requested range was unsatisfied. - */ - - const char *ptr = v; - - /* Move forward until first digit or asterisk */ - while(*ptr && !ISDIGIT(*ptr) && *ptr != '*') - ptr++; - - /* if it truly stopped on a digit */ - if(ISDIGIT(*ptr)) { - if(!curlx_str_number(&ptr, &k->offset, CURL_OFF_T_MAX) && - (data->state.resume_from == k->offset)) - /* we asked for a resume and we got it */ - k->content_range = TRUE; - } - else if(k->httpcode < 300) - data->state.resume_from = 0; /* get everything */ - } - return CURLE_OK; -} - -/* - * http_header_l() parses a single response header starting with L. - */ -static CURLcode http_header_l(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - struct connectdata *conn = data->conn; - struct SingleRequest *k = &data->req; - const char *v = (!k->http_bodyless && - (data->set.timecondition || data->set.get_filetime)) ? - HD_VAL(hd, hdlen, "Last-Modified:") : NULL; - if(v) { - if(Curl_getdate_capped(v, &k->timeofdoc)) - k->timeofdoc = 0; - if(data->set.get_filetime) - data->info.filetime = k->timeofdoc; - return CURLE_OK; - } - if(HD_IS(hd, hdlen, "Location:")) { - /* this is the URL that the server advises us to use instead */ - char *location = Curl_copy_header_value(hd); - if(!location) - return CURLE_OUT_OF_MEMORY; - if(!*location || - (data->req.location && !strcmp(data->req.location, location))) { - /* ignore empty header, or exact repeat of a previous one */ - curlx_free(location); - return CURLE_OK; - } - else { - /* has value and is not an exact repeat */ - if(data->req.location) { - failf(data, "Multiple Location headers"); - curlx_free(location); - return CURLE_WEIRD_SERVER_REPLY; - } - data->req.location = location; - - if((k->httpcode >= 300 && k->httpcode < 400) && - data->set.http_follow_mode) { - CURLcode result; - DEBUGASSERT(!data->req.newurl); - data->req.newurl = curlx_strdup(data->req.location); /* clone */ - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - - /* some cases of POST and PUT etc needs to rewind the data - stream at this point */ - result = http_perhapsrewind(data, conn); - if(result) - return result; - - /* mark the next request as a followed location: */ - data->state.this_is_a_follow = TRUE; - } - } - } - return CURLE_OK; -} - -/* - * http_header_p() parses a single response header starting with P. - */ -static CURLcode http_header_p(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - struct SingleRequest *k = &data->req; - -#ifndef CURL_DISABLE_PROXY - const char *v = HD_VAL(hd, hdlen, "Proxy-Connection:"); - if(v) { - struct connectdata *conn = data->conn; - if((k->httpversion == 10) && conn->bits.httpproxy && - HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "keep-alive")) { - /* - * When an HTTP/1.0 reply comes when using a proxy, the - * 'Proxy-Connection: keep-alive' line tells us the - * connection will be kept alive for our pleasure. - * Default action for 1.0 is to close. - */ - connkeep(conn, "Proxy-Connection keep-alive"); /* do not close */ - infof(data, "HTTP/1.0 proxy connection set to keep alive"); - } - else if((k->httpversion == 11) && conn->bits.httpproxy && - HD_IS_AND_SAYS(hd, hdlen, "Proxy-Connection:", "close")) { - /* - * We get an HTTP/1.1 response from a proxy and it says it will - * close down after this transfer. - */ - connclose(conn, "Proxy-Connection: asked to close after done"); - infof(data, "HTTP/1.1 proxy connection set close"); - } - return CURLE_OK; - } -#endif - if((407 == k->httpcode) && HD_IS(hd, hdlen, "Proxy-authenticate:")) { - char *auth = Curl_copy_header_value(hd); - CURLcode result = auth ? CURLE_OK : CURLE_OUT_OF_MEMORY; - if(!result) { - result = Curl_http_input_auth(data, TRUE, auth); - curlx_free(auth); - } - return result; - } -#ifdef USE_SPNEGO - if(HD_IS(hd, hdlen, "Persistent-Auth:")) { - struct connectdata *conn = data->conn; - struct negotiatedata *negdata = Curl_auth_nego_get(conn, FALSE); - struct auth *authp = &data->state.authhost; - if(!negdata) - return CURLE_OUT_OF_MEMORY; - if(authp->picked == CURLAUTH_NEGOTIATE) { - char *persistentauth = Curl_copy_header_value(hd); - if(!persistentauth) - return CURLE_OUT_OF_MEMORY; - negdata->noauthpersist = !!checkprefix("false", persistentauth); - negdata->havenoauthpersist = TRUE; - infof(data, "Negotiate: noauthpersist -> %d, header part: %s", - negdata->noauthpersist, persistentauth); - curlx_free(persistentauth); - } - } -#endif - return CURLE_OK; -} - -/* - * http_header_r() parses a single response header starting with R. - */ -static CURLcode http_header_r(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - const char *v = HD_VAL(hd, hdlen, "Retry-After:"); - if(v) { - /* Retry-After = HTTP-date / delay-seconds */ - curl_off_t retry_after = 0; /* zero for unknown or "now" */ - time_t date = 0; - curlx_str_passblanks(&v); - - /* try it as a date first, because a date can otherwise start with and - get treated as a number */ - if(!Curl_getdate_capped(v, &date)) { - time_t current = time(NULL); - if(date >= current) - /* convert date to number of seconds into the future */ - retry_after = date - current; - } - else - /* Try it as a decimal number, ignore errors */ - (void)curlx_str_number(&v, &retry_after, CURL_OFF_T_MAX); - /* limit to 6 hours max. this is not documented so that it can be changed - in the future if necessary. */ - if(retry_after > 21600) - retry_after = 21600; - data->info.retry_after = retry_after; - } - return CURLE_OK; -} - -/* - * http_header_s() parses a single response header starting with S. - */ -static CURLcode http_header_s(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ -#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_HSTS) - struct connectdata *conn = data->conn; - const char *v; -#else - (void)data; - (void)hd; - (void)hdlen; -#endif - -#ifndef CURL_DISABLE_COOKIES - v = (data->cookies && data->state.cookie_engine) ? - HD_VAL(hd, hdlen, "Set-Cookie:") : NULL; - if(v) { - /* If there is a custom-set Host: name, use it here, or else use - * real peer hostname. */ - const char *host = data->req.cookiehost ? - data->req.cookiehost : conn->host.name; - const bool secure_context = Curl_secure_context(conn, host); - CURLcode result; - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - result = Curl_cookie_add(data, data->cookies, TRUE, FALSE, v, host, - data->state.up.path, secure_context); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - return result; - } -#endif -#ifndef CURL_DISABLE_HSTS - /* If enabled, the header is incoming and this is over HTTPS */ - v = (data->hsts && - (Curl_xfer_is_secure(data) || -#ifdef DEBUGBUILD - /* allow debug builds to circumvent the HTTPS restriction */ - getenv("CURL_HSTS_HTTP") -#else - 0 -#endif - ) - ) ? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL; - if(v) { - CURLcode result = - Curl_hsts_parse(data->hsts, conn->host.name, v); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - return result; - infof(data, "Illegal STS header skipped"); - } -#ifdef DEBUGBUILD - else - infof(data, "Parsed STS header fine (%zu entries)", - Curl_llist_count(&data->hsts->list)); -#endif - } -#endif - - return CURLE_OK; -} - -/* - * http_header_t() parses a single response header starting with T. - */ -static CURLcode http_header_t(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - struct connectdata *conn = data->conn; - struct SingleRequest *k = &data->req; - - /* RFC 9112, ch. 6.1 - * "Transfer-Encoding MAY be sent in a response to a HEAD request or - * in a 304 (Not Modified) response (Section 15.4.5 of [HTTP]) to a - * GET request, neither of which includes a message body, to indicate - * that the origin server would have applied a transfer coding to the - * message body if the request had been an unconditional GET." - * - * Read: in these cases the 'Transfer-Encoding' does not apply - * to any data following the response headers. Do not add any decoders. - */ - const char *v = (!k->http_bodyless && - (data->state.httpreq != HTTPREQ_HEAD) && - (k->httpcode != 304)) ? - HD_VAL(hd, hdlen, "Transfer-Encoding:") : NULL; - if(v) { - /* One or more encodings. We check for chunked and/or a compression - algorithm. */ - CURLcode result = Curl_build_unencoding_stack(data, v, TRUE); - if(result) - return result; - if(!k->chunk && data->set.http_transfer_encoding) { - /* if this is not chunked, only close can signal the end of this - * transfer as Content-Length is said not to be trusted for - * transfer-encoding! */ - connclose(conn, "HTTP/1.1 transfer-encoding without chunks"); - k->ignore_cl = TRUE; - } - return CURLE_OK; - } - v = HD_VAL(hd, hdlen, "Trailer:"); - if(v) { - data->req.resp_trailer = TRUE; - return CURLE_OK; - } - return CURLE_OK; -} - -/* - * http_header_w() parses a single response header starting with W. - */ -static CURLcode http_header_w(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - struct SingleRequest *k = &data->req; - CURLcode result = CURLE_OK; - - if((401 == k->httpcode) && HD_IS(hd, hdlen, "WWW-Authenticate:")) { - char *auth = Curl_copy_header_value(hd); - if(!auth) - result = CURLE_OUT_OF_MEMORY; - else { - result = Curl_http_input_auth(data, FALSE, auth); - curlx_free(auth); - } - } - return result; -} - -/* - * http_header() parses a single response header. - */ -static CURLcode http_header(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - CURLcode result = CURLE_OK; - - switch(hd[0]) { - case 'a': - case 'A': - result = http_header_a(data, hd, hdlen); - break; - case 'c': - case 'C': - result = http_header_c(data, hd, hdlen); - break; - case 'l': - case 'L': - result = http_header_l(data, hd, hdlen); - break; - case 'p': - case 'P': - result = http_header_p(data, hd, hdlen); - break; - case 'r': - case 'R': - result = http_header_r(data, hd, hdlen); - break; - case 's': - case 'S': - result = http_header_s(data, hd, hdlen); - break; - case 't': - case 'T': - result = http_header_t(data, hd, hdlen); - break; - case 'w': - case 'W': - result = http_header_w(data, hd, hdlen); - break; - } - - if(!result) { - struct connectdata *conn = data->conn; - if(conn->scheme->protocol & CURLPROTO_RTSP) - result = Curl_rtsp_parseheader(data, hd); - } - return result; -} - -/* - * Called after the first HTTP response line (the status line) has been - * received and parsed. - */ -static CURLcode http_statusline(struct Curl_easy *data, - struct connectdata *conn) -{ - struct SingleRequest *k = &data->req; - - switch(k->httpversion) { - case 10: - case 11: -#ifdef USE_HTTP2 - case 20: -#endif -#ifdef USE_HTTP3 - case 30: -#endif - /* no major version switch mid-connection */ - if(k->httpversion_sent && - (k->httpversion / 10 != k->httpversion_sent / 10)) { - failf(data, "Version mismatch (from HTTP/%d to HTTP/%d)", - k->httpversion_sent / 10, k->httpversion / 10); - return CURLE_WEIRD_SERVER_REPLY; - } - break; - default: - failf(data, "Unsupported HTTP version (%d.%d) in response", - k->httpversion / 10, k->httpversion % 10); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - data->info.httpcode = k->httpcode; - data->info.httpversion = k->httpversion; - conn->httpversion_seen = k->httpversion; - - if(!data->state.http_neg.rcvd_min || - data->state.http_neg.rcvd_min > k->httpversion) - /* store the lowest server version we encounter */ - data->state.http_neg.rcvd_min = k->httpversion; - - /* - * This code executes as part of processing the header. As a - * result, it is not totally clear how to interpret the - * response code yet as that depends on what other headers may - * be present. 401 and 407 may be errors, but may be OK - * depending on how authentication is working. Other codes - * are definitely errors, so give up here. - */ - if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET && - k->httpcode == 416) { - /* "Requested Range Not Satisfiable", proceed and pretend this is no - error */ - k->ignorebody = TRUE; /* Avoid appending error msg to good data. */ - } - - if(k->httpversion == 10) { - /* Default action for HTTP/1.0 must be to close, unless - we get one of those fancy headers that tell us the - server keeps it open for us! */ - infof(data, "HTTP 1.0, assume close after body"); - connclose(conn, "HTTP/1.0 close after body"); - } - - k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; - switch(k->httpcode) { - case 304: - /* (quote from RFC2616, section 10.3.5): The 304 response - * MUST NOT contain a message-body, and thus is always - * terminated by the first empty line after the header - * fields. */ - if(data->set.timecondition) - data->info.timecond = TRUE; - FALLTHROUGH(); - case 204: - /* (quote from RFC2616, section 10.2.5): The server has - * fulfilled the request but does not need to return an - * entity-body ... The 204 response MUST NOT include a - * message-body, and thus is always terminated by the first - * empty line after the header fields. */ - k->size = 0; - k->maxdownload = 0; - k->http_bodyless = TRUE; - break; - default: - break; - } - return CURLE_OK; -} - -/* Content-Length must be ignored if any Transfer-Encoding is present in the - response. Refer to RFC 7230 section 3.3.3 and RFC2616 section 4.4. This is - figured out here after all headers have been received but before the final - call to the user's header callback, so that a valid content length can be - retrieved by the user in the final call. */ -static CURLcode http_size(struct Curl_easy *data) -{ - struct SingleRequest *k = &data->req; - if(data->req.ignore_cl || k->chunk) { - k->size = k->maxdownload = -1; - } - else if(k->size != -1) { - if(data->set.max_filesize && - !k->ignorebody && - (k->size > data->set.max_filesize)) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - if(k->ignorebody) - infof(data, "setting size while ignoring"); - Curl_pgrsSetDownloadSize(data, k->size); - k->maxdownload = k->size; - } - return CURLE_OK; -} - -static CURLcode verify_header(struct Curl_easy *data, - const char *hd, size_t hdlen) -{ - struct SingleRequest *k = &data->req; - const char *ptr = memchr(hd, 0x00, hdlen); - if(ptr) { - /* this is bad, bail out */ - failf(data, "Nul byte in header"); - return CURLE_WEIRD_SERVER_REPLY; - } - if(k->headerline < 2) - /* the first "header" is the status-line and it has no colon */ - return CURLE_OK; - if(((hd[0] == ' ') || (hd[0] == '\t')) && k->headerline > 2) - /* line folding, cannot happen on line 2 */ - ; - else { - ptr = memchr(hd, ':', hdlen); - if(!ptr) { - /* this is bad, bail out */ - failf(data, "Header without colon"); - return CURLE_WEIRD_SERVER_REPLY; - } - } - return CURLE_OK; -} - -CURLcode Curl_bump_headersize(struct Curl_easy *data, - size_t delta, - bool connect_only) -{ - size_t bad = 0; - unsigned int max = MAX_HTTP_RESP_HEADER_SIZE; - if(delta < MAX_HTTP_RESP_HEADER_SIZE) { - data->info.header_size += (unsigned int)delta; - data->req.allheadercount += (unsigned int)delta; - if(!connect_only) - data->req.headerbytecount += (unsigned int)delta; - if(data->req.allheadercount > max) - bad = data->req.allheadercount; - else if(data->info.header_size > (max * 20)) { - bad = data->info.header_size; - max *= 20; - } - } - else - bad = data->req.allheadercount + delta; - if(bad) { - failf(data, "Too large response headers: %zu > %u", bad, max); - return CURLE_RECV_ERROR; - } - return CURLE_OK; -} - -/* - * Handle a 101 Switching Protocols response. Performs the actual protocol - * upgrade to HTTP/2 or WebSocket based on what was requested. - */ -static CURLcode http_on_101_upgrade(struct Curl_easy *data, - const char *buf, size_t blen, - size_t *pconsumed, - bool *conn_changed) -{ - struct connectdata *conn = data->conn; - struct SingleRequest *k = &data->req; - -#if !defined(USE_NGHTTP2) && defined(CURL_DISABLE_WEBSOCKETS) - (void)buf; - (void)blen; - (void)pconsumed; -#else - CURLcode result; - int upgr101_requested = k->upgr101; -#endif - - if(k->httpversion_sent != 11) { - /* invalid for other HTTP versions */ - failf(data, "server sent 101 response while not talking HTTP/1.1"); - return CURLE_WEIRD_SERVER_REPLY; - } - - /* Whatever the success, upgrade was selected. */ - k->upgr101 = UPGR101_RECEIVED; - conn->bits.upgrade_in_progress = FALSE; - *conn_changed = TRUE; - - /* To be fully compliant, we would check the "Upgrade:" response header to - * mention the protocol we requested. */ -#ifdef USE_NGHTTP2 - if(upgr101_requested == UPGR101_H2) { - /* Switch to HTTP/2, where we will get more responses. blen bytes in buf - * are already h2 protocol bytes */ - infof(data, "Received 101, Switching to HTTP/2"); - result = Curl_http2_upgrade(data, conn, FIRSTSOCKET, buf, blen); - if(!result) - *pconsumed += blen; - return result; - } -#endif -#ifndef CURL_DISABLE_WEBSOCKETS - if(upgr101_requested == UPGR101_WS) { - /* Switch to WebSocket, where we now stream ws frames. blen bytes in buf - * are already ws protocol bytes */ - infof(data, "Received 101, Switching to WebSocket"); - result = Curl_ws_accept(data, buf, blen); - if(!result) - *pconsumed += blen; /* ws accept handled the data */ - return result; - } -#endif - /* We silently accept this as the final response. What are we switching to - * if we did not ask for an Upgrade? Maybe the application provided an - * `Upgrade: xxx` header? */ - k->header = FALSE; - return CURLE_OK; -} - -/* - * Handle 1xx intermediate HTTP responses. Sets up state for more - * headers and processes 100-continue and 101 upgrade responses. - */ -static CURLcode http_on_1xx_response(struct Curl_easy *data, - const char *buf, size_t blen, - size_t *pconsumed, - bool *conn_changed) -{ - struct SingleRequest *k = &data->req; - - /* "A user agent MAY ignore unexpected 1xx status responses." - * By default, we expect to get more responses after this one. */ - k->header = TRUE; - k->headerline = 0; /* restart the header line counter */ - - switch(k->httpcode) { - case 100: - /* We have made an HTTP PUT or POST and this is 1.1-lingo that tells us - * that the server is OK with this and ready to receive the data. */ - http_exp100_got100(data); - break; - case 101: - return http_on_101_upgrade(data, buf, blen, pconsumed, conn_changed); - default: - /* The server may send us other 1xx responses, like informative 103. This - * has no influence on request processing and we expect to receive a - * final response eventually. */ - break; - } - return CURLE_OK; -} - -#if defined(USE_NTLM) || defined(USE_SPNEGO) -/* - * Check if NTLM or SPNEGO authentication negotiation failed due to - * connection closure (typically on HTTP/1.0 servers). - */ -static void http_check_auth_closure(struct Curl_easy *data, - struct connectdata *conn) -{ - /* At this point we have some idea about the fate of the connection. If we - are closing the connection it may result auth failure. */ -#ifdef USE_NTLM - if(conn->bits.close && - (((data->req.httpcode == 401) && - (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || - ((data->req.httpcode == 407) && - (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) { - infof(data, "Connection closure while negotiating auth (HTTP 1.0?)"); - data->state.authproblem = TRUE; - } -#endif -#ifdef USE_SPNEGO - if(conn->bits.close && - (((data->req.httpcode == 401) && - (conn->http_negotiate_state == GSS_AUTHRECV)) || - ((data->req.httpcode == 407) && - (conn->proxy_negotiate_state == GSS_AUTHRECV)))) { - infof(data, "Connection closure while negotiating auth (HTTP 1.0?)"); - data->state.authproblem = TRUE; - } - if((conn->http_negotiate_state == GSS_AUTHDONE) && - (data->req.httpcode != 401)) { - conn->http_negotiate_state = GSS_AUTHSUCC; - } - if((conn->proxy_negotiate_state == GSS_AUTHDONE) && - (data->req.httpcode != 407)) { - conn->proxy_negotiate_state = GSS_AUTHSUCC; - } -#endif -} -#else -#define http_check_auth_closure(x, y) /* empty */ -#endif - -/* - * Handle an error response (>= 300) received while still sending the - * request body. Deals with 417 Expectation Failed retries, keep-sending - * on error, and aborting the send. - */ -static CURLcode http_handle_send_error(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - struct SingleRequest *k = &data->req; - CURLcode result = CURLE_OK; - - if(!data->req.authneg && !conn->bits.close && - !Curl_creader_will_rewind(data)) { - /* - * General treatment of errors when about to send data. - * Including: "417 Expectation Failed", while waiting for - * 100-continue. - * - * The check for close above is done because if something - * else has already deemed the connection to get closed then - * something else should have considered the big picture and - * we avoid this check. - */ - - switch(data->state.httpreq) { - case HTTPREQ_PUT: - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - /* We got an error response. If this happened before the - * whole request body has been sent we stop sending and - * mark the connection for closure after we have read the - * entire response. */ - if(!Curl_req_done_sending(data)) { - if((k->httpcode == 417) && http_exp100_is_selected(data)) { - /* 417 Expectation Failed - try again without the - Expect header */ - if(!k->writebytecount && http_exp100_is_waiting(data)) { - infof(data, "Got HTTP failure 417 while waiting for a 100"); - } - else { - infof(data, "Got HTTP failure 417 while sending data"); - streamclose(conn, "Stop sending data before everything sent"); - result = http_perhapsrewind(data, conn); - if(result) - return result; - } - data->state.disableexpect = TRUE; - Curl_req_abort_sending(data); - DEBUGASSERT(!data->req.newurl); - data->req.newurl = Curl_bufref_dup(&data->state.url); - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - } - else if(data->set.http_keep_sending_on_error) { - infof(data, "HTTP error before end of send, keep sending"); - http_exp100_send_anyway(data); - } - else { - infof(data, "HTTP error before end of send, stop sending"); - streamclose(conn, "Stop sending data before everything sent"); - result = Curl_req_abort_sending(data); - if(result) - return result; - } - } - break; - - default: /* default label present to avoid compiler warnings */ - break; - } - } - - if(Curl_creader_will_rewind(data) && !Curl_req_done_sending(data)) { - /* We rewind before next send, continue sending now */ - infof(data, "Keep sending data to get tossed away"); - CURL_REQ_SET_SEND(data); - } - return result; -} - -static CURLcode http_on_response(struct Curl_easy *data, - const char *last_hd, size_t last_hd_len, - const char *buf, size_t blen, - size_t *pconsumed) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - struct SingleRequest *k = &data->req; - bool conn_changed = FALSE; - - (void)buf; /* not used without HTTP2 enabled */ - *pconsumed = 0; - - if(k->upgr101 == UPGR101_RECEIVED) { - /* supposedly upgraded to http2 now */ - if(data->req.httpversion != 20) - infof(data, "Lying server, not serving HTTP/2"); - } - - if(k->httpcode < 200 && last_hd) { - /* Intermediate responses might trigger processing of more responses, - * write the last header to the client before proceeding. */ - result = http_write_header(data, last_hd, last_hd_len); - last_hd = NULL; /* handled it */ - if(result) - goto out; - } - - if(k->httpcode < 100) { - failf(data, "Unsupported response code in HTTP response"); - result = CURLE_UNSUPPORTED_PROTOCOL; - goto out; - } - else if(k->httpcode < 200) { - result = http_on_1xx_response(data, buf, blen, pconsumed, &conn_changed); - goto out; - } - - /* k->httpcode >= 200, final response */ - k->header = FALSE; - if(conn->bits.upgrade_in_progress) { - /* Asked for protocol upgrade, but it was not selected */ - conn->bits.upgrade_in_progress = FALSE; - conn_changed = TRUE; - } - - if((k->size == -1) && !k->chunk && !conn->bits.close && - (k->httpversion == 11) && - !(conn->scheme->protocol & CURLPROTO_RTSP) && - data->state.httpreq != HTTPREQ_HEAD) { - /* On HTTP 1.1, when connection is not to get closed, but no - Content-Length nor Transfer-Encoding chunked have been received, - according to RFC2616 section 4.4 point 5, we assume that the server - will close the connection to signal the end of the document. */ - infof(data, "no chunk, no close, no size. Assume close to signal end"); - streamclose(conn, "HTTP: No end-of-message indicator"); - } - - http_check_auth_closure(data, conn); - -#ifndef CURL_DISABLE_WEBSOCKETS - /* All >=200 HTTP status codes are errors when wanting ws */ - if(data->req.upgr101 == UPGR101_WS) { - failf(data, "Refused WebSocket upgrade: %d", k->httpcode); - result = CURLE_HTTP_RETURNED_ERROR; - goto out; - } -#endif - - /* Check if this response means the transfer errored. */ - if(http_should_fail(data, data->req.httpcode)) { - failf(data, "The requested URL returned error: %d", - k->httpcode); - result = CURLE_HTTP_RETURNED_ERROR; - goto out; - } - - /* Curl_http_auth_act() checks what authentication methods that are - * available and decides which one (if any) to use. It will set 'newurl' if - * an auth method was picked. */ - result = Curl_http_auth_act(data); - if(result) - goto out; - - if(k->httpcode >= 300) { - result = http_handle_send_error(data); - if(result) - goto out; - } - - /* If we requested a "no body", this is a good time to get - * out and return home. - */ - if(data->req.no_body) - k->download_done = TRUE; - - /* If max download size is *zero* (nothing) we already have nothing and can - safely return ok now! For HTTP/2, we would like to call - http2_handle_stream_close to properly close a stream. In order to do - this, we keep reading until we close the stream. */ - if((k->maxdownload == 0) && (k->httpversion_sent < 20)) - k->download_done = TRUE; - - /* final response without error, prepare to receive the body */ - result = http_firstwrite(data); - - if(!result) - /* This is the last response that we get for the current request. Check on - * the body size and determine if the response is complete. */ - result = http_size(data); - -out: - if(last_hd) - /* if not written yet, write it now */ - result = Curl_1st_fatal(result, - http_write_header(data, last_hd, last_hd_len)); - if(conn_changed) - /* poke the multi handle to allow pending pipewait to retry */ - Curl_multi_connchanged(data->multi); - return result; -} - -static CURLcode http_rw_hd(struct Curl_easy *data, - const char *hd, size_t hdlen, - const char *buf_remain, size_t blen, - size_t *pconsumed) -{ - CURLcode result = CURLE_OK; - struct SingleRequest *k = &data->req; - int writetype; - DEBUGASSERT(!hd[hdlen]); /* null-terminated */ - - *pconsumed = 0; - if((0x0a == *hd) || (0x0d == *hd)) { - /* Empty header line means end of headers! */ - struct dynbuf last_header; - size_t consumed; - - curlx_dyn_init(&last_header, hdlen + 1); - result = curlx_dyn_addn(&last_header, hd, hdlen); - if(result) - return result; - - /* analyze the response to find out what to do. */ - /* Caveat: we clear anything in the header brigade, because a - * response might switch HTTP version which may call use recursively. - * Not nice, but that is currently the way of things. */ - curlx_dyn_reset(&data->state.headerb); - result = http_on_response(data, curlx_dyn_ptr(&last_header), - curlx_dyn_len(&last_header), - buf_remain, blen, &consumed); - *pconsumed += consumed; - curlx_dyn_free(&last_header); - return result; - } - - /* - * Checks for special headers coming up. - */ - - writetype = CLIENTWRITE_HEADER; - if(!k->headerline++) { - /* This is the first header, it MUST be the error code line - or else we consider this to be the body right away! */ - bool fine_statusline = FALSE; - - k->httpversion = 0; /* Do not know yet */ - if(data->conn->scheme->protocol & PROTO_FAMILY_HTTP) { - /* - * https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2 - * - * The response code is always a three-digit number in HTTP as the spec - * says. We allow any three-digit number here, but we cannot make - * guarantees on future behaviors since it is not within the protocol. - */ - const char *p = hd; - - curlx_str_passblanks(&p); - if(!strncmp(p, "HTTP/", 5)) { - p += 5; - switch(*p) { - case '1': - p++; - if((p[0] == '.') && (p[1] == '0' || p[1] == '1')) { - if(ISBLANK(p[2])) { - k->httpversion = (unsigned char)(10 + (p[1] - '0')); - p += 3; - if(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2])) { - k->httpcode = ((p[0] - '0') * 100) + ((p[1] - '0') * 10) + - (p[2] - '0'); - /* RFC 9112 requires a single space following the status code, - but the browsers do not so let's not insist */ - fine_statusline = TRUE; - } - } - } - if(!fine_statusline) { - failf(data, "Unsupported HTTP/1 subversion in response"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - break; - case '2': - case '3': - if(!ISBLANK(p[1])) - break; - k->httpversion = (unsigned char)((*p - '0') * 10); - p += 2; - if(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2])) { - k->httpcode = ((p[0] - '0') * 100) + ((p[1] - '0') * 10) + - (p[2] - '0'); - p += 3; - if(!ISBLANK(*p)) - break; - fine_statusline = TRUE; - } - break; - default: /* unsupported */ - failf(data, "Unsupported HTTP version in response"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - } - - if(!fine_statusline) { - /* If user has set option HTTP200ALIASES, - compare header line against list of aliases - */ - statusline check = checkhttpprefix(data, hd, hdlen); - if(check == STATUS_DONE) { - fine_statusline = TRUE; - k->httpcode = 200; - k->httpversion = 10; - } - } - } - else if(data->conn->scheme->protocol & CURLPROTO_RTSP) { - const char *p = hd; - struct Curl_str ver; - curl_off_t status; - /* we set the max string a little excessive to forgive some leading - spaces */ - if(!curlx_str_until(&p, &ver, 32, ' ') && - !curlx_str_single(&p, ' ') && - !curlx_str_number(&p, &status, 999)) { - curlx_str_trimblanks(&ver); - if(curlx_str_cmp(&ver, "RTSP/1.0")) { - k->httpcode = (int)status; - fine_statusline = TRUE; - k->httpversion = 11; /* RTSP acts like HTTP 1.1 */ - } - } - if(!fine_statusline) - return CURLE_WEIRD_SERVER_REPLY; - } - - if(fine_statusline) { - result = http_statusline(data, data->conn); - if(result) - return result; - writetype |= CLIENTWRITE_STATUS; - } - else { - k->header = FALSE; /* this is not a header line */ - return CURLE_WEIRD_SERVER_REPLY; - } - } - - result = verify_header(data, hd, hdlen); - if(result) - return result; - - result = http_header(data, hd, hdlen); - if(result) - return result; - - /* - * Taken in one (more) header. Write it to the client. - */ - Curl_debug(data, CURLINFO_HEADER_IN, hd, hdlen); - - if(k->httpcode / 100 == 1) - writetype |= CLIENTWRITE_1XX; - result = Curl_client_write(data, writetype, hd, hdlen); - if(result) - return result; - - result = Curl_bump_headersize(data, hdlen, FALSE); - if(result) - return result; - - return CURLE_OK; -} - -/* remove trailing CRLF then all trailing whitespace */ -void Curl_http_to_fold(struct dynbuf *bf) -{ - size_t len = curlx_dyn_len(bf); - const char *hd = curlx_dyn_ptr(bf); - if(len && (hd[len - 1] == '\n')) - len--; - if(len && (hd[len - 1] == '\r')) - len--; - while(len && ISBLANK(hd[len - 1])) /* strip off trailing whitespace */ - len--; - curlx_dyn_setlen(bf, len); -} - -static void unfold_header(struct Curl_easy *data) -{ - Curl_http_to_fold(&data->state.headerb); - data->state.leading_unfold = TRUE; -} - -/* - * Read any HTTP header lines from the server and pass them to the client app. - */ -static CURLcode http_parse_headers(struct Curl_easy *data, - const char *buf, size_t blen, - size_t *pconsumed) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - struct SingleRequest *k = &data->req; - const char *end_ptr; - bool leftover_body = FALSE; - - /* we have bytes for the next header, make sure it is not a folded header - before passing it on */ - if(data->state.maybe_folded && blen) { - if(ISBLANK(buf[0])) { - /* folded, remove the trailing newlines and append the next header */ - unfold_header(data); - } - else { - /* the header data we hold is a complete header, pass it on */ - size_t ignore_this; - result = http_rw_hd(data, curlx_dyn_ptr(&data->state.headerb), - curlx_dyn_len(&data->state.headerb), - NULL, 0, &ignore_this); - curlx_dyn_reset(&data->state.headerb); - if(result) - return result; - } - data->state.maybe_folded = FALSE; - } - - /* header line within buffer loop */ - *pconsumed = 0; - while(blen && k->header) { - size_t consumed; - size_t hlen; - const char *hd; - size_t unfold_len = 0; - - if(data->state.leading_unfold) { - /* immediately after an unfold, keep only a single whitespace */ - while(blen && ISBLANK(buf[0])) { - buf++; - blen--; - unfold_len++; - } - if(blen) { - /* insert a single space */ - result = curlx_dyn_addn(&data->state.headerb, " ", 1); - if(result) - return result; - data->state.leading_unfold = FALSE; /* done now */ - } - } - - end_ptr = memchr(buf, '\n', blen); - if(!end_ptr) { - /* Not a complete header line within buffer, append the data to - the end of the headerbuff. */ - result = curlx_dyn_addn(&data->state.headerb, buf, blen); - if(result) - return result; - *pconsumed += blen + unfold_len; - - if(!k->headerline) { - /* check if this looks like a protocol header */ - statusline st = - checkprotoprefix(data, conn, - curlx_dyn_ptr(&data->state.headerb), - curlx_dyn_len(&data->state.headerb)); - - if(st == STATUS_BAD) { - /* this is not the beginning of a protocol first header line. - * Cannot be 0.9 if version was detected or connection was reused. */ - k->header = FALSE; - streamclose(conn, "bad HTTP: No end-of-message indicator"); - if((k->httpversion >= 10) || conn->bits.reuse) { - failf(data, "Invalid status line"); - return CURLE_WEIRD_SERVER_REPLY; - } - if(!data->state.http_neg.accept_09) { - failf(data, "Received HTTP/0.9 when not allowed"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - leftover_body = TRUE; - goto out; - } - } - goto out; /* read more and try again */ - } - - /* the size of the remaining header line */ - consumed = (end_ptr - buf) + 1; - - result = curlx_dyn_addn(&data->state.headerb, buf, consumed); - if(result) - return result; - blen -= consumed; - buf += consumed; - *pconsumed += consumed + unfold_len; - - /**** - * We now have a FULL header line in 'headerb'. - *****/ - - hlen = curlx_dyn_len(&data->state.headerb); - hd = curlx_dyn_ptr(&data->state.headerb); - - if(!k->headerline) { - /* the first read "header", the status line */ - statusline st = checkprotoprefix(data, conn, hd, hlen); - if(st == STATUS_BAD) { - streamclose(conn, "bad HTTP: No end-of-message indicator"); - /* this is not the beginning of a protocol first header line. - * Cannot be 0.9 if version was detected or connection was reused. */ - if((k->httpversion >= 10) || conn->bits.reuse) { - failf(data, "Invalid status line"); - return CURLE_WEIRD_SERVER_REPLY; - } - if(!data->state.http_neg.accept_09) { - failf(data, "Received HTTP/0.9 when not allowed"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - k->header = FALSE; - leftover_body = TRUE; - goto out; - } - } - else { - if(hlen && !ISNEWLINE(hd[0])) { - /* this is NOT the header separator */ - - /* if we have bytes for the next header, check for folding */ - if(blen && ISBLANK(buf[0])) { - /* remove the trailing CRLF and append the next header */ - unfold_header(data); - continue; - } - else if(!blen) { - /* this might be a folded header so deal with it in next invoke */ - data->state.maybe_folded = TRUE; - break; - } - } - } - - result = http_rw_hd(data, hd, hlen, buf, blen, &consumed); - /* We are done with this line. We reset because response - * processing might switch to HTTP/2 and that might call us - * directly again. */ - curlx_dyn_reset(&data->state.headerb); - if(consumed) { - blen -= consumed; - buf += consumed; - *pconsumed += consumed; - } - if(result) - return result; - } - - /* We might have reached the end of the header part here, but - there might be a non-header part left in the end of the read - buffer. */ -out: - if(!k->header && !leftover_body) { - curlx_dyn_free(&data->state.headerb); - } - return CURLE_OK; -} - -CURLcode Curl_http_write_resp_hd(struct Curl_easy *data, - const char *hd, size_t hdlen, - bool is_eos) -{ - CURLcode result; - size_t consumed; - char tmp = 0; - DEBUGASSERT(!hd[hdlen]); /* null-terminated */ - - result = http_rw_hd(data, hd, hdlen, &tmp, 0, &consumed); - if(!result && is_eos) { - result = Curl_client_write(data, (CLIENTWRITE_BODY | CLIENTWRITE_EOS), - &tmp, 0); - } - return result; -} - -/* - * HTTP protocol `write_resp` implementation. Parse headers - * when not done yet and otherwise return without consuming data. - */ -CURLcode Curl_http_write_resp_hds(struct Curl_easy *data, - const char *buf, size_t blen, - size_t *pconsumed) -{ - if(!data->req.header) { - *pconsumed = 0; - return CURLE_OK; - } - else { - CURLcode result; - - result = http_parse_headers(data, buf, blen, pconsumed); - if(!result && !data->req.header) { - if(!data->req.no_body && curlx_dyn_len(&data->state.headerb)) { - /* leftover from parsing something that turned out not - * to be a header, only happens if we allow for - * HTTP/0.9 like responses */ - result = Curl_client_write(data, CLIENTWRITE_BODY, - curlx_dyn_ptr(&data->state.headerb), - curlx_dyn_len(&data->state.headerb)); - } - curlx_dyn_free(&data->state.headerb); - } - return result; - } -} - -CURLcode Curl_http_write_resp(struct Curl_easy *data, - const char *buf, size_t blen, - bool is_eos) -{ - CURLcode result; - size_t consumed; - int flags; - - result = Curl_http_write_resp_hds(data, buf, blen, &consumed); - if(result || data->req.done) - goto out; - - DEBUGASSERT(consumed <= blen); - blen -= consumed; - buf += consumed; - /* either all was consumed in header parsing, or we have data left - * and are done with headers, e.g. it is BODY data */ - DEBUGASSERT(!blen || !data->req.header); - if(!data->req.header && (blen || is_eos)) { - /* BODY data after header been parsed, write and consume */ - flags = CLIENTWRITE_BODY; - if(is_eos) - flags |= CLIENTWRITE_EOS; - result = Curl_client_write(data, flags, buf, blen); - } -out: - return result; -} - -/* Decode HTTP status code string. */ -CURLcode Curl_http_decode_status(int *pstatus, const char *s, size_t len) -{ - CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; - int status = 0; - int i; - - if(len != 3) - goto out; - - for(i = 0; i < 3; ++i) { - char c = s[i]; - - if(c < '0' || c > '9') - goto out; - - status *= 10; - status += c - '0'; - } - result = CURLE_OK; -out: - *pstatus = result ? -1 : status; - return result; -} - -CURLcode Curl_http_req_make(struct httpreq **preq, - const char *method, size_t m_len, - const char *scheme, size_t s_len, - const char *authority, size_t a_len, - const char *path, size_t p_len) -{ - struct httpreq *req; - CURLcode result = CURLE_OUT_OF_MEMORY; - - DEBUGASSERT(method && m_len); - - req = curlx_calloc(1, sizeof(*req) + m_len); - if(!req) - goto out; -#if defined(__GNUC__) && __GNUC__ >= 13 -#pragma GCC diagnostic push -/* error: 'memcpy' offset [137, 142] from the object at 'req' is out of - the bounds of referenced subobject 'method' with type 'char[1]' at - offset 136 */ -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - memcpy(req->method, method, m_len); -#if defined(__GNUC__) && __GNUC__ >= 13 -#pragma GCC diagnostic pop -#endif - if(scheme) { - req->scheme = curlx_memdup0(scheme, s_len); - if(!req->scheme) - goto out; - } - if(authority) { - req->authority = curlx_memdup0(authority, a_len); - if(!req->authority) - goto out; - } - if(path) { - req->path = curlx_memdup0(path, p_len); - if(!req->path) - goto out; - } - Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST); - Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST); - result = CURLE_OK; - -out: - if(result && req) - Curl_http_req_free(req); - *preq = result ? NULL : req; - return result; -} - -static CURLcode req_assign_url_authority(struct httpreq *req, CURLU *url) -{ - char *host, *port; - struct dynbuf buf; - CURLUcode uc; - CURLcode result = CURLE_URL_MALFORMAT; - - host = port = NULL; - curlx_dyn_init(&buf, DYN_HTTP_REQUEST); - - uc = curl_url_get(url, CURLUPART_HOST, &host, 0); - if(uc && uc != CURLUE_NO_HOST) - goto out; - if(!host) { - req->authority = NULL; - result = CURLE_OK; - goto out; - } - - uc = curl_url_get(url, CURLUPART_PORT, &port, CURLU_NO_DEFAULT_PORT); - if(uc && uc != CURLUE_NO_PORT) - goto out; - - result = curlx_dyn_add(&buf, host); - if(result) - goto out; - if(port) { - result = curlx_dyn_addf(&buf, ":%s", port); - if(result) - goto out; - } - req->authority = curlx_dyn_ptr(&buf); -out: - curlx_free(host); - curlx_free(port); - if(result) - curlx_dyn_free(&buf); - return result; -} - -static CURLcode req_assign_url_path(struct httpreq *req, CURLU *url) -{ - char *path, *query; - struct dynbuf buf; - CURLUcode uc; - CURLcode result = CURLE_URL_MALFORMAT; - - path = query = NULL; - curlx_dyn_init(&buf, DYN_HTTP_REQUEST); - - uc = curl_url_get(url, CURLUPART_PATH, &path, 0); - if(uc) - goto out; - uc = curl_url_get(url, CURLUPART_QUERY, &query, 0); - if(uc && uc != CURLUE_NO_QUERY) - goto out; - - if(!query) { - req->path = path; - path = NULL; - } - else { - result = curlx_dyn_add(&buf, path); - if(!result) - result = curlx_dyn_addf(&buf, "?%s", query); - if(result) - goto out; - req->path = curlx_dyn_ptr(&buf); - } - result = CURLE_OK; - -out: - curlx_free(path); - curlx_free(query); - if(result) - curlx_dyn_free(&buf); - return result; -} - -CURLcode Curl_http_req_make2(struct httpreq **preq, - const char *method, size_t m_len, - CURLU *url, const char *scheme_default) -{ - struct httpreq *req; - CURLcode result = CURLE_OUT_OF_MEMORY; - CURLUcode uc; - - DEBUGASSERT(method && m_len); - - req = curlx_calloc(1, sizeof(*req) + m_len); - if(!req) - goto out; - memcpy(req->method, method, m_len); - - uc = curl_url_get(url, CURLUPART_SCHEME, &req->scheme, 0); - if(uc && uc != CURLUE_NO_SCHEME) - goto out; - if(!req->scheme && scheme_default) { - req->scheme = curlx_strdup(scheme_default); - if(!req->scheme) - goto out; - } - - result = req_assign_url_authority(req, url); - if(result) - goto out; - result = req_assign_url_path(req, url); - if(result) - goto out; - - Curl_dynhds_init(&req->headers, 0, DYN_HTTP_REQUEST); - Curl_dynhds_init(&req->trailers, 0, DYN_HTTP_REQUEST); - result = CURLE_OK; - -out: - if(result && req) - Curl_http_req_free(req); - *preq = result ? NULL : req; - return result; -} - -void Curl_http_req_free(struct httpreq *req) -{ - if(req) { - curlx_free(req->scheme); - curlx_free(req->authority); - curlx_free(req->path); - Curl_dynhds_free(&req->headers); - Curl_dynhds_free(&req->trailers); - curlx_free(req); - } -} - -struct name_const { - const char *name; - size_t namelen; -}; - -/* keep them sorted by length! */ -static const struct name_const H2_NON_FIELD[] = { - { STRCONST("Host") }, - { STRCONST("Upgrade") }, - { STRCONST("Connection") }, - { STRCONST("Keep-Alive") }, - { STRCONST("Proxy-Connection") }, - { STRCONST("Transfer-Encoding") }, -}; - -static bool h2_permissible_field(struct dynhds_entry *e) -{ - size_t i; - for(i = 0; i < CURL_ARRAYSIZE(H2_NON_FIELD); ++i) { - if(e->namelen < H2_NON_FIELD[i].namelen) - return TRUE; - if(e->namelen == H2_NON_FIELD[i].namelen && - curl_strequal(H2_NON_FIELD[i].name, e->name)) - return FALSE; - } - return TRUE; -} - -static bool http_TE_has_token(const char *fvalue, const char *token) -{ - while(*fvalue) { - struct Curl_str name; - - /* skip to first token */ - while(ISBLANK(*fvalue) || *fvalue == ',') - fvalue++; - if(curlx_str_cspn(&fvalue, &name, " \t\r;,")) - return FALSE; - if(curlx_str_casecompare(&name, token)) - return TRUE; - - /* skip any remainder after token, e.g. parameters with quoted strings */ - while(*fvalue && *fvalue != ',') { - if(*fvalue == '"') { - struct Curl_str qw; - /* if we do not cleanly find a quoted word here, the header value - * does not follow HTTP syntax and we reject */ - if(curlx_str_quotedword(&fvalue, &qw, CURL_MAX_HTTP_HEADER)) - return FALSE; - } - else - fvalue++; - } - } - return FALSE; -} - -CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, - struct httpreq *req, struct Curl_easy *data) -{ - const char *scheme = NULL, *authority = NULL; - struct dynhds_entry *e; - size_t i; - CURLcode result; - - DEBUGASSERT(req); - DEBUGASSERT(h2_headers); - - if(req->scheme) { - scheme = req->scheme; - } - else if(strcmp("CONNECT", req->method)) { - scheme = Curl_checkheaders(data, STRCONST(HTTP_PSEUDO_SCHEME)); - if(scheme) { - scheme += sizeof(HTTP_PSEUDO_SCHEME); - curlx_str_passblanks(&scheme); - infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme); - } - else { - scheme = Curl_xfer_is_secure(data) ? "https" : "http"; - } - } - - if(req->authority) { - authority = req->authority; - } - else { - e = Curl_dynhds_get(&req->headers, STRCONST("Host")); - if(e) - authority = e->value; - } - - Curl_dynhds_reset(h2_headers); - Curl_dynhds_set_opts(h2_headers, DYNHDS_OPT_LOWERCASE); - result = Curl_dynhds_add(h2_headers, STRCONST(HTTP_PSEUDO_METHOD), - req->method, strlen(req->method)); - if(!result && scheme) { - result = Curl_dynhds_add(h2_headers, STRCONST(HTTP_PSEUDO_SCHEME), - scheme, strlen(scheme)); - } - if(!result && authority) { - result = Curl_dynhds_add(h2_headers, STRCONST(HTTP_PSEUDO_AUTHORITY), - authority, strlen(authority)); - } - if(!result && req->path) { - result = Curl_dynhds_add(h2_headers, STRCONST(HTTP_PSEUDO_PATH), - req->path, strlen(req->path)); - } - for(i = 0; !result && i < Curl_dynhds_count(&req->headers); ++i) { - e = Curl_dynhds_getn(&req->headers, i); - /* "TE" is special in that it is only permissible when it - * has only value "trailers". RFC 9113 ch. 8.2.2 */ - if(e->namelen == 2 && curl_strequal("TE", e->name)) { - if(http_TE_has_token(e->value, "trailers")) - result = Curl_dynhds_add(h2_headers, e->name, e->namelen, - "trailers", sizeof("trailers") - 1); - } - else if(h2_permissible_field(e)) { - result = Curl_dynhds_add(h2_headers, e->name, e->namelen, - e->value, e->valuelen); - } - } - - return result; -} - -CURLcode Curl_http_resp_make(struct http_resp **presp, - int status, - const char *description) -{ - struct http_resp *resp; - CURLcode result = CURLE_OUT_OF_MEMORY; - - resp = curlx_calloc(1, sizeof(*resp)); - if(!resp) - goto out; - - resp->status = status; - if(description) { - resp->description = curlx_strdup(description); - if(!resp->description) - goto out; - } - Curl_dynhds_init(&resp->headers, 0, DYN_HTTP_REQUEST); - Curl_dynhds_init(&resp->trailers, 0, DYN_HTTP_REQUEST); - result = CURLE_OK; - -out: - if(result && resp) - Curl_http_resp_free(resp); - *presp = result ? NULL : resp; - return result; -} - -void Curl_http_resp_free(struct http_resp *resp) -{ - if(resp) { - curlx_free(resp->description); - Curl_dynhds_free(&resp->headers); - Curl_dynhds_free(&resp->trailers); - if(resp->prev) - Curl_http_resp_free(resp->prev); - curlx_free(resp); - } -} - -/* - * HTTP handler interface. - */ -const struct Curl_protocol Curl_protocol_http = { - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - Curl_http_doing_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - Curl_http_perform_pollset, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - Curl_http_write_resp, /* write_resp */ - Curl_http_write_resp_hd, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - Curl_http_follow, /* follow */ -}; - -#endif /* CURL_DISABLE_HTTP */ diff --git a/vendor/curl/lib/http.h b/vendor/curl/lib/http.h deleted file mode 100644 index 6e33c00e9..000000000 --- a/vendor/curl/lib/http.h +++ /dev/null @@ -1,271 +0,0 @@ -#ifndef HEADER_CURL_HTTP_H -#define HEADER_CURL_HTTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "bufq.h" -#include "dynhds.h" - -typedef enum { - HTTPREQ_GET, - HTTPREQ_POST, - HTTPREQ_POST_FORM, /* we make a difference internally */ - HTTPREQ_POST_MIME, /* we make a difference internally */ - HTTPREQ_PUT, - HTTPREQ_HEAD -} Curl_HttpReq; - -#define CURL_HTTP_V1x (1 << 0) -#define CURL_HTTP_V2x (1 << 1) -#define CURL_HTTP_V3x (1 << 2) -/* bitmask of CURL_HTTP_V* values */ -typedef unsigned char http_majors; - -#ifndef CURL_DISABLE_HTTP - -extern const struct Curl_protocol Curl_protocol_http; - -struct dynhds; - -struct http_negotiation { - unsigned char rcvd_min; /* minimum version seen in responses, 09, 10, 11 */ - http_majors wanted; /* wanted major versions when talking to server */ - http_majors allowed; /* allowed major versions when talking to server */ - http_majors preferred; /* preferred major version when talking to server */ - BIT(h2_upgrade); /* Do HTTP Upgrade from 1.1 to 2 */ - BIT(h2_prior_knowledge); /* Directly do HTTP/2 without ALPN/SSL */ - BIT(accept_09); /* Accept an HTTP/0.9 response */ - BIT(only_10); /* When using major version 1x, use only 1.0 */ -}; - -void Curl_http_neg_init(struct Curl_easy *data, struct http_negotiation *neg); - -CURLcode Curl_bump_headersize(struct Curl_easy *data, - size_t delta, - bool connect_only); - -/* Header specific functions */ -bool Curl_compareheader(const char *headerline, /* line to check */ - const char *header, /* header keyword _with_ colon */ - const size_t hlen, /* len of the keyword in bytes */ - const char *content, /* content string to find */ - const size_t clen); /* len of the content in bytes */ - -char *Curl_copy_header_value(const char *header); - -char *Curl_checkProxyheaders(struct Curl_easy *data, - const struct connectdata *conn, - const char *thisheader, - const size_t thislen); - -CURLcode Curl_add_timecondition(struct Curl_easy *data, struct dynbuf *req); -CURLcode Curl_add_custom_headers(struct Curl_easy *data, bool is_connect, - int httpversion, struct dynbuf *req); -CURLcode Curl_dynhds_add_custom(struct Curl_easy *data, bool is_connect, - struct dynhds *hds); - -void Curl_http_to_fold(struct dynbuf *bf); - -void Curl_http_method(struct Curl_easy *data, - const char **method, Curl_HttpReq *reqp); - -/* protocol-specific functions set up to be called by the main engine */ -CURLcode Curl_http_setup_conn(struct Curl_easy *data, - struct connectdata *conn); -CURLcode Curl_http(struct Curl_easy *data, bool *done); -CURLcode Curl_http_done(struct Curl_easy *data, - CURLcode status, bool premature); -CURLcode Curl_http_doing_pollset(struct Curl_easy *data, - struct easy_pollset *ps); -CURLcode Curl_http_perform_pollset(struct Curl_easy *data, - struct easy_pollset *ps); -CURLcode Curl_http_write_resp(struct Curl_easy *data, - const char *buf, size_t blen, - bool is_eos); -CURLcode Curl_http_write_resp_hd(struct Curl_easy *data, - const char *hd, size_t hdlen, - bool is_eos); - -/* These functions are in http.c */ -CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, - const char *auth); - -CURLcode Curl_http_auth_act(struct Curl_easy *data); - -/* follow a redirect or not */ -CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl, - followtype type); - -/* If only the PICKNONE bit is set, there has been a round-trip and we - selected to use no auth at all. Ie, we actively select no auth, as opposed - to not having one selected. The other CURLAUTH_* defines are present in the - public curl/curl.h header. */ -#define CURLAUTH_PICKNONE (1 << 30) /* do not use auth */ - -/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST - data get included in the initial data chunk sent to the server. If the - data is larger than this, it will automatically get split up in multiple - system calls. - - This value used to be fairly big (100K), but we must take into account that - if the server rejects the POST due for authentication reasons, this data - will always be unconditionally sent and thus it may not be larger than can - always be afforded to send twice. - - It must not be greater than 64K to work on VMS. -*/ -#ifndef MAX_INITIAL_POST_SIZE -#define MAX_INITIAL_POST_SIZE (64 * 1024) -#endif - -/* EXPECT_100_THRESHOLD is the request body size limit for when libcurl will - * automatically add an "Expect: 100-continue" header in HTTP requests. When - * the size is unknown, it will always add it. - * - */ -#ifndef EXPECT_100_THRESHOLD -#define EXPECT_100_THRESHOLD (1024 * 1024) -#endif - -/* MAX_HTTP_RESP_HEADER_SIZE is the maximum size of all response headers - combined that libcurl allows for a single HTTP response, any HTTP - version. This count includes CONNECT response headers. */ -#define MAX_HTTP_RESP_HEADER_SIZE (300 * 1024) - -/* MAX_HTTP_RESP_HEADER_COUNT is the maximum number of response headers that - libcurl allows for a single HTTP response, including CONNECT and - redirects. */ -#define MAX_HTTP_RESP_HEADER_COUNT 5000 - -#endif /* CURL_DISABLE_HTTP */ - -/**************************************************************************** - * HTTP unique setup - ***************************************************************************/ - -CURLcode Curl_http_write_resp_hds(struct Curl_easy *data, - const char *buf, size_t blen, - size_t *pconsumed); - -/** - * Curl_http_output_auth() setups the authentication headers for the - * host/proxy and the correct authentication - * method. data->state.authdone is set to TRUE when authentication is - * done. - * - * @param data all information about the current transfer - * @param conn all information about the current connection - * @param request pointer to the request keyword - * @param httpreq is the request type - * @param path pointer to the requested path - * @param proxytunnel boolean if this is the request setting up a "proxy - * tunnel" - * - * @returns CURLcode - */ -CURLcode Curl_http_output_auth(struct Curl_easy *data, - struct connectdata *conn, - const char *request, - Curl_HttpReq httpreq, - const char *path, - bool proxytunnel); /* TRUE if this is - the request setting up - the proxy tunnel */ - -/* Decode HTTP status code string. */ -CURLcode Curl_http_decode_status(int *pstatus, const char *s, size_t len); - -/** - * All about a core HTTP request, excluding body and trailers - */ -struct httpreq { - struct dynhds headers; - struct dynhds trailers; - char *scheme; - char *authority; - char *path; - char method[1]; -}; - -/** - * Create an HTTP request struct. - */ -CURLcode Curl_http_req_make(struct httpreq **preq, - const char *method, size_t m_len, - const char *scheme, size_t s_len, - const char *authority, size_t a_len, - const char *path, size_t p_len); - -CURLcode Curl_http_req_make2(struct httpreq **preq, - const char *method, size_t m_len, - CURLU *url, const char *scheme_default); - -void Curl_http_req_free(struct httpreq *req); - -#define HTTP_PSEUDO_METHOD ":method" -#define HTTP_PSEUDO_SCHEME ":scheme" -#define HTTP_PSEUDO_AUTHORITY ":authority" -#define HTTP_PSEUDO_PATH ":path" -#define HTTP_PSEUDO_STATUS ":status" - -/** - * Create the list of HTTP/2 headers which represent the request, - * using HTTP/2 pseudo headers preceding the `req->headers`. - * - * Applies the following transformations: - * - if `authority` is set, any "Host" header is removed. - * - if `authority` is unset and a "Host" header is present, use - * that as `authority` and remove "Host" - * - removes and Connection header fields as defined in rfc9113 ch. 8.2.2 - * - lower-cases the header field names - * - * @param h2_headers will contain the HTTP/2 headers on success - * @param req the request to transform - * @param data the handle to lookup defaults like ' :scheme' from - */ -CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, - struct httpreq *req, struct Curl_easy *data); - -/** - * All about a core HTTP response, excluding body and trailers - */ -struct http_resp { - int status; - char *description; - struct dynhds headers; - struct dynhds trailers; - struct http_resp *prev; -}; - -/** - * Create an HTTP response struct. - */ -CURLcode Curl_http_resp_make(struct http_resp **presp, - int status, - const char *description); - -void Curl_http_resp_free(struct http_resp *resp); - -#endif /* HEADER_CURL_HTTP_H */ diff --git a/vendor/curl/lib/http1.c b/vendor/curl/lib/http1.c deleted file mode 100644 index 60ad32ce8..000000000 --- a/vendor/curl/lib/http1.c +++ /dev/null @@ -1,347 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -#include "urldata.h" -#include "http.h" -#include "http1.h" -#include "urlapi-int.h" - - -#define H1_MAX_URL_LEN (8 * 1024) - -void Curl_h1_req_parse_init(struct h1_req_parser *parser, size_t max_line_len) -{ - memset(parser, 0, sizeof(*parser)); - parser->max_line_len = max_line_len; - curlx_dyn_init(&parser->scratch, max_line_len); -} - -void Curl_h1_req_parse_free(struct h1_req_parser *parser) -{ - if(parser) { - Curl_http_req_free(parser->req); - curlx_dyn_free(&parser->scratch); - parser->req = NULL; - parser->done = FALSE; - } -} - -static CURLcode trim_line(struct h1_req_parser *parser, int options) -{ - DEBUGASSERT(parser->line); - if(parser->line_len) { - if(parser->line[parser->line_len - 1] == '\n') - --parser->line_len; - if(parser->line_len) { - if(parser->line[parser->line_len - 1] == '\r') - --parser->line_len; - else if(options & H1_PARSE_OPT_STRICT) - return CURLE_URL_MALFORMAT; - } - else if(options & H1_PARSE_OPT_STRICT) - return CURLE_URL_MALFORMAT; - } - else if(options & H1_PARSE_OPT_STRICT) - return CURLE_URL_MALFORMAT; - - if(parser->line_len > parser->max_line_len) { - return CURLE_URL_MALFORMAT; - } - return CURLE_OK; -} - -static CURLcode detect_line(struct h1_req_parser *parser, - const uint8_t *buf, const size_t buflen, - size_t *pnread) -{ - const char *line_end; - - DEBUGASSERT(!parser->line); - *pnread = 0; - line_end = memchr(buf, '\n', buflen); - if(!line_end) - return CURLE_AGAIN; - parser->line = (const char *)buf; - parser->line_len = line_end - parser->line + 1; - *pnread = parser->line_len; - return CURLE_OK; -} - -static CURLcode next_line(struct h1_req_parser *parser, - const uint8_t *buf, const size_t buflen, int options, - size_t *pnread) -{ - CURLcode result; - - *pnread = 0; - if(parser->line) { - parser->line = NULL; - parser->line_len = 0; - curlx_dyn_reset(&parser->scratch); - } - - result = detect_line(parser, buf, buflen, pnread); - if(!result) { - if(curlx_dyn_len(&parser->scratch)) { - /* append detected line to scratch to have the complete line */ - result = curlx_dyn_addn(&parser->scratch, parser->line, - parser->line_len); - if(result) - return result; - parser->line = curlx_dyn_ptr(&parser->scratch); - parser->line_len = curlx_dyn_len(&parser->scratch); - } - result = trim_line(parser, options); - if(result) - return result; - } - else if(result == CURLE_AGAIN) { - /* no line end in `buf`, add it to our scratch */ - result = curlx_dyn_addn(&parser->scratch, (const unsigned char *)buf, - buflen); - *pnread = buflen; - } - return result; -} - -static CURLcode start_req(struct h1_req_parser *parser, - const char *scheme_default, - const char *custom_method, - int options) -{ - const char *p, *m, *target, *hv, *scheme, *authority, *path; - size_t m_len, target_len, hv_len, scheme_len, authority_len, path_len; - size_t i; - CURLU *url = NULL; - CURLcode result = CURLE_URL_MALFORMAT; /* Use this as default fail */ - - DEBUGASSERT(!parser->req); - /* line must match: "METHOD TARGET HTTP_VERSION" */ - if(custom_method && custom_method[0] && - !strncmp(custom_method, parser->line, strlen(custom_method))) { - p = parser->line + strlen(custom_method); - } - else { - p = memchr(parser->line, ' ', parser->line_len); - if(!p || p == parser->line) - goto out; - } - - m = parser->line; - m_len = p - parser->line; - target = p + 1; - target_len = hv_len = 0; - hv = NULL; - - /* URL may contain spaces so scan backwards */ - for(i = parser->line_len; i > m_len; --i) { - if(parser->line[i] == ' ') { - hv = &parser->line[i + 1]; - hv_len = parser->line_len - i; - target_len = (hv - target) - 1; - break; - } - } - /* no SPACE found or empty TARGET or empty HTTP_VERSION */ - if(!target_len || !hv_len) - goto out; - - (void)hv; - - /* The TARGET can be (rfc 9112, ch. 3.2): - * origin-form: path + optional query - * absolute-form: absolute URI - * authority-form: host+port for CONNECT - * asterisk-form: '*' for OPTIONS - * - * from TARGET, we derive `scheme` `authority` `path` - * origin-form -- -- TARGET - * absolute-form URL* URL* URL* - * authority-form -- TARGET -- - * asterisk-form -- -- TARGET - */ - scheme = authority = path = NULL; - scheme_len = authority_len = path_len = 0; - - if(target_len == 1 && target[0] == '*') { - /* asterisk-form */ - path = target; - path_len = target_len; - } - else if(!strncmp("CONNECT", m, m_len)) { - /* authority-form */ - authority = target; - authority_len = target_len; - } - else if(target[0] == '/') { - /* origin-form */ - path = target; - path_len = target_len; - } - else { - /* origin-form OR absolute-form */ - CURLUcode uc; - char tmp[H1_MAX_URL_LEN]; - - /* default, unless we see an absolute URL */ - path = target; - path_len = target_len; - - /* URL parser wants null-termination */ - if(target_len >= sizeof(tmp)) - goto out; - memcpy(tmp, target, target_len); - tmp[target_len] = '\0'; - /* See if treating TARGET as an absolute URL makes sense */ - if(Curl_is_absolute_url(tmp, NULL, 0, FALSE)) { - unsigned int url_options; - - url = curl_url(); - if(!url) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - url_options = (CURLU_NON_SUPPORT_SCHEME | - CURLU_PATH_AS_IS | - CURLU_NO_DEFAULT_PORT); - if(!(options & H1_PARSE_OPT_STRICT)) - url_options |= CURLU_ALLOW_SPACE; - uc = curl_url_set(url, CURLUPART_URL, tmp, url_options); - if(uc) { - goto out; - } - } - - if(!url && (options & H1_PARSE_OPT_STRICT)) { - /* we should have an absolute URL or have seen `/` earlier */ - goto out; - } - } - - if(url) { - result = Curl_http_req_make2(&parser->req, m, m_len, url, scheme_default); - } - else { - if(!scheme && scheme_default) { - scheme = scheme_default; - scheme_len = strlen(scheme_default); - } - result = Curl_http_req_make(&parser->req, m, m_len, scheme, scheme_len, - authority, authority_len, path, path_len); - } - -out: - curl_url_cleanup(url); - return result; -} - -CURLcode Curl_h1_req_parse_read(struct h1_req_parser *parser, - const uint8_t *buf, size_t buflen, - const char *scheme_default, - const char *custom_method, - int options, size_t *pnread) -{ - CURLcode result = CURLE_OK; - size_t nread; - - *pnread = 0; - - DEBUGASSERT(buf); - if(!buf) - return CURLE_BAD_FUNCTION_ARGUMENT; - - while(!parser->done) { - result = next_line(parser, buf, buflen, options, &nread); - if(result) { - if(result == CURLE_AGAIN) - result = CURLE_OK; - goto out; - } - - /* Consume this line */ - *pnread += nread; - buf += nread; - buflen -= nread; - - if(!parser->line) { - /* consumed bytes, but line not complete */ - if(!buflen) - goto out; - } - else if(!parser->req) { - result = start_req(parser, scheme_default, custom_method, options); - if(result) - goto out; - } - else if(parser->line_len == 0) { - /* last, empty line, we are finished */ - if(!parser->req) { - result = CURLE_URL_MALFORMAT; - goto out; - } - parser->done = TRUE; - curlx_dyn_reset(&parser->scratch); - /* last chance adjustments */ - } - else { - result = Curl_dynhds_h1_add_line(&parser->req->headers, - parser->line, parser->line_len); - if(result) - goto out; - } - } - -out: - return result; -} - -CURLcode Curl_h1_req_write_head(struct httpreq *req, int http_minor, - struct dynbuf *dbuf) -{ - CURLcode result; - - result = curlx_dyn_addf(dbuf, "%s %s%s%s%s HTTP/1.%d\r\n", - req->method, - req->scheme ? req->scheme : "", - req->scheme ? "://" : "", - req->authority ? req->authority : "", - req->path ? req->path : "", - http_minor); - if(result) - goto out; - - result = Curl_dynhds_h1_dprint(&req->headers, dbuf); - if(result) - goto out; - - result = curlx_dyn_addn(dbuf, STRCONST("\r\n")); - -out: - return result; -} - -#endif /* !CURL_DISABLE_HTTP */ diff --git a/vendor/curl/lib/http1.h b/vendor/curl/lib/http1.h deleted file mode 100644 index c2894613d..000000000 --- a/vendor/curl/lib/http1.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef HEADER_CURL_HTTP1_H -#define HEADER_CURL_HTTP1_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP -#include "bufq.h" -#include "http.h" - -#define H1_PARSE_OPT_NONE 0 -#define H1_PARSE_OPT_STRICT (1 << 0) - -#define H1_PARSE_DEFAULT_MAX_LINE_LEN DYN_HTTP_REQUEST - -struct h1_req_parser { - struct httpreq *req; - struct dynbuf scratch; - size_t scratch_skip; - const char *line; - size_t max_line_len; - size_t line_len; - BIT(done); -}; - -void Curl_h1_req_parse_init(struct h1_req_parser *parser, size_t max_line_len); -void Curl_h1_req_parse_free(struct h1_req_parser *parser); - -CURLcode Curl_h1_req_parse_read(struct h1_req_parser *parser, - const uint8_t *buf, size_t buflen, - const char *scheme_default, - const char *custom_method, - int options, size_t *pnread); - -CURLcode Curl_h1_req_dprint(const struct httpreq *req, - struct dynbuf *dbuf); - -CURLcode Curl_h1_req_write_head(struct httpreq *req, int http_minor, - struct dynbuf *dbuf); - -#endif /* !CURL_DISABLE_HTTP */ -#endif /* HEADER_CURL_HTTP1_H */ diff --git a/vendor/curl/lib/http2.c b/vendor/curl/lib/http2.c deleted file mode 100644 index 7be5abdd3..000000000 --- a/vendor/curl/lib/http2.c +++ /dev/null @@ -1,3029 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) -#include - -#include "urldata.h" -#include "bufq.h" -#include "uint-hash.h" -#include "http1.h" -#include "http2.h" -#include "http.h" -#include "sendf.h" -#include "curl_trc.h" -#include "select.h" -#include "curlx/base64.h" -#include "multiif.h" -#include "progress.h" -#include "url.h" -#include "urlapi-int.h" -#include "cfilters.h" -#include "connect.h" -#include "transfer.h" -#include "bufref.h" -#include "curlx/dynbuf.h" -#include "headers.h" - -#if (NGHTTP2_VERSION_NUM < 0x010c00) -#error too old nghttp2 version, upgrade! -#endif - -#if (NGHTTP2_VERSION_NUM >= 0x010c00) -#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1 -#endif - - -/* buffer dimensioning: - * use 16K as chunk size, as that fits H2 DATA frames well */ -#define H2_CHUNK_SIZE (16 * 1024) -/* connection window size */ -#define H2_CONN_WINDOW_SIZE (10 * 1024 * 1024) -/* on receiving from TLS, we prep for holding a full stream window */ -#define H2_NW_RECV_CHUNKS (H2_CONN_WINDOW_SIZE / H2_CHUNK_SIZE) -/* on send into TLS, we want to accumulate small frames */ -#define H2_NW_SEND_CHUNKS 1 -/* this is how much we want "in flight" for a stream, unthrottled */ -#define H2_STREAM_WINDOW_SIZE_MAX (10 * 1024 * 1024) -/* this is how much we want "in flight" for a stream, initially, IFF - * nghttp2 allows us to tweak the local window size. */ -#if NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE -#define H2_STREAM_WINDOW_SIZE_INITIAL (64 * 1024) -#else -#define H2_STREAM_WINDOW_SIZE_INITIAL H2_STREAM_WINDOW_SIZE_MAX -#endif -/* keep smaller stream upload buffer (default h2 window size) to have - * our progress bars and "upload done" reporting closer to reality */ -#define H2_STREAM_SEND_CHUNKS ((64 * 1024) / H2_CHUNK_SIZE) -/* spare chunks we keep for a full window */ -#define H2_STREAM_POOL_SPARES (H2_CONN_WINDOW_SIZE / H2_CHUNK_SIZE) - -/* We need to accommodate the max number of streams with their window sizes on - * the overall connection. Streams might become PAUSED which will block their - * received QUOTA in the connection window. If we run out of space, the server - * is blocked from sending us any data. See #10988 for an issue with this. */ -#define HTTP2_HUGE_WINDOW_SIZE (100 * H2_STREAM_WINDOW_SIZE_MAX) - -#define H2_SETTINGS_IV_LEN 3 -#define H2_BINSETTINGS_LEN 80 - -struct cf_h2_ctx { - nghttp2_session *h2; - /* The easy handle used in the current filter call, cleared at return */ - struct cf_call_data call_data; - - struct bufq inbufq; /* network input */ - struct bufq outbufq; /* network output */ - struct bufc_pool stream_bufcp; /* spares for stream buffers */ - struct dynbuf scratch; /* scratch buffer for temp use */ - - struct uint_hash streams; /* hash of `data->mid` to `h2_stream_ctx` */ - size_t drain_total; /* sum of all stream's UrlState drain */ - uint32_t initial_win_size; /* current initial window size (settings) */ - uint32_t max_concurrent_streams; - uint32_t goaway_error; /* goaway error code from server */ - int32_t remote_max_sid; /* max id processed by server */ - int32_t local_max_sid; /* max id processed by us */ - BIT(initialized); - BIT(via_h1_upgrade); - BIT(conn_closed); - BIT(rcvd_goaway); - BIT(sent_goaway); - BIT(enable_push); - BIT(nw_out_blocked); -}; - -/* How to access `call_data` from a cf_h2 filter */ -#undef CF_CTX_CALL_DATA -#define CF_CTX_CALL_DATA(cf) ((struct cf_h2_ctx *)(cf)->ctx)->call_data - -/** - * All about the H2 internals of a stream - */ -struct h2_stream_ctx { - struct bufq sendbuf; /* request buffer */ - struct h1_req_parser h1; /* parsing the request */ - struct dynhds resp_trailers; /* response trailer fields */ - size_t resp_hds_len; /* amount of response header bytes in recvbuf */ - curl_off_t nrcvd_data; /* number of DATA bytes received */ - - char **push_headers; /* allocated array */ - size_t push_headers_used; /* number of entries filled in */ - size_t push_headers_alloc; /* number of entries allocated */ - - int status_code; /* HTTP response status code */ - uint32_t error; /* stream error code */ - CURLcode xfer_result; /* Result of writing out response */ - int32_t local_window_size; /* the local recv window size */ - int32_t id; /* HTTP/2 protocol identifier for stream */ - BIT(resp_hds_complete); /* we have a complete, final response */ - BIT(closed); /* TRUE on stream close */ - BIT(reset); /* TRUE on stream reset */ - BIT(reset_by_server); /* TRUE on stream reset by server */ - BIT(close_handled); /* TRUE if stream closure is handled by libcurl */ - BIT(bodystarted); - BIT(body_eos); /* the complete body has been added to `sendbuf` and - * is being/has been processed from there. */ - BIT(write_paused); /* stream write is paused */ -}; - -static void free_push_headers(struct h2_stream_ctx *stream) -{ - size_t i; - for(i = 0; i < stream->push_headers_used; i++) - curlx_free(stream->push_headers[i]); - curlx_safefree(stream->push_headers); - stream->push_headers_used = 0; -} - -static void h2_stream_ctx_free(struct h2_stream_ctx *stream) -{ - Curl_bufq_free(&stream->sendbuf); - Curl_h1_req_parse_free(&stream->h1); - Curl_dynhds_free(&stream->resp_trailers); - free_push_headers(stream); - curlx_free(stream); -} - -static void h2_stream_hash_free(unsigned int id, void *stream) -{ - (void)id; - DEBUGASSERT(stream); - h2_stream_ctx_free((struct h2_stream_ctx *)stream); -} - -static void cf_h2_ctx_init(struct cf_h2_ctx *ctx, bool via_h1_upgrade) -{ - Curl_bufcp_init(&ctx->stream_bufcp, H2_CHUNK_SIZE, H2_STREAM_POOL_SPARES); - Curl_bufq_initp(&ctx->inbufq, &ctx->stream_bufcp, H2_NW_RECV_CHUNKS, 0); - Curl_bufq_initp(&ctx->outbufq, &ctx->stream_bufcp, H2_NW_SEND_CHUNKS, 0); - curlx_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER); - Curl_uint32_hash_init(&ctx->streams, 63, h2_stream_hash_free); - ctx->remote_max_sid = 2147483647; - ctx->via_h1_upgrade = via_h1_upgrade; - ctx->initialized = TRUE; -} - -static void cf_h2_ctx_free(struct cf_h2_ctx *ctx) -{ - if(ctx && ctx->initialized) { - Curl_bufq_free(&ctx->inbufq); - Curl_bufq_free(&ctx->outbufq); - Curl_bufcp_free(&ctx->stream_bufcp); - curlx_dyn_free(&ctx->scratch); - Curl_uint32_hash_destroy(&ctx->streams); - memset(ctx, 0, sizeof(*ctx)); - } - curlx_free(ctx); -} - -static void cf_h2_ctx_close(struct cf_h2_ctx *ctx) -{ - if(ctx->h2) { - nghttp2_session_del(ctx->h2); - ctx->h2 = NULL; - } -} - -static uint32_t cf_h2_initial_win_size(struct Curl_easy *data) -{ -#if NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE - /* If the transfer has a rate-limit lower than the default initial - * stream window size, use that. It needs to be at least 8k or servers - * may be unhappy. */ - curl_off_t rps = Curl_rlimit_per_step(&data->progress.dl.rlimit); - if((rps > 0) && (rps < H2_STREAM_WINDOW_SIZE_INITIAL)) - return CURLMAX((uint32_t)rps, 8192); -#endif - return H2_STREAM_WINDOW_SIZE_INITIAL; -} - -static size_t populate_settings(nghttp2_settings_entry *iv, - struct Curl_easy *data, - struct cf_h2_ctx *ctx) -{ - iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; - iv[0].value = Curl_multi_max_concurrent_streams(data->multi); - - iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; - iv[1].value = cf_h2_initial_win_size(data); - if(ctx) - ctx->initial_win_size = iv[1].value; - iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; - iv[2].value = data->multi->push_cb != NULL; - - return 3; -} - -static ssize_t populate_binsettings(uint8_t *binsettings, - struct Curl_easy *data) -{ - nghttp2_settings_entry iv[H2_SETTINGS_IV_LEN]; - size_t ivlen; - - ivlen = populate_settings(iv, data, NULL); - /* this returns number of bytes it wrote or a negative number on error. */ - return nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN, - iv, ivlen); -} - -static CURLcode cf_h2_update_settings(struct cf_h2_ctx *ctx, - uint32_t initial_win_size) -{ - nghttp2_settings_entry entry; - entry.settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; - entry.value = initial_win_size; - if(nghttp2_submit_settings(ctx->h2, NGHTTP2_FLAG_NONE, &entry, 1)) - return CURLE_SEND_ERROR; - ctx->initial_win_size = initial_win_size; - return CURLE_OK; -} - -#define H2_STREAM_CTX(ctx, data) \ - ((struct h2_stream_ctx *)( \ - (data) ? Curl_uint32_hash_get(&(ctx)->streams, (data)->mid) : NULL)) - -static struct h2_stream_ctx *h2_stream_ctx_create(struct cf_h2_ctx *ctx) -{ - struct h2_stream_ctx *stream; - - (void)ctx; - stream = curlx_calloc(1, sizeof(*stream)); - if(!stream) - return NULL; - - stream->id = -1; - Curl_bufq_initp(&stream->sendbuf, &ctx->stream_bufcp, - H2_STREAM_SEND_CHUNKS, BUFQ_OPT_NONE); - Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN); - Curl_dynhds_init(&stream->resp_trailers, 0, DYN_HTTP_REQUEST); - stream->bodystarted = FALSE; - stream->status_code = -1; - stream->closed = FALSE; - stream->close_handled = FALSE; - stream->error = NGHTTP2_NO_ERROR; - stream->local_window_size = H2_STREAM_WINDOW_SIZE_INITIAL; - stream->nrcvd_data = 0; - return stream; -} - -#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE -static int32_t cf_h2_get_desired_local_win(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - curl_off_t avail = Curl_rlimit_avail(&data->progress.dl.rlimit, - Curl_pgrs_now(data)); - - (void)cf; - if(avail < CURL_OFF_T_MAX) { /* limit in place */ - if(avail <= 0) - return 0; - else if(avail < INT32_MAX) - return (int32_t)avail; - } - return H2_STREAM_WINDOW_SIZE_MAX; -} - -static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream) -{ - struct cf_h2_ctx *ctx = cf->ctx; - int32_t dwsize; - int rv; - - dwsize = (stream->write_paused || stream->xfer_result) ? - 0 : cf_h2_get_desired_local_win(cf, data); - if(dwsize != stream->local_window_size) { - int32_t wsize = nghttp2_session_get_stream_effective_local_window_size( - ctx->h2, stream->id); - if(dwsize > wsize) { - rv = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, dwsize); - if(rv) { - failf(data, "[%d] nghttp2 set_local_window_size(%d) failed: " - "%s(%d)", stream->id, dwsize, nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } - rv = nghttp2_submit_window_update(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, dwsize - wsize); - if(rv) { - failf(data, "[%d] nghttp2_submit_window_update() failed: " - "%s(%d)", stream->id, nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } - stream->local_window_size = dwsize; - CURL_TRC_CF(data, cf, "[%d] local window update by %d", - stream->id, dwsize - wsize); - } - else { - rv = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, dwsize); - if(rv) { - failf(data, "[%d] nghttp2_session_set_local_window_size() failed: " - "%s(%d)", stream->id, nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } - stream->local_window_size = dwsize; - CURL_TRC_CF(data, cf, "[%d] local window size now %d", - stream->id, dwsize); - } - } - return CURLE_OK; -} - -#else /* NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE */ - -static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream) -{ - (void)cf; - (void)data; - (void)stream; - return CURLE_OK; -} -#endif /* !NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE */ - -static CURLcode http2_data_setup(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx **pstream) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream; - - (void)cf; - DEBUGASSERT(data); - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - stream = H2_STREAM_CTX(ctx, data); - if(stream) { - *pstream = stream; - return CURLE_OK; - } - - stream = h2_stream_ctx_create(ctx); - if(!stream) - return CURLE_OUT_OF_MEMORY; - - if(!Curl_uint32_hash_set(&ctx->streams, data->mid, stream)) { - h2_stream_ctx_free(stream); - return CURLE_OUT_OF_MEMORY; - } - - *pstream = stream; - return CURLE_OK; -} - -static CURLcode nw_out_flush(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - size_t nwritten; - CURLcode result; - - if(Curl_bufq_is_empty(&ctx->outbufq)) - return CURLE_OK; - - result = Curl_cf_send_bufq(cf->next, data, &ctx->outbufq, NULL, 0, - &nwritten); - if(result) { - if(result == CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "flush nw send buffer(%zu) -> EAGAIN", - Curl_bufq_len(&ctx->outbufq)); - ctx->nw_out_blocked = 1; - } - return result; - } - return Curl_bufq_is_empty(&ctx->outbufq) ? CURLE_OK : CURLE_AGAIN; -} - -static void http2_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - - DEBUGASSERT(ctx); - if(!stream || !ctx->initialized) - return; - - if(ctx->h2) { - bool flush_egress = FALSE; - /* returns error if stream not known, which is fine here */ - (void)nghttp2_session_set_stream_user_data(ctx->h2, stream->id, NULL); - - if(!stream->closed && stream->id > 0) { - /* RST_STREAM */ - CURL_TRC_CF(data, cf, "[%d] premature DATA_DONE, RST stream", - stream->id); - stream->closed = TRUE; - stream->reset = TRUE; - nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, NGHTTP2_STREAM_CLOSED); - flush_egress = TRUE; - } - - if(flush_egress) { - (void)nghttp2_session_send(ctx->h2); - (void)nw_out_flush(cf, data); - } - } - - Curl_uint32_hash_remove(&ctx->streams, data->mid); -} - -static int h2_client_new(struct Curl_cfilter *cf, - nghttp2_session_callbacks *cbs) -{ - struct cf_h2_ctx *ctx = cf->ctx; - nghttp2_option *o; - nghttp2_mem mem = { NULL, Curl_nghttp2_malloc, Curl_nghttp2_free, - Curl_nghttp2_calloc, Curl_nghttp2_realloc }; - - int rc = nghttp2_option_new(&o); - if(rc) - return rc; - /* We handle window updates ourself to enforce buffer limits */ - nghttp2_option_set_no_auto_window_update(o, 1); -#if NGHTTP2_VERSION_NUM >= 0x013200 - /* with 1.50.0 */ - /* turn off RFC 9113 leading and trailing white spaces validation against - HTTP field value. */ - nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1); -#endif - rc = nghttp2_session_client_new3(&ctx->h2, cbs, cf, o, &mem); - nghttp2_option_del(o); - return rc; -} - -/* - * Returns nonzero if current HTTP/2 session should be closed. - */ -static int should_close_session(struct cf_h2_ctx *ctx) -{ - return ctx->drain_total == 0 && !nghttp2_session_want_read(ctx->h2) && - !nghttp2_session_want_write(ctx->h2); -} - -/* - * Processes pending input left in network input buffer. - * This function returns 0 if it succeeds, or -1 and error code will - * be assigned to *err. - */ -static CURLcode h2_process_pending_input(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - const unsigned char *buf; - size_t blen, nread; - ssize_t rv; - - while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) { - rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen); - if(!curlx_sztouz(rv, &nread)) { - failf(data, "nghttp2 recv error %zd: %s", rv, nghttp2_strerror((int)rv)); - return CURLE_HTTP2; - } - Curl_bufq_skip(&ctx->inbufq, nread); - if(Curl_bufq_is_empty(&ctx->inbufq)) { - break; - } - else { - CURL_TRC_CF(data, cf, "process_pending_input: %zu bytes left " - "in connection buffer", Curl_bufq_len(&ctx->inbufq)); - } - } - - if(nghttp2_session_check_request_allowed(ctx->h2) == 0) { - /* No more requests are allowed in the current session, so - the connection may not be reused. This is set when a - GOAWAY frame has been received or when the limit of stream - identifiers has been reached. */ - connclose(cf->conn, "http/2: No new requests allowed"); - } - - return CURLE_OK; -} - -/* - * The server may send us data at any point (e.g. PING frames). Therefore, we - * cannot assume that an HTTP/2 socket is dead because it is readable. - * - * Check the lower filters first and, if successful, peek at the socket - * and distinguish between closed and data. - */ -static bool http2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data, - bool *input_pending) -{ - struct cf_h2_ctx *ctx = cf->ctx; - bool alive = TRUE; - - *input_pending = FALSE; - if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending)) - return FALSE; - - if(*input_pending) { - /* This happens before we have sent off a request and the connection is - not in use by any other transfer, there should not be any data here, - only "protocol frames" */ - CURLcode result; - size_t nread; - - *input_pending = FALSE; - result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); - if(!result) { - CURL_TRC_CF(data, cf, "%zu bytes stray data read before trying " - "h2 connection", nread); - result = h2_process_pending_input(cf, data); - if(result) - /* immediate error, considered dead */ - alive = FALSE; - else { - alive = !should_close_session(ctx); - } - } - else if(result != CURLE_AGAIN) { - /* the read failed so let's say this is dead anyway */ - alive = FALSE; - } - } - - return alive; -} - -static CURLcode http2_send_ping(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - int rc; - - rc = nghttp2_submit_ping(ctx->h2, 0, ZERO_NULL); - if(rc) { - failf(data, "nghttp2_submit_ping() failed: %s(%d)", - nghttp2_strerror(rc), rc); - return CURLE_HTTP2; - } - - rc = nghttp2_session_send(ctx->h2); - if(rc) { - failf(data, "nghttp2_session_send() failed: %s(%d)", - nghttp2_strerror(rc), rc); - return CURLE_SEND_ERROR; - } - return CURLE_OK; -} - -/* - * Store nghttp2 version info in this buffer. - */ -void Curl_http2_ver(char *p, size_t len) -{ - nghttp2_info *h2 = nghttp2_version(0); - (void)curl_msnprintf(p, len, "nghttp2/%s", h2->version_str); -} - -/* - * The implementation of nghttp2_send_callback type. Here we write |data| with - * size |length| to the network and return the number of bytes actually - * written. See the documentation of nghttp2_send_callback for the details. - */ -static ssize_t send_callback(nghttp2_session *h2, - const uint8_t *buf, size_t blen, int flags, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nwritten; - CURLcode result = CURLE_OK; - - (void)h2; - (void)flags; - DEBUGASSERT(data); - - if(!cf->connected) - result = Curl_bufq_write(&ctx->outbufq, buf, blen, &nwritten); - else - result = Curl_cf_send_bufq(cf->next, data, &ctx->outbufq, buf, blen, - &nwritten); - - if(result) { - if(result == CURLE_AGAIN) { - ctx->nw_out_blocked = 1; - return NGHTTP2_ERR_WOULDBLOCK; - } - failf(data, "Failed sending HTTP2 data"); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - if(!nwritten) { - ctx->nw_out_blocked = 1; - return NGHTTP2_ERR_WOULDBLOCK; - } - return (nwritten > SSIZE_MAX) ? - NGHTTP2_ERR_CALLBACK_FAILURE : (ssize_t)nwritten; -} - -/* We pass a pointer to this struct in the push callback, but the contents of - the struct are hidden from the user. */ -struct curl_pushheaders { - struct Curl_easy *data; - struct h2_stream_ctx *stream; - const nghttp2_push_promise *frame; -}; - -/* - * push header access function. Only to be used from within the push callback - */ -char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) -{ - /* Verify that we got a good easy handle in the push header struct, mostly to - detect rubbish input fast(er). */ - if(!h || !GOOD_EASY_HANDLE(h->data)) - return NULL; - else { - if(h->stream && num < h->stream->push_headers_used) - return h->stream->push_headers[num]; - } - return NULL; -} - -/* - * push header access function. Only to be used from within the push callback - */ -char *curl_pushheader_byname(struct curl_pushheaders *h, const char *name) -{ - struct h2_stream_ctx *stream; - size_t len; - size_t i; - /* Verify that we got a good easy handle in the push header struct, - mostly to detect rubbish input fast(er). Also empty header name - is rubbish too. We have to allow ":" at the beginning of - the header, but header == ":" must be rejected. If we have ':' in - the middle of header, it could be matched in middle of the value, - this is because we do prefix match.*/ - if(!h || !GOOD_EASY_HANDLE(h->data) || !name || !name[0] || - !strcmp(name, ":") || strchr(name + 1, ':')) - return NULL; - - stream = h->stream; - if(!stream) - return NULL; - - len = strlen(name); - for(i = 0; i < stream->push_headers_used; i++) { - if(!strncmp(name, stream->push_headers[i], len)) { - /* sub-match, make sure that it is followed by a colon */ - if(stream->push_headers[i][len] != ':') - continue; - return &stream->push_headers[i][len + 1]; - } - } - return NULL; -} - -static struct Curl_easy *h2_duphandle(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct Curl_easy *second = curl_easy_duphandle(data); - if(second) { - struct h2_stream_ctx *second_stream; - http2_data_setup(cf, second, &second_stream); - second->state.priority.weight = data->state.priority.weight; - } - return second; -} - -static int set_transfer_url(struct Curl_easy *newhandle, - struct curl_pushheaders *hp, - struct Curl_easy *data) -{ - const char *v; - CURLUcode uc; - char *url = NULL; - int rc = 0; - CURLU *u = curl_url(); - - if(!u) - return 5; - - v = curl_pushheader_byname(hp, HTTP_PSEUDO_SCHEME); - if(v) { - uc = curl_url_set(u, CURLUPART_SCHEME, v, 0); - if(uc) { - rc = 1; - goto fail; - } - } - - v = curl_pushheader_byname(hp, HTTP_PSEUDO_AUTHORITY); - if(v) { - uc = Curl_url_set_authority(u, v); - if(uc) { - rc = 2; - goto fail; - } - } - - v = curl_pushheader_byname(hp, HTTP_PSEUDO_PATH); - if(v) { - uc = curl_url_set(u, CURLUPART_PATH, v, 0); - if(uc) { - rc = 3; - goto fail; - } - } - - /* We can only allow PUSH of resource from the same origin, e.g. - * scheme + hostname + port */ - if(!Curl_url_same_origin(data->state.uh, u)) { - rc = 1; - goto fail; - } - - uc = curl_url_get(u, CURLUPART_URL, &url, 0); - if(uc) - rc = 4; -fail: - curl_url_cleanup(u); - if(rc) - return rc; - - Curl_bufref_set(&newhandle->state.url, url, 0, curl_free); - return 0; -} - -static void discard_newhandle(struct Curl_cfilter *cf, - struct Curl_easy *newhandle) -{ - http2_data_done(cf, newhandle); - (void)Curl_close(&newhandle); -} - -static int push_promise(struct Curl_cfilter *cf, - struct Curl_easy *data, - const nghttp2_push_promise *frame) -{ - struct cf_h2_ctx *ctx = cf->ctx; - int rv; /* one of the CURL_PUSH_* defines */ - - CURL_TRC_CF(data, cf, "[%d] PUSH_PROMISE received", - frame->promised_stream_id); - if(data->multi->push_cb) { - struct h2_stream_ctx *stream; - struct h2_stream_ctx *newstream; - struct curl_pushheaders heads; - CURLMcode mresult; - CURLcode result; - /* clone the parent */ - struct Curl_easy *newhandle = h2_duphandle(cf, data); - if(!newhandle) { - infof(data, "failed to duplicate handle"); - rv = CURL_PUSH_DENY; /* FAIL HARD */ - goto fail; - } - - stream = H2_STREAM_CTX(ctx, data); - if(!stream) { - failf(data, "Internal NULL stream"); - discard_newhandle(cf, newhandle); - rv = CURL_PUSH_DENY; - goto fail; - } - - heads.data = data; - heads.stream = stream; - heads.frame = frame; - - rv = set_transfer_url(newhandle, &heads, data); - if(rv) { - CURL_TRC_CF(data, cf, "[%d] PUSH_PROMISE, failed to set URL -> %d", - frame->promised_stream_id, rv); - discard_newhandle(cf, newhandle); - rv = CURL_PUSH_DENY; - goto fail; - } - - Curl_set_in_callback(data, TRUE); - rv = data->multi->push_cb(data, newhandle, - stream->push_headers_used, &heads, - data->multi->push_userp); - Curl_set_in_callback(data, FALSE); - - /* free the headers again */ - free_push_headers(stream); - - if(rv) { - DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT)); - /* denied, kill off the new handle again */ - CURL_TRC_CF(data, cf, "[%d] PUSH_PROMISE, denied by application -> %d", - frame->promised_stream_id, rv); - discard_newhandle(cf, newhandle); - goto fail; - } - - /* approved, add to the multi handle for processing. This - * assigns newhandle->mid. For the new `mid` we assign the - * h2_stream instance and remember the stream_id already known. */ - mresult = Curl_multi_add_perform(data->multi, newhandle, cf->conn); - if(mresult) { - infof(data, "failed to add handle to multi"); - discard_newhandle(cf, newhandle); - rv = CURL_PUSH_DENY; - goto fail; - } - - result = http2_data_setup(cf, newhandle, &newstream); - if(result) { - failf(data, "error setting up stream: %d", result); - discard_newhandle(cf, newhandle); - rv = CURL_PUSH_DENY; - goto fail; - } - - DEBUGASSERT(newstream); - newstream->id = frame->promised_stream_id; - newhandle->req.maxdownload = -1; - newhandle->req.size = -1; - - CURL_TRC_CF(data, cf, "promise easy handle added to multi, mid=%u", - newhandle->mid); - rv = nghttp2_session_set_stream_user_data(ctx->h2, - newstream->id, - newhandle); - if(rv) { - infof(data, "failed to set user_data for stream %d", - newstream->id); - DEBUGASSERT(0); - discard_newhandle(cf, newhandle); - rv = CURL_PUSH_DENY; - goto fail; - } - - /* success, remember max stream id processed */ - if(newstream->id > ctx->local_max_sid) - ctx->local_max_sid = newstream->id; - } - else { - CURL_TRC_CF(data, cf, "Got PUSH_PROMISE, ignore it"); - rv = CURL_PUSH_DENY; - } -fail: - return rv; -} - -static void h2_xfer_write_resp_hd(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream, - const char *buf, size_t blen, bool eos) -{ - /* If we already encountered an error, skip further writes */ - if(!stream->xfer_result) { - stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, blen, eos); - if(!stream->xfer_result && !eos) - stream->xfer_result = cf_h2_update_local_win(cf, data, stream); - if(stream->xfer_result) - CURL_TRC_CF(data, cf, "[%d] error %d writing %zu bytes of headers", - stream->id, stream->xfer_result, blen); - } -} - -static void h2_xfer_write_resp(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream, - const char *buf, size_t blen, bool eos) -{ - /* If we already encountered an error, skip further writes */ - if(!stream->xfer_result) - stream->xfer_result = Curl_xfer_write_resp(data, buf, blen, eos); - /* If the transfer write is errored, we do not want any more data */ - if(stream->xfer_result) { - struct cf_h2_ctx *ctx = cf->ctx; - CURL_TRC_CF(data, cf, "[%d] error %d writing %zu bytes of data, " - "RST-ing stream", - stream->id, stream->xfer_result, blen); - nghttp2_submit_rst_stream(ctx->h2, 0, stream->id, - (uint32_t)NGHTTP2_ERR_CALLBACK_FAILURE); - } - else if(!stream->write_paused && Curl_xfer_write_is_paused(data)) { - CURL_TRC_CF(data, cf, "[%d] stream output paused", stream->id); - stream->write_paused = TRUE; - } - else if(stream->write_paused && !Curl_xfer_write_is_paused(data)) { - CURL_TRC_CF(data, cf, "[%d] stream output unpaused", stream->id); - stream->write_paused = FALSE; - } - - if(!stream->xfer_result && !eos) - stream->xfer_result = cf_h2_update_local_win(cf, data, stream); -} - -static CURLcode on_stream_frame(struct Curl_cfilter *cf, - struct Curl_easy *data, - const nghttp2_frame *frame) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - int32_t stream_id = frame->hd.stream_id; - int rv; - - if(!stream) { - CURL_TRC_CF(data, cf, "[%d] No stream_ctx set", stream_id); - return CURLE_FAILED_INIT; - } - - switch(frame->hd.type) { - case NGHTTP2_DATA: - CURL_TRC_CF(data, cf, "[%d] DATA, window=%d/%d", - stream_id, - nghttp2_session_get_stream_effective_recv_data_length( - ctx->h2, stream->id), - nghttp2_session_get_stream_effective_local_window_size( - ctx->h2, stream->id)); - /* If !body started on this stream, then receiving DATA is illegal. */ - if(!stream->bodystarted) { - rv = nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, - stream_id, NGHTTP2_PROTOCOL_ERROR); - - if(nghttp2_is_fatal(rv)) { - return CURLE_RECV_ERROR; - } - } - break; - case NGHTTP2_HEADERS: - if(stream->bodystarted) { - /* Only valid HEADERS after body started is trailer HEADERS. We - buffer them in on_header callback. */ - break; - } - - /* nghttp2 guarantees that :status is received, and we store it to - stream->status_code. Fuzzing has proven this can still be reached - without status code having been set. */ - if(stream->status_code == -1) - return CURLE_RECV_ERROR; - - /* Only final status code signals the end of header */ - if(stream->status_code / 100 != 1) - stream->bodystarted = TRUE; - else - stream->status_code = -1; - - h2_xfer_write_resp_hd(cf, data, stream, STRCONST("\r\n"), - (bool)stream->closed); - - if(stream->status_code / 100 != 1) { - stream->resp_hds_complete = TRUE; - } - Curl_multi_mark_dirty(data); - break; - case NGHTTP2_PUSH_PROMISE: - rv = push_promise(cf, data, &frame->push_promise); - if(rv) { /* deny! */ - DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT)); - rv = nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, - frame->push_promise.promised_stream_id, - NGHTTP2_CANCEL); - if(nghttp2_is_fatal(rv)) - return CURLE_SEND_ERROR; - else if(rv == CURL_PUSH_ERROROUT) { - CURL_TRC_CF(data, cf, "[%d] fail in PUSH_PROMISE received", - stream_id); - return CURLE_RECV_ERROR; - } - } - break; - case NGHTTP2_RST_STREAM: - if(frame->rst_stream.error_code) - stream->reset_by_server = TRUE; - Curl_multi_mark_dirty(data); - break; - case NGHTTP2_WINDOW_UPDATE: - if(CURL_REQ_WANT_SEND(data) && Curl_bufq_is_empty(&stream->sendbuf)) { - /* need more data, force processing of transfer */ - Curl_multi_mark_dirty(data); - } - else if(!Curl_bufq_is_empty(&stream->sendbuf)) { - /* resume the potentially suspended stream */ - rv = nghttp2_session_resume_data(ctx->h2, stream->id); - if(nghttp2_is_fatal(rv)) - return CURLE_SEND_ERROR; - } - break; - default: - break; - } - - if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { - if(!stream->closed && !stream->body_eos && - ((stream->status_code >= 400) || (stream->status_code < 200))) { - /* The server did not give us a positive response and we are not - * done uploading the request body. We need to stop doing that and - * also inform the server that we aborted our side. */ - CURL_TRC_CF(data, cf, "[%d] EOS frame with unfinished upload and " - "HTTP status %d, abort upload by RST", - stream_id, stream->status_code); - nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, NGHTTP2_STREAM_CLOSED); - stream->closed = TRUE; - } - Curl_multi_mark_dirty(data); - } - return CURLE_OK; -} - -#ifdef CURLVERBOSE -int Curl_nghttp2_fr_print(const nghttp2_frame *frame, char *buffer, - size_t blen) -{ - switch(frame->hd.type) { - case NGHTTP2_DATA: { - return curl_msnprintf(buffer, blen, - "FRAME[DATA, len=%d, eos=%d, padlen=%d]", - (int)frame->hd.length, - !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM), - (int)frame->data.padlen); - } - case NGHTTP2_HEADERS: { - return curl_msnprintf(buffer, blen, - "FRAME[HEADERS, len=%d, hend=%d, eos=%d]", - (int)frame->hd.length, - !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS), - !!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)); - } - case NGHTTP2_PRIORITY: { - return curl_msnprintf(buffer, blen, - "FRAME[PRIORITY, len=%d, flags=%d]", - (int)frame->hd.length, frame->hd.flags); - } - case NGHTTP2_RST_STREAM: { - return curl_msnprintf(buffer, blen, - "FRAME[RST_STREAM, len=%d, flags=%d, error=%u]", - (int)frame->hd.length, frame->hd.flags, - frame->rst_stream.error_code); - } - case NGHTTP2_SETTINGS: { - if(frame->hd.flags & NGHTTP2_FLAG_ACK) { - return curl_msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]"); - } - return curl_msnprintf(buffer, blen, - "FRAME[SETTINGS, len=%d]", (int)frame->hd.length); - } - case NGHTTP2_PUSH_PROMISE: - return curl_msnprintf(buffer, blen, - "FRAME[PUSH_PROMISE, len=%d, hend=%d]", - (int)frame->hd.length, - !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS)); - case NGHTTP2_PING: - return curl_msnprintf(buffer, blen, - "FRAME[PING, len=%d, ack=%d]", - (int)frame->hd.length, - frame->hd.flags & NGHTTP2_FLAG_ACK); - case NGHTTP2_GOAWAY: { - char scratch[128]; - size_t s_len = CURL_ARRAYSIZE(scratch); - size_t len = (frame->goaway.opaque_data_len < s_len) ? - frame->goaway.opaque_data_len : s_len - 1; - if(len) - memcpy(scratch, frame->goaway.opaque_data, len); - scratch[len] = '\0'; - return curl_msnprintf(buffer, blen, - "FRAME[GOAWAY, error=%u, reason='%s', " - "last_stream=%d]", frame->goaway.error_code, - scratch, frame->goaway.last_stream_id); - } - case NGHTTP2_WINDOW_UPDATE: { - return curl_msnprintf(buffer, blen, - "FRAME[WINDOW_UPDATE, incr=%d]", - frame->window_update.window_size_increment); - } - default: - return curl_msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]", - frame->hd.type, (int)frame->hd.length, - frame->hd.flags); - } -} - -static int on_frame_send(nghttp2_session *session, const nghttp2_frame *frame, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - - (void)session; - DEBUGASSERT(data); - if(Curl_trc_cf_is_verbose(cf, data)) { - char buffer[256]; - int len; - len = Curl_nghttp2_fr_print(frame, buffer, sizeof(buffer) - 1); - buffer[len] = 0; - CURL_TRC_CF(data, cf, "[%d] -> %s", frame->hd.stream_id, buffer); - } - if((frame->hd.type == NGHTTP2_GOAWAY) && !ctx->sent_goaway) { - /* A GOAWAY not initiated by us, but by nghttp2 itself on detecting - * a protocol error on the connection */ - failf(data, "nghttp2 shuts down connection with error %u: %s", - frame->goaway.error_code, - nghttp2_http2_strerror(frame->goaway.error_code)); - } - return 0; -} -#endif /* CURLVERBOSE */ - -static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf), *data_s; - int32_t stream_id = frame->hd.stream_id; - - DEBUGASSERT(data); -#ifdef CURLVERBOSE - if(Curl_trc_cf_is_verbose(cf, data)) { - char buffer[256]; - int len; - len = Curl_nghttp2_fr_print(frame, buffer, sizeof(buffer) - 1); - buffer[len] = 0; - CURL_TRC_CF(data, cf, "[%d] <- %s", frame->hd.stream_id, buffer); - } -#endif /* CURLVERBOSE */ - - if(!stream_id) { - /* stream ID zero is for connection-oriented stuff */ - DEBUGASSERT(data); - switch(frame->hd.type) { - case NGHTTP2_SETTINGS: { - if(!(frame->hd.flags & NGHTTP2_FLAG_ACK)) { - uint32_t max_conn = ctx->max_concurrent_streams; - ctx->max_concurrent_streams = nghttp2_session_get_remote_settings( - session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); - ctx->enable_push = nghttp2_session_get_remote_settings( - session, NGHTTP2_SETTINGS_ENABLE_PUSH) != 0; - CURL_TRC_CF(data, cf, "[0] MAX_CONCURRENT_STREAMS: %u", - ctx->max_concurrent_streams); - CURL_TRC_CF(data, cf, "[0] ENABLE_PUSH: %s", - ctx->enable_push ? "TRUE" : "false"); - if(data && max_conn != ctx->max_concurrent_streams) { - /* only signal change if the value actually changed */ - CURL_TRC_CF(data, cf, "[0] notify MAX_CONCURRENT_STREAMS: %u", - ctx->max_concurrent_streams); - Curl_multi_connchanged(data->multi); - } - /* Since the initial stream window is 64K, a request might be on HOLD, - * due to exhaustion. The (initial) SETTINGS may announce a much larger - * window and *assume* that we treat this like a WINDOW_UPDATE. Some - * servers send an explicit WINDOW_UPDATE, but not all seem to do that. - * To be safe, we UNHOLD a stream in order not to stall. */ - if(CURL_REQ_WANT_SEND(data)) - Curl_multi_mark_dirty(data); - } - break; - } - case NGHTTP2_GOAWAY: - ctx->rcvd_goaway = TRUE; - ctx->goaway_error = frame->goaway.error_code; - ctx->remote_max_sid = frame->goaway.last_stream_id; - if(data) { - infof(data, "received GOAWAY, error=%u, last_stream=%d", - ctx->goaway_error, ctx->remote_max_sid); - Curl_multi_connchanged(data->multi); - } - break; - default: - break; - } - return 0; - } - - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) { - CURL_TRC_CF(data, cf, "[%d] No Curl_easy associated", stream_id); - return 0; - } - - return on_stream_frame(cf, data_s, frame) ? NGHTTP2_ERR_CALLBACK_FAILURE : 0; -} - -static int cf_h2_on_invalid_frame_recv(nghttp2_session *session, - const nghttp2_frame *frame, - int ngerr, void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct Curl_easy *data; - int32_t stream_id = frame->hd.stream_id; - - data = nghttp2_session_get_stream_user_data(session, stream_id); - if(data) { - struct h2_stream_ctx *stream; -#ifdef CURLVERBOSE - char buffer[256]; - int len; - len = Curl_nghttp2_fr_print(frame, buffer, sizeof(buffer) - 1); - buffer[len] = 0; - failf(data, "[HTTP2] [%d] received invalid frame: %s, error %d: %s", - stream_id, buffer, ngerr, nghttp2_strerror(ngerr)); -#endif /* CURLVERBOSE */ - stream = H2_STREAM_CTX(ctx, data); - if(stream) { - nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, NGHTTP2_STREAM_CLOSED); - stream->error = ngerr; - stream->closed = TRUE; - stream->reset = TRUE; - return 0; /* keep the connection alive */ - } - } - return NGHTTP2_ERR_CALLBACK_FAILURE; -} - -static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const uint8_t *mem, size_t len, void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream; - struct Curl_easy *data_s; - (void)flags; - - DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ - DEBUGASSERT(CF_DATA_CURRENT(cf)); - - /* get the stream from the hash based on Stream ID */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) { - /* Receiving a Stream ID not in the hash should not happen - unless - we have aborted a transfer artificially and there were more data - in the pipeline. Silently ignore. */ - CURL_TRC_CF(CF_DATA_CURRENT(cf), cf, "[%d] Data for unknown", stream_id); - /* consumed explicitly as no one will read it */ - nghttp2_session_consume(session, stream_id, len); - return 0; - } - - stream = H2_STREAM_CTX(ctx, data_s); - if(!stream) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - h2_xfer_write_resp(cf, data_s, stream, (const char *)mem, len, FALSE); - - nghttp2_session_consume(ctx->h2, stream_id, len); - stream->nrcvd_data += (curl_off_t)len; - return 0; -} - -static int on_stream_close(nghttp2_session *session, int32_t stream_id, - uint32_t error_code, void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct Curl_easy *data_s, *call_data = CF_DATA_CURRENT(cf); - struct h2_stream_ctx *stream; - int rv; - (void)session; - - DEBUGASSERT(call_data); - /* stream id 0 is the connection, do not look there for streams. */ - data_s = stream_id ? - nghttp2_session_get_stream_user_data(session, stream_id) : NULL; - if(!data_s) { - CURL_TRC_CF(call_data, cf, - "[%d] on_stream_close, no easy set on stream", stream_id); - return 0; - } - if(!GOOD_EASY_HANDLE(data_s)) { - /* nghttp2 still has an easy registered for the stream which has - * been freed be libcurl. This points to a code path that does not - * trigger DONE or DETACH events as it must. */ - CURL_TRC_CF(call_data, cf, - "[%d] on_stream_close, not a GOOD easy on stream", stream_id); - (void)nghttp2_session_set_stream_user_data(session, stream_id, 0); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - stream = H2_STREAM_CTX(ctx, data_s); - if(!stream) { - CURL_TRC_CF(data_s, cf, - "[%d] on_stream_close, GOOD easy but no stream", stream_id); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - stream->closed = TRUE; - stream->error = error_code; - if(stream->error) - stream->reset = TRUE; - - if(stream->error) - CURL_TRC_CF(data_s, cf, "[%d] RESET: %s (err %u)", - stream_id, nghttp2_http2_strerror(error_code), error_code); - else - CURL_TRC_CF(data_s, cf, "[%d] CLOSED", stream_id); - Curl_multi_mark_dirty(data_s); - - /* remove `data_s` from the nghttp2 stream */ - rv = nghttp2_session_set_stream_user_data(session, stream_id, 0); - if(rv) { - infof(data_s, "http/2: failed to clear user_data for stream %d", - stream_id); - DEBUGASSERT(0); - } - return 0; -} - -static int on_begin_headers(nghttp2_session *session, - const nghttp2_frame *frame, void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream; - struct Curl_easy *data_s = NULL; - - (void)cf; - data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); - if(!data_s) { - return 0; - } - - if(frame->hd.type != NGHTTP2_HEADERS) { - return 0; - } - - stream = H2_STREAM_CTX(ctx, data_s); - if(!stream || !stream->bodystarted) { - return 0; - } - - return 0; -} - -static void cf_h2_header_error(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream, - CURLcode result) -{ - struct cf_h2_ctx *ctx = cf->ctx; - - failf(data, "Error receiving HTTP2 header: %d(%s)", result, - curl_easy_strerror(result)); - if(stream) { - nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, NGHTTP2_STREAM_CLOSED); - stream->closed = TRUE; - stream->reset = TRUE; - } -} - -/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */ -static int on_header(nghttp2_session *session, const nghttp2_frame *frame, - const uint8_t *name, size_t namelen, - const uint8_t *value, size_t valuelen, - uint8_t flags, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream; - struct Curl_easy *data_s; - int32_t stream_id = frame->hd.stream_id; - CURLcode result; - (void)flags; - - DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ - - /* get the stream from the hash based on Stream ID */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!GOOD_EASY_HANDLE(data_s)) - /* Receiving a Stream ID not in the hash should not happen, this is an - internal error more than anything else! */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - - stream = H2_STREAM_CTX(ctx, data_s); - if(!stream) { - failf(data_s, "Internal NULL stream"); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - /* Store received PUSH_PROMISE headers to be used when the subsequent - PUSH_PROMISE callback comes */ - if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { - char *h; - - if((namelen == (sizeof(HTTP_PSEUDO_AUTHORITY) - 1)) && - !strncmp(HTTP_PSEUDO_AUTHORITY, (const char *)name, namelen)) { - /* pseudo headers are lower case */ - int rc = 0; - char *check = curl_maprintf("%s:%d", cf->conn->host.name, - cf->conn->remote_port); - if(!check) - /* no memory */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - if(!curl_strequal(check, (const char *)value) && - ((cf->conn->remote_port != cf->conn->given->defport) || - !curl_strequal(cf->conn->host.name, (const char *)value))) { - /* This is push is not for the same authority that was asked for in - * the URL. RFC 7540 section 8.2 says: "A client MUST treat a - * PUSH_PROMISE for which the server is not authoritative as a stream - * error of type PROTOCOL_ERROR." - */ - (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, - stream_id, NGHTTP2_PROTOCOL_ERROR); - rc = NGHTTP2_ERR_CALLBACK_FAILURE; - } - curlx_free(check); - if(rc) - return rc; - } - - if(!stream->push_headers) { - stream->push_headers_alloc = 10; - stream->push_headers = curlx_malloc(stream->push_headers_alloc * - sizeof(char *)); - if(!stream->push_headers) - return NGHTTP2_ERR_CALLBACK_FAILURE; - stream->push_headers_used = 0; - } - else if(stream->push_headers_used == - stream->push_headers_alloc) { - char **headp; - if(stream->push_headers_alloc > 1000) { - /* this is beyond crazy many headers, bail out */ - failf(data_s, "Too many PUSH_PROMISE headers"); - free_push_headers(stream); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - stream->push_headers_alloc *= 2; - headp = curlx_realloc(stream->push_headers, - stream->push_headers_alloc * sizeof(char *)); - if(!headp) { - free_push_headers(stream); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - stream->push_headers = headp; - } - h = curl_maprintf("%s:%s", name, value); - if(!h) { - free_push_headers(stream); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - stream->push_headers[stream->push_headers_used++] = h; - return 0; - } - - if(stream->bodystarted) { - /* This is a trailer */ - CURL_TRC_CF(data_s, cf, "[%d] trailer: %.*s: %.*s", - stream->id, (int)namelen, name, (int)valuelen, value); - result = Curl_dynhds_add(&stream->resp_trailers, - (const char *)name, namelen, - (const char *)value, valuelen); - if(result) { - cf_h2_header_error(cf, data_s, stream, result); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - return 0; - } - - if(namelen == sizeof(HTTP_PSEUDO_STATUS) - 1 && - memcmp(HTTP_PSEUDO_STATUS, name, namelen) == 0) { - /* nghttp2 guarantees :status is received first and only once. */ - char buffer[32]; - size_t hlen; - result = Curl_http_decode_status(&stream->status_code, - (const char *)value, valuelen); - if(result) { - cf_h2_header_error(cf, data_s, stream, result); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - hlen = curl_msnprintf(buffer, sizeof(buffer), HTTP_PSEUDO_STATUS ":%d\r", - stream->status_code); - result = Curl_headers_push(data_s, buffer, hlen, CURLH_PSEUDO); - if(result) { - cf_h2_header_error(cf, data_s, stream, result); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - curlx_dyn_reset(&ctx->scratch); - result = curlx_dyn_addn(&ctx->scratch, STRCONST("HTTP/2 ")); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, value, valuelen); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, STRCONST(" \r\n")); - if(!result) - h2_xfer_write_resp_hd(cf, data_s, stream, curlx_dyn_ptr(&ctx->scratch), - curlx_dyn_len(&ctx->scratch), FALSE); - if(result) { - cf_h2_header_error(cf, data_s, stream, result); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - /* if we receive data for another handle, wake that up */ - if(CF_DATA_CURRENT(cf) != data_s) - Curl_multi_mark_dirty(data_s); - - CURL_TRC_CF(data_s, cf, "[%d] status: HTTP/2 %03d", - stream->id, stream->status_code); - return 0; - } - - /* nghttp2 guarantees that namelen > 0, and :status was already - received, and this is not pseudo-header field . */ - /* convert to an HTTP1-style header */ - curlx_dyn_reset(&ctx->scratch); - result = curlx_dyn_addn(&ctx->scratch, (const char *)name, namelen); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, STRCONST(": ")); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, (const char *)value, valuelen); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, STRCONST("\r\n")); - if(!result) - h2_xfer_write_resp_hd(cf, data_s, stream, curlx_dyn_ptr(&ctx->scratch), - curlx_dyn_len(&ctx->scratch), FALSE); - if(result) { - cf_h2_header_error(cf, data_s, stream, result); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - /* if we receive data for another handle, wake that up */ - if(CF_DATA_CURRENT(cf) != data_s) - Curl_multi_mark_dirty(data_s); - - CURL_TRC_CF(data_s, cf, "[%d] header: %.*s: %.*s", - stream->id, (int)namelen, name, (int)valuelen, value); - - return 0; /* 0 is successful */ -} - -static ssize_t req_body_read_callback(nghttp2_session *session, - int32_t stream_id, - uint8_t *buf, size_t length, - uint32_t *data_flags, - nghttp2_data_source *source, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct cf_h2_ctx *ctx = cf->ctx; - struct Curl_easy *data_s; - struct h2_stream_ctx *stream = NULL; - CURLcode result; - ssize_t nread; - size_t n; - (void)source; - - (void)cf; - if(!stream_id) - return NGHTTP2_ERR_INVALID_ARGUMENT; - - /* get the stream from the hash based on Stream ID, stream ID zero is for - connection-oriented stuff */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) - /* Receiving a Stream ID not in the hash should not happen, this is an - internal error more than anything else! */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - - stream = H2_STREAM_CTX(ctx, data_s); - if(!stream) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - result = Curl_bufq_read(&stream->sendbuf, buf, length, &n); - if(result) { - if(result != CURLE_AGAIN) - return NGHTTP2_ERR_CALLBACK_FAILURE; - nread = 0; - } - else - nread = (ssize_t)n; - - CURL_TRC_CF(data_s, cf, "[%d] req_body_read(len=%zu) eos=%d -> %zd, %d", - stream_id, length, stream->body_eos, nread, result); - - if(stream->body_eos && Curl_bufq_is_empty(&stream->sendbuf)) { - *data_flags = NGHTTP2_DATA_FLAG_EOF; - return nread; - } - return (nread == 0) ? NGHTTP2_ERR_DEFERRED : nread; -} - -#ifdef CURLVERBOSE -static int error_callback(nghttp2_session *session, - const char *msg, - size_t len, - void *userp) -{ - struct Curl_cfilter *cf = userp; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - (void)session; - failf(data, "%.*s", (int)len, msg); - return 0; -} -#endif - -/* - * Append headers to ask for an HTTP1.1 to HTTP2 upgrade. - */ -CURLcode Curl_http2_request_upgrade(struct dynbuf *req, - struct Curl_easy *data) -{ - CURLcode result; - char *base64; - size_t blen; - struct SingleRequest *k = &data->req; - uint8_t binsettings[H2_BINSETTINGS_LEN]; - ssize_t rc; - size_t binlen; /* length of the binsettings data */ - - rc = populate_binsettings(binsettings, data); - if(!curlx_sztouz(rc, &binlen) || !binlen) { - failf(data, "nghttp2 unexpectedly failed on pack_settings_payload"); - curlx_dyn_free(req); - return CURLE_FAILED_INIT; - } - - result = curlx_base64url_encode(binsettings, binlen, &base64, &blen); - if(result) { - curlx_dyn_free(req); - return result; - } - - data->state.http_hd_upgrade = TRUE; - data->state.http_hd_h2_settings = TRUE; - result = curlx_dyn_addf(req, - "Upgrade: %s\r\n" - "HTTP2-Settings: %s\r\n", - NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64); - curlx_free(base64); - - k->upgr101 = UPGR101_H2; - data->conn->bits.upgrade_in_progress = TRUE; - - return result; -} - -static CURLcode http2_handle_stream_close(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream, - size_t *pnlen) -{ - CURLcode result; - - *pnlen = 0; - if(stream->reset) { - if(stream->error == NGHTTP2_REFUSED_STREAM) { - infof(data, "HTTP/2 stream %d refused by server, try again on a new " - "connection", stream->id); - connclose(cf->conn, "REFUSED_STREAM"); /* do not use this anymore */ - data->state.refused_stream = TRUE; - return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ - } - else if(stream->resp_hds_complete && data->req.no_body) { - CURL_TRC_CF(data, cf, "[%d] error after response headers, but we did " - "not want a body anyway, ignore: %s (err %u)", - stream->id, nghttp2_http2_strerror(stream->error), - stream->error); - stream->close_handled = TRUE; - return CURLE_OK; - } - failf(data, "HTTP/2 stream %d reset by %s (error 0x%x %s)", - stream->id, stream->reset_by_server ? "server" : "curl", - stream->error, nghttp2_http2_strerror(stream->error)); - return stream->error ? CURLE_HTTP2_STREAM : - (data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2); - } - else if(!stream->bodystarted) { - failf(data, "HTTP/2 stream %d was closed cleanly, but before getting " - "all response header fields, treated as error", stream->id); - return CURLE_HTTP2_STREAM; - } - - if(Curl_dynhds_count(&stream->resp_trailers)) { - struct dynhds_entry *e; - struct dynbuf dbuf; - size_t i; - - result = CURLE_OK; - curlx_dyn_init(&dbuf, DYN_TRAILERS); - for(i = 0; i < Curl_dynhds_count(&stream->resp_trailers); ++i) { - e = Curl_dynhds_getn(&stream->resp_trailers, i); - if(!e) - break; - curlx_dyn_reset(&dbuf); - result = curlx_dyn_addf(&dbuf, "%.*s: %.*s\x0d\x0a", - (int)e->namelen, e->name, - (int)e->valuelen, e->value); - if(result) - break; - Curl_debug(data, CURLINFO_HEADER_IN, curlx_dyn_ptr(&dbuf), - curlx_dyn_len(&dbuf)); - result = Curl_client_write(data, - CLIENTWRITE_HEADER | CLIENTWRITE_TRAILER, - curlx_dyn_ptr(&dbuf), curlx_dyn_len(&dbuf)); - if(result) - break; - } - curlx_dyn_free(&dbuf); - if(result) - goto out; - } - - stream->close_handled = TRUE; - result = CURLE_OK; - -out: - CURL_TRC_CF(data, cf, "handle_stream_close -> %d, %zu", result, *pnlen); - return result; -} - -static int sweight_wanted(const struct Curl_easy *data) -{ - /* 0 weight is not set by user and we take the nghttp2 default one */ - return data->set.priority.weight ? - data->set.priority.weight : NGHTTP2_DEFAULT_WEIGHT; -} - -static int sweight_in_effect(const struct Curl_easy *data) -{ - /* 0 weight is not set by user and we take the nghttp2 default one */ - return data->state.priority.weight ? - data->state.priority.weight : NGHTTP2_DEFAULT_WEIGHT; -} - -/* - * h2_pri_spec() fills in the pri_spec struct, used by nghttp2 to send weight - * and dependency to the peer. It also stores the updated values in the state - * struct. - */ - -static void h2_pri_spec(struct cf_h2_ctx *ctx, - struct Curl_easy *data, - nghttp2_priority_spec *pri_spec) -{ - struct Curl_data_priority *prio = &data->set.priority; - struct h2_stream_ctx *depstream = H2_STREAM_CTX(ctx, prio->parent); - int32_t depstream_id = depstream ? depstream->id : 0; - nghttp2_priority_spec_init(pri_spec, depstream_id, - sweight_wanted(data), - data->set.priority.exclusive); - data->state.priority = *prio; -} - -/* - * Check if there is been an update in the priority / - * dependency settings and if so it submits a PRIORITY frame with the updated - * info. - * Flush any out data pending in the network buffer. - */ -static CURLcode h2_progress_egress(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - int rv = 0; - - if(stream && stream->id > 0 && - ((sweight_wanted(data) != sweight_in_effect(data)) || - (data->set.priority.exclusive != data->state.priority.exclusive) || - (data->set.priority.parent != data->state.priority.parent))) { - /* send new weight and/or dependency */ - nghttp2_priority_spec pri_spec; - - h2_pri_spec(ctx, data, &pri_spec); - CURL_TRC_CF(data, cf, "[%d] Queuing PRIORITY", stream->id); - DEBUGASSERT(stream->id != -1); - rv = nghttp2_submit_priority(ctx->h2, NGHTTP2_FLAG_NONE, - stream->id, &pri_spec); - if(rv) - goto out; - } - - ctx->nw_out_blocked = 0; - while(!rv && !ctx->nw_out_blocked && nghttp2_session_want_write(ctx->h2)) - rv = nghttp2_session_send(ctx->h2); - -out: - if(nghttp2_is_fatal(rv)) { - CURL_TRC_CF(data, cf, "nghttp2_session_send error (%s)%d", - nghttp2_strerror(rv), rv); - return CURLE_SEND_ERROR; - } - /* Defer flushing during the connect phase so that the SETTINGS and - * other initial frames are sent together with the first request. - * Unless we are 'connect_only' where the request will never come. */ - if(!cf->connected && !cf->conn->bits.connect_only) - return CURLE_OK; - return nw_out_flush(cf, data); -} - -static CURLcode stream_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - struct h2_stream_ctx *stream, - char *buf, size_t len, size_t *pnread) -{ - struct cf_h2_ctx *ctx = cf->ctx; - CURLcode result = CURLE_AGAIN; - - (void)buf; - (void)len; - *pnread = 0; - - if(!stream->xfer_result) - stream->xfer_result = cf_h2_update_local_win(cf, data, stream); - - if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%d] xfer write failed", stream->id); - result = stream->xfer_result; - } - else if(stream->closed) { - CURL_TRC_CF(data, cf, "[%d] returning CLOSE", stream->id); - result = http2_handle_stream_close(cf, data, stream, pnread); - } - else if(stream->reset || - (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) || - (ctx->rcvd_goaway && ctx->remote_max_sid < stream->id)) { - CURL_TRC_CF(data, cf, "[%d] returning ERR", stream->id); - result = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2; - } - - if(result && (result != CURLE_AGAIN)) - CURL_TRC_CF(data, cf, "[%d] stream_recv(len=%zu) -> %d, %zu", - stream->id, len, result, *pnread); - return result; -} - -static CURLcode h2_progress_ingress(struct Curl_cfilter *cf, - struct Curl_easy *data, - size_t data_max_bytes) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream; - CURLcode result = CURLE_OK; - size_t nread; - - if(should_close_session(ctx)) { - CURL_TRC_CF(data, cf, "[0] ingress: session is closed"); - return CURLE_HTTP2; - } - - /* Process network input buffer first */ - if(!Curl_bufq_is_empty(&ctx->inbufq)) { - CURL_TRC_CF(data, cf, "Process %zu bytes in connection buffer", - Curl_bufq_len(&ctx->inbufq)); - result = h2_process_pending_input(cf, data); - if(result) - return result; - } - - if(!data_max_bytes) - data_max_bytes = H2_CHUNK_SIZE; - - /* Receive data from the "lower" filters, e.g. network until - * it is time to stop due to connection close or us not processing - * all network input */ - while(!ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) { - stream = H2_STREAM_CTX(ctx, data); - if(stream && (stream->closed || !data_max_bytes)) { - /* We would like to abort here and stop processing, so that the transfer - * loop can handle the data/close here. This may leave data in - * underlying buffers that will not be consumed. */ - if(!cf->next || !cf->next->cft->has_data_pending(cf->next, data)) - Curl_multi_mark_dirty(data); - break; - } - else if(!stream) { - DEBUGASSERT(0); - break; - } - - result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread); - if(result) { - if(result != CURLE_AGAIN) { - failf(data, "Failed receiving HTTP2 data: %d(%s)", result, - curl_easy_strerror(result)); - return result; - } - break; - } - else if(nread == 0) { - CURL_TRC_CF(data, cf, "[0] ingress: connection closed"); - ctx->conn_closed = TRUE; - break; - } - else { - CURL_TRC_CF(data, cf, "[0] ingress: read %zu bytes", nread); - data_max_bytes = (data_max_bytes > nread) ? (data_max_bytes - nread) : 0; - } - - result = h2_process_pending_input(cf, data); - if(result) - return result; - CURL_TRC_CF(data, cf, "[0] ingress: nw-in buffered %zu", - Curl_bufq_len(&ctx->inbufq)); - } - - if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) { - connclose(cf->conn, ctx->rcvd_goaway ? "server closed with GOAWAY" : - "server closed abruptly"); - } - - CURL_TRC_CF(data, cf, "[0] ingress: done"); - return CURLE_OK; -} - -static CURLcode cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream; - CURLcode result, r2; - struct cf_call_data save; - - if(!data) - return CURLE_HTTP2; - - stream = H2_STREAM_CTX(ctx, data); - - *pnread = 0; - if(!stream) { - /* Abnormal call sequence: either this transfer has never opened a stream - * (unlikely) or the transfer has been done, cleaned up its resources, but - * a read() is called anyway. It is not clear what the calling sequence - * is for such a case. */ - failf(data, "http/2 recv on a transfer never opened " - "or already cleared, mid=%u", data->mid); - return CURLE_HTTP2; - } - - CF_DATA_SAVE(save, cf, data); - - result = stream_recv(cf, data, stream, buf, len, pnread); - if(result && (result != CURLE_AGAIN)) - goto out; - - if(result) { - result = h2_progress_ingress(cf, data, len); - if(result) - goto out; - - result = stream_recv(cf, data, stream, buf, len, pnread); - } - - if(*pnread > 0) { - /* Now that we transferred this to the upper layer, we report - * the actual amount of DATA consumed to the H2 session, so - * that it adjusts stream flow control */ - nghttp2_session_consume(ctx->h2, stream->id, *pnread); - if(stream->closed) { - CURL_TRC_CF(data, cf, "[%d] DRAIN closed stream", stream->id); - Curl_multi_mark_dirty(data); - } - } - -out: - r2 = h2_progress_egress(cf, data); - if(r2 == CURLE_AGAIN) { - /* pending data to send, need to be called again. Ideally, we - * monitor the socket for POLLOUT, but when not SENDING - * any more, we force processing of the transfer. */ - if(!CURL_REQ_WANT_SEND(data)) - Curl_multi_mark_dirty(data); - } - else if(r2) { - result = r2; - } - CURL_TRC_CF(data, cf, "[%d] cf_recv(len=%zu) -> %d, %zu, " - "window=%d/%d, connection %d/%d", - stream->id, len, result, *pnread, - nghttp2_session_get_stream_effective_recv_data_length( - ctx->h2, stream->id), - nghttp2_session_get_stream_effective_local_window_size( - ctx->h2, stream->id), - nghttp2_session_get_local_window_size(ctx->h2), - HTTP2_HUGE_WINDOW_SIZE); - - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode cf_h2_body_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h2_stream_ctx *stream, - const void *buf, size_t blen, bool eos, - size_t *pnwritten) -{ - struct cf_h2_ctx *ctx = cf->ctx; - CURLcode result; - - *pnwritten = 0; - if(stream->closed) { - if(stream->resp_hds_complete) { - /* Server decided to close the stream after having sent us a final - * response. This is valid if it is not interested in the request - * body. This happens on 30x or 40x responses. - * We silently discard the data sent, since this is not a transport - * error situation. */ - CURL_TRC_CF(data, cf, "[%d] discarding data" - "on closed stream with response", stream->id); - if(eos) - stream->body_eos = TRUE; - *pnwritten = blen; - return CURLE_OK; - } - /* Server closed before we got a response, this is an error */ - infof(data, "stream %d closed", stream->id); - return CURLE_SEND_ERROR; - } - - result = Curl_bufq_write(&stream->sendbuf, buf, blen, pnwritten); - if(result) - return result; - - if(eos && (blen == *pnwritten)) - stream->body_eos = TRUE; - - if(eos || !Curl_bufq_is_empty(&stream->sendbuf)) { - /* resume the potentially suspended stream */ - int rv = nghttp2_session_resume_data(ctx->h2, stream->id); - if(nghttp2_is_fatal(rv)) - return CURLE_SEND_ERROR; - } - - return CURLE_OK; -} - -static CURLcode h2_submit(struct h2_stream_ctx **pstream, - struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, - bool eos, size_t *pnwritten) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream = NULL; - struct dynhds h2_headers; - nghttp2_nv *nva = NULL; - const void *body = NULL; - size_t nheader, bodylen; - nghttp2_data_provider data_prd; - int32_t stream_id; - nghttp2_priority_spec pri_spec; - size_t nwritten; - CURLcode result = CURLE_OK; - uint32_t initial_win_size; - - *pnwritten = 0; - Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); - - result = http2_data_setup(cf, data, &stream); - if(result) - goto out; - - result = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, - !data->state.http_ignorecustom ? - data->set.str[STRING_CUSTOMREQUEST] : NULL, - 0, &nwritten); - if(result) - goto out; - *pnwritten = nwritten; - if(!stream->h1.done) { - /* need more data */ - goto out; - } - DEBUGASSERT(stream->h1.req); - - result = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); - if(result) - goto out; - /* no longer needed */ - Curl_h1_req_parse_free(&stream->h1); - - nva = Curl_dynhds_to_nva(&h2_headers, &nheader); - if(!nva) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - h2_pri_spec(ctx, data, &pri_spec); - if(!nghttp2_session_check_request_allowed(ctx->h2)) - CURL_TRC_CF(data, cf, "send request NOT allowed (via nghttp2)"); - - /* Check the initial windows size of the transfer (rate-limits?) and - * send an updated settings on changes from previous value. */ - initial_win_size = cf_h2_initial_win_size(data); - if(initial_win_size != ctx->initial_win_size) { - result = cf_h2_update_settings(ctx, initial_win_size); - if(result) - goto out; - } - - switch(data->state.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - case HTTPREQ_PUT: - data_prd.read_callback = req_body_read_callback; - data_prd.source.ptr = NULL; - stream_id = nghttp2_submit_request(ctx->h2, &pri_spec, nva, nheader, - &data_prd, data); - break; - default: - stream_id = nghttp2_submit_request(ctx->h2, &pri_spec, nva, nheader, - NULL, data); - } - - if(stream_id < 0) { - CURL_TRC_CF(data, cf, "send: nghttp2_submit_request error (%s)%d", - nghttp2_strerror(stream_id), stream_id); - result = CURLE_SEND_ERROR; - goto out; - } - -#ifdef CURLVERBOSE -#define MAX_ACC 60000 /* <64KB to account for some overhead */ - if(Curl_trc_is_verbose(data)) { - size_t acc = 0, i; - - infof(data, "[HTTP/2] [%d] OPENED stream for %s", - stream_id, Curl_bufref_ptr(&data->state.url)); - for(i = 0; i < nheader; ++i) { - acc += nva[i].namelen + nva[i].valuelen; - - infof(data, "[HTTP/2] [%d] [%.*s: %.*s]", stream_id, - (int)nva[i].namelen, nva[i].name, - (int)nva[i].valuelen, nva[i].value); - } - - if(acc > MAX_ACC) { - infof(data, "[HTTP/2] Warning: The cumulative length of all " - "headers exceeds %d bytes and that could cause the " - "stream to be rejected.", MAX_ACC); - } - } -#endif - - stream->id = stream_id; - - body = (const char *)buf + *pnwritten; - bodylen = len - *pnwritten; - - if(bodylen || eos) { - size_t n; - result = cf_h2_body_send(cf, data, stream, body, bodylen, eos, &n); - if(!result) - *pnwritten += n; - else if(result == CURLE_AGAIN) - result = CURLE_OK; - else { - result = CURLE_SEND_ERROR; - } - } - -out: - CURL_TRC_CF(data, cf, "[%d] submit -> %d, %zu", - stream ? stream->id : -1, result, *pnwritten); - curlx_safefree(nva); - *pstream = stream; - Curl_dynhds_free(&h2_headers); - return result; -} - -static CURLcode cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - struct cf_call_data save; - CURLcode result = CURLE_OK, r2; - - CF_DATA_SAVE(save, cf, data); - *pnwritten = 0; - - if(!stream || stream->id == -1) { - result = h2_submit(&stream, cf, data, buf, len, eos, pnwritten); - if(result) - goto out; - DEBUGASSERT(stream); - } - else if(stream->body_eos) { - /* We already wrote this, but CURLE_AGAIN-ed the call due to not - * being able to flush stream->sendbuf. Make a 0-length write - * to trigger flushing again. - * If this works, we report to have written `len` bytes. */ - size_t n; - DEBUGASSERT(eos); - result = cf_h2_body_send(cf, data, stream, buf, 0, eos, &n); - CURL_TRC_CF(data, cf, "[%d] cf_body_send last CHUNK -> %d, %zu, eos=%d", - stream->id, result, n, eos); - if(result) - goto out; - *pnwritten = len; - } - else { - result = cf_h2_body_send(cf, data, stream, buf, len, eos, pnwritten); - CURL_TRC_CF(data, cf, "[%d] cf_body_send(len=%zu) -> %d, %zu, eos=%d", - stream->id, len, result, *pnwritten, eos); - } - - /* Call the nghttp2 send loop and flush to write ALL buffered data, - * headers and/or request body completely out to the network */ - r2 = h2_progress_egress(cf, data); - - /* if the stream has been closed in egress handling (nghttp2 does that - * when it does not like the headers, for example */ - if(stream && stream->closed) { - infof(data, "stream %d closed", stream->id); - result = CURLE_SEND_ERROR; - goto out; - } - else if(r2 && (r2 != CURLE_AGAIN)) { - result = r2; - goto out; - } - - if(should_close_session(ctx)) { - /* nghttp2 thinks this session is done. If the stream has not been - * closed, this is an error state for out transfer */ - if(stream && stream->closed) { - result = http2_handle_stream_close(cf, data, stream, pnwritten); - } - else { - CURL_TRC_CF(data, cf, "send: nothing to do in this session"); - result = CURLE_HTTP2; - } - } - -out: - if(stream) { - CURL_TRC_CF(data, cf, "[%d] cf_send(len=%zu) -> %d, %zu, " - "eos=%d, h2 windows %d-%d (stream-conn), " - "buffers %zu-%zu (stream-conn)", - stream->id, len, result, *pnwritten, - stream->body_eos, - nghttp2_session_get_stream_remote_window_size( - ctx->h2, stream->id), - nghttp2_session_get_remote_window_size(ctx->h2), - Curl_bufq_len(&stream->sendbuf), - Curl_bufq_len(&ctx->outbufq)); - } - else { - CURL_TRC_CF(data, cf, "cf_send(len=%zu) -> %d, %zu, " - "connection-window=%d, nw_send_buffer(%zu)", - len, result, *pnwritten, - nghttp2_session_get_remote_window_size(ctx->h2), - Curl_bufq_len(&ctx->outbufq)); - } - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode cf_h2_flush(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - struct cf_call_data save; - CURLcode result = CURLE_OK; - - CF_DATA_SAVE(save, cf, data); - if(stream && !Curl_bufq_is_empty(&stream->sendbuf)) { - /* resume the potentially suspended stream */ - int rv = nghttp2_session_resume_data(ctx->h2, stream->id); - if(nghttp2_is_fatal(rv)) { - result = CURLE_SEND_ERROR; - goto out; - } - } - - result = h2_progress_egress(cf, data); - -out: - if(stream) { - CURL_TRC_CF(data, cf, "[%d] flush -> %d, " - "h2 windows %d-%d (stream-conn), " - "buffers %zu-%zu (stream-conn)", - stream->id, result, - nghttp2_session_get_stream_remote_window_size( - ctx->h2, stream->id), - nghttp2_session_get_remote_window_size(ctx->h2), - Curl_bufq_len(&stream->sendbuf), - Curl_bufq_len(&ctx->outbufq)); - } - else { - CURL_TRC_CF(data, cf, "flush -> %d, " - "connection-window=%d, nw_send_buffer(%zu)", - result, nghttp2_session_get_remote_window_size(ctx->h2), - Curl_bufq_len(&ctx->outbufq)); - } - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode cf_h2_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct cf_call_data save; - curl_socket_t sock; - bool want_recv, want_send; - CURLcode result = CURLE_OK; - - if(!ctx->h2) - return CURLE_OK; - - sock = Curl_conn_cf_get_socket(cf, data); - Curl_pollset_check(data, ps, sock, &want_recv, &want_send); - if(want_recv || want_send) { - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - bool c_exhaust, s_exhaust; - - CF_DATA_SAVE(save, cf, data); - c_exhaust = want_send && !nghttp2_session_get_remote_window_size(ctx->h2); - s_exhaust = want_send && stream && stream->id >= 0 && - !nghttp2_session_get_stream_remote_window_size(ctx->h2, - stream->id); - want_recv = (want_recv || c_exhaust || s_exhaust); - want_send = (!s_exhaust && want_send) || - (!c_exhaust && nghttp2_session_want_write(ctx->h2)) || - !Curl_bufq_is_empty(&ctx->outbufq); - - result = Curl_pollset_set(data, ps, sock, want_recv, want_send); - CF_DATA_RESTORE(cf, save); - } - else if(ctx->sent_goaway && !cf->shutdown) { - /* shutdown in progress */ - CF_DATA_SAVE(save, cf, data); - want_send = nghttp2_session_want_write(ctx->h2) || - !Curl_bufq_is_empty(&ctx->outbufq); - want_recv = nghttp2_session_want_read(ctx->h2); - result = Curl_pollset_set(data, ps, sock, want_recv, want_send); - CF_DATA_RESTORE(cf, save); - } - return result; -} - -static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream; - CURLcode result = CURLE_OUT_OF_MEMORY; - int rc; - nghttp2_session_callbacks *cbs = NULL; - - DEBUGASSERT(!ctx->h2); - DEBUGASSERT(ctx->initialized); - - rc = nghttp2_session_callbacks_new(&cbs); - if(rc) { - failf(data, "Could not initialize nghttp2 callbacks"); - goto out; - } - - nghttp2_session_callbacks_set_send_callback(cbs, send_callback); - nghttp2_session_callbacks_set_on_frame_recv_callback(cbs, on_frame_recv); - nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(cbs, - cf_h2_on_invalid_frame_recv); -#ifdef CURLVERBOSE - nghttp2_session_callbacks_set_on_frame_send_callback(cbs, on_frame_send); -#endif - nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - cbs, on_data_chunk_recv); - nghttp2_session_callbacks_set_on_stream_close_callback(cbs, on_stream_close); - nghttp2_session_callbacks_set_on_begin_headers_callback( - cbs, on_begin_headers); - nghttp2_session_callbacks_set_on_header_callback(cbs, on_header); -#ifdef CURLVERBOSE - nghttp2_session_callbacks_set_error_callback(cbs, error_callback); -#endif - - /* The nghttp2 session is not yet setup, do it */ - rc = h2_client_new(cf, cbs); - if(rc) { - failf(data, "Could not initialize nghttp2"); - goto out; - } - ctx->max_concurrent_streams = DEFAULT_MAX_CONCURRENT_STREAMS; - - if(ctx->via_h1_upgrade) { - /* HTTP/1.1 Upgrade issued. H2 Settings have already been submitted - * in the H1 request and we upgrade from there. This stream - * is opened implicitly as #1. */ - uint8_t binsettings[H2_BINSETTINGS_LEN]; - ssize_t rclen; - size_t binlen; /* length of the binsettings data */ - - rclen = populate_binsettings(binsettings, data); - - if(!curlx_sztouz(rclen, &binlen) || !binlen) { - failf(data, "nghttp2 unexpectedly failed on pack_settings_payload"); - result = CURLE_FAILED_INIT; - goto out; - } - - result = http2_data_setup(cf, data, &stream); - if(result) - goto out; - DEBUGASSERT(stream); - stream->id = 1; - /* queue SETTINGS frame (again) */ - rc = nghttp2_session_upgrade2(ctx->h2, binsettings, binlen, - data->state.httpreq == HTTPREQ_HEAD, - NULL); - if(rc) { - failf(data, "nghttp2_session_upgrade2() failed: %s(%d)", - nghttp2_strerror(rc), rc); - result = CURLE_HTTP2; - goto out; - } - - rc = nghttp2_session_set_stream_user_data(ctx->h2, stream->id, - data); - if(rc) { - infof(data, "http/2: failed to set user_data for stream %d", - stream->id); - DEBUGASSERT(0); - } - CURL_TRC_CF(data, cf, "created session via Upgrade"); - } - else { - nghttp2_settings_entry iv[H2_SETTINGS_IV_LEN]; - size_t ivlen; - - ivlen = populate_settings(iv, data, ctx); - rc = nghttp2_submit_settings(ctx->h2, NGHTTP2_FLAG_NONE, - iv, ivlen); - if(rc) { - failf(data, "nghttp2_submit_settings() failed: %s(%d)", - nghttp2_strerror(rc), rc); - result = CURLE_HTTP2; - goto out; - } - } - - rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0, - HTTP2_HUGE_WINDOW_SIZE); - if(rc) { - failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)", - nghttp2_strerror(rc), rc); - result = CURLE_HTTP2; - goto out; - } - - /* all set, traffic will be send on connect */ - result = CURLE_OK; - CURL_TRC_CF(data, cf, "[0] created h2 session%s", - ctx->via_h1_upgrade ? " (via h1 upgrade)" : ""); - -out: - if(cbs) - nghttp2_session_callbacks_del(cbs); - return result; -} - -static CURLcode cf_h2_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_h2_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - struct cf_call_data save; - bool first_time = FALSE; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* Connect the lower filters first */ - if(!cf->next->connected) { - result = Curl_conn_cf_connect(cf->next, data, done); - if(result || !*done) - return result; - } - - *done = FALSE; - - CF_DATA_SAVE(save, cf, data); - DEBUGASSERT(ctx->initialized); - if(!ctx->h2) { - result = cf_h2_ctx_open(cf, data); - if(result) - goto out; - first_time = TRUE; - } - - if(!first_time) { - result = h2_progress_ingress(cf, data, 0); - if(result) - goto out; - } - - /* Send out our SETTINGS and ACKs and such. If that blocks, we - * have it buffered and can count this filter as being connected */ - result = h2_progress_egress(cf, data); - if(result && (result != CURLE_AGAIN)) - goto out; - - *done = TRUE; - cf->connected = TRUE; - result = CURLE_OK; - -out: - CURL_TRC_CF(data, cf, "cf_connect() -> %d, %d, ", result, *done); - CF_DATA_RESTORE(cf, save); - return result; -} - -static void cf_h2_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - - if(ctx) { - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - cf_h2_ctx_close(ctx); - CF_DATA_RESTORE(cf, save); - cf->connected = FALSE; - } - if(cf->next) - cf->next->cft->do_close(cf->next, data); -} - -static void cf_h2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - - (void)data; - if(ctx) { - cf_h2_ctx_free(ctx); - cf->ctx = NULL; - } -} - -static CURLcode cf_h2_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct cf_call_data save; - CURLcode result; - int rv; - - if(!cf->connected || !ctx->h2 || cf->shutdown || ctx->conn_closed) { - *done = TRUE; - return CURLE_OK; - } - - CF_DATA_SAVE(save, cf, data); - - if(!ctx->sent_goaway) { - ctx->sent_goaway = TRUE; - rv = nghttp2_submit_goaway(ctx->h2, NGHTTP2_FLAG_NONE, - ctx->local_max_sid, 0, - (const uint8_t *)"shutdown", - sizeof("shutdown")); - if(rv) { - failf(data, "nghttp2_submit_goaway() failed: %s(%d)", - nghttp2_strerror(rv), rv); - result = CURLE_SEND_ERROR; - goto out; - } - } - /* GOAWAY submitted, process egress and ingress until nghttp2 is done. */ - result = CURLE_OK; - if(nghttp2_session_want_write(ctx->h2) || - !Curl_bufq_is_empty(&ctx->outbufq)) - result = h2_progress_egress(cf, data); - if(!result && nghttp2_session_want_read(ctx->h2)) - result = h2_progress_ingress(cf, data, 0); - - if(result == CURLE_AGAIN) - result = CURLE_OK; - - *done = (ctx->conn_closed || - (!result && !nghttp2_session_want_write(ctx->h2) && - !nghttp2_session_want_read(ctx->h2) && - Curl_bufq_is_empty(&ctx->outbufq))); - -out: - CF_DATA_RESTORE(cf, save); - cf->shutdown = (result || *done); - return result; -} - -static CURLcode http2_data_pause(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool pause) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - - DEBUGASSERT(data); - if(ctx && ctx->h2 && stream) { - CURLcode result; - - stream->write_paused = pause; - result = cf_h2_update_local_win(cf, data, stream); - if(result) - return result; - - /* attempt to send the window update */ - (void)h2_progress_egress(cf, data); - - if(!pause) { - /* Unpausing a h2 transfer, requires it to be run again. The server - * may send new DATA on us increasing the flow window, and it may - * not. We may have already buffered and exhausted the new window - * by operating on things in flight during the handling of other - * transfers. */ - Curl_multi_mark_dirty(data); - } - CURL_TRC_CF(data, cf, "[%d] stream now %spaused", stream->id, - pause ? "" : "un"); - } - return CURLE_OK; -} - -static CURLcode cf_h2_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - CURLcode result = CURLE_OK; - struct cf_call_data save; - - (void)arg2; - - CF_DATA_SAVE(save, cf, data); - switch(event) { - case CF_CTRL_DATA_SETUP: - break; - case CF_CTRL_DATA_PAUSE: - result = http2_data_pause(cf, data, (arg1 != 0)); - break; - case CF_CTRL_FLUSH: - result = cf_h2_flush(cf, data); - break; - case CF_CTRL_DATA_DONE: - http2_data_done(cf, data); - break; - case CF_CTRL_CONN_INFO_UPDATE: - if(!cf->sockindex && cf->connected) { - cf->conn->httpversion_seen = 20; - Curl_conn_set_multiplex(cf->conn); - } - break; - default: - break; - } - CF_DATA_RESTORE(cf, save); - return result; -} - -static bool cf_h2_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct cf_h2_ctx *ctx = cf->ctx; - - if(ctx && !Curl_bufq_is_empty(&ctx->inbufq)) - return TRUE; - return cf->next ? cf->next->cft->has_data_pending(cf->next, data) : FALSE; -} - -static bool cf_h2_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending) -{ - struct cf_h2_ctx *ctx = cf->ctx; - bool alive; - struct cf_call_data save; - - *input_pending = FALSE; - CF_DATA_SAVE(save, cf, data); - alive = (ctx && ctx->h2 && http2_connisalive(cf, data, input_pending)); - CURL_TRC_CF(data, cf, "conn alive -> %d, input_pending=%d", - alive, *input_pending); - CF_DATA_RESTORE(cf, save); - return alive; -} - -static CURLcode cf_h2_keep_alive(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURLcode result; - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - result = http2_send_ping(cf, data); - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode cf_h2_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_h2_ctx *ctx = cf->ctx; - struct cf_call_data save; - size_t effective_max; - - switch(query) { - case CF_QUERY_MAX_CONCURRENT: - DEBUGASSERT(pres1); - - CF_DATA_SAVE(save, cf, data); - if(!ctx->h2 || !nghttp2_session_check_request_allowed(ctx->h2)) { - /* the limit is what we have in use right now */ - effective_max = cf->conn->attached_xfers; - } - else { - effective_max = ctx->max_concurrent_streams; - } - *pres1 = (effective_max > INT_MAX) ? INT_MAX : (int)effective_max; - CF_DATA_RESTORE(cf, save); - return CURLE_OK; - case CF_QUERY_STREAM_ERROR: { - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - *pres1 = stream ? (int)stream->error : 0; - return CURLE_OK; - } - case CF_QUERY_NEED_FLUSH: { - struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data); - if(!Curl_bufq_is_empty(&ctx->outbufq) || - (stream && !Curl_bufq_is_empty(&stream->sendbuf))) { - *pres1 = TRUE; - return CURLE_OK; - } - break; - } - case CF_QUERY_HTTP_VERSION: - *pres1 = 20; - return CURLE_OK; - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -struct Curl_cftype Curl_cft_nghttp2 = { - "HTTP/2", - CF_TYPE_MULTIPLEX | CF_TYPE_HTTP, - CURL_LOG_LVL_NONE, - cf_h2_destroy, - cf_h2_connect, - cf_h2_close, - cf_h2_shutdown, - cf_h2_adjust_pollset, - cf_h2_data_pending, - cf_h2_send, - cf_h2_recv, - cf_h2_cntrl, - cf_h2_is_alive, - cf_h2_keep_alive, - cf_h2_query, -}; - -static CURLcode http2_cfilter_add(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - int sockindex, - bool via_h1_upgrade) -{ - struct Curl_cfilter *cf = NULL; - struct cf_h2_ctx *ctx; - CURLcode result = CURLE_OUT_OF_MEMORY; - - DEBUGASSERT(data->conn); - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) - goto out; - cf_h2_ctx_init(ctx, via_h1_upgrade); - - result = Curl_cf_create(&cf, &Curl_cft_nghttp2, ctx); - if(result) - goto out; - - ctx = NULL; - Curl_conn_cf_add(data, conn, sockindex, cf); - -out: - if(result) - cf_h2_ctx_free(ctx); - *pcf = result ? NULL : cf; - return result; -} - -static CURLcode http2_cfilter_insert_after(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool via_h1_upgrade) -{ - struct Curl_cfilter *cf_h2 = NULL; - struct cf_h2_ctx *ctx; - CURLcode result = CURLE_OUT_OF_MEMORY; - - (void)data; - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) - goto out; - cf_h2_ctx_init(ctx, via_h1_upgrade); - - result = Curl_cf_create(&cf_h2, &Curl_cft_nghttp2, ctx); - if(result) - goto out; - - ctx = NULL; - Curl_conn_cf_insert_after(cf, cf_h2); - -out: - if(result) - cf_h2_ctx_free(ctx); - return result; -} - -bool Curl_http2_may_switch(struct Curl_easy *data) -{ - if(Curl_conn_http_version(data, data->conn) < 20 && - (data->state.http_neg.wanted & CURL_HTTP_V2x) && - data->state.http_neg.h2_prior_knowledge) { -#ifndef CURL_DISABLE_PROXY - if(data->conn->bits.httpproxy && !data->conn->bits.tunnel_proxy) { - /* We do not support HTTP/2 proxies yet. Also it is debatable - whether or not this setting should apply to HTTP/2 proxies. */ - infof(data, "Ignoring HTTP/2 prior knowledge due to proxy"); - return FALSE; - } -#endif - return TRUE; - } - return FALSE; -} - -CURLcode Curl_http2_switch(struct Curl_easy *data) -{ - struct Curl_cfilter *cf; - CURLcode result; - - DEBUGASSERT(Curl_conn_http_version(data, data->conn) < 20); - - result = http2_cfilter_add(&cf, data, data->conn, FIRSTSOCKET, FALSE); - if(result) - return result; - CURL_TRC_CF(data, cf, "switching connection to HTTP/2"); - - if(cf->next) { - bool done; - return Curl_conn_cf_connect(cf, data, &done); - } - return CURLE_OK; -} - -CURLcode Curl_http2_switch_at(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct Curl_cfilter *cf_h2; - CURLcode result; - - DEBUGASSERT(Curl_conn_http_version(data, data->conn) < 20); - - result = http2_cfilter_insert_after(cf, data, FALSE); - if(result) - return result; - - cf_h2 = cf->next; - - if(cf_h2->next) { - bool done; - return Curl_conn_cf_connect(cf_h2, data, &done); - } - return CURLE_OK; -} - -CURLcode Curl_http2_upgrade(struct Curl_easy *data, - struct connectdata *conn, int sockindex, - const char *mem, size_t nread) -{ - struct Curl_cfilter *cf; - struct cf_h2_ctx *ctx; - CURLcode result; - - DEBUGASSERT(Curl_conn_http_version(data, conn) < 20); - - result = http2_cfilter_add(&cf, data, conn, sockindex, TRUE); - if(result) - return result; - CURL_TRC_CF(data, cf, "upgrading connection to HTTP/2"); - - DEBUGASSERT(cf->cft == &Curl_cft_nghttp2); - ctx = cf->ctx; - - data->req.httpversion_sent = 20; /* it is an h2 request now */ - data->req.header = TRUE; /* we expect the real response to come in h2 */ - data->req.headerline = 0; /* restart the header line counter */ - - if(nread > 0) { - /* Remaining data from the protocol switch reply is already using - * the switched protocol, ie. HTTP/2. We add that to the network - * inbufq. */ - size_t copied; - - result = Curl_bufq_write(&ctx->inbufq, - (const unsigned char *)mem, nread, &copied); - if(result) { - failf(data, "error on copying HTTP Upgrade response: %d", result); - return CURLE_RECV_ERROR; - } - if(copied < nread) { - failf(data, "connection buffer size could not take all data " - "from HTTP Upgrade response header: copied=%zu, datalen=%zu", - copied, nread); - return CURLE_HTTP2; - } - infof(data, "Copied HTTP/2 data in stream buffer to connection buffer" - " after upgrade: len=%zu", nread); - } - - if(cf->next) { - bool done; - result = Curl_conn_cf_connect(cf, data, &done); - if(!result) - cf->cft->cntrl(cf, data, CF_CTRL_CONN_INFO_UPDATE, 0, NULL); - } - return result; -} - -/* Only call this function for a transfer that already got an HTTP/2 - CURLE_HTTP2_STREAM error! */ -bool Curl_h2_http_1_1_error(struct Curl_easy *data) -{ - if(Curl_conn_http_version(data, data->conn) == 20) { - int err = Curl_conn_get_stream_error(data, data->conn, FIRSTSOCKET); - return err == NGHTTP2_HTTP_1_1_REQUIRED; - } - return FALSE; -} - -void *Curl_nghttp2_malloc(size_t size, void *user_data) -{ - (void)user_data; - return Curl_cmalloc(size); -} - -void Curl_nghttp2_free(void *ptr, void *user_data) -{ - (void)user_data; - Curl_cfree(ptr); -} - -void *Curl_nghttp2_calloc(size_t nmemb, size_t size, void *user_data) -{ - (void)user_data; - return Curl_ccalloc(nmemb, size); -} - -void *Curl_nghttp2_realloc(void *ptr, size_t size, void *user_data) -{ - (void)user_data; - return Curl_crealloc(ptr, size); -} - -#else /* CURL_DISABLE_HTTP || !USE_NGHTTP2 */ - -/* Satisfy external references even if http2 is not compiled in. */ - -char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) -{ - (void)h; - (void)num; - return NULL; -} - -char *curl_pushheader_byname(struct curl_pushheaders *h, const char *name) -{ - (void)h; - (void)name; - return NULL; -} - -#endif /* !CURL_DISABLE_HTTP && USE_NGHTTP2 */ diff --git a/vendor/curl/lib/http2.h b/vendor/curl/lib/http2.h deleted file mode 100644 index e38dc5745..000000000 --- a/vendor/curl/lib/http2.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef HEADER_CURL_HTTP2_H -#define HEADER_CURL_HTTP2_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_NGHTTP2 - -/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting - from the peer */ -#define DEFAULT_MAX_CONCURRENT_STREAMS 100 - -/* - * Store nghttp2 version info in this buffer. - */ -void Curl_http2_ver(char *p, size_t len); - -#ifdef CURLVERBOSE -int Curl_nghttp2_fr_print(const nghttp2_frame *frame, char *buffer, - size_t blen); -#endif - -CURLcode Curl_http2_request_upgrade(struct dynbuf *req, - struct Curl_easy *data); - -/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */ -bool Curl_h2_http_1_1_error(struct Curl_easy *data); - -bool Curl_http2_may_switch(struct Curl_easy *data); - -CURLcode Curl_http2_switch(struct Curl_easy *data); - -CURLcode Curl_http2_switch_at(struct Curl_cfilter *cf, struct Curl_easy *data); - -CURLcode Curl_http2_upgrade(struct Curl_easy *data, - struct connectdata *conn, int sockindex, - const char *mem, size_t nread); - -void *Curl_nghttp2_malloc(size_t size, void *user_data); -void Curl_nghttp2_free(void *ptr, void *user_data); -void *Curl_nghttp2_calloc(size_t nmemb, size_t size, void *user_data); -void *Curl_nghttp2_realloc(void *ptr, size_t size, void *user_data); - -extern struct Curl_cftype Curl_cft_nghttp2; - -#else /* USE_NGHTTP2 */ - -#define Curl_http2_may_switch(a) FALSE - -#define Curl_http2_request_upgrade(x, y) CURLE_UNSUPPORTED_PROTOCOL -#define Curl_http2_switch(a) CURLE_UNSUPPORTED_PROTOCOL -#define Curl_h2_http_1_1_error(x) 0 -#endif - -#endif /* HEADER_CURL_HTTP2_H */ diff --git a/vendor/curl/lib/http_aws_sigv4.c b/vendor/curl/lib/http_aws_sigv4.c deleted file mode 100644 index 55efa1204..000000000 --- a/vendor/curl/lib/http_aws_sigv4.c +++ /dev/null @@ -1,1135 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_AWS) - -#include "urldata.h" -#include "strcase.h" -#include "curlx/strdup.h" -#include "http_aws_sigv4.h" -#include "curl_sha256.h" -#include "transfer.h" -#include "curl_trc.h" -#include "escape.h" -#include "curlx/strparse.h" -#include "slist.h" - -#include - -#define HMAC_SHA256(k, kl, d, dl, o) \ - do { \ - result = Curl_hmacit(&Curl_HMAC_SHA256, \ - (const unsigned char *)(k), \ - kl, \ - (const unsigned char *)(d), \ - dl, o); \ - if(result) { \ - goto fail; \ - } \ - } while(0) - -#define TIMESTAMP_SIZE 17 - -/* hex-encoded with trailing null */ -#define SHA256_HEX_LENGTH ((2 * CURL_SHA256_DIGEST_LENGTH) + 1) - -#define MAX_QUERY_COMPONENTS 128 - -struct pair { - struct dynbuf key; - struct dynbuf value; -}; - -static void sha256_to_hex(char *dst, unsigned char *sha) -{ - Curl_hexencode(sha, CURL_SHA256_DIGEST_LENGTH, - (unsigned char *)dst, SHA256_HEX_LENGTH); -} - -static char *find_date_hdr(struct Curl_easy *data, const char *sig_hdr) -{ - char *tmp = Curl_checkheaders(data, sig_hdr, strlen(sig_hdr)); - - if(tmp) - return tmp; - return Curl_checkheaders(data, STRCONST("Date")); -} - -/* remove whitespace, and lowercase all headers */ -static void trim_headers(struct curl_slist *head) -{ - struct curl_slist *l; - for(l = head; l; l = l->next) { - const char *value; /* to read from */ - char *store; - size_t colon = strcspn(l->data, ":"); - Curl_strntolower(l->data, l->data, colon); - - value = &l->data[colon]; - if(!*value) - continue; - ++value; - store = (char *)CURL_UNCONST(value); - - /* skip leading whitespace */ - curlx_str_passblanks(&value); - - while(*value) { - int space = 0; - while(ISBLANK(*value)) { - value++; - space++; - } - if(space) { - /* replace any number of consecutive whitespace with a single space, - unless at the end of the string, then nothing */ - if(*value) - *store++ = ' '; - } - else - *store++ = *value++; - } - *store = 0; /* null-terminate */ - } -} - -/* - * Frees all allocated strings in a dynbuf pair array, and the dynbuf itself - */ -static void pair_array_free(struct pair *pair_array, size_t num_elements) -{ - size_t index; - - for(index = 0; index != num_elements; index++) { - curlx_dyn_free(&pair_array[index].key); - curlx_dyn_free(&pair_array[index].value); - } -} - -/* - * Frees all allocated strings in a split dynbuf, and the dynbuf itself - */ -static void dyn_array_free(struct dynbuf *db, size_t num_elements) -{ - size_t index; - - for(index = 0; index < num_elements; index++) - curlx_dyn_free((&db[index])); -} - -/* - * Splits source string by SPLIT_BY, and creates an array of dynbuf in db. - * db is initialized by this function. - * Caller is responsible for freeing the array elements with dyn_array_free - */ - -#define SPLIT_BY '&' - -static CURLcode split_to_dyn_array(const char *source, - struct dynbuf db[MAX_QUERY_COMPONENTS], - size_t *num_splits_out) -{ - CURLcode result = CURLE_OK; - size_t len = strlen(source); - size_t pos; /* Position in result buffer */ - size_t start = 0; /* Start of current segment */ - size_t segment_length = 0; - size_t index = 0; - size_t num_splits = 0; - - /* Split source_ptr on SPLIT_BY and store the segment offsets and length in - * array */ - for(pos = 0; pos < len; pos++) { - if(source[pos] == SPLIT_BY) { - if(segment_length) { - curlx_dyn_init(&db[index], segment_length + 1); - result = curlx_dyn_addn(&db[index], &source[start], segment_length); - if(result) - goto fail; - - segment_length = 0; - index++; - if(++num_splits == MAX_QUERY_COMPONENTS) { - result = CURLE_TOO_LARGE; - goto fail; - } - } - start = pos + 1; - } - else { - segment_length++; - } - } - - if(segment_length) { - curlx_dyn_init(&db[index], segment_length + 1); - result = curlx_dyn_addn(&db[index], &source[start], segment_length); - if(!result) { - if(++num_splits == MAX_QUERY_COMPONENTS) - result = CURLE_TOO_LARGE; - } - } -fail: - *num_splits_out = num_splits; - return result; -} - -static bool is_reserved_char(const char c) -{ - return (ISALNUM(c) || ISURLPUNTCS(c)); -} - -static CURLcode uri_encode_path(struct Curl_str *original_path, - struct dynbuf *new_path) -{ - const char *p = curlx_str(original_path); - size_t i; - - for(i = 0; i < curlx_strlen(original_path); i++) { - /* Do not encode slashes or unreserved chars from RFC 3986 */ - CURLcode result = CURLE_OK; - unsigned char c = p[i]; - if(is_reserved_char(c) || c == '/') - result = curlx_dyn_addn(new_path, &c, 1); - else - result = curlx_dyn_addf(new_path, "%%%02X", c); - if(result) - return result; - } - - return CURLE_OK; -} - -/* Normalize the query part. Make sure %2B is left percent encoded, and not - decoded to plus, then encoded to space. -*/ -static CURLcode normalize_query(const char *string, size_t len, - struct dynbuf *db) -{ - CURLcode result = CURLE_OK; - - while(len && !result) { - unsigned char in = (unsigned char)*string; - if(('%' == in) && (len > 2) && - ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { - /* this is two hexadecimal digits following a '%' */ - in = (unsigned char)((curlx_hexval(string[1]) << 4) | - curlx_hexval(string[2])); - string += 3; - len -= 3; - if(in == '+') { - /* decodes to plus, so leave this encoded */ - result = curlx_dyn_addn(db, "%2B", 3); - continue; - } - } - else { - string++; - len--; - } - - if(is_reserved_char(in)) - /* Escape unreserved chars from RFC 3986 */ - result = curlx_dyn_addn(db, &in, 1); - else if(in == '+') - /* Encode '+' as space */ - result = curlx_dyn_add(db, "%20"); - else - result = curlx_dyn_addf(db, "%%%02X", in); - } - - return result; -} - -static bool should_urlencode(struct Curl_str *service_name) -{ - /* - * These services require unmodified (not additionally URL-encoded) URL - * paths. - * should_urlencode == true is equivalent to should_urlencode_uri_path - * from the AWS SDK. Urls are already normalized by the curl URL parser - */ - - if(curlx_str_cmp(service_name, "s3") || - curlx_str_cmp(service_name, "s3-express") || - curlx_str_cmp(service_name, "s3-outposts")) { - return false; - } - return true; -} - -/* maximum length for the aws sivg4 parts */ -#define MAX_SIGV4_LEN 64 -#define DATE_HDR_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Date")) - -/* string been x-PROVIDER-date:TIMESTAMP, I need +1 for ':' */ -#define DATE_FULL_HDR_LEN (DATE_HDR_KEY_LEN + TIMESTAMP_SIZE + 1) - -/* alphabetically compare two headers by their name, expecting - headers to use ':' at this point */ -static int compare_header_names(const char *a, const char *b) -{ - const char *colon_a; - const char *colon_b; - size_t len_a; - size_t len_b; - size_t min_len; - int cmp; - - colon_a = strchr(a, ':'); - colon_b = strchr(b, ':'); - - DEBUGASSERT(colon_a); - DEBUGASSERT(colon_b); - - len_a = colon_a ? (size_t)(colon_a - a) : strlen(a); - len_b = colon_b ? (size_t)(colon_b - b) : strlen(b); - - min_len = (len_a < len_b) ? len_a : len_b; - - cmp = strncmp(a, b, min_len); - - /* return the shorter of the two if one is shorter */ - if(!cmp) - return (int)(len_a - len_b); - - return cmp; -} - -/* Merge duplicate header definitions by comma delimiting their values - in the order defined the headers are defined, expecting headers to - be alpha-sorted and use ':' at this point */ -static CURLcode merge_duplicate_headers(struct curl_slist *head) -{ - struct curl_slist *curr = head; - CURLcode result = CURLE_OK; - - while(curr) { - struct curl_slist *next = curr->next; - if(!next) - break; - - if(compare_header_names(curr->data, next->data) == 0) { - struct dynbuf buf; - const char *colon_next; - const char *val_next; - - curlx_dyn_init(&buf, CURL_MAX_HTTP_HEADER); - - result = curlx_dyn_add(&buf, curr->data); - if(result) - return result; - - colon_next = strchr(next->data, ':'); - DEBUGASSERT(colon_next); - val_next = colon_next + 1; - - result = curlx_dyn_addn(&buf, ",", 1); - if(result) - return result; - - result = curlx_dyn_add(&buf, val_next); - if(result) - return result; - - curlx_free(curr->data); - curr->data = curlx_dyn_ptr(&buf); - - curr->next = next->next; - curlx_free(next->data); - curlx_free(next); - } - else { - curr = curr->next; - } - } - - return CURLE_OK; -} - -/* timestamp should point to a buffer of at last TIMESTAMP_SIZE bytes */ -static CURLcode make_headers(struct Curl_easy *data, - const char *hostname, - char *timestamp, - const char *provider1, - size_t plen, /* length of provider1 */ - char **date_header, - char *content_sha256_header, - struct dynbuf *canonical_headers, - struct dynbuf *signed_headers) -{ - char date_hdr_key[DATE_HDR_KEY_LEN]; - char date_full_hdr[DATE_FULL_HDR_LEN]; - struct curl_slist *head = NULL; - struct curl_slist *tmp_head = NULL; - CURLcode ret = CURLE_OUT_OF_MEMORY; - struct curl_slist *l; - bool again = TRUE; - - curl_msnprintf(date_hdr_key, DATE_HDR_KEY_LEN, "X-%.*s-Date", - (int)plen, provider1); - /* provider1 ucfirst */ - Curl_strntolower(&date_hdr_key[2], provider1, plen); - date_hdr_key[2] = Curl_raw_toupper(provider1[0]); - - curl_msnprintf(date_full_hdr, DATE_FULL_HDR_LEN, - "x-%.*s-date:%s", (int)plen, provider1, timestamp); - /* provider1 lowercase */ - Curl_strntolower(&date_full_hdr[2], provider1, plen); - - if(!Curl_checkheaders(data, STRCONST("Host"))) { - char *fullhost; - - if(data->state.aptr.host) { - /* remove /r/n as the separator for canonical request must be '\n' */ - size_t pos = strcspn(data->state.aptr.host, "\n\r"); - fullhost = curlx_memdup0(data->state.aptr.host, pos); - } - else - fullhost = curl_maprintf("host:%s", hostname); - - if(fullhost) - head = Curl_slist_append_nodup(NULL, fullhost); - if(!head) { - curlx_free(fullhost); - goto fail; - } - } - - if(*content_sha256_header) { - tmp_head = curl_slist_append(head, content_sha256_header); - if(!tmp_head) - goto fail; - head = tmp_head; - } - - /* copy user headers to our header list. the logic is based on how http.c - handles user headers. - - user headers in format 'name:' with no value are used to signal that an - internal header of that name should be removed. those user headers are not - added to this list. - - user headers in format 'name;' with no value are used to signal that a - header of that name with no value should be sent. those user headers are - added to this list but in the format that they will be sent, ie the - semi-colon is changed to a colon for format 'name:'. - - user headers with a value of whitespace only, or without a colon or - semi-colon, are not added to this list. - */ - for(l = data->set.headers; l; l = l->next) { - char *dupdata; - const char *ptr; - const char *sep = strchr(l->data, ':'); - if(!sep) - sep = strchr(l->data, ';'); - if(!sep || (*sep == ':' && !*(sep + 1))) - continue; - for(ptr = sep + 1; ISBLANK(*ptr); ++ptr) - ; - if(!*ptr && ptr != sep + 1) /* a value of whitespace only */ - continue; - dupdata = curlx_strdup(l->data); - if(!dupdata) - goto fail; - dupdata[sep - l->data] = ':'; - tmp_head = Curl_slist_append_nodup(head, dupdata); - if(!tmp_head) { - curlx_free(dupdata); - goto fail; - } - head = tmp_head; - } - - trim_headers(head); - - *date_header = find_date_hdr(data, date_hdr_key); - if(!*date_header) { - tmp_head = curl_slist_append(head, date_full_hdr); - if(!tmp_head) - goto fail; - head = tmp_head; - *date_header = curl_maprintf("%s: %s\r\n", date_hdr_key, timestamp); - if(!*date_header) - goto fail; - } - else { - const char *value; - const char *endp; - value = strchr(*date_header, ':'); - if(!value) { - *date_header = NULL; - goto fail; - } - ++value; - curlx_str_passblanks(&value); - endp = value; - while(*endp && ISALNUM(*endp)) - ++endp; - /* 16 bytes => "19700101T000000Z" */ - if((endp - value) == TIMESTAMP_SIZE - 1) { - memcpy(timestamp, value, TIMESTAMP_SIZE - 1); - timestamp[TIMESTAMP_SIZE - 1] = 0; - } - else - /* bad timestamp length */ - timestamp[0] = 0; - *date_header = NULL; - } - - /* alpha-sort by header name in a case sensitive manner */ - do { - again = FALSE; - for(l = head; l; l = l->next) { - struct curl_slist *next = l->next; - - if(next && compare_header_names(l->data, next->data) > 0) { - char *tmp = l->data; - - l->data = next->data; - next->data = tmp; - again = TRUE; - } - } - } while(again); - - ret = merge_duplicate_headers(head); - if(ret) - goto fail; - - for(l = head; l; l = l->next) { - char *tmp; - - if(curlx_dyn_add(canonical_headers, l->data)) - goto fail; - if(curlx_dyn_add(canonical_headers, "\n")) - goto fail; - - tmp = strchr(l->data, ':'); - if(tmp) - *tmp = 0; - - if(l != head) { - if(curlx_dyn_add(signed_headers, ";")) - goto fail; - } - if(curlx_dyn_add(signed_headers, l->data)) - goto fail; - } - - ret = CURLE_OK; -fail: - curl_slist_free_all(head); - - return ret; -} - -#define CONTENT_SHA256_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Content-Sha256")) -/* add 2 for ": " between header name and value */ -#define CONTENT_SHA256_HDR_LEN (CONTENT_SHA256_KEY_LEN + 2 + SHA256_HEX_LENGTH) - -/* try to parse a payload hash from the content-sha256 header */ -static const char *parse_content_sha_hdr(struct Curl_easy *data, - const char *provider1, - size_t plen, - size_t *value_len) -{ - char key[CONTENT_SHA256_KEY_LEN]; - size_t key_len; - const char *value; - size_t len; - - key_len = curl_msnprintf(key, sizeof(key), "x-%.*s-content-sha256", - (int)plen, provider1); - - value = Curl_checkheaders(data, key, key_len); - if(!value) - return NULL; - - value = strchr(value, ':'); - if(!value) - return NULL; - ++value; - - curlx_str_passblanks(&value); - - len = strlen(value); - while(len > 0 && ISBLANK(value[len - 1])) - --len; - - *value_len = len; - return value; -} - -static CURLcode calc_payload_hash(struct Curl_easy *data, - unsigned char *sha_hash, char *sha_hex) -{ - const char *post_data = data->set.postfields; - size_t post_data_len = 0; - CURLcode result; - - if(post_data) { - if(data->set.postfieldsize < 0) - post_data_len = strlen(post_data); - else - post_data_len = (size_t)data->set.postfieldsize; - } - result = Curl_sha256it(sha_hash, (const unsigned char *)post_data, - post_data_len); - if(!result) - sha256_to_hex(sha_hex, sha_hash); - return result; -} - -#define S3_UNSIGNED_PAYLOAD "UNSIGNED-PAYLOAD" - -static CURLcode calc_s3_payload_hash(struct Curl_easy *data, - Curl_HttpReq httpreq, - const char *provider1, - size_t plen, - unsigned char *sha_hash, - char *sha_hex, char *header) -{ - bool empty_method = (httpreq == HTTPREQ_GET || httpreq == HTTPREQ_HEAD); - /* The request method or filesize indicate no request payload */ - bool empty_payload = (empty_method || data->set.filesize == 0); - /* The POST payload is in memory */ - bool post_payload = (httpreq == HTTPREQ_POST && data->set.postfields); - CURLcode ret = CURLE_OUT_OF_MEMORY; - - if(empty_payload || post_payload) { - /* Calculate a real hash when we know the request payload */ - ret = calc_payload_hash(data, sha_hash, sha_hex); - if(ret) - goto fail; - } - else { - /* Fall back to s3's UNSIGNED-PAYLOAD */ - size_t len = sizeof(S3_UNSIGNED_PAYLOAD) - 1; - DEBUGASSERT(len < SHA256_HEX_LENGTH); /* 16 < 65 */ - memcpy(sha_hex, S3_UNSIGNED_PAYLOAD, len); - sha_hex[len] = 0; - } - - /* format the required content-sha256 header */ - curl_msnprintf(header, CONTENT_SHA256_HDR_LEN, - "x-%.*s-content-sha256: %s", (int)plen, provider1, sha_hex); - - ret = CURLE_OK; -fail: - return ret; -} - -static int compare_func(const void *a, const void *b) -{ - const struct pair *aa = a; - const struct pair *bb = b; - const size_t aa_key_len = curlx_dyn_len(&aa->key); - const size_t bb_key_len = curlx_dyn_len(&bb->key); - const size_t aa_value_len = curlx_dyn_len(&aa->value); - const size_t bb_value_len = curlx_dyn_len(&bb->value); - int compare; - - /* If one element is empty, the other is always sorted higher */ - - /* Compare keys */ - if((aa_key_len == 0) && (bb_key_len == 0)) - return 0; - if(aa_key_len == 0) - return -1; - if(bb_key_len == 0) - return 1; - compare = strcmp(curlx_dyn_ptr(&aa->key), curlx_dyn_ptr(&bb->key)); - if(compare) { - return compare; - } - - /* Compare values */ - if((aa_value_len == 0) && (bb_value_len == 0)) - return 0; - if(aa_value_len == 0) - return -1; - if(bb_value_len == 0) - return 1; - compare = strcmp(curlx_dyn_ptr(&aa->value), curlx_dyn_ptr(&bb->value)); - - return compare; -} - -/* @unittest 1979 */ -UNITTEST CURLcode canon_path(const char *q, size_t len, - struct dynbuf *new_path, - bool do_uri_encode); -UNITTEST CURLcode canon_path(const char *q, size_t len, - struct dynbuf *new_path, - bool do_uri_encode) -{ - CURLcode result = CURLE_OK; - - struct Curl_str original_path; - - curlx_str_assign(&original_path, q, len); - - /* Normalized path will be either the same or shorter than the original - * path, plus trailing slash */ - - if(do_uri_encode) - result = uri_encode_path(&original_path, new_path); - else - result = curlx_dyn_addn(new_path, q, len); - - if(!result) { - if(curlx_dyn_len(new_path) == 0) - result = curlx_dyn_add(new_path, "/"); - } - - return result; -} - -/* @unittest 1980 */ -UNITTEST CURLcode canon_query(const char *query, struct dynbuf *dq); -UNITTEST CURLcode canon_query(const char *query, struct dynbuf *dq) -{ - CURLcode result = CURLE_OK; - - struct dynbuf query_array[MAX_QUERY_COMPONENTS]; - struct pair encoded_query_array[MAX_QUERY_COMPONENTS]; - size_t num_query_components; - size_t counted_query_components = 0; - size_t index; - - if(!query) - return result; - - result = split_to_dyn_array(query, &query_array[0], &num_query_components); - if(result) { - goto fail; - } - - /* Create list of pairs, each pair containing an encoded query - * component */ - - for(index = 0; index < num_query_components; index++) { - const char *in_key; - size_t in_key_len; - const char *offset; - size_t query_part_len = curlx_dyn_len(&query_array[index]); - const char *query_part = curlx_dyn_ptr(&query_array[index]); - - in_key = query_part; - - offset = strchr(query_part, '='); - /* If there is no equals, this key has no value */ - if(!offset) { - in_key_len = strlen(in_key); - } - else { - in_key_len = offset - in_key; - } - - curlx_dyn_init(&encoded_query_array[index].key, - (query_part_len * 3) + 1); - curlx_dyn_init(&encoded_query_array[index].value, - (query_part_len * 3) + 1); - counted_query_components++; - - /* Decode/encode the key */ - result = normalize_query(in_key, in_key_len, - &encoded_query_array[index].key); - if(result) { - goto fail; - } - - /* Decode/encode the value if it exists */ - if(offset && offset != (query_part + query_part_len - 1)) { - size_t in_value_len; - const char *in_value = offset + 1; - in_value_len = query_part + query_part_len - (offset + 1); - result = normalize_query(in_value, in_value_len, - &encoded_query_array[index].value); - if(result) { - goto fail; - } - } - else { - /* If there is no value, the value is an empty string */ - curlx_dyn_init(&encoded_query_array[index].value, 2); - result = curlx_dyn_addn(&encoded_query_array[index].value, "", 1); - } - - if(result) { - goto fail; - } - } - - /* Sort the encoded query components by key and value */ - qsort(&encoded_query_array, num_query_components, - sizeof(struct pair), compare_func); - - /* Append the query components together to make a full query string */ - for(index = 0; index < num_query_components; index++) { - - if(index) - result = curlx_dyn_addn(dq, "&", 1); - if(!result) { - const char *key_ptr = curlx_dyn_ptr(&encoded_query_array[index].key); - const char *value_ptr = curlx_dyn_ptr(&encoded_query_array[index].value); - size_t vlen = curlx_dyn_len(&encoded_query_array[index].value); - if(value_ptr && vlen) { - result = curlx_dyn_addf(dq, "%s=%s", key_ptr, value_ptr); - } - else { - /* Empty value is always encoded to key= */ - result = curlx_dyn_addf(dq, "%s=", key_ptr); - } - } - if(result) - break; - } - -fail: - if(counted_query_components) - /* the encoded_query_array might not be initialized yet */ - pair_array_free(&encoded_query_array[0], counted_query_components); - dyn_array_free(&query_array[0], num_query_components); - return result; -} - -CURLcode Curl_output_aws_sigv4(struct Curl_easy *data) -{ - CURLcode result = CURLE_OUT_OF_MEMORY; - struct connectdata *conn = data->conn; - const char *line; - struct Curl_str provider0; - struct Curl_str provider1; - struct Curl_str region = { NULL, 0 }; - struct Curl_str service = { NULL, 0 }; - const char *hostname = conn->host.name; - time_t clock; - struct tm tm; - char timestamp[TIMESTAMP_SIZE]; - char date[9]; - struct dynbuf canonical_headers; - struct dynbuf signed_headers; - struct dynbuf canonical_query; - struct dynbuf canonical_path; - char *date_header = NULL; - Curl_HttpReq httpreq; - const char *method = NULL; - const char *payload_hash = NULL; - size_t payload_hash_len = 0; - unsigned char sha_hash[CURL_SHA256_DIGEST_LENGTH]; - char sha_hex[SHA256_HEX_LENGTH]; - char content_sha256_hdr[CONTENT_SHA256_HDR_LEN + 2] = ""; /* add \r\n */ - char *canonical_request = NULL; - char *request_type = NULL; - char *credential_scope = NULL; - char *str_to_sign = NULL; - const char *user = data->state.aptr.user ? data->state.aptr.user : ""; - char *secret = NULL; - unsigned char sign0[CURL_SHA256_DIGEST_LENGTH] = { 0 }; - unsigned char sign1[CURL_SHA256_DIGEST_LENGTH] = { 0 }; - char *auth_headers = NULL; - - if(data->set.path_as_is) { - failf(data, "Cannot use sigv4 authentication with path-as-is flag"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - if(Curl_checkheaders(data, STRCONST("Authorization"))) { - /* Authorization already present, Bailing out */ - return CURLE_OK; - } - - /* we init those buffers here, so goto fail will free initialized dynbuf */ - curlx_dyn_init(&canonical_headers, CURL_MAX_HTTP_HEADER); - curlx_dyn_init(&canonical_query, CURL_MAX_HTTP_HEADER); - curlx_dyn_init(&signed_headers, CURL_MAX_HTTP_HEADER); - curlx_dyn_init(&canonical_path, CURL_MAX_HTTP_HEADER); - - /* - * Parameters parsing - * Google and Outscale use the same OSC or GOOG, - * but Amazon uses AWS and AMZ for header arguments. - * AWS is the default because most of non-amazon providers - * are still using aws:amz as a prefix. - */ - line = data->set.str[STRING_AWS_SIGV4]; - if(!line || !*line) - line = "aws:amz"; - - /* provider0[:provider1[:region[:service]]] - - No string can be longer than N bytes of non-whitespace - */ - if(curlx_str_until(&line, &provider0, MAX_SIGV4_LEN, ':')) { - failf(data, "first aws-sigv4 provider cannot be empty"); - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto fail; - } - if(curlx_str_single(&line, ':') || - curlx_str_until(&line, &provider1, MAX_SIGV4_LEN, ':')) { - provider1 = provider0; - } - else if(curlx_str_single(&line, ':') || - curlx_str_until(&line, ®ion, MAX_SIGV4_LEN, ':') || - curlx_str_single(&line, ':') || - curlx_str_until(&line, &service, MAX_SIGV4_LEN, ':')) { - /* nothing to do */ - } - - if(!curlx_strlen(&service)) { - const char *p = hostname; - if(curlx_str_until(&p, &service, MAX_SIGV4_LEN, '.') || - curlx_str_single(&p, '.')) { - failf(data, "aws-sigv4: service missing in parameters and hostname"); - result = CURLE_URL_MALFORMAT; - goto fail; - } - - infof(data, "aws_sigv4: picked service %.*s from host", - (int)curlx_strlen(&service), curlx_str(&service)); - - if(!curlx_strlen(®ion)) { - if(curlx_str_until(&p, ®ion, MAX_SIGV4_LEN, '.') || - curlx_str_single(&p, '.')) { - failf(data, "aws-sigv4: region missing in parameters and hostname"); - result = CURLE_URL_MALFORMAT; - goto fail; - } - infof(data, "aws_sigv4: picked region %.*s from host", - (int)curlx_strlen(®ion), curlx_str(®ion)); - } - } - - Curl_http_method(data, &method, &httpreq); - - payload_hash = - parse_content_sha_hdr(data, curlx_str(&provider1), - curlx_strlen(&provider1), &payload_hash_len); - - if(!payload_hash) { - /* AWS S3 requires a x-amz-content-sha256 header, and supports special - * values like UNSIGNED-PAYLOAD */ - bool sign_as_s3 = curlx_str_casecompare(&provider0, "aws") && - curlx_str_casecompare(&service, "s3"); - - if(sign_as_s3) - result = calc_s3_payload_hash(data, httpreq, curlx_str(&provider1), - curlx_strlen(&provider1), sha_hash, - sha_hex, content_sha256_hdr); - else - result = calc_payload_hash(data, sha_hash, sha_hex); - if(result) - goto fail; - - payload_hash = sha_hex; - /* may be shorter than SHA256_HEX_LENGTH, like S3_UNSIGNED_PAYLOAD */ - payload_hash_len = strlen(sha_hex); - } - -#ifdef DEBUGBUILD - { - char *force_timestamp = getenv("CURL_FORCETIME"); - if(force_timestamp) - clock = 0; - else - clock = time(NULL); - } -#else - clock = time(NULL); -#endif - result = curlx_gmtime(clock, &tm); - if(result) { - goto fail; - } - if(!strftime(timestamp, sizeof(timestamp), "%Y%m%dT%H%M%SZ", &tm)) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - result = make_headers(data, hostname, timestamp, - curlx_str(&provider1), curlx_strlen(&provider1), - &date_header, content_sha256_hdr, - &canonical_headers, &signed_headers); - if(result) - goto fail; - - if(*content_sha256_hdr) { - /* make_headers() needed this without the \r\n for canonicalization */ - size_t hdrlen = strlen(content_sha256_hdr); - DEBUGASSERT(hdrlen + 3 < sizeof(content_sha256_hdr)); - memcpy(content_sha256_hdr + hdrlen, "\r\n", 3); - } - - memcpy(date, timestamp, sizeof(date)); - date[sizeof(date) - 1] = 0; - - result = canon_query(data->state.up.query, &canonical_query); - if(result) - goto fail; - - result = canon_path(data->state.up.path, strlen(data->state.up.path), - &canonical_path, - should_urlencode(&service)); - if(result) - goto fail; - result = CURLE_OUT_OF_MEMORY; - - canonical_request = - curl_maprintf("%s\n" /* HTTPRequestMethod */ - "%s\n" /* CanonicalURI */ - "%s\n" /* CanonicalQueryString */ - "%s\n" /* CanonicalHeaders */ - "%s\n" /* SignedHeaders */ - "%.*s", /* HashedRequestPayload in hex */ - method, - curlx_dyn_ptr(&canonical_path), - curlx_dyn_ptr(&canonical_query) ? - curlx_dyn_ptr(&canonical_query) : "", - curlx_dyn_ptr(&canonical_headers), - curlx_dyn_ptr(&signed_headers), - (int)payload_hash_len, payload_hash); - if(!canonical_request) - goto fail; - - infof(data, "aws_sigv4: Canonical request (enclosed in []) - [%s]", - canonical_request); - - request_type = curl_maprintf("%.*s4_request", - (int)curlx_strlen(&provider0), - curlx_str(&provider0)); - if(!request_type) - goto fail; - - /* provider0 is lowercased *after* curl_maprintf() so that the buffer - can be written to */ - Curl_strntolower(request_type, request_type, curlx_strlen(&provider0)); - - credential_scope = curl_maprintf("%s/%.*s/%.*s/%s", date, - (int)curlx_strlen(®ion), - curlx_str(®ion), - (int)curlx_strlen(&service), - curlx_str(&service), - request_type); - if(!credential_scope) - goto fail; - - if(Curl_sha256it(sha_hash, (unsigned char *)canonical_request, - strlen(canonical_request))) - goto fail; - - sha256_to_hex(sha_hex, sha_hash); - - /* - * Google allows using RSA key instead of HMAC, so this code might change - * in the future. For now we only support HMAC. - */ - str_to_sign = curl_maprintf("%.*s4-HMAC-SHA256\n" /* Algorithm */ - "%s\n" /* RequestDateTime */ - "%s\n" /* CredentialScope */ - "%s", /* HashedCanonicalRequest in hex */ - (int)curlx_strlen(&provider0), - curlx_str(&provider0), - timestamp, - credential_scope, - sha_hex); - if(!str_to_sign) - goto fail; - - /* make provider0 part done uppercase */ - Curl_strntoupper(str_to_sign, curlx_str(&provider0), - curlx_strlen(&provider0)); - - infof(data, "aws_sigv4: String to sign (enclosed in []) - [%s]", - str_to_sign); - - secret = curl_maprintf("%.*s4%s", (int)curlx_strlen(&provider0), - curlx_str(&provider0), data->state.aptr.passwd ? - data->state.aptr.passwd : ""); - if(!secret) - goto fail; - /* make provider0 part done uppercase */ - Curl_strntoupper(secret, curlx_str(&provider0), curlx_strlen(&provider0)); - - HMAC_SHA256(secret, strlen(secret), date, strlen(date), sign0); - HMAC_SHA256(sign0, sizeof(sign0), - curlx_str(®ion), curlx_strlen(®ion), sign1); - HMAC_SHA256(sign1, sizeof(sign1), - curlx_str(&service), curlx_strlen(&service), sign0); - HMAC_SHA256(sign0, sizeof(sign0), request_type, strlen(request_type), sign1); - HMAC_SHA256(sign1, sizeof(sign1), str_to_sign, strlen(str_to_sign), sign0); - - sha256_to_hex(sha_hex, sign0); - - infof(data, "aws_sigv4: Signature - %s", sha_hex); - - auth_headers = curl_maprintf("Authorization: %.*s4-HMAC-SHA256 " - "Credential=%s/%s, " - "SignedHeaders=%s, " - "Signature=%s\r\n" - /* - * date_header is added here, only if it was not - * user-specified (using CURLOPT_HTTPHEADER). - * date_header includes \r\n - */ - "%s" - "%s", /* optional sha256 header includes \r\n */ - (int)curlx_strlen(&provider0), - curlx_str(&provider0), - user, - credential_scope, - curlx_dyn_ptr(&signed_headers), - sha_hex, - date_header ? date_header : "", - content_sha256_hdr); - if(!auth_headers) { - goto fail; - } - /* provider 0 uppercase */ - Curl_strntoupper(&auth_headers[sizeof("Authorization: ") - 1], - curlx_str(&provider0), curlx_strlen(&provider0)); - - curlx_free(data->req.userpwd); - data->req.userpwd = auth_headers; - data->state.authhost.done = TRUE; - result = CURLE_OK; - -fail: - curlx_dyn_free(&canonical_query); - curlx_dyn_free(&canonical_path); - curlx_dyn_free(&canonical_headers); - curlx_dyn_free(&signed_headers); - curlx_free(canonical_request); - curlx_free(request_type); - curlx_free(credential_scope); - curlx_free(str_to_sign); - curlx_free(secret); - curlx_free(date_header); - return result; -} - -#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_AWS */ diff --git a/vendor/curl/lib/http_aws_sigv4.h b/vendor/curl/lib/http_aws_sigv4.h deleted file mode 100644 index 7dd002476..000000000 --- a/vendor/curl/lib/http_aws_sigv4.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef HEADER_CURL_HTTP_AWS_SIGV4_H -#define HEADER_CURL_HTTP_AWS_SIGV4_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/dynbuf.h" -#include "urldata.h" - -/* this is for creating aws_sigv4 header output */ -CURLcode Curl_output_aws_sigv4(struct Curl_easy *data); - -#endif /* HEADER_CURL_HTTP_AWS_SIGV4_H */ diff --git a/vendor/curl/lib/http_chunks.c b/vendor/curl/lib/http_chunks.c deleted file mode 100644 index aa45c79e3..000000000 --- a/vendor/curl/lib/http_chunks.c +++ /dev/null @@ -1,669 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -#include "urldata.h" /* it includes http_chunks.h */ -#include "curl_trc.h" -#include "sendf.h" /* for the client write stuff */ -#include "curlx/dynbuf.h" -#include "multiif.h" -#include "curlx/strparse.h" - -/* - Chunk format (simplified): - - [ chunk extension ] CRLF - CRLF - - Highlights from RFC2616 section 3.6 say: - - The chunked encoding modifies the body of a message in order to - transfer it as a series of chunks, each with its own size indicator, - followed by an OPTIONAL trailer containing entity-header fields. This - allows dynamically produced content to be transferred along with the - information necessary for the recipient to verify that it has - received the full message. - - Chunked-Body = *chunk - last-chunk - trailer - CRLF - - chunk = chunk-size [ chunk-extension ] CRLF - chunk-data CRLF - chunk-size = 1*HEX - last-chunk = 1*("0") [ chunk-extension ] CRLF - - chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) - chunk-ext-name = token - chunk-ext-val = token | quoted-string - chunk-data = chunk-size(OCTET) - trailer = *(entity-header CRLF) - - The chunk-size field is a string of hex digits indicating the size of - the chunk. The chunked encoding is ended by any chunk whose size is - zero, followed by the trailer, which is terminated by an empty line. - - */ - -void Curl_httpchunk_init(struct Curl_easy *data, struct Curl_chunker *ch, - bool ignore_body) -{ - (void)data; - ch->hexindex = 0; /* start at 0 */ - ch->state = CHUNK_HEX; /* we get hex first! */ - ch->last_code = CHUNKE_OK; - curlx_dyn_init(&ch->trailer, DYN_H1_TRAILER); - ch->ignore_body = ignore_body; -} - -void Curl_httpchunk_reset(struct Curl_easy *data, struct Curl_chunker *ch, - bool ignore_body) -{ - (void)data; - ch->hexindex = 0; /* start at 0 */ - ch->state = CHUNK_HEX; /* we get hex first! */ - ch->last_code = CHUNKE_OK; - curlx_dyn_reset(&ch->trailer); - ch->ignore_body = ignore_body; -} - -void Curl_httpchunk_free(struct Curl_easy *data, struct Curl_chunker *ch) -{ - (void)data; - curlx_dyn_free(&ch->trailer); -} - -bool Curl_httpchunk_is_done(struct Curl_easy *data, struct Curl_chunker *ch) -{ - (void)data; - return ch->state == CHUNK_DONE; -} - -static CURLcode httpchunk_readwrite(struct Curl_easy *data, - struct Curl_chunker *ch, - struct Curl_cwriter *cw_next, - const char *buf, size_t blen, - size_t *pconsumed) -{ - CURLcode result = CURLE_OK; - size_t piece; - - *pconsumed = 0; /* nothing's written yet */ - /* first check terminal states that will not progress anywhere */ - if(ch->state == CHUNK_DONE) - return CURLE_OK; - if(ch->state == CHUNK_FAILED) - return CURLE_RECV_ERROR; - - /* the original data is written to the client, but we go on with the - chunk read process, to properly calculate the content length */ - if(data->set.http_te_skip && !ch->ignore_body) { - if(cw_next) - result = Curl_cwriter_write(data, cw_next, CLIENTWRITE_BODY, buf, blen); - else - result = Curl_client_write(data, CLIENTWRITE_BODY, buf, blen); - if(result) { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_PASSTHRU_ERROR; - return result; - } - } - - while(blen) { - switch(ch->state) { - case CHUNK_HEX: - if(ISXDIGIT(*buf)) { - if(ch->hexindex >= CHUNK_MAXNUM_LEN) { - failf(data, "chunk hex-length longer than %d", CHUNK_MAXNUM_LEN); - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_TOO_LONG_HEX; /* longer than we support */ - return CURLE_RECV_ERROR; - } - ch->hexbuffer[ch->hexindex++] = *buf; - buf++; - blen--; - (*pconsumed)++; - } - else { - const char *p; - if(ch->hexindex == 0) { - /* This is illegal data, we received junk where we expected - a hexadecimal digit. */ - failf(data, "chunk hex-length char not a hex digit: 0x%x", *buf); - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_ILLEGAL_HEX; - return CURLE_RECV_ERROR; - } - /* blen and buf are unmodified */ - ch->hexbuffer[ch->hexindex] = 0; - p = &ch->hexbuffer[0]; - if(curlx_str_hex(&p, &ch->datasize, CURL_OFF_T_MAX)) { - failf(data, "invalid chunk size: '%s'", ch->hexbuffer); - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_ILLEGAL_HEX; - return CURLE_RECV_ERROR; - } - ch->state = CHUNK_LF; /* now wait for the CRLF */ - } - break; - - case CHUNK_LF: - /* waiting for the LF after a chunk size */ - if(*buf == 0x0a) { - /* we are now expecting data to come, unless size was zero! */ - if(ch->datasize == 0) { - ch->state = CHUNK_TRAILER; /* now check for trailers */ - } - else { - ch->state = CHUNK_DATA; - CURL_TRC_WRITE(data, "http_chunked, chunk start of %" - FMT_OFF_T " bytes", ch->datasize); - } - } - - buf++; - blen--; - (*pconsumed)++; - break; - - case CHUNK_DATA: - /* We expect 'datasize' of data. We have 'blen' right now, it can be - more or less than 'datasize'. Get the smallest piece. - */ - piece = blen; - if(ch->datasize < (curl_off_t)blen) - piece = curlx_sotouz(ch->datasize); - - /* Write the data portion available */ - if(!data->set.http_te_skip && !ch->ignore_body) { - if(cw_next) - result = Curl_cwriter_write(data, cw_next, CLIENTWRITE_BODY, - buf, piece); - else - result = Curl_client_write(data, CLIENTWRITE_BODY, buf, piece); - if(result) { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_PASSTHRU_ERROR; - return result; - } - } - - *pconsumed += piece; - ch->datasize -= piece; /* decrease amount left to expect */ - buf += piece; /* move read pointer forward */ - blen -= piece; /* decrease space left in this round */ - CURL_TRC_WRITE(data, "http_chunked, write %zu body bytes, %" - FMT_OFF_T " bytes in chunk remain", - piece, ch->datasize); - - if(ch->datasize == 0) - /* end of data this round, we now expect a trailing CRLF */ - ch->state = CHUNK_POSTLF; - break; - - case CHUNK_POSTLF: - if(*buf == 0x0a) { - /* The last one before we go back to hex state and start all over. */ - Curl_httpchunk_reset(data, ch, (bool)ch->ignore_body); - } - else if(*buf != 0x0d) { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_BAD_CHUNK; - return CURLE_RECV_ERROR; - } - buf++; - blen--; - (*pconsumed)++; - break; - - case CHUNK_TRAILER: - if((*buf == 0x0d) || (*buf == 0x0a)) { - const char *tr = curlx_dyn_ptr(&ch->trailer); - /* this is the end of a trailer, but if the trailer was zero bytes - there was no trailer and we move on */ - - if(tr) { - result = curlx_dyn_addn(&ch->trailer, STRCONST("\x0d\x0a")); - if(result) { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_OUT_OF_MEMORY; - return result; - } - tr = curlx_dyn_ptr(&ch->trailer); - if(!data->set.http_te_skip) { - size_t trlen = curlx_dyn_len(&ch->trailer); - if(cw_next) - result = Curl_cwriter_write(data, cw_next, - CLIENTWRITE_HEADER | - CLIENTWRITE_TRAILER, - tr, trlen); - else - result = Curl_client_write(data, - CLIENTWRITE_HEADER | - CLIENTWRITE_TRAILER, - tr, trlen); - if(result) { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_PASSTHRU_ERROR; - return result; - } - } - curlx_dyn_reset(&ch->trailer); - ch->state = CHUNK_TRAILER_CR; - if(*buf == 0x0a) - /* already on the LF */ - break; - } - else { - /* no trailer, we are on the final CRLF pair */ - ch->state = CHUNK_TRAILER_POSTCR; - break; /* do not advance the pointer */ - } - } - else { - result = curlx_dyn_addn(&ch->trailer, buf, 1); - if(result) { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_OUT_OF_MEMORY; - return result; - } - } - buf++; - blen--; - (*pconsumed)++; - break; - - case CHUNK_TRAILER_CR: - if(*buf == 0x0a) { - ch->state = CHUNK_TRAILER_POSTCR; - buf++; - blen--; - (*pconsumed)++; - } - else { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_BAD_CHUNK; - return CURLE_RECV_ERROR; - } - break; - - case CHUNK_TRAILER_POSTCR: - /* We enter this state when a CR should arrive so we expect to - have to first pass a CR before we wait for LF */ - if((*buf != 0x0d) && (*buf != 0x0a)) { - /* not a CR then it must be another header in the trailer */ - ch->state = CHUNK_TRAILER; - break; - } - if(*buf == 0x0d) { - /* skip if CR */ - buf++; - blen--; - (*pconsumed)++; - } - /* now wait for the final LF */ - ch->state = CHUNK_STOP; - break; - - case CHUNK_STOP: - if(*buf == 0x0a) { - blen--; - (*pconsumed)++; - /* Record the length of any data left in the end of the buffer - even if there is no more chunks to read */ - ch->datasize = blen; - ch->state = CHUNK_DONE; - CURL_TRC_WRITE(data, "http_chunk, response complete"); - return CURLE_OK; - } - else { - ch->state = CHUNK_FAILED; - ch->last_code = CHUNKE_BAD_CHUNK; - CURL_TRC_WRITE(data, "http_chunk error, expected 0x0a, seeing 0x%ux", - (unsigned int)*buf); - return CURLE_RECV_ERROR; - } - case CHUNK_DONE: - return CURLE_OK; - - case CHUNK_FAILED: - return CURLE_RECV_ERROR; - } - } - return CURLE_OK; -} - -static const char *Curl_chunked_strerror(CHUNKcode code) -{ - switch(code) { - default: - return "OK"; - case CHUNKE_TOO_LONG_HEX: - return "Too long hexadecimal number"; - case CHUNKE_ILLEGAL_HEX: - return "Illegal or missing hexadecimal sequence"; - case CHUNKE_BAD_CHUNK: - return "Malformed encoding found"; - case CHUNKE_PASSTHRU_ERROR: - return "Error writing data to client"; - case CHUNKE_BAD_ENCODING: - return "Bad content-encoding found"; - case CHUNKE_OUT_OF_MEMORY: - return "Out of memory"; - } -} - -CURLcode Curl_httpchunk_read(struct Curl_easy *data, - struct Curl_chunker *ch, - char *buf, size_t blen, - size_t *pconsumed) -{ - return httpchunk_readwrite(data, ch, NULL, buf, blen, pconsumed); -} - -struct chunked_writer { - struct Curl_cwriter super; - struct Curl_chunker ch; -}; - -static CURLcode cw_chunked_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct chunked_writer *ctx = writer->ctx; - - data->req.chunk = TRUE; /* chunks coming our way. */ - Curl_httpchunk_init(data, &ctx->ch, FALSE); - return CURLE_OK; -} - -static void cw_chunked_close(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct chunked_writer *ctx = writer->ctx; - Curl_httpchunk_free(data, &ctx->ch); -} - -static CURLcode cw_chunked_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t blen) -{ - struct chunked_writer *ctx = writer->ctx; - CURLcode result; - size_t consumed; - - if(!(type & CLIENTWRITE_BODY)) - return Curl_cwriter_write(data, writer->next, type, buf, blen); - - consumed = 0; - result = httpchunk_readwrite(data, &ctx->ch, writer->next, buf, blen, - &consumed); - - if(result) { - if(CHUNKE_PASSTHRU_ERROR == ctx->ch.last_code) { - failf(data, "Failed reading the chunked-encoded stream"); - } - else { - failf(data, "%s in chunked-encoding", - Curl_chunked_strerror(ctx->ch.last_code)); - } - return result; - } - - blen -= consumed; - if(CHUNK_DONE == ctx->ch.state) { - /* chunks read successfully, download is complete */ - data->req.download_done = TRUE; - if(blen) { - infof(data, "Leftovers after chunking: %zu bytes", blen); - } - } - else if((type & CLIENTWRITE_EOS) && !data->req.no_body) { - failf(data, "transfer closed with outstanding read data remaining"); - return CURLE_PARTIAL_FILE; - } - - return CURLE_OK; -} - -/* HTTP chunked Transfer-Encoding decoder */ -const struct Curl_cwtype Curl_httpchunk_unencoder = { - "chunked", - NULL, - cw_chunked_init, - cw_chunked_write, - cw_chunked_close, - sizeof(struct chunked_writer) -}; - -/* max length of an HTTP chunk that we want to generate */ -#define CURL_CHUNKED_MINLEN 1024 -#define CURL_CHUNKED_MAXLEN (64 * 1024) - -struct chunked_reader { - struct Curl_creader super; - struct bufq chunkbuf; - BIT(read_eos); /* we read an EOS from the next reader */ - BIT(eos); /* we have returned an EOS */ -}; - -static CURLcode cr_chunked_init(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct chunked_reader *ctx = reader->ctx; - (void)data; - Curl_bufq_init2(&ctx->chunkbuf, CURL_CHUNKED_MAXLEN, 2, BUFQ_OPT_SOFT_LIMIT); - return CURLE_OK; -} - -static void cr_chunked_close(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct chunked_reader *ctx = reader->ctx; - (void)data; - Curl_bufq_free(&ctx->chunkbuf); -} - -static CURLcode add_last_chunk(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct chunked_reader *ctx = reader->ctx; - struct curl_slist *trailers = NULL, *tr; - CURLcode result; - size_t n; - int rc; - - if(!data->set.trailer_callback) { - CURL_TRC_READ(data, "http_chunk, added last, empty chunk"); - return Curl_bufq_cwrite(&ctx->chunkbuf, STRCONST("0\r\n\r\n"), &n); - } - - result = Curl_bufq_cwrite(&ctx->chunkbuf, STRCONST("0\r\n"), &n); - if(result) - goto out; - - Curl_set_in_callback(data, TRUE); - rc = data->set.trailer_callback(&trailers, data->set.trailer_data); - Curl_set_in_callback(data, FALSE); - - if(rc != CURL_TRAILERFUNC_OK) { - failf(data, "operation aborted by trailing headers callback"); - result = CURLE_ABORTED_BY_CALLBACK; - goto out; - } - - for(tr = trailers; tr; tr = tr->next) { - /* only add correctly formatted trailers */ - const char *ptr = strchr(tr->data, ':'); - if(!ptr || *(ptr + 1) != ' ') { - infof(data, "Malformatted trailing header, skipping trailer"); - continue; - } - - result = Curl_bufq_cwrite(&ctx->chunkbuf, tr->data, strlen(tr->data), &n); - if(!result) - result = Curl_bufq_cwrite(&ctx->chunkbuf, STRCONST("\r\n"), &n); - if(result) - goto out; - } - - result = Curl_bufq_cwrite(&ctx->chunkbuf, STRCONST("\r\n"), &n); - -out: - curl_slist_free_all(trailers); - CURL_TRC_READ(data, "http_chunk, added last chunk with trailers " - "from client -> %d", result); - return result; -} - -static CURLcode add_chunk(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen) -{ - struct chunked_reader *ctx = reader->ctx; - CURLcode result; - char tmp[CURL_CHUNKED_MINLEN]; - size_t nread; - bool eos; - - DEBUGASSERT(!ctx->read_eos); - blen = CURLMIN(blen, CURL_CHUNKED_MAXLEN); /* respect our buffer pref */ - if(blen < sizeof(tmp)) { - /* small read, make a chunk of decent size */ - buf = tmp; - blen = sizeof(tmp); - } - else { - /* larger read, make a chunk that will fit when read back */ - blen -= (8 + 2 + 2); /* deduct max overhead, 8 hex + 2*crlf */ - } - - result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos); - if(result) - return result; - if(eos) - ctx->read_eos = TRUE; - - if(nread) { - /* actually got bytes, wrap them into the chunkbuf */ - char hd[11] = ""; - int hdlen; - size_t n; - - hdlen = curl_msnprintf(hd, sizeof(hd), "%zx\r\n", nread); - if(hdlen <= 0) - return CURLE_READ_ERROR; - /* On a soft-limited bufq, we do not need to check that all was written */ - result = Curl_bufq_cwrite(&ctx->chunkbuf, hd, hdlen, &n); - if(!result) - result = Curl_bufq_cwrite(&ctx->chunkbuf, buf, nread, &n); - if(!result) - result = Curl_bufq_cwrite(&ctx->chunkbuf, "\r\n", 2, &n); - CURL_TRC_READ(data, "http_chunk, made chunk of %zu bytes -> %d", - nread, result); - if(result) - return result; - } - - if(ctx->read_eos) - return add_last_chunk(data, reader); - return CURLE_OK; -} - -static CURLcode cr_chunked_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct chunked_reader *ctx = reader->ctx; - CURLcode result = CURLE_READ_ERROR; - - *pnread = 0; - *peos = (bool)ctx->eos; - - if(!ctx->eos) { - if(!ctx->read_eos && Curl_bufq_is_empty(&ctx->chunkbuf)) { - /* Still getting data form the next reader, buffer is empty */ - result = add_chunk(data, reader, buf, blen); - if(result) - return result; - } - - if(!Curl_bufq_is_empty(&ctx->chunkbuf)) { - result = Curl_bufq_cread(&ctx->chunkbuf, buf, blen, pnread); - if(!result && ctx->read_eos && Curl_bufq_is_empty(&ctx->chunkbuf)) { - /* no more data, read all, done. */ - ctx->eos = TRUE; - *peos = TRUE; - } - return result; - } - } - /* We may get here, because we are done or because callbacks paused */ - DEBUGASSERT(ctx->eos || !ctx->read_eos); - return CURLE_OK; -} - -static curl_off_t cr_chunked_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - /* this reader changes length depending on input */ - (void)data; - (void)reader; - return -1; -} - -/* HTTP chunked Transfer-Encoding encoder */ -const struct Curl_crtype Curl_httpchunk_encoder = { - "chunked", - cr_chunked_init, - cr_chunked_read, - cr_chunked_close, - Curl_creader_def_needs_rewind, - cr_chunked_total_length, - Curl_creader_def_resume_from, - Curl_creader_def_cntrl, - Curl_creader_def_is_paused, - Curl_creader_def_done, - sizeof(struct chunked_reader) -}; - -CURLcode Curl_httpchunk_add_reader(struct Curl_easy *data) -{ - struct Curl_creader *reader = NULL; - CURLcode result; - - result = Curl_creader_create(&reader, data, &Curl_httpchunk_encoder, - CURL_CR_TRANSFER_ENCODE); - if(!result) - result = Curl_creader_add(data, reader); - - if(result && reader) - Curl_creader_free(data, reader); - return result; -} - -#endif /* CURL_DISABLE_HTTP */ diff --git a/vendor/curl/lib/http_chunks.h b/vendor/curl/lib/http_chunks.h deleted file mode 100644 index d8e5982e6..000000000 --- a/vendor/curl/lib/http_chunks.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef HEADER_CURL_HTTP_CHUNKS_H -#define HEADER_CURL_HTTP_CHUNKS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -#include "curlx/dynbuf.h" - -struct connectdata; - -/* - * The longest possible hexadecimal number we support in a chunked transfer. - * Neither RFC2616 nor the later HTTP specs define a maximum chunk size. - * For 64-bit curl_off_t we support 16 digits. For 32-bit, 8 digits. - */ -#define CHUNK_MAXNUM_LEN (SIZEOF_CURL_OFF_T * 2) - -typedef enum { - /* await and buffer all hexadecimal digits until we get one that is not a - hexadecimal digit. When done, we go CHUNK_LF */ - CHUNK_HEX, - - /* wait for LF, ignore all else */ - CHUNK_LF, - - /* We eat the amount of data specified. When done, we move on to the - POST_CR state. */ - CHUNK_DATA, - - /* POSTLF should get a CR and then an LF and nothing else, then move back to - HEX as the CRLF combination marks the end of a chunk. A missing CR is no - big deal. */ - CHUNK_POSTLF, - - /* Used to mark that we are out of the game. NOTE: that there is a - 'datasize' field in the struct that will tell how many bytes that were - not passed to the client in the end of the last buffer! */ - CHUNK_STOP, - - /* At this point optional trailer headers can be found, unless the next line - is CRLF */ - CHUNK_TRAILER, - - /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. - Next char must be an LF */ - CHUNK_TRAILER_CR, - - /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be - signalled If this is an empty trailer CHUNKE_STOP will be signalled. - Otherwise the trailer will be broadcasted via Curl_client_write() and the - next state will be CHUNK_TRAILER */ - CHUNK_TRAILER_POSTCR, - - /* Successfully de-chunked everything */ - CHUNK_DONE, - - /* Failed on seeing a bad or not correctly terminated chunk */ - CHUNK_FAILED -} ChunkyState; - -typedef enum { - CHUNKE_OK = 0, - CHUNKE_TOO_LONG_HEX = 1, - CHUNKE_ILLEGAL_HEX, - CHUNKE_BAD_CHUNK, - CHUNKE_BAD_ENCODING, - CHUNKE_OUT_OF_MEMORY, - CHUNKE_PASSTHRU_ERROR /* Curl_httpchunk_read() returns a CURLcode to use */ -} CHUNKcode; - -struct Curl_chunker { - curl_off_t datasize; - ChunkyState state; - CHUNKcode last_code; - struct dynbuf trailer; /* for chunked-encoded trailer */ - unsigned char hexindex; - char hexbuffer[CHUNK_MAXNUM_LEN + 1]; /* +1 for null-terminator */ - BIT(ignore_body); /* never write response body data */ -}; - -/* The following functions are defined in http_chunks.c */ -void Curl_httpchunk_init(struct Curl_easy *data, struct Curl_chunker *ch, - bool ignore_body); -void Curl_httpchunk_free(struct Curl_easy *data, struct Curl_chunker *ch); -void Curl_httpchunk_reset(struct Curl_easy *data, struct Curl_chunker *ch, - bool ignore_body); - -/* - * Read BODY bytes in HTTP/1.1 chunked encoding from `buf` and return - * the amount of bytes consumed. The actual response bytes and trailer - * headers are written out to the client. - * On success, this will consume all bytes up to the end of the response, - * e.g. the last chunk, has been processed. - * @param data the transfer involved - * @param ch the chunker instance keeping state across calls - * @param buf the response data - * @param blen amount of bytes in `buf` - * @param pconsumed on successful return, the number of bytes in `buf` - * consumed - * - * This function always uses ASCII hex values to accommodate non-ASCII hosts. - * For example, 0x0d and 0x0a are used instead of '\r' and '\n'. - */ -CURLcode Curl_httpchunk_read(struct Curl_easy *data, struct Curl_chunker *ch, - char *buf, size_t blen, size_t *pconsumed); - -/** - * @return TRUE iff chunked decoded has finished successfully. - */ -bool Curl_httpchunk_is_done(struct Curl_easy *data, struct Curl_chunker *ch); - -extern const struct Curl_cwtype Curl_httpchunk_unencoder; - -extern const struct Curl_crtype Curl_httpchunk_encoder; - -/** - * Add a transfer-encoding "chunked" reader to the transfers reader stack - */ -CURLcode Curl_httpchunk_add_reader(struct Curl_easy *data); - -#endif /* !CURL_DISABLE_HTTP */ - -#endif /* HEADER_CURL_HTTP_CHUNKS_H */ diff --git a/vendor/curl/lib/http_digest.c b/vendor/curl/lib/http_digest.c deleted file mode 100644 index b7007071e..000000000 --- a/vendor/curl/lib/http_digest.c +++ /dev/null @@ -1,178 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) - -#include "urldata.h" -#include "strcase.h" -#include "vauth/vauth.h" -#include "http_digest.h" -#include "curlx/strparse.h" - -/* Test example headers: - -WWW-Authenticate: Digest realm="testrealm", nonce="1053604598" -Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" - -*/ - -CURLcode Curl_input_digest(struct Curl_easy *data, - bool proxy, - const char *header) /* rest of the *-authenticate: - header */ -{ - /* Point to the correct struct with this */ - struct digestdata *digest; - - if(proxy) { - digest = &data->state.proxydigest; - } - else { - digest = &data->state.digest; - } - - if(!checkprefix("Digest", header) || !ISBLANK(header[6])) - return CURLE_BAD_CONTENT_ENCODING; - - header += strlen("Digest"); - curlx_str_passblanks(&header); - - return Curl_auth_decode_digest_http_message(header, digest); -} - -CURLcode Curl_output_digest(struct Curl_easy *data, - bool proxy, - const unsigned char *request, - const unsigned char *uripath) -{ - CURLcode result; - unsigned char *path = NULL; - const char *tmp = NULL; - char *response; - size_t len; - bool have_chlg; - - /* Point to the address of the pointer that holds the string to send to the - server, which is for a plain host or for an HTTP proxy */ - char **allocuserpwd; - - /* Point to the name and password for this */ - const char *userp; - const char *passwdp; - - /* Point to the correct struct with this */ - struct digestdata *digest; - struct auth *authp; - - if(proxy) { -#ifdef CURL_DISABLE_PROXY - return CURLE_NOT_BUILT_IN; -#else - digest = &data->state.proxydigest; - allocuserpwd = &data->req.proxyuserpwd; - userp = data->state.aptr.proxyuser; - passwdp = data->state.aptr.proxypasswd; - authp = &data->state.authproxy; -#endif - } - else { - digest = &data->state.digest; - allocuserpwd = &data->req.userpwd; - userp = data->state.aptr.user; - passwdp = data->state.aptr.passwd; - authp = &data->state.authhost; - } - - curlx_safefree(*allocuserpwd); - - /* not set means empty */ - if(!userp) - userp = ""; - - if(!passwdp) - passwdp = ""; - -#ifdef USE_WINDOWS_SSPI - have_chlg = !!digest->input_token; -#else - have_chlg = !!digest->nonce; -#endif - - if(!have_chlg) { - authp->done = FALSE; - return CURLE_OK; - } - - /* IE browsers < v7 cut off the URI part at the query part when they - evaluate the MD5 and some (IIS?) servers work with them so we may need to - do the Digest IE-style. Note that the different ways cause different MD5 - sums to get sent. - - Apache servers can be set to do the Digest IE-style automatically using - the BrowserMatch feature: - https://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie - - Further details on Digest implementation differences: - https://web.archive.org/web/2009/fngtps.com/2006/09/http-authentication - */ - - if(authp->iestyle) { - tmp = strchr((const char *)uripath, '?'); - if(tmp) { - size_t urilen = tmp - (const char *)uripath; - /* typecast is fine here since the value is always less than 32 bits */ - path = (unsigned char *)curl_maprintf("%.*s", (int)urilen, uripath); - } - } - if(!tmp) - path = (unsigned char *)curlx_strdup((const char *)uripath); - - if(!path) - return CURLE_OUT_OF_MEMORY; - - result = Curl_auth_create_digest_http_message(data, userp, passwdp, request, - path, digest, &response, &len); - curlx_free(path); - if(result) - return result; - - *allocuserpwd = curl_maprintf("%sAuthorization: Digest %s\r\n", - proxy ? "Proxy-" : "", response); - curlx_free(response); - if(!*allocuserpwd) - return CURLE_OUT_OF_MEMORY; - - authp->done = TRUE; - - return CURLE_OK; -} - -void Curl_http_auth_cleanup_digest(struct Curl_easy *data) -{ - Curl_auth_digest_cleanup(&data->state.digest); - Curl_auth_digest_cleanup(&data->state.proxydigest); -} - -#endif diff --git a/vendor/curl/lib/http_digest.h b/vendor/curl/lib/http_digest.h deleted file mode 100644 index 5f797310f..000000000 --- a/vendor/curl/lib/http_digest.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef HEADER_CURL_HTTP_DIGEST_H -#define HEADER_CURL_HTTP_DIGEST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) - -/* this is for digest header input */ -CURLcode Curl_input_digest(struct Curl_easy *data, - bool proxy, const char *header); - -/* this is for creating digest header output */ -CURLcode Curl_output_digest(struct Curl_easy *data, - bool proxy, - const unsigned char *request, - const unsigned char *uripath); - -void Curl_http_auth_cleanup_digest(struct Curl_easy *data); - -#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_DIGEST_AUTH */ - -#endif /* HEADER_CURL_HTTP_DIGEST_H */ diff --git a/vendor/curl/lib/http_negotiate.c b/vendor/curl/lib/http_negotiate.c deleted file mode 100644 index 74d63d6cc..000000000 --- a/vendor/curl/lib/http_negotiate.c +++ /dev/null @@ -1,262 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) - -#include "urldata.h" -#include "cfilters.h" -#include "curl_trc.h" -#include "http_negotiate.h" -#include "vauth/vauth.h" -#include "vtls/vtls.h" -#include "curlx/strparse.h" - - -static void http_auth_nego_reset(struct connectdata *conn, - struct negotiatedata *neg_ctx, - bool proxy) -{ - if(proxy) - conn->proxy_negotiate_state = GSS_AUTHNONE; - else - conn->http_negotiate_state = GSS_AUTHNONE; - if(neg_ctx) - Curl_auth_cleanup_spnego(neg_ctx); -} - -CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, - bool proxy, const char *header) -{ - CURLcode result; - size_t len; - - /* Point to the username, password, service and host */ - const char *userp; - const char *passwdp; - const char *service; - const char *host; - - /* Point to the correct struct with this */ - struct negotiatedata *neg_ctx; - curlnegotiate state; - - if(proxy) { -#ifndef CURL_DISABLE_PROXY - userp = conn->http_proxy.user; - passwdp = conn->http_proxy.passwd; - service = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; - host = conn->http_proxy.host.name; - state = conn->proxy_negotiate_state; -#else - return CURLE_NOT_BUILT_IN; -#endif - } - else { - userp = conn->user; - passwdp = conn->passwd; - service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : "HTTP"; - host = conn->host.name; - state = conn->http_negotiate_state; - } - - neg_ctx = Curl_auth_nego_get(conn, proxy); - if(!neg_ctx) - return CURLE_OUT_OF_MEMORY; - - /* Not set means empty */ - if(!userp) - userp = ""; - - if(!passwdp) - passwdp = ""; - - /* Obtain the input token, if any */ - header += strlen("Negotiate"); - curlx_str_passblanks(&header); - - len = strlen(header); - neg_ctx->havenegdata = len != 0; - if(!len) { - if(state == GSS_AUTHSUCC) { - infof(data, "Negotiate auth restarted"); - http_auth_nego_reset(conn, neg_ctx, proxy); - } - else if(state != GSS_AUTHNONE) { - /* The server rejected our authentication and has not supplied any more - negotiation mechanisms */ - http_auth_nego_reset(conn, neg_ctx, proxy); - return CURLE_LOGIN_DENIED; - } - } - - /* Supports SSL channel binding for Windows ISS extended protection */ -#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) - neg_ctx->sslContext = conn->sslContext; -#endif - /* Check if the connection is using SSL and get the channel binding data */ -#ifdef GSS_C_CHANNEL_BOUND_FLAG -#ifdef USE_SSL - curlx_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE + 1); - if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - result = Curl_ssl_get_channel_binding(data, FIRSTSOCKET, - &neg_ctx->channel_binding_data); - if(result) { - http_auth_nego_reset(conn, neg_ctx, proxy); - return result; - } - } -#else - curlx_dyn_init(&neg_ctx->channel_binding_data, 1); -#endif /* USE_SSL */ -#endif /* GSS_C_CHANNEL_BOUND_FLAG */ - - /* Initialize the security context and decode our challenge */ - result = Curl_auth_decode_spnego_message(data, userp, passwdp, service, - host, header, neg_ctx); - -#ifdef GSS_C_CHANNEL_BOUND_FLAG - curlx_dyn_free(&neg_ctx->channel_binding_data); -#endif - - if(result) - http_auth_nego_reset(conn, neg_ctx, proxy); - - return result; -} - -CURLcode Curl_output_negotiate(struct Curl_easy *data, - struct connectdata *conn, bool proxy) -{ - struct negotiatedata *neg_ctx; - struct auth *authp; - curlnegotiate *state; - char *base64 = NULL; - size_t len = 0; - char *userp; - CURLcode result; - - if(proxy) { -#ifndef CURL_DISABLE_PROXY - authp = &data->state.authproxy; - state = &conn->proxy_negotiate_state; -#else - return CURLE_NOT_BUILT_IN; -#endif - } - else { - authp = &data->state.authhost; - state = &conn->http_negotiate_state; - } - neg_ctx = Curl_auth_nego_get(conn, proxy); - if(!neg_ctx) - return CURLE_OUT_OF_MEMORY; - - authp->done = FALSE; - - if(*state == GSS_AUTHRECV) { - if(neg_ctx->havenegdata) { - neg_ctx->havemultiplerequests = TRUE; - } - } - else if(*state == GSS_AUTHSUCC) { - if(!neg_ctx->havenoauthpersist) { - neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests; - } - } - - if(neg_ctx->noauthpersist || - (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) { - - if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) { - infof(data, "Curl_output_negotiate, " - "no persistent authentication: cleanup existing context"); - http_auth_nego_reset(conn, neg_ctx, proxy); - } - if(!neg_ctx->context) { - result = Curl_input_negotiate(data, conn, proxy, "Negotiate"); - if(result == CURLE_AUTH_ERROR) { - /* negotiate auth failed, let's continue unauthenticated to stay - * compatible with the behavior before curl-7_64_0-158-g6c6035532 */ - authp->done = TRUE; - return CURLE_OK; - } - else if(result) - return result; - } - - result = Curl_auth_create_spnego_message(neg_ctx, &base64, &len); - if(result) - return result; - - userp = curl_maprintf("%sAuthorization: Negotiate %s\r\n", - proxy ? "Proxy-" : "", base64); - - if(proxy) { -#ifndef CURL_DISABLE_PROXY - curlx_free(data->req.proxyuserpwd); - data->req.proxyuserpwd = userp; -#endif - } - else { - curlx_free(data->req.userpwd); - data->req.userpwd = userp; - } - - curlx_free(base64); - - if(!userp) { - return CURLE_OUT_OF_MEMORY; - } - - *state = GSS_AUTHSENT; -#ifdef HAVE_GSSAPI - if(neg_ctx->status == GSS_S_COMPLETE || - neg_ctx->status == GSS_S_CONTINUE_NEEDED) { - *state = GSS_AUTHDONE; - } -#else -#ifdef USE_WINDOWS_SSPI - if(neg_ctx->status == SEC_E_OK || - neg_ctx->status == SEC_I_CONTINUE_NEEDED) { - *state = GSS_AUTHDONE; - } -#endif -#endif - } - - if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) { - /* connection is already authenticated, - * do not send a header in future requests */ - authp->done = TRUE; - } - - neg_ctx->havenegdata = FALSE; - - return CURLE_OK; -} - -#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ diff --git a/vendor/curl/lib/http_negotiate.h b/vendor/curl/lib/http_negotiate.h deleted file mode 100644 index 6c285f152..000000000 --- a/vendor/curl/lib/http_negotiate.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_HTTP_NEGOTIATE_H -#define HEADER_CURL_HTTP_NEGOTIATE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) - -/* this is for Negotiate header input */ -CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, - bool proxy, const char *header); - -/* this is for creating Negotiate header output */ -CURLcode Curl_output_negotiate(struct Curl_easy *data, - struct connectdata *conn, bool proxy); - -#endif - -#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */ diff --git a/vendor/curl/lib/http_ntlm.c b/vendor/curl/lib/http_ntlm.c deleted file mode 100644 index 82b050529..000000000 --- a/vendor/curl/lib/http_ntlm.c +++ /dev/null @@ -1,254 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) - -/* - * NTLM details: - * - * https://davenport.sourceforge.net/ntlm.html - * https://www.innovation.ch/java/ntlm.html - */ - -#include "urldata.h" -#include "curl_trc.h" -#include "strcase.h" -#include "http_ntlm.h" -#include "curl_ntlm_core.h" -#include "curlx/base64.h" -#include "vauth/vauth.h" -#include "url.h" -#include "curlx/strparse.h" - -/* SSL backend-specific #if branches in this file must be kept in the order - documented in curl_ntlm_core. */ -#ifdef USE_WINDOWS_SSPI -#include "curl_sspi.h" -#endif - -CURLcode Curl_input_ntlm(struct Curl_easy *data, - bool proxy, /* if proxy or not */ - const char *header) /* rest of the www-authenticate: - header */ -{ - /* point to the correct struct with this */ - curlntlm *state; - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - - state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; - - if(checkprefix("NTLM", header)) { - struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, proxy); - if(!ntlm) - return CURLE_OUT_OF_MEMORY; - - header += strlen("NTLM"); - curlx_str_passblanks(&header); - if(*header) { - unsigned char *hdr; - size_t hdrlen; - - result = curlx_base64_decode(header, &hdr, &hdrlen); - if(!result) { - struct bufref hdrbuf; - - Curl_bufref_init(&hdrbuf); - Curl_bufref_set(&hdrbuf, hdr, hdrlen, curl_free); - result = Curl_auth_decode_ntlm_type2_message(data, &hdrbuf, ntlm); - Curl_bufref_free(&hdrbuf); - } - if(result) - return result; - - *state = NTLMSTATE_TYPE2; /* We got a type-2 message */ - } - else { - if(*state == NTLMSTATE_LAST) { - infof(data, "NTLM auth restarted"); - Curl_auth_ntlm_remove(conn, proxy); - } - else if(*state == NTLMSTATE_TYPE3) { - infof(data, "NTLM handshake rejected"); - Curl_auth_ntlm_remove(conn, proxy); - *state = NTLMSTATE_NONE; - return CURLE_REMOTE_ACCESS_DENIED; - } - else if(*state >= NTLMSTATE_TYPE1) { - infof(data, "NTLM handshake failure (internal error)"); - return CURLE_REMOTE_ACCESS_DENIED; - } - - *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ - } - } - - return result; -} - -/* - * This is for creating NTLM header output - */ -CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) -{ - char *base64 = NULL; - size_t len = 0; - CURLcode result = CURLE_OK; - struct bufref ntlmmsg; - - /* point to the address of the pointer that holds the string to send to the - server, which is for a plain host or for an HTTP proxy */ - char **allocuserpwd; - - /* point to the username, password, service and host */ - const char *userp; - const char *passwdp; - const char *service = NULL; - const char *hostname = NULL; - - /* point to the correct struct with this */ - struct ntlmdata *ntlm; - curlntlm *state; - struct auth *authp; - struct connectdata *conn = data->conn; - - DEBUGASSERT(conn); - DEBUGASSERT(data); - - if(proxy) { -#ifndef CURL_DISABLE_PROXY - allocuserpwd = &data->req.proxyuserpwd; - userp = data->state.aptr.proxyuser; - passwdp = data->state.aptr.proxypasswd; - service = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; - hostname = conn->http_proxy.host.name; - state = &conn->proxy_ntlm_state; - authp = &data->state.authproxy; -#else - return CURLE_NOT_BUILT_IN; -#endif - } - else { - allocuserpwd = &data->req.userpwd; - userp = data->state.aptr.user; - passwdp = data->state.aptr.passwd; - service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : "HTTP"; - hostname = conn->host.name; - state = &conn->http_ntlm_state; - authp = &data->state.authhost; - } - ntlm = Curl_auth_ntlm_get(conn, proxy); - if(!ntlm) - return CURLE_OUT_OF_MEMORY; - authp->done = FALSE; - - /* not set means empty */ - if(!userp) - userp = ""; - - if(!passwdp) - passwdp = ""; - -#ifdef USE_WINDOWS_SSPI - if(!Curl_pSecFn) { - /* not thread-safe and leaks - use curl_global_init() to avoid */ - result = Curl_sspi_global_init(); - if(!Curl_pSecFn) - return result; - } -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - ntlm->sslContext = conn->sslContext; -#endif -#endif - - Curl_bufref_init(&ntlmmsg); - - /* connection is already authenticated, do not send a header in future - * requests so go directly to NTLMSTATE_LAST */ - if(*state == NTLMSTATE_TYPE3) - *state = NTLMSTATE_LAST; - - switch(*state) { - case NTLMSTATE_TYPE1: - default: /* for the weird cases we (re)start here */ - /* Create a type-1 message */ - result = Curl_auth_create_ntlm_type1_message(data, userp, passwdp, service, - hostname, ntlm, &ntlmmsg); - if(!result) { - DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0); - result = curlx_base64_encode(Curl_bufref_uptr(&ntlmmsg), - Curl_bufref_len(&ntlmmsg), &base64, &len); - if(!result) { - curlx_free(*allocuserpwd); - *allocuserpwd = curl_maprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", base64); - curlx_free(base64); - if(!*allocuserpwd) - result = CURLE_OUT_OF_MEMORY; - } - } - break; - - case NTLMSTATE_TYPE2: - /* We already received the type-2 message, create a type-3 message */ - result = Curl_auth_create_ntlm_type3_message(data, userp, passwdp, - ntlm, &ntlmmsg); - if(!result && Curl_bufref_len(&ntlmmsg)) { - result = curlx_base64_encode(Curl_bufref_uptr(&ntlmmsg), - Curl_bufref_len(&ntlmmsg), &base64, &len); - if(!result) { - curlx_free(*allocuserpwd); - *allocuserpwd = curl_maprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", base64); - curlx_free(base64); - if(!*allocuserpwd) - result = CURLE_OUT_OF_MEMORY; - else { - *state = NTLMSTATE_TYPE3; /* we send a type-3 */ - authp->done = TRUE; - } - } - } - break; - - case NTLMSTATE_LAST: - /* since this is a little artificial in that this is used without any - outgoing auth headers being set, we need to set the bit by force */ - if(proxy) - data->info.proxyauthpicked = CURLAUTH_NTLM; - else - data->info.httpauthpicked = CURLAUTH_NTLM; - curlx_safefree(*allocuserpwd); - authp->done = TRUE; - break; - } - Curl_bufref_free(&ntlmmsg); - - return result; -} - -#endif /* !CURL_DISABLE_HTTP && USE_NTLM */ diff --git a/vendor/curl/lib/http_ntlm.h b/vendor/curl/lib/http_ntlm.h deleted file mode 100644 index ff5218d89..000000000 --- a/vendor/curl/lib/http_ntlm.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_HTTP_NTLM_H -#define HEADER_CURL_HTTP_NTLM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) - -/* this is for NTLM header input */ -CURLcode Curl_input_ntlm(struct Curl_easy *data, bool proxy, - const char *header); - -/* this is for creating NTLM header output */ -CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy); - -#endif - -#endif /* HEADER_CURL_HTTP_NTLM_H */ diff --git a/vendor/curl/lib/http_proxy.c b/vendor/curl/lib/http_proxy.c deleted file mode 100644 index a4bdd7e36..000000000 --- a/vendor/curl/lib/http_proxy.c +++ /dev/null @@ -1,434 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "http_proxy.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) - -#include "curl_trc.h" -#include "http.h" -#include "url.h" -#include "cfilters.h" -#include "cf-h1-proxy.h" -#include "cf-h2-proxy.h" -#include "connect.h" -#include "vauth/vauth.h" -#include "curlx/strparse.h" - -static CURLcode dynhds_add_custom(struct Curl_easy *data, - bool is_connect, int httpversion, - struct dynhds *hds) -{ - struct connectdata *conn = data->conn; - struct curl_slist *h[2]; - struct curl_slist *headers; - int numlists = 1; /* by default */ - int i; - - enum Curl_proxy_use proxy; - - if(is_connect) - proxy = HEADER_CONNECT; - else - proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy ? - HEADER_PROXY : HEADER_SERVER; - - switch(proxy) { - case HEADER_SERVER: - h[0] = data->set.headers; - break; - case HEADER_PROXY: - h[0] = data->set.headers; - if(data->set.sep_headers) { - h[1] = data->set.proxyheaders; - numlists++; - } - break; - case HEADER_CONNECT: - if(data->set.sep_headers) - h[0] = data->set.proxyheaders; - else - h[0] = data->set.headers; - break; - } - - /* loop through one or two lists */ - for(i = 0; i < numlists; i++) { - for(headers = h[i]; headers; headers = headers->next) { - struct Curl_str name; - const char *value = NULL; - size_t valuelen = 0; - const char *ptr = headers->data; - - /* There are 2 quirks in place for custom headers: - * 1. setting only 'name:' to suppress a header from being sent - * 2. setting only 'name;' to send an empty (illegal) header - */ - if(!curlx_str_cspn(&ptr, &name, ";:")) { - if(!curlx_str_single(&ptr, ':')) { - curlx_str_passblanks(&ptr); - if(*ptr) { - value = ptr; - valuelen = strlen(value); - } - else { - /* quirk #1, suppress this header */ - continue; - } - } - else if(!curlx_str_single(&ptr, ';')) { - curlx_str_passblanks(&ptr); - if(!*ptr) { - /* quirk #2, send an empty header */ - value = ""; - valuelen = 0; - } - else { - /* this may be used for something else in the future, - * ignore this for now */ - continue; - } - } - else - /* neither : nor ; in provided header value. We ignore this - * silently */ - continue; - } - else - /* no name, move on */ - continue; - - DEBUGASSERT(curlx_strlen(&name) && value); - if(data->state.aptr.host && - /* a Host: header was sent already, do not pass on any custom Host: - header as that will produce *two* in the same request! */ - curlx_str_casecompare(&name, "Host")) - ; - else if(data->state.httpreq == HTTPREQ_POST_FORM && - /* this header (extended by formdata.c) is sent later */ - curlx_str_casecompare(&name, "Content-Type")) - ; - else if(data->state.httpreq == HTTPREQ_POST_MIME && - /* this header is sent later */ - curlx_str_casecompare(&name, "Content-Type")) - ; - else if(data->req.authneg && - /* while doing auth neg, do not allow the custom length since - we will force length zero then */ - curlx_str_casecompare(&name, "Content-Length")) - ; - else if((httpversion >= 20) && - curlx_str_casecompare(&name, "Transfer-Encoding")) - ; - /* HTTP/2 and HTTP/3 do not support chunked requests */ - else if((curlx_str_casecompare(&name, "Authorization") || - curlx_str_casecompare(&name, "Cookie")) && - /* be careful of sending this potentially sensitive header to - other hosts */ - !Curl_auth_allowed_to_host(data)) - ; - else { - CURLcode result = - Curl_dynhds_add(hds, curlx_str(&name), curlx_strlen(&name), - value, valuelen); - if(result) - return result; - } - } - } - - return CURLE_OK; -} - -void Curl_http_proxy_get_destination(struct Curl_cfilter *cf, - const char **phostname, - uint16_t *pport, bool *pipv6_ip) -{ - DEBUGASSERT(cf); - DEBUGASSERT(cf->conn); - - if(cf->conn->bits.conn_to_host) - *phostname = cf->conn->conn_to_host.name; - else if(cf->sockindex == SECONDARYSOCKET) - *phostname = cf->conn->secondaryhostname; - else - *phostname = cf->conn->host.name; - - if(cf->sockindex == SECONDARYSOCKET) - *pport = cf->conn->secondary_port; - else if(cf->conn->bits.conn_to_port) - *pport = cf->conn->conn_to_port; - else - *pport = cf->conn->remote_port; - - *pipv6_ip = (strchr(*phostname, ':') != NULL); -} - -struct cf_proxy_ctx { - int httpversion; /* HTTP version used to CONNECT */ - BIT(sub_filter_installed); -}; - -CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq, - struct Curl_cfilter *cf, - struct Curl_easy *data, - int http_version_major) -{ - struct cf_proxy_ctx *ctx = cf->ctx; - const char *hostname = NULL; - char *authority = NULL; - uint16_t port; - bool ipv6_ip; - CURLcode result; - struct httpreq *req = NULL; - - Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip); - - authority = curl_maprintf("%s%s%s:%u", ipv6_ip ? "[" : "", hostname, - ipv6_ip ? "]" : "", port); - if(!authority) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = Curl_http_req_make(&req, "CONNECT", sizeof("CONNECT") - 1, - NULL, 0, authority, strlen(authority), - NULL, 0); - if(result) - goto out; - - /* Setup the proxy-authorization header, if any */ - result = Curl_http_output_auth(data, cf->conn, req->method, HTTPREQ_GET, - req->authority, TRUE); - if(result) - goto out; - - /* If user is not overriding Host: header, we add for HTTP/1.x */ - if(http_version_major == 1 && - !Curl_checkProxyheaders(data, cf->conn, STRCONST("Host"))) { - result = Curl_dynhds_cadd(&req->headers, "Host", authority); - if(result) - goto out; - } - - if(data->req.proxyuserpwd) { - result = Curl_dynhds_h1_cadd_line(&req->headers, - data->req.proxyuserpwd); - if(result) - goto out; - } - - if(!Curl_checkProxyheaders(data, cf->conn, STRCONST("User-Agent")) && - data->set.str[STRING_USERAGENT] && *data->set.str[STRING_USERAGENT]) { - result = Curl_dynhds_cadd(&req->headers, "User-Agent", - data->set.str[STRING_USERAGENT]); - if(result) - goto out; - } - - if(http_version_major == 1 && - !Curl_checkProxyheaders(data, cf->conn, STRCONST("Proxy-Connection"))) { - result = Curl_dynhds_cadd(&req->headers, "Proxy-Connection", "Keep-Alive"); - if(result) - goto out; - } - - result = dynhds_add_custom(data, TRUE, ctx->httpversion, &req->headers); - -out: - if(result && req) { - Curl_http_req_free(req); - req = NULL; - } - curlx_free(authority); - *preq = req; - return result; -} - -static CURLcode http_proxy_cf_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_proxy_ctx *ctx = cf->ctx; - CURLcode result; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - CURL_TRC_CF(data, cf, "connect"); -connect_sub: - result = cf->next->cft->do_connect(cf->next, data, done); - if(result || !*done) - return result; - - *done = FALSE; - if(!ctx->sub_filter_installed) { - int httpversion = 0; - const char *alpn = Curl_conn_cf_get_alpn_negotiated(cf->next, data); - - if(alpn) - infof(data, "CONNECT: '%s' negotiated", alpn); - else - infof(data, "CONNECT: no ALPN negotiated"); - - if(alpn && !strcmp(alpn, "http/1.0")) { - CURL_TRC_CF(data, cf, "installing subfilter for HTTP/1.0"); - result = Curl_cf_h1_proxy_insert_after(cf, data); - if(result) - goto out; - httpversion = 10; - } - else if(!alpn || !strcmp(alpn, "http/1.1")) { - CURL_TRC_CF(data, cf, "installing subfilter for HTTP/1.1"); - result = Curl_cf_h1_proxy_insert_after(cf, data); - if(result) - goto out; - /* Assume that without an ALPN, we are talking to an ancient one */ - httpversion = 11; - } -#ifdef USE_NGHTTP2 - else if(!strcmp(alpn, "h2")) { - CURL_TRC_CF(data, cf, "installing subfilter for HTTP/2"); - result = Curl_cf_h2_proxy_insert_after(cf, data); - if(result) - goto out; - httpversion = 20; - } -#endif - else { - failf(data, "CONNECT: negotiated ALPN '%s' not supported", alpn); - result = CURLE_COULDNT_CONNECT; - goto out; - } - - ctx->sub_filter_installed = TRUE; - ctx->httpversion = httpversion; - /* after we installed the filter "below" us, we call connect - * on out sub-chain again. - */ - goto connect_sub; - } - else { - /* subchain connected and we had already installed the protocol filter. - * This means the protocol tunnel is established, we are done. - */ - DEBUGASSERT(ctx->sub_filter_installed); - result = CURLE_OK; - } - -out: - if(!result) { - cf->connected = TRUE; - *done = TRUE; - } - return result; -} - -CURLcode Curl_cf_http_proxy_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - switch(query) { - case CF_QUERY_HOST_PORT: - *pres1 = (int)cf->conn->http_proxy.port; - *((const char **)pres2) = cf->conn->http_proxy.host.name; - return CURLE_OK; - case CF_QUERY_ALPN_NEGOTIATED: { - const char **palpn = pres2; - DEBUGASSERT(palpn); - *palpn = NULL; - return CURLE_OK; - } - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -static void http_proxy_cf_destroy(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_proxy_ctx *ctx = cf->ctx; - - CURL_TRC_CF(data, cf, "destroy"); - curlx_free(ctx); -} - -static void http_proxy_cf_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURL_TRC_CF(data, cf, "close"); - cf->connected = FALSE; - if(cf->next) - cf->next->cft->do_close(cf->next, data); -} - -struct Curl_cftype Curl_cft_http_proxy = { - "HTTP-PROXY", - CF_TYPE_IP_CONNECT | CF_TYPE_PROXY | CF_TYPE_SETUP, - 0, - http_proxy_cf_destroy, - http_proxy_cf_connect, - http_proxy_cf_close, - Curl_cf_def_shutdown, - Curl_cf_def_adjust_pollset, - Curl_cf_def_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - Curl_cf_def_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - Curl_cf_http_proxy_query, -}; - -CURLcode Curl_cf_http_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf; - struct cf_proxy_ctx *ctx = NULL; - CURLcode result; - - (void)data; - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - result = Curl_cf_create(&cf, &Curl_cft_http_proxy, ctx); - if(result) - goto out; - ctx = NULL; - Curl_conn_cf_insert_after(cf_at, cf); - -out: - curlx_free(ctx); - return result; -} - -#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */ diff --git a/vendor/curl/lib/http_proxy.h b/vendor/curl/lib/http_proxy.h deleted file mode 100644 index 155b222ed..000000000 --- a/vendor/curl/lib/http_proxy.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef HEADER_CURL_HTTP_PROXY_H -#define HEADER_CURL_HTTP_PROXY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP) - -#include "urldata.h" - -enum Curl_proxy_use { - HEADER_SERVER, /* direct to server */ - HEADER_PROXY, /* regular request to proxy */ - HEADER_CONNECT /* sending CONNECT to a proxy */ -}; - -void Curl_http_proxy_get_destination(struct Curl_cfilter *cf, - const char **phostname, - uint16_t *pport, bool *pipv6_ip); - -CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq, - struct Curl_cfilter *cf, - struct Curl_easy *data, - int http_version_major); - -/* Default proxy timeout in milliseconds */ -#define PROXY_TIMEOUT (3600 * 1000) - -CURLcode Curl_cf_http_proxy_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2); - -CURLcode Curl_cf_http_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data); - -extern struct Curl_cftype Curl_cft_http_proxy; - -#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */ - -#define IS_HTTPS_PROXY(t) (((t) == CURLPROXY_HTTPS) || \ - ((t) == CURLPROXY_HTTPS2)) - -#endif /* HEADER_CURL_HTTP_PROXY_H */ diff --git a/vendor/curl/lib/httpsrr.c b/vendor/curl/lib/httpsrr.c deleted file mode 100644 index 90fcb524e..000000000 --- a/vendor/curl/lib/httpsrr.c +++ /dev/null @@ -1,311 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_HTTPSRR - -#include "urldata.h" -#include "httpsrr.h" -#include "connect.h" -#include "curl_trc.h" -#include "curlx/strdup.h" -#include "curlx/inet_ntop.h" - -static CURLcode httpsrr_decode_alpn(const uint8_t *cp, size_t len, - unsigned char *alpns) -{ - /* - * The wire-format value for "alpn" consists of at least one alpn-id - * prefixed by its length as a single octet, and these length-value pairs - * are concatenated to form the SvcParamValue. These pairs MUST exactly fill - * the SvcParamValue; otherwise, the SvcParamValue is malformed. - */ - int idnum = 0; - - while(len > 0) { - size_t tlen = *cp++; - enum alpnid id; - len--; - if(tlen > len) - return CURLE_BAD_CONTENT_ENCODING; - - /* we only store ALPN ids we know about */ - id = Curl_alpn2alpnid(cp, tlen); - if(id != ALPN_none) { - if(idnum == MAX_HTTPSRR_ALPNS) - break; - if(idnum && memchr(alpns, id, idnum)) - /* this ALPN id is already stored */ - ; - else - alpns[idnum++] = (unsigned char)id; - } - cp += tlen; - len -= tlen; - } - if(idnum < MAX_HTTPSRR_ALPNS) - alpns[idnum] = ALPN_none; /* terminate the list */ - return CURLE_OK; -} - -#ifdef CURLVERBOSE - -static CURLcode httpsrr_print_addr(struct dynbuf *dyn, - int ai_family, - const uint8_t *addr, - size_t total_len) -{ - char buf[MAX_IPADR_LEN]; - size_t i, alen = (ai_family == AF_INET6) ? 16 : 4; - const char *sep = ""; - CURLcode result = CURLE_OK; - - for(i = 0; (i < (total_len / alen)) && !result; ++i) { - if(!curlx_inet_ntop(ai_family, addr + (i * alen), buf, sizeof(buf))) - result = curlx_dyn_add(dyn, ""); - else - result = curlx_dyn_addf(dyn, "%s%s", sep, buf); - sep = ","; - } - return result; -} - -void Curl_httpsrr_trace(struct Curl_easy *data, - struct Curl_https_rrinfo *rr) -{ - struct dynbuf tmp; - CURLcode result; - - if(!rr || !rr->complete) { - CURL_TRC_DNS(data, "[HTTPS-RR] not available"); - return; - } - curlx_dyn_init(&tmp, 1024); - result = Curl_httpsrr_print(&tmp, rr); - if(!result) - CURL_TRC_DNS(data, "HTTPS-RR: %s", curlx_dyn_ptr(&tmp)); - else - CURL_TRC_DNS(data, "Error printing HTTPS-RR information"); - curlx_dyn_free(&tmp); -} - -CURLcode Curl_httpsrr_print(struct dynbuf *tmp, - struct Curl_https_rrinfo *rr) -{ - CURLcode result; - int i; - - curlx_dyn_reset(tmp); - result = curlx_dyn_addf(tmp, "%u %s", rr->priority, - rr->target ? rr->target : "."); - if(!result && rr->mandatory) - result = curlx_dyn_add(tmp, " mandatory-keys(ignored)"); - if(!result && rr->alpns[0]) { - const char *sep = "", *name; - result = curlx_dyn_add(tmp, " alpn="); - for(i = 0; !result && (i < 4); ++i) { - switch(rr->alpns[i]) { - case ALPN_h1: - name = "http/1.1"; - break; - case ALPN_h2: - name = "h2"; - break; - case ALPN_h3: - name = "h3"; - break; - default: - name = NULL; - } - if(name) { - result = curlx_dyn_addf(tmp, "%s%s", sep, name); - sep = ","; - } - } - } - if(!result && rr->port_set) { - result = curlx_dyn_addf(tmp, " port=%u", rr->port); - } - if(!result && rr->no_def_alpn) - result = curlx_dyn_add(tmp, " no-default-alpn"); - if(!result && rr->ipv6hints_len) { - result = curlx_dyn_add(tmp, " ipv6hint="); - if(!result) - result = httpsrr_print_addr( - tmp, AF_INET6, rr->ipv6hints, rr->ipv6hints_len); - } - if(!result && rr->ipv4hints_len) { - result = curlx_dyn_add(tmp, " ipv4hint="); - if(!result) - result = httpsrr_print_addr( - tmp, AF_INET, rr->ipv4hints, rr->ipv4hints_len); - } - if(!result && rr->echconfiglist_len) - result = curlx_dyn_addf(tmp, " ech=<%zu bytes>", rr->echconfiglist_len); - - return result; -} - -#endif /* CURLVERBOSE */ - -CURLcode Curl_httpsrr_set(struct Curl_https_rrinfo *rr, - uint16_t rrkey, const uint8_t *val, size_t vlen) -{ - CURLcode result = CURLE_OK; - switch(rrkey) { - case HTTPS_RR_CODE_MANDATORY: - rr->mandatory = TRUE; - break; - case HTTPS_RR_CODE_ALPN: /* str_list */ - result = httpsrr_decode_alpn(val, vlen, rr->alpns); - break; - case HTTPS_RR_CODE_NO_DEF_ALPN: - if(vlen) /* no data */ - return CURLE_BAD_FUNCTION_ARGUMENT; - rr->no_def_alpn = TRUE; - break; - case HTTPS_RR_CODE_IPV4: /* addr4 list */ - if(!vlen || (vlen & 3)) /* the size must be 4-byte aligned */ - return CURLE_BAD_FUNCTION_ARGUMENT; - curlx_free(rr->ipv4hints); - rr->ipv4hints = curlx_memdup(val, vlen); - if(!rr->ipv4hints) - return CURLE_OUT_OF_MEMORY; - rr->ipv4hints_len = vlen; - break; - case HTTPS_RR_CODE_ECH: - if(!vlen) - return CURLE_BAD_FUNCTION_ARGUMENT; - curlx_free(rr->echconfiglist); - rr->echconfiglist = curlx_memdup(val, vlen); - if(!rr->echconfiglist) - return CURLE_OUT_OF_MEMORY; - rr->echconfiglist_len = vlen; - break; - case HTTPS_RR_CODE_IPV6: /* addr6 list */ - if(!vlen || (vlen & 15)) /* the size must be 16-byte aligned */ - return CURLE_BAD_FUNCTION_ARGUMENT; - curlx_free(rr->ipv6hints); - rr->ipv6hints = curlx_memdup(val, vlen); - if(!rr->ipv6hints) - return CURLE_OUT_OF_MEMORY; - rr->ipv6hints_len = vlen; - break; - case HTTPS_RR_CODE_PORT: - if(vlen != 2) - return CURLE_BAD_FUNCTION_ARGUMENT; - rr->port = (uint16_t)((val[0] << 8) | val[1]); - rr->port_set = TRUE; - break; - default: - /* unknown code */ - break; - } - return result; -} - -struct Curl_https_rrinfo *Curl_httpsrr_dup_move( - struct Curl_https_rrinfo *rrinfo) -{ - struct Curl_https_rrinfo *dup = curlx_memdup(rrinfo, sizeof(*rrinfo)); - if(dup) - memset(rrinfo, 0, sizeof(*rrinfo)); - return dup; -} - -void Curl_httpsrr_cleanup(struct Curl_https_rrinfo *rrinfo) -{ - curlx_safefree(rrinfo->target); - curlx_safefree(rrinfo->echconfiglist); - curlx_safefree(rrinfo->ipv4hints); - curlx_safefree(rrinfo->ipv6hints); - curlx_safefree(rrinfo->rrname); - rrinfo->complete = FALSE; -} - -bool Curl_httpsrr_applicable(struct Curl_easy *data, - const struct Curl_https_rrinfo *rr) -{ - if(!data->conn || !rr) - return FALSE; - return (!rr->target || !rr->target[0] || - (rr->target[0] == '.' && !rr->target[1])) && - (!rr->port_set || rr->port == data->conn->remote_port); -} - -#ifdef USE_ARES - -static CURLcode httpsrr_opt(const ares_dns_rr_t *rr, - ares_dns_rr_key_t key, size_t idx, - struct Curl_https_rrinfo *hinfo) -{ - const unsigned char *val = NULL; - unsigned short code; - size_t len = 0; - - code = ares_dns_rr_get_opt(rr, key, idx, &val, &len); - return Curl_httpsrr_set(hinfo, code, val, len); -} - -CURLcode Curl_httpsrr_from_ares(const ares_dns_record_t *dnsrec, - struct Curl_https_rrinfo *hinfo) -{ - CURLcode result = CURLE_OK; - size_t i; - - for(i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) { - const char *target; - size_t opt; - const ares_dns_rr_t *rr = - ares_dns_record_rr_get_const(dnsrec, ARES_SECTION_ANSWER, i); - if(ares_dns_rr_get_type(rr) != ARES_REC_TYPE_HTTPS) - continue; - /* When SvcPriority is 0, the SVCB record is in AliasMode. Otherwise, it - is in ServiceMode */ - target = ares_dns_rr_get_str(rr, ARES_RR_HTTPS_TARGET); - if(target && target[0]) { - curlx_free(hinfo->target); - hinfo->target = curlx_strdup(target); - if(!hinfo->target) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - hinfo->priority = ares_dns_rr_get_u16(rr, ARES_RR_HTTPS_PRIORITY); - for(opt = 0; opt < ares_dns_rr_get_opt_cnt(rr, ARES_RR_HTTPS_PARAMS); - opt++) { - result = httpsrr_opt(rr, ARES_RR_HTTPS_PARAMS, opt, hinfo); - if(result) - break; - } - } -out: - hinfo->complete = !result; - curlx_safefree(hinfo->rrname); - return result; -} - -#endif /* USE_ARES */ - -#endif /* USE_HTTPSRR */ diff --git a/vendor/curl/lib/httpsrr.h b/vendor/curl/lib/httpsrr.h deleted file mode 100644 index 28a790d17..000000000 --- a/vendor/curl/lib/httpsrr.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef HEADER_CURL_HTTPSRR_H -#define HEADER_CURL_HTTPSRR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_ARES -#include -#endif - -#ifdef USE_HTTPSRR - -#define CURL_MAXLEN_host_name 253 -#define MAX_HTTPSRR_ALPNS 4 - -struct Curl_easy; -struct dynbuf; - -struct Curl_https_rrinfo { - char *rrname; /* if NULL, the same as the URL hostname */ - /* - * Fields from HTTPS RR. The only mandatory fields are priority and target. - * See https://datatracker.ietf.org/doc/html/rfc9460#section-14.3.2 - */ - char *target; - unsigned char *ipv4hints; /* keytag = 4 */ - size_t ipv4hints_len; - unsigned char *echconfiglist; /* keytag = 5 */ - size_t echconfiglist_len; - unsigned char *ipv6hints; /* keytag = 6 */ - size_t ipv6hints_len; - unsigned char alpns[MAX_HTTPSRR_ALPNS]; /* keytag = 1 */ - /* store parsed alpnid entries in the array, end with ALPN_none */ - uint16_t port; - uint16_t priority; - BIT(no_def_alpn); /* keytag = 2 */ - BIT(mandatory); /* keytag = 0 */ - BIT(port_set); /* port value has been assigned */ - BIT(complete); /* values have been successfully assigned */ -}; - -CURLcode Curl_httpsrr_set(struct Curl_https_rrinfo *rr, - uint16_t rrkey, const uint8_t *val, size_t vlen); - -struct Curl_https_rrinfo *Curl_httpsrr_dup_move( - struct Curl_https_rrinfo *rrinfo); - -void Curl_httpsrr_cleanup(struct Curl_https_rrinfo *rrinfo); - -/* TRUE if the record is applicable to the transfer and its connection. */ -bool Curl_httpsrr_applicable(struct Curl_easy *data, - const struct Curl_https_rrinfo *rr); - -/* - * Code points for DNS wire format SvcParams as per RFC 9460 - */ -#define HTTPS_RR_CODE_MANDATORY 0x00 -#define HTTPS_RR_CODE_ALPN 0x01 -#define HTTPS_RR_CODE_NO_DEF_ALPN 0x02 -#define HTTPS_RR_CODE_PORT 0x03 -#define HTTPS_RR_CODE_IPV4 0x04 -#define HTTPS_RR_CODE_ECH 0x05 -#define HTTPS_RR_CODE_IPV6 0x06 - -#ifdef USE_ARES -CURLcode Curl_httpsrr_from_ares(const ares_dns_record_t *dnsrec, - struct Curl_https_rrinfo *hinfo); -#endif /* USE_ARES */ - -#ifdef CURLVERBOSE -CURLcode Curl_httpsrr_print(struct dynbuf *tmp, - struct Curl_https_rrinfo *rr); -void Curl_httpsrr_trace(struct Curl_easy *data, - struct Curl_https_rrinfo *rr); -#else -#define Curl_httpsrr_trace(a, b) Curl_nop_stmt -#endif - -#endif /* USE_HTTPSRR */ - -#endif /* HEADER_CURL_HTTPSRR_H */ diff --git a/vendor/curl/lib/idn.c b/vendor/curl/lib/idn.c deleted file mode 100644 index f2b954e2d..000000000 --- a/vendor/curl/lib/idn.c +++ /dev/null @@ -1,376 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * IDN conversions - */ -#include "curl_setup.h" - -#include "urldata.h" -#include "idn.h" - -#ifdef USE_LIBIDN2 -#include - -#if defined(_WIN32) && defined(UNICODE) -#define IDN2_LOOKUP(name, host, flags) \ - idn2_lookup_u8((const uint8_t *)name, (uint8_t **)host, flags) -#else -#define IDN2_LOOKUP(name, host, flags) \ - idn2_lookup_ul((const char *)(name), (char **)(host), flags) -#endif -#endif /* USE_LIBIDN2 */ - -/* for macOS and iOS targets */ -#ifdef USE_APPLE_IDN -#include -#include -#include - -#define MAX_HOST_LENGTH 512 - -static CURLcode iconv_to_utf8(const char *in, size_t inlen, - char **out, size_t *outlen) -{ - iconv_t cd = iconv_open("UTF-8", nl_langinfo(CODESET)); - if(cd != (iconv_t)-1) { - size_t iconv_outlen = *outlen; - char *iconv_in = (char *)CURL_UNCONST(in); - size_t iconv_inlen = inlen; - size_t iconv_result = iconv(cd, &iconv_in, &iconv_inlen, - out, &iconv_outlen); - *outlen -= iconv_outlen; - iconv_close(cd); - if(iconv_result == (size_t)-1) { - /* !checksrc! disable ERRNOVAR 1 */ - if(errno == ENOMEM) - return CURLE_OUT_OF_MEMORY; - else - return CURLE_URL_MALFORMAT; - } - - return CURLE_OK; - } - else { - /* !checksrc! disable ERRNOVAR 1 */ - if(errno == ENOMEM) - return CURLE_OUT_OF_MEMORY; - else - return CURLE_FAILED_INIT; - } -} - -static CURLcode mac_idn_to_ascii(const char *in, char **out) -{ - size_t inlen = strlen(in); - if(inlen < MAX_HOST_LENGTH) { - char iconv_buffer[MAX_HOST_LENGTH] = { 0 }; - char *iconv_outptr = iconv_buffer; - size_t iconv_outlen = sizeof(iconv_buffer); - CURLcode iconv_result = iconv_to_utf8(in, inlen, - &iconv_outptr, &iconv_outlen); - if(!iconv_result) { - UErrorCode err = U_ZERO_ERROR; - UIDNA *idna = uidna_openUTS46( - UIDNA_CHECK_BIDI | UIDNA_NONTRANSITIONAL_TO_ASCII, &err); - if(!U_FAILURE(err)) { - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - char buffer[MAX_HOST_LENGTH] = { 0 }; - (void)uidna_nameToASCII_UTF8(idna, iconv_buffer, (int)iconv_outlen, - buffer, sizeof(buffer) - 1, &info, &err); - uidna_close(idna); - if(!U_FAILURE(err) && !info.errors) { - *out = curlx_strdup(buffer); - if(*out) - return CURLE_OK; - else - return CURLE_OUT_OF_MEMORY; - } - } - } - else - return iconv_result; - } - return CURLE_URL_MALFORMAT; -} - -static CURLcode mac_ascii_to_idn(const char *in, char **out) -{ - size_t inlen = strlen(in); - if(inlen < MAX_HOST_LENGTH) { - UErrorCode err = U_ZERO_ERROR; - UIDNA *idna = uidna_openUTS46( - UIDNA_CHECK_BIDI | UIDNA_NONTRANSITIONAL_TO_UNICODE, &err); - if(!U_FAILURE(err)) { - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - char buffer[MAX_HOST_LENGTH] = { 0 }; - (void)uidna_nameToUnicodeUTF8(idna, in, -1, buffer, - sizeof(buffer) - 1, &info, &err); - uidna_close(idna); - if(!U_FAILURE(err)) { - *out = curlx_strdup(buffer); - if(*out) - return CURLE_OK; - else - return CURLE_OUT_OF_MEMORY; - } - } - } - return CURLE_URL_MALFORMAT; -} -#endif - -#ifdef USE_WIN32_IDN -/* using Windows kernel32 and normaliz libraries. */ - -#define IDN_MAX_LENGTH 255 - -static char *idn_curlx_convert_wchar_to_UTF8(const wchar_t *str_w, int chars) -{ - char *str_utf8 = NULL; - int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, chars, NULL, 0, - NULL, NULL); - if(bytes > 0) { - str_utf8 = curlx_malloc(bytes); - if(str_utf8) { - if(WideCharToMultiByte(CP_UTF8, 0, str_w, chars, str_utf8, bytes, - NULL, NULL) == 0) { - curlx_free(str_utf8); - return NULL; - } - } - } - return str_utf8; -} - -static CURLcode win32_idn_to_ascii(const char *in, char **out) -{ - wchar_t in_w[IDN_MAX_LENGTH]; - int in_w_len; - *out = NULL; - /* Returned in_w_len includes the null-terminator, which then gets - preserved across the calls that follow, ending up terminating - the buffer returned to the caller. */ - in_w_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, in_w, IDN_MAX_LENGTH); - if(in_w_len) { - wchar_t punycode[IDN_MAX_LENGTH]; - int chars = IdnToAscii(0, in_w, in_w_len, punycode, IDN_MAX_LENGTH); - if(chars > 0) { - *out = idn_curlx_convert_wchar_to_UTF8(punycode, chars); - if(!*out) - return CURLE_OUT_OF_MEMORY; - } - else - return CURLE_URL_MALFORMAT; - } - else - return CURLE_URL_MALFORMAT; - - return CURLE_OK; -} - -static CURLcode win32_ascii_to_idn(const char *in, char **out) -{ - wchar_t in_w[IDN_MAX_LENGTH]; - int in_w_len; - *out = NULL; - /* Returned in_w_len includes the null-terminator, which then gets - preserved across the calls that follow, ending up terminating - the buffer returned to the caller. */ - in_w_len = MultiByteToWideChar(CP_UTF8, 0, in, -1, in_w, IDN_MAX_LENGTH); - if(in_w_len) { - WCHAR idn[IDN_MAX_LENGTH]; /* stores a UTF-16 string */ - int chars = IdnToUnicode(0, in_w, in_w_len, idn, IDN_MAX_LENGTH); - if(chars > 0) { /* 'chars' is "the number of characters retrieved" */ - *out = idn_curlx_convert_wchar_to_UTF8(idn, chars); - if(!*out) - return CURLE_OUT_OF_MEMORY; - } - else - return CURLE_URL_MALFORMAT; - } - else - return CURLE_URL_MALFORMAT; - - return CURLE_OK; -} - -#endif /* USE_WIN32_IDN */ - -/* - * Helpers for IDNA conversions. - */ -bool Curl_is_ASCII_name(const char *hostname) -{ - /* get an UNSIGNED local version of the pointer */ - const unsigned char *ch = (const unsigned char *)hostname; - - if(!hostname) /* bad input, consider it ASCII! */ - return TRUE; - - while(*ch) { - if(*ch++ & 0x80) - return FALSE; - } - return TRUE; -} - -#ifdef USE_IDN -/* - * Curl_idn_decode() returns an allocated IDN decoded string if it was - * possible. NULL on error. - * - * CURLE_URL_MALFORMAT - the hostname could not be converted - * CURLE_OUT_OF_MEMORY - memory problem - * - */ -static CURLcode idn_decode(const char *input, char **output) -{ - char *decoded = NULL; - CURLcode result = CURLE_OK; -#ifdef USE_LIBIDN2 - if(idn2_check_version(IDN2_VERSION)) { - int flags = IDN2_NFC_INPUT -#if IDN2_VERSION_NUMBER >= 0x00140000 - /* IDN2_NFC_INPUT: Normalize input string using normalization form C. - IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional - processing. */ - | IDN2_NONTRANSITIONAL -#endif - ; - int rc = IDN2_LOOKUP(input, &decoded, flags); - if(rc != IDN2_OK) - /* fallback to TR46 Transitional mode for better IDNA2003 - compatibility */ - rc = IDN2_LOOKUP(input, &decoded, IDN2_TRANSITIONAL); - if(rc != IDN2_OK) - result = CURLE_URL_MALFORMAT; - } - else - /* a too old libidn2 version */ - result = CURLE_NOT_BUILT_IN; -#elif defined(USE_WIN32_IDN) - result = win32_idn_to_ascii(input, &decoded); -#elif defined(USE_APPLE_IDN) - result = mac_idn_to_ascii(input, &decoded); -#endif - if(!result) - *output = decoded; - return result; -} - -static CURLcode idn_encode(const char *puny, char **output) -{ - char *enc = NULL; -#ifdef USE_LIBIDN2 - int rc = idn2_to_unicode_8z8z(puny, &enc, 0); - if(rc != IDNA_SUCCESS) - return rc == IDNA_MALLOC_ERROR ? CURLE_OUT_OF_MEMORY : CURLE_URL_MALFORMAT; -#elif defined(USE_WIN32_IDN) - CURLcode result = win32_ascii_to_idn(puny, &enc); - if(result) - return result; -#elif defined(USE_APPLE_IDN) - CURLcode result = mac_ascii_to_idn(puny, &enc); - if(result) - return result; -#endif - *output = enc; - return CURLE_OK; -} - -CURLcode Curl_idn_decode(const char *input, char **output) -{ - char *d = NULL; - CURLcode result = idn_decode(input, &d); -#ifdef USE_LIBIDN2 - if(!result) { - char *c = curlx_strdup(d); - idn2_free(d); - if(c) - d = c; - else - result = CURLE_OUT_OF_MEMORY; - } -#endif - if(!result) { - if(!d[0]) { /* ended up zero length, not acceptable */ - result = CURLE_URL_MALFORMAT; - curlx_free(d); - } - else - *output = d; - } - return result; -} - -CURLcode Curl_idn_encode(const char *puny, char **output) -{ - char *d = NULL; - CURLcode result = idn_encode(puny, &d); -#ifdef USE_LIBIDN2 - if(!result) { - char *c = curlx_strdup(d); - idn2_free(d); - if(c) - d = c; - else - result = CURLE_OUT_OF_MEMORY; - } -#endif - if(!result) - *output = d; - return result; -} - -/* - * Frees data allocated by idnconvert_hostname() - */ -void Curl_free_idnconverted_hostname(struct hostname *host) -{ - curlx_safefree(host->encalloc); -} - -#endif /* USE_IDN */ - -/* - * Perform any necessary IDN conversion of hostname - */ -CURLcode Curl_idnconvert_hostname(struct hostname *host) -{ - /* set the name we use to display the hostname */ - host->dispname = host->name; - -#ifdef USE_IDN - /* Check name for non-ASCII and convert hostname if we can */ - if(!Curl_is_ASCII_name(host->name)) { - char *decoded; - CURLcode result = Curl_idn_decode(host->name, &decoded); - if(result) - return result; - /* successful */ - host->name = host->encalloc = decoded; - } -#endif - return CURLE_OK; -} diff --git a/vendor/curl/lib/idn.h b/vendor/curl/lib/idn.h deleted file mode 100644 index 90d8e811b..000000000 --- a/vendor/curl/lib/idn.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_IDN_H -#define HEADER_CURL_IDN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -bool Curl_is_ASCII_name(const char *hostname); -CURLcode Curl_idnconvert_hostname(struct hostname *host); - -#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) -#define USE_IDN -void Curl_free_idnconverted_hostname(struct hostname *host); -CURLcode Curl_idn_decode(const char *input, char **output); -CURLcode Curl_idn_encode(const char *puny, char **output); -#else -#define Curl_free_idnconverted_hostname(x) -#define Curl_idn_decode(x) NULL -#endif - -#endif /* HEADER_CURL_IDN_H */ diff --git a/vendor/curl/lib/if2ip.c b/vendor/curl/lib/if2ip.c deleted file mode 100644 index b71254ada..000000000 --- a/vendor/curl/lib/if2ip.c +++ /dev/null @@ -1,262 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_NET_IF_H -# include -#endif -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_SYS_SOCKIO_H -# include -#endif -#ifdef HAVE_IFADDRS_H -# include -#endif -#ifdef HAVE_STROPTS_H -# include -#endif -#ifdef __VMS -# include -#endif - -#include "curlx/inet_ntop.h" -#include "if2ip.h" - -/* ------------------------------------------------------------------ */ - -#ifdef USE_IPV6 -/* Return the scope of the given address. */ -unsigned int Curl_ipv6_scope(const struct sockaddr *sa) -{ - if(sa->sa_family == AF_INET6) { - const struct sockaddr_in6 *sa6 = - (const struct sockaddr_in6 *)(const void *)sa; - const unsigned char *b = sa6->sin6_addr.s6_addr; - unsigned short w = (unsigned short)((b[0] << 8) | b[1]); - - if((b[0] & 0xFE) == 0xFC) /* Handle ULAs */ - return IPV6_SCOPE_UNIQUELOCAL; - switch(w & 0xFFC0) { - case 0xFE80: - return IPV6_SCOPE_LINKLOCAL; - case 0xFEC0: - return IPV6_SCOPE_SITELOCAL; - case 0x0000: - w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] | - b[10] | b[11] | b[12] | b[13] | b[14]; - if(w || b[15] != 0x01) - break; - return IPV6_SCOPE_NODELOCAL; - default: - break; - } - } - return IPV6_SCOPE_GLOBAL; -} -#endif - -#if !defined(CURL_DISABLE_BINDLOCAL) || !defined(CURL_DISABLE_FTP) - -#ifdef HAVE_GETIFADDRS - -if2ip_result_t Curl_if2ip(int af, -#ifdef USE_IPV6 - unsigned int remote_scope, - unsigned int local_scope_id, -#endif - const char *interf, - char *buf, size_t buf_size) -{ - struct ifaddrs *iface, *head; - if2ip_result_t res = IF2IP_NOT_FOUND; - -#if defined(USE_IPV6) && !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) - (void)local_scope_id; -#endif - - if(getifaddrs(&head) >= 0) { - for(iface = head; iface != NULL; iface = iface->ifa_next) { - if(iface->ifa_addr) { - if(iface->ifa_addr->sa_family == af) { - if(curl_strequal(iface->ifa_name, interf)) { - void *addr; - const char *ip; - char scope[12] = ""; - char ipstr[64]; -#ifdef USE_IPV6 - if(af == AF_INET6) { -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - unsigned int scopeid = 0; -#endif - unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr); - - if(ifscope != remote_scope) { - /* We are interested only in interface addresses whose scope - matches the remote address we want to connect to: global - for global, link-local for link-local, etc... */ - if(res == IF2IP_NOT_FOUND) - res = IF2IP_AF_NOT_SUPPORTED; - continue; - } - - addr = - &((struct sockaddr_in6 *)(void *)iface->ifa_addr)->sin6_addr; -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - /* Include the scope of this interface as part of the address */ - scopeid = ((struct sockaddr_in6 *)(void *)iface->ifa_addr) - ->sin6_scope_id; - - /* If given, scope id should match. */ - if(local_scope_id && scopeid != local_scope_id) { - if(res == IF2IP_NOT_FOUND) - res = IF2IP_AF_NOT_SUPPORTED; - - continue; - } - - if(scopeid) - curl_msnprintf(scope, sizeof(scope), "%%%u", scopeid); -#endif - } - else -#endif - addr = - &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr; - res = IF2IP_FOUND; - ip = curlx_inet_ntop(af, addr, ipstr, sizeof(ipstr)); - curl_msnprintf(buf, buf_size, "%s%s", ip, scope); - break; - } - } - else if((res == IF2IP_NOT_FOUND) && - curl_strequal(iface->ifa_name, interf)) { - res = IF2IP_AF_NOT_SUPPORTED; - } - } - } - - freeifaddrs(head); - } - - return res; -} - -#elif defined(HAVE_IOCTL_SIOCGIFADDR) - -if2ip_result_t Curl_if2ip(int af, -#ifdef USE_IPV6 - unsigned int remote_scope, - unsigned int local_scope_id, -#endif - const char *interf, - char *buf, size_t buf_size) -{ - struct ifreq req; - struct in_addr in; - struct sockaddr_in *s; - curl_socket_t dummy; - size_t len; - const char *r; - -#ifdef USE_IPV6 - (void)remote_scope; - (void)local_scope_id; -#endif - - if(!interf || (af != AF_INET)) - return IF2IP_NOT_FOUND; - - len = strlen(interf); - if(len >= sizeof(req.ifr_name)) - return IF2IP_NOT_FOUND; - - dummy = CURL_SOCKET(AF_INET, SOCK_STREAM, 0); - if(dummy == CURL_SOCKET_BAD) - return IF2IP_NOT_FOUND; - - memset(&req, 0, sizeof(req)); - memcpy(req.ifr_name, interf, len + 1); - req.ifr_addr.sa_family = AF_INET; - -#if defined(CURL_HAVE_DIAG) && defined(_AIX) -/* Suppress warning inside system headers */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshift-sign-overflow" -#endif - if(ioctl(dummy, SIOCGIFADDR, &req) < 0) { -#if defined(CURL_HAVE_DIAG) && defined(_AIX) -#pragma GCC diagnostic pop -#endif - sclose(dummy); - /* With SIOCGIFADDR, we cannot tell the difference between an interface - that does not exist and an interface that has no address of the - correct family. Assume the interface does not exist */ - return IF2IP_NOT_FOUND; - } - - s = (struct sockaddr_in *)(void *)&req.ifr_addr; - memcpy(&in, &s->sin_addr, sizeof(in)); - r = curlx_inet_ntop(s->sin_family, &in, buf, buf_size); - - sclose(dummy); - if(!r) - return IF2IP_NOT_FOUND; - return IF2IP_FOUND; -} - -#else - -if2ip_result_t Curl_if2ip(int af, -#ifdef USE_IPV6 - unsigned int remote_scope, - unsigned int local_scope_id, -#endif - const char *interf, - char *buf, size_t buf_size) -{ - (void)af; -#ifdef USE_IPV6 - (void)remote_scope; - (void)local_scope_id; -#endif - (void)interf; - (void)buf; - (void)buf_size; - return IF2IP_NOT_FOUND; -} - -#endif - -#endif /* CURL_DISABLE_BINDLOCAL && CURL_DISABLE_FTP */ diff --git a/vendor/curl/lib/if2ip.h b/vendor/curl/lib/if2ip.h deleted file mode 100644 index 12fdaabd7..000000000 --- a/vendor/curl/lib/if2ip.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef HEADER_CURL_IF2IP_H -#define HEADER_CURL_IF2IP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* IPv6 address scopes. */ -#define IPV6_SCOPE_GLOBAL 0 /* Global scope. */ -#define IPV6_SCOPE_LINKLOCAL 1 /* Link-local scope. */ -#define IPV6_SCOPE_SITELOCAL 2 /* Site-local scope (deprecated). */ -#define IPV6_SCOPE_UNIQUELOCAL 3 /* Unique local */ -#define IPV6_SCOPE_NODELOCAL 4 /* Loopback. */ - -#ifdef USE_IPV6 -unsigned int Curl_ipv6_scope(const struct sockaddr *sa); -#else -#define Curl_ipv6_scope(x) 0 -#endif - -typedef enum { - IF2IP_NOT_FOUND = 0, /* Interface not found */ - IF2IP_AF_NOT_SUPPORTED = 1, /* Int. exists but has no address for this af */ - IF2IP_FOUND = 2 /* The address has been stored in "buf" */ -} if2ip_result_t; - -if2ip_result_t Curl_if2ip(int af, -#ifdef USE_IPV6 - unsigned int remote_scope, - unsigned int local_scope_id, -#endif - const char *interf, - char *buf, size_t buf_size); - -#ifdef __INTERIX - -/* Nedelcho Stanev's work-around for SFU 3.0 */ -struct ifreq { -#define IFNAMSIZ 16 -#define IFHWADDRLEN 6 - union { - char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - } ifr_ifrn; - - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_broadaddr; - struct sockaddr ifru_netmask; - struct sockaddr ifru_hwaddr; - short ifru_flags; - int ifru_metric; - int ifru_mtu; - } ifr_ifru; -}; - -/* This define exists to avoid an extra #ifdef INTERIX in the C code. */ - -#define ifr_name ifr_ifrn.ifrn_name /* interface name */ -#define ifr_addr ifr_ifru.ifru_addr /* address */ -#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ -#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ -#define ifr_flags ifr_ifru.ifru_flags /* flags */ -#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ -#define ifr_metric ifr_ifru.ifru_metric /* metric */ -#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ - -#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */ - -#endif /* __INTERIX */ - -#endif /* HEADER_CURL_IF2IP_H */ diff --git a/vendor/curl/lib/imap.c b/vendor/curl/lib/imap.c deleted file mode 100644 index 5ef2a2cb2..000000000 --- a/vendor/curl/lib/imap.c +++ /dev/null @@ -1,2326 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC2195 CRAM-MD5 authentication - * RFC2595 Using TLS with IMAP, POP3 and ACAP - * RFC2831 DIGEST-MD5 authentication - * RFC3501 IMAPv4 protocol - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * RFC4959 IMAP Extension for SASL Initial Client Response - * RFC5092 IMAP URL Scheme - * RFC6749 OAuth 2.0 Authorization Framework - * RFC8314 Use of TLS for Email Submission and Access - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "imap.h" - -#ifndef CURL_DISABLE_IMAP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "curlx/dynbuf.h" -#include "sendf.h" -#include "curl_trc.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "pingpong.h" -#include "mime.h" -#include "curlx/strparse.h" -#include "strcase.h" -#include "vtls/vtls.h" -#include "cfilters.h" -#include "connect.h" -#include "select.h" -#include "url.h" -#include "bufref.h" -#include "curl_sasl.h" -#include "curlx/strcopy.h" - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_IMAP_EASY "meta:proto:imap:easy" -/* meta key for storing protocol meta at connection */ -#define CURL_META_IMAP_CONN "meta:proto:imap:conn" - -typedef enum { - IMAP_STOP, /* do nothing state, stops the state machine */ - IMAP_SERVERGREET, /* waiting for the initial greeting immediately after - a connect */ - IMAP_CAPABILITY, - IMAP_STARTTLS, - IMAP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS - (multi mode only) */ - IMAP_AUTHENTICATE, - IMAP_LOGIN, - IMAP_LIST, - IMAP_SELECT, - IMAP_FETCH, - IMAP_FETCH_FINAL, - IMAP_APPEND, - IMAP_APPEND_FINAL, - IMAP_SEARCH, - IMAP_LOGOUT, - IMAP_LAST /* never used */ -} imapstate; - -/* imap_conn is used for struct connection-oriented data */ -struct imap_conn { - struct pingpong pp; - struct SASL sasl; /* SASL-related parameters */ - struct dynbuf dyn; /* for the IMAP commands */ - char *mailbox; /* The last selected mailbox */ - imapstate state; /* Always use imap.c:state() to change state! */ - unsigned int mb_uidvalidity; /* UIDVALIDITY parsed from select response */ - char resptag[5]; /* Response tag to wait for */ - unsigned char preftype; /* Preferred authentication type */ - unsigned char cmdid; /* Last used command ID */ - BIT(ssldone); /* Is connect() over SSL done? */ - BIT(preauth); /* Is this connection PREAUTH? */ - BIT(tls_supported); /* StartTLS capability supported by server */ - BIT(login_disabled); /* LOGIN command disabled by server */ - BIT(ir_supported); /* Initial response supported by server */ - BIT(mb_uidvalidity_set); -}; - -/* This IMAP struct is used in the Curl_easy. All IMAP data that is - connection-oriented must be in imap_conn to properly deal with the fact that - perhaps the Curl_easy is changed between the times the connection is - used. */ -struct IMAP { - curl_pp_transfer transfer; - char *mailbox; /* Mailbox to select */ - char *uid; /* Message UID to fetch */ - char *mindex; /* Index in mail box of mail to fetch */ - char *section; /* Message SECTION to fetch */ - char *partial; /* Message PARTIAL to fetch */ - char *query; /* Query to search for */ - char *custom; /* Custom request */ - char *custom_params; /* Parameters for the custom request */ - unsigned int uidvalidity; /* UIDVALIDITY to check in select */ - BIT(uidvalidity_set); -}; - -#define IMAP_RESP_OK 1 -#define IMAP_RESP_NOT_OK 2 -#define IMAP_RESP_PREAUTH 3 - -struct ulbits { - int bit; - const char *flag; -}; - -/*********************************************************************** - * - * imap_sendf() - * - * Sends the formatted string as an IMAP command to the server. - * - * Designed to never block. - */ -static CURLcode imap_sendf(struct Curl_easy *data, - struct imap_conn *imapc, - const char *fmt, ...) CURL_PRINTF(3, 0); -static CURLcode imap_sendf(struct Curl_easy *data, - struct imap_conn *imapc, - const char *fmt, ...) -{ - CURLcode result = CURLE_OK; - - DEBUGASSERT(fmt); - - /* Calculate the tag based on the connection ID and command ID */ - curl_msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d", - 'A' + curlx_sltosi((long)(data->conn->connection_id % 26)), - ++imapc->cmdid); - - /* start with a blank buffer */ - curlx_dyn_reset(&imapc->dyn); - - /* append tag + space + fmt */ - result = curlx_dyn_addf(&imapc->dyn, "%s %s", imapc->resptag, fmt); - if(!result) { - va_list ap; - va_start(ap, fmt); -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wformat-nonliteral" -#endif - result = Curl_pp_vsendf(data, &imapc->pp, curlx_dyn_ptr(&imapc->dyn), ap); -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - va_end(ap); - } - return result; -} - -/*********************************************************************** - * - * imap_atom() - * - * Checks the input string for characters that need escaping and returns an - * atom ready for sending to the server. - * - * The returned string needs to be freed. - * - */ -static char *imap_atom(const char *str, bool escape_only) -{ - struct dynbuf line; - size_t nclean; - size_t len; - - if(!str) - return NULL; - - len = strlen(str); - nclean = strcspn(str, "() {%*]\\\""); - if(len == nclean) - /* nothing to escape, return a strdup */ - return curlx_strdup(str); - - curlx_dyn_init(&line, 2000); - - if(!escape_only && curlx_dyn_addn(&line, "\"", 1)) - return NULL; - - while(*str) { - if((*str == '\\' || *str == '"') && - curlx_dyn_addn(&line, "\\", 1)) - return NULL; - if(curlx_dyn_addn(&line, str, 1)) - return NULL; - str++; - } - - if(!escape_only && curlx_dyn_addn(&line, "\"", 1)) - return NULL; - - return curlx_dyn_ptr(&line); -} - -/* - * Finds the start of a literal '{size}' in line, skipping over quoted strings. - */ -static const char *imap_find_literal(const char *line, size_t len) -{ - const char *end = line + len; - bool in_quote = FALSE; - - while(line < end) { - if(in_quote) { - if(*line == '\\' && (line + 1) < end) { - line += 2; - continue; - } - if(*line == '"') - in_quote = FALSE; - } - else { - if(*line == '"') - in_quote = TRUE; - else if(*line == '{') - return line; - } - line++; - } - return NULL; -} - -/*********************************************************************** - * - * imap_matchresp() - * - * Determines whether the untagged response is related to the specified - * command by checking if it is in format "* ..." or - * "* ...". - * - * The "* " marker is assumed to have already been checked by the caller. - */ -static bool imap_matchresp(const char *line, size_t len, const char *cmd) -{ - const char *end = line + len; - size_t cmd_len = strlen(cmd); - - /* Skip the untagged response marker */ - line += 2; - - /* Do we have a number after the marker? */ - if(line < end && ISDIGIT(*line)) { - /* Skip the number */ - do - line++; - while(line < end && ISDIGIT(*line)); - - /* Do we have the space character? */ - if(line == end || *line != ' ') - return FALSE; - - line++; - } - - /* Does the command name match and is it followed by a space character or at - the end of line? */ - if(line + cmd_len <= end && curl_strnequal(line, cmd, cmd_len) && - (line[cmd_len] == ' ' || line + cmd_len + 2 == end)) - return TRUE; - - return FALSE; -} - -/*********************************************************************** - * - * imap_endofresp() - * - * Checks whether the given string is a valid tagged, untagged or continuation - * response which can be processed by the response handler. - */ -static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn, - const char *line, size_t len, int *resp) -{ - struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN); - struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); - const char *id; - size_t id_len; - - DEBUGASSERT(imapc); - DEBUGASSERT(imap); - if(!imapc || !imap) - return FALSE; - - /* Do we have a tagged command response? */ - id = imapc->resptag; - id_len = strlen(id); - if(len >= id_len + 1 && !memcmp(id, line, id_len) && line[id_len] == ' ') { - line += id_len + 1; - len -= id_len + 1; - - if(len >= 2 && !memcmp(line, "OK", 2)) - *resp = IMAP_RESP_OK; - else if(len >= 7 && !memcmp(line, "PREAUTH", 7)) - *resp = IMAP_RESP_PREAUTH; - else - *resp = IMAP_RESP_NOT_OK; - - return TRUE; - } - - /* Do we have an untagged command response? */ - if(len >= 2 && !memcmp("* ", line, 2)) { - switch(imapc->state) { - /* States which are interested in untagged responses */ - case IMAP_CAPABILITY: - if(!imap_matchresp(line, len, "CAPABILITY")) - return FALSE; - break; - - case IMAP_LIST: - if((!imap->custom && !imap_matchresp(line, len, "LIST")) || - (imap->custom && !imap_matchresp(line, len, imap->custom) && - (!curl_strequal(imap->custom, "STORE") || - !imap_matchresp(line, len, "FETCH")) && - !curl_strequal(imap->custom, "SELECT") && - !curl_strequal(imap->custom, "EXAMINE") && - !curl_strequal(imap->custom, "SEARCH") && - !curl_strequal(imap->custom, "EXPUNGE") && - !curl_strequal(imap->custom, "LSUB") && - !curl_strequal(imap->custom, "UID") && - !curl_strequal(imap->custom, "GETQUOTAROOT") && - !curl_strequal(imap->custom, "NOOP"))) - return FALSE; - break; - - case IMAP_SELECT: - /* SELECT is special in that its untagged responses do not have a - common prefix so accept anything! */ - break; - - case IMAP_FETCH: - if(!imap_matchresp(line, len, "FETCH")) - return FALSE; - break; - - case IMAP_SEARCH: - if(!imap_matchresp(line, len, "SEARCH")) - return FALSE; - break; - - /* Ignore other untagged responses */ - default: - return FALSE; - } - - *resp = '*'; - return TRUE; - } - - /* Do we have a continuation response? This should be a + symbol followed by - a space and optionally some text as per RFC-3501 for the AUTHENTICATE and - APPEND commands and as outlined in Section 4. Examples of RFC-4959 but - some email servers ignore this and only send a single + instead. */ - if(!imap->custom && ((len == 3 && line[0] == '+') || - (len >= 2 && !memcmp("+ ", line, 2)))) { - switch(imapc->state) { - /* States which are interested in continuation responses */ - case IMAP_AUTHENTICATE: - case IMAP_APPEND: - *resp = '+'; - break; - - default: - failf(data, "Unexpected continuation response"); - *resp = -1; - break; - } - - return TRUE; - } - - return FALSE; /* Nothing for us */ -} - -/*********************************************************************** - * - * imap_get_message() - * - * Gets the authentication message from the response buffer. - */ -static CURLcode imap_get_message(struct Curl_easy *data, struct bufref *out) -{ - struct imap_conn *imapc = - Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); - char *message; - size_t len; - - if(!imapc) - return CURLE_FAILED_INIT; - - message = curlx_dyn_ptr(&imapc->pp.recvbuf); - len = imapc->pp.nfinal; - if(len > 2) { - /* Find the start of the message */ - len -= 2; - for(message += 2; ISBLANK(*message); message++, len--) - ; - - /* Find the end of the message */ - while(len--) - if(!ISNEWLINE(message[len]) && !ISBLANK(message[len])) - break; - - /* Terminate the message */ - message[++len] = '\0'; - Curl_bufref_set(out, message, len, NULL); - } - else - /* junk input => zero length output */ - Curl_bufref_set(out, "", 0, NULL); - - return CURLE_OK; -} - -/*********************************************************************** - * - * imap_state() - * - * This is the ONLY way to change IMAP state! - */ -static void imap_state(struct Curl_easy *data, - struct imap_conn *imapc, - imapstate newstate) -{ -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - /* for debug purposes */ - static const char * const names[] = { - "STOP", - "SERVERGREET", - "CAPABILITY", - "STARTTLS", - "UPGRADETLS", - "AUTHENTICATE", - "LOGIN", - "LIST", - "SELECT", - "FETCH", - "FETCH_FINAL", - "APPEND", - "APPEND_FINAL", - "SEARCH", - "LOGOUT", - /* LAST */ - }; - - if(imapc->state != newstate) - infof(data, "IMAP %p state change from %s to %s", - (void *)imapc, names[imapc->state], names[newstate]); -#else - (void)data; -#endif - imapc->state = newstate; -} - -/*********************************************************************** - * - * imap_perform_capability() - * - * Sends the CAPABILITY command in order to obtain a list of server side - * supported capabilities. - */ -static CURLcode imap_perform_capability(struct Curl_easy *data, - struct imap_conn *imapc) -{ - CURLcode result = CURLE_OK; - - imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */ - imapc->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */ - imapc->tls_supported = FALSE; /* Clear the TLS capability */ - - /* Send the CAPABILITY command */ - result = imap_sendf(data, imapc, "CAPABILITY"); - - if(!result) - imap_state(data, imapc, IMAP_CAPABILITY); - - return result; -} - -/*********************************************************************** - * - * imap_perform_starttls() - * - * Sends the STARTTLS command to start the upgrade to TLS. - */ -static CURLcode imap_perform_starttls(struct Curl_easy *data, - struct imap_conn *imapc) -{ - /* Send the STARTTLS command */ - CURLcode result = imap_sendf(data, imapc, "STARTTLS"); - - if(!result) - imap_state(data, imapc, IMAP_STARTTLS); - - return result; -} - -/*********************************************************************** - * - * imap_perform_upgrade_tls() - * - * Performs the upgrade to TLS. - */ -static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data, - struct imap_conn *imapc, - struct connectdata *conn) -{ -#ifdef USE_SSL - /* Start the SSL connection */ - CURLcode result; - bool ssldone = FALSE; - - if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); - if(result) - goto out; - /* Change the connection handler */ - conn->scheme = &Curl_scheme_imaps; - } - - DEBUGASSERT(!imapc->ssldone); - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - DEBUGF(infof(data, "imap_perform_upgrade_tls, connect -> %d, %d", - result, ssldone)); - if(!result && ssldone) { - imapc->ssldone = ssldone; - /* perform CAPA now, changes imapc->state out of IMAP_UPGRADETLS */ - result = imap_perform_capability(data, imapc); - } -out: - return result; -#else - (void)data; - (void)imapc; - (void)conn; - return CURLE_NOT_BUILT_IN; -#endif -} - -/*********************************************************************** - * - * imap_perform_login() - * - * Sends a clear text LOGIN command to authenticate with. - */ -static CURLcode imap_perform_login(struct Curl_easy *data, - struct imap_conn *imapc, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - char *user; - char *passwd; - - /* Check we have a username and password to authenticate with and end the - connect phase if we do not */ - if(!data->state.aptr.user) { - imap_state(data, imapc, IMAP_STOP); - - return result; - } - - /* Make sure the username and password are in the correct atom format */ - user = imap_atom(conn->user, FALSE); - passwd = imap_atom(conn->passwd, FALSE); - - /* Send the LOGIN command */ - result = imap_sendf(data, imapc, "LOGIN %s %s", user ? user : "", - passwd ? passwd : ""); - - curlx_free(user); - curlx_free(passwd); - - if(!result) - imap_state(data, imapc, IMAP_LOGIN); - - return result; -} - -/*********************************************************************** - * - * imap_perform_authenticate() - * - * Sends an AUTHENTICATE command allowing the client to login with the given - * SASL authentication mechanism. - */ -static CURLcode imap_perform_authenticate(struct Curl_easy *data, - const char *mech, - const struct bufref *initresp) -{ - struct imap_conn *imapc = - Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); - CURLcode result = CURLE_OK; - const char *ir = Curl_bufref_ptr(initresp); - - if(!imapc) - return CURLE_FAILED_INIT; - if(ir) { - /* Send the AUTHENTICATE command with the initial response */ - result = imap_sendf(data, imapc, "AUTHENTICATE %s %s", mech, ir); - } - else { - /* Send the AUTHENTICATE command */ - result = imap_sendf(data, imapc, "AUTHENTICATE %s", mech); - } - - return result; -} - -/*********************************************************************** - * - * imap_continue_authenticate() - * - * Sends SASL continuation data. - */ -static CURLcode imap_continue_authenticate(struct Curl_easy *data, - const char *mech, - const struct bufref *resp) -{ - struct imap_conn *imapc = - Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); - - (void)mech; - if(!imapc) - return CURLE_FAILED_INIT; - return Curl_pp_sendf(data, &imapc->pp, "%s", Curl_bufref_ptr(resp)); -} - -/*********************************************************************** - * - * imap_cancel_authenticate() - * - * Sends SASL cancellation. - */ -static CURLcode imap_cancel_authenticate(struct Curl_easy *data, - const char *mech) -{ - struct imap_conn *imapc = - Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); - - (void)mech; - if(!imapc) - return CURLE_FAILED_INIT; - return Curl_pp_sendf(data, &imapc->pp, "*"); -} - -/*********************************************************************** - * - * imap_perform_authentication() - * - * Initiates the authentication sequence, with the appropriate SASL - * authentication mechanism, falling back to clear text should a common - * mechanism not be available between the client and server. - */ -static CURLcode imap_perform_authentication(struct Curl_easy *data, - struct imap_conn *imapc) -{ - CURLcode result = CURLE_OK; - saslprogress progress; - - /* Check if already authenticated OR if there is enough data to authenticate - with and end the connect phase if we do not */ - if(imapc->preauth || - !Curl_sasl_can_authenticate(&imapc->sasl, data)) { - imap_state(data, imapc, IMAP_STOP); - return result; - } - - /* Calculate the SASL login details */ - result = Curl_sasl_start(&imapc->sasl, data, (bool)imapc->ir_supported, - &progress); - - if(!result) { - if(progress == SASL_INPROGRESS) - imap_state(data, imapc, IMAP_AUTHENTICATE); - else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) - /* Perform clear text authentication */ - result = imap_perform_login(data, imapc, data->conn); - else - result = Curl_sasl_is_blocked(&imapc->sasl, data); - } - - return result; -} - -/*********************************************************************** - * - * imap_perform_list() - * - * Sends a LIST command or an alternative custom request. - */ -static CURLcode imap_perform_list(struct Curl_easy *data, - struct imap_conn *imapc, - struct IMAP *imap) -{ - CURLcode result = CURLE_OK; - - if(imap->custom) - /* Send the custom request */ - result = imap_sendf(data, imapc, "%s%s", imap->custom, - imap->custom_params ? imap->custom_params : ""); - else { - /* Make sure the mailbox is in the correct atom format if necessary */ - char *mailbox = imap->mailbox ? imap_atom(imap->mailbox, TRUE) - : curlx_strdup(""); - if(!mailbox) - return CURLE_OUT_OF_MEMORY; - - /* Send the LIST command */ - result = imap_sendf(data, imapc, "LIST \"%s\" *", mailbox); - - curlx_free(mailbox); - } - - if(!result) - imap_state(data, imapc, IMAP_LIST); - - return result; -} - -/*********************************************************************** - * - * imap_perform_select() - * - * Sends a SELECT command to ask the server to change the selected mailbox. - */ -static CURLcode imap_perform_select(struct Curl_easy *data, - struct imap_conn *imapc, - struct IMAP *imap) -{ - CURLcode result = CURLE_OK; - char *mailbox; - - /* Invalidate old information as we are switching mailboxes */ - curlx_safefree(imapc->mailbox); - imapc->mb_uidvalidity_set = FALSE; - - /* Check we have a mailbox */ - if(!imap->mailbox) { - failf(data, "Cannot SELECT without a mailbox."); - return CURLE_URL_MALFORMAT; - } - - /* Make sure the mailbox is in the correct atom format */ - mailbox = imap_atom(imap->mailbox, FALSE); - if(!mailbox) - return CURLE_OUT_OF_MEMORY; - - /* Send the SELECT command */ - result = imap_sendf(data, imapc, "SELECT %s", mailbox); - - curlx_free(mailbox); - - if(!result) - imap_state(data, imapc, IMAP_SELECT); - - return result; -} - -/*********************************************************************** - * - * imap_perform_fetch() - * - * Sends a FETCH command to initiate the download of a message. - */ -static CURLcode imap_perform_fetch(struct Curl_easy *data, - struct imap_conn *imapc, - struct IMAP *imap) -{ - CURLcode result = CURLE_OK; - /* Check we have a UID */ - if(imap->uid) { - - /* Send the FETCH command */ - if(imap->partial) - result = imap_sendf(data, imapc, "UID FETCH %s BODY[%s]<%s>", - imap->uid, imap->section ? imap->section : "", - imap->partial); - else - result = imap_sendf(data, imapc, "UID FETCH %s BODY[%s]", - imap->uid, imap->section ? imap->section : ""); - } - else if(imap->mindex) { - /* Send the FETCH command */ - if(imap->partial) - result = imap_sendf(data, imapc, "FETCH %s BODY[%s]<%s>", - imap->mindex, imap->section ? imap->section : "", - imap->partial); - else - result = imap_sendf(data, imapc, "FETCH %s BODY[%s]", - imap->mindex, imap->section ? imap->section : ""); - } - else { - failf(data, "Cannot FETCH without a UID."); - return CURLE_URL_MALFORMAT; - } - if(!result) - imap_state(data, imapc, IMAP_FETCH); - - return result; -} - -/*********************************************************************** - * - * imap_perform_append() - * - * Sends an APPEND command to initiate the upload of a message. - */ -static CURLcode imap_perform_append(struct Curl_easy *data, - struct imap_conn *imapc, - struct IMAP *imap) -{ - CURLcode result = CURLE_OK; - char *mailbox; - struct dynbuf flags; - - /* Check we have a mailbox */ - if(!imap->mailbox) { - failf(data, "Cannot APPEND without a mailbox."); - return CURLE_URL_MALFORMAT; - } - -#ifndef CURL_DISABLE_MIME - /* Prepare the mime data if some. */ - if(IS_MIME_POST(data)) { - curl_mimepart *postp = data->set.mimepostp; - - /* Use the whole structure as data. */ - postp->flags &= ~(unsigned int)MIME_BODY_ONLY; - - /* Add external headers and mime version. */ - curl_mime_headers(postp, data->set.headers, 0); - result = Curl_mime_prepare_headers(data, postp, NULL, - NULL, MIMESTRATEGY_MAIL); - - if(!result) - if(!Curl_checkheaders(data, STRCONST("Mime-Version"))) - result = Curl_mime_add_header(&postp->curlheaders, - "Mime-Version: 1.0"); - - if(!result) - result = Curl_creader_set_mime(data, postp); - if(result) - return result; - data->state.infilesize = Curl_creader_client_length(data); - } - else -#endif - { - result = Curl_creader_set_fread(data, data->state.infilesize); - if(result) - return result; - } - - /* Check we know the size of the upload */ - if(data->state.infilesize < 0) { - failf(data, "Cannot APPEND with unknown input file size"); - return CURLE_UPLOAD_FAILED; - } - - /* Make sure the mailbox is in the correct atom format */ - mailbox = imap_atom(imap->mailbox, FALSE); - if(!mailbox) - return CURLE_OUT_OF_MEMORY; - - /* Generate flags string and send the APPEND command */ - curlx_dyn_init(&flags, 100); - if(data->set.upload_flags) { - int i; - struct ulbits ulflag[] = { - {CURLULFLAG_ANSWERED, "Answered"}, - {CURLULFLAG_DELETED, "Deleted"}, - {CURLULFLAG_DRAFT, "Draft"}, - {CURLULFLAG_FLAGGED, "Flagged"}, - {CURLULFLAG_SEEN, "Seen"}, - {0, NULL} - }; - - result = CURLE_OUT_OF_MEMORY; - if(curlx_dyn_add(&flags, " (")) { - goto cleanup; - } - - for(i = 0; ulflag[i].bit; i++) { - if(data->set.upload_flags & ulflag[i].bit) { - if((curlx_dyn_len(&flags) > 2 && curlx_dyn_add(&flags, " ")) || - curlx_dyn_add(&flags, "\\") || - curlx_dyn_add(&flags, ulflag[i].flag)) - goto cleanup; - } - } - - if(curlx_dyn_add(&flags, ")")) - goto cleanup; - } - else if(curlx_dyn_add(&flags, "")) - goto cleanup; - - result = imap_sendf(data, imapc, "APPEND %s%s {%" FMT_OFF_T "}", - mailbox, curlx_dyn_ptr(&flags), data->state.infilesize); - -cleanup: - curlx_dyn_free(&flags); - curlx_free(mailbox); - - if(!result) - imap_state(data, imapc, IMAP_APPEND); - - return result; -} - -/*********************************************************************** - * - * imap_perform_search() - * - * Sends a SEARCH command. - */ -static CURLcode imap_perform_search(struct Curl_easy *data, - struct imap_conn *imapc, - struct IMAP *imap) -{ - CURLcode result = CURLE_OK; - - /* Check we have a query string */ - if(!imap->query) { - failf(data, "Cannot SEARCH without a query string."); - return CURLE_URL_MALFORMAT; - } - - /* Send the SEARCH command */ - result = imap_sendf(data, imapc, "SEARCH %s", imap->query); - - if(!result) - imap_state(data, imapc, IMAP_SEARCH); - - return result; -} - -/*********************************************************************** - * - * imap_perform_logout() - * - * Performs the logout action prior to sclose() being called. - */ -static CURLcode imap_perform_logout(struct Curl_easy *data, - struct imap_conn *imapc) -{ - /* Send the LOGOUT command */ - CURLcode result = imap_sendf(data, imapc, "LOGOUT"); - - if(!result) - imap_state(data, imapc, IMAP_LOGOUT); - - return result; -} - -/* For the initial server greeting */ -static CURLcode imap_state_servergreet_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - (void)instate; - - if(imapcode == IMAP_RESP_PREAUTH) { - /* PREAUTH */ - imapc->preauth = TRUE; - infof(data, "PREAUTH connection, already authenticated"); - } - else if(imapcode != IMAP_RESP_OK) { - failf(data, "Got unexpected imap-server response"); - return CURLE_WEIRD_SERVER_REPLY; - } - - return imap_perform_capability(data, imapc); -} - -/* For CAPABILITY responses */ -static CURLcode imap_state_capability_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - const char *line = curlx_dyn_ptr(&imapc->pp.recvbuf); - - (void)instate; - - /* Do we have an untagged response? */ - if(imapcode == '*') { - line += 2; - - /* Loop through the data line */ - for(;;) { - size_t wordlen; - while(*line && (ISBLANK(*line) || ISNEWLINE(*line))) - line++; - - if(!*line) - break; - - /* Extract the word */ - for(wordlen = 0; line[wordlen] && !ISBLANK(line[wordlen]) && - !ISNEWLINE(line[wordlen]);) - wordlen++; - - /* Does the server support the STARTTLS capability? */ - if(wordlen == 8 && curl_strnequal(line, "STARTTLS", 8)) - imapc->tls_supported = TRUE; - - /* Has the server explicitly disabled clear text authentication? */ - else if(wordlen == 13 && curl_strnequal(line, "LOGINDISABLED", 13)) - imapc->login_disabled = TRUE; - - /* Does the server support the SASL-IR capability? */ - else if(wordlen == 7 && curl_strnequal(line, "SASL-IR", 7)) - imapc->ir_supported = TRUE; - - /* Do we have a SASL based authentication mechanism? */ - else if(wordlen > 5 && curl_strnequal(line, "AUTH=", 5)) { - size_t llen; - unsigned short mechbit; - - line += 5; - wordlen -= 5; - - /* Test the word for a matching authentication mechanism */ - mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); - if(mechbit && llen == wordlen) - imapc->sasl.authmechs |= mechbit; - } - - line += wordlen; - } - } - else if(data->set.use_ssl && !Curl_xfer_is_secure(data)) { - /* PREAUTH is not compatible with STARTTLS. */ - if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) { - /* Switch to TLS connection now */ - result = imap_perform_starttls(data, imapc); - } - else if(data->set.use_ssl <= CURLUSESSL_TRY) - result = imap_perform_authentication(data, imapc); - else { - failf(data, "STARTTLS not available."); - result = CURLE_USE_SSL_FAILED; - } - } - else - result = imap_perform_authentication(data, imapc); - - return result; -} - -/* For STARTTLS responses */ -static CURLcode imap_state_starttls_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - - (void)instate; - - /* Pipelining in response is forbidden. */ - if(imapc->pp.overflow) - return CURLE_WEIRD_SERVER_REPLY; - - if(imapcode != IMAP_RESP_OK) { - if(data->set.use_ssl != CURLUSESSL_TRY) { - failf(data, "STARTTLS denied"); - result = CURLE_USE_SSL_FAILED; - } - else - result = imap_perform_authentication(data, imapc); - } - else - imap_state(data, imapc, IMAP_UPGRADETLS); - - return result; -} - -/* For SASL authentication responses */ -static CURLcode imap_state_auth_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - saslprogress progress; - - (void)instate; - - result = Curl_sasl_continue(&imapc->sasl, data, imapcode, &progress); - if(!result) - switch(progress) { - case SASL_DONE: - imap_state(data, imapc, IMAP_STOP); /* Authenticated */ - break; - case SASL_IDLE: /* No mechanism left after cancellation */ - if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) - /* Perform clear text authentication */ - result = imap_perform_login(data, imapc, data->conn); - else { - failf(data, "Authentication cancelled"); - result = CURLE_LOGIN_DENIED; - } - break; - default: - break; - } - - return result; -} - -/* For LOGIN responses */ -static CURLcode imap_state_login_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(imapcode != IMAP_RESP_OK) { - failf(data, "Access denied. %c", imapcode); - result = CURLE_LOGIN_DENIED; - } - else - /* End of connect phase */ - imap_state(data, imapc, IMAP_STOP); - - return result; -} - -/* Detect IMAP listings vs. downloading a single email */ -static bool is_custom_fetch_listing_match(const char *params) -{ - /* match " 1:* (FLAGS ..." or " 1,2,3 (FLAGS ..." */ - if(*params++ != ' ') - return FALSE; - - while(ISDIGIT(*params)) { - params++; - if(*params == 0) - return FALSE; - } - if(*params == ':') - return true; - if(*params == ',') - return true; - return FALSE; -} - -static bool is_custom_fetch_listing(struct IMAP *imap) -{ - /* filter out "UID FETCH 1:* (FLAGS ..." queries to list emails */ - if(!imap->custom) - return FALSE; - else if(curl_strequal(imap->custom, "FETCH") && imap->custom_params) { - const char *p = imap->custom_params; - return is_custom_fetch_listing_match(p); - } - else if(curl_strequal(imap->custom, "UID") && imap->custom_params) { - if(curl_strnequal(imap->custom_params, " FETCH ", 7)) { - const char *p = imap->custom_params + 6; - return is_custom_fetch_listing_match(p); - } - } - return FALSE; -} - -/* For LIST and SEARCH responses */ -static CURLcode imap_state_listsearch_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - const char *line = curlx_dyn_ptr(&imapc->pp.recvbuf); - size_t len = imapc->pp.nfinal; - struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); - - DEBUGASSERT(imap); - if(!imap) - return CURLE_FAILED_INIT; - (void)instate; - - if(imapcode == '*' && is_custom_fetch_listing(imap)) { - /* custom FETCH or UID FETCH for listing is not handled here */ - } - else if(imapcode == '*') { - /* Check if this response contains a literal (e.g. FETCH responses with - body data). Literal syntax is {size}\r\n */ - const char *cr = memchr(line, '\r', len); - size_t line_len = cr ? (size_t)(cr - line) : len; - const char *ptr = imap_find_literal(line, line_len); - if(ptr) { - curl_off_t size = 0; - bool parsed = FALSE; - ptr++; - if(!curlx_str_number(&ptr, &size, CURL_OFF_T_MAX) && - !curlx_str_single(&ptr, '}')) - parsed = TRUE; - - if(parsed) { - struct pingpong *pp = &imapc->pp; - size_t buffer_len = curlx_dyn_len(&pp->recvbuf); - size_t after_header = buffer_len - pp->nfinal; - - /* This is a literal response, setup to receive the body data */ - infof(data, "Found %" FMT_OFF_T " bytes to download", size); - - /* First write the header line */ - result = Curl_client_write(data, CLIENTWRITE_BODY, line, len); - if(result) - return result; - - /* Handle data already in buffer after the header line */ - if(after_header > 0) { - /* There is already data in the buffer that is part of the literal - body or subsequent responses */ - size_t chunk = after_header; - - /* Keep only the data after the header line */ - curlx_dyn_tail(&pp->recvbuf, chunk); - pp->nfinal = 0; /* done */ - - /* Limit chunk to the literal size */ - if(chunk > (size_t)size) - chunk = (size_t)size; - - if(chunk) { - /* Write the literal body data */ - result = Curl_client_write(data, CLIENTWRITE_BODY, - curlx_dyn_ptr(&pp->recvbuf), chunk); - if(result) - return result; - } - - /* Handle remaining data in buffer (either more literal data or - subsequent responses) */ - if(after_header > chunk) { - /* Keep the data after the literal body */ - pp->overflow = after_header - chunk; - curlx_dyn_tail(&pp->recvbuf, pp->overflow); - } - else { - pp->overflow = 0; - curlx_dyn_reset(&pp->recvbuf); - } - } - else { - /* No data in buffer yet, reset overflow */ - pp->overflow = 0; - } - - if((CURL_OFF_T_MAX - size) < (curl_off_t)len) - /* unlikely to actually be a transfer this big, but avoid integer - overflow */ - size = CURL_OFF_T_MAX; - else - size += len; - - /* Progress size includes both header line and literal body */ - Curl_pgrsSetDownloadSize(data, size); - - if(data->req.bytecount == size) - /* All data already transferred (header + literal body) */ - Curl_xfer_setup_nop(data); - else { - /* Setup to receive the literal body data. - maxdownload and transfer size include both header line and - literal body */ - data->req.maxdownload = size; - Curl_xfer_setup_recv(data, FIRSTSOCKET, size); - } - /* End of DO phase */ - imap_state(data, imapc, IMAP_STOP); - } - else { - /* Failed to parse literal, write the line */ - result = Curl_client_write(data, CLIENTWRITE_BODY, line, len); - } - } - else { - /* No literal, write the line as-is */ - result = Curl_client_write(data, CLIENTWRITE_BODY, line, len); - } - } - else if(imapcode != IMAP_RESP_OK) - result = CURLE_QUOTE_ERROR; - else - /* End of DO phase */ - imap_state(data, imapc, IMAP_STOP); - - return result; -} - -/* For SELECT responses */ -static CURLcode imap_state_select_resp(struct Curl_easy *data, - struct imap_conn *imapc, - struct IMAP *imap, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(imapcode == '*') { - /* See if this is an UIDVALIDITY response */ - const char *line = curlx_dyn_ptr(&imapc->pp.recvbuf); - size_t len = curlx_dyn_len(&imapc->pp.recvbuf); - if((len >= 18) && checkprefix("OK [UIDVALIDITY ", &line[2])) { - curl_off_t value; - const char *p = &line[2] + strlen("OK [UIDVALIDITY "); - if(!curlx_str_number(&p, &value, UINT_MAX)) { - imapc->mb_uidvalidity = (unsigned int)value; - imapc->mb_uidvalidity_set = TRUE; - } - } - } - else if(imapcode == IMAP_RESP_OK) { - /* Check if the UIDVALIDITY has been specified and matches */ - if(imap->uidvalidity_set && imapc->mb_uidvalidity_set && - (imap->uidvalidity != imapc->mb_uidvalidity)) { - failf(data, "Mailbox UIDVALIDITY has changed"); - result = CURLE_REMOTE_FILE_NOT_FOUND; - } - else { - /* Note the currently opened mailbox on this connection */ - DEBUGASSERT(!imapc->mailbox); - imapc->mailbox = curlx_strdup(imap->mailbox); - if(!imapc->mailbox) - return CURLE_OUT_OF_MEMORY; - - if(imap->custom) - result = imap_perform_list(data, imapc, imap); - else if(imap->query) - result = imap_perform_search(data, imapc, imap); - else - result = imap_perform_fetch(data, imapc, imap); - } - } - else { - failf(data, "Select failed"); - result = CURLE_LOGIN_DENIED; - } - - return result; -} - -/* For the (first line of the) FETCH responses */ -static CURLcode imap_state_fetch_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct pingpong *pp = &imapc->pp; - const char *ptr = curlx_dyn_ptr(&imapc->pp.recvbuf); - size_t len = imapc->pp.nfinal; - bool parsed = FALSE; - curl_off_t size = 0; - - (void)instate; - - if(imapcode != '*') { - Curl_pgrsSetDownloadSize(data, -1); - imap_state(data, imapc, IMAP_STOP); - return CURLE_REMOTE_FILE_NOT_FOUND; - } - - /* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse - the continuation data contained within the curly brackets */ - ptr = imap_find_literal(ptr, len); - if(ptr) { - ptr++; - if(!curlx_str_number(&ptr, &size, CURL_OFF_T_MAX) && - !curlx_str_single(&ptr, '}')) - parsed = TRUE; - } - - if(parsed) { - infof(data, "Found %" FMT_OFF_T " bytes to download", size); - Curl_pgrsSetDownloadSize(data, size); - - if(pp->overflow) { - /* At this point there is a data in the receive buffer that is body - content, send it as body and then skip it. Do note that there may - even be additional "headers" after the body. */ - size_t chunk = pp->overflow; - - /* keep only the overflow */ - curlx_dyn_tail(&pp->recvbuf, chunk); - pp->nfinal = 0; /* done */ - - if(chunk > (size_t)size) - /* The conversion from curl_off_t to size_t is always fine here */ - chunk = (size_t)size; - - if(!chunk) { - /* no size, we are done with the data */ - imap_state(data, imapc, IMAP_STOP); - return CURLE_OK; - } - result = Curl_client_write(data, CLIENTWRITE_BODY, - curlx_dyn_ptr(&pp->recvbuf), chunk); - if(result) - return result; - - infof(data, "Written %zu bytes, %" FMT_OFF_T - " bytes are left for transfer", chunk, (curl_off_t)(size - chunk)); - - /* Have we used the entire overflow or part of it?*/ - if(pp->overflow > chunk) { - /* remember the remaining trailing overflow data */ - pp->overflow -= chunk; - curlx_dyn_tail(&pp->recvbuf, pp->overflow); - } - else { - pp->overflow = 0; /* handled */ - /* Free the cache */ - curlx_dyn_reset(&pp->recvbuf); - } - } - - if(data->req.bytecount == size) - /* The entire data is already transferred! */ - Curl_xfer_setup_nop(data); - else { - /* IMAP download */ - data->req.maxdownload = size; - Curl_xfer_setup_recv(data, FIRSTSOCKET, size); - } - } - else { - /* We do not know how to parse this line */ - failf(data, "Failed to parse FETCH response."); - result = CURLE_WEIRD_SERVER_REPLY; - } - - /* End of DO phase */ - imap_state(data, imapc, IMAP_STOP); - - return result; -} - -/* For final FETCH responses performed after the download */ -static CURLcode imap_state_fetch_final_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - - (void)instate; - - if(imapcode != IMAP_RESP_OK) - result = CURLE_WEIRD_SERVER_REPLY; - else - /* End of DONE phase */ - imap_state(data, imapc, IMAP_STOP); - - return result; -} - -/* For APPEND responses */ -static CURLcode imap_state_append_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(imapcode != '+') { - result = CURLE_UPLOAD_FAILED; - } - else { - /* Set the progress upload size */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* IMAP upload */ - Curl_xfer_setup_send(data, FIRSTSOCKET); - - /* End of DO phase */ - imap_state(data, imapc, IMAP_STOP); - } - - return result; -} - -/* For final APPEND responses performed after the upload */ -static CURLcode imap_state_append_final_resp(struct Curl_easy *data, - struct imap_conn *imapc, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - - (void)instate; - - if(imapcode != IMAP_RESP_OK) - result = CURLE_UPLOAD_FAILED; - else - /* End of DONE phase */ - imap_state(data, imapc, IMAP_STOP); - - return result; -} - -static CURLcode imap_pp_statemachine(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - int imapcode; - struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN); - struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); - struct pingpong *pp; - size_t nread = 0; - - if(!imapc || !imap) - return CURLE_FAILED_INIT; - pp = &imapc->pp; - /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */ -upgrade_tls: - if(imapc->state == IMAP_UPGRADETLS) { - result = imap_perform_upgrade_tls(data, imapc, conn); - if(result || (imapc->state == IMAP_UPGRADETLS)) - return result; - } - - /* Flush any data that needs to be sent */ - if(pp->sendleft) - return Curl_pp_flushsend(data, pp); - - do { - /* Read the response from the server */ - result = Curl_pp_readresp(data, FIRSTSOCKET, pp, &imapcode, &nread); - if(result) - return result; - - /* Was there an error parsing the response line? */ - if(imapcode == -1) - return CURLE_WEIRD_SERVER_REPLY; - - if(!imapcode) - break; - - /* We have now received a full IMAP server response */ - switch(imapc->state) { - case IMAP_SERVERGREET: - result = imap_state_servergreet_resp(data, imapc, - imapcode, imapc->state); - break; - - case IMAP_CAPABILITY: - result = imap_state_capability_resp(data, imapc, imapcode, imapc->state); - break; - - case IMAP_STARTTLS: - result = imap_state_starttls_resp(data, imapc, imapcode, imapc->state); - /* During UPGRADETLS, leave the read loop as we need to connect - * (e.g. TLS handshake) before we continue sending/receiving. */ - if(!result && (imapc->state == IMAP_UPGRADETLS)) - goto upgrade_tls; - break; - - case IMAP_AUTHENTICATE: - result = imap_state_auth_resp(data, imapc, imapcode, imapc->state); - break; - - case IMAP_LOGIN: - result = imap_state_login_resp(data, imapc, imapcode, imapc->state); - break; - - case IMAP_LIST: - case IMAP_SEARCH: - result = imap_state_listsearch_resp(data, imapc, imapcode, imapc->state); - break; - - case IMAP_SELECT: - result = imap_state_select_resp(data, imapc, imap, - imapcode, imapc->state); - break; - - case IMAP_FETCH: - result = imap_state_fetch_resp(data, imapc, imapcode, imapc->state); - break; - - case IMAP_FETCH_FINAL: - result = imap_state_fetch_final_resp(data, imapc, - imapcode, imapc->state); - break; - - case IMAP_APPEND: - result = imap_state_append_resp(data, imapc, imapcode, imapc->state); - break; - - case IMAP_APPEND_FINAL: - result = imap_state_append_final_resp(data, imapc, - imapcode, imapc->state); - break; - - case IMAP_LOGOUT: - default: - /* internal error */ - imap_state(data, imapc, IMAP_STOP); - break; - } - } while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp)); - - return result; -} - -/* Called repeatedly until done from multi.c */ -static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = - Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); - - *done = FALSE; - if(!imapc) - return CURLE_FAILED_INIT; - result = Curl_pp_statemach(data, &imapc->pp, FALSE, FALSE); - *done = (imapc->state == IMAP_STOP); - - return result; -} - -static CURLcode imap_block_statemach(struct Curl_easy *data, - struct imap_conn *imapc, - bool disconnecting) -{ - CURLcode result = CURLE_OK; - - while(imapc->state != IMAP_STOP && !result) - result = Curl_pp_statemach(data, &imapc->pp, TRUE, disconnecting); - - return result; -} - -/* For the IMAP "protocol connect" and "doing" phases only */ -static CURLcode imap_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct imap_conn *imapc = - Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); - return imapc ? Curl_pp_pollset(data, &imapc->pp, ps) : CURLE_OK; -} - -static void imap_easy_reset(struct IMAP *imap) -{ - curlx_safefree(imap->mailbox); - curlx_safefree(imap->uid); - curlx_safefree(imap->mindex); - curlx_safefree(imap->section); - curlx_safefree(imap->partial); - curlx_safefree(imap->query); - curlx_safefree(imap->custom); - curlx_safefree(imap->custom_params); - imap->uidvalidity_set = FALSE; - /* Clear the transfer mode for the next request */ - imap->transfer = PPTRANSFER_BODY; -} - -/*********************************************************************** - * - * imap_is_bchar() - * - * Portable test of whether the specified char is a "bchar" as defined in the - * grammar of RFC-5092. - */ -static bool imap_is_bchar(char ch) -{ - /* Performing the alnum check first with macro is faster because of ASCII - arithmetic */ - return ch && (ISALNUM(ch) || strchr(":@/&=-._~!$\'()*+,%", ch)); -} - -/*********************************************************************** - * - * imap_parse_url_options() - * - * Parse the URL login options. - */ -static CURLcode imap_parse_url_options(struct connectdata *conn, - struct imap_conn *imapc) -{ - CURLcode result = CURLE_OK; - const char *ptr = conn->options; - bool prefer_login = FALSE; - - while(!result && ptr && *ptr) { - const char *key = ptr; - const char *value; - - while(*ptr && *ptr != '=') - ptr++; - - value = ptr + 1; - - while(*ptr && *ptr != ';') - ptr++; - - if(curl_strnequal(key, "AUTH=+LOGIN", 11)) { - /* User prefers plaintext LOGIN over any SASL, including SASL LOGIN */ - prefer_login = TRUE; - imapc->sasl.prefmech = SASL_AUTH_NONE; - } - else if(curl_strnequal(key, "AUTH=", 5)) { - prefer_login = FALSE; - result = Curl_sasl_parse_url_auth_option(&imapc->sasl, - value, ptr - value); - } - else { - prefer_login = FALSE; - result = CURLE_URL_MALFORMAT; - } - - if(*ptr == ';') - ptr++; - } - - if(prefer_login) - imapc->preftype = IMAP_TYPE_CLEARTEXT; - else { - switch(imapc->sasl.prefmech) { - case SASL_AUTH_NONE: - imapc->preftype = IMAP_TYPE_NONE; - break; - case SASL_AUTH_DEFAULT: - imapc->preftype = IMAP_TYPE_ANY; - break; - default: - imapc->preftype = IMAP_TYPE_SASL; - break; - } - } - - return result; -} - -/*********************************************************************** - * - * imap_parse_url_path() - * - * Parse the URL path into separate path components. - * - */ -static CURLcode imap_parse_url_path(struct Curl_easy *data, - struct IMAP *imap) -{ - /* The imap struct is already initialised in imap_connect() */ - CURLcode result = CURLE_OK; - const char *begin = &data->state.up.path[1]; /* skip leading slash */ - const char *ptr = begin; - - /* See how much of the URL is a valid path and decode it */ - while(imap_is_bchar(*ptr)) - ptr++; - - if(ptr != begin) { - /* Remove the trailing slash if present */ - const char *end = ptr; - if(end > begin && end[-1] == '/') - end--; - - result = Curl_urldecode(begin, end - begin, &imap->mailbox, NULL, - REJECT_CTRL); - if(result) - return result; - } - else - imap->mailbox = NULL; - - /* There can be any number of parameters in the form ";NAME=VALUE" */ - while(*ptr == ';') { - char *name; - char *value; - size_t valuelen; - - /* Find the length of the name parameter */ - begin = ++ptr; - while(*ptr && *ptr != '=') - ptr++; - - if(!*ptr) - return CURLE_URL_MALFORMAT; - - /* Decode the name parameter */ - result = Curl_urldecode(begin, ptr - begin, &name, NULL, - REJECT_CTRL); - if(result) - return result; - - /* Find the length of the value parameter */ - begin = ++ptr; - while(imap_is_bchar(*ptr)) - ptr++; - - /* Decode the value parameter */ - result = Curl_urldecode(begin, ptr - begin, &value, &valuelen, - REJECT_CTRL); - if(result) { - curlx_free(name); - return result; - } - - DEBUGF(infof(data, "IMAP URL parameter '%s' = '%s'", name, value)); - - /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION - and PARTIAL) stripping of the trailing slash character if it is - present. - - Note: Unknown parameters trigger a URL_MALFORMAT error. */ - if(valuelen > 0 && value[valuelen - 1] == '/') - value[valuelen - 1] = '\0'; - if(valuelen) { - if(curl_strequal(name, "UIDVALIDITY") && !imap->uidvalidity_set) { - curl_off_t num; - const char *p = (const char *)value; - if(!curlx_str_number(&p, &num, UINT_MAX)) { - imap->uidvalidity = (unsigned int)num; - imap->uidvalidity_set = TRUE; - } - curlx_free(value); - } - else if(curl_strequal(name, "UID") && !imap->uid) { - imap->uid = value; - } - else if(curl_strequal(name, "MAILINDEX") && !imap->mindex) { - imap->mindex = value; - } - else if(curl_strequal(name, "SECTION") && !imap->section) { - imap->section = value; - } - else if(curl_strequal(name, "PARTIAL") && !imap->partial) { - imap->partial = value; - } - else { - curlx_free(name); - curlx_free(value); - return CURLE_URL_MALFORMAT; - } - } - else - /* blank? */ - curlx_free(value); - curlx_free(name); - } - - /* Does the URL contain a query parameter? Only valid when we have a mailbox - and no UID as per RFC-5092 */ - if(imap->mailbox && !imap->uid && !imap->mindex) { - /* Get the query parameter, URL decoded */ - CURLUcode uc = curl_url_get(data->state.uh, CURLUPART_QUERY, &imap->query, - CURLU_URLDECODE); - if(uc == CURLUE_OUT_OF_MEMORY) - return CURLE_OUT_OF_MEMORY; - } - - /* Any extra stuff at the end of the URL is an error */ - if(*ptr) - return CURLE_URL_MALFORMAT; - - return CURLE_OK; -} - -/*********************************************************************** - * - * imap_parse_custom_request() - * - * Parse the custom request. - */ -static CURLcode imap_parse_custom_request(struct Curl_easy *data, - struct IMAP *imap) -{ - CURLcode result = CURLE_OK; - const char *custom = data->set.str[STRING_CUSTOMREQUEST]; - - if(custom) { - /* URL decode the custom request */ - result = Curl_urldecode(custom, 0, &imap->custom, NULL, REJECT_CTRL); - - /* Extract the parameters if specified */ - if(!result) { - const char *params = imap->custom; - - while(*params && *params != ' ') - params++; - - if(*params) { - imap->custom_params = curlx_strdup(params); - imap->custom[params - imap->custom] = '\0'; - - if(!imap->custom_params) - result = CURLE_OUT_OF_MEMORY; - } - } - } - - return result; -} - -/*********************************************************************** - * - * imap_connect() - * - * This function should do everything that is to be considered a part of the - * connection phase. - * - * The variable 'done' points to will be TRUE if the protocol-layer connect - * phase is done when this function returns, or FALSE if not. - */ -static CURLcode imap_connect(struct Curl_easy *data, bool *done) -{ - struct imap_conn *imapc = - Curl_conn_meta_get(data->conn, CURL_META_IMAP_CONN); - CURLcode result = CURLE_OK; - - *done = FALSE; /* default to not done yet */ - if(!imapc) - return CURLE_FAILED_INIT; - - /* Parse the URL options */ - result = imap_parse_url_options(data->conn, imapc); - if(result) - return result; - - /* Start off waiting for the server greeting response */ - imap_state(data, imapc, IMAP_SERVERGREET); - - /* Start off with an response id of '*' */ - curlx_strcopy(imapc->resptag, sizeof(imapc->resptag), STRCONST("*")); - - result = imap_multi_statemach(data, done); - - return result; -} - -/*********************************************************************** - * - * imap_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode imap_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN); - struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); - - (void)premature; - - if(!imapc) - return CURLE_FAILED_INIT; - if(!imap) - return CURLE_OK; - - if(status) { - connclose(conn, "IMAP done with bad status"); /* marked for closure */ - result = status; /* use the already set error code */ - } - else if(!data->set.connect_only && - ((!imap->custom && (imap->uid || imap->mindex)) || - (imap->custom && data->req.maxdownload > 0) || - data->state.upload || IS_MIME_POST(data))) { - /* Handle responses after FETCH or APPEND transfer has finished. - For custom commands, check if we set up a download which indicates - a FETCH-like command with literal data. */ - - if(!data->state.upload && !IS_MIME_POST(data)) - imap_state(data, imapc, IMAP_FETCH_FINAL); - else { - /* End the APPEND command first by sending an empty line */ - result = Curl_pp_sendf(data, &imapc->pp, "%s", ""); - if(!result) - imap_state(data, imapc, IMAP_APPEND_FINAL); - } - - /* Run the state-machine */ - if(!result) - result = imap_block_statemach(data, imapc, FALSE); - } - - imap_easy_reset(imap); - return result; -} - -/*********************************************************************** - * - * imap_perform() - * - * This is the actual DO function for IMAP. Fetch or append a message, or do - * other things according to the options previously setup. - */ -static CURLcode imap_perform(struct Curl_easy *data, bool *connected, - bool *dophase_done) -{ - /* This is IMAP and no proxy */ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN); - struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); - bool selected = FALSE; - - DEBUGF(infof(data, "DO phase starts")); - if(!imapc || !imap) - return CURLE_FAILED_INIT; - - if(data->req.no_body) { - /* Requested no body means no transfer */ - imap->transfer = PPTRANSFER_INFO; - } - - *dophase_done = FALSE; /* not done yet */ - - /* Determine if the requested mailbox (with the same UIDVALIDITY if set) - has already been selected on this connection */ - if(imap->mailbox && imapc->mailbox && - curl_strequal(imap->mailbox, imapc->mailbox) && - (!imap->uidvalidity_set || !imapc->mb_uidvalidity_set || - (imap->uidvalidity == imapc->mb_uidvalidity))) - selected = TRUE; - - /* Start the first command in the DO phase */ - if(data->state.upload || IS_MIME_POST(data)) - /* APPEND can be executed directly */ - result = imap_perform_append(data, imapc, imap); - else if(imap->custom && (selected || !imap->mailbox)) - /* Custom command using the same mailbox or no mailbox */ - result = imap_perform_list(data, imapc, imap); - else if(!imap->custom && selected && (imap->uid || imap->mindex)) - /* FETCH from the same mailbox */ - result = imap_perform_fetch(data, imapc, imap); - else if(!imap->custom && selected && imap->query) - /* SEARCH the current mailbox */ - result = imap_perform_search(data, imapc, imap); - else if(imap->mailbox && !selected && - (imap->custom || imap->uid || imap->mindex || imap->query)) - /* SELECT the mailbox */ - result = imap_perform_select(data, imapc, imap); - else - /* LIST */ - result = imap_perform_list(data, imapc, imap); - - if(result) - return result; - - /* Run the state-machine */ - result = imap_multi_statemach(data, dophase_done); - - *connected = Curl_conn_is_connected(conn, FIRSTSOCKET); - - if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete")); - - return result; -} - -/* Call this when the DO phase has completed */ -static CURLcode imap_dophase_done(struct Curl_easy *data, - struct IMAP *imap, - bool connected) -{ - (void)connected; - - if(imap->transfer != PPTRANSFER_BODY) - /* no data to transfer */ - Curl_xfer_setup_nop(data); - - return CURLE_OK; -} - -/*********************************************************************** - * - * imap_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - */ -static CURLcode imap_regular_transfer(struct Curl_easy *data, - struct IMAP *imap, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - bool connected = FALSE; - - /* Make sure size is unknown at this point */ - data->req.size = -1; - - /* Set the progress data */ - Curl_pgrsReset(data); - - /* Carry out the perform */ - result = imap_perform(data, &connected, dophase_done); - - /* Perform post DO phase operations if necessary */ - if(!result && *dophase_done) - result = imap_dophase_done(data, imap, connected); - - return result; -} - -/*********************************************************************** - * - * imap_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (imap_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode imap_do(struct Curl_easy *data, bool *done) -{ - struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); - CURLcode result = CURLE_OK; - *done = FALSE; /* default to false */ - - if(!imap) - return CURLE_FAILED_INIT; - /* Parse the URL path */ - result = imap_parse_url_path(data, imap); - if(result) - return result; - - /* Parse the custom request */ - result = imap_parse_custom_request(data, imap); - if(result) - return result; - - result = imap_regular_transfer(data, imap, done); - - return result; -} - -/*********************************************************************** - * - * imap_disconnect() - * - * Disconnect from an IMAP server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode imap_disconnect(struct Curl_easy *data, - struct connectdata *conn, bool dead_connection) -{ - struct imap_conn *imapc = Curl_conn_meta_get(conn, CURL_META_IMAP_CONN); - - if(imapc) { - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way (pingpong has pending data to send), - sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. */ - if(!dead_connection && conn->bits.protoconnstart && - !Curl_pp_needs_flush(data, &imapc->pp)) { - if(!imap_perform_logout(data, imapc)) - (void)imap_block_statemach(data, imapc, TRUE); /* ignore errors */ - } - } - return CURLE_OK; -} - -/* Called from multi.c while DOing */ -static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done) -{ - struct IMAP *imap = Curl_meta_get(data, CURL_META_IMAP_EASY); - CURLcode result; - - if(!imap) - return CURLE_FAILED_INIT; - - result = imap_multi_statemach(data, dophase_done); - if(result) - DEBUGF(infof(data, "DO phase failed")); - else if(*dophase_done) { - result = imap_dophase_done(data, imap, FALSE /* not connected */); - - DEBUGF(infof(data, "DO phase is complete")); - } - - return result; -} - -static void imap_easy_dtor(void *key, size_t klen, void *entry) -{ - struct IMAP *imap = entry; - (void)key; - (void)klen; - imap_easy_reset(imap); - curlx_free(imap); -} - -static void imap_conn_dtor(void *key, size_t klen, void *entry) -{ - struct imap_conn *imapc = entry; - (void)key; - (void)klen; - Curl_pp_disconnect(&imapc->pp); - curlx_dyn_free(&imapc->dyn); - curlx_safefree(imapc->mailbox); - curlx_free(imapc); -} - -/* SASL parameters for the imap protocol */ -static const struct SASLproto saslimap = { - "imap", /* The service name */ - imap_perform_authenticate, /* Send authentication command */ - imap_continue_authenticate, /* Send authentication continuation */ - imap_cancel_authenticate, /* Send authentication cancellation */ - imap_get_message, /* Get SASL response message */ - 0, /* No maximum initial response length */ - '+', /* Code received when continuation is expected */ - IMAP_RESP_OK, /* Code to receive upon authentication success */ - SASL_AUTH_DEFAULT, /* Default mechanisms */ - SASL_FLAG_BASE64 /* Configuration flags */ -}; - -static CURLcode imap_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct imap_conn *imapc; - struct pingpong *pp; - struct IMAP *imap; - - imapc = curlx_calloc(1, sizeof(*imapc)); - if(!imapc) - return CURLE_OUT_OF_MEMORY; - - pp = &imapc->pp; - PINGPONG_SETUP(pp, imap_pp_statemachine, imap_endofresp); - - /* Set the default preferred authentication type and mechanism */ - imapc->preftype = IMAP_TYPE_ANY; - Curl_sasl_init(&imapc->sasl, data, &saslimap); - - curlx_dyn_init(&imapc->dyn, DYN_IMAP_CMD); - Curl_pp_init(pp, Curl_pgrs_now(data)); - - if(Curl_conn_meta_set(conn, CURL_META_IMAP_CONN, imapc, imap_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - imap = curlx_calloc(1, sizeof(struct IMAP)); - if(!imap || - Curl_meta_set(data, CURL_META_IMAP_EASY, imap, imap_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -/* - * IMAP protocol. - */ -const struct Curl_protocol Curl_protocol_imap = { - imap_setup_connection, /* setup_connection */ - imap_do, /* do_it */ - imap_done, /* done */ - ZERO_NULL, /* do_more */ - imap_connect, /* connect_it */ - imap_multi_statemach, /* connecting */ - imap_doing, /* doing */ - imap_pollset, /* proto_pollset */ - imap_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - imap_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* CURL_DISABLE_IMAP */ diff --git a/vendor/curl/lib/imap.h b/vendor/curl/lib/imap.h deleted file mode 100644 index ecfb1ec9b..000000000 --- a/vendor/curl/lib/imap.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_IMAP_H -#define HEADER_CURL_IMAP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* Authentication type flags */ -#define IMAP_TYPE_CLEARTEXT (1 << 0) -#define IMAP_TYPE_SASL (1 << 1) - -/* Authentication type values */ -#define IMAP_TYPE_NONE 0 -#define IMAP_TYPE_ANY (IMAP_TYPE_CLEARTEXT | IMAP_TYPE_SASL) - -#ifndef CURL_DISABLE_IMAP -extern const struct Curl_protocol Curl_protocol_imap; -#endif - -#endif /* HEADER_CURL_IMAP_H */ diff --git a/vendor/curl/lib/ldap.c b/vendor/curl/lib/ldap.c deleted file mode 100644 index 16c93eeca..000000000 --- a/vendor/curl/lib/ldap.c +++ /dev/null @@ -1,1001 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "curl_ldap.h" - -#if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP) - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -/* - * Notice that USE_OPENLDAP is only a source code selection switch. When - * libcurl is built with USE_OPENLDAP defined the libcurl source code that - * gets compiled is the code from openldap.c, otherwise the code that gets - * compiled is the code from ldap.c. - * - * When USE_OPENLDAP is defined a recent version of the OpenLDAP library - * might be required for compilation and runtime. In order to use ancient - * OpenLDAP library versions, USE_OPENLDAP shall not be defined. - */ - -#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */ -# include -/* Undefine indirect symbols conflicting with BoringSSL/AWS-LC. */ -# undef X509_NAME -# undef X509_EXTENSIONS -# undef PKCS7_ISSUER_AND_SERIAL -# undef PKCS7_SIGNER_INFO -# undef OCSP_REQUEST -# undef OCSP_RESPONSE -# include -#else -# define LDAP_DEPRECATED 1 /* Be sure ldap_init() is defined. */ -# ifdef HAVE_LBER_H -# include -# endif -# include -# if defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H) -# include -# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */ -#endif - -#include "cfilters.h" -#include "sendf.h" -#include "curl_trc.h" -#include "escape.h" -#include "progress.h" -#include "transfer.h" -#include "curlx/strparse.h" -#include "bufref.h" -#include "curlx/multibyte.h" -#include "curlx/base64.h" -#include "connect.h" - -#ifdef USE_WIN32_LDAP -#define FREE_ON_WINLDAP(x) curlx_free(x) -#define curl_ldap_num_t ULONG -#else -#define FREE_ON_WINLDAP(x) do {} while(0) -#define curl_ldap_num_t int -#endif - -#ifndef HAVE_LDAP_URL_PARSE - -/* Use our own implementation. */ - -struct ldap_urldesc { - char *lud_host; - int lud_port; -#ifdef USE_WIN32_LDAP - TCHAR *lud_dn; - TCHAR **lud_attrs; -#else - char *lud_dn; - char **lud_attrs; -#endif - int lud_scope; -#ifdef USE_WIN32_LDAP - TCHAR *lud_filter; -#else - char *lud_filter; -#endif - char **lud_exts; - size_t lud_attrs_dups; /* how many were dup'ed, this field is not in the - "real" struct so can only be used in code - without HAVE_LDAP_URL_PARSE defined */ -}; - -#undef LDAPURLDesc -#define LDAPURLDesc struct ldap_urldesc - -static curl_ldap_num_t ldap_url_parse_low(struct Curl_easy *data, - const struct connectdata *conn, - LDAPURLDesc **ludpp); -static void ldap_free_urldesc_low(LDAPURLDesc *ludp); - -#undef ldap_free_urldesc -#define ldap_free_urldesc ldap_free_urldesc_low - -#endif /* !HAVE_LDAP_URL_PARSE */ - -#ifdef DEBUG_LDAP -#define LDAP_TRACE(x) \ - do { \ - ldap_trace_low("%u: ", __LINE__); \ - ldap_trace_low x; \ - } while(0) - -static void ldap_trace_low(const char *fmt, ...) CURL_PRINTF(1, 2); -#else -#define LDAP_TRACE(x) Curl_nop_stmt -#endif - -#if defined(USE_WIN32_LDAP) && defined(ldap_err2string) -/* Use ANSI error strings in Unicode builds */ -#undef ldap_err2string -#define ldap_err2string ldap_err2stringA -#endif - -#if defined(USE_WIN32_LDAP) && defined(_MSC_VER) && (_MSC_VER <= 1700) -/* Workaround for warning: - 'type cast' : conversion from 'int' to 'void *' of greater size */ -#undef LDAP_OPT_ON -#undef LDAP_OPT_OFF -#define LDAP_OPT_ON ((void *)(size_t)1) -#define LDAP_OPT_OFF ((void *)(size_t)0) -#endif - -#ifdef USE_WIN32_LDAP - -#ifdef USE_WINDOWS_SSPI -static ULONG ldap_win_bind_auth(LDAP *server, const char *user, - const char *passwd, unsigned long authflags) -{ - ULONG method = 0; - SEC_WINNT_AUTH_IDENTITY cred; - ULONG rc = LDAP_AUTH_METHOD_NOT_SUPPORTED; - - memset(&cred, 0, sizeof(cred)); - -#ifdef USE_SPNEGO - if(authflags & CURLAUTH_NEGOTIATE) { - method = LDAP_AUTH_NEGOTIATE; - } - else -#endif -#ifdef USE_NTLM - if(authflags & CURLAUTH_NTLM) { - method = LDAP_AUTH_NTLM; - } - else -#endif -#ifndef CURL_DISABLE_DIGEST_AUTH - if(authflags & CURLAUTH_DIGEST) { - method = LDAP_AUTH_DIGEST; - } - else -#endif - { - /* required anyway if one of upper preprocessor definitions enabled */ - } - - if(method && user && passwd) { - CURLcode result = Curl_create_sspi_identity(user, passwd, &cred); - if(!result) { - rc = ldap_bind_s(server, NULL, (TCHAR *)&cred, method); - Curl_sspi_free_identity(&cred); - } - else { - rc = LDAP_NO_MEMORY; - } - } - else { - /* proceed with current user credentials */ - method = LDAP_AUTH_NEGOTIATE; - rc = ldap_bind_s(server, NULL, NULL, method); - } - return rc; -} -#endif /* USE_WINDOWS_SSPI */ - -static ULONG ldap_win_bind(struct Curl_easy *data, LDAP *server, - const char *user, const char *passwd) -{ - ULONG rc = LDAP_INVALID_CREDENTIALS; - - PTCHAR inuser = NULL; - PTCHAR inpass = NULL; - - if(user && passwd && (data->set.httpauth & CURLAUTH_BASIC)) { - inuser = curlx_convert_UTF8_to_tchar(user); - inpass = curlx_convert_UTF8_to_tchar(passwd); - - rc = ldap_simple_bind_s(server, inuser, inpass); - - curlx_free(inuser); - curlx_free(inpass); - } -#ifdef USE_WINDOWS_SSPI - else { - rc = ldap_win_bind_auth(server, user, passwd, data->set.httpauth); - } -#endif - - return rc; -} -#endif /* USE_WIN32_LDAP */ - -static CURLcode ldap_do(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - curl_ldap_num_t rc = LDAP_SUCCESS; - LDAP *server = NULL; - LDAPURLDesc *ludp = NULL; - LDAPMessage *ldapmsg = NULL; - LDAPMessage *entryIterator; - int num = 0; - struct connectdata *conn = data->conn; - int ldap_proto = LDAP_VERSION3; - int ldap_ssl = 0; - char *val_b64 = NULL; - size_t val_b64_sz = 0; -#ifdef LDAP_OPT_NETWORK_TIMEOUT - struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */ -#endif -#ifdef USE_WIN32_LDAP - TCHAR *host = NULL; -#else - char *host = NULL; -#endif - char *user = NULL; - char *passwd = NULL; - struct ip_quadruple ipquad; - bool is_ipv6; - - *done = TRUE; /* unconditionally */ - infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d", - LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); - infof(data, "LDAP local: %s", Curl_bufref_ptr(&data->state.url)); - -#ifdef HAVE_LDAP_URL_PARSE - rc = ldap_url_parse(Curl_bufref_ptr(&data->state.url), &ludp); -#else - rc = ldap_url_parse_low(data, conn, &ludp); -#endif - if(rc) { - failf(data, "Bad LDAP URL: %s", ldap_err2string(rc)); - result = CURLE_URL_MALFORMAT; - goto quit; - } - - result = Curl_conn_get_ip_info(data, conn, FIRSTSOCKET, &is_ipv6, &ipquad); - if(result) - goto quit; - - /* Get the URL scheme (either ldap or ldaps) */ - if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) - ldap_ssl = 1; - infof(data, "LDAP local: trying to establish %s connection", - ldap_ssl ? "encrypted" : "cleartext"); - -#ifdef USE_WIN32_LDAP - host = curlx_convert_UTF8_to_tchar(conn->host.name); - if(!host) { - result = CURLE_OUT_OF_MEMORY; - - goto quit; - } -#else - host = conn->host.name; -#endif - - if(data->state.aptr.user) { - user = conn->user; - passwd = conn->passwd; - } - -#ifdef USE_WIN32_LDAP - if(ldap_ssl) - server = ldap_sslinit(host, (curl_ldap_num_t)ipquad.remote_port, 1); - else -#endif - server = ldap_init(host, (curl_ldap_num_t)ipquad.remote_port); - if(!server) { - failf(data, "LDAP: cannot setup connect to %s:%u", - conn->host.dispname, ipquad.remote_port); - result = CURLE_COULDNT_CONNECT; - goto quit; - } - -#ifdef LDAP_OPT_NETWORK_TIMEOUT - ldap_set_option(server, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout); -#endif - ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); - - if(ldap_ssl) { -#ifdef HAVE_LDAP_SSL -#ifdef USE_WIN32_LDAP - /* Win32 LDAP SDK does not support insecure mode without CA! */ - ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON); -#else /* !USE_WIN32_LDAP */ - int ldap_option; - const char *ldap_ca = conn->ssl_config.CAfile; -#ifdef LDAP_OPT_X_TLS - if(conn->ssl_config.verifypeer) { - /* OpenLDAP SDK supports BASE64 files. */ - if(data->set.ssl.cert_type && - !curl_strequal(data->set.ssl.cert_type, "PEM")) { - failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type"); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - if(!ldap_ca) { - failf(data, "LDAP local: ERROR PEM CA cert not set"); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - infof(data, "LDAP local: using PEM CA cert: %s", ldap_ca); - rc = ldap_set_option(server, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting PEM CA cert: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - ldap_option = LDAP_OPT_X_TLS_DEMAND; - } - else - ldap_option = LDAP_OPT_X_TLS_NEVER; - - rc = ldap_set_option(server, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting cert verify mode: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - ldap_option = LDAP_OPT_X_TLS_HARD; - rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } -#else /* !LDAP_OPT_X_TLS */ - (void)ldap_option; - (void)ldap_ca; - /* we should probably never come up to here since configure - should check in first place if we can support LDAP SSL/TLS */ - failf(data, "LDAP local: SSL/TLS not supported with this version " - "of the OpenLDAP toolkit"); - result = CURLE_SSL_CERTPROBLEM; - goto quit; -#endif /* LDAP_OPT_X_TLS */ -#endif /* USE_WIN32_LDAP */ -#endif /* HAVE_LDAP_SSL */ - } - else if(data->set.use_ssl > CURLUSESSL_TRY) { - failf(data, "LDAP local: explicit TLS not supported"); - result = CURLE_NOT_BUILT_IN; - goto quit; - } - -#ifdef USE_WIN32_LDAP - rc = ldap_win_bind(data, server, user, passwd); -#else - rc = ldap_simple_bind_s(server, user, passwd); -#endif - if(!ldap_ssl && rc != LDAP_SUCCESS) { - ldap_proto = LDAP_VERSION2; - ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); -#ifdef USE_WIN32_LDAP - rc = ldap_win_bind(data, server, user, passwd); -#else - rc = ldap_simple_bind_s(server, user, passwd); -#endif - } - if(rc != LDAP_SUCCESS) { -#ifdef USE_WIN32_LDAP - failf(data, "LDAP local: bind via ldap_win_bind %s", - ldap_err2string(rc)); -#else - failf(data, "LDAP local: bind via ldap_simple_bind_s %s", - ldap_err2string(rc)); -#endif - result = CURLE_LDAP_CANNOT_BIND; - goto quit; - } - - Curl_pgrsReset(data); - rc = ldap_search_s(server, ludp->lud_dn, - ludp->lud_scope, - ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg); - - if(rc != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED) { - failf(data, "LDAP remote: %s", ldap_err2string(rc)); - result = CURLE_LDAP_SEARCH_FAILED; - goto quit; - } - - num = 0; - for(entryIterator = ldap_first_entry(server, ldapmsg); - entryIterator; - entryIterator = ldap_next_entry(server, entryIterator), num++) { - BerElement *ber = NULL; -#ifdef USE_WIN32_LDAP - TCHAR *attribute; -#else - char *attribute; -#endif - int i; - - /* Get the DN and write it to the client */ - { - char *name; - size_t name_len = 0; -#ifdef USE_WIN32_LDAP - TCHAR *dn = ldap_get_dn(server, entryIterator); - name = curlx_convert_tchar_to_UTF8(dn); - if(!name) { - ldap_memfree(dn); - - result = CURLE_OUT_OF_MEMORY; - - goto quit; - } -#else - char *dn = name = ldap_get_dn(server, entryIterator); -#endif - if(!name) - result = CURLE_FAILED_INIT; - else { - name_len = strlen(name); - result = Curl_client_write(data, CLIENTWRITE_BODY, "DN: ", 4); - } - if(!result) - result = Curl_client_write(data, CLIENTWRITE_BODY, name, name_len); - if(!result) - result = Curl_client_write(data, CLIENTWRITE_BODY, "\n", 1); - FREE_ON_WINLDAP(name); - ldap_memfree(dn); - if(result) - goto quit; - } - - /* Get the attributes and write them to the client */ - for(attribute = ldap_first_attribute(server, entryIterator, &ber); - attribute; - attribute = ldap_next_attribute(server, entryIterator, ber)) { - BerValue **vals; - size_t attr_len; -#ifdef USE_WIN32_LDAP - char *attr = curlx_convert_tchar_to_UTF8(attribute); - if(!attr) { - if(ber) - ber_free(ber, 0); - - result = CURLE_OUT_OF_MEMORY; - - goto quit; - } -#else - char *attr = attribute; -#endif - attr_len = strlen(attr); - - vals = ldap_get_values_len(server, entryIterator, attribute); - if(vals) { - for(i = 0; (vals[i] != NULL); i++) { - result = Curl_client_write(data, CLIENTWRITE_BODY, "\t", 1); - if(result) { - ldap_value_free_len(vals); - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - result = Curl_client_write(data, CLIENTWRITE_BODY, attr, attr_len); - if(result) { - ldap_value_free_len(vals); - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - result = Curl_client_write(data, CLIENTWRITE_BODY, ": ", 2); - if(result) { - ldap_value_free_len(vals); - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - if((attr_len > 7) && - curl_strequal(";binary", attr + (attr_len - 7))) { - /* Binary attribute, encode to base64. */ - if(vals[i]->bv_len) { - result = curlx_base64_encode((uint8_t *)vals[i]->bv_val, - vals[i]->bv_len, - &val_b64, &val_b64_sz); - if(result) { - ldap_value_free_len(vals); - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - if(val_b64_sz > 0) { - result = Curl_client_write(data, CLIENTWRITE_BODY, val_b64, - val_b64_sz); - curlx_free(val_b64); - if(result) { - ldap_value_free_len(vals); - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - } - } - } - else { - result = Curl_client_write(data, CLIENTWRITE_BODY, vals[i]->bv_val, - vals[i]->bv_len); - if(result) { - ldap_value_free_len(vals); - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - } - - result = Curl_client_write(data, CLIENTWRITE_BODY, "\n", 1); - if(result) { - ldap_value_free_len(vals); - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - } - - /* Free memory used to store values */ - ldap_value_free_len(vals); - } - - /* Free the attribute as we are done with it */ - FREE_ON_WINLDAP(attr); - ldap_memfree(attribute); - - result = Curl_client_write(data, CLIENTWRITE_BODY, "\n", 1); - if(result) - goto quit; - } - - if(ber) - ber_free(ber, 0); - } - -quit: - if(ldapmsg) { - ldap_msgfree(ldapmsg); - LDAP_TRACE(("Received %d entries\n", num)); - } - if(rc == LDAP_SIZELIMIT_EXCEEDED) - infof(data, "There are more than %d entries", num); - if(ludp) - ldap_free_urldesc(ludp); - if(server) - ldap_unbind_s(server); - - FREE_ON_WINLDAP(host); - - /* no data to transfer */ - Curl_xfer_setup_nop(data); - connclose(conn, "LDAP connection always disable reuse"); - - return result; -} - -#ifdef DEBUG_LDAP -static void ldap_trace_low(const char *fmt, ...) -{ - static int do_trace = -1; - va_list args; - - if(do_trace == -1) { - const char *env = getenv("CURL_TRACE"); - curl_off_t e = 0; - if(!curlx_str_number(&env, &e, INT_MAX)) - do_trace = e > 0; - } - if(!do_trace) - return; - - va_start(args, fmt); - curl_mvfprintf(stderr, fmt, args); - va_end(args); -} -#endif /* DEBUG_LDAP */ - -#ifndef HAVE_LDAP_URL_PARSE - -/* - * Return scope-value for a scope-string. - */ -static int str2scope(const char *p) -{ - if(curl_strequal(p, "one")) - return LDAP_SCOPE_ONELEVEL; - if(curl_strequal(p, "onetree")) - return LDAP_SCOPE_ONELEVEL; - if(curl_strequal(p, "base")) - return LDAP_SCOPE_BASE; - if(curl_strequal(p, "sub")) - return LDAP_SCOPE_SUBTREE; - if(curl_strequal(p, "subtree")) - return LDAP_SCOPE_SUBTREE; - return -1; -} - -/* number of entries in the attributes list */ -static size_t num_entries(const char *s) -{ - size_t items = 1; - - s = strchr(s, ','); - while(s) { - items++; - s = strchr(s + 1, ','); - } - return items; -} - -/* - * Break apart the pieces of an LDAP URL. - * Syntax: - * ldap://:/???? - * - * already known from 'conn->host.name'. - * already known from 'conn->remote_port'. - * extract the rest from 'data->state.path+1'. All fields are optional. - * e.g. - * ldap://:/??? - * yields ludp->lud_dn = "". - * - * Defined in RFC4516 section 2. - */ -static curl_ldap_num_t ldap_url_parse2_low(struct Curl_easy *data, - const struct connectdata *conn, - LDAPURLDesc *ludp) -{ - curl_ldap_num_t rc = LDAP_SUCCESS; - char *p; - char *path; - char *q = NULL; - char *query = NULL; - size_t i; - - if(!data || - !data->state.up.path || - data->state.up.path[0] != '/' || - !curl_strnequal("LDAP", data->state.up.scheme, 4)) - return LDAP_INVALID_SYNTAX; - - ludp->lud_scope = LDAP_SCOPE_BASE; - ludp->lud_port = conn->remote_port; - ludp->lud_host = conn->host.name; - - /* Duplicate the path */ - p = path = curlx_strdup(data->state.up.path + 1); - if(!path) - return LDAP_NO_MEMORY; - - /* Duplicate the query if present */ - if(data->state.up.query) { - q = query = curlx_strdup(data->state.up.query); - if(!query) { - curlx_free(path); - return LDAP_NO_MEMORY; - } - } - - /* Parse the DN (Distinguished Name) */ - if(*p) { - char *dn = p; - char *unescaped; - CURLcode result; - - LDAP_TRACE(("DN '%s'\n", dn)); - - /* Unescape the DN */ - result = Curl_urldecode(dn, 0, &unescaped, NULL, REJECT_ZERO); - if(result) { - rc = LDAP_NO_MEMORY; - - goto quit; - } - -#ifdef USE_WIN32_LDAP - /* Convert the unescaped string to a tchar */ - ludp->lud_dn = curlx_convert_UTF8_to_tchar(unescaped); - - /* Free the unescaped string as we are done with it */ - curlx_free(unescaped); - - if(!ludp->lud_dn) { - rc = LDAP_NO_MEMORY; - - goto quit; - } -#else - ludp->lud_dn = unescaped; -#endif - } - - p = q; - if(!p) - goto quit; - - /* Parse the attributes. skip "??" */ - q = strchr(p, '?'); - if(q) - *q++ = '\0'; - - if(*p) { - size_t count = num_entries(p); /* at least one */ - const char *atp = p; - - /* Allocate our array (+1 for the NULL entry) */ -#ifdef USE_WIN32_LDAP - ludp->lud_attrs = curlx_calloc(count + 1, sizeof(TCHAR *)); -#else - ludp->lud_attrs = curlx_calloc(count + 1, sizeof(char *)); -#endif - if(!ludp->lud_attrs) { - rc = LDAP_NO_MEMORY; - goto quit; - } - - for(i = 0; i < count; i++) { - char *unescaped; - CURLcode result; - struct Curl_str out; - - if(curlx_str_until(&atp, &out, 1024, ',')) - break; - - LDAP_TRACE(("attr[%zu] '%.*s'\n", i, (int)out.len, out.str)); - - /* Unescape the attribute */ - result = Curl_urldecode(out.str, out.len, &unescaped, NULL, REJECT_ZERO); - if(result) { - rc = LDAP_NO_MEMORY; - goto quit; - } - -#ifdef USE_WIN32_LDAP - /* Convert the unescaped string to a tchar */ - ludp->lud_attrs[i] = curlx_convert_UTF8_to_tchar(unescaped); - - /* Free the unescaped string as we are done with it */ - curlx_free(unescaped); - - if(!ludp->lud_attrs[i]) { - rc = LDAP_NO_MEMORY; - goto quit; - } -#else - ludp->lud_attrs[i] = unescaped; -#endif - - ludp->lud_attrs_dups++; - if(curlx_str_single(&atp, ',')) - break; - } - } - - p = q; - if(!p) - goto quit; - - /* Parse the scope. skip "??" */ - q = strchr(p, '?'); - if(q) - *q++ = '\0'; - - if(*p) { - ludp->lud_scope = str2scope(p); - if(ludp->lud_scope == -1) { - rc = LDAP_INVALID_SYNTAX; - - goto quit; - } - LDAP_TRACE(("scope %d\n", ludp->lud_scope)); - } - - p = q; - if(!p) - goto quit; - - /* Parse the filter */ - q = strchr(p, '?'); - if(q) - *q++ = '\0'; - - if(*p) { - char *filter = p; - char *unescaped; - CURLcode result; - - LDAP_TRACE(("filter '%s'\n", filter)); - - /* Unescape the filter */ - result = Curl_urldecode(filter, 0, &unescaped, NULL, REJECT_ZERO); - if(result) { - rc = LDAP_NO_MEMORY; - - goto quit; - } - -#ifdef USE_WIN32_LDAP - /* Convert the unescaped string to a tchar */ - ludp->lud_filter = curlx_convert_UTF8_to_tchar(unescaped); - - /* Free the unescaped string as we are done with it */ - curlx_free(unescaped); - - if(!ludp->lud_filter) { - rc = LDAP_NO_MEMORY; - - goto quit; - } -#else - ludp->lud_filter = unescaped; -#endif - } - - p = q; - if(p && !*p) { - rc = LDAP_INVALID_SYNTAX; - - goto quit; - } - -quit: - curlx_free(path); - curlx_free(query); - - return rc; -} - -static curl_ldap_num_t ldap_url_parse_low(struct Curl_easy *data, - const struct connectdata *conn, - LDAPURLDesc **ludpp) -{ - LDAPURLDesc *ludp = curlx_calloc(1, sizeof(*ludp)); - curl_ldap_num_t rc; - - *ludpp = NULL; - if(!ludp) - return LDAP_NO_MEMORY; - - rc = ldap_url_parse2_low(data, conn, ludp); - if(rc != LDAP_SUCCESS) { - ldap_free_urldesc_low(ludp); - ludp = NULL; - } - *ludpp = ludp; - return rc; -} - -static void ldap_free_urldesc_low(LDAPURLDesc *ludp) -{ - if(!ludp) - return; - - curlx_free(ludp->lud_dn); - curlx_free(ludp->lud_filter); - - if(ludp->lud_attrs) { - size_t i; - for(i = 0; i < ludp->lud_attrs_dups; i++) { - curlx_free(ludp->lud_attrs[i]); - } - curlx_free(ludp->lud_attrs); - } - - curlx_free(ludp); -} -#endif /* !HAVE_LDAP_URL_PARSE */ - -void Curl_ldap_version(char *buf, size_t bufsz) -{ -#ifdef USE_WIN32_LDAP - curl_msnprintf(buf, bufsz, "WinLDAP"); -#else -#ifdef LDAP_OPT_X_TLS_PASSPHRASE - static const char *flavor = "/Apple"; -#else - static const char *flavor = ""; -#endif - LDAPAPIInfo api; - api.ldapai_info_version = LDAP_API_INFO_VERSION; - - /* Comparing against 0, as different platforms - disagree on the success define name */ - if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) == 0) { - unsigned int patch = (unsigned int)(api.ldapai_vendor_version % 100); - unsigned int major = (unsigned int)(api.ldapai_vendor_version / 10000); - unsigned int minor = - (((unsigned int)api.ldapai_vendor_version - (major * 10000)) - - patch) / 100; -#ifdef __OS400__ - curl_msnprintf(buf, bufsz, "IBMLDAP/%u.%u.%u", major, minor, patch); - ldap_value_free(api.ldapai_extensions); - (void)flavor; -#else - curl_msnprintf(buf, bufsz, "%s/%u.%u.%u%s", - api.ldapai_vendor_name, major, minor, patch, flavor); - ldap_memfree(api.ldapai_vendor_name); - ber_memvfree((void **)api.ldapai_extensions); -#endif - } - else - curl_msnprintf(buf, bufsz, "LDAP/1"); -#endif /* USE_WIN32_LDAP */ -} - -/* - * LDAP protocol handler. - */ -const struct Curl_protocol Curl_protocol_ldap = { - ZERO_NULL, /* setup_connection */ - ldap_do, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - ZERO_NULL, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic pop -#endif - -#endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */ diff --git a/vendor/curl/lib/llist.c b/vendor/curl/lib/llist.c deleted file mode 100644 index 3ec85e4a2..000000000 --- a/vendor/curl/lib/llist.c +++ /dev/null @@ -1,270 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "llist.h" - -#ifdef DEBUGBUILD -#define LLISTINIT 0x100cc001 /* random pattern */ -#define NODEINIT 0x12344321 /* random pattern */ -#define NODEREM 0x54321012 /* random pattern */ - -#define VERIFYNODE(x) verifynode(x) -static struct Curl_llist_node *verifynode(struct Curl_llist_node *n) -{ - DEBUGASSERT(!n || (n->_init == NODEINIT)); - return n; -} -#else -#define VERIFYNODE(x) x -#endif -/* - * @unittest 1300 - */ -void Curl_llist_init(struct Curl_llist *l, Curl_llist_dtor dtor) -{ - l->_size = 0; - l->_dtor = dtor; - l->_head = NULL; - l->_tail = NULL; -#ifdef DEBUGBUILD - l->_init = LLISTINIT; -#endif -} - -/* - * Curl_llist_insert_next() - * - * Inserts a new list element after the given one 'e'. If the given existing - * entry is NULL and the list already has elements, the new one will be - * inserted first in the list. - * - * The 'ne' argument should be a pointer into the object to store. - * - * @unittest 1300 - */ -void Curl_llist_insert_next(struct Curl_llist *list, - struct Curl_llist_node *e, /* may be NULL */ - const void *p, - struct Curl_llist_node *ne) -{ - DEBUGASSERT(list); - DEBUGASSERT(list->_init == LLISTINIT); - DEBUGASSERT(ne); - -#ifdef DEBUGBUILD - ne->_init = NODEINIT; -#endif - ne->_ptr = CURL_UNCONST(p); - ne->_list = list; - if(list->_size == 0) { - list->_head = ne; - list->_head->_prev = NULL; - list->_head->_next = NULL; - list->_tail = ne; - } - else { - /* if 'e' is NULL here, we insert the new element first in the list */ - ne->_next = e ? e->_next : list->_head; - ne->_prev = e; - if(!e) { - list->_head->_prev = ne; - list->_head = ne; - } - else if(e->_next) { - e->_next->_prev = ne; - } - else { - list->_tail = ne; - } - if(e) - e->_next = ne; - } - - ++list->_size; -} - -/* - * Curl_llist_append() - * - * Adds a new list element to the end of the list. - * - * The 'ne' argument should be a pointer into the object to store. - * - * @unittest 1300 - */ -void Curl_llist_append(struct Curl_llist *list, const void *p, - struct Curl_llist_node *ne) -{ - DEBUGASSERT(list); - DEBUGASSERT(list->_init == LLISTINIT); - DEBUGASSERT(ne); - Curl_llist_insert_next(list, list->_tail, p, ne); -} - -void *Curl_node_take_elem(struct Curl_llist_node *e) -{ - void *ptr; - struct Curl_llist *list; - if(!e) - return NULL; - - list = e->_list; - DEBUGASSERT(list); - DEBUGASSERT(list->_init == LLISTINIT); - DEBUGASSERT(list->_size); - DEBUGASSERT(e->_init == NODEINIT); - if(list) { - if(e == list->_head) { - list->_head = e->_next; - - if(!list->_head) - list->_tail = NULL; - else - e->_next->_prev = NULL; - } - else { - if(e->_prev) - e->_prev->_next = e->_next; - - if(!e->_next) - list->_tail = e->_prev; - else - e->_next->_prev = e->_prev; - } - --list->_size; - } - ptr = e->_ptr; - - e->_list = NULL; - e->_ptr = NULL; - e->_prev = NULL; - e->_next = NULL; -#ifdef DEBUGBUILD - e->_init = NODEREM; /* specific pattern on remove - not zero */ -#endif - - return ptr; -} - -static void node_uremove(struct Curl_llist_node *e, void *user) -{ - struct Curl_llist *list; - void *ptr; - if(!e) - return; - - list = e->_list; - DEBUGASSERT(list); - if(list) { - ptr = Curl_node_take_elem(e); - if(list->_dtor) - list->_dtor(user, ptr); - } -} - -void Curl_node_remove(struct Curl_llist_node *e) -{ - node_uremove(e, NULL); -} - -void Curl_llist_destroy(struct Curl_llist *list, void *user) -{ - if(list) { - DEBUGASSERT(list->_init == LLISTINIT); - while(list->_size > 0) - node_uremove(list->_tail, user); - } -} - -/* Curl_llist_head() returns the first 'struct Curl_llist_node *', which - might be NULL */ -struct Curl_llist_node *Curl_llist_head(struct Curl_llist *list) -{ - DEBUGASSERT(list); - DEBUGASSERT(list->_init == LLISTINIT); - return VERIFYNODE(list->_head); -} - -#ifdef UNITTESTS -/* llist_tail() returns the last 'struct Curl_llist_node *', which might be - NULL - - @unittest 1300 -*/ -UNITTEST struct Curl_llist_node *llist_tail(struct Curl_llist *list); -UNITTEST struct Curl_llist_node *llist_tail(struct Curl_llist *list) -{ - DEBUGASSERT(list); - DEBUGASSERT(list->_init == LLISTINIT); - return VERIFYNODE(list->_tail); -} -#endif - -/* Curl_llist_count() returns a size_t the number of nodes in the list */ -size_t Curl_llist_count(struct Curl_llist *list) -{ - DEBUGASSERT(list); - DEBUGASSERT(list->_init == LLISTINIT); - return list->_size; -} - -/* Curl_node_elem() returns the custom data from a Curl_llist_node */ -void *Curl_node_elem(struct Curl_llist_node *n) -{ - DEBUGASSERT(n); - DEBUGASSERT(n->_init == NODEINIT); - return n->_ptr; -} - -/* Curl_node_next() returns the next element in a list from a given - Curl_llist_node */ -struct Curl_llist_node *Curl_node_next(struct Curl_llist_node *n) -{ - DEBUGASSERT(n); - DEBUGASSERT(n->_init == NODEINIT); - return VERIFYNODE(n->_next); -} - -#ifdef UNITTESTS -/* llist_node_prev() returns the previous element in a list from a given - Curl_llist_node - - @unittest 1300 -*/ -UNITTEST struct Curl_llist_node *llist_node_prev(struct Curl_llist_node *n); -UNITTEST struct Curl_llist_node *llist_node_prev(struct Curl_llist_node *n) -{ - DEBUGASSERT(n); - DEBUGASSERT(n->_init == NODEINIT); - return VERIFYNODE(n->_prev); -} -#endif - -struct Curl_llist *Curl_node_llist(struct Curl_llist_node *n) -{ - DEBUGASSERT(n); - DEBUGASSERT(!n->_list || n->_init == NODEINIT); - return n->_list; -} diff --git a/vendor/curl/lib/llist.h b/vendor/curl/lib/llist.h deleted file mode 100644 index 28e958d5c..000000000 --- a/vendor/curl/lib/llist.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef HEADER_CURL_LLIST_H -#define HEADER_CURL_LLIST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -typedef void (*Curl_llist_dtor)(void *user, void *elem); - -/* none of these struct members should be referenced directly, use the - dedicated functions */ - -struct Curl_llist { - struct Curl_llist_node *_head; - struct Curl_llist_node *_tail; - Curl_llist_dtor _dtor; - size_t _size; -#ifdef DEBUGBUILD - int _init; /* detect API usage mistakes */ -#endif -}; - -struct Curl_llist_node { - struct Curl_llist *_list; /* the list where this belongs */ - void *_ptr; - struct Curl_llist_node *_prev; - struct Curl_llist_node *_next; -#ifdef DEBUGBUILD - int _init; /* detect API usage mistakes */ -#endif -}; - -void Curl_llist_init(struct Curl_llist *l, Curl_llist_dtor dtor); -void Curl_llist_insert_next(struct Curl_llist *list, struct Curl_llist_node *e, - const void *p, struct Curl_llist_node *ne); -void Curl_llist_append(struct Curl_llist *list, const void *p, - struct Curl_llist_node *ne); -void Curl_node_remove(struct Curl_llist_node *e); -void Curl_llist_destroy(struct Curl_llist *list, void *user); - -/* Curl_llist_head() returns the first 'struct Curl_llist_node *', which - might be NULL */ -struct Curl_llist_node *Curl_llist_head(struct Curl_llist *list); - -/* Curl_llist_count() returns a size_t the number of nodes in the list */ -size_t Curl_llist_count(struct Curl_llist *list); - -/* Curl_node_elem() returns the custom data from a Curl_llist_node */ -void *Curl_node_elem(struct Curl_llist_node *n); - -/* Remove the node from the list and return the custom data - * from a Curl_llist_node. Does NOT invoke a registered `dtor`. */ -void *Curl_node_take_elem(struct Curl_llist_node *e); - -/* Curl_node_next() returns the next element in a list from a given - Curl_llist_node */ -struct Curl_llist_node *Curl_node_next(struct Curl_llist_node *n); - -/* Curl_node_llist() return the list the node is in or NULL. */ -struct Curl_llist *Curl_node_llist(struct Curl_llist_node *n); - -#endif /* HEADER_CURL_LLIST_H */ diff --git a/vendor/curl/lib/macos.c b/vendor/curl/lib/macos.c deleted file mode 100644 index 334dbc7d1..000000000 --- a/vendor/curl/lib/macos.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef CURL_MACOS_CALL_COPYPROXIES - -#include "macos.h" - -#include - -CURLcode Curl_macos_init(void) -{ - /* - * The automagic conversion from IPv4 literals to IPv6 literals only - * works if the SCDynamicStoreCopyProxies system function gets called - * first. As curl currently does not support system-wide HTTP proxies, we - * therefore do not use any value this function might return. - * - * This function is only available on macOS and is not needed for - * IPv4-only builds, hence the conditions for defining - * CURL_MACOS_CALL_COPYPROXIES in curl_setup.h. - */ - CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); - if(dict) - CFRelease(dict); - return CURLE_OK; -} - -#endif diff --git a/vendor/curl/lib/macos.h b/vendor/curl/lib/macos.h deleted file mode 100644 index 0a72a3027..000000000 --- a/vendor/curl/lib/macos.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef HEADER_CURL_MACOS_H -#define HEADER_CURL_MACOS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef CURL_MACOS_CALL_COPYPROXIES -CURLcode Curl_macos_init(void); -#else -#define Curl_macos_init() CURLE_OK -#endif - -#endif /* HEADER_CURL_MACOS_H */ diff --git a/vendor/curl/lib/md4.c b/vendor/curl/lib/md4.c deleted file mode 100644 index 0213483ad..000000000 --- a/vendor/curl/lib/md4.c +++ /dev/null @@ -1,461 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_CURL_NTLM_CORE - -#include "curl_md4.h" - -#ifdef USE_OPENSSL -#include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(USE_AMISSL) -/* OpenSSL 3.0.0 marks the MD4 functions as deprecated */ -#define OPENSSL_NO_MD4 -#else -/* Cover also OPENSSL_NO_MD4 configured in OpenSSL */ -#include -#endif -#endif /* USE_OPENSSL */ - -#ifdef USE_WOLFSSL -#include -#endif - -/* When OpenSSL or wolfSSL is available, we use their MD4 functions. */ - -#if defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4) -#include - -/* Map directly to OpenSSL implementation */ -#define my_md4_ctx MD4_CTX -#define my_md4_init MD4_Init -#define my_md4_update MD4_Update -#define my_md4_final MD4_Final - -#elif defined(USE_WOLFSSL) && !defined(NO_MD4) -#include -#include - -#if LIBWOLFSSL_VERSION_HEX >= 0x05007006 -typedef wc_Md4 my_md4_ctx; -#else -typedef Md4 my_md4_ctx; -#endif - -static int my_md4_init(my_md4_ctx *ctx) -{ - wc_InitMd4(ctx); - return 1; -} - -static void my_md4_update(my_md4_ctx *ctx, - const void *input, unsigned long len) -{ - wc_Md4Update(ctx, input, (word32)len); -} - -static void my_md4_final(unsigned char *digest, my_md4_ctx *ctx) -{ - wc_Md4Final(ctx, digest); -} - -#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \ - defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ - (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \ - (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ - (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000) && \ - defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ - (__IPHONE_OS_VERSION_MIN_REQUIRED < 130000)) -#include - -typedef CC_MD4_CTX my_md4_ctx; - -static int my_md4_init(my_md4_ctx *ctx) -{ - return CC_MD4_Init(ctx); -} - -static void my_md4_update(my_md4_ctx *ctx, - const void *input, unsigned long len) -{ - (void)CC_MD4_Update(ctx, input, (CC_LONG)len); -} - -static void my_md4_final(unsigned char *digest, my_md4_ctx *ctx) -{ - (void)CC_MD4_Final(digest, ctx); -} - -#elif defined(USE_WIN32_CRYPTO) -#include - -struct md4_ctx { - HCRYPTPROV hCryptProv; - HCRYPTHASH hHash; -}; -typedef struct md4_ctx my_md4_ctx; - -static int my_md4_init(my_md4_ctx *ctx) -{ - ctx->hCryptProv = 0; - ctx->hHash = 0; - - if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return 0; - - if(!CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash)) { - CryptReleaseContext(ctx->hCryptProv, 0); - ctx->hCryptProv = 0; - return 0; - } - - return 1; -} - -static void my_md4_update(my_md4_ctx *ctx, - const void *input, unsigned long len) -{ - CryptHashData(ctx->hHash, (const BYTE *)input, (unsigned int)len, 0); -} - -static void my_md4_final(unsigned char *digest, my_md4_ctx *ctx) -{ - unsigned long length = 0; - - CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); - if(length == MD4_DIGEST_LENGTH) - CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); - - if(ctx->hHash) - CryptDestroyHash(ctx->hHash); - - if(ctx->hCryptProv) - CryptReleaseContext(ctx->hCryptProv, 0); -} - -#elif defined(USE_GNUTLS) -#include - -typedef struct md4_ctx my_md4_ctx; - -static int my_md4_init(my_md4_ctx *ctx) -{ - md4_init(ctx); - return 1; -} - -static void my_md4_update(my_md4_ctx *ctx, - const void *input, unsigned long len) -{ - md4_update(ctx, len, input); -} - -static void my_md4_final(unsigned char *digest, my_md4_ctx *ctx) -{ - md4_digest(ctx, MD4_DIGEST_SIZE, digest); -} - -#else -/* When no other crypto library is available, or the crypto library does not - * support MD4, we use this code segment this implementation of it - * - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD4 Message-Digest Algorithm (RFC 1320). - * - * Homepage: - * https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 - * - * Author: - * Alexander Peslyak, better known as Solar Designer - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. In case - * this attempt to disclaim copyright and place the software in the public - * domain is deemed null and void, then the software is Copyright (c) 2001 - * Alexander Peslyak and it is hereby released to the general public under - * the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There is ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - */ - -struct md4_ctx { - uint32_t lo, hi; - uint32_t a, b, c, d; - unsigned char buffer[64]; - uint32_t block[16]; -}; -typedef struct md4_ctx my_md4_ctx; - -/* - * The basic MD4 functions. - * - * F and G are optimized compared to their RFC 1320 definitions, with the - * optimization for F borrowed from Colin Plumb's MD5 implementation. - */ -#define MD4_F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define MD4_G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) -#define MD4_H(x, y, z) ((x) ^ (y) ^ (z)) - -/* - * The MD4 transformation for all three rounds. - */ -#define MD4_STEP(f, a, b, c, d, x, s) \ - (a) += f(b, c, d) + (x); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); - -/* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned memory - * accesses is an optimization. Nothing will break if it does not work. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -#define MD4_SET(n) (*(const uint32_t *)(const void *)&ptr[(n) * 4]) -#define MD4_GET(n) MD4_SET(n) -#else -#define MD4_SET(n) (ctx->block[n] = \ - (uint32_t)ptr[(n) * 4] | \ - ((uint32_t)ptr[((n) * 4) + 1] << 8) | \ - ((uint32_t)ptr[((n) * 4) + 2] << 16) | \ - ((uint32_t)ptr[((n) * 4) + 3] << 24)) -#define MD4_GET(n) ctx->block[n] -#endif - -/* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. - */ -static const void *my_md4_body(my_md4_ctx *ctx, - const void *input, unsigned long size) -{ - const unsigned char *ptr; - uint32_t a, b, c, d; - - ptr = (const unsigned char *)input; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - uint32_t saved_a, saved_b, saved_c, saved_d; - - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - - /* Round 1 */ - MD4_STEP(MD4_F, a, b, c, d, MD4_SET(0), 3) - MD4_STEP(MD4_F, d, a, b, c, MD4_SET(1), 7) - MD4_STEP(MD4_F, c, d, a, b, MD4_SET(2), 11) - MD4_STEP(MD4_F, b, c, d, a, MD4_SET(3), 19) - MD4_STEP(MD4_F, a, b, c, d, MD4_SET(4), 3) - MD4_STEP(MD4_F, d, a, b, c, MD4_SET(5), 7) - MD4_STEP(MD4_F, c, d, a, b, MD4_SET(6), 11) - MD4_STEP(MD4_F, b, c, d, a, MD4_SET(7), 19) - MD4_STEP(MD4_F, a, b, c, d, MD4_SET(8), 3) - MD4_STEP(MD4_F, d, a, b, c, MD4_SET(9), 7) - MD4_STEP(MD4_F, c, d, a, b, MD4_SET(10), 11) - MD4_STEP(MD4_F, b, c, d, a, MD4_SET(11), 19) - MD4_STEP(MD4_F, a, b, c, d, MD4_SET(12), 3) - MD4_STEP(MD4_F, d, a, b, c, MD4_SET(13), 7) - MD4_STEP(MD4_F, c, d, a, b, MD4_SET(14), 11) - MD4_STEP(MD4_F, b, c, d, a, MD4_SET(15), 19) - - /* Round 2 */ - MD4_STEP(MD4_G, a, b, c, d, MD4_GET(0) + 0x5a827999, 3) - MD4_STEP(MD4_G, d, a, b, c, MD4_GET(4) + 0x5a827999, 5) - MD4_STEP(MD4_G, c, d, a, b, MD4_GET(8) + 0x5a827999, 9) - MD4_STEP(MD4_G, b, c, d, a, MD4_GET(12) + 0x5a827999, 13) - MD4_STEP(MD4_G, a, b, c, d, MD4_GET(1) + 0x5a827999, 3) - MD4_STEP(MD4_G, d, a, b, c, MD4_GET(5) + 0x5a827999, 5) - MD4_STEP(MD4_G, c, d, a, b, MD4_GET(9) + 0x5a827999, 9) - MD4_STEP(MD4_G, b, c, d, a, MD4_GET(13) + 0x5a827999, 13) - MD4_STEP(MD4_G, a, b, c, d, MD4_GET(2) + 0x5a827999, 3) - MD4_STEP(MD4_G, d, a, b, c, MD4_GET(6) + 0x5a827999, 5) - MD4_STEP(MD4_G, c, d, a, b, MD4_GET(10) + 0x5a827999, 9) - MD4_STEP(MD4_G, b, c, d, a, MD4_GET(14) + 0x5a827999, 13) - MD4_STEP(MD4_G, a, b, c, d, MD4_GET(3) + 0x5a827999, 3) - MD4_STEP(MD4_G, d, a, b, c, MD4_GET(7) + 0x5a827999, 5) - MD4_STEP(MD4_G, c, d, a, b, MD4_GET(11) + 0x5a827999, 9) - MD4_STEP(MD4_G, b, c, d, a, MD4_GET(15) + 0x5a827999, 13) - - /* Round 3 */ - MD4_STEP(MD4_H, a, b, c, d, MD4_GET(0) + 0x6ed9eba1, 3) - MD4_STEP(MD4_H, d, a, b, c, MD4_GET(8) + 0x6ed9eba1, 9) - MD4_STEP(MD4_H, c, d, a, b, MD4_GET(4) + 0x6ed9eba1, 11) - MD4_STEP(MD4_H, b, c, d, a, MD4_GET(12) + 0x6ed9eba1, 15) - MD4_STEP(MD4_H, a, b, c, d, MD4_GET(2) + 0x6ed9eba1, 3) - MD4_STEP(MD4_H, d, a, b, c, MD4_GET(10) + 0x6ed9eba1, 9) - MD4_STEP(MD4_H, c, d, a, b, MD4_GET(6) + 0x6ed9eba1, 11) - MD4_STEP(MD4_H, b, c, d, a, MD4_GET(14) + 0x6ed9eba1, 15) - MD4_STEP(MD4_H, a, b, c, d, MD4_GET(1) + 0x6ed9eba1, 3) - MD4_STEP(MD4_H, d, a, b, c, MD4_GET(9) + 0x6ed9eba1, 9) - MD4_STEP(MD4_H, c, d, a, b, MD4_GET(5) + 0x6ed9eba1, 11) - MD4_STEP(MD4_H, b, c, d, a, MD4_GET(13) + 0x6ed9eba1, 15) - MD4_STEP(MD4_H, a, b, c, d, MD4_GET(3) + 0x6ed9eba1, 3) - MD4_STEP(MD4_H, d, a, b, c, MD4_GET(11) + 0x6ed9eba1, 9) - MD4_STEP(MD4_H, c, d, a, b, MD4_GET(7) + 0x6ed9eba1, 11) - MD4_STEP(MD4_H, b, c, d, a, MD4_GET(15) + 0x6ed9eba1, 15) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while(size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; -} - -static int my_md4_init(my_md4_ctx *ctx) -{ - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; - - return 1; -} - -static void my_md4_update(my_md4_ctx *ctx, - const void *input, unsigned long len) -{ - uint32_t saved_lo; - unsigned long used; - - saved_lo = ctx->lo; - ctx->lo = (saved_lo + len) & 0x1fffffff; - if(ctx->lo < saved_lo) - ctx->hi++; - ctx->hi += (uint32_t)len >> 29; - - used = saved_lo & 0x3f; - - if(used) { - unsigned long available = 64 - used; - - if(len < available) { - memcpy(&ctx->buffer[used], input, len); - return; - } - - memcpy(&ctx->buffer[used], input, available); - input = (const unsigned char *)input + available; - len -= available; - my_md4_body(ctx, ctx->buffer, 64); - } - - if(len >= 64) { - input = my_md4_body(ctx, input, len & ~(unsigned long)0x3f); - len &= 0x3f; - } - - memcpy(ctx->buffer, input, len); -} - -static void my_md4_final(unsigned char *digest, my_md4_ctx *ctx) -{ - unsigned long used, available; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - available = 64 - used; - - if(available < 8) { - memset(&ctx->buffer[used], 0, available); - my_md4_body(ctx, ctx->buffer, 64); - used = 0; - available = 64; - } - - memset(&ctx->buffer[used], 0, available - 8); - - ctx->lo <<= 3; - ctx->buffer[56] = curlx_ultouc((ctx->lo) & 0xff); - ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8) & 0xff); - ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16) & 0xff); - ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24) & 0xff); - ctx->buffer[60] = curlx_ultouc((ctx->hi) & 0xff); - ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8) & 0xff); - ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16) & 0xff); - ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); - - my_md4_body(ctx, ctx->buffer, 64); - - digest[0] = curlx_ultouc((ctx->a) & 0xff); - digest[1] = curlx_ultouc((ctx->a >> 8) & 0xff); - digest[2] = curlx_ultouc((ctx->a >> 16) & 0xff); - digest[3] = curlx_ultouc(ctx->a >> 24); - digest[4] = curlx_ultouc((ctx->b) & 0xff); - digest[5] = curlx_ultouc((ctx->b >> 8) & 0xff); - digest[6] = curlx_ultouc((ctx->b >> 16) & 0xff); - digest[7] = curlx_ultouc(ctx->b >> 24); - digest[8] = curlx_ultouc((ctx->c) & 0xff); - digest[9] = curlx_ultouc((ctx->c >> 8) & 0xff); - digest[10] = curlx_ultouc((ctx->c >> 16) & 0xff); - digest[11] = curlx_ultouc(ctx->c >> 24); - digest[12] = curlx_ultouc((ctx->d) & 0xff); - digest[13] = curlx_ultouc((ctx->d >> 8) & 0xff); - digest[14] = curlx_ultouc((ctx->d >> 16) & 0xff); - digest[15] = curlx_ultouc(ctx->d >> 24); - - memset(ctx, 0, sizeof(*ctx)); -} - -#endif /* CRYPTO LIBS */ - -CURLcode Curl_md4it(unsigned char *output, - const unsigned char *input, const size_t len) -{ - my_md4_ctx ctx; - if(!my_md4_init(&ctx)) - return CURLE_FAILED_INIT; - my_md4_update(&ctx, input, curlx_uztoui(len)); - my_md4_final(output, &ctx); - return CURLE_OK; -} - -#endif /* USE_CURL_NTLM_CORE */ diff --git a/vendor/curl/lib/md5.c b/vendor/curl/lib/md5.c deleted file mode 100644 index 4dd0d7c27..000000000 --- a/vendor/curl/lib/md5.c +++ /dev/null @@ -1,607 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \ - !defined(CURL_DISABLE_DIGEST_AUTH) - -#include "curl_md5.h" -#include "curl_hmac.h" - -#ifdef USE_OPENSSL -#include -#endif - -#ifdef USE_WOLFSSL -#include -#endif - -#ifdef USE_MBEDTLS -#include -#if MBEDTLS_VERSION_NUMBER < 0x03020000 -#error "mbedTLS 3.2.0 or later required" -#endif -#include -#endif - -#ifdef USE_GNUTLS -#include - -typedef struct md5_ctx my_md5_ctx; - -static CURLcode my_md5_init(void *ctx) -{ - md5_init(ctx); - return CURLE_OK; -} - -static void my_md5_update(void *ctx, - const unsigned char *input, unsigned int len) -{ - md5_update(ctx, len, input); -} - -static void my_md5_final(unsigned char *digest, void *ctx) -{ - md5_digest(ctx, 16, digest); -} - -#elif defined(USE_OPENSSL) && \ - !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_DEPRECATED_3_0) -#include - -typedef MD5_CTX my_md5_ctx; - -static CURLcode my_md5_init(void *ctx) -{ - if(!MD5_Init(ctx)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static void my_md5_update(void *ctx, - const unsigned char *input, unsigned int len) -{ - (void)MD5_Update(ctx, input, len); -} - -static void my_md5_final(unsigned char *digest, void *ctx) -{ - (void)MD5_Final(digest, ctx); -} - -#elif defined(USE_WOLFSSL) && !defined(NO_MD5) -#include - -typedef wc_Md5 my_md5_ctx; - -static CURLcode my_md5_init(void *ctx) -{ - if(wc_InitMd5(ctx)) - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -} - -static void my_md5_update(void *ctx, - const unsigned char *input, unsigned int len) -{ - (void)wc_Md5Update(ctx, input, (word32)len); -} - -static void my_md5_final(unsigned char *digest, void *ctx) -{ - (void)wc_Md5Final(ctx, digest); -} - -#elif defined(USE_MBEDTLS) && \ - defined(PSA_WANT_ALG_MD5) && PSA_WANT_ALG_MD5 /* mbedTLS 4+ */ -#include - -typedef psa_hash_operation_t my_md5_ctx; - -static CURLcode my_md5_init(void *ctx) -{ - memset(ctx, 0, sizeof(my_md5_ctx)); - if(psa_hash_setup(ctx, PSA_ALG_MD5) != PSA_SUCCESS) - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -} - -static void my_md5_update(void *ctx, - const unsigned char *input, unsigned int len) -{ - (void)psa_hash_update(ctx, input, len); -} - -static void my_md5_final(unsigned char *digest, void *ctx) -{ - size_t actual_length; - (void)psa_hash_finish(ctx, digest, 16, &actual_length); -} - -#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \ - defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ - (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \ - (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ - (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000) && \ - defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ - (__IPHONE_OS_VERSION_MIN_REQUIRED < 130000)) -#include - -/* For Apple operating systems: CommonCrypto has the functions we need. - These functions are available on Tiger and later, as well as iOS 2.0 - and later. If you are building for an older cat, well, sorry. - - Declaring the functions as static like this seems to be a bit more - reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */ -# define my_md5_ctx CC_MD5_CTX - -static CURLcode my_md5_init(void *ctx) -{ - if(!CC_MD5_Init(ctx)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static void my_md5_update(void *ctx, - const unsigned char *input, unsigned int len) -{ - CC_MD5_Update(ctx, input, len); -} - -static void my_md5_final(unsigned char *digest, void *ctx) -{ - CC_MD5_Final(digest, ctx); -} - -#elif defined(USE_WIN32_CRYPTO) -#include - -struct md5_ctx { - HCRYPTPROV hCryptProv; - HCRYPTHASH hHash; -}; -typedef struct md5_ctx my_md5_ctx; - -static CURLcode my_md5_init(void *in) -{ - my_md5_ctx *ctx = (my_md5_ctx *)in; - if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return CURLE_OUT_OF_MEMORY; - - if(!CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash)) { - CryptReleaseContext(ctx->hCryptProv, 0); - ctx->hCryptProv = 0; - return CURLE_FAILED_INIT; - } - - return CURLE_OK; -} - -static void my_md5_update(void *in, - const unsigned char *input, unsigned int len) -{ - my_md5_ctx *ctx = in; - CryptHashData(ctx->hHash, (const BYTE *)input, len, 0); -} - -static void my_md5_final(unsigned char *digest, void *in) -{ - my_md5_ctx *ctx = (my_md5_ctx *)in; - unsigned long length = 0; - CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); - if(length == 16) - CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); - if(ctx->hHash) - CryptDestroyHash(ctx->hHash); - if(ctx->hCryptProv) - CryptReleaseContext(ctx->hCryptProv, 0); -} - -#else - -/* When no other crypto library is available we use this code segment */ - -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. In case - * this attempt to disclaim copyright and place the software in the public - * domain is deemed null and void, then the software is Copyright (c) 2001 - * Alexander Peslyak and it is hereby released to the general public under - * the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There is ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - */ - -struct md5_ctx { - uint32_t lo, hi; - uint32_t a, b, c, d; - unsigned char buffer[64]; - uint32_t block[16]; -}; -typedef struct md5_ctx my_md5_ctx; - -/* - * The basic MD5 functions. - * - * F and G are optimized compared to their RFC 1321 definitions for - * architectures that lack an AND-NOT instruction, like in Colin Plumb's - * implementation. - */ -#define MD5_F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define MD5_G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define MD5_H(x, y, z) (((x) ^ (y)) ^ (z)) -#define MD5_H2(x, y, z) ((x) ^ ((y) ^ (z))) -#define MD5_I(x, y, z) ((y) ^ ((x) | ~(z))) - -/* - * The MD5 transformation for all four rounds. - */ -#define MD5_STEP(f, a, b, c, d, x, t, s) \ - (a) += f(b, c, d) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); - -/* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned memory - * accesses is an optimization. Nothing will break if it does not work. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -#define MD5_SET(n) (*(const uint32_t *)(const void *)&ptr[(n) * 4]) -#define MD5_GET(n) MD5_SET(n) -#else -#define MD5_SET(n) (ctx->block[n] = \ - (uint32_t)ptr[(n) * 4] | \ - ((uint32_t)ptr[((n) * 4) + 1] << 8) | \ - ((uint32_t)ptr[((n) * 4) + 2] << 16) | \ - ((uint32_t)ptr[((n) * 4) + 3] << 24)) -#define MD5_GET(n) ctx->block[n] -#endif - -/* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. - */ -static const void *my_md5_body(my_md5_ctx *ctx, - const void *data, unsigned long size) -{ - const unsigned char *ptr; - uint32_t a, b, c, d; - - ptr = (const unsigned char *)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - uint32_t saved_a, saved_b, saved_c, saved_d; - - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - - /* Round 1 */ - MD5_STEP(MD5_F, a, b, c, d, MD5_SET(0), 0xd76aa478, 7) - MD5_STEP(MD5_F, d, a, b, c, MD5_SET(1), 0xe8c7b756, 12) - MD5_STEP(MD5_F, c, d, a, b, MD5_SET(2), 0x242070db, 17) - MD5_STEP(MD5_F, b, c, d, a, MD5_SET(3), 0xc1bdceee, 22) - MD5_STEP(MD5_F, a, b, c, d, MD5_SET(4), 0xf57c0faf, 7) - MD5_STEP(MD5_F, d, a, b, c, MD5_SET(5), 0x4787c62a, 12) - MD5_STEP(MD5_F, c, d, a, b, MD5_SET(6), 0xa8304613, 17) - MD5_STEP(MD5_F, b, c, d, a, MD5_SET(7), 0xfd469501, 22) - MD5_STEP(MD5_F, a, b, c, d, MD5_SET(8), 0x698098d8, 7) - MD5_STEP(MD5_F, d, a, b, c, MD5_SET(9), 0x8b44f7af, 12) - MD5_STEP(MD5_F, c, d, a, b, MD5_SET(10), 0xffff5bb1, 17) - MD5_STEP(MD5_F, b, c, d, a, MD5_SET(11), 0x895cd7be, 22) - MD5_STEP(MD5_F, a, b, c, d, MD5_SET(12), 0x6b901122, 7) - MD5_STEP(MD5_F, d, a, b, c, MD5_SET(13), 0xfd987193, 12) - MD5_STEP(MD5_F, c, d, a, b, MD5_SET(14), 0xa679438e, 17) - MD5_STEP(MD5_F, b, c, d, a, MD5_SET(15), 0x49b40821, 22) - - /* Round 2 */ - MD5_STEP(MD5_G, a, b, c, d, MD5_GET(1), 0xf61e2562, 5) - MD5_STEP(MD5_G, d, a, b, c, MD5_GET(6), 0xc040b340, 9) - MD5_STEP(MD5_G, c, d, a, b, MD5_GET(11), 0x265e5a51, 14) - MD5_STEP(MD5_G, b, c, d, a, MD5_GET(0), 0xe9b6c7aa, 20) - MD5_STEP(MD5_G, a, b, c, d, MD5_GET(5), 0xd62f105d, 5) - MD5_STEP(MD5_G, d, a, b, c, MD5_GET(10), 0x02441453, 9) - MD5_STEP(MD5_G, c, d, a, b, MD5_GET(15), 0xd8a1e681, 14) - MD5_STEP(MD5_G, b, c, d, a, MD5_GET(4), 0xe7d3fbc8, 20) - MD5_STEP(MD5_G, a, b, c, d, MD5_GET(9), 0x21e1cde6, 5) - MD5_STEP(MD5_G, d, a, b, c, MD5_GET(14), 0xc33707d6, 9) - MD5_STEP(MD5_G, c, d, a, b, MD5_GET(3), 0xf4d50d87, 14) - MD5_STEP(MD5_G, b, c, d, a, MD5_GET(8), 0x455a14ed, 20) - MD5_STEP(MD5_G, a, b, c, d, MD5_GET(13), 0xa9e3e905, 5) - MD5_STEP(MD5_G, d, a, b, c, MD5_GET(2), 0xfcefa3f8, 9) - MD5_STEP(MD5_G, c, d, a, b, MD5_GET(7), 0x676f02d9, 14) - MD5_STEP(MD5_G, b, c, d, a, MD5_GET(12), 0x8d2a4c8a, 20) - - /* Round 3 */ - MD5_STEP(MD5_H, a, b, c, d, MD5_GET(5), 0xfffa3942, 4) - MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(8), 0x8771f681, 11) - MD5_STEP(MD5_H, c, d, a, b, MD5_GET(11), 0x6d9d6122, 16) - MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(14), 0xfde5380c, 23) - MD5_STEP(MD5_H, a, b, c, d, MD5_GET(1), 0xa4beea44, 4) - MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(4), 0x4bdecfa9, 11) - MD5_STEP(MD5_H, c, d, a, b, MD5_GET(7), 0xf6bb4b60, 16) - MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(10), 0xbebfbc70, 23) - MD5_STEP(MD5_H, a, b, c, d, MD5_GET(13), 0x289b7ec6, 4) - MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(0), 0xeaa127fa, 11) - MD5_STEP(MD5_H, c, d, a, b, MD5_GET(3), 0xd4ef3085, 16) - MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(6), 0x04881d05, 23) - MD5_STEP(MD5_H, a, b, c, d, MD5_GET(9), 0xd9d4d039, 4) - MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(12), 0xe6db99e5, 11) - MD5_STEP(MD5_H, c, d, a, b, MD5_GET(15), 0x1fa27cf8, 16) - MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(2), 0xc4ac5665, 23) - - /* Round 4 */ - MD5_STEP(MD5_I, a, b, c, d, MD5_GET(0), 0xf4292244, 6) - MD5_STEP(MD5_I, d, a, b, c, MD5_GET(7), 0x432aff97, 10) - MD5_STEP(MD5_I, c, d, a, b, MD5_GET(14), 0xab9423a7, 15) - MD5_STEP(MD5_I, b, c, d, a, MD5_GET(5), 0xfc93a039, 21) - MD5_STEP(MD5_I, a, b, c, d, MD5_GET(12), 0x655b59c3, 6) - MD5_STEP(MD5_I, d, a, b, c, MD5_GET(3), 0x8f0ccc92, 10) - MD5_STEP(MD5_I, c, d, a, b, MD5_GET(10), 0xffeff47d, 15) - MD5_STEP(MD5_I, b, c, d, a, MD5_GET(1), 0x85845dd1, 21) - MD5_STEP(MD5_I, a, b, c, d, MD5_GET(8), 0x6fa87e4f, 6) - MD5_STEP(MD5_I, d, a, b, c, MD5_GET(15), 0xfe2ce6e0, 10) - MD5_STEP(MD5_I, c, d, a, b, MD5_GET(6), 0xa3014314, 15) - MD5_STEP(MD5_I, b, c, d, a, MD5_GET(13), 0x4e0811a1, 21) - MD5_STEP(MD5_I, a, b, c, d, MD5_GET(4), 0xf7537e82, 6) - MD5_STEP(MD5_I, d, a, b, c, MD5_GET(11), 0xbd3af235, 10) - MD5_STEP(MD5_I, c, d, a, b, MD5_GET(2), 0x2ad7d2bb, 15) - MD5_STEP(MD5_I, b, c, d, a, MD5_GET(9), 0xeb86d391, 21) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while(size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; -} - -static CURLcode my_md5_init(void *in) -{ - my_md5_ctx *ctx = (my_md5_ctx *)in; - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; - - return CURLE_OK; -} - -static void my_md5_update(void *in, - const unsigned char *input, unsigned int len) -{ - uint32_t saved_lo; - unsigned int used; - my_md5_ctx *ctx = (my_md5_ctx *)in; - - saved_lo = ctx->lo; - ctx->lo = (saved_lo + len) & 0x1fffffff; - if(ctx->lo < saved_lo) - ctx->hi++; - ctx->hi += (uint32_t)len >> 29; - - used = saved_lo & 0x3f; - - if(used) { - unsigned int available = 64 - used; - - if(len < available) { - memcpy(&ctx->buffer[used], input, len); - return; - } - - memcpy(&ctx->buffer[used], input, available); - input = (const unsigned char *)input + available; - len -= available; - my_md5_body(ctx, ctx->buffer, 64); - } - - if(len >= 64) { - input = my_md5_body(ctx, input, len & ~(unsigned long)0x3f); - len &= 0x3f; - } - - memcpy(ctx->buffer, input, len); -} - -static void my_md5_final(unsigned char *digest, void *in) -{ - unsigned int used, available; - my_md5_ctx *ctx = (my_md5_ctx *)in; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - available = 64 - used; - - if(available < 8) { - memset(&ctx->buffer[used], 0, available); - my_md5_body(ctx, ctx->buffer, 64); - used = 0; - available = 64; - } - - memset(&ctx->buffer[used], 0, available - 8); - - ctx->lo <<= 3; - ctx->buffer[56] = curlx_ultouc((ctx->lo) & 0xff); - ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8) & 0xff); - ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16) & 0xff); - ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24); - ctx->buffer[60] = curlx_ultouc((ctx->hi) & 0xff); - ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8) & 0xff); - ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16) & 0xff); - ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); - - my_md5_body(ctx, ctx->buffer, 64); - - digest[0] = curlx_ultouc((ctx->a) & 0xff); - digest[1] = curlx_ultouc((ctx->a >> 8) & 0xff); - digest[2] = curlx_ultouc((ctx->a >> 16) & 0xff); - digest[3] = curlx_ultouc(ctx->a >> 24); - digest[4] = curlx_ultouc((ctx->b) & 0xff); - digest[5] = curlx_ultouc((ctx->b >> 8) & 0xff); - digest[6] = curlx_ultouc((ctx->b >> 16) & 0xff); - digest[7] = curlx_ultouc(ctx->b >> 24); - digest[8] = curlx_ultouc((ctx->c) & 0xff); - digest[9] = curlx_ultouc((ctx->c >> 8) & 0xff); - digest[10] = curlx_ultouc((ctx->c >> 16) & 0xff); - digest[11] = curlx_ultouc(ctx->c >> 24); - digest[12] = curlx_ultouc((ctx->d) & 0xff); - digest[13] = curlx_ultouc((ctx->d >> 8) & 0xff); - digest[14] = curlx_ultouc((ctx->d >> 16) & 0xff); - digest[15] = curlx_ultouc(ctx->d >> 24); - - memset(ctx, 0, sizeof(*ctx)); -} - -#endif /* CRYPTO LIBS */ - -const struct HMAC_params Curl_HMAC_MD5 = { - my_md5_init, /* Hash initialization function. */ - my_md5_update, /* Hash update function. */ - my_md5_final, /* Hash computation end function. */ - sizeof(my_md5_ctx), /* Size of hash context structure. */ - 64, /* Maximum key length. */ - 16 /* Result size. */ -}; - -const struct MD5_params Curl_DIGEST_MD5 = { - my_md5_init, /* Digest initialization function */ - my_md5_update, /* Digest update function */ - my_md5_final, /* Digest computation end function */ - sizeof(my_md5_ctx), /* Size of digest context struct */ - 16 /* Result size */ -}; - -/* - * @unittest: 1601 - * Returns CURLE_OK on success. - */ -CURLcode Curl_md5it(unsigned char *output, - const unsigned char *input, size_t len) -{ - CURLcode result; - my_md5_ctx ctx; - - result = my_md5_init(&ctx); - if(!result) { - do { - unsigned int ilen = (unsigned int)CURLMIN(len, UINT_MAX); - my_md5_update(&ctx, input, ilen); - input += ilen; - len -= ilen; - } while(len); - my_md5_final(output, &ctx); - } - return result; -} - -struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params) -{ - struct MD5_context *ctxt; - - /* Create MD5 context */ - ctxt = curlx_malloc(sizeof(*ctxt)); - - if(!ctxt) - return ctxt; - - ctxt->md5_hashctx = curlx_malloc(md5params->md5_ctxtsize); - - if(!ctxt->md5_hashctx) { - curlx_free(ctxt); - return NULL; - } - - ctxt->md5_hash = md5params; - - if((*md5params->md5_init_func)(ctxt->md5_hashctx)) { - curlx_free(ctxt->md5_hashctx); - curlx_free(ctxt); - return NULL; - } - - return ctxt; -} - -CURLcode Curl_MD5_update(struct MD5_context *context, - const unsigned char *input, unsigned int len) -{ - (*context->md5_hash->md5_update_func)(context->md5_hashctx, input, len); - - return CURLE_OK; -} - -CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result) -{ - (*context->md5_hash->md5_final_func)(result, context->md5_hashctx); - - curlx_free(context->md5_hashctx); - curlx_free(context); - - return CURLE_OK; -} - -#endif /* Using NTLM (without SSPI) || Digest */ diff --git a/vendor/curl/lib/memdebug.c b/vendor/curl/lib/memdebug.c deleted file mode 100644 index 6eda7a823..000000000 --- a/vendor/curl/lib/memdebug.c +++ /dev/null @@ -1,579 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef CURL_MEMDEBUG - -#include /* for offsetof() */ - -#include "urldata.h" -#include "curl_threads.h" -#include "curlx/fopen.h" /* for CURLX_FOPEN_LOW(), CURLX_FREOPEN_LOW() */ - -#ifdef USE_BACKTRACE -#include -#endif - -struct memdebug { - size_t size; - union { - curl_off_t o; - double d; - void *p; - } mem[1]; - /* I am hoping this is the thing with the strictest alignment - * requirements. That also means we waste some space :-( */ -}; - -/* - * Note that these debug functions are simple and they are meant to remain so. - * For advanced analysis, record a log file and write perl scripts to analyze - * them! - * - * Do not use these with multi-threaded test programs! - */ - -FILE *curl_dbg_logfile = NULL; -static bool registered_cleanup = FALSE; /* atexit registered cleanup */ -static bool memlimit = FALSE; /* enable memory limit */ -static long memsize = 0; /* set number of mallocs allowed */ -#ifdef USE_BACKTRACE -static struct backtrace_state *btstate; -#endif - -static char membuf[10000]; -static size_t memwidx = 0; /* write index */ - -#ifdef USE_MUTEX -static bool dbg_mutex_init = 0; -static curl_mutex_t dbg_mutex; -#endif - -static bool curl_dbg_lock(void) -{ -#ifdef USE_MUTEX - if(dbg_mutex_init) { - Curl_mutex_acquire(&dbg_mutex); - return TRUE; - } -#endif - return FALSE; -} - -static void curl_dbg_unlock(bool was_locked) -{ -#ifdef USE_MUTEX - if(was_locked) - Curl_mutex_release(&dbg_mutex); -#else - (void)was_locked; -#endif -} - -static void curl_dbg_log_locked(const char *format, ...) CURL_PRINTF(1, 2); - -/* LeakSantizier (LSAN) calls _exit() instead of exit() when a leak is detected - on exit so the logfile must be closed explicitly or data could be lost. - Though _exit() does not call atexit handlers such as this, LSAN's call to - _exit() comes after the atexit handlers are called. curl/curl#6620 */ -static void curl_dbg_cleanup(void) -{ - bool locked = curl_dbg_lock(); - if(curl_dbg_logfile && - curl_dbg_logfile != stderr && - curl_dbg_logfile != stdout) { - if(memwidx) - fwrite(membuf, 1, memwidx, curl_dbg_logfile); - /* !checksrc! disable BANNEDFUNC 1 */ - fclose(curl_dbg_logfile); - } - curl_dbg_logfile = NULL; - curl_dbg_unlock(locked); -#ifdef USE_MUTEX - if(dbg_mutex_init) { - Curl_mutex_destroy(&dbg_mutex); - dbg_mutex_init = FALSE; - } -#endif -} - -#ifdef USE_BACKTRACE -static void error_bt_callback(void *data, const char *message, - int error_number) -{ - (void)data; - if(error_number == -1) - curl_dbg_log("compile with -g\n\n"); - else - curl_dbg_log("Backtrace error %d: %s\n", error_number, message); -} - -static int full_callback(void *data, uintptr_t pc, const char *pathname, - int line_number, const char *function) -{ - (void)data; - (void)pc; - if(pathname || function || line_number) - curl_dbg_log("BT %s:%d -- %s\n", pathname, line_number, function); - return 0; -} - -static void dump_bt(void) -{ - backtrace_full(btstate, 0, full_callback, error_bt_callback, NULL); -} -#else -#define dump_bt() /* nothing to do */ -#endif - -/* this sets the log filename */ -void curl_dbg_memdebug(const char *logname) -{ - if(!curl_dbg_logfile) { - if(logname && *logname) - curl_dbg_logfile = CURLX_FOPEN_LOW(logname, FOPEN_WRITETEXT); -#ifdef MEMDEBUG_LOG_SYNC - /* Flush the log file after every line so the log is not lost in a crash */ - if(curl_dbg_logfile) - setbuf(curl_dbg_logfile, (char *)NULL); -#endif - } -#ifdef USE_MUTEX - if(!dbg_mutex_init) { - dbg_mutex_init = TRUE; - Curl_mutex_init(&dbg_mutex); - } -#endif -#ifdef USE_BACKTRACE - btstate = backtrace_create_state(NULL, 0, error_bt_callback, NULL); -#endif - if(!registered_cleanup) - registered_cleanup = !atexit(curl_dbg_cleanup); -} - -/* This function sets the number of malloc() calls that should return - successfully! */ -void curl_dbg_memlimit(long limit) -{ - if(!memlimit) { - memlimit = TRUE; - memsize = limit; - } -} - -/* returns TRUE if this is not allowed! */ -static bool countcheck(const char *func, int line, const char *source) -{ - /* if source is NULL, then the call is made internally and this check - should not be made */ - if(memlimit && source) { - if(!memsize) { - /* log to file */ - curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", source, line, func); - /* log to stderr also */ - curl_mfprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", - source, line, func); - dump_bt(); - fflush(curl_dbg_logfile); /* because it might crash now */ - /* !checksrc! disable ERRNOVAR 1 */ - errno = ENOMEM; - return TRUE; /* RETURN ERROR! */ - } - else - memsize--; /* countdown */ - } - - return FALSE; /* allow this */ -} - -ALLOC_FUNC -void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) -{ - struct memdebug *mem; - size_t size; - - DEBUGASSERT(wantedsize != 0); - - if(countcheck("malloc", line, source)) - return NULL; - - /* alloc at least 64 bytes */ - size = sizeof(struct memdebug) + wantedsize; - - mem = Curl_cmalloc(size); - if(mem) { - mem->size = wantedsize; - } - - if(source) - curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n", - source, line, wantedsize, - mem ? (void *)mem->mem : (void *)0); - - return mem ? mem->mem : NULL; -} - -ALLOC_FUNC -void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, - int line, const char *source) -{ - struct memdebug *mem; - size_t size, user_size; - - DEBUGASSERT(wanted_elements != 0); - DEBUGASSERT(wanted_size != 0); - - if(countcheck("calloc", line, source)) - return NULL; - - /* alloc at least 64 bytes */ - user_size = wanted_size * wanted_elements; - size = sizeof(struct memdebug) + user_size; - - mem = Curl_ccalloc(1, size); - if(mem) - mem->size = user_size; - - if(source) - curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n", - source, line, wanted_elements, wanted_size, - mem ? (void *)mem->mem : (void *)0); - - return mem ? mem->mem : NULL; -} - -ALLOC_FUNC -char *curl_dbg_strdup(const char *str, int line, const char *source) -{ - char *mem; - size_t len; - - DEBUGASSERT(str != NULL); - - if(countcheck("strdup", line, source)) - return NULL; - - len = strlen(str) + 1; - - mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */ - if(mem) - memcpy(mem, str, len); - - if(source) - curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n", - source, line, (const void *)str, len, (const void *)mem); - - return mem; -} - -#if defined(_WIN32) && defined(UNICODE) -ALLOC_FUNC -wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) -{ - wchar_t *mem; - size_t wsiz, bsiz; - - DEBUGASSERT(str != NULL); - - if(countcheck("wcsdup", line, source)) - return NULL; - - wsiz = wcslen(str) + 1; - bsiz = wsiz * sizeof(wchar_t); - - mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */ - if(mem) - memcpy(mem, str, bsiz); - - if(source) - curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n", - source, line, (const void *)str, bsiz, (void *)mem); - - return mem; -} -#endif - -/* We provide a realloc() that accepts a NULL as pointer, which then - performs a malloc(). In order to work with ares. */ -void *curl_dbg_realloc(void *ptr, size_t wantedsize, - int line, const char *source) -{ - struct memdebug *mem = NULL; - bool was_locked; - - size_t size = sizeof(struct memdebug) + wantedsize; - - DEBUGASSERT(wantedsize != 0); - - if(countcheck("realloc", line, source)) - return NULL; - - /* need to realloc under lock, as we get out-of-order log - * entries otherwise, since another thread might alloc the - * memory released by realloc() before otherwise would log it. */ - was_locked = curl_dbg_lock(); -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:1684) - /* 1684: conversion from pointer to same-sized integral type */ -#endif - - if(ptr) - mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif - - mem = Curl_crealloc(mem, size); - if(source) - curl_dbg_log_locked("MEM %s:%d realloc(%p, %zu) = %p\n", - source, line, (void *)ptr, wantedsize, - mem ? (void *)mem->mem : (void *)0); - - curl_dbg_unlock(was_locked); - if(mem) { - mem->size = wantedsize; - return mem->mem; - } - - return NULL; -} - -void curl_dbg_free(void *ptr, int line, const char *source) -{ - if(ptr) { - struct memdebug *mem; - - if(source) - curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr); - -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:1684) - /* 1684: conversion from pointer to same-sized integral type */ -#endif - - mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif - - /* free for real */ - Curl_cfree(mem); - } -} - -curl_socket_t curl_dbg_socket(int domain, int type, int protocol, - int line, const char *source) -{ - curl_socket_t sockfd; - - if(countcheck("socket", line, source)) - return CURL_SOCKET_BAD; - - /* !checksrc! disable BANNEDFUNC 1 */ - sockfd = socket(domain, type, protocol); - - if(source && (sockfd != CURL_SOCKET_BAD)) - curl_dbg_log("FD %s:%d socket() = %" FMT_SOCKET_T "\n", - source, line, sockfd); - - return sockfd; -} - -#ifdef HAVE_SOCKETPAIR -int curl_dbg_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source) -{ - /* !checksrc! disable BANNEDFUNC 1 */ - int res = socketpair(domain, type, protocol, socket_vector); - - if(source && (res == 0)) - curl_dbg_log("FD %s:%d socketpair() = " - "%" FMT_SOCKET_T " %" FMT_SOCKET_T "\n", - source, line, socket_vector[0], socket_vector[1]); - - return res; -} -#endif - -curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, - int line, const char *source) -{ - struct sockaddr *addr = (struct sockaddr *)saddr; - curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen; - - /* !checksrc! disable BANNEDFUNC 1 */ - curl_socket_t sockfd = accept(s, addr, addrlen); - - if(source && (sockfd != CURL_SOCKET_BAD)) - curl_dbg_log("FD %s:%d accept() = %" FMT_SOCKET_T "\n", - source, line, sockfd); - - return sockfd; -} - -#ifdef HAVE_ACCEPT4 -curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr, void *saddrlen, - int flags, - int line, const char *source) -{ - struct sockaddr *addr = (struct sockaddr *)saddr; - curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen; - - /* !checksrc! disable BANNEDFUNC 1 */ - curl_socket_t sockfd = accept4(s, addr, addrlen, flags); - - if(source && (sockfd != CURL_SOCKET_BAD)) - curl_dbg_log("FD %s:%d accept() = %" FMT_SOCKET_T "\n", - source, line, sockfd); - - return sockfd; -} -#endif - -/* separate function to allow libcurl to mark a "faked" close */ -void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) -{ - if(source) - curl_dbg_log("FD %s:%d sclose(%" FMT_SOCKET_T ")\n", - source, line, sockfd); -} - -/* this is our own defined way to close sockets on *ALL* platforms */ -int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) -{ - curl_dbg_mark_sclose(sockfd, line, source); - return CURL_SCLOSE(sockfd); -} - -ALLOC_FUNC -FILE *curl_dbg_fopen(const char *file, const char *mode, - int line, const char *source) -{ - FILE *res = CURLX_FOPEN_LOW(file, mode); - if(source) - curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", - source, line, file, mode, (void *)res); - - return res; -} - -ALLOC_FUNC -FILE *curl_dbg_freopen(const char *file, const char *mode, FILE *fh, - int line, const char *source) -{ - FILE *res = CURLX_FREOPEN_LOW(file, mode, fh); - if(source) - curl_dbg_log("FILE %s:%d freopen(\"%s\",\"%s\",%p) = %p\n", - source, line, file, mode, (void *)fh, (void *)res); - - return res; -} - -ALLOC_FUNC -FILE *curl_dbg_fdopen(int filedes, const char *mode, - int line, const char *source) -{ - FILE *res = CURLX_FDOPEN_LOW(filedes, mode); - if(source) - curl_dbg_log("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n", - source, line, filedes, mode, (void *)res); - return res; -} - -int curl_dbg_fclose(FILE *file, int line, const char *source) -{ - int res; - - DEBUGASSERT(file != NULL); - - if(source) - curl_dbg_log("FILE %s:%d fclose(%p)\n", source, line, (void *)file); - - /* !checksrc! disable BANNEDFUNC 1 */ - res = fclose(file); - - return res; -} - -static void curl_dbg_vlog(const char * const fmt, - va_list ap) CURL_PRINTF(1, 0); - -static void curl_dbg_vlog(const char * const fmt, va_list ap) -{ - char buf[1024]; - size_t nchars = curl_mvsnprintf(buf, sizeof(buf), fmt, ap); - - if(nchars > (int)sizeof(buf) - 1) - nchars = (int)sizeof(buf) - 1; - - if(nchars > 0) { - if(sizeof(membuf) - nchars < memwidx) { - /* flush */ - fwrite(membuf, 1, memwidx, curl_dbg_logfile); - fflush(curl_dbg_logfile); - memwidx = 0; - } - if(memwidx) { - /* the previous line ends with a newline */ - DEBUGASSERT(membuf[memwidx - 1] == '\n'); - } - memcpy(&membuf[memwidx], buf, nchars); - memwidx += nchars; - } -} - -static void curl_dbg_log_locked(const char *format, ...) -{ - va_list ap; - - if(!curl_dbg_logfile) - return; - - va_start(ap, format); - curl_dbg_vlog(format, ap); - va_end(ap); -} - -/* this does the writing to the memory tracking log file */ -void curl_dbg_log(const char *format, ...) -{ - bool was_locked; - va_list ap; - - if(!curl_dbg_logfile) - return; - - was_locked = curl_dbg_lock(); - va_start(ap, format); - curl_dbg_vlog(format, ap); - va_end(ap); - curl_dbg_unlock(was_locked); -} - -#endif /* CURL_MEMDEBUG */ diff --git a/vendor/curl/lib/mime.c b/vendor/curl/lib/mime.c deleted file mode 100644 index b7e51aae4..000000000 --- a/vendor/curl/lib/mime.c +++ /dev/null @@ -1,2250 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_easy; - -#include "mime.h" -#include "urldata.h" -#include "sendf.h" -#include "curl_trc.h" -#include "transfer.h" -#include "curlx/strdup.h" -#include "curlx/basename.h" -#include "curlx/strcopy.h" -#include "curlx/fopen.h" -#include "curlx/base64.h" - -#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ - !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_IMAP)) - -#include "rand.h" -#include "slist.h" -#include "curlx/dynbuf.h" - -#define MAX_MIME_LEVELS 40 /* avoid deep nesting */ - -#define READ_ERROR ((size_t)-1) -#define STOP_FILLING ((size_t)-2) - -static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, - void *instream, bool *hasread, - size_t call_depth); -static curl_off_t mime_size(curl_mimepart *part); - -/* Quoted-printable character class table. - * - * We cannot rely on ctype functions since quoted-printable input data - * is assumed to be ASCII-compatible, even on non-ASCII platforms. */ -#define QP_OK 1 /* Can be represented by itself. */ -#define QP_SP 2 /* Space or tab. */ -#define QP_CR 3 /* Carriage return. */ -#define QP_LF 4 /* Line-feed. */ -static const unsigned char qp_class[] = { - 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 07 */ - 0, QP_SP, QP_LF, 0, 0, QP_CR, 0, 0, /* 08 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 17 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 18 - 1F */ - QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 20 - 27 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 28 - 2F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 30 - 37 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0 , QP_OK, QP_OK, /* 38 - 3F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 40 - 47 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 48 - 4F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 50 - 57 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 58 - 5F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 60 - 67 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 68 - 6F */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 70 - 77 */ - QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0, /* 78 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */ -}; - -/* Binary --> hexadecimal ASCII table. */ -static const char aschex[] = - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x46"; - -#ifndef __VMS -#define filesize(name, stat_data) stat_data.st_size -#define fopen_read curlx_fopen - -#else - -#include -/* - * get_vms_file_size does what it takes to get the real size of the file - * - * For fixed files, find out the size of the EOF block and adjust. - * - * For all others, have to read the entire file in, discarding the contents. - * Most posted text files will be small, and binary files like zlib archives - * and CD/DVD images should be either a STREAM_LF format or a fixed format. - * - */ -curl_off_t VmsRealFileSize(const char *name, const curlx_struct_stat *stat_buf) -{ - char buffer[8192]; - curl_off_t count; - int ret_stat; - FILE *file; - - file = curlx_fopen(name, FOPEN_READTEXT); /* VMS */ - if(!file) - return 0; - - count = 0; - ret_stat = 1; - while(ret_stat > 0) { - ret_stat = fread(buffer, 1, sizeof(buffer), file); - if(ret_stat) - count += ret_stat; - } - curlx_fclose(file); - - return count; -} - -/* - * - * VmsSpecialSize checks to see if the stat st_size can be trusted and - * if not to call a routine to get the correct size. - * - */ -static curl_off_t VmsSpecialSize(const char *name, - const curlx_struct_stat *stat_buf) -{ - switch(stat_buf->st_fab_rfm) { - case FAB$C_VAR: - case FAB$C_VFC: - return VmsRealFileSize(name, stat_buf); - break; - default: - return stat_buf->st_size; - } -} - -#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data) - -/* - * vmsfopenread - * - * For upload to work as expected on VMS, different optional - * parameters must be added to the fopen command based on - * record format of the file. - * - */ -static FILE *vmsfopenread(const char *file, const char *mode) -{ - curlx_struct_stat statbuf; - int res = curlx_stat(file, &statbuf); - - if(res != -1) { - switch(statbuf.st_fab_rfm) { - case FAB$C_VAR: - case FAB$C_VFC: - case FAB$C_STMCR: - return curlx_fopen(file, FOPEN_READTEXT); /* VMS */ - break; - default: - return curlx_fopen(file, FOPEN_READTEXT, "rfm=stmlf", "ctx=stm"); - } - } - return NULL; -} - -#define fopen_read vmsfopenread -#endif /* !__VMS */ - -/* Set readback state. */ -static void mimesetstate(struct mime_state *state, - enum mimestate tok, void *ptr) -{ - state->state = tok; - state->ptr = ptr; - state->offset = 0; -} - -/* Escape header string into allocated memory. */ -static char *escape_string(struct Curl_easy *data, - const char *src, enum mimestrategy strategy) -{ - CURLcode result; - struct dynbuf db; - const char * const *table; - const char * const *p; - /* replace first character by rest of string. */ - static const char * const mimetable[] = { - "\\\\\\", - "\"\\\"", - NULL - }; - /* WHATWG HTML living standard 4.10.21.8 2 specifies: - For field names and filenames for file fields, the result of the - encoding in the previous bullet point must be escaped by replacing - any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D` - and 0x22 (") with `%22`. - The user agent must not perform any other escapes. */ - static const char * const formtable[] = { - "\"%22", - "\r%0D", - "\n%0A", - NULL - }; - - table = formtable; - /* data can be NULL when this function is called indirectly from - curl_formget(). */ - if(strategy == MIMESTRATEGY_MAIL || (data && (data->set.mime_formescape))) - table = mimetable; - - curlx_dyn_init(&db, CURL_MAX_INPUT_LENGTH); - - for(result = curlx_dyn_addn(&db, STRCONST("")); !result && *src; src++) { - for(p = table; *p && **p != *src; p++) - ; - - if(*p) - result = curlx_dyn_add(&db, *p + 1); - else - result = curlx_dyn_addn(&db, src, 1); - } - - return curlx_dyn_ptr(&db); -} - -/* Check if header matches. */ -static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len) -{ - char *value = NULL; - - if(curl_strnequal(hdr->data, lbl, len) && hdr->data[len] == ':') - for(value = hdr->data + len + 1; *value == ' '; value++) - ; - return value; -} - -/* Get a header from an slist. */ -static char *search_header(struct curl_slist *hdrlist, - const char *hdr, size_t len) -{ - char *value = NULL; - - for(; !value && hdrlist; hdrlist = hdrlist->next) - value = match_header(hdrlist, hdr, len); - - return value; -} - -static char *strippath(const char *fullfile) -{ - char *filename; - char *base; - filename = curlx_strdup(fullfile); /* duplicate since basename() may ruin - the buffer it works on */ - if(!filename) - return NULL; - base = curlx_strdup(curlx_basename(filename)); - - curlx_free(filename); /* free temporary buffer */ - - return base; /* returns an allocated string or NULL ! */ -} - -/* Initialize data encoder state. */ -static void cleanup_encoder_state(struct mime_encoder_state *p) -{ - p->pos = 0; - p->bufbeg = 0; - p->bufend = 0; -} - -/* Dummy encoder. This is used for 8-bit and binary content encodings. */ -static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, - struct curl_mimepart *part) -{ - struct mime_encoder_state *st = &part->encstate; - size_t insize = st->bufend - st->bufbeg; - - (void)ateof; - - if(!size) - return STOP_FILLING; - - if(size > insize) - size = insize; - - if(size) - memcpy(buffer, st->buf + st->bufbeg, size); - - st->bufbeg += size; - return size; -} - -static curl_off_t encoder_nop_size(curl_mimepart *part) -{ - return part->datasize; -} - -/* 7-bit encoder: the encoder is a data validity check. */ -static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, - curl_mimepart *part) -{ - struct mime_encoder_state *st = &part->encstate; - size_t cursize = st->bufend - st->bufbeg; - - (void)ateof; - - if(!size) - return STOP_FILLING; - - if(size > cursize) - size = cursize; - - for(cursize = 0; cursize < size; cursize++) { - *buffer = st->buf[st->bufbeg]; - if(*buffer++ & 0x80) - return cursize ? cursize : READ_ERROR; - st->bufbeg++; - } - - return cursize; -} - -/* Base64 content encoder. */ -static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, - curl_mimepart *part) -{ - struct mime_encoder_state *st = &part->encstate; - size_t cursize = 0; - int i; - char *ptr = buffer; - - while(st->bufbeg < st->bufend) { - /* Line full ? */ - if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) { - /* Yes, we need 2 characters for CRLF. */ - if(size < 2) { - if(!cursize) - return STOP_FILLING; - break; - } - *ptr++ = '\r'; - *ptr++ = '\n'; - st->pos = 0; - cursize += 2; - size -= 2; - } - - /* Be sure there is enough space and input data for a base64 group. */ - if(size < 4) { - if(!cursize) - return STOP_FILLING; - break; - } - if(st->bufend - st->bufbeg < 3) - break; - - /* Encode three bytes as four characters. */ - i = st->buf[st->bufbeg++] & 0xFF; - i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); - i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); - *ptr++ = curlx_base64encdec[(i >> 18) & 0x3F]; - *ptr++ = curlx_base64encdec[(i >> 12) & 0x3F]; - *ptr++ = curlx_base64encdec[(i >> 6) & 0x3F]; - *ptr++ = curlx_base64encdec[i & 0x3F]; - cursize += 4; - st->pos += 4; - size -= 4; - } - - /* If at eof, we have to flush the buffered data. */ - if(ateof) { - if(size < 4) { - if(!cursize) - return STOP_FILLING; - } - else { - /* Buffered data size can only be 0, 1 or 2. */ - ptr[2] = ptr[3] = '='; - i = 0; - - /* If there is buffered data */ - if(st->bufend != st->bufbeg) { - - if(st->bufend - st->bufbeg == 2) - i = (st->buf[st->bufbeg + 1] & 0xFF) << 8; - - i |= (st->buf[st->bufbeg] & 0xFF) << 16; - ptr[0] = curlx_base64encdec[(i >> 18) & 0x3F]; - ptr[1] = curlx_base64encdec[(i >> 12) & 0x3F]; - if(++st->bufbeg != st->bufend) { - ptr[2] = curlx_base64encdec[(i >> 6) & 0x3F]; - st->bufbeg++; - } - cursize += 4; - st->pos += 4; - } - } - } - - return cursize; -} - -static curl_off_t encoder_base64_size(curl_mimepart *part) -{ - curl_off_t size = part->datasize; - - if(size <= 0) - return size; /* Unknown size or no data. */ - - /* Compute base64 character count. */ - size = 4 * (1 + ((size - 1) / 3)); - - /* Effective character count must include CRLFs. */ - return size + (2 * ((size - 1) / MAX_ENCODED_LINE_LENGTH)); -} - -/* Quoted-printable lookahead. - * - * Check if a CRLF or end of data is in input buffer at current position + n. - * Return -1 if more data needed, 1 if CRLF or end of data, else 0. - */ -static int qp_lookahead_eol(struct mime_encoder_state *st, int ateof, size_t n) -{ - n += st->bufbeg; - if(n >= st->bufend && ateof) - return 1; - if(n + 2 > st->bufend) - return ateof ? 0 : -1; - if(qp_class[st->buf[n] & 0xFF] == QP_CR && - qp_class[st->buf[n + 1] & 0xFF] == QP_LF) - return 1; - return 0; -} - -/* Quoted-printable encoder. */ -static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, - curl_mimepart *part) -{ - struct mime_encoder_state *st = &part->encstate; - char *ptr = buffer; - size_t cursize = 0; - int softlinebreak; - char buf[4]; - - /* On all platforms, input is supposed to be ASCII compatible: for this - reason, we use hexadecimal ASCII codes in this function rather than - character constants that can be interpreted as non-ASCII on some - platforms. Preserve ASCII encoding on output too. */ - while(st->bufbeg < st->bufend) { - size_t len = 1; - size_t consumed = 1; - int i = (unsigned char)st->buf[st->bufbeg]; - buf[0] = (char)i; - buf[1] = aschex[(i >> 4) & 0xF]; - buf[2] = aschex[i & 0xF]; - - switch(qp_class[st->buf[st->bufbeg] & 0xFF]) { - case QP_OK: /* Not a special character. */ - break; - case QP_SP: /* Space or tab. */ - /* Spacing must be escaped if followed by CRLF. */ - switch(qp_lookahead_eol(st, ateof, 1)) { - case -1: /* More input data needed. */ - return cursize; - case 0: /* No encoding needed. */ - break; - default: /* CRLF after space or tab. */ - buf[0] = '\x3D'; /* '=' */ - len = 3; - break; - } - break; - case QP_CR: /* Carriage return. */ - /* If followed by a line-feed, output the CRLF pair. - Else escape it. */ - switch(qp_lookahead_eol(st, ateof, 0)) { - case -1: /* Need more data. */ - return cursize; - case 1: /* CRLF found. */ - buf[len++] = '\x0A'; /* Append '\n'. */ - consumed = 2; - break; - default: /* Not followed by LF: escape. */ - buf[0] = '\x3D'; /* '=' */ - len = 3; - break; - } - break; - default: /* Character must be escaped. */ - buf[0] = '\x3D'; /* '=' */ - len = 3; - break; - } - - /* Be sure the encoded character fits within maximum line length. */ - if(buf[len - 1] != '\x0A') { /* '\n' */ - softlinebreak = st->pos + len > MAX_ENCODED_LINE_LENGTH; - if(!softlinebreak && st->pos + len == MAX_ENCODED_LINE_LENGTH) { - /* We may use the current line only if end of data or followed by - a CRLF. */ - switch(qp_lookahead_eol(st, ateof, consumed)) { - case -1: /* Need more data. */ - return cursize; - case 0: /* Not followed by a CRLF. */ - softlinebreak = 1; - break; - } - } - if(softlinebreak) { - curlx_strcopy(buf, sizeof(buf), STRCONST("\x3D\x0D\x0A")); /* =\r\n */ - len = 3; - consumed = 0; - } - } - - /* If the output buffer would overflow, do not store. */ - if(len > size) { - if(!cursize) - return STOP_FILLING; - break; - } - - /* Append to output buffer. */ - memcpy(ptr, buf, len); - cursize += len; - ptr += len; - size -= len; - st->pos += len; - if(buf[len - 1] == '\x0A') /* '\n' */ - st->pos = 0; - st->bufbeg += consumed; - } - - return cursize; -} - -static curl_off_t encoder_qp_size(curl_mimepart *part) -{ - /* Determining the size can only be done by reading the data: unless the - data size is 0, we return it as unknown (-1). */ - return part->datasize ? -1 : 0; -} - -/* In-memory data callbacks. */ -/* Argument is a pointer to the mime part. */ -static size_t mime_mem_read(char *buffer, size_t size, size_t nitems, - void *instream) -{ - curl_mimepart *part = (curl_mimepart *)instream; - size_t sz = curlx_sotouz(part->datasize - part->state.offset); - (void)size; /* Always 1 */ - - if(!nitems) - return STOP_FILLING; - - if(sz > nitems) - sz = nitems; - - if(sz) - memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz); - - return sz; -} - -static int mime_mem_seek(void *instream, curl_off_t offset, int whence) -{ - curl_mimepart *part = (curl_mimepart *)instream; - - switch(whence) { - case SEEK_CUR: - offset += part->state.offset; - break; - case SEEK_END: - offset += part->datasize; - break; - } - - if(offset < 0 || offset > part->datasize) - return CURL_SEEKFUNC_FAIL; - - part->state.offset = offset; - return CURL_SEEKFUNC_OK; -} - -static void mime_mem_free(void *ptr) -{ - curlx_safefree(((curl_mimepart *)ptr)->data); -} - -/* Named file callbacks. */ -/* Argument is a pointer to the mime part. */ -static bool mime_open_file(curl_mimepart *part) -{ - /* Open a MIMEKIND_FILE part. */ - - if(part->fp) - return FALSE; - part->fp = fopen_read(part->data, "rb"); - return part->fp ? FALSE : TRUE; -} - -static size_t mime_file_read(char *buffer, size_t size, size_t nitems, - void *instream) -{ - curl_mimepart *part = (curl_mimepart *)instream; - - if(!nitems) - return STOP_FILLING; - - if(mime_open_file(part)) - return READ_ERROR; - - return fread(buffer, size, nitems, part->fp); -} - -static int mime_file_seek(void *instream, curl_off_t offset, int whence) -{ - curl_mimepart *part = (curl_mimepart *)instream; - - if(whence == SEEK_SET && !offset && !part->fp) - return CURL_SEEKFUNC_OK; /* Not open: implicitly already at BOF. */ - - if(mime_open_file(part)) - return CURL_SEEKFUNC_FAIL; - - return curlx_fseek(part->fp, offset, whence) ? - CURL_SEEKFUNC_CANTSEEK : CURL_SEEKFUNC_OK; -} - -static void mime_file_free(void *ptr) -{ - curl_mimepart *part = (curl_mimepart *)ptr; - - if(part->fp) { - curlx_fclose(part->fp); - part->fp = NULL; - } - curlx_safefree(part->data); -} - -/* Subparts callbacks. */ -/* Argument is a pointer to the mime structure. */ - -/* Readback a byte string segment. */ -static size_t readback_bytes(struct mime_state *state, - char *buffer, size_t bufsize, - const char *bytes, size_t numbytes, - const char *trail, size_t traillen) -{ - size_t sz; - size_t offset = curlx_sotouz(state->offset); - - if(numbytes > offset) { - sz = numbytes - offset; - bytes += offset; - } - else { - sz = offset - numbytes; - if(sz >= traillen) - return 0; - bytes = trail + sz; - sz = traillen - sz; - } - - if(sz > bufsize) - sz = bufsize; - - memcpy(buffer, bytes, sz); - state->offset += sz; - return sz; -} - -/* Read a non-encoded part content. */ - -static size_t read_part_content(curl_mimepart *part, char *buffer, - size_t bufsize, bool *hasread, - size_t call_depth) -{ - size_t sz = 0; - - if(++call_depth > MAX_MIME_LEVELS) - return READ_ERROR; - - switch(part->lastreadstatus) { - case 0: - case CURL_READFUNC_ABORT: - case CURL_READFUNC_PAUSE: - case READ_ERROR: - return part->lastreadstatus; - default: - break; - } - - /* If we can determine we are at end of part data, spare a read. */ - if(part->datasize != (curl_off_t)-1 && - part->state.offset >= part->datasize) { - /* sz is already zero. */ - } - else { - switch(part->kind) { - case MIMEKIND_MULTIPART: - /* - * Cannot be processed as other kinds since read function requires - * an additional parameter and is highly recursive. - */ - sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread, - call_depth); - break; - case MIMEKIND_FILE: - if(part->fp && feof(part->fp)) - break; /* At EOF. */ - FALLTHROUGH(); - default: - if(part->readfunc) { - if(!(part->flags & MIME_FAST_READ)) { - if(*hasread) - return STOP_FILLING; - *hasread = TRUE; - } - sz = part->readfunc(buffer, 1, bufsize, part->arg); - } - break; - } - } - - switch(sz) { - case STOP_FILLING: - break; - case 0: - case CURL_READFUNC_ABORT: - case CURL_READFUNC_PAUSE: - case READ_ERROR: - part->lastreadstatus = sz; - break; - default: - part->state.offset += sz; - part->lastreadstatus = sz; - break; - } - - return sz; -} - -/* Read and encode part content. */ -static size_t read_encoded_part_content(curl_mimepart *part, char *buffer, - size_t bufsize, bool *hasread, - size_t call_depth) -{ - struct mime_encoder_state *st = &part->encstate; - size_t cursize = 0; - size_t sz; - bool ateof = FALSE; - - if(++call_depth > MAX_MIME_LEVELS) - return READ_ERROR; - - for(;;) { - if(st->bufbeg < st->bufend || ateof) { - /* Encode buffered data. */ - sz = part->encoder->encodefunc(buffer, bufsize, ateof, part); - switch(sz) { - case 0: - if(ateof) - return cursize; - break; - case READ_ERROR: - case STOP_FILLING: - return cursize ? cursize : sz; - default: - cursize += sz; - buffer += sz; - bufsize -= sz; - continue; - } - } - - /* We need more data in input buffer. */ - if(st->bufbeg) { - size_t len = st->bufend - st->bufbeg; - - if(len) - memmove(st->buf, st->buf + st->bufbeg, len); - st->bufbeg = 0; - st->bufend = len; - } - if(st->bufend >= sizeof(st->buf)) - return cursize ? cursize : READ_ERROR; /* Buffer full. */ - sz = read_part_content(part, st->buf + st->bufend, - sizeof(st->buf) - st->bufend, hasread, call_depth); - switch(sz) { - case 0: - ateof = TRUE; - break; - case CURL_READFUNC_ABORT: - case CURL_READFUNC_PAUSE: - case READ_ERROR: - case STOP_FILLING: - return cursize ? cursize : sz; - default: - st->bufend += sz; - break; - } - } - - /* NOTREACHED */ -} - -/* Readback a mime part. */ -static size_t readback_part(curl_mimepart *part, - char *buffer, size_t bufsize, bool *hasread, - size_t call_depth) -{ - size_t cursize = 0; - - if(++call_depth > MAX_MIME_LEVELS) - return READ_ERROR; - - /* Readback from part. */ - while(bufsize) { - size_t sz = 0; - struct curl_slist *hdr = (struct curl_slist *)part->state.ptr; - switch(part->state.state) { - case MIMESTATE_BEGIN: - mimesetstate(&part->state, - (part->flags & MIME_BODY_ONLY) ? - MIMESTATE_BODY : MIMESTATE_CURLHEADERS, - part->curlheaders); - break; - case MIMESTATE_USERHEADERS: - if(!hdr) { - mimesetstate(&part->state, MIMESTATE_EOH, NULL); - break; - } - if(match_header(hdr, "Content-Type", 12)) { - mimesetstate(&part->state, MIMESTATE_USERHEADERS, hdr->next); - break; - } - FALLTHROUGH(); - case MIMESTATE_CURLHEADERS: - if(!hdr) - mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders); - else { - sz = readback_bytes(&part->state, buffer, bufsize, - hdr->data, strlen(hdr->data), STRCONST("\r\n")); - if(!sz) - mimesetstate(&part->state, part->state.state, hdr->next); - } - break; - case MIMESTATE_EOH: - sz = readback_bytes(&part->state, buffer, bufsize, STRCONST("\r\n"), - STRCONST("")); - if(!sz) - mimesetstate(&part->state, MIMESTATE_BODY, NULL); - break; - case MIMESTATE_BODY: - cleanup_encoder_state(&part->encstate); - mimesetstate(&part->state, MIMESTATE_CONTENT, NULL); - break; - case MIMESTATE_CONTENT: - if(part->encoder) - sz = read_encoded_part_content(part, buffer, bufsize, hasread, - call_depth); - else - sz = read_part_content(part, buffer, bufsize, hasread, call_depth); - switch(sz) { - case 0: - mimesetstate(&part->state, MIMESTATE_END, NULL); - /* Try sparing open file descriptors. */ - if(part->kind == MIMEKIND_FILE && part->fp) { - curlx_fclose(part->fp); - part->fp = NULL; - } - FALLTHROUGH(); - case CURL_READFUNC_ABORT: - case CURL_READFUNC_PAUSE: - case READ_ERROR: - case STOP_FILLING: - return cursize ? cursize : sz; - } - break; - case MIMESTATE_END: - return cursize; - default: - break; /* Other values not in part state. */ - } - - /* Bump buffer and counters according to read size. */ - cursize += sz; - buffer += sz; - bufsize -= sz; - } - - return cursize; -} - -/* Readback from mime. Warning: not a read callback function. */ -static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, - void *instream, bool *hasread, - size_t call_depth) -{ - curl_mime *mime = (curl_mime *)instream; - size_t cursize = 0; - (void)size; /* Always 1 */ - - if(++call_depth > MAX_MIME_LEVELS) - return READ_ERROR; - - while(nitems) { - size_t sz = 0; - curl_mimepart *part = mime->state.ptr; - switch(mime->state.state) { - case MIMESTATE_BEGIN: - case MIMESTATE_BODY: - mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart); - /* The first boundary always follows the header termination empty line, - so is always preceded by a CRLF. We can then spare 2 characters - by skipping the leading CRLF in boundary. */ - mime->state.offset += 2; - break; - case MIMESTATE_BOUNDARY1: - sz = readback_bytes(&mime->state, buffer, nitems, STRCONST("\r\n--"), - STRCONST("")); - if(!sz) - mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part); - break; - case MIMESTATE_BOUNDARY2: - if(part) - sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary, - MIME_BOUNDARY_LEN, STRCONST("\r\n")); - else - sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary, - MIME_BOUNDARY_LEN, STRCONST("--\r\n")); - if(!sz) { - mimesetstate(&mime->state, MIMESTATE_CONTENT, part); - } - break; - case MIMESTATE_CONTENT: - if(!part) { - mimesetstate(&mime->state, MIMESTATE_END, NULL); - break; - } - sz = readback_part(part, buffer, nitems, hasread, call_depth); - switch(sz) { - case CURL_READFUNC_ABORT: - case CURL_READFUNC_PAUSE: - case READ_ERROR: - case STOP_FILLING: - return cursize ? cursize : sz; - case 0: - mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, part->nextpart); - break; - } - break; - case MIMESTATE_END: - return cursize; - default: - break; /* other values not used in mime state. */ - } - - /* Bump buffer and counters according to read size. */ - cursize += sz; - buffer += sz; - nitems -= sz; - } - - return cursize; -} - -static int mime_part_rewind(curl_mimepart *part) -{ - int res = CURL_SEEKFUNC_OK; - enum mimestate targetstate = MIMESTATE_BEGIN; - - if(part->flags & MIME_BODY_ONLY) - targetstate = MIMESTATE_BODY; - cleanup_encoder_state(&part->encstate); - if(part->state.state > targetstate) { - res = CURL_SEEKFUNC_CANTSEEK; - if(part->seekfunc) { - res = part->seekfunc(part->arg, (curl_off_t)0, SEEK_SET); - switch(res) { - case CURL_SEEKFUNC_OK: - case CURL_SEEKFUNC_FAIL: - case CURL_SEEKFUNC_CANTSEEK: - break; - case -1: /* For fseek() error. */ - res = CURL_SEEKFUNC_CANTSEEK; - break; - default: - res = CURL_SEEKFUNC_FAIL; - break; - } - } - } - - if(res == CURL_SEEKFUNC_OK) - mimesetstate(&part->state, targetstate, NULL); - - part->lastreadstatus = 1; /* Successful read status. */ - return res; -} - -static int mime_subparts_seek(void *instream, curl_off_t offset, int whence) -{ - curl_mime *mime = (curl_mime *)instream; - curl_mimepart *part; - int rc = CURL_SEEKFUNC_OK; - - if(whence != SEEK_SET || offset) - return CURL_SEEKFUNC_CANTSEEK; /* Only support full rewind. */ - - if(mime->state.state == MIMESTATE_BEGIN) - return CURL_SEEKFUNC_OK; /* Already rewound. */ - - for(part = mime->firstpart; part; part = part->nextpart) { - int res = mime_part_rewind(part); - if(res != CURL_SEEKFUNC_OK) - rc = res; - } - - if(rc == CURL_SEEKFUNC_OK) - mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); - - return rc; -} - -/* Release part content. */ -static void cleanup_part_content(curl_mimepart *part) -{ - if(part->freefunc) - part->freefunc(part->arg); - - part->readfunc = NULL; - part->seekfunc = NULL; - part->freefunc = NULL; - part->arg = (void *)part; /* Defaults to part itself. */ - part->data = NULL; - part->fp = NULL; - part->datasize = (curl_off_t)0; /* No size yet. */ - cleanup_encoder_state(&part->encstate); - part->kind = MIMEKIND_NONE; - part->flags &= ~(unsigned int)MIME_FAST_READ; - part->lastreadstatus = 1; /* Successful read status. */ - part->state.state = MIMESTATE_BEGIN; -} - -static void mime_subparts_free(void *ptr) -{ - curl_mime *mime = (curl_mime *)ptr; - - if(mime && mime->parent) { - mime->parent->freefunc = NULL; /* Be sure we will not be called again. */ - cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ - } - curl_mime_free(mime); -} - -/* Do not free subparts: unbind them. This is used for the top level only. */ -static void mime_subparts_unbind(void *ptr) -{ - curl_mime *mime = (curl_mime *)ptr; - - if(mime && mime->parent) { - mime->parent->freefunc = NULL; /* Be sure we will not be called again. */ - cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ - mime->parent = NULL; - } -} - -void Curl_mime_cleanpart(curl_mimepart *part) -{ - if(part) { - cleanup_part_content(part); - curl_slist_free_all(part->curlheaders); - if(part->flags & MIME_USERHEADERS_OWNER) - curl_slist_free_all(part->userheaders); - curlx_safefree(part->mimetype); - curlx_safefree(part->name); - curlx_safefree(part->filename); - Curl_mime_initpart(part); - } -} - -/* Recursively delete a mime handle and its parts. */ -void curl_mime_free(curl_mime *mime) -{ - curl_mimepart *part; - - if(mime) { - mime_subparts_unbind(mime); /* Be sure it is not referenced anymore. */ - while(mime->firstpart) { - part = mime->firstpart; - mime->firstpart = part->nextpart; - Curl_mime_cleanpart(part); - curlx_free(part); - } - curlx_free(mime); - } -} - -CURLcode Curl_mime_duppart(struct Curl_easy *data, - curl_mimepart *dst, const curl_mimepart *src) -{ - curl_mime *mime; - curl_mimepart *d; - const curl_mimepart *s; - CURLcode res = CURLE_OK; - - DEBUGASSERT(dst); - - /* Duplicate content. */ - switch(src->kind) { - case MIMEKIND_NONE: - break; - case MIMEKIND_DATA: - res = curl_mime_data(dst, src->data, (size_t)src->datasize); - break; - case MIMEKIND_FILE: - res = curl_mime_filedata(dst, src->data); - /* Do not abort duplication if file is not readable. */ - if(res == CURLE_READ_ERROR) - res = CURLE_OK; - break; - case MIMEKIND_CALLBACK: - res = curl_mime_data_cb(dst, src->datasize, src->readfunc, - src->seekfunc, src->freefunc, src->arg); - break; - case MIMEKIND_MULTIPART: - /* No one knows about the cloned subparts, thus always attach ownership - to the part. */ - mime = curl_mime_init(data); - res = mime ? curl_mime_subparts(dst, mime) : CURLE_OUT_OF_MEMORY; - - /* Duplicate subparts. */ - for(s = ((curl_mime *)src->arg)->firstpart; !res && s; s = s->nextpart) { - d = curl_mime_addpart(mime); - res = d ? Curl_mime_duppart(data, d, s) : CURLE_OUT_OF_MEMORY; - } - break; - default: /* Invalid kind: should not occur. */ - DEBUGF(infof(data, "invalid MIMEKIND* attempt")); - res = CURLE_BAD_FUNCTION_ARGUMENT; /* Internal error? */ - break; - } - - /* Duplicate headers. */ - if(!res && src->userheaders) { - struct curl_slist *hdrs = Curl_slist_duplicate(src->userheaders); - - if(!hdrs) - res = CURLE_OUT_OF_MEMORY; - else { - /* No one but this procedure knows about the new header list, - so always take ownership. */ - res = curl_mime_headers(dst, hdrs, TRUE); - if(res) - curl_slist_free_all(hdrs); - } - } - - if(!res) { - /* Duplicate other fields. */ - dst->encoder = src->encoder; - res = curl_mime_type(dst, src->mimetype); - } - if(!res) - res = curl_mime_name(dst, src->name); - if(!res) - res = curl_mime_filename(dst, src->filename); - - /* If an error occurred, rollback. */ - if(res) - Curl_mime_cleanpart(dst); - - return res; -} - -/* - * Mime build functions. - */ - -/* Create a mime handle. */ -curl_mime *curl_mime_init(void *easy) -{ - curl_mime *mime; - - mime = (curl_mime *)curlx_malloc(sizeof(*mime)); - - if(mime) { - mime->parent = NULL; - mime->firstpart = NULL; - mime->lastpart = NULL; - - memset(mime->boundary, '-', MIME_BOUNDARY_DASHES); - if(Curl_rand_alnum(easy, - (unsigned char *)&mime->boundary[MIME_BOUNDARY_DASHES], - MIME_RAND_BOUNDARY_CHARS + 1)) { - /* failed to get random separator, bail out */ - curlx_free(mime); - return NULL; - } - mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); - } - - return mime; -} - -/* Initialize a mime part. */ -void Curl_mime_initpart(curl_mimepart *part) -{ - memset(part, 0, sizeof(*part)); - part->lastreadstatus = 1; /* Successful read status. */ - mimesetstate(&part->state, MIMESTATE_BEGIN, NULL); -} - -/* Create a mime part and append it to a mime handle's part list. */ -curl_mimepart *curl_mime_addpart(curl_mime *mime) -{ - curl_mimepart *part; - - if(!mime) - return NULL; - - part = (curl_mimepart *)curlx_malloc(sizeof(*part)); - - if(part) { - Curl_mime_initpart(part); - part->parent = mime; - - if(mime->lastpart) - mime->lastpart->nextpart = part; - else - mime->firstpart = part; - - mime->lastpart = part; - } - - return part; -} - -/* Set mime part name. */ -CURLcode curl_mime_name(curl_mimepart *part, const char *name) -{ - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - curlx_safefree(part->name); - - if(name) { - part->name = curlx_strdup(name); - if(!part->name) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -/* Set mime part remote filename. */ -CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) -{ - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - curlx_safefree(part->filename); - - if(filename) { - part->filename = curlx_strdup(filename); - if(!part->filename) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -/* Set mime part content from memory data. */ -CURLcode curl_mime_data(curl_mimepart *part, const char *data, size_t datasize) -{ - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - cleanup_part_content(part); - - if(data) { - if(datasize == CURL_ZERO_TERMINATED) - datasize = strlen(data); - - part->data = curlx_memdup0(data, datasize); - if(!part->data) - return CURLE_OUT_OF_MEMORY; - - part->datasize = datasize; - part->readfunc = mime_mem_read; - part->seekfunc = mime_mem_seek; - part->freefunc = mime_mem_free; - part->flags |= MIME_FAST_READ; - part->kind = MIMEKIND_DATA; - } - - return CURLE_OK; -} - -/* Set mime part content from named local file. */ -CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) -{ - CURLcode result = CURLE_OK; - - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - cleanup_part_content(part); - - if(filename) { - char *base; - curlx_struct_stat sbuf; - - if(curlx_stat(filename, &sbuf)) - result = CURLE_READ_ERROR; - else { - part->data = curlx_strdup(filename); - if(!part->data) - result = CURLE_OUT_OF_MEMORY; - else { - part->datasize = -1; - if(S_ISREG(sbuf.st_mode)) { - part->datasize = filesize(filename, sbuf); - part->seekfunc = mime_file_seek; - } - - part->readfunc = mime_file_read; - part->freefunc = mime_file_free; - part->kind = MIMEKIND_FILE; - - /* As a side effect, set the filename to the current file's base name. - It is possible to withdraw this by explicitly calling - curl_mime_filename() with a NULL filename argument after the current - call. */ - base = strippath(filename); - if(!base) - result = CURLE_OUT_OF_MEMORY; - else { - result = curl_mime_filename(part, base); - curlx_free(base); - } - } - } - } - return result; -} - -/* Set mime part type. */ -CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype) -{ - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - curlx_safefree(part->mimetype); - - if(mimetype) { - part->mimetype = curlx_strdup(mimetype); - if(!part->mimetype) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -static const struct mime_encoder encoders[] = { - { "binary", encoder_nop_read, encoder_nop_size }, - { "8bit", encoder_nop_read, encoder_nop_size }, - { "7bit", encoder_7bit_read, encoder_nop_size }, - { "base64", encoder_base64_read, encoder_base64_size }, - { "quoted-printable", encoder_qp_read, encoder_qp_size }, - { ZERO_NULL, ZERO_NULL, ZERO_NULL } -}; - -/* Set mime data transfer encoder. */ -CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) -{ - CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; - const struct mime_encoder *mep; - - if(!part) - return result; - - part->encoder = NULL; - - if(!encoding) - return CURLE_OK; /* Removing current encoder. */ - - for(mep = encoders; mep->name; mep++) - if(curl_strequal(encoding, mep->name)) { - part->encoder = mep; - result = CURLE_OK; - } - - return result; -} - -/* Set mime part headers. */ -CURLcode curl_mime_headers(curl_mimepart *part, - struct curl_slist *headers, int take_ownership) -{ - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(part->flags & MIME_USERHEADERS_OWNER) { - if(part->userheaders != headers) /* Allow setting twice the same list. */ - curl_slist_free_all(part->userheaders); - part->flags &= ~(unsigned int)MIME_USERHEADERS_OWNER; - } - part->userheaders = headers; - if(headers && take_ownership) - part->flags |= MIME_USERHEADERS_OWNER; - return CURLE_OK; -} - -/* Set mime part content from callback. */ -CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize, - curl_read_callback readfunc, - curl_seek_callback seekfunc, - curl_free_callback freefunc, void *arg) -{ - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - cleanup_part_content(part); - - if(readfunc) { - part->readfunc = readfunc; - part->seekfunc = seekfunc; - part->freefunc = freefunc; - part->arg = arg; - part->datasize = datasize; - part->kind = MIMEKIND_CALLBACK; - } - - return CURLE_OK; -} - -/* Set mime part content from subparts. */ -CURLcode Curl_mime_set_subparts(curl_mimepart *part, - curl_mime *subparts, int take_ownership) -{ - curl_mime *root; - - if(!part) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* Accept setting twice the same subparts. */ - if(part->kind == MIMEKIND_MULTIPART && part->arg == subparts) - return CURLE_OK; - - cleanup_part_content(part); - - if(subparts) { - /* Should not have been attached already. */ - if(subparts->parent) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* Should not be the part's root. */ - root = part->parent; - if(root) { - while(root->parent && root->parent->parent) - root = root->parent->parent; - if(subparts == root) { - /* cannot add as a subpart of itself. */ - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - - /* If subparts have already been used as a top-level MIMEPOST, - they might not be positioned at start. Rewind them now, as - a future check while rewinding the parent may cause this - content to be skipped. */ - if(mime_subparts_seek(subparts, (curl_off_t)0, SEEK_SET) != - CURL_SEEKFUNC_OK) - return CURLE_SEND_FAIL_REWIND; - - subparts->parent = part; - /* Subparts are processed internally: no read callback. */ - part->seekfunc = mime_subparts_seek; - part->freefunc = take_ownership ? mime_subparts_free : - mime_subparts_unbind; - part->arg = subparts; - part->datasize = -1; - part->kind = MIMEKIND_MULTIPART; - } - - return CURLE_OK; -} - -CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) -{ - return Curl_mime_set_subparts(part, subparts, TRUE); -} - -/* Readback from top mime. */ -/* Argument is the dummy top part. */ -size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) -{ - curl_mimepart *part = (curl_mimepart *)instream; - size_t ret; - bool hasread; - - (void)size; /* Always 1 */ - - /* If `nitems` is <= 4, some encoders will return STOP_FILLING without - * adding any data and this loops infinitely. */ - do { - hasread = FALSE; - ret = readback_part(part, buffer, nitems, &hasread, 0); - /* - * If this is not possible to get some data without calling more than - * one read callback (probably because a content encoder is not able to - * deliver a new bunch for the few data accumulated so far), force another - * read until we get enough data or a special exit code. - */ - } while(ret == STOP_FILLING); - - return ret; -} - -/* Rewind mime stream. */ -static CURLcode mime_rewind(curl_mimepart *part) -{ - return mime_part_rewind(part) == CURL_SEEKFUNC_OK ? - CURLE_OK : CURLE_SEND_FAIL_REWIND; -} - -/* Compute header list size. */ -static size_t slist_size(struct curl_slist *s, - size_t overhead, const char *skip, size_t skiplen) -{ - size_t size = 0; - - for(; s; s = s->next) - if(!skip || !match_header(s, skip, skiplen)) - size += strlen(s->data) + overhead; - return size; -} - -/* Get/compute multipart size. */ -static curl_off_t multipart_size(curl_mime *mime) -{ - curl_off_t size; - curl_off_t boundarysize; - curl_mimepart *part; - - if(!mime) - return 0; /* Not present -> empty. */ - - boundarysize = 4 + MIME_BOUNDARY_LEN + 2; - size = boundarysize; /* Final boundary - CRLF after headers. */ - - for(part = mime->firstpart; part; part = part->nextpart) { - curl_off_t sz = mime_size(part); - - if(sz < 0) - size = sz; - - if(size >= 0) - size += boundarysize + sz; - } - - return size; -} - -/* Get/compute mime size. */ -static curl_off_t mime_size(curl_mimepart *part) -{ - curl_off_t size; - - if(part->kind == MIMEKIND_MULTIPART) - part->datasize = multipart_size(part->arg); - - size = part->datasize; - - if(part->encoder) - size = part->encoder->sizefunc(part); - - if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) { - /* Compute total part size. */ - size += slist_size(part->curlheaders, 2, NULL, 0); - size += slist_size(part->userheaders, 2, STRCONST("Content-Type")); - size += 2; /* CRLF after headers. */ - } - return size; -} - -/* Add a header. */ -/* VARARGS2 */ -CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) -{ - struct curl_slist *hdr = NULL; - char *s = NULL; - va_list ap; - - va_start(ap, fmt); - s = curl_mvaprintf(fmt, ap); - va_end(ap); - - if(s) { - hdr = Curl_slist_append_nodup(*slp, s); - if(hdr) - *slp = hdr; - else - curlx_free(s); - } - - return hdr ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} - -/* Add a content type header. */ -static CURLcode add_content_type(struct curl_slist **slp, - const char *type, const char *boundary) -{ - return Curl_mime_add_header(slp, "Content-Type: %s%s%s", type, - boundary ? "; boundary=" : "", - boundary ? boundary : ""); -} - -const char *Curl_mime_contenttype(const char *filename) -{ - /* - * If no content type was specified, we scan through a few well-known - * extensions and pick the first we match! - */ - struct ContentType { - const char *extension; - const char *type; - }; - static const struct ContentType ctts[] = { - { ".gif", "image/gif" }, - { ".jpg", "image/jpeg" }, - { ".jpeg", "image/jpeg" }, - { ".png", "image/png" }, - { ".svg", "image/svg+xml" }, - { ".txt", "text/plain" }, - { ".htm", "text/html" }, - { ".html", "text/html" }, - { ".pdf", "application/pdf" }, - { ".xml", "application/xml" } - }; - - if(filename) { - size_t len1 = strlen(filename); - const char *nameend = filename + len1; - unsigned int i; - - for(i = 0; i < CURL_ARRAYSIZE(ctts); i++) { - size_t len2 = strlen(ctts[i].extension); - - if(len1 >= len2 && curl_strequal(nameend - len2, ctts[i].extension)) - return ctts[i].type; - } - } - return NULL; -} - -static bool content_type_match(const char *contenttype, - const char *target, size_t len) -{ - if(contenttype && curl_strnequal(contenttype, target, len)) - switch(contenttype[len]) { - case '\0': - case '\t': - case '\r': - case '\n': - case ' ': - case ';': - return TRUE; - } - return FALSE; -} - -CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, - curl_mimepart *part, - const char *contenttype, - const char *disposition, - enum mimestrategy strategy) -{ - curl_mime *mime = NULL; - const char *boundary = NULL; - char *customct; - const char *cte = NULL; - CURLcode result = CURLE_OK; - - /* Get rid of previously prepared headers. */ - curl_slist_free_all(part->curlheaders); - part->curlheaders = NULL; - - /* Be sure we will not access old headers later. */ - if(part->state.state == MIMESTATE_CURLHEADERS) - mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL); - - /* Check if content type is specified. */ - customct = part->mimetype; - if(!customct) - customct = search_header(part->userheaders, STRCONST("Content-Type")); - if(customct) - contenttype = customct; - - /* If content type is not specified, try to determine it. */ - if(!contenttype) { - switch(part->kind) { - case MIMEKIND_MULTIPART: - contenttype = MULTIPART_CONTENTTYPE_DEFAULT; - break; - case MIMEKIND_FILE: - contenttype = Curl_mime_contenttype(part->filename); - if(!contenttype) - contenttype = Curl_mime_contenttype(part->data); - if(!contenttype && part->filename) - contenttype = FILE_CONTENTTYPE_DEFAULT; - break; - default: - contenttype = Curl_mime_contenttype(part->filename); - break; - } - } - - if(part->kind == MIMEKIND_MULTIPART) { - mime = (curl_mime *)part->arg; - if(mime) - boundary = mime->boundary; - } - else if(contenttype && !customct && - content_type_match(contenttype, STRCONST("text/plain"))) - if(strategy == MIMESTRATEGY_MAIL || !part->filename) - contenttype = NULL; - - /* Issue content-disposition header only if not already set by caller. */ - if(!search_header(part->userheaders, STRCONST("Content-Disposition"))) { - if(!disposition) - if(part->filename || part->name || - (contenttype && !curl_strnequal(contenttype, "multipart/", 10))) - disposition = DISPOSITION_DEFAULT; - if(disposition && curl_strequal(disposition, "attachment") && - !part->name && !part->filename) - disposition = NULL; - if(disposition) { - char *name = NULL; - char *filename = NULL; - - if(part->name) { - name = escape_string(data, part->name, strategy); - if(!name) - result = CURLE_OUT_OF_MEMORY; - } - if(!result && part->filename) { - filename = escape_string(data, part->filename, strategy); - if(!filename) - result = CURLE_OUT_OF_MEMORY; - } - if(!result) - result = Curl_mime_add_header(&part->curlheaders, - "Content-Disposition: %s%s%s%s%s%s%s", - disposition, - name ? "; name=\"" : "", - name ? name : "", - name ? "\"" : "", - filename ? "; filename=\"" : "", - filename ? filename : "", - filename ? "\"" : ""); - curlx_safefree(name); - curlx_safefree(filename); - if(result) - return result; - } - } - - /* Issue Content-Type header. */ - if(contenttype) { - result = add_content_type(&part->curlheaders, contenttype, boundary); - if(result) - return result; - } - - /* Content-Transfer-Encoding header. */ - if(!search_header(part->userheaders, - STRCONST("Content-Transfer-Encoding"))) { - if(part->encoder) - cte = part->encoder->name; - else if(contenttype && strategy == MIMESTRATEGY_MAIL && - part->kind != MIMEKIND_MULTIPART) - cte = "8bit"; - if(cte) { - result = Curl_mime_add_header(&part->curlheaders, - "Content-Transfer-Encoding: %s", cte); - if(result) - return result; - } - } - - /* If we were reading curl-generated headers, restart with new ones (this - should not occur). */ - if(part->state.state == MIMESTATE_CURLHEADERS) - mimesetstate(&part->state, MIMESTATE_CURLHEADERS, part->curlheaders); - - /* Process subparts. */ - if(part->kind == MIMEKIND_MULTIPART && mime) { - curl_mimepart *subpart; - - disposition = NULL; - if(content_type_match(contenttype, STRCONST("multipart/form-data"))) - disposition = "form-data"; - for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) { - result = Curl_mime_prepare_headers(data, subpart, NULL, - disposition, strategy); - if(result) - return result; - } - } - return result; -} - -/* Recursively reset paused status in the given part. */ -static void mime_unpause(curl_mimepart *part) -{ - if(part) { - if(part->lastreadstatus == CURL_READFUNC_PAUSE) - part->lastreadstatus = 1; /* Successful read status. */ - if(part->kind == MIMEKIND_MULTIPART) { - curl_mime *mime = (curl_mime *)part->arg; - - if(mime) { - curl_mimepart *subpart; - - for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) - mime_unpause(subpart); - } - } - } -} - -struct cr_mime_ctx { - struct Curl_creader super; - curl_mimepart *part; - curl_off_t total_len; - curl_off_t read_len; - CURLcode error_result; - struct bufq tmpbuf; - BIT(seen_eos); - BIT(errored); -}; - -static CURLcode cr_mime_init(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - ctx->total_len = -1; - ctx->read_len = 0; - Curl_bufq_init2(&ctx->tmpbuf, 1024, 1, BUFQ_OPT_NO_SPARES); - return CURLE_OK; -} - -static void cr_mime_close(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - Curl_bufq_free(&ctx->tmpbuf); -} - -/* Real client reader to installed client callbacks. */ -static CURLcode cr_mime_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct cr_mime_ctx *ctx = reader->ctx; - CURLcode result = CURLE_OK; - size_t nread; - char tmp[256]; - - /* Once we have errored, we will return the same error forever */ - if(ctx->errored) { - CURL_TRC_READ(data, "cr_mime_read(len=%zu) is errored -> %d, eos=0", - blen, ctx->error_result); - *pnread = 0; - *peos = FALSE; - return ctx->error_result; - } - if(ctx->seen_eos) { - CURL_TRC_READ(data, "cr_mime_read(len=%zu) seen eos -> 0, eos=1", blen); - *pnread = 0; - *peos = TRUE; - return CURLE_OK; - } - /* respect length limitations */ - if(ctx->total_len >= 0) { - curl_off_t remain = ctx->total_len - ctx->read_len; - if(remain <= 0) - blen = 0; - else if(remain < (curl_off_t)blen) - blen = (size_t)remain; - } - - if(!Curl_bufq_is_empty(&ctx->tmpbuf)) { - result = Curl_bufq_read(&ctx->tmpbuf, (unsigned char *)buf, blen, &nread); - if(result) { - ctx->errored = TRUE; - ctx->error_result = result; - return result; - } - } - else if(blen <= 4) { - /* Curl_mime_read() may go into an infinite loop when reading - * via a base64 encoder, as it stalls when the read buffer is too small - * to contain a complete 3 byte encoding. Read into a larger buffer - * and use that until empty. */ - CURL_TRC_READ(data, "cr_mime_read(len=%zu), small read, using tmp", blen); - nread = Curl_mime_read(tmp, 1, sizeof(tmp), ctx->part); - if(nread <= sizeof(tmp)) { - size_t n; - result = Curl_bufq_write(&ctx->tmpbuf, (unsigned char *)tmp, nread, &n); - if(result) { - ctx->errored = TRUE; - ctx->error_result = result; - return result; - } - /* stored it, read again */ - result = Curl_bufq_cread(&ctx->tmpbuf, buf, blen, &nread); - if(result) { - ctx->errored = TRUE; - ctx->error_result = result; - return result; - } - } - } - else - nread = Curl_mime_read(buf, 1, blen, ctx->part); - - CURL_TRC_READ(data, "cr_mime_read(len=%zu), mime_read() -> %zu", - blen, nread); - - switch(nread) { - case 0: - if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) { - failf(data, "client mime read EOF fail, " - "only %" FMT_OFF_T "/%" FMT_OFF_T - " of needed bytes read", ctx->read_len, ctx->total_len); - return CURLE_READ_ERROR; - } - *pnread = 0; - *peos = TRUE; - ctx->seen_eos = TRUE; - break; - - case CURL_READFUNC_ABORT: - failf(data, "operation aborted by callback"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_ABORTED_BY_CALLBACK; - result = CURLE_ABORTED_BY_CALLBACK; - break; - - case CURL_READFUNC_PAUSE: - /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ - CURL_TRC_READ(data, "cr_mime_read(len=%zu), paused by callback", blen); - *pnread = 0; - *peos = FALSE; - result = Curl_xfer_pause_send(data, TRUE); - break; /* nothing was read */ - - case STOP_FILLING: - case READ_ERROR: - failf(data, "read error getting mime data"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_READ_ERROR; - result = CURLE_READ_ERROR; - break; - - default: - if(nread > blen) { - /* the read function returned a too large value */ - failf(data, "read function returned funny value"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_READ_ERROR; - return CURLE_READ_ERROR; - } - ctx->read_len += nread; - if(ctx->total_len >= 0) - ctx->seen_eos = (ctx->read_len >= ctx->total_len); - *pnread = nread; - *peos = (bool)ctx->seen_eos; - break; - } - - CURL_TRC_READ(data, "cr_mime_read(len=%zu, total=%" FMT_OFF_T - ", read=%" FMT_OFF_T ") -> %d, %zu, %d", - blen, ctx->total_len, ctx->read_len, result, *pnread, *peos); - return result; -} - -static bool cr_mime_needs_rewind(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - return ctx->read_len > 0; -} - -static curl_off_t cr_mime_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - return ctx->total_len; -} - -static CURLcode cr_mime_resume_from(struct Curl_easy *data, - struct Curl_creader *reader, - curl_off_t offset) -{ - struct cr_mime_ctx *ctx = reader->ctx; - - if(offset > 0) { - curl_off_t passed = 0; - - do { - char scratch[4 * 1024]; - size_t readthisamountnow = - (offset - passed > (curl_off_t)sizeof(scratch)) ? - sizeof(scratch) : - curlx_sotouz(offset - passed); - size_t nread; - - nread = Curl_mime_read(scratch, 1, readthisamountnow, ctx->part); - passed += (curl_off_t)nread; - if((nread == 0) || (nread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Could only read %" FMT_OFF_T - " bytes from the mime post", passed); - return CURLE_READ_ERROR; - } - } while(passed < offset); - - /* now, decrease the size of the read */ - if(ctx->total_len > 0) { - ctx->total_len -= offset; - - if(ctx->total_len <= 0) { - failf(data, "Mime post already completely uploaded"); - return CURLE_PARTIAL_FILE; - } - } - /* we have passed, proceed as normal */ - } - return CURLE_OK; -} - -static CURLcode cr_mime_cntrl(struct Curl_easy *data, - struct Curl_creader *reader, - Curl_creader_cntrl opcode) -{ - struct cr_mime_ctx *ctx = reader->ctx; - switch(opcode) { - case CURL_CRCNTRL_REWIND: { - CURLcode result = mime_rewind(ctx->part); - if(result) - failf(data, "Cannot rewind mime/post data"); - return result; - } - case CURL_CRCNTRL_UNPAUSE: - mime_unpause(ctx->part); - break; - case CURL_CRCNTRL_CLEAR_EOS: - ctx->seen_eos = FALSE; - break; - default: - break; - } - return CURLE_OK; -} - -static bool cr_mime_is_paused(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - return ctx->part && ctx->part->lastreadstatus == CURL_READFUNC_PAUSE; -} - -static const struct Curl_crtype cr_mime = { - "cr-mime", - cr_mime_init, - cr_mime_read, - cr_mime_close, - cr_mime_needs_rewind, - cr_mime_total_length, - cr_mime_resume_from, - cr_mime_cntrl, - cr_mime_is_paused, - Curl_creader_def_done, - sizeof(struct cr_mime_ctx) -}; - -CURLcode Curl_creader_set_mime(struct Curl_easy *data, curl_mimepart *part) -{ - struct Curl_creader *r; - struct cr_mime_ctx *ctx; - CURLcode result; - - result = Curl_creader_create(&r, data, &cr_mime, CURL_CR_CLIENT); - if(result) - return result; - ctx = r->ctx; - ctx->part = part; - /* Make sure we will read the entire mime structure. */ - result = mime_rewind(ctx->part); - if(result) { - Curl_creader_free(data, r); - return result; - } - ctx->total_len = mime_size(ctx->part); - - return Curl_creader_set(data, r); -} - -#else /* !CURL_DISABLE_MIME && (!CURL_DISABLE_HTTP || - !CURL_DISABLE_SMTP || - !CURL_DISABLE_IMAP) */ - -/* Mime not compiled in: define stubs for externally-referenced functions. */ -curl_mime *curl_mime_init(CURL *easy) -{ - (void)easy; - return NULL; -} - -void curl_mime_free(curl_mime *mime) -{ - (void)mime; -} - -curl_mimepart *curl_mime_addpart(curl_mime *mime) -{ - (void)mime; - return NULL; -} - -CURLcode curl_mime_name(curl_mimepart *part, const char *name) -{ - (void)part; - (void)name; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) -{ - (void)part; - (void)filename; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype) -{ - (void)part; - (void)mimetype; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) -{ - (void)part; - (void)encoding; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_data(curl_mimepart *part, const char *data, size_t datasize) -{ - (void)part; - (void)data; - (void)datasize; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) -{ - (void)part; - (void)filename; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize, - curl_read_callback readfunc, - curl_seek_callback seekfunc, - curl_free_callback freefunc, - void *arg) -{ - (void)part; - (void)datasize; - (void)readfunc; - (void)seekfunc; - (void)freefunc; - (void)arg; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) -{ - (void)part; - (void)subparts; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_mime_headers(curl_mimepart *part, - struct curl_slist *headers, int take_ownership) -{ - (void)part; - (void)headers; - (void)take_ownership; - return CURLE_NOT_BUILT_IN; -} - -CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) -{ - (void)slp; - (void)fmt; - return CURLE_NOT_BUILT_IN; -} - -#endif /* if disabled */ diff --git a/vendor/curl/lib/mime.h b/vendor/curl/lib/mime.h deleted file mode 100644 index e84f04051..000000000 --- a/vendor/curl/lib/mime.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef HEADER_CURL_MIME_H -#define HEADER_CURL_MIME_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#define MIME_BOUNDARY_DASHES 24 /* leading boundary dashes */ -#define MIME_RAND_BOUNDARY_CHARS 22 /* Nb. of random boundary chars. */ -#define MAX_ENCODED_LINE_LENGTH 76 /* Maximum encoded line length. */ -#define ENCODING_BUFFER_SIZE 256 /* Encoding temp buffers size. */ - -/* Part flags. */ -#define MIME_USERHEADERS_OWNER (1 << 0) -#define MIME_BODY_ONLY (1 << 1) -#define MIME_FAST_READ (1 << 2) - -#define FILE_CONTENTTYPE_DEFAULT "application/octet-stream" -#define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed" -#define DISPOSITION_DEFAULT "attachment" - -/* Part source kinds. */ -enum mimekind { - MIMEKIND_NONE = 0, /* Part not set. */ - MIMEKIND_DATA, /* Allocated mime data. */ - MIMEKIND_FILE, /* Data from file. */ - MIMEKIND_CALLBACK, /* Data from `read' callback. */ - MIMEKIND_MULTIPART, /* Data is a mime subpart. */ - MIMEKIND_LAST -}; - -/* Readback state tokens. */ -enum mimestate { - MIMESTATE_BEGIN, /* Readback has not yet started. */ - MIMESTATE_CURLHEADERS, /* In curl-generated headers. */ - MIMESTATE_USERHEADERS, /* In caller's supplied headers. */ - MIMESTATE_EOH, /* End of headers. */ - MIMESTATE_BODY, /* Placeholder. */ - MIMESTATE_BOUNDARY1, /* In boundary prefix. */ - MIMESTATE_BOUNDARY2, /* In boundary. */ - MIMESTATE_CONTENT, /* In content. */ - MIMESTATE_END, /* End of part reached. */ - MIMESTATE_LAST -}; - -/* Mime headers strategies. */ -enum mimestrategy { - MIMESTRATEGY_MAIL, /* Mime mail. */ - MIMESTRATEGY_FORM, /* HTTP post form. */ - MIMESTRATEGY_LAST -}; - -/* Content transfer encoder. */ -struct mime_encoder { - const char * name; /* Encoding name. */ - size_t (*encodefunc)(char *buffer, size_t size, bool ateof, - curl_mimepart *part); /* Encoded read. */ - curl_off_t (*sizefunc)(curl_mimepart *part); /* Encoded size. */ -}; - -/* Content transfer encoder state. */ -struct mime_encoder_state { - size_t pos; /* Position on output line. */ - size_t bufbeg; /* Next data index in input buffer. */ - size_t bufend; /* First unused byte index in input buffer. */ - char buf[ENCODING_BUFFER_SIZE]; /* Input buffer. */ -}; - -/* Mime readback state. */ -struct mime_state { - enum mimestate state; /* Current state token. */ - void *ptr; /* State-dependent pointer. */ - curl_off_t offset; /* State-dependent offset. */ -}; - -/* Boundary string length. */ -#define MIME_BOUNDARY_LEN (MIME_BOUNDARY_DASHES + MIME_RAND_BOUNDARY_CHARS) - -/* A mime multipart. */ -struct curl_mime { - curl_mimepart *parent; /* Parent part. */ - curl_mimepart *firstpart; /* First part. */ - curl_mimepart *lastpart; /* Last part. */ - char boundary[MIME_BOUNDARY_LEN + 1]; /* The part boundary. */ - struct mime_state state; /* Current readback state. */ -}; - -/* A mime part. */ -struct curl_mimepart { - curl_mime *parent; /* Parent mime structure. */ - curl_mimepart *nextpart; /* Forward linked list. */ - enum mimekind kind; /* The part kind. */ - unsigned int flags; /* Flags. */ - char *data; /* Memory data or filename. */ - curl_read_callback readfunc; /* Read function. */ - curl_seek_callback seekfunc; /* Seek function. */ - curl_free_callback freefunc; /* Argument free function. */ - void *arg; /* Argument to callback functions. */ - FILE *fp; /* File pointer. */ - struct curl_slist *curlheaders; /* Part headers. */ - struct curl_slist *userheaders; /* Part headers. */ - char *mimetype; /* Part mime type. */ - char *filename; /* Remote filename. */ - char *name; /* Data name. */ - curl_off_t datasize; /* Expected data size. */ - struct mime_state state; /* Current readback state. */ - const struct mime_encoder *encoder; /* Content data encoder. */ - struct mime_encoder_state encstate; /* Data encoder state. */ - size_t lastreadstatus; /* Last read callback returned status. */ -}; - -CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) - CURL_PRINTF(2, 3); - -#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ - !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_IMAP)) - -/* Prototypes. */ -void Curl_mime_initpart(struct curl_mimepart *part); -void Curl_mime_cleanpart(struct curl_mimepart *part); -CURLcode Curl_mime_duppart(struct Curl_easy *data, - struct curl_mimepart *dst, - const curl_mimepart *src); -CURLcode Curl_mime_set_subparts(struct curl_mimepart *part, - struct curl_mime *subparts, - int take_ownership); -CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, - struct curl_mimepart *part, - const char *contenttype, - const char *disposition, - enum mimestrategy strategy); -size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, - void *instream); -const char *Curl_mime_contenttype(const char *filename); - -/** - * Install a client reader as upload source that reads the given - * mime part. - */ -CURLcode Curl_creader_set_mime(struct Curl_easy *data, curl_mimepart *part); - -#else /* if disabled */ -#define Curl_mime_initpart(x) -#define Curl_mime_cleanpart(x) -#define Curl_mime_duppart(x, y, z) CURLE_OK /* Nothing to duplicate. Succeed */ -#define Curl_mime_set_subparts(a, b, c) CURLE_NOT_BUILT_IN -#define Curl_mime_prepare_headers(a, b, c, d, e) CURLE_NOT_BUILT_IN -#define Curl_mime_read NULL -#define Curl_creader_set_mime(x, y) ((void)(x), CURLE_NOT_BUILT_IN) -#endif - -#endif /* HEADER_CURL_MIME_H */ diff --git a/vendor/curl/lib/mprintf.c b/vendor/curl/lib/mprintf.c deleted file mode 100644 index 6eaea66b7..000000000 --- a/vendor/curl/lib/mprintf.c +++ /dev/null @@ -1,1259 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/dynbuf.h" -#include "curl_printf.h" -#include "curlx/strparse.h" -#include "curlx/snprintf.h" /* for curlx_win32_snprintf() */ - -#define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should - fit negative DBL_MAX (317 letters) */ -#define MAX_PARAMETERS 128 /* number of input arguments */ -#define MAX_SEGMENTS 128 /* number of output segments */ - -/* Lower-case digits. */ -const unsigned char Curl_ldigits[] = "0123456789abcdef"; - -/* Upper-case digits. */ -const unsigned char Curl_udigits[] = "0123456789ABCDEF"; - -#define OUTCHAR(x) \ - do { \ - if(stream((unsigned char)(x), userp)) \ - return TRUE; \ - (*donep)++; \ - } while(0) - -/* Data type to read from the arglist */ -typedef enum { - MTYPE_STRING, - MTYPE_PTR, - MTYPE_INTPTR, - MTYPE_INT, - MTYPE_LONG, - MTYPE_LONGLONG, - MTYPE_INTU, - MTYPE_LONGU, - MTYPE_LONGLONGU, - MTYPE_DOUBLE, - MTYPE_LONGDOUBLE, - MTYPE_WIDTH, - MTYPE_PRECISION -} FormatType; - -/* conversion and display flags */ -enum { - FLAGS_SPACE = 1 << 0, - FLAGS_SHOWSIGN = 1 << 1, - FLAGS_LEFT = 1 << 2, - FLAGS_ALT = 1 << 3, - FLAGS_SHORT = 1 << 4, - FLAGS_LONG = 1 << 5, - FLAGS_LONGLONG = 1 << 6, - FLAGS_LONGDOUBLE = 1 << 7, - FLAGS_PAD_NIL = 1 << 8, - FLAGS_UNSIGNED = 1 << 9, - FLAGS_OCTAL = 1 << 10, - FLAGS_HEX = 1 << 11, - FLAGS_UPPER = 1 << 12, - FLAGS_WIDTH = 1 << 13, /* '*' or '*$' used */ - FLAGS_WIDTHPARAM = 1 << 14, /* width PARAMETER was specified */ - FLAGS_PREC = 1 << 15, /* precision was specified */ - FLAGS_PRECPARAM = 1 << 16, /* precision PARAMETER was specified */ - FLAGS_CHAR = 1 << 17, /* %c story */ - FLAGS_FLOATE = 1 << 18, /* %e or %E */ - FLAGS_FLOATG = 1 << 19, /* %g or %G */ - FLAGS_SUBSTR = 1 << 20 /* no input, only substring */ -}; - -enum { - DOLLAR_UNKNOWN, - DOLLAR_NOPE, - DOLLAR_USE -}; - -/* - * Describes an input va_arg type and hold its value. - */ -struct va_input { - FormatType type; /* FormatType */ - union { - const char *str; - void *ptr; - int64_t nums; /* signed */ - uint64_t numu; /* unsigned */ - double dnum; - } val; -}; - -/* - * Describes an output segment. - */ -struct outsegment { - int width; /* width OR width parameter number */ - int precision; /* precision OR precision parameter number */ - unsigned int flags; - unsigned int input; /* input argument array index */ - const char *start; /* format string start to output */ - size_t outlen; /* number of bytes from the format string to output */ -}; - -struct nsprintf { - char *buffer; - size_t length; - size_t max; -}; - -struct asprintf { - struct dynbuf *b; - char merr; -}; - -/* the provided input number is 1-based but this returns the number 0-based. - * - * returns -1 if no valid number was provided. - */ -static int dollarstring(const char *p, const char **end) -{ - curl_off_t num; - if(curlx_str_number(&p, &num, MAX_PARAMETERS) || - curlx_str_single(&p, '$') || !num) - return -1; - *end = p; - return (int)num - 1; -} - -#define is_arg_used(x, y) ((x)[(y) / 8] & (1 << ((y) & 7))) -#define mark_arg_used(x, y) ((x)[(y) / 8] |= (unsigned char)(1 << ((y) & 7))) - -/* - * Parse the format string. - * - * Create two arrays. One describes the inputs, one describes the outputs. - * - * Returns zero on success. - */ - -#define PFMT_OK 0 -#define PFMT_DOLLAR 1 /* bad dollar for main param */ -#define PFMT_DOLLARWIDTH 2 /* bad dollar use for width */ -#define PFMT_DOLLARPREC 3 /* bad dollar use for precision */ -#define PFMT_MANYARGS 4 /* too many input arguments used */ -#define PFMT_PREC 5 /* precision overflow */ -#define PFMT_PRECMIX 6 /* bad mix of precision specifiers */ -#define PFMT_WIDTH 7 /* width overflow */ -#define PFMT_INPUTGAP 8 /* gap in arguments */ -#define PFMT_WIDTHARG 9 /* attempted to use same arg twice, for width */ -#define PFMT_PRECARG 10 /* attempted to use same arg twice, for prec */ -#define PFMT_MANYSEGS 11 /* maxed out output segments */ - -static int parse_flags(const char **fmtp, unsigned int *flagsp, int use_dollar, - int *precp, int *widthp) -{ - const char *fmt = *fmtp; - bool loopit = TRUE; - unsigned int flags = 0; - int width = 0; - int precision = 0; - - /* Handle the flags */ - do { - switch(*fmt++) { - case ' ': - flags |= FLAGS_SPACE; - break; - case '+': - flags |= FLAGS_SHOWSIGN; - break; - case '-': - flags |= FLAGS_LEFT; - flags &= ~(unsigned int)FLAGS_PAD_NIL; - break; - case '#': - flags |= FLAGS_ALT; - break; - case '.': - if('*' == *fmt) { - /* The precision is picked from a specified parameter */ - flags |= FLAGS_PRECPARAM; - fmt++; - - if(use_dollar == DOLLAR_USE) { - precision = dollarstring(fmt, &fmt); - if(precision < 0) - /* illegal combo */ - return PFMT_DOLLARPREC; - } - else - /* get it from the next argument */ - precision = -1; - } - else { - bool is_neg; - curl_off_t num; - flags |= FLAGS_PREC; - is_neg = ('-' == *fmt); - if(is_neg) - fmt++; - if(curlx_str_number(&fmt, &num, INT_MAX)) - return PFMT_PREC; - precision = (int)num; - if(is_neg) - precision = -precision; - } - if((flags & (FLAGS_PREC | FLAGS_PRECPARAM)) == - (FLAGS_PREC | FLAGS_PRECPARAM)) - /* it is not permitted to use both kinds of precision for the same - argument */ - return PFMT_PRECMIX; - break; - case 'h': - flags |= FLAGS_SHORT; - break; -#ifdef _WIN32 - case 'I': - /* Non-ANSI integer extensions I32 I64 */ - if((fmt[0] == '3') && (fmt[1] == '2')) { - flags |= FLAGS_LONG; - fmt += 2; - } - else if((fmt[0] == '6') && (fmt[1] == '4')) { - flags |= FLAGS_LONGLONG; - fmt += 2; - } - else { -#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG) - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - } - break; -#endif /* _WIN32 */ - case 'l': - if(flags & FLAGS_LONG) - flags |= FLAGS_LONGLONG; - else - flags |= FLAGS_LONG; - break; - case 'L': - flags |= FLAGS_LONGDOUBLE; - break; - case 'q': - flags |= FLAGS_LONGLONG; - break; - case 'z': - /* the code below generates a warning if -Wunreachable-code is - used */ -#if (SIZEOF_SIZE_T > SIZEOF_LONG) - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case 'O': -#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG) - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case '0': - if(!(flags & FLAGS_LEFT)) - flags |= FLAGS_PAD_NIL; - FALLTHROUGH(); - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - curl_off_t num; - flags |= FLAGS_WIDTH; - fmt--; - if(curlx_str_number(&fmt, &num, INT_MAX)) - return PFMT_WIDTH; - width = (int)num; - break; - } - case '*': /* read width from argument list */ - flags |= FLAGS_WIDTHPARAM; - if(use_dollar == DOLLAR_USE) { - width = dollarstring(fmt, &fmt); - if(width < 0) - /* illegal combo */ - return PFMT_DOLLARWIDTH; - } - else - /* pick from the next argument */ - width = -1; - break; - default: - loopit = FALSE; - fmt--; - break; - } /* switch */ - } while(loopit); /* do */ - *flagsp = flags; - *precp = precision; - *widthp = width; - *fmtp = fmt; - return PFMT_OK; -} - -static bool parse_conversion(const char f, unsigned int *flagp, - FormatType *typep) -{ - unsigned int flags = *flagp; - FormatType type; - switch(f) { - case 'S': - flags |= FLAGS_ALT; - type = MTYPE_STRING; - break; - case 's': - type = MTYPE_STRING; - break; - case 'n': - type = MTYPE_INTPTR; - break; - case 'p': - type = MTYPE_PTR; - break; - case 'd': - case 'i': - if(flags & FLAGS_LONGLONG) - type = MTYPE_LONGLONG; - else if(flags & FLAGS_LONG) - type = MTYPE_LONG; - else - type = MTYPE_INT; - break; - case 'u': - if(flags & FLAGS_LONGLONG) - type = MTYPE_LONGLONGU; - else if(flags & FLAGS_LONG) - type = MTYPE_LONGU; - else - type = MTYPE_INTU; - flags |= FLAGS_UNSIGNED; - break; - case 'o': - if(flags & FLAGS_LONGLONG) - type = MTYPE_LONGLONGU; - else if(flags & FLAGS_LONG) - type = MTYPE_LONGU; - else - type = MTYPE_INTU; - flags |= FLAGS_OCTAL | FLAGS_UNSIGNED; - break; - case 'x': - if(flags & FLAGS_LONGLONG) - type = MTYPE_LONGLONGU; - else if(flags & FLAGS_LONG) - type = MTYPE_LONGU; - else - type = MTYPE_INTU; - flags |= FLAGS_HEX | FLAGS_UNSIGNED; - break; - case 'X': - if(flags & FLAGS_LONGLONG) - type = MTYPE_LONGLONGU; - else if(flags & FLAGS_LONG) - type = MTYPE_LONGU; - else - type = MTYPE_INTU; - flags |= FLAGS_HEX | FLAGS_UPPER | FLAGS_UNSIGNED; - break; - case 'c': - type = MTYPE_INT; - flags |= FLAGS_CHAR; - break; - case 'f': - type = MTYPE_DOUBLE; - break; - case 'e': - type = MTYPE_DOUBLE; - flags |= FLAGS_FLOATE; - break; - case 'E': - type = MTYPE_DOUBLE; - flags |= FLAGS_FLOATE | FLAGS_UPPER; - break; - case 'g': - type = MTYPE_DOUBLE; - flags |= FLAGS_FLOATG; - break; - case 'G': - type = MTYPE_DOUBLE; - flags |= FLAGS_FLOATG | FLAGS_UPPER; - break; - default: - /* invalid instruction, disregard and continue */ - return TRUE; - } /* switch */ - - *flagp |= flags; - *typep = type; - return FALSE; -} - - -static int parsefmt(const char *format, - struct outsegment *out, - struct va_input *in, - int *opieces, - int *ipieces, va_list arglist) -{ - const char *fmt = format; - int param_num = 0; - int max_param = -1; - int i; - int ocount = 0; - unsigned char usedinput[MAX_PARAMETERS / 8]; - size_t outlen = 0; - struct outsegment *optr; - int use_dollar = DOLLAR_UNKNOWN; - const char *start = fmt; - - /* clear, set a bit for each used input */ - memset(usedinput, 0, sizeof(usedinput)); - - while(*fmt) { - if(*fmt == '%') { - struct va_input *iptr; - FormatType type; - unsigned int flags = 0; - int width = 0; - int precision = 0; - int param = -1; - int rc; - fmt++; - outlen = (size_t)(fmt - start - 1); - if(*fmt == '%') { - /* this means a %% that should be output only as %. Create an output - segment. */ - if(outlen) { - optr = &out[ocount++]; - if(ocount > MAX_SEGMENTS) - return PFMT_MANYSEGS; - optr->input = 0; - optr->flags = FLAGS_SUBSTR; - optr->start = start; - optr->outlen = outlen; - } - start = fmt; - fmt++; - continue; /* while */ - } - - if(use_dollar != DOLLAR_NOPE) { - param = dollarstring(fmt, &fmt); - if(param < 0) { - if(use_dollar == DOLLAR_USE) - /* illegal combo */ - return PFMT_DOLLAR; - - /* we got no positional, get the next arg */ - param = -1; - use_dollar = DOLLAR_NOPE; - } - else - use_dollar = DOLLAR_USE; - } - - rc = parse_flags(&fmt, &flags, use_dollar, &precision, &width); - if(rc) - return rc; - - if(parse_conversion(*fmt, &flags, &type)) - continue; - - if(flags & FLAGS_WIDTHPARAM) { - if(width < 0) - width = param_num++; - else { - /* if this identifies a parameter already used, this is illegal */ - if(is_arg_used(usedinput, width)) - return PFMT_WIDTHARG; - } - if(width >= MAX_PARAMETERS) - return PFMT_MANYARGS; - if(width >= max_param) - max_param = width; - - in[width].type = MTYPE_WIDTH; - /* mark as used */ - mark_arg_used(usedinput, width); - } - - if(flags & FLAGS_PRECPARAM) { - if(precision < 0) - precision = param_num++; - else { - /* if this identifies a parameter already used, this is illegal */ - if(is_arg_used(usedinput, precision)) - return PFMT_PRECARG; - } - if(precision >= MAX_PARAMETERS) - return PFMT_MANYARGS; - if(precision >= max_param) - max_param = precision; - - in[precision].type = MTYPE_PRECISION; - mark_arg_used(usedinput, precision); - } - - /* Handle the specifier */ - if(param < 0) - param = param_num++; - if(param >= MAX_PARAMETERS) - return PFMT_MANYARGS; - if(param >= max_param) - max_param = param; - - iptr = &in[param]; - iptr->type = type; - - /* mark this input as used */ - mark_arg_used(usedinput, param); - - fmt++; - optr = &out[ocount++]; - if(ocount > MAX_SEGMENTS) - return PFMT_MANYSEGS; - optr->input = (unsigned int)param; - optr->flags = flags; - optr->width = width; - optr->precision = precision; - optr->start = start; - optr->outlen = outlen; - start = fmt; - } - else - fmt++; - } - - /* is there a trailing piece */ - outlen = (size_t)(fmt - start); - if(outlen) { - optr = &out[ocount++]; - if(ocount > MAX_SEGMENTS) - return PFMT_MANYSEGS; - optr->input = 0; - optr->flags = FLAGS_SUBSTR; - optr->start = start; - optr->outlen = outlen; - } - - /* Read the arg list parameters into our data list */ - for(i = 0; i < max_param + 1; i++) { - struct va_input *iptr = &in[i]; - if(!is_arg_used(usedinput, i)) - /* bad input */ - return PFMT_INPUTGAP; - - /* based on the type, read the correct argument */ - switch(iptr->type) { - case MTYPE_STRING: - iptr->val.str = va_arg(arglist, const char *); - break; - - case MTYPE_INTPTR: - case MTYPE_PTR: - iptr->val.ptr = va_arg(arglist, void *); - break; - - case MTYPE_LONGLONGU: - iptr->val.numu = va_arg(arglist, uint64_t); - break; - - case MTYPE_LONGLONG: - iptr->val.nums = va_arg(arglist, int64_t); - break; - - case MTYPE_LONGU: - iptr->val.numu = va_arg(arglist, unsigned long); - break; - - case MTYPE_LONG: - iptr->val.nums = va_arg(arglist, long); - break; - - case MTYPE_INTU: - iptr->val.numu = va_arg(arglist, unsigned int); - break; - - case MTYPE_INT: - case MTYPE_WIDTH: - case MTYPE_PRECISION: - iptr->val.nums = va_arg(arglist, int); - break; - - case MTYPE_DOUBLE: - iptr->val.dnum = va_arg(arglist, double); - break; - - default: - DEBUGASSERT(NULL); /* unexpected */ - break; - } - } - *ipieces = max_param + 1; - *opieces = ocount; - - return PFMT_OK; -} - -struct mproperty { - int width; /* Width of a field. */ - int prec; /* Precision of a field. */ - unsigned int flags; -}; - -static bool out_double(void *userp, - int (*stream)(unsigned char, void *), - struct mproperty *p, - double dnum, - char *work, int *donep) -{ - char fmt[32] = "%"; - char *fptr = &fmt[1]; - size_t left = sizeof(fmt) - strlen(fmt); - int flags = p->flags; - int width = p->width; - int prec = p->prec; - - if(flags & FLAGS_LEFT) - *fptr++ = '-'; - if(flags & FLAGS_SHOWSIGN) - *fptr++ = '+'; - if(flags & FLAGS_SPACE) - *fptr++ = ' '; - if(flags & FLAGS_ALT) - *fptr++ = '#'; - - *fptr = 0; - - if(width >= 0) { - size_t dlen; - if(width >= BUFFSIZE) - width = BUFFSIZE - 1; - /* RECURSIVE USAGE */ - dlen = (size_t)curl_msnprintf(fptr, left, "%d", width); - fptr += dlen; - left -= dlen; - } - if(prec >= 0) { - /* for each digit in the integer part, we can have one less - precision */ - int maxprec = BUFFSIZE - 1; - double val = dnum; - int len; - if(prec > maxprec) - prec = maxprec - 1; - if(width > 0 && prec <= width) - maxprec -= width; - while(val >= 10.0) { - val /= 10; - maxprec--; - } - - if(prec > maxprec) - prec = maxprec - 1; - if(prec < 0) - prec = 0; - /* RECURSIVE USAGE */ - len = curl_msnprintf(fptr, left, ".%d", prec); - fptr += len; - } - if(flags & FLAGS_LONG) - *fptr++ = 'l'; - - if(flags & FLAGS_FLOATE) - *fptr++ = (char)((flags & FLAGS_UPPER) ? 'E' : 'e'); - else if(flags & FLAGS_FLOATG) - *fptr++ = (char)((flags & FLAGS_UPPER) ? 'G' : 'g'); - else - *fptr++ = 'f'; - - *fptr = 0; /* and a final null-termination */ - - /* NOTE NOTE NOTE!! Not all sprintf implementations return number of - output characters */ -#ifdef CURL_HAVE_DIAG -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" -#endif -#ifdef _WIN32 - curlx_win32_snprintf(work, BUFFSIZE, fmt, dnum); -#else - /* !checksrc! disable BANNEDFUNC 1 */ - /* !checksrc! disable LONGLINE */ - /* NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) */ - snprintf(work, BUFFSIZE, fmt, dnum); -#endif -#ifdef CURL_HAVE_DIAG -#pragma GCC diagnostic pop -#endif - DEBUGASSERT(strlen(work) < BUFFSIZE); - while(*work) { - if(stream(*work++, userp)) - return TRUE; - (*donep)++; - } - return 0; -} - -static bool out_number(void *userp, - int (*stream)(unsigned char, void *), - struct mproperty *p, - uint64_t num, - int64_t nums, - char *work, int *donep) -{ - const unsigned char *digits = Curl_ldigits; - int flags = p->flags; - int width = p->width; - int prec = p->prec; - bool is_alt = flags & FLAGS_ALT; - bool is_neg = FALSE; - int base = 10; - - /* 'workend' points to the final buffer byte position, but with an extra - byte as margin to avoid the (FALSE?) warning Coverity gives us - otherwise */ - char *workend = &work[BUFFSIZE - 2]; - char *w; - - if(flags & FLAGS_CHAR) { - /* Character. */ - if(!(flags & FLAGS_LEFT)) - while(--width > 0) - OUTCHAR(' '); - OUTCHAR((char)num); - if(flags & FLAGS_LEFT) - while(--width > 0) - OUTCHAR(' '); - return FALSE; - } - if(flags & FLAGS_OCTAL) - /* Octal unsigned integer */ - base = 8; - - else if(flags & FLAGS_HEX) { - /* Hexadecimal unsigned integer */ - digits = (flags & FLAGS_UPPER) ? Curl_udigits : Curl_ldigits; - base = 16; - } - else if(flags & FLAGS_UNSIGNED) - /* Decimal unsigned integer */ - ; - - else { - /* Decimal integer. */ - is_neg = (nums < 0); - if(is_neg) { - /* signed_num might fail to hold absolute negative minimum by 1 */ - int64_t signed_num; /* Used to convert negative in positive. */ - signed_num = nums + (int64_t)1; - signed_num = -signed_num; - num = (uint64_t)signed_num; - num += (uint64_t)1; - } - } - - /* Supply a default precision if none was given. */ - if(prec == -1) - prec = 1; - - /* Put the number in WORK. */ - w = workend; - DEBUGASSERT(base <= 16); - switch(base) { - case 10: - while(num > 0) { - *w-- = (char)('0' + (num % 10)); - num /= 10; - } - break; - default: - while(num > 0) { - *w-- = digits[num % base]; - num /= base; - } - break; - } - width -= (int)(workend - w); - prec -= (int)(workend - w); - - if(is_alt && base == 8 && prec <= 0) { - *w-- = '0'; - --width; - } - - if(prec > 0) { - width -= prec; - while(prec-- > 0 && w >= work) - *w-- = '0'; - } - - if(is_alt && base == 16) - width -= 2; - - if(is_neg || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) - --width; - - if(!(flags & FLAGS_LEFT) && !(flags & FLAGS_PAD_NIL)) - while(width-- > 0) - OUTCHAR(' '); - - if(is_neg) - OUTCHAR('-'); - else if(flags & FLAGS_SHOWSIGN) - OUTCHAR('+'); - else if(flags & FLAGS_SPACE) - OUTCHAR(' '); - - if(is_alt && base == 16) { - OUTCHAR('0'); - if(flags & FLAGS_UPPER) - OUTCHAR('X'); - else - OUTCHAR('x'); - } - - if(!(flags & FLAGS_LEFT) && (flags & FLAGS_PAD_NIL)) - while(width-- > 0) - OUTCHAR('0'); - - /* Write the number. */ - while(++w <= workend) { - OUTCHAR(*w); - } - - if(flags & FLAGS_LEFT) - while(width-- > 0) - OUTCHAR(' '); - - return FALSE; -} - -static const char nilstr[] = "(nil)"; - -static bool out_string(void *userp, - int (*stream)(unsigned char, void *), - struct mproperty *p, - const char *str, - int *donep) -{ - int flags = p->flags; - int width = p->width; - int prec = p->prec; - size_t len; - - if(!str) { - /* Write null string if there is space. */ - if(prec == -1 || prec >= (int)sizeof(nilstr) - 1) { - str = nilstr; - len = sizeof(nilstr) - 1; - /* Disable quotes around (nil) */ - flags &= ~(unsigned int)FLAGS_ALT; - } - else { - str = ""; - len = 0; - } - } - else if(prec != -1) - len = (size_t)prec; - else if(*str == '\0') - len = 0; - else - len = strlen(str); - - width -= (len > INT_MAX) ? INT_MAX : (int)len; - - if(flags & FLAGS_ALT) - OUTCHAR('"'); - - if(!(flags & FLAGS_LEFT)) - while(width-- > 0) - OUTCHAR(' '); - - for(; len && *str; len--) - OUTCHAR(*str++); - if(flags & FLAGS_LEFT) - while(width-- > 0) - OUTCHAR(' '); - - if(flags & FLAGS_ALT) - OUTCHAR('"'); - - return FALSE; -} - -static bool out_pointer(void *userp, - int (*stream)(unsigned char, void *), - struct mproperty *p, - const char *ptr, - char *work, - int *donep) -{ - /* Generic pointer. */ - if(ptr) { - size_t num = (size_t)ptr; - - /* If the pointer is not NULL, write it as a %#x spec. */ - p->flags |= FLAGS_HEX | FLAGS_ALT; - if(out_number(userp, stream, p, num, 0, work, donep)) - return TRUE; - } - else { - /* Write "(nil)" for a nil pointer. */ - const char *point; - int width = p->width; - int flags = p->flags; - - width -= (int)(sizeof(nilstr) - 1); - if(flags & FLAGS_LEFT) - while(width-- > 0) - OUTCHAR(' '); - for(point = nilstr; *point; ++point) - OUTCHAR(*point); - if(!(flags & FLAGS_LEFT)) - while(width-- > 0) - OUTCHAR(' '); - } - return FALSE; -} - -/* - * formatf() - the general printf function. - * - * It calls parsefmt() to parse the format string. It populates two arrays; - * one that describes the input arguments and one that describes a number of - * output segments. - * - * On success, the input array describes the type of all arguments and their - * values. - * - * The function then iterates over the output segments and outputs them one - * by one until done. Using the appropriate input arguments (if any). - * - * All output is sent to the 'stream()' callback, one byte at a time. - */ - -static int formatf(void *userp, /* untouched by format(), sent to the - stream() function in the second argument */ - /* function pointer called for each output character */ - int (*stream)(unsigned char, void *), - const char *format, /* %-formatted string */ - va_list ap_save) /* list of parameters */ -{ - int done = 0; /* number of characters written */ - int i; - int ocount = 0; /* number of output segments */ - int icount = 0; /* number of input arguments */ - - struct outsegment output[MAX_SEGMENTS]; - struct va_input input[MAX_PARAMETERS]; - char work[BUFFSIZE + 2]; - - /* Parse the format string */ - if(parsefmt(format, output, input, &ocount, &icount, ap_save)) - return 0; - - for(i = 0; i < ocount; i++) { - struct outsegment *optr = &output[i]; - struct va_input *iptr = &input[optr->input]; - struct mproperty p; - size_t outlen = optr->outlen; - - if(outlen) { - const char *str = optr->start; - for(; outlen && *str; outlen--) { - if(stream(*str++, userp)) - return done; - done++; - } - if(optr->flags & FLAGS_SUBSTR) - /* this is a substring */ - continue; - } - - p.flags = optr->flags; - - /* pick up the specified width */ - if(p.flags & FLAGS_WIDTHPARAM) { - p.width = (int)input[optr->width].val.nums; - if(p.width < 0) { - /* "A negative field width is taken as a '-' flag followed by a - positive field width." */ - if(p.width == INT_MIN) - p.width = INT_MAX; - else - p.width = -p.width; - p.flags |= FLAGS_LEFT; - p.flags &= ~(unsigned int)FLAGS_PAD_NIL; - } - } - else - p.width = optr->width; - - /* pick up the specified precision */ - if(p.flags & FLAGS_PRECPARAM) { - p.prec = (int)input[optr->precision].val.nums; - if(p.prec < 0) - /* "A negative precision is taken as if the precision were - omitted." */ - p.prec = -1; - } - else if(p.flags & FLAGS_PREC) - p.prec = optr->precision; - else - p.prec = -1; - - switch(iptr->type) { - case MTYPE_INTU: - case MTYPE_LONGU: - case MTYPE_LONGLONGU: - p.flags |= FLAGS_UNSIGNED; - if(out_number(userp, stream, &p, iptr->val.numu, 0, work, &done)) - return done; - break; - - case MTYPE_INT: - case MTYPE_LONG: - case MTYPE_LONGLONG: - if(out_number(userp, stream, &p, iptr->val.numu, - iptr->val.nums, work, &done)) - return done; - break; - - case MTYPE_STRING: - if(out_string(userp, stream, &p, iptr->val.str, &done)) - return done; - break; - - case MTYPE_PTR: - if(out_pointer(userp, stream, &p, iptr->val.ptr, work, &done)) - return done; - break; - - case MTYPE_DOUBLE: - if(out_double(userp, stream, &p, iptr->val.dnum, work, &done)) - return done; - break; - - case MTYPE_INTPTR: - /* Answer the count of characters written. */ - if(p.flags & FLAGS_LONGLONG) - *(int64_t *)iptr->val.ptr = (int64_t)done; - else - if(p.flags & FLAGS_LONG) - *(long *)iptr->val.ptr = (long)done; - else if(!(p.flags & FLAGS_SHORT)) - *(int *)iptr->val.ptr = done; - else - *(short *)iptr->val.ptr = (short)done; - break; - - default: - break; - } - } - return done; -} - -/* fputc() look-alike */ -static int addbyter(unsigned char outc, void *f) -{ - struct nsprintf *infop = f; - if(infop->length < infop->max) { - /* only do this if we have not reached max length yet */ - *infop->buffer++ = (char)outc; /* store */ - infop->length++; /* we are now one byte larger */ - return 0; /* fputc() returns like this on success */ - } - return 1; -} - -int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, - va_list args) -{ - int retcode; - struct nsprintf info; - - info.buffer = buffer; - info.length = 0; - info.max = maxlength; - - retcode = formatf(&info, addbyter, format, args); - if(info.max) { - /* we terminate this with a zero byte */ - if(info.max == info.length) { - /* we are at maximum, scrap the last letter */ - info.buffer[-1] = 0; - DEBUGASSERT(retcode); - retcode--; /* do not count the nul byte */ - } - else - info.buffer[0] = 0; - } - return retcode; -} - -int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...) -{ - int retcode; - va_list args; /* argument pointer */ - va_start(args, format); - retcode = curl_mvsnprintf(buffer, maxlength, format, args); - va_end(args); - return retcode; -} - -/* fputc() look-alike */ -static int alloc_addbyter(unsigned char outc, void *f) -{ - struct asprintf *infop = f; - CURLcode result = curlx_dyn_addn(infop->b, &outc, 1); - if(result) { - infop->merr = result == CURLE_TOO_LARGE ? MERR_TOO_LARGE : MERR_MEM; - return 1; /* fail */ - } - return 0; -} - -/* appends the formatted string, returns MERR error code */ -int curlx_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list args) -{ - struct asprintf info; - info.b = dyn; - info.merr = MERR_OK; - - (void)formatf(&info, alloc_addbyter, format, args); - if(info.merr) { - curlx_dyn_free(info.b); - return info.merr; - } - return 0; -} - -char *curl_mvaprintf(const char *format, va_list args) -{ - struct asprintf info; - struct dynbuf dyn; - info.b = &dyn; - curlx_dyn_init(info.b, DYN_APRINTF); - info.merr = MERR_OK; - - (void)formatf(&info, alloc_addbyter, format, args); - if(info.merr) { - curlx_dyn_free(info.b); - return NULL; - } - if(curlx_dyn_len(info.b)) - return curlx_dyn_ptr(info.b); - return curlx_strdup(""); -} - -char *curl_maprintf(const char *format, ...) -{ - va_list args; - char *s; - va_start(args, format); - s = curl_mvaprintf(format, args); - va_end(args); - return s; -} - -static int storebuffer(unsigned char outc, void *f) -{ - char **buffer = f; - **buffer = (char)outc; - (*buffer)++; - return 0; -} - -int curl_msprintf(char *buffer, const char *format, ...) -{ - va_list args; /* argument pointer */ - int retcode; - va_start(args, format); - retcode = formatf(&buffer, storebuffer, format, args); - va_end(args); - *buffer = 0; /* we terminate this with a zero byte */ - return retcode; -} - -static int fputc_wrapper(unsigned char outc, void *f) -{ - int out = outc; - FILE *s = f; - int rc = fputc(out, s); - return rc == EOF; -} - -int curl_mprintf(const char *format, ...) -{ - int retcode; - va_list args; /* argument pointer */ - va_start(args, format); - retcode = formatf(stdout, fputc_wrapper, format, args); - va_end(args); - return retcode; -} - -int curl_mfprintf(FILE *fd, const char *format, ...) -{ - int retcode; - va_list args; /* argument pointer */ - va_start(args, format); - retcode = formatf(fd, fputc_wrapper, format, args); - va_end(args); - return retcode; -} - -int curl_mvsprintf(char *buffer, const char *format, va_list args) -{ - int retcode = formatf(&buffer, storebuffer, format, args); - *buffer = 0; /* we terminate this with a zero byte */ - return retcode; -} - -int curl_mvprintf(const char *format, va_list args) -{ - return formatf(stdout, fputc_wrapper, format, args); -} - -int curl_mvfprintf(FILE *fd, const char *format, va_list args) -{ - return formatf(fd, fputc_wrapper, format, args); -} diff --git a/vendor/curl/lib/mqtt.c b/vendor/curl/lib/mqtt.c deleted file mode 100644 index 84fd272e2..000000000 --- a/vendor/curl/lib/mqtt.c +++ /dev/null @@ -1,1012 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Björn Stenberg, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" - -#ifndef CURL_DISABLE_MQTT - -#include "transfer.h" -#include "sendf.h" -#include "curl_trc.h" -#include "progress.h" -#include "mqtt.h" -#include "select.h" -#include "url.h" -#include "escape.h" -#include "rand.h" -#include "cfilters.h" -#include "connect.h" - -/* first byte is command. - second byte is for flags. */ -#define MQTT_MSG_CONNECT 0x10 -/* #define MQTT_MSG_CONNACK 0x20 */ -#define MQTT_MSG_PUBLISH 0x30 -#define MQTT_MSG_SUBSCRIBE 0x82 -#define MQTT_MSG_SUBACK 0x90 -#define MQTT_MSG_DISCONNECT 0xe0 -/* #define MQTT_MSG_PINGREQ 0xC0 */ -#define MQTT_MSG_PINGRESP 0xD0 - -#define MQTT_CONNACK_LEN 2 -#define MQTT_SUBACK_LEN 3 -#define MQTT_CLIENTID_LEN 12 /* "curl0123abcd" */ - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_MQTT_EASY "meta:proto:mqtt:easy" -/* meta key for storing protocol meta at connection */ -#define CURL_META_MQTT_CONN "meta:proto:mqtt:conn" - -enum mqttstate { - MQTT_FIRST, /* 0 */ - MQTT_REMAINING_LENGTH, /* 1 */ - MQTT_CONNACK, /* 2 */ - MQTT_SUBACK, /* 3 */ - MQTT_SUBACK_COMING, /* 4 - the SUBACK remainder */ - MQTT_PUBWAIT, /* 5 - wait for publish */ - MQTT_PUB_REMAIN, /* 6 - wait for the remainder of the publish */ - - MQTT_NOSTATE /* 7 - never used an actual state */ -}; - -struct mqtt_conn { - enum mqttstate state; - enum mqttstate nextstate; /* switch to this after remaining length is - done */ - unsigned int packetid; -}; - -/* protocol-specific transfer-related data */ -struct MQTT { - struct dynbuf sendbuf; - /* when receiving */ - struct dynbuf recvbuf; - size_t npacket; /* byte counter */ - size_t remaining_length; - unsigned char pkt_hd[4]; /* for decoding the arriving packet length */ - struct curltime lastTime; /* last time we sent or received data */ - unsigned char firstbyte; - BIT(pingsent); /* 1 while we wait for ping response */ -}; - -static void mqtt_easy_dtor(void *key, size_t klen, void *entry) -{ - struct MQTT *mq = entry; - (void)key; - (void)klen; - curlx_dyn_free(&mq->sendbuf); - curlx_dyn_free(&mq->recvbuf); - curlx_free(mq); -} - -static void mqtt_conn_dtor(void *key, size_t klen, void *entry) -{ - (void)key; - (void)klen; - curlx_free(entry); -} - -static CURLcode mqtt_setup_conn(struct Curl_easy *data, - struct connectdata *conn) -{ - /* setup MQTT specific meta data at easy handle and connection */ - struct mqtt_conn *mqtt; - struct MQTT *mq; - - mqtt = curlx_calloc(1, sizeof(*mqtt)); - if(!mqtt || - Curl_conn_meta_set(conn, CURL_META_MQTT_CONN, mqtt, mqtt_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - mq = curlx_calloc(1, sizeof(struct MQTT)); - if(!mq) - return CURLE_OUT_OF_MEMORY; - curlx_dyn_init(&mq->recvbuf, DYN_MQTT_RECV); - curlx_dyn_init(&mq->sendbuf, DYN_MQTT_SEND); - if(Curl_meta_set(data, CURL_META_MQTT_EASY, mq, mqtt_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -} - -static CURLcode mqtt_send(struct Curl_easy *data, - const char *buf, size_t len) -{ - size_t n; - CURLcode result; - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - - if(!mq) - return CURLE_FAILED_INIT; - - result = Curl_xfer_send(data, buf, len, FALSE, &n); - if(result) - return result; - mq->lastTime = *Curl_pgrs_now(data); - Curl_debug(data, CURLINFO_HEADER_OUT, buf, n); - if(len != n) { - size_t nsend = len - n; - if(curlx_dyn_len(&mq->sendbuf)) { - DEBUGASSERT(curlx_dyn_len(&mq->sendbuf) >= nsend); - result = curlx_dyn_tail(&mq->sendbuf, nsend); /* keep this much */ - } - else { - result = curlx_dyn_addn(&mq->sendbuf, &buf[n], nsend); - } - } - else - curlx_dyn_reset(&mq->sendbuf); - return result; -} - -/* Generic function called by the multi interface to figure out what socket(s) - to wait for and for what actions during the DOING and PROTOCONNECT - states */ -static CURLcode mqtt_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]); -} - -static int mqtt_encode_len(char *buf, size_t len) -{ - int i; - - for(i = 0; (len > 0) && (i < 4); i++) { - unsigned char encoded; - encoded = len % 0x80; - len /= 0x80; - if(len) - encoded |= 0x80; - buf[i] = (char)encoded; - } - - return i; -} - -/* add the passwd to the CONNECT packet */ -static int add_passwd(const char *passwd, const size_t plen, - char *pkt, const size_t start, int remain_pos) -{ - /* magic number that need to be set properly */ - const size_t conn_flags_pos = remain_pos + 8; - if(plen > 0xffff) - return 1; - - /* set password flag */ - pkt[conn_flags_pos] |= 0x40; - - /* length of password provided */ - pkt[start] = (char)((plen >> 8) & 0xFF); - pkt[start + 1] = (char)(plen & 0xFF); - memcpy(&pkt[start + 2], passwd, plen); - return 0; -} - -/* add user to the CONNECT packet */ -static int add_user(const char *username, const size_t ulen, - unsigned char *pkt, const size_t start, int remain_pos) -{ - /* magic number that need to be set properly */ - const size_t conn_flags_pos = remain_pos + 8; - if(ulen > 0xffff) - return 1; - - /* set username flag */ - pkt[conn_flags_pos] |= 0x80; - /* length of username provided */ - pkt[start] = (unsigned char)((ulen >> 8) & 0xFF); - pkt[start + 1] = (unsigned char)(ulen & 0xFF); - memcpy(&pkt[start + 2], username, ulen); - return 0; -} - -/* add client ID to the CONNECT packet */ -static int add_client_id(const char *client_id, const size_t client_id_len, - char *pkt, const size_t start) -{ - if(client_id_len != MQTT_CLIENTID_LEN) - return 1; - pkt[start] = 0x00; - pkt[start + 1] = MQTT_CLIENTID_LEN; - memcpy(&pkt[start + 2], client_id, MQTT_CLIENTID_LEN); - return 0; -} - -/* Set initial values of CONNECT packet */ -static int init_connpack(char *packet, char *remain, int remain_pos) -{ - /* Fixed header starts */ - /* packet type */ - packet[0] = MQTT_MSG_CONNECT; - /* remaining length field */ - memcpy(&packet[1], remain, remain_pos); - /* Fixed header ends */ - - /* Variable header starts */ - /* protocol length */ - packet[remain_pos + 1] = 0x00; - packet[remain_pos + 2] = 0x04; - /* protocol name */ - packet[remain_pos + 3] = 'M'; - packet[remain_pos + 4] = 'Q'; - packet[remain_pos + 5] = 'T'; - packet[remain_pos + 6] = 'T'; - /* protocol level */ - packet[remain_pos + 7] = 0x04; - /* CONNECT flag: CleanSession */ - packet[remain_pos + 8] = 0x02; - /* keep-alive 0 = disabled */ - packet[remain_pos + 9] = 0x00; - packet[remain_pos + 10] = 0x3c; - /* end of variable header */ - return remain_pos + 10; -} - -static CURLcode mqtt_connect(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - int pos = 0; - int rc = 0; - /* remain length */ - int remain_pos = 0; - char remain[4] = { 0 }; - size_t packetlen = 0; - size_t start_user = 0; - size_t start_pwd = 0; - char client_id[MQTT_CLIENTID_LEN + 1] = "curl"; - const size_t clen = strlen("curl"); - char *packet = NULL; - - /* extracting username from request */ - const char *username = data->state.aptr.user ? data->state.aptr.user : ""; - const size_t ulen = strlen(username); - /* extracting password from request */ - const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : ""; - const size_t plen = strlen(passwd); - const size_t payloadlen = ulen + plen + MQTT_CLIENTID_LEN + 2 + - /* The plus 2s below are for the MSB and LSB describing the length of the - string to be added on the payload. Refer to spec 1.5.2 and 1.5.4 */ - (ulen ? 2 : 0) + - (plen ? 2 : 0); - - /* getting how much occupy the remain length */ - remain_pos = mqtt_encode_len(remain, payloadlen + 10); - - /* 10 length of variable header and 1 the first byte of the fixed header */ - packetlen = payloadlen + 10 + remain_pos + 1; - - /* allocating packet */ - if(packetlen > 0xFFFFFFF) - return CURLE_WEIRD_SERVER_REPLY; - packet = curlx_calloc(1, packetlen); - if(!packet) - return CURLE_OUT_OF_MEMORY; - - /* set initial values for the CONNECT packet */ - pos = init_connpack(packet, remain, remain_pos); - - result = Curl_rand_alnum(data, (unsigned char *)&client_id[clen], - MQTT_CLIENTID_LEN - clen + 1); - /* add client id */ - rc = add_client_id(client_id, strlen(client_id), packet, pos + 1); - if(rc) { - failf(data, "Client ID length mismatched: [%zu]", strlen(client_id)); - result = CURLE_WEIRD_SERVER_REPLY; - goto end; - } - infof(data, "Using client id '%s'", client_id); - - /* position where the user payload starts */ - start_user = pos + 3 + MQTT_CLIENTID_LEN; - /* position where the password payload starts */ - start_pwd = start_user + ulen; - /* if username was provided, add it to the packet */ - if(ulen) { - start_pwd += 2; - - rc = add_user(username, ulen, - (unsigned char *)packet, start_user, remain_pos); - if(rc) { - failf(data, "Username too long: [%zu]", ulen); - result = CURLE_WEIRD_SERVER_REPLY; - goto end; - } - } - - /* if passwd was provided, add it to the packet */ - if(plen) { - rc = add_passwd(passwd, plen, packet, start_pwd, remain_pos); - if(rc) { - failf(data, "Password too long: [%zu]", plen); - result = CURLE_WEIRD_SERVER_REPLY; - goto end; - } - } - - if(!result) - result = mqtt_send(data, packet, packetlen); - -end: - if(packet) - curlx_free(packet); - curlx_safefree(data->state.aptr.user); - curlx_safefree(data->state.aptr.passwd); - return result; -} - -static CURLcode mqtt_disconnect(struct Curl_easy *data) -{ - return mqtt_send(data, "\xe0\x00", 2); -} - -static CURLcode mqtt_recv_atleast(struct Curl_easy *data, size_t nbytes) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - size_t rlen; - CURLcode result; - - if(!mq) - return CURLE_FAILED_INIT; - rlen = curlx_dyn_len(&mq->recvbuf); - - if(rlen < nbytes) { - unsigned char readbuf[1024]; - size_t nread; - - DEBUGASSERT(nbytes - rlen < sizeof(readbuf)); - result = Curl_xfer_recv(data, (char *)readbuf, nbytes - rlen, &nread); - if(result) - return result; - if(!nread) /* EOF */ - return CURLE_RECV_ERROR; - if(curlx_dyn_addn(&mq->recvbuf, readbuf, nread)) - return CURLE_OUT_OF_MEMORY; - rlen = curlx_dyn_len(&mq->recvbuf); - } - return (rlen >= nbytes) ? CURLE_OK : CURLE_AGAIN; -} - -static void mqtt_recv_consume(struct Curl_easy *data, size_t nbytes) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - DEBUGASSERT(mq); - if(mq) { - size_t rlen = curlx_dyn_len(&mq->recvbuf); - if(rlen <= nbytes) - curlx_dyn_reset(&mq->recvbuf); - else - curlx_dyn_tail(&mq->recvbuf, rlen - nbytes); - } -} - -static CURLcode mqtt_verify_connack(struct Curl_easy *data) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - CURLcode result; - const char *ptr; - - DEBUGASSERT(mq); - if(!mq) - return CURLE_FAILED_INIT; - if(mq->remaining_length != 2) { - failf(data, "CONNACK expected Remaining Length 2, got %zu", - mq->remaining_length); - return CURLE_WEIRD_SERVER_REPLY; - } - - result = mqtt_recv_atleast(data, MQTT_CONNACK_LEN); - if(result) - return result; - - /* verify CONNACK */ - DEBUGASSERT(curlx_dyn_len(&mq->recvbuf) >= MQTT_CONNACK_LEN); - ptr = curlx_dyn_ptr(&mq->recvbuf); - Curl_debug(data, CURLINFO_HEADER_IN, ptr, MQTT_CONNACK_LEN); - - if(ptr[0] != 0x00 || ptr[1] != 0x00) { - failf(data, "Expected %02x%02x but got %02x%02x", - 0x00, 0x00, ptr[0], ptr[1]); - curlx_dyn_reset(&mq->recvbuf); - return CURLE_WEIRD_SERVER_REPLY; - } - mqtt_recv_consume(data, MQTT_CONNACK_LEN); - return CURLE_OK; -} - -static CURLcode mqtt_get_topic(struct Curl_easy *data, - char **topic, size_t *topiclen) -{ - const char *path = data->state.up.path; - CURLcode result = CURLE_URL_MALFORMAT; - if(strlen(path) > 1) { - result = Curl_urldecode(path + 1, 0, topic, topiclen, REJECT_NADA); - if(!result && (*topiclen > 0xffff)) { - failf(data, "Too long MQTT topic"); - result = CURLE_URL_MALFORMAT; - } - } - else - failf(data, "No MQTT topic found. Forgot to URL encode it?"); - - return result; -} - -static CURLcode mqtt_subscribe(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - char *topic = NULL; - size_t topiclen; - unsigned char *packet = NULL; - size_t packetlen; - char encodedsize[4]; - size_t n; - struct connectdata *conn = data->conn; - struct mqtt_conn *mqtt = Curl_conn_meta_get(conn, CURL_META_MQTT_CONN); - - if(!mqtt) - return CURLE_FAILED_INIT; - - result = mqtt_get_topic(data, &topic, &topiclen); - if(result) - goto fail; - - mqtt->packetid++; - - packetlen = topiclen + 5; /* packetid + topic (has a two byte length field) - + 2 bytes topic length + QoS byte */ - n = mqtt_encode_len((char *)encodedsize, packetlen); - packetlen += n + 1; /* add one for the control packet type byte */ - - packet = curlx_malloc(packetlen); - if(!packet) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - packet[0] = MQTT_MSG_SUBSCRIBE; - memcpy(&packet[1], encodedsize, n); - packet[1 + n] = (mqtt->packetid >> 8) & 0xff; - packet[2 + n] = mqtt->packetid & 0xff; - packet[3 + n] = (topiclen >> 8) & 0xff; - packet[4 + n] = topiclen & 0xff; - memcpy(&packet[5 + n], topic, topiclen); - packet[5 + n + topiclen] = 0; /* QoS zero */ - - result = mqtt_send(data, (const char *)packet, packetlen); - -fail: - curlx_free(topic); - curlx_free(packet); - return result; -} - -/* - * Called when the first byte was already read. - */ -static CURLcode mqtt_verify_suback(struct Curl_easy *data) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - struct connectdata *conn = data->conn; - struct mqtt_conn *mqtt = Curl_conn_meta_get(conn, CURL_META_MQTT_CONN); - CURLcode result; - const char *ptr; - - if(!mqtt || !mq) - return CURLE_FAILED_INIT; - - if(mq->remaining_length != 3) { - failf(data, "SUBACK expected Remaining Length 3, got %zu", - mq->remaining_length); - return CURLE_WEIRD_SERVER_REPLY; - } - - result = mqtt_recv_atleast(data, MQTT_SUBACK_LEN); - if(result) - goto fail; - - /* verify SUBACK */ - DEBUGASSERT(curlx_dyn_len(&mq->recvbuf) >= MQTT_SUBACK_LEN); - ptr = curlx_dyn_ptr(&mq->recvbuf); - Curl_debug(data, CURLINFO_HEADER_IN, ptr, MQTT_SUBACK_LEN); - - if(((unsigned char)ptr[0]) != ((mqtt->packetid >> 8) & 0xff) || - ((unsigned char)ptr[1]) != (mqtt->packetid & 0xff) || - ptr[2] != 0x00) { - curlx_dyn_reset(&mq->recvbuf); - result = CURLE_WEIRD_SERVER_REPLY; - goto fail; - } - mqtt_recv_consume(data, MQTT_SUBACK_LEN); -fail: - return result; -} - -#define MAX_MQTT_MESSAGE_SIZE 0xFFFFFFF - -static CURLcode mqtt_publish(struct Curl_easy *data) -{ - CURLcode result; - char *payload = data->set.postfields; - size_t payloadlen; - char *topic = NULL; - size_t topiclen; - unsigned char *pkt = NULL; - size_t i = 0; - size_t remaininglength; - size_t encodelen; - char encodedbytes[4]; - curl_off_t postfieldsize = data->set.postfieldsize; - - if(!payload) { - DEBUGF(infof(data, "mqtt_publish without payload, return bad arg")); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(!curlx_sotouz_fits(postfieldsize, &payloadlen)) { - if(postfieldsize > 0) /* off_t does not fit into size_t */ - return CURLE_BAD_FUNCTION_ARGUMENT; - payloadlen = strlen(payload); - } - - result = mqtt_get_topic(data, &topic, &topiclen); - if(result) - goto fail; - - remaininglength = payloadlen + 2 + topiclen; - encodelen = mqtt_encode_len(encodedbytes, remaininglength); - if(remaininglength > (MAX_MQTT_MESSAGE_SIZE - encodelen - 1)) { - result = CURLE_TOO_LARGE; - goto fail; - } - - /* add the control byte and the encoded remaining length */ - pkt = curlx_malloc(remaininglength + 1 + encodelen); - if(!pkt) { - result = CURLE_OUT_OF_MEMORY; - goto fail; - } - - /* assemble packet */ - pkt[i++] = MQTT_MSG_PUBLISH; - memcpy(&pkt[i], encodedbytes, encodelen); - i += encodelen; - pkt[i++] = (topiclen >> 8) & 0xff; - pkt[i++] = (topiclen & 0xff); - memcpy(&pkt[i], topic, topiclen); - i += topiclen; - memcpy(&pkt[i], payload, payloadlen); - i += payloadlen; - result = mqtt_send(data, (const char *)pkt, i); - -fail: - curlx_free(pkt); - curlx_free(topic); - return result; -} - -/* return 0 on success, non-zero on error */ -static int mqtt_decode_len(size_t *lenp, const unsigned char *buf, - size_t buflen) -{ - size_t len = 0; - size_t mult = 1; - size_t i; - unsigned char encoded = 128; - - for(i = 0; (i < buflen) && (encoded & 128); i++) { - if(i == 4) - return 1; /* bad size */ - encoded = buf[i]; - len += (encoded & 127) * mult; - mult *= 128; - } - - *lenp = len; - return 0; -} - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) -static const char *statenames[] = { - "MQTT_FIRST", - "MQTT_REMAINING_LENGTH", - "MQTT_CONNACK", - "MQTT_SUBACK", - "MQTT_SUBACK_COMING", - "MQTT_PUBWAIT", - "MQTT_PUB_REMAIN", - - "NOT A STATE" -}; -#endif - -/* The only way to change state */ -static void mqstate(struct Curl_easy *data, - enum mqttstate state, - enum mqttstate nextstate) /* used if state == FIRST */ -{ - struct connectdata *conn = data->conn; - struct mqtt_conn *mqtt = Curl_conn_meta_get(conn, CURL_META_MQTT_CONN); - DEBUGASSERT(mqtt); - if(!mqtt) - return; -#ifdef DEBUGBUILD - infof(data, "%s (from %s) (next is %s)", - statenames[state], - statenames[mqtt->state], - (state == MQTT_FIRST) ? statenames[nextstate] : ""); -#endif - mqtt->state = state; - if(state == MQTT_FIRST) - mqtt->nextstate = nextstate; -} - -static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - size_t nread; - size_t remlen; - struct mqtt_conn *mqtt = Curl_conn_meta_get(conn, CURL_META_MQTT_CONN); - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - unsigned char packet; - - DEBUGASSERT(mqtt); - if(!mqtt || !mq) - return CURLE_FAILED_INIT; - - switch(mqtt->state) { -MQTT_SUBACK_COMING: - case MQTT_SUBACK_COMING: - result = mqtt_verify_suback(data); - if(result) - break; - - mqstate(data, MQTT_FIRST, MQTT_PUBWAIT); - break; - - case MQTT_SUBACK: - case MQTT_PUBWAIT: - /* we are expecting PUBLISH or SUBACK */ - packet = mq->firstbyte & 0xf0; - if(packet == MQTT_MSG_PUBLISH) - mqstate(data, MQTT_PUB_REMAIN, MQTT_NOSTATE); - else if(packet == MQTT_MSG_SUBACK) { - mqstate(data, MQTT_SUBACK_COMING, MQTT_NOSTATE); - goto MQTT_SUBACK_COMING; - } - else if(packet == MQTT_MSG_DISCONNECT) { - infof(data, "Got DISCONNECT"); - *done = TRUE; - goto end; - } - else { - result = CURLE_WEIRD_SERVER_REPLY; - goto end; - } - - /* -- switched state -- */ - remlen = mq->remaining_length; - infof(data, "Remaining length: %zu bytes", remlen); - if(data->set.max_filesize && - (curl_off_t)remlen > data->set.max_filesize) { - failf(data, "Maximum file size exceeded"); - result = CURLE_FILESIZE_EXCEEDED; - goto end; - } - Curl_pgrsSetDownloadSize(data, remlen); - data->req.bytecount = 0; - data->req.size = remlen; - mq->npacket = remlen; /* get this many bytes */ - FALLTHROUGH(); - case MQTT_PUB_REMAIN: { - /* read rest of packet, but no more. Cap to buffer size */ - char buffer[4 * 1024]; - size_t rest = mq->npacket; - if(rest > sizeof(buffer)) - rest = sizeof(buffer); - result = Curl_xfer_recv(data, buffer, rest, &nread); - if(result) { - if(result == CURLE_AGAIN) { - infof(data, "EEEE AAAAGAIN"); - } - goto end; - } - if(!nread) { - infof(data, "server disconnected"); - result = CURLE_PARTIAL_FILE; - goto end; - } - - /* we received something */ - mq->lastTime = *Curl_pgrs_now(data); - - /* if QoS is set, message contains packet id */ - result = Curl_client_write(data, CLIENTWRITE_BODY, buffer, nread); - if(result) - goto end; - - mq->npacket -= nread; - if(!mq->npacket) - /* no more PUBLISH payload, back to subscribe wait state */ - mqstate(data, MQTT_FIRST, MQTT_PUBWAIT); - break; - } - default: - DEBUGASSERT(NULL); /* illegal state */ - result = CURLE_WEIRD_SERVER_REPLY; - goto end; - } -end: - return result; -} - -static CURLcode mqtt_do(struct Curl_easy *data, bool *done) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - CURLcode result = CURLE_OK; - *done = FALSE; /* unconditionally */ - - if(!mq) - return CURLE_FAILED_INIT; - mq->lastTime = *Curl_pgrs_now(data); - mq->pingsent = FALSE; - - result = mqtt_connect(data); - if(result) { - failf(data, "Error %d sending MQTT CONNECT request", result); - return result; - } - mqstate(data, MQTT_FIRST, MQTT_CONNACK); - return CURLE_OK; -} - -static CURLcode mqtt_done(struct Curl_easy *data, - CURLcode status, bool premature) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - (void)status; - (void)premature; - if(mq) { - curlx_dyn_free(&mq->sendbuf); - curlx_dyn_free(&mq->recvbuf); - } - return CURLE_OK; -} - -/* we ping regularly to avoid being disconnected by the server */ -static CURLcode mqtt_ping(struct Curl_easy *data) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct mqtt_conn *mqtt = Curl_conn_meta_get(conn, CURL_META_MQTT_CONN); - - if(!mqtt || !mq) - return CURLE_FAILED_INIT; - - if(mqtt->state == MQTT_FIRST && - !mq->pingsent && - data->set.upkeep_interval_ms > 0) { - struct curltime t = *Curl_pgrs_now(data); - timediff_t diff = curlx_ptimediff_ms(&t, &mq->lastTime); - - if(diff > data->set.upkeep_interval_ms) { - /* 0xC0 is PINGREQ, and 0x00 is remaining length */ - unsigned char packet[2] = { 0xC0, 0x00 }; - size_t packetlen = sizeof(packet); - - result = mqtt_send(data, (char *)packet, packetlen); - if(!result) { - mq->pingsent = TRUE; - } - infof(data, "mqtt_ping: sent ping request."); - } - } - return result; -} - -static CURLcode mqtt_doing(struct Curl_easy *data, bool *done) -{ - struct MQTT *mq = Curl_meta_get(data, CURL_META_MQTT_EASY); - CURLcode result = CURLE_OK; - size_t nread; - unsigned char recvbyte; - struct mqtt_conn *mqtt = Curl_conn_meta_get(data->conn, CURL_META_MQTT_CONN); - - if(!mqtt || !mq) - return CURLE_FAILED_INIT; - - *done = FALSE; - - if(curlx_dyn_len(&mq->sendbuf)) { - /* send the remainder of an outgoing packet */ - result = mqtt_send(data, curlx_dyn_ptr(&mq->sendbuf), - curlx_dyn_len(&mq->sendbuf)); - if(result) - return result; - } - - result = mqtt_ping(data); - if(result) - return result; - - infof(data, "mqtt_doing: state [%d]", (int)mqtt->state); - switch(mqtt->state) { - case MQTT_FIRST: - /* Read the initial byte only */ - result = Curl_xfer_recv(data, (char *)&mq->firstbyte, 1, &nread); - if(result) - break; - else if(!nread) { - failf(data, "Connection disconnected"); - *done = TRUE; - result = CURLE_RECV_ERROR; - break; - } - Curl_debug(data, CURLINFO_HEADER_IN, (const char *)&mq->firstbyte, 1); - - /* we received something */ - mq->lastTime = *Curl_pgrs_now(data); - - /* remember the first byte */ - mq->npacket = 0; - mqstate(data, MQTT_REMAINING_LENGTH, MQTT_NOSTATE); - FALLTHROUGH(); - case MQTT_REMAINING_LENGTH: - do { - result = Curl_xfer_recv(data, (char *)&recvbyte, 1, &nread); - if(result || !nread) - break; - Curl_debug(data, CURLINFO_HEADER_IN, (const char *)&recvbyte, 1); - mq->pkt_hd[mq->npacket++] = recvbyte; - } while((recvbyte & 0x80) && (mq->npacket < 4)); - if(!result && nread && (recvbyte & 0x80)) - /* MQTT supports up to 127 * 128^0 + 127 * 128^1 + 127 * 128^2 + - 127 * 128^3 bytes. server tried to send more */ - result = CURLE_WEIRD_SERVER_REPLY; - if(result) - break; - if(mqtt_decode_len(&mq->remaining_length, mq->pkt_hd, mq->npacket)) { - result = CURLE_WEIRD_SERVER_REPLY; - break; - } - mq->npacket = 0; - if(mq->remaining_length) { - mqstate(data, mqtt->nextstate, MQTT_NOSTATE); - break; - } - mqstate(data, MQTT_FIRST, MQTT_FIRST); - - if(mq->firstbyte == MQTT_MSG_DISCONNECT) { - infof(data, "Got DISCONNECT"); - *done = TRUE; - } - - /* ping response */ - if(mq->firstbyte == MQTT_MSG_PINGRESP) { - infof(data, "Received ping response."); - mq->pingsent = FALSE; - mqstate(data, MQTT_FIRST, MQTT_PUBWAIT); - } - break; - case MQTT_CONNACK: - result = mqtt_verify_connack(data); - if(result) - break; - - if(data->state.httpreq == HTTPREQ_POST) { - result = mqtt_publish(data); - if(!result) { - result = mqtt_disconnect(data); - *done = TRUE; - } - mqtt->nextstate = MQTT_FIRST; - } - else { - result = mqtt_subscribe(data); - if(!result) { - mqstate(data, MQTT_FIRST, MQTT_SUBACK); - } - } - break; - - case MQTT_SUBACK: - case MQTT_PUBWAIT: - case MQTT_PUB_REMAIN: - result = mqtt_read_publish(data, done); - break; - - default: - failf(data, "State not handled yet"); - *done = TRUE; - break; - } - - if(result == CURLE_AGAIN) - result = CURLE_OK; - return result; -} - -#ifdef USE_SSL - -static CURLcode mqtts_connecting(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - CURLcode result; - - result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done); - if(result) - connclose(conn, "Failed TLS connection"); - return result; -} - -/* - * MQTTS protocol. - */ -const struct Curl_protocol Curl_protocol_mqtts = { - mqtt_setup_conn, /* setup_connection */ - mqtt_do, /* do_it */ - mqtt_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - mqtts_connecting, /* connecting */ - mqtt_doing, /* doing */ - ZERO_NULL, /* proto_pollset */ - mqtt_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif - -/* - * MQTT protocol. - */ -const struct Curl_protocol Curl_protocol_mqtt = { - mqtt_setup_conn, /* setup_connection */ - mqtt_do, /* do_it */ - mqtt_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - mqtt_doing, /* doing */ - ZERO_NULL, /* proto_pollset */ - mqtt_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* CURL_DISABLE_MQTT */ diff --git a/vendor/curl/lib/mqtt.h b/vendor/curl/lib/mqtt.h deleted file mode 100644 index 3d95293f1..000000000 --- a/vendor/curl/lib/mqtt.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_MQTT_H -#define HEADER_CURL_MQTT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Björn Stenberg, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_MQTT -extern const struct Curl_protocol Curl_protocol_mqtt; -#ifdef USE_SSL -extern const struct Curl_protocol Curl_protocol_mqtts; -#endif -#endif - -#endif /* HEADER_CURL_MQTT_H */ diff --git a/vendor/curl/lib/multi.c b/vendor/curl/lib/multi.c deleted file mode 100644 index 7520253d7..000000000 --- a/vendor/curl/lib/multi.c +++ /dev/null @@ -1,4124 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "transfer.h" -#include "url.h" -#include "cfilters.h" -#include "connect.h" -#include "progress.h" -#include "curl_share.h" -#include "psl.h" -#include "multiif.h" -#include "multi_ev.h" -#include "sendf.h" -#include "curl_trc.h" -#include "http.h" -#include "select.h" -#include "curlx/wait.h" -#include "conncache.h" -#include "multihandle.h" -#include "sigpipe.h" -#include "vtls/vtls.h" -#include "vtls/vtls_scache.h" -#include "http_proxy.h" -#include "http2.h" -#include "socketpair.h" -#include "bufref.h" - -/* initial multi->xfers table size for a full multi */ -#define CURL_XFER_TABLE_SIZE 512 - -/* - CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97 - to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every - curl handle takes 6K memory, therefore this 3K are not significant. -*/ -#ifndef CURL_SOCKET_HASH_TABLE_SIZE -#define CURL_SOCKET_HASH_TABLE_SIZE 911 -#endif - -#ifndef CURL_CONNECTION_HASH_SIZE -#define CURL_CONNECTION_HASH_SIZE 97 -#endif - -#ifndef CURL_DNS_HASH_SIZE -#define CURL_DNS_HASH_SIZE 71 -#endif - -#ifndef CURL_TLS_SESSION_SIZE -#define CURL_TLS_SESSION_SIZE 25 -#endif - -#define CURL_MULTI_HANDLE 0x000bab1e - -#ifdef DEBUGBUILD -/* On a debug build, we want to fail hard on multi handles that - * are not NULL, but no longer have the MAGIC touch. This gives - * us early warning on things only discovered by valgrind otherwise. */ -#define GOOD_MULTI_HANDLE(x) \ - (((x) && (x)->magic == CURL_MULTI_HANDLE)? TRUE: \ - (DEBUGASSERT(!(x)), FALSE)) -#else -#define GOOD_MULTI_HANDLE(x) \ - ((x) && (x)->magic == CURL_MULTI_HANDLE) -#endif - -static void move_pending_to_connect(struct Curl_multi *multi, - struct Curl_easy *data); -static CURLMcode add_next_timeout(const struct curltime *pnow, - struct Curl_multi *multi, - struct Curl_easy *d); -static void multi_timeout(struct Curl_multi *multi, - struct curltime *expire_time, - long *timeout_ms); -static void process_pending_handles(struct Curl_multi *multi); -static void multi_xfer_bufs_free(struct Curl_multi *multi); -#ifdef DEBUGBUILD -static void multi_xfer_tbl_dump(struct Curl_multi *multi); -#endif - -static const struct curltime *multi_now(struct Curl_multi *multi) -{ - curlx_pnow(&multi->now); - return &multi->now; -} - -/* function pointer called once when switching TO a state */ -typedef void (*init_multistate_func)(struct Curl_easy *data); - -/* called in DID state, before PERFORMING state */ -static void before_perform(struct Curl_easy *data) -{ - data->req.chunk = FALSE; - Curl_pgrsTime(data, TIMER_PRETRANSFER); -} - -static void init_completed(struct Curl_easy *data) -{ - /* this is a completed transfer */ - - /* Important: reset the conn pointer so that we do not point to memory - that could be freed anytime */ - Curl_detach_connection(data); - Curl_expire_clear(data); /* stop all timers */ -} - -/* always use this function to change state, to make debugging easier */ -static void mstate(struct Curl_easy *data, CURLMstate state -#ifdef DEBUGBUILD - , int lineno -#endif -) -{ - CURLMstate oldstate = data->mstate; - static const init_multistate_func finit[MSTATE_LAST] = { - NULL, /* INIT */ - NULL, /* PENDING */ - NULL, /* SETUP */ - Curl_init_CONNECT, /* CONNECT */ - NULL, /* CONNECTING */ - NULL, /* PROTOCONNECT */ - NULL, /* PROTOCONNECTING */ - NULL, /* DO */ - NULL, /* DOING */ - NULL, /* DOING_MORE */ - before_perform, /* DID */ - NULL, /* PERFORMING */ - NULL, /* RATELIMITING */ - NULL, /* DONE */ - init_completed, /* COMPLETED */ - NULL /* MSGSENT */ - }; - - if(oldstate == state) - /* do not bother when the new state is the same as the old state */ - return; - -#ifdef DEBUGBUILD - NOVERBOSE((void)lineno); - CURL_TRC_M(data, "-> [%s] (line %d)", CURL_MSTATE_NAME(state), lineno); -#else - CURL_TRC_M(data, "-> [%s]", CURL_MSTATE_NAME(state)); -#endif - - /* really switching state */ - data->mstate = state; - switch(state) { - case MSTATE_DONE: - CURLM_NTFY(data, CURLMNOTIFY_EASY_DONE); - break; - case MSTATE_COMPLETED: - /* we sometimes directly jump to COMPLETED, trigger also a notification - * in that case. */ - if(oldstate < MSTATE_DONE) - CURLM_NTFY(data, CURLMNOTIFY_EASY_DONE); - /* changing to COMPLETED means it is in process and needs to go */ - DEBUGASSERT(Curl_uint32_bset_contains(&data->multi->process, data->mid)); - Curl_uint32_bset_remove(&data->multi->process, data->mid); - Curl_uint32_bset_remove(&data->multi->pending, data->mid); /* to be sure */ - - if(Curl_uint32_bset_empty(&data->multi->process)) { - /* free the transfer buffer when we have no more active transfers */ - multi_xfer_bufs_free(data->multi); - } - break; - default: - break; - } - - /* if this state has an init-function, run it */ - if(finit[state]) - finit[state](data); -} - -#ifndef DEBUGBUILD -#define multistate(x, y) mstate(x, y) -#else -#define multistate(x, y) mstate(x, y, __LINE__) -#endif - -/* multi->proto_hash destructor. Should never be called as elements - * MUST be added with their own destructor */ -static void ph_freeentry(void *p) -{ - (void)p; - /* Always FALSE. Cannot use a 0 assert here since compilers - * are not in agreement if they then want a NORETURN attribute or - * not. *sigh* */ - DEBUGASSERT(p == NULL); -} - -/* - * multi_addmsg() - * - * Called when a transfer is completed. Adds the given msg pointer to - * the list kept in the multi handle. - */ -static void multi_addmsg(struct Curl_multi *multi, struct Curl_message *msg) -{ - if(!Curl_llist_count(&multi->msglist)) - CURLM_NTFY(multi->admin, CURLMNOTIFY_INFO_READ); - Curl_llist_append(&multi->msglist, msg, &msg->list); -} - -struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size, - size_t ev_hashsize, /* event hash */ - size_t chashsize, /* connection hash */ - size_t dnssize, /* dns hash */ - size_t sesssize) /* TLS session cache */ -{ - struct Curl_multi *multi = curlx_calloc(1, sizeof(struct Curl_multi)); - - if(!multi) - return NULL; - - multi->magic = CURL_MULTI_HANDLE; - - Curl_dnscache_init(&multi->dnscache, dnssize); - Curl_mntfy_init(multi); - Curl_multi_ev_init(multi, ev_hashsize); - Curl_uint32_tbl_init(&multi->xfers, NULL); - Curl_uint32_bset_init(&multi->process); - Curl_uint32_bset_init(&multi->dirty); - Curl_uint32_bset_init(&multi->pending); - Curl_uint32_bset_init(&multi->msgsent); - Curl_hash_init(&multi->proto_hash, 23, - Curl_hash_str, curlx_str_key_compare, ph_freeentry); - Curl_llist_init(&multi->msglist, NULL); - - multi->multiplexing = TRUE; - multi->max_concurrent_streams = 100; - multi->last_timeout_ms = -1; -#ifdef ENABLE_WAKEUP - multi->wakeup_pair[0] = CURL_SOCKET_BAD; - multi->wakeup_pair[1] = CURL_SOCKET_BAD; -#endif - - if(Curl_mntfy_resize(multi) || - Curl_uint32_bset_resize(&multi->process, xfer_table_size) || - Curl_uint32_bset_resize(&multi->pending, xfer_table_size) || - Curl_uint32_bset_resize(&multi->dirty, xfer_table_size) || - Curl_uint32_bset_resize(&multi->msgsent, xfer_table_size) || - Curl_uint32_tbl_resize(&multi->xfers, xfer_table_size)) - goto error; - - multi->admin = curl_easy_init(); - if(!multi->admin) - goto error; - /* Initialize admin handle to operate inside this multi */ - multi->admin->multi = multi; - multi->admin->state.internal = TRUE; - Curl_llist_init(&multi->admin->state.timeoutlist, NULL); - -#ifdef DEBUGBUILD - if(getenv("CURL_DEBUG")) - multi->admin->set.verbose = TRUE; -#endif - Curl_uint32_tbl_add(&multi->xfers, multi->admin, &multi->admin->mid); - Curl_uint32_bset_add(&multi->process, multi->admin->mid); - - if(Curl_cshutdn_init(&multi->cshutdn, multi)) - goto error; - - Curl_cpool_init(&multi->cpool, multi->admin, NULL, chashsize); - -#ifdef USE_SSL - if(Curl_ssl_scache_create(sesssize, 2, &multi->ssl_scache)) - goto error; -#else - (void)sesssize; -#endif - -#ifdef USE_WINSOCK - multi->wsa_event = WSACreateEvent(); - if(multi->wsa_event == WSA_INVALID_EVENT) - goto error; -#endif -#ifdef ENABLE_WAKEUP - /* When enabled, rely on this to work. We ignore this in previous - * versions, but that seems an unnecessary complication. */ - if(Curl_wakeup_init(multi->wakeup_pair, TRUE) < 0) - goto error; -#endif - - if(Curl_probeipv6(multi)) - goto error; - -#ifdef USE_RESOLV_THREADED - if(xfer_table_size < CURL_XFER_TABLE_SIZE) { /* easy multi */ - if(Curl_async_thrdd_multi_init(multi, 0, 2, 10)) - goto error; - } - else { /* real multi handle */ - if(Curl_async_thrdd_multi_init(multi, 0, 20, 2000)) - goto error; - } -#endif - - return multi; - -error: - -#ifdef USE_RESOLV_THREADED - Curl_async_thrdd_multi_destroy(multi, TRUE); -#endif - Curl_multi_ev_cleanup(multi); - Curl_hash_destroy(&multi->proto_hash); - Curl_dnscache_destroy(&multi->dnscache); - Curl_cpool_destroy(&multi->cpool); - Curl_cshutdn_destroy(&multi->cshutdn, multi->admin); -#ifdef USE_SSL - Curl_ssl_scache_destroy(multi->ssl_scache); -#endif - if(multi->admin) { - Curl_multi_ev_xfer_done(multi, multi->admin); - multi->admin->multi = NULL; - Curl_close(&multi->admin); - } - Curl_mntfy_cleanup(multi); - - Curl_uint32_bset_destroy(&multi->process); - Curl_uint32_bset_destroy(&multi->dirty); - Curl_uint32_bset_destroy(&multi->pending); - Curl_uint32_bset_destroy(&multi->msgsent); - Curl_uint32_tbl_destroy(&multi->xfers); -#ifdef ENABLE_WAKEUP - Curl_wakeup_destroy(multi->wakeup_pair); -#endif - - curlx_free(multi); - return NULL; -} - -CURLM *curl_multi_init(void) -{ - return Curl_multi_handle(CURL_XFER_TABLE_SIZE, - CURL_SOCKET_HASH_TABLE_SIZE, - CURL_CONNECTION_HASH_SIZE, - CURL_DNS_HASH_SIZE, - CURL_TLS_SESSION_SIZE); -} - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) -static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data) -{ - if(!multi->warned) { - infof(data, "!!! WARNING !!!"); - infof(data, "This is a debug build of libcurl, " - "do not use in production."); - multi->warned = TRUE; - } -} -#else -#define multi_warn_debug(x, y) Curl_nop_stmt -#endif - -bool Curl_is_connecting(struct Curl_easy *data) -{ - return data->mstate < MSTATE_DO; -} - -static CURLMcode multi_assess_wakeup(struct Curl_multi *multi) -{ -#ifdef ENABLE_WAKEUP - if(multi->socket_cb) - return Curl_multi_ev_assess_xfer(multi, multi->admin); -#else - (void)multi; -#endif - return CURLM_OK; -} - -static CURLMcode multi_xfers_add(struct Curl_multi *multi, - struct Curl_easy *data) -{ - uint32_t capacity = Curl_uint32_tbl_capacity(&multi->xfers); - uint32_t new_size = 0; - /* Prepare to make this into a CURLMOPT_MAX_TRANSFERS, because some - * applications may want to prevent a run-away of their memory use. */ - /* UINT_MAX is our "invalid" id, do not let the table grow up to that. */ - const uint32_t max_capacity = UINT_MAX - 1; - - if(capacity < max_capacity) { - /* We want `multi->xfers` to have "sufficient" free rows, so that we do - * have to reuse the `mid` from a removed easy right away. - * Since uint_tbl and uint_bset are memory efficient, - * regard less than 25% free as insufficient. - * (for low capacities, e.g. multi_easy, 4 or less). */ - uint32_t used = Curl_uint32_tbl_count(&multi->xfers); - uint32_t unused = capacity - used; - uint32_t min_unused = CURLMAX(capacity >> 2, 4); - if(unused <= min_unused) { - /* Make sure the uint arithmetic here works on the corner - * cases where we are close to max_capacity or UINT_MAX */ - if((min_unused >= max_capacity) || - ((max_capacity - min_unused) <= capacity) || - ((UINT_MAX - min_unused - 63) <= capacity)) { - new_size = max_capacity; /* can not be larger than this */ - } - else { - /* make it a 64 multiple, since our bitsets frow by that and - * small (easy_multi) grows to at least 64 on first resize. */ - new_size = (((used + min_unused) + 63) / 64) * 64; - } - } - } - - if(new_size > capacity) { - /* Grow the bitsets first. Should one fail, we do not need - * to downsize the already resized ones. The sets continue - * to work properly when larger than the table, but not - * the other way around. */ - CURL_TRC_M(data, "increasing xfer table size to %u", new_size); - if(Curl_uint32_bset_resize(&multi->process, new_size) || - Curl_uint32_bset_resize(&multi->dirty, new_size) || - Curl_uint32_bset_resize(&multi->pending, new_size) || - Curl_uint32_bset_resize(&multi->msgsent, new_size) || - Curl_uint32_tbl_resize(&multi->xfers, new_size)) - return CURLM_OUT_OF_MEMORY; - } - - /* Insert the easy into the table now */ - if(!Curl_uint32_tbl_add(&multi->xfers, data, &data->mid)) { - /* MUST only happen when table is full */ - DEBUGASSERT(Curl_uint32_tbl_capacity(&multi->xfers) <= - Curl_uint32_tbl_count(&multi->xfers)); - return CURLM_OUT_OF_MEMORY; - } - return CURLM_OK; -} - -CURLMcode curl_multi_add_handle(CURLM *m, CURL *curl) -{ - CURLMcode mresult; - struct Curl_multi *multi = m; - struct Curl_easy *data = curl; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - /* Verify that we got a somewhat good easy handle too */ - if(!GOOD_EASY_HANDLE(data)) - return CURLM_BAD_EASY_HANDLE; - - /* Prevent users from adding same easy handle more than once and prevent - adding to more than one multi stack */ - if(data->multi) - return CURLM_ADDED_ALREADY; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - if(multi->dead) { - /* a "dead" handle cannot get added transfers while any existing easy - handles are still alive - but if there are none alive anymore, it is - fine to start over and unmark the "deadness" of this handle. - This means only the admin handle MUST be present. */ - if((Curl_uint32_tbl_count(&multi->xfers) != 1) || - !Curl_uint32_tbl_contains(&multi->xfers, 0)) - return CURLM_ABORTED_BY_CALLBACK; - multi->dead = FALSE; - Curl_uint32_bset_clear(&multi->process); - Curl_uint32_bset_clear(&multi->dirty); - Curl_uint32_bset_clear(&multi->pending); - Curl_uint32_bset_clear(&multi->msgsent); - } - - if(data->multi_easy) { - /* if this easy handle was previously used for curl_easy_perform(), there - is a private multi handle here that we can kill */ - curl_multi_cleanup(data->multi_easy); - data->multi_easy = NULL; - } - - /* Insert the easy into the multi->xfers table, assigning it a `mid`. */ - if(multi_xfers_add(multi, data)) - return CURLM_OUT_OF_MEMORY; - - /* Initialize timeout list for this handle */ - Curl_llist_init(&data->state.timeoutlist, NULL); - - /* - * No failure allowed in this function beyond this point. No modification of - * easy nor multi handle allowed before this except for potential multi's - * connection pool growing which will not be undone in this function no - * matter what. - */ - if(data->set.errorbuffer) - data->set.errorbuffer[0] = 0; - - data->state.os_errno = 0; - - /* make the Curl_easy refer back to this multi handle - before Curl_expire() - is called. */ - data->multi = multi; - - /* set the easy handle */ - multistate(data, MSTATE_INIT); - -#ifdef USE_LIBPSL - /* Do the same for PSL. */ - if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL))) - data->psl = &data->share->psl; - else - data->psl = &multi->psl; -#endif - - /* add the easy handle to the process set */ - Curl_uint32_bset_add(&multi->process, data->mid); - ++multi->xfers_alive; - ++multi->xfers_total_ever; - - Curl_cpool_xfer_init(data); - multi_warn_debug(multi, data); - - /* Make sure the new handle will run */ - Curl_multi_mark_dirty(data); - - /* Necessary in event based processing, where dirty handles trigger - * a timeout callback invocation. */ - mresult = Curl_update_timer(multi); - if(mresult) { - data->multi = NULL; /* not anymore */ - Curl_uint32_tbl_remove(&multi->xfers, data->mid); - data->mid = UINT32_MAX; - return mresult; - } - - /* The admin handle only ever has default timeouts set. To improve the - state somewhat we clone the timeouts from each added handle so that the - admin handle always has the same timeouts as the most recently added - easy handle. */ - multi->admin->set.timeout = data->set.timeout; - multi->admin->set.server_response_timeout = - data->set.server_response_timeout; - multi->admin->set.no_signal = data->set.no_signal; - - mresult = multi_assess_wakeup(multi); - if(mresult) { - failf(data, "error enabling wakeup listening: %d", mresult); - return mresult; - } - - CURL_TRC_M(data, "added to multi, mid=%u, running=%u, total=%u", - data->mid, Curl_multi_xfers_running(multi), - Curl_uint32_tbl_count(&multi->xfers)); - return CURLM_OK; -} - -#if 0 -/* Debug-function, used like this: - * - * Curl_hash_print(&multi->sockhash, debug_print_sock_hash); - * - * Enable the hash print function first by editing hash.c - */ -static void debug_print_sock_hash(void *p) -{ - struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p; - - curl_mfprintf(stderr, " [readers %u][writers %u]", - sh->readers, sh->writers); -} -#endif - -struct multi_done_ctx { - BIT(premature); -}; - -static bool multi_conn_should_close(struct connectdata *conn, - struct Curl_easy *data, - bool premature) -{ - /* if conn->bits.close is TRUE, it means that the connection should be - closed in spite of everything else. */ - if(conn->bits.close) - return TRUE; - - /* if data->set.reuse_forbid is TRUE, it means the libcurl client has - forced us to close this connection. This is ignored for requests taking - place in a NTLM/NEGOTIATE authentication handshake. */ - if(data->set.reuse_forbid -#ifdef USE_NTLM - && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || - conn->proxy_ntlm_state == NTLMSTATE_TYPE2) -#endif -#ifdef USE_SPNEGO - && !(conn->http_negotiate_state == GSS_AUTHRECV || - conn->proxy_negotiate_state == GSS_AUTHRECV) -#endif - ) - return TRUE; - - /* Unless this connection is for a "connect-only" transfer, it - * needs to be closed if the protocol handler does not support reuse. */ - if(!data->set.connect_only && conn->scheme && - !(conn->scheme->flags & PROTOPT_CONN_REUSE)) - return TRUE; - - /* if premature is TRUE, it means this connection was said to be DONE before - the entire request operation is complete and thus we cannot know in what - state it is for reusing, so we are forced to close it. In a perfect world - we can add code that keep track of if we really must close it here or not, - but currently we have no such detail knowledge. */ - if(premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET)) - return TRUE; - - return FALSE; -} - -static void multi_done_locked(struct connectdata *conn, - struct Curl_easy *data, - void *userdata) -{ - struct multi_done_ctx *mdctx = userdata; - - Curl_detach_connection(data); - - CURL_TRC_M(data, "multi_done_locked, in use=%u", conn->attached_xfers); - if(CONN_INUSE(conn)) { - /* Stop if still used. */ - CURL_TRC_M(data, "Connection still in use %u, no more multi_done now!", - conn->attached_xfers); - return; - } - - data->state.done = TRUE; /* called now! */ - data->state.recent_conn_id = conn->connection_id; - - Curl_dnscache_prune(data); - - if(multi_conn_should_close(conn, data, (bool)mdctx->premature)) { - CURL_TRC_M(data, "multi_done, terminating conn #%" FMT_OFF_T " to %s, " - "forbid=%d, close=%d, premature=%d, conn_multiplex=%d", - conn->connection_id, conn->destination, - data->set.reuse_forbid, conn->bits.close, mdctx->premature, - Curl_conn_is_multiplex(conn, FIRSTSOCKET)); - connclose(conn, "disconnecting"); - Curl_conn_terminate(data, conn, (bool)mdctx->premature); - } - else if(!Curl_conn_get_max_concurrent(data, conn, FIRSTSOCKET)) { - CURL_TRC_M(data, "multi_done, conn #%" FMT_OFF_T " to %s was shutdown" - " by server, not reusing", conn->connection_id, - conn->destination); - connclose(conn, "server shutdown"); - Curl_conn_terminate(data, conn, (bool)mdctx->premature); - } - else { - /* the connection is no longer in use by any transfer */ - if(Curl_cpool_conn_now_idle(data, conn)) { - /* connection kept in the cpool */ - data->state.lastconnect_id = conn->connection_id; - infof(data, "Connection #%" FMT_OFF_T " to host %s left intact", - conn->connection_id, conn->destination); - } - else { - /* connection was removed from the cpool and destroyed. */ - data->state.lastconnect_id = -1; - } - } -} - -static CURLcode multi_done(struct Curl_easy *data, - CURLcode status, /* an error if this is called - after an error was detected */ - bool premature) -{ - CURLcode result; - struct connectdata *conn = data->conn; - - CURL_TRC_M(data, "multi_done: status: %d prem: %d done: %d", - (int)status, (int)premature, data->state.done); - - if(data->state.done) - /* Stop if multi_done() has already been called */ - return CURLE_OK; - - /* Shut down any ongoing async resolver operation. */ - Curl_resolv_shutdown_all(data); - - /* Cleanup possible redirect junk */ - curlx_safefree(data->req.newurl); - curlx_safefree(data->req.location); - - switch(status) { - case CURLE_ABORTED_BY_CALLBACK: - case CURLE_READ_ERROR: - case CURLE_WRITE_ERROR: - /* When we are aborted due to a callback return code it has to be counted - as premature as there is trouble ahead if we do not. We have many - callbacks and protocols work differently, we could potentially do this - more fine-grained in the future. */ - premature = TRUE; - FALLTHROUGH(); - default: - break; - } - - /* this calls the protocol-specific function pointer previously set */ - if(conn && conn->scheme->run->done && (data->mstate >= MSTATE_PROTOCONNECT)) - result = conn->scheme->run->done(data, status, premature); - else - result = status; - - if(data->mstate > MSTATE_CONNECTING && - (result != CURLE_ABORTED_BY_CALLBACK)) { - /* avoid this if - * - the transfer has not connected - * - we already aborted by callback to avoid this calling another callback - */ - int rc = Curl_pgrsDone(data); - if(!result && rc) - result = CURLE_ABORTED_BY_CALLBACK; - } - - /* Make sure that transfer client writes are really done now. */ - result = Curl_1st_fatal(result, Curl_xfer_write_done(data, premature)); - - /* Inform connection filters that this transfer is done */ - if(conn) - Curl_conn_ev_data_done(data, premature); - - process_pending_handles(data->multi); /* connection / multiplex */ - - if(!result) - result = Curl_req_done(&data->req, data, premature); - - if(conn) { - /* Under the potential connection pool's share lock, decide what to - * do with the transfer's connection. */ - struct multi_done_ctx mdctx; - - memset(&mdctx, 0, sizeof(mdctx)); - mdctx.premature = premature; - Curl_cpool_do_locked(data, data->conn, multi_done_locked, &mdctx); - } - - /* flush the netrc cache */ - Curl_netrc_cleanup(&data->state.netrc); - return result; -} - -static void close_connect_only(struct connectdata *conn, - struct Curl_easy *data, - void *userdata) -{ - (void)userdata; - (void)data; - if(conn->bits.connect_only) - connclose(conn, "Removing connect-only easy handle"); -} - -CURLMcode curl_multi_remove_handle(CURLM *m, CURL *curl) -{ - struct Curl_multi *multi = m; - struct Curl_easy *data = curl; - bool premature; - struct Curl_llist_node *e; - CURLMcode mresult; - uint32_t mid; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - /* Verify that we got a somewhat good easy handle too */ - if(!GOOD_EASY_HANDLE(data)) - return CURLM_BAD_EASY_HANDLE; - - /* Prevent users from trying to remove same easy handle more than once */ - if(!data->multi) - return CURLM_OK; /* it is already removed so let's say it is fine! */ - - /* Prevent users from trying to remove an easy handle from the wrong multi */ - if(data->multi != multi) - return CURLM_BAD_EASY_HANDLE; - - if(data->mid == UINT32_MAX) { - DEBUGASSERT(0); - return CURLM_INTERNAL_ERROR; - } - if(Curl_uint32_tbl_get(&multi->xfers, data->mid) != data) { - DEBUGASSERT(0); - return CURLM_INTERNAL_ERROR; - } - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - premature = (data->mstate < MSTATE_COMPLETED); - - /* If the 'state' is not INIT or COMPLETED, we might need to do something - nice to put the easy_handle in a good known state when this returns. */ - if(data->conn && - data->mstate > MSTATE_DO && - data->mstate < MSTATE_COMPLETED) { - /* Set connection owner so that the DONE function closes it. We can - safely do this here since connection is killed. */ - streamclose(data->conn, "Removed with partial response"); - } - - if(data->conn) { - /* multi_done() clears the association between the easy handle and the - connection. - - Note that this ignores the return code because there is - nothing really useful to do with it anyway! */ - (void)multi_done(data, data->result, premature); - } - - /* The timer must be shut down before data->multi is set to NULL, else the - timenode will remain in the splay tree after curl_easy_cleanup is - called. Do it after multi_done() in case that sets another time! */ - Curl_expire_clear(data); - - /* If in `msgsent`, it was deducted from `multi->xfers_alive` already. */ - if(!Curl_uint32_bset_contains(&multi->msgsent, data->mid)) - --multi->xfers_alive; - - Curl_wildcard_dtor(&data->wildcard); - - data->mstate = MSTATE_COMPLETED; - - /* Remove the association between the connection and the handle */ - Curl_detach_connection(data); - - /* Tell event handling that this transfer is definitely going away */ - Curl_multi_ev_xfer_done(multi, data); - - if(data->set.connect_only && !data->multi_easy) { - /* This removes a handle that was part the multi interface that used - CONNECT_ONLY, that connection is now left alive but since this handle - has bits.close set nothing can use that transfer anymore and it is - forbidden from reuse. This easy handle cannot find the connection - anymore once removed from the multi handle - - Better close the connection here, at once. - */ - struct connectdata *c; - curl_socket_t s; - s = Curl_getconnectinfo(data, &c); - if((s != CURL_SOCKET_BAD) && c) { - Curl_conn_terminate(data, c, TRUE); - } - } - - if(data->state.lastconnect_id != -1) { - /* Mark any connect-only connection for closure */ - Curl_cpool_do_by_id(data, data->state.lastconnect_id, - close_connect_only, NULL); - } - -#ifdef USE_LIBPSL - /* Remove the PSL association. */ - if(data->psl == &multi->psl) - data->psl = NULL; -#endif - - /* make sure there is no pending message in the queue sent from this easy - handle */ - for(e = Curl_llist_head(&multi->msglist); e; e = Curl_node_next(e)) { - struct Curl_message *msg = Curl_node_elem(e); - - if(msg->extmsg.easy_handle == data) { - Curl_node_remove(e); - /* there can only be one from this specific handle */ - break; - } - } - - /* clear the association to this multi handle */ - mid = data->mid; - DEBUGASSERT(Curl_uint32_tbl_contains(&multi->xfers, mid)); - Curl_uint32_tbl_remove(&multi->xfers, mid); - Curl_uint32_bset_remove(&multi->process, mid); - Curl_uint32_bset_remove(&multi->dirty, mid); - Curl_uint32_bset_remove(&multi->pending, mid); - Curl_uint32_bset_remove(&multi->msgsent, mid); - data->multi = NULL; - data->mid = UINT32_MAX; - data->master_mid = UINT32_MAX; - - /* NOTE NOTE NOTE - We do not touch the easy handle here! */ - process_pending_handles(multi); - - mresult = Curl_update_timer(multi); - if(mresult) - return mresult; - - mresult = multi_assess_wakeup(multi); - if(mresult) { - failf(data, "error enabling wakeup listening: %d", mresult); - return mresult; - } - - CURL_TRC_M(data, "removed from multi, mid=%u, running=%u, total=%u", - mid, Curl_multi_xfers_running(multi), - Curl_uint32_tbl_count(&multi->xfers)); - return CURLM_OK; -} - -/* Return TRUE if the application asked for multiplexing */ -bool Curl_multiplex_wanted(const struct Curl_multi *multi) -{ - return multi && multi->multiplexing; -} - -/* - * Curl_detach_connection() removes the given transfer from the connection. - * - * This is the only function that should clear data->conn. This will - * occasionally be called with the data->conn pointer already cleared. - */ -void Curl_detach_connection(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - if(conn) { - /* this should never happen, prevent underflow */ - DEBUGASSERT(conn->attached_xfers); - if(conn->attached_xfers) { - conn->attached_xfers--; - if(!conn->attached_xfers) - conn->attached_multi = NULL; - } - } - data->conn = NULL; -} - -/* - * Curl_attach_connection() attaches this transfer to this connection. - * - * This is the only function that should assign data->conn - */ -void Curl_attach_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - DEBUGASSERT(data); - DEBUGASSERT(!data->conn); - DEBUGASSERT(conn); - DEBUGASSERT(conn->attached_xfers < UINT32_MAX); - data->conn = conn; - conn->attached_xfers++; - /* all attached transfers must be from the same multi */ - if(!conn->attached_multi) - conn->attached_multi = data->multi; - DEBUGASSERT(conn->attached_multi == data->multi); - - if(conn->scheme && conn->scheme->run->attach) - conn->scheme->run->attach(data, conn); -} - -/* adjust pollset for rate limits/pauses */ -static CURLcode multi_adjust_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - CURLcode result = CURLE_OK; - - if(ps->n) { - const struct curltime *pnow = Curl_pgrs_now(data); - bool send_blocked, recv_blocked; - - recv_blocked = (Curl_rlimit_avail(&data->progress.dl.rlimit, pnow) <= 0); - send_blocked = (Curl_rlimit_avail(&data->progress.ul.rlimit, pnow) <= 0); - if(send_blocked || recv_blocked) { - int i; - for(i = 0; i <= SECONDARYSOCKET; ++i) { - curl_socket_t sock = data->conn->sock[i]; - if(sock == CURL_SOCKET_BAD) - continue; - if(recv_blocked && Curl_pollset_want_recv(data, ps, sock)) { - result = Curl_pollset_remove_in(data, ps, sock); - if(result) - break; - } - if(send_blocked && Curl_pollset_want_send(data, ps, sock)) { - result = Curl_pollset_remove_out(data, ps, sock); - if(result) - break; - } - } - } - - /* Not blocked and wanting to receive. If there is data pending - * in the connection filters, make transfer run again. */ - if(!recv_blocked && - ((Curl_pollset_want_recv(data, ps, data->conn->sock[FIRSTSOCKET]) && - Curl_conn_data_pending(data, FIRSTSOCKET)) || - (Curl_pollset_want_recv(data, ps, data->conn->sock[SECONDARYSOCKET]) && - Curl_conn_data_pending(data, SECONDARYSOCKET)))) { - CURL_TRC_M(data, "pollset[] has POLLIN, but there is still " - "buffered input -> mark as dirty"); - Curl_multi_mark_dirty(data); - } - } - return result; -} - -static CURLcode mstate_connecting_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - curl_socket_t sockfd; - CURLcode result = CURLE_OK; - - if(Curl_xfer_recv_is_paused(data)) - return CURLE_OK; - /* If a socket is set, receiving is default. If the socket - * has not been determined yet (eyeballing), always ask the - * connection filters for what to monitor. */ - sockfd = Curl_conn_get_first_socket(data); - if(sockfd != CURL_SOCKET_BAD) { - result = Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); - if(!result) - result = multi_adjust_pollset(data, ps); - } - if(!result) - result = Curl_conn_adjust_pollset(data, conn, ps); - return result; -} - -static CURLcode mstate_protocol_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - - if(conn->scheme->run->proto_pollset) - result = conn->scheme->run->proto_pollset(data, ps); - else { - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - if(sockfd != CURL_SOCKET_BAD) { - /* Default is to wait to something from the server */ - result = Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); - } - } - if(!result) - result = multi_adjust_pollset(data, ps); - if(!result) - result = Curl_conn_adjust_pollset(data, conn, ps); - return result; -} - -static CURLcode mstate_do_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - - if(conn->scheme->run->doing_pollset) - result = conn->scheme->run->doing_pollset(data, ps); - else if(CONN_SOCK_IDX_VALID(conn->send_idx)) { - /* Default is that we want to send something to the server */ - result = Curl_pollset_add_out(data, ps, conn->sock[conn->send_idx]); - } - if(!result) - result = multi_adjust_pollset(data, ps); - if(!result) - result = Curl_conn_adjust_pollset(data, conn, ps); - return result; -} - -static CURLcode mstate_domore_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - - if(conn->scheme->run->domore_pollset) - result = conn->scheme->run->domore_pollset(data, ps); - else if(CONN_SOCK_IDX_VALID(conn->send_idx)) { - /* Default is that we want to send something to the server */ - result = Curl_pollset_add_out(data, ps, conn->sock[conn->send_idx]); - } - if(!result) - result = multi_adjust_pollset(data, ps); - if(!result) - result = Curl_conn_adjust_pollset(data, conn, ps); - return result; -} - -static CURLcode mstate_perform_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - - if(conn->scheme->run->perform_pollset) - result = conn->scheme->run->perform_pollset(data, ps); - else { - /* Default is to obey the request flags for send/recv */ - if(Curl_req_want_recv(data) && CONN_SOCK_IDX_VALID(conn->recv_idx)) { - result = Curl_pollset_add_in(data, ps, conn->sock[conn->recv_idx]); - } - if(!result && Curl_req_want_send(data) && - CONN_SOCK_IDX_VALID(conn->send_idx)) { - result = Curl_pollset_add_out(data, ps, conn->sock[conn->send_idx]); - } - } - if(!result) - result = multi_adjust_pollset(data, ps); - if(!result) - result = Curl_conn_adjust_pollset(data, conn, ps); - return result; -} - -/* Initializes `poll_set` with the current socket poll actions needed - * for transfer `data`. */ -CURLMcode Curl_multi_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - CURLcode result = CURLE_OK; - - Curl_pollset_reset(ps); -#ifdef ENABLE_WAKEUP - /* The admin handle always listens on the wakeup socket when there - * are transfers alive. */ - if(data->multi && (data == data->multi->admin) && - data->multi->xfers_alive) { - result = Curl_pollset_add_in(data, ps, data->multi->wakeup_pair[0]); - } -#endif - /* If the transfer has no connection, this is fine. Happens when - called via curl_multi_remove_handle() => Curl_multi_ev_assess() => - Curl_multi_pollset(). */ - if(!result && data->conn) { - switch(data->mstate) { - case MSTATE_INIT: - case MSTATE_PENDING: - case MSTATE_SETUP: - case MSTATE_CONNECT: - /* nothing to poll for yet */ - break; - - case MSTATE_CONNECTING: - if(data->conn && !data->conn->bits.dns_resolved) - result = Curl_resolv_pollset(data, ps); - if(!result) - result = mstate_connecting_pollset(data, ps); - break; - - case MSTATE_PROTOCONNECT: - case MSTATE_PROTOCONNECTING: - result = mstate_protocol_pollset(data, ps); - break; - - case MSTATE_DO: - case MSTATE_DOING: - result = mstate_do_pollset(data, ps); - break; - - case MSTATE_DOING_MORE: - result = mstate_domore_pollset(data, ps); - break; - - case MSTATE_DID: /* same as PERFORMING in regard to polling */ - case MSTATE_PERFORMING: - result = mstate_perform_pollset(data, ps); - break; - - case MSTATE_RATELIMITING: - /* we need to let time pass, ignore socket(s) */ - break; - - case MSTATE_DONE: - case MSTATE_COMPLETED: - case MSTATE_MSGSENT: - /* nothing more to poll for */ - break; - - default: - failf(data, "multi_getsock: unexpected multi state %d", data->mstate); - DEBUGASSERT(0); - break; - } - } - - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - return CURLM_OUT_OF_MEMORY; - failf(data, "error determining pollset: %d", result); - return CURLM_INTERNAL_ERROR; - } - -#ifdef CURLVERBOSE - if(CURL_TRC_M_is_verbose(data)) { - size_t timeout_count = Curl_llist_count(&data->state.timeoutlist); - switch(ps->n) { - case 0: - CURL_TRC_M(data, "pollset[], timeouts=%zu, paused %d/%d (r/w)", - timeout_count, - Curl_xfer_send_is_paused(data), - Curl_xfer_recv_is_paused(data)); - break; - case 1: - CURL_TRC_M(data, "pollset[fd=%" FMT_SOCKET_T " %s%s], timeouts=%zu", - ps->sockets[0], - (ps->actions[0] & CURL_POLL_IN) ? "IN" : "", - (ps->actions[0] & CURL_POLL_OUT) ? "OUT" : "", - timeout_count); - break; - case 2: - CURL_TRC_M(data, "pollset[fd=%" FMT_SOCKET_T " %s%s, " - "fd=%" FMT_SOCKET_T " %s%s], timeouts=%zu", - ps->sockets[0], - (ps->actions[0] & CURL_POLL_IN) ? "IN" : "", - (ps->actions[0] & CURL_POLL_OUT) ? "OUT" : "", - ps->sockets[1], - (ps->actions[1] & CURL_POLL_IN) ? "IN" : "", - (ps->actions[1] & CURL_POLL_OUT) ? "OUT" : "", - timeout_count); - break; - default: - CURL_TRC_M(data, "pollset[fds=%u], timeouts=%zu", ps->n, timeout_count); - break; - } - CURL_TRC_EASY_TIMERS(data); - } -#endif - - return CURLM_OK; -} - -CURLMcode curl_multi_fdset(CURLM *m, - fd_set *read_fd_set, fd_set *write_fd_set, - fd_set *exc_fd_set, int *max_fd) -{ - /* Scan through all the easy handles to get the file descriptors set. - Some easy handles may not have connected to the remote host yet, - and then we must make sure that is done. */ - int this_max_fd = -1; - struct Curl_multi *multi = m; - struct easy_pollset ps; - unsigned int i; - uint32_t mid; - (void)exc_fd_set; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - Curl_pollset_init(&ps); - if(Curl_uint32_bset_first(&multi->process, &mid)) { - do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - - if(!data) { - DEBUGASSERT(0); - continue; - } - - Curl_multi_pollset(data, &ps); - for(i = 0; i < ps.n; i++) { - if(!FDSET_SOCK(ps.sockets[i])) - /* pretend it does not exist */ - continue; - if(ps.actions[i] & CURL_POLL_IN) - FD_SET(ps.sockets[i], read_fd_set); - if(ps.actions[i] & CURL_POLL_OUT) - FD_SET(ps.sockets[i], write_fd_set); - if((int)ps.sockets[i] > this_max_fd) - this_max_fd = (int)ps.sockets[i]; - } - } while(Curl_uint32_bset_next(&multi->process, mid, &mid)); - } - - Curl_cshutdn_setfds(&multi->cshutdn, multi->admin, - read_fd_set, write_fd_set, &this_max_fd); - - *max_fd = this_max_fd; - Curl_pollset_cleanup(&ps); - - return CURLM_OK; -} - -CURLMcode curl_multi_waitfds(CURLM *m, - struct curl_waitfd *ufds, - unsigned int size, - unsigned int *fd_count) -{ - struct Curl_waitfds cwfds; - CURLMcode mresult = CURLM_OK; - struct Curl_multi *multi = m; - struct easy_pollset ps; - unsigned int need = 0; - uint32_t mid; - - if(!ufds && (size || !fd_count)) - return CURLM_BAD_FUNCTION_ARGUMENT; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - Curl_pollset_init(&ps); - Curl_waitfds_init(&cwfds, ufds, size); - if(Curl_uint32_bset_first(&multi->process, &mid)) { - do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - if(!data) { - DEBUGASSERT(0); - Curl_uint32_bset_remove(&multi->process, mid); - Curl_uint32_bset_remove(&multi->dirty, mid); - continue; - } - Curl_multi_pollset(data, &ps); - need += Curl_waitfds_add_ps(&cwfds, &ps); - } while(Curl_uint32_bset_next(&multi->process, mid, &mid)); - } - - need += Curl_cshutdn_add_waitfds(&multi->cshutdn, multi->admin, &cwfds); - - if(need != cwfds.n && ufds) - mresult = CURLM_OUT_OF_MEMORY; - - if(fd_count) - *fd_count = need; - Curl_pollset_cleanup(&ps); - return mresult; -} - -#ifdef USE_WINSOCK -/* Reset FD_WRITE for TCP sockets. Nothing is actually sent. UDP sockets cannot - * be reset this way because an empty datagram would be sent. #9203 - * - * "On Windows the internal state of FD_WRITE as returned from - * WSAEnumNetworkEvents is only reset after successful send()." - */ -static void reset_socket_fdwrite(curl_socket_t s) -{ - int t; - int l = (int)sizeof(t); - if(!getsockopt(s, SOL_SOCKET, SO_TYPE, (char *)&t, &l) && t == SOCK_STREAM) - swrite(s, NULL, 0); -} - -static CURLMcode multi_winsock_select(struct Curl_multi *multi, - struct curl_pollfds *cpfds, - unsigned int curl_nfds, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - bool extrawait, - int *pnevents) -{ - CURLMcode mresult = CURLM_OK; - WSANETWORKEVENTS wsa_events; - int nevents = 0; - size_t i; - - DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT); - - /* Set the WSA events based on the collected pollds */ - for(i = 0; i < cpfds->n; i++) { - long mask = 0; - if(cpfds->pfds[i].events & POLLIN) - mask |= FD_READ | FD_ACCEPT | FD_CLOSE; - if(cpfds->pfds[i].events & POLLPRI) - mask |= FD_OOB; - if(cpfds->pfds[i].events & POLLOUT) { - mask |= FD_WRITE | FD_CONNECT | FD_CLOSE; - reset_socket_fdwrite(cpfds->pfds[i].fd); - } - if(mask) { - if(WSAEventSelect(cpfds->pfds[i].fd, multi->wsa_event, mask) != 0) { - mresult = CURLM_OUT_OF_MEMORY; - goto out; - } - } - } - - if(cpfds->n || extrawait) { - int pollrc = 0; - - if(cpfds->n) { /* pre-check with Winsock */ - pollrc = Curl_poll(cpfds->pfds, cpfds->n, 0); - if(pollrc < 0) { - mresult = CURLM_UNRECOVERABLE_POLL; - goto out; - } - nevents = pollrc; - } - - if(!nevents) { - /* now wait... if not ready during the pre-check (pollrc == 0) */ - WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, (DWORD)timeout_ms, - FALSE); - } - - /* With Winsock, we have to run the following section unconditionally - to call WSAEventSelect(fd, event, 0) on all the sockets */ - /* copy revents results from the poll to the curl_multi_wait poll - struct, the bit values of the actual underlying poll() implementation - may not be the same as the ones in the public libcurl API! */ - for(i = 0; i < extra_nfds; i++) { - unsigned short mask = 0; - curl_socket_t s = extra_fds[i].fd; - - wsa_events.lNetworkEvents = 0; - if(WSAEnumNetworkEvents(s, NULL, &wsa_events) == 0) { - if(wsa_events.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) - mask |= CURL_WAIT_POLLIN; - if(wsa_events.lNetworkEvents & (FD_WRITE | FD_CONNECT | FD_CLOSE)) - mask |= CURL_WAIT_POLLOUT; - if(wsa_events.lNetworkEvents & FD_OOB) - mask |= CURL_WAIT_POLLPRI; - if(!pollrc && wsa_events.lNetworkEvents) - nevents++; - } - WSAEventSelect(s, multi->wsa_event, 0); - if(!pollrc) { - extra_fds[i].revents = (short)mask; - continue; - } - else { - unsigned r = (unsigned)cpfds->pfds[curl_nfds + i].revents; - if(r & POLLIN) - mask |= CURL_WAIT_POLLIN; - if(r & POLLOUT) - mask |= CURL_WAIT_POLLOUT; - if(r & POLLPRI) - mask |= CURL_WAIT_POLLPRI; - extra_fds[i].revents = (short)mask; - } - } - - /* Count up all our own sockets that had activity, - and remove them from the event. */ - for(i = 0; i < curl_nfds; ++i) { - wsa_events.lNetworkEvents = 0; - if(WSAEnumNetworkEvents(cpfds->pfds[i].fd, NULL, &wsa_events) == 0) { - if(!pollrc && wsa_events.lNetworkEvents) - nevents++; - } - WSAEventSelect(cpfds->pfds[i].fd, multi->wsa_event, 0); - } - WSAResetEvent(multi->wsa_event); - } - -out: - *pnevents = nevents; - return mresult; -} - -#else /* USE_WINSOCK */ - -static CURLMcode multi_posix_poll(struct Curl_multi *multi, - struct curl_pollfds *cpfds, - unsigned int curl_nfds, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - bool extrawait, - int *pnevents) -{ - CURLMcode mresult = CURLM_OK; - int nevents = 0; - size_t i; - - (void)multi; - if(cpfds->n) { - int pollrc = Curl_poll(cpfds->pfds, cpfds->n, timeout_ms); /* wait... */ - if(pollrc < 0) { - mresult = CURLM_UNRECOVERABLE_POLL; - goto out; - } - nevents = pollrc; - - /* copy revents results from the poll to the curl_multi_wait poll - struct, the bit values of the actual underlying poll() implementation - may not be the same as the ones in the public libcurl API! */ - for(i = 0; i < extra_nfds; i++) { - unsigned r = (unsigned)cpfds->pfds[curl_nfds + i].revents; - unsigned short mask = 0; - if(r & POLLIN) - mask |= CURL_WAIT_POLLIN; - if(r & POLLOUT) - mask |= CURL_WAIT_POLLOUT; - if(r & POLLPRI) - mask |= CURL_WAIT_POLLPRI; - extra_fds[i].revents = (short)mask; - } - } - else if(extrawait) { - /* No fds to poll, but asked to obey timeout_ms anyway. We cannot - * use Curl_poll() as it, on some platforms, returns immediately - * without fds. */ - curlx_wait_ms(timeout_ms); - } - -out: - *pnevents = nevents; - return mresult; -} - -#endif /* !USE_WINSOCK */ - -#define NUM_POLLS_ON_STACK 10 - -static CURLMcode multi_wait(struct Curl_multi *multi, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret, - bool extrawait) /* when no socket, wait */ -{ - size_t i; - struct curltime expire_time; - long timeout_internal; - int nevents = 0; - struct easy_pollset ps; - struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; - struct curl_pollfds cpfds; - unsigned int curl_nfds = 0; /* how many pfds are for curl transfers */ - struct Curl_easy *data = NULL; - CURLMcode mresult = CURLM_OK; - uint32_t mid; -#ifdef ENABLE_WAKEUP - int wakeup_idx = -1; -#endif - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - if(timeout_ms < 0) - return CURLM_BAD_FUNCTION_ARGUMENT; - - Curl_pollset_init(&ps); - Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK); - - /* Add the curl handles to our pollfds first */ - if(Curl_uint32_bset_first(&multi->process, &mid)) { - do { - data = Curl_multi_get_easy(multi, mid); - if(!data) { - DEBUGASSERT(0); - Curl_uint32_bset_remove(&multi->process, mid); - Curl_uint32_bset_remove(&multi->dirty, mid); - continue; - } - Curl_multi_pollset(data, &ps); - if(Curl_pollfds_add_ps(&cpfds, &ps)) { - mresult = CURLM_OUT_OF_MEMORY; - goto out; - } - } while(Curl_uint32_bset_next(&multi->process, mid, &mid)); - } - - if(Curl_cshutdn_add_pollfds(&multi->cshutdn, multi->admin, &cpfds)) { - mresult = CURLM_OUT_OF_MEMORY; - goto out; - } - -#ifdef ENABLE_WAKEUP - /* If `extrawait` is TRUE *or* we have `extra_fds`to poll *or* we - * have transfer sockets to poll, we obey `timeout_ms`. - * Then we need to also monitor the multi's wakeup - * socket to catch calls to `curl_multi_wakeup()` during the wait. */ - if(extrawait || cpfds.n || extra_nfds) { - wakeup_idx = cpfds.n; - if(Curl_pollfds_add_sock(&cpfds, multi->wakeup_pair[0], POLLIN)) { - mresult = CURLM_OUT_OF_MEMORY; - goto out; - } - } -#endif - - curl_nfds = cpfds.n; /* what curl internally uses in cpfds */ - /* Add external file descriptions from poll-like struct curl_waitfd */ - for(i = 0; i < extra_nfds; i++) { - unsigned short events = 0; - if(extra_fds[i].events & CURL_WAIT_POLLIN) - events |= POLLIN; - if(extra_fds[i].events & CURL_WAIT_POLLPRI) - events |= POLLPRI; - if(extra_fds[i].events & CURL_WAIT_POLLOUT) - events |= POLLOUT; - if(Curl_pollfds_add_sock(&cpfds, extra_fds[i].fd, events)) { - mresult = CURLM_OUT_OF_MEMORY; - goto out; - } - } - - /* We check the internal timeout *AFTER* we collected all sockets to - * poll. Collecting the sockets may install new timers by protocols - * and connection filters. - * Use the shorter one of the internal and the caller requested timeout. - * If we are called with `!extrawait` and multi_timeout() reports no - * timeouts exist, do not wait. */ - multi_timeout(multi, &expire_time, &timeout_internal); - if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) - timeout_ms = (int)timeout_internal; - - if(data) - CURL_TRC_M(data, "multi_wait(fds=%u, timeout=%d) tinternal=%ld", - cpfds.n, timeout_ms, timeout_internal); - -#ifdef USE_WINSOCK - mresult = multi_winsock_select(multi, &cpfds, curl_nfds, - extra_fds, extra_nfds, - timeout_ms, extrawait, &nevents); -#else - mresult = multi_posix_poll(multi, &cpfds, curl_nfds, - extra_fds, extra_nfds, - timeout_ms, extrawait, &nevents); -#endif - -#ifdef ENABLE_WAKEUP - if(nevents && (wakeup_idx >= 0)) { - if(cpfds.pfds[wakeup_idx].revents & POLLIN) { - (void)Curl_wakeup_consume(multi->wakeup_pair, TRUE); - /* do not count the wakeup socket into the returned value */ - nevents--; - } - } -#endif - -out: - Curl_pollset_cleanup(&ps); - Curl_pollfds_cleanup(&cpfds); - if(ret) - *ret = nevents; - return mresult; -} - -CURLMcode curl_multi_wait(CURLM *m, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret) -{ - return multi_wait(m, extra_fds, extra_nfds, timeout_ms, ret, FALSE); -} - -CURLMcode curl_multi_poll(CURLM *m, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret) -{ - return multi_wait(m, extra_fds, extra_nfds, timeout_ms, ret, TRUE); -} - -CURLMcode curl_multi_wakeup(CURLM *m) -{ - /* this function is usually called from another thread, - it has to be careful only to access parts of the - Curl_multi struct that are constant */ - struct Curl_multi *multi = m; - CURLMcode mresult = CURLM_WAKEUP_FAILURE; - - /* GOOD_MULTI_HANDLE can be safely called */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - -#ifdef ENABLE_WAKEUP - /* the wakeup_pair variable is only written during init and cleanup, - making it safe to access from another thread after the init part - and before cleanup */ - if(!Curl_wakeup_signal(multi->wakeup_pair)) - mresult = CURLM_OK; -#endif -#ifdef USE_WINSOCK - if(WSASetEvent(multi->wsa_event)) - mresult = CURLM_OK; -#endif - return mresult; -} - -/* - * multi_ischanged() is called - * - * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND - * => CONNECT action. - * - * Set 'clear' to TRUE to have it also clear the state variable. - */ -static bool multi_ischanged(struct Curl_multi *multi, bool clear) -{ - bool retval = (bool)multi->recheckstate; - if(clear) - multi->recheckstate = FALSE; - return retval; -} - -/* - * Curl_multi_connchanged() is called to tell that there is a connection in - * this multi handle that has changed state (multiplexing become possible, the - * number of allowed streams changed or similar), and a subsequent use of this - * multi handle should move CONNECT_PEND handles back to CONNECT to have them - * retry. - */ -void Curl_multi_connchanged(struct Curl_multi *multi) -{ - multi->recheckstate = TRUE; -} - -CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn) -{ - CURLMcode mresult; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - mresult = curl_multi_add_handle(multi, data); - if(!mresult) { - CURLcode result; - - /* pass in NULL for 'conn' here since we do not want to init the - connection, only this transfer */ - result = Curl_init_do(data, NULL); - if(result) { - curl_multi_remove_handle(multi, data); - return CURLM_INTERNAL_ERROR; - } - - /* take this handle to the perform state right away */ - multistate(data, MSTATE_PERFORMING); - Curl_attach_connection(data, conn); - CURL_REQ_SET_RECV(data); - } - return mresult; -} - -static CURLcode multi_do(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - - DEBUGASSERT(conn); - DEBUGASSERT(conn->scheme); - - if(conn->scheme->run->do_it) - result = conn->scheme->run->do_it(data, done); - - return result; -} - -/* - * multi_do_more() is called during the DO_MORE multi state. It is a second - * stage DO state which (wrongly) was introduced to support FTP's second - * connection. - * - * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to - * DOING state there is more work to do! - */ - -static CURLcode multi_do_more(struct Curl_easy *data, int *complete) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - - *complete = 0; - - if(conn->scheme->run->do_more) - result = conn->scheme->run->do_more(data, complete); - - return result; -} - -/* - * Check whether a timeout occurred, and handle it if it did - */ -static bool multi_handle_timeout(struct Curl_easy *data, - bool *stream_error, - CURLcode *result) -{ - timediff_t timeout_ms; - - timeout_ms = Curl_timeleft_ms(data); - if(timeout_ms < 0) { - /* Handle timed out */ - struct curltime since; - if(Curl_is_connecting(data)) - since = data->progress.t_startsingle; - else - since = data->progress.t_startop; - if(data->mstate == MSTATE_CONNECTING) - failf(data, "%s timed out after %" FMT_TIMEDIFF_T " milliseconds", - data->conn->bits.dns_resolved ? "Connection" : "Resolving", - curlx_ptimediff_ms(Curl_pgrs_now(data), &since)); - else { - struct SingleRequest *k = &data->req; - if(k->size != -1) { - failf(data, "Operation timed out after %" FMT_TIMEDIFF_T - " milliseconds with %" FMT_OFF_T " out of %" - FMT_OFF_T " bytes received", - curlx_ptimediff_ms(Curl_pgrs_now(data), &since), - k->bytecount, k->size); - } - else { - failf(data, "Operation timed out after %" FMT_TIMEDIFF_T - " milliseconds with %" FMT_OFF_T " bytes received", - curlx_ptimediff_ms(Curl_pgrs_now(data), &since), - k->bytecount); - } - } - *result = CURLE_OPERATION_TIMEDOUT; - if(data->conn) { - /* Force connection closed if the connection has indeed been used */ - if(data->mstate > MSTATE_DO) { - streamclose(data->conn, "Disconnect due to timeout"); - *stream_error = TRUE; - } - (void)multi_done(data, *result, TRUE); - } - return TRUE; - } - - return FALSE; -} - -/* - * We are doing protocol-specific connecting and this is being called over and - * over from the multi interface until the connection phase is done on - * protocol layer. - */ - -static CURLcode protocol_connecting(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - - if(conn && conn->scheme->run->connecting) { - *done = FALSE; - result = conn->scheme->run->connecting(data, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We are DOING this is being called over and over from the multi interface - * until the DOING phase is done on protocol layer. - */ - -static CURLcode protocol_doing(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - - if(conn && conn->scheme->run->doing) { - *done = FALSE; - result = conn->scheme->run->doing(data, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We have discovered that the TCP connection has been successful, we can now - * proceed with some action. - * - */ -static CURLcode protocol_connect(struct Curl_easy *data, bool *protocol_done) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - - DEBUGASSERT(conn); - DEBUGASSERT(protocol_done); - DEBUGASSERT(Curl_conn_is_connected(conn, FIRSTSOCKET)); - - *protocol_done = FALSE; - if(!conn->bits.protoconnstart) { - if(conn->scheme->run->connect_it) { - /* Call the protocol-specific connect function */ - result = conn->scheme->run->connect_it(data, protocol_done); - if(result) - return result; - } - conn->bits.protoconnstart = TRUE; - } - - /* Unless this protocol does not have any protocol-connect callback, as - then we know we are done. */ - if(!conn->scheme->run->connecting) - *protocol_done = TRUE; - return CURLE_OK; -} - -static void set_in_callback(struct Curl_multi *multi, bool value) -{ - multi->in_callback = value; -} - -/* - * posttransfer() is called immediately after a transfer ends - */ -static void multi_posttransfer(struct Curl_easy *data) -{ -#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(MSG_NOSIGNAL) - /* restore the signal handler for SIGPIPE before we get back */ - if(!data->set.no_signal) - signal(SIGPIPE, data->state.prev_signal); -#else - (void)data; -#endif -} - -/* - * multi_follow() handles the URL redirect magic. Pass in the 'newurl' string - * as given by the remote server and set up the new URL to request. - * - * This function DOES NOT FREE the given URL. - */ -static CURLcode multi_follow(struct Curl_easy *data, - const struct Curl_scheme *handler, - const char *newurl, /* the Location: string */ - followtype type) /* see transfer.h */ -{ - if(handler && handler->run->follow) - return handler->run->follow(data, newurl, type); - - if(type == FOLLOW_RETRY) - /* Retries are generic and do not require protocol-specific redirect - handling. */ - return CURLE_OK; - - return CURLE_TOO_MANY_REDIRECTS; -} - -static CURLcode mspeed_check(struct Curl_easy *data) -{ - if(Curl_rlimit_active(&data->progress.dl.rlimit) || - Curl_rlimit_active(&data->progress.ul.rlimit)) { - /* check if our send/recv limits require idle waits */ - const struct curltime *pnow = Curl_pgrs_now(data); - timediff_t recv_ms, send_ms; - - send_ms = Curl_rlimit_wait_ms(&data->progress.ul.rlimit, pnow); - recv_ms = Curl_rlimit_wait_ms(&data->progress.dl.rlimit, pnow); - - if(send_ms || recv_ms) { - if(data->mstate != MSTATE_RATELIMITING) { - multistate(data, MSTATE_RATELIMITING); - } - Curl_expire(data, CURLMAX(send_ms, recv_ms), EXPIRE_TOOFAST); - Curl_multi_clear_dirty(data); - CURL_TRC_M(data, "[RLIMIT] waiting %" FMT_TIMEDIFF_T "ms", - CURLMAX(send_ms, recv_ms)); - return CURLE_AGAIN; - } - else { - /* when will the rate limits increase next? The transfer needs - * to run again at that time or it may stall. */ - send_ms = Curl_rlimit_next_step_ms(&data->progress.ul.rlimit, pnow); - recv_ms = Curl_rlimit_next_step_ms(&data->progress.dl.rlimit, pnow); - if(send_ms || recv_ms) { - timediff_t next_ms = CURLMIN(send_ms, recv_ms); - if(!next_ms) - next_ms = CURLMAX(send_ms, recv_ms); - Curl_expire(data, next_ms, EXPIRE_TOOFAST); - CURL_TRC_M(data, "[RLIMIT] next token update in %" FMT_TIMEDIFF_T "ms", - next_ms); - } - } - } - - if(data->mstate != MSTATE_PERFORMING) { - CURL_TRC_M(data, "[RLIMIT] wait over, continue"); - multistate(data, MSTATE_PERFORMING); - } - return CURLE_OK; -} - -static CURLMcode state_performing(struct Curl_easy *data, - bool *stream_errorp, - CURLcode *resultp) -{ - char *newurl = NULL; - bool retry = FALSE; - CURLMcode mresult = CURLM_OK; - CURLcode result = *resultp = CURLE_OK; - *stream_errorp = FALSE; - - if(mspeed_check(data) == CURLE_AGAIN) - return CURLM_OK; - - /* read/write data if it is ready to do so */ - result = Curl_sendrecv(data); - - if(data->req.done || (result == CURLE_RECV_ERROR)) { - /* If CURLE_RECV_ERROR happens early enough, we assume it was a race - * condition and the server closed the reused connection exactly when we - * wanted to use it, so figure out if that is indeed the case. - */ - CURLcode ret = Curl_retry_request(data, &newurl); - if(!ret) - retry = !!newurl; - else if(!result) - result = ret; - - if(retry) { - /* if we are to retry, set the result to OK and consider the - request as done */ - result = CURLE_OK; - data->req.done = TRUE; - } - } -#ifndef CURL_DISABLE_HTTP - else if((result == CURLE_HTTP2_STREAM) && - Curl_h2_http_1_1_error(data)) { - CURLcode ret = Curl_retry_request(data, &newurl); - - if(!ret) { - infof(data, "Downgrades to HTTP/1.1"); - streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1"); - data->state.http_neg.wanted = CURL_HTTP_V1x; - data->state.http_neg.allowed = CURL_HTTP_V1x; - /* clear the error message bit too as we ignore the one we got */ - data->state.errorbuf = FALSE; - if(!newurl) - /* typically for HTTP_1_1_REQUIRED error on first flight */ - newurl = Curl_bufref_dup(&data->state.url); - if(!newurl) { - result = CURLE_OUT_OF_MEMORY; - } - else { - /* if we are to retry, set the result to OK and consider the request - as done */ - retry = TRUE; - result = CURLE_OK; - data->req.done = TRUE; - } - } - else - result = ret; - } -#endif - - if(result) { - /* - * The transfer phase returned error, we mark the connection to get closed - * to prevent being reused. This is because we cannot possibly know if the - * connection is in a good shape or not now. Unless it is a protocol which - * uses two "channels" like FTP, as then the error happened in the data - * connection. - */ - - if(!(data->conn->scheme->flags & PROTOPT_DUAL) && - result != CURLE_HTTP2_STREAM) - streamclose(data->conn, "Transfer returned error"); - - multi_posttransfer(data); - multi_done(data, result, TRUE); - } - else if(data->req.done && !Curl_cwriter_is_paused(data)) { - const struct Curl_scheme *handler = data->conn->scheme; - - /* call this even if the readwrite function returned error */ - multi_posttransfer(data); - - /* When we follow redirects or is set to retry the connection, we must to - go back to the CONNECT state */ - if(data->req.newurl || retry) { - followtype follow = FOLLOW_NONE; - if(!retry) { - /* if the URL is a follow-location and not a retried request then - figure out the URL here */ - curlx_free(newurl); - newurl = data->req.newurl; - data->req.newurl = NULL; - follow = FOLLOW_REDIR; - } - else - follow = FOLLOW_RETRY; - (void)multi_done(data, CURLE_OK, FALSE); - /* multi_done() might return CURLE_GOT_NOTHING */ - result = multi_follow(data, handler, newurl, follow); - if(!result) { - multistate(data, MSTATE_SETUP); - mresult = CURLM_CALL_MULTI_PERFORM; - } - } - else { - /* after the transfer is done, go DONE */ - - /* but first check to see if we got a location info even though we are - not following redirects */ - if(data->req.location) { - curlx_free(newurl); - newurl = data->req.location; - data->req.location = NULL; - result = multi_follow(data, handler, newurl, FOLLOW_FAKE); - if(result) { - *stream_errorp = TRUE; - result = multi_done(data, result, TRUE); - } - } - - if(!result) { - multistate(data, MSTATE_DONE); - mresult = CURLM_CALL_MULTI_PERFORM; - } - } - } - else { /* not errored, not done */ - mspeed_check(data); - } - curlx_free(newurl); - *resultp = result; - return mresult; -} - -static CURLMcode state_do(struct Curl_easy *data, - bool *stream_errorp, - CURLcode *resultp) -{ - CURLMcode mresult = CURLM_OK; - CURLcode result = CURLE_OK; - if(data->set.fprereq) { - int prereq_rc; - - /* call the prerequest callback function */ - Curl_set_in_callback(data, TRUE); - prereq_rc = data->set.fprereq(data->set.prereq_userp, - data->info.primary.remote_ip, - data->info.primary.local_ip, - data->info.primary.remote_port, - data->info.primary.local_port); - Curl_set_in_callback(data, FALSE); - if(prereq_rc != CURL_PREREQFUNC_OK) { - failf(data, "operation aborted by pre-request callback"); - /* failure in pre-request callback - do not do any other processing */ - result = CURLE_ABORTED_BY_CALLBACK; - multi_posttransfer(data); - multi_done(data, result, FALSE); - *stream_errorp = TRUE; - goto end; - } - } - - if(data->set.connect_only && !data->set.connect_only_ws) { - multistate(data, MSTATE_DONE); - mresult = CURLM_CALL_MULTI_PERFORM; - } - else { - bool dophase_done = FALSE; - /* Perform the protocol's DO action */ - result = multi_do(data, &dophase_done); - - /* When multi_do() returns failure, data->conn might be NULL! */ - - if(!result) { - if(!dophase_done) { -#ifndef CURL_DISABLE_FTP - /* some steps needed for wildcard matching */ - if(data->state.wildcardmatch) { - struct WildcardData *wc = data->wildcard; - if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { - /* skip some states if it is important */ - multi_done(data, CURLE_OK, FALSE); - - /* if there is no connection left, skip the DONE state */ - multistate(data, data->conn ? MSTATE_DONE : MSTATE_COMPLETED); - mresult = CURLM_CALL_MULTI_PERFORM; - goto end; - } - } -#endif - /* DO was not completed in one function call, we must continue - DOING... */ - multistate(data, MSTATE_DOING); - mresult = CURLM_CALL_MULTI_PERFORM; - } - - /* after DO, go DO_DONE... or DO_MORE */ - else if(data->conn->bits.do_more) { - /* we are supposed to do more, but we need to sit down, relax and wait - a little while first */ - multistate(data, MSTATE_DOING_MORE); - mresult = CURLM_CALL_MULTI_PERFORM; - } - else { - /* we are done with the DO, now DID */ - multistate(data, MSTATE_DID); - mresult = CURLM_CALL_MULTI_PERFORM; - } - } - else if((result == CURLE_SEND_ERROR) && - data->conn->bits.reuse) { - /* - * In this situation, a connection that we were trying to use may have - * unexpectedly died. If possible, send the connection back to the - * CONNECT phase so we can try again. - */ - const struct Curl_scheme *handler = data->conn->scheme; - char *newurl = NULL; - followtype follow = FOLLOW_NONE; - CURLcode drc; - - drc = Curl_retry_request(data, &newurl); - if(drc) { - /* a failure here pretty much implies an out of memory */ - result = drc; - *stream_errorp = TRUE; - } - - multi_posttransfer(data); - drc = multi_done(data, result, FALSE); - - /* When set to retry the connection, we must go back to the CONNECT - * state */ - if(newurl) { - if(!drc || (drc == CURLE_SEND_ERROR)) { - follow = FOLLOW_RETRY; - drc = multi_follow(data, handler, newurl, follow); - if(!drc) { - multistate(data, MSTATE_SETUP); - mresult = CURLM_CALL_MULTI_PERFORM; - result = CURLE_OK; - } - else { - /* Follow failed */ - result = drc; - } - } - else { - /* done did not return OK or SEND_ERROR */ - result = drc; - } - } - else { - /* Have error handler disconnect conn if we cannot retry */ - *stream_errorp = TRUE; - } - curlx_free(newurl); - } - else { - /* failure detected */ - multi_posttransfer(data); - if(data->conn) - multi_done(data, result, FALSE); - *stream_errorp = TRUE; - } - } -end: - *resultp = result; - return mresult; -} - -static CURLMcode state_ratelimiting(struct Curl_easy *data, - CURLcode *resultp) -{ - CURLcode result = CURLE_OK; - CURLMcode mresult = CURLM_OK; - DEBUGASSERT(data->conn); - /* if both rates are within spec, resume transfer */ - result = Curl_pgrsCheck(data); - - if(result) { - if(!(data->conn->scheme->flags & PROTOPT_DUAL) && - result != CURLE_HTTP2_STREAM) - streamclose(data->conn, "Transfer returned error"); - - multi_posttransfer(data); - multi_done(data, result, TRUE); - } - else { - if(!mspeed_check(data)) - mresult = CURLM_CALL_MULTI_PERFORM; - } - *resultp = result; - return mresult; -} - -static CURLMcode state_connect(struct Curl_multi *multi, - struct Curl_easy *data, - CURLcode *resultp) -{ - /* Connect. We want to get a connection identifier filled in. This state can - be entered from SETUP and from PENDING. */ - bool connected; - CURLMcode mresult = CURLM_OK; - CURLcode result = Curl_connect(data, &connected); - if(result == CURLE_NO_CONNECTION_AVAILABLE) { - /* There was no connection available. We will go to the pending state and - wait for an available connection. */ - multistate(data, MSTATE_PENDING); - /* move from process to pending set */ - Curl_uint32_bset_remove(&multi->process, data->mid); - Curl_uint32_bset_remove(&multi->dirty, data->mid); - Curl_uint32_bset_add(&multi->pending, data->mid); - *resultp = CURLE_OK; - return mresult; - } - else - process_pending_handles(data->multi); - - if(!result) { - /* after the connect has been sent off, go WAITCONNECT unless the - protocol connect is already done and we can go directly to WAITDO or - DO! */ - mresult = CURLM_CALL_MULTI_PERFORM; - - if(connected) { - if(!data->conn->bits.reuse && - Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) { - /* new connection, can multiplex, wake pending handles */ - process_pending_handles(data->multi); - } - multistate(data, MSTATE_PROTOCONNECT); - } - else { - multistate(data, MSTATE_CONNECTING); - } - } - *resultp = result; - return mresult; -} - -/* returns the possibly updated result */ -static CURLcode is_finished(struct Curl_multi *multi, - struct Curl_easy *data, - bool stream_error, - CURLcode result) -{ - if(data->mstate < MSTATE_COMPLETED) { - if(result) { - /* - * If an error was returned, and we are not in completed state now, - * then we go to completed and consider this transfer aborted. - */ - - /* No attempt to disconnect connections must be made before this - - connection detach and termination happens only here */ - - /* Check if we can move pending requests to send pipe */ - process_pending_handles(multi); /* connection */ - - if(data->conn) { - if(stream_error) { - /* Do not attempt to send data over a connection that timed out */ - bool dead_connection = result == CURLE_OPERATION_TIMEDOUT; - struct connectdata *conn = data->conn; - - /* This is where we make sure that the conn pointer is reset. - We do not have to do this in every case block above where a - failure is detected */ - Curl_detach_connection(data); - Curl_conn_terminate(data, conn, dead_connection); - } - } - else if(data->mstate == MSTATE_CONNECT) { - /* Curl_connect() failed */ - multi_posttransfer(data); - Curl_pgrsUpdate_nometer(data); - } - - multistate(data, MSTATE_COMPLETED); - return result; - } - /* if there is still a connection to use, call the progress function */ - else if(data->conn && Curl_conn_is_connected(data->conn, FIRSTSOCKET)) { - result = Curl_pgrsUpdate(data); - if(result) { - /* aborted due to progress callback return code must close the - connection */ - streamclose(data->conn, "Aborted by callback"); - - /* if not yet in DONE state, go there, otherwise COMPLETED */ - multistate(data, (data->mstate < MSTATE_DONE) ? - MSTATE_DONE : MSTATE_COMPLETED); - return result; - } - } - } - return result; -} - -static void handle_completed(struct Curl_multi *multi, - struct Curl_easy *data, - CURLcode result) -{ - if(data->master_mid != UINT32_MAX) { - /* A sub transfer, not for msgsent to application */ - struct Curl_easy *mdata; - - CURL_TRC_M(data, "sub xfer done for master %u", data->master_mid); - mdata = Curl_multi_get_easy(multi, data->master_mid); - if(mdata) { - if(mdata->sub_xfer_done) - mdata->sub_xfer_done(mdata, data, result); - else - CURL_TRC_M(data, "master easy %u without sub_xfer_done callback.", - data->master_mid); - } - else { - CURL_TRC_M(data, "master easy %u already gone.", data->master_mid); - } - } - else { - /* now fill in the Curl_message with this info */ - struct Curl_message *msg = &data->msg; - - msg->extmsg.msg = CURLMSG_DONE; - msg->extmsg.easy_handle = data; - msg->extmsg.data.result = result; - - multi_addmsg(multi, msg); - DEBUGASSERT(!data->conn); - } - multistate(data, MSTATE_MSGSENT); - - /* remove from the other sets, add to msgsent */ - Curl_uint32_bset_remove(&multi->process, data->mid); - Curl_uint32_bset_remove(&multi->dirty, data->mid); - Curl_uint32_bset_remove(&multi->pending, data->mid); - Curl_uint32_bset_add(&multi->msgsent, data->mid); - --multi->xfers_alive; - if(!multi->xfers_alive) - multi_assess_wakeup(multi); -} - -static CURLMcode multi_runsingle(struct Curl_multi *multi, - struct Curl_easy *data, - struct Curl_sigpipe_ctx *sigpipe_ctx) -{ - bool connected; - bool protocol_connected = FALSE; - bool dophase_done = FALSE; - CURLMcode mresult; - CURLcode result = CURLE_OK; - int control; - - if(!GOOD_EASY_HANDLE(data)) - return CURLM_BAD_EASY_HANDLE; - - if(multi->dead) { - /* a multi-level callback returned error before, meaning every individual - transfer now has failed */ - result = CURLE_ABORTED_BY_CALLBACK; - multi_posttransfer(data); - multi_done(data, result, FALSE); - multistate(data, MSTATE_COMPLETED); - } - - multi_warn_debug(multi, data); - - /* transfer runs now, clear the dirty bit. This may be set - * again during processing, triggering a re-run later. */ - Curl_uint32_bset_remove(&multi->dirty, data->mid); - - if(data == multi->admin) { -#ifdef USE_RESOLV_THREADED - Curl_async_thrdd_multi_process(multi); -#endif - Curl_cshutdn_perform(&multi->cshutdn, multi->admin, sigpipe_ctx); - return CURLM_OK; - } - - sigpipe_apply(data, sigpipe_ctx); - do { - /* A "stream" here is a logical stream if the protocol can handle that - (HTTP/2), or the full connection for older protocols */ - bool stream_error = FALSE; - mresult = CURLM_OK; - - if(multi_ischanged(multi, TRUE)) { - CURL_TRC_M(data, "multi changed, check CONNECT_PEND queue"); - process_pending_handles(multi); /* multiplexed */ - } - - if(data->mstate > MSTATE_CONNECT && - data->mstate < MSTATE_COMPLETED) { - /* Make sure we set the connection's current owner */ - DEBUGASSERT(data->conn); - if(!data->conn) - return CURLM_INTERNAL_ERROR; - } - - /* Wait for the connect state as only then is the start time stored, but - we must not check already completed handles */ - if((data->mstate >= MSTATE_CONNECT) && (data->mstate < MSTATE_COMPLETED) && - multi_handle_timeout(data, &stream_error, &result)) - /* Skip the statemachine and go directly to error handling section. */ - goto statemachine_end; - - switch(data->mstate) { - case MSTATE_INIT: - /* Transitional state. init this transfer. A handle never comes back to - this state. */ - result = Curl_pretransfer(data); - if(result) - break; - - /* after init, go SETUP */ - multistate(data, MSTATE_SETUP); - Curl_pgrsTime(data, TIMER_STARTOP); - FALLTHROUGH(); - - case MSTATE_SETUP: - /* Transitional state. Setup things for a new transfer. The handle - can come back to this state on a redirect. */ - Curl_pgrsTime(data, TIMER_STARTSINGLE); - if(data->set.timeout) - Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT); - if(data->set.connecttimeout) - /* Since a connection might go to pending and back to CONNECT several - times before it actually takes off, we need to set the timeout once - in SETUP before we enter CONNECT the first time. */ - Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT); - - multistate(data, MSTATE_CONNECT); - FALLTHROUGH(); - - case MSTATE_CONNECT: - mresult = state_connect(multi, data, &result); - break; - - case MSTATE_CONNECTING: - /* awaiting a completion of an asynch TCP connect */ - if(!data->conn) { - DEBUGASSERT(0); - result = CURLE_FAILED_INIT; - break; - } - else if(!Curl_xfer_recv_is_paused(data)) { - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected); - if(connected && !result) { - if(!data->conn->bits.reuse && - Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) { - /* new connection, can multiplex, wake pending handles */ - process_pending_handles(data->multi); - } - mresult = CURLM_CALL_MULTI_PERFORM; - multistate(data, MSTATE_PROTOCONNECT); - } - else if(result) { - /* failure detected */ - CURL_TRC_M(data, "connect failed -> %d", result); - multi_posttransfer(data); - multi_done(data, result, TRUE); - stream_error = TRUE; - break; - } - } - break; - - case MSTATE_PROTOCONNECT: - if(!result && data->conn->bits.reuse) { - /* ftp seems to hang when protoconnect on reused connection since we - * handle PROTOCONNECT in general inside the filers, it seems wrong to - * restart this on a reused connection. - */ - multistate(data, MSTATE_DO); - mresult = CURLM_CALL_MULTI_PERFORM; - break; - } - if(!result) - result = protocol_connect(data, &protocol_connected); - if(!result && !protocol_connected) { - /* switch to waiting state */ - multistate(data, MSTATE_PROTOCONNECTING); - mresult = CURLM_CALL_MULTI_PERFORM; - } - else if(!result) { - /* protocol connect has completed, go WAITDO or DO */ - multistate(data, MSTATE_DO); - mresult = CURLM_CALL_MULTI_PERFORM; - } - else { - /* failure detected */ - multi_posttransfer(data); - multi_done(data, result, TRUE); - stream_error = TRUE; - } - break; - - case MSTATE_PROTOCONNECTING: - /* protocol-specific connect phase */ - result = protocol_connecting(data, &protocol_connected); - if(!result && protocol_connected) { - /* after the connect has completed, go WAITDO or DO */ - multistate(data, MSTATE_DO); - mresult = CURLM_CALL_MULTI_PERFORM; - } - else if(result) { - /* failure detected */ - multi_posttransfer(data); - multi_done(data, result, TRUE); - stream_error = TRUE; - } - break; - - case MSTATE_DO: - mresult = state_do(data, &stream_error, &result); - break; - - case MSTATE_DOING: - /* we continue DOING until the DO phase is complete */ - DEBUGASSERT(data->conn); - result = protocol_doing(data, &dophase_done); - if(!result) { - if(dophase_done) { - /* after DO, go DO_DONE or DO_MORE */ - multistate(data, data->conn->bits.do_more ? - MSTATE_DOING_MORE : MSTATE_DID); - mresult = CURLM_CALL_MULTI_PERFORM; - } /* dophase_done */ - } - else { - /* failure detected */ - multi_posttransfer(data); - multi_done(data, result, FALSE); - stream_error = TRUE; - } - break; - - case MSTATE_DOING_MORE: - /* - * When we are connected, DOING MORE and then go DID - */ - DEBUGASSERT(data->conn); - result = multi_do_more(data, &control); - - if(!result) { - if(control) { - /* if positive, advance to DO_DONE - if negative, go back to DOING */ - multistate(data, control == 1 ? MSTATE_DID : MSTATE_DOING); - mresult = CURLM_CALL_MULTI_PERFORM; - } - /* else - stay in DO_MORE */ - } - else { - /* failure detected */ - multi_posttransfer(data); - multi_done(data, result, FALSE); - stream_error = TRUE; - } - break; - - case MSTATE_DID: - DEBUGASSERT(data->conn); - if(data->conn->bits.multiplex) - /* Check if we can move pending requests to send pipe */ - process_pending_handles(multi); /* multiplexed */ - - /* Only perform the transfer if there is a good socket to work with. - Having both BAD is a signal to skip immediately to DONE */ - if(CONN_SOCK_IDX_VALID(data->conn->recv_idx) || - CONN_SOCK_IDX_VALID(data->conn->send_idx)) - multistate(data, MSTATE_PERFORMING); - else { -#ifndef CURL_DISABLE_FTP - if(data->state.wildcardmatch && - ((data->conn->scheme->flags & PROTOPT_WILDCARD) == 0)) { - data->wildcard->state = CURLWC_DONE; - } -#endif - multistate(data, MSTATE_DONE); - } - mresult = CURLM_CALL_MULTI_PERFORM; - break; - - case MSTATE_RATELIMITING: /* limit-rate exceeded in either direction */ - mresult = state_ratelimiting(data, &result); - break; - - case MSTATE_PERFORMING: - mresult = state_performing(data, &stream_error, &result); - break; - - case MSTATE_DONE: - /* this state is highly transient, so run another loop after this */ - mresult = CURLM_CALL_MULTI_PERFORM; - - if(data->conn) { - CURLcode res; - - /* post-transfer command */ - res = multi_done(data, result, FALSE); - - /* allow a previously set error code take precedence */ - if(!result) - result = res; - } - -#ifndef CURL_DISABLE_FTP - if(data->state.wildcardmatch) { - if(data->wildcard->state != CURLWC_DONE) { - /* if a wildcard is set and we are not ending -> lets start again - with MSTATE_INIT */ - multistate(data, MSTATE_INIT); - break; - } - } -#endif - /* after we have DONE what we are supposed to do, go COMPLETED, and - it does not matter what the multi_done() returned! */ - multistate(data, MSTATE_COMPLETED); - break; - - case MSTATE_COMPLETED: - break; - - case MSTATE_PENDING: - case MSTATE_MSGSENT: - /* handles in these states should NOT be in this list */ - break; - - default: - return CURLM_INTERNAL_ERROR; - } - - if(data->mstate >= MSTATE_CONNECT && - data->mstate < MSTATE_DO && - mresult != CURLM_CALL_MULTI_PERFORM && - !multi_ischanged(multi, FALSE)) { - /* We now handle stream timeouts if and only if this will be the last - * loop iteration. We only check this on the last iteration to ensure - * that if we know we have additional work to do immediately - * (i.e. CURLM_CALL_MULTI_PERFORM == TRUE) then we should do that before - * declaring the connection timed out as we may almost have a completed - * connection. */ - multi_handle_timeout(data, &stream_error, &result); - } - -statemachine_end: - - result = is_finished(multi, data, stream_error, result); - if(result) - mresult = CURLM_CALL_MULTI_PERFORM; - - if(MSTATE_COMPLETED == data->mstate) { - handle_completed(multi, data, result); - return CURLM_OK; - } - } while((mresult == CURLM_CALL_MULTI_PERFORM) || - multi_ischanged(multi, FALSE)); - - data->result = result; - return mresult; -} - -static CURLMcode multi_perform(struct Curl_multi *multi, - int *running_handles) -{ - CURLMcode returncode = CURLM_OK; - struct curltime start = *multi_now(multi); - uint32_t mid; - struct Curl_sigpipe_ctx sigpipe_ctx; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - if(multi->in_ntfy_callback) - return CURLM_RECURSIVE_API_CALL; - - sigpipe_init(&sigpipe_ctx); - - if(Curl_uint32_bset_first(&multi->process, &mid)) { - CURL_TRC_M(multi->admin, "multi_perform(running=%u)", - Curl_multi_xfers_running(multi)); - do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - CURLMcode mresult; - if(!data) { - DEBUGASSERT(0); - Curl_uint32_bset_remove(&multi->process, mid); - Curl_uint32_bset_remove(&multi->dirty, mid); - continue; - } - mresult = multi_runsingle(multi, data, &sigpipe_ctx); - if(mresult) - returncode = mresult; - } while(Curl_uint32_bset_next(&multi->process, mid, &mid)); - } - sigpipe_restore(&sigpipe_ctx); - - if(multi_ischanged(multi, TRUE)) - process_pending_handles(multi); - - if(!returncode && CURL_MNTFY_HAS_ENTRIES(multi)) - returncode = Curl_mntfy_dispatch_all(multi); - - /* - * Remove all expired timers from the splay since handles are dealt - * with unconditionally by this function and curl_multi_timeout() requires - * that already passed/handled expire times are removed from the splay. - * - * It is important that the 'now' value is set at the entry of this function - * and not for the current time as it may have ticked a little while since - * then and then we risk this loop to remove timers that actually have not - * been handled! - */ - if(multi->timetree) { - struct Curl_tree *t = NULL; - do { - multi->timetree = Curl_splaygetbest(&start, multi->timetree, &t); - if(t) { - /* the removed may have another timeout in queue */ - struct Curl_easy *data = Curl_splayget(t); - (void)add_next_timeout(&start, multi, data); - if(data->mstate == MSTATE_PENDING) { - bool stream_unused; - CURLcode result_unused; - if(multi_handle_timeout(data, &stream_unused, &result_unused)) { - infof(data, "PENDING handle timeout"); - move_pending_to_connect(multi, data); - } - } - } - } while(t); - } - - if(running_handles) { - unsigned int running = Curl_multi_xfers_running(multi); - *running_handles = (running < INT_MAX) ? (int)running : INT_MAX; - } - - if(CURLM_OK >= returncode) - returncode = Curl_update_timer(multi); - - return returncode; -} - -CURLMcode curl_multi_perform(CURLM *m, int *running_handles) -{ - struct Curl_multi *multi = m; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - return multi_perform(multi, running_handles); -} - -CURLMcode curl_multi_cleanup(CURLM *m) -{ - struct Curl_multi *multi = m; - if(GOOD_MULTI_HANDLE(multi)) { - void *entry; - uint32_t mid; - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - if(multi->in_ntfy_callback) - return CURLM_RECURSIVE_API_CALL; - - /* First remove all remaining easy handles, - * close internal ones. admin handle is special */ - if(Curl_uint32_tbl_first(&multi->xfers, &mid, &entry)) { - do { - struct Curl_easy *data = entry; - if(!GOOD_EASY_HANDLE(data)) - return CURLM_BAD_HANDLE; - -#ifdef DEBUGBUILD - if(mid != data->mid) { - CURL_TRC_M(data, "multi_cleanup: still present with mid=%u, " - "but unexpected data->mid=%u\n", mid, data->mid); - DEBUGASSERT(0); - } -#endif - - if(data == multi->admin) - continue; - - if(!data->state.done && data->conn) - /* if DONE was never called for this handle */ - (void)multi_done(data, CURLE_OK, TRUE); - - data->multi = NULL; /* clear the association */ - Curl_uint32_tbl_remove(&multi->xfers, mid); - data->mid = UINT32_MAX; - -#ifdef USE_LIBPSL - if(data->psl == &multi->psl) - data->psl = NULL; -#endif - if(data->state.internal) - Curl_close(&data); - } while(Curl_uint32_tbl_next(&multi->xfers, mid, &mid, &entry)); - } - -#ifdef USE_RESOLV_THREADED - Curl_async_thrdd_multi_destroy(multi, !multi->quick_exit); -#endif - Curl_cpool_destroy(&multi->cpool); - Curl_cshutdn_destroy(&multi->cshutdn, multi->admin); - if(multi->admin) { - CURL_TRC_M(multi->admin, "multi_cleanup, closing admin handle, done"); - multi->admin->multi = NULL; - Curl_uint32_tbl_remove(&multi->xfers, multi->admin->mid); - Curl_close(&multi->admin); - } - - multi->magic = 0; /* not good anymore */ - - Curl_multi_ev_cleanup(multi); - Curl_hash_destroy(&multi->proto_hash); - Curl_dnscache_destroy(&multi->dnscache); - Curl_psl_destroy(&multi->psl); -#ifdef USE_SSL - Curl_ssl_scache_destroy(multi->ssl_scache); -#endif - -#ifdef USE_WINSOCK - WSACloseEvent(multi->wsa_event); -#endif -#ifdef ENABLE_WAKEUP - Curl_wakeup_destroy(multi->wakeup_pair); -#endif - - multi_xfer_bufs_free(multi); - Curl_mntfy_cleanup(multi); -#ifdef DEBUGBUILD - if(Curl_uint32_tbl_count(&multi->xfers)) { - multi_xfer_tbl_dump(multi); - DEBUGASSERT(0); - } -#endif - Curl_uint32_bset_destroy(&multi->process); - Curl_uint32_bset_destroy(&multi->dirty); - Curl_uint32_bset_destroy(&multi->pending); - Curl_uint32_bset_destroy(&multi->msgsent); - Curl_uint32_tbl_destroy(&multi->xfers); - curlx_free(multi); - - return CURLM_OK; - } - return CURLM_BAD_HANDLE; -} - -/* - * curl_multi_info_read() - * - * This function is the primary way for a multi/multi_socket application to - * figure out if a transfer has ended. We MUST make this function as fast as - * possible as it will be polled frequently and we MUST NOT scan any lists in - * here to figure out things. We must scale fine to thousands of handles and - * beyond. The current design is fully O(1). - */ - -CURLMsg *curl_multi_info_read(CURLM *m, int *msgs_in_queue) -{ - struct Curl_message *msg; - struct Curl_multi *multi = m; - - *msgs_in_queue = 0; /* default to none */ - - if(GOOD_MULTI_HANDLE(multi) && - !multi->in_callback && - Curl_llist_count(&multi->msglist)) { - /* there is one or more messages in the list */ - struct Curl_llist_node *e; - - /* extract the head of the list to return */ - e = Curl_llist_head(&multi->msglist); - - msg = Curl_node_elem(e); - - /* remove the extracted entry */ - Curl_node_remove(e); - - *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist)); - - return &msg->extmsg; - } - return NULL; -} - -void Curl_multi_will_close(struct Curl_easy *data, curl_socket_t s) -{ - if(data) { - struct Curl_multi *multi = data->multi; - if(multi) { - CURL_TRC_M(data, "Curl_multi_will_close fd=%" FMT_SOCKET_T, s); - Curl_multi_ev_socket_done(multi, data, s); - } - } -} - -/* - * add_next_timeout() - * - * Each Curl_easy has a list of timeouts. The add_next_timeout() is called - * when it has been removed from the splay tree because the timeout has - * expired. This function is then to advance in the list to pick the next - * timeout to use (skip the already expired ones) and add this node back to - * the splay tree again. - * - * The splay tree only has each sessionhandle as a single node and the nearest - * timeout is used to sort it on. - */ -static CURLMcode add_next_timeout(const struct curltime *pnow, - struct Curl_multi *multi, - struct Curl_easy *d) -{ - struct curltime *tv = &d->state.expiretime; - struct Curl_llist *list = &d->state.timeoutlist; - struct Curl_llist_node *e; - - /* move over the timeout list for this specific handle and remove all - timeouts that are now passed tense and store the next pending - timeout in *tv */ - for(e = Curl_llist_head(list); e;) { - struct Curl_llist_node *n = Curl_node_next(e); - struct time_node *node = Curl_node_elem(e); - timediff_t diff = curlx_ptimediff_us(&node->time, pnow); - if(diff <= 0) - /* remove outdated entry */ - Curl_node_remove(e); - else - /* the list is sorted so get out on the first mismatch */ - break; - e = n; - } - e = Curl_llist_head(list); - if(!e) { - /* clear the expire times within the handles that we remove from the - splay tree */ - tv->tv_sec = 0; - tv->tv_usec = 0; - } - else { - struct time_node *node = Curl_node_elem(e); - /* copy the first entry to 'tv' */ - memcpy(tv, &node->time, sizeof(*tv)); - - /* Insert this node again into the splay. Keep the timer in the list in - case we need to recompute future timers. */ - multi->timetree = Curl_splayinsert(tv, multi->timetree, - &d->state.timenode); - } - return CURLM_OK; -} - -static void multi_mark_expired_as_dirty(struct Curl_multi *multi, - const struct curltime *ts) -{ - struct Curl_easy *data = NULL; - struct Curl_tree *t = NULL; - - /* - * The loop following here will go on as long as there are expire-times left - * to process (compared to `ts`) in the splay and 'data' will be - * re-assigned for every expired handle we deal with. - */ - while(1) { - /* Check if there is one (more) expired timer to deal with! This function - extracts a matching node if there is one */ - multi->timetree = Curl_splaygetbest(ts, multi->timetree, &t); - if(!t) - return; - - data = Curl_splayget(t); /* assign this for next loop */ - if(!data) - continue; -#ifdef CURLVERBOSE - if(CURL_TRC_TIMER_is_verbose(data)) { - struct Curl_llist_node *e = Curl_llist_head(&data->state.timeoutlist); - if(e) { - struct time_node *n = Curl_node_elem(e); - CURL_TRC_TIMER(data, n->eid, "has expired"); - } - } -#endif - (void)add_next_timeout(ts, multi, data); - Curl_multi_mark_dirty(data); - } -} - -static CURLMcode multi_run_dirty(struct Curl_multi *multi, - struct Curl_sigpipe_ctx *sigpipe_ctx, - uint32_t *pnum) -{ - CURLMcode mresult = CURLM_OK; - uint32_t mid; - - *pnum = 0; - if(Curl_uint32_bset_first(&multi->dirty, &mid)) { - do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - if(data) { - CURL_TRC_M(data, "multi_run_dirty"); - - if(!Curl_uint32_bset_contains(&multi->process, mid)) { - /* We are no longer processing this transfer */ - Curl_uint32_bset_remove(&multi->dirty, mid); - continue; - } - - (*pnum)++; - /* runsingle() clears the dirty mid */ - mresult = multi_runsingle(multi, data, sigpipe_ctx); - - if(CURLM_OK >= mresult) { - /* reassess event handling of data */ - mresult = Curl_multi_ev_assess_xfer(multi, data); - if(mresult) - goto out; - } - } - else { - CURL_TRC_M(multi->admin, "multi_run_dirty, %u no longer found", mid); - Curl_uint32_bset_remove(&multi->dirty, mid); - } - } while(Curl_uint32_bset_next(&multi->dirty, mid, &mid)); - } - -out: - return mresult; -} - -static CURLMcode multi_socket(struct Curl_multi *multi, - bool checkall, - curl_socket_t s, - int ev_bitmask, - int *running_handles) -{ - CURLMcode mresult = CURLM_OK; - struct Curl_sigpipe_ctx pipe_ctx; - uint32_t run_xfers; - - (void)ev_bitmask; - sigpipe_init(&pipe_ctx); - - if(checkall) { - /* *perform() deals with running_handles on its own */ - mresult = multi_perform(multi, running_handles); - - if(mresult != CURLM_BAD_HANDLE) { - /* Reassess event status of all active transfers */ - mresult = Curl_multi_ev_assess_xfer_bset(multi, &multi->process); - } - goto out; - } - - if(s != CURL_SOCKET_TIMEOUT) { - /* Mark all transfers of that socket as dirty */ - Curl_multi_ev_dirty_xfers(multi, s); - } - else { - /* Asked to run due to time-out. Clear the 'last_expire_ts' variable to - force Curl_update_timer() to trigger a callback to the app again even - if the same timeout is still the one to run after this call. That - handles the case when the application asks libcurl to run the timeout - prematurely. */ - memset(&multi->last_expire_ts, 0, sizeof(multi->last_expire_ts)); - - /* Applications may set `socket_cb` *after* having added transfers - * first. *Then* kick off processing with a - * curl_multi_socket_action(TIMEOUT) afterwards. Make sure our - * admin handle registers its pollset with the callbacks present. */ - mresult = multi_assess_wakeup(multi); - if(mresult) - goto out; - } - - multi_mark_expired_as_dirty(multi, multi_now(multi)); - mresult = multi_run_dirty(multi, &pipe_ctx, &run_xfers); - if(mresult) - goto out; - - if(run_xfers) { - /* Running transfers takes time. With a new timestamp, we might catch - * other expires which are due now. Instead of telling the application - * to set a 0 timeout and call us again, we run them here. - * Do that only once or it might be unfair to transfers on other - * sockets. */ - multi_mark_expired_as_dirty(multi, &multi->now); - mresult = multi_run_dirty(multi, &pipe_ctx, &run_xfers); - } - -out: - sigpipe_restore(&pipe_ctx); - - if(multi_ischanged(multi, TRUE)) - process_pending_handles(multi); - - if(!mresult && CURL_MNTFY_HAS_ENTRIES(multi)) - mresult = Curl_mntfy_dispatch_all(multi); - - if(running_handles) { - unsigned int running = Curl_multi_xfers_running(multi); - *running_handles = (running < INT_MAX) ? (int)running : INT_MAX; - } - - if(CURLM_OK >= mresult) - mresult = Curl_update_timer(multi); - return mresult; -} - -#undef curl_multi_setopt -CURLMcode curl_multi_setopt(CURLM *m, CURLMoption option, ...) -{ - CURLMcode mresult = CURLM_OK; - va_list param; - unsigned long uarg; - struct Curl_multi *multi = m; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - va_start(param, option); - - switch(option) { - case CURLMOPT_SOCKETFUNCTION: - multi->socket_cb = va_arg(param, curl_socket_callback); - break; - case CURLMOPT_SOCKETDATA: - multi->socket_userp = va_arg(param, void *); - break; - case CURLMOPT_PUSHFUNCTION: - multi->push_cb = va_arg(param, curl_push_callback); - break; - case CURLMOPT_PUSHDATA: - multi->push_userp = va_arg(param, void *); - break; - case CURLMOPT_PIPELINING: - multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX ? 1 : 0; - break; - case CURLMOPT_TIMERFUNCTION: - multi->timer_cb = va_arg(param, curl_multi_timer_callback); - break; - case CURLMOPT_TIMERDATA: - multi->timer_userp = va_arg(param, void *); - break; - case CURLMOPT_MAXCONNECTS: - uarg = va_arg(param, unsigned long); - if(uarg <= UINT_MAX) - multi->maxconnects = (unsigned int)uarg; - break; - case CURLMOPT_MAX_HOST_CONNECTIONS: - if(!curlx_sltouz(va_arg(param, long), &multi->max_host_connections)) - mresult = CURLM_BAD_FUNCTION_ARGUMENT; - break; - case CURLMOPT_MAX_TOTAL_CONNECTIONS: - if(!curlx_sltouz(va_arg(param, long), &multi->max_total_connections)) - mresult = CURLM_BAD_FUNCTION_ARGUMENT; - break; - /* options formerly used for pipelining */ - case CURLMOPT_MAX_PIPELINE_LENGTH: - break; - case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE: - break; - case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE: - break; - case CURLMOPT_PIPELINING_SITE_BL: - break; - case CURLMOPT_PIPELINING_SERVER_BL: - break; - case CURLMOPT_MAX_CONCURRENT_STREAMS: { - long streams = va_arg(param, long); - if((streams < 1) || (streams > INT_MAX)) - streams = 100; - multi->max_concurrent_streams = (unsigned int)streams; - break; - } - case CURLMOPT_NETWORK_CHANGED: { - long val = va_arg(param, long); - if(val & CURLMNWC_CLEAR_ALL) - /* In the beginning, all values available to set were 1 by mistake. We - converted this to mean "all", thus setting all the bits - automatically */ - val = CURLMNWC_CLEAR_DNS | CURLMNWC_CLEAR_CONNS; - if(val & CURLMNWC_CLEAR_DNS) { - Curl_dnscache_clear(multi->admin); - } - if(val & CURLMNWC_CLEAR_CONNS) { - Curl_cpool_nw_changed(multi->admin); - } - break; - } - case CURLMOPT_NOTIFYFUNCTION: - multi->ntfy.ntfy_cb = va_arg(param, curl_notify_callback); - break; - case CURLMOPT_NOTIFYDATA: - multi->ntfy.ntfy_cb_data = va_arg(param, void *); - break; - case CURLMOPT_RESOLVE_THREADS_MAX: -#ifdef USE_RESOLV_THREADED - uarg = va_arg(param, long); - if((uarg <= 0) || (uarg > UINT32_MAX)) - mresult = CURLM_BAD_FUNCTION_ARGUMENT; - else { - CURLcode result = Curl_async_thrdd_multi_set_props( - multi, 0, (uint32_t)uarg, 2000); - switch(result) { - case CURLE_OK: - mresult = CURLM_OK; - break; - case CURLE_BAD_FUNCTION_ARGUMENT: - mresult = CURLM_BAD_FUNCTION_ARGUMENT; - break; - case CURLE_OUT_OF_MEMORY: - mresult = CURLM_OUT_OF_MEMORY; - break; - default: - mresult = CURLM_INTERNAL_ERROR; - break; - } - } -#endif - break; - case CURLMOPT_QUICK_EXIT: - multi->quick_exit = va_arg(param, long) ? 1 : 0; - break; - default: - mresult = CURLM_UNKNOWN_OPTION; - break; - } - va_end(param); - return mresult; -} - -/* we define curl_multi_socket() in the public multi.h header */ -#undef curl_multi_socket - -CURLMcode curl_multi_socket(CURLM *m, curl_socket_t s, int *running_handles) -{ - struct Curl_multi *multi = m; - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - if(multi->in_ntfy_callback) - return CURLM_RECURSIVE_API_CALL; - return multi_socket(multi, FALSE, s, 0, running_handles); -} - -CURLMcode curl_multi_socket_action(CURLM *m, curl_socket_t s, - int ev_bitmask, int *running_handles) -{ - struct Curl_multi *multi = m; - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - if(multi->in_ntfy_callback) - return CURLM_RECURSIVE_API_CALL; - return multi_socket(multi, FALSE, s, ev_bitmask, running_handles); -} - -CURLMcode curl_multi_socket_all(CURLM *m, int *running_handles) -{ - struct Curl_multi *multi = m; - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - if(multi->in_ntfy_callback) - return CURLM_RECURSIVE_API_CALL; - return multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); -} - -static bool multi_has_dirties(struct Curl_multi *multi) -{ - uint32_t mid; - if(Curl_uint32_bset_first(&multi->dirty, &mid)) { - do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - if(data) { - if(Curl_uint32_bset_contains(&multi->process, mid)) - return TRUE; - /* We are no longer processing this transfer */ - Curl_uint32_bset_remove(&multi->dirty, mid); - } - else { - CURL_TRC_M(multi->admin, "dirty transfer %u no longer found", mid); - Curl_uint32_bset_remove(&multi->dirty, mid); - } - } while(Curl_uint32_bset_next(&multi->dirty, mid, &mid)); - } - return FALSE; -} - -static void multi_timeout(struct Curl_multi *multi, - struct curltime *expire_time, - long *timeout_ms) -{ - static const struct curltime tv_zero = { 0, 0 }; - VERBOSE(struct Curl_easy *data = NULL); - - if(multi->dead) { - *timeout_ms = 0; - return; - } - - if(multi_has_dirties(multi)) { - *expire_time = *multi_now(multi); - *timeout_ms = 0; - return; - } - else if(multi->timetree) { - const struct curltime *pnow = multi_now(multi); - /* splay the lowest to the bottom */ - multi->timetree = Curl_splay(&tv_zero, multi->timetree); - /* this will not return NULL from a non-empty tree, but some compilers - * are not convinced of that. Analyzers are hard. */ - *expire_time = multi->timetree ? multi->timetree->key : tv_zero; - - /* 'multi->timetree' will be non-NULL here but the compilers sometimes - yell at us if we assume so */ - if(multi->timetree && - curlx_ptimediff_us(&multi->timetree->key, pnow) > 0) { - /* some time left before expiration */ - timediff_t diff_ms = - curlx_timediff_ceil_ms(multi->timetree->key, *pnow); - VERBOSE(data = Curl_splayget(multi->timetree)); - /* this should be safe even on 32-bit archs, as we do not use that - overly long timeouts */ - *timeout_ms = (long)diff_ms; - } - else { - if(multi->timetree) - VERBOSE(data = Curl_splayget(multi->timetree)); - /* 0 means immediately */ - *timeout_ms = 0; - } - } - else { - *expire_time = tv_zero; - *timeout_ms = -1; - } - -#ifdef CURLVERBOSE - if(CURL_TRC_TIMER_is_verbose(data)) { - struct Curl_llist_node *e = Curl_llist_head(&data->state.timeoutlist); - if(e) { - struct time_node *n = Curl_node_elem(e); - CURL_TRC_TIMER(data, n->eid, "gives multi timeout in %ldms", - *timeout_ms); - } - } -#endif -} - -CURLMcode curl_multi_timeout(CURLM *m, - long *timeout_ms) -{ - struct curltime expire_time; - struct Curl_multi *multi = m; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - if(multi->in_callback) - return CURLM_RECURSIVE_API_CALL; - - multi_timeout(multi, &expire_time, timeout_ms); - return CURLM_OK; -} - -/* - * Tell the application it should update its timers, if it subscribes to the - * update timer callback. - */ -CURLMcode Curl_update_timer(struct Curl_multi *multi) -{ - struct curltime expire_ts; - long timeout_ms; - int rc; - bool set_value = FALSE; - - if(!multi->timer_cb || multi->dead) - return CURLM_OK; - multi_timeout(multi, &expire_ts, &timeout_ms); - - if(timeout_ms < 0 && multi->last_timeout_ms < 0) { - /* nothing to do */ - } - else if(timeout_ms < 0) { - /* there is no timeout now but there was one previously */ - CURL_TRC_M(multi->admin, "[TIMER] clear"); - timeout_ms = -1; /* normalize */ - set_value = TRUE; - } - else if(multi->last_timeout_ms < 0) { - CURL_TRC_M(multi->admin, "[TIMER] set %ldms, none before", timeout_ms); - set_value = TRUE; - } - else if(curlx_ptimediff_us(&multi->last_expire_ts, &expire_ts)) { - /* We had a timeout before and have one now, the absolute timestamp - * differs. The relative timeout_ms may be the same, but the starting - * point differs. Let the application restart its timer. */ - CURL_TRC_M(multi->admin, "[TIMER] set %ldms, replace previous", - timeout_ms); - set_value = TRUE; - } - else { - /* We have same expire time as previously. Our relative 'timeout_ms' - * may be different now, but the application has the timer running - * and we do not to tell it to start this again. */ - } - - if(set_value) { - multi->last_expire_ts = expire_ts; - multi->last_timeout_ms = timeout_ms; - set_in_callback(multi, TRUE); - rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp); - set_in_callback(multi, FALSE); - if(rc == -1) { - multi->dead = TRUE; - return CURLM_ABORTED_BY_CALLBACK; - } - } - return CURLM_OK; -} - -/* - * multi_deltimeout() - * - * Remove a given timestamp from the list of timeouts. - */ -static void multi_deltimeout(struct Curl_easy *data, expire_id eid) -{ - struct Curl_llist_node *e; - struct Curl_llist *timeoutlist = &data->state.timeoutlist; - /* find and remove the specific node from the list */ - for(e = Curl_llist_head(timeoutlist); e; e = Curl_node_next(e)) { - struct time_node *n = Curl_node_elem(e); - if(n->eid == eid) { - Curl_node_remove(e); - return; - } - } -} - -/* - * multi_addtimeout() - * - * Add a timestamp to the list of timeouts. Keep the list sorted so that head - * of list is always the timeout nearest in time. - * - */ -static CURLMcode multi_addtimeout(struct Curl_easy *data, - struct curltime *stamp, - expire_id eid) -{ - struct Curl_llist_node *e; - struct time_node *node; - struct Curl_llist_node *prev = NULL; - size_t n; - struct Curl_llist *timeoutlist = &data->state.timeoutlist; - - node = &data->state.expires[eid]; - - /* copy the timestamp and id */ - memcpy(&node->time, stamp, sizeof(*stamp)); - node->eid = eid; /* also marks it as in use */ - - n = Curl_llist_count(timeoutlist); - if(n) { - /* find the correct spot in the list */ - for(e = Curl_llist_head(timeoutlist); e; e = Curl_node_next(e)) { - struct time_node *check = Curl_node_elem(e); - timediff_t diff = curlx_ptimediff_ms(&check->time, &node->time); - if(diff > 0) - break; - prev = e; - } - } - /* else - this is the first timeout on the list */ - - Curl_llist_insert_next(timeoutlist, prev, node, &node->list); - CURL_TRC_TIMER(data, eid, "set for %" FMT_TIMEDIFF_T "ns", - curlx_ptimediff_us(&node->time, Curl_pgrs_now(data))); - return CURLM_OK; -} - -void Curl_expire_ex(struct Curl_easy *data, - timediff_t milli, expire_id id) -{ - struct Curl_multi *multi = data->multi; - struct curltime *curr_expire = &data->state.expiretime; - struct curltime set; - - /* this is only interesting while there is still an associated multi struct - remaining! */ - if(!multi) - return; - - DEBUGASSERT(id < EXPIRE_LAST); - - set = *Curl_pgrs_now(data); - set.tv_sec += (time_t)(milli / 1000); /* may be a 64 to 32-bit conversion */ - set.tv_usec += (int)(milli % 1000) * 1000; - - if(set.tv_usec >= 1000000) { - set.tv_sec++; - set.tv_usec -= 1000000; - } - - /* Remove any timer with the same id */ - multi_deltimeout(data, id); - - /* Add it to the timer list. It must stay in the list until it has expired - in case we need to recompute the minimum timer later. */ - multi_addtimeout(data, &set, id); - - if(curr_expire->tv_sec || curr_expire->tv_usec) { - /* This means that the struct is added as a node in the splay tree. - Compare if the new time is earlier, and only remove-old/add-new if it - is. */ - timediff_t diff = curlx_ptimediff_ms(&set, curr_expire); - int rc; - - if(diff > 0) { - /* The current splay tree entry is sooner than this new expiry time. - We do not need to update our splay tree entry. */ - return; - } - - /* Since this is an updated time, we must remove the previous entry from - the splay tree first and then re-add the new value */ - rc = Curl_splayremove(multi->timetree, &data->state.timenode, - &multi->timetree); - if(rc) - infof(data, "Internal error removing splay node = %d", rc); - } - - /* Indicate that we are in the splay tree and insert the new timer expiry - value since it is our local minimum. */ - *curr_expire = set; - Curl_splayset(&data->state.timenode, data); - multi->timetree = Curl_splayinsert(curr_expire, multi->timetree, - &data->state.timenode); -} - -/* - * Curl_expire() - * - * given a number of milliseconds from now to use to set the 'act before - * this'-time for the transfer, to be extracted by curl_multi_timeout() - * - * The timeout will be added to a queue of timeouts if it defines a moment in - * time that is later than the current head of queue. - * - * Expire replaces a former timeout using the same id if already set. - */ -void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) -{ - Curl_expire_ex(data, milli, id); -} - -/* - * Curl_expire_done() - * - * Removes the expire timer. Marks it as done. - * - */ -void Curl_expire_done(struct Curl_easy *data, expire_id id) -{ - /* remove the timer, if there */ - multi_deltimeout(data, id); - CURL_TRC_TIMER(data, id, "cleared"); -} - -/* - * Curl_expire_clear() - * - * Clear ALL timeout values for this handle. - */ -void Curl_expire_clear(struct Curl_easy *data) -{ - struct Curl_multi *multi = data->multi; - struct curltime *nowp = &data->state.expiretime; - - /* this is only interesting while there is still an associated multi struct - remaining! */ - if(!multi) - return; - - if(nowp->tv_sec || nowp->tv_usec) { - /* Since this is an cleared time, we must remove the previous entry from - the splay tree */ - struct Curl_llist *list = &data->state.timeoutlist; - int rc; - - rc = Curl_splayremove(multi->timetree, &data->state.timenode, - &multi->timetree); - if(rc) - infof(data, "Internal error clearing splay node = %d", rc); - - /* clear the timeout list too */ - Curl_llist_destroy(list, NULL); - - if(data->id >= 0) - CURL_TRC_M(data, "[TIMEOUT] all cleared"); - nowp->tv_sec = 0; - nowp->tv_usec = 0; - } -} - -CURLMcode curl_multi_assign(CURLM *m, curl_socket_t sockfd, - void *sockp) -{ - struct Curl_multi *multi = m; - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - return Curl_multi_ev_assign(multi, sockfd, sockp); -} - -static void move_pending_to_connect(struct Curl_multi *multi, - struct Curl_easy *data) -{ - DEBUGASSERT(data->mstate == MSTATE_PENDING); - - /* Remove this node from the pending set, add into process set */ - Curl_uint32_bset_remove(&multi->pending, data->mid); - Curl_uint32_bset_add(&multi->process, data->mid); - - multistate(data, MSTATE_CONNECT); - Curl_multi_mark_dirty(data); /* make it run */ -} - -/* process_pending_handles() moves a handle from PENDING back into the process - list and change state to CONNECT. - - We do not move all transfers because that can be a significant amount. - Since this is tried every now and then doing too many too often becomes a - performance problem. - - When there is a change for connection limits like max host connections etc, - this likely only allows one new transfer. When there is a pipewait change, - it can potentially allow hundreds of new transfers. - - We could consider an improvement where we store the queue reason and allow - more pipewait rechecks than others. -*/ -static void process_pending_handles(struct Curl_multi *multi) -{ - uint32_t mid = multi->last_pending_mid; - - if(mid) { - while(Curl_uint32_bset_next(&multi->pending, mid, &mid)) { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - if(data) { - move_pending_to_connect(multi, data); - multi->last_pending_mid = mid; - return; - } - /* transfer no longer known, should not happen */ - Curl_uint32_bset_remove(&multi->pending, mid); - DEBUGASSERT(0); - } - /* found no pending transfers with `mid` larger than `last_pending_mid`. - * Start at the beginning of the pending set again. */ - multi->last_pending_mid = 0; - } - - if(Curl_uint32_bset_first(&multi->pending, &mid)) { - do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - if(data) { - move_pending_to_connect(multi, data); - multi->last_pending_mid = mid; - return; - } - /* transfer no longer known, should not happen */ - Curl_uint32_bset_remove(&multi->pending, mid); - DEBUGASSERT(0); - } while(Curl_uint32_bset_next(&multi->pending, mid, &mid)); - } -} - -void Curl_set_in_callback(struct Curl_easy *data, bool value) -{ - if(data && data->multi) - data->multi->in_callback = value; -} - -bool Curl_is_in_callback(struct Curl_easy *data) -{ - return data && data->multi && data->multi->in_callback; -} - -unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi) -{ - DEBUGASSERT(multi); - return multi->max_concurrent_streams; -} - -CURL **curl_multi_get_handles(CURLM *m) -{ - struct Curl_multi *multi = m; - void *entry; - size_t count = Curl_uint32_tbl_count(&multi->xfers); - CURL **a = curlx_malloc(sizeof(struct Curl_easy *) * (count + 1)); - if(a) { - unsigned int i = 0; - uint32_t mid; - - if(Curl_uint32_tbl_first(&multi->xfers, &mid, &entry)) { - do { - struct Curl_easy *data = entry; - DEBUGASSERT(i < count); - if(!data->state.internal) - a[i++] = data; - } while(Curl_uint32_tbl_next(&multi->xfers, mid, &mid, &entry)); - } - a[i] = NULL; /* last entry is a NULL */ - } - return a; -} - -CURLMcode curl_multi_get_offt(CURLM *m, - CURLMinfo_offt info, - curl_off_t *pvalue) -{ - struct Curl_multi *multi = m; - uint32_t n; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - if(!pvalue) - return CURLM_BAD_FUNCTION_ARGUMENT; - - switch(info) { - case CURLMINFO_XFERS_CURRENT: - n = Curl_uint32_tbl_count(&multi->xfers); - if(n && multi->admin) - --n; - *pvalue = (curl_off_t)n; - return CURLM_OK; - case CURLMINFO_XFERS_RUNNING: - n = Curl_uint32_bset_count(&multi->process); - if(n && Curl_uint32_bset_contains(&multi->process, multi->admin->mid)) - --n; - *pvalue = (curl_off_t)n; - return CURLM_OK; - case CURLMINFO_XFERS_PENDING: - *pvalue = (curl_off_t)Curl_uint32_bset_count(&multi->pending); - return CURLM_OK; - case CURLMINFO_XFERS_DONE: - *pvalue = (curl_off_t)Curl_uint32_bset_count(&multi->msgsent); - return CURLM_OK; - case CURLMINFO_XFERS_ADDED: - *pvalue = multi->xfers_total_ever; - return CURLM_OK; - default: - *pvalue = -1; - return CURLM_UNKNOWN_OPTION; - } -} - -CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data, - char **pbuf, size_t *pbuflen) -{ - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - *pbuf = NULL; - *pbuflen = 0; - if(!data->multi) { - failf(data, "transfer has no multi handle"); - return CURLE_FAILED_INIT; - } - if(!data->set.buffer_size) { - failf(data, "transfer buffer size is 0"); - return CURLE_FAILED_INIT; - } - if(data->multi->xfer_buf_borrowed) { - failf(data, "attempt to borrow xfer_buf when already borrowed"); - return CURLE_AGAIN; - } - - if(data->multi->xfer_buf && - data->set.buffer_size > data->multi->xfer_buf_len) { - /* not large enough, get a new one */ - curlx_free(data->multi->xfer_buf); - data->multi->xfer_buf = NULL; - data->multi->xfer_buf_len = 0; - } - - if(!data->multi->xfer_buf) { - data->multi->xfer_buf = curlx_malloc(curlx_uitouz(data->set.buffer_size)); - if(!data->multi->xfer_buf) { - failf(data, "could not allocate xfer_buf of %u bytes", - data->set.buffer_size); - return CURLE_OUT_OF_MEMORY; - } - data->multi->xfer_buf_len = data->set.buffer_size; - } - - data->multi->xfer_buf_borrowed = TRUE; - *pbuf = data->multi->xfer_buf; - *pbuflen = data->multi->xfer_buf_len; - return CURLE_OK; -} - -void Curl_multi_xfer_buf_release(struct Curl_easy *data, char *buf) -{ - (void)buf; - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - DEBUGASSERT(!buf || data->multi->xfer_buf == buf); - data->multi->xfer_buf_borrowed = FALSE; -} - -CURLcode Curl_multi_xfer_ulbuf_borrow(struct Curl_easy *data, - char **pbuf, size_t *pbuflen) -{ - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - *pbuf = NULL; - *pbuflen = 0; - if(!data->multi) { - failf(data, "transfer has no multi handle"); - return CURLE_FAILED_INIT; - } - if(!data->set.upload_buffer_size) { - failf(data, "transfer upload buffer size is 0"); - return CURLE_FAILED_INIT; - } - if(data->multi->xfer_ulbuf_borrowed) { - failf(data, "attempt to borrow xfer_ulbuf when already borrowed"); - return CURLE_AGAIN; - } - - if(data->multi->xfer_ulbuf && - data->set.upload_buffer_size > data->multi->xfer_ulbuf_len) { - /* not large enough, get a new one */ - curlx_free(data->multi->xfer_ulbuf); - data->multi->xfer_ulbuf = NULL; - data->multi->xfer_ulbuf_len = 0; - } - - if(!data->multi->xfer_ulbuf) { - data->multi->xfer_ulbuf = - curlx_malloc(curlx_uitouz(data->set.upload_buffer_size)); - if(!data->multi->xfer_ulbuf) { - failf(data, "could not allocate xfer_ulbuf of %u bytes", - data->set.upload_buffer_size); - return CURLE_OUT_OF_MEMORY; - } - data->multi->xfer_ulbuf_len = data->set.upload_buffer_size; - } - - data->multi->xfer_ulbuf_borrowed = TRUE; - *pbuf = data->multi->xfer_ulbuf; - *pbuflen = data->multi->xfer_ulbuf_len; - return CURLE_OK; -} - -void Curl_multi_xfer_ulbuf_release(struct Curl_easy *data, char *buf) -{ - (void)buf; - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - DEBUGASSERT(!buf || data->multi->xfer_ulbuf == buf); - data->multi->xfer_ulbuf_borrowed = FALSE; -} - -CURLcode Curl_multi_xfer_sockbuf_borrow(struct Curl_easy *data, - size_t blen, char **pbuf) -{ - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - *pbuf = NULL; - if(!data->multi) { - failf(data, "transfer has no multi handle"); - return CURLE_FAILED_INIT; - } - if(data->multi->xfer_sockbuf_borrowed) { - failf(data, "attempt to borrow xfer_sockbuf when already borrowed"); - return CURLE_AGAIN; - } - - if(data->multi->xfer_sockbuf && blen > data->multi->xfer_sockbuf_len) { - /* not large enough, get a new one */ - curlx_free(data->multi->xfer_sockbuf); - data->multi->xfer_sockbuf = NULL; - data->multi->xfer_sockbuf_len = 0; - } - - if(!data->multi->xfer_sockbuf) { - data->multi->xfer_sockbuf = curlx_malloc(blen); - if(!data->multi->xfer_sockbuf) { - failf(data, "could not allocate xfer_sockbuf of %zu bytes", blen); - return CURLE_OUT_OF_MEMORY; - } - data->multi->xfer_sockbuf_len = blen; - } - - data->multi->xfer_sockbuf_borrowed = TRUE; - *pbuf = data->multi->xfer_sockbuf; - return CURLE_OK; -} - -void Curl_multi_xfer_sockbuf_release(struct Curl_easy *data, char *buf) -{ - (void)buf; - DEBUGASSERT(data); - DEBUGASSERT(data->multi); - DEBUGASSERT(!buf || data->multi->xfer_sockbuf == buf); - data->multi->xfer_sockbuf_borrowed = FALSE; -} - -static void multi_xfer_bufs_free(struct Curl_multi *multi) -{ - DEBUGASSERT(multi); - curlx_safefree(multi->xfer_buf); - multi->xfer_buf_len = 0; - multi->xfer_buf_borrowed = FALSE; - curlx_safefree(multi->xfer_ulbuf); - multi->xfer_ulbuf_len = 0; - multi->xfer_ulbuf_borrowed = FALSE; - curlx_safefree(multi->xfer_sockbuf); - multi->xfer_sockbuf_len = 0; - multi->xfer_sockbuf_borrowed = FALSE; -} - -struct Curl_easy *Curl_multi_get_easy(struct Curl_multi *multi, - uint32_t mid) -{ - struct Curl_easy *data = Curl_uint32_tbl_get(&multi->xfers, mid); - if(GOOD_EASY_HANDLE(data)) - return data; - CURL_TRC_M(multi->admin, "invalid easy handle in xfer table for mid=%u", - mid); - Curl_uint32_tbl_remove(&multi->xfers, mid); - return NULL; -} - -unsigned int Curl_multi_xfers_running(struct Curl_multi *multi) -{ - return multi->xfers_alive; -} - -void Curl_multi_mark_dirty(struct Curl_easy *data) -{ - if(data->multi && data->mid != UINT32_MAX) - Curl_uint32_bset_add(&data->multi->dirty, data->mid); -} - -void Curl_multi_clear_dirty(struct Curl_easy *data) -{ - if(data->multi && data->mid != UINT32_MAX) - Curl_uint32_bset_remove(&data->multi->dirty, data->mid); -} - -CURLMcode curl_multi_notify_enable(CURLM *m, unsigned int notification) -{ - struct Curl_multi *multi = m; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - return Curl_mntfy_enable(multi, notification); -} - -CURLMcode curl_multi_notify_disable(CURLM *m, unsigned int notification) -{ - struct Curl_multi *multi = m; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - return Curl_mntfy_disable(multi, notification); -} - -#ifdef DEBUGBUILD -static void multi_xfer_dump(struct Curl_multi *multi, uint32_t mid, - void *entry) -{ - struct Curl_easy *data = entry; - - (void)multi; - if(!data) { - curl_mfprintf(stderr, "mid=%u, entry=NULL, bug in xfer table?\n", mid); - } - else { - curl_mfprintf(stderr, "mid=%u, magic=%s, p=%p, id=%" FMT_OFF_T - ", url=%s\n", - mid, - (data->magic == CURLEASY_MAGIC_NUMBER) ? "GOOD" : "BAD!", - (void *)data, data->id, Curl_bufref_ptr(&data->state.url)); - } -} - -static void multi_xfer_tbl_dump(struct Curl_multi *multi) -{ - uint32_t mid; - void *entry; - curl_mfprintf(stderr, "=== multi xfer table (count=%u, capacity=%u\n", - Curl_uint32_tbl_count(&multi->xfers), - Curl_uint32_tbl_capacity(&multi->xfers)); - if(Curl_uint32_tbl_first(&multi->xfers, &mid, &entry)) { - multi_xfer_dump(multi, mid, entry); - while(Curl_uint32_tbl_next(&multi->xfers, mid, &mid, &entry)) - multi_xfer_dump(multi, mid, entry); - } - curl_mfprintf(stderr, "===\n"); - fflush(stderr); -} -#endif /* DEBUGBUILD */ diff --git a/vendor/curl/lib/multi_ev.c b/vendor/curl/lib/multi_ev.c deleted file mode 100644 index 937e7ce48..000000000 --- a/vendor/curl/lib/multi_ev.c +++ /dev/null @@ -1,627 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "url.h" -#include "cfilters.h" -#include "curl_trc.h" -#include "multiif.h" -#include "multi_ev.h" -#include "select.h" -#include "uint-bset.h" -#include "uint-spbset.h" -#include "multihandle.h" - - -static void mev_in_callback(struct Curl_multi *multi, bool value) -{ - multi->in_callback = value; -} - -/* Information about a socket for which we inform the libcurl application - * what to supervise (CURL_POLL_IN/CURL_POLL_OUT/CURL_POLL_REMOVE) - */ -struct mev_sh_entry { - struct uint32_spbset xfers; /* bitset of transfers `mid`s on this socket */ - struct connectdata *conn; /* connection using this socket or NULL */ - void *user_data; /* libcurl app data via curl_multi_assign() */ - unsigned int action; /* CURL_POLL_IN/CURL_POLL_OUT we last told the - * libcurl application to watch out for */ - unsigned int readers; /* this many transfers want to read */ - unsigned int writers; /* this many transfers want to write */ - BIT(announced); /* this socket has been passed to the socket - callback at least once */ -}; - -static size_t mev_sh_entry_hash(void *key, size_t key_length, size_t slots_num) -{ - curl_socket_t fd = *((curl_socket_t *)key); - (void)key_length; - return (fd % (curl_socket_t)slots_num); -} - -static size_t mev_sh_entry_compare(void *k1, size_t k1_len, - void *k2, size_t k2_len) -{ - (void)k1_len; - (void)k2_len; - return (*((curl_socket_t *)k1)) == (*((curl_socket_t *)k2)); -} - -/* sockhash entry destructor callback */ -static void mev_sh_entry_dtor(void *freethis) -{ - struct mev_sh_entry *entry = (struct mev_sh_entry *)freethis; - Curl_uint32_spbset_destroy(&entry->xfers); - curlx_free(entry); -} - -/* look up a given socket in the socket hash, skip invalid sockets */ -static struct mev_sh_entry *mev_sh_entry_get(struct Curl_hash *sh, - curl_socket_t s) -{ - if(s != CURL_SOCKET_BAD) { - /* only look for proper sockets */ - return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t)); - } - return NULL; -} - -/* make sure this socket is present in the hash for this handle */ -static struct mev_sh_entry *mev_sh_entry_add(struct Curl_hash *sh, - curl_socket_t s) -{ - struct mev_sh_entry *there = mev_sh_entry_get(sh, s); - struct mev_sh_entry *check; - - if(there) { - /* it is present, return fine */ - return there; - } - - /* not present, add it */ - check = curlx_calloc(1, sizeof(struct mev_sh_entry)); - if(!check) - return NULL; /* major failure */ - - Curl_uint32_spbset_init(&check->xfers); - - /* make/add new hash entry */ - if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { - mev_sh_entry_dtor(check); - return NULL; /* major failure */ - } - - return check; /* things are good in sockhash land */ -} - -/* delete the given socket entry from the hash */ -static void mev_sh_entry_kill(struct Curl_multi *multi, curl_socket_t s) -{ - Curl_hash_delete(&multi->ev.sh_entries, (char *)&s, sizeof(curl_socket_t)); -} - -static size_t mev_sh_entry_user_count(struct mev_sh_entry *e) -{ - return Curl_uint32_spbset_count(&e->xfers) + (e->conn ? 1 : 0); -} - -static bool mev_sh_entry_xfer_known(struct mev_sh_entry *e, - struct Curl_easy *data) -{ - return Curl_uint32_spbset_contains(&e->xfers, data->mid); -} - -static bool mev_sh_entry_conn_known(struct mev_sh_entry *e, - struct connectdata *conn) -{ - return (e->conn == conn); -} - -static bool mev_sh_entry_xfer_add(struct mev_sh_entry *e, - struct Curl_easy *data) -{ - /* detect weird values */ - DEBUGASSERT(mev_sh_entry_user_count(e) < 100000); - return Curl_uint32_spbset_add(&e->xfers, data->mid); -} - -static bool mev_sh_entry_conn_add(struct mev_sh_entry *e, - struct connectdata *conn) -{ - /* detect weird values */ - DEBUGASSERT(mev_sh_entry_user_count(e) < 100000); - DEBUGASSERT(!e->conn); - if(e->conn) - return FALSE; - e->conn = conn; - return TRUE; -} - -static bool mev_sh_entry_xfer_remove(struct mev_sh_entry *e, - struct Curl_easy *data) -{ - bool present = Curl_uint32_spbset_contains(&e->xfers, data->mid); - if(present) - Curl_uint32_spbset_remove(&e->xfers, data->mid); - return present; -} - -static bool mev_sh_entry_conn_remove(struct mev_sh_entry *e, - struct connectdata *conn) -{ - DEBUGASSERT(e->conn == conn); - if(e->conn == conn) { - e->conn = NULL; - return TRUE; - } - return FALSE; -} - -/* Purge any information about socket `s`. - * Let the socket callback know as well when necessary */ -static CURLMcode mev_forget_socket(struct Curl_multi *multi, - struct Curl_easy *data, - curl_socket_t s, - const char *cause) -{ - struct mev_sh_entry *entry = mev_sh_entry_get(&multi->ev.sh_entries, s); - int rc = 0; - - if(!entry) /* we never knew or already forgot about this socket */ - return CURLM_OK; - - /* We managed this socket before, tell the socket callback to forget it. */ - if(entry->announced && multi->socket_cb) { - NOVERBOSE((void)cause); - CURL_TRC_M(data, "ev %s, call(fd=%" FMT_SOCKET_T ", ev=REMOVE)", cause, s); - mev_in_callback(multi, TRUE); - rc = multi->socket_cb(data, s, CURL_POLL_REMOVE, - multi->socket_userp, entry->user_data); - mev_in_callback(multi, FALSE); - entry->announced = FALSE; - } - - mev_sh_entry_kill(multi, s); - if(rc == -1) { - multi->dead = TRUE; - return CURLM_ABORTED_BY_CALLBACK; - } - return CURLM_OK; -} - -static CURLMcode mev_sh_entry_update(struct Curl_multi *multi, - struct Curl_easy *data, - struct mev_sh_entry *entry, - curl_socket_t s, - unsigned char last_action, - unsigned char cur_action) -{ - int rc, comboaction; - - /* we should only be called when the callback exists */ - DEBUGASSERT(multi->socket_cb); - if(!multi->socket_cb) - return CURLM_OK; - - /* Transfer `data` goes from `last_action` to `cur_action` on socket `s` - * with `multi->ev.sh_entries` entry `entry`. Update `entry` and trigger - * `multi->socket_cb` on change, if the callback is set. */ - if(last_action == cur_action) /* nothing from `data` changed */ - return CURLM_OK; - - if(last_action & CURL_POLL_IN) { - DEBUGASSERT(entry->readers); - if(!(cur_action & CURL_POLL_IN)) - entry->readers--; - } - else if(cur_action & CURL_POLL_IN) - entry->readers++; - - if(last_action & CURL_POLL_OUT) { - DEBUGASSERT(entry->writers); - if(!(cur_action & CURL_POLL_OUT)) - entry->writers--; - } - else if(cur_action & CURL_POLL_OUT) - entry->writers++; - - DEBUGASSERT(entry->readers <= mev_sh_entry_user_count(entry)); - DEBUGASSERT(entry->writers <= mev_sh_entry_user_count(entry)); - DEBUGASSERT(entry->writers + entry->readers); - - CURL_TRC_M(data, "ev update fd=%" FMT_SOCKET_T ", action '%s%s' -> '%s%s'" - " (%u/%u r/w)", s, - (last_action & CURL_POLL_IN) ? "IN" : "", - (last_action & CURL_POLL_OUT) ? "OUT" : "", - (cur_action & CURL_POLL_IN) ? "IN" : "", - (cur_action & CURL_POLL_OUT) ? "OUT" : "", - entry->readers, entry->writers); - - comboaction = (entry->writers ? CURL_POLL_OUT : 0) | - (entry->readers ? CURL_POLL_IN : 0); - if(((int)entry->action == comboaction)) /* nothing for socket changed */ - return CURLM_OK; - - CURL_TRC_M(data, "ev update call(fd=%" FMT_SOCKET_T ", ev=%s%s)", - s, (comboaction & CURL_POLL_IN) ? "IN" : "", - (comboaction & CURL_POLL_OUT) ? "OUT" : ""); - mev_in_callback(multi, TRUE); - rc = multi->socket_cb(data, s, comboaction, multi->socket_userp, - entry->user_data); - mev_in_callback(multi, FALSE); - entry->announced = TRUE; - if(rc == -1) { - multi->dead = TRUE; - return CURLM_ABORTED_BY_CALLBACK; - } - entry->action = (unsigned int)comboaction; - return CURLM_OK; -} - -static CURLMcode mev_pollset_diff(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn, - struct easy_pollset *ps, - struct easy_pollset *prev_ps) -{ - struct mev_sh_entry *entry; - curl_socket_t s; - unsigned int i, j; - CURLMcode mresult; - - /* The transfer `data` reports in `ps` the sockets it is interested - * in and which combination of CURL_POLL_IN/CURL_POLL_OUT it wants - * to have monitored for events. - * There can be more than 1 transfer interested in the same socket - * and 1 transfer might be interested in more than 1 socket. - * `prev_ps` is the pollset copy from the previous call here. On - * the 1st call it will be empty. - */ - DEBUGASSERT(ps); - DEBUGASSERT(prev_ps); - - /* Handle changes to sockets the transfer is interested in. */ - for(i = 0; i < ps->n; i++) { - unsigned char last_action; - bool first_time = FALSE; /* data/conn appears first time on socket */ - - s = ps->sockets[i]; - /* Have we handled this socket before? */ - entry = mev_sh_entry_get(&multi->ev.sh_entries, s); - if(!entry) { - /* new socket, add new entry */ - first_time = TRUE; - entry = mev_sh_entry_add(&multi->ev.sh_entries, s); - if(!entry) /* fatal */ - return CURLM_OUT_OF_MEMORY; - CURL_TRC_M(data, "ev new entry fd=%" FMT_SOCKET_T, s); - } - else if(conn) { - first_time = !mev_sh_entry_conn_known(entry, conn); - } - else { - first_time = !mev_sh_entry_xfer_known(entry, data); - } - - /* What was the previous action the transfer had regarding this socket? - * If the transfer is new to the socket, disregard the information - * in `last_poll`, because the socket might have been destroyed and - * reopened. We would have cleared the sh_entry for that, but the socket - * might still be mentioned in the hashed pollsets. */ - last_action = 0; - if(first_time) { - if(conn) { - if(!mev_sh_entry_conn_add(entry, conn)) - return CURLM_OUT_OF_MEMORY; - } - else { - if(!mev_sh_entry_xfer_add(entry, data)) - return CURLM_OUT_OF_MEMORY; - } - CURL_TRC_M(data, "ev entry fd=%" FMT_SOCKET_T ", added %s #%" FMT_OFF_T - ", total=%u/%d (xfer/conn)", s, - conn ? "connection" : "transfer", - conn ? conn->connection_id : data->mid, - Curl_uint32_spbset_count(&entry->xfers), - entry->conn ? 1 : 0); - } - else { - for(j = 0; j < prev_ps->n; j++) { - if(s == prev_ps->sockets[j]) { - last_action = prev_ps->actions[j]; - break; - } - } - } - /* track readers/writers changes and report to socket callback */ - mresult = mev_sh_entry_update(multi, data, entry, s, - last_action, ps->actions[i]); - if(mresult) - return mresult; - } - - /* Handle changes to sockets the transfer is NO LONGER interested in. */ - for(i = 0; i < prev_ps->n; i++) { - bool stillused = FALSE; - - s = prev_ps->sockets[i]; - for(j = 0; j < ps->n; j++) { - if(s == ps->sockets[j]) { - /* socket is still supervised */ - stillused = TRUE; - break; - } - } - if(stillused) - continue; - - entry = mev_sh_entry_get(&multi->ev.sh_entries, s); - /* if entry does not exist, we were either never told about it or - * have already cleaned up this socket via Curl_multi_ev_socket_done(). - * In other words: this is perfectly normal */ - if(!entry) - continue; - - if(conn && !mev_sh_entry_conn_remove(entry, conn)) { - /* `conn` says in `prev_ps` that it had been using a socket, - * but `conn` has not been registered for it. - * This should not happen if our book-keeping is correct? */ - CURL_TRC_M(data, "ev entry fd=%" FMT_SOCKET_T ", conn lost " - "interest but is not registered", s); - DEBUGASSERT(NULL); - continue; - } - - if(!conn && !mev_sh_entry_xfer_remove(entry, data)) { - /* `data` says in `prev_ps` that it had been using a socket, - * but `data` has not been registered for it. - * This should not happen if our book-keeping is correct? */ - CURL_TRC_M(data, "ev entry fd=%" FMT_SOCKET_T ", transfer lost " - "interest but is not registered", s); - DEBUGASSERT(NULL); - continue; - } - - if(mev_sh_entry_user_count(entry)) { - /* track readers/writers changes and report to socket callback */ - mresult = mev_sh_entry_update(multi, data, entry, s, - prev_ps->actions[i], 0); - if(mresult) - return mresult; - CURL_TRC_M(data, "ev entry fd=%" FMT_SOCKET_T ", removed transfer, " - "total=%u/%d (xfer/conn)", s, - Curl_uint32_spbset_count(&entry->xfers), - entry->conn ? 1 : 0); - } - else { - mresult = mev_forget_socket(multi, data, s, "last user gone"); - if(mresult) - return mresult; - } - } /* for loop over num */ - - /* Remember for next time */ - Curl_pollset_move(prev_ps, ps); - return CURLM_OK; -} - -static void mev_pollset_dtor(void *key, size_t klen, void *entry) -{ - struct easy_pollset *ps = entry; - (void)key; - (void)klen; - if(ps) { - Curl_pollset_cleanup(ps); - curlx_free(ps); - } -} - -static struct easy_pollset *mev_add_new_conn_pollset(struct connectdata *conn) -{ - struct easy_pollset *ps; - - ps = Curl_pollset_create(); - if(!ps) - return NULL; - if(Curl_conn_meta_set(conn, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) - return NULL; - return ps; -} - -static struct easy_pollset *mev_add_new_xfer_pollset(struct Curl_easy *data) -{ - struct easy_pollset *ps; - - ps = Curl_pollset_create(); - if(!ps) - return NULL; - if(Curl_meta_set(data, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) - return NULL; - return ps; -} - -static struct easy_pollset *mev_get_last_pollset(struct Curl_easy *data, - struct connectdata *conn) -{ - if(data) { - if(conn) - return Curl_conn_meta_get(conn, CURL_META_MEV_POLLSET); - return Curl_meta_get(data, CURL_META_MEV_POLLSET); - } - return NULL; -} - -static CURLMcode mev_assess(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn) -{ - struct easy_pollset ps, *last_ps; - CURLMcode mresult = CURLM_OK; - - if(!multi || !multi->socket_cb) - return CURLM_OK; - - Curl_pollset_init(&ps); - if(conn) { - CURLcode r = Curl_conn_adjust_pollset(data, conn, &ps); - if(r) { - mresult = (r == CURLE_OUT_OF_MEMORY) ? - CURLM_OUT_OF_MEMORY : CURLM_INTERNAL_ERROR; - goto out; - } - } - else - Curl_multi_pollset(data, &ps); - last_ps = mev_get_last_pollset(data, conn); - - if(!last_ps && ps.n) { - if(conn) - last_ps = mev_add_new_conn_pollset(conn); - else - last_ps = mev_add_new_xfer_pollset(data); - if(!last_ps) { - mresult = CURLM_OUT_OF_MEMORY; - goto out; - } - } - - if(last_ps) - mresult = mev_pollset_diff(multi, data, conn, &ps, last_ps); - else - DEBUGASSERT(!ps.n); -out: - Curl_pollset_cleanup(&ps); - return mresult; -} - -CURLMcode Curl_multi_ev_assess_xfer(struct Curl_multi *multi, - struct Curl_easy *data) -{ - return mev_assess(multi, data, NULL); -} - -CURLMcode Curl_multi_ev_assess_conn(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn) -{ - return mev_assess(multi, data, conn); -} - -CURLMcode Curl_multi_ev_assess_xfer_bset(struct Curl_multi *multi, - struct uint32_bset *set) -{ - uint32_t mid; - CURLMcode mresult = CURLM_OK; - - if(multi && multi->socket_cb && Curl_uint32_bset_first(set, &mid)) { - do { - struct Curl_easy *data = Curl_multi_get_easy(multi, mid); - if(data) { - mresult = Curl_multi_ev_assess_xfer(multi, data); - } - } while(!mresult && Curl_uint32_bset_next(set, mid, &mid)); - } - return mresult; -} - -CURLMcode Curl_multi_ev_assign(struct Curl_multi *multi, - curl_socket_t s, - void *user_data) -{ - struct mev_sh_entry *e = mev_sh_entry_get(&multi->ev.sh_entries, s); - if(!e) - return CURLM_BAD_SOCKET; - e->user_data = user_data; - return CURLM_OK; -} - -void Curl_multi_ev_dirty_xfers(struct Curl_multi *multi, - curl_socket_t s) -{ - struct mev_sh_entry *entry; - - DEBUGASSERT(s != CURL_SOCKET_TIMEOUT); - entry = mev_sh_entry_get(&multi->ev.sh_entries, s); - - /* Unmatched socket, we cannot act on it but we ignore this fact. In - real-world tests it has been proved that libevent can in fact give - the application actions even though the socket was previously - asked to get removed, so thus we better survive stray socket actions - and move on. */ - if(entry) { - struct Curl_easy *data; - uint32_t mid; - - if(Curl_uint32_spbset_first(&entry->xfers, &mid)) { - do { - data = Curl_multi_get_easy(multi, mid); - if(data) { - Curl_multi_mark_dirty(data); - } - else { - CURL_TRC_M(multi->admin, "socket transfer %u no longer found", mid); - Curl_uint32_spbset_remove(&entry->xfers, mid); - } - } while(Curl_uint32_spbset_next(&entry->xfers, mid, &mid)); - } - - if(entry->conn) - Curl_multi_mark_dirty(multi->admin); - } -} - -void Curl_multi_ev_socket_done(struct Curl_multi *multi, - struct Curl_easy *data, curl_socket_t s) -{ - mev_forget_socket(multi, data, s, "socket done"); -} - -void Curl_multi_ev_xfer_done(struct Curl_multi *multi, - struct Curl_easy *data) -{ - DEBUGASSERT(!data->conn); /* transfer should have been detached */ - (void)mev_assess(multi, data, NULL); - Curl_meta_remove(data, CURL_META_MEV_POLLSET); -} - -void Curl_multi_ev_conn_done(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn) -{ - (void)mev_assess(multi, data, conn); - Curl_conn_meta_remove(conn, CURL_META_MEV_POLLSET); -} - -void Curl_multi_ev_init(struct Curl_multi *multi, size_t hashsize) -{ - Curl_hash_init(&multi->ev.sh_entries, hashsize, mev_sh_entry_hash, - mev_sh_entry_compare, mev_sh_entry_dtor); -} - -void Curl_multi_ev_cleanup(struct Curl_multi *multi) -{ - Curl_hash_destroy(&multi->ev.sh_entries); -} diff --git a/vendor/curl/lib/multi_ev.h b/vendor/curl/lib/multi_ev.h deleted file mode 100644 index ddbb9331d..000000000 --- a/vendor/curl/lib/multi_ev.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef HEADER_CURL_MULTI_EV_H -#define HEADER_CURL_MULTI_EV_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "hash.h" - -struct Curl_easy; -struct Curl_multi; -struct easy_pollset; -struct uint32_bset; - -/* meta key for event pollset at easy handle or connection */ -#define CURL_META_MEV_POLLSET "meta:mev:ps" - -struct curl_multi_ev { - struct Curl_hash sh_entries; -}; - -/* Setup/teardown of multi event book-keeping. */ -void Curl_multi_ev_init(struct Curl_multi *multi, size_t hashsize); -void Curl_multi_ev_cleanup(struct Curl_multi *multi); - -/* Assign a 'user_data' to be passed to the socket callback when - * invoked with the given socket. This will fail if this socket - * is not active, e.g. the application has not been told to monitor it. */ -CURLMcode Curl_multi_ev_assign(struct Curl_multi *multi, curl_socket_t s, - void *user_data); - -/* Assess the transfer by getting its current pollset, compute - * any changes to the last one and inform the application's socket - * callback if things have changed. */ -CURLMcode Curl_multi_ev_assess_xfer(struct Curl_multi *multi, - struct Curl_easy *data); -/* Assess all easy handles on the list */ -CURLMcode Curl_multi_ev_assess_xfer_bset(struct Curl_multi *multi, - struct uint32_bset *set); -/* Assess the connection by getting its current pollset */ -CURLMcode Curl_multi_ev_assess_conn(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn); - -/* Mark all transfers tied to the given socket as dirty */ -void Curl_multi_ev_dirty_xfers(struct Curl_multi *multi, - curl_socket_t s); - -/* Socket will be closed, forget anything we know about it. */ -void Curl_multi_ev_socket_done(struct Curl_multi *multi, - struct Curl_easy *data, curl_socket_t s); - -/* Transfer is removed from the multi */ -void Curl_multi_ev_xfer_done(struct Curl_multi *multi, - struct Curl_easy *data); - -/* Connection is being destroyed */ -void Curl_multi_ev_conn_done(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn); - -#endif /* HEADER_CURL_MULTI_EV_H */ diff --git a/vendor/curl/lib/multi_ntfy.c b/vendor/curl/lib/multi_ntfy.c deleted file mode 100644 index 1319aaec0..000000000 --- a/vendor/curl/lib/multi_ntfy.c +++ /dev/null @@ -1,207 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "curl_trc.h" -#include "multihandle.h" -#include "multiif.h" -#include "multi_ntfy.h" - - -struct mntfy_entry { - uint32_t mid; - uint32_t type; -}; - -#define CURL_MNTFY_CHUNK_SIZE 128 - -struct mntfy_chunk { - struct mntfy_chunk *next; - size_t r_offset; - size_t w_offset; - struct mntfy_entry entries[CURL_MNTFY_CHUNK_SIZE]; -}; - -static struct mntfy_chunk *mnfty_chunk_create(void) -{ - return curlx_calloc(1, sizeof(struct mntfy_chunk)); -} - -static void mnfty_chunk_destroy(struct mntfy_chunk *chunk) -{ - curlx_free(chunk); -} - -static void mnfty_chunk_reset(struct mntfy_chunk *chunk) -{ - memset(chunk, 0, sizeof(*chunk)); -} - -static bool mntfy_chunk_append(struct mntfy_chunk *chunk, - struct Curl_easy *data, - uint32_t type) -{ - struct mntfy_entry *e; - - if(chunk->w_offset >= CURL_MNTFY_CHUNK_SIZE) - return FALSE; - e = &chunk->entries[chunk->w_offset++]; - e->mid = data->mid; - e->type = type; - return TRUE; -} - -static struct mntfy_chunk *mntfy_non_full_tail(struct curl_multi_ntfy *mntfy) -{ - struct mntfy_chunk *chunk; - if(!mntfy->tail) { - chunk = mnfty_chunk_create(); - if(!chunk) - return NULL; - DEBUGASSERT(!mntfy->head); - mntfy->head = mntfy->tail = chunk; - return chunk; - } - else if(mntfy->tail->w_offset < CURL_MNTFY_CHUNK_SIZE) - return mntfy->tail; - else { /* tail is full. */ - chunk = mnfty_chunk_create(); - if(!chunk) - return NULL; - DEBUGASSERT(mntfy->head); - mntfy->tail->next = chunk; - mntfy->tail = chunk; - return chunk; - } -} - -static void mntfy_chunk_dispatch_all(struct Curl_multi *multi, - struct mntfy_chunk *chunk) -{ - struct mntfy_entry *e; - struct Curl_easy *data; - - if(multi->ntfy.ntfy_cb) { - while((chunk->r_offset < chunk->w_offset) && !multi->ntfy.failure) { - e = &chunk->entries[chunk->r_offset]; - data = e->mid ? Curl_multi_get_easy(multi, e->mid) : multi->admin; - /* only when notification has not been disabled in the meantime */ - if(data && Curl_uint32_bset_contains(&multi->ntfy.enabled, e->type)) { - /* this may cause new notifications to be added! */ - CURL_TRC_M(multi->admin, "[NTFY] dispatch %u to xfer %u", - e->type, e->mid); - multi->ntfy.ntfy_cb(multi, e->type, data, multi->ntfy.ntfy_cb_data); - } - /* once dispatched, safe to increment */ - chunk->r_offset++; - } - } - mnfty_chunk_reset(chunk); -} - -void Curl_mntfy_init(struct Curl_multi *multi) -{ - memset(&multi->ntfy, 0, sizeof(multi->ntfy)); - Curl_uint32_bset_init(&multi->ntfy.enabled); -} - -CURLMcode Curl_mntfy_resize(struct Curl_multi *multi) -{ - if(Curl_uint32_bset_resize(&multi->ntfy.enabled, CURLMNOTIFY_EASY_DONE + 1)) - return CURLM_OUT_OF_MEMORY; - return CURLM_OK; -} - -void Curl_mntfy_cleanup(struct Curl_multi *multi) -{ - while(multi->ntfy.head) { - struct mntfy_chunk *chunk = multi->ntfy.head; - multi->ntfy.head = chunk->next; - mnfty_chunk_destroy(chunk); - } - multi->ntfy.tail = NULL; - Curl_uint32_bset_destroy(&multi->ntfy.enabled); -} - -CURLMcode Curl_mntfy_enable(struct Curl_multi *multi, unsigned int type) -{ - if(type > CURLMNOTIFY_EASY_DONE) - return CURLM_UNKNOWN_OPTION; - Curl_uint32_bset_add(&multi->ntfy.enabled, type); - return CURLM_OK; -} - -CURLMcode Curl_mntfy_disable(struct Curl_multi *multi, unsigned int type) -{ - if(type > CURLMNOTIFY_EASY_DONE) - return CURLM_UNKNOWN_OPTION; - Curl_uint32_bset_remove(&multi->ntfy.enabled, (uint32_t)type); - return CURLM_OK; -} - -void Curl_mntfy_add(struct Curl_easy *data, unsigned int type) -{ - struct Curl_multi *multi = data ? data->multi : NULL; - if(multi && multi->ntfy.ntfy_cb && !multi->ntfy.failure && - Curl_uint32_bset_contains(&multi->ntfy.enabled, (uint32_t)type)) { - /* append to list of outstanding notifications */ - struct mntfy_chunk *tail = mntfy_non_full_tail(&multi->ntfy); - CURL_TRC_M(data, "[NTFY] add %u for xfer %u", type, data->mid); - if(tail) - mntfy_chunk_append(tail, data, (uint32_t)type); - else - multi->ntfy.failure = CURLM_OUT_OF_MEMORY; - multi->ntfy.has_entries = TRUE; - } -} - -CURLMcode Curl_mntfy_dispatch_all(struct Curl_multi *multi) -{ - DEBUGASSERT(!multi->in_ntfy_callback); - multi->in_ntfy_callback = TRUE; - while(multi->ntfy.head && !multi->ntfy.failure) { - struct mntfy_chunk *chunk = multi->ntfy.head; - /* this may cause new notifications to be added! */ - mntfy_chunk_dispatch_all(multi, chunk); - DEBUGASSERT(chunk->r_offset == chunk->w_offset); - - if(chunk == multi->ntfy.tail) /* last one, keep */ - break; - DEBUGASSERT(chunk->next); - DEBUGASSERT(multi->ntfy.head != multi->ntfy.tail); - multi->ntfy.head = chunk->next; - mnfty_chunk_destroy(chunk); - } - multi->in_ntfy_callback = FALSE; - - if(multi->ntfy.failure) { - CURLMcode mresult = multi->ntfy.failure; - multi->ntfy.failure = CURLM_OK; /* reset, once delivered */ - return mresult; - } - else - multi->ntfy.has_entries = FALSE; - return CURLM_OK; -} diff --git a/vendor/curl/lib/multi_ntfy.h b/vendor/curl/lib/multi_ntfy.h deleted file mode 100644 index 05df2d668..000000000 --- a/vendor/curl/lib/multi_ntfy.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef HEADER_CURL_MULTI_NTFY_H -#define HEADER_CURL_MULTI_NTFY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "uint-bset.h" - -struct Curl_easy; -struct Curl_multi; - -struct curl_multi_ntfy { - curl_notify_callback ntfy_cb; - void *ntfy_cb_data; - struct uint32_bset enabled; - struct mntfy_chunk *head; - struct mntfy_chunk *tail; - CURLMcode failure; - BIT(has_entries); -}; - -void Curl_mntfy_init(struct Curl_multi *multi); -CURLMcode Curl_mntfy_resize(struct Curl_multi *multi); -void Curl_mntfy_cleanup(struct Curl_multi *multi); - -CURLMcode Curl_mntfy_enable(struct Curl_multi *multi, unsigned int type); -CURLMcode Curl_mntfy_disable(struct Curl_multi *multi, unsigned int type); - -void Curl_mntfy_add(struct Curl_easy *data, unsigned int type); - -#define CURLM_NTFY(d, t) \ - do { \ - if((d) && (d)->multi && (d)->multi->ntfy.ntfy_cb) \ - Curl_mntfy_add((d), (t)); \ - } while(0) - -#define CURL_MNTFY_HAS_ENTRIES(m) ((m)->ntfy.has_entries) - -CURLMcode Curl_mntfy_dispatch_all(struct Curl_multi *multi); - -#endif /* HEADER_CURL_MULTI_NTFY_H */ diff --git a/vendor/curl/lib/multihandle.h b/vendor/curl/lib/multihandle.h deleted file mode 100644 index c5cdfbe82..000000000 --- a/vendor/curl/lib/multihandle.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef HEADER_CURL_MULTIHANDLE_H -#define HEADER_CURL_MULTIHANDLE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "llist.h" -#include "hash.h" -#include "conncache.h" -#include "cshutdn.h" -#include "dnscache.h" -#include "multi_ev.h" -#include "multi_ntfy.h" -#include "psl.h" -#include "socketpair.h" -#include "uint-bset.h" -#include "uint-spbset.h" -#include "uint-table.h" - -struct connectdata; -struct Curl_easy; - -struct Curl_message { - struct Curl_llist_node list; - /* the 'CURLMsg' is the part that is visible to the external user */ - struct CURLMsg extmsg; -}; - -/* NOTE: if you add a state here, add the name to the statenames[] array - * in curl_trc.c as well! - */ -typedef enum { - MSTATE_INIT, /* 0 - start in this state */ - MSTATE_PENDING, /* no connections, waiting for one */ - MSTATE_SETUP, /* start a new transfer */ - MSTATE_CONNECT, /* resolve/connect has been sent off */ - MSTATE_CONNECTING, /* awaiting the TCP connect to finalize */ - MSTATE_PROTOCONNECT, /* initiate protocol connect procedure */ - MSTATE_PROTOCONNECTING, /* completing the protocol-specific connect phase */ - MSTATE_DO, /* start send off the request (part 1) */ - MSTATE_DOING, /* sending off the request (part 1) */ - MSTATE_DOING_MORE, /* send off the request (part 2) */ - MSTATE_DID, /* done sending off request */ - MSTATE_PERFORMING, /* transfer data */ - MSTATE_RATELIMITING, /* wait because limit-rate exceeded */ - MSTATE_DONE, /* post data transfer operation */ - MSTATE_COMPLETED, /* operation complete */ - MSTATE_MSGSENT, /* the operation complete message is sent */ - MSTATE_LAST /* not a true state, never use this */ -} CURLMstate; - -#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) - -#if !defined(CURL_DISABLE_SOCKETPAIR) && !defined(USE_WINSOCK) -#define ENABLE_WAKEUP -#endif - -/* value for MAXIMUM CONCURRENT STREAMS upper limit */ -#define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1) - -/* This is the struct known as CURLM on the outside */ -struct Curl_multi { - /* First a simple identifier to easier detect if a user mix up - this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */ - unsigned int magic; - - unsigned int xfers_alive; /* amount of added transfers that have - not yet reached COMPLETE state */ - curl_off_t xfers_total_ever; /* total of added transfers, ever. */ - struct uint32_tbl xfers; /* transfers added to this multi */ - /* Each transfer's mid may be present in at most one of these */ - struct uint32_bset process; /* transfer being processed */ - struct uint32_bset dirty; /* transfer to be run NOW, e.g. ASAP. */ - struct uint32_bset pending; /* transfers in waiting (conn limit etc.) */ - struct uint32_bset msgsent; /* transfers done with message for application */ - - struct Curl_llist msglist; /* a list of messages from completed transfers */ - - struct Curl_easy *admin; /* internal easy handle for admin operations. - gets assigned `mid` 0 on multi init */ - - /* callback function and user data pointer for the *socket() API */ - curl_socket_callback socket_cb; - void *socket_userp; - - /* callback function and user data pointer for server push */ - curl_push_callback push_cb; - void *push_userp; - - struct Curl_dnscache dnscache; /* DNS cache */ - struct Curl_ssl_scache *ssl_scache; /* TLS session pool */ -#ifdef USE_RESOLV_THREADED - struct curl_thrdq *resolv_thrdq; -#endif - -#ifdef USE_LIBPSL - /* PSL cache. */ - struct PslCache psl; -#endif - - /* current time for transfers running in this multi handle */ - struct curltime now; - /* timetree points to the splay-tree of time nodes to figure out expire - times of all currently set timers */ - struct Curl_tree *timetree; - - /* buffer used for transfer data, lazy initialized */ - char *xfer_buf; /* the actual buffer */ - size_t xfer_buf_len; /* the allocated length */ - /* buffer used for upload data, lazy initialized */ - char *xfer_ulbuf; /* the actual buffer */ - size_t xfer_ulbuf_len; /* the allocated length */ - /* buffer used for socket I/O operations, lazy initialized */ - char *xfer_sockbuf; /* the actual buffer */ - size_t xfer_sockbuf_len; /* the allocated length */ - - /* multi event related things */ - struct curl_multi_ev ev; - /* multi notification related things */ - struct curl_multi_ntfy ntfy; - - /* `proto_hash` is a general key-value store for protocol implementations - * with the lifetime of the multi handle. The number of elements kept here - * should be in the order of supported protocols (and sub-protocols like - * TLS), *not* in the order of connections or current transfers! - * Elements need to be added with their own destructor to be invoked when - * the multi handle is cleaned up (see Curl_hash_add2()).*/ - struct Curl_hash proto_hash; - - struct cshutdn cshutdn; /* connection shutdown handling */ - struct cpool cpool; /* connection pool (bundles) */ - - size_t max_host_connections; /* if >0, a fixed limit of the maximum number - of connections per host */ - size_t max_total_connections; /* if >0, a fixed limit of the maximum number - of connections in total */ - - /* timer callback and user data pointer for the *socket() API */ - curl_multi_timer_callback timer_cb; - void *timer_userp; - long last_timeout_ms; /* the last timeout value set via timer_cb */ - struct curltime last_expire_ts; /* timestamp of last expiry */ - -#ifdef USE_WINSOCK - WSAEVENT wsa_event; /* Winsock event used for waits */ -#endif -#ifdef ENABLE_WAKEUP - curl_socket_t wakeup_pair[2]; /* eventfd()/pipe()/socketpair() used for - wakeup 0 is used for read, 1 is used - for write */ -#endif - unsigned int max_concurrent_streams; - unsigned int maxconnects; /* if >0, a fixed limit of the maximum number of - entries we are allowed to grow the connection - cache to */ -#ifdef DEBUGBUILD - unsigned int now_access_count; -#endif - uint32_t last_pending_mid; /* mid of last pending transfer rescheduled */ - uint32_t last_resolv_id; /* id of the last DNS resolve operation */ - BIT(ipv6_works); - BIT(multiplexing); /* multiplexing wanted */ - BIT(recheckstate); /* see Curl_multi_connchanged */ - BIT(in_callback); /* true while executing a callback */ - BIT(in_ntfy_callback); /* true while dispatching notifications */ -#ifdef USE_OPENSSL - BIT(ssl_seeded); -#endif - BIT(dead); /* a callback returned error, everything needs to crash and - burn */ - BIT(xfer_buf_borrowed); /* xfer_buf is currently being borrowed */ - BIT(xfer_ulbuf_borrowed); /* xfer_ulbuf is currently being borrowed */ - BIT(xfer_sockbuf_borrowed); /* xfer_sockbuf is currently being borrowed */ - BIT(quick_exit); /* do not join threads on cleanup */ -#ifdef DEBUGBUILD - BIT(warned); /* true after user warned of DEBUGBUILD */ -#endif -}; - -#endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/vendor/curl/lib/multiif.h b/vendor/curl/lib/multiif.h deleted file mode 100644 index 039db269e..000000000 --- a/vendor/curl/lib/multiif.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef HEADER_CURL_MULTIIF_H -#define HEADER_CURL_MULTIIF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Prototypes for library-wide functions provided by multi.c - */ - -void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id); -void Curl_expire_ex(struct Curl_easy *data, - timediff_t milli, expire_id id); -void Curl_expire_clear(struct Curl_easy *data); -void Curl_expire_done(struct Curl_easy *data, expire_id id); -CURLMcode Curl_update_timer(struct Curl_multi *multi) WARN_UNUSED_RESULT; -void Curl_attach_connection(struct Curl_easy *data, - struct connectdata *conn); -void Curl_detach_connection(struct Curl_easy *data); -bool Curl_multiplex_wanted(const struct Curl_multi *multi); -void Curl_set_in_callback(struct Curl_easy *data, bool value); -bool Curl_is_in_callback(struct Curl_easy *data); -CURLcode Curl_preconnect(struct Curl_easy *data); -bool Curl_is_connecting(struct Curl_easy *data); - -void Curl_multi_connchanged(struct Curl_multi *multi); - -/* Internal version of curl_multi_init() accepts size parameters for the - socket, connection and dns hashes */ -struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size, - size_t ev_hashsize, - size_t chashsize, - size_t dnssize, - size_t sesssize); - -/** - * Let the multi handle know that the socket is about to be closed. - * The multi will then remove anything it knows about the socket, so - * when the OS is using this socket (number) again subsequently, - * the internal book keeping will not get confused. - */ -void Curl_multi_will_close(struct Curl_easy *data, curl_socket_t s); - -/* - * Add a handle and move it into PERFORM state at once. For pushed streams. - */ -CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, - struct Curl_easy *data, - struct connectdata *conn); - -/* Return the value of the CURLMOPT_MAX_CONCURRENT_STREAMS option */ -unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi); - -CURLMcode Curl_multi_pollset(struct Curl_easy *data, - struct easy_pollset *ps); - -/** - * Borrow the transfer buffer from the multi, suitable - * for the given transfer `data`. The buffer may only be used in one - * multi processing of the easy handle. It MUST be returned to the - * multi before it can be borrowed again. - * Pointers into the buffer remain only valid as long as it is borrowed. - * - * @param data the easy handle - * @param pbuf on return, the buffer to use or NULL on error - * @param pbuflen on return, the size of *pbuf or 0 on error - * @return CURLE_OK when buffer is available and is returned. - * CURLE_OUT_OF_MEMORy on failure to allocate the buffer, - * CURLE_FAILED_INIT if the easy handle is without multi. - * CURLE_AGAIN if the buffer is borrowed already. - */ -CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data, - char **pbuf, size_t *pbuflen); -/** - * Release the borrowed buffer. All references into the buffer become - * invalid after this. - * @param buf the buffer pointer borrowed for coding error checks. - */ -void Curl_multi_xfer_buf_release(struct Curl_easy *data, char *buf); - -/** - * Borrow the upload buffer from the multi, suitable - * for the given transfer `data`. The buffer may only be used in one - * multi processing of the easy handle. It MUST be returned to the - * multi before it can be borrowed again. - * Pointers into the buffer remain only valid as long as it is borrowed. - * - * @param data the easy handle - * @param pbuf on return, the buffer to use or NULL on error - * @param pbuflen on return, the size of *pbuf or 0 on error - * @return CURLE_OK when buffer is available and is returned. - * CURLE_OUT_OF_MEMORy on failure to allocate the buffer, - * CURLE_FAILED_INIT if the easy handle is without multi. - * CURLE_AGAIN if the buffer is borrowed already. - */ -CURLcode Curl_multi_xfer_ulbuf_borrow(struct Curl_easy *data, - char **pbuf, size_t *pbuflen); - -/** - * Release the borrowed upload buffer. All references into the buffer become - * invalid after this. - * @param buf the upload buffer pointer borrowed for coding error checks. - */ -void Curl_multi_xfer_ulbuf_release(struct Curl_easy *data, char *buf); - -/** - * Borrow the socket scratch buffer from the multi, suitable - * for the given transfer `data`. The buffer may only be used for - * direct socket I/O operation by one connection at a time and MUST be - * returned to the multi before the I/O call returns. - * Pointers into the buffer remain only valid as long as it is borrowed. - * - * @param data the easy handle - * @param blen requested length of the buffer - * @param pbuf on return, the buffer to use or NULL on error - * @return CURLE_OK when buffer is available and is returned. - * CURLE_OUT_OF_MEMORy on failure to allocate the buffer, - * CURLE_FAILED_INIT if the easy handle is without multi. - * CURLE_AGAIN if the buffer is borrowed already. - */ -CURLcode Curl_multi_xfer_sockbuf_borrow(struct Curl_easy *data, - size_t blen, char **pbuf); -/** - * Release the borrowed buffer. All references into the buffer become - * invalid after this. - * @param buf the buffer pointer borrowed for coding error checks. - */ -void Curl_multi_xfer_sockbuf_release(struct Curl_easy *data, char *buf); - -/** - * Get the easy handle for the given mid. - * Returns NULL if not found. - */ -struct Curl_easy *Curl_multi_get_easy(struct Curl_multi *multi, - uint32_t mid); - -/* Get the # of transfers current in process/pending. */ -unsigned int Curl_multi_xfers_running(struct Curl_multi *multi); - -/* Mark a transfer as dirty, e.g. to be rerun at earliest convenience. - * A cheap operation, can be done many times repeatedly. */ -void Curl_multi_mark_dirty(struct Curl_easy *data); -/* Clear transfer from the dirty set. */ -void Curl_multi_clear_dirty(struct Curl_easy *data); - -void Curl_multi_set_now(struct Curl_multi *multi); - -#endif /* HEADER_CURL_MULTIIF_H */ diff --git a/vendor/curl/lib/netrc.c b/vendor/curl/lib/netrc.c deleted file mode 100644 index 72d8feee7..000000000 --- a/vendor/curl/lib/netrc.c +++ /dev/null @@ -1,580 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_NETRC - -#ifdef HAVE_PWD_H -#ifdef __AMIGA__ -#undef __NO_NET_API /* required for AmigaOS to declare getpwuid() */ -#endif -#include -#ifdef __AMIGA__ -#define __NO_NET_API -#endif -#endif - -#include "netrc.h" -#include "strcase.h" -#include "curl_get_line.h" -#include "curlx/fopen.h" -#include "curlx/strparse.h" - -/* Get user and password from .netrc when given a machine name */ - -enum host_lookup_state { - NOTHING, - HOSTFOUND, /* the 'machine' keyword was found */ - HOSTVALID, /* this is "our" machine! */ - MACDEF -}; - -enum found_state { - NONE, - LOGIN, - PASSWORD -}; - -#define FOUND_LOGIN 1 -#define FOUND_PASSWORD 2 - -#define MAX_NETRC_LINE 16384 -#define MAX_NETRC_FILE (128 * 1024) -#define MAX_NETRC_TOKEN 4096 - -/* convert a dynbuf call CURLcode error to a NETRCcode error */ -#define curl2netrc(result) \ - (((result) == CURLE_OUT_OF_MEMORY) ? \ - NETRC_OUT_OF_MEMORY : NETRC_SYNTAX_ERROR) - -static NETRCcode file2memory(const char *filename, struct dynbuf *filebuf) -{ - NETRCcode ret = NETRC_FILE_MISSING; /* if it cannot open the file */ - FILE *file = curlx_fopen(filename, FOPEN_READTEXT); - - if(file) { - curlx_struct_stat stat; - if((curlx_fstat(fileno(file), &stat) == -1) || !S_ISDIR(stat.st_mode)) { - CURLcode result = CURLE_OK; - bool eof; - struct dynbuf linebuf; - curlx_dyn_init(&linebuf, MAX_NETRC_LINE); - ret = NETRC_OK; - do { - const char *line; - /* Curl_get_line always returns lines ending with a newline */ - result = Curl_get_line(&linebuf, file, &eof); - if(!result) { - line = curlx_dyn_ptr(&linebuf); - /* skip comments on load */ - curlx_str_passblanks(&line); - if(*line == '#') - continue; - result = curlx_dyn_add(filebuf, line); - } - if(result) { - curlx_dyn_free(filebuf); - ret = curl2netrc(result); - break; - } - } while(!eof); - curlx_dyn_free(&linebuf); - } - curlx_fclose(file); - } - return ret; -} - -/* bundled parser state to keep function signatures compact */ -struct netrc_state { - char *login; - char *password; - enum host_lookup_state state; - enum found_state keyword; - NETRCcode retcode; - unsigned char found; /* FOUND_LOGIN | FOUND_PASSWORD bits */ - bool our_login; - bool done; - bool specific_login; -}; - -/* - * Parse a quoted token starting after the opening '"'. Handles \n, \r, \t - * escape sequences. Advances *tok_endp past the closing '"'. - * - * Returns NETRC_OK or error. - */ -static NETRCcode netrc_quoted_token(const char **tok_endp, - struct dynbuf *token) -{ - bool escape = FALSE; - NETRCcode rc = NETRC_SYNTAX_ERROR; - const char *tok_end = *tok_endp; - tok_end++; /* pass the leading quote */ - while(*tok_end) { - CURLcode result; - char s = *tok_end; - if(escape) { - escape = FALSE; - switch(s) { - case 'n': - s = '\n'; - break; - case 'r': - s = '\r'; - break; - case 't': - s = '\t'; - break; - } - } - else if(s == '\\') { - escape = TRUE; - tok_end++; - continue; - } - else if(s == '\"') { - tok_end++; /* pass the ending quote */ - rc = NETRC_OK; - break; - } - result = curlx_dyn_addn(token, &s, 1); - if(result) { - *tok_endp = tok_end; - return curl2netrc(result); - } - tok_end++; - } - *tok_endp = tok_end; - return rc; -} - -/* - * Gets the next token from the netrc buffer at *tokp. Writes the token into - * the 'token' dynbuf. Advances *tok_endp past the consumed token in the input - * buffer. Updates *statep for MACDEF newline handling. Sets *lineend = TRUE - * when the line is exhausted. - * - * Returns NETRC_OK or an error code. - */ -static NETRCcode netrc_get_token(const char **tokp, - const char **tok_endp, - struct dynbuf *token, - enum host_lookup_state *statep, - bool *lineend) -{ - const char *tok = *tokp; - const char *tok_end; - - *lineend = FALSE; - curlx_dyn_reset(token); - curlx_str_passblanks(&tok); - - /* tok is first non-space letter */ - if(*statep == MACDEF) { - if((*tok == '\n') || (*tok == '\r')) - *statep = NOTHING; /* end of macro definition */ - *lineend = TRUE; - *tokp = tok; - return NETRC_OK; - } - - if(!*tok || (*tok == '\n')) { - /* end of line */ - *lineend = TRUE; - *tokp = tok; - return NETRC_OK; - } - - tok_end = tok; - if(*tok == '\"') { - /* quoted string */ - NETRCcode ret = netrc_quoted_token(&tok_end, token); - if(ret) - return ret; - } - else { - /* unquoted token */ - size_t len = 0; - CURLcode result; - while(*tok_end > ' ') { - tok_end++; - len++; - } - if(!len) - return NETRC_SYNTAX_ERROR; - result = curlx_dyn_addn(token, tok, len); - if(result) - return curl2netrc(result); - } - - *tok_endp = tok_end; - - if(curlx_dyn_len(token)) - *tokp = curlx_dyn_ptr(token); - else - /* set it to blank to avoid NULL */ - *tokp = ""; - - return NETRC_OK; -} - -/* - * Reset parser for a new machine entry. Frees password and optionally login - * if it was not user-specified. - */ -static void netrc_new_machine(struct netrc_state *ns) -{ - ns->keyword = NONE; - ns->found = 0; - ns->our_login = FALSE; - curlx_safefree(ns->password); - if(!ns->specific_login) - curlx_safefree(ns->login); -} - -/* - * Process a parsed token through the HOSTVALID state machine branch. This - * handles login/password values and keyword transitions for the matched host. - * - * Returns NETRC_OK or an error code. - */ -static NETRCcode netrc_hostvalid(struct netrc_state *ns, const char *tok) -{ - if(ns->keyword == LOGIN) { - if(ns->specific_login) - ns->our_login = !Curl_timestrcmp(ns->login, tok); - else { - ns->our_login = TRUE; - curlx_free(ns->login); - ns->login = curlx_strdup(tok); - if(!ns->login) - return NETRC_OUT_OF_MEMORY; - } - ns->found |= FOUND_LOGIN; - ns->keyword = NONE; - } - else if(ns->keyword == PASSWORD) { - curlx_free(ns->password); - ns->password = curlx_strdup(tok); - if(!ns->password) - return NETRC_OUT_OF_MEMORY; - ns->found |= FOUND_PASSWORD; - ns->keyword = NONE; - } - else if(curl_strequal("login", tok)) - ns->keyword = LOGIN; - else if(curl_strequal("password", tok)) - ns->keyword = PASSWORD; - else if(curl_strequal("machine", tok)) { - /* a new machine here */ - - if(ns->found & FOUND_PASSWORD && - /* a password was provided for this host */ - - ((!ns->specific_login || ns->our_login) || - /* either there was no specific login to search for, or this - is the specific one we wanted */ - (ns->specific_login && !(ns->found & FOUND_LOGIN)))) { - /* or we look for a specific login, but that was not specified */ - - ns->done = TRUE; - return NETRC_OK; - } - - ns->state = HOSTFOUND; - netrc_new_machine(ns); - } - else if(curl_strequal("default", tok)) { - ns->state = HOSTVALID; - ns->retcode = NETRC_OK; - netrc_new_machine(ns); - } - if((ns->found == (FOUND_PASSWORD | FOUND_LOGIN)) && ns->our_login) - ns->done = TRUE; - return NETRC_OK; -} - -/* - * Process one parsed token through the netrc state - * machine. Updates the parser state in *ns. - * Returns NETRC_OK or an error code. - */ -static NETRCcode netrc_handle_token(struct netrc_state *ns, - const char *tok, - const char *host) -{ - switch(ns->state) { - case NOTHING: - if(curl_strequal("macdef", tok)) - ns->state = MACDEF; - else if(curl_strequal("machine", tok)) { - ns->state = HOSTFOUND; - netrc_new_machine(ns); - } - else if(curl_strequal("default", tok)) { - ns->state = HOSTVALID; - ns->retcode = NETRC_OK; - } - break; - case MACDEF: - if(!*tok) - ns->state = NOTHING; - break; - case HOSTFOUND: - if(curl_strequal(host, tok)) { - ns->state = HOSTVALID; - ns->retcode = NETRC_OK; - } - else - ns->state = NOTHING; - break; - case HOSTVALID: - return netrc_hostvalid(ns, tok); - } - return NETRC_OK; -} - -/* - * Finalize the parse result: fill in defaults and free - * resources on error. - */ -static NETRCcode netrc_finalize(struct netrc_state *ns, - char **loginp, - char **passwordp, - struct store_netrc *store) -{ - NETRCcode retcode = ns->retcode; - if(!retcode) { - if(!ns->password && ns->our_login) { - /* success without a password, set a blank one */ - ns->password = curlx_strdup(""); - if(!ns->password) - retcode = NETRC_OUT_OF_MEMORY; - } - else if(!ns->login && !ns->password) - /* a default with no credentials */ - retcode = NETRC_NO_MATCH; - } - if(!retcode) { - /* success */ - if(!ns->specific_login) - *loginp = ns->login; - - /* netrc_finalize() can return a password even when specific_login is set - but our_login is false (e.g., host matched but the requested login - never matched). See test 685. */ - *passwordp = ns->password; - } - else { - curlx_dyn_free(&store->filebuf); - store->loaded = FALSE; - if(!ns->specific_login) - curlx_free(ns->login); - curlx_free(ns->password); - } - return retcode; -} - -/* - * Returns zero on success. - */ -static NETRCcode parsenetrc(struct store_netrc *store, - const char *host, - char **loginp, - char **passwordp, - const char *netrcfile) -{ - const char *netrcbuffer; - struct dynbuf token; - struct dynbuf *filebuf = &store->filebuf; - struct netrc_state ns; - - memset(&ns, 0, sizeof(ns)); - ns.retcode = NETRC_NO_MATCH; - ns.login = *loginp; - ns.specific_login = !!ns.login; - - DEBUGASSERT(!*passwordp); - curlx_dyn_init(&token, MAX_NETRC_TOKEN); - - if(!store->loaded) { - NETRCcode ret = file2memory(netrcfile, filebuf); - if(ret) - return ret; - store->loaded = TRUE; - } - - netrcbuffer = curlx_dyn_ptr(filebuf); - - while(!ns.done) { - const char *tok = netrcbuffer; - while(tok && !ns.done) { - const char *tok_end; - bool lineend; - NETRCcode ret; - - ret = netrc_get_token(&tok, &tok_end, &token, &ns.state, &lineend); - if(ret) { - ns.retcode = ret; - goto out; - } - if(lineend) - break; - - ret = netrc_handle_token(&ns, tok, host); - if(ret) { - ns.retcode = ret; - goto out; - } - /* tok_end cannot point to a null byte here since lines are always - newline terminated */ - DEBUGASSERT(*tok_end); - tok = ++tok_end; - } - if(!ns.done) { - const char *nl = NULL; - if(tok) - nl = strchr(tok, '\n'); - if(!nl) - break; - /* point to next line */ - netrcbuffer = &nl[1]; - } - } /* while !done */ - -out: - curlx_dyn_free(&token); - return netrc_finalize(&ns, loginp, passwordp, store); -} - -const char *Curl_netrc_strerror(NETRCcode ret) -{ - switch(ret) { - default: - return ""; /* not a legit error */ - case NETRC_FILE_MISSING: - return "no such file"; - case NETRC_NO_MATCH: - return "no matching entry"; - case NETRC_OUT_OF_MEMORY: - return "out of memory"; - case NETRC_SYNTAX_ERROR: - return "syntax error"; - } - /* never reached */ -} - -/* - * @unittest: 1304 - * - * *loginp and *passwordp MUST be allocated if they are not NULL when passed - * in. - */ -NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host, - char **loginp, char **passwordp, - const char *netrcfile) -{ - NETRCcode retcode = NETRC_OK; - char *filealloc = NULL; - - if(!netrcfile) { - char *home = NULL; - char *homea = NULL; -#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - char pwbuf[1024]; -#endif - filealloc = curl_getenv("NETRC"); - if(!filealloc) { - homea = curl_getenv("HOME"); /* portable environment reader */ - if(homea) { - home = homea; -#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - } - else { - struct passwd pw, *pw_res; - if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) && - pw_res) { - home = pw.pw_dir; - } -#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - } - else { - struct passwd *pw; - pw = getpwuid(geteuid()); - if(pw) { - home = pw->pw_dir; - } -#elif defined(_WIN32) - } - else { - homea = curl_getenv("USERPROFILE"); - if(homea) { - home = homea; - } -#endif - } - - if(!home) - return NETRC_FILE_MISSING; /* no home directory found (or possibly out - of memory) */ - - filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR); - if(!filealloc) { - curlx_free(homea); - return NETRC_OUT_OF_MEMORY; - } - } - retcode = parsenetrc(store, host, loginp, passwordp, filealloc); - curlx_free(filealloc); -#ifdef _WIN32 - if(retcode == NETRC_FILE_MISSING) { - /* fallback to the old-style "_netrc" file */ - filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR); - if(!filealloc) { - curlx_free(homea); - return NETRC_OUT_OF_MEMORY; - } - retcode = parsenetrc(store, host, loginp, passwordp, filealloc); - curlx_free(filealloc); - } -#endif - curlx_free(homea); - } - else - retcode = parsenetrc(store, host, loginp, passwordp, netrcfile); - return retcode; -} - -void Curl_netrc_init(struct store_netrc *store) -{ - curlx_dyn_init(&store->filebuf, MAX_NETRC_FILE); - store->loaded = FALSE; -} -void Curl_netrc_cleanup(struct store_netrc *store) -{ - curlx_dyn_free(&store->filebuf); - store->loaded = FALSE; -} -#endif diff --git a/vendor/curl/lib/netrc.h b/vendor/curl/lib/netrc.h deleted file mode 100644 index 90318c2bd..000000000 --- a/vendor/curl/lib/netrc.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef HEADER_CURL_NETRC_H -#define HEADER_CURL_NETRC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_NETRC - -#include "curlx/dynbuf.h" - -struct store_netrc { - struct dynbuf filebuf; - char *filename; - BIT(loaded); -}; - -typedef enum { - NETRC_OK, - NETRC_NO_MATCH, /* no matching entry in the file */ - NETRC_SYNTAX_ERROR, /* in the netrc file */ - NETRC_FILE_MISSING, /* the netrc file does not exist */ - NETRC_OUT_OF_MEMORY, /* while parsing netrc */ - NETRC_LAST /* never used */ -} NETRCcode; - -const char *Curl_netrc_strerror(NETRCcode ret); -void Curl_netrc_init(struct store_netrc *store); -void Curl_netrc_cleanup(struct store_netrc *store); - -NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host, - char **loginp, char **passwordp, - const char *netrcfile); -/* Assume: (*passwordp)[0]=0, host[0] != 0. - * If (*loginp)[0] = 0, search for login and password within a machine - * section in the netrc. - * If (*loginp)[0] != 0, search for password within machine and login. - */ -#else -/* disabled */ -#define Curl_netrc_init(x) -#define Curl_netrc_cleanup(x) -#endif - -#endif /* HEADER_CURL_NETRC_H */ diff --git a/vendor/curl/lib/noproxy.c b/vendor/curl/lib/noproxy.c deleted file mode 100644 index 05c59a0f1..000000000 --- a/vendor/curl/lib/noproxy.c +++ /dev/null @@ -1,266 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_PROXY - -#include "curlx/inet_pton.h" -#include "noproxy.h" -#include "curlx/strparse.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#ifdef HAVE_ARPA_INET_H -#include -#endif - -/* - * cidr4_match() returns TRUE if the given IPv4 address is within the - * specified CIDR address range. - * - * @unittest 1614 - */ -UNITTEST bool cidr4_match(const char *ipv4, /* 1.2.3.4 address */ - const char *network, /* 1.2.3.4 address */ - unsigned int bits); -UNITTEST bool cidr4_match(const char *ipv4, /* 1.2.3.4 address */ - const char *network, /* 1.2.3.4 address */ - unsigned int bits) -{ - unsigned int address = 0; - unsigned int check = 0; - - if(bits > 32) - /* strange input */ - return FALSE; - - if(curlx_inet_pton(AF_INET, ipv4, &address) != 1) - return FALSE; - if(curlx_inet_pton(AF_INET, network, &check) != 1) - return FALSE; - - if(bits && (bits != 32)) { - unsigned int mask = 0xffffffff << (32 - bits); - unsigned int haddr = htonl(address); - unsigned int hcheck = htonl(check); -#if 0 - curl_mfprintf(stderr, "Host %s (%x) network %s (%x) " - "bits %u mask %x => %x\n", - ipv4, haddr, network, hcheck, bits, mask, - (haddr ^ hcheck) & mask); -#endif - if((haddr ^ hcheck) & mask) - return FALSE; - return TRUE; - } - return address == check; -} - -/* @unittest 1614 */ -UNITTEST bool cidr6_match(const char *ipv6, const char *network, - unsigned int bits); -UNITTEST bool cidr6_match(const char *ipv6, const char *network, - unsigned int bits) -{ -#ifdef USE_IPV6 - unsigned int bytes; - unsigned int rest; - unsigned char address[16]; - unsigned char check[16]; - - if(!bits) - bits = 128; - - bytes = bits / 8; - rest = bits & 0x07; - if((bytes > 16) || ((bytes == 16) && rest)) - return FALSE; - if(curlx_inet_pton(AF_INET6, ipv6, address) != 1) - return FALSE; - if(curlx_inet_pton(AF_INET6, network, check) != 1) - return FALSE; - if(bytes && memcmp(address, check, bytes)) - return FALSE; - if(rest && ((address[bytes] ^ check[bytes]) & (0xff << (8 - rest)))) - return FALSE; - - return TRUE; -#else - (void)ipv6; - (void)network; - (void)bits; - return FALSE; -#endif -} - -enum nametype { - TYPE_HOST, - TYPE_IPV4, - TYPE_IPV6 -}; - -static bool match_host(const char *token, size_t tokenlen, - const char *name, size_t namelen) -{ - bool match = FALSE; - - /* ignore trailing dots in the token to check */ - if(token[tokenlen - 1] == '.') - tokenlen--; - - if(tokenlen && (*token == '.')) { - /* ignore leading token dot as well */ - token++; - tokenlen--; - } - /* A: example.com matches 'example.com' - B: www.example.com matches 'example.com' - C: nonexample.com DOES NOT match 'example.com' - */ - if(tokenlen == namelen) - /* case A, exact match */ - match = curl_strnequal(token, name, namelen); - else if(tokenlen < namelen) { - /* case B, tailmatch domain */ - match = (name[namelen - tokenlen - 1] == '.') && - curl_strnequal(token, name + (namelen - tokenlen), tokenlen); - } - /* case C passes through, not a match */ - return match; -} - -static bool match_ip(int type, const char *token, size_t tokenlen, - const char *name) -{ - char *slash; - unsigned int bits = 0; - char checkip[128]; - if(tokenlen >= sizeof(checkip)) - /* this cannot match */ - return FALSE; - /* copy the check name to a temp buffer */ - memcpy(checkip, token, tokenlen); - checkip[tokenlen] = 0; - - slash = strchr(checkip, '/'); - /* if the slash is part of this token, use it */ - if(slash) { - curl_off_t value; - const char *p = &slash[1]; - if(curlx_str_number(&p, &value, 128) || *p) - return FALSE; - /* a too large value is rejected in the cidr function below */ - bits = (unsigned int)value; - *slash = 0; /* null-terminate there */ - } - if(type == TYPE_IPV6) - return cidr6_match(name, checkip, bits); - else - return cidr4_match(name, checkip, bits); -} - -/**************************************************************** - * Checks if the host is in the noproxy list. returns TRUE if it matches and - * therefore the proxy should NOT be used. - ****************************************************************/ -bool Curl_check_noproxy(const char *name, const char *no_proxy) -{ - /* - * If we do not have a hostname at all, like for example with a FILE - * transfer, we have nothing to interrogate the noproxy list with. - */ - if(!name || name[0] == '\0') - return FALSE; - - /* no_proxy=domain1.dom,host.domain2.dom - * (a comma-separated list of hosts which should - * not be proxied, or an asterisk to override - * all proxy variables) - */ - if(no_proxy && no_proxy[0]) { - const char *p = no_proxy; - size_t namelen; - char address[16]; - enum nametype type = TYPE_HOST; - if(!strcmp("*", no_proxy)) - return TRUE; - - /* NO_PROXY was specified and it was not only an asterisk */ - - /* Check if name is an IP address; if not, assume it being a hostname. */ - namelen = strlen(name); - if(curlx_inet_pton(AF_INET, name, &address) == 1) - type = TYPE_IPV4; -#ifdef USE_IPV6 - else if(curlx_inet_pton(AF_INET6, name, &address) == 1) - type = TYPE_IPV6; -#endif - else { - /* ignore trailing dots in the hostname */ - if(name[namelen - 1] == '.') - namelen--; - } - - while(*p) { - const char *token; - size_t tokenlen = 0; - - /* pass blanks */ - curlx_str_passblanks(&p); - - token = p; - /* pass over the pattern */ - while(*p && !ISBLANK(*p) && (*p != ',')) { - p++; - tokenlen++; - } - - if(tokenlen) { - bool match = FALSE; - if(type == TYPE_HOST) - match = match_host(token, tokenlen, name, namelen); - else - match = match_ip(type, token, tokenlen, name); - - if(match) - return TRUE; - } - - /* pass blanks after pattern */ - curlx_str_passblanks(&p); - /* if not a comma, this ends the loop */ - if(*p != ',') - break; - /* pass any number of commas */ - while(*p == ',') - p++; - } /* while(*p) */ - } /* NO_PROXY was specified and it was not only an asterisk */ - - return FALSE; -} - -#endif /* CURL_DISABLE_PROXY */ diff --git a/vendor/curl/lib/noproxy.h b/vendor/curl/lib/noproxy.h deleted file mode 100644 index e16c139bb..000000000 --- a/vendor/curl/lib/noproxy.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef HEADER_CURL_NOPROXY_H -#define HEADER_CURL_NOPROXY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_PROXY -bool Curl_check_noproxy(const char *name, const char *no_proxy); -#endif - -#endif /* HEADER_CURL_NOPROXY_H */ diff --git a/vendor/curl/lib/openldap.c b/vendor/curl/lib/openldap.c deleted file mode 100644 index 48bf5b746..000000000 --- a/vendor/curl/lib/openldap.c +++ /dev/null @@ -1,1291 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Howard Chu, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP) - -/* - * Notice that USE_OPENLDAP is only a source code selection switch. When - * libcurl is built with USE_OPENLDAP defined the libcurl source code that - * gets compiled is the code from openldap.c, otherwise the code that gets - * compiled is the code from ldap.c. - * - * When USE_OPENLDAP is defined a recent version of the OpenLDAP library - * might be required for compilation and runtime. In order to use ancient - * OpenLDAP library versions, USE_OPENLDAP shall not be defined. - */ - -#include - -#include "urldata.h" -#include "url.h" -#include "sendf.h" -#include "curl_trc.h" -#include "vtls/vtls.h" -#include "transfer.h" -#include "curl_ldap.h" -#include "curlx/base64.h" -#include "cfilters.h" -#include "connect.h" -#include "curl_sasl.h" -#include "strcase.h" -#include "bufref.h" - -/* - * Uncommenting this will enable the built-in debug logging of the openldap - * library. The debug log level can be set using the CURL_OPENLDAP_TRACE - * environment variable. The debug output is written to stderr. - * - * The library supports the following debug flags: - * LDAP_DEBUG_NONE 0x0000 - * LDAP_DEBUG_TRACE 0x0001 - * LDAP_DEBUG_CONSTRUCT 0x0002 - * LDAP_DEBUG_DESTROY 0x0004 - * LDAP_DEBUG_PARAMETER 0x0008 - * LDAP_DEBUG_ANY 0xffff - * - * For example, use CURL_OPENLDAP_TRACE=0 for no debug, - * CURL_OPENLDAP_TRACE=2 for LDAP_DEBUG_CONSTRUCT messages only, - * CURL_OPENLDAP_TRACE=65535 for all debug message levels. - */ -/* #define CURL_OPENLDAP_DEBUG */ - -/* Machine states. */ -typedef enum { - OLDAP_STOP, /* Do nothing state, stops the state machine */ - OLDAP_SSL, /* Performing SSL handshake. */ - OLDAP_STARTTLS, /* STARTTLS request sent. */ - OLDAP_TLS, /* Performing TLS handshake. */ - OLDAP_MECHS, /* Get SASL authentication mechanisms. */ - OLDAP_SASL, /* SASL binding reply. */ - OLDAP_BIND, /* Simple bind reply. */ - OLDAP_BINDV2, /* Simple bind reply in protocol version 2. */ - OLDAP_LAST /* Never used */ -} ldapstate; - -#ifndef _LDAP_PVT_H -extern int ldap_pvt_url_scheme2proto(const char *); -extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, - LDAP **ld); -#endif - -static Curl_recv oldap_recv; - -struct ldapconninfo { - struct SASL sasl; /* SASL-related parameters */ - LDAP *ld; /* Openldap connection handle. */ - Curl_recv *recv; /* For stacking SSL handler */ - Curl_send *send; - struct berval *servercred; /* SASL data from server. */ - ldapstate state; /* Current machine state. */ - int proto; /* LDAP_PROTO_TCP/LDAP_PROTO_UDP/LDAP_PROTO_IPC */ - int msgid; /* Current message id. */ -}; - -struct ldapreqinfo { - int msgid; - int nument; -}; - -/* meta key for storing ldapconninfo at easy handle */ -#define CURL_META_LDAP_EASY "meta:proto:ldap:easy" -/* meta key for storing ldapconninfo at connection */ -#define CURL_META_LDAP_CONN "meta:proto:ldap:conn" - -/* - * oldap_state() - * - * This is the ONLY way to change LDAP state! - */ -static void oldap_state(struct Curl_easy *data, struct ldapconninfo *li, - ldapstate newstate) -{ -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - /* for debug purposes */ - static const char * const names[] = { - "STOP", - "SSL", - "STARTTLS", - "TLS", - "MECHS", - "SASL", - "BIND", - "BINDV2", - /* LAST */ - }; - - if(li->state != newstate) - infof(data, "LDAP %p state change from %s to %s", - (void *)li, names[li->state], names[newstate]); -#else - (void)data; -#endif - li->state = newstate; -} - -/* Map some particular LDAP error codes to CURLcode values. */ -static CURLcode oldap_map_error(int rc, CURLcode result) -{ - switch(rc) { - case LDAP_NO_MEMORY: - return CURLE_OUT_OF_MEMORY; - case LDAP_INVALID_CREDENTIALS: - return CURLE_LOGIN_DENIED; - case LDAP_PROTOCOL_ERROR: - return CURLE_UNSUPPORTED_PROTOCOL; - case LDAP_INSUFFICIENT_ACCESS: - return CURLE_REMOTE_ACCESS_DENIED; - } - return result; -} - -static CURLcode oldap_url_parse(struct Curl_easy *data, LDAPURLDesc **ludp) -{ - CURLcode result = CURLE_OK; - int rc = LDAP_URL_ERR_BADURL; - static const char * const url_errs[] = { - "success", - "out of memory", - "bad parameter", - "unrecognized scheme", - "unbalanced delimiter", - "bad URL", - "bad host or port", - "bad or missing attributes", - "bad or missing scope", - "bad or missing filter", - "bad or missing extensions" - }; - - *ludp = NULL; - if(!data->state.up.user && !data->state.up.password && - !data->state.up.options) - rc = ldap_url_parse(Curl_bufref_ptr(&data->state.url), ludp); - if(rc != LDAP_URL_SUCCESS) { - const char *msg = "url parsing problem"; - - result = rc == LDAP_URL_ERR_MEM ? CURLE_OUT_OF_MEMORY : - CURLE_URL_MALFORMAT; - rc -= LDAP_URL_SUCCESS; - if((size_t)rc < CURL_ARRAYSIZE(url_errs)) - msg = url_errs[rc]; - failf(data, "LDAP local: %s", msg); - } - return result; -} - -/* Parse the login options. */ -static CURLcode oldap_parse_login_options(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - const char *ptr = conn->options; - - DEBUGASSERT(li); - if(!li) - return CURLE_FAILED_INIT; - - while(!result && ptr && *ptr) { - const char *key = ptr; - const char *value; - - while(*ptr && *ptr != '=') - ptr++; - - value = ptr + 1; - - while(*ptr && *ptr != ';') - ptr++; - - if(checkprefix("AUTH=", key)) - result = Curl_sasl_parse_url_auth_option(&li->sasl, value, ptr - value); - else - result = CURLE_SETOPT_OPTION_SYNTAX; - - if(*ptr == ';') - ptr++; - } - - return result == CURLE_URL_MALFORMAT ? CURLE_SETOPT_OPTION_SYNTAX : result; -} - -static CURLcode oldap_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result; - LDAPURLDesc *lud; - (void)conn; - - /* Early URL syntax check. */ - result = oldap_url_parse(data, &lud); - ldap_free_urldesc(lud); - - return result; -} - -/* - * Get the SASL authentication challenge from the server credential buffer. - */ -static CURLcode oldap_get_message(struct Curl_easy *data, struct bufref *out) -{ - struct ldapconninfo *li = - Curl_conn_meta_get(data->conn, CURL_META_LDAP_CONN); - struct berval *servercred = li ? li->servercred : NULL; - DEBUGASSERT(li); - if(!li) - return CURLE_FAILED_INIT; - - if(!servercred || !servercred->bv_val) - return CURLE_WEIRD_SERVER_REPLY; - Curl_bufref_set(out, servercred->bv_val, servercred->bv_len, NULL); - return CURLE_OK; -} - -/* - * Sends an initial SASL bind request to the server. - */ -static CURLcode oldap_perform_auth(struct Curl_easy *data, const char *mech, - const struct bufref *initresp) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - struct berval cred; - struct berval *pcred = &cred; - int rc; - - DEBUGASSERT(li); - if(!li) - return CURLE_FAILED_INIT; - cred.bv_val = (char *)CURL_UNCONST(Curl_bufref_ptr(initresp)); - cred.bv_len = Curl_bufref_len(initresp); - if(!cred.bv_val) - pcred = NULL; - rc = ldap_sasl_bind(li->ld, NULL, mech, pcred, NULL, NULL, &li->msgid); - if(rc != LDAP_SUCCESS) - return oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND); - return CURLE_OK; -} - -/* - * Sends SASL continuation. - */ -static CURLcode oldap_continue_auth(struct Curl_easy *data, const char *mech, - const struct bufref *resp) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - struct berval cred; - struct berval *pcred = &cred; - int rc; - - if(!li) - return CURLE_FAILED_INIT; - cred.bv_val = (char *)CURL_UNCONST(Curl_bufref_ptr(resp)); - cred.bv_len = Curl_bufref_len(resp); - if(!cred.bv_val) - pcred = NULL; - rc = ldap_sasl_bind(li->ld, NULL, mech, pcred, NULL, NULL, &li->msgid); - if(rc != LDAP_SUCCESS) - return oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND); - return CURLE_OK; -} - -/* - * Sends SASL bind cancellation. - */ -static CURLcode oldap_cancel_auth(struct Curl_easy *data, const char *mech) -{ - struct ldapconninfo *li = - Curl_conn_meta_get(data->conn, CURL_META_LDAP_CONN); - int rc; - - (void)mech; - if(!li) - return CURLE_FAILED_INIT; - rc = ldap_sasl_bind(li->ld, NULL, LDAP_SASL_NULL, NULL, NULL, NULL, - &li->msgid); - if(rc != LDAP_SUCCESS) - return oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND); - return CURLE_OK; -} - -/* Starts LDAP simple bind. */ -static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - const char *binddn = NULL; - struct berval passwd; - int rc; - - if(!li) - return CURLE_FAILED_INIT; - passwd.bv_val = NULL; - passwd.bv_len = 0; - - if(data->state.aptr.user) { - binddn = conn->user; - passwd.bv_val = conn->passwd; - passwd.bv_len = strlen(passwd.bv_val); - } - - rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd, - NULL, NULL, &li->msgid); - if(rc != LDAP_SUCCESS) - return oldap_map_error(rc, - data->state.aptr.user ? - CURLE_LOGIN_DENIED : CURLE_LDAP_CANNOT_BIND); - oldap_state(data, li, newstate); - return CURLE_OK; -} - -/* Query the supported SASL authentication mechanisms. */ -static CURLcode oldap_perform_mechs(struct Curl_easy *data) -{ - struct ldapconninfo *li = - Curl_conn_meta_get(data->conn, CURL_META_LDAP_CONN); - int rc; - static const char * const supportedSASLMechanisms[] = { - "supportedSASLMechanisms", - NULL - }; - - if(!li) - return CURLE_FAILED_INIT; - /* Casting away the const for the 3rd parameter that the LDAP API expects as - a non-const char ** is potentially unsafe but we believe the lack of - const in the API was an oversight and that no LDAP implementation - actually modifies the input. */ - rc = ldap_search_ext(li->ld, "", LDAP_SCOPE_BASE, "(objectclass=*)", - (char **)CURL_UNCONST(supportedSASLMechanisms), 0, - NULL, NULL, NULL, 0, &li->msgid); - if(rc != LDAP_SUCCESS) - return oldap_map_error(rc, CURLE_LOGIN_DENIED); - oldap_state(data, li, OLDAP_MECHS); - return CURLE_OK; -} - -/* Starts SASL bind. */ -static CURLcode oldap_perform_sasl(struct Curl_easy *data) -{ - struct ldapconninfo *li = - Curl_conn_meta_get(data->conn, CURL_META_LDAP_CONN); - saslprogress progress = SASL_IDLE; - CURLcode result; - - if(!li) - return CURLE_FAILED_INIT; - result = Curl_sasl_start(&li->sasl, data, TRUE, &progress); - - oldap_state(data, li, OLDAP_SASL); - if(!result && progress != SASL_INPROGRESS) - result = Curl_sasl_is_blocked(&li->sasl, data); - return result; -} - -#ifdef USE_SSL -static int ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg) -{ - sbiod->sbiod_pvt = arg; - return 0; -} - -static int ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod) -{ - sbiod->sbiod_pvt = NULL; - return 0; -} - -/* We do not need to do anything because libcurl does it already */ -static int ldapsb_tls_close(Sockbuf_IO_Desc *sbiod) -{ - (void)sbiod; - return 0; -} - -static int ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) -{ - (void)arg; - if(opt == LBER_SB_OPT_DATA_READY) { - struct Curl_easy *data = sbiod->sbiod_pvt; - return Curl_conn_data_pending(data, FIRSTSOCKET); - } - return 0; -} - -static ber_slen_t ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, - ber_len_t len) -{ - struct Curl_easy *data = sbiod->sbiod_pvt; - ber_slen_t ret = 0; - if(data) { - struct connectdata *conn = data->conn; - if(conn) { - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - CURLcode result = CURLE_RECV_ERROR; - size_t nread; - - if(!li) { - SET_SOCKERRNO(SOCKEINVAL); - return -1; - } - result = (li->recv)(data, FIRSTSOCKET, buf, len, &nread); - if(result == CURLE_AGAIN) { - SET_SOCKERRNO(SOCKEWOULDBLOCK); - } - ret = result ? -1 : (ber_slen_t)nread; - } - } - return ret; -} - -static ber_slen_t ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, - ber_len_t len) -{ - struct Curl_easy *data = sbiod->sbiod_pvt; - ber_slen_t ret = 0; - if(data) { - struct connectdata *conn = data->conn; - if(conn) { - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - CURLcode result = CURLE_SEND_ERROR; - size_t nwritten; - - if(!li) { - SET_SOCKERRNO(SOCKEINVAL); - return -1; - } - result = (li->send)(data, FIRSTSOCKET, buf, len, FALSE, &nwritten); - if(result == CURLE_AGAIN) { - SET_SOCKERRNO(SOCKEWOULDBLOCK); - } - ret = result ? -1 : (ber_slen_t)nwritten; - } - } - return ret; -} - -static Sockbuf_IO ldapsb_tls = { - ldapsb_tls_setup, - ldapsb_tls_remove, - ldapsb_tls_ctrl, - ldapsb_tls_read, - ldapsb_tls_write, - ldapsb_tls_close -}; - -static bool ssl_installed(struct connectdata *conn) -{ - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - return li && li->recv != NULL; -} - -static CURLcode oldap_ssl_connect(struct Curl_easy *data, ldapstate newstate) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - bool ssldone = FALSE; - CURLcode result; - - if(!li) - return CURLE_FAILED_INIT; - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - if(result) - return result; - oldap_state(data, li, newstate); - - if(ssldone) { - Sockbuf *sb; - - /* Install the libcurl SSL handlers into the sockbuf. */ - if((ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb) != LDAP_OPT_SUCCESS) || - ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data)) - return CURLE_FAILED_INIT; - li->recv = conn->recv[FIRSTSOCKET]; - li->send = conn->send[FIRSTSOCKET]; - } - - return result; -} - -/* Send the STARTTLS request */ -static CURLcode oldap_perform_starttls(struct Curl_easy *data) -{ - struct ldapconninfo *li = - Curl_conn_meta_get(data->conn, CURL_META_LDAP_CONN); - int rc; - - if(!li) - return CURLE_FAILED_INIT; - rc = ldap_start_tls(li->ld, NULL, NULL, &li->msgid); - if(rc != LDAP_SUCCESS) - return oldap_map_error(rc, CURLE_USE_SSL_FAILED); - oldap_state(data, li, OLDAP_STARTTLS); - return CURLE_OK; -} -#endif - -static void oldap_easy_dtor(void *key, size_t klen, void *entry) -{ - struct ldapreqinfo *lr = entry; - (void)key; - (void)klen; - curlx_free(lr); -} - -static void oldap_conn_dtor(void *key, size_t klen, void *entry) -{ - struct ldapconninfo *li = entry; - (void)key; - (void)klen; - if(li->ld) { - ldap_unbind_ext(li->ld, NULL, NULL); - li->ld = NULL; - } - curlx_free(li); -} - -/* SASL parameters for the ldap protocol */ -static const struct SASLproto saslldap = { - "ldap", /* The service name */ - oldap_perform_auth, /* Send authentication command */ - oldap_continue_auth, /* Send authentication continuation */ - oldap_cancel_auth, /* Send authentication cancellation */ - oldap_get_message, /* Get SASL response message */ - 0, /* Maximum initial response length (no max) */ - LDAP_SASL_BIND_IN_PROGRESS, /* Code received when continuation is expected */ - LDAP_SUCCESS, /* Code to receive upon authentication success */ - SASL_AUTH_NONE, /* Default mechanisms */ - 0 /* Configuration flags */ -}; - -static CURLcode oldap_connect(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li; - static const int version = LDAP_VERSION3; - char *hosturl = NULL; - CURLcode result; - int rc; -#ifdef CURL_OPENLDAP_DEBUG - static int do_trace = -1; -#endif - - (void)done; - - li = curlx_calloc(1, sizeof(struct ldapconninfo)); - if(!li) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = Curl_conn_meta_set(conn, CURL_META_LDAP_CONN, li, oldap_conn_dtor); - if(result) - goto out; - - li->proto = ldap_pvt_url_scheme2proto(data->state.up.scheme); - - /* Initialize the SASL storage */ - Curl_sasl_init(&li->sasl, data, &saslldap); - - result = oldap_parse_login_options(conn); - if(result) - goto out; - - hosturl = curl_maprintf("%s://%s:%d", - conn->scheme->name, - (data->state.up.hostname[0] == '[') ? - data->state.up.hostname : conn->host.name, - conn->remote_port); - if(!hosturl) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld); - if(rc) { - failf(data, "LDAP local: Cannot connect to %s, %s", - hosturl, ldap_err2string(rc)); - result = CURLE_COULDNT_CONNECT; - goto out; - } - -#ifdef CURL_OPENLDAP_DEBUG - if(do_trace < 0) { - const char *env = getenv("CURL_OPENLDAP_TRACE"); - curl_off_t e = 0; - if(!curlx_str_number(&env, &e, INT_MAX)) - do_trace = e > 0; - } - if(do_trace) - ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace); -#endif - - /* Try version 3 first. */ - ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - - /* Do not chase referrals. */ - ldap_set_option(li->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - - { - ber_len_t max = 256 * 1024; - Sockbuf *sb; - if((ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb) != LDAP_OPT_SUCCESS) || - /* Set the maximum allowed size of an incoming message, which to - OpenLDAP means that it will malloc() memory up to this size. If not - set, there is no limit and we instead risk a malloc() failure. */ - !ber_sockbuf_ctrl(sb, LBER_SB_OPT_SET_MAX_INCOMING, &max)) { - result = CURLE_FAILED_INIT; - goto out; - } - } - -#ifdef USE_SSL - if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - result = oldap_ssl_connect(data, OLDAP_SSL); - goto out; - } - - if(data->set.use_ssl) { - result = oldap_perform_starttls(data); - if(!result || data->set.use_ssl != CURLUSESSL_TRY) - goto out; - } -#endif - - if(li->sasl.prefmech != SASL_AUTH_NONE) { - result = oldap_perform_mechs(data); - goto out; - } - - /* Force bind even if anonymous bind is not needed in protocol version 3 - to detect missing version 3 support. */ - result = oldap_perform_bind(data, OLDAP_BIND); - -out: - curlx_free(hosturl); - return result; -} - -/* Handle the supported SASL mechanisms query response */ -static CURLcode oldap_state_mechs_resp(struct Curl_easy *data, - LDAPMessage *msg, int code) -{ - struct connectdata *conn; - struct ldapconninfo *li; - int rc; - BerElement *ber = NULL; - CURLcode result = CURLE_OK; - struct berval bv, *bvals; - - if(!data) - return CURLE_FAILED_INIT; - - conn = data->conn; - li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - - if(!li) - return CURLE_FAILED_INIT; - switch(ldap_msgtype(msg)) { - case LDAP_RES_SEARCH_ENTRY: - /* Got a list of supported SASL mechanisms. */ - if(code != LDAP_SUCCESS && code != LDAP_NO_RESULTS_RETURNED) - return CURLE_LOGIN_DENIED; - - rc = ldap_get_dn_ber(li->ld, msg, &ber, &bv); - if(rc < 0) - return oldap_map_error(rc, CURLE_BAD_CONTENT_ENCODING); - for(rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals); - rc == LDAP_SUCCESS; - rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals)) { - int i; - - if(!bv.bv_val) - break; - - if(bvals) { - for(i = 0; bvals[i].bv_val; i++) { - size_t llen; - unsigned short mech = - Curl_sasl_decode_mech((const char *)bvals[i].bv_val, - bvals[i].bv_len, &llen); - if(bvals[i].bv_len == llen) - li->sasl.authmechs |= mech; - } - ber_memfree(bvals); - } - } - ber_free(ber, 0); - break; - - case LDAP_RES_SEARCH_RESULT: - switch(code) { - case LDAP_SIZELIMIT_EXCEEDED: - infof(data, "Too many authentication mechanisms"); - FALLTHROUGH(); - case LDAP_SUCCESS: - case LDAP_NO_RESULTS_RETURNED: - if(Curl_sasl_can_authenticate(&li->sasl, data)) - result = oldap_perform_sasl(data); - else - result = CURLE_LOGIN_DENIED; - break; - default: - result = oldap_map_error(code, CURLE_LOGIN_DENIED); - break; - } - break; - default: - break; - } - return result; -} - -/* Handle a SASL bind response. */ -static CURLcode oldap_state_sasl_resp(struct Curl_easy *data, - LDAPMessage *msg, int code) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - CURLcode result = CURLE_OK; - saslprogress progress; - int rc; - - if(!li) - return CURLE_FAILED_INIT; - li->servercred = NULL; - rc = ldap_parse_sasl_bind_result(li->ld, msg, &li->servercred, 0); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: sasl ldap_parse_result %s", ldap_err2string(rc)); - result = oldap_map_error(rc, CURLE_LOGIN_DENIED); - } - else { - result = Curl_sasl_continue(&li->sasl, data, code, &progress); - if(!result && progress != SASL_INPROGRESS) - oldap_state(data, li, OLDAP_STOP); - } - - if(li->servercred) - ber_bvfree(li->servercred); - return result; -} - -/* Handle a simple bind response. */ -static CURLcode oldap_state_bind_resp(struct Curl_easy *data, LDAPMessage *msg, - int code) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - CURLcode result = CURLE_OK; - struct berval *bv = NULL; - int rc; - - if(!li) - return CURLE_FAILED_INIT; - - if(code != LDAP_SUCCESS) - return oldap_map_error(code, CURLE_LDAP_CANNOT_BIND); - - rc = ldap_parse_sasl_bind_result(li->ld, msg, &bv, 0); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: bind ldap_parse_sasl_bind_result %s", - ldap_err2string(rc)); - result = oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND); - } - else - oldap_state(data, li, OLDAP_STOP); - - if(bv) - ber_bvfree(bv); - return result; -} - -static CURLcode oldap_connecting(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - LDAPMessage *msg = NULL; - struct timeval tv = { 0, 0 }; - int code = LDAP_SUCCESS; - int rc; - - if(!li) - return CURLE_FAILED_INIT; - - if(li->state != OLDAP_SSL && li->state != OLDAP_TLS) { - /* Get response to last command. */ - rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, &tv, &msg); - switch(rc) { - case 0: /* Timed out. */ - return CURLE_OK; - case LDAP_RES_SEARCH_ENTRY: - case LDAP_RES_SEARCH_REFERENCE: - break; - default: - li->msgid = 0; /* Nothing to abandon upon error. */ - if(rc < 0) { - failf(data, "LDAP local: connecting ldap_result %s", - ldap_err2string(rc)); - return oldap_map_error(rc, CURLE_COULDNT_CONNECT); - } - break; - } - - /* Get error code from message. */ - rc = ldap_parse_result(li->ld, msg, &code, NULL, NULL, NULL, NULL, 0); - if(rc) - code = rc; - else { - /* store the latest code for later retrieval */ - data->info.httpcode = code; - } - - /* If protocol version 3 is not supported, fallback to version 2. */ - if(code == LDAP_PROTOCOL_ERROR && li->state != OLDAP_BINDV2 && -#ifdef USE_SSL - (ssl_installed(conn) || data->set.use_ssl <= CURLUSESSL_TRY) && -#endif - li->sasl.prefmech == SASL_AUTH_NONE) { - static const int version = LDAP_VERSION2; - - ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - ldap_msgfree(msg); - return oldap_perform_bind(data, OLDAP_BINDV2); - } - } - - /* Handle response message according to current state. */ - switch(li->state) { - -#ifdef USE_SSL - case OLDAP_SSL: - result = oldap_ssl_connect(data, OLDAP_SSL); - if(!result && ssl_installed(conn)) { - if(li->sasl.prefmech != SASL_AUTH_NONE) - result = oldap_perform_mechs(data); - else - result = oldap_perform_bind(data, OLDAP_BIND); - } - break; - case OLDAP_STARTTLS: - if(code != LDAP_SUCCESS) { - if(data->set.use_ssl != CURLUSESSL_TRY) - result = oldap_map_error(code, CURLE_USE_SSL_FAILED); - else if(li->sasl.prefmech != SASL_AUTH_NONE) - result = oldap_perform_mechs(data); - else - result = oldap_perform_bind(data, OLDAP_BIND); - break; - } - result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); - if(result) - break; - FALLTHROUGH(); - case OLDAP_TLS: - result = oldap_ssl_connect(data, OLDAP_TLS); - if(result) - result = oldap_map_error(code, CURLE_USE_SSL_FAILED); - else if(ssl_installed(conn)) { - if(li->sasl.prefmech != SASL_AUTH_NONE) - result = oldap_perform_mechs(data); - else if(data->state.aptr.user) - result = oldap_perform_bind(data, OLDAP_BIND); - else { - /* Version 3 supported: no bind required */ - oldap_state(data, li, OLDAP_STOP); - result = CURLE_OK; - } - } - break; -#endif - - case OLDAP_MECHS: - result = oldap_state_mechs_resp(data, msg, code); - break; - case OLDAP_SASL: - result = oldap_state_sasl_resp(data, msg, code); - break; - case OLDAP_BIND: - case OLDAP_BINDV2: - result = oldap_state_bind_resp(data, msg, code); - break; - default: - /* internal error */ - result = CURLE_COULDNT_CONNECT; - break; - } - - ldap_msgfree(msg); - - *done = li->state == OLDAP_STOP; - if(*done) - conn->recv[FIRSTSOCKET] = oldap_recv; - - if(result && li->msgid) { - ldap_abandon_ext(li->ld, li->msgid, NULL, NULL); - li->msgid = 0; - } - return result; -} - -static CURLcode oldap_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection) -{ - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - (void)dead_connection; -#ifndef USE_SSL - (void)data; -#endif - - if(li && li->ld) { -#ifdef USE_SSL - if(ssl_installed(conn)) { - Sockbuf *sb; - if(ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb) != LDAP_OPT_SUCCESS || - ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data)) - return CURLE_FAILED_INIT; - } -#endif - ldap_unbind_ext(li->ld, NULL, NULL); - li->ld = NULL; - } - return CURLE_OK; -} - -static CURLcode oldap_do(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - struct ldapreqinfo *lr; - CURLcode result; - int rc; - LDAPURLDesc *lud; - int msgid; - - if(!li) - return CURLE_FAILED_INIT; - - infof(data, "LDAP local: %s", Curl_bufref_ptr(&data->state.url)); - - result = oldap_url_parse(data, &lud); - if(result) - goto out; - -#ifdef USE_SSL - if(ssl_installed(conn)) { - Sockbuf *sb; - /* re-install the libcurl SSL handlers into the sockbuf. */ - if((ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb) != LDAP_OPT_SUCCESS) || - ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data)) { - ldap_free_urldesc(lud); - return CURLE_FAILED_INIT; - } - } -#endif - - rc = ldap_search_ext(li->ld, lud->lud_dn, lud->lud_scope, - lud->lud_filter, lud->lud_attrs, 0, - NULL, NULL, NULL, 0, &msgid); - ldap_free_urldesc(lud); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc)); - result = CURLE_LDAP_SEARCH_FAILED; - goto out; - } - - lr = curlx_calloc(1, sizeof(struct ldapreqinfo)); - if(!lr || - Curl_meta_set(data, CURL_META_LDAP_EASY, lr, oldap_easy_dtor)) { - ldap_abandon_ext(li->ld, msgid, NULL, NULL); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - lr->msgid = msgid; - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); - *done = TRUE; - -out: - return result; -} - -static CURLcode oldap_done(struct Curl_easy *data, CURLcode res, - bool premature) -{ - struct connectdata *conn = data->conn; - struct ldapreqinfo *lr = Curl_meta_get(data, CURL_META_LDAP_EASY); - - (void)res; - (void)premature; - - if(lr) { - /* if there was a search in progress, abandon it */ - if(lr->msgid) { - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - if(li && li->ld) { - ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL); - } - lr->msgid = 0; - } - Curl_meta_remove(data, CURL_META_LDAP_EASY); - } - - return CURLE_OK; -} - -static CURLcode client_write(struct Curl_easy *data, - const char *prefix, size_t plen, - const char *value, size_t len, - const char *suffix, size_t slen) -{ - CURLcode result = CURLE_OK; - - if(prefix) { - /* If we have a zero-length value and the prefix ends with a space - separator, drop the latter. */ - if(!len && plen && prefix[plen - 1] == ' ') - plen--; - result = Curl_client_write(data, CLIENTWRITE_BODY, prefix, plen); - } - if(!result && value) { - result = Curl_client_write(data, CLIENTWRITE_BODY, value, len); - } - if(!result && suffix) { - result = Curl_client_write(data, CLIENTWRITE_BODY, suffix, slen); - } - return result; -} - -static CURLcode oldap_recv(struct Curl_easy *data, int sockindex, char *buf, - size_t len, size_t *pnread) -{ - struct connectdata *conn = data->conn; - struct ldapconninfo *li = Curl_conn_meta_get(conn, CURL_META_LDAP_CONN); - struct ldapreqinfo *lr = Curl_meta_get(data, CURL_META_LDAP_EASY); - int rc; - LDAPMessage *msg = NULL; - BerElement *ber = NULL; - struct timeval tv = { 0, 0 }; - struct berval bv, *bvals; - CURLcode result = CURLE_AGAIN; - int code; - char *info = NULL; - - (void)len; - (void)buf; - (void)sockindex; - *pnread = 0; - if(!li || !lr) - return CURLE_FAILED_INIT; - - rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_ONE, &tv, &msg); - if(rc < 0) { - failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc)); - result = CURLE_RECV_ERROR; - } - - /* error or timed out */ - if(!msg) - return result; - - result = CURLE_OK; - - switch(ldap_msgtype(msg)) { - case LDAP_RES_SEARCH_RESULT: - lr->msgid = 0; - rc = ldap_parse_result(li->ld, msg, &code, NULL, &info, NULL, NULL, 0); - if(rc) { - failf(data, "LDAP local: search ldap_parse_result %s", - ldap_err2string(rc)); - result = CURLE_LDAP_SEARCH_FAILED; - break; - } - - /* store the latest code for later retrieval */ - data->info.httpcode = code; - - switch(code) { - case LDAP_SIZELIMIT_EXCEEDED: - infof(data, "There are more than %d entries", lr->nument); - FALLTHROUGH(); - case LDAP_SUCCESS: - data->req.size = data->req.bytecount; - break; - default: - failf(data, "LDAP remote: search failed %s %s", ldap_err2string(code), - info ? info : ""); - result = CURLE_LDAP_SEARCH_FAILED; - break; - } - if(info) - ldap_memfree(info); - break; - case LDAP_RES_SEARCH_ENTRY: - lr->nument++; - rc = ldap_get_dn_ber(li->ld, msg, &ber, &bv); - if(rc < 0) { - result = CURLE_RECV_ERROR; - break; - } - - result = client_write(data, STRCONST("DN: "), bv.bv_val, bv.bv_len, - STRCONST("\n")); - if(result) - break; - - for(rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals); - rc == LDAP_SUCCESS; - rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals)) { - int i; - bool binary; - - if(!bv.bv_val) - break; - - if(!bvals) { - result = client_write(data, STRCONST("\t"), bv.bv_val, bv.bv_len, - STRCONST(":\n")); - if(result) - break; - continue; - } - - binary = bv.bv_len > 7 && - curl_strnequal(bv.bv_val + bv.bv_len - 7, ";binary", 7); - - for(i = 0; bvals[i].bv_val != NULL; i++) { - bool binval = FALSE; - - result = client_write(data, STRCONST("\t"), bv.bv_val, bv.bv_len, - STRCONST(":")); - if(result) - break; - - if(!binary) { - /* check for leading or trailing whitespace */ - if(bvals[i].bv_len && - (ISBLANK(bvals[i].bv_val[0]) || - ISBLANK(bvals[i].bv_val[bvals[i].bv_len - 1]))) - binval = TRUE; - else { - /* check for unprintable characters */ - unsigned int j; - for(j = 0; j < bvals[i].bv_len; j++) - if(!ISPRINT(bvals[i].bv_val[j])) { - binval = TRUE; - break; - } - } - } - if(binary || binval) { - char *val_b64 = NULL; - size_t val_b64_sz = 0; - - /* Binary value, encode to base64. */ - if(bvals[i].bv_len) - result = curlx_base64_encode((uint8_t *)bvals[i].bv_val, - bvals[i].bv_len, - &val_b64, &val_b64_sz); - if(!result) - result = client_write(data, STRCONST(": "), val_b64, val_b64_sz, - STRCONST("\n")); - curlx_free(val_b64); - } - else - result = client_write(data, STRCONST(" "), - bvals[i].bv_val, bvals[i].bv_len, - STRCONST("\n")); - if(result) - break; - } - - ber_memfree(bvals); - bvals = NULL; - if(!result) - result = client_write(data, STRCONST("\n"), NULL, 0, NULL, 0); - if(result) - break; - } - - if(!result) - result = client_write(data, STRCONST("\n"), NULL, 0, NULL, 0); - if(!result) - result = CURLE_AGAIN; - break; - } - - ber_free(ber, 0); - ldap_msgfree(msg); - return result; -} - -void Curl_ldap_version(char *buf, size_t bufsz) -{ - LDAPAPIInfo api; - api.ldapai_info_version = LDAP_API_INFO_VERSION; - - if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) == LDAP_OPT_SUCCESS) { - unsigned int patch = (unsigned int)(api.ldapai_vendor_version % 100); - unsigned int major = (unsigned int)(api.ldapai_vendor_version / 10000); - unsigned int minor = - (((unsigned int)api.ldapai_vendor_version - (major * 10000)) - - patch) / 100; - curl_msnprintf(buf, bufsz, "%s/%u.%u.%u", - api.ldapai_vendor_name, major, minor, patch); - ldap_memfree(api.ldapai_vendor_name); - ber_memvfree((void **)api.ldapai_extensions); - } - else - curl_msnprintf(buf, bufsz, "OpenLDAP"); -} - -/* - * LDAP protocol handler. - */ -const struct Curl_protocol Curl_protocol_ldap = { - oldap_setup_connection, /* setup_connection */ - oldap_do, /* do_it */ - oldap_done, /* done */ - ZERO_NULL, /* do_more */ - oldap_connect, /* connect_it */ - oldap_connecting, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - ZERO_NULL, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - oldap_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */ - -/* The LDAP scheme structs are in ldap.c */ diff --git a/vendor/curl/lib/parsedate.c b/vendor/curl/lib/parsedate.c deleted file mode 100644 index ce358bd46..000000000 --- a/vendor/curl/lib/parsedate.c +++ /dev/null @@ -1,605 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "parsedate.h" -#include "curlx/strparse.h" -#include "curlx/strcopy.h" - -/* - A brief summary of the date string formats this parser groks: - - RFC 2616 3.3.1 - - Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 - Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 - Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format - - we support dates without week day name: - - 06 Nov 1994 08:49:37 GMT - 06-Nov-94 08:49:37 GMT - Nov 6 08:49:37 1994 - - without the time zone: - - 06 Nov 1994 08:49:37 - 06-Nov-94 08:49:37 - - weird order: - - 1994 Nov 6 08:49:37 (GNU date fails) - GMT 08:49:37 06-Nov-94 Sunday - 94 6 Nov 08:49:37 (GNU date fails) - - time left out: - - 1994 Nov 6 - 06-Nov-94 - Sun Nov 6 94 - - unusual separators: - - 1994.Nov.6 - Sun/Nov/6/94/GMT - - commonly used time zone names: - - Sun, 06 Nov 1994 08:49:37 CET - 06 Nov 1994 08:49:37 EST - - time zones specified using RFC822 style: - - Sun, 12 Sep 2004 15:05:58 -0700 - Sat, 11 Sep 2004 21:32:11 +0200 - - compact numerical date strings: - - 20040912 15:05:58 -0700 - 20040911 +0200 - -*/ - -#if !defined(CURL_DISABLE_PARSEDATE) || !defined(CURL_DISABLE_FTP) || \ - !defined(CURL_DISABLE_FILE) || defined(USE_GNUTLS) -/* These names are also used by FTP and FILE code */ -const char * const Curl_wkday[] = { - "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" -}; -const char * const Curl_month[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; -#endif - -#define PARSEDATE_OK 0 -#define PARSEDATE_FAIL (-1) - -#ifndef CURL_DISABLE_PARSEDATE - -#define PARSEDATE_LATER 1 -#define PARSEDATE_SOONER 2 - -static const char * const weekday[] = { - "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" -}; - -struct tzinfo { - char name[5]; - int16_t offset; /* +/- in minutes */ -}; - -#define tDAYZONE (-60) /* offset for daylight savings time */ - -/* alpha-sorted list of time zones */ -static const struct tzinfo tz[] = { - { "A", -1 * 60 }, /* Alpha */ - { "ADT", 240 + tDAYZONE }, /* Atlantic Daylight */ - { "AHST", 600 }, /* Alaska-Hawaii Standard */ - { "AST", 240 }, /* Atlantic Standard */ - { "B", -2 * 60 }, /* Bravo */ - { "BST", 0 + tDAYZONE }, /* British Summer */ - { "C", -3 * 60 }, /* Charlie */ - { "CAT", 600 }, /* Central Alaska */ - { "CCT", -480 }, /* China Coast, USSR Zone 7 */ - { "CDT", 360 + tDAYZONE }, /* Central Daylight */ - { "CEST", -60 + tDAYZONE }, /* Central European Summer */ - { "CET", -60 }, /* Central European */ - { "CST", 360 }, /* Central Standard */ - { "D", -4 * 60 }, /* Delta */ - { "E", -5 * 60 }, /* Echo */ - { "EADT", -600 + tDAYZONE }, /* Eastern Australian Daylight */ - { "EAST", -600 }, /* Eastern Australian Standard */ - { "EDT", 300 + tDAYZONE }, /* Eastern Daylight */ - { "EET", -120 }, /* Eastern Europe, USSR Zone 1 */ - { "EST", 300 }, /* Eastern Standard */ - { "F", -6 * 60 }, /* Foxtrot */ - { "FST", -60 + tDAYZONE }, /* French Summer */ - { "FWT", -60 }, /* French Winter */ - { "G", -7 * 60 }, /* Golf */ - { "GMT", 0 }, /* Greenwich Mean */ - { "GST", -600 }, /* Guam Standard, USSR Zone 9 */ - { "H", -8 * 60 }, /* Hotel */ - { "HDT", 600 + tDAYZONE }, /* Hawaii Daylight */ - { "HST", 600 }, /* Hawaii Standard */ - { "I", -9 * 60 }, /* India */ - { "IDLE", -720 }, /* International Date Line East */ - { "IDLW", 720 }, /* International Date Line West */ - { "JST", -540 }, /* Japan Standard, USSR Zone 8 */ - { "K", -10 * 60 }, /* Kilo */ - { "L", -11 * 60 }, /* Lima */ - { "M", -12 * 60 }, /* Mike */ - { "MDT", 420 + tDAYZONE }, /* Mountain Daylight */ - { "MEST", -60 + tDAYZONE }, /* Middle European Summer */ - { "MESZ", -60 + tDAYZONE }, /* Middle European Summer */ - { "MET", -60 }, /* Middle European */ - { "MEWT", -60 }, /* Middle European Winter */ - { "MST", 420 }, /* Mountain Standard */ - { "N", 60 }, /* November */ - { "NT", 660 }, /* Nome */ /* spellchecker:disable-line */ - { "NZDT", -720 + tDAYZONE }, /* New Zealand Daylight */ - { "NZST", -720 }, /* New Zealand Standard */ - { "NZT", -720 }, /* New Zealand */ - { "O", 2 * 60 }, /* Oscar */ - { "P", 3 * 60 }, /* Papa */ - { "PDT", 480 + tDAYZONE }, /* Pacific Daylight */ - { "PST", 480 }, /* Pacific Standard */ - { "Q", 4 * 60 }, /* Quebec */ - { "R", 5 * 60 }, /* Romeo */ - { "S", 6 * 60 }, /* Sierra */ - { "T", 7 * 60 }, /* Tango */ - { "U", 8 * 60 }, /* Uniform */ - { "UT", 0 }, /* Universal Time */ - { "UTC", 0 }, /* Universal (Coordinated) */ - { "V", 9 * 60 }, /* Victor */ - { "W", 10 * 60 }, /* Whiskey */ - { "WADT", -420 + tDAYZONE }, /* West Australian Daylight */ - { "WAST", -420 }, /* spellchecker:disable-line */ - /* West Australian Standard */ - { "WAT", 60 }, /* West Africa */ - { "WET", 0 }, /* Western European */ - { "X", 11 * 60 }, /* X-ray */ - { "Y", 12 * 60 }, /* Yankee */ - { "YDT", 540 + tDAYZONE }, /* Yukon Daylight */ - { "YST", 540 }, /* Yukon Standard */ - { "Z", 0 }, /* Zulu, zero meridian, a.k.a. UTC */ -}; - -/* returns: - -1 no day - 0 monday - 6 sunday -*/ - -static int checkday(const char *check, size_t len) -{ - int i; - const char * const *what; - if(len > 3) - what = &weekday[0]; - else if(len == 3) - what = &Curl_wkday[0]; - else - return -1; /* too short */ - for(i = 0; i < 7; i++) { - size_t ilen = strlen(what[0]); - if((ilen == len) && - curl_strnequal(check, what[0], len)) - return i; - what++; - } - return -1; -} - -static int checkmonth(const char *check, size_t len) -{ - int i; - const char * const *what = &Curl_month[0]; - if(len != 3) - return -1; /* not a month */ - - for(i = 0; i < 12; i++) { - if(curl_strnequal(check, what[0], 3)) - return i; - what++; - } - return -1; /* return the offset or -1, no real offset is -1 */ -} - -static int tzcompare(const void *m1, const void *m2) -{ - const struct tzinfo *tz1 = m1; - const struct tzinfo *tz2 = m2; - return strcmp(tz1->name, tz2->name); -} - -/* return the time zone offset between GMT and the input one, in number of - seconds or -1 if the timezone was not found/legal */ -static int checktz(const char *check, size_t len) -{ - if(len <= 4) { - const struct tzinfo *what; - struct tzinfo find; - curlx_strcopy(find.name, sizeof(find.name), check, len); - what = bsearch(&find, tz, CURL_ARRAYSIZE(tz), sizeof(tz[0]), tzcompare); - if(what) - return what->offset * 60; - } - return -1; -} - -static void skip(const char **date) -{ - /* skip everything that are not letters or digits */ - while(**date && !ISALNUM(**date)) - (*date)++; -} - -/* each field is exactly -1 when unknown */ -struct when { - int wday; /* day of the week, 0-6 (mon-sun) */ - int mon; /* month of the year, 0-11 */ - int mday; /* day of month, 1 - 31 */ - int hour; /* hour of day, 0 - 23 */ - int min; /* minute of hour, 0 - 59 */ - int sec; /* second of minute, 0 - 60 (leap second) */ - int year; /* year, >= 1583 */ - int tzoff; /* time zone offset in seconds */ -}; - -enum assume { - DATE_MDAY, - DATE_YEAR, - DATE_TIME -}; - -/* (1969 / 4) - (1969 / 100) + (1969 / 400) = 492 - 19 + 4 = 477 */ -#define LEAP_DAYS_BEFORE_1969 477 - -/* - * time2epoch: time stamp to seconds since epoch in GMT time zone. Similar to - * mktime but for GMT only. - */ -static curl_off_t time2epoch(struct when *w) -{ - static const int cumulative_days[12] = { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 - }; - int y = w->year - (w->mon <= 1); - int leap_days = (y / 4) - (y / 100) + (y / 400) - LEAP_DAYS_BEFORE_1969; - curl_off_t days = (curl_off_t)(w->year - 1970) * 365 + leap_days + - cumulative_days[w->mon] + w->mday - 1; - - return (((days * 24 + w->hour) * 60 + w->min) * 60) + w->sec; -} - -/* Returns the value of a single-digit or two-digit decimal number, return - then pointer to after the number. The 'date' pointer is known to point to a - digit. */ -static int oneortwodigit(const char *date, const char **endp) -{ - int num = date[0] - '0'; - if(ISDIGIT(date[1])) { - *endp = &date[2]; - return (num * 10) + (date[1] - '0'); - } - *endp = &date[1]; - return num; -} - -/* HH:MM:SS or HH:MM and accept single-digits too */ -static bool match_time(const char *date, struct when *w, char **endp) -{ - const char *p; - int hh, mm, ss = 0; - hh = oneortwodigit(date, &p); - if((hh < 24) && (*p == ':') && ISDIGIT(p[1])) { - mm = oneortwodigit(&p[1], &p); - if(mm < 60) { - if((*p == ':') && ISDIGIT(p[1])) { - ss = oneortwodigit(&p[1], &p); - if(ss <= 60) { - /* valid HH:MM:SS */ - goto match; - } - } - else { - /* valid HH:MM */ - goto match; - } - } - } - return FALSE; /* not a time string */ -match: - w->hour = hh; - w->min = mm; - w->sec = ss; - *endp = (char *)CURL_UNCONST(p); - return TRUE; -} - -/* - * parsedate() - * - * Returns: - * - * PARSEDATE_OK - a fine conversion - * PARSEDATE_FAIL - failed to convert - * PARSEDATE_LATER - time overflow at the far end of time_t - * PARSEDATE_SOONER - time underflow at the low end of time_t - */ - -/* Wednesday is the longest name this parser knows about */ -#define NAME_LEN 12 - -static void initwhen(struct when *w) -{ - w->wday = w->mon = w->mday = w->hour = w->min = w->sec = w->year = w->tzoff = - -1; -} - -static int datestring(const char **datep, struct when *w) -{ - /* a name coming up */ - size_t len = 0; - const char *p = *datep; - bool found = FALSE; - while(ISALPHA(*p) && (len < NAME_LEN)) { - p++; - len++; - } - - if(len != NAME_LEN) { - if(w->wday == -1) { - w->wday = checkday(*datep, len); - if(w->wday != -1) - found = TRUE; - } - if(!found && (w->mon == -1)) { - w->mon = checkmonth(*datep, len); - if(w->mon != -1) - found = TRUE; - } - - if(!found && (w->tzoff == -1)) { - /* this must be a time zone string */ - w->tzoff = checktz(*datep, len); - if(w->tzoff != -1) - found = TRUE; - } - } - if(!found) - return PARSEDATE_FAIL; /* bad string */ - - *datep += len; - return PARSEDATE_OK; -} - -static int datenum(const char *indate, const char **datep, struct when *w, - enum assume *dignextp) -{ - /* a digit */ - unsigned int val; - char *end; - const char *date = *datep; - enum assume dignext = *dignextp; - - if((w->sec == -1) && match_time(date, w, &end)) { - /* time stamp */ - date = end; - } - else { - bool found = FALSE; - curl_off_t lval; - int num_digits = 0; - const char *p = *datep; - if(curlx_str_number(&p, &lval, 99999999)) - return PARSEDATE_FAIL; - - /* we know num_digits cannot be larger than 8 */ - num_digits = (int)(p - *datep); - val = (unsigned int)lval; - - if((w->tzoff == -1) && - (num_digits == 4) && - (val <= 1400) && - (indate < date) && - (date[-1] == '+' || date[-1] == '-')) { - /* four digits and a value less than or equal to 1400 (to take into - account all sorts of funny time zone diffs) and it is preceded - with a plus or minus. This is a time zone indication. 1400 is - picked since +1300 is frequently used and +1400 is mentioned as - an edge number in the document "ISO C 200X Proposal: Timezone - Functions" at http://david.tribble.com/text/c0xtimezone.html If - anyone has a more authoritative source for the exact maximum time - zone offsets, please speak up! */ - found = TRUE; - w->tzoff = ((val / 100 * 60) + (val % 100)) * 60; - - /* the + and - prefix indicates the local time compared to GMT, - this we need their reversed math to get what we want */ - w->tzoff = date[-1] == '+' ? -w->tzoff : w->tzoff; - } - - else if((num_digits == 8) && (w->year == -1) && - (w->mon == -1) && (w->mday == -1)) { - /* 8 digits, no year, month or day yet. This is YYYYMMDD */ - found = TRUE; - w->year = val / 10000; - w->mon = ((val % 10000) / 100) - 1; /* month is 0 - 11 */ - w->mday = val % 100; - } - - if(!found && (dignext == DATE_MDAY) && (w->mday == -1)) { - if((val > 0) && (val < 32)) { - w->mday = val; - found = TRUE; - } - dignext = DATE_YEAR; - } - - if(!found && (dignext == DATE_YEAR) && (w->year == -1)) { - w->year = val; - found = TRUE; - if(w->year < 100) { - if(w->year > 70) - w->year += 1900; - else - w->year += 2000; - } - if(w->mday == -1) - dignext = DATE_MDAY; - } - - if(!found) - return PARSEDATE_FAIL; - - date = p; - } - *datep = date; - *dignextp = dignext; - return PARSEDATE_OK; -} - -static int datecheck(struct when *w) -{ - if(w->sec == -1) - w->sec = w->min = w->hour = 0; /* no time, make it zero */ - - if((w->mday == -1) || (w->mon == -1) || (w->year == -1)) - /* lacks vital info, fail */ - return PARSEDATE_FAIL; - - /* The Gregorian calendar was introduced 1582 */ - else if(w->year < 1583) - return PARSEDATE_FAIL; - - else if((w->mday > 31) || (w->mon > 11) || (w->hour > 23) || - (w->min > 59) || (w->sec > 60)) - return PARSEDATE_FAIL; /* clearly an illegal date */ - - return PARSEDATE_OK; -} - -static void tzadjust(curl_off_t *tp, struct when *w) -{ - if(w->tzoff == -1) /* unknown tz means no offset */ - w->tzoff = 0; - - /* Add the time zone diff between local time zone and GMT. */ - if((w->tzoff > 0) && (*tp > (curl_off_t)(CURL_OFF_T_MAX - w->tzoff))) - *tp = CURL_OFF_T_MAX; - else - *tp += w->tzoff; - /* this needs no minimum check since we require a year > 1582 */ -} - -static int mktimet(curl_off_t seconds, time_t *output) -{ -#if SIZEOF_TIME_T < 5 - if(seconds > TIME_T_MAX) { - *output = TIME_T_MAX; - return PARSEDATE_LATER; - } - else if(seconds < TIME_T_MIN) { - *output = TIME_T_MIN; - return PARSEDATE_SOONER; - } -#elif defined(HAVE_TIME_T_UNSIGNED) - if(seconds < 0) { - *output = 0; - return PARSEDATE_SOONER; - } -#endif - *output = (time_t)seconds; - return PARSEDATE_OK; -} - -static int parsedate(const char *date, time_t *output) -{ - curl_off_t seconds = 0; - enum assume dignext = DATE_MDAY; - const char *indate = date; /* save the original pointer */ - int part = 0; /* max 6 parts */ - int rc = 0; - struct when w; - initwhen(&w); - - while(*date && (part < 6)) { - skip(&date); - - if(ISALPHA(*date)) - rc = datestring(&date, &w); - else if(ISDIGIT(*date)) - rc = datenum(indate, &date, &w, &dignext); - if(rc) - return rc; - - part++; - } - - rc = datecheck(&w); - if(rc) - return rc; - - seconds = time2epoch(&w); /* get number of seconds */ - tzadjust(&seconds, &w); /* handle the time zone offset */ - rc = mktimet(seconds, output); /* squeeze seconds into a time_t */ - - return rc; -} -#else -/* disabled */ -static int parsedate(const char *date, time_t *output) -{ - (void)date; - *output = 0; - return PARSEDATE_OK; /* a lie */ -} -#endif - -time_t curl_getdate(const char *p, const time_t *unused) -{ - time_t parsed = -1; - int rc = parsedate(p, &parsed); - (void)unused; /* legacy argument from the past that we ignore */ - - if(rc == PARSEDATE_OK) { - if(parsed == (time_t)-1) - /* avoid returning -1 for a working scenario */ - parsed++; - return parsed; - } - /* everything else is fail */ - return -1; -} - -/* Curl_getdate_capped() differs from curl_getdate() in that this will return - TIME_T_MAX in case the parsed time value was too big, instead of an - error. Returns non-zero on error. */ - -int Curl_getdate_capped(const char *p, time_t *tp) -{ - int rc = parsedate(p, tp); - return (rc == PARSEDATE_FAIL); -} diff --git a/vendor/curl/lib/parsedate.h b/vendor/curl/lib/parsedate.h deleted file mode 100644 index ea136bd30..000000000 --- a/vendor/curl/lib/parsedate.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HEADER_CURL_PARSEDATE_H -#define HEADER_CURL_PARSEDATE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -extern const char * const Curl_wkday[7]; -extern const char * const Curl_month[12]; - -/* Curl_getdate_capped() differs from curl_getdate() in that this returns - TIME_T_MAX in case the parsed time value was too big, instead of an - error. */ - -int Curl_getdate_capped(const char *p, time_t *tp); - -#endif /* HEADER_CURL_PARSEDATE_H */ diff --git a/vendor/curl/lib/pingpong.c b/vendor/curl/lib/pingpong.c deleted file mode 100644 index 44e424418..000000000 --- a/vendor/curl/lib/pingpong.c +++ /dev/null @@ -1,405 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * 'pingpong' is for generic back-and-forth support functions used by FTP, - * IMAP, POP3, SMTP and whatever more that likes them. - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "pingpong.h" - -#ifdef USE_PINGPONG - -#include "cfilters.h" -#include "connect.h" -#include "multiif.h" -#include "sendf.h" -#include "curl_trc.h" -#include "select.h" -#include "progress.h" - -timediff_t Curl_pp_state_timeleft_ms(struct Curl_easy *data, - struct pingpong *pp) -{ - timediff_t xfer_remain_ms; - timediff_t remain_ms = data->set.server_response_timeout ? - data->set.server_response_timeout : PINGPONG_TIMEOUT_MS; - - /* If the overall transfer has less time remaining than pingpong - * has otherwise for the state, return that. */ - remain_ms -= curlx_ptimediff_ms(Curl_pgrs_now(data), &pp->response); - /* transfer remaining time is 0, when it has no timeout. */ - xfer_remain_ms = Curl_timeleft_ms(data); - if(xfer_remain_ms) - return CURLMIN(remain_ms, xfer_remain_ms); - return remain_ms; -} - -/* - * Curl_pp_statemach() - */ -CURLcode Curl_pp_statemach(struct Curl_easy *data, - struct pingpong *pp, bool block, - bool disconnecting) -{ - struct connectdata *conn = data->conn; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int rc; - timediff_t interval_ms; - timediff_t timeout_ms = Curl_pp_state_timeleft_ms(data, pp); - CURLcode result = CURLE_OK; - - if(timeout_ms <= 0) { - failf(data, "server response timeout"); - return CURLE_OPERATION_TIMEDOUT; /* already too little time */ - } - - if(block) { - interval_ms = 1000; /* use 1 second timeout intervals */ - if(timeout_ms < interval_ms) - interval_ms = timeout_ms; - } - else - interval_ms = 0; /* immediate */ - - if(Curl_conn_data_pending(data, FIRSTSOCKET)) - rc = 1; - else if(pp->overflow) - /* We are receiving and there is data in the cache so read it */ - rc = 1; - else if(!pp->sendleft && Curl_conn_data_pending(data, FIRSTSOCKET)) - /* We are receiving and there is data ready in the SSL library */ - rc = 1; - else { - rc = Curl_socket_check(pp->sendleft ? CURL_SOCKET_BAD : sock, /* reading */ - CURL_SOCKET_BAD, - pp->sendleft ? sock : CURL_SOCKET_BAD, /* writing */ - interval_ms); - } - - if(block) { - /* if we did not wait, we do not have to spend time on this now */ - result = Curl_pgrsCheck(data); - if(result) - return result; - } - - if(rc == -1) { - failf(data, "select/poll error"); - result = CURLE_OUT_OF_MEMORY; - } - else if(rc) - result = pp->statemachine(data, data->conn); - else if(disconnecting) - return CURLE_OPERATION_TIMEDOUT; - - return result; -} - -/* initialize stuff to prepare for reading a fresh new response */ -void Curl_pp_init(struct pingpong *pp, const struct curltime *pnow) -{ - DEBUGASSERT(!pp->initialised); - pp->nread_resp = 0; - pp->response = *pnow; /* start response time-out */ - pp->pending_resp = TRUE; - curlx_dyn_init(&pp->sendbuf, DYN_PINGPPONG_CMD); - curlx_dyn_init(&pp->recvbuf, DYN_PINGPPONG_CMD); - pp->initialised = TRUE; -} - -/*********************************************************************** - * - * Curl_pp_vsendf() - * - * Send the formatted string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_vsendf(struct Curl_easy *data, - struct pingpong *pp, - const char *fmt, - va_list args) -{ - size_t bytes_written = 0; - size_t write_len; - char *s; - CURLcode result; - struct connectdata *conn = data->conn; - - DEBUGASSERT(pp->sendleft == 0); - DEBUGASSERT(pp->sendsize == 0); - DEBUGASSERT(pp->sendthis == NULL); - - if(!conn) - /* cannot send without a connection! */ - return CURLE_SEND_ERROR; - - curlx_dyn_reset(&pp->sendbuf); - result = curlx_dyn_vaddf(&pp->sendbuf, fmt, args); - if(result) - return result; - - /* append CRLF */ - result = curlx_dyn_addn(&pp->sendbuf, "\r\n", 2); - if(result) - return result; - - pp->pending_resp = TRUE; - write_len = curlx_dyn_len(&pp->sendbuf); - s = curlx_dyn_ptr(&pp->sendbuf); - - result = Curl_conn_send(data, FIRSTSOCKET, s, write_len, FALSE, - &bytes_written); - if(result == CURLE_AGAIN) { - bytes_written = 0; - } - else if(result) - return result; - - Curl_debug(data, CURLINFO_HEADER_OUT, s, bytes_written); - - if(bytes_written != write_len) { - /* the whole chunk was not sent, keep it around and adjust sizes */ - pp->sendthis = s; - pp->sendsize = write_len; - pp->sendleft = write_len - bytes_written; - } - else { - pp->sendthis = NULL; - pp->sendleft = pp->sendsize = 0; - pp->response = *Curl_pgrs_now(data); - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * Curl_pp_sendf() - * - * Send the formatted string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_sendf(struct Curl_easy *data, struct pingpong *pp, - const char *fmt, ...) -{ - CURLcode result; - va_list ap; - va_start(ap, fmt); - - result = Curl_pp_vsendf(data, pp, fmt, ap); - - va_end(ap); - - return result; -} - -static CURLcode pingpong_read(struct Curl_easy *data, - int sockindex, - char *buffer, - size_t buflen, - size_t *nread) -{ - return Curl_conn_recv(data, sockindex, buffer, buflen, nread); -} - -/* - * Curl_pp_readresp() - * - * Reads a piece of a server response. - */ -CURLcode Curl_pp_readresp(struct Curl_easy *data, - int sockindex, - struct pingpong *pp, - int *code, /* return the server code if done */ - size_t *size) /* size of the response */ -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - size_t gotbytes; - char buffer[900]; - - *code = 0; /* 0 for errors or not done */ - *size = 0; - - do { - gotbytes = 0; - if(pp->nfinal) { - /* a previous call left this many bytes in the beginning of the buffer as - that was the final line; now ditch that */ - size_t full = curlx_dyn_len(&pp->recvbuf); - - /* trim off the "final" leading part */ - curlx_dyn_tail(&pp->recvbuf, full - pp->nfinal); - - pp->nfinal = 0; /* now gone */ - } - if(!pp->overflow) { - result = pingpong_read(data, sockindex, buffer, sizeof(buffer), - &gotbytes); - if(result == CURLE_AGAIN) - return CURLE_OK; - - if(result) - return result; - - if(!gotbytes) { - failf(data, "response reading failed (errno: %d)", SOCKERRNO); - return CURLE_RECV_ERROR; - } - - result = curlx_dyn_addn(&pp->recvbuf, buffer, gotbytes); - if(result) - return result; - - data->req.headerbytecount += (unsigned int)gotbytes; - - pp->nread_resp += gotbytes; - } - - do { - const char *line = curlx_dyn_ptr(&pp->recvbuf); - const char *nl = memchr(line, '\n', curlx_dyn_len(&pp->recvbuf)); - if(nl) { - /* a newline is CRLF in pp-talk, so the CR is ignored as - the line is not really terminated until the LF comes */ - size_t length = nl - line + 1; - - /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_HEADER_IN, line, length); - - /* - * Pass all response-lines to the callback function registered for - * "headers". The response lines can be seen as a kind of headers. - */ - result = Curl_client_write(data, CLIENTWRITE_INFO, line, length); - if(result) - return result; - - if(pp->endofresp(data, conn, line, length, code)) { - /* When at "end of response", keep the endofresp line first in the - buffer since it will be accessed outside (by pingpong - parsers). Store the overflow counter to inform about additional - data in this buffer after the endofresp line. */ - pp->nfinal = length; - if(curlx_dyn_len(&pp->recvbuf) > length) - pp->overflow = curlx_dyn_len(&pp->recvbuf) - length; - else - pp->overflow = 0; - *size = pp->nread_resp; /* size of the response */ - pp->nread_resp = 0; /* restart */ - gotbytes = 0; /* force break out of outer loop */ - break; - } - if(curlx_dyn_len(&pp->recvbuf) > length) - /* keep the remaining piece */ - curlx_dyn_tail((&pp->recvbuf), curlx_dyn_len(&pp->recvbuf) - length); - else - curlx_dyn_reset(&pp->recvbuf); - } - else { - /* without a newline, there is no overflow */ - pp->overflow = 0; - break; - } - - } while(1); /* while there is buffer left to scan */ - - } while(gotbytes == sizeof(buffer)); - - pp->pending_resp = FALSE; - - return result; -} - -CURLcode Curl_pp_pollset(struct Curl_easy *data, - struct pingpong *pp, - struct easy_pollset *ps) -{ - int flags = pp->sendleft ? CURL_POLL_OUT : CURL_POLL_IN; - return Curl_pollset_change(data, ps, data->conn->sock[FIRSTSOCKET], - flags, 0); -} - -bool Curl_pp_needs_flush(struct Curl_easy *data, - struct pingpong *pp) -{ - (void)data; - return pp->sendleft > 0; -} - -CURLcode Curl_pp_flushsend(struct Curl_easy *data, - struct pingpong *pp) -{ - /* we have a piece of a command still left to send */ - size_t written; - CURLcode result; - - if(!Curl_pp_needs_flush(data, pp)) - return CURLE_OK; - - result = Curl_conn_send(data, FIRSTSOCKET, - pp->sendthis + pp->sendsize - pp->sendleft, - pp->sendleft, FALSE, &written); - if(result == CURLE_AGAIN) { - result = CURLE_OK; - written = 0; - } - if(result) - return result; - - if(written != pp->sendleft) { - /* only a fraction was sent */ - pp->sendleft -= written; - } - else { - pp->sendthis = NULL; - pp->sendleft = pp->sendsize = 0; - pp->response = *Curl_pgrs_now(data); - } - return CURLE_OK; -} - -CURLcode Curl_pp_disconnect(struct pingpong *pp) -{ - if(pp->initialised) { - curlx_dyn_free(&pp->sendbuf); - curlx_dyn_free(&pp->recvbuf); - memset(pp, 0, sizeof(*pp)); - } - return CURLE_OK; -} - -bool Curl_pp_moredata(struct pingpong *pp) -{ - return !pp->sendleft && curlx_dyn_len(&pp->recvbuf) > pp->nfinal; -} - -#endif diff --git a/vendor/curl/lib/pingpong.h b/vendor/curl/lib/pingpong.h deleted file mode 100644 index 864f2c683..000000000 --- a/vendor/curl/lib/pingpong.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef HEADER_CURL_PINGPONG_H -#define HEADER_CURL_PINGPONG_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_FTP) || \ - !defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_SMTP) -#define USE_PINGPONG -#endif - -/* forward-declaration, this is defined in urldata.h */ -struct connectdata; - -typedef enum { - PPTRANSFER_BODY, /* yes do transfer a body */ - PPTRANSFER_INFO, /* do still go through to get info/headers */ - PPTRANSFER_NONE /* do not get anything and do not get info */ -} curl_pp_transfer; - -/* - * 'pingpong' is the generic struct used for protocols doing server<->client - * conversations in a back-and-forth style such as FTP, IMAP, POP3, SMTP etc. - * - * It holds response cache and non-blocking sending data. - */ -struct pingpong { - size_t nread_resp; /* number of bytes currently read of a server response */ - char *sendthis; /* pointer to a buffer that is to be sent to the server */ - size_t sendleft; /* number of bytes left to send from the sendthis buffer */ - size_t sendsize; /* total size of the sendthis buffer */ - struct curltime response; /* set to Curl_now() when a command has been sent - off, used to time-out response reading */ - struct dynbuf sendbuf; - struct dynbuf recvbuf; - size_t overflow; /* number of bytes left after a final response line */ - size_t nfinal; /* number of bytes in the final response line, which - after a match is first in the receive buffer */ - - /* Function pointers the protocols MUST implement and provide for the - pingpong layer to function */ - - CURLcode (*statemachine)(struct Curl_easy *data, struct connectdata *conn); - bool (*endofresp)(struct Curl_easy *data, struct connectdata *conn, - const char *ptr, size_t len, int *code); - BIT(initialised); - BIT(pending_resp); /* set TRUE when a server response is pending or in - progress, and is cleared once the last response is - read */ -}; - -/* Default pingpong response timeout in milliseconds, unless a transfer - * has CURLOPT_SERVER_RESPONSE_TIMEOUT(_MS) set. */ -#define PINGPONG_TIMEOUT_MS (60 * 1000) - -#define PINGPONG_SETUP(pp, s, e) \ - do { \ - (pp)->statemachine = s; \ - (pp)->endofresp = e; \ - } while(0) - -/* - * Curl_pp_statemach() - * - * called repeatedly until done. Set 'wait' to make it wait a while on the - * socket if there is no traffic. - */ -CURLcode Curl_pp_statemach(struct Curl_easy *data, struct pingpong *pp, - bool block, bool disconnecting); - -/* initialize stuff to prepare for reading a fresh new response */ -void Curl_pp_init(struct pingpong *pp, const struct curltime *pnow); - -/* Returns time remaining in ms. 0 or negative number means the - timeout has already triggered */ -timediff_t Curl_pp_state_timeleft_ms(struct Curl_easy *data, - struct pingpong *pp); - -/*********************************************************************** - * - * Curl_pp_sendf() - * - * Send the formatted string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_sendf(struct Curl_easy *data, - struct pingpong *pp, - const char *fmt, ...) CURL_PRINTF(3, 4); - -/*********************************************************************** - * - * Curl_pp_vsendf() - * - * Send the formatted string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_vsendf(struct Curl_easy *data, - struct pingpong *pp, - const char *fmt, - va_list args) CURL_PRINTF(3, 0); - -/* - * Curl_pp_readresp() - * - * Reads a piece of a server response. - */ -CURLcode Curl_pp_readresp(struct Curl_easy *data, - int sockindex, - struct pingpong *pp, - int *code, /* return the server code if done */ - size_t *size); /* size of the response */ - -bool Curl_pp_needs_flush(struct Curl_easy *data, - struct pingpong *pp); - -CURLcode Curl_pp_flushsend(struct Curl_easy *data, - struct pingpong *pp); - -/* call this when a pingpong connection is disconnected */ -CURLcode Curl_pp_disconnect(struct pingpong *pp); - -CURLcode Curl_pp_pollset(struct Curl_easy *data, - struct pingpong *pp, - struct easy_pollset *ps); - -/*********************************************************************** - * - * Curl_pp_moredata() - * - * Returns whether there are still more data in the cache and so a call - * to Curl_pp_readresp() will not block. - */ -bool Curl_pp_moredata(struct pingpong *pp); - -#endif /* HEADER_CURL_PINGPONG_H */ diff --git a/vendor/curl/lib/pop3.c b/vendor/curl/lib/pop3.c deleted file mode 100644 index 317c04bbe..000000000 --- a/vendor/curl/lib/pop3.c +++ /dev/null @@ -1,1714 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC1734 POP3 Authentication - * RFC1939 POP3 protocol - * RFC2195 CRAM-MD5 authentication - * RFC2384 POP URL Scheme - * RFC2449 POP3 Extension Mechanism - * RFC2595 Using TLS with IMAP, POP3 and ACAP - * RFC2831 DIGEST-MD5 authentication - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * RFC5034 POP3 SASL Authentication Mechanism - * RFC6749 OAuth 2.0 Authorization Framework - * RFC8314 Use of TLS for Email Submission and Access - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "pop3.h" - -#ifndef CURL_DISABLE_POP3 - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "sendf.h" -#include "curl_trc.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "pingpong.h" -#include "vtls/vtls.h" -#include "cfilters.h" -#include "connect.h" -#include "select.h" -#include "url.h" -#include "bufref.h" -#include "curl_sasl.h" -#include "curl_md5.h" -#include "curlx/strdup.h" - -/* Authentication type flags */ -#define POP3_TYPE_CLEARTEXT (1 << 0) -#define POP3_TYPE_APOP (1 << 1) -#define POP3_TYPE_SASL (1 << 2) - -/* Authentication type values */ -#define POP3_TYPE_NONE 0 -#define POP3_TYPE_ANY (POP3_TYPE_CLEARTEXT | POP3_TYPE_APOP | POP3_TYPE_SASL) - -/* This is the 5-bytes End-Of-Body marker for POP3 */ -#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a" -#define POP3_EOB_LEN 5 - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_POP3_EASY "meta:proto:pop3:easy" -/* meta key for storing protocol meta at connection */ -#define CURL_META_POP3_CONN "meta:proto:pop3:conn" - -/* - * POP3 easy handle state - */ -struct POP3 { - curl_pp_transfer transfer; - char *id; /* Message ID */ - char *custom; /* Custom Request */ -}; - -/* - * POP3 connection state - */ -typedef enum { - POP3_STOP, /* do nothing state, stops the state machine */ - POP3_SERVERGREET, /* waiting for the initial greeting immediately after - a connect */ - POP3_CAPA, - POP3_STARTTLS, - POP3_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS - (multi mode only) */ - POP3_AUTH, - POP3_APOP, - POP3_USER, - POP3_PASS, - POP3_COMMAND, - POP3_QUIT, - POP3_LAST /* never used */ -} pop3state; - -struct pop3_conn { - struct pingpong pp; - pop3state state; /* Always use pop3.c:state() to change state! */ - size_t eob; /* Number of bytes of the EOB (End Of Body) that - have been received so far */ - size_t strip; /* Number of bytes from the start to ignore as - non-body */ - struct SASL sasl; /* SASL-related storage */ - char *apoptimestamp; /* APOP timestamp from the server greeting */ - unsigned char authtypes; /* Accepted authentication types */ - unsigned char preftype; /* Preferred authentication type */ - BIT(ssldone); /* Is connect() over SSL done? */ - BIT(tls_supported); /* StartTLS capability supported by server */ -}; - -struct pop3_cmd { - const char *name; - unsigned short nlen; - BIT(multiline); /* response is multi-line with last '.' line */ - BIT(multiline_with_args); /* is multi-line when command has args */ -}; - -static const struct pop3_cmd pop3cmds[] = { - { "APOP", 4, FALSE, FALSE }, - { "AUTH", 4, FALSE, FALSE }, - { "CAPA", 4, TRUE, TRUE }, - { "DELE", 4, FALSE, FALSE }, - { "LIST", 4, TRUE, FALSE }, - { "MSG", 3, TRUE, TRUE }, - { "NOOP", 4, FALSE, FALSE }, - { "PASS", 4, FALSE, FALSE }, - { "QUIT", 4, FALSE, FALSE }, - { "RETR", 4, TRUE, TRUE }, - { "RSET", 4, FALSE, FALSE }, - { "STAT", 4, FALSE, FALSE }, - { "STLS", 4, FALSE, FALSE }, - { "TOP", 3, TRUE, TRUE }, - { "UIDL", 4, TRUE, FALSE }, - { "USER", 4, FALSE, FALSE }, - { "UTF8", 4, FALSE, FALSE }, - { "XTND", 4, TRUE, TRUE }, -}; - -/*********************************************************************** - * - * pop3_parse_url_options() - * - * Parse the URL login options. - */ -static CURLcode pop3_parse_url_options(struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - const char *ptr = conn->options; - - if(!pop3c) - return CURLE_FAILED_INIT; - - while(!result && ptr && *ptr) { - const char *key = ptr; - const char *value; - - while(*ptr && *ptr != '=') - ptr++; - - value = ptr + 1; - - while(*ptr && *ptr != ';') - ptr++; - - if(curl_strnequal(key, "AUTH=", 5)) { - result = Curl_sasl_parse_url_auth_option(&pop3c->sasl, - value, ptr - value); - - if(result && curl_strnequal(value, "+APOP", ptr - value)) { - pop3c->preftype = POP3_TYPE_APOP; - pop3c->sasl.prefmech = SASL_AUTH_NONE; - result = CURLE_OK; - } - } - else - result = CURLE_URL_MALFORMAT; - - if(*ptr == ';') - ptr++; - } - - if(pop3c->preftype != POP3_TYPE_APOP) - switch(pop3c->sasl.prefmech) { - case SASL_AUTH_NONE: - pop3c->preftype = POP3_TYPE_NONE; - break; - case SASL_AUTH_DEFAULT: - pop3c->preftype = POP3_TYPE_ANY; - break; - default: - pop3c->preftype = POP3_TYPE_SASL; - break; - } - - return result; -} - -/*********************************************************************** - * - * pop3_parse_url_path() - * - * Parse the URL path into separate path components. - */ -static CURLcode pop3_parse_url_path(struct Curl_easy *data) -{ - /* The POP3 struct is already initialised in pop3_connect() */ - struct POP3 *pop3 = Curl_meta_get(data, CURL_META_POP3_EASY); - const char *path = &data->state.up.path[1]; /* skip leading path */ - - if(!pop3) - return CURLE_FAILED_INIT; - /* URL decode the path for the message ID */ - return Curl_urldecode(path, 0, &pop3->id, NULL, REJECT_CTRL); -} - -/*********************************************************************** - * - * pop3_parse_custom_request() - * - * Parse the custom request. - */ -static CURLcode pop3_parse_custom_request(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - struct POP3 *pop3 = Curl_meta_get(data, CURL_META_POP3_EASY); - const char *custom = data->set.str[STRING_CUSTOMREQUEST]; - - if(!pop3) - return CURLE_FAILED_INIT; - /* URL decode the custom request */ - if(custom) - result = Curl_urldecode(custom, 0, &pop3->custom, NULL, REJECT_CTRL); - - return result; -} - -/* Return iff a command is defined as "multi-line" (RFC 1939), - * has a response terminated by a last line with a '.'. - */ -static bool pop3_is_multiline(const char *cmdline) -{ - size_t i; - for(i = 0; i < CURL_ARRAYSIZE(pop3cmds); ++i) { - if(curl_strnequal(pop3cmds[i].name, cmdline, pop3cmds[i].nlen)) { - if(!cmdline[pop3cmds[i].nlen]) - return (bool)pop3cmds[i].multiline; - else if(cmdline[pop3cmds[i].nlen] == ' ') - return (bool)pop3cmds[i].multiline_with_args; - } - } - /* Unknown command, assume multi-line for backward compatibility with - * earlier curl versions that only could do multi-line responses. */ - return TRUE; -} - -/*********************************************************************** - * - * pop3_endofresp() - * - * Checks for an ending POP3 status code at the start of the given string, but - * also detects the APOP timestamp from the server greeting and various - * capabilities from the CAPA response including the supported authentication - * types and allowed SASL mechanisms. - */ -static bool pop3_endofresp(struct Curl_easy *data, struct connectdata *conn, - const char *line, size_t len, int *resp) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - (void)data; - DEBUGASSERT(pop3c); - if(!pop3c) /* internal error */ - return TRUE; - - /* Do we have an error response? */ - if(len >= 4 && !memcmp("-ERR", line, 4)) { - *resp = '-'; - - return TRUE; - } - - /* Are we processing CAPA command responses? */ - if(pop3c->state == POP3_CAPA) { - /* Do we have the terminating line? Per RFC 2449 this is a line - containing only a single dot */ - if((len == 3 && line[0] == '.' && line[1] == '\r') || - (len == 2 && line[0] == '.' && line[1] == '\n')) - /* Treat the response as a success */ - *resp = '+'; - else - /* Treat the response as an untagged continuation */ - *resp = '*'; - - return TRUE; - } - - /* Do we have a success response? */ - if(len >= 3 && !memcmp("+OK", line, 3)) { - *resp = '+'; - - return TRUE; - } - - /* Do we have a continuation response? */ - if(len >= 1 && line[0] == '+') { - *resp = '*'; - - return TRUE; - } - - return FALSE; /* Nothing for us */ -} - -/*********************************************************************** - * - * pop3_get_message() - * - * Gets the authentication message from the response buffer. - */ -static CURLcode pop3_get_message(struct Curl_easy *data, struct bufref *out) -{ - struct pop3_conn *pop3c = - Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN); - char *message; - size_t len; - - if(!pop3c) - return CURLE_FAILED_INIT; - message = curlx_dyn_ptr(&pop3c->pp.recvbuf); - len = pop3c->pp.nfinal; - if(len > 2) { - /* Find the start of the message */ - len -= 2; - for(message += 2; ISBLANK(*message); message++, len--) - ; - - /* Find the end of the message */ - while(len--) - if(!ISBLANK(message[len]) && !ISNEWLINE(message[len])) - break; - - /* Terminate the message */ - message[++len] = '\0'; - Curl_bufref_set(out, message, len, NULL); - } - else - /* junk input => zero length output */ - Curl_bufref_set(out, "", 0, NULL); - - return CURLE_OK; -} - -/*********************************************************************** - * - * pop3_state() - * - * This is the ONLY way to change POP3 state! - */ -static void pop3_state(struct Curl_easy *data, pop3state newstate) -{ - struct pop3_conn *pop3c = - Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN); - if(pop3c) { -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - /* for debug purposes */ - static const char * const names[] = { - "STOP", - "SERVERGREET", - "CAPA", - "STARTTLS", - "UPGRADETLS", - "AUTH", - "APOP", - "USER", - "PASS", - "COMMAND", - "QUIT", - /* LAST */ - }; - - if(pop3c->state != newstate) - infof(data, "POP3 %p state change from %s to %s", - (void *)pop3c, names[pop3c->state], names[newstate]); -#endif - - pop3c->state = newstate; - } -} - -/*********************************************************************** - * - * pop3_perform_capa() - * - * Sends the CAPA command in order to obtain a list of server side supported - * capabilities. - */ -static CURLcode pop3_perform_capa(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - - if(!pop3c) - return CURLE_FAILED_INIT; - - pop3c->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */ - pop3c->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */ - pop3c->tls_supported = FALSE; /* Clear the TLS capability */ - - /* Send the CAPA command */ - result = Curl_pp_sendf(data, &pop3c->pp, "%s", "CAPA"); - - if(!result) - pop3_state(data, POP3_CAPA); - - return result; -} - -/*********************************************************************** - * - * pop3_perform_starttls() - * - * Sends the STLS command to start the upgrade to TLS. - */ -static CURLcode pop3_perform_starttls(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* Send the STLS command */ - result = Curl_pp_sendf(data, &pop3c->pp, "%s", "STLS"); - if(!result) - pop3_state(data, POP3_STARTTLS); - - return result; -} - -/*********************************************************************** - * - * pop3_perform_upgrade_tls() - * - * Performs the upgrade to TLS. - */ -static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data, - struct connectdata *conn) -{ -#ifdef USE_SSL - /* Start the SSL connection */ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result; - bool ssldone = FALSE; - - if(!pop3c) - return CURLE_FAILED_INIT; - - if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); - if(result) - goto out; - /* Change the connection handler */ - conn->scheme = &Curl_scheme_pop3s; - } - - DEBUGASSERT(!pop3c->ssldone); - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - DEBUGF(infof(data, "pop3_perform_upgrade_tls, connect -> %d, %d", - result, ssldone)); - if(!result && ssldone) { - pop3c->ssldone = ssldone; - /* perform CAPA now, changes pop3c->state out of POP3_UPGRADETLS */ - result = pop3_perform_capa(data, conn); - } -out: - return result; -#else - (void)data; - (void)conn; - return CURLE_NOT_BUILT_IN; -#endif -} - -/*********************************************************************** - * - * pop3_perform_user() - * - * Sends a clear text USER command to authenticate with. - */ -static CURLcode pop3_perform_user(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* Check we have a username and password to authenticate with and end the - connect phase if we do not */ - if(!data->state.aptr.user) { - pop3_state(data, POP3_STOP); - - return result; - } - - /* Send the USER command */ - result = Curl_pp_sendf(data, &pop3c->pp, "USER %s", - conn->user ? conn->user : ""); - if(!result) - pop3_state(data, POP3_USER); - - return result; -} - -#ifndef CURL_DISABLE_DIGEST_AUTH -/*********************************************************************** - * - * pop3_perform_apop() - * - * Sends an APOP command to authenticate with. - */ -static CURLcode pop3_perform_apop(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - size_t i; - struct MD5_context *ctxt; - unsigned char digest[MD5_DIGEST_LEN]; - char secret[(2 * MD5_DIGEST_LEN) + 1]; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* Check we have a username and password to authenticate with and end the - connect phase if we do not */ - if(!data->state.aptr.user) { - pop3_state(data, POP3_STOP); - - return result; - } - - /* Create the digest */ - ctxt = Curl_MD5_init(&Curl_DIGEST_MD5); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - Curl_MD5_update(ctxt, (const unsigned char *)pop3c->apoptimestamp, - curlx_uztoui(strlen(pop3c->apoptimestamp))); - - Curl_MD5_update(ctxt, (const unsigned char *)conn->passwd, - curlx_uztoui(strlen(conn->passwd))); - - /* Finalise the digest */ - Curl_MD5_final(ctxt, digest); - - /* Convert the calculated 16 octet digest into a 32 byte hex string */ - for(i = 0; i < MD5_DIGEST_LEN; i++) - curl_msnprintf(&secret[2 * i], 3, "%02x", digest[i]); - - result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret); - - if(!result) - pop3_state(data, POP3_APOP); - - return result; -} -#endif - -/*********************************************************************** - * - * pop3_perform_auth() - * - * Sends an AUTH command allowing the client to login with the given SASL - * authentication mechanism. - */ -static CURLcode pop3_perform_auth(struct Curl_easy *data, - const char *mech, - const struct bufref *initresp) -{ - struct pop3_conn *pop3c = - Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - const char *ir = Curl_bufref_ptr(initresp); - - if(!pop3c) - return CURLE_FAILED_INIT; - - if(ir) { /* AUTH ... */ - /* Send the AUTH command with the initial response */ - result = Curl_pp_sendf(data, &pop3c->pp, "AUTH %s %s", mech, ir); - } - else { - /* Send the AUTH command */ - result = Curl_pp_sendf(data, &pop3c->pp, "AUTH %s", mech); - } - - return result; -} - -/*********************************************************************** - * - * pop3_continue_auth() - * - * Sends SASL continuation data. - */ -static CURLcode pop3_continue_auth(struct Curl_easy *data, - const char *mech, - const struct bufref *resp) -{ - struct pop3_conn *pop3c = - Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN); - - (void)mech; - if(!pop3c) - return CURLE_FAILED_INIT; - - return Curl_pp_sendf(data, &pop3c->pp, "%s", Curl_bufref_ptr(resp)); -} - -/*********************************************************************** - * - * pop3_cancel_auth() - * - * Sends SASL cancellation. - */ -static CURLcode pop3_cancel_auth(struct Curl_easy *data, const char *mech) -{ - struct pop3_conn *pop3c = - Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN); - - (void)mech; - if(!pop3c) - return CURLE_FAILED_INIT; - - return Curl_pp_sendf(data, &pop3c->pp, "*"); -} - -/*********************************************************************** - * - * pop3_perform_authentication() - * - * Initiates the authentication sequence, with the appropriate SASL - * authentication mechanism, falling back to APOP and clear text should a - * common mechanism not be available between the client and server. - */ -static CURLcode pop3_perform_authentication(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - saslprogress progress = SASL_IDLE; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* Check we have enough data to authenticate with and end the - connect phase if we do not */ - if(!Curl_sasl_can_authenticate(&pop3c->sasl, data)) { - pop3_state(data, POP3_STOP); - return result; - } - - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_SASL) { - /* Calculate the SASL login details */ - result = Curl_sasl_start(&pop3c->sasl, data, FALSE, &progress); - - if(!result) - if(progress == SASL_INPROGRESS) - pop3_state(data, POP3_AUTH); - } - - if(!result && progress == SASL_IDLE) { -#ifndef CURL_DISABLE_DIGEST_AUTH - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP) - /* Perform APOP authentication */ - result = pop3_perform_apop(data, conn); - else -#endif - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT) - /* Perform clear text authentication */ - result = pop3_perform_user(data, conn); - else - result = Curl_sasl_is_blocked(&pop3c->sasl, data); - } - - return result; -} - -/*********************************************************************** - * - * pop3_perform_command() - * - * Sends a POP3 based command. - */ -static CURLcode pop3_perform_command(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct POP3 *pop3 = Curl_meta_get(data, CURL_META_POP3_EASY); - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - const char *command = NULL; - - if(!pop3 || !pop3c) - return CURLE_FAILED_INIT; - - /* Calculate the default command */ - if(pop3->id[0] == '\0' || data->set.list_only) { - command = "LIST"; - - if(pop3->id[0] != '\0') - /* Message specific LIST so skip the BODY transfer */ - pop3->transfer = PPTRANSFER_INFO; - } - else - command = "RETR"; - - if(pop3->custom && pop3->custom[0] != '\0') - command = pop3->custom; - - /* Send the command */ - if(pop3->id[0] != '\0') - result = Curl_pp_sendf(data, &pop3c->pp, "%s %s", command, pop3->id); - else - result = Curl_pp_sendf(data, &pop3c->pp, "%s", command); - - if(!result) { - pop3_state(data, POP3_COMMAND); - data->req.no_body = !pop3_is_multiline(command); - } - - return result; -} - -/*********************************************************************** - * - * pop3_perform_quit() - * - * Performs the quit action prior to sclose() be called. - */ -static CURLcode pop3_perform_quit(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* Send the QUIT command */ - result = Curl_pp_sendf(data, &pop3c->pp, "%s", "QUIT"); - if(!result) - pop3_state(data, POP3_QUIT); - - return result; -} - -/* For the initial server greeting */ -static CURLcode pop3_state_servergreet_resp(struct Curl_easy *data, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - const char *line; - size_t len; - - (void)instate; - if(!pop3c) - return CURLE_FAILED_INIT; - - line = curlx_dyn_ptr(&pop3c->pp.recvbuf); - len = pop3c->pp.nfinal; - - if(pop3code != '+') { - failf(data, "Got unexpected pop3-server response"); - result = CURLE_WEIRD_SERVER_REPLY; - } - else if(len > 3) { - /* Does the server support APOP authentication? */ - const char *lt; - const char *gt = NULL; - - /* Look for the APOP timestamp */ - lt = memchr(line, '<', len); - if(lt) - /* search the remainder for '>' */ - gt = memchr(lt, '>', len - (lt - line)); - if(gt) { - /* the length of the timestamp, including the brackets */ - size_t timestamplen = gt - lt + 1; - const char *at = memchr(lt, '@', timestamplen); - /* If the timestamp does not contain '@' it is not (as required by - RFC-1939) conformant to the RFC-822 message id syntax, and we - therefore do not use APOP authentication. */ - if(at) { - /* dupe the timestamp */ - pop3c->apoptimestamp = curlx_memdup0(lt, timestamplen); - if(!pop3c->apoptimestamp) - return CURLE_OUT_OF_MEMORY; - /* Store the APOP capability */ - pop3c->authtypes |= POP3_TYPE_APOP; - } - } - - if(!result) - result = pop3_perform_capa(data, conn); - } - - return result; -} - -/* For CAPA responses */ -static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - const char *line; - size_t len; - - (void)instate; - if(!pop3c) - return CURLE_FAILED_INIT; - - line = curlx_dyn_ptr(&pop3c->pp.recvbuf); - len = pop3c->pp.nfinal; - - /* Do we have an untagged continuation response? */ - if(pop3code == '*') { - /* Does the server support the STLS capability? */ - if(len >= 4 && curl_strnequal(line, "STLS", 4)) - pop3c->tls_supported = TRUE; - - /* Does the server support clear text authentication? */ - else if(len >= 4 && curl_strnequal(line, "USER", 4)) - pop3c->authtypes |= POP3_TYPE_CLEARTEXT; - - /* Does the server support SASL based authentication? */ - else if(len >= 5 && curl_strnequal(line, "SASL ", 5)) { - pop3c->authtypes |= POP3_TYPE_SASL; - - /* Advance past the SASL keyword */ - line += 5; - len -= 5; - - /* Loop through the data line */ - for(;;) { - size_t llen; - size_t wordlen = 0; - unsigned short mechbit; - - while(len && (ISBLANK(*line) || ISNEWLINE(*line))) { - line++; - len--; - } - - if(!len) - break; - - /* Extract the word */ - while(wordlen < len && !ISBLANK(line[wordlen]) && - !ISNEWLINE(line[wordlen])) - wordlen++; - - /* Test the word for a matching authentication mechanism */ - mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); - if(mechbit && llen == wordlen) - pop3c->sasl.authmechs |= mechbit; - - line += wordlen; - len -= wordlen; - } - } - } - else { - /* Clear text is supported when CAPA is not recognised */ - if(pop3code != '+') - pop3c->authtypes |= POP3_TYPE_CLEARTEXT; - - if(!data->set.use_ssl || Curl_conn_is_ssl(conn, FIRSTSOCKET)) - result = pop3_perform_authentication(data, conn); - else if(pop3code == '+' && pop3c->tls_supported) - /* Switch to TLS connection now */ - result = pop3_perform_starttls(data, conn); - else if(data->set.use_ssl <= CURLUSESSL_TRY) - /* Fallback and carry on with authentication */ - result = pop3_perform_authentication(data, conn); - else { - failf(data, "STLS not supported."); - result = CURLE_USE_SSL_FAILED; - } - } - - return result; -} - -/* For STARTTLS responses */ -static CURLcode pop3_state_starttls_resp(struct Curl_easy *data, - struct connectdata *conn, - int pop3code, - pop3state instate) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - (void)instate; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* Pipelining in response is forbidden. */ - if(pop3c->pp.overflow) - return CURLE_WEIRD_SERVER_REPLY; - - if(pop3code != '+') { - if(data->set.use_ssl != CURLUSESSL_TRY) { - failf(data, "STARTTLS denied"); - result = CURLE_USE_SSL_FAILED; - } - else - result = pop3_perform_authentication(data, conn); - } - else - pop3_state(data, POP3_UPGRADETLS); - - return result; -} - -/* For SASL authentication responses */ -static CURLcode pop3_state_auth_resp(struct Curl_easy *data, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - saslprogress progress; - - (void)instate; - if(!pop3c) - return CURLE_FAILED_INIT; - - result = Curl_sasl_continue(&pop3c->sasl, data, pop3code, &progress); - if(!result) - switch(progress) { - case SASL_DONE: - pop3_state(data, POP3_STOP); /* Authenticated */ - break; - case SASL_IDLE: /* No mechanism left after cancellation */ -#ifndef CURL_DISABLE_DIGEST_AUTH - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP) - /* Perform APOP authentication */ - result = pop3_perform_apop(data, conn); - else -#endif - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT) - /* Perform clear text authentication */ - result = pop3_perform_user(data, conn); - else { - failf(data, "Authentication cancelled"); - result = CURLE_LOGIN_DENIED; - } - break; - default: - break; - } - - return result; -} - -#ifndef CURL_DISABLE_DIGEST_AUTH -/* For APOP responses */ -static CURLcode pop3_state_apop_resp(struct Curl_easy *data, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(pop3code != '+') { - failf(data, "Authentication failed: %d", pop3code); - result = CURLE_LOGIN_DENIED; - } - else - /* End of connect phase */ - pop3_state(data, POP3_STOP); - - return result; -} -#endif - -/* For USER responses */ -static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - (void)instate; - - if(!pop3c) - return CURLE_FAILED_INIT; - - if(pop3code != '+') { - failf(data, "Access denied. %c", pop3code); - result = CURLE_LOGIN_DENIED; - } - else - /* Send the PASS command */ - result = Curl_pp_sendf(data, &pop3c->pp, "PASS %s", conn->passwd); - if(!result) - pop3_state(data, POP3_PASS); - - return result; -} - -/* For PASS responses */ -static CURLcode pop3_state_pass_resp(struct Curl_easy *data, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(pop3code != '+') { - failf(data, "Access denied. %c", pop3code); - result = CURLE_LOGIN_DENIED; - } - else - /* End of connect phase */ - pop3_state(data, POP3_STOP); - - return result; -} - -/*********************************************************************** - * - * pop3_write() - * - * This function scans the body after the end-of-body and writes everything - * until the end is found. - */ -static CURLcode pop3_write(struct Curl_easy *data, const char *str, - size_t nread, bool is_eos) -{ - /* This code could be made into a special function in the handler struct */ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - bool strip_dot = FALSE; - size_t last = 0; - size_t i; - (void)is_eos; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* Search through the buffer looking for the end-of-body marker which is - 5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches - the eob so the server will have prefixed it with an extra dot which we - need to strip out. Additionally the marker could of course be spread out - over 5 different data chunks. */ - for(i = 0; i < nread; i++) { - size_t prev = pop3c->eob; - - switch(str[i]) { - case 0x0d: - if(pop3c->eob == 0) { - pop3c->eob++; - - if(i) { - /* Write out the body part that did not match */ - result = Curl_client_write(data, CLIENTWRITE_BODY, &str[last], - i - last); - - if(result) - return result; - - last = i; - } - } - else if(pop3c->eob == 3) - pop3c->eob++; - else - /* If the character match was not at position 0 or 3 then restart the - pattern matching */ - pop3c->eob = 1; - break; - - case 0x0a: - if(pop3c->eob == 1 || pop3c->eob == 4) - pop3c->eob++; - else - /* If the character match was not at position 1 or 4 then start the - search again */ - pop3c->eob = 0; - break; - - case 0x2e: - if(pop3c->eob == 2) - pop3c->eob++; - else if(pop3c->eob == 3) { - /* We have an extra dot after the CRLF which we need to strip off */ - strip_dot = TRUE; - pop3c->eob = 0; - } - else - /* If the character match was not at position 2 then start the search - again */ - pop3c->eob = 0; - break; - - default: - pop3c->eob = 0; - break; - } - - /* Did we have a partial match which has subsequently failed? */ - if(prev && prev >= pop3c->eob) { - /* Strip can only be non-zero for the first mismatch after CRLF and - then both prev and strip are equal and nothing will be output below */ - while(prev && pop3c->strip) { - prev--; - pop3c->strip--; - } - - if(prev) { - /* If the partial match was the CRLF and dot then only write the CRLF - as the server would have inserted the dot */ - if(strip_dot && prev - 1 > 0) { - result = Curl_client_write(data, CLIENTWRITE_BODY, POP3_EOB, - prev - 1); - } - else if(!strip_dot) { - result = Curl_client_write(data, CLIENTWRITE_BODY, POP3_EOB, - prev); - } - else { - result = CURLE_OK; - } - - if(result) - return result; - - last = i; - strip_dot = FALSE; - } - } - } - - if(pop3c->eob == POP3_EOB_LEN) { - /* We have a full match so the transfer is done, however we must transfer - the CRLF at the start of the EOB as this is considered to be part of the - message as per RFC-1939, sect. 3 */ - result = Curl_client_write(data, CLIENTWRITE_BODY, POP3_EOB, 2); - - CURL_REQ_CLEAR_RECV(data); - pop3c->eob = 0; - - return result; - } - - if(pop3c->eob) - /* While EOB is matching nothing should be output */ - return CURLE_OK; - - if(nread - last) { - result = Curl_client_write(data, CLIENTWRITE_BODY, &str[last], - nread - last); - } - - return result; -} - -/* For command responses */ -static CURLcode pop3_state_command_resp(struct Curl_easy *data, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct POP3 *pop3 = Curl_meta_get(data, CURL_META_POP3_EASY); - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - struct pingpong *pp; - - (void)instate; - if(!pop3 || !pop3c) - return CURLE_FAILED_INIT; - - pp = &pop3c->pp; - if(pop3code != '+') { - pop3_state(data, POP3_STOP); - return CURLE_WEIRD_SERVER_REPLY; - } - - /* This 'OK' line ends with a CR LF pair which is the two first bytes of the - EOB string so count this is two matching bytes. This is necessary to make - the code detect the EOB if the only data than comes now is %2e CR LF like - when there is no body to return. */ - pop3c->eob = 2; - - /* Since this initial CR LF pair is not part of the actual body, we set - the strip counter here so that these bytes will not be delivered. */ - pop3c->strip = 2; - - if(pop3->transfer == PPTRANSFER_BODY) { - /* POP3 download */ - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); - - if(pp->overflow) { - /* The recv buffer contains data that is actually body content so send - it as such. Note that there may even be additional "headers" after - the body */ - - /* keep only the overflow */ - curlx_dyn_tail(&pp->recvbuf, pp->overflow); - pp->nfinal = 0; /* done */ - - if(!data->req.no_body) { - result = pop3_write(data, curlx_dyn_ptr(&pp->recvbuf), - curlx_dyn_len(&pp->recvbuf), FALSE); - if(result) - return result; - } - - /* reset the buffer */ - curlx_dyn_reset(&pp->recvbuf); - pp->overflow = 0; - } - } - else - pp->overflow = 0; - - /* End of DO phase */ - pop3_state(data, POP3_STOP); - - return result; -} - -static CURLcode pop3_statemachine(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - CURLcode result = CURLE_OK; - int pop3code; - struct pingpong *pp; - size_t nread = 0; - (void)data; - - if(!pop3c) - return CURLE_FAILED_INIT; - - pp = &pop3c->pp; - /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */ -upgrade_tls: - if(pop3c->state == POP3_UPGRADETLS) { - result = pop3_perform_upgrade_tls(data, conn); - if(result || (pop3c->state == POP3_UPGRADETLS)) - return result; - } - - /* Flush any data that needs to be sent */ - if(pp->sendleft) - return Curl_pp_flushsend(data, pp); - - do { - /* Read the response from the server */ - result = Curl_pp_readresp(data, FIRSTSOCKET, pp, &pop3code, &nread); - if(result) - return result; - - if(!pop3code) - break; - - /* We have now received a full POP3 server response */ - switch(pop3c->state) { - case POP3_SERVERGREET: - result = pop3_state_servergreet_resp(data, pop3code, pop3c->state); - break; - - case POP3_CAPA: - result = pop3_state_capa_resp(data, pop3code, pop3c->state); - break; - - case POP3_STARTTLS: - result = pop3_state_starttls_resp(data, conn, pop3code, pop3c->state); - /* During UPGRADETLS, leave the read loop as we need to connect - * (e.g. TLS handshake) before we continue sending/receiving. */ - if(!result && (pop3c->state == POP3_UPGRADETLS)) - goto upgrade_tls; - break; - - case POP3_AUTH: - result = pop3_state_auth_resp(data, pop3code, pop3c->state); - break; - -#ifndef CURL_DISABLE_DIGEST_AUTH - case POP3_APOP: - result = pop3_state_apop_resp(data, pop3code, pop3c->state); - break; -#endif - - case POP3_USER: - result = pop3_state_user_resp(data, pop3code, pop3c->state); - break; - - case POP3_PASS: - result = pop3_state_pass_resp(data, pop3code, pop3c->state); - break; - - case POP3_COMMAND: - result = pop3_state_command_resp(data, pop3code, pop3c->state); - break; - - case POP3_QUIT: - pop3_state(data, POP3_STOP); - break; - - default: - /* internal error */ - pop3_state(data, POP3_STOP); - break; - } - } while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp)); - - return result; -} - -/* Called repeatedly until done from multi.c */ -static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - - if(!pop3c) - return CURLE_FAILED_INIT; - result = Curl_pp_statemach(data, &pop3c->pp, FALSE, FALSE); - *done = (pop3c->state == POP3_STOP); - - return result; -} - -static CURLcode pop3_block_statemach(struct Curl_easy *data, - struct connectdata *conn, - bool disconnecting) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - - if(!pop3c) - return CURLE_FAILED_INIT; - - while(pop3c->state != POP3_STOP && !result) - result = Curl_pp_statemach(data, &pop3c->pp, TRUE, disconnecting); - - return result; -} - -/* For the POP3 "protocol connect" and "doing" phases only */ -static CURLcode pop3_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct pop3_conn *pop3c = - Curl_conn_meta_get(data->conn, CURL_META_POP3_CONN); - return pop3c ? Curl_pp_pollset(data, &pop3c->pp, ps) : CURLE_OK; -} - -/* SASL parameters for the pop3 protocol */ -static const struct SASLproto saslpop3 = { - "pop", /* The service name */ - pop3_perform_auth, /* Send authentication command */ - pop3_continue_auth, /* Send authentication continuation */ - pop3_cancel_auth, /* Send authentication cancellation */ - pop3_get_message, /* Get SASL response message */ - 255 - 8, /* Max line len - strlen("AUTH ") - 1 space - crlf */ - '*', /* Code received when continuation is expected */ - '+', /* Code to receive upon authentication success */ - SASL_AUTH_DEFAULT, /* Default mechanisms */ - SASL_FLAG_BASE64 /* Configuration flags */ -}; - -/*********************************************************************** - * - * pop3_connect() - * - * This function should do everything that is to be considered a part of the - * connection phase. - * - * The variable 'done' points to will be TRUE if the protocol-layer connect - * phase is done when this function returns, or FALSE if not. - */ -static CURLcode pop3_connect(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - struct pingpong *pp = pop3c ? &pop3c->pp : NULL; - - *done = FALSE; /* default to not done yet */ - if(!pop3c) - return CURLE_FAILED_INIT; - - PINGPONG_SETUP(pp, pop3_statemachine, pop3_endofresp); - - /* Set the default preferred authentication type and mechanism */ - pop3c->preftype = POP3_TYPE_ANY; - Curl_sasl_init(&pop3c->sasl, data, &saslpop3); - - /* Initialise the pingpong layer */ - Curl_pp_init(pp, Curl_pgrs_now(data)); - - /* Parse the URL options */ - result = pop3_parse_url_options(conn); - if(result) - return result; - - /* Start off waiting for the server greeting response */ - pop3_state(data, POP3_SERVERGREET); - - result = pop3_multi_statemach(data, done); - - return result; -} - -/*********************************************************************** - * - * pop3_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode pop3_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - CURLcode result = CURLE_OK; - struct POP3 *pop3 = Curl_meta_get(data, CURL_META_POP3_EASY); - - (void)premature; - - if(!pop3) - return CURLE_OK; - - if(status) { - connclose(data->conn, "POP3 done with bad status"); - result = status; /* use the already set error code */ - } - - /* Cleanup our per-request based variables */ - curlx_safefree(pop3->id); - curlx_safefree(pop3->custom); - - /* Clear the transfer mode for the next request */ - pop3->transfer = PPTRANSFER_BODY; - - return result; -} - -/*********************************************************************** - * - * pop3_perform() - * - * This is the actual DO function for POP3. Get a message/listing according to - * the options previously setup. - */ -static CURLcode pop3_perform(struct Curl_easy *data, bool *connected, - bool *dophase_done) -{ - /* This is POP3 and no proxy */ - CURLcode result = CURLE_OK; - struct POP3 *pop3 = Curl_meta_get(data, CURL_META_POP3_EASY); - - if(!pop3) - return CURLE_FAILED_INIT; - - DEBUGF(infof(data, "DO phase starts")); - - /* Start the first command in the DO phase, may alter data->req.no_body */ - result = pop3_perform_command(data); - if(result) - return result; - - if(data->req.no_body) - /* Requested no body means no transfer */ - pop3->transfer = PPTRANSFER_INFO; - - *dophase_done = FALSE; /* not done yet */ - - /* Run the state-machine */ - result = pop3_multi_statemach(data, dophase_done); - *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); - - if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete")); - - return result; -} - -/* Call this when the DO phase has completed */ -static CURLcode pop3_dophase_done(struct Curl_easy *data, bool connected) -{ - (void)data; - (void)connected; - - return CURLE_OK; -} - -/*********************************************************************** - * - * pop3_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - */ -static CURLcode pop3_regular_transfer(struct Curl_easy *data, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - bool connected = FALSE; - - /* Make sure size is unknown at this point */ - data->req.size = -1; - - /* Set the progress data */ - Curl_pgrsReset(data); - - /* Carry out the perform */ - result = pop3_perform(data, &connected, dophase_done); - - /* Perform post DO phase operations if necessary */ - if(!result && *dophase_done) - result = pop3_dophase_done(data, connected); - - return result; -} - -/*********************************************************************** - * - * pop3_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (pop3_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode pop3_do(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - *done = FALSE; /* default to false */ - - /* Parse the URL path */ - result = pop3_parse_url_path(data); - if(result) - return result; - - /* Parse the custom request */ - result = pop3_parse_custom_request(data); - if(result) - return result; - - result = pop3_regular_transfer(data, done); - - return result; -} - -/*********************************************************************** - * - * pop3_disconnect() - * - * Disconnect from an POP3 server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode pop3_disconnect(struct Curl_easy *data, - struct connectdata *conn, bool dead_connection) -{ - struct pop3_conn *pop3c = Curl_conn_meta_get(conn, CURL_META_POP3_CONN); - (void)data; - - if(!pop3c) - return CURLE_FAILED_INIT; - - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. */ - - if(!dead_connection && conn->bits.protoconnstart && - !Curl_pp_needs_flush(data, &pop3c->pp)) { - if(!pop3_perform_quit(data, conn)) - (void)pop3_block_statemach(data, conn, TRUE); /* ignore errors on QUIT */ - } - - /* Disconnect from the server */ - Curl_pp_disconnect(&pop3c->pp); - - /* Cleanup our connection based variables */ - curlx_safefree(pop3c->apoptimestamp); - - return CURLE_OK; -} - -/* Called from multi.c while DOing */ -static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done) -{ - CURLcode result = pop3_multi_statemach(data, dophase_done); - - if(result) - DEBUGF(infof(data, "DO phase failed")); - else if(*dophase_done) { - result = pop3_dophase_done(data, FALSE /* not connected */); - - DEBUGF(infof(data, "DO phase is complete")); - } - - return result; -} - -static void pop3_easy_dtor(void *key, size_t klen, void *entry) -{ - struct POP3 *pop3 = entry; - (void)key; - (void)klen; - DEBUGASSERT(pop3); - /* Cleanup our per-request based variables */ - curlx_safefree(pop3->id); - curlx_safefree(pop3->custom); - curlx_free(pop3); -} - -static void pop3_conn_dtor(void *key, size_t klen, void *entry) -{ - struct pop3_conn *pop3c = entry; - (void)key; - (void)klen; - DEBUGASSERT(pop3c); - Curl_pp_disconnect(&pop3c->pp); - curlx_safefree(pop3c->apoptimestamp); - curlx_free(pop3c); -} - -static CURLcode pop3_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct pop3_conn *pop3c; - struct POP3 *pop3 = curlx_calloc(1, sizeof(*pop3)); - if(!pop3 || - Curl_meta_set(data, CURL_META_POP3_EASY, pop3, pop3_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - pop3c = curlx_calloc(1, sizeof(*pop3c)); - if(!pop3c || - Curl_conn_meta_set(conn, CURL_META_POP3_CONN, pop3c, pop3_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -/* - * POP3 protocol. - */ -const struct Curl_protocol Curl_protocol_pop3 = { - pop3_setup_connection, /* setup_connection */ - pop3_do, /* do_it */ - pop3_done, /* done */ - ZERO_NULL, /* do_more */ - pop3_connect, /* connect_it */ - pop3_multi_statemach, /* connecting */ - pop3_doing, /* doing */ - pop3_pollset, /* proto_pollset */ - pop3_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - pop3_disconnect, /* disconnect */ - pop3_write, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* CURL_DISABLE_POP3 */ diff --git a/vendor/curl/lib/pop3.h b/vendor/curl/lib/pop3.h deleted file mode 100644 index 75c3a67da..000000000 --- a/vendor/curl/lib/pop3.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_POP3_H -#define HEADER_CURL_POP3_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_POP3 -extern const struct Curl_protocol Curl_protocol_pop3; -#endif - -#endif /* HEADER_CURL_POP3_H */ diff --git a/vendor/curl/lib/progress.c b/vendor/curl/lib/progress.c deleted file mode 100644 index 919c151e7..000000000 --- a/vendor/curl/lib/progress.c +++ /dev/null @@ -1,705 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "curl_trc.h" -#include "multiif.h" -#include "progress.h" -#include "transfer.h" -#include "curlx/strcopy.h" - -#ifndef CURL_DISABLE_PROGRESS_METER -/* Provide a string that is 7 letters long (plus the zero byte). - - @unittest 1636 -*/ -UNITTEST void time2str(char *r, size_t rsize, curl_off_t seconds); -UNITTEST void time2str(char *r, size_t rsize, curl_off_t seconds) -{ - curl_off_t h; - if(seconds <= 0) { - curlx_strcopy(r, rsize, STRCONST(" ")); - return; - } - h = seconds / 3600; - if(h <= 99) { - curl_off_t m = (seconds - (h * 3600)) / 60; - if(h <= 9) { - curl_off_t s = (seconds - (h * 3600)) - (m * 60); - if(h) - curl_msnprintf(r, rsize, "%" FMT_OFF_T ":%02" FMT_OFF_T ":" - "%02" FMT_OFF_T, h, m, s); - else - curl_msnprintf(r, rsize, " %02" FMT_OFF_T ":%02" FMT_OFF_T, m, s); - } - else - curl_msnprintf(r, rsize, "%" FMT_OFF_T "h %02" FMT_OFF_T "m", h, m); - } - else { - curl_off_t d = seconds / 86400; - h = (seconds - (d * 86400)) / 3600; - if(d <= 99) - curl_msnprintf(r, rsize, "%2" FMT_OFF_T "d %02" FMT_OFF_T "h", d, h); - else if(d <= 999) - curl_msnprintf(r, rsize, "%6" FMT_OFF_T "d", d); - else { /* more than 999 days */ - curl_off_t m = d / 30; - if(m <= 999) - curl_msnprintf(r, rsize, "%6" FMT_OFF_T "m", m); - else { /* more than 999 months */ - curl_off_t y = d / 365; - if(y <= 99999) - curl_msnprintf(r, rsize, "%6" FMT_OFF_T "y", y); - else - curlx_strcopy(r, rsize, STRCONST(">99999y")); - } - } - } -} - -/* The point of this function would be to return a string of the input data, - but never longer than 6 columns (+ one zero byte). - Add suffix k, M, G when suitable... - - @unittest 1636 -*/ -UNITTEST char *max6out(curl_off_t bytes, char *max6, size_t mlen); -UNITTEST char *max6out(curl_off_t bytes, char *max6, size_t mlen) -{ - /* a signed 64-bit value is 8192 petabytes maximum, shown as - 8.0E (exabytes)*/ - if(bytes < 100000) - curl_msnprintf(max6, mlen, "%6" CURL_FORMAT_CURL_OFF_T, bytes); - else { - const char unit[] = { 'k', 'M', 'G', 'T', 'P', 'E', 0 }; - int k = 0; - curl_off_t nbytes; - curl_off_t rest; - do { - nbytes = bytes / 1024; - if(nbytes < 1000) - break; - bytes = nbytes; - k++; - DEBUGASSERT(unit[k]); - } while(unit[k]); - rest = bytes % 1024; - if(nbytes <= 99) - /* xx.yyU */ - curl_msnprintf(max6, mlen, "%2" CURL_FORMAT_CURL_OFF_T - ".%02" CURL_FORMAT_CURL_OFF_T "%c", nbytes, - rest * 100 / 1024, unit[k]); - else - /* xxx.yU */ - curl_msnprintf(max6, mlen, "%3" CURL_FORMAT_CURL_OFF_T - ".%" CURL_FORMAT_CURL_OFF_T "%c", nbytes, - rest * 10 / 1024, unit[k]); - } - return max6; -} -#endif - -static void pgrs_speedinit(struct Curl_easy *data) -{ - memset(&data->state.keeps_speed, 0, sizeof(struct curltime)); -} - -/* - * @unittest 1606 - */ -UNITTEST CURLcode pgrs_speedcheck(struct Curl_easy *data, - const struct curltime *pnow); -UNITTEST CURLcode pgrs_speedcheck(struct Curl_easy *data, - const struct curltime *pnow) -{ - if(!data->set.low_speed_time || !data->set.low_speed_limit || - Curl_xfer_recv_is_paused(data) || Curl_xfer_send_is_paused(data)) - /* A paused transfer is not qualified for speed checks */ - return CURLE_OK; - - if(data->progress.current_speed >= 0) { - if(data->progress.current_speed < data->set.low_speed_limit) { - if(!data->state.keeps_speed.tv_sec) - /* under the limit at this moment */ - data->state.keeps_speed = *pnow; - else { - /* how long has it been under the limit */ - timediff_t howlong = - curlx_ptimediff_ms(pnow, &data->state.keeps_speed); - - if(howlong >= data->set.low_speed_time * 1000) { - /* too long */ - failf(data, "Operation too slow. Less than %" FMT_OFF_T - " bytes/sec transferred the last %u seconds", - data->set.low_speed_limit, data->set.low_speed_time); - return CURLE_OPERATION_TIMEDOUT; - } - } - } - else - /* faster right now */ - data->state.keeps_speed.tv_sec = 0; - } - - /* since low speed limit is enabled, set the expire timer to make this - connection's speed get checked again in a second */ - Curl_expire(data, 1000, EXPIRE_SPEEDCHECK); - - return CURLE_OK; -} - -const struct curltime *Curl_pgrs_now(struct Curl_easy *data) -{ - struct curltime *pnow = data->multi ? - &data->multi->now : &data->progress.now; - curlx_pnow(pnow); - return pnow; -} - -/* - New proposed interface, 9th of February 2000: - - pgrsStartNow() - sets start time - pgrsSetDownloadSize(x) - known expected download size - pgrsSetUploadSize(x) - known expected upload size - pgrsSetDownloadCounter() - amount of data currently downloaded - pgrsSetUploadCounter() - amount of data currently uploaded - pgrsUpdate() - show progress - pgrsDone() - transfer complete -*/ - -int Curl_pgrsDone(struct Curl_easy *data) -{ - int rc; - data->progress.lastshow = 0; - rc = Curl_pgrsUpdate(data); /* the final (forced) update */ - if(rc) - return rc; - - if(!data->progress.hide && !data->progress.callback) - /* only output if we do not use a progress callback and we are not - * hidden */ - curl_mfprintf(data->set.err, "\n"); - - return 0; -} - -void Curl_pgrsReset(struct Curl_easy *data) -{ - Curl_pgrsSetUploadCounter(data, 0); - data->progress.dl.cur_size = 0; - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - data->progress.speeder_c = 0; /* reset speed records */ - data->progress.deliver = 0; - pgrs_speedinit(data); -} - -/* reset the known transfer sizes */ -void Curl_pgrsResetTransferSizes(struct Curl_easy *data) -{ - Curl_pgrsSetDownloadSize(data, -1); - Curl_pgrsSetUploadSize(data, -1); -} - -void Curl_pgrsRecvPause(struct Curl_easy *data, bool enable) -{ - if(!enable) { - data->progress.speeder_c = 0; /* reset speed records */ - pgrs_speedinit(data); /* reset low speed measurements */ - } -} - -void Curl_pgrsSendPause(struct Curl_easy *data, bool enable) -{ - if(!enable) { - data->progress.speeder_c = 0; /* reset speed records */ - pgrs_speedinit(data); /* reset low speed measurements */ - } -} - -/* - * Curl_pgrsTimeWas(). Store the timestamp time at the given label. - */ -void Curl_pgrsTimeWas(struct Curl_easy *data, timerid timer, - struct curltime timestamp) -{ - timediff_t *delta = NULL; - - switch(timer) { - default: - case TIMER_NONE: - /* mistake filter */ - break; - case TIMER_STARTOP: - /* This is set at the start of a transfer */ - data->progress.t_startop = timestamp; - data->progress.t_startqueue = timestamp; - data->progress.t_postqueue = 0; - break; - case TIMER_STARTSINGLE: - /* This is set at the start of each single transfer */ - data->progress.t_startsingle = timestamp; - data->progress.is_t_startransfer_set = FALSE; - break; - case TIMER_POSTQUEUE: - /* Queue time is accumulative from all involved redirects */ - data->progress.t_postqueue += - curlx_ptimediff_us(×tamp, &data->progress.t_startqueue); - break; - case TIMER_STARTACCEPT: - data->progress.t_acceptdata = timestamp; - break; - case TIMER_NAMELOOKUP: - delta = &data->progress.t_nslookup; - break; - case TIMER_CONNECT: - delta = &data->progress.t_connect; - break; - case TIMER_APPCONNECT: - delta = &data->progress.t_appconnect; - break; - case TIMER_PRETRANSFER: - delta = &data->progress.t_pretransfer; - break; - case TIMER_STARTTRANSFER: - delta = &data->progress.t_starttransfer; - /* prevent updating t_starttransfer unless: - * 1. this is the first time we are setting t_starttransfer - * 2. a redirect has occurred since the last time t_starttransfer was set - * This prevents repeated invocations of the function from incorrectly - * changing the t_starttransfer time. - */ - if(data->progress.is_t_startransfer_set) { - return; - } - else { - data->progress.is_t_startransfer_set = TRUE; - break; - } - case TIMER_POSTRANSFER: - delta = &data->progress.t_posttransfer; - break; - case TIMER_REDIRECT: - data->progress.t_redirect = curlx_ptimediff_us(×tamp, - &data->progress.start); - data->progress.t_startqueue = timestamp; - break; - } - if(delta) { - timediff_t us = curlx_ptimediff_us(×tamp, - &data->progress.t_startsingle); - if(us < 1) - us = 1; /* make sure at least one microsecond passed */ - *delta += us; - } -} - -/* - * Curl_pgrsTime(). Store the current time at the given label. This fetches a - * fresh "now" and returns it. - * - * @unittest: 1399 - */ -void Curl_pgrsTime(struct Curl_easy *data, timerid timer) -{ - Curl_pgrsTimeWas(data, timer, *Curl_pgrs_now(data)); -} - -void Curl_pgrsStartNow(struct Curl_easy *data) -{ - struct Progress *p = &data->progress; - - p->speeder_c = 0; /* reset the progress meter display */ - p->start = *Curl_pgrs_now(data); - p->is_t_startransfer_set = FALSE; - p->dl.cur_size = 0; - p->ul.cur_size = 0; - /* the sizes are unknown at start */ - p->dl_size_known = FALSE; - p->ul_size_known = FALSE; -} - -/* check that the 'delta' amount of bytes are okay to deliver to the - application, or return error if not. */ -CURLcode Curl_pgrs_deliver_check(struct Curl_easy *data, size_t delta) -{ - if(data->set.max_filesize && - ((curl_off_t)delta > data->set.max_filesize - data->progress.deliver)) { - failf(data, "Would have exceeded max file size"); - return CURLE_FILESIZE_EXCEEDED; - } - return CURLE_OK; -} - -/* this counts how much data is delivered to the application, which - in compressed cases may differ from downloaded amount */ -void Curl_pgrs_deliver_inc(struct Curl_easy *data, size_t delta) -{ - data->progress.deliver += delta; -} - -void Curl_pgrs_download_inc(struct Curl_easy *data, size_t delta) -{ - if(delta) { - data->progress.dl.cur_size += delta; - Curl_rlimit_drain(&data->progress.dl.rlimit, delta, Curl_pgrs_now(data)); - } -} - -void Curl_pgrs_upload_inc(struct Curl_easy *data, size_t delta) -{ - if(delta) { - data->progress.ul.cur_size += delta; - Curl_rlimit_drain(&data->progress.ul.rlimit, delta, Curl_pgrs_now(data)); - } -} - -/* - * Set the number of uploaded bytes so far. - */ -void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size) -{ - data->progress.ul.cur_size = size; -} - -void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size) -{ - if(size >= 0) { - data->progress.dl.total_size = size; - data->progress.dl_size_known = TRUE; - } - else { - data->progress.dl.total_size = 0; - data->progress.dl_size_known = FALSE; - } -} - -void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size) -{ - if(size >= 0) { - data->progress.ul.total_size = size; - data->progress.ul_size_known = TRUE; - } - else { - data->progress.ul.total_size = 0; - data->progress.ul_size_known = FALSE; - } -} - -void Curl_pgrsEarlyData(struct Curl_easy *data, curl_off_t sent) -{ - data->progress.earlydata_sent = sent; -} - -/* returns the average speed in bytes / second */ -static curl_off_t trspeed(curl_off_t size, /* number of bytes */ - curl_off_t us) /* microseconds */ -{ - if(us < 1) - return size * 1000000; - else if(size < CURL_OFF_T_MAX / 1000000) - return (size * 1000000) / us; - else if(us >= 1000000) - return size / (us / 1000000); - else - return CURL_OFF_T_MAX; -} - -/* returns TRUE if it is time to show the progress meter */ -static bool progress_calc(struct Curl_easy *data, - const struct curltime *pnow) -{ - struct Progress * const p = &data->progress; - int i_next, i_oldest, i_latest; - timediff_t duration_us; - curl_off_t amount; - - /* The time spent so far (from the start) in microseconds */ - p->timespent = curlx_ptimediff_us(pnow, &p->start); - p->dl.speed = trspeed(p->dl.cur_size, p->timespent); - p->ul.speed = trspeed(p->ul.cur_size, p->timespent); - - if(!p->speeder_c) { /* no previous record exists */ - p->speed_amount[0] = p->dl.cur_size + p->ul.cur_size; - p->speed_time[0] = *pnow; - p->speeder_c++; - /* use the overall average at the start */ - p->current_speed = p->ul.speed + p->dl.speed; - p->lastshow = pnow->tv_sec; - return TRUE; - } - /* We have at least one record now. Where to put the next and - * where is the latest one? */ - i_next = p->speeder_c % CURL_SPEED_RECORDS; - i_latest = (i_next > 0) ? (i_next - 1) : (CURL_SPEED_RECORDS - 1); - - /* Make a new record only when some time has passed. - * Too frequent calls otherwise ruin the history. */ - if(curlx_ptimediff_ms(pnow, &p->speed_time[i_latest]) >= 1000) { - p->speeder_c++; - i_latest = i_next; - p->speed_amount[i_latest] = p->dl.cur_size + p->ul.cur_size; - p->speed_time[i_latest] = *pnow; - } - else if(data->req.done) { - /* When a transfer is done, and we did not have a current speed - * already, update the last record. Otherwise, stay at the speed - * we have. The last chunk of data, when rate limiting, would increase - * reported speed since it no longer measures a full second. */ - if(!p->current_speed) { - p->speed_amount[i_latest] = p->dl.cur_size + p->ul.cur_size; - p->speed_time[i_latest] = *pnow; - } - } - else { - /* transfer ongoing, wait for more time to pass. */ - return FALSE; - } - - i_oldest = (p->speeder_c < CURL_SPEED_RECORDS) ? 0 : - ((i_latest + 1) % CURL_SPEED_RECORDS); - - /* How much we transferred between oldest and current records */ - amount = p->speed_amount[i_latest] - p->speed_amount[i_oldest]; - /* How long this took */ - duration_us = curlx_ptimediff_us(&p->speed_time[i_latest], - &p->speed_time[i_oldest]); - if(duration_us <= 0) - duration_us = 1; - - if(amount > (CURL_OFF_T_MAX / 1000000)) { - /* the 'amount' value is bigger than would fit in 64 bits if - multiplied with 1000000, so we use the double math for this */ - p->current_speed = - (curl_off_t)(((double)amount * 1000000.0) / (double)duration_us); - } - else { - p->current_speed = amount * 1000000 / duration_us; - } - - if((p->lastshow == pnow->tv_sec) && !data->req.done) - return FALSE; - p->lastshow = pnow->tv_sec; - return TRUE; -} - -#ifndef CURL_DISABLE_PROGRESS_METER - -struct pgrs_estimate { - curl_off_t secs; - curl_off_t percent; -}; - -static curl_off_t pgrs_est_percent(curl_off_t total, curl_off_t cur) -{ - if(total > 10000) - return cur / (total / 100); - else if(total > 0) - return (cur * 100) / total; - return 0; -} - -static void pgrs_estimates(struct pgrs_dir *d, - bool total_known, - struct pgrs_estimate *est) -{ - est->secs = 0; - est->percent = 0; - if(total_known && (d->speed > 0)) { - est->secs = d->total_size / d->speed; - est->percent = pgrs_est_percent(d->total_size, d->cur_size); - } -} - -static void progress_meter(struct Curl_easy *data) -{ - struct Progress *p = &data->progress; - char max6[6][7]; - struct pgrs_estimate dl_estm; - struct pgrs_estimate ul_estm; - struct pgrs_estimate total_estm; - curl_off_t total_cur_size; - curl_off_t total_expected_size; - curl_off_t dl_size; - char time_left[8]; - char time_total[8]; - char time_spent[8]; - curl_off_t cur_secs = (curl_off_t)p->timespent / 1000000; /* seconds */ - - if(!p->headers_out) { - if(data->state.resume_from) { - curl_mfprintf(data->set.err, - "** Resuming transfer from byte position %" FMT_OFF_T "\n", - data->state.resume_from); - } - curl_mfprintf(data->set.err, - " %% Total %% Received %% Xferd Average Speed " - "Time Time Time Current\n" - " Dload Upload " - "Total Spent Left Speed\n"); - p->headers_out = TRUE; /* headers are shown */ - } - - /* Figure out the estimated time of arrival for upload and download */ - pgrs_estimates(&p->ul, (bool)p->ul_size_known, &ul_estm); - pgrs_estimates(&p->dl, (bool)p->dl_size_known, &dl_estm); - - /* Since both happen at the same time, total expected duration is max. */ - total_estm.secs = CURLMAX(ul_estm.secs, dl_estm.secs); - /* create the three time strings */ - time2str(time_left, sizeof(time_left), - total_estm.secs > 0 ? (total_estm.secs - cur_secs) : 0); - time2str(time_total, sizeof(time_total), total_estm.secs); - time2str(time_spent, sizeof(time_spent), cur_secs); - - /* Get the total amount of data expected to get transferred */ - total_expected_size = p->ul_size_known ? p->ul.total_size : p->ul.cur_size; - - dl_size = p->dl_size_known ? p->dl.total_size : p->dl.cur_size; - - /* integer overflow check */ - if((CURL_OFF_T_MAX - total_expected_size) < dl_size) - total_expected_size = CURL_OFF_T_MAX; /* capped */ - else - total_expected_size += dl_size; - - /* We have transferred this much so far */ - total_cur_size = p->dl.cur_size + p->ul.cur_size; - - /* Get the percentage of data transferred so far */ - total_estm.percent = pgrs_est_percent(total_expected_size, total_cur_size); - - curl_mfprintf(data->set.err, - "\r" - "%3" FMT_OFF_T " %s " - "%3" FMT_OFF_T " %s " - "%3" FMT_OFF_T " %s %s %s %s %s %s %s", - total_estm.percent, /* 3 letters */ /* total % */ - max6out(total_expected_size, max6[2], - sizeof(max6[2])), /* total size */ - dl_estm.percent, /* 3 letters */ /* rcvd % */ - max6out(p->dl.cur_size, max6[0], - sizeof(max6[0])), /* rcvd size */ - ul_estm.percent, /* 3 letters */ /* xfer % */ - max6out(p->ul.cur_size, max6[1], - sizeof(max6[1])), /* xfer size */ - max6out(p->dl.speed, max6[3], - sizeof(max6[3])), /* avrg dl speed */ - max6out(p->ul.speed, max6[4], - sizeof(max6[4])), /* avrg ul speed */ - time_total, /* 7 letters */ /* total time */ - time_spent, /* 7 letters */ /* time spent */ - time_left, /* 7 letters */ /* time left */ - max6out(p->current_speed, max6[5], - sizeof(max6[5])) /* current speed */ - ); - - /* we flush the output stream to make it appear as soon as possible */ - fflush(data->set.err); -} -#else /* CURL_DISABLE_PROGRESS_METER */ -#define progress_meter(x) Curl_nop_stmt -#endif - -/* - * Curl_pgrsUpdate() returns 0 for success or the value returned by the - * progress callback! - */ -static CURLcode pgrsupdate(struct Curl_easy *data, bool showprogress) -{ - if(!data->progress.hide) { - int rc; - if(data->set.fxferinfo) { - /* There is a callback set, call that */ - Curl_set_in_callback(data, TRUE); - rc = data->set.fxferinfo(data->set.progress_client, - data->progress.dl.total_size, - data->progress.dl.cur_size, - data->progress.ul.total_size, - data->progress.ul.cur_size); - Curl_set_in_callback(data, FALSE); - if(rc != CURL_PROGRESSFUNC_CONTINUE) { - if(rc) { - failf(data, "Callback aborted"); - return CURLE_ABORTED_BY_CALLBACK; - } - return CURLE_OK; - } - } - else if(data->set.fprogress) { - /* The older deprecated callback is set, call that */ - Curl_set_in_callback(data, TRUE); - rc = data->set.fprogress(data->set.progress_client, - (double)data->progress.dl.total_size, - (double)data->progress.dl.cur_size, - (double)data->progress.ul.total_size, - (double)data->progress.ul.cur_size); - Curl_set_in_callback(data, FALSE); - if(rc != CURL_PROGRESSFUNC_CONTINUE) { - if(rc) { - failf(data, "Callback aborted"); - return CURLE_ABORTED_BY_CALLBACK; - } - return CURLE_OK; - } - } - - if(showprogress) - progress_meter(data); - } - - return CURLE_OK; -} - -static CURLcode pgrs_update(struct Curl_easy *data, - const struct curltime *pnow) -{ - bool showprogress = progress_calc(data, pnow); - return pgrsupdate(data, showprogress); -} - -CURLcode Curl_pgrsUpdate(struct Curl_easy *data) -{ - return pgrs_update(data, Curl_pgrs_now(data)); -} - -CURLcode Curl_pgrsCheck(struct Curl_easy *data) -{ - CURLcode result; - - result = pgrs_update(data, Curl_pgrs_now(data)); - if(!result && !data->req.done) - result = pgrs_speedcheck(data, Curl_pgrs_now(data)); - return result; -} - -/* - * Update all progress, do not do progress meter/callbacks. - */ -void Curl_pgrsUpdate_nometer(struct Curl_easy *data) -{ - (void)progress_calc(data, Curl_pgrs_now(data)); -} diff --git a/vendor/curl/lib/progress.h b/vendor/curl/lib/progress.h deleted file mode 100644 index 7d419ecb8..000000000 --- a/vendor/curl/lib/progress.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef HEADER_CURL_PROGRESS_H -#define HEADER_CURL_PROGRESS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/timeval.h" - -struct Curl_easy; - -typedef enum { - TIMER_NONE, - TIMER_STARTOP, - TIMER_STARTSINGLE, /* start of transfer, might get queued */ - TIMER_POSTQUEUE, /* start, immediately after dequeue */ - TIMER_NAMELOOKUP, - TIMER_CONNECT, - TIMER_APPCONNECT, - TIMER_PRETRANSFER, - TIMER_STARTTRANSFER, - TIMER_POSTRANSFER, - TIMER_STARTACCEPT, - TIMER_REDIRECT, - TIMER_LAST /* must be last */ -} timerid; - -/* Get the current timestamp of the transfer */ -const struct curltime *Curl_pgrs_now(struct Curl_easy *data); - -int Curl_pgrsDone(struct Curl_easy *data); -void Curl_pgrsStartNow(struct Curl_easy *data); -void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size); -void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size); -CURLcode Curl_pgrs_deliver_check(struct Curl_easy *data, size_t delta); -void Curl_pgrs_deliver_inc(struct Curl_easy *data, size_t delta); -void Curl_pgrs_download_inc(struct Curl_easy *data, size_t delta); -void Curl_pgrs_upload_inc(struct Curl_easy *data, size_t delta); -void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size); - -/* perform progress update, invoking callbacks at intervals */ -CURLcode Curl_pgrsUpdate(struct Curl_easy *data); -/* perform progress update, no callbacks invoked */ -void Curl_pgrsUpdate_nometer(struct Curl_easy *data); -/* perform progress update with callbacks and speed checks */ -CURLcode Curl_pgrsCheck(struct Curl_easy *data); - -/* Inform progress/speedcheck about receive/send pausing */ -void Curl_pgrsRecvPause(struct Curl_easy *data, bool enable); -void Curl_pgrsSendPause(struct Curl_easy *data, bool enable); - -/* Reset sizes and counters for up- and download. */ -void Curl_pgrsReset(struct Curl_easy *data); -/* Reset sizes for up- and download. */ -void Curl_pgrsResetTransferSizes(struct Curl_easy *data); - -void Curl_pgrsTime(struct Curl_easy *data, timerid timer); -/** - * Update progress timer with the elapsed time from its start to `timestamp`. - * This allows updating timers later and is used by happy eyeballing, where - * we only want to record the winner's times. - */ -void Curl_pgrsTimeWas(struct Curl_easy *data, timerid timer, - struct curltime timestamp); - -void Curl_pgrsEarlyData(struct Curl_easy *data, curl_off_t sent); - -#endif /* HEADER_CURL_PROGRESS_H */ diff --git a/vendor/curl/lib/protocol.c b/vendor/curl/lib/protocol.c deleted file mode 100644 index c8d43251c..000000000 --- a/vendor/curl/lib/protocol.c +++ /dev/null @@ -1,485 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "protocol.h" -#include "strcase.h" - -#include "dict.h" -#include "file.h" -#include "ftp.h" -#include "gopher.h" -#include "http.h" -#include "imap.h" -#include "curl_ldap.h" -#include "mqtt.h" -#include "pop3.h" -#include "rtsp.h" -#include "smb.h" -#include "smtp.h" -#include "telnet.h" -#include "tftp.h" -#include "ws.h" -#include "vssh/ssh.h" - - -/* All URI schemes known to libcurl, but not necessarily implemented - * by protocol handlers. */ -const struct Curl_scheme Curl_scheme_dict = { - "dict", /* scheme */ -#ifdef CURL_DISABLE_DICT - ZERO_NULL, -#else - &Curl_protocol_dict, -#endif - CURLPROTO_DICT, /* protocol */ - CURLPROTO_DICT, /* family */ - PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */ - PORT_DICT, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_file = { - "file", /* scheme */ -#ifdef CURL_DISABLE_FILE - ZERO_NULL, -#else - &Curl_protocol_file, -#endif - CURLPROTO_FILE, /* protocol */ - CURLPROTO_FILE, /* family */ - PROTOPT_NONETWORK | PROTOPT_NOURLQUERY, /* flags */ - 0 /* defport */ -}; - -const struct Curl_scheme Curl_scheme_ftp = { - "ftp", /* scheme */ -#ifdef CURL_DISABLE_FTP - ZERO_NULL, -#else - &Curl_protocol_ftp, -#endif - CURLPROTO_FTP, /* protocol */ - CURLPROTO_FTP, /* family */ - PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | - PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP | - PROTOPT_WILDCARD | PROTOPT_SSL_REUSE | - PROTOPT_CONN_REUSE, /* flags */ - PORT_FTP, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_ftps = { - "ftps", /* scheme */ -#if defined(CURL_DISABLE_FTP) || !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_ftp, -#endif - CURLPROTO_FTPS, /* protocol */ - CURLPROTO_FTP, /* family */ - PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | - PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD | - PROTOPT_CONN_REUSE, /* flags */ - PORT_FTPS, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_gopher = { - "gopher", /* scheme */ -#ifdef CURL_DISABLE_GOPHER - ZERO_NULL, -#else - &Curl_protocol_gopher, -#endif - CURLPROTO_GOPHER, /* protocol */ - CURLPROTO_GOPHER, /* family */ - PROTOPT_NONE, /* flags */ - PORT_GOPHER, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_gophers = { - "gophers", /* scheme */ -#if defined(CURL_DISABLE_GOPHER) || !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_gophers, -#endif - CURLPROTO_GOPHERS, /* protocol */ - CURLPROTO_GOPHER, /* family */ - PROTOPT_SSL, /* flags */ - PORT_GOPHER, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_http = { - "http", /* scheme */ -#ifdef CURL_DISABLE_HTTP - ZERO_NULL, -#else - &Curl_protocol_http, -#endif - CURLPROTO_HTTP, /* protocol */ - CURLPROTO_HTTP, /* family */ - PROTOPT_CREDSPERREQUEST | /* flags */ - PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE, - PORT_HTTP, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_https = { - "https", /* scheme */ -#if defined(CURL_DISABLE_HTTP) || !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_http, -#endif - CURLPROTO_HTTPS, /* protocol */ - CURLPROTO_HTTP, /* family */ - PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */ - PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE, - PORT_HTTPS, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_imap = { - "imap", /* scheme */ -#ifdef CURL_DISABLE_IMAP - ZERO_NULL, -#else - &Curl_protocol_imap, -#endif - CURLPROTO_IMAP, /* protocol */ - CURLPROTO_IMAP, /* family */ - PROTOPT_CLOSEACTION | /* flags */ - PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | - PROTOPT_CONN_REUSE, - PORT_IMAP, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_imaps = { - "imaps", /* scheme */ -#if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_imap, -#endif - CURLPROTO_IMAPS, /* protocol */ - CURLPROTO_IMAP, /* family */ - PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ - PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, - PORT_IMAPS, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_ldap = { - "ldap", /* scheme */ -#ifdef CURL_DISABLE_LDAP - ZERO_NULL, -#else - &Curl_protocol_ldap, -#endif - CURLPROTO_LDAP, /* protocol */ - CURLPROTO_LDAP, /* family */ - PROTOPT_SSL_REUSE, /* flags */ - PORT_LDAP, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_ldaps = { - "ldaps", /* scheme */ -#if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL) - ZERO_NULL, -#else - &Curl_protocol_ldap, -#endif - CURLPROTO_LDAPS, /* protocol */ - CURLPROTO_LDAP, /* family */ - PROTOPT_SSL, /* flags */ - PORT_LDAPS, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_mqtt = { - "mqtt", /* scheme */ -#ifdef CURL_DISABLE_MQTT - ZERO_NULL, -#else - &Curl_protocol_mqtt, -#endif - CURLPROTO_MQTT, /* protocol */ - CURLPROTO_MQTT, /* family */ - PROTOPT_NONE, /* flags */ - PORT_MQTT, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_mqtts = { - "mqtts", /* scheme */ -#if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_mqtts, -#endif - CURLPROTO_MQTTS, /* protocol */ - CURLPROTO_MQTT, /* family */ - PROTOPT_SSL, /* flags */ - PORT_MQTTS, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_pop3 = { - "pop3", /* scheme */ -#ifdef CURL_DISABLE_POP3 - ZERO_NULL, -#else - &Curl_protocol_pop3, -#endif - CURLPROTO_POP3, /* protocol */ - CURLPROTO_POP3, /* family */ - PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ - PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE, - PORT_POP3, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_pop3s = { - "pop3s", /* scheme */ -#if defined(CURL_DISABLE_POP3) || !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_pop3, -#endif - CURLPROTO_POP3S, /* protocol */ - CURLPROTO_POP3, /* family */ - PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ - PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, - PORT_POP3S, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_rtsp = { - "rtsp", /* scheme */ -#ifdef CURL_DISABLE_RTSP - ZERO_NULL, -#else - &Curl_protocol_rtsp, -#endif - CURLPROTO_RTSP, /* protocol */ - CURLPROTO_RTSP, /* family */ - PROTOPT_CONN_REUSE, /* flags */ - PORT_RTSP, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_sftp = { - "sftp", /* scheme */ -#ifndef USE_SSH - NULL, -#else - &Curl_protocol_sftp, -#endif - CURLPROTO_SFTP, /* protocol */ - CURLPROTO_SFTP, /* family */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */ - PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE, - PORT_SSH /* defport */ -}; - -const struct Curl_scheme Curl_scheme_scp = { - "scp", /* scheme */ -#ifndef USE_SSH - NULL, -#else - &Curl_protocol_scp, -#endif - CURLPROTO_SCP, /* protocol */ - CURLPROTO_SCP, /* family */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */ - PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE, - PORT_SSH, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_smb = { - "smb", /* scheme */ -#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) - &Curl_protocol_smb, -#else - ZERO_NULL, -#endif - CURLPROTO_SMB, /* protocol */ - CURLPROTO_SMB, /* family */ - PROTOPT_NONE, /* flags */ - PORT_SMB, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_smbs = { - "smbs", /* scheme */ -#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) && defined(USE_SSL) - &Curl_protocol_smb, -#else - ZERO_NULL, -#endif - CURLPROTO_SMBS, /* protocol */ - CURLPROTO_SMB, /* family */ - PROTOPT_SSL, /* flags */ - PORT_SMBS, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_smtp = { - "smtp", /* scheme */ -#ifdef CURL_DISABLE_SMTP - ZERO_NULL, -#else - &Curl_protocol_smtp, -#endif - CURLPROTO_SMTP, /* protocol */ - CURLPROTO_SMTP, /* family */ - PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ - PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE, - PORT_SMTP, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_smtps = { - "smtps", /* scheme */ -#if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_smtp, -#endif - CURLPROTO_SMTPS, /* protocol */ - CURLPROTO_SMTP, /* family */ - PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ - PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, - PORT_SMTPS, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_telnet = { - "telnet", /* scheme */ -#ifdef CURL_DISABLE_TELNET - ZERO_NULL, -#else - &Curl_protocol_telnet, -#endif - CURLPROTO_TELNET, /* protocol */ - CURLPROTO_TELNET, /* family */ - PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */ - PORT_TELNET, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_tftp = { - "tftp", /* scheme */ -#ifdef CURL_DISABLE_TFTP - ZERO_NULL, -#else - &Curl_protocol_tftp, -#endif - CURLPROTO_TFTP, /* protocol */ - CURLPROTO_TFTP, /* family */ - PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */ - PORT_TFTP, /* defport */ -}; - -const struct Curl_scheme Curl_scheme_ws = { - "ws", /* scheme */ -#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) - ZERO_NULL, -#else - &Curl_protocol_ws, -#endif - CURLPROTO_WS, /* protocol */ - CURLPROTO_HTTP, /* family */ - PROTOPT_CREDSPERREQUEST | /* flags */ - PROTOPT_USERPWDCTRL, - PORT_HTTP /* defport */ -}; - -const struct Curl_scheme Curl_scheme_wss = { - "wss", /* scheme */ -#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) || \ - !defined(USE_SSL) - ZERO_NULL, -#else - &Curl_protocol_ws, -#endif - CURLPROTO_WSS, /* protocol */ - CURLPROTO_HTTP, /* family */ - PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */ - PROTOPT_USERPWDCTRL, - PORT_HTTPS /* defport */ -}; - -/* Returns a struct scheme pointer if the name is a known scheme. Check the - ->run struct field for non-NULL to figure out if an implementation is - present. */ -const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len) -{ - /* table generated by schemetable.c: - 1. gcc schemetable.c && ./a.out - 2. check how small the table gets - 3. tweak the hash algorithm, then rerun from 1 - 4. when the table is good enough - 5. copy the table into this source code - 6. make sure this function uses the same hash function that worked for - schemetable.c - */ - static const struct Curl_scheme * const all_schemes[47] = { - &Curl_scheme_mqtt, - &Curl_scheme_smtp, - &Curl_scheme_tftp, - &Curl_scheme_imap, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - &Curl_scheme_ldaps, - &Curl_scheme_dict, NULL, - &Curl_scheme_file, NULL, - &Curl_scheme_pop3s, - &Curl_scheme_ftp, - &Curl_scheme_scp, - &Curl_scheme_mqtts, - &Curl_scheme_imaps, - &Curl_scheme_ldap, - &Curl_scheme_http, - &Curl_scheme_smb, NULL, NULL, - &Curl_scheme_telnet, - &Curl_scheme_https, - &Curl_scheme_gopher, - &Curl_scheme_rtsp, NULL, NULL, - &Curl_scheme_wss, NULL, - &Curl_scheme_gophers, - &Curl_scheme_smtps, - &Curl_scheme_pop3, - &Curl_scheme_ws, NULL, NULL, - &Curl_scheme_sftp, - &Curl_scheme_ftps, NULL, - &Curl_scheme_smbs, NULL, - }; - - if(len && (len <= 7)) { - const char *s = scheme; - size_t l = len; - const struct Curl_scheme *h; - unsigned int c = 792; - while(l) { - c <<= 4; - c += (unsigned int)Curl_raw_tolower(*s); - s++; - l--; - } - - h = all_schemes[c % 47]; - if(h && curl_strnequal(scheme, h->name, len) && !h->name[len]) - return h; - } - return NULL; -} - -const struct Curl_scheme *Curl_get_scheme(const char *scheme) -{ - return Curl_getn_scheme(scheme, strlen(scheme)); -} diff --git a/vendor/curl/lib/protocol.h b/vendor/curl/lib/protocol.h deleted file mode 100644 index f8254096e..000000000 --- a/vendor/curl/lib/protocol.h +++ /dev/null @@ -1,276 +0,0 @@ -#ifndef HEADER_CURL_PROTOCOL_H -#define HEADER_CURL_PROTOCOL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* This file is for lib internal stuff */ -#include "curl_setup.h" - -struct Curl_easy; -struct connectdata; -struct easy_pollset; - -/* Known protocol default port numbers */ -#define PORT_FTP 21 -#define PORT_FTPS 990 -#define PORT_TELNET 23 -#define PORT_HTTP 80 -#define PORT_HTTPS 443 -#define PORT_DICT 2628 -#define PORT_LDAP 389 -#define PORT_LDAPS 636 -#define PORT_TFTP 69 -#define PORT_SSH 22 -#define PORT_IMAP 143 -#define PORT_IMAPS 993 -#define PORT_POP3 110 -#define PORT_POP3S 995 -#define PORT_SMB 445 -#define PORT_SMBS 445 -#define PORT_SMTP 25 -#define PORT_SMTPS 465 /* sometimes called SSMTP */ -#define PORT_RTSP 554 -#define PORT_GOPHER 70 -#define PORT_MQTT 1883 -#define PORT_MQTTS 8883 - -/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number, - * the rest are internal information. If we use higher bits we only do this on - * platforms that have a >= 64-bit type and then we use such a type for the - * protocol fields in the scheme definition. - */ -#define CURLPROTO_WS (1L << 30) -#define CURLPROTO_WSS ((curl_prot_t)1 << 31) -#define CURLPROTO_MQTTS (1LL << 32) - -#define CURLPROTO_64ALL ((uint64_t)0xffffffffffffffff) - -/* the default protocols accepting a redirect to */ -#define CURLPROTO_REDIR (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | \ - CURLPROTO_FTPS) - -typedef curl_off_t curl_prot_t; - -/* This mask is for all the old protocols that are provided and defined in the - public header and shall exclude protocols added since which are not exposed - in the API */ -#define CURLPROTO_MASK 0x3fffffff - -/* Convenience defines for checking protocols or their SSL based version. Each - protocol scheme should only ever have a single CURLPROTO_ in its protocol - field. */ -#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_WS | \ - CURLPROTO_WSS) -#define PROTO_FAMILY_FTP (CURLPROTO_FTP | CURLPROTO_FTPS) -#define PROTO_FAMILY_POP3 (CURLPROTO_POP3 | CURLPROTO_POP3S) -#define PROTO_FAMILY_SMB (CURLPROTO_SMB | CURLPROTO_SMBS) -#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP | CURLPROTO_SMTPS) -#define PROTO_FAMILY_SSH (CURLPROTO_SCP | CURLPROTO_SFTP) - -#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) || \ - !defined(CURL_DISABLE_POP3) -/* these protocols support CURLOPT_DIRLISTONLY */ -#define CURL_LIST_ONLY_PROTOCOL 1 -#endif - -/* When redirecting transfers. */ -typedef enum { - FOLLOW_NONE, /* not used within the function, a placeholder to allow - initing to this */ - FOLLOW_FAKE, /* only records stuff, not actually following */ - FOLLOW_RETRY, /* set if this is a request retry as opposed to a real - redirect following */ - FOLLOW_REDIR /* a full true redirect */ -} followtype; - -/* - * Specific protocol handler, an implementation of one or more URI schemes. - */ -struct Curl_protocol { - /* Complement to setup_connection_internals(). This is done before the - transfer "owns" the connection. */ - CURLcode (*setup_connection)(struct Curl_easy *data, - struct connectdata *conn); - - /* These two functions MUST be set to be protocol dependent */ - CURLcode (*do_it)(struct Curl_easy *data, bool *done); - CURLcode (*done)(struct Curl_easy *, CURLcode, bool); - - /* If the curl_do() function is better made in two halves, this - * curl_do_more() function will be called afterwards, if set. For example - * for doing the FTP stuff after the PASV/PORT command. - */ - CURLcode (*do_more)(struct Curl_easy *, int *); - - /* This function *MAY* be set to a protocol-dependent function that is run - * after the connect() and everything is done, as a step in the connection. - * The 'done' pointer points to a bool that should be set to TRUE if the - * function completes before return. If it does not complete, the caller - * should call the ->connecting() function until it is. - */ - CURLcode (*connect_it)(struct Curl_easy *data, bool *done); - - /* See above. */ - CURLcode (*connecting)(struct Curl_easy *data, bool *done); - CURLcode (*doing)(struct Curl_easy *data, bool *done); - - /* Called from the multi interface during the PROTOCONNECT phase, and it - should then return a proper fd set */ - CURLcode (*proto_pollset)(struct Curl_easy *data, - struct easy_pollset *ps); - - /* Called from the multi interface during the DOING phase, and it should - then return a proper fd set */ - CURLcode (*doing_pollset)(struct Curl_easy *data, - struct easy_pollset *ps); - - /* Called from the multi interface during the DO_MORE phase, and it should - then return a proper fd set */ - CURLcode (*domore_pollset)(struct Curl_easy *data, - struct easy_pollset *ps); - - /* Called from the multi interface during the DO_DONE, PERFORM and - WAITPERFORM phases, and it should then return a proper fd set. Not setting - this will make libcurl use the generic default one. */ - CURLcode (*perform_pollset)(struct Curl_easy *data, - struct easy_pollset *ps); - - /* This function *MAY* be set to a protocol-dependent function that is run - * by the curl_disconnect(), as a step in the disconnection. If the handler - * is called because the connection has been considered dead, - * dead_connection is set to TRUE. The connection is (again) associated with - * the transfer here. - */ - CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *, - bool dead_connection); - - /* If used, this function gets called from transfer.c to - allow the protocol to do extra handling in writing response to - the client. */ - CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen, - bool is_eos); - - /* If used, this function gets called from transfer.c to - allow the protocol to do extra handling in writing a single response - header line to the client. */ - CURLcode (*write_resp_hd)(struct Curl_easy *data, - const char *hd, size_t hdlen, bool is_eos); - - /* If used, this function checks for a connection managed by this - protocol and currently not in use, if it should be considered dead. */ - bool (*connection_is_dead)(struct Curl_easy *data, - struct connectdata *conn); - - /* attach() attaches this transfer to this connection */ - void (*attach)(struct Curl_easy *data, struct connectdata *conn); - - /* return CURLE_OK if a redirect to `newurl` should be followed, - CURLE_TOO_MANY_REDIRECTS otherwise. May alter `data` to change - the way the follow request is performed. */ - CURLcode (*follow)(struct Curl_easy *data, const char *newurl, - followtype type); -}; - -#define PROTOPT_NONE 0 /* nothing extra */ -#define PROTOPT_SSL (1 << 0) /* uses SSL */ -#define PROTOPT_DUAL (1 << 1) /* this protocol uses two connections */ -#define PROTOPT_CLOSEACTION (1 << 2) /* need action before socket close */ -/* some protocols will have to call the underlying functions without regard to - what exact state the socket signals. IE even if the socket says "readable", - the send function might need to be called while uploading, or vice versa. -*/ -#define PROTOPT_DIRLOCK (1 << 3) -#define PROTOPT_NONETWORK (1 << 4) /* protocol does not use the network! */ -#define PROTOPT_NEEDSPWD (1 << 5) /* needs a password, and if none is set it - gets a default */ -#define PROTOPT_NOURLQUERY (1 << 6) /* protocol cannot handle - URL query strings (?foo=bar) ! */ -#define PROTOPT_CREDSPERREQUEST (1 << 7) /* requires login credentials per - request instead of per - connection */ -#define PROTOPT_ALPN (1 << 8) /* set ALPN for this */ -/* (1 << 9) was PROTOPT_STREAM, now free */ -#define PROTOPT_URLOPTIONS (1 << 10) /* allow options part in the userinfo - field of the URL */ -#define PROTOPT_PROXY_AS_HTTP (1 << 11) /* allow this non-HTTP scheme over a - HTTP proxy as HTTP proxies may know - this protocol and act as - a gateway */ -#define PROTOPT_WILDCARD (1 << 12) /* protocol supports wildcard matching */ -#define PROTOPT_USERPWDCTRL (1 << 13) /* Allow "control bytes" (< 32 ASCII) in - username and password */ -#define PROTOPT_NOTCPPROXY (1 << 14) /* this protocol cannot proxy over TCP */ -#define PROTOPT_SSL_REUSE (1 << 15) /* this protocol may reuse an existing - SSL connection in the same family - without having PROTOPT_SSL. */ -#define PROTOPT_CONN_REUSE (1 << 16) /* this protocol can reuse connections */ - -/* Everything about a URI scheme. */ -struct Curl_scheme { - const char *name; /* URL scheme name in lowercase */ - const struct Curl_protocol *run; /* implementation, optional */ - curl_prot_t protocol; /* See CURLPROTO_* - this needs to be the single - specific protocol bit */ - curl_prot_t family; /* single bit for protocol family; the non-TLS name - of the protocol this is */ - uint32_t flags; /* Extra particular characteristics, see PROTOPT_* */ - uint16_t defport; /* Default port. */ -}; - -/* Get scheme definition for a URI scheme name - * @param scheme URI scheme name, case-insensitive - * @return NULL if scheme is not known - */ -const struct Curl_scheme *Curl_get_scheme(const char *scheme); -const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len); - -/* For direct access to a URI scheme */ -extern const struct Curl_scheme Curl_scheme_dict; -extern const struct Curl_scheme Curl_scheme_file; -extern const struct Curl_scheme Curl_scheme_ftp; -extern const struct Curl_scheme Curl_scheme_ftps; -extern const struct Curl_scheme Curl_scheme_gopher; -extern const struct Curl_scheme Curl_scheme_gophers; -extern const struct Curl_scheme Curl_scheme_http; -extern const struct Curl_scheme Curl_scheme_https; -extern const struct Curl_scheme Curl_scheme_imap; -extern const struct Curl_scheme Curl_scheme_imaps; -extern const struct Curl_scheme Curl_scheme_ldap; -extern const struct Curl_scheme Curl_scheme_ldaps; -extern const struct Curl_scheme Curl_scheme_mqtt; -extern const struct Curl_scheme Curl_scheme_mqtts; -extern const struct Curl_scheme Curl_scheme_pop3; -extern const struct Curl_scheme Curl_scheme_pop3s; -extern const struct Curl_scheme Curl_scheme_rtsp; -extern const struct Curl_scheme Curl_scheme_scp; -extern const struct Curl_scheme Curl_scheme_sftp; -extern const struct Curl_scheme Curl_scheme_smb; -extern const struct Curl_scheme Curl_scheme_smbs; -extern const struct Curl_scheme Curl_scheme_smtp; -extern const struct Curl_scheme Curl_scheme_smtps; -extern const struct Curl_scheme Curl_scheme_telnet; -extern const struct Curl_scheme Curl_scheme_tftp; -extern const struct Curl_scheme Curl_scheme_ws; -extern const struct Curl_scheme Curl_scheme_wss; - -#endif /* HEADER_CURL_PROTOCOL_H */ diff --git a/vendor/curl/lib/psl.c b/vendor/curl/lib/psl.c deleted file mode 100644 index e2488aea2..000000000 --- a/vendor/curl/lib/psl.c +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_LIBPSL - -#include "psl.h" -#include "progress.h" -#include "curl_share.h" - -void Curl_psl_destroy(struct PslCache *pslcache) -{ - if(pslcache->psl) { - if(pslcache->dynamic) - psl_free((psl_ctx_t *)CURL_UNCONST(pslcache->psl)); - pslcache->psl = NULL; - pslcache->dynamic = FALSE; - } -} - -const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy) -{ - struct PslCache *pslcache = easy->psl; - const psl_ctx_t *psl; - time_t now_sec; - - if(!pslcache) - return NULL; - - Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED); - now_sec = Curl_pgrs_now(easy)->tv_sec; - if(!pslcache->psl || pslcache->expires <= now_sec) { - /* Let a chance to other threads to do the job: avoids deadlock. */ - Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); - - /* Update cache: this needs an exclusive lock. */ - Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SINGLE); - - /* Recheck in case another thread did the job. */ - if(pslcache->expires <= now_sec) { - now_sec = Curl_pgrs_now(easy)->tv_sec; - } - if(!pslcache->psl || pslcache->expires <= now_sec) { - bool dynamic = FALSE; - time_t expires = TIME_T_MAX; - -#if defined(PSL_VERSION_NUMBER) && PSL_VERSION_NUMBER >= 0x001000 - psl = psl_latest(NULL); - dynamic = psl != NULL; - /* Take care of possible time computation overflow. */ - expires = (now_sec < TIME_T_MAX - PSL_TTL) ? - (now_sec + PSL_TTL) : TIME_T_MAX; - - /* Only get the built-in PSL if we do not already have the "latest". */ - if(!psl && !pslcache->dynamic) -#endif - - psl = psl_builtin(); - - if(psl) { - Curl_psl_destroy(pslcache); - pslcache->psl = psl; - pslcache->dynamic = dynamic; - pslcache->expires = expires; - } - } - Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); /* Release exclusive lock. */ - Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED); - } - psl = pslcache->psl; - if(!psl) - Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); - return psl; -} - -void Curl_psl_release(struct Curl_easy *easy) -{ - Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); -} - -#endif /* USE_LIBPSL */ diff --git a/vendor/curl/lib/psl.h b/vendor/curl/lib/psl.h deleted file mode 100644 index 97871f963..000000000 --- a/vendor/curl/lib/psl.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef HEADER_PSL_H -#define HEADER_PSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifdef USE_LIBPSL - -#include - -struct Curl_easy; - -#define PSL_TTL (72 * 3600) /* PSL time to live before a refresh. */ - -struct PslCache { - const psl_ctx_t *psl; /* The PSL. */ - time_t expires; /* Time this PSL life expires. */ - BIT(dynamic); /* PSL should be released when no longer needed. */ -}; - -const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy); -void Curl_psl_release(struct Curl_easy *easy); -void Curl_psl_destroy(struct PslCache *pslcache); - -#else - -#define Curl_psl_use(easy) NULL -#define Curl_psl_release(easy) -#define Curl_psl_destroy(pslcache) - -#endif /* USE_LIBPSL */ -#endif /* HEADER_PSL_H */ diff --git a/vendor/curl/lib/rand.c b/vendor/curl/lib/rand.c deleted file mode 100644 index dd82750ba..000000000 --- a/vendor/curl/lib/rand.c +++ /dev/null @@ -1,246 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "urldata.h" -#include "vtls/vtls.h" -#include "curl_trc.h" -#include "rand.h" -#include "escape.h" - -#ifdef _WIN32 -#include -#ifndef STATUS_SUCCESS -#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) -#endif - -CURLcode Curl_win32_random(unsigned char *entropy, size_t length) -{ - memset(entropy, 0, length); - - if(BCryptGenRandom(NULL, entropy, (ULONG)length, - BCRYPT_USE_SYSTEM_PREFERRED_RNG) != STATUS_SUCCESS) - return CURLE_FAILED_INIT; - - return CURLE_OK; -} -#endif - -#ifndef USE_SSL -/* ---- possibly non-cryptographic version following ---- */ -static CURLcode weak_random(struct Curl_easy *data, - unsigned char *entropy, - size_t length) /* always 4, size of int */ -{ - unsigned int r; - DEBUGASSERT(length == sizeof(int)); - - /* Trying cryptographically secure functions first */ -#ifdef _WIN32 - (void)data; - { - CURLcode result = Curl_win32_random(entropy, length); - if(result != CURLE_NOT_BUILT_IN) - return result; - } -#endif - -#ifdef HAVE_ARC4RANDOM - (void)data; - r = (unsigned int)arc4random(); - memcpy(entropy, &r, length); -#else - infof(data, "WARNING: using weak random seed"); - { - static unsigned int randseed; - static bool seeded = FALSE; - unsigned int rnd; - if(!seeded) { - struct curltime now; - curlx_pnow(&now); - randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec; - randseed = randseed * 1103515245 + 12345; - randseed = randseed * 1103515245 + 12345; - randseed = randseed * 1103515245 + 12345; - seeded = TRUE; - } - - /* Return an unsigned 32-bit pseudo-random number. */ - r = randseed = randseed * 1103515245 + 12345; - rnd = (r << 16) | ((r >> 16) & 0xFFFF); - memcpy(entropy, &rnd, length); - } -#endif - return CURLE_OK; -} -#endif - -static CURLcode randit(struct Curl_easy *data, unsigned int *rnd, - bool env_override) -{ -#ifdef DEBUGBUILD - if(env_override) { - char *force_entropy = getenv("CURL_ENTROPY"); - if(force_entropy) { - static unsigned int randseed; - static bool seeded = FALSE; - - if(!seeded) { - unsigned int seed = 0; - size_t elen = strlen(force_entropy); - size_t clen = sizeof(seed); - size_t min = elen < clen ? elen : clen; - memcpy((char *)&seed, force_entropy, min); - randseed = ntohl(seed); - seeded = TRUE; - } - else - randseed++; - *rnd = randseed; - return CURLE_OK; - } - } -#else - (void)env_override; -#endif - - /* data may be NULL! */ -#ifdef USE_SSL - return Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd)); -#else - return weak_random(data, (unsigned char *)rnd, sizeof(*rnd)); -#endif -} - -/* - * Curl_rand() stores 'num' number of random unsigned characters in the buffer - * 'rnd' points to. - * - * If libcurl is built without TLS support or arc4random, this function will - * use "weak" random. - * - * When built *with* TLS support, it will return error if it cannot provide - * strong random values. - * - * NOTE: 'data' may be passed in as NULL when coming from external API without - * easy handle! - * - */ - -CURLcode Curl_rand_bytes(struct Curl_easy *data, -#ifdef DEBUGBUILD - bool env_override, -#endif - unsigned char *rnd, size_t num) -{ - CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; -#ifndef DEBUGBUILD - const bool env_override = FALSE; -#endif - - DEBUGASSERT(num); - - while(num) { - unsigned int r; - size_t left = num < sizeof(unsigned int) ? num : sizeof(unsigned int); - - result = randit(data, &r, env_override); - if(result) - return result; - - while(left) { - *rnd++ = (unsigned char)(r & 0xFF); - r >>= 8; - --num; - --left; - } - } - - return result; -} - -/* - * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random - * hexadecimal digits PLUS a null-terminating byte. It must be an odd number - * size. - */ - -CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, size_t num) -{ - CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; - unsigned char buffer[128]; - DEBUGASSERT(num > 1); - - if((num / 2 >= sizeof(buffer)) || !(num & 1)) { - /* make sure it fits in the local buffer and that it is an odd number! */ - DEBUGF(infof(data, "invalid buffer size with Curl_rand_hex")); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - num--; /* save one for null-termination */ - - result = Curl_rand(data, buffer, num / 2); - if(result) - return result; - - Curl_hexencode(buffer, num / 2, rnd, num + 1); - return result; -} - -/* - * Curl_rand_alnum() fills the 'rnd' buffer with a given 'num' size with random - * alphanumerical chars PLUS a null-terminating byte. - */ - -static const char alnum[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -CURLcode Curl_rand_alnum(struct Curl_easy *data, unsigned char *rnd, - size_t num) -{ - CURLcode result = CURLE_OK; - const unsigned int alnumspace = sizeof(alnum) - 1; - unsigned int r; - DEBUGASSERT(num > 1); - - num--; /* save one for null-termination */ - - while(num) { - do { - result = randit(data, &r, TRUE); - if(result) - return result; - } while(r >= (UINT_MAX - UINT_MAX % alnumspace)); - - *rnd++ = (unsigned char)alnum[r % alnumspace]; - num--; - } - *rnd = 0; - - return result; -} diff --git a/vendor/curl/lib/rand.h b/vendor/curl/lib/rand.h deleted file mode 100644 index afccd0aac..000000000 --- a/vendor/curl/lib/rand.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef HEADER_CURL_RAND_H -#define HEADER_CURL_RAND_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -CURLcode Curl_rand_bytes(struct Curl_easy *data, -#ifdef DEBUGBUILD - bool env_override, -#endif - unsigned char *rnd, size_t num); - -#ifdef DEBUGBUILD -#define Curl_rand(a, b, c) Curl_rand_bytes(a, TRUE, b, c) -#else -#define Curl_rand(a, b, c) Curl_rand_bytes(a, b, c) -#endif - -/* - * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random - * hexadecimal digits PLUS a null-terminating byte. It must be an odd number - * size. - */ -CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, size_t num); - -/* - * Curl_rand_alnum() fills the 'rnd' buffer with a given 'num' size with random - * alphanumerical chars PLUS a null-terminating byte. - */ -CURLcode Curl_rand_alnum(struct Curl_easy *data, unsigned char *rnd, - size_t num); - -#ifdef _WIN32 -/* Random generator shared between the Schannel vtls and Curl_rand*() - functions */ -CURLcode Curl_win32_random(unsigned char *entropy, size_t length); -#endif - -#endif /* HEADER_CURL_RAND_H */ diff --git a/vendor/curl/lib/ratelimit.c b/vendor/curl/lib/ratelimit.c deleted file mode 100644 index dc013757e..000000000 --- a/vendor/curl/lib/ratelimit.c +++ /dev/null @@ -1,293 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "ratelimit.h" - -#define CURL_US_PER_SEC 1000000 -#define CURL_RLIMIT_MIN_RATE (4 * 1024) /* minimum step rate */ -#define CURL_RLIMIT_STEP_MIN_MS 2 /* minimum step duration */ - -static void rlimit_update(struct Curl_rlimit *r, - const struct curltime *pts) -{ - timediff_t elapsed_us, elapsed_steps; - int64_t token_gain; - - DEBUGASSERT(r->rate_per_step); - if((r->ts.tv_sec == pts->tv_sec) && (r->ts.tv_usec == pts->tv_usec)) - return; - - elapsed_us = curlx_ptimediff_us(pts, &r->ts); - if(elapsed_us < 0) { /* not going back in time */ - DEBUGASSERT(0); - return; - } - - elapsed_us += r->spare_us; - if(elapsed_us < r->step_us) - return; - - /* we do the update */ - r->ts = *pts; - elapsed_steps = elapsed_us / r->step_us; - r->spare_us = elapsed_us % r->step_us; - - /* How many tokens did we gain since the last update? */ - if(r->rate_per_step > (INT64_MAX / elapsed_steps)) - token_gain = INT64_MAX; - else { - token_gain = r->rate_per_step * elapsed_steps; - } - - if((INT64_MAX - token_gain) > r->tokens) - r->tokens += token_gain; - else - r->tokens = INT64_MAX; - - /* Limit the token again by the burst rate (if set), so we - * do not suddenly have a huge number of tokens after inactivity. */ - if(r->burst_per_step && (r->tokens > r->burst_per_step)) { - r->tokens = r->burst_per_step; - } -} - -static void rlimit_tune_steps(struct Curl_rlimit *r, - int64_t tokens_total) -{ - int64_t tokens_last, tokens_main, msteps; - - /* Tune the ratelimit at the start *if* we know how many tokens - * are expected to be consumed in total. - * The reason for tuning is that rlimit provides tokens to be consumed - * per "step" which starts out to be a second. The tokens may be consumed - * in full at the beginning of a step. The remainder of the second will - * have no tokens available, effectively blocking the consumption and - * so keeping the "step average" in line. - * This works will up to the last step. When no more tokens are needed, - * no wait will happen and the last step would be too fast. This is - * especially noticeable when only a few steps are needed. - * - * Example: downloading 1.5kb with a ratelimit of 1k could be done in - * roughly 1 second (1k in the first second and the 0.5 at the start of - * the second one). - * - * The tuning tries to make the last step small, using only - * 1 percent of the total tokens (at least 1). The rest of the tokens - * are to be consumed in the steps before by adjusting the duration of - * the step and the amount of tokens it provides. */ - if(!r->rate_per_step || - (tokens_total <= 1) || - (tokens_total > (INT64_MAX / 1000))) - return; - - /* Calculate tokens for the last step and the ones before. */ - tokens_last = tokens_total / 100; - if(!tokens_last) /* less than 100 total, use 1 */ - tokens_last = 1; - else if(tokens_last > CURL_RLIMIT_MIN_RATE) - tokens_last = CURL_RLIMIT_MIN_RATE; - DEBUGASSERT(tokens_last); - tokens_main = tokens_total - tokens_last; - DEBUGASSERT(tokens_main); - - /* how many milli-steps will it take to consume those, give the - * original rate limit per second? */ - DEBUGASSERT(r->step_us == CURL_US_PER_SEC); - - msteps = (tokens_main * 1000 / r->rate_per_step); - if(msteps < CURL_RLIMIT_STEP_MIN_MS) { - /* Steps this small will not work. Do not tune. */ - return; - } - else if(msteps < 1000) { - /* It needs less than one step to provide the needed tokens. - * Make it exactly that long and with exactly those tokens. */ - r->step_us = (timediff_t)msteps * 1000; - r->rate_per_step = tokens_main; - r->tokens = r->rate_per_step; - } - else { - /* More than 1 step. Spread the remainder milli steps and - * the tokens they need to provide across all steps. If integer - * arithmetic can do it. */ - curl_off_t ms_unaccounted = (msteps % 1000); - curl_off_t mstep_inc = (ms_unaccounted / (msteps / 1000)); - if(mstep_inc) { - curl_off_t rate_inc = ((r->rate_per_step * mstep_inc) / 1000); - if(rate_inc) { - r->step_us = CURL_US_PER_SEC + ((timediff_t)mstep_inc * 1000); - r->rate_per_step += rate_inc; - r->tokens = r->rate_per_step; - } - } - } - - if(r->burst_per_step) - r->burst_per_step = r->rate_per_step; -} - -void Curl_rlimit_init(struct Curl_rlimit *r, - int64_t rate_per_sec, - int64_t burst_per_sec, - const struct curltime *pts) -{ - DEBUGASSERT(rate_per_sec >= 0); - DEBUGASSERT(burst_per_sec >= rate_per_sec || !burst_per_sec); - DEBUGASSERT(pts); - r->rate_per_step = r->rate_per_sec = rate_per_sec; - r->burst_per_step = r->burst_per_sec = burst_per_sec; - r->step_us = CURL_US_PER_SEC; - r->spare_us = 0; - r->tokens = r->rate_per_step; - r->ts = *pts; - r->blocked = FALSE; -} - -void Curl_rlimit_start(struct Curl_rlimit *r, const struct curltime *pts, - int64_t total_tokens) -{ - /* A start always resets the values to initial defaults, then - * fine tunes the intervals for the total_tokens expected. */ - r->rate_per_step = r->rate_per_sec; - r->burst_per_step = r->burst_per_sec; - r->step_us = CURL_US_PER_SEC; - r->spare_us = 0; - r->tokens = r->rate_per_step; - r->ts = *pts; - rlimit_tune_steps(r, total_tokens); -} - -int64_t Curl_rlimit_per_step(struct Curl_rlimit *r) -{ - return r->rate_per_step; -} - -bool Curl_rlimit_active(struct Curl_rlimit *r) -{ - return (r->rate_per_step > 0) || r->blocked; -} - -bool Curl_rlimit_is_blocked(struct Curl_rlimit *r) -{ - return (bool)r->blocked; -} - -int64_t Curl_rlimit_avail(struct Curl_rlimit *r, - const struct curltime *pts) -{ - if(r->blocked) - return 0; - else if(r->rate_per_step) { - rlimit_update(r, pts); - return r->tokens; - } - else - return INT64_MAX; -} - -void Curl_rlimit_drain(struct Curl_rlimit *r, - size_t tokens, - const struct curltime *pts) -{ - if(r->blocked || !r->rate_per_step) - return; - - rlimit_update(r, pts); -#if 8 <= SIZEOF_SIZE_T - if(tokens > INT64_MAX) { - r->tokens = INT64_MAX; - } - else -#endif - { - int64_t val = (int64_t)tokens; - if((INT64_MIN + val) < r->tokens) - r->tokens -= val; - else - r->tokens = INT64_MIN; - } -} - -timediff_t Curl_rlimit_wait_ms(struct Curl_rlimit *r, - const struct curltime *pts) -{ - timediff_t wait_us, elapsed_us; - - if(r->blocked || !r->rate_per_step) - return 0; - rlimit_update(r, pts); - if(r->tokens > 0) - return 0; - - /* How much time will it take tokens to become positive again? - * Deduct `spare_us` and check against already elapsed time */ - wait_us = r->step_us - r->spare_us; - if(r->tokens < 0) { - curl_off_t debt_pct = ((-r->tokens) * 100 / r->rate_per_step); - if(debt_pct) - wait_us += (r->step_us * debt_pct / 100); - } - - elapsed_us = curlx_ptimediff_us(pts, &r->ts); - if(elapsed_us >= wait_us) - return 0; - wait_us -= elapsed_us; - return (wait_us + 999) / 1000; /* in milliseconds */ -} - -timediff_t Curl_rlimit_next_step_ms(struct Curl_rlimit *r, - const struct curltime *pts) -{ - if(!r->blocked && r->rate_per_step) { - timediff_t elapsed_us, next_us; - - elapsed_us = curlx_ptimediff_us(pts, &r->ts) + r->spare_us; - if(r->step_us > elapsed_us) { - next_us = r->step_us - elapsed_us; - return (next_us + 999) / 1000; /* in milliseconds */ - } - } - return 0; -} - -void Curl_rlimit_block(struct Curl_rlimit *r, - bool activate, - const struct curltime *pts) -{ - if(!activate == !r->blocked) - return; - - r->ts = *pts; - r->blocked = activate; - if(!r->blocked) { - /* Start rate limiting fresh. The amount of time this was blocked - * does not generate extra tokens. */ - Curl_rlimit_start(r, pts, -1); - } - else { - r->tokens = 0; - } -} diff --git a/vendor/curl/lib/ratelimit.h b/vendor/curl/lib/ratelimit.h deleted file mode 100644 index 3c3e38b89..000000000 --- a/vendor/curl/lib/ratelimit.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef HEADER_CURL_RLIMIT_H -#define HEADER_CURL_RLIMIT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curlx/timeval.h" - -struct Curl_easy; - -/* This is a rate limiter that provides "tokens" to be consumed - * per second. In the literature, this is referred to as a - * "token bucket" (https://en.wikipedia.org/wiki/Token_bucket). - * Example: - * A rate limit of 1 megabyte per second. - * - initially 1 million tokens are available. - * - these are drained in the first second. - * - checking available tokens before the 2nd second will return 0. - * - at/after the 2nd second, 1 million tokens are available again. - * - nothing happens for a second, the 1 million tokens would grow - * to 2 million, however the burst limit caps those at 1.5 million. - * Thus: - * - setting "burst" to CURL_OFF_T_MAX would average tokens over the - * complete lifetime. E.g. for a download, at the *end* of it, the - * average rate from start to finish would be the rate limit. - * - setting "burst" to the same value as "rate" would make a - * download always try to stay *at/below* the rate and slow times will - * not generate extra tokens. - * - * A rate limit can be blocked, causing the available tokens to become - * always 0 until unblocked. After unblocking, the rate limiting starts - * again with no history of the past. - * - * Finally, a rate limiter with rate 0 will always have CURL_OFF_T_MAX - * tokens available, unless blocked. - */ - -struct Curl_rlimit { - int64_t rate_per_sec; /* rate tokens generated per second */ - int64_t burst_per_sec; /* burst rate of tokens per second */ - int64_t rate_per_step; /* rate tokens generated per step us */ - int64_t burst_per_step; /* burst rate of tokens per step us */ - timediff_t step_us; /* microseconds between token increases */ - int64_t tokens; /* tokens available in the next second */ - timediff_t spare_us; /* microseconds unaffecting tokens */ - struct curltime ts; /* time of the last update */ - BIT(blocked); /* blocking sets available tokens to 0 */ -}; - -void Curl_rlimit_init(struct Curl_rlimit *r, - int64_t rate_per_sec, - int64_t burst_per_sec, - const struct curltime *pts); - -/* Start ratelimiting with the given timestamp. Resets available tokens. - * `total_tokens` is either -1 or the number of total tokens expected - * to be consumed. */ -void Curl_rlimit_start(struct Curl_rlimit *r, const struct curltime *pts, - int64_t total_tokens); - -/* How many milliseconds to wait until token are available again. */ -timediff_t Curl_rlimit_wait_ms(struct Curl_rlimit *r, - const struct curltime *pts); - -/* When the rate limit will update its tokens again */ -timediff_t Curl_rlimit_next_step_ms(struct Curl_rlimit *r, - const struct curltime *pts); - -/* Return if rate limiting of tokens is active */ -bool Curl_rlimit_active(struct Curl_rlimit *r); -bool Curl_rlimit_is_blocked(struct Curl_rlimit *r); -int64_t Curl_rlimit_per_step(struct Curl_rlimit *r); - -/* Return how many tokens are available to spend, may be negative */ -int64_t Curl_rlimit_avail(struct Curl_rlimit *r, - const struct curltime *pts); - -/* Drain tokens from the ratelimit, give an estimate of how many tokens - * remain to be drained in the future (-1 for unknown). */ -void Curl_rlimit_drain(struct Curl_rlimit *r, - size_t tokens, - const struct curltime *pts); - -/* Block/unblock ratelimiting. A blocked ratelimit has 0 tokens available. */ -void Curl_rlimit_block(struct Curl_rlimit *r, - bool activate, - const struct curltime *pts); - -#endif /* HEADER_CURL_RLIMIT_H */ diff --git a/vendor/curl/lib/request.c b/vendor/curl/lib/request.c deleted file mode 100644 index c414383dc..000000000 --- a/vendor/curl/lib/request.c +++ /dev/null @@ -1,502 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "cfilters.h" -#include "curlx/dynbuf.h" -#include "doh.h" -#include "progress.h" -#include "request.h" -#include "sendf.h" -#include "curl_trc.h" -#include "transfer.h" -#include "url.h" -#include "curlx/strparse.h" - -void Curl_req_init(struct SingleRequest *req) -{ - memset(req, 0, sizeof(*req)); -} - -CURLcode Curl_req_soft_reset(struct SingleRequest *req, - struct Curl_easy *data) -{ - CURLcode result; - - req->done = FALSE; - req->upload_done = FALSE; - req->upload_aborted = FALSE; - req->download_done = FALSE; - req->eos_written = FALSE; - req->eos_read = FALSE; - req->eos_sent = FALSE; - req->ignorebody = FALSE; - req->shutdown = FALSE; - req->bytecount = 0; - req->writebytecount = 0; - req->header = FALSE; - req->headerline = 0; - req->headerbytecount = 0; - req->allheadercount = 0; - req->deductheadercount = 0; - req->httpversion_sent = 0; - req->httpversion = 0; - req->sendbuf_hds_len = 0; - - curlx_safefree(req->userpwd); -#ifndef CURL_DISABLE_PROXY - curlx_safefree(req->proxyuserpwd); -#endif - - result = Curl_client_start(data); - if(result) - return result; - - if(!req->sendbuf_init) { - Curl_bufq_init2(&req->sendbuf, data->set.upload_buffer_size, 1, - BUFQ_OPT_SOFT_LIMIT); - req->sendbuf_init = TRUE; - } - else { - Curl_bufq_reset(&req->sendbuf); - if(data->set.upload_buffer_size != req->sendbuf.chunk_size) { - Curl_bufq_free(&req->sendbuf); - Curl_bufq_init2(&req->sendbuf, data->set.upload_buffer_size, 1, - BUFQ_OPT_SOFT_LIMIT); - } - } - - return CURLE_OK; -} - -CURLcode Curl_req_start(struct SingleRequest *req, - struct Curl_easy *data) -{ - req->start = *Curl_pgrs_now(data); - return Curl_req_soft_reset(req, data); -} - -static CURLcode req_flush(struct Curl_easy *data); - -CURLcode Curl_req_done(struct SingleRequest *req, - struct Curl_easy *data, bool aborted) -{ - (void)req; - if(!aborted) - (void)req_flush(data); - Curl_client_reset(data); - return CURLE_OK; -} - -void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) -{ - struct curltime t0 = { 0, 0 }; - - curlx_safefree(req->newurl); - curlx_safefree(req->userpwd); -#ifndef CURL_DISABLE_PROXY - curlx_safefree(req->proxyuserpwd); -#endif -#ifndef CURL_DISABLE_COOKIES - curlx_safefree(req->cookiehost); -#endif - Curl_client_reset(data); - if(req->sendbuf_init) - Curl_bufq_reset(&req->sendbuf); - - /* clear any resolve data */ - Curl_resolv_destroy_all(data); - /* Can no longer memset() this struct as we need to keep some state */ - req->size = -1; - req->maxdownload = -1; - req->bytecount = 0; - req->writebytecount = 0; - req->start = t0; - req->headerbytecount = 0; - req->allheadercount = 0; - req->deductheadercount = 0; - req->headerline = 0; - req->offset = 0; - req->httpcode = 0; - req->io_flags = 0; - req->upgr101 = UPGR101_NONE; - req->sendbuf_hds_len = 0; - req->timeofdoc = 0; - req->location = NULL; - req->newurl = NULL; -#ifndef CURL_DISABLE_COOKIES - req->setcookies = 0; -#endif - req->header = FALSE; - req->content_range = FALSE; - req->download_done = FALSE; - req->eos_written = FALSE; - req->eos_read = FALSE; - req->eos_sent = FALSE; - req->rewind_read = FALSE; - req->upload_done = FALSE; - req->upload_aborted = FALSE; - req->ignorebody = FALSE; - req->http_bodyless = FALSE; - req->chunk = FALSE; - req->resp_trailer = FALSE; - req->ignore_cl = FALSE; - req->upload_chunky = FALSE; - req->no_body = data->set.opt_no_body; - req->authneg = FALSE; - req->shutdown = FALSE; - /* Unpause all directions */ - Curl_rlimit_block(&data->progress.dl.rlimit, FALSE, &t0); - Curl_rlimit_block(&data->progress.ul.rlimit, FALSE, &t0); -} - -void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data) -{ - curlx_safefree(req->newurl); - curlx_safefree(req->userpwd); -#ifndef CURL_DISABLE_PROXY - curlx_safefree(req->proxyuserpwd); -#endif - if(req->sendbuf_init) - Curl_bufq_free(&req->sendbuf); - Curl_client_cleanup(data); -} - -static CURLcode xfer_send(struct Curl_easy *data, - const char *buf, size_t blen, - size_t hds_len, size_t *pnwritten) -{ - CURLcode result = CURLE_OK; - bool eos = FALSE; - - *pnwritten = 0; - DEBUGASSERT(hds_len <= blen); -#ifdef DEBUGBUILD - { - /* Allow debug builds to override this logic to force short initial - sends */ - size_t body_len = blen - hds_len; - if(body_len) { - const char *p = getenv("CURL_SMALLREQSEND"); - if(p) { - curl_off_t body_small; - if(!curlx_str_number(&p, &body_small, body_len)) - blen = hds_len + (size_t)body_small; - } - } - } -#endif - /* Make sure this does not send more body bytes than what the max send - speed says. The headers do not count to the max speed. */ - if(data->set.max_send_speed) { - size_t body_bytes = blen - hds_len; - if((curl_off_t)body_bytes > data->set.max_send_speed) - blen = hds_len + (size_t)data->set.max_send_speed; - } - - if(data->req.eos_read && - (Curl_bufq_is_empty(&data->req.sendbuf) || - Curl_bufq_len(&data->req.sendbuf) == blen)) { - DEBUGF(infof(data, "sending last upload chunk of %zu bytes", blen)); - eos = TRUE; - } - result = Curl_xfer_send(data, buf, blen, eos, pnwritten); - if(!result) { - if(eos && (blen == *pnwritten)) - data->req.eos_sent = TRUE; - if(*pnwritten) { - if(hds_len) - Curl_debug(data, CURLINFO_HEADER_OUT, buf, - CURLMIN(hds_len, *pnwritten)); - if(*pnwritten > hds_len) { - size_t body_len = *pnwritten - hds_len; - Curl_debug(data, CURLINFO_DATA_OUT, buf + hds_len, body_len); - data->req.writebytecount += body_len; - Curl_pgrs_upload_inc(data, body_len); - } - } - } - return result; -} - -static CURLcode req_send_buffer_flush(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - const unsigned char *buf; - size_t blen; - - while(Curl_bufq_peek(&data->req.sendbuf, &buf, &blen)) { - size_t nwritten, hds_len = CURLMIN(data->req.sendbuf_hds_len, blen); - result = xfer_send(data, (const char *)buf, blen, hds_len, &nwritten); - if(result) - break; - - Curl_bufq_skip(&data->req.sendbuf, nwritten); - if(hds_len) { - data->req.sendbuf_hds_len -= CURLMIN(hds_len, nwritten); - } - /* leave if we could not send all. Maybe network blocking or - * speed limits on transfer */ - if(nwritten < blen) - break; - } - return result; -} - -static CURLcode req_set_upload_done(struct Curl_easy *data) -{ - DEBUGASSERT(!data->req.upload_done); - data->req.upload_done = TRUE; - CURL_REQ_CLEAR_SEND(data); - - Curl_pgrsTime(data, TIMER_POSTRANSFER); - Curl_creader_done(data, data->req.upload_aborted); - - if(data->req.upload_aborted) { - Curl_bufq_reset(&data->req.sendbuf); - if(data->req.writebytecount) - infof(data, "abort upload after having sent %" FMT_OFF_T " bytes", - data->req.writebytecount); - else - infof(data, "abort upload"); - } - else if(data->req.writebytecount) - infof(data, "upload completely sent off: %" FMT_OFF_T " bytes", - data->req.writebytecount); - else if(!data->req.download_done) { - DEBUGASSERT(Curl_bufq_is_empty(&data->req.sendbuf)); - infof(data, Curl_creader_total_length(data) ? - "We are completely uploaded and fine" : - "Request completely sent off"); - } - - return Curl_xfer_send_close(data); -} - -static CURLcode req_flush(struct Curl_easy *data) -{ - CURLcode result; - - if(!data || !data->conn) - return CURLE_FAILED_INIT; - - if(!Curl_bufq_is_empty(&data->req.sendbuf)) { - result = req_send_buffer_flush(data); - if(result) - return result; - if(!Curl_bufq_is_empty(&data->req.sendbuf)) { - DEBUGF(infof(data, "Curl_req_flush(len=%zu) -> EAGAIN", - Curl_bufq_len(&data->req.sendbuf))); - return CURLE_AGAIN; - } - } - else if(Curl_xfer_needs_flush(data)) { - DEBUGF(infof(data, "Curl_req_flush(), xfer send_pending")); - return Curl_xfer_flush(data); - } - - if(data->req.eos_read && !data->req.eos_sent) { - char tmp = 0; - size_t nwritten; - result = xfer_send(data, &tmp, 0, 0, &nwritten); - if(result) - return result; - DEBUGASSERT(data->req.eos_sent); - } - - if(!data->req.upload_done && data->req.eos_read && data->req.eos_sent) { - DEBUGASSERT(Curl_bufq_is_empty(&data->req.sendbuf)); - if(data->req.shutdown) { - bool done; - result = Curl_xfer_send_shutdown(data, &done); - if(result && data->req.shutdown_err_ignore) { - infof(data, "Shutdown send direction error: %d. Broken server? " - "Proceeding as if everything is ok.", result); - result = CURLE_OK; - done = TRUE; - } - - if(result) - return result; - if(!done) - return CURLE_AGAIN; - } - return req_set_upload_done(data); - } - return CURLE_OK; -} - -static CURLcode add_from_client(void *reader_ctx, - unsigned char *buf, size_t buflen, - size_t *pnread) -{ - struct Curl_easy *data = reader_ctx; - CURLcode result; - bool eos; - - result = Curl_client_read(data, (char *)buf, buflen, pnread, &eos); - if(!result && eos) - data->req.eos_read = TRUE; - return result; -} - -static CURLcode req_send_buffer_add(struct Curl_easy *data, - const char *buf, size_t blen, - size_t hds_len) -{ - CURLcode result = CURLE_OK; - size_t n; - result = Curl_bufq_cwrite(&data->req.sendbuf, buf, blen, &n); - if(result) - return result; - /* We rely on a SOFTLIMIT on sendbuf, so it can take all data in */ - DEBUGASSERT(n == blen); - data->req.sendbuf_hds_len += hds_len; - return CURLE_OK; -} - -CURLcode Curl_req_send(struct Curl_easy *data, struct dynbuf *req, - unsigned char httpversion) -{ - CURLcode result; - const char *buf; - size_t blen, nwritten; - - if(!data || !data->conn) - return CURLE_FAILED_INIT; - - data->req.httpversion_sent = httpversion; - buf = curlx_dyn_ptr(req); - blen = curlx_dyn_len(req); - /* if the sendbuf is empty and the request without body and - * the length to send fits info a sendbuf chunk, we send it directly. - * If `blen` is larger then `chunk_size`, we can not. Because we - * might have to retry a blocked send later from sendbuf and that - * would result in retry sends with a shrunken length. That is trouble. */ - if(Curl_bufq_is_empty(&data->req.sendbuf) && - !Curl_creader_total_length(data) && - (blen <= data->req.sendbuf.chunk_size)) { - data->req.eos_read = TRUE; - result = xfer_send(data, buf, blen, blen, &nwritten); - if(result) - return result; - buf += nwritten; - blen -= nwritten; - if(!blen) { - result = req_set_upload_done(data); - if(result) - return result; - } - } - - if(blen) { - /* Either we have a request body, or we could not send the complete - * request in one go. Buffer the remainder and try to add as much - * body bytes as room is left in the buffer. Then flush. */ - result = req_send_buffer_add(data, buf, blen, blen); - if(result) - return result; - - return Curl_req_send_more(data); - } - return CURLE_OK; -} - -bool Curl_req_sendbuf_empty(struct Curl_easy *data) -{ - return !data->req.sendbuf_init || Curl_bufq_is_empty(&data->req.sendbuf); -} - -bool Curl_req_want_send(struct Curl_easy *data) -{ - /* Not done and upload not blocked and either one of - * - REQ_IO_SEND - * - request has buffered data to send - * - connection has pending data to send */ - return !data->req.done && - !Curl_rlimit_is_blocked(&data->progress.ul.rlimit) && - (CURL_REQ_WANT_SEND(data) || - !Curl_req_sendbuf_empty(data) || - Curl_xfer_needs_flush(data)); -} - -bool Curl_req_want_recv(struct Curl_easy *data) -{ - /* Not done and download not blocked and want RECV */ - return !data->req.done && - !Curl_rlimit_is_blocked(&data->progress.dl.rlimit) && - CURL_REQ_WANT_RECV(data); -} - -bool Curl_req_done_sending(struct Curl_easy *data) -{ - return data->req.upload_done && !Curl_req_want_send(data); -} - -CURLcode Curl_req_send_more(struct Curl_easy *data) -{ - CURLcode result; - - /* Fill our send buffer if more from client can be read. */ - if(!data->req.upload_aborted && - !data->req.eos_read && - !Curl_xfer_send_is_paused(data) && - !Curl_bufq_is_full(&data->req.sendbuf)) { - size_t nread; - result = Curl_bufq_sipn(&data->req.sendbuf, 0, - add_from_client, data, &nread); - if(result && result != CURLE_AGAIN) - return result; - } - - result = req_flush(data); - if(result == CURLE_AGAIN) - result = CURLE_OK; - - return result; -} - -CURLcode Curl_req_abort_sending(struct Curl_easy *data) -{ - if(!data->req.upload_done) { - Curl_bufq_reset(&data->req.sendbuf); - data->req.upload_aborted = TRUE; - CURL_REQ_CLEAR_SEND(data); - return req_set_upload_done(data); - } - return CURLE_OK; -} - -CURLcode Curl_req_stop_send_recv(struct Curl_easy *data) -{ - /* stop receiving and ALL sending as well, including PAUSE and HOLD. - * We might still be paused on receive client writes though, so - * keep those bits around. */ - CURLcode result = CURLE_OK; - if(CURL_REQ_WANT_SEND(data)) - result = Curl_req_abort_sending(data); - CURL_REQ_CLEAR_IO(data); - return result; -} diff --git a/vendor/curl/lib/request.h b/vendor/curl/lib/request.h deleted file mode 100644 index 6948d79be..000000000 --- a/vendor/curl/lib/request.h +++ /dev/null @@ -1,251 +0,0 @@ -#ifndef HEADER_CURL_REQUEST_H -#define HEADER_CURL_REQUEST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* This file is for lib internal stuff */ -#include "curl_setup.h" - -#include "bufq.h" - -/* forward declarations */ -struct UserDefined; - -/* Bits on the io_flags member of SingleRequest */ -#define REQ_IO_RECV (1 << 0) /* there is or may be data to read */ -#define REQ_IO_SEND (1 << 1) /* there is or may be data to write */ - -/* Low level request receive/send io_flags checks. */ -#define CURL_REQ_WANT_SEND(d) ((d)->req.io_flags & REQ_IO_SEND) -#define CURL_REQ_WANT_RECV(d) ((d)->req.io_flags & REQ_IO_RECV) -#define CURL_REQ_WANT_IO(d) \ - ((d)->req.io_flags & (REQ_IO_RECV | REQ_IO_SEND)) -/* Low level request receive/send io_flags manipulations. */ -#define CURL_REQ_SET_SEND(d) ((d)->req.io_flags |= REQ_IO_SEND) -#define CURL_REQ_SET_RECV(d) ((d)->req.io_flags |= REQ_IO_RECV) -#define CURL_REQ_CLEAR_SEND(d) \ - ((d)->req.io_flags &= (uint8_t)~REQ_IO_SEND) -#define CURL_REQ_CLEAR_RECV(d) \ - ((d)->req.io_flags &= (uint8_t)~REQ_IO_RECV) -#define CURL_REQ_CLEAR_IO(d) \ - ((d)->req.io_flags &= (uint8_t)~(REQ_IO_RECV | REQ_IO_SEND)) - -enum expect100 { - EXP100_SEND_DATA, /* enough waiting, send the body now */ - EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */ - EXP100_SENDING_REQUEST, /* still sending the request but will wait for - the 100 header once done with the request */ - EXP100_FAILED /* used on 417 Expectation Failed */ -}; - -enum upgrade101 { - UPGR101_NONE, /* default state */ - UPGR101_WS, /* upgrade to WebSocket requested */ - UPGR101_H2, /* upgrade to HTTP/2 requested */ - UPGR101_RECEIVED /* 101 response received */ -}; - -/* - * Request specific data in the easy handle (Curl_easy). Previously, - * these members were on the connectdata struct but since a conn struct may - * now be shared between different Curl_easys, we store connection-specific - * data here. This struct only keeps stuff that is interesting for *this* - * request, as it will be cleared between multiple ones - */ -struct SingleRequest { - curl_off_t size; /* -1 if unknown at this point */ - curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, - -1 means unlimited */ - curl_off_t bytecount; /* total number of bytes read */ - curl_off_t writebytecount; /* number of bytes written */ - curl_off_t offset; /* possible resume offset read from the - Content-Range: header */ - - struct curltime start; /* transfer started at this time */ - unsigned int headerbytecount; /* received server headers (not CONNECT - headers) */ - unsigned int allheadercount; /* all received headers (server + CONNECT) */ - unsigned int deductheadercount; /* this amount of bytes does not count when - we check if anything has been transferred - at the end of a connection. We use this - counter to make only a 100 reply (without - a following second response code) result - in a CURLE_GOT_NOTHING error code */ - int headerline; /* counts header lines to better track the - first one */ - int httpcode; /* error code from the 'HTTP/1.? XXX' or - 'RTSP/1.? XXX' line */ - unsigned char httpversion_sent; /* Version in request (09, 10, 11, etc.) */ - unsigned char httpversion; /* Version in response (09, 10, 11, etc.) */ - enum upgrade101 upgr101; /* 101 upgrade state */ - - /* Client Writer stack, handles transfer- and content-encodings, protocol - * checks, pausing by client callbacks. */ - struct Curl_cwriter *writer_stack; - /* Client Reader stack, handles transfer- and content-encodings, protocol - * checks, pausing by client callbacks. */ - struct Curl_creader *reader_stack; - struct bufq sendbuf; /* data which needs to be send to the server */ - size_t sendbuf_hds_len; /* amount of header bytes in sendbuf */ - time_t timeofdoc; - char *location; /* This points to an allocated version of the Location: - header data */ - char *newurl; /* Set to the new URL to use when a redirect or a retry is - wanted */ - uint8_t io_flags; /* REQ_IO_RECV | REQ_IO_SEND */ - - char *userpwd; /* auth header */ -#ifndef CURL_DISABLE_PROXY - char *proxyuserpwd; /* proxy auth header */ -#endif -#ifndef CURL_DISABLE_COOKIES - char *cookiehost; -#endif -#ifndef CURL_DISABLE_COOKIES - unsigned char setcookies; -#endif - BIT(header); /* incoming data has HTTP header */ - BIT(done); /* request is done, e.g. no more send/recv should - * happen. This can be TRUE before `upload_done` or - * `download_done` is TRUE. */ - BIT(content_range); /* set TRUE if Content-Range: was found */ - BIT(download_done); /* set to TRUE when download is complete */ - BIT(eos_written); /* iff EOS has been written to client */ - BIT(eos_read); /* iff EOS has been read from the client */ - BIT(eos_sent); /* iff EOS has been sent to the server */ - BIT(rewind_read); /* iff reader needs rewind at next start */ - BIT(upload_done); /* set to TRUE when all request data has been sent */ - BIT(upload_aborted); /* set to TRUE when upload was aborted. Also - * shows `upload_done` as TRUE. */ - BIT(ignorebody); /* we read a response-body but we ignore it! */ - BIT(http_bodyless); /* HTTP response status code is between 100 and 199, - 204 or 304 */ - BIT(chunk); /* if set, this is a chunked transfer-encoding */ - BIT(resp_trailer); /* response carried 'Trailer:' header field */ - BIT(ignore_cl); /* ignore content-length */ - BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding - on upload */ - BIT(no_body); /* the response has no body */ - BIT(authneg); /* TRUE when the auth phase has started, which means - that we are creating a request with an auth header, - but it is not the final request in the auth - negotiation. */ - BIT(sendbuf_init); /* sendbuf is initialized */ - BIT(shutdown); /* request end will shutdown connection */ - BIT(shutdown_err_ignore); /* errors in shutdown will not fail request */ - BIT(reader_started); /* client reads have started */ -}; - -/** - * Initialize the state of the request for first use. - */ -void Curl_req_init(struct SingleRequest *req); - -/** - * The request is about to start. Record time and do a soft reset. - */ -CURLcode Curl_req_start(struct SingleRequest *req, - struct Curl_easy *data); - -/** - * The request may continue with a follow up. Reset - * members, but keep start time for overall duration calc. - */ -CURLcode Curl_req_soft_reset(struct SingleRequest *req, - struct Curl_easy *data); - -/** - * The request is done. If not aborted, make sure that buffers are - * flushed to the client. - * @param req the request - * @param data the transfer - * @param aborted TRUE iff the request was aborted/errored - */ -CURLcode Curl_req_done(struct SingleRequest *req, - struct Curl_easy *data, bool aborted); - -/** - * Free the state of the request, not usable afterwards. - */ -void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data); - -/** - * Hard reset the state of the request to virgin state base on - * transfer settings. - */ -void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data); - -/** - * Send request headers. If not all could be sent - * they will be buffered. Use `Curl_req_flush()` to make sure - * bytes are really send. - * @param data the transfer making the request - * @param req the complete header bytes, no body - * @param httpversion version used in request (09, 10, 11, etc.) - * @return CURLE_OK (on blocking with *pnwritten == 0) or error. - */ -CURLcode Curl_req_send(struct Curl_easy *data, struct dynbuf *req, - unsigned char httpversion); - -/** - * TRUE iff the request has sent all request headers and data. - */ -bool Curl_req_done_sending(struct Curl_easy *data); - -/* - * Read more from client and flush all buffered request bytes. - * @return CURLE_OK on success or the error on the sending. - * Never returns CURLE_AGAIN. - */ -CURLcode Curl_req_send_more(struct Curl_easy *data); - -/* TRUE if the request wants to send, e.g. is not done sending - * and is not blocked. */ -bool Curl_req_want_send(struct Curl_easy *data); - -/* TRUE if the request wants to receive and is not blocked. */ -bool Curl_req_want_recv(struct Curl_easy *data); - -/** - * TRUE iff the request has no buffered bytes yet to send. - */ -bool Curl_req_sendbuf_empty(struct Curl_easy *data); - -/** - * Stop sending any more request data to the server. - * Clear the send buffer and mark request sending as done. - */ -CURLcode Curl_req_abort_sending(struct Curl_easy *data); - -/** - * Stop sending and receiving any more request data. - * Abort sending if not done. - */ -CURLcode Curl_req_stop_send_recv(struct Curl_easy *data); - -/** - * Invoked when all request data has been uploaded. - */ -CURLcode Curl_req_set_upload_done(struct Curl_easy *data); - -#endif /* HEADER_CURL_REQUEST_H */ diff --git a/vendor/curl/lib/rtsp.c b/vendor/curl/lib/rtsp.c deleted file mode 100644 index b08767f37..000000000 --- a/vendor/curl/lib/rtsp.c +++ /dev/null @@ -1,1068 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "rtsp.h" - -#ifndef CURL_DISABLE_RTSP - -#include "transfer.h" -#include "sendf.h" -#include "curl_trc.h" -#include "multiif.h" -#include "http.h" -#include "url.h" -#include "progress.h" -#include "strcase.h" -#include "select.h" -#include "connect.h" -#include "cfilters.h" -#include "curlx/strdup.h" -#include "bufref.h" -#include "curlx/strparse.h" - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_RTSP_EASY "meta:proto:rtsp:easy" -/* meta key for storing protocol meta at connection */ -#define CURL_META_RTSP_CONN "meta:proto:rtsp:conn" - -typedef enum { - RTP_PARSE_SKIP, - RTP_PARSE_CHANNEL, - RTP_PARSE_LEN, - RTP_PARSE_DATA -} rtp_parse_st; - -/* RTSP Connection data - * Currently, only used for tracking incomplete RTP data reads */ -struct rtsp_conn { - struct dynbuf buf; - int rtp_channel; - size_t rtp_len; - rtp_parse_st state; - BIT(in_header); -}; - -/* RTSP transfer data */ -struct RTSP { - uint32_t CSeq_sent; /* CSeq of this request */ - uint32_t CSeq_recv; /* CSeq received */ -}; - -#define RTP_PKT_LENGTH(p) ((((unsigned int)((unsigned char)((p)[2]))) << 8) | \ - ((unsigned int)((unsigned char)((p)[3])))) - -/* this returns the socket to wait for in the DO and DOING state for the multi - interface and then we are always _sending_ a request and thus we wait for - the single socket to become writable only */ -static CURLcode rtsp_do_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - /* write mode */ - return Curl_pollset_add_out(data, ps, data->conn->sock[FIRSTSOCKET]); -} - -#define MAX_RTP_BUFFERSIZE 1000000 /* arbitrary */ - -static void rtsp_easy_dtor(void *key, size_t klen, void *entry) -{ - struct RTSP *rtsp = entry; - (void)key; - (void)klen; - curlx_free(rtsp); -} - -static void rtsp_conn_dtor(void *key, size_t klen, void *entry) -{ - struct rtsp_conn *rtspc = entry; - (void)key; - (void)klen; - curlx_dyn_free(&rtspc->buf); - curlx_free(rtspc); -} - -static CURLcode rtsp_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct rtsp_conn *rtspc; - struct RTSP *rtsp; - - rtspc = curlx_calloc(1, sizeof(*rtspc)); - if(!rtspc) - return CURLE_OUT_OF_MEMORY; - curlx_dyn_init(&rtspc->buf, MAX_RTP_BUFFERSIZE); - if(Curl_conn_meta_set(conn, CURL_META_RTSP_CONN, rtspc, rtsp_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - rtsp = curlx_calloc(1, sizeof(struct RTSP)); - if(!rtsp || - Curl_meta_set(data, CURL_META_RTSP_EASY, rtsp, rtsp_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -/* - * Function to check on various aspects of a connection. - */ -static bool rtsp_conn_is_dead(struct Curl_easy *data, - struct connectdata *conn) -{ - bool input_pending; - /* Contrary to default handling, this protocol allows pending - * input on an unused connection. */ - return !Curl_conn_is_alive(data, conn, &input_pending); -} - -static CURLcode rtsp_connect(struct Curl_easy *data, bool *done) -{ - struct rtsp_conn *rtspc = - Curl_conn_meta_get(data->conn, CURL_META_RTSP_CONN); - - if(!rtspc) - return CURLE_FAILED_INIT; - - /* Initialize the CSeq if not already done */ - if(data->state.rtsp_next_client_CSeq == 0) - data->state.rtsp_next_client_CSeq = 1; - if(data->state.rtsp_next_server_CSeq == 0) - data->state.rtsp_next_server_CSeq = 1; - - rtspc->rtp_channel = -1; - *done = TRUE; - return CURLE_OK; -} - -static CURLcode rtsp_done(struct Curl_easy *data, - CURLcode status, bool premature) -{ - struct rtsp_conn *rtspc = - Curl_conn_meta_get(data->conn, CURL_META_RTSP_CONN); - struct RTSP *rtsp = Curl_meta_get(data, CURL_META_RTSP_EASY); - CURLcode result; - - if(!rtspc || !rtsp) - return CURLE_FAILED_INIT; - - /* Bypass HTTP empty-reply checks on receive */ - if(data->set.rtspreq == RTSPREQ_RECEIVE) - premature = TRUE; - - result = Curl_http_done(data, status, premature); - - if(!status && !result) { - /* Check the sequence numbers */ - uint32_t CSeq_sent = rtsp->CSeq_sent; - uint32_t CSeq_recv = rtsp->CSeq_recv; - if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) { - failf(data, - "The CSeq of this request %u did not match the response %u", - CSeq_sent, CSeq_recv); - return CURLE_RTSP_CSEQ_ERROR; - } - if(data->set.rtspreq == RTSPREQ_RECEIVE && (rtspc->rtp_channel == -1)) { - infof(data, "Got an RTP Receive with a CSeq of %u", CSeq_recv); - } - if(data->set.rtspreq == RTSPREQ_RECEIVE && - data->req.eos_written) { - failf(data, "Server prematurely closed the RTSP connection."); - return CURLE_RECV_ERROR; - } - } - - return result; -} - -static CURLcode rtsp_setup_body(struct Curl_easy *data, - Curl_RtspReq rtspreq, - struct dynbuf *reqp) -{ - CURLcode result; - if(rtspreq == RTSPREQ_ANNOUNCE || - rtspreq == RTSPREQ_SET_PARAMETER || - rtspreq == RTSPREQ_GET_PARAMETER) { - curl_off_t req_clen; /* request content length */ - - if(data->state.upload) { - req_clen = data->state.infilesize; - data->state.httpreq = HTTPREQ_PUT; - result = Curl_creader_set_fread(data, req_clen); - if(result) - return result; - } - else { - if(data->set.postfields) { - size_t plen = (data->set.postfieldsize >= 0) ? - (size_t)data->set.postfieldsize : strlen(data->set.postfields); - req_clen = (curl_off_t)plen; - result = Curl_creader_set_buf(data, data->set.postfields, plen); - } - else if(data->state.infilesize >= 0) { - req_clen = data->state.infilesize; - result = Curl_creader_set_fread(data, req_clen); - } - else { - req_clen = 0; - result = Curl_creader_set_null(data); - } - if(result) - return result; - } - - if(req_clen > 0) { - /* As stated in the http comments, it is probably not wise to - * actually set a custom Content-Length in the headers */ - if(!Curl_checkheaders(data, STRCONST("Content-Length"))) { - result = curlx_dyn_addf(reqp, "Content-Length: %" FMT_OFF_T "\r\n", - req_clen); - if(result) - return result; - } - - if(rtspreq == RTSPREQ_SET_PARAMETER || - rtspreq == RTSPREQ_GET_PARAMETER) { - if(!Curl_checkheaders(data, STRCONST("Content-Type"))) { - result = curlx_dyn_addn(reqp, STRCONST("Content-Type: " - "text/parameters\r\n")); - if(result) - return result; - } - } - - if(rtspreq == RTSPREQ_ANNOUNCE) { - if(!Curl_checkheaders(data, STRCONST("Content-Type"))) { - result = curlx_dyn_addn(reqp, STRCONST("Content-Type: " - "application/sdp\r\n")); - if(result) - return result; - } - } - } - else if(rtspreq == RTSPREQ_GET_PARAMETER) { - /* Check for an empty GET_PARAMETER (heartbeat) request */ - data->state.httpreq = HTTPREQ_HEAD; - data->req.no_body = TRUE; - } - } - else - result = Curl_creader_set_null(data); - return result; -} - -static CURLcode rtsp_do(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - const Curl_RtspReq rtspreq = data->set.rtspreq; - struct RTSP *rtsp = Curl_meta_get(data, CURL_META_RTSP_EASY); - struct dynbuf req_buffer; - const unsigned char httpversion = 11; /* RTSP is close to HTTP/1.1, sort - of... */ - const char *p_request = NULL; - const char *p_session_id = NULL; - const char *p_accept = NULL; - const char *p_accept_encoding = NULL; - const char *p_range = NULL; - const char *p_referrer = NULL; - const char *p_stream_uri = NULL; - const char *p_transport = NULL; - const char *p_uagent = NULL; - const char *p_proxyuserpwd = NULL; - const char *p_userpwd = NULL; - - *done = TRUE; - if(!rtsp) - return CURLE_FAILED_INIT; - - /* Initialize a dynamic send buffer */ - curlx_dyn_init(&req_buffer, DYN_RTSP_REQ_HEADER); - - rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq; - rtsp->CSeq_recv = 0; - - /* Setup the first_* fields to allow auth details get sent - to this origin */ - - if(!data->state.first_host) { - data->state.first_host = curlx_strdup(conn->host.name); - if(!data->state.first_host) - return CURLE_OUT_OF_MEMORY; - - data->state.first_remote_port = conn->remote_port; - data->state.first_remote_protocol = conn->scheme->protocol; - } - - /* Setup the 'p_request' pointer to the proper p_request string - * Since all RTSP requests are included here, there is no need to - * support custom requests like HTTP. - **/ - data->req.no_body = TRUE; /* most requests do not contain a body */ - switch(rtspreq) { - default: - failf(data, "Got invalid RTSP request"); - return CURLE_BAD_FUNCTION_ARGUMENT; - case RTSPREQ_OPTIONS: - p_request = "OPTIONS"; - break; - case RTSPREQ_DESCRIBE: - p_request = "DESCRIBE"; - data->req.no_body = FALSE; - break; - case RTSPREQ_ANNOUNCE: - p_request = "ANNOUNCE"; - break; - case RTSPREQ_SETUP: - p_request = "SETUP"; - break; - case RTSPREQ_PLAY: - p_request = "PLAY"; - break; - case RTSPREQ_PAUSE: - p_request = "PAUSE"; - break; - case RTSPREQ_TEARDOWN: - p_request = "TEARDOWN"; - break; - case RTSPREQ_GET_PARAMETER: - /* GET_PARAMETER's no_body status is determined later */ - p_request = "GET_PARAMETER"; - data->req.no_body = FALSE; - break; - case RTSPREQ_SET_PARAMETER: - p_request = "SET_PARAMETER"; - break; - case RTSPREQ_RECORD: - p_request = "RECORD"; - break; - case RTSPREQ_RECEIVE: - p_request = ""; - /* Treat interleaved RTP as body */ - data->req.no_body = FALSE; - break; - case RTSPREQ_LAST: - failf(data, "Got invalid RTSP request: RTSPREQ_LAST"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - if(rtspreq == RTSPREQ_RECEIVE) { - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); - goto out; - } - - p_session_id = data->set.str[STRING_RTSP_SESSION_ID]; - if(!p_session_id && - (rtspreq & ~(Curl_RtspReq)(RTSPREQ_OPTIONS | - RTSPREQ_DESCRIBE | - RTSPREQ_SETUP))) { - failf(data, "Refusing to issue an RTSP request [%s] without a session ID.", - p_request); - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - - /* Stream URI. Default to server '*' if not specified */ - if(data->set.str[STRING_RTSP_STREAM_URI]) { - p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI]; - } - else { - p_stream_uri = "*"; - } - - /* Transport Header for SETUP requests */ - p_transport = Curl_checkheaders(data, STRCONST("Transport")); - if(rtspreq == RTSPREQ_SETUP && !p_transport) { - /* New Transport: setting? */ - if(data->set.str[STRING_RTSP_TRANSPORT]) { - curlx_free(data->state.aptr.rtsp_transport); - data->state.aptr.rtsp_transport = - curl_maprintf("Transport: %s\r\n", - data->set.str[STRING_RTSP_TRANSPORT]); - if(!data->state.aptr.rtsp_transport) - return CURLE_OUT_OF_MEMORY; - } - else { - failf(data, - "Refusing to issue an RTSP SETUP without a Transport: header."); - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - - p_transport = data->state.aptr.rtsp_transport; - } - - /* Accept Headers for DESCRIBE requests */ - if(rtspreq == RTSPREQ_DESCRIBE) { - /* Accept Header */ - p_accept = Curl_checkheaders(data, STRCONST("Accept")) ? - NULL : "Accept: application/sdp\r\n"; - - /* Accept-Encoding header */ - if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) && - data->set.str[STRING_ENCODING]) { - curlx_free(data->state.aptr.accept_encoding); - data->state.aptr.accept_encoding = - curl_maprintf("Accept-Encoding: %s\r\n", - data->set.str[STRING_ENCODING]); - - if(!data->state.aptr.accept_encoding) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - p_accept_encoding = data->state.aptr.accept_encoding; - } - } - - /* The User-Agent string might have been allocated already, because - it might have been used in the proxy connect, but if we have got a header - with the user-agent string specified, we erase the previously made string - here. */ - if(Curl_checkheaders(data, STRCONST("User-Agent")) && - data->state.aptr.uagent) { - curlx_safefree(data->state.aptr.uagent); - } - else if(!Curl_checkheaders(data, STRCONST("User-Agent")) && - data->set.str[STRING_USERAGENT]) { - p_uagent = data->state.aptr.uagent; - } - - /* setup the authentication headers */ - result = Curl_http_output_auth(data, conn, p_request, HTTPREQ_GET, - p_stream_uri, FALSE); - if(result) - goto out; - -#ifndef CURL_DISABLE_PROXY - p_proxyuserpwd = data->req.proxyuserpwd; -#endif - p_userpwd = data->req.userpwd; - - /* Referrer */ - curlx_safefree(data->state.aptr.ref); - if(Curl_bufref_ptr(&data->state.referer) && - !Curl_checkheaders(data, STRCONST("Referer"))) - data->state.aptr.ref = - curl_maprintf("Referer: %s\r\n", Curl_bufref_ptr(&data->state.referer)); - - p_referrer = data->state.aptr.ref; - - /* - * Range Header - * Only applies to PLAY, PAUSE, RECORD - * - * Go ahead and use the Range stuff supplied for HTTP - */ - if(data->state.use_range && - (rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) { - - /* Check to see if there is a range set in the custom headers */ - if(!Curl_checkheaders(data, STRCONST("Range")) && data->state.range) { - curlx_free(data->state.aptr.rangeline); - data->state.aptr.rangeline = curl_maprintf("Range: %s\r\n", - data->state.range); - p_range = data->state.aptr.rangeline; - } - } - - /* - * Sanity check the custom headers - */ - if(Curl_checkheaders(data, STRCONST("CSeq"))) { - failf(data, "CSeq cannot be set as a custom header."); - result = CURLE_RTSP_CSEQ_ERROR; - goto out; - } - if(Curl_checkheaders(data, STRCONST("Session"))) { - failf(data, "Session ID cannot be set as a custom header."); - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - - result = - curlx_dyn_addf(&req_buffer, - "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */ - "CSeq: %u\r\n", /* CSeq */ - p_request, p_stream_uri, rtsp->CSeq_sent); - if(result) - goto out; - - /* - * Rather than do a normal alloc line, keep the session_id unformatted - * to make comparison easier - */ - if(p_session_id) { - result = curlx_dyn_addf(&req_buffer, "Session: %s\r\n", p_session_id); - if(result) - goto out; - } - - /* - * Shared HTTP-like options - */ - result = curlx_dyn_addf(&req_buffer, - "%s" /* transport */ - "%s" /* accept */ - "%s" /* accept-encoding */ - "%s" /* range */ - "%s" /* referrer */ - "%s" /* user-agent */ - "%s" /* proxyuserpwd */ - "%s" /* userpwd */ - , - p_transport ? p_transport : "", - p_accept ? p_accept : "", - p_accept_encoding ? p_accept_encoding : "", - p_range ? p_range : "", - p_referrer ? p_referrer : "", - p_uagent ? p_uagent : "", - p_proxyuserpwd ? p_proxyuserpwd : "", - p_userpwd ? p_userpwd : ""); - - if(result) - goto out; - - if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) { - result = Curl_add_timecondition(data, &req_buffer); - if(result) - goto out; - } - - result = Curl_add_custom_headers(data, FALSE, httpversion, &req_buffer); - if(result) - goto out; - - result = rtsp_setup_body(data, rtspreq, &req_buffer); - if(result) - goto out; - - /* Finish the request buffer */ - result = curlx_dyn_addn(&req_buffer, STRCONST("\r\n")); - if(result) - goto out; - - Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); - - /* issue the request */ - result = Curl_req_send(data, &req_buffer, httpversion); - if(result) { - failf(data, "Failed sending RTSP request"); - goto out; - } - - /* Increment the CSeq on success */ - data->state.rtsp_next_client_CSeq++; - - if(data->req.writebytecount) { - /* if a request-body has been sent off, we make sure this progress is - noted properly */ - Curl_pgrsSetUploadCounter(data, data->req.writebytecount); - result = Curl_pgrsUpdate(data); - } -out: - curlx_dyn_free(&req_buffer); - return result; -} - -/** - * write any BODY bytes missing to the client, ignore the rest. - */ -static CURLcode rtp_write_body_junk(struct Curl_easy *data, - struct rtsp_conn *rtspc, - const char *buf, - size_t blen) -{ - curl_off_t body_remain; - bool in_body; - - in_body = (data->req.headerline && !rtspc->in_header) && - (data->req.size >= 0) && - (data->req.bytecount < data->req.size); - body_remain = in_body ? (data->req.size - data->req.bytecount) : 0; - DEBUGASSERT(body_remain >= 0); - if(body_remain) { - if((curl_off_t)blen > body_remain) - blen = (size_t)body_remain; - return Curl_client_write(data, CLIENTWRITE_BODY, buf, blen); - } - return CURLE_OK; -} - -static CURLcode rtp_client_write(struct Curl_easy *data, const char *ptr, - size_t len) -{ - size_t wrote; - curl_write_callback writeit; - void *user_ptr; - - if(len == 0) { - failf(data, "Cannot write a 0 size RTP packet."); - return CURLE_WRITE_ERROR; - } - - /* If the user has configured CURLOPT_INTERLEAVEFUNCTION then use that - function and any configured CURLOPT_INTERLEAVEDATA to write out the RTP - data. Otherwise, use the CURLOPT_WRITEFUNCTION with the CURLOPT_WRITEDATA - pointer to write out the RTP data. */ - if(data->set.fwrite_rtp) { - writeit = data->set.fwrite_rtp; - user_ptr = data->set.rtp_out; - } - else { - writeit = data->set.fwrite_func; - user_ptr = data->set.out; - } - - Curl_set_in_callback(data, TRUE); - wrote = writeit((char *)CURL_UNCONST(ptr), 1, len, user_ptr); - Curl_set_in_callback(data, FALSE); - - if(wrote == CURL_WRITEFUNC_PAUSE) { - failf(data, "Cannot pause RTP"); - return CURLE_WRITE_ERROR; - } - - if(wrote != len) { - failf(data, "Failed writing RTP data"); - return CURLE_WRITE_ERROR; - } - - return CURLE_OK; -} - -static CURLcode rtsp_filter_rtp(struct Curl_easy *data, - struct rtsp_conn *rtspc, - const char *buf, - size_t blen, - size_t *pconsumed) -{ - CURLcode result = CURLE_OK; - size_t skip_len = 0; - - *pconsumed = 0; - while(blen) { - bool in_body = (data->req.headerline && !rtspc->in_header) && - (data->req.size >= 0) && - (data->req.bytecount < data->req.size); - switch(rtspc->state) { - - case RTP_PARSE_SKIP: { - DEBUGASSERT(curlx_dyn_len(&rtspc->buf) == 0); - while(blen && buf[0] != '$') { - if(!in_body && buf[0] == 'R' && - data->set.rtspreq != RTSPREQ_RECEIVE) { - if(strncmp(buf, "RTSP/", (blen < 5) ? blen : 5) == 0) { - /* This could be the next response, no consume and return */ - if(*pconsumed) { - DEBUGF(infof(data, "RTP rtsp_filter_rtp[SKIP] RTSP/ prefix, " - "skipping %zu bytes of junk", *pconsumed)); - } - rtspc->state = RTP_PARSE_SKIP; - rtspc->in_header = TRUE; - goto out; - } - } - /* junk/BODY, consume without buffering */ - *pconsumed += 1; - ++buf; - --blen; - ++skip_len; - } - if(blen && buf[0] == '$') { - /* possible start of an RTP message, buffer */ - if(skip_len) { - /* end of junk/BODY bytes, flush */ - result = rtp_write_body_junk(data, rtspc, buf - skip_len, skip_len); - skip_len = 0; - if(result) - goto out; - } - if(curlx_dyn_addn(&rtspc->buf, buf, 1)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - *pconsumed += 1; - ++buf; - --blen; - rtspc->state = RTP_PARSE_CHANNEL; - } - break; - } - - case RTP_PARSE_CHANNEL: { - int idx = ((unsigned char)buf[0]) / 8; - int off = ((unsigned char)buf[0]) % 8; - DEBUGASSERT(curlx_dyn_len(&rtspc->buf) == 1); - if(!(data->state.rtp_channel_mask[idx] & (1 << off))) { - /* invalid channel number, junk or BODY data */ - rtspc->state = RTP_PARSE_SKIP; - DEBUGASSERT(skip_len == 0); - /* we do not consume this byte, it is BODY data */ - DEBUGF(infof(data, "RTSP: invalid RTP channel %d, skipping", idx)); - if(*pconsumed == 0) { - /* We did not consume the initial '$' in our buffer, but had - * it from an earlier call. We cannot un-consume it and have - * to write it directly as BODY data */ - result = rtp_write_body_junk(data, rtspc, - curlx_dyn_ptr(&rtspc->buf), 1); - if(result) - goto out; - } - else { - /* count the '$' as skip and continue */ - skip_len = 1; - } - curlx_dyn_free(&rtspc->buf); - break; - } - /* a valid channel, so we expect this to be a real RTP message */ - rtspc->rtp_channel = (unsigned char)buf[0]; - if(curlx_dyn_addn(&rtspc->buf, buf, 1)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - *pconsumed += 1; - ++buf; - --blen; - rtspc->state = RTP_PARSE_LEN; - break; - } - - case RTP_PARSE_LEN: { - size_t rtp_len = curlx_dyn_len(&rtspc->buf); - const char *rtp_buf; - DEBUGASSERT(rtp_len >= 2 && rtp_len < 4); - if(curlx_dyn_addn(&rtspc->buf, buf, 1)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - *pconsumed += 1; - ++buf; - --blen; - if(rtp_len == 2) - break; - rtp_buf = curlx_dyn_ptr(&rtspc->buf); - rtspc->rtp_len = RTP_PKT_LENGTH(rtp_buf) + 4; - if(rtspc->rtp_len == 4) { - /* zero-length payload, the 4-byte header is the complete RTP - message. Dispatch immediately without entering RTP_PARSE_DATA. */ - DEBUGF(infof(data, "RTP write channel %d rtp_len %zu (no payload)", - rtspc->rtp_channel, rtspc->rtp_len)); - result = rtp_client_write(data, rtp_buf, rtspc->rtp_len); - curlx_dyn_free(&rtspc->buf); - rtspc->state = RTP_PARSE_SKIP; - if(result) - goto out; - break; - } - rtspc->state = RTP_PARSE_DATA; - break; - } - - case RTP_PARSE_DATA: { - size_t rtp_len = curlx_dyn_len(&rtspc->buf); - size_t needed; - DEBUGASSERT(rtp_len < rtspc->rtp_len); - needed = rtspc->rtp_len - rtp_len; - if(needed <= blen) { - if(curlx_dyn_addn(&rtspc->buf, buf, needed)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - *pconsumed += needed; - buf += needed; - blen -= needed; - /* complete RTP message in buffer */ - DEBUGF(infof(data, "RTP write channel %d rtp_len %zu", - rtspc->rtp_channel, rtspc->rtp_len)); - result = rtp_client_write(data, curlx_dyn_ptr(&rtspc->buf), - rtspc->rtp_len); - curlx_dyn_free(&rtspc->buf); - rtspc->state = RTP_PARSE_SKIP; - if(result) - goto out; - } - else { - if(curlx_dyn_addn(&rtspc->buf, buf, blen)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - *pconsumed += blen; - buf += blen; - blen = 0; - } - break; - } - - default: - DEBUGASSERT(0); - return CURLE_RECV_ERROR; - } - } -out: - if(!result && skip_len) - result = rtp_write_body_junk(data, rtspc, buf - skip_len, skip_len); - return result; -} - -/* - * Parse and write out an RTSP response. - * @param data the transfer - * @param conn the connection - * @param buf data read from connection - * @param blen amount of data in buf - * @param is_eos TRUE iff this is the last write - * @param readmore out, TRUE iff complete buf was consumed and more data - * is needed - */ -static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data, - const char *buf, - size_t blen, - bool is_eos) -{ - struct rtsp_conn *rtspc = - Curl_conn_meta_get(data->conn, CURL_META_RTSP_CONN); - CURLcode result = CURLE_OK; - size_t consumed = 0; - - if(!rtspc) - return CURLE_FAILED_INIT; - - if(!data->req.header) - rtspc->in_header = FALSE; - if(!blen) { - goto out; - } - - DEBUGF(infof(data, "rtsp_rtp_write_resp(len=%zu, in_header=%d, eos=%d)", - blen, rtspc->in_header, is_eos)); - - /* If header parsing is not ongoing, extract RTP messages */ - if(!rtspc->in_header) { - result = rtsp_filter_rtp(data, rtspc, buf, blen, &consumed); - if(result) - goto out; - buf += consumed; - blen -= consumed; - /* either we consumed all or are at the start of header parsing */ - if(blen && !data->req.header) - DEBUGF(infof(data, "RTSP: %zu bytes, possibly excess in response body", - blen)); - } - - /* we want to parse headers, do so */ - if(data->req.header && blen) { - rtspc->in_header = TRUE; - result = Curl_http_write_resp_hds(data, buf, blen, &consumed); - if(result) - goto out; - - buf += consumed; - blen -= consumed; - - if(!data->req.header) - rtspc->in_header = FALSE; - - if(!rtspc->in_header) { - /* If header parsing is done, extract interleaved RTP messages */ - if(data->req.size <= -1) { - /* Respect section 4.4 of rfc2326: If the Content-Length header is - absent, a length 0 must be assumed. */ - data->req.size = 0; - data->req.download_done = TRUE; - } - result = rtsp_filter_rtp(data, rtspc, buf, blen, &consumed); - if(result) - goto out; - blen -= consumed; - } - } - - if(rtspc->state != RTP_PARSE_SKIP) - data->req.done = FALSE; - /* we SHOULD have consumed all bytes, unless the response is borked. - * In which case we write out the left over bytes, letting the client - * writer deal with it (it will report EXCESS and fail the transfer). */ - DEBUGF(infof(data, "rtsp_rtp_write_resp(len=%zu, in_header=%d, done=%d, " - "rtspc->state=%d, req.size=%" FMT_OFF_T ")", - blen, rtspc->in_header, data->req.done, rtspc->state, - data->req.size)); - if(!result && (is_eos || blen)) { - result = Curl_client_write(data, CLIENTWRITE_BODY | - (is_eos ? CLIENTWRITE_EOS : 0), buf, blen); - } - -out: - if((data->set.rtspreq == RTSPREQ_RECEIVE) && - (rtspc->state == RTP_PARSE_SKIP)) { - /* In special mode RECEIVE, we process one chunk of network - * data, so we stop the transfer here, if we have no incomplete - * RTP message pending. */ - data->req.download_done = TRUE; - } - return result; -} - -static CURLcode rtsp_rtp_write_resp_hd(struct Curl_easy *data, - const char *buf, - size_t blen, - bool is_eos) -{ - return rtsp_rtp_write_resp(data, buf, blen, is_eos); -} - -static CURLcode rtsp_parse_transport(struct Curl_easy *data, - const char *transport) -{ - /* If we receive multiple Transport response-headers, the interleaved - channels of each response header is recorded and used together for - subsequent data validity checks.*/ - /* e.g.: ' RTP/AVP/TCP;unicast;interleaved=5-6' */ - const char *start, *end; - start = transport; - while(start && *start) { - curlx_str_passblanks(&start); - end = strchr(start, ';'); - if(checkprefix("interleaved=", start)) { - curl_off_t chan1, chan2, chan; - const char *p = start + 12; - if(!curlx_str_number(&p, &chan1, 255)) { - unsigned char *rtp_channel_mask = data->state.rtp_channel_mask; - chan2 = chan1; - if(!curlx_str_single(&p, '-')) { - if(curlx_str_number(&p, &chan2, 255)) { - infof(data, "Unable to read the interleaved parameter from " - "Transport header: [%s]", transport); - chan2 = chan1; - } - } - for(chan = chan1; chan <= chan2; chan++) { - int idx = (int)chan / 8; - int off = (int)chan % 8; - rtp_channel_mask[idx] |= (unsigned char)(1 << off); - } - } - else { - infof(data, "Unable to read the interleaved parameter from " - "Transport header: [%s]", transport); - } - break; - } - /* skip to next parameter */ - start = (!end) ? end : (end + 1); - } - return CURLE_OK; -} - -CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header) -{ - if(checkprefix("CSeq:", header)) { - curl_off_t CSeq = 0; - struct RTSP *rtsp = Curl_meta_get(data, CURL_META_RTSP_EASY); - const char *p = &header[5]; - if(!rtsp) - return CURLE_FAILED_INIT; - curlx_str_passblanks(&p); - if(curlx_str_number(&p, &CSeq, UINT_MAX)) { - failf(data, "Unable to read the CSeq header: [%s]", header); - return CURLE_RTSP_CSEQ_ERROR; - } - data->state.rtsp_CSeq_recv = rtsp->CSeq_recv = (uint32_t)CSeq; - } - else if(checkprefix("Session:", header)) { - const char *start, *end; - size_t idlen; - - /* Find the first non-space letter */ - start = header + 8; - curlx_str_passblanks(&start); - - if(!*start) { - failf(data, "Got a blank Session ID"); - return CURLE_RTSP_SESSION_ERROR; - } - - /* Find the end of Session ID - * - * Allow any non whitespace content, up to the field separator or end of - * line. RFC 2326 is not 100% clear on the session ID and for example - * gstreamer does URL-encoded session ID's not covered by the standard. - */ - end = start; - while((*end > ' ') && (*end != ';')) - end++; - idlen = end - start; - - if(data->set.str[STRING_RTSP_SESSION_ID]) { - - /* If the Session ID is set, then compare */ - if(strlen(data->set.str[STRING_RTSP_SESSION_ID]) != idlen || - strncmp(start, data->set.str[STRING_RTSP_SESSION_ID], idlen)) { - failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]", - start, data->set.str[STRING_RTSP_SESSION_ID]); - return CURLE_RTSP_SESSION_ERROR; - } - } - else { - /* If the Session ID is not set, and we find it in a response, then set - * it. - */ - - /* Copy the id substring into a new buffer */ - data->set.str[STRING_RTSP_SESSION_ID] = curlx_memdup0(start, idlen); - if(!data->set.str[STRING_RTSP_SESSION_ID]) - return CURLE_OUT_OF_MEMORY; - } - } - else if(checkprefix("Transport:", header)) { - CURLcode result; - result = rtsp_parse_transport(data, header + 10); - if(result) - return result; - } - return CURLE_OK; -} - -/* - * RTSP handler interface. - */ -const struct Curl_protocol Curl_protocol_rtsp = { - rtsp_setup_connection, /* setup_connection */ - rtsp_do, /* do_it */ - rtsp_done, /* done */ - ZERO_NULL, /* do_more */ - rtsp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - rtsp_do_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - Curl_http_perform_pollset, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - rtsp_rtp_write_resp, /* write_resp */ - rtsp_rtp_write_resp_hd, /* write_resp_hd */ - rtsp_conn_is_dead, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - Curl_http_follow, /* follow */ -}; - -#endif /* CURL_DISABLE_RTSP */ diff --git a/vendor/curl/lib/rtsp.h b/vendor/curl/lib/rtsp.h deleted file mode 100644 index dd5df3ff7..000000000 --- a/vendor/curl/lib/rtsp.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_RTSP_H -#define HEADER_CURL_RTSP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_RTSP -CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header); -extern const struct Curl_protocol Curl_protocol_rtsp; -#else -#define Curl_rtsp_parseheader(x, y) CURLE_NOT_BUILT_IN -#endif - -#endif /* HEADER_CURL_RTSP_H */ diff --git a/vendor/curl/lib/select.c b/vendor/curl/lib/select.c deleted file mode 100644 index 888490f2c..000000000 --- a/vendor/curl/lib/select.c +++ /dev/null @@ -1,733 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(HAVE_SELECT) && !defined(HAVE_POLL) -#error "We cannot compile without select() or poll() support." -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#elif defined(HAVE_UNISTD_H) -#include -#endif - -#include "urldata.h" -#include "connect.h" -#include "select.h" -#include "curl_trc.h" -#include "curlx/timediff.h" -#include "curlx/wait.h" - -#ifndef HAVE_POLL -/* - * This is a wrapper around select() to aid in Windows compatibility. A - * negative timeout value makes this function wait indefinitely, unless no - * valid file descriptor is given, when this happens the negative timeout is - * ignored and the function times out immediately. - * - * Return values: - * -1 = system call error or fd >= FD_SETSIZE - * 0 = timeout - * N = number of signalled file descriptors - */ -static int our_select(curl_socket_t maxfd, /* highest socket number */ - fd_set *fds_read, /* sockets ready for reading */ - fd_set *fds_write, /* sockets ready for writing */ - fd_set *fds_err, /* sockets with errors */ - timediff_t timeout_ms) /* milliseconds to wait */ -{ - struct timeval pending_tv; - struct timeval *ptimeout; - -#ifdef USE_WINSOCK - /* Winsock select() cannot handle zero events. See the comment below. */ - if((!fds_read || fds_read->fd_count == 0) && - (!fds_write || fds_write->fd_count == 0) && - (!fds_err || fds_err->fd_count == 0)) { - /* no sockets, wait */ - return curlx_wait_ms(timeout_ms); - } -#endif - - ptimeout = curlx_mstotv(&pending_tv, timeout_ms); - -#ifdef USE_WINSOCK - /* Winsock select() must not be called with an fd_set that contains zero - fd flags, or it will return WSAEINVAL. It also cannot be called with - no fd_sets at all! From the documentation: - - Any two of the parameters, readfds, writefds, or exceptfds, can be - given as null. At least one must be non-null, and any non-null - descriptor set must contain at least one handle to a socket. - - It is unclear why Winsock does not handle this for us instead of - calling this an error. Luckily, with Winsock, we can _also_ ask how - many bits are set on an fd_set. Therefore, let's check it beforehand. - */ - return select((int)maxfd + 1, - fds_read && fds_read->fd_count ? fds_read : NULL, - fds_write && fds_write->fd_count ? fds_write : NULL, - fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout); -#else - return select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout); -#endif -} - -#endif - -/* - * Wait for read or write events on a set of file descriptors. It uses poll() - * when poll() is available, in order to avoid limits with FD_SETSIZE, - * otherwise select() is used. An error is returned if select() is being used - * and a file descriptor is too large for FD_SETSIZE. - * - * A negative timeout value makes this function wait indefinitely, unless no - * valid file descriptor is given, when this happens the negative timeout is - * ignored and the function times out immediately. - * - * Return values: - * -1 = system call error or fd >= FD_SETSIZE - * 0 = timeout - * [bitmask] = action as described below - * - * CURL_CSELECT_IN - first socket is readable - * CURL_CSELECT_IN2 - second socket is readable - * CURL_CSELECT_OUT - write socket is writable - * CURL_CSELECT_ERR - an error condition occurred - */ -int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ - curl_socket_t readfd1, - curl_socket_t writefd, /* socket to write to */ - timediff_t timeout_ms) /* milliseconds to wait */ -{ - struct pollfd pfd[3]; - int num; - int r; - - if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) && - (writefd == CURL_SOCKET_BAD)) { - /* no sockets, wait */ - return curlx_wait_ms(timeout_ms); - } - - /* Avoid initial timestamp, avoid curlx_now() call, when elapsed - time in this function does not need to be measured. This happens - when function is called with a zero timeout or a negative timeout - value indicating a blocking call should be performed. */ - - num = 0; - if(readfd0 != CURL_SOCKET_BAD) { - pfd[num].fd = readfd0; - pfd[num].events = POLLRDNORM | POLLIN | POLLRDBAND | POLLPRI; - pfd[num].revents = 0; - num++; - } - if(readfd1 != CURL_SOCKET_BAD) { - pfd[num].fd = readfd1; - pfd[num].events = POLLRDNORM | POLLIN | POLLRDBAND | POLLPRI; - pfd[num].revents = 0; - num++; - } - if(writefd != CURL_SOCKET_BAD) { - pfd[num].fd = writefd; - pfd[num].events = POLLWRNORM | POLLOUT | POLLPRI; - pfd[num].revents = 0; - num++; - } - - r = Curl_poll(pfd, (unsigned int)num, timeout_ms); - if(r <= 0) - return r; - - r = 0; - num = 0; - if(readfd0 != CURL_SOCKET_BAD) { - if(pfd[num].revents & (POLLRDNORM | POLLIN | POLLERR | POLLHUP)) - r |= CURL_CSELECT_IN; - if(pfd[num].revents & (POLLPRI | POLLNVAL)) - r |= CURL_CSELECT_ERR; - num++; - } - if(readfd1 != CURL_SOCKET_BAD) { - if(pfd[num].revents & (POLLRDNORM | POLLIN | POLLERR | POLLHUP)) - r |= CURL_CSELECT_IN2; - if(pfd[num].revents & (POLLPRI | POLLNVAL)) - r |= CURL_CSELECT_ERR; - num++; - } - if(writefd != CURL_SOCKET_BAD) { - if(pfd[num].revents & (POLLWRNORM | POLLOUT)) - r |= CURL_CSELECT_OUT; - if(pfd[num].revents & (POLLERR | POLLHUP | POLLPRI | POLLNVAL)) - r |= CURL_CSELECT_ERR; - } - - return r; -} - -/* - * This is a wrapper around poll(). If poll() does not exist, then - * select() is used instead. An error is returned if select() is - * being used and a file descriptor is too large for FD_SETSIZE. - * A negative timeout value makes this function wait indefinitely, - * unless no valid file descriptor is given, when this happens the - * negative timeout is ignored and the function times out immediately. - * - * Return values: - * -1 = system call error or fd >= FD_SETSIZE - * 0 = timeout - * N = number of structures with non zero revent fields - */ -int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) -{ -#ifdef HAVE_POLL - int pending_ms; -#else - fd_set fds_read; - fd_set fds_write; - fd_set fds_err; - curl_socket_t maxfd; -#endif - bool fds_none = TRUE; - unsigned int i; - int r; - - if(ufds) { - for(i = 0; i < nfds; i++) { - if(ufds[i].fd != CURL_SOCKET_BAD) { - fds_none = FALSE; - break; - } - } - } - if(fds_none) { - /* no sockets, wait */ - return curlx_wait_ms(timeout_ms); - } - - /* Avoid initial timestamp, avoid curlx_now() call, when elapsed - time in this function does not need to be measured. This happens - when function is called with a zero timeout or a negative timeout - value indicating a blocking call should be performed. */ - -#ifdef HAVE_POLL - - /* prevent overflow, timeout_ms is typecast to int. */ -#if TIMEDIFF_T_MAX > INT_MAX - if(timeout_ms > INT_MAX) - timeout_ms = INT_MAX; -#endif - if(timeout_ms > 0) - pending_ms = (int)timeout_ms; - else if(timeout_ms < 0) - pending_ms = -1; - else - pending_ms = 0; - r = poll(ufds, nfds, pending_ms); - if(r <= 0) { - if((r == -1) && (SOCKERRNO == SOCKEINTR)) - /* make EINTR from select or poll not a "lethal" error */ - r = 0; - return r; - } - - for(i = 0; i < nfds; i++) { - if(ufds[i].fd == CURL_SOCKET_BAD) - continue; - if(ufds[i].revents & POLLHUP) - ufds[i].revents |= POLLIN; - if(ufds[i].revents & POLLERR) - ufds[i].revents |= POLLIN | POLLOUT; - } - -#else /* !HAVE_POLL */ - - FD_ZERO(&fds_read); - FD_ZERO(&fds_write); - FD_ZERO(&fds_err); - maxfd = (curl_socket_t)-1; - - for(i = 0; i < nfds; i++) { - ufds[i].revents = 0; - if(ufds[i].fd == CURL_SOCKET_BAD) - continue; - VERIFY_SOCK(ufds[i].fd); - if(ufds[i].events & (POLLIN | POLLOUT | POLLPRI | - POLLRDNORM | POLLWRNORM | POLLRDBAND)) { - if(ufds[i].fd > maxfd) - maxfd = ufds[i].fd; - if(ufds[i].events & (POLLRDNORM | POLLIN)) - FD_SET(ufds[i].fd, &fds_read); - if(ufds[i].events & (POLLWRNORM | POLLOUT)) - FD_SET(ufds[i].fd, &fds_write); - if(ufds[i].events & (POLLRDBAND | POLLPRI)) - FD_SET(ufds[i].fd, &fds_err); - } - } - - /* - Note also that Winsock ignores the first argument, so we do not worry - about the fact that maxfd is computed incorrectly with Winsock (since - curl_socket_t is unsigned in such cases and thus -1 is the largest - value). - */ - r = our_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms); - if(r <= 0) { - if((r == -1) && (SOCKERRNO == SOCKEINTR)) - /* make EINTR from select or poll not a "lethal" error */ - r = 0; - return r; - } - - r = 0; - for(i = 0; i < nfds; i++) { - ufds[i].revents = 0; - if(ufds[i].fd == CURL_SOCKET_BAD) - continue; - if(FD_ISSET(ufds[i].fd, &fds_read)) { - if(ufds[i].events & POLLRDNORM) - ufds[i].revents |= POLLRDNORM; - if(ufds[i].events & POLLIN) - ufds[i].revents |= POLLIN; - } - if(FD_ISSET(ufds[i].fd, &fds_write)) { - if(ufds[i].events & POLLWRNORM) - ufds[i].revents |= POLLWRNORM; - if(ufds[i].events & POLLOUT) - ufds[i].revents |= POLLOUT; - } - if(FD_ISSET(ufds[i].fd, &fds_err)) { - if(ufds[i].events & POLLRDBAND) - ufds[i].revents |= POLLRDBAND; - if(ufds[i].events & POLLPRI) - ufds[i].revents |= POLLPRI; - } - if(ufds[i].revents) - r++; - } - -#endif /* HAVE_POLL */ - - return r; -} - -void Curl_pollfds_init(struct curl_pollfds *cpfds, - struct pollfd *static_pfds, - unsigned int static_count) -{ - DEBUGASSERT(cpfds); - memset(cpfds, 0, sizeof(*cpfds)); - if(static_pfds && static_count) { - cpfds->pfds = static_pfds; - cpfds->count = static_count; - } -} - -void Curl_pollfds_reset(struct curl_pollfds *cpfds) -{ - cpfds->n = 0; -} - -void Curl_pollfds_cleanup(struct curl_pollfds *cpfds) -{ - DEBUGASSERT(cpfds); - if(cpfds->allocated_pfds) { - curlx_free(cpfds->pfds); - } - memset(cpfds, 0, sizeof(*cpfds)); -} - -static CURLcode cpfds_increase(struct curl_pollfds *cpfds, unsigned int inc) -{ - struct pollfd *new_fds; - unsigned int new_count = cpfds->count + inc; - - new_fds = curlx_calloc(new_count, sizeof(struct pollfd)); - if(!new_fds) - return CURLE_OUT_OF_MEMORY; - - memcpy(new_fds, cpfds->pfds, cpfds->count * sizeof(struct pollfd)); - if(cpfds->allocated_pfds) - curlx_free(cpfds->pfds); - cpfds->pfds = new_fds; - cpfds->count = new_count; - cpfds->allocated_pfds = TRUE; - return CURLE_OK; -} - -static CURLcode cpfds_add_sock(struct curl_pollfds *cpfds, - curl_socket_t sock, short events, bool fold) -{ - int i; - - if(fold && cpfds->n <= INT_MAX) { - for(i = (int)cpfds->n - 1; i >= 0; --i) { - if(sock == cpfds->pfds[i].fd) { - cpfds->pfds[i].events |= events; - return CURLE_OK; - } - } - } - /* not folded, add new entry */ - if(cpfds->n >= cpfds->count) { - if(cpfds_increase(cpfds, 100)) - return CURLE_OUT_OF_MEMORY; - } - cpfds->pfds[cpfds->n].fd = sock; - cpfds->pfds[cpfds->n].events = events; - ++cpfds->n; - return CURLE_OK; -} - -CURLcode Curl_pollfds_add_sock(struct curl_pollfds *cpfds, - curl_socket_t sock, short events) -{ - return cpfds_add_sock(cpfds, sock, events, FALSE); -} - -CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds, - struct easy_pollset *ps) -{ - size_t i; - - DEBUGASSERT(cpfds); - DEBUGASSERT(ps); - for(i = 0; i < ps->n; i++) { - short events = 0; - if(ps->actions[i] & CURL_POLL_IN) - events |= POLLIN; - if(ps->actions[i] & CURL_POLL_OUT) - events |= POLLOUT; - if(events) { - if(cpfds_add_sock(cpfds, ps->sockets[i], events, TRUE)) - return CURLE_OUT_OF_MEMORY; - } - } - return CURLE_OK; -} - -void Curl_waitfds_init(struct Curl_waitfds *cwfds, - struct curl_waitfd *static_wfds, - unsigned int static_count) -{ - DEBUGASSERT(cwfds); - DEBUGASSERT(static_wfds || !static_count); - memset(cwfds, 0, sizeof(*cwfds)); - cwfds->wfds = static_wfds; - cwfds->count = static_count; -} - -static unsigned int cwfds_add_sock(struct Curl_waitfds *cwfds, - curl_socket_t sock, short events) -{ - int i; - if(!cwfds->wfds) { - DEBUGASSERT(!cwfds->count && !cwfds->n); - return 1; - } - if(cwfds->n <= INT_MAX) { - for(i = (int)cwfds->n - 1; i >= 0; --i) { - if(sock == cwfds->wfds[i].fd) { - cwfds->wfds[i].events |= events; - return 0; - } - } - } - /* not folded, add new entry */ - if(cwfds->n < cwfds->count) { - cwfds->wfds[cwfds->n].fd = sock; - cwfds->wfds[cwfds->n].events = events; - ++cwfds->n; - } - return 1; -} - -unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds, - struct easy_pollset *ps) -{ - size_t i; - unsigned int need = 0; - - DEBUGASSERT(cwfds); - DEBUGASSERT(ps); - for(i = 0; i < ps->n; i++) { - short events = 0; - if(ps->actions[i] & CURL_POLL_IN) - events |= CURL_WAIT_POLLIN; - if(ps->actions[i] & CURL_POLL_OUT) - events |= CURL_WAIT_POLLOUT; - if(events) - need += cwfds_add_sock(cwfds, ps->sockets[i], events); - } - return need; -} - -void Curl_pollset_reset(struct easy_pollset *ps) -{ - unsigned int i; - ps->n = 0; -#ifdef DEBUGBUILD - DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC); -#endif - DEBUGASSERT(ps->count); - for(i = 0; i < ps->count; i++) - ps->sockets[i] = CURL_SOCKET_BAD; - memset(ps->actions, 0, ps->count * sizeof(ps->actions[0])); -} - -void Curl_pollset_init(struct easy_pollset *ps) -{ -#ifdef DEBUGBUILD - ps->init = CURL_EASY_POLLSET_MAGIC; -#endif - ps->sockets = ps->def_sockets; - ps->actions = ps->def_actions; - ps->count = CURL_ARRAYSIZE(ps->def_sockets); - ps->n = 0; - Curl_pollset_reset(ps); -} - -struct easy_pollset *Curl_pollset_create(void) -{ - struct easy_pollset *ps = curlx_calloc(1, sizeof(*ps)); - if(ps) - Curl_pollset_init(ps); - return ps; -} - -void Curl_pollset_cleanup(struct easy_pollset *ps) -{ -#ifdef DEBUGBUILD - DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC); -#endif - if(ps->sockets != ps->def_sockets) { - curlx_free(ps->sockets); - ps->sockets = ps->def_sockets; - } - if(ps->actions != ps->def_actions) { - curlx_free(ps->actions); - ps->actions = ps->def_actions; - } - ps->count = CURL_ARRAYSIZE(ps->def_sockets); - Curl_pollset_reset(ps); -} - -void Curl_pollset_move(struct easy_pollset *to, struct easy_pollset *from) -{ - Curl_pollset_cleanup(to); /* deallocate anything in to */ - if(from->sockets != from->def_sockets) { - DEBUGASSERT(from->actions != from->def_actions); - to->sockets = from->sockets; - to->actions = from->actions; - to->count = from->count; - to->n = from->n; - Curl_pollset_init(from); - } - else { - DEBUGASSERT(to->sockets == to->def_sockets); - DEBUGASSERT(to->actions == to->def_actions); - memcpy(to->sockets, from->sockets, to->count * sizeof(to->sockets[0])); - memcpy(to->actions, from->actions, to->count * sizeof(to->actions[0])); - to->n = from->n; - Curl_pollset_init(from); - } -} - -/** - * - */ -CURLcode Curl_pollset_change(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - int add_flags, int remove_flags) -{ - unsigned int i; - -#ifdef DEBUGBUILD - DEBUGASSERT(ps->init == CURL_EASY_POLLSET_MAGIC); -#endif - - DEBUGASSERT(VALID_SOCK(sock)); - if(!VALID_SOCK(sock)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - DEBUGASSERT(add_flags <= (CURL_POLL_IN | CURL_POLL_OUT)); - DEBUGASSERT(remove_flags <= (CURL_POLL_IN | CURL_POLL_OUT)); - DEBUGASSERT((add_flags & remove_flags) == 0); /* no overlap */ - for(i = 0; i < ps->n; ++i) { - if(ps->sockets[i] == sock) { - ps->actions[i] &= (unsigned char)(~remove_flags); - ps->actions[i] |= (unsigned char)add_flags; - /* all gone? remove socket */ - if(!ps->actions[i]) { - if((i + 1) < ps->n) { - memmove(&ps->sockets[i], &ps->sockets[i + 1], - (ps->n - (i + 1)) * sizeof(ps->sockets[0])); - memmove(&ps->actions[i], &ps->actions[i + 1], - (ps->n - (i + 1)) * sizeof(ps->actions[0])); - } - --ps->n; - } - return CURLE_OK; - } - } - /* not present */ - if(add_flags) { - if(i >= ps->count) { /* need to grow */ - unsigned int new_count = CURLMAX(ps->count * 2, 8); - curl_socket_t *nsockets; - unsigned char *nactions; - - CURL_TRC_M(data, "growing pollset capacity from %u to %u", - ps->count, new_count); - if(new_count <= ps->count) - return CURLE_OUT_OF_MEMORY; - nsockets = curlx_calloc(new_count, sizeof(nsockets[0])); - if(!nsockets) - return CURLE_OUT_OF_MEMORY; - nactions = curlx_calloc(new_count, sizeof(nactions[0])); - if(!nactions) { - curlx_free(nsockets); - return CURLE_OUT_OF_MEMORY; - } - memcpy(nsockets, ps->sockets, ps->count * sizeof(ps->sockets[0])); - memcpy(nactions, ps->actions, ps->count * sizeof(ps->actions[0])); - if(ps->sockets != ps->def_sockets) - curlx_free(ps->sockets); - ps->sockets = nsockets; - if(ps->actions != ps->def_actions) - curlx_free(ps->actions); - ps->actions = nactions; - ps->count = new_count; - } - DEBUGASSERT(i < ps->count); - if(i < ps->count) { - ps->sockets[i] = sock; - ps->actions[i] = (unsigned char)add_flags; - ps->n = i + 1; - } - } - return CURLE_OK; -} - -CURLcode Curl_pollset_set(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool do_in, bool do_out) -{ - return Curl_pollset_change(data, ps, sock, - (do_in ? CURL_POLL_IN : 0) | - (do_out ? CURL_POLL_OUT : 0), - (!do_in ? CURL_POLL_IN : 0) | - (!do_out ? CURL_POLL_OUT : 0)); -} - -/* - * Return values: - * -1 = error - * 0 = timeout - * N = number of structures with non zero revent fields - */ -int Curl_pollset_poll(struct Curl_easy *data, - struct easy_pollset *ps, - timediff_t timeout_ms) -{ - struct pollfd *pfds; - unsigned int i, npfds; - int rc; - - (void)data; - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - - if(!ps->n) - return curlx_wait_ms(timeout_ms); - - pfds = curlx_calloc(ps->n, sizeof(*pfds)); - if(!pfds) - return -1; - - npfds = 0; - for(i = 0; i < ps->n; ++i) { - short events = 0; - if(ps->actions[i] & CURL_POLL_IN) { - events |= POLLIN; - } - if(ps->actions[i] & CURL_POLL_OUT) { - events |= POLLOUT; - } - if(events) { - pfds[npfds].fd = ps->sockets[i]; - pfds[npfds].events = events; - ++npfds; - } - } - - rc = Curl_poll(pfds, npfds, timeout_ms); - curlx_free(pfds); - return rc; -} - -void Curl_pollset_check(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool *pwant_read, bool *pwant_write) -{ - unsigned int i; - - (void)data; - DEBUGASSERT(VALID_SOCK(sock)); - for(i = 0; i < ps->n; ++i) { - if(ps->sockets[i] == sock) { - *pwant_read = !!(ps->actions[i] & CURL_POLL_IN); - *pwant_write = !!(ps->actions[i] & CURL_POLL_OUT); - return; - } - } - *pwant_read = *pwant_write = FALSE; -} - -bool Curl_pollset_want_recv(struct Curl_easy *data, - struct easy_pollset *ps, - curl_socket_t sock) -{ - unsigned int i; - (void)data; - for(i = 0; i < ps->n; ++i) { - if((ps->sockets[i] == sock) && (ps->actions[i] & CURL_POLL_IN)) - return TRUE; - } - return FALSE; -} - -bool Curl_pollset_want_send(struct Curl_easy *data, - struct easy_pollset *ps, - curl_socket_t sock) -{ - unsigned int i; - (void)data; - for(i = 0; i < ps->n; ++i) { - if((ps->sockets[i] == sock) && (ps->actions[i] & CURL_POLL_OUT)) - return TRUE; - } - return FALSE; -} diff --git a/vendor/curl/lib/select.h b/vendor/curl/lib/select.h deleted file mode 100644 index 87b695463..000000000 --- a/vendor/curl/lib/select.h +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef HEADER_CURL_SELECT_H -#define HEADER_CURL_SELECT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_POLL_H -#include -#elif defined(HAVE_SYS_POLL_H) -#include -#endif - -/* - * Definition of pollfd struct and constants for platforms lacking them. - */ - -#if !defined(HAVE_SYS_POLL_H) && !defined(HAVE_POLL_H) && !defined(POLLIN) - -#define POLLIN 0x01 -#define POLLPRI 0x02 -#define POLLOUT 0x04 -#define POLLERR 0x08 -#define POLLHUP 0x10 -#define POLLNVAL 0x20 - -struct pollfd { - curl_socket_t fd; - short events; - short revents; -}; - -#endif - -#ifndef POLLRDNORM -#define POLLRDNORM POLLIN -#endif - -#ifndef POLLWRNORM -#define POLLWRNORM POLLOUT -#endif - -#ifndef POLLRDBAND -#define POLLRDBAND POLLPRI -#endif - -/* there are three CSELECT defines that are defined in the public header that - are exposed to users, but this *IN2 bit is only ever used internally and - therefore defined here */ -#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1) - -int Curl_socket_check(curl_socket_t readfd0, - curl_socket_t readfd1, - curl_socket_t writefd, - timediff_t timeout_ms); -#define SOCKET_READABLE(x, z) \ - Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z) -#define SOCKET_WRITABLE(x, z) \ - Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z) - -int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms); - -/* - With Winsock the valid range is [0..INVALID_SOCKET-1] according to - https://learn.microsoft.com/windows/win32/winsock/socket-data-type-2 -*/ -#ifdef USE_WINSOCK -#define VALID_SOCK(s) ((s) < INVALID_SOCKET) -#define FDSET_SOCK(x) 1 -#define VERIFY_SOCK(x) \ - do { \ - if(!VALID_SOCK(x)) { \ - SET_SOCKERRNO(SOCKEINVAL); \ - return -1; \ - } \ - } while(0) -#else -#define VALID_SOCK(s) ((s) >= 0) - -/* If the socket is small enough to get set or read from an fdset */ -#define FDSET_SOCK(s) ((s) < FD_SETSIZE) - -#define VERIFY_SOCK(x) \ - do { \ - if(!VALID_SOCK(x) || !FDSET_SOCK(x)) { \ - SET_SOCKERRNO(SOCKEINVAL); \ - return -1; \ - } \ - } while(0) -#endif - -/* Keep the sockets to poll for an easy handle. - * `actions` are bitmaps of CURL_POLL_IN and CURL_POLL_OUT. - * Starts with small capacity, grows on demand. - */ -#define EZ_POLLSET_DEF_COUNT 2 - -struct easy_pollset { - curl_socket_t *sockets; - unsigned char *actions; - unsigned int n; - unsigned int count; -#ifdef DEBUGBUILD - int init; -#endif - curl_socket_t def_sockets[EZ_POLLSET_DEF_COUNT]; - unsigned char def_actions[EZ_POLLSET_DEF_COUNT]; -}; - -#ifdef DEBUGBUILD -#define CURL_EASY_POLLSET_MAGIC 0x7a657370 -#endif - -/* allocate and initialise */ -struct easy_pollset *Curl_pollset_create(void); - -/* Initialize before first use */ -void Curl_pollset_init(struct easy_pollset *ps); -/* Free any allocated resources */ -void Curl_pollset_cleanup(struct easy_pollset *ps); -/* Reset to an empty pollset */ -void Curl_pollset_reset(struct easy_pollset *ps); -/* Move pollset from to pollset to, replacing all in to, - * leaving from empty. */ -void Curl_pollset_move(struct easy_pollset *to, struct easy_pollset *from); - -/* Change the poll flags (CURL_POLL_IN/CURL_POLL_OUT) to the poll set for - * socket `sock`. If the socket is not already part of the poll set, it - * will be added. - * If the socket is present and all poll flags are cleared, it will be removed. - */ -CURLcode Curl_pollset_change(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - int add_flags, - int remove_flags) WARN_UNUSED_RESULT; - -CURLcode Curl_pollset_set(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool do_in, bool do_out) WARN_UNUSED_RESULT; - -#define Curl_pollset_add_in(data, ps, sock) \ - Curl_pollset_change(data, ps, sock, CURL_POLL_IN, 0) -#define Curl_pollset_remove_in(data, ps, sock) \ - Curl_pollset_change(data, ps, sock, 0, CURL_POLL_IN) -#define Curl_pollset_add_out(data, ps, sock) \ - Curl_pollset_change(data, ps, sock, CURL_POLL_OUT, 0) -#define Curl_pollset_remove_out(data, ps, sock) \ - Curl_pollset_change(data, ps, sock, 0, CURL_POLL_OUT) -#define Curl_pollset_add_inout(data, ps, sock) \ - Curl_pollset_change(data, ps, sock, CURL_POLL_IN | CURL_POLL_OUT, 0) -#define Curl_pollset_set_in_only(data, ps, sock) \ - Curl_pollset_change(data, ps, sock, CURL_POLL_IN, CURL_POLL_OUT) -#define Curl_pollset_set_out_only(data, ps, sock) \ - Curl_pollset_change(data, ps, sock, CURL_POLL_OUT, CURL_POLL_IN) - -/* return < = on error, 0 on timeout or how many sockets are ready */ -int Curl_pollset_poll(struct Curl_easy *data, - struct easy_pollset *ps, - timediff_t timeout_ms); - -/** - * Check if the pollset, as is, wants to read and/or write regarding - * the given socket. - */ -void Curl_pollset_check(struct Curl_easy *data, - struct easy_pollset *ps, curl_socket_t sock, - bool *pwant_read, bool *pwant_write); - -/* TRUE if the pollset contains socket with CURL_POLL_IN. */ -bool Curl_pollset_want_recv(struct Curl_easy *data, - struct easy_pollset *ps, - curl_socket_t sock); -/* TRUE if the pollset contains socket with CURL_POLL_OUT. */ -bool Curl_pollset_want_send(struct Curl_easy *data, - struct easy_pollset *ps, - curl_socket_t sock); - -struct curl_pollfds { - struct pollfd *pfds; - unsigned int n; - unsigned int count; - BIT(allocated_pfds); -}; - -void Curl_pollfds_init(struct curl_pollfds *cpfds, - struct pollfd *static_pfds, - unsigned int static_count); - -void Curl_pollfds_reset(struct curl_pollfds *cpfds); - -void Curl_pollfds_cleanup(struct curl_pollfds *cpfds); - -CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds, - struct easy_pollset *ps); - -CURLcode Curl_pollfds_add_sock(struct curl_pollfds *cpfds, - curl_socket_t sock, short events); - -struct Curl_waitfds { - struct curl_waitfd *wfds; - unsigned int n; - unsigned int count; -}; - -void Curl_waitfds_init(struct Curl_waitfds *cwfds, - struct curl_waitfd *static_wfds, - unsigned int static_count); - -unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds, - struct easy_pollset *ps); - -#endif /* HEADER_CURL_SELECT_H */ diff --git a/vendor/curl/lib/sendf.c b/vendor/curl/lib/sendf.c deleted file mode 100644 index 7c977d3b9..000000000 --- a/vendor/curl/lib/sendf.c +++ /dev/null @@ -1,1477 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#ifdef HAVE_LINUX_TCP_H -#include -#elif defined(HAVE_NETINET_TCP_H) -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "curl_trc.h" -#include "transfer.h" -#include "cfilters.h" -#include "connect.h" -#include "cw-out.h" -#include "cw-pause.h" -#include "multiif.h" -#include "progress.h" - -static void cl_reset_writer(struct Curl_easy *data) -{ - struct Curl_cwriter *writer = data->req.writer_stack; - while(writer) { - data->req.writer_stack = writer->next; - writer->cwt->do_close(data, writer); - curlx_free(writer); - writer = data->req.writer_stack; - } -} - -static void cl_reset_reader(struct Curl_easy *data) -{ - struct Curl_creader *reader = data->req.reader_stack; - data->req.reader_started = FALSE; - while(reader) { - data->req.reader_stack = reader->next; - reader->crt->do_close(data, reader); - curlx_free(reader); - reader = data->req.reader_stack; - } -} - -void Curl_client_cleanup(struct Curl_easy *data) -{ - cl_reset_reader(data); - cl_reset_writer(data); - - data->req.bytecount = 0; - data->req.headerline = 0; -} - -void Curl_client_reset(struct Curl_easy *data) -{ - if(data->req.rewind_read) { - /* already requested */ - CURL_TRC_READ(data, "client_reset, will rewind reader"); - } - else { - CURL_TRC_READ(data, "client_reset, clear readers"); - cl_reset_reader(data); - } - cl_reset_writer(data); - - data->req.bytecount = 0; - data->req.headerline = 0; -} - -CURLcode Curl_client_start(struct Curl_easy *data) -{ - if(data->req.rewind_read) { - struct Curl_creader *r = data->req.reader_stack; - CURLcode result = CURLE_OK; - - CURL_TRC_READ(data, "client start, rewind readers"); - while(r) { - result = r->crt->cntrl(data, r, CURL_CRCNTRL_REWIND); - if(result) { - failf(data, "rewind of client reader '%s' failed: %d", - r->crt->name, result); - return result; - } - r = r->next; - } - data->req.rewind_read = FALSE; - cl_reset_reader(data); - } - return CURLE_OK; -} - -bool Curl_creader_will_rewind(struct Curl_easy *data) -{ - return (bool)data->req.rewind_read; -} - -void Curl_creader_set_rewind(struct Curl_easy *data, bool enable) -{ - data->req.rewind_read = !!enable; -} - -/* Write data using an unencoding writer stack. */ -CURLcode Curl_cwriter_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - if(!writer) - return CURLE_WRITE_ERROR; - return writer->cwt->do_write(data, writer, type, buf, nbytes); -} - -CURLcode Curl_cwriter_def_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - (void)data; - (void)writer; - return CURLE_OK; -} - -CURLcode Curl_cwriter_def_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); -} - -void Curl_cwriter_def_close(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - (void)data; - (void)writer; -} - -static size_t get_max_body_write_len(struct Curl_easy *data, curl_off_t limit) -{ - if(limit != -1) { - /* How much more are we allowed to write? */ - return curlx_sotouz_range(limit - data->req.bytecount, 0, SIZE_MAX); - } - return SIZE_MAX; -} - -struct cw_download_ctx { - struct Curl_cwriter super; - BIT(started_response); - BIT(started_body); -}; - -/* Download client writer in phase CURL_CW_PROTOCOL that - * sees the "real" download body data. */ -static CURLcode cw_download_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - struct cw_download_ctx *ctx = writer->ctx; - CURLcode result; - size_t nwrite, excess_len = 0; - bool is_connect = !!(type & CLIENTWRITE_CONNECT); - - if(!ctx->started_response && - !(type & (CLIENTWRITE_INFO | CLIENTWRITE_CONNECT))) { - Curl_pgrsTime(data, TIMER_STARTTRANSFER); - ctx->started_response = TRUE; - } - - if(!(type & CLIENTWRITE_BODY)) { - if(is_connect && data->set.suppress_connect_headers) - return CURLE_OK; - result = Curl_cwriter_write(data, writer->next, type, buf, nbytes); - CURL_TRC_WRITE(data, "download_write header(type=%x, blen=%zu) -> %d", - type, nbytes, result); - return result; - } - - if(!ctx->started_body && - !(type & (CLIENTWRITE_INFO | CLIENTWRITE_CONNECT))) { - Curl_rlimit_start(&data->progress.dl.rlimit, Curl_pgrs_now(data), - data->req.size); - ctx->started_body = TRUE; - } - - /* Here, we deal with REAL BODY bytes. All filtering and transfer - * encodings have been applied and only the true content, e.g. BODY, - * bytes are passed here. - * This allows us to check sizes, update stats, etc. independent - * from the protocol in play. */ - - if(data->req.no_body && nbytes > 0) { - /* BODY arrives although we want none, bail out */ - streamclose(data->conn, "ignoring body"); - CURL_TRC_WRITE(data, "download_write body(type=%x, blen=%zu), " - "did not want a BODY", type, nbytes); - data->req.download_done = TRUE; - if(data->info.header_size) - /* if headers have been received, this is fine */ - return CURLE_OK; - return CURLE_WEIRD_SERVER_REPLY; - } - - /* Determine if we see any bytes in excess to what is allowed. - * We write the allowed bytes and handle excess further below. - * This gives deterministic BODY writes on varying buffer receive - * lengths. */ - nwrite = nbytes; - if(data->req.maxdownload != -1) { - size_t wmax = get_max_body_write_len(data, data->req.maxdownload); - if(nwrite > wmax) { - excess_len = nbytes - wmax; - nwrite = wmax; - } - - if(nwrite == wmax) { - data->req.download_done = TRUE; - } - - if((type & CLIENTWRITE_EOS) && !data->req.no_body && - (data->req.size > data->req.bytecount)) { - failf(data, "end of response with %" FMT_OFF_T " bytes missing", - data->req.size - data->req.bytecount); - return CURLE_PARTIAL_FILE; - } - } - - /* Error on too large filesize is handled below, after writing - * the permitted bytes */ - if(data->set.max_filesize && !data->req.ignorebody) { - size_t wmax = get_max_body_write_len(data, data->set.max_filesize); - if(nwrite > wmax) { - nwrite = wmax; - } - } - - if(!data->req.ignorebody && (nwrite || (type & CLIENTWRITE_EOS))) { - result = Curl_cwriter_write(data, writer->next, type, buf, nwrite); - CURL_TRC_WRITE(data, "download_write body(type=%x, blen=%zu) -> %d", - type, nbytes, result); - if(result) - return result; - } - - /* Update stats, write and report progress */ - if(nwrite) { - data->req.bytecount += nwrite; - Curl_pgrs_download_inc(data, nwrite); - } - - if(excess_len) { - if(!data->req.ignorebody) { - infof(data, - "Excess found writing body:" - " excess = %zu" - ", size = %" FMT_OFF_T - ", maxdownload = %" FMT_OFF_T - ", bytecount = %" FMT_OFF_T, - excess_len, data->req.size, data->req.maxdownload, - data->req.bytecount); - connclose(data->conn, "excess found in a read"); - } - } - else if((nwrite < nbytes) && !data->req.ignorebody) { - failf(data, "Exceeded the maximum allowed file size " - "(%" FMT_OFF_T ") with %" FMT_OFF_T " bytes", - data->set.max_filesize, data->req.bytecount); - return CURLE_FILESIZE_EXCEEDED; - } - - return CURLE_OK; -} - -static const struct Curl_cwtype cw_download = { - "protocol", - NULL, - Curl_cwriter_def_init, - cw_download_write, - Curl_cwriter_def_close, - sizeof(struct cw_download_ctx) -}; - -/* RAW client writer in phase CURL_CW_RAW that - * enabled tracing of raw data. */ -static CURLcode cw_raw_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - if(type & CLIENTWRITE_BODY && data->set.verbose && !data->req.ignorebody) { - Curl_debug(data, CURLINFO_DATA_IN, buf, nbytes); - } - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); -} - -static const struct Curl_cwtype cw_raw = { - "raw", - NULL, - Curl_cwriter_def_init, - cw_raw_write, - Curl_cwriter_def_close, - sizeof(struct Curl_cwriter) -}; - -static CURLcode do_init_writer_stack(struct Curl_easy *data) -{ - struct Curl_cwriter *writer; - CURLcode result; - - DEBUGASSERT(!data->req.writer_stack); - result = Curl_cwriter_create(&data->req.writer_stack, - data, &Curl_cwt_out, CURL_CW_CLIENT); - if(result) - return result; - - /* This places the "pause" writer behind the "download" writer that - * is added below. Meaning the "download" can do checks on content length - * and other things *before* write outs are buffered for paused transfers. */ - result = Curl_cwriter_create(&writer, data, &Curl_cwt_pause, - CURL_CW_PROTOCOL); - if(!result) { - result = Curl_cwriter_add(data, writer); - if(result) - Curl_cwriter_free(data, writer); - } - if(result) - return result; - - result = Curl_cwriter_create(&writer, data, &cw_download, CURL_CW_PROTOCOL); - if(!result) { - result = Curl_cwriter_add(data, writer); - if(result) - Curl_cwriter_free(data, writer); - } - if(result) - return result; - - result = Curl_cwriter_create(&writer, data, &cw_raw, CURL_CW_RAW); - if(!result) { - result = Curl_cwriter_add(data, writer); - if(result) - Curl_cwriter_free(data, writer); - } - if(result) - return result; - - return result; -} - -/* Curl_client_write() sends data to the write callback(s) - - The bit pattern defines to what "streams" to write to. Body and/or header. - The defines are in sendf.h of course. - */ -CURLcode Curl_client_write(struct Curl_easy *data, int type, const char *buf, - size_t len) -{ - CURLcode result; - - /* it is one of those, at least */ - DEBUGASSERT(type & - (CLIENTWRITE_BODY | CLIENTWRITE_HEADER | CLIENTWRITE_INFO)); - /* BODY is only BODY (with optional EOS) */ - DEBUGASSERT(!(type & CLIENTWRITE_BODY) || - ((type & ~(CLIENTWRITE_BODY | CLIENTWRITE_EOS)) == 0)); - /* INFO is only INFO (with optional EOS) */ - DEBUGASSERT(!(type & CLIENTWRITE_INFO) || - ((type & ~(CLIENTWRITE_INFO | CLIENTWRITE_EOS)) == 0)); - - if(!data->req.writer_stack) { - result = do_init_writer_stack(data); - if(result) - return result; - DEBUGASSERT(data->req.writer_stack); - } - - result = Curl_cwriter_write(data, data->req.writer_stack, type, buf, len); - CURL_TRC_WRITE(data, "client_write(type=%x, len=%zu) -> %d", - type, len, result); - return result; -} - -/* Create an unencoding writer stage using the given handler. */ -CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter, - struct Curl_easy *data, - const struct Curl_cwtype *cwt, - Curl_cwriter_phase phase) -{ - struct Curl_cwriter *writer = NULL; - CURLcode result = CURLE_OUT_OF_MEMORY; - void *p; - - DEBUGASSERT(cwt->cwriter_size >= sizeof(struct Curl_cwriter)); - p = curlx_calloc(1, cwt->cwriter_size); - if(!p) - goto out; - - writer = (struct Curl_cwriter *)p; - writer->cwt = cwt; - writer->ctx = p; - writer->phase = phase; - result = cwt->do_init(data, writer); - -out: - *pwriter = result ? NULL : writer; - if(result) - curlx_free(writer); - return result; -} - -void Curl_cwriter_free(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - if(writer) { - writer->cwt->do_close(data, writer); - curlx_free(writer); - } -} - -size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase) -{ - struct Curl_cwriter *w; - size_t n = 0; - - for(w = data->req.writer_stack; w; w = w->next) { - if(w->phase == phase) - ++n; - } - return n; -} - -CURLcode Curl_cwriter_add(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - CURLcode result; - struct Curl_cwriter **anchor = &data->req.writer_stack; - - if(!*anchor) { - result = do_init_writer_stack(data); - if(result) - return result; - } - - /* Insert the writer as first in its phase. - * Skip existing writers of lower phases. */ - while(*anchor && (*anchor)->phase < writer->phase) - anchor = &((*anchor)->next); - writer->next = *anchor; - *anchor = writer; - return CURLE_OK; -} - -struct Curl_cwriter *Curl_cwriter_get_by_name(struct Curl_easy *data, - const char *name) -{ - struct Curl_cwriter *writer; - for(writer = data->req.writer_stack; writer; writer = writer->next) { - if(!strcmp(name, writer->cwt->name)) - return writer; - } - return NULL; -} - -struct Curl_cwriter *Curl_cwriter_get_by_type(struct Curl_easy *data, - const struct Curl_cwtype *cwt) -{ - struct Curl_cwriter *writer; - for(writer = data->req.writer_stack; writer; writer = writer->next) { - if(writer->cwt == cwt) - return writer; - } - return NULL; -} - -bool Curl_cwriter_is_content_decoding(struct Curl_easy *data) -{ - struct Curl_cwriter *writer; - for(writer = data->req.writer_stack; writer; writer = writer->next) { - if(writer->phase == CURL_CW_CONTENT_DECODE) - return TRUE; - } - return FALSE; -} - -bool Curl_cwriter_is_paused(struct Curl_easy *data) -{ - return Curl_cw_out_is_paused(data); -} - -CURLcode Curl_cwriter_unpause(struct Curl_easy *data) -{ - return Curl_cw_out_unpause(data); -} - -CURLcode Curl_creader_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, size_t *nread, bool *eos) -{ - *nread = 0; - *eos = FALSE; - if(!reader) - return CURLE_READ_ERROR; - return reader->crt->do_read(data, reader, buf, blen, nread, eos); -} - -void Curl_creader_clear_eos(struct Curl_easy *data, - struct Curl_creader *reader) -{ - while(reader) { - (void)reader->crt->cntrl(data, reader, CURL_CRCNTRL_CLEAR_EOS); - reader = reader->next; - } -} - -CURLcode Curl_creader_def_init(struct Curl_easy *data, - struct Curl_creader *reader) -{ - (void)data; - (void)reader; - return CURLE_OK; -} - -void Curl_creader_def_close(struct Curl_easy *data, - struct Curl_creader *reader) -{ - (void)data; - (void)reader; -} - -CURLcode Curl_creader_def_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *nread, bool *eos) -{ - if(reader->next) - return reader->next->crt->do_read(data, reader->next, buf, blen, - nread, eos); - else { - *nread = 0; - *eos = FALSE; - return CURLE_READ_ERROR; - } -} - -bool Curl_creader_def_needs_rewind(struct Curl_easy *data, - struct Curl_creader *reader) -{ - (void)data; - (void)reader; - return FALSE; -} - -curl_off_t Curl_creader_def_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - return reader->next ? - reader->next->crt->total_length(data, reader->next) : -1; -} - -CURLcode Curl_creader_def_resume_from(struct Curl_easy *data, - struct Curl_creader *reader, - curl_off_t offset) -{ - (void)data; - (void)reader; - (void)offset; - return CURLE_READ_ERROR; -} - -CURLcode Curl_creader_def_cntrl(struct Curl_easy *data, - struct Curl_creader *reader, - Curl_creader_cntrl opcode) -{ - (void)data; - (void)reader; - (void)opcode; - return CURLE_OK; -} - -bool Curl_creader_def_is_paused(struct Curl_easy *data, - struct Curl_creader *reader) -{ - (void)data; - (void)reader; - return FALSE; -} - -void Curl_creader_def_done(struct Curl_easy *data, - struct Curl_creader *reader, int premature) -{ - (void)data; - (void)reader; - (void)premature; -} - -struct cr_in_ctx { - struct Curl_creader super; - curl_read_callback read_cb; - void *cb_user_data; - curl_off_t total_len; - curl_off_t read_len; - CURLcode error_result; - BIT(seen_eos); - BIT(errored); - BIT(has_used_cb); - BIT(is_paused); -}; - -static CURLcode cr_in_init(struct Curl_easy *data, struct Curl_creader *reader) -{ - struct cr_in_ctx *ctx = reader->ctx; - ctx->read_cb = data->state.fread_func; - ctx->cb_user_data = data->state.in; - ctx->total_len = -1; - ctx->read_len = 0; - return CURLE_OK; -} - -/* Real client reader to installed client callbacks. */ -static CURLcode cr_in_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct cr_in_ctx *ctx = reader->ctx; - CURLcode result = CURLE_OK; - size_t nread; - - ctx->is_paused = FALSE; - - /* Once we have errored, we will return the same error forever */ - if(ctx->errored) { - *pnread = 0; - *peos = FALSE; - return ctx->error_result; - } - if(ctx->seen_eos) { - *pnread = 0; - *peos = TRUE; - return CURLE_OK; - } - /* respect length limitations */ - if(ctx->total_len >= 0) { - blen = curlx_sotouz_range(ctx->total_len - ctx->read_len, 0, blen); - } - nread = 0; - if(ctx->read_cb && blen) { - Curl_set_in_callback(data, TRUE); - nread = ctx->read_cb(buf, 1, blen, ctx->cb_user_data); - Curl_set_in_callback(data, FALSE); - ctx->has_used_cb = TRUE; - } - - switch(nread) { - case 0: - if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) { - failf(data, "client read function EOF fail, " - "only %" FMT_OFF_T "/%" FMT_OFF_T " of needed bytes read", - ctx->read_len, ctx->total_len); - result = CURLE_READ_ERROR; - break; - } - *pnread = 0; - *peos = TRUE; - ctx->seen_eos = TRUE; - break; - - case CURL_READFUNC_ABORT: - failf(data, "operation aborted by callback"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_ABORTED_BY_CALLBACK; - result = CURLE_ABORTED_BY_CALLBACK; - break; - - case CURL_READFUNC_PAUSE: - if(data->conn->scheme->flags & PROTOPT_NONETWORK) { - /* protocols that work without network cannot be paused. This is - actually only FILE:// now, and it cannot pause since the transfer - is not done using the "normal" procedure. */ - failf(data, "Read callback asked for PAUSE when not supported"); - result = CURLE_READ_ERROR; - break; - } - /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ - CURL_TRC_READ(data, "cr_in_read, callback returned CURL_READFUNC_PAUSE"); - ctx->is_paused = TRUE; - *pnread = 0; - *peos = FALSE; - result = Curl_xfer_pause_send(data, TRUE); - break; /* nothing was read */ - - default: - if(nread > blen) { - /* the read function returned a too large value */ - failf(data, "read function returned funny value"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_READ_ERROR; - result = CURLE_READ_ERROR; - break; - } - ctx->read_len += nread; - if(ctx->total_len >= 0) - ctx->seen_eos = (ctx->read_len >= ctx->total_len); - *pnread = nread; - *peos = (bool)ctx->seen_eos; - break; - } - CURL_TRC_READ(data, "cr_in_read(len=%zu, total=%" FMT_OFF_T - ", read=%" FMT_OFF_T ") -> %d, nread=%zu, eos=%d", - blen, ctx->total_len, ctx->read_len, result, - *pnread, *peos); - return result; -} - -static bool cr_in_needs_rewind(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_in_ctx *ctx = reader->ctx; - (void)data; - return (bool)ctx->has_used_cb; -} - -static curl_off_t cr_in_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_in_ctx *ctx = reader->ctx; - (void)data; - return ctx->total_len; -} - -static CURLcode cr_in_resume_from(struct Curl_easy *data, - struct Curl_creader *reader, - curl_off_t offset) -{ - struct cr_in_ctx *ctx = reader->ctx; - int seekerr = CURL_SEEKFUNC_CANTSEEK; - - DEBUGASSERT(data->conn); - /* already started reading? */ - if(ctx->read_len) - return CURLE_READ_ERROR; - - if(data->set.seek_func) { - Curl_set_in_callback(data, TRUE); - seekerr = data->set.seek_func(data->set.seek_client, offset, SEEK_SET); - Curl_set_in_callback(data, FALSE); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - curl_off_t passed = 0; - - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_READ_ERROR; - } - /* when seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */ - do { - char scratch[4 * 1024]; - size_t readthisamountnow = - (offset - passed > (curl_off_t)sizeof(scratch)) ? - sizeof(scratch) : - curlx_sotouz(offset - passed); - size_t actuallyread; - - Curl_set_in_callback(data, TRUE); - actuallyread = ctx->read_cb(scratch, 1, readthisamountnow, - ctx->cb_user_data); - Curl_set_in_callback(data, FALSE); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Could only read %" FMT_OFF_T " bytes from the input", - passed); - return CURLE_READ_ERROR; - } - } while(passed < offset); - } - - /* now, decrease the size of the read */ - if(ctx->total_len > 0) { - ctx->total_len -= offset; - - if(ctx->total_len <= 0) { - failf(data, "File already completely uploaded"); - return CURLE_PARTIAL_FILE; - } - } - /* we have passed, proceed as normal */ - return CURLE_OK; -} - -static CURLcode cr_in_rewind(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_in_ctx *ctx = reader->ctx; - - /* If we never invoked the callback, there is noting to rewind */ - if(!ctx->has_used_cb) - return CURLE_OK; - - if(data->set.seek_func) { - int err; - - Curl_set_in_callback(data, TRUE); - err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET); - Curl_set_in_callback(data, FALSE); - CURL_TRC_READ(data, "cr_in, rewind via set.seek_func -> %d", err); - if(err) { - failf(data, "seek callback returned error %d", err); - return CURLE_SEND_FAIL_REWIND; - } - } - else if(data->set.ioctl_func) { - curlioerr err; - - Curl_set_in_callback(data, TRUE); - err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD, - data->set.ioctl_client); - Curl_set_in_callback(data, FALSE); - CURL_TRC_READ(data, "cr_in, rewind via set.ioctl_func -> %d", (int)err); - if(err) { - failf(data, "ioctl callback returned error %d", (int)err); - return CURLE_SEND_FAIL_REWIND; - } - } - else { - /* If no CURLOPT_READFUNCTION is used, we know that we operate on a - given FILE * stream and we can actually attempt to rewind that - ourselves with fseek() */ -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - if(data->state.fread_func == (curl_read_callback)fread) { -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - int err = fseek(data->state.in, 0, SEEK_SET); - CURL_TRC_READ(data, "cr_in, rewind via fseek -> %d(%d)", - (int)err, (int)errno); - if(err != -1) - /* successful rewind */ - return CURLE_OK; - } - - /* no callback set or failure above, makes us fail at once */ - failf(data, "necessary data rewind was not possible"); - return CURLE_SEND_FAIL_REWIND; - } - return CURLE_OK; -} - -static CURLcode cr_in_cntrl(struct Curl_easy *data, - struct Curl_creader *reader, - Curl_creader_cntrl opcode) -{ - struct cr_in_ctx *ctx = reader->ctx; - - switch(opcode) { - case CURL_CRCNTRL_REWIND: - return cr_in_rewind(data, reader); - case CURL_CRCNTRL_UNPAUSE: - ctx->is_paused = FALSE; - break; - case CURL_CRCNTRL_CLEAR_EOS: - ctx->seen_eos = FALSE; - break; - default: - break; - } - return CURLE_OK; -} - -static bool cr_in_is_paused(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_in_ctx *ctx = reader->ctx; - (void)data; - return (bool)ctx->is_paused; -} - -static const struct Curl_crtype cr_in = { - "cr-in", - cr_in_init, - cr_in_read, - Curl_creader_def_close, - cr_in_needs_rewind, - cr_in_total_length, - cr_in_resume_from, - cr_in_cntrl, - cr_in_is_paused, - Curl_creader_def_done, - sizeof(struct cr_in_ctx) -}; - -CURLcode Curl_creader_create(struct Curl_creader **preader, - struct Curl_easy *data, - const struct Curl_crtype *crt, - Curl_creader_phase phase) -{ - struct Curl_creader *reader = NULL; - CURLcode result = CURLE_OUT_OF_MEMORY; - void *p; - - DEBUGASSERT(crt->creader_size >= sizeof(struct Curl_creader)); - p = curlx_calloc(1, crt->creader_size); - if(!p) - goto out; - - reader = (struct Curl_creader *)p; - reader->crt = crt; - reader->ctx = p; - reader->phase = phase; - result = crt->do_init(data, reader); - -out: - *preader = result ? NULL : reader; - if(result) - curlx_free(reader); - return result; -} - -void Curl_creader_free(struct Curl_easy *data, struct Curl_creader *reader) -{ - if(reader) { - reader->crt->do_close(data, reader); - curlx_free(reader); - } -} - -struct cr_lc_ctx { - struct Curl_creader super; - struct bufq buf; - BIT(read_eos); /* we read an EOS from the next reader */ - BIT(eos); /* we have returned an EOS */ - BIT(prev_cr); /* the last byte was a CR */ -}; - -static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader) -{ - struct cr_lc_ctx *ctx = reader->ctx; - (void)data; - Curl_bufq_init2(&ctx->buf, (16 * 1024), 1, BUFQ_OPT_SOFT_LIMIT); - return CURLE_OK; -} - -static void cr_lc_close(struct Curl_easy *data, struct Curl_creader *reader) -{ - struct cr_lc_ctx *ctx = reader->ctx; - (void)data; - Curl_bufq_free(&ctx->buf); -} - -/* client reader doing line end conversions. */ -static CURLcode cr_lc_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct cr_lc_ctx *ctx = reader->ctx; - CURLcode result; - size_t nread, i, start, n; - bool eos; - - if(ctx->eos) { - *pnread = 0; - *peos = TRUE; - return CURLE_OK; - } - - if(Curl_bufq_is_empty(&ctx->buf)) { - if(ctx->read_eos) { - ctx->eos = TRUE; - *pnread = 0; - *peos = TRUE; - return CURLE_OK; - } - /* Still getting data form the next reader, ctx->buf is empty */ - result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos); - if(result) - return result; - ctx->read_eos = eos; - - if(!nread || !memchr(buf, '\n', nread)) { - /* nothing to convert, return this right away */ - if(nread) - ctx->prev_cr = (buf[nread - 1] == '\r'); - if(ctx->read_eos) - ctx->eos = TRUE; - *pnread = nread; - *peos = (bool)ctx->eos; - goto out; - } - - /* at least one \n might need conversion to '\r\n', place into ctx->buf */ - for(i = start = 0; i < nread; ++i) { - /* if this byte is not an LF character, or if the preceding character is - a CR (meaning this already is a CRLF pair), go to next */ - if((buf[i] != '\n') || ctx->prev_cr) { - ctx->prev_cr = (buf[i] == '\r'); - continue; - } - ctx->prev_cr = FALSE; - /* on a soft limit bufq, we do not need to check length */ - result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n); - if(!result) - result = Curl_bufq_cwrite(&ctx->buf, STRCONST("\r\n"), &n); - if(result) - return result; - start = i + 1; - } - - if(start < i) { /* leftover */ - result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n); - if(result) - return result; - } - } - - DEBUGASSERT(!Curl_bufq_is_empty(&ctx->buf)); - *peos = FALSE; - result = Curl_bufq_cread(&ctx->buf, buf, blen, pnread); - if(!result && ctx->read_eos && Curl_bufq_is_empty(&ctx->buf)) { - /* no more data, read all, done. */ - ctx->eos = TRUE; - *peos = TRUE; - } - -out: - CURL_TRC_READ(data, "cr_lc_read(len=%zu) -> %d, nread=%zu, eos=%d", - blen, result, *pnread, *peos); - return result; -} - -static curl_off_t cr_lc_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - /* this reader changes length depending on input */ - (void)data; - (void)reader; - return -1; -} - -static const struct Curl_crtype cr_lc = { - "cr-lineconv", - cr_lc_init, - cr_lc_read, - cr_lc_close, - Curl_creader_def_needs_rewind, - cr_lc_total_length, - Curl_creader_def_resume_from, - Curl_creader_def_cntrl, - Curl_creader_def_is_paused, - Curl_creader_def_done, - sizeof(struct cr_lc_ctx) -}; - -static CURLcode cr_lc_add(struct Curl_easy *data) -{ - struct Curl_creader *reader = NULL; - CURLcode result; - - result = Curl_creader_create(&reader, data, &cr_lc, CURL_CR_CONTENT_ENCODE); - if(!result) - result = Curl_creader_add(data, reader); - - if(result && reader) - Curl_creader_free(data, reader); - return result; -} - -static CURLcode do_init_reader_stack(struct Curl_easy *data, - struct Curl_creader *r) -{ - CURLcode result = CURLE_OK; - curl_off_t clen; - - DEBUGASSERT(r); - DEBUGASSERT(r->crt); - DEBUGASSERT(r->phase == CURL_CR_CLIENT); - DEBUGASSERT(!data->req.reader_stack); - - data->req.reader_stack = r; - clen = r->crt->total_length(data, r); - /* if we do not have 0 length init, and crlf conversion is wanted, - * add the reader for it */ - if(clen && (data->set.crlf -#ifdef CURL_PREFER_LF_LINEENDS - || data->state.prefer_ascii -#endif - )) { - result = cr_lc_add(data); - if(result) - return result; - } - - return result; -} - -CURLcode Curl_creader_set_fread(struct Curl_easy *data, curl_off_t len) -{ - CURLcode result; - struct Curl_creader *r; - struct cr_in_ctx *ctx; - - result = Curl_creader_create(&r, data, &cr_in, CURL_CR_CLIENT); - if(result || !r) - goto out; - ctx = r->ctx; - ctx->total_len = len; - - cl_reset_reader(data); - result = do_init_reader_stack(data, r); -out: - CURL_TRC_READ(data, "add fread reader, len=%" FMT_OFF_T " -> %d", - len, result); - return result; -} - -CURLcode Curl_creader_add(struct Curl_easy *data, - struct Curl_creader *reader) -{ - CURLcode result; - struct Curl_creader **anchor = &data->req.reader_stack; - - if(!*anchor) { - result = Curl_creader_set_fread(data, data->state.infilesize); - if(result) - return result; - } - - /* Insert the writer as first in its phase. - * Skip existing readers of lower phases. */ - while(*anchor && (*anchor)->phase < reader->phase) - anchor = &((*anchor)->next); - reader->next = *anchor; - *anchor = reader; - return CURLE_OK; -} - -CURLcode Curl_creader_set(struct Curl_easy *data, struct Curl_creader *r) -{ - CURLcode result; - - DEBUGASSERT(r); - DEBUGASSERT(r->crt); - DEBUGASSERT(r->phase == CURL_CR_CLIENT); - - cl_reset_reader(data); - result = do_init_reader_stack(data, r); - if(result) - Curl_creader_free(data, r); - return result; -} - -CURLcode Curl_client_read(struct Curl_easy *data, char *buf, size_t blen, - size_t *nread, bool *eos) -{ - CURLcode result; - - DEBUGASSERT(buf); - DEBUGASSERT(blen); - DEBUGASSERT(nread); - DEBUGASSERT(eos); - *nread = 0; - - if(!data->req.reader_stack) { - result = Curl_creader_set_fread(data, data->state.infilesize); - if(result) - return result; - DEBUGASSERT(data->req.reader_stack); - } - if(!data->req.reader_started) { - Curl_rlimit_start(&data->progress.ul.rlimit, Curl_pgrs_now(data), -1); - data->req.reader_started = TRUE; - } - - if(Curl_rlimit_active(&data->progress.ul.rlimit)) { - curl_off_t ul_avail = Curl_rlimit_avail(&data->progress.ul.rlimit, - Curl_pgrs_now(data)); - if(ul_avail <= 0) { - result = CURLE_OK; - *eos = FALSE; - goto out; - } - if(ul_avail < (curl_off_t)blen) - blen = (size_t)ul_avail; - } - result = Curl_creader_read(data, data->req.reader_stack, buf, blen, - nread, eos); - -out: - CURL_TRC_READ(data, "client_read(len=%zu) -> %d, nread=%zu, eos=%d", - blen, result, *nread, *eos); - return result; -} - -bool Curl_creader_needs_rewind(struct Curl_easy *data) -{ - struct Curl_creader *reader = data->req.reader_stack; - while(reader) { - if(reader->crt->needs_rewind(data, reader)) { - CURL_TRC_READ(data, "client reader needs rewind before next request"); - return TRUE; - } - reader = reader->next; - } - return FALSE; -} - -static CURLcode cr_null_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - (void)data; - (void)reader; - (void)buf; - (void)blen; - *pnread = 0; - *peos = TRUE; - return CURLE_OK; -} - -static curl_off_t cr_null_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - /* this reader changes length depending on input */ - (void)data; - (void)reader; - return 0; -} - -static const struct Curl_crtype cr_null = { - "cr-null", - Curl_creader_def_init, - cr_null_read, - Curl_creader_def_close, - Curl_creader_def_needs_rewind, - cr_null_total_length, - Curl_creader_def_resume_from, - Curl_creader_def_cntrl, - Curl_creader_def_is_paused, - Curl_creader_def_done, - sizeof(struct Curl_creader) -}; - -CURLcode Curl_creader_set_null(struct Curl_easy *data) -{ - struct Curl_creader *r; - CURLcode result; - - result = Curl_creader_create(&r, data, &cr_null, CURL_CR_CLIENT); - if(result) - return result; - - cl_reset_reader(data); - return do_init_reader_stack(data, r); -} - -struct cr_buf_ctx { - struct Curl_creader super; - const char *buf; - size_t blen; - size_t index; -}; - -static CURLcode cr_buf_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct cr_buf_ctx *ctx = reader->ctx; - size_t nread = ctx->blen - ctx->index; - - if(!nread || !ctx->buf) { - *pnread = 0; - *peos = TRUE; - } - else { - if(nread > blen) - nread = blen; - memcpy(buf, ctx->buf + ctx->index, nread); - *pnread = nread; - ctx->index += nread; - *peos = (ctx->index == ctx->blen); - } - CURL_TRC_READ(data, "cr_buf_read(len=%zu) -> 0, nread=%zu, eos=%d", - blen, *pnread, *peos); - return CURLE_OK; -} - -static bool cr_buf_needs_rewind(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_buf_ctx *ctx = reader->ctx; - (void)data; - return ctx->index > 0; -} - -static CURLcode cr_buf_cntrl(struct Curl_easy *data, - struct Curl_creader *reader, - Curl_creader_cntrl opcode) -{ - struct cr_buf_ctx *ctx = reader->ctx; - (void)data; - switch(opcode) { - case CURL_CRCNTRL_REWIND: - ctx->index = 0; - break; - default: - break; - } - return CURLE_OK; -} - -static curl_off_t cr_buf_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_buf_ctx *ctx = reader->ctx; - (void)data; - return (curl_off_t)ctx->blen; -} - -static CURLcode cr_buf_resume_from(struct Curl_easy *data, - struct Curl_creader *reader, - curl_off_t offset) -{ - struct cr_buf_ctx *ctx = reader->ctx; - size_t boffset; - - (void)data; - DEBUGASSERT(data->conn); - /* already started reading? */ - if(ctx->index) - return CURLE_READ_ERROR; - boffset = curlx_sotouz_range(offset, 0, SIZE_MAX); - if(!boffset) - return CURLE_OK; - if(boffset > ctx->blen) - return CURLE_READ_ERROR; - - ctx->buf += boffset; - ctx->blen -= boffset; - return CURLE_OK; -} - -static const struct Curl_crtype cr_buf = { - "cr-buf", - Curl_creader_def_init, - cr_buf_read, - Curl_creader_def_close, - cr_buf_needs_rewind, - cr_buf_total_length, - cr_buf_resume_from, - cr_buf_cntrl, - Curl_creader_def_is_paused, - Curl_creader_def_done, - sizeof(struct cr_buf_ctx) -}; - -CURLcode Curl_creader_set_buf(struct Curl_easy *data, - const char *buf, size_t blen) -{ - CURLcode result; - struct Curl_creader *r; - struct cr_buf_ctx *ctx; - - result = Curl_creader_create(&r, data, &cr_buf, CURL_CR_CLIENT); - if(result) - goto out; - ctx = r->ctx; - ctx->buf = buf; - ctx->blen = blen; - ctx->index = 0; - - cl_reset_reader(data); - result = do_init_reader_stack(data, r); -out: - CURL_TRC_READ(data, "add buf reader, len=%zu -> %d", blen, result); - return result; -} - -curl_off_t Curl_creader_total_length(struct Curl_easy *data) -{ - struct Curl_creader *r = data->req.reader_stack; - return r ? r->crt->total_length(data, r) : -1; -} - -curl_off_t Curl_creader_client_length(struct Curl_easy *data) -{ - struct Curl_creader *r = data->req.reader_stack; - while(r && r->phase != CURL_CR_CLIENT) - r = r->next; - return r ? r->crt->total_length(data, r) : -1; -} - -CURLcode Curl_creader_resume_from(struct Curl_easy *data, curl_off_t offset) -{ - struct Curl_creader *r = data->req.reader_stack; - while(r && r->phase != CURL_CR_CLIENT) - r = r->next; - return r ? r->crt->resume_from(data, r, offset) : CURLE_READ_ERROR; -} - -CURLcode Curl_creader_unpause(struct Curl_easy *data) -{ - struct Curl_creader *reader = data->req.reader_stack; - CURLcode result = CURLE_OK; - - while(reader) { - result = reader->crt->cntrl(data, reader, CURL_CRCNTRL_UNPAUSE); - CURL_TRC_READ(data, "unpausing %s -> %d", reader->crt->name, result); - if(result) - break; - reader = reader->next; - } - return result; -} - -bool Curl_creader_is_paused(struct Curl_easy *data) -{ - struct Curl_creader *reader = data->req.reader_stack; - - while(reader) { - if(reader->crt->is_paused(data, reader)) - return TRUE; - reader = reader->next; - } - return FALSE; -} - -void Curl_creader_done(struct Curl_easy *data, int premature) -{ - struct Curl_creader *reader = data->req.reader_stack; - while(reader) { - reader->crt->done(data, reader, premature); - reader = reader->next; - } -} - -struct Curl_creader *Curl_creader_get_by_type(struct Curl_easy *data, - const struct Curl_crtype *crt) -{ - struct Curl_creader *r; - for(r = data->req.reader_stack; r; r = r->next) { - if(r->crt == crt) - return r; - } - return NULL; -} diff --git a/vendor/curl/lib/sendf.h b/vendor/curl/lib/sendf.h deleted file mode 100644 index 75c6e248e..000000000 --- a/vendor/curl/lib/sendf.h +++ /dev/null @@ -1,423 +0,0 @@ -#ifndef HEADER_CURL_SENDF_H -#define HEADER_CURL_SENDF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/** - * Type of data that is being written to the client (application) - * - data written can be either BODY or META data - * - META data is either INFO or HEADER - * - INFO is meta information, e.g. not BODY, that cannot be interpreted - * as headers of a response. Example FTP/IMAP pingpong answers. - * - HEADER can have additional bits set (more than one) - * - STATUS special "header", e.g. response status line in HTTP - * - CONNECT header was received during proxying the connection - * - 1XX header is part of an intermediate response, e.g. HTTP 1xx code - * - TRAILER header is trailing response data, e.g. HTTP trailers - * BODY, INFO and HEADER should not be mixed, as this would lead to - * confusion on how to interpret/format/convert the data. - */ -#define CLIENTWRITE_BODY (1 << 0) /* non-meta information, BODY */ -#define CLIENTWRITE_INFO (1 << 1) /* meta information, not a HEADER */ -#define CLIENTWRITE_HEADER (1 << 2) /* meta information, HEADER */ -#define CLIENTWRITE_STATUS (1 << 3) /* a special status HEADER */ -#define CLIENTWRITE_CONNECT (1 << 4) /* a CONNECT related HEADER */ -#define CLIENTWRITE_1XX (1 << 5) /* a 1xx response related HEADER */ -#define CLIENTWRITE_TRAILER (1 << 6) /* a trailer HEADER */ -#define CLIENTWRITE_EOS (1 << 7) /* End Of transfer download Stream */ -#define CLIENTWRITE_0LEN (1 << 8) /* write even 0-length buffers */ - -/* Forward declarations */ -struct Curl_creader; -struct Curl_cwriter; -struct Curl_easy; - -/** - * Write `len` bytes at `buf` to the client. `type` indicates what - * kind of data is being written. - */ -CURLcode Curl_client_write(struct Curl_easy *data, int type, const char *buf, - size_t len) WARN_UNUSED_RESULT; - -/** - * Free all resources related to client writing. - */ -void Curl_client_cleanup(struct Curl_easy *data); - -/** - * Reset readers and writer chains, keep rewind information - * when necessary. - */ -void Curl_client_reset(struct Curl_easy *data); - -/** - * A new request is starting, perform any ops like rewinding - * previous readers when needed. - */ -CURLcode Curl_client_start(struct Curl_easy *data); - -/** - * Client Writers - a chain passing transfer BODY data to the client. - * Main application: HTTP and related protocols - * Other uses: monitoring of download progress - * - * Writers in the chain are order by their `phase`. First come all - * writers in CURL_CW_RAW, followed by any in CURL_CW_TRANSFER_DECODE, - * followed by any in CURL_CW_PROTOCOL, etc. - * - * When adding a writer, it is inserted as first in its phase. This means - * the order of adding writers of the same phase matters, but writers for - * different phases may be added in any order. - * - * Writers which do modify the BODY data written are expected to be of - * phases TRANSFER_DECODE or CONTENT_DECODE. The other phases are intended - * for monitoring writers. Which do *not* modify the data but gather - * statistics or update progress reporting. - */ - -/* Phase a writer operates at. */ -typedef enum { - CURL_CW_RAW, /* raw data written, before any decoding */ - CURL_CW_TRANSFER_DECODE, /* remove transfer-encodings */ - CURL_CW_PROTOCOL, /* after transfer, but before content decoding */ - CURL_CW_CONTENT_DECODE, /* remove content-encodings */ - CURL_CW_CLIENT /* data written to client */ -} Curl_cwriter_phase; - -/* Client Writer Type, provides the implementation */ -struct Curl_cwtype { - const char *name; /* writer name. */ - const char *alias; /* writer name alias, maybe NULL. */ - CURLcode (*do_init)(struct Curl_easy *data, - struct Curl_cwriter *writer); - CURLcode (*do_write)(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes); - void (*do_close)(struct Curl_easy *data, - struct Curl_cwriter *writer); - size_t cwriter_size; /* sizeof() allocated struct Curl_cwriter */ -}; - -/* Client writer instance, allocated on creation. - * `void *ctx` is the pointer from the allocation of - * the `struct Curl_cwriter` itself. This is suitable for "downcasting" - * by the writers implementation. See https://github.com/curl/curl/pull/13054 - * for the alignment problems that arise otherwise. - */ -struct Curl_cwriter { - const struct Curl_cwtype *cwt; /* type implementation */ - struct Curl_cwriter *next; /* Downstream writer. */ - void *ctx; /* allocated instance pointer */ - Curl_cwriter_phase phase; /* phase at which it operates */ -}; - -/** - * Create a new cwriter instance with given type and phase. Is not - * inserted into the writer chain by this call. - * Invokes `writer->do_init()`. - */ -CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter, - struct Curl_easy *data, - const struct Curl_cwtype *cwt, - Curl_cwriter_phase phase); - -/** - * Free a cwriter instance. - * Invokes `writer->do_close()`. - */ -void Curl_cwriter_free(struct Curl_easy *data, - struct Curl_cwriter *writer); - -/** - * Count the number of writers installed of the given phase. - */ -size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase); - -/** - * Adds a writer to the transfer's writer chain. - * The writers `phase` determines where in the chain it is inserted. - */ -CURLcode Curl_cwriter_add(struct Curl_easy *data, - struct Curl_cwriter *writer); - -/** - * Look up an installed client writer on `data` by its type. - * @return first writer with that type or NULL - */ -struct Curl_cwriter *Curl_cwriter_get_by_type(struct Curl_easy *data, - const struct Curl_cwtype *cwt); - -struct Curl_cwriter *Curl_cwriter_get_by_name(struct Curl_easy *data, - const char *name); - -/** - * Convenience method for calling `writer->do_write()` that - * checks for NULL writer. - */ -CURLcode Curl_cwriter_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes); - -/** - * Return TRUE iff client writer is paused. - */ -bool Curl_cwriter_is_paused(struct Curl_easy *data); - -bool Curl_cwriter_is_content_decoding(struct Curl_easy *data); - -/** - * Unpause client writer and flush any buffered date to the client. - */ -CURLcode Curl_cwriter_unpause(struct Curl_easy *data); - -/** - * Default implementations for do_init, do_write, do_close that - * do nothing and pass the data through. - */ -CURLcode Curl_cwriter_def_init(struct Curl_easy *data, - struct Curl_cwriter *writer); -CURLcode Curl_cwriter_def_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes); -void Curl_cwriter_def_close(struct Curl_easy *data, - struct Curl_cwriter *writer); - -typedef enum { - CURL_CRCNTRL_REWIND, - CURL_CRCNTRL_UNPAUSE, - CURL_CRCNTRL_CLEAR_EOS -} Curl_creader_cntrl; - -/* Client Reader Type, provides the implementation */ -struct Curl_crtype { - const char *name; /* writer name. */ - CURLcode (*do_init)(struct Curl_easy *data, struct Curl_creader *reader); - CURLcode (*do_read)(struct Curl_easy *data, struct Curl_creader *reader, - char *buf, size_t blen, size_t *nread, bool *eos); - void (*do_close)(struct Curl_easy *data, struct Curl_creader *reader); - bool (*needs_rewind)(struct Curl_easy *data, struct Curl_creader *reader); - curl_off_t (*total_length)(struct Curl_easy *data, - struct Curl_creader *reader); - CURLcode (*resume_from)(struct Curl_easy *data, - struct Curl_creader *reader, curl_off_t offset); - CURLcode (*cntrl)(struct Curl_easy *data, struct Curl_creader *reader, - Curl_creader_cntrl opcode); - bool (*is_paused)(struct Curl_easy *data, struct Curl_creader *reader); - void (*done)(struct Curl_easy *data, - struct Curl_creader *reader, int premature); - size_t creader_size; /* sizeof() allocated struct Curl_creader */ -}; - -/* Phase a reader operates at. */ -typedef enum { - CURL_CR_NET, /* data send to the network (connection filters) */ - CURL_CR_TRANSFER_ENCODE, /* add transfer-encodings */ - CURL_CR_PROTOCOL, /* before transfer, but after content decoding */ - CURL_CR_CONTENT_ENCODE, /* add content-encodings */ - CURL_CR_CLIENT /* data read from client */ -} Curl_creader_phase; - -/* Client reader instance, allocated on creation. - * `void *ctx` is the pointer from the allocation of - * the `struct Curl_cwriter` itself. This is suitable for "downcasting" - * by the writers implementation. See https://github.com/curl/curl/pull/13054 - * for the alignment problems that arise otherwise. - */ -struct Curl_creader { - const struct Curl_crtype *crt; /* type implementation */ - struct Curl_creader *next; /* Downstream reader. */ - void *ctx; - Curl_creader_phase phase; /* phase at which it operates */ -}; - -/** - * Default implementations for do_init, do_write, do_close that - * do nothing and pass the data through. - */ -CURLcode Curl_creader_def_init(struct Curl_easy *data, - struct Curl_creader *reader); -void Curl_creader_def_close(struct Curl_easy *data, - struct Curl_creader *reader); -CURLcode Curl_creader_def_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *nread, bool *eos); -bool Curl_creader_def_needs_rewind(struct Curl_easy *data, - struct Curl_creader *reader); -curl_off_t Curl_creader_def_total_length(struct Curl_easy *data, - struct Curl_creader *reader); -CURLcode Curl_creader_def_resume_from(struct Curl_easy *data, - struct Curl_creader *reader, - curl_off_t offset); -CURLcode Curl_creader_def_cntrl(struct Curl_easy *data, - struct Curl_creader *reader, - Curl_creader_cntrl opcode); -bool Curl_creader_def_is_paused(struct Curl_easy *data, - struct Curl_creader *reader); -void Curl_creader_def_done(struct Curl_easy *data, - struct Curl_creader *reader, int premature); - -/** - * Convenience method for calling `reader->do_read()` that - * checks for NULL reader. - */ -CURLcode Curl_creader_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, size_t *nread, bool *eos); - -/* Tell the reader and all below that any EOS state is to be cleared */ -void Curl_creader_clear_eos(struct Curl_easy *data, - struct Curl_creader *reader); - -/** - * Create a new creader instance with given type and phase. Is not - * inserted into the writer chain by this call. - * Invokes `reader->do_init()`. - */ -CURLcode Curl_creader_create(struct Curl_creader **preader, - struct Curl_easy *data, - const struct Curl_crtype *crt, - Curl_creader_phase phase); - -/** - * Free a creader instance. - * Invokes `reader->do_close()`. - */ -void Curl_creader_free(struct Curl_easy *data, struct Curl_creader *reader); - -/** - * Adds a reader to the transfer's reader chain. - * The readers `phase` determines where in the chain it is inserted. - */ -CURLcode Curl_creader_add(struct Curl_easy *data, - struct Curl_creader *reader); - -/** - * Set the given reader, which needs to be of type CURL_CR_CLIENT, - * as the new first reader. Discard any installed readers and init - * the reader chain anew. - * The function takes ownership of `r`. - */ -CURLcode Curl_creader_set(struct Curl_easy *data, struct Curl_creader *r); - -/** - * Read at most `blen` bytes at `buf` from the client. - * @param data the transfer to read client bytes for - * @param buf the memory location to read to - * @param blen the amount of memory at `buf` - * @param nread on return the number of bytes read into `buf` - * @param eos TRUE iff bytes are the end of data from client - * @return CURLE_OK on successful read (even 0 length) or error - */ -CURLcode Curl_client_read(struct Curl_easy *data, char *buf, size_t blen, - size_t *nread, bool *eos) WARN_UNUSED_RESULT; - -/** - * TRUE iff client reader needs rewing before it can be used for - * a retry request. - */ -bool Curl_creader_needs_rewind(struct Curl_easy *data); - -/** - * TRUE iff client reader will rewind at next start - */ -bool Curl_creader_will_rewind(struct Curl_easy *data); - -/** - * En-/disable rewind of client reader at next start. - */ -void Curl_creader_set_rewind(struct Curl_easy *data, bool enable); - -/** - * Get the total length of bytes provided by the installed readers. - * This is independent of the amount already delivered and is calculated - * by all readers in the stack. If a reader like "chunked" or - * "crlf conversion" is installed, the returned length will be -1. - * @return -1 if length is indeterminate - */ -curl_off_t Curl_creader_total_length(struct Curl_easy *data); - -/** - * Get the total length of bytes provided by the reader at phase - * CURL_CR_CLIENT. This may not match the amount of bytes read - * for a request, depending if other, encoding readers are also installed. - * However it allows for rough estimation of the overall length. - * @return -1 if length is indeterminate - */ -curl_off_t Curl_creader_client_length(struct Curl_easy *data); - -/** - * Ask the installed reader at phase CURL_CR_CLIENT to start - * reading from the given offset. On success, this will reduce - * the `total_length()` by the amount. - * @param data the transfer to read client bytes for - * @param offset the offset where to start reads from, negative - * values will be ignored. - * @return CURLE_OK if offset could be set - * CURLE_READ_ERROR if not supported by reader or seek/read failed - * of offset larger then total length - * CURLE_PARTIAL_FILE if offset led to 0 total length - */ -CURLcode Curl_creader_resume_from(struct Curl_easy *data, curl_off_t offset); - -/** - * Unpause all installed readers. - */ -CURLcode Curl_creader_unpause(struct Curl_easy *data); - -/** - * Return TRUE iff any of the installed readers is paused. - */ -bool Curl_creader_is_paused(struct Curl_easy *data); - -/** - * Tell all client readers that they are done. - */ -void Curl_creader_done(struct Curl_easy *data, int premature); - -/** - * Look up an installed client reader on `data` by its type. - * @return first reader with that type or NULL - */ -struct Curl_creader *Curl_creader_get_by_type(struct Curl_easy *data, - const struct Curl_crtype *crt); - -/** - * Set the client reader to provide 0 bytes, immediate EOS. - */ -CURLcode Curl_creader_set_null(struct Curl_easy *data); - -/** - * Set the client reader the reads from fread callback. - */ -CURLcode Curl_creader_set_fread(struct Curl_easy *data, curl_off_t len); - -/** - * Set the client reader the reads from the supplied buf (NOT COPIED). - */ -CURLcode Curl_creader_set_buf(struct Curl_easy *data, - const char *buf, size_t blen); - -#endif /* HEADER_CURL_SENDF_H */ diff --git a/vendor/curl/lib/setopt.c b/vendor/curl/lib/setopt.c deleted file mode 100644 index b8a632748..000000000 --- a/vendor/curl/lib/setopt.c +++ /dev/null @@ -1,2933 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#ifdef HAVE_LINUX_TCP_H -#include -#elif defined(HAVE_NETINET_TCP_H) -#include -#endif - -#include "urldata.h" -#include "url.h" -#include "progress.h" -#include "content_encoding.h" -#include "strcase.h" -#include "curl_share.h" -#include "vtls/vtls.h" -#include "curl_trc.h" -#include "hostip.h" -#include "setopt.h" -#include "altsvc.h" -#include "hsts.h" -#include "tftp.h" -#include "curlx/strdup.h" -#include "escape.h" -#include "bufref.h" -#include "vauth/vauth.h" - -static CURLcode setopt_set_timeout_sec(timediff_t *ptimeout_ms, long secs) -{ - if(secs < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; -#if LONG_MAX > (TIMEDIFF_T_MAX / 1000) - if(secs > (TIMEDIFF_T_MAX / 1000)) { - *ptimeout_ms = TIMEDIFF_T_MAX; - return CURLE_OK; - } -#endif - *ptimeout_ms = (timediff_t)secs * 1000; - return CURLE_OK; -} - -static CURLcode setopt_set_timeout_ms(timediff_t *ptimeout_ms, long ms) -{ - if(ms < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; -#if LONG_MAX > TIMEDIFF_T_MAX - if(ms > TIMEDIFF_T_MAX) { - *ptimeout_ms = TIMEDIFF_T_MAX; - return CURLE_OK; - } -#endif - *ptimeout_ms = (timediff_t)ms; - return CURLE_OK; -} - -CURLcode Curl_setstropt(char **charp, const char *s) -{ - /* Release the previous storage at `charp' and replace by a dynamic storage - copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ - - curlx_safefree(*charp); - - if(s) { - if(strlen(s) > CURL_MAX_INPUT_LENGTH) - return CURLE_BAD_FUNCTION_ARGUMENT; - - *charp = curlx_strdup(s); - if(!*charp) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -CURLcode Curl_setblobopt(struct curl_blob **blobp, - const struct curl_blob *blob) -{ - /* free the previous storage at `blobp' and replace by a dynamic storage - copy of blob. If CURL_BLOB_COPY is set, the data is copied. */ - - curlx_safefree(*blobp); - - if(blob) { - struct curl_blob *nblob; - if(!blob->len || (blob->len > CURL_MAX_INPUT_LENGTH)) - return CURLE_BAD_FUNCTION_ARGUMENT; - nblob = (struct curl_blob *) - curlx_malloc(sizeof(struct curl_blob) + - ((blob->flags & CURL_BLOB_COPY) ? blob->len : 0)); - if(!nblob) - return CURLE_OUT_OF_MEMORY; - *nblob = *blob; - if(blob->flags & CURL_BLOB_COPY) { - /* put the data after the blob struct in memory */ - nblob->data = (char *)nblob + sizeof(struct curl_blob); - memcpy(nblob->data, blob->data, blob->len); - } - - *blobp = nblob; - return CURLE_OK; - } - - return CURLE_OK; -} - -static CURLcode setstropt_userpwd(const char *option, char **userp, - char **passwdp) -{ - char *user = NULL; - char *passwd = NULL; - - DEBUGASSERT(userp); - DEBUGASSERT(passwdp); - - /* Parse the login details if specified. If not, then we treat NULL as a - hint to clear the existing data */ - if(option) { - size_t len = strlen(option); - CURLcode result; - if(len > CURL_MAX_INPUT_LENGTH) - return CURLE_BAD_FUNCTION_ARGUMENT; - - result = Curl_parse_login_details(option, len, &user, &passwd, NULL); - if(result) - return result; - } - - curlx_free(*userp); - *userp = user; - - curlx_free(*passwdp); - *passwdp = passwd; - - return CURLE_OK; -} - -static CURLcode setstropt_interface(char *option, char **devp, - char **ifacep, char **hostp) -{ - char *dev = NULL; - char *iface = NULL; - char *host = NULL; - CURLcode result; - - DEBUGASSERT(devp); - DEBUGASSERT(ifacep); - DEBUGASSERT(hostp); - - if(option) { - /* Parse the interface details if set, otherwise clear them all */ - result = Curl_parse_interface(option, &dev, &iface, &host); - if(result) - return result; - } - curlx_free(*devp); - *devp = dev; - - curlx_free(*ifacep); - *ifacep = iface; - - curlx_free(*hostp); - *hostp = host; - - return CURLE_OK; -} - -#ifdef USE_SSL -#define C_SSLVERSION_VALUE(x) ((x) & 0xffff) -#define C_SSLVERSION_MAX_VALUE(x) ((unsigned long)(x) & 0xffff0000) -#endif - -static CURLcode protocol2num(const char *str, curl_prot_t *val) -{ - /* - * We are asked to cherry-pick protocols, so play it safe and disallow all - * protocols to start with, and re-add the wanted ones back in. - */ - *val = 0; - - if(!str) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(curl_strequal(str, "all")) { - *val = ~(curl_prot_t)0; - return CURLE_OK; - } - - do { - const char *token = str; - size_t tlen; - - str = strchr(str, ','); - tlen = str ? (size_t)(str - token) : strlen(token); - if(tlen) { - const struct Curl_scheme *h = Curl_getn_scheme(token, tlen); - - if(!h || !h->run) - return CURLE_UNSUPPORTED_PROTOCOL; - - *val |= h->protocol; - } - } while(str && str++); - - if(!*val) - /* no protocol listed */ - return CURLE_BAD_FUNCTION_ARGUMENT; - return CURLE_OK; -} - -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) -static CURLcode httpauth(struct Curl_easy *data, bool proxy, - unsigned long auth) -{ - if(auth != CURLAUTH_NONE) { - int bitcheck = 0; - bool authbits = FALSE; - /* the DIGEST_IE bit is only used to set a special marker, for all the - rest we need to handle it as normal DIGEST */ - bool iestyle = !!(auth & CURLAUTH_DIGEST_IE); - if(proxy) - data->state.authproxy.iestyle = iestyle; - else - data->state.authhost.iestyle = iestyle; - - if(auth & CURLAUTH_DIGEST_IE) { - auth |= CURLAUTH_DIGEST; /* set standard digest bit */ - auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ - } - - /* switch off bits we cannot support */ -#ifndef USE_NTLM - auth &= ~CURLAUTH_NTLM; /* no NTLM support */ -#endif -#ifndef USE_SPNEGO - auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without GSS-API - or SSPI */ -#endif - - /* check if any auth bit lower than CURLAUTH_ONLY is still set */ - while(bitcheck < 31) { - if(auth & (1UL << bitcheck++)) { - authbits = TRUE; - break; - } - } - if(!authbits) - return CURLE_NOT_BUILT_IN; /* no supported types left! */ - } - if(proxy) - data->set.proxyauth = (uint32_t)auth; - else - data->set.httpauth = (uint32_t)auth; - return CURLE_OK; -} -#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ - -#ifndef CURL_DISABLE_HTTP -static CURLcode setopt_HTTP_VERSION(struct Curl_easy *data, long arg) -{ - /* - * This sets a requested HTTP version to be used. The value is one of - * the listed enums in curl/curl.h. - */ - switch(arg) { - case CURL_HTTP_VERSION_NONE: - /* accepted */ - break; - case CURL_HTTP_VERSION_1_0: - case CURL_HTTP_VERSION_1_1: - /* accepted */ - break; -#ifdef USE_HTTP2 - case CURL_HTTP_VERSION_2_0: - case CURL_HTTP_VERSION_2TLS: - case CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE: - /* accepted */ - break; -#endif -#ifdef USE_HTTP3 - case CURL_HTTP_VERSION_3: - case CURL_HTTP_VERSION_3ONLY: - /* accepted */ - break; -#endif - default: - /* not accepted */ - if(arg < CURL_HTTP_VERSION_NONE) - return CURLE_BAD_FUNCTION_ARGUMENT; - return CURLE_UNSUPPORTED_PROTOCOL; - } - data->set.httpwant = (unsigned char)arg; - return CURLE_OK; -} -#endif /* !CURL_DISABLE_HTTP */ - -#ifdef USE_SSL -CURLcode Curl_setopt_SSLVERSION(struct Curl_easy *data, CURLoption option, - long arg) -{ - /* - * Set explicit SSL version to try to connect with, as some SSL - * implementations are lame. - */ - { - long version, version_max; - struct ssl_primary_config *primary = &data->set.ssl.primary; -#ifndef CURL_DISABLE_PROXY - if(option != CURLOPT_SSLVERSION) - primary = &data->set.proxy_ssl.primary; -#else - if(option) {} -#endif - version = C_SSLVERSION_VALUE(arg); - version_max = (long)C_SSLVERSION_MAX_VALUE(arg); - - if(version < CURL_SSLVERSION_DEFAULT || - version == CURL_SSLVERSION_SSLv2 || - version == CURL_SSLVERSION_SSLv3 || - version >= CURL_SSLVERSION_LAST || - version_max < CURL_SSLVERSION_MAX_NONE || - version_max >= CURL_SSLVERSION_MAX_LAST) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(version == CURL_SSLVERSION_DEFAULT) - version = CURL_SSLVERSION_TLSv1_2; - - primary->version = (unsigned char)version; - primary->version_max = (unsigned int)version_max; - } - return CURLE_OK; -} -#endif /* !USE_SSL */ - -#ifndef CURL_DISABLE_RTSP -static CURLcode setopt_RTSP_REQUEST(struct Curl_easy *data, long arg) -{ - /* - * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) Would this be - * better if the RTSPREQ_* were moved into here? - */ - Curl_RtspReq rtspreq = RTSPREQ_NONE; - switch(arg) { - case CURL_RTSPREQ_OPTIONS: - rtspreq = RTSPREQ_OPTIONS; - break; - case CURL_RTSPREQ_DESCRIBE: - rtspreq = RTSPREQ_DESCRIBE; - break; - case CURL_RTSPREQ_ANNOUNCE: - rtspreq = RTSPREQ_ANNOUNCE; - break; - case CURL_RTSPREQ_SETUP: - rtspreq = RTSPREQ_SETUP; - break; - case CURL_RTSPREQ_PLAY: - rtspreq = RTSPREQ_PLAY; - break; - case CURL_RTSPREQ_PAUSE: - rtspreq = RTSPREQ_PAUSE; - break; - case CURL_RTSPREQ_TEARDOWN: - rtspreq = RTSPREQ_TEARDOWN; - break; - case CURL_RTSPREQ_GET_PARAMETER: - rtspreq = RTSPREQ_GET_PARAMETER; - break; - case CURL_RTSPREQ_SET_PARAMETER: - rtspreq = RTSPREQ_SET_PARAMETER; - break; - case CURL_RTSPREQ_RECORD: - rtspreq = RTSPREQ_RECORD; - break; - case CURL_RTSPREQ_RECEIVE: - rtspreq = RTSPREQ_RECEIVE; - break; - default: - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - data->set.rtspreq = rtspreq; - return CURLE_OK; -} -#endif /* !CURL_DISABLE_RTSP */ - -#ifdef USE_SSL -static void set_ssl_options(struct ssl_config_data *ssl, - struct ssl_primary_config *config, - long arg) -{ - config->ssl_options = (unsigned char)(arg & 0xff); - ssl->enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST); - ssl->no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); - ssl->no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); - ssl->revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT); - ssl->native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA); - ssl->auto_client_cert = !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT); - ssl->earlydata = !!(arg & CURLSSLOPT_EARLYDATA); -} -#endif - -static CURLcode setopt_long_bool(struct Curl_easy *data, CURLoption option, - long arg) -{ - bool enabled = !!arg; - int ok = 1; - struct UserDefined *s = &data->set; - switch(option) { - case CURLOPT_FORBID_REUSE: - /* - * When this transfer is done, it must not be left to be reused by a - * subsequent transfer but shall be closed immediately. - */ - s->reuse_forbid = enabled; - break; - case CURLOPT_FRESH_CONNECT: - /* - * This transfer shall not use a previously cached connection but - * should be made with a fresh new connect! - */ - s->reuse_fresh = enabled; - break; - case CURLOPT_VERBOSE: - /* - * Verbose means infof() calls that give a lot of information about - * the connection and transfer procedures as well as internal choices. - */ - s->verbose = enabled; - break; - case CURLOPT_HEADER: - /* - * Set to include the header in the general data output stream. - */ - s->include_header = enabled; - break; - case CURLOPT_NOPROGRESS: - /* - * Shut off the internal supported progress meter - */ - data->progress.hide = enabled; - break; - case CURLOPT_NOBODY: - /* - * Do not include the body part in the output data stream. - */ - s->opt_no_body = enabled; -#ifndef CURL_DISABLE_HTTP - if(s->opt_no_body) - /* in HTTP lingo, no body means using the HEAD request... */ - s->method = HTTPREQ_HEAD; - else if(s->method == HTTPREQ_HEAD) - s->method = HTTPREQ_GET; -#endif - break; - case CURLOPT_FAILONERROR: - /* - * Do not output the >=400 error code HTML-page, but instead only - * return error. - */ - s->http_fail_on_error = enabled; - break; - case CURLOPT_KEEP_SENDING_ON_ERROR: - s->http_keep_sending_on_error = enabled; - break; - case CURLOPT_UPLOAD: - case CURLOPT_PUT: - /* - * We want to send data to the remote host. If this is HTTP, that equals - * using the PUT request. - */ - if(enabled) { - /* If this is HTTP, PUT is what's needed to "upload" */ - s->method = HTTPREQ_PUT; - s->opt_no_body = FALSE; /* this is implied */ - } - else - /* In HTTP, the opposite of upload is GET (unless NOBODY is true as - then this can be changed to HEAD later on) */ - s->method = HTTPREQ_GET; - break; - case CURLOPT_FILETIME: - /* - * Try to get the file time of the remote document. The time will - * later (possibly) become available using curl_easy_getinfo(). - */ - s->get_filetime = enabled; - break; -#ifndef CURL_DISABLE_HTTP - case CURLOPT_HTTP09_ALLOWED: - s->http09_allowed = enabled; - break; -#ifndef CURL_DISABLE_COOKIES - case CURLOPT_COOKIESESSION: - /* - * Set this option to TRUE to start a new "cookie session". It will - * prevent the forthcoming read-cookies-from-file actions to accept - * cookies that are marked as being session cookies, as they belong to a - * previous session. - */ - s->cookiesession = enabled; - break; -#endif - case CURLOPT_AUTOREFERER: - /* - * Switch on automatic referer that gets set if curl follows locations. - */ - s->http_auto_referer = enabled; - break; - case CURLOPT_TRANSFER_ENCODING: - s->http_transfer_encoding = enabled; - break; - case CURLOPT_UNRESTRICTED_AUTH: - /* - * Send authentication (user+password) when following locations, even when - * hostname changed. - */ - s->allow_auth_to_other_hosts = enabled; - break; - case CURLOPT_HTTP_TRANSFER_DECODING: - /* - * disable libcurl transfer encoding is used - */ - s->http_te_skip = !enabled; /* reversed */ - break; - case CURLOPT_HTTP_CONTENT_DECODING: - /* - * raw data passed to the application when content encoding is used - */ - s->http_ce_skip = !enabled; /* reversed */ - break; - case CURLOPT_HTTPGET: - /* - * Set to force us do HTTP GET - */ - if(enabled) { - s->method = HTTPREQ_GET; - s->opt_no_body = FALSE; /* this is implied */ - } - break; - case CURLOPT_POST: - /* Does this option serve a purpose anymore? Yes it does, when - CURLOPT_POSTFIELDS is not used and the POST data is read off the - callback! */ - if(enabled) { - s->method = HTTPREQ_POST; - s->opt_no_body = FALSE; /* this is implied */ - } - else - s->method = HTTPREQ_GET; - break; -#endif /* !CURL_DISABLE_HTTP */ -#ifndef CURL_DISABLE_PROXY - case CURLOPT_HTTPPROXYTUNNEL: - /* - * Tunnel operations through the proxy instead of normal proxy use - */ - s->tunnel_thru_httpproxy = enabled; - break; - case CURLOPT_HAPROXYPROTOCOL: - /* - * Set to send the HAProxy Proxy Protocol header - */ - s->haproxyprotocol = enabled; - break; - case CURLOPT_PROXY_SSL_VERIFYPEER: - /* - * Enable peer SSL verifying for proxy. - */ - s->proxy_ssl.primary.verifypeer = enabled; - - /* Update the current connection proxy_ssl_config. */ - Curl_ssl_conn_config_update(data, TRUE); - break; - case CURLOPT_PROXY_SSL_VERIFYHOST: - /* - * Enable verification of the hostname in the peer certificate for proxy - */ - s->proxy_ssl.primary.verifyhost = enabled; - ok = 2; - /* Update the current connection proxy_ssl_config. */ - Curl_ssl_conn_config_update(data, TRUE); - break; - case CURLOPT_PROXY_TRANSFER_MODE: - /* - * set transfer mode (;type=) when doing FTP via an HTTP proxy - */ - s->proxy_transfer_mode = enabled; - break; -#endif /* !CURL_DISABLE_PROXY */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - case CURLOPT_SOCKS5_GSSAPI_NEC: - /* - * Set flag for NEC SOCKS5 support - */ - s->socks5_gssapi_nec = enabled; - break; -#endif -#ifdef CURL_LIST_ONLY_PROTOCOL - case CURLOPT_DIRLISTONLY: - /* - * An option that changes the command to one that asks for a list only, no - * file info details. Used for FTP, POP3 and SFTP. - */ - s->list_only = enabled; - break; -#endif - case CURLOPT_APPEND: - /* - * We want to upload and append to an existing file. Used for FTP and - * SFTP. - */ - s->remote_append = enabled; - break; -#ifndef CURL_DISABLE_FTP - case CURLOPT_FTP_USE_EPRT: - s->ftp_use_eprt = enabled; - break; - case CURLOPT_FTP_USE_EPSV: - s->ftp_use_epsv = enabled; - break; - case CURLOPT_FTP_USE_PRET: - s->ftp_use_pret = enabled; - break; - case CURLOPT_FTP_SKIP_PASV_IP: - /* - * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the - * bypass of the IP address in PASV responses. - */ - s->ftp_skip_ip = enabled; - break; - case CURLOPT_WILDCARDMATCH: - s->wildcard_enabled = enabled; - break; -#endif - case CURLOPT_CRLF: - /* - * Kludgy option to enable CRLF conversions. Subject for removal. - */ - s->crlf = enabled; - break; -#ifndef CURL_DISABLE_TFTP - case CURLOPT_TFTP_NO_OPTIONS: - /* - * Option that prevents libcurl from sending TFTP option requests to the - * server. - */ - s->tftp_no_options = enabled; - break; -#endif /* !CURL_DISABLE_TFTP */ - case CURLOPT_TRANSFERTEXT: - /* - * This option was previously named 'FTPASCII'. Renamed to work with - * more protocols than merely FTP. - * - * Transfer using ASCII (instead of BINARY). - */ - s->prefer_ascii = enabled; - break; - case CURLOPT_SSL_VERIFYPEER: - /* - * Enable peer SSL verifying. - */ - s->ssl.primary.verifypeer = enabled; - - /* Update the current connection ssl_config. */ - Curl_ssl_conn_config_update(data, FALSE); - break; -#ifndef CURL_DISABLE_DOH - case CURLOPT_DOH_SSL_VERIFYPEER: - /* - * Enable peer SSL verifying for DoH. - */ - s->doh_verifypeer = enabled; - break; - case CURLOPT_DOH_SSL_VERIFYHOST: - /* - * Enable verification of the hostname in the peer certificate for DoH - */ - s->doh_verifyhost = enabled; - ok = 2; - break; - case CURLOPT_DOH_SSL_VERIFYSTATUS: - /* - * Enable certificate status verifying for DoH. - */ - if(!Curl_ssl_cert_status_request()) - return CURLE_NOT_BUILT_IN; - - s->doh_verifystatus = enabled; - ok = 2; - break; -#endif /* !CURL_DISABLE_DOH */ - case CURLOPT_SSL_VERIFYHOST: - /* - * Enable verification of the hostname in the peer certificate - */ - - /* Obviously people are not reading documentation and too many thought - this argument took a boolean when it was not and misused it. - Treat 1 and 2 the same */ - s->ssl.primary.verifyhost = enabled; - ok = 2; - - /* Update the current connection ssl_config. */ - Curl_ssl_conn_config_update(data, FALSE); - break; - case CURLOPT_SSL_VERIFYSTATUS: - /* - * Enable certificate status verifying. - */ - if(!Curl_ssl_cert_status_request()) - return CURLE_NOT_BUILT_IN; - - s->ssl.primary.verifystatus = enabled; - - /* Update the current connection ssl_config. */ - Curl_ssl_conn_config_update(data, FALSE); - break; - case CURLOPT_CERTINFO: -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CERTINFO)) - s->ssl.certinfo = enabled; - else -#endif - return CURLE_NOT_BUILT_IN; - break; - case CURLOPT_NOSIGNAL: - /* - * The application asks not to set any signal() or alarm() handlers, - * even when using a timeout. - */ - s->no_signal = enabled; - break; - case CURLOPT_TCP_NODELAY: - /* - * Enable or disable TCP_NODELAY, which will disable/enable the Nagle - * algorithm - */ - s->tcp_nodelay = enabled; - break; - case CURLOPT_IGNORE_CONTENT_LENGTH: - s->ignorecl = enabled; - break; - case CURLOPT_SSL_SESSIONID_CACHE: - s->ssl.primary.cache_session = enabled; -#ifndef CURL_DISABLE_PROXY - s->proxy_ssl.primary.cache_session = s->ssl.primary.cache_session; -#endif - break; -#ifdef USE_SSH - case CURLOPT_SSH_COMPRESSION: - s->ssh_compression = enabled; - break; -#endif /* !USE_SSH */ -#ifndef CURL_DISABLE_SMTP - case CURLOPT_MAIL_RCPT_ALLOWFAILS: - /* allow RCPT TO command to fail for some recipients */ - s->mail_rcpt_allowfails = enabled; - break; -#endif /* !CURL_DISABLE_SMTP */ - case CURLOPT_SASL_IR: - /* Enable/disable SASL initial response */ - s->sasl_ir = enabled; - break; - case CURLOPT_TCP_KEEPALIVE: - s->tcp_keepalive = enabled; - break; - case CURLOPT_TCP_FASTOPEN: -#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \ - defined(TCP_FASTOPEN_CONNECT) - s->tcp_fastopen = enabled; - break; -#else - return CURLE_NOT_BUILT_IN; -#endif - case CURLOPT_SSL_ENABLE_ALPN: - s->ssl_enable_alpn = enabled; - break; - case CURLOPT_PATH_AS_IS: - s->path_as_is = enabled; - break; - case CURLOPT_PIPEWAIT: - s->pipewait = enabled; - break; - case CURLOPT_SUPPRESS_CONNECT_HEADERS: - s->suppress_connect_headers = enabled; - break; -#ifndef CURL_DISABLE_SHUFFLE_DNS - case CURLOPT_DNS_SHUFFLE_ADDRESSES: - s->dns_shuffle_addresses = enabled; - break; -#endif - case CURLOPT_DISALLOW_USERNAME_IN_URL: - s->disallow_username_in_url = enabled; - break; - case CURLOPT_QUICK_EXIT: - s->quick_exit = enabled; - break; - default: - return CURLE_UNKNOWN_OPTION; - } - if((arg > ok) || (arg < 0)) - /* reserve other values for future use */ - infof(data, "boolean setopt(%d) got unsupported argument %ld," - " treated as %d", option, arg, enabled); - - return CURLE_OK; -} - -static CURLcode value_range(long *value, long below_error, long min, long max) -{ - if(*value < below_error) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if(*value < min) - *value = min; - else if(*value > max) - *value = max; - return CURLE_OK; -} - -static CURLcode setopt_long_net(struct Curl_easy *data, CURLoption option, - long arg) -{ - CURLcode result = CURLE_OK; - struct UserDefined *s = &data->set; - - switch(option) { - case CURLOPT_DNS_CACHE_TIMEOUT: - if(arg != -1) - return setopt_set_timeout_sec(&s->dns_cache_timeout_ms, arg); - s->dns_cache_timeout_ms = -1; - break; - case CURLOPT_MAXCONNECTS: - result = value_range(&arg, 1, 1, INT_MAX); - if(!result) - s->maxconnects = (uint32_t)arg; - break; - case CURLOPT_SERVER_RESPONSE_TIMEOUT: - return setopt_set_timeout_sec(&s->server_response_timeout, arg); - case CURLOPT_SERVER_RESPONSE_TIMEOUT_MS: - return setopt_set_timeout_ms(&s->server_response_timeout, arg); - case CURLOPT_LOW_SPEED_LIMIT: - if(arg < 0) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->low_speed_limit = arg; - break; - case CURLOPT_LOW_SPEED_TIME: - result = value_range(&arg, 0, 0, USHRT_MAX); - if(!result) - s->low_speed_time = (uint16_t)arg; - break; - case CURLOPT_PORT: - if((arg < 0) || (arg > 65535)) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->use_port = (unsigned short)arg; - break; - case CURLOPT_TIMEOUT: - return setopt_set_timeout_sec(&s->timeout, arg); - case CURLOPT_TIMEOUT_MS: - return setopt_set_timeout_ms(&s->timeout, arg); - case CURLOPT_CONNECTTIMEOUT: - return setopt_set_timeout_sec(&s->connecttimeout, arg); - case CURLOPT_CONNECTTIMEOUT_MS: - return setopt_set_timeout_ms(&s->connecttimeout, arg); -#ifndef CURL_DISABLE_BINDLOCAL - case CURLOPT_LOCALPORT: - if((arg < 0) || (arg > 65535)) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->localport = curlx_sltous(arg); - break; - case CURLOPT_LOCALPORTRANGE: - if((arg < 0) || (arg > 65535)) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->localportrange = curlx_sltous(arg); - break; -#endif - case CURLOPT_BUFFERSIZE: - result = value_range(&arg, 0, READBUFFER_MIN, READBUFFER_MAX); - if(!result) - s->buffer_size = (unsigned int)arg; - break; - case CURLOPT_UPLOAD_BUFFERSIZE: - result = value_range(&arg, 0, UPLOADBUFFER_MIN, UPLOADBUFFER_MAX); - if(!result) - s->upload_buffer_size = (unsigned int)arg; - break; - case CURLOPT_MAXFILESIZE: - if(arg < 0) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->max_filesize = arg; - break; - case CURLOPT_IPRESOLVE: - if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->ipver = (unsigned char)arg; - break; - case CURLOPT_CONNECT_ONLY: - if(arg < 0 || arg > 2) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else { - s->connect_only = !!arg; - s->connect_only_ws = (arg == 2); - } - break; -#ifdef USE_IPV6 - case CURLOPT_ADDRESS_SCOPE: -#if SIZEOF_LONG > 4 - if((unsigned long)arg > UINT_MAX) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else -#endif - s->scope_id = (unsigned int)arg; - break; -#endif - case CURLOPT_TCP_KEEPIDLE: - result = value_range(&arg, 0, 0, INT_MAX); - if(!result) - s->tcp_keepidle = (int)arg; - break; - case CURLOPT_TCP_KEEPINTVL: - result = value_range(&arg, 0, 0, INT_MAX); - if(!result) - s->tcp_keepintvl = (int)arg; - break; - case CURLOPT_TCP_KEEPCNT: - result = value_range(&arg, 0, 0, INT_MAX); - if(!result) - s->tcp_keepcnt = (int)arg; - break; - case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS: - return setopt_set_timeout_ms(&s->happy_eyeballs_timeout, arg); - case CURLOPT_UPKEEP_INTERVAL_MS: - return setopt_set_timeout_ms(&s->upkeep_interval_ms, arg); - case CURLOPT_MAXAGE_CONN: - return setopt_set_timeout_sec(&s->conn_max_idle_ms, arg); - case CURLOPT_MAXLIFETIME_CONN: - return setopt_set_timeout_sec(&s->conn_max_age_ms, arg); - case CURLOPT_DNS_USE_GLOBAL_CACHE: - /* deprecated */ - break; - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -} - -static CURLcode setopt_long_ssl(struct Curl_easy *data, CURLoption option, - long arg) -{ -#ifdef USE_SSL - CURLcode result = CURLE_OK; - struct UserDefined *s = &data->set; - switch(option) { - case CURLOPT_CA_CACHE_TIMEOUT: - if(Curl_ssl_supports(data, SSLSUPP_CA_CACHE)) { - result = value_range(&arg, -1, -1, INT_MAX); - if(!result) - s->general_ssl.ca_cache_timeout = (int)arg; - } - else - result = CURLE_NOT_BUILT_IN; - break; - case CURLOPT_SSLVERSION: -#ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXY_SSLVERSION: -#endif - return Curl_setopt_SSLVERSION(data, option, arg); - case CURLOPT_SSL_FALSESTART: - result = CURLE_NOT_BUILT_IN; - break; - case CURLOPT_USE_SSL: - if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->use_ssl = (unsigned char)arg; - break; - case CURLOPT_SSL_OPTIONS: - set_ssl_options(&s->ssl, &s->ssl.primary, arg); - break; -#ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXY_SSL_OPTIONS: - set_ssl_options(&s->proxy_ssl, &s->proxy_ssl.primary, arg); - break; -#endif - case CURLOPT_SSL_ENABLE_NPN: - break; - case CURLOPT_SSLENGINE_DEFAULT: - curlx_safefree(s->str[STRING_SSL_ENGINE]); - result = Curl_ssl_set_engine_default(data); - break; - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -#else /* USE_SSL */ - (void)data; - (void)option; - (void)arg; - return CURLE_UNKNOWN_OPTION; -#endif /* !USE_SSL */ -} - -static CURLcode setopt_long_proxy(struct Curl_easy *data, CURLoption option, - long arg) -{ -#ifndef CURL_DISABLE_PROXY - struct UserDefined *s = &data->set; - - switch(option) { - case CURLOPT_PROXYPORT: - if((arg < 0) || (arg > UINT16_MAX)) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->proxyport = (uint16_t)arg; - break; - case CURLOPT_PROXYAUTH: - return httpauth(data, TRUE, (unsigned long)arg); - case CURLOPT_PROXYTYPE: - if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME)) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->proxytype = (unsigned char)arg; - break; - case CURLOPT_SOCKS5_AUTH: - if(arg & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) - return CURLE_NOT_BUILT_IN; - s->socks5auth = (unsigned char)arg; - break; - default: - return CURLE_UNKNOWN_OPTION; - } - return CURLE_OK; -#else - (void)data; - (void)option; - (void)arg; - return CURLE_UNKNOWN_OPTION; -#endif -} - -static CURLcode setopt_long_http(struct Curl_easy *data, CURLoption option, - long arg) -{ -#ifndef CURL_DISABLE_HTTP - CURLcode result = CURLE_OK; - struct UserDefined *s = &data->set; - - switch(option) { - case CURLOPT_FOLLOWLOCATION: - if((unsigned long)arg > 3) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->http_follow_mode = (unsigned char)arg; - break; - case CURLOPT_MAXREDIRS: - result = value_range(&arg, -1, -1, 0x7fff); - if(!result) - s->maxredirs = (short)arg; - break; - case CURLOPT_POSTREDIR: - if(arg < CURL_REDIR_GET_ALL) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else { - s->post301 = !!(arg & CURL_REDIR_POST_301); - s->post302 = !!(arg & CURL_REDIR_POST_302); - s->post303 = !!(arg & CURL_REDIR_POST_303); - } - break; - case CURLOPT_HEADEROPT: - s->sep_headers = !!(arg & CURLHEADER_SEPARATE); - break; - case CURLOPT_HTTPAUTH: - return httpauth(data, FALSE, (unsigned long)arg); - case CURLOPT_HTTP_VERSION: - return setopt_HTTP_VERSION(data, arg); - case CURLOPT_EXPECT_100_TIMEOUT_MS: - result = value_range(&arg, 0, 0, 0xffff); - if(!result) - s->expect_100_timeout = (unsigned short)arg; - break; - case CURLOPT_STREAM_WEIGHT: -#if defined(USE_HTTP2) || defined(USE_HTTP3) - if((arg >= 1) && (arg <= 256)) - s->priority.weight = (int)arg; - break; -#else - result = CURLE_NOT_BUILT_IN; - break; -#endif - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -#else - (void)data; - (void)option; - (void)arg; - return CURLE_UNKNOWN_OPTION; -#endif -} - -static CURLcode setopt_long_proto(struct Curl_easy *data, CURLoption option, - long arg) -{ - CURLcode result = CURLE_OK; - struct UserDefined *s = &data->set; - - switch(option) { -#ifndef CURL_DISABLE_TFTP - case CURLOPT_TFTP_BLKSIZE: - result = value_range(&arg, 0, TFTP_BLKSIZE_MIN, TFTP_BLKSIZE_MAX); - if(!result) - s->tftp_blksize = (unsigned short)arg; - break; -#endif -#ifndef CURL_DISABLE_NETRC - case CURLOPT_NETRC: - if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->use_netrc = (unsigned char)arg; - break; -#endif -#ifndef CURL_DISABLE_FTP - case CURLOPT_FTP_FILEMETHOD: - if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->ftp_filemethod = (unsigned char)arg; - break; - case CURLOPT_FTP_SSL_CCC: - if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->ftp_ccc = (unsigned char)arg; - break; - case CURLOPT_FTPSSLAUTH: - if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->ftpsslauth = (unsigned char)arg; - break; - case CURLOPT_ACCEPTTIMEOUT_MS: - return setopt_set_timeout_ms(&s->accepttimeout, arg); -#endif -#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) - case CURLOPT_FTP_CREATE_MISSING_DIRS: - if((arg < CURLFTP_CREATE_DIR_NONE) || (arg > CURLFTP_CREATE_DIR_RETRY)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->ftp_create_missing_dirs = (unsigned char)arg; - break; - case CURLOPT_NEW_FILE_PERMS: - if((arg < 0) || (arg > 0777)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->new_file_perms = (unsigned int)arg; - break; -#endif -#ifndef CURL_DISABLE_RTSP - case CURLOPT_RTSP_REQUEST: - return setopt_RTSP_REQUEST(data, arg); - case CURLOPT_RTSP_CLIENT_CSEQ: - result = value_range(&arg, 0, 0, INT_MAX); - if(!result) - data->state.rtsp_next_client_CSeq = (uint32_t)arg; - break; - case CURLOPT_RTSP_SERVER_CSEQ: - result = value_range(&arg, 0, 0, INT_MAX); - if(!result) - data->state.rtsp_next_server_CSeq = (uint32_t)arg; - break; -#endif -#ifdef USE_SSH - case CURLOPT_SSH_AUTH_TYPES: - s->ssh_auth_types = (uint32_t)arg; - break; - case CURLOPT_NEW_DIRECTORY_PERMS: - if((arg < 0) || (arg > 0777)) - result = CURLE_BAD_FUNCTION_ARGUMENT; - else - s->new_directory_perms = (unsigned int)arg; - break; -#endif - case CURLOPT_PROTOCOLS: - s->allowed_protocols = (curl_prot_t)arg; - break; - case CURLOPT_REDIR_PROTOCOLS: - s->redir_protocols = (curl_prot_t)arg; - break; -#ifndef CURL_DISABLE_WEBSOCKETS - case CURLOPT_WS_OPTIONS: - s->ws_raw_mode = (bool)(arg & CURLWS_RAW_MODE); - s->ws_no_auto_pong = (bool)(arg & CURLWS_NOAUTOPONG); - break; -#endif - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -} - -static CURLcode setopt_long_misc(struct Curl_easy *data, CURLoption option, - long arg) -{ - struct UserDefined *s = &data->set; - - switch(option) { - case CURLOPT_TIMECONDITION: - if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST)) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->timecondition = (unsigned char)arg; - break; - case CURLOPT_TIMEVALUE: - s->timevalue = (time_t)arg; - break; - case CURLOPT_POSTFIELDSIZE: - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(s->postfieldsize < arg && - s->postfields == s->str[STRING_COPYPOSTFIELDS]) { - curlx_safefree(s->str[STRING_COPYPOSTFIELDS]); - s->postfields = NULL; - } - s->postfieldsize = arg; - break; - case CURLOPT_INFILESIZE: - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->filesize = arg; - break; - case CURLOPT_RESUME_FROM: - if(arg < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->set_resume_from = arg; - break; - case CURLOPT_UPLOAD_FLAGS: - s->upload_flags = (unsigned char)arg; - break; -#ifndef CURL_DISABLE_MIME - case CURLOPT_MIME_OPTIONS: - s->mime_formescape = !!(arg & CURLMIMEOPT_FORMESCAPE); - break; -#endif -#ifndef CURL_DISABLE_HSTS - case CURLOPT_HSTS_CTRL: - if(arg & CURLHSTS_ENABLE) { - if(!data->hsts) { - data->hsts = Curl_hsts_init(); - if(!data->hsts) - return CURLE_OUT_OF_MEMORY; - } - } - else - Curl_hsts_cleanup(&data->hsts); - break; -#endif -#ifndef CURL_DISABLE_ALTSVC - case CURLOPT_ALTSVC_CTRL: - return Curl_altsvc_ctrl(data, arg); -#endif -#ifdef HAVE_GSSAPI - case CURLOPT_GSSAPI_DELEGATION: - s->gssapi_delegation = (unsigned char)arg & - (CURLGSSAPI_DELEGATION_POLICY_FLAG | CURLGSSAPI_DELEGATION_FLAG); - break; -#endif - default: - return CURLE_UNKNOWN_OPTION; - } - return CURLE_OK; -} - -static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, - long arg) -{ - typedef CURLcode (*setoptfunc)(struct Curl_easy *data, - CURLoption option, long arg); - static const setoptfunc setopt_call[] = { - setopt_long_bool, - setopt_long_net, - setopt_long_http, - setopt_long_proxy, - setopt_long_ssl, - setopt_long_proto, - setopt_long_misc - }; - size_t i; - - for(i = 0; i < CURL_ARRAYSIZE(setopt_call); i++) { - CURLcode result = setopt_call[i](data, option, arg); - if(result != CURLE_UNKNOWN_OPTION) - return result; - } - return CURLE_UNKNOWN_OPTION; -} - -static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option, - struct curl_slist *slist) -{ - CURLcode result = CURLE_OK; - struct UserDefined *s = &data->set; - switch(option) { -#ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXYHEADER: - /* - * Set a list with proxy headers to use (or replace internals with) - * - * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a - * long time we remain doing it this way until CURLOPT_PROXYHEADER is - * used. As soon as this option has been used, if set to anything but - * NULL, custom headers for proxies are only picked from this list. - * - * Set this option to NULL to restore the previous behavior. - */ - s->proxyheaders = slist; - break; -#endif -#ifndef CURL_DISABLE_HTTP - case CURLOPT_HTTP200ALIASES: - /* - * Set a list of aliases for HTTP 200 in response header - */ - s->http200aliases = slist; - break; -#endif -#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) - case CURLOPT_POSTQUOTE: - /* - * List of RAW FTP commands to use after a transfer - */ - s->postquote = slist; - break; - case CURLOPT_PREQUOTE: - /* - * List of RAW FTP commands to use prior to RETR (Wesley Laxton) - */ - s->prequote = slist; - break; - case CURLOPT_QUOTE: - /* - * List of RAW FTP commands to use before a transfer - */ - s->quote = slist; - break; -#endif - case CURLOPT_RESOLVE: - /* - * List of HOST:PORT:[addresses] strings to populate the DNS cache with - * Entries added this way will remain in the cache until explicitly - * removed or the handle is cleaned up. - * - * Prefix the HOST with plus sign (+) to have the entry expire like - * automatically added entries. - * - * Prefix the HOST with dash (-) to _remove_ the entry from the cache. - * - * This API can remove any entry from the DNS cache, but only entries - * that are not actually in use right now will be pruned immediately. - */ - s->resolve = slist; - data->state.resolve = s->resolve; - break; -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME) - case CURLOPT_HTTPHEADER: - /* - * Set a list with HTTP headers to use (or replace internals with) - */ - s->headers = slist; - break; -#endif -#ifndef CURL_DISABLE_TELNET - case CURLOPT_TELNETOPTIONS: - /* - * Set a linked list of telnet options - */ - s->telnet_options = slist; - break; -#endif -#ifndef CURL_DISABLE_SMTP - case CURLOPT_MAIL_RCPT: - /* Set the list of mail recipients */ - s->mail_rcpt = slist; - break; -#endif - case CURLOPT_CONNECT_TO: - s->connect_to = slist; - break; - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -} - -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_IMAP) -#ifndef CURL_DISABLE_MIME -static CURLcode setopt_mimepost(struct Curl_easy *data, curl_mime *mimep) -{ - /* - * Set to make us do MIME POST - */ - CURLcode result; - struct UserDefined *s = &data->set; - if(!s->mimepostp) { - s->mimepostp = curlx_malloc(sizeof(*s->mimepostp)); - if(!s->mimepostp) - return CURLE_OUT_OF_MEMORY; - Curl_mime_initpart(s->mimepostp); - } - - result = Curl_mime_set_subparts(s->mimepostp, mimep, FALSE); - if(!result) { - s->method = HTTPREQ_POST_MIME; - s->opt_no_body = FALSE; /* this is implied */ -#ifndef CURL_DISABLE_FORM_API - Curl_mime_cleanpart(data->state.formp); - curlx_safefree(data->state.formp); - data->state.mimepost = NULL; -#endif - } - return result; -} -#endif /* !CURL_DISABLE_MIME */ -#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */ - -/* assorted pointer type arguments */ -static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, - va_list param) -{ - CURLcode result = CURLE_OK; - struct UserDefined *s = &data->set; - switch(option) { - case CURLOPT_CURLU: - /* - * pass CURLU to set URL - */ - Curl_bufref_free(&data->state.url); - curlx_safefree(s->str[STRING_SET_URL]); - s->uh = va_arg(param, CURLU *); - break; -#ifndef CURL_DISABLE_HTTP -#ifndef CURL_DISABLE_FORM_API - case CURLOPT_HTTPPOST: - /* - * Set to make us do HTTP POST. Legacy API-style. - */ - s->httppost = va_arg(param, struct curl_httppost *); - s->method = HTTPREQ_POST_FORM; - s->opt_no_body = FALSE; /* this is implied */ - Curl_mime_cleanpart(data->state.formp); - curlx_safefree(data->state.formp); - data->state.mimepost = NULL; - break; -#endif /* !CURL_DISABLE_FORM_API */ -#endif /* !CURL_DISABLE_HTTP */ -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_IMAP) -#ifndef CURL_DISABLE_MIME - case CURLOPT_MIMEPOST: - result = setopt_mimepost(data, va_arg(param, curl_mime *)); - break; -#endif /* !CURL_DISABLE_MIME */ -#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */ - case CURLOPT_STDERR: - /* - * Set to a FILE * that should receive all error writes. This - * defaults to stderr for normal operations. - */ - s->err = va_arg(param, FILE *); - if(!s->err) - s->err = stderr; - break; - case CURLOPT_SHARE: { - struct Curl_share *set = va_arg(param, struct Curl_share *); - - /* disconnect from old share, if any and possible */ - result = Curl_share_easy_unlink(data); - if(result) - return result; - - /* use new share if it set */ - if(GOOD_SHARE_HANDLE(set)) { - result = Curl_share_easy_link(data, set); - if(result) - return result; - } - break; - } - -#ifdef USE_HTTP2 - case CURLOPT_STREAM_DEPENDS: - case CURLOPT_STREAM_DEPENDS_E: { - struct Curl_easy *dep = va_arg(param, struct Curl_easy *); - if(!dep || GOOD_EASY_HANDLE(dep)) - return Curl_data_priority_add_child(dep, data, - option == CURLOPT_STREAM_DEPENDS_E); - break; - } -#endif - - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -} - -#ifndef CURL_DISABLE_COOKIES -static CURLcode cookielist(struct Curl_easy *data, const char *ptr) -{ - CURLcode result = CURLE_OK; - if(!ptr) - return CURLE_OK; - - if(curl_strequal(ptr, "ALL")) { - /* clear all cookies */ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_clearall(data->cookies); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - else if(curl_strequal(ptr, "SESS")) { - /* clear session cookies */ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_clearsess(data->cookies); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - else if(curl_strequal(ptr, "FLUSH")) { - /* flush cookies to file, takes care of the locking */ - Curl_flush_cookies(data, FALSE); - } - else if(curl_strequal(ptr, "RELOAD")) { - /* reload cookies from file */ - return Curl_cookie_loadfiles(data); - } - else { - if(!data->cookies) { - /* if cookie engine was not running, activate it */ - data->cookies = Curl_cookie_init(); - if(!data->cookies) - return CURLE_OUT_OF_MEMORY; - data->state.cookie_engine = TRUE; - } - - /* general protection against mistakes and abuse */ - if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) - return CURLE_BAD_FUNCTION_ARGUMENT; - - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(checkprefix("Set-Cookie:", ptr)) - /* HTTP Header format line */ - result = Curl_cookie_add(data, data->cookies, TRUE, FALSE, ptr + 11, - NULL, NULL, TRUE); - else - /* Netscape format line */ - result = Curl_cookie_add(data, data->cookies, FALSE, FALSE, ptr, NULL, - NULL, TRUE); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - return result; -} - -static CURLcode cookiefile(struct Curl_easy *data, const char *ptr) -{ - /* - * Set cookie file to read and parse. Can be used multiple times. - */ - if(ptr) { - struct curl_slist *cl; - /* general protection against mistakes and abuse */ - if(strlen(ptr) > CURL_MAX_INPUT_LENGTH) - return CURLE_BAD_FUNCTION_ARGUMENT; - /* append the cookie filename to the list of filenames, and deal with - them later */ - cl = curl_slist_append(data->state.cookielist, ptr); - if(!cl) { - curl_slist_free_all(data->state.cookielist); - data->state.cookielist = NULL; - return CURLE_OUT_OF_MEMORY; - } - data->state.cookielist = cl; /* store the list for later use */ - } - else { - /* clear the list of cookie files */ - curl_slist_free_all(data->state.cookielist); - data->state.cookielist = NULL; - - if(!data->share || !data->share->cookies) { - /* throw away all existing cookies if this is not a shared cookie - container */ - Curl_cookie_clearall(data->cookies); - Curl_cookie_cleanup(data->cookies); - } - /* disable the cookie engine */ - data->cookies = NULL; - } - return CURLE_OK; -} -#endif - -#ifndef CURL_DISABLE_PROXY -static CURLcode setproxy(struct Curl_easy *data, const char *proxy) -{ - if((data->set.str[STRING_PROXY] && proxy) && - /* there was one set, is this a new one? */ - !strcmp(data->set.str[STRING_PROXY], proxy)) - return CURLE_OK; /* same one as before */ - - Curl_auth_digest_cleanup(&data->state.proxydigest); - memset(&data->state.authproxy, 0, sizeof(data->state.authproxy)); - return Curl_setstropt(&data->set.str[STRING_PROXY], proxy); -} - -static CURLcode setopt_cptr_proxy(struct Curl_easy *data, CURLoption option, - const char *ptr) -{ - CURLcode result = CURLE_OK; - struct UserDefined *s = &data->set; - switch(option) { - case CURLOPT_PROXYUSERPWD: { - /* - * user:password needed to use the proxy - */ - char *u = NULL; - char *p = NULL; - result = setstropt_userpwd(ptr, &u, &p); - - /* URL decode the components */ - if(!result && u) { - curlx_safefree(s->str[STRING_PROXYUSERNAME]); - result = Curl_urldecode(u, 0, &s->str[STRING_PROXYUSERNAME], NULL, - REJECT_ZERO); - } - if(!result && p) { - curlx_safefree(s->str[STRING_PROXYPASSWORD]); - result = Curl_urldecode(p, 0, &s->str[STRING_PROXYPASSWORD], NULL, - REJECT_ZERO); - } - curlx_free(u); - curlx_free(p); - break; - } - case CURLOPT_PROXYUSERNAME: - /* - * authentication username to use in the operation - */ - return Curl_setstropt(&s->str[STRING_PROXYUSERNAME], ptr); - - case CURLOPT_PROXYPASSWORD: - /* - * authentication password to use in the operation - */ - return Curl_setstropt(&s->str[STRING_PROXYPASSWORD], ptr); - - case CURLOPT_NOPROXY: - /* - * proxy exception list - */ - return Curl_setstropt(&s->str[STRING_NOPROXY], ptr); - case CURLOPT_PROXY_SSLCERT: - /* - * String that holds filename of the SSL certificate to use for proxy - */ - return Curl_setstropt(&s->str[STRING_CERT_PROXY], ptr); - case CURLOPT_PROXY_SSLCERTTYPE: - /* - * String that holds file type of the SSL certificate to use for proxy - */ - return Curl_setstropt(&s->str[STRING_CERT_TYPE_PROXY], ptr); - case CURLOPT_PROXY_SSLKEY: - /* - * String that holds filename of the SSL key to use for proxy - */ - return Curl_setstropt(&s->str[STRING_KEY_PROXY], ptr); - case CURLOPT_PROXY_KEYPASSWD: - /* - * String that holds the SSL private key password for proxy. - */ - return Curl_setstropt(&s->str[STRING_KEY_PASSWD_PROXY], ptr); - case CURLOPT_PROXY_SSLKEYTYPE: - /* - * String that holds file type of the SSL key to use for proxy - */ - return Curl_setstropt(&s->str[STRING_KEY_TYPE_PROXY], ptr); - case CURLOPT_PROXY_SSL_CIPHER_LIST: - if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) { - /* set a list of cipher we want to use in the SSL connection for proxy */ - return Curl_setstropt(&s->str[STRING_SSL_CIPHER_LIST_PROXY], ptr); - } - else - return CURLE_NOT_BUILT_IN; - case CURLOPT_PROXY_TLS13_CIPHERS: - if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES)) - /* set preferred list of TLS 1.3 cipher suites for proxy */ - return Curl_setstropt(&s->str[STRING_SSL_CIPHER13_LIST_PROXY], ptr); - else - return CURLE_NOT_BUILT_IN; - case CURLOPT_PROXY: - /* - * Set proxy server:port to use as proxy. - * - * If the proxy is set to "" (and CURLOPT_PRE_PROXY is set to "" or NULL) - * we explicitly say that we do not want to use a proxy (even though there - * might be environment variables saying so). - * - * Setting it to NULL, means no proxy but allows the environment variables - * to decide for us (if CURLOPT_PRE_PROXY setting it to NULL). - */ - return setproxy(data, ptr); - case CURLOPT_PRE_PROXY: - /* - * Set proxy server:port to use as SOCKS proxy. - * - * If the proxy is set to "" or NULL we explicitly say that we do not want - * to use the socks proxy. - */ - return Curl_setstropt(&s->str[STRING_PRE_PROXY], ptr); - case CURLOPT_SOCKS5_GSSAPI_SERVICE: - case CURLOPT_PROXY_SERVICE_NAME: - /* - * Set proxy authentication service name for Kerberos 5 and SPNEGO - */ - return Curl_setstropt(&s->str[STRING_PROXY_SERVICE_NAME], ptr); - case CURLOPT_PROXY_PINNEDPUBLICKEY: - /* - * Set pinned public key for SSL connection. - * Specify filename of the public key in DER format. - */ -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY)) - return Curl_setstropt(&s->str[STRING_SSL_PINNEDPUBLICKEY_PROXY], ptr); -#endif - return CURLE_NOT_BUILT_IN; - - case CURLOPT_HAPROXY_CLIENT_IP: - /* - * Set the client IP to send through HAProxy PROXY protocol - */ - result = Curl_setstropt(&s->str[STRING_HAPROXY_CLIENT_IP], ptr); - - /* enable the HAProxy protocol if an IP is provided */ - s->haproxyprotocol = !!s->str[STRING_HAPROXY_CLIENT_IP]; - break; - case CURLOPT_PROXY_CAINFO: - /* - * Set CA info SSL connection for proxy. Specify filename of the - * CA certificate - */ - s->proxy_ssl.custom_cafile = TRUE; - return Curl_setstropt(&s->str[STRING_SSL_CAFILE_PROXY], ptr); - case CURLOPT_PROXY_CRLFILE: - /* - * Set CRL file info for SSL connection for proxy. Specify filename of the - * CRL to check certificates revocation - */ - return Curl_setstropt(&s->str[STRING_SSL_CRLFILE_PROXY], ptr); - case CURLOPT_PROXY_ISSUERCERT: - /* - * Set Issuer certificate file - * to check certificates issuer - */ - return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT_PROXY], ptr); - case CURLOPT_PROXY_CAPATH: - /* - * Set CA path info for SSL connection proxy. Specify directory name of the - * CA certificates which have been prepared using openssl c_rehash utility. - */ -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) { - /* This does not work on Windows. */ - s->proxy_ssl.custom_capath = TRUE; - return Curl_setstropt(&s->str[STRING_SSL_CAPATH_PROXY], ptr); - } -#endif - return CURLE_NOT_BUILT_IN; - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -} -#endif - -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT) -/* - * A string with POST data. Makes curl HTTP POST. Even if it is NULL. If - * needed, CURLOPT_POSTFIELDSIZE must have been set prior to - * CURLOPT_COPYPOSTFIELDS and not altered later. - */ -static CURLcode setopt_copypostfields(const char *ptr, struct UserDefined *s) -{ - CURLcode result = CURLE_OK; - if(!ptr || s->postfieldsize == -1) - result = Curl_setstropt(&s->str[STRING_COPYPOSTFIELDS], ptr); - else { - size_t pflen; - - if(s->postfieldsize < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - pflen = curlx_sotouz_range(s->postfieldsize, 0, SIZE_MAX); - if(pflen == SIZE_MAX) - return CURLE_OUT_OF_MEMORY; - else { - /* Allocate even when size == 0. This satisfies the need of possible - later address compare to detect the COPYPOSTFIELDS mode, and to mark - that postfields is used rather than read function or form data. - */ - char *p = curlx_memdup0(ptr, pflen); - if(!p) - return CURLE_OUT_OF_MEMORY; - else { - curlx_free(s->str[STRING_COPYPOSTFIELDS]); - s->str[STRING_COPYPOSTFIELDS] = p; - } - } - } - - s->postfields = s->str[STRING_COPYPOSTFIELDS]; - s->method = HTTPREQ_POST; - return result; -} -#endif - -static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, - char *ptr) -{ - CURLcode result; - struct UserDefined *s = &data->set; -#ifndef CURL_DISABLE_PROXY - result = setopt_cptr_proxy(data, option, ptr); - if(result != CURLE_UNKNOWN_OPTION) - return result; -#endif - result = CURLE_OK; - - switch(option) { - case CURLOPT_CAINFO: - /* - * Set CA info for SSL connection. Specify filename of the CA certificate - */ - s->ssl.custom_cafile = TRUE; - return Curl_setstropt(&s->str[STRING_SSL_CAFILE], ptr); - case CURLOPT_CAPATH: - /* - * Set CA path info for SSL connection. Specify directory name of the CA - * certificates which have been prepared using openssl c_rehash utility. - */ -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) { - /* This does not work on Windows. */ - s->ssl.custom_capath = TRUE; - return Curl_setstropt(&s->str[STRING_SSL_CAPATH], ptr); - } -#endif - return CURLE_NOT_BUILT_IN; - case CURLOPT_CRLFILE: - /* - * Set CRL file info for SSL connection. Specify filename of the CRL - * to check certificates revocation - */ - if(Curl_ssl_supports(data, SSLSUPP_CRLFILE)) - return Curl_setstropt(&s->str[STRING_SSL_CRLFILE], ptr); - return CURLE_NOT_BUILT_IN; - case CURLOPT_SSL_CIPHER_LIST: - if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) - /* set a list of cipher we want to use in the SSL connection */ - return Curl_setstropt(&s->str[STRING_SSL_CIPHER_LIST], ptr); - else - return CURLE_NOT_BUILT_IN; - case CURLOPT_TLS13_CIPHERS: - if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES)) { - /* set preferred list of TLS 1.3 cipher suites */ - return Curl_setstropt(&s->str[STRING_SSL_CIPHER13_LIST], ptr); - } - else - return CURLE_NOT_BUILT_IN; - case CURLOPT_RANDOM_FILE: - break; - case CURLOPT_EGDSOCKET: - break; - case CURLOPT_REQUEST_TARGET: - return Curl_setstropt(&s->str[STRING_TARGET], ptr); -#ifndef CURL_DISABLE_NETRC - case CURLOPT_NETRC_FILE: - /* - * Use this file instead of the $HOME/.netrc file - */ - return Curl_setstropt(&s->str[STRING_NETRC_FILE], ptr); -#endif - -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT) - case CURLOPT_COPYPOSTFIELDS: - return setopt_copypostfields(ptr, s); - - case CURLOPT_POSTFIELDS: - /* - * Like above, but use static data instead of copying it. - */ - s->postfields = ptr; - /* Release old copied data. */ - curlx_safefree(s->str[STRING_COPYPOSTFIELDS]); - s->method = HTTPREQ_POST; - break; -#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_MQTT */ - -#ifndef CURL_DISABLE_HTTP - case CURLOPT_TRAILERDATA: - s->trailer_data = ptr; - break; - case CURLOPT_ACCEPT_ENCODING: - /* - * String to use at the value of Accept-Encoding header. - * - * If the encoding is set to "" we use an Accept-Encoding header that - * encompasses all the encodings we support. - * If the encoding is set to NULL we do not send an Accept-Encoding header - * and ignore an received Content-Encoding header. - * - */ - if(ptr && !*ptr) { - ptr = Curl_get_content_encodings(); - if(ptr) { - curlx_free(s->str[STRING_ENCODING]); - s->str[STRING_ENCODING] = ptr; - } - else - result = CURLE_OUT_OF_MEMORY; - return result; - } - return Curl_setstropt(&s->str[STRING_ENCODING], ptr); - -#ifndef CURL_DISABLE_AWS - case CURLOPT_AWS_SIGV4: - /* - * String that is merged to some authentication - * parameters are used by the algorithm. - */ - result = Curl_setstropt(&s->str[STRING_AWS_SIGV4], ptr); - /* - * Basic been set by default it need to be unset here - */ - if(s->str[STRING_AWS_SIGV4]) - s->httpauth = CURLAUTH_AWS_SIGV4; - break; -#endif - case CURLOPT_REFERER: - /* - * String to set in the HTTP Referer: field. - */ - result = Curl_setstropt(&s->str[STRING_SET_REFERER], ptr); - break; - - case CURLOPT_USERAGENT: - /* - * String to use in the HTTP User-Agent field - */ - return Curl_setstropt(&s->str[STRING_USERAGENT], ptr); - -#ifndef CURL_DISABLE_COOKIES - case CURLOPT_COOKIE: - /* - * Cookie string to send to the remote server in the request. - */ - return Curl_setstropt(&s->str[STRING_COOKIE], ptr); - - case CURLOPT_COOKIEFILE: - return cookiefile(data, ptr); - - case CURLOPT_COOKIEJAR: - /* - * Set cookie filename to dump all cookies to when we are done. - */ - result = Curl_setstropt(&s->str[STRING_COOKIEJAR], ptr); - if(!result) { - /* - * Activate the cookie parser. This may or may not already - * have been made. - */ - if(!data->cookies) - data->cookies = Curl_cookie_init(); - if(!data->cookies) - result = CURLE_OUT_OF_MEMORY; - else - data->state.cookie_engine = TRUE; - } - break; - - case CURLOPT_COOKIELIST: - return cookielist(data, ptr); -#endif /* !CURL_DISABLE_COOKIES */ - -#endif /* !CURL_DISABLE_HTTP */ - - case CURLOPT_CUSTOMREQUEST: - /* - * Set a custom string to use as request - */ - return Curl_setstropt(&s->str[STRING_CUSTOMREQUEST], ptr); - - /* we do not set s->method = HTTPREQ_CUSTOM; here, we continue as if we - were using the already set type and this changes the actual request - keyword */ - case CURLOPT_SERVICE_NAME: - /* - * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO - */ - return Curl_setstropt(&s->str[STRING_SERVICE_NAME], ptr); - - case CURLOPT_HEADERDATA: - /* - * Custom pointer to pass the header write callback function - */ - s->writeheader = ptr; - break; - case CURLOPT_READDATA: - /* - * FILE pointer to read the file to be uploaded from. Or possibly used as - * argument to the read callback. - */ - s->in_set = ptr; - break; - case CURLOPT_WRITEDATA: - /* - * FILE pointer to write to. Or possibly used as argument to the write - * callback. - */ - s->out = ptr; - break; - case CURLOPT_DEBUGDATA: - /* - * Set to a void * that should receive all error writes. This - * defaults to CURLOPT_STDERR for normal operations. - */ - s->debugdata = ptr; - break; - case CURLOPT_PROGRESSDATA: - /* - * Custom client data to pass to the progress callback - */ - s->progress_client = ptr; - break; - case CURLOPT_SEEKDATA: - /* - * Seek control callback. Might be NULL. - */ - s->seek_client = ptr; - break; - case CURLOPT_IOCTLDATA: - /* - * I/O control data pointer. Might be NULL. - */ - s->ioctl_client = ptr; - break; - case CURLOPT_SSL_CTX_DATA: - /* - * Set an SSL_CTX callback parameter pointer - */ -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) { - s->ssl.fsslctxp = ptr; - break; - } - else -#endif - return CURLE_NOT_BUILT_IN; - case CURLOPT_SOCKOPTDATA: - /* - * socket callback data pointer. Might be NULL. - */ - s->sockopt_client = ptr; - break; - case CURLOPT_OPENSOCKETDATA: - /* - * socket callback data pointer. Might be NULL. - */ - s->opensocket_client = ptr; - break; - case CURLOPT_RESOLVER_START_DATA: - /* - * resolver start callback data pointer. Might be NULL. - */ - s->resolver_start_client = ptr; - break; - case CURLOPT_CLOSESOCKETDATA: - /* - * socket callback data pointer. Might be NULL. - */ - s->closesocket_client = ptr; - break; - case CURLOPT_PREREQDATA: - s->prereq_userp = ptr; - break; - case CURLOPT_ERRORBUFFER: - /* - * Error buffer provided by the caller to get the human readable error - * string in. - */ - s->errorbuffer = ptr; - break; - -#ifndef CURL_DISABLE_FTP - case CURLOPT_FTPPORT: - /* - * Use FTP PORT, this also specifies which IP address to use - */ - result = Curl_setstropt(&s->str[STRING_FTPPORT], ptr); - s->ftp_use_port = !!(s->str[STRING_FTPPORT]); - break; - - case CURLOPT_FTP_ACCOUNT: - return Curl_setstropt(&s->str[STRING_FTP_ACCOUNT], ptr); - - case CURLOPT_FTP_ALTERNATIVE_TO_USER: - return Curl_setstropt(&s->str[STRING_FTP_ALTERNATIVE_TO_USER], ptr); - - case CURLOPT_KRBLEVEL: - return CURLE_NOT_BUILT_IN; /* removed in 8.17.0 */ - case CURLOPT_CHUNK_DATA: - s->wildcardptr = ptr; - break; - case CURLOPT_FNMATCH_DATA: - s->fnmatch_data = ptr; - break; -#endif - case CURLOPT_URL: - /* - * The URL to fetch. - */ - result = Curl_setstropt(&s->str[STRING_SET_URL], ptr); - Curl_bufref_set(&data->state.url, s->str[STRING_SET_URL], 0, NULL); - break; - - case CURLOPT_USERPWD: - /* - * user:password to use in the operation - */ - return setstropt_userpwd(ptr, &s->str[STRING_USERNAME], - &s->str[STRING_PASSWORD]); - - case CURLOPT_USERNAME: - /* - * authentication username to use in the operation - */ - return Curl_setstropt(&s->str[STRING_USERNAME], ptr); - - case CURLOPT_PASSWORD: - /* - * authentication password to use in the operation - */ - return Curl_setstropt(&s->str[STRING_PASSWORD], ptr); - - case CURLOPT_LOGIN_OPTIONS: - /* - * authentication options to use in the operation - */ - return Curl_setstropt(&s->str[STRING_OPTIONS], ptr); - - case CURLOPT_XOAUTH2_BEARER: - /* - * OAuth 2.0 bearer token to use in the operation - */ - return Curl_setstropt(&s->str[STRING_BEARER], ptr); - case CURLOPT_RANGE: - /* - * What range of the file you want to transfer - */ - return Curl_setstropt(&s->str[STRING_SET_RANGE], ptr); - case CURLOPT_SSLCERT: - /* - * String that holds filename of the SSL certificate to use - */ - return Curl_setstropt(&s->str[STRING_CERT], ptr); - case CURLOPT_SSLCERTTYPE: - /* - * String that holds file type of the SSL certificate to use - */ - return Curl_setstropt(&s->str[STRING_CERT_TYPE], ptr); - case CURLOPT_SSLKEY: - /* - * String that holds filename of the SSL key to use - */ - return Curl_setstropt(&s->str[STRING_KEY], ptr); - case CURLOPT_SSLKEYTYPE: - /* - * String that holds file type of the SSL key to use - */ - return Curl_setstropt(&s->str[STRING_KEY_TYPE], ptr); - case CURLOPT_KEYPASSWD: - /* - * String that holds the SSL or SSH private key password. - */ - return Curl_setstropt(&s->str[STRING_KEY_PASSWD], ptr); - case CURLOPT_SSLENGINE: - /* - * String that holds the SSL crypto engine. - */ - if(ptr && ptr[0]) { - result = Curl_setstropt(&s->str[STRING_SSL_ENGINE], ptr); - if(!result) { - result = Curl_ssl_set_engine(data, ptr); - } - } - break; - case CURLOPT_INTERFACE: - /* - * Set what interface or address/hostname to bind the socket to when - * performing an operation and thus what from-IP your connection will use. - */ - return setstropt_interface(ptr, - &s->str[STRING_DEVICE], - &s->str[STRING_INTERFACE], - &s->str[STRING_BINDHOST]); - case CURLOPT_ISSUERCERT: - /* - * Set Issuer certificate file - * to check certificates issuer - */ - if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT)) - return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT], ptr); - return CURLE_NOT_BUILT_IN; - case CURLOPT_PRIVATE: - /* - * Set private data pointer. - */ - s->private_data = ptr; - break; -#ifdef USE_SSL - case CURLOPT_SSL_EC_CURVES: - /* - * Set accepted curves in SSL connection setup. - * Specify colon-delimited list of curve algorithm names. - */ - if(Curl_ssl_supports(data, SSLSUPP_SSL_EC_CURVES)) - return Curl_setstropt(&s->str[STRING_SSL_EC_CURVES], ptr); - return CURLE_NOT_BUILT_IN; - case CURLOPT_SSL_SIGNATURE_ALGORITHMS: - /* - * Set accepted signature algorithms. - * Specify colon-delimited list of signature scheme names. - */ - if(Curl_ssl_supports(data, SSLSUPP_SIGNATURE_ALGORITHMS)) - return Curl_setstropt(&s->str[STRING_SSL_SIGNATURE_ALGORITHMS], ptr); - return CURLE_NOT_BUILT_IN; - case CURLOPT_PINNEDPUBLICKEY: - /* - * Set pinned public key for SSL connection. - * Specify filename of the public key in DER format. - */ - if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY)) - return Curl_setstropt(&s->str[STRING_SSL_PINNEDPUBLICKEY], ptr); - return CURLE_NOT_BUILT_IN; -#endif -#ifdef USE_SSH - case CURLOPT_SSH_PUBLIC_KEYFILE: - /* - * Use this file instead of the $HOME/.ssh/id_dsa.pub file - */ - return Curl_setstropt(&s->str[STRING_SSH_PUBLIC_KEY], ptr); - case CURLOPT_SSH_PRIVATE_KEYFILE: - /* - * Use this file instead of the $HOME/.ssh/id_dsa file - */ - return Curl_setstropt(&s->str[STRING_SSH_PRIVATE_KEY], ptr); - case CURLOPT_SSH_KEYDATA: - /* - * Custom client data to pass to the SSH keyfunc callback - */ - s->ssh_keyfunc_userp = ptr; - break; -#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) - case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: - /* - * Option to allow for the MD5 of the host public key to be checked - * for validation purposes. - */ - return Curl_setstropt(&s->str[STRING_SSH_HOST_PUBLIC_KEY_MD5], ptr); - case CURLOPT_SSH_KNOWNHOSTS: - /* - * Store the filename to read known hosts from. - */ - return Curl_setstropt(&s->str[STRING_SSH_KNOWNHOSTS], ptr); -#endif -#ifdef USE_LIBSSH2 - case CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256: - /* - * Option to allow for the SHA256 of the host public key to be checked - * for validation purposes. - */ - return Curl_setstropt(&s->str[STRING_SSH_HOST_PUBLIC_KEY_SHA256], ptr); - case CURLOPT_SSH_HOSTKEYDATA: - /* - * Custom client data to pass to the SSH keyfunc callback - */ - s->ssh_hostkeyfunc_userp = ptr; - break; -#endif /* USE_LIBSSH2 */ -#endif /* USE_SSH */ - case CURLOPT_PROTOCOLS_STR: - if(ptr) { - curl_prot_t protos; - result = protocol2num(ptr, &protos); - if(!result) - s->allowed_protocols = protos; - } - else - /* make a NULL argument reset to default */ - s->allowed_protocols = (curl_prot_t)CURLPROTO_64ALL; - break; - case CURLOPT_REDIR_PROTOCOLS_STR: - if(ptr) { - curl_prot_t protos; - result = protocol2num(ptr, &protos); - if(!result) - s->redir_protocols = protos; - } - else - /* make a NULL argument reset to default */ - s->redir_protocols = (curl_prot_t)CURLPROTO_REDIR; - break; - case CURLOPT_DEFAULT_PROTOCOL: - /* Set the protocol to use when the URL does not include any protocol */ - return Curl_setstropt(&s->str[STRING_DEFAULT_PROTOCOL], ptr); -#ifndef CURL_DISABLE_SMTP - case CURLOPT_MAIL_FROM: - /* Set the SMTP mail originator */ - return Curl_setstropt(&s->str[STRING_MAIL_FROM], ptr); - case CURLOPT_MAIL_AUTH: - /* Set the SMTP auth originator */ - return Curl_setstropt(&s->str[STRING_MAIL_AUTH], ptr); -#endif - case CURLOPT_SASL_AUTHZID: - /* Authorization identity (identity to act as) */ - return Curl_setstropt(&s->str[STRING_SASL_AUTHZID], ptr); -#ifndef CURL_DISABLE_RTSP - case CURLOPT_RTSP_SESSION_ID: - /* - * Set the RTSP Session ID manually. Useful if the application is - * resuming a previously established RTSP session - */ - return Curl_setstropt(&s->str[STRING_RTSP_SESSION_ID], ptr); - case CURLOPT_RTSP_STREAM_URI: - /* - * Set the Stream URI for the RTSP request. Unless the request is - * for generic server options, the application will need to set this. - */ - return Curl_setstropt(&s->str[STRING_RTSP_STREAM_URI], ptr); - case CURLOPT_RTSP_TRANSPORT: - /* - * The content of the Transport: header for the RTSP request - */ - return Curl_setstropt(&s->str[STRING_RTSP_TRANSPORT], ptr); - case CURLOPT_INTERLEAVEDATA: - s->rtp_out = ptr; - break; -#endif /* !CURL_DISABLE_RTSP */ -#ifdef USE_TLS_SRP - case CURLOPT_TLSAUTH_USERNAME: - return Curl_setstropt(&s->str[STRING_TLSAUTH_USERNAME], ptr); - case CURLOPT_TLSAUTH_PASSWORD: - return Curl_setstropt(&s->str[STRING_TLSAUTH_PASSWORD], ptr); - case CURLOPT_TLSAUTH_TYPE: - if(ptr && !curl_strequal(ptr, "SRP")) - result = CURLE_BAD_FUNCTION_ARGUMENT; - break; -#ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXY_TLSAUTH_USERNAME: - return Curl_setstropt(&s->str[STRING_TLSAUTH_USERNAME_PROXY], ptr); - case CURLOPT_PROXY_TLSAUTH_PASSWORD: - return Curl_setstropt(&s->str[STRING_TLSAUTH_PASSWORD_PROXY], ptr); - case CURLOPT_PROXY_TLSAUTH_TYPE: - if(ptr && !curl_strequal(ptr, "SRP")) - result = CURLE_BAD_FUNCTION_ARGUMENT; - break; -#endif -#endif -#ifdef USE_RESOLV_ARES - case CURLOPT_DNS_SERVERS: - return Curl_setstropt(&s->str[STRING_DNS_SERVERS], ptr); - - case CURLOPT_DNS_INTERFACE: - return Curl_setstropt(&s->str[STRING_DNS_INTERFACE], ptr); - - case CURLOPT_DNS_LOCAL_IP4: - return Curl_setstropt(&s->str[STRING_DNS_LOCAL_IP4], ptr); - - case CURLOPT_DNS_LOCAL_IP6: - return Curl_setstropt(&s->str[STRING_DNS_LOCAL_IP6], ptr); - -#endif -#ifdef USE_UNIX_SOCKETS - case CURLOPT_UNIX_SOCKET_PATH: - s->abstract_unix_socket = FALSE; - return Curl_setstropt(&s->str[STRING_UNIX_SOCKET_PATH], ptr); - - case CURLOPT_ABSTRACT_UNIX_SOCKET: - s->abstract_unix_socket = TRUE; - return Curl_setstropt(&s->str[STRING_UNIX_SOCKET_PATH], ptr); - -#endif - -#ifndef CURL_DISABLE_DOH - case CURLOPT_DOH_URL: - result = Curl_setstropt(&s->str[STRING_DOH], ptr); - s->doh = !!(s->str[STRING_DOH]); - break; -#endif -#ifndef CURL_DISABLE_HSTS - case CURLOPT_HSTSREADDATA: - s->hsts_read_userp = ptr; - break; - case CURLOPT_HSTSWRITEDATA: - s->hsts_write_userp = ptr; - break; - case CURLOPT_HSTS: { - struct curl_slist *h; - if(!data->hsts) { - data->hsts = Curl_hsts_init(); - if(!data->hsts) - return CURLE_OUT_OF_MEMORY; - } - if(ptr) { - result = Curl_setstropt(&s->str[STRING_HSTS], ptr); - if(result) - return result; - /* this needs to build a list of filenames to read from, so that it can - read them later, as we might get a shared HSTS handle to load them - into */ - h = curl_slist_append(data->state.hstslist, ptr); - if(!h) { - curl_slist_free_all(data->state.hstslist); - data->state.hstslist = NULL; - return CURLE_OUT_OF_MEMORY; - } - data->state.hstslist = h; /* store the list for later use */ - } - else { - /* clear the list of HSTS files */ - curl_slist_free_all(data->state.hstslist); - data->state.hstslist = NULL; - if(!data->share || !data->share->hsts) - /* throw away the HSTS cache unless shared */ - Curl_hsts_cleanup(&data->hsts); - } - break; - } -#endif /* !CURL_DISABLE_HSTS */ -#ifndef CURL_DISABLE_ALTSVC - case CURLOPT_ALTSVC: - if(!data->asi) { - data->asi = Curl_altsvc_init(); - if(!data->asi) - return CURLE_OUT_OF_MEMORY; - } - result = Curl_setstropt(&s->str[STRING_ALTSVC], ptr); - if(result) - break; - if(ptr) - return Curl_altsvc_load(data->asi, ptr); - break; -#endif /* !CURL_DISABLE_ALTSVC */ -#ifdef USE_ECH - case CURLOPT_ECH: { - size_t plen = 0; - - if(!ptr) { - s->tls_ech = CURLECH_DISABLE; - break; - } - plen = strlen(ptr); - if(plen > CURL_MAX_INPUT_LENGTH) { - s->tls_ech = CURLECH_DISABLE; - return CURLE_BAD_FUNCTION_ARGUMENT; - } - /* set tls_ech flag value, preserving CLA_CFG bit */ - if(!strcmp(ptr, "false")) - s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_DISABLE; - else if(!strcmp(ptr, "grease")) - s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_GREASE; - else if(!strcmp(ptr, "true")) - s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_ENABLE; - else if(!strcmp(ptr, "hard")) - s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_HARD; - else if(plen > 5 && !strncmp(ptr, "ecl:", 4)) { - result = Curl_setstropt(&s->str[STRING_ECH_CONFIG], ptr + 4); - if(!result) - s->tls_ech |= CURLECH_CLA_CFG; - } - else if(plen > 4 && !strncmp(ptr, "pn:", 3)) - result = Curl_setstropt(&s->str[STRING_ECH_PUBLIC], ptr + 3); - break; - } -#endif - default: - return CURLE_UNKNOWN_OPTION; - } - return result; -} - -static CURLcode setopt_func(struct Curl_easy *data, CURLoption option, - va_list param) -{ - struct UserDefined *s = &data->set; - switch(option) { - case CURLOPT_PROGRESSFUNCTION: - /* - * Progress callback function - */ - s->fprogress = va_arg(param, curl_progress_callback); - if(s->fprogress) - data->progress.callback = TRUE; /* no longer internal */ - else - data->progress.callback = FALSE; /* NULL enforces internal */ - break; - - case CURLOPT_XFERINFOFUNCTION: - /* - * Transfer info callback function - */ - s->fxferinfo = va_arg(param, curl_xferinfo_callback); - if(s->fxferinfo) - data->progress.callback = TRUE; /* no longer internal */ - else - data->progress.callback = FALSE; /* NULL enforces internal */ - - break; - case CURLOPT_DEBUGFUNCTION: - /* - * stderr write callback. - */ - s->fdebug = va_arg(param, curl_debug_callback); - /* - * if the callback provided is NULL, it will use the default callback - */ - break; - case CURLOPT_HEADERFUNCTION: - /* - * Set header write callback - */ - s->fwrite_header = va_arg(param, curl_write_callback); - break; - case CURLOPT_WRITEFUNCTION: - /* - * Set data write callback - */ - s->fwrite_func = va_arg(param, curl_write_callback); - if(!s->fwrite_func) -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - /* When set to NULL, reset to our internal default function */ - s->fwrite_func = (curl_write_callback)fwrite; -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - break; - case CURLOPT_READFUNCTION: - /* - * Read data callback - */ - s->fread_func_set = va_arg(param, curl_read_callback); - if(!s->fread_func_set) { - s->is_fread_set = 0; -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - /* When set to NULL, reset to our internal default function */ - s->fread_func_set = (curl_read_callback)fread; -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - } - else - s->is_fread_set = 1; - break; - case CURLOPT_SEEKFUNCTION: - /* - * Seek callback. Might be NULL. - */ - s->seek_func = va_arg(param, curl_seek_callback); - break; - case CURLOPT_IOCTLFUNCTION: - /* - * I/O control callback. Might be NULL. - */ - s->ioctl_func = va_arg(param, curl_ioctl_callback); - break; - case CURLOPT_SSL_CTX_FUNCTION: - /* - * Set an SSL_CTX callback - */ -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) { - s->ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); - break; - } - else -#endif - return CURLE_NOT_BUILT_IN; - - case CURLOPT_SOCKOPTFUNCTION: - /* - * socket callback function: called after socket() but before connect() - */ - s->fsockopt = va_arg(param, curl_sockopt_callback); - break; - - case CURLOPT_OPENSOCKETFUNCTION: - /* - * open/create socket callback function: called instead of socket(), - * before connect() - */ - s->fopensocket = va_arg(param, curl_opensocket_callback); - break; - - case CURLOPT_CLOSESOCKETFUNCTION: - /* - * close socket callback function: called instead of close() - * when shutting down a connection - */ - s->fclosesocket = va_arg(param, curl_closesocket_callback); - break; - - case CURLOPT_RESOLVER_START_FUNCTION: - /* - * resolver start callback function: called before a new resolver request - * is started - */ - s->resolver_start = va_arg(param, curl_resolver_start_callback); - break; - -#ifdef USE_SSH -#ifdef USE_LIBSSH2 - case CURLOPT_SSH_HOSTKEYFUNCTION: - /* the callback to check the hostkey without the knownhost file */ - s->ssh_hostkeyfunc = va_arg(param, curl_sshhostkeycallback); - break; -#endif - - case CURLOPT_SSH_KEYFUNCTION: - /* setting to NULL is fine since the ssh.c functions themselves will - then revert to use the internal default */ - s->ssh_keyfunc = va_arg(param, curl_sshkeycallback); - break; - -#endif /* USE_SSH */ - -#ifndef CURL_DISABLE_RTSP - case CURLOPT_INTERLEAVEFUNCTION: - /* Set the user defined RTP write function */ - s->fwrite_rtp = va_arg(param, curl_write_callback); - break; -#endif -#ifndef CURL_DISABLE_FTP - case CURLOPT_CHUNK_BGN_FUNCTION: - s->chunk_bgn = va_arg(param, curl_chunk_bgn_callback); - break; - case CURLOPT_CHUNK_END_FUNCTION: - s->chunk_end = va_arg(param, curl_chunk_end_callback); - break; - case CURLOPT_FNMATCH_FUNCTION: - s->fnmatch = va_arg(param, curl_fnmatch_callback); - break; -#endif -#ifndef CURL_DISABLE_HTTP - case CURLOPT_TRAILERFUNCTION: - s->trailer_callback = va_arg(param, curl_trailer_callback); - break; -#endif -#ifndef CURL_DISABLE_HSTS - case CURLOPT_HSTSREADFUNCTION: - s->hsts_read = va_arg(param, curl_hstsread_callback); - break; - case CURLOPT_HSTSWRITEFUNCTION: - s->hsts_write = va_arg(param, curl_hstswrite_callback); - break; -#endif - case CURLOPT_PREREQFUNCTION: - s->fprereq = va_arg(param, curl_prereq_callback); - break; - default: - return CURLE_UNKNOWN_OPTION; - } - return CURLE_OK; -} - -static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option, - curl_off_t offt) -{ - struct UserDefined *s = &data->set; - switch(option) { - case CURLOPT_TIMEVALUE_LARGE: - /* - * This is the value to compare with the remote document with the - * method set with CURLOPT_TIMECONDITION - */ - s->timevalue = (time_t)offt; - break; - - /* MQTT "borrows" some of the HTTP options */ - case CURLOPT_POSTFIELDSIZE_LARGE: - /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. - */ - if(offt < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(s->postfieldsize < offt && - s->postfields == s->str[STRING_COPYPOSTFIELDS]) { - /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ - curlx_safefree(s->str[STRING_COPYPOSTFIELDS]); - s->postfields = NULL; - } - s->postfieldsize = offt; - break; - case CURLOPT_INFILESIZE_LARGE: - /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. - */ - if(offt < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->filesize = offt; - break; - case CURLOPT_MAX_SEND_SPEED_LARGE: - /* - * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE - * bytes per second the transfer is throttled.. - */ - if(offt < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->max_send_speed = offt; - Curl_rlimit_init(&data->progress.ul.rlimit, offt, offt, - Curl_pgrs_now(data)); - break; - case CURLOPT_MAX_RECV_SPEED_LARGE: - /* - * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per - * second the transfer is throttled.. - */ - if(offt < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->max_recv_speed = offt; - Curl_rlimit_init(&data->progress.dl.rlimit, offt, offt, - Curl_pgrs_now(data)); - break; - case CURLOPT_RESUME_FROM_LARGE: - /* - * Resume transfer at the given file position - */ - if(offt < -1) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->set_resume_from = offt; - break; - case CURLOPT_MAXFILESIZE_LARGE: - /* - * Set the maximum size of a file to download. - */ - if(offt < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - s->max_filesize = offt; - break; - - default: - return CURLE_UNKNOWN_OPTION; - } - return CURLE_OK; -} - -static CURLcode setopt_blob(struct Curl_easy *data, CURLoption option, - struct curl_blob *blob) -{ - struct UserDefined *s = &data->set; - switch(option) { - case CURLOPT_SSLCERT_BLOB: - /* - * Blob that holds file content of the SSL certificate to use - */ - return Curl_setblobopt(&s->blobs[BLOB_CERT], blob); -#ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXY_SSLCERT_BLOB: - /* - * Blob that holds file content of the SSL certificate to use for proxy - */ - return Curl_setblobopt(&s->blobs[BLOB_CERT_PROXY], blob); - case CURLOPT_PROXY_SSLKEY_BLOB: - /* - * Blob that holds file content of the SSL key to use for proxy - */ - return Curl_setblobopt(&s->blobs[BLOB_KEY_PROXY], blob); - case CURLOPT_PROXY_CAINFO_BLOB: - /* - * Blob that holds CA info for SSL connection proxy. - * Specify entire PEM of the CA certificate - */ -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) - return Curl_setblobopt(&s->blobs[BLOB_CAINFO_PROXY], blob); -#endif - return CURLE_NOT_BUILT_IN; - case CURLOPT_PROXY_ISSUERCERT_BLOB: - /* - * Blob that holds Issuer certificate to check certificates issuer - */ - return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT_PROXY], blob); -#endif - case CURLOPT_SSLKEY_BLOB: - /* - * Blob that holds file content of the SSL key to use - */ - return Curl_setblobopt(&s->blobs[BLOB_KEY], blob); - case CURLOPT_CAINFO_BLOB: - /* - * Blob that holds CA info for SSL connection. - * Specify entire PEM of the CA certificate - */ -#ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) { - s->ssl.custom_cablob = TRUE; - return Curl_setblobopt(&s->blobs[BLOB_CAINFO], blob); - } -#endif - return CURLE_NOT_BUILT_IN; - case CURLOPT_ISSUERCERT_BLOB: - /* - * Blob that holds Issuer certificate to check certificates issuer - */ - if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT_BLOB)) - return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT], blob); - return CURLE_NOT_BUILT_IN; - - default: - return CURLE_UNKNOWN_OPTION; - } - /* unreachable */ -} - -/* - * Do not make Curl_vsetopt() static: it is called from - * projects/OS400/ccsidcurl.c. - */ -CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) -{ - if(option < CURLOPTTYPE_OBJECTPOINT) - return setopt_long(data, option, va_arg(param, long)); - else if(option < CURLOPTTYPE_FUNCTIONPOINT) { - /* unfortunately, different pointer types cannot be identified any other - way than being listed explicitly */ - switch(option) { - case CURLOPT_HTTPHEADER: - case CURLOPT_QUOTE: - case CURLOPT_POSTQUOTE: - case CURLOPT_TELNETOPTIONS: - case CURLOPT_PREQUOTE: - case CURLOPT_HTTP200ALIASES: - case CURLOPT_MAIL_RCPT: - case CURLOPT_RESOLVE: - case CURLOPT_PROXYHEADER: - case CURLOPT_CONNECT_TO: - return setopt_slist(data, option, va_arg(param, struct curl_slist *)); - case CURLOPT_HTTPPOST: /* curl_httppost * */ - case CURLOPT_MIMEPOST: /* curl_mime * */ - case CURLOPT_STDERR: /* FILE * */ - case CURLOPT_SHARE: /* CURLSH * */ - case CURLOPT_STREAM_DEPENDS: /* CURL * */ - case CURLOPT_STREAM_DEPENDS_E: /* CURL * */ - case CURLOPT_CURLU: /* CURLU * */ - return setopt_pointers(data, option, param); - default: - break; - } - /* the char pointer options */ - return setopt_cptr(data, option, va_arg(param, char *)); - } - else if(option < CURLOPTTYPE_OFF_T) - return setopt_func(data, option, param); - else if(option < CURLOPTTYPE_BLOB) - return setopt_offt(data, option, va_arg(param, curl_off_t)); - return setopt_blob(data, option, va_arg(param, struct curl_blob *)); -} - -/* - * curl_easy_setopt() is the external interface for setting options on an - * easy handle. - * - * NOTE: This is one of few API functions that are allowed to be called from - * within a callback. - */ - -#undef curl_easy_setopt -CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...) -{ - va_list arg; - CURLcode result; - struct Curl_easy *data = curl; - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - va_start(arg, option); - - result = Curl_vsetopt(data, option, arg); - - va_end(arg); - if(result == CURLE_BAD_FUNCTION_ARGUMENT) - failf(data, "setopt 0x%x got bad argument", option); - return result; -} diff --git a/vendor/curl/lib/setopt.h b/vendor/curl/lib/setopt.h deleted file mode 100644 index c421f5c5e..000000000 --- a/vendor/curl/lib/setopt.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_SETOPT_H -#define HEADER_CURL_SETOPT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#ifdef USE_SSL -CURLcode Curl_setopt_SSLVERSION(struct Curl_easy *data, CURLoption option, - long arg); -#else -#define Curl_setopt_SSLVERSION(a, b, c) CURLE_NOT_BUILT_IN -#endif - -CURLcode Curl_setstropt(char **charp, const char *s) WARN_UNUSED_RESULT; -CURLcode Curl_setblobopt(struct curl_blob **blobp, - const struct curl_blob *blob) WARN_UNUSED_RESULT; -CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) - WARN_UNUSED_RESULT; - -#endif /* HEADER_CURL_SETOPT_H */ diff --git a/vendor/curl/lib/setup-os400.h b/vendor/curl/lib/setup-os400.h deleted file mode 100644 index b5bd73367..000000000 --- a/vendor/curl/lib/setup-os400.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef HEADER_CURL_SETUP_OS400_H -#define HEADER_CURL_SETUP_OS400_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* OS/400 netdb.h does not define NI_MAXHOST. */ -#define NI_MAXHOST 1025 - -/* OS/400 netdb.h does not define NI_MAXSERV. */ -#define NI_MAXSERV 32 - -/* OS/400 has no idea of a tty! */ -#define isatty(fd) 0 - -/* Workaround bug in IBM QADRT runtime library: - * function puts() does not output the implicit trailing newline. - */ - -#include /* Be sure it is loaded. */ -#undef puts -#define puts(s) (fputs(s, stdout) == EOF ? EOF : putchar('\n')) - -/* System API wrapper prototypes & definitions to support ASCII parameters. */ - -#include -#include -#include -#include -#include - -#ifdef BUILDING_LIBCURL - -extern int Curl_getaddrinfo_a(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct addrinfo **res); -#define getaddrinfo Curl_getaddrinfo_a - -/* Note socklen_t must be used as this is declared before curl_socklen_t */ -extern int Curl_getnameinfo_a(const struct sockaddr *sa, - socklen_t salen, - char *nodename, socklen_t nodenamelen, - char *servname, socklen_t servnamelen, - int flags); -#define getnameinfo Curl_getnameinfo_a - -/* GSSAPI wrappers. */ - -extern OM_uint32 Curl_gss_import_name_a(OM_uint32 *minor_status, - gss_buffer_t in_name, - gss_OID in_name_type, - gss_name_t *out_name); -#define gss_import_name Curl_gss_import_name_a - -extern OM_uint32 Curl_gss_display_status_a(OM_uint32 *minor_status, - OM_uint32 status_value, - int status_type, gss_OID mech_type, - gss_msg_ctx_t *message_context, - gss_buffer_t status_string); -#define gss_display_status Curl_gss_display_status_a - -extern OM_uint32 Curl_gss_init_sec_context_a(OM_uint32 *minor_status, - gss_cred_id_t cred_handle, - gss_ctx_id_t *context_handle, - gss_name_t target_name, - gss_OID mech_type, - gss_flags_t req_flags, - OM_uint32 time_req, - gss_channel_bindings_t - input_chan_bindings, - gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - gss_flags_t *ret_flags, - OM_uint32 *time_rec); -#define gss_init_sec_context Curl_gss_init_sec_context_a - -extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - gss_buffer_t output_token); -#define gss_delete_sec_context Curl_gss_delete_sec_context_a - -/* LDAP wrappers. */ - -#define BerValue struct berval - -#define ldap_url_parse ldap_url_parse_utf8 -#define ldap_init Curl_ldap_init_a -#define ldap_simple_bind_s Curl_ldap_simple_bind_s_a -#define ldap_search_s Curl_ldap_search_s_a -#define ldap_get_values_len Curl_ldap_get_values_len_a -#define ldap_err2string Curl_ldap_err2string_a -#define ldap_get_dn Curl_ldap_get_dn_a -#define ldap_first_attribute Curl_ldap_first_attribute_a -#define ldap_next_attribute Curl_ldap_next_attribute_a - -/* Some socket functions must be wrapped to process textual addresses - like AF_UNIX. */ - -extern int Curl_os400_connect(int sd, struct sockaddr *destaddr, int addrlen); -extern int Curl_os400_bind(int sd, struct sockaddr *localaddr, int addrlen); -extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags, - const struct sockaddr *dstaddr, int addrlen); -extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags, - struct sockaddr *fromaddr, int *addrlen); -extern int Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen); -extern int Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen); - -#define connect Curl_os400_connect -#define bind Curl_os400_bind -#define sendto Curl_os400_sendto -#define recvfrom Curl_os400_recvfrom -#define getpeername Curl_os400_getpeername -#define getsockname Curl_os400_getsockname - -#ifdef HAVE_LIBZ -#define zlibVersion Curl_os400_zlibVersion -#define inflateInit_ Curl_os400_inflateInit_ -#define inflateInit2_ Curl_os400_inflateInit2_ -#define inflate Curl_os400_inflate -#define inflateEnd Curl_os400_inflateEnd -#endif - -#endif /* BUILDING_LIBCURL */ - -#endif /* HEADER_CURL_SETUP_OS400_H */ diff --git a/vendor/curl/lib/setup-vms.h b/vendor/curl/lib/setup-vms.h deleted file mode 100644 index 35d12f0b4..000000000 --- a/vendor/curl/lib/setup-vms.h +++ /dev/null @@ -1,396 +0,0 @@ -#ifndef HEADER_CURL_SETUP_VMS_H -#define HEADER_CURL_SETUP_VMS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* JEM, 2012-12-30, VMS now generates config.h, so only define wrappers for */ -/* getenv(), getpwuid() and provide is_vms_shell() */ -/* Also need upper case symbols for system services, and */ -/* OpenSSL, and some Kerberos image */ - -#ifdef __DECC -#pragma message save -#pragma message disable dollarid -#endif - -/* Hide the stuff we are overriding */ -#define getenv decc_getenv -#ifdef __DECC -# if __INITIAL_POINTER_SIZE != 64 -# define getpwuid decc_getpwuid -# endif -#endif -#include -char *decc$getenv(const char *__name); -#include - -#include -#include - -#undef getenv -#undef getpwuid -#define getenv vms_getenv -#define getpwuid vms_getpwuid - -/* VAX needs these in upper case when compiling exact case */ -#define sys$assign SYS$ASSIGN -#define sys$dassgn SYS$DASSGN -#define sys$qiow SYS$QIOW - -#ifdef __DECC -# if __INITIAL_POINTER_SIZE -# pragma __pointer_size __save -# endif -#endif - -#if __USE_LONG_GID_T -# define decc_getpwuid DECC$__LONG_GID_GETPWUID -#else -# if __INITIAL_POINTER_SIZE -# define decc_getpwuid decc$__32_getpwuid -# else -# define decc_getpwuid decc$getpwuid -# endif -#endif - -struct passwd *decc_getpwuid(uid_t uid); - -#ifdef __DECC -# if __INITIAL_POINTER_SIZE == 32 -/* Translate the path, but only if the path is a VMS file specification */ -/* The translation is usually only needed for older versions of VMS */ -static char *vms_translate_path(const char *path) -{ - char *unix_path; - char *test_str; - - /* See if the result is in VMS format, if not, we are done */ - /* Assume that this is a PATH, not some data */ - test_str = strpbrk(path, ":[<^"); - if(!test_str) { - return (char *)path; - } - - unix_path = decc$translate_vms(path); - - if((int)unix_path <= 0) { - /* We can not translate it, so return the original string */ - return (char *)path; - } -} -# else - /* VMS translate path is actually not needed on the current 64-bit */ - /* VMS platforms, so instead of figuring out the pointer settings */ - /* Change it to a noop */ -# define vms_translate_path(__path) __path -# endif -#endif - -#ifdef __DECC -# if __INITIAL_POINTER_SIZE -# pragma __pointer_size __restore -# endif -#endif - -static char *vms_getenv(const char *envvar) -{ - char *result; - char *vms_path; - - /* first use the DECC getenv() function */ - result = decc$getenv(envvar); - if(!result) { - return result; - } - - vms_path = result; - result = vms_translate_path(vms_path); - - /* note that if you backport this to use VAX C RTL, that the VAX C RTL */ - /* may do a malloc(2048) for each call to getenv(), so you will need */ - /* to add a free(vms_path) */ - /* Do not do a free() for DEC C RTL builds, which should be used for */ - /* VMS 5.5-2 and later, even if using GCC */ - - return result; -} - -static struct passwd vms_passwd_cache; - -static struct passwd *vms_getpwuid(uid_t uid) -{ - struct passwd *my_passwd; - -/* Hack needed to support 64-bit builds, decc_getpwnam is 32-bit only */ -#ifdef __DECC -# if __INITIAL_POINTER_SIZE - __char_ptr32 unix_path; -# else - char *unix_path; -# endif -#else - char *unix_path; -#endif - - my_passwd = decc_getpwuid(uid); - if(!my_passwd) { - return my_passwd; - } - - unix_path = vms_translate_path(my_passwd->pw_dir); - - if((long)unix_path <= 0) { - /* We can not translate it, so return the original string */ - return my_passwd; - } - - /* If no changes needed, return it */ - if(unix_path == my_passwd->pw_dir) { - return my_passwd; - } - - /* Need to copy the structure returned */ - /* Since curl is only using pw_dir, no need to fix up */ - /* the pw_shell when running under Bash */ - vms_passwd_cache.pw_name = my_passwd->pw_name; - vms_passwd_cache.pw_uid = my_passwd->pw_uid; - vms_passwd_cache.pw_gid = my_passwd->pw_uid; - vms_passwd_cache.pw_dir = unix_path; - vms_passwd_cache.pw_shell = my_passwd->pw_shell; - - return &vms_passwd_cache; -} - -#ifdef __DECC -#pragma message restore -#endif - -/* Bug - VMS OpenSSL and Kerberos universal symbols are in uppercase only */ -/* VMS libraries should have universal symbols in exact and uppercase */ - -#define ASN1_INTEGER_get ASN1_INTEGER_GET -#define ASN1_STRING_data ASN1_STRING_DATA -#define ASN1_STRING_length ASN1_STRING_LENGTH -#define ASN1_STRING_print ASN1_STRING_PRINT -#define ASN1_STRING_to_UTF8 ASN1_STRING_TO_UTF8 -#define ASN1_STRING_type ASN1_STRING_TYPE -#define BIO_ctrl BIO_CTRL -#define BIO_free BIO_FREE -#define BIO_new BIO_NEW -#define BIO_s_mem BIO_S_MEM -#define BN_bn2bin BN_BN2BIN -#define BN_num_bits BN_NUM_BITS -#define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA -#define CRYPTO_free CRYPTO_FREE -#define CRYPTO_malloc CRYPTO_MALLOC -#define CONF_modules_load_file CONF_MODULES_LOAD_FILE -#ifdef __VAX -# ifdef VMS_OLD_SSL - /* Ancient OpenSSL on VAX/VMS missing this constant */ -# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 -# undef CONF_modules_load_file -static int CONF_modules_load_file(const char *filename, - const char *appname, - unsigned long flags) { - return 1; -} -# endif -#endif -#define DES_ecb_encrypt DES_ECB_ENCRYPT -#define DES_set_key DES_SET_KEY -#define DES_set_odd_parity DES_SET_ODD_PARITY -#define ENGINE_ctrl ENGINE_CTRL -#define ENGINE_ctrl_cmd ENGINE_CTRL_CMD -#define ENGINE_finish ENGINE_FINISH -#define ENGINE_free ENGINE_FREE -#define ENGINE_get_first ENGINE_GET_FIRST -#define ENGINE_get_id ENGINE_GET_ID -#define ENGINE_get_next ENGINE_GET_NEXT -#define ENGINE_init ENGINE_INIT -#define ENGINE_load_builtin_engines ENGINE_LOAD_BUILTIN_ENGINES -#define ENGINE_load_private_key ENGINE_LOAD_PRIVATE_KEY -#define ENGINE_set_default ENGINE_SET_DEFAULT -#define ERR_clear_error ERR_CLEAR_ERROR -#define ERR_error_string ERR_ERROR_STRING -#define ERR_error_string_n ERR_ERROR_STRING_N -#define ERR_free_strings ERR_FREE_STRINGS -#define ERR_get_error ERR_GET_ERROR -#define ERR_peek_error ERR_PEEK_ERROR -#define ERR_remove_state ERR_REMOVE_STATE -#define EVP_PKEY_copy_parameters EVP_PKEY_COPY_PARAMETERS -#define EVP_PKEY_free EVP_PKEY_FREE -#define EVP_cleanup EVP_CLEANUP -#define GENERAL_NAMES_free GENERAL_NAMES_FREE -#define i2d_X509_PUBKEY I2D_X509_PUBKEY -#define MD4_Final MD4_FINAL -#define MD4_Init MD4_INIT -#define MD4_Update MD4_UPDATE -#define MD5_Final MD5_FINAL -#define MD5_Init MD5_INIT -#define MD5_Update MD5_UPDATE -#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF -#ifndef __VAX -#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES -#endif -#define PEM_read_X509 PEM_READ_X509 -#define PEM_write_bio_X509 PEM_WRITE_BIO_X509 -#define PKCS12_free PKCS12_FREE -#define PKCS12_parse PKCS12_PARSE -#define RAND_add RAND_ADD -#define RAND_bytes RAND_BYTES -#define RAND_file_name RAND_FILE_NAME -#define RAND_load_file RAND_LOAD_FILE -#define RAND_status RAND_STATUS -#define SSL_CIPHER_get_name SSL_CIPHER_GET_NAME -#define SSL_CTX_add_client_CA SSL_CTX_ADD_CLIENT_CA -#define SSL_CTX_callback_ctrl SSL_CTX_CALLBACK_CTRL -#define SSL_CTX_check_private_key SSL_CTX_CHECK_PRIVATE_KEY -#define SSL_CTX_ctrl SSL_CTX_CTRL -#define SSL_CTX_free SSL_CTX_FREE -#define SSL_CTX_get_cert_store SSL_CTX_GET_CERT_STORE -#define SSL_CTX_load_verify_locations SSL_CTX_LOAD_VERIFY_LOCATIONS -#define SSL_CTX_new SSL_CTX_NEW -#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST -#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD -#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB -#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK -#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY -#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY -#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE -#define SSL_CTX_use_cert_chain_file SSL_CTX_USE_CERT_CHAIN_FILE -#define SSL_CTX_use_certificate SSL_CTX_USE_CERTIFICATE -#define SSL_CTX_use_certificate_file SSL_CTX_USE_CERTIFICATE_FILE -#define SSL_SESSION_free SSL_SESSION_FREE -#define SSL_connect SSL_CONNECT -#define SSL_free SSL_FREE -#define SSL_get1_session SSL_GET1_SESSION -#define SSL_get_certificate SSL_GET_CERTIFICATE -#define SSL_get_current_cipher SSL_GET_CURRENT_CIPHER -#define SSL_get_error SSL_GET_ERROR -#define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN -#define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE -#define SSL_get_privatekey SSL_GET_PRIVATEKEY -#define SSL_get_session SSL_GET_SESSION -#define SSL_get_shutdown SSL_GET_SHUTDOWN -#define SSL_get_verify_result SSL_GET_VERIFY_RESULT -#define SSL_library_init SSL_LIBRARY_INIT -#define SSL_load_error_strings SSL_LOAD_ERROR_STRINGS -#define SSL_new SSL_NEW -#define SSL_peek SSL_PEEK -#define SSL_pending SSL_PENDING -#define SSL_read SSL_READ -#define SSL_set_connect_state SSL_SET_CONNECT_STATE -#define SSL_set_fd SSL_SET_FD -#define SSL_set_session SSL_SET_SESSION -#define SSL_shutdown SSL_SHUTDOWN -#define SSL_version SSL_VERSION -#define SSL_write SSL_WRITE -#define SSLeay SSLEAY -#define SSLv23_client_method SSLV23_CLIENT_METHOD -#define SSLv3_client_method SSLV3_CLIENT_METHOD -#define TLSv1_client_method TLSV1_CLIENT_METHOD -#define UI_create_method UI_CREATE_METHOD -#define UI_destroy_method UI_DESTROY_METHOD -#define UI_get0_user_data UI_GET0_USER_DATA -#define UI_get_input_flags UI_GET_INPUT_FLAGS -#define UI_get_string_type UI_GET_STRING_TYPE -#define UI_create_method UI_CREATE_METHOD -#define UI_destroy_method UI_DESTROY_METHOD -#define UI_method_get_closer UI_METHOD_GET_CLOSER -#define UI_method_get_opener UI_METHOD_GET_OPENER -#define UI_method_get_reader UI_METHOD_GET_READER -#define UI_method_get_writer UI_METHOD_GET_WRITER -#define UI_method_set_closer UI_METHOD_SET_CLOSER -#define UI_method_set_opener UI_METHOD_SET_OPENER -#define UI_method_set_reader UI_METHOD_SET_READER -#define UI_method_set_writer UI_METHOD_SET_WRITER -#define UI_OpenSSL UI_OPENSSL -#define UI_set_result UI_SET_RESULT -#define X509V3_EXT_print X509V3_EXT_PRINT -#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL -#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA -#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT -#define X509_LOOKUP_file X509_LOOKUP_FILE -#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA -#define X509_NAME_get_entry X509_NAME_GET_ENTRY -#define X509_NAME_get_index_by_NID X509_NAME_GET_INDEX_BY_NID -#define X509_NAME_print_ex X509_NAME_PRINT_EX -#define X509_STORE_CTX_get_current_cert X509_STORE_CTX_GET_CURRENT_CERT -#define X509_STORE_add_lookup X509_STORE_ADD_LOOKUP -#define X509_STORE_set_flags X509_STORE_SET_FLAGS -#define X509_check_issued X509_CHECK_ISSUED -#define X509_free X509_FREE -#define X509_get_ext_d2i X509_GET_EXT_D2I -#define X509_get_issuer_name X509_GET_ISSUER_NAME -#define X509_get_pubkey X509_GET_PUBKEY -#define X509_get_serialNumber X509_GET_SERIALNUMBER -#define X509_get_subject_name X509_GET_SUBJECT_NAME -#define X509_load_crl_file X509_LOAD_CRL_FILE -#define X509_verify_cert_error_string X509_VERIFY_CERT_ERROR_STRING -#define d2i_PKCS12_fp D2I_PKCS12_FP -#define i2t_ASN1_OBJECT I2T_ASN1_OBJECT -#define sk_num SK_NUM -#define sk_pop SK_POP -#define sk_pop_free SK_POP_FREE -#define sk_value SK_VALUE -#define SHA256_Final SHA256_FINAL -#define SHA256_Init SHA256_INIT -#define SHA256_Update SHA256_UPDATE - -#define USE_UPPERCASE_GSSAPI 1 -#define gss_seal GSS_SEAL -#define gss_unseal GSS_UNSEAL - -#define USE_UPPERCASE_KRBAPI 1 - -/* AI_NUMERICHOST needed for IP V6 support in curl */ -#ifdef HAVE_NETDB_H -#include -#ifndef AI_NUMERICHOST -#undef USE_IPV6 -#endif -#endif - -/* VAX symbols are always in uppercase */ -#ifdef __VAX -#define inflate INFLATE -#define inflateEnd INFLATEEND -#define inflateInit2_ INFLATEINIT2_ -#define inflateInit_ INFLATEINIT_ -#define zlibVersion ZLIBVERSION -#endif - -/* Older VAX OpenSSL port defines these as Macros */ -/* Need to include the headers first and then redefine */ -/* that way a newer port will also work if some one has one */ -#ifdef __VAX - -# include -# ifndef OpenSSL_add_all_algorithms -# define OpenSSL_add_all_algorithms OPENSSL_ADD_ALL_ALGORITHMS - void OPENSSL_ADD_ALL_ALGORITHMS(void); -# endif -#endif - -#endif /* HEADER_CURL_SETUP_VMS_H */ diff --git a/vendor/curl/lib/setup-win32.h b/vendor/curl/lib/setup-win32.h deleted file mode 100644 index 6a89b966d..000000000 --- a/vendor/curl/lib/setup-win32.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef HEADER_CURL_SETUP_WIN32_H -#define HEADER_CURL_SETUP_WIN32_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#undef USE_WINSOCK -/* ---------------------------------------------------------------- */ -/* Watt-32 TCP/IP SPECIFIC */ -/* ---------------------------------------------------------------- */ -#ifdef USE_WATT32 -# include -# include -# undef byte -# undef word -# define HAVE_SYS_IOCTL_H -# define HAVE_NETINET_IN_H -# define HAVE_NETDB_H -# define HAVE_ARPA_INET_H -# define SOCKET int -/* ---------------------------------------------------------------- */ -/* BSD-style lwIP TCP/IP stack SPECIFIC */ -/* ---------------------------------------------------------------- */ -#elif defined(USE_LWIPSOCK) - /* Define to use BSD-style lwIP TCP/IP stack. */ - /* #define USE_LWIPSOCK 1 */ -# undef HAVE_GETHOSTNAME -# define HAVE_GETHOSTBYNAME_R -# define HAVE_GETHOSTBYNAME_R_6 -# undef LWIP_POSIX_SOCKETS_IO_NAMES -# define LWIP_POSIX_SOCKETS_IO_NAMES 0 -# undef RECV_TYPE_ARG1 -# define RECV_TYPE_ARG1 int -# undef RECV_TYPE_ARG3 -# define RECV_TYPE_ARG3 size_t -# undef SEND_TYPE_ARG1 -# define SEND_TYPE_ARG1 int -# undef SEND_TYPE_ARG3 -# define SEND_TYPE_ARG3 size_t -#elif defined(_WIN32) -# define USE_WINSOCK 2 -# include -# include -#endif - -/* - * Include header files for Windows builds before redefining anything. Use - * this preprocessor block only to include or exclude windows.h, winsock2.h or - * ws2tcpip.h. Any other Windows thing belongs to any other further and - * independent block. Under Cygwin things work as under Linux (e.g. - * ) and the Winsock headers should never be included when - * __CYGWIN__ is defined. - */ -#ifdef _WIN32 -# if defined(UNICODE) && !defined(_UNICODE) -# error "UNICODE is defined but _UNICODE is not defined" -# endif -# if defined(_UNICODE) && !defined(UNICODE) -# error "_UNICODE is defined but UNICODE is not defined" -# endif -# include -# include -# include -#endif - -/* - * Define _WIN32_WINNT_[OS] symbols because not all Windows build systems have - * those symbols to compare against, and even those that do may be missing - * newer symbols. - */ -#ifndef _WIN32_WINNT_VISTA -#define _WIN32_WINNT_VISTA 0x0600 /* Windows Vista */ -#endif -#ifndef _WIN32_WINNT_WS08 -#define _WIN32_WINNT_WS08 0x0600 /* Windows Server 2008 */ -#endif -#ifndef _WIN32_WINNT_WIN7 -#define _WIN32_WINNT_WIN7 0x0601 /* Windows 7 */ -#endif -#ifndef _WIN32_WINNT_WIN8 -#define _WIN32_WINNT_WIN8 0x0602 /* Windows 8 */ -#endif -#ifndef _WIN32_WINNT_WINBLUE -#define _WIN32_WINNT_WINBLUE 0x0603 /* Windows 8.1 */ -#endif -#ifndef _WIN32_WINNT_WIN10 -#define _WIN32_WINNT_WIN10 0x0A00 /* Windows 10 */ -#endif - -#endif /* HEADER_CURL_SETUP_WIN32_H */ diff --git a/vendor/curl/lib/sha256.c b/vendor/curl/lib/sha256.c deleted file mode 100644 index d97f45f05..000000000 --- a/vendor/curl/lib/sha256.c +++ /dev/null @@ -1,508 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Florin Petriuc, - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \ - defined(USE_LIBSSH2) || defined(USE_SSL) - -#include "curl_sha256.h" - -#ifdef USE_MBEDTLS -#include -#if MBEDTLS_VERSION_NUMBER < 0x03020000 -#error "mbedTLS 3.2.0 or later required" -#endif -#include -#endif - -/* Please keep the SSL backend-specific #if branches in this order: - * - * 1. USE_OPENSSL - * 2. USE_WOLFSSL - * 3. USE_GNUTLS - * 4. USE_MBEDTLS - * 5. USE_COMMON_CRYPTO - * 6. USE_WIN32_CRYPTO - * - * This ensures that the same SSL branch gets activated throughout this source - * file even if multiple backends are enabled at the same time. - */ - -#ifdef USE_OPENSSL -#include - -struct ossl_sha256_ctx { - EVP_MD_CTX *openssl_ctx; -}; -typedef struct ossl_sha256_ctx my_sha256_ctx; - -static CURLcode my_sha256_init(void *in) -{ - my_sha256_ctx *ctx = (my_sha256_ctx *)in; - ctx->openssl_ctx = EVP_MD_CTX_create(); - if(!ctx->openssl_ctx) - return CURLE_OUT_OF_MEMORY; - - if(!EVP_DigestInit_ex(ctx->openssl_ctx, EVP_sha256(), NULL)) { - EVP_MD_CTX_destroy(ctx->openssl_ctx); - return CURLE_FAILED_INIT; - } - return CURLE_OK; -} - -static void my_sha256_update(void *in, - const unsigned char *data, - unsigned int length) -{ - my_sha256_ctx *ctx = (my_sha256_ctx *)in; - EVP_DigestUpdate(ctx->openssl_ctx, data, length); -} - -static void my_sha256_final(unsigned char *digest, void *in) -{ - my_sha256_ctx *ctx = (my_sha256_ctx *)in; - EVP_DigestFinal_ex(ctx->openssl_ctx, digest, NULL); - EVP_MD_CTX_destroy(ctx->openssl_ctx); -} - -#elif defined(USE_WOLFSSL) -#include -#include - -typedef struct wc_Sha256 my_sha256_ctx; - -static CURLcode my_sha256_init(void *in) -{ - if(wc_InitSha256(in)) - return CURLE_FAILED_INIT; - return CURLE_OK; -} - -static void my_sha256_update(void *in, - const unsigned char *data, - unsigned int length) -{ - (void)wc_Sha256Update(in, data, (word32)length); -} - -static void my_sha256_final(unsigned char *digest, void *in) -{ - (void)wc_Sha256Final(in, digest); -} - -#elif defined(USE_GNUTLS) -#include - -typedef struct sha256_ctx my_sha256_ctx; - -static CURLcode my_sha256_init(void *ctx) -{ - sha256_init(ctx); - return CURLE_OK; -} - -static void my_sha256_update(void *ctx, - const unsigned char *data, - unsigned int length) -{ - sha256_update(ctx, length, data); -} - -static void my_sha256_final(unsigned char *digest, void *ctx) -{ - sha256_digest(ctx, SHA256_DIGEST_SIZE, digest); -} - -#elif defined(USE_MBEDTLS) && \ - defined(PSA_WANT_ALG_SHA_256) && PSA_WANT_ALG_SHA_256 /* mbedTLS 4+ */ -#include - -typedef psa_hash_operation_t my_sha256_ctx; - -static CURLcode my_sha256_init(void *ctx) -{ - memset(ctx, 0, sizeof(my_sha256_ctx)); - if(psa_hash_setup(ctx, PSA_ALG_SHA_256) != PSA_SUCCESS) - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -} - -static void my_sha256_update(void *ctx, - const unsigned char *data, - unsigned int length) -{ - (void)psa_hash_update(ctx, data, length); -} - -static void my_sha256_final(unsigned char *digest, void *ctx) -{ - size_t actual_length; - (void)psa_hash_finish(ctx, digest, CURL_SHA256_DIGEST_LENGTH, - &actual_length); -} - -#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \ - (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ - (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000)) -#include - -typedef CC_SHA256_CTX my_sha256_ctx; - -static CURLcode my_sha256_init(void *ctx) -{ - (void)CC_SHA256_Init(ctx); - return CURLE_OK; -} - -static void my_sha256_update(void *ctx, - const unsigned char *data, - unsigned int length) -{ - (void)CC_SHA256_Update(ctx, data, length); -} - -static void my_sha256_final(unsigned char *digest, void *ctx) -{ - (void)CC_SHA256_Final(digest, ctx); -} - -#elif defined(USE_WIN32_CRYPTO) -#include - -struct sha256_ctx { - HCRYPTPROV hCryptProv; - HCRYPTHASH hHash; -}; -typedef struct sha256_ctx my_sha256_ctx; - -static CURLcode my_sha256_init(void *in) -{ - my_sha256_ctx *ctx = (my_sha256_ctx *)in; - if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return CURLE_OUT_OF_MEMORY; - - if(!CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash)) { - CryptReleaseContext(ctx->hCryptProv, 0); - ctx->hCryptProv = 0; - return CURLE_FAILED_INIT; - } - - return CURLE_OK; -} - -static void my_sha256_update(void *in, - const unsigned char *data, - unsigned int length) -{ - my_sha256_ctx *ctx = (my_sha256_ctx *)in; - CryptHashData(ctx->hHash, (const BYTE *)data, length, 0); -} - -static void my_sha256_final(unsigned char *digest, void *in) -{ - my_sha256_ctx *ctx = (my_sha256_ctx *)in; - unsigned long length = 0; - - CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); - if(length == CURL_SHA256_DIGEST_LENGTH) - CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); - - if(ctx->hHash) - CryptDestroyHash(ctx->hHash); - - if(ctx->hCryptProv) - CryptReleaseContext(ctx->hCryptProv, 0); -} - -#else - -/* When no other crypto library is available we use this code segment */ - -/* This is based on the SHA256 implementation in LibTomCrypt that was released - * into public domain. */ - -#define WPA_GET_BE32(a) \ - ((((unsigned long)(a)[0]) << 24) | \ - (((unsigned long)(a)[1]) << 16) | \ - (((unsigned long)(a)[2]) << 8) | \ - ((unsigned long)(a)[3])) -#define WPA_PUT_BE32(a, val) \ - do { \ - (a)[0] = (unsigned char)((((unsigned long)(val)) >> 24) & 0xff); \ - (a)[1] = (unsigned char)((((unsigned long)(val)) >> 16) & 0xff); \ - (a)[2] = (unsigned char)((((unsigned long)(val)) >> 8) & 0xff); \ - (a)[3] = (unsigned char)(((unsigned long)(val)) & 0xff); \ - } while(0) - -#define WPA_PUT_BE64(a, val) \ - do { \ - (a)[0] = (unsigned char)(((uint64_t)(val)) >> 56); \ - (a)[1] = (unsigned char)(((uint64_t)(val)) >> 48); \ - (a)[2] = (unsigned char)(((uint64_t)(val)) >> 40); \ - (a)[3] = (unsigned char)(((uint64_t)(val)) >> 32); \ - (a)[4] = (unsigned char)(((uint64_t)(val)) >> 24); \ - (a)[5] = (unsigned char)(((uint64_t)(val)) >> 16); \ - (a)[6] = (unsigned char)(((uint64_t)(val)) >> 8); \ - (a)[7] = (unsigned char)(((uint64_t)(val)) & 0xff); \ - } while(0) - -struct sha256_state { - uint64_t length; - unsigned long state[8], curlen; - unsigned char buf[64]; -}; -typedef struct sha256_state my_sha256_ctx; - -/* The K array */ -static const unsigned long K[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, - 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, - 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, - 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, - 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, - 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, - 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, - 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, - 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, - 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* Various logical functions */ -#define RORc(x, y) \ - (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \ - ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL) - -#define Sha256_Ch(x, y, z) (z ^ (x & (y ^ z))) -#define Sha256_Maj(x, y, z) (((x | y) & z) | (x & y)) -#define Sha256_S(x, n) RORc(x, n) -#define Sha256_R(x, n) (((x) & 0xFFFFFFFFUL) >> (n)) - -#define Sigma0(x) (Sha256_S(x, 2) ^ Sha256_S(x, 13) ^ Sha256_S(x, 22)) -#define Sigma1(x) (Sha256_S(x, 6) ^ Sha256_S(x, 11) ^ Sha256_S(x, 25)) -#define Gamma0(x) (Sha256_S(x, 7) ^ Sha256_S(x, 18) ^ Sha256_R(x, 3)) -#define Gamma1(x) (Sha256_S(x, 17) ^ Sha256_S(x, 19) ^ Sha256_R(x, 10)) - -/* Compress 512 bits */ -static int sha256_compress(struct sha256_state *md, const unsigned char *buf) -{ - unsigned long S[8], W[64]; - int i; - - /* Copy state into S */ - for(i = 0; i < 8; i++) { - S[i] = md->state[i]; - } - /* copy the state into 512 bits into W[0..15] */ - for(i = 0; i < 16; i++) - W[i] = WPA_GET_BE32(buf + (4 * i)); - /* fill W[16..63] */ - for(i = 16; i < 64; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - - /* Compress */ -#define RND(a, b, c, d, e, f, g, h, i) \ - do { \ - unsigned long t0 = h + Sigma1(e) + Sha256_Ch(e, f, g) + K[i] + W[i]; \ - unsigned long t1 = Sigma0(a) + Sha256_Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; \ - } while(0) - - for(i = 0; i < 64; ++i) { - unsigned long t; - RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); - t = S[7]; - S[7] = S[6]; - S[6] = S[5]; - S[5] = S[4]; - S[4] = S[3]; - S[3] = S[2]; - S[2] = S[1]; - S[1] = S[0]; - S[0] = t; - } - - /* Feedback */ - for(i = 0; i < 8; i++) { - md->state[i] = md->state[i] + S[i]; - } - - return 0; -} - -/* Initialize the hash state */ -static CURLcode my_sha256_init(void *in) -{ - struct sha256_state *md = (struct sha256_state *)in; - md->curlen = 0; - md->length = 0; - md->state[0] = 0x6A09E667UL; - md->state[1] = 0xBB67AE85UL; - md->state[2] = 0x3C6EF372UL; - md->state[3] = 0xA54FF53AUL; - md->state[4] = 0x510E527FUL; - md->state[5] = 0x9B05688CUL; - md->state[6] = 0x1F83D9ABUL; - md->state[7] = 0x5BE0CD19UL; - - return CURLE_OK; -} - -/* - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) -*/ -static void my_sha256_update(void *ctx, - const unsigned char *in, - unsigned int len) -{ - unsigned long inlen = len; - unsigned long n; - struct sha256_state *md = (struct sha256_state *)ctx; -#define CURL_SHA256_BLOCK_SIZE 64 - if(md->curlen > sizeof(md->buf)) - return; - while(inlen > 0) { - if(md->curlen == 0 && inlen >= CURL_SHA256_BLOCK_SIZE) { - if(sha256_compress(md, in) < 0) - return; - md->length += CURL_SHA256_BLOCK_SIZE * 8; - in += CURL_SHA256_BLOCK_SIZE; - inlen -= CURL_SHA256_BLOCK_SIZE; - } - else { - n = CURLMIN(inlen, (CURL_SHA256_BLOCK_SIZE - md->curlen)); - memcpy(md->buf + md->curlen, in, n); - md->curlen += n; - in += n; - inlen -= n; - if(md->curlen == CURL_SHA256_BLOCK_SIZE) { - if(sha256_compress(md, md->buf) < 0) - return; - md->length += 8 * CURL_SHA256_BLOCK_SIZE; - md->curlen = 0; - } - } - } -} - -/* - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (32 bytes) - @return 0 if successful -*/ -static void my_sha256_final(unsigned char *out, void *ctx) -{ - struct sha256_state *md = ctx; - int i; - - if(md->curlen >= sizeof(md->buf)) - return; - - /* Increase the length of the message */ - md->length += md->curlen * 8; - - /* Append the '1' bit */ - md->buf[md->curlen++] = (unsigned char)0x80; - - /* If the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if(md->curlen > 56) { - while(md->curlen < 64) { - md->buf[md->curlen++] = 0; - } - sha256_compress(md, md->buf); - md->curlen = 0; - } - - /* Pad up to 56 bytes of zeroes */ - while(md->curlen < 56) { - md->buf[md->curlen++] = 0; - } - - /* Store length */ - WPA_PUT_BE64(md->buf + 56, md->length); - sha256_compress(md, md->buf); - - /* Copy output */ - for(i = 0; i < 8; i++) - WPA_PUT_BE32(out + (4 * i), md->state[i]); -} - -#endif /* CRYPTO LIBS */ - -/* - * Curl_sha256it() - * - * Generates a SHA256 hash for the given input data. - * - * Parameters: - * - * output [in/out] - The output buffer. - * input [in] - The input data. - * length [in] - The input length. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input, - size_t len) -{ - CURLcode result; - my_sha256_ctx ctx; - - result = my_sha256_init(&ctx); - if(!result) { - do { - unsigned int ilen = (unsigned int)CURLMIN(len, UINT_MAX); - my_sha256_update(&ctx, input, ilen); - len -= ilen; - input += ilen; - } while(len); - my_sha256_final(output, &ctx); - } - return result; -} - -const struct HMAC_params Curl_HMAC_SHA256 = { - my_sha256_init, /* Hash initialization function. */ - my_sha256_update, /* Hash update function. */ - my_sha256_final, /* Hash computation end function. */ - sizeof(my_sha256_ctx), /* Size of hash context structure. */ - 64, /* Maximum key length. */ - 32 /* Result size. */ -}; - -#endif /* AWS, DIGEST, or libssh2 */ diff --git a/vendor/curl/lib/sigpipe.h b/vendor/curl/lib/sigpipe.h deleted file mode 100644 index b48979695..000000000 --- a/vendor/curl/lib/sigpipe.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef HEADER_CURL_SIGPIPE_H -#define HEADER_CURL_SIGPIPE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(HAVE_SIGACTION) && !defined(USE_SO_NOSIGPIPE) -#include - -struct Curl_sigpipe_ctx { - struct sigaction old_pipe_act; - BIT(no_signal); -}; - -static CURL_INLINE void sigpipe_init(struct Curl_sigpipe_ctx *ig) -{ - memset(ig, 0, sizeof(*ig)); - ig->no_signal = TRUE; -} - -/* - * sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl - * internals, and then sigpipe_restore() will restore the situation when we - * return from libcurl again. - */ -static CURL_INLINE void sigpipe_ignore(struct Curl_easy *data, - struct Curl_sigpipe_ctx *ig) -{ - /* get a local copy of no_signal because the Curl_easy might not be - around when we restore */ - ig->no_signal = data->set.no_signal; - if(!data->set.no_signal) { - struct sigaction action; - /* first, extract the existing situation */ - sigaction(SIGPIPE, NULL, &ig->old_pipe_act); - action = ig->old_pipe_act; - /* ignore this signal */ - action.sa_handler = SIG_IGN; -#ifdef SA_SIGINFO - /* clear SA_SIGINFO flag since we are using sa_handler */ - action.sa_flags &= ~SA_SIGINFO; -#endif - sigaction(SIGPIPE, &action, NULL); - } -} - -/* - * sigpipe_restore() puts back the outside world's opinion of signal handler - * and SIGPIPE handling. It MUST only be called after a corresponding - * sigpipe_ignore() was used. - */ -static CURL_INLINE void sigpipe_restore(struct Curl_sigpipe_ctx *ig) -{ - if(!ig->no_signal) - /* restore the outside state */ - sigaction(SIGPIPE, &ig->old_pipe_act, NULL); -} - -static CURL_INLINE void sigpipe_apply(struct Curl_easy *data, - struct Curl_sigpipe_ctx *ig) -{ - if(data && (data->set.no_signal != ig->no_signal)) { - sigpipe_restore(ig); - sigpipe_ignore(data, ig); - } -} - -#else /* !HAVE_SIGACTION || USE_SO_NOSIGPIPE */ -/* for systems without sigaction or where SO_NOSIGPIPE is used. */ -#define sigpipe_ignore(x, y) do { (void)(x); (void)(y); } while(0) -#define sigpipe_apply(x, y) do { (void)(x); (void)(y); } while(0) -#define sigpipe_init(x) do { (void)(x); } while(0) -#define sigpipe_restore(x) do { (void)(x); } while(0) - -struct Curl_sigpipe_ctx { - bool dummy; -}; - -#endif /* else HAVE_SIGACTION && !USE_SO_NOSIGPIPE */ - -#endif /* HEADER_CURL_SIGPIPE_H */ diff --git a/vendor/curl/lib/slist.c b/vendor/curl/lib/slist.c deleted file mode 100644 index 83fd2918c..000000000 --- a/vendor/curl/lib/slist.c +++ /dev/null @@ -1,139 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "slist.h" - -/* returns last node in linked list */ -static struct curl_slist *slist_get_last(struct curl_slist *list) -{ - struct curl_slist *item; - - /* if caller passed us a NULL, return now */ - if(!list) - return NULL; - - /* loop through to find the last item */ - item = list; - while(item->next) { - item = item->next; - } - return item; -} - -/* - * Curl_slist_append_nodup() appends a string to the linked list. Rather than - * copying the string in dynamic storage, it takes its ownership. The string - * should have been malloc()ated. Curl_slist_append_nodup always returns - * the address of the first record, so that you can use this function as an - * initialization function as well as an append function. - * If an error occurs, NULL is returned and the string argument is NOT - * released. - */ -struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, - const char *data) -{ - struct curl_slist *last; - struct curl_slist *new_item; - - DEBUGASSERT(data); - - new_item = curlx_malloc(sizeof(struct curl_slist)); - if(!new_item) - return NULL; - - new_item->next = NULL; - new_item->data = CURL_UNCONST(data); - - /* if this is the first item, then new_item *is* the list */ - if(!list) - return new_item; - - last = slist_get_last(list); - last->next = new_item; - return list; -} - -/* - * curl_slist_append() appends a string to the linked list. It always returns - * the address of the first record, so that you can use this function as an - * initialization function as well as an append function. If you find this - * bothersome, then create a separate _init function and call it - * appropriately from within the program. - */ -struct curl_slist *curl_slist_append(struct curl_slist *list, const char *data) -{ - char *dupdata = curlx_strdup(data); - - if(!dupdata) - return NULL; - - list = Curl_slist_append_nodup(list, dupdata); - if(!list) - curlx_free(dupdata); - - return list; -} - -/* - * Curl_slist_duplicate() duplicates a linked list. It always returns the - * address of the first record of the cloned list or NULL in case of an - * error (or if the input list was NULL). - */ -struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist) -{ - struct curl_slist *outlist = NULL; - struct curl_slist *tmp; - - while(inlist) { - tmp = curl_slist_append(outlist, inlist->data); - - if(!tmp) { - curl_slist_free_all(outlist); - return NULL; - } - - outlist = tmp; - inlist = inlist->next; - } - return outlist; -} - -/* be nice and clean up resources */ -void curl_slist_free_all(struct curl_slist *list) -{ - struct curl_slist *next; - struct curl_slist *item; - - if(!list) - return; - - item = list; - do { - next = item->next; - curlx_safefree(item->data); - curlx_free(item); - item = next; - } while(next); -} diff --git a/vendor/curl/lib/slist.h b/vendor/curl/lib/slist.h deleted file mode 100644 index 47a30824d..000000000 --- a/vendor/curl/lib/slist.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef HEADER_CURL_SLIST_H -#define HEADER_CURL_SLIST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* - * Curl_slist_duplicate() duplicates a linked list. It always returns the - * address of the first record of the cloned list or NULL in case of an - * error (or if the input list was NULL). - */ -struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist); - -/* - * Curl_slist_append_nodup() takes ownership of the given string and appends - * it to the list. - */ -struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, - const char *data); - -#endif /* HEADER_CURL_SLIST_H */ diff --git a/vendor/curl/lib/smb.c b/vendor/curl/lib/smb.c deleted file mode 100644 index 6a97d2e00..000000000 --- a/vendor/curl/lib/smb.c +++ /dev/null @@ -1,1231 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Bill Nagel , Exacq Technologies - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" - -#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) - -#ifdef HAVE_ARPA_INET_H -#include /* for htons() */ -#endif - -#include "smb.h" -#include "url.h" -#include "sendf.h" -#include "curl_trc.h" -#include "cfilters.h" -#include "connect.h" -#include "progress.h" -#include "transfer.h" -#include "select.h" -#include "curl_ntlm_core.h" -#include "escape.h" -#include "curl_endian.h" -#include "curlx/strcopy.h" - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_SMB_EASY "meta:proto:smb:easy" -/* meta key for storing protocol meta at connection */ -#define CURL_META_SMB_CONN "meta:proto:smb:conn" - -enum smb_conn_state { - SMB_NOT_CONNECTED = 0, - SMB_CONNECTING, - SMB_NEGOTIATE, - SMB_SETUP, - SMB_CONNECTED -}; - -/* SMB connection data, kept at connection */ -struct smb_conn { - enum smb_conn_state state; - char *user; - char *domain; - char *share; - unsigned char challenge[8]; - unsigned int session_key; - unsigned short uid; - char *recv_buf; - char *send_buf; - size_t upload_size; - size_t send_size; - size_t sent; - size_t got; -}; - -/* SMB request state */ -enum smb_req_state { - SMB_REQUESTING, - SMB_TREE_CONNECT, - SMB_OPEN, - SMB_DOWNLOAD, - SMB_UPLOAD, - SMB_CLOSE, - SMB_TREE_DISCONNECT, - SMB_DONE -}; - -/* SMB request data, kept at easy handle */ -struct smb_request { - enum smb_req_state state; - char *path; - unsigned short tid; /* Even if we connect to the same tree as another */ - unsigned short fid; /* request, the tid will be different */ - CURLcode result; -}; - -/* - * Definitions for SMB protocol data structures - */ -#if defined(_MSC_VER) || defined(__ILEC400__) -# define PACK -# pragma pack(push) -# pragma pack(1) -#elif defined(__GNUC__) -# define PACK __attribute__((packed)) -#else -# define PACK -#endif - -#define SMB_COM_CLOSE 0x04 -#define SMB_COM_READ_ANDX 0x2e -#define SMB_COM_WRITE_ANDX 0x2f -#define SMB_COM_TREE_DISCONNECT 0x71 -#define SMB_COM_NEGOTIATE 0x72 -#define SMB_COM_SETUP_ANDX 0x73 -#define SMB_COM_TREE_CONNECT_ANDX 0x75 -#define SMB_COM_NT_CREATE_ANDX 0xa2 -#define SMB_COM_NO_ANDX_COMMAND 0xff - -#define SMB_WC_CLOSE 0x03 -#define SMB_WC_READ_ANDX 0x0c -#define SMB_WC_WRITE_ANDX 0x0e -#define SMB_WC_SETUP_ANDX 0x0d -#define SMB_WC_TREE_CONNECT_ANDX 0x04 -#define SMB_WC_NT_CREATE_ANDX 0x18 - -#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10 -#define SMB_FLAGS_CASELESS_PATHNAMES 0x08 -/* #define SMB_FLAGS2_UNICODE_STRINGS 0x8000 */ -#define SMB_FLAGS2_IS_LONG_NAME 0x0040 -#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001 - -#define SMB_CAP_LARGE_FILES 0x08 -#define SMB_GENERIC_WRITE 0x40000000 -#define SMB_GENERIC_READ 0x80000000 -#define SMB_FILE_SHARE_ALL 0x07 -#define SMB_FILE_OPEN 0x01 -#define SMB_FILE_OVERWRITE_IF 0x05 - -#define SMB_ERR_NOACCESS 0x00050001 - -struct smb_header { - unsigned char nbt_type; - unsigned char nbt_flags; - unsigned short nbt_length; - unsigned char magic[4]; - unsigned char command; - unsigned int status; - unsigned char flags; - unsigned short flags2; - unsigned short pid_high; - unsigned char signature[8]; - unsigned short pad; - unsigned short tid; - unsigned short pid; - unsigned short uid; - unsigned short mid; -} PACK; - -struct smb_negotiate_response { - struct smb_header h; - unsigned char word_count; - unsigned short dialect_index; - unsigned char security_mode; - unsigned short max_mpx_count; - unsigned short max_number_vcs; - unsigned int max_buffer_size; - unsigned int max_raw_size; - unsigned int session_key; - unsigned int capabilities; - unsigned int system_time_low; - unsigned int system_time_high; - unsigned short server_time_zone; - unsigned char encryption_key_length; - unsigned short byte_count; - char bytes[1]; -} PACK; - -struct andx { - unsigned char command; - unsigned char pad; - unsigned short offset; -} PACK; - -struct smb_setup { - unsigned char word_count; - struct andx andx; - unsigned short max_buffer_size; - unsigned short max_mpx_count; - unsigned short vc_number; - unsigned int session_key; - unsigned short lengths[2]; - unsigned int pad; - unsigned int capabilities; - unsigned short byte_count; - char bytes[1024]; -} PACK; - -struct smb_tree_connect { - unsigned char word_count; - struct andx andx; - unsigned short flags; - unsigned short pw_len; - unsigned short byte_count; - char bytes[1024]; -} PACK; - -struct smb_nt_create { - unsigned char word_count; - struct andx andx; - unsigned char pad; - unsigned short name_length; - unsigned int flags; - unsigned int root_fid; - unsigned int access; - curl_off_t allocation_size; - unsigned int ext_file_attributes; - unsigned int share_access; - unsigned int create_disposition; - unsigned int create_options; - unsigned int impersonation_level; - unsigned char security_flags; - unsigned short byte_count; - char bytes[1024]; -} PACK; - -struct smb_nt_create_response { - struct smb_header h; - unsigned char word_count; - struct andx andx; - unsigned char op_lock_level; - unsigned short fid; - unsigned int create_disposition; - - curl_off_t create_time; - curl_off_t last_access_time; - curl_off_t last_write_time; - curl_off_t last_change_time; - unsigned int ext_file_attributes; - curl_off_t allocation_size; - curl_off_t end_of_file; -} PACK; - -struct smb_read { - unsigned char word_count; - struct andx andx; - unsigned short fid; - unsigned int offset; - unsigned short max_bytes; - unsigned short min_bytes; - unsigned int timeout; - unsigned short remaining; - unsigned int offset_high; - unsigned short byte_count; -} PACK; - -struct smb_write { - struct smb_header h; - unsigned char word_count; - struct andx andx; - unsigned short fid; - unsigned int offset; - unsigned int timeout; - unsigned short write_mode; - unsigned short remaining; - unsigned short pad; - unsigned short data_length; - unsigned short data_offset; - unsigned int offset_high; - unsigned short byte_count; - unsigned char pad2; -} PACK; - -struct smb_close { - unsigned char word_count; - unsigned short fid; - unsigned int last_mtime; - unsigned short byte_count; -} PACK; - -struct smb_tree_disconnect { - unsigned char word_count; - unsigned short byte_count; -} PACK; - -#if defined(_MSC_VER) || defined(__ILEC400__) -# pragma pack(pop) -#endif - -#define MAX_PAYLOAD_SIZE 0x8000 -#define MAX_MESSAGE_SIZE (MAX_PAYLOAD_SIZE + 0x1000) -#define CLIENTNAME "curl" -#define SERVICENAME "?????" - -/* SMB is mostly little endian */ -#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ - defined(__OS400__) -static unsigned short smb_swap16(unsigned short x) -{ - return (unsigned short)((x << 8) | ((x >> 8) & 0xff)); -} - -static unsigned int smb_swap32(unsigned int x) -{ - return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | - ((x >> 24) & 0xff); -} - -static curl_off_t smb_swap64(curl_off_t x) -{ - return ((curl_off_t)smb_swap32((unsigned int)x) << 32) | - smb_swap32((unsigned int)(x >> 32)); -} - -#else -# define smb_swap16(x) (x) -# define smb_swap32(x) (x) -# define smb_swap64(x) (x) -#endif - -static void conn_state(struct Curl_easy *data, struct smb_conn *smbc, - enum smb_conn_state newstate) -{ -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - /* For debug purposes */ - static const char * const names[] = { - "SMB_NOT_CONNECTED", - "SMB_CONNECTING", - "SMB_NEGOTIATE", - "SMB_SETUP", - "SMB_CONNECTED", - /* LAST */ - }; - - if(smbc->state != newstate) - infof(data, "SMB conn %p state change from %s to %s", - (void *)smbc, names[smbc->state], names[newstate]); -#else - (void)data; -#endif - smbc->state = newstate; -} - -static void request_state(struct Curl_easy *data, - enum smb_req_state newstate) -{ - struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY); - if(req) { -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - /* For debug purposes */ - static const char * const names[] = { - "SMB_REQUESTING", - "SMB_TREE_CONNECT", - "SMB_OPEN", - "SMB_DOWNLOAD", - "SMB_UPLOAD", - "SMB_CLOSE", - "SMB_TREE_DISCONNECT", - "SMB_DONE", - /* LAST */ - }; - - if(req->state != newstate) - infof(data, "SMB request %p state change from %s to %s", - (void *)req, names[req->state], names[newstate]); -#endif - - req->state = newstate; - } -} - -static void smb_easy_dtor(void *key, size_t klen, void *entry) -{ - struct smb_request *req = entry; - (void)key; - (void)klen; - curlx_safefree(req->path); - curlx_free(req); -} - -static void smb_conn_dtor(void *key, size_t klen, void *entry) -{ - struct smb_conn *smbc = entry; - (void)key; - (void)klen; - curlx_safefree(smbc->share); - curlx_safefree(smbc->domain); - curlx_safefree(smbc->recv_buf); - curlx_safefree(smbc->send_buf); - curlx_free(smbc); -} - -static CURLcode smb_parse_url_path(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - char *path; - char *slash, *s; - CURLcode result; - - /* URL decode the path */ - result = Curl_urldecode(data->state.up.path, 0, &path, NULL, REJECT_CTRL); - if(result) - return result; - - /* Parse the path for the share */ - curlx_safefree(smbc->share); - smbc->share = curlx_strdup((*path == '/' || *path == '\\') - ? path + 1 : path); - curlx_free(path); - if(!smbc->share) - return CURLE_OUT_OF_MEMORY; - - slash = strchr(smbc->share, '/'); - if(!slash) - slash = strchr(smbc->share, '\\'); - - /* The share must be present */ - if(!slash) { - curlx_safefree(smbc->share); - failf(data, "missing share in URL path for SMB"); - return CURLE_URL_MALFORMAT; - } - - /* Parse the path for the file path converting any forward slashes into - backslashes */ - *slash++ = 0; - for(s = slash; *s; s++) { - if(*s == '/') - *s = '\\'; - } - /* keep a copy at easy struct to not share this with connection state */ - req->path = curlx_strdup(slash); - if(!req->path) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -/* this should setup things in the connection, not in the easy - handle */ -static CURLcode smb_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct smb_conn *smbc; - struct smb_request *req; - - /* Initialize the connection state */ - smbc = curlx_calloc(1, sizeof(*smbc)); - if(!smbc || - Curl_conn_meta_set(conn, CURL_META_SMB_CONN, smbc, smb_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - /* Initialize the request state */ - req = curlx_calloc(1, sizeof(*req)); - if(!req || - Curl_meta_set(data, CURL_META_SMB_EASY, req, smb_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - /* Parse the URL path */ - return smb_parse_url_path(data, smbc, req); -} - -static CURLcode smb_connect(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN); - char *slash; - - (void)done; - if(!smbc) - return CURLE_FAILED_INIT; - - /* Check we have a username and password to authenticate with */ - if(!data->state.aptr.user) - return CURLE_LOGIN_DENIED; - - /* Initialize the connection state */ - smbc->state = SMB_CONNECTING; - smbc->recv_buf = curlx_malloc(MAX_MESSAGE_SIZE); - if(!smbc->recv_buf) - return CURLE_OUT_OF_MEMORY; - smbc->send_buf = curlx_malloc(MAX_MESSAGE_SIZE); - if(!smbc->send_buf) - return CURLE_OUT_OF_MEMORY; - - /* Parse the username, domain, and password */ - slash = strchr(conn->user, '/'); - if(!slash) - slash = strchr(conn->user, '\\'); - - if(slash) { - smbc->user = slash + 1; - smbc->domain = curlx_strdup(conn->user); - if(!smbc->domain) - return CURLE_OUT_OF_MEMORY; - smbc->domain[slash - conn->user] = 0; - } - else { - smbc->user = conn->user; - smbc->domain = curlx_strdup(conn->host.name); - if(!smbc->domain) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -static CURLcode smb_recv_message(struct Curl_easy *data, - struct smb_conn *smbc, - void **msg) -{ - char *buf = smbc->recv_buf; - size_t bytes_read; - size_t nbt_size; - size_t msg_size = sizeof(struct smb_header); - size_t len = MAX_MESSAGE_SIZE - smbc->got; - CURLcode result; - - result = Curl_xfer_recv(data, buf + smbc->got, len, &bytes_read); - if(result) - return result; - - if(!bytes_read) - return CURLE_OK; - - smbc->got += bytes_read; - - /* Check for a 32-bit nbt header */ - if(smbc->got < sizeof(unsigned int)) - return CURLE_OK; - - nbt_size = Curl_read16_be((const unsigned char *) - (buf + sizeof(unsigned short))) + - sizeof(unsigned int); - if(nbt_size > MAX_MESSAGE_SIZE) { - failf(data, "too large NetBIOS frame size %zu", nbt_size); - return CURLE_RECV_ERROR; - } - else if(nbt_size < msg_size) { - /* Each SMB message must be at least this large, e.g. 32 bytes */ - failf(data, "too small NetBIOS frame size %zu", nbt_size); - return CURLE_RECV_ERROR; - } - - if(smbc->got < nbt_size) - return CURLE_OK; - - if(nbt_size >= msg_size + 1) { - /* Add the word count */ - msg_size += 1 + (((unsigned char)buf[msg_size]) * sizeof(unsigned short)); - if(nbt_size >= msg_size + sizeof(unsigned short)) { - /* Add the byte count */ - msg_size += sizeof(unsigned short) + - Curl_read16_le((const unsigned char *)&buf[msg_size]); - if(nbt_size < msg_size) - return CURLE_RECV_ERROR; - } - } - - *msg = buf; - - return CURLE_OK; -} - -static void smb_pop_message(struct smb_conn *smbc) -{ - smbc->got = 0; -} - -static void smb_format_message(struct smb_conn *smbc, - struct smb_request *req, - struct smb_header *h, - unsigned char cmd, size_t len) -{ - const unsigned int pid = 0xbad71d; /* made up */ - - memset(h, 0, sizeof(*h)); - h->nbt_length = htons((unsigned short)(sizeof(*h) - sizeof(unsigned int) + - len)); - memcpy((char *)h->magic, "\xffSMB", 4); - h->command = cmd; - h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES; - h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME); - h->uid = smb_swap16(smbc->uid); - h->tid = smb_swap16(req->tid); - h->pid_high = smb_swap16((unsigned short)(pid >> 16)); - h->pid = smb_swap16((unsigned short)pid); -} - -static CURLcode smb_send(struct Curl_easy *data, struct smb_conn *smbc, - size_t len, size_t upload_size) -{ - size_t bytes_written; - CURLcode result; - - result = Curl_xfer_send(data, smbc->send_buf, len, FALSE, &bytes_written); - if(result) - return result; - - if(bytes_written != len) { - smbc->send_size = len; - smbc->sent = bytes_written; - } - - smbc->upload_size = upload_size; - - return CURLE_OK; -} - -static CURLcode smb_flush(struct Curl_easy *data, struct smb_conn *smbc) -{ - size_t bytes_written; - size_t len = smbc->send_size - smbc->sent; - CURLcode result; - - if(!smbc->send_size) - return CURLE_OK; - - result = Curl_xfer_send(data, smbc->send_buf + smbc->sent, len, FALSE, - &bytes_written); - if(result) - return result; - - if(bytes_written != len) - smbc->sent += bytes_written; - else - smbc->send_size = 0; - - return CURLE_OK; -} - -static CURLcode smb_send_message(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req, - unsigned char cmd, - const void *msg, size_t msg_len) -{ - if((MAX_MESSAGE_SIZE - sizeof(struct smb_header)) < msg_len) { - DEBUGASSERT(0); - return CURLE_SEND_ERROR; - } - smb_format_message(smbc, req, (struct smb_header *)smbc->send_buf, - cmd, msg_len); - memcpy(smbc->send_buf + sizeof(struct smb_header), msg, msg_len); - - return smb_send(data, smbc, sizeof(struct smb_header) + msg_len, 0); -} - -static CURLcode smb_send_negotiate(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - const char *msg = "\x00\x0c\x00\x02NT LM 0.12"; - - return smb_send_message(data, smbc, req, SMB_COM_NEGOTIATE, msg, 15); -} - -static CURLcode smb_send_setup(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN); - struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY); - struct smb_setup msg; - char *p = msg.bytes; - unsigned char lm_hash[21]; - unsigned char lm[24]; - unsigned char nt_hash[21]; - unsigned char nt[24]; - size_t byte_count; - - if(!smbc || !req) - return CURLE_FAILED_INIT; - - byte_count = sizeof(lm) + sizeof(nt) + - strlen(smbc->user) + strlen(smbc->domain) + - strlen(CURL_OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */ - if(byte_count > sizeof(msg.bytes)) - return CURLE_FILESIZE_EXCEEDED; - - Curl_ntlm_core_mk_lm_hash(conn->passwd, lm_hash); - Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm); - Curl_ntlm_core_mk_nt_hash(conn->passwd, nt_hash); - Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt); - - memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes)); - msg.word_count = SMB_WC_SETUP_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE); - msg.max_mpx_count = smb_swap16(1); - msg.vc_number = smb_swap16(1); - msg.session_key = smb_swap32(smbc->session_key); - msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES); - msg.lengths[0] = smb_swap16(sizeof(lm)); - msg.lengths[1] = smb_swap16(sizeof(nt)); - memcpy(p, lm, sizeof(lm)); - p += sizeof(lm); - memcpy(p, nt, sizeof(nt)); - p += sizeof(nt); - p += curl_msnprintf(p, byte_count - sizeof(nt) - sizeof(lm), - "%s%c" /* user */ - "%s%c" /* domain */ - "%s%c" /* OS */ - "%s", /* client name */ - smbc->user, 0, smbc->domain, 0, CURL_OS, 0, CLIENTNAME); - p++; /* count the final null-termination */ - DEBUGASSERT(byte_count == (size_t)(p - msg.bytes)); - msg.byte_count = smb_swap16((unsigned short)byte_count); - - return smb_send_message(data, smbc, req, SMB_COM_SETUP_ANDX, &msg, - sizeof(msg) - sizeof(msg.bytes) + byte_count); -} - -static CURLcode smb_send_tree_connect(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - struct smb_tree_connect msg; - struct connectdata *conn = data->conn; - char *p = msg.bytes; - const size_t byte_count = strlen(conn->host.name) + strlen(smbc->share) + - strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */ - - if(byte_count > sizeof(msg.bytes)) - return CURLE_FILESIZE_EXCEEDED; - - memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes)); - msg.word_count = SMB_WC_TREE_CONNECT_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - msg.pw_len = 0; - - p += curl_msnprintf(p, byte_count, - "\\\\%s\\" /* hostname */ - "%s%c" /* share */ - "%s", /* service */ - conn->host.name, smbc->share, 0, SERVICENAME); - p++; /* count the final null-termination */ - DEBUGASSERT(byte_count == (size_t)(p - msg.bytes)); - msg.byte_count = smb_swap16((unsigned short)byte_count); - - return smb_send_message(data, smbc, req, SMB_COM_TREE_CONNECT_ANDX, &msg, - sizeof(msg) - sizeof(msg.bytes) + byte_count); -} - -static CURLcode smb_send_open(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - struct smb_nt_create msg; - const size_t byte_count = strlen(req->path) + 1; - - if(byte_count > sizeof(msg.bytes)) - return CURLE_FILESIZE_EXCEEDED; - - memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes)); - msg.word_count = SMB_WC_NT_CREATE_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - msg.name_length = smb_swap16((unsigned short)(byte_count - 1)); - msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL); - if(data->state.upload) { - msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE); - msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF); - } - else { - msg.access = smb_swap32(SMB_GENERIC_READ); - msg.create_disposition = smb_swap32(SMB_FILE_OPEN); - } - msg.byte_count = smb_swap16((unsigned short)byte_count); - curlx_strcopy(msg.bytes, sizeof(msg.bytes), req->path, byte_count - 1); - - return smb_send_message(data, smbc, req, SMB_COM_NT_CREATE_ANDX, &msg, - sizeof(msg) - sizeof(msg.bytes) + byte_count); -} - -static CURLcode smb_send_close(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - struct smb_close msg; - - memset(&msg, 0, sizeof(msg)); - msg.word_count = SMB_WC_CLOSE; - msg.fid = smb_swap16(req->fid); - - return smb_send_message(data, smbc, req, SMB_COM_CLOSE, &msg, sizeof(msg)); -} - -static CURLcode smb_send_tree_disconnect(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - struct smb_tree_disconnect msg; - memset(&msg, 0, sizeof(msg)); - return smb_send_message(data, smbc, req, SMB_COM_TREE_DISCONNECT, - &msg, sizeof(msg)); -} - -static CURLcode smb_send_read(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - curl_off_t offset = data->req.offset; - struct smb_read msg; - - memset(&msg, 0, sizeof(msg)); - msg.word_count = SMB_WC_READ_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - msg.fid = smb_swap16(req->fid); - msg.offset = smb_swap32((unsigned int)offset); - msg.offset_high = smb_swap32((unsigned int)(offset >> 32)); - msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE); - msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE); - - return smb_send_message(data, smbc, req, SMB_COM_READ_ANDX, - &msg, sizeof(msg)); -} - -static CURLcode smb_send_write(struct Curl_easy *data, - struct smb_conn *smbc, - struct smb_request *req) -{ - struct smb_write *msg; - curl_off_t offset = data->req.offset; - curl_off_t upload_size = data->req.size - data->req.bytecount; - - msg = (struct smb_write *)smbc->send_buf; - if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */ - upload_size = MAX_PAYLOAD_SIZE - 1; - - memset(msg, 0, sizeof(*msg)); - msg->word_count = SMB_WC_WRITE_ANDX; - msg->andx.command = SMB_COM_NO_ANDX_COMMAND; - msg->fid = smb_swap16(req->fid); - msg->offset = smb_swap32((unsigned int)offset); - msg->offset_high = smb_swap32((unsigned int)(offset >> 32)); - msg->data_length = smb_swap16((unsigned short)upload_size); - msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int)); - msg->byte_count = smb_swap16((unsigned short)(upload_size + 1)); - - smb_format_message(smbc, req, &msg->h, SMB_COM_WRITE_ANDX, - sizeof(*msg) - sizeof(msg->h) + (size_t)upload_size); - - return smb_send(data, smbc, sizeof(*msg), (size_t)upload_size); -} - -static CURLcode smb_send_and_recv(struct Curl_easy *data, - struct smb_conn *smbc, void **msg) -{ - CURLcode result; - *msg = NULL; /* if it returns early */ - - /* Check if there is data in the transfer buffer */ - if(!smbc->send_size && smbc->upload_size) { - size_t nread = smbc->upload_size > (size_t)MAX_MESSAGE_SIZE ? - (size_t)MAX_MESSAGE_SIZE : smbc->upload_size; - bool eos; - - result = Curl_client_read(data, smbc->send_buf, nread, &nread, &eos); - if(result && result != CURLE_AGAIN) - return result; - if(!nread) - return CURLE_OK; - - smbc->upload_size -= nread; - smbc->send_size = nread; - smbc->sent = 0; - } - - /* Check if there is data to send */ - if(smbc->send_size) { - result = smb_flush(data, smbc); - if(result) - return result; - } - - /* Check if there is still data to be sent */ - if(smbc->send_size || smbc->upload_size) - return CURLE_AGAIN; - - return smb_recv_message(data, smbc, msg); -} - -static CURLcode smb_connection_state(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN); - struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY); - struct smb_negotiate_response *nrsp; - struct smb_header *h; - CURLcode result; - void *msg = NULL; - - if(!smbc || !req) - return CURLE_FAILED_INIT; - - if(smbc->state == SMB_CONNECTING) { -#ifdef USE_SSL - if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - bool ssl_done = FALSE; - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssl_done); - if(result && result != CURLE_AGAIN) - return result; - if(!ssl_done) - return CURLE_OK; - } -#endif - - result = smb_send_negotiate(data, smbc, req); - if(result) { - connclose(conn, "SMB: failed to send negotiate message"); - return result; - } - - conn_state(data, smbc, SMB_NEGOTIATE); - } - - /* Send the previous message and check for a response */ - result = smb_send_and_recv(data, smbc, &msg); - if(result && result != CURLE_AGAIN) { - connclose(conn, "SMB: failed to communicate"); - return result; - } - - if(!msg) - return CURLE_OK; - - h = msg; - - switch(smbc->state) { - case SMB_NEGOTIATE: - if((smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) || - h->status) { - connclose(conn, "SMB: negotiation failed"); - return CURLE_COULDNT_CONNECT; - } - nrsp = msg; -#if defined(__GNUC__) && __GNUC__ >= 13 -#pragma GCC diagnostic push -/* error: 'memcpy' offset [74, 80] from the object at '' is out of - the bounds of referenced subobject 'bytes' with type 'char[1]' */ -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge)); -#if defined(__GNUC__) && __GNUC__ >= 13 -#pragma GCC diagnostic pop -#endif - smbc->session_key = smb_swap32(nrsp->session_key); - result = smb_send_setup(data); - if(result) { - connclose(conn, "SMB: failed to send setup message"); - return result; - } - conn_state(data, smbc, SMB_SETUP); - break; - - case SMB_SETUP: - if(h->status) { - connclose(conn, "SMB: authentication failed"); - return CURLE_LOGIN_DENIED; - } - smbc->uid = smb_swap16(h->uid); - conn_state(data, smbc, SMB_CONNECTED); - *done = TRUE; - break; - - default: - smb_pop_message(smbc); - return CURLE_OK; /* ignore */ - } - - smb_pop_message(smbc); - - return CURLE_OK; -} - -/* - * Convert a timestamp from the Windows world (100 nsec units from 1 Jan 1601) - * to POSIX time. Cap the output to fit within a time_t. - */ -static void get_posix_time(time_t *out, curl_off_t timestamp) -{ - if(timestamp >= (curl_off_t)116444736000000000) { - timestamp -= (curl_off_t)116444736000000000; - timestamp /= 10000000; -#if SIZEOF_TIME_T < SIZEOF_CURL_OFF_T - if(timestamp > TIME_T_MAX) - *out = TIME_T_MAX; - else if(timestamp < TIME_T_MIN) - *out = TIME_T_MIN; - else -#endif - *out = (time_t)timestamp; - } - else - *out = 0; -} - -static CURLcode smb_request_state(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN); - struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY); - struct smb_header *h; - enum smb_req_state next_state = SMB_DONE; - unsigned short len; - unsigned short off; - CURLcode result; - void *msg = NULL; - const struct smb_nt_create_response *smb_m; - - if(!smbc || !req) - return CURLE_FAILED_INIT; - - if(data->state.upload && (data->state.infilesize < 0)) { - failf(data, "SMB upload needs to know the size up front"); - return CURLE_SEND_ERROR; - } - - /* Start the request */ - if(req->state == SMB_REQUESTING) { - result = smb_send_tree_connect(data, smbc, req); - if(result) { - connclose(conn, "SMB: failed to send tree connect message"); - return result; - } - - request_state(data, SMB_TREE_CONNECT); - } - - /* Send the previous message and check for a response */ - result = smb_send_and_recv(data, smbc, &msg); - if(result && result != CURLE_AGAIN) { - connclose(conn, "SMB: failed to communicate"); - return result; - } - - if(!msg) - return CURLE_OK; - - h = msg; - - switch(req->state) { - case SMB_TREE_CONNECT: - if(h->status) { - req->result = CURLE_REMOTE_FILE_NOT_FOUND; - if(h->status == smb_swap32(SMB_ERR_NOACCESS)) - req->result = CURLE_REMOTE_ACCESS_DENIED; - break; - } - req->tid = smb_swap16(h->tid); - next_state = SMB_OPEN; - break; - - case SMB_OPEN: - if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) { - req->result = CURLE_REMOTE_FILE_NOT_FOUND; - if(h->status == smb_swap32(SMB_ERR_NOACCESS)) - req->result = CURLE_REMOTE_ACCESS_DENIED; - next_state = SMB_TREE_DISCONNECT; - break; - } - smb_m = (const struct smb_nt_create_response *)msg; - req->fid = smb_swap16(smb_m->fid); - data->req.offset = 0; - if(data->state.upload) { - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->req.size); - next_state = SMB_UPLOAD; - } - else { - data->req.size = smb_swap64(smb_m->end_of_file); - if(data->req.size < 0) { - req->result = CURLE_WEIRD_SERVER_REPLY; - next_state = SMB_CLOSE; - } - else { - Curl_pgrsSetDownloadSize(data, data->req.size); - if(data->set.get_filetime) - get_posix_time(&data->info.filetime, smb_m->last_change_time); - next_state = SMB_DOWNLOAD; - } - } - break; - - case SMB_DOWNLOAD: - if(h->status || smbc->got < sizeof(struct smb_header) + 15) { - req->result = CURLE_RECV_ERROR; - next_state = SMB_CLOSE; - break; - } - len = Curl_read16_le((const unsigned char *)msg + - sizeof(struct smb_header) + 11); - off = Curl_read16_le((const unsigned char *)msg + - sizeof(struct smb_header) + 13); - if(len > 0) { - if(off + sizeof(unsigned int) + len > smbc->got) { - failf(data, "Invalid input packet"); - result = CURLE_RECV_ERROR; - } - else - result = Curl_client_write(data, CLIENTWRITE_BODY, - (char *)msg + off + sizeof(unsigned int), - len); - if(result) { - req->result = result; - next_state = SMB_CLOSE; - break; - } - } - data->req.offset += len; - next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD; - break; - - case SMB_UPLOAD: - if(h->status || smbc->got < sizeof(struct smb_header) + 7) { - req->result = CURLE_UPLOAD_FAILED; - next_state = SMB_CLOSE; - break; - } - len = Curl_read16_le((const unsigned char *)msg + - sizeof(struct smb_header) + 5); - data->req.bytecount += len; - data->req.offset += len; - Curl_pgrs_upload_inc(data, len); - if(data->req.bytecount >= data->req.size) - next_state = SMB_CLOSE; - else - next_state = SMB_UPLOAD; - break; - - case SMB_CLOSE: - /* We do not care if the close failed, proceed to tree disconnect anyway */ - next_state = SMB_TREE_DISCONNECT; - break; - - case SMB_TREE_DISCONNECT: - next_state = SMB_DONE; - break; - - default: - smb_pop_message(smbc); - return CURLE_OK; /* ignore */ - } - - smb_pop_message(smbc); - - switch(next_state) { - case SMB_OPEN: - result = smb_send_open(data, smbc, req); - break; - - case SMB_DOWNLOAD: - result = smb_send_read(data, smbc, req); - break; - - case SMB_UPLOAD: - result = smb_send_write(data, smbc, req); - break; - - case SMB_CLOSE: - result = smb_send_close(data, smbc, req); - break; - - case SMB_TREE_DISCONNECT: - result = smb_send_tree_disconnect(data, smbc, req); - break; - - case SMB_DONE: - result = req->result; - *done = TRUE; - break; - - default: - break; - } - - if(result) { - connclose(conn, "SMB: failed to send message"); - return result; - } - - request_state(data, next_state); - - return CURLE_OK; -} - -static CURLcode smb_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - return Curl_pollset_add_inout(data, ps, data->conn->sock[FIRSTSOCKET]); -} - -static CURLcode smb_do(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN); - - *done = FALSE; - if(!smbc) - return CURLE_FAILED_INIT; - if(smbc->share) - return CURLE_OK; - return CURLE_URL_MALFORMAT; -} - -/* - * SMB handler interface - */ -const struct Curl_protocol Curl_protocol_smb = { - smb_setup_connection, /* setup_connection */ - smb_do, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - smb_connect, /* connect_it */ - smb_connection_state, /* connecting */ - smb_request_state, /* doing */ - smb_pollset, /* proto_pollset */ - smb_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* CURL_ENABLE_SMB && USE_CURL_NTLM_CORE && SIZEOF_CURL_OFF_T > 4 */ diff --git a/vendor/curl/lib/smb.h b/vendor/curl/lib/smb.h deleted file mode 100644 index 5a92ad13d..000000000 --- a/vendor/curl/lib/smb.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_SMB_H -#define HEADER_CURL_SMB_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Bill Nagel , Exacq Technologies - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) -extern const struct Curl_protocol Curl_protocol_smb; -#endif - -#endif /* HEADER_CURL_SMB_H */ diff --git a/vendor/curl/lib/smtp.c b/vendor/curl/lib/smtp.c deleted file mode 100644 index b5c425cd7..000000000 --- a/vendor/curl/lib/smtp.c +++ /dev/null @@ -1,2007 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC1870 SMTP Service Extension for Message Size - * RFC2195 CRAM-MD5 authentication - * RFC2831 DIGEST-MD5 authentication - * RFC3207 SMTP over TLS - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * RFC4954 SMTP Authentication - * RFC5321 SMTP protocol - * RFC5890 Internationalized Domain Names for Applications (IDNA) - * RFC6531 SMTP Extension for Internationalized Email - * RFC6532 Internationalized Email Headers - * RFC6749 OAuth 2.0 Authorization Framework - * RFC8314 Use of TLS for Email Submission and Access - * Draft SMTP URL Interface - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "smtp.h" - -#ifndef CURL_DISABLE_SMTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "sendf.h" -#include "curl_trc.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "pingpong.h" -#include "mime.h" -#include "vtls/vtls.h" -#include "cfilters.h" -#include "connect.h" -#include "select.h" -#include "url.h" -#include "curl_gethostname.h" -#include "bufref.h" -#include "curl_sasl.h" -#include "idn.h" -#include "curlx/strparse.h" - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_SMTP_EASY "meta:proto:smtp:easy" -/* meta key for storing protocol meta at connection */ -#define CURL_META_SMTP_CONN "meta:proto:smtp:conn" - -/**************************************************************************** - * SMTP unique setup - ***************************************************************************/ -typedef enum { - SMTP_STOP, /* do nothing state, stops the state machine */ - SMTP_SERVERGREET, /* waiting for the initial greeting immediately after - a connect */ - SMTP_EHLO, - SMTP_HELO, - SMTP_STARTTLS, - SMTP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS - (multi mode only) */ - SMTP_AUTH, - SMTP_COMMAND, /* VRFY, EXPN, NOOP, RSET and HELP */ - SMTP_MAIL, /* MAIL FROM */ - SMTP_RCPT, /* RCPT TO */ - SMTP_DATA, - SMTP_POSTDATA, - SMTP_QUIT, - SMTP_LAST /* never used */ -} smtpstate; - -/* smtp_conn is used for struct connection-oriented data in the connectdata - struct */ -struct smtp_conn { - struct pingpong pp; - struct SASL sasl; /* SASL-related storage */ - smtpstate state; /* Always use smtp.c:state() to change state! */ - char *domain; /* Client address/name to send in the EHLO */ - BIT(ssldone); /* Is connect() over SSL done? */ - BIT(tls_supported); /* StartTLS capability supported by server */ - BIT(size_supported); /* If server supports SIZE extension according to - RFC 1870 */ - BIT(utf8_supported); /* If server supports SMTPUTF8 extension according - to RFC 6531 */ - BIT(auth_supported); /* AUTH capability supported by server */ -}; - -/* This SMTP struct is used in the Curl_easy. All SMTP data that is - connection-oriented must be in smtp_conn to properly deal with the fact that - perhaps the Curl_easy is changed between the times the connection is - used. */ -struct SMTP { - curl_pp_transfer transfer; - char *custom; /* Custom Request */ - struct curl_slist *rcpt; /* Recipient list */ - int rcpt_last_error; /* The last error received for RCPT TO command */ - size_t eob; /* Number of bytes of the EOB (End Of Body) that - have been received so far */ - BIT(rcpt_had_ok); /* Whether any of RCPT TO commands (depends on - total number of recipients) succeeded so far */ - BIT(trailing_crlf); /* Specifies if the trailing CRLF is present */ -}; - -/*********************************************************************** - * - * smtp_parse_url_options() - * - * Parse the URL login options. - */ -static CURLcode smtp_parse_url_options(struct connectdata *conn, - struct smtp_conn *smtpc) -{ - CURLcode result = CURLE_OK; - const char *ptr = conn->options; - - while(!result && ptr && *ptr) { - const char *key = ptr; - const char *value; - - while(*ptr && *ptr != '=') - ptr++; - - value = ptr + 1; - - while(*ptr && *ptr != ';') - ptr++; - - if(curl_strnequal(key, "AUTH=", 5)) - result = Curl_sasl_parse_url_auth_option(&smtpc->sasl, - value, ptr - value); - else - result = CURLE_URL_MALFORMAT; - - if(*ptr == ';') - ptr++; - } - - return result; -} - -/*********************************************************************** - * - * smtp_parse_url_path() - * - * Parse the URL path into separate path components. - */ -static CURLcode smtp_parse_url_path(struct Curl_easy *data, - struct smtp_conn *smtpc) -{ - /* The SMTP struct is already initialised in smtp_connect() */ - const char *path = &data->state.up.path[1]; /* skip leading path */ - char localhost[HOSTNAME_MAX + 1]; - - /* Calculate the path if necessary */ - if(!*path) { - if(!Curl_gethostname(localhost, sizeof(localhost))) - path = localhost; - else - path = "localhost"; - } - - /* URL decode the path and use it as the domain in our EHLO */ - return Curl_urldecode(path, 0, &smtpc->domain, NULL, REJECT_CTRL); -} - -/*********************************************************************** - * - * smtp_parse_custom_request() - * - * Parse the custom request. - */ -static CURLcode smtp_parse_custom_request(struct Curl_easy *data, - struct SMTP *smtp) -{ - CURLcode result = CURLE_OK; - const char *custom = data->set.str[STRING_CUSTOMREQUEST]; - - /* URL decode the custom request */ - if(custom) - result = Curl_urldecode(custom, 0, &smtp->custom, NULL, REJECT_CTRL); - - return result; -} - -/*********************************************************************** - * - * smtp_parse_address() - * - * Parse the fully qualified mailbox address into a local address part and the - * hostname, converting the hostname to an IDN A-label, as per RFC-5890, if - * necessary. - * - * Parameters: - * - * fqma [in] - The fully qualified mailbox address (which may or - * may not contain UTF-8 characters). - * address [in/out] - A new allocated buffer which holds the local - * address part of the mailbox. This buffer must be - * free'ed by the caller. - * host [in/out] - The hostname structure that holds the original, - * and optionally encoded, hostname. - * Curl_free_idnconverted_hostname() must be called - * once the caller has finished with the structure. - * - * Returns CURLE_OK on success. - * - * Notes: - * - * Should a UTF-8 hostname require conversion to IDN ACE and we cannot honor - * that conversion then we shall return success. This allow the caller to send - * the data to the server as a U-label (as per RFC-6531 sect. 3.2). - * - * If an mailbox '@' separator cannot be located then the mailbox is considered - * to be either a local mailbox or an invalid mailbox (depending on what the - * calling function deems it to be) then the input will be returned in - * the address part with the hostname being NULL. - */ -static CURLcode smtp_parse_address(const char *fqma, char **address, - struct hostname *host, const char **suffix) -{ - CURLcode result = CURLE_OK; - size_t length; - char *addressend; - - /* Duplicate the fully qualified email address so we can manipulate it, - ensuring it does not contain the delimiters if specified */ - char *dup = curlx_strdup(fqma[0] == '<' ? fqma + 1 : fqma); - if(!dup) - return CURLE_OUT_OF_MEMORY; - - if(fqma[0] != '<') { - length = strlen(dup); - if(length) { - if(dup[length - 1] == '>') - dup[length - 1] = '\0'; - } - } - else { - addressend = strrchr(dup, '>'); - if(addressend) { - *addressend = '\0'; - *suffix = addressend + 1; - } - } - - /* Extract the hostname from the address (if we can) */ - host->name = strpbrk(dup, "@"); - if(host->name) { - *host->name = '\0'; - host->name = host->name + 1; - - /* Attempt to convert the hostname to IDN ACE */ - (void)Curl_idnconvert_hostname(host); - - /* If Curl_idnconvert_hostname() fails then we shall attempt to continue - and send the hostname using UTF-8 rather than as 7-bit ACE (which is - our preference) */ - } - - /* Extract the local address from the mailbox */ - *address = dup; - - return result; -} - -struct cr_eob_ctx { - struct Curl_creader super; - struct bufq buf; - size_t n_eob; /* how many EOB bytes we matched so far */ - size_t eob; /* Number of bytes of the EOB (End Of Body) that - have been received so far */ - BIT(read_eos); /* we read an EOS from the next reader */ - BIT(processed_eos); /* we read and processed an EOS */ - BIT(eos); /* we have returned an EOS */ -}; - -static CURLcode cr_eob_init(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_eob_ctx *ctx = reader->ctx; - (void)data; - /* The first char we read is the first on a line, as if we had - * read CRLF before */ - ctx->n_eob = 2; - Curl_bufq_init2(&ctx->buf, (16 * 1024), 1, BUFQ_OPT_SOFT_LIMIT); - return CURLE_OK; -} - -static void cr_eob_close(struct Curl_easy *data, struct Curl_creader *reader) -{ - struct cr_eob_ctx *ctx = reader->ctx; - (void)data; - Curl_bufq_free(&ctx->buf); -} - -/* this is the 5-bytes End-Of-Body marker for SMTP */ -#define SMTP_EOB "\r\n.\r\n" -#define SMTP_EOB_FIND_LEN 3 - -/* client reader doing SMTP End-Of-Body escaping. */ -static CURLcode cr_eob_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct cr_eob_ctx *ctx = reader->ctx; - CURLcode result = CURLE_OK; - size_t nread, i, start, n; - bool eos; - - if(!ctx->read_eos && Curl_bufq_is_empty(&ctx->buf)) { - /* Get more and convert it when needed */ - result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos); - CURL_TRC_SMTP(data, "cr_eob_read, next_read(len=%zu) -> %d, %zu eos=%d", - blen, result, nread, eos); - if(result) - return result; - - ctx->read_eos = eos; - if(nread) { - if(!ctx->n_eob && !memchr(buf, SMTP_EOB[0], nread)) { - /* not in the middle of a match, no EOB start found, pass */ - *pnread = nread; - *peos = FALSE; - return CURLE_OK; - } - /* scan for EOB (continuation) and convert */ - for(i = start = 0; i < nread; ++i) { - if(ctx->n_eob >= SMTP_EOB_FIND_LEN) { - /* matched the EOB prefix and seeing additional char, add '.' */ - result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n); - if(result) - return result; - result = Curl_bufq_cwrite(&ctx->buf, ".", 1, &n); - if(result) - return result; - ctx->n_eob = 0; - start = i; - if(data->state.infilesize > 0) - data->state.infilesize++; - } - - if(buf[i] != SMTP_EOB[ctx->n_eob]) - ctx->n_eob = 0; - - if(buf[i] == SMTP_EOB[ctx->n_eob]) { - /* matching another char of the EOB */ - ++ctx->n_eob; - } - } - - /* add any remainder to buf */ - if(start < nread) { - result = Curl_bufq_cwrite(&ctx->buf, buf + start, nread - start, &n); - if(result) - return result; - } - } - } - - *peos = FALSE; - - if(ctx->read_eos && !ctx->processed_eos) { - /* if we last matched a CRLF or if the data was empty, add ".\r\n" - * to end the body. If we sent something and it did not end with "\r\n", - * add "\r\n.\r\n" to end the body */ - const char *eob = SMTP_EOB; - CURL_TRC_SMTP(data, "auto-ending mail body with '\\r\\n.\\r\\n'"); - switch(ctx->n_eob) { - case 2: - /* seen a CRLF at the end, add the remainder */ - eob = &SMTP_EOB[2]; - break; - case 3: - /* ended with '\r\n.', we should escape the last '.' */ - eob = "." SMTP_EOB; - break; - default: - break; - } - result = Curl_bufq_cwrite(&ctx->buf, eob, strlen(eob), &n); - if(result) - return result; - ctx->processed_eos = TRUE; - } - - if(!Curl_bufq_is_empty(&ctx->buf)) { - result = Curl_bufq_cread(&ctx->buf, buf, blen, pnread); - } - else - *pnread = 0; - - if(ctx->read_eos && Curl_bufq_is_empty(&ctx->buf)) { - /* no more data, read all, done. */ - CURL_TRC_SMTP(data, "mail body complete, returning EOS"); - ctx->eos = TRUE; - } - *peos = (bool)ctx->eos; - DEBUGF(infof(data, "cr_eob_read(%zu) -> %d, %zu, %d", - blen, result, *pnread, *peos)); - return result; -} - -static curl_off_t cr_eob_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - /* this reader changes length depending on input */ - (void)data; - (void)reader; - return -1; -} - -static const struct Curl_crtype cr_eob = { - "cr-smtp-eob", - cr_eob_init, - cr_eob_read, - cr_eob_close, - Curl_creader_def_needs_rewind, - cr_eob_total_length, - Curl_creader_def_resume_from, - Curl_creader_def_cntrl, - Curl_creader_def_is_paused, - Curl_creader_def_done, - sizeof(struct cr_eob_ctx) -}; - -static CURLcode cr_eob_add(struct Curl_easy *data) -{ - struct Curl_creader *reader = NULL; - CURLcode result; - - result = Curl_creader_create(&reader, data, &cr_eob, CURL_CR_CONTENT_ENCODE); - if(!result) - result = Curl_creader_add(data, reader); - - if(result && reader) - Curl_creader_free(data, reader); - return result; -} - -/*********************************************************************** - * - * smtp_endofresp() - * - * Checks for an ending SMTP status code at the start of the given string, but - * also detects various capabilities from the EHLO response including the - * supported authentication mechanisms. - */ -static bool smtp_endofresp(struct Curl_easy *data, struct connectdata *conn, - const char *line, size_t len, int *resp) -{ - struct smtp_conn *smtpc = Curl_conn_meta_get(conn, CURL_META_SMTP_CONN); - bool end = FALSE; - (void)data; - - DEBUGASSERT(smtpc); - if(!smtpc) - return FALSE; - - /* Nothing for us */ - if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2])) - return FALSE; - - /* Do we have a command response? This should be the response code followed - by a space and optionally some text as per RFC-5321 and as outlined in - Section 4. Examples of RFC-4954 but some email servers ignore this and - only send the response code instead as per Section 4.2. */ - if(line[3] == ' ' || len == 5) { - char tmpline[6]; - curl_off_t code; - const char *p = tmpline; - end = TRUE; - memcpy(tmpline, line, (len == 5 ? 5 : 3)); - tmpline[len == 5 ? 5 : 3] = 0; - if(curlx_str_number(&p, &code, len == 5 ? 99999 : 999)) - return FALSE; - *resp = (int)code; - - /* Make sure real server never sends internal value */ - if(*resp == 1) - *resp = 0; - } - /* Do we have a multiline (continuation) response? */ - else if(line[3] == '-' && - (smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) { - end = TRUE; - *resp = 1; /* Internal response code */ - } - - return end; -} - -/*********************************************************************** - * - * smtp_get_message() - * - * Gets the authentication message from the response buffer. - */ -static CURLcode smtp_get_message(struct Curl_easy *data, struct bufref *out) -{ - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - char *message; - size_t len; - - if(!smtpc) - return CURLE_FAILED_INIT; - - message = curlx_dyn_ptr(&smtpc->pp.recvbuf); - len = smtpc->pp.nfinal; - if(len > 4) { - /* Find the start of the message */ - len -= 4; - for(message += 4; ISBLANK(*message); message++, len--) - ; - - /* Find the end of the message */ - while(len--) - if(!ISNEWLINE(message[len]) && !ISBLANK(message[len])) - break; - - /* Terminate the message */ - message[++len] = '\0'; - Curl_bufref_set(out, message, len, NULL); - } - else - /* junk input => zero length output */ - Curl_bufref_set(out, "", 0, NULL); - - return CURLE_OK; -} - -/*********************************************************************** - * - * smtp_state() - * - * This is the ONLY way to change SMTP state! - */ -static void smtp_state(struct Curl_easy *data, - struct smtp_conn *smtpc, - smtpstate newstate) -{ -#ifdef CURLVERBOSE - /* for debug purposes */ - static const char * const names[] = { - "STOP", - "SERVERGREET", - "EHLO", - "HELO", - "STARTTLS", - "UPGRADETLS", - "AUTH", - "COMMAND", - "MAIL", - "RCPT", - "DATA", - "POSTDATA", - "QUIT", - /* LAST */ - }; - - if(smtpc->state != newstate) - CURL_TRC_SMTP(data, "state change from %s to %s", - names[smtpc->state], names[newstate]); -#else - (void)data; -#endif - - smtpc->state = newstate; -} - -/*********************************************************************** - * - * smtp_perform_ehlo() - * - * Sends the EHLO command to not only initialise communication with the ESMTP - * server but to also obtain a list of server side supported capabilities. - */ -static CURLcode smtp_perform_ehlo(struct Curl_easy *data, - struct smtp_conn *smtpc) -{ - CURLcode result = CURLE_OK; - - smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */ - smtpc->sasl.authused = SASL_AUTH_NONE; /* Clear the authentication mechanism - used for esmtp connections */ - smtpc->tls_supported = FALSE; /* Clear the TLS capability */ - smtpc->auth_supported = FALSE; /* Clear the AUTH capability */ - - /* Send the EHLO command */ - result = Curl_pp_sendf(data, &smtpc->pp, "EHLO %s", smtpc->domain); - - if(!result) - smtp_state(data, smtpc, SMTP_EHLO); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_helo() - * - * Sends the HELO command to initialise communication with the SMTP server. - */ -static CURLcode smtp_perform_helo(struct Curl_easy *data, - struct smtp_conn *smtpc) -{ - CURLcode result = CURLE_OK; - - smtpc->sasl.authused = SASL_AUTH_NONE; /* No authentication mechanism used - in smtp connections */ - - /* Send the HELO command */ - result = Curl_pp_sendf(data, &smtpc->pp, "HELO %s", smtpc->domain); - - if(!result) - smtp_state(data, smtpc, SMTP_HELO); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_starttls() - * - * Sends the STLS command to start the upgrade to TLS. - */ -static CURLcode smtp_perform_starttls(struct Curl_easy *data, - struct smtp_conn *smtpc) -{ - /* Send the STARTTLS command */ - CURLcode result = Curl_pp_sendf(data, &smtpc->pp, "%s", "STARTTLS"); - - if(!result) - smtp_state(data, smtpc, SMTP_STARTTLS); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_upgrade_tls() - * - * Performs the upgrade to TLS. - */ -static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data, - struct smtp_conn *smtpc) -{ -#ifdef USE_SSL - /* Start the SSL connection */ - struct connectdata *conn = data->conn; - CURLcode result; - bool ssldone = FALSE; - - DEBUGASSERT(smtpc->state == SMTP_UPGRADETLS); - if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); - if(result) - goto out; - /* Change the connection handler and SMTP state */ - conn->scheme = &Curl_scheme_smtps; - } - - DEBUGASSERT(!smtpc->ssldone); - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - DEBUGF(infof(data, "smtp_perform_upgrade_tls, connect -> %d, %d", - result, ssldone)); - if(!result && ssldone) { - smtpc->ssldone = ssldone; - /* perform EHLO now, changes smtp->state out of SMTP_UPGRADETLS */ - result = smtp_perform_ehlo(data, smtpc); - } -out: - return result; -#else - (void)data; - (void)smtpc; - return CURLE_NOT_BUILT_IN; -#endif -} - -/*********************************************************************** - * - * smtp_perform_auth() - * - * Sends an AUTH command allowing the client to login with the given SASL - * authentication mechanism. - */ -static CURLcode smtp_perform_auth(struct Curl_easy *data, - const char *mech, - const struct bufref *initresp) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - const char *ir = Curl_bufref_ptr(initresp); - - if(!smtpc) - return CURLE_FAILED_INIT; - - if(ir) { /* AUTH ... */ - /* Send the AUTH command with the initial response */ - result = Curl_pp_sendf(data, &smtpc->pp, "AUTH %s %s", mech, ir); - } - else { - /* Send the AUTH command */ - result = Curl_pp_sendf(data, &smtpc->pp, "AUTH %s", mech); - } - - return result; -} - -/*********************************************************************** - * - * smtp_continue_auth() - * - * Sends SASL continuation data. - */ -static CURLcode smtp_continue_auth(struct Curl_easy *data, - const char *mech, - const struct bufref *resp) -{ - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - - (void)mech; - if(!smtpc) - return CURLE_FAILED_INIT; - return Curl_pp_sendf(data, &smtpc->pp, "%s", Curl_bufref_ptr(resp)); -} - -/*********************************************************************** - * - * smtp_cancel_auth() - * - * Sends SASL cancellation. - */ -static CURLcode smtp_cancel_auth(struct Curl_easy *data, const char *mech) -{ - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - - (void)mech; - if(!smtpc) - return CURLE_FAILED_INIT; - return Curl_pp_sendf(data, &smtpc->pp, "*"); -} - -/*********************************************************************** - * - * smtp_perform_authentication() - * - * Initiates the authentication sequence, with the appropriate SASL - * authentication mechanism. - */ -static CURLcode smtp_perform_authentication(struct Curl_easy *data, - struct smtp_conn *smtpc) -{ - CURLcode result = CURLE_OK; - saslprogress progress; - - /* Check we have enough data to authenticate with, and the - server supports authentication, and end the connect phase if not */ - if(!smtpc->auth_supported || - !Curl_sasl_can_authenticate(&smtpc->sasl, data)) { - smtp_state(data, smtpc, SMTP_STOP); - return result; - } - - /* Calculate the SASL login details */ - result = Curl_sasl_start(&smtpc->sasl, data, FALSE, &progress); - - if(!result) { - if(progress == SASL_INPROGRESS) - smtp_state(data, smtpc, SMTP_AUTH); - else - result = Curl_sasl_is_blocked(&smtpc->sasl, data); - } - - return result; -} - -/*********************************************************************** - * - * smtp_perform_command() - * - * Sends an SMTP based command. - */ -static CURLcode smtp_perform_command(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp) -{ - CURLcode result = CURLE_OK; - - if(smtp->rcpt) { - /* We notify the server we are sending UTF-8 data if a) it supports the - SMTPUTF8 extension and b) The mailbox contains UTF-8 characters, in - either the local address or hostname parts. This is regardless of - whether the hostname is encoded using IDN ACE */ - bool utf8 = FALSE; - - if(!smtp->custom || !smtp->custom[0]) { - char *address = NULL; - struct hostname host = { NULL, NULL, NULL, NULL }; - const char *suffix = ""; - - /* Parse the mailbox to verify into the local address and hostname - parts, converting the hostname to an IDN A-label if necessary */ - result = smtp_parse_address(smtp->rcpt->data, - &address, &host, &suffix); - if(result) - return result; - - /* Establish whether we should report SMTPUTF8 to the server for this - mailbox as per RFC-6531 sect. 3.1 point 6 */ - utf8 = smtpc->utf8_supported && - (host.encalloc || - !Curl_is_ASCII_name(address) || - !Curl_is_ASCII_name(host.name)); - - /* Send the VRFY command (Note: The hostname part may be absent when the - host is a local system) */ - result = Curl_pp_sendf(data, &smtpc->pp, "VRFY %s%s%s%s", - address, - host.name ? "@" : "", - host.name ? host.name : "", - utf8 ? " SMTPUTF8" : ""); - - Curl_free_idnconverted_hostname(&host); - curlx_free(address); - } - else { - /* Establish whether we should report that we support SMTPUTF8 for EXPN - commands to the server as per RFC-6531 sect. 3.1 point 6 */ - utf8 = (smtpc->utf8_supported) && (!strcmp(smtp->custom, "EXPN")); - - /* Send the custom recipient based command such as the EXPN command */ - result = Curl_pp_sendf(data, &smtpc->pp, - "%s %s%s", smtp->custom, - smtp->rcpt->data, - utf8 ? " SMTPUTF8" : ""); - } - } - else - /* Send the non-recipient based command such as HELP */ - result = Curl_pp_sendf(data, &smtpc->pp, "%s", - smtp->custom && smtp->custom[0] != '\0' ? - smtp->custom : "HELP"); - - if(!result) - smtp_state(data, smtpc, SMTP_COMMAND); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_mail() - * - * Sends an MAIL command to initiate the upload of a message. - */ -static CURLcode smtp_perform_mail(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp) -{ - char *from = NULL; - char *auth = NULL; - char *size = NULL; - CURLcode result = CURLE_OK; - - /* We notify the server we are sending UTF-8 data if a) it supports the - SMTPUTF8 extension and b) The mailbox contains UTF-8 characters, in - either the local address or hostname parts. This is regardless of - whether the hostname is encoded using IDN ACE */ - bool utf8 = FALSE; - - /* Calculate the FROM parameter */ - if(data->set.str[STRING_MAIL_FROM]) { - char *address = NULL; - struct hostname host = { NULL, NULL, NULL, NULL }; - const char *suffix = ""; - - /* Parse the FROM mailbox into the local address and hostname parts, - converting the hostname to an IDN A-label if necessary */ - result = smtp_parse_address(data->set.str[STRING_MAIL_FROM], - &address, &host, &suffix); - if(result) - goto out; - - /* Establish whether we should report SMTPUTF8 to the server for this - mailbox as per RFC-6531 sect. 3.1 point 4 and sect. 3.4 */ - utf8 = smtpc->utf8_supported && - (host.encalloc || - !Curl_is_ASCII_name(address) || - !Curl_is_ASCII_name(host.name)); - - if(host.name) { - from = curl_maprintf("<%s@%s>%s", address, host.name, suffix); - - Curl_free_idnconverted_hostname(&host); - } - else - /* An invalid mailbox was provided but we let the server worry - about that and reply with a 501 error */ - from = curl_maprintf("<%s>%s", address, suffix); - - curlx_free(address); - } - else - /* Null reverse-path, RFC-5321, sect. 3.6.3 */ - from = curlx_strdup("<>"); - - if(!from) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Calculate the optional AUTH parameter */ - if(data->set.str[STRING_MAIL_AUTH] && smtpc->sasl.authused) { - if(data->set.str[STRING_MAIL_AUTH][0] != '\0') { - char *address = NULL; - struct hostname host = { NULL, NULL, NULL, NULL }; - const char *suffix = ""; - - /* Parse the AUTH mailbox into the local address and hostname parts, - converting the hostname to an IDN A-label if necessary */ - result = smtp_parse_address(data->set.str[STRING_MAIL_AUTH], - &address, &host, &suffix); - if(result) - goto out; - - /* Establish whether we should report SMTPUTF8 to the server for this - mailbox as per RFC-6531 sect. 3.1 point 4 and sect. 3.4 */ - if(!utf8 && smtpc->utf8_supported && - (host.encalloc || - !Curl_is_ASCII_name(address) || - !Curl_is_ASCII_name(host.name))) - utf8 = TRUE; - - if(host.name) { - auth = curl_maprintf("<%s@%s>%s", address, host.name, suffix); - - Curl_free_idnconverted_hostname(&host); - } - else - /* An invalid mailbox was provided but we let the server worry - about it */ - auth = curl_maprintf("<%s>%s", address, suffix); - curlx_free(address); - } - else - /* Empty AUTH, RFC-2554, sect. 5 */ - auth = curlx_strdup("<>"); - - if(!auth) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - -#ifndef CURL_DISABLE_MIME - /* Prepare the mime data if some. */ - if(IS_MIME_POST(data)) { - curl_mimepart *postp = data->set.mimepostp; - - /* Use the whole structure as data. */ - postp->flags &= ~(unsigned int)MIME_BODY_ONLY; - - /* Add external headers and mime version. */ - curl_mime_headers(postp, data->set.headers, 0); - result = Curl_mime_prepare_headers(data, postp, NULL, - NULL, MIMESTRATEGY_MAIL); - - if(!result) - if(!Curl_checkheaders(data, STRCONST("Mime-Version"))) - result = Curl_mime_add_header(&postp->curlheaders, - "Mime-Version: 1.0"); - - if(!result) - result = Curl_creader_set_mime(data, postp); - if(result) - goto out; - data->state.infilesize = Curl_creader_total_length(data); - } - else -#endif - { - result = Curl_creader_set_fread(data, data->state.infilesize); - if(result) - goto out; - } - - /* Calculate the optional SIZE parameter */ - if(smtpc->size_supported && data->state.infilesize > 0) { - size = curl_maprintf("%" FMT_OFF_T, data->state.infilesize); - - if(!size) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - /* If the mailboxes in the FROM and AUTH parameters do not include a UTF-8 - based address then quickly scan through the recipient list and check if - any there do, as we need to correctly identify our support for SMTPUTF8 - in the envelope, as per RFC-6531 sect. 3.4 */ - if(smtpc->utf8_supported && !utf8) { - struct curl_slist *rcpt = smtp->rcpt; - - while(rcpt && !utf8) { - /* Does the hostname contain non-ASCII characters? */ - if(!Curl_is_ASCII_name(rcpt->data)) - utf8 = TRUE; - - rcpt = rcpt->next; - } - } - - /* Add the client reader doing STMP EOB escaping */ - result = cr_eob_add(data); - if(result) - goto out; - - /* Send the MAIL command */ - result = Curl_pp_sendf(data, &smtpc->pp, - "MAIL FROM:%s%s%s%s%s%s", - from, /* Mandatory */ - auth ? " AUTH=" : "", /* Optional on AUTH support */ - auth ? auth : "", - size ? " SIZE=" : "", /* Optional on SIZE support */ - size ? size : "", - utf8 ? " SMTPUTF8" /* Internationalised mailbox */ - : ""); /* included in our envelope */ - -out: - curlx_free(from); - curlx_free(auth); - curlx_free(size); - - if(!result) - smtp_state(data, smtpc, SMTP_MAIL); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_rcpt_to() - * - * Sends a RCPT TO command for a given recipient as part of the message upload - * process. - */ -static CURLcode smtp_perform_rcpt_to(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp) -{ - CURLcode result = CURLE_OK; - char *address = NULL; - struct hostname host = { NULL, NULL, NULL, NULL }; - const char *suffix = ""; - - /* Parse the recipient mailbox into the local address and hostname parts, - converting the hostname to an IDN A-label if necessary */ - result = smtp_parse_address(smtp->rcpt->data, - &address, &host, &suffix); - if(result) - return result; - - /* Send the RCPT TO command */ - if(host.name) - result = Curl_pp_sendf(data, &smtpc->pp, "RCPT TO:<%s@%s>%s", - address, host.name, suffix); - else - /* An invalid mailbox was provided but we let the server worry about - that and reply with a 501 error */ - result = Curl_pp_sendf(data, &smtpc->pp, "RCPT TO:<%s>%s", - address, suffix); - - Curl_free_idnconverted_hostname(&host); - curlx_free(address); - - if(!result) - smtp_state(data, smtpc, SMTP_RCPT); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_quit() - * - * Performs the quit action prior to sclose() being called. - */ -static CURLcode smtp_perform_quit(struct Curl_easy *data, - struct smtp_conn *smtpc) -{ - /* Send the QUIT command */ - CURLcode result = Curl_pp_sendf(data, &smtpc->pp, "%s", "QUIT"); - - if(!result) - smtp_state(data, smtpc, SMTP_QUIT); - - return result; -} - -/* For the initial server greeting */ -static CURLcode smtp_state_servergreet_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(smtpcode / 100 != 2) { - failf(data, "Got unexpected smtp-server response: %d", smtpcode); - result = CURLE_WEIRD_SERVER_REPLY; - } - else - result = smtp_perform_ehlo(data, smtpc); - - return result; -} - -/* For STARTTLS responses */ -static CURLcode smtp_state_starttls_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - /* Pipelining in response is forbidden. */ - if(smtpc->pp.overflow) - return CURLE_WEIRD_SERVER_REPLY; - - if(smtpcode != 220) { - if(data->set.use_ssl != CURLUSESSL_TRY) { - failf(data, "STARTTLS denied, code %d", smtpcode); - result = CURLE_USE_SSL_FAILED; - } - else - result = smtp_perform_authentication(data, smtpc); - } - else - smtp_state(data, smtpc, SMTP_UPGRADETLS); - - return result; -} - -/* For EHLO responses */ -static CURLcode smtp_state_ehlo_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - const char *line = curlx_dyn_ptr(&smtpc->pp.recvbuf); - size_t len = smtpc->pp.nfinal; - - (void)instate; - - if(smtpcode / 100 != 2 && smtpcode != 1) { - if(data->set.use_ssl <= CURLUSESSL_TRY || - Curl_conn_is_ssl(data->conn, FIRSTSOCKET)) - result = smtp_perform_helo(data, smtpc); - else { - failf(data, "Remote access denied: %d", smtpcode); - result = CURLE_REMOTE_ACCESS_DENIED; - } - } - else if(len >= 4) { - line += 4; - len -= 4; - - /* Does the server support the STARTTLS capability? */ - if(len >= 8 && curl_strnequal(line, "STARTTLS", 8)) - smtpc->tls_supported = TRUE; - - /* Does the server support the SIZE capability? */ - else if(len >= 4 && curl_strnequal(line, "SIZE", 4)) - smtpc->size_supported = TRUE; - - /* Does the server support the UTF-8 capability? */ - else if(len >= 8 && curl_strnequal(line, "SMTPUTF8", 8)) - smtpc->utf8_supported = TRUE; - - /* Does the server support authentication? */ - else if(len >= 5 && curl_strnequal(line, "AUTH ", 5)) { - smtpc->auth_supported = TRUE; - - /* Advance past the AUTH keyword */ - line += 5; - len -= 5; - - /* Loop through the data line */ - for(;;) { - size_t llen; - size_t wordlen; - unsigned short mechbit; - - while(len && (ISBLANK(*line) || ISNEWLINE(*line))) { - line++; - len--; - } - - if(!len) - break; - - /* Extract the word */ - for(wordlen = 0; wordlen < len && !ISBLANK(line[wordlen]) && - !ISNEWLINE(line[wordlen]);) - wordlen++; - - /* Test the word for a matching authentication mechanism */ - mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); - if(mechbit && llen == wordlen) - smtpc->sasl.authmechs |= mechbit; - - line += wordlen; - len -= wordlen; - } - } - - if(smtpcode != 1) { - if(data->set.use_ssl && !Curl_conn_is_ssl(data->conn, FIRSTSOCKET)) { - /* We do not have an SSL/TLS connection yet, but SSL is requested */ - if(smtpc->tls_supported) - /* Switch to TLS connection now */ - result = smtp_perform_starttls(data, smtpc); - else if(data->set.use_ssl == CURLUSESSL_TRY) - /* Fallback and carry on with authentication */ - result = smtp_perform_authentication(data, smtpc); - else { - failf(data, "STARTTLS not supported."); - result = CURLE_USE_SSL_FAILED; - } - } - else - result = smtp_perform_authentication(data, smtpc); - } - } - else { - failf(data, "Unexpectedly short EHLO response"); - result = CURLE_WEIRD_SERVER_REPLY; - } - - return result; -} - -/* For HELO responses */ -static CURLcode smtp_state_helo_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(smtpcode / 100 != 2) { - failf(data, "Remote access denied: %d", smtpcode); - result = CURLE_REMOTE_ACCESS_DENIED; - } - else - /* End of connect phase */ - smtp_state(data, smtpc, SMTP_STOP); - - return result; -} - -/* For SASL authentication responses */ -static CURLcode smtp_state_auth_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - saslprogress progress; - - (void)instate; - - result = Curl_sasl_continue(&smtpc->sasl, data, smtpcode, &progress); - if(!result) - switch(progress) { - case SASL_DONE: - smtp_state(data, smtpc, SMTP_STOP); /* Authenticated */ - break; - case SASL_IDLE: /* No mechanism left after cancellation */ - failf(data, "Authentication cancelled"); - result = CURLE_LOGIN_DENIED; - break; - default: - break; - } - - return result; -} - -/* For command responses */ -static CURLcode smtp_state_command_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - const char *line = curlx_dyn_ptr(&smtpc->pp.recvbuf); - size_t len = smtpc->pp.nfinal; - - (void)instate; - - if((smtp->rcpt && smtpcode / 100 != 2 && smtpcode != 553 && smtpcode != 1) || - (!smtp->rcpt && smtpcode / 100 != 2 && smtpcode != 1)) { - failf(data, "Command failed: %d", smtpcode); - result = CURLE_WEIRD_SERVER_REPLY; - } - else { - if(!data->req.no_body) - result = Curl_client_write(data, CLIENTWRITE_BODY, line, len); - - if(!result && (smtpcode != 1)) { - if(smtp->rcpt) { - smtp->rcpt = smtp->rcpt->next; - - if(smtp->rcpt) { - /* Send the next command */ - result = smtp_perform_command(data, smtpc, smtp); - } - else - /* End of DO phase */ - smtp_state(data, smtpc, SMTP_STOP); - } - else - /* End of DO phase */ - smtp_state(data, smtpc, SMTP_STOP); - } - } - - return result; -} - -/* For MAIL responses */ -static CURLcode smtp_state_mail_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(smtpcode / 100 != 2) { - failf(data, "MAIL failed: %d", smtpcode); - result = CURLE_SEND_ERROR; - } - else - /* Start the RCPT TO command */ - result = smtp_perform_rcpt_to(data, smtpc, smtp); - - return result; -} - -/* For RCPT responses */ -static CURLcode smtp_state_rcpt_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - bool is_smtp_err = FALSE; - bool is_smtp_blocking_err = FALSE; - - (void)instate; - - is_smtp_err = (smtpcode / 100 != 2); - - /* If there is multiple RCPT TO to be issued, it is possible to ignore errors - and proceed with only the valid addresses. */ - is_smtp_blocking_err = (is_smtp_err && !data->set.mail_rcpt_allowfails); - - if(is_smtp_err) { - /* Remembering the last failure which we can report if all "RCPT TO" have - failed and we cannot proceed. */ - smtp->rcpt_last_error = smtpcode; - - if(is_smtp_blocking_err) { - failf(data, "RCPT failed: %d", smtpcode); - result = CURLE_SEND_ERROR; - } - } - else { - /* Some RCPT TO commands have succeeded. */ - smtp->rcpt_had_ok = TRUE; - } - - if(!is_smtp_blocking_err) { - smtp->rcpt = smtp->rcpt->next; - - if(smtp->rcpt) - /* Send the next RCPT TO command */ - result = smtp_perform_rcpt_to(data, smtpc, smtp); - else { - /* We were not able to issue a successful RCPT TO command while going - over recipients (potentially multiple). Sending back last error. */ - if(!smtp->rcpt_had_ok) { - failf(data, "RCPT failed: %d (last error)", smtp->rcpt_last_error); - result = CURLE_SEND_ERROR; - } - else { - /* Send the DATA command */ - result = Curl_pp_sendf(data, &smtpc->pp, "%s", "DATA"); - - if(!result) - smtp_state(data, smtpc, SMTP_DATA); - } - } - } - - return result; -} - -/* For DATA response */ -static CURLcode smtp_state_data_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - (void)instate; - - if(smtpcode != 354) { - failf(data, "DATA failed: %d", smtpcode); - result = CURLE_SEND_ERROR; - } - else { - /* Set the progress upload size */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* SMTP upload */ - Curl_xfer_setup_send(data, FIRSTSOCKET); - - /* End of DO phase */ - smtp_state(data, smtpc, SMTP_STOP); - } - - return result; -} - -/* For POSTDATA responses, which are received after the entire DATA - part has been sent to the server */ -static CURLcode smtp_state_postdata_resp(struct Curl_easy *data, - struct smtp_conn *smtpc, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - - (void)instate; - - if(smtpcode != 250) - result = CURLE_WEIRD_SERVER_REPLY; - - /* End of DONE phase */ - smtp_state(data, smtpc, SMTP_STOP); - - return result; -} - -static CURLcode smtp_pp_statemachine(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - int smtpcode; - struct smtp_conn *smtpc = Curl_conn_meta_get(conn, CURL_META_SMTP_CONN); - struct SMTP *smtp = Curl_meta_get(data, CURL_META_SMTP_EASY); - size_t nread = 0; - - if(!smtpc || !smtp) - return CURLE_FAILED_INIT; - - /* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */ -upgrade_tls: - if(smtpc->state == SMTP_UPGRADETLS) { - result = smtp_perform_upgrade_tls(data, smtpc); - if(result || (smtpc->state == SMTP_UPGRADETLS)) - return result; - } - - /* Flush any data that needs to be sent */ - if(smtpc->pp.sendleft) - return Curl_pp_flushsend(data, &smtpc->pp); - - do { - /* Read the response from the server */ - result = Curl_pp_readresp(data, FIRSTSOCKET, &smtpc->pp, - &smtpcode, &nread); - if(result) - return result; - - /* Store the latest response for later retrieval if necessary */ - if(smtpc->state != SMTP_QUIT && smtpcode != 1) - data->info.httpcode = smtpcode; - - if(!smtpcode) - break; - - /* We have now received a full SMTP server response */ - switch(smtpc->state) { - case SMTP_SERVERGREET: - result = smtp_state_servergreet_resp(data, smtpc, - smtpcode, smtpc->state); - break; - - case SMTP_EHLO: - result = smtp_state_ehlo_resp(data, smtpc, smtpcode, smtpc->state); - break; - - case SMTP_HELO: - result = smtp_state_helo_resp(data, smtpc, smtpcode, smtpc->state); - break; - - case SMTP_STARTTLS: - result = smtp_state_starttls_resp(data, smtpc, smtpcode, smtpc->state); - /* During UPGRADETLS, leave the read loop as we need to connect - * (e.g. TLS handshake) before we continue sending/receiving. */ - if(!result && (smtpc->state == SMTP_UPGRADETLS)) - goto upgrade_tls; - break; - - case SMTP_AUTH: - result = smtp_state_auth_resp(data, smtpc, smtpcode, smtpc->state); - break; - - case SMTP_COMMAND: - result = smtp_state_command_resp(data, smtpc, smtp, - smtpcode, smtpc->state); - break; - - case SMTP_MAIL: - result = smtp_state_mail_resp(data, smtpc, smtp, smtpcode, smtpc->state); - break; - - case SMTP_RCPT: - result = smtp_state_rcpt_resp(data, smtpc, smtp, smtpcode, smtpc->state); - break; - - case SMTP_DATA: - result = smtp_state_data_resp(data, smtpc, smtpcode, smtpc->state); - break; - - case SMTP_POSTDATA: - result = smtp_state_postdata_resp(data, smtpc, smtpcode, smtpc->state); - break; - - case SMTP_QUIT: - default: - /* internal error */ - smtp_state(data, smtpc, SMTP_STOP); - break; - } - } while(!result && smtpc->state != SMTP_STOP && - Curl_pp_moredata(&smtpc->pp)); - - return result; -} - -/* Called repeatedly until done from multi.c */ -static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - - *done = FALSE; - if(!smtpc) - return CURLE_FAILED_INIT; - - result = Curl_pp_statemach(data, &smtpc->pp, FALSE, FALSE); - *done = (smtpc->state == SMTP_STOP); - return result; -} - -static CURLcode smtp_block_statemach(struct Curl_easy *data, - struct smtp_conn *smtpc, - bool disconnecting) -{ - CURLcode result = CURLE_OK; - - while(smtpc->state != SMTP_STOP && !result) - result = Curl_pp_statemach(data, &smtpc->pp, TRUE, disconnecting); - - return result; -} - -/* For the SMTP "protocol connect" and "doing" phases only */ -static CURLcode smtp_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - return smtpc ? Curl_pp_pollset(data, &smtpc->pp, ps) : CURLE_OK; -} - -/* SASL parameters for the smtp protocol */ -static const struct SASLproto saslsmtp = { - "smtp", /* The service name */ - smtp_perform_auth, /* Send authentication command */ - smtp_continue_auth, /* Send authentication continuation */ - smtp_cancel_auth, /* Cancel authentication */ - smtp_get_message, /* Get SASL response message */ - 512 - 8, /* Max line len - strlen("AUTH ") - 1 space - crlf */ - 334, /* Code received when continuation is expected */ - 235, /* Code to receive upon authentication success */ - SASL_AUTH_DEFAULT, /* Default mechanisms */ - SASL_FLAG_BASE64 /* Configuration flags */ -}; - -/*********************************************************************** - * - * smtp_connect() - * - * This function should do everything that is to be considered a part of - * the connection phase. - * - * The variable pointed to by 'done' will be TRUE if the protocol-layer - * connect phase is done when this function returns, or FALSE if not. - */ -static CURLcode smtp_connect(struct Curl_easy *data, bool *done) -{ - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - CURLcode result = CURLE_OK; - - *done = FALSE; /* default to not done yet */ - if(!smtpc) - return CURLE_FAILED_INIT; - - PINGPONG_SETUP(&smtpc->pp, smtp_pp_statemachine, smtp_endofresp); - - /* Initialize the SASL storage */ - Curl_sasl_init(&smtpc->sasl, data, &saslsmtp); - - /* Initialise the pingpong layer */ - Curl_pp_init(&smtpc->pp, Curl_pgrs_now(data)); - - /* Parse the URL options */ - result = smtp_parse_url_options(data->conn, smtpc); - if(result) - return result; - - /* Parse the URL path */ - result = smtp_parse_url_path(data, smtpc); - if(result) - return result; - - /* Start off waiting for the server greeting response */ - smtp_state(data, smtpc, SMTP_SERVERGREET); - - result = smtp_multi_statemach(data, done); - - return result; -} - -/*********************************************************************** - * - * smtp_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode smtp_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct SMTP *smtp = Curl_meta_get(data, CURL_META_SMTP_EASY); - - (void)premature; - - if(!smtpc) - return CURLE_FAILED_INIT; - if(!smtp) - return CURLE_OK; - - /* Cleanup our per-request based variables */ - curlx_safefree(smtp->custom); - - if(status) { - connclose(conn, "SMTP done with bad status"); /* marked for closure */ - result = status; /* use the already set error code */ - } - else if(!data->set.connect_only && data->set.mail_rcpt && - (data->state.upload || IS_MIME_POST(data))) { - - smtp_state(data, smtpc, SMTP_POSTDATA); - - /* Run the state-machine */ - result = smtp_block_statemach(data, smtpc, FALSE); - } - - /* Clear the transfer mode for the next request */ - smtp->transfer = PPTRANSFER_BODY; - CURL_TRC_SMTP(data, "smtp_done(status=%d, premature=%d) -> %d", - status, premature, result); - return result; -} - -/*********************************************************************** - * - * smtp_perform() - * - * This is the actual DO function for SMTP. Transfer a mail, send a command - * or get some data according to the options previously setup. - */ -static CURLcode smtp_perform(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp, - bool *connected, - bool *dophase_done) -{ - /* This is SMTP and no proxy */ - CURLcode result = CURLE_OK; - - CURL_TRC_SMTP(data, "smtp_perform(), start"); - - if(data->req.no_body) { - /* Requested no body means no transfer */ - smtp->transfer = PPTRANSFER_INFO; - } - - *dophase_done = FALSE; /* not done yet */ - - /* Store the first recipient (or NULL if not specified) */ - smtp->rcpt = data->set.mail_rcpt; - - /* Track of whether we have successfully sent at least one RCPT TO command */ - smtp->rcpt_had_ok = FALSE; - - /* Track of the last error we have received by sending RCPT TO command */ - smtp->rcpt_last_error = 0; - - /* Initial data character is the first character in line: it is implicitly - preceded by a virtual CRLF. */ - smtp->trailing_crlf = TRUE; - smtp->eob = 2; - - /* Start the first command in the DO phase */ - if((data->state.upload || IS_MIME_POST(data)) && data->set.mail_rcpt) - /* MAIL transfer */ - result = smtp_perform_mail(data, smtpc, smtp); - else - /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */ - result = smtp_perform_command(data, smtpc, smtp); - - if(result) - goto out; - - /* Run the state-machine */ - result = smtp_multi_statemach(data, dophase_done); - - *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); - -out: - CURL_TRC_SMTP(data, "smtp_perform() -> %d, connected=%d, done=%d", - result, *connected, *dophase_done); - return result; -} - -/* Call this when the DO phase has completed */ -static CURLcode smtp_dophase_done(struct Curl_easy *data, - struct SMTP *smtp, - bool connected) -{ - (void)connected; - - if(smtp->transfer != PPTRANSFER_BODY) - /* no data to transfer */ - Curl_xfer_setup_nop(data); - - return CURLE_OK; -} - -/*********************************************************************** - * - * smtp_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - */ -static CURLcode smtp_regular_transfer(struct Curl_easy *data, - struct smtp_conn *smtpc, - struct SMTP *smtp, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - bool connected = FALSE; - - /* Make sure size is unknown at this point */ - data->req.size = -1; - - /* Set the progress data */ - Curl_pgrsReset(data); - - /* Carry out the perform */ - result = smtp_perform(data, smtpc, smtp, &connected, dophase_done); - - /* Perform post DO phase operations if necessary */ - if(!result && *dophase_done) - result = smtp_dophase_done(data, smtp, connected); - - CURL_TRC_SMTP(data, "smtp_regular_transfer() -> %d, done=%d", - result, *dophase_done); - return result; -} - -/*********************************************************************** - * - * smtp_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (smtp_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode smtp_do(struct Curl_easy *data, bool *done) -{ - struct smtp_conn *smtpc = - Curl_conn_meta_get(data->conn, CURL_META_SMTP_CONN); - struct SMTP *smtp = Curl_meta_get(data, CURL_META_SMTP_EASY); - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - *done = FALSE; /* default to false */ - if(!smtpc || !smtp) - return CURLE_FAILED_INIT; - - /* Parse the custom request */ - result = smtp_parse_custom_request(data, smtp); - if(result) - return result; - - result = smtp_regular_transfer(data, smtpc, smtp, done); - CURL_TRC_SMTP(data, "smtp_do() -> %d, done=%d", result, *done); - return result; -} - -/*********************************************************************** - * - * smtp_disconnect() - * - * Disconnect from an SMTP server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode smtp_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection) -{ - struct smtp_conn *smtpc = Curl_conn_meta_get(conn, CURL_META_SMTP_CONN); - - if(!smtpc) - return CURLE_FAILED_INIT; - - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. */ - - if(!dead_connection && conn->bits.protoconnstart && - !Curl_pp_needs_flush(data, &smtpc->pp)) { - if(!smtp_perform_quit(data, smtpc)) - (void)smtp_block_statemach(data, smtpc, TRUE); /* ignore on QUIT */ - } - - CURL_TRC_SMTP(data, "smtp_disconnect(), finished"); - return CURLE_OK; -} - -/* Called from multi.c while DOing */ -static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done) -{ - struct SMTP *smtp = Curl_meta_get(data, CURL_META_SMTP_EASY); - CURLcode result; - - if(!smtp) - return CURLE_FAILED_INIT; - result = smtp_multi_statemach(data, dophase_done); - if(result) - DEBUGF(infof(data, "DO phase failed")); - else if(*dophase_done) { - result = smtp_dophase_done(data, smtp, FALSE /* not connected */); - - DEBUGF(infof(data, "DO phase is complete")); - } - - CURL_TRC_SMTP(data, "smtp_doing() -> %d, done=%d", result, *dophase_done); - return result; -} - -static void smtp_easy_dtor(void *key, size_t klen, void *entry) -{ - struct SMTP *smtp = entry; - (void)key; - (void)klen; - curlx_free(smtp); -} - -static void smtp_conn_dtor(void *key, size_t klen, void *entry) -{ - struct smtp_conn *smtpc = entry; - (void)key; - (void)klen; - Curl_pp_disconnect(&smtpc->pp); - curlx_safefree(smtpc->domain); - curlx_free(smtpc); -} - -static CURLcode smtp_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct smtp_conn *smtpc; - struct SMTP *smtp; - CURLcode result = CURLE_OK; - - smtpc = curlx_calloc(1, sizeof(*smtpc)); - if(!smtpc || - Curl_conn_meta_set(conn, CURL_META_SMTP_CONN, smtpc, smtp_conn_dtor)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - smtp = curlx_calloc(1, sizeof(*smtp)); - if(!smtp || - Curl_meta_set(data, CURL_META_SMTP_EASY, smtp, smtp_easy_dtor)) - result = CURLE_OUT_OF_MEMORY; - -out: - CURL_TRC_SMTP(data, "smtp_setup_connection() -> %d", result); - return result; -} - -/* - * SMTP protocol handler. - */ -const struct Curl_protocol Curl_protocol_smtp = { - smtp_setup_connection, /* setup_connection */ - smtp_do, /* do_it */ - smtp_done, /* done */ - ZERO_NULL, /* do_more */ - smtp_connect, /* connect_it */ - smtp_multi_statemach, /* connecting */ - smtp_doing, /* doing */ - smtp_pollset, /* proto_pollset */ - smtp_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - smtp_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* CURL_DISABLE_SMTP */ diff --git a/vendor/curl/lib/smtp.h b/vendor/curl/lib/smtp.h deleted file mode 100644 index 75b81979c..000000000 --- a/vendor/curl/lib/smtp.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_SMTP_H -#define HEADER_CURL_SMTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_SMTP -extern const struct Curl_protocol Curl_protocol_smtp; -#endif - -#endif /* HEADER_CURL_SMTP_H */ diff --git a/vendor/curl/lib/sockaddr.h b/vendor/curl/lib/sockaddr.h deleted file mode 100644 index 2b0333508..000000000 --- a/vendor/curl/lib/sockaddr.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef HEADER_CURL_SOCKADDR_H -#define HEADER_CURL_SOCKADDR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_sockaddr_storage { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -#ifdef USE_IPV6 - struct sockaddr_in6 sa_in6; -#endif -#ifdef HAVE_STRUCT_SOCKADDR_STORAGE - struct sockaddr_storage sa_stor; -#else - char cbuf[256]; /* this should be big enough to fit a lot */ -#endif - } buffer; -}; - -#endif /* HEADER_CURL_SOCKADDR_H */ diff --git a/vendor/curl/lib/socketpair.c b/vendor/curl/lib/socketpair.c deleted file mode 100644 index 76b959dd4..000000000 --- a/vendor/curl/lib/socketpair.c +++ /dev/null @@ -1,376 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "socketpair.h" -#include "urldata.h" -#include "rand.h" -#include "curlx/nonblock.h" - -#ifndef CURL_DISABLE_SOCKETPAIR - -/* choose implementation */ -#ifdef USE_EVENTFD - -#include - -static int wakeup_eventfd(curl_socket_t socks[2], bool nonblocking) -{ - int efd = eventfd(0, nonblocking ? EFD_CLOEXEC | EFD_NONBLOCK : EFD_CLOEXEC); - if(efd == -1) { - socks[0] = socks[1] = CURL_SOCKET_BAD; - return -1; - } - socks[0] = socks[1] = efd; - return 0; -} - -#elif defined(HAVE_PIPE) - -#ifdef HAVE_FCNTL -#include -#endif - -static int wakeup_pipe(curl_socket_t socks[2], bool nonblocking) -{ -#ifdef HAVE_PIPE2 - int flags = nonblocking ? O_NONBLOCK | O_CLOEXEC : O_CLOEXEC; - if(pipe2(socks, flags)) - return -1; -#else - if(pipe(socks)) - return -1; -#ifdef HAVE_FCNTL - if(fcntl(socks[0], F_SETFD, FD_CLOEXEC) || - fcntl(socks[1], F_SETFD, FD_CLOEXEC)) { - sclose(socks[0]); - sclose(socks[1]); - socks[0] = socks[1] = CURL_SOCKET_BAD; - return -1; - } -#endif - if(nonblocking) { - if(curlx_nonblock(socks[0], TRUE) < 0 || - curlx_nonblock(socks[1], TRUE) < 0) { - sclose(socks[0]); - sclose(socks[1]); - socks[0] = socks[1] = CURL_SOCKET_BAD; - return -1; - } - } -#endif - - return 0; -} - -#elif defined(HAVE_SOCKETPAIR) /* !USE_EVENTFD && !HAVE_PIPE */ - -#ifndef USE_UNIX_SOCKETS -#error "unsupported Unix domain and socketpair build combo" -#endif - -static int wakeup_socketpair(curl_socket_t socks[2], bool nonblocking) -{ - int type = SOCK_STREAM; -#ifdef SOCK_CLOEXEC - type |= SOCK_CLOEXEC; -#endif -#ifdef SOCK_NONBLOCK - if(nonblocking) - type |= SOCK_NONBLOCK; -#endif - - if(CURL_SOCKETPAIR(AF_UNIX, type, 0, socks)) - return -1; -#ifndef SOCK_NONBLOCK - if(nonblocking) { - if(curlx_nonblock(socks[0], TRUE) < 0 || - curlx_nonblock(socks[1], TRUE) < 0) { - sclose(socks[0]); - sclose(socks[1]); - socks[0] = socks[1] = CURL_SOCKET_BAD; - return -1; - } - } -#endif -#ifdef USE_SO_NOSIGPIPE - if(Curl_sock_nosigpipe(socks[1]) < 0) { - sclose(socks[0]); - sclose(socks[1]); - socks[0] = socks[1] = CURL_SOCKET_BAD; - return -1; - } -#endif /* USE_SO_NOSIGPIPE */ - - return 0; -} - -#else /* !USE_EVENTFD && !HAVE_PIPE && !HAVE_SOCKETPAIR */ - -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include /* for IPPROTO_TCP */ -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001 -#endif - -#include "select.h" /* for Curl_poll */ - -static int wakeup_inet(curl_socket_t socks[2], bool nonblocking) -{ - union { - struct sockaddr_in inaddr; - struct sockaddr addr; - } a; - curl_socket_t listener; - curl_socklen_t addrlen = sizeof(a.inaddr); - int reuse = 1; - struct pollfd pfd[1]; - - listener = CURL_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(listener == CURL_SOCKET_BAD) - return -1; - - memset(&a, 0, sizeof(a)); - a.inaddr.sin_family = AF_INET; - a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - a.inaddr.sin_port = 0; - - socks[0] = socks[1] = CURL_SOCKET_BAD; - -#if defined(_WIN32) || defined(__CYGWIN__) - /* do not set SO_REUSEADDR on Windows */ - (void)reuse; -#ifdef SO_EXCLUSIVEADDRUSE - { - int exclusive = 1; - if(setsockopt(listener, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, - (char *)&exclusive, (curl_socklen_t)sizeof(exclusive)) == -1) - goto error; - } -#endif -#else - if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, - (char *)&reuse, (curl_socklen_t)sizeof(reuse)) == -1) - goto error; -#endif - if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1) - goto error; - if(getsockname(listener, &a.addr, &addrlen) == -1 || - addrlen < (int)sizeof(a.inaddr)) - goto error; - if(listen(listener, 1) == -1) - goto error; - socks[0] = CURL_SOCKET(AF_INET, SOCK_STREAM, 0); - if(socks[0] == CURL_SOCKET_BAD) - goto error; - if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1) - goto error; - - /* use non-blocking accept to make sure we do not block forever */ - if(curlx_nonblock(listener, TRUE) < 0) - goto error; - pfd[0].fd = listener; - pfd[0].events = POLLIN; - pfd[0].revents = 0; - (void)Curl_poll(pfd, 1, 1000); /* one second */ - socks[1] = CURL_ACCEPT(listener, NULL, NULL); - if(socks[1] == CURL_SOCKET_BAD) - goto error; - else { - struct curltime start = curlx_now(); - char rnd[9]; - char check[sizeof(rnd)]; - char *p = &check[0]; - size_t s = sizeof(check); - - if(Curl_rand(NULL, (unsigned char *)rnd, sizeof(rnd))) - goto error; - - /* write data to the socket */ - swrite(socks[0], rnd, sizeof(rnd)); - /* verify that we read the correct data */ - do { - ssize_t nread; - - pfd[0].fd = socks[1]; - pfd[0].events = POLLIN; - pfd[0].revents = 0; - (void)Curl_poll(pfd, 1, 1000); /* one second */ - - nread = sread(socks[1], p, s); - if(nread == -1) { - int sockerr = SOCKERRNO; - /* Do not block forever */ - if(curlx_timediff_ms(curlx_now(), start) > (60 * 1000)) - goto error; - if( -#ifdef USE_WINSOCK - /* This is how Windows does it */ - (SOCKEWOULDBLOCK == sockerr) -#else - /* errno may be EWOULDBLOCK or on some systems EAGAIN when it - returned due to its inability to send off data without - blocking. We therefore treat both error codes the same here */ - (SOCKEWOULDBLOCK == sockerr) || (EAGAIN == sockerr) || - (SOCKEINTR == sockerr) || (SOCKEINPROGRESS == sockerr) -#endif - ) { - continue; - } - goto error; - } - s -= nread; - if(s) { - p += nread; - continue; - } - if(memcmp(rnd, check, sizeof(check))) - goto error; - break; - } while(1); - } - - if(nonblocking) - if(curlx_nonblock(socks[0], TRUE) < 0 || - curlx_nonblock(socks[1], TRUE) < 0) - goto error; -#ifdef USE_SO_NOSIGPIPE - if(Curl_sock_nosigpipe(socks[1]) < 0) - goto error; -#endif - sclose(listener); - return 0; - -error: - sclose(listener); - sclose(socks[0]); - sclose(socks[1]); - socks[0] = socks[1] = CURL_SOCKET_BAD; - return -1; -} - -#endif /* choose implementation */ - -int Curl_wakeup_init(curl_socket_t socks[2], bool nonblocking) -{ -#ifdef USE_EVENTFD - return wakeup_eventfd(socks, nonblocking); -#elif defined(HAVE_PIPE) - return wakeup_pipe(socks, nonblocking); -#elif defined(HAVE_SOCKETPAIR) - return wakeup_socketpair(socks, nonblocking); -#else - return wakeup_inet(socks, nonblocking); -#endif -} - -#if defined(USE_EVENTFD) || defined(HAVE_PIPE) - -#define wakeup_write write -#define wakeup_read read -#define wakeup_close close - -#else /* !USE_EVENTFD && !HAVE_PIPE */ - -#define wakeup_write swrite -#define wakeup_read sread -#define wakeup_close sclose - -#endif - -int Curl_wakeup_signal(curl_socket_t socks[2]) -{ - int err = 0; -#ifdef USE_EVENTFD - const uint64_t buf[1] = { 1 }; -#else - const char buf[1] = { 1 }; -#endif - - while(1) { - err = 0; - if(wakeup_write(socks[1], buf, sizeof(buf)) < 0) { - err = SOCKERRNO; -#ifdef USE_WINSOCK - if(err == SOCKEWOULDBLOCK) - err = 0; /* wakeup is already ongoing */ -#else - if(SOCKEINTR == err) - continue; - if((err == SOCKEWOULDBLOCK) || (err == EAGAIN)) - err = 0; /* wakeup is already ongoing */ -#endif - } - break; - } - return err; -} - -CURLcode Curl_wakeup_consume(curl_socket_t socks[2], bool all) -{ - char buf[64]; - ssize_t rc; - CURLcode result = CURLE_OK; - - do { - rc = wakeup_read(socks[0], buf, sizeof(buf)); - if(!rc) - break; - else if(rc < 0) { -#ifdef USE_WINSOCK - if(SOCKERRNO == SOCKEWOULDBLOCK) - break; -#else - if(SOCKEINTR == SOCKERRNO) - continue; - if((SOCKERRNO == SOCKEWOULDBLOCK) || (SOCKERRNO == EAGAIN)) - break; -#endif - result = CURLE_READ_ERROR; - break; - } - } while(all); - return result; -} - -void Curl_wakeup_destroy(curl_socket_t socks[2]) -{ -#ifndef USE_EVENTFD - if(socks[1] != CURL_SOCKET_BAD) - wakeup_close(socks[1]); -#endif - if(socks[0] != CURL_SOCKET_BAD) - wakeup_close(socks[0]); - socks[0] = socks[1] = CURL_SOCKET_BAD; -} - -#endif /* !CURL_DISABLE_SOCKETPAIR */ diff --git a/vendor/curl/lib/socketpair.h b/vendor/curl/lib/socketpair.h deleted file mode 100644 index 0427e72fc..000000000 --- a/vendor/curl/lib/socketpair.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef HEADER_CURL_SOCKETPAIR_H -#define HEADER_CURL_SOCKETPAIR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_SOCKETPAIR - -/* return < 0 for failure to initialise */ -int Curl_wakeup_init(curl_socket_t socks[2], bool nonblocking); -void Curl_wakeup_destroy(curl_socket_t socks[2]); - -/* return 0 on success or errno on failure */ -int Curl_wakeup_signal(curl_socket_t socks[2]); - -CURLcode Curl_wakeup_consume(curl_socket_t socks[2], bool all); - -#else -#define Curl_wakeup_destroy(x) Curl_nop_stmt -#endif - -#endif /* HEADER_CURL_SOCKETPAIR_H */ diff --git a/vendor/curl/lib/socks.c b/vendor/curl/lib/socks.c deleted file mode 100644 index b3da5be0a..000000000 --- a/vendor/curl/lib/socks.c +++ /dev/null @@ -1,1406 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_PROXY - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "urldata.h" -#include "bufq.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "select.h" -#include "cfilters.h" -#include "cf-dns.h" -#include "connect.h" -#include "socks.h" -#include "curlx/inet_pton.h" - -/* for the (SOCKS) connect state machine */ -enum socks_state_t { - SOCKS_ST_INIT, - /* SOCKS Version 4 states */ - SOCKS4_ST_START, - SOCKS4_ST_RESOLVING, - SOCKS4_ST_SEND, - SOCKS4_ST_RECV, - /* SOCKS Version 5 states */ - SOCKS5_ST_START, - SOCKS5_ST_REQ0_SEND, - SOCKS5_ST_RESP0_RECV, /* set up read */ - SOCKS5_ST_GSSAPI_INIT, - SOCKS5_ST_AUTH_INIT, /* setup outgoing auth buffer */ - SOCKS5_ST_AUTH_SEND, /* send auth */ - SOCKS5_ST_AUTH_RECV, /* read auth response */ - SOCKS5_ST_REQ1_INIT, /* init SOCKS "request" */ - SOCKS5_ST_RESOLVING, - SOCKS5_ST_REQ1_SEND, - SOCKS5_ST_RESP1_RECV, - /* Terminal states, all SOCKS versions */ - SOCKS_ST_SUCCESS, - SOCKS_ST_FAILED -}; - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) -static const char * const cf_socks_statename[] = { - "SOCKS_INIT", - "SOCKS4_START", - "SOCKS4_RESOLVING", - "SOCKS4_SEND", - "SOCKS4_RECV", - "SOCKS5_START", - "SOCKS5_REQ0_SEND", - "SOCKS5_RESP0_RECV", - "SOCKS5_GSSAPI_INIT", - "SOCKS5_AUTH_INIT", - "SOCKS5_AUTH_SEND", - "SOCKS5_AUTH_RECV", - "SOCKS5_REQ1_INIT", - "SOCKS5_RESOLVING", - "SOCKS5_REQ1_SEND", - "SOCKS5_RESP1_RECV", - "SOCKS_SUCCESS", - "SOCKS_FAILED" -}; -#endif - -#define SOCKS_CHUNK_SIZE 1024 -#define SOCKS_CHUNKS 1 - - -struct socks_ctx { - enum socks_state_t state; - struct bufq iobuf; - uint16_t remote_port; - const char *user; - const char *passwd; - CURLproxycode presult; - uint32_t resolv_id; - uint8_t ip_version; - uint8_t proxy_type; - unsigned char version; - BIT(resolve_local); - BIT(start_resolving); - BIT(socks4a); - char hostname[1]; -}; - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) -/* - * Helper read-from-socket functions. Does the same as Curl_read() but it - * blocks until all bytes amount of buffersize will be read. No more, no less. - * - * This is STUPID BLOCKING behavior. Only used by the SOCKS GSSAPI functions. - */ -CURLcode Curl_blockread_all(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, /* store read data here */ - size_t blen, /* space in buf */ - size_t *pnread) /* amount bytes read */ -{ - size_t nread = 0; - CURLcode result; - - *pnread = 0; - for(;;) { - timediff_t timeout_ms = Curl_timeleft_ms(data); - curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); - - if(timeout_ms < 0) { - /* we already got the timeout */ - return CURLE_OPERATION_TIMEDOUT; - } - if(!timeout_ms) - timeout_ms = TIMEDIFF_T_MAX; - if(SOCKET_READABLE(sock, timeout_ms) <= 0) - return CURLE_OPERATION_TIMEDOUT; - result = Curl_conn_cf_recv(cf->next, data, buf, blen, &nread); - if(result == CURLE_AGAIN) - continue; - else if(result) - return result; - - if(blen == nread) { - *pnread += nread; - return CURLE_OK; - } - if(!nread) /* EOF */ - return CURLE_RECV_ERROR; - - buf += nread; - blen -= nread; - *pnread += nread; - } -} -#endif - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) -#define sxstate(x, c, d, y) socksstate(x, c, d, y, __LINE__) -#else -#define sxstate(x, c, d, y) socksstate(x, c, d, y) -#endif - -/* always use this function to change state, to make debugging easier */ -static void socksstate(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - enum socks_state_t state -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - , int lineno -#endif -) -{ - enum socks_state_t oldstate = sx->state; - - if(oldstate == state) - /* do not bother when the new state is the same as the old state */ - return; - - sx->state = state; - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - CURL_TRC_CF(data, cf, "[%s] -> [%s] (line %d)", - cf_socks_statename[oldstate], - cf_socks_statename[sx->state], lineno); -#else - (void)cf; - (void)data; -#endif -} - -static CURLproxycode socks_failed(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - CURLproxycode presult) -{ - sxstate(sx, cf, data, SOCKS_ST_FAILED); - sx->presult = presult; - return presult; -} - -static CURLproxycode socks_flush(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - CURLcode result; - size_t nwritten; - - *done = FALSE; - while(!Curl_bufq_is_empty(&sx->iobuf)) { - result = Curl_cf_send_bufq(cf->next, data, &sx->iobuf, NULL, 0, - &nwritten); - if(result == CURLE_AGAIN) - return CURLPX_OK; - else if(result) { - failf(data, "Failed to send SOCKS request: %s", - curl_easy_strerror(result)); - return socks_failed(sx, cf, data, CURLPX_SEND_CONNECT); - } - } - *done = TRUE; - return CURLPX_OK; -} - -static CURLproxycode socks_recv(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - size_t min_bytes, - bool *done) -{ - CURLcode result; - size_t nread; - - *done = FALSE; - while(Curl_bufq_len(&sx->iobuf) < min_bytes) { - result = Curl_cf_recv_bufq(cf->next, data, &sx->iobuf, - min_bytes - Curl_bufq_len(&sx->iobuf), - &nread); - if(result == CURLE_AGAIN) - return CURLPX_OK; - else if(result) { - failf(data, "Failed to receive SOCKS response: %s", - curl_easy_strerror(result)); - return CURLPX_RECV_CONNECT; - } - else if(!nread) { /* EOF */ - if(Curl_bufq_len(&sx->iobuf) < min_bytes) { - failf(data, "Failed to receive SOCKS response, " - "proxy closed connection"); - return CURLPX_RECV_CONNECT; - } - break; - } - } - *done = TRUE; - return CURLPX_OK; -} - -static CURLproxycode socks4_req_add_hd(struct socks_ctx *sx, - struct Curl_easy *data) -{ - unsigned char buf[4]; - size_t nwritten; - CURLcode result; - - (void)data; - buf[0] = 4; /* version (SOCKS4) */ - buf[1] = 1; /* connect */ - buf[2] = (unsigned char)((sx->remote_port >> 8) & 0xffU); /* MSB */ - buf[3] = (unsigned char)(sx->remote_port & 0xffU); /* LSB */ - - result = Curl_bufq_write(&sx->iobuf, buf, 4, &nwritten); - if(result || (nwritten != 4)) - return CURLPX_SEND_REQUEST; - return CURLPX_OK; -} - -static CURLproxycode socks4_req_add_user(struct socks_ctx *sx, - struct Curl_easy *data) -{ - CURLcode result; - size_t nwritten; - - if(sx->user) { - size_t plen = strlen(sx->user); - if(plen > 255) { - /* there is no real size limit to this field in the protocol, but - SOCKS5 limits the proxy user field to 255 bytes and it seems likely - that a longer field is either a mistake or malicious input */ - failf(data, "Too long SOCKS proxy username"); - return CURLPX_LONG_USER; - } - /* add proxy name WITH trailing zero */ - result = Curl_bufq_cwrite(&sx->iobuf, sx->user, plen + 1, - &nwritten); - if(result || (nwritten != (plen + 1))) - return CURLPX_SEND_REQUEST; - } - else { - /* empty username */ - unsigned char b = 0; - result = Curl_bufq_write(&sx->iobuf, &b, 1, &nwritten); - if(result || (nwritten != 1)) - return CURLPX_SEND_REQUEST; - } - return CURLPX_OK; -} - -static CURLproxycode socks4_resolving(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - const struct Curl_addrinfo *ai = NULL; - CURLcode result; - size_t nwritten; - bool dns_done; - - *done = FALSE; - if(sx->start_resolving) { - /* need to resolve hostname to add destination address */ - sx->start_resolving = FALSE; - result = Curl_cf_dns_insert_after( - cf, data, Curl_resolv_dns_queries(data, sx->ip_version), - sx->hostname, sx->remote_port, TRNSPRT_TCP, TRUE); - if(result) { - failf(data, "unable to create DNS filter for socks"); - return CURLPX_UNKNOWN_FAIL; - } - } - - /* resolve the hostname by connecting the DNS filter */ - result = Curl_conn_cf_connect(cf->next, data, &dns_done); - if(result) { - failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", - sx->hostname); - return CURLPX_RESOLVE_HOST; - } - else if(!dns_done) - return CURLPX_OK; - - ai = Curl_cf_dns_get_ai(cf->next, data, AF_INET, 0); - if(ai) { - struct sockaddr_in *saddr_in; - char ipbuf[64]; - - Curl_printable_address(ai, ipbuf, sizeof(ipbuf)); - CURL_TRC_CF(data, cf, "SOCKS4 connect to IPv4 %s (locally resolved)", - ipbuf); - - saddr_in = (struct sockaddr_in *)(void *)ai->ai_addr; - result = Curl_bufq_write(&sx->iobuf, - (unsigned char *)&saddr_in->sin_addr.s_addr, 4, - &nwritten); - - if(result || (nwritten != 4)) - return CURLPX_SEND_REQUEST; - } - else { - /* No ipv4 address resolved */ - failf(data, "SOCKS4 connection to %s not supported", sx->hostname); - return CURLPX_RESOLVE_HOST; - } - - *done = TRUE; - return CURLPX_OK; -} - -static CURLproxycode socks4_check_resp(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - const unsigned char *resp; - size_t rlen; - - if(!Curl_bufq_peek(&sx->iobuf, &resp, &rlen) || rlen < 8) { - failf(data, "SOCKS4 reply is incomplete."); - return CURLPX_RECV_CONNECT; - } - - DEBUGASSERT(rlen == 8); - /* - * Response format - * - * +----+----+----+----+----+----+----+----+ - * | VN | CD | DSTPORT | DSTIP | - * +----+----+----+----+----+----+----+----+ - * # of bytes: 1 1 2 4 - * - * VN is the version of the reply code and should be 0. CD is the result - * code with one of the following values: - * - * 90: request granted - * 91: request rejected or failed - * 92: request rejected because SOCKS server cannot connect to - * identd on the client - * 93: request rejected because the client program and identd - * report different user-ids - */ - - /* wrong version ? */ - if(resp[0]) { - failf(data, "SOCKS4 reply has wrong version, version should be 0."); - return CURLPX_BAD_VERSION; - } - - /* Result */ - switch(resp[1]) { - case 90: - CURL_TRC_CF(data, cf, "SOCKS4%s request granted.", sx->socks4a ? "a" : ""); - Curl_bufq_skip(&sx->iobuf, 8); - return CURLPX_OK; - case 91: - failf(data, - "[SOCKS] cannot complete SOCKS4 connection to %u.%u.%u.%u:%u. (%u)" - ", request rejected or failed.", - resp[4], resp[5], resp[6], resp[7], - (unsigned int)((resp[2] << 8) | resp[3]), resp[1]); - return CURLPX_REQUEST_FAILED; - case 92: - failf(data, - "[SOCKS] cannot complete SOCKS4 connection to %u.%u.%u.%u:%u. (%u)" - ", request rejected because SOCKS server cannot connect to " - "identd on the client.", - resp[4], resp[5], resp[6], resp[7], - (unsigned int)((resp[2] << 8) | resp[3]), resp[1]); - return CURLPX_IDENTD; - case 93: - failf(data, - "[SOCKS] cannot complete SOCKS4 connection to %u.%u.%u.%u:%u. (%u)" - ", request rejected because the client program and identd " - "report different user-ids.", - resp[4], resp[5], resp[6], resp[7], - (unsigned int)((resp[2] << 8) | resp[3]), resp[1]); - return CURLPX_IDENTD_DIFFER; - default: - failf(data, - "[SOCKS] cannot complete SOCKS4 connection to %u.%u.%u.%u:%u. (%u)" - ", Unknown.", - resp[4], resp[5], resp[6], resp[7], - (unsigned int)((resp[2] << 8) | resp[3]), resp[1]); - return CURLPX_UNKNOWN_FAIL; - } -} - -/* - * This function logs in to a SOCKS4 proxy and sends the specifics to the final - * destination server. - * - * Reference : - * https://www.openssh.com/txt/socks4.protocol - * - * Note : - * Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" - * Nonsupport "Identification Protocol (RFC1413)" - */ -static CURLproxycode socks4_connect(struct Curl_cfilter *cf, - struct socks_ctx *sx, - struct Curl_easy *data) -{ - size_t nwritten; - CURLproxycode presult; - CURLcode result; - bool done; - -process_state: - switch(sx->state) { - case SOCKS_ST_INIT: - sx->version = 4; - sxstate(sx, cf, data, SOCKS4_ST_START); - FALLTHROUGH(); - - case SOCKS4_ST_START: - Curl_bufq_reset(&sx->iobuf); - sx->start_resolving = FALSE; - sx->socks4a = (sx->proxy_type == CURLPROXY_SOCKS4A); - sx->resolve_local = !sx->socks4a; - sx->presult = CURLPX_OK; - - /* SOCKS4 can only do IPv4, insist! */ - sx->ip_version = CURL_IPRESOLVE_V4; - CURL_TRC_CF(data, cf, "SOCKS4%s connecting to %s:%u", - sx->socks4a ? "a" : "", sx->hostname, sx->remote_port); - - /* - * Compose socks4 request - * - * Request format - * - * +----+----+----+----+----+----+----+----+----+----+....+----+ - * | VN | CD | DSTPORT | DSTIP | USERID |NULL| - * +----+----+----+----+----+----+----+----+----+----+....+----+ - * # of bytes: 1 1 2 4 variable 1 - */ - presult = socks4_req_add_hd(sx, data); - if(presult) - return socks_failed(sx, cf, data, presult); - - /* DNS resolve only for SOCKS4, not SOCKS4a */ - if(!sx->resolve_local) { - /* socks4a, not resolving locally, sends the hostname. - * add an invalid address + user + hostname */ - unsigned char buf[4] = { 0, 0, 0, 1 }; - size_t hlen = strlen(sx->hostname) + 1; /* including NUL */ - - if(hlen > 255) { - failf(data, "SOCKS4: too long hostname"); - return socks_failed(sx, cf, data, CURLPX_LONG_HOSTNAME); - } - result = Curl_bufq_write(&sx->iobuf, buf, 4, &nwritten); - if(result || (nwritten != 4)) - return socks_failed(sx, cf, data, CURLPX_SEND_REQUEST); - presult = socks4_req_add_user(sx, data); - if(presult) - return socks_failed(sx, cf, data, presult); - result = Curl_bufq_cwrite(&sx->iobuf, sx->hostname, hlen, &nwritten); - if(result || (nwritten != hlen)) - return socks_failed(sx, cf, data, CURLPX_SEND_REQUEST); - /* request complete */ - sxstate(sx, cf, data, SOCKS4_ST_SEND); - goto process_state; - } - sx->start_resolving = TRUE; - sxstate(sx, cf, data, SOCKS4_ST_RESOLVING); - FALLTHROUGH(); - - case SOCKS4_ST_RESOLVING: - presult = socks4_resolving(sx, cf, data, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - if(!done) - return CURLPX_OK; - /* append user */ - presult = socks4_req_add_user(sx, data); - if(presult) - return socks_failed(sx, cf, data, presult); - sxstate(sx, cf, data, SOCKS4_ST_SEND); - FALLTHROUGH(); - - case SOCKS4_ST_SEND: - presult = socks_flush(sx, cf, data, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - else if(!done) - return CURLPX_OK; - sxstate(sx, cf, data, SOCKS4_ST_RECV); - FALLTHROUGH(); - - case SOCKS4_ST_RECV: - /* Receive 8 byte response */ - presult = socks_recv(sx, cf, data, 8, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - else if(!done) - return CURLPX_OK; - presult = socks4_check_resp(sx, cf, data); - if(presult) - return socks_failed(sx, cf, data, presult); - sxstate(sx, cf, data, SOCKS_ST_SUCCESS); - FALLTHROUGH(); - - case SOCKS_ST_SUCCESS: - return CURLPX_OK; - - case SOCKS_ST_FAILED: - DEBUGASSERT(sx->presult); - return sx->presult; - - default: - DEBUGASSERT(0); - return socks_failed(sx, cf, data, CURLPX_SEND_REQUEST); - } -} - -static CURLproxycode socks5_req0_init(struct Curl_cfilter *cf, - struct socks_ctx *sx, - struct Curl_easy *data) -{ - const unsigned char auth = data->set.socks5auth; - unsigned char req[5]; /* version + len + 3 possible auth methods */ - unsigned char nauths; - size_t req_len, nwritten; - CURLcode result; - - (void)cf; - /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */ - if(!sx->resolve_local && strlen(sx->hostname) > 255) { - failf(data, "SOCKS5: the destination hostname is too long to be " - "resolved remotely by the proxy."); - return CURLPX_LONG_HOSTNAME; - } - - if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) - infof(data, "warning: unsupported value passed to " - "CURLOPT_SOCKS5_AUTH: %u", auth); - if(!(auth & CURLAUTH_BASIC)) - /* disable username/password auth */ - sx->user = NULL; - - req[0] = 5; /* version */ - nauths = 1; - req[1 + nauths] = 0; /* 1. no authentication */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - if(auth & CURLAUTH_GSSAPI) { - ++nauths; - req[1 + nauths] = 1; /* GSS-API */ - } -#endif - if(sx->user) { - ++nauths; - req[1 + nauths] = 2; /* username/password */ - } - req[1] = nauths; - req_len = 2 + nauths; - - result = Curl_bufq_write(&sx->iobuf, req, req_len, &nwritten); - if(result || (nwritten != req_len)) - return CURLPX_SEND_REQUEST; - return CURLPX_OK; -} - -static CURLproxycode socks5_check_resp0(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - const unsigned char *resp; - unsigned char auth_mode; - size_t rlen; - - if(!Curl_bufq_peek(&sx->iobuf, &resp, &rlen) || rlen < 2) { - failf(data, "SOCKS5 initial reply is incomplete."); - return CURLPX_RECV_CONNECT; - } - - if(resp[0] != 5) { - failf(data, "Received invalid version in initial SOCKS5 response."); - return CURLPX_BAD_VERSION; - } - - auth_mode = resp[1]; - Curl_bufq_skip(&sx->iobuf, 2); - - switch(auth_mode) { - case 0: - /* DONE! No authentication needed. Send request. */ - sxstate(sx, cf, data, SOCKS5_ST_REQ1_INIT); - return CURLPX_OK; - case 1: - if(data->set.socks5auth & CURLAUTH_GSSAPI) { - sxstate(sx, cf, data, SOCKS5_ST_GSSAPI_INIT); - return CURLPX_OK; - } - failf(data, - "SOCKS5 GSSAPI per-message authentication is not enabled."); - return CURLPX_GSSAPI_PERMSG; - case 2: - /* regular name + password authentication */ - if(data->set.socks5auth & CURLAUTH_BASIC) { - sxstate(sx, cf, data, SOCKS5_ST_AUTH_INIT); - return CURLPX_OK; - } - failf(data, "BASIC authentication proposed but not enabled."); - return CURLPX_NO_AUTH; - case 255: - failf(data, "No authentication method was acceptable."); - return CURLPX_NO_AUTH; - default: - failf(data, "Unknown SOCKS5 mode attempted to be used by server."); - return CURLPX_UNKNOWN_MODE; - } -} - -static CURLproxycode socks5_auth_init(struct Curl_cfilter *cf, - struct socks_ctx *sx, - struct Curl_easy *data) -{ - /* Needs username and password */ - size_t ulen = 0, plen = 0, nwritten; - unsigned char buf[2]; - CURLcode result; - - if(sx->user && sx->passwd) { - ulen = strlen(sx->user); - plen = strlen(sx->passwd); - /* the lengths must fit in a single byte */ - if(ulen > 255) { - failf(data, "Excessive username length for proxy auth"); - return CURLPX_LONG_USER; - } - if(plen > 255) { - failf(data, "Excessive password length for proxy auth"); - return CURLPX_LONG_PASSWD; - } - } - - /* username/password request looks like - * +----+------+----------+------+----------+ - * |VER | ULEN | UNAME | PLEN | PASSWD | - * +----+------+----------+------+----------+ - * | 1 | 1 | 1 to 255 | 1 | 1 to 255 | - * +----+------+----------+------+----------+ - */ - buf[0] = 1; /* username/pw subnegotiation version */ - buf[1] = (unsigned char)ulen; - result = Curl_bufq_write(&sx->iobuf, buf, 2, &nwritten); - if(result || (nwritten != 2)) - return CURLPX_SEND_REQUEST; - if(ulen) { - result = Curl_bufq_cwrite(&sx->iobuf, sx->user, ulen, &nwritten); - if(result || (nwritten != ulen)) - return CURLPX_SEND_REQUEST; - } - buf[0] = (unsigned char)plen; - result = Curl_bufq_write(&sx->iobuf, buf, 1, &nwritten); - if(result || (nwritten != 1)) - return CURLPX_SEND_REQUEST; - if(plen) { - result = Curl_bufq_cwrite(&sx->iobuf, sx->passwd, plen, &nwritten); - if(result || (nwritten != plen)) - return CURLPX_SEND_REQUEST; - } - sxstate(sx, cf, data, SOCKS5_ST_AUTH_SEND); - return CURLPX_OK; -} - -static CURLproxycode socks5_check_auth_resp(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - const unsigned char *resp; - unsigned char auth_status; - size_t rlen; - - (void)cf; - if(!Curl_bufq_peek(&sx->iobuf, &resp, &rlen) || rlen < 2) { - failf(data, "SOCKS5 sub-negotiation response incomplete."); - return CURLPX_RECV_CONNECT; - } - - /* ignore the first (VER) byte */ - auth_status = resp[1]; - if(auth_status) { - failf(data, "User was rejected by the SOCKS5 server (%d %d).", - resp[0], resp[1]); - return CURLPX_USER_REJECTED; - } - Curl_bufq_skip(&sx->iobuf, 2); - return CURLPX_OK; -} - -static CURLproxycode socks5_req1_init(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - unsigned char req[5]; - unsigned char ipbuf[16]; - const unsigned char *destination; - unsigned char desttype, destlen, hdlen; - size_t nwritten; - CURLcode result; - - req[0] = 5; /* version (SOCKS5) */ - req[1] = 1; /* connect */ - req[2] = 0; /* must be zero */ - if(sx->resolve_local) { - /* rest of request is added after resolving */ - result = Curl_bufq_write(&sx->iobuf, req, 3, &nwritten); - if(result || (nwritten != 3)) - return CURLPX_SEND_REQUEST; - return CURLPX_OK; - } - - /* remote resolving, send what type+addr/string to resolve */ -#ifdef USE_IPV6 - if(strchr(sx->hostname, ':')) { - desttype = 4; - destination = ipbuf; - destlen = 16; - if(curlx_inet_pton(AF_INET6, sx->hostname, ipbuf) != 1) - return CURLPX_BAD_ADDRESS_TYPE; - } - else -#endif - if(curlx_inet_pton(AF_INET, sx->hostname, ipbuf) == 1) { - desttype = 1; - destination = ipbuf; - destlen = 4; - } - else { - const size_t hostname_len = strlen(sx->hostname); - /* socks5_req0_init() already rejects hostnames longer than 255 bytes, so - this cast to unsigned char is safe. Assert to guard against future - refactoring that might remove or reorder that earlier check. */ - DEBUGASSERT(hostname_len <= 255); - desttype = 3; - destination = (const unsigned char *)sx->hostname; - destlen = (unsigned char)hostname_len; /* one byte length */ - } - - req[3] = desttype; - req[4] = destlen; - hdlen = (desttype == 3) ? 5 : 4; /* no length byte for ip addresses */ - result = Curl_bufq_write(&sx->iobuf, req, hdlen, &nwritten); - if(result || (nwritten != hdlen)) - return CURLPX_SEND_REQUEST; - result = Curl_bufq_write(&sx->iobuf, destination, destlen, &nwritten); - if(result || (nwritten != destlen)) - return CURLPX_SEND_REQUEST; - /* PORT MSB+LSB */ - req[0] = (unsigned char)((sx->remote_port >> 8) & 0xff); - req[1] = (unsigned char)(sx->remote_port & 0xff); - result = Curl_bufq_write(&sx->iobuf, req, 2, &nwritten); - if(result || (nwritten != 2)) - return CURLPX_SEND_REQUEST; - CURL_TRC_CF(data, cf, "SOCKS5 connect to %s:%u (remotely resolved)", - sx->hostname, sx->remote_port); - return CURLPX_OK; -} - -static CURLproxycode socks5_resolving(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - const struct Curl_addrinfo *ai = NULL; - char dest[MAX_IPADR_LEN]; /* printable address */ - const unsigned char *destination = NULL; - unsigned char desttype = 1, destlen = 4; - unsigned char req[2]; - CURLcode result; - CURLproxycode presult = CURLPX_OK; - size_t nwritten; - bool dns_done; - - *done = FALSE; - if(sx->start_resolving) { - /* need to resolve hostname to add destination address */ - sx->start_resolving = FALSE; - result = Curl_cf_dns_insert_after( - cf, data, Curl_resolv_dns_queries(data, sx->ip_version), - sx->hostname, sx->remote_port, TRNSPRT_TCP, TRUE); - if(result) { - failf(data, "unable to create DNS filter for socks"); - return CURLPX_UNKNOWN_FAIL; - } - } - - /* resolve the hostname by connecting the DNS filter */ - result = Curl_conn_cf_connect(cf->next, data, &dns_done); - if(result) { - failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", sx->hostname); - return CURLPX_RESOLVE_HOST; - } - else if(!dns_done) - return CURLPX_OK; - -#ifdef USE_IPV6 - if(data->set.ipver != CURL_IPRESOLVE_V4) - ai = Curl_cf_dns_get_ai(cf->next, data, AF_INET6, 0); -#endif - if(!ai) - ai = Curl_cf_dns_get_ai(cf->next, data, AF_INET, 0); - - if(!ai) { - failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", sx->hostname); - presult = CURLPX_RESOLVE_HOST; - goto out; - } - - Curl_printable_address(ai, dest, sizeof(dest)); - - if(ai->ai_family == AF_INET) { - struct sockaddr_in *saddr_in; - desttype = 1; /* ATYP: IPv4 = 1 */ - destlen = 4; - saddr_in = (struct sockaddr_in *)(void *)ai->ai_addr; - destination = (const unsigned char *)&saddr_in->sin_addr.s_addr; - CURL_TRC_CF(data, cf, "SOCKS5 connect to %s:%u (locally resolved)", - dest, sx->remote_port); - } -#ifdef USE_IPV6 - else if(ai->ai_family == AF_INET6) { - struct sockaddr_in6 *saddr_in6; - desttype = 4; /* ATYP: IPv6 = 4 */ - destlen = 16; - saddr_in6 = (struct sockaddr_in6 *)(void *)ai->ai_addr; - destination = (const unsigned char *)&saddr_in6->sin6_addr.s6_addr; - CURL_TRC_CF(data, cf, "SOCKS5 connect to [%s]:%u (locally resolved)", - dest, sx->remote_port); - } -#endif - - if(!destination) { - failf(data, "SOCKS5 connection to %s not supported", dest); - presult = CURLPX_RESOLVE_HOST; - goto out; - } - - req[0] = desttype; - result = Curl_bufq_write(&sx->iobuf, req, 1, &nwritten); - if(result || (nwritten != 1)) { - presult = CURLPX_SEND_REQUEST; - goto out; - } - result = Curl_bufq_write(&sx->iobuf, destination, destlen, &nwritten); - if(result || (nwritten != destlen)) { - presult = CURLPX_SEND_REQUEST; - goto out; - } - /* PORT MSB+LSB */ - req[0] = (unsigned char)((sx->remote_port >> 8) & 0xffU); - req[1] = (unsigned char)(sx->remote_port & 0xffU); - result = Curl_bufq_write(&sx->iobuf, req, 2, &nwritten); - if(result || (nwritten != 2)) { - presult = CURLPX_SEND_REQUEST; - goto out; - } - -out: - *done = (presult == CURLPX_OK); - return presult; -} - -static CURLproxycode socks5_recv_resp1(struct socks_ctx *sx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - const unsigned char *resp; - size_t rlen, resp_len = 8; /* minimum response length */ - CURLproxycode presult; - - presult = socks_recv(sx, cf, data, resp_len, done); - if(presult) - return presult; - else if(!*done) - return CURLPX_OK; - - if(!Curl_bufq_peek(&sx->iobuf, &resp, &rlen) || rlen < resp_len) { - failf(data, "SOCKS5 response is incomplete."); - return CURLPX_RECV_CONNECT; - } - - /* Response packet includes BND.ADDR is variable length parameter by RFC - 1928, so the response packet MUST be read until the end to avoid errors - at subsequent protocol level. - - +----+-----+-------+------+----------+----------+ - |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | - +----+-----+-------+------+----------+----------+ - | 1 | 1 | X'00' | 1 | Variable | 2 | - +----+-----+-------+------+----------+----------+ - - ATYP: - o IP v4 address: X'01', BND.ADDR = 4 byte - o domain name: X'03', BND.ADDR = [ 1 byte length, string ] - o IP v6 address: X'04', BND.ADDR = 16 byte - */ - if(resp[0] != 5) { /* version */ - failf(data, "SOCKS5 reply has wrong version, version should be 5."); - return CURLPX_BAD_VERSION; - } - else if(resp[1]) { /* Anything besides 0 is an error */ - CURLproxycode rc = CURLPX_REPLY_UNASSIGNED; - int code = resp[1]; - failf(data, "cannot complete SOCKS5 connection to %s. (%d)", - sx->hostname, code); - if(code < 9) { - /* RFC 1928 section 6 lists: */ - static const CURLproxycode lookup[] = { - CURLPX_OK, - CURLPX_REPLY_GENERAL_SERVER_FAILURE, - CURLPX_REPLY_NOT_ALLOWED, - CURLPX_REPLY_NETWORK_UNREACHABLE, - CURLPX_REPLY_HOST_UNREACHABLE, - CURLPX_REPLY_CONNECTION_REFUSED, - CURLPX_REPLY_TTL_EXPIRED, - CURLPX_REPLY_COMMAND_NOT_SUPPORTED, - CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED, - }; - rc = lookup[code]; - } - return rc; - } - - /* Calculate real packet size */ - switch(resp[3]) { - case 1: /* IPv4 */ - resp_len = 4 + 4 + 2; - break; - case 3: /* domain name */ - resp_len = 4 + 1 + resp[4] + 2; /* header, var length, var bytes, port */ - break; - case 4: /* IPv6 */ - resp_len = 4 + 16 + 2; - break; - default: - failf(data, "SOCKS5 reply has wrong address type."); - return CURLPX_BAD_ADDRESS_TYPE; - } - - /* receive the rest of the response */ - presult = socks_recv(sx, cf, data, resp_len, done); - if(presult) - return presult; - else if(!*done) - return CURLPX_OK; - - if(!Curl_bufq_peek(&sx->iobuf, &resp, &rlen) || rlen < resp_len) { - failf(data, "SOCKS5 response is incomplete."); - return CURLPX_RECV_CONNECT; - } - /* got it all */ - *done = TRUE; - return CURLPX_OK; -} - -/* - * This function logs in to a SOCKS5 proxy and sends the specifics to the final - * destination server. - */ -static CURLproxycode socks5_connect(struct Curl_cfilter *cf, - struct socks_ctx *sx, - struct Curl_easy *data) -{ - CURLproxycode presult; - bool done; - -process_state: - switch(sx->state) { - case SOCKS_ST_INIT: - sx->version = 5; - sx->resolve_local = (sx->proxy_type == CURLPROXY_SOCKS5); - sxstate(sx, cf, data, SOCKS5_ST_START); - FALLTHROUGH(); - - case SOCKS5_ST_START: - CURL_TRC_CF(data, cf, "SOCKS5: connecting to %s:%u", - sx->hostname, sx->remote_port); - presult = socks5_req0_init(cf, sx, data); - if(presult) - return socks_failed(sx, cf, data, presult); - sxstate(sx, cf, data, SOCKS5_ST_REQ0_SEND); - FALLTHROUGH(); - - case SOCKS5_ST_REQ0_SEND: - presult = socks_flush(sx, cf, data, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - else if(!done) - return CURLPX_OK; - /* done sending! */ - sxstate(sx, cf, data, SOCKS5_ST_RESP0_RECV); - FALLTHROUGH(); - - case SOCKS5_ST_RESP0_RECV: - presult = socks_recv(sx, cf, data, 2, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - else if(!done) - return CURLPX_OK; - presult = socks5_check_resp0(sx, cf, data); - if(presult) - return socks_failed(sx, cf, data, presult); - /* socks5_check_resp0() sets next socks state */ - goto process_state; - - case SOCKS5_ST_GSSAPI_INIT: { -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - /* GSSAPI stuff done non-blocking */ - CURLcode result = Curl_SOCKS5_gssapi_negotiate(cf, data); - if(result) { - failf(data, "Unable to negotiate SOCKS5 GSS-API context."); - return CURLPX_GSSAPI; - } - sxstate(sx, cf, data, SOCKS5_ST_REQ1_INIT); - goto process_state; -#else - failf(data, - "SOCKS5 GSSAPI per-message authentication is not supported."); - return socks_failed(sx, cf, data, CURLPX_GSSAPI_PERMSG); -#endif - } - - case SOCKS5_ST_AUTH_INIT: - presult = socks5_auth_init(cf, sx, data); - if(presult) - return socks_failed(sx, cf, data, presult); - sxstate(sx, cf, data, SOCKS5_ST_AUTH_SEND); - FALLTHROUGH(); - - case SOCKS5_ST_AUTH_SEND: - presult = socks_flush(sx, cf, data, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - else if(!done) - return CURLPX_OK; - sxstate(sx, cf, data, SOCKS5_ST_AUTH_RECV); - FALLTHROUGH(); - - case SOCKS5_ST_AUTH_RECV: - presult = socks_recv(sx, cf, data, 2, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - else if(!done) - return CURLPX_OK; - presult = socks5_check_auth_resp(sx, cf, data); - if(presult) - return socks_failed(sx, cf, data, presult); - /* Everything is good so far, user was authenticated! */ - sxstate(sx, cf, data, SOCKS5_ST_REQ1_INIT); - FALLTHROUGH(); - - case SOCKS5_ST_REQ1_INIT: - presult = socks5_req1_init(sx, cf, data); - if(presult) - return socks_failed(sx, cf, data, presult); - if(!sx->resolve_local) { - /* we do not resolve, request is complete */ - sxstate(sx, cf, data, SOCKS5_ST_REQ1_SEND); - goto process_state; - } - sx->start_resolving = TRUE; - sxstate(sx, cf, data, SOCKS5_ST_RESOLVING); - FALLTHROUGH(); - - case SOCKS5_ST_RESOLVING: - presult = socks5_resolving(sx, cf, data, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - if(!done) - return CURLPX_OK; - sxstate(sx, cf, data, SOCKS5_ST_REQ1_SEND); - FALLTHROUGH(); - - case SOCKS5_ST_REQ1_SEND: - presult = socks_flush(sx, cf, data, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - else if(!done) - return CURLPX_OK; -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - if(cf->conn->socks5_gssapi_enctype) { - failf(data, "SOCKS5 GSS-API protection not yet implemented."); - return CURLPX_GSSAPI_PROTECTION; - } -#endif - sxstate(sx, cf, data, SOCKS5_ST_RESP1_RECV); - FALLTHROUGH(); - - case SOCKS5_ST_RESP1_RECV: - presult = socks5_recv_resp1(sx, cf, data, &done); - if(presult) - return socks_failed(sx, cf, data, presult); - if(!done) - return CURLPX_OK; - CURL_TRC_CF(data, cf, "SOCKS5 request granted."); - sxstate(sx, cf, data, SOCKS_ST_SUCCESS); - FALLTHROUGH(); - - case SOCKS_ST_SUCCESS: - return CURLPX_OK; - - case SOCKS_ST_FAILED: - DEBUGASSERT(sx->presult); - return sx->presult; - - default: - DEBUGASSERT(0); - return socks_failed(sx, cf, data, CURLPX_SEND_REQUEST); - } -} - -static void socks_proxy_ctx_free(struct socks_ctx *ctx) -{ - if(ctx) { - Curl_bufq_free(&ctx->iobuf); - curlx_free(ctx); - } -} - -/* After a TCP connection to the proxy has been verified, this function does - the next magic steps. If 'done' is not set TRUE, it is not done yet and - must be called again. - - Note: this function's sub-functions call failf() - -*/ -static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct socks_ctx *ctx = cf->ctx; - CURLproxycode pxresult = CURLPX_OK; - CURLcode result; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - result = cf->next->cft->do_connect(cf->next, data, done); - if(result || !*done) - return result; - - switch(ctx->proxy_type) { - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: - pxresult = socks5_connect(cf, ctx, data); - break; - - case CURLPROXY_SOCKS4: - case CURLPROXY_SOCKS4A: - pxresult = socks4_connect(cf, ctx, data); - break; - - default: - DEBUGASSERT(0); /* should not come here, checked it at creation time */ - result = CURLE_COULDNT_CONNECT; - goto out; - } - - if(pxresult) { - result = CURLE_PROXY; - data->info.pxcode = pxresult; - goto out; - } - else if(ctx->state != SOCKS_ST_SUCCESS) - goto out; - -#ifdef CURLVERBOSE - if(Curl_trc_is_verbose(data)) { - struct ip_quadruple ipquad; - bool is_ipv6; - if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) - infof(data, "Opened %sSOCKS connection from %s port %d to %s port %d " - "(via %s port %u)", - (cf->sockindex == SECONDARYSOCKET) ? "2nd " : "", - ipquad.local_ip, ipquad.local_port, - ctx->hostname, ctx->remote_port, - ipquad.remote_ip, ipquad.remote_port); - else - infof(data, "Opened %sSOCKS connection", - (cf->sockindex == SECONDARYSOCKET) ? "2nd " : ""); - } -#endif - cf->connected = TRUE; - -out: - *done = (bool)cf->connected; - if(*done || result) { - ctx->user = NULL; - ctx->passwd = NULL; - } - return result; -} - -static CURLcode socks_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct socks_ctx *sx = cf->ctx; - CURLcode result = CURLE_OK; - - if(!cf->connected && sx) { - /* If we are not connected, the filter below is and has nothing - * to wait on, we determine what to wait for. */ - curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); - switch(sx->state) { - case SOCKS4_ST_SEND: - case SOCKS5_ST_REQ0_SEND: - case SOCKS5_ST_AUTH_SEND: - case SOCKS5_ST_REQ1_SEND: - CURL_TRC_CF(data, cf, "adjust pollset out (%d)", sx->state); - result = Curl_pollset_set_out_only(data, ps, sock); - break; - default: - CURL_TRC_CF(data, cf, "adjust pollset in (%d)", sx->state); - result = Curl_pollset_set_in_only(data, ps, sock); - break; - } - } - return result; -} - -static void socks_proxy_cf_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - cf->connected = FALSE; - if(cf->next) - cf->next->cft->do_close(cf->next, data); -} - -static void socks_proxy_cf_destroy(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - (void)data; - socks_proxy_ctx_free(cf->ctx); - cf->ctx = NULL; -} - -static CURLcode socks_cf_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct socks_ctx *sx = cf->ctx; - - switch(query) { - case CF_QUERY_HOST_PORT: - if(sx) { - *pres1 = sx->remote_port; - *((const char **)pres2) = sx->hostname; - return CURLE_OK; - } - break; - case CF_QUERY_ALPN_NEGOTIATED: { - const char **palpn = pres2; - DEBUGASSERT(palpn); - *palpn = NULL; - return CURLE_OK; - } - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -struct Curl_cftype Curl_cft_socks_proxy = { - "SOCKS", - CF_TYPE_IP_CONNECT | CF_TYPE_PROXY, - 0, - socks_proxy_cf_destroy, - socks_proxy_cf_connect, - socks_proxy_cf_close, - Curl_cf_def_shutdown, - socks_cf_adjust_pollset, - Curl_cf_def_data_pending, - Curl_cf_def_send, - Curl_cf_def_recv, - Curl_cf_def_cntrl, - Curl_cf_def_conn_is_alive, - Curl_cf_def_conn_keep_alive, - socks_cf_query, -}; - -CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - const char *hostname, - uint16_t port, - uint8_t ip_version, - uint8_t proxy_type, - const char *user, - const char *passwd) -{ - struct Curl_cfilter *cf; - struct socks_ctx *ctx; - size_t hostlen = hostname ? strlen(hostname) : 0; - CURLcode result; - - if(!hostlen) - return CURLE_FAILED_INIT; - - switch(proxy_type) { - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: - case CURLPROXY_SOCKS4: - case CURLPROXY_SOCKS4A: - break; /* all supported */ - default: - failf(data, "unknown proxytype %d option given", proxy_type); - return CURLE_COULDNT_CONNECT; - } - - /* NUL byte already part of struct size */ - ctx = curlx_calloc(1, sizeof(*ctx) + hostlen); - if(!ctx) { - return CURLE_OUT_OF_MEMORY; - } - - memcpy(ctx->hostname, hostname, hostlen); - ctx->remote_port = port; - ctx->ip_version = ip_version; - ctx->proxy_type = proxy_type; - ctx->user = user; - ctx->passwd = passwd; - Curl_bufq_init2(&ctx->iobuf, SOCKS_CHUNK_SIZE, SOCKS_CHUNKS, - BUFQ_OPT_SOFT_LIMIT); - - result = Curl_cf_create(&cf, &Curl_cft_socks_proxy, ctx); - if(!result) - Curl_conn_cf_insert_after(cf_at, cf); - else - socks_proxy_ctx_free(ctx); - return result; -} - -#endif /* CURL_DISABLE_PROXY */ diff --git a/vendor/curl/lib/socks.h b/vendor/curl/lib/socks.h deleted file mode 100644 index ea368326d..000000000 --- a/vendor/curl/lib/socks.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef HEADER_CURL_SOCKS_H -#define HEADER_CURL_SOCKS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_PROXY -/* - * Helper read-from-socket functions. Does the same as Curl_read() but it - * blocks until all bytes amount of buffersize will be read. No more, no less. - * - * This is STUPID BLOCKING behavior - */ -CURLcode Curl_blockread_all(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, - size_t blen, - size_t *pnread); - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) -/* - * This function handles the SOCKS5 GSS-API negotiation and initialization - */ -CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, - struct Curl_easy *data); -#endif - -/* Insert a SOCKS filter after `cf_at` for connecting to `hostname` - * and `port` with optional credentials. - * Credentials are NOT duplicated and are - * expected to exist during connect phase. - */ -CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data, - const char *hostname, - uint16_t port, - uint8_t ip_version, - uint8_t proxy_type, - const char *user, - const char *passwd); - -extern struct Curl_cftype Curl_cft_socks_proxy; - -#endif /* !CURL_DISABLE_PROXY */ - -#endif /* HEADER_CURL_SOCKS_H */ diff --git a/vendor/curl/lib/socks_gssapi.c b/vendor/curl/lib/socks_gssapi.c deleted file mode 100644 index 32db07044..000000000 --- a/vendor/curl/lib/socks_gssapi.c +++ /dev/null @@ -1,546 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Markus Moeller, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY) - -#include "curl_gssapi.h" -#include "urldata.h" -#include "curl_trc.h" -#include "cfilters.h" -#include "connect.h" -#include "curlx/nonblock.h" -#include "socks.h" -#include "curlx/strdup.h" - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -#define MAX_GSS_LEN 1024 - -/* - * Helper GSS-API error functions. - */ -static int check_gss_err(struct Curl_easy *data, - OM_uint32 major_status, - OM_uint32 minor_status, - const char *function) -{ - if(GSS_ERROR(major_status)) { - OM_uint32 maj_stat, min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status_string = GSS_C_EMPTY_BUFFER; - struct dynbuf dbuf; - - curlx_dyn_init(&dbuf, MAX_GSS_LEN); - msg_ctx = 0; - while(!msg_ctx) { - /* convert major status code (GSS-API error) to text */ - maj_stat = gss_display_status(&min_stat, major_status, - GSS_C_GSS_CODE, - GSS_C_NULL_OID, - &msg_ctx, &status_string); - if(maj_stat == GSS_S_COMPLETE) { - if(curlx_dyn_addn(&dbuf, status_string.value, status_string.length)) - return 1; /* error */ - gss_release_buffer(&min_stat, &status_string); - break; - } - gss_release_buffer(&min_stat, &status_string); - } - if(curlx_dyn_addn(&dbuf, ".\n", 2)) - return 1; /* error */ - msg_ctx = 0; - while(!msg_ctx) { - /* convert minor status code (underlying routine error) to text */ - maj_stat = gss_display_status(&min_stat, minor_status, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, &status_string); - if(maj_stat == GSS_S_COMPLETE) { - if(curlx_dyn_addn(&dbuf, status_string.value, status_string.length)) - return 1; /* error */ - gss_release_buffer(&min_stat, &status_string); - break; - } - gss_release_buffer(&min_stat, &status_string); - } - failf(data, "GSS-API error: %s failed: %s", function, - curlx_dyn_ptr(&dbuf)); - curlx_dyn_free(&dbuf); - return 1; - } - - return 0; -} - -CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct connectdata *conn = cf->conn; - curl_socket_t sock = conn->sock[cf->sockindex]; - CURLcode code; - size_t actualread; - size_t nwritten; - CURLcode result; - OM_uint32 gss_major_status, gss_minor_status, gss_status; - OM_uint32 gss_ret_flags; - int gss_conf_state, gss_enc; - gss_buffer_desc service = GSS_C_EMPTY_BUFFER; - gss_buffer_desc gss_send_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc gss_recv_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc gss_w_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc *gss_token = GSS_C_NO_BUFFER; - gss_name_t server = GSS_C_NO_NAME; - gss_name_t gss_client_name = GSS_C_NO_NAME; - unsigned short us_length; - unsigned char socksreq[4]; /* room for GSS-API exchange header only */ - const char *serviceptr = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd"; - const size_t serviceptr_length = strlen(serviceptr); - gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT; - - /* GSS-API request looks like - * +----+------+-----+----------------+ - * |VER | MTYP | LEN | TOKEN | - * +----+------+----------------------+ - * | 1 | 1 | 2 | up to 2^16 - 1 | - * +----+------+-----+----------------+ - */ - - /* prepare service name */ - if(strchr(serviceptr, '/')) { - service.length = serviceptr_length; - service.value = curlx_memdup(serviceptr, service.length); - if(!service.value) - return CURLE_OUT_OF_MEMORY; - - gss_major_status = gss_import_name(&gss_minor_status, &service, - (gss_OID)GSS_C_NULL_OID, &server); - } - else { - service.value = curlx_malloc(serviceptr_length + - strlen(conn->socks_proxy.host.name) + 2); - if(!service.value) - return CURLE_OUT_OF_MEMORY; - service.length = serviceptr_length + - strlen(conn->socks_proxy.host.name) + 1; - curl_msnprintf(service.value, service.length + 1, "%s@%s", - serviceptr, conn->socks_proxy.host.name); - - gss_major_status = gss_import_name(&gss_minor_status, &service, - GSS_C_NT_HOSTBASED_SERVICE, &server); - } - - curlx_safefree(service.value); - service.length = 0; - - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_import_name()")) { - failf(data, "Failed to create service name."); - gss_release_name(&gss_status, &server); - return CURLE_COULDNT_CONNECT; - } - - (void)curlx_nonblock(sock, FALSE); - - /* As long as we need to keep sending some context info, and there is no - * errors, keep sending it... */ - for(;;) { - gss_major_status = Curl_gss_init_sec_context(data, - &gss_minor_status, - &gss_context, - server, - &Curl_krb5_mech_oid, - NULL, - gss_token, - &gss_send_token, - TRUE, - &gss_ret_flags); - - if(gss_token != GSS_C_NO_BUFFER) { - curlx_safefree(gss_recv_token.value); - gss_recv_token.length = 0; - } - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_init_sec_context") || - /* the size needs to fit in a 16-bit field */ - (gss_send_token.length > 0xffff)) { - gss_release_name(&gss_status, &server); - gss_release_buffer(&gss_status, &gss_send_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - failf(data, "Failed to initial GSS-API token."); - return CURLE_COULDNT_CONNECT; - } - - if(gss_send_token.length) { - socksreq[0] = 1; /* GSS-API subnegotiation version */ - socksreq[1] = 1; /* authentication message type */ - us_length = htons((unsigned short)gss_send_token.length); - memcpy(socksreq + 2, &us_length, sizeof(short)); - - code = Curl_conn_cf_send(cf->next, data, socksreq, 4, FALSE, &nwritten); - if(code || (nwritten != 4)) { - failf(data, "Failed to send GSS-API authentication request."); - gss_release_name(&gss_status, &server); - gss_release_buffer(&gss_status, &gss_send_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - code = Curl_conn_cf_send(cf->next, data, - gss_send_token.value, - gss_send_token.length, FALSE, &nwritten); - if(code || (gss_send_token.length != nwritten)) { - failf(data, "Failed to send GSS-API authentication token."); - gss_release_name(&gss_status, &server); - gss_release_buffer(&gss_status, &gss_send_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - } - - gss_release_buffer(&gss_status, &gss_send_token); - if(gss_major_status != GSS_S_CONTINUE_NEEDED) - break; - - /* analyze response */ - - /* GSS-API response looks like - * +----+------+-----+----------------+ - * |VER | MTYP | LEN | TOKEN | - * +----+------+----------------------+ - * | 1 | 1 | 2 | up to 2^16 - 1 | - * +----+------+-----+----------------+ - */ - - result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive GSS-API authentication response."); - gss_release_name(&gss_status, &server); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - /* ignore the first (VER) byte */ - if(socksreq[1] == 255) { /* status / message type */ - failf(data, "User was rejected by the SOCKS5 server (%d %d).", - socksreq[0], socksreq[1]); - gss_release_name(&gss_status, &server); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 1) { /* status / message type */ - failf(data, "Invalid GSS-API authentication response type (%d %d).", - socksreq[0], socksreq[1]); - gss_release_name(&gss_status, &server); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq + 2, sizeof(short)); - us_length = ntohs(us_length); - - if(!us_length) { - failf(data, "Invalid zero-length GSS-API authentication token."); - gss_release_name(&gss_status, &server); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - gss_recv_token.length = us_length; - gss_recv_token.value = curlx_malloc(gss_recv_token.length); - if(!gss_recv_token.value) { - failf(data, - "Could not allocate memory for GSS-API authentication " - "response token."); - gss_release_name(&gss_status, &server); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_OUT_OF_MEMORY; - } - - result = Curl_blockread_all(cf, data, (char *)gss_recv_token.value, - gss_recv_token.length, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive GSS-API authentication token."); - gss_release_name(&gss_status, &server); - curlx_safefree(gss_recv_token.value); - gss_recv_token.length = 0; - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - gss_token = &gss_recv_token; - } - - gss_release_name(&gss_status, &server); - - /* Everything is good so far, user was authenticated! */ - gss_major_status = gss_inquire_context(&gss_minor_status, gss_context, - &gss_client_name, NULL, NULL, NULL, - NULL, NULL, NULL); - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_inquire_context")) { - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - gss_release_name(&gss_status, &gss_client_name); - failf(data, "Failed to determine username."); - return CURLE_COULDNT_CONNECT; - } - gss_major_status = gss_display_name(&gss_minor_status, gss_client_name, - &gss_send_token, NULL); - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_display_name")) { - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - gss_release_name(&gss_status, &gss_client_name); - gss_release_buffer(&gss_status, &gss_send_token); - failf(data, "Failed to determine username."); - return CURLE_COULDNT_CONNECT; - } - - infof(data, "SOCKS5 server authenticated user %.*s with GSS-API.", - (int)gss_send_token.length, (const char *)gss_send_token.value); - - gss_release_name(&gss_status, &gss_client_name); - gss_release_buffer(&gss_status, &gss_send_token); - - /* Do encryption */ - socksreq[0] = 1; /* GSS-API subnegotiation version */ - socksreq[1] = 2; /* encryption message type */ - - gss_enc = 0; /* no data protection */ - /* do confidentiality protection if supported */ - if(gss_ret_flags & GSS_C_CONF_FLAG) - gss_enc = 2; - /* else do integrity protection */ - else if(gss_ret_flags & GSS_C_INTEG_FLAG) - gss_enc = 1; - - infof(data, "SOCKS5 server supports GSS-API %s data protection.", - (gss_enc == 0) ? "no" : - ((gss_enc == 1) ? "integrity" : "confidentiality")); - - /* - * Sending the encryption type in clear seems wrong. It should be - * protected with gss_seal()/gss_wrap(). See RFC1961 extract below - * The NEC reference implementations on which this is based is - * therefore at fault - * - * +------+------+------+.......................+ - * + ver | mtyp | len | token | - * +------+------+------+.......................+ - * + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets | - * +------+------+------+.......................+ - * - * Where: - * - * - "ver" is the protocol version number, here 1 to represent the - * first version of the SOCKS/GSS-API protocol - * - * - "mtyp" is the message type, here 2 to represent a protection - * -level negotiation message - * - * - "len" is the length of the "token" field in octets - * - * - "token" is the GSS-API encapsulated protection level - * - * The token is produced by encapsulating an octet containing the - * required protection level using gss_seal()/gss_wrap() with conf_req - * set to FALSE. The token is verified using gss_unseal()/ - * gss_unwrap(). - * - */ - if(data->set.socks5_gssapi_nec) { - us_length = htons((short)1); - memcpy(socksreq + 2, &us_length, sizeof(short)); - } - else { - gss_send_token.length = 1; - gss_send_token.value = curlx_memdup(&gss_enc, gss_send_token.length); - if(!gss_send_token.value) { - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_OUT_OF_MEMORY; - } - - gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0, - GSS_C_QOP_DEFAULT, &gss_send_token, - &gss_conf_state, &gss_w_token); - - if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) { - curlx_safefree(gss_send_token.value); - gss_send_token.length = 0; - gss_release_buffer(&gss_status, &gss_w_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - failf(data, "Failed to wrap GSS-API encryption value into token."); - return CURLE_COULDNT_CONNECT; - } - curlx_safefree(gss_send_token.value); - gss_send_token.length = 0; - - us_length = htons((unsigned short)gss_w_token.length); - memcpy(socksreq + 2, &us_length, sizeof(short)); - } - - code = Curl_conn_cf_send(cf->next, data, socksreq, 4, FALSE, &nwritten); - if(code || (nwritten != 4)) { - failf(data, "Failed to send GSS-API encryption request."); - gss_release_buffer(&gss_status, &gss_w_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(data->set.socks5_gssapi_nec) { - memcpy(socksreq, &gss_enc, 1); - code = Curl_conn_cf_send(cf->next, data, socksreq, 1, FALSE, &nwritten); - if(code || (nwritten != 1)) { - failf(data, "Failed to send GSS-API encryption type."); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - } - else { - code = Curl_conn_cf_send(cf->next, data, gss_w_token.value, - gss_w_token.length, FALSE, &nwritten); - if(code || (gss_w_token.length != nwritten)) { - failf(data, "Failed to send GSS-API encryption type."); - gss_release_buffer(&gss_status, &gss_w_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - gss_release_buffer(&gss_status, &gss_w_token); - } - - result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive GSS-API encryption response."); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - /* ignore the first (VER) byte */ - if(socksreq[1] == 255) { /* status / message type */ - failf(data, "User was rejected by the SOCKS5 server (%d %d).", - socksreq[0], socksreq[1]); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 2) { /* status / message type */ - failf(data, "Invalid GSS-API encryption response type (%d %d).", - socksreq[0], socksreq[1]); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq + 2, sizeof(short)); - us_length = ntohs(us_length); - - if(!us_length) { - failf(data, "Invalid zero-length GSS-API encryption token."); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - gss_recv_token.length = us_length; - gss_recv_token.value = curlx_malloc(gss_recv_token.length); - if(!gss_recv_token.value) { - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_OUT_OF_MEMORY; - } - result = Curl_blockread_all(cf, data, (char *)gss_recv_token.value, - gss_recv_token.length, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive GSS-API encryption type."); - curlx_safefree(gss_recv_token.value); - gss_recv_token.length = 0; - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(!data->set.socks5_gssapi_nec) { - gss_major_status = gss_unwrap(&gss_minor_status, gss_context, - &gss_recv_token, &gss_w_token, - 0, GSS_C_QOP_DEFAULT); - - if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) { - curlx_safefree(gss_recv_token.value); - gss_recv_token.length = 0; - gss_release_buffer(&gss_status, &gss_w_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - failf(data, "Failed to unwrap GSS-API encryption value into token."); - return CURLE_COULDNT_CONNECT; - } - curlx_safefree(gss_recv_token.value); - gss_recv_token.length = 0; - - if(gss_w_token.length != 1) { - failf(data, "Invalid GSS-API encryption response length (%zu).", - gss_w_token.length); - gss_release_buffer(&gss_status, &gss_w_token); - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(socksreq, gss_w_token.value, gss_w_token.length); - gss_release_buffer(&gss_status, &gss_w_token); - } - else { - if(gss_recv_token.length != 1) { - failf(data, "Invalid GSS-API encryption response length (%zu).", - gss_recv_token.length); - curlx_safefree(gss_recv_token.value); - gss_recv_token.length = 0; - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(socksreq, gss_recv_token.value, gss_recv_token.length); - curlx_safefree(gss_recv_token.value); - gss_recv_token.length = 0; - } - - (void)curlx_nonblock(sock, TRUE); - - infof(data, "SOCKS5 access with%s protection granted.", - (socksreq[0] == 0) ? "out GSS-API data" : - ((socksreq[0] == 1) ? " GSS-API integrity" : - " GSS-API confidentiality")); - - conn->socks5_gssapi_enctype = socksreq[0]; - if(socksreq[0] == 0) - Curl_gss_delete_sec_context(&gss_status, &gss_context, NULL); - - return CURLE_OK; -} - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic pop -#endif - -#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */ diff --git a/vendor/curl/lib/socks_sspi.c b/vendor/curl/lib/socks_sspi.c deleted file mode 100644 index 385312a36..000000000 --- a/vendor/curl/lib/socks_sspi.c +++ /dev/null @@ -1,538 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Markus Moeller, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY) - -#include "urldata.h" -#include "curl_trc.h" -#include "cfilters.h" -#include "connect.h" -#include "strerror.h" -#include "curlx/nonblock.h" -#include "socks.h" -#include "curl_sspi.h" -#include "curlx/multibyte.h" - -/* - * Helper sspi error functions. - */ -static int check_sspi_err(struct Curl_easy *data, - SECURITY_STATUS status, - const char *function) -{ - if(status != SEC_E_OK && - status != SEC_I_COMPLETE_AND_CONTINUE && - status != SEC_I_COMPLETE_NEEDED && - status != SEC_I_CONTINUE_NEEDED) { - char buffer[STRERROR_LEN]; - failf(data, "SSPI error: %s failed: %s", function, - Curl_sspi_strerror(status, buffer, sizeof(buffer))); - return 1; - } - return 0; -} - -/* This is the SSPI-using version of this function */ -static CURLcode socks5_sspi_setup(struct Curl_cfilter *cf, - struct Curl_easy *data, - CredHandle *cred_handle, - char **service_namep) -{ - struct connectdata *conn = cf->conn; - const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd"; - SECURITY_STATUS status; - - /* prepare service name */ - if(strchr(service, '/')) - *service_namep = curlx_strdup(service); - else - *service_namep = curl_maprintf("%s/%s", - service, conn->socks_proxy.host.name); - if(!*service_namep) - return CURLE_OUT_OF_MEMORY; - - status = - Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(TEXT("Kerberos")), - SECPKG_CRED_OUTBOUND, - NULL, NULL, NULL, NULL, - cred_handle, NULL); - - if(check_sspi_err(data, status, "AcquireCredentialsHandle")) { - failf(data, "Failed to acquire credentials."); - return CURLE_COULDNT_CONNECT; - } - - return CURLE_OK; -} - -static CURLcode socks5_free_token(SecBuffer *send_token, - CURLcode result) -{ - if(send_token->pvBuffer) { - Curl_pSecFn->FreeContextBuffer(send_token->pvBuffer); - send_token->pvBuffer = NULL; - } - return result; -} - -static CURLcode socks5_sspi_loop(struct Curl_cfilter *cf, - struct Curl_easy *data, - CredHandle *cred_handle, - CtxtHandle *sspi_context, - char *service_name, - unsigned long *sspi_ret_flagsp) -{ - struct connectdata *conn = cf->conn; - curl_socket_t sock = conn->sock[cf->sockindex]; - CURLcode result = CURLE_OK; - CURLcode code; - SECURITY_STATUS status; - SecBuffer sspi_send_token, sspi_recv_token; - SecBufferDesc input_desc, output_desc; - PCtxtHandle context_handle = NULL; - unsigned short us_length; - size_t actualread; - size_t written; - unsigned char socksreq[4]; - - input_desc.cBuffers = 1; - input_desc.pBuffers = &sspi_recv_token; - input_desc.ulVersion = SECBUFFER_VERSION; - - sspi_recv_token.BufferType = SECBUFFER_TOKEN; - sspi_recv_token.cbBuffer = 0; - sspi_recv_token.pvBuffer = NULL; - - output_desc.cBuffers = 1; - output_desc.pBuffers = &sspi_send_token; - output_desc.ulVersion = SECBUFFER_VERSION; - - sspi_send_token.BufferType = SECBUFFER_TOKEN; - sspi_send_token.cbBuffer = 0; - sspi_send_token.pvBuffer = NULL; - - (void)curlx_nonblock(sock, FALSE); - - for(;;) { - TCHAR *sname = curlx_convert_UTF8_to_tchar(service_name); - if(!sname) { - curlx_free(sspi_recv_token.pvBuffer); - return socks5_free_token(&sspi_send_token, CURLE_OUT_OF_MEMORY); - } - - status = - Curl_pSecFn->InitializeSecurityContext(cred_handle, context_handle, - sname, - ISC_REQ_MUTUAL_AUTH | - ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_CONFIDENTIALITY | - ISC_REQ_REPLAY_DETECT, - 0, SECURITY_NATIVE_DREP, - &input_desc, 0, - sspi_context, - &output_desc, - sspi_ret_flagsp, NULL); - - curlx_free(sname); - curlx_safefree(sspi_recv_token.pvBuffer); - sspi_recv_token.cbBuffer = 0; - - if(check_sspi_err(data, status, "InitializeSecurityContext")) { - failf(data, "Failed to initialise security context."); - return socks5_free_token(&sspi_send_token, CURLE_COULDNT_CONNECT); - } - - if(sspi_send_token.cbBuffer) { - socksreq[0] = 1; /* GSS-API subnegotiation version */ - socksreq[1] = 1; /* authentication message type */ - if(sspi_send_token.cbBuffer > 0xffff) { - /* needs to fit in an unsigned 16-bit field */ - return socks5_free_token(&sspi_send_token, CURLE_COULDNT_CONNECT); - } - us_length = htons((unsigned short)sspi_send_token.cbBuffer); - memcpy(socksreq + 2, &us_length, sizeof(short)); - - code = Curl_conn_cf_send(cf->next, data, socksreq, 4, FALSE, &written); - if(code || (written != 4)) { - failf(data, "Failed to send SSPI authentication request."); - return socks5_free_token(&sspi_send_token, CURLE_COULDNT_CONNECT); - } - - code = Curl_conn_cf_send(cf->next, data, - sspi_send_token.pvBuffer, - sspi_send_token.cbBuffer, FALSE, &written); - if(code || (sspi_send_token.cbBuffer != written)) { - failf(data, "Failed to send SSPI authentication token."); - return socks5_free_token(&sspi_send_token, CURLE_COULDNT_CONNECT); - } - } - - if(sspi_send_token.pvBuffer) - socks5_free_token(&sspi_send_token, CURLE_OK); - sspi_send_token.cbBuffer = 0; - - curlx_safefree(sspi_recv_token.pvBuffer); - sspi_recv_token.cbBuffer = 0; - - if(status != SEC_I_CONTINUE_NEEDED) - break; - - result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive SSPI authentication response."); - return result ? result : CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] == 255) { - failf(data, "User was rejected by the SOCKS5 server (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 1) { - failf(data, "Invalid SSPI authentication response type (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq + 2, sizeof(short)); - us_length = ntohs(us_length); - - if(!us_length) { - failf(data, "Invalid zero-length SSPI authentication token."); - return CURLE_COULDNT_CONNECT; - } - - sspi_recv_token.cbBuffer = us_length; - sspi_recv_token.pvBuffer = curlx_malloc(us_length); - - if(!sspi_recv_token.pvBuffer) - return CURLE_OUT_OF_MEMORY; - - result = Curl_blockread_all(cf, data, (char *)sspi_recv_token.pvBuffer, - sspi_recv_token.cbBuffer, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive SSPI authentication token."); - curlx_free(sspi_recv_token.pvBuffer); - return result ? result : CURLE_COULDNT_CONNECT; - } - - context_handle = sspi_context; - } - - return CURLE_OK; -} - -static CURLcode socks5_free(SecBuffer *sspi_w_token, - CURLcode result) -{ - curlx_safefree(sspi_w_token[0].pvBuffer); - curlx_safefree(sspi_w_token[1].pvBuffer); - curlx_safefree(sspi_w_token[2].pvBuffer); - return result; -} - -static CURLcode socks5_sspi_encrypt(struct Curl_cfilter *cf, - struct Curl_easy *data, - CtxtHandle *sspi_context, - unsigned long sspi_ret_flags) -{ - CURLcode result = CURLE_OK; - CURLcode code; - SECURITY_STATUS status; - unsigned char gss_enc; - SecBuffer sspi_w_token[3]; - SecBufferDesc wrap_desc; - SecPkgContext_Sizes sspi_sizes; - unsigned short us_length; - unsigned long qop; - unsigned char socksreq[4]; - uint8_t *etbuf = NULL; - size_t etbuf_size = 0; - size_t actualread; - size_t written; - - gss_enc = 0; - if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY) - gss_enc = 2; - else if(sspi_ret_flags & ISC_REQ_INTEGRITY) - gss_enc = 1; - - infof(data, "SOCKS5 server supports GSS-API %s data protection.", - (gss_enc == 0) ? "no" : - ((gss_enc == 1) ? "integrity" : "confidentiality")); - - sspi_w_token[0].pvBuffer = - sspi_w_token[1].pvBuffer = - sspi_w_token[2].pvBuffer = NULL; - - wrap_desc.cBuffers = 3; - wrap_desc.pBuffers = sspi_w_token; - wrap_desc.ulVersion = SECBUFFER_VERSION; - - socksreq[0] = 1; - socksreq[1] = 2; - - if(data->set.socks5_gssapi_nec) { - us_length = htons((unsigned short)1); - memcpy(socksreq + 2, &us_length, sizeof(short)); - } - else { - status = Curl_pSecFn->QueryContextAttributes(sspi_context, - SECPKG_ATTR_SIZES, - &sspi_sizes); - if(check_sspi_err(data, status, "QueryContextAttributes")) { - failf(data, "Failed to query security context attributes."); - return CURLE_COULDNT_CONNECT; - } - - sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer; - sspi_w_token[0].BufferType = SECBUFFER_TOKEN; - sspi_w_token[0].pvBuffer = curlx_malloc(sspi_sizes.cbSecurityTrailer); - - if(!sspi_w_token[0].pvBuffer) - return CURLE_OUT_OF_MEMORY; - - sspi_w_token[1].cbBuffer = 1; - sspi_w_token[1].BufferType = SECBUFFER_DATA; - sspi_w_token[1].pvBuffer = curlx_malloc(1); - if(!sspi_w_token[1].pvBuffer) - return socks5_free(sspi_w_token, CURLE_OUT_OF_MEMORY); - - memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1); - sspi_w_token[2].BufferType = SECBUFFER_PADDING; - sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize; - sspi_w_token[2].pvBuffer = curlx_malloc(sspi_sizes.cbBlockSize); - if(!sspi_w_token[2].pvBuffer) - return socks5_free(sspi_w_token, CURLE_OUT_OF_MEMORY); - - status = Curl_pSecFn->EncryptMessage(sspi_context, - KERB_WRAP_NO_ENCRYPT, - &wrap_desc, 0); - if(check_sspi_err(data, status, "EncryptMessage")) - return socks5_free(sspi_w_token, CURLE_COULDNT_CONNECT); - - etbuf_size = sspi_w_token[0].cbBuffer + sspi_w_token[1].cbBuffer + - sspi_w_token[2].cbBuffer; - if(etbuf_size > 0xffff) - return socks5_free(sspi_w_token, CURLE_COULDNT_CONNECT); - - etbuf = curlx_malloc(etbuf_size); - if(!etbuf) - return socks5_free(sspi_w_token, CURLE_OUT_OF_MEMORY); - - memcpy(etbuf, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer); - memcpy(etbuf + sspi_w_token[0].cbBuffer, - sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer); - memcpy(etbuf + sspi_w_token[0].cbBuffer + sspi_w_token[1].cbBuffer, - sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer); - - (void)socks5_free(sspi_w_token, CURLE_OK); - - us_length = htons((unsigned short)etbuf_size); - memcpy(socksreq + 2, &us_length, sizeof(short)); - } - - code = Curl_conn_cf_send(cf->next, data, socksreq, 4, FALSE, &written); - if(code || (written != 4)) { - failf(data, "Failed to send SSPI encryption request."); - curlx_free(etbuf); - return CURLE_COULDNT_CONNECT; - } - - if(data->set.socks5_gssapi_nec) { - memcpy(socksreq, &gss_enc, 1); - code = Curl_conn_cf_send(cf->next, data, socksreq, 1, FALSE, &written); - if(code || (written != 1)) { - failf(data, "Failed to send SSPI encryption type."); - return CURLE_COULDNT_CONNECT; - } - } - else { - code = Curl_conn_cf_send(cf->next, data, etbuf, etbuf_size, FALSE, - &written); - curlx_free(etbuf); - if(code || (etbuf_size != written)) { - failf(data, "Failed to send SSPI encryption type."); - return CURLE_COULDNT_CONNECT; - } - } - - result = Curl_blockread_all(cf, data, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive SSPI encryption response."); - return result ? result : CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] == 255) { - failf(data, "User was rejected by the SOCKS5 server (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 2) { - failf(data, "Invalid SSPI encryption response type (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq + 2, sizeof(short)); - us_length = ntohs(us_length); - - if(!us_length) { - failf(data, "Invalid zero-length SSPI encryption token."); - return CURLE_COULDNT_CONNECT; - } - - sspi_w_token[0].cbBuffer = us_length; - sspi_w_token[0].pvBuffer = curlx_malloc(us_length); - if(!sspi_w_token[0].pvBuffer) - return CURLE_OUT_OF_MEMORY; - - result = Curl_blockread_all(cf, data, (char *)sspi_w_token[0].pvBuffer, - sspi_w_token[0].cbBuffer, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive SSPI encryption type."); - curlx_free(sspi_w_token[0].pvBuffer); - return result ? result : CURLE_COULDNT_CONNECT; - } - - if(!data->set.socks5_gssapi_nec) { - wrap_desc.cBuffers = 2; - sspi_w_token[0].BufferType = SECBUFFER_STREAM; - sspi_w_token[1].BufferType = SECBUFFER_DATA; - sspi_w_token[1].cbBuffer = 0; - sspi_w_token[1].pvBuffer = NULL; - - status = Curl_pSecFn->DecryptMessage(sspi_context, &wrap_desc, - 0, &qop); - - if(check_sspi_err(data, status, "DecryptMessage")) { - if(sspi_w_token[1].pvBuffer) - Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - curlx_free(sspi_w_token[0].pvBuffer); - return CURLE_COULDNT_CONNECT; - } - - if(sspi_w_token[1].cbBuffer != 1) { - failf(data, "Invalid SSPI encryption response length (%lu).", - (unsigned long)sspi_w_token[1].cbBuffer); - if(sspi_w_token[1].pvBuffer) - Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - curlx_free(sspi_w_token[0].pvBuffer); - return CURLE_COULDNT_CONNECT; - } - - memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer); - Curl_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - } - else { - if(sspi_w_token[0].cbBuffer != 1) { - failf(data, "Invalid SSPI encryption response length (%lu).", - (unsigned long)sspi_w_token[0].cbBuffer); - curlx_free(sspi_w_token[0].pvBuffer); - return CURLE_COULDNT_CONNECT; - } - memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer); - } - curlx_free(sspi_w_token[0].pvBuffer); - - infof(data, "SOCKS5 access with%s protection granted BUT NOT USED.", - (socksreq[0] == 0) ? "out GSS-API data" : - ((socksreq[0] == 1) ? " GSS-API integrity" : - " GSS-API confidentiality")); - - return CURLE_OK; -} - -CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct connectdata *conn = cf->conn; - curl_socket_t sock = conn->sock[cf->sockindex]; - CURLcode result; - SECURITY_STATUS status; - CredHandle cred_handle; - CtxtHandle sspi_context; - SecPkgCredentials_Names names; - char *service_name = NULL; - unsigned long sspi_ret_flags = 0; - - memset(&cred_handle, 0, sizeof(cred_handle)); - memset(&sspi_context, 0, sizeof(sspi_context)); - names.sUserName = NULL; - - result = socks5_sspi_setup(cf, data, &cred_handle, &service_name); - if(result) - goto error; - - result = socks5_sspi_loop(cf, data, &cred_handle, &sspi_context, - service_name, &sspi_ret_flags); - if(result) - goto error; - - curlx_safefree(service_name); - - status = Curl_pSecFn->QueryCredentialsAttributes(&cred_handle, - SECPKG_CRED_ATTR_NAMES, - &names); - if(check_sspi_err(data, status, "QueryCredentialAttributes")) { - failf(data, "Failed to determine username."); - result = CURLE_COULDNT_CONNECT; - goto error; - } - else { - VERBOSE(char *user_utf8 = curlx_convert_tchar_to_UTF8(names.sUserName)); - infof(data, "SOCKS5 server authenticated user %s with GSS-API.", - (user_utf8 ? user_utf8 : "(unknown)")); - VERBOSE(curlx_free(user_utf8)); - Curl_pSecFn->FreeContextBuffer(names.sUserName); - names.sUserName = NULL; - } - - result = socks5_sspi_encrypt(cf, data, &sspi_context, sspi_ret_flags); - if(result) - goto error; - - (void)curlx_nonblock(sock, TRUE); - Curl_pSecFn->DeleteSecurityContext(&sspi_context); - Curl_pSecFn->FreeCredentialsHandle(&cred_handle); - return CURLE_OK; - -error: - (void)curlx_nonblock(sock, TRUE); - curlx_free(service_name); - Curl_pSecFn->DeleteSecurityContext(&sspi_context); - Curl_pSecFn->FreeCredentialsHandle(&cred_handle); - if(names.sUserName) - Curl_pSecFn->FreeContextBuffer(names.sUserName); - return result; -} -#endif diff --git a/vendor/curl/lib/splay.c b/vendor/curl/lib/splay.c deleted file mode 100644 index ddab7a4d6..000000000 --- a/vendor/curl/lib/splay.c +++ /dev/null @@ -1,291 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "splay.h" - -/* - * This macro compares two node keys i and j and returns: - * - * negative value: when i is smaller than j - * zero : when i is equal to j - * positive when : when i is larger than j - */ -#define splay_compare(i, j) curlx_ptimediff_us(i, j) - -/* - * Splay using the key i (which may or may not be in the tree.) The starting - * root is t. - */ -struct Curl_tree *Curl_splay(const struct curltime *pkey, - struct Curl_tree *t) -{ - struct Curl_tree N, *l, *r, *y; - - if(!t) - return NULL; - N.smaller = N.larger = NULL; - l = r = &N; - - for(;;) { - timediff_t comp = splay_compare(pkey, &t->key); - if(comp < 0) { - if(!t->smaller) - break; - if(splay_compare(pkey, &t->smaller->key) < 0) { - y = t->smaller; /* rotate smaller */ - t->smaller = y->larger; - y->larger = t; - t = y; - if(!t->smaller) - break; - } - r->smaller = t; /* link smaller */ - r = t; - t = t->smaller; - } - else if(comp > 0) { - if(!t->larger) - break; - if(splay_compare(pkey, &t->larger->key) > 0) { - y = t->larger; /* rotate larger */ - t->larger = y->smaller; - y->smaller = t; - t = y; - if(!t->larger) - break; - } - l->larger = t; /* link larger */ - l = t; - t = t->larger; - } - else - break; - } - - l->larger = t->smaller; /* assemble */ - r->smaller = t->larger; - t->smaller = N.larger; - t->larger = N.smaller; - - return t; -} - -static const struct curltime SPLAY_SUBNODE = { - ~0, -1 -}; - -/* Insert key i into the tree t. Return a pointer to the resulting tree or - * NULL if something went wrong. - * - * @unittest: 1309 - */ -struct Curl_tree *Curl_splayinsert(const struct curltime *pkey, - struct Curl_tree *t, - struct Curl_tree *node) -{ - DEBUGASSERT(node); - - if(t) { - t = Curl_splay(pkey, t); - DEBUGASSERT(t); - if(splay_compare(pkey, &t->key) == 0) { - /* There already exists a node in the tree with the same key. Build a - doubly-linked circular list of nodes. We add the new 'node' struct to - the end of this list. */ - - node->key = SPLAY_SUBNODE; /* identify this node as a subnode */ - node->samen = t; - node->samep = t->samep; - t->samep->samen = node; - t->samep = node; - - return t; /* the root node always stays the same */ - } - } - - if(!t) { - node->smaller = node->larger = NULL; - } - else if(splay_compare(pkey, &t->key) < 0) { - node->smaller = t->smaller; - node->larger = t; - t->smaller = NULL; - } - else { - node->larger = t->larger; - node->smaller = t; - t->larger = NULL; - } - node->key = *pkey; - - /* no identical nodes (yet), we are the only one in the list of nodes */ - node->samen = node; - node->samep = node; - return node; -} - -/* Finds and deletes the best-fit node from the tree. Return a pointer to the - resulting tree. best-fit means the smallest node if it is not larger than - the key */ -struct Curl_tree *Curl_splaygetbest(const struct curltime *pkey, - struct Curl_tree *t, - struct Curl_tree **removed) -{ - static const struct curltime tv_zero = { 0, 0 }; - struct Curl_tree *x; - - if(!t) { - *removed = NULL; /* none removed since there was no root */ - return NULL; - } - - /* find smallest */ - t = Curl_splay(&tv_zero, t); - DEBUGASSERT(t); - if(splay_compare(pkey, &t->key) < 0) { - /* even the smallest is too big */ - *removed = NULL; - return t; - } - - /* FIRST! Check if there is a list with identical keys */ - x = t->samen; - if(x != t) { - /* there is, pick one from the list */ - - /* 'x' is the new root node */ - - x->key = t->key; - x->larger = t->larger; - x->smaller = t->smaller; - x->samep = t->samep; - t->samep->samen = x; - - *removed = t; - return x; /* new root */ - } - - /* we splayed the tree to the smallest element, there is no smaller */ - x = t->larger; - *removed = t; - - return x; -} - -/* Deletes the node we point out from the tree if it is there. Stores a - * pointer to the new resulting tree in 'newroot'. - * - * Returns zero on success and non-zero on errors! - * When returning error, it does not touch the 'newroot' pointer. - * - * NOTE: when the last node of the tree is removed, there is no tree left so - * 'newroot' will be made to point to NULL. - * - * @unittest: 1309 - */ -int Curl_splayremove(struct Curl_tree *t, - struct Curl_tree *removenode, - struct Curl_tree **newroot) -{ - struct Curl_tree *x; - - if(!t) - return 1; - - DEBUGASSERT(removenode); - - if(splay_compare(&SPLAY_SUBNODE, &removenode->key) == 0) { - /* It is a subnode within a 'same' linked list and thus we can unlink it - easily. */ - DEBUGASSERT(removenode->samen != removenode); - if(removenode->samen == removenode) - /* A non-subnode should never be set to SPLAY_SUBNODE */ - return 3; - - removenode->samep->samen = removenode->samen; - removenode->samen->samep = removenode->samep; - - /* Ensures that double-remove gets caught. */ - removenode->samen = removenode; - - *newroot = t; /* return the same root */ - return 0; - } - - t = Curl_splay(&removenode->key, t); - DEBUGASSERT(t); - - /* First make sure that we got the same root node as the one we want - to remove, as otherwise we might be trying to remove a node that - is not actually in the tree. - - We cannot compare the keys here as a double remove in quick - succession of a node with key != SPLAY_SUBNODE && same != NULL - could return the same key but a different node. */ - DEBUGASSERT(t == removenode); - if(t != removenode) - return 2; - - /* Check if there is a list with identical sizes, as then we are trying to - remove the root node of a list of nodes with identical keys. */ - x = t->samen; - if(x != t) { - /* 'x' is the new root node, we make it use the root node's - smaller/larger links */ - - x->key = t->key; - x->larger = t->larger; - x->smaller = t->smaller; - x->samep = t->samep; - t->samep->samen = x; - } - else { - /* Remove the root node */ - if(!t->smaller) - x = t->larger; - else { - x = Curl_splay(&removenode->key, t->smaller); - DEBUGASSERT(x); - x->larger = t->larger; - } - } - - *newroot = x; /* store new root pointer */ - - return 0; -} - -/* set and get the custom payload for this tree node */ -void Curl_splayset(struct Curl_tree *node, void *payload) -{ - DEBUGASSERT(node); - node->ptr = payload; -} - -void *Curl_splayget(struct Curl_tree *node) -{ - DEBUGASSERT(node); - return node->ptr; -} diff --git a/vendor/curl/lib/splay.h b/vendor/curl/lib/splay.h deleted file mode 100644 index c6623f2ef..000000000 --- a/vendor/curl/lib/splay.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef HEADER_CURL_SPLAY_H -#define HEADER_CURL_SPLAY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "curlx/timeval.h" - -/* only use function calls to access this struct */ -struct Curl_tree { - struct Curl_tree *smaller; /* smaller node */ - struct Curl_tree *larger; /* larger node */ - struct Curl_tree *samen; /* points to the next node with identical key */ - struct Curl_tree *samep; /* points to the prev node with identical key */ - struct curltime key; /* this node's "sort" key */ - void *ptr; /* data the splay code does not care about */ -}; - -struct Curl_tree *Curl_splay(const struct curltime *pkey, - struct Curl_tree *t); - -struct Curl_tree *Curl_splayinsert(const struct curltime *pkey, - struct Curl_tree *t, - struct Curl_tree *node); - -struct Curl_tree *Curl_splaygetbest(const struct curltime *pkey, - struct Curl_tree *t, - struct Curl_tree **removed); - -int Curl_splayremove(struct Curl_tree *t, - struct Curl_tree *removenode, - struct Curl_tree **newroot); - -/* set and get the custom payload for this tree node */ -void Curl_splayset(struct Curl_tree *node, void *payload); -void *Curl_splayget(struct Curl_tree *node); - -#endif /* HEADER_CURL_SPLAY_H */ diff --git a/vendor/curl/lib/strcase.c b/vendor/curl/lib/strcase.c deleted file mode 100644 index 9f70f41bd..000000000 --- a/vendor/curl/lib/strcase.c +++ /dev/null @@ -1,146 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "strcase.h" - -/* Mapping table to go from lowercase to uppercase for plain ASCII.*/ -static const unsigned char touppermap[256] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255 -}; - -/* Mapping table to go from uppercase to lowercase for plain ASCII.*/ -static const unsigned char tolowermap[256] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255 -}; - -/* Portable, consistent toupper. Do not use toupper() because its behavior is - altered by the current locale. */ -char Curl_raw_toupper(char in) -{ - return (char)touppermap[(unsigned char)in]; -} - -/* Portable, consistent tolower. Do not use tolower() because its behavior is - altered by the current locale. */ -char Curl_raw_tolower(char in) -{ - return (char)tolowermap[(unsigned char)in]; -} - -/* Copy an upper case version of the string from src to dest. The - * strings may overlap. No more than n characters of the string are copied - * (including any NUL) and the destination string will NOT be - * null-terminated if that limit is reached. - */ -void Curl_strntoupper(char *dest, const char *src, size_t n) -{ - if(n < 1) - return; - - do { - *dest++ = Curl_raw_toupper(*src); - } while(*src++ && --n); -} - -/* Copy a lower case version of the string from src to dest. The - * strings may overlap. No more than n characters of the string are copied - * (including any NUL) and the destination string will NOT be - * null-terminated if that limit is reached. - */ -void Curl_strntolower(char *dest, const char *src, size_t n) -{ - if(n < 1) - return; - - do { - *dest++ = Curl_raw_tolower(*src); - } while(*src++ && --n); -} - -/* Compare case-sensitive null-terminated strings, taking care of possible - * null pointers. Return true if arguments match. - */ -bool Curl_safecmp(const char *a, const char *b) -{ - if(a && b) - return !strcmp(a, b); - return !a && !b; -} - -/* - * Curl_timestrcmp() returns 0 if the two strings are identical. The time this - * function spends is a function of the shortest string, not of the contents. - */ -int Curl_timestrcmp(const char *a, const char *b) -{ - int match = 0; - int i = 0; - - if(a && b) { - while(1) { - match |= a[i] ^ b[i]; - if(!a[i] || !b[i]) - break; - i++; - } - } - else - return a || b; - return match; -} diff --git a/vendor/curl/lib/strcase.h b/vendor/curl/lib/strcase.h deleted file mode 100644 index 54299812b..000000000 --- a/vendor/curl/lib/strcase.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef HEADER_CURL_STRCASE_H -#define HEADER_CURL_STRCASE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -char Curl_raw_toupper(char in); -char Curl_raw_tolower(char in); - -/* checkprefix() is a shorter version of the above, used when the first - argument is the string literal */ -#define checkprefix(a, b) curl_strnequal(b, STRCONST(a)) - -void Curl_strntoupper(char *dest, const char *src, size_t n); -void Curl_strntolower(char *dest, const char *src, size_t n); - -bool Curl_safecmp(const char *a, const char *b); -int Curl_timestrcmp(const char *a, const char *b); - -#endif /* HEADER_CURL_STRCASE_H */ diff --git a/vendor/curl/lib/strequal.c b/vendor/curl/lib/strequal.c deleted file mode 100644 index a352fda70..000000000 --- a/vendor/curl/lib/strequal.c +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "strcase.h" - -/* - * curl_strequal() is for doing "raw" case insensitive strings. This is meant - * to be locale independent and only compare strings we know are safe for - * this. See https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for - * further explanations as to why this function is necessary. - */ - -static int casecompare(const char *first, const char *second) -{ - while(*first) { - if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) - /* get out of the loop as soon as they do not match */ - return 0; - first++; - second++; - } - /* If we are here either the strings are the same or the length is different. - We can test if the "current" character is non-zero for one and zero - for the other. Note that the characters may not be exactly the same even - if they match, we only want to compare zero-ness. */ - return !*first == !*second; -} - -static int ncasecompare(const char *first, const char *second, size_t max) -{ - while(*first && max) { - if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) - return 0; - max--; - first++; - second++; - } - if(max == 0) - return 1; /* they are equal this far */ - - return Curl_raw_toupper(*first) == Curl_raw_toupper(*second); -} - -/* - * Only "raw" case insensitive strings. This is meant to be locale independent - * and only compare strings we know are safe for this. - * - * The function is capable of comparing a-z case insensitively. - * - * Result is 1 if text matches and 0 if not. - */ - -/* --- public function --- */ -int curl_strequal(const char *s1, const char *s2) -{ - if(s1 && s2) - /* both pointers point to something then compare them */ - return casecompare(s1, s2); - - /* if both pointers are NULL then treat them as equal */ - return NULL == s1 && NULL == s2; -} - -/* --- public function --- */ -int curl_strnequal(const char *s1, const char *s2, size_t n) -{ - if(s1 && s2) - /* both pointers point to something then compare them */ - return ncasecompare(s1, s2, n); - - /* if both pointers are NULL then treat them as equal if max is non-zero */ - return NULL == s1 && NULL == s2 && n; -} diff --git a/vendor/curl/lib/strerror.c b/vendor/curl/lib/strerror.c deleted file mode 100644 index 1e97c2829..000000000 --- a/vendor/curl/lib/strerror.c +++ /dev/null @@ -1,676 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_WINDOWS_SSPI -#include "curl_sspi.h" -#endif - -#include "curlx/winapi.h" -#include "strerror.h" -#include "curlx/strcopy.h" - -const char *curl_easy_strerror(CURLcode error) -{ -#ifdef CURLVERBOSE - switch(error) { - case CURLE_OK: - return "No error"; - - case CURLE_UNSUPPORTED_PROTOCOL: - return "Unsupported protocol"; - - case CURLE_FAILED_INIT: - return "Failed initialization"; - - case CURLE_URL_MALFORMAT: - return "URL using bad/illegal format or missing URL"; - - case CURLE_NOT_BUILT_IN: - return "A requested feature, protocol or option was not found built-in in" - " this libcurl due to a build-time decision."; - - case CURLE_COULDNT_RESOLVE_PROXY: - return "Could not resolve proxy name"; - - case CURLE_COULDNT_RESOLVE_HOST: - return "Could not resolve hostname"; - - case CURLE_COULDNT_CONNECT: - return "Could not connect to server"; - - case CURLE_WEIRD_SERVER_REPLY: - return "Weird server reply"; - - case CURLE_REMOTE_ACCESS_DENIED: - return "Access denied to remote resource"; - - case CURLE_FTP_ACCEPT_FAILED: - return "FTP: The server failed to connect to data port"; - - case CURLE_FTP_ACCEPT_TIMEOUT: - return "FTP: Accepting server connect has timed out"; - - case CURLE_FTP_PRET_FAILED: - return "FTP: The server did not accept the PRET command."; - - case CURLE_FTP_WEIRD_PASS_REPLY: - return "FTP: unknown PASS reply"; - - case CURLE_FTP_WEIRD_PASV_REPLY: - return "FTP: unknown PASV reply"; - - case CURLE_FTP_WEIRD_227_FORMAT: - return "FTP: unknown 227 response format"; - - case CURLE_FTP_CANT_GET_HOST: - return "FTP: cannot figure out the host in the PASV response"; - - case CURLE_HTTP2: - return "Error in the HTTP2 framing layer"; - - case CURLE_FTP_COULDNT_SET_TYPE: - return "FTP: could not set file type"; - - case CURLE_PARTIAL_FILE: - return "Transferred a partial file"; - - case CURLE_FTP_COULDNT_RETR_FILE: - return "FTP: could not retrieve (RETR failed) the specified file"; - - case CURLE_QUOTE_ERROR: - return "Quote command returned error"; - - case CURLE_HTTP_RETURNED_ERROR: - return "HTTP response code said error"; - - case CURLE_WRITE_ERROR: - return "Failed writing received data to disk/application"; - - case CURLE_UPLOAD_FAILED: - return "Upload failed (at start/before it took off)"; - - case CURLE_READ_ERROR: - return "Failed to open/read local data from file/application"; - - case CURLE_OUT_OF_MEMORY: - return "Out of memory"; - - case CURLE_OPERATION_TIMEDOUT: - return "Timeout was reached"; - - case CURLE_FTP_PORT_FAILED: - return "FTP: command PORT failed"; - - case CURLE_FTP_COULDNT_USE_REST: - return "FTP: command REST failed"; - - case CURLE_RANGE_ERROR: - return "Requested range was not delivered by the server"; - - case CURLE_SSL_CONNECT_ERROR: - return "SSL connect error"; - - case CURLE_BAD_DOWNLOAD_RESUME: - return "Could not resume download"; - - case CURLE_FILE_COULDNT_READ_FILE: - return "Could not read a file:// file"; - - case CURLE_LDAP_CANNOT_BIND: - return "LDAP: cannot bind"; - - case CURLE_LDAP_SEARCH_FAILED: - return "LDAP: search failed"; - - case CURLE_ABORTED_BY_CALLBACK: - return "Operation was aborted by an application callback"; - - case CURLE_BAD_FUNCTION_ARGUMENT: - return "A libcurl function was given a bad argument"; - - case CURLE_INTERFACE_FAILED: - return "Failed binding local connection end"; - - case CURLE_TOO_MANY_REDIRECTS: - return "Number of redirects hit maximum amount"; - - case CURLE_UNKNOWN_OPTION: - return "An unknown option was passed in to libcurl"; - - case CURLE_SETOPT_OPTION_SYNTAX: - return "Malformed option provided in a setopt"; - - case CURLE_GOT_NOTHING: - return "Server returned nothing (no headers, no data)"; - - case CURLE_SSL_ENGINE_NOTFOUND: - return "SSL crypto engine not found"; - - case CURLE_SSL_ENGINE_SETFAILED: - return "Can not set SSL crypto engine as default"; - - case CURLE_SSL_ENGINE_INITFAILED: - return "Failed to initialise SSL crypto engine"; - - case CURLE_SEND_ERROR: - return "Failed sending data to the peer"; - - case CURLE_RECV_ERROR: - return "Failure when receiving data from the peer"; - - case CURLE_SSL_CERTPROBLEM: - return "Problem with the local SSL certificate"; - - case CURLE_SSL_CIPHER: - return "Could not use specified SSL cipher"; - - case CURLE_PEER_FAILED_VERIFICATION: - return "SSL peer certificate or SSH remote key was not OK"; - - case CURLE_SSL_CACERT_BADFILE: - return "Problem with the SSL CA cert (path? access rights?)"; - - case CURLE_BAD_CONTENT_ENCODING: - return "Unrecognized or bad HTTP Content or Transfer-Encoding"; - - case CURLE_FILESIZE_EXCEEDED: - return "Maximum file size exceeded"; - - case CURLE_USE_SSL_FAILED: - return "Requested SSL level failed"; - - case CURLE_SSL_SHUTDOWN_FAILED: - return "Failed to shut down the SSL connection"; - - case CURLE_SSL_CRL_BADFILE: - return "Failed to load CRL file (path? access rights?, format?)"; - - case CURLE_SSL_ISSUER_ERROR: - return "Issuer check against peer certificate failed"; - - case CURLE_SEND_FAIL_REWIND: - return "Send failed since rewinding of the data stream failed"; - - case CURLE_LOGIN_DENIED: - return "Login denied"; - - case CURLE_TFTP_NOTFOUND: - return "TFTP: File Not Found"; - - case CURLE_TFTP_PERM: - return "TFTP: Access Violation"; - - case CURLE_REMOTE_DISK_FULL: - return "Disk full or allocation exceeded"; - - case CURLE_TFTP_ILLEGAL: - return "TFTP: Illegal operation"; - - case CURLE_TFTP_UNKNOWNID: - return "TFTP: Unknown transfer ID"; - - case CURLE_REMOTE_FILE_EXISTS: - return "Remote file already exists"; - - case CURLE_TFTP_NOSUCHUSER: - return "TFTP: No such user"; - - case CURLE_REMOTE_FILE_NOT_FOUND: - return "Remote file not found"; - - case CURLE_SSH: - return "Error in the SSH layer"; - - case CURLE_AGAIN: - return "Socket not ready for send/recv"; - - case CURLE_RTSP_CSEQ_ERROR: - return "RTSP CSeq mismatch or invalid CSeq"; - - case CURLE_RTSP_SESSION_ERROR: - return "RTSP session error"; - - case CURLE_FTP_BAD_FILE_LIST: - return "Unable to parse FTP file list"; - - case CURLE_CHUNK_FAILED: - return "Chunk callback failed"; - - case CURLE_NO_CONNECTION_AVAILABLE: - return "The max connection limit is reached"; - - case CURLE_SSL_PINNEDPUBKEYNOTMATCH: - return "SSL public key does not match pinned public key"; - - case CURLE_SSL_INVALIDCERTSTATUS: - return "SSL server certificate status verification FAILED"; - - case CURLE_HTTP2_STREAM: - return "Stream error in the HTTP/2 framing layer"; - - case CURLE_RECURSIVE_API_CALL: - return "API function called from within callback"; - - case CURLE_AUTH_ERROR: - return "An authentication function returned an error"; - - case CURLE_HTTP3: - return "HTTP/3 error"; - - case CURLE_QUIC_CONNECT_ERROR: - return "QUIC connection error"; - - case CURLE_PROXY: - return "proxy handshake error"; - - case CURLE_SSL_CLIENTCERT: - return "SSL Client Certificate required"; - - case CURLE_UNRECOVERABLE_POLL: - return "Unrecoverable error in select/poll"; - - case CURLE_TOO_LARGE: - return "A value or data field grew larger than allowed"; - - case CURLE_ECH_REQUIRED: - return "ECH attempted but failed"; - - /* error codes not used by current libcurl */ - default: - break; - } - /* - * By using a switch, gcc -Wall will complain about enum values - * which do not appear, helping keep this function up-to-date. - * By using gcc -Wall -Werror, you cannot forget. - * - * A table would not have the same benefit. Most compilers will generate - * code similar to a table in any case, so there is little performance gain - * from a table. Something is broken for the user's application, anyways, so - * does it matter how fast it _does not_ work? - * - * The line number for the error will be near this comment, which is why it - * is here, and not at the start of the switch. - */ - return "Unknown error"; -#else - if(!error) - return "No error"; - else - return "Error"; -#endif -} - -const char *curl_multi_strerror(CURLMcode error) -{ -#ifdef CURLVERBOSE - switch(error) { - case CURLM_CALL_MULTI_PERFORM: - return "Please call curl_multi_perform() soon"; - - case CURLM_OK: - return "No error"; - - case CURLM_BAD_HANDLE: - return "Invalid multi handle"; - - case CURLM_BAD_EASY_HANDLE: - return "Invalid easy handle"; - - case CURLM_OUT_OF_MEMORY: - return "Out of memory"; - - case CURLM_INTERNAL_ERROR: - return "Internal error"; - - case CURLM_BAD_SOCKET: - return "Invalid socket argument"; - - case CURLM_UNKNOWN_OPTION: - return "Unknown option"; - - case CURLM_ADDED_ALREADY: - return "The easy handle is already added to a multi handle"; - - case CURLM_RECURSIVE_API_CALL: - return "API function called from within callback"; - - case CURLM_WAKEUP_FAILURE: - return "Wakeup is unavailable or failed"; - - case CURLM_BAD_FUNCTION_ARGUMENT: - return "A libcurl function was given a bad argument"; - - case CURLM_ABORTED_BY_CALLBACK: - return "Operation was aborted by an application callback"; - - case CURLM_UNRECOVERABLE_POLL: - return "Unrecoverable error in select/poll"; - - case CURLM_LAST: - break; - } - - return "Unknown error"; -#else - if(error == CURLM_OK) - return "No error"; - else - return "Error"; -#endif -} - -const char *curl_share_strerror(CURLSHcode error) -{ -#ifdef CURLVERBOSE - switch(error) { - case CURLSHE_OK: - return "No error"; - - case CURLSHE_BAD_OPTION: - return "Unknown share option"; - - case CURLSHE_IN_USE: - return "Share currently in use"; - - case CURLSHE_INVALID: - return "Invalid share handle"; - - case CURLSHE_NOMEM: - return "Out of memory"; - - case CURLSHE_NOT_BUILT_IN: - return "Feature not enabled in this library"; - - case CURLSHE_LAST: - break; - } - - return "CURLSHcode unknown"; -#else - if(error == CURLSHE_OK) - return "No error"; - else - return "Error"; -#endif -} - -const char *curl_url_strerror(CURLUcode error) -{ -#ifdef CURLVERBOSE - switch(error) { - case CURLUE_OK: - return "No error"; - - case CURLUE_BAD_HANDLE: - return "An invalid CURLU pointer was passed as argument"; - - case CURLUE_BAD_PARTPOINTER: - return "An invalid 'part' argument was passed as argument"; - - case CURLUE_MALFORMED_INPUT: - return "Malformed input to a URL function"; - - case CURLUE_BAD_PORT_NUMBER: - return "Port number was not a decimal number between 0 and 65535"; - - case CURLUE_UNSUPPORTED_SCHEME: - return "Unsupported URL scheme"; - - case CURLUE_URLDECODE: - return "URL decode error, most likely because of rubbish in the input"; - - case CURLUE_OUT_OF_MEMORY: - return "A memory function failed"; - - case CURLUE_USER_NOT_ALLOWED: - return "Credentials was passed in the URL when prohibited"; - - case CURLUE_UNKNOWN_PART: - return "An unknown part ID was passed to a URL API function"; - - case CURLUE_NO_SCHEME: - return "No scheme part in the URL"; - - case CURLUE_NO_USER: - return "No user part in the URL"; - - case CURLUE_NO_PASSWORD: - return "No password part in the URL"; - - case CURLUE_NO_OPTIONS: - return "No options part in the URL"; - - case CURLUE_NO_HOST: - return "No host part in the URL"; - - case CURLUE_NO_PORT: - return "No port part in the URL"; - - case CURLUE_NO_QUERY: - return "No query part in the URL"; - - case CURLUE_NO_FRAGMENT: - return "No fragment part in the URL"; - - case CURLUE_NO_ZONEID: - return "No zoneid part in the URL"; - - case CURLUE_BAD_LOGIN: - return "Bad login part"; - - case CURLUE_BAD_IPV6: - return "Bad IPv6 address"; - - case CURLUE_BAD_HOSTNAME: - return "Bad hostname"; - - case CURLUE_BAD_FILE_URL: - return "Bad file:// URL"; - - case CURLUE_BAD_SLASHES: - return "Unsupported number of slashes following scheme"; - - case CURLUE_BAD_SCHEME: - return "Bad scheme"; - - case CURLUE_BAD_PATH: - return "Bad path"; - - case CURLUE_BAD_FRAGMENT: - return "Bad fragment"; - - case CURLUE_BAD_QUERY: - return "Bad query"; - - case CURLUE_BAD_PASSWORD: - return "Bad password"; - - case CURLUE_BAD_USER: - return "Bad user"; - - case CURLUE_LACKS_IDN: - return "libcurl lacks IDN support"; - - case CURLUE_TOO_LARGE: - return "A value or data field is larger than allowed"; - - case CURLUE_LAST: - break; - } - - return "CURLUcode unknown"; -#else - if(error == CURLUE_OK) - return "No error"; - else - return "Error"; -#endif -} - -#ifdef USE_WINDOWS_SSPI -/* - * Curl_sspi_strerror: - * Variant of curlx_strerror if the error code is definitely Windows SSPI. - */ -const char *Curl_sspi_strerror(SECURITY_STATUS err, char *buf, size_t buflen) -{ -#ifdef _WIN32 - DWORD old_win_err = GetLastError(); -#endif - int old_errno = errno; - VERBOSE(const char *txt); - - if(!buflen) - return NULL; - - *buf = '\0'; - -#ifdef CURLVERBOSE - switch(err) { - case SEC_E_OK: - txt = "No error"; - break; -#define SEC2TXT(sec) case sec: txt = #sec; break - SEC2TXT(CRYPT_E_REVOKED); - SEC2TXT(CRYPT_E_NO_REVOCATION_DLL); - SEC2TXT(CRYPT_E_NO_REVOCATION_CHECK); - SEC2TXT(CRYPT_E_REVOCATION_OFFLINE); - SEC2TXT(CRYPT_E_NOT_IN_REVOCATION_DATABASE); - SEC2TXT(SEC_E_ALGORITHM_MISMATCH); - SEC2TXT(SEC_E_BAD_BINDINGS); - SEC2TXT(SEC_E_BAD_PKGID); - SEC2TXT(SEC_E_BUFFER_TOO_SMALL); - SEC2TXT(SEC_E_CANNOT_INSTALL); - SEC2TXT(SEC_E_CANNOT_PACK); - SEC2TXT(SEC_E_CERT_EXPIRED); - SEC2TXT(SEC_E_CERT_UNKNOWN); - SEC2TXT(SEC_E_CERT_WRONG_USAGE); - SEC2TXT(SEC_E_CONTEXT_EXPIRED); - SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE); - SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID); - SEC2TXT(SEC_E_DECRYPT_FAILURE); - SEC2TXT(SEC_E_DELEGATION_POLICY); - SEC2TXT(SEC_E_DELEGATION_REQUIRED); - SEC2TXT(SEC_E_DOWNGRADE_DETECTED); - SEC2TXT(SEC_E_ENCRYPT_FAILURE); - SEC2TXT(SEC_E_ILLEGAL_MESSAGE); - SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS); - SEC2TXT(SEC_E_INCOMPLETE_MESSAGE); - SEC2TXT(SEC_E_INSUFFICIENT_MEMORY); - SEC2TXT(SEC_E_INTERNAL_ERROR); - SEC2TXT(SEC_E_INVALID_HANDLE); - SEC2TXT(SEC_E_INVALID_PARAMETER); - SEC2TXT(SEC_E_INVALID_TOKEN); - SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED); - SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC); - SEC2TXT(SEC_E_KDC_CERT_EXPIRED); - SEC2TXT(SEC_E_KDC_CERT_REVOKED); - SEC2TXT(SEC_E_KDC_INVALID_REQUEST); - SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER); - SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE); - SEC2TXT(SEC_E_LOGON_DENIED); - SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED); - SEC2TXT(SEC_E_MESSAGE_ALTERED); - SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS); - SEC2TXT(SEC_E_MUST_BE_KDC); - SEC2TXT(SEC_E_NOT_OWNER); - SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY); - SEC2TXT(SEC_E_NO_CREDENTIALS); - SEC2TXT(SEC_E_NO_IMPERSONATION); - SEC2TXT(SEC_E_NO_IP_ADDRESSES); - SEC2TXT(SEC_E_NO_KERB_KEY); - SEC2TXT(SEC_E_NO_PA_DATA); - SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT); - SEC2TXT(SEC_E_NO_TGT_REPLY); - SEC2TXT(SEC_E_OUT_OF_SEQUENCE); - SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE); - SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH); - SEC2TXT(SEC_E_POLICY_NLTM_ONLY); - SEC2TXT(SEC_E_QOP_NOT_SUPPORTED); - SEC2TXT(SEC_E_REVOCATION_OFFLINE_C); - SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC); - SEC2TXT(SEC_E_SECPKG_NOT_FOUND); - SEC2TXT(SEC_E_SECURITY_QOS_FAILED); - SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS); - SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED); - SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED); - SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED); - SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED); - SEC2TXT(SEC_E_TARGET_UNKNOWN); - SEC2TXT(SEC_E_TIME_SKEW); - SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS); - SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED); - SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS); - SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION); - SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH); - SEC2TXT(SEC_E_UNTRUSTED_ROOT); - SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE); - SEC2TXT(SEC_E_WRONG_PRINCIPAL); - SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE); - SEC2TXT(SEC_I_COMPLETE_NEEDED); - SEC2TXT(SEC_I_CONTEXT_EXPIRED); - SEC2TXT(SEC_I_CONTINUE_NEEDED); - SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS); - SEC2TXT(SEC_I_LOCAL_LOGON); - SEC2TXT(SEC_I_NO_LSA_CONTEXT); - SEC2TXT(SEC_I_RENEGOTIATE); - SEC2TXT(SEC_I_SIGNATURE_NEEDED); - default: - txt = "Unknown error"; - } - - if(err == SEC_E_ILLEGAL_MESSAGE) { - curl_msnprintf(buf, buflen, - "SEC_E_ILLEGAL_MESSAGE (0x%08lx) - This error usually " - "occurs when a fatal SSL/TLS alert is received (e.g. " - "handshake failed). More detail may be available in " - "the Windows System event log.", err); - } - else { - char msgbuf[256]; - if(curlx_get_winapi_error((DWORD)err, msgbuf, sizeof(msgbuf))) - curl_msnprintf(buf, buflen, "%s (0x%08lx) - %s", txt, err, msgbuf); - else - curl_msnprintf(buf, buflen, "%s (0x%08lx)", txt, err); - } -#else /* CURLVERBOSE */ - if(err == SEC_E_OK) - curlx_strcopy(buf, buflen, STRCONST("No error")); - else - curlx_strcopy(buf, buflen, STRCONST("Error")); -#endif - - if(errno != old_errno) - errno = old_errno; - -#ifdef _WIN32 - if(old_win_err != GetLastError()) - SetLastError(old_win_err); -#endif - - return buf; -} -#endif /* USE_WINDOWS_SSPI */ diff --git a/vendor/curl/lib/strerror.h b/vendor/curl/lib/strerror.h deleted file mode 100644 index 4b9779ff2..000000000 --- a/vendor/curl/lib/strerror.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef HEADER_CURL_STRERROR_H -#define HEADER_CURL_STRERROR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_WINDOWS_SSPI -const char *Curl_sspi_strerror(SECURITY_STATUS err, char *buf, size_t buflen); -#endif - -#endif /* HEADER_CURL_STRERROR_H */ diff --git a/vendor/curl/lib/system_win32.c b/vendor/curl/lib/system_win32.c deleted file mode 100644 index 1b052357b..000000000 --- a/vendor/curl/lib/system_win32.c +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef _WIN32 - -#include "system_win32.h" -#include "curl_sspi.h" -#include "curlx/timeval.h" -#include "curlx/version_win32.h" /* for curlx_verify_windows_init() */ - -/* Curl_win32_init() performs Win32 global initialization */ -CURLcode Curl_win32_init(long flags) -{ - /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which - is for Winsock at the moment. Any required Win32 initialization - should take place after this block. */ - if(flags & CURL_GLOBAL_WIN32) { -#ifdef USE_WINSOCK - WORD wVersionRequested; - WSADATA wsaData; - int res; - - wVersionRequested = MAKEWORD(2, 2); - res = WSAStartup(wVersionRequested, &wsaData); - - if(res) - /* Tell the user that we could not find a usable */ - /* winsock.dll. */ - return CURLE_FAILED_INIT; - - /* Confirm that the Windows Sockets DLL supports what we need.*/ - /* Note that if the DLL supports versions greater */ - /* than wVersionRequested, it will still return */ - /* wVersionRequested in wVersion. wHighVersion contains the */ - /* highest supported version. */ - - if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) { - /* Tell the user that we could not find a usable */ - - /* winsock.dll. */ - WSACleanup(); - return CURLE_FAILED_INIT; - } - /* The Windows Sockets DLL is acceptable. Proceed. */ -#elif defined(USE_LWIPSOCK) - lwip_init(); -#endif - } /* CURL_GLOBAL_WIN32 */ - -#ifdef USE_WINDOWS_SSPI - { - CURLcode result = Curl_sspi_global_init(); - if(result) - return result; - } -#endif - - curlx_verify_windows_init(); - curlx_now_init(); - return CURLE_OK; -} - -/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ -void Curl_win32_cleanup(long init_flags) -{ -#ifdef USE_WINDOWS_SSPI - Curl_sspi_global_cleanup(); -#endif - - if(init_flags & CURL_GLOBAL_WIN32) { -#ifdef USE_WINSOCK - WSACleanup(); -#endif - } -} - -#endif /* _WIN32 */ diff --git a/vendor/curl/lib/system_win32.h b/vendor/curl/lib/system_win32.h deleted file mode 100644 index 8a51f0967..000000000 --- a/vendor/curl/lib/system_win32.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADER_CURL_SYSTEM_WIN32_H -#define HEADER_CURL_SYSTEM_WIN32_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef _WIN32 -extern LARGE_INTEGER Curl_freq; - -CURLcode Curl_win32_init(long flags); -void Curl_win32_cleanup(long init_flags); -#else -#define Curl_win32_init(x) CURLE_OK -#endif /* _WIN32 */ - -#endif /* HEADER_CURL_SYSTEM_WIN32_H */ diff --git a/vendor/curl/lib/telnet.c b/vendor/curl/lib/telnet.c deleted file mode 100644 index c5ce9c2c9..000000000 --- a/vendor/curl/lib/telnet.c +++ /dev/null @@ -1,1592 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "telnet.h" - -#ifndef CURL_DISABLE_TELNET - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "url.h" -#include "transfer.h" -#include "sendf.h" -#include "curl_trc.h" -#include "progress.h" -#include "arpa_telnet.h" -#include "select.h" -#include "curlx/strparse.h" - -#define SUBBUFSIZE 512 - -#define CURL_SB_CLEAR(x) x->subpointer = (x)->subbuffer -#define CURL_SB_TERM(x) \ - do { \ - (x)->subend = (x)->subpointer; \ - CURL_SB_CLEAR(x); \ - } while(0) -#define CURL_SB_ACCUM(x, c) \ - do { \ - if((x)->subpointer < ((x)->subbuffer + sizeof((x)->subbuffer))) \ - *(x)->subpointer++ = (c); \ - } while(0) - -#define CURL_SB_GET(x) ((*(x)->subpointer++) & 0xff) -#define CURL_SB_LEN(x) ((x)->subend - (x)->subpointer) - -/* For posterity: -#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff) -#define CURL_SB_EOF(x) (x->subpointer >= x->subend) */ - -/* For negotiation compliant to RFC 1143 */ -#define CURL_NO 0 -#define CURL_YES 1 -#define CURL_WANTYES 2 -#define CURL_WANTNO 3 - -#define CURL_EMPTY 0 -#define CURL_OPPOSITE 1 - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_TELNET_EASY "meta:proto:telnet:easy" - -/* - * Telnet receiver states for fsm - */ -typedef enum { - CURL_TS_DATA = 0, - CURL_TS_IAC, - CURL_TS_WILL, - CURL_TS_WONT, - CURL_TS_DO, - CURL_TS_DONT, - CURL_TS_CR, - CURL_TS_SB, /* sub-option collection */ - CURL_TS_SE /* looking for sub-option end */ -} TelnetReceive; - -struct TELNET { - int please_negotiate; - int already_negotiated; - int us[256]; - int usq[256]; - int us_preferred[256]; - int him[256]; - int himq[256]; - int him_preferred[256]; - int subnegotiation[256]; - const char *subopt_ttype; /* Set with suboption TTYPE */ - const char *subopt_xdisploc; /* Set with suboption XDISPLOC */ - unsigned short subopt_wsx; /* Set with suboption NAWS */ - unsigned short subopt_wsy; /* Set with suboption NAWS */ - TelnetReceive telrcv_state; - struct curl_slist *telnet_vars; /* Environment variables */ - struct dynbuf out; /* output buffer */ - - /* suboptions */ - unsigned char subbuffer[SUBBUFSIZE]; - unsigned char *subpointer, *subend; /* buffer for sub-options */ -}; - -#ifndef CURLVERBOSE -#define printoption(a, b, c, d) Curl_nop_stmt -#else -static void printoption(struct Curl_easy *data, - const char *direction, int cmd, int option) -{ - if(data->set.verbose) { - if(cmd == CURL_IAC) { - if(CURL_TELCMD_OK(option)) - infof(data, "%s IAC %s", direction, CURL_TELCMD(option)); - else - infof(data, "%s IAC %d", direction, option); - } - else { - const char *fmt = (cmd == CURL_WILL) ? "WILL" : - (cmd == CURL_WONT) ? "WONT" : - (cmd == CURL_DO) ? "DO" : - (cmd == CURL_DONT) ? "DONT" : 0; - if(fmt) { - const char *opt; - if(CURL_TELOPT_OK(option)) - opt = CURL_TELOPT(option); - else if(option == CURL_TELOPT_EXOPL) - opt = "EXOPL"; - else - opt = NULL; - - if(opt) - infof(data, "%s %s %s", direction, fmt, opt); - else - infof(data, "%s %s %d", direction, fmt, option); - } - else - infof(data, "%s %d %d", direction, cmd, option); - } - } -} -#endif /* !CURLVERBOSE */ - -static void telnet_easy_dtor(void *key, size_t klen, void *entry) -{ - struct TELNET *tn = entry; - (void)key; - (void)klen; - curl_slist_free_all(tn->telnet_vars); - curlx_dyn_free(&tn->out); - curlx_free(tn); -} - -static CURLcode init_telnet(struct Curl_easy *data) -{ - struct TELNET *tn; - - tn = curlx_calloc(1, sizeof(struct TELNET)); - if(!tn) - return CURLE_OUT_OF_MEMORY; - - curlx_dyn_init(&tn->out, 0xffff); - - tn->telrcv_state = CURL_TS_DATA; - - /* Init suboptions */ - CURL_SB_CLEAR(tn); - - /* Set the options we want by default */ - tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES; - tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES; - - /* To be compliant with previous releases of libcurl - we enable this option by default. This behavior - can be changed thanks to the "BINARY" option in - CURLOPT_TELNETOPTIONS - */ - tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES; - tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES; - - /* We must allow the server to echo what we sent - but it is not necessary to request the server - to do so (it might forces the server to close - the connection). Hence, we ignore ECHO in the - negotiate function - */ - tn->him_preferred[CURL_TELOPT_ECHO] = CURL_YES; - - /* Set the subnegotiation fields to send information after negotiation - passed (do/will) - - Default values are (0,0) initialized by calloc. - According to the RFC1013 it is valid: - A value equal to zero is acceptable for the width (or height), - and means that no character width (or height) is being sent. - In this case, the width (or height) that will be assumed by the - Telnet server is operating system specific (it will probably be - based upon the terminal type information that may have been sent - using the TERMINAL TYPE Telnet option). */ - tn->subnegotiation[CURL_TELOPT_NAWS] = CURL_YES; - - return Curl_meta_set(data, CURL_META_TELNET_EASY, tn, telnet_easy_dtor); -} - -static void send_negotiation(struct Curl_easy *data, int cmd, int option) -{ - unsigned char buf[3]; - ssize_t bytes_written; - struct connectdata *conn = data->conn; - - buf[0] = CURL_IAC; - buf[1] = (unsigned char)cmd; - buf[2] = (unsigned char)option; - - bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3); - if(bytes_written < 0) { - int err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - } - - printoption(data, "SENT", cmd, option); -} - -static void set_remote_option(struct Curl_easy *data, struct TELNET *tn, - int option, int newstate) -{ - if(newstate == CURL_YES) { - switch(tn->him[option]) { - case CURL_NO: - tn->him[option] = CURL_WANTYES; - send_negotiation(data, CURL_DO, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Already negotiating for CURL_YES, queue the request */ - tn->himq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - /* Error: already queued an enable request */ - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Error: already negotiating for enable */ - break; - case CURL_OPPOSITE: - tn->himq[option] = CURL_EMPTY; - break; - } - break; - } - } - else { /* NO */ - switch(tn->him[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->him[option] = CURL_WANTNO; - send_negotiation(data, CURL_DONT, option); - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Already negotiating for NO */ - break; - case CURL_OPPOSITE: - tn->himq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->himq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - break; - } - break; - } - } -} - -static void set_local_option(struct Curl_easy *data, struct TELNET *tn, - int option, int newstate) -{ - if(newstate == CURL_YES) { - switch(tn->us[option]) { - case CURL_NO: - tn->us[option] = CURL_WANTYES; - send_negotiation(data, CURL_WILL, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Already negotiating for CURL_YES, queue the request */ - tn->usq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - /* Error: already queued an enable request */ - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Error: already negotiating for enable */ - break; - case CURL_OPPOSITE: - tn->usq[option] = CURL_EMPTY; - break; - } - break; - } - } - else { /* NO */ - switch(tn->us[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->us[option] = CURL_WANTNO; - send_negotiation(data, CURL_WONT, option); - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Already negotiating for NO */ - break; - case CURL_OPPOSITE: - tn->usq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->usq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - break; - } - break; - } - } -} - -static void telnet_negotiate(struct Curl_easy *data, struct TELNET *tn) -{ - int i; - - for(i = 0; i < CURL_NTELOPTS; i++) { - if(i == CURL_TELOPT_ECHO) - continue; - - if(tn->us_preferred[i] == CURL_YES) - set_local_option(data, tn, i, CURL_YES); - - if(tn->him_preferred[i] == CURL_YES) - set_remote_option(data, tn, i, CURL_YES); - } -} - -static void rec_will(struct Curl_easy *data, struct TELNET *tn, int option) -{ - switch(tn->him[option]) { - case CURL_NO: - if(tn->him_preferred[option] == CURL_YES) { - tn->him[option] = CURL_YES; - send_negotiation(data, CURL_DO, option); - } - else - send_negotiation(data, CURL_DONT, option); - - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Error: DONT answered by WILL */ - tn->him[option] = CURL_NO; - break; - case CURL_OPPOSITE: - /* Error: DONT answered by WILL */ - tn->him[option] = CURL_YES; - tn->himq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->him[option] = CURL_YES; - break; - case CURL_OPPOSITE: - tn->him[option] = CURL_WANTNO; - tn->himq[option] = CURL_EMPTY; - send_negotiation(data, CURL_DONT, option); - break; - } - break; - } -} - -static void rec_wont(struct Curl_easy *data, struct TELNET *tn, int option) -{ - switch(tn->him[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->him[option] = CURL_NO; - send_negotiation(data, CURL_DONT, option); - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->him[option] = CURL_NO; - break; - - case CURL_OPPOSITE: - tn->him[option] = CURL_WANTYES; - tn->himq[option] = CURL_EMPTY; - send_negotiation(data, CURL_DO, option); - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->him[option] = CURL_NO; - break; - case CURL_OPPOSITE: - tn->him[option] = CURL_NO; - tn->himq[option] = CURL_EMPTY; - break; - } - break; - } -} - -static void printsub(struct Curl_easy *data, - int direction, /* '<' or '>' */ - const unsigned char *pointer, /* ptr to suboption data */ - size_t length) /* suboption data length */ -{ - if(data->set.verbose) { - unsigned int i = 0; - if(direction) { - infof(data, "%s IAC SB ", (direction == '<') ? "RCVD" : "SENT"); - if(length >= 3) { - int j; - - i = pointer[length - 2]; - j = pointer[length - 1]; - - if(i != CURL_IAC || j != CURL_SE) { - infof(data, "(terminated by "); - if(CURL_TELOPT_OK(i)) - infof(data, "%s ", CURL_TELOPT(i)); - else if(CURL_TELCMD_OK(i)) - infof(data, "%s ", CURL_TELCMD(i)); - else - infof(data, "%u ", i); - if(CURL_TELOPT_OK(j)) - infof(data, "%s", CURL_TELOPT(j)); - else if(CURL_TELCMD_OK(j)) - infof(data, "%s", CURL_TELCMD(j)); - else - infof(data, "%d", j); - infof(data, ", not IAC SE) "); - } - } - if(length >= 2) - length -= 2; - else /* bad input */ - return; - } - if(length <= 1) { - infof(data, "(Empty suboption?)"); - return; - } - - if(CURL_TELOPT_OK(pointer[0])) { - switch(pointer[0]) { - case CURL_TELOPT_TTYPE: - case CURL_TELOPT_XDISPLOC: - case CURL_TELOPT_NEW_ENVIRON: - case CURL_TELOPT_NAWS: - infof(data, "%s", CURL_TELOPT(pointer[0])); - break; - default: - infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0])); - break; - } - } - else - infof(data, "%d (unknown)", pointer[0]); - - switch(pointer[0]) { - case CURL_TELOPT_NAWS: - if(length > 4) - infof(data, "Width: %d ; Height: %d", (pointer[1] << 8) | pointer[2], - (pointer[3] << 8) | pointer[4]); - break; - default: - switch(pointer[1]) { - case CURL_TELQUAL_IS: - infof(data, " IS"); - break; - case CURL_TELQUAL_SEND: - infof(data, " SEND"); - break; - case CURL_TELQUAL_INFO: - infof(data, " INFO/REPLY"); - break; - case CURL_TELQUAL_NAME: - infof(data, " NAME"); - break; - } - - switch(pointer[0]) { - case CURL_TELOPT_TTYPE: - case CURL_TELOPT_XDISPLOC: - infof(data, " \"%.*s\"", - (int)((length > 2) ? (length - 2) : 0), &pointer[2]); - break; - case CURL_TELOPT_NEW_ENVIRON: - if(pointer[1] == CURL_TELQUAL_IS) { - infof(data, " "); - for(i = 3; i < length; i++) { - switch(pointer[i]) { - case CURL_NEW_ENV_VAR: - infof(data, ", "); - break; - case CURL_NEW_ENV_VALUE: - infof(data, " = "); - break; - default: - infof(data, "%c", pointer[i]); - break; - } - } - } - break; - default: - for(i = 2; i < length; i++) - infof(data, " %.2x", pointer[i]); - break; - } - } - } -} - -/* Escape and send a telnet data block */ -static CURLcode send_telnet_data(struct Curl_easy *data, - struct TELNET *tn, - const char *buffer, ssize_t nread) -{ - size_t i, outlen; - const unsigned char *outbuf; - CURLcode result = CURLE_OK; - size_t bytes_written; - size_t total_written = 0; - struct connectdata *conn = data->conn; - - DEBUGASSERT(tn); - DEBUGASSERT(nread > 0); - if(nread < 0) - return CURLE_TOO_LARGE; - - if(memchr(buffer, CURL_IAC, nread)) { - /* only use the escape buffer when necessary */ - curlx_dyn_reset(&tn->out); - - for(i = 0; i < (size_t)nread && !result; i++) { - result = curlx_dyn_addn(&tn->out, &buffer[i], 1); - if(!result && ((unsigned char)buffer[i] == CURL_IAC)) - /* IAC is FF in hex */ - result = curlx_dyn_addn(&tn->out, "\xff", 1); - } - - outlen = curlx_dyn_len(&tn->out); - outbuf = curlx_dyn_uptr(&tn->out); - } - else { - outlen = (size_t)nread; - outbuf = (const unsigned char *)buffer; - } - while(!result && total_written < outlen) { - /* Make sure socket is writable to avoid EWOULDBLOCK condition */ - struct pollfd pfd[1]; - pfd[0].fd = conn->sock[FIRSTSOCKET]; - pfd[0].events = POLLOUT; - switch(Curl_poll(pfd, 1, -1)) { - case -1: /* error, abort writing */ - case 0: /* timeout (will never happen) */ - result = CURLE_SEND_ERROR; - break; - default: /* write! */ - bytes_written = 0; - result = Curl_xfer_send(data, outbuf + total_written, - outlen - total_written, FALSE, &bytes_written); - total_written += bytes_written; - break; - } - } - - return result; -} - -/* - * sendsuboption() - * - * Send suboption information to the server side. - */ -static void sendsuboption(struct Curl_easy *data, - struct TELNET *tn, int option) -{ - ssize_t bytes_written; - int err; - unsigned short x, y; - const unsigned char *uc1, *uc2; - struct connectdata *conn = data->conn; - - switch(option) { - case CURL_TELOPT_NAWS: - /* We prepare data to be sent */ - CURL_SB_CLEAR(tn); - CURL_SB_ACCUM(tn, CURL_IAC); - CURL_SB_ACCUM(tn, CURL_SB); - CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS); - /* We must deal either with little or big endian processors */ - /* Window size must be sent according to the 'network order' */ - x = htons(tn->subopt_wsx); - y = htons(tn->subopt_wsy); - uc1 = (const unsigned char *)&x; - uc2 = (const unsigned char *)&y; - CURL_SB_ACCUM(tn, uc1[0]); - CURL_SB_ACCUM(tn, uc1[1]); - CURL_SB_ACCUM(tn, uc2[0]); - CURL_SB_ACCUM(tn, uc2[1]); - - CURL_SB_ACCUM(tn, CURL_IAC); - CURL_SB_ACCUM(tn, CURL_SE); - CURL_SB_TERM(tn); - /* data suboption is now ready */ - - printsub(data, '>', (const unsigned char *)tn->subbuffer + 2, - CURL_SB_LEN(tn) - 2); - - /* we send the header of the suboption... */ - bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - } - /* ... then the window size with the send_telnet_data() function - to deal with 0xFF cases ... */ - send_telnet_data(data, tn, (const char *)tn->subbuffer + 3, 4); - /* ... and the footer */ - bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer + 7, 2); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - } - break; - } -} - -static void rec_do(struct Curl_easy *data, struct TELNET *tn, int option) -{ - switch(tn->us[option]) { - case CURL_NO: - if(tn->us_preferred[option] == CURL_YES) { - tn->us[option] = CURL_YES; - send_negotiation(data, CURL_WILL, option); - if(tn->subnegotiation[option] == CURL_YES) - /* transmission of data option */ - sendsuboption(data, tn, option); - } - else if(tn->subnegotiation[option] == CURL_YES) { - /* send information to achieve this option */ - tn->us[option] = CURL_YES; - send_negotiation(data, CURL_WILL, option); - sendsuboption(data, tn, option); - } - else - send_negotiation(data, CURL_WONT, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Error: DONT answered by WILL */ - tn->us[option] = CURL_NO; - break; - case CURL_OPPOSITE: - /* Error: DONT answered by WILL */ - tn->us[option] = CURL_YES; - tn->usq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->us[option] = CURL_YES; - if(tn->subnegotiation[option] == CURL_YES) { - /* transmission of data option */ - sendsuboption(data, tn, option); - } - break; - case CURL_OPPOSITE: - tn->us[option] = CURL_WANTNO; - tn->himq[option] = CURL_EMPTY; - send_negotiation(data, CURL_WONT, option); - break; - } - break; - } -} - -static void rec_dont(struct Curl_easy *data, struct TELNET *tn, int option) -{ - switch(tn->us[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->us[option] = CURL_NO; - send_negotiation(data, CURL_WONT, option); - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->us[option] = CURL_NO; - break; - - case CURL_OPPOSITE: - tn->us[option] = CURL_WANTYES; - tn->usq[option] = CURL_EMPTY; - send_negotiation(data, CURL_WILL, option); - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->us[option] = CURL_NO; - break; - case CURL_OPPOSITE: - tn->us[option] = CURL_NO; - tn->usq[option] = CURL_EMPTY; - break; - } - break; - } -} - -static bool str_is_nonascii(const char *str) -{ - char c; - while((c = *str++) != 0) - if(c & 0x80) - return TRUE; - - return FALSE; -} - -static CURLcode check_telnet_options(struct Curl_easy *data, - struct TELNET *tn) -{ - struct curl_slist *head; - struct curl_slist *beg; - CURLcode result = CURLE_OK; - - /* Add the username as an environment variable if it - was given on the command line */ - if(data->state.aptr.user) { - char buffer[256]; - if(str_is_nonascii(data->conn->user)) { - DEBUGF(infof(data, "set a non ASCII username in telnet")); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - curl_msnprintf(buffer, sizeof(buffer), "USER,%s", data->conn->user); - beg = curl_slist_append(tn->telnet_vars, buffer); - if(!beg) { - curl_slist_free_all(tn->telnet_vars); - tn->telnet_vars = NULL; - return CURLE_OUT_OF_MEMORY; - } - tn->telnet_vars = beg; - tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; - } - - for(head = data->set.telnet_options; head && !result; head = head->next) { - size_t olen; - const char *option = head->data; - const char *arg; - const char *sep = strchr(option, '='); - if(sep) { - olen = sep - option; - arg = ++sep; - if(str_is_nonascii(arg)) - continue; - switch(olen) { - case 5: - /* Terminal type */ - if(curl_strnequal(option, "TTYPE", 5)) { - tn->subopt_ttype = arg; - tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; - break; - } - result = CURLE_UNKNOWN_OPTION; - break; - - case 8: - /* Display variable */ - if(curl_strnequal(option, "XDISPLOC", 8)) { - tn->subopt_xdisploc = arg; - tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; - break; - } - result = CURLE_UNKNOWN_OPTION; - break; - - case 7: - /* Environment variable */ - if(curl_strnequal(option, "NEW_ENV", 7)) { - beg = curl_slist_append(tn->telnet_vars, arg); - if(!beg) { - result = CURLE_OUT_OF_MEMORY; - break; - } - tn->telnet_vars = beg; - tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; - } - else - result = CURLE_UNKNOWN_OPTION; - break; - - case 2: - /* Window Size */ - if(curl_strnequal(option, "WS", 2)) { - const char *p = arg; - curl_off_t x = 0; - curl_off_t y = 0; - if(curlx_str_number(&p, &x, 0xffff) || - curlx_str_single(&p, 'x') || - curlx_str_number(&p, &y, 0xffff)) { - failf(data, "Syntax error in telnet option: %s", head->data); - result = CURLE_SETOPT_OPTION_SYNTAX; - } - else { - tn->subopt_wsx = (unsigned short)x; - tn->subopt_wsy = (unsigned short)y; - tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES; - } - } - else - result = CURLE_UNKNOWN_OPTION; - break; - - case 6: - /* To take care or not of the 8th bit in data exchange */ - if(curl_strnequal(option, "BINARY", 6)) { - const char *p = arg; - curl_off_t binary_option; - if(!curlx_str_number(&p, &binary_option, 1) && - (binary_option != 1)) { - tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO; - tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO; - } - } - else - result = CURLE_UNKNOWN_OPTION; - break; - default: - failf(data, "Unknown telnet option %s", head->data); - result = CURLE_UNKNOWN_OPTION; - break; - } - } - else { - failf(data, "Syntax error in telnet option: %s", head->data); - result = CURLE_SETOPT_OPTION_SYNTAX; - } - } - - if(result) { - curl_slist_free_all(tn->telnet_vars); - tn->telnet_vars = NULL; - } - - return result; -} - -/* if the option contains an IAC code, it should be escaped in the output, but - as we cannot think of any legit way to send that as part of the content we - rather ban its use instead */ -static bool bad_option(const char *data) -{ - return !data || !!strchr(data, CURL_IAC); -} - -/* - * suboption() - * - * Look at the sub-option buffer, and try to be helpful to the other - * side. - */ -static CURLcode suboption(struct Curl_easy *data, struct TELNET *tn) -{ - struct curl_slist *v; - unsigned char temp[2048]; - ssize_t bytes_written; - size_t len; - int err; - struct connectdata *conn = data->conn; - - if(!CURL_SB_LEN(tn)) /* ignore empty suboption */ - return CURLE_OK; - - printsub(data, '<', (const unsigned char *)tn->subbuffer, - CURL_SB_LEN(tn) + 2); - switch(CURL_SB_GET(tn)) { - case CURL_TELOPT_TTYPE: - if(bad_option(tn->subopt_ttype)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(strlen(tn->subopt_ttype) > 1000) { - failf(data, "Tool long telnet TTYPE"); - return CURLE_SEND_ERROR; - } - len = curl_msnprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c", - CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE, - CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, - CURL_SE); - bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); - - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - return CURLE_SEND_ERROR; - } - printsub(data, '>', &temp[2], len-2); - break; - case CURL_TELOPT_XDISPLOC: - if(bad_option(tn->subopt_xdisploc)) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(strlen(tn->subopt_xdisploc) > 1000) { - failf(data, "Tool long telnet XDISPLOC"); - return CURLE_SEND_ERROR; - } - len = curl_msnprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c", - CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC, - CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, - CURL_SE); - bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - return CURLE_SEND_ERROR; - } - printsub(data, '>', &temp[2], len - 2); - break; - case CURL_TELOPT_NEW_ENVIRON: - len = curl_msnprintf((char *)temp, sizeof(temp), "%c%c%c%c", - CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON, - CURL_TELQUAL_IS); - for(v = tn->telnet_vars; v; v = v->next) { - size_t tmplen = (strlen(v->data) + 1); - if(bad_option(v->data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - /* Add the variable if it fits */ - if(len + tmplen < (int)sizeof(temp) - 6) { - const char *s = strchr(v->data, ','); - if(!s) - len += curl_msnprintf((char *)&temp[len], sizeof(temp) - len, - "%c%s", CURL_NEW_ENV_VAR, v->data); - else { - size_t vlen = s - v->data; - len += curl_msnprintf((char *)&temp[len], sizeof(temp) - len, - "%c%.*s%c%s", CURL_NEW_ENV_VAR, - (int)vlen, v->data, CURL_NEW_ENV_VALUE, ++s); - } - } - } - curl_msnprintf((char *)&temp[len], sizeof(temp) - len, - "%c%c", CURL_IAC, CURL_SE); - len += 2; - bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - } - printsub(data, '>', &temp[2], len - 2); - break; - } - return CURLE_OK; -} - -static CURLcode telrcv(struct Curl_easy *data, - struct TELNET *tn, - const unsigned char *inbuf, /* Data received from - socket */ - ssize_t count) /* Number of bytes - received */ -{ - unsigned char c; - CURLcode result; - int in = 0; - int startwrite = -1; - -#define startskipping() \ - if(startwrite >= 0) { \ - result = Curl_client_write(data, \ - CLIENTWRITE_BODY, \ - (const char *)&inbuf[startwrite], \ - in-startwrite); \ - if(result) \ - return result; \ - } \ - startwrite = -1 - -#define writebyte() \ - if(startwrite < 0) \ - startwrite = in - -#define bufferflush() startskipping() - - while(count--) { - c = inbuf[in]; - - switch(tn->telrcv_state) { - case CURL_TS_CR: - tn->telrcv_state = CURL_TS_DATA; - if(c == '\0') { - startskipping(); - break; /* Ignore \0 after CR */ - } - writebyte(); - break; - - case CURL_TS_DATA: - if(c == CURL_IAC) { - tn->telrcv_state = CURL_TS_IAC; - startskipping(); - break; - } - else if(c == '\r') - tn->telrcv_state = CURL_TS_CR; - writebyte(); - break; - - case CURL_TS_IAC: - DEBUGASSERT(startwrite < 0); - switch(c) { - case CURL_WILL: - tn->telrcv_state = CURL_TS_WILL; - break; - case CURL_WONT: - tn->telrcv_state = CURL_TS_WONT; - break; - case CURL_DO: - tn->telrcv_state = CURL_TS_DO; - break; - case CURL_DONT: - tn->telrcv_state = CURL_TS_DONT; - break; - case CURL_SB: - CURL_SB_CLEAR(tn); - tn->telrcv_state = CURL_TS_SB; - break; - case CURL_IAC: - tn->telrcv_state = CURL_TS_DATA; - writebyte(); - break; - case CURL_DM: - case CURL_NOP: - case CURL_GA: - default: - tn->telrcv_state = CURL_TS_DATA; - printoption(data, "RCVD", CURL_IAC, c); - break; - } - break; - - case CURL_TS_WILL: - printoption(data, "RCVD", CURL_WILL, c); - tn->please_negotiate = 1; - rec_will(data, tn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_WONT: - printoption(data, "RCVD", CURL_WONT, c); - tn->please_negotiate = 1; - rec_wont(data, tn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_DO: - printoption(data, "RCVD", CURL_DO, c); - tn->please_negotiate = 1; - rec_do(data, tn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_DONT: - printoption(data, "RCVD", CURL_DONT, c); - tn->please_negotiate = 1; - rec_dont(data, tn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_SB: - if(c == CURL_IAC) - tn->telrcv_state = CURL_TS_SE; - else - CURL_SB_ACCUM(tn, c); - break; - - case CURL_TS_SE: - if(c != CURL_SE) { - if(c != CURL_IAC) { - /* - * This is an error. We only expect to get "IAC IAC" or "IAC SE". - * Several things may have happened. An IAC was not doubled, the IAC - * SE was left off, or another option got inserted into the - * suboption are all possibilities. - */ - failf(data, "telnet: suboption error"); - return CURLE_RECV_ERROR; - } - CURL_SB_ACCUM(tn, c); - tn->telrcv_state = CURL_TS_SB; - } - else { - CURL_SB_ACCUM(tn, CURL_IAC); - CURL_SB_ACCUM(tn, CURL_SE); - tn->subpointer -= 2; - CURL_SB_TERM(tn); - result = suboption(data, tn); /* handle sub-option */ - if(result) - return result; - tn->telrcv_state = CURL_TS_DATA; - } - break; - } - ++in; - } - bufferflush(); - return CURLE_OK; -} - -static CURLcode telnet_done(struct Curl_easy *data, - CURLcode status, bool premature) -{ - (void)status; - (void)premature; - Curl_meta_remove(data, CURL_META_TELNET_EASY); - return CURLE_OK; -} - -static CURLcode telnet_do(struct Curl_easy *data, bool *done) -{ - CURLcode result; - struct connectdata *conn = data->conn; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; -#ifdef USE_WINSOCK - WSAEVENT event_handle; - WSANETWORKEVENTS events; - HANDLE stdin_handle; - HANDLE objs[2]; - DWORD obj_count; - DWORD wait_timeout; - DWORD readfile_read; - int err; -#else - timediff_t interval_ms; - struct pollfd pfd[2]; - int poll_cnt; - ssize_t snread; -#endif - bool keepon = TRUE; - char buffer[4 * 1024]; - struct TELNET *tn; - - *done = TRUE; /* unconditionally */ - - result = init_telnet(data); - if(result) - return result; - - tn = Curl_meta_get(data, CURL_META_TELNET_EASY); - if(!tn) - return CURLE_FAILED_INIT; - - result = check_telnet_options(data, tn); - if(result) - return result; - -#ifdef USE_WINSOCK - /* We want to wait for both stdin and the socket. Since - * the select() function in Winsock only works on sockets - * we have to use the WaitForMultipleObjects() call. - */ - - /* First, create a sockets event object */ - event_handle = WSACreateEvent(); - if(event_handle == WSA_INVALID_EVENT) { - failf(data, "WSACreateEvent failed (%d)", SOCKERRNO); - return CURLE_FAILED_INIT; - } - - /* Tell Winsock what events we want to listen to */ - if(WSAEventSelect(sockfd, event_handle, FD_READ | FD_CLOSE) != 0) { - WSACloseEvent(event_handle); - return CURLE_RECV_ERROR; - } - - /* The get the Windows file handle for stdin */ - stdin_handle = GetStdHandle(STD_INPUT_HANDLE); - - /* Create the list of objects to wait for */ - objs[0] = event_handle; - objs[1] = stdin_handle; - - /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it, - else use the old WaitForMultipleObjects() way */ - if(GetFileType(stdin_handle) == FILE_TYPE_PIPE || data->set.is_fread_set) { - /* Do not wait for stdin_handle, wait for event_handle */ - obj_count = 1; - /* Check stdin_handle per 100 milliseconds */ - wait_timeout = 100; - } - else { - obj_count = 2; - wait_timeout = 1000; - } - - /* Keep on listening and act on events */ - while(keepon) { - const DWORD buf_size = (DWORD)sizeof(buffer); - DWORD waitret = WaitForMultipleObjects(obj_count, objs, - FALSE, wait_timeout); - switch(waitret) { - - case WAIT_TIMEOUT: { - for(;;) { - if(data->set.is_fread_set) { - size_t n; - /* read from user-supplied method */ - n = data->state.fread_func(buffer, 1, buf_size, data->state.in); - if(n == CURL_READFUNC_ABORT) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - - if(n == CURL_READFUNC_PAUSE) - break; - - if(n == 0) /* no bytes */ - break; - - /* fall through with number of bytes read */ - readfile_read = (DWORD)n; - } - else { - /* read from stdin */ - if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, - &readfile_read, NULL)) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - - if(!readfile_read) - break; - - if(!ReadFile(stdin_handle, buffer, buf_size, &readfile_read, NULL)) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - } - - result = send_telnet_data(data, tn, buffer, readfile_read); - if(result) { - keepon = FALSE; - break; - } - } - } - break; - - case WAIT_OBJECT_0 + 1: { - if(!ReadFile(stdin_handle, buffer, buf_size, &readfile_read, NULL)) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - - result = send_telnet_data(data, tn, buffer, readfile_read); - if(result) { - keepon = FALSE; - break; - } - } - break; - - case WAIT_OBJECT_0: { - events.lNetworkEvents = 0; - if(WSAEnumNetworkEvents(sockfd, event_handle, &events) != 0) { - err = SOCKERRNO; - if(err != SOCKEINPROGRESS) { - infof(data, "WSAEnumNetworkEvents failed (%d)", err); - keepon = FALSE; - result = CURLE_READ_ERROR; - } - break; - } - if(events.lNetworkEvents & FD_READ) { - /* read data from network */ - size_t nread; - result = Curl_xfer_recv(data, buffer, sizeof(buffer), &nread); - /* read would have blocked. Loop again */ - if(result == CURLE_AGAIN) - break; - /* returned not-zero, this an error */ - else if(result) { - keepon = FALSE; - break; - } - /* returned zero but actually received 0 or less here, - the server closed the connection and we bail out */ - else if(!nread) { - keepon = FALSE; - break; - } - - result = telrcv(data, tn, (unsigned char *)buffer, nread); - if(result) { - keepon = FALSE; - break; - } - - /* Negotiate if the peer has started negotiating, - otherwise do not. We do not want to speak telnet with - non-telnet servers, like POP or SMTP. */ - if(tn->please_negotiate && !tn->already_negotiated) { - telnet_negotiate(data, tn); - tn->already_negotiated = 1; - } - } - if(events.lNetworkEvents & FD_CLOSE) { - keepon = FALSE; - } - break; - } - } /* switch */ - - if(data->set.timeout) { - if(curlx_ptimediff_ms(Curl_pgrs_now(data), &conn->created) >= - data->set.timeout) { - failf(data, "Time-out"); - result = CURLE_OPERATION_TIMEDOUT; - keepon = FALSE; - } - } - } - - /* We called WSACreateEvent, so call WSACloseEvent */ - if(!WSACloseEvent(event_handle)) { - infof(data, "WSACloseEvent failed (%d)", SOCKERRNO); - } -#else - pfd[0].fd = sockfd; - pfd[0].events = POLLIN; - - if(data->set.is_fread_set) { - poll_cnt = 1; - interval_ms = 100; /* poll user-supplied read function */ - } - else { - /* really using fread, so infile is a FILE* */ - pfd[1].fd = fileno((FILE *)data->state.in); - pfd[1].events = POLLIN; - poll_cnt = 2; - interval_ms = 1 * 1000; - if(pfd[1].fd < 0) { - failf(data, "cannot read input"); - result = CURLE_RECV_ERROR; - keepon = FALSE; - } - } - - while(keepon) { - DEBUGF(infof(data, "telnet_do, poll %d fds", poll_cnt)); - switch(Curl_poll(pfd, (unsigned int)poll_cnt, interval_ms)) { - case -1: /* error, stop reading */ - keepon = FALSE; - continue; - case 0: /* timeout */ - pfd[0].revents = 0; - pfd[1].revents = 0; - FALLTHROUGH(); - default: /* read! */ - if(pfd[0].revents & POLLIN) { - /* read data from network */ - size_t nread; - result = Curl_xfer_recv(data, buffer, sizeof(buffer), &nread); - /* read would have blocked. Loop again */ - if(result == CURLE_AGAIN) - break; - /* returned not-zero, this an error */ - if(result) { - keepon = FALSE; - /* In test 1452, macOS sees a ECONNRESET sometimes? Is this the - * telnet test server not shutting down the socket in a clean way? - * Seems to be timing related, happens more on slow debug build */ - if(data->state.os_errno == SOCKECONNRESET) { - DEBUGF(infof(data, "telnet_do, unexpected ECONNRESET on recv")); - } - break; - } - /* returned zero but actually received 0 or less here, - the server closed the connection and we bail out */ - else if(!nread) { - keepon = FALSE; - break; - } - - Curl_pgrs_download_inc(data, nread); - result = telrcv(data, tn, (unsigned char *)buffer, nread); - if(result) { - keepon = FALSE; - break; - } - - /* Negotiate if the peer has started negotiating, - otherwise do not. We do not want to speak telnet with - non-telnet servers, like POP or SMTP. */ - if(tn->please_negotiate && !tn->already_negotiated) { - telnet_negotiate(data, tn); - tn->already_negotiated = 1; - } - } - - snread = 0; - if(poll_cnt == 2) { - if(pfd[1].revents & POLLIN) { /* read from in file */ - snread = read(pfd[1].fd, buffer, sizeof(buffer)); - } - } - else { - /* read from user-supplied method */ - snread = (int)data->state.fread_func(buffer, 1, sizeof(buffer), - data->state.in); - if(snread == CURL_READFUNC_ABORT) { - keepon = FALSE; - break; - } - if(snread == CURL_READFUNC_PAUSE) - break; - } - - if(snread > 0) { - result = send_telnet_data(data, tn, buffer, snread); - if(result) { - keepon = FALSE; - break; - } - Curl_pgrs_upload_inc(data, (size_t)snread); - } - else if(snread < 0) - keepon = FALSE; - - break; - } /* poll switch statement */ - - if(data->set.timeout) { - if(curlx_ptimediff_ms(Curl_pgrs_now(data), &conn->created) >= - data->set.timeout) { - failf(data, "Time-out"); - result = CURLE_OPERATION_TIMEDOUT; - keepon = FALSE; - } - } - - if(!result) { - result = Curl_pgrsUpdate(data); - if(result) - keepon = FALSE; - } - } -#endif - /* mark this as "no further transfer wanted" */ - Curl_xfer_setup_nop(data); - - return result; -} - -/* - * TELNET protocol handler. - */ -const struct Curl_protocol Curl_protocol_telnet = { - ZERO_NULL, /* setup_connection */ - telnet_do, /* do_it */ - telnet_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - ZERO_NULL, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* !CURL_DISABLE_TELNET */ diff --git a/vendor/curl/lib/telnet.h b/vendor/curl/lib/telnet.h deleted file mode 100644 index 3848fff3b..000000000 --- a/vendor/curl/lib/telnet.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef HEADER_CURL_TELNET_H -#define HEADER_CURL_TELNET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_TELNET -extern const struct Curl_protocol Curl_protocol_telnet; -#endif - -#endif /* HEADER_CURL_TELNET_H */ diff --git a/vendor/curl/lib/tftp.c b/vendor/curl/lib/tftp.c deleted file mode 100644 index 6cc672d44..000000000 --- a/vendor/curl/lib/tftp.c +++ /dev/null @@ -1,1355 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "tftp.h" - -#ifndef CURL_DISABLE_TFTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "cfilters.h" -#include "cf-socket.h" -#include "transfer.h" -#include "sendf.h" -#include "curl_trc.h" -#include "progress.h" -#include "connect.h" -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "url.h" -#include "strcase.h" -#include "select.h" -#include "escape.h" -#include "curlx/strerr.h" -#include "curlx/strparse.h" -#include "curlx/strcopy.h" - -/* RFC2348 allows the block size to be negotiated */ -#define TFTP_BLKSIZE_DEFAULT 512 -#define TFTP_OPTION_BLKSIZE "blksize" - -/* from RFC2349: */ -#define TFTP_OPTION_TSIZE "tsize" -#define TFTP_OPTION_INTERVAL "timeout" - -typedef enum { - TFTP_MODE_NETASCII = 0, - TFTP_MODE_OCTET -} tftp_mode_t; - -typedef enum { - TFTP_STATE_START = 0, - TFTP_STATE_RX, - TFTP_STATE_TX, - TFTP_STATE_FIN -} tftp_state_t; - -typedef enum { - TFTP_EVENT_NONE = -1, - TFTP_EVENT_INIT = 0, - TFTP_EVENT_RRQ = 1, - TFTP_EVENT_WRQ = 2, - TFTP_EVENT_DATA = 3, - TFTP_EVENT_ACK = 4, - TFTP_EVENT_ERROR = 5, - TFTP_EVENT_OACK = 6, - TFTP_EVENT_TIMEOUT -} tftp_event_t; - -typedef enum { - TFTP_ERR_UNDEF = 0, - TFTP_ERR_NOTFOUND, - TFTP_ERR_PERM, - TFTP_ERR_DISKFULL, - TFTP_ERR_ILLEGAL, - TFTP_ERR_UNKNOWNID, - TFTP_ERR_EXISTS, - TFTP_ERR_NOSUCHUSER, /* This will never be triggered by this code */ - - /* The remaining error codes are internal to curl */ - TFTP_ERR_NONE = -100, - TFTP_ERR_TIMEOUT, - TFTP_ERR_NORESPONSE -} tftp_error_t; - -struct tftp_packet { - unsigned char *data; -}; - -/* meta key for storing protocol meta at connection */ -#define CURL_META_TFTP_CONN "meta:proto:tftp:conn" - -struct tftp_conn { - struct Curl_sockaddr_storage local_addr; - struct Curl_sockaddr_storage remote_addr; - struct tftp_packet rpacket; - struct tftp_packet spacket; - tftp_state_t state; - tftp_mode_t mode; - tftp_error_t error; - tftp_event_t event; - struct Curl_easy *data; - curl_socket_t sockfd; - int retries; - int retry_time; - int retry_max; - time_t rx_time; - curl_socklen_t remote_addrlen; - int rbytes; - size_t sbytes; - unsigned int blksize; - unsigned int requested_blksize; - unsigned short block; - BIT(remote_pinned); -}; - -/********************************************************** - * - * tftp_set_timeouts - - * - * Set timeouts based on state machine state. - * Use user provided connect timeouts until DATA or ACK - * packet is received, then use user-provided transfer timeouts - * - * - **********************************************************/ -static CURLcode tftp_set_timeouts(struct tftp_conn *state) -{ - time_t timeout; - timediff_t timeout_ms; - - /* Compute drop-dead time */ - timeout_ms = Curl_timeleft_ms(state->data); - - if(timeout_ms < 0) { - /* time-out, bail out, go home */ - failf(state->data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* Set per-block timeout to total */ - if(timeout_ms > 0) - timeout = (time_t)(timeout_ms + 500) / 1000; - else - timeout = 15; - - /* Average reposting an ACK after 5 seconds */ - state->retry_max = (int)timeout / 5; - - /* Bound the total number */ - if(state->retry_max < 3) - state->retry_max = 3; - - if(state->retry_max > 50) - state->retry_max = 50; - - /* Compute the re-ACK interval to suit the timeout */ - state->retry_time = (int)(timeout / state->retry_max); - if(state->retry_time < 1) - state->retry_time = 1; - - infof(state->data, - "set timeouts for state %d; Total %" FMT_OFF_T ", retry %d maxtry %d", - (int)state->state, timeout_ms, state->retry_time, state->retry_max); - - /* init RX time */ - state->rx_time = time(NULL); - - return CURLE_OK; -} - -/********************************************************** - * - * tftp_set_send_first - * - * Event handler for the START state - * - **********************************************************/ - -static void setpacketevent(struct tftp_packet *packet, unsigned short num) -{ - packet->data[0] = (unsigned char)(num >> 8); - packet->data[1] = (unsigned char)(num & 0xff); -} - -static void setpacketblock(struct tftp_packet *packet, unsigned short num) -{ - packet->data[2] = (unsigned char)(num >> 8); - packet->data[3] = (unsigned char)(num & 0xff); -} - -static unsigned short getrpacketevent(const struct tftp_packet *packet) -{ - return (unsigned short)((packet->data[0] << 8) | packet->data[1]); -} - -static unsigned short getrpacketblock(const struct tftp_packet *packet) -{ - return (unsigned short)((packet->data[2] << 8) | packet->data[3]); -} - -static size_t tftp_strnlen(const char *string, size_t maxlen) -{ - const char *end = memchr(string, '\0', maxlen); - return end ? (size_t)(end - string) : maxlen; -} - -static const char *tftp_option_get(const char *buf, size_t len, - const char **option, const char **value) -{ - size_t loc; - - loc = tftp_strnlen(buf, len); - loc++; /* NULL term */ - - if(loc >= len) - return NULL; - *option = buf; - - loc += tftp_strnlen(buf + loc, len - loc); - loc++; /* NULL term */ - - if(loc > len) - return NULL; - *value = &buf[strlen(*option) + 1]; - - return &buf[loc]; -} - -static CURLcode tftp_parse_option_ack(struct tftp_conn *state, - const char *ptr, int len) -{ - const char *tmp = ptr; - struct Curl_easy *data = state->data; - - /* if OACK does not contain blksize option, the default (512) must be used */ - state->blksize = TFTP_BLKSIZE_DEFAULT; - - while(tmp < ptr + len) { - const char *option, *value; - - tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value); - if(!tmp) { - failf(data, "Malformed ACK packet, rejecting"); - return CURLE_TFTP_ILLEGAL; - } - - infof(data, "got option=(%s) value=(%s)", option, value); - - if(checkprefix(TFTP_OPTION_BLKSIZE, option)) { - curl_off_t blksize; - if(curlx_str_number(&value, &blksize, TFTP_BLKSIZE_MAX)) { - failf(data, "%s (%d)", "blksize is larger than max supported", - TFTP_BLKSIZE_MAX); - return CURLE_TFTP_ILLEGAL; - } - if(!blksize) { - failf(data, "invalid blocksize value in OACK packet"); - return CURLE_TFTP_ILLEGAL; - } - else if(blksize < TFTP_BLKSIZE_MIN) { - failf(data, "%s (%d)", "blksize is smaller than min supported", - TFTP_BLKSIZE_MIN); - return CURLE_TFTP_ILLEGAL; - } - else if(blksize > state->requested_blksize) { - /* could realloc pkt buffers here, but the spec does not call out - * support for the server requesting a bigger blksize than the client - * requests */ - failf(data, "server requested blksize larger than allocated (%" - CURL_FORMAT_CURL_OFF_T ")", blksize); - return CURLE_TFTP_ILLEGAL; - } - - state->blksize = (unsigned int)blksize; - infof(data, "blksize parsed from OACK (%u) requested (%u)", - state->blksize, state->requested_blksize); - } - else if(checkprefix(TFTP_OPTION_TSIZE, option)) { - curl_off_t tsize = 0; - /* tsize should be ignored on upload: Who cares about the size of the - remote file? */ - if(!data->state.upload && - !curlx_str_number(&value, &tsize, CURL_OFF_T_MAX)) { - if(!tsize) { - failf(data, "invalid tsize -:%s:- value in OACK packet", value); - return CURLE_TFTP_ILLEGAL; - } - infof(data, "tsize parsed from OACK (%" CURL_FORMAT_CURL_OFF_T ")", - tsize); - Curl_pgrsSetDownloadSize(data, tsize); - } - } - } - - return CURLE_OK; -} - -static CURLcode tftp_option_add(struct tftp_conn *state, size_t *csize, - size_t index, const char *option) -{ - char *buf = (char *)&state->spacket.data[index]; - size_t oplen = strlen(option); - size_t blen; - if((state->blksize <= index) || - (oplen + 1) > (size_t)(state->blksize - index)) - return CURLE_TFTP_ILLEGAL; - blen = state->blksize - index; - curlx_strcopy(buf, blen, option, oplen); - *csize += oplen + 1; - return CURLE_OK; -} - -/* the next blocknum is x + 1 but it needs to wrap at an unsigned 16-bit - boundary */ -#define NEXT_BLOCKNUM(x) (((x) + 1) & 0xffff) - -/********************************************************** - * - * tftp_tx - * - * Event handler for the TX state - * - **********************************************************/ -static CURLcode tftp_tx(struct tftp_conn *state, tftp_event_t event) -{ - struct Curl_easy *data = state->data; - ssize_t sbytes; - CURLcode result = CURLE_OK; - struct SingleRequest *k = &data->req; - size_t cb; /* Bytes currently read */ - char buffer[STRERROR_LEN]; - char *bufptr; - bool eos; - - switch(event) { - - case TFTP_EVENT_ACK: - case TFTP_EVENT_OACK: - if(event == TFTP_EVENT_ACK) { - /* Ack the packet */ - int rblock = getrpacketblock(&state->rpacket); - - if(rblock != state->block && - /* There is a bug in tftpd-hpa that causes it to send us an ACK for - * 65535 when the block number wraps to 0. To handle it, when we are - * expecting 0, also accept 65535. See - * https://www.syslinux.org/archives/2010-September/015612.html - * */ - !(state->block == 0 && rblock == 65535)) { - /* This is not the expected block. Log it and up the retry counter */ - infof(data, "Received ACK for block %d, expecting %d", - rblock, state->block); - state->retries++; - /* Bail out if over the maximum */ - if(state->retries > state->retry_max) { - failf(data, "tftp_tx: giving up waiting for block %d ack", - state->block); - result = CURLE_SEND_ERROR; - } - else { - /* Re-send the data packet */ - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4 + (SEND_TYPE_ARG3)state->sbytes, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* Check all sbytes were sent */ - if(sbytes < 0) { - failf(data, "%s", - curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - result = CURLE_SEND_ERROR; - } - } - - return result; - } - /* This is the expected packet. Reset the counters and send the next - block */ - state->rx_time = time(NULL); - state->block++; - } - else - state->block = 1; /* first data block is 1 when using OACK */ - - state->retries = 0; - setpacketevent(&state->spacket, TFTP_EVENT_DATA); - setpacketblock(&state->spacket, state->block); - if(state->block > 1 && state->sbytes < state->blksize) { - state->state = TFTP_STATE_FIN; - return CURLE_OK; - } - - /* TFTP considers data block size < 512 bytes as an end of session, so - * in some cases we must wait for additional data to build full (512 bytes) - * data block. - * */ - state->sbytes = 0; - bufptr = (char *)state->spacket.data + 4; - do { - result = Curl_client_read(data, bufptr, state->blksize - state->sbytes, - &cb, &eos); - if(result) - return result; - state->sbytes += cb; - bufptr += cb; - } while(state->sbytes < state->blksize && cb); - - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4 + (SEND_TYPE_ARG3)state->sbytes, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* Check all sbytes were sent */ - if(sbytes < 0) { - failf(data, "%s", curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_SEND_ERROR; - } - /* Update the progress meter */ - k->writebytecount += state->sbytes; - Curl_pgrs_upload_inc(data, state->sbytes); - break; - - case TFTP_EVENT_TIMEOUT: - /* Increment the retry counter and log the timeout */ - state->retries++; - infof(data, "Timeout waiting for block %d ACK. " - "Retries = %d", NEXT_BLOCKNUM(state->block), state->retries); - /* Decide if we have had enough */ - if(state->retries > state->retry_max) { - state->error = TFTP_ERR_TIMEOUT; - state->state = TFTP_STATE_FIN; - } - else { - /* Re-send the data packet */ - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4 + (SEND_TYPE_ARG3)state->sbytes, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* Check all sbytes were sent */ - if(sbytes < 0) { - failf(data, "%s", curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_SEND_ERROR; - } - /* since this was a re-send, we remain at the still byte position */ - Curl_pgrsSetUploadCounter(data, k->writebytecount); - } - break; - - case TFTP_EVENT_ERROR: - state->state = TFTP_STATE_FIN; - setpacketevent(&state->spacket, TFTP_EVENT_ERROR); - setpacketblock(&state->spacket, state->block); - (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* do not bother with the return code, but if the socket is still up we - * should be a good TFTP client and let the server know we are done */ - state->state = TFTP_STATE_FIN; - break; - - default: - failf(data, "tftp_tx: internal error, event: %i", (int)event); - break; - } - - return result; -} - -static CURLcode tftp_connect_for_tx(struct tftp_conn *state, - tftp_event_t event) -{ - CURLcode result; - - infof(state->data, "%s", "Connected for transmit"); - - state->state = TFTP_STATE_TX; - result = tftp_set_timeouts(state); - if(result) - return result; - return tftp_tx(state, event); -} - -/********************************************************** - * - * tftp_rx - * - * Event handler for the RX state - * - **********************************************************/ -static CURLcode tftp_rx(struct tftp_conn *state, tftp_event_t event) -{ - ssize_t sbytes; - int rblock; - struct Curl_easy *data = state->data; - char buffer[STRERROR_LEN]; - - switch(event) { - - case TFTP_EVENT_DATA: - /* Is this the block we expect? */ - rblock = getrpacketblock(&state->rpacket); - if(NEXT_BLOCKNUM(state->block) == rblock) { - /* This is the expected block. Reset counters and ACK it. */ - state->retries = 0; - } - else if(state->block == rblock) { - /* This is the last recently received block again. Log it and ACK it - again. */ - infof(data, "Received last DATA packet block %d again.", rblock); - } - else { - /* totally unexpected, log it */ - infof(data, - "Received unexpected DATA packet block %d, expecting block %d", - rblock, NEXT_BLOCKNUM(state->block)); - break; - } - - /* ACK this block. */ - state->block = (unsigned short)rblock; - setpacketevent(&state->spacket, TFTP_EVENT_ACK); - setpacketblock(&state->spacket, state->block); - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - if(sbytes < 0) { - failf(data, "%s", curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_SEND_ERROR; - } - - /* Check if completed (That is, a less than full packet is received) */ - if(state->rbytes < (ssize_t)state->blksize + 4) { - state->state = TFTP_STATE_FIN; - } - else { - state->state = TFTP_STATE_RX; - } - state->rx_time = time(NULL); - break; - - case TFTP_EVENT_OACK: - /* ACK option acknowledgement so we can move on to data */ - state->block = 0; - state->retries = 0; - setpacketevent(&state->spacket, TFTP_EVENT_ACK); - setpacketblock(&state->spacket, state->block); - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - if(sbytes < 0) { - failf(data, "%s", curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_SEND_ERROR; - } - - /* we are ready to RX data */ - state->state = TFTP_STATE_RX; - state->rx_time = time(NULL); - break; - - case TFTP_EVENT_TIMEOUT: - /* Increment the retry count and fail if over the limit */ - state->retries++; - infof(data, - "Timeout waiting for block %d ACK. Retries = %d", - NEXT_BLOCKNUM(state->block), state->retries); - if(state->retries > state->retry_max) { - state->error = TFTP_ERR_TIMEOUT; - state->state = TFTP_STATE_FIN; - } - else { - /* Resend the previous ACK */ - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - if(sbytes < 0) { - failf(data, "%s", curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_SEND_ERROR; - } - } - break; - - case TFTP_EVENT_ERROR: - setpacketevent(&state->spacket, TFTP_EVENT_ERROR); - setpacketblock(&state->spacket, state->block); - (void)sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* do not bother with the return code, but if the socket is still up we - * should be a good TFTP client and let the server know we are done */ - state->state = TFTP_STATE_FIN; - break; - - default: - failf(data, "%s", "tftp_rx: internal error"); - return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for - this */ - } - return CURLE_OK; -} - -static CURLcode tftp_connect_for_rx(struct tftp_conn *state, - tftp_event_t event) -{ - CURLcode result; - - infof(state->data, "%s", "Connected for receive"); - - state->state = TFTP_STATE_RX; - result = tftp_set_timeouts(state); - if(result) - return result; - return tftp_rx(state, event); -} - -static CURLcode tftp_send_first(struct tftp_conn *state, - tftp_event_t event) -{ - size_t sbytes; - ssize_t senddata; - const char *mode = "octet"; - char *filename; - struct Curl_easy *data = state->data; - const struct Curl_sockaddr_ex *remote_addr = NULL; - CURLcode result = CURLE_OK; - - /* Set ASCII mode if -B flag was used */ - if(data->state.prefer_ascii) - mode = "netascii"; - - switch(event) { - - case TFTP_EVENT_INIT: /* Send the first packet out */ - case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */ - /* Increment the retry counter, quit if over the limit */ - state->retries++; - if(state->retries > state->retry_max) { - state->error = TFTP_ERR_NORESPONSE; - state->state = TFTP_STATE_FIN; - return result; - } - - if(data->state.upload) { - /* If we are uploading, send an WRQ */ - setpacketevent(&state->spacket, TFTP_EVENT_WRQ); - if(data->state.infilesize != -1) - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - else { - /* If we are downloading, send an RRQ */ - setpacketevent(&state->spacket, TFTP_EVENT_RRQ); - } - /* As RFC3617 describes the separator slash is not actually part of the - filename so we skip the always-present first letter of the path - string. */ - if(!state->data->state.up.path[1]) { - failf(data, "Missing filename"); - return CURLE_TFTP_ILLEGAL; - } - result = Curl_urldecode(&state->data->state.up.path[1], 0, - &filename, NULL, REJECT_ZERO); - if(result) - return result; - - if(strlen(filename) + strlen(mode) + 4 > state->blksize) { - failf(data, "TFTP filename too long"); - curlx_free(filename); - return CURLE_TFTP_ILLEGAL; /* too long filename field */ - } - - sbytes = 2 + - curl_msnprintf((char *)state->spacket.data + 2, - state->blksize, - "%s%c%s%c", filename, '\0', mode, '\0'); - curlx_free(filename); - - /* optional addition of TFTP options */ - if(!data->set.tftp_no_options) { - char buf[64]; - /* add tsize option */ - curl_msnprintf(buf, sizeof(buf), "%" FMT_OFF_T, - data->state.upload && (data->state.infilesize != -1) ? - data->state.infilesize : 0); - - result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_TSIZE); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, sbytes, buf); - - /* add blksize option */ - curl_msnprintf(buf, sizeof(buf), "%u", state->requested_blksize); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_BLKSIZE); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, sbytes, buf); - - /* add timeout option */ - curl_msnprintf(buf, sizeof(buf), "%d", state->retry_time); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, sbytes, TFTP_OPTION_INTERVAL); - if(result == CURLE_OK) - result = tftp_option_add(state, &sbytes, sbytes, buf); - - if(result != CURLE_OK) { - failf(data, "TFTP buffer too small for options"); - return CURLE_TFTP_ILLEGAL; - } - } - - /* the typecase for the 3rd argument is mostly for systems that do - not have a size_t argument, like older unixes that want an 'int' */ -#ifdef __AMIGA__ -#define CURL_SENDTO_ARG5(x) CURL_UNCONST(x) -#else -#define CURL_SENDTO_ARG5(x) (x) -#endif - remote_addr = Curl_conn_get_remote_addr(data, FIRSTSOCKET); - if(!remote_addr) - return CURLE_FAILED_INIT; - - senddata = sendto(state->sockfd, (void *)state->spacket.data, - (SEND_TYPE_ARG3)sbytes, 0, - CURL_SENDTO_ARG5(&remote_addr->curl_sa_addr), - (curl_socklen_t)remote_addr->addrlen); - if(senddata != (ssize_t)sbytes) { - char buffer[STRERROR_LEN]; - failf(data, "%s", curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_SEND_ERROR; - } - break; - - case TFTP_EVENT_OACK: - if(data->state.upload) { - result = tftp_connect_for_tx(state, event); - } - else { - result = tftp_connect_for_rx(state, event); - } - break; - - case TFTP_EVENT_ACK: /* Connected for transmit */ - result = tftp_connect_for_tx(state, event); - break; - - case TFTP_EVENT_DATA: /* Connected for receive */ - result = tftp_connect_for_rx(state, event); - break; - - case TFTP_EVENT_ERROR: - state->state = TFTP_STATE_FIN; - break; - - default: - failf(state->data, "tftp_send_first: internal error"); - return CURLE_TFTP_ILLEGAL; - } - - return result; -} - -/********************************************************** - * - * tftp_translate_code - * - * Translate internal error codes to CURL error codes - * - **********************************************************/ -static CURLcode tftp_translate_code(tftp_error_t error) -{ - CURLcode result = CURLE_OK; - - if(error != TFTP_ERR_NONE) { - switch(error) { - case TFTP_ERR_NOTFOUND: - result = CURLE_TFTP_NOTFOUND; - break; - case TFTP_ERR_PERM: - result = CURLE_TFTP_PERM; - break; - case TFTP_ERR_DISKFULL: - result = CURLE_REMOTE_DISK_FULL; - break; - case TFTP_ERR_UNDEF: - case TFTP_ERR_ILLEGAL: - result = CURLE_TFTP_ILLEGAL; - break; - case TFTP_ERR_UNKNOWNID: - result = CURLE_TFTP_UNKNOWNID; - break; - case TFTP_ERR_EXISTS: - result = CURLE_REMOTE_FILE_EXISTS; - break; - case TFTP_ERR_NOSUCHUSER: - result = CURLE_TFTP_NOSUCHUSER; - break; - case TFTP_ERR_TIMEOUT: - result = CURLE_OPERATION_TIMEDOUT; - break; - case TFTP_ERR_NORESPONSE: - result = CURLE_COULDNT_CONNECT; - break; - default: - result = CURLE_ABORTED_BY_CALLBACK; - break; - } - } - else - result = CURLE_OK; - - return result; -} - -/********************************************************** - * - * tftp_state_machine - * - * The tftp state machine event dispatcher - * - **********************************************************/ -static CURLcode tftp_state_machine(struct tftp_conn *state, - tftp_event_t event) -{ - CURLcode result = CURLE_OK; - struct Curl_easy *data = state->data; - - switch(state->state) { - case TFTP_STATE_START: - DEBUGF(infof(data, "TFTP_STATE_START")); - result = tftp_send_first(state, event); - break; - case TFTP_STATE_RX: - DEBUGF(infof(data, "TFTP_STATE_RX")); - result = tftp_rx(state, event); - break; - case TFTP_STATE_TX: - DEBUGF(infof(data, "TFTP_STATE_TX")); - result = tftp_tx(state, event); - break; - case TFTP_STATE_FIN: - infof(data, "%s", "TFTP finished"); - break; - default: - DEBUGF(infof(data, "STATE: %d", state->state)); - failf(data, "%s", "Internal state machine error"); - result = CURLE_TFTP_ILLEGAL; - break; - } - - return result; -} - -static void tftp_conn_dtor(void *key, size_t klen, void *entry) -{ - struct tftp_conn *state = entry; - (void)key; - (void)klen; - curlx_safefree(state->rpacket.data); - curlx_safefree(state->spacket.data); - curlx_free(state); -} - -/********************************************************** - * - * tftp_connect - * - * The connect callback - * - **********************************************************/ -static CURLcode tftp_connect(struct Curl_easy *data, bool *done) -{ - struct tftp_conn *state; - int blksize; - int need_blksize; - struct connectdata *conn = data->conn; - const struct Curl_sockaddr_ex *remote_addr = NULL; - CURLcode result; - - blksize = TFTP_BLKSIZE_DEFAULT; - - state = curlx_calloc(1, sizeof(*state)); - if(!state || - Curl_conn_meta_set(conn, CURL_META_TFTP_CONN, state, tftp_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - /* alloc pkt buffers based on specified blksize */ - if(data->set.tftp_blksize) - /* range checked when set */ - blksize = (int)data->set.tftp_blksize; - - need_blksize = blksize; - /* default size is the fallback when no OACK is received */ - if(need_blksize < TFTP_BLKSIZE_DEFAULT) - need_blksize = TFTP_BLKSIZE_DEFAULT; - - if(!state->rpacket.data) { - state->rpacket.data = curlx_calloc(1, need_blksize + 2 + 2); - - if(!state->rpacket.data) - return CURLE_OUT_OF_MEMORY; - } - - if(!state->spacket.data) { - state->spacket.data = curlx_calloc(1, need_blksize + 2 + 2); - - if(!state->spacket.data) - return CURLE_OUT_OF_MEMORY; - } - - /* we do not keep TFTP connections up because there is none or little gain - * for UDP */ - connclose(conn, "TFTP"); - - state->data = data; - state->sockfd = conn->sock[FIRSTSOCKET]; - state->state = TFTP_STATE_START; - state->error = TFTP_ERR_NONE; - state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */ - state->requested_blksize = blksize; - - remote_addr = Curl_conn_get_remote_addr(data, FIRSTSOCKET); - DEBUGASSERT(remote_addr); - if(!remote_addr) - return CURLE_FAILED_INIT; - - ((struct sockaddr *)&state->local_addr)->sa_family = - (CURL_SA_FAMILY_T)(remote_addr->family); - - result = tftp_set_timeouts(state); - if(result) - return result; - - if(!conn->bits.bound) { - /* If not already bound, bind to any interface, random UDP port. If it is - * reused or a custom local port was desired, this has already been done! - * - * We once used the size of the local_addr struct as the third argument - * for bind() to better work with IPv6 or whatever size the struct could - * have, but we learned that at least Tru64, AIX and IRIX *requires* the - * size of that argument to match the exact size of a 'sockaddr_in' struct - * when running IPv4-only. - * - * Therefore we use the size from the address we connected to, which we - * assume uses the same IP version and thus hopefully this works for both - * IPv4 and IPv6... - */ - int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr, - (curl_socklen_t)remote_addr->addrlen); - if(rc) { - char buffer[STRERROR_LEN]; - failf(data, "bind() failed; %s", - curlx_strerror(SOCKERRNO, buffer, sizeof(buffer))); - return CURLE_COULDNT_CONNECT; - } - conn->bits.bound = TRUE; - } - - Curl_pgrsStartNow(data); - - *done = TRUE; - - return CURLE_OK; -} - -/********************************************************** - * - * tftp_done - * - * The done callback - * - **********************************************************/ -static CURLcode tftp_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); - - (void)status; - (void)premature; - - if(Curl_pgrsDone(data)) - return CURLE_ABORTED_BY_CALLBACK; - - /* If we have encountered an error */ - if(state) - result = tftp_translate_code(state->error); - - return result; -} - -static CURLcode tftp_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - return Curl_pollset_add_in(data, ps, data->conn->sock[FIRSTSOCKET]); -} - -/********************************************************** - * - * tftp_receive_packet - * - * Called once select fires and data is ready on the socket - * - **********************************************************/ -static CURLcode tftp_receive_packet(struct Curl_easy *data, - struct tftp_conn *state) -{ - CURLcode result = CURLE_OK; - struct Curl_sockaddr_storage remote_addr; - curl_socklen_t fromlen = sizeof(remote_addr); - - /* Receive the packet */ - state->rbytes = (int)recvfrom(state->sockfd, - (void *)state->rpacket.data, - (RECV_TYPE_ARG3)state->blksize + 4, - 0, - (struct sockaddr *)&remote_addr, - &fromlen); - if((state->rbytes >= 0) && fromlen) { - if(state->remote_pinned) { - /* pinned, verify that it comes from the same address */ - if((state->remote_addrlen != fromlen) || - memcmp(&remote_addr, &state->remote_addr, fromlen)) { - failf(data, "Data received from another address"); - return CURLE_RECV_ERROR; - } - } - else { - /* pin address on first use */ - state->remote_pinned = TRUE; - state->remote_addrlen = fromlen; - memcpy(&state->remote_addr, &remote_addr, fromlen); - } - } - - /* Sanity check packet length */ - if(state->rbytes < 4) { - failf(data, "Received too short packet"); - /* Not a timeout, but how best to handle it? */ - state->event = TFTP_EVENT_TIMEOUT; - } - else { - /* The event is given by the TFTP packet time */ - unsigned short event = getrpacketevent(&state->rpacket); - state->event = (tftp_event_t)event; - - switch(state->event) { - case TFTP_EVENT_DATA: - /* Do not pass to the client empty or retransmitted packets */ - if(state->rbytes > 4 && - (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) { - result = Curl_client_write(data, CLIENTWRITE_BODY, - (const char *)state->rpacket.data + 4, - state->rbytes - 4); - if(result) { - tftp_state_machine(state, TFTP_EVENT_ERROR); - return result; - } - } - break; - case TFTP_EVENT_ERROR: { - unsigned short error = getrpacketblock(&state->rpacket); - const char *str = (const char *)state->rpacket.data + 4; - size_t strn = state->rbytes - 4; - state->error = (tftp_error_t)error; - if(tftp_strnlen(str, strn) < strn) - infof(data, "TFTP error: %s", str); - break; - } - case TFTP_EVENT_ACK: - break; - case TFTP_EVENT_OACK: - result = tftp_parse_option_ack(state, - (const char *)state->rpacket.data + 2, - state->rbytes-2); - if(result) - return result; - break; - case TFTP_EVENT_RRQ: - case TFTP_EVENT_WRQ: - default: - failf(data, "%s", "Internal error: Unexpected packet"); - break; - } - - /* Update the progress meter */ - result = Curl_pgrsUpdate(data); - if(result) { - tftp_state_machine(state, TFTP_EVENT_ERROR); - return result; - } - } - return result; -} - -/********************************************************** - * - * tftp_state_timeout - * - * Check if timeouts have been reached - * - **********************************************************/ -static timediff_t tftp_state_timeout(struct tftp_conn *state, - tftp_event_t *event) -{ - time_t current; - timediff_t timeout_ms; - - if(event) - *event = TFTP_EVENT_NONE; - - timeout_ms = Curl_timeleft_ms(state->data); - if(timeout_ms < 0) { - state->error = TFTP_ERR_TIMEOUT; - state->state = TFTP_STATE_FIN; - return timeout_ms; - } - current = time(NULL); - if(current > state->rx_time + state->retry_time) { - if(event) - *event = TFTP_EVENT_TIMEOUT; - state->rx_time = time(NULL); /* update even though we received nothing */ - } - - return timeout_ms; -} - -/********************************************************** - * - * tftp_multi_statemach - * - * Handle single RX socket event and return - * - **********************************************************/ -static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done) -{ - tftp_event_t event; - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); - timediff_t timeout_ms; - - *done = FALSE; - if(!state) - return CURLE_FAILED_INIT; - - timeout_ms = tftp_state_timeout(state, &event); - if(timeout_ms < 0) { - failf(data, "TFTP response timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - if(event != TFTP_EVENT_NONE) { - result = tftp_state_machine(state, event); - if(result) - return result; - *done = (state->state == TFTP_STATE_FIN); - if(*done) - /* Tell curl we are done */ - Curl_xfer_setup_nop(data); - } - else { - /* no timeouts to handle, check our socket */ - int rc = SOCKET_READABLE(state->sockfd, 0); - - if(rc == -1) { - /* bail out */ - int error = SOCKERRNO; - char buffer[STRERROR_LEN]; - failf(data, "%s", curlx_strerror(error, buffer, sizeof(buffer))); - state->event = TFTP_EVENT_ERROR; - } - else if(rc) { - result = tftp_receive_packet(data, state); - if(result) - return result; - result = tftp_state_machine(state, state->event); - if(result) - return result; - *done = (state->state == TFTP_STATE_FIN); - if(*done) - /* Tell curl we are done */ - Curl_xfer_setup_nop(data); - } - /* if rc == 0, then select() timed out */ - } - - return result; -} - -/********************************************************** - * - * tftp_doing - * - * Called from multi.c while DOing - * - **********************************************************/ -static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done) -{ - CURLcode result; - result = tftp_multi_statemach(data, dophase_done); - - if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete")); - } - else if(!result) { - /* The multi code does not have this logic for the DOING state so we - provide it for TFTP since it may do the entire transfer in this - state. */ - result = Curl_pgrsCheck(data); - } - return result; -} - -/********************************************************** - * - * tftp_perform - * - * Entry point for transfer from tftp_do, starts state mach - * - **********************************************************/ -static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = data->conn; - struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); - - *dophase_done = FALSE; - if(!state) - return CURLE_FAILED_INIT; - - result = tftp_state_machine(state, TFTP_EVENT_INIT); - - if((state->state == TFTP_STATE_FIN) || result) - return result; - - result = tftp_multi_statemach(data, dophase_done); - - if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete")); - - return result; -} - -/********************************************************** - * - * tftp_do - * - * The do callback - * - * This callback initiates the TFTP transfer - * - **********************************************************/ - -static CURLcode tftp_do(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct tftp_conn *state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); - CURLcode result; - - *done = FALSE; - - if(!state) { - result = tftp_connect(data, done); - if(result) - return result; - - state = Curl_conn_meta_get(conn, CURL_META_TFTP_CONN); - if(!state) - return CURLE_TFTP_ILLEGAL; - } - - result = tftp_perform(data, done); - - /* If tftp_perform() returned an error, use that for return code. If it - was OK, see if tftp_translate_code() has an error. */ - if(!result) - /* If we have encountered an internal tftp error, translate it. */ - result = tftp_translate_code(state->error); - - return result; -} - -static CURLcode tftp_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - char *path = data->state.up.path; - size_t len = strlen(path); - - conn->transport_wanted = TRNSPRT_UDP; - - /* TFTP URLs support a trailing ";mode=netascii" or ";mode=octet" */ - if((len >= 14) && !memcmp(&path[len - 14], ";mode=netascii", 14)) { - data->state.prefer_ascii = TRUE; - path[len - 14] = 0; /* cut it there */ - } - else if((len >= 11) && !memcmp(&path[len - 11], ";mode=octet", 11)) { - data->state.prefer_ascii = FALSE; - path[len - 11] = 0; /* cut it there */ - } - - return CURLE_OK; -} - -/* - * TFTP protocol handler. - */ -const struct Curl_protocol Curl_protocol_tftp = { - tftp_setup_connection, /* setup_connection */ - tftp_do, /* do_it */ - tftp_done, /* done */ - ZERO_NULL, /* do_more */ - tftp_connect, /* connect_it */ - tftp_multi_statemach, /* connecting */ - tftp_doing, /* doing */ - tftp_pollset, /* proto_pollset */ - tftp_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ZERO_NULL, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif diff --git a/vendor/curl/lib/tftp.h b/vendor/curl/lib/tftp.h deleted file mode 100644 index 32310103b..000000000 --- a/vendor/curl/lib/tftp.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_TFTP_H -#define HEADER_CURL_TFTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#ifndef CURL_DISABLE_TFTP -extern const struct Curl_protocol Curl_protocol_tftp; -#endif - -#define TFTP_BLKSIZE_MIN 8 -#define TFTP_BLKSIZE_MAX 65464 - -#endif /* HEADER_CURL_TFTP_H */ diff --git a/vendor/curl/lib/thrdpool.c b/vendor/curl/lib/thrdpool.c deleted file mode 100644 index 22faa396e..000000000 --- a/vendor/curl/lib/thrdpool.c +++ /dev/null @@ -1,481 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_THREADS - -#include "llist.h" -#include "curl_threads.h" -#include "curlx/timeval.h" -#include "thrdpool.h" -#ifdef CURLVERBOSE -#include "curl_trc.h" -#include "urldata.h" -#endif - - -struct thrdslot { - struct Curl_llist_node node; - struct curl_thrdpool *tpool; - curl_thread_t thread; - curl_cond_t await; - struct curltime starttime; - const char *work_description; - timediff_t work_timeout_ms; - uint32_t id; - BIT(running); - BIT(idle); -}; - -struct curl_thrdpool { - char *name; - uint64_t refcount; - curl_mutex_t lock; - curl_cond_t await; - struct Curl_llist slots; - struct Curl_llist zombies; - Curl_thrdpool_take_item_cb *fn_take; - Curl_thrdpool_process_item_cb *fn_process; - Curl_thrdpool_return_item_cb *fn_return; - void *fn_user_data; - CURLcode fatal_err; - uint32_t min_threads; - uint32_t max_threads; - uint32_t idle_time_ms; - uint32_t next_id; - BIT(aborted); - BIT(detached); -}; - -static void thrdpool_join_zombies(struct curl_thrdpool *tpool); -static bool thrdpool_unlink(struct curl_thrdpool *tpool, bool locked); - -static void thrdslot_destroy(struct thrdslot *tslot) -{ - DEBUGASSERT(tslot->thread == curl_thread_t_null); - DEBUGASSERT(!tslot->running); - Curl_cond_destroy(&tslot->await); - curlx_free(tslot); -} - -static void thrdslot_done(struct thrdslot *tslot) -{ - struct curl_thrdpool *tpool = tslot->tpool; - - DEBUGASSERT(Curl_node_llist(&tslot->node) == &tpool->slots); - Curl_node_remove(&tslot->node); - tslot->running = FALSE; - Curl_llist_append(&tpool->zombies, tslot, &tslot->node); - Curl_cond_signal(&tpool->await); -} - -static CURL_THREAD_RETURN_T CURL_STDCALL thrdslot_run(void *arg) -{ - struct thrdslot *tslot = arg; - struct curl_thrdpool *tpool = tslot->tpool; - void *item; - - Curl_mutex_acquire(&tpool->lock); - DEBUGASSERT(Curl_node_llist(&tslot->node) == &tpool->slots); - for(;;) { - while(!tpool->aborted) { - tslot->work_description = NULL; - tslot->work_timeout_ms = 0; - item = tpool->fn_take(tpool->fn_user_data, &tslot->work_description, - &tslot->work_timeout_ms); - if(!item) - break; - tslot->starttime = curlx_now(); - tslot->idle = FALSE; - Curl_mutex_release(&tpool->lock); - - tpool->fn_process(item); - - Curl_mutex_acquire(&tpool->lock); - tslot->work_description = NULL; - tpool->fn_return(item, tpool->aborted ? NULL : tpool->fn_user_data); - } - - if(tpool->aborted || - (Curl_llist_count(&tpool->slots) > tpool->max_threads)) - goto out; - - tslot->idle = TRUE; - tslot->starttime = curlx_now(); - thrdpool_join_zombies(tpool); - Curl_cond_signal(&tpool->await); - /* Only wait with idle timeout when we are above the minimum - * number of threads. Otherwise short idle timeouts will keep - * on activating threads that have no means to shut down. */ - if((tpool->idle_time_ms > 0) && - (Curl_llist_count(&tpool->slots) > tpool->min_threads)) { - CURLcode r = Curl_cond_timedwait(&tslot->await, &tpool->lock, - tpool->idle_time_ms); - if((r == CURLE_OPERATION_TIMEDOUT) && - (Curl_llist_count(&tpool->slots) > tpool->min_threads)) { - goto out; - } - } - else { - Curl_cond_wait(&tslot->await, &tpool->lock); - } - } - -out: - thrdslot_done(tslot); - if(!thrdpool_unlink(tslot->tpool, TRUE)) { - /* tpool not destroyed */ - Curl_mutex_release(&tpool->lock); - } - return 0; -} - -static CURLcode thrdslot_start(struct curl_thrdpool *tpool) -{ - struct thrdslot *tslot; - CURLcode result = CURLE_OUT_OF_MEMORY; - - tslot = curlx_calloc(1, sizeof(*tslot)); - if(!tslot) - goto out; - tslot->id = tpool->next_id++; - tslot->tpool = tpool; - tslot->thread = curl_thread_t_null; - Curl_cond_init(&tslot->await); - - tpool->refcount++; - tslot->running = TRUE; - tslot->thread = Curl_thread_create(thrdslot_run, tslot); - if(tslot->thread == curl_thread_t_null) { /* never started */ - tslot->running = FALSE; - thrdpool_unlink(tpool, TRUE); - result = CURLE_FAILED_INIT; - goto out; - } - - Curl_llist_append(&tpool->slots, tslot, &tslot->node); - tslot = NULL; - result = CURLE_OK; - -out: - if(tslot) - thrdslot_destroy(tslot); - return result; -} - -static void thrdpool_wake_all(struct curl_thrdpool *tpool) -{ - struct Curl_llist_node *e; - for(e = Curl_llist_head(&tpool->slots); e; e = Curl_node_next(e)) { - struct thrdslot *tslot = Curl_node_elem(e); - Curl_cond_signal(&tslot->await); - } -} - -static void thrdpool_join_zombies(struct curl_thrdpool *tpool) -{ - struct Curl_llist_node *e; - - for(e = Curl_llist_head(&tpool->zombies); e; - e = Curl_llist_head(&tpool->zombies)) { - struct thrdslot *tslot = Curl_node_elem(e); - - Curl_node_remove(&tslot->node); - if(tslot->thread != curl_thread_t_null) { - Curl_mutex_release(&tpool->lock); - Curl_thread_join(&tslot->thread); - Curl_mutex_acquire(&tpool->lock); - tslot->thread = curl_thread_t_null; - } - thrdslot_destroy(tslot); - } -} - -static bool thrdpool_unlink(struct curl_thrdpool *tpool, bool locked) -{ - DEBUGASSERT(tpool->refcount); - if(tpool->refcount) - tpool->refcount--; - if(tpool->refcount) - return FALSE; - - /* no more references, free */ - DEBUGASSERT(tpool->aborted); - thrdpool_join_zombies(tpool); - if(locked) - Curl_mutex_release(&tpool->lock); - curlx_free(tpool->name); - Curl_cond_destroy(&tpool->await); - Curl_mutex_destroy(&tpool->lock); - curlx_free(tpool); - return TRUE; -} - -static CURLcode thrdpool_signal(struct curl_thrdpool *tpool, - uint32_t nthreads) -{ - struct Curl_llist_node *e, *n; - CURLcode result = CURLE_OK; - - DEBUGASSERT(!tpool->aborted); - thrdpool_join_zombies(tpool); - - for(e = Curl_llist_head(&tpool->slots); e && nthreads; e = n) { - struct thrdslot *tslot = Curl_node_elem(e); - n = Curl_node_next(e); - if(tslot->idle) { - Curl_cond_signal(&tslot->await); - --nthreads; - } - else if(!tslot->starttime.tv_sec && !tslot->starttime.tv_usec) { - /* starting thread, queries for work soon. */ - --nthreads; - } - } - - while(nthreads && !result && - Curl_llist_count(&tpool->slots) < tpool->max_threads) { - result = thrdslot_start(tpool); - if(result) - break; - --nthreads; - } - - return result; -} - -CURLcode Curl_thrdpool_set_props(struct curl_thrdpool *tpool, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms) -{ - CURLcode result = CURLE_OK; - size_t running; - - if(!max_threads || (min_threads > max_threads)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - Curl_mutex_acquire(&tpool->lock); - tpool->min_threads = min_threads; - tpool->max_threads = max_threads; - tpool->idle_time_ms = idle_time_ms; - running = Curl_llist_count(&tpool->slots); - if(tpool->min_threads > running) { - result = thrdpool_signal(tpool, tpool->min_threads - (uint32_t)running); - } - Curl_mutex_release(&tpool->lock); - - return result; -} - -CURLcode Curl_thrdpool_create(struct curl_thrdpool **ptpool, - const char *name, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms, - Curl_thrdpool_take_item_cb *fn_take, - Curl_thrdpool_process_item_cb *fn_process, - Curl_thrdpool_return_item_cb *fn_return, - void *user_data) -{ - struct curl_thrdpool *tpool; - CURLcode result = CURLE_OUT_OF_MEMORY; - - tpool = curlx_calloc(1, sizeof(*tpool)); - if(!tpool) - goto out; - tpool->refcount = 1; - - Curl_mutex_init(&tpool->lock); - Curl_cond_init(&tpool->await); - Curl_llist_init(&tpool->slots, NULL); - Curl_llist_init(&tpool->zombies, NULL); - tpool->fn_take = fn_take; - tpool->fn_process = fn_process; - tpool->fn_return = fn_return; - tpool->fn_user_data = user_data; - - tpool->name = curlx_strdup(name); - if(!tpool->name) - goto out; - - result = Curl_thrdpool_set_props(tpool, min_threads, max_threads, - idle_time_ms); - -out: - if(result && tpool) { - tpool->aborted = TRUE; - thrdpool_unlink(tpool, FALSE); - tpool = NULL; - } - *ptpool = tpool; - return result; -} - -void Curl_thrdpool_destroy(struct curl_thrdpool *tpool, bool join) -{ - Curl_mutex_acquire(&tpool->lock); - - tpool->aborted = TRUE; - - while(join && Curl_llist_count(&tpool->slots)) { - thrdpool_wake_all(tpool); - Curl_cond_wait(&tpool->await, &tpool->lock); - } - - thrdpool_join_zombies(tpool); - - /* detach all still running threads */ - if(Curl_llist_count(&tpool->slots)) { - struct Curl_llist_node *e; - for(e = Curl_llist_head(&tpool->slots); e; e = Curl_node_next(e)) { - struct thrdslot *tslot = Curl_node_elem(e); - if(tslot->thread != curl_thread_t_null) - Curl_thread_destroy(&tslot->thread); - } - tpool->detached = TRUE; - } - - if(!thrdpool_unlink(tpool, TRUE)) { - /* tpool not destroyed */ - Curl_mutex_release(&tpool->lock); - } -} - -CURLcode Curl_thrdpool_signal(struct curl_thrdpool *tpool, uint32_t nthreads) -{ - CURLcode result; - - Curl_mutex_acquire(&tpool->lock); - result = thrdpool_signal(tpool, nthreads); - Curl_mutex_release(&tpool->lock); - return result; -} - -static bool thrdpool_all_idle(struct curl_thrdpool *tpool) -{ - struct Curl_llist_node *e; - for(e = Curl_llist_head(&tpool->slots); e; e = Curl_node_next(e)) { - struct thrdslot *tslot = Curl_node_elem(e); - if(!tslot->idle) - return FALSE; - } - return TRUE; -} - -CURLcode Curl_thrdpool_await_idle(struct curl_thrdpool *tpool, - uint32_t timeout_ms) -{ - CURLcode result = CURLE_OK; - struct curltime end = { 0 }; - - Curl_mutex_acquire(&tpool->lock); - DEBUGASSERT(!tpool->aborted); - if(tpool->aborted) { - result = CURLE_FAILED_INIT; - goto out; - } - - while(!thrdpool_all_idle(tpool)) { - if(timeout_ms) { - timediff_t remain_ms; - CURLcode r; - - if(!end.tv_sec && !end.tv_usec) { - end = curlx_now(); - end.tv_sec += (time_t)(timeout_ms / 1000); - end.tv_usec += (int)(timeout_ms % 1000) * 1000; - if(end.tv_usec >= 1000000) { - end.tv_sec++; - end.tv_usec -= 1000000; - } - } - remain_ms = curlx_timediff_ms(curlx_now(), end); - if(remain_ms <= 0) - r = CURLE_OPERATION_TIMEDOUT; - else - r = Curl_cond_timedwait(&tpool->await, &tpool->lock, - (uint32_t)remain_ms); - if(r == CURLE_OPERATION_TIMEDOUT) { - result = r; - break; - } - } - else { - Curl_cond_wait(&tpool->await, &tpool->lock); - } - } - -out: - thrdpool_join_zombies(tpool); - Curl_mutex_release(&tpool->lock); - return result; -} - -#ifdef CURLVERBOSE -void Curl_thrdpool_trace(struct curl_thrdpool *tpool, - struct Curl_easy *data) -{ - struct curl_trc_feat *feat = &Curl_trc_feat_threads; - if(Curl_trc_ft_is_verbose(data, feat)) { - struct Curl_llist_node *e; - struct curltime now = curlx_now(); - - Curl_mutex_acquire(&tpool->lock); - if(!Curl_llist_count(&tpool->slots)) { - Curl_trc_feat_infof(data, feat, "[TPOOL-%s] no threads running", - tpool->name); - } - for(e = Curl_llist_head(&tpool->slots); e; e = Curl_node_next(e)) { - struct thrdslot *tslot = Curl_node_elem(e); - timediff_t elapsed_ms = curlx_ptimediff_ms(&now, &tslot->starttime); - if(!tslot->running) { - Curl_trc_feat_infof(data, feat, "[TPOOL-%s] [%u]: not running", - tpool->name, tslot->id); - } - else if(!tslot->starttime.tv_sec && !tslot->starttime.tv_usec) { - Curl_trc_feat_infof(data, feat, "[TPOOL-%s] [%u]: starting...", - tpool->name, tslot->id); - } - else if(tslot->idle) { - Curl_trc_feat_infof(data, feat, "[TPOOL-%s] [%u]: idle for %" - FMT_TIMEDIFF_T "ms", - tpool->name, tslot->id, elapsed_ms); - } - else { - timediff_t remain_ms = tslot->work_timeout_ms ? - (tslot->work_timeout_ms - elapsed_ms) : 0; - Curl_trc_feat_infof(data, feat, "[TPOOL-%s] [%u]: busy %" - FMT_TIMEDIFF_T "ms, timeout in %" FMT_TIMEDIFF_T - "ms: %s", - tpool->name, tslot->id, elapsed_ms, remain_ms, - tslot->work_description); - } - } - Curl_mutex_release(&tpool->lock); - } -} -#endif - -#endif /* USE_THREADS */ diff --git a/vendor/curl/lib/thrdpool.h b/vendor/curl/lib/thrdpool.h deleted file mode 100644 index cc81fb6fc..000000000 --- a/vendor/curl/lib/thrdpool.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef HEADER_CURL_THRDPOOL_H -#define HEADER_CURL_THRDPOOL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "curlx/timediff.h" - -#ifdef USE_THREADS - -struct curl_thrdpool; -struct Curl_easy; - -/* Invoked under thread pool lock to get an "item" to work on. Must - * return NULL if there is nothing to do. - * Caller might return a descriptive string about the "item", where - * available. The string needs to have the same lifetime as the - * item itself. */ -typedef void *Curl_thrdpool_take_item_cb(void *user_data, - const char **pdescription, - timediff_t *ptimeout_ms); - -/* Invoked outside thread pool lock to process the item taken. */ -typedef void Curl_thrdpool_process_item_cb(void *item); - -/* Invoked under thread pool lock to return a processed item back - * to the producer. - * If the thread pool has been destroyed, `user_data` will be NULL - * and the callback is responsible to release all `item` resources. */ -typedef void Curl_thrdpool_return_item_cb(void *item, void *user_data); - -/* Create a new thread pool. - * @param name name of pool for tracing purposes - * @param min_threads minimum number of threads to have always running - * @param max_threads maximum number of threads running, ever. - * @param idle_time_ms maximum time a thread should wait for tasks to - * process before shutting down (unless the pool is - * already at minimum thread count), use 0 for - * infinite wait. - * @param fn_take take the next item to process - * @param fn_process process the item taken - * @param fn_return return the processed item - * @param user_data parameter passed to take/return callbacks - */ -CURLcode Curl_thrdpool_create(struct curl_thrdpool **ptpool, - const char *name, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms, - Curl_thrdpool_take_item_cb *fn_take, - Curl_thrdpool_process_item_cb *fn_process, - Curl_thrdpool_return_item_cb *fn_return, - void *user_data); - -/* Destroy the thread pool, release its resources. - * With `join` being TRUE, the call will wait for all threads to finish - * processing before returning. On FALSE, it will detach all threads - * running. Ongoing item processing will continue to run and - * `fn_return` will be invoked with NULL user_data before the thread exits. - */ -void Curl_thrdpool_destroy(struct curl_thrdpool *tpool, bool join); - -/* Signal the pool to wake up `nthreads` idle worker threads, possible - * creating new threads up to the max limit. The number should reflect - * the items that can actually be taken for processing right away, e.g. - * the producers "queue" length of outstanding items. - */ -CURLcode Curl_thrdpool_signal(struct curl_thrdpool *tpool, uint32_t nthreads); - -CURLcode Curl_thrdpool_await_idle(struct curl_thrdpool *tpool, - uint32_t timeout_ms); - -/* Change the properties of a threadpool. */ -CURLcode Curl_thrdpool_set_props(struct curl_thrdpool *tpool, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms); - -#ifdef CURLVERBOSE -void Curl_thrdpool_trace(struct curl_thrdpool *tpool, - struct Curl_easy *data); -#endif - -#endif /* USE_THREADS */ - -#endif /* HEADER_CURL_THRDPOOL_H */ diff --git a/vendor/curl/lib/thrdqueue.c b/vendor/curl/lib/thrdqueue.c deleted file mode 100644 index 1521ccfbe..000000000 --- a/vendor/curl/lib/thrdqueue.c +++ /dev/null @@ -1,411 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_THREADS - -#include "llist.h" -#include "curl_threads.h" -#include "thrdpool.h" -#include "thrdqueue.h" -#include "curlx/timeval.h" -#ifdef CURLVERBOSE -#include "curl_trc.h" -#include "urldata.h" -#endif - - -struct curl_thrdq { - char *name; - curl_mutex_t lock; - curl_cond_t await; - struct Curl_llist sendq; - struct Curl_llist recvq; - struct curl_thrdpool *tpool; - Curl_thrdq_item_free_cb *fn_free; - Curl_thrdq_item_process_cb *fn_process; - Curl_thrdq_ev_cb *fn_event; - void *fn_user_data; - uint32_t send_max_len; - BIT(aborted); -}; - -struct thrdq_item { - struct Curl_llist_node node; - Curl_thrdq_item_free_cb *fn_free; - Curl_thrdq_item_process_cb *fn_process; - void *item; - struct curltime start; - timediff_t timeout_ms; - const char *description; -}; - -static struct thrdq_item *thrdq_item_create(struct curl_thrdq *tqueue, - void *item, - const char *description, - timediff_t timeout_ms) -{ - struct thrdq_item *qitem; - - qitem = curlx_calloc(1, sizeof(*qitem)); - if(!qitem) - return NULL; - qitem->item = item; - qitem->description = description; - qitem->fn_free = tqueue->fn_free; - qitem->fn_process = tqueue->fn_process; - if(timeout_ms) { - qitem->start = curlx_now(); - qitem->timeout_ms = timeout_ms; - } - return qitem; -} - -static void thrdq_item_destroy(struct thrdq_item *qitem) -{ - if(qitem->item) - qitem->fn_free(qitem->item); - curlx_free(qitem); -} - -static void thrdq_item_list_dtor(void *user_data, void *elem) -{ - (void)user_data; - thrdq_item_destroy(elem); -} - -static void *thrdq_tpool_take(void *user_data, const char **pdescription, - timediff_t *ptimeout_ms) -{ - struct curl_thrdq *tqueue = user_data; - struct thrdq_item *qitem = NULL; - struct Curl_llist_node *e; - Curl_thrdq_ev_cb *fn_event = NULL; - void *fn_user_data = NULL; - - Curl_mutex_acquire(&tqueue->lock); - *pdescription = NULL; - *ptimeout_ms = 0; - if(!tqueue->aborted) { - e = Curl_llist_head(&tqueue->sendq); - if(e) { - struct curltime now = curlx_now(); - timediff_t timeout_ms; - while(e) { - qitem = Curl_node_take_elem(e); - timeout_ms = (!qitem->timeout_ms) ? 0 : - (qitem->timeout_ms - curlx_ptimediff_ms(&now, &qitem->start)); - if(timeout_ms < 0) { - /* timed out while queued, place on receive queue */ - Curl_llist_append(&tqueue->recvq, qitem, &qitem->node); - fn_event = tqueue->fn_event; - fn_user_data = tqueue->fn_user_data; - qitem = NULL; - e = Curl_llist_head(&tqueue->sendq); - continue; - } - else { - *pdescription = qitem->description; - *ptimeout_ms = timeout_ms; - break; - } - } - } - } - Curl_mutex_release(&tqueue->lock); - /* avoiding deadlocks */ - if(fn_event) - fn_event(tqueue, CURL_THRDQ_EV_ITEM_DONE, fn_user_data); - return qitem; -} - -static void thrdq_tpool_return(void *item, void *user_data) -{ - struct curl_thrdq *tqueue = user_data; - struct thrdq_item *qitem = item; - Curl_thrdq_ev_cb *fn_event = NULL; - void *fn_user_data = NULL; - - if(!tqueue) { - thrdq_item_destroy(item); - return; - } - - Curl_mutex_acquire(&tqueue->lock); - if(tqueue->aborted) { - thrdq_item_destroy(qitem); - } - else { - DEBUGASSERT(!Curl_node_llist(&qitem->node)); - Curl_llist_append(&tqueue->recvq, qitem, &qitem->node); - fn_event = tqueue->fn_event; - fn_user_data = tqueue->fn_user_data; - } - Curl_mutex_release(&tqueue->lock); - /* avoiding deadlocks */ - if(fn_event) - fn_event(tqueue, CURL_THRDQ_EV_ITEM_DONE, fn_user_data); -} - -static void thrdq_tpool_process(void *item) -{ - struct thrdq_item *qitem = item; - qitem->fn_process(qitem->item); -} - -static void thrdq_unlink(struct curl_thrdq *tqueue, bool locked, bool join) -{ - DEBUGASSERT(tqueue->aborted); - if(tqueue->tpool) { - if(locked) - Curl_mutex_release(&tqueue->lock); - Curl_thrdpool_destroy(tqueue->tpool, join); - tqueue->tpool = NULL; - if(locked) - Curl_mutex_acquire(&tqueue->lock); - } - - Curl_llist_destroy(&tqueue->sendq, NULL); - Curl_llist_destroy(&tqueue->recvq, NULL); - curlx_free(tqueue->name); - Curl_cond_destroy(&tqueue->await); - if(locked) - Curl_mutex_release(&tqueue->lock); - Curl_mutex_destroy(&tqueue->lock); - curlx_free(tqueue); -} - -CURLcode Curl_thrdq_create(struct curl_thrdq **ptqueue, - const char *name, - uint32_t max_len, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms, - Curl_thrdq_item_free_cb *fn_free, - Curl_thrdq_item_process_cb *fn_process, - Curl_thrdq_ev_cb *fn_event, - void *user_data) -{ - struct curl_thrdq *tqueue; - CURLcode result = CURLE_OUT_OF_MEMORY; - - tqueue = curlx_calloc(1, sizeof(*tqueue)); - if(!tqueue) - goto out; - - Curl_mutex_init(&tqueue->lock); - Curl_cond_init(&tqueue->await); - Curl_llist_init(&tqueue->sendq, thrdq_item_list_dtor); - Curl_llist_init(&tqueue->recvq, thrdq_item_list_dtor); - tqueue->fn_free = fn_free; - tqueue->fn_process = fn_process; - tqueue->fn_event = fn_event; - tqueue->fn_user_data = user_data; - tqueue->send_max_len = max_len; - - tqueue->name = curlx_strdup(name); - if(!tqueue->name) - goto out; - - result = Curl_thrdpool_create(&tqueue->tpool, name, - min_threads, max_threads, idle_time_ms, - thrdq_tpool_take, - thrdq_tpool_process, - thrdq_tpool_return, - tqueue); - -out: - if(result && tqueue) { - tqueue->aborted = TRUE; - thrdq_unlink(tqueue, FALSE, TRUE); - tqueue = NULL; - } - *ptqueue = tqueue; - return result; -} - -void Curl_thrdq_destroy(struct curl_thrdq *tqueue, bool join) -{ - Curl_mutex_acquire(&tqueue->lock); - DEBUGASSERT(!tqueue->aborted); - tqueue->aborted = TRUE; - thrdq_unlink(tqueue, TRUE, join); -} - -CURLcode Curl_thrdq_send(struct curl_thrdq *tqueue, void *item, - const char *description, timediff_t timeout_ms) -{ - CURLcode result = CURLE_AGAIN; - size_t signals = 0; - - Curl_mutex_acquire(&tqueue->lock); - if(tqueue->aborted) { - DEBUGASSERT(0); - result = CURLE_SEND_ERROR; - goto out; - } - if(timeout_ms < 0) { - result = CURLE_OPERATION_TIMEDOUT; - goto out; - } - - if(!tqueue->send_max_len || - (Curl_llist_count(&tqueue->sendq) < tqueue->send_max_len)) { - struct thrdq_item *qitem = thrdq_item_create(tqueue, item, description, - timeout_ms); - if(!qitem) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - item = NULL; - Curl_llist_append(&tqueue->sendq, qitem, &qitem->node); - signals = Curl_llist_count(&tqueue->sendq); - result = CURLE_OK; - } - -out: - Curl_mutex_release(&tqueue->lock); - /* Signal thread pool unlocked to avoid deadlocks. Since we added - * item to the queue already, it might have been taken for processing - * already. Any error in signalling the pool cannot be reported to - * the caller since it needs to give up ownership of item. */ - if(!result && signals) - (void)Curl_thrdpool_signal(tqueue->tpool, (uint32_t)signals); - return result; -} - -CURLcode Curl_thrdq_recv(struct curl_thrdq *tqueue, void **pitem) -{ - CURLcode result = CURLE_AGAIN; - struct Curl_llist_node *e; - - *pitem = NULL; - Curl_mutex_acquire(&tqueue->lock); - if(tqueue->aborted) { - DEBUGASSERT(0); - result = CURLE_RECV_ERROR; - goto out; - } - - e = Curl_llist_head(&tqueue->recvq); - if(e) { - struct thrdq_item *qitem = Curl_node_take_elem(e); - *pitem = qitem->item; - qitem->item = NULL; - thrdq_item_destroy(qitem); - result = CURLE_OK; - } -out: - Curl_mutex_release(&tqueue->lock); - return result; -} - -static void thrdq_llist_clean_matches(struct Curl_llist *llist, - Curl_thrdq_item_match_cb *fn_match, - void *match_data) -{ - struct Curl_llist_node *e, *n; - struct thrdq_item *qitem; - - for(e = Curl_llist_head(llist); e; e = n) { - n = Curl_node_next(e); - qitem = Curl_node_elem(e); - if(fn_match(qitem->item, match_data)) - Curl_node_remove(e); - } -} - -void Curl_thrdq_clear(struct curl_thrdq *tqueue, - Curl_thrdq_item_match_cb *fn_match, - void *match_data) -{ - Curl_mutex_acquire(&tqueue->lock); - if(tqueue->aborted) { - DEBUGASSERT(0); - goto out; - } - thrdq_llist_clean_matches(&tqueue->sendq, fn_match, match_data); - thrdq_llist_clean_matches(&tqueue->recvq, fn_match, match_data); -out: - Curl_mutex_release(&tqueue->lock); -} - -CURLcode Curl_thrdq_await_done(struct curl_thrdq *tqueue, - uint32_t timeout_ms) -{ - return Curl_thrdpool_await_idle(tqueue->tpool, timeout_ms); -} - -CURLcode Curl_thrdq_set_props(struct curl_thrdq *tqueue, - uint32_t max_len, - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms) -{ - CURLcode result; - size_t signals; - - Curl_mutex_acquire(&tqueue->lock); - tqueue->send_max_len = max_len; - signals = Curl_llist_count(&tqueue->sendq); - Curl_mutex_release(&tqueue->lock); - - result = Curl_thrdpool_set_props(tqueue->tpool, min_threads, - max_threads, idle_time_ms); - if(!result && signals) - result = Curl_thrdpool_signal(tqueue->tpool, (uint32_t)signals); - return result; -} - -#ifdef CURLVERBOSE -void Curl_thrdq_trace(struct curl_thrdq *tqueue, - struct Curl_easy *data) -{ - struct curl_trc_feat *feat = &Curl_trc_feat_threads; - if(Curl_trc_ft_is_verbose(data, feat)) { - struct Curl_llist_node *e; - struct thrdq_item *qitem; - - Curl_thrdpool_trace(tqueue->tpool, data); - Curl_mutex_acquire(&tqueue->lock); - if(!Curl_llist_count(&tqueue->sendq) && - !Curl_llist_count(&tqueue->recvq)) { - Curl_trc_feat_infof(data, feat, "[TQUEUE-%s] empty", tqueue->name); - } - for(e = Curl_llist_head(&tqueue->sendq); e; e = Curl_node_next(e)) { - qitem = Curl_node_elem(e); - Curl_trc_feat_infof(data, feat, "[TQUEUE-%s] in: %s", - tqueue->name, qitem->description); - } - for(e = Curl_llist_head(&tqueue->recvq); e; e = Curl_node_next(e)) { - qitem = Curl_node_elem(e); - Curl_trc_feat_infof(data, feat, "[TQUEUE-%s] out: %s", - tqueue->name, qitem->description); - } - Curl_mutex_release(&tqueue->lock); - } -} -#endif - -#endif /* USE_THREADS */ diff --git a/vendor/curl/lib/thrdqueue.h b/vendor/curl/lib/thrdqueue.h deleted file mode 100644 index d267f5d09..000000000 --- a/vendor/curl/lib/thrdqueue.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef HEADER_CURL_THRDQUEUE_H -#define HEADER_CURL_THRDQUEUE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "curlx/timediff.h" - -#ifdef USE_THREADS - -struct Curl_easy; -struct curl_thrdq; - -typedef enum { - CURL_THRDQ_EV_ITEM_DONE /* an item has been processed and is ready */ -} Curl_thrdq_event; - -/* Notification callback when "events" happen in the queue. May be - * call from any thread, queue is not locked. */ -typedef void Curl_thrdq_ev_cb(const struct curl_thrdq *tqueue, - Curl_thrdq_event ev, - void *user_data); - -/* Process a queued item. Maybe call from any thread. Queue is - * not locked. */ -typedef void Curl_thrdq_item_process_cb(void *item); - -/* Free an item. May be called from any thread at any time for an - * item that is in the queue (either before or after processing). */ -typedef void Curl_thrdq_item_free_cb(void *item); - -/* Create a new queue processing "items" by a thread pool. - */ -CURLcode Curl_thrdq_create(struct curl_thrdq **ptqueue, - const char *name, - uint32_t max_len, /* 0 for unlimited */ - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms, - Curl_thrdq_item_free_cb *fn_free, - Curl_thrdq_item_process_cb *fn_process, - Curl_thrdq_ev_cb *fn_event, /* optional */ - void *user_data); - -/* Destroy the queue, free all queued items unprocessed and destroy - * the thread pool used. - * @param join TRUE when thread pool shall be joined. FALSE for - * detaching any running threads. - */ -void Curl_thrdq_destroy(struct curl_thrdq *tqueue, bool join); - -/* Send "item" onto the queue. The caller needs to clear any reference - * to "item" on success, e.g. the queue takes ownership. - * `description` is an optional string describing the item for tracing - * purposes. It needs to have the same lifetime as `item`. - * Returns CURLE_AGAIN when the queue has already been full. - * - * With`timeout_ms` != 0, items that get stuck that long in the send - * queue are removed and added to the receive queue right away. - */ -CURLcode Curl_thrdq_send(struct curl_thrdq *tqueue, void *item, - const char *description, timediff_t timeout_ms); - -/* Receive the oldest, processed item from the queue again, if there is one. - * The caller takes ownership of the item received, e.g. the queue - * relinquishes all references to item. - * Returns CURLE_AGAIN when there is no processed item, setting `pitem` - * to NULL. - */ -CURLcode Curl_thrdq_recv(struct curl_thrdq *tqueue, void **pitem); - -/* Return TRUE if the passed "item" matches. */ -typedef bool Curl_thrdq_item_match_cb(void *item, void *match_data); - -/* Clear all scheduled/processed items that match from the queue. This - * will *not* be able to clear items that are being processed. - */ -void Curl_thrdq_clear(struct curl_thrdq *tqueue, - Curl_thrdq_item_match_cb *fn_match, - void *match_data); - -CURLcode Curl_thrdq_await_done(struct curl_thrdq *tqueue, - uint32_t timeout_ms); - -CURLcode Curl_thrdq_set_props(struct curl_thrdq *tqueue, - uint32_t max_len, /* 0 for unlimited */ - uint32_t min_threads, - uint32_t max_threads, - uint32_t idle_time_ms); - -#ifdef CURLVERBOSE -void Curl_thrdq_trace(struct curl_thrdq *tqueue, - struct Curl_easy *data); -#endif - -#endif /* USE_THREADS */ - -#endif /* HEADER_CURL_THRDQUEUE_H */ diff --git a/vendor/curl/lib/transfer.c b/vendor/curl/lib/transfer.c deleted file mode 100644 index fd1a903da..000000000 --- a/vendor/curl/lib/transfer.c +++ /dev/null @@ -1,957 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#include - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#elif defined(HAVE_UNISTD_H) -#include -#endif - -#ifndef HAVE_SOCKET -#error "We cannot compile without socket() support!" -#endif - -#include "urldata.h" - -#include "hostip.h" -#include "cfilters.h" -#include "cw-out.h" -#include "dnscache.h" -#include "transfer.h" -#include "sendf.h" -#include "curl_trc.h" -#include "progress.h" -#include "http.h" -#include "url.h" -#include "getinfo.h" -#include "multiif.h" -#include "connect.h" -#include "hsts.h" -#include "setopt.h" -#include "headers.h" -#include "bufref.h" - -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_IMAP) -/* - * checkheaders() checks the linked list of custom headers for a - * particular header (prefix). Provide the prefix without colon! - * - * Returns a pointer to the first matching header or NULL if none matched. - */ -char *Curl_checkheaders(const struct Curl_easy *data, - const char *thisheader, - const size_t thislen) -{ - struct curl_slist *head; - DEBUGASSERT(thislen); - DEBUGASSERT(thisheader[thislen - 1] != ':'); - - for(head = data->set.headers; head; head = head->next) { - if(curl_strnequal(head->data, thisheader, thislen) && - Curl_headersep(head->data[thislen])) - return head->data; - } - - return NULL; -} -#endif - -static int data_pending(struct Curl_easy *data, bool rcvd_eagain) -{ - struct connectdata *conn = data->conn; - - if(conn->scheme->protocol & PROTO_FAMILY_FTP) - return Curl_conn_data_pending(data, SECONDARYSOCKET); - - /* in the case of libssh2, we can never be really sure that we have emptied - its internal buffers so we MUST always try until we get EAGAIN back */ - return (!rcvd_eagain && - conn->scheme->protocol & (CURLPROTO_SCP | CURLPROTO_SFTP)) || - Curl_conn_data_pending(data, FIRSTSOCKET); -} - -/* - * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the - * remote document with the time provided by CURLOPT_TIMEVAL - */ -bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) -{ - if((timeofdoc == 0) || (data->set.timevalue == 0)) - return TRUE; - - switch(data->set.timecondition) { - case CURL_TIMECOND_IFMODSINCE: - default: - if(timeofdoc <= data->set.timevalue) { - infof(data, "The requested document is not new enough"); - data->info.timecond = TRUE; - return FALSE; - } - break; - case CURL_TIMECOND_IFUNMODSINCE: - if(timeofdoc >= data->set.timevalue) { - infof(data, "The requested document is not old enough"); - data->info.timecond = TRUE; - return FALSE; - } - break; - } - - return TRUE; -} - -static CURLcode xfer_recv_shutdown(struct Curl_easy *data, bool *done) -{ - if(!data || !data->conn) - return CURLE_FAILED_INIT; - return Curl_conn_shutdown(data, data->conn->recv_idx, done); -} - -static bool xfer_recv_shutdown_started(struct Curl_easy *data) -{ - if(!data || !data->conn) - return FALSE; - return Curl_shutdown_started(data, data->conn->recv_idx); -} - -CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done) -{ - if(!data || !data->conn) - return CURLE_FAILED_INIT; - return Curl_conn_shutdown(data, data->conn->send_idx, done); -} - -/** - * Receive raw response data for the transfer. - * @param data the transfer - * @param buf buffer to keep response data received - * @param blen length of `buf` - * @param eos_reliable if EOS detection in underlying connection is reliable - * @return number of bytes read or -1 for error - */ -static CURLcode xfer_recv_resp(struct Curl_easy *data, - char *buf, size_t blen, - bool eos_reliable, - size_t *pnread) -{ - CURLcode result; - - DEBUGASSERT(blen > 0); - *pnread = 0; - /* If we are reading BODY data and the connection does NOT handle EOF - * and we know the size of the BODY data, limit the read amount */ - if(!eos_reliable && !data->req.header && data->req.size != -1) { - blen = curlx_sotouz_range(data->req.size - data->req.bytecount, 0, blen); - } - else if(xfer_recv_shutdown_started(data)) { - /* we already received everything. Do not try more. */ - blen = 0; - } - - if(blen) { - result = Curl_xfer_recv(data, buf, blen, pnread); - if(result) - return result; - } - - if(*pnread == 0) { - if(data->req.shutdown) { - bool done; - result = xfer_recv_shutdown(data, &done); - if(result) - return result; - if(!done) { - return CURLE_AGAIN; - } - } - DEBUGF(infof(data, "sendrecv_dl: we are done")); - } - return CURLE_OK; -} - -/* - * Go ahead and do a read if we have a readable socket or if - * the stream was rewound (in which case we have data in a - * buffer) - */ -static CURLcode sendrecv_dl(struct Curl_easy *data, - struct SingleRequest *k) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - char *buf, *xfer_buf; - size_t blen, xfer_blen; - int maxloops = 10; - bool is_multiplex = FALSE; - bool rcvd_eagain = FALSE; - bool is_eos = FALSE, rate_limited = FALSE; - - result = Curl_multi_xfer_buf_borrow(data, &xfer_buf, &xfer_blen); - if(result) - goto out; - - /* This is where we loop until we have read everything there is to - read or we get a CURLE_AGAIN */ - do { - size_t bytestoread; - - if(!is_multiplex) { - /* Multiplexed connection have inherent handling of EOF and we do not - * have to carefully restrict the amount we try to read. - * Multiplexed changes only in one direction. */ - is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET); - } - - buf = xfer_buf; - bytestoread = xfer_blen; - - if(bytestoread && Curl_rlimit_active(&data->progress.dl.rlimit)) { - curl_off_t dl_avail = Curl_rlimit_avail(&data->progress.dl.rlimit, - Curl_pgrs_now(data)); -#if 0 - DEBUGF(infof(data, "dl_rlimit, available=%" FMT_OFF_T, dl_avail)); -#endif - /* In case of rate limited downloads: if this loop already got data and - * less than 16k is left in the limit, break out. We want to stutter a - * bit to keep in the limit, but too small receives will cost cpu - * unnecessarily. */ - if(dl_avail <= 0) { - rate_limited = TRUE; - break; - } - if(dl_avail < (curl_off_t)bytestoread) - bytestoread = (size_t)dl_avail; - } - - rcvd_eagain = FALSE; - result = xfer_recv_resp(data, buf, bytestoread, is_multiplex, &blen); - if(result) { - if(result != CURLE_AGAIN) - goto out; /* real error */ - rcvd_eagain = TRUE; - result = CURLE_OK; - if(data->req.download_done && data->req.no_body && - !data->req.resp_trailer) { - DEBUGF(infof(data, "EAGAIN, download done, no trailer announced, " - "not waiting for EOS")); - blen = 0; - /* continue as if we received the EOS */ - } - else - break; /* get out of loop */ - } - - /* We only get a 0-length receive at the end of the response */ - is_eos = (blen == 0); - - if(!blen) { - result = Curl_req_stop_send_recv(data); - if(result) - goto out; - if(k->eos_written) /* already did write this to client, leave */ - break; - } - - result = Curl_xfer_write_resp(data, buf, blen, is_eos); - if(result || data->req.done) - goto out; - - /* if we are done, we stop receiving. On multiplexed connections, - * we should read the EOS. Which may arrive as meta data after - * the bytes. Not taking it in might lead to RST of streams. */ - if((!is_multiplex && data->req.download_done) || is_eos) { - CURL_REQ_CLEAR_RECV(data); - } - /* if we stopped receiving, leave the loop */ - if(!CURL_REQ_WANT_RECV(data)) - break; - - } while(maxloops--); - - if(!is_eos && !rate_limited && CURL_REQ_WANT_RECV(data) && - (!rcvd_eagain || data_pending(data, rcvd_eagain))) { - /* Did not read until EAGAIN/EOS or there is still data pending - * in buffers. Mark as read-again via simulated SELECT results. */ - Curl_multi_mark_dirty(data); - CURL_TRC_M(data, "sendrecv_dl() no EAGAIN/pending data, mark as dirty"); - } - - if(!CURL_REQ_WANT_RECV(data) && CURL_REQ_WANT_SEND(data) && - (conn->bits.close || is_multiplex)) { - /* When we have read the entire thing and the close bit is set, the server - may now close the connection. If there is now any kind of sending going - on from our side, we need to stop that immediately. */ - infof(data, "we are done reading and this is set to close, stop send"); - Curl_req_abort_sending(data); - } - -out: - Curl_multi_xfer_buf_release(data, xfer_buf); - if(result) - DEBUGF(infof(data, "sendrecv_dl() -> %d", result)); - return result; -} - -/* - * Send data to upload to the server, when the socket is writable. - */ -static CURLcode sendrecv_ul(struct Curl_easy *data) -{ - /* We should not get here when the sending is already done. */ - DEBUGASSERT(!Curl_req_done_sending(data)); - - if(!Curl_req_done_sending(data)) - return Curl_req_send_more(data); - return CURLE_OK; -} - -/* - * Curl_sendrecv() is the low-level function to be called when data is to - * be read and written to/from the connection. - */ -CURLcode Curl_sendrecv(struct Curl_easy *data) -{ - struct SingleRequest *k = &data->req; - CURLcode result = CURLE_OK; - - if(Curl_xfer_is_blocked(data)) { - result = CURLE_OK; - goto out; - } - - /* We go ahead and do a read if we have a readable socket or if the stream - was rewound (in which case we have data in a buffer) */ - if(CURL_REQ_WANT_RECV(data)) { - result = sendrecv_dl(data, k); - if(result || data->req.done) - goto out; - } - - /* If we still have writing to do, we check if we have a writable socket. */ - if(Curl_req_want_send(data)) { - result = sendrecv_ul(data); - if(result) - goto out; - } - - result = Curl_pgrsCheck(data); - if(result) - goto out; - - if(CURL_REQ_WANT_IO(data)) { - if(Curl_timeleft_ms(data) < 0) { - if(k->size != -1) { - failf(data, "Operation timed out after %" FMT_TIMEDIFF_T - " milliseconds with %" FMT_OFF_T " out of %" - FMT_OFF_T " bytes received", - curlx_ptimediff_ms(Curl_pgrs_now(data), - &data->progress.t_startsingle), - k->bytecount, k->size); - } - else { - failf(data, "Operation timed out after %" FMT_TIMEDIFF_T - " milliseconds with %" FMT_OFF_T " bytes received", - curlx_ptimediff_ms(Curl_pgrs_now(data), - &data->progress.t_startsingle), - k->bytecount); - } - result = CURLE_OPERATION_TIMEDOUT; - goto out; - } - } - else { - /* - * The transfer has been performed. Make some general checks before - * returning. - */ - if(!(data->req.no_body) && (k->size != -1) && - (k->bytecount != k->size) && !k->newurl) { - failf(data, "transfer closed with %" FMT_OFF_T - " bytes remaining to read", k->size - k->bytecount); - result = CURLE_PARTIAL_FILE; - goto out; - } - } - - /* If there is nothing more to send/recv, the request is done */ - if(!CURL_REQ_WANT_IO(data)) - data->req.done = TRUE; - - result = Curl_pgrsUpdate(data); - -out: - if(result) - DEBUGF(infof(data, "Curl_sendrecv() -> %d", result)); - return result; -} - -/* Curl_init_CONNECT() gets called each time the handle switches to CONNECT - which means this gets called once for each subsequent redirect etc */ -void Curl_init_CONNECT(struct Curl_easy *data) -{ - data->state.fread_func = data->set.fread_func_set; - data->state.in = data->set.in_set; - data->state.upload = (data->state.httpreq == HTTPREQ_PUT); -} - -/* - * Restore the user credentials to those set in options. - */ -CURLcode Curl_reset_userpwd(struct Curl_easy *data) -{ - CURLcode result; - if(data->set.str[STRING_USERNAME] || data->set.str[STRING_PASSWORD]) - data->state.creds_from = CREDS_OPTION; - result = Curl_setstropt(&data->state.aptr.user, - data->set.str[STRING_USERNAME]); - if(!result) - result = Curl_setstropt(&data->state.aptr.passwd, - data->set.str[STRING_PASSWORD]); - return result; -} - -/* - * Restore the proxy credentials to those set in options. - */ -CURLcode Curl_reset_proxypwd(struct Curl_easy *data) -{ -#ifndef CURL_DISABLE_PROXY - CURLcode result = Curl_setstropt(&data->state.aptr.proxyuser, - data->set.str[STRING_PROXYUSERNAME]); - if(!result) - result = Curl_setstropt(&data->state.aptr.proxypasswd, - data->set.str[STRING_PROXYPASSWORD]); - return result; -#else - (void)data; - return CURLE_OK; -#endif -} - -/* - * Curl_pretransfer() is called immediately before a transfer starts, and only - * once for one transfer no matter if it has redirects or do multi-pass - * authentication etc. - */ -CURLcode Curl_pretransfer(struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - - /* Reset the retry count at the start of each request. - * If the retry count is not reset, when the connection drops, - * it will not enter the retry mechanism on CONN_MAX_RETRIES + 1 attempts - * and will immediately throw - * "Connection died, tried CONN_MAX_RETRIES times before giving up". - * By resetting it here, we ensure each new request starts fresh. */ - data->state.retrycount = 0; - - if(!data->set.str[STRING_SET_URL] && !data->set.uh) { - /* we cannot do anything without URL */ - failf(data, "No URL set"); - return CURLE_URL_MALFORMAT; - } - - /* CURLOPT_CURLU overrides CURLOPT_URL and the contents of the CURLU handle - is allowed to be changed by the user between transfers */ - if(data->set.uh) { - CURLUcode uc; - curlx_free(data->set.str[STRING_SET_URL]); - uc = curl_url_get(data->set.uh, - CURLUPART_URL, &data->set.str[STRING_SET_URL], 0); - if(uc) { - /* clear the pointer to not point to freed memory anymore */ - Curl_bufref_set(&data->state.url, NULL, 0, NULL); - failf(data, "No URL set"); - return CURLE_URL_MALFORMAT; - } - } - - Curl_bufref_set(&data->state.url, data->set.str[STRING_SET_URL], 0, NULL); - - if(data->set.postfields && data->set.set_resume_from) { - /* we cannot */ - failf(data, "cannot mix POSTFIELDS with RESUME_FROM"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - data->state.prefer_ascii = data->set.prefer_ascii; -#ifdef CURL_LIST_ONLY_PROTOCOL - data->state.list_only = data->set.list_only; -#endif - data->state.httpreq = data->set.method; - - data->state.requests = 0; - data->state.followlocation = 0; /* reset the location-follow counter */ - data->state.this_is_a_follow = FALSE; /* reset this */ - data->state.http_ignorecustom = FALSE; /* use custom HTTP method */ - data->state.errorbuf = FALSE; /* no error has occurred */ -#ifndef CURL_DISABLE_HTTP - Curl_http_neg_init(data, &data->state.http_neg); -#endif - data->state.authproblem = FALSE; - data->state.authhost.want = data->set.httpauth; - data->state.authproxy.want = data->set.proxyauth; - curlx_safefree(data->info.wouldredirect); - Curl_data_priority_clear_state(data); - if(data->set.http_auto_referer) - Curl_bufref_free(&data->state.referer); - if(data->set.str[STRING_SET_REFERER]) - Curl_bufref_set(&data->state.referer, data->set.str[STRING_SET_REFERER], - 0, NULL); - - if(data->state.httpreq == HTTPREQ_PUT) - data->state.infilesize = data->set.filesize; - else if((data->state.httpreq != HTTPREQ_GET) && - (data->state.httpreq != HTTPREQ_HEAD)) { - data->state.infilesize = data->set.postfieldsize; - if(data->set.postfields && (data->state.infilesize == -1)) - data->state.infilesize = (curl_off_t)strlen(data->set.postfields); - } - else - data->state.infilesize = 0; - - /* If there is a list of cookie files to read, do it now! */ - result = Curl_cookie_loadfiles(data); - if(!result) - Curl_cookie_run(data); /* activate */ - - /* If there is a list of host pairs to deal with */ - if(!result && data->state.resolve) - result = Curl_loadhostpairs(data); - - if(!result) - /* If there is a list of hsts files to read */ - result = Curl_hsts_loadfiles(data); - - if(!result) { - /* Allow data->set.use_port to set which port to use. This needs to be - * disabled for example when we follow Location: headers to URLs using - * different ports! */ - data->state.allow_port = TRUE; - -#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(MSG_NOSIGNAL) - /************************************************************* - * Tell signal handler to ignore SIGPIPE - *************************************************************/ - if(!data->set.no_signal) - data->state.prev_signal = signal(SIGPIPE, SIG_IGN); -#endif - - Curl_initinfo(data); /* reset session-specific information "variables" */ - Curl_pgrsResetTransferSizes(data); - Curl_pgrsStartNow(data); - - /* In case the handle is reused and an authentication method was picked - in the session we need to make sure we only use the one(s) we now - consider to be fine */ - data->state.authhost.picked &= data->state.authhost.want; - data->state.authproxy.picked &= data->state.authproxy.want; - -#ifndef CURL_DISABLE_FTP - data->state.wildcardmatch = data->set.wildcard_enabled; - if(data->state.wildcardmatch) { - struct WildcardData *wc; - if(!data->wildcard) { - data->wildcard = curlx_calloc(1, sizeof(struct WildcardData)); - if(!data->wildcard) - return CURLE_OUT_OF_MEMORY; - } - wc = data->wildcard; - if(wc->state < CURLWC_INIT) { - if(wc->ftpwc) - wc->dtor(wc->ftpwc); - curlx_safefree(wc->pattern); - curlx_safefree(wc->path); - Curl_wildcard_init(wc); /* init wildcard structures */ - } - } -#endif - result = Curl_hsts_loadcb(data, data->hsts); - } - - /* - * Set user-agent. Used for HTTP, but since we can attempt to tunnel - * anything through an HTTP proxy we cannot limit this based on protocol. - */ - if(!result && data->set.str[STRING_USERAGENT]) { - curlx_free(data->state.aptr.uagent); - data->state.aptr.uagent = - curl_maprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); - if(!data->state.aptr.uagent) - return CURLE_OUT_OF_MEMORY; - } - - if(!result) - result = Curl_reset_userpwd(data); - if(!result) - result = Curl_reset_proxypwd(data); - - data->req.headerbytecount = 0; - Curl_headers_cleanup(data); - return result; -} - -/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted. - - NOTE: that the *url is curlx_malloc()ed. */ -CURLcode Curl_retry_request(struct Curl_easy *data, char **url) -{ - struct connectdata *conn = data->conn; - bool retry = FALSE; - *url = NULL; - - /* if we are talking upload, we cannot do the checks below, unless the - protocol is HTTP as when uploading over HTTP we will still get a - response */ - if(data->state.upload && - !(conn->scheme->protocol & (PROTO_FAMILY_HTTP | CURLPROTO_RTSP))) - return CURLE_OK; - - if(conn->bits.reuse && - (data->req.bytecount + data->req.headerbytecount == 0) && - ((!data->req.no_body && !data->req.done) || - (conn->scheme->protocol & PROTO_FAMILY_HTTP)) -#ifndef CURL_DISABLE_RTSP - && (data->set.rtspreq != RTSPREQ_RECEIVE) -#endif - ) - /* We got no data, we attempted to reuse a connection. For HTTP this - can be a retry so we try again regardless if we expected a body. - For other protocols we only try again only if we expected a body. - - This might happen if the connection was left alive when we were - done using it before, but that was closed when we wanted to read from - it again. Bad luck. Retry the same request on a fresh connect! */ - retry = TRUE; - else if(data->state.refused_stream && - (data->req.bytecount + data->req.headerbytecount == 0)) { - /* This was sent on a refused stream, safe to rerun. A refused stream - error can typically only happen on HTTP/2 level if the stream is safe - to issue again, but the nghttp2 API can deliver the message to other - streams as well, which is why this adds the check the data counters - too. */ - infof(data, "REFUSED_STREAM, retrying a fresh connect"); - data->state.refused_stream = FALSE; /* clear again */ - retry = TRUE; - } - if(retry) { -#define CONN_MAX_RETRIES 5 - if(data->state.retrycount++ >= CONN_MAX_RETRIES) { - failf(data, "Connection died, tried %d times before giving up", - CONN_MAX_RETRIES); - data->state.retrycount = 0; - return CURLE_SEND_ERROR; - } - infof(data, "Connection died, retrying a fresh connect (retry count: %d)", - data->state.retrycount); - *url = Curl_bufref_dup(&data->state.url); - if(!*url) - return CURLE_OUT_OF_MEMORY; - - connclose(conn, "retry"); /* close this connection */ - conn->bits.retry = TRUE; /* mark this as a connection we are about to - retry. Marking it this way should prevent i.e - HTTP transfers to return error because nothing - has been transferred! */ - Curl_creader_set_rewind(data, TRUE); - } - return CURLE_OK; -} - -static void xfer_setup( - struct Curl_easy *data, /* transfer */ - int send_idx, /* sockindex to send on or -1 */ - int recv_idx, /* sockindex to receive on or -1 */ - curl_off_t recv_size /* how much to receive, -1 if unknown */ - ) -{ - struct SingleRequest *k = &data->req; - struct connectdata *conn = data->conn; - - DEBUGASSERT(conn != NULL); - /* indexes are in range */ - DEBUGASSERT((send_idx <= 1) && (send_idx >= -1)); - DEBUGASSERT((recv_idx <= 1) && (recv_idx >= -1)); - /* if request wants to send, switching off the send direction is wrong */ - DEBUGASSERT((send_idx >= 0) || !Curl_req_want_send(data)); - - conn->send_idx = send_idx; - conn->recv_idx = recv_idx; - - /* without receiving, there should be not recv_size */ - DEBUGASSERT((conn->recv_idx >= 0) || (recv_size == -1)); - k->size = recv_size; - k->header = !!conn->scheme->run->write_resp_hd; - /* by default, we do not shutdown at the end of the transfer */ - k->shutdown = FALSE; - k->shutdown_err_ignore = FALSE; - - /* The code sequence below is placed in this function because all necessary - input is not always known in do_complete() as this function may be called - after that */ - if(!k->header && (recv_size > 0)) - Curl_pgrsSetDownloadSize(data, recv_size); - - /* we want header and/or body, if neither then do not do this! */ - if(conn->scheme->run->write_resp_hd || !data->req.no_body) { - if(conn->recv_idx != -1) - CURL_REQ_SET_RECV(data); - if(conn->send_idx != -1) - CURL_REQ_SET_SEND(data); - } - CURL_TRC_M(data, "xfer_setup: recv_idx=%d, send_idx=%d", - conn->recv_idx, conn->send_idx); -} - -void Curl_xfer_setup_nop(struct Curl_easy *data) -{ - xfer_setup(data, -1, -1, -1); -} - -void Curl_xfer_setup_sendrecv(struct Curl_easy *data, - int sockindex, - curl_off_t recv_size) -{ - xfer_setup(data, sockindex, sockindex, recv_size); -} - -void Curl_xfer_setup_send(struct Curl_easy *data, - int sockindex) -{ - xfer_setup(data, sockindex, -1, -1); -} - -void Curl_xfer_setup_recv(struct Curl_easy *data, - int sockindex, - curl_off_t recv_size) -{ - xfer_setup(data, -1, sockindex, recv_size); -} - -void Curl_xfer_set_shutdown(struct Curl_easy *data, - bool shutdown, - bool ignore_errors) -{ - /* Shutdown should only be set when the transfer only sends or receives. */ - DEBUGASSERT(!shutdown || - (data->conn->send_idx < 0) || (data->conn->recv_idx < 0)); - data->req.shutdown = shutdown; - data->req.shutdown_err_ignore = ignore_errors; -} - -CURLcode Curl_xfer_write_resp(struct Curl_easy *data, - const char *buf, size_t blen, - bool is_eos) -{ - CURLcode result = CURLE_OK; - - if(data->conn->scheme->run->write_resp) { - /* protocol handlers offering this function take full responsibility - * for writing all received download data to the client. */ - result = data->conn->scheme->run->write_resp(data, buf, blen, is_eos); - } - else { - /* No special handling by protocol handler, write all received data - * as BODY to the client. */ - if(blen || is_eos) { - int cwtype = CLIENTWRITE_BODY; - if(is_eos) - cwtype |= CLIENTWRITE_EOS; - result = Curl_client_write(data, cwtype, buf, blen); - } - } - - if(!result && is_eos) { - /* If we wrote the EOS, we are definitely done */ - data->req.eos_written = TRUE; - data->req.download_done = TRUE; - } - CURL_TRC_WRITE(data, "xfer_write_resp(len=%zu, eos=%d) -> %d", - blen, is_eos, result); - return result; -} - -bool Curl_xfer_write_is_paused(struct Curl_easy *data) -{ - return Curl_cwriter_is_paused(data); -} - -CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data, - const char *hd0, size_t hdlen, bool is_eos) -{ - if(data->conn->scheme->run->write_resp_hd) { - DEBUGASSERT(!hd0[hdlen]); /* null-terminated */ - /* protocol handlers offering this function take full responsibility - * for writing all received download data to the client. */ - return data->conn->scheme->run->write_resp_hd(data, hd0, hdlen, is_eos); - } - /* No special handling by protocol handler, write as response bytes */ - return Curl_xfer_write_resp(data, hd0, hdlen, is_eos); -} - -CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature) -{ - (void)premature; - return Curl_cw_out_done(data); -} - -bool Curl_xfer_needs_flush(struct Curl_easy *data) -{ - return Curl_conn_needs_flush(data, data->conn->send_idx); -} - -CURLcode Curl_xfer_flush(struct Curl_easy *data) -{ - return Curl_conn_flush(data, data->conn->send_idx); -} - -CURLcode Curl_xfer_send(struct Curl_easy *data, - const void *buf, size_t blen, bool eos, - size_t *pnwritten) -{ - CURLcode result; - - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - - result = Curl_conn_send(data, data->conn->send_idx, - buf, blen, eos, pnwritten); - if(result == CURLE_AGAIN) { - result = CURLE_OK; - *pnwritten = 0; - } - else if(!result && *pnwritten) - data->info.request_size += *pnwritten; - - DEBUGF(infof(data, "Curl_xfer_send(len=%zu, eos=%d) -> %d, %zu", - blen, eos, result, *pnwritten)); - return result; -} - -CURLcode Curl_xfer_recv(struct Curl_easy *data, - char *buf, size_t blen, - size_t *pnrcvd) -{ - DEBUGASSERT(data); - DEBUGASSERT(data->conn); - DEBUGASSERT(data->set.buffer_size > 0); - - if(curlx_uitouz(data->set.buffer_size) < blen) - blen = curlx_uitouz(data->set.buffer_size); - return Curl_conn_recv(data, data->conn->recv_idx, buf, blen, pnrcvd); -} - -CURLcode Curl_xfer_send_close(struct Curl_easy *data) -{ - Curl_conn_ev_data_done_send(data); - return CURLE_OK; -} - -bool Curl_xfer_is_blocked(struct Curl_easy *data) -{ - bool want_send = CURL_REQ_WANT_SEND(data); - bool want_recv = CURL_REQ_WANT_RECV(data); - if(!want_send) - return want_recv && Curl_xfer_recv_is_paused(data); - else if(!want_recv) - return want_send && Curl_xfer_send_is_paused(data); - else - return Curl_xfer_recv_is_paused(data) && Curl_xfer_send_is_paused(data); -} - -bool Curl_xfer_send_is_paused(struct Curl_easy *data) -{ - return Curl_rlimit_is_blocked(&data->progress.ul.rlimit); -} - -bool Curl_xfer_recv_is_paused(struct Curl_easy *data) -{ - return Curl_rlimit_is_blocked(&data->progress.dl.rlimit); -} - -CURLcode Curl_xfer_pause_send(struct Curl_easy *data, bool enable) -{ - CURLcode result = CURLE_OK; - Curl_rlimit_block(&data->progress.ul.rlimit, enable, Curl_pgrs_now(data)); - if(!enable && Curl_creader_is_paused(data)) - result = Curl_creader_unpause(data); - Curl_pgrsSendPause(data, enable); - return result; -} - -CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable) -{ - CURLcode result = CURLE_OK; - Curl_rlimit_block(&data->progress.dl.rlimit, enable, Curl_pgrs_now(data)); - if(!enable && Curl_cwriter_is_paused(data)) - result = Curl_cwriter_unpause(data); - Curl_conn_ev_data_pause(data, enable); - Curl_pgrsRecvPause(data, enable); - return result; -} - -bool Curl_xfer_is_secure(struct Curl_easy *data) -{ - const struct Curl_scheme *scheme = NULL; - - if(data->conn) { - scheme = data->conn->scheme; - /* if we are connected, but not use SSL, the transfer is not secure. - * This covers an insecure http:// proxy that is not tunneling. - * We enforce tunneling for such cases, but better be sure here. */ - if(Curl_conn_is_connected(data->conn, FIRSTSOCKET) && - !Curl_conn_is_ssl(data->conn, FIRSTSOCKET)) - return FALSE; - } - else if(data->info.conn_scheme) { /* was connected once */ - scheme = Curl_get_scheme(data->info.conn_scheme); - } - else { /* never connected (yet?) */ - DEBUGASSERT(0); /* not implemented, would need to parse URL */ - } - return scheme ? (scheme->flags & PROTOPT_SSL) : FALSE; -} diff --git a/vendor/curl/lib/transfer.h b/vendor/curl/lib/transfer.h deleted file mode 100644 index b29e70b9e..000000000 --- a/vendor/curl/lib/transfer.h +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef HEADER_CURL_TRANSFER_H -#define HEADER_CURL_TRANSFER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#define Curl_headersep(x) ((((x) == ':') || ((x) == ';'))) - -char *Curl_checkheaders(const struct Curl_easy *data, - const char *thisheader, - const size_t thislen); - -void Curl_init_CONNECT(struct Curl_easy *data); - -CURLcode Curl_reset_userpwd(struct Curl_easy *data); -CURLcode Curl_reset_proxypwd(struct Curl_easy *data); -CURLcode Curl_pretransfer(struct Curl_easy *data); - -CURLcode Curl_sendrecv(struct Curl_easy *data); -CURLcode Curl_retry_request(struct Curl_easy *data, char **url); -bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc); - -/** - * Write the transfer raw response bytes, as received from the connection. - * Handle all passed bytes or return an error. By default, this writes - * the bytes as BODY to the client. Protocols may provide a - * "write_resp" callback in their handler to add specific treatment. E.g. - * HTTP parses response headers and passes them differently to the client. - * @param data the transfer - * @param buf the raw response bytes - * @param blen the amount of bytes in `buf` - * @param is_eos TRUE iff the connection indicates this to be the last - * bytes of the response - */ -CURLcode Curl_xfer_write_resp(struct Curl_easy *data, - const char *buf, size_t blen, - bool is_eos); - -bool Curl_xfer_write_is_paused(struct Curl_easy *data); - -/** - * Write a single "header" line from a server response. - * @param hd0 the null-terminated, single header line - * @param hdlen the length of the header line - * @param is_eos TRUE iff this is the end of the response - */ -CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data, - const char *hd0, size_t hdlen, bool is_eos); - -/* The transfer is neither receiving nor sending. */ -void Curl_xfer_setup_nop(struct Curl_easy *data); - -/* The transfer sends data on the given socket index */ -void Curl_xfer_setup_send(struct Curl_easy *data, - int sockindex); - -/* The transfer receives data on the given socket index, the - * amount to receive (or -1 if unknown). */ -void Curl_xfer_setup_recv(struct Curl_easy *data, - int sockindex, - curl_off_t recv_size); - -/* *After* Curl_xfer_setup_xxx(), tell the transfer to shutdown the - * connection at the end. Let the transfer either fail or ignore any - * errors during shutdown. */ -void Curl_xfer_set_shutdown(struct Curl_easy *data, - bool shutdown, - bool ignore_errors); - -/** - * The transfer will use socket 1 to send/recv. `recv_size` is - * the amount to receive or -1 if unknown. - */ -void Curl_xfer_setup_sendrecv(struct Curl_easy *data, - int sockindex, - curl_off_t recv_size); - -/** - * Multi has set transfer to DONE. Last chance to trigger - * missing response things like writing an EOS to the client. - */ -CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature); - -/** - * Return TRUE iff transfer has pending data to send. Checks involved - * connection filters. - */ -bool Curl_xfer_needs_flush(struct Curl_easy *data); - -/** - * Flush any pending send data on the transfer connection. - */ -CURLcode Curl_xfer_flush(struct Curl_easy *data); - -/** - * Send data on the socket/connection filter designated - * for transfer's outgoing data. - * Return CURLE_OK on blocking with (*pnwritten == 0). - */ -CURLcode Curl_xfer_send(struct Curl_easy *data, - const void *buf, size_t blen, bool eos, - size_t *pnwritten); - -/** - * Receive data on the socket/connection filter designated - * for transfer's incoming data. - * Return CURLE_AGAIN on blocking with (*pnrcvd == 0). - */ -CURLcode Curl_xfer_recv(struct Curl_easy *data, - char *buf, size_t blen, - size_t *pnrcvd); - -CURLcode Curl_xfer_send_close(struct Curl_easy *data); -CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done); - -/* Return TRUE if the transfer is not done, but further progress - * is blocked. For example when it is only receiving and its writer - * is PAUSED. */ -bool Curl_xfer_is_blocked(struct Curl_easy *data); - -/* Query if send/recv for transfer is paused. */ -bool Curl_xfer_send_is_paused(struct Curl_easy *data); -bool Curl_xfer_recv_is_paused(struct Curl_easy *data); - -/* Enable/Disable pausing of send/recv for the transfer. */ -CURLcode Curl_xfer_pause_send(struct Curl_easy *data, bool enable); -CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable); - -/* TRUE if the transfer is secure (e.g. TLS) from libcurl to the - * URL's host. */ -bool Curl_xfer_is_secure(struct Curl_easy *data); - -#endif /* HEADER_CURL_TRANSFER_H */ diff --git a/vendor/curl/lib/uint-bset.c b/vendor/curl/lib/uint-bset.c deleted file mode 100644 index 546917494..000000000 --- a/vendor/curl/lib/uint-bset.c +++ /dev/null @@ -1,233 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "uint-bset.h" - -#ifdef DEBUGBUILD -#define CURL_UINT32_BSET_MAGIC 0x62757473 -#endif - -void Curl_uint32_bset_init(struct uint32_bset *bset) -{ - memset(bset, 0, sizeof(*bset)); -#ifdef DEBUGBUILD - bset->init = CURL_UINT32_BSET_MAGIC; -#endif -} - -CURLcode Curl_uint32_bset_resize(struct uint32_bset *bset, uint32_t nmax) -{ - uint32_t nslots = (nmax < (UINT32_MAX - 63)) ? - ((nmax + 63) / 64) : (UINT32_MAX / 64); - - DEBUGASSERT(bset->init == CURL_UINT32_BSET_MAGIC); - if(nslots != bset->nslots) { - uint64_t *slots = curlx_calloc(nslots, sizeof(uint64_t)); - if(!slots) - return CURLE_OUT_OF_MEMORY; - - if(bset->slots) { - memcpy(slots, bset->slots, - (CURLMIN(nslots, bset->nslots) * sizeof(uint64_t))); - curlx_free(bset->slots); - } - bset->slots = slots; - bset->nslots = nslots; - bset->first_slot_used = 0; - } - return CURLE_OK; -} - -void Curl_uint32_bset_destroy(struct uint32_bset *bset) -{ - DEBUGASSERT(bset->init == CURL_UINT32_BSET_MAGIC); - curlx_free(bset->slots); - memset(bset, 0, sizeof(*bset)); -} - -#ifdef UNITTESTS -/* @unittest 3211 */ -UNITTEST uint32_t uint32_bset_capacity(struct uint32_bset *bset); -UNITTEST uint32_t uint32_bset_capacity(struct uint32_bset *bset) -{ - return bset->nslots * 64; -} -#endif - -uint32_t Curl_uint32_bset_count(struct uint32_bset *bset) -{ - uint32_t i; - uint32_t n = 0; - for(i = 0; i < bset->nslots; ++i) { - if(bset->slots[i]) - n += CURL_POPCOUNT64(bset->slots[i]); - } - return n; -} - -bool Curl_uint32_bset_empty(struct uint32_bset *bset) -{ - uint32_t i; - for(i = bset->first_slot_used; i < bset->nslots; ++i) { - if(bset->slots[i]) - return FALSE; - } - return TRUE; -} - -void Curl_uint32_bset_clear(struct uint32_bset *bset) -{ - if(bset->nslots) { - memset(bset->slots, 0, bset->nslots * sizeof(uint64_t)); - bset->first_slot_used = UINT32_MAX; - } -} - -bool Curl_uint32_bset_add(struct uint32_bset *bset, uint32_t i) -{ - uint32_t islot = i / 64; - if(islot >= bset->nslots) - return FALSE; - bset->slots[islot] |= ((uint64_t)1 << (i % 64)); - if(islot < bset->first_slot_used) - bset->first_slot_used = islot; - return TRUE; -} - -void Curl_uint32_bset_remove(struct uint32_bset *bset, uint32_t i) -{ - size_t islot = i / 64; - if(islot < bset->nslots) - bset->slots[islot] &= ~((uint64_t)1 << (i % 64)); -} - -bool Curl_uint32_bset_contains(struct uint32_bset *bset, uint32_t i) -{ - uint32_t islot = i / 64; - if(islot >= bset->nslots) - return FALSE; - return (bset->slots[islot] & ((uint64_t)1 << (i % 64))) != 0; -} - -bool Curl_uint32_bset_first(struct uint32_bset *bset, uint32_t *pfirst) -{ - uint32_t i; - for(i = bset->first_slot_used; i < bset->nslots; ++i) { - if(bset->slots[i]) { - *pfirst = (i * 64) + CURL_CTZ64(bset->slots[i]); - bset->first_slot_used = i; - return TRUE; - } - } - bset->first_slot_used = *pfirst = UINT32_MAX; - return FALSE; -} - -bool Curl_uint32_bset_next(struct uint32_bset *bset, uint32_t last, - uint32_t *pnext) -{ - uint32_t islot; - uint64_t x; - - ++last; /* look for number one higher than last */ - islot = last / 64; /* the slot this would be in */ - if(islot < bset->nslots) { - /* shift away the bits we already iterated in this slot */ - x = (bset->slots[islot] >> (last % 64)); - if(x) { - /* more bits set, next is `last` + trailing0s of the shifted slot */ - *pnext = last + CURL_CTZ64(x); - return TRUE; - } - /* no more bits set in the last slot, scan forward */ - for(islot = islot + 1; islot < bset->nslots; ++islot) { - if(bset->slots[islot]) { - *pnext = (islot * 64) + CURL_CTZ64(bset->slots[islot]); - return TRUE; - } - } - } - *pnext = UINT32_MAX; /* a value we cannot store */ - return FALSE; -} - -#ifdef CURL_POPCOUNT64_IMPLEMENT -uint32_t Curl_popcount64(uint64_t x) -{ - /* Compute the "Hamming Distance" between 'x' and 0, - * which is the number of set bits in 'x'. - * See: https://en.wikipedia.org/wiki/Hamming_weight */ - const uint64_t m1 = 0x5555555555555555LL; /* 0101+ */ - const uint64_t m2 = 0x3333333333333333LL; /* 00110011+ */ - const uint64_t m4 = 0x0f0f0f0f0f0f0f0fLL; /* 00001111+ */ - /* 1 + 256^1 + 256^2 + 256^3 + ... + 256^7 */ - const uint64_t h01 = 0x0101010101010101LL; - x -= (x >> 1) & m1; /* replace every 2 bits with bits present */ - x = (x & m2) + ((x >> 2) & m2); /* replace every nibble with bits present */ - x = (x + (x >> 4)) & m4; /* replace every byte with bits present */ - /* top 8 bits of x + (x << 8) + (x << 16) + (x << 24) + ... which makes the - * top byte the sum of all individual 8 bytes, throw away the rest */ - return (uint32_t)((x * h01) >> 56); -} -#endif /* CURL_POPCOUNT64_IMPLEMENT */ - -#ifdef CURL_CTZ64_IMPLEMENT -uint32_t Curl_ctz64(uint64_t x) -{ - /* count trailing zeros in a uint64_t. - * divide and conquer to find the number of lower 0 bits */ - const uint64_t ml32 = 0xFFFFFFFF; /* lower 32 bits */ - const uint64_t ml16 = 0x0000FFFF; /* lower 16 bits */ - const uint64_t ml8 = 0x000000FF; /* lower 8 bits */ - const uint64_t ml4 = 0x0000000F; /* lower 4 bits */ - const uint64_t ml2 = 0x00000003; /* lower 2 bits */ - uint32_t n; - - if(!x) - return 64; - n = 1; - if(!(x & ml32)) { - n = n + 32; - x = x >> 32; - } - if(!(x & ml16)) { - n = n + 16; - x = x >> 16; - } - if(!(x & ml8)) { - n = n + 8; - x = x >> 8; - } - if(!(x & ml4)) { - n = n + 4; - x = x >> 4; - } - if(!(x & ml2)) { - n = n + 2; - x = x >> 2; - } - return n - (uint32_t)(x & 1); -} -#endif /* CURL_CTZ64_IMPLEMENT */ diff --git a/vendor/curl/lib/uint-bset.h b/vendor/curl/lib/uint-bset.h deleted file mode 100644 index ce0450c53..000000000 --- a/vendor/curl/lib/uint-bset.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef HEADER_CURL_UINT_BSET_H -#define HEADER_CURL_UINT_BSET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* A bitset for unsigned int values. - * It can hold the numbers from 0 - (nmax - 1), - * rounded to the next 64 multiple. - * - * Optimized for high efficiency in adding/removing numbers. - * Efficient storage when the set is (often) relatively full. - * - * If the set's cardinality is only expected to be a fraction of nmax, - * uint_spbset offers a "sparse" variant with more memory efficiency at - * the price of slightly slower operations. - */ - -struct uint32_bset { - uint64_t *slots; - uint32_t nslots; - uint32_t first_slot_used; -#ifdef DEBUGBUILD - int init; -#endif -}; - -/* Initialize the bitset with capacity 0. */ -void Curl_uint32_bset_init(struct uint32_bset *bset); - -/* Resize the bitset capacity to hold numbers from 0 to `nmax`, - * which rounds up `nmax` to the next multiple of 64. */ -CURLcode Curl_uint32_bset_resize(struct uint32_bset *bset, uint32_t nmax); - -/* Destroy the bitset, freeing all resources. */ -void Curl_uint32_bset_destroy(struct uint32_bset *bset); - -/* Get the cardinality of the bitset, e.g. numbers present in the set. */ -uint32_t Curl_uint32_bset_count(struct uint32_bset *bset); - -/* TRUE of bitset is empty */ -bool Curl_uint32_bset_empty(struct uint32_bset *bset); - -/* Clear the bitset, making it empty. */ -void Curl_uint32_bset_clear(struct uint32_bset *bset); - -/* Add the number `i` to the bitset. Return FALSE if the number is - * outside the set's capacity. - * Numbers can be added more than once, without making a difference. */ -bool Curl_uint32_bset_add(struct uint32_bset *bset, uint32_t i); - -/* Remove the number `i` from the bitset. */ -void Curl_uint32_bset_remove(struct uint32_bset *bset, uint32_t i); - -/* Return TRUE if the bitset contains number `i`. */ -bool Curl_uint32_bset_contains(struct uint32_bset *bset, uint32_t i); - -/* Get the first number in the bitset, e.g. the smallest. - * Returns FALSE when the bitset is empty. */ -bool Curl_uint32_bset_first(struct uint32_bset *bset, uint32_t *pfirst); - -/* Get the next number in the bitset, following `last` in natural order. - * Put another way, this is the smallest number greater than `last` in - * the bitset. `last` does not have to be present in the set. - * - * Returns FALSE when no such number is in the set. - * - * This allows to iterate the set while being modified: - * - added numbers higher than 'last' will be picked up by the iteration. - * - added numbers lower than 'last' will not show up. - * - removed numbers lower or equal to 'last' will not show up. - * - removed numbers higher than 'last' will not be visited. */ -bool Curl_uint32_bset_next(struct uint32_bset *bset, uint32_t last, - uint32_t *pnext); - -#ifndef CURL_POPCOUNT64 -#define CURL_POPCOUNT64(x) Curl_popcount64(x) -#define CURL_POPCOUNT64_IMPLEMENT -uint32_t Curl_popcount64(uint64_t x); -#endif /* !CURL_POPCOUNT64 */ - -#ifndef CURL_CTZ64 -#define CURL_CTZ64(x) Curl_ctz64(x) -#define CURL_CTZ64_IMPLEMENT -uint32_t Curl_ctz64(uint64_t x); -#endif /* !CURL_CTZ64 */ - -#endif /* HEADER_CURL_UINT_BSET_H */ diff --git a/vendor/curl/lib/uint-hash.c b/vendor/curl/lib/uint-hash.c deleted file mode 100644 index c37448fd1..000000000 --- a/vendor/curl/lib/uint-hash.c +++ /dev/null @@ -1,235 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "uint-hash.h" - -/* random patterns for API verification */ -#ifdef DEBUGBUILD -#define CURL_UINT32_HASHINIT 0x7117e779 -#endif - -static uint32_t uint32_hash_hash(uint32_t id, uint32_t slots) -{ - return (id % slots); -} - -struct uint_hash_entry { - struct uint_hash_entry *next; - void *value; - uint32_t id; -}; - -void Curl_uint32_hash_init(struct uint_hash *h, - uint32_t slots, - Curl_uint32_hash_dtor *dtor) -{ - DEBUGASSERT(h); - DEBUGASSERT(slots); - - h->table = NULL; - h->dtor = dtor; - h->size = 0; - h->slots = slots; -#ifdef DEBUGBUILD - h->init = CURL_UINT32_HASHINIT; -#endif -} - -static struct uint_hash_entry *uint32_hash_mk_entry(uint32_t id, void *value) -{ - struct uint_hash_entry *e; - - /* allocate the struct for the hash entry */ - e = curlx_malloc(sizeof(*e)); - if(e) { - e->id = id; - e->next = NULL; - e->value = value; - } - return e; -} - -static void uint32_hash_entry_clear(struct uint_hash *h, - struct uint_hash_entry *e) -{ - DEBUGASSERT(h); - DEBUGASSERT(e); - if(e->value) { - if(h->dtor) - h->dtor(e->id, e->value); - e->value = NULL; - } -} - -static void uint32_hash_entry_destroy(struct uint_hash *h, - struct uint_hash_entry *e) -{ - uint32_hash_entry_clear(h, e); - curlx_free(e); -} - -static void uint32_hash_entry_unlink(struct uint_hash *h, - struct uint_hash_entry **he_anchor, - struct uint_hash_entry *he) -{ - *he_anchor = he->next; - --h->size; -} - -static void uint32_hash_elem_link(struct uint_hash *h, - struct uint_hash_entry **he_anchor, - struct uint_hash_entry *he) -{ - he->next = *he_anchor; - *he_anchor = he; - ++h->size; -} - -#define CURL_UINT32_HASH_SLOT(h, id) h->table[uint32_hash_hash(id, (h)->slots)] -#define CURL_UINT32_HASH_SLOT_ADDR(h, id) &CURL_UINT32_HASH_SLOT(h, id) - -bool Curl_uint32_hash_set(struct uint_hash *h, uint32_t id, void *value) -{ - struct uint_hash_entry *he, **slot; - - DEBUGASSERT(h); - DEBUGASSERT(h->slots); - DEBUGASSERT(h->init == CURL_UINT32_HASHINIT); - if(!h->table) { - h->table = curlx_calloc(h->slots, sizeof(*he)); - if(!h->table) - return FALSE; /* OOM */ - } - - slot = CURL_UINT32_HASH_SLOT_ADDR(h, id); - for(he = *slot; he; he = he->next) { - if(he->id == id) { - /* existing key entry, overwrite by clearing old pointer */ - uint32_hash_entry_clear(h, he); - he->value = value; - return TRUE; - } - } - - he = uint32_hash_mk_entry(id, value); - if(!he) - return FALSE; /* OOM */ - - uint32_hash_elem_link(h, slot, he); - return TRUE; -} - -bool Curl_uint32_hash_remove(struct uint_hash *h, uint32_t id) -{ - DEBUGASSERT(h); - DEBUGASSERT(h->slots); - DEBUGASSERT(h->init == CURL_UINT32_HASHINIT); - if(h->table) { - struct uint_hash_entry *he, **he_anchor; - - he_anchor = CURL_UINT32_HASH_SLOT_ADDR(h, id); - while(*he_anchor) { - he = *he_anchor; - if(id == he->id) { - uint32_hash_entry_unlink(h, he_anchor, he); - uint32_hash_entry_destroy(h, he); - return TRUE; - } - he_anchor = &he->next; - } - } - return FALSE; -} - -void *Curl_uint32_hash_get(struct uint_hash *h, uint32_t id) -{ - DEBUGASSERT(h); - DEBUGASSERT(h->init == CURL_UINT32_HASHINIT); - if(h->table) { - struct uint_hash_entry *he; - DEBUGASSERT(h->slots); - he = CURL_UINT32_HASH_SLOT(h, id); - while(he) { - if(id == he->id) { - return he->value; - } - he = he->next; - } - } - return NULL; -} - -/* @unittest 1616 */ -UNITTEST void uint_hash_clear(struct uint_hash *h); -UNITTEST void uint_hash_clear(struct uint_hash *h) -{ - if(h && h->table) { - struct uint_hash_entry *he, **he_anchor; - size_t i; - DEBUGASSERT(h->init == CURL_UINT32_HASHINIT); - for(i = 0; i < h->slots; ++i) { - he_anchor = &h->table[i]; - while(*he_anchor) { - he = *he_anchor; - uint32_hash_entry_unlink(h, he_anchor, he); - uint32_hash_entry_destroy(h, he); - } - } - } -} - -void Curl_uint32_hash_destroy(struct uint_hash *h) -{ - DEBUGASSERT(h->init == CURL_UINT32_HASHINIT); - if(h->table) { - uint_hash_clear(h); - curlx_safefree(h->table); - } - DEBUGASSERT(h->size == 0); - h->slots = 0; -} - -uint32_t Curl_uint32_hash_count(struct uint_hash *h) -{ - DEBUGASSERT(h->init == CURL_UINT32_HASHINIT); - return h->size; -} - -void Curl_uint32_hash_visit(struct uint_hash *h, - Curl_uint32_hash_visit_cb *cb, - void *user_data) -{ - if(h && h->table && cb) { - struct uint_hash_entry *he; - size_t i; - DEBUGASSERT(h->init == CURL_UINT32_HASHINIT); - for(i = 0; i < h->slots; ++i) { - for(he = h->table[i]; he; he = he->next) { - if(!cb(he->id, he->value, user_data)) - return; - } - } - } -} diff --git a/vendor/curl/lib/uint-hash.h b/vendor/curl/lib/uint-hash.h deleted file mode 100644 index 3cbcf8f8f..000000000 --- a/vendor/curl/lib/uint-hash.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef HEADER_CURL_UINT_HASH_H -#define HEADER_CURL_UINT_HASH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* A version with uint32_t as key */ -typedef void Curl_uint32_hash_dtor(uint32_t id, void *value); -struct uint_hash_entry; - -/* Hash for `uint32_t` as key */ -struct uint_hash { - struct uint_hash_entry **table; - Curl_uint32_hash_dtor *dtor; - uint32_t slots; - uint32_t size; -#ifdef DEBUGBUILD - int init; -#endif -}; - -void Curl_uint32_hash_init(struct uint_hash *h, - uint32_t slots, - Curl_uint32_hash_dtor *dtor); -void Curl_uint32_hash_destroy(struct uint_hash *h); -bool Curl_uint32_hash_set(struct uint_hash *h, uint32_t id, void *value); -bool Curl_uint32_hash_remove(struct uint_hash *h, uint32_t id); -void *Curl_uint32_hash_get(struct uint_hash *h, uint32_t id); -uint32_t Curl_uint32_hash_count(struct uint_hash *h); - -typedef bool Curl_uint32_hash_visit_cb(uint32_t id, void *value, - void *user_data); - -void Curl_uint32_hash_visit(struct uint_hash *h, - Curl_uint32_hash_visit_cb *cb, - void *user_data); - -#endif /* HEADER_CURL_UINT_HASH_H */ diff --git a/vendor/curl/lib/uint-spbset.c b/vendor/curl/lib/uint-spbset.c deleted file mode 100644 index 3daa2eea7..000000000 --- a/vendor/curl/lib/uint-spbset.c +++ /dev/null @@ -1,253 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "uint-bset.h" -#include "uint-spbset.h" - -#ifdef DEBUGBUILD -#define CURL_UINT32_SPBSET_MAGIC 0x70737362 -#endif - -void Curl_uint32_spbset_init(struct uint32_spbset *bset) -{ - memset(bset, 0, sizeof(*bset)); -#ifdef DEBUGBUILD - bset->init = CURL_UINT32_SPBSET_MAGIC; -#endif -} - -/* Clear the bitset, making it empty. - - @unittest 3213 - */ -UNITTEST void uint32_spbset_clear(struct uint32_spbset *bset); -UNITTEST void uint32_spbset_clear(struct uint32_spbset *bset) -{ - struct uint32_spbset_chunk *next, *chunk; - - for(chunk = bset->head.next; chunk; chunk = next) { - next = chunk->next; - curlx_free(chunk); - } - memset(&bset->head, 0, sizeof(bset->head)); -} - -void Curl_uint32_spbset_destroy(struct uint32_spbset *bset) -{ - DEBUGASSERT(bset->init == CURL_UINT32_SPBSET_MAGIC); - uint32_spbset_clear(bset); -} - -uint32_t Curl_uint32_spbset_count(struct uint32_spbset *bset) -{ - struct uint32_spbset_chunk *chunk; - uint32_t i, n = 0; - - for(chunk = &bset->head; chunk; chunk = chunk->next) { - for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) { - if(chunk->slots[i]) - n += CURL_POPCOUNT64(chunk->slots[i]); - } - } - return n; -} - -static struct uint32_spbset_chunk *uint32_spbset_get_chunk( - struct uint32_spbset *bset, uint32_t i, bool grow) -{ - struct uint32_spbset_chunk *chunk, **panchor = NULL; - uint32_t i_offset = (i & ~CURL_UINT32_SPBSET_CH_MASK); - - if(!bset) - return NULL; - - for(chunk = &bset->head; chunk; - panchor = &chunk->next, chunk = chunk->next) { - if(chunk->offset == i_offset) { - return chunk; - } - else if(chunk->offset > i_offset) { - /* need new chunk here */ - chunk = NULL; - break; - } - } - - if(!grow) - return NULL; - - /* need a new one */ - chunk = curlx_calloc(1, sizeof(*chunk)); - if(!chunk) - return NULL; - - if(panchor) { /* insert between panchor and *panchor */ - chunk->next = *panchor; - *panchor = chunk; - } - else { /* prepend to head, switching places */ - memcpy(chunk, &bset->head, sizeof(*chunk)); - memset(&bset->head, 0, sizeof(bset->head)); - bset->head.next = chunk; - } - chunk->offset = i_offset; - return chunk; -} - -bool Curl_uint32_spbset_add(struct uint32_spbset *bset, uint32_t i) -{ - struct uint32_spbset_chunk *chunk; - uint32_t i_chunk; - - chunk = uint32_spbset_get_chunk(bset, i, TRUE); - if(!chunk) - return FALSE; - - DEBUGASSERT(i >= chunk->offset); - i_chunk = (i - chunk->offset); - DEBUGASSERT((i_chunk / 64) < CURL_UINT32_SPBSET_CH_SLOTS); - chunk->slots[(i_chunk / 64)] |= ((uint64_t)1 << (i_chunk % 64)); - return TRUE; -} - -void Curl_uint32_spbset_remove(struct uint32_spbset *bset, uint32_t i) -{ - struct uint32_spbset_chunk *chunk; - uint32_t i_chunk; - - chunk = uint32_spbset_get_chunk(bset, i, FALSE); - if(chunk) { - DEBUGASSERT(i >= chunk->offset); - i_chunk = (i - chunk->offset); - DEBUGASSERT((i_chunk / 64) < CURL_UINT32_SPBSET_CH_SLOTS); - chunk->slots[(i_chunk / 64)] &= ~((uint64_t)1 << (i_chunk % 64)); - } -} - -bool Curl_uint32_spbset_contains(struct uint32_spbset *bset, uint32_t i) -{ - struct uint32_spbset_chunk *chunk; - uint32_t i_chunk; - - chunk = uint32_spbset_get_chunk(bset, i, FALSE); - if(chunk) { - DEBUGASSERT(i >= chunk->offset); - i_chunk = (i - chunk->offset); - DEBUGASSERT((i_chunk / 64) < CURL_UINT32_SPBSET_CH_SLOTS); - return (chunk->slots[i_chunk / 64] & - ((uint64_t)1 << (i_chunk % 64))) != 0; - } - return FALSE; -} - -bool Curl_uint32_spbset_first(struct uint32_spbset *bset, uint32_t *pfirst) -{ - struct uint32_spbset_chunk *chunk; - uint32_t i; - - for(chunk = &bset->head; chunk; chunk = chunk->next) { - for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) { - if(chunk->slots[i]) { - *pfirst = chunk->offset + ((i * 64) + CURL_CTZ64(chunk->slots[i])); - return TRUE; - } - } - } - *pfirst = 0; /* give it a defined value even if it should not be used */ - return FALSE; -} - -static bool uint32_spbset_chunk_first(struct uint32_spbset_chunk *chunk, - uint32_t *pfirst) -{ - uint32_t i; - for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) { - if(chunk->slots[i]) { - *pfirst = chunk->offset + ((i * 64) + CURL_CTZ64(chunk->slots[i])); - return TRUE; - } - } - *pfirst = UINT32_MAX; /* a value we cannot store */ - return FALSE; -} - -static bool uint32_spbset_chunk_next(struct uint32_spbset_chunk *chunk, - uint32_t last, - uint32_t *pnext) -{ - if(chunk->offset <= last) { - uint64_t x; - uint32_t i = ((last - chunk->offset) / 64); - if(i < CURL_UINT32_SPBSET_CH_SLOTS) { - x = (chunk->slots[i] >> (last % 64)); - if(x) { - /* more bits set, next is `last` + trailing0s of the shifted slot */ - *pnext = last + CURL_CTZ64(x); - return TRUE; - } - /* no more bits set in the last slot, scan forward */ - for(i = i + 1; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) { - if(chunk->slots[i]) { - *pnext = chunk->offset + ((i * 64) + CURL_CTZ64(chunk->slots[i])); - return TRUE; - } - } - } - } - *pnext = UINT32_MAX; - return FALSE; -} - -bool Curl_uint32_spbset_next(struct uint32_spbset *bset, uint32_t last, - uint32_t *pnext) -{ - struct uint32_spbset_chunk *chunk; - uint32_t last_offset; - - ++last; /* look for the next higher number */ - last_offset = (last & ~CURL_UINT32_SPBSET_CH_MASK); - - for(chunk = &bset->head; chunk; chunk = chunk->next) { - if(chunk->offset >= last_offset) { - break; - } - } - - if(chunk && (chunk->offset == last_offset)) { - /* is there a number higher than last in this chunk? */ - if(uint32_spbset_chunk_next(chunk, last, pnext)) - return TRUE; - /* not in this chunk */ - chunk = chunk->next; - } - /* look for the first in the "higher" chunks, if there are any. */ - while(chunk) { - if(uint32_spbset_chunk_first(chunk, pnext)) - return TRUE; - chunk = chunk->next; - } - *pnext = UINT32_MAX; - return FALSE; -} diff --git a/vendor/curl/lib/uint-spbset.h b/vendor/curl/lib/uint-spbset.h deleted file mode 100644 index 4b105c02e..000000000 --- a/vendor/curl/lib/uint-spbset.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef HEADER_CURL_UINT_SPBSET_H -#define HEADER_CURL_UINT_SPBSET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* A "sparse" bitset for uint32_t values. - * It can hold any uint32_t value. - * - * Optimized for the case where only a small set of numbers need - * to be kept, especially when "close" together. Then storage space - * is most efficient, deteriorating when many number are far apart. - */ - -/* 4 slots = 256 bits, keep this a 2^n value. */ -#define CURL_UINT32_SPBSET_CH_SLOTS 4 -#define CURL_UINT32_SPBSET_CH_MASK ((CURL_UINT32_SPBSET_CH_SLOTS * 64) - 1) - -/* store the uint value from offset to - * (offset + (CURL_UINT32_SPBSET_CHUNK_SLOTS * 64) - 1 */ -struct uint32_spbset_chunk { - struct uint32_spbset_chunk *next; - uint64_t slots[CURL_UINT32_SPBSET_CH_SLOTS]; - uint32_t offset; -}; - -struct uint32_spbset { - struct uint32_spbset_chunk head; -#ifdef DEBUGBUILD - int init; -#endif -}; - -void Curl_uint32_spbset_init(struct uint32_spbset *bset); - -void Curl_uint32_spbset_destroy(struct uint32_spbset *bset); - -/* Get the cardinality of the bitset, e.g. numbers present in the set. */ -uint32_t Curl_uint32_spbset_count(struct uint32_spbset *bset); - -/* Add the number `i` to the bitset. - * Numbers can be added more than once, without making a difference. - * Returns FALSE if allocations failed. */ -bool Curl_uint32_spbset_add(struct uint32_spbset *bset, uint32_t i); - -/* Remove the number `i` from the bitset. */ -void Curl_uint32_spbset_remove(struct uint32_spbset *bset, uint32_t i); - -/* Return TRUE if the bitset contains number `i`. */ -bool Curl_uint32_spbset_contains(struct uint32_spbset *bset, uint32_t i); - -/* Get the first number in the bitset, e.g. the smallest. - * Returns FALSE when the bitset is empty. */ -bool Curl_uint32_spbset_first(struct uint32_spbset *bset, uint32_t *pfirst); - -/* Get the next number in the bitset, following `last` in natural order. - * Put another way, this is the smallest number greater than `last` in - * the bitset. `last` does not have to be present in the set. - * - * Returns FALSE when no such number is in the set. - * - * This allows to iterate the set while being modified: - * - added numbers higher than 'last' will be picked up by the iteration. - * - added numbers lower than 'last' will not show up. - * - removed numbers lower or equal to 'last' will not show up. - * - removed numbers higher than 'last' will not be visited. */ -bool Curl_uint32_spbset_next(struct uint32_spbset *bset, uint32_t last, - uint32_t *pnext); - -#endif /* HEADER_CURL_UINT_SPBSET_H */ diff --git a/vendor/curl/lib/uint-table.c b/vendor/curl/lib/uint-table.c deleted file mode 100644 index addd2c9cb..000000000 --- a/vendor/curl/lib/uint-table.c +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "uint-table.h" - -#ifdef DEBUGBUILD -#define CURL_UINT32_TBL_MAGIC 0x62757473 -#endif - -void Curl_uint32_tbl_init(struct uint32_tbl *tbl, - Curl_uint32_tbl_entry_dtor *entry_dtor) -{ - memset(tbl, 0, sizeof(*tbl)); - tbl->entry_dtor = entry_dtor; - tbl->last_key_added = UINT32_MAX; -#ifdef DEBUGBUILD - tbl->init = CURL_UINT32_TBL_MAGIC; -#endif -} - -static void uint32_tbl_clear_rows(struct uint32_tbl *tbl, - uint32_t from, - uint32_t upto_excluding) -{ - uint32_t i, end; - - end = CURLMIN(upto_excluding, tbl->nrows); - for(i = from; i < end; ++i) { - if(tbl->rows[i]) { - if(tbl->entry_dtor) - tbl->entry_dtor(i, tbl->rows[i]); - tbl->rows[i] = NULL; - tbl->nentries--; - } - } -} - -CURLcode Curl_uint32_tbl_resize(struct uint32_tbl *tbl, uint32_t nrows) -{ - /* we use `tbl->nrows + 1` during iteration, want that to work */ - DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC); - if(!nrows) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(nrows != tbl->nrows) { - void **rows = curlx_calloc(nrows, sizeof(void *)); - if(!rows) - return CURLE_OUT_OF_MEMORY; - if(tbl->rows) { - memcpy(rows, tbl->rows, (CURLMIN(nrows, tbl->nrows) * sizeof(void *))); - if(nrows < tbl->nrows) - uint32_tbl_clear_rows(tbl, nrows, tbl->nrows); - curlx_free(tbl->rows); - } - tbl->rows = rows; - tbl->nrows = nrows; - } - return CURLE_OK; -} - -/* Clear the table, making it empty. - - @unittest 3212 - */ -UNITTEST void uint32_tbl_clear(struct uint32_tbl *tbl); -UNITTEST void uint32_tbl_clear(struct uint32_tbl *tbl) -{ - DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC); - uint32_tbl_clear_rows(tbl, 0, tbl->nrows); - DEBUGASSERT(!tbl->nentries); - tbl->last_key_added = UINT32_MAX; -} - -void Curl_uint32_tbl_destroy(struct uint32_tbl *tbl) -{ - DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC); - uint32_tbl_clear(tbl); - curlx_free(tbl->rows); - memset(tbl, 0, sizeof(*tbl)); -} - -uint32_t Curl_uint32_tbl_capacity(struct uint32_tbl *tbl) -{ - return tbl->nrows; -} - -uint32_t Curl_uint32_tbl_count(struct uint32_tbl *tbl) -{ - return tbl->nentries; -} - -void *Curl_uint32_tbl_get(struct uint32_tbl *tbl, uint32_t key) -{ - return (key < tbl->nrows) ? tbl->rows[key] : NULL; -} - -bool Curl_uint32_tbl_add(struct uint32_tbl *tbl, void *entry, uint32_t *pkey) -{ - uint32_t key, start_pos; - - DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC); - if(!entry || !pkey) - return FALSE; - *pkey = UINT32_MAX; - if(tbl->nentries == tbl->nrows) /* full */ - return FALSE; - - start_pos = CURLMIN(tbl->last_key_added, tbl->nrows) + 1; - for(key = start_pos; key < tbl->nrows; ++key) { - if(!tbl->rows[key]) { - tbl->rows[key] = entry; - tbl->nentries++; - tbl->last_key_added = key; - *pkey = key; - return TRUE; - } - } - /* no free entry at or above tbl->maybe_next_key, wrap around */ - for(key = 0; key < start_pos; ++key) { - if(!tbl->rows[key]) { - tbl->rows[key] = entry; - tbl->nentries++; - tbl->last_key_added = key; - *pkey = key; - return TRUE; - } - } - /* Did not find any free row? Should not happen */ - DEBUGASSERT(0); - return FALSE; -} - -void Curl_uint32_tbl_remove(struct uint32_tbl *tbl, uint32_t key) -{ - uint32_tbl_clear_rows(tbl, key, key + 1); -} - -bool Curl_uint32_tbl_contains(struct uint32_tbl *tbl, uint32_t key) -{ - return (key < tbl->nrows) ? !!tbl->rows[key] : FALSE; -} - -static bool uint32_tbl_next_at(struct uint32_tbl *tbl, uint32_t key, - uint32_t *pkey, void **pentry) -{ - for(; key < tbl->nrows; ++key) { - if(tbl->rows[key]) { - *pkey = key; - *pentry = tbl->rows[key]; - return TRUE; - } - } - *pkey = UINT32_MAX; /* always invalid */ - *pentry = NULL; - return FALSE; -} - -bool Curl_uint32_tbl_first(struct uint32_tbl *tbl, - uint32_t *pkey, void **pentry) -{ - if(!pkey || !pentry) - return FALSE; - if(tbl->nentries && uint32_tbl_next_at(tbl, 0, pkey, pentry)) - return TRUE; - DEBUGASSERT(!tbl->nentries); - *pkey = UINT32_MAX; /* always invalid */ - *pentry = NULL; - return FALSE; -} - -bool Curl_uint32_tbl_next(struct uint32_tbl *tbl, uint32_t last_key, - uint32_t *pkey, void **pentry) -{ - if(!pkey || !pentry) - return FALSE; - if(uint32_tbl_next_at(tbl, last_key + 1, pkey, pentry)) - return TRUE; - *pkey = UINT32_MAX; /* always invalid */ - *pentry = NULL; - return FALSE; -} diff --git a/vendor/curl/lib/uint-table.h b/vendor/curl/lib/uint-table.h deleted file mode 100644 index 398a26a64..000000000 --- a/vendor/curl/lib/uint-table.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef HEADER_CURL_UINT_TABLE_H -#define HEADER_CURL_UINT_TABLE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* Destructor for a single table entry */ -typedef void Curl_uint32_tbl_entry_dtor(uint32_t key, void *entry); - -struct uint32_tbl { - void **rows; /* array of void* holding entries */ - Curl_uint32_tbl_entry_dtor *entry_dtor; - uint32_t nrows; /* length of `rows` array */ - uint32_t nentries; /* entries in table */ - uint32_t last_key_added; /* UINT_MAX or last key added */ -#ifdef DEBUGBUILD - int init; -#endif -}; - -/* Initialize the table with 0 capacity. - * The optional `entry_dtor` is called when a table entry is removed, - * Passing NULL means no action is taken on removal. */ -void Curl_uint32_tbl_init(struct uint32_tbl *tbl, - Curl_uint32_tbl_entry_dtor *entry_dtor); - -/* Resize the table to change capacity `nmax`. When `nmax` is reduced, - * all present entries with key equal or larger to `nmax` are removed. */ -CURLcode Curl_uint32_tbl_resize(struct uint32_tbl *tbl, uint32_t nrows); - -/* Destroy the table, freeing all entries. */ -void Curl_uint32_tbl_destroy(struct uint32_tbl *tbl); - -/* Get the table capacity. */ -uint32_t Curl_uint32_tbl_capacity(struct uint32_tbl *tbl); - -/* Get the number of entries in the table. */ -uint32_t Curl_uint32_tbl_count(struct uint32_tbl *tbl); - -/* Get the entry for key or NULL if not present */ -void *Curl_uint32_tbl_get(struct uint32_tbl *tbl, uint32_t key); - -/* Add a new entry to the table and assign it a free key. - * Returns FALSE if the table is full. - * - * Keys are assigned in a round-robin manner. - * No matter the capacity, UINT_MAX is never assigned. */ -bool Curl_uint32_tbl_add(struct uint32_tbl *tbl, void *entry, uint32_t *pkey); - -/* Remove the entry with `key`. */ -void Curl_uint32_tbl_remove(struct uint32_tbl *tbl, uint32_t key); - -/* Return TRUE if the table contains an tryn with that keys. */ -bool Curl_uint32_tbl_contains(struct uint32_tbl *tbl, uint32_t key); - -/* Get the first entry in the table (with the smallest `key`). - * Returns FALSE if the table is empty. */ -bool Curl_uint32_tbl_first(struct uint32_tbl *tbl, - uint32_t *pkey, void **pentry); - -/* Get the next key in the table, following `last_key` in natural order. - * Put another way, this is the smallest key greater than `last_key` in - * the table. `last_key` does not have to be present in the table. - * - * Returns FALSE when no such entry is in the table. - * - * This allows to iterate the table while being modified: - * - added keys higher than 'last_key' will be picked up by the iteration. - * - added keys lower than 'last_key' will not show up. - * - removed keys lower or equal to 'last_key' will not show up. - * - removed keys higher than 'last_key' will not be visited. */ -bool Curl_uint32_tbl_next(struct uint32_tbl *tbl, uint32_t last_key, - uint32_t *pkey, void **pentry); - -#endif /* HEADER_CURL_UINT_TABLE_H */ diff --git a/vendor/curl/lib/url.c b/vendor/curl/lib/url.c deleted file mode 100644 index 5fe68033d..000000000 --- a/vendor/curl/lib/url.c +++ /dev/null @@ -1,3633 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_IPHLPAPI_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_SYS_UN_H -#include -#endif - -#ifndef HAVE_SOCKET -#error "We cannot compile without socket() support!" -#endif - -#if defined(HAVE_IF_NAMETOINDEX) && defined(USE_WINSOCK) -#if defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR <= 5) -#include /* workaround for old mingw-w64 missing to include it */ -#endif -#include -#endif - -#include "urldata.h" -#include "mime.h" -#include "bufref.h" -#include "vtls/vtls.h" -#include "vssh/vssh.h" -#include "hostip.h" -#include "transfer.h" -#include "curl_addrinfo.h" -#include "curl_trc.h" -#include "progress.h" -#include "cookie.h" -#include "strcase.h" -#include "escape.h" -#include "curl_share.h" -#include "http_digest.h" -#include "multiif.h" -#include "getinfo.h" -#include "pop3.h" -#include "urlapi-int.h" -#include "system_win32.h" -#include "hsts.h" -#include "noproxy.h" -#include "cfilters.h" -#include "idn.h" -#include "http_proxy.h" -#include "conncache.h" -#include "multihandle.h" -#include "curlx/strdup.h" -#include "setopt.h" -#include "altsvc.h" -#include "curlx/dynbuf.h" -#include "headers.h" -#include "curlx/strerr.h" -#include "curlx/strparse.h" - -/* Now for the protocols */ -#include "ftp.h" -#include "dict.h" -#include "telnet.h" -#include "tftp.h" -#include "http.h" -#include "file.h" -#include "curl_ldap.h" -#include "vssh/ssh.h" -#include "imap.h" -#include "url.h" -#include "connect.h" -#include "gopher.h" -#include "mqtt.h" -#include "rtsp.h" -#include "smtp.h" -#include "ws.h" - -#ifdef USE_NGHTTP2 -static void data_priority_cleanup(struct Curl_easy *data); -#else -#define data_priority_cleanup(x) -#endif - -/* Some parts of the code (e.g. chunked encoding) assume this buffer has more - * than a few bytes to play with. Do not let it become too small or bad things - * will happen. - */ -#if READBUFFER_SIZE < READBUFFER_MIN -# error READBUFFER_SIZE is too small -#endif - -/* Reject URLs exceeding this length */ -#define MAX_URL_LEN 0xffff - -/* - * get_protocol_family() - * - * This is used to return the protocol family for a given protocol. - * - * Parameters: - * - * 's' [in] - struct Curl_scheme pointer. - * - * Returns the family as a single bit protocol identifier. - */ -static curl_prot_t get_protocol_family(const struct Curl_scheme *s) -{ - DEBUGASSERT(s); - DEBUGASSERT(s->family); - return s->family; -} - -void Curl_freeset(struct Curl_easy *data) -{ - /* Free all dynamic strings stored in the data->set substructure. */ - enum dupstring i; - enum dupblob j; - - for(i = (enum dupstring)0; i < STRING_LAST; i++) { - curlx_safefree(data->set.str[i]); - } - - for(j = (enum dupblob)0; j < BLOB_LAST; j++) { - curlx_safefree(data->set.blobs[j]); - } - - Curl_bufref_free(&data->state.referer); - Curl_bufref_free(&data->state.url); - -#if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) - Curl_mime_cleanpart(data->set.mimepostp); - curlx_safefree(data->set.mimepostp); -#endif - -#ifndef CURL_DISABLE_COOKIES - curl_slist_free_all(data->state.cookielist); - data->state.cookielist = NULL; -#endif -} - -/* free the URL pieces */ -static void up_free(struct Curl_easy *data) -{ - struct urlpieces *up = &data->state.up; - curlx_safefree(up->scheme); - curlx_safefree(up->hostname); - curlx_safefree(up->port); - curlx_safefree(up->user); - curlx_safefree(up->password); - curlx_safefree(up->options); - curlx_safefree(up->path); - curlx_safefree(up->query); - curl_url_cleanup(data->state.uh); - data->state.uh = NULL; -} - -/* - * This is the internal function curl_easy_cleanup() calls. This should - * cleanup and free all resources associated with this sessionhandle. - * - * We ignore SIGPIPE when this is called from curl_easy_cleanup. - */ - -CURLcode Curl_close(struct Curl_easy **datap) -{ - struct Curl_easy *data; - - if(!datap || !*datap) - return CURLE_OK; - - data = *datap; - *datap = NULL; - - if(!data->state.internal && data->multi) { - /* This handle is still part of a multi handle, take care of this first - and detach this handle from there. - This detaches the connection. */ - curl_multi_remove_handle(data->multi, data); - } - else { - /* Detach connection if any is left. This should not be normal, but can be - the case for example with CONNECT_ONLY + recv/send (test 556) */ - Curl_detach_connection(data); - if(!data->state.internal && data->multi_easy) { - /* when curl_easy_perform() is used, it creates its own multi handle to - use and this is the one */ - curl_multi_cleanup(data->multi_easy); - data->multi_easy = NULL; - } - } - DEBUGASSERT(!data->conn || data->state.internal); - - Curl_expire_clear(data); /* shut off any timers left */ - - if(data->state.rangestringalloc) - curlx_free(data->state.range); - - /* release any resolve information this transfer kept */ - Curl_resolv_destroy_all(data); - - data->set.verbose = FALSE; /* no more calls to DEBUGFUNCTION */ - data->magic = 0; /* force a clear AFTER the possibly enforced removal from - * the multi handle and async dns shutdown. The multi - * handle might check the magic and so might any - * DEBUGFUNCTION invoked for tracing */ - - /* freed here in case DONE was not called */ - Curl_req_free(&data->req, data); - - /* Close down all open SSL info and sessions */ - Curl_ssl_close_all(data); - curlx_safefree(data->state.first_host); - Curl_ssl_free_certinfo(data); - - Curl_bufref_free(&data->state.referer); - - up_free(data); - curlx_dyn_free(&data->state.headerb); - Curl_flush_cookies(data, TRUE); -#ifndef CURL_DISABLE_ALTSVC - Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]); - Curl_altsvc_cleanup(&data->asi); -#endif -#ifndef CURL_DISABLE_HSTS - Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]); - if(!data->share || !data->share->hsts) - Curl_hsts_cleanup(&data->hsts); - curl_slist_free_all(data->state.hstslist); /* clean up list */ -#endif -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) - Curl_http_auth_cleanup_digest(data); -#endif - curlx_safefree(data->state.most_recent_ftp_entrypath); - curlx_safefree(data->info.contenttype); - curlx_safefree(data->info.wouldredirect); - - data_priority_cleanup(data); - - /* No longer a dirty share, if it exists */ - if(Curl_share_easy_unlink(data)) - DEBUGASSERT(0); - - Curl_hash_destroy(&data->meta_hash); - curlx_safefree(data->state.aptr.uagent); - curlx_safefree(data->state.aptr.accept_encoding); - curlx_safefree(data->state.aptr.rangeline); - curlx_safefree(data->state.aptr.ref); - curlx_safefree(data->state.aptr.host); -#ifndef CURL_DISABLE_COOKIES - curlx_safefree(data->req.cookiehost); -#endif -#ifndef CURL_DISABLE_RTSP - curlx_safefree(data->state.aptr.rtsp_transport); -#endif - curlx_safefree(data->state.aptr.user); - curlx_safefree(data->state.aptr.passwd); -#ifndef CURL_DISABLE_PROXY - curlx_safefree(data->state.aptr.proxyuser); - curlx_safefree(data->state.aptr.proxypasswd); -#endif - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API) - Curl_mime_cleanpart(data->state.formp); - curlx_safefree(data->state.formp); -#endif - - /* destruct wildcard structures if it is needed */ - Curl_wildcard_dtor(&data->wildcard); - Curl_freeset(data); - Curl_headers_cleanup(data); - Curl_netrc_cleanup(&data->state.netrc); - curlx_free(data); - return CURLE_OK; -} - -/* - * Initialize the UserDefined fields within a Curl_easy. - * This may be safely called on a new or existing Curl_easy. - */ -void Curl_init_userdefined(struct Curl_easy *data) -{ - struct UserDefined *set = &data->set; - - set->out = stdout; /* default output to stdout */ - set->in_set = stdin; /* default input from stdin */ - set->err = stderr; /* default stderr to stderr */ - -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - /* use fwrite as default function to store output */ - set->fwrite_func = (curl_write_callback)fwrite; - - /* use fread as default function to read input */ - set->fread_func_set = (curl_read_callback)fread; -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - set->is_fread_set = 0; - - set->seek_client = ZERO_NULL; - - set->filesize = -1; /* we do not know the size */ - set->postfieldsize = -1; /* unknown size */ - set->maxredirs = 30; /* sensible default */ - - set->method = HTTPREQ_GET; /* Default HTTP request */ -#ifndef CURL_DISABLE_RTSP - set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ -#endif -#ifndef CURL_DISABLE_FTP - set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ - set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ - set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ - set->ftp_filemethod = FTPFILE_MULTICWD; - set->ftp_skip_ip = TRUE; /* skip PASV IP by default */ -#endif - set->dns_cache_timeout_ms = 60000; /* Timeout every 60 seconds by default */ - - /* Timeout every 24 hours by default */ - set->general_ssl.ca_cache_timeout = 24 * 60 * 60; - - set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ - -#ifndef CURL_DISABLE_PROXY - set->proxyport = 0; - set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ - set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ - /* SOCKS5 proxy auth defaults to username/password + GSS-API */ - set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI; -#endif - - Curl_ssl_easy_config_init(data); -#ifndef CURL_DISABLE_DOH - set->doh_verifyhost = TRUE; - set->doh_verifypeer = TRUE; -#endif -#ifdef USE_SSH - /* defaults to any auth type */ - set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; - set->new_directory_perms = 0755; /* Default permissions */ -#endif - - set->new_file_perms = 0644; /* Default permissions */ - set->allowed_protocols = (curl_prot_t)CURLPROTO_64ALL; - set->redir_protocols = CURLPROTO_REDIR; - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - /* - * disallow unprotected protection negotiation NEC reference implementation - * seem not to follow rfc1961 section 4.3/4.4 - */ - set->socks5_gssapi_nec = FALSE; -#endif - - /* set default minimum TLS version */ -#ifdef USE_SSL - Curl_setopt_SSLVERSION(data, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT); -#ifndef CURL_DISABLE_PROXY - Curl_setopt_SSLVERSION(data, CURLOPT_PROXY_SSLVERSION, - CURL_SSLVERSION_DEFAULT); -#endif -#endif -#ifndef CURL_DISABLE_FTP - set->wildcard_enabled = FALSE; - set->chunk_bgn = ZERO_NULL; - set->chunk_end = ZERO_NULL; - set->fnmatch = ZERO_NULL; -#endif - set->tcp_keepalive = FALSE; - set->tcp_keepintvl = 60; - set->tcp_keepidle = 60; - set->tcp_keepcnt = 9; - set->tcp_fastopen = FALSE; - set->tcp_nodelay = TRUE; - set->ssl_enable_alpn = TRUE; - set->expect_100_timeout = 1000L; /* Wait for a second by default. */ - set->sep_headers = TRUE; /* separated header lists by default */ - set->buffer_size = READBUFFER_SIZE; - set->upload_buffer_size = UPLOADBUFFER_DEFAULT; - set->upload_flags = CURLULFLAG_SEEN; - set->happy_eyeballs_timeout = CURL_HET_DEFAULT; - set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT; - set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ - set->conn_max_idle_ms = 118 * 1000; - set->conn_max_age_ms = 24 * 3600 * 1000; - set->http09_allowed = FALSE; - set->httpwant = CURL_HTTP_VERSION_NONE; -#if defined(USE_HTTP2) || defined(USE_HTTP3) - memset(&set->priority, 0, sizeof(set->priority)); -#endif - set->quick_exit = 0L; -#ifndef CURL_DISABLE_WEBSOCKETS - set->ws_raw_mode = FALSE; - set->ws_no_auto_pong = FALSE; -#endif -} - -/* easy->meta_hash destructor. Should never be called as elements - * MUST be added with their own destructor */ -static void easy_meta_freeentry(void *p) -{ - (void)p; - /* Always FALSE. Cannot use a 0 assert here since compilers - * are not in agreement if they then want a NORETURN attribute or - * not. *sigh* */ - DEBUGASSERT(p == NULL); -} - -/** - * Curl_open() - * - * @param curl is a pointer to a sessionhandle pointer that gets set by this - * function. - * @return CURLcode - */ - -CURLcode Curl_open(struct Curl_easy **curl) -{ - struct Curl_easy *data; - - /* simple start-up: alloc the struct, init it with zeroes and return */ - data = curlx_calloc(1, sizeof(struct Curl_easy)); - if(!data) { - /* this is a serious error */ - DEBUGF(curl_mfprintf(stderr, "Error: calloc of Curl_easy failed\n")); - return CURLE_OUT_OF_MEMORY; - } - - data->magic = CURLEASY_MAGIC_NUMBER; - /* most recent connection is not yet defined */ - data->state.lastconnect_id = -1; - data->state.recent_conn_id = -1; - /* and not assigned an id yet */ - data->id = -1; - data->mid = UINT32_MAX; - data->master_mid = UINT32_MAX; - data->progress.hide = TRUE; - data->state.current_speed = -1; /* init to negative == impossible */ - - Curl_hash_init(&data->meta_hash, 23, - Curl_hash_str, curlx_str_key_compare, easy_meta_freeentry); - curlx_dyn_init(&data->state.headerb, CURL_MAX_HTTP_HEADER); - Curl_bufref_init(&data->state.url); - Curl_bufref_init(&data->state.referer); - Curl_req_init(&data->req); - Curl_initinfo(data); -#ifndef CURL_DISABLE_HTTP - Curl_llist_init(&data->state.httphdrs, NULL); -#endif - Curl_netrc_init(&data->state.netrc); - Curl_init_userdefined(data); - - *curl = data; - return CURLE_OK; -} - -void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn) -{ - size_t i; - - DEBUGASSERT(conn); - - if(conn->scheme && conn->scheme->run->disconnect && - !conn->bits.shutdown_handler) - conn->scheme->run->disconnect(data, conn, TRUE); - - for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) { - Curl_conn_cf_discard_all(data, conn, (int)i); - } - - Curl_free_idnconverted_hostname(&conn->host); - Curl_free_idnconverted_hostname(&conn->conn_to_host); -#ifndef CURL_DISABLE_PROXY - Curl_free_idnconverted_hostname(&conn->http_proxy.host); - Curl_free_idnconverted_hostname(&conn->socks_proxy.host); - curlx_safefree(conn->http_proxy.user); - curlx_safefree(conn->socks_proxy.user); - curlx_safefree(conn->http_proxy.passwd); - curlx_safefree(conn->socks_proxy.passwd); - curlx_safefree(conn->http_proxy.host.rawalloc); /* http proxy name */ - curlx_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name */ -#endif - curlx_safefree(conn->user); - curlx_safefree(conn->passwd); - curlx_safefree(conn->sasl_authzid); - curlx_safefree(conn->options); - curlx_safefree(conn->oauth_bearer); - curlx_safefree(conn->host.rawalloc); /* hostname buffer */ - curlx_safefree(conn->conn_to_host.rawalloc); /* hostname buffer */ - curlx_safefree(conn->secondaryhostname); - curlx_safefree(conn->localdev); - Curl_ssl_conn_config_cleanup(conn); - -#ifdef USE_UNIX_SOCKETS - curlx_safefree(conn->unix_domain_socket); -#endif - curlx_safefree(conn->destination); - Curl_hash_destroy(&conn->meta_hash); - - curlx_free(conn); /* free all the connection oriented data */ -} - -/* - * xfer_may_multiplex() - * - * Return a TRUE, iff the transfer can be done over an (appropriate) - * multiplexed connection. - */ -static bool xfer_may_multiplex(const struct Curl_easy *data, - const struct connectdata *conn) -{ -#ifndef CURL_DISABLE_HTTP - /* If an HTTP protocol and multiplexing is enabled */ - if((conn->scheme->protocol & PROTO_FAMILY_HTTP) && - (!conn->bits.protoconnstart || !conn->bits.close)) { - - if(Curl_multiplex_wanted(data->multi) && - (data->state.http_neg.allowed & (CURL_HTTP_V2x | CURL_HTTP_V3x))) - /* allows HTTP/2 or newer */ - return TRUE; - } -#else - (void)data; - (void)conn; -#endif - return FALSE; -} - -#ifndef CURL_DISABLE_PROXY -static bool proxy_info_matches(const struct proxy_info *data, - const struct proxy_info *needle) -{ - if((data->proxytype == needle->proxytype) && - (data->port == needle->port) && - curl_strequal(data->host.name, needle->host.name)) { - - if(Curl_timestrcmp(data->user, needle->user) || - Curl_timestrcmp(data->passwd, needle->passwd)) - return FALSE; - return TRUE; - } - return FALSE; -} -#endif - -/* A connection has to have been idle for less than 'conn_max_idle_ms' - (the success rate is too low after this), or created less than - 'conn_max_age_ms' ago, to be subject for reuse. */ -static bool conn_maxage(struct Curl_easy *data, - struct connectdata *conn, - struct curltime now) -{ - timediff_t age_ms; - - if(data->set.conn_max_idle_ms) { - age_ms = curlx_ptimediff_ms(&now, &conn->lastused); - if(age_ms > data->set.conn_max_idle_ms) { - infof(data, "Too old connection (%" FMT_TIMEDIFF_T - " ms idle, max idle is %" FMT_TIMEDIFF_T " ms), disconnect it", - age_ms, data->set.conn_max_idle_ms); - return TRUE; - } - } - - if(data->set.conn_max_age_ms) { - age_ms = curlx_ptimediff_ms(&now, &conn->created); - if(age_ms > data->set.conn_max_age_ms) { - infof(data, - "Too old connection (created %" FMT_TIMEDIFF_T - " ms ago, max lifetime is %" FMT_TIMEDIFF_T " ms), disconnect it", - age_ms, data->set.conn_max_age_ms); - return TRUE; - } - } - - return FALSE; -} - -/* - * Return TRUE iff the given connection is considered dead. - */ -bool Curl_conn_seems_dead(struct connectdata *conn, - struct Curl_easy *data) -{ - DEBUGASSERT(!data->conn); - if(!CONN_INUSE(conn)) { - /* The check for a dead socket makes sense only if the connection is not in - use */ - bool dead; - - if(conn_maxage(data, conn, *Curl_pgrs_now(data))) { - /* avoid check if already too old */ - dead = TRUE; - } - else if(conn->scheme->run->connection_is_dead) { - /* The protocol has a special method for checking the state of the - connection. Use it to check if the connection is dead. */ - /* briefly attach the connection for the check */ - Curl_attach_connection(data, conn); - dead = conn->scheme->run->connection_is_dead(data, conn); - Curl_detach_connection(data); - } - else { - bool input_pending = FALSE; - - Curl_attach_connection(data, conn); - dead = !Curl_conn_is_alive(data, conn, &input_pending); - if(input_pending) { - /* For reuse, we want a "clean" connection state. The includes - * that we expect - in general - no waiting input data. Input - * waiting might be a TLS Notify Close, for example. We reject - * that. - * For protocols where data from other end may arrive at - * any time (HTTP/2 PING for example), the protocol handler needs - * to install its own `connection_check` callback. - */ - DEBUGF(infof(data, "connection has input pending, not reusable")); - dead = TRUE; - } - Curl_detach_connection(data); - } - - if(dead) { - /* remove connection from cpool */ - infof(data, "Connection %" FMT_OFF_T " seems to be dead", - conn->connection_id); - return TRUE; - } - } - return FALSE; -} - -CURLcode Curl_conn_upkeep(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - if(curlx_ptimediff_ms(Curl_pgrs_now(data), &conn->keepalive) <= - data->set.upkeep_interval_ms) - return result; - - /* briefly attach for action */ - Curl_attach_connection(data, conn); - result = Curl_conn_keep_alive(data, conn, FIRSTSOCKET); - Curl_detach_connection(data); - - conn->keepalive = *Curl_pgrs_now(data); - return result; -} - -#ifdef USE_SSH -static bool ssh_config_matches(struct connectdata *one, - struct connectdata *two) -{ - struct ssh_conn *sshc1, *sshc2; - - sshc1 = Curl_conn_meta_get(one, CURL_META_SSH_CONN); - sshc2 = Curl_conn_meta_get(two, CURL_META_SSH_CONN); - return sshc1 && sshc2 && Curl_safecmp(sshc1->rsa, sshc2->rsa) && - Curl_safecmp(sshc1->rsa_pub, sshc2->rsa_pub); -} -#endif - -struct url_conn_match { - struct connectdata *found; - struct Curl_easy *data; - struct connectdata *needle; - BIT(may_multiplex); - BIT(want_ntlm_http); - BIT(want_proxy_ntlm_http); - BIT(want_nego_http); - BIT(want_proxy_nego_http); - BIT(req_tls); /* require TLS use from a clear-text start */ - BIT(wait_pipe); - BIT(force_reuse); - BIT(seen_pending_conn); - BIT(seen_single_use_conn); - BIT(seen_multiplex_conn); -}; - -static bool url_match_connect_config(struct connectdata *conn, - struct url_conn_match *m) -{ - /* connect-only or to-be-closed connections will not be reused */ - if(conn->bits.connect_only || conn->bits.close || conn->bits.no_reuse) - return FALSE; - - /* ip_version must match */ - if(m->data->set.ipver != CURL_IPRESOLVE_WHATEVER && - m->data->set.ipver != conn->ip_version) - return FALSE; - - if(m->needle->localdev || m->needle->localport) { - /* If we are bound to a specific local end (IP+port), we must not reuse a - random other one, although if we did not ask for a particular one we - can reuse one that was bound. - - This comparison is a bit rough and too strict. Since the input - parameters can be specified in numerous ways and still end up the same - it would take a lot of processing to make it really accurate. Instead, - this matching will assume that reuses of bound connections will most - likely also reuse the exact same binding parameters and missing out a - few edge cases should not hurt anyone much. - */ - if((conn->localport != m->needle->localport) || - (conn->localportrange != m->needle->localportrange) || - (m->needle->localdev && - (!conn->localdev || strcmp(conn->localdev, m->needle->localdev)))) - return FALSE; - } - - if(m->needle->bits.conn_to_host != conn->bits.conn_to_host) - /* do not mix connections that use the "connect to host" feature and - * connections that do not use this feature */ - return FALSE; - - if(m->needle->bits.conn_to_port != conn->bits.conn_to_port) - /* do not mix connections that use the "connect to port" feature and - * connections that do not use this feature */ - return FALSE; - - /* Does `conn` use the correct protocol? */ -#ifdef USE_UNIX_SOCKETS - if(m->needle->unix_domain_socket) { - if(!conn->unix_domain_socket) - return FALSE; - if(strcmp(m->needle->unix_domain_socket, conn->unix_domain_socket)) - return FALSE; - if(m->needle->bits.abstract_unix_socket != conn->bits.abstract_unix_socket) - return FALSE; - } - else if(conn->unix_domain_socket) - return FALSE; -#endif - - return TRUE; -} - -static bool url_match_fully_connected(struct connectdata *conn, - struct url_conn_match *m) -{ - if(!Curl_conn_is_connected(conn, FIRSTSOCKET) || - conn->bits.upgrade_in_progress) { - /* Not yet connected, or a protocol upgrade is in progress. The later - * happens for HTTP/2 Upgrade: requests that need a response. */ - if(m->may_multiplex) { - m->seen_pending_conn = TRUE; - /* Do not pick a connection that has not connected yet */ - infof(m->data, "Connection #%" FMT_OFF_T - " is not open enough, cannot reuse", conn->connection_id); - } - /* Do not pick a connection that has not connected yet */ - return FALSE; - } - return TRUE; -} - -static bool url_match_multi(struct connectdata *conn, - struct url_conn_match *m) -{ - if(CONN_INUSE(conn)) { - DEBUGASSERT(conn->attached_multi); - if(conn->attached_multi != m->data->multi) - return FALSE; - } - return TRUE; -} - -static bool url_match_multiplex_needs(struct connectdata *conn, - struct url_conn_match *m) -{ - if(CONN_INUSE(conn)) { - if(!conn->bits.multiplex) { - /* conn busy and conn cannot take more transfers */ - m->seen_single_use_conn = TRUE; - return FALSE; - } - m->seen_multiplex_conn = TRUE; - if(!m->may_multiplex || !url_match_multi(conn, m)) - /* conn busy and transfer cannot be multiplexed */ - return FALSE; - } - return TRUE; -} - -static bool url_match_multiplex_limits(struct connectdata *conn, - struct url_conn_match *m) -{ - if(CONN_INUSE(conn) && m->may_multiplex) { - DEBUGASSERT(conn->bits.multiplex); - /* If multiplexed, make sure we do not go over concurrency limit */ - if(conn->attached_xfers >= - Curl_multi_max_concurrent_streams(m->data->multi)) { - infof(m->data, "client side MAX_CONCURRENT_STREAMS reached" - ", skip (%u)", conn->attached_xfers); - return FALSE; - } - if(conn->attached_xfers >= - Curl_conn_get_max_concurrent(m->data, conn, FIRSTSOCKET)) { - infof(m->data, "MAX_CONCURRENT_STREAMS reached, skip (%u)", - conn->attached_xfers); - return FALSE; - } - /* When not multiplexed, we have a match here! */ - infof(m->data, "Multiplexed connection found"); - } - return TRUE; -} - -static bool url_match_ssl_use(struct connectdata *conn, - struct url_conn_match *m) -{ - if(m->needle->scheme->flags & PROTOPT_SSL) { - /* We are looking for SSL, if `conn` does not do it, not a match. */ - if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) - return FALSE; - } - else if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - /* If the protocol does not allow reuse of SSL connections OR - is of another protocol family, not a match. */ - if(!(m->needle->scheme->flags & PROTOPT_SSL_REUSE) || - (get_protocol_family(conn->scheme) != m->needle->scheme->protocol)) - return FALSE; - } - else if(m->req_tls) - /* a clear-text STARTTLS protocol with required TLS */ - return FALSE; - return TRUE; -} - -#ifndef CURL_DISABLE_PROXY -static bool url_match_proxy_use(struct connectdata *conn, - struct url_conn_match *m) -{ - if(m->needle->bits.httpproxy != conn->bits.httpproxy || - m->needle->bits.socksproxy != conn->bits.socksproxy) - return FALSE; - - if(m->needle->bits.socksproxy && - !proxy_info_matches(&m->needle->socks_proxy, &conn->socks_proxy)) - return FALSE; - - if(m->needle->bits.httpproxy) { - if(m->needle->bits.tunnel_proxy != conn->bits.tunnel_proxy) - return FALSE; - - if(!proxy_info_matches(&m->needle->http_proxy, &conn->http_proxy)) - return FALSE; - - if(IS_HTTPS_PROXY(m->needle->http_proxy.proxytype)) { - /* https proxies come in different types, http/1.1, h2, ... */ - if(m->needle->http_proxy.proxytype != conn->http_proxy.proxytype) - return FALSE; - /* match SSL config to proxy */ - if(!Curl_ssl_conn_config_match(m->data, conn, TRUE)) { - DEBUGF(infof(m->data, - "Connection #%" FMT_OFF_T - " has different SSL proxy parameters, cannot reuse", - conn->connection_id)); - return FALSE; - } - /* the SSL config to the server, which may apply here is checked - * further below */ - } - } - return TRUE; -} -#else -#define url_match_proxy_use(c, m) ((void)(c), (void)(m), TRUE) -#endif - -#ifndef CURL_DISABLE_HTTP -static bool url_match_http_multiplex(struct connectdata *conn, - struct url_conn_match *m) -{ - if(m->may_multiplex && - (m->data->state.http_neg.allowed & (CURL_HTTP_V2x | CURL_HTTP_V3x)) && - (m->needle->scheme->protocol & CURLPROTO_HTTP) && - !conn->httpversion_seen) { - if(m->data->set.pipewait) { - infof(m->data, "Server upgrade does not support multiplex yet, wait"); - m->found = NULL; - m->wait_pipe = TRUE; - return TRUE; /* stop searching, we want to wait */ - } - infof(m->data, "Server upgrade cannot be used"); - return FALSE; - } - return TRUE; -} - -static bool url_match_http_version(struct connectdata *conn, - struct url_conn_match *m) -{ - /* If looking for HTTP and the HTTP versions allowed do not include - * the HTTP version of conn, continue looking. */ - if((m->needle->scheme->protocol & PROTO_FAMILY_HTTP)) { - switch(Curl_conn_http_version(m->data, conn)) { - case 30: - if(!(m->data->state.http_neg.allowed & CURL_HTTP_V3x)) { - DEBUGF(infof(m->data, "not reusing conn #%" CURL_FORMAT_CURL_OFF_T - ", we do not want h3", conn->connection_id)); - return FALSE; - } - break; - case 20: - if(!(m->data->state.http_neg.allowed & CURL_HTTP_V2x)) { - DEBUGF(infof(m->data, "not reusing conn #%" CURL_FORMAT_CURL_OFF_T - ", we do not want h2", conn->connection_id)); - return FALSE; - } - break; - default: - if(!(m->data->state.http_neg.allowed & CURL_HTTP_V1x)) { - DEBUGF(infof(m->data, "not reusing conn #%" CURL_FORMAT_CURL_OFF_T - ", we do not want h1", conn->connection_id)); - return FALSE; - } - break; - } - } - return TRUE; -} -#else -#define url_match_http_multiplex(c, m) ((void)(c), (void)(m), TRUE) -#define url_match_http_version(c, m) ((void)(c), (void)(m), TRUE) -#endif - -static bool url_match_proto_config(struct connectdata *conn, - struct url_conn_match *m) -{ - if(!url_match_http_version(conn, m)) - return FALSE; - -#ifdef USE_SSH - if(get_protocol_family(m->needle->scheme) & PROTO_FAMILY_SSH) { - if(!ssh_config_matches(m->needle, conn)) - return FALSE; - } -#endif -#ifndef CURL_DISABLE_FTP - else if(get_protocol_family(m->needle->scheme) & PROTO_FAMILY_FTP) { - if(!ftp_conns_match(m->needle, conn)) - return FALSE; - } -#endif - return TRUE; -} - -static bool url_match_auth(struct connectdata *conn, - struct url_conn_match *m) -{ - if(!(m->needle->scheme->flags & PROTOPT_CREDSPERREQUEST)) { - /* This protocol requires credentials per connection, - so verify that we are using the same name and password as well */ - if(Curl_timestrcmp(m->needle->user, conn->user) || - Curl_timestrcmp(m->needle->passwd, conn->passwd) || - Curl_timestrcmp(m->needle->sasl_authzid, conn->sasl_authzid) || - Curl_timestrcmp(m->needle->oauth_bearer, conn->oauth_bearer)) { - /* one of them was different */ - return FALSE; - } - } -#ifdef HAVE_GSSAPI - /* GSS delegation differences do not actually affect every connection - and auth method, but this check takes precaution before efficiency */ - if(m->needle->gssapi_delegation != conn->gssapi_delegation) - return FALSE; -#endif - - return TRUE; -} - -static bool url_match_destination(struct connectdata *conn, - struct url_conn_match *m) -{ - /* Additional match requirements if talking TLS OR - * not talking to an HTTP proxy OR using a tunnel through a proxy */ - if((m->needle->scheme->flags & PROTOPT_SSL) -#ifndef CURL_DISABLE_PROXY - || !m->needle->bits.httpproxy || m->needle->bits.tunnel_proxy -#endif - ) { - if(!curl_strequal(m->needle->scheme->name, conn->scheme->name)) { - /* `needle` and `conn` do not have the same scheme... */ - if(get_protocol_family(conn->scheme) != m->needle->scheme->protocol) { - /* and `conn`s protocol family is not the protocol `needle` wants. - * IMAPS would work for IMAP, but no vice versa. */ - return FALSE; - } - /* We are in an IMAPS vs IMAP like case. We expect `conn` to have SSL */ - if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) { - DEBUGF(infof(m->data, "Connection #%" FMT_OFF_T - " has compatible protocol family, but no SSL, no match", - conn->connection_id)); - return FALSE; - } - } - - /* If needle has "conn_to_*" set, conn must match this */ - if((m->needle->bits.conn_to_host && !curl_strequal( - m->needle->conn_to_host.name, conn->conn_to_host.name)) || - (m->needle->bits.conn_to_port && - m->needle->conn_to_port != conn->conn_to_port)) - return FALSE; - - /* hostname and port must match */ - if(!curl_strequal(m->needle->host.name, conn->host.name) || - m->needle->remote_port != conn->remote_port) - return FALSE; - } - return TRUE; -} - -static bool url_match_ssl_config(struct connectdata *conn, - struct url_conn_match *m) -{ - /* If talking TLS, conn needs to use the same SSL options. */ - if((m->needle->scheme->flags & PROTOPT_SSL) && - !Curl_ssl_conn_config_match(m->data, conn, FALSE)) { - DEBUGF(infof(m->data, "Connection #%" FMT_OFF_T - " has different SSL parameters, cannot reuse", - conn->connection_id)); - return FALSE; - } - return TRUE; -} - -#ifdef USE_NTLM -static bool url_match_auth_ntlm(struct connectdata *conn, - struct url_conn_match *m) -{ - /* If we are looking for an HTTP+NTLM connection, check if this is - already authenticating with the right credentials. If not, keep - looking so that we can reuse NTLM connections if - possible. (Especially we must not reuse the same connection if - partway through a handshake!) */ - if(m->want_ntlm_http) { - if(Curl_timestrcmp(m->needle->user, conn->user) || - Curl_timestrcmp(m->needle->passwd, conn->passwd)) { - /* we prefer a credential match, but this is at least a connection - that can be reused and "upgraded" to NTLM if it does - not have any auth ongoing. */ -#ifdef USE_SPNEGO - if((conn->http_ntlm_state == NTLMSTATE_NONE) - && (conn->http_negotiate_state == GSS_AUTHNONE)) { -#else - if(conn->http_ntlm_state == NTLMSTATE_NONE) { -#endif - m->found = conn; - } - return FALSE; - } - } - else if(conn->http_ntlm_state != NTLMSTATE_NONE) { - /* Connection is using NTLM auth but we do not want NTLM */ - return FALSE; - } - -#ifndef CURL_DISABLE_PROXY - /* Same for Proxy NTLM authentication */ - if(m->want_proxy_ntlm_http) { - /* Both conn->http_proxy.user and conn->http_proxy.passwd can be - * NULL */ - if(!conn->http_proxy.user || !conn->http_proxy.passwd) - return FALSE; - - if(Curl_timestrcmp(m->needle->http_proxy.user, - conn->http_proxy.user) || - Curl_timestrcmp(m->needle->http_proxy.passwd, - conn->http_proxy.passwd)) - return FALSE; - } - else if(conn->proxy_ntlm_state != NTLMSTATE_NONE) { - /* Proxy connection is using NTLM auth but we do not want NTLM */ - return FALSE; - } -#endif - if(m->want_ntlm_http || m->want_proxy_ntlm_http) { - /* Credentials are already checked, we may use this connection. - * With NTLM being weird as it is, we MUST use a - * connection where it has already been fully negotiated. - * If it has not, we keep on looking for a better one. */ - m->found = conn; - - if((m->want_ntlm_http && - (conn->http_ntlm_state != NTLMSTATE_NONE)) || - (m->want_proxy_ntlm_http && - (conn->proxy_ntlm_state != NTLMSTATE_NONE))) { - /* We must use this connection, no other */ - m->force_reuse = TRUE; - return TRUE; - } - /* Continue look up for a better connection */ - return FALSE; - } - return TRUE; -} -#else -#define url_match_auth_ntlm(c, m) ((void)(c), (void)(m), TRUE) -#endif - -#ifdef USE_SPNEGO -static bool url_match_auth_nego(struct connectdata *conn, - struct url_conn_match *m) -{ - /* If we are looking for an HTTP+Negotiate connection, check if this is - already authenticating with the right credentials. If not, keep looking - so that we can reuse Negotiate connections if possible. */ - if(m->want_nego_http) { - if(Curl_timestrcmp(m->needle->user, conn->user) || - Curl_timestrcmp(m->needle->passwd, conn->passwd)) - return FALSE; - } - else if(conn->http_negotiate_state != GSS_AUTHNONE) { - /* Connection is using Negotiate auth but we do not want Negotiate */ - return FALSE; - } - -#ifndef CURL_DISABLE_PROXY - /* Same for Proxy Negotiate authentication */ - if(m->want_proxy_nego_http) { - /* Both conn->http_proxy.user and conn->http_proxy.passwd can be - * NULL */ - if(!conn->http_proxy.user || !conn->http_proxy.passwd) - return FALSE; - - if(Curl_timestrcmp(m->needle->http_proxy.user, - conn->http_proxy.user) || - Curl_timestrcmp(m->needle->http_proxy.passwd, - conn->http_proxy.passwd)) - return FALSE; - } - else if(conn->proxy_negotiate_state != GSS_AUTHNONE) { - /* Proxy connection is using Negotiate auth but we do not want Negotiate */ - return FALSE; - } -#endif - if(m->want_nego_http || m->want_proxy_nego_http) { - /* Credentials are already checked, we may use this connection. We MUST - * use a connection where it has already been fully negotiated. If it has - * not, we keep on looking for a better one. */ - m->found = conn; - if((m->want_nego_http && - (conn->http_negotiate_state != GSS_AUTHNONE)) || - (m->want_proxy_nego_http && - (conn->proxy_negotiate_state != GSS_AUTHNONE))) { - /* We must use this connection, no other */ - m->force_reuse = TRUE; - return TRUE; - } - return FALSE; /* get another */ - } - return TRUE; -} -#else -#define url_match_auth_nego(c, m) ((void)(c), (void)(m), TRUE) -#endif - -static bool url_match_conn(struct connectdata *conn, void *userdata) -{ - struct url_conn_match *m = userdata; - /* Check if `conn` can be used for transfer `m->data` */ - - /* general connect config setting match? */ - if(!url_match_connect_config(conn, m)) - return FALSE; - - /* match for destination and protocol? */ - if(!url_match_destination(conn, m)) - return FALSE; - - if(!url_match_fully_connected(conn, m)) - return FALSE; - - if(!url_match_multiplex_needs(conn, m)) - return FALSE; - - if(!url_match_ssl_use(conn, m)) - return FALSE; - if(!url_match_proxy_use(conn, m)) - return FALSE; - if(!url_match_ssl_config(conn, m)) - return FALSE; - - if(!url_match_http_multiplex(conn, m)) - return FALSE; - else if(m->wait_pipe) - /* we decided to wait on PIPELINING */ - return TRUE; - - if(!url_match_auth(conn, m)) - return FALSE; - - if(!url_match_proto_config(conn, m)) - return FALSE; - - if(!url_match_auth_ntlm(conn, m)) - return FALSE; - else if(m->force_reuse) - return TRUE; - - if(!url_match_auth_nego(conn, m)) - return FALSE; - else if(m->force_reuse) - return TRUE; - - if(!url_match_multiplex_limits(conn, m)) - return FALSE; - - if(!CONN_INUSE(conn) && Curl_conn_seems_dead(conn, m->data)) { - /* remove and disconnect. */ - Curl_conn_terminate(m->data, conn, FALSE); - return FALSE; - } - - /* conn matches our needs. */ - m->found = conn; - return TRUE; -} - -static bool url_match_result(void *userdata) -{ - struct url_conn_match *match = userdata; - if(match->found) { - /* Attach it now while still under lock, so the connection does - * no longer appear idle and can be reaped. */ - Curl_attach_connection(match->data, match->found); - return TRUE; - } - else if(match->seen_single_use_conn && !match->seen_multiplex_conn) { - /* We have seen a single-use, existing connection to the destination and - * no multiplexed one. It seems safe to assume that the server does - * not support multiplexing. */ - match->wait_pipe = FALSE; - } - else if(match->seen_pending_conn && match->data->set.pipewait) { - infof(match->data, - "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set"); - match->wait_pipe = TRUE; - } - match->force_reuse = FALSE; - return FALSE; -} - -/* - * Given a transfer and a prototype connection (needle), - * find and attach an existing connection that matches. - * - * Return TRUE if an existing connection was attached. - * `waitpipe` is TRUE if no existing connection matched, but there - * might be suitable one in the near future (common cause: multiplexing - * capability has not been determined yet, e.g. ALPN handshake). - */ -static bool url_attach_existing(struct Curl_easy *data, - struct connectdata *needle, - bool *waitpipe) -{ - struct url_conn_match match; - bool success; - - DEBUGASSERT(!data->conn); - memset(&match, 0, sizeof(match)); - match.data = data; - match.needle = needle; - match.may_multiplex = xfer_may_multiplex(data, needle); - -#ifdef USE_NTLM - match.want_ntlm_http = - (data->state.authhost.want & CURLAUTH_NTLM) && - (needle->scheme->protocol & PROTO_FAMILY_HTTP); -#ifndef CURL_DISABLE_PROXY - match.want_proxy_ntlm_http = - needle->bits.proxy_user_passwd && - (data->state.authproxy.want & CURLAUTH_NTLM) && - (needle->scheme->protocol & PROTO_FAMILY_HTTP); -#endif -#endif - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) - match.want_nego_http = - (data->state.authhost.want & CURLAUTH_NEGOTIATE) && - (needle->scheme->protocol & PROTO_FAMILY_HTTP); -#ifndef CURL_DISABLE_PROXY - match.want_proxy_nego_http = - needle->bits.proxy_user_passwd && - (data->state.authproxy.want & CURLAUTH_NEGOTIATE) && - (needle->scheme->protocol & PROTO_FAMILY_HTTP); -#endif -#endif - match.req_tls = data->set.use_ssl >= CURLUSESSL_CONTROL; - - /* Find a connection in the pool that matches what "data + needle" - * requires. If a suitable candidate is found, it is attached to "data". */ - success = Curl_cpool_find(data, needle->destination, - url_match_conn, url_match_result, &match); - - /* wait_pipe is TRUE if we encounter a bundle that is undecided. There - * is no matching connection then, yet. */ - *waitpipe = (bool)match.wait_pipe; - return success; -} - -/* - * Allocate and initialize a new connectdata object. - */ -static struct connectdata *allocate_conn(struct Curl_easy *data) -{ - struct connectdata *conn = curlx_calloc(1, sizeof(struct connectdata)); - if(!conn) - return NULL; - - /* and we setup a few fields in case we end up actually using this struct */ - - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->recv_idx = 0; /* default for receiving transfer data */ - conn->send_idx = 0; /* default for sending transfer data */ - conn->connection_id = -1; /* no ID */ - conn->attached_xfers = 0; - conn->remote_port = 0; /* unknown at this point */ - - /* Store creation time to help future close decision making */ - conn->created = *Curl_pgrs_now(data); - - /* Store current time to give a baseline to keepalive connection times. */ - conn->keepalive = conn->created; - -#ifndef CURL_DISABLE_PROXY - conn->http_proxy.proxytype = data->set.proxytype; - conn->socks_proxy.proxytype = CURLPROXY_SOCKS4; - - /* note that these two proxy bits are set on what looks to be - requested, they may be altered down the road */ - conn->bits.proxy = (data->set.str[STRING_PROXY] && - *data->set.str[STRING_PROXY]); - conn->bits.httpproxy = (conn->bits.proxy && - (conn->http_proxy.proxytype == CURLPROXY_HTTP || - conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 || - IS_HTTPS_PROXY(conn->http_proxy.proxytype))); - conn->bits.socksproxy = (conn->bits.proxy && !conn->bits.httpproxy); - - if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) { - conn->bits.proxy = TRUE; - conn->bits.socksproxy = TRUE; - } - - conn->bits.proxy_user_passwd = !!data->state.aptr.proxyuser; - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; -#endif /* CURL_DISABLE_PROXY */ - -#ifndef CURL_DISABLE_FTP - conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; - conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; -#endif - conn->ip_version = data->set.ipver; - conn->bits.connect_only = (bool)data->set.connect_only; - conn->transport_wanted = TRNSPRT_TCP; /* most of them are TCP streams */ - - /* Store the local bind parameters that will be used for this connection */ - if(data->set.str[STRING_DEVICE]) { - conn->localdev = curlx_strdup(data->set.str[STRING_DEVICE]); - if(!conn->localdev) - goto error; - } -#ifndef CURL_DISABLE_BINDLOCAL - conn->localportrange = data->set.localportrange; - conn->localport = data->set.localport; -#endif - - /* the close socket stuff needs to be copied to the connection struct as - it may live on without (this specific) Curl_easy */ - conn->fclosesocket = data->set.fclosesocket; - conn->closesocket_client = data->set.closesocket_client; - conn->lastused = conn->created; -#ifdef HAVE_GSSAPI - conn->gssapi_delegation = data->set.gssapi_delegation; -#endif - DEBUGF(infof(data, "alloc connection, bits.close=%d", conn->bits.close)); - return conn; -error: - - curlx_free(conn->localdev); - curlx_free(conn); - return NULL; -} - -static CURLcode findprotocol(struct Curl_easy *data, - struct connectdata *conn, - const char *protostr) -{ - const struct Curl_scheme *p = Curl_get_scheme(protostr); - - if(p && p->run && /* Protocol found supported. Check if allowed */ - (data->set.allowed_protocols & p->protocol)) { - - /* it is allowed for "normal" request, now do an extra check if this is - the result of a redirect */ - if(data->state.this_is_a_follow && - !(data->set.redir_protocols & p->protocol)) - /* nope, get out */ - ; - else { - /* Perform setup complement if some. */ - conn->scheme = conn->given = p; - /* 'port' and 'remote_port' are set in setup_connection_internals() */ - return CURLE_OK; - } - } - - /* The protocol was not found in the table, but we do not have to assign it - to anything since it is already assigned to a dummy-struct in the - create_conn() function when the connectdata struct is allocated. */ - failf(data, "Protocol \"%s\" %s%s", protostr, - p ? "disabled" : "not supported", - data->state.this_is_a_follow ? " (in redirect)" : ""); - - return CURLE_UNSUPPORTED_PROTOCOL; -} - -CURLcode Curl_uc_to_curlcode(CURLUcode uc) -{ - switch(uc) { - default: - return CURLE_URL_MALFORMAT; - case CURLUE_UNSUPPORTED_SCHEME: - return CURLE_UNSUPPORTED_PROTOCOL; - case CURLUE_OUT_OF_MEMORY: - return CURLE_OUT_OF_MEMORY; - case CURLUE_USER_NOT_ALLOWED: - return CURLE_LOGIN_DENIED; - } -} - -#ifdef USE_IPV6 -/* - * If the URL was set with an IPv6 numerical address with a zone id part, set - * the scope_id based on that! - */ - -static void zonefrom_url(CURLU *uh, struct Curl_easy *data, - struct connectdata *conn) -{ - char *zoneid; - CURLUcode uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0); -#if !defined(HAVE_IF_NAMETOINDEX) || !defined(CURLVERBOSE) - (void)data; -#endif - - if(!uc && zoneid) { - const char *p = zoneid; - curl_off_t scope; - if(!curlx_str_number(&p, &scope, UINT_MAX)) - /* A plain number, use it directly as a scope id. */ - conn->scope_id = (unsigned int)scope; -#ifdef HAVE_IF_NAMETOINDEX - else { - /* Zone identifier is not numeric */ - unsigned int scopeidx = 0; - scopeidx = if_nametoindex(zoneid); - if(!scopeidx) { -#ifdef CURLVERBOSE - char buffer[STRERROR_LEN]; - infof(data, "Invalid zoneid: %s; %s", zoneid, - curlx_strerror(errno, buffer, sizeof(buffer))); -#endif - } - else - conn->scope_id = scopeidx; - } -#endif /* HAVE_IF_NAMETOINDEX */ - - curlx_free(zoneid); - } -} -#else -#define zonefrom_url(a, b, c) Curl_nop_stmt -#endif - -/* - * Parse URL and fill in the relevant members of the connection struct. - */ -static CURLcode parseurlandfillconn(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result; - CURLU *uh; - CURLUcode uc; - char *hostname; - size_t hlen; - bool use_set_uh = (data->set.uh && !data->state.this_is_a_follow); - - up_free(data); /* cleanup previous leftovers first */ - - /* parse the URL */ - if(use_set_uh) { - uh = data->state.uh = curl_url_dup(data->set.uh); - } - else { - uh = data->state.uh = curl_url(); - } - - if(!uh) - return CURLE_OUT_OF_MEMORY; - - if(data->set.str[STRING_DEFAULT_PROTOCOL] && - !Curl_is_absolute_url(Curl_bufref_ptr(&data->state.url), NULL, 0, TRUE)) { - char *url = curl_maprintf("%s://%s", - data->set.str[STRING_DEFAULT_PROTOCOL], - Curl_bufref_ptr(&data->state.url)); - if(!url) - return CURLE_OUT_OF_MEMORY; - Curl_bufref_set(&data->state.url, url, 0, curl_free); - } - - if(!use_set_uh) { - char *newurl; - uc = curl_url_set(uh, CURLUPART_URL, Curl_bufref_ptr(&data->state.url), - (unsigned int)(CURLU_GUESS_SCHEME | - CURLU_NON_SUPPORT_SCHEME | - (data->set.disallow_username_in_url ? - CURLU_DISALLOW_USER : 0) | - (data->set.path_as_is ? CURLU_PATH_AS_IS : 0))); - if(uc) { - failf(data, "URL rejected: %s", curl_url_strerror(uc)); - return Curl_uc_to_curlcode(uc); - } - - /* after it was parsed, get the generated normalized version */ - uc = curl_url_get(uh, CURLUPART_URL, &newurl, 0); - if(uc) - return Curl_uc_to_curlcode(uc); - Curl_bufref_set(&data->state.url, newurl, 0, curl_free); - } - - uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0); - if(uc) - return Curl_uc_to_curlcode(uc); - - uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0); - if(uc) { - if(!curl_strequal("file", data->state.up.scheme)) - return CURLE_OUT_OF_MEMORY; - } - else if(strlen(data->state.up.hostname) > MAX_URL_LEN) { - failf(data, "Too long hostname (maximum is %d)", MAX_URL_LEN); - return CURLE_URL_MALFORMAT; - } - - hostname = data->state.up.hostname; - hlen = hostname ? strlen(hostname) : 0; - - if(hostname && hostname[0] == '[') { - /* This looks like an IPv6 address literal. See if there is an address - scope. */ - /* cut off the brackets after copying this! */ - hostname++; - hlen -= 2; - - zonefrom_url(uh, data, conn); - } - - /* make sure the connect struct gets its own copy of the hostname */ - conn->host.rawalloc = curlx_strdup(hostname ? hostname : ""); - if(!conn->host.rawalloc) - return CURLE_OUT_OF_MEMORY; - conn->host.rawalloc[hlen] = 0; /* cut off for ipv6 case */ - conn->host.name = conn->host.rawalloc; - - /************************************************************* - * IDN-convert the hostnames - *************************************************************/ - result = Curl_idnconvert_hostname(&conn->host); - if(result) - return result; - -#ifndef CURL_DISABLE_HSTS - /* HSTS upgrade */ - if(data->hsts && curl_strequal("http", data->state.up.scheme)) { - /* This MUST use the IDN decoded name */ - if(Curl_hsts(data->hsts, conn->host.name, strlen(conn->host.name), TRUE)) { - char *url; - curlx_safefree(data->state.up.scheme); - uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0); - if(uc) - return Curl_uc_to_curlcode(uc); - Curl_bufref_free(&data->state.url); - /* after update, get the updated version */ - uc = curl_url_get(uh, CURLUPART_URL, &url, 0); - if(uc) - return Curl_uc_to_curlcode(uc); - uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0); - if(uc) { - curlx_free(url); - return Curl_uc_to_curlcode(uc); - } - Curl_bufref_set(&data->state.url, url, 0, curl_free); - infof(data, "Switched from HTTP to HTTPS due to HSTS => %s", url); - } - } -#endif - - result = findprotocol(data, conn, data->state.up.scheme); - if(result) - return result; - - /* - * username and password set with their own options override the credentials - * possibly set in the URL, but netrc does not. - */ - if(!data->state.aptr.passwd || (data->state.creds_from != CREDS_OPTION)) { - uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0); - if(!uc) { - char *decoded; - result = Curl_urldecode(data->state.up.password, 0, &decoded, NULL, - conn->scheme->flags&PROTOPT_USERPWDCTRL ? - REJECT_ZERO : REJECT_CTRL); - if(result) - return result; - conn->passwd = decoded; - result = Curl_setstropt(&data->state.aptr.passwd, decoded); - if(result) - return result; - data->state.creds_from = CREDS_URL; - } - else if(uc != CURLUE_NO_PASSWORD) - return Curl_uc_to_curlcode(uc); - } - - if(!data->state.aptr.user || (data->state.creds_from != CREDS_OPTION)) { - /* we do not use the URL API's URL decoder option here since it rejects - control codes and we want to allow them for some schemes in the user - and password fields */ - uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0); - if(!uc) { - char *decoded; - result = Curl_urldecode(data->state.up.user, 0, &decoded, NULL, - conn->scheme->flags&PROTOPT_USERPWDCTRL ? - REJECT_ZERO : REJECT_CTRL); - if(result) - return result; - conn->user = decoded; - result = Curl_setstropt(&data->state.aptr.user, decoded); - data->state.creds_from = CREDS_URL; - } - else if(uc != CURLUE_NO_USER) - return Curl_uc_to_curlcode(uc); - if(result) - return result; - } - - uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options, - CURLU_URLDECODE); - if(!uc) { - conn->options = curlx_strdup(data->state.up.options); - if(!conn->options) - return CURLE_OUT_OF_MEMORY; - } - else if(uc != CURLUE_NO_OPTIONS) - return Curl_uc_to_curlcode(uc); - - uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path, CURLU_URLENCODE); - if(uc) - return Curl_uc_to_curlcode(uc); - - uc = curl_url_get(uh, CURLUPART_PORT, &data->state.up.port, - CURLU_DEFAULT_PORT); - if(uc) { - if((uc == CURLUE_OUT_OF_MEMORY) || - !curl_strequal("file", data->state.up.scheme)) - return CURLE_OUT_OF_MEMORY; - } - else { - curl_off_t port; - bool valid = TRUE; - if(data->set.use_port && data->state.allow_port) - port = data->set.use_port; - else { - const char *p = data->state.up.port; - if(curlx_str_number(&p, &port, 0xffff)) - valid = FALSE; - } - if(valid) - conn->remote_port = (unsigned short)port; - } - - uc = curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); - if(uc && (uc != CURLUE_NO_QUERY)) - return CURLE_OUT_OF_MEMORY; - -#ifdef USE_IPV6 - if(data->set.scope_id) - /* Override any scope that was set above. */ - conn->scope_id = data->set.scope_id; -#endif - - return CURLE_OK; -} - -/* - * If we are doing a resumed transfer, we need to setup our stuff - * properly. - */ -static CURLcode setup_range(struct Curl_easy *data) -{ - struct UrlState *s = &data->state; - s->resume_from = data->set.set_resume_from; - if(s->resume_from || data->set.str[STRING_SET_RANGE]) { - if(s->rangestringalloc) - curlx_free(s->range); - - if(s->resume_from) - s->range = curl_maprintf("%" FMT_OFF_T "-", s->resume_from); - else - s->range = curlx_strdup(data->set.str[STRING_SET_RANGE]); - - if(!s->range) - return CURLE_OUT_OF_MEMORY; - - s->rangestringalloc = TRUE; - - /* tell ourselves to fetch this range */ - s->use_range = TRUE; /* enable range download */ - } - else - s->use_range = FALSE; /* disable range download */ - - return CURLE_OK; -} - -/* - * setup_connection_internals() - - * - * Setup connection internals specific to the requested protocol in the - * Curl_easy. This is inited and setup before the connection is made but - * is about the particular protocol that is to be used. - * - * This MUST get called after proxy magic has been figured out. - */ -static CURLcode setup_connection_internals(struct Curl_easy *data, - struct connectdata *conn) -{ - const char *hostname; - uint16_t port; - CURLcode result; - - DEBUGF(infof(data, "setup connection, bits.close=%d", conn->bits.close)); - if(conn->scheme->run->setup_connection) { - result = conn->scheme->run->setup_connection(data, conn); - if(result) - return result; - } - DEBUGF(infof(data, "setup connection, bits.close=%d", conn->bits.close)); - - /* Now create the destination name */ -#ifndef CURL_DISABLE_PROXY - if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { - hostname = conn->http_proxy.host.name; - port = conn->http_proxy.port; - } - else -#endif - { - port = conn->bits.conn_to_port ? - conn->conn_to_port : conn->remote_port; - hostname = conn->bits.conn_to_host ? - conn->conn_to_host.name : conn->host.name; - } - -#ifdef USE_IPV6 - /* IPv6 addresses with a scope_id (0 is default == global) have a - * printable representation with a '%' suffix. */ - if(conn->scope_id) - conn->destination = curl_maprintf("[%s:%u]%%%u", hostname, port, - conn->scope_id); - else -#endif - conn->destination = curl_maprintf("%s:%u", hostname, port); - if(!conn->destination) - return CURLE_OUT_OF_MEMORY; - - Curl_strntolower(conn->destination, conn->destination, - strlen(conn->destination)); - - return CURLE_OK; -} - -#ifndef CURL_DISABLE_PROXY - -#ifndef CURL_DISABLE_HTTP -/**************************************************************** - * Detect what (if any) proxy to use. Remember that this selects a host - * name and is not limited to HTTP proxies only. - * The returned pointer must be freed by the caller (unless NULL) - ****************************************************************/ -static char *detect_proxy(struct Curl_easy *data, - struct connectdata *conn) -{ - char *proxy = NULL; - - /* If proxy was not specified, we check for default proxy environment - * variables, to enable i.e Lynx compliance: - * - * http_proxy=http://some.server.dom:port/ - * https_proxy=http://some.server.dom:port/ - * ftp_proxy=http://some.server.dom:port/ - * no_proxy=domain1.dom,host.domain2.dom - * (a comma-separated list of hosts which should - * not be proxied, or an asterisk to override - * all proxy variables) - * all_proxy=http://some.server.dom:port/ - * (seems to exist for the CERN www lib. Probably - * the first to check for.) - * - * For compatibility, the all-uppercase versions of these variables are - * checked if the lowercase versions do not exist. - */ - char proxy_env[20]; - const char *envp; - VERBOSE(envp = proxy_env); - - curl_msnprintf(proxy_env, sizeof(proxy_env), "%s_proxy", - conn->scheme->name); - - /* read the protocol proxy: */ - proxy = curl_getenv(proxy_env); - - /* - * We do not try the uppercase version of HTTP_PROXY because of - * security reasons: - * - * When curl is used in a webserver application - * environment (cgi or php), this environment variable can - * be controlled by the web server user by setting the - * http header 'Proxy:' to some value. - * - * This can cause 'internal' http/ftp requests to be - * arbitrarily redirected by any external attacker. - */ - if(!proxy && !curl_strequal("http_proxy", proxy_env)) { - /* There was no lowercase variable, try the uppercase version: */ - Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); - proxy = curl_getenv(proxy_env); - } - - if(!proxy) { -#ifndef CURL_DISABLE_WEBSOCKETS - /* websocket proxy fallbacks */ - if(curl_strequal("ws_proxy", proxy_env)) { - proxy = curl_getenv("http_proxy"); - } - else if(curl_strequal("wss_proxy", proxy_env)) { - proxy = curl_getenv("https_proxy"); - if(!proxy) - proxy = curl_getenv("HTTPS_PROXY"); - } - if(!proxy) { -#endif - envp = "all_proxy"; - proxy = curl_getenv(envp); /* default proxy to use */ - if(!proxy) { - envp = "ALL_PROXY"; - proxy = curl_getenv(envp); - } -#ifndef CURL_DISABLE_WEBSOCKETS - } -#endif - } - if(proxy) - infof(data, "Uses proxy env variable %s == '%s'", envp, proxy); - - return proxy; -} -#endif /* CURL_DISABLE_HTTP */ - -/* - * If this is supposed to use a proxy, we need to figure out the proxy - * hostname, so that we can reuse an existing connection - * that may exist registered to the same proxy host. - */ -static CURLcode parse_proxy(struct Curl_easy *data, - struct connectdata *conn, const char *proxy, - long proxytype) -{ - char *portptr = NULL; - char *proxyuser = NULL; - char *proxypasswd = NULL; - char *host = NULL; - bool sockstype; - CURLUcode uc; - struct proxy_info *proxyinfo; - CURLU *uhp = curl_url(); - CURLcode result = CURLE_OK; - char *scheme = NULL; -#ifdef USE_UNIX_SOCKETS - char *path = NULL; - bool is_unix_proxy = FALSE; -#endif - - if(!uhp) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - /* When parsing the proxy, allowing non-supported schemes since we have - these made up ones for proxies. Guess scheme for URLs without it. */ - uc = curl_url_set(uhp, CURLUPART_URL, proxy, - CURLU_NON_SUPPORT_SCHEME | CURLU_GUESS_SCHEME); - if(!uc) { - /* parsed okay as a URL */ - uc = curl_url_get(uhp, CURLUPART_SCHEME, &scheme, 0); - if(uc) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - if(curl_strequal("https", scheme)) { - if(proxytype != CURLPROXY_HTTPS2) - proxytype = CURLPROXY_HTTPS; - else - proxytype = CURLPROXY_HTTPS2; - } - else if(curl_strequal("socks5h", scheme)) - proxytype = CURLPROXY_SOCKS5_HOSTNAME; - else if(curl_strequal("socks5", scheme)) - proxytype = CURLPROXY_SOCKS5; - else if(curl_strequal("socks4a", scheme)) - proxytype = CURLPROXY_SOCKS4A; - else if(curl_strequal("socks4", scheme) || - curl_strequal("socks", scheme)) - proxytype = CURLPROXY_SOCKS4; - else if(curl_strequal("http", scheme)) - ; /* leave it as HTTP or HTTP/1.0 */ - else { - /* Any other xxx:// reject! */ - failf(data, "Unsupported proxy scheme for \'%s\'", proxy); - result = CURLE_COULDNT_CONNECT; - goto error; - } - } - else { - failf(data, "Unsupported proxy syntax in \'%s\': %s", proxy, - curl_url_strerror(uc)); - result = CURLE_COULDNT_RESOLVE_PROXY; - goto error; - } - - if(IS_HTTPS_PROXY(proxytype) && - !Curl_ssl_supports(data, SSLSUPP_HTTPS_PROXY)) { - failf(data, "Unsupported proxy \'%s\', libcurl is built without the " - "HTTPS-proxy support.", proxy); - result = CURLE_NOT_BUILT_IN; - goto error; - } - - sockstype = - proxytype == CURLPROXY_SOCKS5_HOSTNAME || - proxytype == CURLPROXY_SOCKS5 || - proxytype == CURLPROXY_SOCKS4A || - proxytype == CURLPROXY_SOCKS4; - - proxyinfo = sockstype ? &conn->socks_proxy : &conn->http_proxy; - proxyinfo->proxytype = (unsigned char)proxytype; - - /* Is there a username and password given in this proxy URL? */ - uc = curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE); - if(uc && (uc != CURLUE_NO_USER)) { - result = Curl_uc_to_curlcode(uc); - goto error; - } - uc = curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE); - if(uc && (uc != CURLUE_NO_PASSWORD)) { - result = Curl_uc_to_curlcode(uc); - goto error; - } - - if(proxyuser || proxypasswd) { - curlx_free(proxyinfo->user); - proxyinfo->user = proxyuser; - result = Curl_setstropt(&data->state.aptr.proxyuser, proxyuser); - proxyuser = NULL; - if(result) - goto error; - curlx_safefree(proxyinfo->passwd); - if(!proxypasswd) { - proxypasswd = curlx_strdup(""); - if(!proxypasswd) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - } - proxyinfo->passwd = proxypasswd; - result = Curl_setstropt(&data->state.aptr.proxypasswd, proxypasswd); - proxypasswd = NULL; - if(result) - goto error; - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - } - - uc = curl_url_get(uhp, CURLUPART_PORT, &portptr, 0); - if(uc == CURLUE_OUT_OF_MEMORY) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - if(portptr) { - curl_off_t num; - const char *p = portptr; - if(!curlx_str_number(&p, &num, UINT16_MAX)) - proxyinfo->port = (uint16_t)num; - /* Should we not error out when the port number is invalid? */ - curlx_free(portptr); - } - else { - if(data->set.proxyport) - /* None given in the proxy string, then get the default one if it is - given */ - proxyinfo->port = data->set.proxyport; - else { - if(IS_HTTPS_PROXY(proxytype)) - proxyinfo->port = CURL_DEFAULT_HTTPS_PROXY_PORT; - else - proxyinfo->port = CURL_DEFAULT_PROXY_PORT; - } - } - - /* now, clone the proxy hostname */ - uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE); - if(uc) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } -#ifdef USE_UNIX_SOCKETS - if(sockstype && curl_strequal(UNIX_SOCKET_PREFIX, host)) { - uc = curl_url_get(uhp, CURLUPART_PATH, &path, CURLU_URLDECODE); - if(uc) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - /* path will be "/", if no path was found */ - if(strcmp("/", path)) { - is_unix_proxy = TRUE; - curlx_free(host); - host = curl_maprintf(UNIX_SOCKET_PREFIX "%s", path); - if(!host) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - curlx_free(proxyinfo->host.rawalloc); - proxyinfo->host.rawalloc = host; - proxyinfo->host.name = host; - host = NULL; - } - } - - if(!is_unix_proxy) { -#endif - curlx_free(proxyinfo->host.rawalloc); - proxyinfo->host.rawalloc = host; - if(host[0] == '[') { - /* this is a numerical IPv6, strip off the brackets */ - size_t len = strlen(host); - host[len - 1] = 0; /* clear the trailing bracket */ - host++; - zonefrom_url(uhp, data, conn); - } - proxyinfo->host.name = host; - host = NULL; -#ifdef USE_UNIX_SOCKETS - } -#endif - -error: - curlx_free(proxyuser); - curlx_free(proxypasswd); - curlx_free(host); - curlx_free(scheme); -#ifdef USE_UNIX_SOCKETS - curlx_free(path); -#endif - curl_url_cleanup(uhp); - return result; -} - -/* - * Extract the user and password from the authentication string - */ -static CURLcode parse_proxy_auth(struct Curl_easy *data, - struct connectdata *conn) -{ - const char *proxyuser = data->state.aptr.proxyuser ? - data->state.aptr.proxyuser : ""; - const char *proxypasswd = data->state.aptr.proxypasswd ? - data->state.aptr.proxypasswd : ""; - CURLcode result = CURLE_OUT_OF_MEMORY; - - conn->http_proxy.user = curlx_strdup(proxyuser); - if(conn->http_proxy.user) { - conn->http_proxy.passwd = curlx_strdup(proxypasswd); - if(conn->http_proxy.passwd) - result = CURLE_OK; - else - curlx_safefree(conn->http_proxy.user); - } - return result; -} - -/* create_conn helper to parse and init proxy values. to be called after Unix - socket init but before any proxy vars are evaluated. */ -static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, - struct connectdata *conn) -{ - char *proxy = NULL; - char *socksproxy = NULL; - char *no_proxy = NULL; - CURLcode result = CURLE_OK; - - /************************************************************* - * Extract the user and password from the authentication string - *************************************************************/ - if(conn->bits.proxy_user_passwd) { - result = parse_proxy_auth(data, conn); - if(result) - goto out; - } - - /************************************************************* - * Detect what (if any) proxy to use - *************************************************************/ - if(data->set.str[STRING_PROXY]) { - proxy = curlx_strdup(data->set.str[STRING_PROXY]); - /* if global proxy is set, this is it */ - if(!proxy) { - failf(data, "memory shortage"); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - if(data->set.str[STRING_PRE_PROXY]) { - socksproxy = curlx_strdup(data->set.str[STRING_PRE_PROXY]); - /* if global socks proxy is set, this is it */ - if(!socksproxy) { - failf(data, "memory shortage"); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - if(!data->set.str[STRING_NOPROXY]) { - const char *p = "no_proxy"; - no_proxy = curl_getenv(p); - if(!no_proxy) { - p = "NO_PROXY"; - no_proxy = curl_getenv(p); - } - if(no_proxy) { - infof(data, "Uses proxy env variable %s == '%s'", p, no_proxy); - } - } - - if(Curl_check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ? - data->set.str[STRING_NOPROXY] : no_proxy)) { - curlx_safefree(proxy); - curlx_safefree(socksproxy); - } -#ifndef CURL_DISABLE_HTTP - else if(!proxy && !socksproxy) - /* if the host is not in the noproxy list, detect proxy. */ - proxy = detect_proxy(data, conn); -#endif /* CURL_DISABLE_HTTP */ - curlx_safefree(no_proxy); - -#ifdef USE_UNIX_SOCKETS - /* For the time being do not mix proxy and Unix domain sockets. See #1274 */ - if(proxy && conn->unix_domain_socket) { - curlx_free(proxy); - proxy = NULL; - } -#endif - - if(proxy && (!*proxy || (conn->scheme->flags & PROTOPT_NONETWORK))) { - curlx_free(proxy); /* Do not bother with an empty proxy string - or if the protocol does not work with network */ - proxy = NULL; - } - if(socksproxy && (!*socksproxy || - (conn->scheme->flags & PROTOPT_NONETWORK))) { - curlx_free(socksproxy); /* Do not bother with an empty socks proxy string - or if the protocol does not work with - network */ - socksproxy = NULL; - } - - /*********************************************************************** - * If this is supposed to use a proxy, we need to figure out the proxy host - * name, proxy type and port number, so that we can reuse an existing - * connection that may exist registered to the same proxy host. - ***********************************************************************/ - if(proxy || socksproxy) { - if(proxy) { - result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype); - curlx_safefree(proxy); /* parse_proxy copies the proxy string */ - if(result) - goto out; - } - - if(socksproxy) { - result = parse_proxy(data, conn, socksproxy, - conn->socks_proxy.proxytype); - /* parse_proxy copies the socks proxy string */ - curlx_safefree(socksproxy); - if(result) - goto out; - } - - if(conn->http_proxy.host.rawalloc) { -#ifdef CURL_DISABLE_HTTP - /* asking for an HTTP proxy is a bit funny when HTTP is disabled... */ - result = CURLE_UNSUPPORTED_PROTOCOL; - goto out; -#else - /* force this connection's protocol to become HTTP if compatible */ - if(!(conn->scheme->protocol & PROTO_FAMILY_HTTP)) { - if((conn->scheme->flags & PROTOPT_PROXY_AS_HTTP) && - !conn->bits.tunnel_proxy) - conn->scheme = &Curl_scheme_http; - else - /* if not converting to HTTP over the proxy, enforce tunneling */ - conn->bits.tunnel_proxy = TRUE; - } - conn->bits.httpproxy = TRUE; -#endif - } - else { - conn->bits.httpproxy = FALSE; /* not an HTTP proxy */ - conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */ - } - - if(conn->socks_proxy.host.rawalloc) { - if(!conn->http_proxy.host.rawalloc) { - /* once a socks proxy */ - if(!conn->socks_proxy.user) { - conn->socks_proxy.user = conn->http_proxy.user; - conn->http_proxy.user = NULL; - curlx_free(conn->socks_proxy.passwd); - conn->socks_proxy.passwd = conn->http_proxy.passwd; - conn->http_proxy.passwd = NULL; - } - } - conn->bits.socksproxy = TRUE; - } - else - conn->bits.socksproxy = FALSE; /* not a socks proxy */ - } - else { - conn->bits.socksproxy = FALSE; - conn->bits.httpproxy = FALSE; - } - conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy; - - if(!conn->bits.proxy) { - /* we are not using the proxy after all... */ - conn->bits.proxy = FALSE; - conn->bits.httpproxy = FALSE; - conn->bits.socksproxy = FALSE; - conn->bits.proxy_user_passwd = FALSE; - conn->bits.tunnel_proxy = FALSE; - /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need - to signal that CURLPROXY_HTTPS is not used for this connection */ - conn->http_proxy.proxytype = CURLPROXY_HTTP; - } - -out: - - curlx_free(socksproxy); - curlx_free(proxy); - return result; -} -#endif /* CURL_DISABLE_PROXY */ - -/* - * Curl_parse_login_details() - * - * This is used to parse a login string for username, password and options in - * the following formats: - * - * user - * user:password - * user:password;options - * user;options - * user;options:password - * :password - * :password;options - * ;options - * ;options:password - * - * Parameters: - * - * login [in] - login string. - * len [in] - length of the login string. - * userp [in/out] - address where a pointer to newly allocated memory - * holding the user will be stored upon completion. - * passwdp [in/out] - address where a pointer to newly allocated memory - * holding the password will be stored upon completion. - * optionsp [in/out] - OPTIONAL address where a pointer to newly allocated - * memory holding the options will be stored upon - * completion. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_parse_login_details(const char *login, const size_t len, - char **userp, char **passwdp, - char **optionsp) -{ - char *ubuf = NULL; - char *pbuf = NULL; - const char *psep = NULL; - const char *osep = NULL; - size_t ulen; - size_t plen; - size_t olen; - - DEBUGASSERT(userp); - DEBUGASSERT(passwdp); - - /* Attempt to find the password separator */ - psep = memchr(login, ':', len); - - /* Attempt to find the options separator */ - if(optionsp) - osep = memchr(login, ';', len); - - /* Calculate the portion lengths */ - ulen = (psep ? - (size_t)(osep && psep > osep ? osep - login : psep - login) : - (osep ? (size_t)(osep - login) : len)); - plen = (psep ? - (osep && osep > psep ? (size_t)(osep - psep) : - (size_t)(login + len - psep)) - 1 : 0); - olen = (osep ? - (psep && psep > osep ? (size_t)(psep - osep) : - (size_t)(login + len - osep)) - 1 : 0); - - /* Clone the user portion buffer, which can be zero length */ - ubuf = curlx_memdup0(login, ulen); - if(!ubuf) - goto error; - - /* Clone the password portion buffer */ - if(psep) { - pbuf = curlx_memdup0(&psep[1], plen); - if(!pbuf) - goto error; - } - - /* Allocate the options portion buffer */ - if(optionsp) { - char *obuf = NULL; - if(olen) { - obuf = curlx_memdup0(&osep[1], olen); - if(!obuf) - goto error; - } - *optionsp = obuf; - } - *userp = ubuf; - *passwdp = pbuf; - return CURLE_OK; -error: - curlx_free(ubuf); - curlx_free(pbuf); - return CURLE_OUT_OF_MEMORY; -} - -/************************************************************* - * Figure out the remote port number and fix it in the URL - * - * No matter if we use a proxy or not, we have to figure out the remote - * port number of various reasons. - * - * The port number embedded in the URL is replaced, if necessary. - *************************************************************/ -static CURLcode parse_remote_port(struct Curl_easy *data, - struct connectdata *conn) -{ - if(data->set.use_port && data->state.allow_port) { - /* if set, we use this instead of the port possibly given in the URL */ - char portbuf[16]; - CURLUcode uc; - conn->remote_port = data->set.use_port; - curl_msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port); - uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0); - if(uc) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -#ifndef CURL_DISABLE_NETRC -static bool str_has_ctrl(const char *input) -{ - if(input) { - const unsigned char *str = (const unsigned char *)input; - while(*str) { - if(*str < 0x20) - return TRUE; - str++; - } - } - return FALSE; -} -#endif - -/* - * Override the login details from the URL with that in the CURLOPT_USERPWD - * option or a .netrc file, if applicable. - */ -static CURLcode override_login(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLUcode uc; - char **userp = &conn->user; - char **passwdp = &conn->passwd; - char **optionsp = &conn->options; - - if(data->set.str[STRING_OPTIONS]) { - curlx_free(*optionsp); - *optionsp = curlx_strdup(data->set.str[STRING_OPTIONS]); - if(!*optionsp) - return CURLE_OUT_OF_MEMORY; - } - -#ifndef CURL_DISABLE_NETRC - if(data->set.use_netrc == CURL_NETRC_REQUIRED) { - curlx_safefree(*userp); - curlx_safefree(*passwdp); - } - conn->bits.netrc = FALSE; - if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) { - bool url_provided = FALSE; - - if(data->state.aptr.user && - (data->state.creds_from != CREDS_NETRC)) { - /* there was a username with a length in the URL. Use the URL decoded - version */ - userp = &data->state.aptr.user; - url_provided = TRUE; - } - - if(!*passwdp) { - NETRCcode ret = Curl_parsenetrc(&data->state.netrc, conn->host.name, - userp, passwdp, - data->set.str[STRING_NETRC_FILE]); - if(ret == NETRC_OUT_OF_MEMORY) - return CURLE_OUT_OF_MEMORY; - else if(ret && ((ret == NETRC_NO_MATCH) || - (data->set.use_netrc == CURL_NETRC_OPTIONAL))) { - infof(data, "Could not find host %s in the %s file; using defaults", - conn->host.name, - (data->set.str[STRING_NETRC_FILE] ? - data->set.str[STRING_NETRC_FILE] : ".netrc")); - } - else if(ret) { - const char *m = Curl_netrc_strerror(ret); - failf(data, ".netrc error: %s", m); - return CURLE_READ_ERROR; - } - else { - if(!(conn->scheme->flags & PROTOPT_USERPWDCTRL)) { - /* if the protocol cannot handle control codes in credentials, make - sure there are none */ - if(str_has_ctrl(*userp) || str_has_ctrl(*passwdp)) { - failf(data, "control code detected in .netrc credentials"); - return CURLE_READ_ERROR; - } - } - /* set bits.netrc TRUE to remember that we got the name from a .netrc - file, so that it is safe to use even if we followed a Location: to a - different host or similar. */ - conn->bits.netrc = TRUE; - } - } - if(url_provided) { - curlx_free(conn->user); - conn->user = curlx_strdup(*userp); - if(!conn->user) - return CURLE_OUT_OF_MEMORY; - } - /* no user was set but a password, set a blank user */ - if(!*userp && *passwdp) { - *userp = curlx_strdup(""); - if(!*userp) - return CURLE_OUT_OF_MEMORY; - } - } -#endif - - /* for updated strings, we update them in the URL */ - if(*userp) { - CURLcode result; - if(data->state.aptr.user != *userp) { - /* nothing to do then */ - result = Curl_setstropt(&data->state.aptr.user, *userp); - if(result) - return result; - data->state.creds_from = CREDS_NETRC; - } - } - if(data->state.aptr.user) { - uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user, - CURLU_URLENCODE); - if(uc) - return Curl_uc_to_curlcode(uc); - if(!*userp) { - *userp = curlx_strdup(data->state.aptr.user); - if(!*userp) - return CURLE_OUT_OF_MEMORY; - } - } - if(*passwdp) { - CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp); - if(result) - return result; - data->state.creds_from = CREDS_NETRC; - } - if(data->state.aptr.passwd) { - uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, - data->state.aptr.passwd, CURLU_URLENCODE); - if(uc) - return Curl_uc_to_curlcode(uc); - if(!*passwdp) { - *passwdp = curlx_strdup(data->state.aptr.passwd); - if(!*passwdp) - return CURLE_OUT_OF_MEMORY; - } - } - - return CURLE_OK; -} - -/* - * Set the login details so they are available in the connection - */ -static CURLcode set_login(struct Curl_easy *data, - struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - const char *setuser = CURL_DEFAULT_USER; - const char *setpasswd = CURL_DEFAULT_PASSWORD; - - /* If our protocol needs a password and we have none, use the defaults */ - if((conn->scheme->flags & PROTOPT_NEEDSPWD) && !data->state.aptr.user) - ; - else { - setuser = ""; - setpasswd = ""; - } - /* Store the default user */ - if(!conn->user) { - conn->user = curlx_strdup(setuser); - if(!conn->user) - return CURLE_OUT_OF_MEMORY; - } - - /* Store the default password */ - if(!conn->passwd) { - conn->passwd = curlx_strdup(setpasswd); - if(!conn->passwd) - result = CURLE_OUT_OF_MEMORY; - } - - return result; -} - -/* - * Parses a "host:port" string to connect to. - * The hostname and the port may be empty; in this case, NULL is returned for - * the hostname and -1 for the port. - */ -static CURLcode parse_connect_to_host_port(struct Curl_easy *data, - const char *host, - char **hostname_result, - int *port_result) -{ - char *host_dup; - char *hostptr; - char *host_portno; - char *portptr; - int port = -1; - CURLcode result = CURLE_OK; - - *hostname_result = NULL; - *port_result = -1; - - if(!host || !*host) - return CURLE_OK; - - host_dup = curlx_strdup(host); - if(!host_dup) - return CURLE_OUT_OF_MEMORY; - - hostptr = host_dup; - - /* start scanning for port number at this point */ - portptr = hostptr; - - /* detect and extract RFC6874-style IPv6-addresses */ - if(*hostptr == '[') { -#ifdef USE_IPV6 - char *ptr = ++hostptr; /* advance beyond the initial bracket */ - while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.'))) - ptr++; - if(*ptr == '%') { - /* There might be a zone identifier */ - if(strncmp("%25", ptr, 3)) - infof(data, "Please URL encode %% as %%25, see RFC 6874."); - ptr++; - /* Allow unreserved characters as defined in RFC 3986 */ - while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') || - (*ptr == '.') || (*ptr == '_') || (*ptr == '~'))) - ptr++; - } - if(*ptr == ']') - /* yeps, it ended nicely with a bracket as well */ - *ptr++ = '\0'; - else - infof(data, "Invalid IPv6 address format"); - portptr = ptr; - /* Note that if this did not end with a bracket, we still advanced the - * hostptr first, but I cannot see anything wrong with that as no host - * name nor a numeric can legally start with a bracket. - */ -#else - failf(data, "Use of IPv6 in *_CONNECT_TO without IPv6 support built-in"); - result = CURLE_NOT_BUILT_IN; - goto error; -#endif - } - - /* Get port number off server.com:1080 */ - host_portno = strchr(portptr, ':'); - if(host_portno) { - *host_portno = '\0'; /* cut off number from hostname */ - host_portno++; - if(*host_portno) { - curl_off_t portparse; - const char *p = host_portno; - if(curlx_str_number(&p, &portparse, 0xffff)) { - failf(data, "No valid port number in connect to host string (%s)", - host_portno); - result = CURLE_SETOPT_OPTION_SYNTAX; - goto error; - } - port = (int)portparse; /* we know it will fit */ - } - } - - /* now, clone the cleaned hostname */ - DEBUGASSERT(hostptr); - *hostname_result = curlx_strdup(hostptr); - if(!*hostname_result) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - - *port_result = port; - -error: - curlx_free(host_dup); - return result; -} - -/* - * Parses one "connect to" string in the form: - * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT". - */ -static CURLcode parse_connect_to_string(struct Curl_easy *data, - struct connectdata *conn, - const char *conn_to_host, - char **host_result, - int *port_result) -{ - CURLcode result = CURLE_OK; - const char *ptr = conn_to_host; - bool host_match = FALSE; - bool port_match = FALSE; - - *host_result = NULL; - *port_result = -1; - - if(*ptr == ':') { - /* an empty hostname always matches */ - host_match = TRUE; - ptr++; - } - else { - /* check whether the URL's hostname matches. Use the URL hostname - * when it was an IPv6 address. Otherwise use the connection's hostname - * that has IDN conversion. */ - char *hostname_to_match = - (data->state.up.hostname && data->state.up.hostname[0] == '[') ? - data->state.up.hostname : conn->host.name; - size_t hlen = strlen(hostname_to_match); - host_match = curl_strnequal(ptr, hostname_to_match, hlen); - ptr += hlen; - - host_match = host_match && *ptr == ':'; - ptr++; - } - - if(host_match) { - if(*ptr == ':') { - /* an empty port always matches */ - port_match = TRUE; - ptr++; - } - else { - /* check whether the URL's port matches */ - const char *ptr_next = strchr(ptr, ':'); - if(ptr_next) { - curl_off_t port_to_match; - if(!curlx_str_number(&ptr, &port_to_match, 0xffff) && - (port_to_match == (curl_off_t)conn->remote_port)) - port_match = TRUE; - ptr = ptr_next + 1; - } - } - } - - if(host_match && port_match) { - /* parse the hostname and port to connect to */ - result = parse_connect_to_host_port(data, ptr, host_result, port_result); - } - - return result; -} - -/* - * Processes all strings in the "connect to" slist, and uses the "connect - * to host" and "connect to port" of the first string that matches. - */ -static CURLcode parse_connect_to_slist(struct Curl_easy *data, - struct connectdata *conn, - struct curl_slist *conn_to_host) -{ - CURLcode result = CURLE_OK; - char *host = NULL; - int port = -1; - - while(conn_to_host && !host && port == -1) { - result = parse_connect_to_string(data, conn, conn_to_host->data, - &host, &port); - if(result) - return result; - - if(host && *host) { - conn->conn_to_host.rawalloc = host; - conn->conn_to_host.name = host; - conn->bits.conn_to_host = TRUE; - - infof(data, "Connecting to hostname: %s", host); - } - else { - /* no "connect to host" */ - conn->bits.conn_to_host = FALSE; - curlx_safefree(host); - } - - if(port >= 0) { - conn->conn_to_port = (uint16_t)port; - conn->bits.conn_to_port = TRUE; - infof(data, "Connecting to port: %u", conn->conn_to_port); - } - else { - /* no "connect to port" */ - conn->bits.conn_to_port = FALSE; - port = -1; - } - - conn_to_host = conn_to_host->next; - } - -#ifndef CURL_DISABLE_ALTSVC - if(data->asi && !host && (port == -1) && - ((conn->scheme->protocol == CURLPROTO_HTTPS) || -#ifdef DEBUGBUILD - /* allow debug builds to circumvent the HTTPS restriction */ - getenv("CURL_ALTSVC_HTTP") -#else - 0 -#endif - )) { - /* no connect_to match, try alt-svc! */ - enum alpnid srcalpnid = ALPN_none; - bool hit = FALSE; - struct altsvc *as = NULL; - int allowed_alpns = ALPN_none; - struct http_negotiation *neg = &data->state.http_neg; - bool same_dest = FALSE; - - DEBUGF(infof(data, "Alt-svc check wanted=%x, allowed=%x", - neg->wanted, neg->allowed)); -#ifdef USE_HTTP3 - if(neg->allowed & CURL_HTTP_V3x) - allowed_alpns |= ALPN_h3; -#endif -#ifdef USE_HTTP2 - if(neg->allowed & CURL_HTTP_V2x) - allowed_alpns |= ALPN_h2; -#endif - if(neg->allowed & CURL_HTTP_V1x) - allowed_alpns |= ALPN_h1; - allowed_alpns &= (int)data->asi->flags; - - host = conn->host.rawalloc; - DEBUGF(infof(data, "check Alt-Svc for host %s", host)); -#ifdef USE_HTTP3 - if(!hit && (neg->wanted & CURL_HTTP_V3x)) { - srcalpnid = ALPN_h3; - hit = Curl_altsvc_lookup(data->asi, - ALPN_h3, host, conn->remote_port, /* from */ - &as /* to */, - allowed_alpns, &same_dest); - } -#endif -#ifdef USE_HTTP2 - if(!hit && (neg->wanted & CURL_HTTP_V2x) && - !neg->h2_prior_knowledge) { - srcalpnid = ALPN_h2; - hit = Curl_altsvc_lookup(data->asi, - ALPN_h2, host, conn->remote_port, /* from */ - &as /* to */, - allowed_alpns, &same_dest); - } -#endif - if(!hit && (neg->wanted & CURL_HTTP_V1x) && - !neg->only_10) { - srcalpnid = ALPN_h1; - hit = Curl_altsvc_lookup(data->asi, - ALPN_h1, host, conn->remote_port, /* from */ - &as /* to */, - allowed_alpns, &same_dest); - } - - if(hit && same_dest) { - /* same destination, but more HTTPS version options */ - switch(as->dst.alpnid) { - case ALPN_h1: - neg->wanted |= CURL_HTTP_V1x; - neg->preferred = CURL_HTTP_V1x; - break; - case ALPN_h2: - neg->wanted |= CURL_HTTP_V2x; - neg->preferred = CURL_HTTP_V2x; - break; - case ALPN_h3: - neg->wanted |= CURL_HTTP_V3x; - neg->preferred = CURL_HTTP_V3x; - break; - default: /* should not be possible */ - break; - } - } - else if(hit) { - char *hostd = curlx_strdup(as->dst.host); - if(!hostd) - return CURLE_OUT_OF_MEMORY; - conn->conn_to_host.rawalloc = hostd; - conn->conn_to_host.name = hostd; - conn->bits.conn_to_host = TRUE; - conn->conn_to_port = as->dst.port; - conn->bits.conn_to_port = TRUE; - conn->bits.altused = TRUE; - infof(data, "Alt-svc connecting from [%s]%s:%u to [%s]%s:%u", - Curl_alpnid2str(srcalpnid), host, conn->remote_port, - Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port); - if(srcalpnid != as->dst.alpnid) { - /* protocol version switch */ - switch(as->dst.alpnid) { - case ALPN_h1: - neg->wanted = neg->allowed = CURL_HTTP_V1x; - neg->only_10 = FALSE; - break; - case ALPN_h2: - neg->wanted = neg->allowed = CURL_HTTP_V2x; - break; - case ALPN_h3: - conn->transport_wanted = TRNSPRT_QUIC; - neg->wanted = neg->allowed = CURL_HTTP_V3x; - break; - default: /* should not be possible */ - break; - } - } - } - } -#endif - - return result; -} - -static void url_move_hostname(struct hostname *dest, struct hostname *src) -{ - curlx_safefree(dest->rawalloc); - Curl_free_idnconverted_hostname(dest); - *dest = *src; - memset(src, 0, sizeof(*src)); -} - -/* - * Adjust reused connection settings to the transfer/needle. - */ -static void url_conn_reuse_adjust(struct Curl_easy *data, - struct connectdata *needle) -{ - struct connectdata *conn = data->conn; - - /* get the user+password information from the needle since it may - * be new for this request even when we reuse conn */ - if(needle->user) { - /* use the new username and password though */ - curlx_free(conn->user); - curlx_free(conn->passwd); - conn->user = needle->user; - conn->passwd = needle->passwd; - needle->user = NULL; - needle->passwd = NULL; - } - -#ifndef CURL_DISABLE_PROXY - conn->bits.proxy_user_passwd = needle->bits.proxy_user_passwd; - if(conn->bits.proxy_user_passwd) { - /* use the new proxy username and proxy password though */ - curlx_free(conn->http_proxy.user); - curlx_free(conn->socks_proxy.user); - curlx_free(conn->http_proxy.passwd); - curlx_free(conn->socks_proxy.passwd); - conn->http_proxy.user = needle->http_proxy.user; - conn->socks_proxy.user = needle->socks_proxy.user; - conn->http_proxy.passwd = needle->http_proxy.passwd; - conn->socks_proxy.passwd = needle->socks_proxy.passwd; - needle->http_proxy.user = NULL; - needle->socks_proxy.user = NULL; - needle->http_proxy.passwd = NULL; - needle->socks_proxy.passwd = NULL; - } -#endif - - /* Finding a connection for reuse in the cpool matches, among other - * things on the "remote-relevant" hostname. This is not necessarily - * the authority of the URL, e.g. conn->host. For example: - * - we use a proxy (not tunneling). we want to send all requests - * that use the same proxy on this connection. - * - we have a "connect-to" setting that may redirect the hostname of - * a new request to the same remote endpoint of an existing conn. - * We want to reuse an existing conn to the remote endpoint. - * Since connection reuse does not match on conn->host necessarily, we - * switch conn to needle's host settings. - */ - url_move_hostname(&conn->host, &needle->host); - url_move_hostname(&conn->conn_to_host, &needle->conn_to_host); - - conn->conn_to_port = needle->conn_to_port; - conn->remote_port = needle->remote_port; -} - -static void conn_meta_freeentry(void *p) -{ - (void)p; - /* Always FALSE. Cannot use a 0 assert here since compilers - * are not in agreement if they then want a NORETURN attribute or - * not. *sigh* */ - DEBUGASSERT(p == NULL); -} - -static CURLcode url_create_needle(struct Curl_easy *data, - struct connectdata **pneedle) -{ - struct connectdata *needle = NULL; - CURLcode result = CURLE_OK; - - /************************************************************* - * Check input data - *************************************************************/ - if(!Curl_bufref_ptr(&data->state.url)) { - result = CURLE_URL_MALFORMAT; - goto out; - } - - /* First, split up the current URL in parts so that we can use the - parts for checking against the already present connections. In order - to not have to modify everything at once, we allocate a temporary - connection data struct and fill in for comparison purposes. */ - needle = allocate_conn(data); - if(!needle) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Do the unfailable inits first, before checks that may early return */ - Curl_hash_init(&needle->meta_hash, 23, - Curl_hash_str, curlx_str_key_compare, conn_meta_freeentry); - - result = parseurlandfillconn(data, needle); - if(result) - goto out; - - if(data->set.str[STRING_SASL_AUTHZID]) { - needle->sasl_authzid = curlx_strdup(data->set.str[STRING_SASL_AUTHZID]); - if(!needle->sasl_authzid) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - if(data->set.str[STRING_BEARER]) { - needle->oauth_bearer = curlx_strdup(data->set.str[STRING_BEARER]); - if(!needle->oauth_bearer) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - -#ifdef USE_UNIX_SOCKETS - if(data->set.str[STRING_UNIX_SOCKET_PATH]) { - needle->unix_domain_socket = - curlx_strdup(data->set.str[STRING_UNIX_SOCKET_PATH]); - if(!needle->unix_domain_socket) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - needle->bits.abstract_unix_socket = data->set.abstract_unix_socket; - } -#endif - - /* After the Unix socket init but before the proxy vars are used, parse and - initialize the proxy vars */ -#ifndef CURL_DISABLE_PROXY - result = create_conn_helper_init_proxy(data, needle); - if(result) - goto out; - - /************************************************************* - * If the protocol is using SSL and HTTP proxy is used, we set - * the tunnel_proxy bit. - *************************************************************/ - if((needle->given->flags & PROTOPT_SSL) && needle->bits.httpproxy) - needle->bits.tunnel_proxy = TRUE; -#endif - - /************************************************************* - * Figure out the remote port number and fix it in the URL - *************************************************************/ - result = parse_remote_port(data, needle); - if(result) - goto out; - - /* Check for overridden login details and set them accordingly so that - they are known when protocol->setup_connection is called! */ - result = override_login(data, needle); - if(result) - goto out; - - result = set_login(data, needle); /* default credentials */ - if(result) - goto out; - - /************************************************************* - * Process the "connect to" linked list of hostname/port mappings. - * Do this after the remote port number has been fixed in the URL. - *************************************************************/ - result = parse_connect_to_slist(data, needle, data->set.connect_to); - if(result) - goto out; - - /************************************************************* - * IDN-convert the proxy hostnames - *************************************************************/ -#ifndef CURL_DISABLE_PROXY - if(needle->bits.httpproxy) { - result = Curl_idnconvert_hostname(&needle->http_proxy.host); - if(result) - goto out; - } - if(needle->bits.socksproxy) { - result = Curl_idnconvert_hostname(&needle->socks_proxy.host); - if(result) - goto out; - } -#endif - if(needle->bits.conn_to_host) { - result = Curl_idnconvert_hostname(&needle->conn_to_host); - if(result) - goto out; - } - - /************************************************************* - * Check whether the host and the "connect to host" are equal. - * Do this after the hostnames have been IDN-converted. - *************************************************************/ - if(needle->bits.conn_to_host && - curl_strequal(needle->conn_to_host.name, needle->host.name)) { - needle->bits.conn_to_host = FALSE; - } - - /************************************************************* - * Check whether the port and the "connect to port" are equal. - * Do this after the remote port number has been fixed in the URL. - *************************************************************/ - if(needle->bits.conn_to_port && - needle->conn_to_port == needle->remote_port) { - needle->bits.conn_to_port = FALSE; - } - -#ifndef CURL_DISABLE_PROXY - /************************************************************* - * If the "connect to" feature is used with an HTTP proxy, - * we set the tunnel_proxy bit. - *************************************************************/ - if((needle->bits.conn_to_host || needle->bits.conn_to_port) && - needle->bits.httpproxy) - needle->bits.tunnel_proxy = TRUE; -#endif - - /************************************************************* - * Setup internals depending on protocol. Needs to be done after - * we figured out what/if proxy to use. - *************************************************************/ - result = setup_connection_internals(data, needle); - if(result) - goto out; - - if(needle->scheme->flags & PROTOPT_ALPN) { - /* The protocol wants it, so set the bits if enabled in the easy handle - (default) */ - if(data->set.ssl_enable_alpn) - needle->bits.tls_enable_alpn = TRUE; - } - - if(!(needle->scheme->flags & PROTOPT_NONETWORK)) { - /* Setup callbacks for network connections */ - needle->recv[FIRSTSOCKET] = Curl_cf_recv; - needle->send[FIRSTSOCKET] = Curl_cf_send; - needle->recv[SECONDARYSOCKET] = Curl_cf_recv; - needle->send[SECONDARYSOCKET] = Curl_cf_send; - needle->bits.tcp_fastopen = data->set.tcp_fastopen; -#ifdef USE_UNIX_SOCKETS - if(Curl_conn_get_unix_path(needle)) - needle->transport_wanted = TRNSPRT_UNIX; -#endif - } - -out: - if(!result) { - DEBUGASSERT(needle); - *pneedle = needle; - } - else { - *pneedle = NULL; - if(needle) - Curl_conn_free(data, needle); - } - return result; -} - -/** - * Find an existing connection for the transfer or create a new one. - * Returns - * - CURLE_OK on success with a connection attached to data - * - CURLE_NO_CONNECTION_AVAILABLE when connection limits apply or when - * a suitable connection has not determined its multiplex capability. - * - a fatal error - */ -static CURLcode url_find_or_create_conn(struct Curl_easy *data) -{ - struct connectdata *needle = NULL; - bool waitpipe = FALSE; - CURLcode result; - - /* create the template connection for transfer data. Use this needle to - * find an existing connection or, if none exists, convert needle - * to a full connection and attach it to data. */ - result = url_create_needle(data, &needle); - if(result) - goto out; - DEBUGASSERT(needle); - - /*********************************************************************** - * file: is a special case in that it does not need a network connection - ***********************************************************************/ -#ifndef CURL_DISABLE_FILE - if(needle->scheme->flags & PROTOPT_NONETWORK) { - bool done; - /* this is supposed to be the connect function so we better at least check - that the file is present here! */ - DEBUGASSERT(needle->scheme->run->connect_it); - data->info.conn_scheme = needle->scheme->name; - /* conn_protocol can only provide "old" protocols */ - data->info.conn_protocol = (needle->scheme->protocol) & CURLPROTO_MASK; - result = needle->scheme->run->connect_it(data, &done); - if(result) - goto out; - - /* Setup a "faked" transfer that will do nothing */ - Curl_attach_connection(data, needle); - needle = NULL; - result = Curl_cpool_add(data, data->conn); - if(!result) { - /* Setup whatever necessary for a resumed transfer */ - result = setup_range(data); - if(!result) { - Curl_xfer_setup_nop(data); - result = Curl_init_do(data, data->conn); - } - } - - if(result) { - DEBUGASSERT(data->conn->scheme->run->done); - /* we ignore the return code for the protocol-specific DONE */ - (void)data->conn->scheme->run->done(data, result, FALSE); - } - goto out; - } -#endif - - /* Complete the easy's SSL configuration for connection cache matching */ - result = Curl_ssl_easy_config_complete(data); - if(result) - goto out; - - /* Get rid of any dead connections so limit are easier kept. */ - Curl_cpool_prune_dead(data); - - /************************************************************* - * Reuse of existing connection is not allowed when - * - connect_only is set or - * - reuse_fresh is set and this is not a follow-up request - * (like with HTTP followlocation) - *************************************************************/ - if((!data->set.reuse_fresh || data->state.followlocation) && - !data->set.connect_only) { - /* Ok, try to find and attach an existing one */ - url_attach_existing(data, needle, &waitpipe); - } - - if(data->conn) { - /* We attached an existing connection for this transfer. Copy - * over transfer specific properties over from needle. */ - struct connectdata *conn = data->conn; - VERBOSE(bool tls_upgraded = (!(needle->given->flags & PROTOPT_SSL) && - Curl_conn_is_ssl(conn, FIRSTSOCKET))); - - conn->bits.reuse = TRUE; - url_conn_reuse_adjust(data, needle); - -#ifndef CURL_DISABLE_PROXY - infof(data, "Reusing existing %s: connection%s with %s %s", - conn->given->name, - tls_upgraded ? " (upgraded to SSL)" : "", - conn->bits.proxy ? "proxy" : "host", - conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname : - conn->http_proxy.host.name ? conn->http_proxy.host.dispname : - conn->host.dispname); -#else - infof(data, "Reusing existing %s: connection%s with host %s", - conn->given->name, - tls_upgraded ? " (upgraded to SSL)" : "", - conn->host.dispname); -#endif - } - else { - /* We have decided that we want a new connection. We may not be able to do - that if we have reached the limit of how many connections we are - allowed to open. */ - DEBUGF(infof(data, "new connection, bits.close=%d", needle->bits.close)); - - if(waitpipe) { - /* There is a connection that *might* become usable for multiplexing - "soon", and we wait for that */ - infof(data, "Waiting on connection to negotiate possible multiplexing."); - result = CURLE_NO_CONNECTION_AVAILABLE; - goto out; - } - else { - switch(Curl_cpool_check_limits(data, needle)) { - case CPOOL_LIMIT_DEST: - infof(data, "No more connections allowed to host"); - result = CURLE_NO_CONNECTION_AVAILABLE; - goto out; - case CPOOL_LIMIT_TOTAL: - if(data->master_mid != UINT32_MAX) - CURL_TRC_M(data, "Allowing sub-requests (like DoH) to override " - "max connection limit"); - else { - infof(data, "No connections available, total of %zu reached.", - data->multi->max_total_connections); - result = CURLE_NO_CONNECTION_AVAILABLE; - goto out; - } - break; - default: - break; - } - } - - /* Convert needle into a full connection by filling in all the - * remaining parts like the cloned SSL configuration. */ - result = Curl_ssl_conn_config_init(data, needle); - if(result) { - DEBUGF(curl_mfprintf(stderr, "Error: init connection ssl config\n")); - goto out; - } - /* attach it and no longer own it */ - Curl_attach_connection(data, needle); - needle = NULL; - - result = Curl_cpool_add(data, data->conn); - if(result) - goto out; - -#ifdef USE_NTLM - /* If NTLM is requested in a part of this connection, make sure we do not - assume the state is fine as this is a fresh connection and NTLM is - connection based. */ - if((data->state.authhost.picked & CURLAUTH_NTLM) && - data->state.authhost.done) { - infof(data, "NTLM picked AND auth done set, clear picked"); - data->state.authhost.picked = CURLAUTH_NONE; - data->state.authhost.done = FALSE; - } - - if((data->state.authproxy.picked & CURLAUTH_NTLM) && - data->state.authproxy.done) { - infof(data, "NTLM-proxy picked AND auth done set, clear picked"); - data->state.authproxy.picked = CURLAUTH_NONE; - data->state.authproxy.done = FALSE; - } -#endif - } - - /* Setup and init stuff before DO starts, in preparing for the transfer. */ - result = Curl_init_do(data, data->conn); - if(result) - goto out; - - /* Setup whatever necessary for a resumed transfer */ - result = setup_range(data); - if(result) - goto out; - - /* persist the scheme and handler the transfer is using */ - data->info.conn_scheme = data->conn->scheme->name; - /* conn_protocol can only provide "old" protocols */ - data->info.conn_protocol = (data->conn->scheme->protocol) & CURLPROTO_MASK; - data->info.used_proxy = -#ifdef CURL_DISABLE_PROXY - 0 -#else - data->conn->bits.proxy -#endif - ; - - /* Lastly, inform connection filters that a new transfer is attached */ - result = Curl_conn_ev_data_setup(data); - -out: - if(needle) - Curl_conn_free(data, needle); - DEBUGASSERT(result || data->conn); - return result; -} - -CURLcode Curl_connect(struct Curl_easy *data, bool *pconnected) -{ - CURLcode result; - struct connectdata *conn; - - *pconnected = FALSE; - - /* Set the request to virgin state based on transfer settings */ - Curl_req_hard_reset(&data->req, data); - - /* Get or create a connection for the transfer. */ - result = url_find_or_create_conn(data); - conn = data->conn; - - if(result) - goto out; - - DEBUGASSERT(conn); - Curl_pgrsTime(data, TIMER_POSTQUEUE); - if(conn->bits.reuse) { - if(conn->attached_xfers > 1) - /* multiplexed */ - *pconnected = TRUE; - } - else if(conn->scheme->flags & PROTOPT_NONETWORK) { - Curl_pgrsTime(data, TIMER_NAMELOOKUP); - *pconnected = TRUE; - } - else { - result = Curl_conn_setup(data, conn, FIRSTSOCKET, NULL, - CURL_CF_SSL_DEFAULT); - if(!result) - result = Curl_headers_init(data); - CURL_TRC_M(data, "Curl_conn_setup() -> %d", result); - } - -out: - if(result == CURLE_NO_CONNECTION_AVAILABLE) - DEBUGASSERT(!conn); - - if(result && conn) { - /* We are not allowed to return failure with memory left allocated in the - connectdata struct, free those here */ - Curl_detach_connection(data); - Curl_conn_terminate(data, conn, TRUE); - } - - return result; -} - -/* - * Curl_init_do() inits the readwrite session. This is inited each time (in - * the DO function before the protocol-specific DO functions are invoked) for - * a transfer, sometimes multiple times on the same Curl_easy. Make sure - * nothing in here depends on stuff that are setup dynamically for the - * transfer. - * - * Allow this function to get called with 'conn' set to NULL. - */ - -CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) -{ - CURLcode result; - - if(conn) { - conn->bits.do_more = FALSE; /* by default there is no curl_do_more() to - use */ - /* if the protocol used does not support wildcards, switch it off */ - if(data->state.wildcardmatch && - !(conn->scheme->flags & PROTOPT_WILDCARD)) - data->state.wildcardmatch = FALSE; - } - - data->state.done = FALSE; /* *_done() is not called yet */ - - data->req.no_body = data->set.opt_no_body; - if(data->req.no_body) - /* in HTTP lingo, no body means using the HEAD request... */ - data->state.httpreq = HTTPREQ_HEAD; - - result = Curl_req_start(&data->req, data); - if(!result) { - Curl_pgrsReset(data); - } - return result; -} - -#if defined(USE_HTTP2) || defined(USE_HTTP3) - -#ifdef USE_NGHTTP2 - -static void priority_remove_child(struct Curl_easy *parent, - struct Curl_easy *child) -{ - struct Curl_data_prio_node **pnext = &parent->set.priority.children; - struct Curl_data_prio_node *pnode = parent->set.priority.children; - - DEBUGASSERT(child->set.priority.parent == parent); - while(pnode && pnode->data != child) { - pnext = &pnode->next; - pnode = pnode->next; - } - - DEBUGASSERT(pnode); - if(pnode) { - *pnext = pnode->next; - curlx_free(pnode); - } - - child->set.priority.parent = 0; - child->set.priority.exclusive = FALSE; -} - -CURLcode Curl_data_priority_add_child(struct Curl_easy *parent, - struct Curl_easy *child, - bool exclusive) -{ - if(child->set.priority.parent) { - priority_remove_child(child->set.priority.parent, child); - } - - if(parent) { - struct Curl_data_prio_node **tail; - struct Curl_data_prio_node *pnode; - - pnode = curlx_calloc(1, sizeof(*pnode)); - if(!pnode) - return CURLE_OUT_OF_MEMORY; - pnode->data = child; - - if(parent->set.priority.children && exclusive) { - /* exclusive: move all existing children underneath the new child */ - struct Curl_data_prio_node *node = parent->set.priority.children; - while(node) { - node->data->set.priority.parent = child; - node = node->next; - } - - tail = &child->set.priority.children; - while(*tail) - tail = &(*tail)->next; - - DEBUGASSERT(!*tail); - *tail = parent->set.priority.children; - parent->set.priority.children = 0; - } - - tail = &parent->set.priority.children; - while(*tail) { - (*tail)->data->set.priority.exclusive = FALSE; - tail = &(*tail)->next; - } - - DEBUGASSERT(!*tail); - *tail = pnode; - } - - child->set.priority.parent = parent; - child->set.priority.exclusive = exclusive; - return CURLE_OK; -} - -#endif /* USE_NGHTTP2 */ - -#ifdef USE_NGHTTP2 -static void data_priority_cleanup(struct Curl_easy *data) -{ - while(data->set.priority.children) { - struct Curl_easy *tmp = data->set.priority.children->data; - priority_remove_child(data, tmp); - if(data->set.priority.parent) - Curl_data_priority_add_child(data->set.priority.parent, tmp, FALSE); - } - - if(data->set.priority.parent) - priority_remove_child(data->set.priority.parent, data); -} -#endif - -void Curl_data_priority_clear_state(struct Curl_easy *data) -{ - memset(&data->state.priority, 0, sizeof(data->state.priority)); -} - -#endif /* USE_HTTP2 || USE_HTTP3 */ - -CURLcode Curl_conn_meta_set(struct connectdata *conn, const char *key, - void *meta_data, Curl_meta_dtor *meta_dtor) -{ - if(!Curl_hash_add2(&conn->meta_hash, CURL_UNCONST(key), strlen(key) + 1, - meta_data, meta_dtor)) { - meta_dtor(CURL_UNCONST(key), strlen(key) + 1, meta_data); - return CURLE_OUT_OF_MEMORY; - } - return CURLE_OK; -} - -void Curl_conn_meta_remove(struct connectdata *conn, const char *key) -{ - Curl_hash_delete(&conn->meta_hash, CURL_UNCONST(key), strlen(key) + 1); -} - -void *Curl_conn_meta_get(struct connectdata *conn, const char *key) -{ - return Curl_hash_pick(&conn->meta_hash, CURL_UNCONST(key), strlen(key) + 1); -} - -CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2) -{ - if(r1 && (r1 != CURLE_AGAIN)) - return r1; - if(r2 && (r2 != CURLE_AGAIN)) - return r2; - return r1; -} diff --git a/vendor/curl/lib/url.h b/vendor/curl/lib/url.h deleted file mode 100644 index 66baf7017..000000000 --- a/vendor/curl/lib/url.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef HEADER_CURL_URL_H -#define HEADER_CURL_URL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* - * Prototypes for library-wide functions - */ - -CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn); -CURLcode Curl_open(struct Curl_easy **curl); -void Curl_init_userdefined(struct Curl_easy *data); - -void Curl_freeset(struct Curl_easy *data); -CURLcode Curl_uc_to_curlcode(CURLUcode uc); -CURLcode Curl_close(struct Curl_easy **datap); /* opposite of Curl_open() */ -CURLcode Curl_connect(struct Curl_easy *data, bool *pconnected); -void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn); -CURLcode Curl_parse_login_details(const char *login, const size_t len, - char **userp, char **passwdp, - char **optionsp); - -/* Attach/Clear/Get meta data for an easy handle. Needs to provide - * a destructor, will be automatically called when the easy handle - * is reset or closed. */ -typedef void Curl_meta_dtor(void *key, size_t key_len, void *meta_data); - -/* Set the transfer meta data for the key. Any existing entry for that - * key will be destroyed. - * Takes ownership of `meta_data` and destroys it when the call fails. */ -CURLcode Curl_meta_set(struct Curl_easy *data, const char *key, - void *meta_data, Curl_meta_dtor *meta_dtor); -void Curl_meta_remove(struct Curl_easy *data, const char *key); -void *Curl_meta_get(struct Curl_easy *data, const char *key); -void Curl_meta_reset(struct Curl_easy *data); - -/* Set connection meta data for the key. Any existing entry for that - * key will be destroyed. - * Takes ownership of `meta_data` and destroys it when the call fails. */ -CURLcode Curl_conn_meta_set(struct connectdata *conn, const char *key, - void *meta_data, Curl_meta_dtor *meta_dtor); -void Curl_conn_meta_remove(struct connectdata *conn, const char *key); -void *Curl_conn_meta_get(struct connectdata *conn, const char *key); - -#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */ -#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless - specified */ - -/** - * Return TRUE iff the given connection is considered dead. - */ -bool Curl_conn_seems_dead(struct connectdata *conn, - struct Curl_easy *data); - -/** - * Perform upkeep operations on the connection. - */ -CURLcode Curl_conn_upkeep(struct Curl_easy *data, - struct connectdata *conn); - -/** - * Always eval all arguments, return the first - * result != (CURLE_OK | CURLE_AGAIN) or `r1`. - */ -CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2); - -#if defined(USE_HTTP2) || defined(USE_HTTP3) -void Curl_data_priority_clear_state(struct Curl_easy *data); -#else -#define Curl_data_priority_clear_state(x) -#endif /* USE_HTTP2 || USE_HTTP3 */ - -#ifdef USE_NGHTTP2 -CURLcode Curl_data_priority_add_child(struct Curl_easy *parent, - struct Curl_easy *child, - bool exclusive); -#else -#define Curl_data_priority_add_child(x, y, z) CURLE_NOT_BUILT_IN -#endif - -#endif /* HEADER_CURL_URL_H */ diff --git a/vendor/curl/lib/urlapi-int.h b/vendor/curl/lib/urlapi-int.h deleted file mode 100644 index 4d8f2c1cb..000000000 --- a/vendor/curl/lib/urlapi-int.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef HEADER_CURL_URLAPI_INT_H -#define HEADER_CURL_URLAPI_INT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include - -/* Internal representation of CURLU. Point to URL-encoded strings. */ -struct Curl_URL { - char *scheme; - char *user; - char *password; - char *options; /* IMAP only? */ - char *host; - char *zoneid; /* for numerical IPv6 addresses */ - char *port; - char *path; - char *query; - char *fragment; - unsigned short portnum; /* the numerical version (if 'port' is set) */ - BIT(query_present); /* to support blank */ - BIT(fragment_present); /* to support blank */ - BIT(guessed_scheme); /* when a URL without scheme is parsed */ -}; - -#define HOST_ERROR (-1) /* out of memory */ -#define HOST_NAME 1 -#define HOST_IPV4 2 -#define HOST_IPV6 3 - -#define QUERY_NO 2 -#define QUERY_NOT_YET 3 /* allow to change to query */ -#define QUERY_YES 4 - -size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, - bool guess_scheme); - -CURLUcode Curl_url_set_authority(CURLU *u, const char *authority); - -CURLUcode Curl_junkscan(const char *url, size_t *urllen, bool allowspace); - -#define U_CURLU_URLDECODE (unsigned int)CURLU_URLDECODE -#define U_CURLU_PATH_AS_IS (unsigned int)CURLU_PATH_AS_IS - -bool Curl_url_same_origin(CURLU *base, CURLU *href); - -#endif /* HEADER_CURL_URLAPI_INT_H */ diff --git a/vendor/curl/lib/urlapi.c b/vendor/curl/lib/urlapi.c deleted file mode 100644 index 103e0a6b5..000000000 --- a/vendor/curl/lib/urlapi.c +++ /dev/null @@ -1,2023 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "urldata.h" -#include "urlapi-int.h" -#include "strcase.h" -#include "url.h" -#include "escape.h" -#include "curlx/inet_pton.h" -#include "curlx/inet_ntop.h" -#include "curlx/strdup.h" -#include "idn.h" -#include "curlx/strparse.h" -#include "curl_memrchr.h" - -#ifdef _WIN32 -/* MS-DOS/Windows style drive prefix, eg c: in c:foo */ -#define STARTS_WITH_DRIVE_PREFIX(str) \ - ((('a' <= (str)[0] && (str)[0] <= 'z') || \ - ('A' <= (str)[0] && (str)[0] <= 'Z')) && \ - ((str)[1] == ':')) -#endif - -/* MS-DOS/Windows style drive prefix, optionally with - * a '|' instead of ':', followed by a slash or NUL */ -#define STARTS_WITH_URL_DRIVE_PREFIX(str) \ - ((('a' <= (str)[0] && (str)[0] <= 'z') || \ - ('A' <= (str)[0] && (str)[0] <= 'Z')) && \ - ((str)[1] == ':' || (str)[1] == '|') && \ - ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0)) - -/* scheme is not URL encoded, the longest libcurl supported ones are... */ -#define MAX_SCHEME_LEN 40 - -/* - * If USE_IPV6 is disabled, we still want to parse IPv6 addresses, so make - * sure we have _some_ value for AF_INET6 without polluting our fake value - * everywhere. - */ -#if !defined(USE_IPV6) && !defined(AF_INET6) -#define AF_INET6 (AF_INET + 1) -#endif - -#define DEFAULT_SCHEME "https" - -static void free_urlhandle(struct Curl_URL *u) -{ - curlx_free(u->scheme); - curlx_free(u->user); - curlx_free(u->password); - curlx_free(u->options); - curlx_free(u->host); - curlx_free(u->zoneid); - curlx_free(u->port); - curlx_free(u->path); - curlx_free(u->query); - curlx_free(u->fragment); -} - -/* - * Find the separator at the end of the hostname, or the '?' in cases like - * http://www.example.com?id=2380 - */ -static const char *find_host_sep(const char *url) -{ - /* Find the start of the hostname */ - const char *sep = strstr(url, "//"); - if(!sep) - sep = url; - else - sep += 2; - - /* Find first / or ? */ - while(*sep && *sep != '/' && *sep != '?') - sep++; - - return sep; -} - -/* convert CURLcode to CURLUcode */ -#define cc2cu(x) \ - ((x) == CURLE_TOO_LARGE ? CURLUE_TOO_LARGE : CURLUE_OUT_OF_MEMORY) - -/* urlencode_str() writes data into an output dynbuf and URL-encodes the - * spaces in the source URL accordingly. - * - * This function re-encodes the string, meaning that it leaves already encoded - * bytes as-is and works by encoding only what *has* to be encoded - unless it - * has to uppercase the hex to normalize. - * - * Illegal percent-encoding sequences are left as-is. - * - * URL encoding should be skipped for hostnames, otherwise IDN resolution - * will fail. - * - * 'query' tells if it is a query part or not, or if it is allowed to - * "transition" into a query part with a question mark. - * - * @unittest 1675 - */ -UNITTEST CURLUcode urlencode_str(struct dynbuf *o, const char *url, - size_t len, bool relative, - unsigned int query); -UNITTEST CURLUcode urlencode_str(struct dynbuf *o, const char *url, - size_t len, bool relative, - unsigned int query) -{ - /* we must add this with whitespace-replacing */ - const unsigned char *iptr; - const unsigned char *host_sep = (const unsigned char *)url; - CURLcode result = CURLE_OK; - - DEBUGASSERT((query >= QUERY_NO) && (query <= QUERY_YES)); - - if(!relative) { - size_t n; - host_sep = (const unsigned char *)find_host_sep(url); - - /* output the first piece as-is */ - n = (const char *)host_sep - url; - result = curlx_dyn_addn(o, url, n); - len -= n; - } - - for(iptr = host_sep; len && !result; iptr++, len--) { - if(*iptr == ' ') { - if(query != QUERY_YES) - result = curlx_dyn_addn(o, "%20", 3); - else - result = curlx_dyn_addn(o, "+", 1); - } - else if((*iptr < ' ') || (*iptr >= 0x7f)) { - unsigned char out[3] = { '%' }; - Curl_hexbyte(&out[1], *iptr); - result = curlx_dyn_addn(o, out, 3); - } - else if(*iptr == '%' && (len >= 3) && - ISXDIGIT(iptr[1]) && ISXDIGIT(iptr[2]) && - (ISLOWER(iptr[1]) || ISLOWER(iptr[2]))) { - /* uppercase it */ - unsigned char hex = (unsigned char)((curlx_hexval(iptr[1]) << 4) | - curlx_hexval(iptr[2])); - unsigned char out[3] = { '%' }; - Curl_hexbyte(&out[1], hex); - result = curlx_dyn_addn(o, out, 3); - iptr += 2; - len -= 2; - } - else { - result = curlx_dyn_addn(o, iptr, 1); - if(*iptr == '?' && (query == QUERY_NOT_YET)) - query = QUERY_YES; - } - } - - if(result) - return cc2cu(result); - return CURLUE_OK; -} - -/* - * Returns the length of the scheme if the given URL is absolute (as opposed - * to relative). Stores the scheme in the buffer if TRUE and 'buf' is - * non-NULL. The buflen must be larger than MAX_SCHEME_LEN if buf is set. - * - * If 'guess_scheme' is TRUE, it means the URL might be provided without - * scheme. - */ -size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, - bool guess_scheme) -{ - size_t i = 0; - DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN)); - (void)buflen; /* only used in debug-builds */ - if(buf) - buf[0] = 0; /* always leave a defined value in buf */ -#ifdef _WIN32 - if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url)) - return 0; -#endif - if(ISALPHA(url[0])) - for(i = 1; i < MAX_SCHEME_LEN; ++i) { - char s = url[i]; - if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.'))) { - /* RFC 3986 3.1 explains: - scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - */ - } - else { - break; - } - } - if(i && (url[i] == ':') && ((url[i + 1] == '/') || !guess_scheme)) { - /* If this does not guess scheme, the scheme always ends with the colon so - that this also detects data: URLs etc. In guessing mode, data: could - be the hostname "data" with a specified port number. */ - - /* the length of the scheme is the name part only */ - size_t len = i; - if(buf) { - Curl_strntolower(buf, url, i); - buf[i] = 0; - } - return len; - } - return 0; -} - -/* scan for byte values <= 31, 127 and sometimes space */ -CURLUcode Curl_junkscan(const char *url, size_t *urllen, bool allowspace) -{ - size_t n = strlen(url); - size_t i; - unsigned char control; - const unsigned char *p = (const unsigned char *)url; - if(n > CURL_MAX_INPUT_LENGTH) - return CURLUE_MALFORMED_INPUT; - - control = allowspace ? 0x1f : 0x20; - for(i = 0; i < n; i++) { - if(p[i] <= control || p[i] == 127) - return CURLUE_MALFORMED_INPUT; - } - *urllen = n; - return CURLUE_OK; -} - -/* - * parse_hostname_login() - * - * Parse the login details (username, password and options) from the URL and - * strip them out of the hostname - * - */ -static CURLUcode parse_hostname_login(struct Curl_URL *u, - const char *login, - size_t len, - unsigned int flags, - size_t *offset) /* to the hostname */ -{ - CURLUcode ures = CURLUE_OK; - CURLcode result; - char *userp = NULL; - char *passwdp = NULL; - char *optionsp = NULL; - const struct Curl_scheme *h = NULL; - - /* At this point, we assume all the other special cases have been taken - * care of, so the host is at most - * - * [user[:password][;options]]@]hostname - * - * We need somewhere to put the embedded details, so do that first. - */ - const char *ptr; - - DEBUGASSERT(login); - - *offset = 0; - ptr = memchr(login, '@', len); - if(!ptr) - goto out; - - /* We will now try to extract the - * possible login information in a string like: - * ftp://user:password@ftp.site.example:8021/README */ - ptr++; - - /* if this is a known scheme, get some details */ - if(u->scheme) - h = Curl_get_scheme(u->scheme); - - /* We could use the login information in the URL so extract it. Only parse - options if the handler says we should. Note that 'h' might be NULL! */ - result = Curl_parse_login_details(login, ptr - login - 1, - &userp, &passwdp, - (h && (h->flags & PROTOPT_URLOPTIONS)) ? - &optionsp : NULL); - if(result) { - /* the only possible error from Curl_parse_login_details is out of - memory: */ - ures = CURLUE_OUT_OF_MEMORY; - goto out; - } - - if(userp) { - if(flags & CURLU_DISALLOW_USER) { - /* Option DISALLOW_USER is set and URL contains username. */ - ures = CURLUE_USER_NOT_ALLOWED; - goto out; - } - curlx_free(u->user); - u->user = userp; - } - - if(passwdp) { - curlx_free(u->password); - u->password = passwdp; - } - - if(optionsp) { - curlx_free(u->options); - u->options = optionsp; - } - - /* the hostname starts at this offset */ - *offset = ptr - login; - return CURLUE_OK; - -out: - - curlx_free(userp); - curlx_free(passwdp); - curlx_free(optionsp); - u->user = NULL; - u->password = NULL; - u->options = NULL; - - return ures; -} - -/* @unittest 1653 */ -UNITTEST CURLUcode parse_port(struct Curl_URL *u, struct dynbuf *host, - bool has_scheme); -UNITTEST CURLUcode parse_port(struct Curl_URL *u, struct dynbuf *host, - bool has_scheme) -{ - const char *portptr; - const char *hostname = curlx_dyn_ptr(host); - /* - * Find the end of an IPv6 address on the ']' ending bracket. - */ - if(hostname[0] == '[') { - portptr = strchr(hostname, ']'); - if(!portptr) - return CURLUE_BAD_IPV6; - portptr++; - /* this is a RFC2732-style specified IP-address */ - if(*portptr) { - if(*portptr != ':') - return CURLUE_BAD_PORT_NUMBER; - } - else - portptr = NULL; - } - else - portptr = strchr(hostname, ':'); - - if(portptr) { - curl_off_t port; - size_t keep = portptr - hostname; - - /* Browser behavior adaptation. If there is a colon with no digits after, - cut off the name there which makes us ignore the colon and use the - default port. Firefox, Chrome and Safari all do that. - - Do not do it if the URL has no scheme, to make something that looks like - a scheme not work! - */ - curlx_dyn_setlen(host, keep); - portptr++; - if(!*portptr) - return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER; - - if(curlx_str_number(&portptr, &port, 0xffff) || *portptr) - return CURLUE_BAD_PORT_NUMBER; - - u->portnum = (unsigned short)port; - /* generate a new port number string to get rid of leading zeroes etc */ - curlx_free(u->port); - u->port = curl_maprintf("%" CURL_FORMAT_CURL_OFF_T, port); - if(!u->port) - return CURLUE_OUT_OF_MEMORY; - } - - return CURLUE_OK; -} - -/* This function assumes 'hostname' now starts with [. It trims 'hostname' in - * place and it sets u->zoneid if present. - * - * @unittest 1675 - */ -UNITTEST CURLUcode ipv6_parse(struct Curl_URL *u, char *hostname, - size_t hlen); -UNITTEST CURLUcode ipv6_parse(struct Curl_URL *u, char *hostname, - size_t hlen) /* length of hostname */ -{ - size_t len; - DEBUGASSERT(*hostname == '['); - if(hlen < 4) /* '[::]' is the shortest possible valid string */ - return CURLUE_BAD_IPV6; - hostname++; - hlen -= 2; - - /* only valid IPv6 letters are ok */ - len = strspn(hostname, "0123456789abcdefABCDEF:."); - - if(hlen != len) { - hlen = len; - if(hostname[len] == '%') { - /* this could now be '%[zone id]' */ - char zoneid[16]; - int i = 0; - char *h = &hostname[len + 1]; - /* pass '25' if present and is a URL encoded percent sign */ - if(!strncmp(h, "25", 2) && h[2] && (h[2] != ']')) - h += 2; - while(*h && (*h != ']') && (i < 15)) - zoneid[i++] = *h++; - if(!i || (']' != *h)) - return CURLUE_BAD_IPV6; - zoneid[i] = 0; - u->zoneid = curlx_strdup(zoneid); - if(!u->zoneid) - return CURLUE_OUT_OF_MEMORY; - hostname[len] = ']'; /* insert end bracket */ - hostname[len + 1] = 0; /* terminate the hostname */ - } - else - return CURLUE_BAD_IPV6; - /* hostname is fine */ - } - - /* Normalize the IPv6 address */ - { - char dest[16]; /* fits a binary IPv6 address */ - hostname[hlen] = 0; /* end the address there */ - if(curlx_inet_pton(AF_INET6, hostname, dest) != 1) - return CURLUE_BAD_IPV6; - if(curlx_inet_ntop(AF_INET6, dest, hostname, hlen + 1)) { - hlen = strlen(hostname); /* might be shorter now */ - hostname[hlen + 1] = 0; - } - hostname[hlen] = ']'; /* restore ending bracket */ - } - return CURLUE_OK; -} - -static CURLUcode hostname_check(struct Curl_URL *u, char *hostname, - size_t hlen) /* length of hostname */ -{ - size_t len; - DEBUGASSERT(hostname); - - if(!hlen) - return CURLUE_NO_HOST; - else if(hostname[0] == '[') - return ipv6_parse(u, hostname, hlen); - else { - /* letters from the second string are not ok */ - len = strcspn(hostname, " \r\n\t/:#?!@{}[]\\$\'\"^`*<>=;,+&()%"); - if(hlen != len) - /* hostname with bad content */ - return CURLUE_BAD_HOSTNAME; - } - return CURLUE_OK; -} - -/* - * Handle partial IPv4 numerical addresses and different bases, like - * '16843009', '0x7f', '0x7f.1' '0177.1.1.1' etc. - * - * If the given input string is syntactically wrong IPv4 or any part for - * example is too big, this function returns HOST_NAME. - * - * Output the "normalized" version of that input string in plain quad decimal - * integers. - * - * Returns the host type. - * - * @unittest 1675 - */ - -UNITTEST int ipv4_normalize(struct dynbuf *host); -UNITTEST int ipv4_normalize(struct dynbuf *host) -{ - bool done = FALSE; - int n = 0; - const char *c = curlx_dyn_ptr(host); - unsigned int parts[4] = { 0, 0, 0, 0 }; - CURLcode result = CURLE_OK; - - if(*c == '[') - return HOST_IPV6; - - while(!done) { - int rc; - curl_off_t l; - if(*c == '0') { - if(c[1] == 'x') { - c += 2; /* skip the prefix */ - rc = curlx_str_hex(&c, &l, UINT_MAX); - } - else - rc = curlx_str_octal(&c, &l, UINT_MAX); - } - else - rc = curlx_str_number(&c, &l, UINT_MAX); - - if(rc) - return HOST_NAME; - - parts[n] = (unsigned int)l; - - switch(*c) { - case '.': - if(n == 3) - return HOST_NAME; - n++; - c++; - break; - - case '\0': - done = TRUE; - break; - - default: - return HOST_NAME; - } - } - - switch(n) { - case 0: /* a -- 32 bits */ - curlx_dyn_reset(host); - - result = curlx_dyn_addf(host, "%u.%u.%u.%u", - (parts[0] >> 24), - ((parts[0] >> 16) & 0xff), - ((parts[0] >> 8) & 0xff), - (parts[0] & 0xff)); - break; - case 1: /* a.b -- 8.24 bits */ - if((parts[0] > 0xff) || (parts[1] > 0xffffff)) - return HOST_NAME; - curlx_dyn_reset(host); - result = curlx_dyn_addf(host, "%u.%u.%u.%u", - (parts[0]), - ((parts[1] >> 16) & 0xff), - ((parts[1] >> 8) & 0xff), - (parts[1] & 0xff)); - break; - case 2: /* a.b.c -- 8.8.16 bits */ - if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xffff)) - return HOST_NAME; - curlx_dyn_reset(host); - result = curlx_dyn_addf(host, "%u.%u.%u.%u", - (parts[0]), - (parts[1]), - ((parts[2] >> 8) & 0xff), - (parts[2] & 0xff)); - break; - case 3: /* a.b.c.d -- 8.8.8.8 bits */ - if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff) || - (parts[3] > 0xff)) - return HOST_NAME; - curlx_dyn_reset(host); - result = curlx_dyn_addf(host, "%u.%u.%u.%u", - (parts[0]), - (parts[1]), - (parts[2]), - (parts[3])); - break; - } - if(result) - return HOST_ERROR; - return HOST_IPV4; -} - -/* if necessary, replace the host content with a URL decoded version */ -static CURLUcode urldecode_host(struct dynbuf *host) -{ - const char *per; - const char *hostname = curlx_dyn_ptr(host); - per = strchr(hostname, '%'); - if(!per) - /* nothing to decode */ - return CURLUE_OK; - else { - /* encoded */ - size_t dlen; - char *decoded; - CURLcode result = Curl_urldecode(hostname, 0, &decoded, &dlen, - REJECT_CTRL); - if(result) - return CURLUE_BAD_HOSTNAME; - curlx_dyn_reset(host); - result = curlx_dyn_addn(host, decoded, dlen); - curlx_free(decoded); - if(result) - return cc2cu(result); - } - - return CURLUE_OK; -} - -static CURLUcode parse_authority(struct Curl_URL *u, - const char *auth, size_t authlen, - unsigned int flags, - struct dynbuf *host, - bool has_scheme) -{ - size_t offset; - CURLUcode uc; - CURLcode result; - - /* - * Parse the login details and strip them out of the hostname. - */ - uc = parse_hostname_login(u, auth, authlen, flags, &offset); - if(uc) - goto out; - - result = curlx_dyn_addn(host, auth + offset, authlen - offset); - if(result) { - uc = cc2cu(result); - goto out; - } - - uc = parse_port(u, host, has_scheme); - if(uc) - goto out; - - if(!curlx_dyn_len(host)) - return CURLUE_NO_HOST; - - switch(ipv4_normalize(host)) { - case HOST_IPV4: - break; - case HOST_IPV6: - uc = ipv6_parse(u, curlx_dyn_ptr(host), curlx_dyn_len(host)); - break; - case HOST_NAME: - uc = urldecode_host(host); - if(!uc) - uc = hostname_check(u, curlx_dyn_ptr(host), curlx_dyn_len(host)); - break; - case HOST_ERROR: - uc = CURLUE_OUT_OF_MEMORY; - break; - default: - uc = CURLUE_BAD_HOSTNAME; /* Bad IPv4 address even */ - break; - } - -out: - return uc; -} - -/* used for HTTP/2 server push */ -CURLUcode Curl_url_set_authority(CURLU *u, const char *authority) -{ - CURLUcode ures; - struct dynbuf host; - - DEBUGASSERT(authority); - curlx_dyn_init(&host, CURL_MAX_INPUT_LENGTH); - - ures = parse_authority(u, authority, strlen(authority), - CURLU_DISALLOW_USER, &host, !!u->scheme); - if(ures) - curlx_dyn_free(&host); - else { - curlx_free(u->host); - u->host = curlx_dyn_ptr(&host); - } - return ures; -} - -/* - * "Remove Dot Segments" - * https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 - */ - -static bool is_dot(const char **str, size_t *clen) -{ - const char *p = *str; - if(*p == '.') { - (*str)++; - (*clen)--; - return TRUE; - } - else if((*clen >= 3) && - (p[0] == '%') && (p[1] == '2') && ((p[2] | 0x20) == 'e')) { - *str += 3; - *clen -= 3; - return TRUE; - } - return FALSE; -} - -#define ISSLASH(x) ((x) == '/') - -/* - * dedotdotify() - * - * This function gets a null-terminated path with dot and dotdot sequences - * passed in and strips them off according to the rules in RFC 3986 section - * 5.2.4. - * - * The function handles a path. It should not contain the query nor fragment. - * - * RETURNS - * - * Zero for success and 'out' set to an allocated dedotdotified string. - * - * @unittest 1395 - */ -UNITTEST int dedotdotify(const char *input, size_t clen, char **outp); -UNITTEST int dedotdotify(const char *input, size_t clen, char **outp) -{ - struct dynbuf out; - CURLcode result = CURLE_OK; - - /* variables for leading dot checks */ - const char *dinput = input; - size_t dlen = clen; - - *outp = NULL; - /* a single byte path cannot be cleaned up */ - if(clen < 2) - return 0; - - curlx_dyn_init(&out, clen + 1); - - /* if the input buffer begins with a prefix of "../" or "./", then remove - that prefix from the input buffer; otherwise, */ - if(is_dot(&dinput, &dlen)) { - if(ISSLASH(*dinput)) { - /* one dot followed by a slash */ - input = dinput + 1; - clen = dlen - 1; - } - - /* if the input buffer consists only of "." or "..", then remove - that from the input buffer; otherwise, */ - else if(is_dot(&dinput, &dlen)) { - if(!dlen) - /* .. [end] */ - goto end; - else if(ISSLASH(*dinput)) { - /* ../ */ - input = dinput + 1; - clen = dlen - 1; - } - } - } - - while(clen && !result) { /* until end of path content */ - if(ISSLASH(*input)) { - const char *p = &input[1]; - size_t blen = clen - 1; - /* if the input buffer begins with a prefix of "/./" or "/.", where "." - is a complete path segment, then replace that prefix with "/" in the - input buffer; otherwise, */ - if(is_dot(&p, &blen)) { - if(!blen) { /* /. */ - result = curlx_dyn_addn(&out, "/", 1); - break; - } - else if(ISSLASH(*p)) { /* /./ */ - input = p; - clen = blen; - continue; - } - - /* if the input buffer begins with a prefix of "/../" or "/..", where - ".." is a complete path segment, then replace that prefix with "/" - in the input buffer and remove the last segment and its preceding - "/" (if any) from the output buffer; otherwise, */ - else if(is_dot(&p, &blen) && (ISSLASH(*p) || !blen)) { - /* remove the last segment from the output buffer */ - size_t len = curlx_dyn_len(&out); - if(len) { - const char *ptr = curlx_dyn_ptr(&out); - const char *last = memrchr(ptr, '/', len); - if(last) - /* trim the output at the slash */ - curlx_dyn_setlen(&out, last - ptr); - } - - if(blen) { /* /../ */ - input = p; - clen = blen; - continue; - } - result = curlx_dyn_addn(&out, "/", 1); - break; - } - } - } - - /* move the first path segment in the input buffer to the end of the - output buffer, including the initial "/" character (if any) and any - subsequent characters up to, but not including, the next "/" character - or the end of the input buffer. */ - - result = curlx_dyn_addn(&out, input, 1); - input++; - clen--; - } -end: - if(!result) { - if(curlx_dyn_len(&out)) - *outp = curlx_dyn_ptr(&out); - else { - *outp = curlx_strdup(""); - if(!*outp) - return 1; - } - } - return result ? 1 : 0; /* success */ -} - -/* - * @unittest 1675 - */ -UNITTEST CURLUcode parse_file(const char *url, size_t urllen, CURLU *u, - const char **pathp, size_t *pathlenp); -UNITTEST CURLUcode parse_file(const char *url, size_t urllen, CURLU *u, - const char **pathp, size_t *pathlenp) -{ - const char *path; - size_t pathlen; - - *pathp = NULL; - *pathlenp = 0; - if(urllen <= 6) - /* file:/ is not enough to actually be a complete file: URL */ - return CURLUE_BAD_FILE_URL; - - /* path has been allocated large enough to hold this */ - path = &url[5]; - pathlen = urllen - 5; - - /* Extra handling URLs with an authority component (i.e. that start with - * "file://") - * - * We allow omitted hostname (e.g. file:/) -- valid according to - * RFC 8089, but not the (current) WHAT-WG URL spec. - */ - if(path[0] == '/' && path[1] == '/') { - /* swallow the two slashes */ - const char *ptr = &path[2]; - - /* - * According to RFC 8089, a file: URL can be reliably dereferenced if: - * - * o it has no/blank hostname, or - * - * o the hostname matches "localhost" (case-insensitively), or - * - * o the hostname is a FQDN that resolves to this machine, or - * - * For brevity, we only consider URLs with empty, "localhost", or - * "127.0.0.1" hostnames as local, otherwise as an UNC String. - * - * Additionally, there is an exception for URLs with a Windows drive - * letter in the authority (which was accidentally omitted from RFC 8089 - * Appendix E, but believe me, it was meant to be there. --MK) - */ - if(ptr[0] != '/' && !STARTS_WITH_URL_DRIVE_PREFIX(ptr)) { - /* the URL includes a hostname, it must match "localhost" or - "127.0.0.1" to be valid */ - if(checkprefix("localhost/", ptr) || - checkprefix("127.0.0.1/", ptr)) { - ptr += 9; /* now points to the slash after the host */ - } - else - /* Invalid file://hostname/, expected localhost or 127.0.0.1 or - none */ - return CURLUE_BAD_FILE_URL; - } - - path = ptr; - pathlen = urllen - (ptr - url); - } - -#if !defined(_WIN32) && !defined(MSDOS) && !defined(__CYGWIN__) - /* Do not allow Windows drive letters when not in Windows. - * This catches both "file:/c:" and "file:c:" */ - if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || - STARTS_WITH_URL_DRIVE_PREFIX(path)) { - /* File drive letters are only accepted in MS-DOS/Windows */ - return CURLUE_BAD_FILE_URL; - } -#else - /* If the path starts with a slash and a drive letter, ditch the slash */ - if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) { - /* This cannot be done with strcpy, as the memory chunks overlap! */ - path++; - pathlen--; - } -#endif - u->scheme = curlx_strdup("file"); - if(!u->scheme) - return CURLUE_OUT_OF_MEMORY; - - *pathp = path; - *pathlenp = pathlen; - return CURLUE_OK; -} - -static CURLUcode parse_scheme(const char *url, CURLU *u, char *schemebuf, - size_t schemelen, unsigned int flags, - const char **hostpp) -{ - /* clear path */ - const char *schemep = NULL; - - if(schemelen) { - int i = 0; - const char *p = &url[schemelen + 1]; - while((*p == '/') && (i < 4)) { - p++; - i++; - } - - schemep = schemebuf; - if(!Curl_get_scheme(schemep) && - !(flags & CURLU_NON_SUPPORT_SCHEME)) - return CURLUE_UNSUPPORTED_SCHEME; - - if((i < 1) || (i > 3)) - /* less than one or more than three slashes */ - return CURLUE_BAD_SLASHES; - - *hostpp = p; /* hostname starts here */ - } - else { - /* no scheme! */ - - if(!(flags & (CURLU_DEFAULT_SCHEME | CURLU_GUESS_SCHEME))) - return CURLUE_BAD_SCHEME; - - if(flags & CURLU_DEFAULT_SCHEME) - schemep = DEFAULT_SCHEME; - - /* - * The URL was badly formatted, let's try without scheme specified. - */ - *hostpp = url; - } - - if(schemep) { - u->scheme = curlx_strdup(schemep); - if(!u->scheme) - return CURLUE_OUT_OF_MEMORY; - } - return CURLUE_OK; -} - -static CURLUcode guess_scheme(CURLU *u, struct dynbuf *host) -{ - const char *hostname = curlx_dyn_ptr(host); - const char *schemep = NULL; - /* legacy curl-style guess based on hostname */ - if(checkprefix("ftp.", hostname)) - schemep = "ftp"; - else if(checkprefix("dict.", hostname)) - schemep = "dict"; - else if(checkprefix("ldap.", hostname)) - schemep = "ldap"; - else if(checkprefix("imap.", hostname)) - schemep = "imap"; - else if(checkprefix("smtp.", hostname)) - schemep = "smtp"; - else if(checkprefix("pop3.", hostname)) - schemep = "pop3"; - else - schemep = "http"; - - u->scheme = curlx_strdup(schemep); - if(!u->scheme) - return CURLUE_OUT_OF_MEMORY; - - u->guessed_scheme = TRUE; - return CURLUE_OK; -} - -static CURLUcode handle_fragment(CURLU *u, const char *fragment, - size_t fraglen, unsigned int flags) -{ - CURLUcode ures; - u->fragment_present = TRUE; - if(fraglen > 1) { - /* skip the leading '#' in the copy but include the terminating null */ - if(flags & CURLU_URLENCODE) { - struct dynbuf enc; - curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - ures = urlencode_str(&enc, fragment + 1, fraglen - 1, TRUE, QUERY_NO); - if(ures) - return ures; - u->fragment = curlx_dyn_ptr(&enc); - } - else { - u->fragment = curlx_memdup0(fragment + 1, fraglen - 1); - if(!u->fragment) - return CURLUE_OUT_OF_MEMORY; - } - } - return CURLUE_OK; -} - -static CURLUcode handle_query(CURLU *u, const char *query, - size_t qlen, unsigned int flags) -{ - u->query_present = TRUE; - if(qlen > 1) { - if(flags & CURLU_URLENCODE) { - struct dynbuf enc; - CURLUcode ures; - curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - /* skip the leading question mark */ - ures = urlencode_str(&enc, query + 1, qlen - 1, TRUE, QUERY_YES); - if(ures) - return ures; - u->query = curlx_dyn_ptr(&enc); - } - else { - u->query = curlx_memdup0(query + 1, qlen - 1); - if(!u->query) - return CURLUE_OUT_OF_MEMORY; - } - } - else { - /* single byte query */ - u->query = curlx_strdup(""); - if(!u->query) - return CURLUE_OUT_OF_MEMORY; - } - return CURLUE_OK; -} - -static CURLUcode handle_path(CURLU *u, const char *path, - size_t pathlen, unsigned int flags, - bool is_file) -{ - CURLUcode ures; - if(pathlen && (flags & CURLU_URLENCODE)) { - struct dynbuf enc; - curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - ures = urlencode_str(&enc, path, pathlen, TRUE, QUERY_NO); - if(ures) - return ures; - pathlen = curlx_dyn_len(&enc); - path = u->path = curlx_dyn_ptr(&enc); - } - - if(pathlen >= (size_t)(1 + !is_file)) { - /* paths for file:// scheme can be one byte, others need to be two */ - if(!u->path) { - u->path = curlx_memdup0(path, pathlen); - if(!u->path) - return CURLUE_OUT_OF_MEMORY; - path = u->path; - } - else if(flags & CURLU_URLENCODE) - /* it might have encoded more than the path so cut it */ - u->path[pathlen] = 0; - - if(!(flags & CURLU_PATH_AS_IS)) { - /* remove ../ and ./ sequences according to RFC3986 */ - char *dedot; - int err = dedotdotify(path, pathlen, &dedot); - if(err) - return CURLUE_OUT_OF_MEMORY; - if(dedot) { - curlx_free(u->path); - u->path = dedot; - } - } - } - return CURLUE_OK; -} - -static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) -{ - const char *path; - size_t pathlen; - char schemebuf[MAX_SCHEME_LEN + 1]; - size_t schemelen = 0; - size_t urllen; - CURLUcode ures = CURLUE_OK; - struct dynbuf host; - bool is_file = FALSE; - - DEBUGASSERT(url); - - curlx_dyn_init(&host, CURL_MAX_INPUT_LENGTH); - - ures = Curl_junkscan(url, &urllen, !!(flags & CURLU_ALLOW_SPACE)); - if(ures) - goto fail; - - schemelen = Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf), - flags & (CURLU_GUESS_SCHEME | - CURLU_DEFAULT_SCHEME)); - - /* handle the file: scheme */ - if(schemelen && !strcmp(schemebuf, "file")) { - is_file = TRUE; - ures = parse_file(url, urllen, u, &path, &pathlen); - } - else { - const char *hostp = NULL; - size_t hostlen; - ures = parse_scheme(url, u, schemebuf, schemelen, flags, &hostp); - if(ures) - goto fail; - - /* find the end of the hostname + port number */ - hostlen = strcspn(hostp, "/?#"); - path = &hostp[hostlen]; - - /* this pathlen also contains the query and the fragment */ - pathlen = urllen - (path - url); - if(hostlen) { - ures = parse_authority(u, hostp, hostlen, flags, &host, - u->scheme != NULL); - if(!ures && (flags & CURLU_GUESS_SCHEME) && !u->scheme) - ures = guess_scheme(u, &host); - } - else if(flags & CURLU_NO_AUTHORITY) { - /* allowed to be empty. */ - if(curlx_dyn_add(&host, "")) - ures = CURLUE_OUT_OF_MEMORY; - } - else - ures = CURLUE_NO_HOST; - } - if(!ures) { - /* The path might at this point contain a fragment and/or a query to - handle */ - const char *fragment = strchr(path, '#'); - if(fragment) { - size_t fraglen = pathlen - (fragment - path); - ures = handle_fragment(u, fragment, fraglen, flags); - /* after this, pathlen still contains the query */ - pathlen -= fraglen; - } - } - if(!ures) { - const char *query = memchr(path, '?', pathlen); - if(query) { - size_t qlen = pathlen - (query - path); - ures = handle_query(u, query, qlen, flags); - pathlen -= qlen; - } - } - if(!ures) - /* the fragment and query parts are trimmed off from the path */ - ures = handle_path(u, path, pathlen, flags, is_file); - if(!ures) { - u->host = curlx_dyn_ptr(&host); - return CURLUE_OK; - } -fail: - curlx_dyn_free(&host); - free_urlhandle(u); - return ures; -} - -/* - * Parse the URL and, if successful, replace everything in the Curl_URL struct. - */ -static CURLUcode parseurl_and_replace(const char *url, CURLU *u, - unsigned int flags) -{ - CURLUcode ures; - CURLU tmpurl; - memset(&tmpurl, 0, sizeof(tmpurl)); - ures = parseurl(url, &tmpurl, flags); - if(!ures) { - free_urlhandle(u); - *u = tmpurl; - } - return ures; -} - -/* - * Concatenate a relative URL onto a base URL making it absolute. - */ -static CURLUcode redirect_url(const char *base, const char *relurl, - CURLU *u, unsigned int flags) -{ - struct dynbuf urlbuf; - bool host_changed = FALSE; - const char *useurl = relurl; - const char *cutoff = NULL; - size_t prelen; - CURLUcode uc; - - /* protsep points to the start of the hostname, after [scheme]:// */ - const char *protsep = base + strlen(u->scheme) + 3; - DEBUGASSERT(base && relurl && u); /* all set here */ - if(!base) - return CURLUE_MALFORMED_INPUT; /* should never happen */ - - /* handle different relative URL types */ - switch(relurl[0]) { - case '/': - if(relurl[1] == '/') { - /* protocol-relative URL: //example.com/path */ - cutoff = protsep; - useurl = &relurl[2]; - host_changed = TRUE; - } - else - /* absolute /path */ - cutoff = strchr(protsep, '/'); - break; - - case '#': - /* fragment-only change */ - if(u->fragment) - cutoff = strchr(protsep, '#'); - break; - - default: - /* path or query-only change */ - if(u->query && u->query[0]) - /* remove existing query */ - cutoff = strchr(protsep, '?'); - else if(u->fragment && u->fragment[0]) - /* Remove existing fragment */ - cutoff = strchr(protsep, '#'); - - if(relurl[0] != '?') { - /* append a relative path after the last slash */ - cutoff = memrchr(protsep, '/', - cutoff ? (size_t)(cutoff - protsep) : strlen(protsep)); - if(cutoff) - cutoff++; /* truncate after last slash */ - } - break; - } - - prelen = cutoff ? (size_t)(cutoff - base) : strlen(base); - - /* build new URL */ - curlx_dyn_init(&urlbuf, CURL_MAX_INPUT_LENGTH); - - if(!curlx_dyn_addn(&urlbuf, base, prelen) && - !urlencode_str(&urlbuf, useurl, strlen(useurl), !host_changed, - QUERY_NOT_YET)) { - uc = parseurl_and_replace(curlx_dyn_ptr(&urlbuf), u, - flags & ~U_CURLU_PATH_AS_IS); - } - else - uc = CURLUE_OUT_OF_MEMORY; - - curlx_dyn_free(&urlbuf); - return uc; -} - -/* - */ -CURLU *curl_url(void) -{ - return curlx_calloc(1, sizeof(struct Curl_URL)); -} - -void curl_url_cleanup(CURLU *u) -{ - if(u) { - free_urlhandle(u); - curlx_free(u); - } -} - -#define DUP(dest, src, name) \ - do { \ - if((src)->name) { \ - (dest)->name = curlx_strdup((src)->name); \ - if(!(dest)->name) \ - goto fail; \ - } \ - } while(0) - -CURLU *curl_url_dup(const CURLU *in) -{ - struct Curl_URL *u = curlx_calloc(1, sizeof(struct Curl_URL)); - if(u) { - DUP(u, in, scheme); - DUP(u, in, user); - DUP(u, in, password); - DUP(u, in, options); - DUP(u, in, host); - DUP(u, in, port); - DUP(u, in, path); - DUP(u, in, query); - DUP(u, in, fragment); - DUP(u, in, zoneid); - u->portnum = in->portnum; - u->fragment_present = in->fragment_present; - u->query_present = in->query_present; - } - return u; -fail: - curl_url_cleanup(u); - return NULL; -} - -#ifndef USE_IDN -#define host_decode(x, y) CURLUE_LACKS_IDN -#define host_encode(x, y) CURLUE_LACKS_IDN -#else -static CURLUcode host_decode(const char *host, char **allochost) -{ - CURLcode result = Curl_idn_decode(host, allochost); - if(result) - return (result == CURLE_OUT_OF_MEMORY) ? - CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; - return CURLUE_OK; -} - -static CURLUcode host_encode(const char *host, char **allochost) -{ - CURLcode result = Curl_idn_encode(host, allochost); - if(result) - return (result == CURLE_OUT_OF_MEMORY) ? - CURLUE_OUT_OF_MEMORY : CURLUE_BAD_HOSTNAME; - return CURLUE_OK; -} -#endif - -static CURLUcode urlget_format(const CURLU *u, CURLUPart what, - const char *ptr, char **partp, - bool plusdecode, unsigned int flags) -{ - CURLUcode uc = CURLUE_OK; - size_t partlen = strlen(ptr); - bool urldecode = (flags & CURLU_URLDECODE) ? 1 : 0; - bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0; - bool punycode = (flags & CURLU_PUNYCODE) && (what == CURLUPART_HOST); - bool depunyfy = (flags & CURLU_PUNY2IDN) && (what == CURLUPART_HOST); - char *part = curlx_memdup0(ptr, partlen); - *partp = NULL; - if(!part) - return CURLUE_OUT_OF_MEMORY; - if(plusdecode) { - /* convert + to space */ - char *plus = part; - size_t i = 0; - for(i = 0; i < partlen; ++plus, i++) { - if(*plus == '+') - *plus = ' '; - } - } - if(urldecode) { - char *decoded; - size_t dlen; - /* this unconditional rejection of control bytes is documented API - behavior */ - CURLcode result = Curl_urldecode(part, partlen, &decoded, &dlen, - REJECT_CTRL); - curlx_free(part); - if(result) - return CURLUE_URLDECODE; - part = decoded; - partlen = dlen; - } - if(urlencode) { - struct dynbuf enc; - curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - uc = urlencode_str(&enc, part, partlen, TRUE, what == CURLUPART_QUERY ? - QUERY_YES : QUERY_NO); - curlx_free(part); - if(uc) - return uc; - part = curlx_dyn_ptr(&enc); - } - else if(punycode) { - if(!Curl_is_ASCII_name(u->host)) { - char *punyversion = NULL; - uc = host_decode(part, &punyversion); - curlx_free(part); - if(uc) - return uc; - part = punyversion; - } - } - else if(depunyfy) { - if(Curl_is_ASCII_name(u->host)) { - char *unpunified = NULL; - uc = host_encode(part, &unpunified); - curlx_free(part); - if(uc) - return uc; - part = unpunified; - } - } - *partp = part; - return CURLUE_OK; -} - -static CURLUcode urlget_url(const CURLU *u, char **part, unsigned int flags) -{ - char *url; - char *allochost = NULL; - const char *fragmentsep = - (u->fragment || (u->fragment_present && flags & CURLU_GET_EMPTY)) ? - "#" : ""; - const char *querysep = ((u->query && u->query[0]) || - (u->query_present && flags & CURLU_GET_EMPTY)) ? - "?" : ""; - char portbuf[7]; - if(u->scheme && curl_strequal("file", u->scheme)) { - url = curl_maprintf("file://%s%s%s%s%s", - u->path, querysep, u->query ? u->query : "", - fragmentsep, u->fragment ? u->fragment : ""); - } - else if(!u->host) - return CURLUE_NO_HOST; - else { - const char *scheme; - char *options = u->options; - char *port = u->port; - const struct Curl_scheme *h = NULL; - char schemebuf[MAX_SCHEME_LEN + 5]; - if(u->scheme) - scheme = u->scheme; - else if(flags & CURLU_DEFAULT_SCHEME) - scheme = DEFAULT_SCHEME; - else - return CURLUE_NO_SCHEME; - - h = Curl_get_scheme(scheme); - if(!port && (flags & CURLU_DEFAULT_PORT)) { - /* there is no stored port number, but asked to deliver - a default one for the scheme */ - if(h) { - curl_msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); - port = portbuf; - } - } - else if(port) { - /* there is a stored port number, but asked to inhibit if it matches - the default one for the scheme */ - if(h && (h->defport == u->portnum) && - (flags & CURLU_NO_DEFAULT_PORT)) - port = NULL; - } - - if(h && !(h->flags & PROTOPT_URLOPTIONS)) - options = NULL; - - if(u->host[0] == '[') { - if(u->zoneid) { - /* make it '[ host %25 zoneid ]' */ - struct dynbuf enc; - size_t hostlen = strlen(u->host); - curlx_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - if(curlx_dyn_addf(&enc, "%.*s%%25%s]", (int)hostlen - 1, u->host, - u->zoneid)) - return CURLUE_OUT_OF_MEMORY; - allochost = curlx_dyn_ptr(&enc); - } - } - else if(flags & CURLU_URLENCODE) { - allochost = curl_easy_escape(NULL, u->host, 0); - if(!allochost) - return CURLUE_OUT_OF_MEMORY; - } - else if(flags & CURLU_PUNYCODE) { - if(!Curl_is_ASCII_name(u->host)) { - CURLUcode ret = host_decode(u->host, &allochost); - if(ret) - return ret; - } - } - else if(flags & CURLU_PUNY2IDN) { - if(Curl_is_ASCII_name(u->host)) { - CURLUcode ret = host_encode(u->host, &allochost); - if(ret) - return ret; - } - } - - if(!(flags & CURLU_NO_GUESS_SCHEME) || !u->guessed_scheme) - curl_msnprintf(schemebuf, sizeof(schemebuf), "%s://", scheme); - else - schemebuf[0] = 0; - - url = curl_maprintf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - schemebuf, - u->user ? u->user : "", - u->password ? ":" : "", - u->password ? u->password : "", - options ? ";" : "", - options ? options : "", - (u->user || u->password || options) ? "@" : "", - allochost ? allochost : u->host, - port ? ":" : "", - port ? port : "", - u->path ? u->path : "/", - querysep, - u->query ? u->query : "", - fragmentsep, - u->fragment ? u->fragment : ""); - curlx_free(allochost); - } - if(!url) - return CURLUE_OUT_OF_MEMORY; - *part = url; - return CURLUE_OK; -} - -CURLUcode curl_url_get(const CURLU *u, CURLUPart what, - char **part, unsigned int flags) -{ - const char *ptr; - CURLUcode ifmissing = CURLUE_UNKNOWN_PART; - char portbuf[7]; - bool plusdecode = FALSE; - if(!u) - return CURLUE_BAD_HANDLE; - if(!part) - return CURLUE_BAD_PARTPOINTER; - *part = NULL; - - switch(what) { - case CURLUPART_SCHEME: - ptr = u->scheme; - ifmissing = CURLUE_NO_SCHEME; - flags &= ~U_CURLU_URLDECODE; /* never for schemes */ - if((flags & CURLU_NO_GUESS_SCHEME) && u->guessed_scheme) - return CURLUE_NO_SCHEME; - break; - case CURLUPART_USER: - ptr = u->user; - ifmissing = CURLUE_NO_USER; - break; - case CURLUPART_PASSWORD: - ptr = u->password; - ifmissing = CURLUE_NO_PASSWORD; - break; - case CURLUPART_OPTIONS: - ptr = u->options; - ifmissing = CURLUE_NO_OPTIONS; - break; - case CURLUPART_HOST: - ptr = u->host; - ifmissing = CURLUE_NO_HOST; - break; - case CURLUPART_ZONEID: - ptr = u->zoneid; - ifmissing = CURLUE_NO_ZONEID; - break; - case CURLUPART_PORT: - ptr = u->port; - ifmissing = CURLUE_NO_PORT; - flags &= ~U_CURLU_URLDECODE; /* never for port */ - if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) { - /* there is no stored port number, but asked to deliver - a default one for the scheme */ - const struct Curl_scheme *h = Curl_get_scheme(u->scheme); - if(h) { - curl_msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); - ptr = portbuf; - } - } - else if(ptr && u->scheme) { - /* there is a stored port number, but ask to inhibit if - it matches the default one for the scheme */ - const struct Curl_scheme *h = Curl_get_scheme(u->scheme); - if(h && (h->defport == u->portnum) && - (flags & CURLU_NO_DEFAULT_PORT)) - ptr = NULL; - } - break; - case CURLUPART_PATH: - ptr = u->path; - if(!ptr) - ptr = "/"; - break; - case CURLUPART_QUERY: - ptr = u->query; - ifmissing = CURLUE_NO_QUERY; - plusdecode = flags & CURLU_URLDECODE; - if(ptr && !ptr[0] && !(flags & CURLU_GET_EMPTY)) - /* there was a blank query and the user do not ask for it */ - ptr = NULL; - break; - case CURLUPART_FRAGMENT: - ptr = u->fragment; - ifmissing = CURLUE_NO_FRAGMENT; - if(!ptr && u->fragment_present && flags & CURLU_GET_EMPTY) - /* there was a blank fragment and the user asks for it */ - ptr = ""; - break; - case CURLUPART_URL: - return urlget_url(u, part, flags); - default: - ptr = NULL; - break; - } - if(ptr) - return urlget_format(u, what, ptr, part, plusdecode, flags); - - return ifmissing; -} - -static CURLUcode set_url_scheme(CURLU *u, const char *scheme, - unsigned int flags) -{ - size_t plen = strlen(scheme); - const struct Curl_scheme *h = NULL; - if((plen > MAX_SCHEME_LEN) || (plen < 1)) - /* too long or too short */ - return CURLUE_BAD_SCHEME; - /* verify that it is a fine scheme */ - h = Curl_get_scheme(scheme); - if(!(flags & CURLU_NON_SUPPORT_SCHEME) && (!h || !h->run)) - return CURLUE_UNSUPPORTED_SCHEME; - if(!h) { - const char *s = scheme; - if(ISALPHA(*s)) { - /* ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ - s++; - while(--plen) { - if(ISALNUM(*s) || (*s == '+') || (*s == '-') || (*s == '.')) - s++; /* fine */ - else - return CURLUE_BAD_SCHEME; - } - } - else - return CURLUE_BAD_SCHEME; - } - u->guessed_scheme = FALSE; - return CURLUE_OK; -} - -static CURLUcode set_url_port(CURLU *u, const char *provided_port) -{ - char *tmp; - curl_off_t port; - if(!ISDIGIT(provided_port[0])) - /* not a number */ - return CURLUE_BAD_PORT_NUMBER; - if(curlx_str_number(&provided_port, &port, 0xffff) || *provided_port) - /* weirdly provided number, not good! */ - return CURLUE_BAD_PORT_NUMBER; - tmp = curl_maprintf("%" CURL_FORMAT_CURL_OFF_T, port); - if(!tmp) - return CURLUE_OUT_OF_MEMORY; - curlx_free(u->port); - u->port = tmp; - u->portnum = (unsigned short)port; - return CURLUE_OK; -} - -static CURLUcode set_url(CURLU *u, const char *url, size_t part_size, - unsigned int flags) -{ - /* - * Allow a new URL to replace the existing (if any) contents. - * - * If the existing contents is enough for a URL, allow a relative URL to - * replace it. - */ - CURLUcode uc; - char *oldurl = NULL; - - if(!part_size) { - /* a blank URL is not a valid URL unless we already have a complete one - and this is a redirect */ - uc = curl_url_get(u, CURLUPART_URL, &oldurl, flags); - if(!uc) { - /* success, meaning the "" is a fine relative URL, but nothing - changes */ - curlx_free(oldurl); - return CURLUE_OK; - } - if(uc == CURLUE_OUT_OF_MEMORY) - return uc; - return CURLUE_MALFORMED_INPUT; - } - - /* if the new URL is absolute replace the existing with the new. */ - if(Curl_is_absolute_url(url, NULL, 0, - flags & (CURLU_GUESS_SCHEME | CURLU_DEFAULT_SCHEME))) - return parseurl_and_replace(url, u, flags); - - /* if the old URL is incomplete (we cannot get an absolute URL in - 'oldurl'), replace the existing with the new */ - uc = curl_url_get(u, CURLUPART_URL, &oldurl, flags); - if(uc == CURLUE_OUT_OF_MEMORY) - return uc; - else if(uc) - return parseurl_and_replace(url, u, flags); - - DEBUGASSERT(oldurl); /* it is set here */ - /* apply the relative part to create a new URL */ - uc = redirect_url(oldurl, url, u, flags); - curlx_free(oldurl); - return uc; -} - -static CURLUcode urlset_clear(CURLU *u, CURLUPart what) -{ - switch(what) { - case CURLUPART_URL: - free_urlhandle(u); - memset(u, 0, sizeof(struct Curl_URL)); - break; - case CURLUPART_SCHEME: - curlx_safefree(u->scheme); - u->guessed_scheme = FALSE; - break; - case CURLUPART_USER: - curlx_safefree(u->user); - break; - case CURLUPART_PASSWORD: - curlx_safefree(u->password); - break; - case CURLUPART_OPTIONS: - curlx_safefree(u->options); - break; - case CURLUPART_HOST: - curlx_safefree(u->host); - break; - case CURLUPART_ZONEID: - curlx_safefree(u->zoneid); - break; - case CURLUPART_PORT: - u->portnum = 0; - curlx_safefree(u->port); - break; - case CURLUPART_PATH: - curlx_safefree(u->path); - break; - case CURLUPART_QUERY: - curlx_safefree(u->query); - u->query_present = FALSE; - break; - case CURLUPART_FRAGMENT: - curlx_safefree(u->fragment); - u->fragment_present = FALSE; - break; - default: - return CURLUE_UNKNOWN_PART; - } - return CURLUE_OK; -} - -static bool allowed_in_path(unsigned char x) -{ - switch(x) { - case '!': - case '$': - case '&': - case '\'': - case '(': - case ')': - case '{': - case '}': - case '[': - case ']': - case '*': - case '+': - case ',': - case ';': - case '=': - case ':': - case '@': - case '/': - return TRUE; - } - return FALSE; -} - -CURLUcode curl_url_set(CURLU *u, CURLUPart what, - const char *part, unsigned int flags) -{ - char **storep = NULL; - bool urlencode = (flags & CURLU_URLENCODE) ? 1 : 0; - bool plusencode = FALSE; - bool pathmode = FALSE; - bool leadingslash = FALSE; - bool appendquery = FALSE; - bool equalsencode = FALSE; - size_t nalloc; - - if(!u) - return CURLUE_BAD_HANDLE; - if(!part) - /* setting a part to NULL clears it */ - return urlset_clear(u, what); - - nalloc = strlen(part); - if(nalloc > CURL_MAX_INPUT_LENGTH) - /* excessive input length */ - return CURLUE_MALFORMED_INPUT; - - switch(what) { - case CURLUPART_SCHEME: { - CURLUcode status = set_url_scheme(u, part, flags); - if(status) - return status; - storep = &u->scheme; - urlencode = FALSE; /* never */ - break; - } - case CURLUPART_USER: - storep = &u->user; - break; - case CURLUPART_PASSWORD: - storep = &u->password; - break; - case CURLUPART_OPTIONS: - storep = &u->options; - break; - case CURLUPART_HOST: - storep = &u->host; - curlx_safefree(u->zoneid); - break; - case CURLUPART_ZONEID: - storep = &u->zoneid; - break; - case CURLUPART_PORT: - return set_url_port(u, part); - case CURLUPART_PATH: - pathmode = TRUE; - leadingslash = TRUE; /* enforce */ - storep = &u->path; - break; - case CURLUPART_QUERY: - plusencode = urlencode; - appendquery = (flags & CURLU_APPENDQUERY) ? 1 : 0; - equalsencode = appendquery; - storep = &u->query; - u->query_present = TRUE; - break; - case CURLUPART_FRAGMENT: - storep = &u->fragment; - u->fragment_present = TRUE; - break; - case CURLUPART_URL: - return set_url(u, part, nalloc, flags); - default: - return CURLUE_UNKNOWN_PART; - } - DEBUGASSERT(storep); - { - const char *newp; - struct dynbuf enc; - curlx_dyn_init(&enc, (nalloc * 3) + 1 + leadingslash); - - if(leadingslash && (part[0] != '/')) { - CURLcode result = curlx_dyn_addn(&enc, "/", 1); - if(result) - return cc2cu(result); - } - if(urlencode) { - const unsigned char *i; - - for(i = (const unsigned char *)part; *i; i++) { - CURLcode result; - if((*i == ' ') && plusencode) { - result = curlx_dyn_addn(&enc, "+", 1); - if(result) - return CURLUE_OUT_OF_MEMORY; - } - else if(ISUNRESERVED(*i) || - (pathmode && allowed_in_path(*i)) || - ((*i == '=') && equalsencode)) { - if((*i == '=') && equalsencode) - /* only skip the first equals sign */ - equalsencode = FALSE; - result = curlx_dyn_addn(&enc, i, 1); - if(result) - return cc2cu(result); - } - else { - unsigned char out[3] = { '%' }; - Curl_hexbyte(&out[1], *i); - result = curlx_dyn_addn(&enc, out, 3); - if(result) - return cc2cu(result); - } - } - } - else { - char *p; - CURLcode result = curlx_dyn_add(&enc, part); - if(result) - return cc2cu(result); - p = curlx_dyn_ptr(&enc); - while(*p) { - /* make sure percent encoded are lower case */ - if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) && - (ISUPPER(p[1]) || ISUPPER(p[2]))) { - p[1] = Curl_raw_tolower(p[1]); - p[2] = Curl_raw_tolower(p[2]); - p += 3; - } - else - p++; - } - } - newp = curlx_dyn_ptr(&enc); - - if(appendquery && newp) { - /* Append the 'newp' string onto the old query. Add a '&' separator if - none is present at the end of the existing query already */ - - size_t querylen = u->query ? strlen(u->query) : 0; - bool addamperand = querylen && (u->query[querylen - 1] != '&'); - if(querylen) { - struct dynbuf qbuf; - curlx_dyn_init(&qbuf, CURL_MAX_INPUT_LENGTH); - - if(curlx_dyn_addn(&qbuf, u->query, querylen)) /* add original query */ - goto nomem; - - if(addamperand) { - if(curlx_dyn_addn(&qbuf, "&", 1)) - goto nomem; - } - if(curlx_dyn_add(&qbuf, newp)) - goto nomem; - curlx_dyn_free(&enc); - curlx_free(*storep); - *storep = curlx_dyn_ptr(&qbuf); - return CURLUE_OK; -nomem: - curlx_dyn_free(&enc); - return CURLUE_OUT_OF_MEMORY; - } - } - - else if(what == CURLUPART_HOST) { - size_t n = curlx_dyn_len(&enc); - if(!n && (flags & CURLU_NO_AUTHORITY)) { - /* Skip hostname check, it is allowed to be empty. */ - } - else { - bool bad = FALSE; - if(!n) - bad = TRUE; /* empty hostname is not okay */ - else if(!urlencode) { - /* if the hostname part was not URL encoded here, it was set ready - URL encoded so we need to decode it to check */ - size_t dlen; - char *decoded = NULL; - CURLcode result = - Curl_urldecode(newp, n, &decoded, &dlen, REJECT_CTRL); - if(result || hostname_check(u, decoded, dlen)) - bad = TRUE; - curlx_free(decoded); - } - else if(hostname_check(u, (char *)CURL_UNCONST(newp), n)) - bad = TRUE; - if(bad) { - curlx_dyn_free(&enc); - return CURLUE_BAD_HOSTNAME; - } - } - } - - curlx_free(*storep); - *storep = (char *)CURL_UNCONST(newp); - } - return CURLUE_OK; -} - -bool Curl_url_same_origin(CURLU *base, CURLU *href) -{ - const struct Curl_scheme *s = NULL; - - /* base must be an absolute URL */ - if(!base->scheme || !base->host) - return FALSE; - if(href->scheme && !curl_strequal(base->scheme, href->scheme)) - return FALSE; - if(href->host) { - if(!curl_strequal(base->host, href->host)) - return FALSE; - if(!curl_strequal(base->port, href->port)) { - /* This may still match if only one has an explicit port - * and it is the default for the scheme. */ - if(base->port && href->port) - return FALSE; - - s = Curl_get_scheme(base->scheme); - if(!s) /* Cannot match default port for unknown scheme */ - return FALSE; - - /* The port which is set must be the default one */ - if((base->port && (base->portnum != s->defport)) || - (href->port && (href->portnum != s->defport))) - return FALSE; - } - } - else if(href->port) /* no host in href, then there must be no port */ - return FALSE; - return TRUE; -} diff --git a/vendor/curl/lib/urldata.h b/vendor/curl/lib/urldata.h deleted file mode 100644 index f35bfee05..000000000 --- a/vendor/curl/lib/urldata.h +++ /dev/null @@ -1,1420 +0,0 @@ -#ifndef HEADER_CURL_URLDATA_H -#define HEADER_CURL_URLDATA_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* This file is for lib internal stuff */ -#include "curl_setup.h" - -#define CURL_DEFAULT_USER "anonymous" -#define CURL_DEFAULT_PASSWORD "ftp@example.com" - -#if !defined(_WIN32) && !defined(MSDOS) -/* do FTP line-end CRLF => LF conversions on platforms that prefer LF-only. It - also means: keep CRLF line endings on the CRLF platforms */ -#define CURL_PREFER_LF_LINEENDS -#endif - -#define DEFAULT_CONNCACHE_SIZE 5 - -/* length of longest IPv6 address string including the trailing null */ -#define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - -/* Max string input length is a precaution against abuse and to detect junk - input easier and better. */ -#define CURL_MAX_INPUT_LENGTH 8000000 - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif - -#include "curlx/timeval.h" - -#include "asyn.h" -#include "cookie.h" -#include "psl.h" -#include "formdata.h" -#include "http_chunks.h" /* for the structs and enum stuff */ -#include "hostip.h" -#include "hash.h" -#include "splay.h" -#include "curlx/dynbuf.h" -#include "bufref.h" -#include "dynhds.h" -#include "request.h" -#include "ratelimit.h" -#include "netrc.h" - -/* On error return, the value of `pnwritten` has no meaning */ -typedef CURLcode (Curl_send)(struct Curl_easy *data, /* transfer */ - int sockindex, /* socketindex */ - const uint8_t *buf, /* data to write */ - size_t len, /* amount to send */ - bool eos, /* last chunk */ - size_t *pnwritten); /* how much sent */ - -/* On error return, the value of `pnread` has no meaning */ -typedef CURLcode (Curl_recv)(struct Curl_easy *data, /* transfer */ - int sockindex, /* socketindex */ - char *buf, /* store data here */ - size_t len, /* max amount to read */ - size_t *pnread); /* how much received */ - -#include "mime.h" -#include "protocol.h" -#include "ftp.h" -#include "http.h" -#include "smb.h" -#include "mqtt.h" -#include "ftplistparser.h" -#include "multihandle.h" -#include "cf-socket.h" - -#ifdef HAVE_GSSAPI -# ifdef HAVE_GSSGNU -# include -# elif defined(HAVE_GSSAPI_H) -# include -# else /* MIT Kerberos */ -# include -# include /* for GSS_C_CHANNEL_BOUND_FLAG in 1.19+ */ -# endif -#endif - -#ifdef USE_LIBSSH2 -#include -#include -#endif /* USE_LIBSSH2 */ - -#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE -#define READBUFFER_MAX CURL_MAX_READ_SIZE -#define READBUFFER_MIN 1024 - -/* The default upload buffer size, should not be smaller than - CURL_MAX_WRITE_SIZE, as it needs to hold a full buffer as could be sent in - a write callback. - - The size was 16KB for many years but was bumped to 64KB because it makes - libcurl able to do significantly faster uploads in some circumstances. Even - larger buffers can help further, but this is deemed a fair memory/speed - compromise. */ -#define UPLOADBUFFER_DEFAULT 65536 -#define UPLOADBUFFER_MAX (2 * 1024 * 1024) -#define UPLOADBUFFER_MIN CURL_MAX_WRITE_SIZE - -#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU -#ifdef DEBUGBUILD -/* On a debug build, we want to fail hard on easy handles that - * are not NULL, but no longer have the MAGIC touch. This gives - * us early warning on things only discovered by valgrind otherwise. */ -#define GOOD_EASY_HANDLE(x) \ - (((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) ? TRUE : \ - (DEBUGASSERT(!(x)), FALSE)) -#else -#define GOOD_EASY_HANDLE(x) \ - ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) -#endif - -struct ssl_primary_config { - char *CApath; /* certificate directory (does not work on Windows) */ - char *CAfile; /* certificate to verify peer against */ - char *issuercert; /* optional issuer certificate filename */ - char *clientcert; - char *cipher_list; /* list of ciphers to use */ - char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ - char *signature_algorithms; /* list of signature algorithms to use */ - char *pinned_key; - char *CRLfile; /* CRL to check certificate revocation */ - struct curl_blob *cert_blob; - struct curl_blob *ca_info_blob; - struct curl_blob *issuercert_blob; -#ifdef USE_TLS_SRP - char *username; /* TLS username (for, e.g., SRP) */ - char *password; /* TLS password (for, e.g., SRP) */ -#endif - char *curves; /* list of curves to use */ - uint32_t version_max; /* max supported version the client wants to use */ - uint8_t ssl_options; /* the CURLOPT_SSL_OPTIONS bitmask */ - uint8_t version; /* what version the client wants to use */ - BIT(verifypeer); /* set TRUE if this is desired */ - BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ - BIT(verifystatus); /* set TRUE if certificate status must be checked */ - BIT(cache_session); /* cache session or not */ -}; - -struct ssl_config_data { - struct ssl_primary_config primary; - long certverifyresult; /* result from the certificate verification */ - curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ - void *fsslctxp; /* parameter for call back */ - char *cert_type; /* format for certificate (default: PEM) */ - char *key; /* private key filename */ - struct curl_blob *key_blob; - char *key_type; /* format for private key (default: PEM) */ - char *key_passwd; /* plain text private key password */ - BIT(certinfo); /* gather lots of certificate info */ - BIT(earlydata); /* use TLS 1.3 early data */ - BIT(enable_beast); /* allow this flaw for interoperability's sake */ - BIT(no_revoke); /* disable SSL certificate revocation checks */ - BIT(no_partialchain); /* do not accept partial certificate chains */ - BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation - list errors */ - BIT(native_ca_store); /* use the native CA store of operating system */ - BIT(auto_client_cert); /* automatically locate and use a client - certificate for authentication (Schannel) */ - BIT(custom_cafile); /* application has set custom CA file */ - BIT(custom_capath); /* application has set custom CA path */ - BIT(custom_cablob); /* application has set custom CA blob */ -}; - -struct ssl_general_config { - int ca_cache_timeout; /* Certificate store cache timeout (seconds) */ -}; - -#ifdef USE_WINDOWS_SSPI -#include "curl_sspi.h" -#endif - -#ifndef CURL_DISABLE_DIGEST_AUTH -/* Struct used for Digest challenge-response authentication */ -struct digestdata { -#ifdef USE_WINDOWS_SSPI - BYTE *input_token; - size_t input_token_len; - CtxtHandle *http_context; - /* copy of user/passwd used to make the identity for http_context. - either may be NULL. */ - char *user; - char *passwd; -#else - char *nonce; - char *cnonce; - char *realm; - char *opaque; - char *qop; - char *algorithm; - int nc; /* nonce count */ - uint8_t algo; - BIT(stale); /* set true for re-negotiation */ - BIT(userhash); -#endif -}; -#endif - -typedef enum { - NTLMSTATE_NONE, - NTLMSTATE_TYPE1, - NTLMSTATE_TYPE2, - NTLMSTATE_TYPE3, - NTLMSTATE_LAST -} curlntlm; - -typedef enum { - GSS_AUTHNONE, - GSS_AUTHRECV, - GSS_AUTHSENT, - GSS_AUTHDONE, - GSS_AUTHSUCC -} curlnegotiate; - -/* - * Boolean values that concerns this connection. - */ -struct ConnectBits { - BIT(connect_only); -#ifndef CURL_DISABLE_PROXY - BIT(httpproxy); /* if set, this transfer is done through an HTTP proxy */ - BIT(socksproxy); /* if set, this transfer is done through a socks proxy */ - BIT(proxy_user_passwd); /* user+password for the proxy? */ - BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy. - This is implicit when SSL-protocols are used through - proxies, but can also be enabled explicitly by - apps */ - BIT(proxy); /* if set, this transfer is done through a proxy - any type */ -#endif - /* always modify bits.close with the connclose() and connkeep() macros! */ - BIT(close); /* if set, we close the connection after this request */ - BIT(reuse); /* if set, this is a reused connection */ - BIT(altused); /* this is an alt-svc "redirect" */ - BIT(conn_to_host); /* if set, this connection has a "connect to host" - that overrides the host in the URL */ - BIT(conn_to_port); /* if set, this connection has a "connect to port" - that overrides the port in the URL (remote port) */ - BIT(ipv6); /* we communicate with a site using an IPv6 address */ - BIT(do_more); /* this is set TRUE if the ->curl_do_more() function is - supposed to be called, after ->curl_do() */ - BIT(protoconnstart);/* the protocol layer has STARTED its operation after - the TCP layer connect */ - BIT(retry); /* this connection is about to get closed and then - re-attempted at another connection. */ -#ifndef CURL_DISABLE_FTP - BIT(ftp_use_epsv); /* As set with CURLOPT_FTP_USE_EPSV, but if we find out - EPSV does not work we disable it for the forthcoming - requests */ - BIT(ftp_use_eprt); /* As set with CURLOPT_FTP_USE_EPRT, but if we find out - EPRT does not work we disable it for the forthcoming - requests */ - BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */ - BIT(ftp_use_control_ssl); /* Enabled SSL for the control connection */ -#endif -#ifndef CURL_DISABLE_NETRC - BIT(netrc); /* name+password provided by netrc */ -#endif - BIT(bound); /* set true if bind() has already been done on this socket/ - connection */ - BIT(upgrade_in_progress); /* protocol upgrade is in progress */ - BIT(multiplex); /* connection is multiplexed */ - BIT(tcp_fastopen); /* use TCP Fast Open */ - BIT(tls_enable_alpn); /* TLS ALPN extension? */ -#ifdef USE_UNIX_SOCKETS - BIT(abstract_unix_socket); -#endif - BIT(sock_accepted); /* TRUE if the SECONDARYSOCKET was created with - accept() */ - BIT(parallel_connect); /* set TRUE when a parallel connect attempt has - started (happy eyeballs) */ - BIT(aborted); /* connection was aborted, e.g. in unclean state */ - BIT(no_reuse); /* connection should not be reused */ - BIT(shutdown_handler); /* connection shutdown: handler shut down */ - BIT(shutdown_filters); /* connection shutdown: filters shut down */ - BIT(in_cpool); /* connection is kept in a connection pool */ - BIT(dns_resolved); /* DNS records for connection were resolved */ -}; - -struct hostname { - char *rawalloc; /* allocated "raw" version of the name */ - char *encalloc; /* allocated IDN-encoded version of the name */ - char *name; /* name to use internally, might be encoded, might be raw */ - const char *dispname; /* name to display, as 'name' might be encoded */ -}; - -#define FIRSTSOCKET 0 -#define SECONDARYSOCKET 1 - -#define TRNSPRT_NONE 0 -#define TRNSPRT_TCP 3 -#define TRNSPRT_UDP 4 -#define TRNSPRT_QUIC 5 -#define TRNSPRT_UNIX 6 - -struct ip_quadruple { - char remote_ip[MAX_IPADR_LEN]; - char local_ip[MAX_IPADR_LEN]; - uint16_t remote_port; - uint16_t local_port; - uint8_t transport; -}; - -#define CUR_IP_QUAD_HAS_PORTS(x) \ - (((x)->transport == TRNSPRT_TCP) || \ - ((x)->transport == TRNSPRT_UDP) || \ - ((x)->transport == TRNSPRT_QUIC)) - -struct proxy_info { - struct hostname host; - uint16_t port; - uint8_t proxytype; /* what kind of proxy that is in use */ - char *user; /* proxy username string, allocated */ - char *passwd; /* proxy password string, allocated */ -}; - -/* - * The connectdata struct contains all fields and variables that should be - * unique for an entire connection. - */ -struct connectdata { - struct Curl_llist_node cpool_node; /* conncache lists */ - struct Curl_llist_node cshutdn_node; /* cshutdn list */ - - curl_closesocket_callback fclosesocket; /* function closing the socket(s) */ - void *closesocket_client; - - /* This is used by the connection pool logic. If this returns TRUE, this - handle is still used by one or more easy handles and can only used by any - other easy handle without careful consideration (== only for - multiplexing) and it cannot be used by another multi handle! */ -#define CONN_INUSE(c) (!!(c)->attached_xfers) - - /**** Fields set when inited and not modified again */ - curl_off_t connection_id; /* Contains a unique number to make it easier to - track the connections in the log output */ - char *destination; /* string carrying normalized hostname+port+scope */ - - /* `meta_hash` is a general key-value store for implementations - * with the lifetime of the connection. - * Elements need to be added with their own destructor to be invoked when - * the connection is cleaned up (see Curl_hash_add2()).*/ - struct Curl_hash meta_hash; - - struct hostname host; - char *secondaryhostname; /* secondary socket hostname (ftp) */ - struct hostname conn_to_host; /* the host to connect to. valid only if - bits.conn_to_host is set */ -#ifndef CURL_DISABLE_PROXY - struct proxy_info socks_proxy; - struct proxy_info http_proxy; -#endif - char *user; /* username string, allocated */ - char *passwd; /* password string, allocated */ - char *options; /* options string, allocated */ - char *sasl_authzid; /* authorization identity string, allocated */ - char *oauth_bearer; /* OAUTH2 bearer, allocated */ - struct curltime created; /* creation time */ - struct curltime lastused; /* when returned to the connection pool as idle */ - - /* A connection can have one or two sockets and connection filters. - * The protocol using the 2nd one is FTP for CONTROL+DATA sockets */ - curl_socket_t sock[2]; - struct Curl_cfilter *cfilter[2]; /* connection filters */ - Curl_recv *recv[2]; - Curl_send *send[2]; - int recv_idx; /* on which socket index to receive, default 0 */ - int send_idx; /* on which socket index to send, default 0 */ - -#define CONN_SOCK_IDX_VALID(i) (((i) >= 0) && ((i) < 2)) - - struct { - struct curltime start[2]; /* when filter shutdown started */ - timediff_t timeout_ms; /* 0 means no timeout */ - } shutdown; - - struct ssl_primary_config ssl_config; -#ifndef CURL_DISABLE_PROXY - struct ssl_primary_config proxy_ssl_config; -#endif - struct ConnectBits bits; /* various state-flags for this connection */ - - const struct Curl_scheme *scheme; /* Connection's protocol handler */ - const struct Curl_scheme *given; /* The protocol first given */ - - /* Protocols can use a custom keepalive mechanism to keep connections alive. - This allows those protocols to track the last time the keepalive mechanism - was used on this connection. */ - struct curltime keepalive; - - /* A connection cache from a SHARE might be used in several multi handles. - * We MUST not reuse connections that are running in another multi, - * for concurrency reasons. That multi might run in another thread. - * `attached_multi` is set by the first transfer attached and cleared - * when the last one is detached. - * NEVER call anything on this multi, check for equality. */ - struct Curl_multi *attached_multi; - - /*************** Request - specific items ************/ -#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) - CtxtHandle *sslContext; /* mingw-w64 v9+. MS SDK 7.0A+. */ -#endif - -#ifdef USE_NTLM - curlntlm http_ntlm_state; - curlntlm proxy_ntlm_state; -#endif - -#ifdef USE_SPNEGO - curlnegotiate http_negotiate_state; - curlnegotiate proxy_negotiate_state; -#endif - -#ifdef USE_UNIX_SOCKETS - char *unix_domain_socket; -#endif - - /* When this connection is created, store the conditions for the local end - bind. This is stored before the actual bind and before any connection is - made and will serve the purpose of being used for comparison reasons so - that subsequent bound-requested connections are not accidentally reusing - wrong connections. */ - char *localdev; -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - int socks5_gssapi_enctype; -#endif - uint32_t attached_xfers; /* # of attached easy handles */ - -#ifdef USE_IPV6 - uint32_t scope_id; /* Scope id for IPv6 */ -#endif - /* The field below gets set in connect.c:connecthost() */ - uint16_t remote_port; /* the remote port, not the proxy port! */ - uint16_t conn_to_port; /* the remote port to connect to. valid only if - bits.conn_to_port is set */ - uint16_t localportrange; - uint16_t localport; - uint16_t secondary_port; /* secondary socket remote port to connect to - (ftp) */ - uint8_t transport_wanted; /* one of the TRNSPRT_* defines. Not necessarily - the transport the connection ends using due to Alt-Svc and happy - eyeballing. Use Curl_conn_get_transport() for actual value once the - connection is set up. */ - uint8_t ip_version; /* copied from the Curl_easy at creation time */ - /* HTTP version last responded with by the server or negotiated via ALPN. - * 0 at start, then one of 09, 10, 11, etc. */ - uint8_t httpversion_seen; - uint8_t gssapi_delegation; /* inherited from set.gssapi_delegation */ -}; - -#ifndef CURL_DISABLE_PROXY -#define CURL_CONN_HOST_DISPNAME(c) \ - ((c)->bits.socksproxy ? (c)->socks_proxy.host.dispname : \ - (c)->bits.httpproxy ? (c)->http_proxy.host.dispname : \ - (c)->bits.conn_to_host ? (c)->conn_to_host.dispname : \ - (c)->host.dispname) -#else -#define CURL_CONN_HOST_DISPNAME(c) \ - (c)->bits.conn_to_host ? (c)->conn_to_host.dispname : \ - (c)->host.dispname -#endif - -/* The end of connectdata. */ - -/* - * Struct to keep statistical and informational data. - * All variables in this struct must be initialized/reset in Curl_initinfo(). - */ -struct PureInfo { - int httpcode; /* Recent HTTP, FTP, RTSP or SMTP response code */ - int httpproxycode; /* response code from proxy when received separate */ - int httpversion; /* the http version number X.Y = X*10+Y */ - time_t filetime; /* If requested, this is might get set. Set to -1 if the - time was unretrievable. */ - curl_off_t request_size; /* the amount of bytes sent in the request(s) */ - curl_off_t numconnects; /* how many new connections libcurl created */ - uint32_t proxyauthavail; /* what proxy auth types were announced */ - uint32_t httpauthavail; /* what host auth types were announced */ - uint32_t proxyauthpicked; /* selected proxy auth type */ - uint32_t httpauthpicked; /* selected host auth type */ - char *contenttype; /* the content type of the object */ - char *wouldredirect; /* URL this would have been redirected to if asked to */ - curl_off_t retry_after; /* info from Retry-After: header */ - uint32_t header_size; /* size of read header(s) in bytes */ - - /* PureInfo primary ip_quadruple is copied over from the connectdata - struct in order to allow curl_easy_getinfo() to return this information - even when the session handle is no longer associated with a connection, - and also allow curl_easy_reset() to clear this information from the - session handle without disturbing information which is still alive, and - that might be reused, in the connection pool. */ - struct ip_quadruple primary; - int conn_remote_port; /* this is the "remote port", which is the port - number of the used URL, independent of proxy or - not */ - const char *conn_scheme; - uint32_t conn_protocol; - struct curl_certinfo certs; /* info about the certs. Asked for with - CURLOPT_CERTINFO / CURLINFO_CERTINFO */ - CURLproxycode pxcode; - BIT(timecond); /* set to TRUE if the time condition did not match, which - thus made the document NOT get fetched */ - BIT(used_proxy); /* the transfer used a proxy */ -}; - -struct pgrs_dir { - curl_off_t total_size; /* total expected bytes */ - curl_off_t cur_size; /* transferred bytes so far */ - curl_off_t speed; /* bytes per second transferred */ - struct Curl_rlimit rlimit; /* speed limiting / pausing */ -}; - -struct Progress { - struct curltime now; /* current time of processing */ - time_t lastshow; /* time() of the last displayed progress meter or NULL to - force redraw at next call */ - struct pgrs_dir ul; - struct pgrs_dir dl; - curl_off_t deliver; /* amount of data delivered to application */ - - curl_off_t current_speed; /* uses the currently fastest transfer */ - curl_off_t earlydata_sent; - - timediff_t timespent; - - timediff_t t_postqueue; - timediff_t t_nslookup; - timediff_t t_connect; - timediff_t t_appconnect; - timediff_t t_pretransfer; - timediff_t t_posttransfer; - timediff_t t_starttransfer; - timediff_t t_redirect; - - struct curltime start; - struct curltime t_startsingle; - struct curltime t_startop; - struct curltime t_startqueue; - struct curltime t_acceptdata; - -#define CURL_SPEED_RECORDS (5 + 1) /* 6 entries for 5 seconds */ - - curl_off_t speed_amount[CURL_SPEED_RECORDS]; - struct curltime speed_time[CURL_SPEED_RECORDS]; - uint32_t speeder_c; - BIT(hide); - BIT(ul_size_known); - BIT(dl_size_known); - BIT(headers_out); /* when the headers have been written */ - BIT(callback); /* set when progress callback is used */ - BIT(is_t_startransfer_set); -}; - -typedef enum { - RTSPREQ_NONE, /* first in list */ - RTSPREQ_OPTIONS, - RTSPREQ_DESCRIBE, - RTSPREQ_ANNOUNCE, - RTSPREQ_SETUP, - RTSPREQ_PLAY, - RTSPREQ_PAUSE, - RTSPREQ_TEARDOWN, - RTSPREQ_GET_PARAMETER, - RTSPREQ_SET_PARAMETER, - RTSPREQ_RECORD, - RTSPREQ_RECEIVE, - RTSPREQ_LAST /* last in list */ -} Curl_RtspReq; - -struct auth { - uint32_t want; /* Bitmask set to the authentication methods wanted by app - (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */ - uint32_t picked; - uint32_t avail; /* Bitmask for what the server reports to support for this - resource */ - BIT(done); /* TRUE when the auth phase is done and ready to do the - actual request */ - BIT(multipass); /* TRUE if this is not yet authenticated but within the - auth multipass negotiation */ - BIT(iestyle); /* TRUE if digest should be done IE-style or FALSE if it - should be RFC compliant */ -}; - -#ifdef USE_NGHTTP2 -struct Curl_data_prio_node { - struct Curl_data_prio_node *next; - struct Curl_easy *data; -}; -#endif - -/** - * Priority information for an easy handle in relation to others - * on the same connection. - */ -struct Curl_data_priority { -#ifdef USE_NGHTTP2 - /* tree like dependencies only implemented in nghttp2 */ - struct Curl_easy *parent; - struct Curl_data_prio_node *children; -#endif - int weight; -#ifdef USE_NGHTTP2 - BIT(exclusive); -#endif -}; - -/* Timers */ -typedef enum { - EXPIRE_100_TIMEOUT, - EXPIRE_ASYNC_NAME, - EXPIRE_CONNECTTIMEOUT, - EXPIRE_DNS_PER_NAME, /* family1 */ - EXPIRE_DNS_PER_NAME2, /* family2 */ - EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */ - EXPIRE_HAPPY_EYEBALLS, - EXPIRE_MULTI_PENDING, - EXPIRE_SPEEDCHECK, - EXPIRE_TIMEOUT, - EXPIRE_TOOFAST, - EXPIRE_QUIC, - EXPIRE_FTP_ACCEPT, - EXPIRE_ALPN_EYEBALLS, - EXPIRE_SHUTDOWN, - EXPIRE_LAST /* not an actual timer, used as a marker only */ -} expire_id; - -/* - * One instance for each timeout an easy handle can set. - */ -struct time_node { - struct Curl_llist_node list; - struct curltime time; - expire_id eid; -}; - -/* individual pieces of the URL */ -struct urlpieces { - char *scheme; - char *hostname; - char *port; - char *user; - char *password; - char *options; - char *path; - char *query; -}; - -#define CREDS_NONE 0 -#define CREDS_URL 1 /* from URL */ -#define CREDS_OPTION 2 /* set with a CURLOPT_ */ -#define CREDS_NETRC 3 /* found in netrc */ - -struct UrlState { - /* buffers to store authentication data in, as parsed from input options */ - struct curltime keeps_speed; /* for the progress meter really */ - - curl_off_t lastconnect_id; /* The last connection, -1 if undefined */ - curl_off_t recent_conn_id; /* The most recent connection used, might no - * longer exist */ - struct dynbuf headerb; /* buffer to store headers in */ -#ifndef CURL_DISABLE_HSTS - struct curl_slist *hstslist; /* list of HSTS files set by - curl_easy_setopt(HSTS) calls */ -#endif - curl_off_t current_speed; /* the ProgressShow() function sets this, - bytes / second */ - - /* hostname, port number and protocol of the first (not followed) request. - if set, this should be the hostname that we will sent authorization to, - no else. Used to make Location: following not keep sending user+password. - This is strdup()ed data. */ - char *first_host; - int first_remote_port; - curl_prot_t first_remote_protocol; - int os_errno; /* filled in with errno whenever an error occurs */ - int requests; /* request counter: redirects + authentication retakes */ -#ifdef HAVE_SIGNAL - /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */ - void (*prev_signal)(int sig); -#endif -#ifndef CURL_DISABLE_DIGEST_AUTH - struct digestdata digest; /* state data for host Digest auth */ - struct digestdata proxydigest; /* state data for proxy Digest auth */ -#endif - struct auth authhost; /* auth details for host */ - struct auth authproxy; /* auth details for proxy */ - -#ifdef USE_CURL_ASYNC - struct Curl_resolv_async *async; /* asynchronous name resolver data */ -#endif - -#ifdef USE_OPENSSL - /* void instead of ENGINE to avoid bleeding OpenSSL into this header */ - void *engine; - /* void instead of OSSL_PROVIDER */ - void *provider; - void *baseprov; - void *libctx; - char *propq; /* for a provider */ - - BIT(provider_loaded); -#endif /* USE_OPENSSL */ - struct curltime expiretime; /* set this with Curl_expire() only */ - struct Curl_tree timenode; /* for the splay stuff */ - struct Curl_llist timeoutlist; /* list of pending timeouts */ - struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */ - - /* a place to store the most recently set (S)FTP entrypath */ - char *most_recent_ftp_entrypath; - char *range; /* range, if used. See README for detailed specification on - this syntax. */ - curl_off_t resume_from; /* continue [ftp] transfer from here */ - -#ifndef CURL_DISABLE_RTSP - /* This RTSP state information survives requests and connections */ - uint32_t rtsp_next_client_CSeq; /* the session's next client CSeq */ - uint32_t rtsp_next_server_CSeq; /* the session's next server CSeq */ - uint32_t rtsp_CSeq_recv; /* most recent CSeq received */ - uint8_t rtp_channel_mask[32]; /* for the correctness checking of the - interleaved data */ -#endif - - curl_off_t infilesize; /* size of file to upload, -1 means unknown. - Copied from set.filesize at start of operation */ -#if defined(USE_HTTP2) || defined(USE_HTTP3) - struct Curl_data_priority priority; /* shallow copy of data->set */ -#endif - - curl_read_callback fread_func; /* read callback/function */ - void *in; /* CURLOPT_READDATA */ - CURLU *uh; /* URL handle for the current parsed URL */ - struct urlpieces up; - struct bufref url; /* work URL, initially copied from UserDefined */ - struct bufref referer; /* referer string */ - struct curl_slist *resolve; /* set to point to the set.resolve list when - this should be dealt with in pretransfer */ -#ifndef CURL_DISABLE_HTTP - curl_mimepart *mimepost; -#ifndef CURL_DISABLE_FORM_API - curl_mimepart *formp; /* storage for old API form-posting, allocated on - demand */ -#endif - size_t trailers_bytes_sent; - struct dynbuf trailers_buf; /* a buffer containing the compiled trailing - headers */ - struct Curl_llist httphdrs; /* received headers */ - struct curl_header headerout[2]; /* for external purposes */ - struct Curl_header_store *prevhead; /* the latest added header */ -#endif -#ifndef CURL_DISABLE_COOKIES - struct curl_slist *cookielist; /* list of cookie files set by - curl_easy_setopt(COOKIEFILE) calls */ -#endif - -#ifdef CURLVERBOSE - struct curl_trc_feat *feat; /* opt. trace feature transfer is part of */ -#endif - -#ifndef CURL_DISABLE_NETRC - struct store_netrc netrc; -#endif - - /* Dynamically allocated strings, MUST be freed before this struct is - killed. */ - struct dynamically_allocated_data { - char *uagent; - char *accept_encoding; - char *rangeline; - char *ref; - char *host; -#ifndef CURL_DISABLE_RTSP - char *rtsp_transport; -#endif - - /* transfer credentials */ - char *user; - char *passwd; -#ifndef CURL_DISABLE_PROXY - char *proxyuser; - char *proxypasswd; -#endif - } aptr; -#ifndef CURL_DISABLE_HTTP - struct http_negotiation http_neg; -#endif - uint16_t followlocation; /* redirect counter */ - uint8_t retrycount; /* number of retries on a new connection, up to - CONN_MAX_RETRIES */ - uint8_t httpreq; /* Curl_HttpReq; what kind of HTTP request (if any) - is this */ - unsigned int creds_from:2; /* where is the server credentials originating - from, see the CREDS_* defines above */ - - /* when curl_easy_perform() is called, the multi handle is "owned" by - the easy handle so curl_easy_cleanup() on such an easy handle will - also close the multi handle! */ - BIT(multi_owned_by_easy); - - BIT(this_is_a_follow); /* this is a followed Location: request */ - BIT(refused_stream); /* this was refused, try again */ - BIT(errorbuf); /* Set to TRUE if the error buffer is already filled in. - This must be set to FALSE every time _easy_perform() is - called. */ - BIT(allow_port); /* Is set.use_port allowed to take effect or not. This - is always set TRUE when curl_easy_perform() is called. */ - BIT(authproblem); /* TRUE if there is some problem authenticating */ - /* set after initial USER failure, to prevent an authentication loop */ - BIT(wildcardmatch); /* enable wildcard matching */ - BIT(disableexpect); /* TRUE if Expect: is disabled due to a previous - 417 response */ - BIT(use_range); - BIT(rangestringalloc); /* the range string is malloc()'ed */ - BIT(done); /* set to FALSE when Curl_init_do() is called and set to TRUE - when multi_done() is called, to prevent multi_done() to get - invoked twice when the multi interface is used. */ -#ifndef CURL_DISABLE_COOKIES - BIT(cookie_engine); -#endif - BIT(prefer_ascii); /* ASCII rather than binary */ -#ifdef CURL_LIST_ONLY_PROTOCOL - BIT(list_only); /* list directory contents */ -#endif - BIT(wildcard_resolve); /* Set to true if any resolve change is a wildcard */ - BIT(upload); /* upload request */ - BIT(internal); /* internal: true if this easy handle was created for - internal use and the user does not have ownership of the - handle. */ - BIT(http_ignorecustom); /* ignore custom method from now */ -#ifndef CURL_DISABLE_HTTP - BIT(http_hd_te); /* Added HTTP header TE: */ - BIT(http_hd_upgrade); /* Added HTTP header Upgrade: */ - BIT(http_hd_h2_settings); /* Added HTTP header H2Settings: */ - BIT(maybe_folded); - BIT(leading_unfold); /* unfold started, this is the leading bytes */ -#endif -}; - -/* - * This 'UserDefined' struct must only contain data that is set once to go - * for many (perhaps) independent connections. Values that are generated or - * calculated internally for the "session handle" MUST be defined within the - * 'struct UrlState' instead. The only exceptions MUST note the changes in - * the 'DynamicStatic' struct. - * Character pointer fields point to dynamic storage, unless otherwise stated. - */ - -struct Curl_multi; /* declared in multihandle.c */ - -enum dupstring { - STRING_CERT, /* client certificate filename */ - STRING_CERT_TYPE, /* format for certificate (default: PEM)*/ - STRING_KEY, /* private key filename */ - STRING_KEY_PASSWD, /* plain text private key password */ - STRING_KEY_TYPE, /* format for private key (default: PEM) */ - STRING_SSL_CAPATH, /* CA directory name (does not work on Windows) */ - STRING_SSL_CAFILE, /* certificate file to verify peer against */ - STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */ - STRING_SSL_CIPHER_LIST, /* list of ciphers to use */ - STRING_SSL_CIPHER13_LIST, /* list of TLS 1.3 ciphers to use */ - STRING_SSL_CRLFILE, /* CRL file to check certificate */ - STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ - STRING_SERVICE_NAME, /* Service name */ -#ifndef CURL_DISABLE_PROXY - STRING_CERT_PROXY, /* client certificate filename */ - STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/ - STRING_KEY_PROXY, /* private key filename */ - STRING_KEY_PASSWD_PROXY, /* plain text private key password */ - STRING_KEY_TYPE_PROXY, /* format for private key (default: PEM) */ - STRING_SSL_CAPATH_PROXY, /* CA directory name (does not work on Windows) */ - STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */ - STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */ - STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */ - STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */ - STRING_SSL_CRLFILE_PROXY, /* CRL file to check certificate */ - STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */ - STRING_PROXY_SERVICE_NAME, /* Proxy service name */ -#endif -#ifndef CURL_DISABLE_COOKIES - STRING_COOKIE, /* HTTP cookie string to send */ - STRING_COOKIEJAR, /* dump all cookies to this file */ -#endif - STRING_CUSTOMREQUEST, /* HTTP/FTP/RTSP request/method to use */ - STRING_DEFAULT_PROTOCOL, /* Protocol to use when the URL does not specify */ - STRING_DEVICE, /* local network interface/address to use */ - STRING_INTERFACE, /* local network interface to use */ - STRING_BINDHOST, /* local address to use */ - STRING_ENCODING, /* Accept-Encoding string */ -#ifndef CURL_DISABLE_FTP - STRING_FTP_ACCOUNT, /* ftp account data */ - STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */ - STRING_FTPPORT, /* port to send with the FTP PORT command */ -#endif -#ifndef CURL_DISABLE_NETRC - STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find - $HOME/.netrc */ -#endif -#ifndef CURL_DISABLE_PROXY - STRING_PROXY, /* proxy to use */ - STRING_PRE_PROXY, /* pre socks proxy to use */ -#endif - STRING_SET_RANGE, /* range, if used */ - STRING_SET_REFERER, /* custom string for the HTTP referer field */ - STRING_SET_URL, /* what original URL to work on */ - STRING_USERAGENT, /* User-Agent string */ - STRING_SSL_ENGINE, /* name of ssl engine */ - STRING_USERNAME, /* , if used */ - STRING_PASSWORD, /* , if used */ - STRING_OPTIONS, /* , if used */ -#ifndef CURL_DISABLE_PROXY - STRING_PROXYUSERNAME, /* Proxy , if used */ - STRING_PROXYPASSWORD, /* Proxy , if used */ - STRING_NOPROXY, /* List of hosts which should not use the proxy, if - used */ -#endif -#ifndef CURL_DISABLE_RTSP - STRING_RTSP_SESSION_ID, /* Session ID to use */ - STRING_RTSP_STREAM_URI, /* Stream URI for this request */ - STRING_RTSP_TRANSPORT, /* Transport for this session */ -#endif -#ifdef USE_SSH - STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */ - STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */ - STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ASCII hex */ - STRING_SSH_HOST_PUBLIC_KEY_SHA256, /* sha256 of host public key in base64 */ - STRING_SSH_KNOWNHOSTS, /* filename of knownhosts file */ -#endif -#ifndef CURL_DISABLE_SMTP - STRING_MAIL_FROM, - STRING_MAIL_AUTH, -#endif -#ifdef USE_TLS_SRP - STRING_TLSAUTH_USERNAME, /* TLS auth */ - STRING_TLSAUTH_PASSWORD, /* TLS auth */ -#ifndef CURL_DISABLE_PROXY - STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth */ - STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth */ -#endif -#endif - STRING_BEARER, /* , if used */ -#ifdef USE_UNIX_SOCKETS - STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */ -#endif - STRING_TARGET, /* CURLOPT_REQUEST_TARGET */ -#ifndef CURL_DISABLE_DOH - STRING_DOH, /* CURLOPT_DOH_URL */ -#endif -#ifndef CURL_DISABLE_ALTSVC - STRING_ALTSVC, /* CURLOPT_ALTSVC */ -#endif -#ifndef CURL_DISABLE_HSTS - STRING_HSTS, /* CURLOPT_HSTS */ -#endif - STRING_SASL_AUTHZID, /* CURLOPT_SASL_AUTHZID */ -#ifdef USE_ARES - STRING_DNS_SERVERS, - STRING_DNS_INTERFACE, - STRING_DNS_LOCAL_IP4, - STRING_DNS_LOCAL_IP6, -#endif - STRING_SSL_EC_CURVES, -#ifndef CURL_DISABLE_AWS - STRING_AWS_SIGV4, /* Parameters for V4 signature */ -#endif -#ifndef CURL_DISABLE_PROXY - STRING_HAPROXY_CLIENT_IP, /* CURLOPT_HAPROXY_CLIENT_IP */ -#endif - STRING_ECH_CONFIG, /* CURLOPT_ECH_CONFIG */ - STRING_ECH_PUBLIC, /* CURLOPT_ECH_PUBLIC */ - STRING_SSL_SIGNATURE_ALGORITHMS, /* CURLOPT_SSL_SIGNATURE_ALGORITHMS */ - - /* -- end of null-terminated strings -- */ - - STRING_LASTZEROTERMINATED, - - /* -- below this are pointers to binary data that cannot be strdup'ed. --- */ - - STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ - - STRING_LAST /* not used, an end-of-list marker */ -}; - -enum dupblob { - BLOB_CERT, - BLOB_KEY, - BLOB_SSL_ISSUERCERT, - BLOB_CAINFO, -#ifndef CURL_DISABLE_PROXY - BLOB_CERT_PROXY, - BLOB_KEY_PROXY, - BLOB_SSL_ISSUERCERT_PROXY, - BLOB_CAINFO_PROXY, -#endif - BLOB_LAST -}; - -struct UserDefined { - FILE *err; /* the stderr user data goes here */ - void *debugdata; /* the data that will be passed to fdebug */ - char *errorbuffer; /* (Static) store failure messages in here */ - void *out; /* CURLOPT_WRITEDATA */ - void *in_set; /* CURLOPT_READDATA */ - void *writeheader; /* write the header to this if non-NULL */ - uint32_t httpauth; /* kind of HTTP authentication to use (bitmask) */ - uint32_t proxyauth; /* kind of proxy authentication to use (bitmask) */ - void *postfields; /* if POST, set the fields' values here */ - curl_seek_callback seek_func; /* function that seeks the input */ - curl_off_t postfieldsize; /* if POST, this might have a size to use instead - of strlen(), and then the data *may* be binary - (contain zero bytes) */ - curl_write_callback fwrite_func; /* function that stores the output */ - curl_write_callback fwrite_header; /* function that stores headers */ - curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */ - curl_read_callback fread_func_set; /* function that reads the input */ - curl_progress_callback fprogress; /* OLD and deprecated progress callback */ - curl_xferinfo_callback fxferinfo; /* progress callback */ - curl_debug_callback fdebug; /* function that write informational data */ - curl_ioctl_callback ioctl_func; /* function for I/O control */ - curl_sockopt_callback fsockopt; /* function for setting socket options */ - void *sockopt_client; /* pointer to pass to the socket options callback */ - curl_opensocket_callback fopensocket; /* function for checking/translating - the address and opening the - socket */ - void *opensocket_client; - curl_closesocket_callback fclosesocket; /* function for closing the - socket */ - void *closesocket_client; - curl_prereq_callback fprereq; /* pre-initial request callback */ - void *prereq_userp; /* pre-initial request user data */ - - void *seek_client; /* pointer to pass to the seek callback */ -#ifndef CURL_DISABLE_HSTS - curl_hstsread_callback hsts_read; - void *hsts_read_userp; - curl_hstswrite_callback hsts_write; - void *hsts_write_userp; -#endif - void *progress_client; /* pointer to pass to the progress callback */ - void *ioctl_client; /* pointer to pass to the ioctl callback */ - timediff_t conn_max_idle_ms; /* max idle time to allow a connection that - is to be reused */ - timediff_t conn_max_age_ms; /* max time since creation to allow a - connection that is to be reused */ - curl_off_t filesize; /* size of file to upload, -1 means unknown */ - curl_off_t low_speed_limit; /* bytes/second */ - curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */ - curl_off_t max_recv_speed; /* high speed limit in bytes/second for - download */ - curl_off_t set_resume_from; /* continue [ftp] transfer from here */ - struct curl_slist *headers; /* linked list of extra headers */ - struct curl_httppost *httppost; /* linked list of old POST data */ -#if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) - curl_mimepart *mimepostp; /* MIME/POST data. */ -#endif -#ifndef CURL_DISABLE_TELNET - struct curl_slist *telnet_options; /* linked list of telnet options */ -#endif - struct curl_slist *resolve; /* list of names to add/remove from - DNS cache */ - struct curl_slist *connect_to; /* list of host:port mappings to override - the hostname and port to connect to */ - time_t timevalue; /* what time to compare with */ - struct ssl_config_data ssl; /* user defined SSL stuff */ -#ifndef CURL_DISABLE_PROXY - struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */ - struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */ - uint16_t proxyport; /* If non-zero, use this port number by - default. If the proxy string features a - ":[port]" that one will override this. */ - uint8_t proxytype; /* what kind of proxy */ - uint8_t socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */ -#endif - struct ssl_general_config general_ssl; /* general user defined SSL stuff */ - timediff_t dns_cache_timeout_ms; /* DNS cache timeout (milliseconds) */ - uint32_t buffer_size; /* size of receive buffer to use */ - uint32_t upload_buffer_size; /* size of upload buffer to use, keep it >= - CURL_MAX_WRITE_SIZE */ - void *private_data; /* application-private data */ -#ifndef CURL_DISABLE_HTTP - struct curl_slist *http200aliases; /* linked list of aliases for http200 */ -#endif - curl_off_t max_filesize; /* Maximum file size to download */ -#ifndef CURL_DISABLE_FTP - timediff_t accepttimeout; /* in milliseconds, 0 means no timeout */ - uint8_t ftp_filemethod; /* how to get to a file: curl_ftpfile */ - uint8_t ftpsslauth; /* what AUTH XXX to try: curl_ftpauth */ - uint8_t ftp_ccc; /* FTP CCC options: curl_ftpccc */ -#endif -#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) - struct curl_slist *quote; /* after connection is established */ - struct curl_slist *postquote; /* after the transfer */ - struct curl_slist *prequote; /* before the transfer, after type */ -#endif -#ifdef USE_LIBSSH2 - curl_sshhostkeycallback ssh_hostkeyfunc; /* hostkey check callback */ - void *ssh_hostkeyfunc_userp; /* custom pointer to callback */ -#endif -#ifdef USE_SSH - curl_sshkeycallback ssh_keyfunc; /* key matching callback */ - void *ssh_keyfunc_userp; /* custom pointer to callback */ - uint32_t ssh_auth_types; /* allowed SSH auth types */ - uint32_t new_directory_perms; /* when creating remote dirs */ -#endif - uint32_t new_file_perms; /* when creating remote files */ - char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */ - struct curl_blob *blobs[BLOB_LAST]; -#ifdef USE_IPV6 - uint32_t scope_id; /* Scope id for IPv6 */ -#endif - curl_prot_t allowed_protocols; - curl_prot_t redir_protocols; -#ifndef CURL_DISABLE_RTSP - void *rtp_out; /* write RTP to this if non-NULL */ - /* Common RTSP header options */ - Curl_RtspReq rtspreq; /* RTSP request type */ -#endif -#ifndef CURL_DISABLE_FTP - curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer - starts */ - curl_chunk_end_callback chunk_end; /* called after part transferring - stopped */ - curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds - to pattern (e.g. if WILDCARDMATCH is on) */ - void *fnmatch_data; - void *wildcardptr; -#endif - - timediff_t timeout; /* ms, 0 means no timeout */ - timediff_t connecttimeout; /* ms, 0 means default timeout */ - timediff_t happy_eyeballs_timeout; /* ms, 0 is a valid value */ - timediff_t server_response_timeout; /* ms, 0 means no timeout */ - timediff_t shutdowntimeout; /* ms, 0 means default timeout */ - int tcp_keepidle; /* seconds in idle before sending keepalive probe */ - int tcp_keepintvl; /* seconds between TCP keepalive probes */ - int tcp_keepcnt; /* maximum number of keepalive probes */ - -#if defined(USE_HTTP2) || defined(USE_HTTP3) - struct Curl_data_priority priority; -#endif - curl_resolver_start_callback resolver_start; /* optional callback called - before resolver start */ - void *resolver_start_client; /* pointer to pass to resolver start callback */ - timediff_t upkeep_interval_ms; /* Time between calls for connection - upkeep. */ - CURLU *uh; /* URL handle for the current parsed URL */ -#ifndef CURL_DISABLE_HTTP - void *trailer_data; /* pointer to pass to trailer data callback */ - curl_trailer_callback trailer_callback; /* trailing data callback */ -#endif -#ifndef CURL_DISABLE_SMTP - struct curl_slist *mail_rcpt; /* linked list of mail recipients */ -#endif - uint32_t maxconnects; /* Max idle connections in the connection cache */ -#ifdef USE_ECH - int tls_ech; /* TLS ECH configuration */ -#endif - short maxredirs; /* maximum no. of http(s) redirects to follow, - set to -1 for infinity */ - uint16_t expect_100_timeout; /* in milliseconds */ - uint16_t use_port; /* which port to use (when not using default) */ - uint16_t low_speed_time; /* number of seconds */ -#ifndef CURL_DISABLE_BINDLOCAL - uint16_t localport; /* local port number to bind to */ - uint16_t localportrange; /* number of additional port numbers to test - in case the 'localport' one cannot be - bind()ed */ -#endif -#ifndef CURL_DISABLE_TFTP - uint16_t tftp_blksize; /* in bytes, 0 means use default */ -#endif -#ifndef CURL_DISABLE_NETRC - uint8_t use_netrc; /* enum CURL_NETRC_OPTION values */ -#endif -#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) - /* Despite the name, ftp_create_missing_dirs is for FTP(S) and SFTP - 1 - create directories that do not exist - 2 - the same but also allow MKD to fail once - */ - uint8_t ftp_create_missing_dirs; -#endif - uint8_t use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or IMAP or - POP3 or others! (type: curl_usessl)*/ - uint8_t timecondition; /* kind of time comparison: curl_TimeCond */ - uint8_t method; /* what kind of HTTP request: Curl_HttpReq */ - uint8_t httpwant; /* when non-zero, a specific HTTP version requested - to be used in the library's request(s) */ - uint8_t ipver; /* the CURL_IPRESOLVE_* defines in the public header - file 0 - whatever, 1 - v2, 2 - v6 */ - uint8_t upload_flags; /* flags set by CURLOPT_UPLOAD_FLAGS */ -#ifdef HAVE_GSSAPI - /* GSS-API credential delegation, see the documentation of - CURLOPT_GSSAPI_DELEGATION */ - uint8_t gssapi_delegation; -#endif - uint8_t http_follow_mode; /* follow HTTP redirects */ - BIT(connect_only); /* make connection/request, then let application use the - socket */ - BIT(connect_only_ws); /* special websocket connect-only level */ -#ifndef CURL_DISABLE_SMTP - BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some - recipients */ -#endif -#ifndef CURL_DISABLE_MIME - BIT(mime_formescape); -#endif - BIT(is_fread_set); /* has read callback been set to non-NULL? */ -#ifndef CURL_DISABLE_TFTP - BIT(tftp_no_options); /* do not send TFTP options requests */ -#endif - BIT(sep_headers); /* handle host and proxy headers separately */ -#ifndef CURL_DISABLE_COOKIES - BIT(cookiesession); /* new cookie session? */ -#endif - BIT(crlf); /* convert crlf on ftp upload(?) */ -#ifdef USE_SSH - BIT(ssh_compression); /* enable SSH compression */ -#endif - -/* Here follows boolean settings that define how to behave during - this session. They are STATIC, set by libcurl users or at least initially - and they do not change during operations. */ - BIT(quick_exit); /* set 1L when it is okay to leak things (like - threads), as we are about to exit() anyway and - do not want lengthy cleanups to delay termination, - e.g. after a DNS timeout */ - BIT(get_filetime); /* get the time and get of the remote file */ -#ifndef CURL_DISABLE_PROXY - BIT(tunnel_thru_httpproxy); /* use CONNECT through an HTTP proxy */ -#endif - BIT(prefer_ascii); /* ASCII rather than binary */ - BIT(remote_append); /* append, not overwrite, on upload */ -#ifdef CURL_LIST_ONLY_PROTOCOL - BIT(list_only); /* list directory */ -#endif -#ifndef CURL_DISABLE_FTP - BIT(ftp_use_port); /* use the FTP PORT command */ - BIT(ftp_use_epsv); /* if EPSV is to be attempted or not */ - BIT(ftp_use_eprt); /* if EPRT is to be attempted or not */ - BIT(ftp_use_pret); /* if PRET is to be used before PASV or not */ - BIT(ftp_skip_ip); /* skip the IP address the FTP server passes on to - us */ - BIT(wildcard_enabled); /* enable wildcard matching */ -#endif - BIT(http_fail_on_error); /* fail on HTTP error codes >= 400 */ - BIT(http_keep_sending_on_error); /* for HTTP status codes >= 300 */ - BIT(http_transfer_encoding); /* request compressed HTTP transfer-encoding */ - BIT(allow_auth_to_other_hosts); - BIT(include_header); /* include received protocol headers in data output */ - BIT(http_set_referer); /* is a custom referer used */ - BIT(http_auto_referer); /* set "correct" referer when following - location: */ - BIT(opt_no_body); /* as set with CURLOPT_NOBODY */ - BIT(verbose); /* output verbosity */ - BIT(reuse_forbid); /* forbidden to be reused, close after use */ - BIT(reuse_fresh); /* do not reuse an existing connection */ - BIT(no_signal); /* do not use any signal/alarm handler */ - BIT(tcp_nodelay); /* whether to enable TCP_NODELAY or not */ - BIT(ignorecl); /* ignore content length */ - BIT(http_te_skip); /* pass the raw body data to the user, even when - transfer-encoded (chunked, compressed) */ - BIT(http_ce_skip); /* pass the raw body data to the user, even when - content-encoded (chunked, compressed) */ - BIT(proxy_transfer_mode); /* set transfer mode (;type=) when doing - FTP via an HTTP proxy */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - BIT(socks5_gssapi_nec); /* Flag to support NEC SOCKS5 server */ -#endif - BIT(sasl_ir); /* Enable/disable SASL initial response */ - BIT(tcp_keepalive); /* use TCP keepalives */ - BIT(tcp_fastopen); /* use TCP Fast Open */ - BIT(ssl_enable_alpn);/* TLS ALPN extension? */ - BIT(path_as_is); /* allow dotdots? */ - BIT(pipewait); /* wait for multiplex status before starting a new - connection */ - BIT(suppress_connect_headers); /* suppress proxy CONNECT response headers - from user callbacks */ - BIT(dns_shuffle_addresses); /* whether to shuffle addresses before use */ -#ifndef CURL_DISABLE_PROXY - BIT(haproxyprotocol); /* whether to send HAProxy PROXY protocol v1 - header */ -#endif -#ifdef USE_UNIX_SOCKETS - BIT(abstract_unix_socket); -#endif - BIT(disallow_username_in_url); /* disallow username in URL */ -#ifndef CURL_DISABLE_DOH - BIT(doh); /* DNS-over-HTTPS enabled */ - BIT(doh_verifypeer); /* DoH certificate peer verification */ - BIT(doh_verifyhost); /* DoH certificate hostname verification */ - BIT(doh_verifystatus); /* DoH certificate status verification */ -#endif - BIT(http09_allowed); /* allow HTTP/0.9 responses */ -#ifndef CURL_DISABLE_WEBSOCKETS - BIT(ws_raw_mode); - BIT(ws_no_auto_pong); -#endif - BIT(post301); /* keep POSTs as POSTs after a 301 request */ - BIT(post302); /* keep POSTs as POSTs after a 302 request */ - BIT(post303); /* keep POSTs as POSTs after a 303 request */ -}; - -#ifndef CURL_DISABLE_MIME -#define IS_MIME_POST(a) \ - ((a)->set.mimepostp && ((a)->set.mimepostp->kind != MIMEKIND_NONE)) -#else -#define IS_MIME_POST(a) FALSE -#endif - -/* callback that gets called when a sub easy (data->master_mid set) is - DONE. Called on the master easy. */ -typedef void multi_sub_xfer_done_cb(struct Curl_easy *master_easy, - struct Curl_easy *sub_easy, - CURLcode result); - -/* - * The 'connectdata' struct MUST have all the connection oriented stuff as we - * may have several simultaneous connections and connection structs in memory. - * - * The 'struct UserDefined' must only contain data that is set once to go for - * many (perhaps) independent connections. Values that are generated or - * calculated internally for the "session handle" must be defined within the - * 'struct UrlState' instead. - */ - -struct Curl_easy { - /* First a simple identifier to easier detect if a user mix up this easy - handle with a multi handle. Set this to CURLEASY_MAGIC_NUMBER */ - uint32_t magic; - /* once an easy handle is tied to a connection pool a non-negative number to - distinguish this transfer from other using the same pool. For easier - tracking in log output. This may wrap around after LONG_MAX to 0 again, - so it has no uniqueness guarantee for large processings. Note: it has no - uniqueness either IFF more than one connection pool is used by the - libcurl application. */ - curl_off_t id; - /* once an easy handle is added to a multi, either explicitly by the - * libcurl application or implicitly during `curl_easy_perform()`, - * a unique identifier inside this one multi instance. */ - uint32_t mid; - uint32_t master_mid; /* if set, this transfer belongs to a master */ - multi_sub_xfer_done_cb *sub_xfer_done; - - struct connectdata *conn; - - CURLMstate mstate; /* the handle's state */ - CURLcode result; /* previous result */ - - struct Curl_message msg; /* A single posted message. */ - - struct Curl_multi *multi; /* if non-NULL, points to the multi handle - struct to which this "belongs" when used by - the multi interface */ - struct Curl_multi *multi_easy; /* if non-NULL, points to the multi handle - struct to which this "belongs" when used - by the easy interface */ - struct Curl_share *share; /* Share, handles global variable mutexing */ - - /* `meta_hash` is a general key-value store for implementations - * with the lifetime of the easy handle. - * Elements need to be added with their own destructor to be invoked when - * the easy handle is cleaned up (see Curl_hash_add2()).*/ - struct Curl_hash meta_hash; - -#ifdef USE_LIBPSL - struct PslCache *psl; /* The associated PSL cache. */ -#endif - struct SingleRequest req; /* Request-specific data */ - struct UserDefined set; /* values set by the libcurl user */ -#ifndef CURL_DISABLE_COOKIES - struct CookieInfo *cookies; /* the cookies, read from files and servers. - NOTE that the 'cookie' field in the - UserDefined struct defines if the "engine" - is to be used or not. */ -#endif -#ifndef CURL_DISABLE_HSTS - struct hsts *hsts; -#endif -#ifndef CURL_DISABLE_ALTSVC - struct altsvcinfo *asi; /* the alt-svc cache */ -#endif - struct Progress progress; /* for all the progress meter data */ - struct UrlState state; /* struct for fields used for state info and - other dynamic purposes */ -#ifndef CURL_DISABLE_FTP - struct WildcardData *wildcard; /* wildcard download state info */ -#endif - struct PureInfo info; /* stats, reports and info data */ - struct curl_tlssessioninfo tsi; /* Information about the TLS session, only - valid after a client has asked for it */ -}; - -#define LIBCURL_NAME "libcurl" - -#endif /* HEADER_CURL_URLDATA_H */ diff --git a/vendor/curl/lib/vauth/cleartext.c b/vendor/curl/lib/vauth/cleartext.c deleted file mode 100644 index 7976adec9..000000000 --- a/vendor/curl/lib/vauth/cleartext.c +++ /dev/null @@ -1,113 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC4616 PLAIN authentication - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_POP3) || \ - (!defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)) - -#include "vauth/vauth.h" - -/* - * Curl_auth_create_plain_message() - * - * This is used to generate an already encoded PLAIN message ready - * for sending to the recipient. - * - * Parameters: - * - * authzid [in] - The authorization identity. - * authcid [in] - The authentication identity. - * passwd [in] - The password. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_plain_message(const char *authzid, - const char *authcid, - const char *passwd, - struct bufref *out) -{ - size_t len; - char *auth; - - size_t zlen = (authzid == NULL ? 0 : strlen(authzid)); - size_t clen = strlen(authcid); - size_t plen = strlen(passwd); - - if((zlen > CURL_MAX_INPUT_LENGTH) || (clen > CURL_MAX_INPUT_LENGTH) || - (plen > CURL_MAX_INPUT_LENGTH)) - return CURLE_TOO_LARGE; - - len = zlen + clen + plen + 2; - - auth = curl_maprintf("%s%c%s%c%s", authzid ? authzid : "", '\0', - authcid, '\0', passwd); - if(!auth) - return CURLE_OUT_OF_MEMORY; - Curl_bufref_set(out, auth, len, curl_free); - return CURLE_OK; -} - -/* - * Curl_auth_create_login_message() - * - * This is used to generate an already encoded LOGIN message containing the - * username or password ready for sending to the recipient. - * - * Parameters: - * - * value [in] - The username or user's password. - * out [out] - The result storage. - * - * Returns void. - */ -void Curl_auth_create_login_message(const char *value, struct bufref *out) -{ - Curl_bufref_set(out, value, strlen(value), NULL); -} - -/* - * Curl_auth_create_external_message() - * - * This is used to generate an already encoded EXTERNAL message containing - * the username ready for sending to the recipient. - * - * Parameters: - * - * user [in] - The username. - * out [out] - The result storage. - * - * Returns void. - */ -void Curl_auth_create_external_message(const char *user, struct bufref *out) -{ - /* This is the same formatting as the login message */ - Curl_auth_create_login_message(user, out); -} - -#endif /* if no users */ diff --git a/vendor/curl/lib/vauth/cram.c b/vendor/curl/lib/vauth/cram.c deleted file mode 100644 index d3f2d137b..000000000 --- a/vendor/curl/lib/vauth/cram.c +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC2195 CRAM-MD5 authentication - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_DIGEST_AUTH - -#include "vauth/vauth.h" -#include "curl_hmac.h" -#include "curl_md5.h" - -/* - * Curl_auth_create_cram_md5_message() - * - * This is used to generate a CRAM-MD5 response message ready for sending to - * the recipient. - * - * Parameters: - * - * chlg [in] - The challenge. - * userp [in] - The username. - * passwdp [in] - The user's password. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg, - const char *userp, - const char *passwdp, - struct bufref *out) -{ - struct HMAC_context *ctxt; - unsigned char digest[MD5_DIGEST_LEN]; - char *response; - - /* Compute the digest using the password as the key */ - ctxt = Curl_HMAC_init(&Curl_HMAC_MD5, - (const unsigned char *)passwdp, - curlx_uztoui(strlen(passwdp))); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - /* Update the digest with the given challenge */ - if(Curl_bufref_len(chlg)) - Curl_HMAC_update(ctxt, Curl_bufref_uptr(chlg), - curlx_uztoui(Curl_bufref_len(chlg))); - - /* Finalise the digest */ - Curl_HMAC_final(ctxt, digest); - - /* Generate the response */ - response = curl_maprintf( - "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - userp, digest[0], digest[1], digest[2], digest[3], digest[4], - digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], - digest[11], digest[12], digest[13], digest[14], digest[15]); - if(!response) - return CURLE_OUT_OF_MEMORY; - - Curl_bufref_set(out, response, strlen(response), curl_free); - return CURLE_OK; -} - -#endif /* !CURL_DISABLE_DIGEST_AUTH */ diff --git a/vendor/curl/lib/vauth/digest.c b/vendor/curl/lib/vauth/digest.c deleted file mode 100644 index 5ecfd60aa..000000000 --- a/vendor/curl/lib/vauth/digest.c +++ /dev/null @@ -1,1048 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC2831 DIGEST-MD5 authentication - * RFC7616 DIGEST-SHA256, DIGEST-SHA512-256 authentication - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_DIGEST_AUTH - -#include "vauth/vauth.h" -#include "vauth/digest.h" -#include "curlx/base64.h" -#include "curl_md5.h" -#include "curl_sha256.h" -#include "curl_sha512_256.h" -#include "curlx/strparse.h" -#include "rand.h" - -#ifndef USE_WINDOWS_SSPI -#define SESSION_ALGO 1 /* for algos with this bit set */ - -#define ALGO_MD5 0 -#define ALGO_MD5SESS (ALGO_MD5 | SESSION_ALGO) -#define ALGO_SHA256 2 -#define ALGO_SHA256SESS (ALGO_SHA256 | SESSION_ALGO) -#define ALGO_SHA512_256 4 -#define ALGO_SHA512_256SESS (ALGO_SHA512_256 | SESSION_ALGO) - -#define DIGEST_QOP_VALUE_AUTH (1 << 0) -#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1) -#define DIGEST_QOP_VALUE_AUTH_CONF (1 << 2) - -#define DIGEST_QOP_VALUE_STRING_AUTH "auth" -#define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int" -#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf" -#endif - -bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, - const char **endptr) -{ - int c; - bool starts_with_quote = FALSE; - bool escape = FALSE; - - for(c = DIGEST_MAX_VALUE_LENGTH - 1; (*str && (*str != '=') && c--);) - *value++ = *str++; - *value = 0; - - if('=' != *str++) - /* eek, no match */ - return FALSE; - - if('\"' == *str) { - /* This starts with a quote so it must end with one as well! */ - str++; - starts_with_quote = TRUE; - } - - for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) { - if(!escape) { - switch(*str) { - case '\\': - if(starts_with_quote) { - /* the start of an escaped quote */ - escape = TRUE; - continue; - } - break; - - case ',': - if(!starts_with_quote) { - /* This signals the end of the content if we did not get a starting - quote and then we do "sloppy" parsing */ - c = 0; /* the end */ - continue; - } - break; - - case '\r': - case '\n': - /* end of string */ - if(starts_with_quote) - return FALSE; /* No closing quote */ - c = 0; - continue; - - case '\"': - if(starts_with_quote) { - /* end of string */ - c = 0; - continue; - } - else - return FALSE; - } - } - - escape = FALSE; - *content++ = *str; - } - if(escape) - return FALSE; /* No character after backslash */ - - *content = 0; - *endptr = str; - - return TRUE; -} - -#ifndef USE_WINDOWS_SSPI -/* Convert MD5 chunk to RFC2617 (section 3.1.3) -suitable ASCII string */ -static void auth_digest_md5_to_ascii( - const unsigned char *source, /* 16 bytes */ - unsigned char *dest) /* 33 bytes */ -{ - int i; - for(i = 0; i < 16; i++) - curl_msnprintf((char *)&dest[i * 2], 3, "%02x", source[i]); -} - -/* Convert sha256 or SHA-512/256 chunk to RFC7616 -suitable ASCII string */ -static void auth_digest_sha256_to_ascii( - const unsigned char *source, /* 32 bytes */ - unsigned char *dest) /* 65 bytes */ -{ - int i; - for(i = 0; i < 32; i++) - curl_msnprintf((char *)&dest[i * 2], 3, "%02x", source[i]); -} - -/* Perform quoted-string escaping as described in RFC2616 and its errata */ -static char *auth_digest_string_quoted(const char *s) -{ - struct dynbuf out; - curlx_dyn_init(&out, 2048); - if(!*s) /* for zero length input, make sure we return an empty string */ - return curlx_strdup(""); - while(*s) { - CURLcode result; - if(*s == '"' || *s == '\\') { - result = curlx_dyn_addn(&out, "\\", 1); - if(!result) - result = curlx_dyn_addn(&out, s, 1); - } - else - result = curlx_dyn_addn(&out, s, 1); - if(result) - return NULL; - s++; - } - return curlx_dyn_ptr(&out); -} - -/* Retrieves the value for a corresponding key from the challenge string - * returns TRUE if the key could be found, FALSE if it does not exists - */ -static bool auth_digest_get_key_value(const char *chlg, const char *key, - char *buf, size_t buflen) -{ - /* keyword=[value],keyword2=[value] - The values may or may not be quoted. - */ - - do { - struct Curl_str data; - struct Curl_str name; - - curlx_str_passblanks(&chlg); - - if(!curlx_str_until(&chlg, &name, 64, '=') && - !curlx_str_single(&chlg, '=')) { - /* this is the key, get the value, possibly quoted */ - int rc = curlx_str_quotedword(&chlg, &data, 256); - if(rc == STRE_BEGQUOTE) - /* try unquoted until comma */ - rc = curlx_str_until(&chlg, &data, 256, ','); - if(rc) - return FALSE; /* weird */ - - if(curlx_str_cmp(&name, key)) { - /* if this is our key, return the value */ - size_t len = curlx_strlen(&data); - const char *src = curlx_str(&data); - size_t i; - size_t outlen = 0; - - if(len >= buflen) - /* does not fit */ - return FALSE; - - for(i = 0; i < len; i++) { - if(src[i] == '\\' && i + 1 < len) { - i++; /* skip backslash */ - } - buf[outlen++] = src[i]; - } - buf[outlen] = 0; - return TRUE; - } - if(curlx_str_single(&chlg, ',')) - return FALSE; - } - else /* odd syntax */ - break; - } while(1); - - return FALSE; -} - -static void auth_digest_get_qop_values(const char *options, int *value) -{ - struct Curl_str out; - /* Initialise the output */ - *value = 0; - - while(!curlx_str_until(&options, &out, 32, ',')) { - if(curlx_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH)) - *value |= DIGEST_QOP_VALUE_AUTH; - else if(curlx_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH_INT)) - *value |= DIGEST_QOP_VALUE_AUTH_INT; - else if(curlx_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH_CONF)) - *value |= DIGEST_QOP_VALUE_AUTH_CONF; - if(curlx_str_single(&options, ',')) - break; - } -} - -/* - * auth_decode_digest_md5_message() - * - * This is used internally to decode an already encoded DIGEST-MD5 challenge - * message into the separate attributes. - * - * Parameters: - * - * chlgref [in] - The challenge message. - * nonce [in/out] - The buffer where the nonce is stored. - * nlen [in] - The length of the nonce buffer. - * realm [in/out] - The buffer where the realm is stored. - * rlen [in] - The length of the realm buffer. - * alg [in/out] - The buffer where the algorithm is stored. - * alen [in] - The length of the algorithm buffer. - * qop [in/out] - The buffer where the qop-options is stored. - * qlen [in] - The length of the qop buffer. - * - * Returns CURLE_OK on success. - */ -static CURLcode auth_decode_digest_md5_message(const struct bufref *chlgref, - char *nonce, size_t nlen, - char *realm, size_t rlen, - char *alg, size_t alen, - char *qop, size_t qlen) -{ - const char *chlg = Curl_bufref_ptr(chlgref); - - /* Ensure we have a valid challenge message */ - if(!Curl_bufref_len(chlgref)) - return CURLE_BAD_CONTENT_ENCODING; - - /* Retrieve nonce string from the challenge */ - if(!auth_digest_get_key_value(chlg, "nonce", nonce, nlen)) - return CURLE_BAD_CONTENT_ENCODING; - - /* Retrieve realm string from the challenge */ - if(!auth_digest_get_key_value(chlg, "realm", realm, rlen)) { - /* Challenge does not have a realm, set empty string [RFC2831] page 6 */ - *realm = '\0'; - } - - /* Retrieve algorithm string from the challenge */ - if(!auth_digest_get_key_value(chlg, "algorithm", alg, alen)) - return CURLE_BAD_CONTENT_ENCODING; - - /* Retrieve qop-options string from the challenge */ - if(!auth_digest_get_key_value(chlg, "qop", qop, qlen)) - return CURLE_BAD_CONTENT_ENCODING; - - return CURLE_OK; -} - -/* - * Curl_auth_is_digest_supported() - * - * This is used to evaluate if DIGEST is supported. - * - * Parameters: None - * - * Returns TRUE as DIGEST as handled by libcurl. - */ -bool Curl_auth_is_digest_supported(void) -{ - return TRUE; -} - -/* - * Curl_auth_create_digest_md5_message() - * - * This is used to generate an already encoded DIGEST-MD5 response message - * ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * chlg [in] - The challenge message. - * userp [in] - The username. - * passwdp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, - const struct bufref *chlg, - const char *userp, - const char *passwdp, - const char *service, - struct bufref *out) -{ - size_t i; - struct MD5_context *ctxt; - char *response = NULL; - unsigned char digest[MD5_DIGEST_LEN]; - char HA1_hex[(2 * MD5_DIGEST_LEN) + 1]; - char HA2_hex[(2 * MD5_DIGEST_LEN) + 1]; - char resp_hash_hex[(2 * MD5_DIGEST_LEN) + 1]; - char nonce[64]; - char realm[128]; - char algorithm[64]; - char qop_options[64]; - int qop_values; - char cnonce[33]; - char nonceCount[] = "00000001"; - char method[] = "AUTHENTICATE"; - char qop[] = DIGEST_QOP_VALUE_STRING_AUTH; - char *spn = NULL; - char *qrealm; - char *qnonce; - char *quserp; - - /* Decode the challenge message */ - CURLcode result = auth_decode_digest_md5_message(chlg, - nonce, sizeof(nonce), - realm, sizeof(realm), - algorithm, - sizeof(algorithm), - qop_options, - sizeof(qop_options)); - if(result) - return result; - - /* We only support md5 sessions */ - if(strcmp(algorithm, "md5-sess") != 0) - return CURLE_BAD_CONTENT_ENCODING; - - /* Get the qop-values from the qop-options */ - auth_digest_get_qop_values(qop_options, &qop_values); - - /* We only support auth quality-of-protection */ - if(!(qop_values & DIGEST_QOP_VALUE_AUTH)) - return CURLE_BAD_CONTENT_ENCODING; - - /* Generate 32 random hex chars, 32 bytes + 1 null-termination */ - result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce)); - if(result) - return result; - - /* Good so far, now calculate A1 and H(A1) according to RFC 2831 */ - ctxt = Curl_MD5_init(&Curl_DIGEST_MD5); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - Curl_MD5_update(ctxt, (const unsigned char *)userp, - curlx_uztoui(strlen(userp))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)realm, - curlx_uztoui(strlen(realm))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)passwdp, - curlx_uztoui(strlen(passwdp))); - Curl_MD5_final(ctxt, digest); - - ctxt = Curl_MD5_init(&Curl_DIGEST_MD5); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - Curl_MD5_update(ctxt, (const unsigned char *)digest, MD5_DIGEST_LEN); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)nonce, - curlx_uztoui(strlen(nonce))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)cnonce, - curlx_uztoui(strlen(cnonce))); - Curl_MD5_final(ctxt, digest); - - /* Convert calculated 16 octet hex into 32 bytes string */ - for(i = 0; i < MD5_DIGEST_LEN; i++) - curl_msnprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]); - - /* Generate our SPN */ - spn = Curl_auth_build_spn(service, data->conn->host.name, NULL); - if(!spn) - return CURLE_OUT_OF_MEMORY; - - /* Calculate H(A2) */ - ctxt = Curl_MD5_init(&Curl_DIGEST_MD5); - if(!ctxt) { - curlx_free(spn); - - return CURLE_OUT_OF_MEMORY; - } - - Curl_MD5_update(ctxt, (const unsigned char *)method, - curlx_uztoui(strlen(method))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)spn, - curlx_uztoui(strlen(spn))); - Curl_MD5_final(ctxt, digest); - - for(i = 0; i < MD5_DIGEST_LEN; i++) - curl_msnprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]); - - /* Now calculate the response hash */ - ctxt = Curl_MD5_init(&Curl_DIGEST_MD5); - if(!ctxt) { - curlx_free(spn); - - return CURLE_OUT_OF_MEMORY; - } - - Curl_MD5_update(ctxt, (const unsigned char *)HA1_hex, 2 * MD5_DIGEST_LEN); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)nonce, - curlx_uztoui(strlen(nonce))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - - Curl_MD5_update(ctxt, (const unsigned char *)nonceCount, - curlx_uztoui(strlen(nonceCount))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)cnonce, - curlx_uztoui(strlen(cnonce))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - Curl_MD5_update(ctxt, (const unsigned char *)qop, - curlx_uztoui(strlen(qop))); - Curl_MD5_update(ctxt, (const unsigned char *)":", 1); - - Curl_MD5_update(ctxt, (const unsigned char *)HA2_hex, 2 * MD5_DIGEST_LEN); - Curl_MD5_final(ctxt, digest); - - for(i = 0; i < MD5_DIGEST_LEN; i++) - curl_msnprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]); - - /* escape double quotes and backslashes in the username, realm and nonce as - necessary */ - qrealm = auth_digest_string_quoted(realm); - qnonce = auth_digest_string_quoted(nonce); - quserp = auth_digest_string_quoted(userp); - if(qrealm && qnonce && quserp) - /* Generate the response */ - response = curl_maprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\"," - "cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\"," - "response=%s,qop=%s", - quserp, qrealm, qnonce, - cnonce, nonceCount, spn, resp_hash_hex, qop); - - curlx_free(qrealm); - curlx_free(qnonce); - curlx_free(quserp); - curlx_free(spn); - if(!response) - return CURLE_OUT_OF_MEMORY; - - /* Return the response. */ - Curl_bufref_set(out, response, strlen(response), curl_free); - return result; -} - -/* - * Curl_auth_decode_digest_http_message() - * - * This is used to decode an HTTP DIGEST challenge message into the separate - * attributes. - * - * Parameters: - * - * chlg [in] - The challenge message. - * digest [in/out] - The digest data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_digest_http_message(const char *chlg, - struct digestdata *digest) -{ - bool before = FALSE; /* got a nonce before */ - - /* If we already have received a nonce, keep that in mind */ - if(digest->nonce) - before = TRUE; - - /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_digest_cleanup(digest); - - for(;;) { - char value[DIGEST_MAX_VALUE_LENGTH]; - char content[DIGEST_MAX_CONTENT_LENGTH]; - - /* Pass all additional spaces here */ - while(*chlg && ISBLANK(*chlg)) - chlg++; - - /* Extract a value=content pair */ - if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { - if(curl_strequal(value, "nonce")) { - curlx_free(digest->nonce); - digest->nonce = curlx_strdup(content); - if(!digest->nonce) - return CURLE_OUT_OF_MEMORY; - } - else if(curl_strequal(value, "stale")) { - if(curl_strequal(content, "true")) { - digest->stale = TRUE; - digest->nc = 1; /* we make a new nonce now */ - } - } - else if(curl_strequal(value, "realm")) { - curlx_free(digest->realm); - digest->realm = curlx_strdup(content); - if(!digest->realm) - return CURLE_OUT_OF_MEMORY; - } - else if(curl_strequal(value, "opaque")) { - curlx_free(digest->opaque); - digest->opaque = curlx_strdup(content); - if(!digest->opaque) - return CURLE_OUT_OF_MEMORY; - } - else if(curl_strequal(value, "qop")) { - const char *token = content; - struct Curl_str out; - bool foundAuth = FALSE; - bool foundAuthInt = FALSE; - /* Pass leading spaces */ - while(*token && ISBLANK(*token)) - token++; - while(!curlx_str_until(&token, &out, 32, ',')) { - if(curlx_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH)) - foundAuth = TRUE; - else if(curlx_str_casecompare(&out, - DIGEST_QOP_VALUE_STRING_AUTH_INT)) - foundAuthInt = TRUE; - if(curlx_str_single(&token, ',')) - break; - while(*token && ISBLANK(*token)) - token++; - } - - /* Select only auth or auth-int. Otherwise, ignore */ - if(foundAuth) { - curlx_free(digest->qop); - digest->qop = curlx_strdup(DIGEST_QOP_VALUE_STRING_AUTH); - if(!digest->qop) - return CURLE_OUT_OF_MEMORY; - } - else if(foundAuthInt) { - curlx_free(digest->qop); - digest->qop = curlx_strdup(DIGEST_QOP_VALUE_STRING_AUTH_INT); - if(!digest->qop) - return CURLE_OUT_OF_MEMORY; - } - } - else if(curl_strequal(value, "algorithm")) { - curlx_free(digest->algorithm); - digest->algorithm = curlx_strdup(content); - if(!digest->algorithm) - return CURLE_OUT_OF_MEMORY; - - if(curl_strequal(content, "MD5-sess")) - digest->algo = ALGO_MD5SESS; - else if(curl_strequal(content, "MD5")) - digest->algo = ALGO_MD5; - else if(curl_strequal(content, "SHA-256")) - digest->algo = ALGO_SHA256; - else if(curl_strequal(content, "SHA-256-SESS")) - digest->algo = ALGO_SHA256SESS; - else if(curl_strequal(content, "SHA-512-256")) { -#ifdef CURL_HAVE_SHA512_256 - digest->algo = ALGO_SHA512_256; -#else /* !CURL_HAVE_SHA512_256 */ - return CURLE_NOT_BUILT_IN; -#endif /* CURL_HAVE_SHA512_256 */ - } - else if(curl_strequal(content, "SHA-512-256-SESS")) { -#ifdef CURL_HAVE_SHA512_256 - digest->algo = ALGO_SHA512_256SESS; -#else /* !CURL_HAVE_SHA512_256 */ - return CURLE_NOT_BUILT_IN; -#endif /* CURL_HAVE_SHA512_256 */ - } - else - return CURLE_BAD_CONTENT_ENCODING; - } - else if(curl_strequal(value, "userhash")) { - if(curl_strequal(content, "true")) { - digest->userhash = TRUE; - } - } - else { - /* Unknown specifier, ignore it! */ - } - } - else - break; /* We are done here */ - - /* Pass all additional spaces here */ - while(*chlg && ISBLANK(*chlg)) - chlg++; - - /* Allow the list to be comma-separated */ - if(',' == *chlg) - chlg++; - } - - /* We had a nonce since before, and we got another one now without - 'stale=true'. This means we provided bad credentials in the previous - request */ - if(before && !digest->stale) - return CURLE_BAD_CONTENT_ENCODING; - - /* We got this header without a nonce, that is a bad Digest line! */ - if(!digest->nonce) - return CURLE_BAD_CONTENT_ENCODING; - - /* "-sess" protocol versions require "auth" or "auth-int" qop */ - if(!digest->qop && (digest->algo & SESSION_ALGO)) - return CURLE_BAD_CONTENT_ENCODING; - - return CURLE_OK; -} - -/* - * auth_create_digest_http_message() - * - * This is used to generate an HTTP DIGEST response message ready for sending - * to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username. - * passwdp [in] - The user's password. - * request [in] - The HTTP request. - * uripath [in] - The path of the HTTP uri. - * digest [in/out] - The digest data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result is stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -static CURLcode auth_create_digest_http_message( - struct Curl_easy *data, - const char *userp, - const char *passwdp, - const unsigned char *request, - const unsigned char *uripath, - struct digestdata *digest, - char **outptr, size_t *outlen, - void (*convert_to_ascii)(const unsigned char *, unsigned char *), - CURLcode (*hash)(unsigned char *, const unsigned char *, const size_t)) -{ - CURLcode result; - unsigned char hashbuf[32]; /* 32 bytes/256 bits */ - unsigned char request_digest[65]; - unsigned char ha1[65]; /* 64 digits and 1 zero byte */ - unsigned char ha2[65]; /* 64 digits and 1 zero byte */ - char userh[65]; - char *cnonce = NULL; - size_t cnonce_sz = 0; - char *userp_quoted = NULL; - char *realm_quoted = NULL; - char *nonce_quoted = NULL; - char *hashthis = NULL; - char *uri_quoted = NULL; - struct dynbuf response; - *outptr = NULL; - - curlx_dyn_init(&response, 4096); /* arbitrary max */ - - memset(hashbuf, 0, sizeof(hashbuf)); - if(!digest->nc) - digest->nc = 1; - - if(!digest->cnonce) { - char cnoncebuf[12]; - result = Curl_rand_bytes(data, -#ifdef DEBUGBUILD - TRUE, -#endif - (unsigned char *)cnoncebuf, - sizeof(cnoncebuf)); - if(!result) - result = curlx_base64_encode((uint8_t *)cnoncebuf, sizeof(cnoncebuf), - &cnonce, &cnonce_sz); - if(result) - goto oom; - - digest->cnonce = cnonce; - } - - if(digest->userhash) { - char *hasht = curl_maprintf("%s:%s", userp, - digest->realm ? digest->realm : ""); - if(!hasht) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - result = hash(hashbuf, (unsigned char *)hasht, strlen(hasht)); - curlx_free(hasht); - if(result) - goto oom; - convert_to_ascii(hashbuf, (unsigned char *)userh); - } - - /* - If the algorithm is "MD5" or unspecified (which then defaults to MD5): - - A1 = unq(username-value) ":" unq(realm-value) ":" passwd - - If the algorithm is "MD5-sess" then: - - A1 = H(unq(username-value) ":" unq(realm-value) ":" passwd) ":" - unq(nonce-value) ":" unq(cnonce-value) - */ - - hashthis = curl_maprintf("%s:%s:%s", userp, digest->realm ? - digest->realm : "", passwdp); - if(!hashthis) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - result = hash(hashbuf, (unsigned char *)hashthis, strlen(hashthis)); - curlx_free(hashthis); - if(result) - goto oom; - convert_to_ascii(hashbuf, ha1); - - if(digest->algo & SESSION_ALGO) { - /* nonce and cnonce are OUTSIDE the hash */ - char *tmp = curl_maprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce); - if(!tmp) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - result = hash(hashbuf, (unsigned char *)tmp, strlen(tmp)); - curlx_free(tmp); - if(result) - goto oom; - convert_to_ascii(hashbuf, ha1); - } - - /* - If the "qop" directive's value is "auth" or is unspecified, then A2 is: - - A2 = Method ":" digest-uri-value - - If the "qop" value is "auth-int", then A2 is: - - A2 = Method ":" digest-uri-value ":" H(entity-body) - - (The "Method" value is the HTTP request method as specified in section - 5.1.1 of RFC 2616) - */ - - uri_quoted = auth_digest_string_quoted((const char *)uripath); - if(!uri_quoted) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - hashthis = curl_maprintf("%s:%s", request, uripath); - if(!hashthis) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - if(digest->qop && curl_strequal(digest->qop, "auth-int")) { - /* We do not support auth-int for PUT or POST */ - char hashed[65]; - char *hashthis2; - - result = hash(hashbuf, (const unsigned char *)"", 0); - if(result) { - curlx_free(hashthis); - goto oom; - } - convert_to_ascii(hashbuf, (unsigned char *)hashed); - - hashthis2 = curl_maprintf("%s:%s", hashthis, hashed); - curlx_free(hashthis); - hashthis = hashthis2; - if(!hashthis) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - } - - result = hash(hashbuf, (unsigned char *)hashthis, strlen(hashthis)); - curlx_free(hashthis); - if(result) - goto oom; - convert_to_ascii(hashbuf, ha2); - - if(digest->qop) - hashthis = curl_maprintf("%s:%s:%08x:%s:%s:%s", ha1, digest->nonce, - digest->nc, digest->cnonce, digest->qop, ha2); - else - hashthis = curl_maprintf("%s:%s:%s", ha1, digest->nonce, ha2); - - if(!hashthis) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - result = hash(hashbuf, (unsigned char *)hashthis, strlen(hashthis)); - curlx_free(hashthis); - if(result) - goto oom; - convert_to_ascii(hashbuf, request_digest); - - /* For test case 64 (snooped from a Mozilla 1.3a request) - - Authorization: Digest username="testuser", realm="testrealm", \ - nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca" - - Digest parameters are all quoted strings. Username which is provided by - the user needs double quotes and backslashes within it escaped. - realm, nonce, and opaque needs backslashes as well as they were - de-escaped when copied from request header. cnonce is generated with - web-safe characters. uri is already percent encoded. nc is 8 hex - characters. algorithm and qop with standard values only contain web-safe - characters. - */ - userp_quoted = auth_digest_string_quoted(digest->userhash ? userh : userp); - if(!userp_quoted) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - if(digest->realm) - realm_quoted = auth_digest_string_quoted(digest->realm); - else { - realm_quoted = curlx_malloc(1); - if(realm_quoted) - realm_quoted[0] = 0; - } - if(!realm_quoted) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - nonce_quoted = auth_digest_string_quoted(digest->nonce); - if(!nonce_quoted) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - - if(digest->qop) { - result = curlx_dyn_addf(&response, "username=\"%s\", " - "realm=\"%s\", " - "nonce=\"%s\", " - "uri=\"%s\", " - "cnonce=\"%s\", " - "nc=%08x, " - "qop=%s, " - "response=\"%s\"", - userp_quoted, - realm_quoted, - nonce_quoted, - uri_quoted, - digest->cnonce, - digest->nc, - digest->qop, - request_digest); - - /* Increment nonce-count to use another nc value for the next request */ - digest->nc++; - } - else { - result = curlx_dyn_addf(&response, "username=\"%s\", " - "realm=\"%s\", " - "nonce=\"%s\", " - "uri=\"%s\", " - "response=\"%s\"", - userp_quoted, - realm_quoted, - nonce_quoted, - uri_quoted, - request_digest); - } - if(result) - goto oom; - - /* Add the optional fields */ - if(digest->opaque) { - /* Append the opaque */ - char *opaque_quoted = auth_digest_string_quoted(digest->opaque); - if(!opaque_quoted) { - result = CURLE_OUT_OF_MEMORY; - goto oom; - } - result = curlx_dyn_addf(&response, ", opaque=\"%s\"", opaque_quoted); - curlx_free(opaque_quoted); - if(result) - goto oom; - } - - if(digest->algorithm) { - /* Append the algorithm */ - result = curlx_dyn_addf(&response, ", algorithm=%s", digest->algorithm); - if(result) - goto oom; - } - - if(digest->userhash) { - /* Append the userhash */ - result = curlx_dyn_add(&response, ", userhash=true"); - if(result) - goto oom; - } - - /* Return the output */ - *outptr = curlx_dyn_ptr(&response); - *outlen = curlx_dyn_len(&response); - result = CURLE_OK; - -oom: - curlx_free(nonce_quoted); - curlx_free(realm_quoted); - curlx_free(uri_quoted); - curlx_free(userp_quoted); - if(result) - curlx_dyn_free(&response); - return result; -} - -/* - * Curl_auth_create_digest_http_message() - * - * This is used to generate an HTTP DIGEST response message ready for sending - * to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username. - * passwdp [in] - The user's password. - * request [in] - The HTTP request. - * uripath [in] - The path of the HTTP uri. - * digest [in/out] - The digest data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result is stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const unsigned char *request, - const unsigned char *uripath, - struct digestdata *digest, - char **outptr, size_t *outlen) -{ - if(digest->algo <= ALGO_MD5SESS) - return auth_create_digest_http_message(data, userp, passwdp, - request, uripath, digest, - outptr, outlen, - auth_digest_md5_to_ascii, - Curl_md5it); - - if(digest->algo <= ALGO_SHA256SESS) - return auth_create_digest_http_message(data, userp, passwdp, - request, uripath, digest, - outptr, outlen, - auth_digest_sha256_to_ascii, - Curl_sha256it); -#ifdef CURL_HAVE_SHA512_256 - if(digest->algo <= ALGO_SHA512_256SESS) - return auth_create_digest_http_message(data, userp, passwdp, - request, uripath, digest, - outptr, outlen, - auth_digest_sha256_to_ascii, - Curl_sha512_256it); -#endif /* CURL_HAVE_SHA512_256 */ - - /* Should be unreachable */ - return CURLE_BAD_CONTENT_ENCODING; -} - -/* - * Curl_auth_digest_cleanup() - * - * This is used to clean up the digest specific data. - * - * Parameters: - * - * digest [in/out] - The digest data struct being cleaned up. - * - */ -void Curl_auth_digest_cleanup(struct digestdata *digest) -{ - curlx_safefree(digest->nonce); - curlx_safefree(digest->cnonce); - curlx_safefree(digest->realm); - curlx_safefree(digest->opaque); - curlx_safefree(digest->qop); - curlx_safefree(digest->algorithm); - - digest->nc = 0; - digest->algo = ALGO_MD5; /* default algorithm */ - digest->stale = FALSE; /* default means normal, not stale */ - digest->userhash = FALSE; -} -#endif /* !USE_WINDOWS_SSPI */ - -#endif /* !CURL_DISABLE_DIGEST_AUTH */ diff --git a/vendor/curl/lib/vauth/digest.h b/vendor/curl/lib/vauth/digest.h deleted file mode 100644 index 5b8f3ae76..000000000 --- a/vendor/curl/lib/vauth/digest.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_DIGEST_H -#define HEADER_CURL_DIGEST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_DIGEST_AUTH - -#define DIGEST_MAX_VALUE_LENGTH 256 -#define DIGEST_MAX_CONTENT_LENGTH 1024 - -/* This is used to extract the realm from a challenge message */ -bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, - const char **endptr); - -#endif - -#endif /* HEADER_CURL_DIGEST_H */ diff --git a/vendor/curl/lib/vauth/digest_sspi.c b/vendor/curl/lib/vauth/digest_sspi.c deleted file mode 100644 index f0b6780fc..000000000 --- a/vendor/curl/lib/vauth/digest_sspi.c +++ /dev/null @@ -1,656 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC2831 DIGEST-MD5 authentication - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_DIGEST_AUTH) - -#include "vauth/vauth.h" -#include "vauth/digest.h" -#include "curlx/multibyte.h" -#include "curl_trc.h" -#include "curlx/strdup.h" -#include "strcase.h" -#include "strerror.h" - -/* - * Curl_auth_is_digest_supported() - * - * This is used to evaluate if DIGEST is supported. - * - * Parameters: None - * - * Returns TRUE if DIGEST is supported by Windows SSPI. - */ -bool Curl_auth_is_digest_supported(void) -{ - PSecPkgInfo SecurityPackage; - SECURITY_STATUS status; - - /* Query the security package for Digest */ - status = - Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_DIGEST)), - &SecurityPackage); - - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - } - - return status == SEC_E_OK; -} - -/* - * Curl_auth_create_digest_md5_message() - * - * This is used to generate an already encoded DIGEST-MD5 response message - * ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * chlg [in] - The challenge message. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, - const struct bufref *chlg, - const char *userp, - const char *passwdp, - const char *service, - struct bufref *out) -{ - CURLcode result = CURLE_OK; - TCHAR *spn = NULL; - size_t token_max = 0; - unsigned char *output_token = NULL; - CredHandle credentials; - CtxtHandle context; - PSecPkgInfo SecurityPackage; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - SecBuffer chlg_buf; - SecBuffer resp_buf; - SecBufferDesc chlg_desc; - SecBufferDesc resp_desc; - SECURITY_STATUS status; - unsigned long attrs; - - /* Ensure we have a valid challenge message */ - if(!Curl_bufref_len(chlg)) { - infof(data, "DIGEST-MD5 handshake failure (empty challenge message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Query the security package for DigestSSP */ - status = - Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_DIGEST)), - &SecurityPackage); - if(status != SEC_E_OK) { - failf(data, "SSPI: could not get auth info"); - return CURLE_AUTH_ERROR; - } - - token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our response buffer */ - output_token = curlx_malloc(token_max); - if(!output_token) - return CURLE_OUT_OF_MEMORY; - - /* Generate our SPN */ - spn = Curl_auth_build_spn(service, data->conn->host.name, NULL); - if(!spn) { - curlx_free(output_token); - return CURLE_OUT_OF_MEMORY; - } - - if(userp && *userp) { - /* Populate our identity structure */ - result = Curl_create_sspi_identity(userp, passwdp, &identity); - if(result) { - curlx_free(spn); - curlx_free(output_token); - return result; - } - - /* Allow proper cleanup of the identity structure */ - p_identity = &identity; - } - else - /* Use the current Windows user */ - p_identity = NULL; - - /* Acquire our credentials handle */ - status = Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_DIGEST)), - SECPKG_CRED_OUTBOUND, NULL, - p_identity, NULL, NULL, - &credentials, NULL); - - if(status != SEC_E_OK) { - Curl_sspi_free_identity(p_identity); - curlx_free(spn); - curlx_free(output_token); - return CURLE_LOGIN_DENIED; - } - - /* Setup the challenge "input" security buffer */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 1; - chlg_desc.pBuffers = &chlg_buf; - chlg_buf.BufferType = SECBUFFER_TOKEN; - chlg_buf.pvBuffer = CURL_UNCONST(Curl_bufref_ptr(chlg)); - chlg_buf.cbBuffer = curlx_uztoul(Curl_bufref_len(chlg)); - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = output_token; - resp_buf.cbBuffer = curlx_uztoul(token_max); - - /* Generate our response message */ - status = Curl_pSecFn->InitializeSecurityContext(&credentials, NULL, spn, - 0, 0, 0, &chlg_desc, 0, - &context, &resp_desc, &attrs, - NULL); - - if(status == SEC_I_COMPLETE_NEEDED || - status == SEC_I_COMPLETE_AND_CONTINUE) - Curl_pSecFn->CompleteAuthToken(&credentials, &resp_desc); - else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { - VERBOSE(char buffer[STRERROR_LEN]); - - Curl_pSecFn->FreeCredentialsHandle(&credentials); - Curl_sspi_free_identity(p_identity); - curlx_free(spn); - curlx_free(output_token); - - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - infof(data, "schannel: InitializeSecurityContext failed: %s", - Curl_sspi_strerror(status, buffer, sizeof(buffer))); - - return CURLE_AUTH_ERROR; - } - - /* Return the response. */ - Curl_bufref_set(out, output_token, resp_buf.cbBuffer, curl_free); - - /* Free our handles */ - Curl_pSecFn->DeleteSecurityContext(&context); - Curl_pSecFn->FreeCredentialsHandle(&credentials); - - /* Free the identity structure */ - Curl_sspi_free_identity(p_identity); - - /* Free the SPN */ - curlx_free(spn); - - return result; -} - -/* - * Curl_override_sspi_http_realm() - * - * This is used to populate the domain in an SSPI identity structure - * The realm is extracted from the challenge message and used as the - * domain if it is not already explicitly set. - * - * Parameters: - * - * chlg [in] - The challenge message. - * identity [in/out] - The identity structure. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_override_sspi_http_realm(const char *chlg, - SEC_WINNT_AUTH_IDENTITY *identity) -{ - xcharp_u domain, dup_domain; - - /* If domain is blank or unset, check challenge message for realm */ - if(!identity->Domain || !identity->DomainLength) { - for(;;) { - char value[DIGEST_MAX_VALUE_LENGTH]; - char content[DIGEST_MAX_CONTENT_LENGTH]; - - /* Pass all additional spaces here */ - while(*chlg && ISBLANK(*chlg)) - chlg++; - - /* Extract a value=content pair */ - if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { - if(curl_strequal(value, "realm")) { - - /* Setup identity's domain and length */ - domain.tchar_ptr = curlx_convert_UTF8_to_tchar(content); - if(!domain.tchar_ptr) - return CURLE_OUT_OF_MEMORY; - - dup_domain.tchar_ptr = curlx_tcsdup(domain.tchar_ptr); - if(!dup_domain.tchar_ptr) { - curlx_free(domain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - - curlx_free(identity->Domain); - identity->Domain = dup_domain.tbyte_ptr; - identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr)); - dup_domain.tchar_ptr = NULL; - - curlx_free(domain.tchar_ptr); - } - else { - /* Unknown specifier, ignore it! */ - } - } - else - break; /* We are done here */ - - /* Pass all additional spaces here */ - while(*chlg && ISBLANK(*chlg)) - chlg++; - - /* Allow the list to be comma-separated */ - if(',' == *chlg) - chlg++; - } - } - - return CURLE_OK; -} - -/* - * Curl_auth_decode_digest_http_message() - * - * This is used to decode an HTTP DIGEST challenge message into the separate - * attributes. - * - * Parameters: - * - * chlg [in] - The challenge message. - * digest [in/out] - The digest data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_digest_http_message(const char *chlg, - struct digestdata *digest) -{ - size_t chlglen = strlen(chlg); - - /* We had an input token before so if there is another one now that means we - provided bad credentials in the previous request or it is stale. */ - if(digest->input_token) { - bool stale = FALSE; - const char *p = chlg; - - /* Check for the 'stale' directive */ - for(;;) { - char value[DIGEST_MAX_VALUE_LENGTH]; - char content[DIGEST_MAX_CONTENT_LENGTH]; - - while(*p && ISBLANK(*p)) - p++; - - if(!Curl_auth_digest_get_pair(p, value, content, &p)) - break; - - if(curl_strequal(value, "stale") && - curl_strequal(content, "true")) { - stale = TRUE; - break; - } - - while(*p && ISBLANK(*p)) - p++; - - if(',' == *p) - p++; - } - - if(stale) - Curl_auth_digest_cleanup(digest); - else - return CURLE_LOGIN_DENIED; - } - - /* Store the challenge for use later */ - digest->input_token = (BYTE *)curlx_memdup(chlg, chlglen + 1); - if(!digest->input_token) - return CURLE_OUT_OF_MEMORY; - - digest->input_token_len = chlglen; - - return CURLE_OK; -} - -/* - * Curl_auth_create_digest_http_message() - * - * This is used to generate an HTTP DIGEST response message ready for sending - * to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * request [in] - The HTTP request. - * uripath [in] - The path of the HTTP uri. - * digest [in/out] - The digest data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result is stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const unsigned char *request, - const unsigned char *uripath, - struct digestdata *digest, - char **outptr, size_t *outlen) -{ - size_t token_max; - char *resp; - BYTE *output_token; - size_t output_token_len = 0; - PSecPkgInfo SecurityPackage; - SecBuffer chlg_buf[5]; - SecBufferDesc chlg_desc; - SECURITY_STATUS status; - - /* Query the security package for DigestSSP */ - status = - Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_DIGEST)), - &SecurityPackage); - if(status != SEC_E_OK) { - failf(data, "SSPI: could not get auth info"); - return CURLE_AUTH_ERROR; - } - - token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate the output buffer according to the max token size as indicated - by the security package */ - output_token = curlx_malloc(token_max); - if(!output_token) { - return CURLE_OUT_OF_MEMORY; - } - - /* If the user/passwd that was used to make the identity for http_context - has changed then delete that context. */ - if((userp && !digest->user) || (!userp && digest->user) || - (passwdp && !digest->passwd) || (!passwdp && digest->passwd) || - (userp && digest->user && Curl_timestrcmp(userp, digest->user)) || - (passwdp && digest->passwd && Curl_timestrcmp(passwdp, digest->passwd))) { - if(digest->http_context) { - Curl_pSecFn->DeleteSecurityContext(digest->http_context); - curlx_safefree(digest->http_context); - } - curlx_safefree(digest->user); - curlx_safefree(digest->passwd); - } - - if(digest->http_context) { - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 5; - chlg_desc.pBuffers = chlg_buf; - chlg_buf[0].BufferType = SECBUFFER_TOKEN; - chlg_buf[0].pvBuffer = NULL; - chlg_buf[0].cbBuffer = 0; - chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS; - chlg_buf[1].pvBuffer = CURL_UNCONST(request); - chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *)request)); - chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS; - chlg_buf[2].pvBuffer = CURL_UNCONST(uripath); - chlg_buf[2].cbBuffer = curlx_uztoul(strlen((const char *)uripath)); - chlg_buf[3].BufferType = SECBUFFER_PKG_PARAMS; - chlg_buf[3].pvBuffer = NULL; - chlg_buf[3].cbBuffer = 0; - chlg_buf[4].BufferType = SECBUFFER_PADDING; - chlg_buf[4].pvBuffer = output_token; - chlg_buf[4].cbBuffer = curlx_uztoul(token_max); - - status = Curl_pSecFn->MakeSignature(digest->http_context, 0, &chlg_desc, - 0); - if(status == SEC_E_OK) - output_token_len = chlg_buf[4].cbBuffer; - else { /* delete the context so a new one can be made */ - infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx", status); - Curl_pSecFn->DeleteSecurityContext(digest->http_context); - curlx_safefree(digest->http_context); - } - } - - if(!digest->http_context) { - CredHandle credentials; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - SecBuffer resp_buf; - SecBufferDesc resp_desc; - unsigned long attrs; - TCHAR *spn; - - /* free the copy of user/passwd used to make the previous identity */ - curlx_safefree(digest->user); - curlx_safefree(digest->passwd); - - if(userp && *userp) { - /* Populate our identity structure */ - if(Curl_create_sspi_identity(userp, passwdp, &identity)) { - curlx_free(output_token); - return CURLE_OUT_OF_MEMORY; - } - - /* Populate our identity domain */ - if(Curl_override_sspi_http_realm((const char *)digest->input_token, - &identity)) { - Curl_sspi_free_identity(&identity); - curlx_free(output_token); - return CURLE_OUT_OF_MEMORY; - } - - /* Allow proper cleanup of the identity structure */ - p_identity = &identity; - } - else - /* Use the current Windows user */ - p_identity = NULL; - - if(userp) { - digest->user = curlx_strdup(userp); - - if(!digest->user) { - curlx_free(output_token); - Curl_sspi_free_identity(p_identity); - return CURLE_OUT_OF_MEMORY; - } - } - - if(passwdp) { - digest->passwd = curlx_strdup(passwdp); - - if(!digest->passwd) { - curlx_free(output_token); - Curl_sspi_free_identity(p_identity); - curlx_safefree(digest->user); - return CURLE_OUT_OF_MEMORY; - } - } - - /* Acquire our credentials handle */ - status = Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_DIGEST)), - SECPKG_CRED_OUTBOUND, NULL, - p_identity, NULL, NULL, - &credentials, NULL); - if(status != SEC_E_OK) { - Curl_sspi_free_identity(p_identity); - curlx_free(output_token); - - return CURLE_LOGIN_DENIED; - } - - /* Setup the challenge "input" security buffer if present */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 3; - chlg_desc.pBuffers = chlg_buf; - chlg_buf[0].BufferType = SECBUFFER_TOKEN; - chlg_buf[0].pvBuffer = digest->input_token; - chlg_buf[0].cbBuffer = curlx_uztoul(digest->input_token_len); - chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS; - chlg_buf[1].pvBuffer = CURL_UNCONST(request); - chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *)request)); - chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS; - chlg_buf[2].pvBuffer = NULL; - chlg_buf[2].cbBuffer = 0; - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = output_token; - resp_buf.cbBuffer = curlx_uztoul(token_max); - - spn = curlx_convert_UTF8_to_tchar((const char *)uripath); - if(!spn) { - Curl_pSecFn->FreeCredentialsHandle(&credentials); - - Curl_sspi_free_identity(p_identity); - curlx_free(output_token); - - return CURLE_OUT_OF_MEMORY; - } - - /* Allocate our new context handle */ - digest->http_context = curlx_calloc(1, sizeof(CtxtHandle)); - if(!digest->http_context) { - Curl_pSecFn->FreeCredentialsHandle(&credentials); - curlx_free(spn); - Curl_sspi_free_identity(p_identity); - curlx_free(output_token); - return CURLE_OUT_OF_MEMORY; - } - - /* Generate our response message */ - status = Curl_pSecFn->InitializeSecurityContext(&credentials, NULL, - spn, - ISC_REQ_USE_HTTP_STYLE, 0, 0, - &chlg_desc, 0, - digest->http_context, - &resp_desc, &attrs, NULL); - curlx_free(spn); - - if(status == SEC_I_COMPLETE_NEEDED || - status == SEC_I_COMPLETE_AND_CONTINUE) - Curl_pSecFn->CompleteAuthToken(&credentials, &resp_desc); - else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { - VERBOSE(char buffer[STRERROR_LEN]); - - Curl_pSecFn->FreeCredentialsHandle(&credentials); - - Curl_sspi_free_identity(p_identity); - curlx_free(output_token); - - curlx_safefree(digest->http_context); - - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - infof(data, "schannel: InitializeSecurityContext failed: %s", - Curl_sspi_strerror(status, buffer, sizeof(buffer))); - - return CURLE_AUTH_ERROR; - } - - output_token_len = resp_buf.cbBuffer; - - Curl_pSecFn->FreeCredentialsHandle(&credentials); - Curl_sspi_free_identity(p_identity); - } - - resp = curlx_memdup0((const char *)output_token, output_token_len); - curlx_free(output_token); - if(!resp) { - return CURLE_OUT_OF_MEMORY; - } - - /* Return the response */ - *outptr = resp; - *outlen = output_token_len; - return CURLE_OK; -} - -/* - * Curl_auth_digest_cleanup() - * - * This is used to clean up the digest specific data. - * - * Parameters: - * - * digest [in/out] - The digest data struct being cleaned up. - * - */ -void Curl_auth_digest_cleanup(struct digestdata *digest) -{ - /* Free the input token */ - curlx_safefree(digest->input_token); - - /* Reset any variables */ - digest->input_token_len = 0; - - /* Delete security context */ - if(digest->http_context) { - Curl_pSecFn->DeleteSecurityContext(digest->http_context); - curlx_safefree(digest->http_context); - } - - /* Free the copy of user/passwd used to make the identity for http_context */ - curlx_safefree(digest->user); - curlx_safefree(digest->passwd); -} - -#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_DIGEST_AUTH */ diff --git a/vendor/curl/lib/vauth/gsasl.c b/vendor/curl/lib/vauth/gsasl.c deleted file mode 100644 index 958f4ffab..000000000 --- a/vendor/curl/lib/vauth/gsasl.c +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Simon Josefsson, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC5802 SCRAM-SHA-1 authentication - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_GSASL - -#include "vauth/vauth.h" -#include "curl_trc.h" - -#include - -bool Curl_auth_gsasl_is_supported(struct Curl_easy *data, - const char *mech, - struct gsasldata *gsasl) -{ - int res; - - res = gsasl_init(&gsasl->ctx); - if(res != GSASL_OK) { - failf(data, "gsasl init: %s", gsasl_strerror(res)); - return FALSE; - } - - res = gsasl_client_start(gsasl->ctx, mech, &gsasl->client); - if(res != GSASL_OK) { - gsasl_done(gsasl->ctx); - return FALSE; - } - - return TRUE; -} - -CURLcode Curl_auth_gsasl_start(struct Curl_easy *data, - const char *userp, - const char *passwdp, - struct gsasldata *gsasl) -{ -#if GSASL_VERSION_NUMBER >= 0x010b00 - int res; - res = -#endif - gsasl_property_set(gsasl->client, GSASL_AUTHID, userp); -#if GSASL_VERSION_NUMBER >= 0x010b00 - if(res != GSASL_OK) { - failf(data, "setting AUTHID failed: %s", gsasl_strerror(res)); - return CURLE_OUT_OF_MEMORY; - } -#endif - -#if GSASL_VERSION_NUMBER >= 0x010b00 - res = -#endif - gsasl_property_set(gsasl->client, GSASL_PASSWORD, passwdp); -#if GSASL_VERSION_NUMBER >= 0x010b00 - if(res != GSASL_OK) { - failf(data, "setting PASSWORD failed: %s", gsasl_strerror(res)); - return CURLE_OUT_OF_MEMORY; - } -#endif - - (void)data; - - return CURLE_OK; -} - -CURLcode Curl_auth_gsasl_token(struct Curl_easy *data, - const struct bufref *chlg, - struct gsasldata *gsasl, - struct bufref *out) -{ - int res; - char *response; - size_t outlen; - - res = gsasl_step(gsasl->client, Curl_bufref_ptr(chlg), Curl_bufref_len(chlg), - &response, &outlen); - if(res != GSASL_OK && res != GSASL_NEEDS_MORE) { - failf(data, "GSASL step: %s", gsasl_strerror(res)); - return CURLE_BAD_CONTENT_ENCODING; - } - - Curl_bufref_set(out, response, outlen, gsasl_free); - return CURLE_OK; -} - -void Curl_auth_gsasl_cleanup(struct gsasldata *gsasl) -{ - gsasl_finish(gsasl->client); - gsasl->client = NULL; - - gsasl_done(gsasl->ctx); - gsasl->ctx = NULL; -} -#endif diff --git a/vendor/curl/lib/vauth/krb5_gssapi.c b/vendor/curl/lib/vauth/krb5_gssapi.c deleted file mode 100644 index 64c735be5..000000000 --- a/vendor/curl/lib/vauth/krb5_gssapi.c +++ /dev/null @@ -1,327 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(HAVE_GSSAPI) && defined(USE_KERBEROS5) - -#include "vauth/vauth.h" -#include "curl_sasl.h" -#include "curl_gssapi.h" -#include "curl_trc.h" - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -/* - * Curl_auth_is_gssapi_supported() - * - * This is used to evaluate if GSSAPI (Kerberos V5) is supported. - * - * Parameters: None - * - * Returns TRUE if Kerberos V5 is supported by the GSS-API library. - */ -bool Curl_auth_is_gssapi_supported(void) -{ - return TRUE; -} - -/* - * Curl_auth_create_gssapi_user_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) user token - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username. - * passwdp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in[ - The hostname. - * mutual_auth [in] - Flag specifying whether or not mutual authentication - * is enabled. - * chlg [in] - Optional challenge message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - const bool mutual_auth, - const struct bufref *chlg, - struct kerberos5data *krb5, - struct bufref *out) -{ - CURLcode result = CURLE_OK; - OM_uint32 major_status; - OM_uint32 minor_status; - OM_uint32 unused_status; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - - (void)userp; - (void)passwdp; - - if(!krb5->spn) { - gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; - - /* Generate our SPN */ - char *spn = Curl_auth_build_spn(service, NULL, host); - if(!spn) - return CURLE_OUT_OF_MEMORY; - - /* Populate the SPN structure */ - spn_token.value = spn; - spn_token.length = strlen(spn); - - /* Import the SPN */ - major_status = gss_import_name(&minor_status, &spn_token, - GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_import_name() failed: ", - major_status, minor_status); - - curlx_free(spn); - - return CURLE_AUTH_ERROR; - } - - curlx_free(spn); - } - - if(chlg) { - if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty challenge message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - input_token.value = CURL_UNCONST(Curl_bufref_ptr(chlg)); - input_token.length = Curl_bufref_len(chlg); - } - - major_status = Curl_gss_init_sec_context(data, - &minor_status, - &krb5->context, - krb5->spn, - &Curl_krb5_mech_oid, - GSS_C_NO_CHANNEL_BINDINGS, - &input_token, - &output_token, - mutual_auth, - NULL); - - if(GSS_ERROR(major_status)) { - if(output_token.value) - gss_release_buffer(&unused_status, &output_token); - - Curl_gss_log_error(data, "gss_init_sec_context() failed: ", - major_status, minor_status); - - return CURLE_AUTH_ERROR; - } - - if(output_token.value && output_token.length) { - result = Curl_bufref_memdup0(out, output_token.value, output_token.length); - gss_release_buffer(&unused_status, &output_token); - } - else - Curl_bufref_set(out, mutual_auth ? "" : NULL, 0, NULL); - - return result; -} - -/* - * Curl_auth_create_gssapi_security_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) security - * token message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * authzid [in] - The authorization identity if some. - * chlg [in] - Optional challenge message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, - const char *authzid, - const struct bufref *chlg, - struct kerberos5data *krb5, - struct bufref *out) -{ - CURLcode result = CURLE_OK; - size_t messagelen = 0; - unsigned char *message = NULL; - OM_uint32 major_status; - OM_uint32 minor_status; - OM_uint32 unused_status; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - unsigned char *indata; - gss_qop_t qop = GSS_C_QOP_DEFAULT; - unsigned int sec_layer = 0; - unsigned int max_size = 0; - - /* Ensure we have a valid challenge message */ - if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty security message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - input_token.value = CURL_UNCONST(Curl_bufref_ptr(chlg)); - input_token.length = Curl_bufref_len(chlg); - - /* Decrypt the inbound challenge and obtain the qop */ - major_status = gss_unwrap(&minor_status, krb5->context, &input_token, - &output_token, NULL, &qop); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_unwrap() failed: ", - major_status, minor_status); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ - if(output_token.length != 4) { - infof(data, "GSSAPI handshake failure (invalid security data)"); - gss_release_buffer(&unused_status, &output_token); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Extract the security layer and the maximum message size */ - indata = output_token.value; - sec_layer = indata[0]; - max_size = ((unsigned int)indata[1] << 16) | - ((unsigned int)indata[2] << 8) | indata[3]; - - /* Free the challenge as it is not required anymore */ - gss_release_buffer(&unused_status, &output_token); - - /* Process the security layer */ - if(!(sec_layer & GSSAUTH_P_NONE)) { - infof(data, "GSSAPI handshake failure (invalid security layer)"); - - return CURLE_BAD_CONTENT_ENCODING; - } - sec_layer &= GSSAUTH_P_NONE; /* We do not support a security layer */ - - /* Process the maximum message size the server can receive */ - if(max_size > 0) { - /* The server has told us it supports a maximum receive buffer, but as we - do not require one unless we are encrypting data, we tell the server - our receive buffer is zero. */ - max_size = 0; - } - - /* Allocate our message */ - messagelen = 4; - if(authzid) - messagelen += strlen(authzid); - message = curlx_malloc(messagelen); - if(!message) - return CURLE_OUT_OF_MEMORY; - - /* Populate the message with the security layer and client supported receive - message size. */ - message[0] = sec_layer & 0xFF; - message[1] = (max_size >> 16) & 0xFF; - message[2] = (max_size >> 8) & 0xFF; - message[3] = max_size & 0xFF; - - /* If given, append the authorization identity. */ - - if(authzid && *authzid) - memcpy(message + 4, authzid, messagelen - 4); - - /* Setup the "authentication data" security buffer */ - input_token.value = message; - input_token.length = messagelen; - - /* Encrypt the data */ - major_status = gss_wrap(&minor_status, krb5->context, 0, - GSS_C_QOP_DEFAULT, &input_token, NULL, - &output_token); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_wrap() failed: ", - major_status, minor_status); - curlx_free(message); - return CURLE_AUTH_ERROR; - } - - /* Return the response. */ - result = Curl_bufref_memdup0(out, output_token.value, output_token.length); - /* Free the output buffer */ - gss_release_buffer(&unused_status, &output_token); - - /* Free the message buffer */ - curlx_free(message); - - return result; -} - -/* - * Curl_auth_cleanup_gssapi() - * - * This is used to clean up the GSSAPI (Kerberos V5) specific data. - * - * Parameters: - * - * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. - * - */ -void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) -{ - OM_uint32 minor_status; - - /* Free our security context */ - if(krb5->context != GSS_C_NO_CONTEXT) { - Curl_gss_delete_sec_context(&minor_status, &krb5->context, - GSS_C_NO_BUFFER); - krb5->context = GSS_C_NO_CONTEXT; - } - - /* Free the SPN */ - if(krb5->spn != GSS_C_NO_NAME) { - gss_release_name(&minor_status, &krb5->spn); - krb5->spn = GSS_C_NO_NAME; - } -} - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic pop -#endif - -#endif /* HAVE_GSSAPI && USE_KERBEROS5 */ diff --git a/vendor/curl/lib/vauth/krb5_sspi.c b/vendor/curl/lib/vauth/krb5_sspi.c deleted file mode 100644 index e7491be02..000000000 --- a/vendor/curl/lib/vauth/krb5_sspi.c +++ /dev/null @@ -1,454 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && defined(USE_KERBEROS5) - -#include "vauth/vauth.h" -#include "curl_trc.h" - -/* - * Curl_auth_is_gssapi_supported() - * - * This is used to evaluate if GSSAPI (Kerberos V5) is supported. - * - * Parameters: None - * - * Returns TRUE if Kerberos V5 is supported by Windows SSPI. - */ -bool Curl_auth_is_gssapi_supported(void) -{ - PSecPkgInfo SecurityPackage; - SECURITY_STATUS status; - - /* Query the security package for Kerberos */ - status = Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_KERBEROS)), - &SecurityPackage); - - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - } - - return status == SEC_E_OK; -} - -/* - * Curl_auth_create_gssapi_user_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) user token - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The hostname. - * mutual_auth [in] - Flag specifying whether or not mutual authentication - * is enabled. - * chlg [in] - Optional challenge message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - const bool mutual_auth, - const struct bufref *chlg, - struct kerberos5data *krb5, - struct bufref *out) -{ - CURLcode result = CURLE_OK; - CtxtHandle context; - PSecPkgInfo SecurityPackage; - SecBuffer chlg_buf; - SecBuffer resp_buf; - SecBufferDesc chlg_desc; - SecBufferDesc resp_desc; - SECURITY_STATUS status; - unsigned long attrs; - - if(!krb5->spn) { - /* Generate our SPN */ - krb5->spn = Curl_auth_build_spn(service, host, NULL); - if(!krb5->spn) - return CURLE_OUT_OF_MEMORY; - } - - if(!krb5->output_token) { - /* Query the security package for Kerberos */ - status = Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_KERBEROS)), - &SecurityPackage); - if(status != SEC_E_OK) { - failf(data, "SSPI: could not get auth info"); - return CURLE_AUTH_ERROR; - } - - krb5->token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our response buffer */ - krb5->output_token = curlx_malloc(krb5->token_max); - if(!krb5->output_token) - return CURLE_OUT_OF_MEMORY; - } - - if(!krb5->credentials) { - /* Do we have credentials to use or are we using single sign-on? */ - if(userp && *userp) { - /* Populate our identity structure */ - result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity); - if(result) - return result; - - /* Allow proper cleanup of the identity structure */ - krb5->p_identity = &krb5->identity; - } - else - /* Use the current Windows user */ - krb5->p_identity = NULL; - - /* Allocate our credentials handle */ - krb5->credentials = curlx_calloc(1, sizeof(CredHandle)); - if(!krb5->credentials) - return CURLE_OUT_OF_MEMORY; - - /* Acquire our credentials handle */ - status = Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_KERBEROS)), - SECPKG_CRED_OUTBOUND, NULL, - krb5->p_identity, NULL, NULL, - krb5->credentials, NULL); - if(status != SEC_E_OK) - return CURLE_LOGIN_DENIED; - - /* Allocate our new context handle */ - krb5->context = curlx_calloc(1, sizeof(CtxtHandle)); - if(!krb5->context) - return CURLE_OUT_OF_MEMORY; - } - - if(chlg) { - if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty challenge message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 1; - chlg_desc.pBuffers = &chlg_buf; - chlg_buf.BufferType = SECBUFFER_TOKEN; - chlg_buf.pvBuffer = CURL_UNCONST(Curl_bufref_ptr(chlg)); - chlg_buf.cbBuffer = curlx_uztoul(Curl_bufref_len(chlg)); - } - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = krb5->output_token; - resp_buf.cbBuffer = curlx_uztoul(krb5->token_max); - - /* Generate our challenge-response message */ - status = Curl_pSecFn->InitializeSecurityContext(krb5->credentials, - chlg ? krb5->context : NULL, - krb5->spn, - (mutual_auth ? - ISC_REQ_MUTUAL_AUTH : 0), - 0, SECURITY_NATIVE_DREP, - chlg ? &chlg_desc : NULL, 0, - &context, - &resp_desc, &attrs, NULL); - - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) - return CURLE_AUTH_ERROR; - - if(memcmp(&context, krb5->context, sizeof(context))) { - Curl_pSecFn->DeleteSecurityContext(krb5->context); - - memcpy(krb5->context, &context, sizeof(context)); - } - - if(resp_buf.cbBuffer) { - result = Curl_bufref_memdup0(out, resp_buf.pvBuffer, resp_buf.cbBuffer); - } - else if(mutual_auth) - Curl_bufref_set(out, "", 0, NULL); - else - Curl_bufref_set(out, NULL, 0, NULL); - - return result; -} - -/* - * Curl_auth_create_gssapi_security_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) security - * token message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * authzid [in] - The authorization identity if some. - * chlg [in] - The challenge message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, - const char *authzid, - const struct bufref *chlg, - struct kerberos5data *krb5, - struct bufref *out) -{ - CURLcode result = CURLE_OK; - size_t offset = 0; - size_t messagelen = 0; - size_t appdatalen = 0; - unsigned char *trailer = NULL; - unsigned char *message = NULL; - unsigned char *padding = NULL; - unsigned char *appdata = NULL; - SecBuffer input_buf[2]; - SecBuffer wrap_buf[3]; - SecBufferDesc input_desc; - SecBufferDesc wrap_desc; - unsigned char *indata; - unsigned long qop = 0; - unsigned long sec_layer = 0; - unsigned long max_size = 0; - SecPkgContext_Sizes sizes; - SECURITY_STATUS status; - - /* Ensure we have a valid challenge message */ - DEBUGASSERT(chlg); - if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty security message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Get our response size information */ - status = Curl_pSecFn->QueryContextAttributes(krb5->context, - SECPKG_ATTR_SIZES, &sizes); - - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - if(status != SEC_E_OK) - return CURLE_AUTH_ERROR; - - /* Setup the "input" security buffer */ - input_desc.ulVersion = SECBUFFER_VERSION; - input_desc.cBuffers = 2; - input_desc.pBuffers = input_buf; - input_buf[0].BufferType = SECBUFFER_STREAM; - input_buf[0].pvBuffer = CURL_UNCONST(Curl_bufref_ptr(chlg)); - input_buf[0].cbBuffer = curlx_uztoul(Curl_bufref_len(chlg)); - input_buf[1].BufferType = SECBUFFER_DATA; - input_buf[1].pvBuffer = NULL; - input_buf[1].cbBuffer = 0; - - /* Decrypt the inbound challenge and obtain the qop */ - status = Curl_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop); - if(status != SEC_E_OK) { - infof(data, "GSSAPI handshake failure (empty security message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ - if(input_buf[1].cbBuffer != 4) { - infof(data, "GSSAPI handshake failure (invalid security data)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Extract the security layer and the maximum message size */ - indata = input_buf[1].pvBuffer; - sec_layer = indata[0]; - max_size = ((unsigned long)indata[1] << 16) | - ((unsigned long)indata[2] << 8) | indata[3]; - - /* Free the challenge as it is not required anymore */ - Curl_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer); - - /* Process the security layer */ - if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) { - infof(data, "GSSAPI handshake failure (invalid security layer)"); - return CURLE_BAD_CONTENT_ENCODING; - } - sec_layer &= KERB_WRAP_NO_ENCRYPT; /* We do not support a security layer */ - - /* Process the maximum message size the server can receive */ - if(max_size > 0) { - /* The server has told us it supports a maximum receive buffer, but as we - do not require one unless we are encrypting data, we tell the server - our receive buffer is zero. */ - max_size = 0; - } - - /* Allocate the trailer */ - trailer = curlx_malloc(sizes.cbSecurityTrailer); - if(!trailer) - return CURLE_OUT_OF_MEMORY; - - /* Allocate our message */ - messagelen = 4; - if(authzid) - messagelen += strlen(authzid); - message = curlx_malloc(messagelen); - if(!message) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Populate the message with the security layer and client supported receive - message size. */ - message[0] = sec_layer & 0xFF; - message[1] = (max_size >> 16) & 0xFF; - message[2] = (max_size >> 8) & 0xFF; - message[3] = max_size & 0xFF; - - /* If given, append the authorization identity. */ - - if(authzid && *authzid) - memcpy(message + 4, authzid, messagelen - 4); - - /* Allocate the padding */ - padding = curlx_malloc(sizes.cbBlockSize); - if(!padding) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Setup the "authentication data" security buffer */ - wrap_desc.ulVersion = SECBUFFER_VERSION; - wrap_desc.cBuffers = 3; - wrap_desc.pBuffers = wrap_buf; - wrap_buf[0].BufferType = SECBUFFER_TOKEN; - wrap_buf[0].pvBuffer = trailer; - wrap_buf[0].cbBuffer = sizes.cbSecurityTrailer; - wrap_buf[1].BufferType = SECBUFFER_DATA; - wrap_buf[1].pvBuffer = message; - wrap_buf[1].cbBuffer = curlx_uztoul(messagelen); - wrap_buf[2].BufferType = SECBUFFER_PADDING; - wrap_buf[2].pvBuffer = padding; - wrap_buf[2].cbBuffer = sizes.cbBlockSize; - - /* Encrypt the data */ - status = Curl_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT, - &wrap_desc, 0); - if(status != SEC_E_OK) { - if(status == SEC_E_INSUFFICIENT_MEMORY) - result = CURLE_OUT_OF_MEMORY; - else - result = CURLE_AUTH_ERROR; - goto out; - } - - /* Allocate the encryption (wrap) buffer */ - appdatalen = wrap_buf[0].cbBuffer + wrap_buf[1].cbBuffer + - wrap_buf[2].cbBuffer; - appdata = curlx_malloc(appdatalen); - if(!appdata) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Populate the encryption buffer */ - memcpy(appdata, wrap_buf[0].pvBuffer, wrap_buf[0].cbBuffer); - offset += wrap_buf[0].cbBuffer; - memcpy(appdata + offset, wrap_buf[1].pvBuffer, wrap_buf[1].cbBuffer); - offset += wrap_buf[1].cbBuffer; - memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer); - -out: - /* Free all of our local buffers */ - curlx_free(padding); - curlx_free(message); - curlx_free(trailer); - - if(result) - return result; - - /* Return the response. */ - Curl_bufref_set(out, appdata, appdatalen, curl_free); - return CURLE_OK; -} - -/* - * Curl_auth_cleanup_gssapi() - * - * This is used to clean up the GSSAPI (Kerberos V5) specific data. - * - * Parameters: - * - * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. - * - */ -void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) -{ - /* Free our security context */ - if(krb5->context) { - Curl_pSecFn->DeleteSecurityContext(krb5->context); - curlx_free(krb5->context); - krb5->context = NULL; - } - - /* Free our credentials handle */ - if(krb5->credentials) { - Curl_pSecFn->FreeCredentialsHandle(krb5->credentials); - curlx_free(krb5->credentials); - krb5->credentials = NULL; - } - - /* Free our identity */ - Curl_sspi_free_identity(krb5->p_identity); - krb5->p_identity = NULL; - - /* Free the SPN and output token */ - curlx_safefree(krb5->spn); - curlx_safefree(krb5->output_token); - - /* Reset any variables */ - krb5->token_max = 0; -} - -#endif /* USE_WINDOWS_SSPI && USE_KERBEROS5 */ diff --git a/vendor/curl/lib/vauth/ntlm.c b/vendor/curl/lib/vauth/ntlm.c deleted file mode 100644 index 1e485ed34..000000000 --- a/vendor/curl/lib/vauth/ntlm.c +++ /dev/null @@ -1,859 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI) - -/* - * NTLM details: - * - * https://davenport.sourceforge.net/ntlm.html - * https://www.innovation.ch/java/ntlm.html - */ - -#define DEBUG_ME 0 - -#include "vauth/vauth.h" -#include "curl_trc.h" -#include "curl_ntlm_core.h" -#include "rand.h" -#include "curlx/strdup.h" -#include "curl_endian.h" - -/* "NTLMSSP" signature is always in ASCII regardless of the platform */ -#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" - -/* NTLM buffer fixed size, large enough for long user + host + domain */ -#define NTLM_BUFSIZE 1024 - -/* Flag bits definitions based on - https://davenport.sourceforge.net/ntlm.html */ - -#define NTLMFLAG_NEGOTIATE_UNICODE (1 << 0) -/* Indicates that Unicode strings are supported for use in security buffer - data. */ - -#define NTLMFLAG_NEGOTIATE_OEM (1 << 1) -/* Indicates that OEM strings are supported for use in security buffer data. */ - -#define NTLMFLAG_REQUEST_TARGET (1 << 2) -/* Requests that the server's authentication realm be included in the Type 2 - message. */ - -#if DEBUG_ME -/* unknown (1 << 3) */ -#define NTLMFLAG_NEGOTIATE_SIGN (1 << 4) -/* Specifies that authenticated communication between the client and server - should carry a digital signature (message integrity). */ - -#define NTLMFLAG_NEGOTIATE_SEAL (1 << 5) -/* Specifies that authenticated communication between the client and server - should be encrypted (message confidentiality). */ - -#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1 << 6) -/* Indicates that datagram authentication is being used. */ - -#define NTLMFLAG_NEGOTIATE_LM_KEY (1 << 7) -/* Indicates that the LAN Manager session key should be used for signing and - sealing authenticated communications. */ -#endif - -#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1 << 9) -/* Indicates that NTLM authentication is being used. */ - -#if DEBUG_ME -/* unknown (1 << 10) */ - -#define NTLMFLAG_NEGOTIATE_ANONYMOUS (1 << 11) -/* Sent by the client in the Type 3 message to indicate that an anonymous - context has been established. This also affects the response fields. */ - -#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1 << 12) -/* Sent by the client in the Type 1 message to indicate that a desired - authentication realm is included in the message. */ - -#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1 << 13) -/* Sent by the client in the Type 1 message to indicate that the client - workstation's name is included in the message. */ - -#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1 << 14) -/* Sent by the server to indicate that the server and client are on the same - machine. Implies that the client may use a pre-established local security - context rather than responding to the challenge. */ -#endif - -#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1 << 15) -/* Indicates that authenticated communication between the client and server - should be signed with a "dummy" signature. */ - -#if DEBUG_ME -#define NTLMFLAG_TARGET_TYPE_DOMAIN (1 << 16) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a domain. */ - -#define NTLMFLAG_TARGET_TYPE_SERVER (1 << 17) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a server. */ - -#define NTLMFLAG_TARGET_TYPE_SHARE (1 << 18) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a share. Presumably, this is for share-level - authentication. Usage is unclear. */ -#endif - -#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1 << 19) -/* Indicates that the NTLM2 signing and sealing scheme should be used for - protecting authenticated communications. */ - -#if DEBUG_ME -#define NTLMFLAG_REQUEST_INIT_RESPONSE (1 << 20) -/* unknown purpose */ - -#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1 << 21) -/* unknown purpose */ - -#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1 << 22) -/* unknown purpose */ -#endif - -#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1 << 23) -/* Sent by the server in the Type 2 message to indicate that it is including a - Target Information block in the message. */ - -#if DEBUG_ME -/* unknown (1<24) */ -/* unknown (1<25) */ -/* unknown (1<26) */ -/* unknown (1<27) */ -/* unknown (1<28) */ - -#define NTLMFLAG_NEGOTIATE_128 (1 << 29) -/* Indicates that 128-bit encryption is supported. */ - -#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1 << 30) -/* Indicates that the client provides an encrypted master key in - the "Session Key" field of the Type 3 message. */ - -#define NTLMFLAG_NEGOTIATE_56 (1 << 31) -/* Indicates that 56-bit encryption is supported. */ - -#define DEBUG_OUT(x) x -static void ntlm_print_flags(FILE *handle, unsigned long flags) -{ - if(flags & NTLMFLAG_NEGOTIATE_UNICODE) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE "); - if(flags & NTLMFLAG_NEGOTIATE_OEM) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_OEM "); - if(flags & NTLMFLAG_REQUEST_TARGET) - curl_mfprintf(handle, "NTLMFLAG_REQUEST_TARGET "); - if(flags & (1 << 3)) - curl_mfprintf(handle, "NTLMFLAG_UNKNOWN_3 "); - if(flags & NTLMFLAG_NEGOTIATE_SIGN) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN "); - if(flags & NTLMFLAG_NEGOTIATE_SEAL) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL "); - if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE "); - if(flags & NTLMFLAG_NEGOTIATE_LM_KEY) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY "); - if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY "); - if(flags & (1 << 10)) - curl_mfprintf(handle, "NTLMFLAG_UNKNOWN_10 "); - if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS "); - if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED "); - if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED "); - if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL "); - if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN "); - if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN) - curl_mfprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN "); - if(flags & NTLMFLAG_TARGET_TYPE_SERVER) - curl_mfprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER "); - if(flags & NTLMFLAG_TARGET_TYPE_SHARE) - curl_mfprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE "); - if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY "); - if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE) - curl_mfprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE "); - if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE) - curl_mfprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE "); - if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY) - curl_mfprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY "); - if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO "); - if(flags & (1 << 24)) - curl_mfprintf(handle, "NTLMFLAG_UNKNOWN_24 "); - if(flags & (1 << 25)) - curl_mfprintf(handle, "NTLMFLAG_UNKNOWN_25 "); - if(flags & (1 << 26)) - curl_mfprintf(handle, "NTLMFLAG_UNKNOWN_26 "); - if(flags & (1 << 27)) - curl_mfprintf(handle, "NTLMFLAG_UNKNOWN_27 "); - if(flags & (1 << 28)) - curl_mfprintf(handle, "NTLMFLAG_UNKNOWN_28 "); - if(flags & NTLMFLAG_NEGOTIATE_128) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_128 "); - if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE "); - if(flags & NTLMFLAG_NEGOTIATE_56) - curl_mfprintf(handle, "NTLMFLAG_NEGOTIATE_56 "); -} - -static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) -{ - const char *p = buf; - - (void)handle; - - curl_mfprintf(stderr, "0x"); - while(len-- > 0) - curl_mfprintf(stderr, "%02.2x", (unsigned int)*p++); -} -#else -#define DEBUG_OUT(x) Curl_nop_stmt -#endif - -/* - * ntlm_decode_type2_target() - * - * This is used to decode the "target info" in the NTLM type-2 message - * received. - * - * Parameters: - * - * data [in] - The session handle. - * type2ref [in] - The type-2 message. - * ntlm [in/out] - The NTLM data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, - const struct bufref *type2ref, - struct ntlmdata *ntlm) -{ - unsigned short target_info_len = 0; - unsigned int target_info_offset = 0; - const unsigned char *type2 = Curl_bufref_uptr(type2ref); - size_t type2len = Curl_bufref_len(type2ref); - - if(type2len >= 48) { - target_info_len = Curl_read16_le(&type2[40]); - target_info_offset = Curl_read32_le(&type2[44]); - if(target_info_len > 0) { - if((target_info_offset > type2len) || - (target_info_offset + target_info_len) > type2len || - target_info_offset < 48) { - infof(data, "NTLM handshake failure (bad type-2 message). " - "Target Info Offset Len is set incorrect by the peer"); - return CURLE_BAD_CONTENT_ENCODING; - } - - curlx_free(ntlm->target_info); /* replace any previous data */ - ntlm->target_info = curlx_memdup(&type2[target_info_offset], - target_info_len); - if(!ntlm->target_info) - return CURLE_OUT_OF_MEMORY; - } - } - - ntlm->target_info_len = target_info_len; - - return CURLE_OK; -} - -/* - NTLM message structure notes: - - A 'short' is a 'network short', a little-endian 16-bit unsigned value. - - A 'long' is a 'network long', a little-endian, 32-bit unsigned value. - - A 'security buffer' represents a triplet used to point to a buffer, - consisting of two shorts and one long: - - 1. A 'short' containing the length of the buffer content in bytes. - 2. A 'short' containing the allocated space for the buffer in bytes. - 3. A 'long' containing the offset to the start of the buffer in bytes, - from the beginning of the NTLM message. -*/ - -/* - * Curl_auth_is_ntlm_supported() - * - * This is used to evaluate if NTLM is supported. - * - * Parameters: None - * - * Returns TRUE as NTLM as handled by libcurl. - */ -bool Curl_auth_is_ntlm_supported(void) -{ - return TRUE; -} - -/* - * Curl_auth_decode_ntlm_type2_message() - * - * This is used to decode an NTLM type-2 message. The raw NTLM message is - * checked * for validity before the appropriate data for creating a type-3 - * message is * written to the given NTLM data structure. - * - * Parameters: - * - * data [in] - The session handle. - * type2ref [in] - The type-2 message. - * ntlm [in/out] - The NTLM data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, - const struct bufref *type2ref, - struct ntlmdata *ntlm) -{ - static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 }; - - /* NTLM type-2 message structure: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x02000000) - 12 Target Name security buffer - 20 Flags long - 24 Challenge 8 bytes - (32) Context 8 bytes (two consecutive longs) (*) - (40) Target Information security buffer (*) - (48) OS Version Structure 8 bytes (*) - 32 (48) (56) Start of data block (*) - (*) -> Optional - */ - - CURLcode result = CURLE_OK; - const unsigned char *type2 = Curl_bufref_uptr(type2ref); - size_t type2len = Curl_bufref_len(type2ref); - - ntlm->flags = 0; - - if((type2len < 32) || - (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) || - (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) { - /* This was not a good enough type-2 message */ - infof(data, "NTLM handshake failure (bad type-2 message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - ntlm->flags = Curl_read32_le(&type2[20]); - memcpy(ntlm->nonce, &type2[24], 8); - - if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) { - result = ntlm_decode_type2_target(data, type2ref, ntlm); - if(result) { - infof(data, "NTLM handshake failure (bad type-2 message)"); - return result; - } - } - - DEBUG_OUT({ - curl_mfprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags); - ntlm_print_flags(stderr, ntlm->flags); - curl_mfprintf(stderr, "\n nonce="); - ntlm_print_hex(stderr, (char *)ntlm->nonce, 8); - curl_mfprintf(stderr, "\n****\n"); - curl_mfprintf(stderr, "**** Header %s\n ", header); - }); - - return result; -} - -/* copy the source to the destination and fill in zeroes in every - other destination byte! */ -static void unicodecpy(unsigned char *dest, const char *src, size_t length) -{ - size_t i; - for(i = 0; i < length; i++) { - dest[2 * i] = (unsigned char)src[i]; - dest[(2 * i) + 1] = '\0'; - } -} - -/* - * Curl_auth_create_ntlm_type1_message() - * - * This is used to generate an NTLM type-1 message ready for sending to the - * recipient using the appropriate compile time crypto API. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The hostname. - * ntlm [in/out] - The NTLM data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - struct ntlmdata *ntlm, - struct bufref *out) -{ - /* NTLM type-1 message structure: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x01000000) - 12 Flags long - (16) Supplied Domain security buffer (*) - (24) Supplied Workstation security buffer (*) - (32) OS Version Structure 8 bytes (*) - (32) (40) Start of data block (*) - (*) -> Optional - */ - - size_t size; - - char *ntlmbuf; - const char *hostname = ""; /* empty */ - const char *domain = ""; /* empty */ - size_t hostlen = 0; - size_t domlen = 0; - size_t hostoff = 0; - size_t domoff = hostoff + hostlen; /* This is 0: remember that host and - domain are empty */ - (void)data; - (void)userp; - (void)passwdp; - (void)service; - (void)host; - - /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_cleanup_ntlm(ntlm); - - ntlmbuf = curl_maprintf(NTLMSSP_SIGNATURE "%c" - "\x01%c%c%c" /* 32-bit type = 1 */ - "%c%c%c%c" /* 32-bit NTLM flag field */ - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* hostname offset */ - "%c%c" /* 2 zeroes */ - "%s" /* hostname */ - "%s", /* domain string */ - 0, /* trailing zero */ - 0, 0, 0, /* part of type-1 long */ - - LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLMFLAG_NEGOTIATE_NTLM2_KEY | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0, 0, - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0, 0, - hostname, /* this is empty */ - domain /* this is empty */); - - if(!ntlmbuf) - return CURLE_OUT_OF_MEMORY; - - /* Initial packet length */ - size = 32 + hostlen + domlen; - - DEBUG_OUT({ - curl_mfprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x " - "0x%08.8x ", - LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLMFLAG_NEGOTIATE_NTLM2_KEY | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), - NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLMFLAG_NEGOTIATE_NTLM2_KEY | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); - ntlm_print_flags(stderr, - NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLMFLAG_NEGOTIATE_NTLM2_KEY | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); - curl_mfprintf(stderr, "\n****\n"); - }); - - Curl_bufref_set(out, ntlmbuf, size, curl_free); - return CURLE_OK; -} - -/* - * Curl_auth_create_ntlm_type3_message() - * - * This is used to generate an already encoded NTLM type-3 message ready for - * sending to the recipient using the appropriate compile time crypto API. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * ntlm [in/out] - The NTLM data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - struct bufref *out) -{ - /* NTLM type-3 message structure: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x03000000) - 12 LM/LMv2 Response security buffer - 20 NTLM/NTLMv2 Response security buffer - 28 Target Name security buffer - 36 username security buffer - 44 Workstation Name security buffer - (52) Session Key security buffer (*) - (60) Flags long (*) - (64) OS Version Structure 8 bytes (*) - 52 (64) (72) Start of data block - (*) -> Optional - */ - - CURLcode result = CURLE_OK; - size_t size; - unsigned char ntlmbuf[NTLM_BUFSIZE]; - unsigned int lmrespoff; - unsigned char lmresp[24]; /* fixed-size */ - unsigned int ntrespoff; - unsigned int ntresplen = 24; - unsigned char ntresp[24]; /* fixed-size */ - const unsigned char *ptr_ntresp = &ntresp[0]; - unsigned char *ntlmv2resp = NULL; - bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE); - /* The fixed hostname we provide, in order to not leak our real local host - name. Copy the name used by Firefox. */ - static const char host[] = "WORKSTATION"; - const char *user; - const char *domain = ""; - size_t hostoff = 0; - size_t useroff = 0; - size_t domoff = 0; - size_t hostlen = 0; - size_t userlen = 0; - size_t domlen = 0; - - memset(lmresp, 0, sizeof(lmresp)); - memset(ntresp, 0, sizeof(ntresp)); - user = strchr(userp, '\\'); - if(!user) - user = strchr(userp, '/'); - - if(user) { - domain = userp; - domlen = (user - domain); - user++; - } - else - user = userp; - - userlen = strlen(user); - hostlen = sizeof(host) - 1; - - if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { - unsigned char ntbuffer[0x18]; - unsigned char entropy[8]; - unsigned char ntlmv2hash[0x18]; - - /* Full NTLM version 2 - Although this cannot be negotiated, it is used here if available, as - servers featuring extended security are likely supporting also - NTLMv2. */ - result = Curl_rand(data, entropy, 8); - if(result) - return result; - - result = Curl_ntlm_core_mk_nt_hash(passwdp, ntbuffer); - if(result) - return result; - - result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen, - ntbuffer, ntlmv2hash); - if(result) - return result; - - /* LMv2 response */ - result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy, - &ntlm->nonce[0], lmresp); - if(result) - return result; - - /* NTLMv2 response */ - result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy, - ntlm, &ntlmv2resp, &ntresplen); - if(result) - return result; - - ptr_ntresp = ntlmv2resp; - } - else { - - unsigned char ntbuffer[0x18]; - unsigned char lmbuffer[0x18]; - - /* NTLM version 1 */ - - result = Curl_ntlm_core_mk_nt_hash(passwdp, ntbuffer); - if(result) - return result; - - Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp); - - result = Curl_ntlm_core_mk_lm_hash(passwdp, lmbuffer); - if(result) - return result; - - Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp); - ntlm->flags &= ~(unsigned int)NTLMFLAG_NEGOTIATE_NTLM2_KEY; - - /* A safer but less compatible alternative is: - * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp); - * See https://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */ - } - - if(unicode) { - domlen = domlen * 2; - userlen = userlen * 2; - hostlen = hostlen * 2; - } - - lmrespoff = 64; /* size of the message header */ - ntrespoff = lmrespoff + 0x18; - domoff = ntrespoff + ntresplen; - useroff = domoff + domlen; - hostoff = useroff + userlen; - - /* Create the big type-3 message binary blob */ - size = curl_msnprintf((char *)ntlmbuf, NTLM_BUFSIZE, - NTLMSSP_SIGNATURE "%c" - "\x03%c%c%c" /* 32-bit type = 3 */ - - "%c%c" /* LanManager length */ - "%c%c" /* LanManager allocated space */ - "%c%c" /* LanManager offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* NT-response length */ - "%c%c" /* NT-response allocated space */ - "%c%c" /* NT-response offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* user length */ - "%c%c" /* user allocated space */ - "%c%c" /* user offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* session key length (unknown purpose) */ - "%c%c" /* session key allocated space - (unknown purpose) */ - "%c%c" /* session key offset (unknown purpose) */ - "%c%c" /* 2 zeroes */ - - "%c%c%c%c", /* flags */ - - /* domain string */ - /* user string */ - /* host string */ - /* LanManager response */ - /* NT response */ - - 0, /* null-termination */ - 0, 0, 0, /* type-3 long, the 24 upper bits */ - - SHORTPAIR(0x18), /* LanManager response length, - twice */ - SHORTPAIR(0x18), - SHORTPAIR(lmrespoff), - 0x0, 0x0, - - SHORTPAIR(ntresplen), /* NT-response length, twice */ - SHORTPAIR(ntresplen), - SHORTPAIR(ntrespoff), - 0x0, 0x0, - - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0x0, 0x0, - - SHORTPAIR(userlen), - SHORTPAIR(userlen), - SHORTPAIR(useroff), - 0x0, 0x0, - - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0x0, 0x0, - - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - - LONGQUARTET(ntlm->flags)); - - DEBUGASSERT(size == 64); - DEBUGASSERT(size == (size_t)lmrespoff); - - /* We append the binary hashes */ - if(size < (NTLM_BUFSIZE - 0x18)) { - memcpy(&ntlmbuf[size], lmresp, 0x18); - size += 0x18; - } - - DEBUG_OUT({ - curl_mfprintf(stderr, "**** TYPE3 header lmresp="); - ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18); - }); - - /* ntresplen + size should not be risking an integer overflow here */ - if(ntresplen + size > sizeof(ntlmbuf)) { - failf(data, "incoming NTLM message too big"); - result = CURLE_TOO_LARGE; - goto error; - } - DEBUGASSERT(size == (size_t)ntrespoff); - memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); - size += ntresplen; - - DEBUG_OUT({ - curl_mfprintf(stderr, "\n ntresp="); - ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen); - }); - - DEBUG_OUT({ - curl_mfprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ", - LONGQUARTET(ntlm->flags), ntlm->flags); - ntlm_print_flags(stderr, ntlm->flags); - curl_mfprintf(stderr, "\n****\n"); - }); - - /* Make sure that the domain, user and host strings fit in the - buffer before we copy them there. */ - if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) { - failf(data, "user + domain + hostname too big for NTLM"); - result = CURLE_TOO_LARGE; - goto error; - } - - DEBUGASSERT(size == domoff); - if(unicode) - unicodecpy(&ntlmbuf[size], domain, domlen / 2); - else - memcpy(&ntlmbuf[size], domain, domlen); - - size += domlen; - - DEBUGASSERT(size == useroff); - if(unicode) - unicodecpy(&ntlmbuf[size], user, userlen / 2); - else - memcpy(&ntlmbuf[size], user, userlen); - - size += userlen; - - DEBUGASSERT(size == hostoff); - if(unicode) - unicodecpy(&ntlmbuf[size], host, hostlen / 2); - else - memcpy(&ntlmbuf[size], host, hostlen); - - size += hostlen; - - /* Return the binary blob. */ - result = Curl_bufref_memdup0(out, ntlmbuf, size); - -error: - curlx_free(ntlmv2resp); /* Free the dynamic buffer allocated for NTLMv2 */ - - Curl_auth_cleanup_ntlm(ntlm); - - return result; -} - -/* - * Curl_auth_cleanup_ntlm() - * - * This is used to clean up the NTLM specific data. - * - * Parameters: - * - * ntlm [in/out] - The NTLM data struct being cleaned up. - * - */ -void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) -{ - /* Free the target info */ - curlx_safefree(ntlm->target_info); - - /* Reset any variables */ - ntlm->target_info_len = 0; -} - -#endif /* USE_NTLM && !USE_WINDOWS_SSPI */ diff --git a/vendor/curl/lib/vauth/ntlm_sspi.c b/vendor/curl/lib/vauth/ntlm_sspi.c deleted file mode 100644 index 4c41eb21f..000000000 --- a/vendor/curl/lib/vauth/ntlm_sspi.c +++ /dev/null @@ -1,353 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && defined(USE_NTLM) - -#include "vauth/vauth.h" -#include "curl_ntlm_core.h" -#include "curl_trc.h" -#include "curlx/strdup.h" - -/* - * Curl_auth_is_ntlm_supported() - * - * This is used to evaluate if NTLM is supported. - * - * Parameters: None - * - * Returns TRUE if NTLM is supported by Windows SSPI. - */ -bool Curl_auth_is_ntlm_supported(void) -{ - PSecPkgInfo SecurityPackage; - SECURITY_STATUS status; - - /* Query the security package for NTLM */ - status = Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_NTLM)), - &SecurityPackage); - - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - } - - return status == SEC_E_OK; -} - -/* - * Curl_auth_create_ntlm_type1_message() - * - * This is used to generate an already encoded NTLM type-1 message ready for - * sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The hostname. - * ntlm [in/out] - The NTLM data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - struct ntlmdata *ntlm, - struct bufref *out) -{ - PSecPkgInfo SecurityPackage; - SecBuffer type_1_buf; - SecBufferDesc type_1_desc; - SECURITY_STATUS status; - unsigned long attrs; - - /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_cleanup_ntlm(ntlm); - - /* Query the security package for NTLM */ - status = Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_NTLM)), - &SecurityPackage); - if(status != SEC_E_OK) { - failf(data, "SSPI: could not get auth info"); - return CURLE_AUTH_ERROR; - } - - ntlm->token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our output buffer */ - ntlm->output_token = curlx_malloc(ntlm->token_max); - if(!ntlm->output_token) - return CURLE_OUT_OF_MEMORY; - - if(userp && *userp) { - CURLcode result; - - /* Populate our identity structure */ - result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity); - if(result) - return result; - - /* Allow proper cleanup of the identity structure */ - ntlm->p_identity = &ntlm->identity; - } - else - /* Use the current Windows user */ - ntlm->p_identity = NULL; - - /* Allocate our credentials handle */ - ntlm->credentials = curlx_calloc(1, sizeof(CredHandle)); - if(!ntlm->credentials) - return CURLE_OUT_OF_MEMORY; - - /* Acquire our credentials handle */ - status = Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_NTLM)), - SECPKG_CRED_OUTBOUND, NULL, - ntlm->p_identity, NULL, NULL, - ntlm->credentials, NULL); - if(status != SEC_E_OK) - return CURLE_LOGIN_DENIED; - - /* Allocate our new context handle */ - ntlm->context = curlx_calloc(1, sizeof(CtxtHandle)); - if(!ntlm->context) - return CURLE_OUT_OF_MEMORY; - - ntlm->spn = Curl_auth_build_spn(service, host, NULL); - if(!ntlm->spn) - return CURLE_OUT_OF_MEMORY; - - /* Setup the type-1 "output" security buffer */ - type_1_desc.ulVersion = SECBUFFER_VERSION; - type_1_desc.cBuffers = 1; - type_1_desc.pBuffers = &type_1_buf; - type_1_buf.BufferType = SECBUFFER_TOKEN; - type_1_buf.pvBuffer = ntlm->output_token; - type_1_buf.cbBuffer = curlx_uztoul(ntlm->token_max); - - /* Generate our type-1 message */ - status = Curl_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL, - ntlm->spn, - 0, 0, SECURITY_NETWORK_DREP, - NULL, 0, - ntlm->context, &type_1_desc, - &attrs, NULL); - if(status == SEC_I_COMPLETE_NEEDED || - status == SEC_I_COMPLETE_AND_CONTINUE) - Curl_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc); - else if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) - return CURLE_AUTH_ERROR; - - /* Return the response. */ - Curl_bufref_set(out, ntlm->output_token, type_1_buf.cbBuffer, NULL); - return CURLE_OK; -} - -/* - * Curl_auth_decode_ntlm_type2_message() - * - * This is used to decode an already encoded NTLM type-2 message. - * - * Parameters: - * - * data [in] - The session handle. - * type2 [in] - The type-2 message. - * ntlm [in/out] - The NTLM data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, - const struct bufref *type2ref, - struct ntlmdata *ntlm) -{ - /* Ensure we have a valid type-2 message */ - if(!Curl_bufref_len(type2ref)) { - infof(data, "NTLM handshake failure (empty type-2 message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Store the challenge for later use */ - ntlm->input_token = curlx_memdup0(Curl_bufref_ptr(type2ref), - Curl_bufref_len(type2ref)); - if(!ntlm->input_token) - return CURLE_OUT_OF_MEMORY; - ntlm->input_token_len = Curl_bufref_len(type2ref); - - return CURLE_OK; -} - -/* - * Curl_auth_create_ntlm_type3_message() - * - * This is used to generate an already encoded NTLM type-3 message ready for - * sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * ntlm [in/out] - The NTLM data struct being used and modified. - * out [out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - struct bufref *out) -{ - CURLcode result = CURLE_OK; - SecBuffer type_2_bufs[2]; - SecBuffer type_3_buf; - SecBufferDesc type_2_desc; - SecBufferDesc type_3_desc; - SECURITY_STATUS status; - unsigned long attrs; - - (void)passwdp; - (void)userp; - - /* Setup the type-2 "input" security buffer */ - type_2_desc.ulVersion = SECBUFFER_VERSION; - type_2_desc.cBuffers = 1; - type_2_desc.pBuffers = &type_2_bufs[0]; - type_2_bufs[0].BufferType = SECBUFFER_TOKEN; - type_2_bufs[0].pvBuffer = ntlm->input_token; - type_2_bufs[0].cbBuffer = curlx_uztoul(ntlm->input_token_len); - -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - /* ssl context comes from schannel. - * When extended protection is used in IIS server, - * we have to pass a second SecBuffer to the SecBufferDesc - * otherwise IIS does not pass the authentication (401 response). - * Minimum supported version is Windows 7. - * https://learn.microsoft.com/security-updates/SecurityAdvisories/2009/973811 - */ - if(ntlm->sslContext) { - SEC_CHANNEL_BINDINGS channelBindings; - SecPkgContext_Bindings pkgBindings; - pkgBindings.Bindings = &channelBindings; - status = Curl_pSecFn->QueryContextAttributes( - ntlm->sslContext, - SECPKG_ATTR_ENDPOINT_BINDINGS, - &pkgBindings - ); - if(status == SEC_E_OK) { - type_2_desc.cBuffers++; - type_2_bufs[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; - type_2_bufs[1].cbBuffer = pkgBindings.BindingsLength; - type_2_bufs[1].pvBuffer = pkgBindings.Bindings; - } - } -#endif - - /* Setup the type-3 "output" security buffer */ - type_3_desc.ulVersion = SECBUFFER_VERSION; - type_3_desc.cBuffers = 1; - type_3_desc.pBuffers = &type_3_buf; - type_3_buf.BufferType = SECBUFFER_TOKEN; - type_3_buf.pvBuffer = ntlm->output_token; - type_3_buf.cbBuffer = curlx_uztoul(ntlm->token_max); - - /* Generate our type-3 message */ - status = Curl_pSecFn->InitializeSecurityContext(ntlm->credentials, - ntlm->context, - ntlm->spn, - 0, 0, SECURITY_NETWORK_DREP, - &type_2_desc, - 0, ntlm->context, - &type_3_desc, - &attrs, NULL); - if(status != SEC_E_OK) { - infof(data, "NTLM handshake failure (type-3 message): Status=0x%08lx", - status); - - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; - } - - /* Return the response. */ - result = Curl_bufref_memdup0(out, ntlm->output_token, type_3_buf.cbBuffer); - Curl_auth_cleanup_ntlm(ntlm); - return result; -} - -/* - * Curl_auth_cleanup_ntlm() - * - * This is used to clean up the NTLM specific data. - * - * Parameters: - * - * ntlm [in/out] - The NTLM data struct being cleaned up. - * - */ -void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) -{ - /* Free our security context */ - if(ntlm->context) { - Curl_pSecFn->DeleteSecurityContext(ntlm->context); - curlx_free(ntlm->context); - ntlm->context = NULL; - } - - /* Free our credentials handle */ - if(ntlm->credentials) { - Curl_pSecFn->FreeCredentialsHandle(ntlm->credentials); - curlx_free(ntlm->credentials); - ntlm->credentials = NULL; - } - - /* Free our identity */ - Curl_sspi_free_identity(ntlm->p_identity); - ntlm->p_identity = NULL; - - /* Free the input and output tokens */ - curlx_safefree(ntlm->input_token); - curlx_safefree(ntlm->output_token); - - /* Reset any variables */ - ntlm->token_max = 0; - - curlx_safefree(ntlm->spn); -} - -#endif /* USE_WINDOWS_SSPI && USE_NTLM */ diff --git a/vendor/curl/lib/vauth/oauth2.c b/vendor/curl/lib/vauth/oauth2.c deleted file mode 100644 index 4541d1d55..000000000 --- a/vendor/curl/lib/vauth/oauth2.c +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC6749 OAuth 2.0 Authorization Framework - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ - !defined(CURL_DISABLE_POP3) || \ - (!defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)) - -#include "vauth/vauth.h" - -/* - * Curl_auth_create_oauth_bearer_message() - * - * This is used to generate an OAuth 2.0 message ready for sending to the - * recipient. - * - * Parameters: - * - * user[in] - The username. - * host[in] - The hostname. - * port[in] - The port(when not Port 80). - * bearer[in] - The bearer token. - * out[out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_oauth_bearer_message(const char *user, - const char *host, - const long port, - const char *bearer, - struct bufref *out) -{ - char *oauth; - - /* Generate the message */ - if(port == 0 || port == 80) - oauth = curl_maprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host, - bearer); - else - oauth = curl_maprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1", - user, host, port, bearer); - if(!oauth) - return CURLE_OUT_OF_MEMORY; - - Curl_bufref_set(out, oauth, strlen(oauth), curl_free); - return CURLE_OK; -} - -/* - * Curl_auth_create_xoauth_bearer_message() - * - * This is used to generate a XOAuth 2.0 message ready for * sending to the - * recipient. - * - * Parameters: - * - * user[in] - The username. - * bearer[in] - The bearer token. - * out[out] - The result storage. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_xoauth_bearer_message(const char *user, - const char *bearer, - struct bufref *out) -{ - /* Generate the message */ - char *xoauth = curl_maprintf("user=%s\1auth=Bearer %s\1\1", user, bearer); - if(!xoauth) - return CURLE_OUT_OF_MEMORY; - - Curl_bufref_set(out, xoauth, strlen(xoauth), curl_free); - return CURLE_OK; -} -#endif /* disabled, no users */ diff --git a/vendor/curl/lib/vauth/spnego_gssapi.c b/vendor/curl/lib/vauth/spnego_gssapi.c deleted file mode 100644 index 38bb4c142..000000000 --- a/vendor/curl/lib/vauth/spnego_gssapi.c +++ /dev/null @@ -1,295 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC4178 Simple and Protected GSS-API Negotiation Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(HAVE_GSSAPI) && defined(USE_SPNEGO) - -#include "vauth/vauth.h" -#include "curlx/base64.h" -#include "curl_gssapi.h" -#include "curl_trc.h" - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -/* - * Curl_auth_is_spnego_supported() - * - * This is used to evaluate if SPNEGO (Negotiate) is supported. - * - * Parameters: None - * - * Returns TRUE if Negotiate supported by the GSS-API library. - */ -bool Curl_auth_is_spnego_supported(void) -{ - return TRUE; -} - -/* - * Curl_auth_decode_spnego_message() - * - * This is used to decode an already encoded SPNEGO (Negotiate) challenge - * message. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The username in the format User or Domain\User. - * passwdp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The hostname. - * chlg64 [in] - The optional base64 encoded challenge message. - * nego [in/out] - The Negotiate data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, - const char *user, - const char *password, - const char *service, - const char *host, - const char *chlg64, - struct negotiatedata *nego) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; - OM_uint32 major_status; - OM_uint32 minor_status; - OM_uint32 unused_status; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - gss_channel_bindings_t chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; -#ifdef GSS_C_CHANNEL_BOUND_FLAG - struct gss_channel_bindings_struct chan; -#endif - - (void)user; - (void)password; - - if(nego->context && nego->status == GSS_S_COMPLETE) { - /* We finished successfully our part of authentication, but server - * rejected it (since we are again here). Exit with an error since we - * cannot invent anything better */ - Curl_auth_cleanup_spnego(nego); - return CURLE_LOGIN_DENIED; - } - - if(!nego->spn) { - gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; - - /* Generate our SPN */ - char *spn = Curl_auth_build_spn(service, NULL, host); - if(!spn) - return CURLE_OUT_OF_MEMORY; - - /* Populate the SPN structure */ - spn_token.value = spn; - spn_token.length = strlen(spn); - - /* Import the SPN */ - major_status = gss_import_name(&minor_status, &spn_token, - GSS_C_NT_HOSTBASED_SERVICE, - &nego->spn); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_import_name() failed: ", - major_status, minor_status); - - curlx_free(spn); - - return CURLE_AUTH_ERROR; - } - - curlx_free(spn); - } - - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = curlx_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "SPNEGO handshake failure (empty challenge message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - input_token.value = chlg; - input_token.length = chlglen; - } - - /* Set channel binding data if available */ -#ifdef GSS_C_CHANNEL_BOUND_FLAG - if(curlx_dyn_len(&nego->channel_binding_data)) { - memset(&chan, 0, sizeof(struct gss_channel_bindings_struct)); - chan.application_data.length = curlx_dyn_len(&nego->channel_binding_data); - chan.application_data.value = curlx_dyn_ptr(&nego->channel_binding_data); - chan_bindings = &chan; - } -#endif - - /* Generate our challenge-response message */ - major_status = Curl_gss_init_sec_context(data, - &minor_status, - &nego->context, - nego->spn, - &Curl_spnego_mech_oid, - chan_bindings, - &input_token, - &output_token, - TRUE, - NULL); - - /* Free the decoded challenge as it is not required anymore */ - curlx_safefree(input_token.value); - - nego->status = major_status; - if(GSS_ERROR(major_status)) { - if(output_token.value) - gss_release_buffer(&unused_status, &output_token); - - Curl_gss_log_error(data, "gss_init_sec_context() failed: ", - major_status, minor_status); - - return CURLE_AUTH_ERROR; - } - - if(!output_token.value || !output_token.length) { - if(output_token.value) - gss_release_buffer(&unused_status, &output_token); - - return CURLE_AUTH_ERROR; - } - - /* Free previous token */ - if(nego->output_token.length && nego->output_token.value) - gss_release_buffer(&unused_status, &nego->output_token); - - nego->output_token = output_token; - - return CURLE_OK; -} - -/* - * Curl_auth_create_spnego_message() - * - * This is used to generate an already encoded SPNEGO (Negotiate) response - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * nego [in/out] - The Negotiate data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result is stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_spnego_message(struct negotiatedata *nego, - char **outptr, size_t *outlen) -{ - CURLcode result; - OM_uint32 minor_status; - - /* Base64 encode the already generated response */ - result = curlx_base64_encode(nego->output_token.value, - nego->output_token.length, - outptr, outlen); - - if(result) { - gss_release_buffer(&minor_status, &nego->output_token); - nego->output_token.value = NULL; - nego->output_token.length = 0; - - return result; - } - - if(!*outptr || !*outlen) { - gss_release_buffer(&minor_status, &nego->output_token); - nego->output_token.value = NULL; - nego->output_token.length = 0; - - return CURLE_REMOTE_ACCESS_DENIED; - } - - return CURLE_OK; -} - -/* - * Curl_auth_cleanup_spnego() - * - * This is used to clean up the SPNEGO (Negotiate) specific data. - * - * Parameters: - * - * nego [in/out] - The Negotiate data struct being cleaned up. - * - */ -void Curl_auth_cleanup_spnego(struct negotiatedata *nego) -{ - OM_uint32 minor_status; - - /* Free our security context */ - if(nego->context != GSS_C_NO_CONTEXT) { - Curl_gss_delete_sec_context(&minor_status, &nego->context, - GSS_C_NO_BUFFER); - nego->context = GSS_C_NO_CONTEXT; - } - - /* Free the output token */ - if(nego->output_token.value) { - gss_release_buffer(&minor_status, &nego->output_token); - nego->output_token.value = NULL; - nego->output_token.length = 0; - } - - /* Free the SPN */ - if(nego->spn != GSS_C_NO_NAME) { - gss_release_name(&minor_status, &nego->spn); - nego->spn = GSS_C_NO_NAME; - } - - /* Reset any variables */ - nego->status = 0; - nego->noauthpersist = FALSE; - nego->havenoauthpersist = FALSE; - nego->havenegdata = FALSE; - nego->havemultiplerequests = FALSE; -} - -#if defined(CURL_HAVE_DIAG) && defined(__APPLE__) -#pragma GCC diagnostic pop -#endif - -#endif /* HAVE_GSSAPI && USE_SPNEGO */ diff --git a/vendor/curl/lib/vauth/spnego_sspi.c b/vendor/curl/lib/vauth/spnego_sspi.c deleted file mode 100644 index 1baf59320..000000000 --- a/vendor/curl/lib/vauth/spnego_sspi.c +++ /dev/null @@ -1,344 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - * RFC4178 Simple and Protected GSS-API Negotiation Mechanism - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && defined(USE_SPNEGO) - -#include "vauth/vauth.h" -#include "curlx/base64.h" -#include "curl_trc.h" -#include "strerror.h" - -/* - * Curl_auth_is_spnego_supported() - * - * This is used to evaluate if SPNEGO (Negotiate) is supported. - * - * Parameters: None - * - * Returns TRUE if Negotiate is supported by Windows SSPI. - */ -bool Curl_auth_is_spnego_supported(void) -{ - PSecPkgInfo SecurityPackage; - SECURITY_STATUS status; - - /* Query the security package for Negotiate */ - status = Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_NEGOTIATE)), - &SecurityPackage); - - /* Release the package buffer as it is not required anymore */ - if(status == SEC_E_OK) { - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - } - - return status == SEC_E_OK; -} - -/* - * Curl_auth_decode_spnego_message() - * - * This is used to decode an already encoded SPNEGO (Negotiate) challenge - * message. - * - * Parameters: - * - * data [in] - The session handle. - * user [in] - The username in the format User or Domain\User. - * password [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The hostname. - * chlg64 [in] - The optional base64 encoded challenge message. - * nego [in/out] - The Negotiate data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, - const char *user, - const char *password, - const char *service, - const char *host, - const char *chlg64, - struct negotiatedata *nego) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; - PSecPkgInfo SecurityPackage; - SecBuffer chlg_buf[2]; - SecBuffer resp_buf; - SecBufferDesc chlg_desc; - SecBufferDesc resp_desc; - unsigned long attrs; - - if(nego->context && nego->status == SEC_E_OK) { - /* We finished successfully our part of authentication, but server - * rejected it (since we are again here). Exit with an error since we - * cannot invent anything better */ - Curl_auth_cleanup_spnego(nego); - return CURLE_LOGIN_DENIED; - } - - if(!nego->spn) { - /* Generate our SPN */ - nego->spn = Curl_auth_build_spn(service, host, NULL); - if(!nego->spn) - return CURLE_OUT_OF_MEMORY; - } - - if(!nego->output_token) { - /* Query the security package for Negotiate */ - nego->status = Curl_pSecFn->QuerySecurityPackageInfo( - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_NEGOTIATE)), - &SecurityPackage); - if(nego->status != SEC_E_OK) { - failf(data, "SSPI: could not get auth info"); - return CURLE_AUTH_ERROR; - } - - nego->token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - Curl_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our output buffer */ - nego->output_token = curlx_malloc(nego->token_max); - if(!nego->output_token) - return CURLE_OUT_OF_MEMORY; - } - - if(!nego->credentials) { - /* Do we have credentials to use or are we using single sign-on? */ - if(user && *user) { - /* Populate our identity structure */ - result = Curl_create_sspi_identity(user, password, &nego->identity); - if(result) - return result; - - /* Allow proper cleanup of the identity structure */ - nego->p_identity = &nego->identity; - } - else - /* Use the current Windows user */ - nego->p_identity = NULL; - - /* Allocate our credentials handle */ - nego->credentials = curlx_calloc(1, sizeof(CredHandle)); - if(!nego->credentials) - return CURLE_OUT_OF_MEMORY; - - /* Acquire our credentials handle */ - nego->status = Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(TEXT(SP_NAME_NEGOTIATE)), - SECPKG_CRED_OUTBOUND, NULL, - nego->p_identity, NULL, NULL, - nego->credentials, NULL); - if(nego->status != SEC_E_OK) - return CURLE_AUTH_ERROR; - - /* Allocate our new context handle */ - nego->context = curlx_calloc(1, sizeof(CtxtHandle)); - if(!nego->context) - return CURLE_OUT_OF_MEMORY; - } - - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = curlx_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "SPNEGO handshake failure (empty challenge message)"); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 1; - chlg_desc.pBuffers = &chlg_buf[0]; - chlg_buf[0].BufferType = SECBUFFER_TOKEN; - chlg_buf[0].pvBuffer = chlg; - chlg_buf[0].cbBuffer = curlx_uztoul(chlglen); - -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - /* ssl context comes from Schannel. - * When extended protection is used in IIS server, - * we have to pass a second SecBuffer to the SecBufferDesc - * otherwise IIS does not pass the authentication (401 response). - * Minimum supported version is Windows 7. - * https://learn.microsoft.com/security-updates/SecurityAdvisories/2009/973811 - */ - if(nego->sslContext) { - SEC_CHANNEL_BINDINGS channelBindings; - SecPkgContext_Bindings pkgBindings; - pkgBindings.Bindings = &channelBindings; - nego->status = Curl_pSecFn->QueryContextAttributes( - nego->sslContext, - SECPKG_ATTR_ENDPOINT_BINDINGS, - &pkgBindings); - if(nego->status == SEC_E_OK) { - chlg_desc.cBuffers++; - chlg_buf[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; - chlg_buf[1].cbBuffer = pkgBindings.BindingsLength; - chlg_buf[1].pvBuffer = pkgBindings.Bindings; - } - } -#endif - } - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = nego->output_token; - resp_buf.cbBuffer = curlx_uztoul(nego->token_max); - - /* Generate our challenge-response message */ - nego->status = - Curl_pSecFn->InitializeSecurityContext(nego->credentials, - chlg ? nego->context : NULL, - nego->spn, - ISC_REQ_CONFIDENTIALITY, - 0, SECURITY_NATIVE_DREP, - chlg ? &chlg_desc : NULL, - 0, nego->context, - &resp_desc, &attrs, NULL); - - /* Free the decoded challenge as it is not required anymore */ - curlx_free(chlg); - - if(GSS_ERROR(nego->status)) { - char buffer[STRERROR_LEN]; - failf(data, "InitializeSecurityContext failed: %s", - Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); - - if(nego->status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; - } - - if(nego->status == SEC_I_COMPLETE_NEEDED || - nego->status == SEC_I_COMPLETE_AND_CONTINUE) { - nego->status = Curl_pSecFn->CompleteAuthToken(nego->context, &resp_desc); - if(GSS_ERROR(nego->status)) { - char buffer[STRERROR_LEN]; - failf(data, "CompleteAuthToken failed: %s", - Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); - - if(nego->status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - return CURLE_AUTH_ERROR; - } - } - - nego->output_token_length = resp_buf.cbBuffer; - - return result; -} - -/* - * Curl_auth_create_spnego_message() - * - * This is used to generate an already encoded SPNEGO (Negotiate) response - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * nego [in/out] - The Negotiate data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result is stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_spnego_message(struct negotiatedata *nego, - char **outptr, size_t *outlen) -{ - /* Base64 encode the already generated response */ - CURLcode result = curlx_base64_encode(nego->output_token, - nego->output_token_length, outptr, - outlen); - if(!result && (!*outptr || !*outlen)) { - curlx_free(*outptr); - result = CURLE_REMOTE_ACCESS_DENIED; - } - - return result; -} - -/* - * Curl_auth_cleanup_spnego() - * - * This is used to clean up the SPNEGO (Negotiate) specific data. - * - * Parameters: - * - * nego [in/out] - The Negotiate data struct being cleaned up. - * - */ -void Curl_auth_cleanup_spnego(struct negotiatedata *nego) -{ - /* Free our security context */ - if(nego->context) { - Curl_pSecFn->DeleteSecurityContext(nego->context); - curlx_free(nego->context); - nego->context = NULL; - } - - /* Free our credentials handle */ - if(nego->credentials) { - Curl_pSecFn->FreeCredentialsHandle(nego->credentials); - curlx_free(nego->credentials); - nego->credentials = NULL; - } - - /* Free our identity */ - Curl_sspi_free_identity(nego->p_identity); - nego->p_identity = NULL; - - /* Free the SPN and output token */ - curlx_safefree(nego->spn); - curlx_safefree(nego->output_token); - - /* Reset any variables */ - nego->status = 0; - nego->token_max = 0; - nego->noauthpersist = FALSE; - nego->havenoauthpersist = FALSE; - nego->havenegdata = FALSE; - nego->havemultiplerequests = FALSE; -} - -#endif /* USE_WINDOWS_SSPI && USE_SPNEGO */ diff --git a/vendor/curl/lib/vauth/vauth.c b/vendor/curl/lib/vauth/vauth.c deleted file mode 100644 index a00078fce..000000000 --- a/vendor/curl/lib/vauth/vauth.c +++ /dev/null @@ -1,249 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "vauth/vauth.h" -#include "curlx/multibyte.h" -#include "url.h" - -/* - * Curl_auth_build_spn() - * - * This is used to build an SPN string in the following formats: - * - * service/host@realm (Not currently used) - * service/host (Not used by GSS-API) - * service@realm (Not used by Windows SSPI) - * - * Parameters: - * - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The hostname. - * realm [in] - The realm. - * - * Returns a pointer to the newly allocated SPN. - */ -#ifndef USE_WINDOWS_SSPI -char *Curl_auth_build_spn(const char *service, const char *host, - const char *realm) -{ - char *spn = NULL; - - /* Generate our SPN */ - if(host && realm) - spn = curl_maprintf("%s/%s@%s", service, host, realm); - else if(host) - spn = curl_maprintf("%s/%s", service, host); - else if(realm) - spn = curl_maprintf("%s@%s", service, realm); - - /* Return our newly allocated SPN */ - return spn; -} -#else -TCHAR *Curl_auth_build_spn(const char *service, const char *host, - const char *realm) -{ - char *utf8_spn = NULL; - TCHAR *tchar_spn = NULL; - - (void)realm; - - /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather - than doing this ourselves but the first is only available in Windows XP - and Windows Server 2003 and the latter is only available in Windows 2000 - but not Windows95/98/ME or Windows NT4.0 unless the Active Directory - Client Extensions are installed. As such it is far simpler for us to - formulate the SPN instead. */ - - /* Generate our UTF8 based SPN */ - utf8_spn = curl_maprintf("%s/%s", service, host); - if(!utf8_spn) - return NULL; - - /* Allocate and return a TCHAR based SPN. */ - tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn); - curlx_free(utf8_spn); - - return tchar_spn; -} -#endif /* USE_WINDOWS_SSPI */ - -/* - * Curl_auth_user_contains_domain() - * - * This is used to test if the specified user contains a Windows domain name as - * follows: - * - * Domain\User (Down-level Logon Name) - * Domain/User (curl Down-level format - for compatibility with existing code) - * User@Domain (User Principal Name) - * - * Note: The username may be empty when using a GSS-API library or Windows - * SSPI as the user and domain are either obtained from the credentials cache - * when using GSS-API or via the currently logged in user's credentials when - * using Windows SSPI. - * - * Parameters: - * - * user [in] - The username. - * - * Returns TRUE on success; otherwise FALSE. - */ -bool Curl_auth_user_contains_domain(const char *user) -{ - bool valid = FALSE; - - if(user && *user) { - /* Check we have a domain name or UPN present */ - const char *p = strpbrk(user, "\\/@"); - - valid = (p != NULL && p > user && p < user + strlen(user) - 1); - } -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - else - /* User and domain are obtained from the GSS-API credentials cache or the - currently logged in user from Windows */ - valid = TRUE; -#endif - - return valid; -} - -/* - * Curl_auth_allowed_to_host() tells if authentication, cookies or other - * "sensitive data" can (still) be sent to this host. - */ -bool Curl_auth_allowed_to_host(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - return !data->state.this_is_a_follow || - data->set.allow_auth_to_other_hosts || - (data->state.first_host && - curl_strequal(data->state.first_host, conn->host.name) && - (data->state.first_remote_port == conn->remote_port) && - (data->state.first_remote_protocol == conn->scheme->protocol)); -} - -#ifdef USE_NTLM -static void ntlm_conn_dtor(void *key, size_t klen, void *entry) -{ - struct ntlmdata *ntlm = entry; - (void)key; - (void)klen; - DEBUGASSERT(ntlm); - Curl_auth_cleanup_ntlm(ntlm); - curlx_free(ntlm); -} - -struct ntlmdata *Curl_auth_ntlm_get(struct connectdata *conn, bool proxy) -{ - const char *key = proxy ? CURL_META_NTLM_PROXY_CONN : CURL_META_NTLM_CONN; - struct ntlmdata *ntlm = Curl_conn_meta_get(conn, key); - if(!ntlm) { - ntlm = curlx_calloc(1, sizeof(*ntlm)); - if(!ntlm || Curl_conn_meta_set(conn, key, ntlm, ntlm_conn_dtor)) - return NULL; - } - return ntlm; -} - -void Curl_auth_ntlm_remove(struct connectdata *conn, bool proxy) -{ - Curl_conn_meta_remove(conn, proxy ? CURL_META_NTLM_PROXY_CONN - : CURL_META_NTLM_CONN); -} -#endif /* USE_NTLM */ - -#ifdef USE_KERBEROS5 -static void krb5_conn_dtor(void *key, size_t klen, void *entry) -{ - struct kerberos5data *krb5 = entry; - (void)key; - (void)klen; - DEBUGASSERT(krb5); - Curl_auth_cleanup_gssapi(krb5); - curlx_free(krb5); -} - -struct kerberos5data *Curl_auth_krb5_get(struct connectdata *conn) -{ - struct kerberos5data *krb5 = Curl_conn_meta_get(conn, CURL_META_KRB5_CONN); - if(!krb5) { - krb5 = curlx_calloc(1, sizeof(*krb5)); - if(!krb5 || - Curl_conn_meta_set(conn, CURL_META_KRB5_CONN, krb5, krb5_conn_dtor)) - return NULL; - } - return krb5; -} -#endif /* USE_KERBEROS5 */ - -#ifdef USE_GSASL -static void gsasl_conn_dtor(void *key, size_t klen, void *entry) -{ - struct gsasldata *gsasl = entry; - (void)key; - (void)klen; - DEBUGASSERT(gsasl); - Curl_auth_gsasl_cleanup(gsasl); - curlx_free(gsasl); -} - -struct gsasldata *Curl_auth_gsasl_get(struct connectdata *conn) -{ - struct gsasldata *gsasl = Curl_conn_meta_get(conn, CURL_META_GSASL_CONN); - if(!gsasl) { - gsasl = curlx_calloc(1, sizeof(*gsasl)); - if(!gsasl || - Curl_conn_meta_set(conn, CURL_META_GSASL_CONN, gsasl, gsasl_conn_dtor)) - return NULL; - } - return gsasl; -} -#endif /* USE_GSASL */ - -#ifdef USE_SPNEGO -static void nego_conn_dtor(void *key, size_t klen, void *entry) -{ - struct negotiatedata *nego = entry; - (void)key; - (void)klen; - DEBUGASSERT(nego); - Curl_auth_cleanup_spnego(nego); - curlx_free(nego); -} - -struct negotiatedata *Curl_auth_nego_get(struct connectdata *conn, bool proxy) -{ - const char *key = proxy ? CURL_META_NEGO_PROXY_CONN : CURL_META_NEGO_CONN; - struct negotiatedata *nego = Curl_conn_meta_get(conn, key); - if(!nego) { - nego = curlx_calloc(1, sizeof(*nego)); - if(!nego || Curl_conn_meta_set(conn, key, nego, nego_conn_dtor)) - return NULL; - } - return nego; -} -#endif /* USE_SPNEGO */ diff --git a/vendor/curl/lib/vauth/vauth.h b/vendor/curl/lib/vauth/vauth.h deleted file mode 100644 index 279da60be..000000000 --- a/vendor/curl/lib/vauth/vauth.h +++ /dev/null @@ -1,350 +0,0 @@ -#ifndef HEADER_CURL_VAUTH_H -#define HEADER_CURL_VAUTH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "bufref.h" -#include "curlx/dynbuf.h" -#include "urldata.h" - -struct Curl_easy; -struct connectdata; - -#ifndef CURL_DISABLE_DIGEST_AUTH -struct digestdata; -#endif - -#ifdef USE_NTLM -struct ntlmdata; -#endif - -#if (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) && defined(USE_SPNEGO) -struct negotiatedata; -#endif - -#ifdef USE_GSASL -struct gsasldata; -#endif - -#ifdef USE_WINDOWS_SSPI -#include "curl_sspi.h" -#define GSS_ERROR(status) ((status) & 0x80000000) -#endif - -/* - * Curl_auth_allowed_to_host() tells if authentication, cookies or other - * "sensitive data" can (still) be sent to this host. - */ -bool Curl_auth_allowed_to_host(struct Curl_easy *data); - -/* This is used to build an SPN string */ -#ifndef USE_WINDOWS_SSPI -char *Curl_auth_build_spn(const char *service, const char *host, - const char *realm); -#else -TCHAR *Curl_auth_build_spn(const char *service, const char *host, - const char *realm); -#endif - -/* This is used to test if the user contains a Windows domain name */ -bool Curl_auth_user_contains_domain(const char *user); - -/* This is used to generate a PLAIN cleartext message */ -CURLcode Curl_auth_create_plain_message(const char *authzid, - const char *authcid, - const char *passwd, - struct bufref *out); - -/* This is used to generate a LOGIN cleartext message */ -void Curl_auth_create_login_message(const char *value, struct bufref *out); - -/* This is used to generate an EXTERNAL cleartext message */ -void Curl_auth_create_external_message(const char *user, struct bufref *out); - -#ifndef CURL_DISABLE_DIGEST_AUTH -/* This is used to generate a CRAM-MD5 response message */ -CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg, - const char *userp, - const char *passwdp, - struct bufref *out); - -/* This is used to evaluate if DIGEST is supported */ -bool Curl_auth_is_digest_supported(void); - -/* This is used to generate a base64 encoded DIGEST-MD5 response message */ -CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, - const struct bufref *chlg, - const char *userp, - const char *passwdp, - const char *service, - struct bufref *out); - -/* This is used to decode an HTTP DIGEST challenge message */ -CURLcode Curl_auth_decode_digest_http_message(const char *chlg, - struct digestdata *digest); - -/* This is used to generate an HTTP DIGEST response message */ -CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const unsigned char *request, - const unsigned char *uripath, - struct digestdata *digest, - char **outptr, size_t *outlen); - -/* This is used to clean up the digest specific data */ -void Curl_auth_digest_cleanup(struct digestdata *digest); -#else -#define Curl_auth_digest_cleanup(x) -#define Curl_auth_is_digest_supported() FALSE -#endif /* !CURL_DISABLE_DIGEST_AUTH */ - -#ifdef USE_GSASL - -/* meta key for storing GSASL meta at connection */ -#define CURL_META_GSASL_CONN "meta:auth:gsasl:conn" - -#include -struct gsasldata { - Gsasl *ctx; - Gsasl_session *client; -}; - -struct gsasldata *Curl_auth_gsasl_get(struct connectdata *conn); - -/* This is used to evaluate if MECH is supported by gsasl */ -bool Curl_auth_gsasl_is_supported(struct Curl_easy *data, - const char *mech, - struct gsasldata *gsasl); -/* This is used to start a gsasl method */ -CURLcode Curl_auth_gsasl_start(struct Curl_easy *data, - const char *userp, - const char *passwdp, - struct gsasldata *gsasl); - -/* This is used to process and generate a new SASL token */ -CURLcode Curl_auth_gsasl_token(struct Curl_easy *data, - const struct bufref *chlg, - struct gsasldata *gsasl, - struct bufref *out); - -/* This is used to clean up the gsasl specific data */ -void Curl_auth_gsasl_cleanup(struct gsasldata *gsasl); -#endif - -#ifdef USE_NTLM - -/* meta key for storing NTML meta at connection */ -#define CURL_META_NTLM_CONN "meta:auth:ntml:conn" -/* meta key for storing NTML-PROXY meta at connection */ -#define CURL_META_NTLM_PROXY_CONN "meta:auth:ntml-proxy:conn" - -struct ntlmdata { -#ifdef USE_WINDOWS_SSPI -/* The sslContext is used for the Schannel bindings. The - * api is available on the Windows 7 SDK and later. - */ -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - CtxtHandle *sslContext; -#endif - CredHandle *credentials; - CtxtHandle *context; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - size_t token_max; - BYTE *output_token; - BYTE *input_token; - size_t input_token_len; - TCHAR *spn; -#else - unsigned int flags; - unsigned char nonce[8]; - unsigned int target_info_len; - void *target_info; /* TargetInfo received in the NTLM type-2 message */ -#endif -}; - -/* This is used to evaluate if NTLM is supported */ -bool Curl_auth_is_ntlm_supported(void); - -struct ntlmdata *Curl_auth_ntlm_get(struct connectdata *conn, bool proxy); -void Curl_auth_ntlm_remove(struct connectdata *conn, bool proxy); - -/* This is used to clean up the NTLM specific data */ -void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); - -/* This is used to generate a base64 encoded NTLM type-1 message */ -CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - struct ntlmdata *ntlm, - struct bufref *out); - -/* This is used to decode a base64 encoded NTLM type-2 message */ -CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, - const struct bufref *type2ref, - struct ntlmdata *ntlm); - -/* This is used to generate a base64 encoded NTLM type-3 message */ -CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - struct bufref *out); - -#else -#define Curl_auth_is_ntlm_supported() FALSE -#endif /* USE_NTLM */ - -/* This is used to generate a base64 encoded OAuth 2.0 message */ -CURLcode Curl_auth_create_oauth_bearer_message(const char *user, - const char *host, - const long port, - const char *bearer, - struct bufref *out); - -/* This is used to generate a base64 encoded XOAuth 2.0 message */ -CURLcode Curl_auth_create_xoauth_bearer_message(const char *user, - const char *bearer, - struct bufref *out); - -#ifdef USE_KERBEROS5 - -/* meta key for storing KRB5 meta at connection */ -#define CURL_META_KRB5_CONN "meta:auth:krb5:conn" - -struct kerberos5data { -#ifdef USE_WINDOWS_SSPI - CredHandle *credentials; - CtxtHandle *context; - TCHAR *spn; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - size_t token_max; - BYTE *output_token; -#else - gss_ctx_id_t context; - gss_name_t spn; -#endif -}; - -struct kerberos5data *Curl_auth_krb5_get(struct connectdata *conn); - -/* This is used to evaluate if GSSAPI (Kerberos V5) is supported */ -bool Curl_auth_is_gssapi_supported(void); - -/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token - message */ -CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - const bool mutual_auth, - const struct bufref *chlg, - struct kerberos5data *krb5, - struct bufref *out); - -/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security - token message */ -CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, - const char *authzid, - const struct bufref *chlg, - struct kerberos5data *krb5, - struct bufref *out); - -/* This is used to clean up the GSSAPI specific data */ -void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5); -#else -#define Curl_auth_is_gssapi_supported() FALSE -#endif /* USE_KERBEROS5 */ - -#ifdef USE_SPNEGO - -bool Curl_auth_is_spnego_supported(void); - -/* meta key for storing NEGO meta at connection */ -#define CURL_META_NEGO_CONN "meta:auth:nego:conn" -/* meta key for storing NEGO PROXY meta at connection */ -#define CURL_META_NEGO_PROXY_CONN "meta:auth:nego-proxy:conn" - -/* Struct used for Negotiate (SPNEGO) authentication */ -struct negotiatedata { -#ifdef HAVE_GSSAPI - OM_uint32 status; - gss_ctx_id_t context; - gss_name_t spn; - gss_buffer_desc output_token; -#ifdef GSS_C_CHANNEL_BOUND_FLAG - struct dynbuf channel_binding_data; -#endif -#else -#ifdef USE_WINDOWS_SSPI -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS - CtxtHandle *sslContext; -#endif - SECURITY_STATUS status; - CredHandle *credentials; - CtxtHandle *context; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - TCHAR *spn; - size_t token_max; - BYTE *output_token; - size_t output_token_length; -#endif -#endif - BIT(noauthpersist); - BIT(havenoauthpersist); - BIT(havenegdata); - BIT(havemultiplerequests); -}; - -struct negotiatedata * -Curl_auth_nego_get(struct connectdata *conn, bool proxy); - -/* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge - message */ -CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, - const char *user, - const char *password, - const char *service, - const char *host, - const char *chlg64, - struct negotiatedata *nego); - -/* This is used to generate a base64 encoded SPNEGO (Negotiate) response - message */ -CURLcode Curl_auth_create_spnego_message(struct negotiatedata *nego, - char **outptr, size_t *outlen); - -/* This is used to clean up the SPNEGO specific data */ -void Curl_auth_cleanup_spnego(struct negotiatedata *nego); - -#endif /* USE_SPNEGO */ - -#endif /* HEADER_CURL_VAUTH_H */ diff --git a/vendor/curl/lib/version.c b/vendor/curl/lib/version.c deleted file mode 100644 index b3b0a46ab..000000000 --- a/vendor/curl/lib/version.c +++ /dev/null @@ -1,676 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_NGHTTP2 -#include -#endif - -#include "urldata.h" -#include "vtls/vtls.h" -#include "http2.h" -#include "vssh/ssh.h" -#include "vquic/vquic.h" -#include "easy_lock.h" - -#ifdef USE_ARES -# include -#endif - -#ifdef USE_LIBIDN2 -#include -#endif - -#ifdef USE_LIBPSL -#include -#endif - -#ifdef HAVE_LIBZ -#include -#endif - -#ifdef HAVE_BROTLI -#ifdef CURL_HAVE_DIAG -/* Ignore -Wvla warnings in brotli headers */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wvla" -#endif -#include -#ifdef CURL_HAVE_DIAG -#pragma GCC diagnostic pop -#endif -#endif - -#ifdef HAVE_ZSTD -#include -#endif - -#ifdef USE_GSASL -#include -#endif - -#ifndef CURL_DISABLE_LDAP -#include "curl_ldap.h" -#endif - -#ifdef HAVE_BROTLI -static void brotli_version(char *buf, size_t bufsz) -{ - uint32_t brotli_version = BrotliDecoderVersion(); - unsigned int major = brotli_version >> 24; - unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12; - unsigned int patch = brotli_version & 0x00000FFF; - (void)curl_msnprintf(buf, bufsz, "brotli/%u.%u.%u", major, minor, patch); -} -#endif - -#ifdef HAVE_ZSTD -static void zstd_version(char *buf, size_t bufsz) -{ - unsigned int version = ZSTD_versionNumber(); - unsigned int major = version / (100 * 100); - unsigned int minor = (version - (major * 100 * 100)) / 100; - unsigned int patch = version - (major * 100 * 100) - (minor * 100); - (void)curl_msnprintf(buf, bufsz, "zstd/%u.%u.%u", major, minor, patch); -} -#endif - -#ifdef USE_LIBPSL -static void psl_version(char *buf, size_t bufsz) -{ -#if defined(PSL_VERSION_MAJOR) && (PSL_VERSION_MAJOR > 0 || \ - PSL_VERSION_MINOR >= 11) - int num = psl_check_version_number(0); - curl_msnprintf(buf, bufsz, "libpsl/%d.%d.%d", - num >> 16, (num >> 8) & 0xff, num & 0xff); -#else - curl_msnprintf(buf, bufsz, "libpsl/%s", psl_get_version()); -#endif -} -#endif - -#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) -#define USE_IDN -#endif - -#ifdef USE_IDN -static void idn_version(char *buf, size_t bufsz) -{ -#ifdef USE_LIBIDN2 - curl_msnprintf(buf, bufsz, "libidn2/%s", idn2_check_version(NULL)); -#elif defined(USE_WIN32_IDN) - curl_msnprintf(buf, bufsz, "WinIDN"); -#elif defined(USE_APPLE_IDN) - curl_msnprintf(buf, bufsz, "AppleIDN"); -#endif -} -#endif - -/* - * curl_version() returns a pointer to a static buffer. - * - * It is implemented to work multi-threaded by making sure repeated invokes - * generate the exact same string and never write any temporary data like - * zeros in the data. - */ - -#define VERSION_PARTS 16 /* number of substrings we can concatenate */ - -char *curl_version(void) -{ - static char out[300]; - char *outp; - size_t outlen; - const char *src[VERSION_PARTS]; -#ifdef USE_SSL - char ssl_version[200]; -#endif -#ifdef HAVE_LIBZ - char z_version[30]; -#endif -#ifdef HAVE_BROTLI - char br_version[30]; -#endif -#ifdef HAVE_ZSTD - char zstd_ver[30]; -#endif -#ifdef USE_ARES - char cares_version[30]; -#endif -#ifdef USE_IDN - char idn_ver[30]; -#endif -#ifdef USE_LIBPSL - char psl_ver[30]; -#endif -#ifdef USE_SSH - char ssh_version[30]; -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) - char h2_version[30]; -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) - char h3_version[30]; -#endif -#ifdef USE_GSASL - char gsasl_buf[30]; -#endif -#ifdef HAVE_GSSAPI - char gss_buf[40]; -#endif -#ifndef CURL_DISABLE_LDAP - char ldap_buf[30]; -#endif - int i = 0; - int j; - -#ifdef DEBUGBUILD - /* Override version string when environment variable CURL_VERSION is set */ - const char *debugversion = getenv("CURL_VERSION"); - if(debugversion) { - curl_msnprintf(out, sizeof(out), "%s", debugversion); - return out; - } -#endif - - src[i++] = LIBCURL_NAME "/" LIBCURL_VERSION; -#ifdef USE_SSL - Curl_ssl_version(ssl_version, sizeof(ssl_version)); - src[i++] = ssl_version; -#endif -#ifdef HAVE_LIBZ - curl_msnprintf(z_version, sizeof(z_version), "zlib/%s", zlibVersion()); - src[i++] = z_version; -#endif -#ifdef HAVE_BROTLI - brotli_version(br_version, sizeof(br_version)); - src[i++] = br_version; -#endif -#ifdef HAVE_ZSTD - zstd_version(zstd_ver, sizeof(zstd_ver)); - src[i++] = zstd_ver; -#endif -#ifdef USE_ARES - curl_msnprintf(cares_version, sizeof(cares_version), - "c-ares/%s", ares_version(NULL)); - src[i++] = cares_version; -#endif -#ifdef USE_IDN - idn_version(idn_ver, sizeof(idn_ver)); - src[i++] = idn_ver; -#endif -#ifdef USE_LIBPSL - psl_version(psl_ver, sizeof(psl_ver)); - src[i++] = psl_ver; -#endif -#ifdef USE_SSH - Curl_ssh_version(ssh_version, sizeof(ssh_version)); - src[i++] = ssh_version; -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) - Curl_http2_ver(h2_version, sizeof(h2_version)); - src[i++] = h2_version; -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) - Curl_quic_ver(h3_version, sizeof(h3_version)); - src[i++] = h3_version; -#endif -#ifdef USE_GSASL - curl_msnprintf(gsasl_buf, sizeof(gsasl_buf), "libgsasl/%s", - gsasl_check_version(NULL)); - src[i++] = gsasl_buf; -#endif -#ifdef HAVE_GSSAPI -#ifdef HAVE_GSSGNU - curl_msnprintf(gss_buf, sizeof(gss_buf), "libgss/%s", GSS_VERSION); -#elif defined(CURL_KRB5_VERSION) - curl_msnprintf(gss_buf, sizeof(gss_buf), "mit-krb5/%s", CURL_KRB5_VERSION); -#else - curl_msnprintf(gss_buf, sizeof(gss_buf), "mit-krb5"); -#endif - src[i++] = gss_buf; -#endif /* HAVE_GSSAPI */ -#ifndef CURL_DISABLE_LDAP - Curl_ldap_version(ldap_buf, sizeof(ldap_buf)); - src[i++] = ldap_buf; -#endif - - DEBUGASSERT(i <= VERSION_PARTS); - - outp = &out[0]; - outlen = sizeof(out); - for(j = 0; j < i; j++) { - size_t n = strlen(src[j]); - /* we need room for a space, the string and the final zero */ - if(outlen <= (n + 2)) - break; - if(j) { - /* prepend a space if not the first */ - *outp++ = ' '; - outlen--; - } - memcpy(outp, src[j], n); - outp += n; - outlen -= n; - } - *outp = 0; - - return out; -} - -/* data for curl_version_info - - Keep the list sorted alphabetically. It is also written so that each - protocol line has its own #if line to make things easier on the eye. - */ - -static const char * const supported_protocols[] = { -#ifndef CURL_DISABLE_DICT - "dict", -#endif -#ifndef CURL_DISABLE_FILE - "file", -#endif -#ifndef CURL_DISABLE_FTP - "ftp", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) - "ftps", -#endif -#ifndef CURL_DISABLE_GOPHER - "gopher", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER) - "gophers", -#endif -#ifndef CURL_DISABLE_HTTP - "http", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) - "https", -#endif -#ifndef CURL_DISABLE_IMAP - "imap", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP) - "imaps", -#endif -#ifndef CURL_DISABLE_LDAP - "ldap", -#if !defined(CURL_DISABLE_LDAPS) && \ - ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ - (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) - "ldaps", -#endif -#endif -#ifndef CURL_DISABLE_MQTT - "mqtt", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_MQTT) - "mqtts", -#endif -#ifndef CURL_DISABLE_POP3 - "pop3", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) - "pop3s", -#endif -#ifndef CURL_DISABLE_RTSP - "rtsp", -#endif -#ifdef USE_SSH - "scp", - "sftp", -#endif -#if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) - "smb", -# ifdef USE_SSL - "smbs", -# endif -#endif -#ifndef CURL_DISABLE_SMTP - "smtp", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP) - "smtps", -#endif -#ifndef CURL_DISABLE_TELNET - "telnet", -#endif -#ifndef CURL_DISABLE_TFTP - "tftp", -#endif -#ifndef CURL_DISABLE_HTTP - /* WebSocket support relies on HTTP */ -#ifndef CURL_DISABLE_WEBSOCKETS - "ws", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_WEBSOCKETS) - "wss", -#endif -#endif - - NULL -}; - -/* - * Feature presence runtime check functions. - * - * Warning: the value returned by these should not change between - * curl_global_init() and curl_global_cleanup() calls. - */ - -#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) -static int idn_present(curl_version_info_data *info) -{ -#if defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) - (void)info; - return TRUE; -#else - return info->libidn != NULL; -#endif -} -#endif - -#if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) && \ - !defined(CURL_DISABLE_HTTP) -static int https_proxy_present(curl_version_info_data *info) -{ - (void)info; - return Curl_ssl_supports(NULL, SSLSUPP_HTTPS_PROXY); -} -#endif - -#if defined(USE_SSL) && defined(USE_ECH) -static int ech_present(curl_version_info_data *info) -{ - (void)info; - return Curl_ssl_supports(NULL, SSLSUPP_ECH); -} -#endif - -/* - * Features table. - * - * Keep the features alphabetically sorted. - * Use FEATURE() macro to define an entry: this allows documentation check. - */ - -#define FEATURE(name, present, bitmask) { (name), (present), (bitmask) } - -struct feat { - const char *name; - int (*present)(curl_version_info_data *info); - int bitmask; -}; - -static const struct feat features_table[] = { -#ifndef CURL_DISABLE_ALTSVC - FEATURE("alt-svc", NULL, CURL_VERSION_ALTSVC), -#endif -#if defined(USE_ARES) && defined(USE_RESOLV_THREADED) && defined(USE_HTTPSRR) - FEATURE("asyn-rr", NULL, 0), -#endif -#ifdef CURLRES_ASYNCH - FEATURE("AsynchDNS", NULL, CURL_VERSION_ASYNCHDNS), -#endif -#ifdef HAVE_BROTLI - FEATURE("brotli", NULL, CURL_VERSION_BROTLI), -#endif -#ifdef DEBUGBUILD - FEATURE("Debug", NULL, CURL_VERSION_DEBUG), -#endif -#if defined(USE_SSL) && defined(USE_ECH) - FEATURE("ECH", ech_present, 0), - -#ifndef USE_HTTPSRR -#error "ECH enabled but not HTTPSRR, must be a config error" -#endif -#endif -#ifdef USE_GSASL - FEATURE("gsasl", NULL, CURL_VERSION_GSASL), -#endif -#ifdef HAVE_GSSAPI - FEATURE("GSS-API", NULL, CURL_VERSION_GSSAPI), -#endif -#ifndef CURL_DISABLE_HSTS - FEATURE("HSTS", NULL, CURL_VERSION_HSTS), -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGHTTP2) - FEATURE("HTTP2", NULL, CURL_VERSION_HTTP2), -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) - FEATURE("HTTP3", NULL, CURL_VERSION_HTTP3), -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) && \ - !defined(CURL_DISABLE_HTTP) - FEATURE("HTTPS-proxy", https_proxy_present, CURL_VERSION_HTTPS_PROXY), -#endif -#ifdef USE_HTTPSRR - FEATURE("HTTPSRR", NULL, 0), -#endif -#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) - FEATURE("IDN", idn_present, CURL_VERSION_IDN), -#endif -#ifdef USE_IPV6 - FEATURE("IPv6", NULL, CURL_VERSION_IPV6), -#endif -#ifdef USE_KERBEROS5 - FEATURE("Kerberos", NULL, CURL_VERSION_KERBEROS5), -#endif -#if (SIZEOF_CURL_OFF_T > 4) && ((SIZEOF_OFF_T > 4) || defined(_WIN32)) - FEATURE("Largefile", NULL, CURL_VERSION_LARGEFILE), -#endif -#ifdef HAVE_LIBZ - FEATURE("libz", NULL, CURL_VERSION_LIBZ), -#endif -#ifdef CURL_WITH_MULTI_SSL - FEATURE("MultiSSL", NULL, CURL_VERSION_MULTI_SSL), -#endif -#ifdef USE_NTLM - FEATURE("NTLM", NULL, CURL_VERSION_NTLM), -#endif -#ifdef USE_LIBPSL - FEATURE("PSL", NULL, CURL_VERSION_PSL), -#endif -#ifdef USE_SSL -#ifdef USE_APPLE_SECTRUST - FEATURE("AppleSecTrust", NULL, 0), -#elif defined(CURL_CA_NATIVE) - FEATURE("NativeCA", NULL, 0), -#endif -#endif /* USE_SSL */ -#ifdef USE_SPNEGO - FEATURE("SPNEGO", NULL, CURL_VERSION_SPNEGO), -#endif -#ifdef USE_SSL - FEATURE("SSL", NULL, CURL_VERSION_SSL), -#endif -#ifdef USE_SSLS_EXPORT - FEATURE("SSLS-EXPORT", NULL, 0), -#endif -#ifdef USE_WINDOWS_SSPI - FEATURE("SSPI", NULL, CURL_VERSION_SSPI), -#endif -#ifdef GLOBAL_INIT_IS_THREADSAFE - FEATURE("threadsafe", NULL, CURL_VERSION_THREADSAFE), -#endif -#ifdef USE_TLS_SRP - FEATURE("TLS-SRP", NULL, CURL_VERSION_TLSAUTH_SRP), -#endif -#if defined(_WIN32) && defined(UNICODE) && defined(_UNICODE) - FEATURE("Unicode", NULL, CURL_VERSION_UNICODE), -#endif -#ifdef USE_UNIX_SOCKETS - FEATURE("UnixSockets", NULL, CURL_VERSION_UNIX_SOCKETS), -#endif -#ifdef HAVE_ZSTD - FEATURE("zstd", NULL, CURL_VERSION_ZSTD), -#endif - {NULL, NULL, 0} -}; - -static const char *feature_names[CURL_ARRAYSIZE(features_table)] = { NULL }; - -static curl_version_info_data version_info = { - CURLVERSION_NOW, - LIBCURL_VERSION, - LIBCURL_VERSION_NUM, - CURL_OS, /* as found by configure or set by hand at build-time */ - 0, /* features bitmask is built at runtime */ - NULL, /* ssl_version */ - 0, /* ssl_version_num, this is kept at zero */ - NULL, /* zlib_version */ - supported_protocols, - NULL, /* c-ares version */ - 0, /* c-ares version numerical */ - NULL, /* libidn version */ - 0, /* iconv version */ - NULL, /* ssh lib version */ - 0, /* brotli_ver_num */ - NULL, /* brotli version */ - 0, /* nghttp2 version number */ - NULL, /* nghttp2 version string */ - NULL, /* quic library string */ -#ifdef CURL_CA_BUNDLE - CURL_CA_BUNDLE, /* cainfo */ -#else - NULL, -#endif -#ifdef CURL_CA_PATH - CURL_CA_PATH, /* capath */ -#else - NULL, -#endif - 0, /* zstd_ver_num */ - NULL, /* zstd version */ - NULL, /* Hyper version */ - NULL, /* gsasl version */ - feature_names, - NULL /* rtmp version */ -}; - -curl_version_info_data *curl_version_info(CURLversion stamp) -{ - size_t n; - const struct feat *p; - int features = 0; - -#ifdef USE_SSH - static char ssh_buf[80]; /* 'ssh_buffer' clashes with libssh/libssh.h */ -#endif -#ifdef USE_SSL -#ifdef CURL_WITH_MULTI_SSL - static char ssl_buffer[200]; -#else - static char ssl_buffer[80]; -#endif -#endif -#ifdef HAVE_BROTLI - static char brotli_buffer[80]; -#endif -#ifdef HAVE_ZSTD - static char zstd_buffer[80]; -#endif - - (void)stamp; - -#ifdef USE_SSL - Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); - version_info.ssl_version = ssl_buffer; -#endif - -#ifdef HAVE_LIBZ - version_info.libz_version = zlibVersion(); - /* libz left NULL if non-existing */ -#endif -#ifdef USE_ARES - { - int aresnum; - version_info.ares = ares_version(&aresnum); - version_info.ares_num = aresnum; - } -#endif -#ifdef USE_LIBIDN2 - /* This returns a version string if we use the given version or later, - otherwise it returns NULL */ - version_info.libidn = idn2_check_version(IDN2_VERSION); -#endif - -#ifdef USE_SSH - Curl_ssh_version(ssh_buf, sizeof(ssh_buf)); - version_info.libssh_version = ssh_buf; -#endif - -#ifdef HAVE_BROTLI - version_info.brotli_ver_num = BrotliDecoderVersion(); - brotli_version(brotli_buffer, sizeof(brotli_buffer)); - version_info.brotli_version = brotli_buffer; -#endif - -#ifdef HAVE_ZSTD - version_info.zstd_ver_num = ZSTD_versionNumber(); - zstd_version(zstd_buffer, sizeof(zstd_buffer)); - version_info.zstd_version = zstd_buffer; -#endif - -#ifdef USE_NGHTTP2 - { - nghttp2_info *h2 = nghttp2_version(0); - version_info.nghttp2_ver_num = (unsigned int)h2->version_num; - version_info.nghttp2_version = h2->version_str; - } -#endif - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) - { - static char quicbuffer[80]; - Curl_quic_ver(quicbuffer, sizeof(quicbuffer)); - version_info.quic_version = quicbuffer; - } -#endif - -#ifdef USE_GSASL - { - version_info.gsasl_version = gsasl_check_version(NULL); - } -#endif - - /* Get available features, build bitmask and names array. */ - n = 0; - for(p = features_table; p->name; p++) - if(!p->present || p->present(&version_info)) { - features |= p->bitmask; - feature_names[n++] = p->name; - } - -#ifdef DEBUGBUILD - features |= CURL_VERSION_CURLDEBUG; /* for compatibility */ -#endif - - feature_names[n] = NULL; /* Terminate array. */ - version_info.features = features; - - return &version_info; -} diff --git a/vendor/curl/lib/vquic/curl_ngtcp2.c b/vendor/curl/lib/vquic/curl_ngtcp2.c deleted file mode 100644 index 8cf3886d2..000000000 --- a/vendor/curl/lib/vquic/curl_ngtcp2.c +++ /dev/null @@ -1,2997 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGTCP2) && defined(USE_NGHTTP3) -#include -#include - -#ifdef USE_OPENSSL -#include -#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) -#include -#elif defined(OPENSSL_QUIC_API2) -#include -#else -#include -#endif -#include "vtls/openssl.h" -#elif defined(USE_GNUTLS) -#include -#include "vtls/gtls.h" -#elif defined(USE_WOLFSSL) -#include -#include "vtls/wolfssl.h" -#endif - -#include "urldata.h" -#include "url.h" -#include "uint-hash.h" -#include "curl_trc.h" -#include "rand.h" -#include "multiif.h" -#include "cfilters.h" -#include "cf-dns.h" -#include "cf-socket.h" -#include "connect.h" -#include "progress.h" -#include "curlx/fopen.h" -#include "curlx/dynbuf.h" -#include "http1.h" -#include "select.h" -#include "transfer.h" -#include "bufref.h" -#include "vquic/vquic.h" -#include "vquic/vquic_int.h" -#include "vquic/vquic-tls.h" -#include "vtls/vtls.h" -#include "vtls/vtls_scache.h" -#include "vquic/curl_ngtcp2.h" - - -#define QUIC_MAX_STREAMS (256 * 1024) -#define QUIC_HANDSHAKE_TIMEOUT (10 * NGTCP2_SECONDS) - -/* We announce a small window size in transport param to the server, - * and grow that immediately to max when no rate limit is in place. - * We need to start small as we are not able to decrease it. */ -#define H3_STREAM_WINDOW_SIZE_INITIAL (32 * 1024) -#define H3_STREAM_WINDOW_SIZE_MAX (10 * 1024 * 1024) -#define H3_CONN_WINDOW_SIZE_MAX (100 * H3_STREAM_WINDOW_SIZE_MAX) - -#define H3_STREAM_CHUNK_SIZE (64 * 1024) -#if H3_STREAM_CHUNK_SIZE < NGTCP2_MAX_UDP_PAYLOAD_SIZE -#error H3_STREAM_CHUNK_SIZE smaller than NGTCP2_MAX_UDP_PAYLOAD_SIZE -#endif - -/* The pool keeps spares around and half of a full stream windows - * seems good. More does not seem to improve performance. - * The benefit of the pool is that stream buffer to not keep - * spares. Memory consumption goes down when streams run empty, - * have a large upload done, etc. */ -#define H3_STREAM_POOL_SPARES 2 -/* The max amount of un-acked upload data we keep around per stream */ -#define H3_STREAM_SEND_BUFFER_MAX (10 * 1024 * 1024) -#define H3_STREAM_SEND_CHUNKS \ - (H3_STREAM_SEND_BUFFER_MAX / H3_STREAM_CHUNK_SIZE) - -/* - * Store ngtcp2 version info in this buffer. - */ -void Curl_ngtcp2_ver(char *p, size_t len) -{ - const ngtcp2_info *ng2 = ngtcp2_version(0); - const nghttp3_info *ht3 = nghttp3_version(0); - (void)curl_msnprintf(p, len, "ngtcp2/%s nghttp3/%s", - ng2->version_str, ht3->version_str); -} - -struct cf_ngtcp2_ctx { - struct cf_quic_ctx q; - struct ssl_peer peer; - struct curl_tls_ctx tls; -#ifdef OPENSSL_QUIC_API2 - ngtcp2_crypto_ossl_ctx *ossl_ctx; -#endif - ngtcp2_path connected_path; - ngtcp2_conn *qconn; - ngtcp2_cid dcid; - ngtcp2_cid scid; - uint32_t version; - ngtcp2_settings settings; - ngtcp2_transport_params transport_params; - ngtcp2_ccerr last_error; - ngtcp2_crypto_conn_ref conn_ref; - struct cf_call_data call_data; - nghttp3_conn *h3conn; - nghttp3_settings h3settings; - struct curltime started_at; /* time the current attempt started */ - struct curltime handshake_at; /* time connect handshake finished */ - struct bufc_pool stream_bufcp; /* chunk pool for streams */ - struct dynbuf scratch; /* temp buffer for header construction */ - struct uint_hash streams; /* hash `data->mid` to `h3_stream_ctx` */ - uint64_t used_bidi_streams; /* bidi streams we have opened */ - uint64_t max_bidi_streams; /* max bidi streams we can open */ - size_t earlydata_max; /* max amount of early data supported by - server on session reuse */ - size_t earlydata_skip; /* sending bytes to skip when earlydata - is accepted by peer */ - CURLcode tls_vrfy_result; /* result of TLS peer verification */ - int qlogfd; - BIT(initialized); - BIT(tls_handshake_complete); /* TLS handshake is done */ - BIT(use_earlydata); /* Using 0RTT data */ - BIT(earlydata_accepted); /* 0RTT was accepted by server */ - BIT(shutdown_started); /* queued shutdown packets */ -}; - -/* How to access `call_data` from a cf_ngtcp2 filter */ -#undef CF_CTX_CALL_DATA -#define CF_CTX_CALL_DATA(cf) ((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data - -static void h3_stream_hash_free(unsigned int id, void *stream); - -static void cf_ngtcp2_ctx_init(struct cf_ngtcp2_ctx *ctx) -{ - DEBUGASSERT(!ctx->initialized); - ctx->qlogfd = -1; - ctx->version = NGTCP2_PROTO_VER_MAX; - Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, - H3_STREAM_POOL_SPARES); - curlx_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER); - Curl_uint32_hash_init(&ctx->streams, 63, h3_stream_hash_free); - ctx->initialized = TRUE; -} - -static void cf_ngtcp2_ctx_free(struct cf_ngtcp2_ctx *ctx) -{ - if(ctx && ctx->initialized) { - Curl_vquic_tls_cleanup(&ctx->tls); - vquic_ctx_free(&ctx->q); - Curl_bufcp_free(&ctx->stream_bufcp); - curlx_dyn_free(&ctx->scratch); - Curl_uint32_hash_destroy(&ctx->streams); - Curl_ssl_peer_cleanup(&ctx->peer); - } - curlx_free(ctx); -} - -static void cf_ngtcp2_setup_keep_alive(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - const ngtcp2_transport_params *rp; - /* Peer should have sent us its transport parameters. If it - * announces a positive `max_idle_timeout` it closes the - * connection when it does not hear from us for that time. - * - * Some servers use this as a keep-alive timer at a rather low - * value. We are doing HTTP/3 here and waiting for the response - * to a request may take a considerable amount of time. We need - * to prevent the peer's QUIC stack from closing in this case. - */ - if(!ctx->qconn) - return; - - rp = ngtcp2_conn_get_remote_transport_params(ctx->qconn); - if(!rp || !rp->max_idle_timeout) { - ngtcp2_conn_set_keep_alive_timeout(ctx->qconn, UINT64_MAX); - CURL_TRC_CF(data, cf, "no peer idle timeout, unset keep-alive"); - } - else if(!Curl_uint32_hash_count(&ctx->streams)) { - ngtcp2_conn_set_keep_alive_timeout(ctx->qconn, UINT64_MAX); - CURL_TRC_CF(data, cf, "no active streams, unset keep-alive"); - } - else { - ngtcp2_duration keep_ns; - keep_ns = (rp->max_idle_timeout > 1) ? (rp->max_idle_timeout / 2) : 1; - ngtcp2_conn_set_keep_alive_timeout(ctx->qconn, keep_ns); - CURL_TRC_CF(data, cf, "peer idle timeout is %" PRIu64 "ms, " - "set keep-alive to %" PRIu64 " ms.", - (rp->max_idle_timeout / NGTCP2_MILLISECONDS), - (keep_ns / NGTCP2_MILLISECONDS)); - } -} - -struct pkt_io_ctx; -static CURLcode cf_progress_ingress(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct pkt_io_ctx *pktx); -static CURLcode cf_progress_egress(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct pkt_io_ctx *pktx); - -/** - * All about the H3 internals of a stream - */ -struct h3_stream_ctx { - int64_t id; /* HTTP/3 protocol identifier */ - struct bufq sendbuf; /* h3 request body */ - struct h1_req_parser h1; /* h1 request parsing */ - size_t sendbuf_len_in_flight; /* sendbuf amount "in flight" */ - uint64_t error3; /* HTTP/3 stream error code */ - curl_off_t upload_left; /* number of request bytes left to upload */ - uint64_t rx_offset; /* current receive offset */ - uint64_t rx_offset_max; /* allowed receive offset */ - uint64_t window_size_max; /* max flow control window set for stream */ - int status_code; /* HTTP status code */ - CURLcode xfer_result; /* result from xfer_resp_write(_hd) */ - BIT(resp_hds_complete); /* we have a complete, final response */ - BIT(closed); /* TRUE on stream close */ - BIT(reset); /* TRUE on stream reset */ - BIT(send_closed); /* stream is local closed */ - BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */ -}; - -static void h3_stream_ctx_free(struct h3_stream_ctx *stream) -{ - Curl_bufq_free(&stream->sendbuf); - Curl_h1_req_parse_free(&stream->h1); - curlx_free(stream); -} - -static void h3_stream_hash_free(unsigned int id, void *stream) -{ - (void)id; - DEBUGASSERT(stream); - h3_stream_ctx_free((struct h3_stream_ctx *)stream); -} - -static CURLcode h3_data_setup(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - - if(!data) - return CURLE_FAILED_INIT; - - if(stream) - return CURLE_OK; - - stream = curlx_calloc(1, sizeof(*stream)); - if(!stream) - return CURLE_OUT_OF_MEMORY; - - stream->id = -1; - stream->rx_offset = 0; - stream->rx_offset_max = H3_STREAM_WINDOW_SIZE_INITIAL; - - /* on send, we control how much we put into the buffer */ - Curl_bufq_initp(&stream->sendbuf, &ctx->stream_bufcp, - H3_STREAM_SEND_CHUNKS, BUFQ_OPT_NONE); - stream->sendbuf_len_in_flight = 0; - stream->window_size_max = H3_STREAM_WINDOW_SIZE_INITIAL; - Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN); - - if(!Curl_uint32_hash_set(&ctx->streams, data->mid, stream)) { - h3_stream_ctx_free(stream); - return CURLE_OUT_OF_MEMORY; - } - - if(Curl_uint32_hash_count(&ctx->streams) == 1) - cf_ngtcp2_setup_keep_alive(cf, data); - - return CURLE_OK; -} - -#if NGTCP2_VERSION_NUM < 0x011100 -struct cf_ngtcp2_sfind_ctx { - int64_t stream_id; - struct h3_stream_ctx *stream; - uint32_t mid; -}; - -static bool cf_ngtcp2_sfind(uint32_t mid, void *value, void *user_data) -{ - struct cf_ngtcp2_sfind_ctx *fctx = user_data; - struct h3_stream_ctx *stream = value; - - if(fctx->stream_id == stream->id) { - fctx->mid = mid; - fctx->stream = stream; - return FALSE; - } - return TRUE; /* continue */ -} - -static struct h3_stream_ctx *cf_ngtcp2_get_stream(struct cf_ngtcp2_ctx *ctx, - int64_t stream_id) -{ - struct cf_ngtcp2_sfind_ctx fctx; - fctx.stream_id = stream_id; - fctx.stream = NULL; - Curl_uint32_hash_visit(&ctx->streams, cf_ngtcp2_sfind, &fctx); - return fctx.stream; -} -#else -static struct h3_stream_ctx *cf_ngtcp2_get_stream(struct cf_ngtcp2_ctx *ctx, - int64_t stream_id) -{ - struct Curl_easy *data = - ngtcp2_conn_get_stream_user_data(ctx->qconn, stream_id); - - if(!data) { - return NULL; - } - - return H3_STREAM_CTX(ctx, data); -} -#endif - -static void cf_ngtcp2_stream_close(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - DEBUGASSERT(data); - DEBUGASSERT(stream); - if(!stream->closed && ctx->qconn && ctx->h3conn) { - CURLcode result; - - nghttp3_conn_set_stream_user_data(ctx->h3conn, stream->id, NULL); - ngtcp2_conn_set_stream_user_data(ctx->qconn, stream->id, NULL); - stream->closed = TRUE; - (void)ngtcp2_conn_shutdown_stream(ctx->qconn, 0, stream->id, - NGHTTP3_H3_REQUEST_CANCELLED); - result = cf_progress_egress(cf, data, NULL); - if(result) - CURL_TRC_CF(data, cf, "[%" PRId64 "] cancel stream -> %d", - stream->id, result); - } -} - -static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - (void)cf; - if(stream) { - CURL_TRC_CF(data, cf, "[%" PRId64 "] easy handle is done", stream->id); - cf_ngtcp2_stream_close(cf, data, stream); - Curl_uint32_hash_remove(&ctx->streams, data->mid); - if(!Curl_uint32_hash_count(&ctx->streams)) - cf_ngtcp2_setup_keep_alive(cf, data); - } -} - -struct pkt_io_ctx { - struct Curl_cfilter *cf; - struct Curl_easy *data; - ngtcp2_tstamp ts; - ngtcp2_path_storage ps; -}; - -static void pktx_update_time(struct Curl_easy *data, - struct pkt_io_ctx *pktx, - struct Curl_cfilter *cf) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - const struct curltime *pnow = Curl_pgrs_now(data); - - vquic_ctx_update_time(&ctx->q, pnow); - pktx->ts = ((ngtcp2_tstamp)pnow->tv_sec * NGTCP2_SECONDS) + - ((ngtcp2_tstamp)pnow->tv_usec * NGTCP2_MICROSECONDS); -} - -static void pktx_init(struct pkt_io_ctx *pktx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - const struct curltime *pnow = Curl_pgrs_now(data); - - pktx->cf = cf; - pktx->data = data; - ngtcp2_path_storage_zero(&pktx->ps); - vquic_ctx_set_time(&ctx->q, pnow); - pktx->ts = ((ngtcp2_tstamp)pnow->tv_sec * NGTCP2_SECONDS) + - ((ngtcp2_tstamp)pnow->tv_usec * NGTCP2_MICROSECONDS); -} - -static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id, - uint64_t datalen, void *user_data, - void *stream_user_data); - -static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref) -{ - struct Curl_cfilter *cf = conn_ref->user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - return ctx->qconn; -} - -#ifdef DEBUG_NGTCP2 -static void quic_printf(void *user_data, const char *fmt, ...) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - - (void)ctx; /* need an easy handle to infof() message */ - va_list ap; - va_start(ap, fmt); - curl_mvfprintf(stderr, fmt, ap); - va_end(ap); - curl_mfprintf(stderr, "\n"); -} -#endif - -static void qlog_callback(void *user_data, uint32_t flags, - const void *data, size_t datalen) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - (void)flags; - if(ctx->qlogfd != -1) { - ssize_t rc = write(ctx->qlogfd, data, datalen); - if(rc == -1) { - /* on write error, stop further write attempts */ - curlx_close(ctx->qlogfd); - ctx->qlogfd = -1; - } - } -} - -static void quic_settings(struct cf_ngtcp2_ctx *ctx, - struct Curl_easy *data, - struct pkt_io_ctx *pktx) -{ - ngtcp2_settings *s = &ctx->settings; - ngtcp2_transport_params *t = &ctx->transport_params; - - ngtcp2_settings_default(s); - ngtcp2_transport_params_default(t); -#ifdef DEBUG_NGTCP2 - s->log_printf = quic_printf; -#else - s->log_printf = NULL; -#endif - - s->initial_ts = pktx->ts; - s->handshake_timeout = (data->set.connecttimeout > 0) ? - data->set.connecttimeout * NGTCP2_MILLISECONDS : QUIC_HANDSHAKE_TIMEOUT; - s->max_window = H3_CONN_WINDOW_SIZE_MAX; - s->max_stream_window = 0; /* disable ngtcp2 auto-tuning of window */ - s->no_pmtud = FALSE; -#ifdef NGTCP2_SETTINGS_V3 - /* try ten times the ngtcp2 defaults here for problems with Caddy */ - s->glitch_ratelim_burst = 1000 * 10; - s->glitch_ratelim_rate = 33 * 10; -#endif - t->initial_max_data = s->max_window; - t->initial_max_stream_data_bidi_local = H3_STREAM_WINDOW_SIZE_INITIAL; - t->initial_max_stream_data_bidi_remote = H3_STREAM_WINDOW_SIZE_INITIAL; - t->initial_max_stream_data_uni = t->initial_max_data; - t->initial_max_streams_bidi = QUIC_MAX_STREAMS; - t->initial_max_streams_uni = QUIC_MAX_STREAMS; - t->max_idle_timeout = 0; /* no idle timeout from our side */ - if(ctx->qlogfd != -1) { - s->qlog_write = qlog_callback; - } -} - -static CURLcode init_ngh3_conn(struct Curl_cfilter *cf, - struct Curl_easy *data); - -static int cf_ngtcp2_handshake_completed(ngtcp2_conn *tconn, void *user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf ? cf->ctx : NULL; - struct Curl_easy *data; - - (void)tconn; - DEBUGASSERT(ctx); - data = CF_DATA_CURRENT(cf); - DEBUGASSERT(data); - if(!ctx || !data) - return NGHTTP3_ERR_CALLBACK_FAILURE; - - ctx->handshake_at = *Curl_pgrs_now(data); - ctx->tls_handshake_complete = TRUE; - Curl_vquic_report_handshake(&ctx->tls, cf, data); - - ctx->tls_vrfy_result = Curl_vquic_tls_verify_peer(&ctx->tls, cf, - data, &ctx->peer); -#ifdef CURLVERBOSE - if(Curl_trc_is_verbose(data)) { - const ngtcp2_transport_params *rp; - rp = ngtcp2_conn_get_remote_transport_params(ctx->qconn); - CURL_TRC_CF(data, cf, "handshake complete after %" FMT_TIMEDIFF_T - "ms, remote transport[max_udp_payload=%" PRIu64 - ", initial_max_data=%" PRIu64 - "]", - curlx_ptimediff_ms(&ctx->handshake_at, &ctx->started_at), - rp->max_udp_payload_size, rp->initial_max_data); - } -#endif - - /* In case of earlydata, where we simulate being connected, update - * the handshake time when we really did connect */ - if(ctx->use_earlydata) - Curl_pgrsTimeWas(data, TIMER_APPCONNECT, ctx->handshake_at); - if(ctx->use_earlydata) { -#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA) - ctx->earlydata_accepted = - (SSL_get_early_data_status(ctx->tls.ossl.ssl) != - SSL_EARLY_DATA_REJECTED); -#endif -#ifdef USE_GNUTLS - int flags = gnutls_session_get_flags(ctx->tls.gtls.session); - ctx->earlydata_accepted = !!(flags & GNUTLS_SFLAGS_EARLY_DATA); -#endif -#ifdef USE_WOLFSSL -#ifdef WOLFSSL_EARLY_DATA - ctx->earlydata_accepted = - (wolfSSL_get_early_data_status(ctx->tls.wssl.ssl) != - WOLFSSL_EARLY_DATA_REJECTED); -#else - DEBUGASSERT(0); /* should not come here if ED is disabled. */ - ctx->earlydata_accepted = FALSE; -#endif /* WOLFSSL_EARLY_DATA */ -#endif - CURL_TRC_CF(data, cf, "server did%s accept %zu bytes of early data", - ctx->earlydata_accepted ? "" : " not", ctx->earlydata_skip); - Curl_pgrsEarlyData(data, ctx->earlydata_accepted ? - (curl_off_t)ctx->earlydata_skip : - -(curl_off_t)ctx->earlydata_skip); - } - return 0; -} - -static void cf_ngtcp2_conn_close(struct Curl_cfilter *cf, - struct Curl_easy *data); - -static bool cf_ngtcp2_err_is_fatal(int code) -{ - return (NGTCP2_ERR_FATAL >= code) || - (NGTCP2_ERR_DROP_CONN == code) || - (NGTCP2_ERR_IDLE_CLOSE == code); -} - -static void cf_ngtcp2_err_set(struct Curl_cfilter *cf, - struct Curl_easy *data, int code) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - if(!ctx->last_error.error_code) { - if(NGTCP2_ERR_CRYPTO == code) { - ngtcp2_ccerr_set_tls_alert(&ctx->last_error, - ngtcp2_conn_get_tls_alert(ctx->qconn), - NULL, 0); - } - else { - ngtcp2_ccerr_set_liberr(&ctx->last_error, code, NULL, 0); - } - } - if(cf_ngtcp2_err_is_fatal(code)) - cf_ngtcp2_conn_close(cf, data); -} - -static bool cf_ngtcp2_h3_err_is_fatal(int code) -{ - return (NGHTTP3_ERR_FATAL >= code) || - (NGHTTP3_ERR_H3_CLOSED_CRITICAL_STREAM == code); -} - -static void cf_ngtcp2_h3_err_set(struct Curl_cfilter *cf, - struct Curl_easy *data, int code) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - if(!ctx->last_error.error_code) { - ngtcp2_ccerr_set_application_error(&ctx->last_error, - nghttp3_err_infer_quic_app_error_code(code), NULL, 0); - } - if(cf_ngtcp2_h3_err_is_fatal(code)) - cf_ngtcp2_conn_close(cf, data); -} - -static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, - int64_t stream_id, uint64_t offset, - const uint8_t *buf, size_t buflen, - void *user_data, void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - nghttp3_ssize rc; - uint64_t nconsumed; - int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0; - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - (void)offset; - - rc = nghttp3_conn_read_stream(ctx->h3conn, stream_id, buf, buflen, fin); - if(rc < 0) { - if(data && stream) { - CURL_TRC_CF(data, cf, "[%" PRId64 "] error on known stream, " - "reset=%d, closed=%d", - stream_id, stream->reset, stream->closed); - } - return NGTCP2_ERR_CALLBACK_FAILURE; - } - nconsumed = (uint64_t)rc; - if(nconsumed) { - /* number of bytes inside buflen which consists of framing overhead - * including QPACK HEADERS. In other words, it does not consume payload of - * DATA frame. */ - ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed); - ngtcp2_conn_extend_max_offset(tconn, nconsumed); - if(stream) { - stream->rx_offset += nconsumed; - stream->rx_offset_max += nconsumed; - } - } - return 0; -} - -static int cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t offset, uint64_t datalen, - void *user_data, void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - int rv; - (void)stream_id; - (void)tconn; - (void)offset; - (void)datalen; - (void)stream_user_data; - - rv = nghttp3_conn_add_ack_offset(ctx->h3conn, stream_id, datalen); - if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags, - int64_t stream_id, uint64_t app_error_code, - void *user_data, void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - int rv; - - (void)tconn; - /* stream is closed... */ - if(!data) - data = CF_DATA_CURRENT(cf); - if(!data) - return NGTCP2_ERR_CALLBACK_FAILURE; - - if(!(flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET)) { - app_error_code = NGHTTP3_H3_NO_ERROR; - } - - rv = nghttp3_conn_close_stream(ctx->h3conn, stream_id, app_error_code); - CURL_TRC_CF(data, cf, "[%" PRId64 "] quic close(app_error=%" - PRIu64 ") -> %d", stream_id, app_error_code, rv); - if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { - cf_ngtcp2_h3_err_set(cf, data, rv); - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t final_size, uint64_t app_error_code, - void *user_data, void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - int rv; - (void)tconn; - (void)final_size; - (void)app_error_code; - - rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id); - CURL_TRC_CF(data, cf, "[%" PRId64 "] reset -> %d", stream_id, rv); - if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_stream_stop_sending(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t app_error_code, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - int rv; - (void)tconn; - (void)app_error_code; - (void)stream_user_data; - - rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id); - if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { - return NGTCP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn, - uint64_t max_streams, - void *user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - - (void)tconn; - ctx->max_bidi_streams = max_streams; - if(data) - CURL_TRC_CF(data, cf, "max bidi streams now %" PRIu64 ", used %" PRIu64, - ctx->max_bidi_streams, ctx->used_bidi_streams); - return 0; -} - -static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t max_data, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *s_data = stream_user_data; - struct h3_stream_ctx *stream; - int rv; - (void)tconn; - (void)max_data; - - rv = nghttp3_conn_unblock_stream(ctx->h3conn, stream_id); - if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { - return NGTCP2_ERR_CALLBACK_FAILURE; - } - stream = H3_STREAM_CTX(ctx, s_data); - if(stream && stream->quic_flow_blocked) { - CURL_TRC_CF(s_data, cf, "[%" PRId64 "] unblock quic flow", stream_id); - stream->quic_flow_blocked = FALSE; - Curl_multi_mark_dirty(s_data); - } - return 0; -} - -static void cb_rand(uint8_t *dest, size_t destlen, - const ngtcp2_rand_ctx *rand_ctx) -{ - CURLcode result; - (void)rand_ctx; - - result = Curl_rand(NULL, dest, destlen); - if(result) { - /* cb_rand is only used for non-cryptographic context. If Curl_rand - failed, fill 0 and call it *random*. */ - memset(dest, 0, destlen); - } -} - -/* for ngtcp2 data, cidlen); - if(result) - return NGTCP2_ERR_CALLBACK_FAILURE; - cid->datalen = cidlen; - - result = Curl_rand(NULL, token, NGTCP2_STATELESS_RESET_TOKENLEN); - if(result) - return NGTCP2_ERR_CALLBACK_FAILURE; - - return 0; -} - -#ifdef NGTCP2_CALLBACKS_V3 /* ngtcp2 v1.22.0+ */ -static int cb_get_new_connection_id2(ngtcp2_conn *tconn, ngtcp2_cid *cid, - struct ngtcp2_stateless_reset_token *token, size_t cidlen, void *user_data) -{ - CURLcode result; - (void)tconn; - (void)user_data; - - result = Curl_rand(NULL, cid->data, cidlen); - if(result) - return NGTCP2_ERR_CALLBACK_FAILURE; - cid->datalen = cidlen; - - result = Curl_rand(NULL, token->data, sizeof(token->data)); - if(result) - return NGTCP2_ERR_CALLBACK_FAILURE; - - return 0; -} -#endif - -static int cb_recv_rx_key(ngtcp2_conn *tconn, ngtcp2_encryption_level level, - void *user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf ? cf->ctx : NULL; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - (void)tconn; - - if(level != NGTCP2_ENCRYPTION_LEVEL_1RTT) - return 0; - - DEBUGASSERT(ctx); - DEBUGASSERT(data); - if(ctx && data && !ctx->h3conn) { - if(init_ngh3_conn(cf, data)) - return NGTCP2_ERR_CALLBACK_FAILURE; - } - return 0; -} - -#if defined(_MSC_VER) && defined(_DLL) -#pragma warning(push) -#pragma warning(disable:4232) /* MSVC extension, dllimport identity */ -#endif - -static ngtcp2_callbacks ng_callbacks = { - ngtcp2_crypto_client_initial_cb, - NULL, /* recv_client_initial */ - ngtcp2_crypto_recv_crypto_data_cb, - cf_ngtcp2_handshake_completed, - NULL, /* recv_version_negotiation */ - ngtcp2_crypto_encrypt_cb, - ngtcp2_crypto_decrypt_cb, - ngtcp2_crypto_hp_mask_cb, - cb_recv_stream_data, - cb_acked_stream_data_offset, - NULL, /* stream_open */ - cb_stream_close, - NULL, /* recv_stateless_reset */ - ngtcp2_crypto_recv_retry_cb, - cb_extend_max_local_streams_bidi, - NULL, /* extend_max_local_streams_uni */ - cb_rand, - cb_get_new_connection_id, /* for ngtcp2 ctx; - struct pkt_io_ctx local_pktx; - ngtcp2_tstamp expiry; - - if(!pktx) { - pktx_init(&local_pktx, cf, data); - pktx = &local_pktx; - } - else { - pktx_update_time(data, pktx, cf); - } - - expiry = ngtcp2_conn_get_expiry(ctx->qconn); - if(expiry != UINT64_MAX) { - if(expiry <= pktx->ts) { - CURLcode result; - int rv = ngtcp2_conn_handle_expiry(ctx->qconn, pktx->ts); - if(rv) { - failf(data, "ngtcp2_conn_handle_expiry returned error: %s", - ngtcp2_strerror(rv)); - cf_ngtcp2_err_set(cf, data, rv); - return CURLE_SEND_ERROR; - } - result = cf_progress_ingress(cf, data, pktx); - if(result) - return result; - result = cf_progress_egress(cf, data, pktx); - if(result) - return result; - /* ask again, things might have changed */ - expiry = ngtcp2_conn_get_expiry(ctx->qconn); - } - - if(expiry > pktx->ts) { - ngtcp2_duration timeout = expiry - pktx->ts; - if(timeout % NGTCP2_MILLISECONDS) { - timeout += NGTCP2_MILLISECONDS; - } - Curl_expire(data, (timediff_t)(timeout / NGTCP2_MILLISECONDS), - EXPIRE_QUIC); - } - } - return CURLE_OK; -} - -static CURLcode cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - bool want_recv, want_send; - CURLcode result = CURLE_OK; - - if(!ctx->qconn) - return CURLE_OK; - - Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send); - if(!want_send && !Curl_bufq_is_empty(&ctx->q.sendbuf)) - want_send = TRUE; - - if(want_recv || want_send) { - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - struct cf_call_data save; - bool c_exhaust, s_exhaust; - - CF_DATA_SAVE(save, cf, data); - c_exhaust = want_send && (!ngtcp2_conn_get_cwnd_left(ctx->qconn) || - !ngtcp2_conn_get_max_data_left(ctx->qconn)); - s_exhaust = want_send && stream && stream->id >= 0 && - stream->quic_flow_blocked; - want_recv = (want_recv || c_exhaust || s_exhaust); - want_send = (!s_exhaust && want_send) || - !Curl_bufq_is_empty(&ctx->q.sendbuf); - - result = Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send); - CF_DATA_RESTORE(cf, save); - } - return result; -} - -static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, - uint64_t app_error_code, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - (void)conn; - (void)stream_id; - - /* we might be called by nghttp3 after we already cleaned up */ - if(!stream) - return 0; - - stream->closed = TRUE; - stream->error3 = app_error_code; - if(stream->error3 != NGHTTP3_H3_NO_ERROR) { - stream->reset = TRUE; - stream->send_closed = TRUE; - CURL_TRC_CF(data, cf, "[%" PRId64 "] RESET: error %" PRIu64, - stream->id, stream->error3); - } - else { - CURL_TRC_CF(data, cf, "[%" PRId64 "] CLOSED", stream->id); - } - Curl_multi_mark_dirty(data); - return 0; -} - -static void h3_xfer_write_resp_hd(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - const char *buf, size_t blen, bool eos) -{ - /* This function returns no error intentionally, but records - * the result at the stream, skipping further writes once the - * `result` of the transfer is known. - * The stream is subsequently cancelled "higher up" in the filter's - * send/recv callbacks. Closing the stream here leads to SEND/RECV - * errors in other places that then overwrite the transfer's result. */ - if(!stream->xfer_result) { - stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, blen, eos); - if(stream->xfer_result) - CURL_TRC_CF(data, cf, "[%" PRId64 "] error %d writing %zu " - "bytes of headers", stream->id, stream->xfer_result, blen); - } -} - -static void h3_xfer_write_resp(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - const char *buf, size_t blen, bool eos) -{ - /* This function returns no error intentionally, but records - * the result at the stream, skipping further writes once the - * `result` of the transfer is known. - * The stream is subsequently cancelled "higher up" in the filter's - * send/recv callbacks. Closing the stream here leads to SEND/RECV - * errors in other places that then overwrite the transfer's result. */ - if(!stream->xfer_result) { - stream->xfer_result = Curl_xfer_write_resp(data, buf, blen, eos); - /* If the transfer write is errored, we do not want any more data */ - if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%" PRId64 "] error %d writing %zu bytes of data", - stream->id, stream->xfer_result, blen); - } - } -} - -static void cf_ngtcp2_upd_rx_win(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - uint64_t cur_win, wanted_win = H3_STREAM_WINDOW_SIZE_MAX; - - /* how much does rate limiting allow us to acknowledge? */ - if(Curl_rlimit_active(&data->progress.dl.rlimit)) { - int64_t avail; - - /* start rate limit updates only after first bytes arrived */ - if(!stream->rx_offset) - return; - - avail = Curl_rlimit_avail(&data->progress.dl.rlimit, - Curl_pgrs_now(data)); - if(avail <= 0) { - /* nothing available, do not extend the rx offset */ - CURL_TRC_CF(data, cf, "[%" PRId64 "] dl rate limit exhausted (%" PRId64 - " tokens)", stream->id, avail); - return; - } - wanted_win = CURLMIN((uint64_t)avail, H3_STREAM_WINDOW_SIZE_MAX); - } - - if(stream->rx_offset_max < stream->rx_offset) { - DEBUGASSERT(0); - return; - } - cur_win = stream->rx_offset_max - stream->rx_offset; - - if(wanted_win > cur_win) { - uint64_t delta = wanted_win - cur_win; - - if(UINT64_MAX - delta < stream->rx_offset_max) - delta = UINT64_MAX - stream->rx_offset_max; - if(delta) { - CURL_TRC_CF(data, cf, "[%" PRId64 "] rx window, extend by %" PRIu64 - " bytes", stream->id, delta); - stream->rx_offset_max += delta; - ngtcp2_conn_extend_max_stream_offset(ctx->qconn, stream->id, delta); - } - } -} - -static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id, - const uint8_t *buf, size_t blen, - void *user_data, void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - - (void)conn; - (void)stream3_id; - - if(!stream) - return NGHTTP3_ERR_CALLBACK_FAILURE; - - h3_xfer_write_resp(cf, data, stream, (const char *)buf, blen, FALSE); - - ngtcp2_conn_extend_max_offset(ctx->qconn, blen); - stream->rx_offset += blen; - if(stream->rx_offset_max < stream->rx_offset) - stream->rx_offset_max = stream->rx_offset; - - CURL_TRC_CF(data, cf, "[%" PRId64 "] DATA len=%zu, rx win=%" PRIu64, - stream->id, blen, stream->rx_offset_max - stream->rx_offset); - cf_ngtcp2_upd_rx_win(cf, data, stream); - return 0; -} - -static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream3_id, - size_t consumed, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - (void)conn; - - /* nghttp3 has consumed bytes on the QUIC stream and we need to - * tell the QUIC connection to increase its flow control */ - ngtcp2_conn_extend_max_stream_offset(ctx->qconn, stream3_id, consumed); - ngtcp2_conn_extend_max_offset(ctx->qconn, consumed); - if(stream) { - stream->rx_offset += consumed; - stream->rx_offset_max += consumed; - } - return 0; -} - -static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id, - int fin, void *user_data, void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - (void)conn; - (void)stream_id; - (void)fin; - (void)cf; - - if(!stream) - return 0; - /* add a CRLF only if we have received some headers */ - h3_xfer_write_resp_hd(cf, data, stream, STRCONST("\r\n"), - (bool)stream->closed); - - CURL_TRC_CF(data, cf, "[%" PRId64 "] end_headers, status=%d", - stream_id, stream->status_code); - if(stream->status_code / 100 != 1) { - stream->resp_hds_complete = TRUE; - } - Curl_multi_mark_dirty(data); - return 0; -} - -static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, - int32_t token, nghttp3_rcbuf *name, - nghttp3_rcbuf *value, uint8_t flags, - void *user_data, void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name); - nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value); - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - CURLcode result = CURLE_OK; - (void)conn; - (void)stream_id; - (void)token; - (void)flags; - (void)cf; - - /* we might have cleaned up this transfer already */ - if(!stream) - return 0; - - if(token == NGHTTP3_QPACK_TOKEN__STATUS) { - - result = Curl_http_decode_status(&stream->status_code, - (const char *)h3val.base, h3val.len); - if(result) - return NGHTTP3_ERR_CALLBACK_FAILURE; - curlx_dyn_reset(&ctx->scratch); - result = curlx_dyn_addn(&ctx->scratch, STRCONST("HTTP/3 ")); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, - (const char *)h3val.base, h3val.len); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, STRCONST(" \r\n")); - if(!result) - h3_xfer_write_resp_hd(cf, data, stream, curlx_dyn_ptr(&ctx->scratch), - curlx_dyn_len(&ctx->scratch), FALSE); - CURL_TRC_CF(data, cf, "[%" PRId64 "] status: %s", - stream_id, curlx_dyn_ptr(&ctx->scratch)); - if(result) { - return NGHTTP3_ERR_CALLBACK_FAILURE; - } - } - else { - /* store as an HTTP1-style header */ - CURL_TRC_CF(data, cf, "[%" PRId64 "] header: %.*s: %.*s", - stream_id, (int)h3name.len, h3name.base, - (int)h3val.len, h3val.base); - curlx_dyn_reset(&ctx->scratch); - result = curlx_dyn_addn(&ctx->scratch, - (const char *)h3name.base, h3name.len); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, STRCONST(": ")); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, - (const char *)h3val.base, h3val.len); - if(!result) - result = curlx_dyn_addn(&ctx->scratch, STRCONST("\r\n")); - if(!result) - h3_xfer_write_resp_hd(cf, data, stream, curlx_dyn_ptr(&ctx->scratch), - curlx_dyn_len(&ctx->scratch), FALSE); - } - return 0; -} - -static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id, - uint64_t app_error_code, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - int rv; - (void)conn; - (void)stream_user_data; - - rv = ngtcp2_conn_shutdown_stream_read(ctx->qconn, 0, stream_id, - app_error_code); - if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) { - return NGHTTP3_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id, - uint64_t app_error_code, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - int rv; - (void)conn; - - rv = ngtcp2_conn_shutdown_stream_write(ctx->qconn, 0, stream_id, - app_error_code); - CURL_TRC_CF(data, cf, "[%" PRId64 "] reset -> %d", stream_id, rv); - if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) { - return NGHTTP3_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static nghttp3_callbacks ngh3_callbacks = { - cb_h3_acked_req_body, /* acked_stream_data */ - cb_h3_stream_close, - cb_h3_recv_data, - cb_h3_deferred_consume, - NULL, /* begin_headers */ - cb_h3_recv_header, - cb_h3_end_headers, - NULL, /* begin_trailers */ - cb_h3_recv_header, - NULL, /* end_trailers */ - cb_h3_stop_sending, - NULL, /* end_stream */ - cb_h3_reset_stream, - NULL, /* shutdown */ - NULL, /* recv_settings (deprecated) */ -#ifdef NGHTTP3_CALLBACKS_V2 /* nghttp3 v1.11.0+ */ - NULL, /* recv_origin */ - NULL, /* end_origin */ - NULL, /* rand */ -#endif -#ifdef NGHTTP3_CALLBACKS_V3 /* nghttp3 v1.14.0+ */ - NULL, /* recv_settings2 */ -#endif -}; - -static CURLcode init_ngh3_conn(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id; - int rc; - - if(ngtcp2_conn_get_streams_uni_left(ctx->qconn) < 3) { - failf(data, "QUIC connection lacks 3 uni streams to run HTTP/3"); - return CURLE_QUIC_CONNECT_ERROR; - } - - nghttp3_settings_default(&ctx->h3settings); - - rc = nghttp3_conn_client_new(&ctx->h3conn, - &ngh3_callbacks, - &ctx->h3settings, - Curl_nghttp3_mem(), - cf); - if(rc) { - failf(data, "error creating nghttp3 connection instance"); - return CURLE_OUT_OF_MEMORY; - } - - rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &ctrl_stream_id, NULL); - if(rc) { - failf(data, "error creating HTTP/3 control stream: %s", - ngtcp2_strerror(rc)); - return CURLE_QUIC_CONNECT_ERROR; - } - - rc = nghttp3_conn_bind_control_stream(ctx->h3conn, ctrl_stream_id); - if(rc) { - failf(data, "error binding HTTP/3 control stream: %s", - ngtcp2_strerror(rc)); - return CURLE_QUIC_CONNECT_ERROR; - } - - rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &qpack_enc_stream_id, NULL); - if(rc) { - failf(data, "error creating HTTP/3 qpack encoding stream: %s", - ngtcp2_strerror(rc)); - return CURLE_QUIC_CONNECT_ERROR; - } - - rc = ngtcp2_conn_open_uni_stream(ctx->qconn, &qpack_dec_stream_id, NULL); - if(rc) { - failf(data, "error creating HTTP/3 qpack decoding stream: %s", - ngtcp2_strerror(rc)); - return CURLE_QUIC_CONNECT_ERROR; - } - - rc = nghttp3_conn_bind_qpack_streams(ctx->h3conn, qpack_enc_stream_id, - qpack_dec_stream_id); - if(rc) { - failf(data, "error binding HTTP/3 qpack streams: %s", - ngtcp2_strerror(rc)); - return CURLE_QUIC_CONNECT_ERROR; - } - - return CURLE_OK; -} - -static CURLcode recv_closed_stream(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - size_t *pnread) -{ - (void)cf; - *pnread = 0; - if(stream->reset) { - if(stream->error3 == CURL_H3_ERR_REQUEST_REJECTED) { - infof(data, "HTTP/3 stream %" PRId64 " refused by server, try again " - "on a new connection", stream->id); - connclose(cf->conn, "REFUSED_STREAM"); /* do not use this anymore */ - data->state.refused_stream = TRUE; - return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ - } - else if(stream->resp_hds_complete && data->req.no_body) { - CURL_TRC_CF(data, cf, "[%" PRId64 "] error after response headers, " - "but we did not want a body anyway, ignore error 0x%" - PRIx64 " %s", stream->id, stream->error3, - vquic_h3_err_str(stream->error3)); - return CURLE_OK; - } - failf(data, "HTTP/3 stream %" PRId64 " reset by server (error 0x%" PRIx64 - " %s)", stream->id, stream->error3, - vquic_h3_err_str(stream->error3)); - return data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3; - } - else if(!stream->resp_hds_complete) { - failf(data, - "HTTP/3 stream %" PRId64 " was closed cleanly, but before " - "getting all response header fields, treated as error", - stream->id); - return CURLE_HTTP3; - } - return CURLE_OK; -} - -/* incoming data frames on the h3 stream */ -static CURLcode cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t blen, size_t *pnread) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - struct cf_call_data save; - struct pkt_io_ctx pktx; - CURLcode result = CURLE_OK; - int i; - - (void)ctx; - (void)buf; - NOVERBOSE((void)blen); - - CF_DATA_SAVE(save, cf, data); - DEBUGASSERT(cf->connected); - DEBUGASSERT(ctx); - DEBUGASSERT(ctx->qconn); - DEBUGASSERT(ctx->h3conn); - *pnread = 0; - - /* handshake verification failed in callback, do not recv anything */ - if(ctx->tls_vrfy_result) { - result = ctx->tls_vrfy_result; - goto denied; - } - - pktx_init(&pktx, cf, data); - - if(!stream || ctx->shutdown_started) { - result = CURLE_RECV_ERROR; - goto out; - } - - cf_ngtcp2_upd_rx_win(cf, data, stream); - - /* first check for results/closed already known without touching - * the connection. For an already failed/closed stream, errors on - * the connection do not count. - * Then handle incoming data and check for failed/closed again. - */ - for(i = 0; i < 2; ++i) { - if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%" PRId64 "] xfer write failed", stream->id); - cf_ngtcp2_stream_close(cf, data, stream); - result = stream->xfer_result; - goto out; - } - else if(stream->closed) { - result = recv_closed_stream(cf, data, stream, pnread); - goto out; - } - - if(!i && cf_progress_ingress(cf, data, &pktx)) { - result = CURLE_RECV_ERROR; - goto out; - } - } - - result = CURLE_AGAIN; - -out: - result = Curl_1st_fatal(result, cf_progress_egress(cf, data, &pktx)); - result = Curl_1st_fatal(result, check_and_set_expiry(cf, data, &pktx)); -denied: - CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_recv(blen=%zu) -> %d, %zu", - stream ? stream->id : -1, blen, result, *pnread); - CF_DATA_RESTORE(cf, save); - return result; -} - -static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id, - uint64_t datalen, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - size_t skiplen; - - (void)cf; - if(!stream) - return 0; - /* The server acknowledged `datalen` of bytes from our request body. - * This is a delta. We have kept this data in `sendbuf` for - * re-transmissions and can free it now. */ - if(datalen >= (uint64_t)stream->sendbuf_len_in_flight) - skiplen = stream->sendbuf_len_in_flight; - else - skiplen = (size_t)datalen; - Curl_bufq_skip(&stream->sendbuf, skiplen); - stream->sendbuf_len_in_flight -= skiplen; - - /* Resume upload processing if we have more data to send */ - if(stream->sendbuf_len_in_flight < Curl_bufq_len(&stream->sendbuf)) { - int rv = nghttp3_conn_resume_stream(conn, stream_id); - if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { - return NGHTTP3_ERR_CALLBACK_FAILURE; - } - } - return 0; -} - -static nghttp3_ssize cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id, - nghttp3_vec *vec, size_t veccnt, - uint32_t *pflags, void *user_data, - void *stream_user_data) -{ - struct Curl_cfilter *cf = user_data; - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = stream_user_data; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - ssize_t nwritten = 0; - size_t nvecs = 0; - (void)cf; - (void)conn; - (void)stream_id; - (void)user_data; - (void)veccnt; - - if(!stream) - return NGHTTP3_ERR_CALLBACK_FAILURE; - /* nghttp3 keeps references to the sendbuf data until it is ACKed - * by the server (see `cb_h3_acked_req_body()` for updates). - * `sendbuf_len_in_flight` is the amount of bytes in `sendbuf` - * that we have already passed to nghttp3, but which have not been - * ACKed yet. - * Any amount beyond `sendbuf_len_in_flight` we need still to pass - * to nghttp3. Do that now, if we can. */ - if(stream->sendbuf_len_in_flight < Curl_bufq_len(&stream->sendbuf)) { - nvecs = 0; - while(nvecs < veccnt && - Curl_bufq_peek_at(&stream->sendbuf, - stream->sendbuf_len_in_flight, - CURL_UNCONST(&vec[nvecs].base), - &vec[nvecs].len)) { - stream->sendbuf_len_in_flight += vec[nvecs].len; - nwritten += vec[nvecs].len; - ++nvecs; - } - DEBUGASSERT(nvecs > 0); /* we SHOULD have been be able to peek */ - } - - if(nwritten > 0 && stream->upload_left != -1) - stream->upload_left -= nwritten; - - /* When we stopped sending and everything in `sendbuf` is "in flight", - * we are at the end of the request body. */ - if(stream->upload_left == 0) { - *pflags = NGHTTP3_DATA_FLAG_EOF; - stream->send_closed = TRUE; - } - else if(!nwritten) { - /* Not EOF, and nothing to give, we signal WOULDBLOCK. */ - CURL_TRC_CF(data, cf, "[%" PRId64 "] read req body -> AGAIN", stream->id); - return NGHTTP3_ERR_WOULDBLOCK; - } - - CURL_TRC_CF(data, cf, "[%" PRId64 "] read req body -> " - "%d vecs%s with %zd (buffered=%zu, left=%" FMT_OFF_T ")", - stream->id, (int)nvecs, - *pflags == NGHTTP3_DATA_FLAG_EOF ? " EOF" : "", - nwritten, Curl_bufq_len(&stream->sendbuf), - stream->upload_left); - return (nghttp3_ssize)nvecs; -} - -static CURLcode h3_stream_open(struct Curl_cfilter *cf, - struct Curl_easy *data, - const uint8_t *buf, size_t len, - size_t *pnwritten) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = NULL; - int64_t sid; - struct dynhds h2_headers; - size_t nheader; - nghttp3_nv *nva = NULL; - int rc = 0; - unsigned int i; - nghttp3_data_reader reader; - nghttp3_data_reader *preader = NULL; - CURLcode result; - - *pnwritten = 0; - Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); - - result = h3_data_setup(cf, data); - if(result) - goto out; - stream = H3_STREAM_CTX(ctx, data); - DEBUGASSERT(stream); - if(!stream) { - result = CURLE_FAILED_INIT; - goto out; - } - - result = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, - !data->state.http_ignorecustom ? - data->set.str[STRING_CUSTOMREQUEST] : NULL, - 0, pnwritten); - if(result) - goto out; - if(!stream->h1.done) { - /* need more data */ - goto out; - } - DEBUGASSERT(stream->h1.req); - - result = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); - if(result) - goto out; - - /* no longer needed */ - Curl_h1_req_parse_free(&stream->h1); - - nheader = Curl_dynhds_count(&h2_headers); - nva = curlx_malloc(sizeof(nghttp3_nv) * nheader); - if(!nva) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - for(i = 0; i < nheader; ++i) { - struct dynhds_entry *e = Curl_dynhds_getn(&h2_headers, i); - nva[i].name = (unsigned char *)e->name; - nva[i].namelen = e->namelen; - nva[i].value = (unsigned char *)e->value; - nva[i].valuelen = e->valuelen; - nva[i].flags = NGHTTP3_NV_FLAG_NONE; - } - - rc = ngtcp2_conn_open_bidi_stream(ctx->qconn, &sid, data); - if(rc) { - failf(data, "can get bidi streams"); - result = CURLE_SEND_ERROR; - goto out; - } - stream->id = sid; - ++ctx->used_bidi_streams; - - switch(data->state.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_POST_MIME: - case HTTPREQ_PUT: - /* known request body size or -1 */ - if(data->state.infilesize != -1) - stream->upload_left = data->state.infilesize; - else - /* data sending without specifying the data amount up front */ - stream->upload_left = -1; /* unknown */ - break; - default: - /* there is not request body */ - stream->upload_left = 0; /* no request body */ - break; - } - - stream->send_closed = (stream->upload_left == 0); - if(!stream->send_closed) { - reader.read_data = cb_h3_read_req_body; - preader = &reader; - } - - rc = nghttp3_conn_submit_request(ctx->h3conn, stream->id, - nva, nheader, preader, data); - if(rc) { - switch(rc) { - case NGHTTP3_ERR_CONN_CLOSING: - CURL_TRC_CF(data, cf, "h3sid[%" PRId64 "] failed to send, " - "connection is closing", stream->id); - break; - default: - CURL_TRC_CF(data, cf, "h3sid[%" PRId64 "] failed to send -> " - "%d (%s)", stream->id, rc, nghttp3_strerror(rc)); - break; - } - cf_ngtcp2_stream_close(cf, data, stream); - result = CURLE_SEND_ERROR; - goto out; - } - - cf_ngtcp2_upd_rx_win(cf, data, stream); - - if(Curl_trc_is_verbose(data)) { - infof(data, "[HTTP/3] [%" PRId64 "] OPENED stream for %s", - stream->id, Curl_bufref_ptr(&data->state.url)); - for(i = 0; i < nheader; ++i) { - infof(data, "[HTTP/3] [%" PRId64 "] [%.*s: %.*s]", stream->id, - (int)nva[i].namelen, nva[i].name, - (int)nva[i].valuelen, nva[i].value); - } - } - -out: - curlx_free(nva); - Curl_dynhds_free(&h2_headers); - return result; -} - -static CURLcode cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - struct cf_call_data save; - struct pkt_io_ctx pktx; - CURLcode result = CURLE_OK; - - CF_DATA_SAVE(save, cf, data); - DEBUGASSERT(cf->connected); - DEBUGASSERT(ctx->qconn); - DEBUGASSERT(ctx->h3conn); - pktx_init(&pktx, cf, data); - *pnwritten = 0; - - /* handshake verification failed in callback, do not send anything */ - if(ctx->tls_vrfy_result) { - result = ctx->tls_vrfy_result; - goto denied; - } - - (void)eos; /* use for stream EOF and block handling */ - result = cf_progress_ingress(cf, data, &pktx); - if(result) - goto out; - - if(!stream || stream->id < 0) { - if(ctx->shutdown_started) { - CURL_TRC_CF(data, cf, "cannot open stream on closed connection"); - result = CURLE_SEND_ERROR; - goto out; - } - result = h3_stream_open(cf, data, buf, len, pnwritten); - if(result) { - CURL_TRC_CF(data, cf, "failed to open stream -> %d", result); - goto out; - } - VERBOSE(stream = H3_STREAM_CTX(ctx, data)); - } - else if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%" PRId64 "] xfer write failed", stream->id); - cf_ngtcp2_stream_close(cf, data, stream); - result = stream->xfer_result; - goto out; - } - else if(stream->closed) { - if(stream->resp_hds_complete) { - /* Server decided to close the stream after having sent us a final - * response. This is valid if it is not interested in the request - * body. This happens on 30x or 40x responses. - * We silently discard the data sent, since this is not a transport - * error situation. */ - CURL_TRC_CF(data, cf, "[%" PRId64 "] discarding data" - "on closed stream with response", stream->id); - result = CURLE_OK; - *pnwritten = len; - goto out; - } - CURL_TRC_CF(data, cf, "[%" PRId64 "] send_body(len=%zu) " - "-> stream closed", stream->id, len); - result = CURLE_HTTP3; - goto out; - } - else if(ctx->shutdown_started) { - CURL_TRC_CF(data, cf, "cannot send on closed connection"); - result = CURLE_SEND_ERROR; - goto out; - } - else { - result = Curl_bufq_write(&stream->sendbuf, buf, len, pnwritten); - CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_send, add to " - "sendbuf(len=%zu) -> %d, %zu", - stream->id, len, result, *pnwritten); - if(result) - goto out; - (void)nghttp3_conn_resume_stream(ctx->h3conn, stream->id); - } - - if(*pnwritten > 0 && !ctx->tls_handshake_complete && ctx->use_earlydata) - ctx->earlydata_skip += *pnwritten; - - DEBUGASSERT(!result); - result = cf_progress_egress(cf, data, &pktx); - -out: - result = Curl_1st_fatal(result, check_and_set_expiry(cf, data, &pktx)); -denied: - CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_send(len=%zu) -> %d, %zu", - stream ? stream->id : -1, len, result, *pnwritten); - CF_DATA_RESTORE(cf, save); - return result; -} - -struct cf_ngtcp2_recv_ctx { - struct pkt_io_ctx *pktx; - size_t pkt_count; -}; - -static CURLcode cf_ngtcp2_recv_pkts(const unsigned char *buf, size_t buflen, - size_t gso_size, - struct sockaddr_storage *remote_addr, - socklen_t remote_addrlen, int ecn, - void *userp) -{ - struct cf_ngtcp2_recv_ctx *rctx = userp; - struct pkt_io_ctx *pktx = rctx->pktx; - struct cf_ngtcp2_ctx *ctx = pktx->cf->ctx; - ngtcp2_pkt_info pi; - ngtcp2_path path; - size_t offset, pktlen; - int rv; - - if(!rctx->pkt_count) { - pktx_update_time(pktx->data, pktx, pktx->cf); - ngtcp2_path_storage_zero(&pktx->ps); - } - - if(ecn) - CURL_TRC_CF(pktx->data, pktx->cf, "vquic_recv(len=%zu, gso=%zu, ecn=%x)", - buflen, gso_size, ecn); - ngtcp2_addr_init(&path.local, (struct sockaddr *)&ctx->q.local_addr, - ctx->q.local_addrlen); - ngtcp2_addr_init(&path.remote, (struct sockaddr *)remote_addr, - remote_addrlen); - pi.ecn = (uint8_t)ecn; - - for(offset = 0; offset < buflen; offset += gso_size) { - rctx->pkt_count++; - pktlen = ((offset + gso_size) <= buflen) ? gso_size : (buflen - offset); - rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, - buf + offset, pktlen, pktx->ts); - if(rv) { - CURL_TRC_CF(pktx->data, pktx->cf, "ingress, read_pkt -> %s (%d)", - ngtcp2_strerror(rv), rv); - cf_ngtcp2_err_set(pktx->cf, pktx->data, rv); - - if(rv == NGTCP2_ERR_CRYPTO) - /* this is a "TLS problem", but a failed certificate verification - is a common reason for this */ - return CURLE_PEER_FAILED_VERIFICATION; - return CURLE_RECV_ERROR; - } - } - return CURLE_OK; -} - -static CURLcode cf_progress_ingress(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct pkt_io_ctx *pktx) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct pkt_io_ctx local_pktx; - struct cf_ngtcp2_recv_ctx rctx; - CURLcode result = CURLE_OK; - - if(!pktx) { - pktx_init(&local_pktx, cf, data); - pktx = &local_pktx; - } - - result = Curl_vquic_tls_before_recv(&ctx->tls, cf, data); - if(result) - return result; - - rctx.pktx = pktx; - rctx.pkt_count = 0; - return vquic_recv_packets(cf, data, &ctx->q, 1000, - cf_ngtcp2_recv_pkts, &rctx); -} - -/** - * Read a network packet to send from ngtcp2 into `buf`. - * Return number of bytes written or -1 with *err set. - */ -static CURLcode read_pkt_to_send(void *userp, - unsigned char *buf, size_t buflen, - size_t *pnread) -{ - struct pkt_io_ctx *x = userp; - struct cf_ngtcp2_ctx *ctx = x->cf->ctx; - nghttp3_vec vec[16]; - nghttp3_ssize veccnt; - ngtcp2_ssize ndatalen; - uint32_t flags; - int64_t stream_id; - int fin; - ssize_t n; - - *pnread = 0; - veccnt = 0; - stream_id = -1; - fin = 0; - - /* ngtcp2 may want to put several frames from different streams into - * this packet. `NGTCP2_WRITE_STREAM_FLAG_MORE` tells it to do so. - * When `NGTCP2_ERR_WRITE_MORE` is returned, we *need* to make - * another iteration. - * When ngtcp2 is happy (because it has no other frame that would fit - * or it has nothing more to send), it returns the total length - * of the assembled packet. This may be 0 if there was nothing to send. */ - for(;;) { - - if(ctx->h3conn && ngtcp2_conn_get_max_data_left(ctx->qconn)) { - veccnt = nghttp3_conn_writev_stream(ctx->h3conn, &stream_id, &fin, vec, - CURL_ARRAYSIZE(vec)); - if(veccnt < 0) { - failf(x->data, "nghttp3_conn_writev_stream returned error: %s", - nghttp3_strerror((int)veccnt)); - cf_ngtcp2_h3_err_set(x->cf, x->data, (int)veccnt); - return CURLE_SEND_ERROR; - } - } - - flags = NGTCP2_WRITE_STREAM_FLAG_MORE | - (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0); - n = ngtcp2_conn_writev_stream(ctx->qconn, &x->ps.path, - NULL, buf, buflen, - &ndatalen, flags, stream_id, - (const ngtcp2_vec *)vec, veccnt, x->ts); - if(n == 0) { - /* nothing to send */ - return CURLE_AGAIN; - } - else if(n < 0) { - switch(n) { - case NGTCP2_ERR_STREAM_DATA_BLOCKED: { - struct h3_stream_ctx *stream; - DEBUGASSERT(ndatalen == -1); - nghttp3_conn_block_stream(ctx->h3conn, stream_id); - CURL_TRC_CF(x->data, x->cf, "[%" PRId64 "] block quic flow", - stream_id); - stream = cf_ngtcp2_get_stream(ctx, stream_id); - if(stream) /* it might be not one of our h3 streams? */ - stream->quic_flow_blocked = TRUE; - n = 0; - break; - } - case NGTCP2_ERR_STREAM_SHUT_WR: - DEBUGASSERT(ndatalen == -1); - nghttp3_conn_shutdown_stream_write(ctx->h3conn, stream_id); - n = 0; - break; - case NGTCP2_ERR_WRITE_MORE: - /* ngtcp2 wants to send more. update the flow of the stream whose data - * is in the buffer and continue */ - DEBUGASSERT(ndatalen >= 0); - n = 0; - break; - default: - DEBUGASSERT(ndatalen == -1); - failf(x->data, "ngtcp2_conn_writev_stream returned error: %s", - ngtcp2_strerror((int)n)); - cf_ngtcp2_err_set(x->cf, x->data, (int)n); - return CURLE_SEND_ERROR; - } - } - - if(ndatalen >= 0) { - /* we add the amount of data bytes to the flow windows */ - int rv = nghttp3_conn_add_write_offset(ctx->h3conn, stream_id, ndatalen); - if(rv) { - failf(x->data, "nghttp3_conn_add_write_offset returned error: %s", - nghttp3_strerror(rv)); - return CURLE_SEND_ERROR; - } - } - - if(n > 0) { - /* packet assembled, leave */ - *pnread = (size_t)n; - return CURLE_OK; - } - } -} - -static CURLcode cf_progress_egress(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct pkt_io_ctx *pktx) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - size_t nread; - size_t max_payload_size, path_max_payload_size; - size_t pktcnt = 0; - size_t gsolen = 0; /* this disables gso until we have a clue */ - size_t send_quantum; - CURLcode curlcode; - struct pkt_io_ctx local_pktx; - - if(!pktx) { - pktx_init(&local_pktx, cf, data); - pktx = &local_pktx; - } - else { - pktx_update_time(data, pktx, cf); - ngtcp2_path_storage_zero(&pktx->ps); - } - - curlcode = vquic_flush(cf, data, &ctx->q); - if(curlcode) { - if(curlcode == CURLE_AGAIN) { - Curl_expire(data, 1, EXPIRE_QUIC); - return CURLE_OK; - } - return curlcode; - } - - /* In UDP, there is a maximum theoretical packet payload length and - * a minimum payload length that is "guaranteed" to work. - * To detect if this minimum payload can be increased, ngtcp2 sends - * now and then a packet payload larger than the minimum. It that - * is ACKed by the peer, both parties know that it works and - * the subsequent packets can use a larger one. - * This is called PMTUD (Path Maximum Transmission Unit Discovery). - * Since a PMTUD might be rejected right on send, we do not want it - * be followed by other packets of lesser size. Because those would - * also fail then. If we detect a PMTUD while buffering, we flush. - */ - max_payload_size = ngtcp2_conn_get_max_tx_udp_payload_size(ctx->qconn); - path_max_payload_size = - ngtcp2_conn_get_path_max_tx_udp_payload_size(ctx->qconn); - send_quantum = ngtcp2_conn_get_send_quantum(ctx->qconn); - CURL_TRC_CF(data, cf, "egress, collect and send packets, quantum=%zu", - send_quantum); - for(;;) { - /* add the next packet to send, if any, to our buffer */ - curlcode = Curl_bufq_sipn(&ctx->q.sendbuf, max_payload_size, - read_pkt_to_send, pktx, &nread); - if(curlcode == CURLE_AGAIN) - break; - else if(curlcode) - return curlcode; - else { - size_t buflen = Curl_bufq_len(&ctx->q.sendbuf); - if((buflen >= send_quantum) || - ((buflen + gsolen) >= ctx->q.sendbuf.chunk_size)) - break; - DEBUGASSERT(nread > 0); - ++pktcnt; - if(pktcnt == 1) { - /* first packet in buffer. This is either of a known, "good" - * payload size or it is a PMTUD. We shall see. */ - gsolen = nread; - } - else if(nread > gsolen || - (gsolen > path_max_payload_size && nread != gsolen)) { - /* The added packet is a PMTUD *or* the one(s) before the - * added were PMTUD and the last one is smaller. - * Flush the buffer before the last add. */ - curlcode = vquic_send_tail_split(cf, data, &ctx->q, - gsolen, nread, nread); - if(curlcode) { - if(curlcode == CURLE_AGAIN) { - Curl_expire(data, 1, EXPIRE_QUIC); - return CURLE_OK; - } - return curlcode; - } - pktcnt = 0; - } - else if(nread < gsolen) { - /* Reached capacity of our buffer *or* - * last add was shorter than the previous ones, flush */ - break; - } - } - } - - if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) { - /* time to send */ - CURL_TRC_CF(data, cf, "egress, send collected %zu packets in %zu bytes", - pktcnt, Curl_bufq_len(&ctx->q.sendbuf)); - curlcode = vquic_send(cf, data, &ctx->q, gsolen); - if(curlcode) { - if(curlcode == CURLE_AGAIN) { - Curl_expire(data, 1, EXPIRE_QUIC); - return CURLE_OK; - } - return curlcode; - } - pktx_update_time(data, pktx, cf); - ngtcp2_conn_update_pkt_tx_time(ctx->qconn, pktx->ts); - } - return CURLE_OK; -} - -static CURLcode h3_data_pause(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool pause) -{ - /* There seems to exist no API in ngtcp2 to shrink/enlarge the streams - * windows. As we do in HTTP/2. */ - (void)cf; - if(!pause) - Curl_multi_mark_dirty(data); - return CURLE_OK; -} - -static CURLcode cf_ngtcp2_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - (void)arg1; - (void)arg2; - switch(event) { - case CF_CTRL_DATA_SETUP: - break; - case CF_CTRL_DATA_PAUSE: - result = h3_data_pause(cf, data, (arg1 != 0)); - break; - case CF_CTRL_DATA_DONE: - h3_data_done(cf, data); - break; - case CF_CTRL_DATA_DONE_SEND: { - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - if(stream && !stream->send_closed) { - stream->send_closed = TRUE; - stream->upload_left = Curl_bufq_len(&stream->sendbuf) - - stream->sendbuf_len_in_flight; - (void)nghttp3_conn_resume_stream(ctx->h3conn, stream->id); - } - break; - } - case CF_CTRL_CONN_INFO_UPDATE: - if(!cf->sockindex && cf->connected) { - cf->conn->httpversion_seen = 30; - Curl_conn_set_multiplex(cf->conn); - } - break; - default: - break; - } - CF_DATA_RESTORE(cf, save); - return result; -} - -static void cf_ngtcp2_ctx_close(struct cf_ngtcp2_ctx *ctx) -{ - struct cf_call_data save = ctx->call_data; - - if(!ctx->initialized) - return; - if(ctx->qlogfd != -1) { - curlx_close(ctx->qlogfd); - } - ctx->qlogfd = -1; - Curl_vquic_tls_cleanup(&ctx->tls); - vquic_ctx_free(&ctx->q); - if(ctx->h3conn) { - nghttp3_conn_del(ctx->h3conn); - ctx->h3conn = NULL; - } - if(ctx->qconn) { - ngtcp2_conn_del(ctx->qconn); - ctx->qconn = NULL; - } -#ifdef OPENSSL_QUIC_API2 - if(ctx->ossl_ctx) { - ngtcp2_crypto_ossl_ctx_del(ctx->ossl_ctx); - ctx->ossl_ctx = NULL; - } -#endif - ctx->call_data = save; -} - -static CURLcode cf_ngtcp2_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct cf_call_data save; - struct pkt_io_ctx pktx; - CURLcode result = CURLE_OK; - - if(cf->shutdown || !ctx->qconn) { - *done = TRUE; - return CURLE_OK; - } - - CF_DATA_SAVE(save, cf, data); - *done = FALSE; - pktx_init(&pktx, cf, data); - - if(!ctx->shutdown_started) { - char buffer[NGTCP2_MAX_UDP_PAYLOAD_SIZE]; - ngtcp2_ssize nwritten; - - if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) { - CURL_TRC_CF(data, cf, "shutdown, flushing sendbuf"); - result = cf_progress_egress(cf, data, &pktx); - if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) { - CURL_TRC_CF(data, cf, "sending shutdown packets blocked"); - result = CURLE_OK; - goto out; - } - else if(result) { - CURL_TRC_CF(data, cf, "shutdown, error %d flushing sendbuf", result); - *done = TRUE; - goto out; - } - } - - DEBUGASSERT(Curl_bufq_is_empty(&ctx->q.sendbuf)); - ctx->shutdown_started = TRUE; - nwritten = ngtcp2_conn_write_connection_close( - ctx->qconn, NULL, /* path */ - NULL, /* pkt_info */ - (uint8_t *)buffer, sizeof(buffer), - &ctx->last_error, pktx.ts); - CURL_TRC_CF(data, cf, "start shutdown(err_type=%d, err_code=%" - PRIu64 ") -> %zd", ctx->last_error.type, - ctx->last_error.error_code, (ssize_t)nwritten); - /* there are cases listed in ngtcp2 documentation where this call - * may fail. Since we are doing a connection shutdown as graceful - * as we can, such an error is ignored here. */ - if(nwritten > 0) { - /* Ignore amount written. sendbuf was empty and has always room for - * NGTCP2_MAX_UDP_PAYLOAD_SIZE. It can only completely fail, in which - * case `result` is set non zero. */ - size_t n; - result = Curl_bufq_write(&ctx->q.sendbuf, (const unsigned char *)buffer, - (size_t)nwritten, &n); - if(result) { - CURL_TRC_CF(data, cf, "error %d adding shutdown packets to sendbuf, " - "aborting shutdown", result); - goto out; - } - - ctx->q.no_gso = TRUE; - ctx->q.gsolen = (size_t)nwritten; - ctx->q.split_len = 0; - } - } - - if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) { - CURL_TRC_CF(data, cf, "shutdown, flushing egress"); - result = vquic_flush(cf, data, &ctx->q); - if(result == CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "sending shutdown packets blocked"); - result = CURLE_OK; - goto out; - } - else if(result) { - CURL_TRC_CF(data, cf, "shutdown, error %d flushing sendbuf", result); - *done = TRUE; - goto out; - } - } - - if(Curl_bufq_is_empty(&ctx->q.sendbuf)) { - /* Sent everything off. ngtcp2 seems to have no support for graceful - * shutdowns. We are done. */ - CURL_TRC_CF(data, cf, "shutdown completely sent off, done"); - *done = TRUE; - result = CURLE_OK; - } -out: - CF_DATA_RESTORE(cf, save); - return result; -} - -static void cf_ngtcp2_conn_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - bool done; - cf_ngtcp2_shutdown(cf, data, &done); -} - -static void cf_ngtcp2_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - if(ctx && ctx->qconn) { - cf_ngtcp2_conn_close(cf, data); - cf_ngtcp2_ctx_close(ctx); - CURL_TRC_CF(data, cf, "close"); - } - cf->connected = FALSE; - CF_DATA_RESTORE(cf, save); -} - -static void cf_ngtcp2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - CURL_TRC_CF(data, cf, "destroy"); - if(cf->ctx) { - cf_ngtcp2_close(cf, data); - cf_ngtcp2_ctx_free(cf->ctx); - cf->ctx = NULL; - } -} - -#ifdef USE_OPENSSL -/* The "new session" callback must return zero if the session can be removed - * or non-zero if the session has been put into the session cache. - */ -static int quic_ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) -{ - struct Curl_cfilter *cf; - struct cf_ngtcp2_ctx *ctx; - struct Curl_easy *data; - ngtcp2_crypto_conn_ref *cref; - - cref = (ngtcp2_crypto_conn_ref *)SSL_get_app_data(ssl); - cf = cref ? cref->user_data : NULL; - ctx = cf ? cf->ctx : NULL; - data = cf ? CF_DATA_CURRENT(cf) : NULL; - if(cf && data && ctx) { - unsigned char *quic_tp = NULL; - size_t quic_tp_len = 0; -#ifdef HAVE_OPENSSL_EARLYDATA - ngtcp2_ssize tplen; - uint8_t tpbuf[256]; - - tplen = ngtcp2_conn_encode_0rtt_transport_params(ctx->qconn, tpbuf, - sizeof(tpbuf)); - if(tplen < 0) - CURL_TRC_CF(data, cf, "error encoding 0RTT transport data: %s", - ngtcp2_strerror((int)tplen)); - else { - quic_tp = (unsigned char *)tpbuf; - quic_tp_len = (size_t)tplen; - } -#endif - Curl_ossl_add_session(cf, data, ctx->peer.scache_key, ssl_sessionid, - SSL_version(ssl), "h3", quic_tp, quic_tp_len); - } - return 0; -} -#endif /* USE_OPENSSL */ - -#ifdef USE_GNUTLS - -#ifdef CURLVERBOSE -static const char *gtls_hs_msg_name(int mtype) -{ - switch(mtype) { - case 1: - return "ClientHello"; - case 2: - return "ServerHello"; - case 4: - return "SessionTicket"; - case 8: - return "EncryptedExtensions"; - case 11: - return "Certificate"; - case 13: - return "CertificateRequest"; - case 15: - return "CertificateVerify"; - case 20: - return "Finished"; - case 24: - return "KeyUpdate"; - case 254: - return "MessageHash"; - } - return "Unknown"; -} -#endif - -static int quic_gtls_handshake_cb(gnutls_session_t session, unsigned int htype, - unsigned when, unsigned int incoming, - const gnutls_datum_t *msg) -{ - ngtcp2_crypto_conn_ref *conn_ref = gnutls_session_get_ptr(session); - struct Curl_cfilter *cf = conn_ref ? conn_ref->user_data : NULL; - struct cf_ngtcp2_ctx *ctx = cf ? cf->ctx : NULL; - - (void)msg; - (void)incoming; - if(when && cf && ctx) { /* after message has been processed */ - struct Curl_easy *data = CF_DATA_CURRENT(cf); - DEBUGASSERT(data); - if(!data) - return 0; - CURL_TRC_CF(data, cf, "SSL message: %s %s [%u]", - incoming ? "<-" : "->", gtls_hs_msg_name(htype), htype); - switch(htype) { - case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: { - ngtcp2_ssize tplen; - uint8_t tpbuf[256]; - unsigned char *quic_tp = NULL; - size_t quic_tp_len = 0; - - tplen = ngtcp2_conn_encode_0rtt_transport_params(ctx->qconn, tpbuf, - sizeof(tpbuf)); - if(tplen < 0) - CURL_TRC_CF(data, cf, "error encoding 0RTT transport data: %s", - ngtcp2_strerror((int)tplen)); - else { - quic_tp = (unsigned char *)tpbuf; - quic_tp_len = (size_t)tplen; - } - (void)Curl_gtls_cache_session(cf, data, ctx->peer.scache_key, - session, 0, "h3", quic_tp, quic_tp_len); - break; - } - default: - break; - } - } - return 0; -} -#endif /* USE_GNUTLS */ - -#ifdef USE_WOLFSSL -static int wssl_quic_new_session_cb(WOLFSSL *ssl, WOLFSSL_SESSION *session) -{ - ngtcp2_crypto_conn_ref *conn_ref = wolfSSL_get_app_data(ssl); - struct Curl_cfilter *cf = conn_ref ? conn_ref->user_data : NULL; - - DEBUGASSERT(cf != NULL); - if(cf && session) { - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - DEBUGASSERT(data); - if(data && ctx) { - ngtcp2_ssize tplen; - uint8_t tpbuf[256]; - unsigned char *quic_tp = NULL; - size_t quic_tp_len = 0; - - tplen = ngtcp2_conn_encode_0rtt_transport_params(ctx->qconn, tpbuf, - sizeof(tpbuf)); - if(tplen < 0) - CURL_TRC_CF(data, cf, "error encoding 0RTT transport data: %s", - ngtcp2_strerror((int)tplen)); - else { - quic_tp = (unsigned char *)tpbuf; - quic_tp_len = (size_t)tplen; - } - (void)Curl_wssl_cache_session(cf, data, ctx->peer.scache_key, - session, wolfSSL_version(ssl), - "h3", quic_tp, quic_tp_len); - } - } - return 0; -} -#endif /* USE_WOLFSSL */ - -static CURLcode cf_ngtcp2_tls_ctx_setup(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *user_data) -{ - struct curl_tls_ctx *ctx = user_data; - -#ifdef USE_OPENSSL -#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) - if(ngtcp2_crypto_boringssl_configure_client_context(ctx->ossl.ssl_ctx) - != 0) { - failf(data, "ngtcp2_crypto_boringssl_configure_client_context failed"); - return CURLE_FAILED_INIT; - } -#elif defined(OPENSSL_QUIC_API2) - /* nothing to do */ -#else - if(ngtcp2_crypto_quictls_configure_client_context(ctx->ossl.ssl_ctx) != 0) { - failf(data, "ngtcp2_crypto_quictls_configure_client_context failed"); - return CURLE_FAILED_INIT; - } -#endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */ - if(Curl_ssl_scache_use(cf, data)) { - /* Enable the session cache because it is a prerequisite for the - * "new session" callback. Use the "external storage" mode to prevent - * OpenSSL from creating an internal session cache. - */ - SSL_CTX_set_session_cache_mode(ctx->ossl.ssl_ctx, - SSL_SESS_CACHE_CLIENT | - SSL_SESS_CACHE_NO_INTERNAL); - SSL_CTX_sess_set_new_cb(ctx->ossl.ssl_ctx, quic_ossl_new_session_cb); - } - -#elif defined(USE_GNUTLS) - if(ngtcp2_crypto_gnutls_configure_client_session(ctx->gtls.session) != 0) { - failf(data, "ngtcp2_crypto_gnutls_configure_client_session failed"); - return CURLE_FAILED_INIT; - } - if(Curl_ssl_scache_use(cf, data)) { - gnutls_handshake_set_hook_function(ctx->gtls.session, - GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST, - quic_gtls_handshake_cb); - } - -#elif defined(USE_WOLFSSL) - if(ngtcp2_crypto_wolfssl_configure_client_context(ctx->wssl.ssl_ctx) != 0) { - failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed"); - return CURLE_FAILED_INIT; - } - if(Curl_ssl_scache_use(cf, data)) { - /* Register to get notified when a new session is received */ - wolfSSL_CTX_sess_set_new_cb(ctx->wssl.ssl_ctx, wssl_quic_new_session_cb); - } -#endif - return CURLE_OK; -} - -static CURLcode cf_ngtcp2_on_session_reuse(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - *do_early_data = FALSE; -#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA) - ctx->earlydata_max = scs->earlydata_max; -#endif -#ifdef USE_GNUTLS - ctx->earlydata_max = - gnutls_record_get_max_early_data_size(ctx->tls.gtls.session); -#endif -#ifdef USE_WOLFSSL -#ifdef WOLFSSL_EARLY_DATA - ctx->earlydata_max = scs->earlydata_max; -#else - ctx->earlydata_max = 0; -#endif /* WOLFSSL_EARLY_DATA */ -#endif -#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ - (defined(USE_OPENSSL) && defined(HAVE_OPENSSL_EARLYDATA)) - if(!ctx->earlydata_max) { - CURL_TRC_CF(data, cf, "SSL session does not allow earlydata"); - } - else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) { - CURL_TRC_CF(data, cf, "SSL session from different ALPN, no early data"); - } - else if(!scs->quic_tp || !scs->quic_tp_len) { - CURL_TRC_CF(data, cf, "no 0RTT transport parameters, no early data, "); - } - else { - int rv; - rv = ngtcp2_conn_decode_and_set_0rtt_transport_params( - ctx->qconn, (const uint8_t *)scs->quic_tp, scs->quic_tp_len); - if(rv) - CURL_TRC_CF(data, cf, "no early data, failed to set 0RTT transport " - "parameters: %s", ngtcp2_strerror(rv)); - else { - infof(data, "SSL session allows %zu bytes of early data, " - "reusing ALPN '%s'", ctx->earlydata_max, scs->alpn); - result = init_ngh3_conn(cf, data); - if(!result) { - ctx->use_earlydata = TRUE; - cf->connected = TRUE; - *do_early_data = TRUE; - } - } - } -#else /* not supported in the TLS backend */ - (void)data; - (void)ctx; - (void)scs; - (void)alpns; -#endif - return result; -} - -static bool cf_ngtcp2_need_httpsrr(struct Curl_easy *data) -{ -#ifdef USE_OPENSSL - return Curl_ossl_need_httpsrr(data); -#elif defined(USE_WOLFSSL) - return Curl_wssl_need_httpsrr(data); -#else - (void)data; - return FALSE; -#endif -} - -/* - * Might be called twice for happy eyeballs. - */ -static CURLcode cf_connect_start(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct pkt_io_ctx *pktx) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - int rc; - int rv; - CURLcode result; - const struct Curl_sockaddr_ex *sockaddr = NULL; - int qfd; - static const struct alpn_spec ALPN_SPEC_H3 = { { "h3", "h3-29" }, 2 }; - - DEBUGASSERT(ctx->initialized); - ctx->dcid.datalen = NGTCP2_MAX_CIDLEN; - result = Curl_rand(data, ctx->dcid.data, NGTCP2_MAX_CIDLEN); - if(result) - return result; - - ctx->scid.datalen = NGTCP2_MAX_CIDLEN; - result = Curl_rand(data, ctx->scid.data, NGTCP2_MAX_CIDLEN); - if(result) - return result; - - (void)Curl_qlogdir(data, ctx->scid.data, NGTCP2_MAX_CIDLEN, &qfd); - ctx->qlogfd = qfd; /* -1 if failure above */ - quic_settings(ctx, data, pktx); - - result = vquic_ctx_init(data, &ctx->q); - if(result) - return result; - - if(Curl_cf_socket_peek(cf->next, data, &ctx->q.sockfd, &sockaddr, NULL)) - return CURLE_QUIC_CONNECT_ERROR; - ctx->q.local_addrlen = sizeof(ctx->q.local_addr); - rv = getsockname(ctx->q.sockfd, (struct sockaddr *)&ctx->q.local_addr, - &ctx->q.local_addrlen); - if(rv == -1) - return CURLE_QUIC_CONNECT_ERROR; - - ngtcp2_addr_init(&ctx->connected_path.local, - (struct sockaddr *)&ctx->q.local_addr, - ctx->q.local_addrlen); - ngtcp2_addr_init(&ctx->connected_path.remote, - &sockaddr->curl_sa_addr, (socklen_t)sockaddr->addrlen); - - rc = ngtcp2_conn_client_new(&ctx->qconn, &ctx->dcid, &ctx->scid, - &ctx->connected_path, - NGTCP2_PROTO_VER_V1, &ng_callbacks, - &ctx->settings, &ctx->transport_params, - Curl_ngtcp2_mem(), cf); - if(rc) - return CURLE_QUIC_CONNECT_ERROR; - - ctx->conn_ref.get_conn = get_conn; - ctx->conn_ref.user_data = cf; - - result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer, &ALPN_SPEC_H3, - cf_ngtcp2_tls_ctx_setup, &ctx->tls, - &ctx->conn_ref, - cf_ngtcp2_on_session_reuse); - if(result) - return result; - -#if defined(USE_OPENSSL) && defined(OPENSSL_QUIC_API2) - if(ngtcp2_crypto_ossl_ctx_new(&ctx->ossl_ctx, ctx->tls.ossl.ssl) != 0) { - failf(data, "ngtcp2_crypto_ossl_ctx_new failed"); - return CURLE_FAILED_INIT; - } - ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->ossl_ctx); - if(ngtcp2_crypto_ossl_configure_client_session(ctx->tls.ossl.ssl) != 0) { - failf(data, "ngtcp2_crypto_ossl_configure_client_session failed"); - return CURLE_FAILED_INIT; - } -#elif defined(USE_OPENSSL) - SSL_set_quic_use_legacy_codepoint(ctx->tls.ossl.ssl, 0); - ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.ossl.ssl); -#elif defined(USE_GNUTLS) - ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.gtls.session); -#elif defined(USE_WOLFSSL) - ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.wssl.ssl); -#else -#error "ngtcp2 TLS backend not defined" -#endif - - ngtcp2_ccerr_default(&ctx->last_error); - - return CURLE_OK; -} - -static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - struct cf_call_data save; - struct pkt_io_ctx pktx; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* Connect the UDP filter first */ - if(!cf->next->connected) { - result = Curl_conn_cf_connect(cf->next, data, done); - if(result || !*done) - return result; - } - - *done = FALSE; - - if(cf_ngtcp2_need_httpsrr(data) && - !Curl_conn_dns_resolved_https(data, cf->sockindex)) { - CURL_TRC_CF(data, cf, "need HTTPS-RR, delaying connect"); - return CURLE_OK; - } - - pktx_init(&pktx, cf, data); - CF_DATA_SAVE(save, cf, data); - - if(!ctx->qconn) { - ctx->started_at = *Curl_pgrs_now(data); - result = cf_connect_start(cf, data, &pktx); - if(result) - goto out; - if(cf->connected) { - *done = TRUE; - goto out; - } - result = cf_progress_egress(cf, data, &pktx); - /* we do not expect to be able to recv anything yet */ - goto out; - } - - result = cf_progress_ingress(cf, data, &pktx); - if(result) - goto out; - - result = cf_progress_egress(cf, data, &pktx); - if(result) - goto out; - - if(ngtcp2_conn_get_handshake_completed(ctx->qconn)) { - result = ctx->tls_vrfy_result; - if(!result) { - CURL_TRC_CF(data, cf, "peer verified"); - cf->connected = TRUE; - *done = TRUE; - } - } - -out: - if(ctx->qconn && - ((result == CURLE_RECV_ERROR) || (result == CURLE_SEND_ERROR)) && - ngtcp2_conn_in_draining_period(ctx->qconn)) { - const ngtcp2_ccerr *cerr = ngtcp2_conn_get_ccerr(ctx->qconn); - - result = CURLE_COULDNT_CONNECT; - if(cerr) { - CURL_TRC_CF(data, cf, "connect error, type=%d, code=%" PRIu64, - cerr->type, cerr->error_code); - switch(cerr->type) { - case NGTCP2_CCERR_TYPE_VERSION_NEGOTIATION: - CURL_TRC_CF(data, cf, "error in version negotiation"); - break; - default: - if(cerr->error_code >= NGTCP2_CRYPTO_ERROR) { - CURL_TRC_CF(data, cf, "crypto error, tls alert=%u", - (unsigned int)(cerr->error_code & 0xffU)); - } - else if(cerr->error_code == NGTCP2_CONNECTION_REFUSED) { - CURL_TRC_CF(data, cf, "connection refused by server"); - /* When a QUIC server instance is shutting down, it may send us a - * CONNECTION_CLOSE with this code right away. We want - * to keep on trying in this case. */ - result = CURLE_WEIRD_SERVER_REPLY; - } - } - } - } - -#ifdef CURLVERBOSE - if(result) { - struct ip_quadruple ip; - - if(!Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip)) - infof(data, "QUIC connect to %s port %u failed: %s", - ip.remote_ip, ip.remote_port, curl_easy_strerror(result)); - } -#endif - if(!result && ctx->qconn) { - result = check_and_set_expiry(cf, data, &pktx); - } - if(result || *done) - CURL_TRC_CF(data, cf, "connect -> %d, done=%d", result, *done); - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode cf_ngtcp2_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct cf_call_data save; - - switch(query) { - case CF_QUERY_MAX_CONCURRENT: { - DEBUGASSERT(pres1); - CF_DATA_SAVE(save, cf, data); - /* Set after transport params arrived and continually updated - * by callback. QUIC counts the number over the lifetime of the - * connection, ever increasing. - * We count the *open* transfers plus the budget for new ones. */ - if(!ctx->qconn || ctx->shutdown_started) { - *pres1 = 0; - } - else if(ctx->max_bidi_streams) { - uint64_t avail_bidi_streams = 0; - uint64_t max_streams = cf->conn->attached_xfers; - if(ctx->max_bidi_streams > ctx->used_bidi_streams) - avail_bidi_streams = ctx->max_bidi_streams - ctx->used_bidi_streams; - max_streams += avail_bidi_streams; - *pres1 = (max_streams > INT_MAX) ? INT_MAX : (int)max_streams; - } - else /* transport params not arrived yet? take our default. */ - *pres1 = (int)Curl_multi_max_concurrent_streams(data->multi); - CURL_TRC_CF(data, cf, "query conn[%" FMT_OFF_T "]: " - "MAX_CONCURRENT -> %d (%u in use)", - cf->conn->connection_id, *pres1, cf->conn->attached_xfers); - CF_DATA_RESTORE(cf, save); - return CURLE_OK; - } - case CF_QUERY_CONNECT_REPLY_MS: - if(ctx->q.got_first_byte) { - timediff_t ms = curlx_ptimediff_ms(&ctx->q.first_byte_at, - &ctx->started_at); - *pres1 = (ms < INT_MAX) ? (int)ms : INT_MAX; - } - else - *pres1 = -1; - return CURLE_OK; - case CF_QUERY_TIMER_CONNECT: { - struct curltime *when = pres2; - if(ctx->q.got_first_byte) - *when = ctx->q.first_byte_at; - return CURLE_OK; - } - case CF_QUERY_TIMER_APPCONNECT: { - struct curltime *when = pres2; - if(cf->connected) - *when = ctx->handshake_at; - return CURLE_OK; - } - case CF_QUERY_HTTP_VERSION: - *pres1 = 30; - return CURLE_OK; - case CF_QUERY_SSL_INFO: - case CF_QUERY_SSL_CTX_INFO: { - struct curl_tlssessioninfo *info = pres2; - if(Curl_vquic_tls_get_ssl_info(&ctx->tls, - (query == CF_QUERY_SSL_CTX_INFO), info)) - return CURLE_OK; - break; - } - case CF_QUERY_ALPN_NEGOTIATED: { - const char **palpn = pres2; - DEBUGASSERT(palpn); - *palpn = cf->connected ? "h3" : NULL; - return CURLE_OK; - } - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -static bool cf_ngtcp2_conn_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending) -{ - struct cf_ngtcp2_ctx *ctx = cf->ctx; - bool alive = FALSE; - const ngtcp2_transport_params *rp; - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - *input_pending = FALSE; - if(!ctx->qconn || ctx->shutdown_started) - goto out; - - /* We do not announce a max idle timeout, but when the peer does - * it closes the connection when it expires. */ - rp = ngtcp2_conn_get_remote_transport_params(ctx->qconn); - if(rp && rp->max_idle_timeout) { - timediff_t idletime_ms = - curlx_ptimediff_ms(Curl_pgrs_now(data), &ctx->q.last_io); - if(idletime_ms > 0) { - uint64_t max_idle_ms = - (uint64_t)(rp->max_idle_timeout / NGTCP2_MILLISECONDS); - if((uint64_t)idletime_ms > max_idle_ms) - goto out; - } - } - - if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending)) - goto out; - - alive = TRUE; - if(*input_pending) { - CURLcode result; - /* This happens before we have sent off a request and the connection is - not in use by any other transfer, there should not be any data here, - only "protocol frames" */ - *input_pending = FALSE; - result = cf_progress_ingress(cf, data, NULL); - CURL_TRC_CF(data, cf, "is_alive, progress ingress -> %d", result); - alive = result ? FALSE : TRUE; - } - -out: - CF_DATA_RESTORE(cf, save); - return alive; -} - -struct Curl_cftype Curl_cft_http3 = { - "HTTP/3", - CF_TYPE_IP_CONNECT | CF_TYPE_SSL | CF_TYPE_MULTIPLEX | CF_TYPE_HTTP, - 0, - cf_ngtcp2_destroy, - cf_ngtcp2_connect, - cf_ngtcp2_close, - cf_ngtcp2_shutdown, - cf_ngtcp2_adjust_pollset, - Curl_cf_def_data_pending, - cf_ngtcp2_send, - cf_ngtcp2_recv, - cf_ngtcp2_cntrl, - cf_ngtcp2_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_ngtcp2_query, -}; - -CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr) -{ - struct cf_ngtcp2_ctx *ctx = NULL; - struct Curl_cfilter *cf = NULL; - CURLcode result; - - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - cf_ngtcp2_ctx_init(ctx); - - result = Curl_cf_create(&cf, &Curl_cft_http3, ctx); - if(result) - goto out; - cf->conn = conn; - - result = Curl_cf_udp_create(&cf->next, data, conn, addr, TRNSPRT_QUIC); - if(result) - goto out; - cf->next->conn = cf->conn; - cf->next->sockindex = cf->sockindex; - -out: - *pcf = (!result) ? cf : NULL; - if(result) { - if(cf) - Curl_conn_cf_discard_chain(&cf, data); - else if(ctx) - cf_ngtcp2_ctx_free(ctx); - } - return result; -} - -#endif diff --git a/vendor/curl/lib/vquic/curl_ngtcp2.h b/vendor/curl/lib/vquic/curl_ngtcp2.h deleted file mode 100644 index 185272ace..000000000 --- a/vendor/curl/lib/vquic/curl_ngtcp2.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef HEADER_CURL_VQUIC_CURL_NGTCP2_H -#define HEADER_CURL_VQUIC_CURL_NGTCP2_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NGTCP2) && defined(USE_NGHTTP3) - -#ifdef HAVE_NETINET_UDP_H -#include -#endif - -#include -#ifdef OPENSSL_QUIC_API2 -#include -#endif -#include -#ifdef USE_OPENSSL -#include -#elif defined(USE_WOLFSSL) -#include -#include -#include -#endif - -struct Curl_cfilter; - -#include "urldata.h" - -void Curl_ngtcp2_ver(char *p, size_t len); - -CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr); -#endif - -#endif /* HEADER_CURL_VQUIC_CURL_NGTCP2_H */ diff --git a/vendor/curl/lib/vquic/curl_quiche.c b/vendor/curl/lib/vquic/curl_quiche.c deleted file mode 100644 index 73f664a65..000000000 --- a/vendor/curl/lib/vquic/curl_quiche.c +++ /dev/null @@ -1,1679 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_QUICHE) -#include -#include -#include - -#include "bufq.h" -#include "uint-hash.h" -#include "urldata.h" -#include "cfilters.h" -#include "cf-dns.h" -#include "cf-socket.h" -#include "curl_trc.h" -#include "rand.h" -#include "multiif.h" -#include "connect.h" -#include "progress.h" -#include "select.h" -#include "http1.h" -#include "vquic/vquic.h" -#include "vquic/vquic_int.h" -#include "vquic/vquic-tls.h" -#include "vquic/curl_quiche.h" -#include "transfer.h" -#include "url.h" -#include "bufref.h" -#include "vtls/openssl.h" -#include "vtls/vtls.h" - -/* HTTP/3 error values defined in RFC 9114, ch. 8.1 */ -#define CURL_H3_NO_ERROR 0x0100 - -#define MAX_PKT_BURST 10 - -#define QUIC_MAX_STREAMS 100 - -#define H3_STREAM_WINDOW_SIZE (1024 * 128) -#define H3_STREAM_CHUNK_SIZE (1024 * 16) -/* Receive and Send max number of chunks follows from the - * chunk size and window size */ -#define H3_STREAM_RECV_CHUNKS \ - (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE) - -/* - * Store quiche version info in this buffer. - */ -void Curl_quiche_ver(char *p, size_t len) -{ - (void)curl_msnprintf(p, len, "quiche/%s", quiche_version()); -} - -struct cf_quiche_ctx { - struct cf_quic_ctx q; - struct ssl_peer peer; - struct curl_tls_ctx tls; - quiche_conn *qconn; - quiche_config *cfg; - quiche_h3_conn *h3c; - quiche_h3_config *h3config; - uint8_t scid[QUICHE_MAX_CONN_ID_LEN]; - struct curltime started_at; /* time the current attempt started */ - struct curltime handshake_at; /* time connect handshake finished */ - struct uint_hash streams; /* hash `data->mid` to `stream_ctx` */ - struct dynbuf h1hdr; /* temp buffer for header construction */ - struct bufq writebuf; /* temp buffer for writing bodies */ - curl_off_t data_recvd; - BIT(initialized); - BIT(goaway); /* got GOAWAY from server */ - BIT(x509_store_setup); /* if x509 store has been set up */ - BIT(shutdown_started); /* queued shutdown packets */ -}; - -#ifdef DEBUG_QUICHE -/* initialize debug log callback only once */ -static int debug_log_init = 0; -static void quiche_debug_log(const char *line, void *argp) -{ - (void)argp; - curl_mfprintf(stderr, "%s\n", line); -} -#endif - -static void h3_stream_hash_free(unsigned int id, void *stream); - -static void cf_quiche_ctx_init(struct cf_quiche_ctx *ctx) -{ - DEBUGASSERT(!ctx->initialized); -#ifdef DEBUG_QUICHE - if(!debug_log_init) { - quiche_enable_debug_logging(quiche_debug_log, NULL); - debug_log_init = 1; - } -#endif - curlx_dyn_init(&ctx->h1hdr, CURL_MAX_HTTP_HEADER); - Curl_uint32_hash_init(&ctx->streams, 63, h3_stream_hash_free); - Curl_bufq_init2(&ctx->writebuf, H3_STREAM_CHUNK_SIZE, H3_STREAM_RECV_CHUNKS, - BUFQ_OPT_SOFT_LIMIT); - ctx->data_recvd = 0; - ctx->initialized = TRUE; -} - -static void cf_quiche_ctx_free(struct cf_quiche_ctx *ctx) -{ - if(ctx && ctx->initialized) { - /* quiche freed it */ - ctx->tls.ossl.ssl = NULL; - Curl_vquic_tls_cleanup(&ctx->tls); - Curl_ssl_peer_cleanup(&ctx->peer); - vquic_ctx_free(&ctx->q); - Curl_uint32_hash_destroy(&ctx->streams); - curlx_dyn_free(&ctx->h1hdr); - Curl_bufq_free(&ctx->writebuf); - } - curlx_free(ctx); -} - -static void cf_quiche_ctx_close(struct cf_quiche_ctx *ctx) -{ - if(ctx->h3c) { - quiche_h3_conn_free(ctx->h3c); - ctx->h3c = NULL; - } - if(ctx->h3config) { - quiche_h3_config_free(ctx->h3config); - ctx->h3config = NULL; - } - if(ctx->qconn) { - quiche_conn_free(ctx->qconn); - ctx->qconn = NULL; - } - if(ctx->cfg) { - quiche_config_free(ctx->cfg); - ctx->cfg = NULL; - } -} - -static CURLcode cf_flush_egress(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/** - * All about the H3 internals of a stream - */ -struct h3_stream_ctx { - uint64_t id; /* HTTP/3 protocol stream identifier */ - struct h1_req_parser h1; /* h1 request parsing */ - uint64_t error3; /* HTTP/3 stream error code */ - int status_code; /* HTTP status code */ - CURLcode xfer_result; /* result from cf_quiche_write_(hd/body) */ - BIT(opened); /* TRUE after stream has been opened */ - BIT(closed); /* TRUE on stream close */ - BIT(reset); /* TRUE on stream reset */ - BIT(send_closed); /* stream is locally closed */ - BIT(resp_hds_complete); /* final response has been received */ - BIT(resp_got_header); /* TRUE when h3 stream has recvd some HEADER */ - BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */ -}; - -static void h3_stream_ctx_free(struct h3_stream_ctx *stream) -{ - Curl_h1_req_parse_free(&stream->h1); - curlx_free(stream); -} - -static void h3_stream_hash_free(unsigned int id, void *stream) -{ - (void)id; - DEBUGASSERT(stream); - h3_stream_ctx_free((struct h3_stream_ctx *)stream); -} - -typedef bool cf_quiche_svisit(struct Curl_cfilter *cf, - struct Curl_easy *sdata, - struct h3_stream_ctx *stream, - void *user_data); - -struct cf_quiche_visit_ctx { - struct Curl_cfilter *cf; - struct Curl_multi *multi; - cf_quiche_svisit *cb; - void *user_data; -}; - -static bool cf_quiche_stream_do(uint32_t mid, void *val, void *user_data) -{ - struct cf_quiche_visit_ctx *vctx = user_data; - struct h3_stream_ctx *stream = val; - struct Curl_easy *sdata = Curl_multi_get_easy(vctx->multi, mid); - if(sdata) - return vctx->cb(vctx->cf, sdata, stream, vctx->user_data); - return TRUE; -} - -static void cf_quiche_for_all_streams(struct Curl_cfilter *cf, - struct Curl_multi *multi, - cf_quiche_svisit *do_cb, - void *user_data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct cf_quiche_visit_ctx vctx; - vctx.cf = cf; - vctx.multi = multi; - vctx.cb = do_cb; - vctx.user_data = user_data; - Curl_uint32_hash_visit(&ctx->streams, cf_quiche_stream_do, &vctx); -} - -static bool cf_quiche_do_resume(struct Curl_cfilter *cf, - struct Curl_easy *sdata, - struct h3_stream_ctx *stream, - void *user_data) -{ - (void)user_data; - if(stream->quic_flow_blocked) { - stream->quic_flow_blocked = FALSE; - Curl_multi_mark_dirty(sdata); - CURL_TRC_CF(sdata, cf, "[%" PRIu64 "] unblock", stream->id); - } - return TRUE; -} - -static bool cf_quiche_do_expire(struct Curl_cfilter *cf, - struct Curl_easy *sdata, - struct h3_stream_ctx *stream, - void *user_data) -{ - (void)stream; - (void)user_data; - CURL_TRC_CF(sdata, cf, "conn closed, mark as dirty"); - stream->xfer_result = CURLE_SEND_ERROR; - Curl_multi_mark_dirty(sdata); - return TRUE; -} - -static CURLcode h3_data_setup(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - - if(stream) - return CURLE_OK; - - stream = curlx_calloc(1, sizeof(*stream)); - if(!stream) - return CURLE_OUT_OF_MEMORY; - - stream->id = -1; - Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN); - - if(!Curl_uint32_hash_set(&ctx->streams, data->mid, stream)) { - h3_stream_ctx_free(stream); - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -static void cf_quiche_stream_close(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - CURLcode result; - - if(ctx->qconn && !stream->closed) { - quiche_conn_stream_shutdown(ctx->qconn, stream->id, - QUICHE_SHUTDOWN_READ, CURL_H3_NO_ERROR); - if(!stream->send_closed) { - quiche_conn_stream_shutdown(ctx->qconn, stream->id, - QUICHE_SHUTDOWN_WRITE, CURL_H3_NO_ERROR); - stream->send_closed = TRUE; - } - stream->closed = TRUE; - result = cf_flush_egress(cf, data); - if(result) - CURL_TRC_CF(data, cf, "[%" PRIu64 "] stream close, flush egress -> %d", - stream->id, result); - } -} - -static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - - (void)cf; - if(stream) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] easy handle is done", stream->id); - cf_quiche_stream_close(cf, data, stream); - Curl_uint32_hash_remove(&ctx->streams, data->mid); - } -} - -static void cf_quiche_expire_conn_closed(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - DEBUGASSERT(data->multi); - CURL_TRC_CF(data, cf, "conn closed, expire all transfers"); - cf_quiche_for_all_streams(cf, data->multi, cf_quiche_do_expire, NULL); -} - -static void cf_quiche_write_hd(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - const char *buf, size_t blen, bool eos) -{ - /* This function returns no error intentionally, but records - * the result at the stream, skipping further writes once the - * `result` of the transfer is known. - * The stream is subsequently cancelled "higher up" in the filter's - * send/recv callbacks. Closing the stream here leads to SEND/RECV - * errors in other places that then overwrite the transfer's result. */ - if(!stream->xfer_result) { - stream->xfer_result = Curl_xfer_write_resp_hd(data, buf, blen, eos); - if(stream->xfer_result) - CURL_TRC_CF(data, cf, "[%" PRIu64 "] error %d writing %zu " - "bytes of headers", stream->id, stream->xfer_result, blen); - } -} - -struct cb_ctx { - struct Curl_cfilter *cf; - struct Curl_easy *data; - struct h3_stream_ctx *stream; -}; - -static bool is_valid_h3_header(const uint8_t *hdr, size_t hlen) -{ - while(hlen--) { - switch(*hdr++) { - case '\n': - case '\r': - case '\0': - return FALSE; - } - } - return TRUE; -} - -static int cb_each_header(uint8_t *name, size_t name_len, - uint8_t *value, size_t value_len, - void *argp) -{ - struct cb_ctx *x = argp; - struct Curl_cfilter *cf = x->cf; - struct Curl_easy *data = x->data; - struct h3_stream_ctx *stream = x->stream; - struct cf_quiche_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(!stream || stream->xfer_result) - return 1; /* abort iteration */ - - if((name_len == 7) && !strncmp(HTTP_PSEUDO_STATUS, (char *)name, 7) && - is_valid_h3_header(value, value_len)) { - curlx_dyn_reset(&ctx->h1hdr); - result = Curl_http_decode_status(&stream->status_code, - (const char *)value, value_len); - if(!result) - result = curlx_dyn_addn(&ctx->h1hdr, STRCONST("HTTP/3 ")); - if(!result) - result = curlx_dyn_addn(&ctx->h1hdr, (const char *)value, value_len); - if(!result) - result = curlx_dyn_addn(&ctx->h1hdr, STRCONST(" \r\n")); - if(!result) - cf_quiche_write_hd(cf, data, stream, curlx_dyn_ptr(&ctx->h1hdr), - curlx_dyn_len(&ctx->h1hdr), FALSE); - CURL_TRC_CF(data, cf, "[%" PRIu64 "] status: %s", - stream->id, curlx_dyn_ptr(&ctx->h1hdr)); - } - else { - if(is_valid_h3_header(value, value_len) && - is_valid_h3_header(name, name_len)) { - /* store as an HTTP1-style header */ - CURL_TRC_CF(data, cf, "[%" PRIu64 "] header: %.*s: %.*s", - stream->id, (int)name_len, name, - (int)value_len, value); - curlx_dyn_reset(&ctx->h1hdr); - result = curlx_dyn_addn(&ctx->h1hdr, (const char *)name, name_len); - if(!result) - result = curlx_dyn_addn(&ctx->h1hdr, STRCONST(": ")); - if(!result) - result = curlx_dyn_addn(&ctx->h1hdr, (const char *)value, value_len); - if(!result) - result = curlx_dyn_addn(&ctx->h1hdr, STRCONST("\r\n")); - if(!result) - cf_quiche_write_hd(cf, data, stream, curlx_dyn_ptr(&ctx->h1hdr), - curlx_dyn_len(&ctx->h1hdr), FALSE); - } - else - CURL_TRC_CF(x->data, x->cf, "[%" PRIu64 "] ignore %zu bytes bad header", - stream->id, value_len + name_len); - } - - if(result) { - CURL_TRC_CF(x->data, x->cf, "[%" PRIu64 "] on header error %d", - stream->id, result); - if(!stream->xfer_result) - stream->xfer_result = result; - } - return stream->xfer_result ? 1 : 0; -} - -static CURLcode stream_resp_read(void *reader_ctx, - unsigned char *buf, size_t len, - size_t *pnread) -{ - struct cb_ctx *x = reader_ctx; - struct cf_quiche_ctx *ctx = x->cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, x->data); - ssize_t nread; - - *pnread = 0; - if(!stream) - return CURLE_RECV_ERROR; - - nread = quiche_h3_recv_body(ctx->h3c, ctx->qconn, stream->id, buf, len); - if(!curlx_sztouz(nread, pnread)) - return CURLE_AGAIN; - return CURLE_OK; -} - -static void cf_quiche_flush_body(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - const uint8_t *buf; - size_t blen; - - while(stream && !stream->xfer_result) { - if(Curl_bufq_peek(&ctx->writebuf, &buf, &blen)) { - stream->xfer_result = Curl_xfer_write_resp( - data, (const char *)buf, blen, FALSE); - Curl_bufq_skip(&ctx->writebuf, blen); - if(stream->xfer_result) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] error %d writing %zu bytes" - " of data", stream->id, stream->xfer_result, blen); - } - } - else - break; - } - Curl_bufq_reset(&ctx->writebuf); -} - -static void cf_quiche_recv_body(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - size_t nread; - struct cb_ctx cb_ctx; - CURLcode result = CURLE_OK; - - if(!stream) - return; - - /* Even when the transfer has already errored, we need to receive - * the data from quiche, as quiche otherwise gets stuck and - * raise events to receive over and over again. */ - cb_ctx.cf = cf; - cb_ctx.data = data; - cb_ctx.stream = stream; - Curl_bufq_reset(&ctx->writebuf); - while(!result) { - result = Curl_bufq_slurp(&ctx->writebuf, - stream_resp_read, &cb_ctx, &nread); - if(!result) - cf_quiche_flush_body(cf, data, stream); - else if(result == CURLE_AGAIN) - break; - else if(result) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] recv_body error %d", - stream->id, result); - failf(data, "[%" PRIu64 "] Error %d in HTTP/3 response body for stream", - stream->id, result); - stream->closed = TRUE; - stream->reset = TRUE; - stream->send_closed = TRUE; - if(!stream->xfer_result) - stream->xfer_result = result; - } - } - cf_quiche_flush_body(cf, data, stream); -} - -static void cf_quiche_process_ev(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - quiche_h3_event *ev) -{ - if(!stream) - return; - - switch(quiche_h3_event_type(ev)) { - case QUICHE_H3_EVENT_HEADERS: { - struct cb_ctx cb_ctx; - stream->resp_got_header = TRUE; - cb_ctx.cf = cf; - cb_ctx.data = data; - cb_ctx.stream = stream; - quiche_h3_event_for_each_header(ev, cb_each_header, &cb_ctx); - CURL_TRC_CF(data, cf, "[%" PRIu64 "] <- [HEADERS]", stream->id); - Curl_multi_mark_dirty(data); - break; - } - case QUICHE_H3_EVENT_DATA: - if(!stream->resp_hds_complete) { - stream->resp_hds_complete = TRUE; - cf_quiche_write_hd(cf, data, stream, "\r\n", 2, FALSE); - } - cf_quiche_recv_body(cf, data, stream); - CURL_TRC_CF(data, cf, "[%" PRIu64 "] <- [DATA]", stream->id); - Curl_multi_mark_dirty(data); - break; - - case QUICHE_H3_EVENT_RESET: - CURL_TRC_CF(data, cf, "[%" PRIu64 "] RESET", stream->id); - stream->closed = TRUE; - stream->reset = TRUE; - stream->send_closed = TRUE; - Curl_multi_mark_dirty(data); - break; - - case QUICHE_H3_EVENT_FINISHED: - CURL_TRC_CF(data, cf, "[%" PRIu64 "] CLOSED", stream->id); - if(!stream->resp_hds_complete) { - stream->resp_hds_complete = TRUE; - cf_quiche_write_hd(cf, data, stream, "\r\n", 2, TRUE); - } - stream->closed = TRUE; - Curl_multi_mark_dirty(data); - break; - - case QUICHE_H3_EVENT_GOAWAY: - CURL_TRC_CF(data, cf, "[%" PRIu64 "] <- [GOAWAY]", stream->id); - break; - - default: - CURL_TRC_CF(data, cf, "[%" PRIu64 "] recv, unhandled event %d", - stream->id, quiche_h3_event_type(ev)); - break; - } -} - -struct cf_quich_disp_ctx { - uint64_t stream_id; - struct Curl_cfilter *cf; - struct Curl_multi *multi; - quiche_h3_event *ev; -}; - -static bool cf_quiche_disp_event(uint32_t mid, void *val, void *user_data) -{ - struct cf_quich_disp_ctx *dctx = user_data; - struct h3_stream_ctx *stream = val; - - if(stream->id == dctx->stream_id) { - struct Curl_easy *sdata = Curl_multi_get_easy(dctx->multi, mid); - if(sdata) - cf_quiche_process_ev(dctx->cf, sdata, stream, dctx->ev); - return FALSE; /* stop iterating */ - } - return TRUE; -} - -static CURLcode cf_poll_events(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = NULL; - quiche_h3_event *ev; - - /* Take in the events and distribute them to the transfers. */ - while(ctx->h3c) { - int64_t rv = quiche_h3_conn_poll(ctx->h3c, ctx->qconn, &ev); - if(rv == QUICHE_H3_ERR_DONE) { - break; - } - else if(rv < 0) { - CURL_TRC_CF(data, cf, "error poll: %" PRId64, rv); - return CURLE_HTTP3; - } - else { - stream = H3_STREAM_CTX(ctx, data); - if(stream && stream->id == (uint64_t)rv) { - /* event for calling transfer */ - cf_quiche_process_ev(cf, data, stream, ev); - quiche_h3_event_free(ev); - if(stream->xfer_result) - return stream->xfer_result; - } - else { - /* another transfer, do not return errors, as they are not for - * the calling transfer */ - struct cf_quich_disp_ctx dctx; - dctx.stream_id = (uint64_t)rv; - dctx.cf = cf; - dctx.multi = data->multi; - dctx.ev = ev; - Curl_uint32_hash_visit(&ctx->streams, cf_quiche_disp_event, &dctx); - quiche_h3_event_free(ev); - } - } - } - return CURLE_OK; -} - -struct recv_ctx { - struct Curl_cfilter *cf; - struct Curl_easy *data; - int pkts; -}; - -static CURLcode cf_quiche_recv_pkts(const unsigned char *buf, size_t buflen, - size_t gso_size, - struct sockaddr_storage *remote_addr, - socklen_t remote_addrlen, int ecn, - void *userp) -{ - struct recv_ctx *r = userp; - struct cf_quiche_ctx *ctx = r->cf->ctx; - quiche_recv_info recv_info; - size_t pktlen, offset, nread; - ssize_t rv; - - (void)ecn; - - recv_info.to = (struct sockaddr *)&ctx->q.local_addr; - recv_info.to_len = ctx->q.local_addrlen; - recv_info.from = (struct sockaddr *)remote_addr; - recv_info.from_len = remote_addrlen; - - for(offset = 0; offset < buflen; offset += gso_size) { - pktlen = ((offset + gso_size) <= buflen) ? gso_size : (buflen - offset); - rv = quiche_conn_recv(ctx->qconn, - (unsigned char *)CURL_UNCONST(buf + offset), - pktlen, &recv_info); - if(!curlx_sztouz(rv, &nread)) { - if(QUICHE_ERR_DONE == rv) { - if(quiche_conn_is_draining(ctx->qconn)) { - CURL_TRC_CF(r->data, r->cf, "ingress, connection is draining"); - return CURLE_RECV_ERROR; - } - if(quiche_conn_is_closed(ctx->qconn)) { - CURL_TRC_CF(r->data, r->cf, "ingress, connection is closed"); - return CURLE_RECV_ERROR; - } - CURL_TRC_CF(r->data, r->cf, "ingress, quiche is DONE"); - return CURLE_OK; - } - else if(QUICHE_ERR_TLS_FAIL == rv) { - long verify_ok = SSL_get_verify_result(ctx->tls.ossl.ssl); - if(verify_ok != X509_V_OK) { - failf(r->data, "SSL certificate problem: %s", - X509_verify_cert_error_string(verify_ok)); - return CURLE_PEER_FAILED_VERIFICATION; - } - failf(r->data, "ingress, quiche reports TLS fail"); - return CURLE_RECV_ERROR; - } - else { - failf(r->data, "quiche reports error %zd on receive", rv); - return CURLE_RECV_ERROR; - } - } - else if(nread < pktlen) { - CURL_TRC_CF(r->data, r->cf, "ingress, quiche only read %zu/%zu bytes", - nread, pktlen); - } - ++r->pkts; - } - - return CURLE_OK; -} - -static CURLcode cf_process_ingress(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct recv_ctx rctx; - CURLcode result; - - DEBUGASSERT(ctx->qconn); - result = Curl_vquic_tls_before_recv(&ctx->tls, cf, data); - if(result) - return result; - - rctx.cf = cf; - rctx.data = data; - rctx.pkts = 0; - - result = vquic_recv_packets(cf, data, &ctx->q, 1000, - cf_quiche_recv_pkts, &rctx); - if(result) - return result; - - if(rctx.pkts > 0) { - /* quiche digested ingress packets. It might have opened flow control - * windows again. */ - DEBUGASSERT(data->multi); - cf_quiche_for_all_streams(cf, data->multi, cf_quiche_do_resume, NULL); - } - return cf_poll_events(cf, data); -} - -struct read_ctx { - struct Curl_cfilter *cf; - struct Curl_easy *data; - quiche_send_info send_info; -}; - -static CURLcode read_pkt_to_send(void *userp, - unsigned char *buf, size_t buflen, - size_t *pnread) -{ - struct read_ctx *x = userp; - struct cf_quiche_ctx *ctx = x->cf->ctx; - ssize_t rv; - - *pnread = 0; - rv = quiche_conn_send(ctx->qconn, buf, buflen, &x->send_info); - if(rv == QUICHE_ERR_DONE) - return CURLE_AGAIN; - - if(!curlx_sztouz(rv, pnread)) { - failf(x->data, "quiche_conn_send returned %zd", rv); - return CURLE_SEND_ERROR; - } - return CURLE_OK; -} - -/* - * flush_egress drains the buffers and sends off data. - * Calls failf() on errors. - */ -static CURLcode cf_flush_egress(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - size_t nread; - CURLcode result; - int64_t expiry_ns; - int64_t timeout_ns; - struct read_ctx readx; - size_t pkt_count, gsolen; - - expiry_ns = quiche_conn_timeout_as_nanos(ctx->qconn); - if(!expiry_ns) { - quiche_conn_on_timeout(ctx->qconn); - if(quiche_conn_is_closed(ctx->qconn)) { - if(quiche_conn_is_timed_out(ctx->qconn)) - failf(data, "connection closed by idle timeout"); - else - failf(data, "connection closed by server"); - /* Connection timed out, expire all transfers belonging to it - * as it does not get any more POLL events here. */ - cf_quiche_expire_conn_closed(cf, data); - return CURLE_SEND_ERROR; - } - } - - result = vquic_flush(cf, data, &ctx->q); - if(result) { - if(result == CURLE_AGAIN) { - Curl_expire(data, 1, EXPIRE_QUIC); - return CURLE_OK; - } - return result; - } - - readx.cf = cf; - readx.data = data; - memset(&readx.send_info, 0, sizeof(readx.send_info)); - pkt_count = 0; - gsolen = quiche_conn_max_send_udp_payload_size(ctx->qconn); - for(;;) { - /* add the next packet to send, if any, to our buffer */ - result = Curl_bufq_sipn(&ctx->q.sendbuf, 0, - read_pkt_to_send, &readx, &nread); - if(result) { - if(result != CURLE_AGAIN) - return result; - /* Nothing more to add, flush and leave */ - result = vquic_send(cf, data, &ctx->q, gsolen); - if(result) { - if(result == CURLE_AGAIN) { - Curl_expire(data, 1, EXPIRE_QUIC); - return CURLE_OK; - } - return result; - } - goto out; - } - - ++pkt_count; - if(nread < gsolen || pkt_count >= MAX_PKT_BURST) { - result = vquic_send(cf, data, &ctx->q, gsolen); - if(result) { - if(result == CURLE_AGAIN) { - Curl_expire(data, 1, EXPIRE_QUIC); - return CURLE_OK; - } - goto out; - } - pkt_count = 0; - } - } - -out: - timeout_ns = quiche_conn_timeout_as_nanos(ctx->qconn); - if(timeout_ns % 1000000) - timeout_ns += 1000000; - /* expire resolution is milliseconds */ - Curl_expire(data, (timeout_ns / 1000000), EXPIRE_QUIC); - return result; -} - -static CURLcode recv_closed_stream(struct Curl_cfilter *cf, - struct Curl_easy *data, - size_t *pnread) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - CURLcode result = CURLE_OK; - - DEBUGASSERT(stream); - *pnread = 0; - if(stream->reset) { - if(stream->error3 == CURL_H3_ERR_REQUEST_REJECTED) { - infof(data, "HTTP/3 stream %" PRIu64 " refused by server, try again " - "on a new connection", stream->id); - connclose(cf->conn, "REFUSED_STREAM"); /* do not use this anymore */ - data->state.refused_stream = TRUE; - return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ - } - else if(stream->resp_hds_complete && data->req.no_body) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] error after response headers, " - "but we did not want a body anyway, ignore error 0x%" - PRIx64 " %s", stream->id, stream->error3, - vquic_h3_err_str(stream->error3)); - return CURLE_OK; - } - failf(data, "HTTP/3 stream %" PRIu64 " reset by server (error 0x%" PRIx64 - " %s)", stream->id, stream->error3, - vquic_h3_err_str(stream->error3)); - result = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP3; - CURL_TRC_CF(data, cf, "[%" PRIu64 "] cf_recv, was reset -> %d", - stream->id, result); - } - else if(!stream->resp_got_header) { - failf(data, "HTTP/3 stream %" PRIu64 " was closed cleanly, but before " - "getting all response header fields, treated as error", - stream->id); - result = CURLE_HTTP3; - } - return result; -} - -static CURLcode cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t blen, size_t *pnread) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - CURLcode result = CURLE_OK; - - *pnread = 0; - (void)buf; - (void)blen; - vquic_ctx_update_time(&ctx->q, Curl_pgrs_now(data)); - - if(!stream) - return CURLE_RECV_ERROR; - - result = cf_process_ingress(cf, data); - if(result) { - CURL_TRC_CF(data, cf, "cf_recv, error on ingress"); - goto out; - } - - if(stream->xfer_result) { - cf_quiche_stream_close(cf, data, stream); - result = stream->xfer_result; - goto out; - } - else if(stream->closed) - result = recv_closed_stream(cf, data, pnread); - else if(quiche_conn_is_draining(ctx->qconn)) { - failf(data, "QUIC connection is draining"); - result = CURLE_HTTP3; - } - else - result = CURLE_AGAIN; - -out: - result = Curl_1st_fatal(result, cf_flush_egress(cf, data)); - if(*pnread > 0) - ctx->data_recvd += *pnread; - CURL_TRC_CF(data, cf, "[%" PRIu64 "] cf_recv(len=%zu) -> %d, %zu, total=%" - FMT_OFF_T, stream->id, blen, result, *pnread, ctx->data_recvd); - return result; -} - -static CURLcode cf_quiche_send_body(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct h3_stream_ctx *stream, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - ssize_t rv; - - *pnwritten = 0; - rv = quiche_h3_send_body(ctx->h3c, ctx->qconn, stream->id, - (uint8_t *)CURL_UNCONST(buf), len, eos); - if(rv == QUICHE_H3_ERR_DONE || (rv == 0 && len > 0)) { - /* Blocked on flow control and should HOLD sending. - When do we open again? */ - if(!quiche_conn_stream_writable(ctx->qconn, stream->id, len)) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] send_body(len=%zu) " - "-> window exhausted", stream->id, len); - stream->quic_flow_blocked = TRUE; - } - return CURLE_AGAIN; - } - else if(rv == QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] send_body(len=%zu) " - "-> invalid stream state", stream->id, len); - return CURLE_HTTP3; - } - else if(rv == QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] send_body(len=%zu) -> exceeds size", - stream->id, len); - return CURLE_SEND_ERROR; - } - else if(!curlx_sztouz(rv, pnwritten)) { - CURL_TRC_CF(data, cf, "[%" PRIu64 "] send_body(len=%zu) -> quiche err %zd", - stream->id, len, rv); - return CURLE_SEND_ERROR; - } - else { - if(eos && (len == *pnwritten)) - stream->send_closed = TRUE; - CURL_TRC_CF(data, cf, "[%" PRIu64 "] send body(len=%zu, eos=%d) -> %zu", - stream->id, len, stream->send_closed, *pnwritten); - return CURLE_OK; - } -} - -static CURLcode h3_open_stream(struct Curl_cfilter *cf, - struct Curl_easy *data, - const uint8_t *buf, size_t blen, bool eos, - size_t *pnwritten) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - size_t nheader, i; - int64_t rv; - struct dynhds h2_headers; - quiche_h3_header *nva = NULL; - CURLcode result = CURLE_OK; - - *pnwritten = 0; - if(!stream) { - result = h3_data_setup(cf, data); - if(result) - return result; - stream = H3_STREAM_CTX(ctx, data); - DEBUGASSERT(stream); - } - - Curl_dynhds_init(&h2_headers, 0, DYN_HTTP_REQUEST); - - DEBUGASSERT(stream); - - result = Curl_h1_req_parse_read(&stream->h1, buf, blen, NULL, - !data->state.http_ignorecustom ? - data->set.str[STRING_CUSTOMREQUEST] : NULL, - 0, pnwritten); - if(result) - goto out; - if(!stream->h1.done) { - /* need more data */ - goto out; - } - DEBUGASSERT(stream->h1.req); - - result = Curl_http_req_to_h2(&h2_headers, stream->h1.req, data); - if(result) - goto out; - - /* no longer needed */ - Curl_h1_req_parse_free(&stream->h1); - - nheader = Curl_dynhds_count(&h2_headers); - nva = curlx_malloc(sizeof(quiche_h3_header) * nheader); - if(!nva) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - for(i = 0; i < nheader; ++i) { - struct dynhds_entry *e = Curl_dynhds_getn(&h2_headers, i); - nva[i].name = (unsigned char *)e->name; - nva[i].name_len = e->namelen; - nva[i].value = (unsigned char *)e->value; - nva[i].value_len = e->valuelen; - } - - buf += *pnwritten; - blen -= *pnwritten; - - if(eos && !blen) - stream->send_closed = TRUE; - - rv = quiche_h3_send_request(ctx->h3c, ctx->qconn, nva, nheader, - stream->send_closed); - CURL_TRC_CF(data, cf, "quiche_send_request() -> %" PRId64, rv); - if(rv < 0) { - if(QUICHE_H3_ERR_STREAM_BLOCKED == rv) { - /* quiche seems to report this error if the connection window is - * exhausted. Which happens frequently and intermittent. */ - CURL_TRC_CF(data, cf, "[%" PRIu64 "] blocked", stream->id); - stream->quic_flow_blocked = TRUE; - result = CURLE_AGAIN; - goto out; - } - else { - CURL_TRC_CF(data, cf, "send_request(%s) -> %" PRId64, - Curl_bufref_ptr(&data->state.url), rv); - } - result = CURLE_SEND_ERROR; - goto out; - } - - DEBUGASSERT(!stream->opened); - stream->id = (uint64_t)rv; - stream->opened = TRUE; - stream->closed = FALSE; - stream->reset = FALSE; - - if(Curl_trc_is_verbose(data)) { - infof(data, "[HTTP/3] [%" PRIu64 "] OPENED stream for %s", - stream->id, Curl_bufref_ptr(&data->state.url)); - for(i = 0; i < nheader; ++i) { - infof(data, "[HTTP/3] [%" PRIu64 "] [%.*s: %.*s]", stream->id, - (int)nva[i].name_len, nva[i].name, - (int)nva[i].value_len, nva[i].value); - } - } - - if(blen) { /* after the headers, there was request BODY data */ - size_t nwritten; - CURLcode r2 = CURLE_OK; - - r2 = cf_quiche_send_body(cf, data, stream, buf, blen, eos, &nwritten); - if(r2 && (r2 != CURLE_AGAIN)) { /* real error, fail */ - result = r2; - } - else if(nwritten > 0) { - *pnwritten += nwritten; - } - } - -out: - curlx_free(nva); - Curl_dynhds_free(&h2_headers); - return result; -} - -static CURLcode cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const uint8_t *buf, size_t len, bool eos, - size_t *pnwritten) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - CURLcode result; - - *pnwritten = 0; - vquic_ctx_update_time(&ctx->q, Curl_pgrs_now(data)); - - result = cf_process_ingress(cf, data); - if(result) - goto out; - - if(!stream || !stream->opened) { - result = h3_open_stream(cf, data, buf, len, eos, pnwritten); - if(result) - goto out; - stream = H3_STREAM_CTX(ctx, data); - } - else if(stream->xfer_result) { - cf_quiche_stream_close(cf, data, stream); - result = stream->xfer_result; - } - else if(stream->closed) { - if(stream->resp_hds_complete) { - /* sending request body on a stream that has been closed by the - * server. If the server has send us a final response, we should - * silently discard the send data. - * This happens for example on redirects where the server, instead - * of reading the full request body closed the stream after - * sending the 30x response. - * This is sort of a race: had the transfer loop called recv first, - * it would see the response and stop/discard sending on its own- */ - CURL_TRC_CF(data, cf, "[%" PRIu64 "] discarding data" - "on closed stream with response", stream->id); - result = CURLE_OK; - *pnwritten = len; - goto out; - } - CURL_TRC_CF(data, cf, "[%" PRIu64 "] send_body(len=%zu) " - "-> stream closed", stream->id, len); - result = CURLE_HTTP3; - goto out; - } - else { - result = cf_quiche_send_body(cf, data, stream, buf, len, eos, pnwritten); - } - -out: - result = Curl_1st_fatal(result, cf_flush_egress(cf, data)); - - CURL_TRC_CF(data, cf, "[%" PRIu64 "] cf_send(len=%zu) -> %d, %zu", - stream ? stream->id : (uint64_t)~0, len, - result, *pnwritten); - return result; -} - -static bool stream_is_writable(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - - return stream && (quiche_conn_stream_writable( - ctx->qconn, stream->id, 1) > 0); -} - -static CURLcode cf_quiche_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - bool want_recv, want_send; - CURLcode result = CURLE_OK; - - if(!ctx->qconn) - return CURLE_OK; - - Curl_pollset_check(data, ps, ctx->q.sockfd, &want_recv, &want_send); - if(want_recv || want_send) { - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - bool c_exhaust, s_exhaust; - - c_exhaust = FALSE; /* Have not found any call in quiche that tells - us if the connection itself is blocked */ - s_exhaust = want_send && stream && stream->opened && - (stream->quic_flow_blocked || !stream_is_writable(cf, data)); - want_recv = (want_recv || c_exhaust || s_exhaust); - want_send = (!s_exhaust && want_send) || - !Curl_bufq_is_empty(&ctx->q.sendbuf); - - result = Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send); - } - return result; -} - -static CURLcode h3_data_pause(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool pause) -{ - /* There seems to exist no API in quiche to shrink/enlarge the streams - * windows. As we do in HTTP/2. */ - (void)cf; - if(!pause) { - Curl_multi_mark_dirty(data); - } - return CURLE_OK; -} - -static CURLcode cf_quiche_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - (void)arg1; - (void)arg2; - switch(event) { - case CF_CTRL_DATA_SETUP: - break; - case CF_CTRL_DATA_PAUSE: - result = h3_data_pause(cf, data, (arg1 != 0)); - break; - case CF_CTRL_DATA_DONE: - h3_data_done(cf, data); - break; - case CF_CTRL_DATA_DONE_SEND: { - struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data); - if(stream && !stream->send_closed) { - unsigned char body[1]; - size_t sent; - - stream->send_closed = TRUE; - body[0] = 'X'; - result = cf_quiche_send(cf, data, body, 0, TRUE, &sent); - CURL_TRC_CF(data, cf, "[%" PRIu64 "] DONE_SEND -> %d, %zu", - stream->id, result, sent); - } - break; - } - case CF_CTRL_CONN_INFO_UPDATE: - if(!cf->sockindex && cf->connected) { - cf->conn->httpversion_seen = 30; - Curl_conn_set_multiplex(cf->conn); - } - break; - default: - break; - } - return result; -} - -static CURLcode cf_quiche_ctx_open(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - int rv; - CURLcode result; - const struct Curl_sockaddr_ex *sockaddr; - static const struct alpn_spec ALPN_SPEC_H3 = { { "h3" }, 1 }; - - DEBUGASSERT(ctx->q.sockfd != CURL_SOCKET_BAD); - DEBUGASSERT(ctx->initialized); - - result = vquic_ctx_init(data, &ctx->q); - if(result) - return result; - - ctx->cfg = quiche_config_new(QUICHE_PROTOCOL_VERSION); - if(!ctx->cfg) { - failf(data, "cannot create quiche config"); - return CURLE_FAILED_INIT; - } - quiche_config_enable_pacing(ctx->cfg, FALSE); - quiche_config_set_initial_max_data(ctx->cfg, (1 * 1024 * 1024) - /* (QUIC_MAX_STREAMS/2) * H3_STREAM_WINDOW_SIZE */); - quiche_config_set_initial_max_streams_bidi(ctx->cfg, QUIC_MAX_STREAMS); - quiche_config_set_initial_max_streams_uni(ctx->cfg, QUIC_MAX_STREAMS); - quiche_config_set_initial_max_stream_data_bidi_local(ctx->cfg, - H3_STREAM_WINDOW_SIZE); - quiche_config_set_initial_max_stream_data_bidi_remote(ctx->cfg, - H3_STREAM_WINDOW_SIZE); - quiche_config_set_initial_max_stream_data_uni(ctx->cfg, - H3_STREAM_WINDOW_SIZE); - quiche_config_set_disable_active_migration(ctx->cfg, TRUE); - - quiche_config_set_max_connection_window(ctx->cfg, - 10 * QUIC_MAX_STREAMS * H3_STREAM_WINDOW_SIZE); - quiche_config_set_max_stream_window(ctx->cfg, 10 * H3_STREAM_WINDOW_SIZE); - quiche_config_set_application_protos(ctx->cfg, - (uint8_t *)CURL_UNCONST(QUICHE_H3_APPLICATION_PROTOCOL), - sizeof(QUICHE_H3_APPLICATION_PROTOCOL) - - 1); - - result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer, - &ALPN_SPEC_H3, NULL, NULL, cf, NULL); - if(result) - return result; - - result = Curl_rand(data, ctx->scid, sizeof(ctx->scid)); - if(result) - return result; - - if(Curl_cf_socket_peek(cf->next, data, &ctx->q.sockfd, &sockaddr, NULL)) - return CURLE_QUIC_CONNECT_ERROR; - - ctx->q.local_addrlen = sizeof(ctx->q.local_addr); - rv = getsockname(ctx->q.sockfd, (struct sockaddr *)&ctx->q.local_addr, - &ctx->q.local_addrlen); - if(rv == -1) - return CURLE_QUIC_CONNECT_ERROR; - - ctx->qconn = quiche_conn_new_with_tls((const uint8_t *)ctx->scid, - sizeof(ctx->scid), NULL, 0, - (struct sockaddr *)&ctx->q.local_addr, - ctx->q.local_addrlen, - &sockaddr->curl_sa_addr, - sockaddr->addrlen, - ctx->cfg, ctx->tls.ossl.ssl, FALSE); - if(!ctx->qconn) { - failf(data, "cannot create quiche connection"); - return CURLE_OUT_OF_MEMORY; - } - - /* Known to not work on Windows */ -#if !defined(_WIN32) && defined(HAVE_QUICHE_CONN_SET_QLOG_FD) - { - int qfd; - (void)Curl_qlogdir(data, ctx->scid, sizeof(ctx->scid), &qfd); - if(qfd != -1) - quiche_conn_set_qlog_fd(ctx->qconn, qfd, "qlog title", "curl qlog"); - } -#endif - - result = cf_flush_egress(cf, data); - if(result) - return result; - - { - unsigned char alpn_protocols[] = QUICHE_H3_APPLICATION_PROTOCOL; - unsigned alpn_len, offset = 0; - - /* Replace each ALPN length prefix by a comma. */ - while(offset < sizeof(alpn_protocols) - 1) { - alpn_len = alpn_protocols[offset]; - alpn_protocols[offset] = ','; - offset += 1 + alpn_len; - } - - CURL_TRC_CF(data, cf, "Sent QUIC client Initial, ALPN: %s", - alpn_protocols + 1); - } - - return CURLE_OK; -} - -static CURLcode cf_quiche_verify_peer(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - return Curl_vquic_tls_verify_peer(&ctx->tls, cf, data, &ctx->peer); -} - -static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(cf->connected) { - *done = TRUE; - return CURLE_OK; - } - - /* Connect the UDP filter first */ - if(!cf->next->connected) { - result = Curl_conn_cf_connect(cf->next, data, done); - if(result || !*done) - return result; - } - - *done = FALSE; - if(Curl_ossl_need_httpsrr(data) && - !Curl_conn_dns_resolved_https(data, cf->sockindex)) { - CURL_TRC_CF(data, cf, "need HTTPS-RR, delaying connect"); - return CURLE_OK; - } - - vquic_ctx_update_time(&ctx->q, Curl_pgrs_now(data)); - - if(!ctx->qconn) { - result = cf_quiche_ctx_open(cf, data); - if(result) - goto out; - ctx->started_at = ctx->q.last_op; - result = cf_flush_egress(cf, data); - /* we do not expect to be able to recv anything yet */ - goto out; - } - - result = cf_process_ingress(cf, data); - if(result) - goto out; - - result = cf_flush_egress(cf, data); - if(result) - goto out; - - if(quiche_conn_is_established(ctx->qconn)) { - ctx->handshake_at = ctx->q.last_op; - CURL_TRC_CF(data, cf, "handshake complete after %" FMT_TIMEDIFF_T "ms", - curlx_ptimediff_ms(&ctx->handshake_at, &ctx->started_at)); - result = cf_quiche_verify_peer(cf, data); - if(!result) { - CURL_TRC_CF(data, cf, "peer verified"); - ctx->h3config = quiche_h3_config_new(); - if(!ctx->h3config) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Create a new HTTP/3 connection on the QUIC connection. */ - ctx->h3c = quiche_h3_conn_new_with_transport(ctx->qconn, ctx->h3config); - if(!ctx->h3c) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - cf->connected = TRUE; - *done = TRUE; - } - } - else if(quiche_conn_is_draining(ctx->qconn)) { - /* When a QUIC server instance is shutting down, it may send us a - * CONNECTION_CLOSE right away. Our connection then enters the DRAINING - * state. The CONNECT may work in the near future again. Indicate - * that as a "weird" reply. */ - result = CURLE_WEIRD_SERVER_REPLY; - } - -out: -#ifdef CURLVERBOSE - if(result && result != CURLE_AGAIN) { - struct ip_quadruple ip; - - if(!Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip)) - infof(data, "connect to %s port %u failed: %s", - ip.remote_ip, ip.remote_port, curl_easy_strerror(result)); - else - infof(data, "connect failed: %s", curl_easy_strerror(result)); - } -#endif - return result; -} - -static CURLcode cf_quiche_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - CURLcode result = CURLE_OK; - - if(cf->shutdown || !ctx || !ctx->qconn) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - if(!ctx->shutdown_started) { - int err; - - ctx->shutdown_started = TRUE; - vquic_ctx_update_time(&ctx->q, Curl_pgrs_now(data)); - err = quiche_conn_close(ctx->qconn, TRUE, 0, NULL, 0); - if(err) { - CURL_TRC_CF(data, cf, "error %d adding shutdown packet, " - "aborting shutdown", err); - result = CURLE_SEND_ERROR; - goto out; - } - } - - if(!Curl_bufq_is_empty(&ctx->q.sendbuf)) { - CURL_TRC_CF(data, cf, "shutdown, flushing sendbuf"); - result = cf_flush_egress(cf, data); - if(result) - goto out; - } - - if(Curl_bufq_is_empty(&ctx->q.sendbuf)) { - /* sent everything, quiche does not seem to support a graceful - * shutdown waiting for a reply, so ware done. */ - CURL_TRC_CF(data, cf, "shutdown completely sent off, done"); - *done = TRUE; - } - else { - CURL_TRC_CF(data, cf, "shutdown sending blocked"); - } - -out: - return result; -} - -static void cf_quiche_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - if(cf->ctx) { - bool done; - (void)cf_quiche_shutdown(cf, data, &done); - cf_quiche_ctx_close(cf->ctx); - cf->connected = FALSE; - } -} - -static void cf_quiche_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - (void)data; - if(cf->ctx) { - cf_quiche_ctx_close(cf->ctx); - cf_quiche_ctx_free(cf->ctx); - cf->ctx = NULL; - } -} - -static CURLcode cf_quiche_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - - switch(query) { - case CF_QUERY_MAX_CONCURRENT: { - uint64_t max_streams = cf->conn->attached_xfers; - if(!ctx->goaway && ctx->qconn) { - max_streams += quiche_conn_peer_streams_left_bidi(ctx->qconn); - } - *pres1 = (max_streams > INT_MAX) ? INT_MAX : (int)max_streams; - CURL_TRC_CF(data, cf, "query conn[%" FMT_OFF_T "]: " - "MAX_CONCURRENT -> %d (%u in use)", - cf->conn->connection_id, *pres1, cf->conn->attached_xfers); - return CURLE_OK; - } - case CF_QUERY_CONNECT_REPLY_MS: - if(ctx->q.got_first_byte) { - timediff_t ms = curlx_ptimediff_ms(&ctx->q.first_byte_at, - &ctx->started_at); - *pres1 = (ms < INT_MAX) ? (int)ms : INT_MAX; - } - else - *pres1 = -1; - return CURLE_OK; - case CF_QUERY_TIMER_CONNECT: { - struct curltime *when = pres2; - if(ctx->q.got_first_byte) - *when = ctx->q.first_byte_at; - return CURLE_OK; - } - case CF_QUERY_TIMER_APPCONNECT: { - struct curltime *when = pres2; - if(cf->connected) - *when = ctx->handshake_at; - return CURLE_OK; - } - case CF_QUERY_HTTP_VERSION: - *pres1 = 30; - return CURLE_OK; - case CF_QUERY_SSL_INFO: - case CF_QUERY_SSL_CTX_INFO: { - struct curl_tlssessioninfo *info = pres2; - if(Curl_vquic_tls_get_ssl_info(&ctx->tls, - (query == CF_QUERY_SSL_CTX_INFO), info)) - return CURLE_OK; - break; - } - case CF_QUERY_ALPN_NEGOTIATED: { - const char **palpn = pres2; - DEBUGASSERT(palpn); - *palpn = cf->connected ? "h3" : NULL; - return CURLE_OK; - } - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -static bool cf_quiche_conn_is_alive(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *input_pending) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - bool alive = TRUE; - - *input_pending = FALSE; - if(!ctx->qconn) - return FALSE; - - if(quiche_conn_is_closed(ctx->qconn)) { - if(quiche_conn_is_timed_out(ctx->qconn)) - CURL_TRC_CF(data, cf, "connection was closed due to idle timeout"); - else - CURL_TRC_CF(data, cf, "connection is closed"); - return FALSE; - } - - if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending)) - return FALSE; - - if(*input_pending) { - /* This happens before we have sent off a request and the connection is - not in use by any other transfer, there should not be any data here, - only "protocol frames" */ - *input_pending = FALSE; - if(cf_process_ingress(cf, data)) - alive = FALSE; - else { - alive = TRUE; - } - } - - return alive; -} - -struct Curl_cftype Curl_cft_http3 = { - "HTTP/3", - CF_TYPE_IP_CONNECT | CF_TYPE_SSL | CF_TYPE_MULTIPLEX | CF_TYPE_HTTP, - 0, - cf_quiche_destroy, - cf_quiche_connect, - cf_quiche_close, - cf_quiche_shutdown, - cf_quiche_adjust_pollset, - Curl_cf_def_data_pending, - cf_quiche_send, - cf_quiche_recv, - cf_quiche_cntrl, - cf_quiche_conn_is_alive, - Curl_cf_def_conn_keep_alive, - cf_quiche_query, -}; - -CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr) -{ - struct cf_quiche_ctx *ctx = NULL; - struct Curl_cfilter *cf = NULL; - CURLcode result; - - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - cf_quiche_ctx_init(ctx); - - result = Curl_cf_create(&cf, &Curl_cft_http3, ctx); - if(result) - goto out; - cf->conn = conn; - - result = Curl_cf_udp_create(&cf->next, data, conn, addr, TRNSPRT_QUIC); - if(result) - goto out; - cf->next->conn = cf->conn; - cf->next->sockindex = cf->sockindex; - -out: - *pcf = (!result) ? cf : NULL; - if(result) { - if(cf) - Curl_conn_cf_discard_chain(&cf, data); - else if(ctx) - cf_quiche_ctx_free(ctx); - } - - return result; -} - -#endif diff --git a/vendor/curl/lib/vquic/curl_quiche.h b/vendor/curl/lib/vquic/curl_quiche.h deleted file mode 100644 index c2c88ddea..000000000 --- a/vendor/curl/lib/vquic/curl_quiche.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HEADER_CURL_VQUIC_CURL_QUICHE_H -#define HEADER_CURL_VQUIC_CURL_QUICHE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_QUICHE) - -#include -#include - -struct Curl_cfilter; -struct Curl_easy; - -void Curl_quiche_ver(char *p, size_t len); - -CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr); - -#endif - -#endif /* HEADER_CURL_VQUIC_CURL_QUICHE_H */ diff --git a/vendor/curl/lib/vquic/vquic-tls.c b/vendor/curl/lib/vquic/vquic-tls.c deleted file mode 100644 index d81f2a9e6..000000000 --- a/vendor/curl/lib/vquic/vquic-tls.c +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_HTTP3) && \ - (defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_WOLFSSL)) - -#ifdef USE_OPENSSL -#include -#include "vtls/openssl.h" -#elif defined(USE_GNUTLS) -#include -#include -#include -#include -#include -#include "vtls/gtls.h" -#elif defined(USE_WOLFSSL) -#include -#include -#include -#include "vtls/wolfssl.h" -#endif - -#include "urldata.h" -#include "cfilters.h" -#include "vtls/vtls.h" -#include "vtls/vtls_scache.h" -#include "vquic/vquic-tls.h" - -CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns, - Curl_vquic_tls_ctx_setup *cb_setup, - void *cb_user_data, void *ssl_user_data, - Curl_vquic_session_reuse_cb *session_reuse_cb) -{ - char tls_id[80]; - CURLcode result; - -#ifdef USE_OPENSSL - Curl_ossl_version(tls_id, sizeof(tls_id)); -#elif defined(USE_GNUTLS) - Curl_gtls_version(tls_id, sizeof(tls_id)); -#elif defined(USE_WOLFSSL) - Curl_wssl_version(tls_id, sizeof(tls_id)); -#else -#error "no TLS lib in used, should not happen" - return CURLE_FAILED_INIT; -#endif - (void)session_reuse_cb; - result = Curl_ssl_peer_init(peer, cf, tls_id, TRNSPRT_QUIC); - if(result) - return result; - -#ifdef USE_OPENSSL - (void)result; - return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer, alpns, - cb_setup, cb_user_data, NULL, ssl_user_data, - session_reuse_cb); -#elif defined(USE_GNUTLS) - return Curl_gtls_ctx_init(&ctx->gtls, cf, data, peer, alpns, - cb_setup, cb_user_data, ssl_user_data, - session_reuse_cb); -#elif defined(USE_WOLFSSL) - return Curl_wssl_ctx_init(&ctx->wssl, cf, data, peer, alpns, - cb_setup, cb_user_data, - ssl_user_data, session_reuse_cb); -#else -#error "no TLS lib in used, should not happen" - return CURLE_FAILED_INIT; -#endif -} - -void Curl_vquic_tls_cleanup(struct curl_tls_ctx *ctx) -{ -#ifdef USE_OPENSSL - if(ctx->ossl.ssl) - SSL_free(ctx->ossl.ssl); - if(ctx->ossl.ssl_ctx) - SSL_CTX_free(ctx->ossl.ssl_ctx); -#elif defined(USE_GNUTLS) - if(ctx->gtls.session) - gnutls_deinit(ctx->gtls.session); - Curl_gtls_shared_creds_free(&ctx->gtls.shared_creds); -#elif defined(USE_WOLFSSL) - if(ctx->wssl.ssl) - wolfSSL_free(ctx->wssl.ssl); - if(ctx->wssl.ssl_ctx) - wolfSSL_CTX_free(ctx->wssl.ssl_ctx); -#endif - memset(ctx, 0, sizeof(*ctx)); -} - -CURLcode Curl_vquic_tls_before_recv(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ -#ifdef USE_OPENSSL - if(!ctx->ossl.x509_store_setup) { - CURLcode result = Curl_ssl_setup_x509_store(cf, data, &ctx->ossl); - if(result) - return result; - ctx->ossl.x509_store_setup = TRUE; - } -#elif defined(USE_WOLFSSL) - if(!ctx->wssl.x509_store_setup) { - CURLcode result = Curl_wssl_setup_x509_store(cf, data, &ctx->wssl); - if(result) - return result; - } -#elif defined(USE_GNUTLS) - if(!ctx->gtls.shared_creds->trust_setup) { - CURLcode result = Curl_gtls_client_trust_setup(cf, data, &ctx->gtls); - if(result) - return result; - } -#else - (void)ctx; - (void)cf; - (void)data; -#endif - return CURLE_OK; -} - -CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer) -{ - struct ssl_primary_config *conn_config; - CURLcode result = CURLE_OK; - - conn_config = Curl_ssl_cf_get_primary_config(cf); - if(!conn_config) - return CURLE_FAILED_INIT; - -#ifdef USE_OPENSSL - (void)conn_config; - result = Curl_ossl_check_peer_cert(cf, data, &ctx->ossl, peer); -#elif defined(USE_GNUTLS) - result = Curl_gtls_verifyserver(cf, data, ctx->gtls.session, - conn_config, &data->set.ssl, peer, - data->set.str[STRING_SSL_PINNEDPUBLICKEY]); - if(result) - return result; -#elif defined(USE_WOLFSSL) - (void)data; - if(conn_config->verifyhost) { - WOLFSSL_X509 *cert = wolfSSL_get_peer_certificate(ctx->wssl.ssl); - if(!cert) - result = CURLE_OUT_OF_MEMORY; - else if(peer->sni && - (wolfSSL_X509_check_host(cert, peer->sni, strlen(peer->sni), 0, - NULL) == WOLFSSL_FAILURE)) - result = CURLE_PEER_FAILED_VERIFICATION; - else if(!peer->sni && - (wolfSSL_X509_check_ip_asc(cert, peer->hostname, - 0) == WOLFSSL_FAILURE)) - result = CURLE_PEER_FAILED_VERIFICATION; - wolfSSL_X509_free(cert); - } - if(!result) - result = Curl_wssl_verify_pinned(cf, data, &ctx->wssl); -#endif - /* on error, remove any session we might have in the pool */ - if(result) - Curl_ssl_scache_remove_all(cf, data, peer->scache_key); - return result; -} - -bool Curl_vquic_tls_get_ssl_info(struct curl_tls_ctx *ctx, - bool give_ssl_ctx, - struct curl_tlssessioninfo *info) -{ -#ifdef USE_OPENSSL - info->backend = CURLSSLBACKEND_OPENSSL; - info->internals = give_ssl_ctx ? - (void *)ctx->ossl.ssl_ctx : (void *)ctx->ossl.ssl; - return TRUE; -#elif defined(USE_GNUTLS) - (void)give_ssl_ctx; /* gnutls always returns its session */ - info->backend = CURLSSLBACKEND_GNUTLS; - info->internals = ctx->gtls.session; - return TRUE; -#elif defined(USE_WOLFSSL) - info->backend = CURLSSLBACKEND_WOLFSSL; - info->internals = give_ssl_ctx ? - (void *)ctx->wssl.ssl_ctx : (void *)ctx->wssl.ssl; - return TRUE; -#else - return FALSE; -#endif -} - -void Curl_vquic_report_handshake(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - (void)cf; -#ifdef USE_OPENSSL - (void)cf; - Curl_ossl_report_handshake(data, &ctx->ossl); -#elif defined(USE_GNUTLS) - Curl_gtls_report_handshake(data, &ctx->gtls); -#elif defined(USE_WOLFSSL) - Curl_wssl_report_handshake(data, &ctx->wssl); -#else - (void)data; - (void)ctx; -#endif -} - -#endif /* !USE_HTTP3 && (USE_OPENSSL || USE_GNUTLS || USE_WOLFSSL) */ diff --git a/vendor/curl/lib/vquic/vquic-tls.h b/vendor/curl/lib/vquic/vquic-tls.h deleted file mode 100644 index c461c1548..000000000 --- a/vendor/curl/lib/vquic/vquic-tls.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef HEADER_CURL_VQUIC_TLS_H -#define HEADER_CURL_VQUIC_TLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_HTTP3) && \ - (defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_WOLFSSL)) - -#include "bufq.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" - -#include "vtls/openssl.h" -#include "vtls/wolfssl.h" - -struct ssl_peer; -struct Curl_ssl_session; -struct curl_tlssessioninfo; - -struct curl_tls_ctx { -#ifdef USE_OPENSSL - struct ossl_ctx ossl; -#elif defined(USE_GNUTLS) - struct gtls_ctx gtls; -#elif defined(USE_WOLFSSL) - struct wssl_ctx wssl; -#endif -}; - -/** - * Callback passed to `Curl_vquic_tls_init()` that can - * do early initializations on the not otherwise configured TLS - * instances created. This varies by TLS backend: - * - openssl/wolfssl: SSL_CTX* has been created - * - gnutls: gtls_client_init() has run - */ -typedef CURLcode Curl_vquic_tls_ctx_setup(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *cb_user_data); - -typedef CURLcode Curl_vquic_session_reuse_cb(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data); - -/** - * Initialize the QUIC TLS instances based of the SSL configurations - * for the connection filter, transfer and peer. - * @param ctx the TLS context to initialize - * @param cf the connection filter involved - * @param data the transfer involved - * @param peer the peer to be connected to - * @param alpns the ALPN specifications to negotiate, may be NULL - * @param cb_setup optional callback for early TLS config - * @param cb_user_data user_data param for callback - * @param ssl_user_data optional pointer to set in TLS application context - * @param session_reuse_cb callback to handle session reuse, signal early data - */ -CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns, - Curl_vquic_tls_ctx_setup *cb_setup, - void *cb_user_data, - void *ssl_user_data, - Curl_vquic_session_reuse_cb *session_reuse_cb); - -/** - * Cleanup all data that has been initialized. - */ -void Curl_vquic_tls_cleanup(struct curl_tls_ctx *ctx); - -CURLcode Curl_vquic_tls_before_recv(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data); - -/** - * After the QUIC basic handshake has been, verify that the peer - * (and its certificate) fulfill our requirements. - */ -CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer); - -bool Curl_vquic_tls_get_ssl_info(struct curl_tls_ctx *ctx, - bool give_ssl_ctx, - struct curl_tlssessioninfo *info); - -void Curl_vquic_report_handshake(struct curl_tls_ctx *ctx, - struct Curl_cfilter *cf, - struct Curl_easy *data); - -#endif /* !USE_HTTP3 && (USE_OPENSSL || USE_GNUTLS || USE_WOLFSSL) */ - -#endif /* HEADER_CURL_VQUIC_TLS_H */ diff --git a/vendor/curl/lib/vquic/vquic.c b/vendor/curl/lib/vquic/vquic.c deleted file mode 100644 index 0040ad671..000000000 --- a/vendor/curl/lib/vquic/vquic.c +++ /dev/null @@ -1,868 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "vquic/vquic.h" - -#include "curl_trc.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) - -#ifdef HAVE_NETINET_UDP_H -#include -#endif - -#ifdef USE_NGHTTP3 -#include -#endif - -#include "bufq.h" -#include "curlx/dynbuf.h" -#include "curlx/fopen.h" -#include "cfilters.h" -#include "vquic/curl_ngtcp2.h" -#include "vquic/curl_quiche.h" -#include "multiif.h" -#include "progress.h" -#include "rand.h" -#include "vquic/vquic_int.h" -#include "curlx/strerr.h" -#include "curlx/strparse.h" - - -#define NW_CHUNK_SIZE (64 * 1024) -#define NW_SEND_CHUNKS 1 - -int Curl_vquic_init(void) -{ -#if defined(USE_NGTCP2) && defined(OPENSSL_QUIC_API2) - if(ngtcp2_crypto_ossl_init()) - return 0; -#endif - - return 1; -} - -void Curl_quic_ver(char *p, size_t len) -{ -#if defined(USE_NGTCP2) && defined(USE_NGHTTP3) - Curl_ngtcp2_ver(p, len); -#elif defined(USE_QUICHE) - Curl_quiche_ver(p, len); -#endif -} - -CURLcode vquic_ctx_init(struct Curl_easy *data, - struct cf_quic_ctx *qctx) -{ - Curl_bufq_init2(&qctx->sendbuf, NW_CHUNK_SIZE, NW_SEND_CHUNKS, - BUFQ_OPT_SOFT_LIMIT); -#if defined(__linux__) && defined(UDP_SEGMENT) && defined(HAVE_SENDMSG) - qctx->no_gso = FALSE; -#else - qctx->no_gso = TRUE; -#endif -#ifdef DEBUGBUILD - { - const char *p = getenv("CURL_DBG_QUIC_WBLOCK"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, 100)) - qctx->wblock_percent = (int)l; - } - } -#endif - vquic_ctx_set_time(qctx, Curl_pgrs_now(data)); - - return CURLE_OK; -} - -void vquic_ctx_free(struct cf_quic_ctx *qctx) -{ - Curl_bufq_free(&qctx->sendbuf); -} - -void vquic_ctx_set_time(struct cf_quic_ctx *qctx, - const struct curltime *pnow) -{ - qctx->last_op = *pnow; -} - -void vquic_ctx_update_time(struct cf_quic_ctx *qctx, - const struct curltime *pnow) -{ - qctx->last_op = *pnow; -} - -static CURLcode send_packet_no_gso(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - const uint8_t *pkt, size_t pktlen, - size_t gsolen, size_t *psent); - -static CURLcode do_sendmsg(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - const uint8_t *pkt, size_t pktlen, size_t gsolen, - size_t *psent) -{ - CURLcode result = CURLE_OK; -#ifdef HAVE_SENDMSG - struct iovec msg_iov; - struct msghdr msg = { 0 }; - ssize_t rv; -#if defined(__linux__) && defined(UDP_SEGMENT) - uint8_t msg_ctrl[32]; - struct cmsghdr *cm; -#endif - - *psent = 0; - msg_iov.iov_base = (uint8_t *)CURL_UNCONST(pkt); - msg_iov.iov_len = pktlen; - msg.msg_iov = &msg_iov; - msg.msg_iovlen = 1; - -#if defined(__linux__) && defined(UDP_SEGMENT) - if(pktlen > gsolen) { - /* Only set this, when we need it. macOS, for example, - * does not seem to like a msg_control of length 0. */ - memset(msg_ctrl, 0, sizeof(msg_ctrl)); - msg.msg_control = msg_ctrl; - assert(sizeof(msg_ctrl) >= CMSG_SPACE(sizeof(int))); - msg.msg_controllen = CMSG_SPACE(sizeof(int)); - cm = CMSG_FIRSTHDR(&msg); - cm->cmsg_level = SOL_UDP; - cm->cmsg_type = UDP_SEGMENT; - cm->cmsg_len = CMSG_LEN(sizeof(uint16_t)); - *(uint16_t *)(void *)CMSG_DATA(cm) = gsolen & 0xffff; - } -#endif - - while((rv = sendmsg(qctx->sockfd, &msg, 0)) == -1 && SOCKERRNO == SOCKEINTR) - ; - - if(!curlx_sztouz(rv, psent)) { - switch(SOCKERRNO) { - case EAGAIN: -#if EAGAIN != SOCKEWOULDBLOCK - case SOCKEWOULDBLOCK: -#endif - return CURLE_AGAIN; - case SOCKEMSGSIZE: - /* UDP datagram is too large; caused by PMTUD. Let it be lost. */ - *psent = pktlen; - break; - case EIO: - if(pktlen > gsolen) { - /* GSO failure */ - infof(data, "sendmsg() returned %zd (errno %d); disable GSO", rv, - SOCKERRNO); - qctx->no_gso = TRUE; - return send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent); - } - FALLTHROUGH(); - default: - failf(data, "sendmsg() returned %zd (errno %d)", rv, SOCKERRNO); - result = CURLE_SEND_ERROR; - goto out; - } - } - else if(pktlen != *psent) { - failf(data, "sendmsg() sent only %zu/%zu bytes", *psent, pktlen); - result = CURLE_SEND_ERROR; - goto out; - } -#else - ssize_t rv; - (void)gsolen; - - *psent = 0; - - while((rv = swrite(qctx->sockfd, pkt, pktlen)) == -1 && - SOCKERRNO == SOCKEINTR) - ; - - if(!curlx_sztouz(rv, psent)) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { - result = CURLE_AGAIN; - goto out; - } - else { - if(SOCKERRNO != SOCKEMSGSIZE) { - failf(data, "send() returned %zd (errno %d)", rv, SOCKERRNO); - result = CURLE_SEND_ERROR; - goto out; - } - /* UDP datagram is too large; caused by PMTUD. Let it be lost. */ - *psent = pktlen; - } - } -#endif - (void)cf; - -out: - return result; -} - -#ifdef CURLVERBOSE -#ifdef HAVE_SENDMSG -#define VQUIC_SEND_METHOD "sendmsg" -#else -#define VQUIC_SEND_METHOD "send" -#endif -#endif - -static CURLcode send_packet_no_gso(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - const uint8_t *pkt, size_t pktlen, - size_t gsolen, size_t *psent) -{ - const uint8_t *p, *end = pkt + pktlen; - size_t sent, len; - CURLcode result = CURLE_OK; - VERBOSE(size_t calls = 0); - - *psent = 0; - - for(p = pkt; p < end; p += gsolen) { - len = CURLMIN(gsolen, (size_t)(end - p)); - result = do_sendmsg(cf, data, qctx, p, len, len, &sent); - if(result) - goto out; - *psent += sent; - VERBOSE(++calls); - } -out: - CURL_TRC_CF(data, cf, "vquic_%s(len=%zu, gso=%zu, calls=%zu)" - " -> %d, sent=%zu", - VQUIC_SEND_METHOD, pktlen, gsolen, calls, result, *psent); - return result; -} - -static CURLcode vquic_send_packets(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - const uint8_t *pkt, size_t pktlen, - size_t gsolen, size_t *psent) -{ - CURLcode result; -#ifdef DEBUGBUILD - /* simulate network blocking/partial writes */ - if(qctx->wblock_percent > 0) { - unsigned char c; - *psent = 0; - Curl_rand(data, &c, 1); - if(c >= ((100 - qctx->wblock_percent) * 256 / 100)) { - CURL_TRC_CF(data, cf, "vquic_flush() simulate EWOULDBLOCK"); - return CURLE_AGAIN; - } - } -#endif - if(qctx->no_gso && pktlen > gsolen) { - result = send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent); - } - else { - result = do_sendmsg(cf, data, qctx, pkt, pktlen, gsolen, psent); - CURL_TRC_CF(data, cf, "vquic_%s(len=%zu, gso=%zu, calls=1)" - " -> %d, sent=%zu", - VQUIC_SEND_METHOD, pktlen, gsolen, result, *psent); - } - if(!result) - qctx->last_io = qctx->last_op; - return result; -} - -CURLcode vquic_flush(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx) -{ - const unsigned char *buf; - size_t blen, sent; - CURLcode result; - size_t gsolen; - - while(Curl_bufq_peek(&qctx->sendbuf, &buf, &blen)) { - gsolen = qctx->gsolen; - if(qctx->split_len) { - gsolen = qctx->split_gsolen; - if(blen > qctx->split_len) - blen = qctx->split_len; - } - - result = vquic_send_packets(cf, data, qctx, buf, blen, gsolen, &sent); - if(result) { - if(result == CURLE_AGAIN) { - Curl_bufq_skip(&qctx->sendbuf, sent); - if(qctx->split_len) - qctx->split_len -= sent; - } - return result; - } - Curl_bufq_skip(&qctx->sendbuf, sent); - if(qctx->split_len) - qctx->split_len -= sent; - } - return CURLE_OK; -} - -CURLcode vquic_send(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx, size_t gsolen) -{ - qctx->gsolen = gsolen; - return vquic_flush(cf, data, qctx); -} - -CURLcode vquic_send_tail_split(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx, size_t gsolen, - size_t tail_len, size_t tail_gsolen) -{ - DEBUGASSERT(Curl_bufq_len(&qctx->sendbuf) > tail_len); - qctx->split_len = Curl_bufq_len(&qctx->sendbuf) - tail_len; - qctx->split_gsolen = gsolen; - qctx->gsolen = tail_gsolen; - CURL_TRC_CF(data, cf, "vquic_send_tail_split: [%zu gso=%zu][%zu gso=%zu]", - qctx->split_len, qctx->split_gsolen, tail_len, qctx->gsolen); - return vquic_flush(cf, data, qctx); -} - -#if defined(HAVE_SENDMMSG) || defined(HAVE_SENDMSG) -static size_t vquic_msghdr_get_udp_gro(struct msghdr *msg) -{ - int gso_size = 0; -#if defined(__linux__) && defined(UDP_GRO) - struct cmsghdr *cmsg; - - /* Workaround musl CMSG_NXTHDR issue */ -#if defined(__clang__) && !defined(__GLIBC__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wsign-compare" -#pragma clang diagnostic ignored "-Wcast-align" -#endif - for(cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { -#if defined(__clang__) && !defined(__GLIBC__) -#pragma clang diagnostic pop -#endif - if(cmsg->cmsg_level == SOL_UDP && cmsg->cmsg_type == UDP_GRO) { - memcpy(&gso_size, CMSG_DATA(cmsg), sizeof(gso_size)); - - break; - } - } -#endif - (void)msg; - - return (size_t)gso_size; -} -#endif - -#ifdef HAVE_SENDMMSG -static CURLcode recvmmsg_packets(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - size_t max_pkts, - vquic_recv_pkts_cb *recv_cb, void *userp) -{ -#if defined(__linux__) && defined(UDP_GRO) -#define MMSG_NUM 16 -#define UDP_GRO_CNT_MAX 64 -#else -#define MMSG_NUM 64 -#define UDP_GRO_CNT_MAX 1 -#endif -#define MSG_BUF_SIZE (UDP_GRO_CNT_MAX * 1500) - struct iovec msg_iov[MMSG_NUM]; - struct mmsghdr mmsg[MMSG_NUM]; - uint8_t msg_ctrl[MMSG_NUM * CMSG_SPACE(sizeof(int))]; - struct sockaddr_storage remote_addr[MMSG_NUM]; - size_t total_nread = 0, pkts = 0; -#ifdef CURLVERBOSE - size_t calls = 0; -#endif - int mcount, i, n; - char errstr[STRERROR_LEN]; - CURLcode result = CURLE_OK; - size_t gso_size; - char *sockbuf = NULL; - uint8_t (*bufs)[MSG_BUF_SIZE] = NULL; - - DEBUGASSERT(max_pkts > 0); - result = Curl_multi_xfer_sockbuf_borrow(data, MMSG_NUM * MSG_BUF_SIZE, - &sockbuf); - if(result) - goto out; - bufs = (uint8_t (*)[MSG_BUF_SIZE])sockbuf; - - total_nread = 0; - while(pkts < max_pkts) { - n = (int)CURLMIN(CURLMIN(MMSG_NUM, IOV_MAX), max_pkts); - memset(&mmsg, 0, sizeof(mmsg)); - for(i = 0; i < n; ++i) { - msg_iov[i].iov_base = bufs[i]; - msg_iov[i].iov_len = (int)sizeof(bufs[i]); - mmsg[i].msg_hdr.msg_iov = &msg_iov[i]; - mmsg[i].msg_hdr.msg_iovlen = 1; - mmsg[i].msg_hdr.msg_name = &remote_addr[i]; - mmsg[i].msg_hdr.msg_namelen = sizeof(remote_addr[i]); - mmsg[i].msg_hdr.msg_control = &msg_ctrl[i * CMSG_SPACE(sizeof(int))]; - mmsg[i].msg_hdr.msg_controllen = CMSG_SPACE(sizeof(int)); - } - - while((mcount = recvmmsg(qctx->sockfd, mmsg, n, 0, NULL)) == -1 && - (SOCKERRNO == SOCKEINTR || SOCKERRNO == SOCKEMSGSIZE)) - ; - if(mcount == -1) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { - CURL_TRC_CF(data, cf, "ingress, recvmmsg -> EAGAIN"); - goto out; - } - if(!cf->connected && SOCKERRNO == SOCKECONNREFUSED) { - struct ip_quadruple ip; - if(!Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip)) - failf(data, "QUIC: connection to %s port %u refused", - ip.remote_ip, ip.remote_port); - result = CURLE_COULDNT_CONNECT; - goto out; - } - curlx_strerror(SOCKERRNO, errstr, sizeof(errstr)); - failf(data, "QUIC: recvmmsg() unexpectedly returned %d (errno=%d; %s)", - mcount, SOCKERRNO, errstr); - result = CURLE_RECV_ERROR; - goto out; - } - - VERBOSE(++calls); - for(i = 0; i < mcount; ++i) { - /* A zero-length UDP packet is no QUIC packet. Ignore. */ - if(!mmsg[i].msg_len) - continue; - total_nread += mmsg[i].msg_len; - - gso_size = vquic_msghdr_get_udp_gro(&mmsg[i].msg_hdr); - if(gso_size == 0) - gso_size = mmsg[i].msg_len; - - result = recv_cb(bufs[i], mmsg[i].msg_len, gso_size, - mmsg[i].msg_hdr.msg_name, - mmsg[i].msg_hdr.msg_namelen, 0, userp); - if(result) - goto out; - pkts += (mmsg[i].msg_len + gso_size - 1) / gso_size; - } - } - -out: - if(total_nread || result) - CURL_TRC_CF(data, cf, "vquic_recvmmsg(len=%zu, packets=%zu, calls=%zu)" - " -> %d", total_nread, pkts, calls, result); - Curl_multi_xfer_sockbuf_release(data, sockbuf); - return result; -} - -#elif defined(HAVE_SENDMSG) -static CURLcode recvmsg_packets(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - size_t max_pkts, - vquic_recv_pkts_cb *recv_cb, void *userp) -{ - struct iovec msg_iov; - struct msghdr msg; - uint8_t buf[64 * 1024]; - struct sockaddr_storage remote_addr; - size_t total_nread, pkts, calls; - ssize_t rc; - size_t nread; - char errstr[STRERROR_LEN]; - CURLcode result = CURLE_OK; - uint8_t msg_ctrl[CMSG_SPACE(sizeof(int))]; - size_t gso_size; - - DEBUGASSERT(max_pkts > 0); - for(pkts = 0, total_nread = 0, calls = 0; pkts < max_pkts;) { - /* fully initialise this on each call to `recvmsg()`. There seem to - * operating systems out there that mess with `msg_iov.iov_len`. */ - memset(&msg, 0, sizeof(msg)); - msg_iov.iov_base = buf; - msg_iov.iov_len = (int)sizeof(buf); - msg.msg_iov = &msg_iov; - msg.msg_iovlen = 1; - msg.msg_control = msg_ctrl; - msg.msg_name = &remote_addr; - msg.msg_namelen = sizeof(remote_addr); - msg.msg_controllen = sizeof(msg_ctrl); - - while((rc = recvmsg(qctx->sockfd, &msg, 0)) == -1 && - (SOCKERRNO == SOCKEINTR || SOCKERRNO == SOCKEMSGSIZE)) - ; - if(!curlx_sztouz(rc, &nread)) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { - goto out; - } - if(!cf->connected && SOCKERRNO == SOCKECONNREFUSED) { - struct ip_quadruple ip; - if(!Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip)) - failf(data, "QUIC: connection to %s port %u refused", - ip.remote_ip, ip.remote_port); - result = CURLE_COULDNT_CONNECT; - goto out; - } - curlx_strerror(SOCKERRNO, errstr, sizeof(errstr)); - failf(data, "QUIC: recvmsg() unexpectedly returned %zd (errno=%d; %s)", - rc, SOCKERRNO, errstr); - result = CURLE_RECV_ERROR; - goto out; - } - - total_nread += nread; - ++calls; - - /* A 0-length UDP packet is no QUIC packet */ - if(!nread) - continue; - - gso_size = vquic_msghdr_get_udp_gro(&msg); - if(gso_size == 0) - gso_size = nread; - - result = recv_cb(buf, nread, gso_size, - msg.msg_name, msg.msg_namelen, 0, userp); - if(result) - goto out; - pkts += (nread + gso_size - 1) / gso_size; - } - -out: - if(total_nread || result) - CURL_TRC_CF(data, cf, "vquic_recvmsg(len=%zu, packets=%zu, calls=%zu)" - " -> %d", total_nread, pkts, calls, result); - return result; -} - -#else /* HAVE_SENDMMSG || HAVE_SENDMSG */ -static CURLcode recvfrom_packets(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - size_t max_pkts, - vquic_recv_pkts_cb *recv_cb, void *userp) -{ - uint8_t buf[64 * 1024]; - int bufsize = (int)sizeof(buf); - struct sockaddr_storage remote_addr; - socklen_t remote_addrlen = sizeof(remote_addr); - size_t total_nread, pkts, calls = 0, nread; - ssize_t rv; - char errstr[STRERROR_LEN]; - CURLcode result = CURLE_OK; - - DEBUGASSERT(max_pkts > 0); - for(pkts = 0, total_nread = 0; pkts < max_pkts;) { - while((rv = recvfrom(qctx->sockfd, (char *)buf, bufsize, 0, - (struct sockaddr *)&remote_addr, - &remote_addrlen)) == -1 && - (SOCKERRNO == SOCKEINTR || SOCKERRNO == SOCKEMSGSIZE)) - ; - if(!curlx_sztouz(rv, &nread)) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == SOCKEWOULDBLOCK) { - CURL_TRC_CF(data, cf, "ingress, recvfrom -> EAGAIN"); - goto out; - } - if(!cf->connected && SOCKERRNO == SOCKECONNREFUSED) { - struct ip_quadruple ip; - if(!Curl_cf_socket_peek(cf->next, data, NULL, NULL, &ip)) - failf(data, "QUIC: connection to %s port %u refused", - ip.remote_ip, ip.remote_port); - result = CURLE_COULDNT_CONNECT; - goto out; - } - curlx_strerror(SOCKERRNO, errstr, sizeof(errstr)); - failf(data, "QUIC: recvfrom() unexpectedly returned %zd (errno=%d; %s)", - rv, SOCKERRNO, errstr); - result = CURLE_RECV_ERROR; - goto out; - } - - ++pkts; - ++calls; - - /* A 0-length UDP packet is no QUIC packet */ - if(!nread) - continue; - - total_nread += nread; - result = recv_cb(buf, nread, nread, &remote_addr, remote_addrlen, - 0, userp); - if(result) - goto out; - } - -out: - if(total_nread || result) - CURL_TRC_CF(data, cf, "vquic_recvfrom(len=%zu, packets=%zu, calls=%zu)" - " -> %d", total_nread, pkts, calls, result); - return result; -} -#endif /* !HAVE_SENDMMSG && !HAVE_SENDMSG */ - -CURLcode vquic_recv_packets(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - size_t max_pkts, - vquic_recv_pkts_cb *recv_cb, void *userp) -{ - CURLcode result; -#ifdef HAVE_SENDMMSG - result = recvmmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); -#elif defined(HAVE_SENDMSG) - result = recvmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); -#else - result = recvfrom_packets(cf, data, qctx, max_pkts, recv_cb, userp); -#endif - if(!result) { - if(!qctx->got_first_byte) { - qctx->got_first_byte = TRUE; - qctx->first_byte_at = qctx->last_op; - } - qctx->last_io = qctx->last_op; - } - return result; -} - -/* - * If the QLOGDIR environment variable is set, open and return a file - * descriptor to write the log to. - * - * This function returns error if something failed outside of failing to - * create the file. Open file success is deemed by seeing if the returned fd - * is != -1. - */ -CURLcode Curl_qlogdir(struct Curl_easy *data, - unsigned char *scid, - size_t scidlen, - int *qlogfdp) -{ - char *qlog_dir = curl_getenv("QLOGDIR"); - *qlogfdp = -1; - if(qlog_dir) { - struct dynbuf fname; - CURLcode result; - unsigned int i; - curlx_dyn_init(&fname, DYN_QLOG_NAME); - result = curlx_dyn_add(&fname, qlog_dir); - if(!result) - result = curlx_dyn_add(&fname, "/"); - for(i = 0; (i < scidlen) && !result; i++) { - char hex[3]; - curl_msnprintf(hex, 3, "%02x", scid[i]); - result = curlx_dyn_add(&fname, hex); - } - if(!result) - result = curlx_dyn_add(&fname, ".sqlog"); - - if(!result) { - int qlogfd = curlx_open(curlx_dyn_ptr(&fname), - O_WRONLY | O_CREAT | CURL_O_BINARY, - data->set.new_file_perms -#ifdef _WIN32 - & (_S_IREAD | _S_IWRITE) -#endif - ); - if(qlogfd != -1) - *qlogfdp = qlogfd; - } - curlx_dyn_free(&fname); - curlx_free(qlog_dir); - if(result) - return result; - } - - return CURLE_OK; -} - -CURLcode Curl_cf_quic_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport) -{ - (void)transport; - DEBUGASSERT(transport == TRNSPRT_QUIC); -#if defined(USE_NGTCP2) && defined(USE_NGHTTP3) - return Curl_cf_ngtcp2_create(pcf, data, conn, addr); -#elif defined(USE_QUICHE) - return Curl_cf_quiche_create(pcf, data, conn, addr); -#else - *pcf = NULL; - (void)data; - (void)conn; - (void)addr; - return CURLE_NOT_BUILT_IN; -#endif -} - -CURLcode Curl_conn_may_http3(struct Curl_easy *data, - const struct connectdata *conn, - unsigned char transport) -{ - if(transport == TRNSPRT_UNIX) { - failf(data, "HTTP/3 cannot be used over UNIX domain sockets"); - return CURLE_QUIC_CONNECT_ERROR; - } - if(!(conn->scheme->flags & PROTOPT_SSL)) { - failf(data, "HTTP/3 requested for non-HTTPS URL"); - return CURLE_URL_MALFORMAT; - } -#ifndef CURL_DISABLE_PROXY - if(conn->bits.socksproxy) { - failf(data, "HTTP/3 is not supported over a SOCKS proxy"); - return CURLE_URL_MALFORMAT; - } - if(conn->bits.httpproxy && conn->bits.tunnel_proxy) { - failf(data, "HTTP/3 is not supported over an HTTP proxy"); - return CURLE_URL_MALFORMAT; - } -#endif - - return CURLE_OK; -} - -#ifdef CURLVERBOSE -const char *vquic_h3_err_str(uint64_t error_code) -{ - if(error_code <= UINT_MAX) { - switch((unsigned int)error_code) { - case CURL_H3_ERR_NO_ERROR: - return "NO_ERROR"; - case CURL_H3_ERR_GENERAL_PROTOCOL_ERROR: - return "GENERAL_PROTOCOL_ERROR"; - case CURL_H3_ERR_INTERNAL_ERROR: - return "INTERNAL_ERROR"; - case CURL_H3_ERR_STREAM_CREATION_ERROR: - return "STREAM_CREATION_ERROR"; - case CURL_H3_ERR_CLOSED_CRITICAL_STREAM: - return "CLOSED_CRITICAL_STREAM"; - case CURL_H3_ERR_FRAME_UNEXPECTED: - return "FRAME_UNEXPECTED"; - case CURL_H3_ERR_FRAME_ERROR: - return "FRAME_ERROR"; - case CURL_H3_ERR_EXCESSIVE_LOAD: - return "EXCESSIVE_LOAD"; - case CURL_H3_ERR_ID_ERROR: - return "ID_ERROR"; - case CURL_H3_ERR_SETTINGS_ERROR: - return "SETTINGS_ERROR"; - case CURL_H3_ERR_MISSING_SETTINGS: - return "MISSING_SETTINGS"; - case CURL_H3_ERR_REQUEST_REJECTED: - return "REQUEST_REJECTED"; - case CURL_H3_ERR_REQUEST_CANCELLED: - return "REQUEST_CANCELLED"; - case CURL_H3_ERR_REQUEST_INCOMPLETE: - return "REQUEST_INCOMPLETE"; - case CURL_H3_ERR_MESSAGE_ERROR: - return "MESSAGE_ERROR"; - case CURL_H3_ERR_CONNECT_ERROR: - return "CONNECT_ERROR"; - case CURL_H3_ERR_VERSION_FALLBACK: - return "VERSION_FALLBACK"; - default: - break; - } - } - /* RFC 9114 ch. 8.1 + 9, reserved future error codes that are NO_ERROR */ - if((error_code >= 0x21) && !((error_code - 0x21) % 0x1f)) - return "NO_ERROR"; - return "unknown"; -} -#endif /* CURLVERBOSE */ - -#if defined(USE_NGTCP2) || defined(USE_NGHTTP3) - -static void *vquic_ngtcp2_malloc(size_t size, void *user_data) -{ - (void)user_data; - return Curl_cmalloc(size); -} - -static void vquic_ngtcp2_free(void *ptr, void *user_data) -{ - (void)user_data; - Curl_cfree(ptr); -} - -static void *vquic_ngtcp2_calloc(size_t nmemb, size_t size, void *user_data) -{ - (void)user_data; - return Curl_ccalloc(nmemb, size); -} - -static void *vquic_ngtcp2_realloc(void *ptr, size_t size, void *user_data) -{ - (void)user_data; - return Curl_crealloc(ptr, size); -} - -#ifdef USE_NGTCP2 -static struct ngtcp2_mem vquic_ngtcp2_mem = { - NULL, - vquic_ngtcp2_malloc, - vquic_ngtcp2_free, - vquic_ngtcp2_calloc, - vquic_ngtcp2_realloc -}; -struct ngtcp2_mem *Curl_ngtcp2_mem(void) -{ - return &vquic_ngtcp2_mem; -} -#endif - -#ifdef USE_NGHTTP3 -static struct nghttp3_mem vquic_nghttp3_mem = { - NULL, - vquic_ngtcp2_malloc, - vquic_ngtcp2_free, - vquic_ngtcp2_calloc, - vquic_ngtcp2_realloc -}; -struct nghttp3_mem *Curl_nghttp3_mem(void) -{ - return &vquic_nghttp3_mem; -} -#endif - -#endif /* USE_NGTCP2 || USE_NGHTTP3 */ - -#else /* CURL_DISABLE_HTTP || !USE_HTTP3 */ - -CURLcode Curl_conn_may_http3(struct Curl_easy *data, - const struct connectdata *conn, - unsigned char transport) -{ - (void)data; - (void)conn; - (void)transport; - DEBUGF(infof(data, "QUIC is not supported in this build")); - return CURLE_NOT_BUILT_IN; -} - -#endif /* !CURL_DISABLE_HTTP && USE_HTTP3 */ diff --git a/vendor/curl/lib/vquic/vquic.h b/vendor/curl/lib/vquic/vquic.h deleted file mode 100644 index 1f0a1ab5e..000000000 --- a/vendor/curl/lib/vquic/vquic.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef HEADER_CURL_VQUIC_QUIC_H -#define HEADER_CURL_VQUIC_QUIC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP3) -struct Curl_cfilter; -struct Curl_easy; -struct connectdata; -struct Curl_addrinfo; - -void Curl_quic_ver(char *p, size_t len); -int Curl_vquic_init(void); - -CURLcode Curl_qlogdir(struct Curl_easy *data, - unsigned char *scid, - size_t scidlen, - int *qlogfdp); - -CURLcode Curl_cf_quic_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn, - struct Curl_sockaddr_ex *addr, - uint8_t transport); - -extern struct Curl_cftype Curl_cft_http3; - -#else -#define Curl_vquic_init() 1 -#endif /* !CURL_DISABLE_HTTP && USE_HTTP3 */ - -CURLcode Curl_conn_may_http3(struct Curl_easy *data, - const struct connectdata *conn, - unsigned char transport); - -#endif /* HEADER_CURL_VQUIC_QUIC_H */ diff --git a/vendor/curl/lib/vquic/vquic_int.h b/vendor/curl/lib/vquic/vquic_int.h deleted file mode 100644 index 82bd5b035..000000000 --- a/vendor/curl/lib/vquic/vquic_int.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef HEADER_CURL_VQUIC_QUIC_INT_H -#define HEADER_CURL_VQUIC_QUIC_INT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_HTTP3 - -#include "bufq.h" - -#define MAX_UDP_PAYLOAD_SIZE 1452 - -/* definitions from RFC 9114, ch 8.1 */ -typedef enum { - CURL_H3_ERR_NO_ERROR = 0x0100, - CURL_H3_ERR_GENERAL_PROTOCOL_ERROR = 0x0101, - CURL_H3_ERR_INTERNAL_ERROR = 0x0102, - CURL_H3_ERR_STREAM_CREATION_ERROR = 0x0103, - CURL_H3_ERR_CLOSED_CRITICAL_STREAM = 0x0104, - CURL_H3_ERR_FRAME_UNEXPECTED = 0x0105, - CURL_H3_ERR_FRAME_ERROR = 0x0106, - CURL_H3_ERR_EXCESSIVE_LOAD = 0x0107, - CURL_H3_ERR_ID_ERROR = 0x0108, - CURL_H3_ERR_SETTINGS_ERROR = 0x0109, - CURL_H3_ERR_MISSING_SETTINGS = 0x010a, - CURL_H3_ERR_REQUEST_REJECTED = 0x010b, - CURL_H3_ERR_REQUEST_CANCELLED = 0x010c, - CURL_H3_ERR_REQUEST_INCOMPLETE = 0x010d, - CURL_H3_ERR_MESSAGE_ERROR = 0x010e, - CURL_H3_ERR_CONNECT_ERROR = 0x010f, - CURL_H3_ERR_VERSION_FALLBACK = 0x0110, -} vquic_h3_error; - -#ifdef CURLVERBOSE -const char *vquic_h3_err_str(uint64_t error_code); -#else -#define vquic_h3_err_str(x) "" -#endif /* CURLVERBOSE */ - -struct cf_quic_ctx { - curl_socket_t sockfd; /* connected UDP socket */ - struct sockaddr_storage local_addr; /* address socket is bound to */ - socklen_t local_addrlen; /* length of local address */ - - struct bufq sendbuf; /* buffer for sending one or more packets */ - struct curltime first_byte_at; /* when first byte was recvd */ - struct curltime last_op; /* last (attempted) send/recv operation */ - struct curltime last_io; /* last successful socket IO */ - size_t gsolen; /* length of individual packets in send buf */ - size_t split_len; /* if != 0, buffer length after which GSO differs */ - size_t split_gsolen; /* length of individual packets after split_len */ -#ifdef DEBUGBUILD - int wblock_percent; /* percent of writes doing EAGAIN */ -#endif - BIT(got_first_byte); /* if first byte was received */ - BIT(no_gso); /* do not use gso on sending */ -}; - -#define H3_STREAM_CTX(ctx, data) \ - ((data) ? Curl_uint32_hash_get(&(ctx)->streams, (data)->mid) : NULL) - -CURLcode vquic_ctx_init(struct Curl_easy *data, - struct cf_quic_ctx *qctx); -void vquic_ctx_free(struct cf_quic_ctx *qctx); - -void vquic_ctx_set_time(struct cf_quic_ctx *qctx, - const struct curltime *pnow); - -void vquic_ctx_update_time(struct cf_quic_ctx *qctx, - const struct curltime *pnow); - -void vquic_push_blocked_pkt(struct Curl_cfilter *cf, - struct cf_quic_ctx *qctx, - const uint8_t *pkt, size_t pktlen, size_t gsolen); - -CURLcode vquic_send_blocked_pkts(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx); - -CURLcode vquic_send(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx, size_t gsolen); - -CURLcode vquic_send_tail_split(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx, size_t gsolen, - size_t tail_len, size_t tail_gsolen); - -CURLcode vquic_flush(struct Curl_cfilter *cf, struct Curl_easy *data, - struct cf_quic_ctx *qctx); - -typedef CURLcode vquic_recv_pkts_cb(const unsigned char *buf, size_t buflen, - size_t gso_size, - struct sockaddr_storage *remote_addr, - socklen_t remote_addrlen, int ecn, - void *userp); - -CURLcode vquic_recv_packets(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct cf_quic_ctx *qctx, - size_t max_pkts, - vquic_recv_pkts_cb *recv_cb, void *userp); - -#ifdef USE_NGTCP2 -struct ngtcp2_mem; -struct ngtcp2_mem *Curl_ngtcp2_mem(void); -#endif -#ifdef USE_NGHTTP3 -struct nghttp3_mem; -struct nghttp3_mem *Curl_nghttp3_mem(void); -#endif - -#endif /* !USE_HTTP3 */ - -#endif /* HEADER_CURL_VQUIC_QUIC_INT_H */ diff --git a/vendor/curl/lib/vssh/libssh.c b/vendor/curl/lib/vssh/libssh.c deleted file mode 100644 index 44094e466..000000000 --- a/vendor/curl/lib/vssh/libssh.c +++ /dev/null @@ -1,3139 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Red Hat, Inc. - * - * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek, - * Robert Kolcun, Andreas Schneider - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_LIBSSH - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "curl_trc.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "vssh/ssh.h" -#include "url.h" -#include "cfilters.h" -#include "connect.h" -#include "parsedate.h" /* for the week day and month names */ -#include "curlx/strparse.h" -#include "multiif.h" -#include "select.h" -#include "vssh/vssh.h" - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -/* A recent macro provided by libssh. Or make our own. */ -#ifndef SSH_STRING_FREE_CHAR -#define SSH_STRING_FREE_CHAR(x) \ - do { \ - if(x) { \ - ssh_string_free_char(x); \ - x = NULL; \ - } \ - } while(0) -#endif - -/* These stat values may not be the same as the user's S_IFMT / S_IFLNK */ -#ifndef SSH_S_IFMT -#define SSH_S_IFMT 00170000 -#endif -#ifndef SSH_S_IFLNK -#define SSH_S_IFLNK 0120000 -#endif - -static CURLcode sftp_error_to_CURLE(int err) -{ - switch(err) { - case SSH_FX_OK: - return CURLE_OK; - - case SSH_FX_NO_SUCH_FILE: - case SSH_FX_NO_SUCH_PATH: - return CURLE_REMOTE_FILE_NOT_FOUND; - - case SSH_FX_PERMISSION_DENIED: - case SSH_FX_WRITE_PROTECT: - return CURLE_REMOTE_ACCESS_DENIED; - - case SSH_FX_FILE_ALREADY_EXISTS: - return CURLE_REMOTE_FILE_EXISTS; - - default: - break; - } - - return CURLE_SSH; -} - -/* Multiple options: - * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5 - * hash (90s style auth, not sure we should have it here) - * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first - * use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE - * is returned by it. - * 3. none of the above. We only accept if it is present on known hosts. - * - * Returns SSH_OK or SSH_ERROR. - */ -static int myssh_is_known(struct Curl_easy *data, struct ssh_conn *sshc) -{ - int rc; - ssh_key pubkey; - size_t hlen; - unsigned char *hash = NULL; - char *found_base64 = NULL; - char *known_base64 = NULL; - int vstate; - enum curl_khmatch keymatch; - struct curl_khkey foundkey; - struct curl_khkey *knownkeyp = NULL; - curl_sshkeycallback func = data->set.ssh_keyfunc; - struct ssh_knownhosts_entry *knownhostsentry = NULL; - struct curl_khkey knownkey; - - rc = ssh_get_server_publickey(sshc->ssh_session, &pubkey); - - if(rc != SSH_OK) - return rc; - - if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) { - int i; - char md5buffer[33]; - const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; - - rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen); - if(rc != SSH_OK || hlen != 16) { - failf(data, - "Denied establishing ssh session: MD5 fingerprint not available"); - goto cleanup; - } - - for(i = 0; i < 16; i++) - curl_msnprintf(&md5buffer[i * 2], 3, "%02x", hash[i]); - - infof(data, "SSH MD5 fingerprint: %s", md5buffer); - - if(!curl_strequal(md5buffer, pubkey_md5)) { - failf(data, - "Denied establishing ssh session: mismatch MD5 fingerprint. " - "Remote %s is not equal to %s", md5buffer, pubkey_md5); - rc = SSH_ERROR; - goto cleanup; - } - - rc = SSH_OK; - goto cleanup; - } - - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - - /* Get the known_key from the known hosts file */ - vstate = ssh_session_get_known_hosts_entry(sshc->ssh_session, - &knownhostsentry); - - /* Case an entry was found in a known hosts file */ - if(knownhostsentry) { - if(knownhostsentry->publickey) { - rc = ssh_pki_export_pubkey_base64(knownhostsentry->publickey, - &known_base64); - if(rc != SSH_OK) { - goto cleanup; - } - knownkey.key = known_base64; - knownkey.len = strlen(known_base64); - - switch(ssh_key_type(knownhostsentry->publickey)) { - case SSH_KEYTYPE_RSA: - knownkey.keytype = CURLKHTYPE_RSA; - break; - case SSH_KEYTYPE_RSA1: - knownkey.keytype = CURLKHTYPE_RSA1; - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_ECDSA_P256: - case SSH_KEYTYPE_ECDSA_P384: - case SSH_KEYTYPE_ECDSA_P521: - knownkey.keytype = CURLKHTYPE_ECDSA; - break; - case SSH_KEYTYPE_ED25519: - knownkey.keytype = CURLKHTYPE_ED25519; - break; - case SSH_KEYTYPE_DSS: - knownkey.keytype = CURLKHTYPE_DSS; - break; - default: - rc = SSH_ERROR; - goto cleanup; - } - knownkeyp = &knownkey; - } - } - - switch(vstate) { - case SSH_KNOWN_HOSTS_OK: - keymatch = CURLKHMATCH_OK; - break; - case SSH_KNOWN_HOSTS_OTHER: - case SSH_KNOWN_HOSTS_NOT_FOUND: - case SSH_KNOWN_HOSTS_UNKNOWN: - case SSH_KNOWN_HOSTS_ERROR: - keymatch = CURLKHMATCH_MISSING; - break; - default: - keymatch = CURLKHMATCH_MISMATCH; - break; - } - - if(func) { /* use callback to determine action */ - rc = ssh_pki_export_pubkey_base64(pubkey, &found_base64); - if(rc != SSH_OK) - goto cleanup; - - foundkey.key = found_base64; - foundkey.len = strlen(found_base64); - - switch(ssh_key_type(pubkey)) { - case SSH_KEYTYPE_RSA: - foundkey.keytype = CURLKHTYPE_RSA; - break; - case SSH_KEYTYPE_RSA1: - foundkey.keytype = CURLKHTYPE_RSA1; - break; - case SSH_KEYTYPE_ECDSA: - case SSH_KEYTYPE_ECDSA_P256: - case SSH_KEYTYPE_ECDSA_P384: - case SSH_KEYTYPE_ECDSA_P521: - foundkey.keytype = CURLKHTYPE_ECDSA; - break; - case SSH_KEYTYPE_ED25519: - foundkey.keytype = CURLKHTYPE_ED25519; - break; - case SSH_KEYTYPE_DSS: - foundkey.keytype = CURLKHTYPE_DSS; - break; - default: - rc = SSH_ERROR; - goto cleanup; - } - - Curl_set_in_callback(data, TRUE); - rc = func(data, knownkeyp, /* from the knownhosts file */ - &foundkey, /* from the remote host */ - keymatch, data->set.ssh_keyfunc_userp); - Curl_set_in_callback(data, FALSE); - - switch(rc) { - case CURLKHSTAT_FINE_ADD_TO_FILE: - rc = ssh_session_update_known_hosts(sshc->ssh_session); - if(rc != SSH_OK) { - goto cleanup; - } - break; - case CURLKHSTAT_FINE: - break; - default: /* REJECT/DEFER */ - rc = SSH_ERROR; - goto cleanup; - } - } - else { - if(keymatch != CURLKHMATCH_OK) { - rc = SSH_ERROR; - goto cleanup; - } - } - } - rc = SSH_OK; - -cleanup: - if(found_base64) { - /* !checksrc! disable BANNEDFUNC 1 */ - free(found_base64); /* allocated by libssh, deallocate with system free */ - } - if(known_base64) { - /* !checksrc! disable BANNEDFUNC 1 */ - free(known_base64); /* allocated by libssh, deallocate with system free */ - } - if(hash) - ssh_clean_pubkey_hash(&hash); - ssh_key_free(pubkey); - if(knownhostsentry) { - ssh_knownhosts_entry_free(knownhostsentry); - } - return rc; -} - -static int myssh_to_ERROR(struct Curl_easy *data, - struct ssh_conn *sshc, - CURLcode result) -{ - myssh_to(data, sshc, SSH_SESSION_DISCONNECT); - sshc->actualcode = result; - return SSH_ERROR; -} - -static int myssh_to_SFTP_CLOSE(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); - return SSH_ERROR; -} - -static int myssh_to_PASSWD_AUTH(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { - myssh_to(data, sshc, SSH_AUTH_PASS_INIT); - return SSH_OK; - } - return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); -} - -static int myssh_to_KEY_AUTH(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { - myssh_to(data, sshc, SSH_AUTH_KEY_INIT); - return SSH_OK; - } - return myssh_to_PASSWD_AUTH(data, sshc); -} - -static int myssh_to_GSSAPI_AUTH(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { - myssh_to(data, sshc, SSH_AUTH_GSSAPI); - return SSH_OK; - } - return myssh_to_KEY_AUTH(data, sshc); -} - -static int myssh_in_SFTP_READDIR_INIT(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - Curl_pgrsSetDownloadSize(data, -1); - if(data->req.no_body) { - myssh_to(data, sshc, SSH_STOP); - return SSH_NO_ERROR; - } - - /* - * This is a directory that we are trying to get, so produce a directory - * listing - */ - sshc->sftp_dir = sftp_opendir(sshc->sftp_session, - sshp->path); - if(!sshc->sftp_dir) { - failf(data, "Could not open directory for reading: %s", - ssh_get_error(sshc->ssh_session)); - return myssh_to_SFTP_CLOSE(data, sshc); - } - myssh_to(data, sshc, SSH_SFTP_READDIR); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_READDIR(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - CURLcode result = CURLE_OK; - - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - curlx_dyn_reset(&sshc->readdir_buf); - if(sshc->readdir_attrs) - sftp_attributes_free(sshc->readdir_attrs); - - sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir); - if(sshc->readdir_attrs) { - sshc->readdir_filename = sshc->readdir_attrs->name; - sshc->readdir_longentry = sshc->readdir_attrs->longname; - sshc->readdir_len = strlen(sshc->readdir_filename); - - if(data->set.list_only) { - char *tmpLine; - - tmpLine = curl_maprintf("%s\n", sshc->readdir_filename); - if(!tmpLine) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - return SSH_ERROR; - } - result = Curl_client_write(data, CLIENTWRITE_BODY, - tmpLine, sshc->readdir_len + 1); - curlx_free(tmpLine); - - if(result) { - myssh_to(data, sshc, SSH_STOP); - sshc->actualcode = result; - return SSH_NO_ERROR; - } - } - else { - if(curlx_dyn_add(&sshc->readdir_buf, sshc->readdir_longentry)) { - sshc->actualcode = CURLE_OUT_OF_MEMORY; - myssh_to(data, sshc, SSH_STOP); - return SSH_ERROR; - } - - if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && - ((sshc->readdir_attrs->permissions & SSH_S_IFMT) == - SSH_S_IFLNK)) { - sshc->readdir_linkPath = curl_maprintf("%s%s", sshp->path, - sshc->readdir_filename); - - if(!sshc->readdir_linkPath) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - return SSH_ERROR; - } - - myssh_to(data, sshc, SSH_SFTP_READDIR_LINK); - return SSH_NO_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM); - return SSH_NO_ERROR; - } - } - else if(sftp_dir_eof(sshc->sftp_dir)) { - myssh_to(data, sshc, SSH_SFTP_READDIR_DONE); - } - else { - failf(data, "Could not open remote directory for reading: %s", - ssh_get_error(sshc->ssh_session)); - return myssh_to_SFTP_CLOSE(data, sshc); - } - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_READDIR_LINK(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->readdir_link_attrs) - sftp_attributes_free(sshc->readdir_link_attrs); - - sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session, - sshc->readdir_linkPath); - if(!sshc->readdir_link_attrs) { - failf(data, "Could not read symlink for reading: %s", - ssh_get_error(sshc->ssh_session)); - return myssh_to_SFTP_CLOSE(data, sshc); - } - - if(!sshc->readdir_link_attrs->name) { - sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, - sshc->readdir_linkPath); - if(!sshc->readdir_tmp) - sshc->readdir_len = 0; - else - sshc->readdir_len = strlen(sshc->readdir_tmp); - sshc->readdir_longentry = NULL; - sshc->readdir_filename = sshc->readdir_tmp; - } - else { - sshc->readdir_len = strlen(sshc->readdir_link_attrs->name); - sshc->readdir_filename = sshc->readdir_link_attrs->name; - sshc->readdir_longentry = sshc->readdir_link_attrs->longname; - } - - curlx_safefree(sshc->readdir_linkPath); - - if(curlx_dyn_addf(&sshc->readdir_buf, " -> %s", sshc->readdir_filename)) { - /* Not using: - * return myssh_to_SFTP_CLOSE(data, sshc); - * - * as that assumes an sftp related error while - * assigning sshc->actualcode whereas the current - * error is curlx_dyn_addf() related. - */ - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - return SSH_ERROR; - } - - sftp_attributes_free(sshc->readdir_link_attrs); - sshc->readdir_link_attrs = NULL; - sshc->readdir_filename = NULL; - sshc->readdir_longentry = NULL; - - myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_READDIR_BOTTOM(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - CURLcode result; - - if(curlx_dyn_addn(&sshc->readdir_buf, "\n", 1)) - result = CURLE_OUT_OF_MEMORY; - else - result = Curl_client_write(data, CLIENTWRITE_BODY, - curlx_dyn_ptr(&sshc->readdir_buf), - curlx_dyn_len(&sshc->readdir_buf)); - - ssh_string_free_char(sshc->readdir_tmp); - sshc->readdir_tmp = NULL; - - if(result) { - myssh_to(data, sshc, SSH_STOP); - sshc->actualcode = result; - } - else - myssh_to(data, sshc, SSH_SFTP_READDIR); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_READDIR_DONE(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - sftp_closedir(sshc->sftp_dir); - sshc->sftp_dir = NULL; - - /* no data to transfer */ - Curl_xfer_setup_nop(data); - myssh_to(data, sshc, SSH_STOP); - return SSH_NO_ERROR; -} - -static void myssh_quote_error(struct Curl_easy *data, struct ssh_conn *sshc, - const char *cmd) -{ - if(cmd) - failf(data, "%s command failed: %s", cmd, - ssh_get_error(sshc->ssh_session)); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; -} - -static int myssh_in_SFTP_QUOTE_STATVFS(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - sftp_statvfs_t statvfs; - - statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1); - if(!statvfs && !sshc->acceptfail) { - myssh_quote_error(data, sshc, "statvfs"); - return SSH_OK; - } - else if(statvfs) { -#ifdef _MSC_VER -#define CURL_LIBSSH_VFS_SIZE_MASK "I64u" -#elif defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR <= 6) -#define CURL_LIBSSH_VFS_SIZE_MASK "llu" -#else -#define CURL_LIBSSH_VFS_SIZE_MASK PRIu64 -#endif - CURLcode result = CURLE_OK; - char *tmp = curl_maprintf("statvfs:\n" - "f_bsize: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_frsize: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_blocks: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_bfree: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_bavail: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_files: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_ffree: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_favail: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_fsid: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_flag: %" CURL_LIBSSH_VFS_SIZE_MASK "\n" - "f_namemax: %" CURL_LIBSSH_VFS_SIZE_MASK "\n", - statvfs->f_bsize, statvfs->f_frsize, - statvfs->f_blocks, statvfs->f_bfree, - statvfs->f_bavail, statvfs->f_files, - statvfs->f_ffree, statvfs->f_favail, - statvfs->f_fsid, statvfs->f_flag, - statvfs->f_namemax); - sftp_statvfs_free(statvfs); - - if(!tmp) - result = CURLE_OUT_OF_MEMORY; - - if(!result) { - result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - curlx_free(tmp); - } - if(result) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_OK; -} - -static int myssh_auth_interactive(struct connectdata *conn, - struct ssh_conn *sshc) -{ - int rc; - int nprompts; - -restart: - switch(sshc->kbd_state) { - case 0: - rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - - if(rc != SSH_AUTH_INFO) - return SSH_ERROR; - - nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); - if(nprompts != 1) - return SSH_ERROR; - - rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd); - if(rc < 0) - return SSH_ERROR; - - FALLTHROUGH(); - case 1: - sshc->kbd_state = 1; - - rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - else if(rc == SSH_AUTH_SUCCESS) - rc = SSH_OK; - else if(rc == SSH_AUTH_INFO) { - nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); - if(nprompts) - return SSH_ERROR; - - sshc->kbd_state = 2; - goto restart; - } - else - rc = SSH_ERROR; - break; - case 2: - sshc->kbd_state = 2; - - rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - else if(rc == SSH_AUTH_SUCCESS) - rc = SSH_OK; - else - rc = SSH_ERROR; - - break; - default: - return SSH_ERROR; - } - - sshc->kbd_state = 0; - return rc; -} - -static void myssh_state_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - sshc->secondCreateDirs = 0; - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_OK; - -#if 0 - ssh_set_log_level(SSH_LOG_PROTOCOL); -#endif - - /* Set libssh to non-blocking, since everything internally is - non-blocking */ - ssh_set_blocking(sshc->ssh_session, 0); - - myssh_to(data, sshc, SSH_S_STARTUP); -} - -static void myssh_block2waitfor(struct connectdata *conn, - struct ssh_conn *sshc, - bool block) -{ - (void)conn; - if(block) { - int dir = ssh_get_poll_flags(sshc->ssh_session); - /* translate the libssh define bits into our own bit defines */ - sshc->waitfor = - ((dir & SSH_READ_PENDING) ? REQ_IO_RECV : 0) | - ((dir & SSH_WRITE_PENDING) ? REQ_IO_SEND : 0); - } - else - sshc->waitfor = 0; -} - -static int myssh_in_S_STARTUP(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - struct connectdata *conn = data->conn; - int rc = ssh_connect(sshc->ssh_session); - - myssh_block2waitfor(conn, sshc, (rc == SSH_AGAIN)); - if(rc == SSH_AGAIN) { - CURL_TRC_SSH(data, "connect -> EAGAIN"); - } - else if(rc != SSH_OK) { - failf(data, "Failure establishing ssh session"); - rc = myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - } - else - myssh_to(data, sshc, SSH_HOSTKEY); - - return rc; -} - -static int myssh_in_AUTHLIST(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc; - sshc->authed = FALSE; - - rc = ssh_userauth_none(sshc->ssh_session, NULL); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - - if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Authenticated with none"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return rc; - } - else if(rc == SSH_AUTH_ERROR) { - rc = myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); - return rc; - } - - sshc->auth_methods = - (unsigned int)ssh_userauth_list(sshc->ssh_session, NULL); - if(sshc->auth_methods) - infof(data, "SSH authentication methods available: %s%s%s%s", - sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY ? - "public key, " : "", - sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC ? - "GSSAPI, " : "", - sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE ? - "keyboard-interactive, " : "", - sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD ? - "password" : ""); - /* For public key auth we need either the private key or - CURLSSH_AUTH_AGENT. */ - if((sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) && - (data->set.str[STRING_SSH_PRIVATE_KEY] || - (data->set.ssh_auth_types & CURLSSH_AUTH_AGENT))) { - myssh_to(data, sshc, SSH_AUTH_PKEY_INIT); - infof(data, "Authentication using SSH public key file"); - } - else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { - myssh_to(data, sshc, SSH_AUTH_GSSAPI); - } - else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { - myssh_to(data, sshc, SSH_AUTH_KEY_INIT); - } - else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { - myssh_to(data, sshc, SSH_AUTH_PASS_INIT); - } - else { /* unsupported authentication method */ - rc = myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); - } - return rc; -} - -static int myssh_in_AUTH_PKEY_INIT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc; - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { - rc = myssh_to_GSSAPI_AUTH(data, sshc); - return rc; - } - - /* Two choices, (1) private key was given on CMD, - * (2) use the "default" keys. */ - if(data->set.str[STRING_SSH_PRIVATE_KEY]) { - if(sshc->pubkey && !data->set.ssl.key_passwd) { - rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL, sshc->pubkey); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - - if(rc != SSH_OK) { - rc = myssh_to_GSSAPI_AUTH(data, sshc); - return rc; - } - } - - rc = ssh_pki_import_privkey_file(data-> - set.str[STRING_SSH_PRIVATE_KEY], - data->set.ssl.key_passwd, NULL, - NULL, &sshc->privkey); - if(rc != SSH_OK) { - failf(data, "Could not load private key file %s", - data->set.str[STRING_SSH_PRIVATE_KEY]); - rc = myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); - return rc; - } - - myssh_to(data, sshc, SSH_AUTH_PKEY); - } - else { - rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL, - data->set.ssl.key_passwd); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - - if(rc == SSH_AUTH_SUCCESS) { - rc = SSH_OK; - sshc->authed = TRUE; - infof(data, "Completed public key authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return rc; - } - - rc = myssh_to_GSSAPI_AUTH(data, sshc); - } - return rc; -} - -static int myssh_in_AUTH_PKEY(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - else if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Completed public key authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return SSH_OK; - } - else { - infof(data, "Failed public key authentication (rc: %d)", rc); - return myssh_to_GSSAPI_AUTH(data, sshc); - } -} - -static int myssh_in_AUTH_GSSAPI(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc; - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) - return myssh_to_KEY_AUTH(data, sshc); - - rc = ssh_userauth_gssapi(sshc->ssh_session); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - - if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Completed gssapi authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return SSH_OK; - } - - return myssh_to_KEY_AUTH(data, sshc); -} - -static int myssh_in_AUTH_KEY_INIT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) { - myssh_to(data, sshc, SSH_AUTH_KEY); - return SSH_NO_ERROR; - } - return myssh_to_PASSWD_AUTH(data, sshc); -} - -static int myssh_in_AUTH_KEY(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* keyboard-interactive authentication */ - int rc = myssh_auth_interactive(data->conn, sshc); - if(rc == SSH_AGAIN) - return rc; - else if(rc == SSH_OK) { - sshc->authed = TRUE; - infof(data, "completed keyboard interactive authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return SSH_NO_ERROR; - } - else - return myssh_to_PASSWD_AUTH(data, sshc); -} - -static int myssh_in_AUTH_PASS_INIT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) - return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); - myssh_to(data, sshc, SSH_AUTH_PASS); - return SSH_NO_ERROR; -} - -static int myssh_in_AUTH_PASS(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = ssh_userauth_password(sshc->ssh_session, NULL, data->conn->passwd); - if(rc == SSH_AUTH_AGAIN) - return SSH_AGAIN; - else if(rc == SSH_AUTH_SUCCESS) { - sshc->authed = TRUE; - infof(data, "Completed password authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return SSH_NO_ERROR; - } - return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); -} - -static int myssh_in_AUTH_DONE(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - struct connectdata *conn = data->conn; - if(!sshc->authed) { - failf(data, "Authentication failure"); - return myssh_to_ERROR(data, sshc, CURLE_LOGIN_DENIED); - } - - /* At this point we have an authenticated ssh session. */ - infof(data, "Authentication complete"); - Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ - conn->recv_idx = FIRSTSOCKET; - conn->send_idx = -1; - - if(conn->scheme->protocol == CURLPROTO_SFTP) { - myssh_to(data, sshc, SSH_SFTP_INIT); - return SSH_NO_ERROR; - } - infof(data, "SSH CONNECT phase done"); - myssh_to(data, sshc, SSH_STOP); - return SSH_NO_ERROR; -} - -static int myssh_in_UPLOAD_INIT(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - int flags; - int rc = 0; - - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - if(data->state.resume_from) { - sftp_attributes attrs; - - if(data->state.resume_from < 0) { - attrs = sftp_stat(sshc->sftp_session, sshp->path); - if(attrs) { - curl_off_t size = attrs->size; - sftp_attributes_free(attrs); - if(size < 0) { - failf(data, "Bad file size (%" FMT_OFF_T ")", size); - rc = myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); - return rc; - } - data->state.resume_from = size; - } - else { - data->state.resume_from = 0; - } - } - } - - if(data->set.remote_append) { - /* True append mode: create if nonexisting */ - flags = O_WRONLY | O_CREAT | O_APPEND; - } - else if(data->state.resume_from > 0) { - /* - * Resume MUST NOT use O_APPEND. Many SFTP servers/impls force all - * writes to EOF when O_APPEND is set, ignoring a prior seek(). - * Open write-only and seek to the resume offset instead. - */ - flags = O_WRONLY; - } - else - /* Clear file before writing (normal behavior) */ - flags = O_WRONLY | O_CREAT | O_TRUNC; - - if(sshc->sftp_file) - sftp_close(sshc->sftp_file); - sshc->sftp_file = - sftp_open(sshc->sftp_session, sshp->path, - flags, (mode_t)data->set.new_file_perms); - if(!sshc->sftp_file) { - int err = sftp_get_error(sshc->sftp_session); - - if((err == SSH_FX_NO_SUCH_FILE || - err == SSH_FX_FAILURE || - err == SSH_FX_NO_SUCH_PATH) && - data->set.ftp_create_missing_dirs && - (strlen(sshp->path) > 1)) { - /* try to create the path remotely */ - rc = 0; - sshc->secondCreateDirs = 1; - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_INIT); - return rc; - } - else { - rc = myssh_to_SFTP_CLOSE(data, sshc); - return rc; - } - } - - /* If we have a restart point then we need to seek to the correct - position. Skip if in explicit remote append mode. */ - if(data->state.resume_from > 0 && !data->set.remote_append) { - int seekerr = CURL_SEEKFUNC_OK; - /* Let's read off the proper amount of bytes from the input. */ - if(data->set.seek_func) { - Curl_set_in_callback(data, TRUE); - seekerr = data->set.seek_func(data->set.seek_client, - data->state.resume_from, SEEK_SET); - Curl_set_in_callback(data, FALSE); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - curl_off_t passed = 0; - - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - rc = myssh_to_ERROR(data, sshc, CURLE_FTP_COULDNT_USE_REST); - return rc; - } - /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */ - do { - char scratch[4 * 1024]; - size_t readthisamountnow = - (data->state.resume_from - passed > - (curl_off_t)sizeof(scratch)) ? - sizeof(scratch) : curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread = - data->state.fread_func(scratch, 1, - readthisamountnow, data->state.in); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Failed to read data"); - rc = myssh_to_ERROR(data, sshc, CURLE_FTP_COULDNT_USE_REST); - return rc; - } - } while(passed < data->state.resume_from); - } - - /* now, decrease the size of the read */ - if(data->state.infilesize > 0) { - if(data->state.resume_from > data->state.infilesize) { - failf(data, "Resume point beyond size"); - return myssh_to_ERROR(data, sshc, CURLE_BAD_FUNCTION_ARGUMENT); - } - data->state.infilesize -= data->state.resume_from; - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - - rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc) { - rc = myssh_to_SFTP_CLOSE(data, sshc); - return rc; - } - } - if(data->state.infilesize > 0) { - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - /* upload data */ - Curl_xfer_setup_send(data, FIRSTSOCKET); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->recv_idx = FIRSTSOCKET; - - /* since we do not really wait for anything at this point, we want the - state machine to move on as soon as possible so we mark this as dirty */ - Curl_multi_mark_dirty(data); -#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - sshc->sftp_send_state = 0; -#endif - myssh_to(data, sshc, SSH_STOP); - return rc; -} - -static int myssh_in_SFTP_DOWNLOAD_INIT(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - /* Work on getting the specified file */ - if(sshc->sftp_file) - sftp_close(sshc->sftp_file); - - sshc->sftp_file = sftp_open(sshc->sftp_session, sshp->path, - O_RDONLY, (mode_t)data->set.new_file_perms); - if(!sshc->sftp_file) { - failf(data, "Could not open remote file for reading: %s", - ssh_get_error(sshc->ssh_session)); - - return myssh_to_SFTP_CLOSE(data, sshc); - } - sftp_file_set_nonblocking(sshc->sftp_file); - myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_STAT); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_DOWNLOAD_STAT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - curl_off_t size; - int rc = 0; - sftp_attributes attrs = sftp_fstat(sshc->sftp_file); - if(!attrs || - !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) || - (attrs->size == 0)) { - /* - * sftp_fstat did not return an error, so maybe the server - * does not support stat() - * OR the server does not return a file size with a stat() - * OR file size is 0 - */ - data->req.size = -1; - data->req.maxdownload = -1; - Curl_pgrsSetDownloadSize(data, -1); - size = 0; - if(attrs) - sftp_attributes_free(attrs); - } - else { - size = attrs->size; - - sftp_attributes_free(attrs); - - if(size < 0) { - failf(data, "Bad file size (%" FMT_OFF_T ")", size); - return myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); - } - if(data->state.use_range) { - curl_off_t from; - CURLcode result = Curl_ssh_range(data, data->state.range, size, - &from, &size); - if(result) - return myssh_to_ERROR(data, sshc, result); - - rc = sftp_seek64(sshc->sftp_file, from); - if(rc) - return myssh_to_SFTP_CLOSE(data, sshc); - } - data->req.size = size; - data->req.maxdownload = size; - Curl_pgrsSetDownloadSize(data, size); - } - - /* We can resume if we can seek to the resume position */ - if(data->state.resume_from) { - if(data->state.resume_from < 0) { - /* We are supposed to download the last abs(from) bytes */ - if(size < -data->state.resume_from) { - failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" - FMT_OFF_T ")", data->state.resume_from, size); - return myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); - } - /* download from where? */ - data->state.resume_from += size; - } - else { - if(size < data->state.resume_from) { - failf(data, "Offset (%" FMT_OFF_T - ") was beyond file size (%" FMT_OFF_T ")", - data->state.resume_from, size); - return myssh_to_ERROR(data, sshc, CURLE_BAD_DOWNLOAD_RESUME); - } - } - /* Now store the number of bytes we are expected to download */ - data->req.size = size - data->state.resume_from; - data->req.maxdownload = size - data->state.resume_from; - Curl_pgrsSetDownloadSize(data, size - data->state.resume_from); - - rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc) - return myssh_to_SFTP_CLOSE(data, sshc); - } - - /* Setup the actual download */ - if(data->req.size == 0) { - /* no data to transfer */ - Curl_xfer_setup_nop(data); - infof(data, "File already completely downloaded"); - myssh_to(data, sshc, SSH_STOP); - return rc; - } - Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->send_idx = 0; - - sshc->sftp_recv_state = 0; - myssh_to(data, sshc, SSH_STOP); - - return rc; -} - -static int myssh_in_SFTP_CLOSE(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - curlx_safefree(sshp->path); - - CURL_TRC_SSH(data, "SFTP DONE done"); - - /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT - After nextstate is executed, the control should come back to - SSH_SFTP_CLOSE to pass the correct result back */ - if(sshc->nextstate != SSH_NO_STATE && - sshc->nextstate != SSH_SFTP_CLOSE) { - myssh_to(data, sshc, sshc->nextstate); - sshc->nextstate = SSH_SFTP_CLOSE; - } - else { - myssh_to(data, sshc, SSH_STOP); - } - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_SHUTDOWN(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* during times we get here due to a broken transfer and then the - sftp_handle might not have been taken down so make sure that is done - before we proceed */ - ssh_set_blocking(sshc->ssh_session, 0); -#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - SFTP_AIO_FREE(sshc->sftp_send_aio); - SFTP_AIO_FREE(sshc->sftp_recv_aio); -#endif - - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - - if(sshc->sftp_session) { - sftp_free(sshc->sftp_session); - sshc->sftp_session = NULL; - } - - SSH_STRING_FREE_CHAR(sshc->homedir); - - myssh_to(data, sshc, SSH_SESSION_DISCONNECT); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_INIT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc; - ssh_set_blocking(sshc->ssh_session, 1); - - sshc->sftp_session = sftp_new(sshc->ssh_session); - if(!sshc->sftp_session) { - failf(data, "Failure initializing sftp session: %s", - ssh_get_error(sshc->ssh_session)); - return myssh_to_ERROR(data, sshc, CURLE_COULDNT_CONNECT); - } - - rc = sftp_init(sshc->sftp_session); - if(rc != SSH_OK) { - failf(data, "Failure initializing sftp session: %s", - ssh_get_error(sshc->ssh_session)); - return myssh_to_ERROR(data, sshc, sftp_error_to_CURLE(SSH_FX_FAILURE)); - } - myssh_to(data, sshc, SSH_SFTP_REALPATH); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_REALPATH(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* Get the "home" directory */ - sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); - if(!sshc->homedir) - return myssh_to_ERROR(data, sshc, CURLE_COULDNT_CONNECT); - - curlx_free(data->state.most_recent_ftp_entrypath); - data->state.most_recent_ftp_entrypath = curlx_strdup(sshc->homedir); - if(!data->state.most_recent_ftp_entrypath) - return myssh_to_ERROR(data, sshc, CURLE_OUT_OF_MEMORY); - - /* This is the last step in the SFTP connect phase. Do note that while - we get the homedir here, we get the "workingpath" in the DO action - since the homedir remains the same between request but the - working path does not. */ - CURL_TRC_SSH(data, "CONNECT phase done"); - myssh_to(data, sshc, SSH_STOP); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE_INIT(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - CURLcode result; - - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); - if(result) { - sshc->actualcode = result; - myssh_to(data, sshc, SSH_STOP); - } - else if(data->set.quote) { - infof(data, "Sending quote commands"); - sshc->quote_item = data->set.quote; - myssh_to(data, sshc, SSH_SFTP_QUOTE); - } - else - myssh_to(data, sshc, SSH_SFTP_GETINFO); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_POSTQUOTE_INIT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(data->set.postquote) { - infof(data, "Sending quote commands"); - sshc->quote_item = data->set.postquote; - myssh_to(data, sshc, SSH_SFTP_QUOTE); - } - else { - myssh_to(data, sshc, SSH_STOP); - } - return SSH_NO_ERROR; -} - -static int quote_error(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - failf(data, "Suspicious data after the command line"); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - const char *cp; - CURLcode result; - - /* - * Support some of the "FTP" commands - */ - const char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command is allowed to fail without it causing any - aborts or cancels etc. It causes libcurl to act as if the command - is successful, whatever the server responds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(curl_strequal("pwd", cmd)) { - /* output debug output if that is requested */ - char *tmp = curl_maprintf("257 \"%s\" is current directory.\n", - sshp->path); - if(!tmp) { - sshc->actualcode = CURLE_OUT_OF_MEMORY; - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return SSH_NO_ERROR; - } - Curl_debug(data, CURLINFO_HEADER_OUT, "PWD\n", 4); - Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); - - /* this sends an FTP-like "header" to the header callback so that - the current directory can be read similar to how it is read when - using ordinary FTP. */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - curlx_free(tmp); - if(result) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - else - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_NO_ERROR; - } - - /* - * the arguments following the command must be separated from the - * command with a space so we can check for it unconditionally - */ - cp = strchr(cmd, ' '); - if(!cp) { - failf(data, "Syntax error in SFTP command. Supply parameter(s)"); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return SSH_NO_ERROR; - } - - /* - * also, every command takes at least one argument so we get that - * first argument right now - */ - result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error: Bad first parameter"); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return SSH_NO_ERROR; - } - - /* - * SFTP is a binary protocol, so we do not send text commands - * to the server. Instead, we scan for commands used by - * OpenSSH's sftp program and call the appropriate libssh - * functions. - */ - if(!strncmp(cmd, "chgrp ", 6) || - !strncmp(cmd, "chmod ", 6) || - !strncmp(cmd, "chown ", 6) || - !strncmp(cmd, "atime ", 6) || - !strncmp(cmd, "mtime ", 6)) { - /* attribute change */ - - /* sshc->quote_path1 contains the mode to set */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in chgrp/chmod/chown/atime/mtime: " - "Bad second parameter"); - curlx_safefree(sshc->quote_path1); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return SSH_NO_ERROR; - } - if(*cp) - return quote_error(data, sshc); - sshc->quote_attrs = NULL; - myssh_to(data, sshc, SSH_SFTP_QUOTE_STAT); - return SSH_NO_ERROR; - } - if(!strncmp(cmd, "ln ", 3) || - !strncmp(cmd, "symlink ", 8)) { - /* symbolic linking */ - /* sshc->quote_path1 is the source */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in ln/symlink: Bad second parameter"); - curlx_safefree(sshc->quote_path1); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return SSH_NO_ERROR; - } - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_SYMLINK); - return SSH_NO_ERROR; - } - else if(!strncmp(cmd, "mkdir ", 6)) { - if(*cp) - return quote_error(data, sshc); - /* create directory */ - myssh_to(data, sshc, SSH_SFTP_QUOTE_MKDIR); - return SSH_NO_ERROR; - } - else if(!strncmp(cmd, "rename ", 7)) { - /* rename file */ - /* first param is the source path */ - /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in rename: Bad second parameter"); - curlx_safefree(sshc->quote_path1); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - return SSH_NO_ERROR; - } - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_RENAME); - return SSH_NO_ERROR; - } - else if(!strncmp(cmd, "rmdir ", 6)) { - /* delete directory */ - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_RMDIR); - return SSH_NO_ERROR; - } - else if(!strncmp(cmd, "rm ", 3)) { - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_UNLINK); - return SSH_NO_ERROR; - } -#ifdef HAS_STATVFS_SUPPORT - else if(!strncmp(cmd, "statvfs ", 8)) { - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_STATVFS); - return SSH_NO_ERROR; - } -#endif - - failf(data, "Unknown SFTP command"); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_NEXT_QUOTE(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - - sshc->quote_item = sshc->quote_item->next; - - if(sshc->quote_item) { - myssh_to(data, sshc, SSH_SFTP_QUOTE); - } - else { - if(sshc->nextstate != SSH_NO_STATE) { - myssh_to(data, sshc, sshc->nextstate); - sshc->nextstate = SSH_NO_STATE; - } - else { - myssh_to(data, sshc, SSH_SFTP_GETINFO); - } - } - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - const char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command is allowed to fail without it causing any - aborts or cancels etc. It causes libcurl to act as if the command - is successful, whatever the server responds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - /* We read the file attributes, store them in sshc->quote_attrs - * and modify them accordingly to command. Then we switch to - * QUOTE_SETSTAT state to write new ones. - */ - - if(sshc->quote_attrs) - sftp_attributes_free(sshc->quote_attrs); - sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); - if(!sshc->quote_attrs) { - failf(data, "Attempt to get SFTP stats failed: %d", - sftp_get_error(sshc->sftp_session)); - myssh_quote_error(data, sshc, NULL); - return SSH_NO_ERROR; - } - - /* Now set the new attributes... */ - if(!strncmp(cmd, "chgrp", 5)) { - const char *p = sshc->quote_path1; - curl_off_t gid; - if(curlx_str_number(&p, &gid, UINT_MAX)) { - failf(data, "Syntax error: chgrp gid not a number"); - myssh_quote_error(data, sshc, NULL); - return SSH_NO_ERROR; - } - sshc->quote_attrs->gid = (uint32_t)gid; - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; - } - else if(!strncmp(cmd, "chmod", 5)) { - curl_off_t perms; - const char *p = sshc->quote_path1; - if(curlx_str_octal(&p, &perms, 07777)) { - failf(data, "Syntax error: chmod permissions not a number"); - myssh_quote_error(data, sshc, NULL); - return SSH_NO_ERROR; - } - sshc->quote_attrs->permissions = (mode_t)perms; - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS; - } - else if(!strncmp(cmd, "chown", 5)) { - const char *p = sshc->quote_path1; - curl_off_t uid; - if(curlx_str_number(&p, &uid, UINT_MAX)) { - failf(data, "Syntax error: chown uid not a number"); - myssh_quote_error(data, sshc, NULL); - return SSH_NO_ERROR; - } - sshc->quote_attrs->uid = (uint32_t)uid; - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; - } - else if(!strncmp(cmd, "atime", 5) || - !strncmp(cmd, "mtime", 5)) { - time_t date; - bool fail = FALSE; - if(Curl_getdate_capped(sshc->quote_path1, &date)) { - failf(data, "incorrect date format for %.*s", 5, cmd); - fail = TRUE; - } -#if SIZEOF_TIME_T > 4 - else if(date > 0xffffffff) { - failf(data, "date overflow"); - fail = TRUE; /* avoid setting a capped time */ - } -#endif - if(fail) { - myssh_quote_error(data, sshc, NULL); - return SSH_NO_ERROR; - } - if(!strncmp(cmd, "atime", 5)) - sshc->quote_attrs->atime = (uint32_t)date; - else /* mtime */ - sshc->quote_attrs->mtime = (uint32_t)date; - - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; - } - - /* Now send the completed structure... */ - myssh_to(data, sshc, SSH_SFTP_QUOTE_SETSTAT); - return SSH_NO_ERROR; -} - -static void conn_forget_socket(struct Curl_easy *data, int sockindex) -{ - struct connectdata *conn = data->conn; - if(conn && CONN_SOCK_IDX_VALID(sockindex)) { - struct Curl_cfilter *cf = conn->cfilter[sockindex]; - if(cf) - (void)Curl_conn_cf_cntrl(cf, data, TRUE, CF_CTRL_FORGET_SOCKET, 0, NULL); - fake_sclose(conn->sock[sockindex]); - conn->sock[sockindex] = CURL_SOCKET_BAD; - } -} - -static void myssh_SESSION_DISCONNECT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* during weird times when we have been prematurely aborted, the channel - is still alive when we reach this state and we MUST kill the channel - properly first */ - if(sshc->scp_session) { - ssh_scp_free(sshc->scp_session); - sshc->scp_session = NULL; - } - - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - if(sshc->sftp_session) { - sftp_free(sshc->sftp_session); - sshc->sftp_session = NULL; - } - - ssh_disconnect(sshc->ssh_session); - if(!ssh_version(SSH_VERSION_INT(0, 10, 0))) { - /* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back, - tell the connection to forget about it. This libssh - bug is fixed in 0.10.0. */ - conn_forget_socket(data, FIRSTSOCKET); - } - - SSH_STRING_FREE_CHAR(sshc->homedir); - - myssh_to(data, sshc, SSH_SESSION_FREE); -} - -static int myssh_SSH_SCP_DOWNLOAD(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - curl_off_t bytecount; - int rc = ssh_scp_pull_request(sshc->scp_session); - if(rc != SSH_SCP_REQUEST_NEWFILE) { - const char *err_msg = ssh_get_error(sshc->ssh_session); - failf(data, "%s", err_msg); - return myssh_to_ERROR(data, sshc, CURLE_REMOTE_FILE_NOT_FOUND); - } - - /* download data */ - bytecount = ssh_scp_request_get_size(sshc->scp_session); - data->req.maxdownload = bytecount; - Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->send_idx = 0; - - myssh_to(data, sshc, SSH_STOP); - return 0; -} - -static int myssh_in_TRANS_INIT(struct Curl_easy *data, struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - CURLcode result; - int rc = 0; - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); - if(result) { - sshc->actualcode = result; - myssh_to(data, sshc, SSH_STOP); - return 0; - } - - /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ - ssh_set_blocking(sshc->ssh_session, 1); - - if(data->state.upload) { - if(data->state.infilesize < 0) { - failf(data, "SCP requires a known file size for upload"); - return myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); - } - - sshc->scp_session = - ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, sshp->path); - myssh_to(data, sshc, SSH_SCP_UPLOAD_INIT); - } - else { - sshc->scp_session = - ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, sshp->path); - myssh_to(data, sshc, SSH_SCP_DOWNLOAD_INIT); - } - - if(!sshc->scp_session) { - const char *err_msg = ssh_get_error(sshc->ssh_session); - failf(data, "%s", err_msg); - rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); - } - return rc; -} - -static void sshc_cleanup(struct ssh_conn *sshc) -{ - if(sshc->initialised) { - if(sshc->sftp_file) { - sftp_close(sshc->sftp_file); - sshc->sftp_file = NULL; - } - if(sshc->sftp_session) { - sftp_free(sshc->sftp_session); - sshc->sftp_session = NULL; - } - if(sshc->ssh_session) { - ssh_free(sshc->ssh_session); - sshc->ssh_session = NULL; - } - - /* worst-case scenario cleanup */ - DEBUGASSERT(sshc->ssh_session == NULL); - DEBUGASSERT(sshc->scp_session == NULL); - - if(sshc->readdir_tmp) { - ssh_string_free_char(sshc->readdir_tmp); - sshc->readdir_tmp = NULL; - } - if(sshc->quote_attrs) { - sftp_attributes_free(sshc->quote_attrs); - sshc->quote_attrs = NULL; - } - if(sshc->readdir_attrs) { - sftp_attributes_free(sshc->readdir_attrs); - sshc->readdir_attrs = NULL; - } - if(sshc->readdir_link_attrs) { - sftp_attributes_free(sshc->readdir_link_attrs); - sshc->readdir_link_attrs = NULL; - } - if(sshc->privkey) { - ssh_key_free(sshc->privkey); - sshc->privkey = NULL; - } - if(sshc->pubkey) { - ssh_key_free(sshc->pubkey); - sshc->pubkey = NULL; - } - - curlx_safefree(sshc->rsa_pub); - curlx_safefree(sshc->rsa); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - curlx_dyn_free(&sshc->readdir_buf); - curlx_safefree(sshc->readdir_linkPath); - SSH_STRING_FREE_CHAR(sshc->homedir); - sshc->initialised = FALSE; - } -} - -static int myssh_in_SFTP_QUOTE_SETSTAT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2, - sshc->quote_attrs); - if(rc == SSH_AGAIN) - return rc; - if(rc && !sshc->acceptfail) { - myssh_quote_error(data, sshc, "setstat"); - return rc; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE_SYMLINK(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2, - sshc->quote_path1); - if(rc == SSH_AGAIN) - return rc; - if(rc && !sshc->acceptfail) { - myssh_quote_error(data, sshc, "symlink"); - return rc; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE_MKDIR(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1, - (mode_t)data->set.new_directory_perms); - if(rc == SSH_AGAIN) - return rc; - if(rc && !sshc->acceptfail) { - myssh_quote_error(data, sshc, "mkdir"); - return rc; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE_RENAME(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = sftp_rename(sshc->sftp_session, sshc->quote_path1, - sshc->quote_path2); - if(rc == SSH_AGAIN) - return rc; - if(rc && !sshc->acceptfail) { - myssh_quote_error(data, sshc, "rename"); - return rc; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE_RMDIR(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1); - if(rc == SSH_AGAIN) - return rc; - if(rc && !sshc->acceptfail) { - myssh_quote_error(data, sshc, "rmdir"); - return rc; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_QUOTE_UNLINK(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1); - if(rc == SSH_AGAIN) - return rc; - if(rc && !sshc->acceptfail) { - myssh_quote_error(data, sshc, "rm"); - return rc; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_GETINFO(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(data->set.get_filetime) - myssh_to(data, sshc, SSH_SFTP_FILETIME); - else - myssh_to(data, sshc, SSH_SFTP_TRANS_INIT); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_FILETIME(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - sftp_attributes attrs; - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - attrs = sftp_stat(sshc->sftp_session, sshp->path); - if(attrs) { - data->info.filetime = attrs->mtime; - sftp_attributes_free(attrs); - } - - myssh_to(data, sshc, SSH_SFTP_TRANS_INIT); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_TRANS_INIT(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - if(data->state.upload) - myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); - else { - size_t path_len = strlen(sshp->path); - - if(path_len && sshp->path[path_len - 1] == '/') - myssh_to(data, sshc, SSH_SFTP_READDIR_INIT); - else - myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_INIT); - } - - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_CREATE_DIRS_INIT(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - if(strlen(sshp->path) > 1) { - sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */ - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS); - } - else { - myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); - } - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_CREATE_DIRS(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - sshc->slash_pos = strchr(sshc->slash_pos, '/'); - if(sshc->slash_pos) { - *sshc->slash_pos = 0; - - infof(data, "Creating directory '%s'", sshp->path); - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_MKDIR); - return SSH_NO_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); - return SSH_NO_ERROR; -} - -static int myssh_in_SFTP_CREATE_DIRS_MKDIR(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - int rc; - int err; - /* 'mode' - parameter is preliminary - default to 0644 */ - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - rc = sftp_mkdir(sshc->sftp_session, sshp->path, - (mode_t)data->set.new_directory_perms); - if(rc == SSH_AGAIN) - return rc; - *sshc->slash_pos = '/'; - ++sshc->slash_pos; - if(rc < 0) { - /* - * Abort if failure was not that the directory already - * exists or the permission was denied (creation might - * succeed further down the path) - retry on unspecific - * FAILURE also - */ - err = sftp_get_error(sshc->sftp_session); - if((err != SSH_FX_FILE_ALREADY_EXISTS) && - (err != SSH_FX_FAILURE) && - (err != SSH_FX_PERMISSION_DENIED)) { - return myssh_to_SFTP_CLOSE(data, sshc); - } - rc = 0; /* clear rc and continue */ - } - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS); - return rc; -} - -static int myssh_in_SCP_UPLOAD_INIT(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - int rc; - if(!sshp) - return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT); - - rc = ssh_scp_init(sshc->scp_session); - if(rc != SSH_OK) { - const char *err_msg = ssh_get_error(sshc->ssh_session); - failf(data, "%s", err_msg); - return myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); - } - - rc = ssh_scp_push_file64(sshc->scp_session, sshp->path, - (uint64_t)data->state.infilesize, - (int)data->set.new_file_perms); - - if(rc != SSH_OK) { - const char *err_msg = ssh_get_error(sshc->ssh_session); - failf(data, "%s", err_msg); - return myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED); - } - - /* upload data */ - Curl_xfer_setup_send(data, FIRSTSOCKET); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->recv_idx = FIRSTSOCKET; - - myssh_to(data, sshc, SSH_STOP); - return SSH_NO_ERROR; -} - -static int myssh_in_SCP_DOWNLOAD_INIT(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = ssh_scp_init(sshc->scp_session); - if(rc != SSH_OK) { - const char *err_msg = ssh_get_error(sshc->ssh_session); - failf(data, "%s", err_msg); - return myssh_to_ERROR(data, sshc, - CURLE_COULDNT_CONNECT); - } - myssh_to(data, sshc, SSH_SCP_DOWNLOAD); - return SSH_NO_ERROR; -} - -static int myssh_in_SCP_DONE(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(data->state.upload) - myssh_to(data, sshc, SSH_SCP_SEND_EOF); - else - myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); - return SSH_NO_ERROR; -} - -static int myssh_in_SCP_SEND_EOF(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->scp_session) { - int rc = ssh_scp_close(sshc->scp_session); - if(rc == SSH_AGAIN) { - /* Currently the ssh_scp_close handles waiting for - * EOF in blocking way. - */ - return SSH_AGAIN; - } - if(rc != SSH_OK) { - infof(data, - "Failed to close libssh scp channel: %s", - ssh_get_error(sshc->ssh_session)); - } - } - - myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); - return SSH_NO_ERROR; -} - -static int myssh_in_SCP_CHANNEL_FREE(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->scp_session) { - ssh_scp_free(sshc->scp_session); - sshc->scp_session = NULL; - } - CURL_TRC_SSH(data, "SCP DONE phase complete"); - - ssh_set_blocking(sshc->ssh_session, 0); - - myssh_to(data, sshc, SSH_SESSION_DISCONNECT); - return SSH_NO_ERROR; -} - -static CURLcode myssh_in_SESSION_FREE(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - CURLcode result; - sshc_cleanup(sshc); - /* the code we are about to return */ - result = sshc->actualcode; - memset(sshc, 0, sizeof(struct ssh_conn)); - connclose(data->conn, "SSH session free"); - sshc->state = SSH_SESSION_FREE; /* current */ - sshc->nextstate = SSH_NO_STATE; - myssh_to(data, sshc, SSH_STOP); - return result; -} - -/* - * myssh_statemachine() runs the SSH state machine as far as it can without - * blocking and without reaching the end. The data the pointer 'block' points - * to is set to TRUE if the libssh function returns SSH_AGAIN - * meaning it wants to be called again when the socket is ready - */ -static CURLcode myssh_statemachine(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *block) -{ - CURLcode result = CURLE_OK; - int rc = SSH_NO_ERROR; - - *block = FALSE; /* we are not blocking by default */ - do { - - switch(sshc->state) { - case SSH_INIT: - myssh_state_init(data, sshc); - FALLTHROUGH(); - case SSH_S_STARTUP: - rc = myssh_in_S_STARTUP(data, sshc); - if(rc) - break; - FALLTHROUGH(); - case SSH_HOSTKEY: - rc = myssh_is_known(data, sshc); - if(rc != SSH_OK) { - rc = myssh_to_ERROR(data, sshc, CURLE_PEER_FAILED_VERIFICATION); - break; - } - myssh_to(data, sshc, SSH_AUTHLIST); - FALLTHROUGH(); - case SSH_AUTHLIST: - rc = myssh_in_AUTHLIST(data, sshc); - break; - case SSH_AUTH_PKEY_INIT: - rc = myssh_in_AUTH_PKEY_INIT(data, sshc); - break; - case SSH_AUTH_PKEY: - rc = myssh_in_AUTH_PKEY(data, sshc); - break; - case SSH_AUTH_GSSAPI: - rc = myssh_in_AUTH_GSSAPI(data, sshc); - break; - case SSH_AUTH_KEY_INIT: - rc = myssh_in_AUTH_KEY_INIT(data, sshc); - break; - case SSH_AUTH_KEY: - rc = myssh_in_AUTH_KEY(data, sshc); - break; - case SSH_AUTH_PASS_INIT: - rc = myssh_in_AUTH_PASS_INIT(data, sshc); - break; - case SSH_AUTH_PASS: - rc = myssh_in_AUTH_PASS(data, sshc); - break; - case SSH_AUTH_DONE: - rc = myssh_in_AUTH_DONE(data, sshc); - break; - case SSH_SFTP_INIT: - rc = myssh_in_SFTP_INIT(data, sshc); - break; - case SSH_SFTP_REALPATH: - rc = myssh_in_SFTP_REALPATH(data, sshc); - break; - case SSH_SFTP_QUOTE_INIT: - rc = myssh_in_SFTP_QUOTE_INIT(data, sshc, sshp); - break; - case SSH_SFTP_POSTQUOTE_INIT: - rc = myssh_in_SFTP_POSTQUOTE_INIT(data, sshc); - break; - case SSH_SFTP_QUOTE: - rc = myssh_in_SFTP_QUOTE(data, sshc, sshp); - break; - case SSH_SFTP_NEXT_QUOTE: - rc = myssh_in_SFTP_NEXT_QUOTE(data, sshc); - break; - case SSH_SFTP_QUOTE_STAT: - rc = myssh_in_SFTP_QUOTE_STAT(data, sshc); - break; - case SSH_SFTP_QUOTE_SETSTAT: - rc = myssh_in_SFTP_QUOTE_SETSTAT(data, sshc); - break; - case SSH_SFTP_QUOTE_SYMLINK: - rc = myssh_in_SFTP_QUOTE_SYMLINK(data, sshc); - break; - case SSH_SFTP_QUOTE_MKDIR: - rc = myssh_in_SFTP_QUOTE_MKDIR(data, sshc); - break; - case SSH_SFTP_QUOTE_RENAME: - rc = myssh_in_SFTP_QUOTE_RENAME(data, sshc); - break; - case SSH_SFTP_QUOTE_RMDIR: - rc = myssh_in_SFTP_QUOTE_RMDIR(data, sshc); - break; - case SSH_SFTP_QUOTE_UNLINK: - rc = myssh_in_SFTP_QUOTE_UNLINK(data, sshc); - break; - case SSH_SFTP_QUOTE_STATVFS: - rc = myssh_in_SFTP_QUOTE_STATVFS(data, sshc); - break; - case SSH_SFTP_GETINFO: - rc = myssh_in_SFTP_GETINFO(data, sshc); - break; - case SSH_SFTP_FILETIME: - rc = myssh_in_SFTP_FILETIME(data, sshc, sshp); - break; - case SSH_SFTP_TRANS_INIT: - rc = myssh_in_SFTP_TRANS_INIT(data, sshc, sshp); - break; - case SSH_SFTP_UPLOAD_INIT: - rc = myssh_in_UPLOAD_INIT(data, sshc, sshp); - break; - case SSH_SFTP_CREATE_DIRS_INIT: - rc = myssh_in_SFTP_CREATE_DIRS_INIT(data, sshc, sshp); - break; - case SSH_SFTP_CREATE_DIRS: - rc = myssh_in_SFTP_CREATE_DIRS(data, sshc, sshp); - break; - case SSH_SFTP_CREATE_DIRS_MKDIR: - rc = myssh_in_SFTP_CREATE_DIRS_MKDIR(data, sshc, sshp); - break; - case SSH_SFTP_READDIR_INIT: - rc = myssh_in_SFTP_READDIR_INIT(data, sshc, sshp); - break; - case SSH_SFTP_READDIR: - rc = myssh_in_SFTP_READDIR(data, sshc, sshp); - break; - case SSH_SFTP_READDIR_LINK: - rc = myssh_in_SFTP_READDIR_LINK(data, sshc); - break; - case SSH_SFTP_READDIR_BOTTOM: - rc = myssh_in_SFTP_READDIR_BOTTOM(data, sshc); - break; - case SSH_SFTP_READDIR_DONE: - rc = myssh_in_SFTP_READDIR_DONE(data, sshc); - break; - case SSH_SFTP_DOWNLOAD_INIT: - rc = myssh_in_SFTP_DOWNLOAD_INIT(data, sshc, sshp); - break; - case SSH_SFTP_DOWNLOAD_STAT: - rc = myssh_in_SFTP_DOWNLOAD_STAT(data, sshc); - break; - case SSH_SFTP_CLOSE: - rc = myssh_in_SFTP_CLOSE(data, sshc, sshp); - break; - case SSH_SFTP_SHUTDOWN: - rc = myssh_in_SFTP_SHUTDOWN(data, sshc); - break; - case SSH_SCP_TRANS_INIT: - rc = myssh_in_TRANS_INIT(data, sshc, sshp); - break; - case SSH_SCP_UPLOAD_INIT: - rc = myssh_in_SCP_UPLOAD_INIT(data, sshc, sshp); - break; - case SSH_SCP_DOWNLOAD_INIT: - rc = myssh_in_SCP_DOWNLOAD_INIT(data, sshc); - if(rc) - break; - FALLTHROUGH(); - case SSH_SCP_DOWNLOAD: - rc = myssh_SSH_SCP_DOWNLOAD(data, sshc); - break; - case SSH_SCP_DONE: - rc = myssh_in_SCP_DONE(data, sshc); - break; - case SSH_SCP_SEND_EOF: - rc = myssh_in_SCP_SEND_EOF(data, sshc); - break; - case SSH_SCP_CHANNEL_FREE: - myssh_in_SCP_CHANNEL_FREE(data, sshc); - FALLTHROUGH(); - case SSH_SESSION_DISCONNECT: - myssh_SESSION_DISCONNECT(data, sshc); - FALLTHROUGH(); - case SSH_SESSION_FREE: - result = myssh_in_SESSION_FREE(data, sshc); - break; - case SSH_QUIT: - default: - /* internal error */ - sshc->nextstate = SSH_NO_STATE; - myssh_to(data, sshc, SSH_STOP); - break; - } - /* break the loop only on STOP or SSH_AGAIN. If `rc` is some - * other error code, we will have progressed the state accordingly. */ - } while((rc != SSH_AGAIN) && (sshc->state != SSH_STOP)); - - if(rc == SSH_AGAIN) { - /* we would block, we need to wait for the socket to be ready (in the - right direction too)! */ - *block = TRUE; - } - if(!result && (sshc->state == SSH_STOP)) - result = sshc->actualcode; - CURL_TRC_SSH(data, "[%s] statemachine() -> %d, block=%d", - Curl_ssh_statename(sshc->state), result, *block); - return result; -} - -/* called by the multi interface to figure out what socket(s) to wait for and - for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static CURLcode myssh_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int waitfor; - - if(!sshc || (sock == CURL_SOCKET_BAD)) - return CURLE_FAILED_INIT; - - waitfor = sshc->waitfor ? sshc->waitfor : data->req.io_flags; - if(waitfor) { - int flags = 0; - if(waitfor & REQ_IO_RECV) - flags |= CURL_POLL_IN; - if(waitfor & REQ_IO_SEND) - flags |= CURL_POLL_OUT; - DEBUGASSERT(flags); - CURL_TRC_SSH(data, "pollset, flags=%x", flags); - return Curl_pollset_change(data, ps, sock, flags, 0); - } - /* While we still have a session, we listen incoming data. */ - if(sshc->ssh_session) - return Curl_pollset_change(data, ps, sock, CURL_POLL_IN, 0); - return CURLE_OK; -} - -/* called repeatedly until done from multi.c */ -static CURLcode myssh_multi_statemach(struct Curl_easy *data, - bool *done) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - bool block; /* we store the status and use that to provide a ssh_pollset() - implementation */ - CURLcode result; - - if(!sshc || !sshp) - return CURLE_FAILED_INIT; - result = myssh_statemachine(data, sshc, sshp, &block); - *done = (sshc->state == SSH_STOP); - myssh_block2waitfor(conn, sshc, block); - - return result; -} - -static CURLcode myssh_block_statemach(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool disconnect) -{ - struct connectdata *conn = data->conn; - CURLcode result = CURLE_OK; - - while((sshc->state != SSH_STOP) && !result) { - bool block; - timediff_t left_ms = 1000; - - result = myssh_statemachine(data, sshc, sshp, &block); - if(result) - break; - - if(!disconnect) { - result = Curl_pgrsCheck(data); - if(result) - break; - - left_ms = Curl_timeleft_ms(data); - if(left_ms < 0) { - failf(data, "Operation timed out"); - return CURLE_OPERATION_TIMEDOUT; - } - } - - if(block) { - curl_socket_t fd_read = conn->sock[FIRSTSOCKET]; - /* wait for the socket to become ready */ - (void)SOCKET_READABLE(fd_read, left_ms > 1000 ? 1000 : left_ms); - } - } - - return result; -} - -static void myssh_easy_dtor(void *key, size_t klen, void *entry) -{ - struct SSHPROTO *sshp = entry; - (void)key; - (void)klen; - curlx_safefree(sshp->path); - curlx_free(sshp); -} - -static void myssh_conn_dtor(void *key, size_t klen, void *entry) -{ - struct ssh_conn *sshc = entry; - (void)key; - (void)klen; - sshc_cleanup(sshc); - curlx_free(sshc); -} - -/* - * SSH setup connection - */ -static CURLcode myssh_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct SSHPROTO *sshp; - struct ssh_conn *sshc; - - sshc = curlx_calloc(1, sizeof(*sshc)); - if(!sshc) - return CURLE_OUT_OF_MEMORY; - - curlx_dyn_init(&sshc->readdir_buf, CURL_PATH_MAX * 2); - sshc->initialised = TRUE; - if(Curl_conn_meta_set(conn, CURL_META_SSH_CONN, sshc, myssh_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - sshp = curlx_calloc(1, sizeof(*sshp)); - if(!sshp || - Curl_meta_set(data, CURL_META_SSH_EASY, sshp, myssh_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static Curl_recv scp_recv, sftp_recv; -static Curl_send scp_send, sftp_send; - -/* - * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. - */ -static CURLcode myssh_connect(struct Curl_easy *data, bool *done) -{ - CURLcode result; - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - struct SSHPROTO *ssh = Curl_meta_get(data, CURL_META_SSH_EASY); - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int rc; - - if(!sshc || !ssh) - return CURLE_FAILED_INIT; - - CURL_TRC_SSH(data, "myssh_connect"); - if(conn->scheme->protocol & CURLPROTO_SCP) { - conn->recv[FIRSTSOCKET] = scp_recv; - conn->send[FIRSTSOCKET] = scp_send; - } - else { - conn->recv[FIRSTSOCKET] = sftp_recv; - conn->send[FIRSTSOCKET] = sftp_send; - } - - sshc->ssh_session = ssh_new(); - if(!sshc->ssh_session) { - failf(data, "Failure initialising ssh session"); - return CURLE_FAILED_INIT; - } - - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_HOST, - (data->state.up.hostname[0] == '[') ? - data->state.up.hostname : conn->host.name); - - if(rc != SSH_OK) { - failf(data, "Could not set remote host"); - return CURLE_FAILED_INIT; - } - - rc = ssh_options_parse_config(sshc->ssh_session, NULL); - if(rc != SSH_OK) { - infof(data, "Could not parse SSH configuration files"); - /* ignore */ - } - - CURL_TRC_SSH(data, "myssh_connect, set socket=%" FMT_SOCKET_T, sock); - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_FD, &sock); - if(rc != SSH_OK) { - failf(data, "Could not set socket"); - return CURLE_FAILED_INIT; - } - - if(conn->user && conn->user[0] != '\0') { - infof(data, "User: %s", conn->user); - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_USER, conn->user); - if(rc != SSH_OK) { - failf(data, "Could not set user"); - return CURLE_FAILED_INIT; - } - } - - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - infof(data, "Known hosts: %s", data->set.str[STRING_SSH_KNOWNHOSTS]); - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_KNOWNHOSTS, - data->set.str[STRING_SSH_KNOWNHOSTS]); - if(rc == SSH_OK) - /* libssh has two separate options for this. Set both to the same file - to avoid surprises */ - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, - data->set.str[STRING_SSH_KNOWNHOSTS]); - if(rc != SSH_OK) { - failf(data, "Could not set known hosts file path"); - return CURLE_FAILED_INIT; - } - } - - if(conn->remote_port) { - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_PORT, - &conn->remote_port); - if(rc != SSH_OK) { - failf(data, "Could not set remote port"); - return CURLE_FAILED_INIT; - } - } - - if(data->set.ssh_compression) { - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_COMPRESSION, - "zlib,zlib@openssh.com,none"); - if(rc != SSH_OK) { - failf(data, "Could not set compression"); - return CURLE_FAILED_INIT; - } - } - - sshc->privkey = NULL; - sshc->pubkey = NULL; - - if(data->set.str[STRING_SSH_PUBLIC_KEY]) { - rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY], - &sshc->pubkey); - if(rc != SSH_OK) { - failf(data, "Could not load public key file"); - return CURLE_FAILED_INIT; - } - } - - /* we do not verify here, we do it at the state machine, - * after connection */ - - myssh_to(data, sshc, SSH_INIT); - - result = myssh_multi_statemach(data, done); - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done) -{ - CURLcode result; - - result = myssh_multi_statemach(data, dophase_done); - - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - return result; -} - -/* - *********************************************************************** - * - * scp_perform() - * - * This is the actual DO function for SCP. Get a file according to - * the options previously setup. - */ - -static CURLcode scp_perform(struct Curl_easy *data, - bool *connected, bool *dophase_done) -{ - CURLcode result = CURLE_OK; - struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - - CURL_TRC_SSH(data, "DO phase starts"); - - *dophase_done = FALSE; /* not done yet */ - if(!sshc) - return CURLE_FAILED_INIT; - - /* start the first command in the DO phase */ - myssh_to(data, sshc, SSH_SCP_TRANS_INIT); - - result = myssh_multi_statemach(data, dophase_done); - - *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); - - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode scp_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection) -{ - CURLcode result = CURLE_OK; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - (void)dead_connection; - - if(sshc && sshc->ssh_session) { - /* only if there is a session still around to use! */ - myssh_to(data, sshc, SSH_SESSION_DISCONNECT); - result = myssh_block_statemach(data, sshc, sshp, TRUE); - } - - return result; -} - -/* generic done function for both SCP and SFTP called from their specific - done functions */ -static CURLcode myssh_done(struct Curl_easy *data, - struct ssh_conn *sshc, - CURLcode status) -{ - CURLcode result = CURLE_OK; - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - - if(!status && sshp) { - /* run the state-machine */ - result = myssh_block_statemach(data, sshc, sshp, FALSE); - } - else - result = status; - - if(Curl_pgrsDone(data)) - return CURLE_ABORTED_BY_CALLBACK; - - CURL_REQ_CLEAR_IO(data); - return result; -} - -static CURLcode scp_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - (void)premature; - - if(!sshc) - return CURLE_FAILED_INIT; - if(!status) - myssh_to(data, sshc, SSH_SCP_DONE); - - return myssh_done(data, sshc, status); -} - -static CURLcode scp_send(struct Curl_easy *data, int sockindex, - const uint8_t *mem, size_t len, bool eos, - size_t *pnwritten) -{ - int rc; - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - (void)eos; - *pnwritten = 0; - - if(!sshc) - return CURLE_FAILED_INIT; - - rc = ssh_scp_write(sshc->scp_session, mem, len); - -#if 0 - /* The following code is misleading, mostly added as wishful thinking - * that libssh at some point would implement non-blocking ssh_scp_write/read. - * Currently rc can only be number of bytes read or SSH_ERROR. */ - myssh_block2waitfor(conn, sshc, (rc == SSH_AGAIN)); - - if(rc == SSH_AGAIN) - return CURLE_AGAIN; - else -#endif - if(rc != SSH_OK) - return CURLE_SSH; - - *pnwritten = len; - return CURLE_OK; -} - -static CURLcode scp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, size_t *pnread) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - int nread; - - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - *pnread = 0; - - if(!sshc) - return CURLE_FAILED_INIT; - - /* libssh returns int */ - nread = ssh_scp_read(sshc->scp_session, mem, len); - if(nread == SSH_ERROR) - return CURLE_SSH; -#if 0 - /* The following code is misleading, mostly added as wishful thinking - * that libssh at some point would implement non-blocking ssh_scp_write/read. - * Currently rc can only be SSH_OK or SSH_ERROR. */ - - myssh_block2waitfor(conn, sshc, (nread == SSH_AGAIN)); - if(nread == SSH_AGAIN) - return CURLE_AGAIN; -#endif - *pnread = (size_t)nread; - return CURLE_OK; -} - -/* - * =============== SFTP =============== - */ - -/* - *********************************************************************** - * - * sftp_perform() - * - * This is the actual DO function for SFTP. Get a file/directory according to - * the options previously setup. - */ - -static CURLcode sftp_perform(struct Curl_easy *data, - bool *connected, - bool *dophase_done) -{ - struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - CURLcode result = CURLE_OK; - - CURL_TRC_SSH(data, "DO phase starts"); - - *dophase_done = FALSE; /* not done yet */ - if(!sshc) - return CURLE_FAILED_INIT; - - /* start the first command in the DO phase */ - myssh_to(data, sshc, SSH_SFTP_QUOTE_INIT); - - /* run the state-machine */ - result = myssh_multi_statemach(data, dophase_done); - - *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); - - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode sftp_doing(struct Curl_easy *data, - bool *dophase_done) -{ - CURLcode result = myssh_multi_statemach(data, dophase_done); - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode sftp_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection) -{ - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - CURLcode result = CURLE_OK; - (void)dead_connection; - - CURL_TRC_SSH(data, "DISCONNECT starts now"); - - if(sshc && sshc->ssh_session) { - /* only if there is a session still around to use! */ - myssh_to(data, sshc, SSH_SFTP_SHUTDOWN); - result = myssh_block_statemach(data, sshc, sshp, TRUE); - } - - CURL_TRC_SSH(data, "DISCONNECT is done"); - return result; -} - -static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - - if(!sshc) - return CURLE_FAILED_INIT; - if(!status) { - /* Post quote commands are executed after the SFTP_CLOSE state to avoid - errors that could happen due to open file handles during POSTQUOTE - operation */ - if(!premature && data->set.postquote && !conn->bits.retry) - sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - myssh_to(data, sshc, SSH_SFTP_CLOSE); - } - return myssh_done(data, sshc, status); -} - -/* return number of sent bytes */ -static CURLcode sftp_send(struct Curl_easy *data, int sockindex, - const uint8_t *mem, size_t len, bool eos, - size_t *pnwritten) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - ssize_t nwrite; - - (void)sockindex; - (void)eos; - *pnwritten = 0; - - if(!sshc) - return CURLE_FAILED_INIT; - -#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - switch(sshc->sftp_send_state) { - case 0: - sftp_file_set_nonblocking(sshc->sftp_file); - if(sftp_aio_begin_write(sshc->sftp_file, mem, len, - &sshc->sftp_send_aio) == SSH_ERROR) { - return CURLE_SEND_ERROR; - } - sshc->sftp_send_state = 1; - FALLTHROUGH(); - case 1: - nwrite = sftp_aio_wait_write(&sshc->sftp_send_aio); - myssh_block2waitfor(conn, sshc, (nwrite == SSH_AGAIN) ? TRUE : FALSE); - if(nwrite == SSH_AGAIN) - return CURLE_AGAIN; - else if(nwrite < 0) - return CURLE_SEND_ERROR; - - /* - * sftp_aio_wait_write() would free sftp_send_aio and - * assign it NULL in all cases except when it returns - * SSH_AGAIN. - */ - - sshc->sftp_send_state = 0; - *pnwritten = (size_t)nwrite; - return CURLE_OK; - default: - /* we never reach here */ - return CURLE_SEND_ERROR; - } -#else - /* - * limit the writes to the maximum specified in Section 3 of - * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02 - * - * libssh started applying appropriate read/write length limits - * internally since version 0.11.0, hence such an operation is - * not needed for versions after (and including) 0.11.0. - */ - if(len > 32768) - len = 32768; - - nwrite = sftp_write(sshc->sftp_file, mem, len); - - myssh_block2waitfor(conn, sshc, FALSE); - -#if 0 /* not returned by libssh on write */ - if(nwrite == SSH_AGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else -#endif - if(nwrite < 0) - return CURLE_SSH; - - *pnwritten = (size_t)nwrite; - return CURLE_OK; -#endif -} - -/* - * Return number of received (decrypted) bytes - * or <0 on error - */ -static CURLcode sftp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, size_t *pnread) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - ssize_t nread; - - (void)sockindex; - *pnread = 0; - - DEBUGASSERT(len < CURL_MAX_READ_SIZE); - if(!sshc) - return CURLE_FAILED_INIT; - - switch(sshc->sftp_recv_state) { - case 0: -#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - if(sftp_aio_begin_read(sshc->sftp_file, len, - &sshc->sftp_recv_aio) == SSH_ERROR) { - return CURLE_RECV_ERROR; - } -#else - sshc->sftp_file_index = - sftp_async_read_begin(sshc->sftp_file, (uint32_t)len); - if(sshc->sftp_file_index < 0) - return CURLE_RECV_ERROR; -#endif - - FALLTHROUGH(); - case 1: - sshc->sftp_recv_state = 1; - -#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - nread = sftp_aio_wait_read(&sshc->sftp_recv_aio, mem, len); -#else - nread = sftp_async_read(sshc->sftp_file, mem, (uint32_t)len, - (uint32_t)sshc->sftp_file_index); -#endif - - myssh_block2waitfor(conn, sshc, (nread == SSH_AGAIN)); - - if(nread == SSH_AGAIN) - return CURLE_AGAIN; - else if(nread < 0) - return CURLE_RECV_ERROR; - - /* - * sftp_aio_wait_read() would free sftp_recv_aio and - * assign it NULL in all cases except when it returns - * SSH_AGAIN. - */ - - sshc->sftp_recv_state = 0; - *pnread = (size_t)nread; - return CURLE_OK; - - default: - /* we never reach here */ - return CURLE_RECV_ERROR; - } -} - -static CURLcode myssh_do_it(struct Curl_easy *data, bool *done) -{ - CURLcode result; - bool connected = FALSE; - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - - *done = FALSE; /* default to false */ - if(!sshc) - return CURLE_FAILED_INIT; - - data->req.size = -1; /* make sure this is unknown at this point */ - - sshc->actualcode = CURLE_OK; /* reset error code */ - sshc->secondCreateDirs = 0; /* reset the create directory attempt state - variable */ - - Curl_pgrsReset(data); - - if(conn->scheme->protocol & CURLPROTO_SCP) - result = scp_perform(data, &connected, done); - else - result = sftp_perform(data, &connected, done); - - return result; -} - -CURLcode Curl_ssh_init(void) -{ - if(ssh_init()) { - DEBUGF(curl_mfprintf(stderr, "Error: libssh_init failed\n")); - return CURLE_FAILED_INIT; - } - return CURLE_OK; -} - -void Curl_ssh_cleanup(void) -{ - (void)ssh_finalize(); -} - -void Curl_ssh_version(char *buffer, size_t buflen) -{ - (void)curl_msnprintf(buffer, buflen, "libssh/%s", ssh_version(0)); -} - -/* - * SCP. - */ -const struct Curl_protocol Curl_protocol_scp = { - myssh_setup_connection, /* setup_connection */ - myssh_do_it, /* do_it */ - scp_done, /* done */ - ZERO_NULL, /* do_more */ - myssh_connect, /* connect_it */ - myssh_multi_statemach, /* connecting */ - scp_doing, /* doing */ - myssh_pollset, /* proto_pollset */ - myssh_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - myssh_pollset, /* perform_pollset */ - scp_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -/* - * SFTP. - */ -const struct Curl_protocol Curl_protocol_sftp = { - myssh_setup_connection, /* setup_connection */ - myssh_do_it, /* do_it */ - sftp_done, /* done */ - ZERO_NULL, /* do_more */ - myssh_connect, /* connect_it */ - myssh_multi_statemach, /* connecting */ - sftp_doing, /* doing */ - myssh_pollset, /* proto_pollset */ - myssh_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - myssh_pollset, /* perform_pollset */ - sftp_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - ZERO_NULL, /* follow */ -}; - -#endif /* USE_LIBSSH */ diff --git a/vendor/curl/lib/vssh/libssh2.c b/vendor/curl/lib/vssh/libssh2.c deleted file mode 100644 index 4e2a72269..000000000 --- a/vendor/curl/lib/vssh/libssh2.c +++ /dev/null @@ -1,4023 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_LIBSSH2 - -/* #define CURL_LIBSSH2_DEBUG */ - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "curl_trc.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "vssh/ssh.h" -#include "url.h" -#include "cfilters.h" -#include "connect.h" -#include "parsedate.h" /* for the week day and month names */ -#include "multiif.h" -#include "select.h" -#include "curlx/fopen.h" -#include "vssh/vssh.h" -#include "curlx/strparse.h" -#include "curlx/base64.h" /* for base64 encoding/decoding */ - -static const char *sftp_libssh2_strerror(unsigned long err) -{ - switch(err) { - case LIBSSH2_FX_NO_SUCH_FILE: - return "No such file or directory"; - - case LIBSSH2_FX_PERMISSION_DENIED: - return "Permission denied"; - - case LIBSSH2_FX_FAILURE: - return "Operation failed"; - - case LIBSSH2_FX_BAD_MESSAGE: - return "Bad message from SFTP server"; - - case LIBSSH2_FX_NO_CONNECTION: - return "Not connected to SFTP server"; - - case LIBSSH2_FX_CONNECTION_LOST: - return "Connection to SFTP server lost"; - - case LIBSSH2_FX_OP_UNSUPPORTED: - return "Operation not supported by SFTP server"; - - case LIBSSH2_FX_INVALID_HANDLE: - return "Invalid handle"; - - case LIBSSH2_FX_NO_SUCH_PATH: - return "No such file or directory"; - - case LIBSSH2_FX_FILE_ALREADY_EXISTS: - return "File already exists"; - - case LIBSSH2_FX_WRITE_PROTECT: - return "File is write protected"; - - case LIBSSH2_FX_NO_MEDIA: - return "No media"; - - case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: - return "Disk full"; - - case LIBSSH2_FX_QUOTA_EXCEEDED: - return "User quota exceeded"; - - case LIBSSH2_FX_UNKNOWN_PRINCIPLE: - return "Unknown principle"; - - case LIBSSH2_FX_LOCK_CONFlICT: - return "File lock conflict"; - - case LIBSSH2_FX_DIR_NOT_EMPTY: - return "Directory not empty"; - - case LIBSSH2_FX_NOT_A_DIRECTORY: - return "Not a directory"; - - case LIBSSH2_FX_INVALID_FILENAME: - return "Invalid filename"; - - case LIBSSH2_FX_LINK_LOOP: - return "Link points to itself"; - } - return "Unknown error in libssh2"; -} - -static void kbd_callback(const char *name, int name_len, - const char *instruction, int instruction_len, - int num_prompts, - const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, - LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, - void **abstract) -{ - struct Curl_easy *data = (struct Curl_easy *)*abstract; - -#ifdef CURL_LIBSSH2_DEBUG - curl_mfprintf(stderr, "name=%s\n", name); - curl_mfprintf(stderr, "name_len=%d\n", name_len); - curl_mfprintf(stderr, "instruction=%s\n", instruction); - curl_mfprintf(stderr, "instruction_len=%d\n", instruction_len); - curl_mfprintf(stderr, "num_prompts=%d\n", num_prompts); -#else - (void)name; - (void)name_len; - (void)instruction; - (void)instruction_len; -#endif /* CURL_LIBSSH2_DEBUG */ - if(num_prompts == 1) { - struct connectdata *conn = data->conn; - /* this function must allocate memory that can be freed by libssh2, which - uses the LIBSSH2_FREE_FUNC callback */ - responses[0].text = Curl_cstrdup(conn->passwd); - responses[0].length = - responses[0].text == NULL ? 0 : curlx_uztoui(strlen(conn->passwd)); - } - (void)prompts; -} /* kbd_callback */ - -static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err) -{ - switch(err) { - case LIBSSH2_FX_OK: - return CURLE_OK; - - case LIBSSH2_FX_NO_SUCH_FILE: - case LIBSSH2_FX_NO_SUCH_PATH: - return CURLE_REMOTE_FILE_NOT_FOUND; - - case LIBSSH2_FX_PERMISSION_DENIED: - case LIBSSH2_FX_WRITE_PROTECT: - case LIBSSH2_FX_LOCK_CONFlICT: - return CURLE_REMOTE_ACCESS_DENIED; - - case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: - case LIBSSH2_FX_QUOTA_EXCEEDED: - return CURLE_REMOTE_DISK_FULL; - - case LIBSSH2_FX_FILE_ALREADY_EXISTS: - return CURLE_REMOTE_FILE_EXISTS; - - case LIBSSH2_FX_DIR_NOT_EMPTY: - return CURLE_QUOTE_ERROR; - - default: - break; - } - - return CURLE_SSH; -} - -static CURLcode libssh2_session_error_to_CURLE(int err) -{ - switch(err) { - /* Ordered by order of appearance in libssh2.h */ - case LIBSSH2_ERROR_NONE: - return CURLE_OK; - - /* This is the error returned by libssh2_scp_recv2 - * on unknown file */ - case LIBSSH2_ERROR_SCP_PROTOCOL: - return CURLE_REMOTE_FILE_NOT_FOUND; - - case LIBSSH2_ERROR_SOCKET_NONE: - return CURLE_COULDNT_CONNECT; - - case LIBSSH2_ERROR_ALLOC: - return CURLE_OUT_OF_MEMORY; - - case LIBSSH2_ERROR_SOCKET_SEND: - return CURLE_SEND_ERROR; - - case LIBSSH2_ERROR_HOSTKEY_INIT: - case LIBSSH2_ERROR_HOSTKEY_SIGN: - case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED: - case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: - return CURLE_PEER_FAILED_VERIFICATION; - - case LIBSSH2_ERROR_PASSWORD_EXPIRED: - return CURLE_LOGIN_DENIED; - - case LIBSSH2_ERROR_SOCKET_TIMEOUT: - case LIBSSH2_ERROR_TIMEOUT: - return CURLE_OPERATION_TIMEDOUT; - - case LIBSSH2_ERROR_EAGAIN: - return CURLE_AGAIN; - } - - return CURLE_SSH; -} - -/* These functions are made to use the libcurl memory functions - NOT the - debugmem functions, as that leads us to trigger on libssh2 memory leaks - that are not ours to care for */ - -static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc) -{ - (void)abstract; - return Curl_cmalloc(count); -} - -static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc) -{ - (void)abstract; - return Curl_crealloc(ptr, count); -} - -static LIBSSH2_FREE_FUNC(my_libssh2_free) -{ - (void)abstract; - if(ptr) /* ssh2 agent sometimes call free with null ptr */ - Curl_cfree(ptr); -} - -static int sshkeycallback(CURL *easy, - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch match, - void *clientp) -{ - (void)easy; - (void)knownkey; - (void)foundkey; - (void)clientp; - - /* we only allow perfect matches, and we reject everything else */ - return (match != CURLKHMATCH_OK) ? CURLKHSTAT_REJECT : CURLKHSTAT_FINE; -} - -static enum curl_khtype convert_ssh2_keytype(int sshkeytype) -{ - enum curl_khtype keytype = CURLKHTYPE_UNKNOWN; - switch(sshkeytype) { - case LIBSSH2_HOSTKEY_TYPE_RSA: - keytype = CURLKHTYPE_RSA; - break; - case LIBSSH2_HOSTKEY_TYPE_DSS: - keytype = CURLKHTYPE_DSS; - break; -#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256 - case LIBSSH2_HOSTKEY_TYPE_ECDSA_256: - keytype = CURLKHTYPE_ECDSA; - break; -#endif -#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384 - case LIBSSH2_HOSTKEY_TYPE_ECDSA_384: - keytype = CURLKHTYPE_ECDSA; - break; -#endif -#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521 - case LIBSSH2_HOSTKEY_TYPE_ECDSA_521: - keytype = CURLKHTYPE_ECDSA; - break; -#endif -#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519 - case LIBSSH2_HOSTKEY_TYPE_ED25519: - keytype = CURLKHTYPE_ED25519; - break; -#endif - } - return keytype; -} - -static CURLcode ssh_knownhost(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int sshkeytype = 0; - size_t keylen = 0; - int rc = 0; - CURLcode result = CURLE_OK; - - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - /* we are asked to verify the host against a file */ - struct connectdata *conn = data->conn; - struct libssh2_knownhost *host = NULL; - const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, - &keylen, &sshkeytype); - int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE; - int keybit = 0; - - if(remotekey) { - /* - * A subject to figure out is what hostname we need to pass in here. - * What hostname does OpenSSH store in its file if an IDN name is - * used? - */ - enum curl_khmatch keymatch; - curl_sshkeycallback func = - data->set.ssh_keyfunc ? data->set.ssh_keyfunc : sshkeycallback; - struct curl_khkey knownkey; - struct curl_khkey *knownkeyp = NULL; - struct curl_khkey foundkey; - - switch(sshkeytype) { - case LIBSSH2_HOSTKEY_TYPE_RSA: - keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA; - break; - case LIBSSH2_HOSTKEY_TYPE_DSS: - keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS; - break; - case LIBSSH2_HOSTKEY_TYPE_ECDSA_256: - keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256; - break; - case LIBSSH2_HOSTKEY_TYPE_ECDSA_384: - keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384; - break; - case LIBSSH2_HOSTKEY_TYPE_ECDSA_521: - keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521; - break; - case LIBSSH2_HOSTKEY_TYPE_ED25519: - keybit = LIBSSH2_KNOWNHOST_KEY_ED25519; - break; - default: - infof(data, "unsupported key type, cannot check knownhosts"); - keybit = 0; - break; - } - if(!keybit) - /* no check means failure! */ - rc = CURLKHSTAT_REJECT; - else { - keycheck = libssh2_knownhost_checkp(sshc->kh, - conn->host.name, - (conn->remote_port != PORT_SSH) ? - conn->remote_port : -1, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); - - infof(data, "SSH host check: %d, key: %s", keycheck, - (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) ? - host->key : ""); - - /* setup 'knownkey' */ - if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { - knownkey.key = host->key; - knownkey.len = 0; - knownkey.keytype = convert_ssh2_keytype(sshkeytype); - knownkeyp = &knownkey; - } - - /* setup 'foundkey' */ - foundkey.key = remotekey; - foundkey.len = keylen; - foundkey.keytype = convert_ssh2_keytype(sshkeytype); - - /* - * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the - * curl_khmatch enum are ever modified, we need to introduce a - * translation table here! - */ - keymatch = (enum curl_khmatch)keycheck; - - /* Ask the callback how to behave */ - Curl_set_in_callback(data, TRUE); - rc = func(data, knownkeyp, /* from the knownhosts file */ - &foundkey, /* from the remote host */ - keymatch, data->set.ssh_keyfunc_userp); - Curl_set_in_callback(data, FALSE); - } - } - else - /* no remotekey means failure! */ - rc = CURLKHSTAT_REJECT; - - switch(rc) { - default: /* unknown return codes is the same as reject */ - case CURLKHSTAT_REJECT: - myssh_to(data, sshc, SSH_SESSION_FREE); - FALLTHROUGH(); - case CURLKHSTAT_DEFER: - /* DEFER means bail out but keep the SSH_HOSTKEY state */ - result = CURLE_PEER_FAILED_VERIFICATION; - break; - case CURLKHSTAT_FINE_REPLACE: - /* remove old host+key that does not match */ - if(host) - libssh2_knownhost_del(sshc->kh, host); - FALLTHROUGH(); - case CURLKHSTAT_FINE: - case CURLKHSTAT_FINE_ADD_TO_FILE: - /* proceed */ - if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) { - /* the found host+key did not match but has been told to be fine - anyway so we add it in memory */ - int addrc = libssh2_knownhost_add(sshc->kh, - conn->host.name, NULL, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, NULL); - if(addrc) - infof(data, "WARNING: adding the known host %s failed", - conn->host.name); - else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE || - rc == CURLKHSTAT_FINE_REPLACE) { - /* now we write the entire in-memory list of known hosts to the - known_hosts file */ - int wrc = - libssh2_knownhost_writefile(sshc->kh, - data->set.str[STRING_SSH_KNOWNHOSTS], - LIBSSH2_KNOWNHOST_FILE_OPENSSH); - if(wrc) { - infof(data, "WARNING: writing %s failed", - data->set.str[STRING_SSH_KNOWNHOSTS]); - } - } - } - break; - } - } - return result; -} - -static CURLcode ssh_check_fingerprint(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; - const char *pubkey_sha256 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256]; - - infof(data, "SSH MD5 public key: %s", - pubkey_md5 != NULL ? pubkey_md5 : "NULL"); - infof(data, "SSH SHA256 public key: %s", - pubkey_sha256 != NULL ? pubkey_sha256 : "NULL"); - - if(pubkey_sha256) { - const char *fingerprint = NULL; - char *fingerprint_b64 = NULL; - size_t fingerprint_b64_len; - size_t pub_pos = 0; - size_t b64_pos = 0; - - /* The fingerprint points to static storage (!), do not free() it. */ - fingerprint = libssh2_hostkey_hash(sshc->ssh_session, - LIBSSH2_HOSTKEY_HASH_SHA256); - if(!fingerprint) { - failf(data, - "Denied establishing ssh session: SHA256 fingerprint " - "not available"); - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_PEER_FAILED_VERIFICATION; - } - - /* The length of fingerprint is 32 bytes for SHA256. - * See libssh2_hostkey_hash documentation. */ - if(curlx_base64_encode((const uint8_t *)fingerprint, 32, &fingerprint_b64, - &fingerprint_b64_len) != CURLE_OK) { - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_PEER_FAILED_VERIFICATION; - } - - if(!fingerprint_b64) { - failf(data, "SHA256 fingerprint could not be encoded"); - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_PEER_FAILED_VERIFICATION; - } - - infof(data, "SSH SHA256 fingerprint: %s", fingerprint_b64); - - /* Find the position of any = padding characters in the public key */ - while((pubkey_sha256[pub_pos] != '=') && pubkey_sha256[pub_pos]) { - pub_pos++; - } - - /* Find the position of any = padding characters in the base64 coded - * hostkey fingerprint */ - while((fingerprint_b64[b64_pos] != '=') && fingerprint_b64[b64_pos]) { - b64_pos++; - } - - /* Before we authenticate we check the hostkey's SHA256 fingerprint - * against a known fingerprint, if available. - */ - if((pub_pos != b64_pos) || - strncmp(fingerprint_b64, pubkey_sha256, pub_pos)) { - failf(data, - "Denied establishing ssh session: mismatch SHA256 fingerprint. " - "Remote %s is not equal to %s", fingerprint_b64, pubkey_sha256); - curlx_free(fingerprint_b64); - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_PEER_FAILED_VERIFICATION; - } - - curlx_free(fingerprint_b64); - - infof(data, "SHA256 checksum match"); - } - - if(pubkey_md5) { - char md5buffer[33]; - const char *fingerprint; - - fingerprint = libssh2_hostkey_hash(sshc->ssh_session, - LIBSSH2_HOSTKEY_HASH_MD5); - - if(fingerprint) { - /* The fingerprint points to static storage (!), do not free() it. */ - int i; - for(i = 0; i < 16; i++) { - curl_msnprintf(&md5buffer[i * 2], 3, "%02x", - (unsigned char)fingerprint[i]); - } - - infof(data, "SSH MD5 fingerprint: %s", md5buffer); - } - - /* This does NOT verify the length of 'pubkey_md5' separately, which - makes the comparison below fail unless it is exactly 32 characters */ - if(!fingerprint || !curl_strequal(md5buffer, pubkey_md5)) { - if(fingerprint) { - failf(data, - "Denied establishing ssh session: mismatch MD5 fingerprint. " - "Remote %s is not equal to %s", md5buffer, pubkey_md5); - } - else { - failf(data, - "Denied establishing ssh session: MD5 fingerprint " - "not available"); - } - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_PEER_FAILED_VERIFICATION; - } - infof(data, "MD5 checksum match"); - } - - if(!pubkey_md5 && !pubkey_sha256) { - if(data->set.ssh_hostkeyfunc) { - size_t keylen = 0; - int sshkeytype = 0; - int rc = 0; - /* we handle the process to the callback */ - const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, - &keylen, &sshkeytype); - if(remotekey) { - enum curl_khtype keytype = convert_ssh2_keytype(sshkeytype); - Curl_set_in_callback(data, TRUE); - rc = data->set.ssh_hostkeyfunc(data->set.ssh_hostkeyfunc_userp, - (int)keytype, remotekey, keylen); - Curl_set_in_callback(data, FALSE); - if(rc != CURLKHMATCH_OK) { - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_PEER_FAILED_VERIFICATION; - } - } - else { - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_PEER_FAILED_VERIFICATION; - } - return CURLE_OK; - } - else { - return ssh_knownhost(data, sshc); - } - } - else { - /* as we already matched, we skip the check for known hosts */ - return CURLE_OK; - } -} - -/* - * ssh_force_knownhost_key_type() checks the known hosts file and try to - * force a specific public key type from the server if an entry is found. - */ -static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - CURLcode result = CURLE_OK; - - static const char hostkey_method_ssh_ed25519[] = "ssh-ed25519"; - static const char hostkey_method_ssh_ecdsa_521[] = "ecdsa-sha2-nistp521"; - static const char hostkey_method_ssh_ecdsa_384[] = "ecdsa-sha2-nistp384"; - static const char hostkey_method_ssh_ecdsa_256[] = "ecdsa-sha2-nistp256"; - static const char hostkey_method_ssh_rsa_all[] = - "rsa-sha2-256,rsa-sha2-512,ssh-rsa"; - static const char hostkey_method_ssh_dss[] = "ssh-dss"; - bool found = FALSE; - - if(sshc->kh && - !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] && - !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256]) { - struct libssh2_knownhost *store = NULL; - struct connectdata *conn = data->conn; - /* lets try to find our host in the known hosts file */ - while(!libssh2_knownhost_get(sshc->kh, &store, store)) { - /* For non-standard ports, the name is enclosed in */ - /* square brackets, followed by a colon and the port */ - if(store) { - if(store->name) { - if(store->name[0] == '[') { - curl_off_t port; - size_t kh_name_size = 0; - const char *p; - const char *kh_name_end = strstr(store->name, "]:"); - if(!kh_name_end) { - infof(data, "Invalid host pattern %s in %s", - store->name, data->set.str[STRING_SSH_KNOWNHOSTS]); - continue; - } - p = kh_name_end + 2; /* start of port number */ - if(!curlx_str_number(&p, &port, 0xffff) && - (kh_name_end && (port == conn->remote_port))) { - kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end); - if(strncmp(store->name + 1, - conn->host.name, kh_name_size) == 0) { - found = TRUE; - break; - } - } - } - else if(strcmp(store->name, conn->host.name) == 0) { - found = TRUE; - break; - } - } - else { - found = TRUE; - break; - } - } - } - - if(found) { - int rc; - const char *hostkey_method = NULL; - infof(data, "Found host %s in %s", - conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]); - - switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) { - case LIBSSH2_KNOWNHOST_KEY_ED25519: - hostkey_method = hostkey_method_ssh_ed25519; - break; - case LIBSSH2_KNOWNHOST_KEY_ECDSA_521: - hostkey_method = hostkey_method_ssh_ecdsa_521; - break; - case LIBSSH2_KNOWNHOST_KEY_ECDSA_384: - hostkey_method = hostkey_method_ssh_ecdsa_384; - break; - case LIBSSH2_KNOWNHOST_KEY_ECDSA_256: - hostkey_method = hostkey_method_ssh_ecdsa_256; - break; - case LIBSSH2_KNOWNHOST_KEY_SSHRSA: - hostkey_method = hostkey_method_ssh_rsa_all; - break; - case LIBSSH2_KNOWNHOST_KEY_SSHDSS: - hostkey_method = hostkey_method_ssh_dss; - break; - case LIBSSH2_KNOWNHOST_KEY_RSA1: - failf(data, "Found host key type RSA1 which is not supported"); - return CURLE_SSH; - default: - failf(data, "Unknown host key type: %i", - (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK)); - return CURLE_SSH; - } - - infof(data, "Set \"%s\" as SSH hostkey type", hostkey_method); - rc = libssh2_session_method_pref(sshc->ssh_session, - LIBSSH2_METHOD_HOSTKEY, hostkey_method); - if(rc) { - char *err_msg = NULL; - int errlen; - libssh2_session_last_error(sshc->ssh_session, &err_msg, &errlen, 0); - failf(data, "libssh2 method '%s' failed: %s", hostkey_method, err_msg); - result = libssh2_session_error_to_CURLE(rc); - } - } - else { - infof(data, "Did not find host %s in %s", - conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]); - } - } - - return result; -} - -static CURLcode quote_error(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - failf(data, "Suspicious data after the command line"); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - return CURLE_QUOTE_ERROR; -} - -static CURLcode sftp_quote(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - const char *cp; - CURLcode result = CURLE_OK; - - /* - * Support some of the "FTP" commands - * - * 'sshc->quote_item' is already verified to be non-NULL before it - * switched to this state. - */ - const char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command is allowed to fail without it causing any - aborts or cancels etc. It causes libcurl to act as if the command - is successful, whatever the server responds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(curl_strequal("pwd", cmd)) { - /* output debug output if that is requested */ - char *tmp = curl_maprintf("257 \"%s\" is current directory.\n", - sshp->path); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - Curl_debug(data, CURLINFO_HEADER_OUT, "PWD\n", 4); - Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); - - /* this sends an FTP-like "header" to the header callback so that - the current directory can be read similar to how it is read when - using ordinary FTP. */ - result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - curlx_free(tmp); - if(!result) - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return result; - } - - /* - * the arguments following the command must be separated from the - * command with a space so we can check for it unconditionally - */ - cp = strchr(cmd, ' '); - if(!cp) { - failf(data, "Syntax error command '%s', missing parameter", cmd); - return result; - } - - /* - * also, every command takes at least one argument so we get that - * first argument right now - */ - result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); - if(result) { - if(result != CURLE_OUT_OF_MEMORY) - failf(data, "Syntax error: Bad first parameter to '%s'", cmd); - return result; - } - - /* - * SFTP is a binary protocol, so we do not send text commands to the server. - * Instead, we scan for commands used by OpenSSH's sftp program and call the - * appropriate libssh2 functions. - */ - if(!strncmp(cmd, "chgrp ", 6) || - !strncmp(cmd, "chmod ", 6) || - !strncmp(cmd, "chown ", 6) || - !strncmp(cmd, "atime ", 6) || - !strncmp(cmd, "mtime ", 6)) { - /* attribute change */ - - /* sshc->quote_path1 contains the mode to set */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result != CURLE_OUT_OF_MEMORY) - failf(data, "Syntax error in %s: Bad second parameter", cmd); - curlx_safefree(sshc->quote_path1); - return result; - } - if(*cp) - return quote_error(data, sshc); - - memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - myssh_to(data, sshc, SSH_SFTP_QUOTE_STAT); - return result; - } - if(!strncmp(cmd, "ln ", 3) || - !strncmp(cmd, "symlink ", 8)) { - /* symbolic linking */ - /* sshc->quote_path1 is the source */ - /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result != CURLE_OUT_OF_MEMORY) - failf(data, "Syntax error in ln/symlink: Bad second parameter"); - curlx_safefree(sshc->quote_path1); - return result; - } - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_SYMLINK); - return result; - } - else if(!strncmp(cmd, "mkdir ", 6)) { - if(*cp) - return quote_error(data, sshc); - /* create directory */ - myssh_to(data, sshc, SSH_SFTP_QUOTE_MKDIR); - return result; - } - else if(!strncmp(cmd, "rename ", 7)) { - /* rename file */ - /* first param is the source path */ - /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); - if(result) { - if(result != CURLE_OUT_OF_MEMORY) - failf(data, "Syntax error in rename: Bad second parameter"); - curlx_safefree(sshc->quote_path1); - return result; - } - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_RENAME); - return result; - } - else if(!strncmp(cmd, "rmdir ", 6)) { - if(*cp) - return quote_error(data, sshc); - /* delete directory */ - myssh_to(data, sshc, SSH_SFTP_QUOTE_RMDIR); - return result; - } - else if(!strncmp(cmd, "rm ", 3)) { - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_UNLINK); - return result; - } - else if(!strncmp(cmd, "statvfs ", 8)) { - if(*cp) - return quote_error(data, sshc); - myssh_to(data, sshc, SSH_SFTP_QUOTE_STATVFS); - return result; - } - - failf(data, "Unknown SFTP command"); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - return CURLE_QUOTE_ERROR; -} - -static CURLcode sftp_upload_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *blockp) -{ - unsigned long flags; - - /* - * NOTE!!! libssh2 requires that the destination path is a full path - * that includes the destination file and name OR ends in a "/" - * If this is not done the destination file is named the - * same name as the last directory in the path. - */ - - if(data->state.resume_from) { - LIBSSH2_SFTP_ATTRIBUTES attrs; - if(data->state.resume_from < 0) { - int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, - curlx_uztoui(strlen(sshp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - *blockp = TRUE; - return CURLE_OK; - } - if(rc) { - data->state.resume_from = 0; - } - else { - curl_off_t size = attrs.filesize; - if(size < 0) { - failf(data, "Bad file size (%" FMT_OFF_T ")", size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - data->state.resume_from = attrs.filesize; - } - } - } - - if(data->set.remote_append) { - /* True append mode: create if nonexisting */ - flags = LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_APPEND; - } - else if(data->state.resume_from > 0) { - /* - * Resume MUST NOT use APPEND; some servers force writes to EOF when - * APPEND is set, ignoring a prior seek(). - */ - flags = LIBSSH2_FXF_WRITE; - } - else { - /* Clear file before writing (normal behavior) */ - flags = LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC; - } - - sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sshp->path, - curlx_uztoui(strlen(sshp->path)), - flags, (long)data->set.new_file_perms, - LIBSSH2_SFTP_OPENFILE); - - if(!sshc->sftp_handle) { - CURLcode result; - unsigned long sftperr; - int rc = libssh2_session_last_errno(sshc->ssh_session); - - if(LIBSSH2_ERROR_EAGAIN == rc) { - *blockp = TRUE; - return CURLE_OK; - } - - if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc) - /* only when there was an SFTP protocol error can we extract - the sftp error! */ - sftperr = libssh2_sftp_last_error(sshc->sftp_session); - else - sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */ - - if(sshc->secondCreateDirs) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - failf(data, "Creating the dir/file failed: %s", - sftp_libssh2_strerror(sftperr)); - return sftp_libssh2_error_to_CURLE(sftperr); - } - if((sftperr == LIBSSH2_FX_NO_SUCH_FILE || - sftperr == LIBSSH2_FX_FAILURE || - sftperr == LIBSSH2_FX_NO_SUCH_PATH) && - data->set.ftp_create_missing_dirs && - (strlen(sshp->path) > 1)) { - /* try to create the path remotely */ - sshc->secondCreateDirs = 1; - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_INIT); - return CURLE_OK; - } - myssh_to(data, sshc, SSH_SFTP_CLOSE); - result = sftp_libssh2_error_to_CURLE(sftperr); - if(!result) { - /* Sometimes, for some reason libssh2_sftp_last_error() returns zero - even though libssh2_sftp_open() failed previously! We need to - work around that! */ - result = CURLE_SSH; - sftperr = LIBSSH2_FX_OK; - } - failf(data, "Upload failed: %s (%lu/%d)", - sftperr != LIBSSH2_FX_OK ? - sftp_libssh2_strerror(sftperr) : "ssh error", - sftperr, rc); - return result; - } - - /* If we have a restart point then we need to seek to the correct - Skip if in explicit remote append mode. */ - if(data->state.resume_from > 0 && !data->set.remote_append) { - int seekerr = CURL_SEEKFUNC_OK; - /* Let's read off the proper amount of bytes from the input. */ - if(data->set.seek_func) { - Curl_set_in_callback(data, TRUE); - seekerr = data->set.seek_func(data->set.seek_client, - data->state.resume_from, SEEK_SET); - Curl_set_in_callback(data, FALSE); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - curl_off_t passed = 0; - - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_FTP_COULDNT_USE_REST; - } - /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */ - do { - char scratch[4 * 1024]; - size_t readthisamountnow = - (data->state.resume_from - passed > - (curl_off_t)sizeof(scratch)) ? - sizeof(scratch) : curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread; - Curl_set_in_callback(data, TRUE); - actuallyread = data->state.fread_func(scratch, 1, - readthisamountnow, - data->state.in); - Curl_set_in_callback(data, FALSE); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Failed to read data"); - return CURLE_FTP_COULDNT_USE_REST; - } - } while(passed < data->state.resume_from); - } - - /* now, decrease the size of the read */ - if(data->state.infilesize > 0) { - data->state.infilesize -= data->state.resume_from; - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - - libssh2_sftp_seek64(sshc->sftp_handle, - (libssh2_uint64_t)data->state.resume_from); - } - if(data->state.infilesize > 0) { - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - /* upload data */ - Curl_xfer_setup_send(data, FIRSTSOCKET); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->recv_idx = FIRSTSOCKET; - - /* since we do not really wait for anything at this point, we want the - state machine to move on as soon as possible so mark this as dirty */ - Curl_multi_mark_dirty(data); - - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; -} - -static CURLcode ssh_state_pkey_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* - * Check the supported auth types in the order I feel is most secure - * with the requested type of authentication - */ - sshc->authed = FALSE; - - if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && - (strstr(sshc->authlist, "publickey") != NULL)) { - bool out_of_memory = FALSE; - - sshc->rsa_pub = sshc->rsa = NULL; - - if(data->set.str[STRING_SSH_PRIVATE_KEY]) { - sshc->rsa = curlx_strdup(data->set.str[STRING_SSH_PRIVATE_KEY]); - if(!sshc->rsa) - out_of_memory = TRUE; - } - else { - /* To ponder about: should really the lib be messing about with the - HOME environment variable etc? */ - char *home = curl_getenv("HOME"); - curlx_struct_stat sbuf; - - /* If no private key file is specified, try some common paths. */ - if(home) { - /* Try ~/.ssh first. */ - sshc->rsa = curl_maprintf("%s/.ssh/id_rsa", home); - if(!sshc->rsa) - out_of_memory = TRUE; - else if(curlx_stat(sshc->rsa, &sbuf)) { - curlx_free(sshc->rsa); - sshc->rsa = curl_maprintf("%s/.ssh/id_dsa", home); - if(!sshc->rsa) - out_of_memory = TRUE; - else if(curlx_stat(sshc->rsa, &sbuf)) { - curlx_safefree(sshc->rsa); - } - } - curlx_free(home); - } - if(!out_of_memory && !sshc->rsa) { - /* Nothing found; try the current dir. */ - sshc->rsa = curlx_strdup("id_rsa"); - if(sshc->rsa && curlx_stat(sshc->rsa, &sbuf)) { - curlx_free(sshc->rsa); - sshc->rsa = curlx_strdup("id_dsa"); - if(sshc->rsa && curlx_stat(sshc->rsa, &sbuf)) { - curlx_free(sshc->rsa); - /* Out of guesses. Set to the empty string to avoid - * surprising info messages. */ - sshc->rsa = curlx_strdup(""); - } - } - } - } - - /* - * Unless the user explicitly specifies a public key file, let - * libssh2 extract the public key from the private key file. - * This is done by passing sshc->rsa_pub = NULL. - */ - if(!out_of_memory && data->set.str[STRING_SSH_PUBLIC_KEY] && - /* treat empty string the same way as NULL */ - data->set.str[STRING_SSH_PUBLIC_KEY][0]) { - sshc->rsa_pub = curlx_strdup(data->set.str[STRING_SSH_PUBLIC_KEY]); - if(!sshc->rsa_pub) - out_of_memory = TRUE; - } - - if(out_of_memory || !sshc->rsa) { - curlx_safefree(sshc->rsa); - curlx_safefree(sshc->rsa_pub); - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_OUT_OF_MEMORY; - } - - sshc->passphrase = data->set.ssl.key_passwd; - if(!sshc->passphrase) - sshc->passphrase = ""; - - if(sshc->rsa_pub) - infof(data, "Using SSH public key file '%s'", sshc->rsa_pub); - infof(data, "Using SSH private key file '%s'", sshc->rsa); - - myssh_to(data, sshc, SSH_AUTH_PKEY); - } - else { - myssh_to(data, sshc, SSH_AUTH_PASS_INIT); - } - return CURLE_OK; -} - -static CURLcode sftp_quote_stat(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *blockp) -{ - const char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command is allowed to fail without it causing any aborts or - cancels etc. It causes libcurl to act as if the command is - successful, whatever the server responds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(!!strncmp(cmd, "chmod", 5)) { - /* Since chown and chgrp only set owner OR group but libssh2 wants to set - * them both at once, we need to obtain the current ownership first. This - * takes an extra protocol round trip. - */ - int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_STAT, - &sshp->quote_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - *blockp = TRUE; - return CURLE_OK; - } - if(rc && !sshc->acceptfail) { /* get those attributes */ - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "Attempt to get SFTP stats failed: %s", - sftp_libssh2_strerror(sftperr)); - goto fail; - } - } - - /* Now set the new attributes... */ - if(!strncmp(cmd, "chgrp", 5)) { - const char *p = sshc->quote_path1; - curl_off_t gid; - if(!curlx_str_number(&p, &gid, ULONG_MAX)) { - sshp->quote_attrs.gid = (unsigned long)gid; - sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - } - else if(!sshc->acceptfail) { - failf(data, "Syntax error: chgrp gid not a number"); - goto fail; - } - } - else if(!strncmp(cmd, "chmod", 5)) { - curl_off_t perms; - const char *p = sshc->quote_path1; - /* permissions are octal */ - if(curlx_str_octal(&p, &perms, 07777)) { - failf(data, "Syntax error: chmod permissions not a number"); - goto fail; - } - - sshp->quote_attrs.permissions = (unsigned long)perms; - sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; - } - else if(!strncmp(cmd, "chown", 5)) { - const char *p = sshc->quote_path1; - curl_off_t uid; - if(!curlx_str_number(&p, &uid, ULONG_MAX)) { - sshp->quote_attrs.uid = (unsigned long)uid; - sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - } - else if(!sshc->acceptfail) { - failf(data, "Syntax error: chown uid not a number"); - goto fail; - } - } - else if(!strncmp(cmd, "atime", 5) || - !strncmp(cmd, "mtime", 5)) { - time_t date; - bool fail = FALSE; - - if(Curl_getdate_capped(sshc->quote_path1, &date)) { - failf(data, "incorrect date format for %.*s", 5, cmd); - fail = TRUE; - } -#if SIZEOF_TIME_T > SIZEOF_LONG - if(date > 0xffffffff) { - /* if 'long' cannot hold >32-bit, this date cannot be sent */ - failf(data, "date overflow"); - fail = TRUE; - } -#endif - if(fail) - goto fail; - if(!strncmp(cmd, "atime", 5)) - sshp->quote_attrs.atime = (unsigned long)date; - else /* mtime */ - sshp->quote_attrs.mtime = (unsigned long)date; - - sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; - } - - /* Now send the completed structure... */ - myssh_to(data, sshc, SSH_SFTP_QUOTE_SETSTAT); - return CURLE_OK; -fail: - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - return CURLE_QUOTE_ERROR; -} - -static CURLcode sftp_download_stat(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *blockp) -{ - LIBSSH2_SFTP_ATTRIBUTES attrs; - int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, - curlx_uztoui(strlen(sshp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - *blockp = TRUE; - return CURLE_OK; - } - if(rc || - !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) || - (attrs.filesize == 0)) { - /* - * libssh2_sftp_open() did not return an error, so maybe the server - * does not support stat() - * OR the server does not return a file size with a stat() - * OR file size is 0 - */ - data->req.size = -1; - data->req.maxdownload = -1; - Curl_pgrsSetDownloadSize(data, -1); - attrs.filesize = 0; /* might be uninitialized but is read below */ - } - else { - curl_off_t size = attrs.filesize; - - if(size < 0) { - failf(data, "Bad file size (%" FMT_OFF_T ")", size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - if(data->state.use_range) { - curl_off_t from; - CURLcode result = Curl_ssh_range(data, data->state.range, size, - &from, &size); - if(result) - return result; - - libssh2_sftp_seek64(sshc->sftp_handle, (libssh2_uint64_t)from); - } - data->req.size = size; - data->req.maxdownload = size; - Curl_pgrsSetDownloadSize(data, size); - } - - /* We can resume if we can seek to the resume position */ - if(data->state.resume_from) { - if(data->state.resume_from < 0) { - /* We are supposed to download the last abs(from) bytes */ - if((curl_off_t)attrs.filesize < -data->state.resume_from) { - failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" - FMT_OFF_T ")", - data->state.resume_from, (curl_off_t)attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* download from where? */ - data->state.resume_from += attrs.filesize; - } - else { - if((curl_off_t)attrs.filesize < data->state.resume_from) { - failf(data, "Offset (%" FMT_OFF_T - ") was beyond file size (%" FMT_OFF_T ")", - data->state.resume_from, (curl_off_t)attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - } - /* Now store the number of bytes we are expected to download */ - data->req.size = attrs.filesize - data->state.resume_from; - data->req.maxdownload = attrs.filesize - data->state.resume_from; - Curl_pgrsSetDownloadSize(data, attrs.filesize - data->state.resume_from); - libssh2_sftp_seek64(sshc->sftp_handle, - (libssh2_uint64_t)data->state.resume_from); - } - - /* Setup the actual download */ - if(data->req.size == 0) { - /* no data to transfer */ - Curl_xfer_setup_nop(data); - infof(data, "File already completely downloaded"); - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; - } - Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->send_idx = 0; - - myssh_to(data, sshc, SSH_STOP); - - return CURLE_OK; -} - -static CURLcode sftp_readdir(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *blockp) -{ - CURLcode result = CURLE_OK; - int rc = libssh2_sftp_readdir_ex(sshc->sftp_handle, - sshp->readdir_filename, CURL_PATH_MAX, - sshp->readdir_longentry, CURL_PATH_MAX, - &sshp->readdir_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - *blockp = TRUE; - return result; - } - if(rc > 0) { - size_t readdir_len = (size_t)rc; - sshp->readdir_filename[readdir_len] = '\0'; - - if(data->set.list_only) { - result = Curl_client_write(data, CLIENTWRITE_BODY, - sshp->readdir_filename, - readdir_len); - if(!result) - result = Curl_client_write(data, CLIENTWRITE_BODY, "\n", 1); - if(result) - return result; - } - else { - result = curlx_dyn_add(&sshp->readdir, sshp->readdir_longentry); - - if(!result) { - if((sshp->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) && - ((sshp->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) == - LIBSSH2_SFTP_S_IFLNK)) { - result = curlx_dyn_addf(&sshp->readdir_link, "%s%s", sshp->path, - sshp->readdir_filename); - myssh_to(data, sshc, SSH_SFTP_READDIR_LINK); - } - else { - myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM); - } - } - return result; - } - } - else if(!rc) { - myssh_to(data, sshc, SSH_SFTP_READDIR_DONE); - } - else { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - result = sftperr ? sftp_libssh2_error_to_CURLE(sftperr) : CURLE_SSH; - failf(data, "Could not open remote file for reading: %s :: %d", - sftp_libssh2_strerror(sftperr), - libssh2_session_last_errno(sshc->ssh_session)); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - } - return result; -} - -static CURLcode ssh_state_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - CURLcode result; - sshc->secondCreateDirs = 0; - sshc->nextstate = SSH_NO_STATE; - - /* Set libssh2 to non-blocking, since everything internally is - non-blocking */ - libssh2_session_set_blocking(sshc->ssh_session, 0); - - result = ssh_force_knownhost_key_type(data, sshc); - if(result) - myssh_to(data, sshc, SSH_SESSION_FREE); - else - myssh_to(data, sshc, SSH_S_STARTUP); - return result; -} - -static CURLcode ssh_state_startup(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - struct connectdata *conn = data->conn; - int rc = libssh2_session_handshake(sshc->ssh_session, - conn->sock[FIRSTSOCKET]); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg); - - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_FAILED_INIT; - } - - myssh_to(data, sshc, SSH_HOSTKEY); - return CURLE_OK; -} - -static CURLcode ssh_state_hostkey(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* - * Before we authenticate we should check the hostkey's fingerprint - * against our known hosts. How that is handled (reading from file, - * whatever) is up to us. - */ - CURLcode result = ssh_check_fingerprint(data, sshc); - if(!result) - myssh_to(data, sshc, SSH_AUTHLIST); - return result; -} - -static CURLcode ssh_state_authlist(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* - * Figure out authentication methods - * NB: As soon as we have provided a username to an openssh server we - * must never change it later. Thus, always specify the correct username - * here, even though the libssh2 docs kind of indicate that it should be - * possible to get a 'generic' list (not user-specific) of authentication - * methods, presumably with a blank username. That does not work in my - * experience. - * Therefore always specify it here. - */ - struct connectdata *conn = data->conn; - sshc->authlist = libssh2_userauth_list(sshc->ssh_session, - conn->user, - curlx_uztoui(strlen(conn->user))); - - if(!sshc->authlist) { - int rc; - if(libssh2_userauth_authenticated(sshc->ssh_session)) { - sshc->authed = TRUE; - infof(data, "SSH user accepted with no authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return CURLE_OK; - } - rc = libssh2_session_last_errno(sshc->ssh_session); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - myssh_to(data, sshc, SSH_SESSION_FREE); - return libssh2_session_error_to_CURLE(rc); - } - infof(data, "SSH authentication methods available: %s", sshc->authlist); - - myssh_to(data, sshc, SSH_AUTH_PKEY_INIT); - return CURLE_OK; -} - -static CURLcode ssh_state_auth_pkey(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* The function below checks if the files exists, no need to stat() here. - */ - struct connectdata *conn = data->conn; - int rc = - libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session, - conn->user, - curlx_uztoui( - strlen(conn->user)), - sshc->rsa_pub, - sshc->rsa, sshc->passphrase); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - curlx_safefree(sshc->rsa_pub); - curlx_safefree(sshc->rsa); - - if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized SSH public key authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - } - else { - char *err_msg = NULL; - char unknown[] = "Reason unknown (-1)"; - if(rc == -1) { - /* No error message has been set and the last set error message, if - any, is from a previous error so ignore it. #11837 */ - err_msg = unknown; - } - else { - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - } - infof(data, "SSH public key authentication failed: %s", err_msg); - myssh_to(data, sshc, SSH_AUTH_PASS_INIT); - } - return CURLE_OK; -} - -static CURLcode ssh_state_auth_pass_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && - (strstr(sshc->authlist, "password") != NULL)) { - myssh_to(data, sshc, SSH_AUTH_PASS); - } - else { - myssh_to(data, sshc, SSH_AUTH_HOST_INIT); - } - return CURLE_OK; -} - -static CURLcode ssh_state_auth_pass(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - struct connectdata *conn = data->conn; - int rc = - libssh2_userauth_password_ex(sshc->ssh_session, conn->user, - curlx_uztoui(strlen(conn->user)), - conn->passwd, - curlx_uztoui(strlen(conn->passwd)), - NULL); - if(rc == LIBSSH2_ERROR_EAGAIN) { - return CURLE_AGAIN; - } - if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized password authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - } - else { - myssh_to(data, sshc, SSH_AUTH_HOST_INIT); - } - return CURLE_OK; -} - -static CURLcode ssh_state_auth_host_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && - (strstr(sshc->authlist, "hostbased") != NULL)) { - myssh_to(data, sshc, SSH_AUTH_HOST); - } - else { - myssh_to(data, sshc, SSH_AUTH_AGENT_INIT); - } - return CURLE_OK; -} - -static CURLcode ssh_state_auth_agent_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = 0; - if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) && - (strstr(sshc->authlist, "publickey") != NULL)) { - - /* Connect to the ssh-agent */ - /* The agent could be shared by a curl thread i believe - but nothing obvious as keys can be added/removed at any time */ - if(!sshc->ssh_agent) { - sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session); - if(!sshc->ssh_agent) { - infof(data, "Could not create agent object"); - - myssh_to(data, sshc, SSH_AUTH_KEY_INIT); - return CURLE_OK; - } - } - - rc = libssh2_agent_connect(sshc->ssh_agent); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - if(rc < 0) { - infof(data, "Failure connecting to agent"); - myssh_to(data, sshc, SSH_AUTH_KEY_INIT); - } - else { - myssh_to(data, sshc, SSH_AUTH_AGENT_LIST); - } - } - else - myssh_to(data, sshc, SSH_AUTH_KEY_INIT); - return CURLE_OK; -} - -static CURLcode ssh_state_auth_agent_list(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = libssh2_agent_list_identities(sshc->ssh_agent); - - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - if(rc < 0) { - infof(data, "Failure requesting identities to agent"); - myssh_to(data, sshc, SSH_AUTH_KEY_INIT); - } - else { - myssh_to(data, sshc, SSH_AUTH_AGENT); - sshc->sshagent_prev_identity = NULL; - } - return CURLE_OK; -} - -static CURLcode ssh_state_auth_agent(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* as prev_identity evolves only after an identity user auth finished we - can safely request it again as long as EAGAIN is returned here or by - libssh2_agent_userauth */ - int rc = libssh2_agent_get_identity(sshc->ssh_agent, - &sshc->sshagent_identity, - sshc->sshagent_prev_identity); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc == 0) { - struct connectdata *conn = data->conn; - rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user, - sshc->sshagent_identity); - - if(rc < 0) { - if(rc != LIBSSH2_ERROR_EAGAIN) { - /* tried and failed? go to next identity */ - sshc->sshagent_prev_identity = sshc->sshagent_identity; - return CURLE_OK; - } - return CURLE_AGAIN; - } - } - - if(rc < 0) - infof(data, "Failure requesting identities to agent"); - else if(rc == 1) - infof(data, "No identity would match"); - - if(rc == LIBSSH2_ERROR_NONE) { - sshc->authed = TRUE; - infof(data, "Agent based authentication successful"); - myssh_to(data, sshc, SSH_AUTH_DONE); - } - else { - myssh_to(data, sshc, SSH_AUTH_KEY_INIT); - } - return CURLE_OK; -} - -static CURLcode ssh_state_auth_key_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) && - (strstr(sshc->authlist, "keyboard-interactive") != NULL)) { - myssh_to(data, sshc, SSH_AUTH_KEY); - } - else { - myssh_to(data, sshc, SSH_AUTH_DONE); - } - return CURLE_OK; -} - -static CURLcode ssh_state_auth_key(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* Authentication failed. Continue with keyboard-interactive now. */ - struct connectdata *conn = data->conn; - int rc = - libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session, - conn->user, - curlx_uztoui( - strlen(conn->user)), - &kbd_callback); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized keyboard interactive authentication"); - myssh_to(data, sshc, SSH_AUTH_DONE); - return CURLE_OK; - } - return CURLE_LOGIN_DENIED; -} - -static CURLcode ssh_state_auth_done(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - struct connectdata *conn = data->conn; - if(!sshc->authed) { - failf(data, "Authentication failure"); - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_LOGIN_DENIED; - } - - /* - * At this point we have an authenticated ssh session. - */ - infof(data, "Authentication complete"); - - Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ - - data->conn->recv_idx = FIRSTSOCKET; - conn->send_idx = -1; - - if(conn->scheme->protocol == CURLPROTO_SFTP) { - myssh_to(data, sshc, SSH_SFTP_INIT); - return CURLE_OK; - } - infof(data, "SSH CONNECT phase done"); - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* - * Start the libssh2 sftp session - */ - sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session); - if(!sshc->sftp_session) { - char *err_msg = NULL; - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - failf(data, "Failure initializing sftp session: %s", err_msg); - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_FAILED_INIT; - } - myssh_to(data, sshc, SSH_SFTP_REALPATH); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_realpath(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - /* - * Get the "home" directory - */ - int rc; - - if(!sshp) - return CURLE_FAILED_INIT; - - rc = libssh2_sftp_symlink_ex(sshc->sftp_session, ".", - curlx_uztoui(strlen(".")), - sshp->readdir_filename, CURL_PATH_MAX, - LIBSSH2_SFTP_REALPATH); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - myssh_to(data, sshc, SSH_STOP); - if(rc > 0) { - curlx_free(sshc->homedir); - sshc->homedir = curlx_strdup(sshp->readdir_filename); - if(!sshc->homedir) - return CURLE_OUT_OF_MEMORY; - curlx_free(data->state.most_recent_ftp_entrypath); - data->state.most_recent_ftp_entrypath = curlx_strdup(sshc->homedir); - if(!data->state.most_recent_ftp_entrypath) - return CURLE_OUT_OF_MEMORY; - } - else { - /* Return the error type */ - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - CURLcode result; - if(sftperr) - result = sftp_libssh2_error_to_CURLE(sftperr); - else - /* in this case, the error was not in the SFTP level but for example a - time-out or similar */ - result = CURLE_SSH; - CURL_TRC_SSH(data, "error = %lu makes libcurl = %d", sftperr, (int)result); - return result; - } - - /* This is the last step in the SFTP connect phase. Do note that while we - get the homedir here, we get the "workingpath" in the DO action since the - homedir remains the same between request but the working path does not. */ - CURL_TRC_SSH(data, "CONNECT phase done"); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - CURLcode result; - - if(!sshp) - return CURLE_FAILED_INIT; - - result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); - if(result) { - myssh_to(data, sshc, SSH_STOP); - return result; - } - - if(data->set.quote) { - infof(data, "Sending quote commands"); - sshc->quote_item = data->set.quote; - myssh_to(data, sshc, SSH_SFTP_QUOTE); - } - else { - myssh_to(data, sshc, SSH_SFTP_GETINFO); - } - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_postquote_init(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(data->set.postquote) { - infof(data, "Sending quote commands"); - sshc->quote_item = data->set.postquote; - myssh_to(data, sshc, SSH_SFTP_QUOTE); - } - else { - myssh_to(data, sshc, SSH_STOP); - } - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - /* Send quote commands */ - CURLcode result; - - if(!sshp) - return CURLE_FAILED_INIT; - - result = sftp_quote(data, sshc, sshp); - if(result) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - } - return result; -} - -static CURLcode ssh_state_sftp_next_quote(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - - sshc->quote_item = sshc->quote_item->next; - - if(sshc->quote_item) { - myssh_to(data, sshc, SSH_SFTP_QUOTE); - } - else { - if(sshc->nextstate != SSH_NO_STATE) { - myssh_to(data, sshc, sshc->nextstate); - sshc->nextstate = SSH_NO_STATE; - } - else { - myssh_to(data, sshc, SSH_SFTP_GETINFO); - } - } - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_stat(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *blockp) -{ - CURLcode result; - - if(!sshp) - return CURLE_FAILED_INIT; - - result = sftp_quote_stat(data, sshc, sshp, blockp); - if(result) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - } - return result; -} - -static CURLcode ssh_state_sftp_quote_setstat(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - int rc; - - if(!sshp) - return CURLE_FAILED_INIT; - - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_SETSTAT, - &sshp->quote_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc && !sshc->acceptfail) { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "Attempt to set SFTP stats for \"%s\" failed: %s", - sshc->quote_path2, sftp_libssh2_strerror(sftperr)); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_QUOTE_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_symlink(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = - libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_SYMLINK); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc && !sshc->acceptfail) { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "symlink \"%s\" to \"%s\" failed: %s", - sshc->quote_path1, sshc->quote_path2, - sftp_libssh2_strerror(sftperr)); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_QUOTE_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_mkdir(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - (long)data->set.new_directory_perms); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc && !sshc->acceptfail) { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "mkdir \"%s\" failed: %s", - sshc->quote_path1, sftp_libssh2_strerror(sftperr)); - curlx_safefree(sshc->quote_path1); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_QUOTE_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_rename(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = - libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_RENAME_OVERWRITE | - LIBSSH2_SFTP_RENAME_ATOMIC | - LIBSSH2_SFTP_RENAME_NATIVE); - - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc && !sshc->acceptfail) { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "rename \"%s\" to \"%s\" failed: %s", - sshc->quote_path1, sshc->quote_path2, - sftp_libssh2_strerror(sftperr)); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_QUOTE_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_rmdir(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1))); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc && !sshc->acceptfail) { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "rmdir \"%s\" failed: %s", - sshc->quote_path1, sftp_libssh2_strerror(sftperr)); - curlx_safefree(sshc->quote_path1); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_QUOTE_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_unlink(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - int rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1))); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc && !sshc->acceptfail) { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "rm \"%s\" failed: %s", - sshc->quote_path1, sftp_libssh2_strerror(sftperr)); - curlx_safefree(sshc->quote_path1); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_QUOTE_ERROR; - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_quote_statvfs(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - LIBSSH2_SFTP_STATVFS statvfs; - int rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - &statvfs); - - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc && !sshc->acceptfail) { - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "statvfs \"%s\" failed: %s", - sshc->quote_path1, sftp_libssh2_strerror(sftperr)); - curlx_safefree(sshc->quote_path1); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_QUOTE_ERROR; - } - else if(rc == 0) { -#ifdef _MSC_VER -#define CURL_LIBSSH2_VFS_SIZE_MASK "I64u" -#else -#define CURL_LIBSSH2_VFS_SIZE_MASK "llu" -#endif - CURLcode result; - char *tmp = curl_maprintf("statvfs:\n" - "f_bsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_frsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_blocks: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_bfree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_bavail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_files: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_ffree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_favail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_fsid: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_flag: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n" - "f_namemax: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n", - statvfs.f_bsize, statvfs.f_frsize, - statvfs.f_blocks, statvfs.f_bfree, - statvfs.f_bavail, statvfs.f_files, - statvfs.f_ffree, statvfs.f_favail, - statvfs.f_fsid, statvfs.f_flag, - statvfs.f_namemax); - if(!tmp) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return CURLE_OUT_OF_MEMORY; - } - - result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - curlx_free(tmp); - if(result) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - return result; - } - } - myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_create_dirs_mkdir(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - /* 'mode' - parameter is preliminary - default to 0644 */ - int rc; - - if(!sshp) - return CURLE_FAILED_INIT; - - rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshp->path, - curlx_uztoui(strlen(sshp->path)), - (long)data->set.new_directory_perms); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - *sshc->slash_pos = '/'; - ++sshc->slash_pos; - if(rc < 0) { - /* - * Abort if failure was not that the directory already exists or - * the permission was denied (creation might succeed further down - * the path) - retry on unspecific FAILURE also - */ - unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); - if((sftperr != LIBSSH2_FX_FILE_ALREADY_EXISTS) && - (sftperr != LIBSSH2_FX_FAILURE) && - (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - return sftp_libssh2_error_to_CURLE(sftperr); - } - } - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_readdir_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return CURLE_FAILED_INIT; - - Curl_pgrsSetDownloadSize(data, -1); - if(data->req.no_body) { - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; - } - - /* - * This is a directory that we are trying to get, so produce a directory - * listing - */ - sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sshp->path, - curlx_uztoui(strlen(sshp->path)), - 0, 0, LIBSSH2_SFTP_OPENDIR); - if(!sshc->sftp_handle) { - unsigned long sftperr; - if(libssh2_session_last_errno(sshc->ssh_session) == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "Could not open directory for reading: %s", - sftp_libssh2_strerror(sftperr)); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - return sftp_libssh2_error_to_CURLE(sftperr); - } - myssh_to(data, sshc, SSH_SFTP_READDIR); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_readdir_link(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - CURLcode result; - int rc; - if(!sshp) - return CURLE_FAILED_INIT; - - rc = libssh2_sftp_symlink_ex(sshc->sftp_session, - curlx_dyn_ptr(&sshp->readdir_link), - (unsigned int) - curlx_dyn_len(&sshp->readdir_link), - sshp->readdir_filename, - CURL_PATH_MAX, LIBSSH2_SFTP_READLINK); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - curlx_dyn_free(&sshp->readdir_link); - - if(rc < 0) - return CURLE_OUT_OF_MEMORY; - - /* append filename and extra output */ - result = curlx_dyn_addf(&sshp->readdir, " -> %s", sshp->readdir_filename); - if(result) - myssh_to(data, sshc, SSH_SFTP_CLOSE); - else - myssh_to(data, sshc, SSH_SFTP_READDIR_BOTTOM); - return result; -} - -static CURLcode ssh_state_scp_download_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - curl_off_t bytecount; - libssh2_struct_stat sb; - - if(!sshp) - return CURLE_FAILED_INIT; - /* - * We must check the remote file; if it is a directory no values are - * be set in sb - */ - - /* - * If support for >2GB files exists, use it. - */ - - /* get a fresh new channel from the ssh layer */ - memset(&sb, 0, sizeof(libssh2_struct_stat)); - sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session, sshp->path, &sb); - if(!sshc->ssh_channel) { - int ssh_err; - char *err_msg = NULL; - - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - ssh_err = libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - failf(data, "%s", err_msg); - myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); - return libssh2_session_error_to_CURLE(ssh_err); - } - - /* download data */ - bytecount = (curl_off_t)sb.st_size; - data->req.maxdownload = (curl_off_t)sb.st_size; - Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->send_idx = 0; - - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_close(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - int rc = 0; - if(!sshp) - return CURLE_FAILED_INIT; - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg); - } - sshc->sftp_handle = NULL; - } - - curlx_safefree(sshp->path); - - CURL_TRC_SSH(data, "SFTP DONE done"); - - /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT - After nextstate is executed, the control should come back to - SSH_SFTP_CLOSE to pass the correct result back */ - if(sshc->nextstate != SSH_NO_STATE && - sshc->nextstate != SSH_SFTP_CLOSE) { - myssh_to(data, sshc, sshc->nextstate); - sshc->nextstate = SSH_SFTP_CLOSE; - } - else - myssh_to(data, sshc, SSH_STOP); - - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_shutdown(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* during times we get here due to a broken transfer and then the - sftp_handle might not have been taken down so make sure that is done - before we proceed */ - int rc = 0; - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg); - } - sshc->sftp_handle = NULL; - } - if(sshc->sftp_session) { - rc = libssh2_sftp_shutdown(sshc->sftp_session); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc < 0) { - infof(data, "Failed to stop libssh2 sftp subsystem"); - } - sshc->sftp_session = NULL; - } - - curlx_safefree(sshc->homedir); - - myssh_to(data, sshc, SSH_SESSION_DISCONNECT); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_download_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return CURLE_FAILED_INIT; - /* - * Work on getting the specified file - */ - sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sshp->path, - curlx_uztoui(strlen(sshp->path)), - LIBSSH2_FXF_READ, (long)data->set.new_file_perms, - LIBSSH2_SFTP_OPENFILE); - if(!sshc->sftp_handle) { - unsigned long sftperr; - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - return CURLE_AGAIN; - } - sftperr = libssh2_sftp_last_error(sshc->sftp_session); - failf(data, "Could not open remote file for reading: %s", - sftp_libssh2_strerror(sftperr)); - myssh_to(data, sshc, SSH_SFTP_CLOSE); - return sftp_libssh2_error_to_CURLE(sftperr); - } - myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_STAT); - return CURLE_OK; -} - -static CURLcode ssh_state_scp_upload_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return CURLE_FAILED_INIT; - /* - * libssh2 requires that the destination path is a full path that - * includes the destination file and name OR ends in a "/" . If this is - * not done the destination file is named the same name as the last - * directory in the path. - */ - sshc->ssh_channel = - libssh2_scp_send64(sshc->ssh_session, sshp->path, - (int)data->set.new_file_perms, - (libssh2_int64_t)data->state.infilesize, 0, 0); - if(!sshc->ssh_channel) { - int ssh_err; - char *err_msg = NULL; - CURLcode result; - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - ssh_err = libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - failf(data, "%s", err_msg); - myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); - result = libssh2_session_error_to_CURLE(ssh_err); - - /* Map generic errors to upload failed */ - if(result == CURLE_SSH || - result == CURLE_REMOTE_FILE_NOT_FOUND) - result = CURLE_UPLOAD_FAILED; - return result; - } - - /* upload data */ - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - Curl_xfer_setup_send(data, FIRSTSOCKET); - - /* not set by Curl_xfer_setup to preserve io_flags */ - data->conn->recv_idx = FIRSTSOCKET; - - myssh_to(data, sshc, SSH_STOP); - - return CURLE_OK; -} - -static CURLcode ssh_state_session_disconnect(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - /* during weird times when we have been prematurely aborted, the channel - is still alive when we reach this state and we MUST kill the channel - properly first */ - int rc = 0; - if(sshc->ssh_channel) { - rc = libssh2_channel_free(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 scp subsystem: %d %s", rc, err_msg); - } - sshc->ssh_channel = NULL; - } - - if(sshc->ssh_session) { - rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown"); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to disconnect libssh2 session: %d %s", rc, err_msg); - } - } - - curlx_safefree(sshc->homedir); - - myssh_to(data, sshc, SSH_SESSION_FREE); - return CURLE_OK; -} - -static CURLcode sshc_cleanup(struct ssh_conn *sshc, struct Curl_easy *data, - bool block) -{ - int rc; - - if(sshc->kh) { - libssh2_knownhost_free(sshc->kh); - sshc->kh = NULL; - } - - if(sshc->ssh_agent) { - rc = libssh2_agent_disconnect(sshc->ssh_agent); - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to disconnect from libssh2 agent: %d %s", - rc, err_msg); - } - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; - - libssh2_agent_free(sshc->ssh_agent); - sshc->ssh_agent = NULL; - - /* NB: there is no need to free identities, they are part of internal - agent stuff */ - sshc->sshagent_identity = NULL; - sshc->sshagent_prev_identity = NULL; - } - - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg); - } - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; - - sshc->sftp_handle = NULL; - } - - if(sshc->ssh_channel) { - rc = libssh2_channel_free(sshc->ssh_channel); - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 scp subsystem: %d %s", rc, err_msg); - } - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; - - sshc->ssh_channel = NULL; - } - - if(sshc->sftp_session) { - rc = libssh2_sftp_shutdown(sshc->sftp_session); - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to stop libssh2 sftp subsystem: %d %s", rc, err_msg); - } - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; - - sshc->sftp_session = NULL; - } - - if(sshc->ssh_session) { - rc = libssh2_session_free(sshc->ssh_session); - if((rc < 0) && data) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 session: %d %s", rc, err_msg); - } - if(!block && (rc == LIBSSH2_ERROR_EAGAIN)) - return CURLE_AGAIN; - - sshc->ssh_session = NULL; - } - - /* worst-case scenario cleanup */ - DEBUGASSERT(sshc->ssh_session == NULL); - DEBUGASSERT(sshc->ssh_channel == NULL); - DEBUGASSERT(sshc->sftp_session == NULL); - DEBUGASSERT(sshc->sftp_handle == NULL); - DEBUGASSERT(sshc->kh == NULL); - DEBUGASSERT(sshc->ssh_agent == NULL); - - curlx_safefree(sshc->rsa_pub); - curlx_safefree(sshc->rsa); - curlx_safefree(sshc->quote_path1); - curlx_safefree(sshc->quote_path2); - curlx_safefree(sshc->homedir); - - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_getinfo(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(data->set.get_filetime) - myssh_to(data, sshc, SSH_SFTP_FILETIME); - else - myssh_to(data, sshc, SSH_SFTP_TRANS_INIT); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_filetime(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - LIBSSH2_SFTP_ATTRIBUTES attrs; - int rc; - - if(!sshp) - return CURLE_FAILED_INIT; - - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, - curlx_uztoui(strlen(sshp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - if(rc == 0) - data->info.filetime = (time_t)attrs.mtime; - - myssh_to(data, sshc, SSH_SFTP_TRANS_INIT); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_trans_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(data->state.upload) - myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); - else if(sshp) { - size_t plen = strlen(sshp->path); - if(plen && (sshp->path[plen - 1] == '/')) - myssh_to(data, sshc, SSH_SFTP_READDIR_INIT); - else - myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_INIT); - } - else - return CURLE_FAILED_INIT; - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_upload_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *block) -{ - CURLcode result; - if(!sshp) - return CURLE_FAILED_INIT; - result = sftp_upload_init(data, sshc, sshp, block); - if(result) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - } - return result; -} - -static CURLcode ssh_state_sftp_create_dirs_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return CURLE_FAILED_INIT; - if(strlen(sshp->path) > 1) { - sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */ - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS); - } - else - myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_create_dirs(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - if(!sshp) - return CURLE_FAILED_INIT; - sshc->slash_pos = strchr(sshc->slash_pos, '/'); - if(sshc->slash_pos) { - *sshc->slash_pos = 0; - infof(data, "Creating directory '%s'", sshp->path); - myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_MKDIR); - return CURLE_OK; - } - myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_readdir(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *block) -{ - CURLcode result; - if(!sshp) - return CURLE_FAILED_INIT; - result = sftp_readdir(data, sshc, sshp, block); - if(result) - myssh_to(data, sshc, SSH_SFTP_CLOSE); - return result; -} - -static CURLcode ssh_state_sftp_readdir_bottom(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - CURLcode result; - if(!sshp) - return CURLE_FAILED_INIT; - - result = curlx_dyn_addn(&sshp->readdir, "\n", 1); - if(!result) - result = Curl_client_write(data, CLIENTWRITE_BODY, - curlx_dyn_ptr(&sshp->readdir), - curlx_dyn_len(&sshp->readdir)); - if(result) { - curlx_dyn_free(&sshp->readdir); - myssh_to(data, sshc, SSH_STOP); - } - else { - curlx_dyn_reset(&sshp->readdir); - myssh_to(data, sshc, SSH_SFTP_READDIR); - } - return result; -} - -static CURLcode ssh_state_sftp_readdir_done(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(libssh2_sftp_closedir(sshc->sftp_handle) == - LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - - sshc->sftp_handle = NULL; - - /* no data to transfer */ - Curl_xfer_setup_nop(data); - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; -} - -static CURLcode ssh_state_sftp_download_stat(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *block) -{ - CURLcode result; - if(!sshp) - return CURLE_FAILED_INIT; - result = sftp_download_stat(data, sshc, sshp, block); - if(result) { - myssh_to(data, sshc, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - } - return result; -} - -static CURLcode ssh_state_scp_trans_init(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp) -{ - CURLcode result; - if(!sshp) - return CURLE_FAILED_INIT; - result = Curl_getworkingpath(data, sshc->homedir, - &sshp->path); - if(result) { - myssh_to(data, sshc, SSH_STOP); - return result; - } - - if(data->state.upload) { - if(data->state.infilesize < 0) { - failf(data, "SCP requires a known file size for upload"); - myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); - return CURLE_UPLOAD_FAILED; - } - myssh_to(data, sshc, SSH_SCP_UPLOAD_INIT); - } - else - myssh_to(data, sshc, SSH_SCP_DOWNLOAD_INIT); - return CURLE_OK; -} - -static CURLcode ssh_state_scp_done(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(data->state.upload) - myssh_to(data, sshc, SSH_SCP_SEND_EOF); - else - myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); - return CURLE_OK; -} - -static CURLcode ssh_state_scp_send_eof(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->ssh_channel) { - int rc = libssh2_channel_send_eof(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, - "Failed to send libssh2 channel EOF: %d %s", - rc, err_msg); - } - } - myssh_to(data, sshc, SSH_SCP_WAIT_EOF); - return CURLE_OK; -} - -static CURLcode ssh_state_scp_wait_eof(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->ssh_channel) { - int rc = libssh2_channel_wait_eof(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Failed to get channel EOF: %d %s", - rc, err_msg); - } - } - myssh_to(data, sshc, SSH_SCP_WAIT_CLOSE); - return CURLE_OK; -} - -static CURLcode ssh_state_scp_wait_close(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->ssh_channel) { - int rc = - libssh2_channel_wait_closed(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - if(rc) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "Channel failed to close: %d %s", - rc, err_msg); - } - } - myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE); - return CURLE_OK; -} - -static CURLcode ssh_state_scp_channel_free( - struct Curl_easy *data, - struct ssh_conn *sshc) -{ - if(sshc->ssh_channel) { - int rc = libssh2_channel_free(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - if(rc < 0) { - char *err_msg = NULL; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, - "Failed to free libssh2 scp subsystem: %d %s", - rc, err_msg); - } - sshc->ssh_channel = NULL; - } - CURL_TRC_SSH(data, "SCP DONE phase complete"); - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; -} - -static CURLcode ssh_state_session_free(struct Curl_easy *data, - struct ssh_conn *sshc) -{ - CURLcode result = sshc_cleanup(sshc, data, FALSE); - struct connectdata *conn = data->conn; - if(result) - return result; - memset(sshc, 0, sizeof(struct ssh_conn)); - connclose(conn, "SSH session free"); - sshc->state = SSH_SESSION_FREE; /* current */ - myssh_to(data, sshc, SSH_STOP); - return CURLE_OK; -} - -/* - * ssh_statemachine() runs the SSH state machine as far as it can without - * blocking and without reaching the end. The data the pointer 'block' points - * to is set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN - * meaning it wants to be called again when the socket is ready - */ -static CURLcode ssh_statemachine(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool *block) -{ - CURLcode result = CURLE_OK; - *block = 0; /* we are not blocking by default */ - - do { - switch(sshc->state) { - case SSH_INIT: - result = ssh_state_init(data, sshc); - if(result) - break; - FALLTHROUGH(); - - case SSH_S_STARTUP: - result = ssh_state_startup(data, sshc); - if(result) - break; - FALLTHROUGH(); - - case SSH_HOSTKEY: - result = ssh_state_hostkey(data, sshc); - break; - - case SSH_AUTHLIST: - result = ssh_state_authlist(data, sshc); - break; - - case SSH_AUTH_PKEY_INIT: - result = ssh_state_pkey_init(data, sshc); - break; - - case SSH_AUTH_PKEY: - result = ssh_state_auth_pkey(data, sshc); - break; - - case SSH_AUTH_PASS_INIT: - result = ssh_state_auth_pass_init(data, sshc); - break; - - case SSH_AUTH_PASS: - result = ssh_state_auth_pass(data, sshc); - break; - - case SSH_AUTH_HOST_INIT: - result = ssh_state_auth_host_init(data, sshc); - break; - - case SSH_AUTH_HOST: - myssh_to(data, sshc, SSH_AUTH_AGENT_INIT); - break; - - case SSH_AUTH_AGENT_INIT: - result = ssh_state_auth_agent_init(data, sshc); - break; - - case SSH_AUTH_AGENT_LIST: - result = ssh_state_auth_agent_list(data, sshc); - break; - - case SSH_AUTH_AGENT: - result = ssh_state_auth_agent(data, sshc); - break; - - case SSH_AUTH_KEY_INIT: - result = ssh_state_auth_key_init(data, sshc); - break; - - case SSH_AUTH_KEY: - result = ssh_state_auth_key(data, sshc); - break; - - case SSH_AUTH_DONE: - result = ssh_state_auth_done(data, sshc); - break; - - case SSH_SFTP_INIT: - result = ssh_state_sftp_init(data, sshc); - break; - - case SSH_SFTP_REALPATH: - result = ssh_state_sftp_realpath(data, sshc, sshp); - break; - - case SSH_SFTP_QUOTE_INIT: - result = ssh_state_sftp_quote_init(data, sshc, sshp); - break; - - case SSH_SFTP_POSTQUOTE_INIT: - result = ssh_state_sftp_postquote_init(data, sshc); - break; - - case SSH_SFTP_QUOTE: - result = ssh_state_sftp_quote(data, sshc, sshp); - break; - - case SSH_SFTP_NEXT_QUOTE: - result = ssh_state_sftp_next_quote(data, sshc); - break; - - case SSH_SFTP_QUOTE_STAT: - result = ssh_state_sftp_quote_stat(data, sshc, sshp, block); - break; - - case SSH_SFTP_QUOTE_SETSTAT: - result = ssh_state_sftp_quote_setstat(data, sshc, sshp); - break; - - case SSH_SFTP_QUOTE_SYMLINK: - result = ssh_state_sftp_quote_symlink(data, sshc); - break; - - case SSH_SFTP_QUOTE_MKDIR: - result = ssh_state_sftp_quote_mkdir(data, sshc); - break; - - case SSH_SFTP_QUOTE_RENAME: - result = ssh_state_sftp_quote_rename(data, sshc); - break; - - case SSH_SFTP_QUOTE_RMDIR: - result = ssh_state_sftp_quote_rmdir(data, sshc); - break; - - case SSH_SFTP_QUOTE_UNLINK: - result = ssh_state_sftp_quote_unlink(data, sshc); - break; - - case SSH_SFTP_QUOTE_STATVFS: - result = ssh_state_sftp_quote_statvfs(data, sshc); - break; - - case SSH_SFTP_GETINFO: - result = ssh_state_sftp_getinfo(data, sshc); - break; - - case SSH_SFTP_FILETIME: - result = ssh_state_sftp_filetime(data, sshc, sshp); - break; - - case SSH_SFTP_TRANS_INIT: - result = ssh_state_sftp_trans_init(data, sshc, sshp); - break; - - case SSH_SFTP_UPLOAD_INIT: - result = ssh_state_sftp_upload_init(data, sshc, sshp, block); - break; - - case SSH_SFTP_CREATE_DIRS_INIT: - result = ssh_state_sftp_create_dirs_init(data, sshc, sshp); - break; - - case SSH_SFTP_CREATE_DIRS: - result = ssh_state_sftp_create_dirs(data, sshc, sshp); - break; - - case SSH_SFTP_CREATE_DIRS_MKDIR: - result = ssh_state_sftp_create_dirs_mkdir(data, sshc, sshp); - break; - - case SSH_SFTP_READDIR_INIT: - result = ssh_state_sftp_readdir_init(data, sshc, sshp); - break; - - case SSH_SFTP_READDIR: - result = ssh_state_sftp_readdir(data, sshc, sshp, block); - break; - - case SSH_SFTP_READDIR_LINK: - result = ssh_state_sftp_readdir_link(data, sshc, sshp); - break; - - case SSH_SFTP_READDIR_BOTTOM: - result = ssh_state_sftp_readdir_bottom(data, sshc, sshp); - break; - - case SSH_SFTP_READDIR_DONE: - result = ssh_state_sftp_readdir_done(data, sshc); - break; - - case SSH_SFTP_DOWNLOAD_INIT: - result = ssh_state_sftp_download_init(data, sshc, sshp); - break; - - case SSH_SFTP_DOWNLOAD_STAT: - result = ssh_state_sftp_download_stat(data, sshc, sshp, block); - break; - - case SSH_SFTP_CLOSE: - result = ssh_state_sftp_close(data, sshc, sshp); - break; - - case SSH_SFTP_SHUTDOWN: - result = ssh_state_sftp_shutdown(data, sshc); - break; - - case SSH_SCP_TRANS_INIT: - result = ssh_state_scp_trans_init(data, sshc, sshp); - break; - - case SSH_SCP_UPLOAD_INIT: - result = ssh_state_scp_upload_init(data, sshc, sshp); - break; - - case SSH_SCP_DOWNLOAD_INIT: - result = ssh_state_scp_download_init(data, sshc, sshp); - break; - - case SSH_SCP_DONE: - result = ssh_state_scp_done(data, sshc); - break; - - case SSH_SCP_SEND_EOF: - result = ssh_state_scp_send_eof(data, sshc); - break; - - case SSH_SCP_WAIT_EOF: - result = ssh_state_scp_wait_eof(data, sshc); - break; - - case SSH_SCP_WAIT_CLOSE: - result = ssh_state_scp_wait_close(data, sshc); - break; - - case SSH_SCP_CHANNEL_FREE: - result = ssh_state_scp_channel_free(data, sshc); - break; - - case SSH_SESSION_DISCONNECT: - result = ssh_state_session_disconnect(data, sshc); - break; - - case SSH_SESSION_FREE: - result = ssh_state_session_free(data, sshc); - break; - - case SSH_QUIT: - default: - /* internal error */ - myssh_to(data, sshc, SSH_STOP); - break; - } - - } while(!result && (sshc->state != SSH_STOP) && !*block); - - if(result == CURLE_AGAIN) { - /* we would block, we need to wait for the socket to be ready (in the - right direction too)! */ - *block = TRUE; - result = CURLE_OK; - } - CURL_TRC_SSH(data, "[%s] statemachine() -> %d, block=%d", - Curl_ssh_statename(sshc->state), result, *block); - - return result; -} - -/* called by the multi interface to figure out what socket(s) to wait for and - for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static CURLcode ssh_pollset(struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int waitfor; - - if(!sshc || (sock == CURL_SOCKET_BAD)) - return CURLE_FAILED_INIT; - - waitfor = sshc->waitfor ? sshc->waitfor : data->req.io_flags; - if(waitfor) { - int flags = 0; - if(waitfor & REQ_IO_RECV) - flags |= CURL_POLL_IN; - if(waitfor & REQ_IO_SEND) - flags |= CURL_POLL_OUT; - DEBUGASSERT(flags); - CURL_TRC_SSH(data, "pollset, flags=%x", flags); - return Curl_pollset_change(data, ps, sock, flags, 0); - } - /* While we still have a session, we listen incoming data. */ - if(sshc->ssh_session) - return Curl_pollset_change(data, ps, sock, CURL_POLL_IN, 0); - return CURLE_OK; -} - -/* - * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this - * function is used to figure out in what direction and stores this info so - * that the multi interface can take advantage of it. Make sure to call this - * function in all cases so that when it _does not_ return EAGAIN we can - * restore the default wait bits. - */ -static void ssh_block2waitfor(struct Curl_easy *data, - struct ssh_conn *sshc, - bool block) -{ - int dir = 0; - (void)data; - if(block) { - dir = libssh2_session_block_directions(sshc->ssh_session); - if(dir) { - /* translate the libssh2 define bits into our own bit defines */ - sshc->waitfor = - ((dir & LIBSSH2_SESSION_BLOCK_INBOUND) ? REQ_IO_RECV : 0) | - ((dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) ? REQ_IO_SEND : 0); - } - } - if(!dir) - sshc->waitfor = 0; -} - -/* called repeatedly until done from multi.c */ -static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - CURLcode result = CURLE_OK; - bool block; /* we store the status and use that to provide a ssh_pollset() - implementation */ - if(!sshc || !sshp) - return CURLE_FAILED_INIT; - - do { - result = ssh_statemachine(data, sshc, sshp, &block); - *done = (sshc->state == SSH_STOP); - /* if there is no error, it is not done and it did not EWOULDBLOCK, then - try again */ - } while(!result && !*done && !block); - ssh_block2waitfor(data, sshc, block); - - return result; -} - -static CURLcode ssh_block_statemach(struct Curl_easy *data, - struct ssh_conn *sshc, - struct SSHPROTO *sshp, - bool disconnect) -{ - CURLcode result = CURLE_OK; - struct curltime start = *Curl_pgrs_now(data); - - while((sshc->state != SSH_STOP) && !result) { - bool block; - timediff_t left_ms = 1000; - - result = ssh_statemachine(data, sshc, sshp, &block); - if(result) - break; - - if(!disconnect) { - result = Curl_pgrsCheck(data); - if(result) - break; - - left_ms = Curl_timeleft_ms(data); - if(left_ms < 0) { - failf(data, "Operation timed out"); - return CURLE_OPERATION_TIMEDOUT; - } - } - else if(curlx_ptimediff_ms(Curl_pgrs_now(data), &start) > 1000) { - /* disconnect timeout */ - failf(data, "Disconnect timed out"); - result = CURLE_OK; - break; - } - - if(block) { - int dir = libssh2_session_block_directions(sshc->ssh_session); - curl_socket_t sock = data->conn->sock[FIRSTSOCKET]; - curl_socket_t fd_read = CURL_SOCKET_BAD; - curl_socket_t fd_write = CURL_SOCKET_BAD; - if(LIBSSH2_SESSION_BLOCK_INBOUND & dir) - fd_read = sock; - if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) - fd_write = sock; - /* wait for the socket to become ready */ - (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, - left_ms > 1000 ? 1000 : left_ms); - } - } - - return result; -} - -static void myssh_easy_dtor(void *key, size_t klen, void *entry) -{ - struct SSHPROTO *sshp = entry; - (void)key; - (void)klen; - curlx_safefree(sshp->path); - curlx_dyn_free(&sshp->readdir); - curlx_dyn_free(&sshp->readdir_link); - curlx_free(sshp); -} - -static void myssh_conn_dtor(void *key, size_t klen, void *entry) -{ - struct ssh_conn *sshc = entry; - (void)key; - (void)klen; - sshc_cleanup(sshc, NULL, TRUE); - curlx_free(sshc); -} - -/* - * SSH setup and connection - */ -static CURLcode ssh_setup_connection(struct Curl_easy *data, - struct connectdata *conn) -{ - struct ssh_conn *sshc; - struct SSHPROTO *sshp; - (void)conn; - - sshc = curlx_calloc(1, sizeof(*sshc)); - if(!sshc) - return CURLE_OUT_OF_MEMORY; - - if(Curl_conn_meta_set(conn, CURL_META_SSH_CONN, sshc, myssh_conn_dtor)) - return CURLE_OUT_OF_MEMORY; - - sshp = curlx_calloc(1, sizeof(*sshp)); - if(!sshp) - return CURLE_OUT_OF_MEMORY; - - curlx_dyn_init(&sshp->readdir, CURL_PATH_MAX * 2); - curlx_dyn_init(&sshp->readdir_link, CURL_PATH_MAX); - if(Curl_meta_set(data, CURL_META_SSH_EASY, sshp, myssh_easy_dtor)) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static Curl_recv scp_recv, sftp_recv; -static Curl_send scp_send, sftp_send; - -#ifndef CURL_DISABLE_PROXY -static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer, - size_t length, int flags, void **abstract) -{ - struct Curl_easy *data = (struct Curl_easy *)*abstract; - int sockindex = Curl_conn_sockindex(data, sock); - size_t nread; - CURLcode result; - struct connectdata *conn = data->conn; - Curl_recv *backup = conn->recv[sockindex]; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - (void)flags; - - if(!sshc) - return -1; - - /* swap in the TLS reader function for this call only, and then swap back - the SSH one again */ - conn->recv[sockindex] = sshc->tls_recv; - result = Curl_conn_recv(data, sockindex, buffer, length, &nread); - conn->recv[sockindex] = backup; - if(result == CURLE_AGAIN) - return -EAGAIN; /* magic return code for libssh2 */ - else if(result) - return -1; /* generic error */ - Curl_debug(data, CURLINFO_DATA_IN, (const char *)buffer, nread); - return (ssize_t)nread; -} - -static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, - size_t length, int flags, void **abstract) -{ - struct Curl_easy *data = (struct Curl_easy *)*abstract; - int sockindex = Curl_conn_sockindex(data, sock); - size_t nwrite; - CURLcode result; - struct connectdata *conn = data->conn; - Curl_send *backup = conn->send[sockindex]; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - (void)flags; - - if(!sshc) - return -1; - - /* swap in the TLS writer function for this call only, and then swap back - the SSH one again */ - conn->send[sockindex] = sshc->tls_send; - result = Curl_conn_send(data, sockindex, buffer, length, FALSE, &nwrite); - conn->send[sockindex] = backup; - if(result == CURLE_AGAIN) - return -EAGAIN; /* magic return code for libssh2 */ - else if(result) - return -1; /* error */ - Curl_debug(data, CURLINFO_DATA_OUT, (const char *)buffer, nwrite); - return (ssize_t)nwrite; -} -#endif - -/* - * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. - */ -static CURLcode ssh_connect(struct Curl_easy *data, bool *done) -{ -#ifdef CURL_LIBSSH2_DEBUG - curl_socket_t sock; -#endif - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - CURLcode result; - -#if LIBSSH2_VERSION_NUM >= 0x010b00 - { - const char *crypto_str; - switch(libssh2_crypto_engine()) { - case libssh2_gcrypt: - crypto_str = "libgcrypt"; - break; - case libssh2_mbedtls: - crypto_str = "mbedTLS"; - break; - case libssh2_openssl: - crypto_str = "openssl compatible"; - break; - case libssh2_os400qc3: - crypto_str = "OS400QC3"; - break; - case libssh2_wincng: - crypto_str = "WinCNG"; - break; - default: - crypto_str = NULL; - break; - } - if(crypto_str) - infof(data, "libssh2 cryptography backend: %s", crypto_str); - } -#endif - - if(!sshc) - return CURLE_FAILED_INIT; - - infof(data, "User: '%s'", conn->user); -#ifdef CURL_LIBSSH2_DEBUG - infof(data, "Password: %s", conn->passwd); - sock = conn->sock[FIRSTSOCKET]; -#endif /* CURL_LIBSSH2_DEBUG */ - - /* libcurl MUST to set custom memory functions so that the kbd_callback - function's memory allocations can be properly freed */ - sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, - my_libssh2_free, - my_libssh2_realloc, data); - - if(!sshc->ssh_session) { - failf(data, "Failure initialising ssh session"); - return CURLE_FAILED_INIT; - } - - /* Set the packet read timeout if the libssh2 version supports it */ -#if LIBSSH2_VERSION_NUM >= 0x010B00 - if(data->set.server_response_timeout > 0) { - libssh2_session_set_read_timeout(sshc->ssh_session, - (long)(data->set.server_response_timeout / 1000)); - } -#endif - -#ifndef CURL_DISABLE_PROXY - if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) { - /* - Setup libssh2 callbacks to make it read/write TLS from the socket. - - ssize_t - recvcb(libssh2_socket_t sock, void *buffer, size_t length, - int flags, void **abstract); - - ssize_t - sendcb(libssh2_socket_t sock, const void *buffer, size_t length, - int flags, void **abstract); - - */ -#if LIBSSH2_VERSION_NUM >= 0x010b01 - infof(data, "Uses HTTPS proxy"); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - libssh2_session_callback_set2(sshc->ssh_session, - LIBSSH2_CALLBACK_RECV, - (libssh2_cb_generic *)ssh_tls_recv); - libssh2_session_callback_set2(sshc->ssh_session, - LIBSSH2_CALLBACK_SEND, - (libssh2_cb_generic *)ssh_tls_send); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif -#else - /* - * This crazy union dance is here to avoid assigning a void pointer a - * function pointer as it is invalid C. The problem is of course that - * libssh2 has such an API... - */ - union receive { - void *recvp; - ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **); - }; - union transfer { - void *sendp; - ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **); - }; - union receive sshrecv; - union transfer sshsend; - - sshrecv.recvptr = ssh_tls_recv; - sshsend.sendptr = ssh_tls_send; - - infof(data, "Uses HTTPS proxy"); - libssh2_session_callback_set(sshc->ssh_session, - LIBSSH2_CALLBACK_RECV, sshrecv.recvp); - libssh2_session_callback_set(sshc->ssh_session, - LIBSSH2_CALLBACK_SEND, sshsend.sendp); -#endif - - /* Store the underlying TLS recv/send function pointers to be used when - reading from the proxy */ - sshc->tls_recv = conn->recv[FIRSTSOCKET]; - sshc->tls_send = conn->send[FIRSTSOCKET]; - } - -#endif /* CURL_DISABLE_PROXY */ - if(conn->scheme->protocol & CURLPROTO_SCP) { - conn->recv[FIRSTSOCKET] = scp_recv; - conn->send[FIRSTSOCKET] = scp_send; - } - else { - conn->recv[FIRSTSOCKET] = sftp_recv; - conn->send[FIRSTSOCKET] = sftp_send; - } - - if(data->set.ssh_compression && - libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) { - infof(data, "Failed to enable compression for ssh session"); - } - - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - int rc; - sshc->kh = libssh2_knownhost_init(sshc->ssh_session); - if(!sshc->kh) { - libssh2_session_free(sshc->ssh_session); - sshc->ssh_session = NULL; - return CURLE_FAILED_INIT; - } - - /* read all known hosts from there */ - rc = libssh2_knownhost_readfile(sshc->kh, - data->set.str[STRING_SSH_KNOWNHOSTS], - LIBSSH2_KNOWNHOST_FILE_OPENSSH); - if(rc < 0) - infof(data, "Failed to read known hosts from %s", - data->set.str[STRING_SSH_KNOWNHOSTS]); - } - -#ifdef CURL_LIBSSH2_DEBUG - libssh2_trace(sshc->ssh_session, ~0); - infof(data, "SSH socket: %d", (int)sock); -#endif /* CURL_LIBSSH2_DEBUG */ - - myssh_to(data, sshc, SSH_INIT); - - result = ssh_multi_statemach(data, done); - - return result; -} - -/* - *********************************************************************** - * - * scp_perform() - * - * This is the actual DO function for SCP. Get a file according to - * the options previously setup. - */ - -static CURLcode scp_perform(struct Curl_easy *data, - bool *connected, - bool *dophase_done) -{ - struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - CURLcode result = CURLE_OK; - - CURL_TRC_SSH(data, "DO phase starts"); - - *dophase_done = FALSE; /* not done yet */ - if(!sshc) - return CURLE_FAILED_INIT; - - /* start the first command in the DO phase */ - myssh_to(data, sshc, SSH_SCP_TRANS_INIT); - - /* run the state-machine */ - result = ssh_multi_statemach(data, dophase_done); - - *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); - - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode scp_doing(struct Curl_easy *data, - bool *dophase_done) -{ - CURLcode result; - result = ssh_multi_statemach(data, dophase_done); - - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode scp_disconnect(struct Curl_easy *data, - struct connectdata *conn, - bool dead_connection) -{ - CURLcode result = CURLE_OK; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - (void)dead_connection; - - if(sshc && sshc->ssh_session) { - /* only if there is a session still around to use! */ - myssh_to(data, sshc, SSH_SESSION_DISCONNECT); - result = ssh_block_statemach(data, sshc, sshp, TRUE); - } - - if(sshc) - return sshc_cleanup(sshc, data, TRUE); - return result; -} - -/* generic done function for both SCP and SFTP called from their specific - done functions */ -static CURLcode ssh_done(struct Curl_easy *data, CURLcode status) -{ - struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - CURLcode result = CURLE_OK; - - if(!sshc || !sshp) - return CURLE_FAILED_INIT; - - if(!status) - /* run the state-machine */ - result = ssh_block_statemach(data, sshc, sshp, FALSE); - else - result = status; - - if(Curl_pgrsDone(data)) - return CURLE_ABORTED_BY_CALLBACK; - - CURL_REQ_CLEAR_IO(data); - return result; -} - -static CURLcode scp_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - (void)premature; - - if(sshc && !status) - myssh_to(data, sshc, SSH_SCP_DONE); - - return ssh_done(data, status); -} - -static CURLcode scp_send(struct Curl_easy *data, int sockindex, - const uint8_t *mem, size_t len, bool eos, - size_t *pnwritten) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - CURLcode result = CURLE_OK; - ssize_t nwritten; - - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - (void)eos; - *pnwritten = 0; - - if(!sshc) - return CURLE_FAILED_INIT; - - /* libssh2_channel_write() returns int! */ - nwritten = (ssize_t)libssh2_channel_write(sshc->ssh_channel, - (const char *)mem, len); - - ssh_block2waitfor(data, sshc, (nwritten == LIBSSH2_ERROR_EAGAIN)); - - if(nwritten == LIBSSH2_ERROR_EAGAIN) - result = CURLE_AGAIN; - else if(nwritten < LIBSSH2_ERROR_NONE) - result = libssh2_session_error_to_CURLE((int)nwritten); - else - *pnwritten = (size_t)nwritten; - - return result; -} - -static CURLcode scp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, size_t *pnread) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - CURLcode result = CURLE_OK; - ssize_t nread; - - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - *pnread = 0; - - if(!sshc) - return CURLE_FAILED_INIT; - - /* libssh2_channel_read() returns int */ - nread = (ssize_t)libssh2_channel_read(sshc->ssh_channel, mem, len); - - ssh_block2waitfor(data, sshc, (nread == LIBSSH2_ERROR_EAGAIN)); - if(nread == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - else if(nread < LIBSSH2_ERROR_NONE) - result = libssh2_session_error_to_CURLE((int)nread); - else - *pnread = (size_t)nread; - - return result; -} - -/* - * =============== SFTP =============== - */ - -/* - *********************************************************************** - * - * sftp_perform() - * - * This is the actual DO function for SFTP. Get a file/directory according to - * the options previously setup. - */ - -static CURLcode sftp_perform(struct Curl_easy *data, - bool *connected, - bool *dophase_done) -{ - struct ssh_conn *sshc = Curl_conn_meta_get(data->conn, CURL_META_SSH_CONN); - CURLcode result = CURLE_OK; - - CURL_TRC_SSH(data, "DO phase starts"); - - *dophase_done = FALSE; /* not done yet */ - if(!sshc) - return CURLE_FAILED_INIT; - - /* start the first command in the DO phase */ - myssh_to(data, sshc, SSH_SFTP_QUOTE_INIT); - - /* run the state-machine */ - result = ssh_multi_statemach(data, dophase_done); - - *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET); - - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode sftp_doing(struct Curl_easy *data, - bool *dophase_done) -{ - CURLcode result = ssh_multi_statemach(data, dophase_done); - - if(*dophase_done) { - CURL_TRC_SSH(data, "DO phase is complete"); - } - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode sftp_disconnect(struct Curl_easy *data, - struct connectdata *conn, bool dead_connection) -{ - CURLcode result = CURLE_OK; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - struct SSHPROTO *sshp = Curl_meta_get(data, CURL_META_SSH_EASY); - (void)dead_connection; - - if(sshc) { - if(sshc->ssh_session) { - /* only if there is a session still around to use! */ - CURL_TRC_SSH(data, "DISCONNECT starts now"); - myssh_to(data, sshc, SSH_SFTP_SHUTDOWN); - result = ssh_block_statemach(data, sshc, sshp, TRUE); - CURL_TRC_SSH(data, "DISCONNECT is done -> %d", result); - } - sshc_cleanup(sshc, data, TRUE); - } - return result; -} - -static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, - bool premature) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - - if(!sshc) - return CURLE_FAILED_INIT; - - if(!status) { - /* Post quote commands are executed after the SFTP_CLOSE state to avoid - errors that could happen due to open file handles during POSTQUOTE - operation */ - if(!premature && data->set.postquote && !conn->bits.retry) - sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - myssh_to(data, sshc, SSH_SFTP_CLOSE); - } - return ssh_done(data, status); -} - -/* return number of sent bytes */ -static CURLcode sftp_send(struct Curl_easy *data, int sockindex, - const uint8_t *mem, size_t len, bool eos, - size_t *pnwritten) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - ssize_t nwrite; - - (void)sockindex; - (void)eos; - *pnwritten = 0; - - if(!sshc) - return CURLE_FAILED_INIT; - - nwrite = libssh2_sftp_write(sshc->sftp_handle, (const char *)mem, len); - - ssh_block2waitfor(data, sshc, (nwrite == LIBSSH2_ERROR_EAGAIN)); - - if(nwrite == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - else if(nwrite < LIBSSH2_ERROR_NONE) - return libssh2_session_error_to_CURLE((int)nwrite); - *pnwritten = (size_t)nwrite; - return CURLE_OK; -} - -/* - * Return number of received (decrypted) bytes - * or <0 on error - */ -static CURLcode sftp_recv(struct Curl_easy *data, int sockindex, - char *mem, size_t len, size_t *pnread) -{ - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - ssize_t nread; - - (void)sockindex; - *pnread = 0; - - if(!sshc) - return CURLE_FAILED_INIT; - - nread = libssh2_sftp_read(sshc->sftp_handle, mem, len); - - ssh_block2waitfor(data, sshc, (nread == LIBSSH2_ERROR_EAGAIN)); - - if(nread == LIBSSH2_ERROR_EAGAIN) - return CURLE_AGAIN; - else if(nread < 0) - return libssh2_session_error_to_CURLE((int)nread); - - *pnread = (size_t)nread; - return CURLE_OK; -} - -/* - * The DO function is generic for both protocols. There was previously two - * separate ones but this way means less duplicated code. - */ -static CURLcode ssh_do(struct Curl_easy *data, bool *done) -{ - CURLcode result; - bool connected = FALSE; - struct connectdata *conn = data->conn; - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - - *done = FALSE; /* default to false */ - if(!sshc) - return CURLE_FAILED_INIT; - - data->req.size = -1; /* make sure this is unknown at this point */ - sshc->secondCreateDirs = 0; /* reset the create directory attempt state - variable */ - - Curl_pgrsReset(data); - - if(conn->scheme->protocol & CURLPROTO_SCP) - result = scp_perform(data, &connected, done); - else - result = sftp_perform(data, &connected, done); - - return result; -} - -CURLcode Curl_ssh_init(void) -{ - if(libssh2_init(0)) { - DEBUGF(curl_mfprintf(stderr, "Error: libssh2_init failed\n")); - return CURLE_FAILED_INIT; - } - return CURLE_OK; -} - -void Curl_ssh_cleanup(void) -{ - libssh2_exit(); -} - -void Curl_ssh_version(char *buffer, size_t buflen) -{ - (void)curl_msnprintf(buffer, buflen, "libssh2/%s", libssh2_version(0)); -} - -/* The SSH session is associated with the *CONNECTION* but the callback user - * pointer is an easy handle pointer. This function allows us to reassign the - * user pointer to the *CURRENT* (new) easy handle. - */ -static void ssh_attach(struct Curl_easy *data, struct connectdata *conn) -{ - DEBUGASSERT(data); - DEBUGASSERT(conn); - if(conn->scheme->protocol & PROTO_FAMILY_SSH) { - struct ssh_conn *sshc = Curl_conn_meta_get(conn, CURL_META_SSH_CONN); - if(sshc && sshc->ssh_session) { - /* only re-attach if the session already exists */ - void **abstract = libssh2_session_abstract(sshc->ssh_session); - *abstract = data; - } - } -} - -/* - * SCP protocol handler. - */ -const struct Curl_protocol Curl_protocol_scp = { - ssh_setup_connection, /* setup_connection */ - ssh_do, /* do_it */ - scp_done, /* done */ - ZERO_NULL, /* do_more */ - ssh_connect, /* connect_it */ - ssh_multi_statemach, /* connecting */ - scp_doing, /* doing */ - ssh_pollset, /* proto_pollset */ - ssh_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ssh_pollset, /* perform_pollset */ - scp_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ssh_attach, /* attach */ - ZERO_NULL, /* follow */ -}; - -/* - * SFTP protocol handler. - */ -const struct Curl_protocol Curl_protocol_sftp = { - ssh_setup_connection, /* setup_connection */ - ssh_do, /* do_it */ - sftp_done, /* done */ - ZERO_NULL, /* do_more */ - ssh_connect, /* connect_it */ - ssh_multi_statemach, /* connecting */ - sftp_doing, /* doing */ - ssh_pollset, /* proto_pollset */ - ssh_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - ssh_pollset, /* perform_pollset */ - sftp_disconnect, /* disconnect */ - ZERO_NULL, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ssh_attach, /* attach */ - ZERO_NULL, /* follow */ -}; - -#endif /* USE_LIBSSH2 */ diff --git a/vendor/curl/lib/vssh/ssh.h b/vendor/curl/lib/vssh/ssh.h deleted file mode 100644 index 44e72ab80..000000000 --- a/vendor/curl/lib/vssh/ssh.h +++ /dev/null @@ -1,262 +0,0 @@ -#ifndef HEADER_CURL_VSSH_SSH_H -#define HEADER_CURL_VSSH_SSH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" - -extern const struct Curl_protocol Curl_protocol_sftp; -extern const struct Curl_protocol Curl_protocol_scp; - -#ifdef USE_SSH - -#ifdef USE_LIBSSH2 -#include -#include -#elif defined(USE_LIBSSH) -/* in 0.10.0 or later, ignore deprecated warnings */ -#define SSH_SUPPRESS_DEPRECATED -#include -#include -#endif - -/* meta key for storing protocol meta at easy handle */ -#define CURL_META_SSH_EASY "meta:proto:ssh:easy" -/* meta key for storing protocol meta at connection */ -#define CURL_META_SSH_CONN "meta:proto:ssh:conn" - -/**************************************************************************** - * SSH unique setup - ***************************************************************************/ -typedef enum { - SSH_NO_STATE = -1, /* Used for "nextState" so say there is none */ - SSH_STOP = 0, /* do nothing state, stops the state machine */ - - SSH_INIT, /* First state in SSH-CONNECT */ - SSH_S_STARTUP, /* Session startup */ - SSH_HOSTKEY, /* verify hostkey */ - SSH_AUTHLIST, - SSH_AUTH_PKEY_INIT, - SSH_AUTH_PKEY, - SSH_AUTH_PASS_INIT, - SSH_AUTH_PASS, - SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */ - SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */ - SSH_AUTH_AGENT, /* attempt one key at a time */ - SSH_AUTH_HOST_INIT, - SSH_AUTH_HOST, - SSH_AUTH_KEY_INIT, - SSH_AUTH_KEY, - SSH_AUTH_GSSAPI, - SSH_AUTH_DONE, - SSH_SFTP_INIT, - SSH_SFTP_REALPATH, /* Last state in SSH-CONNECT */ - - SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */ - SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */ - SSH_SFTP_QUOTE, - SSH_SFTP_NEXT_QUOTE, - SSH_SFTP_QUOTE_STAT, - SSH_SFTP_QUOTE_SETSTAT, - SSH_SFTP_QUOTE_SYMLINK, - SSH_SFTP_QUOTE_MKDIR, - SSH_SFTP_QUOTE_RENAME, - SSH_SFTP_QUOTE_RMDIR, - SSH_SFTP_QUOTE_UNLINK, - SSH_SFTP_QUOTE_STATVFS, - SSH_SFTP_GETINFO, - SSH_SFTP_FILETIME, - SSH_SFTP_TRANS_INIT, - SSH_SFTP_UPLOAD_INIT, - SSH_SFTP_CREATE_DIRS_INIT, - SSH_SFTP_CREATE_DIRS, - SSH_SFTP_CREATE_DIRS_MKDIR, - SSH_SFTP_READDIR_INIT, - SSH_SFTP_READDIR, - SSH_SFTP_READDIR_LINK, - SSH_SFTP_READDIR_BOTTOM, - SSH_SFTP_READDIR_DONE, - SSH_SFTP_DOWNLOAD_INIT, - SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */ - SSH_SFTP_CLOSE, /* Last state in SFTP-DONE */ - SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */ - SSH_SCP_TRANS_INIT, /* First state in SCP-DO */ - SSH_SCP_UPLOAD_INIT, - SSH_SCP_DOWNLOAD_INIT, - SSH_SCP_DOWNLOAD, - SSH_SCP_DONE, - SSH_SCP_SEND_EOF, - SSH_SCP_WAIT_EOF, - SSH_SCP_WAIT_CLOSE, - SSH_SCP_CHANNEL_FREE, /* Last state in SCP-DONE */ - SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */ - SSH_SESSION_FREE, /* Last state in SCP/SFTP-DISCONNECT */ - SSH_QUIT, - SSH_LAST /* never used */ -} sshstate; - -#define CURL_PATH_MAX 1024 - -/* this struct is used in the HandleData struct which is part of the - Curl_easy, which means this is used on a per-easy handle basis. - Everything that is strictly related to a connection is banned from this - struct. */ -struct SSHPROTO { - char *path; /* the path we operate on, at least one byte long */ -#ifdef USE_LIBSSH2 - struct dynbuf readdir_link; - struct dynbuf readdir; - char readdir_filename[CURL_PATH_MAX + 1]; - char readdir_longentry[CURL_PATH_MAX + 1]; - - LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */ - - /* Here's a set of struct members used by the SFTP_READDIR state */ - LIBSSH2_SFTP_ATTRIBUTES readdir_attrs; -#endif -}; - -/* ssh_conn is used for struct connection-oriented data in the connectdata - struct */ -struct ssh_conn { - const char *authlist; /* List of auth. methods, managed by libssh2 */ - - /* common */ - const char *passphrase; /* pass-phrase to use */ - char *rsa_pub; /* strdup'ed public key file */ - char *rsa; /* strdup'ed private key file */ - sshstate state; /* always use ssh.c:state() to change state! */ - sshstate nextstate; /* the state to goto after stopping */ - struct curl_slist *quote_item; /* for the quote option */ - char *quote_path1; /* two generic pointers for the QUOTE stuff */ - char *quote_path2; - - char *homedir; /* when doing SFTP we figure out home directory - in the connect phase */ - /* end of READDIR stuff */ - - int secondCreateDirs; /* counter use by the code to see if the - second attempt has been made to change - to/create a directory */ - int waitfor; /* REQ_IO_RECV/REQ_IO_SEND bits overriding - pollset given flags */ - char *slash_pos; /* used by the SFTP_CREATE_DIRS state */ - -#ifdef USE_LIBSSH - CURLcode actualcode; /* the actual error code */ - char *readdir_linkPath; - size_t readdir_len; - struct dynbuf readdir_buf; -/* our variables */ - unsigned kbd_state; /* 0 or 1 */ - ssh_key privkey; - ssh_key pubkey; - unsigned int auth_methods; - ssh_session ssh_session; - ssh_scp scp_session; - sftp_session sftp_session; - sftp_file sftp_file; - sftp_dir sftp_dir; - - unsigned sftp_recv_state; /* 0 or 1 */ -#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0) - sftp_aio sftp_recv_aio; - - sftp_aio sftp_send_aio; - unsigned sftp_send_state; /* 0 or 1 */ -#else - int sftp_file_index; /* for async read */ -#endif - sftp_attributes readdir_attrs; /* used by the SFTP readdir actions */ - sftp_attributes readdir_link_attrs; /* used by the SFTP readdir actions */ - sftp_attributes quote_attrs; /* used by the SFTP_QUOTE state */ - - const char *readdir_filename; /* points within readdir_attrs */ - const char *readdir_longentry; - char *readdir_tmp; - BIT(initialised); -#elif defined(USE_LIBSSH2) - LIBSSH2_SESSION *ssh_session; /* Secure Shell session */ - LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */ - LIBSSH2_SFTP *sftp_session; /* SFTP handle */ - LIBSSH2_SFTP_HANDLE *sftp_handle; - -#ifndef CURL_DISABLE_PROXY - /* for HTTPS proxy storage */ - Curl_recv *tls_recv; - Curl_send *tls_send; -#endif - - LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */ - struct libssh2_agent_publickey *sshagent_identity; - struct libssh2_agent_publickey *sshagent_prev_identity; - LIBSSH2_KNOWNHOSTS *kh; -#endif /* USE_LIBSSH */ - BIT(authed); /* the connection has been authenticated fine */ - BIT(acceptfail); /* used by the SFTP_QUOTE (continue if - quote command fails) */ -}; - -#ifdef USE_LIBSSH -#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 9, 0) -#error "SCP/SFTP protocols require libssh 0.9.0 or later" -#endif -#endif - -#ifdef USE_LIBSSH2 - -/* Feature detection based on version numbers to better work with - non-configure platforms */ - -#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x010208) -#error "SCP/SFTP protocols require libssh2 1.2.8 or later" -/* 1.2.8 was released on April 5 2011 */ -#endif - -#endif /* USE_LIBSSH2 */ - -#ifdef CURLVERBOSE -const char *Curl_ssh_statename(sshstate state); -#else -#define Curl_ssh_statename(x) "" -#endif -void Curl_ssh_set_state(struct Curl_easy *data, - struct ssh_conn *sshc, - sshstate nowstate); - -#define myssh_to(x, y, z) Curl_ssh_set_state(x, y, z) - -/* generic SSH backend functions */ -CURLcode Curl_ssh_init(void); -void Curl_ssh_cleanup(void); -void Curl_ssh_version(char *buffer, size_t buflen); -void Curl_ssh_attach(struct Curl_easy *data, - struct connectdata *conn); -#else /* !USE_SSH */ -#define Curl_ssh_cleanup() -#define Curl_ssh_attach(x, y) -#define Curl_ssh_init() 0 -#endif /* USE_SSH */ - -#endif /* HEADER_CURL_SSH_H */ diff --git a/vendor/curl/lib/vssh/vssh.c b/vendor/curl/lib/vssh/vssh.c deleted file mode 100644 index 0ba4a9e69..000000000 --- a/vendor/curl/lib/vssh/vssh.c +++ /dev/null @@ -1,333 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl AND ISC - * - ***************************************************************************/ -#include "curl_setup.h" -#include "vssh/ssh.h" - -#ifdef USE_SSH - -#include "vssh/vssh.h" -#include "curlx/strparse.h" -#include "curl_trc.h" -#include "escape.h" - -#ifdef CURLVERBOSE -const char *Curl_ssh_statename(sshstate state) -{ - static const char * const names[] = { - "SSH_STOP", - "SSH_INIT", - "SSH_S_STARTUP", - "SSH_HOSTKEY", - "SSH_AUTHLIST", - "SSH_AUTH_PKEY_INIT", - "SSH_AUTH_PKEY", - "SSH_AUTH_PASS_INIT", - "SSH_AUTH_PASS", - "SSH_AUTH_AGENT_INIT", - "SSH_AUTH_AGENT_LIST", - "SSH_AUTH_AGENT", - "SSH_AUTH_HOST_INIT", - "SSH_AUTH_HOST", - "SSH_AUTH_KEY_INIT", - "SSH_AUTH_KEY", - "SSH_AUTH_GSSAPI", - "SSH_AUTH_DONE", - "SSH_SFTP_INIT", - "SSH_SFTP_REALPATH", - "SSH_SFTP_QUOTE_INIT", - "SSH_SFTP_POSTQUOTE_INIT", - "SSH_SFTP_QUOTE", - "SSH_SFTP_NEXT_QUOTE", - "SSH_SFTP_QUOTE_STAT", - "SSH_SFTP_QUOTE_SETSTAT", - "SSH_SFTP_QUOTE_SYMLINK", - "SSH_SFTP_QUOTE_MKDIR", - "SSH_SFTP_QUOTE_RENAME", - "SSH_SFTP_QUOTE_RMDIR", - "SSH_SFTP_QUOTE_UNLINK", - "SSH_SFTP_QUOTE_STATVFS", - "SSH_SFTP_GETINFO", - "SSH_SFTP_FILETIME", - "SSH_SFTP_TRANS_INIT", - "SSH_SFTP_UPLOAD_INIT", - "SSH_SFTP_CREATE_DIRS_INIT", - "SSH_SFTP_CREATE_DIRS", - "SSH_SFTP_CREATE_DIRS_MKDIR", - "SSH_SFTP_READDIR_INIT", - "SSH_SFTP_READDIR", - "SSH_SFTP_READDIR_LINK", - "SSH_SFTP_READDIR_BOTTOM", - "SSH_SFTP_READDIR_DONE", - "SSH_SFTP_DOWNLOAD_INIT", - "SSH_SFTP_DOWNLOAD_STAT", - "SSH_SFTP_CLOSE", - "SSH_SFTP_SHUTDOWN", - "SSH_SCP_TRANS_INIT", - "SSH_SCP_UPLOAD_INIT", - "SSH_SCP_DOWNLOAD_INIT", - "SSH_SCP_DOWNLOAD", - "SSH_SCP_DONE", - "SSH_SCP_SEND_EOF", - "SSH_SCP_WAIT_EOF", - "SSH_SCP_WAIT_CLOSE", - "SSH_SCP_CHANNEL_FREE", - "SSH_SESSION_DISCONNECT", - "SSH_SESSION_FREE", - "QUIT" - }; - /* a precaution to make sure the lists are in sync */ - DEBUGASSERT(CURL_ARRAYSIZE(names) == SSH_LAST); - return ((size_t)state < CURL_ARRAYSIZE(names)) ? names[state] : ""; -} -#endif /* CURLVERBOSE */ - -/* - * SSH State machine related code - */ -/* This is the ONLY way to change SSH state! */ -void Curl_ssh_set_state(struct Curl_easy *data, - struct ssh_conn *sshc, - sshstate nowstate) -{ -#ifdef CURLVERBOSE - if(sshc->state != nowstate) { - CURL_TRC_SSH(data, "[%s] -> [%s]", - Curl_ssh_statename(sshc->state), - Curl_ssh_statename(nowstate)); - } -#else - (void)data; -#endif - sshc->state = nowstate; -} - -#define MAX_SSHPATH_LEN 100000 /* arbitrary */ - -/* figure out the path to work with in this particular request */ -CURLcode Curl_getworkingpath(struct Curl_easy *data, - const char *homedir, /* when SFTP is used */ - char **path) /* returns the allocated - real path to work with */ -{ - char *working_path; - size_t working_path_len; - struct dynbuf npath; - CURLcode result = - Curl_urldecode(data->state.up.path, 0, &working_path, - &working_path_len, REJECT_ZERO); - if(result) - return result; - - /* new path to switch to in case we need to */ - curlx_dyn_init(&npath, MAX_SSHPATH_LEN); - - /* Check for /~/, indicating relative to the user's home directory */ - if((data->conn->scheme->protocol & CURLPROTO_SCP) && - (working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) { - /* It is referenced to the home directory, so strip the leading '/~/' */ - if(curlx_dyn_addn(&npath, &working_path[3], working_path_len - 3)) { - curlx_free(working_path); - return CURLE_OUT_OF_MEMORY; - } - } - else if((data->conn->scheme->protocol & CURLPROTO_SFTP) && - (!strcmp("/~", working_path) || - ((working_path_len > 2) && !memcmp(working_path, "/~/", 3)))) { - if(curlx_dyn_add(&npath, homedir)) { - curlx_free(working_path); - return CURLE_OUT_OF_MEMORY; - } - if(working_path_len > 2) { - size_t len; - const char *p; - int copyfrom = 3; - /* Copy a separating '/' if homedir does not end with one */ - len = curlx_dyn_len(&npath); - p = curlx_dyn_ptr(&npath); - if(len && (p[len - 1] != '/')) - copyfrom = 2; - - if(curlx_dyn_addn(&npath, &working_path[copyfrom], - working_path_len - copyfrom)) { - curlx_free(working_path); - return CURLE_OUT_OF_MEMORY; - } - } - else { - if(curlx_dyn_add(&npath, "/")) { - curlx_free(working_path); - return CURLE_OUT_OF_MEMORY; - } - } - } - - if(curlx_dyn_len(&npath)) { - curlx_free(working_path); - - /* store the pointer for the caller to receive */ - *path = curlx_dyn_ptr(&npath); - } - else - *path = working_path; - DEBUGASSERT(*path && (*path)[0]); - - return CURLE_OK; -} - -#define MAX_PATHLENGTH 65535 /* arbitrary long */ - -CURLcode Curl_get_pathname(const char **cpp, char **path, const char *homedir) -{ - const char *cp = *cpp; - struct dynbuf out; - CURLcode result; - - DEBUGASSERT(homedir); - *path = NULL; - *cpp = NULL; - if(!*cp || !homedir) - return CURLE_QUOTE_ERROR; - - curlx_dyn_init(&out, MAX_PATHLENGTH); - - /* Ignore leading whitespace */ - curlx_str_passblanks(&cp); - - /* Check for quoted filenames */ - if(*cp == '\"' || *cp == '\'') { - char quot = *cp++; - - /* Search for terminating quote, unescape some chars */ - while(*cp != quot) { - if(!*cp) /* End of string */ - goto fail; - - if(*cp == '\\') { /* Escaped characters */ - cp++; - if(*cp != '\'' && *cp != '\"' && *cp != '\\') - goto fail; - } - result = curlx_dyn_addn(&out, cp, 1); - if(result) - return result; - cp++; - } - cp++; /* pass the end quote */ - - if(!curlx_dyn_len(&out)) - goto fail; - } - else { - struct Curl_str word; - bool content = FALSE; - int rc; - /* Handling for relative path - prepend home directory */ - if(cp[0] == '/' && cp[1] == '~' && cp[2] == '/') { - result = curlx_dyn_add(&out, homedir); - if(!result) - result = curlx_dyn_addn(&out, "/", 1); - if(result) - return result; - cp += 3; - content = TRUE; - } - /* Read to end of filename - either to whitespace or terminator */ - rc = curlx_str_word(&cp, &word, MAX_PATHLENGTH); - if(rc) { - if(rc == STRE_BIG) { - curlx_dyn_free(&out); - return CURLE_TOO_LARGE; - } - else if(!content) - /* no path, no word, this is incorrect */ - goto fail; - } - else { - /* append the word */ - result = curlx_dyn_addn(&out, curlx_str(&word), curlx_strlen(&word)); - if(result) - return result; - } - } - /* skip whitespace */ - curlx_str_passblanks(&cp); - - /* return pointer to second parameter if it exists */ - *cpp = cp; - - *path = curlx_dyn_ptr(&out); - return CURLE_OK; - -fail: - curlx_dyn_free(&out); - return CURLE_QUOTE_ERROR; -} - -CURLcode Curl_ssh_range(struct Curl_easy *data, - const char *range, curl_off_t filesize, - curl_off_t *startp, curl_off_t *sizep) -{ - curl_off_t from, to; - int to_t; - int from_t = curlx_str_number(&range, &from, CURL_OFF_T_MAX); - if(from_t == STRE_OVERFLOW) - return CURLE_RANGE_ERROR; - curlx_str_passblanks(&range); - (void)curlx_str_single(&range, '-'); - - to_t = curlx_str_numblanks(&range, &to); - if((to_t == STRE_OVERFLOW) || (to_t && from_t) || *range) - return CURLE_RANGE_ERROR; - - if(from_t) { - /* no start point given, set from relative to end of file */ - if(!to) - /* "-0" is not a fine range */ - return CURLE_RANGE_ERROR; - else if(to > filesize) - to = filesize; - from = filesize - to; - to = filesize - 1; - } - else if(from > filesize) { - failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%" - FMT_OFF_T ")", from, filesize); - return CURLE_RANGE_ERROR; - } - else if((to_t == STRE_NO_NUM) || (to >= filesize)) - to = filesize - 1; - - if(from > to) { - failf(data, "Bad range: start offset larger than end offset"); - return CURLE_RANGE_ERROR; - } - if((to - from) == CURL_OFF_T_MAX) - return CURLE_RANGE_ERROR; - - *startp = from; - *sizep = to - from + 1; - return CURLE_OK; -} - -#endif /* USE_SSH */ diff --git a/vendor/curl/lib/vssh/vssh.h b/vendor/curl/lib/vssh/vssh.h deleted file mode 100644 index 492108fbd..000000000 --- a/vendor/curl/lib/vssh/vssh.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef HEADER_CURL_VSSH_VSSH_H -#define HEADER_CURL_VSSH_VSSH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SSH - -#include "urldata.h" - -CURLcode Curl_getworkingpath(struct Curl_easy *data, - const char *homedir, - char **path); - -CURLcode Curl_get_pathname(const char **cpp, char **path, const char *homedir); - -CURLcode Curl_ssh_range(struct Curl_easy *data, - const char *range, curl_off_t filesize, - curl_off_t *startp, curl_off_t *sizep); -#endif /* USE_SSH */ -#endif /* HEADER_CURL_VSSH_VSSH_H */ diff --git a/vendor/curl/lib/vtls/apple.c b/vendor/curl/lib/vtls/apple.c deleted file mode 100644 index e28a40cc0..000000000 --- a/vendor/curl/lib/vtls/apple.c +++ /dev/null @@ -1,293 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* This file is for implementing all "generic" SSL functions that all libcurl - internals should use. It is then responsible for calling the proper - "backend" function. - - SSL-functions in libcurl should call functions in this source file, and not - to any specific SSL-layer. - - Curl_ssl_ - prefix for generic ones - - Note that this source code uses the functions of the configured SSL - backend via the global Curl_ssl instance. - - "SSL/TLS Strong Encryption: An Introduction" - https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html -*/ - -#include "curl_setup.h" - -#ifdef USE_APPLE_SECTRUST - -#include "urldata.h" -#include "cfilters.h" -#include "curl_trc.h" -#include "vtls/vtls.h" -#include "vtls/apple.h" - -#include - -#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= 101400) || \ - (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000) -#define SUPPORTS_SecTrustEvaluateWithError 1 -#endif - -#if defined(SUPPORTS_SecTrustEvaluateWithError) && \ - ((defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ - MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || \ - (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ - __IPHONE_OS_VERSION_MIN_REQUIRED >= 120000)) -#define REQUIRES_SecTrustEvaluateWithError 1 -#endif - -#if defined(SUPPORTS_SecTrustEvaluateWithError) && \ - !defined(HAVE_BUILTIN_AVAILABLE) && \ - !defined(REQUIRES_SecTrustEvaluateWithError) -#undef SUPPORTS_SecTrustEvaluateWithError -#endif - -#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= 100900) || \ - (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) -#define SUPPORTS_SecOCSP 1 -#endif - -CURLcode Curl_vtls_apple_verify(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - size_t num_certs, - Curl_vtls_get_cert_der *der_cb, - void *cb_user_data, - const unsigned char *ocsp_buf, - size_t ocsp_len) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - CURLcode result = CURLE_OK; - SecTrustRef trust = NULL; - SecPolicyRef policy = NULL; - CFMutableArrayRef policies = NULL; - CFMutableArrayRef cert_array = NULL; - CFStringRef host_str = NULL; - CFErrorRef error = NULL; - OSStatus status = noErr; - CFStringRef error_ref = NULL; - char *err_desc = NULL; - size_t i; - - if(conn_config->verifyhost) { - host_str = CFStringCreateWithCString(NULL, - peer->sni ? peer->sni : peer->hostname, kCFStringEncodingUTF8); - if(!host_str) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - policies = CFArrayCreateMutable(NULL, 2, &kCFTypeArrayCallBacks); - if(!policies) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - policy = SecPolicyCreateSSL(true, host_str); - if(!policy) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - CFArrayAppendValue(policies, policy); - CFRelease(policy); - policy = NULL; - -#if defined(HAVE_BUILTIN_AVAILABLE) && defined(SUPPORTS_SecOCSP) - { - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - if(!ssl_config->no_revoke) { - if(__builtin_available(macOS 10.9, iOS 7, tvOS 9, watchOS 2, *)) { - /* Even without this set, validation seemingly-unavoidably fails - * for certificates that trustd already knows to be revoked. - * This policy further allows trustd to consult CRLs and OCSP data - * to determine revocation status (which it may then cache). */ - CFOptionFlags revocation_flags = kSecRevocationUseAnyAvailableMethod; -#if 0 - /* `revoke_best_effort` is off by default in libcurl. When we - * add `kSecRevocationRequirePositiveResponse` to the Apple - * Trust policies, it interprets this as it NEEDs a confirmation - * of a cert being NOT REVOKED. Which not in general available for - * certificates on the Internet. - * It seems that applications using this policy are expected to PIN - * their certificate public keys or verification fails. - * This does not seem to be what we want here. */ - if(!ssl_config->revoke_best_effort) { - revocation_flags |= kSecRevocationRequirePositiveResponse; - } -#endif - policy = SecPolicyCreateRevocation(revocation_flags); - if(!policy) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - CFArrayAppendValue(policies, policy); - } - } - } -#endif - - cert_array = CFArrayCreateMutable(NULL, num_certs, &kCFTypeArrayCallBacks); - if(!cert_array) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - for(i = 0; i < num_certs; i++) { - SecCertificateRef cert; - CFDataRef certdata; - unsigned char *der; - size_t der_len; - - result = der_cb(cf, data, cb_user_data, i, &der, &der_len); - if(result) - goto out; - - certdata = CFDataCreate(NULL, der, (CFIndex)der_len); - if(!certdata) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - cert = SecCertificateCreateWithData(NULL, certdata); - CFRelease(certdata); - if(!cert) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - CFArrayAppendValue(cert_array, cert); - CFRelease(cert); - } - - status = SecTrustCreateWithCertificates(cert_array, policies, &trust); - if(status != noErr || !trust) { - failf(data, "Apple SecTrust: failed to create validation trust"); - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; - } - -#if defined(HAVE_BUILTIN_AVAILABLE) && defined(SUPPORTS_SecOCSP) - if(ocsp_len > 0) { - if(__builtin_available(macOS 10.9, iOS 7, tvOS 9, watchOS 2, *)) { - CFDataRef ocspdata = CFDataCreate(NULL, ocsp_buf, (CFIndex)ocsp_len); - - status = SecTrustSetOCSPResponse(trust, ocspdata); - CFRelease(ocspdata); - if(status != noErr) { - failf(data, "Apple SecTrust: failed to set OCSP response: %i", - (int)status); - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; - } - } - } -#else - (void)ocsp_buf; - (void)ocsp_len; -#endif - -#ifdef SUPPORTS_SecTrustEvaluateWithError -#ifdef HAVE_BUILTIN_AVAILABLE - if(__builtin_available(macOS 10.14, iOS 12, tvOS 12, watchOS 5, *)) { -#else - if(1) { -#endif - result = SecTrustEvaluateWithError(trust, &error) ? - CURLE_OK : CURLE_PEER_FAILED_VERIFICATION; - if(error) { - VERBOSE(CFIndex code = CFErrorGetCode(error)); - error_ref = CFErrorCopyDescription(error); - - if(error_ref) { - CFIndex size = CFStringGetMaximumSizeForEncoding( - CFStringGetLength(error_ref), kCFStringEncodingUTF8); - err_desc = curlx_malloc(size + 1); - if(err_desc) { - if(!CFStringGetCString(error_ref, err_desc, size, - kCFStringEncodingUTF8)) { - curlx_free(err_desc); - err_desc = NULL; - } - } - } - infof(data, "Apple SecTrust failure %ld%s%s", code, - err_desc ? ": " : "", err_desc ? err_desc : ""); - } - } - else -#endif /* SUPPORTS_SecTrustEvaluateWithError */ - { -#ifndef REQUIRES_SecTrustEvaluateWithError - SecTrustResultType sec_result; - status = SecTrustEvaluate(trust, &sec_result); - - if(status != noErr) { - failf(data, "Apple SecTrust verification failed: error %i", (int)status); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else if((sec_result == kSecTrustResultUnspecified) || - (sec_result == kSecTrustResultProceed)) { - /* "unspecified" means system-trusted with no explicit user setting */ - result = CURLE_OK; - } - else { - /* Any other trust result is a verification failure in this context */ - result = CURLE_PEER_FAILED_VERIFICATION; - } -#endif /* REQUIRES_SecTrustEvaluateWithError */ - } - -out: - curlx_free(err_desc); - if(error_ref) - CFRelease(error_ref); - if(error) - CFRelease(error); - if(host_str) - CFRelease(host_str); - if(policies) - CFRelease(policies); - if(policy) - CFRelease(policy); - if(cert_array) - CFRelease(cert_array); - if(trust) - CFRelease(trust); - return result; -} - -#endif /* USE_APPLE_SECTRUST */ diff --git a/vendor/curl/lib/vtls/apple.h b/vendor/curl/lib/vtls/apple.h deleted file mode 100644 index d86a56b1f..000000000 --- a/vendor/curl/lib/vtls/apple.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef HEADER_CURL_VTLS_APPLE_H -#define HEADER_CURL_VTLS_APPLE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Jan Venekamp, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_APPLE_SECTRUST -struct Curl_cfilter; -struct Curl_easy; -struct ssl_peer; - -/* Get the DER encoded i-th certificate in the server handshake */ -typedef CURLcode Curl_vtls_get_cert_der(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *user_data, - size_t i, - unsigned char **pder, - size_t *pder_len); - -/* Ask Apple's Security framework to verify the certificate chain - * send by the peer. On CURLE_OK it has been verified. - */ -CURLcode Curl_vtls_apple_verify(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - size_t num_certs, - Curl_vtls_get_cert_der *der_cb, - void *cb_user_data, - const unsigned char *ocsp_buf, - size_t ocsp_len); -#endif /* USE_APPLE_SECTRUST */ - -#endif /* HEADER_CURL_VTLS_APPLE_H */ diff --git a/vendor/curl/lib/vtls/cipher_suite.c b/vendor/curl/lib/vtls/cipher_suite.c deleted file mode 100644 index 1fc6e9f8c..000000000 --- a/vendor/curl/lib/vtls/cipher_suite.c +++ /dev/null @@ -1,702 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Jan Venekamp, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_MBEDTLS) || defined(USE_RUSTLS) - -#include "vtls/cipher_suite.h" - -/* - * To support the CURLOPT_SSL_CIPHER_LIST option on SSL backends - * that do not support it natively, but do support setting a list of - * IANA ids, we need a list of all supported cipher suite names - * (OpenSSL and IANA) to be able to look up the IANA ids. - * - * To keep the binary size of this list down we compress each entry - * down to 2 + 6 bytes using the C preprocessor. - */ - -/* - * mbedTLS NOTE: mbedTLS has mbedtls_ssl_get_ciphersuite_id() to - * convert a string representation to an IANA id, we do not use that - * because it does not support "standard" OpenSSL cipher suite - * names, nor IANA names. - */ - -/* NOTE: also see tests/unit/unit3205.c */ - -/* Text for cipher suite parts (max 64 entries), - keep indexes below in sync with this! */ -static const char *cs_txt = - "\0" - "TLS" "\0" - "WITH" "\0" - "128" "\0" - "256" "\0" - "3DES" "\0" - "8" "\0" - "AES" "\0" - "AES128" "\0" - "AES256" "\0" - "CBC" "\0" - "CBC3" "\0" - "CCM" "\0" - "CCM8" "\0" - "CHACHA20" "\0" - "DES" "\0" - "DHE" "\0" - "ECDH" "\0" - "ECDHE" "\0" - "ECDSA" "\0" - "EDE" "\0" /* spellchecker:disable-line */ - "GCM" "\0" - "MD5" "\0" - "NULL" "\0" - "POLY1305" "\0" - "PSK" "\0" - "RSA" "\0" - "SHA" "\0" - "SHA256" "\0" - "SHA384" "\0" -#ifdef USE_MBEDTLS - "ARIA" "\0" - "ARIA128" "\0" - "ARIA256" "\0" - "CAMELLIA" "\0" - "CAMELLIA128" "\0" - "CAMELLIA256" "\0" -#endif -; -/* Indexes of above cs_txt */ -enum { - CS_TXT_IDX_, - CS_TXT_IDX_TLS, - CS_TXT_IDX_WITH, - CS_TXT_IDX_128, - CS_TXT_IDX_256, - CS_TXT_IDX_3DES, - CS_TXT_IDX_8, - CS_TXT_IDX_AES, - CS_TXT_IDX_AES128, - CS_TXT_IDX_AES256, - CS_TXT_IDX_CBC, - CS_TXT_IDX_CBC3, - CS_TXT_IDX_CCM, - CS_TXT_IDX_CCM8, - CS_TXT_IDX_CHACHA20, - CS_TXT_IDX_DES, - CS_TXT_IDX_DHE, - CS_TXT_IDX_ECDH, - CS_TXT_IDX_ECDHE, - CS_TXT_IDX_ECDSA, - CS_TXT_IDX_EDE, /* spellchecker:disable-line */ - CS_TXT_IDX_GCM, - CS_TXT_IDX_MD5, - CS_TXT_IDX_NULL, - CS_TXT_IDX_POLY1305, - CS_TXT_IDX_PSK, - CS_TXT_IDX_RSA, - CS_TXT_IDX_SHA, - CS_TXT_IDX_SHA256, - CS_TXT_IDX_SHA384, -#ifdef USE_MBEDTLS - CS_TXT_IDX_ARIA, - CS_TXT_IDX_ARIA128, - CS_TXT_IDX_ARIA256, - CS_TXT_IDX_CAMELLIA, - CS_TXT_IDX_CAMELLIA128, - CS_TXT_IDX_CAMELLIA256, -#endif - CS_TXT_LEN, -}; - -#define CS_ZIP_IDX(a, b, c, d, e, f, g, h) \ -{ \ - (uint8_t)((((a) << 2) & 0xFF) | ((b) & 0x3F) >> 4), \ - (uint8_t)((((b) << 4) & 0xFF) | ((c) & 0x3F) >> 2), \ - (uint8_t)((((c) << 6) & 0xFF) | ((d) & 0x3F)), \ - (uint8_t)((((e) << 2) & 0xFF) | ((f) & 0x3F) >> 4), \ - (uint8_t)((((f) << 4) & 0xFF) | ((g) & 0x3F) >> 2), \ - (uint8_t)((((g) << 6) & 0xFF) | ((h) & 0x3F)) \ -} -#define CS_ENTRY(id, a, b, c, d, e, f, g, h) \ -{ \ - id, \ - CS_ZIP_IDX( \ - CS_TXT_IDX_ ## a, CS_TXT_IDX_ ## b, \ - CS_TXT_IDX_ ## c, CS_TXT_IDX_ ## d, \ - CS_TXT_IDX_ ## e, CS_TXT_IDX_ ## f, \ - CS_TXT_IDX_ ## g, CS_TXT_IDX_ ## h \ - ) \ -} - -struct cs_entry { - uint16_t id; - uint8_t zip[6]; -}; - -/* !checksrc! disable COMMANOSPACE all */ -static const struct cs_entry cs_list[] = { - /* TLS 1.3 ciphers */ - CS_ENTRY(0x1301, TLS,AES,128,GCM,SHA256,,,), - CS_ENTRY(0x1302, TLS,AES,256,GCM,SHA384,,,), - CS_ENTRY(0x1303, TLS,CHACHA20,POLY1305,SHA256,,,,), - CS_ENTRY(0x1304, TLS,AES,128,CCM,SHA256,,,), - CS_ENTRY(0x1305, TLS,AES,128,CCM,8,SHA256,,), - /* TLS 1.2 ciphers */ - CS_ENTRY(0xC02B, TLS,ECDHE,ECDSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0xC02B, ECDHE,ECDSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0xC02C, TLS,ECDHE,ECDSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0xC02C, ECDHE,ECDSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0xC02F, TLS,ECDHE,RSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0xC02F, ECDHE,RSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0xC030, TLS,ECDHE,RSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0xC030, ECDHE,RSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0xCCA8, TLS,ECDHE,RSA,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCA8, ECDHE,RSA,CHACHA20,POLY1305,,,,), - CS_ENTRY(0xCCA9, TLS,ECDHE,ECDSA,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCA9, ECDHE,ECDSA,CHACHA20,POLY1305,,,,), -#ifdef USE_MBEDTLS - CS_ENTRY(0x002F, TLS,RSA,WITH,AES,128,CBC,SHA,), - CS_ENTRY(0x002F, AES128,SHA,,,,,,), - CS_ENTRY(0x0035, TLS,RSA,WITH,AES,256,CBC,SHA,), - CS_ENTRY(0x0035, AES256,SHA,,,,,,), - CS_ENTRY(0x003C, TLS,RSA,WITH,AES,128,CBC,SHA256,), - CS_ENTRY(0x003C, AES128,SHA256,,,,,,), - CS_ENTRY(0x003D, TLS,RSA,WITH,AES,256,CBC,SHA256,), - CS_ENTRY(0x003D, AES256,SHA256,,,,,,), - CS_ENTRY(0x009C, TLS,RSA,WITH,AES,128,GCM,SHA256,), - CS_ENTRY(0x009C, AES128,GCM,SHA256,,,,,), - CS_ENTRY(0x009D, TLS,RSA,WITH,AES,256,GCM,SHA384,), - CS_ENTRY(0x009D, AES256,GCM,SHA384,,,,,), - CS_ENTRY(0xC004, TLS,ECDH,ECDSA,WITH,AES,128,CBC,SHA), - CS_ENTRY(0xC004, ECDH,ECDSA,AES128,SHA,,,,), - CS_ENTRY(0xC005, TLS,ECDH,ECDSA,WITH,AES,256,CBC,SHA), - CS_ENTRY(0xC005, ECDH,ECDSA,AES256,SHA,,,,), - CS_ENTRY(0xC009, TLS,ECDHE,ECDSA,WITH,AES,128,CBC,SHA), - CS_ENTRY(0xC009, ECDHE,ECDSA,AES128,SHA,,,,), - CS_ENTRY(0xC00A, TLS,ECDHE,ECDSA,WITH,AES,256,CBC,SHA), - CS_ENTRY(0xC00A, ECDHE,ECDSA,AES256,SHA,,,,), - CS_ENTRY(0xC00E, TLS,ECDH,RSA,WITH,AES,128,CBC,SHA), - CS_ENTRY(0xC00E, ECDH,RSA,AES128,SHA,,,,), - CS_ENTRY(0xC00F, TLS,ECDH,RSA,WITH,AES,256,CBC,SHA), - CS_ENTRY(0xC00F, ECDH,RSA,AES256,SHA,,,,), - CS_ENTRY(0xC013, TLS,ECDHE,RSA,WITH,AES,128,CBC,SHA), - CS_ENTRY(0xC013, ECDHE,RSA,AES128,SHA,,,,), - CS_ENTRY(0xC014, TLS,ECDHE,RSA,WITH,AES,256,CBC,SHA), - CS_ENTRY(0xC014, ECDHE,RSA,AES256,SHA,,,,), - CS_ENTRY(0xC023, TLS,ECDHE,ECDSA,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0xC023, ECDHE,ECDSA,AES128,SHA256,,,,), - CS_ENTRY(0xC024, TLS,ECDHE,ECDSA,WITH,AES,256,CBC,SHA384), - CS_ENTRY(0xC024, ECDHE,ECDSA,AES256,SHA384,,,,), - CS_ENTRY(0xC025, TLS,ECDH,ECDSA,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0xC025, ECDH,ECDSA,AES128,SHA256,,,,), - CS_ENTRY(0xC026, TLS,ECDH,ECDSA,WITH,AES,256,CBC,SHA384), - CS_ENTRY(0xC026, ECDH,ECDSA,AES256,SHA384,,,,), - CS_ENTRY(0xC027, TLS,ECDHE,RSA,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0xC027, ECDHE,RSA,AES128,SHA256,,,,), - CS_ENTRY(0xC028, TLS,ECDHE,RSA,WITH,AES,256,CBC,SHA384), - CS_ENTRY(0xC028, ECDHE,RSA,AES256,SHA384,,,,), - CS_ENTRY(0xC029, TLS,ECDH,RSA,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0xC029, ECDH,RSA,AES128,SHA256,,,,), - CS_ENTRY(0xC02A, TLS,ECDH,RSA,WITH,AES,256,CBC,SHA384), - CS_ENTRY(0xC02A, ECDH,RSA,AES256,SHA384,,,,), - CS_ENTRY(0xC02D, TLS,ECDH,ECDSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0xC02D, ECDH,ECDSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0xC02E, TLS,ECDH,ECDSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0xC02E, ECDH,ECDSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0xC031, TLS,ECDH,RSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0xC031, ECDH,RSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0xC032, TLS,ECDH,RSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0xC032, ECDH,RSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0x0001, TLS,RSA,WITH,NULL,MD5,,,), - CS_ENTRY(0x0001, NULL,MD5,,,,,,), - CS_ENTRY(0x0002, TLS,RSA,WITH,NULL,SHA,,,), - CS_ENTRY(0x0002, NULL,SHA,,,,,,), - CS_ENTRY(0x002C, TLS,PSK,WITH,NULL,SHA,,,), - CS_ENTRY(0x002C, PSK,NULL,SHA,,,,,), - CS_ENTRY(0x002D, TLS,DHE,PSK,WITH,NULL,SHA,,), - CS_ENTRY(0x002D, DHE,PSK,NULL,SHA,,,,), - CS_ENTRY(0x002E, TLS,RSA,PSK,WITH,NULL,SHA,,), - CS_ENTRY(0x002E, RSA,PSK,NULL,SHA,,,,), - CS_ENTRY(0x0033, TLS,DHE,RSA,WITH,AES,128,CBC,SHA), - CS_ENTRY(0x0033, DHE,RSA,AES128,SHA,,,,), - CS_ENTRY(0x0039, TLS,DHE,RSA,WITH,AES,256,CBC,SHA), - CS_ENTRY(0x0039, DHE,RSA,AES256,SHA,,,,), - CS_ENTRY(0x003B, TLS,RSA,WITH,NULL,SHA256,,,), - CS_ENTRY(0x003B, NULL,SHA256,,,,,,), - CS_ENTRY(0x0067, TLS,DHE,RSA,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0x0067, DHE,RSA,AES128,SHA256,,,,), - CS_ENTRY(0x006B, TLS,DHE,RSA,WITH,AES,256,CBC,SHA256), - CS_ENTRY(0x006B, DHE,RSA,AES256,SHA256,,,,), - CS_ENTRY(0x008C, TLS,PSK,WITH,AES,128,CBC,SHA,), - CS_ENTRY(0x008C, PSK,AES128,CBC,SHA,,,,), - CS_ENTRY(0x008D, TLS,PSK,WITH,AES,256,CBC,SHA,), - CS_ENTRY(0x008D, PSK,AES256,CBC,SHA,,,,), - CS_ENTRY(0x0090, TLS,DHE,PSK,WITH,AES,128,CBC,SHA), - CS_ENTRY(0x0090, DHE,PSK,AES128,CBC,SHA,,,), - CS_ENTRY(0x0091, TLS,DHE,PSK,WITH,AES,256,CBC,SHA), - CS_ENTRY(0x0091, DHE,PSK,AES256,CBC,SHA,,,), - CS_ENTRY(0x0094, TLS,RSA,PSK,WITH,AES,128,CBC,SHA), - CS_ENTRY(0x0094, RSA,PSK,AES128,CBC,SHA,,,), - CS_ENTRY(0x0095, TLS,RSA,PSK,WITH,AES,256,CBC,SHA), - CS_ENTRY(0x0095, RSA,PSK,AES256,CBC,SHA,,,), - CS_ENTRY(0x009E, TLS,DHE,RSA,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0x009E, DHE,RSA,AES128,GCM,SHA256,,,), - CS_ENTRY(0x009F, TLS,DHE,RSA,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0x009F, DHE,RSA,AES256,GCM,SHA384,,,), - CS_ENTRY(0x00A8, TLS,PSK,WITH,AES,128,GCM,SHA256,), - CS_ENTRY(0x00A8, PSK,AES128,GCM,SHA256,,,,), - CS_ENTRY(0x00A9, TLS,PSK,WITH,AES,256,GCM,SHA384,), - CS_ENTRY(0x00A9, PSK,AES256,GCM,SHA384,,,,), - CS_ENTRY(0x00AA, TLS,DHE,PSK,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0x00AA, DHE,PSK,AES128,GCM,SHA256,,,), - CS_ENTRY(0x00AB, TLS,DHE,PSK,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0x00AB, DHE,PSK,AES256,GCM,SHA384,,,), - CS_ENTRY(0x00AC, TLS,RSA,PSK,WITH,AES,128,GCM,SHA256), - CS_ENTRY(0x00AC, RSA,PSK,AES128,GCM,SHA256,,,), - CS_ENTRY(0x00AD, TLS,RSA,PSK,WITH,AES,256,GCM,SHA384), - CS_ENTRY(0x00AD, RSA,PSK,AES256,GCM,SHA384,,,), - CS_ENTRY(0x00AE, TLS,PSK,WITH,AES,128,CBC,SHA256,), - CS_ENTRY(0x00AE, PSK,AES128,CBC,SHA256,,,,), - CS_ENTRY(0x00AF, TLS,PSK,WITH,AES,256,CBC,SHA384,), - CS_ENTRY(0x00AF, PSK,AES256,CBC,SHA384,,,,), - CS_ENTRY(0x00B0, TLS,PSK,WITH,NULL,SHA256,,,), - CS_ENTRY(0x00B0, PSK,NULL,SHA256,,,,,), - CS_ENTRY(0x00B1, TLS,PSK,WITH,NULL,SHA384,,,), - CS_ENTRY(0x00B1, PSK,NULL,SHA384,,,,,), - CS_ENTRY(0x00B2, TLS,DHE,PSK,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0x00B2, DHE,PSK,AES128,CBC,SHA256,,,), - CS_ENTRY(0x00B3, TLS,DHE,PSK,WITH,AES,256,CBC,SHA384), - CS_ENTRY(0x00B3, DHE,PSK,AES256,CBC,SHA384,,,), - CS_ENTRY(0x00B4, TLS,DHE,PSK,WITH,NULL,SHA256,,), - CS_ENTRY(0x00B4, DHE,PSK,NULL,SHA256,,,,), - CS_ENTRY(0x00B5, TLS,DHE,PSK,WITH,NULL,SHA384,,), - CS_ENTRY(0x00B5, DHE,PSK,NULL,SHA384,,,,), - CS_ENTRY(0x00B6, TLS,RSA,PSK,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0x00B6, RSA,PSK,AES128,CBC,SHA256,,,), - CS_ENTRY(0x00B7, TLS,RSA,PSK,WITH,AES,256,CBC,SHA384), - CS_ENTRY(0x00B7, RSA,PSK,AES256,CBC,SHA384,,,), - CS_ENTRY(0x00B8, TLS,RSA,PSK,WITH,NULL,SHA256,,), - CS_ENTRY(0x00B8, RSA,PSK,NULL,SHA256,,,,), - CS_ENTRY(0x00B9, TLS,RSA,PSK,WITH,NULL,SHA384,,), - CS_ENTRY(0x00B9, RSA,PSK,NULL,SHA384,,,,), - CS_ENTRY(0xC001, TLS,ECDH,ECDSA,WITH,NULL,SHA,,), - CS_ENTRY(0xC001, ECDH,ECDSA,NULL,SHA,,,,), - CS_ENTRY(0xC006, TLS,ECDHE,ECDSA,WITH,NULL,SHA,,), - CS_ENTRY(0xC006, ECDHE,ECDSA,NULL,SHA,,,,), - CS_ENTRY(0xC00B, TLS,ECDH,RSA,WITH,NULL,SHA,,), - CS_ENTRY(0xC00B, ECDH,RSA,NULL,SHA,,,,), - CS_ENTRY(0xC010, TLS,ECDHE,RSA,WITH,NULL,SHA,,), - CS_ENTRY(0xC010, ECDHE,RSA,NULL,SHA,,,,), - CS_ENTRY(0xC035, TLS,ECDHE,PSK,WITH,AES,128,CBC,SHA), - CS_ENTRY(0xC035, ECDHE,PSK,AES128,CBC,SHA,,,), - CS_ENTRY(0xC036, TLS,ECDHE,PSK,WITH,AES,256,CBC,SHA), - CS_ENTRY(0xC036, ECDHE,PSK,AES256,CBC,SHA,,,), - CS_ENTRY(0xCCAB, TLS,PSK,WITH,CHACHA20,POLY1305,SHA256,,), - CS_ENTRY(0xCCAB, PSK,CHACHA20,POLY1305,,,,,), - CS_ENTRY(0xC09C, TLS,RSA,WITH,AES,128,CCM,,), - CS_ENTRY(0xC09C, AES128,CCM,,,,,,), - CS_ENTRY(0xC09D, TLS,RSA,WITH,AES,256,CCM,,), - CS_ENTRY(0xC09D, AES256,CCM,,,,,,), - CS_ENTRY(0xC0A0, TLS,RSA,WITH,AES,128,CCM,8,), - CS_ENTRY(0xC0A0, AES128,CCM8,,,,,,), - CS_ENTRY(0xC0A1, TLS,RSA,WITH,AES,256,CCM,8,), - CS_ENTRY(0xC0A1, AES256,CCM8,,,,,,), - CS_ENTRY(0xC0AC, TLS,ECDHE,ECDSA,WITH,AES,128,CCM,), - CS_ENTRY(0xC0AC, ECDHE,ECDSA,AES128,CCM,,,,), - CS_ENTRY(0xC0AD, TLS,ECDHE,ECDSA,WITH,AES,256,CCM,), - CS_ENTRY(0xC0AD, ECDHE,ECDSA,AES256,CCM,,,,), - CS_ENTRY(0xC0AE, TLS,ECDHE,ECDSA,WITH,AES,128,CCM,8), - CS_ENTRY(0xC0AE, ECDHE,ECDSA,AES128,CCM8,,,,), - CS_ENTRY(0xC0AF, TLS,ECDHE,ECDSA,WITH,AES,256,CCM,8), - CS_ENTRY(0xC0AF, ECDHE,ECDSA,AES256,CCM8,,,,), - /* entries marked ns are "non-standard", they are not in OpenSSL */ - CS_ENTRY(0x0041, TLS,RSA,WITH,CAMELLIA,128,CBC,SHA,), - CS_ENTRY(0x0041, CAMELLIA128,SHA,,,,,,), - CS_ENTRY(0x0045, TLS,DHE,RSA,WITH,CAMELLIA,128,CBC,SHA), - CS_ENTRY(0x0045, DHE,RSA,CAMELLIA128,SHA,,,,), - CS_ENTRY(0x0084, TLS,RSA,WITH,CAMELLIA,256,CBC,SHA,), - CS_ENTRY(0x0084, CAMELLIA256,SHA,,,,,,), - CS_ENTRY(0x0088, TLS,DHE,RSA,WITH,CAMELLIA,256,CBC,SHA), - CS_ENTRY(0x0088, DHE,RSA,CAMELLIA256,SHA,,,,), - CS_ENTRY(0x00BA, TLS,RSA,WITH,CAMELLIA,128,CBC,SHA256,), - CS_ENTRY(0x00BA, CAMELLIA128,SHA256,,,,,,), - CS_ENTRY(0x00BE, TLS,DHE,RSA,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0x00BE, DHE,RSA,CAMELLIA128,SHA256,,,,), - CS_ENTRY(0x00C0, TLS,RSA,WITH,CAMELLIA,256,CBC,SHA256,), - CS_ENTRY(0x00C0, CAMELLIA256,SHA256,,,,,,), - CS_ENTRY(0x00C4, TLS,DHE,RSA,WITH,CAMELLIA,256,CBC,SHA256), - CS_ENTRY(0x00C4, DHE,RSA,CAMELLIA256,SHA256,,,,), - CS_ENTRY(0xC037, TLS,ECDHE,PSK,WITH,AES,128,CBC,SHA256), - CS_ENTRY(0xC037, ECDHE,PSK,AES128,CBC,SHA256,,,), - CS_ENTRY(0xC038, TLS,ECDHE,PSK,WITH,AES,256,CBC,SHA384), - CS_ENTRY(0xC038, ECDHE,PSK,AES256,CBC,SHA384,,,), - CS_ENTRY(0xC039, TLS,ECDHE,PSK,WITH,NULL,SHA,,), - CS_ENTRY(0xC039, ECDHE,PSK,NULL,SHA,,,,), - CS_ENTRY(0xC03A, TLS,ECDHE,PSK,WITH,NULL,SHA256,,), - CS_ENTRY(0xC03A, ECDHE,PSK,NULL,SHA256,,,,), - CS_ENTRY(0xC03B, TLS,ECDHE,PSK,WITH,NULL,SHA384,,), - CS_ENTRY(0xC03B, ECDHE,PSK,NULL,SHA384,,,,), - CS_ENTRY(0xC03C, TLS,RSA,WITH,ARIA,128,CBC,SHA256,), - CS_ENTRY(0xC03C, ARIA128,SHA256,,,,,,), /* ns */ - CS_ENTRY(0xC03D, TLS,RSA,WITH,ARIA,256,CBC,SHA384,), - CS_ENTRY(0xC03D, ARIA256,SHA384,,,,,,), /* ns */ - CS_ENTRY(0xC044, TLS,DHE,RSA,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC044, DHE,RSA,ARIA128,SHA256,,,,), /* ns */ - CS_ENTRY(0xC045, TLS,DHE,RSA,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC045, DHE,RSA,ARIA256,SHA384,,,,), /* ns */ - CS_ENTRY(0xC048, TLS,ECDHE,ECDSA,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC048, ECDHE,ECDSA,ARIA128,SHA256,,,,), /* ns */ - CS_ENTRY(0xC049, TLS,ECDHE,ECDSA,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC049, ECDHE,ECDSA,ARIA256,SHA384,,,,), /* ns */ - CS_ENTRY(0xC04A, TLS,ECDH,ECDSA,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC04A, ECDH,ECDSA,ARIA128,SHA256,,,,), /* ns */ - CS_ENTRY(0xC04B, TLS,ECDH,ECDSA,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC04B, ECDH,ECDSA,ARIA256,SHA384,,,,), /* ns */ - CS_ENTRY(0xC04C, TLS,ECDHE,RSA,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC04C, ECDHE,ARIA128,SHA256,,,,,), /* ns */ - CS_ENTRY(0xC04D, TLS,ECDHE,RSA,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC04D, ECDHE,ARIA256,SHA384,,,,,), /* ns */ - CS_ENTRY(0xC04E, TLS,ECDH,RSA,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC04E, ECDH,ARIA128,SHA256,,,,,), /* ns */ - CS_ENTRY(0xC04F, TLS,ECDH,RSA,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC04F, ECDH,ARIA256,SHA384,,,,,), /* ns */ - CS_ENTRY(0xC050, TLS,RSA,WITH,ARIA,128,GCM,SHA256,), - CS_ENTRY(0xC050, ARIA128,GCM,SHA256,,,,,), - CS_ENTRY(0xC051, TLS,RSA,WITH,ARIA,256,GCM,SHA384,), - CS_ENTRY(0xC051, ARIA256,GCM,SHA384,,,,,), - CS_ENTRY(0xC052, TLS,DHE,RSA,WITH,ARIA,128,GCM,SHA256), - CS_ENTRY(0xC052, DHE,RSA,ARIA128,GCM,SHA256,,,), - CS_ENTRY(0xC053, TLS,DHE,RSA,WITH,ARIA,256,GCM,SHA384), - CS_ENTRY(0xC053, DHE,RSA,ARIA256,GCM,SHA384,,,), - CS_ENTRY(0xC05C, TLS,ECDHE,ECDSA,WITH,ARIA,128,GCM,SHA256), - CS_ENTRY(0xC05C, ECDHE,ECDSA,ARIA128,GCM,SHA256,,,), - CS_ENTRY(0xC05D, TLS,ECDHE,ECDSA,WITH,ARIA,256,GCM,SHA384), - CS_ENTRY(0xC05D, ECDHE,ECDSA,ARIA256,GCM,SHA384,,,), - CS_ENTRY(0xC05E, TLS,ECDH,ECDSA,WITH,ARIA,128,GCM,SHA256), - CS_ENTRY(0xC05E, ECDH,ECDSA,ARIA128,GCM,SHA256,,,), /* ns */ - CS_ENTRY(0xC05F, TLS,ECDH,ECDSA,WITH,ARIA,256,GCM,SHA384), - CS_ENTRY(0xC05F, ECDH,ECDSA,ARIA256,GCM,SHA384,,,), /* ns */ - CS_ENTRY(0xC060, TLS,ECDHE,RSA,WITH,ARIA,128,GCM,SHA256), - CS_ENTRY(0xC060, ECDHE,ARIA128,GCM,SHA256,,,,), - CS_ENTRY(0xC061, TLS,ECDHE,RSA,WITH,ARIA,256,GCM,SHA384), - CS_ENTRY(0xC061, ECDHE,ARIA256,GCM,SHA384,,,,), - CS_ENTRY(0xC062, TLS,ECDH,RSA,WITH,ARIA,128,GCM,SHA256), - CS_ENTRY(0xC062, ECDH,ARIA128,GCM,SHA256,,,,), /* ns */ - CS_ENTRY(0xC063, TLS,ECDH,RSA,WITH,ARIA,256,GCM,SHA384), - CS_ENTRY(0xC063, ECDH,ARIA256,GCM,SHA384,,,,), /* ns */ - CS_ENTRY(0xC064, TLS,PSK,WITH,ARIA,128,CBC,SHA256,), - CS_ENTRY(0xC064, PSK,ARIA128,SHA256,,,,,), /* ns */ - CS_ENTRY(0xC065, TLS,PSK,WITH,ARIA,256,CBC,SHA384,), - CS_ENTRY(0xC065, PSK,ARIA256,SHA384,,,,,), /* ns */ - CS_ENTRY(0xC066, TLS,DHE,PSK,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC066, DHE,PSK,ARIA128,SHA256,,,,), /* ns */ - CS_ENTRY(0xC067, TLS,DHE,PSK,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC067, DHE,PSK,ARIA256,SHA384,,,,), /* ns */ - CS_ENTRY(0xC068, TLS,RSA,PSK,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC068, RSA,PSK,ARIA128,SHA256,,,,), /* ns */ - CS_ENTRY(0xC069, TLS,RSA,PSK,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC069, RSA,PSK,ARIA256,SHA384,,,,), /* ns */ - CS_ENTRY(0xC06A, TLS,PSK,WITH,ARIA,128,GCM,SHA256,), - CS_ENTRY(0xC06A, PSK,ARIA128,GCM,SHA256,,,,), - CS_ENTRY(0xC06B, TLS,PSK,WITH,ARIA,256,GCM,SHA384,), - CS_ENTRY(0xC06B, PSK,ARIA256,GCM,SHA384,,,,), - CS_ENTRY(0xC06C, TLS,DHE,PSK,WITH,ARIA,128,GCM,SHA256), - CS_ENTRY(0xC06C, DHE,PSK,ARIA128,GCM,SHA256,,,), - CS_ENTRY(0xC06D, TLS,DHE,PSK,WITH,ARIA,256,GCM,SHA384), - CS_ENTRY(0xC06D, DHE,PSK,ARIA256,GCM,SHA384,,,), - CS_ENTRY(0xC06E, TLS,RSA,PSK,WITH,ARIA,128,GCM,SHA256), - CS_ENTRY(0xC06E, RSA,PSK,ARIA128,GCM,SHA256,,,), - CS_ENTRY(0xC06F, TLS,RSA,PSK,WITH,ARIA,256,GCM,SHA384), - CS_ENTRY(0xC06F, RSA,PSK,ARIA256,GCM,SHA384,,,), - CS_ENTRY(0xC070, TLS,ECDHE,PSK,WITH,ARIA,128,CBC,SHA256), - CS_ENTRY(0xC070, ECDHE,PSK,ARIA128,SHA256,,,,), /* ns */ - CS_ENTRY(0xC071, TLS,ECDHE,PSK,WITH,ARIA,256,CBC,SHA384), - CS_ENTRY(0xC071, ECDHE,PSK,ARIA256,SHA384,,,,), /* ns */ - CS_ENTRY(0xC072, TLS,ECDHE,ECDSA,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0xC072, ECDHE,ECDSA,CAMELLIA128,SHA256,,,,), - CS_ENTRY(0xC073, TLS,ECDHE,ECDSA,WITH,CAMELLIA,256,CBC,SHA384), - CS_ENTRY(0xC073, ECDHE,ECDSA,CAMELLIA256,SHA384,,,,), - CS_ENTRY(0xC074, TLS,ECDH,ECDSA,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0xC074, ECDH,ECDSA,CAMELLIA128,SHA256,,,,), /* ns */ - CS_ENTRY(0xC075, TLS,ECDH,ECDSA,WITH,CAMELLIA,256,CBC,SHA384), - CS_ENTRY(0xC075, ECDH,ECDSA,CAMELLIA256,SHA384,,,,), /* ns */ - CS_ENTRY(0xC076, TLS,ECDHE,RSA,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0xC076, ECDHE,RSA,CAMELLIA128,SHA256,,,,), - CS_ENTRY(0xC077, TLS,ECDHE,RSA,WITH,CAMELLIA,256,CBC,SHA384), - CS_ENTRY(0xC077, ECDHE,RSA,CAMELLIA256,SHA384,,,,), - CS_ENTRY(0xC078, TLS,ECDH,RSA,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0xC078, ECDH,CAMELLIA128,SHA256,,,,,), /* ns */ - CS_ENTRY(0xC079, TLS,ECDH,RSA,WITH,CAMELLIA,256,CBC,SHA384), - CS_ENTRY(0xC079, ECDH,CAMELLIA256,SHA384,,,,,), /* ns */ - CS_ENTRY(0xC07A, TLS,RSA,WITH,CAMELLIA,128,GCM,SHA256,), - CS_ENTRY(0xC07A, CAMELLIA128,GCM,SHA256,,,,,), /* ns */ - CS_ENTRY(0xC07B, TLS,RSA,WITH,CAMELLIA,256,GCM,SHA384,), - CS_ENTRY(0xC07B, CAMELLIA256,GCM,SHA384,,,,,), /* ns */ - CS_ENTRY(0xC07C, TLS,DHE,RSA,WITH,CAMELLIA,128,GCM,SHA256), - CS_ENTRY(0xC07C, DHE,RSA,CAMELLIA128,GCM,SHA256,,,), /* ns */ - CS_ENTRY(0xC07D, TLS,DHE,RSA,WITH,CAMELLIA,256,GCM,SHA384), - CS_ENTRY(0xC07D, DHE,RSA,CAMELLIA256,GCM,SHA384,,,), /* ns */ - CS_ENTRY(0xC086, TLS,ECDHE,ECDSA,WITH,CAMELLIA,128,GCM,SHA256), - CS_ENTRY(0xC086, ECDHE,ECDSA,CAMELLIA128,GCM,SHA256,,,), /* ns */ - CS_ENTRY(0xC087, TLS,ECDHE,ECDSA,WITH,CAMELLIA,256,GCM,SHA384), - CS_ENTRY(0xC087, ECDHE,ECDSA,CAMELLIA256,GCM,SHA384,,,), /* ns */ - CS_ENTRY(0xC088, TLS,ECDH,ECDSA,WITH,CAMELLIA,128,GCM,SHA256), - CS_ENTRY(0xC088, ECDH,ECDSA,CAMELLIA128,GCM,SHA256,,,), /* ns */ - CS_ENTRY(0xC089, TLS,ECDH,ECDSA,WITH,CAMELLIA,256,GCM,SHA384), - CS_ENTRY(0xC089, ECDH,ECDSA,CAMELLIA256,GCM,SHA384,,,), /* ns */ - CS_ENTRY(0xC08A, TLS,ECDHE,RSA,WITH,CAMELLIA,128,GCM,SHA256), - CS_ENTRY(0xC08A, ECDHE,CAMELLIA128,GCM,SHA256,,,,), /* ns */ - CS_ENTRY(0xC08B, TLS,ECDHE,RSA,WITH,CAMELLIA,256,GCM,SHA384), - CS_ENTRY(0xC08B, ECDHE,CAMELLIA256,GCM,SHA384,,,,), /* ns */ - CS_ENTRY(0xC08C, TLS,ECDH,RSA,WITH,CAMELLIA,128,GCM,SHA256), - CS_ENTRY(0xC08C, ECDH,CAMELLIA128,GCM,SHA256,,,,), /* ns */ - CS_ENTRY(0xC08D, TLS,ECDH,RSA,WITH,CAMELLIA,256,GCM,SHA384), - CS_ENTRY(0xC08D, ECDH,CAMELLIA256,GCM,SHA384,,,,), /* ns */ - CS_ENTRY(0xC08E, TLS,PSK,WITH,CAMELLIA,128,GCM,SHA256,), - CS_ENTRY(0xC08E, PSK,CAMELLIA128,GCM,SHA256,,,,), /* ns */ - CS_ENTRY(0xC08F, TLS,PSK,WITH,CAMELLIA,256,GCM,SHA384,), - CS_ENTRY(0xC08F, PSK,CAMELLIA256,GCM,SHA384,,,,), /* ns */ - CS_ENTRY(0xC090, TLS,DHE,PSK,WITH,CAMELLIA,128,GCM,SHA256), - CS_ENTRY(0xC090, DHE,PSK,CAMELLIA128,GCM,SHA256,,,), /* ns */ - CS_ENTRY(0xC091, TLS,DHE,PSK,WITH,CAMELLIA,256,GCM,SHA384), - CS_ENTRY(0xC091, DHE,PSK,CAMELLIA256,GCM,SHA384,,,), /* ns */ - CS_ENTRY(0xC092, TLS,RSA,PSK,WITH,CAMELLIA,128,GCM,SHA256), - CS_ENTRY(0xC092, RSA,PSK,CAMELLIA128,GCM,SHA256,,,), /* ns */ - CS_ENTRY(0xC093, TLS,RSA,PSK,WITH,CAMELLIA,256,GCM,SHA384), - CS_ENTRY(0xC093, RSA,PSK,CAMELLIA256,GCM,SHA384,,,), /* ns */ - CS_ENTRY(0xC094, TLS,PSK,WITH,CAMELLIA,128,CBC,SHA256,), - CS_ENTRY(0xC094, PSK,CAMELLIA128,SHA256,,,,,), - CS_ENTRY(0xC095, TLS,PSK,WITH,CAMELLIA,256,CBC,SHA384,), - CS_ENTRY(0xC095, PSK,CAMELLIA256,SHA384,,,,,), - CS_ENTRY(0xC096, TLS,DHE,PSK,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0xC096, DHE,PSK,CAMELLIA128,SHA256,,,,), - CS_ENTRY(0xC097, TLS,DHE,PSK,WITH,CAMELLIA,256,CBC,SHA384), - CS_ENTRY(0xC097, DHE,PSK,CAMELLIA256,SHA384,,,,), - CS_ENTRY(0xC098, TLS,RSA,PSK,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0xC098, RSA,PSK,CAMELLIA128,SHA256,,,,), - CS_ENTRY(0xC099, TLS,RSA,PSK,WITH,CAMELLIA,256,CBC,SHA384), - CS_ENTRY(0xC099, RSA,PSK,CAMELLIA256,SHA384,,,,), - CS_ENTRY(0xC09A, TLS,ECDHE,PSK,WITH,CAMELLIA,128,CBC,SHA256), - CS_ENTRY(0xC09A, ECDHE,PSK,CAMELLIA128,SHA256,,,,), - CS_ENTRY(0xC09B, TLS,ECDHE,PSK,WITH,CAMELLIA,256,CBC,SHA384), - CS_ENTRY(0xC09B, ECDHE,PSK,CAMELLIA256,SHA384,,,,), - CS_ENTRY(0xC09E, TLS,DHE,RSA,WITH,AES,128,CCM,), - CS_ENTRY(0xC09E, DHE,RSA,AES128,CCM,,,,), - CS_ENTRY(0xC09F, TLS,DHE,RSA,WITH,AES,256,CCM,), - CS_ENTRY(0xC09F, DHE,RSA,AES256,CCM,,,,), - CS_ENTRY(0xC0A2, TLS,DHE,RSA,WITH,AES,128,CCM,8), - CS_ENTRY(0xC0A2, DHE,RSA,AES128,CCM8,,,,), - CS_ENTRY(0xC0A3, TLS,DHE,RSA,WITH,AES,256,CCM,8), - CS_ENTRY(0xC0A3, DHE,RSA,AES256,CCM8,,,,), - CS_ENTRY(0xC0A4, TLS,PSK,WITH,AES,128,CCM,,), - CS_ENTRY(0xC0A4, PSK,AES128,CCM,,,,,), - CS_ENTRY(0xC0A5, TLS,PSK,WITH,AES,256,CCM,,), - CS_ENTRY(0xC0A5, PSK,AES256,CCM,,,,,), - CS_ENTRY(0xC0A6, TLS,DHE,PSK,WITH,AES,128,CCM,), - CS_ENTRY(0xC0A6, DHE,PSK,AES128,CCM,,,,), - CS_ENTRY(0xC0A7, TLS,DHE,PSK,WITH,AES,256,CCM,), - CS_ENTRY(0xC0A7, DHE,PSK,AES256,CCM,,,,), - CS_ENTRY(0xC0A8, TLS,PSK,WITH,AES,128,CCM,8,), - CS_ENTRY(0xC0A8, PSK,AES128,CCM8,,,,,), - CS_ENTRY(0xC0A9, TLS,PSK,WITH,AES,256,CCM,8,), - CS_ENTRY(0xC0A9, PSK,AES256,CCM8,,,,,), - CS_ENTRY(0xC0AA, TLS,PSK,DHE,WITH,AES,128,CCM,8), - CS_ENTRY(0xC0AA, DHE,PSK,AES128,CCM8,,,,), - CS_ENTRY(0xC0AB, TLS,PSK,DHE,WITH,AES,256,CCM,8), - CS_ENTRY(0xC0AB, DHE,PSK,AES256,CCM8,,,,), - CS_ENTRY(0xCCAA, TLS,DHE,RSA,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCAA, DHE,RSA,CHACHA20,POLY1305,,,,), - CS_ENTRY(0xCCAC, TLS,ECDHE,PSK,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCAC, ECDHE,PSK,CHACHA20,POLY1305,,,,), - CS_ENTRY(0xCCAD, TLS,DHE,PSK,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCAD, DHE,PSK,CHACHA20,POLY1305,,,,), - CS_ENTRY(0xCCAE, TLS,RSA,PSK,WITH,CHACHA20,POLY1305,SHA256,), - CS_ENTRY(0xCCAE, RSA,PSK,CHACHA20,POLY1305,,,,), -#endif -}; -#define CS_LIST_LEN CURL_ARRAYSIZE(cs_list) - -static int cs_str_to_zip(const char *cs_str, size_t cs_len, uint8_t zip[6]) -{ - uint8_t indexes[8] = { 0 }; - const char *entry, *cur; - const char *nxt = cs_str; - const char *end = cs_str + cs_len; - char separator = '-'; - int idx, i = 0; - size_t len; - - /* split the cipher string by '-' or '_' */ - if(curl_strnequal(cs_str, "TLS", 3)) - separator = '_'; - - do { - if(i == 8) - return -1; - - /* determine the length of the part */ - cur = nxt; - for(; nxt < end && *nxt != '\0' && *nxt != separator; nxt++) - ; - len = nxt - cur; - - /* lookup index for the part (skip empty string at 0) */ - for(idx = 1, entry = cs_txt + 1; idx < CS_TXT_LEN; idx++) { - size_t elen = strlen(entry); - if(elen == len && curl_strnequal(entry, cur, len)) - break; - entry += elen + 1; - } - if(idx == CS_TXT_LEN) - return -1; - - indexes[i++] = (uint8_t)idx; - } while(nxt < end && *(nxt++) != '\0'); - - /* zip the 8 indexes into 48 bits */ - zip[0] = (uint8_t)(indexes[0] << 2 | (indexes[1] & 0x3F) >> 4); - zip[1] = (uint8_t)(indexes[1] << 4 | (indexes[2] & 0x3F) >> 2); - zip[2] = (uint8_t)(indexes[2] << 6 | (indexes[3] & 0x3F)); - zip[3] = (uint8_t)(indexes[4] << 2 | (indexes[5] & 0x3F) >> 4); - zip[4] = (uint8_t)(indexes[5] << 4 | (indexes[6] & 0x3F) >> 2); - zip[5] = (uint8_t)(indexes[6] << 6 | (indexes[7] & 0x3F)); - - return 0; -} - -static int cs_zip_to_str(const uint8_t zip[6], char *buf, size_t buf_size) -{ - uint8_t indexes[8] = { 0 }; - const char *entry; - char separator = '-'; - int idx, i, r; - size_t len = 0; - - /* unzip the 8 indexes */ - indexes[0] = zip[0] >> 2; - indexes[1] = (uint8_t)(((zip[0] << 4) & 0x3F) | zip[1] >> 4); - indexes[2] = (uint8_t)(((zip[1] << 2) & 0x3F) | zip[2] >> 6); - indexes[3] = ((zip[2] << 0) & 0x3F); - indexes[4] = zip[3] >> 2; - indexes[5] = (uint8_t)(((zip[3] << 4) & 0x3F) | zip[4] >> 4); - indexes[6] = (uint8_t)(((zip[4] << 2) & 0x3F) | zip[5] >> 6); - indexes[7] = ((zip[5] << 0) & 0x3F); - - if(indexes[0] == CS_TXT_IDX_TLS) - separator = '_'; - - for(i = 0; i < 8 && indexes[i] != 0 && len < buf_size; i++) { - if(indexes[i] >= CS_TXT_LEN) - return -1; - - /* lookup the part string for the index (skip empty string at 0) */ - for(idx = 1, entry = cs_txt + 1; idx < indexes[i]; idx++) { - size_t elen = strlen(entry); - entry += elen + 1; - } - - /* append the part string to the buffer */ - if(i > 0) - r = curl_msnprintf(&buf[len], buf_size - len, "%c%s", separator, entry); - else - r = curl_msnprintf(&buf[len], buf_size - len, "%s", entry); - - if(r < 0) - return -1; - len += r; - } - - return 0; -} - -uint16_t Curl_cipher_suite_lookup_id(const char *cs_str, size_t cs_len) -{ - size_t i; - uint8_t zip[6]; - - if(cs_len > 0 && cs_str_to_zip(cs_str, cs_len, zip) == 0) { - for(i = 0; i < CS_LIST_LEN; i++) { - if(memcmp(cs_list[i].zip, zip, sizeof(zip)) == 0) - return cs_list[i].id; - } - } - - return 0; -} - -static bool cs_is_separator(char c) -{ - switch(c) { - case ' ': - case '\t': - case ':': - case ',': - case ';': - return TRUE; - } - return FALSE; -} - -uint16_t Curl_cipher_suite_walk_str(const char **str, const char **end) -{ - /* move string pointer to first non-separator or end of string */ - for(; cs_is_separator(*str[0]); (*str)++) - ; - - /* move end pointer to next separator or end of string */ - for(*end = *str; *end[0] != '\0' && !cs_is_separator(*end[0]); (*end)++) - ; - - return Curl_cipher_suite_lookup_id(*str, *end - *str); -} - -int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, - bool prefer_rfc) -{ - size_t i, j = CS_LIST_LEN; - int r = -1; - - for(i = 0; i < CS_LIST_LEN; i++) { - if(cs_list[i].id != id) - continue; - if((cs_list[i].zip[0] >> 2 != CS_TXT_IDX_TLS) == !prefer_rfc) { - j = i; - break; - } - if(j == CS_LIST_LEN) - j = i; - } - - if(j < CS_LIST_LEN) - r = cs_zip_to_str(cs_list[j].zip, buf, buf_size); - - if(r < 0) - curl_msnprintf(buf, buf_size, "TLS_UNKNOWN_0x%04x", id); - - return r; -} - -#endif /* defined(USE_MBEDTLS) || defined(USE_RUSTLS) */ diff --git a/vendor/curl/lib/vtls/cipher_suite.h b/vendor/curl/lib/vtls/cipher_suite.h deleted file mode 100644 index 0e185e351..000000000 --- a/vendor/curl/lib/vtls/cipher_suite.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef HEADER_CURL_CIPHER_SUITE_H -#define HEADER_CURL_CIPHER_SUITE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Jan Venekamp, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_MBEDTLS) || defined(USE_RUSTLS) - -/* Lookup IANA id for cipher suite string, returns 0 if not recognized */ -uint16_t Curl_cipher_suite_lookup_id(const char *cs_str, size_t cs_len); - -/* Walk over cipher suite string, update str and end pointers to next - cipher suite in string, returns IANA id of that suite if recognized */ -uint16_t Curl_cipher_suite_walk_str(const char **str, const char **end); - -/* Copy openssl or RFC name for cipher suite in supplied buffer. - Caller is responsible to supply sufficiently large buffer (size - of 64 should suffice), excess bytes are silently truncated. */ -int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, - bool prefer_rfc); - -#endif /* defined(USE_MBEDTLS) || defined(USE_RUSTLS) */ -#endif /* HEADER_CURL_CIPHER_SUITE_H */ diff --git a/vendor/curl/lib/vtls/gtls.c b/vendor/curl/lib/vtls/gtls.c deleted file mode 100644 index 9b6a4fab2..000000000 --- a/vendor/curl/lib/vtls/gtls.c +++ /dev/null @@ -1,2319 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - * Note: do not use the GnuTLS' *_t variable type names in this source code, - * since they were not present in 1.0.X. - */ -#include "curl_setup.h" - -#ifdef USE_GNUTLS - -#include -#include -#include -#include -#include - -#include "urldata.h" -#include "curl_trc.h" -#include "vtls/keylog.h" -#include "vtls/gtls.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" -#include "vtls/vtls_scache.h" -#include "vtls/apple.h" -#include "vauth/vauth.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "progress.h" -#include "curlx/strdup.h" -#include "curlx/fopen.h" -#include "vtls/x509asn1.h" - -/* Enable GnuTLS debugging by defining GTLSDEBUG */ -#if 0 -#define GTLSDEBUG -#endif - -#ifdef GTLSDEBUG -static void tls_log_func(int level, const char *str) -{ - curl_mfprintf(stderr, "|<%d>| %s", level, str); -} -#endif - -#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x030605) -#error "too old GnuTLS version" -#endif - -#undef CURL_GNUTLS_EARLY_DATA -#if GNUTLS_VERSION_NUMBER >= 0x03060d -#define CURL_GNUTLS_EARLY_DATA -#endif - -#include - -struct gtls_ssl_backend_data { - struct gtls_ctx gtls; -}; - -static ssize_t gtls_push(void *s, const void *buf, size_t blen) -{ - struct Curl_cfilter *cf = s; - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nwritten; - CURLcode result; - - DEBUGASSERT(data); - result = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &nwritten); - CURL_TRC_CF(data, cf, "gtls_push(len=%zu) -> %d, %zu", - blen, result, nwritten); - backend->gtls.io_result = result; - if(result) { - /* !checksrc! disable ERRNOVAR 1 */ - gnutls_transport_set_errno(backend->gtls.session, - (result == CURLE_AGAIN) ? EAGAIN : EINVAL); - return -1; - } - return (ssize_t)nwritten; -} - -static ssize_t gtls_pull(void *s, void *buf, size_t blen) -{ - struct Curl_cfilter *cf = s; - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nread; - CURLcode result; - - DEBUGASSERT(data); - if(!backend->gtls.shared_creds->trust_setup) { - result = Curl_gtls_client_trust_setup(cf, data, &backend->gtls); - if(result) { - /* !checksrc! disable ERRNOVAR 1 */ - gnutls_transport_set_errno(backend->gtls.session, EINVAL); - backend->gtls.io_result = result; - return -1; - } - } - - result = Curl_conn_cf_recv(cf->next, data, buf, blen, &nread); - CURL_TRC_CF(data, cf, "glts_pull(len=%zu) -> %d, %zu", blen, result, nread); - backend->gtls.io_result = result; - if(result) { - /* !checksrc! disable ERRNOVAR 1 */ - gnutls_transport_set_errno(backend->gtls.session, - (result == CURLE_AGAIN) ? EAGAIN : EINVAL); - return -1; - } - else if(nread == 0) - connssl->peer_closed = TRUE; - return (ssize_t)nread; -} - -/** - * gtls_init() - * - * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that - * are not thread-safe (It is thread-safe since GnuTLS 3.3.0) and thus this - * function itself is not thread-safe and must only be called from within - * curl_global_init() to keep the thread situation under control! - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ -static int gtls_init(void) -{ - int ret = 1; - ret = gnutls_global_init() ? 0 : 1; -#ifdef GTLSDEBUG - gnutls_global_set_log_function(tls_log_func); - gnutls_global_set_log_level(2); -#endif - return ret; -} - -static void gtls_cleanup(void) -{ - gnutls_global_deinit(); - Curl_tls_keylog_close(); -} - -#ifdef CURLVERBOSE -static void showtime(struct Curl_easy *data, const char *text, time_t stamp) -{ - struct tm buffer; - const struct tm *tm = &buffer; - char str[96]; - CURLcode result = curlx_gmtime(stamp, &buffer); - if(result) - return; - - curl_msnprintf(str, - sizeof(str), - " %s: %s, %02d %s %4d %02d:%02d:%02d GMT", - text, - Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - infof(data, "%s", str); -} -#endif - -static gnutls_datum_t load_file(const char *file) -{ - FILE *f; - gnutls_datum_t loaded_file = { NULL, 0 }; - long filelen; - void *ptr; - - f = curlx_fopen(file, "rb"); - if(!f) - return loaded_file; - if(fseek(f, 0, SEEK_END) != 0) - goto out; - filelen = ftell(f); - if(filelen < 0 || filelen > CURL_MAX_INPUT_LENGTH) - goto out; - if(fseek(f, 0, SEEK_SET) != 0) - goto out; - ptr = curlx_malloc((size_t)filelen); - if(!ptr) - goto out; - if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) { - curlx_free(ptr); - goto out; - } - - loaded_file.data = ptr; - loaded_file.size = (unsigned int)filelen; -out: - curlx_fclose(f); - return loaded_file; -} - -static void unload_file(gnutls_datum_t data) -{ - curlx_free(data.data); -} - -/* this function does an SSL/TLS (re-)handshake */ -static CURLcode cf_gtls_handshake(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - gnutls_session_t session; - int rc; - - DEBUGASSERT(backend); - session = backend->gtls.session; - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - backend->gtls.io_result = CURLE_OK; - rc = gnutls_handshake(session); - - if(!backend->gtls.shared_creds->trust_setup) { - /* After having send off the ClientHello, we prepare the trust - * store to verify the coming certificate from the server */ - CURLcode result = Curl_gtls_client_trust_setup(cf, data, &backend->gtls); - if(result) - return result; - } - - if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) { - connssl->io_need = - gnutls_record_get_direction(session) ? - CURL_SSL_IO_NEED_SEND : CURL_SSL_IO_NEED_RECV; - return CURLE_AGAIN; - } - else if((rc < 0) && !gnutls_error_is_fatal(rc)) { -#ifdef CURLVERBOSE - const char *strerr = NULL; - - if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) { - gnutls_alert_description_t alert = gnutls_alert_get(session); - strerr = gnutls_alert_get_name(alert); - } - - if(!strerr) - strerr = gnutls_strerror(rc); - - infof(data, "gnutls_handshake() warning: %s", strerr); -#endif - return CURLE_AGAIN; - } - else if((rc < 0) && backend->gtls.io_result) { - return backend->gtls.io_result; - } - else if(rc < 0) { - const char *strerr = NULL; - - if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) { - gnutls_alert_description_t alert = gnutls_alert_get(session); - strerr = gnutls_alert_get_name(alert); - } - - if(!strerr) - strerr = gnutls_strerror(rc); - - failf(data, "GnuTLS, handshake failed: %s", strerr); - return CURLE_SSL_CONNECT_ERROR; - } - - return CURLE_OK; -} - -static gnutls_x509_crt_fmt_t gnutls_do_file_type(const char *type) -{ - if(!type || !type[0]) - return GNUTLS_X509_FMT_PEM; - if(curl_strequal(type, "PEM")) - return GNUTLS_X509_FMT_PEM; - if(curl_strequal(type, "DER")) - return GNUTLS_X509_FMT_DER; - return GNUTLS_X509_FMT_PEM; /* default to PEM */ -} - -#define GNUTLS_CIPHERS "NORMAL:%PROFILE_MEDIUM:-ARCFOUR-128:" \ - "-CTYPE-ALL:+CTYPE-X509" -/* If GnuTLS was compiled without support for SRP it errors out if SRP is - requested in the priority string, so treat it specially - */ -#define GNUTLS_SRP "+SRP" - -#define QUIC_PRIORITY \ - "NORMAL:%PROFILE_MEDIUM:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:" \ - "+AES-256-GCM:+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:" \ - "+GROUP-SECP256R1:+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \ - "%DISABLE_TLS13_COMPAT_MODE" - -static CURLcode -gnutls_set_ssl_version_min_max(struct Curl_easy *data, - struct ssl_peer *peer, - struct ssl_primary_config *conn_config, - const char **prioritylist, - bool tls13support) -{ - long ssl_version = conn_config->version; - long ssl_version_max = conn_config->version_max; - - DEBUGASSERT(ssl_version != CURL_SSLVERSION_DEFAULT); - if(ssl_version <= CURL_SSLVERSION_TLSv1) - ssl_version = CURL_SSLVERSION_TLSv1_0; - if((ssl_version_max == CURL_SSLVERSION_MAX_NONE) || - (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) - ssl_version_max = tls13support ? - CURL_SSLVERSION_MAX_TLSv1_3 : CURL_SSLVERSION_MAX_TLSv1_2; - - if(peer->transport == TRNSPRT_QUIC) { - if(ssl_version_max < CURL_SSLVERSION_MAX_TLSv1_3) { - failf(data, "QUIC needs at least TLS version 1.3"); - return CURLE_SSL_CONNECT_ERROR; - } - *prioritylist = QUIC_PRIORITY; - return CURLE_OK; - } - - switch(ssl_version | ssl_version_max) { - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1:+VERS-TLS1.0"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2:+VERS-TLS1.1"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.3"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_3: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_3: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_3: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.3:+VERS-TLS1.2"; - return CURLE_OK; - } - - failf(data, "GnuTLS: cannot set TLS protocol"); - return CURLE_SSL_CONNECT_ERROR; -} - -CURLcode Curl_gtls_shared_creds_create(struct Curl_easy *data, - struct gtls_shared_creds **pcreds) -{ - struct gtls_shared_creds *shared; - int rc; - - *pcreds = NULL; - shared = curlx_calloc(1, sizeof(*shared)); - if(!shared) - return CURLE_OUT_OF_MEMORY; - - rc = gnutls_certificate_allocate_credentials(&shared->creds); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc)); - curlx_free(shared); - return CURLE_SSL_CONNECT_ERROR; - } - - shared->refcount = 1; - shared->time = *Curl_pgrs_now(data); - *pcreds = shared; - return CURLE_OK; -} - -CURLcode Curl_gtls_shared_creds_up_ref(struct gtls_shared_creds *creds) -{ - DEBUGASSERT(creds); - if(creds->refcount < SIZE_MAX) { - ++creds->refcount; - return CURLE_OK; - } - return CURLE_BAD_FUNCTION_ARGUMENT; -} - -void Curl_gtls_shared_creds_free(struct gtls_shared_creds **pcreds) -{ - struct gtls_shared_creds *shared = *pcreds; - *pcreds = NULL; - if(shared) { - --shared->refcount; - if(!shared->refcount) { - gnutls_certificate_free_credentials(shared->creds); - curlx_free(shared->CAfile); - curlx_free(shared); - } - } -} - -static CURLcode gtls_populate_creds(struct Curl_cfilter *cf, - struct Curl_easy *data, - gnutls_certificate_credentials_t creds) -{ - struct ssl_primary_config *config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - bool creds_are_empty = TRUE; - int rc; - - if(!config->verifypeer) { - infof(data, "SSL Trust: peer verification disabled"); - return CURLE_OK; - } - - infof(data, "SSL Trust Anchors:"); - if(ssl_config->native_ca_store) { -#ifdef USE_APPLE_SECTRUST - infof(data, " Native: Apple SecTrust"); - creds_are_empty = FALSE; -#else - rc = gnutls_certificate_set_x509_system_trust(creds); - if(rc < 0) - infof(data, "error reading native CA store (%s), continuing anyway", - gnutls_strerror(rc)); - else { - infof(data, " Native: %d certificates from system trust", rc); - if(rc > 0) - creds_are_empty = FALSE; - } -#endif - } - - if(config->ca_info_blob) { - gnutls_datum_t ca_info_datum; - if(config->ca_info_blob->len > (size_t)UINT_MAX) { - failf(data, "certificate blob too long: %zu bytes", - config->ca_info_blob->len); - return CURLE_SSL_CACERT_BADFILE; - } - ca_info_datum.data = config->ca_info_blob->data; - ca_info_datum.size = (unsigned int)config->ca_info_blob->len; - rc = gnutls_certificate_set_x509_trust_mem(creds, &ca_info_datum, - GNUTLS_X509_FMT_PEM); - creds_are_empty = creds_are_empty && (rc <= 0); - if(rc < 0) { - infof(data, "error reading CA cert blob (%s)%s", gnutls_strerror(rc), - (creds_are_empty ? "" : ", continuing anyway")); - if(creds_are_empty) { - ssl_config->certverifyresult = rc; - return CURLE_SSL_CACERT_BADFILE; - } - } - else - infof(data, " CA Blob: %d certificates", rc); - } - /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - else if(config->CAfile) { - /* set the trusted CA cert bundle file */ - gnutls_certificate_set_verify_flags(creds, - GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); - - rc = gnutls_certificate_set_x509_trust_file(creds, - config->CAfile, - GNUTLS_X509_FMT_PEM); - creds_are_empty = creds_are_empty && (rc <= 0); - if(rc < 0) { - infof(data, "error reading CA cert file %s (%s)%s", - config->CAfile, gnutls_strerror(rc), - (creds_are_empty ? "" : ", continuing anyway")); - if(creds_are_empty) { - ssl_config->certverifyresult = rc; - return CURLE_SSL_CACERT_BADFILE; - } - } - else - infof(data, " CAfile: %d certificates in %s", rc, config->CAfile); - } - - if(config->CApath) { - /* set the trusted CA cert directory */ - rc = gnutls_certificate_set_x509_trust_dir(creds, config->CApath, - GNUTLS_X509_FMT_PEM); - creds_are_empty = creds_are_empty && (rc <= 0); - if(rc < 0) { - infof(data, "error reading CA cert file %s (%s)%s", - config->CApath, gnutls_strerror(rc), - (creds_are_empty ? "" : ", continuing anyway")); - if(creds_are_empty) { - ssl_config->certverifyresult = rc; - return CURLE_SSL_CACERT_BADFILE; - } - } - else - infof(data, " CApath: %d certificates in %s", rc, config->CApath); - } - - if(creds_are_empty) - infof(data, " no trust anchors configured"); - - if(config->CRLfile) { - /* set the CRL list file */ - rc = gnutls_certificate_set_x509_crl_file(creds, config->CRLfile, - GNUTLS_X509_FMT_PEM); - if(rc < 0) { - failf(data, "error reading CRL file %s (%s)", - config->CRLfile, gnutls_strerror(rc)); - return CURLE_SSL_CRL_BADFILE; - } - else - infof(data, " CRLfile: %d CRL in %s", rc, config->CRLfile); - } - - return CURLE_OK; -} - -/* key to use at `multi->proto_hash` */ -#define MPROTO_GTLS_X509_KEY "tls:gtls:x509:share" - -static bool gtls_shared_creds_expired(struct Curl_easy *data, - const struct gtls_shared_creds *sc) -{ - const struct ssl_general_config *cfg = &data->set.general_ssl; - timediff_t elapsed_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &sc->time); - timediff_t timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000; - - if(timeout_ms < 0) - return FALSE; - - return elapsed_ms >= timeout_ms; -} - -static bool gtls_shared_creds_different(struct Curl_cfilter *cf, - const struct gtls_shared_creds *sc) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - if(!sc->CAfile || !conn_config->CAfile) - return sc->CAfile != conn_config->CAfile; - - return strcmp(sc->CAfile, conn_config->CAfile); -} - -static struct gtls_shared_creds *gtls_get_cached_creds(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct gtls_shared_creds *shared_creds; - - if(data->multi) { - shared_creds = Curl_hash_pick(&data->multi->proto_hash, - CURL_UNCONST(MPROTO_GTLS_X509_KEY), - sizeof(MPROTO_GTLS_X509_KEY) - 1); - if(shared_creds && shared_creds->creds && - !gtls_shared_creds_expired(data, shared_creds) && - !gtls_shared_creds_different(cf, shared_creds)) { - return shared_creds; - } - } - return NULL; -} - -static void gtls_shared_creds_hash_free(void *key, size_t key_len, void *p) -{ - struct gtls_shared_creds *sc = p; - DEBUGASSERT(key_len == (sizeof(MPROTO_GTLS_X509_KEY) - 1)); - DEBUGASSERT(!memcmp(MPROTO_GTLS_X509_KEY, key, key_len)); - (void)key; - (void)key_len; - Curl_gtls_shared_creds_free(&sc); /* down reference */ -} - -static void gtls_set_cached_creds(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct gtls_shared_creds *sc) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - - DEBUGASSERT(sc); - DEBUGASSERT(sc->creds); - DEBUGASSERT(!sc->CAfile); - DEBUGASSERT(sc->refcount == 1); - if(!data->multi) - return; - - if(conn_config->CAfile) { - sc->CAfile = curlx_strdup(conn_config->CAfile); - if(!sc->CAfile) - return; - } - - if(Curl_gtls_shared_creds_up_ref(sc)) - return; - - if(!Curl_hash_add2(&data->multi->proto_hash, - CURL_UNCONST(MPROTO_GTLS_X509_KEY), - sizeof(MPROTO_GTLS_X509_KEY) - 1, - sc, gtls_shared_creds_hash_free)) { - Curl_gtls_shared_creds_free(&sc); /* down reference again */ - return; - } -} - -CURLcode Curl_gtls_client_trust_setup(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct gtls_ctx *gtls) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - struct gtls_shared_creds *cached_creds = NULL; - bool cache_criteria_met; - CURLcode result; - int rc; - - /* Consider the X509 store cacheable if it comes exclusively from a CAfile, - or no source is provided and we are falling back to OpenSSL's built-in - default. */ - cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) && - conn_config->verifypeer && - !conn_config->CApath && - !conn_config->ca_info_blob && - !ssl_config->primary.CRLfile && - !ssl_config->native_ca_store && - !conn_config->clientcert; /* GnuTLS adds client cert to its credentials! */ - - if(cache_criteria_met) - cached_creds = gtls_get_cached_creds(cf, data); - - if(cached_creds && !Curl_gtls_shared_creds_up_ref(cached_creds)) { - CURL_TRC_CF(data, cf, "using shared trust anchors and CRLs"); - Curl_gtls_shared_creds_free(>ls->shared_creds); - gtls->shared_creds = cached_creds; - rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_CERTIFICATE, - gtls->shared_creds->creds); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { - CURL_TRC_CF(data, cf, "loading trust anchors and CRLs"); - result = gtls_populate_creds(cf, data, gtls->shared_creds->creds); - if(result) - return result; - gtls->shared_creds->trust_setup = TRUE; - if(cache_criteria_met) - gtls_set_cached_creds(cf, data, gtls->shared_creds); - } - return CURLE_OK; -} - -#ifdef CURL_GNUTLS_EARLY_DATA -CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - gnutls_session_t session, - curl_off_t valid_until, - const char *alpn, - unsigned char *quic_tp, - size_t quic_tp_len) -{ - struct Curl_ssl_session *sc_session; - unsigned char *sdata, *qtp_clone = NULL; - size_t sdata_len = 0; - size_t earlydata_max = 0; - CURLcode result = CURLE_OK; - - if(!Curl_ssl_scache_use(cf, data)) - return CURLE_OK; - - /* we always unconditionally get the session id here, as even if we - already got it from the cache and asked to use it in the connection, it - might have been rejected and then a new one is in use now and we need to - detect that. */ - - /* get the session ID data size */ - gnutls_session_get_data(session, NULL, &sdata_len); - if(!sdata_len) /* GnuTLS does this for some version combinations */ - return CURLE_OK; - - sdata = curlx_malloc(sdata_len); /* get a buffer for it */ - if(!sdata) - return CURLE_OUT_OF_MEMORY; - - /* extract session ID to the allocated buffer */ - gnutls_session_get_data(session, sdata, &sdata_len); - earlydata_max = gnutls_record_get_max_early_data_size(session); - - CURL_TRC_CF(data, cf, "get session id (len=%zu, alpn=%s, earlymax=%zu) " - "and store in cache", sdata_len, alpn ? alpn : "-", - earlydata_max); - if(quic_tp && quic_tp_len) { - qtp_clone = curlx_memdup0((const char *)quic_tp, quic_tp_len); - if(!qtp_clone) { - curlx_free(sdata); - return CURLE_OUT_OF_MEMORY; - } - } - - result = Curl_ssl_session_create2(sdata, sdata_len, - Curl_glts_get_ietf_proto(session), - alpn, valid_until, earlydata_max, - qtp_clone, quic_tp_len, - &sc_session); - /* call took ownership of `sdata` and `qtp_clone` */ - if(!result) { - result = Curl_ssl_scache_put(cf, data, ssl_peer_key, sc_session); - /* took ownership of `sc_session` */ - } - return result; -} -#endif - -int Curl_glts_get_ietf_proto(gnutls_session_t session) -{ - switch(gnutls_protocol_get_version(session)) { - case GNUTLS_SSL3: - return CURL_IETF_PROTO_SSL3; - case GNUTLS_TLS1_0: - return CURL_IETF_PROTO_TLS1; - case GNUTLS_TLS1_1: - return CURL_IETF_PROTO_TLS1_1; - case GNUTLS_TLS1_2: - return CURL_IETF_PROTO_TLS1_2; - case GNUTLS_TLS1_3: - return CURL_IETF_PROTO_TLS1_3; - default: - return CURL_IETF_PROTO_UNKNOWN; - } -} - -#ifdef CURL_GNUTLS_EARLY_DATA -static CURLcode cf_gtls_update_session_id(struct Curl_cfilter *cf, - struct Curl_easy *data, - gnutls_session_t session) -{ - struct ssl_connect_data *connssl = cf->ctx; - return Curl_gtls_cache_session(cf, data, connssl->peer.scache_key, - session, 0, connssl->negotiated.alpn, - NULL, 0); -} - -static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype, - unsigned when, unsigned int incoming, - const gnutls_datum_t *msg) -{ - struct Curl_cfilter *cf = gnutls_session_get_ptr(session); - - (void)msg; - (void)incoming; - if(when) { /* after message has been processed */ - struct Curl_easy *data = CF_DATA_CURRENT(cf); - if(data) { - CURL_TRC_CF(data, cf, "handshake: %s message type %u", - incoming ? "incoming" : "outgoing", htype); - switch(htype) { - case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: { - cf_gtls_update_session_id(cf, data, session); - break; - } - default: - break; - } - } - } - return 0; -} -#endif - -static CURLcode gtls_set_priority(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct gtls_ctx *gtls, - const char *priority) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct dynbuf buf; - const char *err = NULL; - CURLcode result = CURLE_OK; - int rc; - - curlx_dyn_init(&buf, 4096); - -#ifdef USE_GNUTLS_SRP - if(conn_config->username) { - /* Only add SRP to the cipher list if SRP is requested. Otherwise - * GnuTLS disables TLS 1.3 support. */ - result = curlx_dyn_add(&buf, priority); - if(!result) - result = curlx_dyn_add(&buf, ":" GNUTLS_SRP); - if(result) - goto out; - priority = curlx_dyn_ptr(&buf); - } -#endif - - if(conn_config->cipher_list) { - if((conn_config->cipher_list[0] == '+') || - (conn_config->cipher_list[0] == '-') || - (conn_config->cipher_list[0] == '!')) { - /* add it to out own */ - if(!curlx_dyn_len(&buf)) { /* not added yet */ - result = curlx_dyn_add(&buf, priority); - if(result) - goto out; - } - result = curlx_dyn_addf(&buf, ":%s", conn_config->cipher_list); - if(result) - goto out; - priority = curlx_dyn_ptr(&buf); - } - else /* replace our own completely */ - priority = conn_config->cipher_list; - } - - infof(data, "GnuTLS priority: %s", priority); - rc = gnutls_priority_set_direct(gtls->session, priority, &err); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "Error %d setting GnuTLS priority: %s", rc, err); - result = CURLE_SSL_CONNECT_ERROR; - } - -out: - curlx_dyn_free(&buf); - return result; -} - -static CURLcode gtls_client_init(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - size_t earlydata_max, - struct gtls_ctx *gtls) -{ - struct ssl_primary_config *config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - unsigned int init_flags; - int rc; - const char *prioritylist; - bool tls13support; - CURLcode result; - - if(config->version == CURL_SSLVERSION_SSLv2 || - config->version == CURL_SSLVERSION_SSLv3) { - failf(data, "GnuTLS does not support SSLv2 or SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - - /* allocate a shared creds struct */ - result = Curl_gtls_shared_creds_create(data, >ls->shared_creds); - if(result) - return result; - -#ifdef USE_GNUTLS_SRP - if(config->username && Curl_auth_allowed_to_host(data)) { - infof(data, "Using TLS-SRP username: %s", config->username); - - rc = gnutls_srp_allocate_client_credentials(>ls->srp_client_cred); - if(rc == GNUTLS_E_UNIMPLEMENTED_FEATURE) { - failf(data, "GnuTLS: TLS-SRP support not built in: %s", - gnutls_strerror(rc)); - return CURLE_NOT_BUILT_IN; - } - else if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_srp_allocate_client_cred() failed: %s", - gnutls_strerror(rc)); - return CURLE_OUT_OF_MEMORY; - } - - rc = gnutls_srp_set_client_credentials(gtls->srp_client_cred, - config->username, - config->password); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_srp_set_client_cred() failed: %s", - gnutls_strerror(rc)); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } -#endif - - ssl_config->certverifyresult = 0; - - /* Initialize TLS session as a client */ - init_flags = GNUTLS_CLIENT; -#ifdef CURL_GNUTLS_EARLY_DATA - if(peer->transport == TRNSPRT_QUIC && earlydata_max > 0) - init_flags |= GNUTLS_ENABLE_EARLY_DATA | GNUTLS_NO_END_OF_EARLY_DATA; - else if(earlydata_max > 0 && earlydata_max != 0xFFFFFFFFUL) - /* See https://gitlab.com/gnutls/gnutls/-/issues/1619 - * We cannot differentiate between a session announcing no earldata - * and one announcing 0xFFFFFFFFUL. On TCP+TLS, this is unlikely, but - * on QUIC this is common. */ - init_flags |= GNUTLS_ENABLE_EARLY_DATA; -#endif - -#ifdef GNUTLS_FORCE_CLIENT_CERT - init_flags |= GNUTLS_FORCE_CLIENT_CERT; -#endif - -#ifdef GNUTLS_NO_TICKETS_TLS12 - init_flags |= GNUTLS_NO_TICKETS_TLS12; -#endif - -#ifdef GNUTLS_NO_STATUS_REQUEST - if(!config->verifystatus) - /* Disable the "status_request" TLS extension, enabled by default since - GnuTLS 3.8.0. */ - init_flags |= GNUTLS_NO_STATUS_REQUEST; -#endif - - CURL_TRC_CF(data, cf, "gnutls_init(flags=%x), earlydata=%zu", - init_flags, earlydata_max); - rc = gnutls_init(>ls->session, init_flags); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_init() failed: %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - - if(peer->sni) { - if(gnutls_server_name_set(gtls->session, GNUTLS_NAME_DNS, - peer->sni, strlen(peer->sni)) < 0) { - failf(data, "Failed to set SNI"); - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* Use default priorities */ - rc = gnutls_set_default_priority(gtls->session); - if(rc != GNUTLS_E_SUCCESS) - return CURLE_SSL_CONNECT_ERROR; - - /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ - tls13support = !!gnutls_check_version("3.6.5"); - - if(config->version == CURL_SSLVERSION_TLSv1_3) { - if(!tls13support) { - failf(data, "This GnuTLS installation does not support TLS 1.3"); - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* At this point we know we have a supported TLS version, so set it */ - result = gnutls_set_ssl_version_min_max(data, peer, - config, &prioritylist, tls13support); - if(result) - return result; - - result = gtls_set_priority(cf, data, gtls, prioritylist); - if(result) - return result; - - if(config->clientcert) { - if(!gtls->shared_creds->trust_setup) { - result = Curl_gtls_client_trust_setup(cf, data, gtls); - if(result) - return result; - } - if(ssl_config->cert_type && curl_strequal(ssl_config->cert_type, "P12")) { - rc = gnutls_certificate_set_x509_simple_pkcs12_file( - gtls->shared_creds->creds, config->clientcert, GNUTLS_X509_FMT_DER, - ssl_config->key_passwd ? ssl_config->key_passwd : ""); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, - "error reading X.509 potentially-encrypted key or certificate " - "file: %s", - gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { - const unsigned int supported_key_encryption_algorithms = - GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR | - GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES | - GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 | - GNUTLS_PKCS_USE_PBES2_AES_256; - rc = gnutls_certificate_set_x509_key_file2( - gtls->shared_creds->creds, - config->clientcert, - ssl_config->key ? ssl_config->key : config->clientcert, - gnutls_do_file_type(ssl_config->cert_type), - ssl_config->key_passwd, - supported_key_encryption_algorithms); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, - "error reading X.509 %skey file: %s", - ssl_config->key_passwd ? "potentially-encrypted " : "", - gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - } - -#ifdef USE_GNUTLS_SRP - /* put the credentials to the current session */ - if(config->username) { - rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_SRP, - gtls->srp_client_cred); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - else -#endif - { - rc = gnutls_credentials_set(gtls->session, GNUTLS_CRD_CERTIFICATE, - gtls->shared_creds->creds); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - - if(config->verifystatus) { - rc = gnutls_ocsp_status_request_enable_client(gtls->session, - NULL, 0, NULL); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - } - - return CURLE_OK; -} - -#ifdef CURL_GNUTLS_EARLY_DATA -static int keylog_callback(gnutls_session_t session, const char *label, - const gnutls_datum_t *secret) -{ - gnutls_datum_t crandom; - gnutls_datum_t srandom; - - gnutls_session_get_random(session, &crandom, &srandom); - if(crandom.size != 32) { - return -1; - } - - Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size); - return 0; -} - -static CURLcode gtls_on_session_reuse(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - - connssl->earlydata_max = - gnutls_record_get_max_early_data_size(backend->gtls.session); - - /* Seems to be no GnuTLS way to signal no EarlyData in session */ - return Curl_on_session_reuse(cf, data, alpns, scs, do_early_data, - connssl->earlydata_max && - connssl->earlydata_max != 0xFFFFFFFFUL); -} -#endif - -CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - Curl_gtls_ctx_setup_cb *cb_setup, - void *cb_user_data, - void *ssl_user_data, - Curl_gtls_init_session_reuse_cb *sess_reuse_cb) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - struct Curl_ssl_session *scs = NULL; - gnutls_datum_t gtls_alpns[ALPN_ENTRIES_MAX]; - size_t gtls_alpns_count = 0; - bool gtls_session_setup = FALSE; - struct alpn_spec alpns; - CURLcode result = CURLE_OK; - int rc; - - DEBUGASSERT(gctx); - Curl_alpn_copy(&alpns, alpns_requested); - - /* This might be a reconnect, so we check for a session ID in the cache - to speed up things. We need to do this before constructing the GnuTLS - session since we need to set flags depending on the kind of reuse. */ - if(conn_config->cache_session && !conn_config->verifystatus) { - result = Curl_ssl_scache_take(cf, data, peer->scache_key, &scs); - if(result) - goto out; - - if(scs && scs->sdata && scs->sdata_len && - (!scs->alpn || Curl_alpn_contains_proto(&alpns, scs->alpn))) { - /* we got a cached session, use it! */ - - result = gtls_client_init(cf, data, peer, scs->earlydata_max, gctx); - if(result) - goto out; - gtls_session_setup = TRUE; - - rc = gnutls_session_set_data(gctx->session, scs->sdata, scs->sdata_len); - if(rc < 0) - infof(data, "SSL session not accepted by GnuTLS, continuing without"); - else { - infof(data, "SSL reusing session with ALPN '%s'", - scs->alpn ? scs->alpn : "-"); - if(ssl_config->earlydata && scs->alpn && - !cf->conn->bits.connect_only) { - bool do_early_data = FALSE; - if(sess_reuse_cb) { - result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data); - if(result) - goto out; - } - if(do_early_data) { - /* We only try the ALPN protocol the session used before, - * otherwise we might send early data for the wrong protocol */ - Curl_alpn_restrict_to(&alpns, scs->alpn); - } - } - } - } - } - - if(!gtls_session_setup) { - result = gtls_client_init(cf, data, peer, 0, gctx); - if(result) - goto out; - } - - gnutls_session_set_ptr(gctx->session, ssl_user_data); - - if(cb_setup) { - result = cb_setup(cf, data, cb_user_data); - if(result) - goto out; - } - -#ifdef CURL_GNUTLS_EARLY_DATA - /* Open the file if a TLS or QUIC backend has not done this before. */ - Curl_tls_keylog_open(); - if(Curl_tls_keylog_enabled()) { - gnutls_session_set_keylog_function(gctx->session, keylog_callback); - } -#endif - - /* convert the ALPN string from our arguments to a list of strings that - * GnuTLS wants and does convert internally back to this string for sending - * to the server. nice. */ - if(!gtls_alpns_count && alpns.count) { - size_t i; - DEBUGASSERT(CURL_ARRAYSIZE(gtls_alpns) >= alpns.count); - for(i = 0; i < alpns.count; ++i) { - gtls_alpns[i].data = (unsigned char *)alpns.entries[i]; - gtls_alpns[i].size = (unsigned int)strlen(alpns.entries[i]); - } - gtls_alpns_count = alpns.count; - } - - if(gtls_alpns_count && - gnutls_alpn_set_protocols(gctx->session, - gtls_alpns, (unsigned int)gtls_alpns_count, - GNUTLS_ALPN_MANDATORY)) { - failf(data, "failed setting ALPN"); - result = CURLE_SSL_CONNECT_ERROR; - } - -out: - Curl_ssl_scache_return(cf, data, peer->scache_key, scs); - return result; -} - -static CURLcode gtls_connect_step1(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - CURLcode result; - - DEBUGASSERT(backend); - - if(connssl->state == ssl_connection_complete) - /* to make us tolerant against being called more than once for the - same connection */ - return CURLE_OK; - - result = Curl_gtls_ctx_init(&backend->gtls, cf, data, &connssl->peer, - connssl->alpn, NULL, NULL, cf, -#ifdef CURL_GNUTLS_EARLY_DATA - gtls_on_session_reuse -#else - NULL -#endif - ); - - if(result) - return result; - - if(connssl->alpn && (connssl->state != ssl_connection_deferred)) { - struct alpn_proto_buf proto; - memset(&proto, 0, sizeof(proto)); - Curl_alpn_to_proto_str(&proto, connssl->alpn); - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); - } - -#ifdef CURL_GNUTLS_EARLY_DATA - gnutls_handshake_set_hook_function(backend->gtls.session, - GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST, - gtls_handshake_cb); -#endif - - /* register callback functions and handle to send and receive data. */ - gnutls_transport_set_ptr(backend->gtls.session, cf); - gnutls_transport_set_push_function(backend->gtls.session, gtls_push); - gnutls_transport_set_pull_function(backend->gtls.session, gtls_pull); - - return CURLE_OK; -} - -static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, - gnutls_x509_crt_t cert, - const char *pinnedpubkey) -{ - /* Scratch */ - size_t len1 = 0, len2 = 0; - unsigned char *buff1 = NULL; - - gnutls_pubkey_t key = NULL; - - /* Result is returned to caller */ - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - /* if a path was not specified, do not pin */ - if(!pinnedpubkey) - return CURLE_OK; - - if(!cert) - return result; - - do { - int ret; - - /* Begin Gyrations to get the public key */ - ret = gnutls_pubkey_init(&key); - if(ret < 0) - break; /* failed */ - - ret = gnutls_pubkey_import_x509(key, cert, 0); - if(ret < 0) - break; /* failed */ - - ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1); - if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0) - break; /* failed */ - - buff1 = curlx_malloc(len1); - if(!buff1) - break; /* failed */ - - len2 = len1; - - ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2); - if(ret < 0 || len1 != len2) - break; /* failed */ - - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); - } while(0); - - if(key) - gnutls_pubkey_deinit(key); - - curlx_safefree(buff1); - - return result; -} - -void Curl_gtls_report_handshake(struct Curl_easy *data, struct gtls_ctx *gctx) -{ -#ifdef CURLVERBOSE - if(Curl_trc_is_verbose(data)) { - const char *ptr; - gnutls_protocol_t version = gnutls_protocol_get_version(gctx->session); - - /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ - ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(gctx->session), - gnutls_cipher_get(gctx->session), - gnutls_mac_get(gctx->session)); - - infof(data, "SSL connection using %s / %s", - gnutls_protocol_get_name(version), ptr); - } -#else - (void)data; - (void)gctx; -#endif -} - -static void gtls_msg_verify_result(struct Curl_easy *data, - struct ssl_peer *peer, - gnutls_x509_crt_t x509_cert, - bool was_verified, - bool needs_verified) -{ - char certname[65] = ""; /* limited to 64 chars by ASN.1 */ - size_t size = sizeof(certname); - int rc; - - rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, - 0, /* the first and only one */ - FALSE, certname, &size); - if(rc) { - infof(data, "error fetching CN from cert:%s", gnutls_strerror(rc)); - certname[0] = 0; - } - - if(!was_verified) { - if(needs_verified) { - failf(data, "SSL: certificate subject name (%s) does not match " - "target hostname '%s'", certname, peer->dispname); - } - else - infof(data, " common name: %s (does not match '%s')", - certname, peer->dispname); - } - else - infof(data, " common name: %s (matched)", certname); -} - -static void gtls_infof_cert(struct Curl_easy *data, - gnutls_x509_crt_t x509_cert) -{ -#ifdef CURLVERBOSE - if(Curl_trc_is_verbose(data)) { - gnutls_datum_t certfields; - int rc, algo; - time_t tstamp; - unsigned int bits; - - /* public key algorithm's parameters */ - algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); - infof(data, " certificate public key: %s", - gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)algo)); - - /* version of the X.509 certificate. */ - infof(data, " certificate version: #%d", - gnutls_x509_crt_get_version(x509_cert)); - - rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields); - if(rc) - infof(data, "Failed to get certificate name"); - else { - infof(data, " subject: %s", certfields.data); - - tstamp = gnutls_x509_crt_get_activation_time(x509_cert); - showtime(data, "start date", tstamp); - - tstamp = gnutls_x509_crt_get_expiration_time(x509_cert); - showtime(data, "expire date", tstamp); - - gnutls_free(certfields.data); - } - - rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields); - if(rc) - infof(data, "Failed to get certificate issuer"); - else { - infof(data, " issuer: %s", certfields.data); - - gnutls_free(certfields.data); - } - } -#else - (void)data; - (void)x509_cert; -#endif -} - -static CURLcode gtls_verify_ocsp_status(struct Curl_easy *data, - gnutls_session_t session) -{ - gnutls_ocsp_resp_t ocsp_resp = NULL; - gnutls_datum_t status_request; - gnutls_ocsp_cert_status_t status; - gnutls_x509_crl_reason_t reason; - CURLcode result = CURLE_OK; - int rc; - - rc = gnutls_ocsp_status_request_get(session, &status_request); - - if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - failf(data, "No OCSP response received"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - else if(rc < 0) { - failf(data, "Invalid OCSP response received"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - - rc = gnutls_ocsp_resp_init(&ocsp_resp); - if(rc < 0) { - failf(data, "Failed to initialize OCSP response object"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - - rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - - (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, - &status, NULL, NULL, NULL, &reason); - - switch(status) { - case GNUTLS_OCSP_CERT_GOOD: - break; - - case GNUTLS_OCSP_CERT_REVOKED: { - const char *crl_reason; - - switch(reason) { - default: - case GNUTLS_X509_CRLREASON_UNSPECIFIED: - crl_reason = "unspecified reason"; - break; - - case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: - crl_reason = "private key compromised"; - break; - - case GNUTLS_X509_CRLREASON_CACOMPROMISE: - crl_reason = "CA compromised"; - break; - - case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: - crl_reason = "affiliation has changed"; - break; - - case GNUTLS_X509_CRLREASON_SUPERSEDED: - crl_reason = "certificate superseded"; - break; - - case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: - crl_reason = "operation has ceased"; - break; - - case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: - crl_reason = "certificate is on hold"; - break; - - case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: - crl_reason = "will be removed from delta CRL"; - break; - - case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: - crl_reason = "privilege withdrawn"; - break; - - case GNUTLS_X509_CRLREASON_AACOMPROMISE: - crl_reason = "AA compromised"; - break; - } - - failf(data, "Server certificate was revoked: %s", crl_reason); - break; - } - - default: - case GNUTLS_OCSP_CERT_UNKNOWN: - failf(data, "Server certificate status is unknown"); - break; - } - - result = (status != GNUTLS_OCSP_CERT_GOOD) ? - CURLE_SSL_INVALIDCERTSTATUS : CURLE_OK; - -out: - if(ocsp_resp) - gnutls_ocsp_resp_deinit(ocsp_resp); - return result; -} - -struct gtls_cert_chain { - const gnutls_datum_t *certs; - unsigned int num_certs; -}; - -#ifdef USE_APPLE_SECTRUST -static CURLcode gtls_chain_get_der(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *user_data, - size_t i, - unsigned char **pder, - size_t *pder_len) -{ - struct gtls_cert_chain *chain = user_data; - - (void)cf; - (void)data; - *pder_len = 0; - *pder = NULL; - - if(i >= chain->num_certs) - return CURLE_TOO_LARGE; - *pder = chain->certs[i].data; - *pder_len = (size_t)chain->certs[i].size; - return CURLE_OK; -} - -static CURLcode glts_apple_verify(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - struct gtls_cert_chain *chain, - bool *pverified) -{ - CURLcode result; - - result = Curl_vtls_apple_verify(cf, data, peer, chain->num_certs, - gtls_chain_get_der, chain, NULL, 0); - *pverified = !result; - return result; -} -#endif /* USE_APPLE_SECTRUST */ - -CURLcode Curl_gtls_verifyserver(struct Curl_cfilter *cf, - struct Curl_easy *data, - gnutls_session_t session, - struct ssl_primary_config *config, - struct ssl_config_data *ssl_config, - struct ssl_peer *peer, - const char *pinned_key) -{ - struct gtls_cert_chain chain; - gnutls_x509_crt_t x509_cert = NULL, x509_issuer = NULL; - time_t certclock; - int rc; - CURLcode result = CURLE_OK; - long * const certverifyresult = &ssl_config->certverifyresult; - - (void)cf; - /* This function returns the peer's raw certificate (chain) as sent by - the peer. These certificates are in raw format (DER encoded for - X.509). In case of a X.509 then a certificate list may be present. The - first certificate in the list is the peer's certificate, following the - issuer's certificate, then the issuer's issuer etc. */ - - chain.certs = gnutls_certificate_get_peers(session, &chain.num_certs); - if(!chain.certs) { - if(config->verifypeer || - config->verifyhost || - config->issuercert) { -#ifdef USE_GNUTLS_SRP - if(ssl_config->primary.username && !config->verifypeer && - gnutls_cipher_get(session)) { - /* no peer cert, but auth is ok if we have SRP user and cipher and no - peer verify */ - } - else { -#endif - failf(data, "failed to get server cert"); - *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; -#ifdef USE_GNUTLS_SRP - } -#endif - } - infof(data, " common name: WARNING could not obtain"); - } - - if(data->set.ssl.certinfo && chain.certs) { - if(chain.num_certs > MAX_ALLOWED_CERT_AMOUNT) { - failf(data, "%u certificates is more than allowed (%d)", - chain.num_certs, MAX_ALLOWED_CERT_AMOUNT); - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - else { - unsigned int i; - - result = Curl_ssl_init_certinfo(data, (int)chain.num_certs); - if(result) - goto out; - - for(i = 0; i < chain.num_certs; i++) { - const char *beg = (const char *)chain.certs[i].data; - const char *end = beg + chain.certs[i].size; - - result = Curl_extract_certinfo(data, (int)i, beg, end); - if(result) - goto out; - } - } - } - - if(config->verifypeer) { - bool verified = FALSE; - unsigned int verify_status = 0; - /* This function tries to verify the peer's certificate and return - its status (trusted, invalid etc.). The value of status should be - one or more of the gnutls_certificate_status_t enumerated elements - bitwise or'd. To avoid denial of service attacks some default - upper limits regarding the certificate key size and chain size - are set. To override them use - gnutls_certificate_set_verify_limits(). */ - rc = gnutls_certificate_verify_peers2(session, &verify_status); - if(rc < 0) { - failf(data, "server cert verify failed: %d", rc); - *certverifyresult = rc; - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - *certverifyresult = verify_status; - verified = !(verify_status & GNUTLS_CERT_INVALID); - if(verified) - infof(data, " SSL certificate verified by GnuTLS"); - -#ifdef USE_APPLE_SECTRUST - if(!verified && ssl_config->native_ca_store) { - result = glts_apple_verify(cf, data, peer, &chain, &verified); - if(result && (result != CURLE_PEER_FAILED_VERIFICATION)) - goto out; /* unexpected error */ - if(verified) { - infof(data, "SSL certificate verified via Apple SecTrust."); - *certverifyresult = 0; - } - } -#endif - - if(!verified) { - /* verify_status is a bitmask of gnutls_certificate_status bits */ - const char *cause = "certificate error, no details available"; - if(verify_status & GNUTLS_CERT_EXPIRED) - cause = "certificate has expired"; - else if(verify_status & GNUTLS_CERT_SIGNER_NOT_FOUND) - cause = "certificate signer not trusted"; - else if(verify_status & GNUTLS_CERT_INSECURE_ALGORITHM) - cause = "certificate uses insecure algorithm"; - else if(verify_status & GNUTLS_CERT_INVALID_OCSP_STATUS) - cause = "attached OCSP status response is invalid"; - failf(data, "SSL certificate verification failed: %s. (CAfile: %s " - "CRLfile: %s)", cause, - config->CAfile ? config->CAfile : "none", - ssl_config->primary.CRLfile ? - ssl_config->primary.CRLfile : "none"); - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; - } - } - else - infof(data, " SSL certificate verification SKIPPED"); - - /* initialize an X.509 certificate structure. */ - if(gnutls_x509_crt_init(&x509_cert)) { - failf(data, "failed to init GnuTLS x509_crt"); - *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - - if(chain.certs) { - /* convert the given DER or PEM encoded Certificate to the native - gnutls_x509_crt_t format */ - rc = gnutls_x509_crt_import(x509_cert, chain.certs, GNUTLS_X509_FMT_DER); - if(rc) { - failf(data, "error parsing server's certificate chain"); - *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - } - - /* Check for time-based validity */ - certclock = gnutls_x509_crt_get_expiration_time(x509_cert); - - if(certclock == (time_t)-1) { - if(config->verifypeer) { - failf(data, "server cert expiration date verify failed"); - *certverifyresult = GNUTLS_CERT_EXPIRED; - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - else - infof(data, " SSL certificate expiration date verify FAILED"); - } - else { - if(certclock < time(NULL)) { - if(config->verifypeer) { - failf(data, "server certificate expiration date has passed."); - *certverifyresult = GNUTLS_CERT_EXPIRED; - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; - } - else - infof(data, " SSL certificate expiration date FAILED"); - } - else - infof(data, " SSL certificate expiration date OK"); - } - - certclock = gnutls_x509_crt_get_activation_time(x509_cert); - - if(certclock == (time_t)-1) { - if(config->verifypeer) { - failf(data, "server cert activation date verify failed"); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - else - infof(data, " SSL certificate activation date verify FAILED"); - } - else { - if(certclock > time(NULL)) { - if(config->verifypeer) { - failf(data, "server certificate not activated yet."); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; - } - else - infof(data, " SSL certificate activation date FAILED"); - } - else - infof(data, " SSL certificate activation date OK"); - } - - if(config->verifystatus) { - result = gtls_verify_ocsp_status(data, session); - if(result) - goto out; - } - else - infof(data, " SSL certificate status verification SKIPPED"); - - if(config->issuercert) { - gnutls_datum_t issuerp; - if(gnutls_x509_crt_init(&x509_issuer)) { - failf(data, "failed to init GnuTLS x509_crt for issuer"); - result = CURLE_SSL_ISSUER_ERROR; - goto out; - } - issuerp = load_file(config->issuercert); - rc = gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); - if(!rc) - rc = (int)gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); - unload_file(issuerp); - if(rc <= 0) { - failf(data, "server certificate issuer check failed (IssuerCert: %s)", - config->issuercert ? config->issuercert : "none"); - result = CURLE_SSL_ISSUER_ERROR; - goto out; - } - infof(data, " SSL certificate issuer check OK (Issuer Cert: %s)", - config->issuercert ? config->issuercert : "none"); - } - - /* This function checks if the given certificate's subject matches the - given hostname. This is a basic implementation of the matching described - in RFC2818 (HTTPS), which takes into account wildcards, and the subject - alternative name PKIX extension. Returns non zero on success, and zero on - failure. */ - - /* This function does not handle trailing dots, so if we have an SNI name - use that and fallback to the hostname only if there is no SNI (like for - IP addresses) */ - rc = (int)gnutls_x509_crt_check_hostname(x509_cert, - peer->sni ? peer->sni : - peer->hostname); - result = (!rc && config->verifyhost) ? - CURLE_PEER_FAILED_VERIFICATION : CURLE_OK; - gtls_msg_verify_result(data, peer, x509_cert, rc, config->verifyhost); - if(result) - goto out; - - if(pinned_key) { - result = pkp_pin_peer_pubkey(data, x509_cert, pinned_key); - if(result != CURLE_OK) { - failf(data, "SSL: public key does not match pinned public key"); - goto out; - } - } - - gtls_infof_cert(data, x509_cert); - -out: - if(x509_issuer) - gnutls_x509_crt_deinit(x509_issuer); - if(x509_cert) - gnutls_x509_crt_deinit(x509_cert); - return result; -} - -static CURLcode gtls_verifyserver(struct Curl_cfilter *cf, - struct Curl_easy *data, - gnutls_session_t session) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); -#ifndef CURL_DISABLE_PROXY - const char *pinned_key = Curl_ssl_cf_is_proxy(cf) ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - const char *pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif - CURLcode result; - - result = Curl_gtls_verifyserver(cf, data, session, conn_config, ssl_config, - &connssl->peer, pinned_key); - if(result) - goto out; - -#ifdef CURL_GNUTLS_EARLY_DATA - /* Only on TLSv1.2 or lower do we have the session id now. For - * TLSv1.3 we get it via a SESSION_TICKET message that arrives later. */ - if(gnutls_protocol_get_version(session) < GNUTLS_TLS1_3) - result = cf_gtls_update_session_id(cf, data, session); -#endif - -out: - return result; -} - -#ifdef CURL_GNUTLS_EARLY_DATA -static CURLcode gtls_send_earlydata(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - const unsigned char *buf; - size_t blen; - ssize_t n; - - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sending); - backend->gtls.io_result = CURLE_OK; - while(Curl_bufq_peek(&connssl->earlydata, &buf, &blen)) { - n = gnutls_record_send_early_data(backend->gtls.session, buf, blen); - CURL_TRC_CF(data, cf, "gtls_send_earlydata(len=%zu) -> %zd", blen, n); - if(n < 0) { - if(n == GNUTLS_E_AGAIN) - result = CURLE_AGAIN; - else - result = backend->gtls.io_result ? - backend->gtls.io_result : CURLE_SEND_ERROR; - goto out; - } - else if(!n) { - /* GnuTLS is buggy, it *SHOULD* return the amount of bytes it took in. - * Instead it returns 0 if everything was written. */ - n = (ssize_t)blen; - } - - Curl_bufq_skip(&connssl->earlydata, (size_t)n); - } - /* sent everything there was */ - infof(data, "SSL sending %zu bytes of early data", connssl->earlydata_skip); -out: - return result; -} -#endif - -/* - * This function is called after the TCP connect has completed. Setup the TLS - * layer and do all necessary magic. - */ -/* We use connssl->connecting_state to keep track of the connection status; - there are three states: 'ssl_connect_1' (not started yet or complete), - 'ssl_connect_2' (doing handshake with the server), and - 'ssl_connect_3' (verifying and getting stats). - */ -static CURLcode gtls_connect_common(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - - DEBUGASSERT(backend); - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - - /* Initiate the connection, if not already done */ - if(connssl->connecting_state == ssl_connect_1) { - result = gtls_connect_step1(cf, data); - if(result) - goto out; - connssl->connecting_state = ssl_connect_2; - } - - if(connssl->connecting_state == ssl_connect_2) { -#ifdef CURL_GNUTLS_EARLY_DATA - if(connssl->earlydata_state == ssl_earlydata_await) { - goto out; - } - else if(connssl->earlydata_state == ssl_earlydata_sending) { - result = gtls_send_earlydata(cf, data); - if(result) - goto out; - connssl->earlydata_state = ssl_earlydata_sent; - } - DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) || - (connssl->earlydata_state == ssl_earlydata_sent)); -#endif - result = cf_gtls_handshake(cf, data); - if(result) - goto out; - connssl->connecting_state = ssl_connect_3; - } - - /* Finish connecting once the handshake is done */ - if(connssl->connecting_state == ssl_connect_3) { - gnutls_datum_t proto; - int rc; - - Curl_gtls_report_handshake(data, &backend->gtls); - - result = gtls_verifyserver(cf, data, backend->gtls.session); - if(result) - goto out; - - connssl->state = ssl_connection_complete; - - rc = gnutls_alpn_get_selected_protocol(backend->gtls.session, &proto); - if(rc) { /* No ALPN from server */ - proto.data = NULL; - proto.size = 0; - } - - result = Curl_alpn_set_negotiated(cf, data, connssl, - proto.data, proto.size); - if(result) - goto out; - -#ifdef CURL_GNUTLS_EARLY_DATA - if(connssl->earlydata_state > ssl_earlydata_none) { - /* We should be in this state by now */ - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent); - connssl->earlydata_state = - (gnutls_session_get_flags(backend->gtls.session) & - GNUTLS_SFLAGS_EARLY_DATA) ? - ssl_earlydata_accepted : ssl_earlydata_rejected; - } -#endif - connssl->connecting_state = ssl_connect_done; - } - - if(connssl->connecting_state == ssl_connect_done) - DEBUGASSERT(connssl->state == ssl_connection_complete); - -out: - if(result == CURLE_AGAIN) { - *done = FALSE; - return CURLE_OK; - } - *done = ((connssl->state == ssl_connection_complete) || - (connssl->state == ssl_connection_deferred)); - CURL_TRC_CF(data, cf, "gtls_connect_common() -> %d, done=%d", result, *done); - return result; -} - -static CURLcode gtls_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ -#ifdef CURL_GNUTLS_EARLY_DATA - struct ssl_connect_data *connssl = cf->ctx; - if((connssl->state == ssl_connection_deferred) && - (connssl->earlydata_state == ssl_earlydata_await)) { - /* We refuse to be pushed, we are waiting for someone to send/recv. */ - *done = TRUE; - return CURLE_OK; - } -#endif - return gtls_connect_common(cf, data, done); -} - -static bool gtls_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct ssl_connect_data *ctx = cf->ctx; - struct gtls_ssl_backend_data *backend; - - (void)data; - DEBUGASSERT(ctx && ctx->backend); - backend = (struct gtls_ssl_backend_data *)ctx->backend; - if(backend->gtls.session && - gnutls_record_check_pending(backend->gtls.session) != 0) - return TRUE; - return FALSE; -} - -static CURLcode gtls_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, - size_t blen, - size_t *pnwritten) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - ssize_t nwritten; - size_t remain = blen; - - DEBUGASSERT(backend); - *pnwritten = 0; - - while(remain) { - backend->gtls.io_result = CURLE_OK; - nwritten = gnutls_record_send(backend->gtls.session, buf, remain); - - if(nwritten >= 0) { - *pnwritten += (size_t)nwritten; - DEBUGASSERT((size_t)nwritten <= remain); - buf = (char *)CURL_UNCONST(buf) + (size_t)nwritten; - remain -= (size_t)nwritten; - } - else { - if(*pnwritten && (nwritten == GNUTLS_E_AGAIN)) { - result = CURLE_OK; - goto out; - } - result = (nwritten == GNUTLS_E_AGAIN) ? - CURLE_AGAIN : - (backend->gtls.io_result ? backend->gtls.io_result : CURLE_SEND_ERROR); - goto out; - } - } - -out: - CURL_TRC_CF(data, cf, "gtls_send(len=%zu) -> %d, %zu", - blen, result, *pnwritten); - return result; -} - -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -static CURLcode gtls_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool send_shutdown, bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - char buf[1024]; - CURLcode result = CURLE_OK; - ssize_t nread = 0; - size_t i; - - DEBUGASSERT(backend); - /* If we have no handshaked connection or already shut down */ - if(!backend->gtls.session || cf->shutdown || - connssl->state != ssl_connection_complete) { - *done = TRUE; - goto out; - } - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - *done = FALSE; - - if(!backend->gtls.sent_shutdown) { - /* do this only once */ - backend->gtls.sent_shutdown = TRUE; - if(send_shutdown) { - int ret = gnutls_bye(backend->gtls.session, GNUTLS_SHUT_RDWR); - if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { - CURL_TRC_CF(data, cf, "SSL shutdown, gnutls_bye EAGAIN"); - connssl->io_need = gnutls_record_get_direction(backend->gtls.session) ? - CURL_SSL_IO_NEED_SEND : CURL_SSL_IO_NEED_RECV; - backend->gtls.sent_shutdown = FALSE; - result = CURLE_OK; - goto out; - } - if(ret != GNUTLS_E_SUCCESS) { - CURL_TRC_CF(data, cf, "SSL shutdown, gnutls_bye error: '%s'(%d)", - gnutls_strerror((int)ret), (int)ret); - result = CURLE_RECV_ERROR; - goto out; - } - } - } - - /* SSL should now have started the shutdown from our side. Since it - * was not complete, we are lacking the close notify from the server. */ - for(i = 0; i < 10; ++i) { - nread = gnutls_record_recv(backend->gtls.session, buf, sizeof(buf)); - if(nread <= 0) - break; - } - if(nread > 0) { - /* still data coming in? */ - } - else if(nread == 0) { - /* We got the close notify alert and are done. */ - *done = TRUE; - } - else if((nread == GNUTLS_E_AGAIN) || (nread == GNUTLS_E_INTERRUPTED)) { - connssl->io_need = gnutls_record_get_direction(backend->gtls.session) ? - CURL_SSL_IO_NEED_SEND : CURL_SSL_IO_NEED_RECV; - } - else { - CURL_TRC_CF(data, cf, "SSL shutdown, error: '%s'(%d)", - gnutls_strerror((int)nread), (int)nread); - result = CURLE_RECV_ERROR; - } - -out: - cf->shutdown = (result || *done); - return result; -} - -static void gtls_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - - DEBUGASSERT(backend); - CURL_TRC_CF(data, cf, "close"); - if(backend->gtls.session) { - gnutls_deinit(backend->gtls.session); - backend->gtls.session = NULL; - } - if(backend->gtls.shared_creds) { - Curl_gtls_shared_creds_free(&backend->gtls.shared_creds); - } -#ifdef USE_GNUTLS_SRP - if(backend->gtls.srp_client_cred) { - gnutls_srp_free_client_credentials(backend->gtls.srp_client_cred); - backend->gtls.srp_client_cred = NULL; - } -#endif -} - -static CURLcode gtls_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, size_t blen, - size_t *pnread) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - ssize_t nread; - - DEBUGASSERT(backend); - - nread = gnutls_record_recv(backend->gtls.session, buf, blen); - - if(nread >= 0) - *pnread = (size_t)nread; - else { - if((nread == GNUTLS_E_AGAIN) || (nread == GNUTLS_E_INTERRUPTED)) { - result = CURLE_AGAIN; - goto out; - } - else if(nread == GNUTLS_E_REHANDSHAKE) { - /* Either TLSv1.2 renegotiate or a TLSv1.3 session key update. */ - result = cf_gtls_handshake(cf, data); - if(!result) - result = CURLE_AGAIN; /* make us get called again. */ - goto out; - } - else { - failf(data, "GnuTLS recv error (%d): %s", - (int)nread, gnutls_strerror((int)nread)); - result = backend->gtls.io_result ? - backend->gtls.io_result : CURLE_RECV_ERROR; - goto out; - } - } - -out: - CURL_TRC_CF(data, cf, "gtls_recv(len=%zu) -> 0, %zd", blen, nread); - return result; -} - -size_t Curl_gtls_version(char *buffer, size_t size) -{ - return curl_msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL)); -} - -/* data might be NULL! */ -static CURLcode gtls_random(struct Curl_easy *data, - unsigned char *entropy, size_t length) -{ - int rc; - (void)data; - rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length); - return rc ? CURLE_FAILED_INIT : CURLE_OK; -} - -static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t sha256len) -{ - struct sha256_ctx SHA256pw; - sha256_init(&SHA256pw); - sha256_update(&SHA256pw, (unsigned int)tmplen, tmp); - sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum); - return CURLE_OK; -} - -static bool gtls_cert_status_request(void) -{ - return TRUE; -} - -static void *gtls_get_internals(struct ssl_connect_data *connssl, - CURLINFO info) -{ - struct gtls_ssl_backend_data *backend = - (struct gtls_ssl_backend_data *)connssl->backend; - (void)info; - DEBUGASSERT(backend); - return backend->gtls.session; -} - -const struct Curl_ssl Curl_ssl_gnutls = { - { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */ - - SSLSUPP_CA_PATH | - SSLSUPP_CERTINFO | - SSLSUPP_PINNEDPUBKEY | - SSLSUPP_HTTPS_PROXY | - SSLSUPP_CAINFO_BLOB | - SSLSUPP_CIPHER_LIST | - SSLSUPP_CA_CACHE | - SSLSUPP_ISSUERCERT | - SSLSUPP_CRLFILE, - - sizeof(struct gtls_ssl_backend_data), - - gtls_init, /* init */ - gtls_cleanup, /* cleanup */ - Curl_gtls_version, /* version */ - gtls_shutdown, /* shutdown */ - gtls_data_pending, /* data_pending */ - gtls_random, /* random */ - gtls_cert_status_request, /* cert_status_request */ - gtls_connect, /* connect */ - Curl_ssl_adjust_pollset, /* adjust_pollset */ - gtls_get_internals, /* get_internals */ - gtls_close, /* close_one */ - NULL, /* close_all */ - NULL, /* set_engine */ - NULL, /* set_engine_default */ - NULL, /* engines_list */ - gtls_sha256sum, /* sha256sum */ - gtls_recv, /* recv decrypted data */ - gtls_send, /* send data to encrypt */ - NULL, /* get_channel_binding */ -}; - -#endif /* USE_GNUTLS */ diff --git a/vendor/curl/lib/vtls/gtls.h b/vendor/curl/lib/vtls/gtls.h deleted file mode 100644 index 49106dd86..000000000 --- a/vendor/curl/lib/vtls/gtls.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef HEADER_CURL_GTLS_H -#define HEADER_CURL_GTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_GNUTLS - -#include - -#include "curlx/timeval.h" - -#ifdef HAVE_GNUTLS_SRP -/* the function exists */ -#ifdef USE_TLS_SRP -/* the functionality is not disabled */ -#define USE_GNUTLS_SRP -#endif -#endif - -struct Curl_easy; -struct Curl_cfilter; -struct alpn_spec; -struct ssl_primary_config; -struct ssl_config_data; -struct ssl_peer; -struct ssl_connect_data; -struct Curl_ssl_session; - -int Curl_glts_get_ietf_proto(gnutls_session_t session); - -struct gtls_shared_creds { - gnutls_certificate_credentials_t creds; - char *CAfile; /* CAfile path used to generate X509 store */ - struct curltime time; /* when the shared creds was created */ - size_t refcount; - BIT(trust_setup); /* x509 anchors + CRLs have been set up */ -}; - -CURLcode Curl_gtls_shared_creds_create(struct Curl_easy *data, - struct gtls_shared_creds **pcreds); -CURLcode Curl_gtls_shared_creds_up_ref(struct gtls_shared_creds *creds); -void Curl_gtls_shared_creds_free(struct gtls_shared_creds **pcreds); - -struct gtls_ctx { - gnutls_session_t session; - struct gtls_shared_creds *shared_creds; -#ifdef USE_GNUTLS_SRP - gnutls_srp_client_credentials_t srp_client_cred; -#endif - CURLcode io_result; /* result of last IO cfilter operation */ - BIT(sent_shutdown); -}; - -size_t Curl_gtls_version(char *buffer, size_t size); - -typedef CURLcode Curl_gtls_ctx_setup_cb(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *user_data); - -typedef CURLcode Curl_gtls_init_session_reuse_cb(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data); - -CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - Curl_gtls_ctx_setup_cb *cb_setup, - void *cb_user_data, - void *ssl_user_data, - Curl_gtls_init_session_reuse_cb *sess_reuse_cb); - -CURLcode Curl_gtls_client_trust_setup(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct gtls_ctx *gtls); - -CURLcode Curl_gtls_verifyserver(struct Curl_cfilter *cf, - struct Curl_easy *data, - gnutls_session_t session, - struct ssl_primary_config *config, - struct ssl_config_data *ssl_config, - struct ssl_peer *peer, - const char *pinned_key); - -/* Extract TLS session and place in cache, if configured. */ -CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - gnutls_session_t session, - curl_off_t valid_until, - const char *alpn, - unsigned char *quic_tp, - size_t quic_tp_len); - -/* Report properties of a successful handshake */ -void Curl_gtls_report_handshake(struct Curl_easy *data, struct gtls_ctx *gctx); - -extern const struct Curl_ssl Curl_ssl_gnutls; - -#endif /* USE_GNUTLS */ -#endif /* HEADER_CURL_GTLS_H */ diff --git a/vendor/curl/lib/vtls/hostcheck.c b/vendor/curl/lib/vtls/hostcheck.c deleted file mode 100644 index ad09b8319..000000000 --- a/vendor/curl/lib/vtls/hostcheck.c +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_OPENSSL) || defined(USE_SCHANNEL) -/* these backends use functions from this file */ - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETINET_IN6_H -#include -#endif - -#include "curl_memrchr.h" -#include "vtls/hostcheck.h" -#include "hostip.h" - -/* check the two input strings with given length, but do not - assume they end in nul-bytes */ -static bool pmatch(const char *hostname, size_t hostlen, - const char *pattern, size_t patternlen) -{ - if(hostlen != patternlen) - return FALSE; - return curl_strnequal(hostname, pattern, hostlen); -} - -/* - * Match a hostname against a wildcard pattern. - * E.g. - * "foo.host.com" matches "*.host.com". - * - * We use the matching rule described in RFC6125, section 6.4.3. - * https://datatracker.ietf.org/doc/html/rfc6125#section-6.4.3 - * - * In addition: ignore trailing dots in the hostnames and wildcards, so that - * the names are used normalized. This is what the browsers do. - * - * Do not allow wildcard matching on IP numbers. There are apparently - * certificates being used with an IP address in the CN field, thus making no - * apparent distinction between a name and an IP. We need to detect the use of - * an IP address and not wildcard match on such names. - * - * Only match on "*" being used for the leftmost label, not "a*", "a*b" nor - * "*b". - * - * Return TRUE on a match. FALSE if not. - * - * @unittest: 1397 - */ - -static bool hostmatch(const char *hostname, - size_t hostlen, - const char *pattern, - size_t patternlen) -{ - const char *pattern_label_end; - - DEBUGASSERT(pattern); - DEBUGASSERT(patternlen); - DEBUGASSERT(hostname); - DEBUGASSERT(hostlen); - - /* normalize pattern and hostname by stripping off trailing dots */ - if(hostname[hostlen - 1] == '.') - hostlen--; - if(pattern[patternlen - 1] == '.') - patternlen--; - - if(strncmp(pattern, "*.", 2)) - return pmatch(hostname, hostlen, pattern, patternlen); - - /* detect host as IP address or starting with a dot and fail if so */ - else if(Curl_host_is_ipnum(hostname) || (hostname[0] == '.')) - return FALSE; - - /* We require at least 2 dots in the pattern to avoid too wide wildcard - match. */ - pattern_label_end = memchr(pattern, '.', patternlen); - if(!pattern_label_end || - (memrchr(pattern, '.', patternlen) == pattern_label_end)) - return pmatch(hostname, hostlen, pattern, patternlen); - else { - const char *hostname_label_end = memchr(hostname, '.', hostlen); - if(hostname_label_end) { - size_t skiphost = hostname_label_end - hostname; - size_t skiplen = pattern_label_end - pattern; - return pmatch(hostname_label_end, hostlen - skiphost, - pattern_label_end, patternlen - skiplen); - } - } - return FALSE; -} - -/* - * Curl_cert_hostcheck() returns TRUE if a match and FALSE if not. - */ -bool Curl_cert_hostcheck(const char *match, size_t matchlen, - const char *hostname, size_t hostlen) -{ - if(match && *match && hostname && *hostname) - return hostmatch(hostname, hostlen, match, matchlen); - return FALSE; -} - -#endif /* USE_OPENSSL || USE_SCHANNEL */ diff --git a/vendor/curl/lib/vtls/hostcheck.h b/vendor/curl/lib/vtls/hostcheck.h deleted file mode 100644 index d8e1a5237..000000000 --- a/vendor/curl/lib/vtls/hostcheck.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HEADER_CURL_HOSTCHECK_H -#define HEADER_CURL_HOSTCHECK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_OPENSSL) || defined(USE_SCHANNEL) - -/* returns TRUE if there is a match */ -bool Curl_cert_hostcheck(const char *match, size_t matchlen, - const char *hostname, size_t hostlen); - -#endif - -#endif /* HEADER_CURL_HOSTCHECK_H */ diff --git a/vendor/curl/lib/vtls/keylog.c b/vendor/curl/lib/vtls/keylog.c deleted file mode 100644 index 4ae2387a7..000000000 --- a/vendor/curl/lib/vtls/keylog.c +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "vtls/keylog.h" - -#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ - defined(USE_RUSTLS) - -#include "escape.h" -#include "curlx/fopen.h" - -/* The fp for the open SSLKEYLOGFILE, or NULL if not open */ -static FILE *keylog_file_fp; -/* Used for verbose logging */ -static char *keylog_file_name; - -void Curl_tls_keylog_open(void) -{ - if(!keylog_file_fp) { - keylog_file_name = getenv("SSLKEYLOGFILE"); - if(keylog_file_name) { - keylog_file_fp = curlx_fopen(keylog_file_name, FOPEN_APPENDTEXT); - if(keylog_file_fp) { -#ifdef _WIN32 - if(setvbuf(keylog_file_fp, NULL, _IONBF, 0)) -#else - if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) -#endif - { - curlx_fclose(keylog_file_fp); - keylog_file_fp = NULL; - } - } - } - } -} - -void Curl_tls_keylog_close(void) -{ - if(keylog_file_fp) { - curlx_fclose(keylog_file_fp); - keylog_file_fp = NULL; - } -} - -bool Curl_tls_keylog_enabled(void) -{ - return keylog_file_fp != NULL; -} - -const char *Curl_tls_keylog_file_name(void) -{ - return keylog_file_name; -} - -bool Curl_tls_keylog_write_line(const char *line) -{ - /* The current maximum valid keylog line length LF and NUL is 195. */ - size_t linelen; - char buf[256]; - - if(!keylog_file_fp || !line) { - return FALSE; - } - - linelen = strlen(line); - if(linelen == 0 || linelen > sizeof(buf) - 2) { - /* Empty line or too big to fit in an LF and NUL. */ - return FALSE; - } - - memcpy(buf, line, linelen); - if(line[linelen - 1] != '\n') { - buf[linelen++] = '\n'; - } - buf[linelen] = '\0'; - - /* Using fputs here instead of fprintf since libcurl's fprintf replacement - may not be thread-safe. */ - fputs(buf, keylog_file_fp); - return TRUE; -} - -bool Curl_tls_keylog_write(const char *label, - const unsigned char client_random[CLIENT_RANDOM_SIZE], - const unsigned char *secret, size_t secretlen) -{ - size_t pos, i; - unsigned char line[KEYLOG_LABEL_MAXLEN + 1 + - (2 * CLIENT_RANDOM_SIZE) + 1 + - (2 * SECRET_MAXLEN) + 1 + 1]; - - if(!keylog_file_fp) { - return FALSE; - } - - pos = strlen(label); - if(pos > KEYLOG_LABEL_MAXLEN || !secretlen || secretlen > SECRET_MAXLEN) { - /* Should never happen - sanity check anyway. */ - return FALSE; - } - - memcpy(line, label, pos); - line[pos++] = ' '; - - /* Client Random */ - for(i = 0; i < CLIENT_RANDOM_SIZE; i++) { - Curl_hexbyte(&line[pos], client_random[i]); - pos += 2; - } - line[pos++] = ' '; - - /* Secret */ - for(i = 0; i < secretlen; i++) { - Curl_hexbyte(&line[pos], secret[i]); - pos += 2; - } - line[pos++] = '\n'; - line[pos] = '\0'; - - /* Using fputs here instead of fprintf since libcurl's fprintf replacement - may not be thread-safe. */ - fputs((char *)line, keylog_file_fp); - return TRUE; -} - -#else /* TLS backend */ - -bool Curl_tls_keylog_enabled(void) -{ - return FALSE; -} - -const char *Curl_tls_keylog_file_name(void) -{ - return NULL; -} - -#endif /* TLS backend */ diff --git a/vendor/curl/lib/vtls/keylog.h b/vendor/curl/lib/vtls/keylog.h deleted file mode 100644 index 68ded4769..000000000 --- a/vendor/curl/lib/vtls/keylog.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef HEADER_CURL_KEYLOG_H -#define HEADER_CURL_KEYLOG_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#define KEYLOG_LABEL_MAXLEN (sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET") - 1) - -#define CLIENT_RANDOM_SIZE 32 - -/* - * The master secret in TLS 1.2 and before is always 48 bytes. In TLS 1.3, the - * secret size depends on the cipher suite's hash function which is 32 bytes - * for SHA-256 and 48 bytes for SHA-384. - */ -#define SECRET_MAXLEN 48 - -/* - * Opens the TLS key log file if requested by the user. The SSLKEYLOGFILE - * environment variable specifies the output file. - */ -void Curl_tls_keylog_open(void); - -/* - * Closes the TLS key log file if not already. - */ -void Curl_tls_keylog_close(void); - -/* - * Returns true if the user successfully enabled the TLS key log file. - */ -bool Curl_tls_keylog_enabled(void); - -/* - * Returns a pointer to the filename keys are being written to, if enabled. - */ -const char *Curl_tls_keylog_file_name(void); - -/* - * Appends a key log file entry. - * Returns true iff the key log file is open and a valid entry was provided. - */ -bool Curl_tls_keylog_write(const char *label, - const unsigned char client_random[CLIENT_RANDOM_SIZE], - const unsigned char *secret, size_t secretlen); - -/* - * Appends a line to the key log file, ensure it is terminated by an LF. - * Returns true iff the key log file is open and a valid line was provided. - */ -bool Curl_tls_keylog_write_line(const char *line); - -#endif /* HEADER_CURL_KEYLOG_H */ diff --git a/vendor/curl/lib/vtls/mbedtls.c b/vendor/curl/lib/vtls/mbedtls.c deleted file mode 100644 index e2822668f..000000000 --- a/vendor/curl/lib/vtls/mbedtls.c +++ /dev/null @@ -1,1626 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Hoi-Ho Chan, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Source file for all mbedTLS-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ -#include "curl_setup.h" - -#ifdef USE_MBEDTLS - -/* Define this to enable lots of debugging for mbedTLS */ -/* #define MBEDTLS_DEBUG */ - -#include -#if MBEDTLS_VERSION_NUMBER < 0x03020000 -#error "mbedTLS 3.2.0 or later required" -#endif -#include -#include -#include -#include -#include - -#if MBEDTLS_VERSION_NUMBER < 0x04000000 && !defined(MBEDTLS_CTR_DRBG_C) -#error "MBEDTLS_CTR_DRBG_C is required for mbedTLS 3.x." -#endif - -#include -#if MBEDTLS_VERSION_NUMBER < 0x04000000 -#include -#include -#endif -#ifdef MBEDTLS_DEBUG -#include -#endif - -#include "vtls/cipher_suite.h" -#include "urldata.h" -#include "curl_trc.h" -#include "vtls/mbedtls.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" -#include "vtls/vtls_scache.h" -#include "vtls/x509asn1.h" -#include "connect.h" /* for the connect timeout */ -#include "curlx/strdup.h" -#include "curl_sha256.h" - -/* ALPN for http2 */ -#if defined(USE_HTTP2) && defined(MBEDTLS_SSL_ALPN) -#define HAS_ALPN_MBEDTLS -#endif - -struct mbed_ssl_backend_data { - mbedtls_ssl_context ssl; - mbedtls_x509_crt cacert; - mbedtls_x509_crt clicert; -#ifdef MBEDTLS_X509_CRL_PARSE_C - mbedtls_x509_crl crl; -#endif - mbedtls_pk_context pk; - mbedtls_ssl_config config; -#ifdef HAS_ALPN_MBEDTLS - const char *protocols[3]; -#endif - int *ciphersuites; - size_t send_blocked_len; - BIT(initialized); /* mbedtls_ssl_context is initialized */ - BIT(sent_shutdown); - BIT(send_blocked); -}; - -/** A context for random number generation (RNG). - */ -#if MBEDTLS_VERSION_NUMBER < 0x04000000 -struct rng_context_t { - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context drbg; -}; - -static struct rng_context_t rng; -#endif - -#ifndef MBEDTLS_ERROR_C -#define mbedtls_strerror(a, b, c) b[0] = 0 -#endif - -#ifdef MBEDTLS_DEBUG -static void mbed_debug(void *context, int level, const char *f_name, - int line_nb, const char *line) -{ - struct Curl_easy *data = (struct Curl_easy *)context; - (void)level; - (void)line_nb; - (void)f_name; - - if(data) { - size_t len = strlen(line); - if(len && (line[len - 1] == '\n')) - /* discount any trailing newline */ - len--; - infof(data, "%.*s", (int)len, line); - } -} -#endif - -static int mbedtls_bio_cf_write(void *bio, - const unsigned char *buf, size_t blen) -{ - struct Curl_cfilter *cf = bio; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nwritten; - CURLcode result; - - DEBUGASSERT(data); - if(!data) - return 0; - - result = Curl_conn_cf_send(cf->next, data, buf, blen, FALSE, &nwritten); - CURL_TRC_CF(data, cf, "mbedtls_bio_cf_out_write(len=%zu) -> %d, %zu", - blen, result, nwritten); - if(result == CURLE_AGAIN) - return MBEDTLS_ERR_SSL_WANT_WRITE; - return result ? -1 : (int)nwritten; -} - -static int mbedtls_bio_cf_read(void *bio, unsigned char *buf, size_t blen) -{ - struct Curl_cfilter *cf = bio; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nread = 0; - CURLcode result; - - DEBUGASSERT(data); - if(!data) - return 0; - /* OpenSSL catches this case, so should we. */ - if(!buf) - return 0; - - result = Curl_conn_cf_recv(cf->next, data, (char *)buf, blen, &nread); - CURL_TRC_CF(data, cf, "mbedtls_bio_cf_in_read(len=%zu) -> %d, %zu", - blen, result, nread); - if(result == CURLE_AGAIN) - return MBEDTLS_ERR_SSL_WANT_READ; - /* nread is never larger than int here */ - return result ? -1 : (int)nread; -} - -/* See: - * https://web.archive.org/web/20200921194007/tls.mbed.org/discussions/generic/howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der - */ -#define RSA_PUB_DER_MAX_BYTES (38 + (2 * MBEDTLS_MPI_MAX_SIZE)) -#define ECP_PUB_DER_MAX_BYTES (30 + (2 * MBEDTLS_ECP_MAX_BYTES)) - -#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ - RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) - -static CURLcode -mbed_set_ssl_version_min_max(struct Curl_easy *data, - struct mbed_ssl_backend_data *backend, - struct ssl_primary_config *conn_config) -{ - mbedtls_ssl_protocol_version ver_min = -#ifdef MBEDTLS_SSL_PROTO_TLS1_2 - MBEDTLS_SSL_VERSION_TLS1_2 -#else - MBEDTLS_SSL_VERSION_TLS1_3 -#endif - ; - mbedtls_ssl_protocol_version ver_max = -#ifdef MBEDTLS_SSL_PROTO_TLS1_3 - MBEDTLS_SSL_VERSION_TLS1_3 -#else - MBEDTLS_SSL_VERSION_TLS1_2 -#endif - ; - - DEBUGASSERT(conn_config->version != CURL_SSLVERSION_DEFAULT); - switch(conn_config->version) { - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: -#ifdef MBEDTLS_SSL_PROTO_TLS1_2 - ver_min = MBEDTLS_SSL_VERSION_TLS1_2; - break; -#endif - case CURL_SSLVERSION_TLSv1_3: -#ifdef MBEDTLS_SSL_PROTO_TLS1_3 - ver_min = MBEDTLS_SSL_VERSION_TLS1_3; - break; -#endif - default: - failf(data, "mbedTLS: unsupported minimum TLS version value: %x", - conn_config->version); - return CURLE_SSL_CONNECT_ERROR; - } - - switch(conn_config->version_max) { - case CURL_SSLVERSION_MAX_DEFAULT: - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_TLSv1_3: -#ifdef MBEDTLS_SSL_PROTO_TLS1_3 - ver_max = MBEDTLS_SSL_VERSION_TLS1_3; - break; -#endif -#ifdef MBEDTLS_SSL_PROTO_TLS1_2 - case CURL_SSLVERSION_MAX_TLSv1_2: - ver_max = MBEDTLS_SSL_VERSION_TLS1_2; - break; -#endif - case CURL_SSLVERSION_MAX_TLSv1_1: - case CURL_SSLVERSION_MAX_TLSv1_0: - default: - failf(data, "mbedTLS: unsupported maximum TLS version value"); - return CURLE_SSL_CONNECT_ERROR; - } - - mbedtls_ssl_conf_min_tls_version(&backend->config, ver_min); - mbedtls_ssl_conf_max_tls_version(&backend->config, ver_max); - - return CURLE_OK; -} - -/* TLS_ECJPAKE_WITH_AES_128_CCM_8 (0xC0FF) is marked experimental in mbedTLS. - The number is not reserved by IANA nor is the cipher suite present in other - SSL implementations. Provide provisional support for specifying the cipher - suite here. */ -#ifdef MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 -static int mbed_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, - bool prefer_rfc) -{ - if(id == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8) - curl_msnprintf(buf, buf_size, "%s", "TLS_ECJPAKE_WITH_AES_128_CCM_8"); - else - return Curl_cipher_suite_get_str(id, buf, buf_size, prefer_rfc); - return 0; -} - -static uint16_t mbed_cipher_suite_walk_str(const char **str, const char **end) -{ - uint16_t id = Curl_cipher_suite_walk_str(str, end); - size_t len = *end - *str; - static const char ecjpake_suite[] = "TLS_ECJPAKE_WITH_AES_128_CCM_8"; - - if(!id) { - if((len == sizeof(ecjpake_suite) - 1) && - curl_strnequal(ecjpake_suite, *str, len)) - id = MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8; - } - return id; -} -#else -#define mbed_cipher_suite_get_str Curl_cipher_suite_get_str -#define mbed_cipher_suite_walk_str Curl_cipher_suite_walk_str -#endif - -static CURLcode -mbed_set_selected_ciphers(struct Curl_easy *data, - struct mbed_ssl_backend_data *backend, - const char *ciphers12, - const char *ciphers13) -{ - const char *ciphers = ciphers12; - const int *supported; - int *selected; - size_t supported_len, count = 0, default13_count = 0, i, j; - const char *ptr, *end; - - supported = mbedtls_ssl_list_ciphersuites(); - for(i = 0; supported[i] != 0; i++) - ; - supported_len = i; - - selected = curlx_malloc(sizeof(int) * (supported_len + 1)); - if(!selected) - return CURLE_OUT_OF_MEMORY; - -#ifndef MBEDTLS_SSL_PROTO_TLS1_3 - (void)ciphers13, (void)j; -#else - if(!ciphers13) { - /* Add default TLSv1.3 ciphers to selection */ - for(j = 0; j < supported_len; j++) { - uint16_t id = (uint16_t)supported[j]; - if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) != 0) - continue; - - selected[count++] = id; - } - - default13_count = count; - } - else - ciphers = ciphers13; - -add_ciphers: -#endif - for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) { - uint16_t id = mbed_cipher_suite_walk_str(&ptr, &end); - - /* Check if cipher is supported */ - if(id) { - for(i = 0; i < supported_len && supported[i] != id; i++) - ; - if(i == supported_len) - id = 0; - } - if(!id) { - if(ptr[0] != '\0') - infof(data, "mbedTLS: unknown cipher in list: \"%.*s\"", - (int)(end - ptr), ptr); - continue; - } - - /* No duplicates allowed (so selected cannot overflow) */ - for(i = 0; i < count && selected[i] != id; i++) - ; - if(i < count) { - if(i >= default13_count) - infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", - (int)(end - ptr), ptr); - continue; - } - - selected[count++] = id; - } - -#ifdef MBEDTLS_SSL_PROTO_TLS1_3 - if(ciphers == ciphers13 && ciphers12) { - ciphers = ciphers12; - goto add_ciphers; - } - - if(!ciphers12) { - /* Add default TLSv1.2 ciphers to selection */ - for(j = 0; j < supported_len; j++) { - uint16_t id = (uint16_t)supported[j]; - if(strncmp(mbedtls_ssl_get_ciphersuite_name(id), "TLS1-3", 6) == 0) - continue; - - /* No duplicates allowed (so selected cannot overflow) */ - for(i = 0; i < count && selected[i] != id; i++) - ; - if(i < count) - continue; - - selected[count++] = id; - } - } -#endif - - selected[count] = 0; - - if(count == 0) { - curlx_free(selected); - failf(data, "mbedTLS: no supported cipher in list"); - return CURLE_SSL_CIPHER; - } - - /* mbedtls_ssl_conf_ciphersuites(): The ciphersuites array is not copied. - It must remain valid for the lifetime of the SSL configuration */ - backend->ciphersuites = selected; - mbedtls_ssl_conf_ciphersuites(&backend->config, backend->ciphersuites); - return CURLE_OK; -} - -static void mbed_dump_cert_info(struct Curl_easy *data, - const mbedtls_x509_crt *crt) -{ -#if !defined(CURLVERBOSE) || defined(MBEDTLS_X509_REMOVE_INFO) - (void)data, (void)crt; -#else - const size_t bufsize = 16384; - char *p, *buffer = curlx_malloc(bufsize); - - if(buffer && mbedtls_x509_crt_info(buffer, bufsize, " ", crt) > 0) { - infof(data, "Server certificate:"); - for(p = buffer; *p; p += *p != '\0') { - size_t s = strcspn(p, "\n"); - infof(data, "%.*s", (int)s, p); - p += s; - } - } - else - infof(data, "Unable to dump certificate information"); - - curlx_free(buffer); -#endif -} - -static void mbed_extract_certinfo(struct Curl_easy *data, - const mbedtls_x509_crt *crt) -{ - CURLcode result; - const mbedtls_x509_crt *cur; - int cert_count = 0; - int i; - - for(cur = crt; cur && cert_count <= MAX_ALLOWED_CERT_AMOUNT; cur = cur->next) - cert_count++; - - if(cert_count > MAX_ALLOWED_CERT_AMOUNT) { - infof(data, "More certificates than allowed (%d), skipping certinfo", - MAX_ALLOWED_CERT_AMOUNT); - return; - } - - result = Curl_ssl_init_certinfo(data, cert_count); - - for(i = 0, cur = crt; result == CURLE_OK && cur; ++i, cur = cur->next) { - const char *beg = (const char *)cur->raw.p; - const char *end = beg + cur->raw.len; - result = Curl_extract_certinfo(data, i, beg, end); - } -} - -static int mbed_verify_cb(void *ptr, mbedtls_x509_crt *crt, - int depth, uint32_t *flags) -{ - struct Curl_cfilter *cf = (struct Curl_cfilter *)ptr; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_easy *data = CF_DATA_CURRENT(cf); - - if(depth == 0) { - if(data->set.verbose) - mbed_dump_cert_info(data, crt); - if(data->set.ssl.certinfo) - mbed_extract_certinfo(data, crt); - } - - if(!conn_config->verifypeer) - *flags = 0; - else if(!conn_config->verifyhost) - *flags &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; - - if(*flags) { -#ifndef MBEDTLS_X509_REMOVE_INFO - char buf[128]; - mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", *flags); - failf(data, "mbedTLS: %s", buf); -#else - failf(data, "mbedTLS: certificate verification error 0x%08x", *flags); -#endif - } - - return 0; -} - -static CURLcode mbed_load_cacert(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; - const char * const ssl_cafile = - /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - (ca_info_blob ? NULL : conn_config->CAfile); - const bool verifypeer = conn_config->verifypeer; - const char * const ssl_capath = conn_config->CApath; -#ifdef MBEDTLS_PEM_PARSE_C - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - const char * const ssl_cert_type = ssl_config->cert_type; -#endif - int ret = -1; - char errorbuf[128]; - - mbedtls_x509_crt_init(&backend->cacert); - - if(ca_info_blob && verifypeer) { -#ifdef MBEDTLS_PEM_PARSE_C - /* if DER or a null-terminated PEM process using - mbedtls_x509_crt_parse(). */ - if((ssl_cert_type && curl_strequal(ssl_cert_type, "DER")) || - ((char *)(ca_info_blob->data))[ca_info_blob->len - 1] == '\0') { - ret = mbedtls_x509_crt_parse(&backend->cacert, ca_info_blob->data, - ca_info_blob->len); - } - else { /* they say it is PEM and it is not null-terminated */ - - /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be - null-terminated if the data is PEM encoded (even when provided the - exact length). The function accepts PEM or DER formats, but we cannot - assume if the user passed in a PEM format cert that it is - null-terminated. */ - unsigned char *newblob = curlx_memdup0(ca_info_blob->data, - ca_info_blob->len); - if(!newblob) - return CURLE_OUT_OF_MEMORY; - - ret = mbedtls_x509_crt_parse(&backend->cacert, newblob, - ca_info_blob->len + 1); - curlx_free(newblob); - } -#else - /* DER encoded certs do not need to be null-terminated because it is a - binary format. Thus, if we are not compiling with PEM_PARSE we can avoid - the extra memory copies altogether. */ - ret = mbedtls_x509_crt_parse_der(&backend->cacert, ca_info_blob->data, - ca_info_blob->len); -#endif - - if(ret < 0) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error importing CA cert blob: (-0x%04X) %s", - -ret, errorbuf); - return CURLE_SSL_CERTPROBLEM; - } - } - - if(ssl_cafile && verifypeer) { -#ifdef MBEDTLS_FS_IO - ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile); - - if(ret < 0) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error reading CA cert file %s: (-0x%04X) %s", - ssl_cafile, -ret, errorbuf); - return CURLE_SSL_CACERT_BADFILE; - } -#else - failf(data, "mbedTLS: functions that use the file system not built in"); - return CURLE_NOT_BUILT_IN; -#endif - } - - if(ssl_capath) { -#ifdef MBEDTLS_FS_IO - ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath); - - if(ret < 0) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error reading CA cert path %s: (-0x%04X) %s", - ssl_capath, -ret, errorbuf); - - if(verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } -#else - failf(data, "mbedTLS: functions that use the file system not built in"); - return CURLE_NOT_BUILT_IN; -#endif - } - - return CURLE_OK; -} - -static CURLcode mbed_load_clicert(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - char * const ssl_cert = ssl_config->primary.clientcert; - const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; -#ifdef MBEDTLS_PEM_PARSE_C - const char * const ssl_cert_type = ssl_config->cert_type; -#endif - int ret = -1; - char errorbuf[128]; - - mbedtls_x509_crt_init(&backend->clicert); - - if(ssl_cert) { -#ifdef MBEDTLS_FS_IO - ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert); - - if(ret) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error reading client cert file %s: (-0x%04X) %s", - ssl_cert, -ret, errorbuf); - - return CURLE_SSL_CERTPROBLEM; - } -#else - failf(data, "mbedTLS: functions that use the file system not built in"); - return CURLE_NOT_BUILT_IN; -#endif - } - - if(ssl_cert_blob) { -#ifdef MBEDTLS_PEM_PARSE_C - /* if DER or a null-terminated PEM process using - mbedtls_x509_crt_parse(). */ - if((ssl_cert_type && curl_strequal(ssl_cert_type, "DER")) || - ((char *)(ssl_cert_blob->data))[ssl_cert_blob->len - 1] == '\0') { - - ret = mbedtls_x509_crt_parse(&backend->clicert, - ssl_cert_blob->data, - ssl_cert_blob->len); - } - else { /* they say it is PEM and it is not null-terminated */ - - /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be - null-terminated if the data is PEM encoded (even when provided the - exact length). The function accepts PEM or DER formats, but we cannot - assume if the user passed in a PEM format cert that it is - null-terminated. */ - unsigned char *newblob = curlx_memdup0(ssl_cert_blob->data, - ssl_cert_blob->len); - if(!newblob) - return CURLE_OUT_OF_MEMORY; - ret = mbedtls_x509_crt_parse(&backend->clicert, newblob, - ssl_cert_blob->len + 1); - curlx_free(newblob); - } -#else - /* DER encoded certs do not need to be null-terminated because it is a - binary format. Thus, if we are not compiling with PEM_PARSE we can avoid - the extra memory copies altogether. */ - ret = mbedtls_x509_crt_parse_der(&backend->clicert, ssl_cert_blob->data, - ssl_cert_blob->len); -#endif - - if(ret) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error reading client cert blob: (-0x%04X) %s", - -ret, errorbuf); - return CURLE_SSL_CERTPROBLEM; - } - } - - return CURLE_OK; -} - -static CURLcode mbed_load_privkey(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - int ret = -1; - char errorbuf[128]; - - mbedtls_pk_init(&backend->pk); - - if(ssl_config->key || ssl_config->key_blob) { - if(ssl_config->key) { -#ifdef MBEDTLS_FS_IO -#if MBEDTLS_VERSION_NUMBER >= 0x04000000 - ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key, - ssl_config->key_passwd); - if(ret == 0 && - !(mbedtls_pk_can_do_psa(&backend->pk, - PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH), - PSA_KEY_USAGE_SIGN_HASH) || - mbedtls_pk_can_do_psa(&backend->pk, - MBEDTLS_PK_ALG_ECDSA(PSA_ALG_ANY_HASH), - PSA_KEY_USAGE_SIGN_HASH))) - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; -#else - ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key, - ssl_config->key_passwd, - mbedtls_ctr_drbg_random, - &rng.drbg); - if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || - mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; -#endif - - if(ret) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error reading private key %s: (-0x%04X) %s", - ssl_config->key, -ret, errorbuf); - return CURLE_SSL_CERTPROBLEM; - } -#else - failf(data, "mbedTLS: functions that use the file system not built in"); - return CURLE_NOT_BUILT_IN; -#endif - } - else { - const struct curl_blob *ssl_key_blob = ssl_config->key_blob; - const unsigned char *key_data = - (const unsigned char *)ssl_key_blob->data; - const char *passwd = ssl_config->key_passwd; -#if MBEDTLS_VERSION_NUMBER >= 0x04000000 - ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, - (const unsigned char *)passwd, - passwd ? strlen(passwd) : 0); - if(ret == 0 && - !(mbedtls_pk_can_do_psa(&backend->pk, - PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH), - PSA_KEY_USAGE_SIGN_HASH) || - mbedtls_pk_can_do_psa(&backend->pk, - MBEDTLS_PK_ALG_ECDSA(PSA_ALG_ANY_HASH), - PSA_KEY_USAGE_SIGN_HASH))) - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; -#else - ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, - (const unsigned char *)passwd, - passwd ? strlen(passwd) : 0, - mbedtls_ctr_drbg_random, - &rng.drbg); - if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || - mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; -#endif - - if(ret) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error parsing private key: (-0x%04X) %s", - -ret, errorbuf); - return CURLE_SSL_CERTPROBLEM; - } - } - } - - return CURLE_OK; -} - -static CURLcode mbed_load_crl(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - const char * const ssl_crlfile = ssl_config->primary.CRLfile; - -#ifdef MBEDTLS_X509_CRL_PARSE_C - mbedtls_x509_crl_init(&backend->crl); - - if(ssl_crlfile) { - char errorbuf[128]; -#ifdef MBEDTLS_FS_IO - int ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile); - - if(ret) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: error reading CRL file %s: (-0x%04X) %s", - ssl_crlfile, -ret, errorbuf); - - return CURLE_SSL_CRL_BADFILE; - } -#else - (void)errorbuf; - failf(data, "mbedTLS: functions that use the file system not built in"); - return CURLE_NOT_BUILT_IN; -#endif - } -#else - (void)backend; - if(ssl_crlfile) { - failf(data, "mbedTLS: CRL support not built in"); - return CURLE_NOT_BUILT_IN; - } -#endif - - return CURLE_OK; -} - -static CURLcode mbed_configure_ssl(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - int ret; - CURLcode result; - char errorbuf[128]; - - infof(data, "mbedTLS: Connecting to %s:%d", - connssl->peer.hostname, connssl->peer.port); - - mbedtls_ssl_config_init(&backend->config); - ret = mbedtls_ssl_config_defaults(&backend->config, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); - if(ret) { - failf(data, "mbedTLS: ssl_config failed"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef MBEDTLS_DEBUG - /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */ - mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data); - /* - 0 No debug - * - 1 Error - * - 2 State change - * - 3 Informational - * - 4 Verbose - */ - mbedtls_debug_set_threshold(4); -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - MBEDTLS_VERSION_NUMBER >= 0x03060100 && \ - MBEDTLS_VERSION_NUMBER < 0x04000000 - /* New in mbedTLS 3.6.1, need to enable, default is now disabled. 4.0.0 - enabled it by default for TLSv1.3. */ - mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets( - &backend->config, MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED); -#endif - - /* Always let mbedTLS verify certificates, if verifypeer or verifyhost are - * disabled we clear the corresponding error flags in the verify callback - * function. That is also where we log verification errors. */ - mbedtls_ssl_conf_verify(&backend->config, mbed_verify_cb, cf); - mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_REQUIRED); - - mbedtls_ssl_init(&backend->ssl); - backend->initialized = TRUE; - - /* use the default secure profile baked into mbedTLS */ - mbedtls_ssl_conf_cert_profile(&backend->config, - &mbedtls_x509_crt_profile_next); - - result = mbed_set_ssl_version_min_max(data, backend, conn_config); - if(result) - return result; - -#if MBEDTLS_VERSION_NUMBER < 0x04000000 - mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random, - &rng.drbg); -#endif - - ret = mbedtls_ssl_setup(&backend->ssl, - &backend->config); - if(ret) { - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "mbedTLS: ssl_setup failed: " - "(-0x%04X) %s", -ret, errorbuf); - return CURLE_SSL_CONNECT_ERROR; - } - - mbedtls_ssl_set_bio(&backend->ssl, cf, - mbedtls_bio_cf_write, - mbedtls_bio_cf_read, - NULL /* rev_timeout() */); - -#ifndef MBEDTLS_SSL_PROTO_TLS1_3 - if(conn_config->cipher_list) { - result = mbed_set_selected_ciphers(data, backend, - conn_config->cipher_list, NULL); -#else - if(conn_config->cipher_list || conn_config->cipher_list13) { - result = mbed_set_selected_ciphers(data, backend, - conn_config->cipher_list, - conn_config->cipher_list13); -#endif - if(result) { - failf(data, "mbedTLS: failed to set cipher suites"); - return result; - } - } - else { - mbedtls_ssl_conf_ciphersuites(&backend->config, - mbedtls_ssl_list_ciphersuites()); - } - -#ifdef MBEDTLS_SSL_RENEGOTIATION - mbedtls_ssl_conf_renegotiation(&backend->config, - MBEDTLS_SSL_RENEGOTIATION_ENABLED); -#endif - -#ifdef MBEDTLS_SSL_SESSION_TICKETS - mbedtls_ssl_conf_session_tickets(&backend->config, - MBEDTLS_SSL_SESSION_TICKETS_DISABLED); -#endif - - /* Check if there is a cached ID we can/should use here! */ - if(Curl_ssl_scache_use(cf, data)) { - struct Curl_ssl_session *sc_session = NULL; - CURLcode sresult = Curl_ssl_scache_take(cf, data, connssl->peer.scache_key, - &sc_session); - if(!sresult && sc_session && sc_session->sdata && sc_session->sdata_len) { - mbedtls_ssl_session session; - - mbedtls_ssl_session_init(&session); - ret = mbedtls_ssl_session_load(&session, sc_session->sdata, - sc_session->sdata_len); - if(ret) { - failf(data, "SSL session error loading: -0x%x", -ret); - } - else { - ret = mbedtls_ssl_set_session(&backend->ssl, &session); - if(ret) - failf(data, "SSL session error setting: -0x%x", -ret); - else - infof(data, "SSL reusing session ID"); - } - mbedtls_ssl_session_free(&session); - } - Curl_ssl_scache_return(cf, data, connssl->peer.scache_key, - sc_session); - } - - mbedtls_ssl_conf_ca_chain(&backend->config, &backend->cacert, -#ifdef MBEDTLS_X509_CRL_PARSE_C - &backend->crl -#else - NULL -#endif - ); - - if(ssl_config->key || ssl_config->key_blob) { - mbedtls_ssl_conf_own_cert(&backend->config, &backend->clicert, - &backend->pk); - } - - if(mbedtls_ssl_set_hostname(&backend->ssl, connssl->peer.sni ? - connssl->peer.sni : connssl->peer.hostname)) { - /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks and - the name to set in the SNI extension. Thus even if curl connects to - a host specified as an IP address, this function must be used. */ - failf(data, "Failed to set SNI"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef HAS_ALPN_MBEDTLS - if(connssl->alpn) { - struct alpn_proto_buf proto; - size_t i; - - for(i = 0; i < connssl->alpn->count; ++i) { - backend->protocols[i] = connssl->alpn->entries[i]; - } - /* this function does not clone the protocols array, which is why we need - to keep it around */ - if(mbedtls_ssl_conf_alpn_protocols(&backend->config, - &backend->protocols[0])) { - failf(data, "Failed setting ALPN protocols"); - return CURLE_SSL_CONNECT_ERROR; - } - Curl_alpn_to_proto_str(&proto, connssl->alpn); - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); - } -#endif - - /* give application a chance to interfere with mbedTLS set up. */ - if(data->set.ssl.fsslctx) { - result = (*data->set.ssl.fsslctx)(data, &backend->config, - data->set.ssl.fsslctxp); - if(result) - failf(data, "error signaled by ssl ctx callback"); - } - - return result; -} - -static CURLcode mbed_connect_step1(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - CURLcode result; - - if((conn_config->version == CURL_SSLVERSION_SSLv2) || - (conn_config->version == CURL_SSLVERSION_SSLv3)) { - failf(data, "Not supported SSL version"); - return CURLE_NOT_BUILT_IN; - } - - result = mbed_load_cacert(cf, data); - if(!result) - result = mbed_load_clicert(cf, data); - if(!result) - result = mbed_load_privkey(cf, data); - if(!result) - result = mbed_load_crl(cf, data); - if(!result) - result = mbed_configure_ssl(cf, data); - if(result) - return result; - - connssl->connecting_state = ssl_connect_2; - return CURLE_OK; -} - -#if defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define HAVE_PINNED_PUBKEY -#endif - -static CURLcode mbed_connect_step2(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ -#if defined(HAVE_PINNED_PUBKEY) || defined(HAS_ALPN_MBEDTLS) - CURLcode result; -#endif - int ret; - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; -#ifdef HAVE_PINNED_PUBKEY -#ifndef CURL_DISABLE_PROXY - const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf) ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif -#endif - - DEBUGASSERT(backend); - - ret = mbedtls_ssl_handshake(&backend->ssl); - - if(ret == MBEDTLS_ERR_SSL_WANT_READ) { - connssl->io_need = CURL_SSL_IO_NEED_RECV; - return CURLE_OK; - } - else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - connssl->io_need = CURL_SSL_IO_NEED_SEND; - return CURLE_OK; - } - else if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { - failf(data, "peer certificate could not be verified"); - return CURLE_PEER_FAILED_VERIFICATION; - } - else if(ret) { - char errorbuf[128]; - CURL_TRC_CF(data, cf, "TLS version %04X", - mbedtls_ssl_get_version_number(&backend->ssl)); - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "ssl_handshake returned: (-0x%04X) %s", - -ret, errorbuf); - return CURLE_SSL_CONNECT_ERROR; - } - - { - char cipher_str[64]; - uint16_t cipher_id; - cipher_id = - (uint16_t)mbedtls_ssl_get_ciphersuite_id_from_ssl(&backend->ssl); - mbed_cipher_suite_get_str(cipher_id, cipher_str, sizeof(cipher_str), TRUE); - infof(data, "mbedTLS: %s Handshake complete, cipher is %s", - mbedtls_ssl_get_version(&backend->ssl), cipher_str); - } - -#ifdef HAVE_PINNED_PUBKEY - if(pinnedpubkey) { - int size; - const mbedtls_x509_crt *peercert; - mbedtls_x509_crt *p = NULL; - unsigned char *pubkey = NULL; - - peercert = mbedtls_ssl_get_peer_cert(&backend->ssl); - if(!peercert || !peercert->raw.p || !peercert->raw.len) { - failf(data, "Failed due to missing peer certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - p = curlx_calloc(1, sizeof(*p)); - - if(!p) - return CURLE_OUT_OF_MEMORY; - - pubkey = curlx_malloc(PUB_DER_MAX_BYTES); - - if(!pubkey) { - result = CURLE_OUT_OF_MEMORY; - goto pinnedpubkey_error; - } - - mbedtls_x509_crt_init(p); - - /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der - needs a non-const key, for now. - https://github.com/Mbed-TLS/mbedtls/issues/396 */ - if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { - failf(data, "Failed copying peer certificate"); - result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - goto pinnedpubkey_error; - } - - size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); - - if(size <= 0) { - failf(data, "Failed copying public key from peer certificate"); - result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - goto pinnedpubkey_error; - } - - /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */ - result = Curl_pin_peer_pubkey(data, - pinnedpubkey, - &pubkey[PUB_DER_MAX_BYTES - size], size); -pinnedpubkey_error: - mbedtls_x509_crt_free(p); - curlx_free(p); - curlx_free(pubkey); - if(result) - return result; - } -#endif - -#ifdef HAS_ALPN_MBEDTLS - if(connssl->alpn) { - const char *proto = mbedtls_ssl_get_alpn_protocol(&backend->ssl); - - result = Curl_alpn_set_negotiated(cf, data, connssl, - (const unsigned char *)proto, - proto ? strlen(proto) : 0); - if(result) - return result; - } -#endif - - connssl->connecting_state = ssl_connect_3; - infof(data, "SSL connected"); - - return CURLE_OK; -} - -static CURLcode mbed_new_session(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - mbedtls_ssl_session session; - bool msession_alloced = FALSE; - struct Curl_ssl_session *sc_session = NULL; - unsigned char *sdata = NULL; - size_t slen = 0; - int ietf_tls_id; - CURLcode result = CURLE_OK; - int ret; - - DEBUGASSERT(backend); - if(!Curl_ssl_scache_use(cf, data)) - return CURLE_OK; - - mbedtls_ssl_session_init(&session); - ret = mbedtls_ssl_get_session(&backend->ssl, &session); - msession_alloced = (ret != MBEDTLS_ERR_SSL_ALLOC_FAILED); - if(ret) { - failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - - mbedtls_ssl_session_save(&session, NULL, 0, &slen); - if(!slen) { - failf(data, "failed to serialize session: length is 0"); - goto out; - } - - sdata = curlx_malloc(slen); - if(!sdata) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - ret = mbedtls_ssl_session_save(&session, sdata, slen, &slen); - if(ret) { - failf(data, "failed to serialize session: -0x%x", -ret); - goto out; - } - - ietf_tls_id = mbedtls_ssl_get_version_number(&backend->ssl); - result = Curl_ssl_session_create(sdata, slen, - ietf_tls_id, - connssl->negotiated.alpn, 0, 0, - &sc_session); - sdata = NULL; /* call took ownership */ - if(!result) - result = Curl_ssl_scache_put(cf, data, connssl->peer.scache_key, - sc_session); - -out: - if(msession_alloced) - mbedtls_ssl_session_free(&session); - curlx_free(sdata); - return result; -} - -static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *mem, size_t len, size_t *pnwritten) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - int nwritten; - - DEBUGASSERT(backend); - *pnwritten = 0; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - /* mbedTLS is picky when a mbedtls_ssl_write() was previously blocked. - * It requires to be called with the same amount of bytes again, or it - * loses bytes, e.g. reporting all was sent but they were not. - * Remember the blocked length and use that when set. */ - if(backend->send_blocked) { - DEBUGASSERT(backend->send_blocked_len <= len); - CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> previously blocked " - "on %zu bytes", len, backend->send_blocked_len); - len = backend->send_blocked_len; - } - - nwritten = mbedtls_ssl_write(&backend->ssl, (const unsigned char *)mem, len); - - if(nwritten >= 0) { - *pnwritten = (size_t)nwritten; - backend->send_blocked = FALSE; - } - else { - CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X", - len, -nwritten); - switch(nwritten) { -#ifdef MBEDTLS_SSL_PROTO_TLS1_3 - case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET: -#endif - case MBEDTLS_ERR_SSL_WANT_READ: - connssl->io_need = CURL_SSL_IO_NEED_RECV; - result = CURLE_AGAIN; - break; - case MBEDTLS_ERR_SSL_WANT_WRITE: - connssl->io_need = CURL_SSL_IO_NEED_SEND; - result = CURLE_AGAIN; - break; - default: - result = CURLE_SEND_ERROR; - break; - } - if((result == CURLE_AGAIN) && !backend->send_blocked) { - backend->send_blocked = TRUE; - backend->send_blocked_len = len; - } - } - - CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> %d, %zu", - len, result, *pnwritten); - return result; -} - -static CURLcode mbedtls_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool send_shutdown, bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - unsigned char buf[1024]; - CURLcode result = CURLE_OK; - int ret = 0; - size_t i; - - DEBUGASSERT(backend); - - if(!backend->initialized || cf->shutdown) { - *done = TRUE; - return CURLE_OK; - } - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - *done = FALSE; - - if(!backend->sent_shutdown) { - /* do this only once */ - backend->sent_shutdown = TRUE; - if(send_shutdown) { - ret = mbedtls_ssl_close_notify(&backend->ssl); - switch(ret) { - case 0: /* we sent it, receive from the server */ - break; - case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: /* server also closed */ - *done = TRUE; - goto out; - case MBEDTLS_ERR_SSL_WANT_READ: - connssl->io_need = CURL_SSL_IO_NEED_RECV; - goto out; - case MBEDTLS_ERR_SSL_WANT_WRITE: - connssl->io_need = CURL_SSL_IO_NEED_SEND; - goto out; - default: - CURL_TRC_CF(data, cf, "mbedtls_shutdown error -0x%04X", -ret); - result = CURLE_RECV_ERROR; - goto out; - } - } - } - - /* SSL should now have started the shutdown from our side. Since it - * was not complete, we are lacking the close notify from the server. */ - for(i = 0; i < 10; ++i) { - ret = mbedtls_ssl_read(&backend->ssl, buf, sizeof(buf)); - /* This seems to be a bug in mbedTLS TLSv1.3 where it reports - * WANT_READ, but has not encountered an EAGAIN. */ - if(ret == MBEDTLS_ERR_SSL_WANT_READ) - ret = mbedtls_ssl_read(&backend->ssl, buf, sizeof(buf)); -#ifdef MBEDTLS_SSL_PROTO_TLS1_3 - if(ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) - continue; -#endif - if(ret <= 0) - break; - } - - if(ret > 0) { - /* still data coming in? */ - CURL_TRC_CF(data, cf, "mbedtls_shutdown, still getting data"); - } - else if(ret == 0 || (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)) { - /* We got the close notify alert and are done. */ - CURL_TRC_CF(data, cf, "mbedtls_shutdown done"); - *done = TRUE; - } - else if(ret == MBEDTLS_ERR_SSL_WANT_READ) { - CURL_TRC_CF(data, cf, "mbedtls_shutdown, need RECV"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; - } - else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - CURL_TRC_CF(data, cf, "mbedtls_shutdown, need SEND"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - } - else { - CURL_TRC_CF(data, cf, "mbedtls_shutdown error -0x%04X", -ret); - result = CURLE_RECV_ERROR; - } - -out: - cf->shutdown = (result || *done); - return result; -} - -static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - - (void)data; - DEBUGASSERT(backend); - mbedtls_pk_free(&backend->pk); - mbedtls_x509_crt_free(&backend->clicert); - mbedtls_x509_crt_free(&backend->cacert); -#ifdef MBEDTLS_X509_CRL_PARSE_C - mbedtls_x509_crl_free(&backend->crl); -#endif - curlx_safefree(backend->ciphersuites); - mbedtls_ssl_config_free(&backend->config); - if(backend->initialized) { - mbedtls_ssl_free(&backend->ssl); - backend->initialized = FALSE; - } -} - -static CURLcode mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t buffersize, size_t *pnread) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - int nread; - - DEBUGASSERT(backend); - *pnread = 0; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - - nread = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, buffersize); - if(nread > 0) - *pnread = (size_t)nread; - else { - char errorbuf[128]; - CURL_TRC_CF(data, cf, "mbedtls_ssl_read(len=%zu) -> -0x%04X", - buffersize, -nread); - switch(nread) { -#ifdef MBEDTLS_SSL_SESSION_TICKETS - case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET: - mbed_new_session(cf, data); - FALLTHROUGH(); -#endif - case MBEDTLS_ERR_SSL_WANT_READ: - connssl->io_need = CURL_SSL_IO_NEED_RECV; - result = CURLE_AGAIN; - break; - case MBEDTLS_ERR_SSL_WANT_WRITE: - connssl->io_need = CURL_SSL_IO_NEED_SEND; - result = CURLE_AGAIN; - break; - case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: - result = CURLE_OK; - break; - default: - mbedtls_strerror(nread, errorbuf, sizeof(errorbuf)); - failf(data, "ssl_read returned: (-0x%04X) %s", -nread, errorbuf); - result = CURLE_RECV_ERROR; - break; - } - } - return result; -} - -static size_t mbedtls_version(char *buffer, size_t size) -{ -#ifdef MBEDTLS_VERSION_C - /* if mbedtls_version_get_number() is available it is better */ - unsigned int version = mbedtls_version_get_number(); - return curl_msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version >> 24, - (version >> 16) & 0xff, (version >> 8) & 0xff); -#else - return curl_msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING); -#endif -} - -/* 'data' might be NULL */ -static CURLcode mbedtls_random(struct Curl_easy *data, - unsigned char *entropy, size_t length) -{ - psa_status_t status; - (void)data; - - status = psa_generate_random(entropy, length); - - return status == PSA_SUCCESS ? CURLE_OK : CURLE_FAILED_INIT; -} - -static CURLcode mbedtls_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - CURLcode result; - struct ssl_connect_data *connssl = cf->ctx; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - - if(ssl_connect_1 == connssl->connecting_state) { - result = mbed_connect_step1(cf, data); - if(result) - return result; - } - - if(ssl_connect_2 == connssl->connecting_state) { - result = mbed_connect_step2(cf, data); - if(result) - return result; - } - - if(ssl_connect_3 == connssl->connecting_state) { - /* For tls1.3 we get notified about new sessions */ - struct ssl_connect_data *ctx = cf->ctx; - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)ctx->backend; - - if(mbedtls_ssl_get_version_number(&backend->ssl) <= - MBEDTLS_SSL_VERSION_TLS1_2) { - result = mbed_new_session(cf, data); - if(result) - return result; - } - connssl->connecting_state = ssl_connect_done; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - *done = TRUE; - } - - return CURLE_OK; -} - -/* - * return 0 error initializing SSL - * return 1 SSL initialized successfully - */ -static int mbedtls_init(void) -{ -#if MBEDTLS_VERSION_NUMBER < 0x04000000 - int ret = 0; -#endif - psa_status_t status; - status = psa_crypto_init(); - - if(status != PSA_SUCCESS) - return 0; - -#if MBEDTLS_VERSION_NUMBER < 0x04000000 - mbedtls_ctr_drbg_init(&rng.drbg); - mbedtls_entropy_init(&rng.entropy); - - ret = mbedtls_ctr_drbg_seed(&rng.drbg, mbedtls_entropy_func, &rng.entropy, - NULL, 0); - - if(ret) - /* mbedtls_ctr_drbg_seed returned error */ - return 0; - - /* To prevent an adversary from reading your random data, - you can enable prediction resistance. - - Entropy is gathered before each mbedtls_ctr_drbg_random() call. - Only use this if you have ample supply of good entropy.*/ - mbedtls_ctr_drbg_set_prediction_resistance(&rng.drbg, - MBEDTLS_CTR_DRBG_PR_ON); -#endif - return 1; -} - -static void mbedtls_cleanup(void) -{ - mbedtls_psa_crypto_free(); - -#if MBEDTLS_VERSION_NUMBER < 0x04000000 - mbedtls_ctr_drbg_free(&rng.drbg); - mbedtls_entropy_free(&rng.entropy); -#endif -} - -static bool mbedtls_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct ssl_connect_data *ctx = cf->ctx; - struct mbed_ssl_backend_data *backend; - - (void)data; - DEBUGASSERT(ctx && ctx->backend); - backend = (struct mbed_ssl_backend_data *)ctx->backend; - return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0; -} - -static CURLcode mbedtls_sha256sum(const unsigned char *input, - size_t inputlen, - unsigned char *sha256sum, - size_t sha256len) -{ -#if defined(PSA_WANT_ALG_SHA_256) && PSA_WANT_ALG_SHA_256 /* mbedTLS 4+ */ - psa_status_t status; - size_t sha256len_actual; - status = psa_hash_compute(PSA_ALG_SHA_256, input, inputlen, - sha256sum, sha256len, - &sha256len_actual); - if(status != PSA_SUCCESS) - return CURLE_BAD_FUNCTION_ARGUMENT; - return CURLE_OK; -#else - (void)sha256len; - return Curl_sha256it(sha256sum, input, inputlen); -#endif -} - -static void *mbedtls_get_internals(struct ssl_connect_data *connssl, - CURLINFO info) -{ - struct mbed_ssl_backend_data *backend = - (struct mbed_ssl_backend_data *)connssl->backend; - (void)info; - DEBUGASSERT(backend); - return &backend->ssl; -} - -const struct Curl_ssl Curl_ssl_mbedtls = { - { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */ - - SSLSUPP_CA_PATH | - SSLSUPP_CAINFO_BLOB | - SSLSUPP_CERTINFO | -#ifdef HAVE_PINNED_PUBKEY - SSLSUPP_PINNEDPUBKEY | -#endif - SSLSUPP_SSL_CTX | -#ifdef MBEDTLS_SSL_PROTO_TLS1_3 /* requires mbedTLS 3.6.0+ */ - SSLSUPP_TLS13_CIPHERSUITES | -#endif - SSLSUPP_HTTPS_PROXY | - SSLSUPP_CIPHER_LIST | -#ifdef MBEDTLS_X509_CRL_PARSE_C - SSLSUPP_CRLFILE | -#endif - 0, - - sizeof(struct mbed_ssl_backend_data), - - mbedtls_init, /* init */ - mbedtls_cleanup, /* cleanup */ - mbedtls_version, /* version */ - mbedtls_shutdown, /* shutdown */ - mbedtls_data_pending, /* data_pending */ - mbedtls_random, /* random */ - NULL, /* cert_status_request */ - mbedtls_connect, /* connect */ - Curl_ssl_adjust_pollset, /* adjust_pollset */ - mbedtls_get_internals, /* get_internals */ - mbedtls_close, /* close_one */ - NULL, /* close_all */ - NULL, /* set_engine */ - NULL, /* set_engine_default */ - NULL, /* engines_list */ - mbedtls_sha256sum, /* sha256sum */ - mbed_recv, /* recv decrypted data */ - mbed_send, /* send data to encrypt */ - NULL, /* get_channel_binding */ -}; - -#endif /* USE_MBEDTLS */ diff --git a/vendor/curl/lib/vtls/mbedtls.h b/vendor/curl/lib/vtls/mbedtls.h deleted file mode 100644 index d8a0a06eb..000000000 --- a/vendor/curl/lib/vtls/mbedtls.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef HEADER_CURL_MBEDTLS_H -#define HEADER_CURL_MBEDTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Hoi-Ho Chan, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_MBEDTLS - -extern const struct Curl_ssl Curl_ssl_mbedtls; - -#endif /* USE_MBEDTLS */ -#endif /* HEADER_CURL_MBEDTLS_H */ diff --git a/vendor/curl/lib/vtls/openssl.c b/vendor/curl/lib/vtls/openssl.c deleted file mode 100644 index 4629ca444..000000000 --- a/vendor/curl/lib/vtls/openssl.c +++ /dev/null @@ -1,5532 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - */ -#include "curl_setup.h" - -#ifdef USE_OPENSSL - -#include "urldata.h" -#include "curl_trc.h" -#include "httpsrr.h" -#include "formdata.h" /* for the boundary function */ -#include "url.h" /* for the ssl config check function */ -#include "curlx/inet_pton.h" -#include "vtls/openssl.h" -#include "connect.h" -#include "cf-dns.h" -#include "progress.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" -#include "vtls/vtls_scache.h" -#include "vauth/vauth.h" -#include "vtls/keylog.h" -#include "vtls/hostcheck.h" -#include "transfer.h" -#include "multiif.h" -#include "curlx/strerr.h" -#include "curlx/strparse.h" -#include "curlx/strcopy.h" -#include "curlx/strdup.h" -#include "vtls/apple.h" -#ifdef USE_ECH -#include "curlx/base64.h" -#endif - -#include -#include -#ifndef OPENSSL_NO_DSA -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(HAVE_SSL_SET1_ECH_CONFIG_LIST) && !defined(HAVE_BORINGSSL_LIKE) -#include -#endif - -#ifndef OPENSSL_NO_OCSP -#include -#endif - -#if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_UI_CONSOLE) -#define USE_OPENSSL_ENGINE -#include -#endif - -#ifdef LIBRESSL_VERSION_NUMBER -/* As of LibreSSL 2.0.0-4.0.0: OPENSSL_VERSION_NUMBER == 0x20000000L */ -# if LIBRESSL_VERSION_NUMBER < 0x2090100fL /* 2019-04-13 */ -# error "LibreSSL 2.9.1 or later required" -# endif -#elif !defined(HAVE_BORINGSSL_LIKE) -# ifndef HAVE_OPENSSL3 /* 2021-09-07 */ -# error "OpenSSL 3.0.0 or later required" -# endif -#endif - -#if defined(HAVE_OPENSSL3) && !defined(OPENSSL_NO_UI_CONSOLE) -#include -#include -/* this is used in the following conditions to make them easier to read */ -#define OPENSSL_HAS_PROVIDERS -#endif - -/* AWS-LC fixed a bug with large buffers in v1.61.0 which also introduced - * X509_V_ERR_EC_KEY_EXPLICIT_PARAMS. */ -#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) && \ - (!defined(OPENSSL_IS_AWSLC) || defined(X509_V_ERR_EC_KEY_EXPLICIT_PARAMS)) -#define HAVE_SSL_CTX_SET_DEFAULT_READ_BUFFER_LEN 1 -#endif - -#if defined(USE_OPENSSL_ENGINE) || defined(OPENSSL_HAS_PROVIDERS) -#include -#endif - -#ifdef HAVE_OPENSSL3 -#define HAVE_EVP_PKEY_GET_PARAMS 1 -#endif - -#ifdef HAVE_EVP_PKEY_GET_PARAMS -#include -#define DECLARE_PKEY_PARAM_BIGNUM(name) BIGNUM *name = NULL -#define FREE_PKEY_PARAM_BIGNUM(name) BN_clear_free(name) -#else -#define DECLARE_PKEY_PARAM_BIGNUM(name) const BIGNUM *name -#define FREE_PKEY_PARAM_BIGNUM(name) -#endif - -/* Whether SSL_CTX_set_ciphersuites is available. - * OpenSSL: supported since 1.1.1 (commit a53b5be6a05) - * BoringSSL: no - * LibreSSL: supported since 3.4.1 (released 2021-10-14) - */ -#if (!defined(LIBRESSL_VERSION_NUMBER) || \ - (defined(LIBRESSL_VERSION_NUMBER) && \ - LIBRESSL_VERSION_NUMBER >= 0x3040100fL)) && \ - !defined(OPENSSL_IS_BORINGSSL) -# define HAVE_SSL_CTX_SET_CIPHERSUITES -# ifndef OPENSSL_IS_AWSLC -# define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH -# endif -#endif - -/* Whether SSL_CTX_set1_sigalgs_list is available - * OpenSSL: supported since 1.0.2 (commit 0b362de5f575) - * BoringSSL: supported since 0.20240913.0 (commit 826ce15) - * LibreSSL: no - */ -#ifndef LIBRESSL_VERSION_NUMBER -#define HAVE_SSL_CTX_SET1_SIGALGS -#endif - -#ifdef LIBRESSL_VERSION_NUMBER -#define OSSL_PACKAGE "LibreSSL" -#elif defined(OPENSSL_IS_BORINGSSL) -#define OSSL_PACKAGE "BoringSSL" -#elif defined(OPENSSL_IS_AWSLC) -#define OSSL_PACKAGE "AWS-LC" -#elif defined(USE_NGTCP2) && defined(USE_NGHTTP3) && \ - !defined(OPENSSL_QUIC_API2) -#define OSSL_PACKAGE "quictls" -#else -#define OSSL_PACKAGE "OpenSSL" -#endif - -#ifdef HAVE_BORINGSSL_LIKE -typedef size_t numcert_t; -typedef uint32_t sslerr_t; -#else -typedef int numcert_t; -typedef unsigned long sslerr_t; -#endif -#define ossl_valsize_t numcert_t - -static CURLcode push_certinfo(struct Curl_easy *data, - BIO *mem, const char *label, int num) - WARN_UNUSED_RESULT; - -static CURLcode push_certinfo(struct Curl_easy *data, - BIO *mem, const char *label, int num) -{ - char *ptr; - long len = BIO_get_mem_data(mem, &ptr); - CURLcode result = Curl_ssl_push_certinfo_len(data, num, label, ptr, len); - (void)BIO_reset(mem); - return result; -} - -static CURLcode pubkey_show(struct Curl_easy *data, - BIO *mem, - int num, - const char *type, - const char *name, - const BIGNUM *bn) WARN_UNUSED_RESULT; - -static CURLcode pubkey_show(struct Curl_easy *data, - BIO *mem, - int num, - const char *type, - const char *name, - const BIGNUM *bn) -{ - char namebuf[32]; - - curl_msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); - - if(bn) - BN_print(mem, bn); - return push_certinfo(data, mem, namebuf, num); -} - -#define print_pubkey_BN(_type, _name, _num) \ - pubkey_show(data, mem, _num, #_type, #_name, _name) - -static int asn1_object_dump(const ASN1_OBJECT *a, char *buf, size_t len) -{ - int i = i2t_ASN1_OBJECT(buf, (int)len, a); - return (i >= (int)len); /* buffer too small */ -} - -static CURLcode X509V3_ext(struct Curl_easy *data, - int certnum, - const STACK_OF(X509_EXTENSION) *extsarg) -{ - int i; - CURLcode result = CURLE_OK; -#ifdef LIBRESSL_VERSION_NUMBER - STACK_OF(X509_EXTENSION) *exts = CURL_UNCONST(extsarg); -#else - const STACK_OF(X509_EXTENSION) *exts = extsarg; -#endif - - if((int)sk_X509_EXTENSION_num(exts) <= 0) - /* no extensions, bail out */ - return result; - - for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) { - const ASN1_OBJECT *obj; - X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, (ossl_valsize_t)i); - BUF_MEM *biomem; - char namebuf[128]; - BIO *bio_out = BIO_new(BIO_s_mem()); - - if(!bio_out) - return result; - - obj = X509_EXTENSION_get_object(ext); - - if(asn1_object_dump(obj, namebuf, sizeof(namebuf))) - /* make sure the name is null-terminated */ - namebuf[sizeof(namebuf) - 1] = 0; - - if(!X509V3_EXT_print(bio_out, ext, 0, 0)) - ASN1_STRING_print(bio_out, - (const ASN1_STRING *)X509_EXTENSION_get_data(ext)); - - BIO_get_mem_ptr(bio_out, &biomem); - result = Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, - biomem->length); - BIO_free(bio_out); - if(result) - break; - } - return result; -} - -static CURLcode get_pkey_rsa(struct Curl_easy *data, - EVP_PKEY *pubkey, BIO *mem, int i) -{ - CURLcode result = CURLE_OK; -#ifndef HAVE_EVP_PKEY_GET_PARAMS - RSA *rsa = EVP_PKEY_get0_RSA(pubkey); -#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ - DECLARE_PKEY_PARAM_BIGNUM(n); - DECLARE_PKEY_PARAM_BIGNUM(e); -#ifdef HAVE_EVP_PKEY_GET_PARAMS - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e); -#else - RSA_get0_key(rsa, &n, &e, NULL); -#endif /* HAVE_EVP_PKEY_GET_PARAMS */ - BIO_printf(mem, "%d", (int)(n ? BN_num_bits(n) : 0)); - result = push_certinfo(data, mem, "RSA Public Key", i); - if(!result) { - result = print_pubkey_BN(rsa, n, i); - if(!result) - result = print_pubkey_BN(rsa, e, i); - } - FREE_PKEY_PARAM_BIGNUM(n); - FREE_PKEY_PARAM_BIGNUM(e); - return result; -} - -#ifndef OPENSSL_NO_DSA -static CURLcode get_pkey_dsa(struct Curl_easy *data, - EVP_PKEY *pubkey, BIO *mem, int i) -{ - CURLcode result = CURLE_OK; -#ifndef HAVE_EVP_PKEY_GET_PARAMS - DSA *dsa = EVP_PKEY_get0_DSA(pubkey); -#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ - DECLARE_PKEY_PARAM_BIGNUM(p); - DECLARE_PKEY_PARAM_BIGNUM(q); - DECLARE_PKEY_PARAM_BIGNUM(g); - DECLARE_PKEY_PARAM_BIGNUM(pub_key); -#ifdef HAVE_EVP_PKEY_GET_PARAMS - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); -#else - DSA_get0_pqg(dsa, &p, &q, &g); - DSA_get0_key(dsa, &pub_key, NULL); -#endif /* HAVE_EVP_PKEY_GET_PARAMS */ - result = print_pubkey_BN(dsa, p, i); - if(!result) - result = print_pubkey_BN(dsa, q, i); - if(!result) - result = print_pubkey_BN(dsa, g, i); - if(!result) - result = print_pubkey_BN(dsa, pub_key, i); - FREE_PKEY_PARAM_BIGNUM(p); - FREE_PKEY_PARAM_BIGNUM(q); - FREE_PKEY_PARAM_BIGNUM(g); - FREE_PKEY_PARAM_BIGNUM(pub_key); - return result; -} -#endif /* !OPENSSL_NO_DSA */ - -static CURLcode get_pkey_dh(struct Curl_easy *data, - EVP_PKEY *pubkey, BIO *mem, int i) -{ - CURLcode result; -#ifndef HAVE_EVP_PKEY_GET_PARAMS - DH *dh = EVP_PKEY_get0_DH(pubkey); -#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ - DECLARE_PKEY_PARAM_BIGNUM(p); - DECLARE_PKEY_PARAM_BIGNUM(q); - DECLARE_PKEY_PARAM_BIGNUM(g); - DECLARE_PKEY_PARAM_BIGNUM(pub_key); -#ifdef HAVE_EVP_PKEY_GET_PARAMS - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); -#else - DH_get0_pqg(dh, &p, &q, &g); - DH_get0_key(dh, &pub_key, NULL); -#endif /* HAVE_EVP_PKEY_GET_PARAMS */ - result = print_pubkey_BN(dh, p, i); - if(!result) - result = print_pubkey_BN(dh, q, i); - if(!result) - result = print_pubkey_BN(dh, g, i); - if(!result) - result = print_pubkey_BN(dh, pub_key, i); - FREE_PKEY_PARAM_BIGNUM(p); - FREE_PKEY_PARAM_BIGNUM(q); - FREE_PKEY_PARAM_BIGNUM(g); - FREE_PKEY_PARAM_BIGNUM(pub_key); - return result; -} - -#ifdef HAVE_OPENSSL3 -/* from OpenSSL commit fc756e594ed5a27af378 */ -typedef const X509_PUBKEY pubkeytype_t; -#else -typedef X509_PUBKEY pubkeytype_t; -#endif - -static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl) -{ - CURLcode result; - STACK_OF(X509) *sk; - int i; - numcert_t numcerts; - BIO *mem; - - DEBUGASSERT(ssl); - - sk = SSL_get_peer_cert_chain(ssl); - if(!sk) - return CURLE_SSL_CONNECT_ERROR; - - numcerts = sk_X509_num(sk); - if(numcerts > MAX_ALLOWED_CERT_AMOUNT) { - failf(data, "%d certificates is more than allowed (%d)", (int)numcerts, - MAX_ALLOWED_CERT_AMOUNT); - return CURLE_SSL_CONNECT_ERROR; - } - - result = Curl_ssl_init_certinfo(data, (int)numcerts); - if(result) - return result; - - mem = BIO_new(BIO_s_mem()); - if(!mem) - result = CURLE_OUT_OF_MEMORY; - - for(i = 0; !result && (i < (int)numcerts); i++) { - ASN1_INTEGER *num; - const unsigned char *numdata; - X509 *x = sk_X509_value(sk, (ossl_valsize_t)i); - EVP_PKEY *pubkey = NULL; - int j; - const ASN1_BIT_STRING *psig = NULL; - - X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); - result = push_certinfo(data, mem, "Subject", i); - if(result) - break; - - X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); - result = push_certinfo(data, mem, "Issuer", i); - if(result) - break; - - BIO_printf(mem, "%lx", X509_get_version(x)); - result = push_certinfo(data, mem, "Version", i); - if(result) - break; - - num = X509_get_serialNumber(x); - if(ASN1_STRING_type(num) == V_ASN1_NEG_INTEGER) - BIO_puts(mem, "-"); - numdata = ASN1_STRING_get0_data(num); - for(j = 0; j < ASN1_STRING_length(num); j++) - BIO_printf(mem, "%02x", numdata[j]); - result = push_certinfo(data, mem, "Serial Number", i); - if(result) - break; - - { - const X509_ALGOR *sigalg = NULL; - pubkeytype_t *xpubkey = NULL; - ASN1_OBJECT *pubkeyoid = NULL; - - X509_get0_signature(&psig, &sigalg, x); - if(sigalg) { - const ASN1_OBJECT *sigalgoid = NULL; - X509_ALGOR_get0(&sigalgoid, NULL, NULL, sigalg); - i2a_ASN1_OBJECT(mem, sigalgoid); - result = push_certinfo(data, mem, "Signature Algorithm", i); - if(result) - break; - } - - xpubkey = X509_get_X509_PUBKEY(x); - if(xpubkey) { - X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); - if(pubkeyoid) { - i2a_ASN1_OBJECT(mem, pubkeyoid); - result = push_certinfo(data, mem, "Public Key Algorithm", i); - if(result) - break; - } - } - - result = X509V3_ext(data, i, X509_get0_extensions(x)); - if(result) - break; - } - - ASN1_TIME_print(mem, X509_get0_notBefore(x)); - result = push_certinfo(data, mem, "Start date", i); - if(result) - break; - - ASN1_TIME_print(mem, X509_get0_notAfter(x)); - result = push_certinfo(data, mem, "Expire date", i); - if(result) - break; - - pubkey = X509_get_pubkey(x); - if(!pubkey) - infof(data, " Unable to load public key"); - else { - switch(EVP_PKEY_id(pubkey)) { - case EVP_PKEY_RSA: - result = get_pkey_rsa(data, pubkey, mem, i); - break; - -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - result = get_pkey_dsa(data, pubkey, mem, i); - break; -#endif - - case EVP_PKEY_DH: - result = get_pkey_dh(data, pubkey, mem, i); - break; - } - EVP_PKEY_free(pubkey); - } - - if(!result && psig) { - const unsigned char *psigdata = ASN1_STRING_get0_data(psig); - for(j = 0; j < ASN1_STRING_length(psig); j++) - BIO_printf(mem, "%02x:", psigdata[j]); - result = push_certinfo(data, mem, "Signature", i); - } - - if(!result) { - PEM_write_bio_X509(mem, x); - result = push_certinfo(data, mem, "Cert", i); - } - } - - BIO_free(mem); - - if(result) - /* cleanup all leftovers */ - Curl_ssl_free_certinfo(data); - - return result; -} - -static int ossl_bio_cf_create(BIO *bio) -{ - BIO_set_shutdown(bio, 1); - BIO_set_init(bio, 1); - BIO_set_data(bio, NULL); - return 1; -} - -static int ossl_bio_cf_destroy(BIO *bio) -{ - if(!bio) - return 0; - return 1; -} - -static long ossl_bio_cf_ctrl(BIO *bio, int cmd, long num, void *ptr) -{ - struct Curl_cfilter *cf = BIO_get_data(bio); - long ret = 1; - - (void)cf; - (void)ptr; - switch(cmd) { - case BIO_CTRL_GET_CLOSE: - ret = (long)BIO_get_shutdown(bio); - break; - case BIO_CTRL_SET_CLOSE: - BIO_set_shutdown(bio, (int)num); - break; - case BIO_CTRL_FLUSH: - /* we do no delayed writes, but if we ever would, this - * needs to trigger it. */ - ret = 1; - break; - case BIO_CTRL_DUP: - ret = 1; - break; - case BIO_CTRL_EOF: { - /* EOF has been reached on input? */ - struct ssl_connect_data *connssl = cf->ctx; - return connssl->peer_closed; - } - default: - ret = 0; - break; - } - return ret; -} - -static int ossl_bio_cf_out_write(BIO *bio, const char *buf, int blen) -{ - struct Curl_cfilter *cf = BIO_get_data(bio); - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nwritten; - CURLcode result; - - DEBUGASSERT(data); - if(blen < 0) - return 0; - - result = Curl_conn_cf_send(cf->next, data, - (const uint8_t *)buf, (size_t)blen, FALSE, - &nwritten); - CURL_TRC_CF(data, cf, "ossl_bio_cf_out_write(len=%d) -> %d, %zu", - blen, result, nwritten); - BIO_clear_retry_flags(bio); - octx->io_result = result; - if(result) { - if(result == CURLE_AGAIN) - BIO_set_retry_write(bio); - return -1; - } - return (int)nwritten; -} - -static int ossl_bio_cf_in_read(BIO *bio, char *buf, int blen) -{ - struct Curl_cfilter *cf = BIO_get_data(bio); - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nread; - CURLcode result, r2; - - DEBUGASSERT(data); - /* OpenSSL catches this case, so should we. */ - if(!buf) - return 0; - if(blen < 0) - return 0; - - result = Curl_conn_cf_recv(cf->next, data, buf, (size_t)blen, &nread); - CURL_TRC_CF(data, cf, "ossl_bio_cf_in_read(len=%d) -> %d, %zu", - blen, result, nread); - BIO_clear_retry_flags(bio); - octx->io_result = result; - if(result) { - if(result == CURLE_AGAIN) - BIO_set_retry_read(bio); - } - else { - /* feeding data to OpenSSL means SSL_read() might succeed */ - connssl->input_pending = TRUE; - if(nread == 0) - connssl->peer_closed = TRUE; - } - - /* Before returning server replies to the SSL instance, we need - * to have setup the x509 store or verification fails. */ - if(!octx->x509_store_setup) { - r2 = Curl_ssl_setup_x509_store(cf, data, octx); - if(r2) { - BIO_clear_retry_flags(bio); - octx->io_result = r2; - return -1; - } - octx->x509_store_setup = TRUE; - } - return result ? -1 : (int)nread; -} - -static BIO_METHOD *ossl_bio_cf_method_create(void) -{ - BIO_METHOD *m = BIO_meth_new(BIO_TYPE_MEM, "OpenSSL CF BIO"); - if(m) { - BIO_meth_set_write(m, &ossl_bio_cf_out_write); - BIO_meth_set_read(m, &ossl_bio_cf_in_read); - BIO_meth_set_ctrl(m, &ossl_bio_cf_ctrl); - BIO_meth_set_create(m, &ossl_bio_cf_create); - BIO_meth_set_destroy(m, &ossl_bio_cf_destroy); - } - return m; -} - -static void ossl_bio_cf_method_free(BIO_METHOD *m) -{ - if(m) - BIO_meth_free(m); -} - -#ifndef HAVE_KEYLOG_UPSTREAM -#ifdef HAVE_KEYLOG_CALLBACK -static void ossl_keylog_callback(const SSL *ssl, const char *line) -{ - (void)ssl; - - Curl_tls_keylog_write_line(line); -} -#else -/* - * ossl_log_tls12_secret is called by libcurl to make the CLIENT_RANDOMs if the - * OpenSSL being used does not have native support for doing that. - */ -static void ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done) -{ - const SSL_SESSION *session; - unsigned char client_random[SSL3_RANDOM_SIZE]; - unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; - int master_key_length = 0; - - ERR_set_mark(); - - session = SSL_get_session(ssl); - - if(!session || *keylog_done) { - ERR_pop_to_mark(); - return; - } - - SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE); - master_key_length = (int) - SSL_SESSION_get_master_key(session, master_key, SSL_MAX_MASTER_KEY_LENGTH); - - ERR_pop_to_mark(); - - /* The handshake has not progressed sufficiently yet, or this is a TLS 1.3 - * session (when curl was built with older OpenSSL headers and running with - * newer OpenSSL runtime libraries). */ - if(master_key_length <= 0) - return; - - *keylog_done = TRUE; - Curl_tls_keylog_write("CLIENT_RANDOM", client_random, - master_key, master_key_length); -} -#endif /* !HAVE_KEYLOG_CALLBACK */ -#endif /* HAVE_KEYLOG_UPSTREAM */ - -static const char *SSL_ERROR_to_str(int err) -{ - switch(err) { - case SSL_ERROR_NONE: - return "SSL_ERROR_NONE"; - case SSL_ERROR_SSL: - return "SSL_ERROR_SSL"; - case SSL_ERROR_WANT_READ: - return "SSL_ERROR_WANT_READ"; - case SSL_ERROR_WANT_WRITE: - return "SSL_ERROR_WANT_WRITE"; - case SSL_ERROR_WANT_X509_LOOKUP: - return "SSL_ERROR_WANT_X509_LOOKUP"; - case SSL_ERROR_SYSCALL: - return "SSL_ERROR_SYSCALL"; - case SSL_ERROR_ZERO_RETURN: - return "SSL_ERROR_ZERO_RETURN"; - case SSL_ERROR_WANT_CONNECT: - return "SSL_ERROR_WANT_CONNECT"; - case SSL_ERROR_WANT_ACCEPT: - return "SSL_ERROR_WANT_ACCEPT"; -#ifdef SSL_ERROR_WANT_ASYNC /* OpenSSL 1.1.0+, LibreSSL 3.6.0+ */ - case SSL_ERROR_WANT_ASYNC: - return "SSL_ERROR_WANT_ASYNC"; -#endif -#ifdef SSL_ERROR_WANT_ASYNC_JOB /* OpenSSL 1.1.0+, LibreSSL 3.6.0+ */ - case SSL_ERROR_WANT_ASYNC_JOB: - return "SSL_ERROR_WANT_ASYNC_JOB"; -#endif -#ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB /* OpenSSL 1.1.1, LibreSSL 3.6.0+ */ - case SSL_ERROR_WANT_CLIENT_HELLO_CB: - return "SSL_ERROR_WANT_CLIENT_HELLO_CB"; -#endif - default: - return "SSL_ERROR unknown"; - } -} - -/* Return error string for last OpenSSL error - */ -static char *ossl_strerror(unsigned long error, char *buf, size_t size) -{ - size_t len; - DEBUGASSERT(size); - *buf = '\0'; - - len = Curl_ossl_version(buf, size); - DEBUGASSERT(len < (size - 2)); - if(len < (size - 2)) { - buf += len; - size -= (len + 2); - *buf++ = ':'; - *buf++ = ' '; - *buf = '\0'; - } - -#ifdef HAVE_BORINGSSL_LIKE - ERR_error_string_n((uint32_t)error, buf, size); -#else - ERR_error_string_n(error, buf, size); -#endif - - if(!*buf) { - const char *msg = error ? "Unknown error" : "No error"; - curlx_strcopy(buf, size, msg, strlen(msg)); - } - - return buf; -} - -static int passwd_callback(char *buf, int num, int encrypting, void *password) -{ - DEBUGASSERT(encrypting == 0); - - if(!encrypting && num >= 0 && password) { - int klen = curlx_uztosi(strlen((char *)password)); - if(num > klen) { - memcpy(buf, password, klen + 1); - return klen; - } - } - return 0; -} - -/* - * rand_enough() returns TRUE if we have seeded the random engine properly. - */ -static bool rand_enough(void) -{ - return RAND_status() != 0; -} - -static CURLcode ossl_seed(struct Curl_easy *data) -{ - /* This might get called before it has been added to a multi handle */ - if(data->multi && data->multi->ssl_seeded) - return CURLE_OK; - - if(rand_enough()) { - /* OpenSSL 1.1.0+ should return here */ - if(data->multi) - data->multi->ssl_seeded = TRUE; - return CURLE_OK; - } - failf(data, "Insufficient randomness"); - return CURLE_SSL_CONNECT_ERROR; -} - -#ifndef SSL_FILETYPE_ENGINE -#define SSL_FILETYPE_ENGINE 42 -#endif -#ifndef SSL_FILETYPE_PKCS12 -#define SSL_FILETYPE_PKCS12 43 -#endif -#ifndef SSL_FILETYPE_PROVIDER -#define SSL_FILETYPE_PROVIDER 44 -#endif -static int ossl_do_file_type(const char *type) -{ - if(!type || !type[0]) - return SSL_FILETYPE_PEM; - if(curl_strequal(type, "PEM")) - return SSL_FILETYPE_PEM; - if(curl_strequal(type, "DER")) - return SSL_FILETYPE_ASN1; - if(curl_strequal(type, "PROV")) - return SSL_FILETYPE_PROVIDER; - if(curl_strequal(type, "ENG")) - return SSL_FILETYPE_ENGINE; - if(curl_strequal(type, "P12")) - return SSL_FILETYPE_PKCS12; - return -1; -} - -#if defined(USE_OPENSSL_ENGINE) || defined(OPENSSL_HAS_PROVIDERS) -/* - * Supply default password to the engine user interface conversation. - * The password is passed by OpenSSL engine from ENGINE_load_private_key() - * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. - */ -static int ssl_ui_reader(UI *ui, UI_STRING *uis) -{ - const char *password; - switch(UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - password = (const char *)UI_get0_user_data(ui); - if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { - UI_set_result(ui, uis, password); - return 1; - } - FALLTHROUGH(); - default: - break; - } - return (UI_method_get_reader(UI_OpenSSL()))(ui, uis); -} - -/* - * Suppress interactive request for a default password if available. - */ -static int ssl_ui_writer(UI *ui, UI_STRING *uis) -{ - switch(UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - if(UI_get0_user_data(ui) && - (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { - return 1; - } - FALLTHROUGH(); - default: - break; - } - return (UI_method_get_writer(UI_OpenSSL()))(ui, uis); -} - -/* - * Check if a given string is a PKCS#11 URI - */ -static bool is_pkcs11_uri(const char *string) -{ - return string && curl_strnequal(string, "pkcs11:", 7); -} - -#endif - -static CURLcode ossl_set_engine(struct Curl_easy *data, const char *name); -#ifdef OPENSSL_HAS_PROVIDERS -static CURLcode ossl_set_provider(struct Curl_easy *data, const char *iname); -#endif - -static int use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob, - int type, const char *key_passwd) -{ - int ret = 0; - X509 *x = NULL; - /* the typecast of blob->len is fine since it is guaranteed to never be - larger than CURL_MAX_INPUT_LENGTH */ - BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len)); - if(!in) - return CURLE_OUT_OF_MEMORY; - - if(type == SSL_FILETYPE_ASN1) { - /* j = ERR_R_ASN1_LIB; */ - x = d2i_X509_bio(in, NULL); - } - else if(type == SSL_FILETYPE_PEM) { - /* ERR_R_PEM_LIB; */ - x = PEM_read_bio_X509(in, NULL, passwd_callback, CURL_UNCONST(key_passwd)); - } - else { - ret = 0; - goto end; - } - - if(!x) { - ret = 0; - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); -end: - X509_free(x); - BIO_free(in); - return ret; -} - -static int use_privatekey_blob(SSL_CTX *ctx, const struct curl_blob *blob, - int type, const char *key_passwd) -{ - int ret = 0; - EVP_PKEY *pkey = NULL; - BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len)); - if(!in) - return CURLE_OUT_OF_MEMORY; - - if(type == SSL_FILETYPE_PEM) - pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback, - CURL_UNCONST(key_passwd)); - else if(type == SSL_FILETYPE_ASN1) - pkey = d2i_PrivateKey_bio(in, NULL); - else - goto end; - - if(!pkey) - goto end; - - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); -end: - BIO_free(in); - return ret; -} - -static int use_certificate_chain_blob(SSL_CTX *ctx, - const struct curl_blob *blob, - const char *key_passwd) -{ - int ret = 0; - X509 *x = NULL; - BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len)); - if(!in) - return CURLE_OUT_OF_MEMORY; - - ERR_clear_error(); - - x = PEM_read_bio_X509_AUX(in, NULL, - passwd_callback, CURL_UNCONST(key_passwd)); - if(!x) - goto end; - - ret = SSL_CTX_use_certificate(ctx, x); - - if(ERR_peek_error() != 0) - ret = 0; - - if(ret) { - X509 *ca; - sslerr_t err; - - if(!SSL_CTX_clear_chain_certs(ctx)) { - ret = 0; - goto end; - } - - while((ca = PEM_read_bio_X509(in, NULL, passwd_callback, - CURL_UNCONST(key_passwd))) != NULL) { - - if(!SSL_CTX_add0_chain_cert(ctx, ca)) { - X509_free(ca); - ret = 0; - goto end; - } - } - - err = ERR_peek_last_error(); - if((ERR_GET_LIB(err) == ERR_LIB_PEM) && - (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) - ERR_clear_error(); - else - ret = 0; - } - -end: - X509_free(x); - BIO_free(in); - return ret; -} - -static int enginecheck(struct Curl_easy *data, - SSL_CTX* ctx, - const char *key_file, - const char *key_passwd) -{ -#ifdef USE_OPENSSL_ENGINE - EVP_PKEY *priv_key = NULL; - - /* Implicitly use pkcs11 engine if none was provided and the - * key_file is a PKCS#11 URI */ - if(!data->state.engine) { - if(is_pkcs11_uri(key_file)) { - if(ossl_set_engine(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } - - if(data->state.engine) { - UI_METHOD *ui_method = UI_create_method("curl user interface"); - if(!ui_method) { - failf(data, "unable to create " OSSL_PACKAGE " user-interface method"); - return 0; - } - UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); - UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); - UI_method_set_reader(ui_method, ssl_ui_reader); - UI_method_set_writer(ui_method, ssl_ui_writer); - priv_key = ENGINE_load_private_key(data->state.engine, key_file, - ui_method, - CURL_UNCONST(key_passwd)); - UI_destroy_method(ui_method); - if(!priv_key) { - failf(data, "failed to load private key from crypto engine"); - return 0; - } - if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { - failf(data, "unable to set private key"); - EVP_PKEY_free(priv_key); - return 0; - } - EVP_PKEY_free(priv_key); /* we do not need the handle any more... */ - } - else { - failf(data, "crypto engine not set, cannot load private key"); - return 0; - } - return 1; -#else - (void)ctx; - (void)key_file; - (void)key_passwd; - failf(data, "SSL_FILETYPE_ENGINE not supported for private key"); - return 0; -#endif -} - -static int providercheck(struct Curl_easy *data, - SSL_CTX* ctx, - const char *key_file) -{ -#ifdef OPENSSL_HAS_PROVIDERS - char error_buffer[256]; - /* Implicitly use pkcs11 provider if none was provided and the - * key_file is a PKCS#11 URI */ - if(!data->state.provider_loaded) { - if(is_pkcs11_uri(key_file)) { - if(ossl_set_provider(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } - - if(data->state.provider_loaded) { - /* Load the private key from the provider */ - EVP_PKEY *priv_key = NULL; - OSSL_STORE_CTX *store = NULL; - OSSL_STORE_INFO *info = NULL; - UI_METHOD *ui_method = UI_create_method("curl user interface"); - if(!ui_method) { - failf(data, "unable to create " OSSL_PACKAGE " user-interface method"); - return 0; - } - UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); - UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); - UI_method_set_reader(ui_method, ssl_ui_reader); - UI_method_set_writer(ui_method, ssl_ui_writer); - - store = OSSL_STORE_open_ex(key_file, data->state.libctx, - data->state.propq, ui_method, NULL, NULL, - NULL, NULL); - if(!store) { - failf(data, "Failed to open OpenSSL store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - UI_destroy_method(ui_method); - return 0; - } - if(OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) != 1) { - failf(data, "Failed to set store preference. Ignoring the error: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - } - - info = OSSL_STORE_load(store); - if(info) { - int ossl_type = OSSL_STORE_INFO_get_type(info); - - if(ossl_type == OSSL_STORE_INFO_PKEY) - priv_key = OSSL_STORE_INFO_get1_PKEY(info); - OSSL_STORE_INFO_free(info); - } - OSSL_STORE_close(store); - UI_destroy_method(ui_method); - if(!priv_key) { - failf(data, "No private key found in the openssl store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - - if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { - failf(data, "unable to set private key [%s]", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - EVP_PKEY_free(priv_key); - return 0; - } - EVP_PKEY_free(priv_key); /* we do not need the handle any more... */ - } - else { - failf(data, "crypto provider not set, cannot load private key"); - return 0; - } - return 1; -#else - (void)ctx; - (void)key_file; - failf(data, "SSL_FILETYPE_PROVIDER not supported for private key"); - return 0; -#endif -} - -static int engineload(struct Curl_easy *data, - SSL_CTX* ctx, - const char *cert_file) -{ -/* ENGINE_CTRL_GET_CMD_FROM_NAME supported by OpenSSL, LibreSSL <=3.8.3 */ -#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) - char error_buffer[256]; - /* Implicitly use pkcs11 engine if none was provided and the - * cert_file is a PKCS#11 URI */ - if(!data->state.engine) { - if(is_pkcs11_uri(cert_file)) { - if(ossl_set_engine(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } - - if(data->state.engine) { - const char *cmd_name = "LOAD_CERT_CTRL"; - struct { - const char *cert_id; - X509 *cert; - } params; - - params.cert_id = cert_file; - params.cert = NULL; - - /* Does the engine supports LOAD_CERT_CTRL ? */ - if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME, - 0, CURL_UNCONST(cmd_name), NULL)) { - failf(data, "ssl engine does not support loading certificates"); - return 0; - } - - /* Load the certificate from the engine */ - if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name, 0, ¶ms, NULL, 1)) { - failf(data, "ssl engine cannot load client cert with id '%s' [%s]", - cert_file, - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - - if(!params.cert) { - failf(data, "ssl engine did not initialized the certificate properly."); - return 0; - } - - if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { - failf(data, "unable to set client certificate [%s]", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - X509_free(params.cert); - return 0; - } - X509_free(params.cert); /* we do not need the handle any more... */ - } - else { - failf(data, "crypto engine not set, cannot load certificate"); - return 0; - } - return 1; -#else - (void)ctx; - (void)cert_file; - failf(data, "SSL_FILETYPE_ENGINE not supported for certificate"); - return 0; -#endif -} - -static int providerload(struct Curl_easy *data, - SSL_CTX* ctx, - const char *cert_file) -{ -#ifdef OPENSSL_HAS_PROVIDERS - char error_buffer[256]; - /* Implicitly use pkcs11 provider if none was provided and the - * cert_file is a PKCS#11 URI */ - if(!data->state.provider_loaded) { - if(is_pkcs11_uri(cert_file)) { - if(ossl_set_provider(data, "pkcs11") != CURLE_OK) { - return 0; - } - } - } - - if(data->state.provider_loaded) { - /* Load the certificate from the provider */ - OSSL_STORE_INFO *info = NULL; - X509 *cert = NULL; - OSSL_STORE_CTX *store = - OSSL_STORE_open_ex(cert_file, data->state.libctx, - NULL, NULL, NULL, NULL, NULL, NULL); - int rc; - - if(!store) { - failf(data, "Failed to open OpenSSL store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - if(OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) != 1) { - failf(data, "Failed to set store preference. Ignoring the error: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - } - - info = OSSL_STORE_load(store); - if(info) { - int ossl_type = OSSL_STORE_INFO_get_type(info); - - if(ossl_type == OSSL_STORE_INFO_CERT) - cert = OSSL_STORE_INFO_get1_CERT(info); - OSSL_STORE_INFO_free(info); - } - OSSL_STORE_close(store); - if(!cert) { - failf(data, "No cert found in the openssl store: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - - rc = SSL_CTX_use_certificate(ctx, cert); - X509_free(cert); /* we do not need the handle any more... */ - - if(rc != 1) { - failf(data, "unable to set client certificate [%s]", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - } - else { - failf(data, "crypto provider not set, cannot load certificate"); - return 0; - } - return 1; -#else - (void)ctx; - (void)cert_file; - failf(data, "SSL_FILETYPE_PROVIDER not supported for certificate"); - return 0; -#endif -} - -static int pkcs12load(struct Curl_easy *data, - SSL_CTX* ctx, - const struct curl_blob *cert_blob, - const char *cert_file, - const char *key_passwd) -{ - char error_buffer[256]; - BIO *cert_bio = NULL; - PKCS12 *p12 = NULL; - EVP_PKEY *pri; - X509 *x509; - int cert_done = 0; - STACK_OF(X509) *ca = NULL; - if(cert_blob) { - cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len)); - if(!cert_bio) { - failf(data, "BIO_new_mem_buf NULL, " OSSL_PACKAGE " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - } - else { - cert_bio = BIO_new(BIO_s_file()); - if(!cert_bio) { - failf(data, "BIO_new return NULL, " OSSL_PACKAGE " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return 0; - } - - if(BIO_read_filename(cert_bio, CURL_UNCONST(cert_file)) <= 0) { - failf(data, "could not open PKCS12 file '%s'", cert_file); - BIO_free(cert_bio); - return 0; - } - } - - p12 = d2i_PKCS12_bio(cert_bio, NULL); - BIO_free(cert_bio); - - if(!p12) { - failf(data, "error reading PKCS12 file '%s'", - cert_blob ? "(memory blob)" : cert_file); - return 0; - } - - if(!PKCS12_parse(p12, key_passwd, &pri, &x509, &ca)) { - failf(data, "could not parse PKCS12 file, check password, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); - PKCS12_free(p12); - return 0; - } - - PKCS12_free(p12); - - if(SSL_CTX_use_certificate(ctx, x509) != 1) { - failf(data, "could not load PKCS12 client certificate, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); - goto fail; - } - - if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) { - failf(data, "unable to use private key from PKCS12 file '%s'", cert_file); - goto fail; - } - - if(!SSL_CTX_check_private_key(ctx)) { - failf(data, "private key from PKCS12 file '%s' " - "does not match certificate in same file", cert_file); - goto fail; - } - /* Set Certificate Verification chain */ - if(ca) { - while(sk_X509_num(ca)) { - /* - * Note that sk_X509_pop() is used below to make sure the cert is - * removed from the stack properly before getting passed to - * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously - * we used sk_X509_value() instead, but then we would clean it in the - * subsequent sk_X509_pop_free() call. - */ - X509 *x = sk_X509_pop(ca); - if(!SSL_CTX_add_client_CA(ctx, x)) { - X509_free(x); - failf(data, "cannot add certificate to client CA list"); - goto fail; - } - if(!SSL_CTX_add_extra_chain_cert(ctx, x)) { - X509_free(x); - failf(data, "cannot add certificate to certificate chain"); - goto fail; - } - } - } - - cert_done = 1; -fail: - EVP_PKEY_free(pri); - X509_free(x509); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - sk_X509_pop_free(ca, X509_free); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - if(!cert_done) - return 0; /* failure! */ - return 1; -} - -static CURLcode client_cert(struct Curl_easy *data, - SSL_CTX* ctx, - char *cert_file, - const struct curl_blob *cert_blob, - const char *cert_type, - char *key_file, - const struct curl_blob *key_blob, - const char *key_type, - char *key_passwd) -{ - char error_buffer[256]; - bool check_privkey = TRUE; - int file_type = ossl_do_file_type(cert_type); - - if(cert_file || cert_blob || (file_type == SSL_FILETYPE_ENGINE) || - (file_type == SSL_FILETYPE_PROVIDER)) { - SSL *ssl; - X509 *x509; - bool pcks12_done = FALSE; - int cert_use_result; - - if(key_passwd) { - /* set the password in the callback userdata */ - SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd); - /* Set passwd callback: */ - SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); - } - - switch(file_type) { - case SSL_FILETYPE_PEM: - /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ - cert_use_result = cert_blob ? - use_certificate_chain_blob(ctx, cert_blob, key_passwd) : - SSL_CTX_use_certificate_chain_file(ctx, cert_file); - if(cert_use_result != 1) { - failf(data, - "could not load PEM client certificate from %s, " OSSL_PACKAGE - " error %s, " - "(no key found, wrong passphrase, or wrong file format?)", - (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file), - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return CURLE_SSL_CERTPROBLEM; - } - break; - - case SSL_FILETYPE_ASN1: - /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but - we use the case above for PEM so this can only be performed with - ASN1 files. */ - - cert_use_result = cert_blob ? - use_certificate_blob(ctx, cert_blob, file_type, key_passwd) : - SSL_CTX_use_certificate_file(ctx, cert_file, file_type); - if(cert_use_result != 1) { - failf(data, - "could not load ASN1 client certificate from %s, " OSSL_PACKAGE - " error %s, " - "(no key found, wrong passphrase, or wrong file format?)", - (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file), - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return CURLE_SSL_CERTPROBLEM; - } - break; - - case SSL_FILETYPE_ENGINE: - if(!cert_file || !engineload(data, ctx, cert_file)) - return CURLE_SSL_CERTPROBLEM; - break; - - case SSL_FILETYPE_PROVIDER: - if(!cert_file || !providerload(data, ctx, cert_file)) - return CURLE_SSL_CERTPROBLEM; - break; - - case SSL_FILETYPE_PKCS12: - if(!pkcs12load(data, ctx, cert_blob, cert_file, key_passwd)) - return CURLE_SSL_CERTPROBLEM; - pcks12_done = TRUE; - break; - - default: - failf(data, "not supported file type '%s' for certificate", cert_type); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - if(!key_file && !key_blob) { - key_file = cert_file; - key_blob = cert_blob; - } - else - file_type = ossl_do_file_type(key_type); - - switch(file_type) { - case SSL_FILETYPE_PEM: - case SSL_FILETYPE_ASN1: - cert_use_result = key_blob ? - use_privatekey_blob(ctx, key_blob, file_type, key_passwd) : - SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type); - if(cert_use_result != 1) { - failf(data, "unable to set private key file: '%s' type %s", - key_file ? key_file : "(memory blob)", - key_type ? key_type : "PEM"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - break; - case SSL_FILETYPE_ENGINE: - if(!enginecheck(data, ctx, key_file, key_passwd)) - return CURLE_SSL_CERTPROBLEM; - break; - - case SSL_FILETYPE_PROVIDER: - if(!providercheck(data, ctx, key_file)) - return CURLE_SSL_CERTPROBLEM; - break; - - case SSL_FILETYPE_PKCS12: - if(!pcks12_done) { - failf(data, "file type P12 for private key not supported"); - return CURLE_SSL_CERTPROBLEM; - } - break; - default: - failf(data, "not supported file type for private key"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - ssl = SSL_new(ctx); - if(!ssl) { - failf(data, "unable to create an SSL structure"); - return CURLE_OUT_OF_MEMORY; - } - - x509 = SSL_get_certificate(ssl); - - if(x509) { - EVP_PKEY *pktmp = X509_get_pubkey(x509); - EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); - EVP_PKEY_free(pktmp); - } - -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) - { - /* If RSA is used, do not check the private key if its flags indicate - * it does not support it. */ - EVP_PKEY *priv_key = SSL_get_privatekey(ssl); - if(EVP_PKEY_id(priv_key) == EVP_PKEY_RSA) { - RSA *rsa = EVP_PKEY_get1_RSA(priv_key); - if(RSA_flags(rsa) & RSA_METHOD_FLAG_NO_CHECK) - check_privkey = FALSE; - RSA_free(rsa); /* Decrement reference count */ - } - } -#endif - - SSL_free(ssl); - - /* If we are using DSA, we can copy the parameters from - * the private key */ - - if(check_privkey == TRUE) { - /* Now we know that a key and cert have been set against - * the SSL context */ - if(!SSL_CTX_check_private_key(ctx)) { - failf(data, "Private key does not match the certificate public key"); - return CURLE_SSL_CERTPROBLEM; - } - } - } - return CURLE_OK; -} - -#ifdef CURLVERBOSE -/* returns non-zero on failure */ -static CURLcode x509_name_oneline(const X509_NAME *a, struct dynbuf *d) -{ - BIO *bio_out = BIO_new(BIO_s_mem()); - BUF_MEM *biomem; - int rc; - CURLcode result = CURLE_OUT_OF_MEMORY; - - if(bio_out) { - unsigned long flags = XN_FLAG_SEP_SPLUS_SPC | - (XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB & ~XN_FLAG_SPC_EQ); - curlx_dyn_reset(d); - rc = X509_NAME_print_ex(bio_out, a, 0, flags); - if(rc != -1) { - BIO_get_mem_ptr(bio_out, &biomem); - result = curlx_dyn_addn(d, biomem->data, biomem->length); - } - BIO_free(bio_out); - } - return result; -} -#endif - -/** - * Global SSL init - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ -static int ossl_init(void) -{ - const uint64_t flags = -#ifdef OPENSSL_INIT_ENGINE_ALL_BUILTIN - /* not present in BoringSSL */ - OPENSSL_INIT_ENGINE_ALL_BUILTIN | -#endif -#ifdef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG - OPENSSL_INIT_NO_LOAD_CONFIG | -#else - OPENSSL_INIT_LOAD_CONFIG | -#endif - 0; - OPENSSL_init_ssl(flags, NULL); - -#ifndef HAVE_KEYLOG_UPSTREAM - Curl_tls_keylog_open(); -#endif - - return 1; -} - -/* Global cleanup */ -static void ossl_cleanup(void) -{ -#ifndef HAVE_KEYLOG_UPSTREAM - Curl_tls_keylog_close(); -#endif -} - -/* Selects an OpenSSL crypto engine or provider. - */ -static CURLcode ossl_set_engine(struct Curl_easy *data, const char *name) -{ -#ifdef USE_OPENSSL_ENGINE - CURLcode result = CURLE_SSL_ENGINE_NOTFOUND; - ENGINE *e = ENGINE_by_id(name); - - if(e) { - - if(data->state.engine) { - ENGINE_finish(data->state.engine); - ENGINE_free(data->state.engine); - data->state.engine = NULL; - } - if(!ENGINE_init(e)) { - char buf[256]; - - ENGINE_free(e); - failf(data, "Failed to initialise SSL Engine '%s': %s", - name, ossl_strerror(ERR_get_error(), buf, sizeof(buf))); - result = CURLE_SSL_ENGINE_INITFAILED; - e = NULL; - } - else { - result = CURLE_OK; - } - data->state.engine = e; - return result; - } -#endif -#ifdef OPENSSL_HAS_PROVIDERS - return ossl_set_provider(data, name); -#else - (void)name; - failf(data, "OpenSSL engine not found"); - return CURLE_SSL_ENGINE_NOTFOUND; -#endif -} - -/* Sets engine as default for all SSL operations - */ -static CURLcode ossl_set_engine_default(struct Curl_easy *data) -{ -#ifdef USE_OPENSSL_ENGINE - if(data->state.engine) { - if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) { - infof(data, "set default crypto engine '%s'", - ENGINE_get_id(data->state.engine)); - } - else { - failf(data, "set default crypto engine '%s' failed", - ENGINE_get_id(data->state.engine)); - return CURLE_SSL_ENGINE_SETFAILED; - } - } -#else - (void)data; -#endif - return CURLE_OK; -} - -/* Return list of OpenSSL crypto engine names. - */ -static struct curl_slist *ossl_engines_list(struct Curl_easy *data) -{ - struct curl_slist *list = NULL; -#ifdef USE_OPENSSL_ENGINE - struct curl_slist *beg; - ENGINE *e; - - for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { - beg = curl_slist_append(list, ENGINE_get_id(e)); - if(!beg) { - curl_slist_free_all(list); - return NULL; - } - list = beg; - } -#endif - (void)data; - return list; -} - -#ifdef OPENSSL_HAS_PROVIDERS - -static void ossl_provider_cleanup(struct Curl_easy *data) -{ - if(data->state.baseprov) { - OSSL_PROVIDER_unload(data->state.baseprov); - data->state.baseprov = NULL; - } - if(data->state.provider) { - OSSL_PROVIDER_unload(data->state.provider); - data->state.provider = NULL; - } - OSSL_LIB_CTX_free(data->state.libctx); - data->state.libctx = NULL; - curlx_safefree(data->state.propq); - data->state.provider_loaded = FALSE; -} - -#define MAX_PROVIDER_LEN 128 /* reasonable */ - -/* Selects an OpenSSL crypto provider. - * - * A provider might need an associated property, a string passed on to - * OpenSSL. Specify this as [PROVIDER][:PROPERTY]: separate the name and the - * property with a colon. No colon means no property is set. - * - * An example provider + property looks like "tpm2:?provider=tpm2". - */ -static CURLcode ossl_set_provider(struct Curl_easy *data, const char *iname) -{ - char name[MAX_PROVIDER_LEN + 1]; - struct Curl_str prov; - const char *propq = NULL; - - if(!iname) { - /* clear and cleanup provider use */ - ossl_provider_cleanup(data); - return CURLE_OK; - } - if(curlx_str_until(&iname, &prov, MAX_PROVIDER_LEN, ':')) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(!curlx_str_single(&iname, ':')) - /* there was a colon, get the propq until the end of string */ - propq = iname; - - /* we need the name in a buffer, null-terminated */ - memcpy(name, curlx_str(&prov), curlx_strlen(&prov)); - name[curlx_strlen(&prov)] = 0; - - if(!data->state.libctx) { - OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); - if(!libctx) - return CURLE_OUT_OF_MEMORY; - if(propq) { - data->state.propq = curlx_strdup(propq); - if(!data->state.propq) { - OSSL_LIB_CTX_free(libctx); - return CURLE_OUT_OF_MEMORY; - } - } - data->state.libctx = libctx; - } - -#ifndef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG - /* load the configuration file into the library context before checking the - * provider availability */ - if(!OSSL_LIB_CTX_load_config(data->state.libctx, NULL)) { - infof(data, "Failed to load default openssl config. Proceeding."); - } -#endif - - if(OSSL_PROVIDER_available(data->state.libctx, name)) { - /* already loaded through the configuration - no action needed */ - data->state.provider_loaded = TRUE; - return CURLE_OK; - } - - data->state.provider = OSSL_PROVIDER_try_load(data->state.libctx, name, 1); - if(!data->state.provider) { - char error_buffer[256]; - failf(data, "Failed to initialize provider: %s", - ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); - ossl_provider_cleanup(data); - return CURLE_SSL_ENGINE_NOTFOUND; - } - - /* load the base provider as well */ - data->state.baseprov = OSSL_PROVIDER_try_load(data->state.libctx, "base", 1); - if(!data->state.baseprov) { - ossl_provider_cleanup(data); - failf(data, "Failed to load base"); - return CURLE_SSL_ENGINE_NOTFOUND; - } - else - data->state.provider_loaded = TRUE; - return CURLE_OK; -} -#endif - -static CURLcode ossl_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool send_shutdown, bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - CURLcode result = CURLE_OK; - char buf[1024]; - int nread = -1, err; - size_t i; - - DEBUGASSERT(octx); - if(!octx->ssl || cf->shutdown) { - *done = TRUE; - goto out; - } - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - *done = FALSE; - if(!(SSL_get_shutdown(octx->ssl) & SSL_SENT_SHUTDOWN)) { - /* We have not started the shutdown from our side yet. Check - * if the server already sent us one. */ - ERR_clear_error(); - for(i = 0; i < 10; ++i) { - nread = SSL_read(octx->ssl, buf, (int)sizeof(buf)); - CURL_TRC_CF(data, cf, "SSL shutdown not sent, read -> %d", nread); - if(nread <= 0) - break; - } - err = SSL_get_error(octx->ssl, nread); - if(!nread && err == SSL_ERROR_ZERO_RETURN) { - bool input_pending; - /* Yes, it did. */ - if(!send_shutdown) { - CURL_TRC_CF(data, cf, "SSL shutdown received, not sending"); - *done = TRUE; - goto out; - } - else if(!cf->next->cft->is_alive(cf->next, data, &input_pending)) { - /* Server closed the connection after its closy notify. It - * seems not interested to see our close notify, so do not - * send it. We are done. */ - connssl->peer_closed = TRUE; - CURL_TRC_CF(data, cf, "peer closed connection"); - *done = TRUE; - goto out; - } - } - } - - /* SSL should now have started the shutdown from our side. Since it - * was not complete, we are lacking the close notify from the server. */ - if(send_shutdown && !(SSL_get_shutdown(octx->ssl) & SSL_SENT_SHUTDOWN)) { - int rc; - ERR_clear_error(); - CURL_TRC_CF(data, cf, "send SSL close notify"); - rc = SSL_shutdown(octx->ssl); - if(rc == 1) { - CURL_TRC_CF(data, cf, "SSL shutdown finished"); - *done = TRUE; - goto out; - } - if(SSL_ERROR_WANT_WRITE == SSL_get_error(octx->ssl, rc)) { - CURL_TRC_CF(data, cf, "SSL shutdown still wants to send"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - goto out; - } - /* Having sent the close notify, we use SSL_read() to get the - * missing close notify from the server. */ - } - - for(i = 0; i < 10; ++i) { - ERR_clear_error(); - nread = SSL_read(octx->ssl, buf, (int)sizeof(buf)); - CURL_TRC_CF(data, cf, "SSL shutdown read -> %d", nread); - if(nread <= 0) - break; - } - err = SSL_get_error(octx->ssl, nread); - switch(err) { - case SSL_ERROR_ZERO_RETURN: /* no more data */ - if(SSL_shutdown(octx->ssl) == 1) - CURL_TRC_CF(data, cf, "SSL shutdown finished"); - else - CURL_TRC_CF(data, cf, "SSL shutdown not received, but closed"); - *done = TRUE; - break; - case SSL_ERROR_NONE: /* did not get anything */ - case SSL_ERROR_WANT_READ: - /* SSL has send its notify and now wants to read the reply - * from the server. We are not really interested in that. */ - CURL_TRC_CF(data, cf, "SSL shutdown sent, want receive"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; - break; - case SSL_ERROR_WANT_WRITE: - CURL_TRC_CF(data, cf, "SSL shutdown send blocked"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - break; - default: - /* Server seems to have closed the connection without sending us - * a close notify. */ - { - VERBOSE(unsigned long sslerr = ERR_get_error()); - CURL_TRC_CF(data, cf, "SSL shutdown, ignore recv error: '%s', errno %d", - (sslerr ? - ossl_strerror(sslerr, buf, sizeof(buf)) : - SSL_ERROR_to_str(err)), - SOCKERRNO); - } - *done = TRUE; - result = CURLE_OK; - break; - } - -out: - cf->shutdown = (result || *done); - if(cf->shutdown || (connssl->io_need != CURL_SSL_IO_NEED_NONE)) - connssl->input_pending = FALSE; - return result; -} - -static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - - (void)data; - DEBUGASSERT(octx); - - connssl->input_pending = FALSE; - if(octx->ssl) { - SSL_free(octx->ssl); - octx->ssl = NULL; - } - if(octx->ssl_ctx) { - SSL_CTX_free(octx->ssl_ctx); - octx->ssl_ctx = NULL; - octx->x509_store_setup = FALSE; - } - if(octx->bio_method) { - ossl_bio_cf_method_free(octx->bio_method); - octx->bio_method = NULL; - } -} - -/* - * This function is called when the 'data' struct is going away. Close - * down everything and free all resources! - */ -static void ossl_close_all(struct Curl_easy *data) -{ -#ifdef USE_OPENSSL_ENGINE - if(data->state.engine) { - ENGINE_finish(data->state.engine); - ENGINE_free(data->state.engine); - data->state.engine = NULL; - } -#else - (void)data; -#endif -#ifdef OPENSSL_HAS_PROVIDERS - ossl_provider_cleanup(data); -#endif -} - -/* ====================================================== */ - -/* Quote from RFC2818 section 3.1 "Server Identity" - - If a subjectAltName extension of type dNSName is present, that MUST - be used as the identity. Otherwise, the (most specific) Common Name - field in the Subject field of the certificate MUST be used. Although - the use of the Common Name is existing practice, it is deprecated and - Certification Authorities are encouraged to use the dNSName instead. - - Matching is performed using the matching rules specified by - [RFC2459]. If more than one identity of a given type is present in - the certificate (e.g., more than one dNSName name, a match in any one - of the set is considered acceptable.) Names may contain the wildcard - character * which is considered to match any single domain name - component or component fragment. E.g., *.a.com matches foo.a.com but - not bar.foo.a.com. f*.com matches foo.com but not bar.com. - - In some cases, the URI is specified as an IP address rather than a - hostname. In this case, the iPAddress subjectAltName must be present - in the certificate and must exactly match the IP in the URI. - - This function is now used from ngtcp2 (QUIC) as well. -*/ -static CURLcode ossl_verifyhost(struct Curl_easy *data, - struct connectdata *conn, - struct ssl_peer *peer, - X509 *server_cert) -{ - bool matched = FALSE; - int target; /* target type, GEN_DNS or GEN_IPADD */ - size_t addrlen = 0; - STACK_OF(GENERAL_NAME) *altnames; -#ifdef USE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - CURLcode result = CURLE_OK; - bool dNSName = FALSE; /* if a dNSName field exists in the cert */ - bool iPAddress = FALSE; /* if an iPAddress field exists in the cert */ - size_t hostlen = strlen(peer->hostname); - - (void)conn; - switch(peer->type) { - case CURL_SSL_PEER_IPV4: - if(!curlx_inet_pton(AF_INET, peer->hostname, &addr)) - return CURLE_PEER_FAILED_VERIFICATION; - target = GEN_IPADD; - addrlen = sizeof(struct in_addr); - break; -#ifdef USE_IPV6 - case CURL_SSL_PEER_IPV6: - if(!curlx_inet_pton(AF_INET6, peer->hostname, &addr)) - return CURLE_PEER_FAILED_VERIFICATION; - target = GEN_IPADD; - addrlen = sizeof(struct in6_addr); - break; -#endif - case CURL_SSL_PEER_DNS: - target = GEN_DNS; - break; - default: - DEBUGASSERT(0); - failf(data, "unexpected ssl peer type: %d", peer->type); - return CURLE_PEER_FAILED_VERIFICATION; - } - - /* get a "list" of alternative names */ - altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); - - if(altnames) { -#ifdef HAVE_BORINGSSL_LIKE - size_t numalts; - size_t i; -#else - int numalts; - int i; -#endif - - /* get amount of alternatives, RFC2459 claims there MUST be at least - one, but we do not depend on it... */ - numalts = sk_GENERAL_NAME_num(altnames); - - /* loop through all alternatives - until a dnsmatch */ - for(i = 0; (i < numalts) && !matched; i++) { - /* get a handle to alternative name number i */ - const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i); - - if(check->type == GEN_DNS) - dNSName = TRUE; - else if(check->type == GEN_IPADD) - iPAddress = TRUE; - - /* only check alternatives of the same type the target is */ - if(check->type == target) { - /* get data and length */ - const char *altptr = (const char *)ASN1_STRING_get0_data(check->d.ia5); - size_t altlen = (size_t)ASN1_STRING_length(check->d.ia5); - - switch(target) { - case GEN_DNS: /* name/pattern comparison */ - /* The OpenSSL man page explicitly says: "In general it cannot be - assumed that the data returned by ASN1_STRING_data() is null - terminated or does not contain embedded nulls.", but also that - "The actual format of the data depends on the actual string - type itself: for example for an IA5String the data is ASCII" - - It has been however verified that in 0.9.6 and 0.9.7, IA5String - is always null-terminated. - */ - if((altlen == strlen(altptr)) && - /* if this is not true, there was an embedded zero in the name - string and we cannot match it. */ - Curl_cert_hostcheck(altptr, altlen, peer->hostname, hostlen)) { - matched = TRUE; - infof(data, " subjectAltName: \"%s\" matches cert's \"%.*s\"", - peer->dispname, (int)altlen, altptr); - } - break; - - case GEN_IPADD: /* IP address comparison */ - /* compare alternative IP address if the data chunk is the same size - our server IP address is */ - if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) { - matched = TRUE; - infof(data, " subjectAltName: \"%s\" matches cert's IP address!", - peer->dispname); - } - break; - } - } - } - GENERAL_NAMES_free(altnames); - } - - if(matched) - /* an alternative name matched */ - ; - else if(dNSName || iPAddress) { - const char *tname = (peer->type == CURL_SSL_PEER_DNS) ? "hostname" : - (peer->type == CURL_SSL_PEER_IPV4) ? - "ipv4 address" : "ipv6 address"; - infof(data, " subjectAltName does not match %s %s", tname, peer->dispname); - failf(data, "SSL: no alternative certificate subject name matches " - "target %s '%s'", tname, peer->dispname); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else { - /* we have to look to the last occurrence of a commonName in the - distinguished one to get the most significant one. */ - int i = -1; - unsigned char *cn = NULL; - int cnlen = 0; - bool free_cn = FALSE; - - /* The following is done because of a bug in 0.9.6b */ - const X509_NAME *name = X509_get_subject_name(server_cert); - if(name) { - int j; - while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0) - i = j; - } - - /* we have the name entry and we now convert this to a string - that we can use for comparison. Doing this we support BMPstring, - UTF8, etc. */ - - if(i >= 0) { - const ASN1_STRING *tmp = - X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); - - /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input - is already UTF-8 encoded. We check for this case and copy the raw - string manually to avoid the problem. This code can be made - conditional in the future when OpenSSL has been fixed. */ - if(tmp) { - if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) { - cnlen = ASN1_STRING_length(tmp); - cn = (unsigned char *)CURL_UNCONST(ASN1_STRING_get0_data(tmp)); - } - else { /* not a UTF8 name */ - cnlen = ASN1_STRING_to_UTF8(&cn, tmp); - free_cn = TRUE; - } - - if((cnlen <= 0) || !cn) - result = CURLE_OUT_OF_MEMORY; - else if((size_t)cnlen != strlen((char *)cn)) { - /* there was a terminating zero before the end of string, this - cannot match and we return failure! */ - failf(data, "SSL: illegal cert name field"); - result = CURLE_PEER_FAILED_VERIFICATION; - } - } - } - - if(result) - /* error already detected, pass through */ - ; - else if(!cn) { - failf(data, "SSL: unable to obtain common name from peer certificate"); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else if(!Curl_cert_hostcheck((const char *)cn, cnlen, - peer->hostname, hostlen)) { - failf(data, "SSL: certificate subject name '%s' does not match " - "target hostname '%s'", cn, peer->dispname); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else { - infof(data, " common name: %s (matched)", cn); - } - if(free_cn) - OPENSSL_free(cn); - } - - return result; -} - -#ifndef OPENSSL_NO_OCSP -static CURLcode verifystatus(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx) -{ - int i, ocsp_status; -#ifdef HAVE_BORINGSSL_LIKE - const uint8_t *status; -#else - unsigned char *status; -#endif - const unsigned char *p; - CURLcode result = CURLE_OK; - OCSP_RESPONSE *rsp = NULL; - OCSP_BASICRESP *br = NULL; - X509_STORE *st = NULL; - STACK_OF(X509) *ch = NULL; - X509 *cert; - OCSP_CERTID *id = NULL; - int cert_status, crl_reason; - ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; - int ret; - long len; - - (void)cf; - DEBUGASSERT(octx); - - len = (long)SSL_get_tlsext_status_ocsp_resp(octx->ssl, &status); - - if(!status) { - failf(data, "No OCSP response received"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - p = status; - rsp = d2i_OCSP_RESPONSE(NULL, &p, len); - if(!rsp) { - failf(data, "Invalid OCSP response"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - ocsp_status = OCSP_response_status(rsp); - if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { - failf(data, "Invalid OCSP response status: %s (%d)", - OCSP_response_status_str(ocsp_status), ocsp_status); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - br = OCSP_response_get1_basic(rsp); - if(!br) { - failf(data, "Invalid OCSP response"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - ch = SSL_get_peer_cert_chain(octx->ssl); - if(!ch) { - failf(data, "Could not get peer certificate chain"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - st = SSL_CTX_get_cert_store(octx->ssl_ctx); - - if(OCSP_basic_verify(br, ch, st, 0) <= 0) { - failf(data, "OCSP response verification failed"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - /* Compute the certificate's ID */ - cert = SSL_get1_peer_certificate(octx->ssl); - if(!cert) { - failf(data, "Error getting peer certificate"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - for(i = 0; i < (int)sk_X509_num(ch); i++) { - X509 *issuer = sk_X509_value(ch, (ossl_valsize_t)i); - if(X509_check_issued(issuer, cert) == X509_V_OK) { - /* Note to analysis tools: using SHA1 here is fine. The `id` - * generated is used as a hash lookup key, not as a verifier - * of the OCSP data itself. This all according to RFC 5019. */ - id = OCSP_cert_to_id(EVP_sha1(), cert, issuer); - break; - } - } - X509_free(cert); - - if(!id) { - failf(data, "Error computing OCSP ID"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - /* Find the single OCSP response corresponding to the certificate ID */ - ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev, - &thisupd, &nextupd); - OCSP_CERTID_free(id); - if(ret != 1) { - failf(data, "Could not find certificate ID in OCSP response"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - /* Validate the OCSP response issuing and update times. - * - `thisupd` is the time the OCSP response was issued - * - `nextupd` is the time the OCSP response should be updated - * (valid life time assigned by the OCSP responder) - * - 3rd param: how many seconds of clock skew we allow between - * our clock and the instance that issued the OCSP response - * - 4th param: how many seconds in the past `thisupd` may be, with - * -1 meaning there is no limit. */ - if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { - failf(data, "OCSP response has expired"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - infof(data, "SSL certificate status: %s (%d)", - OCSP_cert_status_str(cert_status), cert_status); - - switch(cert_status) { - case V_OCSP_CERTSTATUS_GOOD: - break; - - case V_OCSP_CERTSTATUS_REVOKED: - result = CURLE_SSL_INVALIDCERTSTATUS; - failf(data, "SSL certificate revocation reason: %s (%d)", - OCSP_crl_reason_str(crl_reason), crl_reason); - goto end; - - case V_OCSP_CERTSTATUS_UNKNOWN: - default: - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - -end: - if(br) - OCSP_BASICRESP_free(br); - OCSP_RESPONSE_free(rsp); - - return result; -} -#endif - -static const char *ssl_msg_type(int ssl_ver, int msg) -{ - if(ssl_ver == SSL3_VERSION_MAJOR) { - switch(msg) { - case SSL3_MT_HELLO_REQUEST: - return "Hello request"; - case SSL3_MT_CLIENT_HELLO: - return "Client hello"; - case SSL3_MT_SERVER_HELLO: - return "Server hello"; -#ifdef SSL3_MT_NEWSESSION_TICKET - case SSL3_MT_NEWSESSION_TICKET: - return "Newsession Ticket"; -#endif - case SSL3_MT_CERTIFICATE: - return "Certificate"; - case SSL3_MT_SERVER_KEY_EXCHANGE: - return "Server key exchange"; - case SSL3_MT_CLIENT_KEY_EXCHANGE: - return "Client key exchange"; - case SSL3_MT_CERTIFICATE_REQUEST: - return "Request CERT"; - case SSL3_MT_SERVER_DONE: - return "Server finished"; - case SSL3_MT_CERTIFICATE_VERIFY: - return "CERT verify"; - case SSL3_MT_FINISHED: - return "Finished"; -#ifdef SSL3_MT_CERTIFICATE_STATUS - case SSL3_MT_CERTIFICATE_STATUS: - return "Certificate Status"; -#endif -#ifdef SSL3_MT_ENCRYPTED_EXTENSIONS - case SSL3_MT_ENCRYPTED_EXTENSIONS: - return "Encrypted Extensions"; -#endif -#ifdef SSL3_MT_SUPPLEMENTAL_DATA - case SSL3_MT_SUPPLEMENTAL_DATA: - return "Supplemental data"; -#endif -#ifdef SSL3_MT_END_OF_EARLY_DATA - case SSL3_MT_END_OF_EARLY_DATA: - return "End of early data"; -#endif -#ifdef SSL3_MT_KEY_UPDATE - case SSL3_MT_KEY_UPDATE: - return "Key update"; -#endif -#ifdef SSL3_MT_NEXT_PROTO - case SSL3_MT_NEXT_PROTO: - return "Next protocol"; -#endif -#ifdef SSL3_MT_MESSAGE_HASH - case SSL3_MT_MESSAGE_HASH: - return "Message hash"; -#endif - } - } - return "Unknown"; -} - -static const char *tls_rt_type(int type) -{ - switch(type) { -#ifdef SSL3_RT_HEADER - case SSL3_RT_HEADER: - return "TLS header"; -#endif - case SSL3_RT_CHANGE_CIPHER_SPEC: - return "TLS change cipher"; - case SSL3_RT_ALERT: - return "TLS alert"; - case SSL3_RT_HANDSHAKE: - return "TLS handshake"; - case SSL3_RT_APPLICATION_DATA: - return "TLS app data"; - default: - return "TLS Unknown"; - } -} - -/* - * Our callback from the SSL/TLS layers. - */ -static void ossl_trace(int direction, int ssl_ver, int content_type, - const void *buf, size_t len, SSL *ssl, - void *userp) -{ - const char *verstr; - struct Curl_cfilter *cf = userp; - struct Curl_easy *data = NULL; - char unknown[32]; - - if(!cf) - return; - data = CF_DATA_CURRENT(cf); - if(!data || !data->set.fdebug || (direction && direction != 1)) - return; - - switch(ssl_ver) { -#ifdef SSL3_VERSION - case SSL3_VERSION: - verstr = "SSLv3"; - break; -#endif - case TLS1_VERSION: - verstr = "TLSv1.0"; - break; -#ifdef TLS1_1_VERSION - case TLS1_1_VERSION: - verstr = "TLSv1.1"; - break; -#endif -#ifdef TLS1_2_VERSION - case TLS1_2_VERSION: - verstr = "TLSv1.2"; - break; -#endif - case TLS1_3_VERSION: - verstr = "TLSv1.3"; - break; - default: - curl_msnprintf(unknown, sizeof(unknown), "(%x)", ssl_ver); - verstr = unknown; - break; - } - - /* Log progress for interesting records only (like Handshake or Alert), skip - * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). - * For TLS 1.3, skip notification of the decrypted inner Content-Type. - */ - if(ssl_ver -#ifdef SSL3_RT_HEADER - && content_type != SSL3_RT_HEADER -#endif -#ifdef SSL3_RT_INNER_CONTENT_TYPE - && content_type != SSL3_RT_INNER_CONTENT_TYPE -#endif - ) { - const char *msg_name = "Truncated message"; - const char *tls_rt_name; - char ssl_buf[1024]; - int msg_type = 0; - int txt_len; - - /* the info given when the version is zero is not that useful for us */ - - ssl_ver >>= 8; /* check the upper 8 bits only below */ - - /* SSLv2 does not seem to have TLS record-type headers, so OpenSSL - * always pass-up content-type as 0, but the interesting message-type - * is at 'buf[0]'. - */ - if(ssl_ver == SSL3_VERSION_MAJOR && content_type) - tls_rt_name = tls_rt_type(content_type); - else - tls_rt_name = ""; - - if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) { - if(len) { - msg_type = *(const unsigned char *)buf; - msg_name = "Change cipher spec"; - } - } - else if(content_type == SSL3_RT_ALERT) { - if(len >= 2) { - msg_type = - (((const unsigned char *)buf)[0] << 8) + - ((const unsigned char *)buf)[1]; - msg_name = SSL_alert_desc_string_long(msg_type); - } - } - else if(len) { - msg_type = *(const unsigned char *)buf; - msg_name = ssl_msg_type(ssl_ver, msg_type); - } - - txt_len = curl_msnprintf(ssl_buf, sizeof(ssl_buf), - "%s (%s), %s, %s (%d):\n", - verstr, direction ? "OUT" : "IN", - tls_rt_name, msg_name, msg_type); - Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len); - } - - Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : - CURLINFO_SSL_DATA_IN, (const char *)buf, len); - (void)ssl; -} - -static CURLcode ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, - SSL_CTX *ctx, - unsigned int ssl_version_min) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - /* first, TLS min version... */ - long curl_ssl_version_min = (long)ssl_version_min; - long curl_ssl_version_max; - - /* convert curl min SSL version option to OpenSSL constant */ -#if defined(HAVE_BORINGSSL_LIKE) || defined(LIBRESSL_VERSION_NUMBER) - uint16_t ossl_ssl_version_min = 0; - uint16_t ossl_ssl_version_max = 0; -#else - long ossl_ssl_version_min = 0; - long ossl_ssl_version_max = 0; -#endif - /* it cannot be default here */ - DEBUGASSERT(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT); - switch(curl_ssl_version_min) { - case CURL_SSLVERSION_TLSv1: /* TLS 1.x */ - case CURL_SSLVERSION_TLSv1_0: - ossl_ssl_version_min = TLS1_VERSION; - break; - case CURL_SSLVERSION_TLSv1_1: - ossl_ssl_version_min = TLS1_1_VERSION; - break; - case CURL_SSLVERSION_TLSv1_2: - ossl_ssl_version_min = TLS1_2_VERSION; - break; - case CURL_SSLVERSION_TLSv1_3: - ossl_ssl_version_min = TLS1_3_VERSION; - break; - } - - /* ... then, TLS max version */ - curl_ssl_version_max = (long)conn_config->version_max; - - /* convert curl max SSL version option to OpenSSL constant */ - switch(curl_ssl_version_max) { - case CURL_SSLVERSION_MAX_TLSv1_0: - ossl_ssl_version_max = TLS1_VERSION; - break; - case CURL_SSLVERSION_MAX_TLSv1_1: - ossl_ssl_version_max = TLS1_1_VERSION; - break; - case CURL_SSLVERSION_MAX_TLSv1_2: - ossl_ssl_version_max = TLS1_2_VERSION; - break; - case CURL_SSLVERSION_MAX_TLSv1_3: - ossl_ssl_version_max = TLS1_3_VERSION; - break; - case CURL_SSLVERSION_MAX_NONE: /* none selected */ - case CURL_SSLVERSION_MAX_DEFAULT: /* max selected */ - default: - /* SSL_CTX_set_max_proto_version states that: setting the maximum to 0 - enables protocol versions up to the highest version supported by - the library */ - ossl_ssl_version_max = 0; - break; - } - - if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min) || - !SSL_CTX_set_max_proto_version(ctx, ossl_ssl_version_max)) - return CURLE_SSL_CONNECT_ERROR; - - return CURLE_OK; -} - -#ifdef HAVE_BORINGSSL_LIKE -typedef uint32_t ctx_option_t; -#elif defined(HAVE_OPENSSL3) -typedef uint64_t ctx_option_t; -#elif defined(LIBRESSL_VERSION_NUMBER) -typedef long ctx_option_t; -#else -typedef unsigned long ctx_option_t; -#endif - -CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - SSL_SESSION *session, - int ietf_tls_id, - const char *alpn, - unsigned char *quic_tp, - size_t quic_tp_len) -{ - unsigned char *der_session_buf = NULL; - unsigned char *qtp_clone = NULL; - CURLcode result = CURLE_OK; - - if(!cf || !data) - goto out; - - if(Curl_ssl_scache_use(cf, data)) { - struct Curl_ssl_session *sc_session = NULL; - size_t der_session_size; - unsigned char *der_session_ptr; - size_t earlydata_max = 0; - - der_session_size = i2d_SSL_SESSION(session, NULL); - if(der_session_size == 0) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - der_session_buf = der_session_ptr = curlx_malloc(der_session_size); - if(!der_session_buf) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - der_session_size = i2d_SSL_SESSION(session, &der_session_ptr); - if(der_session_size == 0) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - -#ifdef HAVE_OPENSSL_EARLYDATA - earlydata_max = SSL_SESSION_get_max_early_data(session); -#endif - if(quic_tp && quic_tp_len) { - qtp_clone = curlx_memdup0((const char *)quic_tp, quic_tp_len); - if(!qtp_clone) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - result = Curl_ssl_session_create2(der_session_buf, der_session_size, - ietf_tls_id, alpn, - (curl_off_t)time(NULL) + - SSL_SESSION_get_timeout(session), - earlydata_max, qtp_clone, quic_tp_len, - &sc_session); - der_session_buf = NULL; /* took ownership of sdata */ - if(!result) { - result = Curl_ssl_scache_put(cf, data, ssl_peer_key, sc_session); - /* took ownership of `sc_session` */ - } - } - -out: - curlx_free(der_session_buf); - return result; -} - -/* The "new session" callback must return zero if the session can be removed - * or non-zero if the session has been put into the session cache. - */ -static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) -{ - struct Curl_cfilter *cf = (struct Curl_cfilter *)SSL_get_app_data(ssl); - if(cf) { - struct Curl_easy *data = CF_DATA_CURRENT(cf); - struct ssl_connect_data *connssl = cf->ctx; - Curl_ossl_add_session(cf, data, connssl->peer.scache_key, ssl_sessionid, - SSL_version(ssl), connssl->negotiated.alpn, NULL, 0); - } - return 0; -} - -static CURLcode load_cacert_from_memory(X509_STORE *store, - const struct curl_blob *ca_info_blob) -{ - /* these need to be freed at the end */ - BIO *cbio = NULL; - STACK_OF(X509_INFO) *inf = NULL; - - /* everything else is a reference */ - int i, count = 0; - X509_INFO *itmp = NULL; - - if(ca_info_blob->len > (size_t)INT_MAX) - return CURLE_SSL_CACERT_BADFILE; - - cbio = BIO_new_mem_buf(ca_info_blob->data, (int)ca_info_blob->len); - if(!cbio) - return CURLE_OUT_OF_MEMORY; - - inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL); - if(!inf) { - BIO_free(cbio); - return CURLE_SSL_CACERT_BADFILE; - } - - /* add each entry from PEM file to x509_store */ - for(i = 0; i < (int)sk_X509_INFO_num(inf); ++i) { - itmp = sk_X509_INFO_value(inf, (ossl_valsize_t)i); - if(itmp->x509) { - if(X509_STORE_add_cert(store, itmp->x509)) { - ++count; - } - else { - /* set count to 0 to return an error */ - count = 0; - break; - } - } - if(itmp->crl) { - if(X509_STORE_add_crl(store, itmp->crl)) { - ++count; - } - else { - /* set count to 0 to return an error */ - count = 0; - break; - } - } - } - -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - sk_X509_INFO_pop_free(inf, X509_INFO_free); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - BIO_free(cbio); - - /* if we did not end up importing anything, treat that as an error */ - return (count > 0) ? CURLE_OK : CURLE_SSL_CACERT_BADFILE; -} - -#ifdef USE_WIN32_CRYPTO -static CURLcode ossl_win_load_store(struct Curl_easy *data, - struct Curl_cfilter *cf, - const char *win_store, - X509_STORE *store, - bool *padded) -{ - CURLcode result = CURLE_OK; - HCERTSTORE hStore; - - *padded = FALSE; - - hStore = CertOpenSystemStoreA(0, win_store); - if(hStore) { - PCCERT_CONTEXT pContext = NULL; - /* The array of enhanced key usage OIDs varies per certificate and - is declared outside of the loop so that rather than malloc/free each - iteration we can grow it with realloc, when necessary. */ - CERT_ENHKEY_USAGE *enhkey_usage = NULL; - DWORD enhkey_usage_size = 0; - VERBOSE(size_t total = 0); - VERBOSE(size_t imported = 0); - - /* This loop makes a best effort to import all valid certificates from - the MS root store. If a certificate cannot be imported it is - skipped. 'result' is used to store only hard-fail conditions (such - as out of memory) that cause an early break. */ - result = CURLE_OK; - for(;;) { - X509 *x509; - FILETIME now; - BYTE key_usage[2]; - DWORD req_size; - const unsigned char *encoded_cert; - pContext = CertEnumCertificatesInStore(hStore, pContext); - if(!pContext) - break; - - VERBOSE(++total); - -#if defined(DEBUGBUILD) && defined(CURLVERBOSE) - { - char cert_name[256]; - if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, - NULL, cert_name, sizeof(cert_name))) - infof(data, "SSL: unknown cert name"); - else - infof(data, "SSL: Checking cert \"%s\"", cert_name); - } -#endif - encoded_cert = (const unsigned char *)pContext->pbCertEncoded; - if(!encoded_cert) - continue; - - GetSystemTimeAsFileTime(&now); - if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 || - CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0) - continue; - - /* If key usage exists check for signing attribute */ - if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType, - pContext->pCertInfo, - key_usage, sizeof(key_usage))) { - if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE)) - continue; - } - else if(GetLastError()) - continue; - - /* If enhanced key usage exists check for server auth attribute. - * - * Note "In a Microsoft environment, a certificate might also have - * EKU extended properties that specify valid uses for the - * certificate." The call below checks both, and behavior varies - * depending on what is found. For more details see - * CertGetEnhancedKeyUsage doc. - */ - if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size) && req_size) { - if(req_size > enhkey_usage_size) { - void *tmp = curlx_realloc(enhkey_usage, req_size); - - if(!tmp) { - failf(data, "SSL: Out of memory allocating for OID list"); - result = CURLE_OUT_OF_MEMORY; - break; - } - - enhkey_usage = (CERT_ENHKEY_USAGE *)tmp; - enhkey_usage_size = req_size; - } - - if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) { - if(!enhkey_usage->cUsageIdentifier) { - /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate - is good for all uses. If it returns zero, the certificate - has no valid uses." */ - if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND) - continue; - } - else { - DWORD i; - bool found = FALSE; - - for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) { - if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */, - enhkey_usage->rgpszUsageIdentifier[i])) { - found = TRUE; - break; - } - } - - if(!found) - continue; - } - } - else - continue; - } - else - continue; - - x509 = d2i_X509(NULL, &encoded_cert, (long)pContext->cbCertEncoded); - if(!x509) - continue; - - /* Try to import the certificate. This may fail for legitimate reasons - such as duplicate certificate, which is allowed by MS but not - OpenSSL. */ - if(X509_STORE_add_cert(store, x509) == 1) { - VERBOSE(++imported); -#ifdef DEBUGBUILD - infof(data, "SSL: Imported cert"); -#endif - *padded = TRUE; - } - X509_free(x509); - } - - curlx_free(enhkey_usage); - CertFreeCertificateContext(pContext); - CertCloseStore(hStore, 0); - - CURL_TRC_CF(data, cf, - "ossl_win_load_store() found: %zu imported: %zu certs in %s.", - total, imported, win_store); - - if(result) - return result; - } - - return result; -} - -static CURLcode ossl_windows_load_anchors(struct Curl_cfilter *cf, - struct Curl_easy *data, - X509_STORE *store, - bool *padded) -{ - /* Import certificates from the Windows root certificate store if - requested. - https://stackoverflow.com/questions/9507184/ - https://github.com/d3x0r/SACK/blob/ff15424d3c581b86d40f818532e5a400c516d39d/src/netlib/ssl_layer.c#L1410 - https://datatracker.ietf.org/doc/html/rfc5280 */ - const char *win_stores[] = { - "ROOT", /* Trusted Root Certification Authorities */ - "CA" /* Intermediate Certification Authorities */ - }; - size_t i; - CURLcode result = CURLE_OK; - - *padded = FALSE; - for(i = 0; i < CURL_ARRAYSIZE(win_stores); ++i) { - bool store_added = FALSE; - result = ossl_win_load_store(data, cf, win_stores[i], store, &store_added); - if(result) - return result; - if(store_added) { - CURL_TRC_CF(data, cf, "added trust anchors from Windows %s store", - win_stores[i]); - *padded = TRUE; - } - else - infof(data, "error importing Windows %s store, continuing anyway", - win_stores[i]); - } - return result; -} - -#endif /* USE_WIN32_CRYPTO */ - -static CURLcode ossl_load_trust_anchors(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx, - X509_STORE *store) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - CURLcode result = CURLE_OK; - const char * const ssl_cafile = - /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - (conn_config->ca_info_blob ? NULL : conn_config->CAfile); - const char * const ssl_capath = conn_config->CApath; - bool have_native_check = FALSE; - - octx->store_is_empty = TRUE; - if(ssl_config->native_ca_store) { -#ifdef USE_WIN32_CRYPTO - bool added = FALSE; - result = ossl_windows_load_anchors(cf, data, store, &added); - if(result) - return result; - if(added) { - infof(data, " Native: Windows System Stores ROOT+CA"); - octx->store_is_empty = FALSE; - } -#elif defined(USE_APPLE_SECTRUST) - infof(data, " Native: Apple SecTrust"); - have_native_check = TRUE; -#endif - } - - if(conn_config->ca_info_blob) { - result = load_cacert_from_memory(store, conn_config->ca_info_blob); - if(result) { - failf(data, "error adding trust anchors from certificate blob: %d", - result); - return result; - } - infof(data, " CA Blob from configuration"); - octx->store_is_empty = FALSE; - } - - if(ssl_cafile || ssl_capath) { -#ifdef HAVE_OPENSSL3 - /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ - if(ssl_cafile) { - if(!X509_STORE_load_file(store, ssl_cafile)) { - if(octx->store_is_empty && !have_native_check) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error adding trust anchors from file: %s", ssl_cafile); - return CURLE_SSL_CACERT_BADFILE; - } - else - infof(data, "error setting certificate file, continuing anyway"); - } - infof(data, " CAfile: %s", ssl_cafile); - octx->store_is_empty = FALSE; - } - if(ssl_capath) { - if(!X509_STORE_load_path(store, ssl_capath)) { - if(octx->store_is_empty && !have_native_check) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error adding trust anchors from path: %s", ssl_capath); - return CURLE_SSL_CACERT_BADFILE; - } - else - infof(data, "error setting certificate path, continuing anyway"); - } - infof(data, " CApath: %s", ssl_capath); - octx->store_is_empty = FALSE; - } -#else - /* tell OpenSSL where to find CA certificates that are used to verify the - server's certificate. */ - if(!X509_STORE_load_locations(store, ssl_cafile, ssl_capath)) { - if(octx->store_is_empty && !have_native_check) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error adding trust anchors from locations:" - " CAfile: %s CApath: %s", - ssl_cafile ? ssl_cafile : "none", - ssl_capath ? ssl_capath : "none"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - infof(data, "error setting certificate verify locations," - " continuing anyway"); - } - } - if(ssl_cafile) - infof(data, " CAfile: %s", ssl_cafile); - if(ssl_capath) - infof(data, " CApath: %s", ssl_capath); - octx->store_is_empty = FALSE; -#endif - } - -#ifdef CURL_CA_FALLBACK - if(octx->store_is_empty) { - /* verifying the peer without any CA certificates does not - work so use OpenSSL's built-in default as fallback */ - X509_STORE_set_default_paths(store); - infof(data, " OpenSSL default paths (fallback)"); - octx->store_is_empty = FALSE; - } -#endif - if(octx->store_is_empty && !have_native_check) - infof(data, " no trust anchors configured"); - - return result; -} - -static CURLcode ossl_populate_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx, - X509_STORE *store) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - CURLcode result = CURLE_OK; - X509_LOOKUP *lookup = NULL; - const char * const ssl_crlfile = ssl_config->primary.CRLfile; - unsigned long x509flags = 0; - - CURL_TRC_CF(data, cf, "configuring OpenSSL's x509 trust store"); - if(!store) - return CURLE_OUT_OF_MEMORY; - - if(!conn_config->verifypeer) { - infof(data, "SSL Trust: peer verification disabled"); - return CURLE_OK; - } - - infof(data, "SSL Trust Anchors:"); - result = ossl_load_trust_anchors(cf, data, octx, store); - if(result) - return result; - - /* Does not make sense to load a CRL file without peer verification */ - if(ssl_crlfile) { - /* tell OpenSSL where to find CRL file that is used to check certificate - * revocation */ - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); - if(!lookup || - (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM))) { - failf(data, "error loading CRL file: %s", ssl_crlfile); - return CURLE_SSL_CRL_BADFILE; - } - x509flags = X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL; - infof(data, " CRLfile: %s", ssl_crlfile); - } - - /* Try building a chain using issuers in the trusted store first to avoid - problems with server-sent legacy intermediates. Newer versions of - OpenSSL do alternate chain checking by default but we do not know how to - determine that in a reliable manner. - https://web.archive.org/web/20190422050538/rt.openssl.org/Ticket/Display.html?id=3621 - */ - x509flags |= X509_V_FLAG_TRUSTED_FIRST; - - if(!ssl_config->no_partialchain && !ssl_crlfile) { - /* Have intermediate certificates in the trust store be treated as - trust-anchors, in the same way as self-signed root CA certificates are. - This allows users to verify servers using the intermediate cert only, - instead of needing the whole chain. - - Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we - cannot do partial chains with a CRL check. - */ - x509flags |= X509_V_FLAG_PARTIAL_CHAIN; - } - (void)X509_STORE_set_flags(store, x509flags); - - return result; -} - -/* key to use at `multi->proto_hash` */ -#define MPROTO_OSSL_X509_KEY "tls:ossl:x509:share" - -struct ossl_x509_share { - char *CAfile; /* CAfile path used to generate X509 store */ - X509_STORE *store; /* cached X509 store or NULL if none */ - struct curltime time; /* when the cached store was created */ - BIT(store_is_empty); /* no certs/paths/blobs are in the store */ - BIT(no_partialchain); /* keep partial chain state */ -}; - -static void oss_x509_share_free(void *key, size_t key_len, void *p) -{ - struct ossl_x509_share *share = p; - DEBUGASSERT(key_len == (sizeof(MPROTO_OSSL_X509_KEY) - 1)); - DEBUGASSERT(!memcmp(MPROTO_OSSL_X509_KEY, key, key_len)); - (void)key; - (void)key_len; - if(share->store) { - X509_STORE_free(share->store); - } - curlx_free(share->CAfile); - curlx_free(share); -} - -static bool ossl_cached_x509_store_expired(struct Curl_easy *data, - const struct ossl_x509_share *mb) -{ - const struct ssl_general_config *cfg = &data->set.general_ssl; - if(cfg->ca_cache_timeout < 0) - return FALSE; - else { - timediff_t elapsed_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &mb->time); - timediff_t timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000; - - return elapsed_ms >= timeout_ms; - } -} - -static bool ossl_cached_x509_store_different(struct Curl_cfilter *cf, - const struct Curl_easy *data, - const struct ossl_x509_share *mb) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = - Curl_ssl_cf_get_config(cf, CURL_UNCONST(data)); - if(mb->no_partialchain != ssl_config->no_partialchain) - return TRUE; - if(!mb->CAfile || !conn_config->CAfile) - return mb->CAfile != conn_config->CAfile; - return strcmp(mb->CAfile, conn_config->CAfile); -} - -static X509_STORE *ossl_get_cached_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *pempty) -{ - struct Curl_multi *multi = data->multi; - struct ossl_x509_share *share; - X509_STORE *store = NULL; - - DEBUGASSERT(multi); - *pempty = TRUE; - share = multi ? Curl_hash_pick(&multi->proto_hash, - CURL_UNCONST(MPROTO_OSSL_X509_KEY), - sizeof(MPROTO_OSSL_X509_KEY) - 1) : NULL; - if(share && share->store && - !ossl_cached_x509_store_expired(data, share) && - !ossl_cached_x509_store_different(cf, data, share)) { - store = share->store; - *pempty = (bool)share->store_is_empty; - } - - return store; -} - -static void ossl_set_cached_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - X509_STORE *store, - bool is_empty) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_multi *multi = data->multi; - struct ossl_x509_share *share; - - DEBUGASSERT(multi); - if(!multi) - return; - share = Curl_hash_pick(&multi->proto_hash, - CURL_UNCONST(MPROTO_OSSL_X509_KEY), - sizeof(MPROTO_OSSL_X509_KEY) - 1); - - if(!share) { - share = curlx_calloc(1, sizeof(*share)); - if(!share) - return; - if(!Curl_hash_add2(&multi->proto_hash, - CURL_UNCONST(MPROTO_OSSL_X509_KEY), - sizeof(MPROTO_OSSL_X509_KEY) - 1, - share, oss_x509_share_free)) { - curlx_free(share); - return; - } - } - - if(X509_STORE_up_ref(store)) { - char *CAfile = NULL; - struct ssl_config_data *ssl_config = - Curl_ssl_cf_get_config(cf, CURL_UNCONST(data)); - - if(conn_config->CAfile) { - CAfile = curlx_strdup(conn_config->CAfile); - if(!CAfile) { - X509_STORE_free(store); - return; - } - } - - if(share->store) { - X509_STORE_free(share->store); - curlx_free(share->CAfile); - } - - share->time = *Curl_pgrs_now(data); - share->store = store; - share->store_is_empty = is_empty; - share->CAfile = CAfile; - share->no_partialchain = ssl_config->no_partialchain; - } -} - -CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - CURLcode result = CURLE_OK; - X509_STORE *cached_store; - bool cache_criteria_met, is_empty; - - /* Consider the X509 store cacheable if it comes exclusively from a CAfile, - or no source is provided and we are falling back to OpenSSL's built-in - default. */ - cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) && - conn_config->verifypeer && - !conn_config->CApath && - !conn_config->ca_info_blob && - !ssl_config->primary.CRLfile && - !ssl_config->native_ca_store; - - ERR_set_mark(); - - cached_store = ossl_get_cached_x509_store(cf, data, &is_empty); - if(cached_store && cache_criteria_met && X509_STORE_up_ref(cached_store)) { - SSL_CTX_set_cert_store(octx->ssl_ctx, cached_store); - octx->store_is_empty = is_empty; - } - else { - X509_STORE *store = SSL_CTX_get_cert_store(octx->ssl_ctx); - - result = ossl_populate_x509_store(cf, data, octx, store); - if(result == CURLE_OK && cache_criteria_met) { - ossl_set_cached_x509_store(cf, data, store, (bool)octx->store_is_empty); - } - } - - ERR_pop_to_mark(); - - return result; -} - -static CURLcode -ossl_init_session_and_alpns(struct ossl_ctx *octx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - Curl_ossl_init_session_reuse_cb *sess_reuse_cb) -{ - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - struct ssl_primary_config *conn_cfg = Curl_ssl_cf_get_primary_config(cf); - struct alpn_spec alpns; - CURLcode result; - - Curl_alpn_copy(&alpns, alpns_requested); - - octx->reused_session = FALSE; - if(Curl_ssl_scache_use(cf, data) && !conn_cfg->verifystatus) { - struct Curl_ssl_session *scs = NULL; - - result = Curl_ssl_scache_take(cf, data, peer->scache_key, &scs); - if(!result && scs && scs->sdata && scs->sdata_len) { - const unsigned char *der_sessionid = scs->sdata; - size_t der_sessionid_size = scs->sdata_len; - SSL_SESSION *ssl_session = NULL; - - /* If OpenSSL does not accept the session from the cache, this - * is not an error. We continue without it. */ - ssl_session = d2i_SSL_SESSION(NULL, &der_sessionid, - (long)der_sessionid_size); - if(ssl_session) { - if(!SSL_set_session(octx->ssl, ssl_session)) { - VERBOSE(char error_buffer[256]); - infof(data, "SSL: SSL_set_session not accepted, " - "continuing without: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - } - else { - if(conn_cfg->verifypeer && - (SSL_get_verify_result(octx->ssl) != X509_V_OK)) { - /* Session was from unverified connection, cannot reuse here */ - SSL_set_session(octx->ssl, NULL); - infof(data, "SSL session not peer verified, not reusing"); - } - else { - infof(data, "SSL reusing session with ALPN '%s'", - scs->alpn ? scs->alpn : "-"); - octx->reused_session = TRUE; - infof(data, "SSL verify result: %lx", - SSL_get_verify_result(octx->ssl)); -#ifdef HAVE_OPENSSL_EARLYDATA - if(ssl_config->earlydata && scs->alpn && - SSL_SESSION_get_max_early_data(ssl_session) && - !cf->conn->bits.connect_only && - (SSL_version(octx->ssl) == TLS1_3_VERSION)) { - bool do_early_data = FALSE; - if(sess_reuse_cb) { - result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data); - if(result) { - SSL_SESSION_free(ssl_session); - return result; - } - } - if(do_early_data) { - /* We only try the ALPN protocol the session used before, - * otherwise we might send early data for the wrong protocol */ - Curl_alpn_restrict_to(&alpns, scs->alpn); - } - } -#else - (void)ssl_config; - (void)sess_reuse_cb; -#endif - } - } - SSL_SESSION_free(ssl_session); - } - else { - infof(data, "SSL session not accepted by OpenSSL, continuing without"); - } - } - Curl_ssl_scache_return(cf, data, peer->scache_key, scs); - } - - if(alpns.count) { - struct alpn_proto_buf proto; - memset(&proto, 0, sizeof(proto)); - result = Curl_alpn_to_proto_buf(&proto, &alpns); - if(result) { - failf(data, "Error determining ALPN"); - return CURLE_SSL_CONNECT_ERROR; - } - if(SSL_set_alpn_protos(octx->ssl, proto.data, proto.len)) { - failf(data, "Error setting ALPN"); - return CURLE_SSL_CONNECT_ERROR; - } - } - - return CURLE_OK; -} - -#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST -bool Curl_ossl_need_httpsrr(struct Curl_easy *data) -{ - if(!CURLECH_ENABLED(data)) - return FALSE; - if((data->set.tls_ech & CURLECH_GREASE) || - (data->set.tls_ech & CURLECH_CLA_CFG)) - return FALSE; - return TRUE; -} - -static CURLcode ossl_init_ech(struct ossl_ctx *octx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer) -{ - unsigned char *ech_config = NULL; - size_t ech_config_len = 0; - char *outername = data->set.str[STRING_ECH_PUBLIC]; - int trying_ech_now = 0; - CURLcode result = CURLE_OK; - - if(!CURLECH_ENABLED(data)) - return CURLE_OK; - - if(data->set.tls_ech & CURLECH_GREASE) { - infof(data, "ECH: will GREASE ClientHello"); -#ifdef HAVE_BORINGSSL_LIKE - SSL_set_enable_ech_grease(octx->ssl, 1); -#else - SSL_set_options(octx->ssl, SSL_OP_ECH_GREASE); -#endif - } - else if(data->set.tls_ech & CURLECH_CLA_CFG) { -#ifdef HAVE_BORINGSSL_LIKE - /* have to do base64 decode here for BoringSSL */ - const char *b64 = data->set.str[STRING_ECH_CONFIG]; - - if(!b64) { - infof(data, "ECH: ECHConfig from command line empty"); - return CURLE_SSL_CONNECT_ERROR; - } - ech_config_len = 2 * strlen(b64); - result = curlx_base64_decode(b64, &ech_config, &ech_config_len); - if(result || !ech_config) { - infof(data, "ECH: cannot base64 decode ECHConfig from command line"); - if(data->set.tls_ech & CURLECH_HARD) - return result; - } - if(SSL_set1_ech_config_list(octx->ssl, ech_config, ech_config_len) != 1) { - infof(data, "ECH: SSL_ECH_set1_ech_config_list failed"); - if(data->set.tls_ech & CURLECH_HARD) { - curlx_free(ech_config); - return CURLE_SSL_CONNECT_ERROR; - } - } - curlx_free(ech_config); - trying_ech_now = 1; -#else - ech_config = (unsigned char *)data->set.str[STRING_ECH_CONFIG]; - if(!ech_config) { - infof(data, "ECH: ECHConfig from command line empty"); - return CURLE_SSL_CONNECT_ERROR; - } - ech_config_len = strlen(data->set.str[STRING_ECH_CONFIG]); - if(SSL_set1_ech_config_list(octx->ssl, ech_config, ech_config_len) != 1) { - infof(data, "ECH: SSL_ECH_set1_ech_config_list failed"); - if(data->set.tls_ech & CURLECH_HARD) - return CURLE_SSL_CONNECT_ERROR; - } - else - trying_ech_now = 1; -#endif /* HAVE_BORINGSSL_LIKE */ - infof(data, "ECH: ECHConfig from command line"); - } - else { - const struct Curl_https_rrinfo *rinfo = - Curl_conn_dns_get_https(data, cf->sockindex); - - if(rinfo && rinfo->echconfiglist) { - const unsigned char *ecl = rinfo->echconfiglist; - size_t elen = rinfo->echconfiglist_len; - - infof(data, "ECH: ECHConfig from HTTPS RR"); - if(SSL_set1_ech_config_list(octx->ssl, ecl, elen) != 1) { - infof(data, "ECH: SSL_set1_ech_config_list failed"); - if(data->set.tls_ech & CURLECH_HARD) - return CURLE_SSL_CONNECT_ERROR; - } - else { - trying_ech_now = 1; - infof(data, "ECH: imported ECHConfigList of length %zu", elen); - } - } - else { - infof(data, "ECH: requested but no ECHConfig available"); - if(data->set.tls_ech & CURLECH_HARD) - return CURLE_SSL_CONNECT_ERROR; - } - } -#ifdef HAVE_BORINGSSL_LIKE - (void)peer; - if(trying_ech_now && outername) { - infof(data, "ECH: setting public_name not supported with BoringSSL"); - return CURLE_SSL_CONNECT_ERROR; - } -#else - if(trying_ech_now && outername) { - infof(data, "ECH: inner: '%s', outer: '%s'", - peer->hostname ? peer->hostname : "NULL", outername); - result = SSL_ech_set1_server_names(octx->ssl, - peer->hostname, outername, - 0 /* do send outer */); - if(result != 1) { - infof(data, "ECH: rv failed to set server name(s) %d [ERROR]", result); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* HAVE_BORINGSSL_LIKE */ - if(trying_ech_now && - SSL_set_min_proto_version(octx->ssl, TLS1_3_VERSION) != 1) { - infof(data, "ECH: cannot force TLSv1.3 [ERROR]"); - return CURLE_SSL_CONNECT_ERROR; - } - - return CURLE_OK; -} -#else /* HAVE_SSL_SET1_ECH_CONFIG_LIST */ -bool Curl_ossl_need_httpsrr(struct Curl_easy *data) -{ - (void)data; - return FALSE; -} -#endif /* else HAVE_SSL_SET1_ECH_CONFIG_LIST */ - -static CURLcode ossl_init_ssl(struct ossl_ctx *octx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - void *ssl_user_data, - Curl_ossl_init_session_reuse_cb *sess_reuse_cb) -{ - /* Let's make an SSL structure */ - if(octx->ssl) - SSL_free(octx->ssl); - octx->ssl = SSL_new(octx->ssl_ctx); - if(!octx->ssl) { - failf(data, "SSL: could not create a context (handle)"); - return CURLE_OUT_OF_MEMORY; - } - - SSL_set_app_data(octx->ssl, ssl_user_data); - -#ifndef OPENSSL_NO_OCSP - if(Curl_ssl_cf_get_primary_config(cf)->verifystatus) - SSL_set_tlsext_status_type(octx->ssl, TLSEXT_STATUSTYPE_ocsp); -#endif - - SSL_set_connect_state(octx->ssl); - - if(peer->sni) { - if(!SSL_set_tlsext_host_name(octx->ssl, peer->sni)) { - failf(data, "Failed set SNI"); - return CURLE_SSL_CONNECT_ERROR; - } - } - -#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST - { - CURLcode result = ossl_init_ech(octx, cf, data, peer); - if(result) - return result; - } -#endif /* HAVE_SSL_SET1_ECH_CONFIG_LIST */ - - return ossl_init_session_and_alpns(octx, cf, data, peer, - alpns_requested, sess_reuse_cb); -} - -static CURLcode ossl_init_method(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const SSL_METHOD **pmethod, - unsigned int *pssl_version_min) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - - *pmethod = NULL; - *pssl_version_min = conn_config->version; - DEBUGASSERT(conn_config->version != CURL_SSLVERSION_DEFAULT); - switch(peer->transport) { - case TRNSPRT_TCP: - /* check to see if we have been told to use an explicit SSL/TLS version */ - switch(*pssl_version_min) { - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - /* it is handled later with the context options */ - *pmethod = TLS_client_method(); - break; - case CURL_SSLVERSION_SSLv2: - failf(data, "No SSLv2 support"); - return CURLE_NOT_BUILT_IN; - case CURL_SSLVERSION_SSLv3: - failf(data, "No SSLv3 support"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - case TRNSPRT_QUIC: - *pssl_version_min = CURL_SSLVERSION_TLSv1_3; - if(conn_config->version_max && - (conn_config->version_max != CURL_SSLVERSION_MAX_DEFAULT) && - (conn_config->version_max != CURL_SSLVERSION_MAX_TLSv1_3)) { - failf(data, "QUIC needs at least TLS version 1.3"); - return CURLE_SSL_CONNECT_ERROR; - } - - *pmethod = TLS_method(); - break; - default: - failf(data, "unsupported transport %d in SSL init", peer->transport); - return CURLE_SSL_CONNECT_ERROR; - } - - return *pmethod ? CURLE_OK : CURLE_SSL_CONNECT_ERROR; -} - -CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - Curl_ossl_ctx_setup_cb *cb_setup, - void *cb_user_data, - Curl_ossl_new_session_cb *cb_new_session, - void *ssl_user_data, - Curl_ossl_init_session_reuse_cb *sess_reuse_cb) -{ - CURLcode result = CURLE_OK; - const char *ciphers; - const SSL_METHOD *req_method = NULL; - ctx_option_t ctx_options = 0; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - char * const ssl_cert = ssl_config->primary.clientcert; - const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; - const char * const ssl_cert_type = ssl_config->cert_type; - unsigned int ssl_version_min; - char error_buffer[256]; - - /* Make funny stuff to get random input */ - result = ossl_seed(data); - if(result) - return result; - - ssl_config->certverifyresult = !X509_V_OK; - - result = ossl_init_method(cf, data, peer, &req_method, &ssl_version_min); - if(result) - return result; - DEBUGASSERT(req_method); - - DEBUGASSERT(!octx->ssl_ctx); - octx->ssl_ctx = -#ifdef OPENSSL_HAS_PROVIDERS - data->state.libctx ? - SSL_CTX_new_ex(data->state.libctx, data->state.propq, req_method): -#endif - SSL_CTX_new(req_method); - - if(!octx->ssl_ctx) { - failf(data, "SSL: could not create a context: %s", - ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer))); - return CURLE_OUT_OF_MEMORY; - } - - if(cb_setup) { - result = cb_setup(cf, data, cb_user_data); - if(result) - return result; - } - - if(data->set.fdebug && data->set.verbose) { - /* the SSL trace callback is only used for verbose logging */ - SSL_CTX_set_msg_callback(octx->ssl_ctx, ossl_trace); - SSL_CTX_set_msg_callback_arg(octx->ssl_ctx, cf); - } - - /* OpenSSL contains code to work around lots of bugs and flaws in various - SSL-implementations. SSL_CTX_set_options() is used to enabled those - work-arounds. The man page for this option states that SSL_OP_ALL enables - all the work-arounds and that "It is usually safe to use SSL_OP_ALL to - enable the bug workaround options if compatibility with somewhat broken - implementations is desired." - - The "-no_ticket" option was introduced in OpenSSL 0.9.8j. it is a flag to - disable "rfc4507bis session ticket support". rfc4507bis was later turned - into the proper RFC5077: https://datatracker.ietf.org/doc/html/rfc5077 - - The enabled extension concerns the session management. I wonder how often - libcurl stops a connection and then resumes a TLS session. Also, sending - the session data is some overhead. I suggest that you use your proposed - patch (which explicitly disables TICKET). - - If someone writes an application with libcurl and OpenSSL who wants to - enable the feature, one can do this in the SSL callback. - - SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper - interoperability with web server Netscape Enterprise Server 2.0.1 which - was released back in 1996. - - Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has - become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate - CVE-2010-4180 when using previous OpenSSL versions we no longer enable - this option regardless of OpenSSL version and SSL_OP_ALL definition. - - OpenSSL added a work-around for an SSL 3.0/TLS 1.0 CBC vulnerability: - https://web.archive.org/web/20240114184648/openssl.org/~bodo/tls-cbc.txt. - In 0.9.6e they added a bit to SSL_OP_ALL that _disables_ that work-around - despite the fact that SSL_OP_ALL is documented to do "rather harmless" - workarounds. In order to keep the secure work-around, the - SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit must not be set. - */ - - ctx_options = SSL_OP_ALL | SSL_OP_NO_TICKET | SSL_OP_NO_COMPRESSION; - - /* mitigate CVE-2010-4180 */ - ctx_options &= ~(ctx_option_t)SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; - - /* unless the user explicitly asks to allow the protocol vulnerability we - use the work-around */ - if(!ssl_config->enable_beast) - ctx_options &= ~(ctx_option_t)SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; - - DEBUGASSERT(ssl_version_min != CURL_SSLVERSION_DEFAULT); - switch(ssl_version_min) { - case CURL_SSLVERSION_SSLv2: - case CURL_SSLVERSION_SSLv3: - return CURLE_NOT_BUILT_IN; - - /* "--tlsv" options mean TLS >= version */ - case CURL_SSLVERSION_TLSv1: /* TLS >= version 1.0 */ - case CURL_SSLVERSION_TLSv1_0: /* TLS >= version 1.0 */ - case CURL_SSLVERSION_TLSv1_1: /* TLS >= version 1.1 */ - case CURL_SSLVERSION_TLSv1_2: /* TLS >= version 1.2 */ - case CURL_SSLVERSION_TLSv1_3: /* TLS >= version 1.3 */ - /* asking for any TLS version as the minimum, means no SSL versions - allowed */ - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_SSLv3; - - result = ossl_set_ssl_version_min_max(cf, octx->ssl_ctx, ssl_version_min); - if(result) - return result; - break; - - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - - SSL_CTX_set_options(octx->ssl_ctx, ctx_options); - SSL_CTX_set_read_ahead(octx->ssl_ctx, 1); - - /* Max TLS1.2 record size 0x4000 + 0x800. - OpenSSL supports processing "jumbo TLS record" (8 TLS records) in one go - for some algorithms, so match that here. - Experimentation shows that a slightly larger buffer is needed - to avoid short reads. - - However using a large buffer (8 packets) actually decreases performance. - 4 packets is better. - */ -#ifdef HAVE_SSL_CTX_SET_DEFAULT_READ_BUFFER_LEN - SSL_CTX_set_default_read_buffer_len(octx->ssl_ctx, 0x401e * 4); -#endif - - /* We do retry writes sometimes from another buffer address */ - SSL_CTX_set_mode(octx->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - - ciphers = conn_config->cipher_list; - if(!ciphers && (peer->transport != TRNSPRT_QUIC)) - ciphers = NULL; - if(ciphers && (ssl_version_min < CURL_SSLVERSION_TLSv1_3)) { - if(!SSL_CTX_set_cipher_list(octx->ssl_ctx, ciphers)) { - failf(data, "failed setting cipher list: %s", ciphers); - return CURLE_SSL_CIPHER; - } - infof(data, "Cipher selection: %s", ciphers); - } - -#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES - { - const char *ciphers13 = conn_config->cipher_list13; - if(ciphers13 && - (!conn_config->version_max || - (conn_config->version_max == CURL_SSLVERSION_MAX_DEFAULT) || - (conn_config->version_max >= CURL_SSLVERSION_MAX_TLSv1_3))) { - if(!SSL_CTX_set_ciphersuites(octx->ssl_ctx, ciphers13)) { - failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); - return CURLE_SSL_CIPHER; - } - infof(data, "TLS 1.3 cipher selection: %s", ciphers13); - } - } -#endif - - if(ssl_cert || ssl_cert_blob || ssl_cert_type) { - result = client_cert(data, octx->ssl_ctx, - ssl_cert, ssl_cert_blob, ssl_cert_type, - ssl_config->key, ssl_config->key_blob, - ssl_config->key_type, ssl_config->key_passwd); - if(result) - /* failf() is already done in client_cert() */ - return result; - } - -#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH - /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ - SSL_CTX_set_post_handshake_auth(octx->ssl_ctx, 1); -#endif - - { - const char *curves = conn_config->curves; - if(curves) { -#ifdef HAVE_BORINGSSL_LIKE -#define OSSL_CURVE_CAST(x) (x) -#else -#define OSSL_CURVE_CAST(x) (char *)CURL_UNCONST(x) -#endif - if(!SSL_CTX_set1_curves_list(octx->ssl_ctx, OSSL_CURVE_CAST(curves))) { - failf(data, "failed setting curves list: '%s'", curves); - return CURLE_SSL_CIPHER; - } - } - } - -#ifdef HAVE_SSL_CTX_SET1_SIGALGS -#define OSSL_SIGALG_CAST(x) OSSL_CURVE_CAST(x) - { - const char *signature_algorithms = conn_config->signature_algorithms; - if(signature_algorithms) { - if(!SSL_CTX_set1_sigalgs_list(octx->ssl_ctx, - OSSL_SIGALG_CAST(signature_algorithms))) { - failf(data, "failed setting signature algorithms: '%s'", - signature_algorithms); - return CURLE_SSL_CIPHER; - } - } - } -#endif - -#if defined(HAVE_OPENSSL_SRP) && defined(USE_TLS_SRP) - if(ssl_config->primary.username && Curl_auth_allowed_to_host(data)) { - char * const ssl_username = ssl_config->primary.username; - char * const ssl_password = ssl_config->primary.password; - infof(data, "Using TLS-SRP username: %s", ssl_username); - - if(!SSL_CTX_set_srp_username(octx->ssl_ctx, ssl_username)) { - failf(data, "Unable to set SRP username"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(!SSL_CTX_set_srp_password(octx->ssl_ctx, ssl_password)) { - failf(data, "failed setting SRP password"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(!conn_config->cipher_list) { - infof(data, "Setting cipher list SRP"); - - if(!SSL_CTX_set_cipher_list(octx->ssl_ctx, "SRP")) { - failf(data, "failed setting SRP cipher list"); - return CURLE_SSL_CIPHER; - } - } - } -#endif /* HAVE_OPENSSL_SRP && USE_TLS_SRP */ - - /* OpenSSL always tries to verify the peer. By setting the failure mode - * to NONE, we allow the connect to complete, regardless of the outcome. - * We then explicitly check the result and may try alternatives like - * Apple's SecTrust for verification. */ - SSL_CTX_set_verify(octx->ssl_ctx, SSL_VERIFY_NONE, NULL); - - /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ -#if !defined(HAVE_KEYLOG_UPSTREAM) && defined(HAVE_KEYLOG_CALLBACK) - if(Curl_tls_keylog_enabled()) { - SSL_CTX_set_keylog_callback(octx->ssl_ctx, ossl_keylog_callback); - } -#endif - - if(cb_new_session) { - /* Enable the session cache because it is a prerequisite for the - * "new session" callback. Use the "external storage" mode to prevent - * OpenSSL from creating an internal session cache. - */ - SSL_CTX_set_session_cache_mode(octx->ssl_ctx, - SSL_SESS_CACHE_CLIENT | - SSL_SESS_CACHE_NO_INTERNAL); - SSL_CTX_sess_set_new_cb(octx->ssl_ctx, cb_new_session); - } - - /* give application a chance to interfere with SSL set up. */ - if(data->set.ssl.fsslctx) { - /* When a user callback is installed to modify the SSL_CTX, - * we need to do the full initialization before calling it. - * See: #11800 */ - if(!octx->x509_store_setup) { - result = Curl_ssl_setup_x509_store(cf, data, octx); - if(result) - return result; - octx->x509_store_setup = TRUE; - } - Curl_set_in_callback(data, TRUE); - result = (*data->set.ssl.fsslctx)(data, octx->ssl_ctx, - data->set.ssl.fsslctxp); - Curl_set_in_callback(data, FALSE); - if(result) { - failf(data, "error signaled by ssl ctx callback"); - return result; - } - } - - return ossl_init_ssl(octx, cf, data, peer, alpns_requested, - ssl_user_data, sess_reuse_cb); -} - -static CURLcode ossl_on_session_reuse(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data) -{ - struct ssl_connect_data *connssl = cf->ctx; - - connssl->earlydata_max = scs->earlydata_max; - - return Curl_on_session_reuse(cf, data, alpns, scs, do_early_data, - connssl->earlydata_max); -} - -void Curl_ossl_report_handshake(struct Curl_easy *data, struct ossl_ctx *octx) -{ -#ifdef CURLVERBOSE - if(Curl_trc_is_verbose(data)) { - int psigtype_nid = NID_undef; - const char *negotiated_group_name = NULL; - -#ifdef HAVE_OPENSSL3 - SSL_get_peer_signature_type_nid(octx->ssl, &psigtype_nid); -#if OPENSSL_VERSION_NUMBER >= 0x30200000L - negotiated_group_name = SSL_get0_group_name(octx->ssl); -#else - negotiated_group_name = - OBJ_nid2sn(SSL_get_negotiated_group(octx->ssl) & 0x0000FFFF); -#endif -#endif - - /* Informational message */ - infof(data, "SSL connection using %s / %s / %s / %s", - SSL_get_version(octx->ssl), - SSL_get_cipher(octx->ssl), - negotiated_group_name ? negotiated_group_name : "[blank]", - OBJ_nid2sn(psigtype_nid)); - } -#else - (void)data; - (void)octx; -#endif /* CURLVERBOSE */ -} - -static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - BIO *bio; - CURLcode result; - - DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); - DEBUGASSERT(octx); - - result = Curl_ossl_ctx_init(octx, cf, data, &connssl->peer, - connssl->alpn, NULL, NULL, - ossl_new_session_cb, cf, - ossl_on_session_reuse); - if(result) - return result; - - octx->bio_method = ossl_bio_cf_method_create(); - if(!octx->bio_method) - return CURLE_OUT_OF_MEMORY; - bio = BIO_new(octx->bio_method); - if(!bio) - return CURLE_OUT_OF_MEMORY; - - BIO_set_data(bio, cf); -#ifdef HAVE_SSL_SET0_WBIO - /* with OpenSSL v1.1.1 we get an alternative to SSL_set_bio() that works - * without backward compat quirks. Every call takes one reference, so we - * up it and pass. SSL* then owns and frees it. - * We check on the function in configure, since LibreSSL and friends - * each have their own versions to add support for this. */ - BIO_up_ref(bio); - SSL_set0_rbio(octx->ssl, bio); - SSL_set0_wbio(octx->ssl, bio); -#else - SSL_set_bio(octx->ssl, bio, bio); -#endif - - if(connssl->alpn && (connssl->state != ssl_connection_deferred)) { - struct alpn_proto_buf proto; - memset(&proto, 0, sizeof(proto)); - Curl_alpn_to_proto_str(&proto, connssl->alpn); - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); - } - - connssl->connecting_state = ssl_connect_2; - return CURLE_OK; -} - -#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST -/* If we have retry configs, then trace those out */ -static int ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL *ssl, - int reason) -{ - CURLcode result = CURLE_OK; - size_t rcl = 0; - int rv = 1; -#ifndef HAVE_BORINGSSL_LIKE - char *inner = NULL; - uint8_t *rcs = NULL; - char *outer = NULL; -#else - const char *inner = NULL; - const uint8_t *rcs = NULL; - const char *outer = NULL; - size_t out_name_len = 0; - int servername_type = 0; -#endif - NOVERBOSE((void)reason); - - /* nothing to trace if not doing ECH */ - if(!CURLECH_ENABLED(data)) - return rv; -#ifndef HAVE_BORINGSSL_LIKE - rv = SSL_ech_get1_retry_config(ssl, &rcs, &rcl); -#else - SSL_get0_ech_retry_configs(ssl, &rcs, &rcl); - rv = (int)rcl; -#endif - - if(rv && rcs) { - char *b64str = NULL; - size_t blen = 0; - - result = curlx_base64_encode(rcs, rcl, &b64str, &blen); - if(!result && b64str) { - infof(data, "ECH: retry_configs %s", b64str); - curlx_free(b64str); -#ifndef HAVE_BORINGSSL_LIKE - rv = SSL_ech_get1_status(ssl, &inner, &outer); - infof(data, "ECH: retry_configs for %s from %s, %d %d", - inner ? inner : "NULL", outer ? outer : "NULL", reason, rv); -#else - rv = SSL_ech_accepted(ssl); - servername_type = SSL_get_servername_type(ssl); - inner = SSL_get_servername(ssl, servername_type); - SSL_get0_ech_name_override(ssl, &outer, &out_name_len); - infof(data, "ECH: retry_configs for %s from %s, %d %d", - inner ? inner : "NULL", outer ? outer : "NULL", reason, rv); -#endif - } - } - else - infof(data, "ECH: no retry_configs (rv = %d)", rv); -#ifndef HAVE_BORINGSSL_LIKE - OPENSSL_free(inner); - OPENSSL_free(rcs); - OPENSSL_free(outer); -#endif - return rv; -} - -#endif - -static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - int err; - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - DEBUGASSERT(ssl_connect_2 == connssl->connecting_state); - DEBUGASSERT(octx); - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - ERR_clear_error(); - - err = SSL_connect(octx->ssl); - - if(!octx->x509_store_setup) { - /* After having send off the ClientHello, we prepare the x509 - * store to verify the coming certificate from the server */ - CURLcode result = Curl_ssl_setup_x509_store(cf, data, octx); - if(result) - return result; - octx->x509_store_setup = TRUE; - } - -#if !defined(HAVE_KEYLOG_UPSTREAM) && !defined(HAVE_KEYLOG_CALLBACK) - /* If key logging is enabled, wait for the handshake to complete and then - * proceed with logging secrets (for TLS 1.2 or older). - */ - if(Curl_tls_keylog_enabled() && !octx->keylog_done) - ossl_log_tls12_secret(octx->ssl, &octx->keylog_done); -#endif - - /* 1 is fine - 0 is "not successful but was shut down controlled" - <0 is "handshake was not successful, because a fatal error occurred" */ - if(err != 1) { - int detail = SSL_get_error(octx->ssl, err); - CURL_TRC_CF(data, cf, "SSL_connect() -> err=%d, detail=%d", err, detail); - - if(SSL_ERROR_WANT_READ == detail) { - CURL_TRC_CF(data, cf, "SSL_connect() -> want recv"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; - return CURLE_AGAIN; - } - if(SSL_ERROR_WANT_WRITE == detail) { - CURL_TRC_CF(data, cf, "SSL_connect() -> want send"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - return CURLE_AGAIN; - } -#ifdef SSL_ERROR_WANT_ASYNC - if(SSL_ERROR_WANT_ASYNC == detail) { - CURL_TRC_CF(data, cf, "SSL_connect() -> want async"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; - return CURLE_AGAIN; - } -#endif -#ifdef SSL_ERROR_WANT_RETRY_VERIFY - if(SSL_ERROR_WANT_RETRY_VERIFY == detail) { - CURL_TRC_CF(data, cf, "SSL_connect() -> want retry_verify"); - Curl_xfer_pause_recv(data, TRUE); - return CURLE_AGAIN; - } -#endif - else { - /* untreated error */ - sslerr_t errdetail; - char error_buffer[256] = ""; - CURLcode result; - long lerr; - int lib; - int reason; - - /* the connection failed, we are not waiting for anything else. */ - connssl->connecting_state = ssl_connect_2; - - /* Get the earliest error code from the thread's error queue and remove - the entry. */ - errdetail = ERR_get_error(); - - /* Extract which lib and reason */ - lib = ERR_GET_LIB(errdetail); - reason = ERR_GET_REASON(errdetail); - - if((lib == ERR_LIB_SSL) && - ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) -/* Missing from OpenSSL 4+ OPENSSL_NO_DEPRECATED_3_0 builds */ -#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED - || (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED) -#endif - )) { - result = CURLE_PEER_FAILED_VERIFICATION; - - lerr = SSL_get_verify_result(octx->ssl); - if(lerr != X509_V_OK) { - ssl_config->certverifyresult = lerr; - failf(data, "SSL certificate problem: %s", - X509_verify_cert_error_string(lerr)); - } - else - failf(data, "%s", "SSL certificate verification failed"); - } -#ifdef SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED - /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on - OpenSSL version above v1.1.1, not LibreSSL, BoringSSL, or AWS-LC */ - else if((lib == ERR_LIB_SSL) && - (reason == SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)) { - /* If client certificate is required, communicate the - error to client */ - result = CURLE_SSL_CLIENTCERT; - failf(data, "TLS cert problem: %s", - ossl_strerror(errdetail, error_buffer, sizeof(error_buffer))); - } -#endif -#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST - else if((lib == ERR_LIB_SSL) && -#ifndef HAVE_BORINGSSL_LIKE - (reason == SSL_R_ECH_REQUIRED)) { -#else - (reason == SSL_R_ECH_REJECTED)) { -#endif /* HAVE_BORINGSSL_LIKE */ - - /* trace retry_configs if we got some */ - ossl_trace_ech_retry_configs(data, octx->ssl, reason); - - result = CURLE_ECH_REQUIRED; - failf(data, "ECH required: %s", - ossl_strerror(errdetail, error_buffer, sizeof(error_buffer))); - } -#endif - else { - result = CURLE_SSL_CONNECT_ERROR; - failf(data, "TLS connect error: %s", - ossl_strerror(errdetail, error_buffer, sizeof(error_buffer))); - } - - /* detail is already set to the SSL error above */ - - /* If we e.g. use SSLv2 request-method and the server does not like us - * (RST connection, etc.), OpenSSL gives no explanation whatsoever and - * the SO_ERROR is also lost. - */ - if(result == CURLE_SSL_CONNECT_ERROR && errdetail == 0) { - char extramsg[80] = ""; - int sockerr = SOCKERRNO; - - if(sockerr && detail == SSL_ERROR_SYSCALL) - curlx_strerror(sockerr, extramsg, sizeof(extramsg)); - failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%d ", - extramsg[0] ? extramsg : SSL_ERROR_to_str(detail), - connssl->peer.hostname, connssl->peer.port); - } - - return result; - } - } - else { - /* we connected fine, we are not waiting for anything else. */ - connssl->connecting_state = ssl_connect_3; - Curl_ossl_report_handshake(data, octx); - -#if defined(HAVE_SSL_SET1_ECH_CONFIG_LIST) && !defined(HAVE_BORINGSSL_LIKE) - if(CURLECH_ENABLED(data)) { - char *inner = NULL, *outer = NULL; - int rv; - VERBOSE(const char *status); - - rv = SSL_ech_get1_status(octx->ssl, &inner, &outer); - switch(rv) { - case SSL_ECH_STATUS_SUCCESS: - VERBOSE(status = "succeeded"); - break; - case SSL_ECH_STATUS_GREASE_ECH: - VERBOSE(status = "sent GREASE, got retry-configs"); - break; - case SSL_ECH_STATUS_GREASE: - VERBOSE(status = "sent GREASE"); - break; - case SSL_ECH_STATUS_NOT_TRIED: - VERBOSE(status = "not attempted"); - break; - case SSL_ECH_STATUS_NOT_CONFIGURED: - VERBOSE(status = "not configured"); - break; - case SSL_ECH_STATUS_BACKEND: - VERBOSE(status = "backend (unexpected)"); - break; - case SSL_ECH_STATUS_FAILED: - VERBOSE(status = "failed"); - break; - case SSL_ECH_STATUS_BAD_CALL: - VERBOSE(status = "bad call (unexpected)"); - break; - case SSL_ECH_STATUS_BAD_NAME: { - struct ssl_primary_config *conn_config = - Curl_ssl_cf_get_primary_config(cf); - if(!conn_config->verifypeer && !conn_config->verifyhost && - inner && !strcmp(inner, connssl->peer.hostname)) { - VERBOSE(status = "bad name (tolerated without peer verification)"); - rv = SSL_ECH_STATUS_SUCCESS; - } - else { - VERBOSE(status = "bad name (unexpected)"); - } - break; - } - default: - VERBOSE(status = "unexpected status"); - infof(data, "ECH: unexpected status %d", rv); - } - infof(data, "ECH: result: status is %s, inner is %s, outer is %s", - (status ? status : "NULL"), - (inner ? inner : "NULL"), - (outer ? outer : "NULL")); - OPENSSL_free(inner); - OPENSSL_free(outer); - if(rv == SSL_ECH_STATUS_GREASE_ECH) { - /* trace retry_configs if we got some */ - ossl_trace_ech_retry_configs(data, octx->ssl, 0); - } - if(rv != SSL_ECH_STATUS_SUCCESS && (data->set.tls_ech & CURLECH_HARD)) { - infof(data, "ECH: ech-hard failed"); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { - infof(data, "ECH: result: status is not attempted"); - } -#endif /* HAVE_SSL_SET1_ECH_CONFIG_LIST && !HAVE_BORINGSSL_LIKE */ - - /* Sets data and len to negotiated protocol, len is 0 if no protocol was - * negotiated - */ - if(connssl->alpn) { - const unsigned char *neg_protocol; - unsigned int len; - SSL_get0_alpn_selected(octx->ssl, &neg_protocol, &len); - - return Curl_alpn_set_negotiated(cf, data, connssl, neg_protocol, len); - } - - return CURLE_OK; - } -} - -/* - * Heavily modified from: - * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL - */ -static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509 *cert, - const char *pinnedpubkey) -{ - /* Scratch */ - int len1 = 0, len2 = 0; - unsigned char *buff1 = NULL, *temp = NULL; - - /* Result is returned to caller */ - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - /* if a path was not specified, do not pin */ - if(!pinnedpubkey) - return CURLE_OK; - - if(!cert) - return result; - - do { - /* Get the subjectPublicKeyInfo */ - /* https://groups.google.com/group/mailing.openssl.users/browse_thread/thread/d61858dae102c6c7 */ - len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL); - if(len1 < 1) - break; /* failed */ - - buff1 = temp = curlx_malloc(len1); - if(!buff1) - break; /* failed */ - - /* https://docs.openssl.org/master/man3/d2i_X509/ */ - len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp); - - /* - * These checks are verifying we got back the same values as when we - * sized the buffer. it is pretty weak since they should always be the - * same, but it gives us something to test. - */ - if((len1 != len2) || !temp || ((temp - buff1) != len1)) - break; /* failed */ - - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); - } while(0); - - if(buff1) - curlx_free(buff1); - - return result; -} - -#ifdef CURLVERBOSE -#if !defined(HAVE_BORINGSSL_LIKE) && \ - !(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3060000fL) -static void infof_certstack(struct Curl_easy *data, const SSL *ssl) -{ - STACK_OF(X509) *certstack; - long verify_result; - int num_cert_levels; - int cert_level; - - if(!Curl_trc_is_verbose(data)) - return; - - verify_result = SSL_get_verify_result(ssl); - if(verify_result != X509_V_OK) - certstack = SSL_get_peer_cert_chain(ssl); - else - certstack = SSL_get0_verified_chain(ssl); - if(!certstack) - return; - num_cert_levels = sk_X509_num(certstack); - - for(cert_level = 0; cert_level < num_cert_levels; cert_level++) { - char cert_algorithm[80] = ""; - char group_name_final[80] = ""; - const X509_ALGOR *palg_cert = NULL; - const ASN1_OBJECT *paobj_cert = NULL; - X509 *current_cert; - EVP_PKEY *current_pkey; - int key_bits; - int key_sec_bits; - int get_group_name; - const char *type_name; - - current_cert = sk_X509_value(certstack, cert_level); - if(!current_cert) - continue; - - current_pkey = X509_get0_pubkey(current_cert); - if(!current_pkey) - continue; - - X509_get0_signature(NULL, &palg_cert, current_cert); - X509_ALGOR_get0(&paobj_cert, NULL, NULL, palg_cert); - OBJ_obj2txt(cert_algorithm, sizeof(cert_algorithm), paobj_cert, 0); - - key_bits = EVP_PKEY_bits(current_pkey); -#ifndef HAVE_OPENSSL3 -#define EVP_PKEY_get_security_bits EVP_PKEY_security_bits -#endif - key_sec_bits = EVP_PKEY_get_security_bits(current_pkey); -#ifdef HAVE_OPENSSL3 - { - char group_name[80] = ""; - get_group_name = EVP_PKEY_get_group_name(current_pkey, group_name, - sizeof(group_name), NULL); - curl_msnprintf(group_name_final, sizeof(group_name_final), "/%s", - group_name); - } - type_name = EVP_PKEY_get0_type_name(current_pkey); -#else - get_group_name = 0; - type_name = NULL; -#endif - - infof(data, " Certificate level %d: " - "Public key type %s%s (%d/%d Bits/secBits), signed using %s", - cert_level, type_name ? type_name : "?", - get_group_name == 0 ? "" : group_name_final, - key_bits, key_sec_bits, cert_algorithm); - } -} -#else -#define infof_certstack(data, ssl) -#endif -#endif /* CURLVERBOSE */ - -static CURLcode ossl_check_issuer(struct Curl_cfilter *cf, - struct Curl_easy *data, - X509 *server_cert) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - X509 *issuer = NULL; - BIO *fp = NULL; - char err_buf[256] = ""; - bool verify_enabled = (conn_config->verifypeer || conn_config->verifyhost); - CURLcode result = CURLE_OK; - - /* e.g. match issuer name with provided issuer certificate */ - if(conn_config->issuercert_blob) { - fp = BIO_new_mem_buf(conn_config->issuercert_blob->data, - (int)conn_config->issuercert_blob->len); - if(!fp) { - failf(data, "BIO_new_mem_buf NULL, " OSSL_PACKAGE " error %s", - ossl_strerror(ERR_get_error(), err_buf, sizeof(err_buf))); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - else if(conn_config->issuercert) { - fp = BIO_new(BIO_s_file()); - if(!fp) { - failf(data, "BIO_new return NULL, " OSSL_PACKAGE " error %s", - ossl_strerror(ERR_get_error(), err_buf, sizeof(err_buf))); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - if(BIO_read_filename(fp, conn_config->issuercert) <= 0) { - if(verify_enabled) - failf(data, "SSL: Unable to open issuer cert (%s)", - conn_config->issuercert); - result = CURLE_SSL_ISSUER_ERROR; - goto out; - } - } - - if(fp) { - issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL); - if(!issuer) { - if(verify_enabled) - failf(data, "SSL: Unable to read issuer cert (%s)", - conn_config->issuercert); - result = CURLE_SSL_ISSUER_ERROR; - goto out; - } - - if(X509_check_issued(issuer, server_cert) != X509_V_OK) { - if(verify_enabled) - failf(data, "SSL: Certificate issuer check failed (%s)", - conn_config->issuercert); - result = CURLE_SSL_ISSUER_ERROR; - goto out; - } - - infof(data, " SSL certificate issuer check ok (%s)", - conn_config->issuercert); - } - -out: - if(fp) - BIO_free(fp); - if(issuer) - X509_free(issuer); - return result; -} - -static CURLcode ossl_check_pinned_key(struct Curl_cfilter *cf, - struct Curl_easy *data, - X509 *server_cert) -{ - const char *ptr; - CURLcode result = CURLE_OK; - - (void)cf; -#ifndef CURL_DISABLE_PROXY - ptr = Curl_ssl_cf_is_proxy(cf) ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif - if(ptr) { - result = ossl_pkp_pin_peer_pubkey(data, server_cert, ptr); - if(result) - failf(data, "SSL: public key does not match pinned public key"); - } - return result; -} - -#ifdef CURLVERBOSE -#define MAX_CERT_NAME_LENGTH 2048 -static CURLcode ossl_infof_cert(struct Curl_cfilter *cf, - struct Curl_easy *data, - X509 *server_cert) -{ - BIO *mem = NULL; - struct dynbuf dname; - char err_buf[256] = ""; - char *buf; - long len; - CURLcode result = CURLE_OK; - - if(!Curl_trc_is_verbose(data)) - return CURLE_OK; - - curlx_dyn_init(&dname, MAX_CERT_NAME_LENGTH); - mem = BIO_new(BIO_s_mem()); - if(!mem) { - failf(data, "BIO_new return NULL, " OSSL_PACKAGE " error %s", - ossl_strerror(ERR_get_error(), err_buf, sizeof(err_buf))); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - infof(data, "%s certificate:", Curl_ssl_cf_is_proxy(cf) ? - "Proxy" : "Server"); - - result = x509_name_oneline(X509_get_subject_name(server_cert), &dname); - infof(data, " subject: %s", result ? "[NONE]" : curlx_dyn_ptr(&dname)); - - ASN1_TIME_print(mem, X509_get0_notBefore(server_cert)); - len = BIO_get_mem_data(mem, (char **)&buf); - infof(data, " start date: %.*s", (int)len, buf); - (void)BIO_reset(mem); - - ASN1_TIME_print(mem, X509_get0_notAfter(server_cert)); - len = BIO_get_mem_data(mem, (char **)&buf); - infof(data, " expire date: %.*s", (int)len, buf); - (void)BIO_reset(mem); - - result = x509_name_oneline(X509_get_issuer_name(server_cert), &dname); - if(result) /* should be only fatal stuff like OOM */ - goto out; - infof(data, " issuer: %s", curlx_dyn_ptr(&dname)); - -out: - BIO_free(mem); - curlx_dyn_free(&dname); - return result; -} -#endif /* CURLVERBOSE */ - -#ifdef USE_APPLE_SECTRUST -struct ossl_certs_ctx { - STACK_OF(X509) *sk; - size_t num_certs; -}; - -static CURLcode ossl_chain_get_der(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *user_data, - size_t i, - unsigned char **pder, - size_t *pder_len) -{ - struct ossl_certs_ctx *chain = user_data; - X509 *cert; - int der_len; - - (void)cf; - (void)data; - *pder_len = 0; - *pder = NULL; - - if(i >= chain->num_certs) - return CURLE_TOO_LARGE; - cert = sk_X509_value(chain->sk, (int)i); - if(!cert) - return CURLE_FAILED_INIT; - der_len = i2d_X509(cert, pder); - if(der_len < 0) - return CURLE_FAILED_INIT; - *pder_len = (size_t)der_len; - return CURLE_OK; -} - -static CURLcode ossl_apple_verify(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx, - struct ssl_peer *peer, - bool *pverified) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ossl_certs_ctx chain; - CURLcode result; - - memset(&chain, 0, sizeof(chain)); - chain.sk = SSL_get_peer_cert_chain(octx->ssl); - chain.num_certs = chain.sk ? sk_X509_num(chain.sk) : 0; - - if(!chain.num_certs && - (conn_config->verifypeer || conn_config->verifyhost)) { - if(!octx->reused_session) { - failf(data, "SSL: could not get peer certificate chain"); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else { - /* when session was reused, there is no peer cert chain */ - *pverified = FALSE; - return CURLE_OK; - } - } - else { -#ifdef HAVE_BORINGSSL_LIKE - const uint8_t *ocsp_data = NULL; -#else - unsigned char *ocsp_data = NULL; -#endif - long ocsp_len = 0; - bool ocsp_missing = FALSE; - if(conn_config->verifystatus && !octx->reused_session) - ocsp_len = (long)SSL_get_tlsext_status_ocsp_resp(octx->ssl, &ocsp_data); - - /* SSL_get_tlsext_status_ocsp_resp() returns the length of the OCSP - response data or -1 if there is no OCSP response data. */ - if(ocsp_len < 0) { - ocsp_len = 0; /* no data available */ - ocsp_missing = TRUE; - } - result = Curl_vtls_apple_verify(cf, data, peer, chain.num_certs, - ossl_chain_get_der, &chain, - ocsp_data, ocsp_len); - if(!result && ocsp_missing && conn_config->verifystatus && - !octx->reused_session) { - /* verified, but OCSP stapling is required and server sent none */ - *pverified = TRUE; - failf(data, "No OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - } - *pverified = !result; - return result; -} -#endif /* USE_APPLE_SECTRUST */ - -CURLcode Curl_ossl_check_peer_cert(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx, - struct ssl_peer *peer) -{ - struct connectdata *conn = cf->conn; - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - CURLcode result = CURLE_OK; - long ossl_verify; - X509 *server_cert; - bool verified = FALSE; -#if !defined(OPENSSL_NO_OCSP) && defined(USE_APPLE_SECTRUST) - bool sectrust_verified = FALSE; -#endif - - if(data->set.ssl.certinfo && !octx->reused_session) { - /* asked to gather certificate info. Reused sessions do not have cert - chains */ - result = ossl_certchain(data, octx->ssl); - if(result) - return result; - } - - server_cert = SSL_get1_peer_certificate(octx->ssl); - if(!server_cert) { - /* no verification at all, this maybe acceptable */ - if(!(conn_config->verifypeer || conn_config->verifyhost)) - goto out; - - failf(data, "SSL: could not get peer certificate"); - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; - } - -#ifdef CURLVERBOSE - result = ossl_infof_cert(cf, data, server_cert); - if(result) - goto out; - infof_certstack(data, octx->ssl); -#endif - - if(conn_config->verifyhost) { - result = ossl_verifyhost(data, conn, peer, server_cert); - if(result) - goto out; - } - /* `verifyhost` is either OK or not requested from here on */ - - ossl_verify = SSL_get_verify_result(octx->ssl); - ssl_config->certverifyresult = ossl_verify; - infof(data, "OpenSSL verify result: %lx", ossl_verify); - - verified = (ossl_verify == X509_V_OK); - if(verified) - infof(data, "SSL certificate verified via OpenSSL."); - -#ifdef USE_APPLE_SECTRUST - if(!verified && conn_config->verifypeer && ssl_config->native_ca_store) { - /* we verify using Apple SecTrust *unless* OpenSSL already verified. - * This may happen if the application intercepted the OpenSSL callback - * and installed its own. */ - result = ossl_apple_verify(cf, data, octx, peer, &verified); - if(result && (result != CURLE_PEER_FAILED_VERIFICATION)) - goto out; /* unexpected error */ - if(verified) { - infof(data, "SSL certificate verified via Apple SecTrust."); - ssl_config->certverifyresult = X509_V_OK; -#ifndef OPENSSL_NO_OCSP - sectrust_verified = TRUE; -#endif - } - } -#endif - - if(!verified) { - /* no trust established, report the OpenSSL status */ - if(conn_config->verifypeer) { - failf(data, "SSL certificate OpenSSL verify result: %s (%ld)", - X509_verify_cert_error_string(ossl_verify), ossl_verify); - result = CURLE_PEER_FAILED_VERIFICATION; - goto out; - } - infof(data, " SSL certificate verification failed, continuing anyway!"); - } - -#ifndef OPENSSL_NO_OCSP - if(conn_config->verifystatus && -#ifdef USE_APPLE_SECTRUST - !sectrust_verified && /* already verified via apple sectrust, cannot - * verifystate via OpenSSL in that case as it - * does not have the trust anchors */ -#endif - !octx->reused_session) { - /* do not do this after Session ID reuse */ - result = verifystatus(cf, data, octx); - if(result) - goto out; - } -#endif - - result = ossl_check_issuer(cf, data, server_cert); - if(result) - goto out; - - result = ossl_check_pinned_key(cf, data, server_cert); - -out: - X509_free(server_cert); - return result; -} - -static CURLcode ossl_connect_step3(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - CURLcode result = CURLE_OK; - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - /* - * We check certificates to authenticate the server; otherwise we risk - * man-in-the-middle attack; NEVERTHELESS, if we are told explicitly not to - * verify the peer, ignore faults and failures from the server cert - * operations. - */ - - result = Curl_ossl_check_peer_cert(cf, data, octx, &connssl->peer); - if(result) - /* on error, remove sessions we might have in the pool */ - Curl_ssl_scache_remove_all(cf, data, connssl->peer.scache_key); - - return result; -} - -#ifdef HAVE_OPENSSL_EARLYDATA -static CURLcode ossl_send_earlydata(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - CURLcode result = CURLE_OK; - const unsigned char *buf; - size_t blen, nwritten; - int rc; - - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sending); - octx->io_result = CURLE_OK; - while(Curl_bufq_peek(&connssl->earlydata, &buf, &blen)) { - nwritten = 0; - rc = SSL_write_early_data(octx->ssl, buf, blen, &nwritten); - CURL_TRC_CF(data, cf, "SSL_write_early_data(len=%zu) -> %d, %zu", - blen, rc, nwritten); - if(rc <= 0) { - long sslerror; - char error_buffer[256]; - int err = SSL_get_error(octx->ssl, rc); - - switch(err) { - case SSL_ERROR_WANT_READ: - connssl->io_need = CURL_SSL_IO_NEED_RECV; - result = CURLE_AGAIN; - goto out; - case SSL_ERROR_WANT_WRITE: - connssl->io_need = CURL_SSL_IO_NEED_SEND; - result = CURLE_AGAIN; - goto out; - case SSL_ERROR_SYSCALL: { - int sockerr = SOCKERRNO; - - if(octx->io_result == CURLE_AGAIN) { - result = CURLE_AGAIN; - goto out; - } - sslerror = ERR_get_error(); - if(sslerror) - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); - else if(sockerr) - curlx_strerror(sockerr, error_buffer, sizeof(error_buffer)); - else - curl_msnprintf(error_buffer, sizeof(error_buffer), "%s", - SSL_ERROR_to_str(err)); - - failf(data, OSSL_PACKAGE " SSL_write:early_data: %s, errno %d", - error_buffer, sockerr); - result = CURLE_SEND_ERROR; - goto out; - } - case SSL_ERROR_SSL: { - /* A failure in the SSL library occurred, usually a protocol error. - The OpenSSL error queue contains more information on the error. */ - sslerror = ERR_get_error(); - failf(data, "SSL_write_early_data() error: %s", - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); - result = CURLE_SEND_ERROR; - goto out; - } - default: - /* a true error */ - failf(data, OSSL_PACKAGE " SSL_write_early_data: %s, errno %d", - SSL_ERROR_to_str(err), SOCKERRNO); - result = CURLE_SEND_ERROR; - goto out; - } - } - Curl_bufq_skip(&connssl->earlydata, nwritten); - } - /* sent everything there was */ - infof(data, "SSL sending %zu bytes of early data", connssl->earlydata_skip); -out: - return result; -} -#endif /* HAVE_OPENSSL_EARLYDATA */ - -static CURLcode ossl_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - CURLcode result = CURLE_OK; - struct ssl_connect_data *connssl = cf->ctx; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - - if(ssl_connect_1 == connssl->connecting_state) { - if(Curl_ossl_need_httpsrr(data) && - !Curl_conn_dns_resolved_https(data, cf->sockindex)) { - CURL_TRC_CF(data, cf, "need HTTPS-RR, delaying connect"); - return CURLE_OK; - } - CURL_TRC_CF(data, cf, "ossl_connect, step1"); - result = ossl_connect_step1(cf, data); - if(result) - goto out; - } - - if(ssl_connect_2 == connssl->connecting_state) { - CURL_TRC_CF(data, cf, "ossl_connect, step2"); -#ifdef HAVE_OPENSSL_EARLYDATA - if(connssl->earlydata_state == ssl_earlydata_await) { - goto out; - } - else if(connssl->earlydata_state == ssl_earlydata_sending) { - result = ossl_send_earlydata(cf, data); - if(result) - goto out; - connssl->earlydata_state = ssl_earlydata_sent; - } -#endif - DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) || - (connssl->earlydata_state == ssl_earlydata_sent)); - - result = ossl_connect_step2(cf, data); - if(result) - goto out; - } - - if(ssl_connect_3 == connssl->connecting_state) { - CURL_TRC_CF(data, cf, "ossl_connect, step3"); - result = ossl_connect_step3(cf, data); - if(result) - goto out; - connssl->connecting_state = ssl_connect_done; -#ifdef HAVE_OPENSSL_EARLYDATA - if(connssl->earlydata_state > ssl_earlydata_none) { - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - /* We should be in this state by now */ - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent); - connssl->earlydata_state = - (SSL_get_early_data_status(octx->ssl) == SSL_EARLY_DATA_ACCEPTED) ? - ssl_earlydata_accepted : ssl_earlydata_rejected; - } -#endif - } - - if(ssl_connect_done == connssl->connecting_state) { - CURL_TRC_CF(data, cf, "ossl_connect, done"); - connssl->state = ssl_connection_complete; - } - -out: - if(result == CURLE_AGAIN) { - *done = FALSE; - return CURLE_OK; - } - *done = ((connssl->state == ssl_connection_complete) || - (connssl->state == ssl_connection_deferred)); - return result; -} - -static bool ossl_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - (void)data; - return (bool)connssl->input_pending; -} - -static CURLcode ossl_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *mem, - size_t len, - size_t *pnwritten) -{ - /* SSL_write() is said to return 'int' while write() and send() returns - 'size_t' */ - int err; - char error_buffer[256]; - sslerr_t sslerror; - int memlen; - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - CURLcode result = CURLE_OK; - int nwritten; - - DEBUGASSERT(octx); - *pnwritten = 0; - ERR_clear_error(); - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; - if(octx->blocked_ssl_write_len && (octx->blocked_ssl_write_len != memlen)) { - /* The previous SSL_write() call was blocked, using that length. - * We need to use that again or OpenSSL freaks out. A shorter - * length should not happen and is a bug in libcurl. */ - if(octx->blocked_ssl_write_len > memlen) { - DEBUGASSERT(0); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - memlen = octx->blocked_ssl_write_len; - } - octx->blocked_ssl_write_len = 0; - nwritten = SSL_write(octx->ssl, mem, memlen); - - if(nwritten > 0) - *pnwritten = (size_t)nwritten; - else { - err = SSL_get_error(octx->ssl, nwritten); - - switch(err) { - case SSL_ERROR_WANT_READ: - connssl->io_need = CURL_SSL_IO_NEED_RECV; - octx->blocked_ssl_write_len = memlen; - result = CURLE_AGAIN; - goto out; - case SSL_ERROR_WANT_WRITE: - result = CURLE_AGAIN; - octx->blocked_ssl_write_len = memlen; - goto out; - case SSL_ERROR_SYSCALL: { - int sockerr = SOCKERRNO; - - if(octx->io_result == CURLE_AGAIN) { - octx->blocked_ssl_write_len = memlen; - result = CURLE_AGAIN; - goto out; - } - sslerror = ERR_get_error(); - if(sslerror) - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); - else if(sockerr) - curlx_strerror(sockerr, error_buffer, sizeof(error_buffer)); - else - curl_msnprintf(error_buffer, sizeof(error_buffer), "%s", - SSL_ERROR_to_str(err)); - - failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d", - error_buffer, sockerr); - result = CURLE_SEND_ERROR; - goto out; - } - case SSL_ERROR_SSL: { - /* A failure in the SSL library occurred, usually a protocol error. - The OpenSSL error queue contains more information on the error. */ - sslerror = ERR_get_error(); - failf(data, "SSL_write() error: %s", - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); - result = CURLE_SEND_ERROR; - goto out; - } - default: - /* a true error */ - failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d", - SSL_ERROR_to_str(err), SOCKERRNO); - result = CURLE_SEND_ERROR; - goto out; - } - } - -out: - return result; -} - -static CURLcode ossl_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, /* transfer */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - size_t *pnread) -{ - char error_buffer[256]; - unsigned long sslerror; - int buffsize; - struct ssl_connect_data *connssl = cf->ctx; - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - CURLcode result = CURLE_OK; - int nread; - - DEBUGASSERT(octx); - - *pnread = 0; - ERR_clear_error(); - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; - nread = SSL_read(octx->ssl, buf, buffsize); - - if(nread > 0) - *pnread = (size_t)nread; - else { - /* failed SSL_read */ - int err = SSL_get_error(octx->ssl, nread); - - switch(err) { - case SSL_ERROR_NONE: /* this is not an error */ - break; - case SSL_ERROR_ZERO_RETURN: /* no more data */ - /* close_notify alert */ - if(cf->sockindex == FIRSTSOCKET) - /* mark the connection for close if it is indeed the control - connection */ - CURL_TRC_CF(data, cf, "TLS close_notify"); - break; - case SSL_ERROR_WANT_READ: - connssl->io_need = CURL_SSL_IO_NEED_RECV; - result = CURLE_AGAIN; - goto out; - case SSL_ERROR_WANT_WRITE: - connssl->io_need = CURL_SSL_IO_NEED_SEND; - result = CURLE_AGAIN; - goto out; - default: - /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return - value/errno" */ - /* https://docs.openssl.org/master/man3/ERR_get_error/ */ - if(octx->io_result == CURLE_AGAIN) { - result = CURLE_AGAIN; - goto out; - } - sslerror = ERR_get_error(); - if((nread < 0) || sslerror) { - /* If the return code was negative or there actually is an error in the - queue */ - int sockerr = SOCKERRNO; - if(sslerror) - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); - else if(sockerr && err == SSL_ERROR_SYSCALL) - curlx_strerror(sockerr, error_buffer, sizeof(error_buffer)); - else - curl_msnprintf(error_buffer, sizeof(error_buffer), "%s", - SSL_ERROR_to_str(err)); - failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d", - error_buffer, sockerr); - result = CURLE_RECV_ERROR; - goto out; - } - else if(err == SSL_ERROR_SYSCALL) { - if(octx->io_result) { - /* logging handling in underlying filter already */ - result = octx->io_result; - } - else if(connssl->peer_closed) { - failf(data, "Connection closed abruptly"); - result = CURLE_RECV_ERROR; - } - else { - /* We should no longer get here nowadays, but handle - * the error in case of some weirdness in the OSSL stack */ - int sockerr = SOCKERRNO; - if(sockerr) - curlx_strerror(sockerr, error_buffer, sizeof(error_buffer)); - else { - curl_msnprintf(error_buffer, sizeof(error_buffer), - "Connection closed abruptly"); - } - failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d", - error_buffer, sockerr); - result = CURLE_RECV_ERROR; - } - goto out; - } - } - } - -out: - if((!result && !*pnread) || (result == CURLE_AGAIN)) { - /* This happens when: - * - we read an EOF - * - OpenSSLs buffers are empty, there is no more data - * - OpenSSL read is blocked on writing something first - * - an incomplete TLS packet is buffered that cannot be read - * until more data arrives */ - connssl->input_pending = FALSE; - } - CURL_TRC_CF(data, cf, "ossl_recv(len=%zu) -> %d, %zu (in_pending=%d)", - buffersize, result, *pnread, connssl->input_pending); - return result; -} - -static CURLcode ossl_get_channel_binding(struct Curl_easy *data, - int sockindex, - struct dynbuf *binding) -{ - X509 *cert; - int mdnid; - bool no_digest_acceptable = FALSE; - const EVP_MD *algo_type = NULL; - const char *algo_name = NULL; - unsigned int length; - unsigned char buf[EVP_MAX_MD_SIZE]; - - const char prefix[] = "tls-server-end-point:"; - struct connectdata *conn = data->conn; - struct Curl_cfilter *cf = conn->cfilter[sockindex]; - struct ossl_ctx *octx = NULL; - CURLcode result = CURLE_OK; - - do { - const struct Curl_cftype *cft = cf->cft; - struct ssl_connect_data *connssl = cf->ctx; - - if(cft->name && !strcmp(cft->name, "SSL")) { - octx = (struct ossl_ctx *)connssl->backend; - break; - } - - cf = cf->next; - } while(cf); - - if(!octx) { - failf(data, "Failed to find the SSL filter"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - cert = SSL_get1_peer_certificate(octx->ssl); - if(!cert) - /* No server certificate, do not do channel binding */ - return CURLE_OK; - -#ifdef HAVE_OPENSSL3 - { - int pknid, secbits; - uint32_t flags; - EVP_PKEY *pkey = X509_get0_pubkey(cert); - - if(!X509_get_signature_info(cert, &mdnid, &pknid, &secbits, &flags)) { - failf(data, "certificate signature algorithm not recognized"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - - if(mdnid != NID_undef) { - if(mdnid == NID_md5 || mdnid == NID_sha1) { - algo_type = EVP_sha256(); - } - else - algo_type = EVP_get_digestbynid(mdnid); - } - else if(pkey && !EVP_PKEY_is_a(pkey, OBJ_nid2sn(pknid))) { - /* The cert's pkey is different from the algorithm used to sign - * the certificate. Since the reported `mdnid` is undefined, there - * is no digest algorithm available here. This happens in PQC - * and is accepted, resulting in no addition to the binding. */ - no_digest_acceptable = TRUE; - } - else if(pkey) { - /* cert's pkey type is the same as the cert signer (or same family). - * Ask for the mandatory/advisory digest algorithm for the pkey. - */ - char mdname[128] = ""; - int rc = EVP_PKEY_get_default_digest_name(pkey, mdname, sizeof(mdname)); - bool md_is_undef = !strcmp(mdname, "UNDEF"); - - if(rc == 2 && md_is_undef) { - /* OpenSSL declares "undef" the *mandatory* digest for this key. - * This is some PQC shit, accept it, no addition to binding. */ - no_digest_acceptable = TRUE; - } - else if(rc > 0 && mdname[0] != '\0' && !md_is_undef) { - infof(data, "Digest algorithm : %s%s (derived from public key)" - ", but unavailable", - mdname, rc == 2 ? " [mandatory]" : " [advisory]"); - } - } - } -#else /* HAVE_OPENSSL3 */ - - if(!OBJ_find_sigid_algs(X509_get_signature_nid(cert), &mdnid, NULL)) { - failf(data, - "Unable to find digest NID for certificate signature algorithm"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - - /* https://datatracker.ietf.org/doc/html/rfc5929#section-4.1 */ - if(mdnid == NID_md5 || mdnid == NID_sha1) { - algo_type = EVP_sha256(); - } - else { - algo_type = EVP_get_digestbynid(mdnid); - if(!algo_type) { - algo_name = OBJ_nid2sn(mdnid); - failf(data, "Could not find digest algorithm %s (NID %d)", - algo_name ? algo_name : "(null)", mdnid); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - } - -#endif /* HAVE_OPENSSL3, else */ - - if(!algo_type) { - if(no_digest_acceptable) { - infof(data, "certificate exposes no signing digest algorithm, " - "nothing to add to channel binding"); - result = CURLE_OK; - goto out; - } - /* unacceptable, something is wrong, fail */ - algo_name = OBJ_nid2sn(mdnid); - failf(data, "Unable to find digest algorithm %s (NID %d) " - "for channel binding", algo_name ? algo_name : "(null)", mdnid); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - - if(!X509_digest(cert, algo_type, buf, &length)) { - failf(data, "X509_digest() failed for channel binding"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto out; - } - - /* Append "tls-server-end-point:" */ - result = curlx_dyn_addn(binding, prefix, sizeof(prefix) - 1); - if(result) - goto out; - - /* Append digest */ - result = curlx_dyn_addn(binding, buf, length); - -out: - X509_free(cert); - return result; -} - -size_t Curl_ossl_version(char *buffer, size_t size) -{ -#ifdef LIBRESSL_VERSION_NUMBER - char *p; - size_t count; - const char *ver = OpenSSL_version(OPENSSL_VERSION); - const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ - if(curl_strnequal(ver, expected, sizeof(expected) - 1)) { - ver += sizeof(expected) - 1; - } - count = curl_msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); - for(p = buffer; *p; ++p) { - if(ISBLANK(*p)) - *p = '_'; - } - return count; -#elif defined(OPENSSL_IS_BORINGSSL) -#ifdef CURL_BORINGSSL_VERSION - return curl_msnprintf(buffer, size, "%s/%s", - OSSL_PACKAGE, CURL_BORINGSSL_VERSION); -#else - return curl_msnprintf(buffer, size, OSSL_PACKAGE); -#endif -#elif defined(OPENSSL_IS_AWSLC) - return curl_msnprintf(buffer, size, "%s/%s", - OSSL_PACKAGE, AWSLC_VERSION_NUMBER_STRING); -#else /* OpenSSL 3+ */ - return curl_msnprintf(buffer, size, "%s/%s", - OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); -#endif -} - -/* can be called with data == NULL */ -static CURLcode ossl_random(struct Curl_easy *data, - unsigned char *entropy, size_t length) -{ - int rc; - if(data) { - if(ossl_seed(data)) /* Initiate the seed if not already done */ - return CURLE_FAILED_INIT; /* could not seed for some reason */ - } - else { - if(!rand_enough()) - return CURLE_FAILED_INIT; - } - /* RAND_bytes() returns 1 on success, 0 otherwise. */ - rc = RAND_bytes(entropy, (ossl_valsize_t)curlx_uztosi(length)); - return rc == 1 ? CURLE_OK : CURLE_FAILED_INIT; -} - -static CURLcode ossl_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum /* output */, - size_t unused) -{ - EVP_MD_CTX *mdctx; - unsigned int len = 0; - (void)unused; - - mdctx = EVP_MD_CTX_create(); - if(!mdctx) - return CURLE_OUT_OF_MEMORY; - if(!EVP_DigestInit(mdctx, EVP_sha256())) { - EVP_MD_CTX_destroy(mdctx); - return CURLE_FAILED_INIT; - } - EVP_DigestUpdate(mdctx, tmp, tmplen); - EVP_DigestFinal_ex(mdctx, sha256sum, &len); - EVP_MD_CTX_destroy(mdctx); - return CURLE_OK; -} - -static bool ossl_cert_status_request(void) -{ -#ifndef OPENSSL_NO_OCSP - return TRUE; -#else - return FALSE; -#endif -} - -static void *ossl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info) -{ - /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ - struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend; - DEBUGASSERT(octx); - return info == CURLINFO_TLS_SESSION ? - (void *)octx->ssl_ctx : (void *)octx->ssl; -} - -const struct Curl_ssl Curl_ssl_openssl = { - { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ - - SSLSUPP_CA_PATH | - SSLSUPP_CAINFO_BLOB | - SSLSUPP_CERTINFO | - SSLSUPP_PINNEDPUBKEY | - SSLSUPP_SSL_CTX | -#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES - SSLSUPP_TLS13_CIPHERSUITES | -#endif -#ifdef HAVE_SSL_CTX_SET1_SIGALGS - SSLSUPP_SIGNATURE_ALGORITHMS | -#endif -#ifdef HAVE_SSL_SET1_ECH_CONFIG_LIST - SSLSUPP_ECH | -#endif - SSLSUPP_CA_CACHE | - SSLSUPP_HTTPS_PROXY | - SSLSUPP_CIPHER_LIST | - SSLSUPP_ISSUERCERT | - SSLSUPP_ISSUERCERT_BLOB | - SSLSUPP_SSL_EC_CURVES | - SSLSUPP_CRLFILE, - - sizeof(struct ossl_ctx), - - ossl_init, /* init */ - ossl_cleanup, /* cleanup */ - Curl_ossl_version, /* version */ - ossl_shutdown, /* shutdown */ - ossl_data_pending, /* data_pending */ - ossl_random, /* random */ - ossl_cert_status_request, /* cert_status_request */ - ossl_connect, /* connect */ - Curl_ssl_adjust_pollset, /* adjust_pollset */ - ossl_get_internals, /* get_internals */ - ossl_close, /* close_one */ - ossl_close_all, /* close_all */ - ossl_set_engine, /* set_engine or provider */ - ossl_set_engine_default, /* set_engine_default */ - ossl_engines_list, /* engines_list */ - ossl_sha256sum, /* sha256sum */ - ossl_recv, /* recv decrypted data */ - ossl_send, /* send data to encrypt */ - ossl_get_channel_binding /* get_channel_binding */ -}; - -#endif /* USE_OPENSSL */ diff --git a/vendor/curl/lib/vtls/openssl.h b/vendor/curl/lib/vtls/openssl.h deleted file mode 100644 index 61d4a1757..000000000 --- a/vendor/curl/lib/vtls/openssl.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef HEADER_CURL_SSLUSE_H -#define HEADER_CURL_SSLUSE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_OPENSSL - -#ifdef USE_WIN32_CRYPTO -#include -/* If is included directly, or indirectly via , - * , , or something else, does this: - * #define X509_NAME ((LPCSTR)7) - * - * In BoringSSL/AWC-LC's there is: - * typedef struct X509_name_st X509_NAME; - * etc. - * - * The redefined symbols break these OpenSSL headers when included after - * . - * The workaround is to undefine those defines here (and only here). - * - * For unity builds it may need to be repeated elsewhere too, e.g. in ldap.c, - * to apply to other sources using OpenSSL includes. Each compilation unit - * needs undefine them between the first include and the first - * OpenSSL include. - * - * OpenSSL does this in and , but it - * also does the #undef by including . <3.1.0 only does - * it on the first include. - * - * LibreSSL automatically undefines these symbols before using them. - */ -#undef X509_NAME -#undef X509_EXTENSIONS -#undef PKCS7_ISSUER_AND_SERIAL -#undef PKCS7_SIGNER_INFO -#undef OCSP_REQUEST -#undef OCSP_RESPONSE -#endif /* USE_WIN32_CRYPTO */ - -/* - * This header should only be needed to get included by vtls.c, openssl.c - * and ngtcp2.c - */ -#include -#include -#include - -#include "urldata.h" - -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -#define HAVE_OPENSSL3 /* non-fork OpenSSL 3.x or later */ -#endif - -#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) -#define HAVE_BORINGSSL_LIKE -#endif - -/* OpenSSL 3.5.0+ has built-in 'SSLKEYLOGFILE' support if built with - 'enable-sslkeylog' */ -#if OPENSSL_VERSION_NUMBER >= 0x30500000L && !defined(OPENSSL_NO_SSLKEYLOG) -#define HAVE_KEYLOG_UPSTREAM -#endif - -/* - * Whether SSL_CTX_set_keylog_callback is available. - * OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287 - * BoringSSL: supported since d28f59c27bac (committed 2015-11-19) - * LibreSSL: not supported. 3.5.0+ has a stub function that does nothing. - */ -#ifndef LIBRESSL_VERSION_NUMBER -#define HAVE_KEYLOG_CALLBACK -#endif - -/* Check for OpenSSL 1.1.1 which has early data support. */ -#undef HAVE_OPENSSL_EARLYDATA -#if defined(TLS1_3_VERSION) && !defined(HAVE_BORINGSSL_LIKE) -#define HAVE_OPENSSL_EARLYDATA -#endif - -struct alpn_spec; -struct ssl_peer; -struct Curl_ssl_session; - -/* Struct to hold a curl OpenSSL instance */ -struct ossl_ctx { - /* these ones requires specific SSL-types */ - SSL_CTX* ssl_ctx; - SSL* ssl; - BIO_METHOD *bio_method; - CURLcode io_result; /* result of last BIO cfilter operation */ - /* blocked writes need to retry with same length, remember it */ - int blocked_ssl_write_len; -#if !defined(HAVE_KEYLOG_UPSTREAM) && !defined(HAVE_KEYLOG_CALLBACK) - /* Set to true once a valid keylog entry has been created to avoid dupes. - This is a bool and not a bitfield because it is passed by address. */ - bool keylog_done; -#endif - BIT(x509_store_setup); /* x509 store has been set up */ - BIT(store_is_empty); /* no certs/paths/blobs in x509 store */ - BIT(reused_session); /* session-ID was reused for this */ -}; - -size_t Curl_ossl_version(char *buffer, size_t size); - -typedef CURLcode Curl_ossl_ctx_setup_cb(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *user_data); - -typedef int Curl_ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid); -typedef CURLcode Curl_ossl_init_session_reuse_cb(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data); - -CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - Curl_ossl_ctx_setup_cb *cb_setup, - void *cb_user_data, - Curl_ossl_new_session_cb *cb_new_session, - void *ssl_user_data, - Curl_ossl_init_session_reuse_cb *sess_reuse_cb); - -/* Is a resolved HTTPS-RR needed for initializing OpenSSL? */ -bool Curl_ossl_need_httpsrr(struct Curl_easy *data); - -#ifndef HAVE_OPENSSL3 -#define SSL_get1_peer_certificate SSL_get_peer_certificate -#endif - -extern const struct Curl_ssl Curl_ssl_openssl; - -/** - * Setup the OpenSSL X509_STORE in `ssl_ctx` for the cfilter `cf` and - * easy handle `data`. Allows reuse of a shared cache if suitable - * and configured. - */ -CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx); - -CURLcode Curl_ossl_ctx_configure(struct Curl_cfilter *cf, - struct Curl_easy *data, - SSL_CTX *ssl_ctx); - -/* - * Add a new session to the cache. Takes ownership of the session. - */ -CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - SSL_SESSION *session, - int ietf_tls_id, - const char *alpn, - unsigned char *quic_tp, - size_t quic_tp_len); - -/* - * Get the server cert, verify it and show it, etc., only call failf() if - * ssl config verifypeer or -host is set. Otherwise all this is for - * informational purposes only! - */ -CURLcode Curl_ossl_check_peer_cert(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ossl_ctx *octx, - struct ssl_peer *peer); - -/* Report properties of a successful handshake */ -void Curl_ossl_report_handshake(struct Curl_easy *data, struct ossl_ctx *octx); - -#endif /* USE_OPENSSL */ -#endif /* HEADER_CURL_SSLUSE_H */ diff --git a/vendor/curl/lib/vtls/rustls.c b/vendor/curl/lib/vtls/rustls.c deleted file mode 100644 index d886c8505..000000000 --- a/vendor/curl/lib/vtls/rustls.c +++ /dev/null @@ -1,1453 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Jacob Hoffman-Andrews, - * Copyright (C) kpcyrd, - * Copyright (C) Daniel McCarney, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_RUSTLS - -#include - -#include "curlx/fopen.h" -#include "curlx/strerr.h" -#include "urldata.h" -#include "cf-dns.h" -#include "curl_trc.h" -#include "httpsrr.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" -#include "vtls/rustls.h" -#include "vtls/keylog.h" -#include "vtls/cipher_suite.h" -#include "vtls/x509asn1.h" -#ifdef USE_ECH -#include "curlx/base64.h" -#endif - -struct rustls_ssl_backend_data { - const struct rustls_client_config *config; - struct rustls_connection *conn; - size_t plain_out_buffered; - BIT(data_in_pending); - BIT(sent_shutdown); -}; - -/* For a given rustls_result error code, return the best-matching CURLcode. */ -static CURLcode map_error(const rustls_result r) -{ - if(rustls_result_is_cert_error(r)) { - return CURLE_PEER_FAILED_VERIFICATION; - } - switch(r) { - case RUSTLS_RESULT_OK: - return CURLE_OK; - case RUSTLS_RESULT_NULL_PARAMETER: - return CURLE_BAD_FUNCTION_ARGUMENT; - default: - return CURLE_RECV_ERROR; - } -} - -static void rustls_failf(struct Curl_easy *data, const rustls_result rr, - const char *msg) -{ - char errorbuf[STRERROR_LEN]; - size_t errorlen; - rustls_error(rr, errorbuf, sizeof(errorbuf), &errorlen); - failf(data, "%s: %.*s", msg, (int)errorlen, errorbuf); -} - -static bool cr_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - const struct ssl_connect_data *ctx = cf->ctx; - struct rustls_ssl_backend_data *backend; - - (void)data; - DEBUGASSERT(ctx && ctx->backend); - backend = (struct rustls_ssl_backend_data *)ctx->backend; - return (bool)backend->data_in_pending; -} - -struct io_ctx { - struct Curl_cfilter *cf; - struct Curl_easy *data; -}; - -static int read_cb(void *userdata, uint8_t *buf, uintptr_t len, - uintptr_t *out_n) -{ - const struct io_ctx *io_ctx = userdata; - struct ssl_connect_data * const connssl = io_ctx->cf->ctx; - CURLcode result; - int ret = 0; - size_t nread; - - result = Curl_conn_cf_recv(io_ctx->cf->next, io_ctx->data, - (char *)buf, len, &nread); - if(result) { - nread = 0; - /* !checksrc! disable ERRNOVAR 4 */ - if(result == CURLE_AGAIN) - ret = EAGAIN; - else - ret = EINVAL; - } - else if(nread == 0) - connssl->peer_closed = TRUE; - *out_n = (uintptr_t)nread; - CURL_TRC_CF(io_ctx->data, io_ctx->cf, "cf->next recv(len=%zu) -> %d, %zu", - (size_t)len, result, nread); - return ret; -} - -static int write_cb(void *userdata, const uint8_t *buf, uintptr_t len, - uintptr_t *out_n) -{ - const struct io_ctx *io_ctx = userdata; - CURLcode result; - int ret = 0; - size_t nwritten; - - result = Curl_conn_cf_send(io_ctx->cf->next, io_ctx->data, - buf, len, FALSE, &nwritten); - if(result) { - nwritten = 0; - if(result == CURLE_AGAIN) - ret = EAGAIN; - else - ret = EINVAL; - } - *out_n = (uintptr_t)nwritten; - CURL_TRC_CF(io_ctx->data, io_ctx->cf, "cf->next send(len=%zu) -> %d, %zu", - len, result, nwritten); - return ret; -} - -static ssize_t tls_recv_more(struct Curl_cfilter *cf, - struct Curl_easy *data, CURLcode *err) -{ - const struct ssl_connect_data * const connssl = cf->ctx; - struct rustls_ssl_backend_data * const backend = - (struct rustls_ssl_backend_data *)connssl->backend; - struct io_ctx io_ctx; - size_t tls_bytes_read = 0; - rustls_io_result io_error; - rustls_result rresult = 0; - - io_ctx.cf = cf; - io_ctx.data = data; - io_error = rustls_connection_read_tls(backend->conn, read_cb, &io_ctx, - &tls_bytes_read); - if(io_error == EAGAIN || io_error == EWOULDBLOCK) { - *err = CURLE_AGAIN; - return -1; - } - else if(io_error) { - char buffer[STRERROR_LEN]; - failf(data, "reading from socket: %s", - curlx_strerror(io_error, buffer, sizeof(buffer))); - *err = CURLE_RECV_ERROR; - return -1; - } - - rresult = rustls_connection_process_new_packets(backend->conn); - if(rresult != RUSTLS_RESULT_OK) { - rustls_failf(data, rresult, "rustls_connection_process_new_packets"); - *err = map_error(rresult); - return -1; - } - - backend->data_in_pending = TRUE; - *err = CURLE_OK; - return (ssize_t)tls_bytes_read; -} - -/* - * Filter receive method implementation. `plainbuf` and `plainlen` - * are always not NULL/0. - */ -static CURLcode cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *plainbuf, size_t plainlen, size_t *pnread) -{ - const struct ssl_connect_data * const connssl = cf->ctx; - struct rustls_ssl_backend_data * const backend = - (struct rustls_ssl_backend_data *)connssl->backend; - struct rustls_connection *rconn = NULL; - CURLcode result = CURLE_OK; - size_t n = 0; - rustls_result rresult = 0; - bool eof = FALSE; - - DEBUGASSERT(backend); - *pnread = 0; - rconn = backend->conn; - - while(*pnread < plainlen) { - if(!backend->data_in_pending) { - if(tls_recv_more(cf, data, &result) < 0) { - if(result != CURLE_AGAIN) { - goto out; - } - result = CURLE_OK; - break; - } - } - - rresult = rustls_connection_read(rconn, - (uint8_t *)plainbuf + *pnread, - plainlen - *pnread, - &n); - if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) { - backend->data_in_pending = FALSE; - } - else if(rresult == RUSTLS_RESULT_UNEXPECTED_EOF) { - failf(data, "rustls: peer closed TCP connection " - "without first closing TLS connection"); - result = CURLE_RECV_ERROR; - goto out; - } - else if(rresult != RUSTLS_RESULT_OK) { - /* n always equals 0 in this case, do not need to check it */ - rustls_failf(data, rresult, "rustls_connection_read"); - result = CURLE_RECV_ERROR; - goto out; - } - else if(n == 0) { - /* n == 0 indicates clean EOF, but we may have read some other - plaintext bytes before we reached this. Break out of the loop - so we can figure out whether to return success or EOF. */ - eof = TRUE; - break; - } - else { - *pnread += n; - } - } - - if(!eof && !*pnread) { - result = CURLE_AGAIN; - } - -out: - CURL_TRC_CF(data, cf, "rustls_recv(len=%zu) -> %d, %zu", - plainlen, result, *pnread); - return result; -} - -static CURLcode cr_flush_out(struct Curl_cfilter *cf, struct Curl_easy *data, - struct rustls_connection *rconn) -{ - struct io_ctx io_ctx; - rustls_io_result io_error; - size_t tlswritten = 0; - size_t tlswritten_total = 0; - - io_ctx.cf = cf; - io_ctx.data = data; - - while(rustls_connection_wants_write(rconn)) { - io_error = rustls_connection_write_tls(rconn, write_cb, &io_ctx, - &tlswritten); - if(io_error == EAGAIN || io_error == EWOULDBLOCK) { - CURL_TRC_CF(data, cf, "cf_send: EAGAIN after %zu bytes", - tlswritten_total); - return CURLE_AGAIN; - } - else if(io_error) { - char buffer[STRERROR_LEN]; - failf(data, "writing to socket: %s", - curlx_strerror(io_error, buffer, sizeof(buffer))); - return CURLE_SEND_ERROR; - } - if(tlswritten == 0) { - failf(data, "EOF in swrite"); - return CURLE_SEND_ERROR; - } - CURL_TRC_CF(data, cf, "cf_send: wrote %zu TLS bytes", tlswritten); - tlswritten_total += tlswritten; - } - return CURLE_OK; -} - -/* - * On each call: - * - Copy `plainlen` bytes into Rustls' plaintext input buffer (if > 0). - * - Fully drain Rustls' plaintext output buffer into the socket until - * we get either an error or EAGAIN/EWOULDBLOCK. - * - * it is okay to call this function with plainbuf == NULL and plainlen == 0. - * In that case, it does not read anything into Rustls' plaintext input buffer. - * It only drains Rustls' plaintext output buffer into the socket. - */ -static CURLcode cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *plainbuf, size_t plainlen, - size_t *pnwritten) -{ - const struct ssl_connect_data * const connssl = cf->ctx; - struct rustls_ssl_backend_data * const backend = - (struct rustls_ssl_backend_data *)connssl->backend; - struct rustls_connection *rconn = NULL; - size_t plainwritten = 0; - const unsigned char *buf = plainbuf; - CURLcode result = CURLE_OK; - size_t blen = plainlen; - - DEBUGASSERT(backend); - *pnwritten = 0; - rconn = backend->conn; - DEBUGASSERT(rconn); - - CURL_TRC_CF(data, cf, "cf_send(len=%zu)", plainlen); - - /* If a previous send blocked, we already added its plain bytes - * to rustsls and must not do that again. Flush the TLS bytes and, - * if successful, deduct the previous plain bytes from the current - * send. */ - if(backend->plain_out_buffered) { - result = cr_flush_out(cf, data, rconn); - CURL_TRC_CF(data, cf, "cf_send: flushing %zu previously added bytes -> %d", - backend->plain_out_buffered, result); - if(result) - return result; - if(blen > backend->plain_out_buffered) { - blen -= backend->plain_out_buffered; - buf += backend->plain_out_buffered; - } - else - blen = 0; - *pnwritten += (ssize_t)backend->plain_out_buffered; - backend->plain_out_buffered = 0; - } - - if(blen > 0) { - rustls_result rresult; - CURL_TRC_CF(data, cf, "cf_send: adding %zu plain bytes to Rustls", blen); - rresult = rustls_connection_write(rconn, buf, blen, &plainwritten); - if(rresult != RUSTLS_RESULT_OK) { - rustls_failf(data, rresult, "rustls_connection_write"); - result = CURLE_WRITE_ERROR; - goto out; - } - else if(plainwritten == 0) { - failf(data, "rustls_connection_write: EOF"); - result = CURLE_WRITE_ERROR; - goto out; - } - } - - result = cr_flush_out(cf, data, rconn); - if(result) { - if(result == CURLE_AGAIN) { - /* The TLS bytes may have been partially written, but we fail the - * complete send() and remember how much we already added to Rustls. */ - backend->plain_out_buffered = plainwritten; - if(*pnwritten) { - result = CURLE_OK; - } - } - goto out; - } - else - *pnwritten += (ssize_t)plainwritten; - -out: - CURL_TRC_CF(data, cf, "rustls_send(len=%zu) -> %d, %zu", - plainlen, result, *pnwritten); - return result; -} - -/* A server certificate verify callback for Rustls that always returns - RUSTLS_RESULT_OK, or in other words disable certificate verification. */ -static uint32_t cr_verify_none(void *userdata, - const rustls_verify_server_cert_params *params) -{ - (void)userdata; - (void)params; - return RUSTLS_RESULT_OK; -} - -static int read_file_into(const char *filename, struct dynbuf *out) -{ - FILE *f = curlx_fopen(filename, FOPEN_READTEXT); - if(!f) { - return 0; - } - - for(;;) { - uint8_t buf[256]; - const size_t rr = fread(buf, 1, sizeof(buf), f); - if((!rr && !feof(f)) || - curlx_dyn_addn(out, buf, rr)) { - curlx_fclose(f); - return 0; - } - if(rr < sizeof(buf)) - break; - } - - return curlx_fclose(f) == 0; -} - -static void -cr_get_selected_ciphers(struct Curl_easy *data, - const char *ciphers12, - const char *ciphers13, - const struct rustls_supported_ciphersuite **selected, - size_t *selected_size) -{ - const size_t supported_len = *selected_size; - const size_t default_len = rustls_default_crypto_provider_ciphersuites_len(); - const struct rustls_supported_ciphersuite *entry = NULL; - const char *ciphers = ciphers12; - size_t count = 0, default13_count = 0, i, j; - const char *ptr, *end; - - DEBUGASSERT(default_len <= supported_len); - - if(!ciphers13) { - /* Add default TLSv1.3 ciphers to selection */ - for(j = 0; j < default_len; j++) { - entry = rustls_default_crypto_provider_ciphersuites_get(j); - if(rustls_supported_ciphersuite_protocol_version(entry) != - RUSTLS_TLS_VERSION_TLSV1_3) - continue; - - selected[count++] = entry; - } - - default13_count = count; - - if(!ciphers) - ciphers = ""; - } - else - ciphers = ciphers13; - -add_ciphers: - for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) { - uint16_t id = Curl_cipher_suite_walk_str(&ptr, &end); - - /* Check if cipher is supported */ - if(id) { - for(i = 0; i < supported_len; i++) { - entry = rustls_default_crypto_provider_ciphersuites_get(i); - if(rustls_supported_ciphersuite_get_suite(entry) == id) - break; - } - if(i == supported_len) - id = 0; - } - if(!id) { - if(ptr[0] != '\0') - infof(data, "rustls: unknown cipher in list: \"%.*s\"", - (int)(end - ptr), ptr); - continue; - } - - /* No duplicates allowed (so selected cannot overflow) */ - for(i = 0; i < count && selected[i] != entry; i++) - ; - if(i < count) { - if(i >= default13_count) - infof(data, "rustls: duplicate cipher in list: \"%.*s\"", - (int)(end - ptr), ptr); - continue; - } - - selected[count++] = entry; - } - - if(ciphers == ciphers13 && ciphers12) { - ciphers = ciphers12; - goto add_ciphers; - } - - if(!ciphers12) { - /* Add default TLSv1.2 ciphers to selection */ - for(j = 0; j < default_len; j++) { - entry = rustls_default_crypto_provider_ciphersuites_get(j); - if(rustls_supported_ciphersuite_protocol_version(entry) == - RUSTLS_TLS_VERSION_TLSV1_3) - continue; - - /* No duplicates allowed (so selected cannot overflow) */ - for(i = 0; i < count && selected[i] != entry; i++) - ; - if(i < count) - continue; - - selected[count++] = entry; - } - } - - *selected_size = count; -} - -static void cr_keylog_log_cb(struct rustls_str label, - const uint8_t *client_random, - size_t client_random_len, const uint8_t *secret, - size_t secret_len) -{ - char clabel[KEYLOG_LABEL_MAXLEN]; - (void)client_random_len; - DEBUGASSERT(client_random_len == CLIENT_RANDOM_SIZE); - /* Turning a "rustls_str" into a null delimited "c" string */ - curl_msnprintf(clabel, sizeof(clabel), "%.*s", (int)label.len, label.data); - Curl_tls_keylog_write(clabel, client_random, secret, secret_len); -} - -static CURLcode -init_config_builder(struct Curl_easy *data, - const struct ssl_primary_config *conn_config, - struct rustls_client_config_builder **config_builder) -{ - const struct rustls_supported_ciphersuite **cipher_suites = NULL; - struct rustls_crypto_provider_builder *custom_provider_builder = NULL; - const struct rustls_crypto_provider *custom_provider = NULL; - - uint16_t tls_versions[2] = { - RUSTLS_TLS_VERSION_TLSV1_2, - RUSTLS_TLS_VERSION_TLSV1_3, - }; - size_t tls_versions_len = 2; - size_t cipher_suites_len = rustls_default_crypto_provider_ciphersuites_len(); - - CURLcode result = CURLE_OK; - rustls_result rr; - - DEBUGASSERT(conn_config->version != CURL_SSLVERSION_DEFAULT); - switch(conn_config->version) { - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - break; - case CURL_SSLVERSION_TLSv1_3: - tls_versions[0] = RUSTLS_TLS_VERSION_TLSV1_3; - tls_versions_len = 1; - break; - default: - failf(data, "rustls: unsupported minimum TLS version value"); - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto cleanup; - } - - switch(conn_config->version_max) { - case CURL_SSLVERSION_MAX_DEFAULT: - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_TLSv1_3: - break; - case CURL_SSLVERSION_MAX_TLSv1_2: - if(tls_versions[0] == RUSTLS_TLS_VERSION_TLSV1_2) { - tls_versions_len = 1; - break; - } - FALLTHROUGH(); - case CURL_SSLVERSION_MAX_TLSv1_1: - case CURL_SSLVERSION_MAX_TLSv1_0: - default: - failf(data, "rustls: unsupported maximum TLS version value"); - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto cleanup; - } - -#ifdef USE_ECH - if(CURLECH_ENABLED(data)) { - tls_versions[0] = RUSTLS_TLS_VERSION_TLSV1_3; - tls_versions_len = 1; - infof(data, "rustls: ECH enabled, forcing TLSv1.3"); - } -#endif /* USE_ECH */ - - cipher_suites = curlx_malloc(sizeof(*cipher_suites) * cipher_suites_len); - if(!cipher_suites) { - result = CURLE_OUT_OF_MEMORY; - goto cleanup; - } - - cr_get_selected_ciphers(data, - conn_config->cipher_list, - conn_config->cipher_list13, - cipher_suites, &cipher_suites_len); - if(cipher_suites_len == 0) { - failf(data, "rustls: no supported cipher in list"); - result = CURLE_SSL_CIPHER; - goto cleanup; - } - - rr = rustls_crypto_provider_builder_new_from_default( - &custom_provider_builder); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, - "failed to create crypto provider builder from default"); - result = CURLE_SSL_CIPHER; - goto cleanup; - } - - rr = - rustls_crypto_provider_builder_set_cipher_suites( - custom_provider_builder, - cipher_suites, - cipher_suites_len); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, - "failed to set ciphersuites for crypto provider builder"); - result = CURLE_SSL_CIPHER; - goto cleanup; - } - - rr = rustls_crypto_provider_builder_build(custom_provider_builder, - &custom_provider); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to build custom crypto provider"); - result = CURLE_SSL_CIPHER; - goto cleanup; - } - - rr = rustls_client_config_builder_new_custom(custom_provider, - tls_versions, - tls_versions_len, - config_builder); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to create client config builder"); - result = CURLE_SSL_CIPHER; - goto cleanup; - } - -cleanup: - if(cipher_suites) { - curlx_free(cipher_suites); - } - if(custom_provider_builder) { - rustls_crypto_provider_builder_free(custom_provider_builder); - } - if(custom_provider) { - rustls_crypto_provider_free(custom_provider); - } - return result; -} - -static void -init_config_builder_alpn(struct Curl_easy *data, - const struct ssl_connect_data *connssl, - struct rustls_client_config_builder *config_builder) -{ - struct alpn_proto_buf proto; - rustls_slice_bytes alpn[ALPN_ENTRIES_MAX]; - size_t i; - - for(i = 0; i < connssl->alpn->count; ++i) { - alpn[i].data = (const uint8_t *)connssl->alpn->entries[i]; - alpn[i].len = strlen(connssl->alpn->entries[i]); - } - rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, - connssl->alpn->count); - Curl_alpn_to_proto_str(&proto, connssl->alpn); - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); -} - -static CURLcode init_config_builder_verifier_crl( - struct Curl_easy *data, - const struct ssl_primary_config *conn_config, - struct rustls_web_pki_server_cert_verifier_builder *builder) -{ - CURLcode result = CURLE_OK; - struct dynbuf crl_contents; - rustls_result rr; - - curlx_dyn_init(&crl_contents, DYN_CRLFILE_SIZE); - if(!read_file_into(conn_config->CRLfile, &crl_contents)) { - failf(data, "rustls: failed to read revocation list file"); - result = CURLE_SSL_CRL_BADFILE; - goto cleanup; - } - - rr = rustls_web_pki_server_cert_verifier_builder_add_crl( - builder, - curlx_dyn_uptr(&crl_contents), - curlx_dyn_len(&crl_contents)); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to parse revocation list"); - result = CURLE_SSL_CRL_BADFILE; - goto cleanup; - } - -cleanup: - curlx_dyn_free(&crl_contents); - return result; -} - -static CURLcode -init_config_builder_verifier(struct Curl_easy *data, - struct rustls_client_config_builder *builder, - const struct ssl_primary_config *conn_config, - const struct curl_blob *ca_info_blob, - const char * const ssl_cafile) -{ - const struct rustls_root_cert_store *roots = NULL; - struct rustls_root_cert_store_builder *roots_builder = NULL; - struct rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL; - struct rustls_server_cert_verifier *server_cert_verifier = NULL; - rustls_result rr = RUSTLS_RESULT_OK; - CURLcode result = CURLE_OK; - - roots_builder = rustls_root_cert_store_builder_new(); - if(ca_info_blob) { - rr = rustls_root_cert_store_builder_add_pem(roots_builder, - ca_info_blob->data, - ca_info_blob->len, - 1); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to parse trusted certificates from blob"); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - } - else if(ssl_cafile) { - rr = rustls_root_cert_store_builder_load_roots_from_file(roots_builder, - ssl_cafile, - 1); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to load trusted certificates"); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - } - - rr = rustls_root_cert_store_builder_build(roots_builder, &roots); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to build trusted root certificate store"); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - - verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(roots); - if(!verifier_builder) { - result = CURLE_OUT_OF_MEMORY; - goto cleanup; - } - - if(conn_config->CRLfile) { - result = init_config_builder_verifier_crl(data, - conn_config, - verifier_builder); - if(result) { - goto cleanup; - } - } - - rr = rustls_web_pki_server_cert_verifier_builder_build( - verifier_builder, &server_cert_verifier); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to build certificate verifier"); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - - rustls_client_config_builder_set_server_verifier(builder, - server_cert_verifier); -cleanup: - if(roots_builder) { - rustls_root_cert_store_builder_free(roots_builder); - } - if(roots) { - rustls_root_cert_store_free(roots); - } - if(verifier_builder) { - rustls_web_pki_server_cert_verifier_builder_free(verifier_builder); - } - if(server_cert_verifier) { - rustls_server_cert_verifier_free(server_cert_verifier); - } - - return result; -} - -static CURLcode init_config_builder_platform_verifier( - struct Curl_easy *data, - struct rustls_client_config_builder *builder) -{ - struct rustls_server_cert_verifier *server_cert_verifier = NULL; - CURLcode result = CURLE_OK; - rustls_result rr; - - rr = rustls_platform_server_cert_verifier(&server_cert_verifier); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to create platform certificate verifier"); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - - rustls_client_config_builder_set_server_verifier(builder, - server_cert_verifier); - -cleanup: - if(server_cert_verifier) { - rustls_server_cert_verifier_free(server_cert_verifier); - } - return result; -} - -static CURLcode -init_config_builder_keylog(struct Curl_easy *data, - struct rustls_client_config_builder *builder) -{ - rustls_result rr; - - Curl_tls_keylog_open(); - if(!Curl_tls_keylog_enabled()) { - return CURLE_OK; - } - - rr = rustls_client_config_builder_set_key_log(builder, - cr_keylog_log_cb, - NULL); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "rustls_client_config_builder_set_key_log"); - Curl_tls_keylog_close(); - return map_error(rr); - } - - return CURLE_OK; -} - -static CURLcode -init_config_builder_client_auth(struct Curl_easy *data, - const struct ssl_primary_config *conn_config, - const struct ssl_config_data *ssl_config, - struct rustls_client_config_builder *builder) -{ - struct dynbuf cert_contents; - struct dynbuf key_contents; - rustls_result rr; - const struct rustls_certified_key *certified_key = NULL; - CURLcode result = CURLE_OK; - - if(conn_config->clientcert && !ssl_config->key) { - failf(data, "rustls: must provide key with certificate '%s'", - conn_config->clientcert); - return CURLE_SSL_CERTPROBLEM; - } - else if(!conn_config->clientcert && ssl_config->key) { - failf(data, "rustls: must provide certificate with key '%s'", - ssl_config->key); - return CURLE_SSL_CERTPROBLEM; - } - - curlx_dyn_init(&cert_contents, DYN_CERTFILE_SIZE); - curlx_dyn_init(&key_contents, DYN_KEYFILE_SIZE); - - if(!read_file_into(conn_config->clientcert, &cert_contents)) { - failf(data, "rustls: failed to read client certificate file: '%s'", - conn_config->clientcert); - result = CURLE_SSL_CERTPROBLEM; - goto cleanup; - } - - if(!read_file_into(ssl_config->key, &key_contents)) { - failf(data, "rustls: failed to read key file: '%s'", ssl_config->key); - result = CURLE_SSL_CERTPROBLEM; - goto cleanup; - } - - rr = rustls_certified_key_build(curlx_dyn_uptr(&cert_contents), - curlx_dyn_len(&cert_contents), - curlx_dyn_uptr(&key_contents), - curlx_dyn_len(&key_contents), - &certified_key); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "rustls: failed to build certified key"); - result = CURLE_SSL_CERTPROBLEM; - goto cleanup; - } - - rr = rustls_certified_key_keys_match(certified_key); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, - "rustls: client certificate and keypair files do not match:"); - result = CURLE_SSL_CERTPROBLEM; - goto cleanup; - } - - rr = rustls_client_config_builder_set_certified_key(builder, - &certified_key, - 1); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "rustls: failed to set certified key"); - result = CURLE_SSL_CERTPROBLEM; - goto cleanup; - } - -cleanup: - curlx_dyn_free(&cert_contents); - curlx_dyn_free(&key_contents); - if(certified_key) { - rustls_certified_key_free(certified_key); - } - return result; -} - -#ifdef USE_ECH - -static bool cr_ech_need_httpsrr(struct Curl_easy *data) -{ - if(!CURLECH_ENABLED(data)) - return FALSE; - if((data->set.tls_ech & CURLECH_GREASE) || - (data->set.tls_ech & CURLECH_CLA_CFG)) - return FALSE; - return TRUE; -} - -static CURLcode -init_config_builder_ech(struct Curl_easy *data, - struct Curl_cfilter *cf, - struct rustls_client_config_builder *builder) -{ - const rustls_hpke *hpke = rustls_supported_hpke(); - unsigned char *ech_config = NULL; - size_t ech_config_len = 0; - struct Curl_dns_entry *dns = NULL; - CURLcode result = CURLE_OK; - rustls_result rr; - - if(!hpke) { - failf(data, - "rustls: ECH unavailable, rustls-ffi built without " - "HPKE compatible crypto provider"); - result = CURLE_SSL_CONNECT_ERROR; - goto cleanup; - } - - if(data->set.str[STRING_ECH_PUBLIC]) { - failf(data, "rustls: ECH outername not supported"); - result = CURLE_SSL_CONNECT_ERROR; - goto cleanup; - } - - if(data->set.tls_ech == CURLECH_GREASE) { - rr = rustls_client_config_builder_enable_ech_grease(builder, hpke); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "rustls: failed to configure ECH GREASE"); - result = CURLE_SSL_CONNECT_ERROR; - goto cleanup; - } - return CURLE_OK; - } - - if(data->set.tls_ech & CURLECH_CLA_CFG && data->set.str[STRING_ECH_CONFIG]) { - const char *b64 = data->set.str[STRING_ECH_CONFIG]; - size_t decode_result; - if(!b64) { - infof(data, "rustls: ECHConfig from command line empty"); - result = CURLE_SSL_CONNECT_ERROR; - goto cleanup; - } - /* rustls-ffi expects the raw TLS encoded ECHConfigList bytes */ - decode_result = curlx_base64_decode(b64, &ech_config, &ech_config_len); - if(decode_result || !ech_config) { - infof(data, "rustls: cannot base64 decode ECHConfig from command line"); - result = CURLE_SSL_CONNECT_ERROR; - goto cleanup; - } - } - else { - const struct Curl_https_rrinfo *rinfo = - Curl_conn_dns_get_https(data, cf->sockindex); - - if(!rinfo || !rinfo->echconfiglist) { - failf(data, "rustls: ECH requested but no ECHConfig available"); - result = CURLE_SSL_CONNECT_ERROR; - goto cleanup; - } - ech_config = rinfo->echconfiglist; - ech_config_len = rinfo->echconfiglist_len; - } - - rr = rustls_client_config_builder_enable_ech(builder, - ech_config, - ech_config_len, - hpke); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "rustls: failed to configure ECH"); - result = CURLE_SSL_CONNECT_ERROR; - goto cleanup; - } -cleanup: - /* if we base64 decoded, we can free now */ - if(data->set.tls_ech & CURLECH_CLA_CFG && data->set.str[STRING_ECH_CONFIG]) { - curlx_free(ech_config); - } - if(dns) { - Curl_dns_entry_unlink(data, &dns); - } - return result; -} -#endif /* USE_ECH */ - -static CURLcode cr_init_backend(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct rustls_ssl_backend_data * const backend) -{ - const struct ssl_connect_data *connssl = cf->ctx; - const struct ssl_primary_config *conn_config = - Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - struct rustls_connection *rconn = NULL; - struct rustls_client_config_builder *config_builder = NULL; - - const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; - const char * const ssl_cafile = - /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - (ca_info_blob ? NULL : conn_config->CAfile); - CURLcode result = CURLE_OK; - rustls_result rr; - - DEBUGASSERT(backend); - rconn = backend->conn; - - result = init_config_builder(data, conn_config, &config_builder); - if(result != CURLE_OK) { - return result; - } - - if(connssl->alpn) { - init_config_builder_alpn(data, connssl, config_builder); - } - - if(!conn_config->verifypeer) { - rustls_client_config_builder_dangerous_set_certificate_verifier( - config_builder, cr_verify_none); - } - else if(ssl_config->native_ca_store) { - result = init_config_builder_platform_verifier(data, config_builder); - if(result != CURLE_OK) { - rustls_client_config_builder_free(config_builder); - return result; - } - } - else if(ca_info_blob || ssl_cafile) { - result = init_config_builder_verifier(data, - config_builder, - conn_config, - ca_info_blob, - ssl_cafile); - if(result != CURLE_OK) { - rustls_client_config_builder_free(config_builder); - return result; - } - } - - if(conn_config->clientcert || ssl_config->key) { - result = init_config_builder_client_auth(data, - conn_config, - ssl_config, - config_builder); - if(result != CURLE_OK) { - rustls_client_config_builder_free(config_builder); - return result; - } - } - -#ifdef USE_ECH - if(CURLECH_ENABLED(data)) { - result = init_config_builder_ech(data, cf, config_builder); - if(result != CURLE_OK && data->set.tls_ech & CURLECH_HARD) { - rustls_client_config_builder_free(config_builder); - return result; - } - } -#endif /* USE_ECH */ - - result = init_config_builder_keylog(data, config_builder); - if(result != CURLE_OK) { - rustls_client_config_builder_free(config_builder); - return result; - } - - rr = rustls_client_config_builder_build(config_builder, &backend->config); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "failed to build client config"); - return CURLE_SSL_CONNECT_ERROR; - } - - DEBUGASSERT(rconn == NULL); - rr = rustls_client_connection_new(backend->config, - connssl->peer.hostname, - &rconn); - if(rr != RUSTLS_RESULT_OK) { - rustls_failf(data, rr, "rustls_client_connection_new"); - rustls_client_config_free(backend->config); - backend->config = NULL; - return CURLE_COULDNT_CONNECT; - } - DEBUGASSERT(rconn); - rustls_connection_set_userdata(rconn, backend); - backend->conn = rconn; - - return result; -} - -static void cr_set_negotiated_alpn(struct Curl_cfilter *cf, - struct Curl_easy *data, - const struct rustls_connection *rconn) -{ - struct ssl_connect_data * const connssl = cf->ctx; - const uint8_t *protocol = NULL; - size_t len = 0; - - rustls_connection_get_alpn_protocol(rconn, &protocol, &len); - Curl_alpn_set_negotiated(cf, data, connssl, protocol, len); -} - -/* Given an established network connection, do a TLS handshake. - * - * This function sets `*done` to true once the handshake is complete. - * This function never reads the value of `*done*`. - */ -static CURLcode cr_connect(struct Curl_cfilter *cf, struct Curl_easy *data, - bool *done) -{ - struct ssl_connect_data * const connssl = cf->ctx; - const struct rustls_ssl_backend_data * const backend = - (struct rustls_ssl_backend_data *)connssl->backend; - const struct rustls_connection *rconn = NULL; - CURLcode tmperr = CURLE_OK; - CURLcode result; - bool wants_read; - bool wants_write; - ssize_t nread; - - DEBUGASSERT(backend); - - CURL_TRC_CF(data, cf, "cr_connect, state=%d", connssl->state); - *done = FALSE; - -#ifdef USE_ECH - /* if we do ECH and need the HTTPS-RR information for it, - * we delay the connect until it arrives or DNS resolve fails. */ - if(cr_ech_need_httpsrr(data) && - !Curl_conn_dns_resolved_https(data, cf->sockindex)) { - CURL_TRC_CF(data, cf, "need HTTPS-RR for ECH, delaying connect"); - return CURLE_OK; - } -#endif /* USE_ECH */ - - if(!backend->conn) { - result = - cr_init_backend(cf, data, - (struct rustls_ssl_backend_data *)connssl->backend); - CURL_TRC_CF(data, cf, "cr_connect, init backend -> %d", result); - if(result) - return result; - connssl->state = ssl_connection_negotiating; - } - rconn = backend->conn; - - /* Read/write data until the handshake is done or the socket would block. */ - for(;;) { - /* - * Connection has been established according to Rustls. Set send/recv - * handlers, and update the state machine. - */ - connssl->io_need = CURL_SSL_IO_NEED_NONE; - if(!rustls_connection_is_handshaking(rconn)) { - /* Rustls claims it is no longer handshaking *before* it has - * send its FINISHED message off. We attempt to let it write - * one more time. Oh my. - */ - size_t nwritten; - cr_set_negotiated_alpn(cf, data, rconn); - tmperr = cr_send(cf, data, NULL, 0, &nwritten); - if(tmperr == CURLE_AGAIN) { - connssl->io_need = CURL_SSL_IO_NEED_SEND; - return CURLE_OK; - } - else if(tmperr != CURLE_OK) { - return tmperr; - } - /* REALLY Done with the handshake. */ - { -#ifdef CURLVERBOSE - const uint16_t proto = rustls_connection_get_protocol_version(rconn); - const rustls_str ciphersuite_name = - rustls_connection_get_negotiated_ciphersuite_name(rconn); - const rustls_str kex_group_name = - rustls_connection_get_negotiated_key_exchange_group_name(rconn); - const char *ver = "TLS version unknown"; - if(proto == RUSTLS_TLS_VERSION_TLSV1_3) - ver = "TLSv1.3"; - if(proto == RUSTLS_TLS_VERSION_TLSV1_2) - ver = "TLSv1.2"; -#endif - infof(data, - "rustls: handshake complete, %s, ciphersuite: %.*s, " - "key exchange group: %.*s", - ver, - (int) ciphersuite_name.len, - ciphersuite_name.data, - (int) kex_group_name.len, - kex_group_name.data); - } - if(data->set.ssl.certinfo) { - size_t num_certs = 0; - size_t i; - while(rustls_connection_get_peer_certificate(rconn, num_certs)) { - num_certs++; - if(num_certs > MAX_ALLOWED_CERT_AMOUNT) { - failf(data, "%zu certificates is more than allowed (%d)", - num_certs, MAX_ALLOWED_CERT_AMOUNT); - return CURLE_SSL_CONNECT_ERROR; - } - } - result = Curl_ssl_init_certinfo(data, (int)num_certs); - if(result) - return result; - for(i = 0; i < num_certs; i++) { - const rustls_certificate *cert; - const unsigned char *der_data; - size_t der_len; - rustls_result rresult = RUSTLS_RESULT_OK; - cert = rustls_connection_get_peer_certificate(rconn, i); - DEBUGASSERT(cert); /* Should exist since we counted already */ - rresult = rustls_certificate_get_der(cert, &der_data, &der_len); - if(rresult != RUSTLS_RESULT_OK) { - char errorbuf[255]; - size_t errorlen; - rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen); - failf(data, - "Failed getting DER of server certificate #%zu: %.*s", i, - (int)errorlen, errorbuf); - return map_error(rresult); - } - { - const char *beg; - const char *end; - beg = (const char *)der_data; - end = (const char *)(der_data + der_len); - result = Curl_extract_certinfo(data, (int)i, beg, end); - if(result) - return result; - } - } - } - - connssl->state = ssl_connection_complete; - *done = TRUE; - return CURLE_OK; - } - - connssl->connecting_state = ssl_connect_2; - wants_read = rustls_connection_wants_read(rconn); - wants_write = rustls_connection_wants_write(rconn) || - backend->plain_out_buffered; - DEBUGASSERT(wants_read || wants_write); - - if(wants_write) { - size_t nwritten; - CURL_TRC_CF(data, cf, "rustls_connection wants us to write_tls."); - tmperr = cr_send(cf, data, NULL, 0, &nwritten); - if(tmperr == CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "writing would block"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - return CURLE_OK; - } - else if(tmperr != CURLE_OK) { - return tmperr; - } - } - - if(wants_read) { - CURL_TRC_CF(data, cf, "rustls_connection wants us to read_tls."); - nread = tls_recv_more(cf, data, &tmperr); - if(nread == 0) { - connssl->peer_closed = TRUE; - failf(data, "TLS connect error: Connection closed abruptly"); - return CURLE_SSL_CONNECT_ERROR; - } - if(nread < 0) { - if(tmperr == CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "reading would block"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; - return CURLE_OK; - } - else if(tmperr == CURLE_RECV_ERROR) { - return CURLE_SSL_CONNECT_ERROR; - } - else { - return tmperr; - } - } - } - } - - /* We should never fall through the loop. We should return either because - the handshake is done or because we cannot read/write without blocking. */ - DEBUGASSERT(FALSE); -} - -static void *cr_get_internals(struct ssl_connect_data *connssl, CURLINFO info) -{ - struct rustls_ssl_backend_data *backend = - (struct rustls_ssl_backend_data *)connssl->backend; - (void)info; - DEBUGASSERT(backend); - return backend->conn; -} - -static CURLcode cr_shutdown(struct Curl_cfilter *cf, struct Curl_easy *data, - const bool send_shutdown, bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct rustls_ssl_backend_data *backend = - (struct rustls_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - size_t i, nread = 0, nwritten; - - DEBUGASSERT(backend); - if(!backend->conn || cf->shutdown) { - *done = TRUE; - goto out; - } - - connssl->io_need = CURL_SSL_IO_NEED_NONE; - *done = FALSE; - - if(!backend->sent_shutdown) { - /* do this only once */ - backend->sent_shutdown = TRUE; - if(send_shutdown) { - rustls_connection_send_close_notify(backend->conn); - } - } - - result = cr_send(cf, data, NULL, 0, &nwritten); - if(result) { - if(result == CURLE_AGAIN) { - connssl->io_need = CURL_SSL_IO_NEED_SEND; - result = CURLE_OK; - goto out; - } - DEBUGASSERT(result); - CURL_TRC_CF(data, cf, "shutdown send failed: %d", result); - goto out; - } - - for(i = 0; i < 10; ++i) { - char buf[1024]; - result = cr_recv(cf, data, buf, (int)sizeof(buf), &nread); - if(result) - break; - } - - if(result == CURLE_AGAIN) { - connssl->io_need = CURL_SSL_IO_NEED_RECV; - result = CURLE_OK; - } - else if(result) { - DEBUGASSERT(result); - CURL_TRC_CF(data, cf, "shutdown, error: %d", result); - } - else if(nread == 0) { - /* We got the close notify alert and are done. */ - *done = TRUE; - } - -out: - cf->shutdown = (result || *done); - return result; -} - -static void cr_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - const struct ssl_connect_data *connssl = cf->ctx; - struct rustls_ssl_backend_data *backend = - (struct rustls_ssl_backend_data *)connssl->backend; - - (void)data; - DEBUGASSERT(backend); - if(backend->conn) { - rustls_connection_free(backend->conn); - backend->conn = NULL; - } - if(backend->config) { - rustls_client_config_free(backend->config); - backend->config = NULL; - } -} - -static size_t cr_version(char *buffer, size_t size) -{ - const struct rustls_str ver = rustls_version(); - return curl_msnprintf(buffer, size, "%.*s", (int)ver.len, ver.data); -} - -static CURLcode cr_random(struct Curl_easy *data, unsigned char *entropy, - size_t length) -{ - rustls_result rresult = 0; - (void)data; - rresult = rustls_default_crypto_provider_random(entropy, length); - return map_error(rresult); -} - -static void cr_cleanup(void) -{ - Curl_tls_keylog_close(); -} - -const struct Curl_ssl Curl_ssl_rustls = { - { CURLSSLBACKEND_RUSTLS, "rustls" }, - SSLSUPP_CAINFO_BLOB | /* supports */ - SSLSUPP_HTTPS_PROXY | - SSLSUPP_CIPHER_LIST | - SSLSUPP_TLS13_CIPHERSUITES | - SSLSUPP_CERTINFO | - SSLSUPP_ECH | - SSLSUPP_CRLFILE, - sizeof(struct rustls_ssl_backend_data), - - NULL, /* init */ - cr_cleanup, /* cleanup */ - cr_version, /* version */ - cr_shutdown, /* shutdown */ - cr_data_pending, /* data_pending */ - cr_random, /* random */ - NULL, /* cert_status_request */ - cr_connect, /* connect */ - Curl_ssl_adjust_pollset, /* adjust_pollset */ - cr_get_internals, /* get_internals */ - cr_close, /* close_one */ - NULL, /* close_all */ - NULL, /* set_engine */ - NULL, /* set_engine_default */ - NULL, /* engines_list */ - NULL, /* sha256sum */ - cr_recv, /* recv decrypted data */ - cr_send, /* send data to encrypt */ - NULL, /* get_channel_binding */ -}; - -#endif /* USE_RUSTLS */ diff --git a/vendor/curl/lib/vtls/rustls.h b/vendor/curl/lib/vtls/rustls.h deleted file mode 100644 index b6ddbd1b7..000000000 --- a/vendor/curl/lib/vtls/rustls.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_RUSTLS_H -#define HEADER_CURL_RUSTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Jacob Hoffman-Andrews, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_RUSTLS - -extern const struct Curl_ssl Curl_ssl_rustls; - -#endif /* USE_RUSTLS */ -#endif /* HEADER_CURL_RUSTLS_H */ diff --git a/vendor/curl/lib/vtls/schannel.c b/vendor/curl/lib/vtls/schannel.c deleted file mode 100644 index fb5ff0e9d..000000000 --- a/vendor/curl/lib/vtls/schannel.c +++ /dev/null @@ -1,2880 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * Copyright (C) Marc Hoersken, - * Copyright (C) Mark Salisbury, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Source file for all Schannel-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - */ -#include "curl_setup.h" - -#ifdef USE_SCHANNEL - -#ifndef USE_WINDOWS_SSPI -#error "cannot compile Schannel support without SSPI." -#endif - -#include "vtls/schannel.h" -#include "vtls/schannel_int.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" -#include "vtls/vtls_scache.h" -#include "curl_trc.h" -#include "connect.h" /* for the connect timeout */ -#include "curlx/strdup.h" -#include "strerror.h" -#include "select.h" /* for the socket readiness */ -#include "curlx/fopen.h" -#include "curlx/multibyte.h" -#include "vtls/x509asn1.h" -#include "system_win32.h" -#include "curlx/version_win32.h" -#include "rand.h" -#include "curlx/strparse.h" -#include "progress.h" -#include "curl_sha256.h" - -/* Some verbose debug messages are wrapped by SCH_DEV() instead of DEBUGF() - * and only shown if CURL_SCHANNEL_DEV_DEBUG was defined at build time. These - * messages are extra verbose and intended for curl developers debugging - * Schannel recv decryption and renegotiation. - */ -#ifdef CURL_SCHANNEL_DEV_DEBUG -#define SCH_DEV(x) x -#define SCH_DEV_SHOWBOOL(x) \ - infof(data, "schannel: " #x " %s", (x) ? "TRUE" : "FALSE"); -#else -#define SCH_DEV(x) do {} while(0) -#define SCH_DEV_SHOWBOOL(x) do {} while(0) -#endif - -/* Offered by mingw-w64 v8+. MS SDK 7.0A+. */ -#ifndef SP_PROT_TLS1_0_CLIENT -#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT -#endif -#ifndef SP_PROT_TLS1_1_CLIENT -#define SP_PROT_TLS1_1_CLIENT 0x00000200 -#endif -#ifndef SP_PROT_TLS1_2_CLIENT -#define SP_PROT_TLS1_2_CLIENT 0x00000800 -#endif - -/* Offered by mingw-w64 v8+. MS SDK ~10+/~VS2017+. */ -#ifndef SP_PROT_TLS1_3_CLIENT -#define SP_PROT_TLS1_3_CLIENT 0x00002000 -#endif -#ifndef SCH_USE_STRONG_CRYPTO -#define SCH_USE_STRONG_CRYPTO 0x00400000 -#endif - -/* Offered by mingw-w64 v10+. MS SDK 7.0A+. */ -#ifndef SECBUFFER_ALERT -#define SECBUFFER_ALERT 17 -#endif - -/* Both schannel buffer sizes must be > 0 */ -#define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096 -#define CURL_SCHANNEL_BUFFER_FREE_SIZE 1024 - -#define CERT_THUMBPRINT_STR_LEN 40 -#define CERT_THUMBPRINT_DATA_LEN 20 - -/* Uncomment to force verbose output - * #define infof(x, y, ...) curl_mprintf(y, __VA_ARGS__) - * #define failf(x, y, ...) curl_mprintf(y, __VA_ARGS__) - */ - -/* Offered by mingw-w64 v4+. MS SDK 6.0A+. */ -#ifndef PKCS12_NO_PERSIST_KEY -#define PKCS12_NO_PERSIST_KEY 0x00008000 -#endif - -/* Offered by mingw-w64 v4+. MS SDK ~10+/~VS2017+. */ -#ifndef CERT_FIND_HAS_PRIVATE_KEY -#define CERT_FIND_HAS_PRIVATE_KEY (21 << CERT_COMPARE_SHIFT) -#endif - -/* key to use at `multi->proto_hash` */ -#define MPROTO_SCHANNEL_CERT_SHARE_KEY "tls:schannel:cert:share" - -/* ALPN requires version 8.1 of the Windows SDK, which was - shipped with Visual Studio 2013, aka _MSC_VER 1800: - https://learn.microsoft.com/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/hh831771 - Or mingw-w64 9.0 or upper. -*/ -#if (defined(__MINGW64_VERSION_MAJOR) && __MINGW64_VERSION_MAJOR >= 9) || \ - (defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(_USING_V110_SDK71_)) -#define HAS_ALPN_SCHANNEL -static bool s_win_has_alpn; -#endif - -static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType, - void *BufDataPtr, unsigned long BufByteSize) -{ - buffer->cbBuffer = BufByteSize; - buffer->BufferType = BufType; - buffer->pvBuffer = BufDataPtr; -} - -static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr, - unsigned long NumArrElem) -{ - desc->ulVersion = SECBUFFER_VERSION; - desc->pBuffers = BufArr; - desc->cBuffers = NumArrElem; -} - -static CURLcode schannel_set_ssl_version_min_max(DWORD *enabled_protocols, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - long ssl_version = conn_config->version; - long ssl_version_max = (long)conn_config->version_max; - long i = ssl_version; - - switch(ssl_version_max) { - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_DEFAULT: - - /* Windows Server 2022 and newer (including Windows 11) support TLS 1.3 - built-in. Previous builds of Windows 10 had broken TLS 1.3 - implementations that could be enabled via registry. - */ - if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; - } - else /* Windows 10 and older */ - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; - - break; - } - - for(; i <= (ssl_version_max >> 16); ++i) { - switch(i) { - case CURL_SSLVERSION_TLSv1_0: - *enabled_protocols |= SP_PROT_TLS1_0_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_1: - *enabled_protocols |= SP_PROT_TLS1_1_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_2: - *enabled_protocols |= SP_PROT_TLS1_2_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_3: - - /* Windows Server 2022 and newer */ - if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { - *enabled_protocols |= SP_PROT_TLS1_3_CLIENT; - break; - } - else { /* Windows 10 and older */ - failf(data, "schannel: TLS 1.3 not supported on Windows prior to 11"); - return CURLE_SSL_CONNECT_ERROR; - } - } - } - return CURLE_OK; -} - -#define CIPHEROPTION(x) { #x, x } - -struct algo { - const char *name; - int id; -}; - -static const struct algo algs[] = { - CIPHEROPTION(CALG_MD2), - CIPHEROPTION(CALG_MD4), - CIPHEROPTION(CALG_MD5), - CIPHEROPTION(CALG_SHA), - CIPHEROPTION(CALG_SHA1), - CIPHEROPTION(CALG_MAC), - CIPHEROPTION(CALG_RSA_SIGN), - CIPHEROPTION(CALG_DSS_SIGN), - CIPHEROPTION(CALG_NO_SIGN), - CIPHEROPTION(CALG_RSA_KEYX), - CIPHEROPTION(CALG_DES), - CIPHEROPTION(CALG_3DES_112), - CIPHEROPTION(CALG_3DES), - CIPHEROPTION(CALG_DESX), - CIPHEROPTION(CALG_RC2), - CIPHEROPTION(CALG_RC4), - CIPHEROPTION(CALG_SEAL), - CIPHEROPTION(CALG_DH_SF), - CIPHEROPTION(CALG_DH_EPHEM), - CIPHEROPTION(CALG_AGREEDKEY_ANY), - CIPHEROPTION(CALG_HUGHES_MD5), - CIPHEROPTION(CALG_SKIPJACK), - CIPHEROPTION(CALG_TEK), - CIPHEROPTION(CALG_CYLINK_MEK), /* spellchecker:disable-line */ - CIPHEROPTION(CALG_SSL3_SHAMD5), - CIPHEROPTION(CALG_SSL3_MASTER), - CIPHEROPTION(CALG_SCHANNEL_MASTER_HASH), - CIPHEROPTION(CALG_SCHANNEL_MAC_KEY), - CIPHEROPTION(CALG_SCHANNEL_ENC_KEY), - CIPHEROPTION(CALG_PCT1_MASTER), - CIPHEROPTION(CALG_SSL2_MASTER), - CIPHEROPTION(CALG_TLS1_MASTER), - CIPHEROPTION(CALG_RC5), - CIPHEROPTION(CALG_HMAC), - CIPHEROPTION(CALG_TLS1PRF), - CIPHEROPTION(CALG_HASH_REPLACE_OWF), - CIPHEROPTION(CALG_AES_128), - CIPHEROPTION(CALG_AES_192), - CIPHEROPTION(CALG_AES_256), - CIPHEROPTION(CALG_AES), - CIPHEROPTION(CALG_SHA_256), - CIPHEROPTION(CALG_SHA_384), - CIPHEROPTION(CALG_SHA_512), - CIPHEROPTION(CALG_ECDH), -/* Offered by mingw-w64 v4+. MS SDK 6.0A+. */ -#ifdef CALG_ECMQV - CIPHEROPTION(CALG_ECMQV), -#endif - CIPHEROPTION(CALG_ECDSA), -/* Offered by mingw-w64 v7+. MS SDK 7.0A+. */ -#ifdef CALG_ECDH_EPHEM - CIPHEROPTION(CALG_ECDH_EPHEM), -#endif - { NULL, 0 }, -}; - -static int get_alg_id_by_name(const char *name) -{ - const char *nameEnd = strchr(name, ':'); - size_t n = nameEnd ? (size_t)(nameEnd - name) : strlen(name); - int i; - - for(i = 0; algs[i].name; i++) { - if((n == strlen(algs[i].name) && !strncmp(algs[i].name, name, n))) - return algs[i].id; - } - return 0; /* not found */ -} - -#define NUM_CIPHERS 47 /* There are a maximum of 47 options listed above */ - -static CURLcode set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers, - ALG_ID *algIds) -{ - const char *startCur = ciphers; - int algCount = 0; - while(startCur && *startCur && (algCount < NUM_CIPHERS)) { - curl_off_t alg; - if(curlx_str_number(&startCur, &alg, INT_MAX) || !alg) - alg = get_alg_id_by_name(startCur); - - if(alg) - algIds[algCount++] = (ALG_ID)alg; - else if(!strncmp(startCur, "USE_STRONG_CRYPTO", - sizeof("USE_STRONG_CRYPTO") - 1) || - !strncmp(startCur, "SCH_USE_STRONG_CRYPTO", - sizeof("SCH_USE_STRONG_CRYPTO") - 1)) - schannel_cred->dwFlags |= SCH_USE_STRONG_CRYPTO; - else - return CURLE_SSL_CIPHER; - startCur = strchr(startCur, ':'); - if(startCur) - startCur++; - } - schannel_cred->palgSupportedAlgs = algIds; - schannel_cred->cSupportedAlgs = (DWORD)algCount; - return CURLE_OK; -} - -/* Function allocates memory for store_path only if CURLE_OK is returned */ -static CURLcode get_cert_location(TCHAR *path, DWORD *store_name, - TCHAR **store_path, TCHAR **thumbprint) -{ - TCHAR *sep; - TCHAR *store_path_start; - size_t store_name_len; - - sep = _tcschr(path, TEXT('\\')); - if(!sep) - return CURLE_SSL_CERTPROBLEM; - - store_name_len = sep - path; - - if(_tcsncmp(path, TEXT("CurrentUser"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_CURRENT_USER; - else if(_tcsncmp(path, TEXT("LocalMachine"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE; - else if(_tcsncmp(path, TEXT("CurrentService"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_CURRENT_SERVICE; - else if(_tcsncmp(path, TEXT("Services"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_SERVICES; - else if(_tcsncmp(path, TEXT("Users"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_USERS; - else if(_tcsncmp(path, TEXT("CurrentUserGroupPolicy"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY; - else if(_tcsncmp(path, TEXT("LocalMachineGroupPolicy"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY; - else if(_tcsncmp(path, TEXT("LocalMachineEnterprise"), store_name_len) == 0) - *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE; - else - return CURLE_SSL_CERTPROBLEM; - - store_path_start = sep + 1; - - sep = _tcschr(store_path_start, TEXT('\\')); - if(!sep) - return CURLE_SSL_CERTPROBLEM; - - *thumbprint = sep + 1; - if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) - return CURLE_SSL_CERTPROBLEM; - - *sep = TEXT('\0'); - *store_path = curlx_tcsdup(store_path_start); - *sep = TEXT('\\'); - if(!*store_path) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static CURLcode get_client_cert(struct Curl_easy *data, - HCERTSTORE *out_cert_store, - PCCERT_CONTEXT *out_cert_context) -{ - PCCERT_CONTEXT client_cert = NULL; - HCERTSTORE client_cert_store = NULL; - CURLcode result = CURLE_OK; - - if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { - DWORD cert_store_name = 0; - TCHAR *cert_store_path = NULL; - TCHAR *cert_thumbprint_str = NULL; - TCHAR cert_thumbprint_buf[CERT_THUMBPRINT_STR_LEN + 1]; - CRYPT_HASH_BLOB cert_thumbprint; - BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN]; - HCERTSTORE cert_store = NULL; - FILE *fInCert = NULL; - void *certdata = NULL; - size_t certsize = 0; - bool blob = data->set.ssl.primary.cert_blob != NULL; - - if(blob) { - certdata = data->set.ssl.primary.cert_blob->data; - certsize = data->set.ssl.primary.cert_blob->len; - } - else { - TCHAR *cert_path = - curlx_convert_UTF8_to_tchar(data->set.ssl.primary.clientcert); - if(!cert_path) - return CURLE_OUT_OF_MEMORY; - - result = get_cert_location(cert_path, &cert_store_name, - &cert_store_path, &cert_thumbprint_str); - - /* 'cert_thumbprint_str' points in to the allocated 'cert_path', copy - the data. The string is verified to be CERT_THUMBPRINT_STR_LEN bytes - long within the get_cert_location() function. */ - if(!result && cert_thumbprint_str) { - memcpy(cert_thumbprint_buf, cert_thumbprint_str, - sizeof(cert_thumbprint_buf)); - cert_thumbprint_str = cert_thumbprint_buf; - } - - curlx_free(cert_path); - if(result && (data->set.ssl.primary.clientcert[0] != '\0')) - fInCert = curlx_fopen(data->set.ssl.primary.clientcert, "rb"); - - if(result && !fInCert) { - failf(data, "schannel: Failed to get certificate location" - " or file for %s", - data->set.ssl.primary.clientcert); - return result; - } - } - - if((fInCert || blob) && data->set.ssl.cert_type && - !curl_strequal(data->set.ssl.cert_type, "P12")) { - failf(data, "schannel: certificate format compatibility error " - "for %s", - blob ? "(memory blob)" : data->set.ssl.primary.clientcert); - curlx_free(cert_store_path); - if(fInCert) - curlx_fclose(fInCert); - return CURLE_SSL_CERTPROBLEM; - } - - if(fInCert || blob) { - /* Reading a .p12 or .pfx file, like the example at bottom of - https://learn.microsoft.com/archive/msdn-technet-forums/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5 - */ - CRYPT_DATA_BLOB datablob; - WCHAR *pszPassword; - size_t pwd_len = 0; - int cert_find_flags; - const char *cert_showfilename_error = blob ? - "(memory blob)" : data->set.ssl.primary.clientcert; - curlx_free(cert_store_path); - if(fInCert) { - long cert_tell = 0; - bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0; - if(continue_reading) - cert_tell = ftell(fInCert); - if(cert_tell < 0) - continue_reading = FALSE; - else - certsize = (size_t)cert_tell; - if(continue_reading) - continue_reading = fseek(fInCert, 0, SEEK_SET) == 0; - if(continue_reading && (certsize < CURL_MAX_INPUT_LENGTH)) - certdata = curlx_malloc(certsize + 1); - if((!certdata) || - ((int) fread(certdata, certsize, 1, fInCert) != 1)) - continue_reading = FALSE; - curlx_fclose(fInCert); - if(!continue_reading) { - failf(data, "schannel: Failed to read cert file %s", - data->set.ssl.primary.clientcert); - curlx_free(certdata); - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Convert key-pair data to the in-memory certificate store */ - datablob.pbData = (BYTE *)certdata; - datablob.cbData = (DWORD)certsize; - - if(data->set.ssl.key_passwd) - pwd_len = strlen(data->set.ssl.key_passwd); - pszPassword = (WCHAR *)curlx_malloc(sizeof(WCHAR) * (pwd_len + 1)); - if(pszPassword) { - int str_w_len = 0; - if(pwd_len > 0) - str_w_len = MultiByteToWideChar(CP_UTF8, - MB_ERR_INVALID_CHARS, - data->set.ssl.key_passwd, - (int)pwd_len, - pszPassword, (int)(pwd_len + 1)); - - if((str_w_len >= 0) && (str_w_len <= (int)pwd_len)) - pszPassword[str_w_len] = 0; - else - pszPassword[0] = 0; - - cert_store = PFXImportCertStore(&datablob, pszPassword, - PKCS12_NO_PERSIST_KEY); - curlx_free(pszPassword); - } - if(!blob) - curlx_free(certdata); - if(!cert_store) { - DWORD errorcode = GetLastError(); - if(errorcode == ERROR_INVALID_PASSWORD) - failf(data, "schannel: Failed to import cert file %s, " - "password is bad", - cert_showfilename_error); - else - failf(data, "schannel: Failed to import cert file %s, " - "last error is 0x%08lx", - cert_showfilename_error, errorcode); - return CURLE_SSL_CERTPROBLEM; - } - - /* CERT_FIND_HAS_PRIVATE_KEY is only available in Windows 8 / Server - 2012, (NT v6.2). For earlier versions we use CURL_FIND_ANY. */ - if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) - cert_find_flags = CERT_FIND_HAS_PRIVATE_KEY; - else - cert_find_flags = CERT_FIND_ANY; - - client_cert = - CertFindCertificateInStore(cert_store, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, - cert_find_flags, NULL, NULL); - - if(!client_cert) { - failf(data, "schannel: Failed to get certificate from file %s" - ", last error is 0x%08lx", - cert_showfilename_error, GetLastError()); - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } - } - else { - cert_store = - CertOpenStore( -#ifdef UNICODE - CERT_STORE_PROV_SYSTEM_W, -#else - CERT_STORE_PROV_SYSTEM_A, -#endif - 0, - (HCRYPTPROV)NULL, - CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name, - cert_store_path); - if(!cert_store) { - char *path_utf8 = - curlx_convert_tchar_to_UTF8(cert_store_path); - failf(data, "schannel: Failed to open cert store %lx %s, " - "last error is 0x%08lx", - cert_store_name, (path_utf8 ? path_utf8 : "(unknown)"), - GetLastError()); - curlx_free(cert_store_path); - curlx_free(path_utf8); - return CURLE_SSL_CERTPROBLEM; - } - curlx_free(cert_store_path); - - cert_thumbprint.pbData = cert_thumbprint_data; - cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN; - - if(!CryptStringToBinary(cert_thumbprint_str, - CERT_THUMBPRINT_STR_LEN, - CRYPT_STRING_HEX, - cert_thumbprint_data, - &cert_thumbprint.cbData, - NULL, NULL)) { - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } - - client_cert = - CertFindCertificateInStore(cert_store, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, - CERT_FIND_HASH, &cert_thumbprint, NULL); - if(!client_cert) { - /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ - CertCloseStore(cert_store, 0); - failf(data, "schannel: client cert not found in cert store"); - return CURLE_SSL_CERTPROBLEM; - } - } - client_cert_store = cert_store; - } - - *out_cert_store = client_cert_store; - *out_cert_context = client_cert; - - return CURLE_OK; -} - -static CURLcode acquire_sspi_handle(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct schannel_ssl_backend_data *backend, - PCCERT_CONTEXT client_cert, - DWORD flags, - DWORD enabled_protocols) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - SECURITY_STATUS sspi_status = SEC_E_OK; - CURLcode result; - - /* We support TLS 1.3 starting in Windows 10 version 1809 (OS build 17763) as - long as the user did not set a legacy algorithm list - (CURLOPT_SSL_CIPHER_LIST). */ - if(!conn_config->cipher_list && - curlx_verify_windows_version(10, 0, 17763, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { - - SCH_CREDENTIALS credentials = { 0 }; - TLS_PARAMETERS tls_parameters = { 0 }; - CRYPTO_SETTINGS crypto_settings[1]; - PCCERT_CONTEXT client_certs[1]; - - if(client_cert) - client_certs[0] = client_cert; - else - client_certs[0] = NULL; - - memset(crypto_settings, 0, sizeof(crypto_settings)); - - tls_parameters.pDisabledCrypto = crypto_settings; - - /* The number of blocked suites */ - tls_parameters.cDisabledCrypto = (DWORD)0; - credentials.pTlsParameters = &tls_parameters; - credentials.cTlsParameters = 1; - - credentials.dwVersion = SCH_CREDENTIALS_VERSION; - credentials.dwFlags = flags | SCH_USE_STRONG_CRYPTO; - - credentials.pTlsParameters->grbitDisabledProtocols = ~enabled_protocols; - - if(client_certs[0]) { - credentials.cCreds = 1; - credentials.paCred = client_certs; - } - - sspi_status = - Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(UNISP_NAME), - SECPKG_CRED_OUTBOUND, NULL, - &credentials, NULL, NULL, - &backend->cred->cred_handle, NULL); - } - else { - /* Pre-Windows 10 1809 or the user set a legacy algorithm list. - Schannel does not negotiate TLS 1.3 when SCHANNEL_CRED is used. */ - ALG_ID algIds[NUM_CIPHERS]; - char *ciphers = conn_config->cipher_list; - SCHANNEL_CRED schannel_cred = { 0 }; - PCCERT_CONTEXT client_certs[1]; - - if(client_cert) - client_certs[0] = client_cert; - else - client_certs[0] = NULL; - - schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; - schannel_cred.dwFlags = flags; - schannel_cred.grbitEnabledProtocols = enabled_protocols; - - if(ciphers) { - if((enabled_protocols & SP_PROT_TLS1_3_CLIENT)) { - infof(data, "schannel: WARNING: This version of Schannel " - "negotiates a less-secure TLS version than TLS 1.3 because the " - "user set an algorithm cipher list."); - } - result = set_ssl_ciphers(&schannel_cred, ciphers, algIds); - if(result) { - failf(data, "schannel: Failed setting algorithm cipher list"); - return result; - } - } - else { - schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO; - } - - if(client_certs[0]) { - schannel_cred.cCreds = 1; - schannel_cred.paCred = client_certs; - } - - sspi_status = - Curl_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)CURL_UNCONST(UNISP_NAME), - SECPKG_CRED_OUTBOUND, NULL, - &schannel_cred, NULL, NULL, - &backend->cred->cred_handle, NULL); - } - - if(sspi_status != SEC_E_OK) { - char buffer[STRERROR_LEN]; - failf(data, "schannel: AcquireCredentialsHandle failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - switch(sspi_status) { - case SEC_E_INSUFFICIENT_MEMORY: - return CURLE_OUT_OF_MEMORY; - case SEC_E_NO_CREDENTIALS: - case SEC_E_SECPKG_NOT_FOUND: - case SEC_E_NOT_OWNER: - case SEC_E_UNKNOWN_CREDENTIALS: - case SEC_E_INTERNAL_ERROR: - default: - return CURLE_SSL_CONNECT_ERROR; - } - } - - return CURLE_OK; -} - -static CURLcode schannel_acquire_credential_handle(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - - PCCERT_CONTEXT client_cert = NULL; - HCERTSTORE client_cert_store = NULL; - CURLcode result; - - /* setup Schannel API options */ - DWORD flags = 0; - DWORD enabled_protocols = 0; - - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)(connssl->backend); - - DEBUGASSERT(backend); - - if(conn_config->verifypeer) { - if(backend->use_manual_cred_validation) - flags = SCH_CRED_MANUAL_CRED_VALIDATION; - else - flags = SCH_CRED_AUTO_CRED_VALIDATION; - - if(ssl_config->no_revoke) { - flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - - DEBUGF(infof(data, "schannel: disabled server certificate revocation " - "checks")); - } - else if(ssl_config->revoke_best_effort) { - flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE | - SCH_CRED_REVOCATION_CHECK_CHAIN; - - DEBUGF(infof(data, "schannel: ignore revocation offline errors")); - } - else { - flags |= SCH_CRED_REVOCATION_CHECK_CHAIN; - - DEBUGF(infof(data, "schannel: checking server certificate revocation")); - } - } - else { - flags = SCH_CRED_MANUAL_CRED_VALIDATION | - SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - DEBUGF(infof(data, "schannel: disabled server cert revocation checks")); - } - - if(!conn_config->verifyhost) { - flags |= SCH_CRED_NO_SERVERNAME_CHECK; - DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from " - "comparing the supplied target name with the subject " - "names in server certificates.")); - } - - if(!ssl_config->auto_client_cert) { - flags &= ~(DWORD)SCH_CRED_USE_DEFAULT_CREDS; - flags |= SCH_CRED_NO_DEFAULT_CREDS; - infof(data, "schannel: disabled automatic use of client certificate"); - } - else - infof(data, "schannel: enabled automatic use of client certificate"); - - DEBUGASSERT(conn_config->version != CURL_SSLVERSION_DEFAULT); - switch(conn_config->version) { - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: { - result = schannel_set_ssl_version_min_max(&enabled_protocols, cf, data); - if(result) - return result; - break; - } - case CURL_SSLVERSION_SSLv3: - case CURL_SSLVERSION_SSLv2: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - - result = get_client_cert(data, &client_cert_store, &client_cert); - if(result) - return result; - - /* allocate memory for the reusable credential handle */ - backend->cred = (struct Curl_schannel_cred *) - curlx_calloc(1, sizeof(struct Curl_schannel_cred)); - if(!backend->cred) { - failf(data, "schannel: unable to allocate memory"); - - if(client_cert) - CertFreeCertificateContext(client_cert); - if(client_cert_store) - CertCloseStore(client_cert_store, 0); - - return CURLE_OUT_OF_MEMORY; - } - backend->cred->refcount = 1; - - /* Since we did not persist the key, we need to extend the store's - * lifetime until the end of the connection - */ - backend->cred->client_cert_store = client_cert_store; - - result = acquire_sspi_handle(cf, data, backend, client_cert, - flags, enabled_protocols); - - if(client_cert) - CertFreeCertificateContext(client_cert); - - return result; -} - -static CURLcode schannel_connect_step1(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - size_t written = 0; - struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - SecBuffer outbuf; - SecBufferDesc outbuf_desc; - SecBuffer inbuf; - SecBufferDesc inbuf_desc; -#ifdef HAS_ALPN_SCHANNEL - unsigned char alpn_buffer[128]; -#endif - SECURITY_STATUS sspi_status = SEC_E_OK; - CURLcode result; - - DEBUGASSERT(backend); - DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %d (step 1/3)", - connssl->peer.hostname, connssl->peer.port)); - -#ifdef HAS_ALPN_SCHANNEL - backend->use_alpn = connssl->alpn && s_win_has_alpn; -#else - backend->use_alpn = FALSE; -#endif - - if(conn_config->CAfile || conn_config->ca_info_blob) { - if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { - backend->use_manual_cred_validation = TRUE; - } - else { - failf(data, "schannel: this version of Windows is too old to support " - "certificate verification via CA bundle file."); - return CURLE_SSL_CACERT_BADFILE; - } - } - else - backend->use_manual_cred_validation = FALSE; - - backend->cred = NULL; - - /* check for an existing reusable credential handle */ - if(Curl_ssl_scache_use(cf, data)) { - struct Curl_schannel_cred *old_cred; - Curl_ssl_scache_lock(data); - old_cred = Curl_ssl_scache_get_obj(cf, data, connssl->peer.scache_key); - if(old_cred) { - backend->cred = old_cred; - DEBUGF(infof(data, "schannel: reusing existing credential handle")); - - /* increment the reference counter of the credential/session handle */ - backend->cred->refcount++; - DEBUGF(infof(data, - "schannel: incremented credential handle refcount = %d", - backend->cred->refcount)); - } - Curl_ssl_scache_unlock(data); - } - - if(!backend->cred) { - char *snihost; - result = schannel_acquire_credential_handle(cf, data); - if(result || !backend->cred) - return result; - /* schannel_acquire_credential_handle() sets backend->cred accordingly or - it returns error otherwise. */ - - /* A hostname associated with the credential is needed by - InitializeSecurityContext for SNI and other reasons. */ - snihost = connssl->peer.sni ? connssl->peer.sni : connssl->peer.hostname; - backend->cred->sni_hostname = curlx_convert_UTF8_to_tchar(snihost); - if(!backend->cred->sni_hostname) - return CURLE_OUT_OF_MEMORY; - } - - /* Warn if SNI is disabled due to use of an IP address */ - if(connssl->peer.type != CURL_SSL_PEER_DNS) { - infof(data, "schannel: using IP address, SNI is not supported by OS."); - } - -#ifdef HAS_ALPN_SCHANNEL - if(backend->use_alpn) { - int cur = 0; - int list_start_index = 0; - unsigned int *extension_len = NULL; - unsigned short *list_len = NULL; - struct alpn_proto_buf proto; - - /* The first four bytes is an unsigned int indicating number - of bytes of data in the rest of the buffer. */ - extension_len = (unsigned int *)(void *)(&alpn_buffer[cur]); - cur += (int)sizeof(unsigned int); - - /* The next four bytes are an indicator that this buffer contains - ALPN data, as opposed to NPN, for example. */ - *(unsigned int *)(void *)&alpn_buffer[cur] = - SecApplicationProtocolNegotiationExt_ALPN; - cur += (int)sizeof(unsigned int); - - /* The next two bytes is an unsigned short indicating the number - of bytes used to list the preferred protocols. */ - list_len = (unsigned short *)(void *)(&alpn_buffer[cur]); - cur += (int)sizeof(unsigned short); - - list_start_index = cur; - - result = Curl_alpn_to_proto_buf(&proto, connssl->alpn); - if(result) { - failf(data, "Error setting ALPN"); - return CURLE_SSL_CONNECT_ERROR; - } - memcpy(&alpn_buffer[cur], proto.data, proto.len); - cur += proto.len; - - *list_len = curlx_uitous(cur - list_start_index); - *extension_len = (unsigned int)(*list_len + - sizeof(unsigned int) + sizeof(unsigned short)); - - InitSecBuffer(&inbuf, SECBUFFER_APPLICATION_PROTOCOLS, alpn_buffer, cur); - InitSecBufferDesc(&inbuf_desc, &inbuf, 1); - - Curl_alpn_to_proto_str(&proto, connssl->alpn); - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); - } - else { - InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, &inbuf, 1); - } -#else /* HAS_ALPN_SCHANNEL */ - InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, &inbuf, 1); -#endif - - /* setup output buffer */ - InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, &outbuf, 1); - - /* security request flags */ - backend->req_flags = - ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_STREAM | - (!ssl_config->auto_client_cert ? ISC_REQ_USE_SUPPLIED_CREDS : 0); - - /* allocate memory for the security context handle */ - backend->ctxt = (struct Curl_schannel_ctxt *) - curlx_calloc(1, sizeof(struct Curl_schannel_ctxt)); - if(!backend->ctxt) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - - /* Schannel InitializeSecurityContext: - https://learn.microsoft.com/windows/win32/api/rrascfg/nn-rrascfg-ieapproviderconfig - - At the moment we do not pass inbuf unless we are using ALPN since we only - use it for that, and WINE (for which we currently disable ALPN) is giving - us problems with inbuf regardless. https://github.com/curl/curl/issues/983 - */ - sspi_status = Curl_pSecFn->InitializeSecurityContext( - &backend->cred->cred_handle, NULL, backend->cred->sni_hostname, - backend->req_flags, 0, 0, - (backend->use_alpn ? &inbuf_desc : NULL), - 0, &backend->ctxt->ctxt_handle, - &outbuf_desc, &backend->ret_flags, NULL); - - if(sspi_status != SEC_I_CONTINUE_NEEDED) { - char buffer[STRERROR_LEN]; - curlx_safefree(backend->ctxt); - switch(sspi_status) { - case SEC_E_INSUFFICIENT_MEMORY: - failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_OUT_OF_MEMORY; - case SEC_E_WRONG_PRINCIPAL: - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_PEER_FAILED_VERIFICATION; -#if 0 - case SEC_E_INVALID_HANDLE: - case SEC_E_INVALID_TOKEN: - case SEC_E_LOGON_DENIED: - case SEC_E_TARGET_UNKNOWN: - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - case SEC_E_INTERNAL_ERROR: - case SEC_E_NO_CREDENTIALS: - case SEC_E_UNSUPPORTED_FUNCTION: - case SEC_E_APPLICATION_PROTOCOL_MISMATCH: -#endif - default: - failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_SSL_CONNECT_ERROR; - } - } - - DEBUGF(infof(data, "schannel: sending initial handshake data: " - "sending %lu bytes.", outbuf.cbBuffer)); - - /* send initial handshake data which is now stored in output buffer */ - result = Curl_conn_cf_send(cf->next, data, - (const uint8_t *)outbuf.pvBuffer, - outbuf.cbBuffer, FALSE, - &written); - Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer); - if(result || (outbuf.cbBuffer != written)) { - failf(data, "schannel: failed to send initial handshake data: " - "sent %zu of %lu bytes", written, outbuf.cbBuffer); - return CURLE_SSL_CONNECT_ERROR; - } - - DEBUGF(infof(data, "schannel: sent initial handshake data: " - "sent %zu bytes", written)); - - backend->recv_unrecoverable_err = CURLE_OK; - backend->recv_sspi_close_notify = FALSE; - backend->recv_connection_closed = FALSE; - backend->recv_renegotiating = FALSE; - backend->renegotiate_state.started = FALSE; - backend->encdata_is_incomplete = FALSE; - - /* continue to second handshake step */ - connssl->connecting_state = ssl_connect_2; - - return CURLE_OK; -} - -static CURLcode schannel_error(struct Curl_easy *data, - SECURITY_STATUS sspi_status) -{ - char buffer[STRERROR_LEN]; - switch(sspi_status) { - case SEC_E_INSUFFICIENT_MEMORY: - failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_OUT_OF_MEMORY; - case SEC_E_WRONG_PRINCIPAL: - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_PEER_FAILED_VERIFICATION; - case SEC_E_UNTRUSTED_ROOT: - failf(data, "schannel: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_PEER_FAILED_VERIFICATION; -#if 0 - case SEC_E_INVALID_HANDLE: - case SEC_E_INVALID_TOKEN: - case SEC_E_LOGON_DENIED: - case SEC_E_TARGET_UNKNOWN: - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - case SEC_E_INTERNAL_ERROR: - case SEC_E_NO_CREDENTIALS: - case SEC_E_UNSUPPORTED_FUNCTION: - case SEC_E_APPLICATION_PROTOCOL_MISMATCH: -#endif - default: - failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_SSL_CONNECT_ERROR; - } -} - -static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *pinnedpubkey) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - CERT_CONTEXT *pCertContextServer = NULL; - - /* Result is returned to caller */ - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - DEBUGASSERT(backend); - - /* if a path was not specified, do not pin */ - if(!pinnedpubkey) - return CURLE_OK; - - do { - SECURITY_STATUS sspi_status; - const char *x509_der; - DWORD x509_der_len; - struct Curl_X509certificate x509_parsed; - struct Curl_asn1Element *pubkey; - - sspi_status = - Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); - - if((sspi_status != SEC_E_OK) || !pCertContextServer) { - char buffer[STRERROR_LEN]; - failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - break; /* failed */ - } - - if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) && - (pCertContextServer->cbCertEncoded > 0))) - break; - - x509_der = (const char *)pCertContextServer->pbCertEncoded; - x509_der_len = pCertContextServer->cbCertEncoded; - memset(&x509_parsed, 0, sizeof(x509_parsed)); - if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) - break; - - pubkey = &x509_parsed.subjectPublicKeyInfo; - if(!pubkey->header || pubkey->end <= pubkey->header) { - failf(data, "SSL: failed retrieving public key from server certificate"); - break; - } - - result = Curl_pin_peer_pubkey(data, - pinnedpubkey, - (const unsigned char *)pubkey->header, - (size_t)(pubkey->end - pubkey->header)); - if(result) { - failf(data, "SSL: public key does not match pinned public key"); - } - } while(0); - - if(pCertContextServer) - CertFreeCertificateContext(pCertContextServer); - - return result; -} - -static CURLcode ensure_encoding_size(struct Curl_easy *data, - struct sbuffer *encdata, - size_t min_length) -{ - size_t size; - DEBUGASSERT(encdata->length >= encdata->offset); - if(encdata->length < encdata->offset) - return CURLE_FAILED_INIT; - size = encdata->length - encdata->offset; - if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE || encdata->length < min_length) { - unsigned char *buffer; - size_t length = encdata->offset + CURL_SCHANNEL_BUFFER_FREE_SIZE; - if(length < min_length) - length = min_length; - buffer = curlx_realloc(encdata->buffer, length); - if(!buffer) { - failf(data, "schannel: unable to re-allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - - encdata->buffer = buffer; - encdata->length = length; - SCH_DEV(infof(data, "schannel: encdata.buffer resized %zu", - encdata->length)); - } - return CURLE_OK; -} - -static CURLcode ensure_decoding_size(struct Curl_easy *data, - struct sbuffer *decdata, - size_t nowsize, - size_t len) -{ - size_t size = nowsize > CURL_SCHANNEL_BUFFER_FREE_SIZE ? - nowsize : CURL_SCHANNEL_BUFFER_FREE_SIZE; - DEBUGASSERT(decdata->length >= decdata->offset); - if(decdata->length < decdata->offset) - return CURLE_FAILED_INIT; - else if(decdata->length - decdata->offset < size || - decdata->length < len) { - /* increase internal decrypted data buffer */ - size_t length = decdata->offset + size; - unsigned char *buffer; - /* make sure that the requested amount of data fits */ - if(length < len) - length = len; - - buffer = curlx_realloc(decdata->buffer, length); - if(!buffer) { - failf(data, "schannel: unable to re-allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - decdata->buffer = buffer; - decdata->length = length; - } - return CURLE_OK; -} - -static CURLcode schannel_connect_step2(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - int i; - size_t nread = 0; - SecBuffer outbuf[3]; - SecBufferDesc outbuf_desc; - SecBuffer inbuf[2]; - SecBufferDesc inbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - CURLcode result; - bool doread; - const char *pubkey_ptr; - - DEBUGASSERT(backend); - - doread = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ? FALSE : TRUE; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - - DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %d (step 2/3)", - connssl->peer.hostname, connssl->peer.port)); - - if(!backend->cred || !backend->ctxt) - return CURLE_SSL_CONNECT_ERROR; - - /* buffer to store previously received and decrypted data */ - if(!backend->decdata.buffer) { - backend->decdata.offset = 0; - backend->decdata.length = CURL_SCHANNEL_BUFFER_INIT_SIZE; - backend->decdata.buffer = curlx_malloc(backend->decdata.length); - if(!backend->decdata.buffer) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - } - - /* buffer to store previously received and encrypted data */ - if(!backend->encdata.buffer) { - backend->encdata_is_incomplete = FALSE; - backend->encdata.offset = 0; - backend->encdata.length = CURL_SCHANNEL_BUFFER_INIT_SIZE; - backend->encdata.buffer = curlx_malloc(backend->encdata.length); - if(!backend->encdata.buffer) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - } - - result = ensure_encoding_size(data, &backend->encdata, 0); - if(result) - return result; - - for(;;) { - if(doread) { - /* read encrypted handshake data from socket */ - result = Curl_conn_cf_recv(cf->next, data, - (char *)(backend->encdata.buffer + - backend->encdata.offset), - backend->encdata.length - - backend->encdata.offset, - &nread); - if(result == CURLE_AGAIN) { - if(!backend->encdata.offset || backend->encdata_is_incomplete) { - connssl->io_need = CURL_SSL_IO_NEED_RECV; - DEBUGF(infof(data, "schannel: failed to receive handshake, " - "need more data")); - return CURLE_OK; - } - else { - DEBUGF(infof(data, "schannel: no new handshake data received, " - "continuing to process existing handshake data")); - } - } - else if(result || (nread == 0)) { - failf(data, "schannel: failed to receive handshake, " - "SSL/TLS connection failed"); - return CURLE_SSL_CONNECT_ERROR; - } - else { - /* increase encrypted data buffer offset */ - backend->encdata.offset += nread; - backend->encdata_is_incomplete = FALSE; - SCH_DEV(infof(data, "schannel: encrypted data got %zu", nread)); - } - } - - SCH_DEV(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu", - backend->encdata.offset, backend->encdata.length)); - - /* setup input buffers */ - InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, - curlx_malloc(backend->encdata.offset), - curlx_uztoul(backend->encdata.offset)); - InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, inbuf, 2); - - /* setup output buffers */ - InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0); - InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0); - InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, outbuf, 3); - - if(!inbuf[0].pvBuffer) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - - /* copy received handshake data into input buffer */ - memcpy(inbuf[0].pvBuffer, backend->encdata.buffer, - backend->encdata.offset); - - /* The socket must be writable (or a poll error occurred) before we call - InitializeSecurityContext to continue processing the received TLS - records. This is because that function is not idempotent and we do not - support partial save/resume sending replies of handshake tokens. */ - if(!SOCKET_WRITABLE(Curl_conn_cf_get_socket(cf, data), 0)) { - SCH_DEV(infof(data, "schannel: handshake waiting for writable socket")); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - curlx_free(inbuf[0].pvBuffer); - return CURLE_OK; - } - - sspi_status = Curl_pSecFn->InitializeSecurityContext( - &backend->cred->cred_handle, &backend->ctxt->ctxt_handle, - backend->cred->sni_hostname, backend->req_flags, - 0, 0, &inbuf_desc, 0, NULL, - &outbuf_desc, &backend->ret_flags, NULL); - - /* free buffer for received handshake data */ - curlx_safefree(inbuf[0].pvBuffer); - - /* check if the handshake was incomplete */ - switch(sspi_status) { - case SEC_E_INCOMPLETE_MESSAGE: - backend->encdata_is_incomplete = TRUE; - connssl->io_need = CURL_SSL_IO_NEED_RECV; - DEBUGF(infof(data, - "schannel: received incomplete message, need more data")); - return CURLE_OK; - - case SEC_I_CONTINUE_NEEDED: - case SEC_E_OK: - /* check if the handshake needs to be continued */ - result = CURLE_OK; - for(i = 0; i < 3; i++) { - /* search for handshake tokens that need to be send */ - if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) { - size_t written = 0; - DEBUGF(infof(data, "schannel: sending next handshake data: " - "sending %lu bytes.", outbuf[i].cbBuffer)); - - /* send handshake token to server */ - result = Curl_conn_cf_send(cf->next, data, - (const uint8_t *)outbuf[i].pvBuffer, - outbuf[i].cbBuffer, - FALSE, &written); - if(result || (outbuf[i].cbBuffer != written)) { - failf(data, "schannel: failed to send next handshake data: " - "sent %zu of %lu bytes", written, outbuf[i].cbBuffer); - result = CURLE_SSL_CONNECT_ERROR; - } - } - } - for(i = 0; i < 3; i++) { - /* free obsolete buffer */ - if(outbuf[i].pvBuffer) - Curl_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer); - } - if(result) - return result; - break; - - case SEC_I_INCOMPLETE_CREDENTIALS: - if(!(backend->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { - /* If the server has requested a client certificate, attempt to - continue the handshake without one. This allows connections to - servers which request a client certificate but do not require - it. */ - backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; - connssl->io_need = CURL_SSL_IO_NEED_SEND; - DEBUGF(infof(data, - "schannel: a client certificate has been requested")); - return CURLE_OK; - } - FALLTHROUGH(); - - default: - return schannel_error(data, sspi_status); - } - - /* check if there was additional remaining encrypted data */ - if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { - SCH_DEV(infof(data, "schannel: encrypted data length: %lu", - inbuf[1].cbBuffer)); - /* - There are two cases where we could be getting extra data here: - 1. If we are renegotiating a connection and the handshake is already - complete (from the server perspective), it can encrypted app data - (not handshake data) in an extra buffer at this point. - 2. (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a - connection and this extra data is part of the handshake. - We should process the data immediately; waiting for the socket to - be ready may fail since the server is done sending handshake data. - */ - /* check if the remaining data is less than the total amount - and therefore begins after the already processed data */ - if(backend->encdata.offset > inbuf[1].cbBuffer) { - memmove(backend->encdata.buffer, - (backend->encdata.buffer + backend->encdata.offset) - - inbuf[1].cbBuffer, inbuf[1].cbBuffer); - backend->encdata.offset = inbuf[1].cbBuffer; - if(sspi_status == SEC_I_CONTINUE_NEEDED) { - doread = FALSE; - continue; - } - } - } - else { - backend->encdata.offset = 0; - } - break; - } - - /* check if the handshake needs to be continued */ - if(sspi_status == SEC_I_CONTINUE_NEEDED) { - connssl->io_need = CURL_SSL_IO_NEED_RECV; - return CURLE_OK; - } - - /* check if the handshake is complete */ - if(sspi_status == SEC_E_OK) { - connssl->connecting_state = ssl_connect_3; - DEBUGF(infof(data, "schannel: SSL/TLS handshake complete")); - } - -#ifndef CURL_DISABLE_PROXY - pubkey_ptr = Curl_ssl_cf_is_proxy(cf) ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - pubkey_ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif - if(pubkey_ptr) { - result = schannel_pkp_pin_peer_pubkey(cf, data, pubkey_ptr); - if(result) { - failf(data, "SSL: public key does not match pinned public key"); - return result; - } - } - - if(conn_config->verifypeer && backend->use_manual_cred_validation) { - /* Certificate verification also verifies the hostname if verifyhost */ - return Curl_verify_certificate(cf, data); - } - - /* Verify the hostname manually when certificate verification is disabled, - because in that case Schannel does not verify it. */ - if(!conn_config->verifypeer && conn_config->verifyhost) - return Curl_verify_host(cf, data); - - return CURLE_OK; -} - -static bool valid_cert_encoding(const CERT_CONTEXT *cert_context) -{ - return (cert_context != NULL) && - ((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) && - (cert_context->pbCertEncoded != NULL) && - (cert_context->cbCertEncoded > 0); -} - -typedef bool (*Read_crt_func)(const CERT_CONTEXT *ccert_context, - bool reverse_order, void *arg); - -static void traverse_cert_store(const CERT_CONTEXT *context, - Read_crt_func func, void *arg) -{ - const CERT_CONTEXT *current_context = NULL; - bool should_continue = TRUE; - bool first = TRUE; - bool reverse_order = FALSE; - while(should_continue && - (current_context = CertEnumCertificatesInStore( - context->hCertStore, - current_context)) != NULL) { - /* Windows 11 22H2 OS Build 22621.674 or higher enumerates certificates in - leaf-to-root order while all previous versions of Windows enumerate - certificates in root-to-leaf order. Determine the order of enumeration - by comparing SECPKG_ATTR_REMOTE_CERT_CONTEXT's pbCertContext with the - first certificate's pbCertContext. */ - if(first && context->pbCertEncoded != current_context->pbCertEncoded) - reverse_order = TRUE; - should_continue = func(current_context, reverse_order, arg); - first = FALSE; - } - - if(current_context) - CertFreeCertificateContext(current_context); -} - -static bool cert_counter_callback(const CERT_CONTEXT *ccert_context, - bool reverse_order, void *certs_count) -{ - (void)reverse_order; - if(valid_cert_encoding(ccert_context)) - (*(int *)certs_count)++; - if(*(int *)certs_count > MAX_ALLOWED_CERT_AMOUNT) - return FALSE; - return TRUE; -} - -struct Adder_args { - struct Curl_easy *data; - CURLcode result; - int idx; - int certs_count; -}; - -static bool add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, - bool reverse_order, void *raw_arg) -{ - struct Adder_args *args = (struct Adder_args *)raw_arg; - args->result = CURLE_OK; - if(valid_cert_encoding(ccert_context)) { - const char *beg = (const char *)ccert_context->pbCertEncoded; - const char *end = beg + ccert_context->cbCertEncoded; - int insert_index = reverse_order ? (args->certs_count - 1) - args->idx : - args->idx; - args->result = Curl_extract_certinfo(args->data, insert_index, - beg, end); - args->idx++; - } - return args->result == CURLE_OK; -} - -static void schannel_session_free(void *sessionid) -{ - /* this is expected to be called under sessionid lock */ - struct Curl_schannel_cred *cred = sessionid; - - if(cred) { - cred->refcount--; - if(cred->refcount == 0) { - Curl_pSecFn->FreeCredentialsHandle(&cred->cred_handle); - curlx_free(cred->sni_hostname); - if(cred->client_cert_store) { - CertCloseStore(cred->client_cert_store, 0); - cred->client_cert_store = NULL; - } - curlx_safefree(cred); - } - } -} - -static CURLcode schannel_connect_step3(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - SECURITY_STATUS sspi_status = SEC_E_OK; - CERT_CONTEXT *ccert_context = NULL; -#ifdef HAS_ALPN_SCHANNEL - SecPkgContext_ApplicationProtocol alpn_result; -#endif - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - DEBUGASSERT(backend); - - DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %d (step 3/3)", - connssl->peer.hostname, connssl->peer.port)); - - if(!backend->cred) - return CURLE_SSL_CONNECT_ERROR; - - /* check if the required context attributes are met */ - if(backend->ret_flags != backend->req_flags) { - if(!(backend->ret_flags & ISC_RET_SEQUENCE_DETECT)) - failf(data, "schannel: failed to setup sequence detection"); - if(!(backend->ret_flags & ISC_RET_REPLAY_DETECT)) - failf(data, "schannel: failed to setup replay detection"); - if(!(backend->ret_flags & ISC_RET_CONFIDENTIALITY)) - failf(data, "schannel: failed to setup confidentiality"); - if(!(backend->ret_flags & ISC_RET_ALLOCATED_MEMORY)) - failf(data, "schannel: failed to setup memory allocation"); - if(!(backend->ret_flags & ISC_RET_STREAM)) - failf(data, "schannel: failed to setup stream orientation"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef HAS_ALPN_SCHANNEL - if(backend->use_alpn) { - sspi_status = - Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, - SECPKG_ATTR_APPLICATION_PROTOCOL, - &alpn_result); - - if(sspi_status != SEC_E_OK) { - failf(data, "schannel: failed to retrieve ALPN result"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(alpn_result.ProtoNegoStatus == - SecApplicationProtocolNegotiationStatus_Success) { - if(backend->recv_renegotiating && - connssl->negotiated.alpn && - strncmp(connssl->negotiated.alpn, - (const char *)alpn_result.ProtocolId, - alpn_result.ProtocolIdSize)) { - /* Renegotiation selected a different protocol now, we cannot - * deal with this */ - failf(data, "schannel: server selected an ALPN protocol too late"); - return CURLE_SSL_CONNECT_ERROR; - } - Curl_alpn_set_negotiated(cf, data, connssl, alpn_result.ProtocolId, - alpn_result.ProtocolIdSize); - } - else { - if(!backend->recv_renegotiating) - Curl_alpn_set_negotiated(cf, data, connssl, NULL, 0); - } - } -#endif - - /* save the current session data for possible reuse */ - if(Curl_ssl_scache_use(cf, data)) { - Curl_ssl_scache_lock(data); - /* Up ref count since call takes ownership */ - backend->cred->refcount++; - result = Curl_ssl_scache_add_obj(cf, data, connssl->peer.scache_key, - backend->cred, schannel_session_free); - Curl_ssl_scache_unlock(data); - if(result) - return result; - } - - if(data->set.ssl.certinfo) { - int certs_count = 0; - sspi_status = - Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &ccert_context); - - if((sspi_status != SEC_E_OK) || !ccert_context) { - failf(data, "schannel: failed to retrieve remote cert context"); - return CURLE_PEER_FAILED_VERIFICATION; - } - - traverse_cert_store(ccert_context, cert_counter_callback, &certs_count); - if(certs_count > MAX_ALLOWED_CERT_AMOUNT) { - failf(data, "%d certificates is more than allowed (%d)", - certs_count, MAX_ALLOWED_CERT_AMOUNT); - CertFreeCertificateContext(ccert_context); - return CURLE_SSL_CONNECT_ERROR; - } - - result = Curl_ssl_init_certinfo(data, certs_count); - if(!result) { - struct Adder_args args; - args.data = data; - args.idx = 0; - args.certs_count = certs_count; - args.result = CURLE_OK; - traverse_cert_store(ccert_context, add_cert_to_certinfo, &args); - result = args.result; - } - CertFreeCertificateContext(ccert_context); - if(result) - return result; - } - - connssl->connecting_state = ssl_connect_done; - - return CURLE_OK; -} - -static CURLcode schannel_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - CURLcode result; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - - if(ssl_connect_1 == connssl->connecting_state) { - result = schannel_connect_step1(cf, data); - if(result) - return result; - } - - if(ssl_connect_2 == connssl->connecting_state) { - result = schannel_connect_step2(cf, data); - if(result) - return result; - } - - if(ssl_connect_3 == connssl->connecting_state) { - result = schannel_connect_step3(cf, data); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - -#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS /* mingw-w64 v9+. MS SDK 7.0A+. */ - /* When SSPI is used in combination with Schannel - * we need the Schannel context to create the Schannel - * binding to pass the IIS extended protection checks. - * Available on Windows 7 or later. - */ - { - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - DEBUGASSERT(backend); - cf->conn->sslContext = &backend->ctxt->ctxt_handle; - } -#endif - - *done = TRUE; - } - - return CURLE_OK; -} - -enum schannel_renegotiate_caller_t { - SCH_RENEG_CALLER_IS_RECV, - SCH_RENEG_CALLER_IS_SEND -}; - -/* The maximum time we allow for Schannel renegotiation which may in some - rare cases block either due to libcurl (waiting on the socket) or Windows - (waiting on an interactive security prompt). Note Schannel "renegotiation" - is not necessarily literal TLS renegotiation, but means DecryptMessage - returned SEC_I_RENEGOTIATE which means at least the security context needs - to be re-established. */ -#define MAX_RENEG_BLOCK_TIME (60 * 1000) /* 60 seconds in milliseconds */ - -/* This function renegotiates the connection due to a server request received - by schannel_recv. This function returns CURLE_AGAIN if the renegotiation is - incomplete. In that case, we remain in the renegotiation (connecting) stage - and future calls to schannel_recv and schannel_send must call this function - first to complete the renegotiation. */ -static CURLcode schannel_recv_renegotiate( - struct Curl_cfilter *cf, struct Curl_easy *data, - enum schannel_renegotiate_caller_t caller) -{ - CURLcode result; - curl_socket_t sockfd; - struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - struct schannel_renegotiate_state *rs = &backend->renegotiate_state; - - if(!backend || !backend->recv_renegotiating) { - failf(data, "schannel: unexpected call to schannel_recv_renegotiate"); - return CURLE_SSL_CONNECT_ERROR; - } - DEBUGASSERT(caller <= SCH_RENEG_CALLER_IS_SEND); - if(caller == SCH_RENEG_CALLER_IS_RECV) - SCH_DEV(infof(data, "schannel: renegotiation caller is schannel_recv")); - else - SCH_DEV(infof(data, "schannel: renegotiation caller is schannel_send")); - - sockfd = Curl_conn_cf_get_socket(cf, data); - - if(sockfd == CURL_SOCKET_BAD) { - failf(data, "schannel: renegotiation missing socket"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(!rs->started) { /* new renegotiation */ - infof(data, "schannel: renegotiating SSL/TLS connection"); - DEBUGASSERT(connssl->state == ssl_connection_complete); - DEBUGASSERT(connssl->connecting_state == ssl_connect_done); - connssl->state = ssl_connection_negotiating; - connssl->connecting_state = ssl_connect_2; - memset(rs, 0, sizeof(*rs)); - rs->io_need = CURL_SSL_IO_NEED_SEND; - rs->start_time = *Curl_pgrs_now(data); - rs->started = TRUE; - } - - for(;;) { - bool block_read, block_write, blocking, done; - curl_socket_t readfd, writefd; - timediff_t elapsed; - - elapsed = curlx_ptimediff_ms(Curl_pgrs_now(data), &rs->start_time); - if(elapsed >= MAX_RENEG_BLOCK_TIME) { - failf(data, "schannel: renegotiation timeout"); - result = CURLE_SSL_CONNECT_ERROR; - break; - } - - /* the current io_need state may have been overwritten since the last time - this function was called. restore the io_need state needed to continue - the renegotiation. */ - - connssl->io_need = rs->io_need; - - result = schannel_connect(cf, data, &done); - - rs->io_need = connssl->io_need; - - if(!result && !done) - result = CURLE_AGAIN; - - if(result != CURLE_AGAIN) - break; - - readfd = (rs->io_need & CURL_SSL_IO_NEED_RECV) ? sockfd : CURL_SOCKET_BAD; - writefd = (rs->io_need & CURL_SSL_IO_NEED_SEND) ? sockfd : CURL_SOCKET_BAD; - - if(readfd == CURL_SOCKET_BAD && writefd == CURL_SOCKET_BAD) - continue; - - /* connect should not have requested io read and write together */ - DEBUGASSERT(readfd == CURL_SOCKET_BAD || writefd == CURL_SOCKET_BAD); - - /* This function is partially blocking to avoid a stoppage that would - * occur if the user is waiting on the socket only in one direction. - * - * For example, if the user has called recv then they may not be waiting - * for a writable socket and vice versa, so we block to avoid that. - * - * In practice a wait is unlikely to occur. For caller recv if handshake - * data needs to be sent then we block for a writable socket that should - * be writable immediately except for OS resource constraints. For caller - * send if handshake data needs to be received then we block for a readable - * socket, which could take some time, but it is more likely the user has - * called recv since they had called it prior (only recv can start - * renegotiation and probably the user is going to call it again to get - * more of their data before calling send). - */ - - block_read = (caller == SCH_RENEG_CALLER_IS_SEND) ? TRUE : FALSE; - block_write = (caller == SCH_RENEG_CALLER_IS_RECV) ? TRUE : FALSE; - - blocking = (block_read && (readfd != CURL_SOCKET_BAD)) || - (block_write && (writefd != CURL_SOCKET_BAD)); - - SCH_DEV_SHOWBOOL(block_read); - SCH_DEV_SHOWBOOL(block_write); - SCH_DEV_SHOWBOOL(blocking); - - for(;;) { - int what; - timediff_t timeout_ms, remaining; - - result = Curl_pgrsUpdate(data); - if(result) - break; - - elapsed = curlx_ptimediff_ms(Curl_pgrs_now(data), &rs->start_time); - if(elapsed >= MAX_RENEG_BLOCK_TIME) { - failf(data, "schannel: renegotiation timeout"); - result = CURLE_SSL_CONNECT_ERROR; - break; - } - remaining = MAX_RENEG_BLOCK_TIME - elapsed; - - if(blocking) { - timeout_ms = Curl_timeleft_ms(data); - - if(timeout_ms < 0) { - result = CURLE_OPERATION_TIMEDOUT; - break; - } - - /* the blocking is in intervals so that the progress function can be - called every second */ - if(!timeout_ms || timeout_ms > 1000) - timeout_ms = 1000; - - if(timeout_ms > remaining) - timeout_ms = remaining; - } - else - timeout_ms = 0; - - SCH_DEV(infof(data, "schannel: renegotiation wait until socket is" - "%s%s for up to %" FMT_TIMEDIFF_T " ms", - ((readfd != CURL_SOCKET_BAD) ? " readable" : ""), - ((writefd != CURL_SOCKET_BAD) ? " writable" : ""), - timeout_ms)); - - what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, timeout_ms); - - if(what > 0 && (what & (CURL_CSELECT_IN | CURL_CSELECT_OUT))) { - SCH_DEV(infof(data, "schannel: renegotiation socket %s%s", - ((what & CURL_CSELECT_IN) ? "CURL_CSELECT_IN " : ""), - ((what & CURL_CSELECT_OUT) ? "CURL_CSELECT_OUT " : ""))); - result = CURLE_AGAIN; - break; - } - else if(!what) { - SCH_DEV(infof(data, "schannel: renegotiation socket timeout")); - if(blocking) - continue; - else - return CURLE_AGAIN; - } - - failf(data, "schannel: socket error during renegotiation"); - result = CURLE_SSL_CONNECT_ERROR; - break; - } - if(result != CURLE_AGAIN) - break; - } - - DEBUGASSERT(result != CURLE_AGAIN); - - rs->started = FALSE; - backend->recv_renegotiating = FALSE; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - - if(result) - failf(data, "schannel: renegotiation failed"); - else - infof(data, "schannel: SSL/TLS connection renegotiated"); - - return result; -} - -static CURLcode schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *buf, size_t len, size_t *pnwritten) -{ - size_t data_len = 0; - unsigned char *ptr = NULL; - struct ssl_connect_data *connssl = cf->ctx; - SecBuffer outbuf[4]; - SecBufferDesc outbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - CURLcode result = CURLE_OK; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - - DEBUGASSERT(backend); - *pnwritten = 0; - - if(backend->recv_renegotiating) { - result = schannel_recv_renegotiate(cf, data, SCH_RENEG_CALLER_IS_SEND); - if(result) - return result; - } - - /* check if the maximum stream sizes were queried */ - if(backend->stream_sizes.cbMaximumMessage == 0) { - sspi_status = Curl_pSecFn->QueryContextAttributes( - &backend->ctxt->ctxt_handle, - SECPKG_ATTR_STREAM_SIZES, - &backend->stream_sizes); - if(sspi_status != SEC_E_OK) { - return CURLE_SEND_ERROR; - } - } - - /* check if the buffer is longer than the maximum message length */ - if(len > backend->stream_sizes.cbMaximumMessage) { - len = backend->stream_sizes.cbMaximumMessage; - } - - /* calculate the complete message length and allocate a buffer for it */ - data_len = backend->stream_sizes.cbHeader + len + - backend->stream_sizes.cbTrailer; - ptr = (unsigned char *)curlx_malloc(data_len); - if(!ptr) { - return CURLE_OUT_OF_MEMORY; - } - - /* setup output buffers (header, data, trailer, empty) */ - InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER, - ptr, backend->stream_sizes.cbHeader); - InitSecBuffer(&outbuf[1], SECBUFFER_DATA, - ptr + backend->stream_sizes.cbHeader, curlx_uztoul(len)); - InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER, - ptr + backend->stream_sizes.cbHeader + len, - backend->stream_sizes.cbTrailer); - InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, outbuf, 4); - - /* copy data into output buffer */ - memcpy(outbuf[1].pvBuffer, buf, len); - - /* https://learn.microsoft.com/windows/win32/api/sspi/nf-sspi-encryptmessage */ - sspi_status = Curl_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0, - &outbuf_desc, 0); - - /* check if the message was encrypted */ - if(sspi_status == SEC_E_OK) { - - /* send the encrypted message including header, data and trailer */ - len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer; - - /* - it is important to send the full message which includes the header, - encrypted payload, and trailer. Until the client receives all the - data a coherent message has not been delivered and the client - cannot read any of it. - - If we wanted to buffer the unwritten encrypted bytes, we would - tell the client that all data it has requested to be sent has been - sent. The unwritten encrypted bytes would be the first bytes to - send on the next invocation. - Here's the catch with this - if we tell the client that all the - bytes have been sent, does the client call this method again to - send the buffered data? Looking at who calls this function, it - seems the answer is NO. - */ - - /* send entire message or fail */ - while(len > *pnwritten) { - size_t this_write = 0; - int what; - timediff_t timeout_ms = Curl_timeleft_ms(data); - if(timeout_ms < 0) { - /* we already got the timeout */ - failf(data, "schannel: timed out sending data (bytes sent: %zu)", - *pnwritten); - result = CURLE_OPERATION_TIMEDOUT; - break; - } - else if(!timeout_ms) - timeout_ms = TIMEDIFF_T_MAX; - what = SOCKET_WRITABLE(Curl_conn_cf_get_socket(cf, data), timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - result = CURLE_SEND_ERROR; - break; - } - else if(what == 0) { - failf(data, "schannel: timed out sending data (bytes sent: %zu)", - *pnwritten); - result = CURLE_OPERATION_TIMEDOUT; - break; - } - /* socket is writable */ - - result = Curl_conn_cf_send(cf->next, data, - (const uint8_t *)ptr + *pnwritten, - len - *pnwritten, - FALSE, &this_write); - if(result == CURLE_AGAIN) - continue; - else if(result) { - break; - } - - *pnwritten += this_write; - } - } - else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) { - result = CURLE_OUT_OF_MEMORY; - } - else { - result = CURLE_SEND_ERROR; - } - - curlx_safefree(ptr); - - if(len == *pnwritten) - /* Encrypted message including header, data and trailer entirely sent. - The return value is the number of unencrypted bytes that were sent. */ - *pnwritten = outbuf[1].cbBuffer; - - return result; -} - -static CURLcode schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread) -{ - size_t size = 0; - size_t nread = 0; - struct ssl_connect_data *connssl = cf->ctx; - SecBuffer inbuf[4]; - SecBufferDesc inbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - - DEBUGASSERT(backend); - *pnread = 0; - - if(backend->recv_renegotiating) { - result = schannel_recv_renegotiate(cf, data, SCH_RENEG_CALLER_IS_RECV); - if(result) - return result; - } - - /**************************************************************************** - * Do not return or set backend->recv_unrecoverable_err unless in the - * cleanup. The pattern for return error is set *err, optional infof, goto - * cleanup. - * - * Some verbose debug messages are wrapped by SCH_DEV() instead of DEBUGF() - * and only shown if CURL_SCHANNEL_DEV_DEBUG was defined at build time. These - * messages are extra verbose and intended for curl developers debugging - * Schannel recv decryption. - * - * Our priority is to always return as much decrypted data to the caller as - * possible, even if an error occurs. The state of the decrypted buffer must - * always be valid. Transfer of decrypted data to the caller's buffer is - * handled in the cleanup. - */ - - SCH_DEV(infof(data, "schannel: client wants to read %zu bytes", len)); - - if(len && len <= backend->decdata.offset) { - SCH_DEV(infof(data, - "schannel: enough decrypted data is already available")); - goto cleanup; - } - else if(backend->recv_unrecoverable_err) { - result = backend->recv_unrecoverable_err; - infof(data, "schannel: an unrecoverable error occurred in a prior call"); - goto cleanup; - } - else if(backend->recv_sspi_close_notify) { - /* once a server has indicated shutdown there is no more encrypted data */ - infof(data, "schannel: server indicated shutdown in a prior call"); - goto cleanup; - } - /* it is debatable what to return when !len. Regardless we cannot return - immediately because there may be data to decrypt (in the case we want to - decrypt all encrypted cached data) so handle !len later in cleanup. - */ - else if(len && !backend->recv_connection_closed) { - /* the encrypted buffer must be large enough to hold all the bytes - requested and some TLS record overhead. 'len' is a buffer size, so this - integer math cannot overflow. */ - const size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE; - - /* make sure encrypt buffer fits the requested amount of data */ - result = ensure_encoding_size(data, &backend->encdata, min_encdata_length); - if(result) - goto cleanup; - - SCH_DEV(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu", - backend->encdata.offset, backend->encdata.length)); - - /* read encrypted data from socket */ - result = Curl_conn_cf_recv(cf->next, data, - (char *)(backend->encdata.buffer + - backend->encdata.offset), - backend->encdata.length - - backend->encdata.offset, - &nread); - if(result) { - if(result == CURLE_AGAIN) - SCH_DEV(infof(data, "schannel: recv returned CURLE_AGAIN")); - else { - infof(data, "schannel: recv returned error %d", result); - backend->recv_unrecoverable_err = result; - } - } - else if(nread == 0) { - backend->recv_connection_closed = TRUE; - DEBUGF(infof(data, "schannel: server closed the connection")); - } - else { - backend->encdata.offset += nread; - backend->encdata_is_incomplete = FALSE; - SCH_DEV(infof(data, "schannel: encrypted data got %zu", nread)); - } - } - - SCH_DEV(infof(data, "schannel: encrypted data buffer: offset %zu length %zu", - backend->encdata.offset, backend->encdata.length)); - - /* decrypt loop */ - while(backend->encdata.offset > 0 && sspi_status == SEC_E_OK && - (!len || backend->decdata.offset < len || - backend->recv_connection_closed)) { - /* prepare data buffer for DecryptMessage call */ - InitSecBuffer(&inbuf[0], SECBUFFER_DATA, backend->encdata.buffer, - curlx_uztoul(backend->encdata.offset)); - - /* we need 3 more empty input buffers for possible output */ - InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0); - InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0); - InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, inbuf, 4); - - /* https://learn.microsoft.com/windows/win32/api/sspi/nf-sspi-decryptmessage - */ - sspi_status = Curl_pSecFn->DecryptMessage(&backend->ctxt->ctxt_handle, - &inbuf_desc, 0, NULL); - - /* check if everything went fine (server may want to renegotiate - or shutdown the connection context) */ - if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE || - sspi_status == SEC_I_CONTEXT_EXPIRED) { - /* check for successfully decrypted data, even before actual - renegotiation or shutdown of the connection context */ - if(inbuf[1].BufferType == SECBUFFER_DATA) { - SCH_DEV(infof(data, "schannel: decrypted data length: %lu", - inbuf[1].cbBuffer)); - - /* ensure the decode buffer fits the received amount of data */ - result = ensure_decoding_size(data, &backend->decdata, - inbuf[1].cbBuffer, len); - if(result) - goto cleanup; - - /* copy decrypted data to internal buffer */ - size = inbuf[1].cbBuffer; - if(size) { - memcpy(backend->decdata.buffer + backend->decdata.offset, - inbuf[1].pvBuffer, size); - backend->decdata.offset += size; - } - - SCH_DEV(infof(data, "schannel: decrypted data added: %zu", size)); - SCH_DEV(infof(data, - "schannel: decrypted cached: offset %zu length %zu", - backend->decdata.offset, backend->decdata.length)); - } - - /* check for remaining encrypted data */ - if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { - SCH_DEV(infof(data, "schannel: encrypted data length: %lu", - inbuf[3].cbBuffer)); - - /* check if the remaining data is less than the total amount - * and therefore begins after the already processed data - */ - if(backend->encdata.offset > inbuf[3].cbBuffer) { - /* move remaining encrypted data forward to the beginning of - buffer */ - memmove(backend->encdata.buffer, - (backend->encdata.buffer + backend->encdata.offset) - - inbuf[3].cbBuffer, inbuf[3].cbBuffer); - backend->encdata.offset = inbuf[3].cbBuffer; - } - - SCH_DEV(infof(data, - "schannel: encrypted cached: offset %zu length %zu", - backend->encdata.offset, backend->encdata.length)); - } - else { - /* reset encrypted buffer offset, because there is no data remaining */ - backend->encdata.offset = 0; - } - - /* check if server wants to renegotiate the connection context */ - if(sspi_status == SEC_I_RENEGOTIATE) { - infof(data, "schannel: remote party requests renegotiation"); - if(result && result != CURLE_AGAIN) { - infof(data, "schannel: cannot renegotiate, an error is pending"); - goto cleanup; - } - - backend->recv_renegotiating = TRUE; - result = schannel_recv_renegotiate(cf, data, SCH_RENEG_CALLER_IS_RECV); - if(result) - goto cleanup; - - /* now retry receiving data */ - sspi_status = SEC_E_OK; - continue; - } - /* check if the server closed the connection */ - else if(sspi_status == SEC_I_CONTEXT_EXPIRED) { - /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not - returned so we have to work around that in cleanup. */ - backend->recv_sspi_close_notify = TRUE; - if(!backend->recv_connection_closed) - backend->recv_connection_closed = TRUE; - /* We received the close notify fine, any error we got - * from the lower filters afterwards (e.g. the socket), is not - * an error on the TLS data stream. That one ended here. */ - if(result == CURLE_RECV_ERROR) - result = CURLE_OK; - infof(data, - "schannel: server close notification received (close_notify)"); - goto cleanup; - } - } - else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { - backend->encdata_is_incomplete = TRUE; - if(!result) - result = CURLE_AGAIN; - SCH_DEV(infof(data, "schannel: failed to decrypt data, need more data")); - goto cleanup; - } - else { - char buffer[STRERROR_LEN]; - failf(data, "schannel: failed to read data from server: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - result = CURLE_RECV_ERROR; - goto cleanup; - } - } - - SCH_DEV(infof(data, "schannel: encrypted data buffer: offset %zu length %zu", - backend->encdata.offset, backend->encdata.length)); - - SCH_DEV(infof(data, "schannel: decrypted data buffer: offset %zu length %zu", - backend->decdata.offset, backend->decdata.length)); - -cleanup: - /* Warning- there is no guarantee the encdata state is valid at this point */ - SCH_DEV(infof(data, "schannel: schannel_recv cleanup")); - - /* Error if the connection has closed without a close_notify. - - The behavior here is a matter of debate. We do not want to be vulnerable - to a truncation attack however there is some browser precedent for - ignoring the close_notify for compatibility reasons. - */ - if(len && !backend->decdata.offset && backend->recv_connection_closed && - !backend->recv_sspi_close_notify) { - result = CURLE_RECV_ERROR; - failf(data, "schannel: server closed abruptly (missing close_notify)"); - } - - /* Any error other than CURLE_AGAIN is an unrecoverable error. */ - if(result && result != CURLE_AGAIN) - backend->recv_unrecoverable_err = result; - - size = len < backend->decdata.offset ? len : backend->decdata.offset; - if(size) { - memcpy(buf, backend->decdata.buffer, size); - memmove(backend->decdata.buffer, backend->decdata.buffer + size, - backend->decdata.offset - size); - backend->decdata.offset -= size; - SCH_DEV(infof(data, "schannel: decrypted data returned %zu", size)); - SCH_DEV(infof(data, - "schannel: decrypted data buffer: offset %zu length %zu", - backend->decdata.offset, backend->decdata.length)); - *pnread = size; - return CURLE_OK; - } - - if(!result && !backend->recv_connection_closed) - result = CURLE_AGAIN; - - /* it is debatable what to return when !len. We could return whatever error - we got from decryption but instead we override here so the return is - consistent. - */ - if(!len) - return CURLE_OK; - - return result; -} - -static bool schannel_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - const struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - - (void)data; - DEBUGASSERT(backend); - - if(backend->ctxt) /* SSL/TLS is in use */ - return backend->decdata.offset > 0 || - (backend->encdata.offset > 0 && !backend->encdata_is_incomplete) || - backend->recv_connection_closed || - backend->recv_sspi_close_notify || - backend->recv_unrecoverable_err; - else - return FALSE; -} - -/* shut down the SSL connection and clean up related memory. - this function can be called multiple times on the same connection including - if the SSL connection failed (eg connection made but failed handshake). */ -static CURLcode schannel_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool send_shutdown, bool *done) -{ - /* See https://learn.microsoft.com/windows/win32/secauthn/shutting-down-an-schannel-connection - * Shutting Down an Schannel Connection - */ - struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - CURLcode result = CURLE_OK; - - if(cf->shutdown) { - *done = TRUE; - return CURLE_OK; - } - - DEBUGASSERT(data); - DEBUGASSERT(backend); - - /* Not supported in schannel */ - (void)send_shutdown; - - *done = FALSE; - if(backend->ctxt) { - infof(data, "schannel: shutting down SSL/TLS connection with %s port %d", - connssl->peer.hostname, connssl->peer.port); - } - - if(!backend->ctxt || cf->shutdown) { - *done = TRUE; - goto out; - } - - if(backend->cred && backend->ctxt && !backend->sent_shutdown) { - SecBufferDesc BuffDesc; - SecBuffer Buffer; - SECURITY_STATUS sspi_status; - SecBuffer outbuf; - SecBufferDesc outbuf_desc; - DWORD dwshut = SCHANNEL_SHUTDOWN; - - InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut)); - InitSecBufferDesc(&BuffDesc, &Buffer, 1); - - sspi_status = Curl_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle, - &BuffDesc); - - if(sspi_status != SEC_E_OK) { - char buffer[STRERROR_LEN]; - failf(data, "schannel: ApplyControlToken failure: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - result = CURLE_SEND_ERROR; - goto out; - } - - /* setup output buffer */ - InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, &outbuf, 1); - - sspi_status = Curl_pSecFn->InitializeSecurityContext( - &backend->cred->cred_handle, - &backend->ctxt->ctxt_handle, - backend->cred->sni_hostname, - backend->req_flags, - 0, - 0, - NULL, - 0, - &backend->ctxt->ctxt_handle, - &outbuf_desc, - &backend->ret_flags, NULL); - - if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { - /* send close message which is in output buffer */ - size_t written; - - result = Curl_conn_cf_send(cf->next, data, - (const uint8_t *)outbuf.pvBuffer, - outbuf.cbBuffer, - FALSE, &written); - Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer); - if(!result) { - if(written < outbuf.cbBuffer) { - result = CURLE_SEND_ERROR; - failf(data, "schannel: failed to send close msg: %s" - " (bytes written: %zu)", curl_easy_strerror(result), written); - goto out; - } - backend->sent_shutdown = TRUE; - *done = TRUE; - } - else if(result == CURLE_AGAIN) { - connssl->io_need = CURL_SSL_IO_NEED_SEND; - result = CURLE_OK; - goto out; - } - else { - if(!backend->recv_connection_closed) { - result = CURLE_SEND_ERROR; - failf(data, "schannel: error sending close msg: %d", result); - goto out; - } - /* Looks like server already closed the connection. - * An error to send our close notify is not a failure. */ - *done = TRUE; - result = CURLE_OK; - } - } - } - - /* If the connection seems open and we have not seen the close notify - * from the server yet, try to receive it. */ - if(backend->cred && backend->ctxt && - !backend->recv_sspi_close_notify && !backend->recv_connection_closed) { - char buffer[1024]; - size_t nread; - - result = schannel_recv(cf, data, buffer, sizeof(buffer), &nread); - if(result == CURLE_AGAIN) { - connssl->io_need = CURL_SSL_IO_NEED_RECV; - } - else if(result) { - CURL_TRC_CF(data, cf, "SSL shutdown, error %d", result); - result = CURLE_RECV_ERROR; - } - else if(nread == 0) { - /* We got the close notify alert and are done. */ - backend->recv_connection_closed = TRUE; - *done = TRUE; - } - else { - /* still data coming in? */ - } - } - -out: - cf->shutdown = (result || *done); - return result; -} - -static void schannel_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - - DEBUGASSERT(data); - DEBUGASSERT(backend); - - /* free SSPI Schannel API security context handle */ - if(backend->ctxt) { - DEBUGF(infof(data, "schannel: clear security context handle")); - Curl_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle); - curlx_safefree(backend->ctxt); - } - - /* free SSPI Schannel API credential handle */ - if(backend->cred) { - Curl_ssl_scache_lock(data); - schannel_session_free(backend->cred); - Curl_ssl_scache_unlock(data); - backend->cred = NULL; - } - - /* free internal buffer for received encrypted data */ - if(backend->encdata.buffer) { - curlx_safefree(backend->encdata.buffer); - backend->encdata.length = 0; - backend->encdata.offset = 0; - backend->encdata_is_incomplete = FALSE; - } - - /* free internal buffer for received decrypted data */ - if(backend->decdata.buffer) { - curlx_safefree(backend->decdata.buffer); - backend->decdata.length = 0; - backend->decdata.offset = 0; - } -} - -static int schannel_init(void) -{ -#ifdef HAS_ALPN_SCHANNEL - typedef const char *(APIENTRY *WINE_GET_VERSION_FN)(void); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-function-type-strict" -#endif - WINE_GET_VERSION_FN p_wine_get_version = - CURLX_FUNCTION_CAST(WINE_GET_VERSION_FN, - GetProcAddress(GetModuleHandle(TEXT("ntdll")), "wine_get_version")); -#if defined(__clang__) && __clang_major__ >= 16 -#pragma clang diagnostic pop -#endif - if(p_wine_get_version) { /* WINE detected */ - curl_off_t ver = 0; - const char *wine_version = p_wine_get_version(); /* e.g. "6.0.2" */ - /* Assume ALPN support with WINE 6.0 or upper */ - if(wine_version) - curlx_str_number(&wine_version, &ver, 20); - s_win_has_alpn = (ver >= 6); - } - else { - /* ALPN is supported on Windows 8.1 / Server 2012 R2 and above. */ - s_win_has_alpn = curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL); - } -#endif /* HAS_ALPN_SCHANNEL */ - - return Curl_sspi_global_init() == CURLE_OK ? 1 : 0; -} - -static void schannel_cleanup(void) -{ - Curl_sspi_global_cleanup(); -} - -static size_t schannel_version(char *buffer, size_t size) -{ - return curl_msnprintf(buffer, size, "Schannel"); -} - -static CURLcode schannel_random(struct Curl_easy *data, - unsigned char *entropy, size_t length) -{ - (void)data; - - return Curl_win32_random(entropy, length); -} - -static void schannel_checksum(const unsigned char *input, - size_t inputlen, - unsigned char *checksum, - size_t checksumlen, - DWORD provType, - const unsigned int algId) -{ - HCRYPTPROV hProv = 0; - HCRYPTHASH hHash = 0; - - /* since this can fail in multiple ways, zero memory first so we never - * return old data - */ - memset(checksum, 0, checksumlen); - - if(!CryptAcquireContext(&hProv, NULL, NULL, provType, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return; /* failed */ - - do { - DWORD cbHashSize = 0; - DWORD dwHashSizeLen = (DWORD)sizeof(cbHashSize); - DWORD dwChecksumLen = (DWORD)checksumlen; - - if(!CryptCreateHash(hProv, algId, 0, 0, &hHash)) - break; /* failed */ - - if(!CryptHashData(hHash, input, (DWORD)inputlen, 0)) - break; /* failed */ - - /* get hash size */ - if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&cbHashSize, - &dwHashSizeLen, 0)) - break; /* failed */ - - /* check hash size */ - if(checksumlen < cbHashSize) - break; /* failed */ - - if(CryptGetHashParam(hHash, HP_HASHVAL, checksum, &dwChecksumLen, 0)) - break; /* failed */ - } while(0); - - if(hHash) - CryptDestroyHash(hHash); - - if(hProv) - CryptReleaseContext(hProv, 0); -} - -static CURLcode schannel_sha256sum(const unsigned char *input, - size_t inputlen, - unsigned char *sha256sum, - size_t sha256len) -{ - schannel_checksum(input, inputlen, sha256sum, sha256len, - PROV_RSA_AES, CALG_SHA_256); - return CURLE_OK; -} - -static void *schannel_get_internals(struct ssl_connect_data *connssl, - CURLINFO info) -{ - struct schannel_ssl_backend_data *backend = - (struct schannel_ssl_backend_data *)connssl->backend; - (void)info; - DEBUGASSERT(backend); - return &backend->ctxt->ctxt_handle; -} - -HCERTSTORE Curl_schannel_get_cached_cert_store(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_multi *multi = data->multi; - const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; - struct schannel_cert_share *share; - const struct ssl_general_config *cfg = &data->set.general_ssl; - timediff_t timeout_ms; - unsigned char info_blob_digest[CURL_SHA256_DIGEST_LENGTH]; - - DEBUGASSERT(multi); - - if(!multi) { - return NULL; - } - - share = Curl_hash_pick(&multi->proto_hash, - CURL_UNCONST(MPROTO_SCHANNEL_CERT_SHARE_KEY), - sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY) - 1); - if(!share || !share->cert_store) { - return NULL; - } - - /* zero ca_cache_timeout completely disables caching */ - if(!cfg->ca_cache_timeout) { - return NULL; - } - - /* check for cache timeout by using the cached_x509_store_expired timediff - calculation pattern from openssl.c. - negative timeout means retain forever. */ - timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000; - if(timeout_ms >= 0) { - timediff_t elapsed_ms = - curlx_ptimediff_ms(Curl_pgrs_now(data), &share->time); - if(elapsed_ms >= timeout_ms) { - return NULL; - } - } - - if(ca_info_blob) { - if(share->CAinfo_blob_size != ca_info_blob->len) { - return NULL; - } - schannel_sha256sum((const unsigned char *)ca_info_blob->data, - ca_info_blob->len, - info_blob_digest, - CURL_SHA256_DIGEST_LENGTH); - if(memcmp(share->CAinfo_blob_digest, info_blob_digest, - CURL_SHA256_DIGEST_LENGTH)) { - return NULL; - } - } - else { - if(!conn_config->CAfile || !share->CAfile || - strcmp(share->CAfile, conn_config->CAfile)) { - return NULL; - } - } - - return share->cert_store; -} - -static void schannel_cert_share_free(void *key, size_t key_len, void *p) -{ - struct schannel_cert_share *share = p; - DEBUGASSERT(key_len == (sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY) - 1)); - DEBUGASSERT(!memcmp(MPROTO_SCHANNEL_CERT_SHARE_KEY, key, key_len)); - (void)key; - (void)key_len; - if(share->cert_store) { - CertCloseStore(share->cert_store, 0); - } - curlx_free(share->CAfile); - curlx_free(share); -} - -bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - HCERTSTORE cert_store) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_multi *multi = data->multi; - const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; - struct schannel_cert_share *share; - size_t CAinfo_blob_size = 0; - char *CAfile = NULL; - - DEBUGASSERT(multi); - - if(!multi) { - return FALSE; - } - - share = Curl_hash_pick(&multi->proto_hash, - CURL_UNCONST(MPROTO_SCHANNEL_CERT_SHARE_KEY), - sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY) - 1); - if(!share) { - share = curlx_calloc(1, sizeof(*share)); - if(!share) { - return FALSE; - } - if(!Curl_hash_add2(&multi->proto_hash, - CURL_UNCONST(MPROTO_SCHANNEL_CERT_SHARE_KEY), - sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY) - 1, - share, schannel_cert_share_free)) { - curlx_free(share); - return FALSE; - } - } - - if(ca_info_blob) { - schannel_sha256sum((const unsigned char *)ca_info_blob->data, - ca_info_blob->len, - share->CAinfo_blob_digest, - CURL_SHA256_DIGEST_LENGTH); - CAinfo_blob_size = ca_info_blob->len; - } - else { - if(conn_config->CAfile) { - CAfile = curlx_strdup(conn_config->CAfile); - if(!CAfile) { - return FALSE; - } - } - } - - /* free old cache data */ - if(share->cert_store) { - CertCloseStore(share->cert_store, 0); - } - curlx_free(share->CAfile); - - share->time = curlx_now(); - share->cert_store = cert_store; - share->CAinfo_blob_size = CAinfo_blob_size; - share->CAfile = CAfile; - return TRUE; -} - -const struct Curl_ssl Curl_ssl_schannel = { - { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ - - SSLSUPP_CERTINFO | - SSLSUPP_CAINFO_BLOB | - SSLSUPP_PINNEDPUBKEY | - SSLSUPP_CA_CACHE | - SSLSUPP_HTTPS_PROXY | - SSLSUPP_CIPHER_LIST, - - sizeof(struct schannel_ssl_backend_data), - - schannel_init, /* init */ - schannel_cleanup, /* cleanup */ - schannel_version, /* version */ - schannel_shutdown, /* shutdown */ - schannel_data_pending, /* data_pending */ - schannel_random, /* random */ - NULL, /* cert_status_request */ - schannel_connect, /* connect */ - Curl_ssl_adjust_pollset, /* adjust_pollset */ - schannel_get_internals, /* get_internals */ - schannel_close, /* close_one */ - NULL, /* close_all */ - NULL, /* set_engine */ - NULL, /* set_engine_default */ - NULL, /* engines_list */ - schannel_sha256sum, /* sha256sum */ - schannel_recv, /* recv decrypted data */ - schannel_send, /* send data to encrypt */ - NULL, /* get_channel_binding */ -}; - -#endif /* USE_SCHANNEL */ diff --git a/vendor/curl/lib/vtls/schannel.h b/vendor/curl/lib/vtls/schannel.h deleted file mode 100644 index fe49e9a9d..000000000 --- a/vendor/curl/lib/vtls/schannel.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef HEADER_CURL_SCHANNEL_H -#define HEADER_CURL_SCHANNEL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Marc Hoersken, , et al. - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SCHANNEL - -#include - -#include "curl_sspi.h" -#include "cfilters.h" -#include "urldata.h" - -extern const struct Curl_ssl Curl_ssl_schannel; - -CURLcode Curl_verify_host(struct Curl_cfilter *cf, struct Curl_easy *data); - -CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, - struct Curl_easy *data); - -#endif /* USE_SCHANNEL */ -#endif /* HEADER_CURL_SCHANNEL_H */ diff --git a/vendor/curl/lib/vtls/schannel_int.h b/vendor/curl/lib/vtls/schannel_int.h deleted file mode 100644 index 496635f2c..000000000 --- a/vendor/curl/lib/vtls/schannel_int.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef HEADER_CURL_SCHANNEL_INT_H -#define HEADER_CURL_SCHANNEL_INT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Marc Hoersken, , et al. - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SCHANNEL - -#include "vtls/vtls.h" -#include "curl_sha256.h" - -#if defined(_MSC_VER) && (_MSC_VER < 1700) -/* Workaround for warning: - 'type cast' : conversion from 'int' to 'LPCSTR' of greater size */ -#undef CERT_STORE_PROV_MEMORY -#undef CERT_STORE_PROV_SYSTEM_A -#undef CERT_STORE_PROV_SYSTEM_W -#define CERT_STORE_PROV_MEMORY ((LPCSTR)(size_t)2) -#define CERT_STORE_PROV_SYSTEM_A ((LPCSTR)(size_t)9) -#define CERT_STORE_PROV_SYSTEM_W ((LPCSTR)(size_t)10) -#endif - -/* Offered by mingw-w64 v8+, MS SDK ~10+/~VS2022+ */ -#ifndef SCH_CREDENTIALS_VERSION -#define SCH_CREDENTIALS_VERSION 0x00000005 - -typedef enum _eTlsAlgorithmUsage { - TlsParametersCngAlgUsageKeyExchange, - TlsParametersCngAlgUsageSignature, - TlsParametersCngAlgUsageCipher, - TlsParametersCngAlgUsageDigest, - TlsParametersCngAlgUsageCertSig -} eTlsAlgorithmUsage; - -/* !checksrc! disable TYPEDEFSTRUCT 1 */ -typedef struct _CRYPTO_SETTINGS { - eTlsAlgorithmUsage eAlgorithmUsage; - UNICODE_STRING strCngAlgId; - DWORD cChainingModes; - PUNICODE_STRING rgstrChainingModes; /* spellchecker:disable-line */ - DWORD dwMinBitLength; - DWORD dwMaxBitLength; -} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS; - -/* !checksrc! disable TYPEDEFSTRUCT 1 */ -typedef struct _TLS_PARAMETERS { - DWORD cAlpnIds; - PUNICODE_STRING rgstrAlpnIds; /* spellchecker:disable-line */ - DWORD grbitDisabledProtocols; - DWORD cDisabledCrypto; - PCRYPTO_SETTINGS pDisabledCrypto; - DWORD dwFlags; -} TLS_PARAMETERS, * PTLS_PARAMETERS; - -/* !checksrc! disable TYPEDEFSTRUCT 1 */ -typedef struct _SCH_CREDENTIALS { - DWORD dwVersion; - DWORD dwCredFormat; - DWORD cCreds; - PCCERT_CONTEXT* paCred; - HCERTSTORE hRootStore; - - DWORD cMappers; - struct _HMAPPER **aphMappers; - - DWORD dwSessionLifespan; - DWORD dwFlags; - DWORD cTlsParameters; - PTLS_PARAMETERS pTlsParameters; -} SCH_CREDENTIALS, * PSCH_CREDENTIALS; - -#endif /* SCH_CREDENTIALS_VERSION */ - -struct Curl_schannel_cred { - CredHandle cred_handle; - TCHAR *sni_hostname; - HCERTSTORE client_cert_store; - int refcount; -}; - -struct Curl_schannel_ctxt { - CtxtHandle ctxt_handle; -}; - -/* handle encoding/decoding buffers */ -struct sbuffer { - size_t length; - size_t offset; - unsigned char *buffer; -}; - -struct schannel_ssl_backend_data { - struct sbuffer encdata; - struct sbuffer decdata; - struct Curl_schannel_cred *cred; - struct Curl_schannel_ctxt *ctxt; - SecPkgContext_StreamSizes stream_sizes; - unsigned long req_flags, ret_flags; - CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */ - struct schannel_renegotiate_state { - bool started; - struct curltime start_time; - int io_need; - } renegotiate_state; - BIT(recv_sspi_close_notify); /* true if connection closed by close_notify */ - BIT(recv_connection_closed); /* true if connection closed, regardless how */ - BIT(recv_renegotiating); /* true if recv is doing renegotiation */ - BIT(use_alpn); /* true if ALPN is used for this connection */ - BIT(use_manual_cred_validation); /* true if manual cred validation is used */ - BIT(sent_shutdown); - /* encdata_is_incomplete: if encdata contains only a partial record that - cannot be decrypted without another recv() (that is, status is - SEC_E_INCOMPLETE_MESSAGE) then set this true. after recv() adds more - bytes into encdata then set this back to false. */ - BIT(encdata_is_incomplete); -}; - -struct schannel_cert_share { - unsigned char CAinfo_blob_digest[CURL_SHA256_DIGEST_LENGTH]; - size_t CAinfo_blob_size; /* CA info blob size */ - char *CAfile; /* CAfile path used to generate - certificate store */ - HCERTSTORE cert_store; /* cached certificate store or - NULL if none */ - struct curltime time; /* when the cached store was created */ -}; - -/* -* size of the structure: 20 bytes. -*/ -struct num_ip_data { - DWORD size; /* 04 bytes */ - union { - struct in_addr ia; /* 04 bytes */ - struct in6_addr ia6; /* 16 bytes */ - } bData; -}; - -HCERTSTORE Curl_schannel_get_cached_cert_store(struct Curl_cfilter *cf, - struct Curl_easy *data); - -bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - HCERTSTORE cert_store); - -#endif /* USE_SCHANNEL */ -#endif /* HEADER_CURL_SCHANNEL_INT_H */ diff --git a/vendor/curl/lib/vtls/schannel_verify.c b/vendor/curl/lib/vtls/schannel_verify.c deleted file mode 100644 index 9be6fe311..000000000 --- a/vendor/curl/lib/vtls/schannel_verify.c +++ /dev/null @@ -1,860 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Marc Hoersken, - * Copyright (C) Mark Salisbury, - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Source file for Schannel-specific certificate verification. This code should - * only be invoked by code in schannel.c. - */ -#include "curl_setup.h" - -#ifdef USE_SCHANNEL - -#ifndef USE_WINDOWS_SSPI -#error "cannot compile Schannel support without SSPI." -#endif - -#include "vtls/schannel.h" -#include "vtls/schannel_int.h" - -#include "vtls/hostcheck.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" -#include "curl_trc.h" -#include "strerror.h" -#include "curlx/fopen.h" -#include "curlx/inet_pton.h" -#include "curlx/multibyte.h" -#include "curlx/version_win32.h" -#include "curlx/winapi.h" - -#define BACKEND ((struct schannel_ssl_backend_data *)connssl->backend) - -#define MAX_CAFILE_SIZE (1024 * 1024) /* 1 MiB */ -#define BEGIN_CERT "-----BEGIN CERTIFICATE-----" -#define END_CERT "\n-----END CERTIFICATE-----" - -struct cert_chain_engine_config_win8 { - DWORD cbSize; - HCERTSTORE hRestrictedRoot; - HCERTSTORE hRestrictedTrust; - HCERTSTORE hRestrictedOther; - DWORD cAdditionalStore; - HCERTSTORE *rghAdditionalStore; - DWORD dwFlags; - DWORD dwUrlRetrievalTimeout; - DWORD MaximumCachedCertificates; - DWORD CycleDetectionModulus; - HCERTSTORE hExclusiveRoot; - HCERTSTORE hExclusiveTrustedPeople; - DWORD dwExclusiveFlags; -}; - -/* Offered by mingw-w64 v4+. MS SDK ~10+/~VS2017+. */ -#ifndef CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG -#define CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG 0x00000001 -#endif - -/* Legacy structure to supply size to Win7 clients */ -struct cert_chain_engine_config_win7 { - DWORD cbSize; - HCERTSTORE hRestrictedRoot; - HCERTSTORE hRestrictedTrust; - HCERTSTORE hRestrictedOther; - DWORD cAdditionalStore; - HCERTSTORE *rghAdditionalStore; - DWORD dwFlags; - DWORD dwUrlRetrievalTimeout; - DWORD MaximumCachedCertificates; - DWORD CycleDetectionModulus; - HCERTSTORE hExclusiveRoot; - HCERTSTORE hExclusiveTrustedPeople; -}; - -static int is_cr_or_lf(char c) -{ - return c == '\r' || c == '\n'; -} - -/* Search the substring needle,needlelen into string haystack,haystacklen - * Strings do not need to be terminated by a '\0'. - * Similar of macOS/Linux memmem (not available on Visual Studio). - * Return position of beginning of first occurrence or NULL if not found - */ -static const char *c_memmem(const void *haystack, size_t haystacklen, - const void *needle, size_t needlelen) -{ - const char *p; - char first; - const char *str_limit = (const char *)haystack + haystacklen; - if(!needlelen || needlelen > haystacklen) - return NULL; - first = *(const char *)needle; - for(p = (const char *)haystack; p <= (str_limit - needlelen); p++) - if(((*p) == first) && (memcmp(p, needle, needlelen) == 0)) - return p; - - return NULL; -} - -static CURLcode add_certs_data_to_store(HCERTSTORE trust_store, - const char *ca_buffer, - size_t ca_buffer_size, - const char *ca_file_text, - struct Curl_easy *data) -{ - const size_t begin_cert_len = strlen(BEGIN_CERT); - const size_t end_cert_len = strlen(END_CERT); - CURLcode result = CURLE_OK; - int num_certs = 0; - bool more_certs = 1; - const char *current_ca_file_ptr = ca_buffer; - const char *ca_buffer_limit = ca_buffer + ca_buffer_size; - - while(more_certs && (current_ca_file_ptr < ca_buffer_limit)) { - const char *begin_cert_ptr = c_memmem(current_ca_file_ptr, - ca_buffer_limit-current_ca_file_ptr, - BEGIN_CERT, - begin_cert_len); - if(!begin_cert_ptr || !is_cr_or_lf(begin_cert_ptr[begin_cert_len])) { - more_certs = 0; - } - else { - const char *end_cert_ptr = c_memmem(begin_cert_ptr, - ca_buffer_limit-begin_cert_ptr, - END_CERT, - end_cert_len); - if(!end_cert_ptr) { - failf(data, - "schannel: CA file '%s' is not correctly formatted", - ca_file_text); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - CERT_BLOB cert_blob; - const CERT_CONTEXT *cert_context = NULL; - BOOL add_cert_result = FALSE; - DWORD actual_content_type = 0; - DWORD cert_size = - (DWORD)((end_cert_ptr + end_cert_len) - begin_cert_ptr); - - cert_blob.pbData = (BYTE *)CURL_UNCONST(begin_cert_ptr); - cert_blob.cbData = cert_size; - /* Caution: CryptQueryObject() is deprecated */ - if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, - &cert_blob, - CERT_QUERY_CONTENT_FLAG_CERT, - CERT_QUERY_FORMAT_FLAG_ALL, - 0, - NULL, - &actual_content_type, - NULL, - NULL, - NULL, - (const void **)&cert_context)) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, - "schannel: failed to extract certificate from CA file " - "'%s': %s", - ca_file_text, - curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - current_ca_file_ptr = begin_cert_ptr + cert_size; - - /* Sanity check that the cert_context object is the right type */ - if(CERT_QUERY_CONTENT_CERT != actual_content_type) { - failf(data, - "schannel: unexpected content type '%lu' when extracting " - "certificate from CA file '%s'", - actual_content_type, ca_file_text); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - add_cert_result = - CertAddCertificateContextToStore(trust_store, - cert_context, - CERT_STORE_ADD_ALWAYS, - NULL); - if(!add_cert_result) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, - "schannel: failed to add certificate from CA file '%s' " - "to certificate store: %s", - ca_file_text, - curlx_winapi_strerror(GetLastError(), buffer, - sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - num_certs++; - } - } - - switch(actual_content_type) { - case CERT_QUERY_CONTENT_CERT: - case CERT_QUERY_CONTENT_SERIALIZED_CERT: - CertFreeCertificateContext(cert_context); - break; - case CERT_QUERY_CONTENT_CRL: - case CERT_QUERY_CONTENT_SERIALIZED_CRL: - CertFreeCRLContext((PCCRL_CONTEXT)cert_context); - break; - case CERT_QUERY_CONTENT_CTL: - case CERT_QUERY_CONTENT_SERIALIZED_CTL: - CertFreeCTLContext((PCCTL_CONTEXT)cert_context); - break; - } - } - } - } - } - - if(result == CURLE_OK) { - if(!num_certs) { - infof(data, "schannel: did not add any certificates from CA file '%s'", - ca_file_text); - } - else { - infof(data, "schannel: added %d certificate(s) from CA file '%s'", - num_certs, ca_file_text); - } - } - return result; -} - -static CURLcode add_certs_file_to_store(HCERTSTORE trust_store, - const char *ca_file, - struct Curl_easy *data) -{ - CURLcode result; - HANDLE ca_file_handle; - LARGE_INTEGER file_size; - char *ca_file_buffer = NULL; - size_t ca_file_bufsize = 0; - DWORD total_bytes_read = 0; - - /* - * Read the CA file completely into memory before parsing it. This - * optimizes for the common case where the CA file is relatively - * small ( < 1 MiB ). - */ - ca_file_handle = curlx_CreateFile(ca_file, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if(ca_file_handle == INVALID_HANDLE_VALUE) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, "schannel: failed to open CA file '%s': %s", ca_file, - curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - - if(!GetFileSizeEx(ca_file_handle, &file_size)) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, "schannel: failed to determine size of CA file '%s': %s", - ca_file, - curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - - if(file_size.QuadPart > MAX_CAFILE_SIZE) { - failf(data, "schannel: CA file exceeds max size of %d bytes", - MAX_CAFILE_SIZE); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - - ca_file_bufsize = (size_t)file_size.QuadPart; - ca_file_buffer = (char *)curlx_malloc(ca_file_bufsize + 1); - if(!ca_file_buffer) { - result = CURLE_OUT_OF_MEMORY; - goto cleanup; - } - - while(total_bytes_read < ca_file_bufsize) { - DWORD bytes_to_read = (DWORD)(ca_file_bufsize - total_bytes_read); - DWORD bytes_read = 0; - - if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read, - bytes_to_read, &bytes_read, NULL)) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, "schannel: failed to read from CA file '%s': %s", ca_file, - curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - goto cleanup; - } - if(bytes_read == 0) { - /* Premature EOF -- adjust the bufsize to the new value */ - ca_file_bufsize = total_bytes_read; - } - else { - total_bytes_read += bytes_read; - } - } - - /* null-terminate the buffer */ - ca_file_buffer[ca_file_bufsize] = '\0'; - - result = add_certs_data_to_store(trust_store, - ca_file_buffer, ca_file_bufsize, - ca_file, - data); - -cleanup: - if(ca_file_handle != INVALID_HANDLE_VALUE) { - CloseHandle(ca_file_handle); - } - curlx_safefree(ca_file_buffer); - - return result; -} - -/* - * Returns the number of characters necessary to populate all the host_names. - * If host_names is not NULL, populate it with all the hostnames. Each string - * in the host_names is null-terminated and the last string is double - * null-terminated. If no DNS names are found, a single null-terminated empty - * string is returned. - */ -static DWORD cert_get_name_string(struct Curl_easy *data, - CERT_CONTEXT *cert_context, - LPTSTR host_names, - DWORD length, - PCERT_ALT_NAME_INFO alt_name_info, - BOOL Win8_compat) -{ - DWORD actual_length = 0; - BOOL compute_content = FALSE; - LPTSTR current_pos = NULL; - DWORD i; - - /* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */ - if(Win8_compat) { -/* Offered by mingw-w64 v4+. MS SDK ~10+/~VS2017+. */ -#ifndef CERT_NAME_SEARCH_ALL_NAMES_FLAG -#define CERT_NAME_SEARCH_ALL_NAMES_FLAG 0x2 -#endif - /* CertGetNameString provides the 8-bit character string without - * any decoding */ - DWORD name_flags = - CERT_NAME_DISABLE_IE4_UTF8_FLAG | CERT_NAME_SEARCH_ALL_NAMES_FLAG; - actual_length = CertGetNameString(cert_context, - CERT_NAME_DNS_TYPE, - name_flags, - NULL, - host_names, - length); - return actual_length; - } - - if(!alt_name_info) - return 0; - - compute_content = host_names != NULL && length != 0; - - /* Initialize default return values. */ - actual_length = 1; - if(compute_content) { - *host_names = '\0'; - } - - current_pos = host_names; - - /* Iterate over the alternate names and populate host_names. */ - for(i = 0; i < alt_name_info->cAltEntry; i++) { - const CERT_ALT_NAME_ENTRY *entry = &alt_name_info->rgAltEntry[i]; - wchar_t *dns_w = NULL; - size_t current_length = 0; - - if(entry->dwAltNameChoice != CERT_ALT_NAME_DNS_NAME) { - continue; - } - if(!entry->pwszDNSName) { - infof(data, "schannel: Empty DNS name."); - continue; - } - current_length = wcslen(entry->pwszDNSName) + 1; - if(!compute_content) { - actual_length += (DWORD)current_length; - continue; - } - /* Sanity check to prevent buffer overrun. */ - if((actual_length + current_length) > length) { - failf(data, "schannel: Not enough memory to list all hostnames."); - break; - } - dns_w = entry->pwszDNSName; - /* pwszDNSName is in ia5 string format and hence does not contain any - * non-ASCII characters. */ - while(*dns_w != '\0') { - *current_pos++ = (TCHAR)(*dns_w++); - } - *current_pos++ = '\0'; - actual_length += (DWORD)current_length; - } - if(compute_content) { - /* Last string has double null-terminator. */ - *current_pos = '\0'; - } - return actual_length; -} - -/* - * Returns TRUE if the hostname is a numeric IPv4/IPv6 Address, - * and populates the buffer with IPv4/IPv6 info. - */ - -static bool get_num_host_info(struct num_ip_data *ip_blob, LPCSTR hostname) -{ - struct in_addr ia; - int res = curlx_inet_pton(AF_INET, hostname, &ia); - if(res) { - ip_blob->size = sizeof(struct in_addr); - memcpy(&ip_blob->bData.ia, &ia, sizeof(struct in_addr)); - return TRUE; - } - else { - struct in6_addr ia6; - res = curlx_inet_pton(AF_INET6, hostname, &ia6); - if(res) { - ip_blob->size = sizeof(struct in6_addr); - memcpy(&ip_blob->bData.ia6, &ia6, sizeof(struct in6_addr)); - return TRUE; - } - } - return FALSE; -} - -static bool get_alt_name_info(struct Curl_easy *data, - PCCERT_CONTEXT ctx, - PCERT_ALT_NAME_INFO *alt_name_info, - LPDWORD alt_name_info_size) -{ - PCERT_INFO cert_info = NULL; - PCERT_EXTENSION extension = NULL; - CRYPT_DECODE_PARA decode_para = { sizeof(CRYPT_DECODE_PARA), NULL, NULL }; - - if(!ctx) { - failf(data, "schannel: Null certificate context."); - return FALSE; - } - - cert_info = ctx->pCertInfo; - if(!cert_info) { - failf(data, "schannel: Null certificate info."); - return FALSE; - } - - extension = CertFindExtension(szOID_SUBJECT_ALT_NAME2, - cert_info->cExtension, - cert_info->rgExtension); - if(!extension) { - failf(data, "schannel: CertFindExtension() returned no extension."); - return FALSE; - } - - if(!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - szOID_SUBJECT_ALT_NAME2, - extension->Value.pbData, - extension->Value.cbData, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - alt_name_info, - alt_name_info_size)) { - failf(data, "schannel: CryptDecodeObjectEx() returned no alternate name " - "information."); - return FALSE; - } - return TRUE; -} - -/* Verify the server's hostname */ -CURLcode Curl_verify_host(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - CURLcode result = CURLE_PEER_FAILED_VERIFICATION; - struct ssl_connect_data *connssl = cf->ctx; - CERT_CONTEXT *pCertContextServer = NULL; - SECURITY_STATUS sspi_status; - TCHAR *cert_hostname_buff = NULL; - size_t cert_hostname_buff_index = 0; - const char *conn_hostname = connssl->peer.hostname; - size_t hostlen = strlen(conn_hostname); - DWORD len = 0; - DWORD actual_len = 0; - PCERT_ALT_NAME_INFO alt_name_info = NULL; - DWORD alt_name_info_size = 0; - struct num_ip_data ip_blob = { 0 }; - bool Win8_compat; - struct num_ip_data *p = &ip_blob; - DWORD i; - - sspi_status = - Curl_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); - - if((sspi_status != SEC_E_OK) || !pCertContextServer) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - goto cleanup; - } - - Win8_compat = curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL); - if(get_num_host_info(p, conn_hostname) || !Win8_compat) { - if(!get_alt_name_info(data, pCertContextServer, - &alt_name_info, &alt_name_info_size)) { - goto cleanup; - } - } - - if(p->size && alt_name_info) { - for(i = 0; i < alt_name_info->cAltEntry; ++i) { - PCERT_ALT_NAME_ENTRY entry = &alt_name_info->rgAltEntry[i]; - if(entry->dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS) { - if(entry->IPAddress.cbData == p->size) { - if(!memcmp(entry->IPAddress.pbData, &p->bData, - entry->IPAddress.cbData)) { - result = CURLE_OK; - infof(data, - "schannel: connection hostname (%s) matched cert's IP address!", - conn_hostname); - break; - } - } - } - } - } - else { - /* Determine the size of the string needed for the cert hostname */ - len = cert_get_name_string(data, pCertContextServer, - NULL, 0, alt_name_info, Win8_compat); - if(len == 0) { - failf(data, - "schannel: CertGetNameString() returned no " - "certificate name information"); - goto cleanup; - } - - /* CertGetNameString guarantees that the returned name does not contain - * embedded null bytes. This appears to be undocumented behavior. - */ - cert_hostname_buff = (LPTSTR)curlx_malloc(len * sizeof(TCHAR)); - if(!cert_hostname_buff) { - result = CURLE_OUT_OF_MEMORY; - goto cleanup; - } - actual_len = cert_get_name_string(data, pCertContextServer, - (LPTSTR)cert_hostname_buff, len, - alt_name_info, Win8_compat); - - /* Sanity check */ - if(actual_len != len) { - failf(data, - "schannel: CertGetNameString() returned certificate " - "name information of unexpected size"); - goto cleanup; - } - - /* cert_hostname_buff contains all DNS names, where each name is - * null-terminated and the last DNS name is double null-terminated. Due to - * this encoding, use the length of the buffer to iterate over all names. - */ - while(cert_hostname_buff_index < len && - cert_hostname_buff[cert_hostname_buff_index] != TEXT('\0') && - result == CURLE_PEER_FAILED_VERIFICATION) { - char *cert_hostname; - - /* Comparing the cert name and the connection hostname encoded as UTF-8 - * is acceptable since both values are assumed to use ASCII - * (or some equivalent) encoding - */ - cert_hostname = curlx_convert_tchar_to_UTF8( - &cert_hostname_buff[cert_hostname_buff_index]); - if(!cert_hostname) { - result = CURLE_OUT_OF_MEMORY; - } - else { - if(Curl_cert_hostcheck(cert_hostname, strlen(cert_hostname), - conn_hostname, hostlen)) { - infof(data, "schannel: connection hostname (%s) validated " - "against certificate name (%s)", - conn_hostname, cert_hostname); - result = CURLE_OK; - } - else { - size_t cert_hostname_len; - - infof(data, - "schannel: connection hostname (%s) did not match " - "against certificate name (%s)", - conn_hostname, cert_hostname); - - cert_hostname_len = - _tcslen(&cert_hostname_buff[cert_hostname_buff_index]); - - /* Move on to next cert name */ - cert_hostname_buff_index += cert_hostname_len + 1; - - result = CURLE_PEER_FAILED_VERIFICATION; - } - curlx_free(cert_hostname); - } - } - - if(result == CURLE_PEER_FAILED_VERIFICATION) { - failf(data, - "schannel: CertGetNameString() failed to match " - "connection hostname (%s) against server certificate names", - conn_hostname); - } - else if(result != CURLE_OK) - failf(data, "schannel: server certificate name verification failed"); - } - -cleanup: - LocalFree(alt_name_info); - curlx_safefree(cert_hostname_buff); - - if(pCertContextServer) - CertFreeCertificateContext(pCertContextServer); - - return result; -} - -/* Verify the server's certificate and hostname */ -CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - SECURITY_STATUS sspi_status; - CURLcode result = CURLE_OK; - CERT_CONTEXT *pCertContextServer = NULL; - const CERT_CHAIN_CONTEXT *pChainContext = NULL; - HCERTCHAINENGINE cert_chain_engine = NULL; - HCERTSTORE trust_store = NULL; - HCERTSTORE own_trust_store = NULL; - - DEBUGASSERT(BACKEND); - - sspi_status = - Curl_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); - - if((sspi_status != SEC_E_OK) || !pCertContextServer) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - result = CURLE_PEER_FAILED_VERIFICATION; - } - - if(result == CURLE_OK && - (conn_config->CAfile || conn_config->ca_info_blob) && - BACKEND->use_manual_cred_validation) { - /* - * Create a chain engine that uses the certificates in the CA file as - * trusted certificates. This is only supported on Windows 7+. - */ - - if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT, - VERSION_LESS_THAN)) { - failf(data, "schannel: this version of Windows is too old to support " - "certificate verification via CA bundle file."); - result = CURLE_SSL_CACERT_BADFILE; - } - else { - /* try cache */ - trust_store = Curl_schannel_get_cached_cert_store(cf, data); - - if(trust_store) { - infof(data, "schannel: reusing certificate store from cache"); - } - else { - /* Open the certificate store */ - trust_store = CertOpenStore(CERT_STORE_PROV_MEMORY, - 0, - (HCRYPTPROV)NULL, - CERT_STORE_CREATE_NEW_FLAG, - NULL); - if(!trust_store) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, "schannel: failed to create certificate store: %s", - curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - } - else { - const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; - own_trust_store = trust_store; - - if(ca_info_blob) { - result = add_certs_data_to_store(trust_store, - (const char *)ca_info_blob->data, - ca_info_blob->len, - "(memory blob)", - data); - } - else { - result = add_certs_file_to_store(trust_store, - conn_config->CAfile, - data); - } - if(result == CURLE_OK) { - if(Curl_schannel_set_cached_cert_store(cf, data, trust_store)) { - own_trust_store = NULL; - } - } - } - } - } - - if(result == CURLE_OK) { - struct cert_chain_engine_config_win8 engine_config; - BOOL create_engine_result; - - memset(&engine_config, 0, sizeof(engine_config)); - engine_config.hExclusiveRoot = trust_store; - - /* Win8/Server2012 allows us to match partial chains */ - if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL) && - !ssl_config->no_partialchain) { - engine_config.cbSize = sizeof(engine_config); - engine_config.dwExclusiveFlags = CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG; - } - else - engine_config.cbSize = sizeof(struct cert_chain_engine_config_win7); - - /* CertCreateCertificateChainEngine checks the expected size of the - * CERT_CHAIN_ENGINE_CONFIG structure and fail if the specified size - * does not match the expected size. When this occurs, it indicates that - * CAINFO is not supported on the version of Windows in use. - */ - create_engine_result = - CertCreateCertificateChainEngine( - (CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine); - if(!create_engine_result) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, - "schannel: failed to create certificate chain engine: %s", - curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - } - } - } - - if(result == CURLE_OK) { - CERT_CHAIN_PARA ChainPara; - - memset(&ChainPara, 0, sizeof(ChainPara)); - ChainPara.cbSize = sizeof(ChainPara); - - if(!CertGetCertificateChain(cert_chain_engine, - pCertContextServer, - NULL, - pCertContextServer->hCertStore, - &ChainPara, - (ssl_config->no_revoke ? 0 : - CERT_CHAIN_REVOCATION_CHECK_CHAIN), - NULL, - &pChainContext)) { - char buffer[WINAPI_ERROR_LEN]; - failf(data, "schannel: failed to get the certificate chain: %s", - curlx_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - pChainContext = NULL; - result = CURLE_PEER_FAILED_VERIFICATION; - } - - if(result == CURLE_OK) { - CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0]; - DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED); - dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus; - - if(data->set.ssl.revoke_best_effort) { - /* Ignore errors when root certificates are missing the revocation - * list URL, or when the list could not be downloaded because the - * server is currently unreachable. */ - dwTrustErrorMask &= ~(DWORD)(CERT_TRUST_REVOCATION_STATUS_UNKNOWN | - CERT_TRUST_IS_OFFLINE_REVOCATION); - } - - if(dwTrustErrorMask) { - if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED) - failf(data, "schannel: trust for this certificate or one of " - "the certificates in the certificate chain has been revoked"); - else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN) - failf(data, "schannel: the certificate chain is incomplete"); - else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT) - failf(data, "schannel: the certificate or certificate chain is " - "based on an untrusted root"); - else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID) - failf(data, "schannel: this certificate or one of the certificates " - "in the certificate chain is not time valid"); - else if(dwTrustErrorMask & CERT_TRUST_REVOCATION_STATUS_UNKNOWN) - failf(data, "schannel: the revocation status is unknown"); - else - failf(data, "schannel: error 0x%08lx", dwTrustErrorMask); - result = CURLE_PEER_FAILED_VERIFICATION; - } - } - } - - if(result == CURLE_OK) { - if(conn_config->verifyhost) { - result = Curl_verify_host(cf, data); - } - } - - if(cert_chain_engine) { - CertFreeCertificateChainEngine(cert_chain_engine); - } - - if(own_trust_store) { - CertCloseStore(own_trust_store, 0); - } - - if(pChainContext) - CertFreeCertificateChain(pChainContext); - - if(pCertContextServer) - CertFreeCertificateContext(pCertContextServer); - - return result; -} - -#endif /* USE_SCHANNEL */ diff --git a/vendor/curl/lib/vtls/vtls.c b/vendor/curl/lib/vtls/vtls.c deleted file mode 100644 index 891facfab..000000000 --- a/vendor/curl/lib/vtls/vtls.c +++ /dev/null @@ -1,2107 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -/* This file is for implementing all "generic" SSL functions that all libcurl - internals should use. It is then responsible for calling the proper - "backend" function. - - SSL-functions in libcurl should call functions in this source file, and not - to any specific SSL-layer. - - Curl_ssl_ - prefix for generic ones - - Note that this source code uses the functions of the configured SSL - backend via the global Curl_ssl instance. - - "SSL/TLS Strong Encryption: An Introduction" - https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html -*/ - -#include "curl_setup.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include "urldata.h" -#include "cfilters.h" - -#include "vtls/vtls.h" /* generic SSL protos etc */ -#include "vtls/vtls_int.h" -#include "vtls/vtls_scache.h" -#include "vtls/keylog.h" - -#include "vtls/openssl.h" /* OpenSSL versions */ -#include "vtls/gtls.h" /* GnuTLS versions */ -#include "vtls/wolfssl.h" /* wolfSSL versions */ -#include "vtls/schannel.h" /* Schannel SSPI version */ -#include "vtls/mbedtls.h" /* mbedTLS versions */ -#include "vtls/rustls.h" /* Rustls versions */ - -#include "slist.h" -#include "curl_trc.h" -#include "strcase.h" -#include "url.h" -#include "progress.h" -#include "curlx/fopen.h" -#include "curl_sha256.h" -#include "curlx/base64.h" -#include "curlx/inet_pton.h" -#include "connect.h" -#include "select.h" -#include "setopt.h" -#include "curlx/strdup.h" -#include "curlx/strcopy.h" - -#ifdef USE_APPLE_SECTRUST -#include -#endif - - -#define CLONE_STRING(var) \ - do { \ - if(source->var) { \ - dest->var = curlx_strdup(source->var); \ - if(!dest->var) \ - return FALSE; \ - } \ - else \ - dest->var = NULL; \ - } while(0) - -#define CLONE_BLOB(var) \ - do { \ - if(blobdup(&dest->var, source->var)) \ - return FALSE; \ - } while(0) - -static CURLcode blobdup(struct curl_blob **dest, struct curl_blob *src) -{ - DEBUGASSERT(dest); - DEBUGASSERT(!*dest); - if(src) { - /* only if there is data to dupe! */ - struct curl_blob *d; - d = curlx_malloc(sizeof(struct curl_blob) + src->len); - if(!d) - return CURLE_OUT_OF_MEMORY; - d->len = src->len; - /* Always duplicate because the connection may survive longer than the - handle that passed in the blob. */ - d->flags = CURL_BLOB_COPY; - d->data = (void *)((char *)d + sizeof(struct curl_blob)); - memcpy(d->data, src->data, src->len); - *dest = d; - } - return CURLE_OK; -} - -/* returns TRUE if the blobs are identical */ -static bool blobcmp(struct curl_blob *first, struct curl_blob *second) -{ - if(!first && !second) /* both are NULL */ - return TRUE; - if(!first || !second) /* one is NULL */ - return FALSE; - if(first->len != second->len) /* different sizes */ - return FALSE; - return !memcmp(first->data, second->data, first->len); /* same data */ -} - -#ifdef USE_SSL -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) -static const struct alpn_spec ALPN_SPEC_H11 = { - { ALPN_HTTP_1_1 }, 1 -}; -static const struct alpn_spec ALPN_SPEC_H10_H11 = { - { ALPN_HTTP_1_0, ALPN_HTTP_1_1 }, 2 -}; -#ifdef USE_HTTP2 -static const struct alpn_spec ALPN_SPEC_H2 = { - { ALPN_H2 }, 1 -}; -static const struct alpn_spec ALPN_SPEC_H2_H11 = { - { ALPN_H2, ALPN_HTTP_1_1 }, 2 -}; -static const struct alpn_spec ALPN_SPEC_H11_H2 = { - { ALPN_HTTP_1_1, ALPN_H2 }, 2 -}; -#endif /* USE_HTTP2 */ - -static const struct alpn_spec *alpn_get_spec(http_majors wanted, - http_majors preferred, - bool only_http_10, - bool use_alpn) -{ - if(!use_alpn) - return NULL; - /* If HTTP/1.0 is the wanted protocol then use ALPN http/1.0 and http/1.1. - This is for compatibility reasons since some HTTP/1.0 servers with old - ALPN implementations understand ALPN http/1.1 but not http/1.0. */ - if(only_http_10 && (wanted & CURL_HTTP_V1x)) - return &ALPN_SPEC_H10_H11; -#ifdef USE_HTTP2 - if(wanted & CURL_HTTP_V2x) { - if(wanted & CURL_HTTP_V1x) - return (preferred == CURL_HTTP_V1x) ? - &ALPN_SPEC_H11_H2 : &ALPN_SPEC_H2_H11; - return &ALPN_SPEC_H2; - } -#else - (void)wanted; - (void)preferred; -#endif - return &ALPN_SPEC_H11; -} -#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ -#endif /* USE_SSL */ - -void Curl_ssl_easy_config_init(struct Curl_easy *data) -{ - /* - * libcurl 7.10 introduced SSL verification *by default*! This needs to be - * switched off unless wanted. - */ - data->set.ssl.primary.verifypeer = TRUE; - data->set.ssl.primary.verifyhost = TRUE; - data->set.ssl.primary.cache_session = TRUE; /* caching by default */ -#ifndef CURL_DISABLE_PROXY - data->set.proxy_ssl = data->set.ssl; -#endif -} - -static bool match_ssl_primary_config(struct Curl_easy *data, - struct ssl_primary_config *c1, - struct ssl_primary_config *c2) -{ - (void)data; - if((c1->version == c2->version) && - (c1->version_max == c2->version_max) && - (c1->ssl_options == c2->ssl_options) && - (c1->verifypeer == c2->verifypeer) && - (c1->verifyhost == c2->verifyhost) && - (c1->verifystatus == c2->verifystatus) && - blobcmp(c1->cert_blob, c2->cert_blob) && - blobcmp(c1->ca_info_blob, c2->ca_info_blob) && - blobcmp(c1->issuercert_blob, c2->issuercert_blob) && - Curl_safecmp(c1->CApath, c2->CApath) && - Curl_safecmp(c1->CAfile, c2->CAfile) && - Curl_safecmp(c1->issuercert, c2->issuercert) && - Curl_safecmp(c1->clientcert, c2->clientcert) && -#ifdef USE_TLS_SRP - !Curl_timestrcmp(c1->username, c2->username) && - !Curl_timestrcmp(c1->password, c2->password) && -#endif - curl_strequal(c1->cipher_list, c2->cipher_list) && - curl_strequal(c1->cipher_list13, c2->cipher_list13) && - curl_strequal(c1->curves, c2->curves) && - curl_strequal(c1->signature_algorithms, c2->signature_algorithms) && - curl_strequal(c1->CRLfile, c2->CRLfile) && - curl_strequal(c1->pinned_key, c2->pinned_key)) - return TRUE; - - return FALSE; -} - -bool Curl_ssl_conn_config_match(struct Curl_easy *data, - struct connectdata *candidate, - bool proxy) -{ -#ifndef CURL_DISABLE_PROXY - if(proxy) - return match_ssl_primary_config(data, &data->set.proxy_ssl.primary, - &candidate->proxy_ssl_config); -#else - (void)proxy; -#endif - return match_ssl_primary_config(data, &data->set.ssl.primary, - &candidate->ssl_config); -} - -static bool clone_ssl_primary_config(struct ssl_primary_config *source, - struct ssl_primary_config *dest) -{ - dest->version = source->version; - dest->version_max = source->version_max; - dest->verifypeer = source->verifypeer; - dest->verifyhost = source->verifyhost; - dest->verifystatus = source->verifystatus; - dest->cache_session = source->cache_session; - dest->ssl_options = source->ssl_options; - - CLONE_BLOB(cert_blob); - CLONE_BLOB(ca_info_blob); - CLONE_BLOB(issuercert_blob); - CLONE_STRING(CApath); - CLONE_STRING(CAfile); - CLONE_STRING(issuercert); - CLONE_STRING(clientcert); - CLONE_STRING(cipher_list); - CLONE_STRING(cipher_list13); - CLONE_STRING(pinned_key); - CLONE_STRING(curves); - CLONE_STRING(signature_algorithms); - CLONE_STRING(CRLfile); -#ifdef USE_TLS_SRP - CLONE_STRING(username); - CLONE_STRING(password); -#endif - - return TRUE; -} - -static void free_primary_ssl_config(struct ssl_primary_config *sslc) -{ - curlx_safefree(sslc->CApath); - curlx_safefree(sslc->CAfile); - curlx_safefree(sslc->issuercert); - curlx_safefree(sslc->clientcert); - curlx_safefree(sslc->cipher_list); - curlx_safefree(sslc->cipher_list13); - curlx_safefree(sslc->pinned_key); - curlx_safefree(sslc->cert_blob); - curlx_safefree(sslc->ca_info_blob); - curlx_safefree(sslc->issuercert_blob); - curlx_safefree(sslc->curves); - curlx_safefree(sslc->signature_algorithms); - curlx_safefree(sslc->CRLfile); -#ifdef USE_TLS_SRP - curlx_safefree(sslc->username); - curlx_safefree(sslc->password); -#endif -} - -CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data) -{ - struct ssl_config_data *sslc = &data->set.ssl; -#if defined(CURL_CA_PATH) || defined(CURL_CA_BUNDLE) - struct UserDefined *set = &data->set; - CURLcode result; -#endif - - if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { -#if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) - if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) - sslc->native_ca_store = TRUE; -#endif -#ifdef CURL_CA_PATH - if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH]) { - result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); - if(result) - return result; - } -#endif -#ifdef CURL_CA_BUNDLE - if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE]) { - result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); - if(result) - return result; - } -#endif - } - sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE]; - sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; - sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH]; - sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; - sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; - sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; - sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST]; - sslc->primary.signature_algorithms = - data->set.str[STRING_SSL_SIGNATURE_ALGORITHMS]; - sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; - sslc->primary.cert_blob = data->set.blobs[BLOB_CERT]; - sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; - sslc->primary.curves = data->set.str[STRING_SSL_EC_CURVES]; -#ifdef USE_TLS_SRP - sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; - sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; -#endif - sslc->cert_type = data->set.str[STRING_CERT_TYPE]; - sslc->key = data->set.str[STRING_KEY]; - sslc->key_type = data->set.str[STRING_KEY_TYPE]; - sslc->key_passwd = data->set.str[STRING_KEY_PASSWD]; - sslc->primary.clientcert = data->set.str[STRING_CERT]; - sslc->key_blob = data->set.blobs[BLOB_KEY]; - -#ifndef CURL_DISABLE_PROXY - sslc = &data->set.proxy_ssl; - if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { -#if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) - if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) - sslc->native_ca_store = TRUE; -#endif -#ifdef CURL_CA_PATH - if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH_PROXY]) { - result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], - CURL_CA_PATH); - if(result) - return result; - } -#endif -#ifdef CURL_CA_BUNDLE - if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE_PROXY]) { - result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], - CURL_CA_BUNDLE); - if(result) - return result; - } -#endif - } - sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; - sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; - sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; - sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; - sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; - sslc->primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; - sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO_PROXY]; - sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; - sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; - sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; - sslc->cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; - sslc->key = data->set.str[STRING_KEY_PROXY]; - sslc->key_type = data->set.str[STRING_KEY_TYPE_PROXY]; - sslc->key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; - sslc->primary.clientcert = data->set.str[STRING_CERT_PROXY]; - sslc->key_blob = data->set.blobs[BLOB_KEY_PROXY]; -#ifdef USE_TLS_SRP - sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; - sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; -#endif -#endif /* CURL_DISABLE_PROXY */ - - return CURLE_OK; -} - -CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, - struct connectdata *conn) -{ - /* Clone "primary" SSL configurations from the easy handle to - * the connection. They are used for connection cache matching and - * probably outlive the easy handle */ - if(!clone_ssl_primary_config(&data->set.ssl.primary, &conn->ssl_config)) - return CURLE_OUT_OF_MEMORY; -#ifndef CURL_DISABLE_PROXY - if(!clone_ssl_primary_config(&data->set.proxy_ssl.primary, - &conn->proxy_ssl_config)) - return CURLE_OUT_OF_MEMORY; -#endif - return CURLE_OK; -} - -void Curl_ssl_conn_config_cleanup(struct connectdata *conn) -{ - free_primary_ssl_config(&conn->ssl_config); -#ifndef CURL_DISABLE_PROXY - free_primary_ssl_config(&conn->proxy_ssl_config); -#endif -} - -void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy) -{ - /* May be called on an easy that has no connection yet */ - if(data->conn) { - struct ssl_primary_config *src, *dest; -#ifndef CURL_DISABLE_PROXY - src = for_proxy ? &data->set.proxy_ssl.primary : &data->set.ssl.primary; - dest = for_proxy ? &data->conn->proxy_ssl_config : &data->conn->ssl_config; -#else - (void)for_proxy; - src = &data->set.ssl.primary; - dest = &data->conn->ssl_config; -#endif - dest->verifyhost = src->verifyhost; - dest->verifypeer = src->verifypeer; - dest->verifystatus = src->verifystatus; - } -} - -#ifdef USE_SSL -static int multissl_setup(const struct Curl_ssl *backend); -#endif - -curl_sslbackend Curl_ssl_backend(void) -{ -#ifdef USE_SSL - multissl_setup(NULL); - return Curl_ssl->info.id; -#else - return CURLSSLBACKEND_NONE; -#endif -} - -#ifdef USE_SSL - -/* "global" init done? */ -static bool init_ssl = FALSE; - -/** - * Global SSL init - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ -int Curl_ssl_init(void) -{ - /* make sure this is only done once */ - if(init_ssl) - return 1; - init_ssl = TRUE; /* never again */ - - if(Curl_ssl->init) - return Curl_ssl->init(); - return 1; -} - -static bool ssl_prefs_check(struct Curl_easy *data) -{ - /* check for CURLOPT_SSLVERSION invalid parameter value */ - const unsigned char sslver = data->set.ssl.primary.version; - if(sslver >= CURL_SSLVERSION_LAST) { - failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION"); - return FALSE; - } - - switch(data->set.ssl.primary.version_max) { - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_DEFAULT: - break; - - default: - if((data->set.ssl.primary.version_max >> 16) < sslver) { - failf(data, "CURL_SSLVERSION_MAX incompatible with CURL_SSLVERSION"); - return FALSE; - } - } - - return TRUE; -} - -static struct ssl_connect_data *cf_ctx_new(struct Curl_easy *data, - const struct alpn_spec *alpn) -{ - struct ssl_connect_data *ctx; - - (void)data; - ctx = curlx_calloc(1, sizeof(*ctx)); - if(!ctx) - return NULL; - - ctx->ssl_impl = Curl_ssl; - ctx->alpn = alpn; - Curl_bufq_init2(&ctx->earlydata, CURL_SSL_EARLY_MAX, 1, BUFQ_OPT_NO_SPARES); - ctx->backend = curlx_calloc(1, ctx->ssl_impl->sizeof_ssl_backend_data); - if(!ctx->backend) { - curlx_free(ctx); - return NULL; - } - return ctx; -} - -static void cf_ctx_free(struct ssl_connect_data *ctx) -{ - if(ctx) { - curlx_safefree(ctx->negotiated.alpn); - Curl_bufq_free(&ctx->earlydata); - curlx_free(ctx->backend); - curlx_free(ctx); - } -} - -CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex, - struct dynbuf *binding) -{ - if(Curl_ssl->get_channel_binding) - return Curl_ssl->get_channel_binding(data, sockindex, binding); - return CURLE_OK; -} - -void Curl_ssl_close_all(struct Curl_easy *data) -{ - if(Curl_ssl->close_all) - Curl_ssl->close_all(data); -} - -CURLcode Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct ssl_connect_data *connssl = cf->ctx; - - if(connssl->io_need) { - curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); - CURLcode result = CURLE_OK; - if(sock != CURL_SOCKET_BAD) { - if(connssl->io_need & CURL_SSL_IO_NEED_SEND) { - result = Curl_pollset_set_out_only(data, ps, sock); - CURL_TRC_CF(data, cf, "adjust_pollset, POLLOUT fd=%" FMT_SOCKET_T, - sock); - } - else { - result = Curl_pollset_set_in_only(data, ps, sock); - CURL_TRC_CF(data, cf, "adjust_pollset, POLLIN fd=%" FMT_SOCKET_T, - sock); - } - } - return result; - } - return CURLE_OK; -} - -/* Selects an SSL crypto engine - */ -CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine) -{ - if(Curl_ssl->set_engine) - return Curl_ssl->set_engine(data, engine); - return CURLE_NOT_BUILT_IN; -} - -/* Selects the default SSL crypto engine - */ -CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data) -{ - if(Curl_ssl->set_engine_default) - return Curl_ssl->set_engine_default(data); - return CURLE_NOT_BUILT_IN; -} - -/* Return list of OpenSSL crypto engine names. */ -struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data) -{ - if(Curl_ssl->engines_list) - return Curl_ssl->engines_list(data); - return NULL; -} - -static size_t multissl_version(char *buffer, size_t size); - -void Curl_ssl_version(char *buffer, size_t size) -{ -#ifdef CURL_WITH_MULTI_SSL - (void)multissl_version(buffer, size); -#else - (void)Curl_ssl->version(buffer, size); -#endif -} - -void Curl_ssl_free_certinfo(struct Curl_easy *data) -{ - struct curl_certinfo *ci = &data->info.certs; - - if(ci->num_of_certs) { - /* free all individual lists used */ - int i; - for(i = 0; i < ci->num_of_certs; i++) { - curl_slist_free_all(ci->certinfo[i]); - ci->certinfo[i] = NULL; - } - - curlx_free(ci->certinfo); /* free the actual array too */ - ci->certinfo = NULL; - ci->num_of_certs = 0; - } -} - -CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num) -{ - struct curl_certinfo *ci = &data->info.certs; - struct curl_slist **table; - - /* Free any previous certificate information structures */ - Curl_ssl_free_certinfo(data); - - /* Allocate the required certificate information structures */ - table = curlx_calloc((size_t)num, sizeof(struct curl_slist *)); - if(!table) - return CURLE_OUT_OF_MEMORY; - - ci->num_of_certs = num; - ci->certinfo = table; - - return CURLE_OK; -} - -/* - * 'value' is NOT a null-terminated string - */ -CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, - int certnum, - const char *label, - const char *value, - size_t valuelen) -{ - struct curl_certinfo *ci = &data->info.certs; - struct curl_slist *nl; - CURLcode result = CURLE_OK; - struct dynbuf build; - - DEBUGASSERT(certnum < ci->num_of_certs); - - curlx_dyn_init(&build, CURL_X509_STR_MAX); - - if(curlx_dyn_add(&build, label) || - curlx_dyn_addn(&build, ":", 1) || - curlx_dyn_addn(&build, value, valuelen)) - return CURLE_OUT_OF_MEMORY; - - nl = Curl_slist_append_nodup(ci->certinfo[certnum], curlx_dyn_ptr(&build)); - if(!nl) { - curlx_dyn_free(&build); - curl_slist_free_all(ci->certinfo[certnum]); - result = CURLE_OUT_OF_MEMORY; - } - - ci->certinfo[certnum] = nl; - return result; -} - -/* get length bytes of randomness */ -CURLcode Curl_ssl_random(struct Curl_easy *data, - unsigned char *buffer, size_t length) -{ - DEBUGASSERT(length == sizeof(int)); - if(Curl_ssl->random) - return Curl_ssl->random(data, buffer, length); - else - return CURLE_NOT_BUILT_IN; -} - -/* - * Public key pem to der conversion - */ - -static CURLcode pubkey_pem_to_der(const char *pem, - unsigned char **der, size_t *der_len) -{ - const char *begin_pos, *end_pos; - size_t pem_count, pem_len; - CURLcode result; - struct dynbuf pbuf; - - /* if no pem, exit. */ - if(!pem) - return CURLE_BAD_CONTENT_ENCODING; - - curlx_dyn_init(&pbuf, MAX_PINNED_PUBKEY_SIZE); - - begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----"); - if(!begin_pos) - return CURLE_BAD_CONTENT_ENCODING; - - pem_count = begin_pos - pem; - /* Invalid if not at beginning AND not directly following \n */ - if(pem_count && '\n' != pem[pem_count - 1]) - return CURLE_BAD_CONTENT_ENCODING; - - /* 26 is length of "-----BEGIN PUBLIC KEY-----" */ - pem_count += 26; - - /* Invalid if not directly following \n */ - end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----"); - if(!end_pos) - return CURLE_BAD_CONTENT_ENCODING; - - pem_len = end_pos - pem; - - /* - * Here we loop through the pem array one character at a time between the - * correct indices, and place each character that is not '\n' or '\r' - * into the stripped_pem array, which should represent the raw base64 string - */ - while(pem_count < pem_len) { - if('\n' != pem[pem_count] && '\r' != pem[pem_count]) { - result = curlx_dyn_addn(&pbuf, &pem[pem_count], 1); - if(result) - return result; - } - ++pem_count; - } - - if(curlx_dyn_len(&pbuf)) { - result = curlx_base64_decode(curlx_dyn_ptr(&pbuf), der, der_len); - curlx_dyn_free(&pbuf); - } - else - result = CURLE_BAD_CONTENT_ENCODING; - - return result; -} - -/* - * Generic pinned public key check. - */ - -CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, - const char *pinnedpubkey, - const unsigned char *pubkey, size_t pubkeylen) -{ - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - /* if a path was not specified, do not pin */ - if(!pinnedpubkey) - return CURLE_OK; - if(!pubkey || !pubkeylen) - return result; - - /* only do this if pinnedpubkey starts with "sha256//", length 8 */ - if(!strncmp(pinnedpubkey, "sha256//", 8)) { - CURLcode encode; - char *cert_hash = NULL; - const char *pinned_hash, *end_pos; - size_t cert_hash_len = 0, pinned_hash_len; - unsigned char *sha256sumdigest; - - if(!Curl_ssl->sha256sum) { - /* without sha256 support, this cannot match */ - return result; - } - - /* compute sha256sum of public key */ - sha256sumdigest = curlx_malloc(CURL_SHA256_DIGEST_LENGTH); - if(!sha256sumdigest) - return CURLE_OUT_OF_MEMORY; - encode = Curl_ssl->sha256sum(pubkey, pubkeylen, - sha256sumdigest, CURL_SHA256_DIGEST_LENGTH); - - if(!encode) - encode = curlx_base64_encode(sha256sumdigest, - CURL_SHA256_DIGEST_LENGTH, - &cert_hash, &cert_hash_len); - curlx_safefree(sha256sumdigest); - - if(encode) - return encode; - - infof(data, " public key hash: sha256//%s", cert_hash); - - pinned_hash = pinnedpubkey; - while(pinned_hash && - !strncmp(pinned_hash, "sha256//", (sizeof("sha256//") - 1))) { - pinned_hash = pinned_hash + (sizeof("sha256//") - 1); - end_pos = strchr(pinned_hash, ';'); - pinned_hash_len = end_pos ? - (size_t)(end_pos - pinned_hash) : strlen(pinned_hash); - - /* compare base64 sha256 digests */ - if(cert_hash_len == pinned_hash_len && - !memcmp(cert_hash, pinned_hash, cert_hash_len)) { - DEBUGF(infof(data, "public key hash matches pinned value")); - result = CURLE_OK; - break; - } - - DEBUGF(infof(data, "public key hash does not match 'sha256//%.*s'", - (int)pinned_hash_len, pinned_hash)); - /* next one or we are at the end */ - pinned_hash = end_pos ? (end_pos + 1) : NULL; - } - curlx_safefree(cert_hash); - } - else { - long filesize; - size_t size, pem_len; - CURLcode pem_read; - struct dynbuf buf; - unsigned char *pem_ptr = NULL; - size_t left; - FILE *fp = curlx_fopen(pinnedpubkey, "rb"); - if(!fp) - return result; - - curlx_dyn_init(&buf, MAX_PINNED_PUBKEY_SIZE); - - /* Determine the file's size */ - if(fseek(fp, 0, SEEK_END)) - goto end; - filesize = ftell(fp); - if(fseek(fp, 0, SEEK_SET)) - goto end; - if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE) - goto end; - - /* - * if the size of our certificate is bigger than the file - * size then it cannot match - */ - size = curlx_sotouz((curl_off_t)filesize); - if(pubkeylen > size) - goto end; - - /* - * Read the file into the dynbuf - */ - left = size; - do { - char buffer[1024]; - size_t want = left > sizeof(buffer) ? sizeof(buffer) : left; - if(want != fread(buffer, 1, want, fp)) - goto end; - if(curlx_dyn_addn(&buf, buffer, want)) - goto end; - left -= want; - } while(left); - - /* If the sizes are the same, it cannot be base64 encoded, must be der */ - if(pubkeylen == size) { - if(!memcmp(pubkey, curlx_dyn_ptr(&buf), pubkeylen)) - result = CURLE_OK; - goto end; - } - - /* - * Otherwise we assume it is PEM and try to decode it after placing - * null-terminator - */ - pem_read = pubkey_pem_to_der(curlx_dyn_ptr(&buf), &pem_ptr, &pem_len); - /* if it was not read successfully, exit */ - if(pem_read) - goto end; - - /* - * if the size of our certificate does not match the size of - * the decoded file, they cannot be the same, otherwise compare - */ - if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen)) - result = CURLE_OK; -end: - curlx_dyn_free(&buf); - curlx_safefree(pem_ptr); - curlx_fclose(fp); - } - - return result; -} - -/* - * Check whether the SSL backend supports the status_request extension. - */ -bool Curl_ssl_cert_status_request(void) -{ - if(Curl_ssl->cert_status_request) - return Curl_ssl->cert_status_request(); - return FALSE; -} - -static int multissl_init(void) -{ - if(multissl_setup(NULL)) - return 1; - if(Curl_ssl->init) - return Curl_ssl->init(); - return 1; -} - -static CURLcode multissl_random(struct Curl_easy *data, - unsigned char *entropy, size_t length) -{ - if(multissl_setup(NULL)) - return CURLE_FAILED_INIT; - return Curl_ssl->random(data, entropy, length); -} - -static CURLcode multissl_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) -{ - if(multissl_setup(NULL)) - return CURLE_FAILED_INIT; - return Curl_ssl->do_connect(cf, data, done); -} - -static CURLcode multissl_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - if(multissl_setup(NULL)) - return CURLE_OK; - return Curl_ssl->adjust_pollset(cf, data, ps); -} - -static void *multissl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info) -{ - if(multissl_setup(NULL)) - return NULL; - return Curl_ssl->get_internals(connssl, info); -} - -static void multissl_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - if(multissl_setup(NULL)) - return; - Curl_ssl->close(cf, data); -} - -static CURLcode multissl_recv_plain(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, size_t len, size_t *pnread) -{ - if(multissl_setup(NULL)) - return CURLE_FAILED_INIT; - return Curl_ssl->recv_plain(cf, data, buf, len, pnread); -} - -static CURLcode multissl_send_plain(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *mem, size_t len, - size_t *pnwritten) -{ - if(multissl_setup(NULL)) - return CURLE_FAILED_INIT; - return Curl_ssl->send_plain(cf, data, mem, len, pnwritten); -} - -static const struct Curl_ssl Curl_ssl_multi = { - { CURLSSLBACKEND_NONE, "multi" }, /* info */ - 0, /* supports nothing */ - (size_t)-1, /* something insanely large to be on the safe side */ - - multissl_init, /* init */ - NULL, /* cleanup */ - multissl_version, /* version */ - NULL, /* shutdown */ - NULL, /* data_pending */ - multissl_random, /* random */ - NULL, /* cert_status_request */ - multissl_connect, /* connect */ - multissl_adjust_pollset, /* adjust_pollset */ - multissl_get_internals, /* get_internals */ - multissl_close, /* close_one */ - NULL, /* close_all */ - NULL, /* set_engine */ - NULL, /* set_engine_default */ - NULL, /* engines_list */ - NULL, /* sha256sum */ - multissl_recv_plain, /* recv decrypted data */ - multissl_send_plain, /* send data to encrypt */ - NULL, /* get_channel_binding */ -}; - -const struct Curl_ssl *Curl_ssl = -#ifdef CURL_WITH_MULTI_SSL - &Curl_ssl_multi; -#elif defined(USE_WOLFSSL) - &Curl_ssl_wolfssl; -#elif defined(USE_GNUTLS) - &Curl_ssl_gnutls; -#elif defined(USE_MBEDTLS) - &Curl_ssl_mbedtls; -#elif defined(USE_RUSTLS) - &Curl_ssl_rustls; -#elif defined(USE_OPENSSL) - &Curl_ssl_openssl; -#elif defined(USE_SCHANNEL) - &Curl_ssl_schannel; -#else -#error "Missing struct Curl_ssl for selected SSL backend" -#endif - -static const struct Curl_ssl *available_backends[] = { -#ifdef USE_WOLFSSL - &Curl_ssl_wolfssl, -#endif -#ifdef USE_GNUTLS - &Curl_ssl_gnutls, -#endif -#ifdef USE_MBEDTLS - &Curl_ssl_mbedtls, -#endif -#ifdef USE_OPENSSL - &Curl_ssl_openssl, -#endif -#ifdef USE_SCHANNEL - &Curl_ssl_schannel, -#endif -#ifdef USE_RUSTLS - &Curl_ssl_rustls, -#endif - NULL -}; - -/* Global cleanup */ -void Curl_ssl_cleanup(void) -{ - if(init_ssl) { - /* only cleanup if we did a previous init */ - if(Curl_ssl->cleanup) - Curl_ssl->cleanup(); -#ifdef CURL_WITH_MULTI_SSL - Curl_ssl = &Curl_ssl_multi; -#endif - init_ssl = FALSE; - } -} - -static size_t multissl_version(char *buffer, size_t size) -{ - static const struct Curl_ssl *selected; - static char backends[200]; - static size_t backends_len; - const struct Curl_ssl *current; - - current = Curl_ssl == &Curl_ssl_multi ? available_backends[0] : Curl_ssl; - - if(current != selected) { - char *p = backends; - const char *end = backends + sizeof(backends); - int i; - - selected = current; - - backends[0] = '\0'; - - for(i = 0; available_backends[i]; ++i) { - char vb[200]; - bool paren = (selected != available_backends[i]); - - if(available_backends[i]->version(vb, sizeof(vb))) { - p += curl_msnprintf(p, end - p, "%s%s%s%s", (p != backends ? " " : ""), - (paren ? "(" : ""), vb, (paren ? ")" : "")); - } - } - - backends_len = p - backends; - } - - if(size) { - curlx_strcopy(buffer, size, backends, backends_len); - } - return 0; -} - -static int multissl_setup(const struct Curl_ssl *backend) -{ - int i; - char *env; - - if(Curl_ssl != &Curl_ssl_multi) - return 1; - - if(backend) { - Curl_ssl = backend; - return 0; - } - - if(!available_backends[0]) - return 1; - - env = curl_getenv("CURL_SSL_BACKEND"); - if(env) { - for(i = 0; available_backends[i]; i++) { - if(curl_strequal(env, available_backends[i]->info.name)) { - Curl_ssl = available_backends[i]; - curlx_free(env); - return 0; - } - } - } - -#ifdef CURL_DEFAULT_SSL_BACKEND - for(i = 0; available_backends[i]; i++) { - if(curl_strequal(CURL_DEFAULT_SSL_BACKEND, - available_backends[i]->info.name)) { - Curl_ssl = available_backends[i]; - curlx_free(env); - return 0; - } - } -#endif - - /* Fall back to first available backend */ - Curl_ssl = available_backends[0]; - curlx_free(env); - return 0; -} - -/* This function is used to select the SSL backend to use. It is called by - curl_global_sslset (easy.c) which uses the global init lock. */ -CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail) -{ - int i; - - if(avail) - *avail = (const curl_ssl_backend **)&available_backends; - - if(Curl_ssl != &Curl_ssl_multi) - return id == Curl_ssl->info.id || - (name && curl_strequal(name, Curl_ssl->info.name)) ? - CURLSSLSET_OK : -#ifdef CURL_WITH_MULTI_SSL - CURLSSLSET_TOO_LATE; -#else - CURLSSLSET_UNKNOWN_BACKEND; -#endif - - for(i = 0; available_backends[i]; i++) { - if(available_backends[i]->info.id == id || - (name && curl_strequal(available_backends[i]->info.name, name))) { - multissl_setup(available_backends[i]); - return CURLSSLSET_OK; - } - } - - return CURLSSLSET_UNKNOWN_BACKEND; -} - -#else /* USE_SSL */ -CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail) -{ - (void)id; - (void)name; - (void)avail; - return CURLSSLSET_NO_BACKENDS; -} - -#endif /* !USE_SSL */ - -#ifdef USE_SSL - -void Curl_ssl_peer_cleanup(struct ssl_peer *peer) -{ - curlx_safefree(peer->sni); - if(peer->dispname != peer->hostname) - curlx_free(peer->dispname); - peer->dispname = NULL; - curlx_safefree(peer->hostname); - curlx_safefree(peer->scache_key); - peer->type = CURL_SSL_PEER_DNS; -} - -static void cf_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - if(connssl) { - connssl->ssl_impl->close(cf, data); - connssl->state = ssl_connection_none; - Curl_ssl_peer_cleanup(&connssl->peer); - } - cf->connected = FALSE; -} - -static ssl_peer_type get_peer_type(const char *hostname) -{ - if(hostname && hostname[0]) { -#ifdef USE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - if(curlx_inet_pton(AF_INET, hostname, &addr)) - return CURL_SSL_PEER_IPV4; -#ifdef USE_IPV6 - else if(curlx_inet_pton(AF_INET6, hostname, &addr)) { - return CURL_SSL_PEER_IPV6; - } -#endif - } - return CURL_SSL_PEER_DNS; -} - -CURLcode Curl_ssl_peer_init(struct ssl_peer *peer, - struct Curl_cfilter *cf, - const char *tls_id, - uint8_t transport) -{ - const char *ehostname, *edispname; - CURLcode result = CURLE_OUT_OF_MEMORY; - - /* We expect a clean struct, e.g. called only ONCE */ - DEBUGASSERT(peer); - DEBUGASSERT(!peer->hostname); - DEBUGASSERT(!peer->dispname); - DEBUGASSERT(!peer->sni); - /* We need the hostname for SNI negotiation. Once handshaked, this remains - * the SNI hostname for the TLS connection. When the connection is reused, - * the settings in cf->conn might change. We keep a copy of the hostname we - * use for SNI. - */ - peer->transport = transport; -#ifndef CURL_DISABLE_PROXY - if(Curl_ssl_cf_is_proxy(cf)) { - ehostname = cf->conn->http_proxy.host.name; - edispname = cf->conn->http_proxy.host.dispname; - peer->port = cf->conn->http_proxy.port; - } - else -#endif - { - ehostname = cf->conn->host.name; - edispname = cf->conn->host.dispname; - peer->port = (uint16_t)cf->conn->remote_port; - } - - /* hostname MUST exist and not be empty */ - if(!ehostname || !ehostname[0]) { - result = CURLE_FAILED_INIT; - goto out; - } - - peer->hostname = curlx_strdup(ehostname); - if(!peer->hostname) - goto out; - if(!edispname || !strcmp(ehostname, edispname)) - peer->dispname = peer->hostname; - else { - peer->dispname = curlx_strdup(edispname); - if(!peer->dispname) - goto out; - } - peer->type = get_peer_type(peer->hostname); - if(peer->type == CURL_SSL_PEER_DNS) { - /* not an IP address, normalize according to RCC 6066 ch. 3, - * max len of SNI is 2^16-1, no trailing dot */ - size_t len = strlen(peer->hostname); - if(len && (peer->hostname[len - 1] == '.')) - len--; - if(len < USHRT_MAX) { - peer->sni = curlx_calloc(1, len + 1); - if(!peer->sni) - goto out; - Curl_strntolower(peer->sni, peer->hostname, len); - peer->sni[len] = 0; - } - } - - result = Curl_ssl_peer_key_make(cf, peer, tls_id, &peer->scache_key); - -out: - if(result) - Curl_ssl_peer_cleanup(peer); - return result; -} - -static void ssl_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - cf_close(cf, data); - CF_DATA_RESTORE(cf, save); - cf_ctx_free(cf->ctx); - cf->ctx = NULL; -} - -static void ssl_cf_close(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - cf_close(cf, data); - if(cf->next) - cf->next->cft->do_close(cf->next, data); - CF_DATA_RESTORE(cf, save); -} - -static CURLcode ssl_cf_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct cf_call_data save; - CURLcode result; - - if(cf->connected && (connssl->state != ssl_connection_deferred)) { - *done = TRUE; - return CURLE_OK; - } - - if(!cf->next) { - *done = FALSE; - return CURLE_FAILED_INIT; - } - - if(!cf->next->connected) { - result = cf->next->cft->do_connect(cf->next, data, done); - if(result || !*done) - return result; - } - - CF_DATA_SAVE(save, cf, data); - CURL_TRC_CF(data, cf, "cf_connect()"); - DEBUGASSERT(connssl); - - *done = FALSE; - - if(!connssl->prefs_checked) { - if(!ssl_prefs_check(data)) { - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - connssl->prefs_checked = TRUE; - } - - if(!connssl->peer.hostname) { - char tls_id[80]; - connssl->ssl_impl->version(tls_id, sizeof(tls_id) - 1); - result = Curl_ssl_peer_init(&connssl->peer, cf, tls_id, TRNSPRT_TCP); - if(result) - goto out; - } - - result = connssl->ssl_impl->do_connect(cf, data, done); - - if(!result && *done) { - cf->connected = TRUE; - if(connssl->state == ssl_connection_complete) { - connssl->handshake_done = *Curl_pgrs_now(data); - } - if(Curl_tls_keylog_enabled()) { - infof(data, "SSLKEYLOGFILE set, all TLS secrets are logged to '%s'", - Curl_tls_keylog_file_name()); -#ifdef LIBRESSL_VERSION_NUMBER - infof(data, "Note LibreSSL only supports SSLKEYLOGFILE for TLS <= 1.2"); -#endif - } - /* Connection can be deferred when sending early data */ - DEBUGASSERT(connssl->state == ssl_connection_complete || - connssl->state == ssl_connection_deferred); - DEBUGASSERT(connssl->state != ssl_connection_deferred || - connssl->earlydata_state > ssl_earlydata_none); - } -out: - CURL_TRC_CF(data, cf, "cf_connect() -> %d, done=%d", result, *done); - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode ssl_cf_set_earlydata(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, size_t blen) -{ - struct ssl_connect_data *connssl = cf->ctx; - size_t nwritten = 0; - CURLcode result = CURLE_OK; - - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_await); - DEBUGASSERT(Curl_bufq_is_empty(&connssl->earlydata)); - if(blen) { - if(blen > connssl->earlydata_max) - blen = connssl->earlydata_max; - result = Curl_bufq_write(&connssl->earlydata, buf, blen, &nwritten); - CURL_TRC_CF(data, cf, "ssl_cf_set_earlydata(len=%zu) -> %zu", - blen, nwritten); - if(result) - return result; - } - return CURLE_OK; -} - -static CURLcode ssl_cf_connect_deferred(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, size_t blen, - bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - CURLcode result = CURLE_OK; - - DEBUGASSERT(connssl->state == ssl_connection_deferred); - *done = FALSE; - if(connssl->earlydata_state == ssl_earlydata_await) { - result = ssl_cf_set_earlydata(cf, data, buf, blen); - if(result) - return result; - /* we buffered any early data we would like to send. Actually - * do the connect now which sends it and performs the handshake. */ - connssl->earlydata_state = ssl_earlydata_sending; - connssl->earlydata_skip = Curl_bufq_len(&connssl->earlydata); - } - - result = ssl_cf_connect(cf, data, done); - - if(!result && *done) { - Curl_pgrsTimeWas(data, TIMER_APPCONNECT, connssl->handshake_done); - switch(connssl->earlydata_state) { - case ssl_earlydata_none: - break; - case ssl_earlydata_accepted: - if(!Curl_ssl_cf_is_proxy(cf)) - Curl_pgrsEarlyData(data, (curl_off_t)connssl->earlydata_skip); - infof(data, "Server accepted %zu bytes of TLS early data.", - connssl->earlydata_skip); - break; - case ssl_earlydata_rejected: - if(!Curl_ssl_cf_is_proxy(cf)) - Curl_pgrsEarlyData(data, -(curl_off_t)connssl->earlydata_skip); - infof(data, "Server rejected TLS early data."); - connssl->earlydata_skip = 0; - break; - default: - /* This should not happen. Either we do not use early data or we - * should know if it was accepted or not. */ - DEBUGASSERT(NULL); - break; - } - } - return result; -} - -static bool ssl_cf_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct cf_call_data save; - bool pending; - - CF_DATA_SAVE(save, cf, data); - if(connssl->ssl_impl->data_pending && - connssl->ssl_impl->data_pending(cf, data)) - pending = TRUE; - else - pending = cf->next->cft->has_data_pending(cf->next, data); - CF_DATA_RESTORE(cf, save); - return pending; -} - -static CURLcode ssl_cf_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const uint8_t *buf, size_t blen, - bool eos, size_t *pnwritten) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct cf_call_data save; - CURLcode result = CURLE_OK; - - (void)eos; - *pnwritten = 0; - CF_DATA_SAVE(save, cf, data); - - if(connssl->state == ssl_connection_deferred) { - bool done = FALSE; - result = ssl_cf_connect_deferred(cf, data, buf, blen, &done); - if(result) - goto out; - else if(!done) { - result = CURLE_AGAIN; - goto out; - } - DEBUGASSERT(connssl->state == ssl_connection_complete); - } - - if(connssl->earlydata_skip) { - if(connssl->earlydata_skip >= blen) { - connssl->earlydata_skip -= blen; - result = CURLE_OK; - *pnwritten = blen; - goto out; - } - else { - *pnwritten = connssl->earlydata_skip; - buf = buf + connssl->earlydata_skip; - blen -= connssl->earlydata_skip; - connssl->earlydata_skip = 0; - } - } - - /* OpenSSL and maybe other TLS libs do not like 0-length writes. Skip. */ - if(blen > 0) { - size_t nwritten; - result = connssl->ssl_impl->send_plain(cf, data, buf, blen, &nwritten); - if(!result) - *pnwritten += nwritten; - } - -out: - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode ssl_cf_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, char *buf, size_t len, - size_t *pnread) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct cf_call_data save; - CURLcode result = CURLE_OK; - - CF_DATA_SAVE(save, cf, data); - *pnread = 0; - if(connssl->state == ssl_connection_deferred) { - bool done = FALSE; - result = ssl_cf_connect_deferred(cf, data, NULL, 0, &done); - if(result) - goto out; - else if(!done) { - result = CURLE_AGAIN; - goto out; - } - DEBUGASSERT(connssl->state == ssl_connection_complete); - } - - result = connssl->ssl_impl->recv_plain(cf, data, buf, len, pnread); - -out: - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode ssl_cf_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - CURLcode result = CURLE_OK; - - *done = TRUE; - /* If we have done the SSL handshake, shut down the connection cleanly */ - if(cf->connected && (connssl->state == ssl_connection_complete) && - !cf->shutdown && Curl_ssl->shut_down) { - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - result = connssl->ssl_impl->shut_down(cf, data, TRUE, done); - CURL_TRC_CF(data, cf, "cf_shutdown -> %d, done=%d", result, *done); - CF_DATA_RESTORE(cf, save); - cf->shutdown = (result || *done); - } - return result; -} - -static CURLcode ssl_cf_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct cf_call_data save; - CURLcode result; - - CF_DATA_SAVE(save, cf, data); - result = connssl->ssl_impl->adjust_pollset(cf, data, ps); - CF_DATA_RESTORE(cf, save); - return result; -} - -static CURLcode ssl_cf_query(struct Curl_cfilter *cf, - struct Curl_easy *data, - int query, int *pres1, void *pres2) -{ - struct ssl_connect_data *connssl = cf->ctx; - - switch(query) { - case CF_QUERY_TIMER_APPCONNECT: { - struct curltime *when = pres2; - if(cf->connected && !Curl_ssl_cf_is_proxy(cf)) - *when = connssl->handshake_done; - return CURLE_OK; - } - case CF_QUERY_SSL_INFO: - case CF_QUERY_SSL_CTX_INFO: - if(!Curl_ssl_cf_is_proxy(cf)) { - struct curl_tlssessioninfo *info = pres2; - struct cf_call_data save; - CF_DATA_SAVE(save, cf, data); - info->backend = Curl_ssl_backend(); - info->internals = connssl->ssl_impl->get_internals( - cf->ctx, (query == CF_QUERY_SSL_INFO) ? - CURLINFO_TLS_SSL_PTR : CURLINFO_TLS_SESSION); - CF_DATA_RESTORE(cf, save); - return CURLE_OK; - } - break; - case CF_QUERY_ALPN_NEGOTIATED: { - const char **palpn = pres2; - DEBUGASSERT(palpn); - *palpn = connssl->negotiated.alpn; - CURL_TRC_CF(data, cf, "query ALPN: returning '%s'", *palpn); - return CURLE_OK; - } - default: - break; - } - return cf->next ? - cf->next->cft->query(cf->next, data, query, pres1, pres2) : - CURLE_UNKNOWN_OPTION; -} - -static CURLcode ssl_cf_cntrl(struct Curl_cfilter *cf, - struct Curl_easy *data, - int event, int arg1, void *arg2) -{ - struct ssl_connect_data *connssl = cf->ctx; - - (void)arg1; - (void)arg2; - (void)data; - switch(event) { - case CF_CTRL_CONN_INFO_UPDATE: - if(connssl->negotiated.alpn && !cf->sockindex) { - if(!strcmp("http/1.1", connssl->negotiated.alpn)) - cf->conn->httpversion_seen = 11; - else if(!strcmp("h2", connssl->negotiated.alpn)) - cf->conn->httpversion_seen = 20; - else if(!strcmp("h3", connssl->negotiated.alpn)) - cf->conn->httpversion_seen = 30; - } - break; - } - return CURLE_OK; -} - -static bool cf_ssl_is_alive(struct Curl_cfilter *cf, struct Curl_easy *data, - bool *input_pending) -{ - /* - * This function tries to determine connection status. - */ - return cf->next ? - cf->next->cft->is_alive(cf->next, data, input_pending) : - FALSE; /* pessimistic in absence of data */ -} - -struct Curl_cftype Curl_cft_ssl = { - "SSL", - CF_TYPE_SSL, - CURL_LOG_LVL_NONE, - ssl_cf_destroy, - ssl_cf_connect, - ssl_cf_close, - ssl_cf_shutdown, - ssl_cf_adjust_pollset, - ssl_cf_data_pending, - ssl_cf_send, - ssl_cf_recv, - ssl_cf_cntrl, - cf_ssl_is_alive, - Curl_cf_def_conn_keep_alive, - ssl_cf_query, -}; - -#ifndef CURL_DISABLE_PROXY - -struct Curl_cftype Curl_cft_ssl_proxy = { - "SSL-PROXY", - CF_TYPE_SSL | CF_TYPE_PROXY, - CURL_LOG_LVL_NONE, - ssl_cf_destroy, - ssl_cf_connect, - ssl_cf_close, - ssl_cf_shutdown, - ssl_cf_adjust_pollset, - ssl_cf_data_pending, - ssl_cf_send, - ssl_cf_recv, - Curl_cf_def_cntrl, - cf_ssl_is_alive, - Curl_cf_def_conn_keep_alive, - ssl_cf_query, -}; - -#endif /* !CURL_DISABLE_PROXY */ - -static CURLcode cf_ssl_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn) -{ - struct Curl_cfilter *cf = NULL; - struct ssl_connect_data *ctx; - CURLcode result; - - DEBUGASSERT(data->conn); - -#ifdef CURL_DISABLE_HTTP - (void)conn; - /* We only support ALPN for HTTP so far. */ - DEBUGASSERT(!conn->bits.tls_enable_alpn); - ctx = cf_ctx_new(data, NULL); -#else - ctx = cf_ctx_new(data, alpn_get_spec(data->state.http_neg.wanted, - data->state.http_neg.preferred, - (bool)data->state.http_neg.only_10, - (bool)conn->bits.tls_enable_alpn)); -#endif - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = Curl_cf_create(&cf, &Curl_cft_ssl, ctx); - -out: - if(result) - cf_ctx_free(ctx); - *pcf = result ? NULL : cf; - return result; -} - -CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex) -{ - struct Curl_cfilter *cf; - CURLcode result; - - result = cf_ssl_create(&cf, data, conn); - if(!result) - Curl_conn_cf_add(data, conn, sockindex, cf); - return result; -} - -CURLcode Curl_cf_ssl_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf; - CURLcode result; - - result = cf_ssl_create(&cf, data, cf_at->conn); - if(!result) - Curl_conn_cf_insert_after(cf_at, cf); - return result; -} - -#ifndef CURL_DISABLE_PROXY - -static CURLcode cf_ssl_proxy_create(struct Curl_cfilter **pcf, - struct Curl_easy *data, - struct connectdata *conn) -{ - struct Curl_cfilter *cf = NULL; - struct ssl_connect_data *ctx; - CURLcode result; - /* ALPN is default, but if user explicitly disables it, obey */ - bool use_alpn = (bool)data->set.ssl_enable_alpn; - http_majors wanted = CURL_HTTP_V1x; - - (void)conn; -#ifdef USE_HTTP2 - if(conn->http_proxy.proxytype == CURLPROXY_HTTPS2) { - use_alpn = TRUE; - wanted = (CURL_HTTP_V1x | CURL_HTTP_V2x); - } -#endif - - ctx = cf_ctx_new(data, alpn_get_spec(wanted, 0, false, use_alpn)); - if(!ctx) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - result = Curl_cf_create(&cf, &Curl_cft_ssl_proxy, ctx); - -out: - if(result) - cf_ctx_free(ctx); - *pcf = result ? NULL : cf; - return result; -} - -CURLcode Curl_cf_ssl_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data) -{ - struct Curl_cfilter *cf; - CURLcode result; - - result = cf_ssl_proxy_create(&cf, data, cf_at->conn); - if(!result) - Curl_conn_cf_insert_after(cf_at, cf); - return result; -} - -#endif /* !CURL_DISABLE_PROXY */ - -bool Curl_ssl_supports(struct Curl_easy *data, unsigned int ssl_option) -{ - (void)data; - return (Curl_ssl->supports & ssl_option); -} - -static CURLcode vtls_shutdown_blocking(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool send_shutdown, bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct cf_call_data save; - CURLcode result = CURLE_OK; - timediff_t timeout_ms; - int what, loop = 10; - - if(cf->shutdown) { - *done = TRUE; - return CURLE_OK; - } - CF_DATA_SAVE(save, cf, data); - - *done = FALSE; - while(!result && !*done && loop--) { - timeout_ms = Curl_shutdown_timeleft(data, cf->conn, cf->sockindex); - - if(timeout_ms < 0) { - /* no need to continue if time is already up */ - failf(data, "SSL shutdown timeout"); - result = CURLE_OPERATION_TIMEDOUT; - goto out; - } - - result = connssl->ssl_impl->shut_down(cf, data, send_shutdown, done); - if(result || *done) - goto out; - - if(connssl->io_need) { - what = Curl_conn_cf_poll(cf, data, timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - result = CURLE_RECV_ERROR; - goto out; - } - else if(what == 0) { - /* timeout */ - failf(data, "SSL shutdown timeout"); - result = CURLE_OPERATION_TIMEDOUT; - goto out; - } - /* socket is readable or writable */ - } - } -out: - CF_DATA_RESTORE(cf, save); - cf->shutdown = (result || *done); - return result; -} - -CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data, - int sockindex, bool send_shutdown) -{ - struct Curl_cfilter *cf, *head; - CURLcode result = CURLE_OK; - - head = data->conn ? data->conn->cfilter[sockindex] : NULL; - for(cf = head; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_ssl) { - bool done; - CURL_TRC_CF(data, cf, "shutdown and remove SSL, start"); - Curl_shutdown_start(data, sockindex, 0); - result = vtls_shutdown_blocking(cf, data, send_shutdown, &done); - Curl_shutdown_clear(data, sockindex); - if(!result && !done) /* blocking failed? */ - result = CURLE_SSL_SHUTDOWN_FAILED; - Curl_conn_cf_discard(&cf, data); - CURL_TRC_CF(data, cf, "shutdown and remove SSL, done -> %d", result); - break; - } - } - return result; -} - -bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf) -{ - return (cf->cft->flags & CF_TYPE_SSL) && (cf->cft->flags & CF_TYPE_PROXY); -} - -struct ssl_config_data * -Curl_ssl_cf_get_config(struct Curl_cfilter *cf, struct Curl_easy *data) -{ -#ifdef CURL_DISABLE_PROXY - (void)cf; - return &data->set.ssl; -#else - return Curl_ssl_cf_is_proxy(cf) ? &data->set.proxy_ssl : &data->set.ssl; -#endif -} - -struct ssl_primary_config * -Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf) -{ -#ifdef CURL_DISABLE_PROXY - return &cf->conn->ssl_config; -#else - return Curl_ssl_cf_is_proxy(cf) ? - &cf->conn->proxy_ssl_config : &cf->conn->ssl_config; -#endif -} - -CURLcode Curl_alpn_to_proto_buf(struct alpn_proto_buf *buf, - const struct alpn_spec *spec) -{ - size_t i, len; - int off = 0; - unsigned char blen; - - memset(buf, 0, sizeof(*buf)); - for(i = 0; spec && i < spec->count; ++i) { - len = strlen(spec->entries[i]); - if(len >= ALPN_NAME_MAX) - return CURLE_FAILED_INIT; - blen = (unsigned char)len; - if(off + blen + 1 >= (int)sizeof(buf->data)) - return CURLE_FAILED_INIT; - buf->data[off++] = blen; - memcpy(buf->data + off, spec->entries[i], blen); - off += blen; - } - buf->len = off; - return CURLE_OK; -} - -CURLcode Curl_alpn_to_proto_str(struct alpn_proto_buf *buf, - const struct alpn_spec *spec) -{ - size_t i, len; - size_t off = 0; - - memset(buf, 0, sizeof(*buf)); - for(i = 0; spec && i < spec->count; ++i) { - len = strlen(spec->entries[i]); - if(len >= ALPN_NAME_MAX) - return CURLE_FAILED_INIT; - if(off + len + 2 >= sizeof(buf->data)) - return CURLE_FAILED_INIT; - if(off) - buf->data[off++] = ','; - memcpy(buf->data + off, spec->entries[i], len); - off += len; - } - buf->data[off] = '\0'; - buf->len = (int)off; - return CURLE_OK; -} - -bool Curl_alpn_contains_proto(const struct alpn_spec *spec, - const char *proto) -{ - size_t i, plen = proto ? strlen(proto) : 0; - for(i = 0; spec && plen && i < spec->count; ++i) { - size_t slen = strlen(spec->entries[i]); - if((slen == plen) && !memcmp(proto, spec->entries[i], plen)) - return TRUE; - } - return FALSE; -} - -void Curl_alpn_restrict_to(struct alpn_spec *spec, const char *proto) -{ - size_t plen = strlen(proto); - DEBUGASSERT(plen < sizeof(spec->entries[0])); - if(plen < sizeof(spec->entries[0])) { - memcpy(spec->entries[0], proto, plen + 1); - spec->count = 1; - } -} - -void Curl_alpn_copy(struct alpn_spec *dest, const struct alpn_spec *src) -{ - if(src) - memcpy(dest, src, sizeof(*dest)); - else - memset(dest, 0, sizeof(*dest)); -} - -CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_connect_data *connssl, - const unsigned char *proto, - size_t proto_len) -{ - CURLcode result = CURLE_OK; - (void)cf; - - if(connssl->negotiated.alpn) { - /* When we ask for a specific ALPN protocol, we need the confirmation - * of it by the server, as we have installed protocol handler and - * connection filter chain for exactly this protocol. */ - if(!proto_len) { - failf(data, "ALPN: asked for '%s' from previous session, " - "but server did not confirm it. Refusing to continue.", - connssl->negotiated.alpn); - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - else if(!proto) { - DEBUGASSERT(0); /* with length, we need a pointer */ - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - else if((strlen(connssl->negotiated.alpn) != proto_len) || - memcmp(connssl->negotiated.alpn, proto, proto_len)) { - failf(data, "ALPN: asked for '%s' from previous session, but server " - "selected '%.*s'. Refusing to continue.", - connssl->negotiated.alpn, (int)proto_len, proto); - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - /* ALPN is exactly what we asked for, done. */ - infof(data, "ALPN: server confirmed to use '%s'", - connssl->negotiated.alpn); - goto out; - } - - if(proto && proto_len) { - if(memchr(proto, '\0', proto_len)) { - failf(data, "ALPN: server selected protocol contains NUL. " - "Refusing to continue."); - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - connssl->negotiated.alpn = curlx_memdup0((const char *)proto, proto_len); - if(!connssl->negotiated.alpn) - return CURLE_OUT_OF_MEMORY; - } - - if(proto && proto_len) { - if(connssl->state == ssl_connection_deferred) - infof(data, VTLS_INFOF_ALPN_DEFERRED, (int)proto_len, proto); - else - infof(data, VTLS_INFOF_ALPN_ACCEPTED, (int)proto_len, proto); - } - else { - if(connssl->state == ssl_connection_deferred) - infof(data, VTLS_INFOF_NO_ALPN_DEFERRED); - else - infof(data, VTLS_INFOF_NO_ALPN); - } - -out: - return result; -} - -CURLcode Curl_on_session_reuse(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data, bool early_data_allowed) -{ - struct ssl_connect_data *connssl = cf->ctx; - CURLcode result = CURLE_OK; - - *do_early_data = FALSE; - - if(!early_data_allowed) { - CURL_TRC_CF(data, cf, "SSL session does not allow earlydata"); - } - else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) { - CURL_TRC_CF(data, cf, "SSL session has different ALPN, no early data"); - } - else { - infof(data, "SSL session allows %zu bytes of early data, " - "reusing ALPN '%s'", connssl->earlydata_max, scs->alpn); - connssl->earlydata_state = ssl_earlydata_await; - connssl->state = ssl_connection_deferred; - result = Curl_alpn_set_negotiated(cf, data, connssl, - (const unsigned char *)scs->alpn, - scs->alpn ? strlen(scs->alpn) : 0); - *do_early_data = !result; - } - return result; -} - -#endif /* USE_SSL */ diff --git a/vendor/curl/lib/vtls/vtls.h b/vendor/curl/lib/vtls/vtls.h deleted file mode 100644 index 6db67cf74..000000000 --- a/vendor/curl/lib/vtls/vtls.h +++ /dev/null @@ -1,275 +0,0 @@ -#ifndef HEADER_CURL_VTLS_H -#define HEADER_CURL_VTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -struct connectdata; -struct ssl_config_data; -struct ssl_primary_config; -struct Curl_cfilter; -struct Curl_easy; -struct dynbuf; - -#define SSLSUPP_CA_PATH (1 << 0) /* supports CAPATH */ -#define SSLSUPP_CERTINFO (1 << 1) /* supports CURLOPT_CERTINFO */ -#define SSLSUPP_PINNEDPUBKEY (1 << 2) /* supports CURLOPT_PINNEDPUBLICKEY */ -#define SSLSUPP_SSL_CTX (1 << 3) /* supports CURLOPT_SSL_CTX */ -#define SSLSUPP_HTTPS_PROXY (1 << 4) /* supports access via HTTPS proxies */ -#define SSLSUPP_TLS13_CIPHERSUITES (1 << 5) /* supports TLS 1.3 ciphersuites */ -#define SSLSUPP_CAINFO_BLOB (1 << 6) -#define SSLSUPP_ECH (1 << 7) -#define SSLSUPP_CA_CACHE (1 << 8) -#define SSLSUPP_CIPHER_LIST (1 << 9) /* supports TLS 1.0-1.2 ciphersuites */ -#define SSLSUPP_SIGNATURE_ALGORITHMS (1 << 10) /* supports TLS sigalgs */ -#define SSLSUPP_ISSUERCERT (1 << 11) /* supports CURLOPT_ISSUERCERT */ -#define SSLSUPP_SSL_EC_CURVES (1 << 12) /* supports CURLOPT_SSL_EC_CURVES */ -#define SSLSUPP_CRLFILE (1 << 13) /* supports CURLOPT_CRLFILE */ -#define SSLSUPP_ISSUERCERT_BLOB (1 << 14) /* CURLOPT_ISSUERCERT_BLOB */ - -#ifdef USE_ECH -/* CURLECH_ bits for the tls_ech option */ -#define CURLECH_DISABLE (1 << 0) -#define CURLECH_GREASE (1 << 1) -#define CURLECH_ENABLE (1 << 2) -#define CURLECH_HARD (1 << 3) -#define CURLECH_CLA_CFG (1 << 4) - -#define CURLECH_ENABLED(data) \ - ((data)->set.tls_ech && !((data)->set.tls_ech & CURLECH_DISABLE)) -#endif /* USE_ECH */ - -#define ALPN_ACCEPTED "ALPN: server accepted " - -#define VTLS_INFOF_NO_ALPN \ - "ALPN: server did not agree on a protocol. Uses default." -#define VTLS_INFOF_ALPN_OFFER_1STR \ - "ALPN: curl offers %s" -#define VTLS_INFOF_ALPN_ACCEPTED \ - ALPN_ACCEPTED "%.*s" - -#define VTLS_INFOF_NO_ALPN_DEFERRED \ - "ALPN: deferred handshake for early data without specific protocol." -#define VTLS_INFOF_ALPN_DEFERRED \ - "ALPN: deferred handshake for early data using '%.*s'." - -/* IETF defined version numbers used in TLS protocol negotiation */ -#define CURL_IETF_PROTO_UNKNOWN 0x0 -#define CURL_IETF_PROTO_SSL3 0x0300 -#define CURL_IETF_PROTO_TLS1 0x0301 -#define CURL_IETF_PROTO_TLS1_1 0x0302 -#define CURL_IETF_PROTO_TLS1_2 0x0303 -#define CURL_IETF_PROTO_TLS1_3 0x0304 -#define CURL_IETF_PROTO_DTLS1 0xFEFF -#define CURL_IETF_PROTO_DTLS1_2 0xFEFD - -typedef enum { - CURL_SSL_PEER_DNS, - CURL_SSL_PEER_IPV4, - CURL_SSL_PEER_IPV6 -} ssl_peer_type; - -struct ssl_peer { - char *hostname; /* hostname for verification */ - char *dispname; /* display version of hostname */ - char *sni; /* SNI version of hostname or NULL if not usable */ - char *scache_key; /* for lookups in session cache */ - ssl_peer_type type; /* type of the peer information */ - uint16_t port; /* port we are talking to */ - uint8_t transport; /* one of TRNSPRT_* defines */ -}; - -CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail); - -#define MAX_PINNED_PUBKEY_SIZE (1024 * 1024) /* 1 MiB */ - -curl_sslbackend Curl_ssl_backend(void); - -/** - * Init ssl config for a new easy handle. - */ -void Curl_ssl_easy_config_init(struct Curl_easy *data); - -/** - * Init the `data->set.ssl` and `data->set.proxy_ssl` for - * connection matching use. - */ -CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data); - -/** - * Init SSL configs (main + proxy) for a new connection from the easy handle. - */ -CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, - struct connectdata *conn); - -/** - * Free allocated resources in SSL configs (main + proxy) for - * the given connection. - */ -void Curl_ssl_conn_config_cleanup(struct connectdata *conn); - -/** - * Return TRUE iff SSL configuration from `data` is functionally the - * same as the one on `candidate`. - * @param proxy match the proxy SSL config or the main one - */ -bool Curl_ssl_conn_config_match(struct Curl_easy *data, - struct connectdata *candidate, - bool proxy); - -/* Update certain connection SSL config flags after they have - * been changed on the easy handle. Works for `verifypeer`, - * `verifyhost` and `verifystatus`. */ -void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy); - -/** - * Init SSL peer information for filter. Can be called repeatedly. - */ -CURLcode Curl_ssl_peer_init(struct ssl_peer *peer, - struct Curl_cfilter *cf, - const char *tls_id, - uint8_t transport); -/** - * Free all allocated data and reset peer information. - */ -void Curl_ssl_peer_cleanup(struct ssl_peer *peer); - -#ifdef USE_SSL -int Curl_ssl_init(void); -void Curl_ssl_cleanup(void); -/* tell the SSL stuff to close down all open information regarding - connections (and thus session ID caching etc) */ -void Curl_ssl_close_all(struct Curl_easy *data); -CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine); -/* Sets engine as default for all SSL operations */ -CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data); -struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data); - -void Curl_ssl_version(char *buffer, size_t size); - -/* Certificate information list handling. */ -#define CURL_X509_STR_MAX 100000 -#define MAX_ALLOWED_CERT_AMOUNT 100 - -void Curl_ssl_free_certinfo(struct Curl_easy *data); -CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num); -CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, int certnum, - const char *label, const char *value, - size_t valuelen); -CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data, int certnum, - const char *label, const char *value); - -/* Functions to be used by SSL library adaptation functions */ - -/* get N random bytes into the buffer */ -CURLcode Curl_ssl_random(struct Curl_easy *data, - unsigned char *buffer, size_t length); -/* Check pinned public key. */ -CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, - const char *pinnedpubkey, - const unsigned char *pubkey, size_t pubkeylen); - -bool Curl_ssl_cert_status_request(void); - -/* The maximum size of the SSL channel binding is 85 bytes, as defined in - * RFC 5929, Section 4.1. The 'tls-server-end-point:' prefix is 21 bytes long, - * and SHA-512 is the longest supported hash algorithm, with a digest length of - * 64 bytes. - * The maximum size of the channel binding is therefore 21 + 64 = 85 bytes. - */ -#define SSL_CB_MAX_SIZE 85 - -/* Return the tls-server-end-point channel binding, including the - * 'tls-server-end-point:' prefix. - * If successful, the data is written to the dynbuf, and CURLE_OK is returned. - * The dynbuf MUST HAVE a minimum toobig size of SSL_CB_MAX_SIZE. - * If the dynbuf is too small, CURLE_OUT_OF_MEMORY is returned. - * If channel binding is not supported, binding stays empty and CURLE_OK is - * returned. - */ -CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex, - struct dynbuf *binding); - -#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ - -CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data, - struct connectdata *conn, - int sockindex); - -CURLcode Curl_cf_ssl_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data); - -CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data, - int sockindex, bool send_shutdown); - -#ifndef CURL_DISABLE_PROXY -CURLcode Curl_cf_ssl_proxy_insert_after(struct Curl_cfilter *cf_at, - struct Curl_easy *data); -#endif /* !CURL_DISABLE_PROXY */ - -/** - * True iff the underlying SSL implementation supports the option. - * Option is one of the defined SSLSUPP_* values. - * `data` maybe NULL for the features of the default implementation. - */ -bool Curl_ssl_supports(struct Curl_easy *data, unsigned int ssl_option); - -/** - * Get the ssl_config_data in `data` that is relevant for cfilter `cf`. - */ -struct ssl_config_data *Curl_ssl_cf_get_config(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/** - * Get the primary config relevant for the filter from its connection. - */ -struct ssl_primary_config * - Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf); - -extern struct Curl_cftype Curl_cft_ssl; -#ifndef CURL_DISABLE_PROXY -extern struct Curl_cftype Curl_cft_ssl_proxy; -#endif - -#else /* if not USE_SSL */ - -/* When SSL support is not present, define away these function calls */ -#define Curl_ssl_init() 1 -#define Curl_ssl_cleanup() Curl_nop_stmt -#define Curl_ssl_close_all(x) Curl_nop_stmt -#define Curl_ssl_set_engine(x, y) CURLE_NOT_BUILT_IN -#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN -#define Curl_ssl_engines_list(x) NULL -#define Curl_ssl_free_certinfo(x) Curl_nop_stmt -#define Curl_ssl_random(x, y, z) ((void)(x), CURLE_NOT_BUILT_IN) -#define Curl_ssl_cert_status_request() FALSE -#define Curl_ssl_supports(a, b) FALSE -#define Curl_ssl_cfilter_add(a, b, c) CURLE_NOT_BUILT_IN -#define Curl_ssl_cfilter_remove(a, b, c) CURLE_OK -#define Curl_ssl_cf_get_config(a, b) NULL -#define Curl_ssl_cf_get_primary_config(a) NULL -#endif - -#endif /* HEADER_CURL_VTLS_H */ diff --git a/vendor/curl/lib/vtls/vtls_int.h b/vendor/curl/lib/vtls/vtls_int.h deleted file mode 100644 index 6700ee74c..000000000 --- a/vendor/curl/lib/vtls/vtls_int.h +++ /dev/null @@ -1,211 +0,0 @@ -#ifndef HEADER_CURL_VTLS_INT_H -#define HEADER_CURL_VTLS_INT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SSL - -#include "cfilters.h" -#include "select.h" -#include "urldata.h" -#include "vtls/vtls.h" - -struct Curl_ssl; -struct ssl_connect_data; -struct Curl_ssl_session; - -/* see https://www.iana.org/assignments/tls-extensiontype-values/ */ -#define ALPN_HTTP_1_0_LENGTH 8 -#define ALPN_HTTP_1_0 "http/1.0" -#define ALPN_HTTP_1_1_LENGTH 8 -#define ALPN_HTTP_1_1 "http/1.1" -#define ALPN_H2_LENGTH 2 -#define ALPN_H2 "h2" -#define ALPN_H3_LENGTH 2 -#define ALPN_H3 "h3" - -/* conservative sizes on the ALPN entries and count we are handling, - * we can increase these if we ever feel the need or have to accommodate - * ALPN strings from the "outside". */ -#define ALPN_NAME_MAX 10 -#define ALPN_ENTRIES_MAX 3 -#define ALPN_PROTO_BUF_MAX (ALPN_ENTRIES_MAX * (ALPN_NAME_MAX + 1)) - -struct alpn_spec { - char entries[ALPN_ENTRIES_MAX][ALPN_NAME_MAX]; - size_t count; /* number of entries */ -}; - -struct alpn_proto_buf { - unsigned char data[ALPN_PROTO_BUF_MAX]; - int len; -}; - -CURLcode Curl_alpn_to_proto_buf(struct alpn_proto_buf *buf, - const struct alpn_spec *spec); -CURLcode Curl_alpn_to_proto_str(struct alpn_proto_buf *buf, - const struct alpn_spec *spec); -void Curl_alpn_restrict_to(struct alpn_spec *spec, const char *proto); -void Curl_alpn_copy(struct alpn_spec *dest, const struct alpn_spec *src); - -CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_connect_data *connssl, - const unsigned char *proto, - size_t proto_len); - -bool Curl_alpn_contains_proto(const struct alpn_spec *spec, const char *proto); - -/* enum for the nonblocking SSL connection state machine */ -typedef enum { - ssl_connect_1, - ssl_connect_2, - ssl_connect_3, - ssl_connect_done -} ssl_connect_state; - -typedef enum { - ssl_connection_none, - ssl_connection_deferred, - ssl_connection_negotiating, - ssl_connection_complete -} ssl_connection_state; - -typedef enum { - ssl_earlydata_none, - ssl_earlydata_await, - ssl_earlydata_sending, - ssl_earlydata_sent, - ssl_earlydata_accepted, - ssl_earlydata_rejected -} ssl_earlydata_state; - -#define CURL_SSL_IO_NEED_NONE 0 -#define CURL_SSL_IO_NEED_RECV (1 << 0) -#define CURL_SSL_IO_NEED_SEND (1 << 1) - -/* Max earlydata payload we want to send */ -#define CURL_SSL_EARLY_MAX (64 * 1024) - -/* Information in each SSL cfilter context: cf->ctx */ -struct ssl_connect_data { - const struct Curl_ssl *ssl_impl; /* TLS backend for this filter */ - struct ssl_peer peer; /* peer the filter talks to */ - const struct alpn_spec *alpn; /* ALPN to use or NULL for none */ - void *backend; /* vtls backend specific props */ - struct cf_call_data call_data; /* data handle used in current call */ - struct curltime handshake_done; /* time when handshake finished */ - struct { - char *alpn; /* ALPN value or NULL */ - } negotiated; - struct bufq earlydata; /* earlydata to be send to peer */ - size_t earlydata_max; /* max earlydata allowed by peer */ - size_t earlydata_skip; /* sending bytes to skip when earlydata - * is accepted by peer */ - ssl_connection_state state; - ssl_connect_state connecting_state; - ssl_earlydata_state earlydata_state; - int io_need; /* TLS signals special SEND/RECV needs */ - BIT(peer_closed); /* peer has closed connection */ - BIT(prefs_checked); /* SSL preferences have been checked */ - BIT(input_pending); /* data for SSL_read() may be available */ -}; - -#undef CF_CTX_CALL_DATA -#define CF_CTX_CALL_DATA(cf) ((struct ssl_connect_data *)(cf)->ctx)->call_data - -/* Definitions for SSL Implementations */ - -struct Curl_ssl { - /* - * This *must* be the first entry to allow returning the list of available - * backends in curl_global_sslset(). - */ - curl_ssl_backend info; - unsigned int supports; /* bitfield, see above */ - size_t sizeof_ssl_backend_data; - - int (*init)(void); - void (*cleanup)(void); - - size_t (*version)(char *buffer, size_t size); - CURLcode (*shut_down)(struct Curl_cfilter *cf, struct Curl_easy *data, - bool send_shutdown, bool *done); - - /* data_pending() shall return TRUE when it wants to get called again to - drain internal buffers and deliver data instead of waiting for the socket - to get readable */ - bool (*data_pending)(struct Curl_cfilter *cf, const struct Curl_easy *data); - - /* return 0 if a find random is filled in */ - CURLcode (*random)(struct Curl_easy *data, unsigned char *entropy, - size_t length); - bool (*cert_status_request)(void); - - CURLcode (*do_connect)(struct Curl_cfilter *cf, struct Curl_easy *data, - bool *done); - - /* During handshake/shutdown, adjust the pollset to include the socket - * for POLLOUT or POLLIN as needed. Mandatory. */ - CURLcode (*adjust_pollset)(struct Curl_cfilter *cf, struct Curl_easy *data, - struct easy_pollset *ps); - void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info); - void (*close)(struct Curl_cfilter *cf, struct Curl_easy *data); - void (*close_all)(struct Curl_easy *data); - - CURLcode (*set_engine)(struct Curl_easy *data, const char *engine); - CURLcode (*set_engine_default)(struct Curl_easy *data); - struct curl_slist *(*engines_list)(struct Curl_easy *data); - - CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, - unsigned char *sha256sum, size_t sha256sumlen); - CURLcode (*recv_plain)(struct Curl_cfilter *cf, struct Curl_easy *data, - char *buf, size_t len, size_t *pnread); - CURLcode (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data, - const void *mem, size_t len, size_t *pnwritten); - - CURLcode (*get_channel_binding)(struct Curl_easy *data, int sockindex, - struct dynbuf *binding); -}; - -extern const struct Curl_ssl *Curl_ssl; - -CURLcode Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct easy_pollset *ps); - -/** - * Get the SSL filter below the given one or NULL if there is none. - */ -bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf); - -CURLcode Curl_on_session_reuse(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data, bool early_data_allowed); -#endif /* USE_SSL */ - -#endif /* HEADER_CURL_VTLS_INT_H */ diff --git a/vendor/curl/lib/vtls/vtls_scache.c b/vendor/curl/lib/vtls/vtls_scache.c deleted file mode 100644 index 59fa256bc..000000000 --- a/vendor/curl/lib/vtls/vtls_scache.c +++ /dev/null @@ -1,1244 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SSL - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include "urldata.h" -#include "cfilters.h" - -#include "vtls/vtls.h" /* generic SSL protos etc */ -#include "vtls/vtls_int.h" -#include "vtls/vtls_scache.h" -#include "vtls/vtls_spack.h" - -#include "strcase.h" -#include "url.h" -#include "llist.h" -#include "curl_share.h" -#include "curl_trc.h" -#include "curl_sha256.h" -#include "rand.h" - - -/* a peer+tls-config we cache sessions for */ -struct Curl_ssl_scache_peer { - char *ssl_peer_key; /* id for peer + relevant TLS configuration */ - char *clientcert; - char *srp_username; - char *srp_password; - struct Curl_llist sessions; - void *sobj; /* object instance or NULL */ - Curl_ssl_scache_obj_dtor *sobj_free; /* free `sobj` callback */ - unsigned char key_salt[CURL_SHA256_DIGEST_LENGTH]; /* for entry export */ - unsigned char key_hmac[CURL_SHA256_DIGEST_LENGTH]; /* for entry export */ - size_t max_sessions; - long age; /* a number, the higher the more recent */ - BIT(hmac_set); /* if key_salt and key_hmac are present */ - BIT(exportable); /* sessions for this peer can be exported */ -}; - -#define CURL_SCACHE_MAGIC 0x000e1551 - -#define GOOD_SCACHE(x) ((x) && (x)->magic == CURL_SCACHE_MAGIC) - -static CURLcode cf_ssl_peer_key_add_path(struct dynbuf *buf, - const char *name, - const char *path, - bool *is_local) -{ - if(path && path[0]) { - /* We try to add absolute paths, so that the session key can stay valid - * when used in another process with different CWD. When a path does not - * exist, this does not work. Then, we add the path as is. */ -#ifdef _WIN32 - char abspath[_MAX_PATH]; - if(_fullpath(abspath, path, _MAX_PATH)) - return curlx_dyn_addf(buf, ":%s-%s", name, abspath); - *is_local = TRUE; -#elif defined(HAVE_REALPATH) - if(path[0] != '/') { - char *abspath = realpath(path, NULL); - if(abspath) { - CURLcode r = curlx_dyn_addf(buf, ":%s-%s", name, abspath); - /* !checksrc! disable BANNEDFUNC 1 */ - free(abspath); /* allocated by libc, free without memdebug */ - return r; - } - *is_local = TRUE; - } -#endif - return curlx_dyn_addf(buf, ":%s-%s", name, path); - } - return CURLE_OK; -} - -static CURLcode cf_ssl_peer_key_add_hash(struct dynbuf *buf, - const char *name, - struct curl_blob *blob) -{ - CURLcode r = CURLE_OK; - if(blob && blob->len) { - unsigned char hash[CURL_SHA256_DIGEST_LENGTH]; - size_t i; - - r = curlx_dyn_addf(buf, ":%s-", name); - if(r) - goto out; - r = Curl_sha256it(hash, blob->data, blob->len); - if(r) - goto out; - for(i = 0; i < CURL_SHA256_DIGEST_LENGTH; ++i) { - r = curlx_dyn_addf(buf, "%02x", hash[i]); - if(r) - goto out; - } - } -out: - return r; -} - -#define CURL_SSLS_LOCAL_SUFFIX ":L" -#define CURL_SSLS_GLOBAL_SUFFIX ":G" - -static bool cf_ssl_peer_key_is_global(const char *peer_key) -{ - size_t len = peer_key ? strlen(peer_key) : 0; - return (len > 2) && - (peer_key[len - 1] == 'G') && - (peer_key[len - 2] == ':'); -} - -CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf, - const struct ssl_peer *peer, - const char *tls_id, - char **ppeer_key) -{ - struct ssl_primary_config *ssl = Curl_ssl_cf_get_primary_config(cf); - struct dynbuf buf; - size_t key_len; - bool is_local = FALSE; - CURLcode r; - - *ppeer_key = NULL; - curlx_dyn_init(&buf, 10 * 1024); - - r = curlx_dyn_addf(&buf, "%s:%d", peer->hostname, peer->port); - if(r) - goto out; - - switch(peer->transport) { - case TRNSPRT_TCP: - break; - case TRNSPRT_UDP: - r = curlx_dyn_add(&buf, ":UDP"); - break; - case TRNSPRT_QUIC: - r = curlx_dyn_add(&buf, ":QUIC"); - break; - case TRNSPRT_UNIX: - r = curlx_dyn_add(&buf, ":UNIX"); - break; - default: - r = curlx_dyn_addf(&buf, ":TRNSPRT-%d", peer->transport); - break; - } - if(r) - goto out; - - if(!ssl->verifypeer) { - r = curlx_dyn_add(&buf, ":NO-VRFY-PEER"); - if(r) - goto out; - } - if(!ssl->verifyhost) { - r = curlx_dyn_add(&buf, ":NO-VRFY-HOST"); - if(r) - goto out; - } - if(ssl->verifystatus) { - r = curlx_dyn_add(&buf, ":VRFY-STATUS"); - if(r) - goto out; - } - if(!ssl->verifypeer || !ssl->verifyhost) { - if(cf->conn->bits.conn_to_host) { - r = curlx_dyn_addf(&buf, ":CHOST-%s", cf->conn->conn_to_host.name); - if(r) - goto out; - } - if(cf->conn->bits.conn_to_port) { - r = curlx_dyn_addf(&buf, ":CPORT-%d", cf->conn->conn_to_port); - if(r) - goto out; - } - } - - if(ssl->version || ssl->version_max) { - r = curlx_dyn_addf(&buf, ":TLSVER-%d-%u", ssl->version, - (ssl->version_max >> 16)); - if(r) - goto out; - } - if(ssl->ssl_options) { - r = curlx_dyn_addf(&buf, ":TLSOPT-%x", ssl->ssl_options); - if(r) - goto out; - } - if(ssl->cipher_list) { - r = curlx_dyn_addf(&buf, ":CIPHER-%s", ssl->cipher_list); - if(r) - goto out; - } - if(ssl->cipher_list13) { - r = curlx_dyn_addf(&buf, ":CIPHER13-%s", ssl->cipher_list13); - if(r) - goto out; - } - if(ssl->curves) { - r = curlx_dyn_addf(&buf, ":CURVES-%s", ssl->curves); - if(r) - goto out; - } - if(ssl->verifypeer) { - r = cf_ssl_peer_key_add_path(&buf, "CA", ssl->CAfile, &is_local); - if(r) - goto out; - r = cf_ssl_peer_key_add_path(&buf, "CApath", ssl->CApath, &is_local); - if(r) - goto out; - r = cf_ssl_peer_key_add_path(&buf, "CRL", ssl->CRLfile, &is_local); - if(r) - goto out; - r = cf_ssl_peer_key_add_path(&buf, "Issuer", ssl->issuercert, &is_local); - if(r) - goto out; - if(ssl->ca_info_blob) { - r = cf_ssl_peer_key_add_hash(&buf, "CAInfoBlob", ssl->ca_info_blob); - if(r) - goto out; - } - if(ssl->issuercert_blob) { - r = cf_ssl_peer_key_add_hash(&buf, "IssuerBlob", ssl->issuercert_blob); - if(r) - goto out; - } - } - if(ssl->cert_blob) { - r = cf_ssl_peer_key_add_hash(&buf, "CertBlob", ssl->cert_blob); - if(r) - goto out; - } - if(ssl->pinned_key && ssl->pinned_key[0]) { - r = curlx_dyn_addf(&buf, ":Pinned-%s", ssl->pinned_key); - if(r) - goto out; - } - - if(ssl->clientcert && ssl->clientcert[0]) { - r = curlx_dyn_add(&buf, ":CCERT"); - if(r) - goto out; - } -#ifdef USE_TLS_SRP - if(ssl->username || ssl->password) { - r = curlx_dyn_add(&buf, ":SRP-AUTH"); - if(r) - goto out; - } -#endif - - if(!tls_id || !tls_id[0]) { - r = CURLE_FAILED_INIT; - goto out; - } - r = curlx_dyn_addf(&buf, ":IMPL-%s", tls_id); - if(r) - goto out; - - r = curlx_dyn_addf(&buf, is_local ? - CURL_SSLS_LOCAL_SUFFIX : CURL_SSLS_GLOBAL_SUFFIX); - if(r) - goto out; - - *ppeer_key = curlx_dyn_take(&buf, &key_len); - /* we added printable char, and dynbuf always null-terminates, no need - * to track length */ - -out: - curlx_dyn_free(&buf); - return r; -} - -struct Curl_ssl_scache { - unsigned int magic; - struct Curl_ssl_scache_peer *peers; - size_t peer_count; - int default_lifetime_secs; - long age; - BIT(is_locked); -}; - -static struct Curl_ssl_scache *cf_ssl_scache_get(struct Curl_easy *data) -{ - struct Curl_ssl_scache *scache = NULL; - /* If a share is present, its ssl_scache has preference over the multi */ - if(data->share && data->share->ssl_scache) - scache = data->share->ssl_scache; - else if(data->multi && data->multi->ssl_scache) - scache = data->multi->ssl_scache; - if(scache && !GOOD_SCACHE(scache)) { - failf(data, "transfer would use an invalid scache at %p, denied", - (void *)scache); - DEBUGASSERT(0); - return NULL; - } - return scache; -} - -static void cf_ssl_scache_session_ldestroy(void *udata, void *obj) -{ - struct Curl_ssl_session *s = obj; - (void)udata; - curlx_free(CURL_UNCONST(s->sdata)); - curlx_free(CURL_UNCONST(s->quic_tp)); - curlx_free((void *)s->alpn); - curlx_free(s); -} - -CURLcode Curl_ssl_session_create(void *sdata, size_t sdata_len, - int ietf_tls_id, const char *alpn, - curl_off_t valid_until, size_t earlydata_max, - struct Curl_ssl_session **psession) -{ - return Curl_ssl_session_create2(sdata, sdata_len, ietf_tls_id, alpn, - valid_until, earlydata_max, - NULL, 0, psession); -} - -CURLcode Curl_ssl_session_create2(void *sdata, size_t sdata_len, - int ietf_tls_id, const char *alpn, - curl_off_t valid_until, size_t earlydata_max, - unsigned char *quic_tp, size_t quic_tp_len, - struct Curl_ssl_session **psession) -{ - struct Curl_ssl_session *s; - - if(!sdata || !sdata_len) { - curlx_free(sdata); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - *psession = NULL; - s = curlx_calloc(1, sizeof(*s)); - if(!s) { - curlx_free(sdata); - curlx_free(quic_tp); - return CURLE_OUT_OF_MEMORY; - } - - s->ietf_tls_id = ietf_tls_id; - s->valid_until = valid_until; - s->earlydata_max = earlydata_max; - s->sdata = sdata; - s->sdata_len = sdata_len; - s->quic_tp = quic_tp; - s->quic_tp_len = quic_tp_len; - if(alpn) { - s->alpn = curlx_strdup(alpn); - if(!s->alpn) { - cf_ssl_scache_session_ldestroy(NULL, s); - return CURLE_OUT_OF_MEMORY; - } - } - *psession = s; - return CURLE_OK; -} - -void Curl_ssl_session_destroy(struct Curl_ssl_session *s) -{ - if(s) { - /* if in the list, the list destructor takes care of it */ - if(Curl_node_llist(&s->list)) - Curl_node_remove(&s->list); - else { - cf_ssl_scache_session_ldestroy(NULL, s); - } - } -} - -static void cf_ssl_scache_clear_peer(struct Curl_ssl_scache_peer *peer) -{ - Curl_llist_destroy(&peer->sessions, NULL); - if(peer->sobj) { - DEBUGASSERT(peer->sobj_free); - if(peer->sobj_free) - peer->sobj_free(peer->sobj); - peer->sobj = NULL; - } - peer->sobj_free = NULL; - curlx_safefree(peer->clientcert); -#ifdef USE_TLS_SRP - curlx_safefree(peer->srp_username); - curlx_safefree(peer->srp_password); -#endif - curlx_safefree(peer->ssl_peer_key); - peer->age = 0; - peer->hmac_set = FALSE; -} - -static void cf_ssl_scache_peer_set_obj(struct Curl_ssl_scache_peer *peer, - void *sobj, - Curl_ssl_scache_obj_dtor *sobj_free) -{ - DEBUGASSERT(peer); - if(peer->sobj_free) { - peer->sobj_free(peer->sobj); - } - peer->sobj = sobj; - peer->sobj_free = sobj_free; -} - -static void cf_ssl_cache_peer_update(struct Curl_ssl_scache_peer *peer) -{ - /* The sessions of this peer are exportable if - * - it has no confidential information - * - its peer key is not yet known, because sessions were - * imported using only the salt+hmac - * - the peer key is global, e.g. carrying no relative paths */ - peer->exportable = (!peer->clientcert && !peer->srp_username && - !peer->srp_password && - (!peer->ssl_peer_key || - cf_ssl_peer_key_is_global(peer->ssl_peer_key))); -} - -static CURLcode -cf_ssl_scache_peer_init(struct Curl_ssl_scache_peer *peer, - const char *ssl_peer_key, - const char *clientcert, - const char *srp_username, - const char *srp_password, - const unsigned char *salt, - const unsigned char *hmac) -{ - CURLcode result = CURLE_OUT_OF_MEMORY; - - DEBUGASSERT(!peer->ssl_peer_key); - if(ssl_peer_key) { - peer->ssl_peer_key = curlx_strdup(ssl_peer_key); - if(!peer->ssl_peer_key) - goto out; - peer->hmac_set = FALSE; - } - else if(salt && hmac) { - memcpy(peer->key_salt, salt, sizeof(peer->key_salt)); - memcpy(peer->key_hmac, hmac, sizeof(peer->key_hmac)); - peer->hmac_set = TRUE; - } - else { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - if(clientcert) { - peer->clientcert = curlx_strdup(clientcert); - if(!peer->clientcert) - goto out; - } - if(srp_username) { - peer->srp_username = curlx_strdup(srp_username); - if(!peer->srp_username) - goto out; - } - if(srp_password) { - peer->srp_password = curlx_strdup(srp_password); - if(!peer->srp_password) - goto out; - } - - cf_ssl_cache_peer_update(peer); - result = CURLE_OK; -out: - if(result) - cf_ssl_scache_clear_peer(peer); - return result; -} - -static void cf_scache_session_remove(struct Curl_ssl_scache_peer *peer, - struct Curl_ssl_session *s) -{ - (void)peer; - DEBUGASSERT(Curl_node_llist(&s->list) == &peer->sessions); - Curl_ssl_session_destroy(s); -} - -static bool cf_scache_session_expired(struct Curl_ssl_session *s, - curl_off_t now) -{ - return (s->valid_until > 0) && (s->valid_until < now); -} - -static void cf_scache_peer_remove_expired(struct Curl_ssl_scache_peer *peer, - curl_off_t now) -{ - struct Curl_llist_node *n = Curl_llist_head(&peer->sessions); - while(n) { - struct Curl_ssl_session *s = Curl_node_elem(n); - n = Curl_node_next(n); - if(cf_scache_session_expired(s, now)) - cf_scache_session_remove(peer, s); - } -} - -static void cf_scache_peer_remove_non13(struct Curl_ssl_scache_peer *peer) -{ - struct Curl_llist_node *n = Curl_llist_head(&peer->sessions); - while(n) { - struct Curl_ssl_session *s = Curl_node_elem(n); - n = Curl_node_next(n); - if(s->ietf_tls_id != CURL_IETF_PROTO_TLS1_3) - cf_scache_session_remove(peer, s); - } -} - -CURLcode Curl_ssl_scache_create(size_t max_peers, - size_t max_sessions_per_peer, - struct Curl_ssl_scache **pscache) -{ - struct Curl_ssl_scache *scache; - struct Curl_ssl_scache_peer *peers; - size_t i; - - *pscache = NULL; - peers = curlx_calloc(max_peers, sizeof(*peers)); - if(!peers) - return CURLE_OUT_OF_MEMORY; - - scache = curlx_calloc(1, sizeof(*scache)); - if(!scache) { - curlx_free(peers); - return CURLE_OUT_OF_MEMORY; - } - - scache->magic = CURL_SCACHE_MAGIC; - scache->default_lifetime_secs = (24 * 60 * 60); /* 1 day */ - scache->peer_count = max_peers; - scache->peers = peers; - scache->age = 1; - for(i = 0; i < scache->peer_count; ++i) { - scache->peers[i].max_sessions = max_sessions_per_peer; - Curl_llist_init(&scache->peers[i].sessions, - cf_ssl_scache_session_ldestroy); - } - - *pscache = scache; - return CURLE_OK; -} - -void Curl_ssl_scache_destroy(struct Curl_ssl_scache *scache) -{ - if(GOOD_SCACHE(scache)) { - size_t i; - scache->magic = 0; - for(i = 0; i < scache->peer_count; ++i) { - cf_ssl_scache_clear_peer(&scache->peers[i]); - } - curlx_free(scache->peers); - curlx_free(scache); - } -} - -bool Curl_ssl_scache_use(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - if(cf_ssl_scache_get(data)) { - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - return ssl_config ? ssl_config->primary.cache_session : FALSE; - } - return FALSE; -} - -/* Lock shared SSL session data */ -void Curl_ssl_scache_lock(struct Curl_easy *data) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - if(scache) { - if(CURL_SHARE_ssl_scache(data)) - Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_ACCESS_SINGLE); - DEBUGASSERT(!scache->is_locked); - scache->is_locked = TRUE; - } -} - -/* Unlock shared SSL session data */ -void Curl_ssl_scache_unlock(struct Curl_easy *data) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - if(scache) { - DEBUGASSERT(scache->is_locked); - scache->is_locked = FALSE; - if(CURL_SHARE_ssl_scache(data)) - Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); - } -} - -static bool cf_ssl_scache_match_auth(struct Curl_ssl_scache_peer *peer, - struct ssl_primary_config *conn_config) -{ - if(!conn_config) { - if(peer->clientcert) - return FALSE; -#ifdef USE_TLS_SRP - if(peer->srp_username || peer->srp_password) - return FALSE; -#endif - return TRUE; - } - else if(!Curl_safecmp(peer->clientcert, conn_config->clientcert)) - return FALSE; -#ifdef USE_TLS_SRP - if(Curl_timestrcmp(peer->srp_username, conn_config->username) || - Curl_timestrcmp(peer->srp_password, conn_config->password)) - return FALSE; -#endif - return TRUE; -} - -static CURLcode cf_ssl_find_peer_by_key(struct Curl_easy *data, - struct Curl_ssl_scache *scache, - const char *ssl_peer_key, - struct ssl_primary_config *conn_config, - struct Curl_ssl_scache_peer **ppeer) -{ - size_t i, peer_key_len = 0; - CURLcode result = CURLE_OK; - - *ppeer = NULL; - if(!GOOD_SCACHE(scache)) { - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - CURL_TRC_SSLS(data, "find peer slot for %s among %zu slots", - ssl_peer_key, scache->peer_count); - - /* check for entries with known peer_key */ - for(i = 0; scache && i < scache->peer_count; i++) { - if(scache->peers[i].ssl_peer_key && - curl_strequal(ssl_peer_key, scache->peers[i].ssl_peer_key) && - cf_ssl_scache_match_auth(&scache->peers[i], conn_config)) { - /* yes, we have a cached session for this! */ - *ppeer = &scache->peers[i]; - goto out; - } - } - /* check for entries with HMAC set but no known peer_key */ - for(i = 0; scache && i < scache->peer_count; i++) { - if(!scache->peers[i].ssl_peer_key && - scache->peers[i].hmac_set && - cf_ssl_scache_match_auth(&scache->peers[i], conn_config)) { - /* possible entry with unknown peer_key, check hmac */ - unsigned char my_hmac[CURL_SHA256_DIGEST_LENGTH]; - if(!peer_key_len) /* we are lazy */ - peer_key_len = strlen(ssl_peer_key); - result = Curl_hmacit(&Curl_HMAC_SHA256, - scache->peers[i].key_salt, - sizeof(scache->peers[i].key_salt), - (const unsigned char *)ssl_peer_key, - peer_key_len, - my_hmac); - if(result) - goto out; - if(!memcmp(scache->peers[i].key_hmac, my_hmac, sizeof(my_hmac))) { - /* remember peer_key for future lookups */ - CURL_TRC_SSLS(data, "peer entry %zu key recovered: %s", - i, ssl_peer_key); - scache->peers[i].ssl_peer_key = curlx_strdup(ssl_peer_key); - if(!scache->peers[i].ssl_peer_key) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - cf_ssl_cache_peer_update(&scache->peers[i]); - *ppeer = &scache->peers[i]; - goto out; - } - } - } - CURL_TRC_SSLS(data, "peer not found for %s", ssl_peer_key); -out: - return result; -} - -static struct Curl_ssl_scache_peer * -cf_ssl_get_free_peer(struct Curl_ssl_scache *scache) -{ - struct Curl_ssl_scache_peer *peer = NULL; - size_t i; - - /* find empty or oldest peer */ - for(i = 0; i < scache->peer_count; ++i) { - /* free peer entry? */ - if(!scache->peers[i].ssl_peer_key && !scache->peers[i].hmac_set) { - peer = &scache->peers[i]; - break; - } - /* peer without sessions and obj */ - if(!scache->peers[i].sobj && - !Curl_llist_count(&scache->peers[i].sessions)) { - peer = &scache->peers[i]; - break; - } - /* remember "oldest" peer */ - if(!peer || (scache->peers[i].age < peer->age)) { - peer = &scache->peers[i]; - } - } - DEBUGASSERT(peer); - if(peer) - cf_ssl_scache_clear_peer(peer); - return peer; -} - -static CURLcode cf_ssl_add_peer(struct Curl_easy *data, - struct Curl_ssl_scache *scache, - const char *ssl_peer_key, - struct ssl_primary_config *conn_config, - struct Curl_ssl_scache_peer **ppeer) -{ - struct Curl_ssl_scache_peer *peer = NULL; - CURLcode result = CURLE_OK; - - *ppeer = NULL; - if(ssl_peer_key) { - result = cf_ssl_find_peer_by_key(data, scache, ssl_peer_key, conn_config, - &peer); - if(result || !scache->peer_count) - return result; - } - - if(peer) { - *ppeer = peer; - return CURLE_OK; - } - - peer = cf_ssl_get_free_peer(scache); - if(peer) { - char buffer[64]; - const char *ccert = conn_config ? conn_config->clientcert : NULL; - const char *username = NULL, *password = NULL; -#ifdef USE_TLS_SRP - username = conn_config ? conn_config->username : NULL; - password = conn_config ? conn_config->password : NULL; -#endif - if(!ccert && conn_config && conn_config->cert_blob) { - /* when using a client cert blob, create a name for it */ - curl_msnprintf(buffer, sizeof(buffer), - "cert-%p", conn_config->cert_blob->data); - ccert = buffer; /* data is strduped by cf_ssl_scache_peer_init */ - } - result = cf_ssl_scache_peer_init(peer, ssl_peer_key, ccert, - username, password, NULL, NULL); - if(result) - goto out; - /* all ready */ - *ppeer = peer; - result = CURLE_OK; - } - -out: - if(result) { - cf_ssl_scache_clear_peer(peer); - } - return result; -} - -static void cf_scache_peer_add_session(struct Curl_ssl_scache_peer *peer, - struct Curl_ssl_session *s, - curl_off_t now) -{ - /* A session not from TLSv1.3 replaces all other. */ - if(s->ietf_tls_id != CURL_IETF_PROTO_TLS1_3) { - Curl_llist_destroy(&peer->sessions, NULL); - Curl_llist_append(&peer->sessions, s, &s->list); - } - else { - /* Expire existing, append, trim from head to obey max_sessions */ - cf_scache_peer_remove_expired(peer, now); - cf_scache_peer_remove_non13(peer); - Curl_llist_append(&peer->sessions, s, &s->list); - while(Curl_llist_count(&peer->sessions) > peer->max_sessions) { - Curl_node_remove(Curl_llist_head(&peer->sessions)); - } - } -} - -static CURLcode cf_scache_add_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct Curl_ssl_scache *scache, - const char *ssl_peer_key, - struct Curl_ssl_session *s) -{ - struct Curl_ssl_scache_peer *peer = NULL; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - CURLcode result = CURLE_OUT_OF_MEMORY; - curl_off_t now = (curl_off_t)time(NULL); - curl_off_t max_lifetime; - - if(!scache || !scache->peer_count) { - Curl_ssl_session_destroy(s); - return CURLE_OK; - } - - if(s->valid_until <= 0) - s->valid_until = now + scache->default_lifetime_secs; - - max_lifetime = (s->ietf_tls_id == CURL_IETF_PROTO_TLS1_3) ? - CURL_SCACHE_MAX_13_LIFETIME_SEC : - CURL_SCACHE_MAX_12_LIFETIME_SEC; - if(s->valid_until > (now + max_lifetime)) - s->valid_until = now + max_lifetime; - - if(cf_scache_session_expired(s, now)) { - CURL_TRC_SSLS(data, "add, session already expired"); - Curl_ssl_session_destroy(s); - return CURLE_OK; - } - - result = cf_ssl_add_peer(data, scache, ssl_peer_key, conn_config, &peer); - if(result || !peer) { - CURL_TRC_SSLS(data, "unable to add scache peer: %d", result); - Curl_ssl_session_destroy(s); - goto out; - } - - cf_scache_peer_add_session(peer, s, now); - -out: - if(result) { - failf(data, "[SCACHE] failed to add session for %s, error=%d", - ssl_peer_key, result); - } - else - CURL_TRC_SSLS(data, "added session for %s [proto=0x%x, " - "valid_secs=%" FMT_OFF_T ", alpn=%s, earlydata=%zu, " - "quic_tp=%s], peer has %zu sessions now", - ssl_peer_key, s->ietf_tls_id, s->valid_until - now, - s->alpn, s->earlydata_max, s->quic_tp ? "yes" : "no", - peer ? Curl_llist_count(&peer->sessions) : 0); - return result; -} - -CURLcode Curl_ssl_scache_put(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct Curl_ssl_session *s) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - CURLcode result; - DEBUGASSERT(ssl_config); - - if(!scache || !ssl_config->primary.cache_session) { - Curl_ssl_session_destroy(s); - return CURLE_OK; - } - - Curl_ssl_scache_lock(data); - result = cf_scache_add_session(cf, data, scache, ssl_peer_key, s); - Curl_ssl_scache_unlock(data); - return result; -} - -void Curl_ssl_scache_return(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct Curl_ssl_session *s) -{ - /* See RFC 8446 C.4: - * "Clients SHOULD NOT reuse a ticket for multiple connections." */ - if(s && s->ietf_tls_id < 0x304) - (void)Curl_ssl_scache_put(cf, data, ssl_peer_key, s); - else - Curl_ssl_session_destroy(s); -} - -CURLcode Curl_ssl_scache_take(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct Curl_ssl_session **ps) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_ssl_scache_peer *peer = NULL; - struct Curl_llist_node *n; - struct Curl_ssl_session *s = NULL; - CURLcode result; - - *ps = NULL; - if(!scache) - return CURLE_OK; - - Curl_ssl_scache_lock(data); - result = cf_ssl_find_peer_by_key(data, scache, ssl_peer_key, conn_config, - &peer); - if(!result && peer) { - cf_scache_peer_remove_expired(peer, (curl_off_t)time(NULL)); - n = Curl_llist_head(&peer->sessions); - if(n) { - s = Curl_node_take_elem(n); - (scache->age)++; /* increase general age */ - peer->age = scache->age; /* set this as used in this age */ - } - } - if(s) { - *ps = s; - CURL_TRC_SSLS(data, "took session for %s [proto=0x%x, " - "alpn=%s, earlydata=%zu, quic_tp=%s], %zu sessions remain", - ssl_peer_key, s->ietf_tls_id, s->alpn, - s->earlydata_max, s->quic_tp ? "yes" : "no", - Curl_llist_count(&peer->sessions)); - } - else { - CURL_TRC_SSLS(data, "no cached session for %s", ssl_peer_key); - } - Curl_ssl_scache_unlock(data); - return result; -} - -CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - void *sobj, - Curl_ssl_scache_obj_dtor *sobj_dtor_cb) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_ssl_scache_peer *peer = NULL; - CURLcode result; - - DEBUGASSERT(sobj); - DEBUGASSERT(sobj_dtor_cb); - - if(!scache) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - - result = cf_ssl_add_peer(data, scache, ssl_peer_key, conn_config, &peer); - if(result || !peer) { - CURL_TRC_SSLS(data, "unable to add scache peer: %d", result); - goto out; - } - - cf_ssl_scache_peer_set_obj(peer, sobj, sobj_dtor_cb); - sobj = NULL; /* peer took ownership */ - -out: - if(sobj && sobj_dtor_cb) - sobj_dtor_cb(sobj); - return result; -} - -void *Curl_ssl_scache_get_obj(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_ssl_scache_peer *peer = NULL; - CURLcode result; - void *sobj; - - if(!scache) - return NULL; - - result = cf_ssl_find_peer_by_key(data, scache, ssl_peer_key, conn_config, - &peer); - if(result) - return NULL; - - sobj = peer ? peer->sobj : NULL; - - CURL_TRC_SSLS(data, "%s cached session for '%s'", - sobj ? "Found" : "No", ssl_peer_key); - return sobj; -} - -void Curl_ssl_scache_remove_all(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_ssl_scache_peer *peer = NULL; - CURLcode result; - - (void)cf; - if(!scache) - return; - - Curl_ssl_scache_lock(data); - result = cf_ssl_find_peer_by_key(data, scache, ssl_peer_key, conn_config, - &peer); - if(!result && peer) - cf_ssl_scache_clear_peer(peer); - Curl_ssl_scache_unlock(data); -} - -#ifdef USE_SSLS_EXPORT - -#define CURL_SSL_TICKET_MAX (16 * 1024) - -bool Curl_ssl_scache_is_locked(struct Curl_easy *data) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - return scache && scache->is_locked; -} - -static CURLcode cf_ssl_scache_peer_set_hmac(struct Curl_ssl_scache_peer *peer) -{ - CURLcode result; - - DEBUGASSERT(peer); - if(!peer->ssl_peer_key) - return CURLE_BAD_FUNCTION_ARGUMENT; - - result = Curl_rand(NULL, peer->key_salt, sizeof(peer->key_salt)); - if(result) - return result; - - result = Curl_hmacit(&Curl_HMAC_SHA256, - peer->key_salt, sizeof(peer->key_salt), - (const unsigned char *)peer->ssl_peer_key, - strlen(peer->ssl_peer_key), - peer->key_hmac); - if(!result) - peer->hmac_set = TRUE; - return result; -} - -static CURLcode -cf_ssl_find_peer_by_hmac(struct Curl_ssl_scache *scache, - const unsigned char *salt, - const unsigned char *hmac, - struct Curl_ssl_scache_peer **ppeer) -{ - size_t i; - CURLcode result = CURLE_OK; - - *ppeer = NULL; - if(!GOOD_SCACHE(scache)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* look for an entry that matches salt+hmac exactly or has a known - * ssl_peer_key which salt+hmac's to the same. */ - for(i = 0; scache && i < scache->peer_count; i++) { - struct Curl_ssl_scache_peer *peer = &scache->peers[i]; - if(!cf_ssl_scache_match_auth(peer, NULL)) - continue; - if(scache->peers[i].hmac_set && - !memcmp(peer->key_salt, salt, sizeof(peer->key_salt)) && - !memcmp(peer->key_hmac, hmac, sizeof(peer->key_hmac))) { - /* found exact match, return */ - *ppeer = peer; - goto out; - } - else if(peer->ssl_peer_key) { - unsigned char my_hmac[CURL_SHA256_DIGEST_LENGTH]; - /* compute hmac for the passed salt */ - result = Curl_hmacit(&Curl_HMAC_SHA256, - salt, sizeof(peer->key_salt), - (const unsigned char *)peer->ssl_peer_key, - strlen(peer->ssl_peer_key), - my_hmac); - if(result) - goto out; - if(!memcmp(my_hmac, hmac, sizeof(my_hmac))) { - /* cryptohash match, take over salt+hmac if no set and return */ - if(!peer->hmac_set) { - memcpy(peer->key_salt, salt, sizeof(peer->key_salt)); - memcpy(peer->key_hmac, hmac, sizeof(peer->key_hmac)); - peer->hmac_set = TRUE; - } - *ppeer = peer; - goto out; - } - } - } -out: - return result; -} - -CURLcode Curl_ssl_session_import(struct Curl_easy *data, - const char *ssl_peer_key, - const unsigned char *shmac, size_t shmac_len, - const void *sdata, size_t sdata_len) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - struct Curl_ssl_scache_peer *peer = NULL; - struct Curl_ssl_session *s = NULL; - CURLcode result; - - if(!scache) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - if(!ssl_peer_key && (!shmac || !shmac_len)) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - - result = Curl_ssl_session_unpack(data, sdata, sdata_len, &s); - if(result) - goto out; - - Curl_ssl_scache_lock(data); - - if(ssl_peer_key) { - result = cf_ssl_add_peer(data, scache, ssl_peer_key, NULL, &peer); - if(result) - goto out; - } - else if(shmac_len != (sizeof(peer->key_salt) + sizeof(peer->key_hmac))) { - /* Either salt+hmac was garbled by caller or is from a curl version - * that does things differently */ - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - else { - const unsigned char *salt = shmac; - const unsigned char *hmac = shmac + sizeof(peer->key_salt); - - result = cf_ssl_find_peer_by_hmac(scache, salt, hmac, &peer); - if(result) - goto out; - if(!peer) { - peer = cf_ssl_get_free_peer(scache); - if(peer) { - result = cf_ssl_scache_peer_init(peer, ssl_peer_key, NULL, - NULL, NULL, salt, hmac); - if(result) - goto out; - } - } - } - - if(peer) { - cf_scache_peer_add_session(peer, s, time(NULL)); - s = NULL; /* peer is now owner */ - CURL_TRC_SSLS(data, "successfully imported ticket for peer %s, now " - "with %zu tickets", - peer->ssl_peer_key ? peer->ssl_peer_key : "without key", - Curl_llist_count(&peer->sessions)); - } - -out: - if(scache && scache->is_locked) - Curl_ssl_scache_unlock(data); - Curl_ssl_session_destroy(s); - return result; -} - -CURLcode Curl_ssl_session_export(struct Curl_easy *data, - curl_ssls_export_cb *export_fn, - void *userptr) -{ - struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); - struct Curl_ssl_scache_peer *peer; - struct dynbuf sbuf, hbuf; - struct Curl_llist_node *n; - size_t i; - curl_off_t now = time(NULL); - CURLcode r = CURLE_OK; -#ifdef CURLVERBOSE - size_t npeers = 0, ntickets = 0; -#endif - - if(!export_fn) - return CURLE_BAD_FUNCTION_ARGUMENT; - - Curl_ssl_scache_lock(data); - - curlx_dyn_init(&hbuf, (CURL_SHA256_DIGEST_LENGTH * 2) + 1); - curlx_dyn_init(&sbuf, CURL_SSL_TICKET_MAX); - - for(i = 0; scache && i < scache->peer_count; i++) { - peer = &scache->peers[i]; - if(!peer->ssl_peer_key && !peer->hmac_set) - continue; /* skip free entry */ - if(!peer->exportable) - continue; - - curlx_dyn_reset(&hbuf); - cf_scache_peer_remove_expired(peer, now); - n = Curl_llist_head(&peer->sessions); - if(n) - VERBOSE(++npeers); - while(n) { - struct Curl_ssl_session *s = Curl_node_elem(n); - if(!peer->hmac_set) { - r = cf_ssl_scache_peer_set_hmac(peer); - if(r) - goto out; - } - if(!curlx_dyn_len(&hbuf)) { - r = curlx_dyn_addn(&hbuf, peer->key_salt, sizeof(peer->key_salt)); - if(r) - goto out; - r = curlx_dyn_addn(&hbuf, peer->key_hmac, sizeof(peer->key_hmac)); - if(r) - goto out; - } - curlx_dyn_reset(&sbuf); - r = Curl_ssl_session_pack(data, s, &sbuf); - if(r) - goto out; - - r = export_fn(data, userptr, peer->ssl_peer_key, - curlx_dyn_uptr(&hbuf), curlx_dyn_len(&hbuf), - curlx_dyn_uptr(&sbuf), curlx_dyn_len(&sbuf), - s->valid_until, s->ietf_tls_id, - s->alpn, s->earlydata_max); - if(r) - goto out; - VERBOSE(++ntickets); - n = Curl_node_next(n); - } - } - r = CURLE_OK; - CURL_TRC_SSLS(data, "exported %zu session tickets for %zu peers", - ntickets, npeers); - -out: - Curl_ssl_scache_unlock(data); - curlx_dyn_free(&hbuf); - curlx_dyn_free(&sbuf); - return r; -} - -#endif /* USE_SSLS_EXPORT */ - -#endif /* USE_SSL */ diff --git a/vendor/curl/lib/vtls/vtls_scache.h b/vendor/curl/lib/vtls/vtls_scache.h deleted file mode 100644 index a6a36f163..000000000 --- a/vendor/curl/lib/vtls/vtls_scache.h +++ /dev/null @@ -1,216 +0,0 @@ -#ifndef HEADER_CURL_VTLS_SCACHE_H -#define HEADER_CURL_VTLS_SCACHE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SSL - -#include "cfilters.h" -#include "urldata.h" - -struct Curl_cfilter; -struct Curl_easy; -struct Curl_ssl_scache; -struct Curl_ssl_session; -struct ssl_peer; - -/* RFC 8446 (TLSv1.3) restrict lifetime to one week max, for - * other, less secure versions, we restrict it to a day */ -#define CURL_SCACHE_MAX_13_LIFETIME_SEC (60 * 60 * 24 * 7) -#define CURL_SCACHE_MAX_12_LIFETIME_SEC (60 * 60 * 24) - -/* Create a session cache for up to max_peers endpoints with a total - * of up to max_sessions SSL sessions per peer */ -CURLcode Curl_ssl_scache_create(size_t max_peers, - size_t max_sessions_per_peer, - struct Curl_ssl_scache **pscache); - -void Curl_ssl_scache_destroy(struct Curl_ssl_scache *scache); - -/* Create a key from peer and TLS configuration information that is - * unique for how the connection filter wants to establish a TLS - * connection to the peer. - * If the filter is a TLS proxy filter, it uses the proxy relevant - * information. - * @param cf the connection filter wanting to use it - * @param peer the peer the filter wants to talk to - * @param tls_id identifier of TLS implementation for sessions. Should - * include full version if session data from other versions - * is to be avoided. - * @param ppeer_key on successful return, the key generated - */ -CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf, - const struct ssl_peer *peer, - const char *tls_id, - char **ppeer_key); - -/* Return if there is a session cache shall be used. - * An ssl session might not be configured or not available for - * "connect-only" transfers. - */ -bool Curl_ssl_scache_use(struct Curl_cfilter *cf, struct Curl_easy *data); - -/* Lock session cache mutex. - * Call this before calling other Curl_ssl_*session* functions - * Caller should unlock this mutex as soon as possible, as it may block - * other SSL connection from making progress. - * The purpose of explicitly locking SSL session cache data is to allow - * individual SSL engines to manage session lifetime in their specific way. - */ -void Curl_ssl_scache_lock(struct Curl_easy *data); - -/* Unlock session cache mutex */ -void Curl_ssl_scache_unlock(struct Curl_easy *data); - -/* Get TLS session object from the cache for the ssl_peer_key. - * scache mutex must be locked (see Curl_ssl_scache_lock). - * Caller must make sure that the ownership of returned session object - * is properly taken (e.g. its refcount is incremented - * under scache mutex). - * @param cf the connection filter wanting to use it - * @param data the transfer involved - * @param ssl_peer_key the key for lookup - * @retval sobj the object for the peer key or NULL - */ -void *Curl_ssl_scache_get_obj(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key); - -typedef void Curl_ssl_scache_obj_dtor(void *sobj); - -/* Add a TLS session related object to the cache. - * Replaces an existing object with the same peer_key. - * scache mutex must be locked (see Curl_ssl_scache_lock). - * Call takes ownership of `sobj`, using `sobj_dtor_cb` - * to deallocate it. Is called in all outcomes, either right away or - * later when the session cache is cleaned up. - * Caller must ensure that it has properly shared ownership of `sobj` - * with cache (e.g. incrementing refcount on success) - * @param cf the connection filter wanting to use it - * @param data the transfer involved - * @param ssl_peer_key the key for lookup - * @param sobj the TLS session object - * @param sobj_free_cb callback to free the session object - */ -CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - void *sobj, - Curl_ssl_scache_obj_dtor *sobj_dtor_cb); - -/* All about an SSL session ticket */ -struct Curl_ssl_session { - const void *sdata; /* session ticket data, plain bytes */ - size_t sdata_len; /* number of bytes in sdata */ - curl_off_t valid_until; /* seconds since EPOCH until ticket expires */ - int ietf_tls_id; /* TLS protocol identifier negotiated */ - char *alpn; /* APLN TLS negotiated protocol string */ - size_t earlydata_max; /* max 0-RTT data supported by peer */ - const unsigned char *quic_tp; /* Optional QUIC transport param bytes */ - size_t quic_tp_len; /* number of bytes in quic_tp */ - struct Curl_llist_node list; /* internal storage handling */ -}; - -/* Create a `session` instance. Does NOT need locking. - * Takes ownership of `sdata` and `sobj` regardless of return code. - * @param sdata bytes of SSL session data or NULL (sobj then required) - * @param sdata_len amount of session data bytes - * @param ietf_tls_id IETF protocol version, e.g. 0x304 for TLSv1.3 - * @param alpn ALPN protocol selected or NULL - * @param valid_until seconds since EPOCH when session expires, pass 0 - * in case this is not known. - * @param psession on return the scached session instance created - */ -CURLcode Curl_ssl_session_create(void *sdata, size_t sdata_len, - int ietf_tls_id, const char *alpn, - curl_off_t valid_until, size_t earlydata_max, - struct Curl_ssl_session **psession); - -/* Variation of session creation with quic transport parameter bytes, - * Takes ownership of `quic_tp` regardless of return code. */ -CURLcode Curl_ssl_session_create2(void *sdata, size_t sdata_len, - int ietf_tls_id, const char *alpn, - curl_off_t valid_until, size_t earlydata_max, - unsigned char *quic_tp, size_t quic_tp_len, - struct Curl_ssl_session **psession); - -/* Destroy a `session` instance. Can be called with NULL. - * Does NOT need locking. */ -void Curl_ssl_session_destroy(struct Curl_ssl_session *s); - -/* Put the scache session into the cache. Does NOT need locking. - * Call takes ownership of `s` in all outcomes. - * @param cf the connection filter wanting to use it - * @param data the transfer involved - * @param ssl_peer_key the key for lookup - * @param s the scache session object - */ -CURLcode Curl_ssl_scache_put(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct Curl_ssl_session *s); - -/* Take a matching scache session from the cache. Does NOT need locking. - * @param cf the connection filter wanting to use it - * @param data the transfer involved - * @param ssl_peer_key the key for lookup - * @param s on return, the scache session object or NULL - */ -CURLcode Curl_ssl_scache_take(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct Curl_ssl_session **ps); - -/* Return a taken scache session to the cache. Does NOT need locking. - * Depending on TLS version and other criteria, it may cache it again - * or destroy it. Maybe called with a NULL session. - */ -void Curl_ssl_scache_return(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct Curl_ssl_session *s); - -/* Remove all sessions and obj for the peer_key. Does NOT need locking. */ -void Curl_ssl_scache_remove_all(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key); - -#ifdef USE_SSLS_EXPORT - -bool Curl_ssl_scache_is_locked(struct Curl_easy *data); - -CURLcode Curl_ssl_session_import(struct Curl_easy *data, - const char *ssl_peer_key, - const unsigned char *shmac, size_t shmac_len, - const void *sdata, size_t sdata_len); - -CURLcode Curl_ssl_session_export(struct Curl_easy *data, - curl_ssls_export_cb *export_fn, - void *userptr); - -#endif /* USE_SSLS_EXPORT */ -#endif /* USE_SSL */ - -#endif /* HEADER_CURL_VTLS_SCACHE_H */ diff --git a/vendor/curl/lib/vtls/vtls_spack.c b/vendor/curl/lib/vtls/vtls_spack.c deleted file mode 100644 index d96f4e41b..000000000 --- a/vendor/curl/lib/vtls/vtls_spack.c +++ /dev/null @@ -1,329 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) - -#include "urldata.h" -#include "curl_trc.h" -#include "vtls/vtls_scache.h" -#include "vtls/vtls_spack.h" -#include "curlx/strdup.h" - -#ifndef UINT16_MAX -#define UINT16_MAX 0xffff -#endif -#ifndef UINT32_MAX -#define UINT32_MAX 0xffffffff -#endif - -#define CURL_SPACK_VERSION 0x01 -#define CURL_SPACK_IETF_ID 0x02 -#define CURL_SPACK_VALID_UNTIL 0x03 -#define CURL_SPACK_TICKET 0x04 -#define CURL_SPACK_ALPN 0x05 -#define CURL_SPACK_EARLYDATA 0x06 -#define CURL_SPACK_QUICTP 0x07 - -static CURLcode spack_enc8(struct dynbuf *buf, uint8_t b) -{ - return curlx_dyn_addn(buf, &b, 1); -} - -static CURLcode spack_dec8(uint8_t *val, const uint8_t **src, - const uint8_t *end) -{ - if(end - *src < 1) - return CURLE_READ_ERROR; - *val = **src; - *src += 1; - return CURLE_OK; -} - -static CURLcode spack_enc16(struct dynbuf *buf, uint16_t val) -{ - uint8_t nval[2]; - nval[0] = (uint8_t)(val >> 8); - nval[1] = (uint8_t)val; - return curlx_dyn_addn(buf, nval, sizeof(nval)); -} - -static CURLcode spack_dec16(uint16_t *val, const uint8_t **src, - const uint8_t *end) -{ - if(end - *src < 2) - return CURLE_READ_ERROR; - *val = (uint16_t)((*src)[0] << 8 | (*src)[1]); - *src += 2; - return CURLE_OK; -} - -static CURLcode spack_enc32(struct dynbuf *buf, uint32_t val) -{ - uint8_t nval[4]; - nval[0] = (uint8_t)(val >> 24); - nval[1] = (uint8_t)(val >> 16); - nval[2] = (uint8_t)(val >> 8); - nval[3] = (uint8_t)val; - return curlx_dyn_addn(buf, nval, sizeof(nval)); -} - -static CURLcode spack_dec32(uint32_t *val, const uint8_t **src, - const uint8_t *end) -{ - if(end - *src < 4) - return CURLE_READ_ERROR; - *val = (uint32_t)(*src)[0] << 24 | (uint32_t)(*src)[1] << 16 | - (uint32_t)(*src)[2] << 8 | (*src)[3]; - *src += 4; - return CURLE_OK; -} - -static CURLcode spack_enc64(struct dynbuf *buf, uint64_t val) -{ - uint8_t nval[8]; - nval[0] = (uint8_t)(val >> 56); - nval[1] = (uint8_t)(val >> 48); - nval[2] = (uint8_t)(val >> 40); - nval[3] = (uint8_t)(val >> 32); - nval[4] = (uint8_t)(val >> 24); - nval[5] = (uint8_t)(val >> 16); - nval[6] = (uint8_t)(val >> 8); - nval[7] = (uint8_t)val; - return curlx_dyn_addn(buf, nval, sizeof(nval)); -} - -static CURLcode spack_dec64(uint64_t *val, const uint8_t **src, - const uint8_t *end) -{ - if(end - *src < 8) - return CURLE_READ_ERROR; - *val = (uint64_t)(*src)[0] << 56 | (uint64_t)(*src)[1] << 48 | - (uint64_t)(*src)[2] << 40 | (uint64_t)(*src)[3] << 32 | - (uint64_t)(*src)[4] << 24 | (uint64_t)(*src)[5] << 16 | - (uint64_t)(*src)[6] << 8 | (*src)[7]; - *src += 8; - return CURLE_OK; -} - -static CURLcode spack_encstr16(struct dynbuf *buf, const char *s) -{ - size_t slen = strlen(s); - CURLcode r; - if(slen > UINT16_MAX) - return CURLE_BAD_FUNCTION_ARGUMENT; - r = spack_enc16(buf, (uint16_t)slen); - if(!r) { - r = curlx_dyn_addn(buf, s, slen); - } - return r; -} - -static CURLcode spack_decstr16(char **val, const uint8_t **src, - const uint8_t *end) -{ - uint16_t slen; - CURLcode r; - - *val = NULL; - r = spack_dec16(&slen, src, end); - if(r) - return r; - if(end - *src < slen) - return CURLE_READ_ERROR; - *val = curlx_memdup0((const char *)(*src), slen); - *src += slen; - return *val ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} - -static CURLcode spack_encdata16(struct dynbuf *buf, const uint8_t *data, - size_t data_len) -{ - CURLcode r; - if(data_len > UINT16_MAX) - return CURLE_BAD_FUNCTION_ARGUMENT; - r = spack_enc16(buf, (uint16_t)data_len); - if(!r) { - r = curlx_dyn_addn(buf, data, data_len); - } - return r; -} - -static CURLcode spack_decdata16(uint8_t **val, size_t *val_len, - const uint8_t **src, const uint8_t *end) -{ - uint16_t data_len; - CURLcode r; - - *val = NULL; - r = spack_dec16(&data_len, src, end); - if(r) - return r; - if(end - *src < data_len) - return CURLE_READ_ERROR; - *val = curlx_memdup0((const char *)(*src), data_len); - *val_len = data_len; - *src += data_len; - return *val ? CURLE_OK : CURLE_OUT_OF_MEMORY; -} - -CURLcode Curl_ssl_session_pack(struct Curl_easy *data, - struct Curl_ssl_session *s, - struct dynbuf *buf) -{ - CURLcode r; - DEBUGASSERT(s->sdata); - DEBUGASSERT(s->sdata_len); - - if(s->valid_until < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - - r = spack_enc8(buf, CURL_SPACK_VERSION); - if(!r) - r = spack_enc8(buf, CURL_SPACK_TICKET); - if(!r) - r = spack_encdata16(buf, s->sdata, s->sdata_len); - if(!r) - r = spack_enc8(buf, CURL_SPACK_IETF_ID); - if(!r) - r = spack_enc16(buf, (uint16_t)s->ietf_tls_id); - if(!r) - r = spack_enc8(buf, CURL_SPACK_VALID_UNTIL); - if(!r) - r = spack_enc64(buf, (uint64_t)s->valid_until); - if(!r && s->alpn) { - r = spack_enc8(buf, CURL_SPACK_ALPN); - if(!r) - r = spack_encstr16(buf, s->alpn); - } - if(!r && s->earlydata_max) { - if(s->earlydata_max > UINT32_MAX) - r = CURLE_BAD_FUNCTION_ARGUMENT; - if(!r) - r = spack_enc8(buf, CURL_SPACK_EARLYDATA); - if(!r) - r = spack_enc32(buf, (uint32_t)s->earlydata_max); - } - if(!r && s->quic_tp && s->quic_tp_len) { - r = spack_enc8(buf, CURL_SPACK_QUICTP); - if(!r) - r = spack_encdata16(buf, s->quic_tp, s->quic_tp_len); - } - - if(r) - CURL_TRC_SSLS(data, "error packing data: %d", r); - return r; -} - -CURLcode Curl_ssl_session_unpack(struct Curl_easy *data, - const void *bufv, size_t buflen, - struct Curl_ssl_session **ps) -{ - struct Curl_ssl_session *s = NULL; - const unsigned char *buf = (const unsigned char *)bufv; - const unsigned char *end = buf + buflen; - uint8_t val8, *pval8; - uint16_t val16; - uint32_t val32; - uint64_t val64; - CURLcode r; - - DEBUGASSERT(buf); - DEBUGASSERT(buflen); - *ps = NULL; - - r = spack_dec8(&val8, &buf, end); - if(r) - goto out; - if(val8 != CURL_SPACK_VERSION) { - r = CURLE_READ_ERROR; - goto out; - } - - s = curlx_calloc(1, sizeof(*s)); - if(!s) { - r = CURLE_OUT_OF_MEMORY; - goto out; - } - - while(buf < end) { - r = spack_dec8(&val8, &buf, end); - if(r) - goto out; - - switch(val8) { - case CURL_SPACK_ALPN: - r = spack_decstr16(&s->alpn, &buf, end); - if(r) - goto out; - break; - case CURL_SPACK_EARLYDATA: - r = spack_dec32(&val32, &buf, end); - if(r) - goto out; - s->earlydata_max = val32; - break; - case CURL_SPACK_IETF_ID: - r = spack_dec16(&val16, &buf, end); - if(r) - goto out; - s->ietf_tls_id = val16; - break; - case CURL_SPACK_QUICTP: { - r = spack_decdata16(&pval8, &s->quic_tp_len, &buf, end); - if(r) - goto out; - s->quic_tp = pval8; - break; - } - case CURL_SPACK_TICKET: { - r = spack_decdata16(&pval8, &s->sdata_len, &buf, end); - if(r) - goto out; - s->sdata = pval8; - break; - } - case CURL_SPACK_VALID_UNTIL: - r = spack_dec64(&val64, &buf, end); - if(r) - goto out; - s->valid_until = (curl_off_t)val64; - break; - default: /* unknown tag */ - r = CURLE_READ_ERROR; - goto out; - } - } - -out: - if(r) { - CURL_TRC_SSLS(data, "error unpacking data: %d", r); - Curl_ssl_session_destroy(s); - } - else - *ps = s; - return r; -} - -#endif /* USE_SSL && USE_SSLS_EXPORT */ diff --git a/vendor/curl/lib/vtls/vtls_spack.h b/vendor/curl/lib/vtls/vtls_spack.h deleted file mode 100644 index 4479384de..000000000 --- a/vendor/curl/lib/vtls/vtls_spack.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef HEADER_CURL_VTLS_SPACK_H -#define HEADER_CURL_VTLS_SPACK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_SSL) && defined(USE_SSLS_EXPORT) - -struct dynbuf; -struct Curl_ssl_session; - -CURLcode Curl_ssl_session_pack(struct Curl_easy *data, - struct Curl_ssl_session *s, - struct dynbuf *buf); - -CURLcode Curl_ssl_session_unpack(struct Curl_easy *data, - const void *bufv, size_t buflen, - struct Curl_ssl_session **ps); - -#endif /* USE_SSL && USE_SSLS_EXPORT */ - -#endif /* HEADER_CURL_VTLS_SPACK_H */ diff --git a/vendor/curl/lib/vtls/wolfssl.c b/vendor/curl/lib/vtls/wolfssl.c deleted file mode 100644 index 15c81c287..000000000 --- a/vendor/curl/lib/vtls/wolfssl.c +++ /dev/null @@ -1,2356 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -/* - * Source file for all wolfSSL specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ -#include "curl_setup.h" - -#ifdef USE_WOLFSSL - -#include -#include - -#if LIBWOLFSSL_VERSION_HEX < 0x05000000 /* wolfSSL 5.0.0 (2021-11-01) */ -#error "wolfSSL version should be at least 5.0.0" -#endif -#if defined(OPENSSL_COEXIST) && LIBWOLFSSL_VERSION_HEX < 0x05007006 -#error "wolfSSL 5.7.6 or newer is required to coexist with OpenSSL" -#endif - -/* To determine what functions are available we rely on one or both of: - - the user's options.h generated by wolfSSL - - the symbols detected by curl's configure - Since they are markedly different from one another, and one or the other may - not be available, we do some checking below to bring things in sync. */ - -/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */ -#ifndef HAVE_ALPN -#ifdef HAVE_WOLFSSL_USEALPN -#define HAVE_ALPN -#endif -#endif - -#include "urldata.h" -#include "curl_trc.h" -#include "httpsrr.h" -#include "cf-dns.h" -#include "vtls/vtls.h" -#include "vtls/vtls_int.h" -#include "vtls/vtls_scache.h" -#include "vtls/keylog.h" -#include "connect.h" /* for the connect timeout */ -#include "progress.h" -#include "curlx/strdup.h" -#include "curlx/strcopy.h" -#include "vtls/x509asn1.h" -#ifdef USE_ECH -#include "curlx/base64.h" -#endif - -#include -#include - -#include "vtls/wolfssl.h" - -/* KEEP_PEER_CERT is a product of the presence of build time symbol - OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is - in wolfSSL's settings.h, and the latter two are build time symbols in - options.h. */ -#ifndef KEEP_PEER_CERT -#if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \ - (defined(OPENSSL_EXTRA) && !defined(NO_CERTS)) -#define KEEP_PEER_CERT -#endif -#endif - -#ifdef HAVE_WOLFSSL_BIO_NEW -#define USE_BIO_CHAIN -#ifdef HAVE_WOLFSSL_BIO_SET_SHUTDOWN -#define USE_FULL_BIO -#else /* HAVE_WOLFSSL_BIO_SET_SHUTDOWN */ -#undef USE_FULL_BIO -#endif -/* wolfSSL 5.7.4 and older do not have these symbols, but only the - * OpenSSL ones. */ -#ifndef WOLFSSL_BIO_CTRL_GET_CLOSE -#define WOLFSSL_BIO_CTRL_GET_CLOSE BIO_CTRL_GET_CLOSE -#define WOLFSSL_BIO_CTRL_SET_CLOSE BIO_CTRL_SET_CLOSE -#define WOLFSSL_BIO_CTRL_FLUSH BIO_CTRL_FLUSH -#define WOLFSSL_BIO_CTRL_DUP BIO_CTRL_DUP -#define wolfSSL_BIO_set_retry_write BIO_set_retry_write -#define wolfSSL_BIO_set_retry_read BIO_set_retry_read -#endif /* !WOLFSSL_BIO_CTRL_GET_CLOSE */ - -#else /* HAVE_WOLFSSL_BIO_NEW */ -#undef USE_BIO_CHAIN -#endif - -#ifdef OPENSSL_EXTRA -/* - * Availability note: - * The TLS 1.3 secret callback (wolfSSL_set_tls13_secret_cb) was added in - * wolfSSL 4.4.0, but requires the -DHAVE_SECRET_CALLBACK build option. If that - * option is not set, then TLS 1.3 is not logged. - * For TLS 1.2 and before, we use wolfSSL_get_keys(). - * wolfSSL_get_client_random and wolfSSL_get_keys require OPENSSL_EXTRA - * (--enable-opensslextra or --enable-all). - */ -#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) -static int wssl_tls13_secret_callback(SSL *ssl, int id, - const unsigned char *secret, - int secretSz, void *ctx) -{ - const char *label; - unsigned char client_random[SSL3_RANDOM_SIZE]; - (void)ctx; - - if(!ssl || !Curl_tls_keylog_enabled()) { - return 0; - } - - switch(id) { - case CLIENT_EARLY_TRAFFIC_SECRET: - label = "CLIENT_EARLY_TRAFFIC_SECRET"; - break; - case CLIENT_HANDSHAKE_TRAFFIC_SECRET: - label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; - break; - case SERVER_HANDSHAKE_TRAFFIC_SECRET: - label = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; - break; - case CLIENT_TRAFFIC_SECRET: - label = "CLIENT_TRAFFIC_SECRET_0"; - break; - case SERVER_TRAFFIC_SECRET: - label = "SERVER_TRAFFIC_SECRET_0"; - break; - case EARLY_EXPORTER_SECRET: - label = "EARLY_EXPORTER_SECRET"; - break; - case EXPORTER_SECRET: - label = "EXPORTER_SECRET"; - break; - default: - return 0; - } - - if(wolfSSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE) == 0) { - /* Should never happen as wolfSSL_KeepArrays() was called before. */ - return 0; - } - - Curl_tls_keylog_write(label, client_random, secret, secretSz); - return 0; -} -#endif /* HAVE_SECRET_CALLBACK && WOLFSSL_TLS13 */ - -static void wssl_log_tls12_secret(WOLFSSL *ssl) -{ - unsigned char *ms, *sr, *cr; - unsigned int msLen, srLen, crLen, i, x = 0; - - /* wolfSSL_GetVersion is available since 3.13, we use it instead of - * SSL_version since the latter relies on OPENSSL_ALL (--enable-opensslall or - * --enable-all). Failing to perform this check could result in an unusable - * key log line when TLS 1.3 is actually negotiated. */ - switch(wolfSSL_GetVersion(ssl)) { - case WOLFSSL_SSLV3: - case WOLFSSL_TLSV1: - case WOLFSSL_TLSV1_1: - case WOLFSSL_TLSV1_2: - break; - default: - /* TLS 1.3 does not use this mechanism, the "master secret" returned below - * is not directly usable. */ - return; - } - - if(wolfSSL_get_keys(ssl, &ms, &msLen, &sr, &srLen, &cr, &crLen) != - WOLFSSL_SUCCESS) { - return; - } - - /* Check for a missing master secret and skip logging. That can happen if - * curl rejects the server certificate and aborts the handshake. - */ - for(i = 0; i < msLen; i++) { - x |= ms[i]; - } - if(x == 0) { - return; - } - - Curl_tls_keylog_write("CLIENT_RANDOM", cr, ms, msLen); -} -#endif /* OPENSSL_EXTRA */ - -static int wssl_do_file_type(const char *type) -{ - if(!type || !type[0]) - return WOLFSSL_FILETYPE_PEM; - if(curl_strequal(type, "PEM")) - return WOLFSSL_FILETYPE_PEM; - if(curl_strequal(type, "DER")) - return WOLFSSL_FILETYPE_ASN1; - return -1; -} - -#ifdef WOLFSSL_HAVE_KYBER -struct group_name_map { - const word16 group; - const char *name; -}; - -static const struct group_name_map gnm[] = { - { WOLFSSL_ML_KEM_512, "ML_KEM_512" }, - { WOLFSSL_ML_KEM_768, "ML_KEM_768" }, - { WOLFSSL_ML_KEM_1024, "ML_KEM_1024" }, - { WOLFSSL_SECP256R1MLKEM512, "SecP256r1MLKEM512" }, - { WOLFSSL_SECP384R1MLKEM768, "SecP384r1MLKEM768" }, - { WOLFSSL_SECP521R1MLKEM1024, "SecP521r1MLKEM1024" }, - { WOLFSSL_SECP256R1MLKEM768, "SecP256r1MLKEM768" }, - { WOLFSSL_SECP384R1MLKEM1024, "SecP384r1MLKEM1024" }, - { WOLFSSL_X25519MLKEM768, "X25519MLKEM768" }, - { 0, NULL } -}; -#endif - -#ifdef USE_BIO_CHAIN - -static int wssl_bio_cf_create(WOLFSSL_BIO *bio) -{ -#ifdef USE_FULL_BIO - wolfSSL_BIO_set_shutdown(bio, 1); -#endif - wolfSSL_BIO_set_data(bio, NULL); - return 1; -} - -static int wssl_bio_cf_destroy(WOLFSSL_BIO *bio) -{ - if(!bio) - return 0; - return 1; -} - -static long wssl_bio_cf_ctrl(WOLFSSL_BIO *bio, int cmd, long num, void *ptr) -{ - struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio); - long ret = 1; - - (void)cf; - (void)ptr; - (void)num; - switch(cmd) { - case WOLFSSL_BIO_CTRL_GET_CLOSE: -#ifdef USE_FULL_BIO - ret = (long)wolfSSL_BIO_get_shutdown(bio); -#else - ret = 0; -#endif - break; - case WOLFSSL_BIO_CTRL_SET_CLOSE: -#ifdef USE_FULL_BIO - wolfSSL_BIO_set_shutdown(bio, (int)num); -#endif - break; - case WOLFSSL_BIO_CTRL_FLUSH: - /* we do no delayed writes, but if we ever would, this - * needs to trigger it. */ - ret = 1; - break; - case WOLFSSL_BIO_CTRL_DUP: - ret = 1; - break; -#ifdef WOLFSSL_BIO_CTRL_EOF - case WOLFSSL_BIO_CTRL_EOF: { - /* EOF has been reached on input? */ - struct ssl_connect_data *connssl = cf->ctx; - return connssl->peer_closed; - } -#endif - default: - ret = 0; - break; - } - return ret; -} - -static int wssl_bio_cf_out_write(WOLFSSL_BIO *bio, const char *buf, int blen) -{ - struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio); - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nwritten, skiplen = 0; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - if(wssl->shutting_down && wssl->io_send_blocked_len && - (wssl->io_send_blocked_len < blen)) { - /* bug in wolfSSL: - * It adds the close notify message again every time we retry - * sending during shutdown. */ - CURL_TRC_CF(data, cf, "bio_write, shutdown restrict send of %d" - " to %d bytes", blen, wssl->io_send_blocked_len); - skiplen = (ssize_t)(blen - wssl->io_send_blocked_len); - blen = wssl->io_send_blocked_len; - } - result = Curl_conn_cf_send(cf->next, data, - (const uint8_t *)buf, blen, FALSE, &nwritten); - wssl->io_result = result; - CURL_TRC_CF(data, cf, "bio_write(len=%d) -> %d, %zu", - blen, result, nwritten); -#ifdef USE_FULL_BIO - wolfSSL_BIO_clear_retry_flags(bio); -#endif - if(result == CURLE_AGAIN) { - wolfSSL_BIO_set_retry_write(bio); - if(wssl->shutting_down && !wssl->io_send_blocked_len) - wssl->io_send_blocked_len = blen; - } - else if(!result && skiplen) - nwritten += skiplen; - return result ? -1 : (int)nwritten; -} - -static int wssl_bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen) -{ - struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio); - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - size_t nread = 0; - CURLcode result = CURLE_OK; - - DEBUGASSERT(data); - if(!data || (blen < 0)) { - wssl->io_result = CURLE_FAILED_INIT; - return -1; - } - if(!buf || !blen) - return 0; - - if((connssl->connecting_state == ssl_connect_2) && - !wssl->x509_store_setup) { - /* During handshake, init the x509 store before receiving the - * server response. This allows sending of ClientHello without delay. */ - result = Curl_wssl_setup_x509_store(cf, data, wssl); - if(result) { - CURL_TRC_CF(data, cf, "Curl_wssl_setup_x509_store() -> %d", result); - wssl->io_result = result; - return -1; - } - } - - result = Curl_conn_cf_recv(cf->next, data, buf, blen, &nread); - wssl->io_result = result; - CURL_TRC_CF(data, cf, "bio_read(len=%d) -> %d, %zu", blen, result, nread); -#ifdef USE_FULL_BIO - wolfSSL_BIO_clear_retry_flags(bio); -#endif - if(result == CURLE_AGAIN) - wolfSSL_BIO_set_retry_read(bio); - else if(nread == 0) - connssl->peer_closed = TRUE; - return result ? -1 : (int)nread; -} - -static WOLFSSL_BIO_METHOD *wssl_bio_cf_method = NULL; - -static int wssl_bio_cf_init_methods(void) -{ - wssl_bio_cf_method = wolfSSL_BIO_meth_new(WOLFSSL_BIO_MEMORY, - "wolfSSL CF BIO"); - if(!wssl_bio_cf_method) - return FALSE; /* error */ - wolfSSL_BIO_meth_set_write(wssl_bio_cf_method, &wssl_bio_cf_out_write); - wolfSSL_BIO_meth_set_read(wssl_bio_cf_method, &wssl_bio_cf_in_read); - wolfSSL_BIO_meth_set_ctrl(wssl_bio_cf_method, &wssl_bio_cf_ctrl); - wolfSSL_BIO_meth_set_create(wssl_bio_cf_method, &wssl_bio_cf_create); - wolfSSL_BIO_meth_set_destroy(wssl_bio_cf_method, &wssl_bio_cf_destroy); - return TRUE; /* fine */ -} - -static void wssl_bio_cf_free_methods(void) -{ - wolfSSL_BIO_meth_free(wssl_bio_cf_method); - wssl_bio_cf_method = NULL; -} - -#else /* USE_BIO_CHAIN */ - -#define wssl_bio_cf_init_methods() TRUE -#define wssl_bio_cf_free_methods() Curl_nop_stmt - -#endif /* !USE_BIO_CHAIN */ - -#ifdef HAVE_EX_DATA -CURLcode Curl_wssl_cache_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - WOLFSSL_SESSION *session, - int ietf_tls_id, - const char *alpn, - unsigned char *quic_tp, - size_t quic_tp_len) -{ - CURLcode result = CURLE_OK; - struct Curl_ssl_session *sc_session = NULL; - unsigned char *sdata = NULL, *sdata_ptr, *qtp_clone = NULL; - unsigned int sdata_len; - unsigned int earlydata_max = 0; - - if(!session) - goto out; - - sdata_len = wolfSSL_i2d_SSL_SESSION(session, NULL); - if(sdata_len <= 0) { - CURL_TRC_CF(data, cf, "fail to assess session length: %u", sdata_len); - result = CURLE_FAILED_INIT; - goto out; - } - sdata = sdata_ptr = curlx_calloc(1, sdata_len); - if(!sdata) { - failf(data, "unable to allocate session buffer of %u bytes", sdata_len); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - /* wolfSSL right now does not change the last parameter here, but it - * might one day decide to do so for OpenSSL compatibility. */ - sdata_len = wolfSSL_i2d_SSL_SESSION(session, &sdata_ptr); - if(sdata_len <= 0) { - CURL_TRC_CF(data, cf, "fail to serialize session: %u", sdata_len); - result = CURLE_FAILED_INIT; - goto out; - } - if(quic_tp && quic_tp_len) { - qtp_clone = curlx_memdup0((const char *)quic_tp, quic_tp_len); - if(!qtp_clone) { - curlx_free(sdata); - return CURLE_OUT_OF_MEMORY; - } - } -#ifdef WOLFSSL_EARLY_DATA - earlydata_max = wolfSSL_SESSION_get_max_early_data(session); -#endif - - result = Curl_ssl_session_create2(sdata, sdata_len, - ietf_tls_id, alpn, - (curl_off_t)time(NULL) + - wolfSSL_SESSION_get_timeout(session), - earlydata_max, qtp_clone, quic_tp_len, - &sc_session); - sdata = NULL; /* took ownership of sdata */ - if(!result) { - result = Curl_ssl_scache_put(cf, data, ssl_peer_key, sc_session); - /* took ownership of `sc_session` */ - } - -out: - curlx_free(sdata); - return result; -} - -static int wssl_vtls_new_session_cb(WOLFSSL *ssl, WOLFSSL_SESSION *session) -{ - struct Curl_cfilter *cf; - - cf = (struct Curl_cfilter *)wolfSSL_get_app_data(ssl); - DEBUGASSERT(cf != NULL); - if(cf && session) { - struct ssl_connect_data *connssl = cf->ctx; - struct Curl_easy *data = CF_DATA_CURRENT(cf); - DEBUGASSERT(connssl); - DEBUGASSERT(data); - if(connssl && data) { - (void)Curl_wssl_cache_session(cf, data, connssl->peer.scache_key, - session, wolfSSL_version(ssl), - connssl->negotiated.alpn, NULL, 0); - } - } - return 0; -} -#endif - -static CURLcode wssl_on_session_reuse(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data) -{ - struct ssl_connect_data *connssl = cf->ctx; -#ifdef WOLFSSL_EARLY_DATA - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - - connssl->earlydata_max = wolfSSL_SESSION_get_max_early_data( - wolfSSL_get_session(wssl->ssl)); -#else - connssl->earlydata_max = 0; -#endif - - /* Seems to be no wolfSSL way to signal no EarlyData in session */ - return Curl_on_session_reuse(cf, data, alpns, scs, do_early_data, - connssl->earlydata_max); -} - -static CURLcode -wssl_setup_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct wssl_ctx *wss, - struct alpn_spec *alpns, - const char *ssl_peer_key, - Curl_wssl_init_session_reuse_cb *sess_reuse_cb) -{ - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - struct Curl_ssl_session *scs = NULL; - CURLcode result; - - result = Curl_ssl_scache_take(cf, data, ssl_peer_key, &scs); - if(!result && scs && scs->sdata && scs->sdata_len && - (!scs->alpn || Curl_alpn_contains_proto(alpns, scs->alpn))) { - WOLFSSL_SESSION *session; - /* wolfSSL changes the passed pointer for whatever reasons, yikes */ - const unsigned char *sdata = scs->sdata; - session = wolfSSL_d2i_SSL_SESSION(NULL, &sdata, (long)scs->sdata_len); - if(session) { - int ret = wolfSSL_set_session(wss->ssl, session); - if(ret != WOLFSSL_SUCCESS) { - Curl_ssl_session_destroy(scs); - scs = NULL; - infof(data, "cached session not accepted (%d), " - "removing from cache", ret); - } - else { - infof(data, "SSL reusing session with ALPN '%s'", - scs->alpn ? scs->alpn : "-"); - if(ssl_config->earlydata && - !cf->conn->bits.connect_only && - !strcmp("TLSv1.3", wolfSSL_get_version(wss->ssl))) { - bool do_early_data = FALSE; - if(sess_reuse_cb) { - result = sess_reuse_cb(cf, data, alpns, scs, &do_early_data); - if(result) { - wolfSSL_SESSION_free(session); - goto out; - } - } -#ifdef WOLFSSL_EARLY_DATA - if(do_early_data) { - unsigned int edmax = (scs->earlydata_max < UINT_MAX) ? - (unsigned int)scs->earlydata_max : UINT_MAX; - /* We only try the ALPN protocol the session used before, - * otherwise we might send early data for the wrong protocol */ - Curl_alpn_restrict_to(alpns, scs->alpn); - wolfSSL_set_max_early_data(wss->ssl, edmax); - } -#else - /* Should never enable when not supported */ - DEBUGASSERT(!do_early_data); -#endif - } - } - wolfSSL_SESSION_free(session); - } - else { - failf(data, "could not decode previous session"); - } - } -out: - Curl_ssl_scache_return(cf, data, ssl_peer_key, scs); - return result; -} - -static CURLcode wssl_populate_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - WOLFSSL_X509_STORE *store, - struct wssl_ctx *wssl) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; - const char * const ssl_cafile = - /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - (ca_info_blob ? NULL : conn_config->CAfile); - const char * const ssl_capath = conn_config->CApath; - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - bool imported_native_ca = FALSE; - bool imported_ca_info_blob = FALSE; - - /* We do not want to do this again, no matter the outcome */ - wssl->x509_store_setup = TRUE; - -#ifndef NO_FILESYSTEM - /* load native CA certificates */ - if(ssl_config->native_ca_store) { -#ifdef WOLFSSL_SYS_CA_CERTS - if(wolfSSL_CTX_load_system_CA_certs(wssl->ssl_ctx) != WOLFSSL_SUCCESS) { - infof(data, "error importing native CA store, continuing anyway"); - } - else { - imported_native_ca = TRUE; - infof(data, "successfully imported native CA store"); - } -#else - infof(data, "ignoring native CA option because wolfSSL was built without " - "native CA support"); -#endif - } -#endif /* !NO_FILESYSTEM */ - - /* load certificate blob */ - if(ca_info_blob) { - if(wolfSSL_CTX_load_verify_buffer(wssl->ssl_ctx, ca_info_blob->data, - (long)ca_info_blob->len, - WOLFSSL_FILETYPE_PEM) != - WOLFSSL_SUCCESS) { - failf(data, "error importing CA certificate blob"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - imported_ca_info_blob = TRUE; - infof(data, "successfully imported CA certificate blob"); - } - } - -#ifndef NO_FILESYSTEM - /* load trusted cacert from file if not blob */ - - CURL_TRC_CF(data, cf, "wssl_populate_x509_store, path=%s, blob=%d", - ssl_cafile ? ssl_cafile : "none", !!ca_info_blob); - if(!store) - return CURLE_OUT_OF_MEMORY; - - if(ssl_cafile || ssl_capath) { - int rc = - wolfSSL_CTX_load_verify_locations_ex(wssl->ssl_ctx, - ssl_cafile, - ssl_capath, - WOLFSSL_LOAD_FLAG_IGNORE_ERR); - if(WOLFSSL_SUCCESS != rc) { - if(conn_config->verifypeer && - !imported_native_ca && !imported_ca_info_blob) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate verify locations:" - " CAfile: %s CApath: %s", - ssl_cafile ? ssl_cafile : "none", - ssl_capath ? ssl_capath : "none"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - /* continue with a warning if no strict certificate - verification is required. */ - infof(data, "error setting certificate verify locations," - " continuing anyway:"); - } - } - else { - /* Everything is fine. */ - infof(data, "successfully set certificate verify locations:"); - } - infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none"); - infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none"); - } -#endif - (void)store; - return CURLE_OK; -} - -/* key to use at `multi->proto_hash` */ -#define MPROTO_WSSL_X509_KEY "tls:wssl:x509:share" - -struct wssl_x509_share { - char *CAfile; /* CAfile path used to generate X509 store */ - WOLFSSL_X509_STORE *store; /* cached X509 store or NULL if none */ - struct curltime time; /* when the cached store was created */ -}; - -static void wssl_x509_share_free(void *key, size_t key_len, void *p) -{ - struct wssl_x509_share *share = p; - DEBUGASSERT(key_len == (sizeof(MPROTO_WSSL_X509_KEY) - 1)); - DEBUGASSERT(!memcmp(MPROTO_WSSL_X509_KEY, key, key_len)); - (void)key; - (void)key_len; - if(share->store) { - wolfSSL_X509_STORE_free(share->store); - } - curlx_free(share->CAfile); - curlx_free(share); -} - -static bool wssl_cached_x509_store_expired(struct Curl_easy *data, - const struct wssl_x509_share *mb) -{ - const struct ssl_general_config *cfg = &data->set.general_ssl; - timediff_t elapsed_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &mb->time); - timediff_t timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000; - - if(timeout_ms < 0) - return FALSE; - - return elapsed_ms >= timeout_ms; -} - -static bool wssl_cached_x509_store_different(struct Curl_cfilter *cf, - const struct wssl_x509_share *mb) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - if(!mb->CAfile || !conn_config->CAfile) - return mb->CAfile != conn_config->CAfile; - - return strcmp(mb->CAfile, conn_config->CAfile); -} - -static WOLFSSL_X509_STORE *wssl_get_cached_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct Curl_multi *multi = data->multi; - struct wssl_x509_share *share; - WOLFSSL_X509_STORE *store = NULL; - - DEBUGASSERT(multi); - share = multi ? Curl_hash_pick(&multi->proto_hash, - CURL_UNCONST(MPROTO_WSSL_X509_KEY), - sizeof(MPROTO_WSSL_X509_KEY) - 1) : NULL; - if(share && share->store && - !wssl_cached_x509_store_expired(data, share) && - !wssl_cached_x509_store_different(cf, share)) { - store = share->store; - } - - return store; -} - -static void wssl_set_cached_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - WOLFSSL_X509_STORE *store) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct Curl_multi *multi = data->multi; - struct wssl_x509_share *share; - - DEBUGASSERT(multi); - if(!multi) - return; - share = Curl_hash_pick(&multi->proto_hash, - CURL_UNCONST(MPROTO_WSSL_X509_KEY), - sizeof(MPROTO_WSSL_X509_KEY) - 1); - - if(!share) { - share = curlx_calloc(1, sizeof(*share)); - if(!share) - return; - if(!Curl_hash_add2(&multi->proto_hash, - CURL_UNCONST(MPROTO_WSSL_X509_KEY), - sizeof(MPROTO_WSSL_X509_KEY) - 1, - share, wssl_x509_share_free)) { - curlx_free(share); - return; - } - } - - if(wolfSSL_X509_STORE_up_ref(store)) { - char *CAfile = NULL; - - if(conn_config->CAfile) { - CAfile = curlx_strdup(conn_config->CAfile); - if(!CAfile) { - wolfSSL_X509_STORE_free(store); - return; - } - } - - if(share->store) { - wolfSSL_X509_STORE_free(share->store); - curlx_free(share->CAfile); - } - - share->time = *Curl_pgrs_now(data); - share->store = store; - share->CAfile = CAfile; - } -} - -CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct wssl_ctx *wssl) -{ - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - CURLcode result = CURLE_OK; - WOLFSSL_X509_STORE *cached_store; - bool cache_criteria_met; - - /* Consider the X509 store cacheable if it comes exclusively from a CAfile, - or no source is provided and we are falling back to wolfSSL's built-in - default. */ - cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) && - conn_config->verifypeer && - !conn_config->CApath && - !conn_config->ca_info_blob && - !ssl_config->primary.CRLfile && - !ssl_config->native_ca_store; - - cached_store = cache_criteria_met ? wssl_get_cached_x509_store(cf, data) - : NULL; - if(cached_store && - wolfSSL_CTX_get_cert_store(wssl->ssl_ctx) == cached_store) { - /* The cached store is already in use, do nothing. */ - } - else if(cached_store && wolfSSL_X509_STORE_up_ref(cached_store)) { - wolfSSL_CTX_set_cert_store(wssl->ssl_ctx, cached_store); - } - else if(cache_criteria_met) { - /* wolfSSL's initial store in CTX is not shareable by default. - * Make a new one, suitable for adding to the cache. See #14278 */ - WOLFSSL_X509_STORE *store = wolfSSL_X509_STORE_new(); - if(!store) { - failf(data, "SSL: could not create a X509 store"); - return CURLE_OUT_OF_MEMORY; - } - wolfSSL_CTX_set_cert_store(wssl->ssl_ctx, store); - - result = wssl_populate_x509_store(cf, data, store, wssl); - if(!result) { - wssl_set_cached_x509_store(cf, data, store); - } - } - else { - /* We never share the CTX's store, use it. */ - WOLFSSL_X509_STORE *store = wolfSSL_CTX_get_cert_store(wssl->ssl_ctx); - result = wssl_populate_x509_store(cf, data, store, wssl); - } - - return result; -} - -#ifdef WOLFSSL_TLS13 -static CURLcode wssl_add_default_ciphers(bool tls13, struct dynbuf *buf) -{ - int i; - char *str; - - for(i = 0; (str = wolfSSL_get_cipher_list(i)) != NULL; i++) { - size_t n; - if((strncmp(str, "TLS13", 5) == 0) != tls13) - continue; - - /* if there already is data in the string, add colon separator */ - if(curlx_dyn_len(buf)) { - CURLcode result = curlx_dyn_addn(buf, ":", 1); - if(result) - return result; - } - - n = strlen(str); - if(curlx_dyn_addn(buf, str, n)) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} -#endif - -#ifndef OPENSSL_EXTRA -static int wssl_legacy_CTX_set_min_proto_version(WOLFSSL_CTX *ctx, int version) -{ - int res; - switch(version) { - default: - case TLS1_VERSION: - res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1); - if(res == WOLFSSL_SUCCESS) - return res; - FALLTHROUGH(); - case TLS1_1_VERSION: - res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_1); - if(res == WOLFSSL_SUCCESS) - return res; - FALLTHROUGH(); - case TLS1_2_VERSION: - res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_2); -#ifdef WOLFSSL_TLS13 - if(res == WOLFSSL_SUCCESS) - return res; - FALLTHROUGH(); - case TLS1_3_VERSION: - res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_3); -#endif - } - return res; -} - -static int wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX *ctx, int version) -{ - (void)ctx, (void)version; - return WOLFSSL_NOT_IMPLEMENTED; -} -#define wolfSSL_CTX_set_min_proto_version wssl_legacy_CTX_set_min_proto_version -#define wolfSSL_CTX_set_max_proto_version wssl_legacy_CTX_set_max_proto_version -#endif /* OPENSSL_EXTRA */ - -static CURLcode wssl_client_cert(struct Curl_easy *data, - struct ssl_config_data *ssl_config, - struct wssl_ctx *wctx) -{ - /* Load the client certificate, and private key */ -#ifndef NO_FILESYSTEM - if(ssl_config->primary.cert_blob || ssl_config->primary.clientcert) { - const char *cert_file = ssl_config->primary.clientcert; - const char *key_file = ssl_config->key; - const struct curl_blob *cert_blob = ssl_config->primary.cert_blob; - const struct curl_blob *key_blob = ssl_config->key_blob; - int file_type = wssl_do_file_type(ssl_config->cert_type); - int rc; - - switch(file_type) { - case WOLFSSL_FILETYPE_PEM: - rc = cert_blob ? - wolfSSL_CTX_use_certificate_chain_buffer(wctx->ssl_ctx, - cert_blob->data, - (long)cert_blob->len) : - wolfSSL_CTX_use_certificate_chain_file(wctx->ssl_ctx, cert_file); - break; - case WOLFSSL_FILETYPE_ASN1: - rc = cert_blob ? - wolfSSL_CTX_use_certificate_buffer(wctx->ssl_ctx, cert_blob->data, - (long)cert_blob->len, file_type) : - wolfSSL_CTX_use_certificate_file(wctx->ssl_ctx, cert_file, file_type); - break; - default: - failf(data, "unknown cert type"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(rc != 1) { - failf(data, "unable to use client certificate"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(!key_blob && !key_file) { - key_blob = cert_blob; - key_file = cert_file; - } - else - file_type = wssl_do_file_type(ssl_config->key_type); - - rc = key_blob ? - wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data, - (long)key_blob->len, file_type) : - wolfSSL_CTX_use_PrivateKey_file(wctx->ssl_ctx, key_file, file_type); - if(rc != 1) { - failf(data, "unable to set private key"); - return CURLE_SSL_CONNECT_ERROR; - } - } -#else /* NO_FILESYSTEM */ - if(ssl_config->primary.cert_blob) { - const struct curl_blob *cert_blob = ssl_config->primary.cert_blob; - const struct curl_blob *key_blob = ssl_config->key_blob; - int file_type = wssl_do_file_type(ssl_config->cert_type); - int rc; - - switch(file_type) { - case WOLFSSL_FILETYPE_PEM: - rc = wolfSSL_CTX_use_certificate_chain_buffer(wctx->ssl_ctx, - cert_blob->data, - (long)cert_blob->len); - break; - case WOLFSSL_FILETYPE_ASN1: - rc = wolfSSL_CTX_use_certificate_buffer(wctx->ssl_ctx, cert_blob->data, - (long)cert_blob->len, file_type); - break; - default: - failf(data, "unknown cert type"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(rc != 1) { - failf(data, "unable to use client certificate"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(!key_blob) - key_blob = cert_blob; - else - file_type = wssl_do_file_type(ssl_config->key_type); - - if(wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data, - (long)key_blob->len, - file_type) != 1) { - failf(data, "unable to set private key"); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* !NO_FILESYSTEM */ - return CURLE_OK; -} - -static CURLcode ssl_version(struct Curl_easy *data, - struct ssl_primary_config *conn_config, - struct wssl_ctx *wctx, - int *min_version, int *max_version) -{ - int res; - *min_version = *max_version = 0; - DEBUGASSERT(conn_config->version != CURL_SSLVERSION_DEFAULT); - - switch(conn_config->version) { - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - *min_version = TLS1_VERSION; - break; - case CURL_SSLVERSION_TLSv1_1: - *min_version = TLS1_1_VERSION; - break; - case CURL_SSLVERSION_TLSv1_2: - *min_version = TLS1_2_VERSION; - break; -#ifdef WOLFSSL_TLS13 - case CURL_SSLVERSION_TLSv1_3: - *min_version = TLS1_3_VERSION; - break; -#endif - default: - failf(data, "wolfSSL: unsupported minimum TLS version value"); - return CURLE_SSL_CONNECT_ERROR; - } - - switch(conn_config->version_max) { -#ifdef WOLFSSL_TLS13 - case CURL_SSLVERSION_MAX_TLSv1_3: - *max_version = TLS1_3_VERSION; - break; -#endif - case CURL_SSLVERSION_MAX_TLSv1_2: - *max_version = TLS1_2_VERSION; - break; - case CURL_SSLVERSION_MAX_TLSv1_1: - *max_version = TLS1_1_VERSION; - break; - case CURL_SSLVERSION_MAX_TLSv1_0: - *max_version = TLS1_VERSION; - break; - case CURL_SSLVERSION_MAX_DEFAULT: - case CURL_SSLVERSION_MAX_NONE: - break; - default: - failf(data, "wolfSSL: unsupported maximum TLS version value"); - return CURLE_SSL_CONNECT_ERROR; - } - - res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, *min_version); - if(res != WOLFSSL_SUCCESS) { - failf(data, "wolfSSL: failed set the minimum TLS version"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(*max_version) { - res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, *max_version); - if(res != WOLFSSL_SUCCESS) { - failf(data, "wolfSSL: failed set the maximum TLS version"); - return CURLE_SSL_CONNECT_ERROR; - } - } - return CURLE_OK; -} - -#define QUIC_GROUPS "P-256:P-384:P-521" -#ifdef WOLFSSL_TLS13 -#define MAX_CIPHER_LEN 4096 -#endif - -static CURLcode wssl_init_ciphers(struct Curl_easy *data, - struct wssl_ctx *wctx, - struct ssl_primary_config *conn_config, - int tls_min, int tls_max) -{ -#ifndef WOLFSSL_TLS13 - const char *ciphers = conn_config->cipher_list; - (void)tls_min; - (void)tls_max; - if(ciphers) { - if(!SSL_CTX_set_cipher_list(wctx->ssl_ctx, ciphers)) { - failf(data, "failed setting cipher list: %s", ciphers); - return CURLE_SSL_CIPHER; - } - infof(data, "Cipher selection: %s", ciphers); - } - return CURLE_OK; -#else - CURLcode result = CURLE_OK; - if(conn_config->cipher_list || conn_config->cipher_list13) { - const char *ciphers12 = conn_config->cipher_list; - const char *ciphers13 = conn_config->cipher_list13; - struct dynbuf c; - curlx_dyn_init(&c, MAX_CIPHER_LEN); - - if(!tls_max || (tls_max >= TLS1_3_VERSION)) { - if(ciphers13) - result = curlx_dyn_add(&c, ciphers13); - else - result = wssl_add_default_ciphers(TRUE, &c); - } - - if(!result && (tls_min < TLS1_3_VERSION)) { - if(ciphers12) { - if(curlx_dyn_len(&c)) - result = curlx_dyn_addn(&c, ":", 1); - if(!result) - result = curlx_dyn_add(&c, ciphers12); - } - else - result = wssl_add_default_ciphers(FALSE, &c); - } - if(!result) { - if(!wolfSSL_CTX_set_cipher_list(wctx->ssl_ctx, curlx_dyn_ptr(&c))) { - failf(data, "failed setting cipher list: %s", curlx_dyn_ptr(&c)); - result = CURLE_SSL_CIPHER; - } - else - infof(data, "Cipher selection: %s", curlx_dyn_ptr(&c)); - } - curlx_dyn_free(&c); - } - return result; -#endif -} - -static CURLcode wssl_init_curves(struct Curl_easy *data, - struct wssl_ctx *wctx, - struct ssl_primary_config *conn_config, - unsigned char transport -#ifdef WOLFSSL_HAVE_KYBER - , word16 *out_pqkem -#endif - ) -{ - char *curves = conn_config->curves; - if(!curves && (transport == TRNSPRT_QUIC)) - curves = (char *)CURL_UNCONST(QUIC_GROUPS); - - if(curves) { -#ifdef WOLFSSL_HAVE_KYBER - size_t idx; - for(idx = 0; gnm[idx].name != NULL; idx++) { - if(!strncmp(curves, gnm[idx].name, strlen(gnm[idx].name))) { - *out_pqkem = gnm[idx].group; - break; - } - } - - if(*out_pqkem == 0) -#endif - { - if(!wolfSSL_CTX_set1_curves_list(wctx->ssl_ctx, curves)) { - failf(data, "failed setting curves list: '%s'", curves); - return CURLE_SSL_CIPHER; - } - } - } - return CURLE_OK; -} - -static CURLcode wssl_init_ssl_handle(struct wssl_ctx *wctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - struct alpn_spec *alpns, - void *ssl_user_data, - unsigned char transport, -#ifdef WOLFSSL_HAVE_KYBER - word16 pqkem, -#endif - Curl_wssl_init_session_reuse_cb - *sess_reuse_cb) -{ - /* Let's make an SSL structure */ - wctx->ssl = wolfSSL_new(wctx->ssl_ctx); - if(!wctx->ssl) { - failf(data, "SSL: could not create a handle"); - return CURLE_OUT_OF_MEMORY; - } - -#ifdef HAVE_EX_DATA - wolfSSL_set_app_data(wctx->ssl, ssl_user_data); -#else - (void)ssl_user_data; -#endif -#ifdef WOLFSSL_QUIC - if(transport == TRNSPRT_QUIC) - wolfSSL_set_quic_use_legacy_codepoint(wctx->ssl, 0); -#else - (void)transport; -#endif - -#ifdef WOLFSSL_HAVE_KYBER - if(pqkem) { - if(wolfSSL_UseKeyShare(wctx->ssl, pqkem) != - WOLFSSL_SUCCESS) { - failf(data, "unable to use PQ KEM"); - } - } -#endif - - /* Check if there is a cached ID we can/should use here! */ - if(Curl_ssl_scache_use(cf, data)) { - /* Set session from cache if there is one */ - (void)wssl_setup_session(cf, data, wctx, alpns, peer->scache_key, - sess_reuse_cb); - } - -#ifdef HAVE_ALPN - if(alpns->count) { - struct alpn_proto_buf proto; - memset(&proto, 0, sizeof(proto)); - Curl_alpn_to_proto_str(&proto, alpns); - - if(wolfSSL_UseALPN(wctx->ssl, (char *)proto.data, - (unsigned int)proto.len, - WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) - != WOLFSSL_SUCCESS) { - failf(data, "SSL: failed setting ALPN protocols"); - return CURLE_SSL_CONNECT_ERROR; - } - CURL_TRC_CF(data, cf, "set ALPN: %s", proto.data); - } -#endif /* HAVE_ALPN */ - -#ifdef OPENSSL_EXTRA - if(Curl_tls_keylog_enabled()) { - /* Ensure the Client Random is preserved. */ - wolfSSL_KeepArrays(wctx->ssl); -#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) - wolfSSL_set_tls13_secret_cb(wctx->ssl, wssl_tls13_secret_callback, NULL); -#endif - } -#endif /* OPENSSL_EXTRA */ - -#ifdef HAVE_SECURE_RENEGOTIATION - if(wolfSSL_UseSecureRenegotiation(wctx->ssl) != SSL_SUCCESS) { - failf(data, "SSL: failed setting secure renegotiation"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* HAVE_SECURE_RENEGOTIATION */ - - return CURLE_OK; -} - -#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG -static CURLcode wssl_init_ech(struct wssl_ctx *wctx, - struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - int trying_ech_now = 0; - - if(data->set.str[STRING_ECH_PUBLIC]) { - infof(data, "ECH: outername not (yet) supported" - " with wolfSSL"); - return CURLE_SSL_CONNECT_ERROR; - } - if(data->set.tls_ech == CURLECH_GREASE) { - infof(data, "ECH: GREASE is done by default by" - " wolfSSL: no need to ask"); - } - if(data->set.tls_ech & CURLECH_CLA_CFG && - data->set.str[STRING_ECH_CONFIG]) { - char *b64val = data->set.str[STRING_ECH_CONFIG]; - word32 b64len = 0; - - b64len = (word32)strlen(b64val); - if(b64len && wolfSSL_SetEchConfigsBase64(wctx->ssl, b64val, - b64len) != WOLFSSL_SUCCESS) { - if(data->set.tls_ech & CURLECH_HARD) - return CURLE_SSL_CONNECT_ERROR; - } - else { - trying_ech_now = 1; - infof(data, "ECH: ECHConfig from command line"); - } - } - else { - const struct Curl_https_rrinfo *rinfo = - Curl_conn_dns_get_https(data, cf->sockindex); - - if(rinfo && rinfo->echconfiglist) { - const unsigned char *ecl = rinfo->echconfiglist; - size_t elen = rinfo->echconfiglist_len; - - infof(data, "ECH: ECHConfig from HTTPS RR"); - if(wolfSSL_SetEchConfigs(wctx->ssl, ecl, (word32)elen) != - WOLFSSL_SUCCESS) { - infof(data, "ECH: wolfSSL_SetEchConfigs failed"); - if(data->set.tls_ech & CURLECH_HARD) { - return CURLE_SSL_CONNECT_ERROR; - } - } - else { - trying_ech_now = 1; - infof(data, "ECH: imported ECHConfigList of length %zu", elen); - } - } - else { - infof(data, "ECH: requested but no ECHConfig available"); - if(data->set.tls_ech & CURLECH_HARD) { - return CURLE_SSL_CONNECT_ERROR; - } - } - } - - if(trying_ech_now && - wolfSSL_set_min_proto_version(wctx->ssl, TLS1_3_VERSION) != 1) { - infof(data, "ECH: cannot force TLSv1.3 [ERROR]"); - return CURLE_SSL_CONNECT_ERROR; - } - return CURLE_OK; -} -#endif /* HAVE_WOLFSSL_CTX_GENERATEECHCONFIG */ - -CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - Curl_wssl_ctx_setup_cb *cb_setup, - void *cb_user_data, - void *ssl_user_data, - Curl_wssl_init_session_reuse_cb *sess_reuse_cb) -{ - struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - struct ssl_primary_config *conn_config; - WOLFSSL_METHOD *req_method = NULL; - struct alpn_spec alpns; -#ifdef WOLFSSL_HAVE_KYBER - word16 pqkem = 0; -#endif - CURLcode result = CURLE_FAILED_INIT; - unsigned char transport; - int tls_min, tls_max; - - DEBUGASSERT(!wctx->ssl_ctx); - DEBUGASSERT(!wctx->ssl); - conn_config = Curl_ssl_cf_get_primary_config(cf); - if(!conn_config) { - result = CURLE_FAILED_INIT; - goto out; - } - Curl_alpn_copy(&alpns, alpns_requested); - DEBUGASSERT(cf->next); - transport = Curl_conn_cf_get_transport(cf->next, data); - - req_method = wolfTLS_client_method(); - if(!req_method) { - failf(data, "wolfSSL: could not create a client method"); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - if(wctx->ssl_ctx) - wolfSSL_CTX_free(wctx->ssl_ctx); - - wctx->ssl_ctx = wolfSSL_CTX_new(req_method); - if(!wctx->ssl_ctx) { - failf(data, "wolfSSL: could not create a context"); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = ssl_version(data, conn_config, wctx, &tls_min, &tls_max); - if(result) - goto out; - - result = wssl_init_ciphers(data, wctx, conn_config, tls_min, tls_max); - if(result) - goto out; - - result = wssl_init_curves(data, wctx, conn_config, transport -#ifdef WOLFSSL_HAVE_KYBER - , &pqkem -#endif - ); - if(result) - goto out; - - result = wssl_client_cert(data, ssl_config, wctx); - if(result) - goto out; - - /* SSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ - wolfSSL_CTX_set_verify(wctx->ssl_ctx, conn_config->verifypeer ? - WOLFSSL_VERIFY_PEER : WOLFSSL_VERIFY_NONE, NULL); - -#ifdef HAVE_SNI - if(peer->sni) { - size_t sni_len = strlen(peer->sni); - if((sni_len < USHRT_MAX)) { - if(wolfSSL_CTX_UseSNI(wctx->ssl_ctx, WOLFSSL_SNI_HOST_NAME, - peer->sni, (unsigned short)sni_len) != 1) { - failf(data, "Failed to set SNI"); - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - CURL_TRC_CF(data, cf, "set SNI '%s'", peer->sni); - } - } -#endif - -#ifdef HAVE_EX_DATA - if(Curl_ssl_scache_use(cf, data) && (transport != TRNSPRT_QUIC)) { - /* Register to get notified when a new session is received */ - wolfSSL_CTX_sess_set_new_cb(wctx->ssl_ctx, wssl_vtls_new_session_cb); - } -#endif - - if(cb_setup) { - result = cb_setup(cf, data, cb_user_data); - if(result) - goto out; - } - - /* give application a chance to interfere with SSL set up. */ - if(data->set.ssl.fsslctx) { - if(!wctx->x509_store_setup) { - result = Curl_wssl_setup_x509_store(cf, data, wctx); - if(result) - goto out; - } - result = (*data->set.ssl.fsslctx)(data, wctx->ssl_ctx, - data->set.ssl.fsslctxp); - if(result) { - failf(data, "error signaled by ssl ctx callback"); - goto out; - } - } -#ifdef NO_FILESYSTEM - else if(conn_config->verifypeer) { - failf(data, "SSL: Certificates cannot be loaded because wolfSSL was built" - " with no file system. Either disable peer verification" - " (insecure) or if you are building an application with libcurl you" - " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); - result = CURLE_SSL_CONNECT_ERROR; - goto out; - } -#endif - - result = wssl_init_ssl_handle(wctx, cf, data, peer, &alpns, ssl_user_data, - transport, -#ifdef WOLFSSL_HAVE_KYBER - pqkem, -#endif - sess_reuse_cb); - if(result) - goto out; - -#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG - if(CURLECH_ENABLED(data)) { - result = wssl_init_ech(wctx, cf, data); - if(result) - goto out; - } -#endif /* HAVE_WOLFSSL_CTX_GENERATEECHCONFIG */ - - result = CURLE_OK; - -out: - if(result && wctx->ssl) { - wolfSSL_free(wctx->ssl); - wctx->ssl = NULL; - } - if(result && wctx->ssl_ctx) { - wolfSSL_CTX_free(wctx->ssl_ctx); - wctx->ssl_ctx = NULL; - } - return result; -} - -bool Curl_wssl_need_httpsrr(struct Curl_easy *data) -{ -#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG - if(!CURLECH_ENABLED(data)) - return FALSE; - if((data->set.tls_ech & CURLECH_GREASE) || - (data->set.tls_ech & CURLECH_CLA_CFG)) - return FALSE; - return TRUE; -#else - (void)data; - return FALSE; -#endif -} - -/* - * This function loads all the client/CA certificates and CRLs. Setup the TLS - * layer and do all necessary magic. - */ -static CURLcode wssl_connect_step1(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - CURLcode result; - - DEBUGASSERT(wssl); - - if(connssl->state == ssl_connection_complete) - return CURLE_OK; - - result = Curl_wssl_ctx_init(wssl, cf, data, &connssl->peer, connssl->alpn, - NULL, NULL, cf, wssl_on_session_reuse); - if(result) - return result; - -#ifdef HAVE_ALPN - if(connssl->alpn && (connssl->state != ssl_connection_deferred)) { - struct alpn_proto_buf proto; - memset(&proto, 0, sizeof(proto)); - Curl_alpn_to_proto_str(&proto, connssl->alpn); - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); - } -#endif - - /* Enable RFC2818 checks on domain names. This cannot check - * IP addresses which we need to do extra after the handshake. */ - if(conn_config->verifyhost && connssl->peer.sni) { - if(wolfSSL_check_domain_name(wssl->ssl, connssl->peer.sni) != - WOLFSSL_SUCCESS) { - return CURLE_SSL_CONNECT_ERROR; - } - } - -#ifdef USE_BIO_CHAIN - { - WOLFSSL_BIO *bio; - - if(!wssl_bio_cf_method) - return CURLE_FAILED_INIT; - bio = wolfSSL_BIO_new(wssl_bio_cf_method); - if(!bio) - return CURLE_OUT_OF_MEMORY; - - wolfSSL_BIO_set_data(bio, cf); - wolfSSL_set_bio(wssl->ssl, bio, bio); - } -#else /* !USE_BIO_CHAIN */ - curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); - if(sockfd > INT_MAX) { - failf(data, "SSL: socket value too large"); - return CURLE_SSL_CONNECT_ERROR; - } - /* pass the raw socket into the SSL layer */ - if(!wolfSSL_set_fd(wssl->ssl, (int)sockfd)) { - failf(data, "SSL: wolfSSL_set_fd failed"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* USE_BIO_CHAIN */ - - return CURLE_OK; -} - -static char *wssl_strerror(unsigned long error, char *buf, unsigned long size) -{ - DEBUGASSERT(size > 40); - *buf = '\0'; - - wolfSSL_ERR_error_string_n(error, buf, size); - - if(!*buf) { - const char *msg = error ? "Unknown error" : "No error"; - curlx_strcopy(buf, size, msg, strlen(msg)); - } - - return buf; -} - -CURLcode Curl_wssl_verify_pinned(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct wssl_ctx *wssl) -{ - WOLFSSL_X509 *x509 = NULL; - CURLcode result = CURLE_OK; -#ifndef CURL_DISABLE_PROXY - const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf) ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; - (void)cf; -#endif - - if(pinnedpubkey) { -#ifdef KEEP_PEER_CERT - const char *x509_der; - int x509_der_len; - struct Curl_X509certificate x509_parsed; - struct Curl_asn1Element *pubkey; - - result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - x509 = wolfSSL_get_peer_certificate(wssl->ssl); - if(!x509) { - failf(data, "SSL: failed retrieving server certificate"); - goto end; - } - - x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len); - if(!x509_der) { - failf(data, "SSL: failed retrieving ASN.1 server certificate"); - goto end; - } - - memset(&x509_parsed, 0, sizeof(x509_parsed)); - if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) - goto end; - - pubkey = &x509_parsed.subjectPublicKeyInfo; - if(!pubkey->header || pubkey->end <= pubkey->header) { - failf(data, "SSL: failed retrieving public key from server certificate"); - goto end; - } - - result = Curl_pin_peer_pubkey(data, pinnedpubkey, - (const unsigned char *)pubkey->header, - (size_t)(pubkey->end - pubkey->header)); - if(result) - failf(data, "SSL: public key does not match pinned public key"); -#else - failf(data, "Library lacks pinning support built-in"); - return CURLE_NOT_BUILT_IN; -#endif - } -end: - wolfSSL_FreeX509(x509); - return result; -} - -#ifdef WOLFSSL_EARLY_DATA -static CURLcode wssl_send_earlydata(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - const unsigned char *buf; - size_t blen; - - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sending); - wssl->io_result = CURLE_OK; - while(Curl_bufq_peek(&connssl->earlydata, &buf, &blen)) { - int nwritten = 0, rc; - - wolfSSL_ERR_clear_error(); - rc = wolfSSL_write_early_data(wssl->ssl, buf, (int)blen, &nwritten); - CURL_TRC_CF(data, cf, "wolfSSL_write_early_data(len=%zu) -> %d, %d", - blen, rc, nwritten); - if(rc < 0) { - int err = wolfSSL_get_error(wssl->ssl, rc); - char error_buffer[256]; - switch(err) { - case WOLFSSL_ERROR_NONE: /* did not get anything */ - case WOLFSSL_ERROR_WANT_READ: - case WOLFSSL_ERROR_WANT_WRITE: - return CURLE_AGAIN; - } - CURL_TRC_CF(data, cf, "SSL send early data, error: '%s'(%d)", - wssl_strerror((unsigned long)err, error_buffer, - sizeof(error_buffer)), err); - return CURLE_SEND_ERROR; - } - - Curl_bufq_skip(&connssl->earlydata, (size_t)nwritten); - } - /* sent everything there was */ - connssl->earlydata_state = ssl_earlydata_sent; - if(!Curl_ssl_cf_is_proxy(cf)) - Curl_pgrsEarlyData(data, (curl_off_t)connssl->earlydata_skip); - infof(data, "SSL sending %zu bytes of early data", connssl->earlydata_skip); - return CURLE_OK; -} -#endif /* WOLFSSL_EARLY_DATA */ - -static CURLcode wssl_handshake(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - int ret = -1, detail; - CURLcode result; - - DEBUGASSERT(wssl); - connssl->io_need = CURL_SSL_IO_NEED_NONE; - -#ifdef WOLFSSL_EARLY_DATA - if(connssl->earlydata_state == ssl_earlydata_sending) { - result = wssl_send_earlydata(cf, data); - if(result) - return result; - } - DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) || - (connssl->earlydata_state == ssl_earlydata_sent)); -#else - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_none); -#endif /* WOLFSSL_EARLY_DATA */ - - wolfSSL_ERR_clear_error(); - ret = wolfSSL_connect(wssl->ssl); - - if(!wssl->x509_store_setup) { - /* After having send off the ClientHello, we prepare the x509 - * store to verify the coming certificate from the server */ - result = Curl_wssl_setup_x509_store(cf, data, wssl); - if(result) { - CURL_TRC_CF(data, cf, "Curl_wssl_setup_x509_store() -> %d", result); - return result; - } - } - -#ifdef OPENSSL_EXTRA - if(Curl_tls_keylog_enabled()) { - /* If key logging is enabled, wait for the handshake to complete and then - * proceed with logging secrets (for TLS 1.2 or older). - * - * During the handshake (ret==-1), wolfSSL_want_read() is true as it waits - * for the server response. At that point the master secret is not yet - * available, so we must not try to read it. - * To log the secret on completion with a handshake failure, detect - * completion via the observation that there is nothing to read or write. - * Note that OpenSSL SSL_want_read() is always true here. If wolfSSL ever - * changes, the worst case is that no key is logged on error. - */ - if(ret == WOLFSSL_SUCCESS || - (!wolfSSL_want_read(wssl->ssl) && - !wolfSSL_want_write(wssl->ssl))) { - wssl_log_tls12_secret(wssl->ssl); - /* Client Random and master secrets are no longer needed, erase these. - * Ignored while the handshake is still in progress. */ - wolfSSL_FreeArrays(wssl->ssl); - } - } -#endif /* OPENSSL_EXTRA */ - - detail = wolfSSL_get_error(wssl->ssl, ret); - CURL_TRC_CF(data, cf, "wolfSSL_connect() -> %d, detail=%d", ret, detail); - - /* On a successful handshake with an IP address, do an extra check - * on the peer certificate */ - if(ret == WOLFSSL_SUCCESS && - conn_config->verifyhost && - !connssl->peer.sni) { - /* we have an IP address as hostname. */ - WOLFSSL_X509 *cert = wolfSSL_get_peer_certificate(wssl->ssl); - if(!cert) { - failf(data, "unable to get peer certificate"); - return CURLE_PEER_FAILED_VERIFICATION; - } - ret = wolfSSL_X509_check_ip_asc(cert, connssl->peer.hostname, 0); - CURL_TRC_CF(data, cf, "check peer certificate for IP match on %s -> %d", - connssl->peer.hostname, ret); - if(ret != WOLFSSL_SUCCESS) - detail = DOMAIN_NAME_MISMATCH; - wolfSSL_X509_free(cert); - } - - if(ret == WOLFSSL_SUCCESS) { - return CURLE_OK; - } - else { - if(WOLFSSL_ERROR_WANT_READ == detail) { - connssl->io_need = CURL_SSL_IO_NEED_RECV; - return CURLE_AGAIN; - } - else if(WOLFSSL_ERROR_WANT_WRITE == detail) { - connssl->io_need = CURL_SSL_IO_NEED_SEND; - return CURLE_AGAIN; - } - else if(DOMAIN_NAME_MISMATCH == detail) { - /* There is no easy way to override only the CN matching. - * This enables the override of both mismatching SubjectAltNames - * as also mismatching CN fields */ - failf(data, " subject alt name(s) or common name do not match \"%s\"", - connssl->peer.dispname); - return CURLE_PEER_FAILED_VERIFICATION; - } - else if(ASN_NO_SIGNER_E == detail) { - if(conn_config->verifypeer) { - failf(data, " CA signer not available for verification"); - return CURLE_SSL_CACERT_BADFILE; - } - /* Continue with a warning if no strict certificate - verification is required. */ - infof(data, "CA signer not available for verification, " - "continuing anyway"); - return CURLE_OK; - } - else if(ASN_AFTER_DATE_E == detail) { - failf(data, "server verification failed: certificate has expired."); - return CURLE_PEER_FAILED_VERIFICATION; - } - else if(ASN_BEFORE_DATE_E == detail) { - failf(data, "server verification failed: certificate not valid yet."); - return CURLE_PEER_FAILED_VERIFICATION; - } - else if(wssl->io_result) { - switch(wssl->io_result) { - case CURLE_SEND_ERROR: - case CURLE_RECV_ERROR: - return CURLE_SSL_CONNECT_ERROR; - default: - return wssl->io_result; - } - } -#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG - else if(detail == -1) { - /* try access a retry_config ECHConfigList for tracing */ - byte echConfigs[1000]; - word32 echConfigsLen = 1000; - int rv = 0; - - /* this currently does not produce the retry_configs */ - rv = wolfSSL_GetEchConfigs(wssl->ssl, echConfigs, &echConfigsLen); - if(rv != WOLFSSL_SUCCESS) { - infof(data, "Failed to get ECHConfigs"); - } - else { - char *b64str = NULL; - size_t blen = 0; - - result = curlx_base64_encode(echConfigs, echConfigsLen, - &b64str, &blen); - if(!result && b64str) - infof(data, "ECH: (not yet) retry_configs %s", b64str); - curlx_free(b64str); - } - return CURLE_SSL_CONNECT_ERROR; - } -#endif - else { - char error_buffer[256]; - failf(data, "SSL_connect failed with error %d: %s", detail, - wssl_strerror((unsigned long)detail, error_buffer, - sizeof(error_buffer))); - return CURLE_SSL_CONNECT_ERROR; - } - } -} - -static CURLcode wssl_send(struct Curl_cfilter *cf, - struct Curl_easy *data, - const void *buf, size_t blen, - size_t *pnwritten) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - CURLcode result = CURLE_OK; - int nwritten; - - DEBUGASSERT(wssl); - *pnwritten = 0; - wolfSSL_ERR_clear_error(); - - if(blen) { - int memlen = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen; - - nwritten = wolfSSL_write(wssl->ssl, buf, memlen); - - if(nwritten > 0) - *pnwritten += (size_t)nwritten; - else { - int err = wolfSSL_get_error(wssl->ssl, nwritten); - - switch(err) { - case WOLFSSL_ERROR_WANT_READ: - case WOLFSSL_ERROR_WANT_WRITE: - /* there is data pending, re-invoke wolfSSL_write() */ - if(*pnwritten) { - result = CURLE_OK; - goto out; - } - result = CURLE_AGAIN; - goto out; - - default: - if(wssl->io_result == CURLE_AGAIN) { - if(*pnwritten) { - result = CURLE_OK; - goto out; - } - result = CURLE_AGAIN; - goto out; - } - { - char error_buffer[256]; - failf(data, "SSL write: %s, errno %d", - wssl_strerror((unsigned long)err, error_buffer, - sizeof(error_buffer)), - SOCKERRNO); - } - result = CURLE_SEND_ERROR; - goto out; - } - } - } - -out: - CURL_TRC_CF(data, cf, "wssl_send(len=%zu) -> %d, %zu", - blen, result, *pnwritten); - return result; -} - -static CURLcode wssl_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool send_shutdown, bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wctx = (struct wssl_ctx *)connssl->backend; - CURLcode result = CURLE_OK; - char buf[1024]; - int nread = -1, err; - size_t i; - VERBOSE(char error_buffer[256]); - - DEBUGASSERT(wctx); - if(!wctx->ssl || cf->shutdown) { - *done = TRUE; - goto out; - } - - wctx->shutting_down = TRUE; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - *done = FALSE; - if(!(wolfSSL_get_shutdown(wctx->ssl) & WOLFSSL_SENT_SHUTDOWN)) { - /* We have not started the shutdown from our side yet. Check - * if the server already sent us one. */ - wolfSSL_ERR_clear_error(); - nread = wolfSSL_read(wctx->ssl, buf, (int)sizeof(buf)); - err = wolfSSL_get_error(wctx->ssl, nread); - CURL_TRC_CF(data, cf, "wolfSSL_read, nread=%d, err=%d", nread, err); - if(!nread && err == WOLFSSL_ERROR_ZERO_RETURN) { - bool input_pending; - /* Yes, it did. */ - if(!send_shutdown) { - CURL_TRC_CF(data, cf, "SSL shutdown received, not sending"); - *done = TRUE; - goto out; - } - else if(!cf->next->cft->is_alive(cf->next, data, &input_pending)) { - /* Server closed the connection after its closy notify. It - * seems not interested to see our close notify, so do not - * send it. We are done. */ - CURL_TRC_CF(data, cf, "peer closed connection"); - connssl->peer_closed = TRUE; - *done = TRUE; - goto out; - } - } - } - - /* wolfSSL should now have started the shutdown from our side. Since it - * was not complete, we are lacking the close notify from the server. */ - if(send_shutdown) { - wolfSSL_ERR_clear_error(); - nread = wolfSSL_shutdown(wctx->ssl); - if(nread == 1) { - CURL_TRC_CF(data, cf, "SSL shutdown finished"); - *done = TRUE; - goto out; - } - if(WOLFSSL_ERROR_WANT_WRITE == wolfSSL_get_error(wctx->ssl, nread)) { - CURL_TRC_CF(data, cf, "SSL shutdown still wants to send"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - goto out; - } - /* Having sent the close notify, we use wolfSSL_read() to get the - * missing close notify from the server. */ - } - - for(i = 0; i < 10; ++i) { - wolfSSL_ERR_clear_error(); - nread = wolfSSL_read(wctx->ssl, buf, (int)sizeof(buf)); - if(nread <= 0) - break; - } - err = wolfSSL_get_error(wctx->ssl, nread); - switch(err) { - case WOLFSSL_ERROR_ZERO_RETURN: /* no more data */ - CURL_TRC_CF(data, cf, "SSL shutdown received"); - *done = TRUE; - break; - case WOLFSSL_ERROR_NONE: /* did not get anything */ - case WOLFSSL_ERROR_WANT_READ: - /* wolfSSL has send its notify and now wants to read the reply - * from the server. We are not really interested in that. */ - CURL_TRC_CF(data, cf, "SSL shutdown sent, want receive"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; - break; - case WOLFSSL_ERROR_WANT_WRITE: - CURL_TRC_CF(data, cf, "SSL shutdown send blocked"); - connssl->io_need = CURL_SSL_IO_NEED_SEND; - break; - default: - CURL_TRC_CF(data, cf, "SSL shutdown, error: '%s'(%d)", - wssl_strerror((unsigned long)err, error_buffer, - sizeof(error_buffer)), - err); - result = CURLE_RECV_ERROR; - break; - } - -out: - cf->shutdown = (result || *done); - return result; -} - -static void wssl_close(struct Curl_cfilter *cf, struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - - (void)data; - - DEBUGASSERT(wssl); - - if(wssl->ssl) { - wolfSSL_free(wssl->ssl); - wssl->ssl = NULL; - } - if(wssl->ssl_ctx) { - wolfSSL_CTX_free(wssl->ssl_ctx); - wssl->ssl_ctx = NULL; - } -} - -static CURLcode wssl_recv(struct Curl_cfilter *cf, - struct Curl_easy *data, - char *buf, size_t blen, - size_t *pnread) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - int buffsize = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen; - int nread; - - DEBUGASSERT(wssl); - - *pnread = 0; - wolfSSL_ERR_clear_error(); - - nread = wolfSSL_read(wssl->ssl, buf, buffsize); - - if(nread > 0) - *pnread = (size_t)nread; - else { - int err = wolfSSL_get_error(wssl->ssl, nread); - - switch(err) { - case WOLFSSL_ERROR_ZERO_RETURN: /* no more data */ - CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen); - return CURLE_OK; - case WOLFSSL_ERROR_NONE: - case WOLFSSL_ERROR_WANT_READ: - case WOLFSSL_ERROR_WANT_WRITE: - if(!wssl->io_result && !connssl->peer_closed) { - /* there is data pending, re-invoke wolfSSL_read() */ - CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> AGAIN", blen); - return CURLE_AGAIN; - } - /* fall through to default error handling below */ - FALLTHROUGH(); - default: - if(wssl->io_result == CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> AGAIN", blen); - return CURLE_AGAIN; - } - else if(!wssl->io_result && connssl->peer_closed) { - CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen); - failf(data, "Connection closed abruptly"); - } - else { - char error_buffer[256]; - failf(data, "SSL read: %s, errno %d", - wssl_strerror((unsigned long)err, error_buffer, - sizeof(error_buffer)), - SOCKERRNO); - } - return CURLE_RECV_ERROR; - } - } - - CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> 0, %zu", blen, *pnread); - return CURLE_OK; -} - -size_t Curl_wssl_version(char *buffer, size_t size) -{ - return curl_msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version()); -} - -static int wssl_init(void) -{ - int ret; - -#ifdef OPENSSL_EXTRA - Curl_tls_keylog_open(); -#endif - ret = (wolfSSL_Init() == WOLFSSL_SUCCESS); - if(ret) - ret = wssl_bio_cf_init_methods(); - return ret; -} - -static void wssl_cleanup(void) -{ - wssl_bio_cf_free_methods(); - wolfSSL_Cleanup(); -#ifdef OPENSSL_EXTRA - Curl_tls_keylog_close(); -#endif -} - -static bool wssl_data_pending(struct Curl_cfilter *cf, - const struct Curl_easy *data) -{ - struct ssl_connect_data *ctx = cf->ctx; - struct wssl_ctx *wssl; - - (void)data; - DEBUGASSERT(ctx && ctx->backend); - - wssl = (struct wssl_ctx *)ctx->backend; - if(wssl->ssl) /* wolfSSL is in use */ - return wolfSSL_pending(wssl->ssl); - else - return FALSE; -} - -void Curl_wssl_report_handshake(struct Curl_easy *data, struct wssl_ctx *wssl) -{ - (void)wssl; - infof(data, "SSL connection using %s / %s", - wolfSSL_get_version(wssl->ssl), - wolfSSL_get_cipher_name(wssl->ssl)); -} - -static CURLcode wssl_connect(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - CURLcode result = CURLE_OK; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - connssl->io_need = CURL_SSL_IO_NEED_NONE; - - if(ssl_connect_1 == connssl->connecting_state) { -#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG - /* if we do ECH and need the HTTPS-RR information for it, - * we delay the connect until it arrives or DNS resolve fails. */ - if(Curl_wssl_need_httpsrr(data) && - !Curl_conn_dns_resolved_https(data, cf->sockindex)) { - CURL_TRC_CF(data, cf, "need HTTPS-RR for ECH, delaying connect"); - return CURLE_OK; - } -#endif /* HAVE_WOLFSSL_CTX_GENERATEECHCONFIG */ - result = wssl_connect_step1(cf, data); - if(result) - return result; - connssl->connecting_state = ssl_connect_2; - } - - if(ssl_connect_2 == connssl->connecting_state) { - if(connssl->earlydata_state == ssl_earlydata_await) { - /* We defer the handshake until request data arrives. */ - DEBUGASSERT(connssl->state == ssl_connection_deferred); - goto out; - } - result = wssl_handshake(cf, data); - if(result == CURLE_AGAIN) - goto out; - wssl->hs_result = result; - connssl->connecting_state = ssl_connect_3; - } - - if(ssl_connect_3 == connssl->connecting_state) { - /* Once the handshake has errored, it stays in that state and - * errors again on every call. */ - if(wssl->hs_result) { - result = wssl->hs_result; - goto out; - } - result = Curl_wssl_verify_pinned(cf, data, wssl); - if(result) { - wssl->hs_result = result; - goto out; - } - /* handhshake was done without errors */ -#ifdef HAVE_ALPN - if(connssl->alpn) { - int rc; - char *protocol = NULL; - unsigned short protocol_len = 0; - - rc = wolfSSL_ALPN_GetProtocol(wssl->ssl, &protocol, &protocol_len); - - if(rc == WOLFSSL_SUCCESS) { - Curl_alpn_set_negotiated(cf, data, connssl, - (const unsigned char *)protocol, - protocol_len); - } - else if(rc == WOLFSSL_ALPN_NOT_FOUND) - Curl_alpn_set_negotiated(cf, data, connssl, NULL, 0); - else { - failf(data, "ALPN, failure getting protocol, error %d", rc); - wssl->hs_result = result = CURLE_SSL_CONNECT_ERROR; - goto out; - } - } -#endif /* HAVE_ALPN */ - - connssl->connecting_state = ssl_connect_done; - connssl->state = ssl_connection_complete; - Curl_wssl_report_handshake(data, wssl); - -#ifdef WOLFSSL_EARLY_DATA - if(connssl->earlydata_state > ssl_earlydata_none) { - /* We should be in this state by now */ - DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent); - connssl->earlydata_state = - (wolfSSL_get_early_data_status(wssl->ssl) == - WOLFSSL_EARLY_DATA_REJECTED) ? - ssl_earlydata_rejected : ssl_earlydata_accepted; - } -#endif /* WOLFSSL_EARLY_DATA */ - } - - if((connssl->connecting_state == ssl_connect_done) || - (connssl->state == ssl_connection_deferred)) { - *done = TRUE; - } - -out: - if(result) { - *done = FALSE; - if(result == CURLE_AGAIN) - return CURLE_OK; - } - else if((connssl->connecting_state == ssl_connect_done) || - (connssl->state == ssl_connection_deferred)) { - *done = TRUE; - } - return result; -} - -static CURLcode wssl_random(struct Curl_easy *data, - unsigned char *entropy, size_t length) -{ - WC_RNG rng; - (void)data; - if(wc_InitRng(&rng)) - return CURLE_FAILED_INIT; - if(length > UINT_MAX) - return CURLE_FAILED_INIT; - if(wc_RNG_GenerateBlock(&rng, entropy, (unsigned)length)) - return CURLE_FAILED_INIT; - if(wc_FreeRng(&rng)) - return CURLE_FAILED_INIT; - return CURLE_OK; -} - -static CURLcode wssl_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum /* output */, - size_t unused) -{ - wc_Sha256 SHA256pw; - (void)unused; - if(wc_InitSha256(&SHA256pw)) - return CURLE_FAILED_INIT; - wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen); - wc_Sha256Final(&SHA256pw, sha256sum); - return CURLE_OK; -} - -static void *wssl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info) -{ - struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend; - DEBUGASSERT(wssl); - return info == CURLINFO_TLS_SESSION ? - (void *)wssl->ssl_ctx : (void *)wssl->ssl; -} - -const struct Curl_ssl Curl_ssl_wolfssl = { - { CURLSSLBACKEND_WOLFSSL, "wolfssl" }, /* info */ - -#ifdef KEEP_PEER_CERT - SSLSUPP_PINNEDPUBKEY | -#endif -#ifdef USE_BIO_CHAIN - SSLSUPP_HTTPS_PROXY | -#endif - SSLSUPP_CA_PATH | - SSLSUPP_CAINFO_BLOB | -#ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG - SSLSUPP_ECH | -#endif - SSLSUPP_SSL_CTX | -#ifdef WOLFSSL_TLS13 - SSLSUPP_TLS13_CIPHERSUITES | -#endif - SSLSUPP_CA_CACHE | - SSLSUPP_CIPHER_LIST | - SSLSUPP_SSL_EC_CURVES, - - sizeof(struct wssl_ctx), - - wssl_init, /* init */ - wssl_cleanup, /* cleanup */ - Curl_wssl_version, /* version */ - wssl_shutdown, /* shutdown */ - wssl_data_pending, /* data_pending */ - wssl_random, /* random */ - NULL, /* cert_status_request */ - wssl_connect, /* connect */ - Curl_ssl_adjust_pollset, /* adjust_pollset */ - wssl_get_internals, /* get_internals */ - wssl_close, /* close_one */ - NULL, /* close_all */ - NULL, /* set_engine */ - NULL, /* set_engine_default */ - NULL, /* engines_list */ - wssl_sha256sum, /* sha256sum */ - wssl_recv, /* recv decrypted data */ - wssl_send, /* send data to encrypt */ - NULL, /* get_channel_binding */ -}; - -#endif diff --git a/vendor/curl/lib/vtls/wolfssl.h b/vendor/curl/lib/vtls/wolfssl.h deleted file mode 100644 index 2490bf3e9..000000000 --- a/vendor/curl/lib/vtls/wolfssl.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef HEADER_CURL_WOLFSSL_H -#define HEADER_CURL_WOLFSSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_WOLFSSL - -#include "urldata.h" - -#include - -struct alpn_spec; -struct ssl_peer; -struct Curl_ssl_session; - -struct WOLFSSL; -struct WOLFSSL_CTX; -struct WOLFSSL_SESSION; - -extern const struct Curl_ssl Curl_ssl_wolfssl; - -struct wssl_ctx { - struct WOLFSSL_CTX *ssl_ctx; - struct WOLFSSL *ssl; - CURLcode io_result; /* result of last BIO cfilter operation */ - CURLcode hs_result; /* result of handshake */ - int io_send_blocked_len; /* length of last BIO write that EAGAIN-ed */ - BIT(x509_store_setup); /* x509 store has been set up */ - BIT(shutting_down); /* TLS is being shut down */ -}; - -size_t Curl_wssl_version(char *buffer, size_t size); - -typedef CURLcode Curl_wssl_ctx_setup_cb(struct Curl_cfilter *cf, - struct Curl_easy *data, - void *user_data); - -typedef CURLcode Curl_wssl_init_session_reuse_cb(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct alpn_spec *alpns, - struct Curl_ssl_session *scs, - bool *do_early_data); - -CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, - struct Curl_cfilter *cf, - struct Curl_easy *data, - struct ssl_peer *peer, - const struct alpn_spec *alpns_requested, - Curl_wssl_ctx_setup_cb *cb_setup, - void *cb_user_data, - void *ssl_user_data, - Curl_wssl_init_session_reuse_cb *sess_reuse_cb); - -/* Is a resolved HTTPS-RR needed for initializing wolfSSL? */ -bool Curl_wssl_need_httpsrr(struct Curl_easy *data); - -CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct wssl_ctx *wssl); - -#ifdef HAVE_EX_DATA -CURLcode Curl_wssl_cache_session(struct Curl_cfilter *cf, - struct Curl_easy *data, - const char *ssl_peer_key, - struct WOLFSSL_SESSION *session, - int ietf_tls_id, - const char *alpn, - unsigned char *quic_tp, - size_t quic_tp_len); -#endif - -CURLcode Curl_wssl_verify_pinned(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct wssl_ctx *wssl); - -void Curl_wssl_report_handshake(struct Curl_easy *data, struct wssl_ctx *wssl); - -#endif /* USE_WOLFSSL */ -#endif /* HEADER_CURL_WOLFSSL_H */ diff --git a/vendor/curl/lib/vtls/x509asn1.c b/vendor/curl/lib/vtls/x509asn1.c deleted file mode 100644 index 788dfb278..000000000 --- a/vendor/curl/lib/vtls/x509asn1.c +++ /dev/null @@ -1,1271 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ - defined(USE_MBEDTLS) || defined(USE_RUSTLS) - -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) || \ - defined(USE_WOLFSSL) || defined(USE_RUSTLS) -#define WANT_PARSEX509 /* uses Curl_parseX509() */ -#endif - -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) || \ - defined(USE_RUSTLS) -#define WANT_EXTRACT_CERTINFO /* uses Curl_extract_certinfo() */ -#endif - -#include "urldata.h" -#include "vtls/vtls.h" -#include "curl_trc.h" -#include "curlx/base64.h" -#include "vtls/x509asn1.h" -#include "curlx/dynbuf.h" - -/* - * Constants. - */ - -/* Largest supported ASN.1 structure. */ -#define CURL_ASN1_MAX ((size_t)0x40000) /* 256K */ - -#ifdef WANT_EXTRACT_CERTINFO - -/* ASN.1 OID table entry. */ -struct Curl_OID { - const char *numoid; /* Dotted-numeric OID. */ - const char *textoid; /* OID name. */ -}; - -/* ASN.1 OIDs. */ -static const struct Curl_OID OIDtable[] = { - { "1.2.840.10040.4.1", "dsa" }, - { "1.2.840.10040.4.3", "dsa-with-sha1" }, - { "1.2.840.10045.2.1", "ecPublicKey" }, - { "1.2.840.10045.3.0.1", "c2pnb163v1" }, - { "1.2.840.10045.4.1", "ecdsa-with-SHA1" }, - { "1.2.840.10045.4.3.1", "ecdsa-with-SHA224" }, - { "1.2.840.10045.4.3.2", "ecdsa-with-SHA256" }, - { "1.2.840.10045.4.3.3", "ecdsa-with-SHA384" }, - { "1.2.840.10045.4.3.4", "ecdsa-with-SHA512" }, - { "1.2.840.10046.2.1", "dhpublicnumber" }, - { "1.2.840.113549.1.1.1", "rsaEncryption" }, - { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" }, - { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" }, - { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" }, - { "1.2.840.113549.1.1.10", "RSASSA-PSS" }, - { "1.2.840.113549.1.1.14", "sha224WithRSAEncryption" }, - { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" }, - { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" }, - { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" }, - { "1.2.840.113549.2.2", "md2" }, - { "1.2.840.113549.2.5", "md5" }, - { "1.3.14.3.2.26", "sha1" }, - { "2.5.4.3", "CN" }, - { "2.5.4.4", "SN" }, - { "2.5.4.5", "serialNumber" }, - { "2.5.4.6", "C" }, - { "2.5.4.7", "L" }, - { "2.5.4.8", "ST" }, - { "2.5.4.9", "streetAddress" }, - { "2.5.4.10", "O" }, - { "2.5.4.11", "OU" }, - { "2.5.4.12", "title" }, - { "2.5.4.13", "description" }, - { "2.5.4.17", "postalCode" }, - { "2.5.4.41", "name" }, - { "2.5.4.42", "givenName" }, - { "2.5.4.43", "initials" }, - { "2.5.4.44", "generationQualifier" }, - { "2.5.4.45", "X500UniqueIdentifier" }, - { "2.5.4.46", "dnQualifier" }, - { "2.5.4.65", "pseudonym" }, - { "1.2.840.113549.1.9.1", "emailAddress" }, - { "2.5.4.72", "role" }, - { "2.5.29.17", "subjectAltName" }, - { "2.5.29.18", "issuerAltName" }, - { "2.5.29.19", "basicConstraints" }, - { "2.16.840.1.101.3.4.2.4", "sha224" }, - { "2.16.840.1.101.3.4.2.1", "sha256" }, - { "2.16.840.1.101.3.4.2.2", "sha384" }, - { "2.16.840.1.101.3.4.2.3", "sha512" }, - { "1.2.840.113549.1.9.2", "unstructuredName" }, - { NULL, NULL } -}; - -#endif /* WANT_EXTRACT_CERTINFO */ - -/* - * Lightweight ASN.1 parser. - * In particular, it does not check for syntactic/lexical errors. - * It is intended to support certificate information gathering for SSL backends - * that offer a mean to get certificates as a whole, but do not supply - * entry points to get particular certificate sub-fields. - * Please note there is no pretension here to rewrite a full SSL library. - */ - -#define CURL_ASN1_MAX_RECURSIONS 16 - -static const char *getASN1Element_(struct Curl_asn1Element *elem, - const char *beg, const char *end, - size_t lvl) -{ - unsigned char b; - size_t len; - struct Curl_asn1Element lelem; - - /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg' - ending at `end'. - Returns a pointer in source string after the parsed element, or NULL - if an error occurs. */ - if(!beg || !end || beg >= end || !*beg || - ((size_t)(end - beg) > CURL_ASN1_MAX) || - lvl >= CURL_ASN1_MAX_RECURSIONS) - return NULL; - - /* Process header byte. */ - elem->header = beg; - b = (unsigned char)*beg++; - elem->constructed = (b & 0x20) != 0; - elem->eclass = (b >> 6) & 3; - b &= 0x1F; - if(b == 0x1F) - return NULL; /* Long tag values not supported here. */ - elem->tag = b; - - /* Process length. */ - if(beg >= end) - return NULL; - b = (unsigned char)*beg++; - if(!(b & 0x80)) - len = b; - else { - b &= 0x7F; - if(!b) { - /* Unspecified length. Since we have all the data, we can determine the - effective length by skipping element until an end element is found. */ - if(!elem->constructed) - return NULL; - elem->beg = beg; - while(beg < end && *beg) { - beg = getASN1Element_(&lelem, beg, end, lvl + 1); - if(!beg) - return NULL; - } - if(beg >= end) - return NULL; - elem->end = beg; - return beg + 1; - } - else if((unsigned)b > (size_t)(end - beg)) - return NULL; /* Does not fit in source. */ - else { - /* Get long length. */ - len = 0; - do { - if(len & 0xFF000000L) - return NULL; /* Lengths > 32 bits are not supported. */ - len = (len << 8) | (unsigned char) *beg++; - } while(--b); - } - } - if(len > (size_t)(end - beg)) - return NULL; /* Element data does not fit in source. */ - elem->beg = beg; - elem->end = beg + len; - return elem->end; -} - -/* - * @unittest 1657 - */ -UNITTEST const char *getASN1Element(struct Curl_asn1Element *elem, - const char *beg, const char *end); -UNITTEST const char *getASN1Element(struct Curl_asn1Element *elem, - const char *beg, const char *end) -{ - return getASN1Element_(elem, beg, end, 0); -} - -#ifdef WANT_EXTRACT_CERTINFO - -/* - * Search the null-terminated OID or OID identifier in local table. - * Return the table entry pointer or NULL if not found. - */ -static const struct Curl_OID *searchOID(const char *oid) -{ - const struct Curl_OID *op; - for(op = OIDtable; op->numoid; op++) - if(!strcmp(op->numoid, oid) || curl_strequal(op->textoid, oid)) - return op; - - return NULL; -} - -/* - * Convert an ASN.1 Boolean value into its string representation. - * - * Return error code. - */ - -static CURLcode bool2str(struct dynbuf *store, - const char *beg, const char *end) -{ - uint8_t val; - if(end - beg != 1) - return CURLE_BAD_FUNCTION_ARGUMENT; - val = (uint8_t)*beg; - if((val != 0xff) && (val != 0x00)) - return CURLE_BAD_FUNCTION_ARGUMENT; - return curlx_dyn_add(store, val ? "TRUE" : "FALSE"); -} - -/* - * Convert an ASN.1 octet string to a printable string. - * - * Return error code. - */ -static CURLcode octet2str(struct dynbuf *store, - const char *beg, const char *end) -{ - CURLcode result = CURLE_OK; - - while(!result && beg < end) - result = curlx_dyn_addf(store, "%02x:", (unsigned char)*beg++); - - return result; -} - -static CURLcode bit2str(struct dynbuf *store, const char *beg, const char *end) -{ - /* Convert an ASN.1 bit string to a printable string. */ - - if(beg < end) { - uint8_t unused_bits = (uint8_t)*beg++; - if(unused_bits > 7) - return CURLE_BAD_FUNCTION_ARGUMENT; - } - else - return CURLE_BAD_FUNCTION_ARGUMENT; - return octet2str(store, beg, end); -} - -/* - * Convert an ASN.1 integer value into its string representation. - * - * Returns error. - */ -static CURLcode int2str(struct dynbuf *store, const char *beg, const char *end) -{ - uint32_t uval = 0; - int32_t sval = 0; - size_t n = end - beg; - size_t i; - const unsigned char *p = (const unsigned char *)beg; - - if(!n) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(n > 4) - return octet2str(store, beg, end); - - if(p[0] & 0x80) - uval = ~0U; - - for(i = 0; i < n; i++) - uval = (uval << 8) | p[i]; - - sval = (int32_t)uval; - - /* small values are easier to read as decimals */ - if(sval > -10000 && sval < 10000) - return curlx_dyn_addf(store, "%d", sval); - - /* represent larger values as hex */ - return curlx_dyn_addf(store, "0x%x", uval); -} - -/* - * Convert from an ASN.1 typed string to UTF8. - * - * The result is stored in a dynbuf that is inited by the user of this - * function. - * - * Returns error. - */ -static CURLcode utf8asn1str(struct dynbuf *to, int type, const char *from, - const char *end) -{ - size_t inlength = end - from; - int size = 1; - CURLcode result = CURLE_OK; - - switch(type) { - case CURL_ASN1_BMP_STRING: - size = 2; - break; - case CURL_ASN1_UNIVERSAL_STRING: - size = 4; - break; - case CURL_ASN1_NUMERIC_STRING: - case CURL_ASN1_PRINTABLE_STRING: - case CURL_ASN1_TELETEX_STRING: - case CURL_ASN1_IA5_STRING: - case CURL_ASN1_VISIBLE_STRING: - case CURL_ASN1_UTF8_STRING: - break; - default: - return CURLE_BAD_FUNCTION_ARGUMENT; /* Conversion not supported. */ - } - - if(inlength % size) - /* Length inconsistent with character size. */ - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(type == CURL_ASN1_UTF8_STRING) { - /* copy. */ - if(inlength) - result = curlx_dyn_addn(to, from, inlength); - } - else { - while(!result && (from < end)) { - char buf[4]; /* decode buffer */ - size_t charsize = 1; - unsigned int wc = 0; - - switch(size) { - case 4: - wc = (wc << 8) | *(const unsigned char *)from++; - wc = (wc << 8) | *(const unsigned char *)from++; - FALLTHROUGH(); - case 2: - wc = (wc << 8) | *(const unsigned char *)from++; - FALLTHROUGH(); - default: /* case 1: */ - wc = (wc << 8) | *(const unsigned char *)from++; - } - if(wc >= 0x00000080) { - if(wc >= 0x00000800) { - if(wc >= 0x00010000) { - if(wc >= 0x00200000) { - /* Invalid char. size for target encoding. */ - return CURLE_WEIRD_SERVER_REPLY; - } - buf[3] = (char)(0x80 | (wc & 0x3F)); - wc = (wc >> 6) | 0x00010000; - charsize++; - } - buf[2] = (char)(0x80 | (wc & 0x3F)); - wc = (wc >> 6) | 0x00000800; - charsize++; - } - buf[1] = (char)(0x80 | (wc & 0x3F)); - wc = (wc >> 6) | 0x000000C0; - charsize++; - } - buf[0] = (char)wc; - result = curlx_dyn_addn(to, buf, charsize); - } - } - return result; -} - -/* - * Convert an ASN.1 OID into its dotted string representation. Each field is - * limited to unsigned 32-bit values. - * - * A minor limitation is in the second number, which can be no larger than 32 - * bits - 80 == 4294967215. - * - * Return error code. - * - * @unittest 1666 - */ -UNITTEST CURLcode encodeOID(struct dynbuf *store, - const char *beg, const char *end); -UNITTEST CURLcode encodeOID(struct dynbuf *store, - const char *beg, const char *end) -{ - uint32_t x; - uint32_t y; - CURLcode result = CURLE_OK; - - if(end <= beg) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* Process the first two numbers. The initial digit cannot be larger than - 2 */ - y = *(const unsigned char *)beg++; - if(y <= 80) - x = y / 40; - else - x = 2; - result = curlx_dyn_addf(store, "%u", x); - if(result) - return result; - - if(y & 0x80) { - uint32_t t = (y & 0x7f); /* the second number */ - if(!t) - /* reject leading 0x80 padding */ - return CURLE_BAD_FUNCTION_ARGUMENT; - do { - if((t & 0xFE000000) || (beg >= end)) - return CURLE_BAD_FUNCTION_ARGUMENT; - y = *(const unsigned char *)beg++; - t = (t << 7) | (y & 0x7F); - } while(y & 0x80); - y = t; - } - - result = curlx_dyn_addf(store, ".%u", y - (x * 40)); - if(result) - return result; - - /* Process the trailing numbers. */ - while((beg < end) && !result) { - x = 0; - y = 0; - do { - /* 0x80 as the first value is invalid since it only adds padding */ - if((y & 0x80) && !x) - return CURLE_BAD_FUNCTION_ARGUMENT; - else if((x & 0xFE000000) || (beg == end)) - return CURLE_BAD_FUNCTION_ARGUMENT; - y = *(const unsigned char *)beg++; - x = (x << 7) | (y & 0x7F); - } while(y & 0x80); - result = curlx_dyn_addf(store, ".%u", x); - } - return result; -} - -/* - * Convert an ASN.1 OID into its dotted or symbolic string representation. - * - * Return error code. - */ - -static CURLcode OID2str(struct dynbuf *store, - const char *beg, const char *end) -{ - CURLcode result = CURLE_OK; - if(beg < end) { - struct dynbuf buf; - curlx_dyn_init(&buf, CURL_X509_STR_MAX); - result = encodeOID(&buf, beg, end); - - if(!result) { - const struct Curl_OID *op = searchOID(curlx_dyn_ptr(&buf)); - if(op) - result = curlx_dyn_add(store, op->textoid); - else - result = curlx_dyn_add(store, curlx_dyn_ptr(&buf)); - } - curlx_dyn_free(&buf); - } - return result; -} - -/* - * @unittest 1656 - */ -UNITTEST CURLcode GTime2str(struct dynbuf *store, - const char *beg, const char *end); -UNITTEST CURLcode GTime2str(struct dynbuf *store, - const char *beg, const char *end) -{ - const char *tzp; - const char *fracp; - char sec1, sec2; - size_t fracl; - size_t tzl; - const char *sep = ""; - - /* Convert an ASN.1 Generalized time to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - - for(fracp = beg; fracp < end && ISDIGIT(*fracp); fracp++) - ; - - /* Get seconds digits. */ - sec1 = '0'; - switch(fracp - beg - 12) { - case 0: - sec2 = '0'; - break; - case 2: - sec1 = fracp[-2]; - FALLTHROUGH(); - case 1: - sec2 = fracp[-1]; - break; - default: - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - /* timezone follows optional fractional seconds. */ - tzp = fracp; - fracl = 0; /* no fractional seconds detected so far */ - if(fracp < end && (*fracp == '.' || *fracp == ',')) { - /* Have fractional seconds, e.g. "[.,]\d+". How many? */ - fracp++; /* should be a digit char or BAD ARGUMENT */ - tzp = fracp; - while(tzp < end && ISDIGIT(*tzp)) - tzp++; - if(tzp == fracp) /* never looped, no digit after [.,] */ - return CURLE_BAD_FUNCTION_ARGUMENT; - fracl = tzp - fracp; /* number of fractional sec digits */ - DEBUGASSERT(fracl > 0); - /* Strip trailing zeroes in fractional seconds. - * May reduce fracl to 0 if only '0's are present. */ - while(fracl && fracp[fracl - 1] == '0') - fracl--; - } - - /* Process timezone. */ - if(tzp >= end) { - tzp = ""; - tzl = 0; - } - else if(*tzp == 'Z') { - sep = " "; - tzp = "GMT"; - tzl = 3; - } - else if((*tzp == '+') || (*tzp == '-')) { - sep = " UTC"; - tzl = end - tzp; - } - else { - sep = " "; - tzl = end - tzp; - } - - return curlx_dyn_addf(store, - "%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s", - beg, beg + 4, beg + 6, - beg + 8, beg + 10, sec1, sec2, - fracl ? "." : "", (int)fracl, fracp, - sep, (int)tzl, tzp); -} - -/* - * Convert an ASN.1 UTC time to a printable string. - * - * Return error code. - */ -static CURLcode UTime2str(struct dynbuf *store, - const char *beg, const char *end) -{ - const char *tzp; - size_t tzl; - const char *sec; - - for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++) - ; - /* Get the seconds. */ - sec = beg + 10; - switch(tzp - sec) { - case 0: - sec = "00"; - FALLTHROUGH(); - case 2: - break; - default: - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - /* Process timezone. */ - if(tzp >= end) - return CURLE_BAD_FUNCTION_ARGUMENT; - if(*tzp == 'Z') { - tzp = "GMT"; - end = tzp + 3; - } - - tzl = end - tzp; - return curlx_dyn_addf(store, "%d%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s", - 20 - (*beg >= '5'), beg, beg + 2, beg + 4, - beg + 6, beg + 8, sec, - (int)tzl, tzp); -} - -/* - * Convert an ASN.1 element to a printable string. - * - * Return error - * - * @unittest 1667 - */ -UNITTEST CURLcode ASN1tostr(struct dynbuf *store, - struct Curl_asn1Element *elem); -UNITTEST CURLcode ASN1tostr(struct dynbuf *store, - struct Curl_asn1Element *elem) -{ - CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; - int type = elem->tag; - if(elem->constructed) - return result; /* No conversion of structured elements. */ - - switch(type) { - case CURL_ASN1_BOOLEAN: - result = bool2str(store, elem->beg, elem->end); - break; - case CURL_ASN1_INTEGER: - case CURL_ASN1_ENUMERATED: - result = int2str(store, elem->beg, elem->end); - break; - case CURL_ASN1_BIT_STRING: - result = bit2str(store, elem->beg, elem->end); - break; - case CURL_ASN1_OCTET_STRING: - result = octet2str(store, elem->beg, elem->end); - break; - case CURL_ASN1_NULL: - result = curlx_dyn_addn(store, "", 1); - break; - case CURL_ASN1_OBJECT_IDENTIFIER: - result = OID2str(store, elem->beg, elem->end); - break; - case CURL_ASN1_UTC_TIME: - result = UTime2str(store, elem->beg, elem->end); - break; - case CURL_ASN1_GENERALIZED_TIME: - result = GTime2str(store, elem->beg, elem->end); - break; - case CURL_ASN1_UTF8_STRING: - case CURL_ASN1_NUMERIC_STRING: - case CURL_ASN1_PRINTABLE_STRING: - case CURL_ASN1_TELETEX_STRING: - case CURL_ASN1_IA5_STRING: - case CURL_ASN1_VISIBLE_STRING: - case CURL_ASN1_UNIVERSAL_STRING: - case CURL_ASN1_BMP_STRING: - result = utf8asn1str(store, type, elem->beg, elem->end); - break; - } - - return result; -} - -/* - * ASCII encode distinguished name at `dn' into the store dynbuf. - * - * Returns error. - */ -static CURLcode encodeDN(struct dynbuf *store, struct Curl_asn1Element *dn) -{ - struct Curl_asn1Element rdn; - struct Curl_asn1Element atv; - struct Curl_asn1Element oid; - struct Curl_asn1Element value; - const char *p1; - const char *p2; - const char *p3; - const char *str; - CURLcode result = CURLE_OK; - bool added = FALSE; - struct dynbuf temp; - curlx_dyn_init(&temp, CURL_X509_STR_MAX); - - for(p1 = dn->beg; p1 < dn->end;) { - p1 = getASN1Element(&rdn, p1, dn->end); - if(!p1) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto error; - } - for(p2 = rdn.beg; p2 < rdn.end;) { - p2 = getASN1Element(&atv, p2, rdn.end); - if(!p2) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto error; - } - p3 = getASN1Element(&oid, atv.beg, atv.end); - if(!p3) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto error; - } - if(!getASN1Element(&value, p3, atv.end)) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto error; - } - curlx_dyn_reset(&temp); - result = ASN1tostr(&temp, &oid); - if(result) - goto error; - - str = curlx_dyn_ptr(&temp); - - if(!str) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto error; - } - - /* Encode delimiter. - If attribute has a short uppercase name, delimiter is ", ". */ - for(p3 = str; ISUPPER(*p3); p3++) - ; - if(added) { - if(p3 - str > 2) - result = curlx_dyn_addn(store, "/", 1); - else - result = curlx_dyn_addn(store, ", ", 2); - if(result) - goto error; - } - - /* Encode attribute name. */ - result = curlx_dyn_add(store, str); - if(result) - goto error; - - /* Generate equal sign. */ - result = curlx_dyn_addn(store, "=", 1); - if(result) - goto error; - - /* Generate value. */ - result = ASN1tostr(store, &value); - if(result) - goto error; - curlx_dyn_reset(&temp); - added = TRUE; /* use separator for next */ - } - } -error: - curlx_dyn_free(&temp); - - return result; -} - -#endif /* WANT_EXTRACT_CERTINFO */ - -#ifdef WANT_PARSEX509 -/* - * ASN.1 parse an X509 certificate into structure subfields. - * Syntax is assumed to have already been checked by the SSL backend. - * See RFC 5280. - */ -int Curl_parseX509(struct Curl_X509certificate *cert, - const char *beg, const char *end) -{ - struct Curl_asn1Element elem; - struct Curl_asn1Element tbsCertificate; - const char *ccp; - static const char defaultVersion = 0; /* v1. */ - - cert->certificate.header = NULL; - cert->certificate.beg = beg; - cert->certificate.end = end; - - /* Get the sequence content. */ - if(!getASN1Element(&elem, beg, end)) - return -1; /* Invalid bounds/size. */ - beg = elem.beg; - end = elem.end; - - /* Get tbsCertificate. */ - beg = getASN1Element(&tbsCertificate, beg, end); - if(!beg) - return -1; - /* Skip the signatureAlgorithm. */ - beg = getASN1Element(&cert->signatureAlgorithm, beg, end); - if(!beg) - return -1; - /* Get the signatureValue. */ - if(!getASN1Element(&cert->signature, beg, end)) - return -1; - - /* Parse TBSCertificate. */ - beg = tbsCertificate.beg; - end = tbsCertificate.end; - /* Get optional version, get serialNumber. */ - cert->version.header = NULL; - cert->version.beg = &defaultVersion; - cert->version.end = &defaultVersion + sizeof(defaultVersion); - beg = getASN1Element(&elem, beg, end); - if(!beg) - return -1; - if(elem.tag == 0) { - if(!getASN1Element(&cert->version, elem.beg, elem.end)) - return -1; - beg = getASN1Element(&elem, beg, end); - if(!beg) - return -1; - } - cert->serialNumber = elem; - /* Get signature algorithm. */ - beg = getASN1Element(&cert->signatureAlgorithm, beg, end); - /* Get issuer. */ - beg = getASN1Element(&cert->issuer, beg, end); - if(!beg) - return -1; - /* Get notBefore and notAfter. */ - beg = getASN1Element(&elem, beg, end); - if(!beg) - return -1; - ccp = getASN1Element(&cert->notBefore, elem.beg, elem.end); - if(!ccp) - return -1; - if(!getASN1Element(&cert->notAfter, ccp, elem.end)) - return -1; - /* Get subject. */ - beg = getASN1Element(&cert->subject, beg, end); - if(!beg) - return -1; - /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */ - beg = getASN1Element(&cert->subjectPublicKeyInfo, beg, end); - if(!beg) - return -1; - ccp = getASN1Element(&cert->subjectPublicKeyAlgorithm, - cert->subjectPublicKeyInfo.beg, - cert->subjectPublicKeyInfo.end); - if(!ccp) - return -1; - if(!getASN1Element(&cert->subjectPublicKey, ccp, - cert->subjectPublicKeyInfo.end)) - return -1; - /* Get optional issuerUniqueID, subjectUniqueID and extensions. */ - cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0; - cert->extensions.tag = elem.tag = 0; - cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL; - cert->issuerUniqueID.beg = cert->issuerUniqueID.end = ""; - cert->subjectUniqueID.beg = cert->subjectUniqueID.end = ""; - cert->extensions.header = NULL; - cert->extensions.beg = cert->extensions.end = ""; - if(beg < end) { - beg = getASN1Element(&elem, beg, end); - if(!beg) - return -1; - } - if(elem.tag == 1) { - cert->issuerUniqueID = elem; - if(beg < end) { - beg = getASN1Element(&elem, beg, end); - if(!beg) - return -1; - } - } - if(elem.tag == 2) { - cert->subjectUniqueID = elem; - if(beg < end) { - beg = getASN1Element(&elem, beg, end); - if(!beg) - return -1; - } - } - if(elem.tag == 3) - if(!getASN1Element(&cert->extensions, elem.beg, elem.end)) - return -1; - return 0; -} - -#endif /* WANT_PARSEX509 */ - -#ifdef WANT_EXTRACT_CERTINFO - -static CURLcode dumpAlgo(struct dynbuf *store, - struct Curl_asn1Element *param, - const char *beg, const char *end) -{ - struct Curl_asn1Element oid; - - /* Get algorithm parameters and return algorithm name. */ - - beg = getASN1Element(&oid, beg, end); - if(!beg) - return CURLE_BAD_FUNCTION_ARGUMENT; - param->header = NULL; - param->tag = 0; - param->beg = param->end = end; - if(beg < end) { - const char *p = getASN1Element(param, beg, end); - if(!p) - return CURLE_BAD_FUNCTION_ARGUMENT; - } - return OID2str(store, oid.beg, oid.end); -} - -/* - * This is a convenience function for push_certinfo_len that takes a zero - * terminated value. - */ -static CURLcode ssl_push_certinfo(struct Curl_easy *data, - int certnum, - const char *label, - const char *value) -{ - size_t valuelen = strlen(value); - - return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen); -} - -/* - * This is a convenience function for push_certinfo_len that takes a - * dynbuf value. - * - * It also does the verbose output if !certnum. - */ -static CURLcode ssl_push_certinfo_dyn(struct Curl_easy *data, - int certnum, - const char *label, - struct dynbuf *ptr) -{ - size_t valuelen = curlx_dyn_len(ptr); - const char *value = curlx_dyn_ptr(ptr); - - CURLcode result = Curl_ssl_push_certinfo_len(data, certnum, label, - value, valuelen); - - if(!certnum && !result) - infof(data, " %s: %s", label, value); - - return result; -} - -static CURLcode do_pubkey_field(struct Curl_easy *data, int certnum, - const char *label, - struct Curl_asn1Element *elem) -{ - CURLcode result; - struct dynbuf out; - - curlx_dyn_init(&out, CURL_X509_STR_MAX); - - /* Generate a certificate information record for the public key. */ - - result = ASN1tostr(&out, elem); - if(!result) { - if(data->set.ssl.certinfo) - result = ssl_push_certinfo_dyn(data, certnum, label, &out); - curlx_dyn_free(&out); - } - return result; -} - -/* return 0 on success, 1 on error */ -static int do_pubkey(struct Curl_easy *data, int certnum, const char *algo, - struct Curl_asn1Element *param, - struct Curl_asn1Element *pubkey) -{ - struct Curl_asn1Element elem; - struct Curl_asn1Element pk; - const char *p; - - /* Generate all information records for the public key. */ - - if(curl_strequal(algo, "ecPublicKey")) { - /* - * ECC public key is all the data, a value of type BIT STRING mapped to - * OCTET STRING and should not be parsed as an ASN.1 value. - */ - const size_t dlen = pubkey->end - pubkey->beg; - size_t len; - if(dlen < 2) - /* too small */ - return 1; - len = (dlen - 2) * 4; - if(!certnum) - infof(data, " ECC Public Key (%zu bits)", len); - if(data->set.ssl.certinfo) { - char q[(sizeof(len) * 8 / 3) + 1]; - (void)curl_msnprintf(q, sizeof(q), "%zu", len); - if(ssl_push_certinfo(data, certnum, "ECC Public Key", q)) - return 1; - } - return do_pubkey_field(data, certnum, "ecPublicKey", pubkey) == CURLE_OK - ? 0 : 1; - } - - /* Get the public key (single element). */ - if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end)) - return 1; - - if(curl_strequal(algo, "rsaEncryption")) { - const char *q; - size_t len; - - p = getASN1Element(&elem, pk.beg, pk.end); - if(!p) - return 1; - - /* Compute key length. */ - for(q = elem.beg; !*q && q < elem.end; q++) - ; - len = ((elem.end - q) * 8); - if(len) { - unsigned int i; - for(i = *(const unsigned char *)q; !(i & 0x80); i <<= 1) - len--; - } - if(len > 32) - elem.beg = q; /* Strip leading zero bytes. */ - if(!certnum) - infof(data, " RSA Public Key (%zu bits)", len); - if(data->set.ssl.certinfo) { - char r[(sizeof(len) * 8 / 3) + 1]; - curl_msnprintf(r, sizeof(r), "%zu", len); - if(ssl_push_certinfo(data, certnum, "RSA Public Key", r)) - return 1; - } - /* Generate coefficients. */ - if(do_pubkey_field(data, certnum, "rsa(n)", &elem)) - return 1; - if(!getASN1Element(&elem, p, pk.end)) - return 1; - if(do_pubkey_field(data, certnum, "rsa(e)", &elem)) - return 1; - } - else if(curl_strequal(algo, "dsa")) { - p = getASN1Element(&elem, param->beg, param->end); - if(p) { - if(do_pubkey_field(data, certnum, "dsa(p)", &elem)) - return 1; - p = getASN1Element(&elem, p, param->end); - if(p) { - if(do_pubkey_field(data, certnum, "dsa(q)", &elem)) - return 1; - if(getASN1Element(&elem, p, param->end)) { - if(do_pubkey_field(data, certnum, "dsa(g)", &elem)) - return 1; - if(do_pubkey_field(data, certnum, "dsa(pub_key)", &pk)) - return 1; - } - } - } - } - else if(curl_strequal(algo, "dhpublicnumber")) { - p = getASN1Element(&elem, param->beg, param->end); - if(p) { - if(do_pubkey_field(data, certnum, "dh(p)", &elem)) - return 1; - if(getASN1Element(&elem, param->beg, param->end)) { - if(do_pubkey_field(data, certnum, "dh(g)", &elem)) - return 1; - if(do_pubkey_field(data, certnum, "dh(pub_key)", &pk)) - return 1; - } - } - } - return 0; -} - -/* - * Convert an ASN.1 distinguished name into a printable string. - * Return error. - */ -static CURLcode DNtostr(struct dynbuf *store, struct Curl_asn1Element *dn) -{ - return encodeDN(store, dn); -} - -CURLcode Curl_extract_certinfo(struct Curl_easy *data, - int certnum, - const char *beg, - const char *end) -{ - struct Curl_X509certificate cert; - struct Curl_asn1Element param; - char *certptr; - size_t clen; - struct dynbuf out; - CURLcode result = CURLE_OK; - unsigned int version; - const char *ptr; - int rc; - - if(!data->set.ssl.certinfo) - if(certnum) - return CURLE_OK; - - curlx_dyn_init(&out, CURL_X509_STR_MAX); - /* Prepare the certificate information for curl_easy_getinfo(). */ - - /* Extract the certificate ASN.1 elements. */ - if(Curl_parseX509(&cert, beg, end)) - return CURLE_PEER_FAILED_VERIFICATION; - - /* Subject. */ - result = DNtostr(&out, &cert.subject); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Subject", &out); - if(result) - goto done; - } - curlx_dyn_reset(&out); - - /* Issuer. */ - result = DNtostr(&out, &cert.issuer); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Issuer", &out); - if(result) - goto done; - } - curlx_dyn_reset(&out); - - /* Version (always fits in less than 32 bits). */ - version = 0; - for(ptr = cert.version.beg; ptr < cert.version.end; ptr++) - version = (version << 8) | *(const unsigned char *)ptr; - if(data->set.ssl.certinfo) { - result = curlx_dyn_addf(&out, "%x", version); - if(result) - goto done; - result = ssl_push_certinfo_dyn(data, certnum, "Version", &out); - if(result) - goto done; - curlx_dyn_reset(&out); - } - - /* Serial number. */ - result = ASN1tostr(&out, &cert.serialNumber); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Serial Number", &out); - if(result) - goto done; - } - curlx_dyn_reset(&out); - - /* Signature algorithm .*/ - result = dumpAlgo(&out, ¶m, cert.signatureAlgorithm.beg, - cert.signatureAlgorithm.end); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Signature Algorithm", &out); - if(result) - goto done; - } - curlx_dyn_reset(&out); - - /* Start Date. */ - result = ASN1tostr(&out, &cert.notBefore); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Start Date", &out); - if(result) - goto done; - } - curlx_dyn_reset(&out); - - /* Expire Date. */ - result = ASN1tostr(&out, &cert.notAfter); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Expire Date", &out); - if(result) - goto done; - } - curlx_dyn_reset(&out); - - /* Public Key Algorithm. */ - result = dumpAlgo(&out, ¶m, cert.subjectPublicKeyAlgorithm.beg, - cert.subjectPublicKeyAlgorithm.end); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Public Key Algorithm", - &out); - if(result) - goto done; - } - - rc = do_pubkey(data, certnum, curlx_dyn_ptr(&out), - ¶m, &cert.subjectPublicKey); - if(rc) { - result = CURLE_OUT_OF_MEMORY; /* the most likely error */ - goto done; - } - curlx_dyn_reset(&out); - - /* Signature. */ - result = ASN1tostr(&out, &cert.signature); - if(result) - goto done; - if(data->set.ssl.certinfo) { - result = ssl_push_certinfo_dyn(data, certnum, "Signature", &out); - if(result) - goto done; - } - curlx_dyn_reset(&out); - - /* Generate PEM certificate. */ - result = curlx_base64_encode((const uint8_t *)cert.certificate.beg, - cert.certificate.end - cert.certificate.beg, - &certptr, &clen); - if(result) - goto done; - - /* Generate the final output certificate string. Format is: - -----BEGIN CERTIFICATE-----\n - \n - . - . - . - -----END CERTIFICATE-----\n - */ - - curlx_dyn_reset(&out); - - /* Build the certificate string. */ - result = curlx_dyn_add(&out, "-----BEGIN CERTIFICATE-----\n"); - if(!result) { - size_t j = 0; - - while(!result && (j < clen)) { - size_t chunksize = (clen - j) > 64 ? 64 : (clen - j); - result = curlx_dyn_addn(&out, &certptr[j], chunksize); - if(!result) - result = curlx_dyn_addn(&out, "\n", 1); - j += chunksize; - } - if(!result) - result = curlx_dyn_add(&out, "-----END CERTIFICATE-----\n"); - } - curlx_free(certptr); - if(!result) - if(data->set.ssl.certinfo) - result = ssl_push_certinfo_dyn(data, certnum, "Cert", &out); - -done: - if(result) - failf(data, "Failed extracting certificate chain"); - curlx_dyn_free(&out); - return result; -} - -#endif /* WANT_EXTRACT_CERTINFO */ - -#endif /* USE_GNUTLS || USE_WOLFSSL || USE_SCHANNEL || USE_MBEDTLS || - USE_RUSTLS */ diff --git a/vendor/curl/lib/vtls/x509asn1.h b/vendor/curl/lib/vtls/x509asn1.h deleted file mode 100644 index dda55ac77..000000000 --- a/vendor/curl/lib/vtls/x509asn1.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef HEADER_CURL_X509ASN1_H -#define HEADER_CURL_X509ASN1_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -/* forward-declare to make it visible in all builds */ -struct Curl_asn1Element; - -#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ - defined(USE_MBEDTLS) || defined(USE_RUSTLS) - -#include "cfilters.h" -#include "urldata.h" - -/* ASN.1 classes. */ -/* #define CURL_ASN1_UNIVERSAL 0 */ -/* #define CURL_ASN1_APPLICATION 1 */ -/* #define CURL_ASN1_CONTEXT_SPECIFIC 2 */ -/* #define CURL_ASN1_PRIVATE 3 */ - -/* ASN.1 types. */ -#define CURL_ASN1_BOOLEAN 1 -#define CURL_ASN1_INTEGER 2 -#define CURL_ASN1_BIT_STRING 3 -#define CURL_ASN1_OCTET_STRING 4 -#define CURL_ASN1_NULL 5 -#define CURL_ASN1_OBJECT_IDENTIFIER 6 -/* #define CURL_ASN1_OBJECT_DESCRIPTOR 7 */ -/* #define CURL_ASN1_INSTANCE_OF 8 */ -/* #define CURL_ASN1_REAL 9 */ -#define CURL_ASN1_ENUMERATED 10 -/* #define CURL_ASN1_EMBEDDED 11 */ -#define CURL_ASN1_UTF8_STRING 12 -/* #define CURL_ASN1_RELATIVE_OID 13 */ -/* #define CURL_ASN1_SEQUENCE 16 */ -/* #define CURL_ASN1_SET 17 */ -#define CURL_ASN1_NUMERIC_STRING 18 -#define CURL_ASN1_PRINTABLE_STRING 19 -#define CURL_ASN1_TELETEX_STRING 20 -/* #define CURL_ASN1_VIDEOTEX_STRING 21 */ -#define CURL_ASN1_IA5_STRING 22 -#define CURL_ASN1_UTC_TIME 23 -#define CURL_ASN1_GENERALIZED_TIME 24 -/* #define CURL_ASN1_GRAPHIC_STRING 25 */ -#define CURL_ASN1_VISIBLE_STRING 26 -/* #define CURL_ASN1_GENERAL_STRING 27 */ -#define CURL_ASN1_UNIVERSAL_STRING 28 -/* #define CURL_ASN1_CHARACTER_STRING 29 */ -#define CURL_ASN1_BMP_STRING 30 - -/* - * Types. - */ - -/* ASN.1 parsed element. */ -struct Curl_asn1Element { - const char *header; /* Pointer to header byte. */ - const char *beg; /* Pointer to element data. */ - const char *end; /* Pointer to 1st byte after element. */ - unsigned char eclass; /* ASN.1 element class. */ - unsigned char tag; /* ASN.1 element tag. */ - BIT(constructed); /* Element is constructed. */ -}; - -/* X509 certificate: RFC 5280. */ -struct Curl_X509certificate { - struct Curl_asn1Element certificate; - struct Curl_asn1Element version; - struct Curl_asn1Element serialNumber; - struct Curl_asn1Element signatureAlgorithm; - struct Curl_asn1Element signature; - struct Curl_asn1Element issuer; - struct Curl_asn1Element notBefore; - struct Curl_asn1Element notAfter; - struct Curl_asn1Element subject; - struct Curl_asn1Element subjectPublicKeyInfo; - struct Curl_asn1Element subjectPublicKeyAlgorithm; - struct Curl_asn1Element subjectPublicKey; - struct Curl_asn1Element issuerUniqueID; - struct Curl_asn1Element subjectUniqueID; - struct Curl_asn1Element extensions; -}; - -/* - * Prototypes. - */ - -int Curl_parseX509(struct Curl_X509certificate *cert, - const char *beg, const char *end); -CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum, - const char *beg, const char *end); -CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data, - const char *beg, const char *end); -#endif /* USE_GNUTLS || USE_WOLFSSL || USE_SCHANNEL || USE_MBEDTLS || - USE_RUSTLS */ -#endif /* HEADER_CURL_X509ASN1_H */ diff --git a/vendor/curl/lib/ws.c b/vendor/curl/lib/ws.c deleted file mode 100644 index d7840f1ff..000000000 --- a/vendor/curl/lib/ws.c +++ /dev/null @@ -1,1982 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" -#include "urldata.h" -#include "ws.h" - -#ifndef CURL_DISABLE_WEBSOCKETS - -#include "url.h" -#include "bufq.h" -#include "curlx/dynbuf.h" -#include "rand.h" -#include "curlx/base64.h" -#include "connect.h" -#include "sendf.h" -#include "curl_trc.h" -#include "multiif.h" -#include "easyif.h" -#include "transfer.h" -#include "select.h" -#include "curlx/strparse.h" -#include "curlx/strcopy.h" - -/*** - RFC 6455 Section 5.2 - - 0 1 2 3 4 5 6 7 - +-+-+-+-+-------+ - |F|R|R|R| opcode| - |I|S|S|S| (4) | - |N|V|V|V| | - | |1|2|3| | -*/ -#define WSBIT_FIN 0x80 -#define WSBIT_RSV1 0x40 -#define WSBIT_RSV2 0x20 -#define WSBIT_RSV3 0x10 -#define WSBIT_RSV_MASK (WSBIT_RSV1 | WSBIT_RSV2 | WSBIT_RSV3) -#define WSBIT_OPCODE_CONT 0x0 -#define WSBIT_OPCODE_TEXT 0x1 -#define WSBIT_OPCODE_BIN 0x2 -#define WSBIT_OPCODE_CLOSE 0x8 -#define WSBIT_OPCODE_PING 0x9 -#define WSBIT_OPCODE_PONG 0xa -#ifdef CURLVERBOSE -#define WSBIT_OPCODE_MASK 0xf -#endif - -#define WSBIT_MASK 0x80 - -/* buffer dimensioning */ -#define WS_CHUNK_SIZE 65535 -#define WS_CHUNK_COUNT 2 - -/* a client-side WS frame decoder, parsing frame headers and - * payload, keeping track of current position and stats */ -enum ws_dec_state { - WS_DEC_INIT, - WS_DEC_HEAD, - WS_DEC_PAYLOAD -}; - -struct ws_decoder { - int frame_age; /* zero */ - int frame_flags; /* See the CURLWS_* defines */ - curl_off_t payload_offset; /* the offset parsing is at */ - curl_off_t payload_len; - uint8_t head[10]; - int head_len, head_total; - enum ws_dec_state state; - int cont_flags; -}; - -/* a client-side WS frame encoder, generating frame headers and - * converting payloads, tracking remaining data in current frame */ -struct ws_encoder { - curl_off_t payload_len; /* payload length of current frame */ - curl_off_t payload_remain; /* remaining payload of current */ - unsigned int xori; /* xor index */ - uint8_t mask[4]; /* 32-bit mask for this connection */ - uint8_t firstbyte; /* first byte of frame we encode */ - BIT(contfragment); /* set TRUE if the previous fragment sent was not final */ -}; - -/* Control frames are allowed up to 125 characters, rfc6455, ch. 5.5 */ -#define WS_MAX_CNTRL_LEN 125 - -struct ws_cntrl_frame { - unsigned int type; - size_t payload_len; - uint8_t payload[WS_MAX_CNTRL_LEN]; -}; - -/* A websocket connection with en- and decoder that treat frames - * and keep track of boundaries. */ -struct websocket { - struct Curl_easy *data; /* used for write callback handling */ - struct ws_decoder dec; /* decode of ws frames */ - struct ws_encoder enc; /* encode of ws frames */ - struct bufq recvbuf; /* raw data from the server */ - struct bufq sendbuf; /* raw data to be sent to the server */ - struct curl_ws_frame recvframe; /* the current WS FRAME received */ - struct ws_cntrl_frame pending; /* a control frame pending to be sent */ - size_t sendbuf_payload; /* number of payload bytes in sendbuf */ -}; - -#ifdef CURLVERBOSE -static const char *ws_frame_name_of_op(uint8_t firstbyte) -{ - switch(firstbyte & WSBIT_OPCODE_MASK) { - case WSBIT_OPCODE_CONT: - return "CONT"; - case WSBIT_OPCODE_TEXT: - return "TEXT"; - case WSBIT_OPCODE_BIN: - return "BIN"; - case WSBIT_OPCODE_CLOSE: - return "CLOSE"; - case WSBIT_OPCODE_PING: - return "PING"; - case WSBIT_OPCODE_PONG: - return "PONG"; - default: - return "???"; - } -} -#endif - -static int ws_frame_firstbyte2flags(struct Curl_easy *data, - uint8_t firstbyte, int cont_flags) -{ - switch(firstbyte) { - /* 0x00 - intermediate TEXT/BINARY fragment */ - case WSBIT_OPCODE_CONT: - if(!(cont_flags & CURLWS_CONT)) { - failf(data, "[WS] no ongoing fragmented message to resume"); - return 0; - } - return cont_flags | CURLWS_CONT; - /* 0x80 - final TEXT/BIN fragment */ - case (WSBIT_OPCODE_CONT | WSBIT_FIN): - if(!(cont_flags & CURLWS_CONT)) { - failf(data, "[WS] no ongoing fragmented message to resume"); - return 0; - } - return cont_flags & ~CURLWS_CONT; - /* 0x01 - first TEXT fragment */ - case WSBIT_OPCODE_TEXT: - if(cont_flags & CURLWS_CONT) { - failf(data, "[WS] fragmented message interrupted by new TEXT msg"); - return 0; - } - return CURLWS_TEXT | CURLWS_CONT; - /* 0x81 - unfragmented TEXT msg */ - case (WSBIT_OPCODE_TEXT | WSBIT_FIN): - if(cont_flags & CURLWS_CONT) { - failf(data, "[WS] fragmented message interrupted by new TEXT msg"); - return 0; - } - return CURLWS_TEXT; - /* 0x02 - first BINARY fragment */ - case WSBIT_OPCODE_BIN: - if(cont_flags & CURLWS_CONT) { - failf(data, "[WS] fragmented message interrupted by new BINARY msg"); - return 0; - } - return CURLWS_BINARY | CURLWS_CONT; - /* 0x82 - unfragmented BINARY msg */ - case (WSBIT_OPCODE_BIN | WSBIT_FIN): - if(cont_flags & CURLWS_CONT) { - failf(data, "[WS] fragmented message interrupted by new BINARY msg"); - return 0; - } - return CURLWS_BINARY; - /* 0x08 - first CLOSE fragment */ - case WSBIT_OPCODE_CLOSE: - failf(data, "[WS] invalid fragmented CLOSE frame"); - return 0; - /* 0x88 - unfragmented CLOSE */ - case (WSBIT_OPCODE_CLOSE | WSBIT_FIN): - return CURLWS_CLOSE; - /* 0x09 - first PING fragment */ - case WSBIT_OPCODE_PING: - failf(data, "[WS] invalid fragmented PING frame"); - return 0; - /* 0x89 - unfragmented PING */ - case (WSBIT_OPCODE_PING | WSBIT_FIN): - return CURLWS_PING; - /* 0x0a - first PONG fragment */ - case WSBIT_OPCODE_PONG: - failf(data, "[WS] invalid fragmented PONG frame"); - return 0; - /* 0x8a - unfragmented PONG */ - case (WSBIT_OPCODE_PONG | WSBIT_FIN): - return CURLWS_PONG; - /* invalid first byte */ - default: - if(firstbyte & WSBIT_RSV_MASK) - /* any of the reserved bits 0x40/0x20/0x10 are set */ - failf(data, "[WS] invalid reserved bits: %02x", firstbyte); - else - /* any of the reserved opcodes 0x3-0x7 or 0xb-0xf is used */ - failf(data, "[WS] invalid opcode: %02x", firstbyte); - return 0; - } -} - -static CURLcode ws_frame_flags2firstbyte(struct Curl_easy *data, - unsigned int flags, - bool contfragment, - uint8_t *pfirstbyte) -{ - *pfirstbyte = 0; - switch(flags & ~CURLWS_OFFSET) { - case 0: - if(contfragment) { - CURL_TRC_WS(data, "no flags given; interpreting as continuation " - "fragment for compatibility"); - *pfirstbyte = (WSBIT_OPCODE_CONT | WSBIT_FIN); - return CURLE_OK; - } - failf(data, "[WS] no flags given"); - return CURLE_BAD_FUNCTION_ARGUMENT; - case CURLWS_CONT: - if(contfragment) { - infof(data, "[WS] setting CURLWS_CONT flag without message type is " - "supported for compatibility but highly discouraged"); - *pfirstbyte = WSBIT_OPCODE_CONT; - return CURLE_OK; - } - failf(data, "[WS] No ongoing fragmented message to continue"); - return CURLE_BAD_FUNCTION_ARGUMENT; - case CURLWS_TEXT: - *pfirstbyte = contfragment ? (WSBIT_OPCODE_CONT | WSBIT_FIN) - : (WSBIT_OPCODE_TEXT | WSBIT_FIN); - return CURLE_OK; - case (CURLWS_TEXT | CURLWS_CONT): - *pfirstbyte = contfragment ? WSBIT_OPCODE_CONT : WSBIT_OPCODE_TEXT; - return CURLE_OK; - case CURLWS_BINARY: - *pfirstbyte = contfragment ? (WSBIT_OPCODE_CONT | WSBIT_FIN) - : (WSBIT_OPCODE_BIN | WSBIT_FIN); - return CURLE_OK; - case (CURLWS_BINARY | CURLWS_CONT): - *pfirstbyte = contfragment ? WSBIT_OPCODE_CONT : WSBIT_OPCODE_BIN; - return CURLE_OK; - case CURLWS_CLOSE: - *pfirstbyte = WSBIT_OPCODE_CLOSE | WSBIT_FIN; - return CURLE_OK; - case (CURLWS_CLOSE | CURLWS_CONT): - failf(data, "[WS] CLOSE frame must not be fragmented"); - return CURLE_BAD_FUNCTION_ARGUMENT; - case CURLWS_PING: - *pfirstbyte = WSBIT_OPCODE_PING | WSBIT_FIN; - return CURLE_OK; - case (CURLWS_PING | CURLWS_CONT): - failf(data, "[WS] PING frame must not be fragmented"); - return CURLE_BAD_FUNCTION_ARGUMENT; - case CURLWS_PONG: - *pfirstbyte = WSBIT_OPCODE_PONG | WSBIT_FIN; - return CURLE_OK; - case (CURLWS_PONG | CURLWS_CONT): - failf(data, "[WS] PONG frame must not be fragmented"); - return CURLE_BAD_FUNCTION_ARGUMENT; - default: - failf(data, "[WS] unknown flags: %x", flags); - return CURLE_BAD_FUNCTION_ARGUMENT; - } -} - -static void ws_dec_info(struct ws_decoder *dec, struct Curl_easy *data, - const char *msg) -{ - NOVERBOSE((void)msg); - switch(dec->head_len) { - case 0: - break; - case 1: - CURL_TRC_WS(data, "decoded %s [%s%s]", msg, - ws_frame_name_of_op(dec->head[0]), - (dec->head[0] & WSBIT_FIN) ? "" : " NON-FINAL"); - break; - default: - if(dec->head_len < dec->head_total) { - CURL_TRC_WS(data, "decoded %s [%s%s](%d/%d)", msg, - ws_frame_name_of_op(dec->head[0]), - (dec->head[0] & WSBIT_FIN) ? "" : " NON-FINAL", - dec->head_len, dec->head_total); - } - else { - CURL_TRC_WS(data, "decoded %s [%s%s payload=%" - FMT_OFF_T "/%" FMT_OFF_T "]", - msg, ws_frame_name_of_op(dec->head[0]), - (dec->head[0] & WSBIT_FIN) ? "" : " NON-FINAL", - dec->payload_offset, dec->payload_len); - } - break; - } -} - -static CURLcode ws_send_raw_blocking(struct Curl_easy *data, - struct websocket *ws, - const char *buffer, size_t buflen); - -typedef CURLcode ws_write_payload(const uint8_t *buf, size_t buflen, - int frame_age, int frame_flags, - curl_off_t payload_offset, - curl_off_t payload_len, - void *userp, - size_t *pnwritten); - -static void ws_dec_next_frame(struct ws_decoder *dec) -{ - dec->frame_age = 0; - dec->frame_flags = 0; - dec->payload_offset = 0; - dec->payload_len = 0; - dec->head_len = dec->head_total = 0; - dec->state = WS_DEC_INIT; - /* dec->cont_flags must be carried over to next frame */ -} - -static void ws_dec_reset(struct ws_decoder *dec) -{ - dec->frame_age = 0; - dec->frame_flags = 0; - dec->payload_offset = 0; - dec->payload_len = 0; - dec->head_len = dec->head_total = 0; - dec->state = WS_DEC_INIT; - dec->cont_flags = 0; -} - -static void ws_dec_init(struct ws_decoder *dec) -{ - ws_dec_reset(dec); -} - -static CURLcode ws_dec_read_head(struct ws_decoder *dec, - struct Curl_easy *data, - struct bufq *inraw) -{ - const uint8_t *inbuf; - size_t inlen; - - while(Curl_bufq_peek(inraw, &inbuf, &inlen)) { - if(dec->head_len == 0) { - dec->head[0] = *inbuf; - Curl_bufq_skip(inraw, 1); - - dec->frame_flags = ws_frame_firstbyte2flags(data, dec->head[0], - dec->cont_flags); - if(!dec->frame_flags) { - ws_dec_reset(dec); - return CURLE_RECV_ERROR; - } - - /* fragmentation only applies to data frames (text/binary); - * control frames (close/ping/pong) do not affect the CONT status */ - if(dec->frame_flags & (CURLWS_TEXT | CURLWS_BINARY)) { - dec->cont_flags = dec->frame_flags; - } - - dec->head_len = 1; -#if 0 - ws_dec_info(dec, data, "seeing opcode"); -#endif - continue; - } - else if(dec->head_len == 1) { - dec->head[1] = *inbuf; - Curl_bufq_skip(inraw, 1); - dec->head_len = 2; - - if(dec->head[1] & WSBIT_MASK) { - /* A client MUST close a connection if it detects a masked frame. */ - failf(data, "[WS] masked input frame"); - ws_dec_reset(dec); - return CURLE_RECV_ERROR; - } - if(dec->frame_flags & CURLWS_PING && dec->head[1] > WS_MAX_CNTRL_LEN) { - /* The maximum valid size of PING frames is 125 bytes. - Accepting overlong pings would mean sending equivalent pongs! */ - failf(data, "[WS] received PING frame is too big"); - ws_dec_reset(dec); - return CURLE_RECV_ERROR; - } - if(dec->frame_flags & CURLWS_PONG && dec->head[1] > WS_MAX_CNTRL_LEN) { - /* The maximum valid size of PONG frames is 125 bytes. */ - failf(data, "[WS] received PONG frame is too big"); - ws_dec_reset(dec); - return CURLE_RECV_ERROR; - } - if(dec->frame_flags & CURLWS_CLOSE && dec->head[1] > WS_MAX_CNTRL_LEN) { - failf(data, "[WS] received CLOSE frame is too big"); - ws_dec_reset(dec); - return CURLE_RECV_ERROR; - } - - /* How long is the frame head? */ - if(dec->head[1] == 126) { - dec->head_total = 4; - continue; - } - else if(dec->head[1] == 127) { - dec->head_total = 10; - continue; - } - else { - dec->head_total = 2; - } - } - - if(dec->head_len < dec->head_total) { - dec->head[dec->head_len] = *inbuf; - Curl_bufq_skip(inraw, 1); - ++dec->head_len; - if(dec->head_len < dec->head_total) { -#if 0 - ws_dec_info(dec, data, "decoding head"); -#endif - continue; - } - } - /* got the complete frame head */ - DEBUGASSERT(dec->head_len == dec->head_total); - switch(dec->head_total) { - case 2: - dec->payload_len = dec->head[1]; - break; - case 4: - dec->payload_len = (dec->head[2] << 8) | dec->head[3]; - break; - case 10: - if(dec->head[2] > 127) { - failf(data, "[WS] frame length longer than 63 bits not supported"); - return CURLE_RECV_ERROR; - } - dec->payload_len = - (curl_off_t)dec->head[2] << 56 | - (curl_off_t)dec->head[3] << 48 | - (curl_off_t)dec->head[4] << 40 | - (curl_off_t)dec->head[5] << 32 | - (curl_off_t)dec->head[6] << 24 | - (curl_off_t)dec->head[7] << 16 | - (curl_off_t)dec->head[8] << 8 | - dec->head[9]; - break; - default: - /* this should never happen */ - DEBUGASSERT(0); - failf(data, "[WS] unexpected frame header length"); - return CURLE_RECV_ERROR; - } - - dec->frame_age = 0; - dec->payload_offset = 0; - ws_dec_info(dec, data, "decoded"); - return CURLE_OK; - } - return CURLE_AGAIN; -} - -static CURLcode ws_dec_pass_payload(struct ws_decoder *dec, - struct Curl_easy *data, - struct bufq *inraw, - ws_write_payload *write_cb, - void *write_ctx) -{ - const uint8_t *inbuf; - size_t inlen; - size_t nwritten; - CURLcode result; - size_t remain = curlx_sotouz_range(dec->payload_len - dec->payload_offset, - 0, SIZE_MAX); - - while(remain && Curl_bufq_peek(inraw, &inbuf, &inlen)) { - if(inlen > remain) - inlen = remain; - result = write_cb(inbuf, inlen, dec->frame_age, dec->frame_flags, - dec->payload_offset, dec->payload_len, - write_ctx, &nwritten); - if(result) - return result; - Curl_bufq_skip(inraw, nwritten); - dec->payload_offset += nwritten; - remain = curlx_sotouz_range(dec->payload_len - dec->payload_offset, - 0, SIZE_MAX); - CURL_TRC_WS(data, "passed %zu bytes payload, %zu remain", - nwritten, remain); - } - - return remain ? CURLE_AGAIN : CURLE_OK; -} - -static CURLcode ws_dec_pass(struct ws_decoder *dec, - struct Curl_easy *data, - struct bufq *inraw, - ws_write_payload *write_cb, - void *write_ctx) -{ - CURLcode result; - - if(Curl_bufq_is_empty(inraw)) - return CURLE_AGAIN; - - switch(dec->state) { - case WS_DEC_INIT: - ws_dec_next_frame(dec); - dec->state = WS_DEC_HEAD; - FALLTHROUGH(); - case WS_DEC_HEAD: - result = ws_dec_read_head(dec, data, inraw); - if(result) { - if(result != CURLE_AGAIN) { - failf(data, "[WS] decode frame error %d", (int)result); - break; /* real error */ - } - /* incomplete ws frame head */ - DEBUGASSERT(Curl_bufq_is_empty(inraw)); - break; - } - /* head parsing done */ - dec->state = WS_DEC_PAYLOAD; - if(dec->payload_len == 0) { - size_t nwritten; - const uint8_t tmp = '\0'; - /* special case of a 0 length frame, need to write once */ - result = write_cb(&tmp, 0, dec->frame_age, dec->frame_flags, - 0, 0, write_ctx, &nwritten); - if(result) - return result; - dec->state = WS_DEC_INIT; - break; - } - FALLTHROUGH(); - case WS_DEC_PAYLOAD: - result = ws_dec_pass_payload(dec, data, inraw, write_cb, write_ctx); - ws_dec_info(dec, data, "passing"); - if(result) - return result; - /* payload parsing done */ - dec->state = WS_DEC_INIT; - break; - default: - /* we covered all enums above, but some code analyzers are wimps */ - result = CURLE_FAILED_INIT; - } - return result; -} - -static void update_meta(struct websocket *ws, - int frame_age, int frame_flags, - curl_off_t payload_offset, - curl_off_t payload_len, - size_t cur_len) -{ - curl_off_t bytesleft = (payload_len - payload_offset - cur_len); - - ws->recvframe.age = frame_age; - ws->recvframe.flags = frame_flags; - ws->recvframe.offset = payload_offset; - ws->recvframe.len = cur_len; - ws->recvframe.bytesleft = bytesleft; -} - -/* WebSocket decoding client writer */ -struct ws_cw_ctx { - struct Curl_cwriter super; - struct bufq buf; -}; - -static CURLcode ws_cw_init(struct Curl_easy *data, - struct Curl_cwriter *writer) -{ - struct ws_cw_ctx *ctx = writer->ctx; - (void)data; - Curl_bufq_init2(&ctx->buf, WS_CHUNK_SIZE, 1, BUFQ_OPT_SOFT_LIMIT); - return CURLE_OK; -} - -static void ws_cw_close(struct Curl_easy *data, struct Curl_cwriter *writer) -{ - struct ws_cw_ctx *ctx = writer->ctx; - (void)data; - Curl_bufq_free(&ctx->buf); -} - -struct ws_cw_dec_ctx { - struct Curl_easy *data; - struct websocket *ws; - struct Curl_cwriter *next_writer; - int cw_type; -}; - -static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws, - bool blocking); -static CURLcode ws_enc_send(struct Curl_easy *data, - struct websocket *ws, - const uint8_t *buffer, - size_t buflen, - curl_off_t fragsize, - unsigned int flags, - size_t *pnsent); -static CURLcode ws_enc_add_pending(struct Curl_easy *data, - struct websocket *ws); - -static CURLcode ws_enc_add_cntrl(struct Curl_easy *data, - struct websocket *ws, - const uint8_t *payload, - size_t plen, - unsigned int frame_type) -{ - DEBUGASSERT(plen <= WS_MAX_CNTRL_LEN); - if(plen > WS_MAX_CNTRL_LEN) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* Overwrite any pending frame with the new one, we keep - * only one. */ - ws->pending.type = frame_type; - ws->pending.payload_len = plen; - memcpy(ws->pending.payload, payload, plen); - - if(!ws->enc.payload_remain) { /* not in the middle of another frame */ - CURLcode result = ws_enc_add_pending(data, ws); - if(!result) - (void)ws_flush(data, ws, Curl_is_in_callback(data)); - return result; - } - return CURLE_OK; -} - -static curl_off_t ws_payload_remain(curl_off_t payload_total, - curl_off_t payload_offset, - size_t payload_buffered) -{ - curl_off_t buffered, remain = payload_total - payload_offset; - if((payload_total < 0) || (payload_offset < 0) || (remain < 0)) - return -1; - buffered = curlx_uztoso(payload_buffered); - if(remain < buffered) - return -1; - return remain - buffered; -} - -static CURLcode ws_cw_dec_next(const uint8_t *buf, size_t buflen, - int frame_age, int frame_flags, - curl_off_t payload_offset, - curl_off_t payload_len, - void *user_data, - size_t *pnwritten) -{ - struct ws_cw_dec_ctx *ctx = user_data; - struct Curl_easy *data = ctx->data; - struct websocket *ws = ctx->ws; - bool auto_pong = !data->set.ws_no_auto_pong; - curl_off_t remain; - CURLcode result; - - (void)frame_age; - *pnwritten = 0; - remain = ws_payload_remain(payload_len, payload_offset, buflen); - if(remain < 0) { - DEBUGASSERT(0); /* parameter mismatch */ - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - if(auto_pong && (frame_flags & CURLWS_PING) && !remain) { - /* auto-respond to PINGs, only works for single-frame payloads atm */ - CURL_TRC_WS(data, "auto PONG to [PING payload=%" FMT_OFF_T - "/%" FMT_OFF_T "]", payload_offset, payload_len); - /* send back the exact same content as a PONG */ - result = ws_enc_add_cntrl(data, ws, buf, buflen, CURLWS_PONG); - if(result) - return result; - } - else if(buflen || !remain) { - /* forward the decoded frame to the next client writer. */ - update_meta(ws, frame_age, frame_flags, payload_offset, - payload_len, buflen); - - result = Curl_cwriter_write(data, ctx->next_writer, - (ctx->cw_type | CLIENTWRITE_0LEN), - (const char *)buf, buflen); - if(result) - return result; - } - *pnwritten = buflen; - return CURLE_OK; -} - -static CURLcode ws_cw_write(struct Curl_easy *data, - struct Curl_cwriter *writer, int type, - const char *buf, size_t nbytes) -{ - struct ws_cw_ctx *ctx = writer->ctx; - struct websocket *ws; - CURLcode result; - - CURL_TRC_WRITE(data, "ws_cw_write(len=%zu, type=%d)", nbytes, type); - if(!(type & CLIENTWRITE_BODY) || data->set.ws_raw_mode) - return Curl_cwriter_write(data, writer->next, type, buf, nbytes); - - ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); - if(!ws) { - failf(data, "[WS] not a websocket transfer"); - return CURLE_FAILED_INIT; - } - - if(nbytes) { - size_t nwritten; - result = Curl_bufq_write(&ctx->buf, (const uint8_t *)buf, - nbytes, &nwritten); - if(result) { - infof(data, "[WS] error adding data to buffer %d", result); - return result; - } - } - - while(!Curl_bufq_is_empty(&ctx->buf)) { - struct ws_cw_dec_ctx pass_ctx; - pass_ctx.data = data; - pass_ctx.ws = ws; - pass_ctx.next_writer = writer->next; - pass_ctx.cw_type = type; - result = ws_dec_pass(&ws->dec, data, &ctx->buf, - ws_cw_dec_next, &pass_ctx); - if(result == CURLE_AGAIN) { - /* insufficient amount of data, keep it for later. - * we pretend to have written all since we have a copy */ - return CURLE_OK; - } - else if(result) { - failf(data, "[WS] decode payload error %d", (int)result); - return result; - } - } - - if((type & CLIENTWRITE_EOS) && !Curl_bufq_is_empty(&ctx->buf)) { - failf(data, "[WS] decode ending with %zu frame bytes remaining", - Curl_bufq_len(&ctx->buf)); - return CURLE_RECV_ERROR; - } - - return CURLE_OK; -} - -/* WebSocket payload decoding client writer. */ -static const struct Curl_cwtype ws_cw_decode = { - "ws-decode", - NULL, - ws_cw_init, - ws_cw_write, - ws_cw_close, - sizeof(struct ws_cw_ctx) -}; - -static void ws_enc_info(struct ws_encoder *enc, struct Curl_easy *data, - const char *msg) -{ - NOVERBOSE((void)enc); - NOVERBOSE((void)msg); - CURL_TRC_WS(data, "WS-ENC: %s [%s%s payload=%" - FMT_OFF_T "/%" FMT_OFF_T "]", - msg, ws_frame_name_of_op(enc->firstbyte), - (enc->firstbyte & WSBIT_FIN) ? "" : " NON-FIN", - enc->payload_len - enc->payload_remain, enc->payload_len); -} - -static void ws_enc_reset(struct ws_encoder *enc) -{ - enc->payload_remain = 0; - enc->xori = 0; - enc->contfragment = FALSE; -} - -static void ws_enc_init(struct ws_encoder *enc) -{ - ws_enc_reset(enc); -} - -/*** - RFC 6455 Section 5.2 - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-------+-+-------------+-------------------------------+ - |F|R|R|R| opcode|M| Payload len | Extended payload length | - |I|S|S|S| (4) |A| (7) | (16/64) | - |N|V|V|V| |S| | (if payload len==126/127) | - | |1|2|3| |K| | | - +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - | Extended payload length continued, if payload len == 127 | - + - - - - - - - - - - - - - - - +-------------------------------+ - | |Masking-key, if MASK set to 1 | - +-------------------------------+-------------------------------+ - | Masking-key (continued) | Payload Data | - +-------------------------------- - - - - - - - - - - - - - - - + - : Payload Data continued ... : - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - | Payload Data continued ... | - +---------------------------------------------------------------+ -*/ - -static CURLcode ws_enc_add_frame(struct Curl_easy *data, - struct ws_encoder *enc, - unsigned int flags, - curl_off_t payload_len, - struct bufq *out) -{ - uint8_t firstb = 0; - uint8_t head[14]; - CURLcode result; - size_t hlen, nwritten; - - if(payload_len < 0) { - failf(data, "[WS] starting new frame with negative payload length %" - FMT_OFF_T, payload_len); - return CURLE_SEND_ERROR; - } - - if(enc->payload_remain > 0) { - /* trying to write a new frame before the previous one is finished */ - failf(data, "[WS] starting new frame with %" FMT_OFF_T " bytes " - "from last one remaining to be sent", enc->payload_remain); - return CURLE_SEND_ERROR; - } - - result = ws_frame_flags2firstbyte(data, flags, (bool)enc->contfragment, - &firstb); - if(result) - return result; - - /* fragmentation only applies to data frames (text/binary); - * control frames (close/ping/pong) do not affect the CONT status */ - if(flags & (CURLWS_TEXT | CURLWS_BINARY)) { - enc->contfragment = (curl_bit)((flags & CURLWS_CONT) ? TRUE : FALSE); - } - - if(flags & CURLWS_PING && payload_len > WS_MAX_CNTRL_LEN) { - failf(data, "[WS] given PING frame is too big"); - return CURLE_TOO_LARGE; - } - if(flags & CURLWS_PONG && payload_len > WS_MAX_CNTRL_LEN) { - failf(data, "[WS] given PONG frame is too big"); - return CURLE_TOO_LARGE; - } - if(flags & CURLWS_CLOSE && payload_len > WS_MAX_CNTRL_LEN) { - failf(data, "[WS] given CLOSE frame is too big"); - return CURLE_TOO_LARGE; - } - - head[0] = enc->firstbyte = firstb; - if(payload_len > 65535) { - head[1] = 127 | WSBIT_MASK; - head[2] = (uint8_t)((payload_len >> 56) & 0xff); - head[3] = (uint8_t)((payload_len >> 48) & 0xff); - head[4] = (uint8_t)((payload_len >> 40) & 0xff); - head[5] = (uint8_t)((payload_len >> 32) & 0xff); - head[6] = (uint8_t)((payload_len >> 24) & 0xff); - head[7] = (uint8_t)((payload_len >> 16) & 0xff); - head[8] = (uint8_t)((payload_len >> 8) & 0xff); - head[9] = (uint8_t)(payload_len & 0xff); - hlen = 10; - } - else if(payload_len >= 126) { - head[1] = 126 | WSBIT_MASK; - head[2] = (uint8_t)((payload_len >> 8) & 0xff); - head[3] = (uint8_t)(payload_len & 0xff); - hlen = 4; - } - else { - head[1] = (uint8_t)payload_len | WSBIT_MASK; - hlen = 2; - } - - enc->payload_remain = enc->payload_len = payload_len; - ws_enc_info(enc, data, "sending"); - - /* 4 bytes random */ - - result = Curl_rand(data, (uint8_t *)&enc->mask, sizeof(enc->mask)); - if(result) - return result; - -#ifdef DEBUGBUILD - if(getenv("CURL_WS_FORCE_ZERO_MASK")) - /* force the bit mask to 0x00000000, effectively disabling masking */ - memset(&enc->mask, 0, sizeof(enc->mask)); -#endif - - /* add 4 bytes mask */ - memcpy(&head[hlen], &enc->mask, 4); - hlen += 4; - /* reset for payload to come */ - enc->xori = 0; - - result = Curl_bufq_write(out, head, hlen, &nwritten); - if(result) - return result; - if(nwritten != hlen) { - /* We use a bufq with SOFT_LIMIT, writing should always succeed */ - DEBUGASSERT(0); - return CURLE_SEND_ERROR; - } - return CURLE_OK; -} - -static CURLcode ws_enc_write_head(struct Curl_easy *data, - struct websocket *ws, - struct ws_encoder *enc, - unsigned int flags, - curl_off_t payload_len, - struct bufq *out) -{ - /* starting a new frame, we want a clean sendbuf. - * Any pending control frame we can add now as part of the flush. */ - if(ws->pending.type) { - CURLcode result = ws_enc_add_pending(data, ws); - if(result) - return result; - } - return ws_enc_add_frame(data, enc, flags, payload_len, out); -} - -static CURLcode ws_enc_write_payload(struct ws_encoder *enc, - struct Curl_easy *data, - const uint8_t *buf, size_t buflen, - struct bufq *out, size_t *pnwritten) -{ - CURLcode result; - size_t i, len, n, remain; - - *pnwritten = 0; - if(Curl_bufq_is_full(out)) - return CURLE_AGAIN; - - /* not the most performant way to do this */ - len = buflen; - remain = curlx_sotouz_range(enc->payload_remain, 0, SIZE_MAX); - if(remain < len) - len = remain; - - for(i = 0; i < len; ++i) { - uint8_t c = buf[i] ^ enc->mask[enc->xori]; - result = Curl_bufq_write(out, &c, 1, &n); - if(result) { - if((result != CURLE_AGAIN) || !i) - return result; - break; - } - enc->xori++; - enc->xori &= 3; - } - *pnwritten = i; - enc->payload_remain -= (curl_off_t)i; - ws_enc_info(enc, data, "buffered"); - return CURLE_OK; -} - -static CURLcode ws_enc_add_pending(struct Curl_easy *data, - struct websocket *ws) -{ - CURLcode result; - size_t n; - - if(!ws->pending.type) /* no pending frame here */ - return CURLE_OK; - if(ws->enc.payload_remain) /* in the middle of another frame */ - return CURLE_AGAIN; - - result = ws_enc_add_frame(data, &ws->enc, ws->pending.type, - (curl_off_t)ws->pending.payload_len, - &ws->sendbuf); - if(result) { - CURL_TRC_WS(data, "ws_enc_cntrl(), error adding head: %d", - result); - goto out; - } - result = ws_enc_write_payload(&ws->enc, data, ws->pending.payload, - ws->pending.payload_len, - &ws->sendbuf, &n); - if(result) { - CURL_TRC_WS(data, "ws_enc_cntrl(), error adding payload: %d", - result); - goto out; - } - if(n != ws->pending.payload_len) { - DEBUGASSERT(0); /* buffer should always be able to take all */ - CURL_TRC_WS(data, "ws_enc_cntrl(), error added only %zu/%zu payload,", - n, ws->pending.payload_len); - result = CURLE_SEND_ERROR; - goto out; - } - /* the frame should be complete now */ - DEBUGASSERT(!ws->enc.payload_remain); - memset(&ws->pending, 0, sizeof(ws->pending)); - -out: - return result; -} - -static CURLcode ws_enc_send(struct Curl_easy *data, - struct websocket *ws, - const uint8_t *buffer, - size_t buflen, - curl_off_t fragsize, - unsigned int flags, - size_t *pnsent) -{ - size_t n; - CURLcode result = CURLE_OK; - - DEBUGASSERT(!data->set.ws_raw_mode); - *pnsent = 0; - - if(ws->enc.payload_remain || !Curl_bufq_is_empty(&ws->sendbuf)) { - /* a frame is ongoing with payload buffered or more payload - * that needs to be encoded into the buffer */ - if(buflen < ws->sendbuf_payload) { - /* We have been called with LESS buffer data than before. This - * is not how it is supposed too work. */ - failf(data, "[WS] curl_ws_send() called with smaller 'buflen' than " - "bytes already buffered in previous call, %zu vs %zu", - buflen, ws->sendbuf_payload); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if((curl_off_t)buflen > - (ws->enc.payload_remain + (curl_off_t)ws->sendbuf_payload)) { - /* too large buflen beyond payload length of frame */ - failf(data, "[WS] unaligned frame size (sending %zu instead of " - "%" FMT_OFF_T ")", buflen, - (curl_off_t)(ws->enc.payload_remain + ws->sendbuf_payload)); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - else { - result = ws_flush(data, ws, Curl_is_in_callback(data)); - if(result) - return result; - - result = ws_enc_write_head(data, ws, &ws->enc, flags, - (flags & CURLWS_OFFSET) ? - fragsize : (curl_off_t)buflen, - &ws->sendbuf); - if(result) { - CURL_TRC_WS(data, "curl_ws_send(), error writing frame head %d", result); - return result; - } - } - - /* While there is either sendbuf to flush OR more payload to encode... */ - while(!Curl_bufq_is_empty(&ws->sendbuf) || (buflen > ws->sendbuf_payload)) { - /* Try to add more payload to sendbuf */ - if(buflen > ws->sendbuf_payload) { - size_t prev_len = Curl_bufq_len(&ws->sendbuf); - result = ws_enc_write_payload(&ws->enc, data, - buffer + ws->sendbuf_payload, - buflen - ws->sendbuf_payload, - &ws->sendbuf, &n); - if(result && (result != CURLE_AGAIN)) - return result; - ws->sendbuf_payload += Curl_bufq_len(&ws->sendbuf) - prev_len; - if(!ws->sendbuf_payload) { - return CURLE_AGAIN; - } - } - - /* flush, blocking when in callback */ - result = ws_flush(data, ws, Curl_is_in_callback(data)); - if(!result && ws->sendbuf_payload > 0) { - *pnsent += ws->sendbuf_payload; - buffer += ws->sendbuf_payload; - buflen -= ws->sendbuf_payload; - ws->sendbuf_payload = 0; - } - else if(result == CURLE_AGAIN) { - if(ws->sendbuf_payload > Curl_bufq_len(&ws->sendbuf)) { - /* blocked, part of payload bytes remain, report length - * that we managed to send. */ - size_t flushed = (ws->sendbuf_payload - Curl_bufq_len(&ws->sendbuf)); - *pnsent += flushed; - ws->sendbuf_payload -= flushed; - return CURLE_OK; - } - else { - /* blocked before sending headers or 1st payload byte. We cannot report - * OK on 0-length send (caller counts only payload) and EAGAIN */ - CURL_TRC_WS(data, "EAGAIN flushing sendbuf, payload_encoded: %zu/%zu", - ws->sendbuf_payload, buflen); - DEBUGASSERT(*pnsent == 0); - return CURLE_AGAIN; - } - } - else - return result; /* real error sending the data */ - } - return CURLE_OK; -} - -struct cr_ws_ctx { - struct Curl_creader super; - BIT(read_eos); /* we read an EOS from the next reader */ - BIT(eos); /* we have returned an EOS */ -}; - -static CURLcode cr_ws_init(struct Curl_easy *data, struct Curl_creader *reader) -{ - (void)data; - (void)reader; - return CURLE_OK; -} - -static void cr_ws_close(struct Curl_easy *data, struct Curl_creader *reader) -{ - (void)data; - (void)reader; -} - -static CURLcode cr_ws_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct cr_ws_ctx *ctx = reader->ctx; - CURLcode result = CURLE_OK; - size_t nread, n; - struct websocket *ws; - bool eos; - - *pnread = 0; - if(ctx->eos) { - *peos = TRUE; - return CURLE_OK; - } - - ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); - if(!ws) { - failf(data, "[WS] not a websocket transfer"); - return CURLE_FAILED_INIT; - } - - if(Curl_bufq_is_empty(&ws->sendbuf)) { - if(ctx->read_eos) { - ctx->eos = TRUE; - *peos = TRUE; - return CURLE_OK; - } - - if(ws->enc.payload_remain) { - CURL_TRC_WS(data, "current frame, %" FMT_OFF_T " remaining", - ws->enc.payload_remain); - blen = curlx_sotouz_range(ws->enc.payload_remain, 0, blen); - } - - result = Curl_creader_read(data, reader->next, buf, blen, &nread, &eos); - if(result) - return result; - ctx->read_eos = eos; - - if(!Curl_bufq_is_empty(&ws->sendbuf)) { - /* client_read started a new frame, we disregard any eos reported */ - ctx->read_eos = FALSE; - Curl_creader_clear_eos(data, reader->next); - } - else if(!nread) { - /* nothing to convert, return this right away */ - if(ctx->read_eos) - ctx->eos = TRUE; - *pnread = nread; - *peos = (bool)ctx->eos; - goto out; - } - - if(!ws->enc.payload_remain && Curl_bufq_is_empty(&ws->sendbuf)) { - /* encode the data as a new BINARY frame */ - result = ws_enc_write_head(data, ws, &ws->enc, CURLWS_BINARY, nread, - &ws->sendbuf); - if(result) - goto out; - } - - result = ws_enc_write_payload(&ws->enc, data, (uint8_t *)buf, - nread, &ws->sendbuf, &n); - if(result) - goto out; - CURL_TRC_READ(data, "cr_ws_read, added %zu payload, len=%zu", nread, n); - } - - DEBUGASSERT(!Curl_bufq_is_empty(&ws->sendbuf)); - *peos = FALSE; - result = Curl_bufq_cread(&ws->sendbuf, buf, blen, pnread); - if(!result && ctx->read_eos && Curl_bufq_is_empty(&ws->sendbuf)) { - /* no more data, read all, done. */ - ctx->eos = TRUE; - *peos = TRUE; - } - -out: - CURL_TRC_READ(data, "cr_ws_read(len=%zu) -> %d, nread=%zu, eos=%d", - blen, result, *pnread, *peos); - return result; -} - -static const struct Curl_crtype ws_cr_encode = { - "ws-encode", - cr_ws_init, - cr_ws_read, - cr_ws_close, - Curl_creader_def_needs_rewind, - Curl_creader_def_total_length, - Curl_creader_def_resume_from, - Curl_creader_def_cntrl, - Curl_creader_def_is_paused, - Curl_creader_def_done, - sizeof(struct cr_ws_ctx) -}; - -struct wsfield { - const char *name; - const char *val; -}; - -CURLcode Curl_ws_request(struct Curl_easy *data, struct dynbuf *req) -{ - unsigned int i; - CURLcode result = CURLE_OK; - uint8_t rand[16]; - char *randstr; - size_t randlen; - char keyval[40]; - struct SingleRequest *k = &data->req; - struct wsfield heads[] = { - { - /* The request MUST contain an |Upgrade| header field whose value - MUST include the "websocket" keyword. */ - "Upgrade", "websocket" - }, - { - /* The request MUST include a header field with the name - |Sec-WebSocket-Version|. The value of this header field MUST be - 13. */ - "Sec-WebSocket-Version", "13", - }, - { - /* The request MUST include a header field with the name - |Sec-WebSocket-Key|. The value of this header field MUST be a nonce - consisting of a randomly selected 16-byte value that has been - base64-encoded (see Section 4 of [RFC4648]). The nonce MUST be - selected randomly for each connection. */ - "Sec-WebSocket-Key", NULL, - } - }; - heads[2].val = &keyval[0]; - - /* 16 bytes random */ - result = Curl_rand(data, rand, sizeof(rand)); - if(result) - return result; - result = curlx_base64_encode(rand, sizeof(rand), &randstr, &randlen); - if(result) - return result; - DEBUGASSERT(randlen < sizeof(keyval)); - if(randlen >= sizeof(keyval)) { - curlx_free(randstr); - return CURLE_FAILED_INIT; - } - curlx_strcopy(keyval, sizeof(keyval), randstr, randlen); - curlx_free(randstr); - for(i = 0; !result && (i < CURL_ARRAYSIZE(heads)); i++) { - if(!Curl_checkheaders(data, heads[i].name, strlen(heads[i].name))) { - result = curlx_dyn_addf(req, "%s: %s\r\n", heads[i].name, heads[i].val); - } - } - data->state.http_hd_upgrade = TRUE; - k->upgr101 = UPGR101_WS; - data->conn->bits.upgrade_in_progress = TRUE; - return result; -} - -static void ws_conn_dtor(void *key, size_t klen, void *entry) -{ - struct websocket *ws = entry; - (void)key; - (void)klen; - Curl_bufq_free(&ws->recvbuf); - Curl_bufq_free(&ws->sendbuf); - curlx_free(ws); -} - -/* - * 'nread' is number of bytes of websocket data already in the buffer at - * 'mem'. - */ -CURLcode Curl_ws_accept(struct Curl_easy *data, - const char *mem, size_t nread) -{ - struct SingleRequest *k = &data->req; - struct websocket *ws; - struct Curl_cwriter *ws_dec_writer = NULL; - struct Curl_creader *ws_enc_reader = NULL; - CURLcode result; - - DEBUGASSERT(data->conn); - ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); - if(!ws) { - size_t chunk_size = WS_CHUNK_SIZE; - ws = curlx_calloc(1, sizeof(*ws)); - if(!ws) - return CURLE_OUT_OF_MEMORY; -#ifdef DEBUGBUILD - { - const char *p = getenv("CURL_WS_CHUNK_SIZE"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, 1 * 1024 * 1024)) - chunk_size = (size_t)l; - } - } -#endif - CURL_TRC_WS(data, "WS, using chunk size %zu", chunk_size); - Curl_bufq_init2(&ws->recvbuf, chunk_size, WS_CHUNK_COUNT, - BUFQ_OPT_SOFT_LIMIT); - Curl_bufq_init2(&ws->sendbuf, chunk_size, WS_CHUNK_COUNT, - BUFQ_OPT_SOFT_LIMIT); - ws_dec_init(&ws->dec); - ws_enc_init(&ws->enc); - result = Curl_conn_meta_set(data->conn, CURL_META_PROTO_WS_CONN, - ws, ws_conn_dtor); - if(result) - return result; - } - else { - Curl_bufq_reset(&ws->recvbuf); - ws_dec_reset(&ws->dec); - ws_enc_reset(&ws->enc); - } - /* Verify the Sec-WebSocket-Accept response. - - The sent value is the base64 encoded version of a SHA-1 hash done on the - |Sec-WebSocket-Key| header field concatenated with - the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11". - */ - - /* If the response includes a |Sec-WebSocket-Extensions| header field and - this header field indicates the use of an extension that was not present - in the client's handshake (the server has indicated an extension not - requested by the client), the client MUST Fail the WebSocket Connection. - */ - - /* If the response includes a |Sec-WebSocket-Protocol| header field - and this header field indicates the use of a subprotocol that was - not present in the client's handshake (the server has indicated a - subprotocol not requested by the client), the client MUST Fail - the WebSocket Connection. */ - - infof(data, "[WS] Received 101, switch to WebSocket"); - - /* Install our client writer that decodes WS frames payload */ - result = Curl_cwriter_create(&ws_dec_writer, data, &ws_cw_decode, - CURL_CW_CONTENT_DECODE); - if(result) - goto out; - result = Curl_cwriter_add(data, ws_dec_writer); - if(result) - goto out; - ws_dec_writer = NULL; /* owned by transfer now */ - - k->header = FALSE; /* we will not get more response headers */ - - if(data->set.connect_only) { - size_t nwritten; - /* In CONNECT_ONLY setup, the payloads from `mem` need to be received - * when using `curl_ws_recv` later on after this transfer is already - * marked as DONE. */ - result = Curl_bufq_write(&ws->recvbuf, (const uint8_t *)mem, - nread, &nwritten); - if(result) - goto out; - DEBUGASSERT(nread == nwritten); - CURL_REQ_CLEAR_RECV(data); /* read no more content */ - } - else { /* !connect_only */ - if(data->set.method == HTTPREQ_PUT) { - CURL_TRC_WS(data, "UPLOAD set, add ws-encode reader"); - result = Curl_creader_set_fread(data, -1); - if(result) - goto out; - - if(!data->set.ws_raw_mode) { - /* Add our client reader encoding WS BINARY frames */ - result = Curl_creader_create(&ws_enc_reader, data, &ws_cr_encode, - CURL_CR_CONTENT_ENCODE); - if(result) - goto out; - result = Curl_creader_add(data, ws_enc_reader); - if(result) - goto out; - ws_enc_reader = NULL; /* owned by transfer now */ - } - - /* start over with sending */ - data->req.eos_read = FALSE; - data->req.upload_done = FALSE; - CURL_REQ_SET_SEND(data); - } - - /* Then pass any additional data to the writers */ - if(nread) { - result = Curl_client_write(data, CLIENTWRITE_BODY, mem, nread); - if(result) - goto out; - } - } - - k->upgr101 = UPGR101_RECEIVED; - k->header = FALSE; /* we will not get more responses */ - -out: - if(ws_dec_writer) - Curl_cwriter_free(data, ws_dec_writer); - if(ws_enc_reader) - Curl_creader_free(data, ws_enc_reader); - if(result) - CURL_TRC_WS(data, "Curl_ws_accept() failed -> %d", result); - else - CURL_TRC_WS(data, "websocket established, %s mode", - data->set.connect_only ? "connect-only" : "callback"); - return result; -} - -struct ws_collect { - struct Curl_easy *data; - struct websocket *ws; - uint8_t *buffer; - size_t buflen; - size_t bufidx; - int frame_age; - int frame_flags; - curl_off_t payload_offset; - curl_off_t payload_len; - bool written; -}; - -static CURLcode ws_client_collect(const uint8_t *buf, size_t buflen, - int frame_age, int frame_flags, - curl_off_t payload_offset, - curl_off_t payload_len, - void *userp, - size_t *pnwritten) -{ - struct ws_collect *ctx = userp; - struct Curl_easy *data = ctx->data; - bool auto_pong = !data->set.ws_no_auto_pong; - curl_off_t remain; - CURLcode result = CURLE_OK; - - *pnwritten = 0; - remain = ws_payload_remain(payload_len, payload_offset, buflen); - if(remain < 0) { - DEBUGASSERT(0); /* parameter mismatch */ - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - if(!ctx->bufidx) { - /* first write */ - ctx->frame_age = frame_age; - ctx->frame_flags = frame_flags; - ctx->payload_offset = payload_offset; - ctx->payload_len = payload_len; - } - - if(auto_pong && (frame_flags & CURLWS_PING) && !remain) { - /* auto-respond to PINGs, only works for single-frame payloads atm */ - CURL_TRC_WS(data, "auto PONG to [PING payload=%" FMT_OFF_T - "/%" FMT_OFF_T "]", payload_offset, payload_len); - /* send back the exact same content as a PONG */ - result = ws_enc_add_cntrl(ctx->data, ctx->ws, buf, buflen, CURLWS_PONG); - if(result) - return result; - *pnwritten = buflen; - } - else { - size_t write_len; - - ctx->written = TRUE; - DEBUGASSERT(ctx->buflen >= ctx->bufidx); - write_len = CURLMIN(buflen, ctx->buflen - ctx->bufidx); - if(!write_len) { - if(!buflen) /* 0 length write, we accept that */ - return CURLE_OK; - return CURLE_AGAIN; /* no more space */ - } - memcpy(ctx->buffer + ctx->bufidx, buf, write_len); - ctx->bufidx += write_len; - *pnwritten = write_len; - } - return result; -} - -static CURLcode nw_in_recv(void *reader_ctx, - uint8_t *buf, size_t buflen, - size_t *pnread) -{ - struct Curl_easy *data = reader_ctx; - return curl_easy_recv(data, buf, buflen, pnread); -} - -CURLcode curl_ws_recv(CURL *curl, void *buffer, - size_t buflen, size_t *recv, - const struct curl_ws_frame **metap) -{ - struct Curl_easy *data = curl; - struct connectdata *conn; - struct websocket *ws; - struct ws_collect ctx; - - *recv = 0; - *metap = NULL; - if(!GOOD_EASY_HANDLE(data) || (buflen && !buffer)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - conn = data->conn; - if(!conn) { - /* Unhappy hack with lifetimes of transfers and connection */ - if(!data->set.connect_only) { - failf(data, "[WS] CONNECT_ONLY is required"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - Curl_getconnectinfo(data, &conn); - if(!conn) { - failf(data, "[WS] connection not found"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - ws = Curl_conn_meta_get(conn, CURL_META_PROTO_WS_CONN); - if(!ws) { - failf(data, "[WS] connection is not setup for websocket"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - memset(&ctx, 0, sizeof(ctx)); - ctx.data = data; - ctx.ws = ws; - ctx.buffer = buffer; - ctx.buflen = buflen; - - while(1) { - CURLcode result; - - /* receive more when our buffer is empty */ - if(Curl_bufq_is_empty(&ws->recvbuf)) { - size_t n; - result = Curl_bufq_slurp(&ws->recvbuf, nw_in_recv, data, &n); - if(result) - return result; - else if(n == 0) { - /* connection closed */ - infof(data, "[WS] connection expectedly closed?"); - return CURLE_GOT_NOTHING; - } - CURL_TRC_WS(data, "curl_ws_recv, added %zu bytes from network", - Curl_bufq_len(&ws->recvbuf)); - } - - result = ws_dec_pass(&ws->dec, data, &ws->recvbuf, - ws_client_collect, &ctx); - if(result == CURLE_AGAIN) { - if(!ctx.written) { - ws_dec_info(&ws->dec, data, "need more input"); - continue; /* nothing written, try more input */ - } - break; - } - else if(result) { - return result; - } - else if(ctx.written) { - /* The decoded frame is passed back to our caller. - * There are frames like PING were we auto-respond to and - * that we do not return. For these `ctx.written` is not set. */ - break; - } - } - - /* update frame information to be passed back */ - update_meta(ws, ctx.frame_age, ctx.frame_flags, ctx.payload_offset, - ctx.payload_len, ctx.bufidx); - *metap = &ws->recvframe; - *recv = ws->recvframe.len; - CURL_TRC_WS(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %" - FMT_OFF_T ", %" FMT_OFF_T " left)", - buflen, *recv, ws->recvframe.offset, - ws->recvframe.bytesleft); - /* all's well, try to send any pending control. we do not know - * when the application will call `curl_ws_send()` again. */ - if(!data->set.ws_raw_mode && ws->pending.type) { - CURLcode r2 = ws_enc_add_pending(data, ws); - if(!r2) - (void)ws_flush(data, ws, Curl_is_in_callback(data)); - } - return CURLE_OK; -} - -static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws, - bool blocking) -{ - if(!Curl_bufq_is_empty(&ws->sendbuf)) { - CURLcode result; - const uint8_t *out; - size_t outlen, n; -#ifdef DEBUGBUILD - /* Simulate a blocking send after this chunk has been sent */ - bool eagain_next = FALSE; - size_t chunk_egain = 0; - const char *p = getenv("CURL_WS_CHUNK_EAGAIN"); - if(p) { - curl_off_t l; - if(!curlx_str_number(&p, &l, 1 * 1024 * 1024)) - chunk_egain = (size_t)l; - } -#endif - - while(Curl_bufq_peek(&ws->sendbuf, &out, &outlen)) { -#ifdef DEBUGBUILD - if(eagain_next) - return CURLE_AGAIN; - if(chunk_egain && (outlen > chunk_egain)) { - outlen = chunk_egain; - eagain_next = TRUE; - } -#endif - if(blocking) { - result = ws_send_raw_blocking(data, ws, (const char *)out, outlen); - n = result ? 0 : outlen; - } - else if(data->set.connect_only || Curl_is_in_callback(data)) - result = Curl_senddata(data, out, outlen, &n); - else { - result = Curl_xfer_send(data, out, outlen, FALSE, &n); - if(!result && !n && outlen) - result = CURLE_AGAIN; - } - - if(result == CURLE_AGAIN) { - CURL_TRC_WS(data, "flush EAGAIN, %zu bytes remain in buffer", - Curl_bufq_len(&ws->sendbuf)); - return result; - } - else if(result) { - failf(data, "[WS] flush, write error %d", result); - return result; - } - else { - CURL_TRC_WS(data, "flushed %zu bytes", n); - Curl_bufq_skip(&ws->sendbuf, n); - } - } - } - return CURLE_OK; -} - -static CURLcode ws_send_raw_blocking(struct Curl_easy *data, - struct websocket *ws, - const char *buffer, size_t buflen) -{ - CURLcode result = CURLE_OK; - size_t nwritten; - - if(!data) - return result; - - (void)ws; - while(buflen) { - result = Curl_xfer_send(data, buffer, buflen, FALSE, &nwritten); - if(result) - return result; - DEBUGASSERT(nwritten <= buflen); - buffer += nwritten; - buflen -= nwritten; - if(buflen) { - curl_socket_t sock = data->conn->sock[FIRSTSOCKET]; - timediff_t left_ms; - int ev; - - CURL_TRC_WS(data, "ws_send_raw_blocking() partial, %zu left to send", - buflen); - left_ms = Curl_timeleft_ms(data); - if(left_ms < 0) { - failf(data, "[WS] Timeout waiting for socket becoming writable"); - return CURLE_SEND_ERROR; - } - - /* POLLOUT socket */ - if(sock == CURL_SOCKET_BAD) - return CURLE_SEND_ERROR; - ev = SOCKET_WRITABLE(sock, left_ms ? left_ms : 500); - if(ev < 0) { - failf(data, "[WS] Error while waiting for socket becoming writable"); - return CURLE_SEND_ERROR; - } - } - } - return result; -} - -static CURLcode ws_send_raw(struct Curl_easy *data, const void *buffer, - size_t buflen, size_t *pnwritten) -{ - struct websocket *ws; - CURLcode result; - - ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); - if(!ws) { - failf(data, "[WS] Not a websocket transfer"); - return CURLE_SEND_ERROR; - } - if(!buflen) - return CURLE_OK; - - if(Curl_is_in_callback(data)) { - /* When invoked from inside callbacks, we do a blocking send as the - * callback will probably not implement partial writes that may then - * mess up the ws framing subsequently. - * We need any pending data to be flushed before sending. */ - result = ws_flush(data, ws, TRUE); - if(result) - return result; - result = ws_send_raw_blocking(data, ws, buffer, buflen); - if(!result) - *pnwritten = buflen; - } - else { - /* We need any pending data to be sent or EAGAIN this call. */ - result = ws_flush(data, ws, FALSE); - if(result) - return result; - result = Curl_senddata(data, buffer, buflen, pnwritten); - } - - CURL_TRC_WS(data, "ws_send_raw(len=%zu) -> %d, %zu", - buflen, result, *pnwritten); - return result; -} - -CURLcode curl_ws_send(CURL *curl, const void *buffer_arg, - size_t buflen, size_t *sent, - curl_off_t fragsize, - unsigned int flags) -{ - struct websocket *ws; - const uint8_t *buffer = buffer_arg; - CURLcode result = CURLE_OK; - struct Curl_easy *data = curl; - size_t ndummy; - size_t *pnsent = sent ? sent : &ndummy; - - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - CURL_TRC_WS(data, "curl_ws_send(len=%zu, fragsize=%" FMT_OFF_T - ", flags=%x), raw=%d", - buflen, fragsize, flags, data->set.ws_raw_mode); - - *pnsent = 0; - - if(!buffer && buflen) { - failf(data, "[WS] buffer is NULL when buflen is not"); - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto out; - } - - if(!data->conn && data->set.connect_only) { - result = Curl_connect_only_attach(data); - if(result) - goto out; - } - if(!data->conn) { - failf(data, "[WS] No associated connection"); - result = CURLE_SEND_ERROR; - goto out; - } - ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); - if(!ws) { - failf(data, "[WS] Not a websocket transfer"); - result = CURLE_SEND_ERROR; - goto out; - } - - if(data->set.ws_raw_mode) { - /* In raw mode, we write directly to the connection */ - /* try flushing any content still waiting to be sent. */ - result = ws_flush(data, ws, FALSE); - if(result) - goto out; - - if(!buffer) { - failf(data, "[WS] buffer is NULL in raw mode"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(!sent) { - failf(data, "[WS] sent is NULL in raw mode"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(fragsize || flags) { - failf(data, "[WS] fragsize and flags must be zero in raw mode"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - result = ws_send_raw(data, buffer, buflen, pnsent); - goto out; - } - - /* Not RAW mode, we do the frame encoding */ - result = ws_enc_send(data, ws, buffer, buflen, fragsize, flags, pnsent); - -out: - CURL_TRC_WS(data, "curl_ws_send(len=%zu, fragsize=%" FMT_OFF_T - ", flags=%x, raw=%d) -> %d, %zu", - buflen, fragsize, flags, data->set.ws_raw_mode, result, - *pnsent); - return result; -} - -static CURLcode ws_setup_conn(struct Curl_easy *data, - struct connectdata *conn) -{ - /* WebSocket is 1.1 only (for now) */ - data->state.http_neg.accept_09 = FALSE; - data->state.http_neg.only_10 = FALSE; - data->state.http_neg.wanted = CURL_HTTP_V1x; - data->state.http_neg.allowed = CURL_HTTP_V1x; - return Curl_http_setup_conn(data, conn); -} - -const struct curl_ws_frame *curl_ws_meta(CURL *curl) -{ - /* we only return something for websocket, called from within the callback - when not using raw mode */ - struct Curl_easy *data = curl; - if(GOOD_EASY_HANDLE(data) && Curl_is_in_callback(data) && - data->conn && !data->set.ws_raw_mode) { - struct websocket *ws; - ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); - if(ws) - return &ws->recvframe; - } - return NULL; -} - -CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl, - unsigned int flags, - curl_off_t frame_len) -{ - struct websocket *ws; - CURLcode result = CURLE_OK; - struct Curl_easy *data = curl; - - if(!GOOD_EASY_HANDLE(data)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(data->set.ws_raw_mode) { - failf(data, "cannot curl_ws_start_frame() with CURLWS_RAW_MODE enabled"); - return CURLE_FAILED_INIT; - } - - CURL_TRC_WS(data, "curl_ws_start_frame(flags=%x, frame_len=%" FMT_OFF_T, - flags, frame_len); - - if(!data->conn) { - failf(data, "[WS] No associated connection"); - result = CURLE_SEND_ERROR; - goto out; - } - ws = Curl_conn_meta_get(data->conn, CURL_META_PROTO_WS_CONN); - if(!ws) { - failf(data, "[WS] Not a websocket transfer"); - result = CURLE_SEND_ERROR; - goto out; - } - - if(ws->enc.payload_remain) { - failf(data, "[WS] previous frame not finished"); - result = CURLE_SEND_ERROR; - goto out; - } - - result = ws_enc_write_head(data, ws, &ws->enc, flags, frame_len, - &ws->sendbuf); - if(result) - CURL_TRC_WS(data, "curl_start_frame(), error adding frame head %d", - result); - -out: - return result; -} - -const struct Curl_protocol Curl_protocol_ws = { - ws_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_pollset */ - Curl_http_doing_pollset, /* doing_pollset */ - ZERO_NULL, /* domore_pollset */ - Curl_http_perform_pollset, /* perform_pollset */ - ZERO_NULL, /* disconnect */ - Curl_http_write_resp, /* write_resp */ - Curl_http_write_resp_hd, /* write_resp_hd */ - ZERO_NULL, /* connection_is_dead */ - ZERO_NULL, /* attach connection */ - Curl_http_follow, /* follow */ -}; - -#else - -CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, - size_t *recv, - const struct curl_ws_frame **metap) -{ - (void)curl; - (void)buffer; - (void)buflen; - (void)recv; - (void)metap; - return CURLE_NOT_BUILT_IN; -} - -CURLcode curl_ws_send(CURL *curl, const void *buffer, - size_t buflen, size_t *sent, - curl_off_t fragsize, - unsigned int flags) -{ - (void)curl; - (void)buffer; - (void)buflen; - (void)sent; - (void)fragsize; - (void)flags; - return CURLE_NOT_BUILT_IN; -} - -const struct curl_ws_frame *curl_ws_meta(CURL *data) -{ - (void)data; - return NULL; -} - -CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl, - unsigned int flags, - curl_off_t frame_len) -{ - (void)curl; - (void)flags; - (void)frame_len; - return CURLE_NOT_BUILT_IN; -} - -#endif /* !CURL_DISABLE_WEBSOCKETS */ diff --git a/vendor/curl/lib/ws.h b/vendor/curl/lib/ws.h deleted file mode 100644 index 71b5b3fff..000000000 --- a/vendor/curl/lib/ws.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef HEADER_CURL_WS_H -#define HEADER_CURL_WS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) - -extern const struct Curl_protocol Curl_protocol_ws; - -/* meta key for storing protocol meta at connection */ -#define CURL_META_PROTO_WS_CONN "meta:proto:ws:conn" - -CURLcode Curl_ws_request(struct Curl_easy *data, struct dynbuf *req); -CURLcode Curl_ws_accept(struct Curl_easy *data, - const char *mem, size_t nread); - -#else -#define Curl_ws_request(x, y) CURLE_OK -#define Curl_ws_free(x) Curl_nop_stmt -#endif - -#endif /* HEADER_CURL_WS_H */ diff --git a/vendor/libpsl.mask b/vendor/libpsl.mask deleted file mode 100644 index c33892277..000000000 --- a/vendor/libpsl.mask +++ /dev/null @@ -1,44 +0,0 @@ -.circleci -.dir-locals.el -.gitattributes -.github -.gitlab-ci.yml -.gtm-ci.yml -.lgtm.yml -AUTHORS -autogen.sh -configure.ac -contrib -docs -fuzz -include/Makefile.am -include/meson.build -libpsl.pc.in -libtool_version_info.txt -list/.github -list/.gitignore -list/.travis.yml -list/CONTRIBUTING.md -list/linter -list/Makefile -list/README.md -list/tests -list/tools -m4 -Makefile.am -meson_options.txt -meson.build -msvc -NEWS -po -README -README.md -README.MSVC.md -src/libpsl-srcs.mk -src/LICENSE.chromium -src/Makefile.am -src/meson.build -src/psl-make-dafsa -src/psl-make-dafsa.1 -tests -tools diff --git a/vendor/libpsl/COPYING b/vendor/libpsl/COPYING deleted file mode 100644 index 85945e764..000000000 --- a/vendor/libpsl/COPYING +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2014-2024 Tim Rühsen - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/vendor/libpsl/LICENSE b/vendor/libpsl/LICENSE deleted file mode 100644 index 85945e764..000000000 --- a/vendor/libpsl/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2014-2024 Tim Rühsen - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/vendor/libpsl/include/libpsl.h.in b/vendor/libpsl/include/libpsl.h.in deleted file mode 100644 index 0ae1fafab..000000000 --- a/vendor/libpsl/include/libpsl.h.in +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright(c) 2014-2024 Tim Ruehsen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of libpsl. - * - * Header file for libpsl library routines - * - * Changelog - * 20.03.2014 Tim Ruehsen created - * - */ - -#ifndef LIBPSL_LIBPSL_H -#define LIBPSL_LIBPSL_H - -#include -#include - -#define PSL_VERSION "@LIBPSL_VERSION@" -#define PSL_VERSION_MAJOR @LIBPSL_VERSION_MAJOR@ -#define PSL_VERSION_MINOR @LIBPSL_VERSION_MINOR@ -#define PSL_VERSION_PATCH @LIBPSL_VERSION_PATCH@ -#define PSL_VERSION_NUMBER @LIBPSL_VERSION_NUMBER@ - -/* support clang's __has_declspec_attribute attribute */ -#ifndef __has_declspec_attribute -# define __has_declspec_attribute(x) 0 -#endif - -#ifndef PSL_API -#if defined BUILDING_PSL && HAVE_VISIBILITY -# define PSL_API __attribute__ ((__visibility__("default"))) -#elif defined BUILDING_PSL && (defined _MSC_VER || __has_declspec_attribute(dllexport)) && !defined PSL_STATIC -# define PSL_API __declspec(dllexport) -#elif (defined _MSC_VER || __has_declspec_attribute(dllimport)) && !defined PSL_STATIC -# define PSL_API __declspec(dllimport) -#else -# define PSL_API -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* types for psl_is_public_suffix2() */ -#define PSL_TYPE_ICANN (1<<0) -#define PSL_TYPE_PRIVATE (1<<1) -#define PSL_TYPE_NO_STAR_RULE (1<<2) -#define PSL_TYPE_ANY (PSL_TYPE_ICANN | PSL_TYPE_PRIVATE) - -/** - * psl_error_t: - * @PSL_SUCCESS: Successful return. - * @PSL_ERR_INVALID_ARG: Invalid argument. - * @PSL_ERR_CONVERTER: Failed to open libicu utf-16 converter. - * @PSL_ERR_TO_UTF16: Failed to convert to utf-16. - * @PSL_ERR_TO_LOWER: Failed to convert utf-16 to lowercase. - * @PSL_ERR_TO_UTF8: Failed to convert utf-16 to utf-8. - * @PSL_ERR_NO_MEM: Failed to allocate memory. - * - * Return codes for PSL functions. - * Negative return codes mean failure. - * Positive values are reserved for non-error return codes. - */ -typedef enum { - PSL_SUCCESS = 0, - PSL_ERR_INVALID_ARG = -1, - PSL_ERR_CONVERTER = -2, /* failed to open libicu utf-16 converter */ - PSL_ERR_TO_UTF16 = -3, /* failed to convert to utf-16 */ - PSL_ERR_TO_LOWER = -4, /* failed to convert utf-16 to lowercase */ - PSL_ERR_TO_UTF8 = -5, /* failed to convert utf-16 to utf-8 */ - PSL_ERR_NO_MEM = -6 /* failed to allocate memory */ -} psl_error_t; - -typedef struct psl_ctx_st psl_ctx_t; - -/* frees PSL context */ -PSL_API -void - psl_free(psl_ctx_t *psl); - -/* frees memory allocated by libpsl routines */ -PSL_API -void - psl_free_string(char *str); - -/* loads PSL data from file */ -PSL_API -psl_ctx_t * - psl_load_file(const char *fname); - -/* loads PSL data from FILE pointer */ -PSL_API -psl_ctx_t * - psl_load_fp(FILE *fp); - -/* retrieves builtin PSL data */ -PSL_API -const psl_ctx_t * - psl_builtin(void); - -/* retrieves most recent PSL data */ -PSL_API -psl_ctx_t * - psl_latest(const char *fname); - -/* checks whether domain is a public suffix or not */ -PSL_API -int - psl_is_public_suffix(const psl_ctx_t *psl, const char *domain); - -/* checks whether domain is a public suffix regarding the type or not */ -PSL_API -int - psl_is_public_suffix2(const psl_ctx_t *psl, const char *domain, int type); - -/* checks whether cookie_domain is acceptable for domain or not */ -PSL_API -int - psl_is_cookie_domain_acceptable(const psl_ctx_t *psl, const char *hostname, const char *cookie_domain); - -/* returns the longest not registrable domain within 'domain' or NULL if none found */ -PSL_API -const char * - psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain); - -/* returns the shortest possible registrable domain part or NULL if domain is not registrable at all */ -PSL_API -const char * - psl_registrable_domain(const psl_ctx_t *psl, const char *domain); - -/* convert a string into lowercase UTF-8 */ -PSL_API -psl_error_t - psl_str_to_utf8lower(const char *str, const char *encoding, const char *locale, char **lower); - -/* does not include exceptions */ -PSL_API -int - psl_suffix_count(const psl_ctx_t *psl); - -/* just counts exceptions */ -PSL_API -int - psl_suffix_exception_count(const psl_ctx_t *psl); - -/* just counts wildcards */ -PSL_API -int - psl_suffix_wildcard_count(const psl_ctx_t *psl); - -/* returns mtime of PSL source file */ -PSL_API -time_t - psl_builtin_file_time(void); - -/* returns SHA1 checksum (hex-encoded, lowercase) of PSL source file */ -PSL_API -const char * - psl_builtin_sha1sum(void); - -/* returns file name of PSL source file */ -PSL_API -const char * - psl_builtin_filename(void); - -/* returns name of distribution PSL data file */ -PSL_API -const char * - psl_dist_filename(void); - -/* returns library version string */ -PSL_API -const char * - psl_get_version(void); - -/* checks library version number */ -PSL_API -int - psl_check_version_number(int version); - -/* returns whether the built-in data is outdated or not */ -PSL_API -int - psl_builtin_outdated(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LIBPSL_LIBPSL_H */ diff --git a/vendor/libpsl/list/CODE_OF_CONDUCT.md b/vendor/libpsl/list/CODE_OF_CONDUCT.md deleted file mode 100644 index 9e15175dd..000000000 --- a/vendor/libpsl/list/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,2 +0,0 @@ -### Community Participation Guidelines -Your participation in the Public Suffix List project should follow the [Mozilla Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/ "Mozilla Community Participation Guidelines") as well as the [GitHub Community Participation Guidelines](https://help.github.com/en/github/site-policy/github-community-guidelines "GitHub Community Participation Guidelines"). Behavior that falls into the areas forbidden by either document is unwelcome and will result in further escalation. diff --git a/vendor/libpsl/list/LICENSE b/vendor/libpsl/list/LICENSE deleted file mode 100644 index ee6256cdb..000000000 --- a/vendor/libpsl/list/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at https://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/libpsl/list/SECURITY.md b/vendor/libpsl/list/SECURITY.md deleted file mode 100644 index eb0b7f5c6..000000000 --- a/vendor/libpsl/list/SECURITY.md +++ /dev/null @@ -1,13 +0,0 @@ -# Security Policy - -Security updates are applied only to the repository itself. - -## Reporting a Vulnerability - -Reports are limited to repo matters. Any vulnerability reports related to the addition or removal of PSL entries in the .dat file shall be rejected and referred to filing pull requests that should make mention the alleged urgency. - -If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. - -Please disclose it at [security advisory](https://github.com/publicsuffix/list/security/advisories/new) and send an email with the link to the newly filed issue to [security@mozilla.org](mailto:security@mozilla.org) to expedite the review on our end. - -This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure. diff --git a/vendor/libpsl/list/public_suffix_list.dat b/vendor/libpsl/list/public_suffix_list.dat deleted file mode 100644 index 43673cec7..000000000 --- a/vendor/libpsl/list/public_suffix_list.dat +++ /dev/null @@ -1,16139 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, -// rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. - -// Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. - -// ===BEGIN ICANN DOMAINS=== - -// ac : http://nic.ac/rules.htm -ac -com.ac -edu.ac -gov.ac -mil.ac -net.ac -org.ac - -// ad : https://www.iana.org/domains/root/db/ad.html -// Confirmed by Amadeu Abril i Abril (CORE) 2024-11-17 -ad - -// ae : https://www.iana.org/domains/root/db/ae.html -ae -ac.ae -co.ae -gov.ae -mil.ae -net.ae -org.ae -sch.ae - -// aero : https://information.aero/registration/policies/dmp -aero -// 2LDs -airline.aero -airport.aero -// 2LDs (currently not accepting registration, seemingly never have) -// As of 2024-07, these are marked as reserved for potential 3LD -// registrations (clause 11 "allocated subdomains" in the 2006 TLD -// policy), but the relevant industry partners have not opened them up -// for registration. Current status can be determined from the TLD's -// policy document: 2LDs that are open for registration must list -// their policy in the TLD's policy. Any 2LD without such a policy is -// not open for registrations. -accident-investigation.aero -accident-prevention.aero -aerobatic.aero -aeroclub.aero -aerodrome.aero -agents.aero -air-surveillance.aero -air-traffic-control.aero -aircraft.aero -airtraffic.aero -ambulance.aero -association.aero -author.aero -ballooning.aero -broker.aero -caa.aero -cargo.aero -catering.aero -certification.aero -championship.aero -charter.aero -civilaviation.aero -club.aero -conference.aero -consultant.aero -consulting.aero -control.aero -council.aero -crew.aero -design.aero -dgca.aero -educator.aero -emergency.aero -engine.aero -engineer.aero -entertainment.aero -equipment.aero -exchange.aero -express.aero -federation.aero -flight.aero -freight.aero -fuel.aero -gliding.aero -government.aero -groundhandling.aero -group.aero -hanggliding.aero -homebuilt.aero -insurance.aero -journal.aero -journalist.aero -leasing.aero -logistics.aero -magazine.aero -maintenance.aero -marketplace.aero -media.aero -microlight.aero -modelling.aero -navigation.aero -parachuting.aero -paragliding.aero -passenger-association.aero -pilot.aero -press.aero -production.aero -recreation.aero -repbody.aero -res.aero -research.aero -rotorcraft.aero -safety.aero -scientist.aero -services.aero -show.aero -skydiving.aero -software.aero -student.aero -taxi.aero -trader.aero -trading.aero -trainer.aero -union.aero -workinggroup.aero -works.aero - -// af : https://www.nic.af/domain-price -af -com.af -edu.af -gov.af -net.af -org.af - -// ag : http://www.nic.ag/prices.htm -ag -co.ag -com.ag -net.ag -nom.ag -org.ag - -// ai : http://nic.com.ai/ -ai -com.ai -net.ai -off.ai -org.ai - -// al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31 -al -com.al -edu.al -gov.al -mil.al -net.al -org.al - -// am : https://www.amnic.net/policy/en/Policy_EN.pdf -// Confirmed by ISOC AM 2024-11-18 -am -co.am -com.am -commune.am -net.am -org.am - -// ao : https://www.iana.org/domains/root/db/ao.html -// https://www.dns.ao/ao/ -ao -co.ao -ed.ao -edu.ao -gov.ao -gv.ao -it.ao -og.ao -org.ao -pb.ao - -// aq : https://www.iana.org/domains/root/db/aq.html -aq - -// ar : https://nic.ar/es/nic-argentina/normativa -ar -bet.ar -com.ar -coop.ar -edu.ar -gob.ar -gov.ar -int.ar -mil.ar -musica.ar -mutual.ar -net.ar -org.ar -seg.ar -senasa.ar -tur.ar - -// arpa : https://www.iana.org/domains/root/db/arpa.html -// Confirmed by registry 2008-06-18 -arpa -e164.arpa -home.arpa -in-addr.arpa -ip6.arpa -iris.arpa -uri.arpa -urn.arpa - -// as : https://www.iana.org/domains/root/db/as.html -as -gov.as - -// asia : https://www.iana.org/domains/root/db/asia.html -asia - -// at : https://www.iana.org/domains/root/db/at.html -// Confirmed by registry 2008-06-17 -at -ac.at -sth.ac.at -co.at -gv.at -or.at - -// au : https://www.iana.org/domains/root/db/au.html -// https://www.auda.org.au/ -// Confirmed by registry 2025-07-16 -au -// 2LDs -asn.au -com.au -edu.au -gov.au -id.au -net.au -org.au -// Historic 2LDs (closed to new registration, but sites still exist) -conf.au -oz.au -// CGDNs : https://www.auda.org.au/au-domain-names/the-different-au-domain-names/state-and-territory-domain-names/ -act.au -nsw.au -nt.au -qld.au -sa.au -tas.au -vic.au -wa.au -// 3LDs -act.edu.au -catholic.edu.au -// eq.edu.au - Removed at the request of the Queensland Department of Education -nsw.edu.au -nt.edu.au -qld.edu.au -sa.edu.au -tas.edu.au -vic.edu.au -wa.edu.au -// act.gov.au - Bug 984824 - Removed at request of Greg Tankard -// nsw.gov.au - Bug 547985 - Removed at request of -// nt.gov.au - Bug 940478 - Removed at request of Greg Connors -qld.gov.au -sa.gov.au -tas.gov.au -vic.gov.au -wa.gov.au -// 4LDs -// education.tas.edu.au - Removed at the request of the Department of Education Tasmania -// schools.nsw.edu.au - Removed at the request of the New South Wales Department of Education. - -// aw : https://www.iana.org/domains/root/db/aw.html -aw -com.aw - -// ax : https://www.iana.org/domains/root/db/ax.html -ax - -// az : https://www.iana.org/domains/root/db/az.html -// Confirmed via https://whois.az/?page_id=10 2024-12-11 -az -biz.az -co.az -com.az -edu.az -gov.az -info.az -int.az -mil.az -name.az -net.az -org.az -pp.az -// No longer available for registration, however domains exist as of 2024-12-11 -// see https://whois.az/?page_id=783 -pro.az - -// ba : https://www.iana.org/domains/root/db/ba.html -ba -com.ba -edu.ba -gov.ba -mil.ba -net.ba -org.ba - -// bb : https://www.iana.org/domains/root/db/bb.html -bb -biz.bb -co.bb -com.bb -edu.bb -gov.bb -info.bb -net.bb -org.bb -store.bb -tv.bb - -// bd : https://www.iana.org/domains/root/db/bd.html -// Confirmed by registry -bd -ac.bd -ai.bd -co.bd -com.bd -edu.bd -gov.bd -id.bd -info.bd -it.bd -mil.bd -net.bd -org.bd -sch.bd -tv.bd - -// be : https://www.iana.org/domains/root/db/be.html -// Confirmed by registry 2008-06-08 -be -ac.be - -// bf : https://www.iana.org/domains/root/db/bf.html -bf -gov.bf - -// bg : https://www.iana.org/domains/root/db/bg.html -// https://www.register.bg/user/static/rules/en/index.html -bg -0.bg -1.bg -2.bg -3.bg -4.bg -5.bg -6.bg -7.bg -8.bg -9.bg -a.bg -b.bg -c.bg -d.bg -e.bg -f.bg -g.bg -h.bg -i.bg -j.bg -k.bg -l.bg -m.bg -n.bg -o.bg -p.bg -q.bg -r.bg -s.bg -t.bg -u.bg -v.bg -w.bg -x.bg -y.bg -z.bg - -// bh : https://www.iana.org/domains/root/db/bh.html -bh -com.bh -edu.bh -gov.bh -net.bh -org.bh - -// bi : https://www.iana.org/domains/root/db/bi.html -// http://whois.nic.bi/ -bi -co.bi -com.bi -edu.bi -or.bi -org.bi - -// biz : https://www.iana.org/domains/root/db/biz.html -biz - -// bj : https://nic.bj/bj-suffixes.txt -// Submitted by registry -bj -africa.bj -agro.bj -architectes.bj -assur.bj -avocats.bj -co.bj -com.bj -eco.bj -econo.bj -edu.bj -info.bj -loisirs.bj -money.bj -net.bj -org.bj -ote.bj -restaurant.bj -resto.bj -tourism.bj -univ.bj - -// bm : https://www.bermudanic.bm/domain-registration/index.php -bm -com.bm -edu.bm -gov.bm -net.bm -org.bm - -// bn : http://www.bnnic.bn/faqs -bn -com.bn -edu.bn -gov.bn -net.bn -org.bn - -// bo : https://nic.bo -// Confirmed by registry 2024-11-19 -bo -com.bo -edu.bo -gob.bo -int.bo -mil.bo -net.bo -org.bo -tv.bo -web.bo -// Social Domains -academia.bo -agro.bo -arte.bo -blog.bo -bolivia.bo -ciencia.bo -cooperativa.bo -democracia.bo -deporte.bo -ecologia.bo -economia.bo -empresa.bo -indigena.bo -industria.bo -info.bo -medicina.bo -movimiento.bo -musica.bo -natural.bo -nombre.bo -noticias.bo -patria.bo -plurinacional.bo -politica.bo -profesional.bo -pueblo.bo -revista.bo -salud.bo -tecnologia.bo -tksat.bo -transporte.bo -wiki.bo - -// br : http://registro.br/dominio/categoria.html -// Submitted by registry -br -9guacu.br -abc.br -adm.br -adv.br -agr.br -aju.br -am.br -anani.br -aparecida.br -api.br -app.br -arq.br -art.br -ato.br -b.br -barueri.br -belem.br -bet.br -bhz.br -bib.br -bio.br -blog.br -bmd.br -boavista.br -bsb.br -campinagrande.br -campinas.br -caxias.br -cim.br -cng.br -cnt.br -com.br -contagem.br -coop.br -coz.br -cri.br -cuiaba.br -curitiba.br -def.br -des.br -det.br -dev.br -ecn.br -eco.br -edu.br -emp.br -enf.br -eng.br -esp.br -etc.br -eti.br -far.br -feira.br -flog.br -floripa.br -fm.br -fnd.br -fortal.br -fot.br -foz.br -fst.br -g12.br -geo.br -ggf.br -goiania.br -gov.br -// gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil -ac.gov.br -al.gov.br -am.gov.br -ap.gov.br -ba.gov.br -ce.gov.br -df.gov.br -es.gov.br -go.gov.br -ma.gov.br -mg.gov.br -ms.gov.br -mt.gov.br -pa.gov.br -pb.gov.br -pe.gov.br -pi.gov.br -pr.gov.br -rj.gov.br -rn.gov.br -ro.gov.br -rr.gov.br -rs.gov.br -sc.gov.br -se.gov.br -sp.gov.br -to.gov.br -gru.br -ia.br -imb.br -ind.br -inf.br -jab.br -jampa.br -jdf.br -joinville.br -jor.br -jus.br -leg.br -leilao.br -lel.br -log.br -londrina.br -macapa.br -maceio.br -manaus.br -maringa.br -mat.br -med.br -mil.br -morena.br -mp.br -mus.br -natal.br -net.br -niteroi.br -*.nom.br -not.br -ntr.br -odo.br -ong.br -org.br -osasco.br -palmas.br -poa.br -ppg.br -pro.br -psc.br -psi.br -pvh.br -qsl.br -radio.br -rec.br -recife.br -rep.br -ribeirao.br -rio.br -riobranco.br -riopreto.br -salvador.br -sampa.br -santamaria.br -santoandre.br -saobernardo.br -saogonca.br -seg.br -sjc.br -slg.br -slz.br -social.br -sorocaba.br -srv.br -taxi.br -tc.br -tec.br -teo.br -the.br -tmp.br -trd.br -tur.br -tv.br -udi.br -vet.br -vix.br -vlog.br -wiki.br -xyz.br -zlg.br - -// bs : http://www.nic.bs/rules.html -bs -com.bs -edu.bs -gov.bs -net.bs -org.bs - -// bt : https://www.iana.org/domains/root/db/bt.html -bt -com.bt -edu.bt -gov.bt -net.bt -org.bt - -// bv : No registrations at this time. -// Submitted by registry -bv - -// bw : https://www.iana.org/domains/root/db/bw.html -// https://nic.net.bw/bw-name-structure -bw -ac.bw -co.bw -gov.bw -net.bw -org.bw - -// by : https://www.iana.org/domains/root/db/by.html -// http://tld.by/rules_2006_en.html -// list of other 2nd level tlds ? -by -gov.by -mil.by -// Official information does not indicate that com.by is a reserved -// second-level domain, but it's being used as one (see www.google.com.by and -// www.yahoo.com.by, for example), so we list it here for safety's sake. -com.by -// http://hoster.by/ -of.by - -// bz : https://www.iana.org/domains/root/db/bz.html -// http://www.belizenic.bz/ -bz -co.bz -com.bz -edu.bz -gov.bz -net.bz -org.bz - -// ca : https://www.iana.org/domains/root/db/ca.html -ca -// ca geographical names -ab.ca -bc.ca -mb.ca -nb.ca -nf.ca -nl.ca -ns.ca -nt.ca -nu.ca -on.ca -pe.ca -qc.ca -sk.ca -yk.ca -// gc.ca: https://en.wikipedia.org/wiki/.gc.ca -// see also: http://registry.gc.ca/en/SubdomainFAQ -gc.ca - -// cat : https://www.iana.org/domains/root/db/cat.html -cat - -// cc : https://www.iana.org/domains/root/db/cc.html -cc - -// cd : https://www.iana.org/domains/root/db/cd.html -// https://www.nic.cd -cd -gov.cd - -// cf : https://www.iana.org/domains/root/db/cf.html -cf - -// cg : https://www.iana.org/domains/root/db/cg.html -cg - -// ch : https://www.iana.org/domains/root/db/ch.html -ch - -// ci : https://www.iana.org/domains/root/db/ci.html -ci -ac.ci -aéroport.ci -asso.ci -co.ci -com.ci -ed.ci -edu.ci -go.ci -gouv.ci -int.ci -net.ci -or.ci -org.ci - -// ck : https://www.iana.org/domains/root/db/ck.html -*.ck -!www.ck - -// cl : https://www.nic.cl -// Confirmed by .CL registry -cl -co.cl -gob.cl -gov.cl -mil.cl - -// cm : https://www.iana.org/domains/root/db/cm.html plus bug 981927 -cm -co.cm -com.cm -gov.cm -net.cm - -// cn : https://www.iana.org/domains/root/db/cn.html -// Submitted by registry -cn -ac.cn -com.cn -edu.cn -gov.cn -mil.cn -net.cn -org.cn -公司.cn -網絡.cn -网络.cn -// cn geographic names -ah.cn -bj.cn -cq.cn -fj.cn -gd.cn -gs.cn -gx.cn -gz.cn -ha.cn -hb.cn -he.cn -hi.cn -hk.cn -hl.cn -hn.cn -jl.cn -js.cn -jx.cn -ln.cn -mo.cn -nm.cn -nx.cn -qh.cn -sc.cn -sd.cn -sh.cn -sn.cn -sx.cn -tj.cn -tw.cn -xj.cn -xz.cn -yn.cn -zj.cn - -// co : https://www.iana.org/domains/root/db/co.html -// https://www.cointernet.com.co/como-funciona-un-dominio-restringido -// Confirmed by registry 2024-11-18 -co -com.co -edu.co -gov.co -mil.co -net.co -nom.co -org.co - -// com : https://www.iana.org/domains/root/db/com.html -com - -// coop : https://www.iana.org/domains/root/db/coop.html -coop - -// cr : https://nic.cr/capitulo-1-registro-de-un-nombre-de-dominio/ -cr -ac.cr -co.cr -ed.cr -fi.cr -go.cr -or.cr -sa.cr - -// cu : https://www.iana.org/domains/root/db/cu.html -cu -com.cu -edu.cu -gob.cu -inf.cu -nat.cu -net.cu -org.cu - -// cv : https://www.iana.org/domains/root/db/cv.html -// https://ola.cv/domain-extensions-under-cv/ -// Confirmed by registry 2024-11-26 -cv -com.cv -edu.cv -id.cv -int.cv -net.cv -nome.cv -org.cv -publ.cv - -// cw : https://www.uoc.cw/cw-registry -// Confirmed by registry 2024-11-19 -cw -com.cw -edu.cw -net.cw -org.cw - -// cx : https://www.iana.org/domains/root/db/cx.html -// list of other 2nd level tlds ? -cx -gov.cx - -// cy : http://www.nic.cy/ -// Submitted by Panayiotou Fotia -// https://nic.cy/wp-content/uploads/2024/01/Create-Request-for-domain-name-registration-1.pdf -cy -ac.cy -biz.cy -com.cy -ekloges.cy -gov.cy -ltd.cy -mil.cy -net.cy -org.cy -press.cy -pro.cy -tm.cy - -// cz : https://www.iana.org/domains/root/db/cz.html -// Confirmed by registry 2025-08-06 -cz -gov.cz - -// de : https://www.iana.org/domains/root/db/de.html -// Confirmed by registry (with technical -// reservations) 2008-07-01 -de - -// dj : https://www.iana.org/domains/root/db/dj.html -dj - -// dk : https://www.iana.org/domains/root/db/dk.html -// Confirmed by registry 2008-06-17 -dk - -// dm : https://www.iana.org/domains/root/db/dm.html -// https://nic.dm/policies/pdf/DMRulesandGuidelines2024v1.pdf -// Confirmed by registry 2024-11-19 -dm -co.dm -com.dm -edu.dm -gov.dm -net.dm -org.dm - -// do : https://www.iana.org/domains/root/db/do.html -do -art.do -com.do -edu.do -gob.do -gov.do -mil.do -net.do -org.do -sld.do -web.do - -// dz : http://www.nic.dz/images/pdf_nic/charte.pdf -dz -art.dz -asso.dz -com.dz -edu.dz -gov.dz -net.dz -org.dz -pol.dz -soc.dz -tm.dz - -// ec : https://www.nic.ec/ -// Submitted by registry -ec -abg.ec -adm.ec -agron.ec -arqt.ec -art.ec -bar.ec -chef.ec -com.ec -cont.ec -cpa.ec -cue.ec -dent.ec -dgn.ec -disco.ec -doc.ec -edu.ec -eng.ec -esm.ec -fin.ec -fot.ec -gal.ec -gob.ec -gov.ec -gye.ec -ibr.ec -info.ec -k12.ec -lat.ec -loj.ec -med.ec -mil.ec -mktg.ec -mon.ec -net.ec -ntr.ec -odont.ec -org.ec -pro.ec -prof.ec -psic.ec -psiq.ec -pub.ec -rio.ec -rrpp.ec -sal.ec -tech.ec -tul.ec -tur.ec -uio.ec -vet.ec -xxx.ec - -// edu : https://www.iana.org/domains/root/db/edu.html -edu - -// ee : https://www.internet.ee/domains/general-domains-and-procedure-for-registration-of-sub-domains-under-general-domains -ee -aip.ee -com.ee -edu.ee -fie.ee -gov.ee -lib.ee -med.ee -org.ee -pri.ee -riik.ee - -// eg : https://www.iana.org/domains/root/db/eg.html -// https://domain.eg/en/domain-rules/subdomain-names-types/ -eg -ac.eg -com.eg -edu.eg -eun.eg -gov.eg -info.eg -me.eg -mil.eg -name.eg -net.eg -org.eg -sci.eg -sport.eg -tv.eg - -// er : https://www.iana.org/domains/root/db/er.html -*.er - -// es : https://www.dominios.es/en -es -com.es -edu.es -gob.es -nom.es -org.es - -// et : https://www.iana.org/domains/root/db/et.html -et -biz.et -com.et -edu.et -gov.et -info.et -name.et -net.et -org.et - -// eu : https://www.iana.org/domains/root/db/eu.html -eu - -// fi : https://www.iana.org/domains/root/db/fi.html -fi -// aland.fi : https://www.iana.org/domains/root/db/ax.html -// This domain is being phased out in favor of .ax. As there are still many -// domains under aland.fi, we still keep it on the list until aland.fi is -// completely removed. -aland.fi - -// fj : https://www.iana.org/domains/root/db/fj.html -fj -ac.fj -biz.fj -com.fj -edu.fj -gov.fj -id.fj -info.fj -mil.fj -name.fj -net.fj -org.fj -pro.fj - -// fk : https://www.iana.org/domains/root/db/fk.html -*.fk - -// fm : https://www.iana.org/domains/root/db/fm.html -fm -com.fm -edu.fm -net.fm -org.fm - -// fo : https://www.iana.org/domains/root/db/fo.html -fo - -// fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -fr -asso.fr -com.fr -gouv.fr -nom.fr -prd.fr -tm.fr -// Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes -avoues.fr -cci.fr -greta.fr -huissier-justice.fr - -// ga : https://www.iana.org/domains/root/db/ga.html -ga - -// gb : This registry is effectively dormant -// Submitted by registry -gb - -// gd : https://www.iana.org/domains/root/db/gd.html -gd -edu.gd -gov.gd - -// ge : https://nic.ge/en/administrator/the-ge-domain-regulations -// Confirmed by registry 2024-11-20 -ge -com.ge -edu.ge -gov.ge -net.ge -org.ge -pvt.ge -school.ge - -// gf : https://www.iana.org/domains/root/db/gf.html -gf - -// gg : https://www.channelisles.net/register-1/register-direct -// Confirmed by registry 2013-11-28 -gg -co.gg -net.gg -org.gg - -// gh : https://www.iana.org/domains/root/db/gh.html -// https://www.nic.gh/ -// Although domains directly at second level are not possible at the moment, -// they have been possible for some time and may come back. -gh -biz.gh -com.gh -edu.gh -gov.gh -mil.gh -net.gh -org.gh - -// gi : http://www.nic.gi/rules.html -gi -com.gi -edu.gi -gov.gi -ltd.gi -mod.gi -org.gi - -// gl : https://www.iana.org/domains/root/db/gl.html -// http://nic.gl -gl -co.gl -com.gl -edu.gl -net.gl -org.gl - -// gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm -gm - -// gn : http://psg.com/dns/gn/gn.txt -// Submitted by registry -gn -ac.gn -com.gn -edu.gn -gov.gn -net.gn -org.gn - -// gov : https://www.iana.org/domains/root/db/gov.html -gov - -// gp : http://www.nic.gp/index.php?lang=en -gp -asso.gp -com.gp -edu.gp -mobi.gp -net.gp -org.gp - -// gq : https://www.iana.org/domains/root/db/gq.html -gq - -// gr : https://www.iana.org/domains/root/db/gr.html -// Submitted by registry -gr -com.gr -edu.gr -gov.gr -net.gr -org.gr - -// gs : https://www.iana.org/domains/root/db/gs.html -gs - -// gt : https://www.gt/sitio/registration_policy.php?lang=en -gt -com.gt -edu.gt -gob.gt -ind.gt -mil.gt -net.gt -org.gt - -// gu : http://gadao.gov.gu/register.html -// University of Guam : https://www.uog.edu -// Submitted by uognoc@triton.uog.edu -gu -com.gu -edu.gu -gov.gu -guam.gu -info.gu -net.gu -org.gu -web.gu - -// gw : https://www.iana.org/domains/root/db/gw.html -// gw : https://nic.gw/regras/ -gw - -// gy : https://www.iana.org/domains/root/db/gy.html -// http://registry.gy/ -gy -co.gy -com.gy -edu.gy -gov.gy -net.gy -org.gy - -// hk : https://www.hkirc.hk -// Submitted by registry -hk -com.hk -edu.hk -gov.hk -idv.hk -net.hk -org.hk -个人.hk -個人.hk -公司.hk -政府.hk -敎育.hk -教育.hk -箇人.hk -組織.hk -組织.hk -網絡.hk -網络.hk -组織.hk -组织.hk -网絡.hk -网络.hk - -// hm : https://www.iana.org/domains/root/db/hm.html -hm - -// hn : https://www.iana.org/domains/root/db/hn.html -hn -com.hn -edu.hn -gob.hn -mil.hn -net.hn -org.hn - -// hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf -hr -com.hr -from.hr -iz.hr -name.hr - -// ht : http://www.nic.ht/info/charte.cfm -ht -adult.ht -art.ht -asso.ht -com.ht -coop.ht -edu.ht -firm.ht -gouv.ht -info.ht -med.ht -net.ht -org.ht -perso.ht -pol.ht -pro.ht -rel.ht -shop.ht - -// hu : https://www.iana.org/domains/root/db/hu.html -// Confirmed by registry 2008-06-12 -hu -2000.hu -agrar.hu -bolt.hu -casino.hu -city.hu -co.hu -erotica.hu -erotika.hu -film.hu -forum.hu -games.hu -hotel.hu -info.hu -ingatlan.hu -jogasz.hu -konyvelo.hu -lakas.hu -media.hu -news.hu -org.hu -priv.hu -reklam.hu -sex.hu -shop.hu -sport.hu -suli.hu -szex.hu -tm.hu -tozsde.hu -utazas.hu -video.hu - -// id : https://www.iana.org/domains/root/db/id.html -id -ac.id -biz.id -co.id -desa.id -go.id -kop.id -mil.id -my.id -net.id -or.id -ponpes.id -sch.id -web.id - -// ie : https://www.iana.org/domains/root/db/ie.html -ie -gov.ie - -// il : http://www.isoc.org.il/domains/ -// see also: https://en.isoc.org.il/il-cctld/registration-rules -// ISOC-IL (operated by .il Registry) -il -ac.il -co.il -gov.il -idf.il -k12.il -muni.il -net.il -org.il -// xn--4dbrk0ce ("Israel", Hebrew) : IL -ישראל -// xn--4dbgdty6c.xn--4dbrk0ce. -אקדמיה.ישראל -// xn--5dbhl8d.xn--4dbrk0ce. -ישוב.ישראל -// xn--8dbq2a.xn--4dbrk0ce. -צהל.ישראל -// xn--hebda8b.xn--4dbrk0ce. -ממשל.ישראל - -// im : https://www.nic.im/ -// Submitted by registry -im -ac.im -co.im -ltd.co.im -plc.co.im -com.im -net.im -org.im -tt.im -tv.im - -// in : https://www.iana.org/domains/root/db/in.html -// see also: https://registry.in/policies -// Please note, that nic.in is not an official eTLD, but used by most -// government institutions. -// Confirmed by Gaurav Kansal 2025-11-06 -in -5g.in -6g.in -ac.in -ai.in -am.in -bank.in -bihar.in -biz.in -business.in -ca.in -cn.in -co.in -com.in -coop.in -cs.in -delhi.in -dr.in -edu.in -er.in -fin.in -firm.in -gen.in -gov.in -gujarat.in -ind.in -info.in -int.in -internet.in -io.in -me.in -mil.in -net.in -nic.in -org.in -pg.in -post.in -pro.in -res.in -travel.in -tv.in -uk.in -up.in -us.in - -// info : https://www.iana.org/domains/root/db/info.html -info - -// int : https://www.iana.org/domains/root/db/int.html -// Confirmed by registry 2008-06-18 -int -eu.int - -// io : http://www.nic.io/rules.htm -io -co.io -com.io -edu.io -gov.io -mil.io -net.io -nom.io -org.io - -// iq : http://www.cmc.iq/english/iq/iqregister1.htm -iq -com.iq -edu.iq -gov.iq -mil.iq -net.iq -org.iq - -// ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules -// Also see http://www.nic.ir/Internationalized_Domain_Names -// Two .ir entries added at request of , 2010-04-16 -ir -ac.ir -co.ir -gov.ir -id.ir -net.ir -org.ir -sch.ir -// xn--mgba3a4f16a.ir (.ir, Persian YEH) -ایران.ir -// xn--mgba3a4fra.ir (.ir, Arabic YEH) -ايران.ir - -// is : http://www.isnic.is/domain/rules.php -// Confirmed by registry 2024-11-17 -is - -// it : https://www.iana.org/domains/root/db/it.html -// https://www.nic.it/ -it -edu.it -gov.it -// Regions (3.3.1) -// https://www.nic.it/en/manage-your-it/forms-and-docs -> "Assignment and Management of domain names" -abr.it -abruzzo.it -aosta-valley.it -aostavalley.it -bas.it -basilicata.it -cal.it -calabria.it -cam.it -campania.it -emilia-romagna.it -emiliaromagna.it -emr.it -friuli-v-giulia.it -friuli-ve-giulia.it -friuli-vegiulia.it -friuli-venezia-giulia.it -friuli-veneziagiulia.it -friuli-vgiulia.it -friuliv-giulia.it -friulive-giulia.it -friulivegiulia.it -friulivenezia-giulia.it -friuliveneziagiulia.it -friulivgiulia.it -fvg.it -laz.it -lazio.it -lig.it -liguria.it -lom.it -lombardia.it -lombardy.it -lucania.it -mar.it -marche.it -mol.it -molise.it -piedmont.it -piemonte.it -pmn.it -pug.it -puglia.it -sar.it -sardegna.it -sardinia.it -sic.it -sicilia.it -sicily.it -taa.it -tos.it -toscana.it -trentin-sud-tirol.it -trentin-süd-tirol.it -trentin-sudtirol.it -trentin-südtirol.it -trentin-sued-tirol.it -trentin-suedtirol.it -trentino.it -trentino-a-adige.it -trentino-aadige.it -trentino-alto-adige.it -trentino-altoadige.it -trentino-s-tirol.it -trentino-stirol.it -trentino-sud-tirol.it -trentino-süd-tirol.it -trentino-sudtirol.it -trentino-südtirol.it -trentino-sued-tirol.it -trentino-suedtirol.it -trentinoa-adige.it -trentinoaadige.it -trentinoalto-adige.it -trentinoaltoadige.it -trentinos-tirol.it -trentinostirol.it -trentinosud-tirol.it -trentinosüd-tirol.it -trentinosudtirol.it -trentinosüdtirol.it -trentinosued-tirol.it -trentinosuedtirol.it -trentinsud-tirol.it -trentinsüd-tirol.it -trentinsudtirol.it -trentinsüdtirol.it -trentinsued-tirol.it -trentinsuedtirol.it -tuscany.it -umb.it -umbria.it -val-d-aosta.it -val-daosta.it -vald-aosta.it -valdaosta.it -valle-aosta.it -valle-d-aosta.it -valle-daosta.it -valleaosta.it -valled-aosta.it -valledaosta.it -vallee-aoste.it -vallée-aoste.it -vallee-d-aoste.it -vallée-d-aoste.it -valleeaoste.it -valléeaoste.it -valleedaoste.it -valléedaoste.it -vao.it -vda.it -ven.it -veneto.it -// Provinces (3.3.2) -ag.it -agrigento.it -al.it -alessandria.it -alto-adige.it -altoadige.it -an.it -ancona.it -andria-barletta-trani.it -andria-trani-barletta.it -andriabarlettatrani.it -andriatranibarletta.it -ao.it -aosta.it -aoste.it -ap.it -aq.it -aquila.it -ar.it -arezzo.it -ascoli-piceno.it -ascolipiceno.it -asti.it -at.it -av.it -avellino.it -ba.it -balsan.it -balsan-sudtirol.it -balsan-südtirol.it -balsan-suedtirol.it -bari.it -barletta-trani-andria.it -barlettatraniandria.it -belluno.it -benevento.it -bergamo.it -bg.it -bi.it -biella.it -bl.it -bn.it -bo.it -bologna.it -bolzano.it -bolzano-altoadige.it -bozen.it -bozen-sudtirol.it -bozen-südtirol.it -bozen-suedtirol.it -br.it -brescia.it -brindisi.it -bs.it -bt.it -bulsan.it -bulsan-sudtirol.it -bulsan-südtirol.it -bulsan-suedtirol.it -bz.it -ca.it -cagliari.it -caltanissetta.it -campidano-medio.it -campidanomedio.it -campobasso.it -carbonia-iglesias.it -carboniaiglesias.it -carrara-massa.it -carraramassa.it -caserta.it -catania.it -catanzaro.it -cb.it -ce.it -cesena-forli.it -cesena-forlì.it -cesenaforli.it -cesenaforlì.it -ch.it -chieti.it -ci.it -cl.it -cn.it -co.it -como.it -cosenza.it -cr.it -cremona.it -crotone.it -cs.it -ct.it -cuneo.it -cz.it -dell-ogliastra.it -dellogliastra.it -en.it -enna.it -fc.it -fe.it -fermo.it -ferrara.it -fg.it -fi.it -firenze.it -florence.it -fm.it -foggia.it -forli-cesena.it -forlì-cesena.it -forlicesena.it -forlìcesena.it -fr.it -frosinone.it -ge.it -genoa.it -genova.it -go.it -gorizia.it -gr.it -grosseto.it -iglesias-carbonia.it -iglesiascarbonia.it -im.it -imperia.it -is.it -isernia.it -kr.it -la-spezia.it -laquila.it -laspezia.it -latina.it -lc.it -le.it -lecce.it -lecco.it -li.it -livorno.it -lo.it -lodi.it -lt.it -lu.it -lucca.it -macerata.it -mantova.it -massa-carrara.it -massacarrara.it -matera.it -mb.it -mc.it -me.it -medio-campidano.it -mediocampidano.it -messina.it -mi.it -milan.it -milano.it -mn.it -mo.it -modena.it -monza.it -monza-brianza.it -monza-e-della-brianza.it -monzabrianza.it -monzaebrianza.it -monzaedellabrianza.it -ms.it -mt.it -na.it -naples.it -napoli.it -no.it -novara.it -nu.it -nuoro.it -og.it -ogliastra.it -olbia-tempio.it -olbiatempio.it -or.it -oristano.it -ot.it -pa.it -padova.it -padua.it -palermo.it -parma.it -pavia.it -pc.it -pd.it -pe.it -perugia.it -pesaro-urbino.it -pesarourbino.it -pescara.it -pg.it -pi.it -piacenza.it -pisa.it -pistoia.it -pn.it -po.it -pordenone.it -potenza.it -pr.it -prato.it -pt.it -pu.it -pv.it -pz.it -ra.it -ragusa.it -ravenna.it -rc.it -re.it -reggio-calabria.it -reggio-emilia.it -reggiocalabria.it -reggioemilia.it -rg.it -ri.it -rieti.it -rimini.it -rm.it -rn.it -ro.it -roma.it -rome.it -rovigo.it -sa.it -salerno.it -sassari.it -savona.it -si.it -siena.it -siracusa.it -so.it -sondrio.it -sp.it -sr.it -ss.it -südtirol.it -suedtirol.it -sv.it -ta.it -taranto.it -te.it -tempio-olbia.it -tempioolbia.it -teramo.it -terni.it -tn.it -to.it -torino.it -tp.it -tr.it -trani-andria-barletta.it -trani-barletta-andria.it -traniandriabarletta.it -tranibarlettaandria.it -trapani.it -trento.it -treviso.it -trieste.it -ts.it -turin.it -tv.it -ud.it -udine.it -urbino-pesaro.it -urbinopesaro.it -va.it -varese.it -vb.it -vc.it -ve.it -venezia.it -venice.it -verbania.it -vercelli.it -verona.it -vi.it -vibo-valentia.it -vibovalentia.it -vicenza.it -viterbo.it -vr.it -vs.it -vt.it -vv.it - -// je : https://www.iana.org/domains/root/db/je.html -// Confirmed by registry 2013-11-28 -je -co.je -net.je -org.je - -// jm : http://www.com.jm/register.html -*.jm - -// jo : https://www.dns.jo/JoFamily.aspx -// Confirmed by registry 2024-11-17 -jo -agri.jo -ai.jo -com.jo -edu.jo -eng.jo -fm.jo -gov.jo -mil.jo -net.jo -org.jo -per.jo -phd.jo -sch.jo -tv.jo - -// jobs : https://www.iana.org/domains/root/db/jobs.html -jobs - -// jp : https://www.iana.org/domains/root/db/jp.html -// http://jprs.co.jp/en/jpdomain.html -// Confirmed by registry 2024-11-22 -jp -// jp organizational type names -ac.jp -ad.jp -co.jp -ed.jp -go.jp -gr.jp -lg.jp -ne.jp -or.jp -// jp prefecture type names -aichi.jp -akita.jp -aomori.jp -chiba.jp -ehime.jp -fukui.jp -fukuoka.jp -fukushima.jp -gifu.jp -gunma.jp -hiroshima.jp -hokkaido.jp -hyogo.jp -ibaraki.jp -ishikawa.jp -iwate.jp -kagawa.jp -kagoshima.jp -kanagawa.jp -kochi.jp -kumamoto.jp -kyoto.jp -mie.jp -miyagi.jp -miyazaki.jp -nagano.jp -nagasaki.jp -nara.jp -niigata.jp -oita.jp -okayama.jp -okinawa.jp -osaka.jp -saga.jp -saitama.jp -shiga.jp -shimane.jp -shizuoka.jp -tochigi.jp -tokushima.jp -tokyo.jp -tottori.jp -toyama.jp -wakayama.jp -yamagata.jp -yamaguchi.jp -yamanashi.jp -三重.jp -京都.jp -佐賀.jp -兵庫.jp -北海道.jp -千葉.jp -和歌山.jp -埼玉.jp -大分.jp -大阪.jp -奈良.jp -宮城.jp -宮崎.jp -富山.jp -山口.jp -山形.jp -山梨.jp -岐阜.jp -岡山.jp -岩手.jp -島根.jp -広島.jp -徳島.jp -愛媛.jp -愛知.jp -新潟.jp -東京.jp -栃木.jp -沖縄.jp -滋賀.jp -熊本.jp -石川.jp -神奈川.jp -福井.jp -福岡.jp -福島.jp -秋田.jp -群馬.jp -茨城.jp -長崎.jp -長野.jp -青森.jp -静岡.jp -香川.jp -高知.jp -鳥取.jp -鹿児島.jp -// jp geographic type names -// http://jprs.jp/doc/rule/saisoku-1.html -// 2024-11-22: JPRS confirmed that jp geographic type names no longer accept new registrations. -// Once all existing registrations expire (marking full discontinuation), these suffixes -// will be removed from the PSL. -*.kawasaki.jp -!city.kawasaki.jp -*.kitakyushu.jp -!city.kitakyushu.jp -*.kobe.jp -!city.kobe.jp -*.nagoya.jp -!city.nagoya.jp -*.sapporo.jp -!city.sapporo.jp -*.sendai.jp -!city.sendai.jp -*.yokohama.jp -!city.yokohama.jp -// 4th level registration -aisai.aichi.jp -ama.aichi.jp -anjo.aichi.jp -asuke.aichi.jp -chiryu.aichi.jp -chita.aichi.jp -fuso.aichi.jp -gamagori.aichi.jp -handa.aichi.jp -hazu.aichi.jp -hekinan.aichi.jp -higashiura.aichi.jp -ichinomiya.aichi.jp -inazawa.aichi.jp -inuyama.aichi.jp -isshiki.aichi.jp -iwakura.aichi.jp -kanie.aichi.jp -kariya.aichi.jp -kasugai.aichi.jp -kira.aichi.jp -kiyosu.aichi.jp -komaki.aichi.jp -konan.aichi.jp -kota.aichi.jp -mihama.aichi.jp -miyoshi.aichi.jp -nishio.aichi.jp -nisshin.aichi.jp -obu.aichi.jp -oguchi.aichi.jp -oharu.aichi.jp -okazaki.aichi.jp -owariasahi.aichi.jp -seto.aichi.jp -shikatsu.aichi.jp -shinshiro.aichi.jp -shitara.aichi.jp -tahara.aichi.jp -takahama.aichi.jp -tobishima.aichi.jp -toei.aichi.jp -togo.aichi.jp -tokai.aichi.jp -tokoname.aichi.jp -toyoake.aichi.jp -toyohashi.aichi.jp -toyokawa.aichi.jp -toyone.aichi.jp -toyota.aichi.jp -tsushima.aichi.jp -yatomi.aichi.jp -akita.akita.jp -daisen.akita.jp -fujisato.akita.jp -gojome.akita.jp -hachirogata.akita.jp -happou.akita.jp -higashinaruse.akita.jp -honjo.akita.jp -honjyo.akita.jp -ikawa.akita.jp -kamikoani.akita.jp -kamioka.akita.jp -katagami.akita.jp -kazuno.akita.jp -kitaakita.akita.jp -kosaka.akita.jp -kyowa.akita.jp -misato.akita.jp -mitane.akita.jp -moriyoshi.akita.jp -nikaho.akita.jp -noshiro.akita.jp -odate.akita.jp -oga.akita.jp -ogata.akita.jp -semboku.akita.jp -yokote.akita.jp -yurihonjo.akita.jp -aomori.aomori.jp -gonohe.aomori.jp -hachinohe.aomori.jp -hashikami.aomori.jp -hiranai.aomori.jp -hirosaki.aomori.jp -itayanagi.aomori.jp -kuroishi.aomori.jp -misawa.aomori.jp -mutsu.aomori.jp -nakadomari.aomori.jp -noheji.aomori.jp -oirase.aomori.jp -owani.aomori.jp -rokunohe.aomori.jp -sannohe.aomori.jp -shichinohe.aomori.jp -shingo.aomori.jp -takko.aomori.jp -towada.aomori.jp -tsugaru.aomori.jp -tsuruta.aomori.jp -abiko.chiba.jp -asahi.chiba.jp -chonan.chiba.jp -chosei.chiba.jp -choshi.chiba.jp -chuo.chiba.jp -funabashi.chiba.jp -futtsu.chiba.jp -hanamigawa.chiba.jp -ichihara.chiba.jp -ichikawa.chiba.jp -ichinomiya.chiba.jp -inzai.chiba.jp -isumi.chiba.jp -kamagaya.chiba.jp -kamogawa.chiba.jp -kashiwa.chiba.jp -katori.chiba.jp -katsuura.chiba.jp -kimitsu.chiba.jp -kisarazu.chiba.jp -kozaki.chiba.jp -kujukuri.chiba.jp -kyonan.chiba.jp -matsudo.chiba.jp -midori.chiba.jp -mihama.chiba.jp -minamiboso.chiba.jp -mobara.chiba.jp -mutsuzawa.chiba.jp -nagara.chiba.jp -nagareyama.chiba.jp -narashino.chiba.jp -narita.chiba.jp -noda.chiba.jp -oamishirasato.chiba.jp -omigawa.chiba.jp -onjuku.chiba.jp -otaki.chiba.jp -sakae.chiba.jp -sakura.chiba.jp -shimofusa.chiba.jp -shirako.chiba.jp -shiroi.chiba.jp -shisui.chiba.jp -sodegaura.chiba.jp -sosa.chiba.jp -tako.chiba.jp -tateyama.chiba.jp -togane.chiba.jp -tohnosho.chiba.jp -tomisato.chiba.jp -urayasu.chiba.jp -yachimata.chiba.jp -yachiyo.chiba.jp -yokaichiba.chiba.jp -yokoshibahikari.chiba.jp -yotsukaido.chiba.jp -ainan.ehime.jp -honai.ehime.jp -ikata.ehime.jp -imabari.ehime.jp -iyo.ehime.jp -kamijima.ehime.jp -kihoku.ehime.jp -kumakogen.ehime.jp -masaki.ehime.jp -matsuno.ehime.jp -matsuyama.ehime.jp -namikata.ehime.jp -niihama.ehime.jp -ozu.ehime.jp -saijo.ehime.jp -seiyo.ehime.jp -shikokuchuo.ehime.jp -tobe.ehime.jp -toon.ehime.jp -uchiko.ehime.jp -uwajima.ehime.jp -yawatahama.ehime.jp -echizen.fukui.jp -eiheiji.fukui.jp -fukui.fukui.jp -ikeda.fukui.jp -katsuyama.fukui.jp -mihama.fukui.jp -minamiechizen.fukui.jp -obama.fukui.jp -ohi.fukui.jp -ono.fukui.jp -sabae.fukui.jp -sakai.fukui.jp -takahama.fukui.jp -tsuruga.fukui.jp -wakasa.fukui.jp -ashiya.fukuoka.jp -buzen.fukuoka.jp -chikugo.fukuoka.jp -chikuho.fukuoka.jp -chikujo.fukuoka.jp -chikushino.fukuoka.jp -chikuzen.fukuoka.jp -chuo.fukuoka.jp -dazaifu.fukuoka.jp -fukuchi.fukuoka.jp -hakata.fukuoka.jp -higashi.fukuoka.jp -hirokawa.fukuoka.jp -hisayama.fukuoka.jp -iizuka.fukuoka.jp -inatsuki.fukuoka.jp -kaho.fukuoka.jp -kasuga.fukuoka.jp -kasuya.fukuoka.jp -kawara.fukuoka.jp -keisen.fukuoka.jp -koga.fukuoka.jp -kurate.fukuoka.jp -kurogi.fukuoka.jp -kurume.fukuoka.jp -minami.fukuoka.jp -miyako.fukuoka.jp -miyama.fukuoka.jp -miyawaka.fukuoka.jp -mizumaki.fukuoka.jp -munakata.fukuoka.jp -nakagawa.fukuoka.jp -nakama.fukuoka.jp -nishi.fukuoka.jp -nogata.fukuoka.jp -ogori.fukuoka.jp -okagaki.fukuoka.jp -okawa.fukuoka.jp -oki.fukuoka.jp -omuta.fukuoka.jp -onga.fukuoka.jp -onojo.fukuoka.jp -oto.fukuoka.jp -saigawa.fukuoka.jp -sasaguri.fukuoka.jp -shingu.fukuoka.jp -shinyoshitomi.fukuoka.jp -shonai.fukuoka.jp -soeda.fukuoka.jp -sue.fukuoka.jp -tachiarai.fukuoka.jp -tagawa.fukuoka.jp -takata.fukuoka.jp -toho.fukuoka.jp -toyotsu.fukuoka.jp -tsuiki.fukuoka.jp -ukiha.fukuoka.jp -umi.fukuoka.jp -usui.fukuoka.jp -yamada.fukuoka.jp -yame.fukuoka.jp -yanagawa.fukuoka.jp -yukuhashi.fukuoka.jp -aizubange.fukushima.jp -aizumisato.fukushima.jp -aizuwakamatsu.fukushima.jp -asakawa.fukushima.jp -bandai.fukushima.jp -date.fukushima.jp -fukushima.fukushima.jp -furudono.fukushima.jp -futaba.fukushima.jp -hanawa.fukushima.jp -higashi.fukushima.jp -hirata.fukushima.jp -hirono.fukushima.jp -iitate.fukushima.jp -inawashiro.fukushima.jp -ishikawa.fukushima.jp -iwaki.fukushima.jp -izumizaki.fukushima.jp -kagamiishi.fukushima.jp -kaneyama.fukushima.jp -kawamata.fukushima.jp -kitakata.fukushima.jp -kitashiobara.fukushima.jp -koori.fukushima.jp -koriyama.fukushima.jp -kunimi.fukushima.jp -miharu.fukushima.jp -mishima.fukushima.jp -namie.fukushima.jp -nango.fukushima.jp -nishiaizu.fukushima.jp -nishigo.fukushima.jp -okuma.fukushima.jp -omotego.fukushima.jp -ono.fukushima.jp -otama.fukushima.jp -samegawa.fukushima.jp -shimogo.fukushima.jp -shirakawa.fukushima.jp -showa.fukushima.jp -soma.fukushima.jp -sukagawa.fukushima.jp -taishin.fukushima.jp -tamakawa.fukushima.jp -tanagura.fukushima.jp -tenei.fukushima.jp -yabuki.fukushima.jp -yamato.fukushima.jp -yamatsuri.fukushima.jp -yanaizu.fukushima.jp -yugawa.fukushima.jp -anpachi.gifu.jp -ena.gifu.jp -gifu.gifu.jp -ginan.gifu.jp -godo.gifu.jp -gujo.gifu.jp -hashima.gifu.jp -hichiso.gifu.jp -hida.gifu.jp -higashishirakawa.gifu.jp -ibigawa.gifu.jp -ikeda.gifu.jp -kakamigahara.gifu.jp -kani.gifu.jp -kasahara.gifu.jp -kasamatsu.gifu.jp -kawaue.gifu.jp -kitagata.gifu.jp -mino.gifu.jp -minokamo.gifu.jp -mitake.gifu.jp -mizunami.gifu.jp -motosu.gifu.jp -nakatsugawa.gifu.jp -ogaki.gifu.jp -sakahogi.gifu.jp -seki.gifu.jp -sekigahara.gifu.jp -shirakawa.gifu.jp -tajimi.gifu.jp -takayama.gifu.jp -tarui.gifu.jp -toki.gifu.jp -tomika.gifu.jp -wanouchi.gifu.jp -yamagata.gifu.jp -yaotsu.gifu.jp -yoro.gifu.jp -annaka.gunma.jp -chiyoda.gunma.jp -fujioka.gunma.jp -higashiagatsuma.gunma.jp -isesaki.gunma.jp -itakura.gunma.jp -kanna.gunma.jp -kanra.gunma.jp -katashina.gunma.jp -kawaba.gunma.jp -kiryu.gunma.jp -kusatsu.gunma.jp -maebashi.gunma.jp -meiwa.gunma.jp -midori.gunma.jp -minakami.gunma.jp -naganohara.gunma.jp -nakanojo.gunma.jp -nanmoku.gunma.jp -numata.gunma.jp -oizumi.gunma.jp -ora.gunma.jp -ota.gunma.jp -shibukawa.gunma.jp -shimonita.gunma.jp -shinto.gunma.jp -showa.gunma.jp -takasaki.gunma.jp -takayama.gunma.jp -tamamura.gunma.jp -tatebayashi.gunma.jp -tomioka.gunma.jp -tsukiyono.gunma.jp -tsumagoi.gunma.jp -ueno.gunma.jp -yoshioka.gunma.jp -asaminami.hiroshima.jp -daiwa.hiroshima.jp -etajima.hiroshima.jp -fuchu.hiroshima.jp -fukuyama.hiroshima.jp -hatsukaichi.hiroshima.jp -higashihiroshima.hiroshima.jp -hongo.hiroshima.jp -jinsekikogen.hiroshima.jp -kaita.hiroshima.jp -kui.hiroshima.jp -kumano.hiroshima.jp -kure.hiroshima.jp -mihara.hiroshima.jp -miyoshi.hiroshima.jp -naka.hiroshima.jp -onomichi.hiroshima.jp -osakikamijima.hiroshima.jp -otake.hiroshima.jp -saka.hiroshima.jp -sera.hiroshima.jp -seranishi.hiroshima.jp -shinichi.hiroshima.jp -shobara.hiroshima.jp -takehara.hiroshima.jp -abashiri.hokkaido.jp -abira.hokkaido.jp -aibetsu.hokkaido.jp -akabira.hokkaido.jp -akkeshi.hokkaido.jp -asahikawa.hokkaido.jp -ashibetsu.hokkaido.jp -ashoro.hokkaido.jp -assabu.hokkaido.jp -atsuma.hokkaido.jp -bibai.hokkaido.jp -biei.hokkaido.jp -bifuka.hokkaido.jp -bihoro.hokkaido.jp -biratori.hokkaido.jp -chippubetsu.hokkaido.jp -chitose.hokkaido.jp -date.hokkaido.jp -ebetsu.hokkaido.jp -embetsu.hokkaido.jp -eniwa.hokkaido.jp -erimo.hokkaido.jp -esan.hokkaido.jp -esashi.hokkaido.jp -fukagawa.hokkaido.jp -fukushima.hokkaido.jp -furano.hokkaido.jp -furubira.hokkaido.jp -haboro.hokkaido.jp -hakodate.hokkaido.jp -hamatonbetsu.hokkaido.jp -hidaka.hokkaido.jp -higashikagura.hokkaido.jp -higashikawa.hokkaido.jp -hiroo.hokkaido.jp -hokuryu.hokkaido.jp -hokuto.hokkaido.jp -honbetsu.hokkaido.jp -horokanai.hokkaido.jp -horonobe.hokkaido.jp -ikeda.hokkaido.jp -imakane.hokkaido.jp -ishikari.hokkaido.jp -iwamizawa.hokkaido.jp -iwanai.hokkaido.jp -kamifurano.hokkaido.jp -kamikawa.hokkaido.jp -kamishihoro.hokkaido.jp -kamisunagawa.hokkaido.jp -kamoenai.hokkaido.jp -kayabe.hokkaido.jp -kembuchi.hokkaido.jp -kikonai.hokkaido.jp -kimobetsu.hokkaido.jp -kitahiroshima.hokkaido.jp -kitami.hokkaido.jp -kiyosato.hokkaido.jp -koshimizu.hokkaido.jp -kunneppu.hokkaido.jp -kuriyama.hokkaido.jp -kuromatsunai.hokkaido.jp -kushiro.hokkaido.jp -kutchan.hokkaido.jp -kyowa.hokkaido.jp -mashike.hokkaido.jp -matsumae.hokkaido.jp -mikasa.hokkaido.jp -minamifurano.hokkaido.jp -mombetsu.hokkaido.jp -moseushi.hokkaido.jp -mukawa.hokkaido.jp -muroran.hokkaido.jp -naie.hokkaido.jp -nakagawa.hokkaido.jp -nakasatsunai.hokkaido.jp -nakatombetsu.hokkaido.jp -nanae.hokkaido.jp -nanporo.hokkaido.jp -nayoro.hokkaido.jp -nemuro.hokkaido.jp -niikappu.hokkaido.jp -niki.hokkaido.jp -nishiokoppe.hokkaido.jp -noboribetsu.hokkaido.jp -numata.hokkaido.jp -obihiro.hokkaido.jp -obira.hokkaido.jp -oketo.hokkaido.jp -okoppe.hokkaido.jp -otaru.hokkaido.jp -otobe.hokkaido.jp -otofuke.hokkaido.jp -otoineppu.hokkaido.jp -oumu.hokkaido.jp -ozora.hokkaido.jp -pippu.hokkaido.jp -rankoshi.hokkaido.jp -rebun.hokkaido.jp -rikubetsu.hokkaido.jp -rishiri.hokkaido.jp -rishirifuji.hokkaido.jp -saroma.hokkaido.jp -sarufutsu.hokkaido.jp -shakotan.hokkaido.jp -shari.hokkaido.jp -shibecha.hokkaido.jp -shibetsu.hokkaido.jp -shikabe.hokkaido.jp -shikaoi.hokkaido.jp -shimamaki.hokkaido.jp -shimizu.hokkaido.jp -shimokawa.hokkaido.jp -shinshinotsu.hokkaido.jp -shintoku.hokkaido.jp -shiranuka.hokkaido.jp -shiraoi.hokkaido.jp -shiriuchi.hokkaido.jp -sobetsu.hokkaido.jp -sunagawa.hokkaido.jp -taiki.hokkaido.jp -takasu.hokkaido.jp -takikawa.hokkaido.jp -takinoue.hokkaido.jp -teshikaga.hokkaido.jp -tobetsu.hokkaido.jp -tohma.hokkaido.jp -tomakomai.hokkaido.jp -tomari.hokkaido.jp -toya.hokkaido.jp -toyako.hokkaido.jp -toyotomi.hokkaido.jp -toyoura.hokkaido.jp -tsubetsu.hokkaido.jp -tsukigata.hokkaido.jp -urakawa.hokkaido.jp -urausu.hokkaido.jp -uryu.hokkaido.jp -utashinai.hokkaido.jp -wakkanai.hokkaido.jp -wassamu.hokkaido.jp -yakumo.hokkaido.jp -yoichi.hokkaido.jp -aioi.hyogo.jp -akashi.hyogo.jp -ako.hyogo.jp -amagasaki.hyogo.jp -aogaki.hyogo.jp -asago.hyogo.jp -ashiya.hyogo.jp -awaji.hyogo.jp -fukusaki.hyogo.jp -goshiki.hyogo.jp -harima.hyogo.jp -himeji.hyogo.jp -ichikawa.hyogo.jp -inagawa.hyogo.jp -itami.hyogo.jp -kakogawa.hyogo.jp -kamigori.hyogo.jp -kamikawa.hyogo.jp -kasai.hyogo.jp -kasuga.hyogo.jp -kawanishi.hyogo.jp -miki.hyogo.jp -minamiawaji.hyogo.jp -nishinomiya.hyogo.jp -nishiwaki.hyogo.jp -ono.hyogo.jp -sanda.hyogo.jp -sannan.hyogo.jp -sasayama.hyogo.jp -sayo.hyogo.jp -shingu.hyogo.jp -shinonsen.hyogo.jp -shiso.hyogo.jp -sumoto.hyogo.jp -taishi.hyogo.jp -taka.hyogo.jp -takarazuka.hyogo.jp -takasago.hyogo.jp -takino.hyogo.jp -tamba.hyogo.jp -tatsuno.hyogo.jp -toyooka.hyogo.jp -yabu.hyogo.jp -yashiro.hyogo.jp -yoka.hyogo.jp -yokawa.hyogo.jp -ami.ibaraki.jp -asahi.ibaraki.jp -bando.ibaraki.jp -chikusei.ibaraki.jp -daigo.ibaraki.jp -fujishiro.ibaraki.jp -hitachi.ibaraki.jp -hitachinaka.ibaraki.jp -hitachiomiya.ibaraki.jp -hitachiota.ibaraki.jp -ibaraki.ibaraki.jp -ina.ibaraki.jp -inashiki.ibaraki.jp -itako.ibaraki.jp -iwama.ibaraki.jp -joso.ibaraki.jp -kamisu.ibaraki.jp -kasama.ibaraki.jp -kashima.ibaraki.jp -kasumigaura.ibaraki.jp -koga.ibaraki.jp -miho.ibaraki.jp -mito.ibaraki.jp -moriya.ibaraki.jp -naka.ibaraki.jp -namegata.ibaraki.jp -oarai.ibaraki.jp -ogawa.ibaraki.jp -omitama.ibaraki.jp -ryugasaki.ibaraki.jp -sakai.ibaraki.jp -sakuragawa.ibaraki.jp -shimodate.ibaraki.jp -shimotsuma.ibaraki.jp -shirosato.ibaraki.jp -sowa.ibaraki.jp -suifu.ibaraki.jp -takahagi.ibaraki.jp -tamatsukuri.ibaraki.jp -tokai.ibaraki.jp -tomobe.ibaraki.jp -tone.ibaraki.jp -toride.ibaraki.jp -tsuchiura.ibaraki.jp -tsukuba.ibaraki.jp -uchihara.ibaraki.jp -ushiku.ibaraki.jp -yachiyo.ibaraki.jp -yamagata.ibaraki.jp -yawara.ibaraki.jp -yuki.ibaraki.jp -anamizu.ishikawa.jp -hakui.ishikawa.jp -hakusan.ishikawa.jp -kaga.ishikawa.jp -kahoku.ishikawa.jp -kanazawa.ishikawa.jp -kawakita.ishikawa.jp -komatsu.ishikawa.jp -nakanoto.ishikawa.jp -nanao.ishikawa.jp -nomi.ishikawa.jp -nonoichi.ishikawa.jp -noto.ishikawa.jp -shika.ishikawa.jp -suzu.ishikawa.jp -tsubata.ishikawa.jp -tsurugi.ishikawa.jp -uchinada.ishikawa.jp -wajima.ishikawa.jp -fudai.iwate.jp -fujisawa.iwate.jp -hanamaki.iwate.jp -hiraizumi.iwate.jp -hirono.iwate.jp -ichinohe.iwate.jp -ichinoseki.iwate.jp -iwaizumi.iwate.jp -iwate.iwate.jp -joboji.iwate.jp -kamaishi.iwate.jp -kanegasaki.iwate.jp -karumai.iwate.jp -kawai.iwate.jp -kitakami.iwate.jp -kuji.iwate.jp -kunohe.iwate.jp -kuzumaki.iwate.jp -miyako.iwate.jp -mizusawa.iwate.jp -morioka.iwate.jp -ninohe.iwate.jp -noda.iwate.jp -ofunato.iwate.jp -oshu.iwate.jp -otsuchi.iwate.jp -rikuzentakata.iwate.jp -shiwa.iwate.jp -shizukuishi.iwate.jp -sumita.iwate.jp -tanohata.iwate.jp -tono.iwate.jp -yahaba.iwate.jp -yamada.iwate.jp -ayagawa.kagawa.jp -higashikagawa.kagawa.jp -kanonji.kagawa.jp -kotohira.kagawa.jp -manno.kagawa.jp -marugame.kagawa.jp -mitoyo.kagawa.jp -naoshima.kagawa.jp -sanuki.kagawa.jp -tadotsu.kagawa.jp -takamatsu.kagawa.jp -tonosho.kagawa.jp -uchinomi.kagawa.jp -utazu.kagawa.jp -zentsuji.kagawa.jp -akune.kagoshima.jp -amami.kagoshima.jp -hioki.kagoshima.jp -isa.kagoshima.jp -isen.kagoshima.jp -izumi.kagoshima.jp -kagoshima.kagoshima.jp -kanoya.kagoshima.jp -kawanabe.kagoshima.jp -kinko.kagoshima.jp -kouyama.kagoshima.jp -makurazaki.kagoshima.jp -matsumoto.kagoshima.jp -minamitane.kagoshima.jp -nakatane.kagoshima.jp -nishinoomote.kagoshima.jp -satsumasendai.kagoshima.jp -soo.kagoshima.jp -tarumizu.kagoshima.jp -yusui.kagoshima.jp -aikawa.kanagawa.jp -atsugi.kanagawa.jp -ayase.kanagawa.jp -chigasaki.kanagawa.jp -ebina.kanagawa.jp -fujisawa.kanagawa.jp -hadano.kanagawa.jp -hakone.kanagawa.jp -hiratsuka.kanagawa.jp -isehara.kanagawa.jp -kaisei.kanagawa.jp -kamakura.kanagawa.jp -kiyokawa.kanagawa.jp -matsuda.kanagawa.jp -minamiashigara.kanagawa.jp -miura.kanagawa.jp -nakai.kanagawa.jp -ninomiya.kanagawa.jp -odawara.kanagawa.jp -oi.kanagawa.jp -oiso.kanagawa.jp -sagamihara.kanagawa.jp -samukawa.kanagawa.jp -tsukui.kanagawa.jp -yamakita.kanagawa.jp -yamato.kanagawa.jp -yokosuka.kanagawa.jp -yugawara.kanagawa.jp -zama.kanagawa.jp -zushi.kanagawa.jp -aki.kochi.jp -geisei.kochi.jp -hidaka.kochi.jp -higashitsuno.kochi.jp -ino.kochi.jp -kagami.kochi.jp -kami.kochi.jp -kitagawa.kochi.jp -kochi.kochi.jp -mihara.kochi.jp -motoyama.kochi.jp -muroto.kochi.jp -nahari.kochi.jp -nakamura.kochi.jp -nankoku.kochi.jp -nishitosa.kochi.jp -niyodogawa.kochi.jp -ochi.kochi.jp -okawa.kochi.jp -otoyo.kochi.jp -otsuki.kochi.jp -sakawa.kochi.jp -sukumo.kochi.jp -susaki.kochi.jp -tosa.kochi.jp -tosashimizu.kochi.jp -toyo.kochi.jp -tsuno.kochi.jp -umaji.kochi.jp -yasuda.kochi.jp -yusuhara.kochi.jp -amakusa.kumamoto.jp -arao.kumamoto.jp -aso.kumamoto.jp -choyo.kumamoto.jp -gyokuto.kumamoto.jp -kamiamakusa.kumamoto.jp -kikuchi.kumamoto.jp -kumamoto.kumamoto.jp -mashiki.kumamoto.jp -mifune.kumamoto.jp -minamata.kumamoto.jp -minamioguni.kumamoto.jp -nagasu.kumamoto.jp -nishihara.kumamoto.jp -oguni.kumamoto.jp -ozu.kumamoto.jp -sumoto.kumamoto.jp -takamori.kumamoto.jp -uki.kumamoto.jp -uto.kumamoto.jp -yamaga.kumamoto.jp -yamato.kumamoto.jp -yatsushiro.kumamoto.jp -ayabe.kyoto.jp -fukuchiyama.kyoto.jp -higashiyama.kyoto.jp -ide.kyoto.jp -ine.kyoto.jp -joyo.kyoto.jp -kameoka.kyoto.jp -kamo.kyoto.jp -kita.kyoto.jp -kizu.kyoto.jp -kumiyama.kyoto.jp -kyotamba.kyoto.jp -kyotanabe.kyoto.jp -kyotango.kyoto.jp -maizuru.kyoto.jp -minami.kyoto.jp -minamiyamashiro.kyoto.jp -miyazu.kyoto.jp -muko.kyoto.jp -nagaokakyo.kyoto.jp -nakagyo.kyoto.jp -nantan.kyoto.jp -oyamazaki.kyoto.jp -sakyo.kyoto.jp -seika.kyoto.jp -tanabe.kyoto.jp -uji.kyoto.jp -ujitawara.kyoto.jp -wazuka.kyoto.jp -yamashina.kyoto.jp -yawata.kyoto.jp -asahi.mie.jp -inabe.mie.jp -ise.mie.jp -kameyama.mie.jp -kawagoe.mie.jp -kiho.mie.jp -kisosaki.mie.jp -kiwa.mie.jp -komono.mie.jp -kumano.mie.jp -kuwana.mie.jp -matsusaka.mie.jp -meiwa.mie.jp -mihama.mie.jp -minamiise.mie.jp -misugi.mie.jp -miyama.mie.jp -nabari.mie.jp -shima.mie.jp -suzuka.mie.jp -tado.mie.jp -taiki.mie.jp -taki.mie.jp -tamaki.mie.jp -toba.mie.jp -tsu.mie.jp -udono.mie.jp -ureshino.mie.jp -watarai.mie.jp -yokkaichi.mie.jp -furukawa.miyagi.jp -higashimatsushima.miyagi.jp -ishinomaki.miyagi.jp -iwanuma.miyagi.jp -kakuda.miyagi.jp -kami.miyagi.jp -kawasaki.miyagi.jp -marumori.miyagi.jp -matsushima.miyagi.jp -minamisanriku.miyagi.jp -misato.miyagi.jp -murata.miyagi.jp -natori.miyagi.jp -ogawara.miyagi.jp -ohira.miyagi.jp -onagawa.miyagi.jp -osaki.miyagi.jp -rifu.miyagi.jp -semine.miyagi.jp -shibata.miyagi.jp -shichikashuku.miyagi.jp -shikama.miyagi.jp -shiogama.miyagi.jp -shiroishi.miyagi.jp -tagajo.miyagi.jp -taiwa.miyagi.jp -tome.miyagi.jp -tomiya.miyagi.jp -wakuya.miyagi.jp -watari.miyagi.jp -yamamoto.miyagi.jp -zao.miyagi.jp -aya.miyazaki.jp -ebino.miyazaki.jp -gokase.miyazaki.jp -hyuga.miyazaki.jp -kadogawa.miyazaki.jp -kawaminami.miyazaki.jp -kijo.miyazaki.jp -kitagawa.miyazaki.jp -kitakata.miyazaki.jp -kitaura.miyazaki.jp -kobayashi.miyazaki.jp -kunitomi.miyazaki.jp -kushima.miyazaki.jp -mimata.miyazaki.jp -miyakonojo.miyazaki.jp -miyazaki.miyazaki.jp -morotsuka.miyazaki.jp -nichinan.miyazaki.jp -nishimera.miyazaki.jp -nobeoka.miyazaki.jp -saito.miyazaki.jp -shiiba.miyazaki.jp -shintomi.miyazaki.jp -takaharu.miyazaki.jp -takanabe.miyazaki.jp -takazaki.miyazaki.jp -tsuno.miyazaki.jp -achi.nagano.jp -agematsu.nagano.jp -anan.nagano.jp -aoki.nagano.jp -asahi.nagano.jp -azumino.nagano.jp -chikuhoku.nagano.jp -chikuma.nagano.jp -chino.nagano.jp -fujimi.nagano.jp -hakuba.nagano.jp -hara.nagano.jp -hiraya.nagano.jp -iida.nagano.jp -iijima.nagano.jp -iiyama.nagano.jp -iizuna.nagano.jp -ikeda.nagano.jp -ikusaka.nagano.jp -ina.nagano.jp -karuizawa.nagano.jp -kawakami.nagano.jp -kiso.nagano.jp -kisofukushima.nagano.jp -kitaaiki.nagano.jp -komagane.nagano.jp -komoro.nagano.jp -matsukawa.nagano.jp -matsumoto.nagano.jp -miasa.nagano.jp -minamiaiki.nagano.jp -minamimaki.nagano.jp -minamiminowa.nagano.jp -minowa.nagano.jp -miyada.nagano.jp -miyota.nagano.jp -mochizuki.nagano.jp -nagano.nagano.jp -nagawa.nagano.jp -nagiso.nagano.jp -nakagawa.nagano.jp -nakano.nagano.jp -nozawaonsen.nagano.jp -obuse.nagano.jp -ogawa.nagano.jp -okaya.nagano.jp -omachi.nagano.jp -omi.nagano.jp -ookuwa.nagano.jp -ooshika.nagano.jp -otaki.nagano.jp -otari.nagano.jp -sakae.nagano.jp -sakaki.nagano.jp -saku.nagano.jp -sakuho.nagano.jp -shimosuwa.nagano.jp -shinanomachi.nagano.jp -shiojiri.nagano.jp -suwa.nagano.jp -suzaka.nagano.jp -takagi.nagano.jp -takamori.nagano.jp -takayama.nagano.jp -tateshina.nagano.jp -tatsuno.nagano.jp -togakushi.nagano.jp -togura.nagano.jp -tomi.nagano.jp -ueda.nagano.jp -wada.nagano.jp -yamagata.nagano.jp -yamanouchi.nagano.jp -yasaka.nagano.jp -yasuoka.nagano.jp -chijiwa.nagasaki.jp -futsu.nagasaki.jp -goto.nagasaki.jp -hasami.nagasaki.jp -hirado.nagasaki.jp -iki.nagasaki.jp -isahaya.nagasaki.jp -kawatana.nagasaki.jp -kuchinotsu.nagasaki.jp -matsuura.nagasaki.jp -nagasaki.nagasaki.jp -obama.nagasaki.jp -omura.nagasaki.jp -oseto.nagasaki.jp -saikai.nagasaki.jp -sasebo.nagasaki.jp -seihi.nagasaki.jp -shimabara.nagasaki.jp -shinkamigoto.nagasaki.jp -togitsu.nagasaki.jp -tsushima.nagasaki.jp -unzen.nagasaki.jp -ando.nara.jp -gose.nara.jp -heguri.nara.jp -higashiyoshino.nara.jp -ikaruga.nara.jp -ikoma.nara.jp -kamikitayama.nara.jp -kanmaki.nara.jp -kashiba.nara.jp -kashihara.nara.jp -katsuragi.nara.jp -kawai.nara.jp -kawakami.nara.jp -kawanishi.nara.jp -koryo.nara.jp -kurotaki.nara.jp -mitsue.nara.jp -miyake.nara.jp -nara.nara.jp -nosegawa.nara.jp -oji.nara.jp -ouda.nara.jp -oyodo.nara.jp -sakurai.nara.jp -sango.nara.jp -shimoichi.nara.jp -shimokitayama.nara.jp -shinjo.nara.jp -soni.nara.jp -takatori.nara.jp -tawaramoto.nara.jp -tenkawa.nara.jp -tenri.nara.jp -uda.nara.jp -yamatokoriyama.nara.jp -yamatotakada.nara.jp -yamazoe.nara.jp -yoshino.nara.jp -aga.niigata.jp -agano.niigata.jp -gosen.niigata.jp -itoigawa.niigata.jp -izumozaki.niigata.jp -joetsu.niigata.jp -kamo.niigata.jp -kariwa.niigata.jp -kashiwazaki.niigata.jp -minamiuonuma.niigata.jp -mitsuke.niigata.jp -muika.niigata.jp -murakami.niigata.jp -myoko.niigata.jp -nagaoka.niigata.jp -niigata.niigata.jp -ojiya.niigata.jp -omi.niigata.jp -sado.niigata.jp -sanjo.niigata.jp -seiro.niigata.jp -seirou.niigata.jp -sekikawa.niigata.jp -shibata.niigata.jp -tagami.niigata.jp -tainai.niigata.jp -tochio.niigata.jp -tokamachi.niigata.jp -tsubame.niigata.jp -tsunan.niigata.jp -uonuma.niigata.jp -yahiko.niigata.jp -yoita.niigata.jp -yuzawa.niigata.jp -beppu.oita.jp -bungoono.oita.jp -bungotakada.oita.jp -hasama.oita.jp -hiji.oita.jp -himeshima.oita.jp -hita.oita.jp -kamitsue.oita.jp -kokonoe.oita.jp -kuju.oita.jp -kunisaki.oita.jp -kusu.oita.jp -oita.oita.jp -saiki.oita.jp -taketa.oita.jp -tsukumi.oita.jp -usa.oita.jp -usuki.oita.jp -yufu.oita.jp -akaiwa.okayama.jp -asakuchi.okayama.jp -bizen.okayama.jp -hayashima.okayama.jp -ibara.okayama.jp -kagamino.okayama.jp -kasaoka.okayama.jp -kibichuo.okayama.jp -kumenan.okayama.jp -kurashiki.okayama.jp -maniwa.okayama.jp -misaki.okayama.jp -nagi.okayama.jp -niimi.okayama.jp -nishiawakura.okayama.jp -okayama.okayama.jp -satosho.okayama.jp -setouchi.okayama.jp -shinjo.okayama.jp -shoo.okayama.jp -soja.okayama.jp -takahashi.okayama.jp -tamano.okayama.jp -tsuyama.okayama.jp -wake.okayama.jp -yakage.okayama.jp -aguni.okinawa.jp -ginowan.okinawa.jp -ginoza.okinawa.jp -gushikami.okinawa.jp -haebaru.okinawa.jp -higashi.okinawa.jp -hirara.okinawa.jp -iheya.okinawa.jp -ishigaki.okinawa.jp -ishikawa.okinawa.jp -itoman.okinawa.jp -izena.okinawa.jp -kadena.okinawa.jp -kin.okinawa.jp -kitadaito.okinawa.jp -kitanakagusuku.okinawa.jp -kumejima.okinawa.jp -kunigami.okinawa.jp -minamidaito.okinawa.jp -motobu.okinawa.jp -nago.okinawa.jp -naha.okinawa.jp -nakagusuku.okinawa.jp -nakijin.okinawa.jp -nanjo.okinawa.jp -nishihara.okinawa.jp -ogimi.okinawa.jp -okinawa.okinawa.jp -onna.okinawa.jp -shimoji.okinawa.jp -taketomi.okinawa.jp -tarama.okinawa.jp -tokashiki.okinawa.jp -tomigusuku.okinawa.jp -tonaki.okinawa.jp -urasoe.okinawa.jp -uruma.okinawa.jp -yaese.okinawa.jp -yomitan.okinawa.jp -yonabaru.okinawa.jp -yonaguni.okinawa.jp -zamami.okinawa.jp -abeno.osaka.jp -chihayaakasaka.osaka.jp -chuo.osaka.jp -daito.osaka.jp -fujiidera.osaka.jp -habikino.osaka.jp -hannan.osaka.jp -higashiosaka.osaka.jp -higashisumiyoshi.osaka.jp -higashiyodogawa.osaka.jp -hirakata.osaka.jp -ibaraki.osaka.jp -ikeda.osaka.jp -izumi.osaka.jp -izumiotsu.osaka.jp -izumisano.osaka.jp -kadoma.osaka.jp -kaizuka.osaka.jp -kanan.osaka.jp -kashiwara.osaka.jp -katano.osaka.jp -kawachinagano.osaka.jp -kishiwada.osaka.jp -kita.osaka.jp -kumatori.osaka.jp -matsubara.osaka.jp -minato.osaka.jp -minoh.osaka.jp -misaki.osaka.jp -moriguchi.osaka.jp -neyagawa.osaka.jp -nishi.osaka.jp -nose.osaka.jp -osakasayama.osaka.jp -sakai.osaka.jp -sayama.osaka.jp -sennan.osaka.jp -settsu.osaka.jp -shijonawate.osaka.jp -shimamoto.osaka.jp -suita.osaka.jp -tadaoka.osaka.jp -taishi.osaka.jp -tajiri.osaka.jp -takaishi.osaka.jp -takatsuki.osaka.jp -tondabayashi.osaka.jp -toyonaka.osaka.jp -toyono.osaka.jp -yao.osaka.jp -ariake.saga.jp -arita.saga.jp -fukudomi.saga.jp -genkai.saga.jp -hamatama.saga.jp -hizen.saga.jp -imari.saga.jp -kamimine.saga.jp -kanzaki.saga.jp -karatsu.saga.jp -kashima.saga.jp -kitagata.saga.jp -kitahata.saga.jp -kiyama.saga.jp -kouhoku.saga.jp -kyuragi.saga.jp -nishiarita.saga.jp -ogi.saga.jp -omachi.saga.jp -ouchi.saga.jp -saga.saga.jp -shiroishi.saga.jp -taku.saga.jp -tara.saga.jp -tosu.saga.jp -yoshinogari.saga.jp -arakawa.saitama.jp -asaka.saitama.jp -chichibu.saitama.jp -fujimi.saitama.jp -fujimino.saitama.jp -fukaya.saitama.jp -hanno.saitama.jp -hanyu.saitama.jp -hasuda.saitama.jp -hatogaya.saitama.jp -hatoyama.saitama.jp -hidaka.saitama.jp -higashichichibu.saitama.jp -higashimatsuyama.saitama.jp -honjo.saitama.jp -ina.saitama.jp -iruma.saitama.jp -iwatsuki.saitama.jp -kamiizumi.saitama.jp -kamikawa.saitama.jp -kamisato.saitama.jp -kasukabe.saitama.jp -kawagoe.saitama.jp -kawaguchi.saitama.jp -kawajima.saitama.jp -kazo.saitama.jp -kitamoto.saitama.jp -koshigaya.saitama.jp -kounosu.saitama.jp -kuki.saitama.jp -kumagaya.saitama.jp -matsubushi.saitama.jp -minano.saitama.jp -misato.saitama.jp -miyashiro.saitama.jp -miyoshi.saitama.jp -moroyama.saitama.jp -nagatoro.saitama.jp -namegawa.saitama.jp -niiza.saitama.jp -ogano.saitama.jp -ogawa.saitama.jp -ogose.saitama.jp -okegawa.saitama.jp -omiya.saitama.jp -otaki.saitama.jp -ranzan.saitama.jp -ryokami.saitama.jp -saitama.saitama.jp -sakado.saitama.jp -satte.saitama.jp -sayama.saitama.jp -shiki.saitama.jp -shiraoka.saitama.jp -soka.saitama.jp -sugito.saitama.jp -toda.saitama.jp -tokigawa.saitama.jp -tokorozawa.saitama.jp -tsurugashima.saitama.jp -urawa.saitama.jp -warabi.saitama.jp -yashio.saitama.jp -yokoze.saitama.jp -yono.saitama.jp -yorii.saitama.jp -yoshida.saitama.jp -yoshikawa.saitama.jp -yoshimi.saitama.jp -aisho.shiga.jp -gamo.shiga.jp -higashiomi.shiga.jp -hikone.shiga.jp -koka.shiga.jp -konan.shiga.jp -kosei.shiga.jp -koto.shiga.jp -kusatsu.shiga.jp -maibara.shiga.jp -moriyama.shiga.jp -nagahama.shiga.jp -nishiazai.shiga.jp -notogawa.shiga.jp -omihachiman.shiga.jp -otsu.shiga.jp -ritto.shiga.jp -ryuoh.shiga.jp -takashima.shiga.jp -takatsuki.shiga.jp -torahime.shiga.jp -toyosato.shiga.jp -yasu.shiga.jp -akagi.shimane.jp -ama.shimane.jp -gotsu.shimane.jp -hamada.shimane.jp -higashiizumo.shimane.jp -hikawa.shimane.jp -hikimi.shimane.jp -izumo.shimane.jp -kakinoki.shimane.jp -masuda.shimane.jp -matsue.shimane.jp -misato.shimane.jp -nishinoshima.shimane.jp -ohda.shimane.jp -okinoshima.shimane.jp -okuizumo.shimane.jp -shimane.shimane.jp -tamayu.shimane.jp -tsuwano.shimane.jp -unnan.shimane.jp -yakumo.shimane.jp -yasugi.shimane.jp -yatsuka.shimane.jp -arai.shizuoka.jp -atami.shizuoka.jp -fuji.shizuoka.jp -fujieda.shizuoka.jp -fujikawa.shizuoka.jp -fujinomiya.shizuoka.jp -fukuroi.shizuoka.jp -gotemba.shizuoka.jp -haibara.shizuoka.jp -hamamatsu.shizuoka.jp -higashiizu.shizuoka.jp -ito.shizuoka.jp -iwata.shizuoka.jp -izu.shizuoka.jp -izunokuni.shizuoka.jp -kakegawa.shizuoka.jp -kannami.shizuoka.jp -kawanehon.shizuoka.jp -kawazu.shizuoka.jp -kikugawa.shizuoka.jp -kosai.shizuoka.jp -makinohara.shizuoka.jp -matsuzaki.shizuoka.jp -minamiizu.shizuoka.jp -mishima.shizuoka.jp -morimachi.shizuoka.jp -nishiizu.shizuoka.jp -numazu.shizuoka.jp -omaezaki.shizuoka.jp -shimada.shizuoka.jp -shimizu.shizuoka.jp -shimoda.shizuoka.jp -shizuoka.shizuoka.jp -susono.shizuoka.jp -yaizu.shizuoka.jp -yoshida.shizuoka.jp -ashikaga.tochigi.jp -bato.tochigi.jp -haga.tochigi.jp -ichikai.tochigi.jp -iwafune.tochigi.jp -kaminokawa.tochigi.jp -kanuma.tochigi.jp -karasuyama.tochigi.jp -kuroiso.tochigi.jp -mashiko.tochigi.jp -mibu.tochigi.jp -moka.tochigi.jp -motegi.tochigi.jp -nasu.tochigi.jp -nasushiobara.tochigi.jp -nikko.tochigi.jp -nishikata.tochigi.jp -nogi.tochigi.jp -ohira.tochigi.jp -ohtawara.tochigi.jp -oyama.tochigi.jp -sakura.tochigi.jp -sano.tochigi.jp -shimotsuke.tochigi.jp -shioya.tochigi.jp -takanezawa.tochigi.jp -tochigi.tochigi.jp -tsuga.tochigi.jp -ujiie.tochigi.jp -utsunomiya.tochigi.jp -yaita.tochigi.jp -aizumi.tokushima.jp -anan.tokushima.jp -ichiba.tokushima.jp -itano.tokushima.jp -kainan.tokushima.jp -komatsushima.tokushima.jp -matsushige.tokushima.jp -mima.tokushima.jp -minami.tokushima.jp -miyoshi.tokushima.jp -mugi.tokushima.jp -nakagawa.tokushima.jp -naruto.tokushima.jp -sanagochi.tokushima.jp -shishikui.tokushima.jp -tokushima.tokushima.jp -wajiki.tokushima.jp -adachi.tokyo.jp -akiruno.tokyo.jp -akishima.tokyo.jp -aogashima.tokyo.jp -arakawa.tokyo.jp -bunkyo.tokyo.jp -chiyoda.tokyo.jp -chofu.tokyo.jp -chuo.tokyo.jp -edogawa.tokyo.jp -fuchu.tokyo.jp -fussa.tokyo.jp -hachijo.tokyo.jp -hachioji.tokyo.jp -hamura.tokyo.jp -higashikurume.tokyo.jp -higashimurayama.tokyo.jp -higashiyamato.tokyo.jp -hino.tokyo.jp -hinode.tokyo.jp -hinohara.tokyo.jp -inagi.tokyo.jp -itabashi.tokyo.jp -katsushika.tokyo.jp -kita.tokyo.jp -kiyose.tokyo.jp -kodaira.tokyo.jp -koganei.tokyo.jp -kokubunji.tokyo.jp -komae.tokyo.jp -koto.tokyo.jp -kouzushima.tokyo.jp -kunitachi.tokyo.jp -machida.tokyo.jp -meguro.tokyo.jp -minato.tokyo.jp -mitaka.tokyo.jp -mizuho.tokyo.jp -musashimurayama.tokyo.jp -musashino.tokyo.jp -nakano.tokyo.jp -nerima.tokyo.jp -ogasawara.tokyo.jp -okutama.tokyo.jp -ome.tokyo.jp -oshima.tokyo.jp -ota.tokyo.jp -setagaya.tokyo.jp -shibuya.tokyo.jp -shinagawa.tokyo.jp -shinjuku.tokyo.jp -suginami.tokyo.jp -sumida.tokyo.jp -tachikawa.tokyo.jp -taito.tokyo.jp -tama.tokyo.jp -toshima.tokyo.jp -chizu.tottori.jp -hino.tottori.jp -kawahara.tottori.jp -koge.tottori.jp -kotoura.tottori.jp -misasa.tottori.jp -nanbu.tottori.jp -nichinan.tottori.jp -sakaiminato.tottori.jp -tottori.tottori.jp -wakasa.tottori.jp -yazu.tottori.jp -yonago.tottori.jp -asahi.toyama.jp -fuchu.toyama.jp -fukumitsu.toyama.jp -funahashi.toyama.jp -himi.toyama.jp -imizu.toyama.jp -inami.toyama.jp -johana.toyama.jp -kamiichi.toyama.jp -kurobe.toyama.jp -nakaniikawa.toyama.jp -namerikawa.toyama.jp -nanto.toyama.jp -nyuzen.toyama.jp -oyabe.toyama.jp -taira.toyama.jp -takaoka.toyama.jp -tateyama.toyama.jp -toga.toyama.jp -tonami.toyama.jp -toyama.toyama.jp -unazuki.toyama.jp -uozu.toyama.jp -yamada.toyama.jp -arida.wakayama.jp -aridagawa.wakayama.jp -gobo.wakayama.jp -hashimoto.wakayama.jp -hidaka.wakayama.jp -hirogawa.wakayama.jp -inami.wakayama.jp -iwade.wakayama.jp -kainan.wakayama.jp -kamitonda.wakayama.jp -katsuragi.wakayama.jp -kimino.wakayama.jp -kinokawa.wakayama.jp -kitayama.wakayama.jp -koya.wakayama.jp -koza.wakayama.jp -kozagawa.wakayama.jp -kudoyama.wakayama.jp -kushimoto.wakayama.jp -mihama.wakayama.jp -misato.wakayama.jp -nachikatsuura.wakayama.jp -shingu.wakayama.jp -shirahama.wakayama.jp -taiji.wakayama.jp -tanabe.wakayama.jp -wakayama.wakayama.jp -yuasa.wakayama.jp -yura.wakayama.jp -asahi.yamagata.jp -funagata.yamagata.jp -higashine.yamagata.jp -iide.yamagata.jp -kahoku.yamagata.jp -kaminoyama.yamagata.jp -kaneyama.yamagata.jp -kawanishi.yamagata.jp -mamurogawa.yamagata.jp -mikawa.yamagata.jp -murayama.yamagata.jp -nagai.yamagata.jp -nakayama.yamagata.jp -nanyo.yamagata.jp -nishikawa.yamagata.jp -obanazawa.yamagata.jp -oe.yamagata.jp -oguni.yamagata.jp -ohkura.yamagata.jp -oishida.yamagata.jp -sagae.yamagata.jp -sakata.yamagata.jp -sakegawa.yamagata.jp -shinjo.yamagata.jp -shirataka.yamagata.jp -shonai.yamagata.jp -takahata.yamagata.jp -tendo.yamagata.jp -tozawa.yamagata.jp -tsuruoka.yamagata.jp -yamagata.yamagata.jp -yamanobe.yamagata.jp -yonezawa.yamagata.jp -yuza.yamagata.jp -abu.yamaguchi.jp -hagi.yamaguchi.jp -hikari.yamaguchi.jp -hofu.yamaguchi.jp -iwakuni.yamaguchi.jp -kudamatsu.yamaguchi.jp -mitou.yamaguchi.jp -nagato.yamaguchi.jp -oshima.yamaguchi.jp -shimonoseki.yamaguchi.jp -shunan.yamaguchi.jp -tabuse.yamaguchi.jp -tokuyama.yamaguchi.jp -toyota.yamaguchi.jp -ube.yamaguchi.jp -yuu.yamaguchi.jp -chuo.yamanashi.jp -doshi.yamanashi.jp -fuefuki.yamanashi.jp -fujikawa.yamanashi.jp -fujikawaguchiko.yamanashi.jp -fujiyoshida.yamanashi.jp -hayakawa.yamanashi.jp -hokuto.yamanashi.jp -ichikawamisato.yamanashi.jp -kai.yamanashi.jp -kofu.yamanashi.jp -koshu.yamanashi.jp -kosuge.yamanashi.jp -minami-alps.yamanashi.jp -minobu.yamanashi.jp -nakamichi.yamanashi.jp -nanbu.yamanashi.jp -narusawa.yamanashi.jp -nirasaki.yamanashi.jp -nishikatsura.yamanashi.jp -oshino.yamanashi.jp -otsuki.yamanashi.jp -showa.yamanashi.jp -tabayama.yamanashi.jp -tsuru.yamanashi.jp -uenohara.yamanashi.jp -yamanakako.yamanashi.jp -yamanashi.yamanashi.jp - -// ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains -ke -ac.ke -co.ke -go.ke -info.ke -me.ke -mobi.ke -ne.ke -or.ke -sc.ke - -// kg : http://www.domain.kg/dmn_n.html -kg -com.kg -edu.kg -gov.kg -mil.kg -net.kg -org.kg - -// kh : http://www.mptc.gov.kh/dns_registration.htm -*.kh - -// ki : https://www.iana.org/domains/root/db/ki.html -ki -biz.ki -com.ki -edu.ki -gov.ki -info.ki -net.ki -org.ki - -// km : https://www.iana.org/domains/root/db/km.html -// http://www.domaine.km/documents/charte.doc -km -ass.km -com.km -edu.km -gov.km -mil.km -nom.km -org.km -prd.km -tm.km -// These are only mentioned as proposed suggestions at domaine.km, but -// https://www.iana.org/domains/root/db/km.html says they're available for registration: -asso.km -coop.km -gouv.km -medecin.km -notaires.km -pharmaciens.km -presse.km -veterinaire.km - -// kn : https://www.iana.org/domains/root/db/kn.html -// http://www.dot.kn/domainRules.html -kn -edu.kn -gov.kn -net.kn -org.kn - -// kp : http://www.kcce.kp/en_index.php -kp -com.kp -edu.kp -gov.kp -org.kp -rep.kp -tra.kp - -// kr : https://www.iana.org/domains/root/db/kr.html -// see also: https://krnic.kisa.or.kr/jsp/infoboard/law/domBylawsReg.jsp -kr -ac.kr -ai.kr -co.kr -es.kr -go.kr -hs.kr -io.kr -it.kr -kg.kr -me.kr -mil.kr -ms.kr -ne.kr -or.kr -pe.kr -re.kr -sc.kr -// kr geographical names -busan.kr -chungbuk.kr -chungnam.kr -daegu.kr -daejeon.kr -gangwon.kr -gwangju.kr -gyeongbuk.kr -gyeonggi.kr -gyeongnam.kr -incheon.kr -jeju.kr -jeonbuk.kr -jeonnam.kr -seoul.kr -ulsan.kr - -// kw : https://www.nic.kw/policies/ -// Confirmed by registry -kw -com.kw -edu.kw -emb.kw -gov.kw -ind.kw -net.kw -org.kw - -// ky : http://www.icta.ky/da_ky_reg_dom.php -// Confirmed by registry 2008-06-17 -ky -com.ky -edu.ky -net.ky -org.ky - -// kz : https://www.iana.org/domains/root/db/kz.html -// see also: http://www.nic.kz/rules/index.jsp -kz -com.kz -edu.kz -gov.kz -mil.kz -net.kz -org.kz - -// la : https://www.iana.org/domains/root/db/la.html -// Submitted by registry -la -com.la -edu.la -gov.la -info.la -int.la -net.la -org.la -per.la - -// lb : https://www.iana.org/domains/root/db/lb.html -// Submitted by registry -lb -com.lb -edu.lb -gov.lb -net.lb -org.lb - -// lc : https://www.iana.org/domains/root/db/lc.html -// see also: http://www.nic.lc/rules.htm -lc -co.lc -com.lc -edu.lc -gov.lc -net.lc -org.lc - -// li : https://www.iana.org/domains/root/db/li.html -li - -// lk : https://www.iana.org/domains/root/db/lk.html -lk -ac.lk -assn.lk -com.lk -edu.lk -gov.lk -grp.lk -hotel.lk -int.lk -ltd.lk -net.lk -ngo.lk -org.lk -sch.lk -soc.lk -web.lk - -// lr : http://psg.com/dns/lr/lr.txt -// Submitted by registry -lr -com.lr -edu.lr -gov.lr -net.lr -org.lr - -// ls : http://www.nic.ls/ -// Confirmed by registry -ls -ac.ls -biz.ls -co.ls -edu.ls -gov.ls -info.ls -net.ls -org.ls -sc.ls - -// lt : https://www.iana.org/domains/root/db/lt.html -lt -// gov.lt : http://www.gov.lt/index_en.php -gov.lt - -// lu : http://www.dns.lu/en/ -lu - -// lv : https://www.iana.org/domains/root/db/lv.html -lv -asn.lv -com.lv -conf.lv -edu.lv -gov.lv -id.lv -mil.lv -net.lv -org.lv - -// ly : http://www.nic.ly/regulations.php -ly -com.ly -edu.ly -gov.ly -id.ly -med.ly -net.ly -org.ly -plc.ly -sch.ly - -// ma : https://www.iana.org/domains/root/db/ma.html -// http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf -ma -ac.ma -co.ma -gov.ma -net.ma -org.ma -press.ma - -// mc : http://www.nic.mc/ -mc -asso.mc -tm.mc - -// md : https://www.iana.org/domains/root/db/md.html -md - -// me : https://www.iana.org/domains/root/db/me.html -me -ac.me -co.me -edu.me -gov.me -its.me -net.me -org.me -priv.me - -// mg : https://nic.mg -mg -co.mg -com.mg -edu.mg -gov.mg -mil.mg -nom.mg -org.mg -prd.mg - -// mh : https://www.iana.org/domains/root/db/mh.html -mh - -// mil : https://www.iana.org/domains/root/db/mil.html -mil - -// mk : https://www.iana.org/domains/root/db/mk.html -// see also: http://dns.marnet.net.mk/postapka.php -mk -com.mk -edu.mk -gov.mk -inf.mk -name.mk -net.mk -org.mk - -// ml : https://www.iana.org/domains/root/db/ml.html -// Confirmed by Boubacar NDIAYE 2024-12-31 -ml -ac.ml -art.ml -asso.ml -com.ml -edu.ml -gouv.ml -gov.ml -info.ml -inst.ml -net.ml -org.ml -pr.ml -presse.ml - -// mm : https://www.iana.org/domains/root/db/mm.html -*.mm - -// mn : https://www.iana.org/domains/root/db/mn.html -mn -edu.mn -gov.mn -org.mn - -// mo : http://www.monic.net.mo/ -mo -com.mo -edu.mo -gov.mo -net.mo -org.mo - -// mobi : https://www.iana.org/domains/root/db/mobi.html -mobi - -// mp : http://www.dot.mp/ -// Confirmed by registry 2008-06-17 -mp - -// mq : https://www.iana.org/domains/root/db/mq.html -mq - -// mr : https://www.iana.org/domains/root/db/mr.html -mr -gov.mr - -// ms : https://www.iana.org/domains/root/db/ms.html -ms -com.ms -edu.ms -gov.ms -net.ms -org.ms - -// mt : https://www.nic.org.mt/go/policy -// Submitted by registry -mt -com.mt -edu.mt -net.mt -org.mt - -// mu : https://www.iana.org/domains/root/db/mu.html -mu -ac.mu -co.mu -com.mu -gov.mu -net.mu -or.mu -org.mu - -// museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ -museum - -// mv : https://www.iana.org/domains/root/db/mv.html -// "mv" included because, contra Wikipedia, google.mv exists. -mv -aero.mv -biz.mv -com.mv -coop.mv -edu.mv -gov.mv -info.mv -int.mv -mil.mv -museum.mv -name.mv -net.mv -org.mv -pro.mv - -// mw : http://www.registrar.mw/ -mw -ac.mw -biz.mw -co.mw -com.mw -coop.mw -edu.mw -gov.mw -int.mw -net.mw -org.mw - -// mx : http://www.nic.mx/ -// Submitted by registry -mx -com.mx -edu.mx -gob.mx -net.mx -org.mx - -// my : http://www.mynic.my/ -// Available strings: https://mynic.my/resources/domains/buying-a-domain/ -my -biz.my -com.my -edu.my -gov.my -mil.my -name.my -net.my -org.my - -// mz : http://www.uem.mz/ -// Submitted by registry -mz -ac.mz -adv.mz -co.mz -edu.mz -gov.mz -mil.mz -net.mz -org.mz - -// na : http://www.na-nic.com.na/ -na -alt.na -co.na -com.na -gov.na -net.na -org.na - -// name : http://www.nic.name/ -// Regarding 2LDs: https://github.com/publicsuffix/list/issues/2306 -name - -// nc : http://www.cctld.nc/ -nc -asso.nc -nom.nc - -// ne : https://www.iana.org/domains/root/db/ne.html -ne - -// net : https://www.iana.org/domains/root/db/net.html -net - -// nf : https://www.iana.org/domains/root/db/nf.html -nf -arts.nf -com.nf -firm.nf -info.nf -net.nf -other.nf -per.nf -rec.nf -store.nf -web.nf - -// ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds -ng -com.ng -edu.ng -gov.ng -i.ng -mil.ng -mobi.ng -name.ng -net.ng -org.ng -sch.ng - -// ni : http://www.nic.ni/ -ni -ac.ni -biz.ni -co.ni -com.ni -edu.ni -gob.ni -in.ni -info.ni -int.ni -mil.ni -net.ni -nom.ni -org.ni -web.ni - -// nl : https://www.iana.org/domains/root/db/nl.html -// https://www.sidn.nl/ -nl - -// no : https://www.norid.no/en/om-domenenavn/regelverk-for-no/ -// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ -// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ -// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ -// RSS feed: https://teknisk.norid.no/en/feed/ -no -// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ -fhs.no -folkebibl.no -fylkesbibl.no -idrett.no -museum.no -priv.no -vgs.no -// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ -dep.no -herad.no -kommune.no -mil.no -stat.no -// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ -// counties -aa.no -ah.no -bu.no -fm.no -hl.no -hm.no -jan-mayen.no -mr.no -nl.no -nt.no -of.no -ol.no -oslo.no -rl.no -sf.no -st.no -svalbard.no -tm.no -tr.no -va.no -vf.no -// primary and lower secondary schools per county -gs.aa.no -gs.ah.no -gs.bu.no -gs.fm.no -gs.hl.no -gs.hm.no -gs.jan-mayen.no -gs.mr.no -gs.nl.no -gs.nt.no -gs.of.no -gs.ol.no -gs.oslo.no -gs.rl.no -gs.sf.no -gs.st.no -gs.svalbard.no -gs.tm.no -gs.tr.no -gs.va.no -gs.vf.no -// cities -akrehamn.no -åkrehamn.no -algard.no -ålgård.no -arna.no -bronnoysund.no -brønnøysund.no -brumunddal.no -bryne.no -drobak.no -drøbak.no -egersund.no -fetsund.no -floro.no -florø.no -fredrikstad.no -hokksund.no -honefoss.no -hønefoss.no -jessheim.no -jorpeland.no -jørpeland.no -kirkenes.no -kopervik.no -krokstadelva.no -langevag.no -langevåg.no -leirvik.no -mjondalen.no -mjøndalen.no -mo-i-rana.no -mosjoen.no -mosjøen.no -nesoddtangen.no -orkanger.no -osoyro.no -osøyro.no -raholt.no -råholt.no -sandnessjoen.no -sandnessjøen.no -skedsmokorset.no -slattum.no -spjelkavik.no -stathelle.no -stavern.no -stjordalshalsen.no -stjørdalshalsen.no -tananger.no -tranby.no -vossevangen.no -// communities -aarborte.no -aejrie.no -afjord.no -åfjord.no -agdenes.no -nes.akershus.no -aknoluokta.no -ákŋoluokta.no -al.no -ål.no -alaheadju.no -álaheadju.no -alesund.no -ålesund.no -alstahaug.no -alta.no -áltá.no -alvdal.no -amli.no -åmli.no -amot.no -åmot.no -andasuolo.no -andebu.no -andoy.no -andøy.no -ardal.no -årdal.no -aremark.no -arendal.no -ås.no -aseral.no -åseral.no -asker.no -askim.no -askoy.no -askøy.no -askvoll.no -asnes.no -åsnes.no -audnedaln.no -aukra.no -aure.no -aurland.no -aurskog-holand.no -aurskog-høland.no -austevoll.no -austrheim.no -averoy.no -averøy.no -badaddja.no -bådåddjå.no -bærum.no -bahcavuotna.no -báhcavuotna.no -bahccavuotna.no -báhccavuotna.no -baidar.no -báidár.no -bajddar.no -bájddar.no -balat.no -bálát.no -balestrand.no -ballangen.no -balsfjord.no -bamble.no -bardu.no -barum.no -batsfjord.no -båtsfjord.no -bearalvahki.no -bearalváhki.no -beardu.no -beiarn.no -berg.no -bergen.no -berlevag.no -berlevåg.no -bievat.no -bievát.no -bindal.no -birkenes.no -bjerkreim.no -bjugn.no -bodo.no -bodø.no -bokn.no -bomlo.no -bømlo.no -bremanger.no -bronnoy.no -brønnøy.no -budejju.no -nes.buskerud.no -bygland.no -bykle.no -cahcesuolo.no -čáhcesuolo.no -davvenjarga.no -davvenjárga.no -davvesiida.no -deatnu.no -dielddanuorri.no -divtasvuodna.no -divttasvuotna.no -donna.no -dønna.no -dovre.no -drammen.no -drangedal.no -dyroy.no -dyrøy.no -eid.no -eidfjord.no -eidsberg.no -eidskog.no -eidsvoll.no -eigersund.no -elverum.no -enebakk.no -engerdal.no -etne.no -etnedal.no -evenassi.no -evenášši.no -evenes.no -evje-og-hornnes.no -farsund.no -fauske.no -fedje.no -fet.no -finnoy.no -finnøy.no -fitjar.no -fjaler.no -fjell.no -fla.no -flå.no -flakstad.no -flatanger.no -flekkefjord.no -flesberg.no -flora.no -folldal.no -forde.no -førde.no -forsand.no -fosnes.no -fræna.no -frana.no -frei.no -frogn.no -froland.no -frosta.no -froya.no -frøya.no -fuoisku.no -fuossko.no -fusa.no -fyresdal.no -gaivuotna.no -gáivuotna.no -galsa.no -gálsá.no -gamvik.no -gangaviika.no -gáŋgaviika.no -gaular.no -gausdal.no -giehtavuoatna.no -gildeskal.no -gildeskål.no -giske.no -gjemnes.no -gjerdrum.no -gjerstad.no -gjesdal.no -gjovik.no -gjøvik.no -gloppen.no -gol.no -gran.no -grane.no -granvin.no -gratangen.no -grimstad.no -grong.no -grue.no -gulen.no -guovdageaidnu.no -ha.no -hå.no -habmer.no -hábmer.no -hadsel.no -hægebostad.no -hagebostad.no -halden.no -halsa.no -hamar.no -hamaroy.no -hammarfeasta.no -hámmárfeasta.no -hammerfest.no -hapmir.no -hápmir.no -haram.no -hareid.no -harstad.no -hasvik.no -hattfjelldal.no -haugesund.no -os.hedmark.no -valer.hedmark.no -våler.hedmark.no -hemne.no -hemnes.no -hemsedal.no -hitra.no -hjartdal.no -hjelmeland.no -hobol.no -hobøl.no -hof.no -hol.no -hole.no -holmestrand.no -holtalen.no -holtålen.no -os.hordaland.no -hornindal.no -horten.no -hoyanger.no -høyanger.no -hoylandet.no -høylandet.no -hurdal.no -hurum.no -hvaler.no -hyllestad.no -ibestad.no -inderoy.no -inderøy.no -iveland.no -ivgu.no -jevnaker.no -jolster.no -jølster.no -jondal.no -kafjord.no -kåfjord.no -karasjohka.no -kárášjohka.no -karasjok.no -karlsoy.no -karmoy.no -karmøy.no -kautokeino.no -klabu.no -klæbu.no -klepp.no -kongsberg.no -kongsvinger.no -kraanghke.no -kråanghke.no -kragero.no -kragerø.no -kristiansand.no -kristiansund.no -krodsherad.no -krødsherad.no -kvæfjord.no -kvænangen.no -kvafjord.no -kvalsund.no -kvam.no -kvanangen.no -kvinesdal.no -kvinnherad.no -kviteseid.no -kvitsoy.no -kvitsøy.no -laakesvuemie.no -lærdal.no -lahppi.no -láhppi.no -lardal.no -larvik.no -lavagis.no -lavangen.no -leangaviika.no -leaŋgaviika.no -lebesby.no -leikanger.no -leirfjord.no -leka.no -leksvik.no -lenvik.no -lerdal.no -lesja.no -levanger.no -lier.no -lierne.no -lillehammer.no -lillesand.no -lindas.no -lindås.no -lindesnes.no -loabat.no -loabát.no -lodingen.no -lødingen.no -lom.no -loppa.no -lorenskog.no -lørenskog.no -loten.no -løten.no -lund.no -lunner.no -luroy.no -lurøy.no -luster.no -lyngdal.no -lyngen.no -malatvuopmi.no -málatvuopmi.no -malselv.no -målselv.no -malvik.no -mandal.no -marker.no -marnardal.no -masfjorden.no -masoy.no -måsøy.no -matta-varjjat.no -mátta-várjjat.no -meland.no -meldal.no -melhus.no -meloy.no -meløy.no -meraker.no -meråker.no -midsund.no -midtre-gauldal.no -moareke.no -moåreke.no -modalen.no -modum.no -molde.no -heroy.more-og-romsdal.no -sande.more-og-romsdal.no -herøy.møre-og-romsdal.no -sande.møre-og-romsdal.no -moskenes.no -moss.no -muosat.no -muosát.no -naamesjevuemie.no -nååmesjevuemie.no -nærøy.no -namdalseid.no -namsos.no -namsskogan.no -nannestad.no -naroy.no -narviika.no -narvik.no -naustdal.no -navuotna.no -návuotna.no -nedre-eiker.no -nesna.no -nesodden.no -nesseby.no -nesset.no -nissedal.no -nittedal.no -nord-aurdal.no -nord-fron.no -nord-odal.no -norddal.no -nordkapp.no -bo.nordland.no -bø.nordland.no -heroy.nordland.no -herøy.nordland.no -nordre-land.no -nordreisa.no -nore-og-uvdal.no -notodden.no -notteroy.no -nøtterøy.no -odda.no -oksnes.no -øksnes.no -omasvuotna.no -oppdal.no -oppegard.no -oppegård.no -orkdal.no -orland.no -ørland.no -orskog.no -ørskog.no -orsta.no -ørsta.no -osen.no -osteroy.no -osterøy.no -valer.ostfold.no -våler.østfold.no -ostre-toten.no -østre-toten.no -overhalla.no -ovre-eiker.no -øvre-eiker.no -oyer.no -øyer.no -oygarden.no -øygarden.no -oystre-slidre.no -øystre-slidre.no -porsanger.no -porsangu.no -porsáŋgu.no -porsgrunn.no -rade.no -råde.no -radoy.no -radøy.no -rælingen.no -rahkkeravju.no -ráhkkerávju.no -raisa.no -ráisa.no -rakkestad.no -ralingen.no -rana.no -randaberg.no -rauma.no -rendalen.no -rennebu.no -rennesoy.no -rennesøy.no -rindal.no -ringebu.no -ringerike.no -ringsaker.no -risor.no -risør.no -rissa.no -roan.no -rodoy.no -rødøy.no -rollag.no -romsa.no -romskog.no -rømskog.no -roros.no -røros.no -rost.no -røst.no -royken.no -røyken.no -royrvik.no -røyrvik.no -ruovat.no -rygge.no -salangen.no -salat.no -sálat.no -sálát.no -saltdal.no -samnanger.no -sandefjord.no -sandnes.no -sandoy.no -sandøy.no -sarpsborg.no -sauda.no -sauherad.no -sel.no -selbu.no -selje.no -seljord.no -siellak.no -sigdal.no -siljan.no -sirdal.no -skanit.no -skánit.no -skanland.no -skånland.no -skaun.no -skedsmo.no -ski.no -skien.no -skierva.no -skiervá.no -skiptvet.no -skjak.no -skjåk.no -skjervoy.no -skjervøy.no -skodje.no -smola.no -smøla.no -snaase.no -snåase.no -snasa.no -snåsa.no -snillfjord.no -snoasa.no -sogndal.no -sogne.no -søgne.no -sokndal.no -sola.no -solund.no -somna.no -sømna.no -sondre-land.no -søndre-land.no -songdalen.no -sor-aurdal.no -sør-aurdal.no -sor-fron.no -sør-fron.no -sor-odal.no -sør-odal.no -sor-varanger.no -sør-varanger.no -sorfold.no -sørfold.no -sorreisa.no -sørreisa.no -sortland.no -sorum.no -sørum.no -spydeberg.no -stange.no -stavanger.no -steigen.no -steinkjer.no -stjordal.no -stjørdal.no -stokke.no -stor-elvdal.no -stord.no -stordal.no -storfjord.no -strand.no -stranda.no -stryn.no -sula.no -suldal.no -sund.no -sunndal.no -surnadal.no -sveio.no -svelvik.no -sykkylven.no -tana.no -bo.telemark.no -bø.telemark.no -time.no -tingvoll.no -tinn.no -tjeldsund.no -tjome.no -tjøme.no -tokke.no -tolga.no -tonsberg.no -tønsberg.no -torsken.no -træna.no -trana.no -tranoy.no -tranøy.no -troandin.no -trogstad.no -trøgstad.no -tromsa.no -tromso.no -tromsø.no -trondheim.no -trysil.no -tvedestrand.no -tydal.no -tynset.no -tysfjord.no -tysnes.no -tysvær.no -tysvar.no -ullensaker.no -ullensvang.no -ulvik.no -unjarga.no -unjárga.no -utsira.no -vaapste.no -vadso.no -vadsø.no -værøy.no -vaga.no -vågå.no -vagan.no -vågan.no -vagsoy.no -vågsøy.no -vaksdal.no -valle.no -vang.no -vanylven.no -vardo.no -vardø.no -varggat.no -várggát.no -varoy.no -vefsn.no -vega.no -vegarshei.no -vegårshei.no -vennesla.no -verdal.no -verran.no -vestby.no -sande.vestfold.no -vestnes.no -vestre-slidre.no -vestre-toten.no -vestvagoy.no -vestvågøy.no -vevelstad.no -vik.no -vikna.no -vindafjord.no -voagat.no -volda.no -voss.no - -// np : http://www.mos.com.np/register.html -*.np - -// nr : http://cenpac.net.nr/dns/index.html -// Submitted by registry -nr -biz.nr -com.nr -edu.nr -gov.nr -info.nr -net.nr -org.nr - -// nu : https://www.iana.org/domains/root/db/nu.html -nu - -// nz : https://www.iana.org/domains/root/db/nz.html -// Submitted by registry -nz -ac.nz -co.nz -cri.nz -geek.nz -gen.nz -govt.nz -health.nz -iwi.nz -kiwi.nz -maori.nz -māori.nz -mil.nz -net.nz -org.nz -parliament.nz -school.nz - -// om : https://www.iana.org/domains/root/db/om.html -om -co.om -com.om -edu.om -gov.om -med.om -museum.om -net.om -org.om -pro.om - -// onion : https://tools.ietf.org/html/rfc7686 -onion - -// org : https://www.iana.org/domains/root/db/org.html -org - -// pa : http://www.nic.pa/ -// Some additional second level "domains" resolve directly as hostnames, such as -// pannet.pa, so we add a rule for "pa". -pa -abo.pa -ac.pa -com.pa -edu.pa -gob.pa -ing.pa -med.pa -net.pa -nom.pa -org.pa -sld.pa - -// pe : https://www.nic.pe/InformeFinalComision.pdf -pe -com.pe -edu.pe -gob.pe -mil.pe -net.pe -nom.pe -org.pe - -// pf : http://www.gobin.info/domainname/formulaire-pf.pdf -pf -com.pf -edu.pf -org.pf - -// pg : https://www.iana.org/domains/root/db/pg.html -*.pg - -// ph : https://www.iana.org/domains/root/db/ph.html -// Submitted by registry -ph -com.ph -edu.ph -gov.ph -i.ph -mil.ph -net.ph -ngo.ph -org.ph - -// pk : https://pk5.pknic.net.pk/pk5/msgNamepk.PK -// Contact Email: staff@pknic.net.pk -pk -ac.pk -biz.pk -com.pk -edu.pk -fam.pk -gkp.pk -gob.pk -gog.pk -gok.pk -gop.pk -gos.pk -gov.pk -net.pk -org.pk -web.pk - -// pl : https://www.dns.pl/en/ -// Confirmed by registry 2024-11-18 -pl -com.pl -net.pl -org.pl -// pl functional domains : https://www.dns.pl/en/list_of_functional_domain_names -agro.pl -aid.pl -atm.pl -auto.pl -biz.pl -edu.pl -gmina.pl -gsm.pl -info.pl -mail.pl -media.pl -miasta.pl -mil.pl -nieruchomosci.pl -nom.pl -pc.pl -powiat.pl -priv.pl -realestate.pl -rel.pl -sex.pl -shop.pl -sklep.pl -sos.pl -szkola.pl -targi.pl -tm.pl -tourism.pl -travel.pl -turystyka.pl -// Government domains : https://www.dns.pl/informacje_o_rejestracji_domen_gov_pl -// In accordance with the .gov.pl Domain Name Regulations : https://www.dns.pl/regulamin_gov_pl -gov.pl -ap.gov.pl -griw.gov.pl -ic.gov.pl -is.gov.pl -kmpsp.gov.pl -konsulat.gov.pl -kppsp.gov.pl -kwp.gov.pl -kwpsp.gov.pl -mup.gov.pl -mw.gov.pl -oia.gov.pl -oirm.gov.pl -oke.gov.pl -oow.gov.pl -oschr.gov.pl -oum.gov.pl -pa.gov.pl -pinb.gov.pl -piw.gov.pl -po.gov.pl -pr.gov.pl -psp.gov.pl -psse.gov.pl -pup.gov.pl -rzgw.gov.pl -sa.gov.pl -sdn.gov.pl -sko.gov.pl -so.gov.pl -sr.gov.pl -starostwo.gov.pl -ug.gov.pl -ugim.gov.pl -um.gov.pl -umig.gov.pl -upow.gov.pl -uppo.gov.pl -us.gov.pl -uw.gov.pl -uzs.gov.pl -wif.gov.pl -wiih.gov.pl -winb.gov.pl -wios.gov.pl -witd.gov.pl -wiw.gov.pl -wkz.gov.pl -wsa.gov.pl -wskr.gov.pl -wsse.gov.pl -wuoz.gov.pl -wzmiuw.gov.pl -zp.gov.pl -zpisdn.gov.pl -// pl regional domains : https://www.dns.pl/en/list_of_regional_domain_names -augustow.pl -babia-gora.pl -bedzin.pl -beskidy.pl -bialowieza.pl -bialystok.pl -bielawa.pl -bieszczady.pl -boleslawiec.pl -bydgoszcz.pl -bytom.pl -cieszyn.pl -czeladz.pl -czest.pl -dlugoleka.pl -elblag.pl -elk.pl -glogow.pl -gniezno.pl -gorlice.pl -grajewo.pl -ilawa.pl -jaworzno.pl -jelenia-gora.pl -jgora.pl -kalisz.pl -karpacz.pl -kartuzy.pl -kaszuby.pl -katowice.pl -kazimierz-dolny.pl -kepno.pl -ketrzyn.pl -klodzko.pl -kobierzyce.pl -kolobrzeg.pl -konin.pl -konskowola.pl -kutno.pl -lapy.pl -lebork.pl -legnica.pl -lezajsk.pl -limanowa.pl -lomza.pl -lowicz.pl -lubin.pl -lukow.pl -malbork.pl -malopolska.pl -mazowsze.pl -mazury.pl -mielec.pl -mielno.pl -mragowo.pl -naklo.pl -nowaruda.pl -nysa.pl -olawa.pl -olecko.pl -olkusz.pl -olsztyn.pl -opoczno.pl -opole.pl -ostroda.pl -ostroleka.pl -ostrowiec.pl -ostrowwlkp.pl -pila.pl -pisz.pl -podhale.pl -podlasie.pl -polkowice.pl -pomorskie.pl -pomorze.pl -prochowice.pl -pruszkow.pl -przeworsk.pl -pulawy.pl -radom.pl -rawa-maz.pl -rybnik.pl -rzeszow.pl -sanok.pl -sejny.pl -skoczow.pl -slask.pl -slupsk.pl -sosnowiec.pl -stalowa-wola.pl -starachowice.pl -stargard.pl -suwalki.pl -swidnica.pl -swiebodzin.pl -swinoujscie.pl -szczecin.pl -szczytno.pl -tarnobrzeg.pl -tgory.pl -turek.pl -tychy.pl -ustka.pl -walbrzych.pl -warmia.pl -warszawa.pl -waw.pl -wegrow.pl -wielun.pl -wlocl.pl -wloclawek.pl -wodzislaw.pl -wolomin.pl -wroclaw.pl -zachpomor.pl -zagan.pl -zarow.pl -zgora.pl -zgorzelec.pl - -// pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -pm - -// pn : https://www.iana.org/domains/root/db/pn.html -pn -co.pn -edu.pn -gov.pn -net.pn -org.pn - -// post : https://www.iana.org/domains/root/db/post.html -post - -// pr : http://www.nic.pr/index.asp?f=1 -pr -biz.pr -com.pr -edu.pr -gov.pr -info.pr -isla.pr -name.pr -net.pr -org.pr -pro.pr -// these aren't mentioned on nic.pr, but on https://www.iana.org/domains/root/db/pr.html -ac.pr -est.pr -prof.pr - -// pro : http://registry.pro/get-pro -pro -aaa.pro -aca.pro -acct.pro -avocat.pro -bar.pro -cpa.pro -eng.pro -jur.pro -law.pro -med.pro -recht.pro - -// ps : https://www.iana.org/domains/root/db/ps.html -// http://www.nic.ps/registration/policy.html#reg -ps -com.ps -edu.ps -gov.ps -net.ps -org.ps -plo.ps -sec.ps - -// pt : https://www.dns.pt/en/domain/pt-terms-and-conditions-registration-rules/ -pt -com.pt -edu.pt -gov.pt -int.pt -net.pt -nome.pt -org.pt -publ.pt - -// pw : https://www.iana.org/domains/root/db/pw.html -// Confirmed by registry in private correspondence with @dnsguru 2024-12-09 -pw -gov.pw - -// py : https://www.iana.org/domains/root/db/py.html -// Submitted by registry -py -com.py -coop.py -edu.py -gov.py -mil.py -net.py -org.py - -// qa : http://domains.qa/en/ -qa -com.qa -edu.qa -gov.qa -mil.qa -name.qa -net.qa -org.qa -sch.qa - -// re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -// Confirmed by registry 2024-11-18 -re -// Closed for registration on 2013-03-15 but domains are still maintained -asso.re -com.re - -// ro : http://www.rotld.ro/ -ro -arts.ro -com.ro -firm.ro -info.ro -nom.ro -nt.ro -org.ro -rec.ro -store.ro -tm.ro -www.ro - -// rs : https://www.rnids.rs/en/domains/national-domains -rs -ac.rs -co.rs -edu.rs -gov.rs -in.rs -org.rs - -// ru : https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf -// Submitted by George Georgievsky -ru - -// rw : https://www.iana.org/domains/root/db/rw.html -rw -ac.rw -co.rw -coop.rw -gov.rw -mil.rw -net.rw -org.rw - -// sa : http://www.nic.net.sa/ -sa -com.sa -edu.sa -gov.sa -med.sa -net.sa -org.sa -pub.sa -sch.sa - -// sb : http://www.sbnic.net.sb/ -// Submitted by registry -sb -com.sb -edu.sb -gov.sb -net.sb -org.sb - -// sc : http://www.nic.sc/ -sc -com.sc -edu.sc -gov.sc -net.sc -org.sc - -// sd : https://www.iana.org/domains/root/db/sd.html -// Submitted by registry -sd -com.sd -edu.sd -gov.sd -info.sd -med.sd -net.sd -org.sd -tv.sd - -// se : https://www.iana.org/domains/root/db/se.html -// https://data.internetstiftelsen.se/barred_domains_list.txt -> Second level domains & Sub-domains -// Confirmed by Registry Services 2024-11-20 -se -a.se -ac.se -b.se -bd.se -brand.se -c.se -d.se -e.se -f.se -fh.se -fhsk.se -fhv.se -g.se -h.se -i.se -k.se -komforb.se -kommunalforbund.se -komvux.se -l.se -lanbib.se -m.se -n.se -naturbruksgymn.se -o.se -org.se -p.se -parti.se -pp.se -press.se -r.se -s.se -t.se -tm.se -u.se -w.se -x.se -y.se -z.se - -// sg : https://www.sgnic.sg/domain-registration/sg-categories-rules -// Confirmed by registry 2024-11-19 -sg -com.sg -edu.sg -gov.sg -net.sg -org.sg - -// sh : http://nic.sh/rules.htm -sh -com.sh -gov.sh -mil.sh -net.sh -org.sh - -// si : https://www.iana.org/domains/root/db/si.html -si - -// sj : No registrations at this time. -// Submitted by registry -sj - -// sk : https://www.iana.org/domains/root/db/sk.html -sk - -// sl : http://www.nic.sl -// Submitted by registry -sl -com.sl -edu.sl -gov.sl -net.sl -org.sl - -// sm : https://www.iana.org/domains/root/db/sm.html -sm - -// sn : https://www.iana.org/domains/root/db/sn.html -sn -art.sn -com.sn -edu.sn -gouv.sn -org.sn -perso.sn -univ.sn - -// so : http://sonic.so/policies/ -so -com.so -edu.so -gov.so -me.so -net.so -org.so - -// sr : https://www.iana.org/domains/root/db/sr.html -sr - -// ss : https://registry.nic.ss/ -// Submitted by registry -ss -biz.ss -co.ss -com.ss -edu.ss -gov.ss -me.ss -net.ss -org.ss -sch.ss - -// st : http://www.nic.st/html/policyrules/ -st -co.st -com.st -consulado.st -edu.st -embaixada.st -mil.st -net.st -org.st -principe.st -saotome.st -store.st - -// su : https://www.iana.org/domains/root/db/su.html -su - -// sv : https://www.iana.org/domains/root/db/sv.html -sv -com.sv -edu.sv -gob.sv -org.sv -red.sv - -// sx : https://www.iana.org/domains/root/db/sx.html -// Submitted by registry -sx -gov.sx - -// sy : https://www.iana.org/domains/root/db/sy.html -sy -com.sy -edu.sy -gov.sy -mil.sy -net.sy -org.sy - -// sz : https://www.iana.org/domains/root/db/sz.html -// http://www.sispa.org.sz/ -sz -ac.sz -co.sz -org.sz - -// tc : https://www.iana.org/domains/root/db/tc.html -tc - -// td : https://www.iana.org/domains/root/db/td.html -td - -// tel : https://www.iana.org/domains/root/db/tel.html -// http://www.telnic.org/ -tel - -// tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -tf - -// tg : https://www.iana.org/domains/root/db/tg.html -// http://www.nic.tg/ -tg - -// th : https://www.iana.org/domains/root/db/th.html -// Submitted by registry -th -ac.th -co.th -go.th -in.th -mi.th -net.th -or.th - -// tj : http://www.nic.tj/policy.html -tj -ac.tj -biz.tj -co.tj -com.tj -edu.tj -go.tj -gov.tj -int.tj -mil.tj -name.tj -net.tj -nic.tj -org.tj -test.tj -web.tj - -// tk : https://www.iana.org/domains/root/db/tk.html -tk - -// tl : https://www.iana.org/domains/root/db/tl.html -tl -gov.tl - -// tm : https://www.nic.tm/local.html -// Confirmed by registry 2024-11-19 -tm -co.tm -com.tm -edu.tm -gov.tm -mil.tm -net.tm -nom.tm -org.tm - -// tn : http://www.registre.tn/fr/ -// https://whois.ati.tn/ -tn -com.tn -ens.tn -fin.tn -gov.tn -ind.tn -info.tn -intl.tn -mincom.tn -nat.tn -net.tn -org.tn -perso.tn -tourism.tn - -// to : https://www.iana.org/domains/root/db/to.html -// Submitted by registry -to -com.to -edu.to -gov.to -mil.to -net.to -org.to - -// tr : https://nic.tr/ -// https://nic.tr/forms/eng/policies.pdf -// https://nic.tr/index.php?USRACTN=PRICELST -tr -av.tr -bbs.tr -bel.tr -biz.tr -com.tr -dr.tr -edu.tr -gen.tr -gov.tr -info.tr -k12.tr -kep.tr -mil.tr -name.tr -net.tr -org.tr -pol.tr -tel.tr -tsk.tr -tv.tr -web.tr -// Used by Northern Cyprus -nc.tr -// Used by government agencies of Northern Cyprus -gov.nc.tr - -// tt : https://www.nic.tt/ -// Confirmed by registry 2024-11-19 -tt -biz.tt -co.tt -com.tt -edu.tt -gov.tt -info.tt -mil.tt -name.tt -net.tt -org.tt -pro.tt - -// tv : https://www.iana.org/domains/root/db/tv.html -// Not listing any 2LDs as reserved since none seem to exist in practice, -// Wikipedia notwithstanding. -tv - -// tw : https://www.iana.org/domains/root/db/tw.html -// https://twnic.tw/dnservice_catag.php -// Confirmed by registry 2024-11-26 -tw -club.tw -com.tw -ebiz.tw -edu.tw -game.tw -gov.tw -idv.tw -mil.tw -net.tw -org.tw - -// tz : http://www.tznic.or.tz/index.php/domains -// Submitted by registry -tz -ac.tz -co.tz -go.tz -hotel.tz -info.tz -me.tz -mil.tz -mobi.tz -ne.tz -or.tz -sc.tz -tv.tz - -// ua : https://hostmaster.ua/policy/?ua -// Submitted by registry -ua -// ua 2LD -com.ua -edu.ua -gov.ua -in.ua -net.ua -org.ua -// ua geographic names -// https://hostmaster.ua/2ld/ -cherkassy.ua -cherkasy.ua -chernigov.ua -chernihiv.ua -chernivtsi.ua -chernovtsy.ua -ck.ua -cn.ua -cr.ua -crimea.ua -cv.ua -dn.ua -dnepropetrovsk.ua -dnipropetrovsk.ua -donetsk.ua -dp.ua -if.ua -ivano-frankivsk.ua -kh.ua -kharkiv.ua -kharkov.ua -kherson.ua -khmelnitskiy.ua -khmelnytskyi.ua -kiev.ua -kirovograd.ua -km.ua -kr.ua -kropyvnytskyi.ua -krym.ua -ks.ua -kv.ua -kyiv.ua -lg.ua -lt.ua -lugansk.ua -luhansk.ua -lutsk.ua -lv.ua -lviv.ua -mk.ua -mykolaiv.ua -nikolaev.ua -od.ua -odesa.ua -odessa.ua -pl.ua -poltava.ua -rivne.ua -rovno.ua -rv.ua -sb.ua -sebastopol.ua -sevastopol.ua -sm.ua -sumy.ua -te.ua -ternopil.ua -uz.ua -uzhgorod.ua -uzhhorod.ua -vinnica.ua -vinnytsia.ua -vn.ua -volyn.ua -yalta.ua -zakarpattia.ua -zaporizhzhe.ua -zaporizhzhia.ua -zhitomir.ua -zhytomyr.ua -zp.ua -zt.ua - -// ug : https://www.registry.co.ug/ -// https://www.registry.co.ug, https://whois.co.ug -// Confirmed by registry 2025-01-20 -ug -ac.ug -co.ug -com.ug -edu.ug -go.ug -gov.ug -mil.ug -ne.ug -or.ug -org.ug -sc.ug -us.ug - -// uk : https://www.iana.org/domains/root/db/uk.html -// Submitted by registry -uk -ac.uk -co.uk -gov.uk -ltd.uk -me.uk -net.uk -nhs.uk -org.uk -plc.uk -police.uk -*.sch.uk - -// us : https://www.iana.org/domains/root/db/us.html -// Confirmed via the .us zone file by William Harrison 2024-12-10 -us -dni.us -isa.us -nsn.us -// Geographic Names -ak.us -al.us -ar.us -as.us -az.us -ca.us -co.us -ct.us -dc.us -de.us -fl.us -ga.us -gu.us -hi.us -ia.us -id.us -il.us -in.us -ks.us -ky.us -la.us -ma.us -md.us -me.us -mi.us -mn.us -mo.us -ms.us -mt.us -nc.us -nd.us -ne.us -nh.us -nj.us -nm.us -nv.us -ny.us -oh.us -ok.us -or.us -pa.us -pr.us -ri.us -sc.us -sd.us -tn.us -tx.us -ut.us -va.us -vi.us -vt.us -wa.us -wi.us -wv.us -wy.us -// The registrar notes several more specific domains available in each state, -// such as state.*.us, dst.*.us, etc., but resolution of these is somewhat -// haphazard; in some states these domains resolve as addresses, while in others -// only subdomains are available, or even nothing at all. We include the -// most common ones where it's clear that different sites are different -// entities. -k12.ak.us -k12.al.us -k12.ar.us -k12.as.us -k12.az.us -k12.ca.us -k12.co.us -k12.ct.us -k12.dc.us -k12.fl.us -k12.ga.us -k12.gu.us -// k12.hi.us - Bug 614565 - Hawaii has a state-wide DOE login -k12.ia.us -k12.id.us -k12.il.us -k12.in.us -k12.ks.us -k12.ky.us -k12.la.us -k12.ma.us -k12.md.us -k12.me.us -k12.mi.us -k12.mn.us -k12.mo.us -k12.ms.us -k12.mt.us -k12.nc.us -// k12.nd.us - Bug 1028347 - Removed at request of Travis Rosso -k12.ne.us -k12.nh.us -k12.nj.us -k12.nm.us -k12.nv.us -k12.ny.us -k12.oh.us -k12.ok.us -k12.or.us -k12.pa.us -k12.pr.us -// k12.ri.us - Removed at request of Kim Cournoyer -k12.sc.us -// k12.sd.us - Bug 934131 - Removed at request of James Booze -k12.tn.us -k12.tx.us -k12.ut.us -k12.va.us -k12.vi.us -k12.vt.us -k12.wa.us -k12.wi.us -// k12.wv.us - Bug 947705 - Removed at request of Verne Britton -cc.ak.us -lib.ak.us -cc.al.us -lib.al.us -cc.ar.us -lib.ar.us -cc.as.us -lib.as.us -cc.az.us -lib.az.us -cc.ca.us -lib.ca.us -cc.co.us -lib.co.us -cc.ct.us -lib.ct.us -cc.dc.us -lib.dc.us -cc.de.us -cc.fl.us -lib.fl.us -cc.ga.us -lib.ga.us -cc.gu.us -lib.gu.us -cc.hi.us -lib.hi.us -cc.ia.us -lib.ia.us -cc.id.us -lib.id.us -cc.il.us -lib.il.us -cc.in.us -lib.in.us -cc.ks.us -lib.ks.us -cc.ky.us -lib.ky.us -cc.la.us -lib.la.us -cc.ma.us -lib.ma.us -cc.md.us -lib.md.us -cc.me.us -lib.me.us -cc.mi.us -lib.mi.us -cc.mn.us -lib.mn.us -cc.mo.us -lib.mo.us -cc.ms.us -cc.mt.us -lib.mt.us -cc.nc.us -lib.nc.us -cc.nd.us -lib.nd.us -cc.ne.us -lib.ne.us -cc.nh.us -lib.nh.us -cc.nj.us -lib.nj.us -cc.nm.us -lib.nm.us -cc.nv.us -lib.nv.us -cc.ny.us -lib.ny.us -cc.oh.us -lib.oh.us -cc.ok.us -lib.ok.us -cc.or.us -lib.or.us -cc.pa.us -lib.pa.us -cc.pr.us -lib.pr.us -cc.ri.us -lib.ri.us -cc.sc.us -lib.sc.us -cc.sd.us -lib.sd.us -cc.tn.us -lib.tn.us -cc.tx.us -lib.tx.us -cc.ut.us -lib.ut.us -cc.va.us -lib.va.us -cc.vi.us -lib.vi.us -cc.vt.us -lib.vt.us -cc.wa.us -lib.wa.us -cc.wi.us -lib.wi.us -cc.wv.us -cc.wy.us -k12.wy.us -// lib.wv.us - Bug 941670 - Removed at request of Larry W Arnold -lib.wy.us -// k12.ma.us contains school districts in Massachusetts. The 4LDs are -// managed independently except for private (PVT), charter (CHTR) and -// parochial (PAROCH) schools. Those are delegated directly to the -// 5LD operators. -chtr.k12.ma.us -paroch.k12.ma.us -pvt.k12.ma.us -// Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following -// see also: https://domreg.merit.edu : domreg@merit.edu -// see also: whois -h whois.domreg.merit.edu help -ann-arbor.mi.us -cog.mi.us -dst.mi.us -eaton.mi.us -gen.mi.us -mus.mi.us -tec.mi.us -washtenaw.mi.us - -// uy : http://www.nic.org.uy/ -uy -com.uy -edu.uy -gub.uy -mil.uy -net.uy -org.uy - -// uz : http://www.reg.uz/ -uz -co.uz -com.uz -net.uz -org.uz - -// va : https://www.iana.org/domains/root/db/va.html -va - -// vc : https://www.iana.org/domains/root/db/vc.html -// Submitted by registry -vc -com.vc -edu.vc -gov.vc -mil.vc -net.vc -org.vc - -// ve : https://registro.nic.ve/ -// https://nic.ve/site/user-agreement -> under "III. Clasificación de Nombres de Dominio" -// Submitted by registry nic@nic.ve and nicve@conatel.gob.ve -ve -arts.ve -bib.ve -co.ve -com.ve -e12.ve -edu.ve -emprende.ve -firm.ve -gob.ve -gov.ve -ia.ve -info.ve -int.ve -mil.ve -net.ve -nom.ve -org.ve -rar.ve -rec.ve -store.ve -tec.ve -web.ve - -// vg : https://www.iana.org/domains/root/db/vg.html -// Confirmed by registry 2025-01-10 -vg -edu.vg - -// vi : https://www.iana.org/domains/root/db/vi.html -vi -co.vi -com.vi -k12.vi -net.vi -org.vi - -// vn : https://www.vnnic.vn/en/domain/cctld-vn -// https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt -vn -ac.vn -ai.vn -biz.vn -com.vn -edu.vn -gov.vn -health.vn -id.vn -info.vn -int.vn -io.vn -name.vn -net.vn -org.vn -pro.vn - -// vn geographical names -angiang.vn -bacgiang.vn -backan.vn -baclieu.vn -bacninh.vn -baria-vungtau.vn -bentre.vn -binhdinh.vn -binhduong.vn -binhphuoc.vn -binhthuan.vn -camau.vn -cantho.vn -caobang.vn -daklak.vn -daknong.vn -danang.vn -dienbien.vn -dongnai.vn -dongthap.vn -gialai.vn -hagiang.vn -haiduong.vn -haiphong.vn -hanam.vn -hanoi.vn -hatinh.vn -haugiang.vn -hoabinh.vn -hungyen.vn -khanhhoa.vn -kiengiang.vn -kontum.vn -laichau.vn -lamdong.vn -langson.vn -laocai.vn -longan.vn -namdinh.vn -nghean.vn -ninhbinh.vn -ninhthuan.vn -phutho.vn -phuyen.vn -quangbinh.vn -quangnam.vn -quangngai.vn -quangninh.vn -quangtri.vn -soctrang.vn -sonla.vn -tayninh.vn -thaibinh.vn -thainguyen.vn -thanhhoa.vn -thanhphohochiminh.vn -thuathienhue.vn -tiengiang.vn -travinh.vn -tuyenquang.vn -vinhlong.vn -vinhphuc.vn -yenbai.vn - -// vu : https://www.iana.org/domains/root/db/vu.html -// http://www.vunic.vu/ -vu -com.vu -edu.vu -net.vu -org.vu - -// wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -wf - -// ws : https://www.iana.org/domains/root/db/ws.html -// http://samoanic.ws/index.dhtml -ws -com.ws -edu.ws -gov.ws -net.ws -org.ws - -// yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -yt - -// IDN ccTLDs -// When submitting patches, please maintain a sort by ISO 3166 ccTLD, then -// U-label, and follow this format: -// // A-Label ("", [, variant info]) : -// // [sponsoring org] -// U-Label - -// xn--mgbaam7a8h ("Emerat", Arabic) : AE -// http://nic.ae/english/arabicdomain/rules.jsp -امارات - -// xn--y9a3aq ("hye", Armenian) : AM -// ISOC AM (operated by .am Registry) -հայ - -// xn--54b7fta0cc ("Bangla", Bangla) : BD -বাংলা - -// xn--90ae ("bg", Bulgarian) : BG -бг - -// xn--mgbcpq6gpa1a ("albahrain", Arabic) : BH -البحرين - -// xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY -// Operated by .by registry -бел - -// xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN -// CNNIC -// https://www.cnnic.cn/11/192/index.html -中国 - -// xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN -// CNNIC -// https://www.cnnic.com.cn/AU/MediaC/Announcement/201609/t20160905_54470.htm -中國 - -// xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ -الجزائر - -// xn--wgbh1c ("Egypt/Masr", Arabic) : EG -// http://www.dotmasr.eg/ -مصر - -// xn--e1a4c ("eu", Cyrillic) : EU -// https://eurid.eu -ею - -// xn--qxa6a ("eu", Greek) : EU -// https://eurid.eu -ευ - -// xn--mgbah1a3hjkrd ("Mauritania", Arabic) : MR -موريتانيا - -// xn--node ("ge", Georgian Mkhedruli) : GE -გე - -// xn--qxam ("el", Greek) : GR -// Hellenic Ministry of Infrastructure, Transport, and Networks -ελ - -// xn--j6w193g ("Hong Kong", Chinese) : HK -// https://www.hkirc.hk -// Submitted by registry -// https://www.hkirc.hk/content.jsp?id=30#!/34 -香港 -個人.香港 -公司.香港 -政府.香港 -教育.香港 -組織.香港 -網絡.香港 - -// xn--2scrj9c ("Bharat", Kannada) : IN -// India -ಭಾರತ - -// xn--3hcrj9c ("Bharat", Oriya) : IN -// India -ଭାରତ - -// xn--45br5cyl ("Bharatam", Assamese) : IN -// India -ভাৰত - -// xn--h2breg3eve ("Bharatam", Sanskrit) : IN -// India -भारतम् - -// xn--h2brj9c8c ("Bharot", Santali) : IN -// India -भारोत - -// xn--mgbgu82a ("Bharat", Sindhi) : IN -// India -ڀارت - -// xn--rvc1e0am3e ("Bharatam", Malayalam) : IN -// India -ഭാരതം - -// xn--h2brj9c ("Bharat", Devanagari) : IN -// India -भारत - -// xn--mgbbh1a ("Bharat", Kashmiri) : IN -// India -بارت - -// xn--mgbbh1a71e ("Bharat", Arabic) : IN -// India -بھارت - -// xn--fpcrj9c3d ("Bharat", Telugu) : IN -// India -భారత్ - -// xn--gecrj9c ("Bharat", Gujarati) : IN -// India -ભારત - -// xn--s9brj9c ("Bharat", Gurmukhi) : IN -// India -ਭਾਰਤ - -// xn--45brj9c ("Bharat", Bengali) : IN -// India -ভারত - -// xn--xkc2dl3a5ee0h ("India", Tamil) : IN -// India -இந்தியா - -// xn--mgba3a4f16a ("Iran", Persian) : IR -ایران - -// xn--mgba3a4fra ("Iran", Arabic) : IR -ايران - -// xn--mgbtx2b ("Iraq", Arabic) : IQ -// Communications and Media Commission -عراق - -// xn--mgbayh7gpa ("al-Ordon", Arabic) : JO -// National Information Technology Center (NITC) -// Royal Scientific Society, Al-Jubeiha -الاردن - -// xn--3e0b707e ("Republic of Korea", Hangul) : KR -한국 - -// xn--80ao21a ("Kaz", Kazakh) : KZ -қаз - -// xn--q7ce6a ("Lao", Lao) : LA -ລາວ - -// xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK -// https://nic.lk -ලංකා - -// xn--xkc2al3hye2a ("Ilangai", Tamil) : LK -// https://nic.lk -இலங்கை - -// xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA -المغرب - -// xn--d1alf ("mkd", Macedonian) : MK -// MARnet -мкд - -// xn--l1acc ("mon", Mongolian) : MN -мон - -// xn--mix891f ("Macao", Chinese, Traditional) : MO -// MONIC / HNET Asia (Registry Operator for .mo) -澳門 - -// xn--mix082f ("Macao", Chinese, Simplified) : MO -澳门 - -// xn--mgbx4cd0ab ("Malaysia", Malay) : MY -مليسيا - -// xn--mgb9awbf ("Oman", Arabic) : OM -عمان - -// xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK -پاکستان - -// xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK -پاكستان - -// xn--ygbi2ammx ("Falasteen", Arabic) : PS -// The Palestinian National Internet Naming Authority (PNINA) -// http://www.pnina.ps -فلسطين - -// xn--90a3ac ("srb", Cyrillic) : RS -// https://www.rnids.rs/en/domains/national-domains -срб -ак.срб -обр.срб -од.срб -орг.срб -пр.срб -упр.срб - -// xn--p1ai ("rf", Russian-Cyrillic) : RU -// https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf -// Submitted by George Georgievsky -рф - -// xn--wgbl6a ("Qatar", Arabic) : QA -// http://www.ict.gov.qa/ -قطر - -// xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA -// http://www.nic.net.sa/ -السعودية - -// xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant): SA -السعودیة - -// xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA -السعودیۃ - -// xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA -السعوديه - -// xn--mgbpl2fh ("sudan", Arabic) : SD -// Operated by .sd registry -سودان - -// xn--yfro4i67o Singapore ("Singapore", Chinese) : SG -新加坡 - -// xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG -சிங்கப்பூர் - -// xn--ogbpf8fl ("Syria", Arabic) : SY -سورية - -// xn--mgbtf8fl ("Syria", Arabic, variant) : SY -سوريا - -// xn--o3cw4h ("Thai", Thai) : TH -// http://www.thnic.co.th -ไทย -ทหาร.ไทย -ธุรกิจ.ไทย -เน็ต.ไทย -รัฐบาล.ไทย -ศึกษา.ไทย -องค์กร.ไทย - -// xn--pgbs0dh ("Tunisia", Arabic) : TN -// http://nic.tn -تونس - -// xn--kpry57d ("Taiwan", Chinese, Traditional) : TW -// https://twnic.tw/dnservice_catag.php -台灣 - -// xn--kprw13d ("Taiwan", Chinese, Simplified) : TW -// http://www.twnic.net/english/dn/dn_07a.htm -台湾 - -// xn--nnx388a ("Taiwan", Chinese, variant) : TW -臺灣 - -// xn--j1amh ("ukr", Cyrillic) : UA -укр - -// xn--mgb2ddes ("AlYemen", Arabic) : YE -اليمن - -// xxx : http://icmregistry.com -xxx - -// ye : http://www.y.net.ye/services/domain_name.htm -ye -com.ye -edu.ye -gov.ye -mil.ye -net.ye -org.ye - -// za : https://www.iana.org/domains/root/db/za.html -ac.za -agric.za -alt.za -co.za -edu.za -gov.za -grondar.za -law.za -mil.za -net.za -ngo.za -nic.za -nis.za -nom.za -org.za -school.za -tm.za -web.za - -// zm : https://zicta.zm/ -// Submitted by registry -zm -ac.zm -biz.zm -co.zm -com.zm -edu.zm -gov.zm -info.zm -mil.zm -net.zm -org.zm -sch.zm - -// zw : https://www.potraz.gov.zw/ -// Confirmed by registry 2017-01-25 -zw -ac.zw -co.zw -gov.zw -mil.zw -org.zw - -// newGTLDs - -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2025-11-08T15:16:38Z -// This list is auto-generated, don't edit it manually. -// aaa : American Automobile Association, Inc. -// https://www.iana.org/domains/root/db/aaa.html -aaa - -// aarp : AARP -// https://www.iana.org/domains/root/db/aarp.html -aarp - -// abb : ABB Ltd -// https://www.iana.org/domains/root/db/abb.html -abb - -// abbott : Abbott Laboratories, Inc. -// https://www.iana.org/domains/root/db/abbott.html -abbott - -// abbvie : AbbVie Inc. -// https://www.iana.org/domains/root/db/abbvie.html -abbvie - -// abc : Disney Enterprises, Inc. -// https://www.iana.org/domains/root/db/abc.html -abc - -// able : Able Inc. -// https://www.iana.org/domains/root/db/able.html -able - -// abogado : Registry Services, LLC -// https://www.iana.org/domains/root/db/abogado.html -abogado - -// abudhabi : Abu Dhabi Systems and Information Centre -// https://www.iana.org/domains/root/db/abudhabi.html -abudhabi - -// academy : Binky Moon, LLC -// https://www.iana.org/domains/root/db/academy.html -academy - -// accenture : Accenture plc -// https://www.iana.org/domains/root/db/accenture.html -accenture - -// accountant : dot Accountant Limited -// https://www.iana.org/domains/root/db/accountant.html -accountant - -// accountants : Binky Moon, LLC -// https://www.iana.org/domains/root/db/accountants.html -accountants - -// aco : ACO Severin Ahlmann GmbH & Co. KG -// https://www.iana.org/domains/root/db/aco.html -aco - -// actor : Dog Beach, LLC -// https://www.iana.org/domains/root/db/actor.html -actor - -// ads : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/ads.html -ads - -// adult : ICM Registry AD LLC -// https://www.iana.org/domains/root/db/adult.html -adult - -// aeg : Aktiebolaget Electrolux -// https://www.iana.org/domains/root/db/aeg.html -aeg - -// aetna : Aetna Life Insurance Company -// https://www.iana.org/domains/root/db/aetna.html -aetna - -// afl : Australian Football League -// https://www.iana.org/domains/root/db/afl.html -afl - -// africa : ZA Central Registry NPC trading as Registry.Africa -// https://www.iana.org/domains/root/db/africa.html -africa - -// agakhan : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/agakhan.html -agakhan - -// agency : Binky Moon, LLC -// https://www.iana.org/domains/root/db/agency.html -agency - -// aig : American International Group, Inc. -// https://www.iana.org/domains/root/db/aig.html -aig - -// airbus : Airbus S.A.S. -// https://www.iana.org/domains/root/db/airbus.html -airbus - -// airforce : Dog Beach, LLC -// https://www.iana.org/domains/root/db/airforce.html -airforce - -// airtel : Bharti Airtel Limited -// https://www.iana.org/domains/root/db/airtel.html -airtel - -// akdn : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/akdn.html -akdn - -// alibaba : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/alibaba.html -alibaba - -// alipay : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/alipay.html -alipay - -// allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft -// https://www.iana.org/domains/root/db/allfinanz.html -allfinanz - -// allstate : Allstate Fire and Casualty Insurance Company -// https://www.iana.org/domains/root/db/allstate.html -allstate - -// ally : Ally Financial Inc. -// https://www.iana.org/domains/root/db/ally.html -ally - -// alsace : Region Grand Est -// https://www.iana.org/domains/root/db/alsace.html -alsace - -// alstom : ALSTOM -// https://www.iana.org/domains/root/db/alstom.html -alstom - -// amazon : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/amazon.html -amazon - -// americanexpress : American Express Travel Related Services Company, Inc. -// https://www.iana.org/domains/root/db/americanexpress.html -americanexpress - -// americanfamily : AmFam, Inc. -// https://www.iana.org/domains/root/db/americanfamily.html -americanfamily - -// amex : American Express Travel Related Services Company, Inc. -// https://www.iana.org/domains/root/db/amex.html -amex - -// amfam : AmFam, Inc. -// https://www.iana.org/domains/root/db/amfam.html -amfam - -// amica : Amica Mutual Insurance Company -// https://www.iana.org/domains/root/db/amica.html -amica - -// amsterdam : Gemeente Amsterdam -// https://www.iana.org/domains/root/db/amsterdam.html -amsterdam - -// analytics : Campus IP LLC -// https://www.iana.org/domains/root/db/analytics.html -analytics - -// android : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/android.html -android - -// anquan : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/anquan.html -anquan - -// anz : Australia and New Zealand Banking Group Limited -// https://www.iana.org/domains/root/db/anz.html -anz - -// aol : Yahoo Inc. -// https://www.iana.org/domains/root/db/aol.html -aol - -// apartments : Binky Moon, LLC -// https://www.iana.org/domains/root/db/apartments.html -apartments - -// app : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/app.html -app - -// apple : Apple Inc. -// https://www.iana.org/domains/root/db/apple.html -apple - -// aquarelle : Aquarelle.com -// https://www.iana.org/domains/root/db/aquarelle.html -aquarelle - -// arab : League of Arab States -// https://www.iana.org/domains/root/db/arab.html -arab - -// aramco : Aramco Services Company -// https://www.iana.org/domains/root/db/aramco.html -aramco - -// archi : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/archi.html -archi - -// army : Dog Beach, LLC -// https://www.iana.org/domains/root/db/army.html -army - -// art : UK Creative Ideas Limited -// https://www.iana.org/domains/root/db/art.html -art - -// arte : Association Relative à la Télévision Européenne G.E.I.E. -// https://www.iana.org/domains/root/db/arte.html -arte - -// asda : Asda Stores Limited -// https://www.iana.org/domains/root/db/asda.html -asda - -// associates : Binky Moon, LLC -// https://www.iana.org/domains/root/db/associates.html -associates - -// athleta : The Gap, Inc. -// https://www.iana.org/domains/root/db/athleta.html -athleta - -// attorney : Dog Beach, LLC -// https://www.iana.org/domains/root/db/attorney.html -attorney - -// auction : Dog Beach, LLC -// https://www.iana.org/domains/root/db/auction.html -auction - -// audi : AUDI Aktiengesellschaft -// https://www.iana.org/domains/root/db/audi.html -audi - -// audible : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/audible.html -audible - -// audio : XYZ.COM LLC -// https://www.iana.org/domains/root/db/audio.html -audio - -// auspost : Australian Postal Corporation -// https://www.iana.org/domains/root/db/auspost.html -auspost - -// author : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/author.html -author - -// auto : XYZ.COM LLC -// https://www.iana.org/domains/root/db/auto.html -auto - -// autos : XYZ.COM LLC -// https://www.iana.org/domains/root/db/autos.html -autos - -// aws : AWS Registry LLC -// https://www.iana.org/domains/root/db/aws.html -aws - -// axa : AXA Group Operations SAS -// https://www.iana.org/domains/root/db/axa.html -axa - -// azure : Microsoft Corporation -// https://www.iana.org/domains/root/db/azure.html -azure - -// baby : XYZ.COM LLC -// https://www.iana.org/domains/root/db/baby.html -baby - -// baidu : Baidu, Inc. -// https://www.iana.org/domains/root/db/baidu.html -baidu - -// banamex : Citigroup Inc. -// https://www.iana.org/domains/root/db/banamex.html -banamex - -// band : Dog Beach, LLC -// https://www.iana.org/domains/root/db/band.html -band - -// bank : fTLD Registry Services LLC -// https://www.iana.org/domains/root/db/bank.html -bank - -// bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable -// https://www.iana.org/domains/root/db/bar.html -bar - -// barcelona : Municipi de Barcelona -// https://www.iana.org/domains/root/db/barcelona.html -barcelona - -// barclaycard : Barclays Bank PLC -// https://www.iana.org/domains/root/db/barclaycard.html -barclaycard - -// barclays : Barclays Bank PLC -// https://www.iana.org/domains/root/db/barclays.html -barclays - -// barefoot : Gallo Vineyards, Inc. -// https://www.iana.org/domains/root/db/barefoot.html -barefoot - -// bargains : Binky Moon, LLC -// https://www.iana.org/domains/root/db/bargains.html -bargains - -// baseball : MLB Advanced Media DH, LLC -// https://www.iana.org/domains/root/db/baseball.html -baseball - -// basketball : Fédération Internationale de Basketball (FIBA) -// https://www.iana.org/domains/root/db/basketball.html -basketball - -// bauhaus : Werkhaus GmbH -// https://www.iana.org/domains/root/db/bauhaus.html -bauhaus - -// bayern : Bayern Connect GmbH -// https://www.iana.org/domains/root/db/bayern.html -bayern - -// bbc : British Broadcasting Corporation -// https://www.iana.org/domains/root/db/bbc.html -bbc - -// bbt : BB&T Corporation -// https://www.iana.org/domains/root/db/bbt.html -bbt - -// bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A. -// https://www.iana.org/domains/root/db/bbva.html -bbva - -// bcg : The Boston Consulting Group, Inc. -// https://www.iana.org/domains/root/db/bcg.html -bcg - -// bcn : Municipi de Barcelona -// https://www.iana.org/domains/root/db/bcn.html -bcn - -// beats : Beats Electronics, LLC -// https://www.iana.org/domains/root/db/beats.html -beats - -// beauty : XYZ.COM LLC -// https://www.iana.org/domains/root/db/beauty.html -beauty - -// beer : Registry Services, LLC -// https://www.iana.org/domains/root/db/beer.html -beer - -// berlin : dotBERLIN GmbH & Co. KG -// https://www.iana.org/domains/root/db/berlin.html -berlin - -// best : BestTLD Pty Ltd -// https://www.iana.org/domains/root/db/best.html -best - -// bestbuy : BBY Solutions, Inc. -// https://www.iana.org/domains/root/db/bestbuy.html -bestbuy - -// bet : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/bet.html -bet - -// bharti : Bharti Enterprises (Holding) Private Limited -// https://www.iana.org/domains/root/db/bharti.html -bharti - -// bible : American Bible Society -// https://www.iana.org/domains/root/db/bible.html -bible - -// bid : dot Bid Limited -// https://www.iana.org/domains/root/db/bid.html -bid - -// bike : Binky Moon, LLC -// https://www.iana.org/domains/root/db/bike.html -bike - -// bing : Microsoft Corporation -// https://www.iana.org/domains/root/db/bing.html -bing - -// bingo : Binky Moon, LLC -// https://www.iana.org/domains/root/db/bingo.html -bingo - -// bio : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/bio.html -bio - -// black : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/black.html -black - -// blackfriday : Registry Services, LLC -// https://www.iana.org/domains/root/db/blackfriday.html -blackfriday - -// blockbuster : Dish DBS Corporation -// https://www.iana.org/domains/root/db/blockbuster.html -blockbuster - -// blog : Knock Knock WHOIS There, LLC -// https://www.iana.org/domains/root/db/blog.html -blog - -// bloomberg : Bloomberg IP Holdings LLC -// https://www.iana.org/domains/root/db/bloomberg.html -bloomberg - -// blue : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/blue.html -blue - -// bms : Bristol-Myers Squibb Company -// https://www.iana.org/domains/root/db/bms.html -bms - -// bmw : Bayerische Motoren Werke Aktiengesellschaft -// https://www.iana.org/domains/root/db/bmw.html -bmw - -// bnpparibas : BNP Paribas -// https://www.iana.org/domains/root/db/bnpparibas.html -bnpparibas - -// boats : XYZ.COM LLC -// https://www.iana.org/domains/root/db/boats.html -boats - -// boehringer : Boehringer Ingelheim International GmbH -// https://www.iana.org/domains/root/db/boehringer.html -boehringer - -// bofa : Bank of America Corporation -// https://www.iana.org/domains/root/db/bofa.html -bofa - -// bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br -// https://www.iana.org/domains/root/db/bom.html -bom - -// bond : ShortDot SA -// https://www.iana.org/domains/root/db/bond.html -bond - -// boo : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/boo.html -boo - -// book : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/book.html -book - -// booking : Booking.com B.V. -// https://www.iana.org/domains/root/db/booking.html -booking - -// bosch : Robert Bosch GMBH -// https://www.iana.org/domains/root/db/bosch.html -bosch - -// bostik : Bostik SA -// https://www.iana.org/domains/root/db/bostik.html -bostik - -// boston : Registry Services, LLC -// https://www.iana.org/domains/root/db/boston.html -boston - -// bot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/bot.html -bot - -// boutique : Binky Moon, LLC -// https://www.iana.org/domains/root/db/boutique.html -boutique - -// box : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/box.html -box - -// bradesco : Banco Bradesco S.A. -// https://www.iana.org/domains/root/db/bradesco.html -bradesco - -// bridgestone : Bridgestone Corporation -// https://www.iana.org/domains/root/db/bridgestone.html -bridgestone - -// broadway : Celebrate Broadway, Inc. -// https://www.iana.org/domains/root/db/broadway.html -broadway - -// broker : Dog Beach, LLC -// https://www.iana.org/domains/root/db/broker.html -broker - -// brother : Brother Industries, Ltd. -// https://www.iana.org/domains/root/db/brother.html -brother - -// brussels : DNS.be vzw -// https://www.iana.org/domains/root/db/brussels.html -brussels - -// build : Plan Bee LLC -// https://www.iana.org/domains/root/db/build.html -build - -// builders : Binky Moon, LLC -// https://www.iana.org/domains/root/db/builders.html -builders - -// business : Binky Moon, LLC -// https://www.iana.org/domains/root/db/business.html -business - -// buy : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/buy.html -buy - -// buzz : DOTSTRATEGY CO. -// https://www.iana.org/domains/root/db/buzz.html -buzz - -// bzh : Association www.bzh -// https://www.iana.org/domains/root/db/bzh.html -bzh - -// cab : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cab.html -cab - -// cafe : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cafe.html -cafe - -// cal : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/cal.html -cal - -// call : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/call.html -call - -// calvinklein : PVH gTLD Holdings LLC -// https://www.iana.org/domains/root/db/calvinklein.html -calvinklein - -// cam : Cam Connecting SARL -// https://www.iana.org/domains/root/db/cam.html -cam - -// camera : Binky Moon, LLC -// https://www.iana.org/domains/root/db/camera.html -camera - -// camp : Binky Moon, LLC -// https://www.iana.org/domains/root/db/camp.html -camp - -// canon : Canon Inc. -// https://www.iana.org/domains/root/db/canon.html -canon - -// capetown : ZA Central Registry NPC trading as ZA Central Registry -// https://www.iana.org/domains/root/db/capetown.html -capetown - -// capital : Binky Moon, LLC -// https://www.iana.org/domains/root/db/capital.html -capital - -// capitalone : Capital One Financial Corporation -// https://www.iana.org/domains/root/db/capitalone.html -capitalone - -// car : XYZ.COM LLC -// https://www.iana.org/domains/root/db/car.html -car - -// caravan : Caravan International, Inc. -// https://www.iana.org/domains/root/db/caravan.html -caravan - -// cards : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cards.html -cards - -// care : Binky Moon, LLC -// https://www.iana.org/domains/root/db/care.html -care - -// career : dotCareer LLC -// https://www.iana.org/domains/root/db/career.html -career - -// careers : Binky Moon, LLC -// https://www.iana.org/domains/root/db/careers.html -careers - -// cars : XYZ.COM LLC -// https://www.iana.org/domains/root/db/cars.html -cars - -// casa : Registry Services, LLC -// https://www.iana.org/domains/root/db/casa.html -casa - -// case : Digity, LLC -// https://www.iana.org/domains/root/db/case.html -case - -// cash : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cash.html -cash - -// casino : Binky Moon, LLC -// https://www.iana.org/domains/root/db/casino.html -casino - -// catering : Binky Moon, LLC -// https://www.iana.org/domains/root/db/catering.html -catering - -// catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/catholic.html -catholic - -// cba : COMMONWEALTH BANK OF AUSTRALIA -// https://www.iana.org/domains/root/db/cba.html -cba - -// cbn : The Christian Broadcasting Network, Inc. -// https://www.iana.org/domains/root/db/cbn.html -cbn - -// cbre : CBRE, Inc. -// https://www.iana.org/domains/root/db/cbre.html -cbre - -// center : Binky Moon, LLC -// https://www.iana.org/domains/root/db/center.html -center - -// ceo : XYZ.COM LLC -// https://www.iana.org/domains/root/db/ceo.html -ceo - -// cern : European Organization for Nuclear Research ("CERN") -// https://www.iana.org/domains/root/db/cern.html -cern - -// cfa : CFA Institute -// https://www.iana.org/domains/root/db/cfa.html -cfa - -// cfd : ShortDot SA -// https://www.iana.org/domains/root/db/cfd.html -cfd - -// chanel : Chanel International B.V. -// https://www.iana.org/domains/root/db/chanel.html -chanel - -// channel : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/channel.html -channel - -// charity : Public Interest Registry -// https://www.iana.org/domains/root/db/charity.html -charity - -// chase : JPMorgan Chase Bank, National Association -// https://www.iana.org/domains/root/db/chase.html -chase - -// chat : Binky Moon, LLC -// https://www.iana.org/domains/root/db/chat.html -chat - -// cheap : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cheap.html -cheap - -// chintai : CHINTAI Corporation -// https://www.iana.org/domains/root/db/chintai.html -chintai - -// christmas : XYZ.COM LLC -// https://www.iana.org/domains/root/db/christmas.html -christmas - -// chrome : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/chrome.html -chrome - -// church : Binky Moon, LLC -// https://www.iana.org/domains/root/db/church.html -church - -// cipriani : Hotel Cipriani Srl -// https://www.iana.org/domains/root/db/cipriani.html -cipriani - -// circle : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/circle.html -circle - -// cisco : Cisco Technology, Inc. -// https://www.iana.org/domains/root/db/cisco.html -cisco - -// citadel : Citadel Domain LLC -// https://www.iana.org/domains/root/db/citadel.html -citadel - -// citi : Citigroup Inc. -// https://www.iana.org/domains/root/db/citi.html -citi - -// citic : CITIC Group Corporation -// https://www.iana.org/domains/root/db/citic.html -citic - -// city : Binky Moon, LLC -// https://www.iana.org/domains/root/db/city.html -city - -// claims : Binky Moon, LLC -// https://www.iana.org/domains/root/db/claims.html -claims - -// cleaning : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cleaning.html -cleaning - -// click : Waterford Limited -// https://www.iana.org/domains/root/db/click.html -click - -// clinic : Binky Moon, LLC -// https://www.iana.org/domains/root/db/clinic.html -clinic - -// clinique : The Estée Lauder Companies Inc. -// https://www.iana.org/domains/root/db/clinique.html -clinique - -// clothing : Binky Moon, LLC -// https://www.iana.org/domains/root/db/clothing.html -clothing - -// cloud : Aruba PEC S.p.A. -// https://www.iana.org/domains/root/db/cloud.html -cloud - -// club : Registry Services, LLC -// https://www.iana.org/domains/root/db/club.html -club - -// clubmed : Club Méditerranée S.A. -// https://www.iana.org/domains/root/db/clubmed.html -clubmed - -// coach : Binky Moon, LLC -// https://www.iana.org/domains/root/db/coach.html -coach - -// codes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/codes.html -codes - -// coffee : Binky Moon, LLC -// https://www.iana.org/domains/root/db/coffee.html -coffee - -// college : XYZ.COM LLC -// https://www.iana.org/domains/root/db/college.html -college - -// cologne : dotKoeln GmbH -// https://www.iana.org/domains/root/db/cologne.html -cologne - -// commbank : COMMONWEALTH BANK OF AUSTRALIA -// https://www.iana.org/domains/root/db/commbank.html -commbank - -// community : Binky Moon, LLC -// https://www.iana.org/domains/root/db/community.html -community - -// company : Binky Moon, LLC -// https://www.iana.org/domains/root/db/company.html -company - -// compare : Registry Services, LLC -// https://www.iana.org/domains/root/db/compare.html -compare - -// computer : Binky Moon, LLC -// https://www.iana.org/domains/root/db/computer.html -computer - -// comsec : VeriSign, Inc. -// https://www.iana.org/domains/root/db/comsec.html -comsec - -// condos : Binky Moon, LLC -// https://www.iana.org/domains/root/db/condos.html -condos - -// construction : Binky Moon, LLC -// https://www.iana.org/domains/root/db/construction.html -construction - -// consulting : Dog Beach, LLC -// https://www.iana.org/domains/root/db/consulting.html -consulting - -// contact : Dog Beach, LLC -// https://www.iana.org/domains/root/db/contact.html -contact - -// contractors : Binky Moon, LLC -// https://www.iana.org/domains/root/db/contractors.html -contractors - -// cooking : Registry Services, LLC -// https://www.iana.org/domains/root/db/cooking.html -cooking - -// cool : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cool.html -cool - -// corsica : Collectivité de Corse -// https://www.iana.org/domains/root/db/corsica.html -corsica - -// country : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/country.html -country - -// coupon : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/coupon.html -coupon - -// coupons : Binky Moon, LLC -// https://www.iana.org/domains/root/db/coupons.html -coupons - -// courses : Registry Services, LLC -// https://www.iana.org/domains/root/db/courses.html -courses - -// cpa : American Institute of Certified Public Accountants -// https://www.iana.org/domains/root/db/cpa.html -cpa - -// credit : Binky Moon, LLC -// https://www.iana.org/domains/root/db/credit.html -credit - -// creditcard : Binky Moon, LLC -// https://www.iana.org/domains/root/db/creditcard.html -creditcard - -// creditunion : DotCooperation LLC -// https://www.iana.org/domains/root/db/creditunion.html -creditunion - -// cricket : dot Cricket Limited -// https://www.iana.org/domains/root/db/cricket.html -cricket - -// crown : Crown Equipment Corporation -// https://www.iana.org/domains/root/db/crown.html -crown - -// crs : Federated Co-operatives Limited -// https://www.iana.org/domains/root/db/crs.html -crs - -// cruise : Viking River Cruises (Bermuda) Ltd. -// https://www.iana.org/domains/root/db/cruise.html -cruise - -// cruises : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cruises.html -cruises - -// cuisinella : SCHMIDT GROUPE S.A.S. -// https://www.iana.org/domains/root/db/cuisinella.html -cuisinella - -// cymru : Nominet UK -// https://www.iana.org/domains/root/db/cymru.html -cymru - -// cyou : ShortDot SA -// https://www.iana.org/domains/root/db/cyou.html -cyou - -// dad : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/dad.html -dad - -// dance : Dog Beach, LLC -// https://www.iana.org/domains/root/db/dance.html -dance - -// data : Dish DBS Corporation -// https://www.iana.org/domains/root/db/data.html -data - -// date : dot Date Limited -// https://www.iana.org/domains/root/db/date.html -date - -// dating : Binky Moon, LLC -// https://www.iana.org/domains/root/db/dating.html -dating - -// datsun : NISSAN MOTOR CO., LTD. -// https://www.iana.org/domains/root/db/datsun.html -datsun - -// day : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/day.html -day - -// dclk : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/dclk.html -dclk - -// dds : Registry Services, LLC -// https://www.iana.org/domains/root/db/dds.html -dds - -// deal : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/deal.html -deal - -// dealer : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/dealer.html -dealer - -// deals : Binky Moon, LLC -// https://www.iana.org/domains/root/db/deals.html -deals - -// degree : Dog Beach, LLC -// https://www.iana.org/domains/root/db/degree.html -degree - -// delivery : Binky Moon, LLC -// https://www.iana.org/domains/root/db/delivery.html -delivery - -// dell : Dell Inc. -// https://www.iana.org/domains/root/db/dell.html -dell - -// deloitte : Deloitte Touche Tohmatsu -// https://www.iana.org/domains/root/db/deloitte.html -deloitte - -// delta : Delta Air Lines, Inc. -// https://www.iana.org/domains/root/db/delta.html -delta - -// democrat : Dog Beach, LLC -// https://www.iana.org/domains/root/db/democrat.html -democrat - -// dental : Binky Moon, LLC -// https://www.iana.org/domains/root/db/dental.html -dental - -// dentist : Dog Beach, LLC -// https://www.iana.org/domains/root/db/dentist.html -dentist - -// desi -// https://www.iana.org/domains/root/db/desi.html -desi - -// design : Registry Services, LLC -// https://www.iana.org/domains/root/db/design.html -design - -// dev : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/dev.html -dev - -// dhl : Deutsche Post AG -// https://www.iana.org/domains/root/db/dhl.html -dhl - -// diamonds : Binky Moon, LLC -// https://www.iana.org/domains/root/db/diamonds.html -diamonds - -// diet : XYZ.COM LLC -// https://www.iana.org/domains/root/db/diet.html -diet - -// digital : Binky Moon, LLC -// https://www.iana.org/domains/root/db/digital.html -digital - -// direct : Binky Moon, LLC -// https://www.iana.org/domains/root/db/direct.html -direct - -// directory : Binky Moon, LLC -// https://www.iana.org/domains/root/db/directory.html -directory - -// discount : Binky Moon, LLC -// https://www.iana.org/domains/root/db/discount.html -discount - -// discover : Discover Financial Services -// https://www.iana.org/domains/root/db/discover.html -discover - -// dish : Dish DBS Corporation -// https://www.iana.org/domains/root/db/dish.html -dish - -// diy : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/diy.html -diy - -// dnp : Dai Nippon Printing Co., Ltd. -// https://www.iana.org/domains/root/db/dnp.html -dnp - -// docs : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/docs.html -docs - -// doctor : Binky Moon, LLC -// https://www.iana.org/domains/root/db/doctor.html -doctor - -// dog : Binky Moon, LLC -// https://www.iana.org/domains/root/db/dog.html -dog - -// domains : Binky Moon, LLC -// https://www.iana.org/domains/root/db/domains.html -domains - -// dot : Dish DBS Corporation -// https://www.iana.org/domains/root/db/dot.html -dot - -// download : dot Support Limited -// https://www.iana.org/domains/root/db/download.html -download - -// drive : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/drive.html -drive - -// dtv : Dish DBS Corporation -// https://www.iana.org/domains/root/db/dtv.html -dtv - -// dubai : Dubai Smart Government Department -// https://www.iana.org/domains/root/db/dubai.html -dubai - -// dupont : DuPont Specialty Products USA, LLC -// https://www.iana.org/domains/root/db/dupont.html -dupont - -// durban : ZA Central Registry NPC trading as ZA Central Registry -// https://www.iana.org/domains/root/db/durban.html -durban - -// dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/dvag.html -dvag - -// dvr : DISH Technologies L.L.C. -// https://www.iana.org/domains/root/db/dvr.html -dvr - -// earth : Interlink Systems Innovation Institute K.K. -// https://www.iana.org/domains/root/db/earth.html -earth - -// eat : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/eat.html -eat - -// eco : Big Room Inc. -// https://www.iana.org/domains/root/db/eco.html -eco - -// edeka : EDEKA Verband kaufmännischer Genossenschaften e.V. -// https://www.iana.org/domains/root/db/edeka.html -edeka - -// education : Binky Moon, LLC -// https://www.iana.org/domains/root/db/education.html -education - -// email : Binky Moon, LLC -// https://www.iana.org/domains/root/db/email.html -email - -// emerck : Merck KGaA -// https://www.iana.org/domains/root/db/emerck.html -emerck - -// energy : Binky Moon, LLC -// https://www.iana.org/domains/root/db/energy.html -energy - -// engineer : Dog Beach, LLC -// https://www.iana.org/domains/root/db/engineer.html -engineer - -// engineering : Binky Moon, LLC -// https://www.iana.org/domains/root/db/engineering.html -engineering - -// enterprises : Binky Moon, LLC -// https://www.iana.org/domains/root/db/enterprises.html -enterprises - -// epson : Seiko Epson Corporation -// https://www.iana.org/domains/root/db/epson.html -epson - -// equipment : Binky Moon, LLC -// https://www.iana.org/domains/root/db/equipment.html -equipment - -// ericsson : Telefonaktiebolaget L M Ericsson -// https://www.iana.org/domains/root/db/ericsson.html -ericsson - -// erni : ERNI Group Holding AG -// https://www.iana.org/domains/root/db/erni.html -erni - -// esq : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/esq.html -esq - -// estate : Binky Moon, LLC -// https://www.iana.org/domains/root/db/estate.html -estate - -// eurovision : European Broadcasting Union (EBU) -// https://www.iana.org/domains/root/db/eurovision.html -eurovision - -// eus : Puntueus Fundazioa -// https://www.iana.org/domains/root/db/eus.html -eus - -// events : Binky Moon, LLC -// https://www.iana.org/domains/root/db/events.html -events - -// exchange : Binky Moon, LLC -// https://www.iana.org/domains/root/db/exchange.html -exchange - -// expert : Binky Moon, LLC -// https://www.iana.org/domains/root/db/expert.html -expert - -// exposed : Binky Moon, LLC -// https://www.iana.org/domains/root/db/exposed.html -exposed - -// express : Binky Moon, LLC -// https://www.iana.org/domains/root/db/express.html -express - -// extraspace : Extra Space Storage LLC -// https://www.iana.org/domains/root/db/extraspace.html -extraspace - -// fage : Fage International S.A. -// https://www.iana.org/domains/root/db/fage.html -fage - -// fail : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fail.html -fail - -// fairwinds : FairWinds Partners, LLC -// https://www.iana.org/domains/root/db/fairwinds.html -fairwinds - -// faith : dot Faith Limited -// https://www.iana.org/domains/root/db/faith.html -faith - -// family : Dog Beach, LLC -// https://www.iana.org/domains/root/db/family.html -family - -// fan : Dog Beach, LLC -// https://www.iana.org/domains/root/db/fan.html -fan - -// fans : ZDNS International Limited -// https://www.iana.org/domains/root/db/fans.html -fans - -// farm : Binky Moon, LLC -// https://www.iana.org/domains/root/db/farm.html -farm - -// farmers : Farmers Insurance Exchange -// https://www.iana.org/domains/root/db/farmers.html -farmers - -// fashion : Registry Services, LLC -// https://www.iana.org/domains/root/db/fashion.html -fashion - -// fast : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/fast.html -fast - -// fedex : Federal Express Corporation -// https://www.iana.org/domains/root/db/fedex.html -fedex - -// feedback : Top Level Spectrum, Inc. -// https://www.iana.org/domains/root/db/feedback.html -feedback - -// ferrari : Fiat Chrysler Automobiles N.V. -// https://www.iana.org/domains/root/db/ferrari.html -ferrari - -// ferrero : Ferrero Trading Lux S.A. -// https://www.iana.org/domains/root/db/ferrero.html -ferrero - -// fidelity : Fidelity Brokerage Services LLC -// https://www.iana.org/domains/root/db/fidelity.html -fidelity - -// fido : Rogers Communications Canada Inc. -// https://www.iana.org/domains/root/db/fido.html -fido - -// film : Motion Picture Domain Registry Pty Ltd -// https://www.iana.org/domains/root/db/film.html -film - -// final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br -// https://www.iana.org/domains/root/db/final.html -final - -// finance : Binky Moon, LLC -// https://www.iana.org/domains/root/db/finance.html -finance - -// financial : Binky Moon, LLC -// https://www.iana.org/domains/root/db/financial.html -financial - -// fire : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/fire.html -fire - -// firestone : Bridgestone Licensing Services, Inc -// https://www.iana.org/domains/root/db/firestone.html -firestone - -// firmdale : Firmdale Holdings Limited -// https://www.iana.org/domains/root/db/firmdale.html -firmdale - -// fish : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fish.html -fish - -// fishing : Registry Services, LLC -// https://www.iana.org/domains/root/db/fishing.html -fishing - -// fit : Registry Services, LLC -// https://www.iana.org/domains/root/db/fit.html -fit - -// fitness : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fitness.html -fitness - -// flickr : Flickr, Inc. -// https://www.iana.org/domains/root/db/flickr.html -flickr - -// flights : Binky Moon, LLC -// https://www.iana.org/domains/root/db/flights.html -flights - -// flir : FLIR Systems, Inc. -// https://www.iana.org/domains/root/db/flir.html -flir - -// florist : Binky Moon, LLC -// https://www.iana.org/domains/root/db/florist.html -florist - -// flowers : XYZ.COM LLC -// https://www.iana.org/domains/root/db/flowers.html -flowers - -// fly : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/fly.html -fly - -// foo : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/foo.html -foo - -// food : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/food.html -food - -// football : Binky Moon, LLC -// https://www.iana.org/domains/root/db/football.html -football - -// ford : Ford Motor Company -// https://www.iana.org/domains/root/db/ford.html -ford - -// forex : Dog Beach, LLC -// https://www.iana.org/domains/root/db/forex.html -forex - -// forsale : Dog Beach, LLC -// https://www.iana.org/domains/root/db/forsale.html -forsale - -// forum : Waterford Limited -// https://www.iana.org/domains/root/db/forum.html -forum - -// foundation : Public Interest Registry -// https://www.iana.org/domains/root/db/foundation.html -foundation - -// fox : FOX Registry, LLC -// https://www.iana.org/domains/root/db/fox.html -fox - -// free : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/free.html -free - -// fresenius : Fresenius Immobilien-Verwaltungs-GmbH -// https://www.iana.org/domains/root/db/fresenius.html -fresenius - -// frl : FRLregistry B.V. -// https://www.iana.org/domains/root/db/frl.html -frl - -// frogans : OP3FT -// https://www.iana.org/domains/root/db/frogans.html -frogans - -// frontier : Frontier Communications Corporation -// https://www.iana.org/domains/root/db/frontier.html -frontier - -// ftr : Frontier Communications Corporation -// https://www.iana.org/domains/root/db/ftr.html -ftr - -// fujitsu : Fujitsu Limited -// https://www.iana.org/domains/root/db/fujitsu.html -fujitsu - -// fun : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/fun.html -fun - -// fund : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fund.html -fund - -// furniture : Binky Moon, LLC -// https://www.iana.org/domains/root/db/furniture.html -furniture - -// futbol : Dog Beach, LLC -// https://www.iana.org/domains/root/db/futbol.html -futbol - -// fyi : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fyi.html -fyi - -// gal : Asociación puntoGAL -// https://www.iana.org/domains/root/db/gal.html -gal - -// gallery : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gallery.html -gallery - -// gallo : Gallo Vineyards, Inc. -// https://www.iana.org/domains/root/db/gallo.html -gallo - -// gallup : Gallup, Inc. -// https://www.iana.org/domains/root/db/gallup.html -gallup - -// game : XYZ.COM LLC -// https://www.iana.org/domains/root/db/game.html -game - -// games : Dog Beach, LLC -// https://www.iana.org/domains/root/db/games.html -games - -// gap : The Gap, Inc. -// https://www.iana.org/domains/root/db/gap.html -gap - -// garden : Registry Services, LLC -// https://www.iana.org/domains/root/db/garden.html -garden - -// gay : Registry Services, LLC -// https://www.iana.org/domains/root/db/gay.html -gay - -// gbiz : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/gbiz.html -gbiz - -// gdn : Joint Stock Company "Navigation-information systems" -// https://www.iana.org/domains/root/db/gdn.html -gdn - -// gea : GEA Group Aktiengesellschaft -// https://www.iana.org/domains/root/db/gea.html -gea - -// gent : Easyhost BV -// https://www.iana.org/domains/root/db/gent.html -gent - -// genting : Resorts World Inc Pte. Ltd. -// https://www.iana.org/domains/root/db/genting.html -genting - -// george : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/george.html -george - -// ggee : GMO Internet, Inc. -// https://www.iana.org/domains/root/db/ggee.html -ggee - -// gift : DotGift, LLC -// https://www.iana.org/domains/root/db/gift.html -gift - -// gifts : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gifts.html -gifts - -// gives : Public Interest Registry -// https://www.iana.org/domains/root/db/gives.html -gives - -// giving : Public Interest Registry -// https://www.iana.org/domains/root/db/giving.html -giving - -// glass : Binky Moon, LLC -// https://www.iana.org/domains/root/db/glass.html -glass - -// gle : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/gle.html -gle - -// global : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/global.html -global - -// globo : Globo Comunicação e Participações S.A -// https://www.iana.org/domains/root/db/globo.html -globo - -// gmail : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/gmail.html -gmail - -// gmbh : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gmbh.html -gmbh - -// gmo : GMO Internet, Inc. -// https://www.iana.org/domains/root/db/gmo.html -gmo - -// gmx : 1&1 Mail & Media GmbH -// https://www.iana.org/domains/root/db/gmx.html -gmx - -// godaddy : Go Daddy East, LLC -// https://www.iana.org/domains/root/db/godaddy.html -godaddy - -// gold : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gold.html -gold - -// goldpoint : YODOBASHI CAMERA CO.,LTD. -// https://www.iana.org/domains/root/db/goldpoint.html -goldpoint - -// golf : Binky Moon, LLC -// https://www.iana.org/domains/root/db/golf.html -golf - -// goo : NTT DOCOMO, INC. -// https://www.iana.org/domains/root/db/goo.html -goo - -// goodyear : The Goodyear Tire & Rubber Company -// https://www.iana.org/domains/root/db/goodyear.html -goodyear - -// goog : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/goog.html -goog - -// google : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/google.html -google - -// gop : Republican State Leadership Committee, Inc. -// https://www.iana.org/domains/root/db/gop.html -gop - -// got : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/got.html -got - -// grainger : Grainger Registry Services, LLC -// https://www.iana.org/domains/root/db/grainger.html -grainger - -// graphics : Binky Moon, LLC -// https://www.iana.org/domains/root/db/graphics.html -graphics - -// gratis : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gratis.html -gratis - -// green : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/green.html -green - -// gripe : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gripe.html -gripe - -// grocery : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/grocery.html -grocery - -// group : Binky Moon, LLC -// https://www.iana.org/domains/root/db/group.html -group - -// gucci : Guccio Gucci S.p.a. -// https://www.iana.org/domains/root/db/gucci.html -gucci - -// guge : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/guge.html -guge - -// guide : Binky Moon, LLC -// https://www.iana.org/domains/root/db/guide.html -guide - -// guitars : XYZ.COM LLC -// https://www.iana.org/domains/root/db/guitars.html -guitars - -// guru : Binky Moon, LLC -// https://www.iana.org/domains/root/db/guru.html -guru - -// hair : XYZ.COM LLC -// https://www.iana.org/domains/root/db/hair.html -hair - -// hamburg : Hamburg Top-Level-Domain GmbH -// https://www.iana.org/domains/root/db/hamburg.html -hamburg - -// hangout : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/hangout.html -hangout - -// haus : Dog Beach, LLC -// https://www.iana.org/domains/root/db/haus.html -haus - -// hbo : HBO Registry Services, Inc. -// https://www.iana.org/domains/root/db/hbo.html -hbo - -// hdfc : HDFC BANK LIMITED -// https://www.iana.org/domains/root/db/hdfc.html -hdfc - -// hdfcbank : HDFC BANK LIMITED -// https://www.iana.org/domains/root/db/hdfcbank.html -hdfcbank - -// health : Registry Services, LLC -// https://www.iana.org/domains/root/db/health.html -health - -// healthcare : Binky Moon, LLC -// https://www.iana.org/domains/root/db/healthcare.html -healthcare - -// help : Innovation service Limited -// https://www.iana.org/domains/root/db/help.html -help - -// helsinki : City of Helsinki -// https://www.iana.org/domains/root/db/helsinki.html -helsinki - -// here : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/here.html -here - -// hermes : HERMES INTERNATIONAL -// https://www.iana.org/domains/root/db/hermes.html -hermes - -// hiphop : Dot Hip Hop, LLC -// https://www.iana.org/domains/root/db/hiphop.html -hiphop - -// hisamitsu : Hisamitsu Pharmaceutical Co.,Inc. -// https://www.iana.org/domains/root/db/hisamitsu.html -hisamitsu - -// hitachi : Hitachi, Ltd. -// https://www.iana.org/domains/root/db/hitachi.html -hitachi - -// hiv : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/hiv.html -hiv - -// hkt : PCCW-HKT DataCom Services Limited -// https://www.iana.org/domains/root/db/hkt.html -hkt - -// hockey : Binky Moon, LLC -// https://www.iana.org/domains/root/db/hockey.html -hockey - -// holdings : Binky Moon, LLC -// https://www.iana.org/domains/root/db/holdings.html -holdings - -// holiday : Binky Moon, LLC -// https://www.iana.org/domains/root/db/holiday.html -holiday - -// homedepot : Home Depot Product Authority, LLC -// https://www.iana.org/domains/root/db/homedepot.html -homedepot - -// homegoods : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/homegoods.html -homegoods - -// homes : XYZ.COM LLC -// https://www.iana.org/domains/root/db/homes.html -homes - -// homesense : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/homesense.html -homesense - -// honda : Honda Motor Co., Ltd. -// https://www.iana.org/domains/root/db/honda.html -honda - -// horse : Registry Services, LLC -// https://www.iana.org/domains/root/db/horse.html -horse - -// hospital : Binky Moon, LLC -// https://www.iana.org/domains/root/db/hospital.html -hospital - -// host : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/host.html -host - -// hosting : XYZ.COM LLC -// https://www.iana.org/domains/root/db/hosting.html -hosting - -// hot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/hot.html -hot - -// hotel : HOTEL Top-Level-Domain S.a.r.l -// https://www.iana.org/domains/root/db/hotel.html -hotel - -// hotels : Booking.com B.V. -// https://www.iana.org/domains/root/db/hotels.html -hotels - -// hotmail : Microsoft Corporation -// https://www.iana.org/domains/root/db/hotmail.html -hotmail - -// house : Binky Moon, LLC -// https://www.iana.org/domains/root/db/house.html -house - -// how : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/how.html -how - -// hsbc : HSBC Global Services (UK) Limited -// https://www.iana.org/domains/root/db/hsbc.html -hsbc - -// hughes : Hughes Satellite Systems Corporation -// https://www.iana.org/domains/root/db/hughes.html -hughes - -// hyatt : Hyatt GTLD, L.L.C. -// https://www.iana.org/domains/root/db/hyatt.html -hyatt - -// hyundai : Hyundai Motor Company -// https://www.iana.org/domains/root/db/hyundai.html -hyundai - -// ibm : International Business Machines Corporation -// https://www.iana.org/domains/root/db/ibm.html -ibm - -// icbc : Industrial and Commercial Bank of China Limited -// https://www.iana.org/domains/root/db/icbc.html -icbc - -// ice : IntercontinentalExchange, Inc. -// https://www.iana.org/domains/root/db/ice.html -ice - -// icu : ShortDot SA -// https://www.iana.org/domains/root/db/icu.html -icu - -// ieee : IEEE Global LLC -// https://www.iana.org/domains/root/db/ieee.html -ieee - -// ifm : ifm electronic gmbh -// https://www.iana.org/domains/root/db/ifm.html -ifm - -// ikano : Ikano S.A. -// https://www.iana.org/domains/root/db/ikano.html -ikano - -// imamat : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/imamat.html -imamat - -// imdb : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/imdb.html -imdb - -// immo : Binky Moon, LLC -// https://www.iana.org/domains/root/db/immo.html -immo - -// immobilien : Dog Beach, LLC -// https://www.iana.org/domains/root/db/immobilien.html -immobilien - -// inc : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/inc.html -inc - -// industries : Binky Moon, LLC -// https://www.iana.org/domains/root/db/industries.html -industries - -// infiniti : NISSAN MOTOR CO., LTD. -// https://www.iana.org/domains/root/db/infiniti.html -infiniti - -// ing : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/ing.html -ing - -// ink : Registry Services, LLC -// https://www.iana.org/domains/root/db/ink.html -ink - -// institute : Binky Moon, LLC -// https://www.iana.org/domains/root/db/institute.html -institute - -// insurance : fTLD Registry Services LLC -// https://www.iana.org/domains/root/db/insurance.html -insurance - -// insure : Binky Moon, LLC -// https://www.iana.org/domains/root/db/insure.html -insure - -// international : Binky Moon, LLC -// https://www.iana.org/domains/root/db/international.html -international - -// intuit : Intuit Administrative Services, Inc. -// https://www.iana.org/domains/root/db/intuit.html -intuit - -// investments : Binky Moon, LLC -// https://www.iana.org/domains/root/db/investments.html -investments - -// ipiranga : Ipiranga Produtos de Petroleo S.A. -// https://www.iana.org/domains/root/db/ipiranga.html -ipiranga - -// irish : Binky Moon, LLC -// https://www.iana.org/domains/root/db/irish.html -irish - -// ismaili : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/ismaili.html -ismaili - -// ist : Istanbul Metropolitan Municipality -// https://www.iana.org/domains/root/db/ist.html -ist - -// istanbul : Istanbul Metropolitan Municipality -// https://www.iana.org/domains/root/db/istanbul.html -istanbul - -// itau : Itau Unibanco Holding S.A. -// https://www.iana.org/domains/root/db/itau.html -itau - -// itv : ITV Services Limited -// https://www.iana.org/domains/root/db/itv.html -itv - -// jaguar : Jaguar Land Rover Ltd -// https://www.iana.org/domains/root/db/jaguar.html -jaguar - -// java : Oracle Corporation -// https://www.iana.org/domains/root/db/java.html -java - -// jcb : JCB Co., Ltd. -// https://www.iana.org/domains/root/db/jcb.html -jcb - -// jeep : FCA US LLC. -// https://www.iana.org/domains/root/db/jeep.html -jeep - -// jetzt : Binky Moon, LLC -// https://www.iana.org/domains/root/db/jetzt.html -jetzt - -// jewelry : Binky Moon, LLC -// https://www.iana.org/domains/root/db/jewelry.html -jewelry - -// jio : Reliance Industries Limited -// https://www.iana.org/domains/root/db/jio.html -jio - -// jll : Jones Lang LaSalle Incorporated -// https://www.iana.org/domains/root/db/jll.html -jll - -// jmp : Matrix IP LLC -// https://www.iana.org/domains/root/db/jmp.html -jmp - -// jnj : Johnson & Johnson Services, Inc. -// https://www.iana.org/domains/root/db/jnj.html -jnj - -// joburg : ZA Central Registry NPC trading as ZA Central Registry -// https://www.iana.org/domains/root/db/joburg.html -joburg - -// jot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/jot.html -jot - -// joy : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/joy.html -joy - -// jpmorgan : JPMorgan Chase Bank, National Association -// https://www.iana.org/domains/root/db/jpmorgan.html -jpmorgan - -// jprs : Japan Registry Services Co., Ltd. -// https://www.iana.org/domains/root/db/jprs.html -jprs - -// juegos : Dog Beach, LLC -// https://www.iana.org/domains/root/db/juegos.html -juegos - -// juniper : JUNIPER NETWORKS, INC. -// https://www.iana.org/domains/root/db/juniper.html -juniper - -// kaufen : Dog Beach, LLC -// https://www.iana.org/domains/root/db/kaufen.html -kaufen - -// kddi : KDDI CORPORATION -// https://www.iana.org/domains/root/db/kddi.html -kddi - -// kerryhotels : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/kerryhotels.html -kerryhotels - -// kerryproperties : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/kerryproperties.html -kerryproperties - -// kfh : Kuwait Finance House -// https://www.iana.org/domains/root/db/kfh.html -kfh - -// kia : KIA MOTORS CORPORATION -// https://www.iana.org/domains/root/db/kia.html -kia - -// kids : DotKids Foundation Limited -// https://www.iana.org/domains/root/db/kids.html -kids - -// kim : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/kim.html -kim - -// kindle : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/kindle.html -kindle - -// kitchen : Binky Moon, LLC -// https://www.iana.org/domains/root/db/kitchen.html -kitchen - -// kiwi : DOT KIWI LIMITED -// https://www.iana.org/domains/root/db/kiwi.html -kiwi - -// koeln : dotKoeln GmbH -// https://www.iana.org/domains/root/db/koeln.html -koeln - -// komatsu : Komatsu Ltd. -// https://www.iana.org/domains/root/db/komatsu.html -komatsu - -// kosher : Kosher Marketing Assets LLC -// https://www.iana.org/domains/root/db/kosher.html -kosher - -// kpmg : KPMG International Cooperative (KPMG International Genossenschaft) -// https://www.iana.org/domains/root/db/kpmg.html -kpmg - -// kpn : Koninklijke KPN N.V. -// https://www.iana.org/domains/root/db/kpn.html -kpn - -// krd : KRG Department of Information Technology -// https://www.iana.org/domains/root/db/krd.html -krd - -// kred : KredTLD Pty Ltd -// https://www.iana.org/domains/root/db/kred.html -kred - -// kuokgroup : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/kuokgroup.html -kuokgroup - -// kyoto : Academic Institution: Kyoto Jyoho Gakuen -// https://www.iana.org/domains/root/db/kyoto.html -kyoto - -// lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” -// https://www.iana.org/domains/root/db/lacaixa.html -lacaixa - -// lamborghini : Automobili Lamborghini S.p.A. -// https://www.iana.org/domains/root/db/lamborghini.html -lamborghini - -// lamer : The Estée Lauder Companies Inc. -// https://www.iana.org/domains/root/db/lamer.html -lamer - -// land : Binky Moon, LLC -// https://www.iana.org/domains/root/db/land.html -land - -// landrover : Jaguar Land Rover Ltd -// https://www.iana.org/domains/root/db/landrover.html -landrover - -// lanxess : LANXESS Corporation -// https://www.iana.org/domains/root/db/lanxess.html -lanxess - -// lasalle : Jones Lang LaSalle Incorporated -// https://www.iana.org/domains/root/db/lasalle.html -lasalle - -// lat : XYZ.COM LLC -// https://www.iana.org/domains/root/db/lat.html -lat - -// latino : Dish DBS Corporation -// https://www.iana.org/domains/root/db/latino.html -latino - -// latrobe : La Trobe University -// https://www.iana.org/domains/root/db/latrobe.html -latrobe - -// law : Registry Services, LLC -// https://www.iana.org/domains/root/db/law.html -law - -// lawyer : Dog Beach, LLC -// https://www.iana.org/domains/root/db/lawyer.html -lawyer - -// lds : IRI Domain Management, LLC -// https://www.iana.org/domains/root/db/lds.html -lds - -// lease : Binky Moon, LLC -// https://www.iana.org/domains/root/db/lease.html -lease - -// leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc -// https://www.iana.org/domains/root/db/leclerc.html -leclerc - -// lefrak : LeFrak Organization, Inc. -// https://www.iana.org/domains/root/db/lefrak.html -lefrak - -// legal : Binky Moon, LLC -// https://www.iana.org/domains/root/db/legal.html -legal - -// lego : LEGO Juris A/S -// https://www.iana.org/domains/root/db/lego.html -lego - -// lexus : TOYOTA MOTOR CORPORATION -// https://www.iana.org/domains/root/db/lexus.html -lexus - -// lgbt : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/lgbt.html -lgbt - -// lidl : Schwarz Domains und Services GmbH & Co. KG -// https://www.iana.org/domains/root/db/lidl.html -lidl - -// life : Binky Moon, LLC -// https://www.iana.org/domains/root/db/life.html -life - -// lifeinsurance : American Council of Life Insurers -// https://www.iana.org/domains/root/db/lifeinsurance.html -lifeinsurance - -// lifestyle : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/lifestyle.html -lifestyle - -// lighting : Binky Moon, LLC -// https://www.iana.org/domains/root/db/lighting.html -lighting - -// like : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/like.html -like - -// lilly : Eli Lilly and Company -// https://www.iana.org/domains/root/db/lilly.html -lilly - -// limited : Binky Moon, LLC -// https://www.iana.org/domains/root/db/limited.html -limited - -// limo : Binky Moon, LLC -// https://www.iana.org/domains/root/db/limo.html -limo - -// lincoln : Ford Motor Company -// https://www.iana.org/domains/root/db/lincoln.html -lincoln - -// link : Nova Registry Ltd -// https://www.iana.org/domains/root/db/link.html -link - -// live : Dog Beach, LLC -// https://www.iana.org/domains/root/db/live.html -live - -// living : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/living.html -living - -// llc : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/llc.html -llc - -// llp : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/llp.html -llp - -// loan : dot Loan Limited -// https://www.iana.org/domains/root/db/loan.html -loan - -// loans : Binky Moon, LLC -// https://www.iana.org/domains/root/db/loans.html -loans - -// locker : Orange Domains LLC -// https://www.iana.org/domains/root/db/locker.html -locker - -// locus : Locus Analytics LLC -// https://www.iana.org/domains/root/db/locus.html -locus - -// lol : XYZ.COM LLC -// https://www.iana.org/domains/root/db/lol.html -lol - -// london : Dot London Domains Limited -// https://www.iana.org/domains/root/db/london.html -london - -// lotte : Lotte Holdings Co., Ltd. -// https://www.iana.org/domains/root/db/lotte.html -lotte - -// lotto : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/lotto.html -lotto - -// love : Waterford Limited -// https://www.iana.org/domains/root/db/love.html -love - -// lpl : LPL Holdings, Inc. -// https://www.iana.org/domains/root/db/lpl.html -lpl - -// lplfinancial : LPL Holdings, Inc. -// https://www.iana.org/domains/root/db/lplfinancial.html -lplfinancial - -// ltd : Binky Moon, LLC -// https://www.iana.org/domains/root/db/ltd.html -ltd - -// ltda : InterNetX, Corp -// https://www.iana.org/domains/root/db/ltda.html -ltda - -// lundbeck : H. Lundbeck A/S -// https://www.iana.org/domains/root/db/lundbeck.html -lundbeck - -// luxe : Registry Services, LLC -// https://www.iana.org/domains/root/db/luxe.html -luxe - -// luxury : Luxury Partners, LLC -// https://www.iana.org/domains/root/db/luxury.html -luxury - -// madrid : Comunidad de Madrid -// https://www.iana.org/domains/root/db/madrid.html -madrid - -// maif : Mutuelle Assurance Instituteur France (MAIF) -// https://www.iana.org/domains/root/db/maif.html -maif - -// maison : Binky Moon, LLC -// https://www.iana.org/domains/root/db/maison.html -maison - -// makeup : XYZ.COM LLC -// https://www.iana.org/domains/root/db/makeup.html -makeup - -// man : MAN Truck & Bus SE -// https://www.iana.org/domains/root/db/man.html -man - -// management : Binky Moon, LLC -// https://www.iana.org/domains/root/db/management.html -management - -// mango : PUNTO FA S.L. -// https://www.iana.org/domains/root/db/mango.html -mango - -// map : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/map.html -map - -// market : Dog Beach, LLC -// https://www.iana.org/domains/root/db/market.html -market - -// marketing : Binky Moon, LLC -// https://www.iana.org/domains/root/db/marketing.html -marketing - -// markets : Dog Beach, LLC -// https://www.iana.org/domains/root/db/markets.html -markets - -// marriott : Marriott Worldwide Corporation -// https://www.iana.org/domains/root/db/marriott.html -marriott - -// marshalls : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/marshalls.html -marshalls - -// mattel : Mattel IT Services, Inc. -// https://www.iana.org/domains/root/db/mattel.html -mattel - -// mba : Binky Moon, LLC -// https://www.iana.org/domains/root/db/mba.html -mba - -// mckinsey : McKinsey Holdings, Inc. -// https://www.iana.org/domains/root/db/mckinsey.html -mckinsey - -// med : Medistry LLC -// https://www.iana.org/domains/root/db/med.html -med - -// media : Binky Moon, LLC -// https://www.iana.org/domains/root/db/media.html -media - -// meet : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/meet.html -meet - -// melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation -// https://www.iana.org/domains/root/db/melbourne.html -melbourne - -// meme : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/meme.html -meme - -// memorial : Dog Beach, LLC -// https://www.iana.org/domains/root/db/memorial.html -memorial - -// men : Exclusive Registry Limited -// https://www.iana.org/domains/root/db/men.html -men - -// menu : Dot Menu Registry, LLC -// https://www.iana.org/domains/root/db/menu.html -menu - -// merck : Merck Registry Holdings, Inc. -// https://www.iana.org/domains/root/db/merck.html -merck - -// merckmsd : MSD Registry Holdings, Inc. -// https://www.iana.org/domains/root/db/merckmsd.html -merckmsd - -// miami : Registry Services, LLC -// https://www.iana.org/domains/root/db/miami.html -miami - -// microsoft : Microsoft Corporation -// https://www.iana.org/domains/root/db/microsoft.html -microsoft - -// mini : Bayerische Motoren Werke Aktiengesellschaft -// https://www.iana.org/domains/root/db/mini.html -mini - -// mint : Intuit Administrative Services, Inc. -// https://www.iana.org/domains/root/db/mint.html -mint - -// mit : Massachusetts Institute of Technology -// https://www.iana.org/domains/root/db/mit.html -mit - -// mitsubishi : Mitsubishi Corporation -// https://www.iana.org/domains/root/db/mitsubishi.html -mitsubishi - -// mlb : MLB Advanced Media DH, LLC -// https://www.iana.org/domains/root/db/mlb.html -mlb - -// mls : The Canadian Real Estate Association -// https://www.iana.org/domains/root/db/mls.html -mls - -// mma : MMA IARD -// https://www.iana.org/domains/root/db/mma.html -mma - -// mobile : Dish DBS Corporation -// https://www.iana.org/domains/root/db/mobile.html -mobile - -// moda : Dog Beach, LLC -// https://www.iana.org/domains/root/db/moda.html -moda - -// moe : Interlink Systems Innovation Institute K.K. -// https://www.iana.org/domains/root/db/moe.html -moe - -// moi : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/moi.html -moi - -// mom : XYZ.COM LLC -// https://www.iana.org/domains/root/db/mom.html -mom - -// monash : Monash University -// https://www.iana.org/domains/root/db/monash.html -monash - -// money : Binky Moon, LLC -// https://www.iana.org/domains/root/db/money.html -money - -// monster : XYZ.COM LLC -// https://www.iana.org/domains/root/db/monster.html -monster - -// mormon : IRI Domain Management, LLC -// https://www.iana.org/domains/root/db/mormon.html -mormon - -// mortgage : Dog Beach, LLC -// https://www.iana.org/domains/root/db/mortgage.html -mortgage - -// moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) -// https://www.iana.org/domains/root/db/moscow.html -moscow - -// moto : Motorola Trademark Holdings, LLC -// https://www.iana.org/domains/root/db/moto.html -moto - -// motorcycles : XYZ.COM LLC -// https://www.iana.org/domains/root/db/motorcycles.html -motorcycles - -// mov : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/mov.html -mov - -// movie : Binky Moon, LLC -// https://www.iana.org/domains/root/db/movie.html -movie - -// msd : MSD Registry Holdings, Inc. -// https://www.iana.org/domains/root/db/msd.html -msd - -// mtn : MTN Dubai Limited -// https://www.iana.org/domains/root/db/mtn.html -mtn - -// mtr : MTR Corporation Limited -// https://www.iana.org/domains/root/db/mtr.html -mtr - -// music : DotMusic Limited -// https://www.iana.org/domains/root/db/music.html -music - -// nab : National Australia Bank Limited -// https://www.iana.org/domains/root/db/nab.html -nab - -// nagoya : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/nagoya.html -nagoya - -// navy : Dog Beach, LLC -// https://www.iana.org/domains/root/db/navy.html -navy - -// nba : NBA REGISTRY, LLC -// https://www.iana.org/domains/root/db/nba.html -nba - -// nec : NEC Corporation -// https://www.iana.org/domains/root/db/nec.html -nec - -// netbank : COMMONWEALTH BANK OF AUSTRALIA -// https://www.iana.org/domains/root/db/netbank.html -netbank - -// netflix : Netflix, Inc. -// https://www.iana.org/domains/root/db/netflix.html -netflix - -// network : Binky Moon, LLC -// https://www.iana.org/domains/root/db/network.html -network - -// neustar : NeuStar, Inc. -// https://www.iana.org/domains/root/db/neustar.html -neustar - -// new : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/new.html -new - -// news : Dog Beach, LLC -// https://www.iana.org/domains/root/db/news.html -news - -// next : Next plc -// https://www.iana.org/domains/root/db/next.html -next - -// nextdirect : Next plc -// https://www.iana.org/domains/root/db/nextdirect.html -nextdirect - -// nexus : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/nexus.html -nexus - -// nfl : NFL Reg Ops LLC -// https://www.iana.org/domains/root/db/nfl.html -nfl - -// ngo : Public Interest Registry -// https://www.iana.org/domains/root/db/ngo.html -ngo - -// nhk : Japan Broadcasting Corporation (NHK) -// https://www.iana.org/domains/root/db/nhk.html -nhk - -// nico : DWANGO Co., Ltd. -// https://www.iana.org/domains/root/db/nico.html -nico - -// nike : NIKE, Inc. -// https://www.iana.org/domains/root/db/nike.html -nike - -// nikon : NIKON CORPORATION -// https://www.iana.org/domains/root/db/nikon.html -nikon - -// ninja : Dog Beach, LLC -// https://www.iana.org/domains/root/db/ninja.html -ninja - -// nissan : NISSAN MOTOR CO., LTD. -// https://www.iana.org/domains/root/db/nissan.html -nissan - -// nissay : Nippon Life Insurance Company -// https://www.iana.org/domains/root/db/nissay.html -nissay - -// nokia : Nokia Corporation -// https://www.iana.org/domains/root/db/nokia.html -nokia - -// norton : Gen Digital Inc. -// https://www.iana.org/domains/root/db/norton.html -norton - -// now : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/now.html -now - -// nowruz -// https://www.iana.org/domains/root/db/nowruz.html -nowruz - -// nowtv : Starbucks (HK) Limited -// https://www.iana.org/domains/root/db/nowtv.html -nowtv - -// nra : National Rifle Association of America -// https://www.iana.org/domains/root/db/nra.html -nra - -// nrw : Minds + Machines GmbH -// https://www.iana.org/domains/root/db/nrw.html -nrw - -// ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION -// https://www.iana.org/domains/root/db/ntt.html -ntt - -// nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications -// https://www.iana.org/domains/root/db/nyc.html -nyc - -// obi : OBI Group Holding SE & Co. KGaA -// https://www.iana.org/domains/root/db/obi.html -obi - -// observer : Fegistry, LLC -// https://www.iana.org/domains/root/db/observer.html -observer - -// office : Microsoft Corporation -// https://www.iana.org/domains/root/db/office.html -office - -// okinawa : BRregistry, Inc. -// https://www.iana.org/domains/root/db/okinawa.html -okinawa - -// olayan : Competrol (Luxembourg) Sarl -// https://www.iana.org/domains/root/db/olayan.html -olayan - -// olayangroup : Competrol (Luxembourg) Sarl -// https://www.iana.org/domains/root/db/olayangroup.html -olayangroup - -// ollo : Dish DBS Corporation -// https://www.iana.org/domains/root/db/ollo.html -ollo - -// omega : The Swatch Group Ltd -// https://www.iana.org/domains/root/db/omega.html -omega - -// one : One.com A/S -// https://www.iana.org/domains/root/db/one.html -one - -// ong : Public Interest Registry -// https://www.iana.org/domains/root/db/ong.html -ong - -// onl : iRegistry GmbH -// https://www.iana.org/domains/root/db/onl.html -onl - -// online : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/online.html -online - -// ooo : INFIBEAM AVENUES LIMITED -// https://www.iana.org/domains/root/db/ooo.html -ooo - -// open : American Express Travel Related Services Company, Inc. -// https://www.iana.org/domains/root/db/open.html -open - -// oracle : Oracle Corporation -// https://www.iana.org/domains/root/db/oracle.html -oracle - -// orange : Orange Brand Services Limited -// https://www.iana.org/domains/root/db/orange.html -orange - -// organic : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/organic.html -organic - -// origins : The Estée Lauder Companies Inc. -// https://www.iana.org/domains/root/db/origins.html -origins - -// osaka : Osaka Registry Co., Ltd. -// https://www.iana.org/domains/root/db/osaka.html -osaka - -// otsuka : Otsuka Holdings Co., Ltd. -// https://www.iana.org/domains/root/db/otsuka.html -otsuka - -// ott : Dish DBS Corporation -// https://www.iana.org/domains/root/db/ott.html -ott - -// ovh : MédiaBC -// https://www.iana.org/domains/root/db/ovh.html -ovh - -// page : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/page.html -page - -// panasonic : Panasonic Holdings Corporation -// https://www.iana.org/domains/root/db/panasonic.html -panasonic - -// paris : City of Paris -// https://www.iana.org/domains/root/db/paris.html -paris - -// pars -// https://www.iana.org/domains/root/db/pars.html -pars - -// partners : Binky Moon, LLC -// https://www.iana.org/domains/root/db/partners.html -partners - -// parts : Binky Moon, LLC -// https://www.iana.org/domains/root/db/parts.html -parts - -// party : Blue Sky Registry Limited -// https://www.iana.org/domains/root/db/party.html -party - -// pay : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/pay.html -pay - -// pccw : PCCW Enterprises Limited -// https://www.iana.org/domains/root/db/pccw.html -pccw - -// pet : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/pet.html -pet - -// pfizer : Pfizer Inc. -// https://www.iana.org/domains/root/db/pfizer.html -pfizer - -// pharmacy : National Association of Boards of Pharmacy -// https://www.iana.org/domains/root/db/pharmacy.html -pharmacy - -// phd : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/phd.html -phd - -// philips : Koninklijke Philips N.V. -// https://www.iana.org/domains/root/db/philips.html -philips - -// phone : Dish DBS Corporation -// https://www.iana.org/domains/root/db/phone.html -phone - -// photo : Registry Services, LLC -// https://www.iana.org/domains/root/db/photo.html -photo - -// photography : Binky Moon, LLC -// https://www.iana.org/domains/root/db/photography.html -photography - -// photos : Binky Moon, LLC -// https://www.iana.org/domains/root/db/photos.html -photos - -// physio : PhysBiz Pty Ltd -// https://www.iana.org/domains/root/db/physio.html -physio - -// pics : XYZ.COM LLC -// https://www.iana.org/domains/root/db/pics.html -pics - -// pictet : Banque Pictet & Cie SA -// https://www.iana.org/domains/root/db/pictet.html -pictet - -// pictures : Binky Moon, LLC -// https://www.iana.org/domains/root/db/pictures.html -pictures - -// pid : Top Level Spectrum, Inc. -// https://www.iana.org/domains/root/db/pid.html -pid - -// pin : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/pin.html -pin - -// ping : Ping Registry Provider, Inc. -// https://www.iana.org/domains/root/db/ping.html -ping - -// pink : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/pink.html -pink - -// pioneer : Pioneer Corporation -// https://www.iana.org/domains/root/db/pioneer.html -pioneer - -// pizza : Binky Moon, LLC -// https://www.iana.org/domains/root/db/pizza.html -pizza - -// place : Binky Moon, LLC -// https://www.iana.org/domains/root/db/place.html -place - -// play : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/play.html -play - -// playstation : Sony Interactive Entertainment Inc. -// https://www.iana.org/domains/root/db/playstation.html -playstation - -// plumbing : Binky Moon, LLC -// https://www.iana.org/domains/root/db/plumbing.html -plumbing - -// plus : Binky Moon, LLC -// https://www.iana.org/domains/root/db/plus.html -plus - -// pnc : PNC Domain Co., LLC -// https://www.iana.org/domains/root/db/pnc.html -pnc - -// pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/pohl.html -pohl - -// poker : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/poker.html -poker - -// politie : Politie Nederland -// https://www.iana.org/domains/root/db/politie.html -politie - -// porn : ICM Registry PN LLC -// https://www.iana.org/domains/root/db/porn.html -porn - -// praxi : Praxi S.p.A. -// https://www.iana.org/domains/root/db/praxi.html -praxi - -// press : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/press.html -press - -// prime : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/prime.html -prime - -// prod : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/prod.html -prod - -// productions : Binky Moon, LLC -// https://www.iana.org/domains/root/db/productions.html -productions - -// prof : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/prof.html -prof - -// progressive : Progressive Casualty Insurance Company -// https://www.iana.org/domains/root/db/progressive.html -progressive - -// promo : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/promo.html -promo - -// properties : Binky Moon, LLC -// https://www.iana.org/domains/root/db/properties.html -properties - -// property : Digital Property Infrastructure Limited -// https://www.iana.org/domains/root/db/property.html -property - -// protection : XYZ.COM LLC -// https://www.iana.org/domains/root/db/protection.html -protection - -// pru : Prudential Financial, Inc. -// https://www.iana.org/domains/root/db/pru.html -pru - -// prudential : Prudential Financial, Inc. -// https://www.iana.org/domains/root/db/prudential.html -prudential - -// pub : Dog Beach, LLC -// https://www.iana.org/domains/root/db/pub.html -pub - -// pwc : PricewaterhouseCoopers LLP -// https://www.iana.org/domains/root/db/pwc.html -pwc - -// qpon : dotQPON LLC -// https://www.iana.org/domains/root/db/qpon.html -qpon - -// quebec : PointQuébec Inc -// https://www.iana.org/domains/root/db/quebec.html -quebec - -// quest : XYZ.COM LLC -// https://www.iana.org/domains/root/db/quest.html -quest - -// racing : Premier Registry Limited -// https://www.iana.org/domains/root/db/racing.html -racing - -// radio : European Broadcasting Union (EBU) -// https://www.iana.org/domains/root/db/radio.html -radio - -// read : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/read.html -read - -// realestate : dotRealEstate LLC -// https://www.iana.org/domains/root/db/realestate.html -realestate - -// realtor : Real Estate Domains LLC -// https://www.iana.org/domains/root/db/realtor.html -realtor - -// realty : Waterford Limited -// https://www.iana.org/domains/root/db/realty.html -realty - -// recipes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/recipes.html -recipes - -// red : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/red.html -red - -// redumbrella : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/redumbrella.html -redumbrella - -// rehab : Dog Beach, LLC -// https://www.iana.org/domains/root/db/rehab.html -rehab - -// reise : Binky Moon, LLC -// https://www.iana.org/domains/root/db/reise.html -reise - -// reisen : Binky Moon, LLC -// https://www.iana.org/domains/root/db/reisen.html -reisen - -// reit : National Association of Real Estate Investment Trusts, Inc. -// https://www.iana.org/domains/root/db/reit.html -reit - -// reliance : Reliance Industries Limited -// https://www.iana.org/domains/root/db/reliance.html -reliance - -// ren : ZDNS International Limited -// https://www.iana.org/domains/root/db/ren.html -ren - -// rent : XYZ.COM LLC -// https://www.iana.org/domains/root/db/rent.html -rent - -// rentals : Binky Moon, LLC -// https://www.iana.org/domains/root/db/rentals.html -rentals - -// repair : Binky Moon, LLC -// https://www.iana.org/domains/root/db/repair.html -repair - -// report : Binky Moon, LLC -// https://www.iana.org/domains/root/db/report.html -report - -// republican : Dog Beach, LLC -// https://www.iana.org/domains/root/db/republican.html -republican - -// rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable -// https://www.iana.org/domains/root/db/rest.html -rest - -// restaurant : Binky Moon, LLC -// https://www.iana.org/domains/root/db/restaurant.html -restaurant - -// review : dot Review Limited -// https://www.iana.org/domains/root/db/review.html -review - -// reviews : Dog Beach, LLC -// https://www.iana.org/domains/root/db/reviews.html -reviews - -// rexroth : Robert Bosch GMBH -// https://www.iana.org/domains/root/db/rexroth.html -rexroth - -// rich : iRegistry GmbH -// https://www.iana.org/domains/root/db/rich.html -rich - -// richardli : Pacific Century Asset Management (HK) Limited -// https://www.iana.org/domains/root/db/richardli.html -richardli - -// ricoh : Ricoh Company, Ltd. -// https://www.iana.org/domains/root/db/ricoh.html -ricoh - -// ril : Reliance Industries Limited -// https://www.iana.org/domains/root/db/ril.html -ril - -// rio : Empresa Municipal de Informática SA - IPLANRIO -// https://www.iana.org/domains/root/db/rio.html -rio - -// rip : Dog Beach, LLC -// https://www.iana.org/domains/root/db/rip.html -rip - -// rocks : Dog Beach, LLC -// https://www.iana.org/domains/root/db/rocks.html -rocks - -// rodeo : Registry Services, LLC -// https://www.iana.org/domains/root/db/rodeo.html -rodeo - -// rogers : Rogers Communications Canada Inc. -// https://www.iana.org/domains/root/db/rogers.html -rogers - -// room : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/room.html -room - -// rsvp : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/rsvp.html -rsvp - -// rugby : World Rugby Strategic Developments Limited -// https://www.iana.org/domains/root/db/rugby.html -rugby - -// ruhr : dotSaarland GmbH -// https://www.iana.org/domains/root/db/ruhr.html -ruhr - -// run : Binky Moon, LLC -// https://www.iana.org/domains/root/db/run.html -run - -// rwe : RWE AG -// https://www.iana.org/domains/root/db/rwe.html -rwe - -// ryukyu : BRregistry, Inc. -// https://www.iana.org/domains/root/db/ryukyu.html -ryukyu - -// saarland : dotSaarland GmbH -// https://www.iana.org/domains/root/db/saarland.html -saarland - -// safe : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/safe.html -safe - -// safety : Safety Registry Services, LLC. -// https://www.iana.org/domains/root/db/safety.html -safety - -// sakura : SAKURA Internet Inc. -// https://www.iana.org/domains/root/db/sakura.html -sakura - -// sale : Dog Beach, LLC -// https://www.iana.org/domains/root/db/sale.html -sale - -// salon : Binky Moon, LLC -// https://www.iana.org/domains/root/db/salon.html -salon - -// samsclub : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/samsclub.html -samsclub - -// samsung : SAMSUNG SDS CO., LTD -// https://www.iana.org/domains/root/db/samsung.html -samsung - -// sandvik : Sandvik AB -// https://www.iana.org/domains/root/db/sandvik.html -sandvik - -// sandvikcoromant : Sandvik AB -// https://www.iana.org/domains/root/db/sandvikcoromant.html -sandvikcoromant - -// sanofi : Sanofi -// https://www.iana.org/domains/root/db/sanofi.html -sanofi - -// sap : SAP AG -// https://www.iana.org/domains/root/db/sap.html -sap - -// sarl : Binky Moon, LLC -// https://www.iana.org/domains/root/db/sarl.html -sarl - -// sas : Research IP LLC -// https://www.iana.org/domains/root/db/sas.html -sas - -// save : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/save.html -save - -// saxo : Saxo Bank A/S -// https://www.iana.org/domains/root/db/saxo.html -saxo - -// sbi : STATE BANK OF INDIA -// https://www.iana.org/domains/root/db/sbi.html -sbi - -// sbs : ShortDot SA -// https://www.iana.org/domains/root/db/sbs.html -sbs - -// scb : The Siam Commercial Bank Public Company Limited ("SCB") -// https://www.iana.org/domains/root/db/scb.html -scb - -// schaeffler : Schaeffler Technologies AG & Co. KG -// https://www.iana.org/domains/root/db/schaeffler.html -schaeffler - -// schmidt : SCHMIDT GROUPE S.A.S. -// https://www.iana.org/domains/root/db/schmidt.html -schmidt - -// scholarships : Scholarships.com, LLC -// https://www.iana.org/domains/root/db/scholarships.html -scholarships - -// school : Binky Moon, LLC -// https://www.iana.org/domains/root/db/school.html -school - -// schule : Binky Moon, LLC -// https://www.iana.org/domains/root/db/schule.html -schule - -// schwarz : Schwarz Domains und Services GmbH & Co. KG -// https://www.iana.org/domains/root/db/schwarz.html -schwarz - -// science : dot Science Limited -// https://www.iana.org/domains/root/db/science.html -science - -// scot : Dot Scot Registry Limited -// https://www.iana.org/domains/root/db/scot.html -scot - -// search : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/search.html -search - -// seat : SEAT, S.A. (Sociedad Unipersonal) -// https://www.iana.org/domains/root/db/seat.html -seat - -// secure : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/secure.html -secure - -// security : XYZ.COM LLC -// https://www.iana.org/domains/root/db/security.html -security - -// seek : Seek Limited -// https://www.iana.org/domains/root/db/seek.html -seek - -// select : Registry Services, LLC -// https://www.iana.org/domains/root/db/select.html -select - -// sener : Sener Ingeniería y Sistemas, S.A. -// https://www.iana.org/domains/root/db/sener.html -sener - -// services : Binky Moon, LLC -// https://www.iana.org/domains/root/db/services.html -services - -// seven : Seven West Media Ltd -// https://www.iana.org/domains/root/db/seven.html -seven - -// sew : SEW-EURODRIVE GmbH & Co KG -// https://www.iana.org/domains/root/db/sew.html -sew - -// sex : ICM Registry SX LLC -// https://www.iana.org/domains/root/db/sex.html -sex - -// sexy : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/sexy.html -sexy - -// sfr : Societe Francaise du Radiotelephone - SFR -// https://www.iana.org/domains/root/db/sfr.html -sfr - -// shangrila : Shangri‐La International Hotel Management Limited -// https://www.iana.org/domains/root/db/shangrila.html -shangrila - -// sharp : Sharp Corporation -// https://www.iana.org/domains/root/db/sharp.html -sharp - -// shell : Shell Information Technology International Inc -// https://www.iana.org/domains/root/db/shell.html -shell - -// shia -// https://www.iana.org/domains/root/db/shia.html -shia - -// shiksha : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/shiksha.html -shiksha - -// shoes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/shoes.html -shoes - -// shop : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/shop.html -shop - -// shopping : Binky Moon, LLC -// https://www.iana.org/domains/root/db/shopping.html -shopping - -// shouji : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/shouji.html -shouji - -// show : Binky Moon, LLC -// https://www.iana.org/domains/root/db/show.html -show - -// silk : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/silk.html -silk - -// sina : Sina Corporation -// https://www.iana.org/domains/root/db/sina.html -sina - -// singles : Binky Moon, LLC -// https://www.iana.org/domains/root/db/singles.html -singles - -// site : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/site.html -site - -// ski : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/ski.html -ski - -// skin : XYZ.COM LLC -// https://www.iana.org/domains/root/db/skin.html -skin - -// sky : Sky UK Limited -// https://www.iana.org/domains/root/db/sky.html -sky - -// skype : Microsoft Corporation -// https://www.iana.org/domains/root/db/skype.html -skype - -// sling : DISH Technologies L.L.C. -// https://www.iana.org/domains/root/db/sling.html -sling - -// smart : Smart Communications, Inc. (SMART) -// https://www.iana.org/domains/root/db/smart.html -smart - -// smile : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/smile.html -smile - -// sncf : Société Nationale SNCF -// https://www.iana.org/domains/root/db/sncf.html -sncf - -// soccer : Binky Moon, LLC -// https://www.iana.org/domains/root/db/soccer.html -soccer - -// social : Dog Beach, LLC -// https://www.iana.org/domains/root/db/social.html -social - -// softbank : SoftBank Group Corp. -// https://www.iana.org/domains/root/db/softbank.html -softbank - -// software : Dog Beach, LLC -// https://www.iana.org/domains/root/db/software.html -software - -// sohu : Sohu.com Limited -// https://www.iana.org/domains/root/db/sohu.html -sohu - -// solar : Binky Moon, LLC -// https://www.iana.org/domains/root/db/solar.html -solar - -// solutions : Binky Moon, LLC -// https://www.iana.org/domains/root/db/solutions.html -solutions - -// song : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/song.html -song - -// sony : Sony Corporation -// https://www.iana.org/domains/root/db/sony.html -sony - -// soy : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/soy.html -soy - -// spa : Asia Spa and Wellness Promotion Council Limited -// https://www.iana.org/domains/root/db/spa.html -spa - -// space : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/space.html -space - -// sport : SportAccord -// https://www.iana.org/domains/root/db/sport.html -sport - -// spot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/spot.html -spot - -// srl : InterNetX, Corp -// https://www.iana.org/domains/root/db/srl.html -srl - -// stada : STADA Arzneimittel AG -// https://www.iana.org/domains/root/db/stada.html -stada - -// staples : Staples, Inc. -// https://www.iana.org/domains/root/db/staples.html -staples - -// star : Star India Private Limited -// https://www.iana.org/domains/root/db/star.html -star - -// statebank : STATE BANK OF INDIA -// https://www.iana.org/domains/root/db/statebank.html -statebank - -// statefarm : State Farm Mutual Automobile Insurance Company -// https://www.iana.org/domains/root/db/statefarm.html -statefarm - -// stc : Saudi Telecom Company -// https://www.iana.org/domains/root/db/stc.html -stc - -// stcgroup : Saudi Telecom Company -// https://www.iana.org/domains/root/db/stcgroup.html -stcgroup - -// stockholm : Stockholms kommun -// https://www.iana.org/domains/root/db/stockholm.html -stockholm - -// storage : XYZ.COM LLC -// https://www.iana.org/domains/root/db/storage.html -storage - -// store : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/store.html -store - -// stream : dot Stream Limited -// https://www.iana.org/domains/root/db/stream.html -stream - -// studio : Dog Beach, LLC -// https://www.iana.org/domains/root/db/studio.html -studio - -// study : Registry Services, LLC -// https://www.iana.org/domains/root/db/study.html -study - -// style : Binky Moon, LLC -// https://www.iana.org/domains/root/db/style.html -style - -// sucks : Vox Populi Registry Ltd. -// https://www.iana.org/domains/root/db/sucks.html -sucks - -// supplies : Binky Moon, LLC -// https://www.iana.org/domains/root/db/supplies.html -supplies - -// supply : Binky Moon, LLC -// https://www.iana.org/domains/root/db/supply.html -supply - -// support : Binky Moon, LLC -// https://www.iana.org/domains/root/db/support.html -support - -// surf : Registry Services, LLC -// https://www.iana.org/domains/root/db/surf.html -surf - -// surgery : Binky Moon, LLC -// https://www.iana.org/domains/root/db/surgery.html -surgery - -// suzuki : SUZUKI MOTOR CORPORATION -// https://www.iana.org/domains/root/db/suzuki.html -suzuki - -// swatch : The Swatch Group Ltd -// https://www.iana.org/domains/root/db/swatch.html -swatch - -// swiss : Swiss Confederation -// https://www.iana.org/domains/root/db/swiss.html -swiss - -// sydney : State of New South Wales, Department of Premier and Cabinet -// https://www.iana.org/domains/root/db/sydney.html -sydney - -// systems : Binky Moon, LLC -// https://www.iana.org/domains/root/db/systems.html -systems - -// tab : Tabcorp Holdings Limited -// https://www.iana.org/domains/root/db/tab.html -tab - -// taipei : Taipei City Government -// https://www.iana.org/domains/root/db/taipei.html -taipei - -// talk : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/talk.html -talk - -// taobao : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/taobao.html -taobao - -// target : Target Domain Holdings, LLC -// https://www.iana.org/domains/root/db/target.html -target - -// tatamotors : Tata Motors Ltd -// https://www.iana.org/domains/root/db/tatamotors.html -tatamotors - -// tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" -// https://www.iana.org/domains/root/db/tatar.html -tatar - -// tattoo : Registry Services, LLC -// https://www.iana.org/domains/root/db/tattoo.html -tattoo - -// tax : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tax.html -tax - -// taxi : Binky Moon, LLC -// https://www.iana.org/domains/root/db/taxi.html -taxi - -// tci -// https://www.iana.org/domains/root/db/tci.html -tci - -// tdk : TDK Corporation -// https://www.iana.org/domains/root/db/tdk.html -tdk - -// team : Binky Moon, LLC -// https://www.iana.org/domains/root/db/team.html -team - -// tech : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/tech.html -tech - -// technology : Binky Moon, LLC -// https://www.iana.org/domains/root/db/technology.html -technology - -// temasek : Temasek Holdings (Private) Limited -// https://www.iana.org/domains/root/db/temasek.html -temasek - -// tennis : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tennis.html -tennis - -// teva : Teva Pharmaceutical Industries Limited -// https://www.iana.org/domains/root/db/teva.html -teva - -// thd : Home Depot Product Authority, LLC -// https://www.iana.org/domains/root/db/thd.html -thd - -// theater : Binky Moon, LLC -// https://www.iana.org/domains/root/db/theater.html -theater - -// theatre : XYZ.COM LLC -// https://www.iana.org/domains/root/db/theatre.html -theatre - -// tiaa : Teachers Insurance and Annuity Association of America -// https://www.iana.org/domains/root/db/tiaa.html -tiaa - -// tickets : XYZ.COM LLC -// https://www.iana.org/domains/root/db/tickets.html -tickets - -// tienda : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tienda.html -tienda - -// tips : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tips.html -tips - -// tires : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tires.html -tires - -// tirol : punkt Tirol GmbH -// https://www.iana.org/domains/root/db/tirol.html -tirol - -// tjmaxx : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/tjmaxx.html -tjmaxx - -// tjx : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/tjx.html -tjx - -// tkmaxx : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/tkmaxx.html -tkmaxx - -// tmall : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/tmall.html -tmall - -// today : Binky Moon, LLC -// https://www.iana.org/domains/root/db/today.html -today - -// tokyo : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/tokyo.html -tokyo - -// tools : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tools.html -tools - -// top : .TOP Registry -// https://www.iana.org/domains/root/db/top.html -top - -// toray : Toray Industries, Inc. -// https://www.iana.org/domains/root/db/toray.html -toray - -// toshiba : TOSHIBA Corporation -// https://www.iana.org/domains/root/db/toshiba.html -toshiba - -// total : TotalEnergies SE -// https://www.iana.org/domains/root/db/total.html -total - -// tours : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tours.html -tours - -// town : Binky Moon, LLC -// https://www.iana.org/domains/root/db/town.html -town - -// toyota : TOYOTA MOTOR CORPORATION -// https://www.iana.org/domains/root/db/toyota.html -toyota - -// toys : Binky Moon, LLC -// https://www.iana.org/domains/root/db/toys.html -toys - -// trade : Elite Registry Limited -// https://www.iana.org/domains/root/db/trade.html -trade - -// trading : Dog Beach, LLC -// https://www.iana.org/domains/root/db/trading.html -trading - -// training : Binky Moon, LLC -// https://www.iana.org/domains/root/db/training.html -training - -// travel : Dog Beach, LLC -// https://www.iana.org/domains/root/db/travel.html -travel - -// travelers : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/travelers.html -travelers - -// travelersinsurance : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/travelersinsurance.html -travelersinsurance - -// trust : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/trust.html -trust - -// trv : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/trv.html -trv - -// tube : Latin American Telecom LLC -// https://www.iana.org/domains/root/db/tube.html -tube - -// tui : TUI AG -// https://www.iana.org/domains/root/db/tui.html -tui - -// tunes : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/tunes.html -tunes - -// tushu : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/tushu.html -tushu - -// tvs : T V SUNDRAM IYENGAR & SONS LIMITED -// https://www.iana.org/domains/root/db/tvs.html -tvs - -// ubank : National Australia Bank Limited -// https://www.iana.org/domains/root/db/ubank.html -ubank - -// ubs : UBS AG -// https://www.iana.org/domains/root/db/ubs.html -ubs - -// unicom : China United Network Communications Corporation Limited -// https://www.iana.org/domains/root/db/unicom.html -unicom - -// university : Binky Moon, LLC -// https://www.iana.org/domains/root/db/university.html -university - -// uno : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/uno.html -uno - -// uol : UBN INTERNET LTDA. -// https://www.iana.org/domains/root/db/uol.html -uol - -// ups : UPS Market Driver, Inc. -// https://www.iana.org/domains/root/db/ups.html -ups - -// vacations : Binky Moon, LLC -// https://www.iana.org/domains/root/db/vacations.html -vacations - -// vana : D3 Registry LLC -// https://www.iana.org/domains/root/db/vana.html -vana - -// vanguard : The Vanguard Group, Inc. -// https://www.iana.org/domains/root/db/vanguard.html -vanguard - -// vegas : Dot Vegas, Inc. -// https://www.iana.org/domains/root/db/vegas.html -vegas - -// ventures : Binky Moon, LLC -// https://www.iana.org/domains/root/db/ventures.html -ventures - -// verisign : VeriSign, Inc. -// https://www.iana.org/domains/root/db/verisign.html -verisign - -// versicherung : tldbox GmbH -// https://www.iana.org/domains/root/db/versicherung.html -versicherung - -// vet : Dog Beach, LLC -// https://www.iana.org/domains/root/db/vet.html -vet - -// viajes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/viajes.html -viajes - -// video : Dog Beach, LLC -// https://www.iana.org/domains/root/db/video.html -video - -// vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe -// https://www.iana.org/domains/root/db/vig.html -vig - -// viking : Viking River Cruises (Bermuda) Ltd. -// https://www.iana.org/domains/root/db/viking.html -viking - -// villas : Binky Moon, LLC -// https://www.iana.org/domains/root/db/villas.html -villas - -// vin : Binky Moon, LLC -// https://www.iana.org/domains/root/db/vin.html -vin - -// vip : Registry Services, LLC -// https://www.iana.org/domains/root/db/vip.html -vip - -// virgin : Virgin Enterprises Limited -// https://www.iana.org/domains/root/db/virgin.html -virgin - -// visa : Visa Worldwide Pte. Limited -// https://www.iana.org/domains/root/db/visa.html -visa - -// vision : Binky Moon, LLC -// https://www.iana.org/domains/root/db/vision.html -vision - -// viva : Saudi Telecom Company -// https://www.iana.org/domains/root/db/viva.html -viva - -// vivo : Telefonica Brasil S.A. -// https://www.iana.org/domains/root/db/vivo.html -vivo - -// vlaanderen : DNS.be vzw -// https://www.iana.org/domains/root/db/vlaanderen.html -vlaanderen - -// vodka : Registry Services, LLC -// https://www.iana.org/domains/root/db/vodka.html -vodka - -// volvo : Volvo Holding Sverige Aktiebolag -// https://www.iana.org/domains/root/db/volvo.html -volvo - -// vote : Monolith Registry LLC -// https://www.iana.org/domains/root/db/vote.html -vote - -// voting : Valuetainment Corp. -// https://www.iana.org/domains/root/db/voting.html -voting - -// voto : Monolith Registry LLC -// https://www.iana.org/domains/root/db/voto.html -voto - -// voyage : Binky Moon, LLC -// https://www.iana.org/domains/root/db/voyage.html -voyage - -// wales : Nominet UK -// https://www.iana.org/domains/root/db/wales.html -wales - -// walmart : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/walmart.html -walmart - -// walter : Sandvik AB -// https://www.iana.org/domains/root/db/walter.html -walter - -// wang : Zodiac Wang Limited -// https://www.iana.org/domains/root/db/wang.html -wang - -// wanggou : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/wanggou.html -wanggou - -// watch : Binky Moon, LLC -// https://www.iana.org/domains/root/db/watch.html -watch - -// watches : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/watches.html -watches - -// weather : International Business Machines Corporation -// https://www.iana.org/domains/root/db/weather.html -weather - -// weatherchannel : The Weather Company, LLC -// https://www.iana.org/domains/root/db/weatherchannel.html -weatherchannel - -// webcam : dot Webcam Limited -// https://www.iana.org/domains/root/db/webcam.html -webcam - -// weber : Saint-Gobain Weber SA -// https://www.iana.org/domains/root/db/weber.html -weber - -// website : Radix Technologies Inc SEZC -// https://www.iana.org/domains/root/db/website.html -website - -// wed -// https://www.iana.org/domains/root/db/wed.html -wed - -// wedding : Registry Services, LLC -// https://www.iana.org/domains/root/db/wedding.html -wedding - -// weibo : Sina Corporation -// https://www.iana.org/domains/root/db/weibo.html -weibo - -// weir : Weir Group IP Limited -// https://www.iana.org/domains/root/db/weir.html -weir - -// whoswho : Who's Who Registry -// https://www.iana.org/domains/root/db/whoswho.html -whoswho - -// wien : punkt.wien GmbH -// https://www.iana.org/domains/root/db/wien.html -wien - -// wiki : Registry Services, LLC -// https://www.iana.org/domains/root/db/wiki.html -wiki - -// williamhill : William Hill Organization Limited -// https://www.iana.org/domains/root/db/williamhill.html -williamhill - -// win : First Registry Limited -// https://www.iana.org/domains/root/db/win.html -win - -// windows : Microsoft Corporation -// https://www.iana.org/domains/root/db/windows.html -windows - -// wine : Binky Moon, LLC -// https://www.iana.org/domains/root/db/wine.html -wine - -// winners : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/winners.html -winners - -// wme : William Morris Endeavor Entertainment, LLC -// https://www.iana.org/domains/root/db/wme.html -wme - -// wolterskluwer : Wolters Kluwer N.V. -// https://www.iana.org/domains/root/db/wolterskluwer.html -wolterskluwer - -// woodside : Woodside Petroleum Limited -// https://www.iana.org/domains/root/db/woodside.html -woodside - -// work : Registry Services, LLC -// https://www.iana.org/domains/root/db/work.html -work - -// works : Binky Moon, LLC -// https://www.iana.org/domains/root/db/works.html -works - -// world : Binky Moon, LLC -// https://www.iana.org/domains/root/db/world.html -world - -// wow : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/wow.html -wow - -// wtc : World Trade Centers Association, Inc. -// https://www.iana.org/domains/root/db/wtc.html -wtc - -// wtf : Binky Moon, LLC -// https://www.iana.org/domains/root/db/wtf.html -wtf - -// xbox : Microsoft Corporation -// https://www.iana.org/domains/root/db/xbox.html -xbox - -// xerox : Xerox DNHC LLC -// https://www.iana.org/domains/root/db/xerox.html -xerox - -// xihuan : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/xihuan.html -xihuan - -// xin : Elegant Leader Limited -// https://www.iana.org/domains/root/db/xin.html -xin - -// xn--11b4c3d : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--11b4c3d.html -कॉम - -// xn--1ck2e1b : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--1ck2e1b.html -セール - -// xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--1qqw23a.html -佛山 - -// xn--30rr7y : Excellent First Limited -// https://www.iana.org/domains/root/db/xn--30rr7y.html -慈善 - -// xn--3bst00m : Eagle Horizon Limited -// https://www.iana.org/domains/root/db/xn--3bst00m.html -集团 - -// xn--3ds443g : Beijing TLD Registry Technology Limited -// https://www.iana.org/domains/root/db/xn--3ds443g.html -在线 - -// xn--3pxu8k : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--3pxu8k.html -点看 - -// xn--42c2d9a : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--42c2d9a.html -คอม - -// xn--45q11c : Zodiac Gemini Ltd -// https://www.iana.org/domains/root/db/xn--45q11c.html -八卦 - -// xn--4gbrim : Helium TLDs Ltd -// https://www.iana.org/domains/root/db/xn--4gbrim.html -موقع - -// xn--55qw42g : China Organizational Name Administration Center -// https://www.iana.org/domains/root/db/xn--55qw42g.html -公益 - -// xn--55qx5d : China Internet Network Information Center (CNNIC) -// https://www.iana.org/domains/root/db/xn--55qx5d.html -公司 - -// xn--5su34j936bgsg : Shangri‐La International Hotel Management Limited -// https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html -香格里拉 - -// xn--5tzm5g : Global Website TLD Asia Limited -// https://www.iana.org/domains/root/db/xn--5tzm5g.html -网站 - -// xn--6frz82g : Identity Digital Domains Limited -// https://www.iana.org/domains/root/db/xn--6frz82g.html -移动 - -// xn--6qq986b3xl : Tycoon Treasure Limited -// https://www.iana.org/domains/root/db/xn--6qq986b3xl.html -我爱你 - -// xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) -// https://www.iana.org/domains/root/db/xn--80adxhks.html -москва - -// xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/xn--80aqecdr1a.html -католик - -// xn--80asehdb : CORE Association -// https://www.iana.org/domains/root/db/xn--80asehdb.html -онлайн - -// xn--80aswg : CORE Association -// https://www.iana.org/domains/root/db/xn--80aswg.html -сайт - -// xn--8y0a063a : China United Network Communications Corporation Limited -// https://www.iana.org/domains/root/db/xn--8y0a063a.html -联通 - -// xn--9dbq2a : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--9dbq2a.html -קום - -// xn--9et52u : RISE VICTORY LIMITED -// https://www.iana.org/domains/root/db/xn--9et52u.html -时尚 - -// xn--9krt00a : Sina Corporation -// https://www.iana.org/domains/root/db/xn--9krt00a.html -微博 - -// xn--b4w605ferd : Temasek Holdings (Private) Limited -// https://www.iana.org/domains/root/db/xn--b4w605ferd.html -淡马锡 - -// xn--bck1b9a5dre4c : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html -ファッション - -// xn--c1avg : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--c1avg.html -орг - -// xn--c2br7g : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--c2br7g.html -नेट - -// xn--cck2b3b : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--cck2b3b.html -ストア - -// xn--cckwcxetd : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--cckwcxetd.html -アマゾン - -// xn--cg4bki : SAMSUNG SDS CO., LTD -// https://www.iana.org/domains/root/db/xn--cg4bki.html -삼성 - -// xn--czr694b : Internet DotTrademark Organisation Limited -// https://www.iana.org/domains/root/db/xn--czr694b.html -商标 - -// xn--czrs0t : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--czrs0t.html -商店 - -// xn--czru2d : Zodiac Aquarius Limited -// https://www.iana.org/domains/root/db/xn--czru2d.html -商城 - -// xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet” -// https://www.iana.org/domains/root/db/xn--d1acj3b.html -дети - -// xn--eckvdtc9d : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--eckvdtc9d.html -ポイント - -// xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--efvy88h.html -新闻 - -// xn--fct429k : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--fct429k.html -家電 - -// xn--fhbei : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--fhbei.html -كوم - -// xn--fiq228c5hs : Beijing TLD Registry Technology Limited -// https://www.iana.org/domains/root/db/xn--fiq228c5hs.html -中文网 - -// xn--fiq64b : CITIC Group Corporation -// https://www.iana.org/domains/root/db/xn--fiq64b.html -中信 - -// xn--fjq720a : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--fjq720a.html -娱乐 - -// xn--flw351e : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/xn--flw351e.html -谷歌 - -// xn--fzys8d69uvgm : PCCW Enterprises Limited -// https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html -電訊盈科 - -// xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD. -// https://www.iana.org/domains/root/db/xn--g2xx48c.html -购物 - -// xn--gckr3f0f : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--gckr3f0f.html -クラウド - -// xn--gk3at1e : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--gk3at1e.html -通販 - -// xn--hxt814e : Zodiac Taurus Limited -// https://www.iana.org/domains/root/db/xn--hxt814e.html -网店 - -// xn--i1b6b1a6a2e : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html -संगठन - -// xn--imr513n : Internet DotTrademark Organisation Limited -// https://www.iana.org/domains/root/db/xn--imr513n.html -餐厅 - -// xn--io0a7i : China Internet Network Information Center (CNNIC) -// https://www.iana.org/domains/root/db/xn--io0a7i.html -网络 - -// xn--j1aef : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--j1aef.html -ком - -// xn--jlq480n2rg : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--jlq480n2rg.html -亚马逊 - -// xn--jvr189m : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--jvr189m.html -食品 - -// xn--kcrx77d1x4a : Koninklijke Philips N.V. -// https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html -飞利浦 - -// xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd -// https://www.iana.org/domains/root/db/xn--kput3i.html -手机 - -// xn--mgba3a3ejt : Aramco Services Company -// https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html -ارامكو - -// xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl -// https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html -العليان - -// xn--mgbab2bd : CORE Association -// https://www.iana.org/domains/root/db/xn--mgbab2bd.html -بازار - -// xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre -// https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html -ابوظبي - -// xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html -كاثوليك - -// xn--mgbt3dhd -// https://www.iana.org/domains/root/db/xn--mgbt3dhd.html -همراه - -// xn--mk1bu44c : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--mk1bu44c.html -닷컴 - -// xn--mxtq1m : Net-Chinese Co., Ltd. -// https://www.iana.org/domains/root/db/xn--mxtq1m.html -政府 - -// xn--ngbc5azd : International Domain Registry Pty. Ltd. -// https://www.iana.org/domains/root/db/xn--ngbc5azd.html -شبكة - -// xn--ngbe9e0a : Kuwait Finance House -// https://www.iana.org/domains/root/db/xn--ngbe9e0a.html -بيتك - -// xn--ngbrx : League of Arab States -// https://www.iana.org/domains/root/db/xn--ngbrx.html -عرب - -// xn--nqv7f : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--nqv7f.html -机构 - -// xn--nqv7fs00ema : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html -组织机构 - -// xn--nyqy26a : Stable Tone Limited -// https://www.iana.org/domains/root/db/xn--nyqy26a.html -健康 - -// xn--otu796d : Jiang Yu Liang Cai Technology Company Limited -// https://www.iana.org/domains/root/db/xn--otu796d.html -招聘 - -// xn--p1acf : Rusnames Limited -// https://www.iana.org/domains/root/db/xn--p1acf.html -рус - -// xn--pssy2u : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--pssy2u.html -大拿 - -// xn--q9jyb4c : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/xn--q9jyb4c.html -みんな - -// xn--qcka1pmc : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/xn--qcka1pmc.html -グーグル - -// xn--rhqv96g : Stable Tone Limited -// https://www.iana.org/domains/root/db/xn--rhqv96g.html -世界 - -// xn--rovu88b : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--rovu88b.html -書籍 - -// xn--ses554g : KNET Co., Ltd. -// https://www.iana.org/domains/root/db/xn--ses554g.html -网址 - -// xn--t60b56a : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--t60b56a.html -닷넷 - -// xn--tckwe : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--tckwe.html -コム - -// xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/xn--tiq49xqyj.html -天主教 - -// xn--unup4y : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--unup4y.html -游戏 - -// xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html -vermögensberater - -// xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html -vermögensberatung - -// xn--vhquv : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--vhquv.html -企业 - -// xn--vuq861b : Beijing Tele-info Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--vuq861b.html -信息 - -// xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html -嘉里大酒店 - -// xn--w4rs40l : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/xn--w4rs40l.html -嘉里 - -// xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--xhq521b.html -广东 - -// xn--zfr164b : China Organizational Name Administration Center -// https://www.iana.org/domains/root/db/xn--zfr164b.html -政务 - -// xyz : XYZ.COM LLC -// https://www.iana.org/domains/root/db/xyz.html -xyz - -// yachts : XYZ.COM LLC -// https://www.iana.org/domains/root/db/yachts.html -yachts - -// yahoo : Yahoo Inc. -// https://www.iana.org/domains/root/db/yahoo.html -yahoo - -// yamaxun : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/yamaxun.html -yamaxun - -// yandex : YANDEX, LLC -// https://www.iana.org/domains/root/db/yandex.html -yandex - -// yodobashi : YODOBASHI CAMERA CO.,LTD. -// https://www.iana.org/domains/root/db/yodobashi.html -yodobashi - -// yoga : Registry Services, LLC -// https://www.iana.org/domains/root/db/yoga.html -yoga - -// yokohama : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/yokohama.html -yokohama - -// you : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/you.html -you - -// youtube : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/youtube.html -youtube - -// yun : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/yun.html -yun - -// zappos : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/zappos.html -zappos - -// zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.) -// https://www.iana.org/domains/root/db/zara.html -zara - -// zero : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/zero.html -zero - -// zip : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/zip.html -zip - -// zone : Binky Moon, LLC -// https://www.iana.org/domains/root/db/zone.html -zone - -// zuerich : Kanton Zürich (Canton of Zurich) -// https://www.iana.org/domains/root/db/zuerich.html -zuerich - -// ===END ICANN DOMAINS=== - -// ===BEGIN PRIVATE DOMAINS=== - -// (Note: these are in alphabetical order by company name) - -// .KRD : https://nic.krd -co.krd -edu.krd - -// .pl domains (grandfathered) -art.pl -gliwice.pl -krakow.pl -poznan.pl -wroc.pl -zakopane.pl - -// 12CHARS : https://12chars.com -// Submitted by Kenny Niehage -12chars.dev -12chars.it -12chars.pro - -// 1GB LLC : https://www.1gb.ua/ -// Submitted by 1GB LLC -cc.ua -inf.ua -ltd.ua - -// 611 blockchain domain name system : https://sixone.one/ -611.to - -// A2 Hosting -// Submitted by Tyler Hall -a2hosted.com -cpserver.com - -// Acorn Labs : https://acorn.io -// Submitted by Craig Jellick -*.on-acorn.io - -// ActiveTrail : https://www.activetrail.biz/ -// Submitted by Ofer Kalaora -activetrail.biz - -// Adaptable.io : https://adaptable.io -// Submitted by Mark Terrel -adaptable.app - -// addr.tools : https://addr.tools/ -// Submitted by Brian Shea -myaddr.dev -myaddr.io -dyn.addr.tools -myaddr.tools - -// Adobe : https://www.adobe.com/ -// Submitted by Ian Boston and Lars Trieloff -adobeaemcloud.com -*.dev.adobeaemcloud.com -aem.live -hlx.live -adobeaemcloud.net -aem.network -aem.page -hlx.page -aem.reviews - -// Adobe Developer Platform : https://developer.adobe.com -// Submitted by Jesse MacFadyen -adobeio-static.net -adobeioruntime.net - -// Africa.com Web Solutions Ltd : https://registry.africa.com -// Submitted by Gavin Brown -africa.com - -// Agnat sp. z o.o. : https://domena.pl -// Submitted by Przemyslaw Plewa -beep.pl - -// Aiven : https://aiven.io/ -// Submitted by Aiven Security Team -aiven.app -aivencloud.com - -// Akamai : https://www.akamai.com/ -// Submitted by Akamai Team -akadns.net -akamai.net -akamai-staging.net -akamaiedge.net -akamaiedge-staging.net -akamaihd.net -akamaihd-staging.net -akamaiorigin.net -akamaiorigin-staging.net -akamaized.net -akamaized-staging.net -edgekey.net -edgekey-staging.net -edgesuite.net -edgesuite-staging.net - -// alboto.ca : http://alboto.ca -// Submitted by Anton Avramov -barsy.ca - -// Alces Software Ltd : http://alces-software.com -// Submitted by Mark J. Titorenko -*.compute.estate -*.alces.network - -// Alibaba Cloud API Gateway -// Submitted by Alibaba Cloud Security -alibabacloudcs.com - -// all-inkl.com : https://all-inkl.com -// Submitted by Werner Kaltofen -kasserver.com - -// Altervista : https://www.altervista.org -// Submitted by Carlo Cannas -altervista.org - -// alwaysdata : https://www.alwaysdata.com -// Submitted by Cyril -alwaysdata.net - -// Amaze Software : https://amaze.co -// Submitted by Domain Admin -myamaze.net - -// Amazon : https://www.amazon.com/ -// Submitted by AWS Security -// Subsections of Amazon/subsidiaries will appear until "concludes" tag - -// Amazon API Gateway -// Submitted by AWS Security -// Reference: 6a4f5a95-8c7d-4077-a7af-9cf1abec0a53 -execute-api.cn-north-1.amazonaws.com.cn -execute-api.cn-northwest-1.amazonaws.com.cn -execute-api.af-south-1.amazonaws.com -execute-api.ap-east-1.amazonaws.com -execute-api.ap-northeast-1.amazonaws.com -execute-api.ap-northeast-2.amazonaws.com -execute-api.ap-northeast-3.amazonaws.com -execute-api.ap-south-1.amazonaws.com -execute-api.ap-south-2.amazonaws.com -execute-api.ap-southeast-1.amazonaws.com -execute-api.ap-southeast-2.amazonaws.com -execute-api.ap-southeast-3.amazonaws.com -execute-api.ap-southeast-4.amazonaws.com -execute-api.ap-southeast-5.amazonaws.com -execute-api.ca-central-1.amazonaws.com -execute-api.ca-west-1.amazonaws.com -execute-api.eu-central-1.amazonaws.com -execute-api.eu-central-2.amazonaws.com -execute-api.eu-north-1.amazonaws.com -execute-api.eu-south-1.amazonaws.com -execute-api.eu-south-2.amazonaws.com -execute-api.eu-west-1.amazonaws.com -execute-api.eu-west-2.amazonaws.com -execute-api.eu-west-3.amazonaws.com -execute-api.il-central-1.amazonaws.com -execute-api.me-central-1.amazonaws.com -execute-api.me-south-1.amazonaws.com -execute-api.sa-east-1.amazonaws.com -execute-api.us-east-1.amazonaws.com -execute-api.us-east-2.amazonaws.com -execute-api.us-gov-east-1.amazonaws.com -execute-api.us-gov-west-1.amazonaws.com -execute-api.us-west-1.amazonaws.com -execute-api.us-west-2.amazonaws.com - -// Amazon CloudFront -// Submitted by Donavan Miller -// Reference: 54144616-fd49-4435-8535-19c6a601bdb3 -cloudfront.net - -// Amazon Cognito -// Submitted by AWS Security -// Reference: e7c02dc1-02f4-4a23-bde3-a8527c830127 -auth.af-south-1.amazoncognito.com -auth.ap-east-1.amazoncognito.com -auth.ap-northeast-1.amazoncognito.com -auth.ap-northeast-2.amazoncognito.com -auth.ap-northeast-3.amazoncognito.com -auth.ap-south-1.amazoncognito.com -auth.ap-south-2.amazoncognito.com -auth.ap-southeast-1.amazoncognito.com -auth.ap-southeast-2.amazoncognito.com -auth.ap-southeast-3.amazoncognito.com -auth.ap-southeast-4.amazoncognito.com -auth.ap-southeast-5.amazoncognito.com -auth.ap-southeast-7.amazoncognito.com -auth.ca-central-1.amazoncognito.com -auth.ca-west-1.amazoncognito.com -auth.eu-central-1.amazoncognito.com -auth.eu-central-2.amazoncognito.com -auth.eu-north-1.amazoncognito.com -auth.eu-south-1.amazoncognito.com -auth.eu-south-2.amazoncognito.com -auth.eu-west-1.amazoncognito.com -auth.eu-west-2.amazoncognito.com -auth.eu-west-3.amazoncognito.com -auth.il-central-1.amazoncognito.com -auth.me-central-1.amazoncognito.com -auth.me-south-1.amazoncognito.com -auth.mx-central-1.amazoncognito.com -auth.sa-east-1.amazoncognito.com -auth.us-east-1.amazoncognito.com -auth-fips.us-east-1.amazoncognito.com -auth.us-east-2.amazoncognito.com -auth-fips.us-east-2.amazoncognito.com -auth-fips.us-gov-east-1.amazoncognito.com -auth-fips.us-gov-west-1.amazoncognito.com -auth.us-west-1.amazoncognito.com -auth-fips.us-west-1.amazoncognito.com -auth.us-west-2.amazoncognito.com -auth-fips.us-west-2.amazoncognito.com - -// Amazon EC2 -// Submitted by Luke Wells -// Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 -*.compute.amazonaws.com.cn -*.compute.amazonaws.com -*.compute-1.amazonaws.com -us-east-1.amazonaws.com - -// Amazon EMR -// Submitted by AWS Security -// Reference: 82f43f9f-bbb8-400e-8349-854f5a62f20d -emrappui-prod.cn-north-1.amazonaws.com.cn -emrnotebooks-prod.cn-north-1.amazonaws.com.cn -emrstudio-prod.cn-north-1.amazonaws.com.cn -emrappui-prod.cn-northwest-1.amazonaws.com.cn -emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn -emrstudio-prod.cn-northwest-1.amazonaws.com.cn -emrappui-prod.af-south-1.amazonaws.com -emrnotebooks-prod.af-south-1.amazonaws.com -emrstudio-prod.af-south-1.amazonaws.com -emrappui-prod.ap-east-1.amazonaws.com -emrnotebooks-prod.ap-east-1.amazonaws.com -emrstudio-prod.ap-east-1.amazonaws.com -emrappui-prod.ap-northeast-1.amazonaws.com -emrnotebooks-prod.ap-northeast-1.amazonaws.com -emrstudio-prod.ap-northeast-1.amazonaws.com -emrappui-prod.ap-northeast-2.amazonaws.com -emrnotebooks-prod.ap-northeast-2.amazonaws.com -emrstudio-prod.ap-northeast-2.amazonaws.com -emrappui-prod.ap-northeast-3.amazonaws.com -emrnotebooks-prod.ap-northeast-3.amazonaws.com -emrstudio-prod.ap-northeast-3.amazonaws.com -emrappui-prod.ap-south-1.amazonaws.com -emrnotebooks-prod.ap-south-1.amazonaws.com -emrstudio-prod.ap-south-1.amazonaws.com -emrappui-prod.ap-south-2.amazonaws.com -emrnotebooks-prod.ap-south-2.amazonaws.com -emrstudio-prod.ap-south-2.amazonaws.com -emrappui-prod.ap-southeast-1.amazonaws.com -emrnotebooks-prod.ap-southeast-1.amazonaws.com -emrstudio-prod.ap-southeast-1.amazonaws.com -emrappui-prod.ap-southeast-2.amazonaws.com -emrnotebooks-prod.ap-southeast-2.amazonaws.com -emrstudio-prod.ap-southeast-2.amazonaws.com -emrappui-prod.ap-southeast-3.amazonaws.com -emrnotebooks-prod.ap-southeast-3.amazonaws.com -emrstudio-prod.ap-southeast-3.amazonaws.com -emrappui-prod.ap-southeast-4.amazonaws.com -emrnotebooks-prod.ap-southeast-4.amazonaws.com -emrstudio-prod.ap-southeast-4.amazonaws.com -emrappui-prod.ca-central-1.amazonaws.com -emrnotebooks-prod.ca-central-1.amazonaws.com -emrstudio-prod.ca-central-1.amazonaws.com -emrappui-prod.ca-west-1.amazonaws.com -emrnotebooks-prod.ca-west-1.amazonaws.com -emrstudio-prod.ca-west-1.amazonaws.com -emrappui-prod.eu-central-1.amazonaws.com -emrnotebooks-prod.eu-central-1.amazonaws.com -emrstudio-prod.eu-central-1.amazonaws.com -emrappui-prod.eu-central-2.amazonaws.com -emrnotebooks-prod.eu-central-2.amazonaws.com -emrstudio-prod.eu-central-2.amazonaws.com -emrappui-prod.eu-north-1.amazonaws.com -emrnotebooks-prod.eu-north-1.amazonaws.com -emrstudio-prod.eu-north-1.amazonaws.com -emrappui-prod.eu-south-1.amazonaws.com -emrnotebooks-prod.eu-south-1.amazonaws.com -emrstudio-prod.eu-south-1.amazonaws.com -emrappui-prod.eu-south-2.amazonaws.com -emrnotebooks-prod.eu-south-2.amazonaws.com -emrstudio-prod.eu-south-2.amazonaws.com -emrappui-prod.eu-west-1.amazonaws.com -emrnotebooks-prod.eu-west-1.amazonaws.com -emrstudio-prod.eu-west-1.amazonaws.com -emrappui-prod.eu-west-2.amazonaws.com -emrnotebooks-prod.eu-west-2.amazonaws.com -emrstudio-prod.eu-west-2.amazonaws.com -emrappui-prod.eu-west-3.amazonaws.com -emrnotebooks-prod.eu-west-3.amazonaws.com -emrstudio-prod.eu-west-3.amazonaws.com -emrappui-prod.il-central-1.amazonaws.com -emrnotebooks-prod.il-central-1.amazonaws.com -emrstudio-prod.il-central-1.amazonaws.com -emrappui-prod.me-central-1.amazonaws.com -emrnotebooks-prod.me-central-1.amazonaws.com -emrstudio-prod.me-central-1.amazonaws.com -emrappui-prod.me-south-1.amazonaws.com -emrnotebooks-prod.me-south-1.amazonaws.com -emrstudio-prod.me-south-1.amazonaws.com -emrappui-prod.sa-east-1.amazonaws.com -emrnotebooks-prod.sa-east-1.amazonaws.com -emrstudio-prod.sa-east-1.amazonaws.com -emrappui-prod.us-east-1.amazonaws.com -emrnotebooks-prod.us-east-1.amazonaws.com -emrstudio-prod.us-east-1.amazonaws.com -emrappui-prod.us-east-2.amazonaws.com -emrnotebooks-prod.us-east-2.amazonaws.com -emrstudio-prod.us-east-2.amazonaws.com -emrappui-prod.us-gov-east-1.amazonaws.com -emrnotebooks-prod.us-gov-east-1.amazonaws.com -emrstudio-prod.us-gov-east-1.amazonaws.com -emrappui-prod.us-gov-west-1.amazonaws.com -emrnotebooks-prod.us-gov-west-1.amazonaws.com -emrstudio-prod.us-gov-west-1.amazonaws.com -emrappui-prod.us-west-1.amazonaws.com -emrnotebooks-prod.us-west-1.amazonaws.com -emrstudio-prod.us-west-1.amazonaws.com -emrappui-prod.us-west-2.amazonaws.com -emrnotebooks-prod.us-west-2.amazonaws.com -emrstudio-prod.us-west-2.amazonaws.com - -// Amazon Managed Workflows for Apache Airflow -// Submitted by AWS Security -// Reference: bfd043cc-2816-451d-894e-612c6b61a438 -*.airflow.af-south-1.on.aws -*.airflow.ap-east-1.on.aws -*.airflow.ap-northeast-1.on.aws -*.airflow.ap-northeast-2.on.aws -*.airflow.ap-northeast-3.on.aws -*.airflow.ap-south-1.on.aws -*.airflow.ap-south-2.on.aws -*.airflow.ap-southeast-1.on.aws -*.airflow.ap-southeast-2.on.aws -*.airflow.ap-southeast-3.on.aws -*.airflow.ap-southeast-4.on.aws -*.airflow.ap-southeast-5.on.aws -*.airflow.ca-central-1.on.aws -*.airflow.ca-west-1.on.aws -*.airflow.eu-central-1.on.aws -*.airflow.eu-central-2.on.aws -*.airflow.eu-north-1.on.aws -*.airflow.eu-south-1.on.aws -*.airflow.eu-south-2.on.aws -*.airflow.eu-west-1.on.aws -*.airflow.eu-west-2.on.aws -*.airflow.eu-west-3.on.aws -*.airflow.il-central-1.on.aws -*.airflow.me-central-1.on.aws -*.airflow.me-south-1.on.aws -*.airflow.sa-east-1.on.aws -*.airflow.us-east-1.on.aws -*.airflow.us-east-2.on.aws -*.airflow.us-west-1.on.aws -*.airflow.us-west-2.on.aws -*.cn-north-1.airflow.amazonaws.com.cn -*.cn-northwest-1.airflow.amazonaws.com.cn -*.airflow.cn-north-1.on.amazonwebservices.com.cn -*.airflow.cn-northwest-1.on.amazonwebservices.com.cn -*.af-south-1.airflow.amazonaws.com -*.ap-east-1.airflow.amazonaws.com -*.ap-northeast-1.airflow.amazonaws.com -*.ap-northeast-2.airflow.amazonaws.com -*.ap-northeast-3.airflow.amazonaws.com -*.ap-south-1.airflow.amazonaws.com -*.ap-south-2.airflow.amazonaws.com -*.ap-southeast-1.airflow.amazonaws.com -*.ap-southeast-2.airflow.amazonaws.com -*.ap-southeast-3.airflow.amazonaws.com -*.ap-southeast-4.airflow.amazonaws.com -*.ap-southeast-5.airflow.amazonaws.com -*.ap-southeast-7.airflow.amazonaws.com -*.ca-central-1.airflow.amazonaws.com -*.ca-west-1.airflow.amazonaws.com -*.eu-central-1.airflow.amazonaws.com -*.eu-central-2.airflow.amazonaws.com -*.eu-north-1.airflow.amazonaws.com -*.eu-south-1.airflow.amazonaws.com -*.eu-south-2.airflow.amazonaws.com -*.eu-west-1.airflow.amazonaws.com -*.eu-west-2.airflow.amazonaws.com -*.eu-west-3.airflow.amazonaws.com -*.il-central-1.airflow.amazonaws.com -*.me-central-1.airflow.amazonaws.com -*.me-south-1.airflow.amazonaws.com -*.sa-east-1.airflow.amazonaws.com -*.us-east-1.airflow.amazonaws.com -*.us-east-2.airflow.amazonaws.com -*.us-west-1.airflow.amazonaws.com -*.us-west-2.airflow.amazonaws.com - -// Amazon Relational Database Service -// Submitted by: AWS Security -// Reference: 5aa87906-fd4f-4831-8727-4ffca6094159 -*.rds.cn-north-1.amazonaws.com.cn -*.rds.cn-northwest-1.amazonaws.com.cn -*.af-south-1.rds.amazonaws.com -*.ap-east-1.rds.amazonaws.com -*.ap-east-2.rds.amazonaws.com -*.ap-northeast-1.rds.amazonaws.com -*.ap-northeast-2.rds.amazonaws.com -*.ap-northeast-3.rds.amazonaws.com -*.ap-south-1.rds.amazonaws.com -*.ap-south-2.rds.amazonaws.com -*.ap-southeast-1.rds.amazonaws.com -*.ap-southeast-2.rds.amazonaws.com -*.ap-southeast-3.rds.amazonaws.com -*.ap-southeast-4.rds.amazonaws.com -*.ap-southeast-5.rds.amazonaws.com -*.ap-southeast-6.rds.amazonaws.com -*.ap-southeast-7.rds.amazonaws.com -*.ca-central-1.rds.amazonaws.com -*.ca-west-1.rds.amazonaws.com -*.eu-central-1.rds.amazonaws.com -*.eu-central-2.rds.amazonaws.com -*.eu-west-1.rds.amazonaws.com -*.eu-west-2.rds.amazonaws.com -*.eu-west-3.rds.amazonaws.com -*.il-central-1.rds.amazonaws.com -*.me-central-1.rds.amazonaws.com -*.me-south-1.rds.amazonaws.com -*.mx-central-1.rds.amazonaws.com -*.sa-east-1.rds.amazonaws.com -*.us-east-1.rds.amazonaws.com -*.us-east-2.rds.amazonaws.com -*.us-gov-east-1.rds.amazonaws.com -*.us-gov-west-1.rds.amazonaws.com -*.us-northeast-1.rds.amazonaws.com -*.us-west-1.rds.amazonaws.com -*.us-west-2.rds.amazonaws.com - -// Amazon S3 -// Submitted by AWS Security -// Reference: ada5c9df-55e1-4195-a1ce-732d6c81e357 -s3.dualstack.cn-north-1.amazonaws.com.cn -s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn -s3-website.dualstack.cn-north-1.amazonaws.com.cn -s3.cn-north-1.amazonaws.com.cn -s3-accesspoint.cn-north-1.amazonaws.com.cn -s3-deprecated.cn-north-1.amazonaws.com.cn -s3-object-lambda.cn-north-1.amazonaws.com.cn -s3-website.cn-north-1.amazonaws.com.cn -s3.dualstack.cn-northwest-1.amazonaws.com.cn -s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn -s3.cn-northwest-1.amazonaws.com.cn -s3-accesspoint.cn-northwest-1.amazonaws.com.cn -s3-object-lambda.cn-northwest-1.amazonaws.com.cn -s3-website.cn-northwest-1.amazonaws.com.cn -s3.dualstack.af-south-1.amazonaws.com -s3-accesspoint.dualstack.af-south-1.amazonaws.com -s3-website.dualstack.af-south-1.amazonaws.com -s3.af-south-1.amazonaws.com -s3-accesspoint.af-south-1.amazonaws.com -s3-object-lambda.af-south-1.amazonaws.com -s3-website.af-south-1.amazonaws.com -s3.dualstack.ap-east-1.amazonaws.com -s3-accesspoint.dualstack.ap-east-1.amazonaws.com -s3.ap-east-1.amazonaws.com -s3-accesspoint.ap-east-1.amazonaws.com -s3-object-lambda.ap-east-1.amazonaws.com -s3-website.ap-east-1.amazonaws.com -s3.dualstack.ap-northeast-1.amazonaws.com -s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com -s3-website.dualstack.ap-northeast-1.amazonaws.com -s3.ap-northeast-1.amazonaws.com -s3-accesspoint.ap-northeast-1.amazonaws.com -s3-object-lambda.ap-northeast-1.amazonaws.com -s3-website.ap-northeast-1.amazonaws.com -s3.dualstack.ap-northeast-2.amazonaws.com -s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com -s3-website.dualstack.ap-northeast-2.amazonaws.com -s3.ap-northeast-2.amazonaws.com -s3-accesspoint.ap-northeast-2.amazonaws.com -s3-object-lambda.ap-northeast-2.amazonaws.com -s3-website.ap-northeast-2.amazonaws.com -s3.dualstack.ap-northeast-3.amazonaws.com -s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com -s3-website.dualstack.ap-northeast-3.amazonaws.com -s3.ap-northeast-3.amazonaws.com -s3-accesspoint.ap-northeast-3.amazonaws.com -s3-object-lambda.ap-northeast-3.amazonaws.com -s3-website.ap-northeast-3.amazonaws.com -s3.dualstack.ap-south-1.amazonaws.com -s3-accesspoint.dualstack.ap-south-1.amazonaws.com -s3-website.dualstack.ap-south-1.amazonaws.com -s3.ap-south-1.amazonaws.com -s3-accesspoint.ap-south-1.amazonaws.com -s3-object-lambda.ap-south-1.amazonaws.com -s3-website.ap-south-1.amazonaws.com -s3.dualstack.ap-south-2.amazonaws.com -s3-accesspoint.dualstack.ap-south-2.amazonaws.com -s3-website.dualstack.ap-south-2.amazonaws.com -s3.ap-south-2.amazonaws.com -s3-accesspoint.ap-south-2.amazonaws.com -s3-object-lambda.ap-south-2.amazonaws.com -s3-website.ap-south-2.amazonaws.com -s3.dualstack.ap-southeast-1.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com -s3-website.dualstack.ap-southeast-1.amazonaws.com -s3.ap-southeast-1.amazonaws.com -s3-accesspoint.ap-southeast-1.amazonaws.com -s3-object-lambda.ap-southeast-1.amazonaws.com -s3-website.ap-southeast-1.amazonaws.com -s3.dualstack.ap-southeast-2.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com -s3-website.dualstack.ap-southeast-2.amazonaws.com -s3.ap-southeast-2.amazonaws.com -s3-accesspoint.ap-southeast-2.amazonaws.com -s3-object-lambda.ap-southeast-2.amazonaws.com -s3-website.ap-southeast-2.amazonaws.com -s3.dualstack.ap-southeast-3.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com -s3-website.dualstack.ap-southeast-3.amazonaws.com -s3.ap-southeast-3.amazonaws.com -s3-accesspoint.ap-southeast-3.amazonaws.com -s3-object-lambda.ap-southeast-3.amazonaws.com -s3-website.ap-southeast-3.amazonaws.com -s3.dualstack.ap-southeast-4.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com -s3-website.dualstack.ap-southeast-4.amazonaws.com -s3.ap-southeast-4.amazonaws.com -s3-accesspoint.ap-southeast-4.amazonaws.com -s3-object-lambda.ap-southeast-4.amazonaws.com -s3-website.ap-southeast-4.amazonaws.com -s3.dualstack.ap-southeast-5.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-5.amazonaws.com -s3-website.dualstack.ap-southeast-5.amazonaws.com -s3.ap-southeast-5.amazonaws.com -s3-accesspoint.ap-southeast-5.amazonaws.com -s3-deprecated.ap-southeast-5.amazonaws.com -s3-object-lambda.ap-southeast-5.amazonaws.com -s3-website.ap-southeast-5.amazonaws.com -s3.dualstack.ca-central-1.amazonaws.com -s3-accesspoint.dualstack.ca-central-1.amazonaws.com -s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com -s3-fips.dualstack.ca-central-1.amazonaws.com -s3-website.dualstack.ca-central-1.amazonaws.com -s3.ca-central-1.amazonaws.com -s3-accesspoint.ca-central-1.amazonaws.com -s3-accesspoint-fips.ca-central-1.amazonaws.com -s3-fips.ca-central-1.amazonaws.com -s3-object-lambda.ca-central-1.amazonaws.com -s3-website.ca-central-1.amazonaws.com -s3.dualstack.ca-west-1.amazonaws.com -s3-accesspoint.dualstack.ca-west-1.amazonaws.com -s3-accesspoint-fips.dualstack.ca-west-1.amazonaws.com -s3-fips.dualstack.ca-west-1.amazonaws.com -s3-website.dualstack.ca-west-1.amazonaws.com -s3.ca-west-1.amazonaws.com -s3-accesspoint.ca-west-1.amazonaws.com -s3-accesspoint-fips.ca-west-1.amazonaws.com -s3-fips.ca-west-1.amazonaws.com -s3-object-lambda.ca-west-1.amazonaws.com -s3-website.ca-west-1.amazonaws.com -s3.dualstack.eu-central-1.amazonaws.com -s3-accesspoint.dualstack.eu-central-1.amazonaws.com -s3-website.dualstack.eu-central-1.amazonaws.com -s3.eu-central-1.amazonaws.com -s3-accesspoint.eu-central-1.amazonaws.com -s3-object-lambda.eu-central-1.amazonaws.com -s3-website.eu-central-1.amazonaws.com -s3.dualstack.eu-central-2.amazonaws.com -s3-accesspoint.dualstack.eu-central-2.amazonaws.com -s3-website.dualstack.eu-central-2.amazonaws.com -s3.eu-central-2.amazonaws.com -s3-accesspoint.eu-central-2.amazonaws.com -s3-object-lambda.eu-central-2.amazonaws.com -s3-website.eu-central-2.amazonaws.com -s3.dualstack.eu-north-1.amazonaws.com -s3-accesspoint.dualstack.eu-north-1.amazonaws.com -s3.eu-north-1.amazonaws.com -s3-accesspoint.eu-north-1.amazonaws.com -s3-object-lambda.eu-north-1.amazonaws.com -s3-website.eu-north-1.amazonaws.com -s3.dualstack.eu-south-1.amazonaws.com -s3-accesspoint.dualstack.eu-south-1.amazonaws.com -s3-website.dualstack.eu-south-1.amazonaws.com -s3.eu-south-1.amazonaws.com -s3-accesspoint.eu-south-1.amazonaws.com -s3-object-lambda.eu-south-1.amazonaws.com -s3-website.eu-south-1.amazonaws.com -s3.dualstack.eu-south-2.amazonaws.com -s3-accesspoint.dualstack.eu-south-2.amazonaws.com -s3-website.dualstack.eu-south-2.amazonaws.com -s3.eu-south-2.amazonaws.com -s3-accesspoint.eu-south-2.amazonaws.com -s3-object-lambda.eu-south-2.amazonaws.com -s3-website.eu-south-2.amazonaws.com -s3.dualstack.eu-west-1.amazonaws.com -s3-accesspoint.dualstack.eu-west-1.amazonaws.com -s3-website.dualstack.eu-west-1.amazonaws.com -s3.eu-west-1.amazonaws.com -s3-accesspoint.eu-west-1.amazonaws.com -s3-deprecated.eu-west-1.amazonaws.com -s3-object-lambda.eu-west-1.amazonaws.com -s3-website.eu-west-1.amazonaws.com -s3.dualstack.eu-west-2.amazonaws.com -s3-accesspoint.dualstack.eu-west-2.amazonaws.com -s3.eu-west-2.amazonaws.com -s3-accesspoint.eu-west-2.amazonaws.com -s3-object-lambda.eu-west-2.amazonaws.com -s3-website.eu-west-2.amazonaws.com -s3.dualstack.eu-west-3.amazonaws.com -s3-accesspoint.dualstack.eu-west-3.amazonaws.com -s3-website.dualstack.eu-west-3.amazonaws.com -s3.eu-west-3.amazonaws.com -s3-accesspoint.eu-west-3.amazonaws.com -s3-object-lambda.eu-west-3.amazonaws.com -s3-website.eu-west-3.amazonaws.com -s3.dualstack.il-central-1.amazonaws.com -s3-accesspoint.dualstack.il-central-1.amazonaws.com -s3-website.dualstack.il-central-1.amazonaws.com -s3.il-central-1.amazonaws.com -s3-accesspoint.il-central-1.amazonaws.com -s3-object-lambda.il-central-1.amazonaws.com -s3-website.il-central-1.amazonaws.com -s3.dualstack.me-central-1.amazonaws.com -s3-accesspoint.dualstack.me-central-1.amazonaws.com -s3-website.dualstack.me-central-1.amazonaws.com -s3.me-central-1.amazonaws.com -s3-accesspoint.me-central-1.amazonaws.com -s3-object-lambda.me-central-1.amazonaws.com -s3-website.me-central-1.amazonaws.com -s3.dualstack.me-south-1.amazonaws.com -s3-accesspoint.dualstack.me-south-1.amazonaws.com -s3.me-south-1.amazonaws.com -s3-accesspoint.me-south-1.amazonaws.com -s3-object-lambda.me-south-1.amazonaws.com -s3-website.me-south-1.amazonaws.com -s3.amazonaws.com -s3-1.amazonaws.com -s3-ap-east-1.amazonaws.com -s3-ap-northeast-1.amazonaws.com -s3-ap-northeast-2.amazonaws.com -s3-ap-northeast-3.amazonaws.com -s3-ap-south-1.amazonaws.com -s3-ap-southeast-1.amazonaws.com -s3-ap-southeast-2.amazonaws.com -s3-ca-central-1.amazonaws.com -s3-eu-central-1.amazonaws.com -s3-eu-north-1.amazonaws.com -s3-eu-west-1.amazonaws.com -s3-eu-west-2.amazonaws.com -s3-eu-west-3.amazonaws.com -s3-external-1.amazonaws.com -s3-fips-us-gov-east-1.amazonaws.com -s3-fips-us-gov-west-1.amazonaws.com -mrap.accesspoint.s3-global.amazonaws.com -s3-me-south-1.amazonaws.com -s3-sa-east-1.amazonaws.com -s3-us-east-2.amazonaws.com -s3-us-gov-east-1.amazonaws.com -s3-us-gov-west-1.amazonaws.com -s3-us-west-1.amazonaws.com -s3-us-west-2.amazonaws.com -s3-website-ap-northeast-1.amazonaws.com -s3-website-ap-southeast-1.amazonaws.com -s3-website-ap-southeast-2.amazonaws.com -s3-website-eu-west-1.amazonaws.com -s3-website-sa-east-1.amazonaws.com -s3-website-us-east-1.amazonaws.com -s3-website-us-gov-west-1.amazonaws.com -s3-website-us-west-1.amazonaws.com -s3-website-us-west-2.amazonaws.com -s3.dualstack.sa-east-1.amazonaws.com -s3-accesspoint.dualstack.sa-east-1.amazonaws.com -s3-website.dualstack.sa-east-1.amazonaws.com -s3.sa-east-1.amazonaws.com -s3-accesspoint.sa-east-1.amazonaws.com -s3-object-lambda.sa-east-1.amazonaws.com -s3-website.sa-east-1.amazonaws.com -s3.dualstack.us-east-1.amazonaws.com -s3-accesspoint.dualstack.us-east-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com -s3-fips.dualstack.us-east-1.amazonaws.com -s3-website.dualstack.us-east-1.amazonaws.com -s3.us-east-1.amazonaws.com -s3-accesspoint.us-east-1.amazonaws.com -s3-accesspoint-fips.us-east-1.amazonaws.com -s3-deprecated.us-east-1.amazonaws.com -s3-fips.us-east-1.amazonaws.com -s3-object-lambda.us-east-1.amazonaws.com -s3-website.us-east-1.amazonaws.com -s3.dualstack.us-east-2.amazonaws.com -s3-accesspoint.dualstack.us-east-2.amazonaws.com -s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com -s3-fips.dualstack.us-east-2.amazonaws.com -s3-website.dualstack.us-east-2.amazonaws.com -s3.us-east-2.amazonaws.com -s3-accesspoint.us-east-2.amazonaws.com -s3-accesspoint-fips.us-east-2.amazonaws.com -s3-deprecated.us-east-2.amazonaws.com -s3-fips.us-east-2.amazonaws.com -s3-object-lambda.us-east-2.amazonaws.com -s3-website.us-east-2.amazonaws.com -s3.dualstack.us-gov-east-1.amazonaws.com -s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com -s3-fips.dualstack.us-gov-east-1.amazonaws.com -s3.us-gov-east-1.amazonaws.com -s3-accesspoint.us-gov-east-1.amazonaws.com -s3-accesspoint-fips.us-gov-east-1.amazonaws.com -s3-fips.us-gov-east-1.amazonaws.com -s3-object-lambda.us-gov-east-1.amazonaws.com -s3-website.us-gov-east-1.amazonaws.com -s3.dualstack.us-gov-west-1.amazonaws.com -s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com -s3-fips.dualstack.us-gov-west-1.amazonaws.com -s3.us-gov-west-1.amazonaws.com -s3-accesspoint.us-gov-west-1.amazonaws.com -s3-accesspoint-fips.us-gov-west-1.amazonaws.com -s3-fips.us-gov-west-1.amazonaws.com -s3-object-lambda.us-gov-west-1.amazonaws.com -s3-website.us-gov-west-1.amazonaws.com -s3.dualstack.us-west-1.amazonaws.com -s3-accesspoint.dualstack.us-west-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com -s3-fips.dualstack.us-west-1.amazonaws.com -s3-website.dualstack.us-west-1.amazonaws.com -s3.us-west-1.amazonaws.com -s3-accesspoint.us-west-1.amazonaws.com -s3-accesspoint-fips.us-west-1.amazonaws.com -s3-fips.us-west-1.amazonaws.com -s3-object-lambda.us-west-1.amazonaws.com -s3-website.us-west-1.amazonaws.com -s3.dualstack.us-west-2.amazonaws.com -s3-accesspoint.dualstack.us-west-2.amazonaws.com -s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com -s3-fips.dualstack.us-west-2.amazonaws.com -s3-website.dualstack.us-west-2.amazonaws.com -s3.us-west-2.amazonaws.com -s3-accesspoint.us-west-2.amazonaws.com -s3-accesspoint-fips.us-west-2.amazonaws.com -s3-deprecated.us-west-2.amazonaws.com -s3-fips.us-west-2.amazonaws.com -s3-object-lambda.us-west-2.amazonaws.com -s3-website.us-west-2.amazonaws.com - -// Amazon SageMaker Ground Truth -// Submitted by AWS Security -// Reference: 98dbfde4-7802-48c3-8751-b60f204e0d9c -labeling.ap-northeast-1.sagemaker.aws -labeling.ap-northeast-2.sagemaker.aws -labeling.ap-south-1.sagemaker.aws -labeling.ap-southeast-1.sagemaker.aws -labeling.ap-southeast-2.sagemaker.aws -labeling.ca-central-1.sagemaker.aws -labeling.eu-central-1.sagemaker.aws -labeling.eu-west-1.sagemaker.aws -labeling.eu-west-2.sagemaker.aws -labeling.us-east-1.sagemaker.aws -labeling.us-east-2.sagemaker.aws -labeling.us-west-2.sagemaker.aws - -// Amazon SageMaker Notebook Instances -// Submitted by AWS Security -// Reference: b5ea56df-669e-43cc-9537-14aa172f5dfc -notebook.af-south-1.sagemaker.aws -notebook.ap-east-1.sagemaker.aws -notebook.ap-northeast-1.sagemaker.aws -notebook.ap-northeast-2.sagemaker.aws -notebook.ap-northeast-3.sagemaker.aws -notebook.ap-south-1.sagemaker.aws -notebook.ap-south-2.sagemaker.aws -notebook.ap-southeast-1.sagemaker.aws -notebook.ap-southeast-2.sagemaker.aws -notebook.ap-southeast-3.sagemaker.aws -notebook.ap-southeast-4.sagemaker.aws -notebook.ca-central-1.sagemaker.aws -notebook-fips.ca-central-1.sagemaker.aws -notebook.ca-west-1.sagemaker.aws -notebook-fips.ca-west-1.sagemaker.aws -notebook.eu-central-1.sagemaker.aws -notebook.eu-central-2.sagemaker.aws -notebook.eu-north-1.sagemaker.aws -notebook.eu-south-1.sagemaker.aws -notebook.eu-south-2.sagemaker.aws -notebook.eu-west-1.sagemaker.aws -notebook.eu-west-2.sagemaker.aws -notebook.eu-west-3.sagemaker.aws -notebook.il-central-1.sagemaker.aws -notebook.me-central-1.sagemaker.aws -notebook.me-south-1.sagemaker.aws -notebook.sa-east-1.sagemaker.aws -notebook.us-east-1.sagemaker.aws -notebook-fips.us-east-1.sagemaker.aws -notebook.us-east-2.sagemaker.aws -notebook-fips.us-east-2.sagemaker.aws -notebook.us-gov-east-1.sagemaker.aws -notebook-fips.us-gov-east-1.sagemaker.aws -notebook.us-gov-west-1.sagemaker.aws -notebook-fips.us-gov-west-1.sagemaker.aws -notebook.us-west-1.sagemaker.aws -notebook-fips.us-west-1.sagemaker.aws -notebook.us-west-2.sagemaker.aws -notebook-fips.us-west-2.sagemaker.aws -notebook.cn-north-1.sagemaker.com.cn -notebook.cn-northwest-1.sagemaker.com.cn - -// Amazon SageMaker Studio -// Submitted by AWS Security -// Reference: 475f237e-ab88-4041-9f41-7cfccdf66aeb -studio.af-south-1.sagemaker.aws -studio.ap-east-1.sagemaker.aws -studio.ap-northeast-1.sagemaker.aws -studio.ap-northeast-2.sagemaker.aws -studio.ap-northeast-3.sagemaker.aws -studio.ap-south-1.sagemaker.aws -studio.ap-southeast-1.sagemaker.aws -studio.ap-southeast-2.sagemaker.aws -studio.ap-southeast-3.sagemaker.aws -studio.ca-central-1.sagemaker.aws -studio.eu-central-1.sagemaker.aws -studio.eu-central-2.sagemaker.aws -studio.eu-north-1.sagemaker.aws -studio.eu-south-1.sagemaker.aws -studio.eu-south-2.sagemaker.aws -studio.eu-west-1.sagemaker.aws -studio.eu-west-2.sagemaker.aws -studio.eu-west-3.sagemaker.aws -studio.il-central-1.sagemaker.aws -studio.me-central-1.sagemaker.aws -studio.me-south-1.sagemaker.aws -studio.sa-east-1.sagemaker.aws -studio.us-east-1.sagemaker.aws -studio.us-east-2.sagemaker.aws -studio.us-gov-east-1.sagemaker.aws -studio-fips.us-gov-east-1.sagemaker.aws -studio.us-gov-west-1.sagemaker.aws -studio-fips.us-gov-west-1.sagemaker.aws -studio.us-west-1.sagemaker.aws -studio.us-west-2.sagemaker.aws -studio.cn-north-1.sagemaker.com.cn -studio.cn-northwest-1.sagemaker.com.cn - -// Amazon SageMaker with MLflow -// Submited by: AWS Security -// Reference: c19f92b3-a82a-452d-8189-831b572eea7e -*.experiments.sagemaker.aws - -// Analytics on AWS -// Submitted by AWS Security -// Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd -analytics-gateway.ap-northeast-1.amazonaws.com -analytics-gateway.ap-northeast-2.amazonaws.com -analytics-gateway.ap-south-1.amazonaws.com -analytics-gateway.ap-southeast-1.amazonaws.com -analytics-gateway.ap-southeast-2.amazonaws.com -analytics-gateway.eu-central-1.amazonaws.com -analytics-gateway.eu-west-1.amazonaws.com -analytics-gateway.us-east-1.amazonaws.com -analytics-gateway.us-east-2.amazonaws.com -analytics-gateway.us-west-2.amazonaws.com - -// AWS Amplify -// Submitted by AWS Security -// Reference: c35bed18-6f4f-424f-9298-5756f2f7d72b -amplifyapp.com - -// AWS App Runner -// Submitted by AWS Security -// Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316 -*.awsapprunner.com - -// AWS Cloud9 -// Submitted by: AWS Security -// Reference: 30717f72-4007-4f0f-8ed4-864c6f2efec9 -webview-assets.aws-cloud9.af-south-1.amazonaws.com -vfs.cloud9.af-south-1.amazonaws.com -webview-assets.cloud9.af-south-1.amazonaws.com -webview-assets.aws-cloud9.ap-east-1.amazonaws.com -vfs.cloud9.ap-east-1.amazonaws.com -webview-assets.cloud9.ap-east-1.amazonaws.com -webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com -vfs.cloud9.ap-northeast-1.amazonaws.com -webview-assets.cloud9.ap-northeast-1.amazonaws.com -webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com -vfs.cloud9.ap-northeast-2.amazonaws.com -webview-assets.cloud9.ap-northeast-2.amazonaws.com -webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com -vfs.cloud9.ap-northeast-3.amazonaws.com -webview-assets.cloud9.ap-northeast-3.amazonaws.com -webview-assets.aws-cloud9.ap-south-1.amazonaws.com -vfs.cloud9.ap-south-1.amazonaws.com -webview-assets.cloud9.ap-south-1.amazonaws.com -webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com -vfs.cloud9.ap-southeast-1.amazonaws.com -webview-assets.cloud9.ap-southeast-1.amazonaws.com -webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com -vfs.cloud9.ap-southeast-2.amazonaws.com -webview-assets.cloud9.ap-southeast-2.amazonaws.com -webview-assets.aws-cloud9.ca-central-1.amazonaws.com -vfs.cloud9.ca-central-1.amazonaws.com -webview-assets.cloud9.ca-central-1.amazonaws.com -webview-assets.aws-cloud9.eu-central-1.amazonaws.com -vfs.cloud9.eu-central-1.amazonaws.com -webview-assets.cloud9.eu-central-1.amazonaws.com -webview-assets.aws-cloud9.eu-north-1.amazonaws.com -vfs.cloud9.eu-north-1.amazonaws.com -webview-assets.cloud9.eu-north-1.amazonaws.com -webview-assets.aws-cloud9.eu-south-1.amazonaws.com -vfs.cloud9.eu-south-1.amazonaws.com -webview-assets.cloud9.eu-south-1.amazonaws.com -webview-assets.aws-cloud9.eu-west-1.amazonaws.com -vfs.cloud9.eu-west-1.amazonaws.com -webview-assets.cloud9.eu-west-1.amazonaws.com -webview-assets.aws-cloud9.eu-west-2.amazonaws.com -vfs.cloud9.eu-west-2.amazonaws.com -webview-assets.cloud9.eu-west-2.amazonaws.com -webview-assets.aws-cloud9.eu-west-3.amazonaws.com -vfs.cloud9.eu-west-3.amazonaws.com -webview-assets.cloud9.eu-west-3.amazonaws.com -webview-assets.aws-cloud9.il-central-1.amazonaws.com -vfs.cloud9.il-central-1.amazonaws.com -webview-assets.aws-cloud9.me-south-1.amazonaws.com -vfs.cloud9.me-south-1.amazonaws.com -webview-assets.cloud9.me-south-1.amazonaws.com -webview-assets.aws-cloud9.sa-east-1.amazonaws.com -vfs.cloud9.sa-east-1.amazonaws.com -webview-assets.cloud9.sa-east-1.amazonaws.com -webview-assets.aws-cloud9.us-east-1.amazonaws.com -vfs.cloud9.us-east-1.amazonaws.com -webview-assets.cloud9.us-east-1.amazonaws.com -webview-assets.aws-cloud9.us-east-2.amazonaws.com -vfs.cloud9.us-east-2.amazonaws.com -webview-assets.cloud9.us-east-2.amazonaws.com -webview-assets.aws-cloud9.us-west-1.amazonaws.com -vfs.cloud9.us-west-1.amazonaws.com -webview-assets.cloud9.us-west-1.amazonaws.com -webview-assets.aws-cloud9.us-west-2.amazonaws.com -vfs.cloud9.us-west-2.amazonaws.com -webview-assets.cloud9.us-west-2.amazonaws.com - -// AWS Directory Service -// Submitted by AWS Security -// Reference: a13203e8-42dc-4045-a0d2-2ee67bed1068 -awsapps.com - -// AWS Elastic Beanstalk -// Submitted by AWS Security -// Reference: e4e02a54-eaf9-4fe7-b662-39ccbc011a04 -cn-north-1.eb.amazonaws.com.cn -cn-northwest-1.eb.amazonaws.com.cn -elasticbeanstalk.com -af-south-1.elasticbeanstalk.com -ap-east-1.elasticbeanstalk.com -ap-northeast-1.elasticbeanstalk.com -ap-northeast-2.elasticbeanstalk.com -ap-northeast-3.elasticbeanstalk.com -ap-south-1.elasticbeanstalk.com -ap-southeast-1.elasticbeanstalk.com -ap-southeast-2.elasticbeanstalk.com -ap-southeast-3.elasticbeanstalk.com -ap-southeast-5.elasticbeanstalk.com -ap-southeast-7.elasticbeanstalk.com -ca-central-1.elasticbeanstalk.com -eu-central-1.elasticbeanstalk.com -eu-north-1.elasticbeanstalk.com -eu-south-1.elasticbeanstalk.com -eu-south-2.elasticbeanstalk.com -eu-west-1.elasticbeanstalk.com -eu-west-2.elasticbeanstalk.com -eu-west-3.elasticbeanstalk.com -il-central-1.elasticbeanstalk.com -me-central-1.elasticbeanstalk.com -me-south-1.elasticbeanstalk.com -sa-east-1.elasticbeanstalk.com -us-east-1.elasticbeanstalk.com -us-east-2.elasticbeanstalk.com -us-gov-east-1.elasticbeanstalk.com -us-gov-west-1.elasticbeanstalk.com -us-west-1.elasticbeanstalk.com -us-west-2.elasticbeanstalk.com - -// (AWS) Elastic Load Balancing -// Submitted by Luke Wells -// Reference: 12a3d528-1bac-4433-a359-a395867ffed2 -*.elb.amazonaws.com.cn -*.elb.amazonaws.com - -// AWS Global Accelerator -// Submitted by Daniel Massaguer -// Reference: d916759d-a08b-4241-b536-4db887383a6a -awsglobalaccelerator.com - -// AWS Lambda Function URLs -// Submitted by AWS Security -// Reference: 57df74ca-0820-46a5-89ea-0f0d0c4714b7 -lambda-url.af-south-1.on.aws -lambda-url.ap-east-1.on.aws -lambda-url.ap-northeast-1.on.aws -lambda-url.ap-northeast-2.on.aws -lambda-url.ap-northeast-3.on.aws -lambda-url.ap-south-1.on.aws -lambda-url.ap-southeast-1.on.aws -lambda-url.ap-southeast-2.on.aws -lambda-url.ap-southeast-3.on.aws -lambda-url.ca-central-1.on.aws -lambda-url.eu-central-1.on.aws -lambda-url.eu-north-1.on.aws -lambda-url.eu-south-1.on.aws -lambda-url.eu-west-1.on.aws -lambda-url.eu-west-2.on.aws -lambda-url.eu-west-3.on.aws -lambda-url.me-south-1.on.aws -lambda-url.sa-east-1.on.aws -lambda-url.us-east-1.on.aws -lambda-url.us-east-2.on.aws -lambda-url.us-west-1.on.aws -lambda-url.us-west-2.on.aws - -// AWS re:Post Private -// Submitted by AWS Security -// Reference: 83385945-225f-416e-9aa0-ad0632bfdcee -*.private.repost.aws - -// AWS Transfer Family web apps -// Submitted by AWS Security -// Reference: 57a658c4-8899-410c-aa24-5b01e4a178d2 -transfer-webapp.af-south-1.on.aws -transfer-webapp.ap-east-1.on.aws -transfer-webapp.ap-northeast-1.on.aws -transfer-webapp.ap-northeast-2.on.aws -transfer-webapp.ap-northeast-3.on.aws -transfer-webapp.ap-south-1.on.aws -transfer-webapp.ap-south-2.on.aws -transfer-webapp.ap-southeast-1.on.aws -transfer-webapp.ap-southeast-2.on.aws -transfer-webapp.ap-southeast-3.on.aws -transfer-webapp.ap-southeast-4.on.aws -transfer-webapp.ap-southeast-5.on.aws -transfer-webapp.ca-central-1.on.aws -transfer-webapp.ca-west-1.on.aws -transfer-webapp.eu-central-1.on.aws -transfer-webapp.eu-central-2.on.aws -transfer-webapp.eu-north-1.on.aws -transfer-webapp.eu-south-1.on.aws -transfer-webapp.eu-south-2.on.aws -transfer-webapp.eu-west-1.on.aws -transfer-webapp.eu-west-2.on.aws -transfer-webapp.eu-west-3.on.aws -transfer-webapp.il-central-1.on.aws -transfer-webapp.me-central-1.on.aws -transfer-webapp.me-south-1.on.aws -transfer-webapp.sa-east-1.on.aws -transfer-webapp.us-east-1.on.aws -transfer-webapp.us-east-2.on.aws -transfer-webapp.us-gov-east-1.on.aws -transfer-webapp-fips.us-gov-east-1.on.aws -transfer-webapp.us-gov-west-1.on.aws -transfer-webapp-fips.us-gov-west-1.on.aws -transfer-webapp.us-west-1.on.aws -transfer-webapp.us-west-2.on.aws -transfer-webapp.cn-north-1.on.amazonwebservices.com.cn -transfer-webapp.cn-northwest-1.on.amazonwebservices.com.cn - -// eero -// Submitted by Yue Kang -// Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 -eero.online -eero-stage.online - -// concludes Amazon - -// Apigee : https://apigee.com/ -// Submitted by Apigee Security Team -apigee.io - -// Apis Networks : https://apisnetworks.com -// Submitted by Matt Saladna -panel.dev - -// Apphud : https://apphud.com -// Submitted by Alexander Selivanov -siiites.com - -// Appspace : https://www.appspace.com -// Submitted by Appspace Security Team -appspacehosted.com -appspaceusercontent.com - -// Appudo UG (haftungsbeschränkt) : https://www.appudo.com -// Submitted by Alexander Hochbaum -appudo.net - -// Appwrite : https://appwrite.io -// Submitted by Steven Nguyen -appwrite.global -*.appwrite.run - -// Aptible : https://www.aptible.com/ -// Submitted by Thomas Orozco -on-aptible.com - -// Aquapal : https://aquapal.net/ -// Submitted by Aki Ueno -f5.si - -// ArvanCloud EdgeCompute -// Submitted by ArvanCloud CDN -arvanedge.ir - -// ASEINet : https://www.aseinet.com/ -// Submitted by Asei SEKIGUCHI -user.aseinet.ne.jp -gv.vc -d.gv.vc - -// Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/ -// Submitted by Hector Martin -user.party.eus - -// Association potager.org : https://potager.org/ -// Submitted by Lunar -pimienta.org -poivron.org -potager.org -sweetpepper.org - -// ASUSTOR Inc. : http://www.asustor.com -// Submitted by Vincent Tseng -myasustor.com - -// Atlassian : https://atlassian.com -// Submitted by Sam Smyth -cdn.prod.atlassian-dev.net - -// Authentick UG (haftungsbeschränkt) : https://authentick.net -// Submitted by Lukas Reschke -translated.page - -// AVM : https://avm.de -// Submitted by Andreas Weise -myfritz.link -myfritz.net - -// AVStack Pte. Ltd. : https://avstack.io -// Submitted by Jasper Hugo -onavstack.net - -// AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com -// Submitted by James Kennedy -*.awdev.ca -*.advisor.ws - -// AZ.pl sp. z.o.o : https://az.pl -// Submitted by Krzysztof Wolski -ecommerce-shop.pl - -// b-data GmbH : https://www.b-data.io -// Submitted by Olivier Benz -b-data.io - -// Balena : https://www.balena.io -// Submitted by Petros Angelatos -balena-devices.com - -// BASE, Inc. : https://binc.jp -// Submitted by Yuya NAGASAWA -base.ec -official.ec -buyshop.jp -fashionstore.jp -handcrafted.jp -kawaiishop.jp -supersale.jp -theshop.jp -shopselect.net -base.shop - -// BeagleBoard.org Foundation : https://beagleboard.org -// Submitted by Jason Kridner -beagleboard.io - -// Bear Blog : https://bearblog.dev -// Submitted by Herman Martinus -bearblog.dev - -// Beget Ltd -// Submitted by Lev Nekrasov -*.beget.app - -// Besties : https://besties.house -// Submitted by Hazel Cora -pages.gay - -// BinaryLane : http://www.binarylane.com -// Submitted by Nathan O'Sullivan -bnr.la - -// Bitbucket : http://bitbucket.org -// Submitted by Andy Ortlieb -bitbucket.io - -// Blackbaud, Inc. : https://www.blackbaud.com -// Submitted by Paul Crowder -blackbaudcdn.net - -// Blatech : http://www.blatech.net -// Submitted by Luke Bratch -of.je - -// Block, Inc. : https://block.xyz -// Submitted by Jonathan Boice -square.site - -// Blue Bite, LLC : https://bluebite.com -// Submitted by Joshua Weiss -bluebite.io - -// Boomla : https://boomla.com -// Submitted by Tibor Halter -boomla.net - -// Boutir : https://www.boutir.com -// Submitted by Eric Ng Ka Ka -boutir.com - -// Boxfuse : https://boxfuse.com -// Submitted by Axel Fontaine -boxfuse.io - -// bplaced : https://www.bplaced.net/ -// Submitted by Miroslav Bozic -square7.ch -bplaced.com -bplaced.de -square7.de -bplaced.net -square7.net - -// Brave : https://brave.com -// Submitted by Andrea Brancaleoni -brave.app -*.s.brave.app -brave.io -*.s.brave.io - -// Brendly : https://brendly.rs -// Submitted by Dusan Radovanovic -shop.brendly.ba -shop.brendly.hr -shop.brendly.rs - -// BrowserSafetyMark -// Submitted by Dave Tharp -browsersafetymark.io - -// BRS Media : https://brsmedia.com/ -// Submitted by Gavin Brown -radio.am -radio.fm - -// Bubble : https://bubble.io/ -// Submitted by Merlin Zhao -cdn.bubble.io -bubbleapps.io - -// Bytemark Hosting : https://www.bytemark.co.uk -// Submitted by Paul Cammish -uk0.bigv.io -dh.bytemark.co.uk -vm.bytemark.co.uk - -// Caf.js Labs LLC : https://www.cafjs.com -// Submitted by Antonio Lain -cafjs.com - -// Canva Pty Ltd : https://canva.com/ -// Submitted by Joel Aquilina -canva-apps.cn -my.canvasite.cn -canva-apps.com -canva-hosted-embed.com -canvacode.com -rice-labs.com -canva.run -my.canva.site - -// Carrd : https://carrd.co -// Submitted by AJ -drr.ac -uwu.ai -carrd.co -crd.co -ju.mp - -// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk -// Submitted by Jamie Tanna -api.gov.uk - -// CDN77.com : http://www.cdn77.com -// Submitted by Jan Krpes -cdn77-storage.com -rsc.contentproxy9.cz -r.cdn77.net -cdn77-ssl.net -c.cdn77.org -rsc.cdn77.org -ssl.origin.cdn77-secure.org - -// CentralNic : https://teaminternet.com/ -// Submitted by registry -za.bz -br.com -cn.com -de.com -eu.com -jpn.com -mex.com -ru.com -sa.com -uk.com -us.com -za.com -com.de -gb.net -hu.net -jp.net -se.net -uk.net -ae.org -com.se - -// Cityhost LLC : https://cityhost.ua -// Submitted by Maksym Rivtin -cx.ua - -// Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/ -// Submitted by Rishabh Nambiar & Michael Brown -discourse.group -discourse.team - -// Clerk : https://www.clerk.dev -// Submitted by Colin Sidoti -clerk.app -clerkstage.app -*.lcl.dev -*.lclstage.dev -*.stg.dev -*.stgstage.dev - -// Clever Cloud : https://www.clever-cloud.com/ -// Submitted by Quentin Adam -cleverapps.cc -*.services.clever-cloud.com -cleverapps.io -cleverapps.tech - -// ClickRising : https://clickrising.com/ -// Submitted by Umut Gumeli -clickrising.net - -// Cloud DNS Ltd : http://www.cloudns.net -// Submitted by Aleksander Hristov & Boyan Peychev -cloudns.asia -cloudns.be -cloud-ip.biz -cloudns.biz -cloud-ip.cc -cloudns.cc -cloudns.ch -cloudns.cl -cloudns.club -abrdns.com -dnsabr.com -ip-ddns.com -cloudns.cx -cloudns.eu -cloudns.in -cloudns.info -ddns-ip.net -dns-cloud.net -dns-dynamic.net -cloudns.nz -cloudns.org -ip-dynamic.org -cloudns.ph -cloudns.pro -cloudns.pw -cloudns.us - -// Cloud66 : https://www.cloud66.com/ -// Submitted by Khash Sajadi -c66.me -cloud66.ws - -// CloudAccess.net : https://www.cloudaccess.net/ -// Submitted by Pawel Panek -jdevcloud.com -wpdevcloud.com -cloudaccess.host -freesite.host -cloudaccess.net - -// Cloudbees, Inc. : https://www.cloudbees.com/ -// Submitted by Mohideen Shajith -cloudbeesusercontent.io - -// Cloudera, Inc. : https://www.cloudera.com/ -// Submitted by Kedarnath Waikar -*.cloudera.site - -// Cloudflare, Inc. : https://www.cloudflare.com/ -// Submitted by Cloudflare Team -cloudflare.app -cf-ipfs.com -cloudflare-ipfs.com -trycloudflare.com -pages.dev -r2.dev -workers.dev -cloudflare.net -cdn.cloudflare.net -cdn.cloudflareanycast.net -cdn.cloudflarecn.net -cdn.cloudflareglobal.net - -// cloudscale.ch AG : https://www.cloudscale.ch/ -// Submitted by Gaudenz Steinlin -cust.cloudscale.ch -objects.lpg.cloudscale.ch -objects.rma.cloudscale.ch -lpg.objectstorage.ch -rma.objectstorage.ch - -// Clovyr : https://clovyr.io -// Submitted by Patrick Nielsen -wnext.app - -// CNPY : https://cnpy.gdn -// Submitted by Angelo Gladding -cnpy.gdn - -// Co & Co : https://co-co.nl/ -// Submitted by Govert Versluis -*.otap.co - -// co.ca : http://registry.co.ca/ -co.ca - -// co.com Registry, LLC : https://registry.co.com -// Submitted by Gavin Brown -co.com - -// Codeberg e. V. : https://codeberg.org -// Submitted by Moritz Marquardt -codeberg.page - -// CodeSandbox B.V. : https://codesandbox.io -// Submitted by Ives van Hoorne -csb.app -preview.csb.app - -// CoDNS B.V. -co.nl -co.no - -// Cognition AI, Inc. : https://cognition.ai -// Submitted by Philip Papurt -*.devinapps.com - -// Combell.com : https://www.combell.com -// Submitted by Thomas Wouters -webhosting.be -hosting-cluster.nl - -// Contentful GmbH : https://www.contentful.com -// Submitted by Contentful Developer Experience Team -ctfcloud.net - -// Convex : https://convex.dev/ -// Submitted by James Cowling -convex.app -convex.cloud -convex.site - -// Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/ -// Submitted by George Georgievsky -ac.ru -edu.ru -gov.ru -int.ru -mil.ru - -// COSIMO GmbH : http://www.cosimo.de -// Submitted by Rene Marticke -dyn.cosidns.de -dnsupdater.de -dynamisches-dns.de -internet-dns.de -l-o-g-i-n.de -dynamic-dns.info -feste-ip.net -knx-server.net -static-access.net - -// Craft Docs Ltd : https://www.craft.do/ -// Submitted by Zsombor Fuszenecker -craft.me - -// Craynic, s.r.o. : http://www.craynic.com/ -// Submitted by Ales Krajnik -realm.cz - -// Crisp IM SAS : https://crisp.chat/ -// Submitted by Baptiste Jamin -on.crisp.email - -// Cryptonomic : https://cryptonomic.net/ -// Submitted by Andrew Cady -*.cryptonomic.net - -// cyber_Folks S.A. : https://cyberfolks.pl -// Submitted by Bartlomiej Kida -cfolks.pl - -// cyon GmbH : https://www.cyon.ch/ -// Submitted by Dominic Luechinger -cyon.link -cyon.site - -// Dansk.net : http://www.dansk.net/ -// Submitted by Anani Voule -biz.dk -co.dk -firm.dk -reg.dk -store.dk - -// dappnode.io : https://dappnode.io/ -// Submitted by Abel Boldu / DAppNode Team -dyndns.dappnode.io - -// Dark, Inc. : https://darklang.com -// Submitted by Paul Biggar -builtwithdark.com -darklang.io - -// DataDetect, LLC. : https://datadetect.com -// Submitted by Andrew Banchich -demo.datadetect.com -instance.datadetect.com - -// Datawire, Inc : https://www.datawire.io -// Submitted by Richard Li -edgestack.me - -// Datto, Inc. : https://www.datto.com/ -// Submitted by Philipp Heckel -dattolocal.com -dattorelay.com -dattoweb.com -mydatto.com -dattolocal.net -mydatto.net - -// ddnss.de : https://www.ddnss.de/ -// Submitted by Robert Niedziela -ddnss.de -dyn.ddnss.de -dyndns.ddnss.de -dyn-ip24.de -dyndns1.de -home-webserver.de -dyn.home-webserver.de -myhome-server.de -ddnss.org - -// Debian : https://www.debian.org/ -// Submitted by Peter Palfrader / Debian Sysadmin Team -debian.net - -// Definima : http://www.definima.com/ -// Submitted by Maxence Bitterli -definima.io -definima.net - -// Deno Land Inc : https://deno.com/ -// Submitted by Luca Casonato -deno.dev -deno-staging.dev -deno.net - -// deSEC : https://desec.io/ -// Submitted by Peter Thomassen -dedyn.io - -// Deta : https://www.deta.sh/ -// Submitted by Aavash Shrestha -deta.app -deta.dev - -// Developed Methods LLC : https://methods.dev -// Submitted by Patrick Lorio -*.at.ply.gg -d6.ply.gg -joinmc.link -playit.plus -*.at.playit.plus -with.playit.plus - -// Dfinity Foundation: https://dfinity.org/ -// Submitted by Dfinity Team -icp0.io -*.raw.icp0.io -icp1.io -*.raw.icp1.io -*.icp.net -caffeine.site -caffeine.xyz - -// dhosting.pl Sp. z o.o. : https://dhosting.pl/ -// Submitted by Michal Kokoszkiewicz -dfirma.pl -dkonto.pl -you2.pl - -// DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ -// Submitted by Braxton Huggins -ondigitalocean.app - -// DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ -// Submitted by Robin H. Johnson -*.digitaloceanspaces.com - -// DigitalPlat : https://www.digitalplat.org/ -// Submitted by Edward Hsing -qzz.io -us.kg -xx.kg -dpdns.org - -// Discord Inc : https://discord.com -// Submitted by Sahn Lam -discordsays.com -discordsez.com - -// DNS Africa Ltd : https://dns.business -// Submitted by Calvin Browne -jozi.biz - -// DNSHE : https://de5.net -// Submitted by DNSHE Team -de5.net - -// DNShome : https://www.dnshome.de/ -// Submitted by Norbert Auler -dnshome.de - -// DotArai : https://www.dotarai.com/ -// Submitted by Atsadawat Netcharadsang -online.th -shop.th - -// DrayTek Corp. : https://www.draytek.com/ -// Submitted by Paul Fang -drayddns.com - -// DreamCommerce : https://shoper.pl/ -// Submitted by Konrad Kotarba -shoparena.pl - -// DreamHost : http://www.dreamhost.com/ -// Submitted by Andrew Farmer -dreamhosters.com - -// Dreamyoungs, Inc. : https://durumis.com -// Submitted by Infra Team -durumis.com - -// DuckDNS : http://www.duckdns.org/ -// Submitted by Richard Harper -duckdns.org - -// dy.fi : http://dy.fi/ -// Submitted by Heikki Hannikainen -dy.fi -tunk.org - -// DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ -dyndns.biz -for-better.biz -for-more.biz -for-some.biz -for-the.biz -selfip.biz -webhop.biz -ftpaccess.cc -game-server.cc -myphotos.cc -scrapping.cc -blogdns.com -cechire.com -dnsalias.com -dnsdojo.com -doesntexist.com -dontexist.com -doomdns.com -dyn-o-saur.com -dynalias.com -dyndns-at-home.com -dyndns-at-work.com -dyndns-blog.com -dyndns-free.com -dyndns-home.com -dyndns-ip.com -dyndns-mail.com -dyndns-office.com -dyndns-pics.com -dyndns-remote.com -dyndns-server.com -dyndns-web.com -dyndns-wiki.com -dyndns-work.com -est-a-la-maison.com -est-a-la-masion.com -est-le-patron.com -est-mon-blogueur.com -from-ak.com -from-al.com -from-ar.com -from-ca.com -from-ct.com -from-dc.com -from-de.com -from-fl.com -from-ga.com -from-hi.com -from-ia.com -from-id.com -from-il.com -from-in.com -from-ks.com -from-ky.com -from-ma.com -from-md.com -from-mi.com -from-mn.com -from-mo.com -from-ms.com -from-mt.com -from-nc.com -from-nd.com -from-ne.com -from-nh.com -from-nj.com -from-nm.com -from-nv.com -from-oh.com -from-ok.com -from-or.com -from-pa.com -from-pr.com -from-ri.com -from-sc.com -from-sd.com -from-tn.com -from-tx.com -from-ut.com -from-va.com -from-vt.com -from-wa.com -from-wi.com -from-wv.com -from-wy.com -getmyip.com -gotdns.com -hobby-site.com -homelinux.com -homeunix.com -iamallama.com -is-a-anarchist.com -is-a-blogger.com -is-a-bookkeeper.com -is-a-bulls-fan.com -is-a-caterer.com -is-a-chef.com -is-a-conservative.com -is-a-cpa.com -is-a-cubicle-slave.com -is-a-democrat.com -is-a-designer.com -is-a-doctor.com -is-a-financialadvisor.com -is-a-geek.com -is-a-green.com -is-a-guru.com -is-a-hard-worker.com -is-a-hunter.com -is-a-landscaper.com -is-a-lawyer.com -is-a-liberal.com -is-a-libertarian.com -is-a-llama.com -is-a-musician.com -is-a-nascarfan.com -is-a-nurse.com -is-a-painter.com -is-a-personaltrainer.com -is-a-photographer.com -is-a-player.com -is-a-republican.com -is-a-rockstar.com -is-a-socialist.com -is-a-student.com -is-a-teacher.com -is-a-techie.com -is-a-therapist.com -is-an-accountant.com -is-an-actor.com -is-an-actress.com -is-an-anarchist.com -is-an-artist.com -is-an-engineer.com -is-an-entertainer.com -is-certified.com -is-gone.com -is-into-anime.com -is-into-cars.com -is-into-cartoons.com -is-into-games.com -is-leet.com -is-not-certified.com -is-slick.com -is-uberleet.com -is-with-theband.com -isa-geek.com -isa-hockeynut.com -issmarterthanyou.com -likes-pie.com -likescandy.com -neat-url.com -saves-the-whales.com -selfip.com -sells-for-less.com -sells-for-u.com -servebbs.com -simple-url.com -space-to-rent.com -teaches-yoga.com -writesthisblog.com -ath.cx -fuettertdasnetz.de -isteingeek.de -istmein.de -lebtimnetz.de -leitungsen.de -traeumtgerade.de -barrel-of-knowledge.info -barrell-of-knowledge.info -dyndns.info -for-our.info -groks-the.info -groks-this.info -here-for-more.info -knowsitall.info -selfip.info -webhop.info -forgot.her.name -forgot.his.name -at-band-camp.net -blogdns.net -broke-it.net -buyshouses.net -dnsalias.net -dnsdojo.net -does-it.net -dontexist.net -dynalias.net -dynathome.net -endofinternet.net -from-az.net -from-co.net -from-la.net -from-ny.net -gets-it.net -ham-radio-op.net -homeftp.net -homeip.net -homelinux.net -homeunix.net -in-the-band.net -is-a-chef.net -is-a-geek.net -isa-geek.net -kicks-ass.net -office-on-the.net -podzone.net -scrapper-site.net -selfip.net -sells-it.net -servebbs.net -serveftp.net -thruhere.net -webhop.net -merseine.nu -mine.nu -shacknet.nu -blogdns.org -blogsite.org -boldlygoingnowhere.org -dnsalias.org -dnsdojo.org -doesntexist.org -dontexist.org -doomdns.org -dvrdns.org -dynalias.org -dyndns.org -go.dyndns.org -home.dyndns.org -endofinternet.org -endoftheinternet.org -from-me.org -game-host.org -gotdns.org -hobby-site.org -homedns.org -homeftp.org -homelinux.org -homeunix.org -is-a-bruinsfan.org -is-a-candidate.org -is-a-celticsfan.org -is-a-chef.org -is-a-geek.org -is-a-knight.org -is-a-linux-user.org -is-a-patsfan.org -is-a-soxfan.org -is-found.org -is-lost.org -is-saved.org -is-very-bad.org -is-very-evil.org -is-very-good.org -is-very-nice.org -is-very-sweet.org -isa-geek.org -kicks-ass.org -misconfused.org -podzone.org -readmyblog.org -selfip.org -sellsyourhome.org -servebbs.org -serveftp.org -servegame.org -stuff-4-sale.org -webhop.org -better-than.tv -dyndns.tv -on-the-web.tv -worse-than.tv -is-by.us -land-4-sale.us -stuff-4-sale.us -dyndns.ws -mypets.ws - -// Dynu.com : https://www.dynu.com/ -// Submitted by Sue Ye -ddnsfree.com -ddnsgeek.com -giize.com -gleeze.com -kozow.com -loseyourip.com -ooguy.com -theworkpc.com -casacam.net -dynu.net -accesscam.org -camdvr.org -freeddns.org -mywire.org -webredirect.org -myddns.rocks - -// dynv6 : https://dynv6.com -// Submitted by Dominik Menke -dynv6.net - -// E4YOU spol. s.r.o. : https://e4you.cz/ -// Submitted by Vladimir Dudr -e4.cz - -// Easypanel : https://easypanel.io -// Submitted by Andrei Canta -easypanel.app -easypanel.host - -// EasyWP : https://www.easywp.com -// Submitted by -*.ewp.live - -// eDirect Corp. : https://hosting.url.com.tw/ -// Submitted by C.S. chang -twmail.cc -twmail.net -twmail.org -mymailer.com.tw -url.tw - -// Electromagnetic Field : https://www.emfcamp.org -// Submitted by -at.emf.camp - -// Elefunc, Inc. : https://elefunc.com -// Submitted by Cetin Sert -rt.ht - -// Elementor : Elementor Ltd. -// Submitted by Anton Barkan -elementor.cloud -elementor.cool - -// Emergent : https://emergent.sh -// Submitted by Emergent Security Team -emergent.cloud -emergent.host - -// En root‽ : https://en-root.org -// Submitted by Emmanuel Raviart -en-root.fr - -// Enalean SAS : https://www.enalean.com -// Submitted by Enalean Security Team -mytuleap.com -tuleap-partners.com - -// Encoretivity AB : https://encore.cloud -// Submitted by André Eriksson -encr.app -frontend.encr.app -encoreapi.com -lp.dev -api.lp.dev -objects.lp.dev - -// encoway GmbH : https://www.encoway.de -// Submitted by Marcel Daus -eu.encoway.cloud - -// EU.org : https://eu.org/ -// Submitted by Pierre Beyssac -eu.org -al.eu.org -asso.eu.org -at.eu.org -au.eu.org -be.eu.org -bg.eu.org -ca.eu.org -cd.eu.org -ch.eu.org -cn.eu.org -cy.eu.org -cz.eu.org -de.eu.org -dk.eu.org -edu.eu.org -ee.eu.org -es.eu.org -fi.eu.org -fr.eu.org -gr.eu.org -hr.eu.org -hu.eu.org -ie.eu.org -il.eu.org -in.eu.org -int.eu.org -is.eu.org -it.eu.org -jp.eu.org -kr.eu.org -lt.eu.org -lu.eu.org -lv.eu.org -me.eu.org -mk.eu.org -mt.eu.org -my.eu.org -net.eu.org -ng.eu.org -nl.eu.org -no.eu.org -nz.eu.org -pl.eu.org -pt.eu.org -ro.eu.org -ru.eu.org -se.eu.org -si.eu.org -sk.eu.org -tr.eu.org -uk.eu.org -us.eu.org - -// Eurobyte : https://eurobyte.ru -// Submitted by Evgeniy Subbotin -eurodir.ru - -// Evennode : http://www.evennode.com/ -// Submitted by Michal Kralik -eu-1.evennode.com -eu-2.evennode.com -eu-3.evennode.com -eu-4.evennode.com -us-1.evennode.com -us-2.evennode.com -us-3.evennode.com -us-4.evennode.com - -// Evervault : https://evervault.com -// Submitted by Hannah Neary -relay.evervault.app -relay.evervault.dev - -// Expo : https://expo.dev/ -// Submitted by James Ide -expo.app -staging.expo.app - -// Fabrica Technologies, Inc. : https://www.fabrica.dev/ -// Submitted by Eric Jiang -onfabrica.com - -// FAITID : https://faitid.org/ -// Submitted by Maxim Alzoba -// https://www.flexireg.net/stat_info -ru.net -adygeya.ru -bashkiria.ru -bir.ru -cbg.ru -com.ru -dagestan.ru -grozny.ru -kalmykia.ru -kustanai.ru -marine.ru -mordovia.ru -msk.ru -mytis.ru -nalchik.ru -nov.ru -pyatigorsk.ru -spb.ru -vladikavkaz.ru -vladimir.ru -abkhazia.su -adygeya.su -aktyubinsk.su -arkhangelsk.su -armenia.su -ashgabad.su -azerbaijan.su -balashov.su -bashkiria.su -bryansk.su -bukhara.su -chimkent.su -dagestan.su -east-kazakhstan.su -exnet.su -georgia.su -grozny.su -ivanovo.su -jambyl.su -kalmykia.su -kaluga.su -karacol.su -karaganda.su -karelia.su -khakassia.su -krasnodar.su -kurgan.su -kustanai.su -lenug.su -mangyshlak.su -mordovia.su -msk.su -murmansk.su -nalchik.su -navoi.su -north-kazakhstan.su -nov.su -obninsk.su -penza.su -pokrovsk.su -sochi.su -spb.su -tashkent.su -termez.su -togliatti.su -troitsk.su -tselinograd.su -tula.su -tuva.su -vladikavkaz.su -vladimir.su -vologda.su - -// Fancy Bits, LLC : http://getchannels.com -// Submitted by Aman Gupta -channelsdvr.net -u.channelsdvr.net - -// Fastly Inc. : http://www.fastly.com/ -// Submitted by Fastly Security -edgecompute.app -fastly-edge.com -fastly-terrarium.com -freetls.fastly.net -map.fastly.net -a.prod.fastly.net -global.prod.fastly.net -a.ssl.fastly.net -b.ssl.fastly.net -global.ssl.fastly.net -fastlylb.net -map.fastlylb.net - -// Fastmail : https://www.fastmail.com/ -// Submitted by Marc Bradshaw -*.user.fm - -// FASTVPS EESTI OU : https://fastvps.ru/ -// Submitted by Likhachev Vasiliy -fastvps-server.com -fastvps.host -myfast.host -fastvps.site -myfast.space - -// FearWorks Media Ltd. : https://fearworksmedia.co.uk -// Submitted by Keith Fairley -conn.uk -copro.uk -hosp.uk - -// Fedora : https://fedoraproject.org/ -// Submitted by Patrick Uiterwijk -fedorainfracloud.org -fedorapeople.org -cloud.fedoraproject.org -app.os.fedoraproject.org -app.os.stg.fedoraproject.org - -// Fermax : https://fermax.com/ -// Submitted by Koen Van Isterdael -mydobiss.com - -// FH Muenster : https://www.fh-muenster.de -// Submitted by Robin Naundorf -fh-muenster.io - -// Figma : https://www.figma.com -// Submitted by Nick Frost -figma.site -figma-gov.site -preview.site - -// Filegear Inc. : https://www.filegear.com -// Submitted by Jason Zhu -filegear.me - -// Firebase, Inc. -// Submitted by Chris Raynor -firebaseapp.com - -// FlashDrive : https://flashdrive.io -// Submitted by Eric Chan -fldrv.com - -// Fleek Labs Inc : https://fleek.xyz -// Submitted by Parsa Ghadimi -on-fleek.app - -// FlutterFlow : https://flutterflow.io -// Submitted by Anton Emelyanov -flutterflow.app - -// fly.io : https://fly.io -// Submitted by Kurt Mackey -fly.dev -shw.io -edgeapp.net - -// Forgerock : https://www.forgerock.com -// Submitted by Roderick Parr -forgeblocks.com -id.forgerock.io - -// FoundryLabs, Inc : https://e2b.dev/ -// Submitted by Jiri Sveceny -e2b.app - -// Framer : https://www.framer.com -// Submitted by Koen Rouwhorst -framer.ai -framer.app -framercanvas.com -framer.media -framer.photos -framer.website -framer.wiki - -// Frederik Braun : https://frederik-braun.com -// Submitted by Frederik Braun -*.0e.vc - -// Freebox : http://www.freebox.fr -// Submitted by Romain Fliedel -freebox-os.com -freeboxos.com -fbx-os.fr -fbxos.fr -freebox-os.fr -freeboxos.fr - -// freedesktop.org : https://www.freedesktop.org -// Submitted by Daniel Stone -freedesktop.org - -// freemyip.com : https://freemyip.com -// Submitted by Cadence -freemyip.com - -// Frusky MEDIA&PR : https://www.frusky.de -// Submitted by Victor Pupynin -*.frusky.de - -// FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at -// Submitted by Daniel A. Maierhofer -wien.funkfeuer.at - -// Future Versatile Group. : https://www.fvg-on.net/ -// T.Kabu -daemon.asia -dix.asia -mydns.bz -0am.jp -0g0.jp -0j0.jp -0t0.jp -mydns.jp -pgw.jp -wjg.jp -keyword-on.net -live-on.net -server-on.net -mydns.tw -mydns.vc - -// Futureweb GmbH : https://www.futureweb.at -// Submitted by Andreas Schnederle-Wagner -*.futurecms.at -*.ex.futurecms.at -*.in.futurecms.at -futurehosting.at -futuremailing.at -*.ex.ortsinfo.at -*.kunden.ortsinfo.at -*.statics.cloud - -// GCom Internet : https://www.gcom.net.au -// Submitted by Leo Julius -aliases121.com - -// GDS : https://www.gov.uk/service-manual/technology/managing-domain-names -// Submitted by Stephen Ford -campaign.gov.uk -service.gov.uk -independent-commission.uk -independent-inquest.uk -independent-inquiry.uk -independent-panel.uk -independent-review.uk -public-inquiry.uk -royal-commission.uk - -// Gehirn Inc. : https://www.gehirn.co.jp/ -// Submitted by Kohei YOSHIDA -gehirn.ne.jp -usercontent.jp - -// Gentlent, Inc. : https://www.gentlent.com -// Submitted by Tom Klein -gentapps.com -gentlentapis.com -cdn-edges.net - -// GignoSystemJapan : http://gsj.bz -// Submitted by GignoSystemJapan -gsj.bz - -// GitBook Inc. : https://www.gitbook.com/ -// Submitted by Samy Pesse -gitbook.io - -// GitHub, Inc. -// Submitted by Patrick Toomey -github.app -githubusercontent.com -githubpreview.dev -github.io - -// GitLab, Inc. : https://about.gitlab.com/ -// Submitted by Alex Hanselka -gitlab.io - -// Gitplac.si : https://gitplac.si -// Submitted by Aljaž Starc -gitapp.si -gitpage.si - -// Global NOG Alliance : https://nogalliance.org/ -// Submitted by Sander Steffann -nog.community - -// Globe Hosting SRL : https://www.globehosting.com/ -// Submitted by Gavin Brown -co.ro -shop.ro - -// GMO Pepabo, Inc. : https://pepabo.com/ -// Submitted by Hosting Div -lolipop.io -angry.jp -babyblue.jp -babymilk.jp -backdrop.jp -bambina.jp -bitter.jp -blush.jp -boo.jp -boy.jp -boyfriend.jp -but.jp -candypop.jp -capoo.jp -catfood.jp -cheap.jp -chicappa.jp -chillout.jp -chips.jp -chowder.jp -chu.jp -ciao.jp -cocotte.jp -coolblog.jp -cranky.jp -cutegirl.jp -daa.jp -deca.jp -deci.jp -digick.jp -egoism.jp -fakefur.jp -fem.jp -flier.jp -floppy.jp -fool.jp -frenchkiss.jp -girlfriend.jp -girly.jp -gloomy.jp -gonna.jp -greater.jp -hacca.jp -heavy.jp -her.jp -hiho.jp -hippy.jp -holy.jp -hungry.jp -icurus.jp -itigo.jp -jellybean.jp -kikirara.jp -kill.jp -kilo.jp -kuron.jp -littlestar.jp -lolipopmc.jp -lolitapunk.jp -lomo.jp -lovepop.jp -lovesick.jp -main.jp -mods.jp -mond.jp -mongolian.jp -moo.jp -namaste.jp -nikita.jp -nobushi.jp -noor.jp -oops.jp -parallel.jp -parasite.jp -pecori.jp -peewee.jp -penne.jp -pepper.jp -perma.jp -pigboat.jp -pinoko.jp -punyu.jp -pupu.jp -pussycat.jp -pya.jp -raindrop.jp -readymade.jp -sadist.jp -schoolbus.jp -secret.jp -staba.jp -stripper.jp -sub.jp -sunnyday.jp -thick.jp -tonkotsu.jp -under.jp -upper.jp -velvet.jp -verse.jp -versus.jp -vivian.jp -watson.jp -weblike.jp -whitesnow.jp -zombie.jp -heteml.net - -// GoDaddy Registry : https://registry.godaddy -// Submitted by Rohan Durrant -graphic.design - -// GoIP DNS Services : http://www.goip.de -// Submitted by Christian Poulter -goip.de - -// Google, Inc. -// Submitted by Shannon McCabe -*.hosted.app -*.run.app -*.mtls.run.app -web.app -*.0emm.com -appspot.com -*.r.appspot.com -blogspot.com -codespot.com -googleapis.com -googlecode.com -pagespeedmobilizer.com -withgoogle.com -withyoutube.com -*.gateway.dev -cloud.goog -translate.goog -*.usercontent.goog -cloudfunctions.net - -// Goupile : https://goupile.fr -// Submitted by Niels Martignene -goupile.fr - -// GOV.UK Pay : https://www.payments.service.gov.uk/ -// Submitted by Richard Baker -pymnt.uk - -// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ -// Submitted by Tom Whitwell -cloudapps.digital -london.cloudapps.digital - -// Government of the Netherlands : https://www.government.nl -// Submitted by -gov.nl - -// Grafana Labs : https://grafana.com/ -// Submitted by Platform Engineering -grafana-dev.net - -// GrayJay Web Solutions Inc. : https://grayjaysports.ca -// Submitted by Matt Yamkowy -grayjayleagues.com - -// GünstigBestellen : https://günstigbestellen.de -// Submitted by Furkan Akkoc -günstigbestellen.de -günstigliefern.de - -// Hackclub Nest : https://hackclub.app -// Submitted by Cyteon -hackclub.app - -// Häkkinen.fi : https://www.häkkinen.fi/ -// Submitted by Eero Häkkinen -häkkinen.fi - -// Hashbang : https://hashbang.sh -hashbang.sh - -// Hasura : https://hasura.io -// Submitted by Shahidh K Muhammed -hasura.app -hasura-app.io - -// Hatena Co., Ltd. : https://hatena.co.jp -// Submitted by Masato Nakamura -hatenablog.com -hatenadiary.com -hateblo.jp -hatenablog.jp -hatenadiary.jp -hatenadiary.org - -// Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages) : https://www.hs-heilbronn.de -// Submitted by Richard Zowalla -pages.it.hs-heilbronn.de -pages-research.it.hs-heilbronn.de - -// HeiyuSpace : https://lazycat.cloud -// Submitted by Xia Bin -heiyu.space - -// Helio Networks : https://heliohost.org -// Submitted by Ben Frede -helioho.st -heliohost.us - -// Hepforge : https://www.hepforge.org -// Submitted by David Grellscheid -hepforge.org - -// Heroku : https://www.heroku.com/ -// Submitted by Shumon Huque -herokuapp.com - -// Heyflow : https://www.heyflow.com -// Submitted by Mirko Nitschke -heyflow.page -heyflow.site - -// Hibernating Rhinos -// Submitted by Oren Eini -ravendb.cloud -ravendb.community -development.run -ravendb.run - -// HiDNS : https://www.hidoha.net -// Submitted by ifeng -hidns.co -hidns.vip - -// home.pl S.A. : https://home.pl -// Submitted by Krzysztof Wolski -homesklep.pl - -// Homebase : https://homebase.id/ -// Submitted by Jason Babo -*.kin.one -*.id.pub -*.kin.pub - -// Hoplix : https://www.hoplix.com -// Submitted by Danilo De Franco -hoplix.shop - -// HOSTBIP REGISTRY : https://www.hostbip.com/ -// Submitted by Atanunu Igbunuroghene -orx.biz -biz.ng -co.biz.ng -dl.biz.ng -go.biz.ng -lg.biz.ng -on.biz.ng -col.ng -firm.ng -gen.ng -ltd.ng -ngo.ng -plc.ng - -// HostyHosting : https://hostyhosting.com -hostyhosting.io - -// Hugging Face : https://huggingface.co -// Submitted by Eliott Coyac -hf.space -static.hf.space - -// Hypernode B.V. : https://www.hypernode.com/ -// Submitted by Cipriano Groenendal -hypernode.io - -// I-O DATA DEVICE, INC. : http://www.iodata.com/ -// Submitted by Yuji Minagawa -iobb.net - -// i-registry s.r.o. : http://www.i-registry.cz/ -// Submitted by Martin Semrad -co.cz - -// Ici la Lune : http://www.icilalune.com/ -// Submitted by Simon Morvan -*.moonscale.io -moonscale.net - -// iDOT Services Limited : http://www.domain.gr.com -// Submitted by Gavin Brown -gr.com - -// iki.fi -// Submitted by Hannu Aronsson -iki.fi - -// iliad italia : https://www.iliad.it -// Submitted by Marios Makassikis -ibxos.it -iliadboxos.it - -// Incsub, LLC : https://incsub.com/ -// Submitted by Aaron Edwards -smushcdn.com -wphostedmail.com -wpmucdn.com -tempurl.host -wpmudev.host - -// Individual Network Berlin e.V. : https://www.in-berlin.de/ -// Submitted by Christian Seitz -dyn-berlin.de -in-berlin.de -in-brb.de -in-butter.de -in-dsl.de -in-vpn.de -in-dsl.net -in-vpn.net -in-dsl.org -in-vpn.org - -// Inferno Communications : https://inferno.co.uk -// Submitted by Connor McFarlane -oninferno.net - -// info.at : http://www.info.at/ -biz.at -info.at - -// info.cx : http://info.cx -// Submitted by June Slater -info.cx - -// Interlegis : http://www.interlegis.leg.br -// Submitted by Gabriel Ferreira -ac.leg.br -al.leg.br -am.leg.br -ap.leg.br -ba.leg.br -ce.leg.br -df.leg.br -es.leg.br -go.leg.br -ma.leg.br -mg.leg.br -ms.leg.br -mt.leg.br -pa.leg.br -pb.leg.br -pe.leg.br -pi.leg.br -pr.leg.br -rj.leg.br -rn.leg.br -ro.leg.br -rr.leg.br -rs.leg.br -sc.leg.br -se.leg.br -sp.leg.br -to.leg.br - -// intermetrics GmbH : https://pixolino.com/ -// Submitted by Wolfgang Schwarz -pixolino.com - -// Internet-Pro, LLP : https://netangels.ru/ -// Submitted by Vasiliy Sheredeko -na4u.ru - -// Inventor Services : https://inventor.gg/ -// Submitted by Inventor Team -botdash.app -botdash.dev -botdash.gg -botdash.net -botda.sh -botdash.xyz - -// IONOS SE : https://www.ionos.com/ -// IONOS Group SE : https://www.ionos-group.com/ -// Submitted by Henrik Willert -apps-1and1.com -live-website.com -webspace-host.com -apps-1and1.net -websitebuilder.online -app-ionos.space - -// iopsys software solutions AB : https://iopsys.eu/ -// Submitted by Roman Azarenko -iopsys.se - -// IPFS Project : https://ipfs.tech/ -// Submitted by Interplanetary Shipyard -*.inbrowser.dev -*.dweb.link -*.inbrowser.link - -// IPiFony Systems, Inc. : https://www.ipifony.com/ -// Submitted by Matthew Hardeman -ipifony.net - -// ir.md : https://nic.ir.md -// Submitted by Ali Soizi -ir.md - -// is-a-good.dev : https://is-a-good.dev -// Submitted by William Harrison -is-a-good.dev - -// IServ GmbH : https://iserv.de -// Submitted by Kim Brodowski -iservschule.de -mein-iserv.de -schuldock.de -schulplattform.de -schulserver.de -test-iserv.de -iserv.dev -iserv.host - -// Ispmanager : https://www.ispmanager.com/ -// Submitted by Ispmanager infrastructure team -ispmanager.name - -// Jelastic, Inc. : https://jelastic.com/ -// Submitted by Ihor Kolodyuk -mel.cloudlets.com.au -cloud.interhostsolutions.be -alp1.ae.flow.ch -appengine.flow.ch -es-1.axarnet.cloud -diadem.cloud -vip.jelastic.cloud -jele.cloud -it1.eur.aruba.jenv-aruba.cloud -it1.jenv-aruba.cloud -keliweb.cloud -cs.keliweb.cloud -oxa.cloud -tn.oxa.cloud -uk.oxa.cloud -primetel.cloud -uk.primetel.cloud -ca.reclaim.cloud -uk.reclaim.cloud -us.reclaim.cloud -ch.trendhosting.cloud -de.trendhosting.cloud -jele.club -dopaas.com -paas.hosted-by-previder.com -rag-cloud.hosteur.com -rag-cloud-ch.hosteur.com -jcloud.ik-server.com -jcloud-ver-jpc.ik-server.com -demo.jelastic.com -paas.massivegrid.com -jed.wafaicloud.com -ryd.wafaicloud.com -j.scaleforce.com.cy -jelastic.dogado.eu -fi.cloudplatform.fi -demo.datacenter.fi -paas.datacenter.fi -jele.host -mircloud.host -paas.beebyte.io -sekd1.beebyteapp.io -jele.io -jc.neen.it -jcloud.kz -cloudjiffy.net -fra1-de.cloudjiffy.net -west1-us.cloudjiffy.net -jls-sto1.elastx.net -jls-sto2.elastx.net -jls-sto3.elastx.net -fr-1.paas.massivegrid.net -lon-1.paas.massivegrid.net -lon-2.paas.massivegrid.net -ny-1.paas.massivegrid.net -ny-2.paas.massivegrid.net -sg-1.paas.massivegrid.net -jelastic.saveincloud.net -nordeste-idc.saveincloud.net -j.scaleforce.net -sdscloud.pl -unicloud.pl -mircloud.ru -enscaled.sg -jele.site -jelastic.team -orangecloud.tn -j.layershift.co.uk -phx.enscaled.us -mircloud.us - -// Jino : https://www.jino.ru -// Submitted by Sergey Ulyashin -myjino.ru -*.hosting.myjino.ru -*.landing.myjino.ru -*.spectrum.myjino.ru -*.vps.myjino.ru - -// Jotelulu S.L. : https://jotelulu.com -// Submitted by Daniel Fariña -jote.cloud -jotelulu.cloud -eu1-plenit.com -la1-plenit.com -us1-plenit.com - -// JouwWeb B.V. : https://www.jouwweb.nl -// Submitted by Camilo Sperberg -webadorsite.com -jouwweb.site - -// Joyent : https://www.joyent.com/ -// Submitted by Brian Bennett -*.cns.joyent.com -*.triton.zone - -// JS.ORG : http://dns.js.org -// Submitted by Stefan Keim -js.org - -// KaasHosting : http://www.kaashosting.nl/ -// Submitted by Wouter Bakker -kaas.gg -khplay.nl - -// Kapsi : https://kapsi.fi -// Submitted by Tomi Juntunen -kapsi.fi - -// Katholieke Universiteit Leuven : https://www.kuleuven.be -// Submitted by Abuse KU Leuven -ezproxy.kuleuven.be -kuleuven.cloud - -// Keyweb AG : https://www.keyweb.de -// Submitted by Martin Dannehl -keymachine.de - -// KingHost : https://king.host -// Submitted by Felipe Keller Braz -kinghost.net -uni5.net - -// KnightPoint Systems, LLC : http://www.knightpoint.com/ -// Submitted by Roy Keene -knightpoint.systems - -// KoobinEvent, SL : https://www.koobin.com -// Submitted by Iván Oliva -koobin.events - -// Krellian Ltd. : https://krellian.com -// Submitted by Ben Francis -webthings.io -krellian.net - -// KUROKU LTD : https://kuroku.ltd/ -// Submitted by DisposaBoy -oya.to - -// KV GmbH : https://www.nic.co.de -// Submitted by KV GmbH -// Abuse reports to -co.de - -// Laravel Holdings, Inc. : https://laravel.com -// Submitted by André Valentin & James Brooks -laravel.cloud -on-forge.com -on-vapor.com - -// LCube - Professional hosting e.K. : https://www.lcube-webhosting.de -// Submitted by Lars Laehn -git-repos.de -lcube-server.de -svn-repos.de - -// Leadpages : https://www.leadpages.net -// Submitted by Greg Dallavalle -leadpages.co -lpages.co -lpusercontent.com - -// Leapcell : https://leapcell.io/ -// Submitted by Leapcell Team -leapcell.app -leapcell.dev -leapcell.online - -// Liara : https://liara.ir -// Submitted by Amirhossein Badinloo -liara.run -iran.liara.run - -// libp2p project : https://libp2p.io -// Submitted by Interplanetary Shipyard -libp2p.direct - -// Libre IT Ltd : https://libre.nz -// Submitted by Tomas Maggio -runcontainers.dev - -// Lifetime Hosting : https://Lifetime.Hosting/ -// Submitted by Mike Fillator -co.business -co.education -co.events -co.financial -co.network -co.place -co.technology - -// linkyard ldt : https://www.linkyard.ch/ -// Submitted by Mario Siegenthaler -linkyard-cloud.ch -linkyard.cloud - -// Linode : https://linode.com -// Submitted by -members.linode.com -*.nodebalancer.linode.com -*.linodeobjects.com -ip.linodeusercontent.com - -// LiquidNet Ltd : http://www.liquidnetlimited.com/ -// Submitted by Victor Velchev -we.bs - -// Listen53 : https://www.l53.net -// Submitted by Gerry Keh -filegear-sg.me -ggff.net - -// Localcert : https://localcert.dev -// Submitted by Lann Martin -*.user.localcert.dev - -// Localtonet : https://localtonet.com/ -// Submitted by Burak Isleyici -localtonet.com -*.localto.net - -// Lodz University of Technology LODMAN regional domains : https://www.man.lodz.pl/dns -// Submitted by Piotr Wilk -lodz.pl -pabianice.pl -plock.pl -sieradz.pl -skierniewice.pl -zgierz.pl - -// Log'in Line : https://www.loginline.com/ -// Submitted by Rémi Mach -loginline.app -loginline.dev -loginline.io -loginline.services -loginline.site - -// Lõhmus Family, The : https://lohmus.me/ -// Submitted by Heiki Lõhmus -lohmus.me - -// Lovable : https://lovable.dev -// Submitted by Fabian Hedin -lovable.app -lovableproject.com -lovable.run -lovable.sh - -// LubMAN UMCS Sp. z o.o : https://lubman.pl/ -// Submitted by Ireneusz Maliszewski -krasnik.pl -leczna.pl -lubartow.pl -lublin.pl -poniatowa.pl -swidnik.pl - -// Lug.org.uk : https://lug.org.uk -// Submitted by Jon Spriggs -glug.org.uk -lug.org.uk -lugs.org.uk - -// Lukanet Ltd : https://lukanet.com -// Submitted by Anton Avramov -barsy.bg -barsy.club -barsycenter.com -barsyonline.com -barsy.de -barsy.dev -barsy.eu -barsy.gr -barsy.in -barsy.info -barsy.io -barsy.me -barsy.menu -barsyonline.menu -barsy.mobi -barsy.net -barsy.online -barsy.org -barsy.pro -barsy.pub -barsy.ro -barsy.rs -barsy.shop -barsyonline.shop -barsy.site -barsy.store -barsy.support -barsy.uk -barsy.co.uk -barsyonline.co.uk - -// Lutra : https://lutra.ai -// Submitted by Joshua Newman -*.lutrausercontent.com - -// Luyani Inc. : https://luyani.com/ -// Submitted by Umut Gumeli -luyani.app -luyani.net - -// Magento Commerce -// Submitted by Damien Tournoud -*.magentosite.cloud - -// Mail.Ru Group : https://hb.cldmail.ru -// Submitted by Ilya Zaretskiy -hb.cldmail.ru - -// MathWorks : https://www.mathworks.com/ -// Submitted by Emily Reed -matlab.cloud -modelscape.com -mwcloudnonprod.com -polyspace.com - -// May First - People Link : https://mayfirst.org/ -// Submitted by Jamie McClelland -mayfirst.info -mayfirst.org - -// Maze Play : https://www.mazeplay.com -// Submitted by Adam Humpherys -mazeplay.com - -// McHost : https://mchost.ru -// Submitted by Evgeniy Subbotin -mcdir.me -mcdir.ru -vps.mcdir.ru -mcpre.ru - -// Mediatech : https://mediatech.by -// Submitted by Evgeniy Kozhuhovskiy -mediatech.by -mediatech.dev - -// Medicom Health : https://medicomhealth.com -// Submitted by Michael Olson -hra.health - -// MedusaJS, Inc : https://medusajs.com/ -// Submitted by Stevche Radevski -medusajs.app - -// Memset hosting : https://www.memset.com -// Submitted by Tom Whitwell -miniserver.com -memset.net - -// Messerli Informatik AG : https://www.messerli.ch/ -// Submitted by Ruben Schmidmeister -messerli.app - -// Meta Platforms, Inc. : https://meta.com/ -// Submitted by Jacob Cordero -atmeta.com -apps.fbsbx.com - -// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ -// Submitted by Zdeněk Šustr and Radim Janča -*.cloud.metacentrum.cz -custom.metacentrum.cz -flt.cloud.muni.cz -usr.cloud.muni.cz - -// Meteor Development Group : https://www.meteor.com/hosting -// Submitted by Pierre Carrier -meteorapp.com -eu.meteorapp.com - -// Michau Enterprises Limited : http://www.co.pl/ -co.pl - -// Microsoft Corporation : http://microsoft.com -// Submitted by Public Suffix List Admin -// Managed by Corporate Domains -// Microsoft Azure : https://home.azure -*.azurecontainer.io -azure-api.net -azure-mobile.net -azureedge.net -azurefd.net -azurestaticapps.net -1.azurestaticapps.net -2.azurestaticapps.net -3.azurestaticapps.net -4.azurestaticapps.net -5.azurestaticapps.net -6.azurestaticapps.net -7.azurestaticapps.net -centralus.azurestaticapps.net -eastasia.azurestaticapps.net -eastus2.azurestaticapps.net -westeurope.azurestaticapps.net -westus2.azurestaticapps.net -azurewebsites.net -cloudapp.net -trafficmanager.net -blob.core.windows.net -servicebus.windows.net - -// MikroTik : https://mikrotik.com -// Submitted by MikroTik SysAdmin Team -routingthecloud.com -sn.mynetname.net -routingthecloud.net -routingthecloud.org - -// Million Software, Inc : https://million.dev/ -// Submitted by Rayhan Noufal Arayilakath -same-app.com -same-preview.com - -// minion.systems : http://minion.systems -// Submitted by Robert Böttinger -csx.cc - -// Mittwald CM Service GmbH & Co. KG : https://mittwald.de -// Submitted by Marco Rieger -mydbserver.com -webspaceconfig.de -mittwald.info -mittwaldserver.info -typo3server.info -project.space - -// Mocha : https://getmocha.com -// Submitted by Ben Reinhart -mocha.app -mochausercontent.com -mocha-sandbox.dev - -// MODX Systems LLC : https://modx.com -// Submitted by Elizabeth Southwell -modx.dev - -// Mozilla Foundation : https://mozilla.org/ -// Submitted by glob -bmoattachments.org - -// MSK-IX : https://www.msk-ix.ru/ -// Submitted by Khannanov Roman -net.ru -org.ru -pp.ru - -// Mythic Beasts : https://www.mythic-beasts.com -// Submitted by Paul Cammish -hostedpi.com -caracal.mythic-beasts.com -customer.mythic-beasts.com -fentiger.mythic-beasts.com -lynx.mythic-beasts.com -ocelot.mythic-beasts.com -oncilla.mythic-beasts.com -onza.mythic-beasts.com -sphinx.mythic-beasts.com -vs.mythic-beasts.com -x.mythic-beasts.com -yali.mythic-beasts.com -cust.retrosnub.co.uk - -// Nabu Casa : https://www.nabucasa.com -// Submitted by Paulus Schoutsen -ui.nabu.casa - -// Needle Tools GmbH : https://needle.tools -// Submitted by Felix Herbst -needle.run - -// Neo : https://www.neo.space -// Submitted by Ankit Kulkarni -co.site - -// Net at Work Gmbh : https://www.netatwork.de -// Submitted by Jan Jaeschke -cloud.nospamproxy.com -o365.cloud.nospamproxy.com - -// Net libre : https://www.netlib.re -// Submitted by Philippe PITTOLI -netlib.re - -// Netlify : https://www.netlify.com -// Submitted by Jessica Parsons -netlify.app - -// Neustar Inc. -// Submitted by Trung Tran -4u.com - -// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ -// Submitted by Jeff Wheelhouse -nfshost.com - -// NFT.Storage : https://nft.storage/ -// Submitted by Vasco Santos or -ipfs.nftstorage.link - -// NGO.US Registry : https://nic.ngo.us -// Submitted by Alstra Solutions Ltd. Networking Team -ngo.us - -// ngrok : https://ngrok.com/ -// Submitted by Alan Shreve -ngrok.app -ngrok-free.app -ngrok.dev -ngrok-free.dev -ngrok.io -ap.ngrok.io -au.ngrok.io -eu.ngrok.io -in.ngrok.io -jp.ngrok.io -sa.ngrok.io -us.ngrok.io -ngrok.pizza -ngrok.pro - -// Nicolaus Copernicus University in Torun - MSK TORMAN : https://www.man.torun.pl -torun.pl - -// Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ -// Submitted by Nicholas Ford -nh-serv.co.uk -nimsite.uk - -// No-IP.com : https://noip.com/ -// Submitted by Deven Reza -mmafan.biz -myftp.biz -no-ip.biz -no-ip.ca -fantasyleague.cc -gotdns.ch -3utilities.com -blogsyte.com -ciscofreak.com -damnserver.com -ddnsking.com -ditchyourip.com -dnsiskinky.com -dynns.com -geekgalaxy.com -health-carereform.com -homesecuritymac.com -homesecuritypc.com -myactivedirectory.com -mysecuritycamera.com -myvnc.com -net-freaks.com -onthewifi.com -point2this.com -quicksytes.com -securitytactics.com -servebeer.com -servecounterstrike.com -serveexchange.com -serveftp.com -servegame.com -servehalflife.com -servehttp.com -servehumour.com -serveirc.com -servemp3.com -servep2p.com -servepics.com -servequake.com -servesarcasm.com -stufftoread.com -unusualperson.com -workisboring.com -dvrcam.info -ilovecollege.info -no-ip.info -brasilia.me -ddns.me -dnsfor.me -hopto.me -loginto.me -noip.me -webhop.me -bounceme.net -ddns.net -eating-organic.net -mydissent.net -myeffect.net -mymediapc.net -mypsx.net -mysecuritycamera.net -nhlfan.net -no-ip.net -pgafan.net -privatizehealthinsurance.net -redirectme.net -serveblog.net -serveminecraft.net -sytes.net -cable-modem.org -collegefan.org -couchpotatofries.org -hopto.org -mlbfan.org -myftp.org -mysecuritycamera.org -nflfan.org -no-ip.org -read-books.org -ufcfan.org -zapto.org -no-ip.co.uk -golffan.us -noip.us -pointto.us - -// NodeArt : https://nodeart.io -// Submitted by Konstantin Nosov -stage.nodeart.io - -// Noop : https://noop.app -// Submitted by Nathaniel Schweinberg -*.developer.app -noop.app - -// Northflank Ltd. : https://northflank.com/ -// Submitted by Marco Suter -*.northflank.app -*.build.run -*.code.run -*.database.run -*.migration.run - -// Noticeable : https://noticeable.io -// Submitted by Laurent Pellegrino -noticeable.news - -// Notion Labs, Inc : https://www.notion.so/ -// Submitted by Jess Yao -notion.site - -// Now-DNS : https://now-dns.com -// Submitted by Steve Russell -dnsking.ch -mypi.co -myiphost.com -forumz.info -soundcast.me -tcp4.me -dnsup.net -hicam.net -now-dns.net -ownip.net -vpndns.net -dynserv.org -now-dns.org -x443.pw -ntdll.top -freeddns.us - -// nsupdate.info : https://www.nsupdate.info/ -// Submitted by Thomas Waldmann -nsupdate.info -nerdpol.ovh - -// NYC.mn : https://dot.nyc.mn/ -// Submitted by NYC.mn Subdomain Service -nyc.mn - -// O3O.Foundation : https://o3o.foundation/ -// Submitted by the prvcy.page Registry Team -prvcy.page - -// Obl.ong : https://obl.ong -// Submitted by Reese Armstrong -obl.ong - -// Observable, Inc. : https://observablehq.com -// Submitted by Mike Bostock -observablehq.cloud -static.observableusercontent.com - -// OMG.LOL : https://omg.lol -// Submitted by Adam Newbold -omg.lol - -// Omnibond Systems, LLC. : https://www.omnibond.com -// Submitted by Cole Estep -cloudycluster.net - -// OmniWe Limited : https://omniwe.com -// Submitted by Vicary Archangel -omniwe.site - -// One.com : https://www.one.com/ -// Submitted by Jacob Bunk Nielsen -123webseite.at -123website.be -simplesite.com.br -123website.ch -simplesite.com -123webseite.de -123hjemmeside.dk -123miweb.es -123kotisivu.fi -123siteweb.fr -simplesite.gr -123homepage.it -123website.lu -123website.nl -123hjemmeside.no -service.one -website.one -simplesite.pl -123paginaweb.pt -123minsida.se - -// ONID : https://get.onid.ca -// Submitted by ONID Engineering Team -onid.ca - -// Open Domains : https://open-domains.net -// Submitted by William Harrison -is-a-fullstack.dev -is-cool.dev -is-not-a.dev -localplayer.dev -is-local.org - -// Open Social : https://www.getopensocial.com/ -// Submitted by Alexander Varwijk -opensocial.site - -// OpenAI : https://openai.com -// Submitted by Thomas Shadwell -*.oaiusercontent.com - -// OpenCraft GmbH : http://opencraft.com/ -// Submitted by Sven Marnach -opencraft.hosting - -// OpenHost : https://registry.openhost.uk -// Submitted by OpenHost Registry Team -16-b.it -32-b.it -64-b.it - -// OpenResearch GmbH : https://openresearch.com/ -// Submitted by Philipp Schmid -orsites.com - -// Opera Software, A.S.A. -// Submitted by Yngve Pettersen -operaunite.com - -// Oracle Dyn : https://cloud.oracle.com/home https://dyn.com/dns/ -// Submitted by Gregory Drake -// Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label -*.customer-oci.com -*.oci.customer-oci.com -*.ocp.customer-oci.com -*.ocs.customer-oci.com -*.oraclecloudapps.com -*.oraclegovcloudapps.com -*.oraclegovcloudapps.uk - -// Orange : https://www.orange.com -// Submitted by Alexandre Linte -tech.orange - -// OsSav Technology Ltd. : https://ossav.com/ -// Submitted by OsSav Technology Ltd. -// https://nic.can.re -can.re - -// Oursky Limited : https://authgear.com/ -// Submitted by Authgear Team & Skygear Developer -authgear-staging.com -authgearapps.com -skygearapp.com - -// OutSystems -// Submitted by Duarte Santos -outsystemscloud.com - -// OVHcloud : https://ovhcloud.com -// Submitted by Vincent Cassé -*.hosting.ovh.net -*.webpaas.ovh.net - -// OwnProvider GmbH : http://www.ownprovider.com -// Submitted by Jan Moennich -ownprovider.com -own.pm - -// OwO : https://whats-th.is/ -// Submitted by Dean Sheather -*.owo.codes - -// OX : http://www.ox.rs -// Submitted by Adam Grand -ox.rs - -// oy.lc -// Submitted by Charly Coste -oy.lc - -// Pagefog : https://pagefog.com/ -// Submitted by Derek Myers -pgfog.com - -// PageXL : https://pagexl.com -// Submitted by Yann Guichard -pagexl.com - -// Pantheon Systems, Inc. : https://pantheon.io/ -// Submitted by Gary Dylina -gotpantheon.com -pantheonsite.io - -// Paywhirl, Inc : https://paywhirl.com/ -// Submitted by Daniel Netzer -*.paywhirl.com - -// pcarrier.ca Software Inc : https://pcarrier.ca/ -// Submitted by Pierre Carrier -*.xmit.co -xmit.dev -madethis.site -srv.us -gh.srv.us -gl.srv.us - -// PE Ulyanov Kirill Sergeevich : https://airy.host -// Submitted by Kirill Ulyanov -lk3.ru - -// Peplink | Pepwave : http://peplink.com/ -// Submitted by Steve Leung -mypep.link - -// Perspecta : https://perspecta.com/ -// Submitted by Kenneth Van Alstyne -perspecta.cloud - -// Plain : https://www.plain.com/ -// Submitted by Jesús Hernández -support.site - -// Planet-Work : https://www.planet-work.com/ -// Submitted by Frédéric VANNIÈRE -on-web.fr - -// Platform.sh : https://platform.sh -// Submitted by Nikola Kotur -*.upsun.app -upsunapp.com -ent.platform.sh -eu.platform.sh -us.platform.sh -*.platformsh.site -*.tst.site - -// Platter : https://platter.dev -// Submitted by Patrick Flor -platter-app.dev -platterp.us - -// Pley AB : https://www.pley.com/ -// Submitted by Henning Pohl -pley.games - -// Porter : https://porter.run/ -// Submitted by Rudraksh MK -onporter.run - -// Positive Codes Technology Company : http://co.bn/faq.html -// Submitted by Zulfais -co.bn - -// Postman, Inc : https://postman.com -// Submitted by Rahul Dhawan -postman-echo.com -pstmn.io -mock.pstmn.io -httpbin.org - -// prequalifyme.today : https://prequalifyme.today -// Submitted by DeepakTiwari deepak@ivylead.io -prequalifyme.today - -// prgmr.com : https://prgmr.com/ -// Submitted by Sarah Newman -xen.prgmr.com - -// priv.at : http://www.nic.priv.at/ -// Submitted by registry -priv.at - -// PROJECT ELIV : https://eliv.kr/ -// Submitted by PROJECT ELIV Domain Team -c01.kr -eliv-cdn.kr -eliv-dns.kr -mmv.kr -vki.kr - -// project-study : https://project-study.com -// Submitted by yumenewa -dev.project-study.com - -// Protonet GmbH : http://protonet.io -// Submitted by Martin Meier -protonet.io - -// PT Ekossistim Indo Digital : https://e.id -// Submitted by Eid Team -e.id - -// Publication Presse Communication SARL : https://ppcom.fr -// Submitted by Yaacov Akiba Slama -chirurgiens-dentistes-en-france.fr -byen.site - -// pubtls.org : https://www.pubtls.org -// Submitted by Kor Nielsen -pubtls.org - -// PythonAnywhere LLP : https://www.pythonanywhere.com -// Submitted by Giles Thomas -pythonanywhere.com -eu.pythonanywhere.com - -// QA2 -// Submitted by Daniel Dent : https://www.danieldent.com/ -qa2.com - -// QCX -// Submitted by Cassandra Beelen -qcx.io -*.sys.qcx.io - -// QNAP System Inc : https://www.qnap.com -// Submitted by Nick Chang -myqnapcloud.cn -alpha-myqnapcloud.com -dev-myqnapcloud.com -mycloudnas.com -mynascloud.com -myqnapcloud.com - -// QOTO, Org. -// Submitted by Jeffrey Phillips Freeman -qoto.io - -// Qualifio : https://qualifio.com/ -// Submitted by Xavier De Cock -qualifioapp.com - -// Quality Unit : https://qualityunit.com -// Submitted by Vasyl Tsalko -ladesk.com - -// Qualy : https://qualyhq.com -// Submitted by Raphael Arias -*.qualyhqpartner.com -*.qualyhqportal.com - -// QuickBackend : https://www.quickbackend.com -// Submitted by Dani Biro -qbuser.com - -// Quip : https://quip.com -// Submitted by Patrick Linehan -*.quipelements.com - -// Qutheory LLC : http://qutheory.io -// Submitted by Jonas Schwartz -vapor.cloud -vaporcloud.io - -// Rackmaze LLC : https://www.rackmaze.com -// Submitted by Kirill Pertsev -rackmaze.com -rackmaze.net - -// Rad Web Hosting : https://radwebhosting.com -// Submitted by Scott Claeys -cloudsite.builders -myradweb.net -servername.us - -// Radix FZC : http://domains.in.net -// Submitted by Gavin Brown -web.in -in.net - -// Raidboxes GmbH : https://raidboxes.de -// Submitted by Auke Tembrink -myrdbx.io -site.rb-hosting.io - -// Railway Corporation : https://railway.com -// Submitted by Phineas Walton -up.railway.app - -// Rancher Labs, Inc : https://rancher.com -// Submitted by Vincent Fiduccia -*.on-rancher.cloud -*.on-k3s.io -*.on-rio.io - -// RavPage : https://www.ravpage.co.il -// Submitted by Roni Horowitz -ravpage.co.il - -// Read The Docs, Inc : https://www.readthedocs.org -// Submitted by David Fischer -readthedocs-hosted.com -readthedocs.io - -// Red Hat, Inc. OpenShift : https://openshift.redhat.com/ -// Submitted by Tim Kramer -rhcloud.com - -// Redgate Software : https://red-gate.com -// Submitted by Andrew Farries -instances.spawn.cc - -// Render : https://render.com -// Submitted by Anurag Goel -onrender.com -app.render.com - -// Repl.it : https://repl.it -// Submitted by Lincoln Bergeson -replit.app -id.replit.app -firewalledreplit.co -id.firewalledreplit.co -repl.co -id.repl.co -replit.dev -archer.replit.dev -bones.replit.dev -canary.replit.dev -global.replit.dev -hacker.replit.dev -id.replit.dev -janeway.replit.dev -kim.replit.dev -kira.replit.dev -kirk.replit.dev -odo.replit.dev -paris.replit.dev -picard.replit.dev -pike.replit.dev -prerelease.replit.dev -reed.replit.dev -riker.replit.dev -sisko.replit.dev -spock.replit.dev -staging.replit.dev -sulu.replit.dev -tarpit.replit.dev -teams.replit.dev -tucker.replit.dev -wesley.replit.dev -worf.replit.dev -repl.run - -// Resin.io : https://resin.io -// Submitted by Tim Perry -resindevice.io -devices.resinstaging.io - -// RethinkDB : https://www.rethinkdb.com/ -// Submitted by Chris Kastorff -hzc.io - -// Rico Developments Limited : https://adimo.co -// Submitted by Colin Brown -adimo.co.uk - -// Riseup Networks : https://riseup.net -// Submitted by Micah Anderson -itcouldbewor.se - -// Roar Domains LLC : https://roar.basketball/ -// Submitted by Gavin Brown -aus.basketball -nz.basketball - -// ROBOT PAYMENT INC. : https://www.robotpayment.co.jp/ -// Submitted by Kentaro Takamori -subsc-pay.com -subsc-pay.net - -// Rochester Institute of Technology : http://www.rit.edu/ -// Submitted by Jennifer Herting -git-pages.rit.edu - -// Rocky Enterprise Software Foundation : https://resf.org -// Submitted by Neil Hanlon -rocky.page - -// Ruhr University Bochum : https://www.ruhr-uni-bochum.de/ -// Submitted by Andreas Jobs -rub.de -ruhr-uni-bochum.de -io.noc.ruhr-uni-bochum.de - -// Rusnames Limited : http://rusnames.ru/ -// Submitted by Sergey Zotov -биз.рус -ком.рус -крым.рус -мир.рус -мск.рус -орг.рус -самара.рус -сочи.рус -спб.рус -я.рус - -// Russian Academy of Sciences -// Submitted by Tech Support -ras.ru - -// Sakura Frp : https://www.natfrp.com -// Submitted by Bobo Liu -nyat.app - -// SAKURA Internet Inc. : https://www.sakura.ad.jp/ -// Submitted by Internet Service Department -180r.com -dojin.com -sakuratan.com -sakuraweb.com -x0.com -2-d.jp -bona.jp -crap.jp -daynight.jp -eek.jp -flop.jp -halfmoon.jp -jeez.jp -matrix.jp -mimoza.jp -ivory.ne.jp -mail-box.ne.jp -mints.ne.jp -mokuren.ne.jp -opal.ne.jp -sakura.ne.jp -sumomo.ne.jp -topaz.ne.jp -netgamers.jp -nyanta.jp -o0o0.jp -rdy.jp -rgr.jp -rulez.jp -s3.isk01.sakurastorage.jp -s3.isk02.sakurastorage.jp -saloon.jp -sblo.jp -skr.jp -tank.jp -uh-oh.jp -undo.jp -rs.webaccel.jp -user.webaccel.jp -websozai.jp -xii.jp -squares.net -jpn.org -kirara.st -x0.to -from.tv -sakura.tv - -// Salesforce.com, Inc. : https://salesforce.com/ -// Submitted by Salesforce Public Suffix List Team -*.builder.code.com -*.dev-builder.code.com -*.stg-builder.code.com -*.001.test.code-builder-stg.platform.salesforce.com -*.d.crm.dev -*.w.crm.dev -*.wa.crm.dev -*.wb.crm.dev -*.wc.crm.dev -*.wd.crm.dev -*.we.crm.dev -*.wf.crm.dev - -// Sandstorm Development Group, Inc. : https://sandcats.io/ -// Submitted by Asheesh Laroia -sandcats.io - -// SBE network solutions GmbH : https://www.sbe.de/ -// Submitted by Norman Meilick -logoip.com -logoip.de - -// Scaleway : https://www.scaleway.com/ -// Submitted by Scaleway PSL Maintainer -fr-par-1.baremetal.scw.cloud -fr-par-2.baremetal.scw.cloud -nl-ams-1.baremetal.scw.cloud -cockpit.fr-par.scw.cloud -ddl.fr-par.scw.cloud -dtwh.fr-par.scw.cloud -fnc.fr-par.scw.cloud -functions.fnc.fr-par.scw.cloud -ifr.fr-par.scw.cloud -k8s.fr-par.scw.cloud -nodes.k8s.fr-par.scw.cloud -kafk.fr-par.scw.cloud -mgdb.fr-par.scw.cloud -rdb.fr-par.scw.cloud -s3.fr-par.scw.cloud -s3-website.fr-par.scw.cloud -scbl.fr-par.scw.cloud -whm.fr-par.scw.cloud -priv.instances.scw.cloud -pub.instances.scw.cloud -k8s.scw.cloud -cockpit.nl-ams.scw.cloud -ddl.nl-ams.scw.cloud -dtwh.nl-ams.scw.cloud -ifr.nl-ams.scw.cloud -k8s.nl-ams.scw.cloud -nodes.k8s.nl-ams.scw.cloud -kafk.nl-ams.scw.cloud -mgdb.nl-ams.scw.cloud -rdb.nl-ams.scw.cloud -s3.nl-ams.scw.cloud -s3-website.nl-ams.scw.cloud -scbl.nl-ams.scw.cloud -whm.nl-ams.scw.cloud -cockpit.pl-waw.scw.cloud -ddl.pl-waw.scw.cloud -dtwh.pl-waw.scw.cloud -ifr.pl-waw.scw.cloud -k8s.pl-waw.scw.cloud -nodes.k8s.pl-waw.scw.cloud -kafk.pl-waw.scw.cloud -mgdb.pl-waw.scw.cloud -rdb.pl-waw.scw.cloud -s3.pl-waw.scw.cloud -s3-website.pl-waw.scw.cloud -scbl.pl-waw.scw.cloud -scalebook.scw.cloud -smartlabeling.scw.cloud -dedibox.fr - -// schokokeks.org GbR : https://schokokeks.org/ -// Submitted by Hanno Böck -schokokeks.net - -// Scottish Government : https://www.gov.scot -// Submitted by Martin Ellis -gov.scot -service.gov.scot - -// Scry Security : http://www.scrysec.com -// Submitted by Shante Adam -scrysec.com - -// Scrypted : https://scrypted.app -// Submitted by Koushik Dutta -client.scrypted.io - -// Securepoint GmbH : https://www.securepoint.de -// Submitted by Erik Anders -firewall-gateway.com -firewall-gateway.de -my-gateway.de -my-router.de -spdns.de -spdns.eu -firewall-gateway.net -my-firewall.org -myfirewall.org -spdns.org - -// Seidat : https://www.seidat.com -// Submitted by Artem Kondratev -seidat.net - -// Sellfy : https://sellfy.com -// Submitted by Yuriy Romadin -sellfy.store - -// Sendmsg : https://www.sendmsg.co.il -// Submitted by Assaf Stern -minisite.ms - -// Senseering GmbH : https://www.senseering.de -// Submitted by Felix Mönckemeyer -senseering.net - -// Servebolt AS : https://servebolt.com -// Submitted by Daniel Kjeserud -servebolt.cloud - -// Service Online LLC : http://drs.ua/ -// Submitted by Serhii Bulakh -biz.ua -co.ua -pp.ua - -// Shanghai Accounting Society : https://www.sasf.org.cn -// Submitted by Information Administration -as.sh.cn - -// Sheezy.Art : https://sheezy.art -// Submitted by Nyoom -sheezy.games - -// Shopblocks : http://www.shopblocks.com/ -// Submitted by Alex Bowers -myshopblocks.com - -// Shopify : https://www.shopify.com -// Submitted by Alex Richter -myshopify.com - -// Shopit : https://www.shopitcommerce.com/ -// Submitted by Craig McMahon -shopitsite.com - -// shopware AG : https://shopware.com -// Submitted by Jens Küper -shopware.shop -shopware.store - -// Siemens Mobility GmbH -// Submitted by Oliver Graebner -mo-siemens.io - -// SinaAppEngine : http://sae.sina.com.cn/ -// Submitted by SinaAppEngine -1kapp.com -appchizi.com -applinzi.com -sinaapp.com -vipsinaapp.com - -// Siteleaf : https://www.siteleaf.com/ -// Submitted by Skylar Challand -siteleaf.net - -// Small Technology Foundation : https://small-tech.org -// Submitted by Aral Balkan -small-web.org - -// Smallregistry by Promopixel SARL : https://www.smallregistry.net -// Former AFNIC's SLDs -// Submitted by Jérôme Lipowicz -aeroport.fr -avocat.fr -chambagri.fr -chirurgiens-dentistes.fr -experts-comptables.fr -medecin.fr -notaires.fr -pharmacien.fr -port.fr -veterinaire.fr - -// Smoove.io : https://www.smoove.io/ -// Submitted by Dan Kozak -vp4.me - -// Snowflake Inc : https://www.snowflake.com/ -// Submitted by Sam Haar -*.snowflake.app -*.privatelink.snowflake.app -streamlit.app -streamlitapp.com - -// Snowplow Analytics : https://snowplowanalytics.com/ -// Submitted by Ian Streeter -try-snowplow.com - -// Software Consulting Michal Zalewski : https://www.mafelo.com -// Submitted by Michal Zalewski -mafelo.net - -// Sony Interactive Entertainment LLC : https://sie.com/ -// Submitted by David Coles -playstation-cloud.com - -// SourceHut : https://sourcehut.org -// Submitted by Drew DeVault -srht.site - -// SourceLair PC : https://www.sourcelair.com -// Submitted by Antonis Kalipetis -apps.lair.io -*.stolos.io - -// sourceWAY GmbH : https://sourceway.de -// Submitted by Richard Reiber -4.at -my.at -my.de -*.nxa.eu -nx.gw - -// SpeedPartner GmbH : https://www.speedpartner.de/ -// Submitted by Stefan Neufeind -customer.speedpartner.de - -// Spreadshop (sprd.net AG) : https://www.spreadshop.com/ -// Submitted by Martin Breest -myspreadshop.at -myspreadshop.com.au -myspreadshop.be -myspreadshop.ca -myspreadshop.ch -myspreadshop.com -myspreadshop.de -myspreadshop.dk -myspreadshop.es -myspreadshop.fi -myspreadshop.fr -myspreadshop.ie -myspreadshop.it -myspreadshop.net -myspreadshop.nl -myspreadshop.no -myspreadshop.pl -myspreadshop.se -myspreadshop.co.uk - -// StackBlitz : https://stackblitz.com -// Submitted by Dominic Elm & Albert Pai -w-corp-staticblitz.com -w-credentialless-staticblitz.com -w-staticblitz.com -bolt.host - -// Stackhero : https://www.stackhero.io -// Submitted by Adrien Gillon -stackhero-network.com - -// STACKIT GmbH & Co. KG : https://www.stackit.de/en/ -// Submitted by STACKIT-DNS Team (Simon Stier) -runs.onstackit.cloud -stackit.gg -stackit.rocks -stackit.run -stackit.zone - -// Staclar : https://staclar.com -// Submitted by Q Misell -// Submitted by Matthias Merkel -musician.io -novecore.site - -// Standard Library : https://stdlib.com -// Submitted by Jacob Lee -api.stdlib.com - -// statichost.eu : https://www.statichost.eu -// Submitted by Eric Selin -statichost.page - -// stereosense GmbH : https://www.involve.me -// Submitted by Florian Burmann -feedback.ac -forms.ac -assessments.cx -calculators.cx -funnels.cx -paynow.cx -quizzes.cx -researched.cx -tests.cx -surveys.so - -// Storacha Network : https://storacha.network -// Submitted by Alan Shaw -ipfs.storacha.link -ipfs.w3s.link - -// Storebase : https://www.storebase.io -// Submitted by Tony Schirmer -storebase.store - -// Storipress : https://storipress.com -// Submitted by Benno Liu -storipress.app - -// Storj Labs Inc. : https://storj.io/ -// Submitted by Philip Hutchins -storj.farm - -// Strapi : https://strapi.io/ -// Submitted by Florent Baldino -strapiapp.com -media.strapiapp.com - -// Strategic System Consulting (eApps Hosting) : https://www.eapps.com/ -// Submitted by Alex Oancea -vps-host.net -atl.jelastic.vps-host.net -njs.jelastic.vps-host.net -ric.jelastic.vps-host.net - -// Streak : https://streak.com -// Submitted by Blake Kadatz -streak-link.com -streaklinks.com -streakusercontent.com - -// Student-Run Computing Facility : https://www.srcf.net/ -// Submitted by Edwin Balani -soc.srcf.net -user.srcf.net - -// Studenten Net Twente : http://www.snt.utwente.nl/ -// Submitted by Silke Hofstra -utwente.io - -// Sub 6 Limited : http://www.sub6.com -// Submitted by Dan Miller -temp-dns.com - -// Supabase : https://supabase.io -// Submitted by Supabase Security -supabase.co -realtime.supabase.co -storage.supabase.co -supabase.in -supabase.net - -// Syncloud : https://syncloud.org -// Submitted by Boris Rybalkin -syncloud.it - -// Synology, Inc. : https://www.synology.com/ -// Submitted by Rony Weng -dscloud.biz -direct.quickconnect.cn -dsmynas.com -familyds.com -diskstation.me -dscloud.me -i234.me -myds.me -synology.me -dscloud.mobi -dsmynas.net -familyds.net -dsmynas.org -familyds.org -direct.quickconnect.to -vpnplus.to - -// Tabit Technologies Ltd. : https://tabit.cloud/ -// Submitted by Oren Agiv -mytabit.com -mytabit.co.il -tabitorder.co.il - -// TAIFUN Software AG : http://taifun-software.de -// Submitted by Bjoern Henke -taifun-dns.de - -// Tailor Inc. : https://www.tailor.tech -// Submitted by Ryuzo Yamamoto -erp.dev -web.erp.dev - -// Tailscale Inc. : https://www.tailscale.com -// Submitted by David Anderson -ts.net -*.c.ts.net - -// TASK geographical domains : https://task.gda.pl/en/services/for-entrepreneurs/ -gda.pl -gdansk.pl -gdynia.pl -med.pl -sopot.pl - -// Tave Creative Corp : https://tave.com/ -// Submitted by Adrian Ziemkowski -taveusercontent.com - -// tawk.to, Inc : https://www.tawk.to -// Submitted by tawk.to developer team -p.tawk.email -p.tawkto.email - -// Tche.br : https://tche.br -// Submitted by Bruno Lorensi -tche.br - -// team.blue : https://team.blue -// Submitted by Cedric Dubois -site.tb-hosting.com -directwp.eu - -// Teckids e.V. : https://www.teckids.org -// Submitted by Dominik George -edugit.io -s3.teckids.org - -// Telebit : https://telebit.cloud -// Submitted by AJ ONeal -telebit.app -telebit.io -*.telebit.xyz - -// Teleport : https://goteleport.com -// Submitted by Rob Picard -teleport.sh - -// Thingdust AG : https://thingdust.com/ -// Submitted by Adrian Imboden -*.firenet.ch -*.svc.firenet.ch -reservd.com -thingdustdata.com -cust.dev.thingdust.io -reservd.dev.thingdust.io -cust.disrec.thingdust.io -reservd.disrec.thingdust.io -cust.prod.thingdust.io -cust.testing.thingdust.io -reservd.testing.thingdust.io - -// ticket i/O GmbH : https://ticket.io -// Submitted by Christian Franke -tickets.io - -// Tlon.io : https://tlon.io -// Submitted by Mark Staarink -arvo.network -azimuth.network -tlon.network - -// Tor Project, Inc. : https://torproject.org -// Submitted by Antoine Beaupré -torproject.net -pages.torproject.net - -// TownNews.com : http://www.townnews.com -// Submitted by Dustin Ward -townnews-staging.com - -// TrafficPlex GmbH : https://www.trafficplex.de/ -// Submitted by Phillipp Röll -12hp.at -2ix.at -4lima.at -lima-city.at -12hp.ch -2ix.ch -4lima.ch -lima-city.ch -trafficplex.cloud -de.cool -12hp.de -2ix.de -4lima.de -lima-city.de -1337.pictures -clan.rip -lima-city.rocks -webspace.rocks -lima.zone - -// TransIP : https://www.transip.nl -// Submitted by Rory Breuk and Cedric Dubois -*.transurl.be -*.transurl.eu -site.transip.me -*.transurl.nl - -// Tunnelmole: https://tunnelmole.com -// Submitted by Robbie Cahill -tunnelmole.net - -// TuxFamily : http://tuxfamily.org -// Submitted by TuxFamily administrators -tuxfamily.org - -// TwoDNS : https://www.twodns.de/ -// Submitted by TwoDNS-Support -dd-dns.de -dray-dns.de -draydns.de -dyn-vpn.de -dynvpn.de -mein-vigor.de -my-vigor.de -my-wan.de -syno-ds.de -synology-diskstation.de -synology-ds.de -diskstation.eu -diskstation.org - -// Typedream : https://typedream.com -// Submitted by Putri Karunia -typedream.app - -// Typeform : https://www.typeform.com -// Submitted by Typeform -pro.typeform.com - -// Uberspace : https://uberspace.de -// Submitted by Moritz Werner -uber.space - -// UDR Limited : http://www.udr.hk.com -// Submitted by registry -hk.com -inc.hk -ltd.hk -hk.org - -// UK Intis Telecom LTD : https://it.com -// Submitted by ITComdomains -it.com - -// Umso Software Inc. : https://www.umso.com -// Submitted by Alexis Taylor -umso.co - -// Unison Computing, PBC : https://unison.cloud -// Submitted by Simon Højberg -unison-services.cloud - -// United Gameserver GmbH : https://united-gameserver.de -// Submitted by Stefan Schwarz -virtual-user.de -virtualuser.de - -// United States Writing Corporation : https://uswriting.co -// Submitted by Andrew Sampson -obj.ag - -// UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ -// see also: whois -h whois.udr.org.yt help -// Submitted by Atanunu Igbunuroghene -name.pm -sch.tf -biz.wf -sch.wf -org.yt - -// University of Banja Luka : https://unibl.org -// Domains for Republic of Srpska administrative entity. -// Submitted by Marko Ivanovic -rs.ba - -// University of Bielsko-Biala regional domain : http://dns.bielsko.pl/ -// Submitted by Marcin -bielsko.pl - -// urown.net : https://urown.net -// Submitted by Hostmaster -urown.cloud -dnsupdate.info - -// US REGISTRY LLC : http://us.org -// Submitted by Gavin Brown -us.org - -// V.UA Domain Registry: https://www.v.ua/ -// Submitted by Serhii Rostilo -v.ua - -// Val Town, Inc : https://val.town/ -// Submitted by Tom MacWright -val.run -web.val.run - -// Vercel, Inc : https://vercel.com/ -// Submitted by Laurens Duijvesteijn -vercel.app -v0.build -vercel.dev -vusercontent.net -vercel.run -now.sh - -// VeryPositive SIA : http://very.lv -// Submitted by Danko Aleksejevs -2038.io - -// Virtual-Info : https://www.virtual-info.info/ -// Submitted by Adnan RIHAN -v-info.info - -// VistaBlog : https://vistablog.ir/ -// Submitted by Hossein Piri -vistablog.ir - -// Viva Republica, Inc. : https://toss.im/ -// Submitted by Deus Team -deus-canvas.com - -// Voorloper.com : https://voorloper.com -// Submitted by Nathan van Bakel -voorloper.cloud - -// Vultr Objects : https://www.vultr.com/products/object-storage/ -// Submitted by Niels Maumenee -*.vultrobjects.com - -// Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com -// Submitted by Masayuki Note -wafflecell.com - -// Walrus : https://walrus.xyz -// Submitted by Max Spector -wal.app - -// Wasmer: https://wasmer.io -// Submitted by Lorentz Kinde -wasmer.app - -// Webflow, Inc. : https://www.webflow.com -// Submitted by Webflow Security Team -webflow.io -webflowtest.io - -// WebHare bv : https://www.webhare.com/ -// Submitted by Arnold Hendriks -*.webhare.dev - -// WebHotelier Technologies Ltd : https://www.webhotelier.net/ -// Submitted by Apostolos Tsakpinis -bookonline.app -hotelwithflight.com -reserve-online.com -reserve-online.net - -// WebPros International, LLC : https://webpros.com/ -// Submitted by Nicolas Rochelemagne -cprapid.com -pleskns.com -wp2.host -pdns.page -plesk.page -cpanel.site -wpsquared.site - -// WebWaddle Ltd : https://webwaddle.com/ -// Submitted by Merlin Glander -*.wadl.top - -// Western Digital Technologies, Inc : https://www.wdc.com -// Submitted by Jung Jin -remotewd.com - -// Whatbox Inc. : https://whatbox.ca/ -// Submitted by Anthony Ryan -box.ca - -// WIARD Enterprises : https://wiardweb.com -// Submitted by Kidd Hustle -pages.wiardweb.com - -// Wikimedia Foundation : https://wikitech.wikimedia.org -// Submitted by Timo Tijhof -toolforge.org -wmcloud.org -beta.wmcloud.org -wmflabs.org - -// William Harrison : https://wharrison.com.au -// Submitted by William Harrison -wdh.app -hrsn.au -vps.hrsn.au -hrsn.dev -is-a.dev -localcert.net - -// Windsurf : https://windsurf.com -// Submitted by Douglas Chen -windsurf.app -windsurf.build - -// WISP : https://wisp.gg -// Submitted by Stepan Fedotov -panel.gg -daemon.panel.gg - -// Wix.com, Inc. : https://www.wix.com -// Submitted by Shahar Talmi / Alon Kochba -wixsite.com -wixstudio.com -editorx.io -wixstudio.io -wix.run - -// Wizard Zines : https://wizardzines.com -// Submitted by Julia Evans -messwithdns.com - -// WoltLab GmbH : https://www.woltlab.com -// Submitted by Tim Düsterhus -woltlab-demo.com -myforum.community -community-pro.de -diskussionsbereich.de -community-pro.net -meinforum.net - -// Woods Valldata : https://www.woodsvalldata.co.uk/ -// Submitted by Chris Whittle -affinitylottery.org.uk -raffleentry.org.uk -weeklylottery.org.uk - -// WP Engine : https://wpengine.com/ -// Submitted by Michael Smith -// Submitted by Brandon DuRette -wpenginepowered.com -js.wpenginepowered.com - -// XenonCloud GbR : https://xenoncloud.net -// Submitted by Julian Uphoff -*.xenonconnect.de -half.host - -// XnBay Technology : http://www.xnbay.com/ -// Submitted by XnBay Developer -xnbay.com -u2.xnbay.com -u2-local.xnbay.com - -// XS4ALL Internet bv : https://www.xs4all.nl/ -// Submitted by Daniel Mostertman -cistron.nl -demon.nl -xs4all.space - -// Yandex.Cloud LLC : https://cloud.yandex.com -// Submitted by Alexander Lodin -yandexcloud.net -storage.yandexcloud.net -website.yandexcloud.net -sourcecraft.site - -// YesCourse Pty Ltd : https://yescourse.com -// Submitted by Atul Bhouraskar -official.academy - -// Yola : https://www.yola.com/ -// Submitted by Stefano Rivera -yolasite.com - -// Yunohost : https://yunohost.org -// Submitted by Valentin Grimaud -ynh.fr -nohost.me -noho.st - -// ZaNiC : http://www.za.net/ -// Submitted by registry -za.net -za.org - -// ZAP-Hosting GmbH & Co. KG : https://zap-hosting.com -// Submitted by Julian Alker -zap.cloud - -// Zeabur : https://zeabur.com/ -// Submitted by Zeabur Team -zeabur.app - -// Zerops : https://zerops.io/ -// Submitted by Zerops Team -*.zerops.app - -// Zine EOOD : https://zine.bg/ -// Submitted by Martin Angelov -bss.design - -// Zitcom A/S : https://www.zitcom.dk -// Submitted by Emil Stahl -basicserver.io -virtualserver.io -enterprisecloud.nu - -// Zone.ID: https://zone.id -// Submitted by Gx1.org -zone.id - -// ZoneABC : https://zoneabc.net -// Submitted by ZoneABC Team -zabc.net - -// ===END PRIVATE DOMAINS=== diff --git a/vendor/libpsl/src/lookup_string_in_fixed_set.c b/vendor/libpsl/src/lookup_string_in_fixed_set.c deleted file mode 100644 index 57c2e4ea1..000000000 --- a/vendor/libpsl/src/lookup_string_in_fixed_set.c +++ /dev/null @@ -1,273 +0,0 @@ -/* Copyright 2015-2016 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE.chromium file. - * - * Converted to C89 2015 by Tim Rühsen - */ - -#include - -#define CHECK_LT(a, b) if ((a) >= b) return 0 - -static const char multibyte_length_table[16] = { - 0, 0, 0, 0, /* 0x00-0x3F */ - 0, 0, 0, 0, /* 0x40-0x7F */ - 0, 0, 0, 0, /* 0x80-0xBF */ - 2, 2, 3, 4, /* 0xC0-0xFF */ -}; - - -/* - * Get length of multibyte character sequence starting at a given byte. - * Returns zero if the byte is not a valid leading byte in UTF-8. - */ -static int GetMultibyteLength(char c) { - return multibyte_length_table[((unsigned char)c) >> 4]; -} - -/* - * Moves pointers one byte forward. - */ -static void NextPos(const unsigned char** pos, - const char** key, - const char** multibyte_start) -{ - ++*pos; - if (*multibyte_start) { - /* Advance key to next byte in multibyte sequence. */ - ++*key; - /* Reset multibyte_start if last byte in multibyte sequence was consumed. */ - if (*key - *multibyte_start == GetMultibyteLength(**multibyte_start)) - *multibyte_start = 0; - } else { - if (GetMultibyteLength(**key)) { - /* Multibyte prefix was matched in the dafsa, start matching multibyte - * content in next round. */ - *multibyte_start = *key; - } else { - /* Advance key as a single byte character was matched. */ - ++*key; - } - } -} - -/* - * Read next offset from pos. - * Returns true if an offset could be read, false otherwise. - */ - -static int GetNextOffset(const unsigned char** pos, - const unsigned char* end, - const unsigned char** offset) -{ - size_t bytes_consumed; - - if (*pos == end) - return 0; - - /* When reading an offset the byte array must always contain at least - * three more bytes to consume. First the offset to read, then a node - * to skip over and finally a destination node. No object can be smaller - * than one byte. */ - CHECK_LT(*pos + 2, end); - switch (**pos & 0x60) { - case 0x60: /* Read three byte offset */ - *offset += (((*pos)[0] & 0x1F) << 16) | ((*pos)[1] << 8) | (*pos)[2]; - bytes_consumed = 3; - break; - case 0x40: /* Read two byte offset */ - *offset += (((*pos)[0] & 0x1F) << 8) | (*pos)[1]; - bytes_consumed = 2; - break; - default: - *offset += (*pos)[0] & 0x3F; - bytes_consumed = 1; - } - if ((**pos & 0x80) != 0) { - *pos = end; - } else { - *pos += bytes_consumed; - } - return 1; -} - -/* - * Check if byte at offset is last in label. - */ - -static int IsEOL(const unsigned char* offset, const unsigned char* end) -{ - CHECK_LT(offset, end); - return(*offset & 0x80) != 0; -} - -/* - * Check if byte at offset matches first character in key. - * This version assumes a range check was already performed by the caller. - */ - -static int IsMatchUnchecked(const unsigned char matcher, - const char* key, - const char* multibyte_start) -{ - if (multibyte_start) { - /* Multibyte matching mode. */ - if (multibyte_start == key) { - /* Match leading byte, which will also match the sequence length. */ - return (matcher ^ 0x80) == (const unsigned char)*key; - } else { - /* Match following bytes. */ - return (matcher ^ 0xC0) == (const unsigned char)*key; - } - } - /* If key points at a leading byte in a multibyte sequence, but we are not yet - * in multibyte mode, then the dafsa should contain a special byte to indicate - * a mode switch. */ - if (GetMultibyteLength(*key)) { - return matcher == 0x1F; - } - /* Normal matching of a single byte character. */ - return matcher == (const unsigned char)*key; -} - -/* - * Check if byte at offset matches first character in key. - * This version matches characters not last in label. - */ - -static int IsMatch(const unsigned char* offset, - const unsigned char* end, - const char* key, - const char* multibyte_start) -{ - CHECK_LT(offset, end); - return IsMatchUnchecked(*offset, key, multibyte_start); -} - -/* - * Check if byte at offset matches first character in key. - * This version matches characters last in label. - */ - -static int IsEndCharMatch(const unsigned char* offset, - const unsigned char* end, - const char* key, - const char* multibyte_start) -{ - CHECK_LT(offset, end); - return IsMatchUnchecked(*offset ^ 0x80, key, multibyte_start); -} - -/* - * Read return value at offset. - * Returns true if a return value could be read, false otherwise. - */ - -static int GetReturnValue(const unsigned char* offset, - const unsigned char* end, - const char* multibyte_start, - int* return_value) -{ - CHECK_LT(offset, end); - if (!multibyte_start && (*offset & 0xE0) == 0x80) { - *return_value = *offset & 0x0F; - return 1; - } - return 0; -} - -/* - * Looks up the string |key| with length |key_length| in a fixed set of - * strings. The set of strings must be known at compile time. It is converted to - * a graph structure named a DAFSA (Deterministic Acyclic Finite State - * Automaton) by the script psl-make-dafsa during compilation. This permits - * efficient (in time and space) lookup. The graph generated by psl-make-dafsa - * takes the form of a constant byte array which should be supplied via the - * |graph| and |length| parameters. The return value is kDafsaNotFound, - * kDafsaFound, or a bitmap consisting of one or more of kDafsaExceptionRule, - * kDafsaWildcardRule and kDafsaPrivateRule ORed together. - * - * Lookup a domain key in a byte array generated by psl-make-dafsa. - */ - -/* prototype to skip warning with -Wmissing-prototypes */ -int LookupStringInFixedSet(const unsigned char*, size_t,const char*, size_t); - -int LookupStringInFixedSet(const unsigned char* graph, - size_t length, - const char* key, - size_t key_length) -{ - const unsigned char* pos = graph; - const unsigned char* end = graph + length; - const unsigned char* offset = pos; - const char* key_end = key + key_length; - const char* multibyte_start = 0; - - while (GetNextOffset(&pos, end, &offset)) { - /*char + end_char offsets - * char + return value - * char end_char offsets - * char return value - * end_char offsets - * return_value - */ - int did_consume = 0; - - if (key != key_end && !IsEOL(offset, end)) { - /* Leading is not a match. Don't dive into this child */ - if (!IsMatch(offset, end, key, multibyte_start)) - continue; - did_consume = 1; - NextPos(&offset, &key, &multibyte_start); - /* Possible matches at this point: - * + end_char offsets - * + return value - * end_char offsets - * return value - */ - - /* Remove all remaining nodes possible */ - while (!IsEOL(offset, end) && key != key_end) { - if (!IsMatch(offset, end, key, multibyte_start)) - return -1; - NextPos(&offset, &key, &multibyte_start); - } - } - /* Possible matches at this point: - * end_char offsets - * return_value - * If one or more elements were consumed, a failure - * to match is terminal. Otherwise, try the next node. - */ - if (key == key_end) { - int return_value; - - if (GetReturnValue(offset, end, multibyte_start, &return_value)) - return return_value; - /* The DAFSA guarantees that if the first char is a match, all - * remaining char elements MUST match if the key is truly present. - */ - if (did_consume) - return -1; - continue; - } - if (!IsEndCharMatch(offset, end, key, multibyte_start)) { - if (did_consume) - return -1; /* Unexpected */ - continue; - } - NextPos(&offset, &key, &multibyte_start); - pos = offset; /* Dive into child */ - } - - return -1; /* No match */ -} - -/* prototype to skip warning with -Wmissing-prototypes */ -int GetUtfMode(const unsigned char *graph, size_t length); - -int GetUtfMode(const unsigned char *graph, size_t length) -{ - return length > 0 && graph[length - 1] < 0x80; -} diff --git a/vendor/libpsl/src/psl.c b/vendor/libpsl/src/psl.c deleted file mode 100644 index 4c5c95e4d..000000000 --- a/vendor/libpsl/src/psl.c +++ /dev/null @@ -1,1964 +0,0 @@ -/* - * Copyright(c) 2014-2024 Tim Ruehsen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of libpsl. - * - * Public Suffix List routines - * - * Changelog - * 19.03.2014 Tim Ruehsen created from libmget/cookie.c - * - */ - -#if HAVE_CONFIG_H -# include -#endif - -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -# define GCC_VERSION_AT_LEAST(major, minor) ((__GNUC__ > (major)) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) -#else -# define GCC_VERSION_AT_LEAST(major, minor) 0 -#endif - -#if GCC_VERSION_AT_LEAST(2,95) -# define PSL_UNUSED __attribute__ ((unused)) -#else -# define PSL_UNUSED -#endif - -#include -#include - -#ifdef _WIN32 -# include -# include -#else -# include -# include -# include -#endif - -#if defined(_MSC_VER) && ! defined(ssize_t) -# include -typedef SSIZE_T ssize_t; -#endif - -#include -#include -#include -#ifdef HAVE_STRINGS_H -# include -#endif -#include -#include -#include -#include /* for UINT_MAX */ - -#ifdef HAVE_NL_LANGINFO -# include -#endif - -#ifndef _WIN32 -# include -#endif - -#ifdef HAVE_ALLOCA_H -# include -#elif defined _WIN32 -# include -#endif - -#ifdef WITH_LIBICU -# include -# include -# include -# include -#elif defined(WITH_LIBIDN2) -# include -# include -# include -# include -#elif defined(WITH_LIBIDN) -# include -# include -# include -# include -# include -#endif - -#ifdef WINICONV_CONST -# define ICONV_CONST WINICONV_CONST -#endif -#ifndef ICONV_CONST -# define ICONV_CONST -#endif - - -#include - -/** - * SECTION:libpsl - * @short_description: Public Suffix List library functions - * @title: libpsl - * @stability: Stable - * @include: libpsl.h - * - * [Public Suffix List](https://publicsuffix.org/) library functions. - * - */ - -#define countof(a) (sizeof(a)/sizeof(*(a))) - -#define PRIV_PSL_FLAG_EXCEPTION (1<<0) -#define PRIV_PSL_FLAG_WILDCARD (1<<1) -#define PRIV_PSL_FLAG_ICANN (1<<2) /* entry of ICANN section */ -#define PRIV_PSL_FLAG_PRIVATE (1<<3) /* entry of PRIVATE section */ -#define PRIV_PSL_FLAG_PLAIN (1<<4) /* just used for PSL syntax checking */ - -typedef struct { - char - label_buf[128]; - const char * - label; - unsigned short - length; - unsigned char - nlabels, /* number of labels */ - flags; -} psl_entry_t; - -/* stripped down version libmget vector routines */ -typedef struct { - int - (*cmp)(const psl_entry_t **, const psl_entry_t **); /* comparison function */ - psl_entry_t - **entry; /* pointer to array of pointers to elements */ - int - max, /* allocated elements */ - cur; /* number of elements in use */ -} psl_vector_t; - -struct psl_ctx_st { - psl_vector_t - *suffixes; - unsigned char - *dafsa; - size_t - dafsa_size; - int - nsuffixes, - nexceptions, - nwildcards; - unsigned - utf8 : 1; /* 1: data contains UTF-8 + punycode encoded rules */ -}; - -/* include the PSL data generated by psl-make-dafsa */ -#ifdef ENABLE_BUILTIN -#include "suffixes_dafsa.h" -#else -static const unsigned char kDafsa[] = ""; -static time_t _psl_file_time = 0; -static int _psl_nsuffixes = 0; -static int _psl_nexceptions = 0; -static int _psl_nwildcards = 0; -static const char _psl_sha1_checksum[] = ""; -static const char _psl_filename[] = ""; -#endif - -/* references to these PSLs will result in lookups to built-in data */ -static const psl_ctx_t - builtin_psl; - -#ifdef PSL_DISTFILE -static const char _psl_dist_filename[] = PSL_DISTFILE; -#else -static const char _psl_dist_filename[] = ""; -#endif - -static psl_vector_t *vector_alloc(int max, int (*cmp)(const psl_entry_t **, const psl_entry_t **)) -{ - psl_vector_t *v; - - if (!(v = calloc(1, sizeof(psl_vector_t)))) - return NULL; - - if (!(v->entry = malloc(max * sizeof(psl_entry_t *)))) { - free(v); - return NULL; - } - - v->max = max; - v->cmp = cmp; - return v; -} - -static void vector_free(psl_vector_t **v) -{ - if (v && *v) { - if ((*v)->entry) { - int it; - - for (it = 0; it < (*v)->cur; it++) - free((*v)->entry[it]); - - free((*v)->entry); - } - free(*v); - } -} - -static psl_entry_t *vector_get(const psl_vector_t *v, int pos) -{ - if (pos < 0 || !v || pos >= v->cur) return NULL; - - return v->entry[pos]; -} - -/* the entries must be sorted by */ -static int vector_find(const psl_vector_t *v, const psl_entry_t *elem) -{ - if (v) { - int l, r, m; - int res; - - /* binary search for element (exact match) */ - for (l = 0, r = v->cur - 1; l <= r;) { - m = (l + r) / 2; - if ((res = v->cmp(&elem, (const psl_entry_t **)&(v->entry[m]))) > 0) l = m + 1; - else if (res < 0) r = m - 1; - else return m; - } - } - - return -1; /* not found */ -} - -static int vector_add(psl_vector_t *v, const psl_entry_t *elem) -{ - if (v) { - void *elemp; - - if (!(elemp = malloc(sizeof(psl_entry_t)))) - return -1; - - memcpy(elemp, elem, sizeof(psl_entry_t)); - - if (v->max == v->cur) { - void *m = realloc(v->entry, (v->max *= 2) * sizeof(psl_entry_t *)); - - if (m) - v->entry = m; - else { - free(elemp); - return -1; - } - } - - v->entry[v->cur++] = elemp; - return v->cur - 1; - } - - return -1; -} - -static void vector_sort(psl_vector_t *v) -{ - if (v && v->cmp) - qsort(v->entry, v->cur, sizeof(psl_vector_t **), (int(*)(const void *, const void *))v->cmp); -} - -/* by this kind of sorting, we can easily see if a domain matches or not */ -static int suffix_compare(const psl_entry_t *s1, const psl_entry_t *s2) -{ - int n; - - if ((n = s2->nlabels - s1->nlabels)) - return n; /* most labels first */ - - if ((n = s1->length - s2->length)) - return n; /* shorter rules first */ - - return strcmp(s1->label ? s1->label : s1->label_buf, s2->label ? s2->label : s2->label_buf); -} - -/* needed to sort array of pointers, given to qsort() */ -static int suffix_compare_array(const psl_entry_t **s1, const psl_entry_t **s2) -{ - return suffix_compare(*s1, *s2); -} - -static int suffix_init(psl_entry_t *suffix, const char *rule, size_t length) -{ - const char *src; - char *dst; - - suffix->label = suffix->label_buf; - - if (length >= sizeof(suffix->label_buf) - 1) { - suffix->nlabels = 0; - /* fprintf(stderr, "Suffix rule too long (%zd, ignored): %s\n", length, rule); */ - return -1; - } - - suffix->length = (unsigned char)length; - - suffix->nlabels = 1; - - for (dst = suffix->label_buf, src = rule; *src;) { - if (*src == '.') - suffix->nlabels++; - *dst++ = *src++; - } - *dst = 0; - - return 0; -} - -#if !defined(WITH_LIBIDN) && !defined(WITH_LIBIDN2) && !defined(WITH_LIBICU) -/* - * When configured without runtime IDNA support (./configure --disable-runtime), we need a pure ASCII - * representation of non-ASCII characters in labels as found in UTF-8 domain names. - * This is because the current DAFSA format used may only hold character values [21..127]. - * - Code copied from http://www.nicemice.net/idn/punycode-spec.gz on - 2011-01-04 with SHA-1 a966a8017f6be579d74a50a226accc7607c40133 - labeled punycode-spec 1.0.3 (2006-Mar-24-Thu). It is modified for - libpsl by Tim Rühsen. License on the original code: - - punycode-spec 1.0.3 (2006-Mar-23-Thu) - http://www.nicemice.net/idn/ - Adam M. Costello - http://www.nicemice.net/amc/ - - B. Disclaimer and license - - Regarding this entire document or any portion of it (including - the pseudocode and C code), the author makes no guarantees and - is not responsible for any damage resulting from its use. The - author grants irrevocable permission to anyone to use, modify, - and distribute it in any way that does not diminish the rights - of anyone else to use, modify, and distribute it, provided that - redistributed derivative works do not contain misleading author or - version information. Derivative works need not be licensed under - similar terms. - - C. Punycode sample implementation - - punycode-sample.c 2.0.0 (2004-Mar-21-Sun) - http://www.nicemice.net/idn/ - Adam M. Costello - http://www.nicemice.net/amc/ - - This is ANSI C code (C89) implementing Punycode 1.0.x. - */ -enum punycode_status { - punycode_success = 0, - punycode_bad_input = 1, /* Input is invalid. */ - punycode_big_output = 2, /* Output would exceed the space provided. */ - punycode_overflow = 3 /* Wider integers needed to process input. */ -}; - -#ifdef PUNYCODE_UINT - typedef PUNYCODE_UINT punycode_uint; -#elif UINT_MAX >= (1 << 26) - 1 - typedef unsigned int punycode_uint; -#else - typedef unsigned long punycode_uint; -#endif - -/*** Bootstring parameters for Punycode ***/ -enum { - base = 36, tmin = 1, tmax = 26, skew = 38, damp = 700, - initial_bias = 72, initial_n = 0x80, delimiter = 0x2D -}; - -static char encode_digit(punycode_uint d) -{ - return d + 22 + 75 * (d < 26); - /* 0..25 map to ASCII a..z or A..Z */ - /* 26..35 map to ASCII 0..9 */ -} -#define flagged(bcp) ((punycode_uint)(bcp) - 65 < 26) -static const punycode_uint maxint = -1; - -static punycode_uint adapt(punycode_uint delta, punycode_uint numpoints, int firsttime) -{ - punycode_uint k; - - delta = firsttime ? delta / damp : delta >> 1; - /* delta >> 1 is a faster way of doing delta / 2 */ - delta += delta / numpoints; - - for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base) { - delta /= base - tmin; - } - - return k + (base - tmin + 1) * delta / (delta + skew); -} - -static enum punycode_status punycode_encode( - size_t input_length_orig, - const punycode_uint input[], - size_t *output_length, - char output[]) -{ - punycode_uint input_length, n, delta, h, b, bias, j, m, q, k, t; - size_t out, max_out; - - /* The Punycode spec assumes that the input length is the same type */ - /* of integer as a code point, so we need to convert the size_t to */ - /* a punycode_uint, which could overflow. */ - - if (input_length_orig > maxint) - return punycode_overflow; - - input_length = (punycode_uint) input_length_orig; - - /* Initialize the state: */ - - n = initial_n; - delta = 0; - out = 0; - max_out = *output_length; - bias = initial_bias; - - /* Handle the basic code points: */ - for (j = 0; j < input_length; ++j) { - if (input[j] < 0x80) { - if (max_out - out < 2) - return punycode_big_output; - output[out++] = (char) input[j]; - } - /* else if (input[j] < n) return punycode_bad_input; */ - /* (not needed for Punycode with unsigned code points) */ - } - - h = b = (punycode_uint) out; - /* cannot overflow because out <= input_length <= maxint */ - - /* h is the number of code points that have been handled, b is the */ - /* number of basic code points, and out is the number of ASCII code */ - /* points that have been output. */ - - if (b > 0) - output[out++] = delimiter; - - /* Main encoding loop: */ - - while (h < input_length) { - /* All non-basic code points < n have been */ - /* handled already. Find the next larger one: */ - - for (m = maxint, j = 0; j < input_length; ++j) { - /* if (basic(input[j])) continue; */ - /* (not needed for Punycode) */ - if (input[j] >= n && input[j] < m) - m = input[j]; - } - - /* Increase delta enough to advance the decoder's */ - /* state to , but guard against overflow: */ - - if (m - n > (maxint - delta) / (h + 1)) - return punycode_overflow; - delta += (m - n) * (h + 1); - n = m; - - for (j = 0; j < input_length; ++j) { - /* Punycode does not need to check whether input[j] is basic: */ - if (input[j] < n /* || basic(input[j]) */) { - if (++delta == 0) - return punycode_overflow; - } - - if (input[j] == n) { - /* Represent delta as a generalized variable-length integer: */ - - for (q = delta, k = base;; k += base) { - if (out >= max_out) - return punycode_big_output; - t = k <= bias /* + tmin */ ? tmin : /* +tmin not needed */ - k >= bias + tmax ? tmax : k - bias; - if (q < t) - break; - output[out++] = encode_digit(t + (q - t) % (base - t)); - q = (q - t) / (base - t); - } - - output[out++] = encode_digit(q); - bias = adapt(delta, h + 1, h == b); - delta = 0; - ++h; - } - } - - ++delta, ++n; - } - - *output_length = out; - return punycode_success; -} - -static ssize_t utf8_to_utf32(const char *in, size_t inlen, punycode_uint *out, size_t outlen) -{ - size_t n = 0; - const unsigned char *s = (void *)in; - const unsigned char *e = (void *)(in + inlen); - - if (!outlen) - return -1; - - outlen--; - - while (n < outlen) { - size_t inleft = e - s; - - if (inleft >= 1 && (*s & 0x80) == 0) { /* 0xxxxxxx ASCII char */ - out[n++] = *s; - s++; - } else if (inleft >= 2 && (*s & 0xE0) == 0xC0) /* 110xxxxx 10xxxxxx */ { - if ((s[1] & 0xC0) != 0x80) - return -1; - out[n++] = ((*s & 0x1F) << 6) | (s[1] & 0x3F); - s += 2; - } else if (inleft >= 3 && (*s & 0xF0) == 0xE0) /* 1110xxxx 10xxxxxx 10xxxxxx */ { - if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80) - return -1; - out[n++] = ((*s & 0x0F) << 12) | ((s[1] & 0x3F) << 6) | (s[2] & 0x3F); - s += 3; - } else if (inleft >= 4 && (*s & 0xF8) == 0xF0) /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ { - if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80 || (s[3] & 0xC0) != 0x80) - return -1; - out[n++] = ((*s & 0x07) << 18) | ((s[1] & 0x3F) << 12) | ((s[1] & 0x3F) << 6) | (s[2] & 0x3F); - s += 4; - } else if (!inleft) { - break; - } else - return -1; - } - - return n; -} - -static int mem_is_ascii(const char *s, size_t n) -{ - for (; n; n--) /* 'while(n--)' generates unsigned integer overflow on n = 0 */ - if (*((unsigned char *)s++) >= 128) - return 0; - - return 1; -} - -static int domain_to_punycode(const char *domain, char *out, size_t outsize) -{ - size_t outlen = 0, labellen; - punycode_uint input[256]; - const char *label, *e; - - for (e = label = domain; e;) { - e = strchr(label, '.'); - labellen = e ? (size_t) (e - label) : strlen(label); - - if (mem_is_ascii(label, labellen)) { - if (outlen + labellen + (e != NULL) >= outsize) - return 1; - - memcpy(out + outlen, label, labellen); - outlen += labellen; - } else { - ssize_t inputlen = 0; - - if (outlen + labellen + (e != NULL) + 4 >= outsize) - return 1; - - if ((inputlen = utf8_to_utf32(label, labellen, input, countof(input))) < 0) - return 1; - - memcpy(out + outlen, "xn--", 4); - outlen += 4; - - labellen = outsize - outlen - (e != NULL) - 1; // -1 to leave space for the trailing \0 - if (punycode_encode(inputlen, input, &labellen, out + outlen)) - return 1; - outlen += labellen; - } - - if (e) { - label = e + 1; - out[outlen++] = '.'; - } - out[outlen] = 0; - } - - return 0; -} -#endif - -static int isspace_ascii(const char c) -{ - return c == ' ' || c == '\t' || c == '\r' || c == '\n'; -} - -static int str_is_ascii(const char *s) -{ - while (*s && *((unsigned char *)s) < 128) s++; - - return !*s; -} - -#if defined(WITH_LIBIDN) -/* - * Work around a libidn <= 1.30 vulnerability. - * - * The function checks for a valid UTF-8 character sequence before - * passing it to idna_to_ascii_8z(). - * - * [1] https://lists.gnu.org/archive/html/help-libidn/2015-05/msg00002.html - * [2] https://lists.gnu.org/archive/html/bug-wget/2015-06/msg00002.html - * [3] https://curl.haxx.se/mail/lib-2015-06/0143.html - */ -static int utf8_is_valid(const char *utf8) -{ - const unsigned char *s = (const unsigned char *) utf8; - - while (*s) { - if ((*s & 0x80) == 0) /* 0xxxxxxx ASCII char */ - s++; - else if ((*s & 0xE0) == 0xC0) /* 110xxxxx 10xxxxxx */ { - if ((s[1] & 0xC0) != 0x80) - return 0; - s += 2; - } else if ((*s & 0xF0) == 0xE0) /* 1110xxxx 10xxxxxx 10xxxxxx */ { - if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80) - return 0; - s += 3; - } else if ((*s & 0xF8) == 0xF0) /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ { - if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80 || (s[3] & 0xC0) != 0x80) - return 0; - s += 4; - } else - return 0; - } - - return 1; -} -#endif - -typedef void *psl_idna_t; - -static psl_idna_t *psl_idna_open(void) -{ -#if defined(WITH_LIBICU) - UErrorCode status = 0; - return (void *)uidna_openUTS46(UIDNA_USE_STD3_RULES | UIDNA_NONTRANSITIONAL_TO_ASCII, &status); -#endif - return NULL; -} - -static void psl_idna_close(psl_idna_t *idna PSL_UNUSED) -{ -#if defined(WITH_LIBICU) - if (idna) - uidna_close((UIDNA *)idna); -#endif -} - -static int psl_idna_toASCII(psl_idna_t *idna PSL_UNUSED, const char *utf8, char **ascii) -{ - int ret = -1; - -#if defined(WITH_LIBICU) - /* IDNA2008 UTS#46 punycode conversion */ - if (idna) { - char lookupname_buf[128] = "", *lookupname = lookupname_buf; - UErrorCode status = 0; - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - UChar utf16_dst[128], utf16_src_buf[128]; - UChar *utf16_src = utf16_src_buf; - int32_t utf16_src_length, bytes_written; - int32_t utf16_dst_length; - - u_strFromUTF8(utf16_src, countof(utf16_src_buf), &utf16_src_length, utf8, -1, &status); - if (!U_SUCCESS(status)) goto cleanup; /* UTF-8 to UTF-16 conversion failed */ - - if (utf16_src_length >= (int) countof(utf16_src_buf)) { - utf16_src = malloc((utf16_src_length + 1) * sizeof(UChar)); - if (!utf16_src) goto cleanup; - - u_strFromUTF8(utf16_src, utf16_src_length, NULL, utf8, -1, &status); - if (!U_SUCCESS(status)) goto cleanup; /* UTF-8 to UTF-16 conversion failed */ - - utf16_src[utf16_src_length] = 0; /* u_strFromUTF8() doesn't 0-terminate if dest is filled up */ - } - - utf16_dst_length = uidna_nameToASCII((UIDNA *)idna, utf16_src, utf16_src_length, utf16_dst, countof(utf16_dst), &info, &status); - if (!U_SUCCESS(status)) goto cleanup; /* to ASCII conversion failed */ - - u_strToUTF8(lookupname, sizeof(lookupname_buf), &bytes_written, utf16_dst, utf16_dst_length, &status); - if (!U_SUCCESS(status)) goto cleanup; /* UTF-16 to UTF-8 conversion failed */ - - if (bytes_written >= (int) sizeof(lookupname_buf)) { - lookupname = malloc(bytes_written + 1); - if (!lookupname) goto cleanup; - - u_strToUTF8(lookupname, bytes_written, NULL, utf16_dst, utf16_dst_length, &status); - if (!U_SUCCESS(status)) goto cleanup; /* UTF-16 to UTF-8 conversion failed */ - - lookupname[bytes_written] = 0; /* u_strToUTF8() doesn't 0-terminate if dest is filled up */ - } else { - if (!(lookupname = strdup(lookupname))) - goto cleanup; - } - - if (ascii) { - *ascii = lookupname; - lookupname = NULL; - } - - ret = 0; - -cleanup: - if (lookupname != lookupname_buf) - free(lookupname); - if (utf16_src != utf16_src_buf) - free(utf16_src); - } -#elif defined(WITH_LIBIDN2) -#if IDN2_VERSION_NUMBER >= 0x00140000 - int rc; - - /* IDN2_TRANSITIONAL automatically converts to lowercase - * IDN2_NFC_INPUT converts to NFC before toASCII conversion - * Since IDN2_TRANSITIONAL implicitly does NFC conversion, we don't need - * the additional IDN2_NFC_INPUT. But just for the unlikely case that the linked - * library is not matching the headers when building and it doesn't support TR46, - * we provide IDN2_NFC_INPUT. */ - - if ((rc = idn2_lookup_u8((uint8_t *)utf8, (uint8_t **)ascii, IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL)) == IDN2_OK) - ret = 0; - /* else - fprintf(stderr, "toASCII(%s) failed (%d): %s\n", lower, rc, idn2_strerror(rc)); */ -#else - int rc; - uint8_t *lower; - size_t len = u8_strlen((uint8_t *)utf8) + 1; - - /* we need a conversion to lowercase */ - if (!(lower = u8_tolower((uint8_t *)utf8, len, 0, UNINORM_NFKC, NULL, &len))) { - /* fprintf(stderr, "u8_tolower(%s) failed (%d)\n", utf8, errno); */ - return -1; - } - - if ((rc = idn2_lookup_u8(lower, (uint8_t **)ascii, 0)) == IDN2_OK) { - ret = 0; - } /* else - fprintf(stderr, "toASCII(%s) failed (%d): %s\n", lower, rc, idn2_strerror(rc)); */ - - free(lower); -#endif -#elif defined(WITH_LIBIDN) - int rc; - - if (!utf8_is_valid(utf8)) { - /* fprintf(stderr, "Invalid UTF-8 sequence not converted: '%s'\n", utf8); */ - return -1; - } - - /* idna_to_ascii_8z() automatically converts UTF-8 to lowercase */ - - if ((rc = idna_to_ascii_8z(utf8, ascii, IDNA_USE_STD3_ASCII_RULES)) == IDNA_SUCCESS) { - ret = 0; - } /* else - fprintf(stderr, "toASCII failed (%d): %s\n", rc, idna_strerror(rc)); */ -#else - char lookupname[128]; - - if (domain_to_punycode(utf8, lookupname, sizeof(lookupname)) == 0) { - if (ascii) - if ((*ascii = strdup(lookupname))) - ret = 0; - } -#endif - - return ret; -} - -static void add_punycode_if_needed(psl_idna_t *idna, psl_vector_t *v, psl_entry_t *e) -{ - char *lookupname; - - if (str_is_ascii(e->label_buf)) - return; - - if (psl_idna_toASCII(idna, e->label_buf, &lookupname) == 0) { - if (strcmp(e->label_buf, lookupname)) { - psl_entry_t suffix, *suffixp; - - /* fprintf(stderr, "toASCII '%s' -> '%s'\n", e->label_buf, lookupname); */ - if (suffix_init(&suffix, lookupname, strlen(lookupname)) == 0) { - suffix.flags = e->flags; - if ((suffixp = vector_get(v, vector_add(v, &suffix)))) - suffixp->label = suffixp->label_buf; /* set label to changed address */ - } - } /* else ignore */ - - free(lookupname); - } -} - -/* prototypes */ -int LookupStringInFixedSet(const unsigned char* graph, size_t length, const char* key, size_t key_length); -int GetUtfMode(const unsigned char *graph, size_t length); - -static int is_public_suffix(const psl_ctx_t *psl, const char *domain, int type) -{ - psl_entry_t suffix; - const char *p; - char *punycode = NULL; - int need_conversion = 0; - - /* this function should be called without leading dots, just make sure */ - if (*domain == '.') - domain++; - - suffix.nlabels = 1; - - for (p = domain; *p; p++) { - if (*p == '.') { - if (suffix.nlabels == 255) // weird input, avoid 8bit overflow - return 0; - suffix.nlabels++; - } - else if (*((unsigned char *)p) >= 128) - need_conversion = 1; /* in case domain is non-ascii we need a toASCII conversion */ - } - - if (suffix.nlabels == 1) { - /* TLD, this is the prevailing '*' match. If type excludes the '*' rule, continue. - */ - if (!(type & PSL_TYPE_NO_STAR_RULE)) - return 1; - } - - type &= ~PSL_TYPE_NO_STAR_RULE; - - if (psl->utf8 || psl == &builtin_psl) - need_conversion = 0; - - if (need_conversion) { - psl_idna_t *idna = psl_idna_open(); - - if (psl_idna_toASCII(idna, domain, &punycode) == 0) { - suffix.label = punycode; - suffix.length = strlen(punycode); - } else { - /* fallback */ - - suffix.label = domain; - suffix.length = p - suffix.label; - } - - psl_idna_close(idna); - } else { - suffix.label = domain; - suffix.length = p - suffix.label; - } - - if (psl == &builtin_psl || psl->dafsa) { - size_t dafsa_size = psl == &builtin_psl ? sizeof(kDafsa) : psl->dafsa_size; - const unsigned char *dafsa = psl == &builtin_psl ? kDafsa : psl->dafsa; - int rc = LookupStringInFixedSet(dafsa, dafsa_size, suffix.label, suffix.length); - if (rc != -1) { - /* check for correct rule type */ - if (type == PSL_TYPE_ICANN && !(rc & PRIV_PSL_FLAG_ICANN)) - goto suffix_no; - else if (type == PSL_TYPE_PRIVATE && !(rc & PRIV_PSL_FLAG_PRIVATE)) - goto suffix_no; - - if (rc & PRIV_PSL_FLAG_EXCEPTION) - goto suffix_no; - - /* wildcard *.foo.bar implicitly make foo.bar a public suffix */ - /* definitely a match, no matter if the found rule is a wildcard or not */ - goto suffix_yes; - } - if ((suffix.label = strchr(suffix.label, '.'))) { - suffix.label++; - suffix.length = strlen(suffix.label); - suffix.nlabels--; - - rc = LookupStringInFixedSet(dafsa, dafsa_size, suffix.label, suffix.length); - if (rc != -1) { - /* check for correct rule type */ - if (type == PSL_TYPE_ICANN && !(rc & PRIV_PSL_FLAG_ICANN)) - goto suffix_no; - else if (type == PSL_TYPE_PRIVATE && !(rc & PRIV_PSL_FLAG_PRIVATE)) - goto suffix_no; - - if (rc & PRIV_PSL_FLAG_WILDCARD) - goto suffix_yes; - } - } - } else { - psl_entry_t *rule = vector_get(psl->suffixes, 0); - - if (!rule || rule->nlabels < suffix.nlabels - 1) - goto suffix_no; - - rule = vector_get(psl->suffixes, vector_find(psl->suffixes, &suffix)); - - if (rule) { - /* check for correct rule type */ - if (type == PSL_TYPE_ICANN && !(rule->flags & PRIV_PSL_FLAG_ICANN)) - goto suffix_no; - else if (type == PSL_TYPE_PRIVATE && !(rule->flags & PRIV_PSL_FLAG_PRIVATE)) - goto suffix_no; - - if (rule->flags & PRIV_PSL_FLAG_EXCEPTION) - goto suffix_no; - - /* wildcard *.foo.bar implicitly make foo.bar a public suffix */ - /* definitely a match, no matter if the found rule is a wildcard or not */ - goto suffix_yes; - } - - if ((suffix.label = strchr(suffix.label, '.'))) { - suffix.label++; - suffix.length = strlen(suffix.label); - suffix.nlabels--; - - rule = vector_get(psl->suffixes, vector_find(psl->suffixes, &suffix)); - - if (rule) { - /* check for correct rule type */ - if (type == PSL_TYPE_ICANN && !(rule->flags & PRIV_PSL_FLAG_ICANN)) - goto suffix_no; - else if (type == PSL_TYPE_PRIVATE && !(rule->flags & PRIV_PSL_FLAG_PRIVATE)) - goto suffix_no; - - if (rule->flags & PRIV_PSL_FLAG_WILDCARD) - goto suffix_yes; - } - } - } - -suffix_no: - if (punycode) - free(punycode); - return 0; - -suffix_yes: - if (punycode) - free(punycode); - return 1; -} - -/** - * psl_is_public_suffix: - * @psl: PSL context - * @domain: Domain string - * - * This function checks if @domain is a public suffix by the means of the - * [Mozilla Public Suffix List](https://publicsuffix.org). - * - * For cookie domain checking see psl_is_cookie_domain_acceptable(). - * - * International @domain names have to be either in UTF-8 (lowercase + NFKC) or in ASCII/ACE format (punycode). - * Other encodings likely result in incorrect return values. - * Use helper function psl_str_to_utf8lower() for normalization @domain. - * - * @psl is a context returned by either psl_load_file(), psl_load_fp() or - * psl_builtin(). - * - * Returns: 1 if domain is a public suffix, 0 if not. - * - * Since: 0.1 - */ -int psl_is_public_suffix(const psl_ctx_t *psl, const char *domain) -{ - if (!psl || !domain) - return 1; - - return is_public_suffix(psl, domain, PSL_TYPE_ANY); -} - -/** - * psl_is_public_suffix2: - * @psl: PSL context - * @domain: Domain string - * @type: Domain type - * - * This function checks if @domain is a public suffix by the means of the - * [Mozilla Public Suffix List](https://publicsuffix.org). - * - * @type specifies the PSL section where to perform the lookup. Valid values are - * %PSL_TYPE_PRIVATE, %PSL_TYPE_ICANN, %PSL_TYPE_NO_STAR_RULE, and %PSL_TYPE_ANY. - * - * %PSL_TYPE_NO_STAR_RULE switches of the 'prevailing star rule' (see - * [List](https://publicsuffix.org/list) under 'Algorithm' 2.). - * Applying the flag means that TLDs not explicitly listed in the PSL are *not* treated as public suffixes. - * - * International @domain names have to be either in UTF-8 (lowercase + NFKC) or in ASCII/ACE format (punycode). - * Other encodings likely result in incorrect return values. - * Use helper function psl_str_to_utf8lower() for normalization @domain. - * - * @psl is a context returned by either psl_load_file(), psl_load_fp() or - * psl_builtin(). - * - * Returns: 1 if domain is a public suffix, 0 if not. - * - * Since: 0.1 - */ -int psl_is_public_suffix2(const psl_ctx_t *psl, const char *domain, int type) -{ - if (!psl || !domain) - return 1; - - return is_public_suffix(psl, domain, type); -} - -/** - * psl_unregistrable_domain: - * @psl: PSL context - * @domain: Domain string - * - * This function finds the longest public suffix part of @domain by the means - * of the [Mozilla Public Suffix List](https://publicsuffix.org). - * - * International @domain names have to be either in UTF-8 (lowercase + NFKC) or in ASCII/ACE format (punycode). - * Other encodings likely result in incorrect return values. - * Use helper function psl_str_to_utf8lower() for normalization @domain. - * - * @psl is a context returned by either psl_load_file(), psl_load_fp() or - * psl_builtin(). - * - * Returns: Pointer to longest public suffix part of @domain or %NULL if @domain - * does not contain a public suffix (or if @psl is %NULL). - * - * Since: 0.1 - */ -const char *psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain) -{ - int nlabels = 0; - const char *p; - - if (!psl || !domain) - return NULL; - - /* - * In the main loop we introduce a O(N^2) behavior to avoid code duplication. - * To avoid nasty CPU hogging, we limit the lookup to max. 8 domain labels to the right. - */ - for (p = domain + strlen(domain) - 1; p >= domain; p--) { - if (*p == '.' && ++nlabels > 8) { - domain = p + 1; - break; - } - } - - /* - * We check from left to right to catch special PSL entries like 'forgot.his.name': - * 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not. - */ - - while (!is_public_suffix(psl, domain, 0)) { - if ((domain = strchr(domain, '.'))) - domain++; - else - break; /* prevent endless loop if is_public_suffix() is broken. */ - } - - return domain; -} - -/** - * psl_registrable_domain: - * @psl: PSL context - * @domain: Domain string - * - * This function finds the shortest private suffix part of @domain by the means - * of the [Mozilla Public Suffix List](https://publicsuffix.org). - * - * International @domain names have to be either in UTF-8 (lowercase + NFKC) or in ASCII/ACE format (punycode). - * Other encodings likely result in incorrect return values. - * Use helper function psl_str_to_utf8lower() for normalization @domain. - * - * @psl is a context returned by either psl_load_file(), psl_load_fp() or - * psl_builtin(). - * - * Returns: Pointer to shortest private suffix part of @domain or %NULL if @domain - * does not contain a private suffix (or if @psl is %NULL). - * - * Since: 0.1 - */ -const char *psl_registrable_domain(const psl_ctx_t *psl, const char *domain) -{ - const char *p, *regdom = NULL; - int nlabels = 0; - - if (!psl || !domain || *domain == '.') - return NULL; - - /* - * In the main loop we introduce a O(N^2) behavior to avoid code duplication. - * To avoid nasty CPU hogging, we limit the lookup to max. 8 domain labels to the right. - */ - for (p = domain + strlen(domain) - 1; p >= domain; p--) { - if (*p == '.' && ++nlabels > 8) { - domain = p + 1; - break; - } - } - - /* - * We check from left to right to catch special PSL entries like 'forgot.his.name': - * 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not. - */ - - while (!is_public_suffix(psl, domain, 0)) { - if ((p = strchr(domain, '.'))) { - regdom = domain; - domain = p + 1; - } else - break; /* prevent endless loop if is_public_suffix() is broken. */ - } - - return regdom; -} - -/** - * psl_load_file: - * @fname: Name of PSL file - * - * This function loads the public suffixes file named @fname. - * To free the allocated resources, call psl_free(). - * - * The suffixes are expected to be UTF-8 encoded (lowercase + NFKC) if they are international. - * - * Returns: Pointer to a PSL context or %NULL on failure. - * - * Since: 0.1 - */ -psl_ctx_t *psl_load_file(const char *fname) -{ - FILE *fp; - psl_ctx_t *psl = NULL; - - if (!fname) - return NULL; - - if ((fp = fopen(fname, "rb"))) { - psl = psl_load_fp(fp); - fclose(fp); - } - - return psl; -} - -/** - * psl_load_fp: - * @fp: %FILE pointer - * - * This function loads the public suffixes from a %FILE pointer. - * To free the allocated resources, call psl_free(). - * - * The suffixes are expected to be UTF-8 encoded (lowercase + NFKC) if they are international. - * - * Returns: Pointer to a PSL context or %NULL on failure. - * - * Since: 0.1 - */ -psl_ctx_t *psl_load_fp(FILE *fp) -{ - psl_ctx_t *psl; - psl_entry_t suffix, *suffixp; - char buf[256], *linep, *p; - int type = 0, is_dafsa; - psl_idna_t *idna; - - if (!fp) - return NULL; - - if (!(psl = calloc(1, sizeof(psl_ctx_t)))) - return NULL; - - /* read first line to allow ASCII / DAFSA detection */ - if (!(linep = fgets(buf, sizeof(buf) - 1, fp))) - goto fail; - - is_dafsa = strlen(buf) == 16 && !strncmp(buf, ".DAFSA@PSL_", 11); - - if (is_dafsa) { - void *m; - size_t size = 65536, n, len = 0; - int version = atoi(buf + 11); - - if (version != 0) - goto fail; - - if (!(psl->dafsa = malloc(size))) - goto fail; - - memcpy(psl->dafsa, buf, len); - - while ((n = fread(psl->dafsa + len, 1, size - len, fp)) > 0) { - len += n; - if (len >= size) { - if (!(m = realloc(psl->dafsa, size *= 2))) - goto fail; - psl->dafsa = m; - } - } - - /* release unused memory */ - if ((m = realloc(psl->dafsa, len))) - psl->dafsa = m; - else if (!len) - psl->dafsa = NULL; /* realloc() just free'd psl->dafsa */ - - psl->dafsa_size = len; - psl->utf8 = !!GetUtfMode(psl->dafsa, len); - - return psl; - } - - idna = psl_idna_open(); - - /* - * as of 02.11.2012, the list at https://publicsuffix.org/list/ contains ~6000 rules and 40 exceptions. - * as of 19.02.2014, the list at https://publicsuffix.org/list/ contains ~6500 rules and 19 exceptions. - * as of 07.10.2018, the list at https://publicsuffix.org/list/ contains ~8600 rules and 8 exceptions. - */ - psl->suffixes = vector_alloc(8*1024, suffix_compare_array); - psl->utf8 = 1; /* we put UTF-8 and punycode rules in the lookup vector */ - - do { - while (isspace_ascii(*linep)) linep++; /* ignore leading whitespace */ - if (!*linep) continue; /* skip empty lines */ - - if (*linep == '/' && linep[1] == '/') { - if (!type) { - if (strstr(linep + 2, "===BEGIN ICANN DOMAINS===")) - type = PRIV_PSL_FLAG_ICANN; - else if (!type && strstr(linep + 2, "===BEGIN PRIVATE DOMAINS===")) - type = PRIV_PSL_FLAG_PRIVATE; - } - else if (type == PRIV_PSL_FLAG_ICANN && strstr(linep + 2, "===END ICANN DOMAINS===")) - type = 0; - else if (type == PRIV_PSL_FLAG_PRIVATE && strstr(linep + 2, "===END PRIVATE DOMAINS===")) - type = 0; - - continue; /* skip comments */ - } - - /* parse suffix rule */ - for (p = linep; *linep && !isspace_ascii(*linep);) linep++; - *linep = 0; - - if (*p == '!') { - p++; - suffix.flags = PRIV_PSL_FLAG_EXCEPTION | type; - psl->nexceptions++; - } else if (*p == '*') { - if (*++p != '.') { - /* fprintf(stderr, "Unsupported kind of rule (ignored): %s\n", p - 1); */ - continue; - } - p++; - /* wildcard *.foo.bar implicitly make foo.bar a public suffix */ - suffix.flags = PRIV_PSL_FLAG_WILDCARD | PRIV_PSL_FLAG_PLAIN | type; - psl->nwildcards++; - psl->nsuffixes++; - } else { - suffix.flags = PRIV_PSL_FLAG_PLAIN | type; - psl->nsuffixes++; - } - - if (suffix_init(&suffix, p, linep - p) == 0) { - int index; - - if ((index = vector_find(psl->suffixes, &suffix)) >= 0) { - /* Found existing entry: - * Combination of exception and plain rule is ambiguous - * !foo.bar - * foo.bar - * - * Allowed: - * !foo.bar + *.foo.bar - * foo.bar + *.foo.bar - * - * We do not check here, let's do it later. - */ - - suffixp = vector_get(psl->suffixes, index); - suffixp->flags |= suffix.flags; - } else { - /* New entry */ - suffixp = vector_get(psl->suffixes, vector_add(psl->suffixes, &suffix)); - } - - if (suffixp) { - suffixp->label = suffixp->label_buf; /* set label to changed address */ - add_punycode_if_needed(idna, psl->suffixes, suffixp); - } - } - } while ((linep = fgets(buf, sizeof(buf), fp))); - - vector_sort(psl->suffixes); - - psl_idna_close(idna); - - return psl; - -fail: - psl_free(psl); - return NULL; -} - -/** - * psl_free: - * @psl: PSL context pointer - * - * This function frees the the PSL context that has been retrieved via - * psl_load_fp() or psl_load_file(). - * - * Since: 0.1 - */ -void psl_free(psl_ctx_t *psl) -{ - if (psl && psl != &builtin_psl) { - vector_free(&psl->suffixes); - free(psl->dafsa); - free(psl); - } -} - -/** - * psl_builtin: - * - * This function returns the PSL context that has been generated and built in at compile-time. - * You don't have to free the returned context explicitly. - * - * The builtin data also contains punycode entries, one for each international domain name. - * - * If the generation of built-in data has been disabled during compilation, %NULL will be returned. - * When using the builtin psl context, you can provide UTF-8 (lowercase + NFKC) or ASCII/ACE (punycode) - * representations of domains to functions like psl_is_public_suffix(). - * - * Returns: Pointer to the built in PSL data or %NULL if this data is not available. - * - * Since: 0.1 - */ -const psl_ctx_t *psl_builtin(void) -{ -#ifdef ENABLE_BUILTIN - return &builtin_psl; -#else - return NULL; -#endif -} - -/** - * psl_suffix_count: - * @psl: PSL context pointer - * - * This function returns number of public suffixes maintained by @psl. - * The number of exceptions within the Public Suffix List are not included. - * - * If the information is not available, the return value is -1 (since 0.19). - * This is the case with DAFSA blobs or if @psl is %NULL. - * - * Returns: Number of public suffixes entries in PSL context or -1 if this information is not available. - * - * Since: 0.1 - */ -int psl_suffix_count(const psl_ctx_t *psl) -{ - if (psl == &builtin_psl) - return _psl_nsuffixes; - else if (psl) - return psl->dafsa ? -1 : psl->nsuffixes; - else - return -1; -} - -/** - * psl_suffix_exception_count: - * @psl: PSL context pointer - * - * This function returns number of public suffix exceptions maintained by @psl. - * - * If the information is not available, the return value is -1 (since 0.19). - * This is the case with DAFSA blobs or if @psl is %NULL. - * - * Returns: Number of public suffix exceptions in PSL context or -1 if this information is not available. - * - * Since: 0.1 - */ -int psl_suffix_exception_count(const psl_ctx_t *psl) -{ - if (psl == &builtin_psl) - return _psl_nexceptions; - else if (psl) - return psl->dafsa ? -1 : psl->nexceptions; - else - return -1; -} - -/** - * psl_suffix_wildcard_count: - * @psl: PSL context pointer - * - * This function returns number of public suffix wildcards maintained by @psl. - * - * If the information is not available, the return value is -1 (since 0.19). - * This is the case with DAFSA blobs or if @psl is %NULL. - * - * Returns: Number of public suffix wildcards in PSL context or -1 if this information is not available. - * - * Since: 0.10.0 - */ -int psl_suffix_wildcard_count(const psl_ctx_t *psl) -{ - if (psl == &builtin_psl) - return _psl_nwildcards; - else if (psl) - return psl->dafsa ? -1 : psl->nwildcards; - else - return -1; -} - -/** - * psl_builtin_file_time: - * - * This function returns the mtime of the Public Suffix List file that has been built in. - * - * If the generation of built-in data has been disabled during compilation, 0 will be returned. - * - * Returns: time_t value or 0. - * - * Since: 0.1 - */ -time_t psl_builtin_file_time(void) -{ - return _psl_file_time; -} - -/** - * psl_builtin_sha1sum: - * - * This function returns the SHA1 checksum of the Public Suffix List file that has been built in. - * The returned string is in lowercase hex encoding, e.g. "2af1e9e3044eda0678bb05949d7cca2f769901d8". - * - * If the generation of built-in data has been disabled during compilation, an empty string will be returned. - * - * Returns: String containing SHA1 checksum or an empty string. - * - * Since: 0.1 - */ -const char *psl_builtin_sha1sum(void) -{ - return _psl_sha1_checksum; -} - -/** - * psl_builtin_filename: - * - * This function returns the file name of the Public Suffix List file that has been built in. - * - * If the generation of built-in data has been disabled during compilation, an empty string will be returned. - * - * Returns: String containing the PSL file name or an empty string. - * - * Since: 0.1 - */ -const char *psl_builtin_filename(void) -{ - return _psl_filename; -} - -/** - * psl_builtin_outdated: - * - * This function checks if the built-in data is older than the file it has been created from. - * If it is, it might be a good idea for the application to reload the PSL. - * The mtime is taken as reference. - * - * If the PSL file does not exist, it is assumed that the built-in data is not outdated. - * - * Returns: 1 if the built-in is outdated, 0 otherwise. - * - * Since: 0.10.0 - */ -int psl_builtin_outdated(void) -{ - struct stat st; - - if (stat(_psl_filename, &st) == 0 && st.st_mtime > _psl_file_time) - return 1; - - return 0; -} - -/** - * psl_dist_filename: - * - * This function returns the file name of the distribution/system PSL data file. - * This file will be considered by psl_latest(). - * - * Return the filename that is set by ./configure --with-psl-distfile, or an empty string. - * - * Returns: String containing a PSL file name or an empty string. - * - * Since: 0.16 - */ -const char *psl_dist_filename(void) -{ - return _psl_dist_filename; -} - -/** - * psl_get_version: - * - * Get libpsl version. - * - * Returns: String containing version of libpsl. - * - * Since: 0.2.5 - **/ -const char *psl_get_version(void) -{ -#ifdef WITH_LIBICU - return PACKAGE_VERSION " (+libicu/" U_ICU_VERSION ")"; -#elif defined(WITH_LIBIDN2) - return PACKAGE_VERSION " (+libidn2/" IDN2_VERSION ")"; -#elif defined(WITH_LIBIDN) - return PACKAGE_VERSION " (+libidn/" STRINGPREP_VERSION ")"; -#else - return PACKAGE_VERSION " (no IDNA support)"; -#endif -} - -/** - * psl_check_version_number: - * @version: Version number (hex) to check against. - * - * Check the given version number is at minimum the current library version number. - * The version number must be a hexadecimal number like 0x000a01 (V0.10.1). - * - * Returns: Returns the library version number if the given version number is at least - * the version of the library, else return 0; If the argument is 0, the function returns - * the library version number without performing a check. - * - * Since: 0.11.0 - **/ -int psl_check_version_number(int version) -{ - if (version) { - int major = version >> 16; - int minor = (version >> 8) & 0xFF; - int patch = version & 0xFF; - - if (major < PSL_VERSION_MAJOR - || (major == PSL_VERSION_MAJOR && minor < PSL_VERSION_MINOR) - || (major == PSL_VERSION_MAJOR && minor == PSL_VERSION_MINOR && patch < PSL_VERSION_PATCH)) - { - return 0; - } - } - - return PSL_VERSION_NUMBER; -} - -/* return whether hostname is an IP address or not */ -static int isip(const char *hostname) -{ -#ifdef _WIN32 - WCHAR wName[INET6_ADDRSTRLEN+1]; - - struct sockaddr_in addr = {0}; - struct sockaddr_in6 addr6 = {0}; - - INT size = sizeof(addr); - INT size6 = sizeof(addr6); - - if (!MultiByteToWideChar(CP_UTF8, 0, hostname, -1, wName, countof(wName))) - return 0; - - return (WSAStringToAddressW(wName, AF_INET, NULL, (struct sockaddr *)&addr, &size) != SOCKET_ERROR) | - (WSAStringToAddressW(wName, AF_INET6, NULL, (struct sockaddr *)&addr6, &size6) != SOCKET_ERROR); -#else - struct in_addr addr; - struct in6_addr addr6; - - return inet_pton(AF_INET, hostname, &addr) || inet_pton(AF_INET6, hostname, &addr6); -#endif -} - -/** - * psl_is_cookie_domain_acceptable: - * @psl: PSL context pointer - * @hostname: The request hostname. - * @cookie_domain: The domain value from a cookie - * - * This helper function checks whether @cookie_domain is an acceptable cookie domain value for the request - * @hostname. - * - * For international domain names both, @hostname and @cookie_domain, have to be either in UTF-8 (lowercase + NFKC) - * or in ASCII/ACE (punycode) format. Other encodings or mixing UTF-8 and punycode likely result in incorrect return values. - * - * Use helper function psl_str_to_utf8lower() for normalization of @hostname and @cookie_domain. - * - * Hint for Windows users: - * Please make sure the calling application has called WSAStartup() before calling psl_is_cookie_domain_acceptable(). - * - * Examples: - * 1. Cookie domain 'example.com' would be acceptable for hostname 'www.example.com', - * but '.com' or 'com' would NOT be acceptable since 'com' is a public suffix. - * - * 2. Cookie domain 'his.name' would be acceptable for hostname 'remember.his.name', - * but NOT for 'forgot.his.name' since 'forgot.his.name' is a public suffix. - * - * Returns: 1 if acceptable, 0 if not acceptable. - * - * Since: 0.1 - */ -int psl_is_cookie_domain_acceptable(const psl_ctx_t *psl, const char *hostname, const char *cookie_domain) -{ - const char *p; - size_t hostname_length, cookie_domain_length; - - if (!psl || !hostname || !cookie_domain) - return 0; - - while (*cookie_domain == '.') - cookie_domain++; - - if (!strcmp(hostname, cookie_domain)) - return 1; /* an exact match is acceptable (and pretty common) */ - - if (isip(hostname)) - return 0; /* Hostname is an IP address and these must match fully (RFC 6265, 5.1.3) */ - - cookie_domain_length = strlen(cookie_domain); - hostname_length = strlen(hostname); - - if (cookie_domain_length >= hostname_length) - return 0; /* cookie_domain is too long */ - - p = hostname + hostname_length - cookie_domain_length; - if (!strcmp(p, cookie_domain) && p[-1] == '.') { - /* OK, cookie_domain matches, but it must be longer than the longest public suffix in 'hostname' */ - - if (!(p = psl_unregistrable_domain(psl, hostname))) - return 1; - - if (cookie_domain_length > strlen(p)) - return 1; - } - - return 0; -} - -/** - * psl_free_string: - * @str: pointer to lowercase string returned by psl_str_to_utf8lower() - * - * This function free()'s the memory allocated by psl_str_to_utf8lower() when - * returning a lowercase string - * - * Since: 0.19 - */ -void psl_free_string(char *str) -{ - if (str) - free(str); -} - -/** - * psl_str_to_utf8lower: - * @str: string to convert - * @encoding: charset encoding of @str, e.g. 'iso-8859-1' or %NULL - * @locale: locale of @str for to lowercase conversion, e.g. 'de' or %NULL - * @lower: return value containing the converted string - * - * This helper function converts a string to UTF-8 lowercase + NFKC representation. - * Lowercase + NFKC UTF-8 is needed as input to the domain checking functions. - * - * @lower stays unchanged on error. - * - * When returning PSL_SUCCESS, the return value 'lower' must be freed after usage. - * - * Returns: psl_error_t value. - * PSL_SUCCESS: Success - * PSL_ERR_INVALID_ARG: @str is a %NULL value. - * PSL_ERR_CONVERTER: Failed to open the unicode converter with name @encoding - * PSL_ERR_TO_UTF16: Failed to convert @str to unicode - * PSL_ERR_TO_LOWER: Failed to convert unicode to lowercase - * PSL_ERR_TO_UTF8: Failed to convert unicode to UTF-8 - * PSL_ERR_NO_MEM: Failed to allocate memory - * - * Since: 0.4 - */ -psl_error_t psl_str_to_utf8lower(const char *str, const char *encoding PSL_UNUSED, const char *locale PSL_UNUSED, char **lower) -{ - int ret = PSL_ERR_INVALID_ARG; - - if (!str) - return PSL_ERR_INVALID_ARG; - - /* shortcut to avoid costly conversion */ - if (str_is_ascii(str)) { - if (lower) { - char *p, *tmp; - - if (!(tmp = strdup(str))) - return PSL_ERR_NO_MEM; - - *lower = tmp; - - /* convert ASCII string to lowercase */ - for (p = *lower; *p; p++) - if (isupper(*p)) - *p = tolower(*p); - } - return PSL_SUCCESS; - } - -#ifdef WITH_LIBICU - do { - size_t str_length = strlen(str); - UErrorCode status = 0; - UChar *utf16_dst, *utf16_lower; - int32_t utf16_dst_length; - char *utf8_lower; - UConverter *uconv; - - if (str_length < 256) { - /* C89 allocation */ - utf16_dst = alloca(sizeof(UChar) * (str_length * 2 + 1)); - utf16_lower = alloca(sizeof(UChar) * (str_length * 2 + 1)); - utf8_lower = alloca(str_length * 6 + 1); - } else { - utf16_dst = malloc(sizeof(UChar) * (str_length * 2 + 1)); - utf16_lower = malloc(sizeof(UChar) * (str_length * 2 + 1)); - utf8_lower = malloc(str_length * 6 + 1); - - if (!utf16_dst || !utf16_lower || !utf8_lower) { - ret = PSL_ERR_NO_MEM; - goto out; - } - } - - uconv = ucnv_open(encoding, &status); - if (U_SUCCESS(status)) { - utf16_dst_length = ucnv_toUChars(uconv, utf16_dst, str_length * 2 + 1, str, str_length, &status); - ucnv_close(uconv); - - if (U_SUCCESS(status)) { - int32_t utf16_lower_length = u_strToLower(utf16_lower, str_length * 2 + 1, utf16_dst, utf16_dst_length, locale, &status); - if (U_SUCCESS(status)) { - u_strToUTF8(utf8_lower, str_length * 6 + 1, NULL, utf16_lower, utf16_lower_length, &status); - if (U_SUCCESS(status)) { - ret = PSL_SUCCESS; - if (lower) { - char *tmp = strdup(utf8_lower); - - if (tmp) - *lower = tmp; - else - ret = PSL_ERR_NO_MEM; - } - } else { - ret = PSL_ERR_TO_UTF8; - /* fprintf(stderr, "Failed to convert UTF-16 to UTF-8 (status %d)\n", status); */ - } - } else { - ret = PSL_ERR_TO_LOWER; - /* fprintf(stderr, "Failed to convert UTF-16 to lowercase (status %d)\n", status); */ - } - } else { - ret = PSL_ERR_TO_UTF16; - /* fprintf(stderr, "Failed to convert string to UTF-16 (status %d)\n", status); */ - } - } else { - ret = PSL_ERR_CONVERTER; - /* fprintf(stderr, "Failed to open converter for '%s' (status %d)\n", encoding, status); */ - } -out: - if (str_length >= 256) { - free(utf16_dst); - free(utf16_lower); - free(utf8_lower); - } - } while (0); -#elif defined(WITH_LIBIDN2) || defined(WITH_LIBIDN) - do { - /* find out local charset encoding */ - if (!encoding) { -#ifdef HAVE_NL_LANGINFO - encoding = nl_langinfo(CODESET); -#elif defined _WIN32 - static char buf[16]; - snprintf(buf, sizeof(buf), "CP%u", GetACP()); - encoding = buf; -#endif - if (!encoding || !*encoding) - encoding = "ASCII"; - } - - /* convert to UTF-8 */ - if (strcasecmp(encoding, "utf-8")) { - iconv_t cd = iconv_open("utf-8", encoding); - - if (cd != (iconv_t)-1) { - char *tmp = (char *)str; /* iconv won't change where str points to, but changes tmp itself */ - size_t tmp_len = strlen(str) + 1; - size_t dst_len = tmp_len * 6, dst_len_tmp = dst_len; - char *dst = malloc(dst_len + 1), *dst_tmp = dst; - - if (!dst) { - ret = PSL_ERR_NO_MEM; - } - else if (iconv(cd, (ICONV_CONST char **)&tmp, &tmp_len, &dst_tmp, &dst_len_tmp) != (size_t)-1 - && iconv(cd, NULL, NULL, &dst_tmp, &dst_len_tmp) != (size_t)-1) - { - /* start size for u8_tolower internal memory allocation. - * u8_tolower() does not terminate the result string. we have 0 byte included in above tmp_len - * and thus in len. */ - size_t len = dst_len - dst_len_tmp; - - if ((tmp = (char *)u8_tolower((uint8_t *)dst, len, 0, UNINORM_NFKC, NULL, &len))) { - ret = PSL_SUCCESS; - if (lower) { - *lower = tmp; - tmp = NULL; - } else - free(tmp); - } else { - ret = PSL_ERR_TO_LOWER; - /* fprintf(stderr, "Failed to convert UTF-8 to lowercase (errno %d)\n", errno); */ - } - } else { - ret = PSL_ERR_TO_UTF8; - /* fprintf(stderr, "Failed to convert '%s' string into '%s' (%d)\n", src_encoding, dst_encoding, errno); */ - } - - free(dst); - iconv_close(cd); - } else { - ret = PSL_ERR_TO_UTF8; - /* fprintf(stderr, "Failed to prepare encoding '%s' into '%s' (%d)\n", src_encoding, dst_encoding, errno); */ - } - } else { - /* we need a conversion to lowercase */ - uint8_t *tmp; - - /* start size for u8_tolower internal memory allocation. - * u8_tolower() does not terminate the result string, so include terminating 0 byte in len. */ - size_t len = u8_strlen((uint8_t *)str) + 1; - - if ((tmp = u8_tolower((uint8_t *)str, len, 0, UNINORM_NFKC, NULL, &len))) { - ret = PSL_SUCCESS; - if (lower) { - *lower = (char*)tmp; - tmp = NULL; - } else - free(tmp); - } else { - ret = PSL_ERR_TO_LOWER; - /* fprintf(stderr, "Failed to convert UTF-8 to lowercase (errno %d)\n", errno); */ - } - } - - } while (0); -#endif - - return ret; -} - -/* if file is newer than the builtin data, insert it reverse sorted by mtime */ -static int insert_file(const char *fname, const char **psl_fname, time_t *psl_mtime, int n) -{ - struct stat st; - int it; - - if (fname && *fname && stat(fname, &st) == 0 && st.st_mtime > _psl_file_time) { - /* add file name and mtime to end of array */ - psl_fname[n] = fname; - psl_mtime[n++] = st.st_mtime; - - /* move the new entry to it's correct position */ - for (it = n - 2; it >= 0 && st.st_mtime > psl_mtime[it]; it--) { - psl_fname[it + 1] = psl_fname[it]; - psl_mtime[it + 1] = psl_mtime[it]; - psl_fname[it] = fname; - psl_mtime[it] = st.st_mtime; - } - } - - return n; -} - -/** - * psl_latest: - * @fname: Name of PSL file or %NULL - * - * This function loads the the latest available PSL data from either - * - @fname (application specific filename, may be %NULL) - * - location specified during built-time (filename from ./configure --with-psl-distfile) - * - built-in PSL data (generated from ./configure --with-psl-file) - * - location of built-in data (filename from ./configure --with-psl-file) - * - * If none of the above is available, the function returns %NULL. - * - * To free the allocated resources, call psl_free(). - * - * Returns: Pointer to a PSL context or %NULL on failure. - * - * Since: 0.16 - */ -psl_ctx_t *psl_latest(const char *fname) -{ - psl_ctx_t *psl; - const char *psl_fname[3]; - time_t psl_mtime[3]; - int it, ntimes; - - psl_fname[0] = NULL; /* silence gcc 6.2 false warning */ - - /* create array of PSL files reverse sorted by mtime (latest first) */ - ntimes = insert_file(fname, psl_fname, psl_mtime, 0); - ntimes = insert_file(_psl_dist_filename, psl_fname, psl_mtime, ntimes); - ntimes = insert_file(_psl_filename, psl_fname, psl_mtime, ntimes); - - /* load PSL data from the latest file, falling back to the second recent, ... */ - for (psl = NULL, it = 0; it < ntimes; it++) { - if (psl_mtime[it] > _psl_file_time) - if ((psl = psl_load_file(psl_fname[it]))) - break; - } - - /* if file loading failed or there is no file newer than the builtin data, - * then return the builtin data. */ - return psl ? psl : (psl_ctx_t *) psl_builtin(); -} diff --git a/vendor/libpsl/version.txt b/vendor/libpsl/version.txt deleted file mode 100644 index e756a90e6..000000000 --- a/vendor/libpsl/version.txt +++ /dev/null @@ -1 +0,0 @@ -0.21.5 diff --git a/vendor/mbedtls.mask b/vendor/mbedtls.mask deleted file mode 100644 index 1e208e407..000000000 --- a/vendor/mbedtls.mask +++ /dev/null @@ -1,41 +0,0 @@ -3rdparty -BRANCHES.md -BUGS.md -ChangeLog -ChangeLog.d -cmake -CMakeLists.txt -configs -CONTRIBUTING.md -DartConfiguration.tcl -dco.txt -docs -doxygen -framework -Makefile -pkgconfig -programs -README.md -scripts -SECURITY.md -SUPPORT.md -tests -tf-psa-crypto -visualc -.circleci -.git-blame-ignore-revs -.gitattributes -.github -.gitignore -.gitmodules -.globalrc -.mypy.ini -.pylintrc -.readthedocs.yaml -.travis.yml -.uncrustify.cfg -include/.gitignore -include/CMakeLists.txt -library/.gitignore -library/CMakeLists.txt -library/Makefile diff --git a/vendor/mbedtls/LICENSE b/vendor/mbedtls/LICENSE deleted file mode 100644 index 776ac77ea..000000000 --- a/vendor/mbedtls/LICENSE +++ /dev/null @@ -1,553 +0,0 @@ -Mbed TLS files are provided under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) -OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license. -This means that users may choose which of these licenses they take the code -under. - -The full text of each of these licenses is given below. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -=============================================================================== - - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/vendor/mbedtls/include/mbedtls/aes.h b/vendor/mbedtls/include/mbedtls/aes.h deleted file mode 100644 index d5eb1fd5c..000000000 --- a/vendor/mbedtls/include/mbedtls/aes.h +++ /dev/null @@ -1,631 +0,0 @@ -/** - * \file aes.h - * - * \brief This file contains AES definitions and functions. - * - * The Advanced Encryption Standard (AES) specifies a FIPS-approved - * cryptographic algorithm that can be used to protect electronic - * data. - * - * The AES algorithm is a symmetric block cipher that can - * encrypt and decrypt information. For more information, see - * FIPS Publication 197: Advanced Encryption Standard and - * ISO/IEC 18033-2:2006: Information technology -- Security - * techniques -- Encryption algorithms -- Part 2: Asymmetric - * ciphers. - * - * The AES-XTS block mode is standardized by NIST SP 800-38E - * - * and described in detail by IEEE P1619 - * . - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_AES_H -#define MBEDTLS_AES_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" -#include "mbedtls/platform_util.h" - -#include -#include - -/* padlock.c and aesni.c rely on these values! */ -#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ -#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ - -/* Error codes in range 0x0020-0x0022 */ -/** Invalid key length. */ -#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 -/** Invalid data input length. */ -#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 - -/* Error codes in range 0x0021-0x0025 */ -/** Invalid input data. */ -#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_AES_ALT) -// Regular implementation -// - -/** - * \brief The AES context-type definition. - */ -typedef struct mbedtls_aes_context { - int MBEDTLS_PRIVATE(nr); /*!< The number of rounds. */ - size_t MBEDTLS_PRIVATE(rk_offset); /*!< The offset in array elements to AES - round keys in the buffer. */ -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C) - uint32_t MBEDTLS_PRIVATE(buf)[44]; /*!< Aligned data buffer to hold - 10 round keys for 128-bit case. */ -#else - uint32_t MBEDTLS_PRIVATE(buf)[68]; /*!< Unaligned data buffer. This buffer can - hold 32 extra Bytes, which can be used for - one of the following purposes: -
  • Alignment if VIA padlock is - used.
  • -
  • Simplifying key expansion in the 256-bit - case by generating an extra round key. -
*/ -#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH && !MBEDTLS_PADLOCK_C */ -} -mbedtls_aes_context; - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief The AES XTS context-type definition. - */ -typedef struct mbedtls_aes_xts_context { - mbedtls_aes_context MBEDTLS_PRIVATE(crypt); /*!< The AES context to use for AES block - encryption or decryption. */ - mbedtls_aes_context MBEDTLS_PRIVATE(tweak); /*!< The AES context used for tweak - computation. */ -} mbedtls_aes_xts_context; -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#else /* MBEDTLS_AES_ALT */ -#include "aes_alt.h" -#endif /* MBEDTLS_AES_ALT */ - -/** - * \brief This function initializes the specified AES context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The AES context to initialize. This must not be \c NULL. - */ -void mbedtls_aes_init(mbedtls_aes_context *ctx); - -/** - * \brief This function releases and clears the specified AES context. - * - * \param ctx The AES context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. - */ -void mbedtls_aes_free(mbedtls_aes_context *ctx); - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function initializes the specified AES XTS context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The AES XTS context to initialize. This must not be \c NULL. - */ -void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx); - -/** - * \brief This function releases and clears the specified AES XTS context. - * - * \param ctx The AES XTS context to clear. - * If this is \c NULL, this function does nothing. - * Otherwise, the context must have been at least initialized. - */ -void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/** - * \brief This function sets the encryption key. - * - * \param ctx The AES context to which the key should be bound. - * It must be initialized. - * \param key The encryption key. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of data passed in bits. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -/** - * \brief This function sets the decryption key. - * - * \param ctx The AES context to which the key should be bound. - * It must be initialized. - * \param key The decryption key. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of data passed. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits); -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function prepares an XTS context for encryption and - * sets the encryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The encryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • - *
  • 512 bits (each of key1 and key2 is a 256-bit key)
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits); - -/** - * \brief This function prepares an XTS context for decryption and - * sets the decryption key. - * - * \param ctx The AES XTS context to which the key should be bound. - * It must be initialized. - * \param key The decryption key. This is comprised of the XTS key1 - * concatenated with the XTS key2. - * This must be a readable buffer of size \p keybits bits. - * \param keybits The size of \p key passed in bits. Valid options are: - *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • - *
  • 512 bits (each of key1 and key2 is a 256-bit key)
- * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/** - * \brief This function performs an AES single-block encryption or - * decryption operation. - * - * It performs the operation defined in the \p mode parameter - * (encrypt or decrypt), on the input data buffer defined in - * the \p input parameter. - * - * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or - * mbedtls_aes_setkey_dec() must be called before the first - * call to this API with the same context. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param input The buffer holding the input data. - * It must be readable and at least \c 16 Bytes long. - * \param output The buffer where the output data will be written. - * It must be writeable and at least \c 16 Bytes long. - - * \return \c 0 on success. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief This function performs an AES-CBC encryption or decryption operation - * on full blocks. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined in - * the \p input parameter. - * - * It can be called as many times as needed, until all the input - * data is processed. mbedtls_aes_init(), and either - * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called - * before the first call to this API with the same context. - * - * \note This function operates on full blocks, that is, the input size - * must be a multiple of the AES block size of \c 16 Bytes. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the IV, you should - * either save it manually or use the cipher module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of the input data in Bytes. This must be a - * multiple of the block size (\c 16 Bytes). - * \param iv Initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH - * on failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/** - * \brief This function performs an AES-XTS encryption or decryption - * operation for an entire XTS data unit. - * - * AES-XTS encrypts or decrypts blocks based on their location as - * defined by a data unit number. The data unit number must be - * provided by \p data_unit. - * - * NIST SP 800-38E limits the maximum size of a data unit to 2^20 - * AES blocks. If the data unit is larger than this, this function - * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. - * - * \param ctx The AES XTS context to use for AES XTS operations. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of a data unit in Bytes. This can be any - * length between 16 bytes and 2^24 bytes inclusive - * (between 1 and 2^20 block cipher blocks). - * \param data_unit The address of the data unit encoded as an array of 16 - * bytes in little-endian format. For disk encryption, this - * is typically the index of the block device sector that - * contains the data. - * \param input The buffer holding the input data (which is an entire - * data unit). This function reads \p length Bytes from \p - * input. - * \param output The buffer holding the output data (which is an entire - * data unit). This function writes \p length Bytes to \p - * output. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is - * smaller than an AES block in size (16 Bytes) or if \p - * length is larger than 2^20 blocks (16 MiB). - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief This function performs an AES-CFB128 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt or decrypt), on the input data buffer - * defined in the \p input parameter. - * - * For CFB, you must set up the context with mbedtls_aes_setkey_enc(), - * regardless of whether you are performing an encryption or decryption - * operation, that is, regardless of the \p mode parameter. This is - * because CFB mode uses the same key schedule for encryption and - * decryption. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you must either save it manually or use the cipher - * module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT. - * \param length The length of the input data in Bytes. - * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function performs an AES-CFB8 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined - * in the \p input parameter. - * - * Due to the nature of CFB, you must use the same key schedule for - * both encryption and decryption operations. Therefore, you must - * use the context initialized with mbedtls_aes_setkey_enc() for - * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or - * #MBEDTLS_AES_DECRYPT - * \param length The length of the input data. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output); -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/** - * \brief This function performs an AES-OFB (Output Feedback Mode) - * encryption or decryption operation. - * - * For OFB, you must set up the context with - * mbedtls_aes_setkey_enc(), regardless of whether you are - * performing an encryption or decryption operation. This is - * because OFB mode uses the same key schedule for encryption and - * decryption. - * - * The OFB operation is identical for encryption or decryption, - * therefore no operation mode needs to be specified. - * - * \note Upon exit, the content of iv, the Initialisation Vector, is - * updated so that you can call the same function again on the next - * block(s) of data and get the same result as if it was encrypted - * in one call. This allows a "streaming" usage, by initialising - * iv_off to 0 before the first call, and preserving its value - * between calls. - * - * For non-streaming use, the iv should be initialised on each call - * to a unique value, and iv_off set to 0 on each call. - * - * If you need to retain the contents of the initialisation vector, - * you must either save it manually or use the cipher module - * instead. - * - * \warning For the OFB mode, the initialisation vector must be unique - * every encryption operation. Reuse of an initialisation vector - * will compromise security. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param length The length of the input data. - * \param iv_off The offset in IV (updated after use). - * It must point to a valid \c size_t. - * \param iv The initialization vector (updated after use). - * It must be a readable and writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output); - -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief This function performs an AES-CTR encryption or decryption - * operation. - * - * Due to the nature of CTR, you must use the same key schedule - * for both encryption and decryption operations. Therefore, you - * must use the context initialized with mbedtls_aes_setkey_enc() - * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 12 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 12 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**96 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. An alternative is to generate random nonces, but this - * limits the number of messages that can be securely encrypted: - * for example, with 96-bit random nonces, you should not encrypt - * more than 2**32 messages with the same key. - * - * Note that for both strategies, sizes are measured in blocks and - * that an AES block is 16 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The AES context to use for encryption or decryption. - * It must be initialized and bound to a key. - * \param length The length of the input data. - * \param nc_off The offset in the current \p stream_block, for - * resuming within the current cipher stream. The - * offset pointer should be 0 at the start of a stream. - * It must point to a valid \c size_t. - * \param nonce_counter The 128-bit nonce and counter. - * It must be a readable-writeable buffer of \c 16 Bytes. - * \param stream_block The saved stream block for resuming. This is - * overwritten by the function. - * It must be a readable-writeable buffer of \c 16 Bytes. - * \param input The buffer holding the input data. - * It must be readable and of size \p length Bytes. - * \param output The buffer holding the output data. - * It must be writeable and of size \p length Bytes. - * - * \return \c 0 on success. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/** - * \brief Internal AES block encryption function. This is only - * exposed to allow overriding it using - * \c MBEDTLS_AES_ENCRYPT_ALT. - * - * \param ctx The AES context to use for encryption. - * \param input The plaintext block. - * \param output The output (ciphertext) block. - * - * \return \c 0 on success. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16]); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -/** - * \brief Internal AES block decryption function. This is only - * exposed to allow overriding it using see - * \c MBEDTLS_AES_DECRYPT_ALT. - * - * \param ctx The AES context to use for decryption. - * \param input The ciphertext block. - * \param output The output (plaintext) block. - * - * \return \c 0 on success. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16]); -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_aes_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* aes.h */ diff --git a/vendor/mbedtls/include/mbedtls/aria.h b/vendor/mbedtls/include/mbedtls/aria.h deleted file mode 100644 index c685fc314..000000000 --- a/vendor/mbedtls/include/mbedtls/aria.h +++ /dev/null @@ -1,343 +0,0 @@ -/** - * \file aria.h - * - * \brief ARIA block cipher - * - * The ARIA algorithm is a symmetric block cipher that can encrypt and - * decrypt information. It is defined by the Korean Agency for - * Technology and Standards (KATS) in KS X 1213:2004 (in - * Korean, but see http://210.104.33.10/ARIA/index-e.html in English) - * and also described by the IETF in RFC 5794. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_ARIA_H -#define MBEDTLS_ARIA_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -#include "mbedtls/platform_util.h" - -#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */ -#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */ - -#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */ -#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maximum number of rounds in ARIA. */ -#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */ - -/** Bad input data. */ -#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C - -/** Invalid data input length. */ -#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_ARIA_ALT) -// Regular implementation -// - -/** - * \brief The ARIA context-type definition. - */ -typedef struct mbedtls_aria_context { - unsigned char MBEDTLS_PRIVATE(nr); /*!< The number of rounds (12, 14 or 16) */ - /*! The ARIA round keys. */ - uint32_t MBEDTLS_PRIVATE(rk)[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4]; -} -mbedtls_aria_context; - -#else /* MBEDTLS_ARIA_ALT */ -#include "aria_alt.h" -#endif /* MBEDTLS_ARIA_ALT */ - -/** - * \brief This function initializes the specified ARIA context. - * - * It must be the first API called before using - * the context. - * - * \param ctx The ARIA context to initialize. This must not be \c NULL. - */ -void mbedtls_aria_init(mbedtls_aria_context *ctx); - -/** - * \brief This function releases and clears the specified ARIA context. - * - * \param ctx The ARIA context to clear. This may be \c NULL, in which - * case this function returns immediately. If it is not \c NULL, - * it must point to an initialized ARIA context. - */ -void mbedtls_aria_free(mbedtls_aria_context *ctx); - -/** - * \brief This function sets the encryption key. - * - * \param ctx The ARIA context to which the key should be bound. - * This must be initialized. - * \param key The encryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The size of \p key in Bits. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx, - const unsigned char *key, - unsigned int keybits); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -/** - * \brief This function sets the decryption key. - * - * \param ctx The ARIA context to which the key should be bound. - * This must be initialized. - * \param key The decryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The size of data passed. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx, - const unsigned char *key, - unsigned int keybits); -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -/** - * \brief This function performs an ARIA single-block encryption or - * decryption operation. - * - * It performs encryption or decryption (depending on whether - * the key was set for encryption on decryption) on the input - * data buffer defined in the \p input parameter. - * - * mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or - * mbedtls_aria_setkey_dec() must be called before the first - * call to this API with the same context. - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param input The 16-Byte buffer holding the input data. - * \param output The 16-Byte buffer holding the output data. - - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx, - const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char output[MBEDTLS_ARIA_BLOCKSIZE]); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief This function performs an ARIA-CBC encryption or decryption operation - * on full blocks. - * - * It performs the operation defined in the \p mode - * parameter (encrypt/decrypt), on the input data buffer defined in - * the \p input parameter. - * - * It can be called as many times as needed, until all the input - * data is processed. mbedtls_aria_init(), and either - * mbedtls_aria_setkey_enc() or mbedtls_aria_setkey_dec() must be called - * before the first call to this API with the same context. - * - * \note This function operates on aligned blocks, that is, the input size - * must be a multiple of the ARIA block size of 16 Bytes. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the IV, you should - * either save it manually or use the cipher module instead. - * - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_ARIA_ENCRYPT for encryption, or - * #MBEDTLS_ARIA_DECRYPT for decryption. - * \param length The length of the input data in Bytes. This must be a - * multiple of the block size (16 Bytes). - * \param iv Initialization vector (updated after use). - * This must be a readable buffer of size 16 Bytes. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief This function performs an ARIA-CFB128 encryption or decryption - * operation. - * - * It performs the operation defined in the \p mode - * parameter (encrypt or decrypt), on the input data buffer - * defined in the \p input parameter. - * - * For CFB, you must set up the context with mbedtls_aria_setkey_enc(), - * regardless of whether you are performing an encryption or decryption - * operation, that is, regardless of the \p mode parameter. This is - * because CFB mode uses the same key schedule for encryption and - * decryption. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the same function again on the next - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If you need to retain the contents of the - * IV, you must either save it manually or use the cipher - * module instead. - * - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_ARIA_ENCRYPT for encryption, or - * #MBEDTLS_ARIA_DECRYPT for decryption. - * \param length The length of the input data \p input in Bytes. - * \param iv_off The offset in IV (updated after use). - * This must not be larger than 15. - * \param iv The initialization vector (updated after use). - * This must be a readable buffer of size 16 Bytes. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief This function performs an ARIA-CTR encryption or decryption - * operation. - * - * Due to the nature of CTR, you must use the same key schedule - * for both encryption and decryption operations. Therefore, you - * must use the context initialized with mbedtls_aria_setkey_enc() - * for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first 12 bytes for the - * per-message nonce, and the last 4 bytes for internal use. In that - * case, before calling this function on a new message you need to - * set the first 12 bytes of \p nonce_counter to your chosen nonce - * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p - * stream_block to be ignored). That way, you can encrypt at most - * 2**96 messages of up to 2**32 blocks each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be unique. - * The recommended way to ensure uniqueness is to use a message - * counter. An alternative is to generate random nonces, but this - * limits the number of messages that can be securely encrypted: - * for example, with 96-bit random nonces, you should not encrypt - * more than 2**32 messages with the same key. - * - * Note that for both strategies, sizes are measured in blocks and - * that an ARIA block is 16 bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The ARIA context to use for encryption or decryption. - * This must be initialized and bound to a key. - * \param length The length of the input data \p input in Bytes. - * \param nc_off The offset in Bytes in the current \p stream_block, - * for resuming within the current cipher stream. The - * offset pointer should be \c 0 at the start of a - * stream. This must not be larger than \c 15 Bytes. - * \param nonce_counter The 128-bit nonce and counter. This must point to - * a read/write buffer of length \c 16 bytes. - * \param stream_block The saved stream block for resuming. This must - * point to a read/write buffer of length \c 16 bytes. - * This is overwritten by the function. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must - * be a writable buffer of length \p length Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine. - * - * \return \c 0 on success, or \c 1 on failure. - */ -int mbedtls_aria_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* aria.h */ diff --git a/vendor/mbedtls/include/mbedtls/asn1.h b/vendor/mbedtls/include/mbedtls/asn1.h deleted file mode 100644 index ff019f432..000000000 --- a/vendor/mbedtls/include/mbedtls/asn1.h +++ /dev/null @@ -1,642 +0,0 @@ -/** - * \file asn1.h - * - * \brief Generic ASN.1 parsing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_ASN1_H -#define MBEDTLS_ASN1_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -/** - * \addtogroup asn1_module - * \{ - */ - -/** - * \name ASN1 Error codes - * These error codes are combined with other error codes for - * higher error granularity. - * e.g. X.509 and PKCS #7 error codes - * ASN1 is a standard to specify data structures. - * \{ - */ -/** Out of data when parsing an ASN1 data structure. */ -#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 -/** ASN1 tag was of an unexpected value. */ -#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 -/** Error when trying to determine the length or invalid length. */ -#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 -/** Actual length differs from expected length. */ -#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 -/** Data is invalid. */ -#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 -/** Memory allocation failed */ -#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A -/** Buffer too small when writing ASN.1 data structure. */ -#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C - -/** \} name ASN1 Error codes */ - -/** - * \name DER constants - * These constants comply with the DER encoded ASN.1 type tags. - * DER encoding uses hexadecimal representation. - * An example DER sequence is:\n - * - 0x02 -- tag indicating INTEGER - * - 0x01 -- length in octets - * - 0x05 -- value - * Such sequences are typically read into \c ::mbedtls_x509_buf. - * \{ - */ -#define MBEDTLS_ASN1_BOOLEAN 0x01 -#define MBEDTLS_ASN1_INTEGER 0x02 -#define MBEDTLS_ASN1_BIT_STRING 0x03 -#define MBEDTLS_ASN1_OCTET_STRING 0x04 -#define MBEDTLS_ASN1_NULL 0x05 -#define MBEDTLS_ASN1_OID 0x06 -#define MBEDTLS_ASN1_ENUMERATED 0x0A -#define MBEDTLS_ASN1_UTF8_STRING 0x0C -#define MBEDTLS_ASN1_SEQUENCE 0x10 -#define MBEDTLS_ASN1_SET 0x11 -#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13 -#define MBEDTLS_ASN1_T61_STRING 0x14 -#define MBEDTLS_ASN1_IA5_STRING 0x16 -#define MBEDTLS_ASN1_UTC_TIME 0x17 -#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18 -#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C -#define MBEDTLS_ASN1_BMP_STRING 0x1E -#define MBEDTLS_ASN1_PRIMITIVE 0x00 -#define MBEDTLS_ASN1_CONSTRUCTED 0x20 -#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 - -/* Slightly smaller way to check if tag is a string tag - * compared to canonical implementation. */ -#define MBEDTLS_ASN1_IS_STRING_TAG(tag) \ - ((unsigned int) (tag) < 32u && ( \ - ((1u << (tag)) & ((1u << MBEDTLS_ASN1_BMP_STRING) | \ - (1u << MBEDTLS_ASN1_UTF8_STRING) | \ - (1u << MBEDTLS_ASN1_T61_STRING) | \ - (1u << MBEDTLS_ASN1_IA5_STRING) | \ - (1u << MBEDTLS_ASN1_UNIVERSAL_STRING) | \ - (1u << MBEDTLS_ASN1_PRINTABLE_STRING))) != 0)) - -/* - * Bit masks for each of the components of an ASN.1 tag as specified in - * ITU X.690 (08/2015), section 8.1 "General rules for encoding", - * paragraph 8.1.2.2: - * - * Bit 8 7 6 5 1 - * +-------+-----+------------+ - * | Class | P/C | Tag number | - * +-------+-----+------------+ - */ -#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0 -#define MBEDTLS_ASN1_TAG_PC_MASK 0x20 -#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F - -/** \} name DER constants */ - -/** Returns the size of the binary string, without the trailing \\0 */ -#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1) - -/** - * Compares an mbedtls_asn1_buf structure to a reference OID. - * - * Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a - * 'unsigned char *oid' here! - */ -#define MBEDTLS_OID_CMP(oid_str, oid_buf) \ - ((MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len) || \ - memcmp((oid_str), (oid_buf)->p, (oid_buf)->len) != 0) - -#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \ - ((MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len)) || \ - memcmp((oid_str), (oid_buf), (oid_buf_len)) != 0) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Functions to parse ASN.1 data structures - * \{ - */ - -/** - * Type-length-value structure that allows for ASN1 using DER. - */ -typedef struct mbedtls_asn1_buf { - int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */ - size_t len; /**< ASN1 length, in octets. */ - unsigned char *p; /**< ASN1 data, e.g. in ASCII. */ -} -mbedtls_asn1_buf; - -/** - * Container for ASN1 bit strings. - */ -typedef struct mbedtls_asn1_bitstring { - size_t len; /**< ASN1 length, in octets. */ - unsigned char unused_bits; /**< Number of unused bits at the end of the string */ - unsigned char *p; /**< Raw ASN1 data for the bit string */ -} -mbedtls_asn1_bitstring; - -/** - * Container for a sequence of ASN.1 items - */ -typedef struct mbedtls_asn1_sequence { - mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */ - - /** The next entry in the sequence. - * - * The details of memory management for sequences are not documented and - * may change in future versions. Set this field to \p NULL when - * initializing a structure, and do not modify it except via Mbed TLS - * library functions. - */ - struct mbedtls_asn1_sequence *next; -} -mbedtls_asn1_sequence; - -/** - * Container for a sequence or list of 'named' ASN.1 data items - */ -typedef struct mbedtls_asn1_named_data { - mbedtls_asn1_buf oid; /**< The object identifier. */ - mbedtls_asn1_buf val; /**< The named value. */ - - /** The next entry in the sequence. - * - * The details of memory management for named data sequences are not - * documented and may change in future versions. Set this field to \p NULL - * when initializing a structure, and do not modify it except via Mbed TLS - * library functions. - */ - struct mbedtls_asn1_named_data *next; - - /** Merge next item into the current one? - * - * This field exists for the sake of Mbed TLS's X.509 certificate parsing - * code and may change in future versions of the library. - */ - unsigned char MBEDTLS_PRIVATE(next_merged); -} -mbedtls_asn1_named_data; - -#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \ - defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) -/** - * \brief Get the length of an ASN.1 element. - * Updates the pointer to immediately behind the length. - * - * \param p On entry, \c *p points to the first byte of the length, - * i.e. immediately after the tag. - * On successful completion, \c *p points to the first byte - * after the length, i.e. the first byte of the content. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param len On successful completion, \c *len contains the length - * read from the ASN.1 input. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element - * would end beyond \p end. - * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable. - */ -int mbedtls_asn1_get_len(unsigned char **p, - const unsigned char *end, - size_t *len); - -/** - * \brief Get the tag and length of the element. - * Check for the requested tag. - * Updates the pointer to immediately behind the tag and length. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * after the length, i.e. the first byte of the content. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param len On successful completion, \c *len contains the length - * read from the ASN.1 input. - * \param tag The expected tag. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start - * with the requested tag. - * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element - * would end beyond \p end. - * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable. - */ -int mbedtls_asn1_get_tag(unsigned char **p, - const unsigned char *end, - size_t *len, int tag); -#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */ - -#if defined(MBEDTLS_ASN1_PARSE_C) -/** - * \brief Retrieve a boolean ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * beyond the ASN.1 element. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param val On success, the parsed value (\c 0 or \c 1). - * - * \return 0 if successful. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 BOOLEAN. - */ -int mbedtls_asn1_get_bool(unsigned char **p, - const unsigned char *end, - int *val); - -/** - * \brief Retrieve an integer ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * beyond the ASN.1 element. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param val On success, the parsed value. - * - * \return 0 if successful. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 INTEGER. - * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does - * not fit in an \c int. - */ -int mbedtls_asn1_get_int(unsigned char **p, - const unsigned char *end, - int *val); - -/** - * \brief Retrieve an enumerated ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * beyond the ASN.1 element. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param val On success, the parsed value. - * - * \return 0 if successful. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 ENUMERATED. - * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does - * not fit in an \c int. - */ -int mbedtls_asn1_get_enum(unsigned char **p, - const unsigned char *end, - int *val); - -/** - * \brief Retrieve a bitstring ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p is equal to \p end. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param bs On success, ::mbedtls_asn1_bitstring information about - * the parsed value. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains - * extra data after a valid BIT STRING. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 BIT STRING. - */ -int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end, - mbedtls_asn1_bitstring *bs); - -/** - * \brief Retrieve a bitstring ASN.1 tag without unused bits and its - * value. - * Updates the pointer to the beginning of the bit/octet string. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * of the content of the BIT STRING. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param len On success, \c *len is the length of the content in bytes. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with - * a valid BIT STRING with a nonzero number of unused bits. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 BIT STRING. - */ -int mbedtls_asn1_get_bitstring_null(unsigned char **p, - const unsigned char *end, - size_t *len); - -/** - * \brief Parses and splits an ASN.1 "SEQUENCE OF ". - * Updates the pointer to immediately behind the full sequence tag. - * - * This function allocates memory for the sequence elements. You can free - * the allocated memory with mbedtls_asn1_sequence_free(). - * - * \note On error, this function may return a partial list in \p cur. - * You must set `cur->next = NULL` before calling this function! - * Otherwise it is impossible to distinguish a previously non-null - * pointer from a pointer to an object allocated by this function. - * - * \note If the sequence is empty, this function does not modify - * \c *cur. If the sequence is valid and non-empty, this - * function sets `cur->buf.tag` to \p tag. This allows - * callers to distinguish between an empty sequence and - * a one-element sequence. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p is equal to \p end. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param cur A ::mbedtls_asn1_sequence which this function fills. - * When this function returns, \c *cur is the head of a linked - * list. Each node in this list is allocated with - * mbedtls_calloc() apart from \p cur itself, and should - * therefore be freed with mbedtls_free(). - * The list describes the content of the sequence. - * The head of the list (i.e. \c *cur itself) describes the - * first element, `*cur->next` describes the second element, etc. - * For each element, `buf.tag == tag`, `buf.len` is the length - * of the content of the content of the element, and `buf.p` - * points to the first byte of the content (i.e. immediately - * past the length of the element). - * Note that list elements may be allocated even on error. - * \param tag Each element of the sequence must have this tag. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains - * extra data after a valid SEQUENCE OF \p tag. - * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with - * an ASN.1 SEQUENCE in which an element has a tag that - * is different from \p tag. - * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 SEQUENCE. - */ -int mbedtls_asn1_get_sequence_of(unsigned char **p, - const unsigned char *end, - mbedtls_asn1_sequence *cur, - int tag); -/** - * \brief Free a heap-allocated linked list presentation of - * an ASN.1 sequence, including the first element. - * - * There are two common ways to manage the memory used for the representation - * of a parsed ASN.1 sequence: - * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc(). - * Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of(). - * When you have finished processing the sequence, - * call mbedtls_asn1_sequence_free() on `head`. - * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner, - * for example on the stack. Make sure that `head->next == NULL`. - * Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of(). - * When you have finished processing the sequence, - * call mbedtls_asn1_sequence_free() on `head->cur`, - * then free `head` itself in the appropriate manner. - * - * \param seq The address of the first sequence component. This may - * be \c NULL, in which case this functions returns - * immediately. - */ -void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq); - -/** - * \brief Traverse an ASN.1 SEQUENCE container and - * call a callback for each entry. - * - * This function checks that the input is a SEQUENCE of elements that - * each have a "must" tag, and calls a callback function on the elements - * that have a "may" tag. - * - * For example, to validate that the input is a SEQUENCE of `tag1` and call - * `cb` on each element, use - * ``` - * mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx); - * ``` - * - * To validate that the input is a SEQUENCE of ANY and call `cb` on - * each element, use - * ``` - * mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx); - * ``` - * - * To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING} - * and call `cb` on each element that is an OCTET STRING, use - * ``` - * mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx); - * ``` - * - * The callback is called on the elements with a "may" tag from left to - * right. If the input is not a valid SEQUENCE of elements with a "must" tag, - * the callback is called on the elements up to the leftmost point where - * the input is invalid. - * - * \warning This function is still experimental and may change - * at any time. - * - * \param p The address of the pointer to the beginning of - * the ASN.1 SEQUENCE header. This is updated to - * point to the end of the ASN.1 SEQUENCE container - * on a successful invocation. - * \param end The end of the ASN.1 SEQUENCE container. - * \param tag_must_mask A mask to be applied to the ASN.1 tags found within - * the SEQUENCE before comparing to \p tag_must_val. - * \param tag_must_val The required value of each ASN.1 tag found in the - * SEQUENCE, after masking with \p tag_must_mask. - * Mismatching tags lead to an error. - * For example, a value of \c 0 for both \p tag_must_mask - * and \p tag_must_val means that every tag is allowed, - * while a value of \c 0xFF for \p tag_must_mask means - * that \p tag_must_val is the only allowed tag. - * \param tag_may_mask A mask to be applied to the ASN.1 tags found within - * the SEQUENCE before comparing to \p tag_may_val. - * \param tag_may_val The desired value of each ASN.1 tag found in the - * SEQUENCE, after masking with \p tag_may_mask. - * Mismatching tags will be silently ignored. - * For example, a value of \c 0 for \p tag_may_mask and - * \p tag_may_val means that any tag will be considered, - * while a value of \c 0xFF for \p tag_may_mask means - * that all tags with value different from \p tag_may_val - * will be ignored. - * \param cb The callback to trigger for each component - * in the ASN.1 SEQUENCE that matches \p tag_may_val. - * The callback function is called with the following - * parameters: - * - \p ctx. - * - The tag of the current element. - * - A pointer to the start of the current element's - * content inside the input. - * - The length of the content of the current element. - * If the callback returns a non-zero value, - * the function stops immediately, - * forwarding the callback's return value. - * \param ctx The context to be passed to the callback \p cb. - * - * \return \c 0 if successful the entire ASN.1 SEQUENCE - * was traversed without parsing or callback errors. - * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input - * contains extra data after a valid SEQUENCE - * of elements with an accepted tag. - * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts - * with an ASN.1 SEQUENCE in which an element has a tag - * that is not accepted. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 SEQUENCE. - * \return A non-zero error code forwarded from the callback - * \p cb in case the latter returns a non-zero value. - */ -int mbedtls_asn1_traverse_sequence_of( - unsigned char **p, - const unsigned char *end, - unsigned char tag_must_mask, unsigned char tag_must_val, - unsigned char tag_may_mask, unsigned char tag_may_val, - int (*cb)(void *ctx, int tag, - unsigned char *start, size_t len), - void *ctx); - -#if defined(MBEDTLS_BIGNUM_C) -/** - * \brief Retrieve an integer ASN.1 tag and its value. - * Updates the pointer to immediately behind the full tag. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * beyond the ASN.1 element. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param X On success, the parsed value. - * - * \return 0 if successful. - * \return An ASN.1 error code if the input does not start with - * a valid ASN.1 INTEGER. - * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does - * not fit in an \c int. - * \return An MPI error code if the parsed value is too large. - */ -int mbedtls_asn1_get_mpi(unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X); -#endif /* MBEDTLS_BIGNUM_C */ - -/** - * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence. - * Updates the pointer to immediately behind the full - * AlgorithmIdentifier. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * beyond the AlgorithmIdentifier element. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param alg The buffer to receive the OID. - * \param params The buffer to receive the parameters. - * This is zeroized if there are no parameters. - * - * \return 0 if successful or a specific ASN.1 or MPI error code. - */ -int mbedtls_asn1_get_alg(unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params); - -/** - * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no - * params. - * Updates the pointer to immediately behind the full - * AlgorithmIdentifier. - * - * \param p On entry, \c *p points to the start of the ASN.1 element. - * On successful completion, \c *p points to the first byte - * beyond the AlgorithmIdentifier element. - * On error, the value of \c *p is undefined. - * \param end End of data. - * \param alg The buffer to receive the OID. - * - * \return 0 if successful or a specific ASN.1 or MPI error code. - */ -int mbedtls_asn1_get_alg_null(unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg); - -/** - * \brief Find a specific named_data entry in a sequence or list based on - * the OID. - * - * \param list The list to seek through - * \param oid The OID to look for - * \param len Size of the OID - * - * \return NULL if not found, or a pointer to the existing entry. - */ -const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list, - const char *oid, size_t len); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief Free a mbedtls_asn1_named_data entry - * - * \deprecated This function is deprecated and will be removed in a - * future version of the library. - * Please use mbedtls_asn1_free_named_data_list() - * or mbedtls_asn1_free_named_data_list_shallow(). - * - * \param entry The named data entry to free. - * This function calls mbedtls_free() on - * `entry->oid.p` and `entry->val.p`. - */ -void MBEDTLS_DEPRECATED mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *entry); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Free all entries in a mbedtls_asn1_named_data list. - * - * \param head Pointer to the head of the list of named data entries to free. - * This function calls mbedtls_free() on - * `entry->oid.p` and `entry->val.p` and then on `entry` - * for each list entry, and sets \c *head to \c NULL. - */ -void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head); - -/** - * \brief Free all shallow entries in a mbedtls_asn1_named_data list, - * but do not free internal pointer targets. - * - * \param name Head of the list of named data entries to free. - * This function calls mbedtls_free() on each list element. - */ -void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name); - -/** \} name Functions to parse ASN.1 data structures */ -/** \} addtogroup asn1_module */ - -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* asn1.h */ diff --git a/vendor/mbedtls/include/mbedtls/asn1write.h b/vendor/mbedtls/include/mbedtls/asn1write.h deleted file mode 100644 index 9a1062a58..000000000 --- a/vendor/mbedtls/include/mbedtls/asn1write.h +++ /dev/null @@ -1,390 +0,0 @@ -/** - * \file asn1write.h - * - * \brief ASN.1 buffer writing functionality - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_ASN1_WRITE_H -#define MBEDTLS_ASN1_WRITE_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/asn1.h" - -#define MBEDTLS_ASN1_CHK_ADD(g, f) \ - do \ - { \ - if ((ret = (f)) < 0) \ - return ret; \ - else \ - (g) += ret; \ - } while (0) - -#define MBEDTLS_ASN1_CHK_CLEANUP_ADD(g, f) \ - do \ - { \ - if ((ret = (f)) < 0) \ - goto cleanup; \ - else \ - (g) += ret; \ - } while (0) - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \ - defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) -/** - * \brief Write a length field in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param len The length value to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start, - size_t len); -/** - * \brief Write an ASN.1 tag in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param tag The tag to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, - unsigned char tag); -#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA*/ - -#if defined(MBEDTLS_ASN1_WRITE_C) -/** - * \brief Write raw buffer data. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The data buffer to write. - * \param size The length of the data buffer. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start, - const unsigned char *buf, size_t size); - -#if defined(MBEDTLS_BIGNUM_C) -/** - * \brief Write an arbitrary-precision number (#MBEDTLS_ASN1_INTEGER) - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param X The MPI to write. - * It must be non-negative. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start, - const mbedtls_mpi *X); -#endif /* MBEDTLS_BIGNUM_C */ - -/** - * \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_null(unsigned char **p, const unsigned char *start); - -/** - * \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param oid The OID to write. - * \param oid_len The length of the OID. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start, - const char *oid, size_t oid_len); - -/** - * \brief Write an AlgorithmIdentifier sequence in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param oid The OID of the algorithm to write. - * \param oid_len The length of the algorithm's OID. - * \param par_len The length of the parameters, which must be already written. - * If 0, NULL parameters are added - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, - const unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len); - -/** - * \brief Write an AlgorithmIdentifier sequence in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param oid The OID of the algorithm to write. - * \param oid_len The length of the algorithm's OID. - * \param par_len The length of the parameters, which must be already written. - * \param has_par If there are any parameters. If 0, par_len must be 0. If 1 - * and \p par_len is 0, NULL parameters are added. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, - const unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len, int has_par); - -/** - * \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param boolean The boolean value to write, either \c 0 or \c 1. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_bool(unsigned char **p, const unsigned char *start, - int boolean); - -/** - * \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param val The integer value to write. - * It must be non-negative. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_int(unsigned char **p, const unsigned char *start, int val); - -/** - * \brief Write an enum tag (#MBEDTLS_ASN1_ENUMERATED) and value - * in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param val The integer value to write. - * - * \return The number of bytes written to \p p on success. - * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_asn1_write_enum(unsigned char **p, const unsigned char *start, int val); - -/** - * \brief Write a string in ASN.1 format using a specific - * string encoding tag. - - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param tag The string encoding tag to write, e.g. - * #MBEDTLS_ASN1_UTF8_STRING. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_tagged_string(unsigned char **p, const unsigned char *start, - int tag, const char *text, - size_t text_len); - -/** - * \brief Write a string in ASN.1 format using the PrintableString - * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_printable_string(unsigned char **p, - const unsigned char *start, - const char *text, size_t text_len); - -/** - * \brief Write a UTF8 string in ASN.1 format using the UTF8String - * string encoding tag (#MBEDTLS_ASN1_UTF8_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_utf8_string(unsigned char **p, const unsigned char *start, - const char *text, size_t text_len); - -/** - * \brief Write a string in ASN.1 format using the IA5String - * string encoding tag (#MBEDTLS_ASN1_IA5_STRING). - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param text The string to write. - * \param text_len The length of \p text in bytes (which might - * be strictly larger than the number of characters). - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_ia5_string(unsigned char **p, const unsigned char *start, - const char *text, size_t text_len); - -/** - * \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and - * value in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The bitstring to write. - * \param bits The total number of bits in the bitstring. - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_bitstring(unsigned char **p, const unsigned char *start, - const unsigned char *buf, size_t bits); - -/** - * \brief This function writes a named bitstring tag - * (#MBEDTLS_ASN1_BIT_STRING) and value in ASN.1 format. - * - * As stated in RFC 5280 Appendix B, trailing zeroes are - * omitted when encoding named bitstrings in DER. - * - * \note This function works backwards within the data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer which is used for bounds-checking. - * \param buf The bitstring to write. - * \param bits The total number of bits in the bitstring. - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_named_bitstring(unsigned char **p, - const unsigned char *start, - const unsigned char *buf, - size_t bits); - -/** - * \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING) - * and value in ASN.1 format. - * - * \note This function works backwards in data buffer. - * - * \param p The reference to the current position pointer. - * \param start The start of the buffer, for bounds-checking. - * \param buf The buffer holding the data to write. - * \param size The length of the data buffer \p buf. - * - * \return The number of bytes written to \p p on success. - * \return A negative error code on failure. - */ -int mbedtls_asn1_write_octet_string(unsigned char **p, const unsigned char *start, - const unsigned char *buf, size_t size); - -/** - * \brief Create or find a specific named_data entry for writing in a - * sequence or list based on the OID. If not already in there, - * a new entry is added to the head of the list. - * Warning: Destructive behaviour for the val data! - * - * \param list The pointer to the location of the head of the list to seek - * through (will be updated in case of a new entry). - * \param oid The OID to look for. - * \param oid_len The size of the OID. - * \param val The associated data to store. If this is \c NULL, - * no data is copied to the new or existing buffer. - * \param val_len The minimum length of the data buffer needed. - * If this is 0, do not allocate a buffer for the associated - * data. - * If the OID was already present, enlarge, shrink or free - * the existing buffer to fit \p val_len. - * - * \return A pointer to the new / existing entry on success. - * \return \c NULL if there was a memory allocation error. - */ -mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data **list, - const char *oid, size_t oid_len, - const unsigned char *val, - size_t val_len); - -#endif /* MBEDTLS_ASN1_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_ASN1_WRITE_H */ diff --git a/vendor/mbedtls/include/mbedtls/base64.h b/vendor/mbedtls/include/mbedtls/base64.h deleted file mode 100644 index 8f459b74c..000000000 --- a/vendor/mbedtls/include/mbedtls/base64.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * \file base64.h - * - * \brief RFC 1521 base64 encoding/decoding - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_BASE64_H -#define MBEDTLS_BASE64_H - -#include "mbedtls/build_info.h" - -#include - -/** Output buffer too small. */ -#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A -/** Invalid character in input. */ -#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Encode a buffer into base64 format - * - * \param dst destination buffer - * \param dlen size of the destination buffer - * \param olen number of bytes written - * \param src source buffer - * \param slen amount of data to be encoded - * - * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. - * *olen is always updated to reflect the amount - * of data that has (or would have) been written. - * If that length cannot be represented, then no data is - * written to the buffer and *olen is set to the maximum - * length representable as a size_t. - * - * \note Call this function with dlen = 0 to obtain the - * required buffer size in *olen - */ -int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen); - -/** - * \brief Decode a base64-formatted buffer - * - * \param dst destination buffer (can be NULL for checking size) - * \param dlen size of the destination buffer - * \param olen number of bytes written - * \param src source buffer - * \param slen amount of data to be decoded - * - * \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or - * MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is - * not correct. *olen is always updated to reflect the amount - * of data that has (or would have) been written. - * - * \note Call this function with *dst = NULL or dlen = 0 to obtain - * the required buffer size in *olen - */ -int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_base64_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* base64.h */ diff --git a/vendor/mbedtls/include/mbedtls/bignum.h b/vendor/mbedtls/include/mbedtls/bignum.h deleted file mode 100644 index 618785671..000000000 --- a/vendor/mbedtls/include/mbedtls/bignum.h +++ /dev/null @@ -1,1088 +0,0 @@ -/** - * \file bignum.h - * - * \brief Multi-precision integer library - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_BIGNUM_H -#define MBEDTLS_BIGNUM_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -/** An error occurred while reading from or writing to a file. */ -#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 -/** There is an invalid character in the digit string. */ -#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 -/** The buffer is too small to write to. */ -#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 -/** The input arguments are negative or result in illegal output. */ -#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A -/** The input argument for division is zero, which is not allowed. */ -#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C -/** The input arguments are not acceptable. */ -#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E -/** Memory allocation failed. */ -#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 - -#define MBEDTLS_MPI_CHK(f) \ - do \ - { \ - if ((ret = (f)) != 0) \ - goto cleanup; \ - } while (0) - -/* - * Maximum size MPIs are allowed to grow to in number of limbs. - */ -#define MBEDTLS_MPI_MAX_LIMBS 10000 - -#if !defined(MBEDTLS_MPI_WINDOW_SIZE) -/* - * Maximum window size used for modular exponentiation. Default: 3 - * Minimum value: 1. Maximum value: 6. - * - * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used - * for the sliding window calculation. (So 8 by default) - * - * Reduction in size, reduces speed. - */ -#define MBEDTLS_MPI_WINDOW_SIZE 3 /**< Maximum window size used. */ -#endif /* !MBEDTLS_MPI_WINDOW_SIZE */ - -#if !defined(MBEDTLS_MPI_MAX_SIZE) -/* - * Maximum size of MPIs allowed in bits and bytes for user-MPIs. - * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) - * - * Note: Calculations can temporarily result in larger MPIs. So the number - * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. - */ -#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ -#endif /* !MBEDTLS_MPI_MAX_SIZE */ - -#define MBEDTLS_MPI_MAX_BITS (8 * MBEDTLS_MPI_MAX_SIZE) /**< Maximum number of bits for usable MPIs. */ - -/* - * When reading from files with mbedtls_mpi_read_file() and writing to files with - * mbedtls_mpi_write_file() the buffer should have space - * for a (short) label, the MPI (in the provided radix), the newline - * characters and the '\0'. - * - * By default we assume at least a 10 char label, a minimum radix of 10 - * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). - * Autosized at compile time for at least a 10 char label, a minimum radix - * of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size. - * - * This used to be statically sized to 1250 for a maximum of 4096 bit - * numbers (1234 decimal chars). - * - * Calculate using the formula: - * MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) + - * LabelSize + 6 - */ -#define MBEDTLS_MPI_MAX_BITS_SCALE100 (100 * MBEDTLS_MPI_MAX_BITS) -#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332 -#define MBEDTLS_MPI_RW_BUFFER_SIZE (((MBEDTLS_MPI_MAX_BITS_SCALE100 + \ - MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / \ - MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6) - -/* - * Define the base integer type, architecture-wise. - * - * 32 or 64-bit integer types can be forced regardless of the underlying - * architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 - * respectively and undefining MBEDTLS_HAVE_ASM. - * - * Double-width integers (e.g. 128-bit in 64-bit architectures) can be - * disabled by defining MBEDTLS_NO_UDBL_DIVISION. - */ -#if !defined(MBEDTLS_HAVE_INT32) - #if defined(_MSC_VER) && defined(_M_AMD64) -/* Always choose 64-bit when using MSC */ - #if !defined(MBEDTLS_HAVE_INT64) - #define MBEDTLS_HAVE_INT64 - #endif /* !MBEDTLS_HAVE_INT64 */ -typedef int64_t mbedtls_mpi_sint; -typedef uint64_t mbedtls_mpi_uint; -#define MBEDTLS_MPI_UINT_MAX UINT64_MAX - #elif defined(__GNUC__) && ( \ - defined(__amd64__) || defined(__x86_64__) || \ - defined(__ppc64__) || defined(__powerpc64__) || \ - defined(__ia64__) || defined(__alpha__) || \ - (defined(__sparc__) && defined(__arch64__)) || \ - defined(__s390x__) || defined(__mips64) || \ - defined(__aarch64__)) - #if !defined(MBEDTLS_HAVE_INT64) - #define MBEDTLS_HAVE_INT64 - #endif /* MBEDTLS_HAVE_INT64 */ -typedef int64_t mbedtls_mpi_sint; -typedef uint64_t mbedtls_mpi_uint; -#define MBEDTLS_MPI_UINT_MAX UINT64_MAX - #if !defined(MBEDTLS_NO_UDBL_DIVISION) -/* mbedtls_t_udbl defined as 128-bit unsigned int */ -typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); - #define MBEDTLS_HAVE_UDBL - #endif /* !MBEDTLS_NO_UDBL_DIVISION */ - #elif defined(__ARMCC_VERSION) && defined(__aarch64__) -/* - * __ARMCC_VERSION is defined for both armcc and armclang and - * __aarch64__ is only defined by armclang when compiling 64-bit code - */ - #if !defined(MBEDTLS_HAVE_INT64) - #define MBEDTLS_HAVE_INT64 - #endif /* !MBEDTLS_HAVE_INT64 */ -typedef int64_t mbedtls_mpi_sint; -typedef uint64_t mbedtls_mpi_uint; -#define MBEDTLS_MPI_UINT_MAX UINT64_MAX - #if !defined(MBEDTLS_NO_UDBL_DIVISION) -/* mbedtls_t_udbl defined as 128-bit unsigned int */ -typedef __uint128_t mbedtls_t_udbl; - #define MBEDTLS_HAVE_UDBL - #endif /* !MBEDTLS_NO_UDBL_DIVISION */ - #elif defined(MBEDTLS_HAVE_INT64) -/* Force 64-bit integers with unknown compiler */ -typedef int64_t mbedtls_mpi_sint; -typedef uint64_t mbedtls_mpi_uint; -#define MBEDTLS_MPI_UINT_MAX UINT64_MAX - #endif -#endif /* !MBEDTLS_HAVE_INT32 */ - -#if !defined(MBEDTLS_HAVE_INT64) -/* Default to 32-bit compilation */ - #if !defined(MBEDTLS_HAVE_INT32) - #define MBEDTLS_HAVE_INT32 - #endif /* !MBEDTLS_HAVE_INT32 */ -typedef int32_t mbedtls_mpi_sint; -typedef uint32_t mbedtls_mpi_uint; -#define MBEDTLS_MPI_UINT_MAX UINT32_MAX - #if !defined(MBEDTLS_NO_UDBL_DIVISION) -typedef uint64_t mbedtls_t_udbl; - #define MBEDTLS_HAVE_UDBL - #endif /* !MBEDTLS_NO_UDBL_DIVISION */ -#endif /* !MBEDTLS_HAVE_INT64 */ - -/* - * Sanity check that exactly one of MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 is defined, - * so that code elsewhere doesn't have to check. - */ -#if (!(defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64))) || \ - (defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64)) -#error "Only 32-bit or 64-bit limbs are supported in bignum" -#endif - -/** \typedef mbedtls_mpi_uint - * \brief The type of machine digits in a bignum, called _limbs_. - * - * This is always an unsigned integer type with no padding bits. The size - * is platform-dependent. - */ - -/** \typedef mbedtls_mpi_sint - * \brief The signed type corresponding to #mbedtls_mpi_uint. - * - * This is always an signed integer type with no padding bits. The size - * is platform-dependent. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MPI structure - */ -typedef struct mbedtls_mpi { - /** Pointer to limbs. - * - * This may be \c NULL if \c n is 0. - */ - mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); - - /** Sign: -1 if the mpi is negative, 1 otherwise. - * - * The number 0 must be represented with `s = +1`. Although many library - * functions treat all-limbs-zero as equivalent to a valid representation - * of 0 regardless of the sign bit, there are exceptions, so bignum - * functions and external callers must always set \c s to +1 for the - * number zero. - * - * Note that this implies that calloc() or `... = {0}` does not create - * a valid MPI representation. You must call mbedtls_mpi_init(). - */ - signed short MBEDTLS_PRIVATE(s); - - /** Total number of limbs in \c p. */ - unsigned short MBEDTLS_PRIVATE(n); - /* Make sure that MBEDTLS_MPI_MAX_LIMBS fits in n. - * Use the same limit value on all platforms so that we don't have to - * think about different behavior on the rare platforms where - * unsigned short can store values larger than the minimum required by - * the C language, which is 65535. - */ -#if MBEDTLS_MPI_MAX_LIMBS > 65535 -#error "MBEDTLS_MPI_MAX_LIMBS > 65535 is not supported" -#endif -} -mbedtls_mpi; - -/** - * \brief Initialize an MPI context. - * - * This makes the MPI ready to be set or freed, - * but does not define a value for the MPI. - * - * \param X The MPI context to initialize. This must not be \c NULL. - */ -void mbedtls_mpi_init(mbedtls_mpi *X); - -/** - * \brief This function frees the components of an MPI context. - * - * \param X The MPI context to be cleared. This may be \c NULL, - * in which case this function is a no-op. If it is - * not \c NULL, it must point to an initialized MPI. - */ -void mbedtls_mpi_free(mbedtls_mpi *X); - -/** - * \brief Enlarge an MPI to the specified number of limbs. - * - * \note This function does nothing if the MPI is - * already large enough. - * - * \param X The MPI to grow. It must be initialized. - * \param nblimbs The target number of limbs. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs); - -/** - * \brief This function resizes an MPI downwards, keeping at least the - * specified number of limbs. - * - * If \c X is smaller than \c nblimbs, it is resized up - * instead. - * - * \param X The MPI to shrink. This must point to an initialized MPI. - * \param nblimbs The minimum number of limbs to keep. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed - * (this can only happen when resizing up). - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs); - -/** - * \brief Make a copy of an MPI. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param Y The source MPI. This must point to an initialized MPI. - * - * \note The limb-buffer in the destination MPI is enlarged - * if necessary to hold the value in the source MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y); - -/** - * \brief Swap the contents of two MPIs. - * - * \param X The first MPI. It must be initialized. - * \param Y The second MPI. It must be initialized. - */ -void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y); - -/** - * \brief Perform a safe conditional copy of MPI which doesn't - * reveal whether the condition was true or not. - * - * \param X The MPI to conditionally assign to. This must point - * to an initialized MPI. - * \param Y The MPI to be assigned from. This must point to an - * initialized MPI. - * \param assign The condition deciding whether to perform the - * assignment or not. Must be either 0 or 1: - * * \c 1: Perform the assignment `X = Y`. - * * \c 0: Keep the original value of \p X. - * - * \note This function is equivalent to - * `if( assign ) mbedtls_mpi_copy( X, Y );` - * except that it avoids leaking any information about whether - * the assignment was done or not (the above code may leak - * information through branch prediction and/or memory access - * patterns analysis). - * - * \warning If \p assign is neither 0 nor 1, the result of this function - * is indeterminate, and the resulting value in \p X might be - * neither its original value nor the value in \p Y. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign); - -/** - * \brief Perform a safe conditional swap which doesn't - * reveal whether the condition was true or not. - * - * \param X The first MPI. This must be initialized. - * \param Y The second MPI. This must be initialized. - * \param swap The condition deciding whether to perform - * the swap or not. Must be either 0 or 1: - * * \c 1: Swap the values of \p X and \p Y. - * * \c 0: Keep the original values of \p X and \p Y. - * - * \note This function is equivalent to - * if( swap ) mbedtls_mpi_swap( X, Y ); - * except that it avoids leaking any information about whether - * the swap was done or not (the above code may leak - * information through branch prediction and/or memory access - * patterns analysis). - * - * \warning If \p swap is neither 0 nor 1, the result of this function - * is indeterminate, and both \p X and \p Y might end up with - * values different to either of the original ones. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - * - */ -int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap); - -/** - * \brief Store integer value in MPI. - * - * \param X The MPI to set. This must be initialized. - * \param z The value to use. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z); - -/** - * \brief Get a specific bit from an MPI. - * - * \param X The MPI to query. This must be initialized. - * \param pos Zero-based index of the bit to query. - * - * \return \c 0 or \c 1 on success, depending on whether bit \c pos - * of \c X is unset or set. - * \return A negative error code on failure. - */ -int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos); - -/** - * \brief Modify a specific bit in an MPI. - * - * \note This function will grow the target MPI if necessary to set a - * bit to \c 1 in a not yet existing limb. It will not grow if - * the bit should be set to \c 0. - * - * \param X The MPI to modify. This must be initialized. - * \param pos Zero-based index of the bit to modify. - * \param val The desired value of bit \c pos: \c 0 or \c 1. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val); - -/** - * \brief Return the number of bits of value \c 0 before the - * least significant bit of value \c 1. - * - * \note This is the same as the zero-based index of - * the least significant bit of value \c 1. - * - * \param X The MPI to query. - * - * \return The number of bits of value \c 0 before the least significant - * bit of value \c 1 in \p X. - */ -size_t mbedtls_mpi_lsb(const mbedtls_mpi *X); - -/** - * \brief Return the number of bits up to and including the most - * significant bit of value \c 1. - * - * * \note This is same as the one-based index of the most - * significant bit of value \c 1. - * - * \param X The MPI to query. This must point to an initialized MPI. - * - * \return The number of bits up to and including the most - * significant bit of value \c 1. - */ -size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X); - -/** - * \brief Return the total size of an MPI value in bytes. - * - * \param X The MPI to use. This must point to an initialized MPI. - * - * \note The value returned by this function may be less than - * the number of bytes used to store \p X internally. - * This happens if and only if there are trailing bytes - * of value zero. - * - * \return The least number of bytes capable of storing - * the absolute value of \p X. - */ -size_t mbedtls_mpi_size(const mbedtls_mpi *X); - -/** - * \brief Import an MPI from an ASCII string. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param radix The numeric base of the input string. - * \param s Null-terminated string buffer. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s); - -/** - * \brief Export an MPI to an ASCII string. - * - * \param X The source MPI. This must point to an initialized MPI. - * \param radix The numeric base of the output string. - * \param buf The buffer to write the string to. This must be writable - * buffer of length \p buflen Bytes. - * \param buflen The available size in Bytes of \p buf. - * \param olen The address at which to store the length of the string - * written, including the final \c NULL byte. This must - * not be \c NULL. - * - * \note You can call this function with `buflen == 0` to obtain the - * minimum required buffer size in `*olen`. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf - * is too small to hold the value of \p X in the desired base. - * In this case, `*olen` is nonetheless updated to contain the - * size of \p buf required for a successful call. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix, - char *buf, size_t buflen, size_t *olen); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Read an MPI from a line in an opened file. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param radix The numeric base of the string representation used - * in the source line. - * \param fin The input file handle to use. This must not be \c NULL. - * - * \note On success, this function advances the file stream - * to the end of the current line or to EOF. - * - * The function returns \c 0 on an empty line. - * - * Leading whitespaces are ignored, as is a - * '0x' prefix for radix \c 16. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer - * is too small. - * \return Another negative error code on failure. - */ -int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin); - -/** - * \brief Export an MPI into an opened file. - * - * \param p A string prefix to emit prior to the MPI data. - * For example, this might be a label, or "0x" when - * printing in base \c 16. This may be \c NULL if no prefix - * is needed. - * \param X The source MPI. This must point to an initialized MPI. - * \param radix The numeric base to be used in the emitted string. - * \param fout The output file handle. This may be \c NULL, in which case - * the output is written to \c stdout. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, - int radix, FILE *fout); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Import an MPI from unsigned big endian binary data. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param buf The input buffer. This must be a readable buffer of length - * \p buflen Bytes. - * \param buflen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, - size_t buflen); - -/** - * \brief Import X from unsigned binary data, little endian - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param buf The input buffer. This must be a readable buffer of length - * \p buflen Bytes. - * \param buflen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_read_binary_le(mbedtls_mpi *X, - const unsigned char *buf, size_t buflen); - -/** - * \brief Export X into unsigned binary data, big endian. - * Always fills the whole buffer, which will start with zeros - * if the number is smaller. - * - * \param X The source MPI. This must point to an initialized MPI. - * \param buf The output buffer. This must be a writable buffer of length - * \p buflen Bytes. - * \param buflen The size of the output buffer \p buf in Bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't - * large enough to hold the value of \p X. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_write_binary(const mbedtls_mpi *X, unsigned char *buf, - size_t buflen); - -/** - * \brief Export X into unsigned binary data, little endian. - * Always fills the whole buffer, which will end with zeros - * if the number is smaller. - * - * \param X The source MPI. This must point to an initialized MPI. - * \param buf The output buffer. This must be a writable buffer of length - * \p buflen Bytes. - * \param buflen The size of the output buffer \p buf in Bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't - * large enough to hold the value of \p X. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X, - unsigned char *buf, size_t buflen); - -/** - * \brief Perform a left-shift on an MPI: X <<= count - * - * \param X The MPI to shift. This must point to an initialized MPI. - * The MPI pointed by \p X may be resized to fit - * the resulting number. - * \param count The number of bits to shift by. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count); - -/** - * \brief Perform a right-shift on an MPI: X >>= count - * - * \param X The MPI to shift. This must point to an initialized MPI. - * \param count The number of bits to shift by. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count); - -/** - * \brief Compare the absolute values of two MPIs. - * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param Y The right-hand MPI. This must point to an initialized MPI. - * - * \return \c 1 if `|X|` is greater than `|Y|`. - * \return \c -1 if `|X|` is lesser than `|Y|`. - * \return \c 0 if `|X|` is equal to `|Y|`. - */ -int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y); - -/** - * \brief Compare two MPIs. - * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param Y The right-hand MPI. This must point to an initialized MPI. - * - * \return \c 1 if \p X is greater than \p Y. - * \return \c -1 if \p X is lesser than \p Y. - * \return \c 0 if \p X is equal to \p Y. - */ -int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y); - -/** - * \brief Check if an MPI is less than the other in constant time. - * - * \param X The left-hand MPI. This must point to an initialized MPI - * with the same allocated length as Y. - * \param Y The right-hand MPI. This must point to an initialized MPI - * with the same allocated length as X. - * \param ret The result of the comparison: - * \c 1 if \p X is less than \p Y. - * \c 0 if \p X is greater than or equal to \p Y. - * - * \return 0 on success. - * \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of - * the two input MPIs is not the same. - */ -int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X, const mbedtls_mpi *Y, - unsigned *ret); - -/** - * \brief Compare an MPI with an integer. - * - * \param X The left-hand MPI. This must point to an initialized MPI. - * \param z The integer value to compare \p X to. - * - * \return \c 1 if \p X is greater than \p z. - * \return \c -1 if \p X is lesser than \p z. - * \return \c 0 if \p X is equal to \p z. - */ -int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z); - -/** - * \brief Perform an unsigned addition of MPIs: X = |A| + |B| - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param B The second summand. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Perform an unsigned subtraction of MPIs: X = |A| - |B| - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param B The subtrahend. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Perform a signed addition of MPIs: X = A + B - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param B The second summand. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Perform a signed subtraction of MPIs: X = A - B - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param B The subtrahend. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Perform a signed addition of an MPI and an integer: X = A + b - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first summand. This must point to an initialized MPI. - * \param b The second summand. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_sint b); - -/** - * \brief Perform a signed subtraction of an MPI and an integer: - * X = A - b - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The minuend. This must point to an initialized MPI. - * \param b The subtrahend. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_sint b); - -/** - * \brief Perform a multiplication of two MPIs: X = A * B - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first factor. This must point to an initialized MPI. - * \param B The second factor. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Perform a multiplication of an MPI with an unsigned integer: - * X = A * b - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param A The first factor. This must point to an initialized MPI. - * \param b The second factor. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, - mbedtls_mpi_uint b); - -/** - * \brief Perform a division with remainder of two MPIs: - * A = Q * B + R - * - * \param Q The destination MPI for the quotient. - * This may be \c NULL if the value of the - * quotient is not needed. This must not alias A or B. - * \param R The destination MPI for the remainder value. - * This may be \c NULL if the value of the - * remainder is not needed. This must not alias A or B. - * \param A The dividend. This must point to an initialized MPI. - * \param B The divisor. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Perform a division with remainder of an MPI by an integer: - * A = Q * b + R - * - * \param Q The destination MPI for the quotient. - * This may be \c NULL if the value of the - * quotient is not needed. This must not alias A. - * \param R The destination MPI for the remainder value. - * This may be \c NULL if the value of the - * remainder is not needed. This must not alias A. - * \param A The dividend. This must point to an initialized MPi. - * \param b The divisor. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - mbedtls_mpi_sint b); - -/** - * \brief Perform a modular reduction. R = A mod B - * - * \param R The destination MPI for the residue value. - * This must point to an initialized MPI. - * \param A The MPI to compute the residue of. - * This must point to an initialized MPI. - * \param B The base of the modular reduction. - * This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative. - * \return Another negative error code on different kinds of failure. - * - */ -int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Perform a modular reduction with respect to an integer. - * r = A mod b - * - * \param r The address at which to store the residue. - * This must not be \c NULL. - * \param A The MPI to compute the residue of. - * This must point to an initialized MPi. - * \param b The integer base of the modular reduction. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, - mbedtls_mpi_sint b); - -/** - * \brief Perform a modular exponentiation: X = A^E mod N - * - * \param X The destination MPI. This must point to an initialized MPI. - * This must not alias E or N. - * \param A The base of the exponentiation. - * This must point to an initialized MPI. - * \param E The exponent MPI. This must point to an initialized MPI. - * \param N The base for the modular reduction. This must point to an - * initialized MPI. - * \param prec_RR A helper MPI depending solely on \p N which can be used to - * speed-up multiple modular exponentiations for the same value - * of \p N. This may be \c NULL. If it is not \c NULL, it must - * point to an initialized MPI. If it hasn't been used after - * the call to mbedtls_mpi_init(), this function will compute - * the helper value and store it in \p prec_RR for reuse on - * subsequent calls to this function. Otherwise, the function - * will assume that \p prec_RR holds the helper value set by a - * previous call to mbedtls_mpi_exp_mod(), and reuse it. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or - * even, or if \c E is negative. - * \return Another negative error code on different kinds of failures. - * - */ -int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR); - -/** - * \brief Fill an MPI with a number of random bytes. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param size The number of random bytes to generate. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on failure. - * - * \note The bytes obtained from the RNG are interpreted - * as a big-endian representation of an MPI; this can - * be relevant in applications like deterministic ECDSA. - */ -int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** Generate a random number uniformly in a range. - * - * This function generates a random number between \p min inclusive and - * \p N exclusive. - * - * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA) - * when the RNG is a suitably parametrized instance of HMAC_DRBG - * and \p min is \c 1. - * - * \note There are `N - min` possible outputs. The lower bound - * \p min can be reached, but the upper bound \p N cannot. - * - * \param X The destination MPI. This must point to an initialized MPI. - * \param min The minimum value to return. - * It must be nonnegative. - * \param N The upper bound of the range, exclusive. - * In other words, this is one plus the maximum value to return. - * \p N must be strictly larger than \p min. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p min or \p N is invalid - * or if they are incompatible. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was - * unable to find a suitable value within a limited number - * of attempts. This has a negligible probability if \p N - * is significantly larger than \p min, which is the case - * for all usual cryptographic applications. - * \return Another negative error code on failure. - */ -int mbedtls_mpi_random(mbedtls_mpi *X, - mbedtls_mpi_sint min, - const mbedtls_mpi *N, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Compute the greatest common divisor: G = gcd(A, B) - * - * \param G The destination MPI. This must point to an initialized MPI. - * This will always be positive or 0. - * \param A The first operand. This must point to an initialized MPI. - * \param B The second operand. This must point to an initialized MPI. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, - const mbedtls_mpi *B); - -/** - * \brief Compute the modular inverse: X = A^-1 mod N - * - * \param X The destination MPI. This must point to an initialized MPI. - * The value returned on success will be between [1, N-1]. - * \param A The MPI to calculate the modular inverse of. This must point - * to an initialized MPI. This value can be negative, in which - * case a positive answer will still be returned in \p X. - * \param N The base of the modular inversion. This must point to an - * initialized MPI and be greater than one. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than - * or equal to one. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p A has no modular - * inverse with respect to \p N. - */ -int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *N); - -/** - * \brief Miller-Rabin primality test. - * - * \warning If \p X is potentially generated by an adversary, for example - * when validating cryptographic parameters that you didn't - * generate yourself and that are supposed to be prime, then - * \p rounds should be at least the half of the security - * strength of the cryptographic algorithm. On the other hand, - * if \p X is chosen uniformly or non-adversarially (as is the - * case when mbedtls_mpi_gen_prime calls this function), then - * \p rounds can be much lower. - * - * \param X The MPI to check for primality. - * This must point to an initialized MPI. - * \param rounds The number of bases to perform the Miller-Rabin primality - * test for. The probability of returning 0 on a composite is - * at most 2-2*\p rounds . - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use - * a context parameter. - * - * \return \c 0 if successful, i.e. \p X is probably prime. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds, - mbedtls_f_rng_t *f_rng, - void *p_rng); -/** - * \brief Flags for mbedtls_mpi_gen_prime() - * - * Each of these flags is a constraint on the result X returned by - * mbedtls_mpi_gen_prime(). - */ -typedef enum { - MBEDTLS_MPI_GEN_PRIME_FLAG_DH = 0x0001, /**< (X-1)/2 is prime too */ - MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2-80 to 2-128 */ -} mbedtls_mpi_gen_prime_flag_t; - -/** - * \brief Generate a prime number. - * - * \param X The destination MPI to store the generated prime in. - * This must point to an initialized MPi. - * \param nbits The required size of the destination MPI in bits. - * This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS. - * \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't use - * a context parameter. - * - * \return \c 0 if successful, in which case \p X holds a - * probably prime number. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between - * \c 3 and #MBEDTLS_MPI_MAX_BITS. - */ -int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_mpi_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* bignum.h */ diff --git a/vendor/mbedtls/include/mbedtls/block_cipher.h b/vendor/mbedtls/include/mbedtls/block_cipher.h deleted file mode 100644 index 3f60f6f7d..000000000 --- a/vendor/mbedtls/include/mbedtls/block_cipher.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * \file block_cipher.h - * - * \brief Internal abstraction layer. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_BLOCK_CIPHER_H -#define MBEDTLS_BLOCK_CIPHER_H - -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#endif -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" -#endif -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -#include "psa/crypto_types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MBEDTLS_BLOCK_CIPHER_ID_NONE = 0, /**< Unset. */ - MBEDTLS_BLOCK_CIPHER_ID_AES, /**< The AES cipher. */ - MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ - MBEDTLS_BLOCK_CIPHER_ID_ARIA, /**< The Aria cipher. */ -} mbedtls_block_cipher_id_t; - -/** - * Used internally to indicate whether a context uses legacy or PSA. - * - * Internal use only. - */ -typedef enum { - MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY = 0, - MBEDTLS_BLOCK_CIPHER_ENGINE_PSA, -} mbedtls_block_cipher_engine_t; - -typedef struct { - mbedtls_block_cipher_id_t MBEDTLS_PRIVATE(id); -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - mbedtls_block_cipher_engine_t MBEDTLS_PRIVATE(engine); - mbedtls_svc_key_id_t MBEDTLS_PRIVATE(psa_key_id); -#endif - union { - unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ -#if defined(MBEDTLS_AES_C) - mbedtls_aes_context MBEDTLS_PRIVATE(aes); -#endif -#if defined(MBEDTLS_ARIA_C) - mbedtls_aria_context MBEDTLS_PRIVATE(aria); -#endif -#if defined(MBEDTLS_CAMELLIA_C) - mbedtls_camellia_context MBEDTLS_PRIVATE(camellia); -#endif - } MBEDTLS_PRIVATE(ctx); -} mbedtls_block_cipher_context_t; - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_BLOCK_CIPHER_H */ diff --git a/vendor/mbedtls/include/mbedtls/build_info.h b/vendor/mbedtls/include/mbedtls/build_info.h deleted file mode 100644 index b5e8066b8..000000000 --- a/vendor/mbedtls/include/mbedtls/build_info.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - * \file mbedtls/build_info.h - * - * \brief Build-time configuration info - * - * Include this file if you need to depend on the - * configuration options defined in mbedtls_config.h or MBEDTLS_CONFIG_FILE - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_BUILD_INFO_H -#define MBEDTLS_BUILD_INFO_H - -/* - * This set of compile-time defines can be used to determine the version number - * of the Mbed TLS library used. Run-time variables for the same can be found in - * version.h - */ - -/** - * The version number x.y.z is split into three parts. - * Major, Minor, Patchlevel - */ -#define MBEDTLS_VERSION_MAJOR 3 -#define MBEDTLS_VERSION_MINOR 6 -#define MBEDTLS_VERSION_PATCH 6 - -/** - * The single version number has the following structure: - * MMNNPP00 - * Major version | Minor version | Patch version - */ -#define MBEDTLS_VERSION_NUMBER 0x03060600 -#define MBEDTLS_VERSION_STRING "3.6.6" -#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.6" - -/* Macros for build-time platform detection */ - -#if !defined(MBEDTLS_ARCH_IS_ARM64) && \ - (defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) -#define MBEDTLS_ARCH_IS_ARM64 -#endif - -#if !defined(MBEDTLS_ARCH_IS_ARM32) && \ - (defined(__arm__) || defined(_M_ARM) || \ - defined(_M_ARMT) || defined(__thumb__) || defined(__thumb2__)) -#define MBEDTLS_ARCH_IS_ARM32 -#endif - -#if !defined(MBEDTLS_ARCH_IS_X64) && \ - (defined(__amd64__) || defined(__x86_64__) || \ - ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))) -#define MBEDTLS_ARCH_IS_X64 -#endif - -#if !defined(MBEDTLS_ARCH_IS_X86) && \ - (defined(__i386__) || defined(_X86_) || \ - (defined(_M_IX86) && !defined(_M_I86))) -#define MBEDTLS_ARCH_IS_X86 -#endif - -#if !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \ - (defined(_M_ARM64) || defined(_M_ARM64EC)) -#define MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64 -#endif - -/* This is defined if the architecture is Armv8-A, or higher */ -#if !defined(MBEDTLS_ARCH_IS_ARMV8_A) -#if defined(__ARM_ARCH) && defined(__ARM_ARCH_PROFILE) -#if (__ARM_ARCH >= 8) && (__ARM_ARCH_PROFILE == 'A') -/* GCC, clang, armclang and IAR */ -#define MBEDTLS_ARCH_IS_ARMV8_A -#endif -#elif defined(__ARM_ARCH_8A) -/* Alternative defined by clang */ -#define MBEDTLS_ARCH_IS_ARMV8_A -#elif defined(_M_ARM64) || defined(_M_ARM64EC) -/* MSVC ARM64 is at least Armv8.0-A */ -#define MBEDTLS_ARCH_IS_ARMV8_A -#endif -#endif - -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \ - && !defined(__llvm__) && !defined(__INTEL_COMPILER) -/* Defined if the compiler really is gcc and not clang, etc */ -#define MBEDTLS_COMPILER_IS_GCC -#define MBEDTLS_GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -/* Define `inline` on some non-C99-compliant compilers. */ -#if (defined(__ARMCC_VERSION) || defined(_MSC_VER)) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#if defined(MBEDTLS_CONFIG_FILES_READ) -#error "Something went wrong: MBEDTLS_CONFIG_FILES_READ defined before reading the config files!" -#endif -#if defined(MBEDTLS_CONFIG_IS_FINALIZED) -#error "Something went wrong: MBEDTLS_CONFIG_IS_FINALIZED defined before reading the config files!" -#endif - -/* X.509, TLS and non-PSA crypto configuration */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/mbedtls_config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CONFIG_VERSION) && ( \ - MBEDTLS_CONFIG_VERSION < 0x03000000 || \ - MBEDTLS_CONFIG_VERSION > MBEDTLS_VERSION_NUMBER) -#error "Invalid config version, defined value of MBEDTLS_CONFIG_VERSION is unsupported" -#endif - -/* Target and application specific configurations - * - * Allow user to override any previous default. - * - */ -#if defined(MBEDTLS_USER_CONFIG_FILE) -#include MBEDTLS_USER_CONFIG_FILE -#endif - -/* PSA crypto configuration */ -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE) -#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE -#else -#include "psa/crypto_config.h" -#endif -#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE) -#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE -#endif -#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */ - -/* Indicate that all configuration files have been read. - * It is now time to adjust the configuration (follow through on dependencies, - * make PSA and legacy crypto consistent, etc.). - */ -#define MBEDTLS_CONFIG_FILES_READ - -/* Auto-enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY if - * MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH and MBEDTLS_CTR_DRBG_C defined - * to ensure a 128-bit key size in CTR_DRBG. - */ -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && defined(MBEDTLS_CTR_DRBG_C) -#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY -#endif - -/* Auto-enable MBEDTLS_MD_C if needed by a module that didn't require it - * in a previous release, to ensure backwards compatibility. - */ -#if defined(MBEDTLS_PKCS5_C) -#define MBEDTLS_MD_C -#endif - -/* PSA crypto specific configuration options - * - If config_psa.h reads a configuration option in preprocessor directive, - * this symbol should be set before its inclusion. (e.g. MBEDTLS_MD_C) - * - If config_psa.h writes a configuration option in conditional directive, - * this symbol should be consulted after its inclusion. - * (e.g. MBEDTLS_MD_LIGHT) - */ -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \ - defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */ || \ - defined(MBEDTLS_PSA_CRYPTO_CLIENT) /* The same as the previous, but with separation only */ -#include "mbedtls/config_psa.h" -#endif - -#include "mbedtls/config_adjust_legacy_crypto.h" - -#include "mbedtls/config_adjust_x509.h" - -#include "mbedtls/config_adjust_ssl.h" - -/* Indicate that all configuration symbols are set, - * even the ones that are calculated programmatically. - * It is now safe to query the configuration (to check it, to size buffers, - * etc.). - */ -#define MBEDTLS_CONFIG_IS_FINALIZED - -#include "mbedtls/check_config.h" - -#endif /* MBEDTLS_BUILD_INFO_H */ diff --git a/vendor/mbedtls/include/mbedtls/camellia.h b/vendor/mbedtls/include/mbedtls/camellia.h deleted file mode 100644 index 557f47253..000000000 --- a/vendor/mbedtls/include/mbedtls/camellia.h +++ /dev/null @@ -1,305 +0,0 @@ -/** - * \file camellia.h - * - * \brief Camellia block cipher - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_CAMELLIA_H -#define MBEDTLS_CAMELLIA_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -#include "mbedtls/platform_util.h" - -#define MBEDTLS_CAMELLIA_ENCRYPT 1 -#define MBEDTLS_CAMELLIA_DECRYPT 0 - -/** Bad input data. */ -#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 - -/** Invalid data input length. */ -#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_CAMELLIA_ALT) -// Regular implementation -// - -/** - * \brief CAMELLIA context structure - */ -typedef struct mbedtls_camellia_context { - int MBEDTLS_PRIVATE(nr); /*!< number of rounds */ - uint32_t MBEDTLS_PRIVATE(rk)[68]; /*!< CAMELLIA round keys */ -} -mbedtls_camellia_context; - -#else /* MBEDTLS_CAMELLIA_ALT */ -#include "camellia_alt.h" -#endif /* MBEDTLS_CAMELLIA_ALT */ - -/** - * \brief Initialize a CAMELLIA context. - * - * \param ctx The CAMELLIA context to be initialized. - * This must not be \c NULL. - */ -void mbedtls_camellia_init(mbedtls_camellia_context *ctx); - -/** - * \brief Clear a CAMELLIA context. - * - * \param ctx The CAMELLIA context to be cleared. This may be \c NULL, - * in which case this function returns immediately. If it is not - * \c NULL, it must be initialized. - */ -void mbedtls_camellia_free(mbedtls_camellia_context *ctx); - -/** - * \brief Perform a CAMELLIA key schedule operation for encryption. - * - * \param ctx The CAMELLIA context to use. This must be initialized. - * \param key The encryption key to use. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be either \c 128, - * \c 192 or \c 256. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -/** - * \brief Perform a CAMELLIA key schedule operation for decryption. - * - * \param ctx The CAMELLIA context to use. This must be initialized. - * \param key The decryption key. This must be a readable buffer - * of size \p keybits Bits. - * \param keybits The length of \p key in Bits. This must be either \c 128, - * \c 192 or \c 256. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits); -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -/** - * \brief Perform a CAMELLIA-ECB block encryption/decryption operation. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param input The input block. This must be a readable buffer - * of size \c 16 Bytes. - * \param output The output block. This must be a writable buffer - * of size \c 16 Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param length The length in Bytes of the input data \p input. - * This must be a multiple of \c 16 Bytes. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 16 Bytes. It is updated to allow streaming - * use as explained above. - * \param input The buffer holding the input data. This must point to a - * readable buffer of length \p length Bytes. - * \param output The buffer holding the output data. This must point to a - * writable buffer of length \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption - * operation. - * - * \note Due to the nature of CFB mode, you should use the same - * key for both encryption and decryption. In particular, calls - * to this function should be preceded by a key-schedule via - * mbedtls_camellia_setkey_enc() regardless of whether \p mode - * is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param mode The mode of operation. This must be either - * #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * \param length The length of the input data \p input. Any value is allowed. - * \param iv_off The current offset in the IV. This must be smaller - * than \c 16 Bytes. It is updated after this call to allow - * the aforementioned streaming usage. - * \param iv The initialization vector. This must be a read/write buffer - * of length \c 16 Bytes. It is updated after this call to - * allow the aforementioned streaming usage. - * \param input The buffer holding the input data. This must be a readable - * buffer of size \p length Bytes. - * \param output The buffer to hold the output data. This must be a writable - * buffer of length \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation. - * - * *note Due to the nature of CTR mode, you should use the same - * key for both encryption and decryption. In particular, calls - * to this function should be preceded by a key-schedule via - * mbedtls_camellia_setkey_enc() regardless of whether the mode - * is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. - * - * \warning You must never reuse a nonce value with the same key. Doing so - * would void the encryption for the two messages encrypted with - * the same nonce and key. - * - * There are two common strategies for managing nonces with CTR: - * - * 1. You can handle everything as a single message processed over - * successive calls to this function. In that case, you want to - * set \p nonce_counter and \p nc_off to 0 for the first call, and - * then preserve the values of \p nonce_counter, \p nc_off and \p - * stream_block across calls to this function as they will be - * updated by this function. - * - * With this strategy, you must not encrypt more than 2**128 - * blocks of data with the same key. - * - * 2. You can encrypt separate messages by dividing the \p - * nonce_counter buffer in two areas: the first one used for a - * per-message nonce, handled by yourself, and the second one - * updated by this function internally. - * - * For example, you might reserve the first \c 12 Bytes for the - * per-message nonce, and the last \c 4 Bytes for internal use. - * In that case, before calling this function on a new message you - * need to set the first \c 12 Bytes of \p nonce_counter to your - * chosen nonce value, the last four to \c 0, and \p nc_off to \c 0 - * (which will cause \p stream_block to be ignored). That way, you - * can encrypt at most \c 2**96 messages of up to \c 2**32 blocks - * each with the same key. - * - * The per-message nonce (or information sufficient to reconstruct - * it) needs to be communicated with the ciphertext and must be - * unique. The recommended way to ensure uniqueness is to use a - * message counter. An alternative is to generate random nonces, - * but this limits the number of messages that can be securely - * encrypted: for example, with 96-bit random nonces, you should - * not encrypt more than 2**32 messages with the same key. - * - * Note that for both strategies, sizes are measured in blocks and - * that a CAMELLIA block is \c 16 Bytes. - * - * \warning Upon return, \p stream_block contains sensitive data. Its - * content must not be written to insecure storage and should be - * securely discarded as soon as it's no longer needed. - * - * \param ctx The CAMELLIA context to use. This must be initialized - * and bound to a key. - * \param length The length of the input data \p input in Bytes. - * Any value is allowed. - * \param nc_off The offset in the current \p stream_block (for resuming - * within current cipher stream). The offset pointer to - * should be \c 0 at the start of a stream. It is updated - * at the end of this call. - * \param nonce_counter The 128-bit nonce and counter. This must be a read/write - * buffer of length \c 16 Bytes. - * \param stream_block The saved stream-block for resuming. This must be a - * read/write buffer of length \c 16 Bytes. - * \param input The input data stream. This must be a readable buffer of - * size \p length Bytes. - * \param output The output data stream. This must be a writable buffer - * of size \p length Bytes. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_camellia_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* camellia.h */ diff --git a/vendor/mbedtls/include/mbedtls/ccm.h b/vendor/mbedtls/include/mbedtls/ccm.h deleted file mode 100644 index 1da57c921..000000000 --- a/vendor/mbedtls/include/mbedtls/ccm.h +++ /dev/null @@ -1,526 +0,0 @@ -/** - * \file ccm.h - * - * \brief This file provides an API for the CCM authenticated encryption - * mode for block ciphers. - * - * CCM combines Counter mode encryption with CBC-MAC authentication - * for 128-bit block ciphers. - * - * Input to CCM includes the following elements: - *
  • Payload - data that is both authenticated and encrypted.
  • - *
  • Associated data (Adata) - data that is authenticated but not - * encrypted, For example, a header.
  • - *
  • Nonce - A unique value that is assigned to the payload and the - * associated data.
- * - * Definition of CCM: - * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - * RFC 3610 "Counter with CBC-MAC (CCM)" - * - * Related: - * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" - * - * Definition of CCM*: - * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks - * Integer representation is fixed most-significant-octet-first order and - * the representation of octets is most-significant-bit-first order. This is - * consistent with RFC 3610. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CCM_H -#define MBEDTLS_CCM_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/cipher.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_C) -#include "mbedtls/block_cipher.h" -#endif - -#define MBEDTLS_CCM_DECRYPT 0 -#define MBEDTLS_CCM_ENCRYPT 1 -#define MBEDTLS_CCM_STAR_DECRYPT 2 -#define MBEDTLS_CCM_STAR_ENCRYPT 3 - -/** Bad input parameters to the function. */ -#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D -/** Authenticated decryption failed. */ -#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_CCM_ALT) -// Regular implementation -// - -/** - * \brief The CCM context-type definition. The CCM context is passed - * to the APIs called. - */ -typedef struct mbedtls_ccm_context { - unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working buffer */ - unsigned char MBEDTLS_PRIVATE(ctr)[16]; /*!< The counter buffer */ - size_t MBEDTLS_PRIVATE(plaintext_len); /*!< Total plaintext length */ - size_t MBEDTLS_PRIVATE(add_len); /*!< Total authentication data length */ - size_t MBEDTLS_PRIVATE(tag_len); /*!< Total tag length */ - size_t MBEDTLS_PRIVATE(processed); /*!< Track how many bytes of input data - were processed (chunked input). - Used independently for both auth data - and plaintext/ciphertext. - This variable is set to zero after - auth data input is finished. */ - unsigned int MBEDTLS_PRIVATE(q); /*!< The Q working value */ - unsigned int MBEDTLS_PRIVATE(mode); /*!< The operation to perform: - #MBEDTLS_CCM_ENCRYPT or - #MBEDTLS_CCM_DECRYPT or - #MBEDTLS_CCM_STAR_ENCRYPT or - #MBEDTLS_CCM_STAR_DECRYPT. */ -#if defined(MBEDTLS_BLOCK_CIPHER_C) - mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */ -#else - mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ -#endif - int MBEDTLS_PRIVATE(state); /*!< Working value holding context's - state. Used for chunked data input */ -} -mbedtls_ccm_context; - -#else /* MBEDTLS_CCM_ALT */ -#include "ccm_alt.h" -#endif /* MBEDTLS_CCM_ALT */ - -/** - * \brief This function initializes the specified CCM context, - * to make references valid, and prepare the context - * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). - * - * \param ctx The CCM context to initialize. This must not be \c NULL. - */ -void mbedtls_ccm_init(mbedtls_ccm_context *ctx); - -/** - * \brief This function initializes the CCM context set in the - * \p ctx parameter and sets the encryption key. - * - * \param ctx The CCM context to initialize. This must be an initialized - * context. - * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. This must not be \c NULL. - * \param keybits The key size in bits. This must be acceptable by the cipher. - * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. - */ -int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits); - -/** - * \brief This function releases and clears the specified CCM context - * and underlying cipher sub-context. - * - * \param ctx The CCM context to clear. If this is \c NULL, the function - * has no effect. Otherwise, this must be initialized. - */ -void mbedtls_ccm_free(mbedtls_ccm_context *ctx); - -/** - * \brief This function encrypts a buffer using CCM. - * - * \note The tag is written to a separate buffer. To concatenate - * the \p tag with the \p output, as done in RFC-3610: - * Counter with CBC-MAC (CCM), use - * \p tag = \p output + \p length, and make sure that the - * output buffer is at least \p length + \p tag_len wide. - * - * \param ctx The CCM context to use for encryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param ad The additional data field. If \p ad_len is greater than - * zero, \p ad must be a readable buffer of at least that - * length. - * \param ad_len The length of additional data in Bytes. - * This must be less than `2^16 - 2^8`. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * writable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: - * 4, 6, 8, 10, 12, 14 or 16. - * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. - */ -int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len); - -/** - * \brief This function encrypts a buffer using CCM*. - * - * \note The tag is written to a separate buffer. To concatenate - * the \p tag with the \p output, as done in RFC-3610: - * Counter with CBC-MAC (CCM), use - * \p tag = \p output + \p length, and make sure that the - * output buffer is at least \p length + \p tag_len wide. - * - * \note When using this function in a variable tag length context, - * the tag length has to be encoded into the \p iv passed to - * this function. - * - * \param ctx The CCM context to use for encryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * For tag length = 0, input length is ignored. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param ad The additional data field. This must be a readable buffer of - * at least \p ad_len Bytes. - * \param ad_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * writable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: - * 0, 4, 6, 8, 10, 12, 14 or 16. - * - * \warning Passing \c 0 as \p tag_len means that the message is no - * longer authenticated. - * - * \return \c 0 on success. - * \return A CCM or cipher-specific error code on failure. - */ -int mbedtls_ccm_star_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len); - -/** - * \brief This function performs a CCM authenticated decryption of a - * buffer. - * - * \param ctx The CCM context to use for decryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param ad The additional data field. This must be a readable buffer - * of at least that \p ad_len Bytes.. - * \param ad_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field to generate in Bytes: - * 4, 6, 8, 10, 12, 14 or 16. - * - * \return \c 0 on success. This indicates that the message is authentic. - * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. - * \return A cipher-specific error code on calculation failure. - */ -int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len); - -/** - * \brief This function performs a CCM* authenticated decryption of a - * buffer. - * - * \note When using this function in a variable tag length context, - * the tag length has to be decoded from \p iv and passed to - * this function as \p tag_len. (\p tag needs to be adjusted - * accordingly.) - * - * \param ctx The CCM context to use for decryption. This must be - * initialized and bound to a key. - * \param length The length of the input data in Bytes. - * For tag length = 0, input length is ignored. - * \param iv The initialization vector (nonce). This must be a readable - * buffer of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * \param ad The additional data field. This must be a readable buffer of - * at least that \p ad_len Bytes. - * \param ad_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. If \p length is greater - * than zero, \p input must be a readable buffer of at least - * that length. - * \param output The buffer holding the output data. If \p length is greater - * than zero, \p output must be a writable buffer of at least - * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication field in Bytes. - * 0, 4, 6, 8, 10, 12, 14 or 16. - * - * \warning Passing \c 0 as \p tag_len means that the message is nos - * longer authenticated. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. - * \return A cipher-specific error code on calculation failure. - */ -int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len); - -/** - * \brief This function starts a CCM encryption or decryption - * operation. - * - * This function and mbedtls_ccm_set_lengths() must be called - * before calling mbedtls_ccm_update_ad() or - * mbedtls_ccm_update(). This function can be called before - * or after mbedtls_ccm_set_lengths(). - * - * \note This function is not implemented in Mbed TLS yet. - * - * \param ctx The CCM context. This must be initialized. - * \param mode The operation to perform: #MBEDTLS_CCM_ENCRYPT or - * #MBEDTLS_CCM_DECRYPT or #MBEDTLS_CCM_STAR_ENCRYPT or - * #MBEDTLS_CCM_STAR_DECRYPT. - * \param iv The initialization vector. This must be a readable buffer - * of at least \p iv_len Bytes. - * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, - * or 13. The length L of the message length field is - * 15 - \p iv_len. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: - * \p ctx is in an invalid state, - * \p mode is invalid, - * \p iv_len is invalid (lower than \c 7 or greater than - * \c 13). - */ -int mbedtls_ccm_starts(mbedtls_ccm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len); - -/** - * \brief This function declares the lengths of the message - * and additional data for a CCM encryption or decryption - * operation. - * - * This function and mbedtls_ccm_starts() must be called - * before calling mbedtls_ccm_update_ad() or - * mbedtls_ccm_update(). This function can be called before - * or after mbedtls_ccm_starts(). - * - * \note This function is not implemented in Mbed TLS yet. - * - * \param ctx The CCM context. This must be initialized. - * \param total_ad_len The total length of additional data in bytes. - * This must be less than `2^16 - 2^8`. - * \param plaintext_len The length in bytes of the plaintext to encrypt or - * result of the decryption (thus not encompassing the - * additional data that are not encrypted). - * \param tag_len The length of the tag to generate in Bytes: - * 4, 6, 8, 10, 12, 14 or 16. - * For CCM*, zero is also valid. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: - * \p ctx is in an invalid state, - * \p total_ad_len is greater than \c 0xFF00. - */ -int mbedtls_ccm_set_lengths(mbedtls_ccm_context *ctx, - size_t total_ad_len, - size_t plaintext_len, - size_t tag_len); - -/** - * \brief This function feeds an input buffer as associated data - * (authenticated but not encrypted data) in a CCM - * encryption or decryption operation. - * - * You may call this function zero, one or more times - * to pass successive parts of the additional data. The - * lengths \p ad_len of the data parts should eventually add - * up exactly to the total length of additional data - * \c total_ad_len passed to mbedtls_ccm_set_lengths(). You - * may not call this function after calling - * mbedtls_ccm_update(). - * - * \note This function is not implemented in Mbed TLS yet. - * - * \param ctx The CCM context. This must have been started with - * mbedtls_ccm_starts(), the lengths of the message and - * additional data must have been declared with - * mbedtls_ccm_set_lengths() and this must not have yet - * received any input with mbedtls_ccm_update(). - * \param ad The buffer holding the additional data, or \c NULL - * if \p ad_len is \c 0. - * \param ad_len The length of the additional data. If \c 0, - * \p ad may be \c NULL. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: - * \p ctx is in an invalid state, - * total input length too long. - */ -int mbedtls_ccm_update_ad(mbedtls_ccm_context *ctx, - const unsigned char *ad, - size_t ad_len); - -/** - * \brief This function feeds an input buffer into an ongoing CCM - * encryption or decryption operation. - * - * You may call this function zero, one or more times - * to pass successive parts of the input: the plaintext to - * encrypt, or the ciphertext (not including the tag) to - * decrypt. After the last part of the input, call - * mbedtls_ccm_finish(). The lengths \p input_len of the - * data parts should eventually add up exactly to the - * plaintext length \c plaintext_len passed to - * mbedtls_ccm_set_lengths(). - * - * This function may produce output in one of the following - * ways: - * - Immediate output: the output length is always equal - * to the input length. - * - Buffered output: except for the last part of input data, - * the output consists of a whole number of 16-byte blocks. - * If the total input length so far (not including - * associated data) is 16 \* *B* + *A* with *A* < 16 then - * the total output length is 16 \* *B*. - * For the last part of input data, the output length is - * equal to the input length plus the number of bytes (*A*) - * buffered in the previous call to the function (if any). - * The function uses the plaintext length - * \c plaintext_len passed to mbedtls_ccm_set_lengths() - * to detect the last part of input data. - * - * In particular: - * - It is always correct to call this function with - * \p output_size >= \p input_len + 15. - * - If \p input_len is a multiple of 16 for all the calls - * to this function during an operation (not necessary for - * the last one) then it is correct to use \p output_size - * =\p input_len. - * - * \note This function is not implemented in Mbed TLS yet. - * - * \param ctx The CCM context. This must have been started with - * mbedtls_ccm_starts() and the lengths of the message and - * additional data must have been declared with - * mbedtls_ccm_set_lengths(). - * \param input The buffer holding the input data. If \p input_len - * is greater than zero, this must be a readable buffer - * of at least \p input_len bytes. - * \param input_len The length of the input data in bytes. - * \param output The buffer for the output data. If \p output_size - * is greater than zero, this must be a writable buffer of - * at least \p output_size bytes. - * \param output_size The size of the output buffer in bytes. - * See the function description regarding the output size. - * \param output_len On success, \p *output_len contains the actual - * length of the output written in \p output. - * On failure, the content of \p *output_len is - * unspecified. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: - * \p ctx is in an invalid state, - * total input length too long, - * or \p output_size too small. - */ -int mbedtls_ccm_update(mbedtls_ccm_context *ctx, - const unsigned char *input, size_t input_len, - unsigned char *output, size_t output_size, - size_t *output_len); - -/** - * \brief This function finishes the CCM operation and generates - * the authentication tag. - * - * It wraps up the CCM stream, and generates the - * tag. The tag can have a maximum length of 16 Bytes. - * - * \note This function is not implemented in Mbed TLS yet. - * - * \param ctx The CCM context. This must have been started with - * mbedtls_ccm_starts() and the lengths of the message and - * additional data must have been declared with - * mbedtls_ccm_set_lengths(). - * \param tag The buffer for holding the tag. If \p tag_len is greater - * than zero, this must be a writable buffer of at least \p - * tag_len Bytes. - * \param tag_len The length of the tag. Must match the tag length passed to - * mbedtls_ccm_set_lengths() function. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: - * \p ctx is in an invalid state, - * invalid value of \p tag_len, - * the total amount of additional data passed to - * mbedtls_ccm_update_ad() was lower than the total length of - * additional data \c total_ad_len passed to - * mbedtls_ccm_set_lengths(), - * the total amount of input data passed to - * mbedtls_ccm_update() was lower than the plaintext length - * \c plaintext_len passed to mbedtls_ccm_set_lengths(). - */ -int mbedtls_ccm_finish(mbedtls_ccm_context *ctx, - unsigned char *tag, size_t tag_len); - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES) -/** - * \brief The CCM checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_ccm_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CCM_H */ diff --git a/vendor/mbedtls/include/mbedtls/chacha20.h b/vendor/mbedtls/include/mbedtls/chacha20.h deleted file mode 100644 index 680fe3604..000000000 --- a/vendor/mbedtls/include/mbedtls/chacha20.h +++ /dev/null @@ -1,202 +0,0 @@ -/** - * \file chacha20.h - * - * \brief This file contains ChaCha20 definitions and functions. - * - * ChaCha20 is a stream cipher that can encrypt and decrypt - * information. ChaCha was created by Daniel Bernstein as a variant of - * its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf - * ChaCha20 is the variant with 20 rounds, that was also standardized - * in RFC 7539. - * - * \author Daniel King - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CHACHA20_H -#define MBEDTLS_CHACHA20_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -/** Invalid input parameter(s). */ -#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_CHACHA20_ALT) - -typedef struct mbedtls_chacha20_context { - uint32_t MBEDTLS_PRIVATE(state)[16]; /*! The state (before round operations). */ - uint8_t MBEDTLS_PRIVATE(keystream8)[64]; /*! Leftover keystream bytes. */ - size_t MBEDTLS_PRIVATE(keystream_bytes_used); /*! Number of keystream bytes already used. */ -} -mbedtls_chacha20_context; - -#else /* MBEDTLS_CHACHA20_ALT */ -#include "chacha20_alt.h" -#endif /* MBEDTLS_CHACHA20_ALT */ - -/** - * \brief This function initializes the specified ChaCha20 context. - * - * It must be the first API called before using - * the context. - * - * It is usually followed by calls to - * \c mbedtls_chacha20_setkey() and - * \c mbedtls_chacha20_starts(), then one or more calls to - * to \c mbedtls_chacha20_update(), and finally to - * \c mbedtls_chacha20_free(). - * - * \param ctx The ChaCha20 context to initialize. - * This must not be \c NULL. - */ -void mbedtls_chacha20_init(mbedtls_chacha20_context *ctx); - -/** - * \brief This function releases and clears the specified - * ChaCha20 context. - * - * \param ctx The ChaCha20 context to clear. This may be \c NULL, - * in which case this function is a no-op. If it is not - * \c NULL, it must point to an initialized context. - * - */ -void mbedtls_chacha20_free(mbedtls_chacha20_context *ctx); - -/** - * \brief This function sets the encryption/decryption key. - * - * \note After using this function, you must also call - * \c mbedtls_chacha20_starts() to set a nonce before you - * start encrypting/decrypting data with - * \c mbedtls_chacha_update(). - * - * \param ctx The ChaCha20 context to which the key should be bound. - * It must be initialized. - * \param key The encryption/decryption key. This must be \c 32 Bytes - * in length. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL. - */ -int mbedtls_chacha20_setkey(mbedtls_chacha20_context *ctx, - const unsigned char key[32]); - -/** - * \brief This function sets the nonce and initial counter value. - * - * \note A ChaCha20 context can be re-used with the same key by - * calling this function to change the nonce. - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality guarantees for the - * messages encrypted with the same nonce and key. - * - * \param ctx The ChaCha20 context to which the nonce should be bound. - * It must be initialized and bound to a key. - * \param nonce The nonce. This must be \c 12 Bytes in size. - * \param counter The initial counter value. This is usually \c 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is - * NULL. - */ -int mbedtls_chacha20_starts(mbedtls_chacha20_context *ctx, - const unsigned char nonce[12], - uint32_t counter); - -/** - * \brief This function encrypts or decrypts data. - * - * Since ChaCha20 is a stream cipher, the same operation is - * used for encrypting and decrypting data. - * - * \note The \p input and \p output pointers must either be equal or - * point to non-overlapping buffers. - * - * \note \c mbedtls_chacha20_setkey() and - * \c mbedtls_chacha20_starts() must be called at least once - * to setup the context before this function can be called. - * - * \note This function can be called multiple times in a row in - * order to encrypt of decrypt data piecewise with the same - * key and nonce. - * - * \param ctx The ChaCha20 context to use for encryption or decryption. - * It must be initialized and bound to a key and nonce. - * \param size The length of the input data in Bytes. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `size == 0`. - * \param output The buffer holding the output data. - * This must be able to hold \p size Bytes. - * This pointer can be \c NULL if `size == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chacha20_update(mbedtls_chacha20_context *ctx, - size_t size, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function encrypts or decrypts data with ChaCha20 and - * the given key and nonce. - * - * Since ChaCha20 is a stream cipher, the same operation is - * used for encrypting and decrypting data. - * - * \warning You must never use the same (key, nonce) pair more than - * once. This would void any confidentiality guarantees for - * the messages encrypted with the same nonce and key. - * - * \note The \p input and \p output pointers must either be equal or - * point to non-overlapping buffers. - * - * \param key The encryption/decryption key. - * This must be \c 32 Bytes in length. - * \param nonce The nonce. This must be \c 12 Bytes in size. - * \param counter The initial counter value. This is usually \c 0. - * \param size The length of the input data in Bytes. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `size == 0`. - * \param output The buffer holding the output data. - * This must be able to hold \p size Bytes. - * This pointer can be \c NULL if `size == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chacha20_crypt(const unsigned char key[32], - const unsigned char nonce[12], - uint32_t counter, - size_t size, - const unsigned char *input, - unsigned char *output); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The ChaCha20 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_chacha20_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CHACHA20_H */ diff --git a/vendor/mbedtls/include/mbedtls/chachapoly.h b/vendor/mbedtls/include/mbedtls/chachapoly.h deleted file mode 100644 index 3dc21e380..000000000 --- a/vendor/mbedtls/include/mbedtls/chachapoly.h +++ /dev/null @@ -1,342 +0,0 @@ -/** - * \file chachapoly.h - * - * \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and - * functions. - * - * ChaCha20-Poly1305 is an algorithm for Authenticated Encryption - * with Associated Data (AEAD) that can be used to encrypt and - * authenticate data. It is based on ChaCha20 and Poly1305 by Daniel - * Bernstein and was standardized in RFC 7539. - * - * \author Daniel King - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CHACHAPOLY_H -#define MBEDTLS_CHACHAPOLY_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -/* for shared error codes */ -#include "mbedtls/poly1305.h" - -/** The requested operation is not permitted in the current state. */ -#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 -/** Authenticated decryption failed: data was not authentic. */ -#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */ - MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */ -} -mbedtls_chachapoly_mode_t; - -#if !defined(MBEDTLS_CHACHAPOLY_ALT) - -#include "mbedtls/chacha20.h" - -typedef struct mbedtls_chachapoly_context { - mbedtls_chacha20_context MBEDTLS_PRIVATE(chacha20_ctx); /**< The ChaCha20 context. */ - mbedtls_poly1305_context MBEDTLS_PRIVATE(poly1305_ctx); /**< The Poly1305 context. */ - uint64_t MBEDTLS_PRIVATE(aad_len); /**< The length (bytes) of the Additional Authenticated Data. */ - uint64_t MBEDTLS_PRIVATE(ciphertext_len); /**< The length (bytes) of the ciphertext. */ - int MBEDTLS_PRIVATE(state); /**< The current state of the context. */ - mbedtls_chachapoly_mode_t MBEDTLS_PRIVATE(mode); /**< Cipher mode (encrypt or decrypt). */ -} -mbedtls_chachapoly_context; - -#else /* !MBEDTLS_CHACHAPOLY_ALT */ -#include "chachapoly_alt.h" -#endif /* !MBEDTLS_CHACHAPOLY_ALT */ - -/** - * \brief This function initializes the specified ChaCha20-Poly1305 context. - * - * It must be the first API called before using - * the context. It must be followed by a call to - * \c mbedtls_chachapoly_setkey() before any operation can be - * done, and to \c mbedtls_chachapoly_free() once all - * operations with that context have been finished. - * - * In order to encrypt or decrypt full messages at once, for - * each message you should make a single call to - * \c mbedtls_chachapoly_crypt_and_tag() or - * \c mbedtls_chachapoly_auth_decrypt(). - * - * In order to encrypt messages piecewise, for each - * message you should make a call to - * \c mbedtls_chachapoly_starts(), then 0 or more calls to - * \c mbedtls_chachapoly_update_aad(), then 0 or more calls to - * \c mbedtls_chachapoly_update(), then one call to - * \c mbedtls_chachapoly_finish(). - * - * \warning Decryption with the piecewise API is discouraged! Always - * use \c mbedtls_chachapoly_auth_decrypt() when possible! - * - * If however this is not possible because the data is too - * large to fit in memory, you need to: - * - * - call \c mbedtls_chachapoly_starts() and (if needed) - * \c mbedtls_chachapoly_update_aad() as above, - * - call \c mbedtls_chachapoly_update() multiple times and - * ensure its output (the plaintext) is NOT used in any other - * way than placing it in temporary storage at this point, - * - call \c mbedtls_chachapoly_finish() to compute the - * authentication tag and compared it in constant time to the - * tag received with the ciphertext. - * - * If the tags are not equal, you must immediately discard - * all previous outputs of \c mbedtls_chachapoly_update(), - * otherwise you can now safely use the plaintext. - * - * \param ctx The ChachaPoly context to initialize. Must not be \c NULL. - */ -void mbedtls_chachapoly_init(mbedtls_chachapoly_context *ctx); - -/** - * \brief This function releases and clears the specified - * ChaCha20-Poly1305 context. - * - * \param ctx The ChachaPoly context to clear. This may be \c NULL, in which - * case this function is a no-op. - */ -void mbedtls_chachapoly_free(mbedtls_chachapoly_context *ctx); - -/** - * \brief This function sets the ChaCha20-Poly1305 - * symmetric encryption key. - * - * \param ctx The ChaCha20-Poly1305 context to which the key should be - * bound. This must be initialized. - * \param key The \c 256 Bit (\c 32 Bytes) key. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_setkey(mbedtls_chachapoly_context *ctx, - const unsigned char key[32]); - -/** - * \brief This function starts a ChaCha20-Poly1305 encryption or - * decryption operation. - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality and authenticity - * guarantees for the messages encrypted with the same nonce - * and key. - * - * \note If the context is being used for AAD only (no data to - * encrypt or decrypt) then \p mode can be set to any value. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context. This must be initialized - * and bound to a key. - * \param nonce The nonce/IV to use for the message. - * This must be a readable buffer of length \c 12 Bytes. - * \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or - * #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning). - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_starts(mbedtls_chachapoly_context *ctx, - const unsigned char nonce[12], - mbedtls_chachapoly_mode_t mode); - -/** - * \brief This function feeds additional data to be authenticated - * into an ongoing ChaCha20-Poly1305 operation. - * - * The Additional Authenticated Data (AAD), also called - * Associated Data (AD) is only authenticated but not - * encrypted nor included in the encrypted output. It is - * usually transmitted separately from the ciphertext or - * computed locally by each party. - * - * \note This function is called before data is encrypted/decrypted. - * I.e. call this function to process the AAD before calling - * \c mbedtls_chachapoly_update(). - * - * You may call this function multiple times to process - * an arbitrary amount of AAD. It is permitted to call - * this function 0 times, if no AAD is used. - * - * This function cannot be called any more if data has - * been processed by \c mbedtls_chachapoly_update(), - * or if the context has been finished. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context. This must be initialized - * and bound to a key. - * \param aad_len The length in Bytes of the AAD. The length has no - * restrictions. - * \param aad Buffer containing the AAD. - * This pointer can be \c NULL if `aad_len == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA - * if \p ctx or \p aad are NULL. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operations has not been started or has been - * finished, or if the AAD has been finished. - */ -int mbedtls_chachapoly_update_aad(mbedtls_chachapoly_context *ctx, - const unsigned char *aad, - size_t aad_len); - -/** - * \brief Thus function feeds data to be encrypted or decrypted - * into an on-going ChaCha20-Poly1305 - * operation. - * - * The direction (encryption or decryption) depends on the - * mode that was given when calling - * \c mbedtls_chachapoly_starts(). - * - * You may call this function multiple times to process - * an arbitrary amount of data. It is permitted to call - * this function 0 times, if no data is to be encrypted - * or decrypted. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. - * \param len The length (in bytes) of the data to encrypt or decrypt. - * \param input The buffer containing the data to encrypt or decrypt. - * This pointer can be \c NULL if `len == 0`. - * \param output The buffer to where the encrypted or decrypted data is - * written. This must be able to hold \p len bytes. - * This pointer can be \c NULL if `len == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operation has not been started or has been - * finished. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_update(mbedtls_chachapoly_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function finished the ChaCha20-Poly1305 operation and - * generates the MAC (authentication tag). - * - * \param ctx The ChaCha20-Poly1305 context to use. This must be initialized. - * \param mac The buffer to where the 128-bit (16 bytes) MAC is written. - * - * \warning Decryption with the piecewise API is discouraged, see the - * warning on \c mbedtls_chachapoly_init(). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE - * if the operation has not been started or has been - * finished. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_finish(mbedtls_chachapoly_context *ctx, - unsigned char mac[16]); - -/** - * \brief This function performs a complete ChaCha20-Poly1305 - * authenticated encryption with the previously-set key. - * - * \note Before using this function, you must set the key with - * \c mbedtls_chachapoly_setkey(). - * - * \warning You must never use the same nonce twice with the same key. - * This would void any confidentiality and authenticity - * guarantees for the messages encrypted with the same nonce - * and key. - * - * \param ctx The ChaCha20-Poly1305 context to use (holds the key). - * This must be initialized. - * \param length The length (in bytes) of the data to encrypt or decrypt. - * \param nonce The 96-bit (12 bytes) nonce/IV to use. - * \param aad The buffer containing the additional authenticated - * data (AAD). This pointer can be \c NULL if `aad_len == 0`. - * \param aad_len The length (in bytes) of the AAD data to process. - * \param input The buffer containing the data to encrypt or decrypt. - * This pointer can be \c NULL if `ilen == 0`. - * \param output The buffer to where the encrypted or decrypted data - * is written. This pointer can be \c NULL if `ilen == 0`. - * \param tag The buffer to where the computed 128-bit (16 bytes) MAC - * is written. This must not be \c NULL. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_chachapoly_encrypt_and_tag(mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16]); - -/** - * \brief This function performs a complete ChaCha20-Poly1305 - * authenticated decryption with the previously-set key. - * - * \note Before using this function, you must set the key with - * \c mbedtls_chachapoly_setkey(). - * - * \param ctx The ChaCha20-Poly1305 context to use (holds the key). - * \param length The length (in Bytes) of the data to decrypt. - * \param nonce The \c 96 Bit (\c 12 bytes) nonce/IV to use. - * \param aad The buffer containing the additional authenticated data (AAD). - * This pointer can be \c NULL if `aad_len == 0`. - * \param aad_len The length (in bytes) of the AAD data to process. - * \param tag The buffer holding the authentication tag. - * This must be a readable buffer of length \c 16 Bytes. - * \param input The buffer containing the data to decrypt. - * This pointer can be \c NULL if `ilen == 0`. - * \param output The buffer to where the decrypted data is written. - * This pointer can be \c NULL if `ilen == 0`. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED - * if the data was not authentic. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char tag[16], - const unsigned char *input, - unsigned char *output); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The ChaCha20-Poly1305 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_chachapoly_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CHACHAPOLY_H */ diff --git a/vendor/mbedtls/include/mbedtls/check_config.h b/vendor/mbedtls/include/mbedtls/check_config.h deleted file mode 100644 index aec5050b7..000000000 --- a/vendor/mbedtls/include/mbedtls/check_config.h +++ /dev/null @@ -1,1149 +0,0 @@ -/** - * \file check_config.h - * - * \brief Consistency checks for configuration options - * - * This is an internal header. Do not include it directly. - * - * This header is included automatically by all public Mbed TLS headers - * (via mbedtls/build_info.h). Do not include it directly in a configuration - * file such as mbedtls/mbedtls_config.h or #MBEDTLS_USER_CONFIG_FILE! - * It would run at the wrong time due to missing derived symbols. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CHECK_CONFIG_H -#define MBEDTLS_CHECK_CONFIG_H - -/* *INDENT-OFF* */ - -#if !defined(MBEDTLS_CONFIG_IS_FINALIZED) -#warning "Do not include mbedtls/check_config.h manually! " \ - "This may cause spurious errors. " \ - "It is included automatically at the right point since Mbed TLS 3.0." -#endif /* !MBEDTLS_CONFIG_IS_FINALIZED */ - -/* - * We assume CHAR_BIT is 8 in many places. In practice, this is true on our - * target platforms, so not an issue, but let's just be extra sure. - */ -#include -#if CHAR_BIT != 8 -#error "Mbed TLS requires a platform with 8-bit chars" -#endif - -#include - -#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) -#if !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_C is required on Windows" -#endif -/* See auto-enabling SNPRINTF_ALT and VSNPRINTF_ALT - * in * config_adjust_legacy_crypto.h */ -#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */ - -#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C) -#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS" -#endif - -#if defined(MBEDTLS_DEPRECATED_WARNING) && \ - !defined(__GNUC__) && !defined(__clang__) -#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" -#endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) -#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" -#endif - -/* Limitations on ECC key types acceleration: if we have any of `PUBLIC_KEY`, - * `KEY_PAIR_BASIC`, `KEY_PAIR_IMPORT`, `KEY_PAIR_EXPORT` then we must have - * all 4 of them. - */ -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) -#error "Unsupported partial support for ECC key type acceleration, see docs/driver-only-builds.md" -#endif /* not all of public, basic, import, export */ -#endif /* one of public, basic, import, export */ - -/* Limitations on ECC curves acceleration: partial curve acceleration is only - * supported with crypto excluding PK, X.509 or TLS. - * Note: no need to check X.509 as it depends on PK. */ -#if defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \ - defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521) -#if defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) -#if defined(MBEDTLS_PK_C) || \ - defined(MBEDTLS_SSL_TLS_C) -#error "Unsupported partial support for ECC curves acceleration, see docs/driver-only-builds.md" -#endif /* modules beyond what's supported */ -#endif /* not all curves accelerated */ -#endif /* some curve accelerated */ - -#if defined(MBEDTLS_CTR_DRBG_C) && !(defined(MBEDTLS_AES_C) || \ - (defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_KEY_TYPE_AES) && \ - defined(PSA_WANT_ALG_ECB_NO_PADDING))) -#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) -#error "MBEDTLS_DHM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CMAC_C) && \ - ( !defined(MBEDTLS_CIPHER_C ) || ( !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) ) ) -#error "MBEDTLS_CMAC_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_NIST_KW_C) && \ - ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) ) -#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) && defined(MBEDTLS_PSA_CRYPTO_CONFIG) -#if defined(PSA_WANT_ALG_CBC_NO_PADDING) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_NO_PADDING cannot be defined simultaneously" -#endif -#if defined(PSA_WANT_ALG_CBC_PKCS7) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_PKCS7 cannot be defined simultaneously" -#endif -#if defined(PSA_WANT_ALG_ECB_NO_PADDING) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_ECB_NO_PADDING cannot be defined simultaneously" -#endif -#if defined(PSA_WANT_KEY_TYPE_DES) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_KEY_TYPE_DES cannot be defined simultaneously" -#endif -#endif - -#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_CBC cannot be defined simultaneously" -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_XTS cannot be defined simultaneously" -#endif -#if defined(MBEDTLS_DES_C) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_DES_C cannot be defined simultaneously" -#endif -#if defined(MBEDTLS_NIST_KW_C) -#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_NIST_KW_C cannot be defined simultaneously" -#endif -#endif - -#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) -#error "MBEDTLS_ECDH_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDSA_C) && \ - ( !defined(MBEDTLS_ECP_C) || \ - !( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) ) || \ - !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_ASN1_WRITE_C) ) -#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) && !defined(MBEDTLS_ASN1_WRITE_C) -#error "MBEDTLS_PK_C with MBEDTLS_USE_PSA_CRYPTO needs MBEDTLS_ASN1_WRITE_C for ECDSA signature" -#endif -#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) && !defined(MBEDTLS_ASN1_PARSE_C) -#error "MBEDTLS_PK_C with MBEDTLS_USE_PSA_CRYPTO needs MBEDTLS_ASN1_PARSE_C for ECDSA verification" -#endif -#endif /* MBEDTLS_PK_C && MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_ECJPAKE_C) && \ - !defined(MBEDTLS_ECP_C) -#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \ - defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \ - defined(MBEDTLS_ECDSA_SIGN_ALT) || \ - defined(MBEDTLS_ECDSA_VERIFY_ALT) || \ - defined(MBEDTLS_ECDSA_GENKEY_ALT) || \ - defined(MBEDTLS_ECP_INTERNAL_ALT) || \ - defined(MBEDTLS_ECP_ALT) ) -#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation" -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - !defined(MBEDTLS_ECP_C) -#error "MBEDTLS_ECP_RESTARTABLE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) -#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_LIGHT) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ - !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) ) -#error "MBEDTLS_ECP_C defined (or a subset enabled), but not all prerequisites" -#endif - -#if defined(MBEDTLS_ENTROPY_C) && \ - !(defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA256)) -#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - (defined(MBEDTLS_ENTROPY_FORCE_SHA256) || !defined(MBEDTLS_MD_CAN_SHA512)) \ - && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_MD_CAN_SHA256) -#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" -#endif - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) -#define MBEDTLS_HAS_MEMSAN // #undef at the end of this paragraph -#endif -#endif -#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN) -#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer" -#endif -#if defined(MBEDTLS_HAS_MEMSAN) && defined(MBEDTLS_HAVE_ASM) -#error "MemorySanitizer does not support assembly implementation" -#endif -#undef MBEDTLS_HAS_MEMSAN // temporary macro defined above - -#if defined(MBEDTLS_CCM_C) && \ - !(defined(MBEDTLS_CCM_GCM_CAN_AES) || defined(MBEDTLS_CCM_GCM_CAN_ARIA) || \ - defined(MBEDTLS_CCM_GCM_CAN_CAMELLIA)) -#error "MBEDTLS_CCM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_GCM_C) && \ - !(defined(MBEDTLS_CCM_GCM_CAN_AES) || defined(MBEDTLS_CCM_GCM_CAN_ARIA) || \ - defined(MBEDTLS_CCM_GCM_CAN_CAMELLIA)) -#error "MBEDTLS_GCM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_CHACHA20_C) -#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_POLY1305_C) -#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && !defined(MBEDTLS_ECP_INTERNAL_ALT) -#error "MBEDTLS_ECP_NO_FALLBACK defined, but no alternative implementation enabled" -#endif - -#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) -#error "MBEDTLS_HKDF_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) -#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_CAN_ECDH) || \ - !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - ( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) -#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ - !defined(MBEDTLS_CAN_ECDH) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_CAN_ECDH) || \ - !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - ( !defined(PSA_WANT_ALG_JPAKE) || \ - !defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - !defined(PSA_WANT_ECC_SECP_R1_256) ) -#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" -#endif -#else /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - ( !defined(MBEDTLS_ECJPAKE_C) || \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) -#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" -#endif -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/* Use of EC J-PAKE in TLS requires SHA-256. */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - !defined(MBEDTLS_MD_CAN_SHA256) -#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \ - !defined(MBEDTLS_MD_CAN_SHA256) && \ - !defined(MBEDTLS_MD_CAN_SHA512) && \ - !defined(MBEDTLS_MD_CAN_SHA1) -#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires SHA-512, SHA-256 or SHA-1". -#endif - -#if defined(MBEDTLS_MD_C) && \ - !defined(MBEDTLS_MD_CAN_MD5) && \ - !defined(MBEDTLS_MD_CAN_RIPEMD160) && \ - !defined(MBEDTLS_MD_CAN_SHA1) && \ - !defined(MBEDTLS_MD_CAN_SHA224) && \ - !defined(MBEDTLS_MD_CAN_SHA256) && \ - !defined(MBEDTLS_MD_CAN_SHA384) && \ - !defined(MBEDTLS_MD_CAN_SHA512) && \ - !defined(MBEDTLS_MD_CAN_SHA3_224) && \ - !defined(MBEDTLS_MD_CAN_SHA3_256) && \ - !defined(MBEDTLS_MD_CAN_SHA3_384) && \ - !defined(MBEDTLS_MD_CAN_SHA3_512) -#error "MBEDTLS_MD_C defined, but no hash algorithm" -#endif - -#if defined(MBEDTLS_LMS_C) && \ - ! ( defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_ALG_SHA_256) ) -#error "MBEDTLS_LMS_C requires MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" -#endif - -#if defined(MBEDTLS_LMS_PRIVATE) && \ - ( !defined(MBEDTLS_LMS_C) ) -#error "MBEDTLS_LMS_PRIVATE requires MBEDTLS_LMS_C" -#endif - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_C) && \ - !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#error "MBEDTLS_PK_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_PARSE_C) && \ - (!defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_OID_C) || \ - !defined(MBEDTLS_PK_C)) -#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_WRITE_C) && \ - (!defined(MBEDTLS_ASN1_WRITE_C) || \ - !defined(MBEDTLS_OID_C) || \ - !defined(MBEDTLS_PK_C)) -#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ - defined(MBEDTLS_PLATFORM_EXIT_ALT) ) -#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_SETBUF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SETBUF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SETBUF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_SETBUF) ||\ - defined(MBEDTLS_PLATFORM_SETBUF_ALT) ) -#error "MBEDTLS_PLATFORM_SETBUF_MACRO and MBEDTLS_PLATFORM_STD_SETBUF/MBEDTLS_PLATFORM_SETBUF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_MS_TIME_ALT) && \ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_MS_TIME_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ - defined(MBEDTLS_PLATFORM_TIME_ALT) ) -#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ - defined(MBEDTLS_PLATFORM_TIME_ALT) ) -#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ - defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_FREE) -#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_CALLOC) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) -#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ - defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ - defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_VSNPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_VSNPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) ||\ - defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_VSNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_VSNPRINTF/MBEDTLS_PLATFORM_VSNPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ - !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ - !defined(MBEDTLS_PLATFORM_EXIT_ALT) -#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ - ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ - !defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) -#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ - !defined(MBEDTLS_ENTROPY_NV_SEED) -#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ - !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ - !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ - defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) -#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ - defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) -#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_C) && \ - !( ( ( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) ) && \ - defined(MBEDTLS_ENTROPY_C) ) || \ - defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) ) -#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_HAVE_SOFT_BLOCK_MODE) && \ - defined(PSA_HAVE_SOFT_BLOCK_CIPHER) && !defined(MBEDTLS_CIPHER_C) -#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C) -#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \ - ! ( defined(MBEDTLS_PSA_CRYPTO_C) && \ - defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) ) -#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -#if defined(MBEDTLS_DEPRECATED_REMOVED) -#error "MBEDTLS_PSA_CRYPTO_SE_C is deprecated and will be removed in a future version of Mbed TLS" -#elif defined(MBEDTLS_DEPRECATED_WARNING) -#warning "MBEDTLS_PSA_CRYPTO_SE_C is deprecated and will be removed in a future version of Mbed TLS" -#endif -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ - ! defined(MBEDTLS_PSA_CRYPTO_C) -#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ - !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ - defined(MBEDTLS_ENTROPY_NV_SEED) ) -#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ - !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) -#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources" -#endif - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ - defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG" -#endif - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && \ - defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) -#error "MBEDTLS_PSA_KEY_STORE_DYNAMIC and MBEDTLS_PSA_STATIC_KEY_SLOTS cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PSA_ITS_FILE_C) && \ - !defined(MBEDTLS_FS_IO) -#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) ) -#error "MBEDTLS_RSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) -#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) && \ - defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) -#error "Must only define one of MBEDTLS_SHA512_USE_A64_CRYPTO_*" -#endif - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \ - defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) -#if !defined(MBEDTLS_SHA512_C) -#error "MBEDTLS_SHA512_USE_A64_CRYPTO_* defined without MBEDTLS_SHA512_C" -#endif -#if defined(MBEDTLS_SHA512_ALT) || defined(MBEDTLS_SHA512_PROCESS_ALT) -#error "MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*" -#endif - -#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) && !defined(__aarch64__) -#error "MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY defined on non-Aarch64 system" -#endif - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) && \ - defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) -#error "Must only define one of MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*" -#endif - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \ - defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) -#if !defined(MBEDTLS_SHA256_C) -#error "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_* defined without MBEDTLS_SHA256_C" -#endif -#if defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA256_PROCESS_ALT) -#error "MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*" -#endif - -#endif - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) && !defined(MBEDTLS_ARCH_IS_ARMV8_A) -#error "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY defined on non-Armv8-A system" -#endif - -/* TLS 1.3 requires separate HKDF parts from PSA, - * and at least one ciphersuite, so at least SHA-256 or SHA-384 - * from PSA to use with HKDF. - * - * Note: for dependencies common with TLS 1.2 (running handshake hash), - * see MBEDTLS_SSL_TLS_C. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - !(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ - defined(PSA_WANT_ALG_HKDF_EXTRACT) && \ - defined(PSA_WANT_ALG_HKDF_EXPAND) && \ - (defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384))) -#error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -#if !( (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \ - defined(MBEDTLS_X509_CRT_PARSE_C) && \ - ( defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || defined(MBEDTLS_PKCS1_V21) ) ) -#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites" -#endif -#endif - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) -#if !( defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) ) -#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED defined, but not all prerequisites" -#endif -#endif - -/* - * The current implementation of TLS 1.3 requires MBEDTLS_SSL_KEEP_PEER_CERTIFICATE. - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#error "MBEDTLS_SSL_PROTO_TLS1_3 defined without MBEDTLS_SSL_KEEP_PEER_CERTIFICATE" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) -#error "One or more versions of the TLS protocol are enabled " \ - "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" -#endif - -#if defined(MBEDTLS_SSL_EARLY_DATA) && \ - ( !defined(MBEDTLS_SSL_SESSION_TICKETS) || \ - ( !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \ - !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) ) ) -#error "MBEDTLS_SSL_EARLY_DATA defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE) && \ - ((MBEDTLS_SSL_MAX_EARLY_DATA_SIZE < 0) || \ - (MBEDTLS_SSL_MAX_EARLY_DATA_SIZE > UINT32_MAX)) -#error "MBEDTLS_SSL_MAX_EARLY_DATA_SIZE must be in the range(0..UINT32_MAX)" -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && !defined(MBEDTLS_X509_CRT_PARSE_C) -#error "MBEDTLS_SSL_ASYNC_PRIVATE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && !(defined(MBEDTLS_CIPHER_C) || \ - defined(MBEDTLS_USE_PSA_CRYPTO)) -#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" -#endif - -/* TLS 1.2 and 1.3 require SHA-256 or SHA-384 (running handshake hash) */ -#if defined(MBEDTLS_SSL_TLS_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if !(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384)) -#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" -#endif -#else /* MBEDTLS_USE_PSA_CRYPTO */ -#if !defined(MBEDTLS_MD_C) || \ - !(defined(MBEDTLS_MD_CAN_SHA256) || defined(MBEDTLS_MD_CAN_SHA384)) -#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" -#endif -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_SSL_TLS_C */ - -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && \ - !( defined(MBEDTLS_SSL_PROTO_TLS1_2) || defined(MBEDTLS_SSL_PROTO_TLS1_3) ) -#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) -#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ - !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \ - MBEDTLS_SSL_CID_IN_LEN_MAX > 255 -#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \ - MBEDTLS_SSL_CID_OUT_LEN_MAX > 255 -#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && \ - !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0 -#if defined(MBEDTLS_DEPRECATED_REMOVED) -#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS" -#elif defined(MBEDTLS_DEPRECATED_WARNING) -#warning "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS" -#endif -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0 */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_RENEGOTIATION defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TICKET_C) && ( !defined(MBEDTLS_CIPHER_C) && \ - !defined(MBEDTLS_USE_PSA_CRYPTO) ) -#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TICKET_C) && \ - !( defined(MBEDTLS_SSL_HAVE_CCM) || defined(MBEDTLS_SSL_HAVE_GCM) || \ - defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) ) -#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH) && \ - MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH >= 256 -#error "MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH must be less than 256" -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ - !defined(MBEDTLS_X509_CRT_PARSE_C) -#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_THREADING_PTHREAD) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL // undef at the end of this paragraph -#endif -#if defined(MBEDTLS_THREADING_ALT) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL // undef at the end of this paragraph -#endif -#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_C defined, single threading implementation required" -#endif -#undef MBEDTLS_THREADING_IMPL // temporary macro defined above - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) -#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_USE_C) && \ - (!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_PK_PARSE_C) || \ - ( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) ) -#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CREATE_C) && \ - (!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ - !defined(MBEDTLS_PK_PARSE_C) || \ - ( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) ) -#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) && \ - ( !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64) -#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously" -#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */ - -#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \ - defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously" -#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) ) -#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) && ( !defined(MBEDTLS_SSL_PROTO_TLS1_3) ) -#error "MBEDTLS_SSL_RECORD_SIZE_LIMIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) && \ - !( defined(MBEDTLS_SSL_HAVE_CCM) || defined(MBEDTLS_SSL_HAVE_GCM) || \ - defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) ) -#error "MBEDTLS_SSL_CONTEXT_SERIALIZATION defined, but not all prerequisites" -#endif - -/* Reject attempts to enable options that have been removed and that could - * cause a build to succeed but with features removed. */ - -#if defined(MBEDTLS_HAVEGE_C) //no-check-names -#error "MBEDTLS_HAVEGE_C was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/2599" -#endif - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) //no-check-names -#error "MBEDTLS_SSL_HW_RECORD_ACCEL was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) //no-check-names -#error "MBEDTLS_SSL_PROTO_SSL3 (SSL v3.0 support) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" -#endif - -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) //no-check-names -#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO (SSL v2 ClientHello support) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) //no-check-names -#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT (compatibility with the buggy implementation of truncated HMAC in Mbed TLS up to 2.7) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" -#endif - -#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) //no-check-names -#error "MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES was removed in Mbed TLS 3.0. See the ChangeLog entry if you really need SHA-1-signed certificates." -#endif - -#if defined(MBEDTLS_ZLIB_SUPPORT) //no-check-names -#error "MBEDTLS_ZLIB_SUPPORT was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" -#endif - -#if defined(MBEDTLS_CHECK_PARAMS) //no-check-names -#error "MBEDTLS_CHECK_PARAMS was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4313" -#endif - -#if defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) //no-check-names -#error "MBEDTLS_SSL_CID_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4335" -#endif - -#if defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY) //no-check-names -#error "MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4335" -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) //no-check-names -#error "MBEDTLS_SSL_TRUNCATED_HMAC was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4341" -#endif - -#if defined(MBEDTLS_PKCS7_C) && ( ( !defined(MBEDTLS_ASN1_PARSE_C) ) || \ - ( !defined(MBEDTLS_OID_C) ) || ( !defined(MBEDTLS_PK_PARSE_C) ) || \ - ( !defined(MBEDTLS_X509_CRT_PARSE_C) ) || \ - ( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || \ - ( !defined(MBEDTLS_MD_C) ) ) -#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites" -#endif - -/* - * Avoid warning from -pedantic. This is a convenient place for this - * workaround since this is included by every single file before the - * #if defined(MBEDTLS_xxx_C) that results in empty translation units. - */ -typedef int mbedtls_iso_c_forbids_empty_translation_units; - -/* *INDENT-ON* */ -#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/vendor/mbedtls/include/mbedtls/cipher.h b/vendor/mbedtls/include/mbedtls/cipher.h deleted file mode 100644 index e54715215..000000000 --- a/vendor/mbedtls/include/mbedtls/cipher.h +++ /dev/null @@ -1,1250 +0,0 @@ -/** - * \file cipher.h - * - * \brief This file contains an abstraction interface for use with the cipher - * primitives provided by the library. It provides a common interface to all of - * the available cipher operations. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CIPHER_H -#define MBEDTLS_CIPHER_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -#define MBEDTLS_CIPHER_MODE_AEAD -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_CIPHER_MODE_WITH_PADDING -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - defined(MBEDTLS_CHACHA20_C) -#define MBEDTLS_CIPHER_MODE_STREAM -#endif - -/** The selected feature is not available. */ -#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 -/** Bad input parameters. */ -#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 -/** Failed to allocate memory. */ -#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 -/** Input data contains invalid padding and is rejected. */ -#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 -/** Decryption of block requires a full block. */ -#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 -/** Authentication failed (for AEAD modes). */ -#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 -/** The context is invalid. For example, because it was freed. */ -#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 - -#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */ -#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Supported cipher types. - * - * \warning DES/3DES are considered weak ciphers and their use - * constitutes a security risk. We recommend considering stronger - * ciphers instead. - */ -typedef enum { - MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ - MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ - MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ - MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. \warning DES is considered weak. */ - MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. \warning 3DES is considered weak. */ - MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ - MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ - MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ -} mbedtls_cipher_id_t; - -/** - * \brief Supported {cipher type, cipher mode} pairs. - * - * \warning DES/3DES are considered weak ciphers and their use - * constitutes a security risk. We recommend considering stronger - * ciphers instead. - */ -typedef enum { - MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ - MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ - MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ - MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. \warning DES is considered weak. */ - MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. \warning DES is considered weak. */ - MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. \warning 3DES is considered weak. */ - MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. \warning 3DES is considered weak. */ - MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. \warning 3DES is considered weak. */ - MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. \warning 3DES is considered weak. */ - MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG, /**< AES cipher with 128-bit CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG, /**< AES cipher with 192-bit CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG, /**< AES cipher with 256-bit CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG, /**< Camellia cipher with 128-bit CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG, /**< Camellia cipher with 192-bit CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG, /**< Camellia cipher with 256-bit CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ - MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ - MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ - MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ - MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ - MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ - MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG, /**< Aria cipher with 128-bit key and CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG, /**< Aria cipher with 192-bit key and CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG, /**< Aria cipher with 256-bit key and CCM_STAR_NO_TAG mode. */ - MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ - MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ - MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ - MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ - MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */ - MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */ - MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */ - MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */ - MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */ - MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */ -} mbedtls_cipher_type_t; - -/** Supported cipher modes. */ -typedef enum { - MBEDTLS_MODE_NONE = 0, /**< None. */ - MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ - MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ - MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ - MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ - MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ - MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ - MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ - MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ - MBEDTLS_MODE_CCM_STAR_NO_TAG, /**< The CCM*-no-tag cipher mode. */ - MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ - MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ - MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */ - MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */ -} mbedtls_cipher_mode_t; - -/** Supported cipher padding types. */ -typedef enum { - MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ - MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ - MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ - MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ - MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ -} mbedtls_cipher_padding_t; - -/** Type of operation. */ -typedef enum { - MBEDTLS_OPERATION_NONE = -1, - MBEDTLS_DECRYPT = 0, - MBEDTLS_ENCRYPT, -} mbedtls_operation_t; - -enum { - /** Undefined key length. */ - MBEDTLS_KEY_LENGTH_NONE = 0, - /** Key length, in bits (including parity), for DES keys. \warning DES is considered weak. */ - MBEDTLS_KEY_LENGTH_DES = 64, - /** Key length in bits, including parity, for DES in two-key EDE. \warning 3DES is considered weak. */ - MBEDTLS_KEY_LENGTH_DES_EDE = 128, - /** Key length in bits, including parity, for DES in three-key EDE. \warning 3DES is considered weak. */ - MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, -}; - -/** Maximum length of any IV, in Bytes. */ -/* This should ideally be derived automatically from list of ciphers. - * This should be kept in sync with MBEDTLS_SSL_MAX_IV_LENGTH defined - * in library/ssl_misc.h. */ -#define MBEDTLS_MAX_IV_LENGTH 16 - -/** Maximum block size of any cipher, in Bytes. */ -/* This should ideally be derived automatically from list of ciphers. - * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined - * in library/ssl_misc.h. */ -#define MBEDTLS_MAX_BLOCK_LENGTH 16 - -/** Maximum key length, in Bytes. */ -/* This should ideally be derived automatically from list of ciphers. - * For now, only check whether XTS is enabled which uses 64 Byte keys, - * and use 32 Bytes as an upper bound for the maximum key length otherwise. - * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined - * in library/ssl_misc.h, which however deliberately ignores the case of XTS - * since the latter isn't used in SSL/TLS. */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) -#define MBEDTLS_MAX_KEY_LENGTH 64 -#else -#define MBEDTLS_MAX_KEY_LENGTH 32 -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/** - * Base cipher information (opaque struct). - */ -typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; - -/** - * CMAC context (opaque struct). - */ -typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; - -/** - * Cipher information. Allows calling cipher functions - * in a generic way. - * - * \note The library does not support custom cipher info structures, - * only built-in structures returned by the functions - * mbedtls_cipher_info_from_string(), - * mbedtls_cipher_info_from_type(), - * mbedtls_cipher_info_from_values(), - * mbedtls_cipher_info_from_psa(). - * - * \note Some fields store a value that has been right-shifted to save - * code-size, so should not be used directly. The accessor - * functions adjust for this and return the "natural" value. - */ -typedef struct mbedtls_cipher_info_t { - /** Name of the cipher. */ - const char *MBEDTLS_PRIVATE(name); - - /** The block size, in bytes. */ - unsigned int MBEDTLS_PRIVATE(block_size) : 5; - - /** IV or nonce size, in bytes (right shifted by #MBEDTLS_IV_SIZE_SHIFT). - * For ciphers that accept variable IV sizes, - * this is the recommended size. - */ - unsigned int MBEDTLS_PRIVATE(iv_size) : 3; - - /** The cipher key length, in bits (right shifted by #MBEDTLS_KEY_BITLEN_SHIFT). - * This is the default length for variable sized ciphers. - * Includes parity bits for ciphers like DES. - */ - unsigned int MBEDTLS_PRIVATE(key_bitlen) : 4; - - /** The cipher mode (as per mbedtls_cipher_mode_t). - * For example, MBEDTLS_MODE_CBC. - */ - unsigned int MBEDTLS_PRIVATE(mode) : 4; - - /** Full cipher identifier (as per mbedtls_cipher_type_t). - * For example, MBEDTLS_CIPHER_AES_256_CBC. - * - * This could be 7 bits, but 8 bits retains byte alignment for the - * next field, which reduces code size to access that field. - */ - unsigned int MBEDTLS_PRIVATE(type) : 8; - - /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and - * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the - * cipher supports variable IV or variable key sizes, respectively. - */ - unsigned int MBEDTLS_PRIVATE(flags) : 2; - - /** Index to LUT for base cipher information and functions. */ - unsigned int MBEDTLS_PRIVATE(base_idx) : 5; - -} mbedtls_cipher_info_t; - -/* For internal use only. - * These are used to more compactly represent the fields above. */ -#define MBEDTLS_KEY_BITLEN_SHIFT 6 -#define MBEDTLS_IV_SIZE_SHIFT 2 -/** - * Generic cipher context. - */ -typedef struct mbedtls_cipher_context_t { - /** Information about the associated cipher. */ - const mbedtls_cipher_info_t *MBEDTLS_PRIVATE(cipher_info); - - /** Key length to use. */ - int MBEDTLS_PRIVATE(key_bitlen); - - /** Operation that the key of the context has been - * initialized for. - */ - mbedtls_operation_t MBEDTLS_PRIVATE(operation); - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /** Padding functions to use, if relevant for - * the specific cipher mode. - */ - void(*MBEDTLS_PRIVATE(add_padding))(unsigned char *output, size_t olen, - size_t data_len); - /* Report invalid-padding condition through the output parameter - * invalid_padding. To minimize changes in Mbed TLS 3.6, where this - * declaration is in a public header, use the public type size_t - * rather than the internal type mbedtls_ct_condition_t. */ - int(*MBEDTLS_PRIVATE(get_padding))(unsigned char *input, size_t ilen, - size_t *data_len, - size_t *invalid_padding); -#endif - - /** Buffer for input that has not been processed yet. */ - unsigned char MBEDTLS_PRIVATE(unprocessed_data)[MBEDTLS_MAX_BLOCK_LENGTH]; - - /** Number of Bytes that have not been processed yet. */ - size_t MBEDTLS_PRIVATE(unprocessed_len); - - /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number - * for XTS-mode. */ - unsigned char MBEDTLS_PRIVATE(iv)[MBEDTLS_MAX_IV_LENGTH]; - - /** IV size in Bytes, for ciphers with variable-length IVs. */ - size_t MBEDTLS_PRIVATE(iv_size); - - /** The cipher-specific context. */ - void *MBEDTLS_PRIVATE(cipher_ctx); - -#if defined(MBEDTLS_CMAC_C) - /** CMAC-specific context. */ - mbedtls_cmac_context_t *MBEDTLS_PRIVATE(cmac_ctx); -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - /** Indicates whether the cipher operations should be performed - * by Mbed TLS' own crypto library or an external implementation - * of the PSA Crypto API. - * This is unset if the cipher context was established through - * mbedtls_cipher_setup(), and set if it was established through - * mbedtls_cipher_setup_psa(). - */ - unsigned char MBEDTLS_PRIVATE(psa_enabled); -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -} mbedtls_cipher_context_t; - -/** - * \brief This function retrieves the list of ciphers supported - * by the generic cipher module. - * - * For any cipher identifier in the returned list, you can - * obtain the corresponding generic cipher information structure - * via mbedtls_cipher_info_from_type(), which can then be used - * to prepare a cipher context via mbedtls_cipher_setup(). - * - * - * \return A statically-allocated array of cipher identifiers - * of type cipher_type_t. The last entry is zero. - */ -const int *mbedtls_cipher_list(void); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher name. - * - * \param cipher_name Name of the cipher to search for. This must not be - * \c NULL. - * - * \return The cipher information structure associated with the - * given \p cipher_name. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(const char *cipher_name); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher type. - * - * \param cipher_type Type of the cipher to search for. - * - * \return The cipher information structure associated with the - * given \p cipher_type. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(const mbedtls_cipher_type_t cipher_type); - -/** - * \brief This function retrieves the cipher-information - * structure associated with the given cipher ID, - * key size and mode. - * - * \param cipher_id The ID of the cipher to search for. For example, - * #MBEDTLS_CIPHER_ID_AES. - * \param key_bitlen The length of the key in bits. - * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. - * - * \return The cipher information structure associated with the - * given \p cipher_id. - * \return \c NULL if the associated cipher information is not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode); - -/** - * \brief Retrieve the identifier for a cipher info structure. - * - * \param[in] info The cipher info structure to query. - * This may be \c NULL. - * - * \return The full cipher identifier (\c MBEDTLS_CIPHER_xxx). - * \return #MBEDTLS_CIPHER_NONE if \p info is \c NULL. - */ -static inline mbedtls_cipher_type_t mbedtls_cipher_info_get_type( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return MBEDTLS_CIPHER_NONE; - } else { - return (mbedtls_cipher_type_t) info->MBEDTLS_PRIVATE(type); - } -} - -/** - * \brief Retrieve the operation mode for a cipher info structure. - * - * \param[in] info The cipher info structure to query. - * This may be \c NULL. - * - * \return The cipher mode (\c MBEDTLS_MODE_xxx). - * \return #MBEDTLS_MODE_NONE if \p info is \c NULL. - */ -static inline mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return MBEDTLS_MODE_NONE; - } else { - return (mbedtls_cipher_mode_t) info->MBEDTLS_PRIVATE(mode); - } -} - -/** - * \brief Retrieve the key size for a cipher info structure. - * - * \param[in] info The cipher info structure to query. - * This may be \c NULL. - * - * \return The key length in bits. - * For variable-sized ciphers, this is the default length. - * For DES, this includes the parity bits. - * \return \c 0 if \p info is \c NULL. - */ -static inline size_t mbedtls_cipher_info_get_key_bitlen( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return 0; - } else { - return ((size_t) info->MBEDTLS_PRIVATE(key_bitlen)) << MBEDTLS_KEY_BITLEN_SHIFT; - } -} - -/** - * \brief Retrieve the human-readable name for a - * cipher info structure. - * - * \param[in] info The cipher info structure to query. - * This may be \c NULL. - * - * \return The cipher name, which is a human readable string, - * with static storage duration. - * \return \c NULL if \p info is \c NULL. - */ -static inline const char *mbedtls_cipher_info_get_name( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return NULL; - } else { - return info->MBEDTLS_PRIVATE(name); - } -} - -/** - * \brief This function returns the size of the IV or nonce - * for the cipher info structure, in bytes. - * - * \param info The cipher info structure. This may be \c NULL. - * - * \return The recommended IV size. - * \return \c 0 for ciphers not using an IV or a nonce. - * \return \c 0 if \p info is \c NULL. - */ -static inline size_t mbedtls_cipher_info_get_iv_size( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return 0; - } - - return ((size_t) info->MBEDTLS_PRIVATE(iv_size)) << MBEDTLS_IV_SIZE_SHIFT; -} - -/** - * \brief This function returns the block size of the given - * cipher info structure in bytes. - * - * \param info The cipher info structure. This may be \c NULL. - * - * \return The block size of the cipher. - * \return \c 1 if the cipher is a stream cipher. - * \return \c 0 if \p info is \c NULL. - */ -static inline size_t mbedtls_cipher_info_get_block_size( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return 0; - } - - return (size_t) (info->MBEDTLS_PRIVATE(block_size)); -} - -/** - * \brief This function returns a non-zero value if the key length for - * the given cipher is variable. - * - * \param info The cipher info structure. This may be \c NULL. - * - * \return Non-zero if the key length is variable, \c 0 otherwise. - * \return \c 0 if the given pointer is \c NULL. - */ -static inline int mbedtls_cipher_info_has_variable_key_bitlen( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return 0; - } - - return info->MBEDTLS_PRIVATE(flags) & MBEDTLS_CIPHER_VARIABLE_KEY_LEN; -} - -/** - * \brief This function returns a non-zero value if the IV size for - * the given cipher is variable. - * - * \param info The cipher info structure. This may be \c NULL. - * - * \return Non-zero if the IV size is variable, \c 0 otherwise. - * \return \c 0 if the given pointer is \c NULL. - */ -static inline int mbedtls_cipher_info_has_variable_iv_size( - const mbedtls_cipher_info_t *info) -{ - if (info == NULL) { - return 0; - } - - return info->MBEDTLS_PRIVATE(flags) & MBEDTLS_CIPHER_VARIABLE_IV_LEN; -} - -/** - * \brief This function initializes a \p ctx as NONE. - * - * \param ctx The context to be initialized. This must not be \c NULL. - */ -void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx); - -/** - * \brief This function frees and clears the cipher-specific - * context of \p ctx. Freeing \p ctx itself remains the - * responsibility of the caller. - * - * \param ctx The context to be freed. If this is \c NULL, the - * function has no effect, otherwise this must point to an - * initialized context. - */ -void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx); - - -/** - * \brief This function prepares a cipher context for - * use with the given cipher primitive. - * - * \note After calling this function, you should call - * mbedtls_cipher_setkey() and, if the mode uses padding, - * mbedtls_cipher_set_padding_mode(), then for each - * message to encrypt or decrypt with this key, either: - * - mbedtls_cipher_crypt() for one-shot processing with - * non-AEAD modes; - * - mbedtls_cipher_auth_encrypt_ext() or - * mbedtls_cipher_auth_decrypt_ext() for one-shot - * processing with AEAD modes or NIST_KW; - * - for multi-part processing, see the documentation of - * mbedtls_cipher_reset(). - * - * \param ctx The context to prepare. This must be initialized by - * a call to mbedtls_cipher_init() first. - * \param cipher_info The cipher to use. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the - * cipher-specific context fails. - */ -int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief This function initializes a cipher context for - * PSA-based use with the given cipher primitive. - * - * \deprecated This function is deprecated and will be removed in a - * future version of the library. - * Please use psa_aead_xxx() / psa_cipher_xxx() directly - * instead. - * - * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA. - * - * \param ctx The context to initialize. May not be \c NULL. - * \param cipher_info The cipher to use. - * \param taglen For AEAD ciphers, the length in bytes of the - * authentication tag to use. Subsequent uses of - * mbedtls_cipher_auth_encrypt_ext() or - * mbedtls_cipher_auth_decrypt_ext() must provide - * the same tag length. - * For non-AEAD ciphers, the value must be \c 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the - * cipher-specific context fails. - */ -int MBEDTLS_DEPRECATED mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info, - size_t taglen); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/** - * \brief This function returns the block size of the given cipher - * in bytes. - * - * \param ctx The context of the cipher. - * - * \return The block size of the underlying cipher. - * \return \c 1 if the cipher is a stream cipher. - * \return \c 0 if \p ctx has not been initialized. - */ -static inline unsigned int mbedtls_cipher_get_block_size( - const mbedtls_cipher_context_t *ctx) -{ - if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { - return 0; - } - - return (unsigned int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(block_size); -} - -/** - * \brief This function returns the mode of operation for - * the cipher. For example, MBEDTLS_MODE_CBC. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The mode of operation. - * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( - const mbedtls_cipher_context_t *ctx) -{ - if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { - return MBEDTLS_MODE_NONE; - } - - return (mbedtls_cipher_mode_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(mode); -} - -/** - * \brief This function returns the size of the IV or nonce - * of the cipher, in Bytes. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The recommended IV size if no IV has been set. - * \return \c 0 for ciphers not using an IV or a nonce. - * \return The actual size if an IV has been set. - */ -static inline int mbedtls_cipher_get_iv_size( - const mbedtls_cipher_context_t *ctx) -{ - if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { - return 0; - } - - if (ctx->MBEDTLS_PRIVATE(iv_size) != 0) { - return (int) ctx->MBEDTLS_PRIVATE(iv_size); - } - - return (int) (((int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(iv_size)) << - MBEDTLS_IV_SIZE_SHIFT); -} - -/** - * \brief This function returns the type of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The type of the cipher. - * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( - const mbedtls_cipher_context_t *ctx) -{ - if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { - return MBEDTLS_CIPHER_NONE; - } - - return (mbedtls_cipher_type_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(type); -} - -/** - * \brief This function returns the name of the given cipher - * as a string. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The name of the cipher. - * \return NULL if \p ctx has not been not initialized. - */ -static inline const char *mbedtls_cipher_get_name( - const mbedtls_cipher_context_t *ctx) -{ - if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { - return 0; - } - - return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(name); -} - -/** - * \brief This function returns the key length of the cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The key length of the cipher in bits. - * \return #MBEDTLS_KEY_LENGTH_NONE if \p ctx has not been - * initialized. - */ -static inline int mbedtls_cipher_get_key_bitlen( - const mbedtls_cipher_context_t *ctx) -{ - if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { - return MBEDTLS_KEY_LENGTH_NONE; - } - - return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(key_bitlen) << - MBEDTLS_KEY_BITLEN_SHIFT; -} - -/** - * \brief This function returns the operation of the given cipher. - * - * \param ctx The context of the cipher. This must be initialized. - * - * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. - * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. - */ -static inline mbedtls_operation_t mbedtls_cipher_get_operation( - const mbedtls_cipher_context_t *ctx) -{ - if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { - return MBEDTLS_OPERATION_NONE; - } - - return ctx->MBEDTLS_PRIVATE(operation); -} - -/** - * \brief This function sets the key to use with the given context. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param key The key to use. This must be a readable buffer of at - * least \p key_bitlen Bits. - * \param key_bitlen The key length to use, in Bits. - * \param operation The operation that the key will be used for: - * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation); - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -/** - * \brief This function sets the padding mode, for cipher modes - * that use padding. - * - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param mode The padding mode. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE - * if the selected padding mode is not supported. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode - * does not support padding. - */ -int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, - mbedtls_cipher_padding_t mode); -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -/** - * \brief This function sets the initialization vector (IV) - * or nonce. - * - * \note Some ciphers do not use IVs nor nonce. For these - * ciphers, this function has no effect. - * - * \note For #MBEDTLS_CIPHER_CHACHA20, the nonce length must - * be 12, and the initial counter value is 0. - * - * \note For #MBEDTLS_CIPHER_CHACHA20_POLY1305, the nonce length - * must be 12. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a cipher information structure. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This - * must be a readable buffer of at least \p iv_len Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - */ -int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len); - -/** - * \brief This function resets the cipher state. - * - * \note With non-AEAD ciphers, the order of calls for each message - * is as follows: - * 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce; - * 2. mbedtls_cipher_reset(); - * 3. mbedtls_cipher_update() zero, one or more times; - * 4. mbedtls_cipher_finish_padded() (recommended for decryption - * if the mode uses padding) or mbedtls_cipher_finish(). - * . - * This sequence can be repeated to encrypt or decrypt multiple - * messages with the same key. - * - * \note With AEAD ciphers, the order of calls for each message - * is as follows: - * 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce; - * 2. mbedtls_cipher_reset(); - * 3. mbedtls_cipher_update_ad(); - * 4. mbedtls_cipher_update() zero, one or more times; - * 5. mbedtls_cipher_finish() (or mbedtls_cipher_finish_padded()); - * 6. mbedtls_cipher_check_tag() (for decryption) or - * mbedtls_cipher_write_tag() (for encryption). - * . - * This sequence can be repeated to encrypt or decrypt multiple - * messages with the same key. - * - * \param ctx The generic cipher context. This must be bound to a key. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - */ -int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx); - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/** - * \brief This function adds additional data for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * - * \param ctx The generic cipher context. This must be initialized. - * \param ad The additional data to use. This must be a readable - * buffer of at least \p ad_len Bytes. - * \param ad_len The length of \p ad in Bytes. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/** - * \brief The generic cipher update function. It encrypts or - * decrypts using the given cipher context. Writes as - * many block-sized blocks of data as possible to output. - * Any data that cannot be written immediately is either - * added to the next block, or flushed when - * mbedtls_cipher_finish() or mbedtls_cipher_finish_padded() - * is called. - * Exception: For MBEDTLS_MODE_ECB, expects a single block - * in size. For example, 16 Bytes for AES. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an - * unsupported mode for a cipher. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, - const unsigned char *input, - size_t ilen, unsigned char *output, - size_t *olen); - -/** - * \brief The generic cipher finalization function. If data still - * needs to be flushed from an incomplete block, the data - * contained in it is padded to the size of - * the last block, and written to the \p output buffer. - * - * \warning This function reports invalid padding through an error - * code. Adversaries may be able to decrypt encrypted - * data if they can submit chosen ciphertexts and - * detect whether it has valid padding or not, - * either through direct observation or through a side - * channel such as timing. This is known as a - * padding oracle attack. - * Therefore applications that call this function for - * decryption with a cipher that involves padding - * should take care around error handling. Preferably, - * such applications should use - * mbedtls_cipher_finish_padded() instead of this function. - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param output The buffer to write data to. This needs to be a writable - * buffer of at least block_size Bytes. - * \param olen The length of the data written to the \p output buffer. - * This may not be \c NULL. - * Note that when decrypting in a mode with padding, - * the actual output length is sensitive and may be - * used to mount a padding oracle attack (see warning - * above), although less efficiently than through - * the invalid-padding condition. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. Note that invalid-padding errors - * should be handled carefully; see the warning above. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen); - -/** - * \brief The generic cipher finalization function. If data still - * needs to be flushed from an incomplete block, the data - * contained in it is padded to the size of - * the last block, and written to the \p output buffer. - * - * \note This function is similar to mbedtls_cipher_finish(). - * The only difference is that it reports invalid padding - * decryption differently, through the \p invalid_padding - * parameter rather than an error code. - * For encryption, and in modes without padding (including - * all authenticated modes), this function is identical - * to mbedtls_cipher_finish(). - * - * \param[in,out] ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param[out] output The buffer to write data to. This needs to be a writable - * buffer of at least block_size Bytes. - * \param[out] olen The length of the data written to the \p output buffer. - * This may not be \c NULL. - * Note that when decrypting in a mode with padding, - * the actual output length is sensitive and may be - * used to mount a padding oracle attack (see warning - * on mbedtls_cipher_finish()). - * \param[out] invalid_padding - * If this function returns \c 0 on decryption, - * \p *invalid_padding is \c 0 if the ciphertext was - * valid, and all-bits-one if the ciphertext had invalid - * padding. - * On encryption, or in a mode without padding (including - * all authenticated modes), \p *invalid_padding is \c 0 - * on success. - * The value in \p *invalid_padding is unspecified if - * this function returns a nonzero status. - * - * \return \c 0 on success. - * Also \c 0 for decryption with invalid padding. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen, - size_t *invalid_padding); - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/** - * \brief This function writes a tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish() - * or mbedtls_cipher_finish_padded(). - * - * \param ctx The generic cipher context. This must be initialized, - * bound to a key, and have just completed a cipher - * operation through mbedtls_cipher_finish() the tag for - * which should be written. - * \param tag The buffer to write the tag to. This must be a writable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to write. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len); - -/** - * \brief This function checks the tag for AEAD ciphers. - * Currently supported with GCM and ChaCha20+Poly1305. - * This must be called after mbedtls_cipher_finish() - * or mbedtls_cipher_finish_padded(). - * - * \param ctx The generic cipher context. This must be initialized. - * \param tag The buffer holding the tag. This must be a readable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to check. - * - * \return \c 0 on success. - * \return A specific error code on failure. - */ -int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len); -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/** - * \brief The generic all-in-one encryption/decryption function, - * for all ciphers except AEAD constructs. - * - * \param ctx The generic cipher context. This must be initialized. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size - * IV. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The buffer for the output data. This must be able to - * hold at least `ilen + block_size`. This must not be the - * same buffer as \p input. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * - * \note Some ciphers do not use IVs nor nonce. For these - * ciphers, use \p iv = NULL and \p iv_len = 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption - * expecting a full block but not receiving one. - * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen); - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C) -/** - * \brief The authenticated encryption (AEAD/NIST_KW) function. - * - * \note For AEAD modes, the tag will be appended to the - * ciphertext, as recommended by RFC 5116. - * (NIST_KW doesn't have a separate tag.) - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key, with an AEAD algorithm or NIST_KW. - * \param iv The nonce to use. This must be a readable buffer of - * at least \p iv_len Bytes and may be \c NULL if \p - * iv_len is \c 0. - * \param iv_len The length of the nonce. For AEAD ciphers, this must - * satisfy the constraints imposed by the cipher used. - * For NIST_KW, this must be \c 0. - * \param ad The additional data to authenticate. This must be a - * readable buffer of at least \p ad_len Bytes, and may - * be \c NULL is \p ad_len is \c 0. - * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes, and may be - * \c NULL if \p ilen is \c 0. - * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be a - * writable buffer of at least \p output_len Bytes, and - * must not be \c NULL. - * \param output_len The length of the \p output buffer in Bytes. For AEAD - * ciphers, this must be at least \p ilen + \p tag_len. - * For NIST_KW, this must be at least \p ilen + 8 - * (rounded up to a multiple of 8 if KWP is used); - * \p ilen + 15 is always a safe value. - * \param olen This will be filled with the actual number of Bytes - * written to the \p output buffer. This must point to a - * writable object of type \c size_t. - * \param tag_len The desired length of the authentication tag. For AEAD - * ciphers, this must match the constraints imposed by - * the cipher used, and in particular must not be \c 0. - * For NIST_KW, this must be \c 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t output_len, - size_t *olen, size_t tag_len); - -/** - * \brief The authenticated encryption (AEAD/NIST_KW) function. - * - * \note If the data is not authentic, then the output buffer - * is zeroed out to prevent the unauthentic plaintext being - * used, making this interface safer. - * - * \note For AEAD modes, the tag must be appended to the - * ciphertext, as recommended by RFC 5116. - * (NIST_KW doesn't have a separate tag.) - * - * \param ctx The generic cipher context. This must be initialized and - * bound to a key, with an AEAD algorithm or NIST_KW. - * \param iv The nonce to use. This must be a readable buffer of - * at least \p iv_len Bytes and may be \c NULL if \p - * iv_len is \c 0. - * \param iv_len The length of the nonce. For AEAD ciphers, this must - * satisfy the constraints imposed by the cipher used. - * For NIST_KW, this must be \c 0. - * \param ad The additional data to authenticate. This must be a - * readable buffer of at least \p ad_len Bytes, and may - * be \c NULL is \p ad_len is \c 0. - * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. - * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes, and may be - * \c NULL if \p ilen is \c 0. - * \param ilen The length of the input data. For AEAD ciphers this - * must be at least \p tag_len. For NIST_KW this must be - * at least \c 8. - * \param output The buffer for the output data. This must be a - * writable buffer of at least \p output_len Bytes, and - * may be \c NULL if \p output_len is \c 0. - * \param output_len The length of the \p output buffer in Bytes. For AEAD - * ciphers, this must be at least \p ilen - \p tag_len. - * For NIST_KW, this must be at least \p ilen - 8. - * \param olen This will be filled with the actual number of Bytes - * written to the \p output buffer. This must point to a - * writable object of type \c size_t. - * \param tag_len The actual length of the authentication tag. For AEAD - * ciphers, this must match the constraints imposed by - * the cipher used, and in particular must not be \c 0. - * For NIST_KW, this must be \c 0. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on - * parameter-verification failure. - * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t output_len, - size_t *olen, size_t tag_len); -#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */ -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_H */ diff --git a/vendor/mbedtls/include/mbedtls/cmac.h b/vendor/mbedtls/include/mbedtls/cmac.h deleted file mode 100644 index 97b86fc42..000000000 --- a/vendor/mbedtls/include/mbedtls/cmac.h +++ /dev/null @@ -1,246 +0,0 @@ -/** - * \file cmac.h - * - * \brief This file contains CMAC definitions and functions. - * - * The Cipher-based Message Authentication Code (CMAC) Mode for - * Authentication is defined in RFC-4493: The AES-CMAC Algorithm. - * It is supported with AES and DES. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CMAC_H -#define MBEDTLS_CMAC_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MBEDTLS_AES_BLOCK_SIZE 16 -#define MBEDTLS_DES3_BLOCK_SIZE 8 - -/* We don't support Camellia or ARIA in this module */ -#if defined(MBEDTLS_AES_C) -#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 16 /**< The longest block used by CMAC is that of AES. */ -#else -#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 8 /**< The longest block used by CMAC is that of 3DES. */ -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** The longest block supported by the cipher module. - * - * \deprecated - * For the maximum block size of a cipher supported by the CMAC module, - * use #MBEDTLS_CMAC_MAX_BLOCK_SIZE. - * For the maximum block size of a cipher supported by the cipher module, - * use #MBEDTLS_MAX_BLOCK_LENGTH. - */ -/* Before Mbed TLS 3.5, this was the maximum block size supported by the CMAC - * module, so it didn't take Camellia or ARIA into account. Since the name - * of the macro doesn't even convey "CMAC", this was misleading. Now the size - * is sufficient for any cipher, but the name is defined in cmac.h for - * backward compatibility. */ -#define MBEDTLS_CIPHER_BLKSIZE_MAX MBEDTLS_MAX_BLOCK_LENGTH -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -#if !defined(MBEDTLS_CMAC_ALT) - -/** - * The CMAC context structure. - */ -struct mbedtls_cmac_context_t { - /** The internal state of the CMAC algorithm. */ - unsigned char MBEDTLS_PRIVATE(state)[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - - /** Unprocessed data - either data that was not block aligned and is still - * pending processing, or the final block. */ - unsigned char MBEDTLS_PRIVATE(unprocessed_block)[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - - /** The length of data pending processing. */ - size_t MBEDTLS_PRIVATE(unprocessed_len); -}; - -#else /* !MBEDTLS_CMAC_ALT */ -#include "cmac_alt.h" -#endif /* !MBEDTLS_CMAC_ALT */ - -/** - * \brief This function starts a new CMAC computation - * by setting the CMAC key, and preparing to authenticate - * the input data. - * It must be called with an initialized cipher context. - * - * Once this function has completed, data can be supplied - * to the CMAC computation by calling - * mbedtls_cipher_cmac_update(). - * - * To start a CMAC computation using the same key as a previous - * CMAC computation, use mbedtls_cipher_cmac_finish(). - * - * \note When the CMAC implementation is supplied by an alternate - * implementation (through #MBEDTLS_CMAC_ALT), some ciphers - * may not be supported by that implementation, and thus - * return an error. Alternate implementations must support - * AES-128 and AES-256, and may support AES-192 and 3DES. - * - * \param ctx The cipher context used for the CMAC operation, initialized - * as one of the following types: MBEDTLS_CIPHER_AES_128_ECB, - * MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB, - * or MBEDTLS_CIPHER_DES_EDE3_ECB. - * \param key The CMAC key. - * \param keybits The length of the CMAC key in bits. - * Must be supported by the cipher. - * - * \return \c 0 on success. - * \return A cipher-specific error code on failure. - */ -int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx, - const unsigned char *key, size_t keybits); - -/** - * \brief This function feeds an input buffer into an ongoing CMAC - * computation. - * - * The CMAC computation must have previously been started - * by calling mbedtls_cipher_cmac_starts() or - * mbedtls_cipher_cmac_reset(). - * - * Call this function as many times as needed to input the - * data to be authenticated. - * Once all of the required data has been input, - * call mbedtls_cipher_cmac_finish() to obtain the result - * of the CMAC operation. - * - * \param ctx The cipher context used for the CMAC operation. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx, - const unsigned char *input, size_t ilen); - -/** - * \brief This function finishes an ongoing CMAC operation, and - * writes the result to the output buffer. - * - * It should be followed either by - * mbedtls_cipher_cmac_reset(), which starts another CMAC - * operation with the same key, or mbedtls_cipher_free(), - * which clears the cipher context. - * - * \param ctx The cipher context used for the CMAC operation. - * \param output The output buffer for the CMAC checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx, - unsigned char *output); - -/** - * \brief This function starts a new CMAC operation with the same - * key as the previous one. - * - * It should be called after finishing the previous CMAC - * operation with mbedtls_cipher_cmac_finish(). - * After calling this function, - * call mbedtls_cipher_cmac_update() to supply the new - * CMAC operation with data. - * - * \param ctx The cipher context used for the CMAC operation. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx); - -/** - * \brief This function calculates the full generic CMAC - * on the input buffer with the provided key. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The CMAC result is calculated as - * output = generic CMAC(cmac key, input buffer). - * - * \note When the CMAC implementation is supplied by an alternate - * implementation (through #MBEDTLS_CMAC_ALT), some ciphers - * may not be supported by that implementation, and thus - * return an error. Alternate implementations must support - * AES-128 and AES-256, and may support AES-192 and 3DES. - * - * \param cipher_info The cipher information. - * \param key The CMAC key. - * \param keylen The length of the CMAC key in bits. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * \param output The buffer for the generic CMAC result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output); - -#if defined(MBEDTLS_AES_C) -/** - * \brief This function implements the AES-CMAC-PRF-128 pseudorandom - * function, as defined in - * RFC-4615: The Advanced Encryption Standard-Cipher-based - * Message Authentication Code-Pseudo-Random Function-128 - * (AES-CMAC-PRF-128) Algorithm for the Internet Key - * Exchange Protocol (IKE). - * - * \param key The key to use. - * \param key_len The key length in Bytes. - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * \param output The buffer holding the generated 16 Bytes of - * pseudorandom output. - * - * \return \c 0 on success. - */ -int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_len, - const unsigned char *input, size_t in_len, - unsigned char output[16]); -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_SELF_TEST) && (defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)) -/** - * \brief The CMAC checkup routine. - * - * \note In case the CMAC routines are provided by an alternative - * implementation (i.e. #MBEDTLS_CMAC_ALT is defined), the - * checkup routine will succeed even if the implementation does - * not support the less widely used AES-192 or 3DES primitives. - * The self-test requires at least AES-128 and AES-256 to be - * supported by the underlying implementation. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_cmac_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CMAC_H */ diff --git a/vendor/mbedtls/include/mbedtls/compat-2.x.h b/vendor/mbedtls/include/mbedtls/compat-2.x.h deleted file mode 100644 index 096341ba7..000000000 --- a/vendor/mbedtls/include/mbedtls/compat-2.x.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * \file compat-2.x.h - * - * \brief Compatibility definitions - * - * \deprecated Use the new names directly instead - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Including compat-2.x.h is deprecated" -#endif - -#ifndef MBEDTLS_COMPAT2X_H -#define MBEDTLS_COMPAT2X_H - -/* - * Macros for renamed functions - */ -#define mbedtls_ctr_drbg_update_ret mbedtls_ctr_drbg_update -#define mbedtls_hmac_drbg_update_ret mbedtls_hmac_drbg_update -#define mbedtls_md5_starts_ret mbedtls_md5_starts -#define mbedtls_md5_update_ret mbedtls_md5_update -#define mbedtls_md5_finish_ret mbedtls_md5_finish -#define mbedtls_md5_ret mbedtls_md5 -#define mbedtls_ripemd160_starts_ret mbedtls_ripemd160_starts -#define mbedtls_ripemd160_update_ret mbedtls_ripemd160_update -#define mbedtls_ripemd160_finish_ret mbedtls_ripemd160_finish -#define mbedtls_ripemd160_ret mbedtls_ripemd160 -#define mbedtls_sha1_starts_ret mbedtls_sha1_starts -#define mbedtls_sha1_update_ret mbedtls_sha1_update -#define mbedtls_sha1_finish_ret mbedtls_sha1_finish -#define mbedtls_sha1_ret mbedtls_sha1 -#define mbedtls_sha256_starts_ret mbedtls_sha256_starts -#define mbedtls_sha256_update_ret mbedtls_sha256_update -#define mbedtls_sha256_finish_ret mbedtls_sha256_finish -#define mbedtls_sha256_ret mbedtls_sha256 -#define mbedtls_sha512_starts_ret mbedtls_sha512_starts -#define mbedtls_sha512_update_ret mbedtls_sha512_update -#define mbedtls_sha512_finish_ret mbedtls_sha512_finish -#define mbedtls_sha512_ret mbedtls_sha512 - -#endif /* MBEDTLS_COMPAT2X_H */ diff --git a/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h b/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h deleted file mode 100644 index db684ad20..000000000 --- a/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +++ /dev/null @@ -1,578 +0,0 @@ -/** - * \file mbedtls/config_adjust_legacy_crypto.h - * \brief Adjust legacy configuration configuration - * - * This is an internal header. Do not include it directly. - * - * Automatically enable certain dependencies. Generally, MBEDTLS_xxx - * configurations need to be explicitly enabled by the user: enabling - * MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a - * compilation error. However, we do automatically enable certain options - * in some circumstances. One case is if MBEDTLS_xxx_B is an internal option - * used to identify parts of a module that are used by other module, and we - * don't want to make the symbol MBEDTLS_xxx_B part of the public API. - * Another case is if A didn't depend on B in earlier versions, and we - * want to use B in A but we need to preserve backward compatibility with - * configurations that explicitly activate MBEDTLS_xxx_A but not - * MBEDTLS_xxx_B. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H -#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -/* Ideally, we'd set those as defaults in mbedtls_config.h, but - * putting an #ifdef _WIN32 in mbedtls_config.h would confuse config.py. - * - * So, adjust it here. - * Not related to crypto, but this is the bottom of the stack. */ -#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) -#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ - !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define MBEDTLS_PLATFORM_SNPRINTF_ALT -#endif -#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \ - !defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) -#define MBEDTLS_PLATFORM_VSNPRINTF_ALT -#endif -#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */ - -/* The number of "true" entropy sources (excluding NV seed). - * This must be consistent with mbedtls_entropy_init() in entropy.c. - */ -/* Define auxiliary macros, because in standard C, defined(xxx) is only - * allowed directly on an #if or #elif line, not in recursive expansion. */ -#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) -#define MBEDTLS_PLATFORM_ENTROPY_ENABLED 0 -#else -#define MBEDTLS_PLATFORM_ENTROPY_ENABLED 1 -#endif -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) -#define MBEDTLS_ENTROPY_HARDWARE_ALT_DEFINED 1 -#else -#define MBEDTLS_ENTROPY_HARDWARE_ALT_DEFINED 0 -#endif - -#define MBEDTLS_ENTROPY_TRUE_SOURCES ( \ - MBEDTLS_ENTROPY_HARDWARE_ALT_DEFINED + \ - MBEDTLS_PLATFORM_ENTROPY_ENABLED + \ - 0) - -/* Whether there is at least one entropy source for the entropy module. - * - * Note that when MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, the entropy - * module is unused and the configuration will typically not include any - * entropy source, so this macro will typically remain undefined. - */ -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#define MBEDTLS_ENTROPY_HAVE_SOURCES (MBEDTLS_ENTROPY_TRUE_SOURCES + 1) -#elif MBEDTLS_ENTROPY_TRUE_SOURCES != 0 -#define MBEDTLS_ENTROPY_HAVE_SOURCES MBEDTLS_ENTROPY_TRUE_SOURCES -#else -#undef MBEDTLS_ENTROPY_HAVE_SOURCES -#endif - -/* Test function dependencies can only check with defined(), - * not other preprocessor expressions. */ -#if MBEDTLS_ENTROPY_TRUE_SOURCES > 0 -#define MBEDTLS_ENTROPY_HAVE_TRUE_SOURCES -#else -#undef MBEDTLS_ENTROPY_HAVE_TRUE_SOURCES -#endif - -/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT - * is defined as well to include all PSA code. - */ -#if defined(MBEDTLS_PSA_CRYPTO_C) -#define MBEDTLS_PSA_CRYPTO_CLIENT -#endif /* MBEDTLS_PSA_CRYPTO_C */ - -/* Auto-enable CIPHER_C when any of the unauthenticated ciphers is builtin - * in PSA. */ -#if defined(MBEDTLS_PSA_CRYPTO_C) && \ - (defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)) -#define MBEDTLS_CIPHER_C -#endif - -/* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C. - * This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C. - */ -#if defined(MBEDTLS_MD_C) -#define MBEDTLS_MD_LIGHT -#endif - -/* Auto-enable MBEDTLS_MD_LIGHT if needed by a module that didn't require it - * in a previous release, to ensure backwards compatibility. - */ -#if defined(MBEDTLS_ECJPAKE_C) || \ - defined(MBEDTLS_PEM_PARSE_C) || \ - defined(MBEDTLS_ENTROPY_C) || \ - defined(MBEDTLS_PK_C) || \ - defined(MBEDTLS_PKCS12_C) || \ - defined(MBEDTLS_RSA_C) || \ - defined(MBEDTLS_SSL_TLS_C) || \ - defined(MBEDTLS_X509_USE_C) || \ - defined(MBEDTLS_X509_CREATE_C) -#define MBEDTLS_MD_LIGHT -#endif - -#if defined(MBEDTLS_MD_LIGHT) -/* - * - MBEDTLS_MD_CAN_xxx is defined if the md module can perform xxx. - * - MBEDTLS_MD_xxx_VIA_PSA is defined if the md module may perform xxx via PSA - * (see below). - * - MBEDTLS_MD_SOME_PSA is defined if at least one algorithm may be performed - * via PSA (see below). - * - MBEDTLS_MD_SOME_LEGACY is defined if at least one algorithm may be performed - * via a direct legacy call (see below). - * - * The md module performs an algorithm via PSA if there is a PSA hash - * accelerator and the PSA driver subsytem is initialized at the time the - * operation is started, and makes a direct legacy call otherwise. - */ - -/* PSA accelerated implementations */ -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5) -#define MBEDTLS_MD_CAN_MD5 -#define MBEDTLS_MD_MD5_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) -#define MBEDTLS_MD_CAN_SHA1 -#define MBEDTLS_MD_SHA1_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) -#define MBEDTLS_MD_CAN_SHA224 -#define MBEDTLS_MD_SHA224_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) -#define MBEDTLS_MD_CAN_SHA256 -#define MBEDTLS_MD_SHA256_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) -#define MBEDTLS_MD_CAN_SHA384 -#define MBEDTLS_MD_SHA384_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) -#define MBEDTLS_MD_CAN_SHA512 -#define MBEDTLS_MD_SHA512_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) -#define MBEDTLS_MD_CAN_RIPEMD160 -#define MBEDTLS_MD_RIPEMD160_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224) -#define MBEDTLS_MD_CAN_SHA3_224 -#define MBEDTLS_MD_SHA3_224_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256) -#define MBEDTLS_MD_CAN_SHA3_256 -#define MBEDTLS_MD_SHA3_256_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384) -#define MBEDTLS_MD_CAN_SHA3_384 -#define MBEDTLS_MD_SHA3_384_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512) -#define MBEDTLS_MD_CAN_SHA3_512 -#define MBEDTLS_MD_SHA3_512_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif - -#elif defined(MBEDTLS_PSA_CRYPTO_CLIENT) - -#if defined(PSA_WANT_ALG_MD5) -#define MBEDTLS_MD_CAN_MD5 -#define MBEDTLS_MD_MD5_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA_1) -#define MBEDTLS_MD_CAN_SHA1 -#define MBEDTLS_MD_SHA1_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA_224) -#define MBEDTLS_MD_CAN_SHA224 -#define MBEDTLS_MD_SHA224_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA_256) -#define MBEDTLS_MD_CAN_SHA256 -#define MBEDTLS_MD_SHA256_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA_384) -#define MBEDTLS_MD_CAN_SHA384 -#define MBEDTLS_MD_SHA384_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA_512) -#define MBEDTLS_MD_CAN_SHA512 -#define MBEDTLS_MD_SHA512_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_RIPEMD160) -#define MBEDTLS_MD_CAN_RIPEMD160 -#define MBEDTLS_MD_RIPEMD160_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA3_224) -#define MBEDTLS_MD_CAN_SHA3_224 -#define MBEDTLS_MD_SHA3_224_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA3_256) -#define MBEDTLS_MD_CAN_SHA3_256 -#define MBEDTLS_MD_SHA3_256_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA3_384) -#define MBEDTLS_MD_CAN_SHA3_384 -#define MBEDTLS_MD_SHA3_384_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif -#if defined(PSA_WANT_ALG_SHA3_512) -#define MBEDTLS_MD_CAN_SHA3_512 -#define MBEDTLS_MD_SHA3_512_VIA_PSA -#define MBEDTLS_MD_SOME_PSA -#endif - -#endif /* !MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */ - -/* Built-in implementations */ -#if defined(MBEDTLS_MD5_C) -#define MBEDTLS_MD_CAN_MD5 -#define MBEDTLS_MD_SOME_LEGACY -#endif -#if defined(MBEDTLS_SHA1_C) -#define MBEDTLS_MD_CAN_SHA1 -#define MBEDTLS_MD_SOME_LEGACY -#endif -#if defined(MBEDTLS_SHA224_C) -#define MBEDTLS_MD_CAN_SHA224 -#define MBEDTLS_MD_SOME_LEGACY -#endif -#if defined(MBEDTLS_SHA256_C) -#define MBEDTLS_MD_CAN_SHA256 -#define MBEDTLS_MD_SOME_LEGACY -#endif -#if defined(MBEDTLS_SHA384_C) -#define MBEDTLS_MD_CAN_SHA384 -#define MBEDTLS_MD_SOME_LEGACY -#endif -#if defined(MBEDTLS_SHA512_C) -#define MBEDTLS_MD_CAN_SHA512 -#define MBEDTLS_MD_SOME_LEGACY -#endif -#if defined(MBEDTLS_SHA3_C) -#define MBEDTLS_MD_CAN_SHA3_224 -#define MBEDTLS_MD_CAN_SHA3_256 -#define MBEDTLS_MD_CAN_SHA3_384 -#define MBEDTLS_MD_CAN_SHA3_512 -#define MBEDTLS_MD_SOME_LEGACY -#endif -#if defined(MBEDTLS_RIPEMD160_C) -#define MBEDTLS_MD_CAN_RIPEMD160 -#define MBEDTLS_MD_SOME_LEGACY -#endif - -#endif /* MBEDTLS_MD_LIGHT */ - -/* BLOCK_CIPHER module can dispatch to PSA when: - * - PSA is enabled and drivers have been initialized - * - desired key type is supported on the PSA side - * If the above conditions are not met, but the legacy support is enabled, then - * BLOCK_CIPHER will dynamically fallback to it. - * - * In case BLOCK_CIPHER is defined (see below) the following symbols/helpers - * can be used to define its capabilities: - * - MBEDTLS_BLOCK_CIPHER_SOME_PSA: there is at least 1 key type between AES, - * ARIA and Camellia which is supported through a driver; - * - MBEDTLS_BLOCK_CIPHER_xxx_VIA_PSA: xxx key type is supported through a - * driver; - * - MBEDTLS_BLOCK_CIPHER_xxx_VIA_LEGACY: xxx key type is supported through - * a legacy module (i.e. MBEDTLS_xxx_C) - */ -#if defined(MBEDTLS_PSA_CRYPTO_C) -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES) -#define MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA -#define MBEDTLS_BLOCK_CIPHER_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA) -#define MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA -#define MBEDTLS_BLOCK_CIPHER_SOME_PSA -#endif -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA) -#define MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA -#define MBEDTLS_BLOCK_CIPHER_SOME_PSA -#endif -#endif /* MBEDTLS_PSA_CRYPTO_C */ - -#if defined(MBEDTLS_AES_C) -#define MBEDTLS_BLOCK_CIPHER_AES_VIA_LEGACY -#endif -#if defined(MBEDTLS_ARIA_C) -#define MBEDTLS_BLOCK_CIPHER_ARIA_VIA_LEGACY -#endif -#if defined(MBEDTLS_CAMELLIA_C) -#define MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_LEGACY -#endif - -/* Helpers to state that BLOCK_CIPHER module supports AES, ARIA and/or Camellia - * block ciphers via either PSA or legacy. */ -#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA) || \ - defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_LEGACY) -#define MBEDTLS_BLOCK_CIPHER_CAN_AES -#endif -#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA) || \ - defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_LEGACY) -#define MBEDTLS_BLOCK_CIPHER_CAN_ARIA -#endif -#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA) || \ - defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_LEGACY) -#define MBEDTLS_BLOCK_CIPHER_CAN_CAMELLIA -#endif - -/* GCM_C and CCM_C can either depend on (in order of preference) BLOCK_CIPHER_C - * or CIPHER_C. The former is auto-enabled when: - * - CIPHER_C is not defined, which is also the legacy solution; - * - BLOCK_CIPHER_SOME_PSA because in this case BLOCK_CIPHER can take advantage - * of the driver's acceleration. - */ -#if (defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)) && \ - (!defined(MBEDTLS_CIPHER_C) || defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)) -#define MBEDTLS_BLOCK_CIPHER_C -#endif - -/* Helpers for GCM/CCM capabilities */ -#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_AES_C)) || \ - (defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_AES)) -#define MBEDTLS_CCM_GCM_CAN_AES -#endif - -#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_ARIA_C)) || \ - (defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_ARIA)) -#define MBEDTLS_CCM_GCM_CAN_ARIA -#endif - -#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_CAMELLIA_C)) || \ - (defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_CAMELLIA)) -#define MBEDTLS_CCM_GCM_CAN_CAMELLIA -#endif - -/* MBEDTLS_ECP_LIGHT is auto-enabled by the following symbols: - * - MBEDTLS_ECP_C because now it consists of MBEDTLS_ECP_LIGHT plus functions - * for curve arithmetic. As a consequence if MBEDTLS_ECP_C is required for - * some reason, then MBEDTLS_ECP_LIGHT should be enabled as well. - * - MBEDTLS_PK_PARSE_EC_EXTENDED and MBEDTLS_PK_PARSE_EC_COMPRESSED because - * these features are not supported in PSA so the only way to have them is - * to enable the built-in solution. - * Both of them are temporary dependencies: - * - PK_PARSE_EC_EXTENDED will be removed after #7779 and #7789 - * - support for compressed points should also be added to PSA, but in this - * case there is no associated issue to track it yet. - * - PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE because Weierstrass key derivation - * still depends on ECP_LIGHT. - * - PK_C + USE_PSA + PSA_WANT_ALG_ECDSA is a temporary dependency which will - * be fixed by #7453. - */ -#if defined(MBEDTLS_ECP_C) || \ - defined(MBEDTLS_PK_PARSE_EC_EXTENDED) || \ - defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#define MBEDTLS_ECP_LIGHT -#endif - -/* Backward compatibility: after #8740 the RSA module offers functions to parse - * and write RSA private/public keys without relying on the PK one. Of course - * this needs ASN1 support to do so, so we enable it here. */ -#if defined(MBEDTLS_RSA_C) -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#endif - -/* MBEDTLS_PK_PARSE_EC_COMPRESSED is introduced in Mbed TLS version 3.5, while - * in previous version compressed points were automatically supported as long - * as PK_PARSE_C and ECP_C were enabled. As a consequence, for backward - * compatibility, we auto-enable PK_PARSE_EC_COMPRESSED when these conditions - * are met. */ -#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_ECP_C) -#define MBEDTLS_PK_PARSE_EC_COMPRESSED -#endif - -/* Helper symbol to state that there is support for ECDH, either through - * library implementation (ECDH_C) or through PSA. */ -#if (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDH)) || \ - (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C)) -#define MBEDTLS_CAN_ECDH -#endif - -/* PK module can achieve ECDSA functionalities by means of either software - * implementations (ECDSA_C) or through a PSA driver. The following defines - * are meant to list these capabilities in a general way which abstracts how - * they are implemented under the hood. */ -#if !defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_ECDSA_C) -#define MBEDTLS_PK_CAN_ECDSA_SIGN -#define MBEDTLS_PK_CAN_ECDSA_VERIFY -#endif /* MBEDTLS_ECDSA_C */ -#else /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(PSA_WANT_ALG_ECDSA) -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) -#define MBEDTLS_PK_CAN_ECDSA_SIGN -#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */ -#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -#define MBEDTLS_PK_CAN_ECDSA_VERIFY -#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ -#endif /* PSA_WANT_ALG_ECDSA */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) || defined(MBEDTLS_PK_CAN_ECDSA_SIGN) -#define MBEDTLS_PK_CAN_ECDSA_SOME -#endif - -/* Helpers to state that each key is supported either on the builtin or PSA side. */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521) -#define MBEDTLS_ECP_HAVE_SECP521R1 -#endif -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) -#define MBEDTLS_ECP_HAVE_BP512R1 -#endif -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_448) -#define MBEDTLS_ECP_HAVE_CURVE448 -#endif -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) -#define MBEDTLS_ECP_HAVE_BP384R1 -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_384) -#define MBEDTLS_ECP_HAVE_SECP384R1 -#endif -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) -#define MBEDTLS_ECP_HAVE_BP256R1 -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_256) -#define MBEDTLS_ECP_HAVE_SECP256K1 -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_256) -#define MBEDTLS_ECP_HAVE_SECP256R1 -#endif -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_255) -#define MBEDTLS_ECP_HAVE_CURVE25519 -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_224) -#define MBEDTLS_ECP_HAVE_SECP224K1 -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_224) -#define MBEDTLS_ECP_HAVE_SECP224R1 -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_192) -#define MBEDTLS_ECP_HAVE_SECP192K1 -#endif -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_192) -#define MBEDTLS_ECP_HAVE_SECP192R1 -#endif - -/* Helper symbol to state that the PK module has support for EC keys. This - * can either be provided through the legacy ECP solution or through the - * PSA friendly MBEDTLS_PK_USE_PSA_EC_DATA (see pk.h for its description). */ -#if defined(MBEDTLS_ECP_C) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) -#define MBEDTLS_PK_HAVE_ECC_KEYS -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */ - -/* Historically pkparse did not check the CBC padding when decrypting - * a key. This was a bug, which is now fixed. As a consequence, pkparse - * now needs PKCS7 padding support, but existing configurations might not - * enable it, so we enable it here. */ -#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PKCS5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#endif - -/* Backwards compatibility for some macros which were renamed to reflect that - * they are related to Armv8, not aarch64. */ -#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) && \ - !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) -#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT -#endif -#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) && !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) -#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY -#endif - -/* psa_util file features some ECDSA conversion functions, to convert between - * legacy's ASN.1 DER format and PSA's raw one. */ -#if (defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ - (defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA))) -#define MBEDTLS_PSA_UTIL_HAVE_ECDSA -#endif - -/* Some internal helpers to determine which keys are available. */ -#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES)) -#define MBEDTLS_SSL_HAVE_AES -#endif -#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ARIA_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ARIA)) -#define MBEDTLS_SSL_HAVE_ARIA -#endif -#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CAMELLIA_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_CAMELLIA)) -#define MBEDTLS_SSL_HAVE_CAMELLIA -#endif - -/* Some internal helpers to determine which operation modes are available. */ -#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CIPHER_MODE_CBC)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CBC_NO_PADDING)) -#define MBEDTLS_SSL_HAVE_CBC -#endif - -#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_GCM_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM)) -#define MBEDTLS_SSL_HAVE_GCM -#endif - -#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CCM_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM)) -#define MBEDTLS_SSL_HAVE_CCM -#endif - -#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CHACHAPOLY_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CHACHA20_POLY1305)) -#define MBEDTLS_SSL_HAVE_CHACHAPOLY -#endif - -#if defined(MBEDTLS_SSL_HAVE_GCM) || defined(MBEDTLS_SSL_HAVE_CCM) || \ - defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) -#define MBEDTLS_SSL_HAVE_AEAD -#endif - -#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H */ diff --git a/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h b/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h deleted file mode 100644 index 48f1bab1e..000000000 --- a/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +++ /dev/null @@ -1,873 +0,0 @@ -/** - * \file mbedtls/config_adjust_legacy_from_psa.h - * \brief Adjust PSA configuration: activate legacy implementations - * - * This is an internal header. Do not include it directly. - * - * When MBEDTLS_PSA_CRYPTO_CONFIG is enabled, activate legacy implementations - * of cryptographic mechanisms as needed to fulfill the needs of the PSA - * configuration. Generally speaking, we activate a legacy mechanism if - * it's needed for a requested PSA mechanism and there is no PSA driver - * for it. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H -#define MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -/* Define appropriate ACCEL macros for the p256-m driver. - * In the future, those should be generated from the drivers JSON description. - */ -#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) -#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256 -#define MBEDTLS_PSA_ACCEL_ALG_ECDSA -#define MBEDTLS_PSA_ACCEL_ALG_ECDH -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE -#endif - -/* - * ECC: support for a feature is controlled by a triplet or a pair: - * (curve, key_type public/basic, alg) or (curve, key_type_). - * - * A triplet/pair is accelerated if all of is components are accelerated; - * otherwise each component needs to be built in. - * - * We proceed in two passes: - * 1. Check if acceleration is complete for curves, key types, algs. - * 2. Then enable built-ins for each thing that's either not accelerated of - * doesn't have complete acceleration of the other triplet/pair components. - * - * Note: this needs psa/crypto_adjust_keypair_types.h to have been included - * already, so that we know the full set of key types that are requested. - */ - -/* ECC: curves: is acceleration complete? */ -#if (defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) && \ - !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256)) || \ - (defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) && \ - !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384)) || \ - (defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) && \ - !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512)) || \ - (defined(PSA_WANT_ECC_SECP_R1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192)) || \ - (defined(PSA_WANT_ECC_SECP_R1_224) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224)) || \ - (defined(PSA_WANT_ECC_SECP_R1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256)) || \ - (defined(PSA_WANT_ECC_SECP_R1_384) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384)) || \ - (defined(PSA_WANT_ECC_SECP_R1_521) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)) || \ - (defined(PSA_WANT_ECC_SECP_K1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192)) || \ - (defined(PSA_WANT_ECC_SECP_K1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256)) -#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES -#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES -#endif - -#if (defined(PSA_WANT_ECC_MONTGOMERY_255) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255)) || \ - (defined(PSA_WANT_ECC_MONTGOMERY_448) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448)) -#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES -#endif - -/* ECC: algs: is acceleration complete? */ -#if (defined(PSA_WANT_ALG_ECDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)) || \ - (defined(PSA_WANT_ALG_ECDSA) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)) || \ - (defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)) || \ - (defined(PSA_WANT_ALG_JPAKE) && !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE)) -#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS -#endif - -/* ECC: key types: is acceleration complete? */ -#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \ - (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC)) -#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC -#endif - -/* Special case: we don't support cooked key derivation in drivers yet */ -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#undef MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE -#endif - -/* Note: the condition about key derivation is always true as DERIVE can't be - * accelerated yet */ -#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \ - (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC)) || \ - (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT)) || \ - (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT)) || \ - (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE)) || \ - (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE)) -#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES -#endif - -/* ECC: curves: enable built-ins as needed. - * - * We need the curve built-in: - * - if it's not accelerated, or - * - if there's a key type with missing acceleration, or - * - if there's a alg with missing acceleration. - */ -#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1 -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */ - -#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1 -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */ - -#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1 -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */ - -#if defined(PSA_WANT_ECC_MONTGOMERY_255) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1 -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_MONTGOMERY_255 */ - -#if defined(PSA_WANT_ECC_MONTGOMERY_448) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1 -#define MBEDTLS_ECP_DP_CURVE448_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_MONTGOMERY_448 */ - -#if defined(PSA_WANT_ECC_SECP_R1_192) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1 -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_SECP_R1_192 */ - -#if defined(PSA_WANT_ECC_SECP_R1_224) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1 -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_SECP_R1_224 */ - -#if defined(PSA_WANT_ECC_SECP_R1_256) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1 -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_SECP_R1_256 */ - -#if defined(PSA_WANT_ECC_SECP_R1_384) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1 -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_SECP_R1_384 */ - -#if defined(PSA_WANT_ECC_SECP_R1_521) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1 -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_SECP_R1_521 */ - -#if defined(PSA_WANT_ECC_SECP_K1_192) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1 -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_SECP_K1_192 */ - -#if defined(PSA_WANT_ECC_SECP_K1_256) -#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1 -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#endif /* missing accel */ -#endif /* PSA_WANT_ECC_SECP_K1_256 */ - -/* ECC: algs: enable built-ins as needed. - * - * We need the alg built-in: - * - if it's not accelerated, or - * - if there's a relevant curve (see below) with missing acceleration, or - * - if there's a key type among (public, basic) with missing acceleration. - * - * Relevant curves are: - * - all curves for ECDH - * - Weierstrass curves for (deterministic) ECDSA - * - secp256r1 for EC J-PAKE - */ -#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) -#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1 -#define MBEDTLS_ECDSA_DETERMINISTIC -#define MBEDTLS_HMAC_DRBG_C -#define MBEDTLS_MD_C -#define MBEDTLS_ECDSA_C -#define MBEDTLS_ECP_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#endif /* missing accel */ -#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */ - -#if defined(PSA_WANT_ALG_ECDH) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) -#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1 -#define MBEDTLS_ECDH_C -#define MBEDTLS_ECP_C -#define MBEDTLS_BIGNUM_C -#endif /* missing accel */ -#endif /* PSA_WANT_ALG_ECDH */ - -#if defined(PSA_WANT_ALG_ECDSA) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) -#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1 -#define MBEDTLS_ECDSA_C -#define MBEDTLS_ECP_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#endif /* missing accel */ -#endif /* PSA_WANT_ALG_ECDSA */ - -#if defined(PSA_WANT_ALG_JPAKE) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE) || \ - !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) -#define MBEDTLS_PSA_BUILTIN_PAKE 1 -#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1 -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_ECP_C -#define MBEDTLS_ECJPAKE_C -#endif /* missing accel */ -#endif /* PSA_WANT_ALG_JPAKE */ - -/* ECC: key types: enable built-ins as needed. - * - * We need the key type built-in: - * - if it's not accelerated, or - * - if there's a curve with missing acceleration, or - * - only for public/basic: if there's an alg with missing acceleration. - */ -#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1 -#endif /* missing accel */ -#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 -#endif /* missing accel */ -#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */ - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 -#endif /* missing accel */ -#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT */ - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 -#endif /* missing accel */ -#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT */ - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 -#endif /* missing accel */ -#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ - -/* Note: the condition is always true as DERIVE can't be accelerated yet */ -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \ - defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 -#endif /* missing accel */ -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#define MBEDTLS_ECP_LIGHT -#define MBEDTLS_BIGNUM_C -#endif - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) -#define MBEDTLS_ECP_C -#define MBEDTLS_BIGNUM_C -#endif - -/* End of ECC section */ - -/* - * DH key types follow the same pattern used above for EC keys. They are defined - * by a triplet (group, key_type, alg). A triplet is accelerated if all its - * component are accelerated, otherwise each component needs to be builtin. - */ - -/* DH: groups: is acceleration complete? */ -#if (defined(PSA_WANT_DH_RFC7919_2048) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048)) || \ - (defined(PSA_WANT_DH_RFC7919_3072) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072)) || \ - (defined(PSA_WANT_DH_RFC7919_4096) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096)) || \ - (defined(PSA_WANT_DH_RFC7919_6144) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144)) || \ - (defined(PSA_WANT_DH_RFC7919_8192) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192)) -#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS -#endif - -/* DH: algs: is acceleration complete? */ -#if defined(PSA_WANT_ALG_FFDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH) -#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS -#endif - -/* DH: key types: is acceleration complete? */ -#if (defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY)) || \ - (defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC)) || \ - (defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT)) || \ - (defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT)) || \ - (defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE)) -#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES -#endif - -#if defined(PSA_WANT_DH_RFC7919_2048) -#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES) -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 1 -#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */ -#endif /* PSA_WANT_DH_RFC7919_2048 */ - -#if defined(PSA_WANT_DH_RFC7919_3072) -#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES) -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 1 -#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */ -#endif /* PSA_WANT_DH_RFC7919_3072 */ - -#if defined(PSA_WANT_DH_RFC7919_4096) -#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES) -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 1 -#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */ -#endif /* PSA_WANT_DH_RFC7919_4096 */ - -#if defined(PSA_WANT_DH_RFC7919_6144) -#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES) -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 1 -#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */ -#endif /* PSA_WANT_DH_RFC7919_6144 */ - -#if defined(PSA_WANT_DH_RFC7919_8192) -#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES) -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 1 -#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */ -#endif /* PSA_WANT_DH_RFC7919_8192 */ - -#if defined(PSA_WANT_ALG_FFDH) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES) -#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1 -#define MBEDTLS_BIGNUM_C -#endif /* !MBEDTLS_PSA_ACCEL_ALG_FFDH */ -#endif /* PSA_WANT_ALG_FFDH */ - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT */ -#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT */ - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT */ -#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT */ - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE */ -#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */ - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC */ -#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC */ - -#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \ - defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1 -#define MBEDTLS_BIGNUM_C -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY */ -#endif /* PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY */ - -/* End of DH section */ - -#if defined(PSA_WANT_ALG_HKDF) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF) -/* - * The PSA implementation has its own implementation of HKDF, separate from - * hkdf.c. No need to enable MBEDTLS_HKDF_C here. - */ -#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF */ -#endif /* PSA_WANT_ALG_HKDF */ - -#if defined(PSA_WANT_ALG_HKDF_EXTRACT) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT) -/* - * The PSA implementation has its own implementation of HKDF, separate from - * hkdf.c. No need to enable MBEDTLS_HKDF_C here. - */ -#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT */ -#endif /* PSA_WANT_ALG_HKDF_EXTRACT */ - -#if defined(PSA_WANT_ALG_HKDF_EXPAND) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND) -/* - * The PSA implementation has its own implementation of HKDF, separate from - * hkdf.c. No need to enable MBEDTLS_HKDF_C here. - */ -#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND */ -#endif /* PSA_WANT_ALG_HKDF_EXPAND */ - -#if defined(PSA_WANT_ALG_HMAC) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC) -#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */ -#endif /* PSA_WANT_ALG_HMAC */ - -#if defined(PSA_WANT_ALG_MD5) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD5) -#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1 -#define MBEDTLS_MD5_C -#endif - -#if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) -#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 -#define MBEDTLS_RIPEMD160_C -#endif - -#if defined(PSA_WANT_ALG_RSA_OAEP) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1 -#define MBEDTLS_RSA_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS1_V21 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP */ -#endif /* PSA_WANT_ALG_RSA_OAEP */ - -#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT) -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1 -#define MBEDTLS_RSA_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS1_V15 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT */ -#endif /* PSA_WANT_ALG_RSA_PKCS1V15_CRYPT */ - -#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN) -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1 -#define MBEDTLS_RSA_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS1_V15 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN */ -#endif /* PSA_WANT_ALG_RSA_PKCS1V15_SIGN */ - -#if defined(PSA_WANT_ALG_RSA_PSS) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS) -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1 -#define MBEDTLS_RSA_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS1_V21 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PSS */ -#endif /* PSA_WANT_ALG_RSA_PSS */ - -#if defined(PSA_WANT_ALG_SHA_1) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1 -#define MBEDTLS_SHA1_C -#endif - -#if defined(PSA_WANT_ALG_SHA_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1 -#define MBEDTLS_SHA224_C -#endif - -#if defined(PSA_WANT_ALG_SHA_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1 -#define MBEDTLS_SHA256_C -#endif - -#if defined(PSA_WANT_ALG_SHA_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1 -#define MBEDTLS_SHA384_C -#endif - -#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1 -#define MBEDTLS_SHA512_C -#endif - -#if defined(PSA_WANT_ALG_SHA3_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_224 1 -#define MBEDTLS_SHA3_C -#endif - -#if defined(PSA_WANT_ALG_SHA3_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_256 1 -#define MBEDTLS_SHA3_C -#endif - -#if defined(PSA_WANT_ALG_SHA3_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_384 1 -#define MBEDTLS_SHA3_C -#endif - -#if defined(PSA_WANT_ALG_SHA3_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_512 1 -#define MBEDTLS_SHA3_C -#endif - -#if defined(PSA_WANT_ALG_PBKDF2_HMAC) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC) -#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC 1 -#define PSA_HAVE_SOFT_PBKDF2_HMAC 1 -#endif /* !MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */ -#endif /* PSA_WANT_ALG_PBKDF2_HMAC */ - -#if defined(PSA_WANT_ALG_TLS12_PRF) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF) -#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF */ -#endif /* PSA_WANT_ALG_TLS12_PRF */ - -#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS) -#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS */ -#endif /* PSA_WANT_ALG_TLS12_PSK_TO_MS */ - -#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS) -#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS */ -#endif /* PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS */ - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT */ -#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT */ - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT */ -#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT */ - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 -#define MBEDTLS_GENPRIME -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ -#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC */ -#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ - -#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1 -#define MBEDTLS_RSA_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_OID_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */ -#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */ - -/* If any of the block modes are requested that don't have an - * associated HW assist, define PSA_HAVE_SOFT_BLOCK_MODE for checking - * in the block cipher key types. */ -#if (defined(PSA_WANT_ALG_CTR) && !defined(MBEDTLS_PSA_ACCEL_ALG_CTR)) || \ - (defined(PSA_WANT_ALG_CFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_CFB)) || \ - (defined(PSA_WANT_ALG_OFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_OFB)) || \ - (defined(PSA_WANT_ALG_ECB_NO_PADDING) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)) || \ - (defined(PSA_WANT_ALG_CBC_NO_PADDING) && !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)) || \ - (defined(PSA_WANT_ALG_CBC_PKCS7) && !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7)) || \ - (defined(PSA_WANT_ALG_CMAC) && !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC)) -#define PSA_HAVE_SOFT_BLOCK_MODE 1 -#endif - -#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128) -#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 1 -#define PSA_HAVE_SOFT_PBKDF2_CMAC 1 -#endif /* !MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128 */ -#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */ - -#if defined(PSA_WANT_KEY_TYPE_AES) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES) -#define PSA_HAVE_SOFT_KEY_TYPE_AES 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_AES */ -#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ - defined(PSA_HAVE_SOFT_BLOCK_MODE) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1 -#define MBEDTLS_AES_C -#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */ -#endif /* PSA_WANT_KEY_TYPE_AES */ - -#if defined(PSA_WANT_KEY_TYPE_ARIA) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA) -#define PSA_HAVE_SOFT_KEY_TYPE_ARIA 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA */ -#if defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ - defined(PSA_HAVE_SOFT_BLOCK_MODE) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1 -#define MBEDTLS_ARIA_C -#endif /* PSA_HAVE_SOFT_KEY_TYPE_ARIA || PSA_HAVE_SOFT_BLOCK_MODE */ -#endif /* PSA_WANT_KEY_TYPE_ARIA */ - -#if defined(PSA_WANT_KEY_TYPE_CAMELLIA) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA) -#define PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA */ -#if defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) || \ - defined(PSA_HAVE_SOFT_BLOCK_MODE) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1 -#define MBEDTLS_CAMELLIA_C -#endif /* PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA || PSA_HAVE_SOFT_BLOCK_MODE */ -#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */ - -#if defined(PSA_WANT_KEY_TYPE_DES) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES) -#define PSA_HAVE_SOFT_KEY_TYPE_DES 1 -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DES */ -#if defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \ - defined(PSA_HAVE_SOFT_BLOCK_MODE) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1 -#define MBEDTLS_DES_C -#endif /*PSA_HAVE_SOFT_KEY_TYPE_DES || PSA_HAVE_SOFT_BLOCK_MODE */ -#endif /* PSA_WANT_KEY_TYPE_DES */ - -#if defined(PSA_WANT_ALG_STREAM_CIPHER) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER) -#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1 -#endif /* MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER */ -#endif /* PSA_WANT_ALG_STREAM_CIPHER */ - -#if defined(PSA_WANT_KEY_TYPE_CHACHA20) -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1 -#define MBEDTLS_CHACHA20_C -#endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20 */ -#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */ - -/* If any of the software block ciphers are selected, define - * PSA_HAVE_SOFT_BLOCK_CIPHER, which can be used in any of these - * situations. */ -#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) -#define PSA_HAVE_SOFT_BLOCK_CIPHER 1 -#endif - -#if defined(PSA_WANT_ALG_CMAC) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) || \ - defined(PSA_HAVE_SOFT_BLOCK_CIPHER) -#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1 -#define MBEDTLS_CMAC_C -#endif /* !MBEDTLS_PSA_ACCEL_ALG_CMAC */ -#endif /* PSA_WANT_ALG_CMAC */ - -#if defined(PSA_HAVE_SOFT_PBKDF2_HMAC) || \ - defined(PSA_HAVE_SOFT_PBKDF2_CMAC) -#define PSA_HAVE_SOFT_PBKDF2 1 -#endif /* PSA_HAVE_SOFT_PBKDF2_HMAC || PSA_HAVE_SOFT_PBKDF2_CMAC */ - -#if defined(PSA_WANT_ALG_CTR) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CTR) || \ - defined(PSA_HAVE_SOFT_BLOCK_CIPHER) -#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1 -#define MBEDTLS_CIPHER_MODE_CTR -#endif -#endif /* PSA_WANT_ALG_CTR */ - -#if defined(PSA_WANT_ALG_CFB) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CFB) || \ - defined(PSA_HAVE_SOFT_BLOCK_CIPHER) -#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1 -#define MBEDTLS_CIPHER_MODE_CFB -#endif -#endif /* PSA_WANT_ALG_CFB */ - -#if defined(PSA_WANT_ALG_OFB) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_OFB) || \ - defined(PSA_HAVE_SOFT_BLOCK_CIPHER) -#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1 -#define MBEDTLS_CIPHER_MODE_OFB -#endif -#endif /* PSA_WANT_ALG_OFB */ - -#if defined(PSA_WANT_ALG_ECB_NO_PADDING) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING) -#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1 -#endif - -#if defined(PSA_WANT_ALG_CBC_NO_PADDING) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING) || \ - defined(PSA_HAVE_SOFT_BLOCK_CIPHER) -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1 -#endif -#endif /* PSA_WANT_ALG_CBC_NO_PADDING */ - -#if defined(PSA_WANT_ALG_CBC_PKCS7) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7) || \ - defined(PSA_HAVE_SOFT_BLOCK_CIPHER) -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1 -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#endif -#endif /* PSA_WANT_ALG_CBC_PKCS7 */ - -#if defined(PSA_WANT_ALG_CCM) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) -#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1 -#define MBEDTLS_CCM_C -#endif -#endif /* PSA_WANT_ALG_CCM */ - -#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) -#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1 -#define MBEDTLS_CCM_C -#endif -#endif /* PSA_WANT_ALG_CCM_STAR_NO_TAG */ - -#if defined(PSA_WANT_ALG_GCM) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_GCM) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ - defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) -#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1 -#define MBEDTLS_GCM_C -#endif -#endif /* PSA_WANT_ALG_GCM */ - -#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) -#if !defined(MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305) -#if defined(PSA_WANT_KEY_TYPE_CHACHA20) -#define MBEDTLS_CHACHAPOLY_C -#define MBEDTLS_CHACHA20_C -#define MBEDTLS_POLY1305_C -#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1 -#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */ -#endif /* !MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305 */ -#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ - -#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H */ diff --git a/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h b/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h deleted file mode 100644 index 14ca14696..000000000 --- a/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +++ /dev/null @@ -1,359 +0,0 @@ -/** - * \file mbedtls/config_adjust_psa_from_legacy.h - * \brief Adjust PSA configuration: construct PSA configuration from legacy - * - * This is an internal header. Do not include it directly. - * - * When MBEDTLS_PSA_CRYPTO_CONFIG is disabled, we automatically enable - * cryptographic mechanisms through the PSA interface when the corresponding - * legacy mechanism is enabled. In many cases, this just enables the PSA - * wrapper code around the legacy implementation, but we also do this for - * some mechanisms where PSA has its own independent implementation so - * that high-level modules that can use either cryptographic API have the - * same feature set in both cases. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H -#define MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -/* - * Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG - * is not defined - */ - -#if defined(MBEDTLS_CCM_C) -#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1 -#define PSA_WANT_ALG_CCM 1 -#if defined(MBEDTLS_CIPHER_C) -#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1 -#define PSA_WANT_ALG_CCM_STAR_NO_TAG 1 -#endif /* MBEDTLS_CIPHER_C */ -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_CMAC_C) -#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1 -#define PSA_WANT_ALG_CMAC 1 -#endif /* MBEDTLS_CMAC_C */ - -#if defined(MBEDTLS_ECDH_C) -#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1 -#define PSA_WANT_ALG_ECDH 1 -#endif /* MBEDTLS_ECDH_C */ - -#if defined(MBEDTLS_ECDSA_C) -#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1 -#define PSA_WANT_ALG_ECDSA 1 -#define PSA_WANT_ALG_ECDSA_ANY 1 - -// Only add in DETERMINISTIC support if ECDSA is also enabled -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1 -#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#endif /* MBEDTLS_ECDSA_C */ - -#if defined(MBEDTLS_ECP_C) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 -/* Normally we wouldn't enable this because it's not implemented in ecp.c, - * but since it used to be available any time ECP_C was enabled, let's enable - * it anyway for the sake of backwards compatibility */ -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 -/* See comment for PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE above. */ -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1 -#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_DHM_C) -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC 1 -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE 1 -#define PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY 1 -#define PSA_WANT_ALG_FFDH 1 -#define PSA_WANT_DH_RFC7919_2048 1 -#define PSA_WANT_DH_RFC7919_3072 1 -#define PSA_WANT_DH_RFC7919_4096 1 -#define PSA_WANT_DH_RFC7919_6144 1 -#define PSA_WANT_DH_RFC7919_8192 1 -#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1 -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 1 -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 1 -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 1 -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 1 -#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 1 -#endif /* MBEDTLS_DHM_C */ - -#if defined(MBEDTLS_GCM_C) -#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1 -#define PSA_WANT_ALG_GCM 1 -#endif /* MBEDTLS_GCM_C */ - -/* Enable PSA HKDF algorithm if mbedtls HKDF is supported. - * PSA HKDF EXTRACT and PSA HKDF EXPAND have minimal cost when - * PSA HKDF is enabled, so enable both algorithms together - * with PSA HKDF. */ -#if defined(MBEDTLS_HKDF_C) -#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 -#define PSA_WANT_ALG_HMAC 1 -#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1 -#define PSA_WANT_ALG_HKDF 1 -#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1 -#define PSA_WANT_ALG_HKDF_EXTRACT 1 -#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1 -#define PSA_WANT_ALG_HKDF_EXPAND 1 -#endif /* MBEDTLS_HKDF_C */ - -#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 -#define PSA_WANT_ALG_HMAC 1 -#define PSA_WANT_KEY_TYPE_HMAC 1 - -#if defined(MBEDTLS_MD_C) -#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1 -#define PSA_WANT_ALG_TLS12_PRF 1 -#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1 -#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1 -#endif /* MBEDTLS_MD_C */ - -#if defined(MBEDTLS_MD5_C) -#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1 -#define PSA_WANT_ALG_MD5 1 -#endif - -#if defined(MBEDTLS_ECJPAKE_C) -#define MBEDTLS_PSA_BUILTIN_PAKE 1 -#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1 -#define PSA_WANT_ALG_JPAKE 1 -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 -#define PSA_WANT_ALG_RIPEMD160 1 -#endif - -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_PKCS1_V15) -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1 -#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1 -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1 -#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1 -#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW 1 -#endif /* MBEDTLS_PKCS1_V15 */ -#if defined(MBEDTLS_PKCS1_V21) -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1 -#define PSA_WANT_ALG_RSA_OAEP 1 -#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1 -#define PSA_WANT_ALG_RSA_PSS 1 -#endif /* MBEDTLS_PKCS1_V21 */ -#if defined(MBEDTLS_GENPRIME) -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 -#endif /* MBEDTLS_GENPRIME */ -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1 -#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_SHA1_C) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1 -#define PSA_WANT_ALG_SHA_1 1 -#endif - -#if defined(MBEDTLS_SHA224_C) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1 -#define PSA_WANT_ALG_SHA_224 1 -#endif - -#if defined(MBEDTLS_SHA256_C) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1 -#define PSA_WANT_ALG_SHA_256 1 -#endif - -#if defined(MBEDTLS_SHA384_C) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1 -#define PSA_WANT_ALG_SHA_384 1 -#endif - -#if defined(MBEDTLS_SHA512_C) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1 -#define PSA_WANT_ALG_SHA_512 1 -#endif - -#if defined(MBEDTLS_SHA3_C) -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_224 1 -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_256 1 -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_384 1 -#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_512 1 -#define PSA_WANT_ALG_SHA3_224 1 -#define PSA_WANT_ALG_SHA3_256 1 -#define PSA_WANT_ALG_SHA3_384 1 -#define PSA_WANT_ALG_SHA3_512 1 -#endif - -#if defined(MBEDTLS_AES_C) -#define PSA_WANT_KEY_TYPE_AES 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1 -#endif - -#if defined(MBEDTLS_ARIA_C) -#define PSA_WANT_KEY_TYPE_ARIA 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1 -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#define PSA_WANT_KEY_TYPE_CAMELLIA 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1 -#endif - -#if defined(MBEDTLS_DES_C) -#define PSA_WANT_KEY_TYPE_DES 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1 -#endif - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) -#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1 -#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1 -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#define PSA_WANT_KEY_TYPE_CHACHA20 1 -#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1 -/* ALG_STREAM_CIPHER requires CIPHER_C in order to be supported in PSA */ -#if defined(MBEDTLS_CIPHER_C) -#define PSA_WANT_ALG_STREAM_CIPHER 1 -#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1 -#endif -#if defined(MBEDTLS_CHACHAPOLY_C) -#define PSA_WANT_ALG_CHACHA20_POLY1305 1 -#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1 -#endif -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1 -#define PSA_WANT_ALG_CBC_NO_PADDING 1 -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) -#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1 -#define PSA_WANT_ALG_CBC_PKCS7 1 -#endif -#endif - -#if (defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \ - defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)) && \ - defined(MBEDTLS_CIPHER_C) -#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1 -#define PSA_WANT_ALG_ECB_NO_PADDING 1 -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1 -#define PSA_WANT_ALG_CFB 1 -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1 -#define PSA_WANT_ALG_CTR 1 -#endif - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1 -#define PSA_WANT_ALG_OFB 1 -#endif - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1 -#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1 -#endif - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1 -#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1 -#endif - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1 -#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1 -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1 -#define PSA_WANT_ECC_MONTGOMERY_255 1 -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1 -#define PSA_WANT_ECC_MONTGOMERY_448 1 -#endif - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1 -#define PSA_WANT_ECC_SECP_R1_192 1 -#endif - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1 -#define PSA_WANT_ECC_SECP_R1_224 1 -#endif - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1 -#define PSA_WANT_ECC_SECP_R1_256 1 -#endif - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1 -#define PSA_WANT_ECC_SECP_R1_384 1 -#endif - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1 -#define PSA_WANT_ECC_SECP_R1_521 1 -#endif - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1 -#define PSA_WANT_ECC_SECP_K1_192 1 -#endif - -/* SECP224K1 is buggy via the PSA API (https://github.com/Mbed-TLS/mbedtls/issues/3541) */ -#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1 -#define PSA_WANT_ECC_SECP_K1_224 1 -#endif - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1 -#define PSA_WANT_ECC_SECP_K1_256 1 -#endif - -#endif /* MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H */ diff --git a/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h b/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h deleted file mode 100644 index 1a232cbb8..000000000 --- a/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +++ /dev/null @@ -1,145 +0,0 @@ -/** - * \file mbedtls/config_adjust_psa_superset_legacy.h - * \brief Adjust PSA configuration: automatic enablement from legacy - * - * This is an internal header. Do not include it directly. - * - * To simplify some edge cases, we automatically enable certain cryptographic - * mechanisms in the PSA API if they are enabled in the legacy API. The general - * idea is that if legacy module M uses mechanism A internally, and A has - * both a legacy and a PSA implementation, we enable A through PSA whenever - * it's enabled through legacy. This facilitates the transition to PSA - * implementations of A for users of M. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H -#define MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -/****************************************************************/ -/* Hashes that are built in are also enabled in PSA. - * This simplifies dependency declarations especially - * for modules that obey MBEDTLS_USE_PSA_CRYPTO. */ -/****************************************************************/ - -#if defined(MBEDTLS_MD5_C) -#define PSA_WANT_ALG_MD5 1 -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#define PSA_WANT_ALG_RIPEMD160 1 -#endif - -#if defined(MBEDTLS_SHA1_C) -#define PSA_WANT_ALG_SHA_1 1 -#endif - -#if defined(MBEDTLS_SHA224_C) -#define PSA_WANT_ALG_SHA_224 1 -#endif - -#if defined(MBEDTLS_SHA256_C) -#define PSA_WANT_ALG_SHA_256 1 -#endif - -#if defined(MBEDTLS_SHA384_C) -#define PSA_WANT_ALG_SHA_384 1 -#endif - -#if defined(MBEDTLS_SHA512_C) -#define PSA_WANT_ALG_SHA_512 1 -#endif - -#if defined(MBEDTLS_SHA3_C) -#define PSA_WANT_ALG_SHA3_224 1 -#define PSA_WANT_ALG_SHA3_256 1 -#define PSA_WANT_ALG_SHA3_384 1 -#define PSA_WANT_ALG_SHA3_512 1 -#endif - -/* Ensure that the PSA's supported curves (PSA_WANT_ECC_xxx) are always a - * superset of the builtin ones (MBEDTLS_ECP_DP_xxx). */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) -#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1 -#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */ -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) -#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1 -#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */ -#endif /*MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) -#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1 -#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */ -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#if !defined(PSA_WANT_ECC_MONTGOMERY_255) -#define PSA_WANT_ECC_MONTGOMERY_255 1 -#endif /* PSA_WANT_ECC_MONTGOMERY_255 */ -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -#if !defined(PSA_WANT_ECC_MONTGOMERY_448) -#define PSA_WANT_ECC_MONTGOMERY_448 1 -#endif /* PSA_WANT_ECC_MONTGOMERY_448 */ -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -#if !defined(PSA_WANT_ECC_SECP_R1_192) -#define PSA_WANT_ECC_SECP_R1_192 1 -#endif /* PSA_WANT_ECC_SECP_R1_192 */ -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -#if !defined(PSA_WANT_ECC_SECP_R1_224) -#define PSA_WANT_ECC_SECP_R1_224 1 -#endif /* PSA_WANT_ECC_SECP_R1_224 */ -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -#if !defined(PSA_WANT_ECC_SECP_R1_256) -#define PSA_WANT_ECC_SECP_R1_256 1 -#endif /* PSA_WANT_ECC_SECP_R1_256 */ -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -#if !defined(PSA_WANT_ECC_SECP_R1_384) -#define PSA_WANT_ECC_SECP_R1_384 1 -#endif /* PSA_WANT_ECC_SECP_R1_384 */ -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -#if !defined(PSA_WANT_ECC_SECP_R1_521) -#define PSA_WANT_ECC_SECP_R1_521 1 -#endif /* PSA_WANT_ECC_SECP_R1_521 */ -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -#if !defined(PSA_WANT_ECC_SECP_K1_192) -#define PSA_WANT_ECC_SECP_K1_192 1 -#endif /* PSA_WANT_ECC_SECP_K1_192 */ -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -#if !defined(PSA_WANT_ECC_SECP_K1_256) -#define PSA_WANT_ECC_SECP_K1_256 1 -#endif /* PSA_WANT_ECC_SECP_K1_256 */ -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#endif /* MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H */ diff --git a/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h b/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h deleted file mode 100644 index 1f82d9c00..000000000 --- a/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * \file mbedtls/config_adjust_ssl.h - * \brief Adjust TLS configuration - * - * This is an internal header. Do not include it directly. - * - * Automatically enable certain dependencies. Generally, MBEDTLS_xxx - * configurations need to be explicitly enabled by the user: enabling - * MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a - * compilation error. However, we do automatically enable certain options - * in some circumstances. One case is if MBEDTLS_xxx_B is an internal option - * used to identify parts of a module that are used by other module, and we - * don't want to make the symbol MBEDTLS_xxx_B part of the public API. - * Another case is if A didn't depend on B in earlier versions, and we - * want to use B in A but we need to preserve backward compatibility with - * configurations that explicitly activate MBEDTLS_xxx_A but not - * MBEDTLS_xxx_B. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONFIG_ADJUST_SSL_H -#define MBEDTLS_CONFIG_ADJUST_SSL_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -/* The following blocks make it easier to disable all of TLS, - * or of TLS 1.2 or 1.3 or DTLS, without having to manually disable all - * key exchanges, options and extensions related to them. */ - -#if !defined(MBEDTLS_SSL_TLS_C) -#undef MBEDTLS_SSL_CLI_C -#undef MBEDTLS_SSL_SRV_C -#undef MBEDTLS_SSL_PROTO_TLS1_3 -#undef MBEDTLS_SSL_PROTO_TLS1_2 -#undef MBEDTLS_SSL_PROTO_DTLS -#endif - -#if !(defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)) -#undef MBEDTLS_SSL_TICKET_C -#endif - -#if !defined(MBEDTLS_SSL_PROTO_DTLS) -#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY -#undef MBEDTLS_SSL_DTLS_CONNECTION_ID -#undef MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT -#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY -#undef MBEDTLS_SSL_DTLS_SRTP -#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE -#endif - -#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#undef MBEDTLS_SSL_ENCRYPT_THEN_MAC -#undef MBEDTLS_SSL_EXTENDED_MASTER_SECRET -#undef MBEDTLS_SSL_RENEGOTIATION -#undef MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED -#undef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED -#endif - -#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) -#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -#undef MBEDTLS_SSL_EARLY_DATA -#undef MBEDTLS_SSL_RECORD_SIZE_LIMIT -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - (defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)) -#define MBEDTLS_SSL_TLS1_2_SOME_ECC -#endif - -#endif /* MBEDTLS_CONFIG_ADJUST_SSL_H */ diff --git a/vendor/mbedtls/include/mbedtls/config_adjust_x509.h b/vendor/mbedtls/include/mbedtls/config_adjust_x509.h deleted file mode 100644 index cfb2d8891..000000000 --- a/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * \file mbedtls/config_adjust_x509.h - * \brief Adjust X.509 configuration - * - * This is an internal header. Do not include it directly. - * - * Automatically enable certain dependencies. Generally, MBEDTLS_xxx - * configurations need to be explicitly enabled by the user: enabling - * MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a - * compilation error. However, we do automatically enable certain options - * in some circumstances. One case is if MBEDTLS_xxx_B is an internal option - * used to identify parts of a module that are used by other module, and we - * don't want to make the symbol MBEDTLS_xxx_B part of the public API. - * Another case is if A didn't depend on B in earlier versions, and we - * want to use B in A but we need to preserve backward compatibility with - * configurations that explicitly activate MBEDTLS_xxx_A but not - * MBEDTLS_xxx_B. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONFIG_ADJUST_X509_H -#define MBEDTLS_CONFIG_ADJUST_X509_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -#endif /* MBEDTLS_CONFIG_ADJUST_X509_H */ diff --git a/vendor/mbedtls/include/mbedtls/config_psa.h b/vendor/mbedtls/include/mbedtls/config_psa.h deleted file mode 100644 index 5f3d0f3d5..000000000 --- a/vendor/mbedtls/include/mbedtls/config_psa.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * \file mbedtls/config_psa.h - * \brief PSA crypto configuration options (set of defines) - * - * This set of compile-time options takes settings defined in - * include/mbedtls/mbedtls_config.h and include/psa/crypto_config.h and uses - * those definitions to define symbols used in the library code. - * - * Users and integrators should not edit this file, please edit - * include/mbedtls/mbedtls_config.h for MBEDTLS_XXX settings or - * include/psa/crypto_config.h for PSA_WANT_XXX settings. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONFIG_PSA_H -#define MBEDTLS_CONFIG_PSA_H - -#include "psa/crypto_legacy.h" - -#include "psa/crypto_adjust_config_synonyms.h" - -#include "psa/crypto_adjust_config_dependencies.h" - -#include "mbedtls/config_adjust_psa_superset_legacy.h" - -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) - -/* Require built-in implementations based on PSA requirements */ - -/* We need this to have a complete list of requirements - * before we deduce what built-ins are required. */ -#include "psa/crypto_adjust_config_key_pair_types.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) -/* If we are implementing PSA crypto ourselves, then we want to enable the - * required built-ins. Otherwise, PSA features will be provided by the server. */ -#include "mbedtls/config_adjust_legacy_from_psa.h" -#endif - -#else /* MBEDTLS_PSA_CRYPTO_CONFIG */ - -/* Infer PSA requirements from Mbed TLS capabilities */ - -#include "mbedtls/config_adjust_psa_from_legacy.h" - -/* Hopefully the file above will have enabled keypair symbols in a consistent - * way, but including this here fixes them if that wasn't the case. */ -#include "psa/crypto_adjust_config_key_pair_types.h" - -#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */ - -#if defined(PSA_WANT_ALG_JPAKE) -#define PSA_WANT_ALG_SOME_PAKE 1 -#endif - -#include "psa/crypto_adjust_auto_enabled.h" - -#endif /* MBEDTLS_CONFIG_PSA_H */ diff --git a/vendor/mbedtls/include/mbedtls/constant_time.h b/vendor/mbedtls/include/mbedtls/constant_time.h deleted file mode 100644 index d31bff677..000000000 --- a/vendor/mbedtls/include/mbedtls/constant_time.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Constant-time functions - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONSTANT_TIME_H -#define MBEDTLS_CONSTANT_TIME_H - -#include - -/** Constant-time buffer comparison without branches. - * - * This is equivalent to the standard memcmp function, but is likely to be - * compiled to code using bitwise operations rather than a branch, such that - * the time taken is constant w.r.t. the data pointed to by \p a and \p b, - * and w.r.t. whether \p a and \p b are equal or not. It is not constant-time - * w.r.t. \p n . - * - * This function can be used to write constant-time code by replacing branches - * with bit operations using masks. - * - * \param a Pointer to the first buffer, containing at least \p n bytes. May not be NULL. - * \param b Pointer to the second buffer, containing at least \p n bytes. May not be NULL. - * \param n The number of bytes to compare. - * - * \return Zero if the contents of the two buffers are the same, - * otherwise non-zero. - */ -int mbedtls_ct_memcmp(const void *a, - const void *b, - size_t n); - -#endif /* MBEDTLS_CONSTANT_TIME_H */ diff --git a/vendor/mbedtls/include/mbedtls/ctr_drbg.h b/vendor/mbedtls/include/mbedtls/ctr_drbg.h deleted file mode 100644 index c8d64830b..000000000 --- a/vendor/mbedtls/include/mbedtls/ctr_drbg.h +++ /dev/null @@ -1,596 +0,0 @@ -/** - * \file ctr_drbg.h - * - * \brief This file contains definitions and functions for the - * CTR_DRBG pseudorandom generator. - * - * CTR_DRBG is a standardized way of building a PRNG from a block-cipher - * in counter mode operation, as defined in NIST SP 800-90A: - * Recommendation for Random Number Generation Using Deterministic Random - * Bit Generators. - * - * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 - * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time) - * as the underlying block cipher, with a derivation function. - * - * The security strength as defined in NIST SP 800-90A is - * 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled) - * and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is - * kept at its default value (and not overridden in mbedtls_config.h) and that the - * DRBG instance is set up with default parameters. - * See the documentation of mbedtls_ctr_drbg_seed() for more - * information. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CTR_DRBG_H -#define MBEDTLS_CTR_DRBG_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -/* The CTR_DRBG implementation can either directly call the low-level AES - * module (gated by MBEDTLS_AES_C) or call the PSA API to perform AES - * operations. Calling the AES module directly is the default, both for - * maximum backward compatibility and because it's a bit more efficient - * (less glue code). - * - * When MBEDTLS_AES_C is disabled, the CTR_DRBG module calls PSA crypto and - * thus benefits from the PSA AES accelerator driver. - * It is technically possible to enable MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO - * to use PSA even when MBEDTLS_AES_C is enabled, but there is very little - * reason to do so other than testing purposes and this is not officially - * supported. - */ -#if !defined(MBEDTLS_AES_C) -#define MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO -#endif - -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#else -#include "mbedtls/aes.h" -#endif - -#include "entropy.h" - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -/** The entropy source failed. */ -#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 -/** The requested random buffer length is too big. */ -#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 -/** The input (entropy + additional data) is too large. */ -#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 -/** Read or write error in file. */ -#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A - -#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ - -#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -#define MBEDTLS_CTR_DRBG_KEYSIZE 16 -/**< The key size in bytes used by the cipher. - * - * Compile-time choice: 16 bytes (128 bits) - * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled. - */ -#else -#define MBEDTLS_CTR_DRBG_KEYSIZE 32 -/**< The key size in bytes used by the cipher. - * - * Compile-time choice: 32 bytes (256 bits) - * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled. - */ -#endif - -#define MBEDTLS_CTR_DRBG_KEYBITS (MBEDTLS_CTR_DRBG_KEYSIZE * 8) /**< The key size for the DRBG operation, in bits. */ -#define MBEDTLS_CTR_DRBG_SEEDLEN (MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE) /**< The seed length, calculated as (counter + AES key). */ - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them using the compiler command - * line. - * \{ - */ - -/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN - * - * \brief The amount of entropy used per seed by default, in bytes. - */ -#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) -#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) -/** This is 48 bytes because the entropy module uses SHA-512. - */ -#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 - -#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ - -/** This is 32 bytes because the entropy module uses SHA-256. - */ -#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -/** \warning To achieve a 256-bit security strength, you must pass a nonce - * to mbedtls_ctr_drbg_seed(). - */ -#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */ -#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 -#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ -#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */ - -#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) -#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 -/**< The interval before reseed is performed by default. */ -#endif - -#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT) -#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 -/**< The maximum number of additional input Bytes. */ -#endif - -#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST) -#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 -/**< The maximum number of requested Bytes per call. */ -#endif - -#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) -#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 -/**< The maximum size of seed or reseed buffer in bytes. */ -#endif - -/** \} name SECTION: Module settings */ - -#define MBEDTLS_CTR_DRBG_PR_OFF 0 -/**< Prediction resistance is disabled. */ -#define MBEDTLS_CTR_DRBG_PR_ON 1 -/**< Prediction resistance is enabled. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 -/** The default length of the nonce read from the entropy source. - * - * This is \c 0 because a single read from the entropy source is sufficient - * to include a nonce. - * See the documentation of mbedtls_ctr_drbg_seed() for more information. - */ -#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0 -#else -/** The default length of the nonce read from the entropy source. - * - * This is half of the default entropy length because a single read from - * the entropy source does not provide enough material to form a nonce. - * See the documentation of mbedtls_ctr_drbg_seed() for more information. - */ -#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN (MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2 -#endif - -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) -typedef struct mbedtls_ctr_drbg_psa_context { - mbedtls_svc_key_id_t key_id; - psa_cipher_operation_t operation; -} mbedtls_ctr_drbg_psa_context; -#endif - -/** - * \brief The CTR_DRBG context structure. - */ -typedef struct mbedtls_ctr_drbg_context { - unsigned char MBEDTLS_PRIVATE(counter)[16]; /*!< The counter (V). */ - int MBEDTLS_PRIVATE(reseed_counter); /*!< The reseed counter. - * This is the number of requests that have - * been made since the last (re)seeding. - * Before the initial seeding, this field - * contains the amount of entropy in bytes - * to use as a nonce for the initial seeding, - * or -1 if no nonce length has been explicitly - * set (see mbedtls_ctr_drbg_set_nonce_len()). - */ - int MBEDTLS_PRIVATE(prediction_resistance); /*!< This determines whether prediction - resistance is enabled, that is - whether to systematically reseed before - each random generation. */ - size_t MBEDTLS_PRIVATE(entropy_len); /*!< The amount of entropy grabbed on each - seed or reseed operation, in bytes. */ - int MBEDTLS_PRIVATE(reseed_interval); /*!< The reseed interval. - * This is the maximum number of requests - * that can be made between reseedings. */ - -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - mbedtls_ctr_drbg_psa_context MBEDTLS_PRIVATE(psa_ctx); /*!< The PSA context. */ -#else - mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */ -#endif - - /* - * Callbacks (Entropy) - */ - int(*MBEDTLS_PRIVATE(f_entropy))(void *, unsigned char *, size_t); - /*!< The entropy callback function. */ - - void *MBEDTLS_PRIVATE(p_entropy); /*!< The context for the entropy function. */ - -#if defined(MBEDTLS_THREADING_C) - /* Invariant: the mutex is initialized if and only if f_entropy != NULL. - * This means that the mutex is initialized during the initial seeding - * in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free(). - * - * Note that this invariant may change without notice. Do not rely on it - * and do not access the mutex directly in application code. - */ - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); -#endif -} -mbedtls_ctr_drbg_context; - -/** - * \brief This function initializes the CTR_DRBG context, - * and prepares it for mbedtls_ctr_drbg_seed() - * or mbedtls_ctr_drbg_free(). - * - * \note The reseed interval is - * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default. - * You can override it by calling - * mbedtls_ctr_drbg_set_reseed_interval(). - * - * \param ctx The CTR_DRBG context to initialize. - */ -void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx); - -/** - * \brief This function seeds and sets up the CTR_DRBG - * entropy source for future reseeds. - * - * A typical choice for the \p f_entropy and \p p_entropy parameters is - * to use the entropy module: - * - \p f_entropy is mbedtls_entropy_func(); - * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized - * with mbedtls_entropy_init() (which registers the platform's default - * entropy sources). - * - * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default. - * You can override it by calling mbedtls_ctr_drbg_set_entropy_len(). - * - * The entropy nonce length is: - * - \c 0 if the entropy length is at least 3/2 times the entropy length, - * which guarantees that the security strength is the maximum permitted - * by the key size and entropy length according to NIST SP 800-90A §10.2.1; - * - Half the entropy length otherwise. - * You can override it by calling mbedtls_ctr_drbg_set_nonce_len(). - * With the default entropy length, the entropy nonce length is - * #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN. - * - * You can provide a nonce and personalization string in addition to the - * entropy source, to make this instantiation as unique as possible. - * See SP 800-90A §8.6.7 for more details about nonces. - * - * The _seed_material_ value passed to the derivation function in - * the CTR_DRBG Instantiate Process described in NIST SP 800-90A §10.2.1.3.2 - * is the concatenation of the following strings: - * - A string obtained by calling \p f_entropy function for the entropy - * length. - */ -#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0 -/** - * - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string - * obtained by calling \p f_entropy function for the specified length. - */ -#else -/** - * - A string obtained by calling \p f_entropy function for the entropy nonce - * length. If the entropy nonce length is \c 0, this function does not - * make a second call to \p f_entropy. - */ -#endif -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * after this function returns successfully, - * it is safe to call mbedtls_ctr_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * - The \p custom string. - * - * \note To achieve the nominal security strength permitted - * by CTR_DRBG, the entropy length must be: - * - at least 16 bytes for a 128-bit strength - * (maximum achievable strength when using AES-128); - * - at least 32 bytes for a 256-bit strength - * (maximum achievable strength when using AES-256). - * - * In addition, if you do not pass a nonce in \p custom, - * the sum of the entropy length - * and the entropy nonce length must be: - * - at least 24 bytes for a 128-bit strength - * (maximum achievable strength when using AES-128); - * - at least 48 bytes for a 256-bit strength - * (maximum achievable strength when using AES-256). - * - * \param ctx The CTR_DRBG context to seed. - * It must have been initialized with - * mbedtls_ctr_drbg_init(). - * After a successful call to mbedtls_ctr_drbg_seed(), - * you may not call mbedtls_ctr_drbg_seed() again on - * the same context unless you call - * mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init() - * again first. - * After a failed call to mbedtls_ctr_drbg_seed(), - * you must call mbedtls_ctr_drbg_free(). - * \param f_entropy The entropy callback, taking as arguments the - * \p p_entropy context, the buffer to fill, and the - * length of the buffer. - * \p f_entropy is always called with a buffer size - * less than or equal to the entropy length. - * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom The personalization string. - * This can be \c NULL, in which case the personalization - * string is empty regardless of the value of \p len. - * \param len The length of the personalization string. - * This must be at most - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - * - #MBEDTLS_CTR_DRBG_ENTROPY_LEN. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. - */ -int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len); - -/** - * \brief This function resets CTR_DRBG context to the state immediately - * after initial call of mbedtls_ctr_drbg_init(). - * - * \param ctx The CTR_DRBG context to clear. - */ -void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx); - -/** - * \brief This function turns prediction resistance on or off. - * The default value is off. - * - * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_ctr_drbg_random_with_add() - * or mbedtls_ctr_drbg_random(). - * Only use this if your entropy source has sufficient - * throughput. - * - * \param ctx The CTR_DRBG context. - * \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF. - */ -void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx, - int resistance); - -/** - * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. - * - * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN. - * - * \note The security strength of CTR_DRBG is bounded by the - * entropy length. Thus: - * - When using AES-256 - * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled, - * which is the default), - * \p len must be at least 32 (in bytes) - * to achieve a 256-bit strength. - * - When using AES-128 - * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled) - * \p len must be at least 16 (in bytes) - * to achieve a 128-bit strength. - * - * \param ctx The CTR_DRBG context. - * \param len The amount of entropy to grab, in bytes. - * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - * and at most the maximum length accepted by the - * entropy function that is set in the context. - */ -void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx, - size_t len); - -/** - * \brief This function sets the amount of entropy grabbed - * as a nonce for the initial seeding. - * - * Call this function before calling mbedtls_ctr_drbg_seed() to read - * a nonce from the entropy source during the initial seeding. - * - * \param ctx The CTR_DRBG context. - * \param len The amount of entropy to grab for the nonce, in bytes. - * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - * and at most the maximum length accepted by the - * entropy function that is set in the context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is - * more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED - * if the initial seeding has already taken place. - */ -int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx, - size_t len); - -/** - * \brief This function sets the reseed interval. - * - * The reseed interval is the number of calls to mbedtls_ctr_drbg_random() - * or mbedtls_ctr_drbg_random_with_add() after which the entropy function - * is called again. - * - * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. - * - * \param ctx The CTR_DRBG context. - * \param interval The reseed interval. - */ -void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx, - int interval); - -/** - * \brief This function reseeds the CTR_DRBG context, that is - * extracts data from the entropy source. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The CTR_DRBG context. - * \param additional Additional data to add to the state. Can be \c NULL. - * \param len The length of the additional data. - * This must be less than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len - * where \c entropy_len is the entropy length - * configured for the context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. - */ -int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, size_t len); - -/** - * \brief This function updates the state of the CTR_DRBG context. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. This must not be - * \c NULL unless \p add_len is \c 0. - * \param add_len Length of \p additional in bytes. This must be at - * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if - * \p add_len is more than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. - * \return An error from the underlying AES cipher on failure. - */ -int mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len); - -/** - * \brief This function updates a CTR_DRBG instance with additional - * data and uses it to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param p_rng The CTR_DRBG context. This must be a pointer to a - * #mbedtls_ctr_drbg_context structure. - * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * \param additional Additional data to update. Can be \c NULL, in which - * case the additional data is empty regardless of - * the value of \p add_len. - * \param add_len The length of the additional data - * if \p additional is not \c NULL. - * This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT - * and less than - * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len - * where \c entropy_len is the entropy length - * configured for the context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or - * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. - */ -int mbedtls_ctr_drbg_random_with_add(void *p_rng, - unsigned char *output, size_t output_len, - const unsigned char *additional, size_t add_len); - -/** - * \brief This function uses CTR_DRBG to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * it is safe to call mbedtls_ctr_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param p_rng The CTR_DRBG context. This must be a pointer to a - * #mbedtls_ctr_drbg_context structure. - * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or - * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. - */ -int mbedtls_ctr_drbg_random(void *p_rng, - unsigned char *output, size_t output_len); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief This function writes a seed file. - * - * \param ctx The CTR_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed - * failure. - */ -int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx, const char *path); - -/** - * \brief This function reads and updates a seed file. The seed - * is added to this instance. - * - * \param ctx The CTR_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on - * reseed failure. - * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing - * seed file is too large. - */ -int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx, const char *path); -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The CTR_DRBG checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_ctr_drbg_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* ctr_drbg.h */ diff --git a/vendor/mbedtls/include/mbedtls/debug.h b/vendor/mbedtls/include/mbedtls/debug.h deleted file mode 100644 index 45bf390a0..000000000 --- a/vendor/mbedtls/include/mbedtls/debug.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * \file debug.h - * - * \brief Functions for controlling and providing debug output from the library. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_DEBUG_H -#define MBEDTLS_DEBUG_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/ssl.h" - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_DEBUG_C) - -#define MBEDTLS_DEBUG_STRIP_PARENS(...) __VA_ARGS__ - -#define MBEDTLS_SSL_DEBUG_MSG(level, args) \ - mbedtls_debug_print_msg(ssl, level, __FILE__, __LINE__, \ - MBEDTLS_DEBUG_STRIP_PARENS args) - -#define MBEDTLS_SSL_DEBUG_RET(level, text, ret) \ - mbedtls_debug_print_ret(ssl, level, __FILE__, __LINE__, text, ret) - -#define MBEDTLS_SSL_DEBUG_BUF(level, text, buf, len) \ - mbedtls_debug_print_buf(ssl, level, __FILE__, __LINE__, text, buf, len) - -#if defined(MBEDTLS_BIGNUM_C) -#define MBEDTLS_SSL_DEBUG_MPI(level, text, X) \ - mbedtls_debug_print_mpi(ssl, level, __FILE__, __LINE__, text, X) -#endif - -#if defined(MBEDTLS_ECP_C) -#define MBEDTLS_SSL_DEBUG_ECP(level, text, X) \ - mbedtls_debug_print_ecp(ssl, level, __FILE__, __LINE__, text, X) -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if !defined(MBEDTLS_X509_REMOVE_INFO) -#define MBEDTLS_SSL_DEBUG_CRT(level, text, crt) \ - mbedtls_debug_print_crt(ssl, level, __FILE__, __LINE__, text, crt) -#else -#define MBEDTLS_SSL_DEBUG_CRT(level, text, crt) do { } while (0) -#endif /* MBEDTLS_X509_REMOVE_INFO */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_ECDH_C) -#define MBEDTLS_SSL_DEBUG_ECDH(level, ecdh, attr) \ - mbedtls_debug_printf_ecdh(ssl, level, __FILE__, __LINE__, ecdh, attr) -#endif - -#else /* MBEDTLS_DEBUG_C */ - -#define MBEDTLS_SSL_DEBUG_MSG(level, args) do { } while (0) -#define MBEDTLS_SSL_DEBUG_RET(level, text, ret) do { } while (0) -#define MBEDTLS_SSL_DEBUG_BUF(level, text, buf, len) do { } while (0) -#define MBEDTLS_SSL_DEBUG_MPI(level, text, X) do { } while (0) -#define MBEDTLS_SSL_DEBUG_ECP(level, text, X) do { } while (0) -#define MBEDTLS_SSL_DEBUG_CRT(level, text, crt) do { } while (0) -#define MBEDTLS_SSL_DEBUG_ECDH(level, ecdh, attr) do { } while (0) - -#endif /* MBEDTLS_DEBUG_C */ - -/** - * \def MBEDTLS_PRINTF_ATTRIBUTE - * - * Mark a function as having printf attributes, and thus enable checking - * via -wFormat and other flags. This does nothing on builds with compilers - * that do not support the format attribute - * - * Module: library/debug.c - * Caller: - * - * This module provides debugging functions. - */ -#if defined(__has_attribute) -#if __has_attribute(format) -#if defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 1 -#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) \ - __attribute__((__format__(gnu_printf, string_index, first_to_check))) -#else /* defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 1 */ -#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) \ - __attribute__((format(printf, string_index, first_to_check))) -#endif -#else /* __has_attribute(format) */ -#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) -#endif /* __has_attribute(format) */ -#else /* defined(__has_attribute) */ -#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) -#endif - -/** - * \def MBEDTLS_PRINTF_SIZET - * - * MBEDTLS_PRINTF_xxx: Due to issues with older window compilers - * and MinGW we need to define the printf specifier for size_t - * and long long per platform. - * - * Module: library/debug.c - * Caller: - * - * This module provides debugging functions. - */ -#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) - #include - #define MBEDTLS_PRINTF_SIZET PRIuPTR - #define MBEDTLS_PRINTF_LONGLONG PRId64 -#else \ - /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */ - #define MBEDTLS_PRINTF_SIZET "zu" - #define MBEDTLS_PRINTF_LONGLONG "lld" -#endif \ - /* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */ - -#if !defined(MBEDTLS_PRINTF_MS_TIME) -#include -#if !defined(PRId64) -#define MBEDTLS_PRINTF_MS_TIME MBEDTLS_PRINTF_LONGLONG -#else -#define MBEDTLS_PRINTF_MS_TIME PRId64 -#endif -#endif /* MBEDTLS_PRINTF_MS_TIME */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Set the threshold error level to handle globally all debug output. - * Debug messages that have a level over the threshold value are - * discarded. - * (Default value: 0 = No debug ) - * - * \param threshold threshold level of messages to filter on. Messages at a - * higher level will be discarded. - * - Debug levels - * - 0 No debug - * - 1 Error - * - 2 State change - * - 3 Informational - * - 4 Verbose - */ -void mbedtls_debug_set_threshold(int threshold); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_DEBUG_H */ diff --git a/vendor/mbedtls/include/mbedtls/des.h b/vendor/mbedtls/include/mbedtls/des.h deleted file mode 100644 index 2b097a13d..000000000 --- a/vendor/mbedtls/include/mbedtls/des.h +++ /dev/null @@ -1,385 +0,0 @@ -/** - * \file des.h - * - * \brief DES block cipher - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - */ -#ifndef MBEDTLS_DES_H -#define MBEDTLS_DES_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#define MBEDTLS_DES_ENCRYPT 1 -#define MBEDTLS_DES_DECRYPT 0 - -/** The data input has an invalid length. */ -#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 - -#define MBEDTLS_DES_KEY_SIZE 8 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_DES_ALT) -// Regular implementation -// - -/** - * \brief DES context structure - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -typedef struct mbedtls_des_context { - uint32_t MBEDTLS_PRIVATE(sk)[32]; /*!< DES subkeys */ -} -mbedtls_des_context; - -/** - * \brief Triple-DES context structure - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -typedef struct mbedtls_des3_context { - uint32_t MBEDTLS_PRIVATE(sk)[96]; /*!< 3DES subkeys */ -} -mbedtls_des3_context; - -#else /* MBEDTLS_DES_ALT */ -#include "des_alt.h" -#endif /* MBEDTLS_DES_ALT */ - -/** - * \brief Initialize DES context - * - * \param ctx DES context to be initialized - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_init(mbedtls_des_context *ctx); - -/** - * \brief Clear DES context - * - * \param ctx DES context to be cleared - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_free(mbedtls_des_context *ctx); - -/** - * \brief Initialize Triple-DES context - * - * \param ctx DES3 context to be initialized - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des3_init(mbedtls_des3_context *ctx); - -/** - * \brief Clear Triple-DES context - * - * \param ctx DES3 context to be cleared - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des3_free(mbedtls_des3_context *ctx); - -/** - * \brief Set key parity on the given key to odd. - * - * DES keys are 56 bits long, but each byte is padded with - * a parity bit to allow verification. - * - * \param key 8-byte secret key - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]); - -/** - * \brief Check that key parity on the given key is odd. - * - * DES keys are 56 bits long, but each byte is padded with - * a parity bit to allow verification. - * - * \param key 8-byte secret key - * - * \return 0 is parity was ok, 1 if parity was not correct. - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE]); - -/** - * \brief Check that key is not a weak or semi-weak DES key - * - * \param key 8-byte secret key - * - * \return 0 if no weak key was found, 1 if a weak key was identified. - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]); - -/** - * \brief DES key schedule (56-bit, encryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - * - * \return 0 - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]); - -/** - * \brief DES key schedule (56-bit, decryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - * - * \return 0 - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]); - -/** - * \brief Triple-DES key schedule (112-bit, encryption) - * - * \param ctx 3DES context to be initialized - * \param key 16-byte secret key - * - * \return 0 - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]); - -/** - * \brief Triple-DES key schedule (112-bit, decryption) - * - * \param ctx 3DES context to be initialized - * \param key 16-byte secret key - * - * \return 0 - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]); - -/** - * \brief Triple-DES key schedule (168-bit, encryption) - * - * \param ctx 3DES context to be initialized - * \param key 24-byte secret key - * - * \return 0 - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]); - -/** - * \brief Triple-DES key schedule (168-bit, decryption) - * - * \param ctx 3DES context to be initialized - * \param key 24-byte secret key - * - * \return 0 - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]); - -/** - * \brief DES-ECB block encryption/decryption - * - * \param ctx DES context - * \param input 64-bit input block - * \param output 64-bit output block - * - * \return 0 if successful - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, - const unsigned char input[8], - unsigned char output[8]); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief DES-CBC buffer encryption/decryption - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx DES context - * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/** - * \brief 3DES-ECB block encryption/decryption - * - * \param ctx 3DES context - * \param input 64-bit input block - * \param output 64-bit output block - * - * \return 0 if successful - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, - const unsigned char input[8], - unsigned char output[8]); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief 3DES-CBC buffer encryption/decryption - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx 3DES context - * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/** - * \brief Internal function for key expansion. - * (Only exposed to allow overriding it, - * see MBEDTLS_DES_SETKEY_ALT) - * - * \param SK Round keys - * \param key Base key - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers - * instead. - */ -void mbedtls_des_setkey(uint32_t SK[32], - const unsigned char key[MBEDTLS_DES_KEY_SIZE]); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_des_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* des.h */ diff --git a/vendor/mbedtls/include/mbedtls/dhm.h b/vendor/mbedtls/include/mbedtls/dhm.h deleted file mode 100644 index bbfe6ea8d..000000000 --- a/vendor/mbedtls/include/mbedtls/dhm.h +++ /dev/null @@ -1,972 +0,0 @@ -/** - * \file dhm.h - * - * \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange - * definitions and functions. - * - * Diffie-Hellman-Merkle (DHM) key exchange is defined in - * RFC-2631: Diffie-Hellman Key Agreement Method and - * Public-Key Cryptography Standards (PKCS) #3: Diffie - * Hellman Key Agreement Standard. - * - * RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for - * Internet Key Exchange (IKE) defines a number of standardized - * Diffie-Hellman groups for IKE. - * - * RFC-5114: Additional Diffie-Hellman Groups for Use with IETF - * Standards defines a number of standardized Diffie-Hellman - * groups that can be used. - * - * \warning The security of the DHM key exchange relies on the proper choice - * of prime modulus - optimally, it should be a safe prime. The usage - * of non-safe primes both decreases the difficulty of the underlying - * discrete logarithm problem and can lead to small subgroup attacks - * leaking private exponent bits when invalid public keys are used - * and not detected. This is especially relevant if the same DHM - * parameters are reused for multiple key exchanges as in static DHM, - * while the criticality of small-subgroup attacks is lower for - * ephemeral DHM. - * - * \warning For performance reasons, the code does neither perform primality - * nor safe primality tests, nor the expensive checks for invalid - * subgroups. Moreover, even if these were performed, non-standardized - * primes cannot be trusted because of the possibility of backdoors - * that can't be effectively checked for. - * - * \warning Diffie-Hellman-Merkle is therefore a security risk when not using - * standardized primes generated using a trustworthy ("nothing up - * my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS - * protocol, DH parameters need to be negotiated, so using the default - * primes systematically is not always an option. If possible, use - * Elliptic Curve Diffie-Hellman (ECDH), which has better performance, - * and for which the TLS protocol mandates the use of standard - * parameters. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_DHM_H -#define MBEDTLS_DHM_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" -#include "mbedtls/bignum.h" - -/* - * DHM Error codes - */ -/** Bad input parameters. */ -#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080 -/** Reading of the DHM parameters failed. */ -#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100 -/** Making of the DHM parameters failed. */ -#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 -/** Reading of the public values failed. */ -#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200 -/** Making of the public value failed. */ -#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 -/** Calculation of the DHM secret failed. */ -#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300 -/** The ASN.1 data is not formatted correctly. */ -#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 -/** Allocation of memory failed. */ -#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 -/** Read or write of file failed. */ -#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 -/** Setting the modulus and generator failed. */ -#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580 - -/** Which parameter to access in mbedtls_dhm_get_value(). */ -typedef enum { - MBEDTLS_DHM_PARAM_P, /*!< The prime modulus. */ - MBEDTLS_DHM_PARAM_G, /*!< The generator. */ - MBEDTLS_DHM_PARAM_X, /*!< Our secret value. */ - MBEDTLS_DHM_PARAM_GX, /*!< Our public key = \c G^X mod \c P. */ - MBEDTLS_DHM_PARAM_GY, /*!< The public key of the peer = \c G^Y mod \c P. */ - MBEDTLS_DHM_PARAM_K, /*!< The shared secret = \c G^(XY) mod \c P. */ -} mbedtls_dhm_parameter; - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_DHM_ALT) - -/** - * \brief The DHM context structure. - */ -typedef struct mbedtls_dhm_context { - mbedtls_mpi MBEDTLS_PRIVATE(P); /*!< The prime modulus. */ - mbedtls_mpi MBEDTLS_PRIVATE(G); /*!< The generator. */ - mbedtls_mpi MBEDTLS_PRIVATE(X); /*!< Our secret value. */ - mbedtls_mpi MBEDTLS_PRIVATE(GX); /*!< Our public key = \c G^X mod \c P. */ - mbedtls_mpi MBEDTLS_PRIVATE(GY); /*!< The public key of the peer = \c G^Y mod \c P. */ - mbedtls_mpi MBEDTLS_PRIVATE(K); /*!< The shared secret = \c G^(XY) mod \c P. */ - mbedtls_mpi MBEDTLS_PRIVATE(RP); /*!< The cached value = \c R^2 mod \c P. */ - mbedtls_mpi MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */ - mbedtls_mpi MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */ - mbedtls_mpi MBEDTLS_PRIVATE(pX); /*!< The previous \c X. */ -} -mbedtls_dhm_context; - -#else /* MBEDTLS_DHM_ALT */ -#include "dhm_alt.h" -#endif /* MBEDTLS_DHM_ALT */ - -/** - * \brief This function initializes the DHM context. - * - * \param ctx The DHM context to initialize. - */ -void mbedtls_dhm_init(mbedtls_dhm_context *ctx); - -/** - * \brief This function parses the DHM parameters in a - * TLS ServerKeyExchange handshake message - * (DHM modulus, generator, and public key). - * - * \note In a TLS handshake, this is the how the client - * sets up its DHM context from the server's public - * DHM key material. - * - * \param ctx The DHM context to use. This must be initialized. - * \param p On input, *p must be the start of the input buffer. - * On output, *p is updated to point to the end of the data - * that has been read. On success, this is the first byte - * past the end of the ServerKeyExchange parameters. - * On error, this is the point at which an error has been - * detected, which is usually not useful except to debug - * failures. - * \param end The end of the input buffer. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx, - unsigned char **p, - const unsigned char *end); - -/** - * \brief This function generates a DHM key pair and exports its - * public part together with the DHM parameters in the format - * used in a TLS ServerKeyExchange handshake message. - * - * \note This function assumes that the DHM parameters \c ctx->P - * and \c ctx->G have already been properly set. For that, use - * mbedtls_dhm_set_group() below in conjunction with - * mbedtls_mpi_read_binary() and mbedtls_mpi_read_string(). - * - * \note In a TLS handshake, this is the how the server generates - * and exports its DHM key material. - * - * \param ctx The DHM context to use. This must be initialized - * and have the DHM parameters set. It may or may not - * already have imported the peer's public key. - * \param x_size The private key size in Bytes. - * \param olen The address at which to store the number of Bytes - * written on success. This must not be \c NULL. - * \param output The destination buffer. This must be a writable buffer of - * sufficient size to hold the reduced binary presentation of - * the modulus, the generator and the public key, each wrapped - * with a 2-byte length field. It is the responsibility of the - * caller to ensure that enough space is available. Refer to - * mbedtls_mpi_size() to computing the byte-size of an MPI. - * \param f_rng The RNG function. Must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t *olen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function sets the prime modulus and generator. - * - * \note This function can be used to set \c ctx->P, \c ctx->G - * in preparation for mbedtls_dhm_make_params(). - * - * \param ctx The DHM context to configure. This must be initialized. - * \param P The MPI holding the DHM prime modulus. This must be - * an initialized MPI. - * \param G The MPI holding the DHM generator. This must be an - * initialized MPI. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx, - const mbedtls_mpi *P, - const mbedtls_mpi *G); - -/** - * \brief This function imports the raw public value of the peer. - * - * \note In a TLS handshake, this is the how the server imports - * the Client's public DHM key. - * - * \param ctx The DHM context to use. This must be initialized and have - * its DHM parameters set, e.g. via mbedtls_dhm_set_group(). - * It may or may not already have generated its own private key. - * \param input The input buffer containing the \c G^Y value of the peer. - * This must be a readable buffer of size \p ilen Bytes. - * \param ilen The size of the input buffer \p input in Bytes. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx, - const unsigned char *input, size_t ilen); - -/** - * \brief This function creates a DHM key pair and exports - * the raw public key in big-endian format. - * - * \note The destination buffer is always fully written - * so as to contain a big-endian representation of G^X mod P. - * If it is larger than \c ctx->len, it is padded accordingly - * with zero-bytes at the beginning. - * - * \param ctx The DHM context to use. This must be initialized and - * have the DHM parameters set. It may or may not already - * have imported the peer's public key. - * \param x_size The private key size in Bytes. - * \param output The destination buffer. This must be a writable buffer of - * size \p olen Bytes. - * \param olen The length of the destination buffer. This must be at least - * equal to `ctx->len` (the size of \c P). - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t olen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function derives and exports the shared secret - * \c (G^Y)^X mod \c P. - * - * \note If \p f_rng is not \c NULL, it is used to blind the input as - * a countermeasure against timing attacks. Blinding is used - * only if our private key \c X is re-used, and not used - * otherwise. We recommend always passing a non-NULL - * \p f_rng argument. - * - * \param ctx The DHM context to use. This must be initialized - * and have its own private key generated and the peer's - * public key imported. - * \param output The buffer to write the generated shared key to. This - * must be a writable buffer of size \p output_size Bytes. - * \param output_size The size of the destination buffer. This must be at - * least the size of \c ctx->len (the size of \c P). - * \param olen On exit, holds the actual number of Bytes written. - * \param f_rng The RNG function. Must not be \c NULL. Used for - * blinding. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. - */ -int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx, - unsigned char *output, size_t output_size, size_t *olen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function returns the size of the prime modulus in bits. - * - * \param ctx The DHM context to query. - * - * \return The size of the prime modulus in bits, - * i.e. the number n such that 2^(n-1) <= P < 2^n. - */ -size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx); - -/** - * \brief This function returns the size of the prime modulus in bytes. - * - * \param ctx The DHM context to query. - * - * \return The size of the prime modulus in bytes, - * i.e. the number n such that 2^(8*(n-1)) <= P < 2^(8*n). - */ -size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx); - -/** - * \brief This function copies a parameter of a DHM key. - * - * \param ctx The DHM context to query. - * \param param The parameter to copy. - * \param dest The MPI object to copy the value into. It must be - * initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_DHM_BAD_INPUT_DATA if \p param is invalid. - * \return An \c MBEDTLS_ERR_MPI_XXX error code if the copy fails. - */ -int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx, - mbedtls_dhm_parameter param, - mbedtls_mpi *dest); - -/** - * \brief This function frees and clears the components - * of a DHM context. - * - * \param ctx The DHM context to free and clear. This may be \c NULL, - * in which case this function is a no-op. If it is not \c NULL, - * it must point to an initialized DHM context. - */ -void mbedtls_dhm_free(mbedtls_dhm_context *ctx); - -#if defined(MBEDTLS_ASN1_PARSE_C) -/** - * \brief This function parses DHM parameters in PEM or DER format. - * - * \param dhm The DHM context to import the DHM parameters into. - * This must be initialized. - * \param dhmin The input buffer. This must be a readable buffer of - * length \p dhminlen Bytes. - * \param dhminlen The size of the input buffer \p dhmin, including the - * terminating \c NULL Byte for PEM data. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error - * code on failure. - */ -int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin, - size_t dhminlen); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief This function loads and parses DHM parameters from a file. - * - * \param dhm The DHM context to load the parameters to. - * This must be initialized. - * \param path The filename to read the DHM parameters from. - * This must not be \c NULL. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX - * error code on failure. - */ -int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path); -#endif /* MBEDTLS_FS_IO */ -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The DMH checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_dhm_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ -#ifdef __cplusplus -} -#endif - -/** - * RFC 3526, RFC 5114 and RFC 7919 standardize a number of - * Diffie-Hellman groups, some of which are included here - * for use within the SSL/TLS module and the user's convenience - * when configuring the Diffie-Hellman parameters by hand - * through \c mbedtls_ssl_conf_dh_param. - * - * The following lists the source of the above groups in the standards: - * - RFC 5114 section 2.2: 2048-bit MODP Group with 224-bit Prime Order Subgroup - * - RFC 3526 section 3: 2048-bit MODP Group - * - RFC 3526 section 4: 3072-bit MODP Group - * - RFC 3526 section 5: 4096-bit MODP Group - * - RFC 7919 section A.1: ffdhe2048 - * - RFC 7919 section A.2: ffdhe3072 - * - RFC 7919 section A.3: ffdhe4096 - * - RFC 7919 section A.4: ffdhe6144 - * - RFC 7919 section A.5: ffdhe8192 - * - * The constants with suffix "_p" denote the chosen prime moduli, while - * the constants with suffix "_g" denote the chosen generator - * of the associated prime field. - * - * The constants further suffixed with "_bin" are provided in binary format, - * while all other constants represent null-terminated strings holding the - * hexadecimal presentation of the respective numbers. - * - * The primes from RFC 3526 and RFC 7919 have been generating by the following - * trust-worthy procedure: - * - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number - * the first and last 64 bits are all 1, and the remaining N - 128 bits of - * which are 0x7ff...ff. - * - Add the smallest multiple of the first N - 129 bits of the binary expansion - * of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string - * such that the resulting integer is a safe-prime. - * - The result is the respective RFC 3526 / 7919 prime, and the corresponding - * generator is always chosen to be 2 (which is a square for these prime, - * hence the corresponding subgroup has order (p-1)/2 and avoids leaking a - * bit in the private exponent). - * - */ - -/* - * Trustworthy DHM parameters in binary form - */ - -#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, \ - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, \ - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, \ - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, \ - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, \ - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, \ - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, \ - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, \ - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, \ - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, \ - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, \ - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, \ - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, \ - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, \ - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, \ - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, \ - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } - -#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ - 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ - 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ - 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ - 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ - 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ - 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ - 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ - 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ - 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ - 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ - 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ - 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ - 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ - 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ - 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ - 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ - 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ - 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ - 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ - 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ - 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ - 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ - 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ - 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ - 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ - 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ - 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ - 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ - 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ - 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ - 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ - 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ - 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ - 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ - 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ - 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ - 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ - 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ - 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ - 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ - 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ - 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ - 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ - 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ - 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ - 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ - 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ - 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ - 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ - 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ - 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ - 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ - 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ - 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ - 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ - 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ - 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ - 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ - 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ - 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ - 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ - 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ - 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ - 0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 } - -#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN { \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ - 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ - 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ - 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ - 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ - 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ - 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ - 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ - 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ - 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ - 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ - 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ - 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ - 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ - 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ - 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ - 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ - 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ - 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ - 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ - 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ - 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ - 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ - 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ - 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ - 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ - 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ - 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ - 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ - 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ - 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ - 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ - 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ - 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ - 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ - 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ - 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ - 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ - 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ - 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ - 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ - 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ - 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ - 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ - 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ - 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ - 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ - 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ - 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ - 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ - 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ - 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ - 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ - 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ - 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ - 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ - 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ - 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ - 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ - 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ - 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ - 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ - 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ - 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ - 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ - 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ - 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ - 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ - 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ - 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ - 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ - 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ - 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ - 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ - 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ - 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ - 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ - 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ - 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ - 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ - 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ - 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ - 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ - 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ - 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ - 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ - 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ - 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ - 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ - 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ - 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ - 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ - 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ - 0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, \ - 0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, \ - 0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, \ - 0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, \ - 0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, \ - 0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, \ - 0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, \ - 0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, \ - 0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, \ - 0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, \ - 0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, \ - 0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, \ - 0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, \ - 0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, \ - 0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, \ - 0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, \ - 0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, \ - 0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, \ - 0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, \ - 0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, \ - 0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, \ - 0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, \ - 0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, \ - 0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, \ - 0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, \ - 0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, \ - 0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, \ - 0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, \ - 0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, \ - 0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, \ - 0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, \ - 0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, \ - 0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, \ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } - -#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 } - -#endif /* dhm.h */ diff --git a/vendor/mbedtls/include/mbedtls/ecdh.h b/vendor/mbedtls/include/mbedtls/ecdh.h deleted file mode 100644 index e81d5c3a5..000000000 --- a/vendor/mbedtls/include/mbedtls/ecdh.h +++ /dev/null @@ -1,454 +0,0 @@ -/** - * \file ecdh.h - * - * \brief This file contains ECDH definitions and functions. - * - * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous - * key agreement protocol allowing two parties to establish a shared - * secret over an insecure channel. Each party must have an - * elliptic-curve public private key pair. - * - * For more information, see NIST SP 800-56A Rev. 2: Recommendation for - * Pair-Wise Key Establishment Schemes Using Discrete Logarithm - * Cryptography. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_ECDH_H -#define MBEDTLS_ECDH_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/ecp.h" - -/* - * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context - * defined in `ecdh.h`). For most applications, the choice of format makes - * no difference, since all library functions can work with either format, - * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. - - * The new format used when this option is disabled is smaller - * (56 bytes on a 32-bit platform). In future versions of the library, it - * will support alternative implementations of ECDH operations. - * The new format is incompatible with applications that access - * context fields directly and with restartable ECP operations. - */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) -#define MBEDTLS_ECDH_LEGACY_CONTEXT -#else -#undef MBEDTLS_ECDH_LEGACY_CONTEXT -#endif - -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) -#undef MBEDTLS_ECDH_LEGACY_CONTEXT -#include "everest/everest.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Defines the source of the imported EC key. - */ -typedef enum { - MBEDTLS_ECDH_OURS, /**< Our key. */ - MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ -} mbedtls_ecdh_side; - -#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) -/** - * Defines the ECDH implementation used. - * - * Later versions of the library may add new variants, therefore users should - * not make any assumptions about them. - */ -typedef enum { - MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ - MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */ -#endif -} mbedtls_ecdh_variant; - -/** - * The context used by the default ECDH implementation. - * - * Later versions might change the structure of this context, therefore users - * should not make any assumptions about the structure of - * mbedtls_ecdh_context_mbed. - */ -typedef struct mbedtls_ecdh_context_mbed { - mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ - mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ - mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ -#endif -} mbedtls_ecdh_context_mbed; -#endif - -/** - * - * \warning Performing multiple operations concurrently on the same - * ECDSA context is not supported; objects of this type - * should not be shared between multiple threads. - * \brief The ECDH context structure. - */ -typedef struct mbedtls_ecdh_context { -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ - mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ - mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ - int MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages. */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */ - mbedtls_mpi MBEDTLS_PRIVATE(_d); /*!< The previous \p d. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - int MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. */ - mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#else - uint8_t MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages - as defined in RFC 4492. */ - mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id);/*!< The elliptic curve used. */ - mbedtls_ecdh_variant MBEDTLS_PRIVATE(var); /*!< The ECDH implementation/structure used. */ - union { - mbedtls_ecdh_context_mbed MBEDTLS_PRIVATE(mbed_ecdh); -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - mbedtls_ecdh_context_everest MBEDTLS_PRIVATE(everest_ecdh); -#endif - } MBEDTLS_PRIVATE(ctx); /*!< Implementation-specific context. The - context in use is specified by the \c var - field. */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - uint8_t MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. Functions of - an alternative implementation not supporting - restartable mode must return - MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error - if this flag is set. */ -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ -} -mbedtls_ecdh_context; - -/** - * \brief Return the ECP group for provided context. - * - * \note To access group specific fields, users should use - * `mbedtls_ecp_curve_info_from_grp_id` or - * `mbedtls_ecp_group_load` on the extracted `group_id`. - * - * \param ctx The ECDH context to parse. This must not be \c NULL. - * - * \return The \c mbedtls_ecp_group_id of the context. - */ -mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx); - -/** - * \brief Check whether a given group can be used for ECDH. - * - * \param gid The ECP group ID to check. - * - * \return \c 1 if the group can be used, \c 0 otherwise - */ -int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid); - -/** - * \brief This function generates an ECDH keypair on an elliptic - * curve. - * - * This function performs the first of two core computations - * implemented during the ECDH key exchange. The second core - * computation is performed by mbedtls_ecdh_compute_shared(). - * - * \see ecp.h - * - * \param grp The ECP group to use. This must be initialized and have - * domain parameters loaded, for example through - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). - * \param d The destination MPI (private key). - * This must be initialized. - * \param Q The destination point (public key). - * This must be initialized. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX or - * \c MBEDTLS_MPI_XXX error code on failure. - */ -int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function computes the shared secret. - * - * This function performs the second of two core computations - * implemented during the ECDH key exchange. The first core - * computation is performed by mbedtls_ecdh_gen_public(). - * - * \see ecp.h - * - * \note If \p f_rng is not NULL, it is used to implement - * countermeasures against side-channel attacks. - * For more information, see mbedtls_ecp_mul(). - * - * \param grp The ECP group to use. This must be initialized and have - * domain parameters loaded, for example through - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). - * \param z The destination MPI (shared secret). - * This must be initialized. - * \param Q The public key from another party. - * This must be initialized. - * \param d Our secret exponent (private key). - * This must be initialized. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't need a - * context argument. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX or - * \c MBEDTLS_MPI_XXX error code on failure. - */ -int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function initializes an ECDH context. - * - * \param ctx The ECDH context to initialize. This must not be \c NULL. - */ -void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx); - -/** - * \brief This function sets up the ECDH context with the information - * given. - * - * This function should be called after mbedtls_ecdh_init() but - * before mbedtls_ecdh_make_params(). There is no need to call - * this function before mbedtls_ecdh_read_params(). - * - * This is the first function used by a TLS server for ECDHE - * ciphersuites. - * - * \param ctx The ECDH context to set up. This must be initialized. - * \param grp_id The group id of the group to set up the context for. - * - * \return \c 0 on success. - */ -int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, - mbedtls_ecp_group_id grp_id); - -/** - * \brief This function frees a context. - * - * \param ctx The context to free. This may be \c NULL, in which - * case this function does nothing. If it is not \c NULL, - * it must point to an initialized ECDH context. - */ -void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx); - -/** - * \brief This function generates an EC key pair and exports its - * in the format used in a TLS ServerKeyExchange handshake - * message. - * - * This is the second function used by a TLS server for ECDHE - * ciphersuites. (It is called after mbedtls_ecdh_setup().) - * - * \see ecp.h - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, for example via mbedtls_ecdh_setup(). - * \param olen The address at which to store the number of Bytes written. - * \param buf The destination buffer. This must be a writable buffer of - * length \p blen Bytes. - * \param blen The length of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function parses the ECDHE parameters in a - * TLS ServerKeyExchange handshake message. - * - * \note In a TLS handshake, this is the how the client - * sets up its ECDHE context from the server's public - * ECDHE key material. - * - * \see ecp.h - * - * \param ctx The ECDHE context to use. This must be initialized. - * \param buf On input, \c *buf must be the start of the input buffer. - * On output, \c *buf is updated to point to the end of the - * data that has been read. On success, this is the first byte - * past the end of the ServerKeyExchange parameters. - * On error, this is the point at which an error has been - * detected, which is usually not useful except to debug - * failures. - * \param end The end of the input buffer. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. - * - */ -int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx, - const unsigned char **buf, - const unsigned char *end); - -/** - * \brief This function sets up an ECDH context from an EC key. - * - * It is used by clients and servers in place of the - * ServerKeyExchange for static ECDH, and imports ECDH - * parameters from the EC key information of a certificate. - * - * \see ecp.h - * - * \param ctx The ECDH context to set up. This must be initialized. - * \param key The EC key to use. This must be initialized. - * \param side Defines the source of the key. Possible values are: - * - #MBEDTLS_ECDH_OURS: The key is ours. - * - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. - * - * \return \c 0 on success. - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - * - */ -int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side); - -/** - * \brief This function generates a public key and exports it - * as a TLS ClientKeyExchange payload. - * - * This is the second function used by a TLS client for ECDH(E) - * ciphersuites. - * - * \see ecp.h - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, the latter usually by - * mbedtls_ecdh_read_params(). - * \param olen The address at which to store the number of Bytes written. - * This must not be \c NULL. - * \param buf The destination buffer. This must be a writable buffer - * of length \p blen Bytes. - * \param blen The size of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL in case \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function parses and processes the ECDHE payload of a - * TLS ClientKeyExchange message. - * - * This is the third function used by a TLS server for ECDH(E) - * ciphersuites. (It is called after mbedtls_ecdh_setup() and - * mbedtls_ecdh_make_params().) - * - * \see ecp.h - * - * \param ctx The ECDH context to use. This must be initialized - * and bound to a group, for example via mbedtls_ecdh_setup(). - * \param buf The pointer to the ClientKeyExchange payload. This must - * be a readable buffer of length \p blen Bytes. - * \param blen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx, - const unsigned char *buf, size_t blen); - -/** - * \brief This function derives and exports the shared secret. - * - * This is the last function used by both TLS client - * and servers. - * - * \note If \p f_rng is not NULL, it is used to implement - * countermeasures against side-channel attacks. - * For more information, see mbedtls_ecp_mul(). - * - * \see ecp.h - - * \param ctx The ECDH context to use. This must be initialized - * and have its own private key generated and the peer's - * public key imported. - * \param olen The address at which to store the total number of - * Bytes written on success. This must not be \c NULL. - * \param buf The buffer to write the generated shared key to. This - * must be a writable buffer of size \p blen Bytes. - * \param blen The length of the destination buffer \p buf in Bytes. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context. This may be \c NULL if \p f_rng - * doesn't need a context argument. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. - */ -int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief This function enables restartable EC computations for this - * context. (Default: disabled.) - * - * \see \c mbedtls_ecp_set_max_ops() - * - * \note It is not possible to safely disable restartable - * computations once enabled, except by free-ing the context, - * which cancels possible in-progress operations. - * - * \param ctx The ECDH context to use. This must be initialized. - */ -void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#ifdef __cplusplus -} -#endif - -#endif /* ecdh.h */ diff --git a/vendor/mbedtls/include/mbedtls/ecdsa.h b/vendor/mbedtls/include/mbedtls/ecdsa.h deleted file mode 100644 index c1616615f..000000000 --- a/vendor/mbedtls/include/mbedtls/ecdsa.h +++ /dev/null @@ -1,674 +0,0 @@ -/** - * \file ecdsa.h - * - * \brief This file contains ECDSA definitions and functions. - * - * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in - * Standards for Efficient Cryptography Group (SECG): - * SEC1 Elliptic Curve Cryptography. - * The use of ECDSA for TLS is defined in RFC-4492: Elliptic Curve - * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS). - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_ECDSA_H -#define MBEDTLS_ECDSA_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/ecp.h" -#include "mbedtls/md.h" - -/** - * \brief Maximum ECDSA signature size for a given curve bit size - * - * \param bits Curve size in bits - * \return Maximum signature size in bytes - * - * \note This macro returns a compile-time constant if its argument - * is one. It may evaluate its argument multiple times. - */ -/* - * Ecdsa-Sig-Value ::= SEQUENCE { - * r INTEGER, - * s INTEGER - * } - * - * For each of r and s, the value (V) may include an extra initial "0" bit. - */ -#define MBEDTLS_ECDSA_MAX_SIG_LEN(bits) \ - (/*T,L of SEQUENCE*/ ((bits) >= 61 * 8 ? 3 : 2) + \ - /*T,L of r,s*/ 2 * (((bits) >= 127 * 8 ? 3 : 2) + \ - /*V of r,s*/ ((bits) + 8) / 8)) - -/** The maximal size of an ECDSA signature in Bytes. */ -#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN(MBEDTLS_ECP_MAX_BITS) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief The ECDSA context structure. - * - * \warning Performing multiple operations concurrently on the same - * ECDSA context is not supported; objects of this type - * should not be shared between multiple threads. - * - * \note pk_wrap module assumes that "ecdsa_context" is identical - * to "ecp_keypair" (see for example structure - * "mbedtls_eckey_info" where ECDSA sign/verify functions - * are used also for EC key) - */ -typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Internal restart context for ecdsa_verify() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx; - -/** - * \brief Internal restart context for ecdsa_sign() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx; - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/** - * \brief Internal restart context for ecdsa_sign_det() - * - * \note Opaque struct, defined in ecdsa.c - */ -typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx; -#endif - -/** - * \brief General context for resuming ECDSA operations - */ -typedef struct { - mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(ecp); /*!< base context for ECP restart and - shared administrative info */ - mbedtls_ecdsa_restart_ver_ctx *MBEDTLS_PRIVATE(ver); /*!< ecdsa_verify() sub-context */ - mbedtls_ecdsa_restart_sig_ctx *MBEDTLS_PRIVATE(sig); /*!< ecdsa_sign() sub-context */ -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - mbedtls_ecdsa_restart_det_ctx *MBEDTLS_PRIVATE(det); /*!< ecdsa_sign_det() sub-context */ -#endif -} mbedtls_ecdsa_restart_ctx; - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_ecdsa_restart_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief This function checks whether a given group can be used - * for ECDSA. - * - * \param gid The ECP group ID to check. - * - * \return \c 1 if the group can be used, \c 0 otherwise - */ -int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid); - -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message. - * - * \note The deterministic version implemented in - * mbedtls_ecdsa_sign_det_ext() is usually preferred. - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated - * as defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized. - * \param buf The content to be signed. This is usually the hash of - * the original data to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param f_rng The RNG function, used both to generate the ECDSA nonce - * and for blinding. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX - * or \c MBEDTLS_MPI_XXX error code on failure. - */ -int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - mbedtls_f_rng_t *f_rng, void *p_rng); - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message, deterministic version. - * - * For more information, see RFC-6979: Deterministic - * Usage of the Digital Signature Algorithm (DSA) and Elliptic - * Curve Digital Signature Algorithm (ECDSA). - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized - * and setup, for example through mbedtls_ecp_gen_privkey(). - * \param buf The hashed content to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param md_alg The hash algorithm used to hash the original data. - * \param f_rng_blind The RNG function used for blinding. This must not be - * \c NULL. - * \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This - * may be \c NULL if \p f_rng_blind doesn't need a context - * parameter. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure. - */ -int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, - mbedtls_mpi *s, const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - mbedtls_f_rng_t *f_rng_blind, - void *p_rng_blind); -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#if !defined(MBEDTLS_ECDSA_SIGN_ALT) -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message, in a restartable way. - * - * \note The deterministic version implemented in - * mbedtls_ecdsa_sign_det_restartable() is usually - * preferred. - * - * \note This function is like \c mbedtls_ecdsa_sign() but - * it can return early and restart according to the - * limit set with \c mbedtls_ecp_set_max_ops() to - * reduce blocking. - * - * \note If the bitlength of the message hash is larger - * than the bitlength of the group order, then the - * hash is truncated as defined in Standards for - * Efficient Cryptography Group (SECG): SEC1 Elliptic - * Curve Cryptography, section 4.1.3, step 5. - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized - * and setup, for example through - * mbedtls_ecp_gen_privkey(). - * \param buf The hashed content to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param f_rng The RNG function used to generate the ECDSA nonce. - * This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * \param f_rng_blind The RNG function used for blinding. This must not be - * \c NULL. - * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context parameter. - * \param rs_ctx The restart context to use. This may be \c NULL - * to disable restarting. If it is not \c NULL, it - * must point to an initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c - * mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX, \c - * MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX - * error code on failure. - */ -int mbedtls_ecdsa_sign_restartable( - mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_f_rng_t *f_rng, - void *p_rng, - mbedtls_f_rng_t *f_rng_blind, - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx); - -#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - -/** - * \brief This function computes the ECDSA signature of a - * previously-hashed message, in a restartable way. - * - * \note This function is like \c - * mbedtls_ecdsa_sign_det_ext() but it can return - * early and restart according to the limit set with - * \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \note If the bitlength of the message hash is larger - * than the bitlength of the group order, then the - * hash is truncated as defined in Standards for - * Efficient Cryptography Group (SECG): SEC1 Elliptic - * Curve Cryptography, section 4.1.3, step 5. - * - * \see ecp.h - * - * \param grp The context for the elliptic curve to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param r The MPI context in which to store the first part - * the signature. This must be initialized. - * \param s The MPI context in which to store the second part - * the signature. This must be initialized. - * \param d The private signing key. This must be initialized - * and setup, for example through - * mbedtls_ecp_gen_privkey(). - * \param buf The hashed content to be signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param md_alg The hash algorithm used to hash the original data. - * \param f_rng_blind The RNG function used for blinding. This must not be - * \c NULL. - * \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This may be - * \c NULL if \p f_rng_blind doesn't need a context parameter. - * \param rs_ctx The restart context to use. This may be \c NULL - * to disable restarting. If it is not \c NULL, it - * must point to an initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c - * mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX, \c - * MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX - * error code on failure. - */ -int mbedtls_ecdsa_sign_det_restartable( - mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - mbedtls_f_rng_t *f_rng_blind, - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx); - -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -/** - * \brief This function verifies the ECDSA signature of a - * previously-hashed message. - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.4, step 3. - * - * \see ecp.h - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param buf The hashed content that was signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param Q The public key to use for verification. This must be - * initialized and setup. - * \param r The first integer of the signature. - * This must be initialized. - * \param s The second integer of the signature. - * This must be initialized. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure. - */ -int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, const mbedtls_mpi *r, - const mbedtls_mpi *s); - -#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) -/** - * \brief This function verifies the ECDSA signature of a - * previously-hashed message, in a restartable manner - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.4, step 3. - * - * \see ecp.h - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param buf The hashed content that was signed. This must be a readable - * buffer of length \p blen Bytes. It may be \c NULL if - * \p blen is zero. - * \param blen The length of \p buf in Bytes. - * \param Q The public key to use for verification. This must be - * initialized and setup. - * \param r The first integer of the signature. - * This must be initialized. - * \param s The second integer of the signature. - * This must be initialized. - * \param rs_ctx The restart context to use. This may be \c NULL to disable - * restarting. If it is not \c NULL, it must point to an - * initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX - * error code on failure. - */ -int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, - const mbedtls_mpi *s, - mbedtls_ecdsa_restart_ctx *rs_ctx); - -#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ - -/** - * \brief This function computes the ECDSA signature and writes it - * to a buffer, serialized as defined in RFC-4492: - * Elliptic Curve Cryptography (ECC) Cipher Suites for - * Transport Layer Security (TLS). - * - * \warning It is not thread-safe to use the same context in - * multiple threads. - * - * \note The deterministic version is used if - * #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more - * information, see RFC-6979: Deterministic Usage - * of the Digital Signature Algorithm (DSA) and Elliptic - * Curve Digital Signature Algorithm (ECDSA). - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.3, step 5. - * - * \see ecp.h - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param md_alg The message digest that was used to hash the message. - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p hlen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length at least twice as large as the - * size of the curve used, plus 9. For example, 73 Bytes if - * a 256-bit curve is used. A buffer length of - * #MBEDTLS_ECDSA_MAX_LEN is always safe. - * \param sig_size The size of the \p sig buffer in bytes. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param f_rng The RNG function. This is used for blinding. - * If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also - * used to generate the ECDSA nonce. - * This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't use a context. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or - * \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t sig_size, size_t *slen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function computes the ECDSA signature and writes it - * to a buffer, in a restartable way. - * - * \see \c mbedtls_ecdsa_write_signature() - * - * \note This function is like \c mbedtls_ecdsa_write_signature() - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and private key bound to it, for example - * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). - * \param md_alg The message digest that was used to hash the message. - * \param hash The message hash to be signed. This must be a readable - * buffer of length \p hlen Bytes. - * \param hlen The length of the hash \p hash in Bytes. - * \param sig The buffer to which to write the signature. This must be a - * writable buffer of length at least twice as large as the - * size of the curve used, plus 9. For example, 73 Bytes if - * a 256-bit curve is used. A buffer length of - * #MBEDTLS_ECDSA_MAX_LEN is always safe. - * \param sig_size The size of the \p sig buffer in bytes. - * \param slen The address at which to store the actual length of - * the signature written. Must not be \c NULL. - * \param f_rng The RNG function. This is used for blinding. - * If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also - * used to generate the ECDSA nonce. - * This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng is \c NULL or doesn't use a context. - * \param rs_ctx The restart context to use. This may be \c NULL to disable - * restarting. If it is not \c NULL, it must point to an - * initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or - * \c MBEDTLS_ERR_ASN1_XXX error code on failure. - */ -int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t sig_size, size_t *slen, - mbedtls_f_rng_t *f_rng, - void *p_rng, - mbedtls_ecdsa_restart_ctx *rs_ctx); - -/** - * \brief This function reads and verifies an ECDSA signature. - * - * \note If the bitlength of the message hash is larger than the - * bitlength of the group order, then the hash is truncated as - * defined in Standards for Efficient Cryptography Group - * (SECG): SEC1 Elliptic Curve Cryptography, section - * 4.1.4, step 3. - * - * \see ecp.h - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and public key bound to it. - * \param hash The message hash that was signed. This must be a readable - * buffer of length \p hlen Bytes. - * \param hlen The size of the hash \p hash. - * \param sig The signature to read and verify. This must be a readable - * buffer of length \p slen Bytes. - * \param slen The size of \p sig in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. - * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig, but its length is less than \p siglen. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX - * error code on failure for any other reason. - */ -int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen); - -/** - * \brief This function reads and verifies an ECDSA signature, - * in a restartable way. - * - * \see \c mbedtls_ecdsa_read_signature() - * - * \note This function is like \c mbedtls_ecdsa_read_signature() - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param ctx The ECDSA context to use. This must be initialized - * and have a group and public key bound to it. - * \param hash The message hash that was signed. This must be a readable - * buffer of length \p hlen Bytes. - * \param hlen The size of the hash \p hash. - * \param sig The signature to read and verify. This must be a readable - * buffer of length \p slen Bytes. - * \param slen The size of \p sig in Bytes. - * \param rs_ctx The restart context to use. This may be \c NULL to disable - * restarting. If it is not \c NULL, it must point to an - * initialized restart context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. - * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig, but its length is less than \p siglen. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX - * error code on failure for any other reason. - */ -int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen, - mbedtls_ecdsa_restart_ctx *rs_ctx); - -/** - * \brief This function generates an ECDSA keypair on the given curve. - * - * \see ecp.h - * - * \param ctx The ECDSA context to store the keypair in. - * This must be initialized. - * \param gid The elliptic curve to use. One of the various - * \c MBEDTLS_ECP_DP_XXX macros depending on configuration. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. - */ -int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** - * \brief This function sets up an ECDSA context from an EC key pair. - * - * \see ecp.h - * - * \param ctx The ECDSA context to setup. This must be initialized. - * \param key The EC key to use. This must be initialized and hold - * a private-public key pair or a public key. In the former - * case, the ECDSA context may be used for signature creation - * and verification after this call. In the latter case, it - * may be used for signature verification. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. - */ -int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, - const mbedtls_ecp_keypair *key); - -/** - * \brief This function initializes an ECDSA context. - * - * \param ctx The ECDSA context to initialize. - * This must not be \c NULL. - */ -void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx); - -/** - * \brief This function frees an ECDSA context. - * - * \param ctx The ECDSA context to free. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must be initialized. - */ -void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx); - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context. - * - * \param ctx The restart context to initialize. - * This must not be \c NULL. - */ -void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx); - -/** - * \brief Free the components of a restart context. - * - * \param ctx The restart context to free. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must be initialized. - */ -void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#ifdef __cplusplus -} -#endif - -#endif /* ecdsa.h */ diff --git a/vendor/mbedtls/include/mbedtls/ecjpake.h b/vendor/mbedtls/include/mbedtls/ecjpake.h deleted file mode 100644 index 7da8cb4e5..000000000 --- a/vendor/mbedtls/include/mbedtls/ecjpake.h +++ /dev/null @@ -1,298 +0,0 @@ -/** - * \file ecjpake.h - * - * \brief Elliptic curve J-PAKE - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_ECJPAKE_H -#define MBEDTLS_ECJPAKE_H -#include "mbedtls/private_access.h" - -/* - * J-PAKE is a password-authenticated key exchange that allows deriving a - * strong shared secret from a (potentially low entropy) pre-shared - * passphrase, with forward secrecy and mutual authentication. - * https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling - * - * This file implements the Elliptic Curve variant of J-PAKE, - * as defined in Chapter 7.4 of the Thread v1.0 Specification, - * available to members of the Thread Group http://threadgroup.org/ - * - * As the J-PAKE algorithm is inherently symmetric, so is our API. - * Each party needs to send its first round message, in any order, to the - * other party, then each sends its second round message, in any order. - * The payloads are serialized in a way suitable for use in TLS, but could - * also be use outside TLS. - */ -#include "mbedtls/build_info.h" - -#include "mbedtls/ecp.h" -#include "mbedtls/md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Roles in the EC J-PAKE exchange - */ -typedef enum { - MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */ - MBEDTLS_ECJPAKE_SERVER, /**< Server */ - MBEDTLS_ECJPAKE_NONE, /**< Undefined */ -} mbedtls_ecjpake_role; - -#if !defined(MBEDTLS_ECJPAKE_ALT) -/** - * EC J-PAKE context structure. - * - * J-PAKE is a symmetric protocol, except for the identifiers used in - * Zero-Knowledge Proofs, and the serialization of the second message - * (KeyExchange) as defined by the Thread spec. - * - * In order to benefit from this symmetry, we choose a different naming - * convention from the Thread v1.0 spec. Correspondence is indicated in the - * description as a pair C: client name, S: server name - */ -typedef struct mbedtls_ecjpake_context { - mbedtls_md_type_t MBEDTLS_PRIVATE(md_type); /**< Hash to use */ - mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /**< Elliptic curve */ - mbedtls_ecjpake_role MBEDTLS_PRIVATE(role); /**< Are we client or server? */ - int MBEDTLS_PRIVATE(point_format); /**< Format for point export */ - - mbedtls_ecp_point MBEDTLS_PRIVATE(Xm1); /**< My public key 1 C: X1, S: X3 */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Xm2); /**< My public key 2 C: X2, S: X4 */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Xp1); /**< Peer public key 1 C: X3, S: X1 */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Xp2); /**< Peer public key 2 C: X4, S: X2 */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Xp); /**< Peer public key C: Xs, S: Xc */ - - mbedtls_mpi MBEDTLS_PRIVATE(xm1); /**< My private key 1 C: x1, S: x3 */ - mbedtls_mpi MBEDTLS_PRIVATE(xm2); /**< My private key 2 C: x2, S: x4 */ - - mbedtls_mpi MBEDTLS_PRIVATE(s); /**< Pre-shared secret (passphrase) */ -} mbedtls_ecjpake_context; - -#else /* MBEDTLS_ECJPAKE_ALT */ -#include "ecjpake_alt.h" -#endif /* MBEDTLS_ECJPAKE_ALT */ - -/** - * \brief Initialize an ECJPAKE context. - * - * \param ctx The ECJPAKE context to initialize. - * This must not be \c NULL. - */ -void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx); - -/** - * \brief Set up an ECJPAKE context for use. - * - * \note Currently the only values for hash/curve allowed by the - * standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1. - * - * \param ctx The ECJPAKE context to set up. This must be initialized. - * \param role The role of the caller. This must be either - * #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER. - * \param hash The identifier of the hash function to use, - * for example #MBEDTLS_MD_SHA256. - * \param curve The identifier of the elliptic curve to use, - * for example #MBEDTLS_ECP_DP_SECP256R1. - * \param secret The pre-shared secret (passphrase). This must be - * a readable not empty buffer of length \p len Bytes. It need - * only be valid for the duration of this call. - * \param len The length of the pre-shared secret \p secret. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx, - mbedtls_ecjpake_role role, - mbedtls_md_type_t hash, - mbedtls_ecp_group_id curve, - const unsigned char *secret, - size_t len); - -/** - * \brief Set the point format for future reads and writes. - * - * \param ctx The ECJPAKE context to configure. - * \param point_format The point format to use: - * #MBEDTLS_ECP_PF_UNCOMPRESSED (default) - * or #MBEDTLS_ECP_PF_COMPRESSED. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p point_format - * is invalid. - */ -int mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx, - int point_format); - -/** - * \brief Check if an ECJPAKE context is ready for use. - * - * \param ctx The ECJPAKE context to check. This must be - * initialized. - * - * \return \c 0 if the context is ready for use. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise. - */ -int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx); - -/** - * \brief Generate and write the first round message - * (TLS: contents of the Client/ServerHello extension, - * excluding extension type and length bytes). - * - * \param ctx The ECJPAKE context to use. This must be - * initialized and set up. - * \param buf The buffer to write the contents to. This must be a - * writable buffer of length \p len Bytes. - * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number - * of Bytes written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Read and process the first round message - * (TLS: contents of the Client/ServerHello extension, - * excluding extension type and length bytes). - * - * \param ctx The ECJPAKE context to use. This must be initialized - * and set up. - * \param buf The buffer holding the first round message. This must - * be a readable buffer of length \p len Bytes. - * \param len The length in Bytes of \p buf. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len); - -/** - * \brief Generate and write the second round message - * (TLS: contents of the Client/ServerKeyExchange). - * - * \param ctx The ECJPAKE context to use. This must be initialized, - * set up, and already have performed round one. - * \param buf The buffer to write the round two contents to. - * This must be a writable buffer of length \p len Bytes. - * \param len The size of \p buf in Bytes. - * \param olen The address at which to store the total number of Bytes - * written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Read and process the second round message - * (TLS: contents of the Client/ServerKeyExchange). - * - * \param ctx The ECJPAKE context to use. This must be initialized - * and set up and already have performed round one. - * \param buf The buffer holding the second round message. This must - * be a readable buffer of length \p len Bytes. - * \param len The length in Bytes of \p buf. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len); - -/** - * \brief Derive the shared secret - * (TLS: Pre-Master Secret). - * - * \param ctx The ECJPAKE context to use. This must be initialized, - * set up and have performed both round one and two. - * \param buf The buffer to write the derived secret to. This must - * be a writable buffer of length \p len Bytes. - * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number of Bytes - * written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Write the shared key material to be passed to a Key - * Derivation Function as described in RFC8236. - * - * \param ctx The ECJPAKE context to use. This must be initialized, - * set up and have performed both round one and two. - * \param buf The buffer to write the derived secret to. This must - * be a writable buffer of length \p len Bytes. - * \param len The length of \p buf in Bytes. - * \param olen The address at which to store the total number of bytes - * written to \p buf. This must not be \c NULL. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This - * may be \c NULL if \p f_rng doesn't use a context. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This clears an ECJPAKE context and frees any - * embedded data structure. - * - * \param ctx The ECJPAKE context to free. This may be \c NULL, - * in which case this function does nothing. If it is not - * \c NULL, it must point to an initialized ECJPAKE context. - */ -void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_ecjpake_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - - -#endif /* ecjpake.h */ diff --git a/vendor/mbedtls/include/mbedtls/ecp.h b/vendor/mbedtls/include/mbedtls/ecp.h deleted file mode 100644 index 5cc027143..000000000 --- a/vendor/mbedtls/include/mbedtls/ecp.h +++ /dev/null @@ -1,1528 +0,0 @@ -/** - * \file ecp.h - * - * \brief This file provides an API for Elliptic Curves over GF(P) (ECP). - * - * The use of ECP in cryptography and TLS is defined in - * Standards for Efficient Cryptography Group (SECG): SEC1 - * Elliptic Curve Cryptography and - * RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites - * for Transport Layer Security (TLS). - * - * RFC-2409: The Internet Key Exchange (IKE) defines ECP - * group types. - * - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_ECP_H -#define MBEDTLS_ECP_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" -#include "mbedtls/platform_util.h" - -#include "mbedtls/bignum.h" - -/* - * ECP error codes - */ -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 -/** The buffer is too small to write to. */ -#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 -/** The requested feature is not available, for example, the requested curve is not supported. */ -#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 -/** The signature is not valid. */ -#define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 -/** Memory allocation failed. */ -#define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 -/** Generation of random value, such as ephemeral key, failed. */ -#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 -/** Invalid private or public key. */ -#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 -/** The buffer contains a valid signature followed by more data. */ -#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 -/** Operation in progress, call again with the same parameters to continue. */ -#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 - -/* Flags indicating whether to include code that is specific to certain - * types of curves. These flags are for internal library use only. */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED -#endif -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ - defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -#define MBEDTLS_ECP_MONTGOMERY_ENABLED -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Domain-parameter identifiers: curve, subgroup, and generator. - * - * \note Only curves over prime fields are supported. - * - * \warning This library does not support validation of arbitrary domain - * parameters. Therefore, only standardized domain parameters from trusted - * sources should be used. See mbedtls_ecp_group_load(). - */ -/* Note: when adding a new curve: - * - Add it at the end of this enum, otherwise you'll break the ABI by - * changing the numerical value for existing curves. - * - Increment MBEDTLS_ECP_DP_MAX below if needed. - * - Update the calculation of MBEDTLS_ECP_MAX_BITS below. - * - Add the corresponding MBEDTLS_ECP_DP_xxx_ENABLED macro definition to - * mbedtls_config.h. - * - List the curve as a dependency of MBEDTLS_ECP_C and - * MBEDTLS_ECDSA_C if supported in check_config.h. - * - Add the curve to the appropriate curve type macro - * MBEDTLS_ECP_yyy_ENABLED above. - * - Add the necessary definitions to ecp_curves.c. - * - Add the curve to the ecp_supported_curves array in ecp.c. - * - Add the curve to applicable profiles in x509_crt.c. - * - Add the curve to applicable presets in ssl_tls.c. - */ -typedef enum { - MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */ - MBEDTLS_ECP_DP_SECP192R1, /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP224R1, /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP384R1, /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_SECP521R1, /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */ - MBEDTLS_ECP_DP_BP256R1, /*!< Domain parameters for 256-bit Brainpool curve. */ - MBEDTLS_ECP_DP_BP384R1, /*!< Domain parameters for 384-bit Brainpool curve. */ - MBEDTLS_ECP_DP_BP512R1, /*!< Domain parameters for 512-bit Brainpool curve. */ - MBEDTLS_ECP_DP_CURVE25519, /*!< Domain parameters for Curve25519. */ - MBEDTLS_ECP_DP_SECP192K1, /*!< Domain parameters for 192-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */ - MBEDTLS_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */ -} mbedtls_ecp_group_id; - -/** - * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE. - */ -#define MBEDTLS_ECP_DP_MAX 14 - -/* - * Curve types - */ -typedef enum { - MBEDTLS_ECP_TYPE_NONE = 0, - MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ - MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ -} mbedtls_ecp_curve_type; - -/** - * Curve information, for use by other modules. - * - * The fields of this structure are part of the public API and can be - * accessed directly by applications. Future versions of the library may - * add extra fields or reorder existing fields. - */ -typedef struct mbedtls_ecp_curve_info { - mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */ - uint16_t tls_id; /*!< The TLS NamedCurve identifier. */ - uint16_t bit_size; /*!< The curve size in bits. */ - const char *name; /*!< A human-friendly name. */ -} mbedtls_ecp_curve_info; - -/** - * \brief The ECP point structure, in Jacobian coordinates. - * - * \note All functions expect and return points satisfying - * the following condition: Z == 0 or - * Z == 1. Other values of \p Z are - * used only by internal functions. - * The point is zero, or "at infinity", if Z == 0. - * Otherwise, \p X and \p Y are its standard (affine) - * coordinates. - */ -typedef struct mbedtls_ecp_point { - mbedtls_mpi MBEDTLS_PRIVATE(X); /*!< The X coordinate of the ECP point. */ - mbedtls_mpi MBEDTLS_PRIVATE(Y); /*!< The Y coordinate of the ECP point. */ - mbedtls_mpi MBEDTLS_PRIVATE(Z); /*!< The Z coordinate of the ECP point. */ -} -mbedtls_ecp_point; - -#if !defined(MBEDTLS_ECP_ALT) -/* - * default Mbed TLS elliptic curve arithmetic implementation - * - * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an - * alternative implementation for the whole module and it will replace this - * one.) - */ - -/** - * \brief The ECP group structure. - * - * We consider two types of curve equations: - *
  • Short Weierstrass: y^2 = x^3 + A x + B mod P - * (SEC1 + RFC-4492)
  • - *
  • Montgomery: y^2 = x^3 + A x^2 + x mod P (Curve25519, - * Curve448)
- * In both cases, the generator (\p G) for a prime-order subgroup is fixed. - * - * For Short Weierstrass, this subgroup is the whole curve, and its - * cardinality is denoted by \p N. Our code requires that \p N is an - * odd prime as mbedtls_ecp_mul() requires an odd number, and - * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. - * - * The default implementation only initializes \p A without setting it to the - * authentic value for curves with A = -3(SECP256R1, etc), in which - * case you need to load \p A by yourself when using domain parameters directly, - * for example: - * \code - * mbedtls_mpi_init(&A); - * mbedtls_ecp_group_init(&grp); - * CHECK_RETURN(mbedtls_ecp_group_load(&grp, grp_id)); - * if (mbedtls_ecp_group_a_is_minus_3(&grp)) { - * CHECK_RETURN(mbedtls_mpi_sub_int(&A, &grp.P, 3)); - * } else { - * CHECK_RETURN(mbedtls_mpi_copy(&A, &grp.A)); - * } - * - * do_something_with_a(&A); - * - * cleanup: - * mbedtls_mpi_free(&A); - * mbedtls_ecp_group_free(&grp); - * \endcode - * - * For Montgomery curves, we do not store \p A, but (A + 2) / 4, - * which is the quantity used in the formulas. Additionally, \p nbits is - * not the size of \p N but the required size for private keys. - * - * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. - * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the - * range of 0..2^(2*pbits)-1, and transforms it in-place to an integer - * which is congruent mod \p P to the given MPI, and is close enough to \p pbits - * in size, so that it may be efficiently brought in the 0..P-1 range by a few - * additions or subtractions. Therefore, it is only an approximate modular - * reduction. It must return 0 on success and non-zero on failure. - * - * \note Alternative implementations of the ECP module must obey the - * following constraints. - * * Group IDs must be distinct: if two group structures have - * the same ID, then they must be identical. - * * The fields \c id, \c P, \c A, \c B, \c G, \c N, - * \c pbits and \c nbits must have the same type and semantics - * as in the built-in implementation. - * They must be available for reading, but direct modification - * of these fields does not need to be supported. - * They do not need to be at the same offset in the structure. - */ -typedef struct mbedtls_ecp_group { - mbedtls_ecp_group_id id; /*!< An internal group identifier. */ - mbedtls_mpi P; /*!< The prime modulus of the base field. */ - mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. Note that - \p A is not set to the authentic value in some cases. - Refer to detailed description of ::mbedtls_ecp_group if - using domain parameters in the structure. - For Montgomery curves: (A + 2) / 4. */ - mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. - For Montgomery curves: unused. */ - mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ - mbedtls_mpi N; /*!< The order of \p G. */ - size_t pbits; /*!< The number of bits in \p P.*/ - size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. - For Montgomery curves: the number of bits in the - private keys. */ - /* End of public fields */ - - unsigned int MBEDTLS_PRIVATE(h); /*!< \internal 1 if the constants are static. */ - int(*MBEDTLS_PRIVATE(modp))(mbedtls_mpi *); /*!< The function for fast pseudo-reduction - mod \p P (see above).*/ - int(*MBEDTLS_PRIVATE(t_pre))(mbedtls_ecp_point *, void *); /*!< Unused. */ - int(*MBEDTLS_PRIVATE(t_post))(mbedtls_ecp_point *, void *); /*!< Unused. */ - void *MBEDTLS_PRIVATE(t_data); /*!< Unused. */ - mbedtls_ecp_point *MBEDTLS_PRIVATE(T); /*!< Pre-computed points for ecp_mul_comb(). */ - size_t MBEDTLS_PRIVATE(T_size); /*!< The number of dynamic allocated pre-computed points. */ -} -mbedtls_ecp_group; - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h, or define them using the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_ECP_WINDOW_SIZE) -/* - * Maximum "window" size used for point multiplication. - * Default: a point where higher memory usage yields diminishing performance - * returns. - * Minimum value: 2. Maximum value: 7. - * - * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) - * points used for point multiplication. This value is directly tied to EC - * peak memory usage, so decreasing it by one should roughly cut memory usage - * by two (if large curves are in use). - * - * Reduction in size may reduce speed, but larger curves are impacted first. - * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): - * w-size: 6 5 4 3 2 - * 521 145 141 135 120 97 - * 384 214 209 198 177 146 - * 256 320 320 303 262 226 - * 224 475 475 453 398 342 - * 192 640 640 633 587 476 - */ -#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< The maximum window size used. */ -#endif /* MBEDTLS_ECP_WINDOW_SIZE */ - -#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) -/* - * Trade code size for speed on fixed-point multiplication. - * - * This speeds up repeated multiplication of the generator (that is, the - * multiplication in ECDSA signatures, and half of the multiplications in - * ECDSA verification and ECDHE) by a factor roughly 3 to 4. - * - * For each n-bit Short Weierstrass curve that is enabled, this adds 4n bytes - * of code size if n < 384 and 8n otherwise. - * - * Change this value to 0 to reduce code size. - */ -#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ -#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ - -/** \} name SECTION: Module settings */ - -#else /* MBEDTLS_ECP_ALT */ -#include "ecp_alt.h" -#endif /* MBEDTLS_ECP_ALT */ - -/** - * The maximum size of the groups, that is, of \c N and \c P. - */ -#if !defined(MBEDTLS_ECP_LIGHT) -/* Dummy definition to help code that has optional ECP support and - * defines an MBEDTLS_ECP_MAX_BYTES-sized array unconditionally. */ -#define MBEDTLS_ECP_MAX_BITS 1 -/* Note: the curves must be listed in DECREASING size! */ -#elif defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 521 -#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 512 -#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 448 -#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 384 -#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 384 -#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 256 -#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 256 -#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 256 -#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 255 -#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 225 // n is slightly above 2^224 -#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 224 -#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 192 -#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -#define MBEDTLS_ECP_MAX_BITS 192 -#else /* !MBEDTLS_ECP_LIGHT */ -#error "Missing definition of MBEDTLS_ECP_MAX_BITS" -#endif /* !MBEDTLS_ECP_LIGHT */ - -#define MBEDTLS_ECP_MAX_BYTES ((MBEDTLS_ECP_MAX_BITS + 7) / 8) -#define MBEDTLS_ECP_MAX_PT_LEN (2 * MBEDTLS_ECP_MAX_BYTES + 1) - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Internal restart context for multiplication - * - * \note Opaque struct - */ -typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx; - -/** - * \brief Internal restart context for ecp_muladd() - * - * \note Opaque struct - */ -typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx; - -/** - * \brief General context for resuming ECC operations - */ -typedef struct { - unsigned MBEDTLS_PRIVATE(ops_done); /*!< current ops count */ - unsigned MBEDTLS_PRIVATE(depth); /*!< call depth (0 = top-level) */ - mbedtls_ecp_restart_mul_ctx *MBEDTLS_PRIVATE(rsm); /*!< ecp_mul_comb() sub-context */ - mbedtls_ecp_restart_muladd_ctx *MBEDTLS_PRIVATE(ma); /*!< ecp_muladd() sub-context */ -} mbedtls_ecp_restart_ctx; - -/* - * Operation counts for restartable functions - */ -#define MBEDTLS_ECP_OPS_CHK 3 /*!< basic ops count for ecp_check_pubkey() */ -#define MBEDTLS_ECP_OPS_DBL 8 /*!< basic ops count for ecp_double_jac() */ -#define MBEDTLS_ECP_OPS_ADD 11 /*!< basic ops count for see ecp_add_mixed() */ -#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv() */ - -/** - * \brief Internal; for restartable functions in other modules. - * Check and update basic ops budget. - * - * \param grp Group structure - * \param rs_ctx Restart context - * \param ops Number of basic ops to do - * - * \return \c 0 if doing \p ops basic ops is still allowed, - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise. - */ -int mbedtls_ecp_check_budget(const mbedtls_ecp_group *grp, - mbedtls_ecp_restart_ctx *rs_ctx, - unsigned ops); - -/* Utility macro for checking and updating ops budget */ -#define MBEDTLS_ECP_BUDGET(ops) \ - MBEDTLS_MPI_CHK(mbedtls_ecp_check_budget(grp, rs_ctx, \ - (unsigned) (ops))); - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define MBEDTLS_ECP_BUDGET(ops) /* no-op; for compatibility */ - -/* We want to declare restartable versions of existing functions anyway */ -typedef void mbedtls_ecp_restart_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief The ECP key-pair structure. - * - * A generic key-pair that may be used for ECDSA and fixed ECDH, for example. - * - * \note Members are deliberately in the same order as in the - * ::mbedtls_ecdsa_context structure. - */ -typedef struct mbedtls_ecp_keypair { - mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< Elliptic curve and base point */ - mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< our secret value */ - mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< our public value */ -} -mbedtls_ecp_keypair; - -/** - * The uncompressed point format for Short Weierstrass curves - * (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX). - */ -#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 -/** - * The compressed point format for Short Weierstrass curves - * (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX). - * - * \warning While this format is supported for all concerned curves for - * writing, when it comes to parsing, it is not supported for all - * curves. Specifically, parsing compressed points on - * MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1 is not - * supported. - */ -#define MBEDTLS_ECP_PF_COMPRESSED 1 - -/* - * Some other constants from RFC 4492 - */ -#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Set the maximum number of basic operations done in a row. - * - * If more operations are needed to complete a computation, - * #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the - * function performing the computation. It is then the - * caller's responsibility to either call again with the same - * parameters until it returns 0 or an error code; or to free - * the restart context if the operation is to be aborted. - * - * It is strictly required that all input parameters and the - * restart context be the same on successive calls for the - * same operation, but output parameters need not be the - * same; they must not be used until the function finally - * returns 0. - * - * This only applies to functions whose documentation - * mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the - * SSL module). For functions that accept a "restart context" - * argument, passing NULL disables restart and makes the - * function equivalent to the function with the same name - * with \c _restartable removed. For functions in the ECDH - * module, restart is disabled unless the function accepts - * an "ECDH context" argument and - * mbedtls_ecdh_enable_restart() was previously called on - * that context. For function in the SSL module, restart is - * only enabled for specific sides and key exchanges - * (currently only for clients and ECDHE-ECDSA). - * - * \warning Using the PSA interruptible interfaces with keys in local - * storage and no accelerator driver will also call this - * function to set the values specified via those interfaces, - * overwriting values previously set. Care should be taken if - * mixing these two interfaces. - * - * \param max_ops Maximum number of basic operations done in a row. - * Default: 0 (unlimited). - * Lower (non-zero) values mean ECC functions will block for - * a lesser maximum amount of time. - * - * \note A "basic operation" is defined as a rough equivalent of a - * multiplication in GF(p) for the NIST P-256 curve. - * As an indication, with default settings, a scalar - * multiplication (full run of \c mbedtls_ecp_mul()) is: - * - about 3300 basic operations for P-256 - * - about 9400 basic operations for P-384 - * - * \note Very low values are not always respected: sometimes - * functions need to block for a minimum number of - * operations, and will do so even if max_ops is set to a - * lower value. That minimum depends on the curve size, and - * can be made lower by decreasing the value of - * \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, here is the - * lowest effective value for various curves and values of - * that parameter (w for short): - * w=6 w=5 w=4 w=3 w=2 - * P-256 208 208 160 136 124 - * P-384 682 416 320 272 248 - * P-521 1364 832 640 544 496 - * - * \note This setting is currently ignored by Curve25519. - */ -void mbedtls_ecp_set_max_ops(unsigned max_ops); - -/** - * \brief Check if restart is enabled (max_ops != 0) - * - * \return \c 0 if \c max_ops == 0 (restart disabled) - * \return \c 1 otherwise (restart enabled) - */ -int mbedtls_ecp_restart_is_enabled(void); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/* - * Get the type of a curve - */ -mbedtls_ecp_curve_type mbedtls_ecp_get_type(const mbedtls_ecp_group *grp); - -/** - * \brief This function retrieves the information defined in - * mbedtls_ecp_curve_info() for all supported curves. - * - * \note This function returns information about all curves - * supported by the library. Some curves may not be - * supported for all algorithms. Call mbedtls_ecdh_can_do() - * or mbedtls_ecdsa_can_do() to check if a curve is - * supported for ECDH or ECDSA. - * - * \return A statically allocated array. The last entry is 0. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list(void); - -/** - * \brief This function retrieves the list of internal group - * identifiers of all supported curves in the order of - * preference. - * - * \note This function returns information about all curves - * supported by the library. Some curves may not be - * supported for all algorithms. Call mbedtls_ecdh_can_do() - * or mbedtls_ecdsa_can_do() to check if a curve is - * supported for ECDH or ECDSA. - * - * \return A statically allocated array, - * terminated with MBEDTLS_ECP_DP_NONE. - */ -const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list(void); - -/** - * \brief This function retrieves curve information from an internal - * group identifier. - * - * \param grp_id An \c MBEDTLS_ECP_DP_XXX value. - * - * \return The associated curve information on success. - * \return NULL on failure. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id(mbedtls_ecp_group_id grp_id); - -/** - * \brief This function retrieves curve information from a TLS - * NamedCurve value. - * - * \param tls_id An \c MBEDTLS_ECP_DP_XXX value. - * - * \return The associated curve information on success. - * \return NULL on failure. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id(uint16_t tls_id); - -/** - * \brief This function retrieves curve information from a - * human-readable name. - * - * \param name The human-readable name. - * - * \return The associated curve information on success. - * \return NULL on failure. - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name(const char *name); - -/** - * \brief This function initializes a point as zero. - * - * \param pt The point to initialize. - */ -void mbedtls_ecp_point_init(mbedtls_ecp_point *pt); - -/** - * \brief This function initializes an ECP group context - * without loading any domain parameters. - * - * \note After this function is called, domain parameters - * for various ECP groups can be loaded through the - * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() - * functions. - */ -void mbedtls_ecp_group_init(mbedtls_ecp_group *grp); - -/** - * \brief This function initializes a key pair as an invalid one. - * - * \param key The key pair to initialize. - */ -void mbedtls_ecp_keypair_init(mbedtls_ecp_keypair *key); - -/** - * \brief This function frees the components of a point. - * - * \param pt The point to free. - */ -void mbedtls_ecp_point_free(mbedtls_ecp_point *pt); - -/** - * \brief This function frees the components of an ECP group. - * - * \param grp The group to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized ECP group. - */ -void mbedtls_ecp_group_free(mbedtls_ecp_group *grp); - -/** - * \brief This function frees the components of a key pair. - * - * \param key The key pair to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized ECP key pair. - */ -void mbedtls_ecp_keypair_free(mbedtls_ecp_keypair *key); - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context. - * - * \param ctx The restart context to initialize. This must - * not be \c NULL. - */ -void mbedtls_ecp_restart_init(mbedtls_ecp_restart_ctx *ctx); - -/** - * \brief Free the components of a restart context. - * - * \param ctx The restart context to free. This may be \c NULL, in which - * case this function returns immediately. If it is not - * \c NULL, it must point to an initialized restart context. - */ -void mbedtls_ecp_restart_free(mbedtls_ecp_restart_ctx *ctx); -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief This function copies the contents of point \p Q into - * point \p P. - * - * \param P The destination point. This must be initialized. - * \param Q The source point. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code for other kinds of failure. - */ -int mbedtls_ecp_copy(mbedtls_ecp_point *P, const mbedtls_ecp_point *Q); - -/** - * \brief This function copies the contents of group \p src into - * group \p dst. - * - * \param dst The destination group. This must be initialized. - * \param src The source group. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_group_copy(mbedtls_ecp_group *dst, - const mbedtls_ecp_group *src); - -/** - * \brief This function sets a point to the point at infinity. - * - * \param pt The point to set. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_set_zero(mbedtls_ecp_point *pt); - -/** - * \brief This function checks if a point is the point at infinity. - * - * \param pt The point to test. This must be initialized. - * - * \return \c 1 if the point is zero. - * \return \c 0 if the point is non-zero. - * \return A negative error code on failure. - */ -int mbedtls_ecp_is_zero(mbedtls_ecp_point *pt); - -/** - * \brief This function compares two points. - * - * \note This assumes that the points are normalized. Otherwise, - * they may compare as "not equal" even if they are. - * - * \param P The first point to compare. This must be initialized. - * \param Q The second point to compare. This must be initialized. - * - * \return \c 0 if the points are equal. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal. - */ -int mbedtls_ecp_point_cmp(const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q); - -/** - * \brief This function imports a non-zero point from two ASCII - * strings. - * - * \param P The destination point. This must be initialized. - * \param radix The numeric base of the input. - * \param x The first affine coordinate, as a null-terminated string. - * \param y The second affine coordinate, as a null-terminated string. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_MPI_XXX error code on failure. - */ -int mbedtls_ecp_point_read_string(mbedtls_ecp_point *P, int radix, - const char *x, const char *y); - -/** - * \brief This function exports a point into unsigned binary data. - * - * \param grp The group to which the point should belong. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param P The point to export. This must be initialized. - * \param format The point format. This must be either - * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. - * (For groups without these formats, this parameter is - * ignored. But it still has to be either of the above - * values.) - * \param olen The address at which to store the length of - * the output in Bytes. This must not be \c NULL. - * \param buf The output buffer. This must be a writable buffer - * of length \p buflen Bytes. - * \param buflen The length of the output buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer - * is too small to hold the point. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format - * or the export for the given group is not implemented. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_point_write_binary(const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *P, - int format, size_t *olen, - unsigned char *buf, size_t buflen); - -/** - * \brief This function imports a point from unsigned binary data. - * - * \note This function does not check that the point actually - * belongs to the given group, see mbedtls_ecp_check_pubkey() - * for that. - * - * \note For compressed points, see #MBEDTLS_ECP_PF_COMPRESSED for - * limitations. - * - * \param grp The group to which the point should belong. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param P The destination context to import the point to. - * This must be initialized. - * \param buf The input buffer. This must be a readable buffer - * of length \p ilen Bytes. - * \param ilen The length of the input buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the - * given group is not implemented. - */ -int mbedtls_ecp_point_read_binary(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *P, - const unsigned char *buf, size_t ilen); - -/** - * \brief This function imports a point from a TLS ECPoint record. - * - * \note On function return, \p *buf is updated to point immediately - * after the ECPoint record. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The destination point. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the buffer. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization - * failure. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - */ -int mbedtls_ecp_tls_read_point(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char **buf, size_t len); - -/** - * \brief This function exports a point as a TLS ECPoint record - * defined in RFC 4492, Section 5.4. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The point to be exported. This must be initialized. - * \param format The point format to use. This must be either - * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. - * \param olen The address at which to store the length in Bytes - * of the data written. - * \param buf The target buffer. This must be a writable buffer of - * length \p blen Bytes. - * \param blen The length of the target buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer - * is too small to hold the exported point. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_write_point(const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt, - int format, size_t *olen, - unsigned char *buf, size_t blen); - -/** - * \brief This function sets up an ECP group context - * from a standardized set of domain parameters. - * - * \note The index should be a value of the NamedCurve enum, - * as defined in RFC-4492: Elliptic Curve Cryptography - * (ECC) Cipher Suites for Transport Layer Security (TLS), - * usually in the form of an \c MBEDTLS_ECP_DP_XXX macro. - * - * \param grp The group context to setup. This must be initialized. - * \param id The identifier of the domain parameter set to load. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't - * correspond to a known group. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id); - -/** - * \brief This function sets up an ECP group context from a TLS - * ECParameters record as defined in RFC 4492, Section 5.4. - * - * \note The read pointer \p buf is updated to point right after - * the ECParameters record on exit. - * - * \param grp The group context to setup. This must be initialized. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the input buffer \c *buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognized. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_read_group(mbedtls_ecp_group *grp, - const unsigned char **buf, size_t len); - -/** - * \brief This function extracts an elliptic curve group ID from a - * TLS ECParameters record as defined in RFC 4492, Section 5.4. - * - * \note The read pointer \p buf is updated to point right after - * the ECParameters record on exit. - * - * \param grp The address at which to store the group id. - * This must not be \c NULL. - * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the input buffer \c *buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognized. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_read_group_id(mbedtls_ecp_group_id *grp, - const unsigned char **buf, - size_t len); -/** - * \brief This function exports an elliptic curve as a TLS - * ECParameters record as defined in RFC 4492, Section 5.4. - * - * \param grp The ECP group to be exported. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param olen The address at which to store the number of Bytes written. - * This must not be \c NULL. - * \param buf The buffer to write to. This must be a writable buffer - * of length \p blen Bytes. - * \param blen The length of the output buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output - * buffer is too small to hold the exported group. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_tls_write_group(const mbedtls_ecp_group *grp, - size_t *olen, - unsigned char *buf, size_t blen); - -/** - * \brief This function performs a scalar multiplication of a point - * by an integer: \p R = \p m * \p P. - * - * It is not thread-safe to use same group in multiple threads. - * - * \note To prevent timing attacks, this function - * executes the exact same sequence of base-field - * operations for any valid \p m. It avoids any if-branch or - * array index depending on the value of \p m. It also uses - * \p f_rng to randomize some intermediate results. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply. This must be initialized. - * \param P The point to multiply. This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c - * NULL if \p f_rng doesn't need a context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private - * key, or \p P is not a valid public key. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** - * \brief This function performs multiplication of a point by - * an integer: \p R = \p m * \p P in a restartable way. - * - * \see mbedtls_ecp_mul() - * - * \note This function does the same as \c mbedtls_ecp_mul(), but - * it can return early and restart according to the limit set - * with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply. This must be initialized. - * \param P The point to multiply. This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c - * NULL if \p f_rng doesn't need a context. - * \param rs_ctx The restart context (NULL disables restart). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private - * key, or \p P is not a valid public key. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - mbedtls_f_rng_t *f_rng, void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx); - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -/** - * \brief This function checks if domain parameter A of the curve is - * \c -3. - * - * \note This function is only defined for short Weierstrass curves. - * It may not be included in builds without any short - * Weierstrass curve. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * - * \return \c 1 if A = -3. - * \return \c 0 Otherwise. - */ -static inline int mbedtls_ecp_group_a_is_minus_3(const mbedtls_ecp_group *grp) -{ - return grp->A.MBEDTLS_PRIVATE(p) == NULL; -} - -/** - * \brief This function performs multiplication and addition of two - * points by integers: \p R = \p m * \p P + \p n * \p Q - * - * It is not thread-safe to use same group in multiple threads. - * - * \note In contrast to mbedtls_ecp_mul(), this function does not - * guarantee a constant execution flow and timing. - * - * \note This function is only defined for short Weierstrass curves. - * It may not be included in builds without any short - * Weierstrass curve. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply \p P. - * This must be initialized. - * \param P The point to multiply by \p m. This must be initialized. - * \param n The integer by which to multiply \p Q. - * This must be initialized. - * \param Q The point to be multiplied by \p n. - * This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not - * valid private keys, or \p P or \p Q are not valid public - * keys. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not - * designate a short Weierstrass curve. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q); - -/** - * \brief This function performs multiplication and addition of two - * points by integers: \p R = \p m * \p P + \p n * \p Q in a - * restartable way. - * - * \see \c mbedtls_ecp_muladd() - * - * \note This function works the same as \c mbedtls_ecp_muladd(), - * but it can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \note This function is only defined for short Weierstrass curves. - * It may not be included in builds without any short - * Weierstrass curve. - * - * \param grp The ECP group to use. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param R The point in which to store the result of the calculation. - * This must be initialized. - * \param m The integer by which to multiply \p P. - * This must be initialized. - * \param P The point to multiply by \p m. This must be initialized. - * \param n The integer by which to multiply \p Q. - * This must be initialized. - * \param Q The point to be multiplied by \p n. - * This must be initialized. - * \param rs_ctx The restart context (NULL disables restart). - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not - * valid private keys, or \p P or \p Q are not valid public - * keys. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not - * designate a short Weierstrass curve. - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_muladd_restartable( - mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q, - mbedtls_ecp_restart_ctx *rs_ctx); -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -/** - * \brief This function checks that a point is a valid public key - * on this curve. - * - * It only checks that the point is non-zero, has - * valid coordinates and lies on the curve. It does not verify - * that it is indeed a multiple of \c G. This additional - * check is computationally more expensive, is not required - * by standards, and should not be necessary if the group - * used has a small cofactor. In particular, it is useless for - * the NIST groups which all have a cofactor of 1. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure, to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group the point should belong to. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param pt The point to check. This must be initialized. - * - * \return \c 0 if the point is a valid public key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not - * a valid public key for the given curve. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt); - -/** - * \brief This function checks that an \c mbedtls_mpi is a - * valid private key for this curve. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group the private key should belong to. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The integer to check. This must be initialized. - * - * \return \c 0 if the point is a valid private key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid - * private key for the given curve. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp, - const mbedtls_mpi *d); - -/** - * \brief This function generates a private key. - * - * \param grp The ECP group to generate a private key for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The destination MPI (secret part). This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp, - mbedtls_mpi *d, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function generates a keypair with a configurable base - * point. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group to generate a key pair for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param G The base point to use. This must be initialized - * and belong to \p grp. It replaces the default base - * point \c grp->G used by mbedtls_ecp_gen_keypair(). - * \param d The destination MPI (secret part). - * This must be initialized. - * \param Q The destination point (public part). - * This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function generates an ECP keypair. - * - * \note This function uses bare components rather than an - * ::mbedtls_ecp_keypair structure to ease use with other - * structures, such as ::mbedtls_ecdh_context or - * ::mbedtls_ecdsa_context. - * - * \param grp The ECP group to generate a key pair for. - * This must be initialized and have group parameters - * set, for example through mbedtls_ecp_group_load(). - * \param d The destination MPI (secret part). - * This must be initialized. - * \param Q The destination point (public part). - * This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d, - mbedtls_ecp_point *Q, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief This function generates an ECP key. - * - * \param grp_id The ECP group identifier. - * \param key The destination key. This must be initialized. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code - * on failure. - */ -int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** \brief Set the public key in a key pair object. - * - * \note This function does not check that the point actually - * belongs to the given group. Call mbedtls_ecp_check_pubkey() - * on \p Q before calling this function to check that. - * - * \note This function does not check that the public key matches - * the private key that is already in \p key, if any. - * To check the consistency of the resulting key pair object, - * call mbedtls_ecp_check_pub_priv() after setting both - * the public key and the private key. - * - * \param grp_id The ECP group identifier. - * \param key The key pair object. It must be initialized. - * If its group has already been set, it must match \p grp_id. - * If its group has not been set, it will be set to \p grp_id. - * If the public key has already been set, it is overwritten. - * \param Q The public key to copy. This must be a point on the - * curve indicated by \p grp_id. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p key does not - * match \p grp_id. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for - * the group is not implemented. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id, - mbedtls_ecp_keypair *key, - const mbedtls_ecp_point *Q); - -/** - * \brief This function reads an elliptic curve private key. - * - * \note This function does not set the public key in the - * key pair object. Without a public key, the key pair object - * cannot be used with operations that require the public key. - * Call mbedtls_ecp_keypair_calc_public() to set the public - * key from the private key. Alternatively, you can call - * mbedtls_ecp_set_public_key() to set the public key part, - * and then optionally mbedtls_ecp_check_pub_priv() to check - * that the private and public parts are consistent. - * - * \note If a public key has already been set in the key pair - * object, this function does not check that it is consistent - * with the private key. Call mbedtls_ecp_check_pub_priv() - * after setting both the public key and the private key - * to make that check. - * - * \param grp_id The ECP group identifier. - * \param key The destination key. - * \param buf The buffer containing the binary representation of the - * key. (Big endian integer for Weierstrass curves, byte - * string for Montgomery curves.) - * \param buflen The length of the buffer in bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is - * invalid. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for - * the group is not implemented. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - const unsigned char *buf, size_t buflen); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief This function exports an elliptic curve private key. - * - * \deprecated Note that although this function accepts an output - * buffer that is smaller or larger than the key, most key - * import interfaces require the output to have exactly - * key's nominal length. It is generally simplest to - * pass the key's nominal length as \c buflen, after - * checking that the output buffer is large enough. - * See the description of the \p buflen parameter for - * how to calculate the nominal length. - * To avoid this difficulty, use mbedtls_ecp_write_key_ext() - * instead. - * mbedtls_ecp_write_key() is deprecated and will be - * removed in a future version of the library. - * - * \note If the private key was not set in \p key, - * the output is unspecified. Future versions - * may return an error in that case. - * - * \param key The private key. - * \param buf The output buffer for containing the binary representation - * of the key. - * For Weierstrass curves, this is the big-endian - * representation, padded with null bytes at the beginning - * to reach \p buflen bytes. - * For Montgomery curves, this is the standard byte string - * representation (which is little-endian), padded with - * null bytes at the end to reach \p buflen bytes. - * \param buflen The total length of the buffer in bytes. - * The length of the output is - * (`grp->nbits` + 7) / 8 bytes - * where `grp->nbits` is the private key size in bits. - * For Weierstrass keys, if the output buffer is smaller, - * leading zeros are trimmed to fit if possible. For - * Montgomery keys, the output buffer must always be large - * enough for the nominal length. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL or - * #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the \p key - * representation is larger than the available space in \p buf. - * \return Another negative error code on different kinds of failure. - */ -int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, - unsigned char *buf, size_t buflen); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief This function exports an elliptic curve private key. - * - * \param key The private key. - * \param olen On success, the length of the private key. - * This is always (`grp->nbits` + 7) / 8 bytes - * where `grp->nbits` is the private key size in bits. - * \param buf The output buffer for containing the binary representation - * of the key. - * \param buflen The total length of the buffer in bytes. - * #MBEDTLS_ECP_MAX_BYTES is always sufficient. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key - * representation is larger than the available space in \p buf. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if no private key is - * set in \p key. - * \return Another negative error code on different kinds of failure. - */ -int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key, - size_t *olen, unsigned char *buf, size_t buflen); - -/** - * \brief This function exports an elliptic curve public key. - * - * \note If the public key was not set in \p key, - * the output is unspecified. Future versions - * may return an error in that case. - * - * \param key The public key. - * \param format The point format. This must be either - * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. - * (For groups without these formats, this parameter is - * ignored. But it still has to be either of the above - * values.) - * \param olen The address at which to store the length of - * the output in Bytes. This must not be \c NULL. - * \param buf The output buffer. This must be a writable buffer - * of length \p buflen Bytes. - * \param buflen The length of the output buffer \p buf in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer - * is too small to hold the point. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format - * or the export for the given group is not implemented. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key, - int format, size_t *olen, - unsigned char *buf, size_t buflen); - -/** - * \brief This function checks that the keypair objects - * \p pub and \p prv have the same group and the - * same public point, and that the private key in - * \p prv is consistent with the public key. - * - * \param pub The keypair structure holding the public key. This - * must be initialized. If it contains a private key, that - * part is ignored. - * \param prv The keypair structure holding the full keypair. - * This must be initialized. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c - * NULL if \p f_rng doesn't need a context. - * - * \return \c 0 on success, meaning that the keys are valid and match. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match. - * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX - * error code on calculation failure. - */ -int mbedtls_ecp_check_pub_priv( - const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** \brief Calculate the public key from a private key in a key pair. - * - * \param key A keypair structure. It must have a private key set. - * If the public key is set, it will be overwritten. - * \param f_rng The RNG function. This must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c - * NULL if \p f_rng doesn't need a context. - * - * \return \c 0 on success. The key pair object can be used for - * operations that require the public key. - * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX - * error code on calculation failure. - */ -int mbedtls_ecp_keypair_calc_public( - mbedtls_ecp_keypair *key, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** \brief Query the group that a key pair belongs to. - * - * \param key The key pair to query. - * - * \return The group ID for the group registered in the key pair - * object. - * This is \c MBEDTLS_ECP_DP_NONE if no group has been set - * in the key pair object. - */ -mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id( - const mbedtls_ecp_keypair *key); - -/** - * \brief This function exports generic key-pair parameters. - * - * Each of the output parameters can be a null pointer - * if you do not need that parameter. - * - * \note If the private key or the public key was not set in \p key, - * the corresponding output is unspecified. Future versions - * may return an error in that case. - * - * \param key The key pair to export from. - * \param grp Slot for exported ECP group. - * It must either be null or point to an initialized ECP group. - * \param d Slot for the exported secret value. - * It must either be null or point to an initialized mpi. - * \param Q Slot for the exported public value. - * It must either be null or point to an initialized ECP point. - * - * \return \c 0 on success, - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if key id doesn't - * correspond to a known group. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The ECP checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_ecp_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* ecp.h */ diff --git a/vendor/mbedtls/include/mbedtls/entropy.h b/vendor/mbedtls/include/mbedtls/entropy.h deleted file mode 100644 index 6c64e3e4e..000000000 --- a/vendor/mbedtls/include/mbedtls/entropy.h +++ /dev/null @@ -1,274 +0,0 @@ -/** - * \file entropy.h - * - * \brief Entropy accumulator implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_ENTROPY_H -#define MBEDTLS_ENTROPY_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include - -#include "md.h" - -#if (defined(MBEDTLS_MD_CAN_SHA512) || defined(PSA_WANT_ALG_SHA_512)) && \ - !defined(MBEDTLS_ENTROPY_FORCE_SHA256) -#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR -#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA512 -#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ -#else -#if (defined(MBEDTLS_MD_CAN_SHA256) || defined(PSA_WANT_ALG_SHA_256)) -#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR -#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA256 -#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ -#endif -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - - -/** Critical entropy source failure. */ -#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C -/** No more sources can be added. */ -#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E -/** No sources have been added to poll. */ -#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 -/** No strong sources have been added to poll. */ -#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D -/** Read/write error in file. */ -#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES) -#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -#endif - -#if !defined(MBEDTLS_ENTROPY_MAX_GATHER) -#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -#endif - -/** \} name SECTION: Module settings */ - -#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ -#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES - -#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ -#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Entropy poll callback pointer - * - * \param data Callback-specific data pointer - * \param output Data to fill - * \param len Maximum size to provide - * \param olen The actual amount of bytes put into the buffer (Can be 0) - * - * \return 0 if no critical failures occurred, - * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise - */ -typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len, - size_t *olen); - -/** - * \brief Entropy source state - */ -typedef struct mbedtls_entropy_source_state { - mbedtls_entropy_f_source_ptr MBEDTLS_PRIVATE(f_source); /**< The entropy source callback */ - void *MBEDTLS_PRIVATE(p_source); /**< The callback data pointer */ - size_t MBEDTLS_PRIVATE(size); /**< Amount received in bytes */ - size_t MBEDTLS_PRIVATE(threshold); /**< Minimum bytes required before release */ - int MBEDTLS_PRIVATE(strong); /**< Is the source strong? */ -} -mbedtls_entropy_source_state; - -/** - * \brief Entropy context structure - */ -typedef struct mbedtls_entropy_context { - mbedtls_md_context_t MBEDTLS_PRIVATE(accumulator); - int MBEDTLS_PRIVATE(accumulator_started); /* 0 after init. - * 1 after the first update. - * -1 after free. */ - int MBEDTLS_PRIVATE(source_count); /* Number of entries used in source. */ - mbedtls_entropy_source_state MBEDTLS_PRIVATE(source)[MBEDTLS_ENTROPY_MAX_SOURCES]; -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); /*!< mutex */ -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) - int MBEDTLS_PRIVATE(initial_entropy_run); -#endif -} -mbedtls_entropy_context; - -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) -/** - * \brief Platform-specific entropy poll callback - */ -int mbedtls_platform_entropy_poll(void *data, - unsigned char *output, size_t len, size_t *olen); -#endif - -/** - * \brief Initialize the context - * - * \param ctx Entropy context to initialize - */ -void mbedtls_entropy_init(mbedtls_entropy_context *ctx); - -/** - * \brief Free the data in the context - * - * \param ctx Entropy context to free - */ -void mbedtls_entropy_free(mbedtls_entropy_context *ctx); - -/** - * \brief Adds an entropy source to poll - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param ctx Entropy context - * \param f_source Entropy function - * \param p_source Function data - * \param threshold Minimum required from source before entropy is released - * ( with mbedtls_entropy_func() ) (in bytes) - * \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or - * MBEDTLS_ENTROPY_SOURCE_WEAK. - * At least one strong source needs to be added. - * Weaker sources (such as the cycle counter) can be used as - * a complement. - * - * \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES - */ -int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx, - mbedtls_entropy_f_source_ptr f_source, void *p_source, - size_t threshold, int strong); - -/** - * \brief Trigger an extra gather poll for the accumulator - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param ctx Entropy context - * - * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_gather(mbedtls_entropy_context *ctx); - -/** - * \brief Retrieve entropy from the accumulator - * (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE) - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data Entropy context - * \param output Buffer to fill - * \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE - * - * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_func(void *data, unsigned char *output, size_t len); - -/** - * \brief Add data to the accumulator manually - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param ctx Entropy context - * \param data Data to add - * \param len Length of data - * - * \return 0 if successful - */ -int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx, - const unsigned char *data, size_t len); - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -/** - * \brief Trigger an update of the seed file in NV by using the - * current entropy pool. - * - * \param ctx Entropy context - * - * \return 0 if successful - */ -int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx); -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Write a seed file - * - * \param ctx Entropy context - * \param path Name of the file - * - * \return 0 if successful, - * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or - * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path); - -/** - * \brief Read and update a seed file. Seed is added to this - * instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are - * read from the seed file. The rest is ignored. - * - * \param ctx Entropy context - * \param path Name of the file - * - * \return 0 if successful, - * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, - * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED - */ -int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path); -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * This module self-test also calls the entropy self-test, - * mbedtls_entropy_source_self_test(); - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_entropy_self_test(int verbose); - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) -/** - * \brief Checkup routine - * - * Verifies the integrity of the hardware entropy source - * provided by the function 'mbedtls_hardware_poll()'. - * - * Note this is the only hardware entropy source that is known - * at link time, and other entropy sources configured - * dynamically at runtime by the function - * mbedtls_entropy_add_source() will not be tested. - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_entropy_source_self_test(int verbose); -#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* entropy.h */ diff --git a/vendor/mbedtls/include/mbedtls/error.h b/vendor/mbedtls/include/mbedtls/error.h deleted file mode 100644 index 635f7cd84..000000000 --- a/vendor/mbedtls/include/mbedtls/error.h +++ /dev/null @@ -1,201 +0,0 @@ -/** - * \file error.h - * - * \brief Error to string translation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_ERROR_H -#define MBEDTLS_ERROR_H - -#include "mbedtls/build_info.h" - -#include - -/** - * Error code layout. - * - * Currently we try to keep all error codes within the negative space of 16 - * bits signed integers to support all platforms (-0x0001 - -0x7FFF). In - * addition we'd like to give two layers of information on the error if - * possible. - * - * For that purpose the error codes are segmented in the following manner: - * - * 16 bit error code bit-segmentation - * - * 1 bit - Unused (sign bit) - * 3 bits - High level module ID - * 5 bits - Module-dependent error code - * 7 bits - Low level module errors - * - * For historical reasons, low-level error codes are divided in even and odd, - * even codes were assigned first, and -1 is reserved for other errors. - * - * Low-level module errors (0x0002-0x007E, 0x0001-0x007F) - * - * Module Nr Codes assigned - * ERROR 2 0x006E 0x0001 - * MPI 7 0x0002-0x0010 - * GCM 3 0x0012-0x0016 0x0013-0x0013 - * THREADING 3 0x001A-0x001E - * AES 5 0x0020-0x0022 0x0021-0x0025 - * CAMELLIA 3 0x0024-0x0026 0x0027-0x0027 - * BASE64 2 0x002A-0x002C - * OID 1 0x002E-0x002E 0x000B-0x000B - * PADLOCK 1 0x0030-0x0030 - * DES 2 0x0032-0x0032 0x0033-0x0033 - * CTR_DBRG 4 0x0034-0x003A - * ENTROPY 3 0x003C-0x0040 0x003D-0x003F - * NET 13 0x0042-0x0052 0x0043-0x0049 - * ARIA 4 0x0058-0x005E - * ASN1 7 0x0060-0x006C - * CMAC 1 0x007A-0x007A - * PBKDF2 1 0x007C-0x007C - * HMAC_DRBG 4 0x0003-0x0009 - * CCM 3 0x000D-0x0011 - * MD5 1 0x002F-0x002F - * RIPEMD160 1 0x0031-0x0031 - * SHA1 1 0x0035-0x0035 0x0073-0x0073 - * SHA256 1 0x0037-0x0037 0x0074-0x0074 - * SHA512 1 0x0039-0x0039 0x0075-0x0075 - * SHA-3 1 0x0076-0x0076 - * CHACHA20 3 0x0051-0x0055 - * POLY1305 3 0x0057-0x005B - * CHACHAPOLY 2 0x0054-0x0056 - * PLATFORM 2 0x0070-0x0072 - * LMS 5 0x0011-0x0019 - * - * High-level module nr (3 bits - 0x0...-0x7...) - * Name ID Nr of Errors - * PEM 1 9 - * PKCS#12 1 4 (Started from top) - * X509 2 20 - * PKCS5 2 4 (Started from top) - * DHM 3 11 - * PK 3 15 (Started from top) - * RSA 4 11 - * ECP 4 10 (Started from top) - * MD 5 5 - * HKDF 5 1 (Started from top) - * PKCS7 5 12 (Started from 0x5300) - * SSL 5 3 (Started from 0x5F00) - * CIPHER 6 8 (Started from 0x6080) - * SSL 6 22 (Started from top, plus 0x6000) - * SSL 7 20 (Started from 0x7000, gaps at - * 0x7380, 0x7900-0x7980, 0x7A80-0x7E80) - * - * Module dependent error code (5 bits 0x.00.-0x.F8.) - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** Generic error */ -#define MBEDTLS_ERR_ERROR_GENERIC_ERROR -0x0001 -/** This is a bug in the library */ -#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E - -/** Hardware accelerator failed */ -#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 -/** The requested feature is not supported by the platform */ -#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 - -/** - * \brief Combines a high-level and low-level error code together. - * - * Wrapper macro for mbedtls_error_add(). See that function for - * more details. - */ -#define MBEDTLS_ERROR_ADD(high, low) \ - mbedtls_error_add(high, low, __FILE__, __LINE__) - -#if defined(MBEDTLS_TEST_HOOKS) -/** - * \brief Testing hook called before adding/combining two error codes together. - * Only used when invasive testing is enabled via MBEDTLS_TEST_HOOKS. - */ -extern void (*mbedtls_test_hook_error_add)(int, int, const char *, int); -#endif - -/** - * \brief Combines a high-level and low-level error code together. - * - * This function can be called directly however it is usually - * called via the #MBEDTLS_ERROR_ADD macro. - * - * While a value of zero is not a negative error code, it is still an - * error code (that denotes success) and can be combined with both a - * negative error code or another value of zero. - * - * \note When invasive testing is enabled via #MBEDTLS_TEST_HOOKS, also try to - * call \link mbedtls_test_hook_error_add \endlink. - * - * \param high high-level error code. See error.h for more details. - * \param low low-level error code. See error.h for more details. - * \param file file where this error code addition occurred. - * \param line line where this error code addition occurred. - */ -static inline int mbedtls_error_add(int high, int low, - const char *file, int line) -{ -#if defined(MBEDTLS_TEST_HOOKS) - if (*mbedtls_test_hook_error_add != NULL) { - (*mbedtls_test_hook_error_add)(high, low, file, line); - } -#endif - (void) file; - (void) line; - - return high + low; -} - -/** - * \brief Translate an Mbed TLS error code into a string representation. - * The result is truncated if necessary and always includes a - * terminating null byte. - * - * \param errnum error code - * \param buffer buffer to place representation in - * \param buflen length of the buffer - */ -void mbedtls_strerror(int errnum, char *buffer, size_t buflen); - -/** - * \brief Translate the high-level part of an Mbed TLS error code into a string - * representation. - * - * This function returns a const pointer to an un-modifiable string. The caller - * must not try to modify the string. It is intended to be used mostly for - * logging purposes. - * - * \param error_code error code - * - * \return The string representation of the error code, or \c NULL if the error - * code is unknown. - */ -const char *mbedtls_high_level_strerr(int error_code); - -/** - * \brief Translate the low-level part of an Mbed TLS error code into a string - * representation. - * - * This function returns a const pointer to an un-modifiable string. The caller - * must not try to modify the string. It is intended to be used mostly for - * logging purposes. - * - * \param error_code error code - * - * \return The string representation of the error code, or \c NULL if the error - * code is unknown. - */ -const char *mbedtls_low_level_strerr(int error_code); - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ diff --git a/vendor/mbedtls/include/mbedtls/gcm.h b/vendor/mbedtls/include/mbedtls/gcm.h deleted file mode 100644 index 390ed4c6d..000000000 --- a/vendor/mbedtls/include/mbedtls/gcm.h +++ /dev/null @@ -1,387 +0,0 @@ -/** - * \file gcm.h - * - * \brief This file contains GCM definitions and functions. - * - * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined - * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation - * (GCM), Natl. Inst. Stand. Technol. - * - * For more information on GCM, see NIST SP 800-38D: Recommendation for - * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_GCM_H -#define MBEDTLS_GCM_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/cipher.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_C) -#include "mbedtls/block_cipher.h" -#endif - -#include - -#define MBEDTLS_GCM_ENCRYPT 1 -#define MBEDTLS_GCM_DECRYPT 0 - -/** Authenticated decryption failed. */ -#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 -/** An output buffer is too small. */ -#define MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL -0x0016 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_GCM_ALT) - -#if defined(MBEDTLS_GCM_LARGE_TABLE) -#define MBEDTLS_GCM_HTABLE_SIZE 256 -#else -#define MBEDTLS_GCM_HTABLE_SIZE 16 -#endif - -/** - * \brief The GCM context structure. - */ -typedef struct mbedtls_gcm_context { -#if defined(MBEDTLS_BLOCK_CIPHER_C) - mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */ -#else - mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ -#endif - uint64_t MBEDTLS_PRIVATE(H)[MBEDTLS_GCM_HTABLE_SIZE][2]; /*!< Precalculated HTable. */ - uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */ - uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */ - unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */ - unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */ - unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */ - unsigned char MBEDTLS_PRIVATE(mode); /*!< The operation to perform: - #MBEDTLS_GCM_ENCRYPT or - #MBEDTLS_GCM_DECRYPT. */ - unsigned char MBEDTLS_PRIVATE(acceleration); /*!< The acceleration to use. */ -} -mbedtls_gcm_context; - -#else /* !MBEDTLS_GCM_ALT */ -#include "gcm_alt.h" -#endif /* !MBEDTLS_GCM_ALT */ - -/** - * \brief This function initializes the specified GCM context, - * to make references valid, and prepares the context - * for mbedtls_gcm_setkey() or mbedtls_gcm_free(). - * - * The function does not bind the GCM context to a particular - * cipher, nor set the key. For this purpose, use - * mbedtls_gcm_setkey(). - * - * \param ctx The GCM context to initialize. This must not be \c NULL. - */ -void mbedtls_gcm_init(mbedtls_gcm_context *ctx); - -/** - * \brief This function associates a GCM context with a - * cipher algorithm and a key. - * - * \param ctx The GCM context. This must be initialized. - * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. This must be a readable buffer of at - * least \p keybits bits. - * \param keybits The key size in bits. Valid options are: - *
  • 128 bits
  • - *
  • 192 bits
  • - *
  • 256 bits
- * - * \return \c 0 on success. - * \return A cipher-specific error code on failure. - */ -int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits); - -/** - * \brief This function performs GCM encryption or decryption of a buffer. - * - * \note The output buffer \p output can be the same as the input - * buffer \p input. If \p output is greater than \p input, they - * cannot overlap. - * - * \warning When this function performs a decryption, it outputs the - * authentication tag and does not verify that the data is - * authentic. You should use this function to perform encryption - * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. - * - * \param ctx The GCM context to use for encryption or decryption. This - * must be initialized. - * \param mode The operation to perform: - * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. - * The ciphertext is written to \p output and the - * authentication tag is written to \p tag. - * - #MBEDTLS_GCM_DECRYPT to perform decryption. - * The plaintext is written to \p output and the - * authentication tag is written to \p tag. - * Note that this mode is not recommended, because it does - * not verify the authenticity of the data. For this reason, - * you should use mbedtls_gcm_auth_decrypt() instead of - * calling this function in decryption mode. - * \param length The length of the input data, which is equal to the length - * of the output data. - * \param iv The initialization vector. This must be a readable buffer of - * at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. - * \param add_len The length of the additional data. - * \param input The buffer holding the input data. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size in Bytes. - * \param output The buffer for holding the output data. If \p length is greater - * than zero, this must be a writable buffer of at least that - * size in Bytes. - * \param tag_len The length of the tag to generate. - * \param tag The buffer for holding the tag. This must be a writable - * buffer of at least \p tag_len Bytes. - * - * \return \c 0 if the encryption or decryption was performed - * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, - * this does not indicate that the data is authentic. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are - * not valid or a cipher-specific error code if the encryption - * or decryption failed. - */ -int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag); - -/** - * \brief This function performs a GCM authenticated decryption of a - * buffer. - * - * \note The output buffer \p output can be the same as the input - * buffer \p input. If \p output is greater than \p input, they - * cannot overlap. Implementations which require - * MBEDTLS_GCM_ALT to be enabled may not provide support for - * overlapping buffers. - * - * \param ctx The GCM context. This must be initialized. - * \param length The length of the ciphertext to decrypt, which is also - * the length of the decrypted plaintext. - * \param iv The initialization vector. This must be a readable buffer - * of at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * \param add The buffer holding the additional data. This must be of at - * least that size in Bytes. - * \param add_len The length of the additional data. - * \param tag The buffer holding the tag to verify. This must be a - * readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to verify. - * \param input The buffer holding the ciphertext. If \p length is greater - * than zero, this must be a readable buffer of at least that - * size. - * \param output The buffer for holding the decrypted plaintext. If \p length - * is greater than zero, this must be a writable buffer of at - * least that size. - * - * \return \c 0 if successful and authenticated. - * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are - * not valid or a cipher-specific error code if the decryption - * failed. - */ -int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function starts a GCM encryption or decryption - * operation. - * - * \param ctx The GCM context. This must be initialized. - * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or - * #MBEDTLS_GCM_DECRYPT. - * \param iv The initialization vector. This must be a readable buffer of - * at least \p iv_len Bytes. - * \param iv_len The length of the IV. - * - * \return \c 0 on success. - */ -int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len); - -/** - * \brief This function feeds an input buffer as associated data - * (authenticated but not encrypted data) in a GCM - * encryption or decryption operation. - * - * Call this function after mbedtls_gcm_starts() to pass - * the associated data. If the associated data is empty, - * you do not need to call this function. You may not - * call this function after calling mbedtls_cipher_update(). - * - * \param ctx The GCM context. This must have been started with - * mbedtls_gcm_starts() and must not have yet received - * any input with mbedtls_gcm_update(). - * \param add The buffer holding the additional data, or \c NULL - * if \p add_len is \c 0. - * \param add_len The length of the additional data. If \c 0, - * \p add may be \c NULL. - * - * \return \c 0 on success. - */ -int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, - const unsigned char *add, - size_t add_len); - -/** - * \brief This function feeds an input buffer into an ongoing GCM - * encryption or decryption operation. - * - * You may call this function zero, one or more times - * to pass successive parts of the input: the plaintext to - * encrypt, or the ciphertext (not including the tag) to - * decrypt. After the last part of the input, call - * mbedtls_gcm_finish(). - * - * This function may produce output in one of the following - * ways: - * - Immediate output: the output length is always equal - * to the input length. - * - Buffered output: the output consists of a whole number - * of 16-byte blocks. If the total input length so far - * (not including associated data) is 16 \* *B* + *A* - * with *A* < 16 then the total output length is 16 \* *B*. - * - * In particular: - * - It is always correct to call this function with - * \p output_size >= \p input_length + 15. - * - If \p input_length is a multiple of 16 for all the calls - * to this function during an operation, then it is - * correct to use \p output_size = \p input_length. - * - * \note The output buffer \p output can be the same as the input - * buffer \p input. If \p output is greater than \p input, they - * cannot overlap. Implementations which require - * MBEDTLS_GCM_ALT to be enabled may not provide support for - * overlapping buffers. - * - * \param ctx The GCM context. This must be initialized. - * \param input The buffer holding the input data. If \p input_length - * is greater than zero, this must be a readable buffer - * of at least \p input_length bytes. - * \param input_length The length of the input data in bytes. - * \param output The buffer for the output data. If \p output_size - * is greater than zero, this must be a writable buffer of - * of at least \p output_size bytes. - * \param output_size The size of the output buffer in bytes. - * See the function description regarding the output size. - * \param output_length On success, \p *output_length contains the actual - * length of the output written in \p output. - * On failure, the content of \p *output_length is - * unspecified. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure: - * total input length too long, - * unsupported input/output buffer overlap detected, - * or \p output_size too small. - */ -int mbedtls_gcm_update(mbedtls_gcm_context *ctx, - const unsigned char *input, size_t input_length, - unsigned char *output, size_t output_size, - size_t *output_length); - -/** - * \brief This function finishes the GCM operation and generates - * the authentication tag. - * - * It wraps up the GCM stream, and generates the - * tag. The tag can have a maximum length of 16 Bytes. - * - * \param ctx The GCM context. This must be initialized. - * \param tag The buffer for holding the tag. This must be a writable - * buffer of at least \p tag_len Bytes. - * \param tag_len The length of the tag to generate. This must be at least - * four. - * \param output The buffer for the final output. - * If \p output_size is nonzero, this must be a writable - * buffer of at least \p output_size bytes. - * \param output_size The size of the \p output buffer in bytes. - * This must be large enough for the output that - * mbedtls_gcm_update() has not produced. In particular: - * - If mbedtls_gcm_update() produces immediate output, - * or if the total input size is a multiple of \c 16, - * then mbedtls_gcm_finish() never produces any output, - * so \p output_size can be \c 0. - * - \p output_size never needs to be more than \c 15. - * \param output_length On success, \p *output_length contains the actual - * length of the output written in \p output. - * On failure, the content of \p *output_length is - * unspecified. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure: - * invalid value of \p tag_len, - * or \p output_size too small. - */ -int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, - unsigned char *output, size_t output_size, - size_t *output_length, - unsigned char *tag, size_t tag_len); - -/** - * \brief This function clears a GCM context and the underlying - * cipher sub-context. - * - * \param ctx The GCM context to clear. If this is \c NULL, the call has - * no effect. Otherwise, this must be initialized. - */ -void mbedtls_gcm_free(mbedtls_gcm_context *ctx); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The GCM checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_gcm_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - - -#endif /* gcm.h */ diff --git a/vendor/mbedtls/include/mbedtls/hkdf.h b/vendor/mbedtls/include/mbedtls/hkdf.h deleted file mode 100644 index 930e93f32..000000000 --- a/vendor/mbedtls/include/mbedtls/hkdf.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * \file hkdf.h - * - * \brief This file contains the HKDF interface. - * - * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is - * specified by RFC 5869. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_HKDF_H -#define MBEDTLS_HKDF_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/md.h" - -/** - * \name HKDF Error codes - * \{ - */ -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 -/** \} name */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief This is the HMAC-based Extract-and-Expand Key Derivation Function - * (HKDF). - * - * \param md A hash function; md.size denotes the length of the hash - * function output in bytes. - * \param salt An optional salt value (a non-secret random value); - * if the salt is not provided, a string of all zeros of - * md.size length is used as the salt. - * \param salt_len The length in bytes of the optional \p salt. - * \param ikm The input keying material. - * \param ikm_len The length in bytes of \p ikm. - * \param info An optional context and application specific information - * string. This can be a zero-length string. - * \param info_len The length of \p info in bytes. - * \param okm The output keying material of \p okm_len bytes. - * \param okm_len The length of the output keying material in bytes. This - * must be less than or equal to 255 * md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf(const mbedtls_md_info_t *md, const unsigned char *salt, - size_t salt_len, const unsigned char *ikm, size_t ikm_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len); - -/** - * \brief Take the input keying material \p ikm and extract from it a - * fixed-length pseudorandom key \p prk. - * - * \warning This function should only be used if the security of it has been - * studied and established in that particular context (eg. TLS 1.3 - * key schedule). For standard HKDF security guarantees use - * \c mbedtls_hkdf instead. - * - * \param md A hash function; md.size denotes the length of the - * hash function output in bytes. - * \param salt An optional salt value (a non-secret random value); - * if the salt is not provided, a string of all zeros - * of md.size length is used as the salt. - * \param salt_len The length in bytes of the optional \p salt. - * \param ikm The input keying material. - * \param ikm_len The length in bytes of \p ikm. - * \param[out] prk A pseudorandom key of at least md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf_extract(const mbedtls_md_info_t *md, - const unsigned char *salt, size_t salt_len, - const unsigned char *ikm, size_t ikm_len, - unsigned char *prk); - -/** - * \brief Expand the supplied \p prk into several additional pseudorandom - * keys, which is the output of the HKDF. - * - * \warning This function should only be used if the security of it has been - * studied and established in that particular context (eg. TLS 1.3 - * key schedule). For standard HKDF security guarantees use - * \c mbedtls_hkdf instead. - * - * \param md A hash function; md.size denotes the length of the hash - * function output in bytes. - * \param prk A pseudorandom key of at least md.size bytes. \p prk is - * usually the output from the HKDF extract step. - * \param prk_len The length in bytes of \p prk. - * \param info An optional context and application specific information - * string. This can be a zero-length string. - * \param info_len The length of \p info in bytes. - * \param okm The output keying material of \p okm_len bytes. - * \param okm_len The length of the output keying material in bytes. This - * must be less than or equal to 255 * md.size bytes. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. - * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying - * MD layer. - */ -int mbedtls_hkdf_expand(const mbedtls_md_info_t *md, const unsigned char *prk, - size_t prk_len, const unsigned char *info, - size_t info_len, unsigned char *okm, size_t okm_len); - -#ifdef __cplusplus -} -#endif - -#endif /* hkdf.h */ diff --git a/vendor/mbedtls/include/mbedtls/hmac_drbg.h b/vendor/mbedtls/include/mbedtls/hmac_drbg.h deleted file mode 100644 index 18b1b75a6..000000000 --- a/vendor/mbedtls/include/mbedtls/hmac_drbg.h +++ /dev/null @@ -1,434 +0,0 @@ -/** - * \file hmac_drbg.h - * - * \brief The HMAC_DRBG pseudorandom generator. - * - * This module implements the HMAC_DRBG pseudorandom generator described - * in NIST SP 800-90A: Recommendation for Random Number Generation Using - * Deterministic Random Bit Generators. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_HMAC_DRBG_H -#define MBEDTLS_HMAC_DRBG_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/md.h" - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -/* - * Error codes - */ -/** Too many random requested in single call. */ -#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 -/** Input too large (Entropy + additional). */ -#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 -/** Read/write error in file. */ -#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 -/** The entropy source failed. */ -#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) -#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -#endif - -#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT) -#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -#endif - -#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST) -#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -#endif - -#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) -#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ -#endif - -/** \} name SECTION: Module settings */ - -#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ -#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * HMAC_DRBG context. - */ -typedef struct mbedtls_hmac_drbg_context { - /* Working state: the key K is not stored explicitly, - * but is implied by the HMAC context */ - mbedtls_md_context_t MBEDTLS_PRIVATE(md_ctx); /*!< HMAC context (inc. K) */ - unsigned char MBEDTLS_PRIVATE(V)[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ - int MBEDTLS_PRIVATE(reseed_counter); /*!< reseed counter */ - - /* Administrative state */ - size_t MBEDTLS_PRIVATE(entropy_len); /*!< entropy bytes grabbed on each (re)seed */ - int MBEDTLS_PRIVATE(prediction_resistance); /*!< enable prediction resistance (Automatic - reseed before every random generation) */ - int MBEDTLS_PRIVATE(reseed_interval); /*!< reseed interval */ - - /* Callbacks */ - int(*MBEDTLS_PRIVATE(f_entropy))(void *, unsigned char *, size_t); /*!< entropy function */ - void *MBEDTLS_PRIVATE(p_entropy); /*!< context for the entropy function */ - -#if defined(MBEDTLS_THREADING_C) - /* Invariant: the mutex is initialized if and only if - * md_ctx->md_info != NULL. This means that the mutex is initialized - * during the initial seeding in mbedtls_hmac_drbg_seed() or - * mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free(). - * - * Note that this invariant may change without notice. Do not rely on it - * and do not access the mutex directly in application code. - */ - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); -#endif -} mbedtls_hmac_drbg_context; - -/** - * \brief HMAC_DRBG context initialization. - * - * This function makes the context ready for mbedtls_hmac_drbg_seed(), - * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). - * - * \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL - * by default. Override this value by calling - * mbedtls_hmac_drbg_set_reseed_interval(). - * - * \param ctx HMAC_DRBG context to be initialized. - */ -void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx); - -/** - * \brief HMAC_DRBG initial seeding. - * - * Set the initial seed and set up the entropy source for future reseeds. - * - * A typical choice for the \p f_entropy and \p p_entropy parameters is - * to use the entropy module: - * - \p f_entropy is mbedtls_entropy_func(); - * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized - * with mbedtls_entropy_init() (which registers the platform's default - * entropy sources). - * - * You can provide a personalization string in addition to the - * entropy source, to make this instantiation as unique as possible. - * - * \note By default, the security strength as defined by NIST is: - * - 128 bits if \p md_info is SHA-1; - * - 192 bits if \p md_info is SHA-224; - * - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. - * Note that SHA-256 is just as efficient as SHA-224. - * The security strength can be reduced if a smaller - * entropy length is set with - * mbedtls_hmac_drbg_set_entropy_len(). - * - * \note The default entropy length is the security strength - * (converted from bits to bytes). You can override - * it by calling mbedtls_hmac_drbg_set_entropy_len(). - * - * \note During the initial seeding, this function calls - * the entropy source to obtain a nonce - * whose length is half the entropy length. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * after this function returns successfully, - * it is safe to call mbedtls_hmac_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param ctx HMAC_DRBG context to be seeded. - * \param md_info MD algorithm to use for HMAC_DRBG. - * \param f_entropy The entropy callback, taking as arguments the - * \p p_entropy context, the buffer to fill, and the - * length of the buffer. - * \p f_entropy is always called with a length that is - * less than or equal to the entropy length. - * \param p_entropy The entropy context to pass to \p f_entropy. - * \param custom The personalization string. - * This can be \c NULL, in which case the personalization - * string is empty regardless of the value of \p len. - * \param len The length of the personalization string. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT - * and also at most - * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len * 3 / 2 - * where \c entropy_len is the entropy length - * described above. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is - * invalid. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough - * memory to allocate context data. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if the call to \p f_entropy failed. - */ -int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t *md_info, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len); - -/** - * \brief Initialisation of simplified HMAC_DRBG (never reseeds). - * - * This function is meant for use in algorithms that need a pseudorandom - * input such as deterministic ECDSA. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * after this function returns successfully, - * it is safe to call mbedtls_hmac_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param ctx HMAC_DRBG context to be initialised. - * \param md_info MD algorithm to use for HMAC_DRBG. - * \param data Concatenation of the initial entropy string and - * the additional data. - * \param data_len Length of \p data in bytes. - * - * \return \c 0 if successful. or - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is - * invalid. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough - * memory to allocate context data. - */ -int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t *md_info, - const unsigned char *data, size_t data_len); - -/** - * \brief This function turns prediction resistance on or off. - * The default value is off. - * - * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_hmac_drbg_random_with_add() - * or mbedtls_hmac_drbg_random(). - * Only use this if your entropy source has sufficient - * throughput. - * - * \param ctx The HMAC_DRBG context. - * \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF. - */ -void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx, - int resistance); - -/** - * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. - * - * See the documentation of mbedtls_hmac_drbg_seed() for the default value. - * - * \param ctx The HMAC_DRBG context. - * \param len The amount of entropy to grab, in bytes. - */ -void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, - size_t len); - -/** - * \brief Set the reseed interval. - * - * The reseed interval is the number of calls to mbedtls_hmac_drbg_random() - * or mbedtls_hmac_drbg_random_with_add() after which the entropy function - * is called again. - * - * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL. - * - * \param ctx The HMAC_DRBG context. - * \param interval The reseed interval. - */ -void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, - int interval); - -/** - * \brief This function updates the state of the HMAC_DRBG context. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The HMAC_DRBG context. - * \param additional The data to update the state with. - * If this is \c NULL, there is no additional data. - * \param add_len Length of \p additional in bytes. - * Unused if \p additional is \c NULL. - * - * \return \c 0 on success, or an error from the underlying - * hash calculation. - */ -int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t add_len); - -/** - * \brief This function reseeds the HMAC_DRBG context, that is - * extracts data from the entropy source. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param ctx The HMAC_DRBG context. - * \param additional Additional data to add to the state. - * If this is \c NULL, there is no additional data - * and \p len should be \c 0. - * \param len The length of the additional data. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT - * and also at most - * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len - * where \c entropy_len is the entropy length - * (see mbedtls_hmac_drbg_set_entropy_len()). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy function failed. - */ -int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t len); - -/** - * \brief This function updates an HMAC_DRBG instance with additional - * data and uses it to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - * - * \note This function is not thread-safe. It is not safe - * to call this function if another thread might be - * concurrently obtaining random numbers from the same - * context or updating or reseeding the same context. - * - * \param p_rng The HMAC_DRBG context. This must be a pointer to a - * #mbedtls_hmac_drbg_context structure. - * \param output The buffer to fill. - * \param output_len The length of the buffer in bytes. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * \param additional Additional data to update with. - * If this is \c NULL, there is no additional data - * and \p add_len should be \c 0. - * \param add_len The length of the additional data. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy source failed. - * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if - * \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if - * \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT. - */ -int mbedtls_hmac_drbg_random_with_add(void *p_rng, - unsigned char *output, size_t output_len, - const unsigned char *additional, - size_t add_len); - -/** - * \brief This function uses HMAC_DRBG to generate random data. - * - * This function automatically reseeds if the reseed counter is exceeded - * or prediction resistance is enabled. - */ -#if defined(MBEDTLS_THREADING_C) -/** - * \note When Mbed TLS is built with threading support, - * it is safe to call mbedtls_ctr_drbg_random() - * from multiple threads. Other operations, including - * reseeding, are not thread-safe. - */ -#endif /* MBEDTLS_THREADING_C */ -/** - * \param p_rng The HMAC_DRBG context. This must be a pointer to a - * #mbedtls_hmac_drbg_context structure. - * \param output The buffer to fill. - * \param out_len The length of the buffer in bytes. - * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED - * if a call to the entropy source failed. - * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if - * \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. - */ -int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len); - -/** - * \brief This function resets HMAC_DRBG context to the state immediately - * after initial call of mbedtls_hmac_drbg_init(). - * - * \param ctx The HMAC_DRBG context to free. - */ -void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief This function writes a seed file. - * - * \param ctx The HMAC_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed - * failure. - */ -int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path); - -/** - * \brief This function reads and updates a seed file. The seed - * is added to this instance. - * - * \param ctx The HMAC_DRBG context. - * \param path The name of the file. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on - * reseed failure. - * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing - * seed file is too large. - */ -int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path); -#endif /* MBEDTLS_FS_IO */ - - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The HMAC_DRBG Checkup routine. - * - * \return \c 0 if successful. - * \return \c 1 if the test failed. - */ -int mbedtls_hmac_drbg_self_test(int verbose); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* hmac_drbg.h */ diff --git a/vendor/mbedtls/include/mbedtls/lms.h b/vendor/mbedtls/include/mbedtls/lms.h deleted file mode 100644 index 2f297914b..000000000 --- a/vendor/mbedtls/include/mbedtls/lms.h +++ /dev/null @@ -1,440 +0,0 @@ -/** - * \file lms.h - * - * \brief This file provides an API for the LMS post-quantum-safe stateful-hash - public-key signature scheme as defined in RFC8554 and NIST.SP.200-208. - * This implementation currently only supports a single parameter set - * MBEDTLS_LMS_SHA256_M32_H10 in order to reduce complexity. This is one - * of the signature schemes recommended by the IETF draft SUIT standard - * for IOT firmware upgrades (RFC9019). - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_LMS_H -#define MBEDTLS_LMS_H - -#include -#include - -#include "mbedtls/private_access.h" -#include "mbedtls/build_info.h" - -#define MBEDTLS_ERR_LMS_BAD_INPUT_DATA -0x0011 /**< Bad data has been input to an LMS function */ -#define MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS -0x0013 /**< Specified LMS key has utilised all of its private keys */ -#define MBEDTLS_ERR_LMS_VERIFY_FAILED -0x0015 /**< LMS signature verification failed */ -#define MBEDTLS_ERR_LMS_ALLOC_FAILED -0x0017 /**< LMS failed to allocate space for a private key */ -#define MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL -0x0019 /**< Input/output buffer is too small to contain requited data */ - -/* Currently only defined for SHA256, 32 is the max hash output size */ -#define MBEDTLS_LMOTS_N_HASH_LEN_MAX (32u) -#define MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX (34u) -#define MBEDTLS_LMOTS_N_HASH_LEN(type) ((type) == MBEDTLS_LMOTS_SHA256_N32_W8 ? 32u : 0) -#define MBEDTLS_LMOTS_I_KEY_ID_LEN (16u) -#define MBEDTLS_LMOTS_Q_LEAF_ID_LEN (4u) -#define MBEDTLS_LMOTS_TYPE_LEN (4u) -#define MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(type) ((type) == MBEDTLS_LMOTS_SHA256_N32_W8 ? 34u : 0) -#define MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type) (MBEDTLS_LMOTS_N_HASH_LEN(type)) - -#define MBEDTLS_LMOTS_SIG_LEN(type) (MBEDTLS_LMOTS_TYPE_LEN + \ - MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type) + \ - (MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(type) * \ - MBEDTLS_LMOTS_N_HASH_LEN(type))) - - -#define MBEDTLS_LMS_TYPE_LEN (4) -#define MBEDTLS_LMS_H_TREE_HEIGHT(type) ((type) == MBEDTLS_LMS_SHA256_M32_H10 ? 10u : 0) - -/* The length of a hash output, Currently only implemented for SHA256. - * Max is 32 bytes. - */ -#define MBEDTLS_LMS_M_NODE_BYTES(type) ((type) == MBEDTLS_LMS_SHA256_M32_H10 ? 32 : 0) -#define MBEDTLS_LMS_M_NODE_BYTES_MAX 32 - -#define MBEDTLS_LMS_SIG_LEN(type, otstype) (MBEDTLS_LMOTS_Q_LEAF_ID_LEN + \ - MBEDTLS_LMOTS_SIG_LEN(otstype) + \ - MBEDTLS_LMS_TYPE_LEN + \ - (MBEDTLS_LMS_H_TREE_HEIGHT(type) * \ - MBEDTLS_LMS_M_NODE_BYTES(type))) - -#define MBEDTLS_LMS_PUBLIC_KEY_LEN(type) (MBEDTLS_LMS_TYPE_LEN + \ - MBEDTLS_LMOTS_TYPE_LEN + \ - MBEDTLS_LMOTS_I_KEY_ID_LEN + \ - MBEDTLS_LMS_M_NODE_BYTES(type)) - - -#ifdef __cplusplus -extern "C" { -#endif - -/** The Identifier of the LMS parameter set, as per - * https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml - * We are only implementing a subset of the types, particularly H10, for the sake of simplicity. - */ -typedef enum { - MBEDTLS_LMS_SHA256_M32_H10 = 0x6, -} mbedtls_lms_algorithm_type_t; - -/** The Identifier of the LMOTS parameter set, as per - * https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml. - * We are only implementing a subset of the types, particularly N32_W8, for the sake of simplicity. - */ -typedef enum { - MBEDTLS_LMOTS_SHA256_N32_W8 = 4 -} mbedtls_lmots_algorithm_type_t; - -/** LMOTS parameters structure. - * - * This contains the metadata associated with an LMOTS key, detailing the - * algorithm type, the key ID, and the leaf identifier should be key be part of - * a LMS key. - */ -typedef struct { - unsigned char MBEDTLS_PRIVATE(I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN]); /*!< The key - identifier. */ - unsigned char MBEDTLS_PRIVATE(q_leaf_identifier[MBEDTLS_LMOTS_Q_LEAF_ID_LEN]); /*!< Which - leaf of the LMS key this is. - 0 if the key is not part of an LMS key. */ - mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LM-OTS key type identifier as - per IANA. Only SHA256_N32_W8 is - currently supported. */ -} mbedtls_lmots_parameters_t; - -/** LMOTS public context structure. - * - * A LMOTS public key is a hash output, and the applicable parameter set. - * - * The context must be initialized before it is used. A public key must either - * be imported or generated from a private context. - * - * \dot - * digraph lmots_public_t { - * UNINITIALIZED -> INIT [label="init"]; - * HAVE_PUBLIC_KEY -> INIT [label="free"]; - * INIT -> HAVE_PUBLIC_KEY [label="import_public_key"]; - * INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"]; - * HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"]; - * } - * \enddot - */ -typedef struct { - mbedtls_lmots_parameters_t MBEDTLS_PRIVATE(params); - unsigned char MBEDTLS_PRIVATE(public_key)[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - unsigned char MBEDTLS_PRIVATE(have_public_key); /*!< Whether the context contains a public key. - Boolean values only. */ -} mbedtls_lmots_public_t; - -#if defined(MBEDTLS_LMS_PRIVATE) -/** LMOTS private context structure. - * - * A LMOTS private key is one hash output for each of digit of the digest + - * checksum, and the applicable parameter set. - * - * The context must be initialized before it is used. A public key must either - * be imported or generated from a private context. - * - * \dot - * digraph lmots_public_t { - * UNINITIALIZED -> INIT [label="init"]; - * HAVE_PRIVATE_KEY -> INIT [label="free"]; - * INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"]; - * HAVE_PRIVATE_KEY -> INIT [label="sign"]; - * } - * \enddot - */ -typedef struct { - mbedtls_lmots_parameters_t MBEDTLS_PRIVATE(params); - unsigned char MBEDTLS_PRIVATE(private_key)[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][ - MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key. - Boolean values only. */ -} mbedtls_lmots_private_t; -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ - - -/** LMS parameters structure. - * - * This contains the metadata associated with an LMS key, detailing the - * algorithm type, the type of the underlying OTS algorithm, and the key ID. - */ -typedef struct { - unsigned char MBEDTLS_PRIVATE(I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN]); /*!< The key - identifier. */ - mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(otstype); /*!< The LM-OTS key type identifier as - per IANA. Only SHA256_N32_W8 is - currently supported. */ - mbedtls_lms_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LMS key type identifier as per - IANA. Only SHA256_M32_H10 is currently - supported. */ -} mbedtls_lms_parameters_t; - -/** LMS public context structure. - * - * A LMS public key is the hash output that is the root of the Merkle tree, and - * the applicable parameter set - * - * The context must be initialized before it is used. A public key must either - * be imported or generated from a private context. - * - * \dot - * digraph lms_public_t { - * UNINITIALIZED -> INIT [label="init"]; - * HAVE_PUBLIC_KEY -> INIT [label="free"]; - * INIT -> HAVE_PUBLIC_KEY [label="import_public_key"]; - * INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"]; - * HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"]; - * } - * \enddot - */ -typedef struct { - mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params); - unsigned char MBEDTLS_PRIVATE(T_1_pub_key)[MBEDTLS_LMS_M_NODE_BYTES_MAX]; /*!< The public key, in - the form of the Merkle tree root node. */ - unsigned char MBEDTLS_PRIVATE(have_public_key); /*!< Whether the context contains a public key. - Boolean values only. */ -} mbedtls_lms_public_t; - - -#if defined(MBEDTLS_LMS_PRIVATE) -/** LMS private context structure. - * - * A LMS private key is a set of LMOTS private keys, an index to the next usable - * key, and the applicable parameter set. - * - * The context must be initialized before it is used. A public key must either - * be imported or generated from a private context. - * - * \dot - * digraph lms_public_t { - * UNINITIALIZED -> INIT [label="init"]; - * HAVE_PRIVATE_KEY -> INIT [label="free"]; - * INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"]; - * } - * \enddot - */ -typedef struct { - mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params); - uint32_t MBEDTLS_PRIVATE(q_next_usable_key); /*!< The index of the next OTS key that has not - been used. */ - mbedtls_lmots_private_t *MBEDTLS_PRIVATE(ots_private_keys); /*!< The private key material. One OTS key - for each leaf node in the Merkle tree. NULL - when have_private_key is 0 and non-NULL otherwise. - is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) in length. */ - mbedtls_lmots_public_t *MBEDTLS_PRIVATE(ots_public_keys); /*!< The OTS key public keys, used to - build the Merkle tree. NULL - when have_private_key is 0 and - non-NULL otherwise. - Is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) - in length. */ - unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key. - Boolean values only. */ -} mbedtls_lms_private_t; -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ - -/** - * \brief This function initializes an LMS public context - * - * \param ctx The uninitialized LMS context that will then be - * initialized. - */ -void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx); - -/** - * \brief This function uninitializes an LMS public context - * - * \param ctx The initialized LMS context that will then be - * uninitialized. - */ -void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx); - -/** - * \brief This function imports an LMS public key into a - * public LMS context. - * - * \note Before this function is called, the context must - * have been initialized. - * - * \note See IETF RFC8554 for details of the encoding of - * this public key. - * - * \param ctx The initialized LMS context store the key in. - * \param key The buffer from which the key will be read. - * #MBEDTLS_LMS_PUBLIC_KEY_LEN bytes will be read from - * this. - * \param key_size The size of the key being imported. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx, - const unsigned char *key, size_t key_size); - -/** - * \brief This function exports an LMS public key from a - * LMS public context that already contains a public - * key. - * - * \note Before this function is called, the context must - * have been initialized and the context must contain - * a public key. - * - * \note See IETF RFC8554 for details of the encoding of - * this public key. - * - * \param ctx The initialized LMS public context that contains - * the public key. - * \param key The buffer into which the key will be output. Must - * be at least #MBEDTLS_LMS_PUBLIC_KEY_LEN in size. - * \param key_size The size of the key buffer. - * \param key_len If not NULL, will be written with the size of the - * key. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx, - unsigned char *key, size_t key_size, - size_t *key_len); - -/** - * \brief This function verifies a LMS signature, using a - * LMS context that contains a public key. - * - * \note Before this function is called, the context must - * have been initialized and must contain a public key - * (either by import or generation). - * - * \param ctx The initialized LMS public context from which the - * public key will be read. - * \param msg The buffer from which the message will be read. - * \param msg_size The size of the message that will be read. - * \param sig The buf from which the signature will be read. - * #MBEDTLS_LMS_SIG_LEN bytes will be read from - * this. - * \param sig_size The size of the signature to be verified. - * - * \return \c 0 on successful verification. - * \return A non-zero error code on failure. - */ -int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx, - const unsigned char *msg, size_t msg_size, - const unsigned char *sig, size_t sig_size); - -#if defined(MBEDTLS_LMS_PRIVATE) -/** - * \brief This function initializes an LMS private context - * - * \param ctx The uninitialized LMS private context that will - * then be initialized. */ -void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx); - -/** - * \brief This function uninitializes an LMS private context - * - * \param ctx The initialized LMS private context that will then - * be uninitialized. - */ -void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx); - -/** - * \brief This function generates an LMS private key, and - * stores in into an LMS private context. - * - * \warning This function is **not intended for use in - * production**, due to as-yet unsolved problems with - * handling stateful keys. The API for this function - * may change considerably in future versions. - * - * \note The seed must have at least 256 bits of entropy. - * - * \param ctx The initialized LMOTS context to generate the key - * into. - * \param type The LMS parameter set identifier. - * \param otstype The LMOTS parameter set identifier. - * \param f_rng The RNG function to be used to generate the key ID. - * \param p_rng The RNG context to be passed to f_rng - * \param seed The seed used to deterministically generate the - * key. - * \param seed_size The length of the seed. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx, - mbedtls_lms_algorithm_type_t type, - mbedtls_lmots_algorithm_type_t otstype, - mbedtls_f_rng_t *f_rng, - void *p_rng, const unsigned char *seed, - size_t seed_size); - -/** - * \brief This function calculates an LMS public key from a - * LMS context that already contains a private key. - * - * \note Before this function is called, the context must - * have been initialized and the context must contain - * a private key. - * - * \param ctx The initialized LMS public context to calculate the key - * from and store it into. - * - * \param priv_ctx The LMS private context to read the private key - * from. This must have been initialized and contain a - * private key. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx, - const mbedtls_lms_private_t *priv_ctx); - -/** - * \brief This function creates a LMS signature, using a - * LMS context that contains unused private keys. - * - * \warning This function is **not intended for use in - * production**, due to as-yet unsolved problems with - * handling stateful keys. The API for this function - * may change considerably in future versions. - * - * \note Before this function is called, the context must - * have been initialized and must contain a private - * key. - * - * \note Each of the LMOTS private keys inside a LMS private - * key can only be used once. If they are reused, then - * attackers may be able to forge signatures with that - * key. This is all handled transparently, but it is - * important to not perform copy operations on LMS - * contexts that contain private key material. - * - * \param ctx The initialized LMS private context from which the - * private key will be read. - * \param f_rng The RNG function to be used for signature - * generation. - * \param p_rng The RNG context to be passed to f_rng - * \param msg The buffer from which the message will be read. - * \param msg_size The size of the message that will be read. - * \param sig The buf into which the signature will be stored. - * Must be at least #MBEDTLS_LMS_SIG_LEN in size. - * \param sig_size The size of the buffer the signature will be - * written into. - * \param sig_len If not NULL, will be written with the size of the - * signature. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lms_sign(mbedtls_lms_private_t *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, const unsigned char *msg, - unsigned int msg_size, unsigned char *sig, size_t sig_size, - size_t *sig_len); -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_LMS_H */ diff --git a/vendor/mbedtls/include/mbedtls/mbedtls_config.h b/vendor/mbedtls/include/mbedtls/mbedtls_config.h deleted file mode 100644 index 8fa445a13..000000000 --- a/vendor/mbedtls/include/mbedtls/mbedtls_config.h +++ /dev/null @@ -1,4437 +0,0 @@ -/** - * \file mbedtls_config.h - * - * \brief Configuration options (set of defines) - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/** - * This is an optional version symbol that enables compatibility handling of - * config files. - * - * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that - * introduced the config format we want to be compatible with. - */ -//#define MBEDTLS_CONFIG_VERSION 0x03000000 - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def MBEDTLS_HAVE_ASM - * - * The compiler has support for asm(). - * - * Requires support for asm() in compiler. - * - * Used in: - * library/aesni.h - * library/aria.c - * library/bn_mul.h - * library/constant_time.c - * library/padlock.h - * - * Required by: - * MBEDTLS_AESCE_C - * MBEDTLS_AESNI_C (on some platforms) - * MBEDTLS_PADLOCK_C - * - * Comment to disable the use of assembly code. - */ -#define MBEDTLS_HAVE_ASM - -/** - * \def MBEDTLS_NO_UDBL_DIVISION - * - * The platform lacks support for double-width integer division (64-bit - * division on a 32-bit platform, 128-bit division on a 64-bit platform). - * - * Used in: - * include/mbedtls/bignum.h - * library/bignum.c - * - * The bignum code uses double-width division to speed up some operations. - * Double-width division is often implemented in software that needs to - * be linked with the program. The presence of a double-width integer - * type is usually detected automatically through preprocessor macros, - * but the automatic detection cannot know whether the code needs to - * and can be linked with an implementation of division for that type. - * By default division is assumed to be usable if the type is present. - * Uncomment this option to prevent the use of double-width division. - * - * Note that division for the native integer type is always required. - * Furthermore, a 64-bit type is always required even on a 32-bit - * platform, but it need not support multiplication or division. In some - * cases it is also desirable to disable some double-width operations. For - * example, if double-width division is implemented in software, disabling - * it can reduce code size in some embedded targets. - */ -//#define MBEDTLS_NO_UDBL_DIVISION - -/** - * \def MBEDTLS_NO_64BIT_MULTIPLICATION - * - * The platform lacks support for 32x32 -> 64-bit multiplication. - * - * Used in: - * library/poly1305.c - * - * Some parts of the library may use multiplication of two unsigned 32-bit - * operands with a 64-bit result in order to speed up computations. On some - * platforms, this is not available in hardware and has to be implemented in - * software, usually in a library provided by the toolchain. - * - * Sometimes it is not desirable to have to link to that library. This option - * removes the dependency of that library on platforms that lack a hardware - * 64-bit multiplier by embedding a software implementation in Mbed TLS. - * - * Note that depending on the compiler, this may decrease performance compared - * to using the library function provided by the toolchain. - */ -//#define MBEDTLS_NO_64BIT_MULTIPLICATION - -/** - * \def MBEDTLS_HAVE_SSE2 - * - * CPU supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - */ -//#define MBEDTLS_HAVE_SSE2 - -/** - * \def MBEDTLS_HAVE_TIME - * - * System has time.h and time(). - * The time does not need to be correct, only time differences are used, - * by contrast with MBEDTLS_HAVE_TIME_DATE - * - * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, - * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and - * MBEDTLS_PLATFORM_STD_TIME. - * - * Comment if your system does not support time functions. - * - * \note If MBEDTLS_TIMING_C is set - to enable the semi-portable timing - * interface - timing.c will include time.h on suitable platforms - * regardless of the setting of MBEDTLS_HAVE_TIME, unless - * MBEDTLS_TIMING_ALT is used. See timing.c for more information. - */ -#define MBEDTLS_HAVE_TIME - -/** - * \def MBEDTLS_HAVE_TIME_DATE - * - * System has time.h, time(), and an implementation for - * mbedtls_platform_gmtime_r() (see below). - * The time needs to be correct (not necessarily very accurate, but at least - * the date should be correct). This is used to verify the validity period of - * X.509 certificates. - * - * Comment if your system does not have a correct clock. - * - * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that - * behaves similarly to the gmtime_r() function from the C standard. Refer to - * the documentation for mbedtls_platform_gmtime_r() for more information. - * - * \note It is possible to configure an implementation for - * mbedtls_platform_gmtime_r() at compile-time by using the macro - * MBEDTLS_PLATFORM_GMTIME_R_ALT. - */ -#define MBEDTLS_HAVE_TIME_DATE - -/** - * \def MBEDTLS_PLATFORM_MEMORY - * - * Enable the memory allocation layer. - * - * By default Mbed TLS uses the system-provided calloc() and free(). - * This allows different allocators (self-implemented or provided) to be - * provided to the platform abstraction layer. - * - * Enabling #MBEDTLS_PLATFORM_MEMORY without the - * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide - * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and - * free() function pointer at runtime. - * - * Enabling #MBEDTLS_PLATFORM_MEMORY and specifying - * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the - * alternate function at compile time. - * - * An overview of how the value of mbedtls_calloc is determined: - * - * - if !MBEDTLS_PLATFORM_MEMORY - * - mbedtls_calloc = calloc - * - if MBEDTLS_PLATFORM_MEMORY - * - if (MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): - * - mbedtls_calloc = MBEDTLS_PLATFORM_CALLOC_MACRO - * - if !(MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): - * - Dynamic setup via mbedtls_platform_set_calloc_free is now possible with a default value MBEDTLS_PLATFORM_STD_CALLOC. - * - How is MBEDTLS_PLATFORM_STD_CALLOC handled? - * - if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: - * - MBEDTLS_PLATFORM_STD_CALLOC is not set to anything; - * - MBEDTLS_PLATFORM_STD_MEM_HDR can be included if present; - * - if !MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: - * - if MBEDTLS_PLATFORM_STD_CALLOC is present: - * - User-defined MBEDTLS_PLATFORM_STD_CALLOC is respected; - * - if !MBEDTLS_PLATFORM_STD_CALLOC: - * - MBEDTLS_PLATFORM_STD_CALLOC = calloc - * - * - At this point the presence of MBEDTLS_PLATFORM_STD_CALLOC is checked. - * - if !MBEDTLS_PLATFORM_STD_CALLOC - * - MBEDTLS_PLATFORM_STD_CALLOC = uninitialized_calloc - * - * - mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC. - * - * Defining MBEDTLS_PLATFORM_CALLOC_MACRO and #MBEDTLS_PLATFORM_STD_CALLOC at the same time is not possible. - * MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO must both be defined or undefined at the same time. - * #MBEDTLS_PLATFORM_STD_CALLOC and #MBEDTLS_PLATFORM_STD_FREE do not have to be defined at the same time, as, if they are used, - * dynamic setup of these functions is possible. See the tree above to see how are they handled in all cases. - * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. - * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Enable this layer to allow use of alternative memory allocators. - */ -//#define MBEDTLS_PLATFORM_MEMORY - -/** - * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - * - * Do not assign standard functions in the platform layer (e.g. calloc() to - * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) - * - * This makes sure there are no linking errors on platforms that do not support - * these functions. You will HAVE to provide alternatives, either at runtime - * via the platform_set_xxx() functions or at compile time by setting - * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a - * MBEDTLS_PLATFORM_XXX_MACRO. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Uncomment to prevent default assignment of standard functions in the - * platform layer. - */ -//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - -/** - * \def MBEDTLS_PLATFORM_EXIT_ALT - * - * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let Mbed TLS support the - * function in the platform abstraction layer. - * - * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, Mbed TLS will - * provide a function "mbedtls_platform_set_printf()" that allows you to set an - * alternative printf function pointer. - * - * All these define require MBEDTLS_PLATFORM_C to be defined! - * - * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; - * it will be enabled automatically by check_config.h - * - * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as - * MBEDTLS_PLATFORM_XXX_MACRO! - * - * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME - * - * Uncomment a macro to enable alternate implementation of specific base - * platform function - */ -//#define MBEDTLS_PLATFORM_SETBUF_ALT -//#define MBEDTLS_PLATFORM_EXIT_ALT -//#define MBEDTLS_PLATFORM_TIME_ALT -//#define MBEDTLS_PLATFORM_FPRINTF_ALT -//#define MBEDTLS_PLATFORM_PRINTF_ALT -//#define MBEDTLS_PLATFORM_SNPRINTF_ALT -//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT -//#define MBEDTLS_PLATFORM_NV_SEED_ALT -//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT -//#define MBEDTLS_PLATFORM_MS_TIME_ALT - -/** - * Uncomment the macro to let Mbed TLS use your alternate implementation of - * mbedtls_platform_gmtime_r(). This replaces the default implementation in - * platform_util.c. - * - * gmtime() is not a thread-safe function as defined in the C standard. The - * library will try to use safer implementations of this function, such as - * gmtime_r() when available. However, if Mbed TLS cannot identify the target - * system, the implementation of mbedtls_platform_gmtime_r() will default to - * using the standard gmtime(). In this case, calls from the library to - * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex - * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the - * library are also guarded with this mutex to avoid race conditions. However, - * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will - * unconditionally use the implementation for mbedtls_platform_gmtime_r() - * supplied at compile time. - */ -//#define MBEDTLS_PLATFORM_GMTIME_R_ALT - -/** - * Uncomment the macro to let Mbed TLS use your alternate implementation of - * mbedtls_platform_zeroize(), to wipe sensitive data in memory. This replaces - * the default implementation in platform_util.c. - * - * By default, the library uses a system function such as memset_s() - * (optional feature of C11), explicit_bzero() (BSD and compatible), or - * SecureZeroMemory (Windows). If no such function is detected, the library - * falls back to a plain C implementation. Compilers are technically - * permitted to optimize this implementation out, meaning that the memory is - * not actually wiped. The library tries to prevent that, but the C language - * makes it impossible to guarantee that the memory will always be wiped. - * - * If your platform provides a guaranteed method to wipe memory which - * `platform_util.c` does not detect, define this macro to the name of - * a function that takes two arguments, a `void *` pointer and a length, - * and wipes that many bytes starting at the specified address. For example, - * if your platform has explicit_bzero() but `platform_util.c` does not - * detect its presence, define `MBEDTLS_PLATFORM_ZEROIZE_ALT` to be - * `explicit_bzero` to use that function as mbedtls_platform_zeroize(). - */ -//#define MBEDTLS_PLATFORM_ZEROIZE_ALT - -/** - * \def MBEDTLS_DEPRECATED_WARNING - * - * Mark deprecated functions and features so that they generate a warning if - * used. Functionality deprecated in one version will usually be removed in the - * next version. You can enable this to help you prepare the transition to a - * new major version by making sure your code is not using this functionality. - * - * This only works with GCC and Clang. With other compilers, you may want to - * use MBEDTLS_DEPRECATED_REMOVED - * - * Uncomment to get warnings on using deprecated functions and features. - */ -//#define MBEDTLS_DEPRECATED_WARNING - -/** - * \def MBEDTLS_DEPRECATED_REMOVED - * - * Remove deprecated functions and features so that they generate an error if - * used. Functionality deprecated in one version will usually be removed in the - * next version. You can enable this to help you prepare the transition to a - * new major version by making sure your code is not using this functionality. - * - * Uncomment to get errors on using deprecated functions and features. - */ -//#define MBEDTLS_DEPRECATED_REMOVED - -/** \} name SECTION: System support */ - -/** - * \name SECTION: Mbed TLS feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def MBEDTLS_TIMING_ALT - * - * Uncomment to provide your own alternate implementation for - * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() - * - * Only works if you have MBEDTLS_TIMING_C enabled. - * - * You will need to provide a header "timing_alt.h" and an implementation at - * compile time. - */ -//#define MBEDTLS_TIMING_ALT - -/** - * \def MBEDTLS_AES_ALT - * - * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let Mbed TLS use your - * alternate core implementation of a symmetric crypto, an arithmetic or hash - * module (e.g. platform specific assembly optimized implementations). Keep - * in mind that the function prototypes should remain the same. - * - * This replaces the whole module. If you only want to replace one of the - * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_AES_ALT, Mbed TLS will no longer - * provide the "struct mbedtls_aes_context" definition and omit the base - * function declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * module. - * - * \warning MD5, DES and SHA-1 are considered weak and their - * use constitutes a security risk. If possible, we recommend - * avoiding dependencies on them, and considering stronger message - * digests and ciphers instead. - * - */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARIA_ALT -//#define MBEDTLS_CAMELLIA_ALT -//#define MBEDTLS_CCM_ALT -//#define MBEDTLS_CHACHA20_ALT -//#define MBEDTLS_CHACHAPOLY_ALT -//#define MBEDTLS_CMAC_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_DHM_ALT -//#define MBEDTLS_ECJPAKE_ALT -//#define MBEDTLS_GCM_ALT -//#define MBEDTLS_NIST_KW_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_POLY1305_ALT -//#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_RSA_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT - -/* - * When replacing the elliptic curve module, please consider, that it is - * implemented with two .c files: - * - ecp.c - * - ecp_curves.c - * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT - * macros as described above. The only difference is that you have to make sure - * that you provide functionality for both .c files. - */ -//#define MBEDTLS_ECP_ALT - -/** - * \def MBEDTLS_SHA256_PROCESS_ALT - * - * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use you - * alternate core implementation of symmetric crypto or hash function. Keep in - * mind that function prototypes should remain the same. - * - * This replaces only one function. The header file from Mbed TLS is still - * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, Mbed TLS will - * no longer provide the mbedtls_sha1_process() function, but it will still provide - * the other function (using your mbedtls_sha1_process() function) and the definition - * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible - * with this definition. - * - * \note If you use the AES_xxx_ALT macros, then it is recommended to also set - * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES - * tables. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - * - * \warning MD5, DES and SHA-1 are considered weak and their use - * constitutes a security risk. If possible, we recommend avoiding - * dependencies on them, and considering stronger message digests - * and ciphers instead. - * - * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are - * enabled, then the deterministic ECDH signature functions pass the - * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore - * alternative implementations should use the RNG only for generating - * the ephemeral key and nothing else. If this is not possible, then - * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative - * implementation should be provided for mbedtls_ecdsa_sign_det_ext(). - * - */ -//#define MBEDTLS_MD5_PROCESS_ALT -//#define MBEDTLS_RIPEMD160_PROCESS_ALT -//#define MBEDTLS_SHA1_PROCESS_ALT -//#define MBEDTLS_SHA256_PROCESS_ALT -//#define MBEDTLS_SHA512_PROCESS_ALT -//#define MBEDTLS_DES_SETKEY_ALT -//#define MBEDTLS_DES_CRYPT_ECB_ALT -//#define MBEDTLS_DES3_CRYPT_ECB_ALT -//#define MBEDTLS_AES_SETKEY_ENC_ALT -//#define MBEDTLS_AES_SETKEY_DEC_ALT -//#define MBEDTLS_AES_ENCRYPT_ALT -//#define MBEDTLS_AES_DECRYPT_ALT -//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT -//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT -//#define MBEDTLS_ECDSA_VERIFY_ALT -//#define MBEDTLS_ECDSA_SIGN_ALT -//#define MBEDTLS_ECDSA_GENKEY_ALT - -/** - * \def MBEDTLS_ECP_INTERNAL_ALT - * - * Expose a part of the internal interface of the Elliptic Curve Point module. - * - * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use your - * alternative core implementation of elliptic curve arithmetic. Keep in mind - * that function prototypes should remain the same. - * - * This partially replaces one function. The header file from Mbed TLS is still - * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation - * is still present and it is used for group structures not supported by the - * alternative. - * - * The original implementation can in addition be removed by setting the - * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the - * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be - * able to fallback to curves not supported by the alternative implementation. - * - * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT - * and implementing the following functions: - * unsigned char mbedtls_internal_ecp_grp_capable( - * const mbedtls_ecp_group *grp ) - * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) - * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) - * The mbedtls_internal_ecp_grp_capable function should return 1 if the - * replacement functions implement arithmetic for the given group and 0 - * otherwise. - * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are - * called before and after each point operation and provide an opportunity to - * implement optimized set up and tear down instructions. - * - * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and - * MBEDTLS_ECP_DOUBLE_JAC_ALT, Mbed TLS will still provide the ecp_double_jac() - * function, but will use your mbedtls_internal_ecp_double_jac() if the group - * for the operation is supported by your implementation (i.e. your - * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the - * group is not supported by your implementation, then the original Mbed TLS - * implementation of ecp_double_jac() is used instead, unless this fallback - * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case - * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE). - * - * The function prototypes and the definition of mbedtls_ecp_group and - * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your - * implementation of mbedtls_internal_ecp__function_name__ must be compatible - * with their definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - */ -/* Required for all the functions in this section */ -//#define MBEDTLS_ECP_INTERNAL_ALT -/* Turn off software fallback for curves not supported in hardware */ -//#define MBEDTLS_ECP_NO_FALLBACK -/* Support for Weierstrass curves with Jacobi representation */ -//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT -//#define MBEDTLS_ECP_ADD_MIXED_ALT -//#define MBEDTLS_ECP_DOUBLE_JAC_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT -/* Support for curves with Montgomery arithmetic */ -//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT -//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT -//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT - -/** - * \def MBEDTLS_ENTROPY_HARDWARE_ALT - * - * Uncomment this macro to let Mbed TLS use your own implementation of a - * hardware entropy collector. - * - * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in library/entropy_poll.h, and accept NULL as first - * argument. - * - * Uncomment to use your own hardware entropy collector. - */ -//#define MBEDTLS_ENTROPY_HARDWARE_ALT - -/** - * \def MBEDTLS_AES_ROM_TABLES - * - * Use precomputed AES tables stored in ROM. - * - * Uncomment this macro to use precomputed AES tables stored in ROM. - * Comment this macro to generate AES tables in RAM at runtime. - * - * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb - * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the - * initialization time before the first AES operation can be performed. - * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c - * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded - * performance if ROM access is slower than RAM access. - * - * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. - */ -//#define MBEDTLS_AES_ROM_TABLES - -/** - * \def MBEDTLS_AES_FEWER_TABLES - * - * Use less ROM/RAM for AES tables. - * - * Uncommenting this macro omits 75% of the AES tables from - * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) - * by computing their values on the fly during operations - * (the tables are entry-wise rotations of one another). - * - * Tradeoff: Uncommenting this reduces the RAM / ROM footprint - * by ~6kb but at the cost of more arithmetic operations during - * runtime. Specifically, one has to compare 4 accesses within - * different tables to 4 accesses with additional arithmetic - * operations within the same table. The performance gain/loss - * depends on the system and memory details. - * - * This option is independent of \c MBEDTLS_AES_ROM_TABLES. - */ -//#define MBEDTLS_AES_FEWER_TABLES - -/** - * \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH - * - * Use only 128-bit keys in AES operations to save ROM. - * - * Uncomment this macro to remove support for AES operations that use 192- - * or 256-bit keys. - * - * Uncommenting this macro reduces the size of AES code by ~300 bytes - * on v8-M/Thumb2. - * - * Module: library/aes.c - * - * Requires: MBEDTLS_AES_C - */ -//#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH - -/* - * Disable plain C implementation for AES. - * - * When the plain C implementation is enabled, and an implementation using a - * special CPU feature (such as MBEDTLS_AESCE_C) is also enabled, runtime - * detection will be used to select between them. - * - * If only one implementation is present, runtime detection will not be used. - * This configuration will crash at runtime if running on a CPU without the - * necessary features. It will not build unless at least one of MBEDTLS_AESCE_C - * and/or MBEDTLS_AESNI_C is enabled & present in the build. - */ -//#define MBEDTLS_AES_USE_HARDWARE_ONLY - -/** - * \def MBEDTLS_CAMELLIA_SMALL_MEMORY - * - * Use less ROM for the Camellia implementation (saves about 768 bytes). - * - * Uncomment this macro to use less memory for Camellia. - */ -//#define MBEDTLS_CAMELLIA_SMALL_MEMORY - -/** - * \def MBEDTLS_CHECK_RETURN_WARNING - * - * If this macro is defined, emit a compile-time warning if application code - * calls a function without checking its return value, but the return value - * should generally be checked in portable applications. - * - * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is - * implemented. Otherwise this option has no effect. - * - * Uncomment to get warnings on using fallible functions without checking - * their return value. - * - * \note This feature is a work in progress. - * Warnings will be added to more functions in the future. - * - * \note A few functions are considered critical, and ignoring the return - * value of these functions will trigger a warning even if this - * macro is not defined. To completely disable return value check - * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion. - */ -//#define MBEDTLS_CHECK_RETURN_WARNING - -/** - * \def MBEDTLS_CIPHER_MODE_CBC - * - * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CBC - -/** - * \def MBEDTLS_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CFB - -/** - * \def MBEDTLS_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CTR - -/** - * \def MBEDTLS_CIPHER_MODE_OFB - * - * Enable Output Feedback mode (OFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_OFB - -/** - * \def MBEDTLS_CIPHER_MODE_XTS - * - * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. - */ -#define MBEDTLS_CIPHER_MODE_XTS - -/** - * \def MBEDTLS_CIPHER_NULL_CIPHER - * - * Enable NULL cipher. - * Warning: Only do so when you know what you are doing. This allows for - * encryption or channels without any security! - * - * To enable the following ciphersuites: - * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA - * - * Uncomment this macro to enable the NULL cipher and ciphersuites - */ -//#define MBEDTLS_CIPHER_NULL_CIPHER - -/** - * \def MBEDTLS_CIPHER_PADDING_PKCS7 - * - * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for - * specific padding modes in the cipher layer with cipher modes that support - * padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define MBEDTLS_CIPHER_PADDING_ZEROS - -/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - * - * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. - * Without this, CTR_DRBG uses a 256-bit key - * unless \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set. - */ -//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - -/** - * Enable the verified implementations of ECDH primitives from Project Everest - * (currently only Curve25519). This feature changes the layout of ECDH - * contexts and therefore is a compatibility break for applications that access - * fields of a mbedtls_ecdh_context structure directly. See also - * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h. - * - * The Everest code is provided under the Apache 2.0 license only; therefore enabling this - * option is not compatible with taking the library under the GPL v2.0-or-later license. - */ -//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED - -/** - * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED - * - * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve - * module. By default all supported curves are enabled. - * - * Comment macros to disable the curve and functions for it - */ -/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -/* Montgomery curves (supporting ECP) */ -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_DP_CURVE448_ENABLED - -/** - * \def MBEDTLS_ECP_NIST_OPTIM - * - * Enable specific 'modulo p' routines for each NIST prime. - * Depending on the prime and architecture, makes operations 4 to 8 times - * faster on the corresponding curve. - * - * Comment this macro to disable NIST curves optimisation. - */ -#define MBEDTLS_ECP_NIST_OPTIM - -/** - * \def MBEDTLS_ECP_RESTARTABLE - * - * Enable "non-blocking" ECC operations that can return early and be resumed. - * - * This allows various functions to pause by returning - * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in - * order to further progress and eventually complete their operation. This is - * controlled through mbedtls_ecp_set_max_ops() which limits the maximum - * number of ECC operations a function may perform before pausing; see - * mbedtls_ecp_set_max_ops() for more information. - * - * This is useful in non-threaded environments if you want to avoid blocking - * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. - * - * This option: - * - Adds xxx_restartable() variants of existing operations in the - * following modules, with corresponding restart context types: - * - ECP (for Short Weierstrass curves only): scalar multiplication (mul), - * linear combination (muladd); - * - ECDSA: signature generation & verification; - * - PK: signature generation & verification; - * - X509: certificate chain verification. - * - Adds mbedtls_ecdh_enable_restart() in the ECDH module. - * - Changes the behaviour of TLS 1.2 clients (not servers) when using the - * ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC - * computations restartable: - * - ECDH operations from the key exchange, only for Short Weierstrass - * curves, only when MBEDTLS_USE_PSA_CRYPTO is not enabled. - * - verification of the server's key exchange signature; - * - verification of the server's certificate chain; - * - generation of the client's signature if client authentication is used, - * with an ECC key/certificate. - * - * \note In the cases above, the usual SSL/TLS functions, such as - * mbedtls_ssl_handshake(), can now return - * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS. - * - * \note When this option and MBEDTLS_USE_PSA_CRYPTO are both enabled, - * restartable operations in PK, X.509 and TLS (see above) are not - * using PSA. On the other hand, ECDH computations in TLS are using - * PSA, and are not restartable. These are temporary limitations that - * should be lifted in the future. - * - * \note This option only works with the default software implementation of - * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT. - * - * Requires: MBEDTLS_ECP_C - * - * Uncomment this macro to enable restartable ECC computations. - */ -//#define MBEDTLS_ECP_RESTARTABLE - -/** - * Uncomment to enable using new bignum code in the ECC modules. - * - * \warning This is currently experimental, incomplete and therefore should not - * be used in production. - */ -//#define MBEDTLS_ECP_WITH_MPI_UINT - -/** - * \def MBEDTLS_ECDSA_DETERMINISTIC - * - * Enable deterministic ECDSA (RFC 6979). - * Standard ECDSA is "fragile" in the sense that lack of entropy when signing - * may result in a compromise of the long-term signing key. This is avoided by - * the deterministic variant. - * - * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C - * - * Comment this macro to disable deterministic ECDSA. - */ -#define MBEDTLS_ECDSA_DETERMINISTIC - -/** - * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - * - * Enable the PSK based ciphersuite modes in SSL / TLS. - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - * - * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - * - * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) - * MBEDTLS_RSA_C - * MBEDTLS_PKCS1_V15 - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - * - * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) - * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) - * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) - * MBEDTLS_RSA_C - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - * - * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Requires: MBEDTLS_ECJPAKE_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_JPAKE) - * SHA-256 (via MBEDTLS_SHA256_C or a PSA driver) - * MBEDTLS_ECP_DP_SECP256R1_ENABLED - * - * \warning If SHA-256 is provided only by a PSA driver, you must call - * psa_crypto_init() before the first handshake (even if - * MBEDTLS_USE_PSA_CRYPTO is disabled). - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 - */ -//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - -/** - * \def MBEDTLS_PK_PARSE_EC_EXTENDED - * - * Enhance support for reading EC keys using variants of SEC1 not allowed by - * RFC 5915 and RFC 5480. - * - * Currently this means parsing the SpecifiedECDomain choice of EC - * parameters (only known groups are supported, not arbitrary domains, to - * avoid validation issues). - * - * Disable if you only need to support RFC 5915 + 5480 key formats. - */ -#define MBEDTLS_PK_PARSE_EC_EXTENDED - -/** - * \def MBEDTLS_PK_PARSE_EC_COMPRESSED - * - * Enable the support for parsing public keys of type Short Weierstrass - * (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX) which are using the - * compressed point format. This parsing is done through ECP module's functions. - * - * \note As explained in the description of MBEDTLS_ECP_PF_COMPRESSED (in ecp.h) - * the only unsupported curves are MBEDTLS_ECP_DP_SECP224R1 and - * MBEDTLS_ECP_DP_SECP224K1. - */ -#define MBEDTLS_PK_PARSE_EC_COMPRESSED - -/** - * \def MBEDTLS_ERROR_STRERROR_DUMMY - * - * Enable a dummy error function to make use of mbedtls_strerror() in - * third party libraries easier when MBEDTLS_ERROR_C is disabled - * (no effect when MBEDTLS_ERROR_C is enabled). - * - * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're - * not using mbedtls_strerror() or error_strerror() in your application. - * - * Disable if you run into name conflicts and want to really remove the - * mbedtls_strerror() - */ -#define MBEDTLS_ERROR_STRERROR_DUMMY - -/** - * \def MBEDTLS_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: MBEDTLS_BIGNUM_C - */ -#define MBEDTLS_GENPRIME - -/** - * \def MBEDTLS_FS_IO - * - * Enable functions that use the filesystem. - */ -#define MBEDTLS_FS_IO - -/** - * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - * Do not add default entropy sources in mbedtls_entropy_init(). - * - * This is useful to have more control over the added entropy sources in an - * application. - * - * Uncomment this macro to prevent loading of default entropy functions. - */ -//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - -/** - * \def MBEDTLS_NO_PLATFORM_ENTROPY - * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. - * - * If you enable this macro, you will probably need to enable - * #MBEDTLS_ENTROPY_HARDWARE_ALT and provide a function - * mbedtls_hardware_poll(). - * - * \note The default platform entropy function supports the following - * sources: - * - getrandom() on Linux (if syscall() is available at compile time); - * - getrandom() on FreeBSD and DragonFlyBSD (if available at compile - * time); - * - `sysctl(KERN_ARND)` on FreeBSD and NetBSD; - * - #MBEDTLS_PLATFORM_DEV_RANDOM on Unix-like platforms - * (unless one of the above is used); - * - BCryptGenRandom() on Windows. - * - * Uncomment this macro to disable the built-in platform entropy functions. - */ -//#define MBEDTLS_NO_PLATFORM_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_FORCE_SHA256 - * - * Force the entropy accumulator to use a SHA-256 accumulator instead of the - * default SHA-512 based one (if both are available). - * - * Requires: MBEDTLS_SHA256_C - * - * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option - * if you have performance concerns. - * - * This option is only useful if both MBEDTLS_SHA256_C and - * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. - */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 - -/** - * \def MBEDTLS_ENTROPY_NV_SEED - * - * Enable the non-volatile (NV) seed file-based entropy source. - * (Also enables the NV seed read/write functions in the platform layer) - * - * This is crucial (if not required) on systems that do not have a - * cryptographic entropy source (in hardware or kernel) available. - * - * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C - * - * \note The read/write functions that are used by the entropy source are - * determined in the platform layer, and can be modified at runtime and/or - * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. - * - * \note If you use the default implementation functions that read a seedfile - * with regular fopen(), please make sure you make a seedfile with the - * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at - * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from - * and written to or you will get an entropy source error! The default - * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE - * bytes from the file. - * - * \note The entropy collector will write to the seed file before entropy is - * given to an external source, to update it. - */ -//#define MBEDTLS_ENTROPY_NV_SEED - -/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - * - * Enable key identifiers that encode a key owner identifier. - * - * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t - * which is currently hard-coded to be int32_t. - * - * Note that this option is meant for internal use only and may be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - -/** - * \def MBEDTLS_MEMORY_DEBUG - * - * Enable debugging of buffer allocator memory issues. Automatically prints - * (to stderr) all (fatal) messages on memory allocation issues. Enables - * function for 'debug output' of allocated memory. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Uncomment this macro to let the buffer allocator print out error messages. - */ -//#define MBEDTLS_MEMORY_DEBUG - -/** - * \def MBEDTLS_MEMORY_BACKTRACE - * - * Include backtrace information with each allocated block. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() and backtrace_symbols() support - * - * Uncomment this macro to include backtrace information - */ -//#define MBEDTLS_MEMORY_BACKTRACE - -/** - * \def MBEDTLS_PK_RSA_ALT_SUPPORT - * - * Support external private RSA keys (eg from a HSM) in the PK layer. - * - * Comment this macro to disable support for external private RSA keys. - */ -#define MBEDTLS_PK_RSA_ALT_SUPPORT - -/** - * \def MBEDTLS_PKCS1_V15 - * - * Enable support for PKCS#1 v1.5 encoding. - * - * Requires: MBEDTLS_RSA_C - * - * This enables support for PKCS#1 v1.5 operations. - */ -#define MBEDTLS_PKCS1_V15 - -/** - * \def MBEDTLS_PKCS1_V21 - * - * Enable support for PKCS#1 v2.1 encoding. - * - * Requires: MBEDTLS_RSA_C - * - * \warning If using a hash that is only provided by PSA drivers, you must - * call psa_crypto_init() before doing any PKCS#1 v2.1 operation. - * - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -#define MBEDTLS_PKCS1_V21 - -/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS - * - * Enable support for platform built-in keys. If you enable this feature, - * you must implement the function mbedtls_psa_platform_get_builtin_key(). - * See the documentation of that function for more information. - * - * Built-in keys are typically derived from a hardware unique key or - * stored in a secure element. - * - * Requires: MBEDTLS_PSA_CRYPTO_C. - * - * \warning This interface is experimental and may change or be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS - -/** \def MBEDTLS_PSA_CRYPTO_CLIENT - * - * Enable support for PSA crypto client. - * - * \note This option allows to include the code necessary for a PSA - * crypto client when the PSA crypto implementation is not included in - * the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the - * code to set and get PSA key attributes. - * The development of PSA drivers partially relying on the library to - * fulfill the hardware gaps is another possible usage of this option. - * - * \warning This interface is experimental and may change or be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_CLIENT - -/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - * - * Make the PSA Crypto module use an external random generator provided - * by a driver, instead of Mbed TLS's entropy and DRBG modules. - * - * \note This random generator must deliver random numbers with cryptographic - * quality and high performance. It must supply unpredictable numbers - * with a uniform distribution. The implementation of this function - * is responsible for ensuring that the random generator is seeded - * with sufficient entropy. If you have a hardware TRNG which is slow - * or delivers non-uniform output, declare it as an entropy source - * with mbedtls_entropy_add_source() instead of enabling this option. - * - * If you enable this option, you must configure the type - * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h - * and define a function called mbedtls_psa_external_get_random() - * with the following prototype: - * ``` - * psa_status_t mbedtls_psa_external_get_random( - * mbedtls_psa_external_random_context_t *context, - * uint8_t *output, size_t output_size, size_t *output_length); - * ); - * ``` - * The \c context value is initialized to 0 before the first call. - * The function must fill the \c output buffer with \c output_size bytes - * of random data and set \c *output_length to \c output_size. - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * \warning If you enable this option, code that uses the PSA cryptography - * interface will not use any of the entropy sources set up for - * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED - * enables. - * - * \note This option is experimental and may be removed without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - -/** - * \def MBEDTLS_PSA_CRYPTO_SPM - * - * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure - * Partition Manager) integration which separates the code into two parts: a - * NSPE (Non-Secure Process Environment) and an SPE (Secure Process - * Environment). - * - * If you enable this option, your build environment must include a header - * file `"crypto_spe.h"` (either in the `psa` subdirectory of the Mbed TLS - * header files, or in another directory on the compiler's include search - * path). Alternatively, your platform may customize the header - * `psa/crypto_platform.h`, in which case it can skip or replace the - * inclusion of `"crypto_spe.h"`. - * - * Module: library/psa_crypto.c - * Requires: MBEDTLS_PSA_CRYPTO_C - * - */ -//#define MBEDTLS_PSA_CRYPTO_SPM - -/** - * \def MBEDTLS_PSA_KEY_STORE_DYNAMIC - * - * Dynamically resize the PSA key store to accommodate any number of - * volatile keys (until the heap memory is exhausted). - * - * If this option is disabled, the key store has a fixed size - * #MBEDTLS_PSA_KEY_SLOT_COUNT for volatile keys and loaded persistent keys - * together. - * - * This option has no effect when #MBEDTLS_PSA_CRYPTO_C is disabled. - * - * Module: library/psa_crypto.c - * Requires: MBEDTLS_PSA_CRYPTO_C - */ -#define MBEDTLS_PSA_KEY_STORE_DYNAMIC - -/** - * Uncomment to enable p256-m. This is an alternative implementation of - * key generation, ECDH and (randomized) ECDSA on the curve SECP256R1. - * Compared to the default implementation: - * - * - p256-m has a much smaller code size and RAM footprint. - * - p256-m is only available via the PSA API. This includes the pk module - * when #MBEDTLS_USE_PSA_CRYPTO is enabled. - * - p256-m does not support deterministic ECDSA, EC-JPAKE, custom protocols - * over the core arithmetic, or deterministic derivation of keys. - * - * We recommend enabling this option if your application uses the PSA API - * and the only elliptic curve support it needs is ECDH and ECDSA over - * SECP256R1. - * - * If you enable this option, you do not need to enable any ECC-related - * MBEDTLS_xxx option. You do need to separately request support for the - * cryptographic mechanisms through the PSA API: - * - #MBEDTLS_PSA_CRYPTO_C and #MBEDTLS_PSA_CRYPTO_CONFIG for PSA-based - * configuration; - * - #MBEDTLS_USE_PSA_CRYPTO if you want to use p256-m from PK, X.509 or TLS; - * - #PSA_WANT_ECC_SECP_R1_256; - * - #PSA_WANT_ALG_ECDH and/or #PSA_WANT_ALG_ECDSA as needed; - * - #PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY, #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC, - * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT, - * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT and/or - * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE as needed. - * - * \note To benefit from the smaller code size of p256-m, make sure that you - * do not enable any ECC-related option not supported by p256-m: this - * would cause the built-in ECC implementation to be built as well, in - * order to provide the required option. - * Make sure #PSA_WANT_ALG_DETERMINISTIC_ECDSA, #PSA_WANT_ALG_JPAKE and - * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE, and curves other than - * SECP256R1 are disabled as they are not supported by this driver. - * Also, avoid defining #MBEDTLS_PK_PARSE_EC_COMPRESSED or - * #MBEDTLS_PK_PARSE_EC_EXTENDED as those currently require a subset of - * the built-in ECC implementation, see docs/driver-only-builds.md. - */ -//#define MBEDTLS_PSA_P256M_DRIVER_ENABLED - -/** - * \def MBEDTLS_PSA_INJECT_ENTROPY - * - * Enable support for entropy injection at first boot. This feature is - * required on systems that do not have a built-in entropy source (TRNG). - * This feature is currently not supported on systems that have a built-in - * entropy source. - * - * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED - * - */ -//#define MBEDTLS_PSA_INJECT_ENTROPY - -/** - * \def MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS - * - * Assume all buffers passed to PSA functions are owned exclusively by the - * PSA function and are not stored in shared memory. - * - * This option may be enabled if all buffers passed to any PSA function reside - * in memory that is accessible only to the PSA function during its execution. - * - * This option MUST be disabled whenever buffer arguments are in memory shared - * with an untrusted party, for example where arguments to PSA calls are passed - * across a trust boundary. - * - * \note Enabling this option reduces memory usage and code size. - * - * \note Enabling this option causes overlap of input and output buffers - * not to be supported by PSA functions. - */ -//#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS - -/** - * \def MBEDTLS_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem - * for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * - */ -//#define MBEDTLS_RSA_NO_CRT - -/** - * \def MBEDTLS_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -#define MBEDTLS_SELF_TEST - -/** - * \def MBEDTLS_SHA256_SMALLER - * - * Enable an implementation of SHA-256 that has lower ROM footprint but also - * lower performance. - * - * The default implementation is meant to be a reasonable compromise between - * performance and size. This version optimizes more aggressively for size at - * the expense of performance. Eg on Cortex-M4 it reduces the size of - * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about - * 30%. - * - * Uncomment to enable the smaller implementation of SHA256. - */ -//#define MBEDTLS_SHA256_SMALLER - -/** - * \def MBEDTLS_SHA512_SMALLER - * - * Enable an implementation of SHA-512 that has lower ROM footprint but also - * lower performance. - * - * Uncomment to enable the smaller implementation of SHA512. - */ -//#define MBEDTLS_SHA512_SMALLER - -/** - * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES - * - * Enable sending of alert messages in case of encountered errors as per RFC. - * If you choose not to send the alert messages, Mbed TLS can still communicate - * with other servers, only debugging of failures is harder. - * - * The advantage of not sending alert messages, is that no information is given - * about reasons for failures thus preventing adversaries of gaining intel. - * - * Enable sending of all alert messages - */ -#define MBEDTLS_SSL_ALL_ALERT_MESSAGES - -/** - * \def MBEDTLS_SSL_DTLS_CONNECTION_ID - * - * Enable support for the DTLS Connection ID (CID) extension, - * which allows to identify DTLS connections across changes - * in the underlying transport. The CID functionality is described - * in RFC 9146. - * - * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, - * mbedtls_ssl_get_own_cid()`, `mbedtls_ssl_get_peer_cid()` and - * `mbedtls_ssl_conf_cid()`. See the corresponding documentation for - * more information. - * - * The maximum lengths of outgoing and incoming CIDs can be configured - * through the options - * - MBEDTLS_SSL_CID_OUT_LEN_MAX - * - MBEDTLS_SSL_CID_IN_LEN_MAX. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Uncomment to enable the Connection ID extension. - */ -#define MBEDTLS_SSL_DTLS_CONNECTION_ID - - -/** - * \def MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT - * - * Defines whether RFC 9146 (default) or the legacy version - * (version draft-ietf-tls-dtls-connection-id-05, - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) - * is used. - * - * Set the value to 0 for the standard version, and - * 1 for the legacy draft version. - * - * \deprecated Support for the legacy version of the DTLS - * Connection ID feature is deprecated. Please - * switch to the standardized version defined - * in RFC 9146 enabled by utilizing - * MBEDTLS_SSL_DTLS_CONNECTION_ID without use - * of MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT. - * - * Requires: MBEDTLS_SSL_DTLS_CONNECTION_ID - */ -#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0 - -/** - * \def MBEDTLS_SSL_ASYNC_PRIVATE - * - * Enable asynchronous external private key operations in SSL. This allows - * you to configure an SSL connection to call an external cryptographic - * module to perform private key operations instead of performing the - * operation inside the library. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - */ -//#define MBEDTLS_SSL_ASYNC_PRIVATE - -/** \def MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME - * - * In TLS clients, when a client authenticates a server through its - * certificate, the client normally checks three things: - * - the certificate chain must be valid; - * - the chain must start from a trusted CA; - * - the certificate must cover the server name that is expected by the client. - * - * Omitting any of these checks is generally insecure, and can allow a - * malicious server to impersonate a legitimate server. - * - * The third check may be safely skipped in some unusual scenarios, - * such as networks where eavesdropping is a risk but not active attacks, - * or a private PKI where the client equally trusts all servers that are - * accredited by the root CA. - * - * You should call mbedtls_ssl_set_hostname() with the expected server name - * before starting a TLS handshake on a client (unless the client is - * set up to only use PSK-based authentication, which does not rely on the - * host name). This configuration option controls what happens if a TLS client - * is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED - * (default), certificate authentication is enabled and the client does not - * call mbedtls_ssl_set_hostname(): - * - * - If this option is unset (default), the connection attempt is aborted - * with the error #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME. - * - If this option is set, the TLS library does not check the server name - * that the certificate is valid for. This is the historical behavior - * of Mbed TLS, but may be insecure as explained above. - * - * Enable this option for strict backward compatibility if you have - * determined that it is secure in the scenario where you are using - * Mbed TLS. - * - * \deprecated This option exists only for backward compatibility and will - * be removed in the next major version of Mbed TLS. - * - */ -//#define MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME - -/** - * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION - * - * Enable serialization of the TLS context structures, through use of the - * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). - * - * This pair of functions allows one side of a connection to serialize the - * context associated with the connection, then free or re-use that context - * while the serialized state is persisted elsewhere, and finally deserialize - * that state to a live context for resuming read/write operations on the - * connection. From a protocol perspective, the state of the connection is - * unaffected, in particular this is entirely transparent to the peer. - * - * Note: this is distinct from TLS session resumption, which is part of the - * protocol and fully visible by the peer. TLS session resumption enables - * establishing new connections associated to a saved session with shorter, - * lighter handshakes, while context serialization is a local optimization in - * handling a single, potentially long-lived connection. - * - * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are - * saved after the handshake to allow for more efficient serialization, so if - * you don't need this feature you'll save RAM by disabling it. - * - * Requires: MBEDTLS_GCM_C or MBEDTLS_CCM_C or MBEDTLS_CHACHAPOLY_C - * - * Comment to disable the context serialization APIs. - */ -#define MBEDTLS_SSL_CONTEXT_SERIALIZATION - -/** - * \def MBEDTLS_SSL_DEBUG_ALL - * - * Enable the debug messages in SSL module for all issues. - * Debug messages have been disabled in some places to prevent timing - * attacks due to (unbalanced) debugging function calls. - * - * If you need all error reporting you should enable this during debugging, - * but remove this for production servers that should log as well. - * - * Uncomment this macro to report all debug messages on errors introducing - * a timing side-channel. - * - */ -//#define MBEDTLS_SSL_DEBUG_ALL - -/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC - * - * Enable support for Encrypt-then-MAC, RFC 7366. - * - * This allows peers that both support it to use a more robust protection for - * ciphersuites using CBC, providing deep resistance against timing attacks - * on the padding or underlying cipher. - * - * This only affects CBC ciphersuites, and is useless if none is defined. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Encrypt-then-MAC - */ -#define MBEDTLS_SSL_ENCRYPT_THEN_MAC - -/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET - * - * Enable support for RFC 7627: Session Hash and Extended Master Secret - * Extension. - * - * This was introduced as "the proper fix" to the Triple Handshake family of - * attacks, but it is recommended to always use it (even if you disable - * renegotiation), since it actually fixes a more fundamental issue in the - * original SSL/TLS design, and has implications beyond Triple Handshake. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Extended Master Secret. - */ -#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET - -/** - * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * - * This option controls the availability of the API mbedtls_ssl_get_peer_cert() - * giving access to the peer's certificate after completion of the handshake. - * - * Unless you need mbedtls_ssl_peer_cert() in your application, it is - * recommended to disable this option for reduced RAM usage. - * - * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still - * defined, but always returns \c NULL. - * - * \note This option has no influence on the protection against the - * triple handshake attack. Even if it is disabled, Mbed TLS will - * still ensure that certificates do not change during renegotiation, - * for example by keeping a hash of the peer's certificate. - * - * \note This option is required if MBEDTLS_SSL_PROTO_TLS1_3 is set. - * - * Comment this macro to disable storing the peer's certificate - * after the handshake. - */ -#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - -/** - * \def MBEDTLS_SSL_KEYING_MATERIAL_EXPORT - * - * When this option is enabled, the client and server can extract additional - * shared symmetric keys after an SSL handshake using the function - * mbedtls_ssl_export_keying_material(). - * - * The process for deriving the keys is specified in RFC 5705 for TLS 1.2 and - * in RFC 8446, Section 7.5, for TLS 1.3. - * - * Comment this macro to disable mbedtls_ssl_export_keying_material(). - */ -#define MBEDTLS_SSL_KEYING_MATERIAL_EXPORT - -/** - * \def MBEDTLS_SSL_RENEGOTIATION - * - * Enable support for TLS renegotiation. - * - * The two main uses of renegotiation are (1) refresh keys on long-lived - * connections and (2) client authentication after the initial handshake. - * If you don't need renegotiation, it's probably better to disable it, since - * it has been associated with security issues in the past and is easy to - * misuse/misunderstand. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this to disable support for renegotiation. - * - * \note Even if this option is disabled, both client and server are aware - * of the Renegotiation Indication Extension (RFC 5746) used to - * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). - * (See \c mbedtls_ssl_conf_legacy_renegotiation for the - * configuration of this extension). - * - */ -#define MBEDTLS_SSL_RENEGOTIATION - -/** - * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - * - * Enable support for RFC 6066 max_fragment_length extension in SSL. - * - * Comment this macro to disable support for the max_fragment_length extension - */ -#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - -/** - * \def MBEDTLS_SSL_RECORD_SIZE_LIMIT - * - * Enable support for RFC 8449 record_size_limit extension in SSL (TLS 1.3 only). - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_3 - * - * Uncomment this macro to enable support for the record_size_limit extension - */ -//#define MBEDTLS_SSL_RECORD_SIZE_LIMIT - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). - * - * Requires: Without MBEDTLS_USE_PSA_CRYPTO: MBEDTLS_MD_C and - * (MBEDTLS_SHA256_C or MBEDTLS_SHA384_C or - * SHA-256 or SHA-512 provided by a PSA driver) - * With MBEDTLS_USE_PSA_CRYPTO: - * PSA_WANT_ALG_SHA_256 or PSA_WANT_ALG_SHA_384 - * - * \warning If building with MBEDTLS_USE_PSA_CRYPTO, or if the hash(es) used - * are only provided by PSA drivers, you must call psa_crypto_init() before - * doing any TLS operations. - * - * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 - */ -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_3 - * - * Enable support for TLS 1.3. - * - * \note See docs/architecture/tls13-support.md for a description of the TLS - * 1.3 support that this option enables. - * - * Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * \note TLS 1.3 uses PSA crypto for cryptographic operations that are - * directly performed by TLS 1.3 code. As a consequence, when TLS 1.3 - * is enabled, a TLS handshake may call psa_crypto_init(), even - * if it ends up negotiating a different TLS version. - * - * \note Cryptographic operations performed indirectly via another module - * (X.509, PK) or by code shared with TLS 1.2 (record protection, - * running handshake hash) only use PSA crypto if - * #MBEDTLS_USE_PSA_CRYPTO is enabled. - * - * \note In multithreaded applications, you must also enable - * #MBEDTLS_THREADING_C, even if individual TLS contexts are not - * shared between threads, unless only one thread ever calls - * TLS functions. - * - * Uncomment this macro to enable the support for TLS 1.3. - */ -#define MBEDTLS_SSL_PROTO_TLS1_3 - -/** - * \def MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE - * - * Enable TLS 1.3 middlebox compatibility mode. - * - * As specified in Section D.4 of RFC 8446, TLS 1.3 offers a compatibility - * mode to make a TLS 1.3 connection more likely to pass through middle boxes - * expecting TLS 1.2 traffic. - * - * Turning on the compatibility mode comes at the cost of a few added bytes - * on the wire, but it doesn't affect compatibility with TLS 1.3 implementations - * that don't use it. Therefore, unless transmission bandwidth is critical and - * you know that middlebox compatibility issues won't occur, it is therefore - * recommended to set this option. - * - * Comment to disable compatibility mode for TLS 1.3. If - * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any - * effect on the build. - * - */ -#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE - -/** - * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED - * - * Enable TLS 1.3 PSK key exchange mode. - * - * Comment to disable support for the PSK key exchange mode in TLS 1.3. If - * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any - * effect on the build. - * - */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED - -/** - * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED - * - * Enable TLS 1.3 ephemeral key exchange mode. - * - * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH - * MBEDTLS_X509_CRT_PARSE_C - * and at least one of: - * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) - * MBEDTLS_PKCS1_V21 - * - * Comment to disable support for the ephemeral key exchange mode in TLS 1.3. - * If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any - * effect on the build. - * - */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED - -/** - * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED - * - * Enable TLS 1.3 PSK ephemeral key exchange mode. - * - * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH - * - * Comment to disable support for the PSK ephemeral key exchange mode in - * TLS 1.3. If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not - * have any effect on the build. - * - */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED - -/** - * \def MBEDTLS_SSL_EARLY_DATA - * - * Enable support for RFC 8446 TLS 1.3 early data. - * - * Requires: MBEDTLS_SSL_SESSION_TICKETS and either - * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or - * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED - * - * Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3 - * is not enabled, this option does not have any effect on the build. - * - * \note The maximum amount of early data can be set with - * MBEDTLS_SSL_MAX_EARLY_DATA_SIZE. - * - */ -//#define MBEDTLS_SSL_EARLY_DATA - -/** - * \def MBEDTLS_SSL_PROTO_DTLS - * - * Enable support for DTLS (all available versions). - * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for DTLS - */ -#define MBEDTLS_SSL_PROTO_DTLS - -/** - * \def MBEDTLS_SSL_ALPN - * - * Enable support for RFC 7301 Application Layer Protocol Negotiation. - * - * Comment this macro to disable support for ALPN. - */ -#define MBEDTLS_SSL_ALPN - -/** - * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY - * - * Enable support for the anti-replay mechanism in DTLS. - * - * Requires: MBEDTLS_SSL_TLS_C - * MBEDTLS_SSL_PROTO_DTLS - * - * \warning Disabling this is often a security risk! - * See mbedtls_ssl_conf_dtls_anti_replay() for details. - * - * Comment this to disable anti-replay in DTLS. - */ -#define MBEDTLS_SSL_DTLS_ANTI_REPLAY - -/** - * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Enable support for HelloVerifyRequest on DTLS servers. - * - * This feature is highly recommended to prevent DTLS servers being used as - * amplifiers in DoS attacks against other hosts. It should always be enabled - * unless you know for sure amplification cannot be a problem in the - * environment in which your server operates. - * - * \warning Disabling this can be a security risk! (see above) - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Comment this to disable support for HelloVerifyRequest. - */ -#define MBEDTLS_SSL_DTLS_HELLO_VERIFY - -/** - * \def MBEDTLS_SSL_DTLS_SRTP - * - * Enable support for negotiation of DTLS-SRTP (RFC 5764) - * through the use_srtp extension. - * - * \note This feature provides the minimum functionality required - * to negotiate the use of DTLS-SRTP and to allow the derivation of - * the associated SRTP packet protection key material. - * In particular, the SRTP packet protection itself, as well as the - * demultiplexing of RTP and DTLS packets at the datagram layer - * (see Section 5 of RFC 5764), are not handled by this feature. - * Instead, after successful completion of a handshake negotiating - * the use of DTLS-SRTP, the extended key exporter API - * mbedtls_ssl_conf_export_keys_cb() should be used to implement - * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 - * (this is implemented in the SSL example programs). - * The resulting key should then be passed to an SRTP stack. - * - * Setting this option enables the runtime API - * mbedtls_ssl_conf_dtls_srtp_protection_profiles() - * through which the supported DTLS-SRTP protection - * profiles can be configured. You must call this API at - * runtime if you wish to negotiate the use of DTLS-SRTP. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Uncomment this to enable support for use_srtp extension. - */ -//#define MBEDTLS_SSL_DTLS_SRTP - -/** - * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - * - * Enable server-side support for clients that reconnect from the same port. - * - * Some clients unexpectedly close the connection and try to reconnect using the - * same source port. This needs special support from the server to handle the - * new connection securely, as described in section 4.2.8 of RFC 6347. This - * flag enables that support. - * - * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Comment this to disable support for clients reusing the source port. - */ -#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - -/** - * \def MBEDTLS_SSL_SESSION_TICKETS - * - * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintenance of a - * session store remains the responsibility of the application, though). - * Server-side, you also need to provide callbacks for writing and parsing - * tickets, including authenticated encryption and key management. Example - * callbacks are provided by MBEDTLS_SSL_TICKET_C. - * - * Comment this macro to disable support for SSL session tickets - */ -#define MBEDTLS_SSL_SESSION_TICKETS - -/** - * \def MBEDTLS_SSL_SERVER_NAME_INDICATION - * - * Enable support for RFC 6066 server name indication (SNI) in SSL. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Comment this macro to disable support for server name indication in SSL - */ -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -/** - * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - * - * When this option is enabled, the SSL buffer will be resized automatically - * based on the negotiated maximum fragment length in each direction. - * - * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - */ -//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - * - * Enable testing of the constant-flow nature of some sensitive functions with - * clang's MemorySanitizer. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires compiling with clang -fsanitize=memory. The test - * suites can then be run normally. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - * - * Enable testing of the constant-flow nature of some sensitive functions with - * valgrind's memcheck tool. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires valgrind headers for building, and is only useful for - * testing if the tests suites are run with valgrind's memcheck. This can be - * done for an individual test suite with 'valgrind ./test_suite_xxx', or when - * using CMake, this can be done for all test suites with 'make memcheck'. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - -/** - * \def MBEDTLS_TEST_HOOKS - * - * Enable features for invasive testing such as introspection functions and - * hooks for fault injection. This enables additional unit tests. - * - * Merely enabling this feature should not change the behavior of the product. - * It only adds new code, and new branching points where the default behavior - * is the same as when this feature is disabled. - * However, this feature increases the attack surface: there is an added - * risk of vulnerabilities, and more gadgets that can make exploits easier. - * Therefore this feature must never be enabled in production. - * - * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more - * information. - * - * Uncomment to enable invasive tests. - */ -//#define MBEDTLS_TEST_HOOKS - -/** - * \def MBEDTLS_THREADING_ALT - * - * Provide your own alternate implementation of threading primitives - * for mutexes. If you enable this option: - * - * - Provide a header file `"threading_alt.h"`, defining the - * type `mbedtls_threading_mutex_t` of mutex objects. - * - * - Call the function mbedtls_threading_set_alt() in your application - * before calling any other library function (in particular before - * calling psa_crypto_init(), performing an asymmetric cryptography - * operation, or starting a TLS connection). - * - * See mbedtls/threading.h for more details, especially the documentation - * of mbedtls_threading_set_alt(). - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to allow your own alternate threading implementation. - */ -//#define MBEDTLS_THREADING_ALT - -/** - * \def MBEDTLS_THREADING_PTHREAD - * - * Enable the pthread wrapper layer for the threading layer. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to enable pthread mutexes. - */ -//#define MBEDTLS_THREADING_PTHREAD - -/** - * \def MBEDTLS_USE_PSA_CRYPTO - * - * Make the X.509 and TLS libraries use PSA for cryptographic operations as - * much as possible, and enable new APIs for using keys handled by PSA Crypto. - * - * \note Development of this option is currently in progress, and parts of Mbed - * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts - * will still continue to work as usual, so enabling this option should not - * break backwards compatibility. - * - * \warning If you enable this option, you need to call `psa_crypto_init()` - * before calling any function from the SSL/TLS, X.509 or PK modules, except - * for the various mbedtls_xxx_init() functions which can be called at any time. - * - * \warning In multithreaded applications, you must also enable - * #MBEDTLS_THREADING_C, unless only one thread ever calls PSA functions - * (`psa_xxx()`), including indirect calls through SSL/TLS, X.509 or PK. - * - * \note An important and desirable effect of this option is that it allows - * PK, X.509 and TLS to take advantage of PSA drivers. For example, enabling - * this option is what allows use of drivers for ECDSA, ECDH and EC J-PAKE in - * those modules. However, note that even with this option disabled, some code - * in PK, X.509, TLS or the crypto library might still use PSA drivers, if it - * can determine it's safe to do so; currently that's the case for hashes. - * - * \note See docs/use-psa-crypto.md for a complete description this option. - * - * Requires: MBEDTLS_PSA_CRYPTO_C. - * - * Uncomment this to enable internal use of PSA Crypto and new associated APIs. - */ -//#define MBEDTLS_USE_PSA_CRYPTO - -/** - * \def MBEDTLS_PSA_CRYPTO_CONFIG - * - * This setting allows support for cryptographic mechanisms through the PSA - * API to be configured separately from support through the mbedtls API. - * - * When this option is disabled, the PSA API exposes the cryptographic - * mechanisms that can be implemented on top of the `mbedtls_xxx` API - * configured with `MBEDTLS_XXX` symbols. - * - * When this option is enabled, the PSA API exposes the cryptographic - * mechanisms requested by the `PSA_WANT_XXX` symbols defined in - * include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are - * automatically enabled if required (i.e. if no PSA driver provides the - * mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols - * in mbedtls_config.h. - * - * If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies - * an alternative header to include instead of include/psa/crypto_config.h. - * - * \warning This option is experimental, in that the set of `PSA_WANT_XXX` - * symbols is not completely finalized yet, and the configuration - * tooling is not ideally adapted to having two separate configuration - * files. - * Future minor releases of Mbed TLS may make minor changes to those - * symbols, but we will endeavor to provide a transition path. - * Nonetheless, this option is considered mature enough to use in - * production, as long as you accept that you may need to make - * minor changes to psa/crypto_config.h when upgrading Mbed TLS. - */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG - -/** - * \def MBEDTLS_VERSION_FEATURES - * - * Allow run-time checking of compile-time enabled features. Thus allowing users - * to check at run-time if the library is for instance compiled with threading - * support via mbedtls_version_check_feature(). - * - * Requires: MBEDTLS_VERSION_C - * - * Comment this to disable run-time checking and save ROM space - */ -#define MBEDTLS_VERSION_FEATURES - -/** - * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK - * - * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()` - * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure - * the set of trusted certificates through a callback instead of a linked - * list. - * - * This is useful for example in environments where a large number of trusted - * certificates is present and storing them in a linked list isn't efficient - * enough, or when the set of trusted certificates changes frequently. - * - * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and - * `mbedtls_ssl_conf_ca_cb()` for more information. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Uncomment to enable trusted certificate callbacks. - */ -//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK - -/** - * \def MBEDTLS_X509_REMOVE_INFO - * - * Disable mbedtls_x509_*_info() and related APIs. - * - * Uncomment to omit mbedtls_x509_*_info(), as well as mbedtls_debug_print_crt() - * and other functions/constants only used by these functions, thus reducing - * the code footprint by several KB. - */ -//#define MBEDTLS_X509_REMOVE_INFO - -/** - * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT - * - * Enable parsing and verification of X.509 certificates, CRLs and CSRS - * signed with RSASSA-PSS (aka PKCS#1 v2.1). - * - * Requires: MBEDTLS_PKCS1_V21 - * - * Comment this macro to disallow using RSASSA-PSS in certificates. - */ -#define MBEDTLS_X509_RSASSA_PSS_SUPPORT -/** \} name SECTION: Mbed TLS feature support */ - -/** - * \name SECTION: Mbed TLS modules - * - * This section enables or disables entire modules in Mbed TLS - * \{ - */ - -/** - * \def MBEDTLS_AESNI_C - * - * Enable AES-NI support on x86-64 or x86-32. - * - * \note AESNI is only supported with certain compilers and target options: - * - Visual Studio: supported - * - GCC, x86-64, target not explicitly supporting AESNI: - * requires MBEDTLS_HAVE_ASM. - * - GCC, x86-32, target not explicitly supporting AESNI: - * not supported. - * - GCC, x86-64 or x86-32, target supporting AESNI: supported. - * For this assembly-less implementation, you must currently compile - * `library/aesni.c` and `library/aes.c` with machine options to enable - * SSE2 and AESNI instructions: `gcc -msse2 -maes -mpclmul` or - * `clang -maes -mpclmul`. - * - Non-x86 targets: this option is silently ignored. - * - Other compilers: this option is silently ignored. - * - * \note - * Above, "GCC" includes compatible compilers such as Clang. - * The limitations on target support are likely to be relaxed in the future. - * - * Module: library/aesni.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM (on some platforms, see note) - * - * This modules adds support for the AES-NI instructions on x86. - */ -#define MBEDTLS_AESNI_C - -/** - * \def MBEDTLS_AESCE_C - * - * Enable AES cryptographic extension support on Armv8. - * - * Module: library/aesce.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_AES_C - * - * \warning Runtime detection only works on Linux. For non-Linux operating - * system, Armv8-A Cryptographic Extensions must be supported by - * the CPU when this option is enabled. - * - * \note Minimum compiler versions for this feature when targeting aarch64 - * are Clang 4.0; armclang 6.6; GCC 6.0; or MSVC 2019 version 16.11.2. - * Minimum compiler versions for this feature when targeting 32-bit - * Arm or Thumb are Clang 11.0; armclang 6.20; or GCC 6.0. - * - * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for - * armclang <= 6.9 - * - * This module adds support for the AES Armv8-A Cryptographic Extensions on Armv8 systems. - */ -#define MBEDTLS_AESCE_C - -/** - * \def MBEDTLS_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/cipher.c - * library/pem.c - * library/ctr_drbg.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * - * PEM_PARSE uses AES for decrypting encrypted keys. - */ -#define MBEDTLS_AES_C - -/** - * \def MBEDTLS_ASN1_PARSE_C - * - * Enable the generic ASN1 parser. - * - * Module: library/asn1.c - * Caller: library/x509.c - * library/dhm.c - * library/pkcs12.c - * library/pkcs5.c - * library/pkparse.c - */ -#define MBEDTLS_ASN1_PARSE_C - -/** - * \def MBEDTLS_ASN1_WRITE_C - * - * Enable the generic ASN1 writer. - * - * Module: library/asn1write.c - * Caller: library/ecdsa.c - * library/pkwrite.c - * library/x509_create.c - * library/x509write_crt.c - * library/x509write_csr.c - */ -#define MBEDTLS_ASN1_WRITE_C - -/** - * \def MBEDTLS_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -#define MBEDTLS_BASE64_C - -/** - * \def MBEDTLS_BLOCK_CIPHER_NO_DECRYPT - * - * Remove decryption operation for AES, ARIA and Camellia block cipher. - * - * \note This feature is incompatible with insecure block cipher, - * MBEDTLS_DES_C, and cipher modes which always require decryption - * operation, MBEDTLS_CIPHER_MODE_CBC, MBEDTLS_CIPHER_MODE_XTS and - * MBEDTLS_NIST_KW_C. When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, - * this feature is incompatible with following supported PSA equivalence, - * PSA_WANT_ALG_ECB_NO_PADDING, PSA_WANT_ALG_CBC_NO_PADDING, - * PSA_WANT_ALG_CBC_PKCS7 and PSA_WANT_KEY_TYPE_DES. - * - * Module: library/aes.c - * library/aesce.c - * library/aesni.c - * library/aria.c - * library/camellia.c - * library/cipher.c - */ -//#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT - -/** - * \def MBEDTLS_BIGNUM_C - * - * Enable the multi-precision integer library. - * - * Module: library/bignum.c - * library/bignum_core.c - * library/bignum_mod.c - * library/bignum_mod_raw.c - * Caller: library/dhm.c - * library/ecp.c - * library/ecdsa.c - * library/rsa.c - * library/rsa_alt_helpers.c - * library/ssl_tls.c - * - * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. - */ -#define MBEDTLS_BIGNUM_C - -/** - * \def MBEDTLS_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_CAMELLIA_C - -/** - * \def MBEDTLS_ARIA_C - * - * Enable the ARIA block cipher. - * - * Module: library/aria.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * - * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 - */ -#define MBEDTLS_ARIA_C - -/** - * \def MBEDTLS_CCM_C - * - * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. - * - * Module: library/ccm.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or - * MBEDTLS_ARIA_C - * - * This module enables the AES-CCM ciphersuites, if other requisites are - * enabled as well. - */ -#define MBEDTLS_CCM_C - -/** - * \def MBEDTLS_CHACHA20_C - * - * Enable the ChaCha20 stream cipher. - * - * Module: library/chacha20.c - */ -#define MBEDTLS_CHACHA20_C - -/** - * \def MBEDTLS_CHACHAPOLY_C - * - * Enable the ChaCha20-Poly1305 AEAD algorithm. - * - * Module: library/chachapoly.c - * - * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C - */ -#define MBEDTLS_CHACHAPOLY_C - -/** - * \def MBEDTLS_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ccm.c - * library/cmac.c - * library/gcm.c - * library/nist_kw.c - * library/pkcs12.c - * library/pkcs5.c - * library/psa_crypto_aead.c - * library/psa_crypto_mac.c - * library/ssl_ciphersuites.c - * library/ssl_msg.c - * library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled) - * Auto-enabled by: MBEDTLS_PSA_CRYPTO_C depending on which ciphers are enabled - * (see the documentation of that option for details). - * - * Uncomment to enable generic cipher wrappers. - */ -#define MBEDTLS_CIPHER_C - -/** - * \def MBEDTLS_CMAC_C - * - * Enable the CMAC (Cipher-based Message Authentication Code) mode for block - * ciphers. - * - * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying - * implementation of the CMAC algorithm is provided by an alternate - * implementation, that alternate implementation may opt to not support - * AES-192 or 3DES as underlying block ciphers for the CMAC operation. - * - * Module: library/cmac.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_DES_C - * - */ -#define MBEDTLS_CMAC_C - -/** - * \def MBEDTLS_CTR_DRBG_C - * - * Enable the CTR_DRBG AES-based random generator. - * The CTR_DRBG generator uses AES-256 by default. - * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. - * - * AES support can either be achieved through builtin (MBEDTLS_AES_C) or PSA. - * Builtin is the default option when MBEDTLS_AES_C is defined otherwise PSA - * is used. - * - * \warning When using PSA, the user should call `psa_crypto_init()` before - * using any CTR_DRBG operation (except `mbedtls_ctr_drbg_init()`). - * - * \note AES-128 will be used if \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set. - * - * \note To achieve a 256-bit security strength with CTR_DRBG, - * you must use AES-256 *and* use sufficient entropy. - * See ctr_drbg.h for more details. - * - * Module: library/ctr_drbg.c - * Caller: - * - * Requires: MBEDTLS_AES_C or - * (PSA_WANT_KEY_TYPE_AES and PSA_WANT_ALG_ECB_NO_PADDING and - * MBEDTLS_PSA_CRYPTO_C) - * - * This module provides the CTR_DRBG AES random number generator. - */ -#define MBEDTLS_CTR_DRBG_C - -/** - * \def MBEDTLS_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_msg.c - * library/ssl_tls.c - * library/ssl_tls12_*.c - * library/ssl_tls13_*.c - * - * This module provides debugging functions. - */ -#define MBEDTLS_DEBUG_C - -/** - * \def MBEDTLS_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/pem.c - * library/cipher.c - * - * PEM_PARSE uses DES/3DES for decrypting encrypted keys. - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -#define MBEDTLS_DES_C - -/** - * \def MBEDTLS_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_DHM_C - -/** - * \def MBEDTLS_ECDH_C - * - * Enable the elliptic curve Diffie-Hellman library. - * - * Module: library/ecdh.c - * Caller: library/psa_crypto.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK - * - * Requires: MBEDTLS_ECP_C - */ -#define MBEDTLS_ECDH_C - -/** - * \def MBEDTLS_ECDSA_C - * - * Enable the elliptic curve DSA library. - * - * Module: library/ecdsa.c - * Caller: - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C, - * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a - * short Weierstrass curve. - */ -#define MBEDTLS_ECDSA_C - -/** - * \def MBEDTLS_ECJPAKE_C - * - * Enable the elliptic curve J-PAKE library. - * - * \note EC J-PAKE support is based on the Thread v1.0.0 specification. - * It has not been reviewed for compliance with newer standards such as - * Thread v1.1 or RFC 8236. - * - * Module: library/ecjpake.c - * Caller: - * - * This module is used by the following key exchanges: - * ECJPAKE - * - * Requires: MBEDTLS_ECP_C and either MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C - * - * \warning If using a hash that is only provided by PSA drivers, you must - * call psa_crypto_init() before doing any EC J-PAKE operations. - */ -#define MBEDTLS_ECJPAKE_C - -/** - * \def MBEDTLS_ECP_C - * - * Enable the elliptic curve over GF(p) library. - * - * Module: library/ecp.c - * Caller: library/ecdh.c - * library/ecdsa.c - * library/ecjpake.c - * - * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED - */ -#define MBEDTLS_ECP_C - -/** - * \def MBEDTLS_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C - * - * This module provides a generic entropy pool - */ -#define MBEDTLS_ENTROPY_C - -/** - * \def MBEDTLS_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables mbedtls_strerror(). - */ -#define MBEDTLS_ERROR_C - -/** - * \def MBEDTLS_GCM_C - * - * Enable the Galois/Counter Mode (GCM). - * - * Module: library/gcm.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or - * MBEDTLS_ARIA_C - * - * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other - * requisites are enabled as well. - */ -#define MBEDTLS_GCM_C - -/** - * \def MBEDTLS_GCM_LARGE_TABLE - * - * Enable large pre-computed tables for Galois/Counter Mode (GCM). - * Can significantly increase throughput on systems without GCM hardware - * acceleration (e.g., AESNI, AESCE). - * - * The mbedtls_gcm_context size will increase by 3840 bytes. - * The code size will increase by roughly 344 bytes. - * - * Module: library/gcm.c - * - * Requires: MBEDTLS_GCM_C - */ -//#define MBEDTLS_GCM_LARGE_TABLE - -/** - * \def MBEDTLS_HKDF_C - * - * Enable the HKDF algorithm (RFC 5869). - * - * Module: library/hkdf.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the Hashed Message Authentication Code - * (HMAC)-based key derivation function (HKDF). - */ -#define MBEDTLS_HKDF_C - -/** - * \def MBEDTLS_HMAC_DRBG_C - * - * Enable the HMAC_DRBG random generator. - * - * Module: library/hmac_drbg.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * Uncomment to enable the HMAC_DRBG random number generator. - */ -#define MBEDTLS_HMAC_DRBG_C - -/** - * \def MBEDTLS_LMS_C - * - * Enable the LMS stateful-hash asymmetric signature algorithm. - * - * Module: library/lms.c - * Caller: - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * Uncomment to enable the LMS verification algorithm and public key operations. - */ -#define MBEDTLS_LMS_C - -/** - * \def MBEDTLS_LMS_PRIVATE - * - * Enable LMS private-key operations and signing code. Functions enabled by this - * option are experimental, and should not be used in production. - * - * Requires: MBEDTLS_LMS_C - * - * Uncomment to enable the LMS signature algorithm and private key operations. - */ -//#define MBEDTLS_LMS_PRIVATE - -/** - * \def MBEDTLS_NIST_KW_C - * - * Enable the Key Wrapping mode for 128-bit block ciphers, - * as defined in NIST SP 800-38F. Only KW and KWP modes - * are supported. At the moment, only AES is approved by NIST. - * - * Module: library/nist_kw.c - * - * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C - */ -#define MBEDTLS_NIST_KW_C - -/** - * \def MBEDTLS_MD_C - * - * Enable the generic layer for message digest (hashing) and HMAC. - * - * Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C, - * MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C, - * MBEDTLS_SHA512_C, or MBEDTLS_PSA_CRYPTO_C with at least - * one hash. - * Module: library/md.c - * Caller: library/constant_time.c - * library/ecdsa.c - * library/ecjpake.c - * library/hkdf.c - * library/hmac_drbg.c - * library/pk.c - * library/pkcs5.c - * library/pkcs12.c - * library/psa_crypto_ecp.c - * library/psa_crypto_rsa.c - * library/rsa.c - * library/ssl_cookie.c - * library/ssl_msg.c - * library/ssl_tls.c - * library/x509.c - * library/x509_crt.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Uncomment to enable generic message digest wrappers. - */ -#define MBEDTLS_MD_C - -/** - * \def MBEDTLS_MD5_C - * - * Enable the MD5 hash algorithm. - * - * Module: library/md5.c - * Caller: library/md.c - * library/pem.c - * library/ssl_tls.c - * - * This module is required for TLS 1.2 depending on the handshake parameters. - * Further, it is used for checking MD5-signed certificates, and for PBKDF1 - * when decrypting PEM-encoded encrypted keys. - * - * \warning MD5 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_MD5_C - -/** - * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Enable the buffer allocator implementation that makes use of a (stack) - * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() - * calls) - * - * Module: library/memory_buffer_alloc.c - * - * Requires: MBEDTLS_PLATFORM_C - * MBEDTLS_PLATFORM_MEMORY (to use it within Mbed TLS) - * - * Enable this module to enable the buffer memory allocator. - */ -//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C - -/** - * \def MBEDTLS_NET_C - * - * Enable the TCP and UDP over IPv6/IPv4 networking routines. - * - * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) - * and Windows. For other platforms, you'll want to disable it, and write your - * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/net_sockets.c - * - * This module provides networking routines. - */ -#define MBEDTLS_NET_C - -/** - * \def MBEDTLS_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#define MBEDTLS_OID_C - -/** - * \def MBEDTLS_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the VIA PadLock on x86. - */ -#define MBEDTLS_PADLOCK_C - -/** - * \def MBEDTLS_PEM_PARSE_C - * - * Enable PEM decoding / parsing. - * - * Module: library/pem.c - * Caller: library/dhm.c - * library/pkparse.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_BASE64_C - * optionally MBEDTLS_MD5_C, or PSA Crypto with MD5 (see below) - * - * \warning When parsing password-protected files, if MD5 is provided only by - * a PSA driver, you must call psa_crypto_init() before the first file. - * - * This modules adds support for decoding / parsing PEM files. - */ -#define MBEDTLS_PEM_PARSE_C - -/** - * \def MBEDTLS_PEM_WRITE_C - * - * Enable PEM encoding / writing. - * - * Module: library/pem.c - * Caller: library/pkwrite.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for encoding / writing PEM files. - */ -#define MBEDTLS_PEM_WRITE_C - -/** - * \def MBEDTLS_PK_C - * - * Enable the generic public (asymmetric) key layer. - * - * Module: library/pk.c - * Caller: library/psa_crypto_rsa.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * library/x509.c - * - * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C or MBEDTLS_ECP_C - * - * Uncomment to enable generic public key wrappers. - */ -#define MBEDTLS_PK_C - -/** - * \def MBEDTLS_PK_PARSE_C - * - * Enable the generic public (asymmetric) key parser. - * - * Module: library/pkparse.c - * Caller: library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_C - * - * Uncomment to enable generic public key parse functions. - */ -#define MBEDTLS_PK_PARSE_C - -/** - * \def MBEDTLS_PK_WRITE_C - * - * Enable the generic public (asymmetric) key writer. - * - * Module: library/pkwrite.c - * Caller: library/x509write.c - * - * Requires: MBEDTLS_ASN1_WRITE_C, MBEDTLS_OID_C, MBEDTLS_PK_C - * - * Uncomment to enable generic public key write functions. - */ -#define MBEDTLS_PK_WRITE_C - -/** - * \def MBEDTLS_PKCS5_C - * - * Enable PKCS#5 functions. - * - * Module: library/pkcs5.c - * - * Auto-enables: MBEDTLS_MD_C - * - * \warning If using a hash that is only provided by PSA drivers, you must - * call psa_crypto_init() before doing any PKCS5 operations. - * - * This module adds support for the PKCS#5 functions. - */ -#define MBEDTLS_PKCS5_C - -/** - * \def MBEDTLS_PKCS7_C - * - * Enable PKCS #7 core for using PKCS #7-formatted signatures. - * RFC Link - https://tools.ietf.org/html/rfc2315 - * - * Module: library/pkcs7.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, - * MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C, - * MBEDTLS_BIGNUM_C, MBEDTLS_MD_C - * - * This module is required for the PKCS #7 parsing modules. - */ -#define MBEDTLS_PKCS7_C - -/** - * \def MBEDTLS_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: MBEDTLS_ASN1_PARSE_C and either MBEDTLS_MD_C or - * MBEDTLS_PSA_CRYPTO_C. - * - * \warning If using a hash that is only provided by PSA drivers, you must - * call psa_crypto_init() before doing any PKCS12 operations. - * - * This module enables PKCS#12 functions. - */ -#define MBEDTLS_PKCS12_C - -/** - * \def MBEDTLS_PLATFORM_C - * - * Enable the platform abstraction layer that allows you to re-assign - * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). - * - * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT - * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned - * above to be specified at runtime or compile time respectively. - * - * \note This abstraction layer must be enabled on Windows (including MSYS2) - * as other modules rely on it for a fixed snprintf implementation. - * - * Module: library/platform.c - * Caller: Most other .c files - * - * This module enables abstraction of common (libc) functions. - */ -#define MBEDTLS_PLATFORM_C - -/** - * \def MBEDTLS_POLY1305_C - * - * Enable the Poly1305 MAC algorithm. - * - * Module: library/poly1305.c - * Caller: library/chachapoly.c - */ -#define MBEDTLS_POLY1305_C - -/** - * \def MBEDTLS_PSA_CRYPTO_C - * - * Enable the Platform Security Architecture (PSA) cryptography API. - * - * \note In multithreaded applications, you must enable #MBEDTLS_THREADING_C, - * unless only one thread ever calls `psa_xxx()` functions. - * That includes indirect calls, such as: - * - performing a TLS handshake if support for TLS 1.3 is enabled; - * - using a TLS 1.3 connection; - * - indirect calls from PK, X.509 or SSL functions when - * #MBEDTLS_USE_PSA_CRYPTO is enabled; - * - indirect calls to calculate a hash when #MBEDTLS_MD_C is disabled; - * - any other call to a function that requires calling psa_crypto_init() - * beforehand. - * - * Module: library/psa_crypto.c - * - * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, - * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, - * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. - * Auto-enables: MBEDTLS_CIPHER_C if any unauthenticated (ie, non-AEAD) cipher - * is enabled in PSA (unless it's fully accelerated, see - * docs/driver-only-builds.md about that). - */ -#define MBEDTLS_PSA_CRYPTO_C - -/** - * \def MBEDTLS_PSA_CRYPTO_SE_C - * - * Enable dynamic secure element support in the Platform Security Architecture - * cryptography API. - * - * \deprecated This feature is deprecated. Please switch to the PSA driver - * interface. - * - * \warning This feature is not thread-safe, and should not be used in a - * multi-threaded environment. - * - * Module: library/psa_crypto_se.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C - * - */ -//#define MBEDTLS_PSA_CRYPTO_SE_C - -/** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_C - * - * Enable the Platform Security Architecture persistent key storage. - * - * Module: library/psa_crypto_storage.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, - * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of - * the PSA ITS interface - */ -#define MBEDTLS_PSA_CRYPTO_STORAGE_C - -/** - * \def MBEDTLS_PSA_ITS_FILE_C - * - * Enable the emulation of the Platform Security Architecture - * Internal Trusted Storage (PSA ITS) over files. - * - * Module: library/psa_its_file.c - * - * Requires: MBEDTLS_FS_IO - */ -#define MBEDTLS_PSA_ITS_FILE_C - -/** - * \def MBEDTLS_PSA_STATIC_KEY_SLOTS - * - * Statically preallocate memory to store keys' material in PSA instead - * of allocating it dynamically when required. This allows builds without a - * heap, if none of the enabled cryptographic implementations or other features - * require it. - * This feature affects both volatile and persistent keys which means that - * it's not possible to persistently store a key which is larger than - * #MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE. - * - * \note This feature comes with a (potentially) higher RAM usage since: - * - All the key slots are allocated no matter if they are used or not. - * - Each key buffer's length is #MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE bytes. - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - */ -//#define MBEDTLS_PSA_STATIC_KEY_SLOTS - -/** - * \def MBEDTLS_RIPEMD160_C - * - * Enable the RIPEMD-160 hash algorithm. - * - * Module: library/ripemd160.c - * Caller: library/md.c - * - */ -#define MBEDTLS_RIPEMD160_C - -/** - * \def MBEDTLS_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * library/rsa_alt_helpers.c - * Caller: library/pk.c - * library/psa_crypto.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module is used by the following key exchanges: - * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C - */ -#define MBEDTLS_RSA_C - -/** - * \def MBEDTLS_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/sha1.c - * Caller: library/md.c - * library/psa_crypto_hash.c - * - * This module is required for TLS 1.2 depending on the handshake parameters, - * and for SHA1-signed certificates. - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_SHA1_C - -/** - * \def MBEDTLS_SHA224_C - * - * Enable the SHA-224 cryptographic hash algorithm. - * - * Module: library/sha256.c - * Caller: library/md.c - * library/ssl_cookie.c - * - * This module adds support for SHA-224. - */ -#define MBEDTLS_SHA224_C - -/** - * \def MBEDTLS_SHA256_C - * - * Enable the SHA-256 cryptographic hash algorithm. - * - * Module: library/sha256.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module adds support for SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. - */ -#define MBEDTLS_SHA256_C - -/** - * \def MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT - * - * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions if they are available at runtime. - * If not, the library will fall back to the C implementation. - * - * \note If MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT is defined when building - * for a non-Armv8-A build it will be silently ignored. - * - * \note Minimum compiler versions for this feature are Clang 4.0, - * armclang 6.6 or GCC 6.0. - * - * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for - * armclang <= 6.9 - * - * \note This was previously known as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT. - * That name is deprecated, but may still be used as an alternative form for this - * option. - * - * \warning MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT cannot be defined at the - * same time as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY. - * - * Requires: MBEDTLS_SHA256_C. - * - * Module: library/sha256.c - * - * Uncomment to have the library check for the Armv8-A SHA-256 crypto extensions - * and use them if available. - */ -//#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT - -/** - * \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT - * - * \deprecated This is now known as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT. - * This name is now deprecated, but may still be used as an alternative form for - * this option. - */ -//#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT - -/** - * \def MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY - * - * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions, which must be available at runtime - * or else an illegal instruction fault will occur. - * - * \note This allows builds with a smaller code size than with - * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT - * - * \note Minimum compiler versions for this feature are Clang 4.0, - * armclang 6.6 or GCC 6.0. - * - * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for - * armclang <= 6.9 - * - * \note This was previously known as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY. - * That name is deprecated, but may still be used as an alternative form for this - * option. - * - * \warning MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY cannot be defined at the same - * time as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT. - * - * Requires: MBEDTLS_SHA256_C. - * - * Module: library/sha256.c - * - * Uncomment to have the library use the Armv8-A SHA-256 crypto extensions - * unconditionally. - */ -//#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY - -/** - * \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY - * - * \deprecated This is now known as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY. - * This name is now deprecated, but may still be used as an alternative form for - * this option. - */ -//#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY - -/** - * \def MBEDTLS_SHA384_C - * - * Enable the SHA-384 cryptographic hash algorithm. - * - * Module: library/sha512.c - * Caller: library/md.c - * library/psa_crypto_hash.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * Comment to disable SHA-384 - */ -#define MBEDTLS_SHA384_C - -/** - * \def MBEDTLS_SHA512_C - * - * Enable SHA-512 cryptographic hash algorithms. - * - * Module: library/sha512.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_tls.c - * library/ssl_cookie.c - * - * This module adds support for SHA-512. - */ -#define MBEDTLS_SHA512_C - -/** - * \def MBEDTLS_SHA3_C - * - * Enable the SHA3 cryptographic hash algorithm. - * - * Module: library/sha3.c - * - * This module adds support for SHA3. - */ -#define MBEDTLS_SHA3_C - -/** - * \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT - * - * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions if they are available at runtime. - * If not, the library will fall back to the C implementation. - * - * \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building - * for a non-Aarch64 build it will be silently ignored. - * - * \note Minimum compiler versions for this feature are Clang 7.0, - * armclang 6.9 or GCC 8.0. - * - * \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for - * armclang 6.9 - * - * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the - * same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY. - * - * Requires: MBEDTLS_SHA512_C. - * - * Module: library/sha512.c - * - * Uncomment to have the library check for the A64 SHA-512 crypto extensions - * and use them if available. - */ -//#define MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT - -/** - * \def MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY - * - * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions, which must be available at runtime - * or else an illegal instruction fault will occur. - * - * \note This allows builds with a smaller code size than with - * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT - * - * \note Minimum compiler versions for this feature are Clang 7.0, - * armclang 6.9 or GCC 8.0. - * - * \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for - * armclang 6.9 - * - * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same - * time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT. - * - * Requires: MBEDTLS_SHA512_C. - * - * Module: library/sha512.c - * - * Uncomment to have the library use the A64 SHA-512 crypto extensions - * unconditionally. - */ -//#define MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY - -/** - * \def MBEDTLS_SSL_CACHE_C - * - * Enable simple SSL cache implementation. - * - * Module: library/ssl_cache.c - * Caller: - * - * Requires: MBEDTLS_SSL_CACHE_C - */ -#define MBEDTLS_SSL_CACHE_C - -/** - * \def MBEDTLS_SSL_COOKIE_C - * - * Enable basic implementation of DTLS cookies for hello verification. - * - * Module: library/ssl_cookie.c - * Caller: - */ -#define MBEDTLS_SSL_COOKIE_C - -/** - * \def MBEDTLS_SSL_TICKET_C - * - * Enable an implementation of TLS server-side callbacks for session tickets. - * - * Module: library/ssl_ticket.c - * Caller: - * - * Requires: (MBEDTLS_CIPHER_C || MBEDTLS_USE_PSA_CRYPTO) && - * (MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C) - */ -#define MBEDTLS_SSL_TICKET_C - -/** - * \def MBEDTLS_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl*_client.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -#define MBEDTLS_SSL_CLI_C - -/** - * \def MBEDTLS_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl*_server.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -#define MBEDTLS_SSL_SRV_C - -/** - * \def MBEDTLS_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl*_client.c - * library/ssl*_server.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * and at least one of the MBEDTLS_SSL_PROTO_XXX defines - * - * This module is required for SSL/TLS. - */ -#define MBEDTLS_SSL_TLS_C - -/** - * \def MBEDTLS_THREADING_C - * - * Enable the threading abstraction layer. - * - * Traditionally, Mbed TLS assumes it is used in a non-threaded environment or - * that contexts are not shared between threads. If you do intend to use contexts - * between threads, you will need to enable this layer to prevent race - * conditions. - * - * The PSA subsystem has an implicit shared context. Therefore, you must - * enable this option if more than one thread may use any part of - * Mbed TLS that is implemented on top of the PSA subsystem. - * - * You must enable this option in multithreaded applications where more than - * one thread performs any of the following operations: - * - * - Any call to a PSA function (`psa_xxx()`). - * - Any call to a TLS, X.509 or PK function (`mbedtls_ssl_xxx()`, - * `mbedtls_x509_xxx()`, `mbedtls_pkcs7_xxx()`, `mbedtls_pk_xxx()`) - * if `MBEDTLS_USE_PSA_CRYPTO` is enabled (regardless of whether individual - * TLS, X.509 or PK contexts are shared between threads). - * - A TLS 1.3 connection, regardless of the compile-time configuration. - * - Any library feature that calculates a hash, if `MBEDTLS_MD_C` is disabled. - * As an exception, algorithm-specific low-level modules do not require - * threading protection unless the contexts are shared between threads. - * - Any library feature that performs symmetric encryption or decryption, - * if `MBEDTLS_CIPHER_C` is disabled. - * As an exception, algorithm-specific low-level modules do not require - * threading protection unless the contexts are shared between threads. - * - Any use of a cryptographic context if the same context is used in - * multiple threads. - * - Any call to a function where the documentation specifies that - * psa_crypto_init() must be called prior to that function. - * - * See also our Knowledge Base article about threading: - * https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading - * - * Module: library/threading.c - * - * This allows different threading implementations (self-implemented or - * provided). - * - * You will have to enable either MBEDTLS_THREADING_ALT or - * MBEDTLS_THREADING_PTHREAD. - * - * Enable this layer to allow use of mutexes within Mbed TLS - */ -//#define MBEDTLS_THREADING_C - -/** - * \def MBEDTLS_TIMING_C - * - * Enable the semi-portable timing interface. - * - * \note The provided implementation only works on POSIX/Unix (including Linux, - * BSD and OS X) and Windows. On other platforms, you can either disable that - * module and provide your own implementations of the callbacks needed by - * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide - * your own implementation of the whole module by setting - * \c MBEDTLS_TIMING_ALT in the current file. - * - * \note The timing module will include time.h on suitable platforms - * regardless of the setting of MBEDTLS_HAVE_TIME, unless - * MBEDTLS_TIMING_ALT is used. See timing.c for more information. - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/timing.c - */ -#define MBEDTLS_TIMING_C - -/** - * \def MBEDTLS_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -#define MBEDTLS_VERSION_C - -/** - * \def MBEDTLS_X509_USE_C - * - * Enable X.509 core for using certificates. - * - * Module: library/x509.c - * Caller: library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, - * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) - * - * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call - * psa_crypto_init() before doing any X.509 operation. - * - * This module is required for the X.509 parsing modules. - */ -#define MBEDTLS_X509_USE_C - -/** - * \def MBEDTLS_X509_CRT_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/x509_crt.c - * Caller: library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 certificate parsing. - */ -#define MBEDTLS_X509_CRT_PARSE_C - -/** - * \def MBEDTLS_X509_CRL_PARSE_C - * - * Enable X.509 CRL parsing. - * - * Module: library/x509_crl.c - * Caller: library/x509_crt.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 CRL parsing. - */ -#define MBEDTLS_X509_CRL_PARSE_C - -/** - * \def MBEDTLS_X509_CSR_PARSE_C - * - * Enable X.509 Certificate Signing Request (CSR) parsing. - * - * Module: library/x509_csr.c - * Caller: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is used for reading X.509 certificate request. - */ -#define MBEDTLS_X509_CSR_PARSE_C - -/** - * \def MBEDTLS_X509_CREATE_C - * - * Enable X.509 core for creating certificates. - * - * Module: library/x509_create.c - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, - * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) - * - * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call - * psa_crypto_init() before doing any X.509 create operation. - * - * This module is the basis for creating X.509 certificates and CSRs. - */ -#define MBEDTLS_X509_CREATE_C - -/** - * \def MBEDTLS_X509_CRT_WRITE_C - * - * Enable creating X.509 certificates. - * - * Module: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate creation. - */ -#define MBEDTLS_X509_CRT_WRITE_C - -/** - * \def MBEDTLS_X509_CSR_WRITE_C - * - * Enable creating X.509 Certificate Signing Requests (CSR). - * - * Module: library/x509_csr_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate request writing. - */ -#define MBEDTLS_X509_CSR_WRITE_C - -/** \} name SECTION: Mbed TLS modules */ - -/** - * \name SECTION: General configuration options - * - * This section contains Mbed TLS build settings that are not associated - * with a particular module. - * - * \{ - */ - -/** - * \def MBEDTLS_CONFIG_FILE - * - * If defined, this is a header which will be included instead of - * `"mbedtls/mbedtls_config.h"`. - * This header file specifies the compile-time configuration of Mbed TLS. - * Unlike other configuration options, this one must be defined on the - * compiler command line: a definition in `mbedtls_config.h` would have - * no effect. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h" - -/** - * \def MBEDTLS_USER_CONFIG_FILE - * - * If defined, this is a header which will be included after - * `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE. - * This allows you to modify the default configuration, including the ability - * to undefine options that are enabled by default. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_USER_CONFIG_FILE "/dev/null" - -/** - * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE - * - * If defined, this is a header which will be included instead of - * `"psa/crypto_config.h"`. - * This header file specifies which cryptographic mechanisms are available - * through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and - * is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" - -/** - * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE - * - * If defined, this is a header which will be included after - * `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE. - * This allows you to modify the default configuration, including the ability - * to undefine options that are enabled by default. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" - -/** - * \def MBEDTLS_PSA_CRYPTO_PLATFORM_FILE - * - * If defined, this is a header which will be included instead of - * `"psa/crypto_platform.h"`. This file should declare the same identifiers - * as the one in Mbed TLS, but with definitions adapted to the platform on - * which the library code will run. - * - * \note The required content of this header can vary from one version of - * Mbed TLS to the next. Integrators who provide an alternative file - * should review the changes in the original file whenever they - * upgrade Mbed TLS. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_PLATFORM_FILE "psa/crypto_platform_alt.h" - -/** - * \def MBEDTLS_PSA_CRYPTO_STRUCT_FILE - * - * If defined, this is a header which will be included instead of - * `"psa/crypto_struct.h"`. This file should declare the same identifiers - * as the one in Mbed TLS, but with definitions adapted to the environment - * in which the library code will run. The typical use for this feature - * is to provide alternative type definitions on the client side in - * client-server integrations of PSA crypto, where operation structures - * contain handles instead of cryptographic data. - * - * \note The required content of this header can vary from one version of - * Mbed TLS to the next. Integrators who provide an alternative file - * should review the changes in the original file whenever they - * upgrade Mbed TLS. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_STRUCT_FILE "psa/crypto_struct_alt.h" - -/** \} name SECTION: General configuration options */ - -/** - * \name SECTION: Module configuration options - * - * This section allows for the setting of module specific sizes and - * configuration options. The default values are already present in the - * relevant header files and should suffice for the regular use cases. - * - * Our advice is to enable options and change their values here - * only if you have a good reason and know the consequences. - * \{ - */ -/* The Doxygen documentation here is used when a user comments out a - * setting and runs doxygen themselves. On the other hand, when we typeset - * the full documentation including disabled settings, the documentation - * in specific modules' header files is used if present. When editing this - * file, make sure that each option is documented in exactly one place, - * plus optionally a same-line Doxygen comment here if there is a Doxygen - * comment in the specific module. */ - -/* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ - -/* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* HMAC_DRBG options */ -//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* ECP options */ -//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */ -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ - -/* Entropy options */ -//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ - -/* Memory buffer allocator options */ -//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -/* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ - -/** \def MBEDTLS_PLATFORM_STD_CALLOC - * - * Default allocator to use, can be undefined. - * It must initialize the allocated buffer memory to zeroes. - * The size of the buffer is the product of the two parameters. - * The calloc function returns either a null pointer or a pointer to the allocated space. - * If the product is 0, the function may either return NULL or a valid pointer to an array of size 0 which is a valid input to the deallocation function. - * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. - * See the description of #MBEDTLS_PLATFORM_MEMORY for more details. - * The corresponding deallocation function is #MBEDTLS_PLATFORM_STD_FREE. - */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc - -/** \def MBEDTLS_PLATFORM_STD_FREE - * - * Default free to use, can be undefined. - * NULL is a valid parameter, and the function must do nothing. - * A non-null parameter will always be a pointer previously returned by #MBEDTLS_PLATFORM_STD_CALLOC and not yet freed. - * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. - * See the description of #MBEDTLS_PLATFORM_MEMORY for more details (same principles as for MBEDTLS_PLATFORM_STD_CALLOC apply). - */ -//#define MBEDTLS_PLATFORM_STD_FREE free -//#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ - -/* To use the following function macros, MBEDTLS_PLATFORM_C must be enabled. */ -/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ -//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_CALLOC for requirements. */ -//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_FREE for requirements. */ -//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t //#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t /**< Default milliseconds time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled. It must be signed, and at least 64 bits. If it is changed from the default, MBEDTLS_PRINTF_MS_TIME must be updated to match.*/ -//#define MBEDTLS_PRINTF_MS_TIME PRId64 /**< Default fmt for printf. That's avoid compiler warning if mbedtls_ms_time_t is redefined */ - -/** \def MBEDTLS_PLATFORM_DEV_RANDOM - * - * Path to a special file that returns cryptographic-quality random bytes - * when read. This is used by the default platform entropy source on - * non-Windows platforms unless a dedicated system call is available - * (see #MBEDTLS_NO_PLATFORM_ENTROPY). - * - * The default value is `/dev/random`, which is suitable on most platforms - * other than Linux. On Linux, either `/dev/random` or `/dev/urandom` - * may be the right choice, depending on the circumstances: - * - * - If possible, the library will use the getrandom() system call, - * which is preferable, and #MBEDTLS_PLATFORM_DEV_RANDOM is not used. - * - If there is a dedicated hardware entropy source (e.g. RDRAND on x86 - * processors), then both `/dev/random` and `/dev/urandom` are fine. - * - `/dev/random` is always secure. However, with kernels older than 5.6, - * `/dev/random` often blocks unnecessarily if there is no dedicated - * hardware entropy source. - * - `/dev/urandom` never blocks. However, it may return predictable data - * if it is used early after the kernel boots, especially on embedded - * devices without an interactive user. - * - * Thus you should change the value to `/dev/urandom` if your application - * definitely won't be used on a device running Linux without a dedicated - * entropy source early during or after boot. - * - * This is the default value of ::mbedtls_platform_dev_random, which - * can be changed at run time. - */ -//#define MBEDTLS_PLATFORM_DEV_RANDOM "/dev/random" - -/** \def MBEDTLS_CHECK_RETURN - * - * This macro is used at the beginning of the declaration of a function - * to indicate that its return value should be checked. It should - * instruct the compiler to emit a warning or an error if the function - * is called without checking its return value. - * - * There is a default implementation for popular compilers in platform_util.h. - * You can override the default implementation by defining your own here. - * - * If the implementation here is empty, this will effectively disable the - * checking of functions' return values. - */ -//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) - -/** \def MBEDTLS_IGNORE_RETURN - * - * This macro requires one argument, which should be a C function call. - * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this - * warning is suppressed. - */ -//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) - -/* PSA options */ -/** - * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the - * PSA crypto subsystem. - * - * If this option is unset, the library chooses a hash (currently between - * #MBEDTLS_MD_SHA512 and #MBEDTLS_MD_SHA256) based on availability and - * unspecified heuristics. - * - * \note The PSA crypto subsystem uses the first available mechanism amongst - * the following: - * - #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG if enabled; - * - Entropy from #MBEDTLS_ENTROPY_C plus CTR_DRBG with AES - * if #MBEDTLS_CTR_DRBG_C is enabled; - * - Entropy from #MBEDTLS_ENTROPY_C plus HMAC_DRBG. - * - * A future version may reevaluate the prioritization of DRBG mechanisms. - */ -//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 - -/** \def MBEDTLS_PSA_KEY_SLOT_COUNT - * - * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled, - * the maximum amount of PSA keys simultaneously in memory. This counts all - * volatile keys, plus loaded persistent keys. - * - * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, - * the maximum number of loaded persistent keys. - * - * Currently, persistent keys do not need to be loaded all the time while - * a multipart operation is in progress, only while the operation is being - * set up. This may change in future versions of the library. - * - * Currently, the library traverses of the whole table on each access to a - * persistent key. Therefore large values may cause poor performance. - * - * This option has no effect when #MBEDTLS_PSA_CRYPTO_C is disabled. - */ -//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 - -/** - * \def MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE - * - * Define the size (in bytes) of each static key buffer when - * #MBEDTLS_PSA_STATIC_KEY_SLOTS is set. If not - * explicitly defined then it's automatically guessed from available PSA keys - * enabled in the build through PSA_WANT_xxx symbols. - * If required by the application this parameter can be set to higher values - * in order to store larger objects (ex: raw keys), but please note that this - * will increase RAM usage. - */ -//#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE 256 - -/* RSA OPTIONS */ -//#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024 /**< Minimum RSA key size that can be generated in bits (Minimum possible value is 128 bits) */ - -/* SSL Cache options */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ - -/* SSL options */ - -/** \def MBEDTLS_SSL_IN_CONTENT_LEN - * - * Maximum length (in bytes) of incoming plaintext fragments. - * - * This determines the size of the incoming TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of the incoming I/O buffer. - */ -//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_CID_IN_LEN_MAX - * - * The maximum length of CIDs used for incoming DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX - * - * The maximum length of CIDs used for outgoing DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY - * - * This option controls the use of record plaintext padding - * in TLS 1.3 and when using the Connection ID extension in DTLS 1.2. - * - * The padding will always be chosen so that the length of the - * padded plaintext is a multiple of the value of this option. - * - * Note: A value of \c 1 means that no padding will be used - * for outgoing records. - * - * Note: On systems lacking division instructions, - * a power of two should be preferred. - */ -//#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 - -/** \def MBEDTLS_SSL_OUT_CONTENT_LEN - * - * Maximum length (in bytes) of outgoing plaintext fragments. - * - * This determines the size of the outgoing TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * It is possible to save RAM by setting a smaller outward buffer, while keeping - * the default inward 16384 byte buffer to conform to the TLS specification. - * - * The minimum required outward buffer size is determined by the handshake - * protocol's usage. Handshaking will fail if the outward buffer is too small. - * The specific size requirement depends on the configured ciphers and any - * certificate data which is sent during the handshake. - * - * Uncomment to set the maximum plaintext size of the outgoing I/O buffer. - */ -//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING - * - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - * - * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN - * to account for a reassembled handshake message of maximum size, - * together with its reassembly bitmap. - * - * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) - * should be sufficient for all practical situations as it allows - * to reassembly a large handshake message (such as a certificate) - * while buffering multiple smaller handshake messages. - * - */ -//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 - -//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 or 384 bits) */ -//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ - -/** - * Complete list of ciphersuites to use, in order of preference. - * - * \warning No dependency checking is done on that field! This option can only - * be used to restrict the set of available ciphersuites. It is your - * responsibility to make sure the needed modules are active. - * - * Use this to save a few hundred bytes of ROM (default ordering of all - * available ciphersuites) and a few to a few hundred bytes of RAM. - * - * The value below is only an example, not the default. - */ -//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - -/** - * \def MBEDTLS_SSL_MAX_EARLY_DATA_SIZE - * - * The default maximum amount of 0-RTT data. See the documentation of - * \c mbedtls_ssl_conf_max_early_data_size() for more information. - * - * It must be positive and smaller than UINT32_MAX. - * - * If MBEDTLS_SSL_EARLY_DATA is not defined, this default value does not - * have any impact on the build. - */ -//#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024 - -/** - * \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE - * - * Maximum allowed ticket age difference in milliseconds tolerated between - * server and client. Default value is 6000. This is not used in TLS 1.2. - * - * - The client ticket age is the time difference between the time when the - * client proposes to the server to use the ticket and the time the client - * received the ticket from the server. - * - The server ticket age is the time difference between the time when the - * server receives a proposition from the client to use the ticket and the - * time when the ticket was created by the server. - * - * The ages might be different due to the client and server clocks not running - * at the same pace. The typical accuracy of an RTC crystal is ±100 to ±20 parts - * per million (360 to 72 milliseconds per hour). Default tolerance window is - * 6s, thus in the worst case clients and servers must sync up their system time - * every 6000/360/2~=8 hours. - * - * See section 8.3 of the TLS 1.3 specification(RFC 8446) for more information. - */ -//#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000 - -/** - * \def MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH - * - * Size in bytes of a ticket nonce. This is not used in TLS 1.2. - * - * This must be less than 256. - */ -//#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32 - -/** - * \def MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS - * - * Default number of NewSessionTicket messages to be sent by a TLS 1.3 server - * after handshake completion. This is not used in TLS 1.2 and relevant only if - * the MBEDTLS_SSL_SESSION_TICKETS option is enabled. - * - */ -//#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1 - -/* X509 options */ -//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ -//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ - -/** \} name SECTION: Module configuration options */ diff --git a/vendor/mbedtls/include/mbedtls/md.h b/vendor/mbedtls/include/mbedtls/md.h deleted file mode 100644 index 478e9f766..000000000 --- a/vendor/mbedtls/include/mbedtls/md.h +++ /dev/null @@ -1,526 +0,0 @@ -/** - * \file md.h - * - * \brief This file contains the generic functions for message-digest - * (hashing) and HMAC. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_MD_H -#define MBEDTLS_MD_H -#include "mbedtls/private_access.h" - -#include - -#include "mbedtls/build_info.h" -#include "mbedtls/platform_util.h" - -/** The selected feature is not available. */ -#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 -/** Failed to allocate memory. */ -#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 -/** Opening or reading of file failed. */ -#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Supported message digests. - * - * \warning MD5 and SHA-1 are considered weak message digests and - * their use constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -/* Note: these are aligned with the definitions of PSA_ALG_ macros for hashes, - * in order to enable an efficient implementation of conversion functions. - * This is tested by md_to_from_psa() in test_suite_md. */ -typedef enum { - MBEDTLS_MD_NONE=0, /**< None. */ - MBEDTLS_MD_MD5=0x03, /**< The MD5 message digest. */ - MBEDTLS_MD_RIPEMD160=0x04, /**< The RIPEMD-160 message digest. */ - MBEDTLS_MD_SHA1=0x05, /**< The SHA-1 message digest. */ - MBEDTLS_MD_SHA224=0x08, /**< The SHA-224 message digest. */ - MBEDTLS_MD_SHA256=0x09, /**< The SHA-256 message digest. */ - MBEDTLS_MD_SHA384=0x0a, /**< The SHA-384 message digest. */ - MBEDTLS_MD_SHA512=0x0b, /**< The SHA-512 message digest. */ - MBEDTLS_MD_SHA3_224=0x10, /**< The SHA3-224 message digest. */ - MBEDTLS_MD_SHA3_256=0x11, /**< The SHA3-256 message digest. */ - MBEDTLS_MD_SHA3_384=0x12, /**< The SHA3-384 message digest. */ - MBEDTLS_MD_SHA3_512=0x13, /**< The SHA3-512 message digest. */ -} mbedtls_md_type_t; - -/* Note: this should always be >= PSA_HASH_MAX_SIZE - * in all builds with both CRYPTO_C and MD_LIGHT. - * - * This is to make things easier for modules such as TLS that may define a - * buffer size using MD_MAX_SIZE in a part of the code that's common to PSA - * and legacy, then assume the buffer's size is PSA_HASH_MAX_SIZE in another - * part of the code based on PSA. - */ -#if defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA3_512) -#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ -#elif defined(MBEDTLS_MD_CAN_SHA384) || defined(MBEDTLS_MD_CAN_SHA3_384) -#define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */ -#elif defined(MBEDTLS_MD_CAN_SHA256) || defined(MBEDTLS_MD_CAN_SHA3_256) -#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 */ -#elif defined(MBEDTLS_MD_CAN_SHA224) || defined(MBEDTLS_MD_CAN_SHA3_224) -#define MBEDTLS_MD_MAX_SIZE 28 /* longest known is SHA224 */ -#else -#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160 - or smaller (MD5 and earlier) */ -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_224) -#define MBEDTLS_MD_MAX_BLOCK_SIZE 144 /* the longest known is SHA3-224 */ -#elif defined(MBEDTLS_MD_CAN_SHA3_256) -#define MBEDTLS_MD_MAX_BLOCK_SIZE 136 -#elif defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA384) -#define MBEDTLS_MD_MAX_BLOCK_SIZE 128 -#elif defined(MBEDTLS_MD_CAN_SHA3_384) -#define MBEDTLS_MD_MAX_BLOCK_SIZE 104 -#elif defined(MBEDTLS_MD_CAN_SHA3_512) -#define MBEDTLS_MD_MAX_BLOCK_SIZE 72 -#else -#define MBEDTLS_MD_MAX_BLOCK_SIZE 64 -#endif - -/** - * Opaque struct. - * - * Constructed using either #mbedtls_md_info_from_string or - * #mbedtls_md_info_from_type. - * - * Fields can be accessed with #mbedtls_md_get_size, - * #mbedtls_md_get_type and #mbedtls_md_get_name. - */ -/* Defined internally in library/md_wrap.h. */ -typedef struct mbedtls_md_info_t mbedtls_md_info_t; - -/** - * Used internally to indicate whether a context uses legacy or PSA. - * - * Internal use only. - */ -typedef enum { - MBEDTLS_MD_ENGINE_LEGACY = 0, - MBEDTLS_MD_ENGINE_PSA, -} mbedtls_md_engine_t; - -/** - * The generic message-digest context. - */ -typedef struct mbedtls_md_context_t { - /** Information about the associated message digest. */ - const mbedtls_md_info_t *MBEDTLS_PRIVATE(md_info); - -#if defined(MBEDTLS_MD_SOME_PSA) - /** Are hash operations dispatched to PSA or legacy? */ - mbedtls_md_engine_t MBEDTLS_PRIVATE(engine); -#endif - - /** The digest-specific context (legacy) or the PSA operation. */ - void *MBEDTLS_PRIVATE(md_ctx); - -#if defined(MBEDTLS_MD_C) - /** The HMAC part of the context. */ - void *MBEDTLS_PRIVATE(hmac_ctx); -#endif -} mbedtls_md_context_t; - -/** - * \brief This function returns the message-digest information - * associated with the given digest type. - * - * \param md_type The type of digest to search for. - * - * \return The message-digest information associated with \p md_type. - * \return NULL if the associated message-digest information is not found. - */ -const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type); - -/** - * \brief This function initializes a message-digest context without - * binding it to a particular message-digest algorithm. - * - * This function should always be called first. It prepares the - * context for mbedtls_md_setup() for binding it to a - * message-digest algorithm. - */ -void mbedtls_md_init(mbedtls_md_context_t *ctx); - -/** - * \brief This function clears the internal structure of \p ctx and - * frees any embedded internal structure, but does not free - * \p ctx itself. - * - * If you have called mbedtls_md_setup() on \p ctx, you must - * call mbedtls_md_free() when you are no longer using the - * context. - * Calling this function if you have previously - * called mbedtls_md_init() and nothing else is optional. - * You must not call this function if you have not called - * mbedtls_md_init(). - */ -void mbedtls_md_free(mbedtls_md_context_t *ctx); - - -/** - * \brief This function selects the message digest algorithm to use, - * and allocates internal structures. - * - * It should be called after mbedtls_md_init() or - * mbedtls_md_free(). Makes it necessary to call - * mbedtls_md_free() later. - * - * \param ctx The context to set up. - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory), - * or non-zero: HMAC is used with this context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac); - -/** - * \brief This function clones the state of a message-digest - * context. - * - * \note You must call mbedtls_md_setup() on \c dst before calling - * this function. - * - * \note The two contexts must have the same type, - * for example, both are SHA-256. - * - * \warning This function clones the message-digest state, not the - * HMAC state. - * - * \param dst The destination context. - * \param src The context to be cloned. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. - * \return #MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE if both contexts are - * not using the same engine. This can be avoided by moving - * the call to psa_crypto_init() before the first call to - * mbedtls_md_setup(). - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_clone(mbedtls_md_context_t *dst, - const mbedtls_md_context_t *src); - -/** - * \brief This function extracts the message-digest size from the - * message-digest information structure. - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * - * \return The size of the message-digest output in Bytes. - */ -unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info); - -/** - * \brief This function gives the message-digest size associated to - * message-digest type. - * - * \param md_type The message-digest type. - * - * \return The size of the message-digest output in Bytes, - * or 0 if the message-digest type is not known. - */ -static inline unsigned char mbedtls_md_get_size_from_type(mbedtls_md_type_t md_type) -{ - return mbedtls_md_get_size(mbedtls_md_info_from_type(md_type)); -} - -/** - * \brief This function extracts the message-digest type from the - * message-digest information structure. - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * - * \return The type of the message digest. - */ -mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info); - -/** - * \brief This function starts a message-digest computation. - * - * You must call this function after setting up the context - * with mbedtls_md_setup(), and before passing data with - * mbedtls_md_update(). - * - * \param ctx The generic message-digest context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_starts(mbedtls_md_context_t *ctx); - -/** - * \brief This function feeds an input buffer into an ongoing - * message-digest computation. - * - * You must call mbedtls_md_starts() before calling this - * function. You may call this function multiple times. - * Afterwards, call mbedtls_md_finish(). - * - * \param ctx The generic message-digest context. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen); - -/** - * \brief This function finishes the digest operation, - * and writes the result to the output buffer. - * - * Call this function after a call to mbedtls_md_starts(), - * followed by any number of calls to mbedtls_md_update(). - * Afterwards, you may either clear the context with - * mbedtls_md_free(), or call mbedtls_md_starts() to reuse - * the context for another digest operation with the same - * algorithm. - * - * \param ctx The generic message-digest context. - * \param output The buffer for the generic message-digest checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output); - -/** - * \brief This function calculates the message-digest of a buffer, - * with respect to a configurable message-digest algorithm - * in a single call. - * - * The result is calculated as - * Output = message_digest(input buffer). - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param input The buffer holding the data. - * \param ilen The length of the input data. - * \param output The generic message-digest checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, - unsigned char *output); - -/** - * \brief This function returns the list of digests supported by the - * generic digest module. - * - * \note The list starts with the strongest available hashes. - * - * \return A statically allocated array of digests. Each element - * in the returned list is an integer belonging to the - * message-digest enumeration #mbedtls_md_type_t. - * The last entry is 0. - */ -const int *mbedtls_md_list(void); - -/** - * \brief This function returns the message-digest information - * associated with the given digest name. - * - * \param md_name The name of the digest to search for. - * - * \return The message-digest information associated with \p md_name. - * \return NULL if the associated message-digest information is not found. - */ -const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name); - -/** - * \brief This function returns the name of the message digest for - * the message-digest information structure given. - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * - * \return The name of the message digest. - */ -const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info); - -/** - * \brief This function returns the message-digest information - * from the given context. - * - * \param ctx The context from which to extract the information. - * This must be initialized (or \c NULL). - * - * \return The message-digest information associated with \p ctx. - * \return \c NULL if \p ctx is \c NULL. - */ -const mbedtls_md_info_t *mbedtls_md_info_from_ctx( - const mbedtls_md_context_t *ctx); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief This function calculates the message-digest checksum - * result of the contents of the provided file. - * - * The result is calculated as - * Output = message_digest(file contents). - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param path The input file name. - * \param output The generic message-digest checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing - * the file pointed by \p path. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, - unsigned char *output); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief This function sets the HMAC key and prepares to - * authenticate a new message. - * - * Call this function after mbedtls_md_setup(), to use - * the MD context for an HMAC calculation, then call - * mbedtls_md_hmac_update() to provide the input data, and - * mbedtls_md_hmac_finish() to get the HMAC value. - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * \param key The HMAC secret key. - * \param keylen The length of the HMAC key in Bytes. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, - size_t keylen); - -/** - * \brief This function feeds an input buffer into an ongoing HMAC - * computation. - * - * Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset() - * before calling this function. - * You may call this function multiple times to pass the - * input piecewise. - * Afterwards, call mbedtls_md_hmac_finish(). - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input, - size_t ilen); - -/** - * \brief This function finishes the HMAC operation, and writes - * the result to the output buffer. - * - * Call this function after mbedtls_md_hmac_starts() and - * mbedtls_md_hmac_update() to get the HMAC value. Afterwards - * you may either call mbedtls_md_free() to clear the context, - * or call mbedtls_md_hmac_reset() to reuse the context with - * the same HMAC key. - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * \param output The generic HMAC checksum result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output); - -/** - * \brief This function prepares to authenticate a new message with - * the same key as the previous HMAC operation. - * - * You may call this function after mbedtls_md_hmac_finish(). - * Afterwards call mbedtls_md_hmac_update() to pass the new - * input. - * - * \param ctx The message digest context containing an embedded HMAC - * context. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx); - -/** - * \brief This function calculates the full generic HMAC - * on the input buffer with the provided key. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The HMAC result is calculated as - * output = generic HMAC(hmac key, input buffer). - * - * \param md_info The information structure of the message-digest algorithm - * to use. - * \param key The HMAC secret key. - * \param keylen The length of the HMAC secret key in Bytes. - * \param input The buffer holding the input data. - * \param ilen The length of the input data. - * \param output The generic HMAC result. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification - * failure. - */ -MBEDTLS_CHECK_RETURN_TYPICAL -int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_MD_H */ diff --git a/vendor/mbedtls/include/mbedtls/md5.h b/vendor/mbedtls/include/mbedtls/md5.h deleted file mode 100644 index 6bf0754a4..000000000 --- a/vendor/mbedtls/include/mbedtls/md5.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - * \file md5.h - * - * \brief MD5 message digest algorithm (hash function) - * - * \warning MD5 is considered a weak message digest and its use constitutes a - * security risk. We recommend considering stronger message - * digests instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_MD5_H -#define MBEDTLS_MD5_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_MD5_ALT) -// Regular implementation -// - -/** - * \brief MD5 context structure - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -typedef struct mbedtls_md5_context { - uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< number of bytes processed */ - uint32_t MBEDTLS_PRIVATE(state)[4]; /*!< intermediate digest state */ - unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< data block being processed */ -} -mbedtls_md5_context; - -#else /* MBEDTLS_MD5_ALT */ -#include "md5_alt.h" -#endif /* MBEDTLS_MD5_ALT */ - -/** - * \brief Initialize MD5 context - * - * \param ctx MD5 context to be initialized - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md5_init(mbedtls_md5_context *ctx); - -/** - * \brief Clear MD5 context - * - * \param ctx MD5 context to be cleared - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md5_free(mbedtls_md5_context *ctx); - -/** - * \brief Clone (the state of) an MD5 context - * - * \param dst The destination context - * \param src The context to be cloned - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -void mbedtls_md5_clone(mbedtls_md5_context *dst, - const mbedtls_md5_context *src); - -/** - * \brief MD5 context setup - * - * \param ctx context to be initialized - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_starts(mbedtls_md5_context *ctx); - -/** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_update(mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen); - -/** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_finish(mbedtls_md5_context *ctx, - unsigned char output[16]); - -/** - * \brief MD5 process data block (internal use only) - * - * \param ctx MD5 context - * \param data buffer holding one block of data - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, - const unsigned char data[64]); - -/** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - * - * \return 0 if successful - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5(const unsigned char *input, - size_t ilen, - unsigned char output[16]); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - * - * \warning MD5 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -int mbedtls_md5_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_md5.h */ diff --git a/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h b/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h deleted file mode 100644 index b527d9b66..000000000 --- a/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +++ /dev/null @@ -1,142 +0,0 @@ -/** - * \file memory_buffer_alloc.h - * - * \brief Buffer-based memory allocator - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H -#define MBEDTLS_MEMORY_BUFFER_ALLOC_H - -#include "mbedtls/build_info.h" - -#include - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE) -#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ -#endif - -/** \} name SECTION: Module settings */ - -#define MBEDTLS_MEMORY_VERIFY_NONE 0 -#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0) -#define MBEDTLS_MEMORY_VERIFY_FREE (1 << 1) -#define MBEDTLS_MEMORY_VERIFY_ALWAYS (MBEDTLS_MEMORY_VERIFY_ALLOC | \ - MBEDTLS_MEMORY_VERIFY_FREE) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Initialize use of stack-based memory allocator. - * The stack-based allocator does memory management inside the - * presented buffer and does not call calloc() and free(). - * It sets the global mbedtls_calloc() and mbedtls_free() pointers - * to its own functions. - * (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if - * MBEDTLS_THREADING_C is defined) - * - * \note This code is not optimized and provides a straight-forward - * implementation of a stack-based memory allocator. - * - * \param buf buffer to use as heap - * \param len size of the buffer - */ -void mbedtls_memory_buffer_alloc_init(unsigned char *buf, size_t len); - -/** - * \brief Free the mutex for thread-safety and clear remaining memory - */ -void mbedtls_memory_buffer_alloc_free(void); - -/** - * \brief Determine when the allocator should automatically verify the state - * of the entire chain of headers / meta-data. - * (Default: MBEDTLS_MEMORY_VERIFY_NONE) - * - * \param verify One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC, - * MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS - */ -void mbedtls_memory_buffer_set_verify(int verify); - -#if defined(MBEDTLS_MEMORY_DEBUG) -/** - * \brief Print out the status of the allocated memory (primarily for use - * after a program should have de-allocated all memory) - * Prints out a list of 'still allocated' blocks and their stack - * trace if MBEDTLS_MEMORY_BACKTRACE is defined. - */ -void mbedtls_memory_buffer_alloc_status(void); - -/** - * \brief Get the number of alloc/free so far. - * - * \param alloc_count Number of allocations. - * \param free_count Number of frees. - */ -void mbedtls_memory_buffer_alloc_count_get(size_t *alloc_count, size_t *free_count); - -/** - * \brief Get the peak heap usage so far - * - * \param max_used Peak number of bytes in use or committed. This - * includes bytes in allocated blocks too small to split - * into smaller blocks but larger than the requested size. - * \param max_blocks Peak number of blocks in use, including free and used - */ -void mbedtls_memory_buffer_alloc_max_get(size_t *max_used, size_t *max_blocks); - -/** - * \brief Reset peak statistics - */ -void mbedtls_memory_buffer_alloc_max_reset(void); - -/** - * \brief Get the current heap usage - * - * \param cur_used Current number of bytes in use or committed. This - * includes bytes in allocated blocks too small to split - * into smaller blocks but larger than the requested size. - * \param cur_blocks Current number of blocks in use, including free and used - */ -void mbedtls_memory_buffer_alloc_cur_get(size_t *cur_used, size_t *cur_blocks); -#endif /* MBEDTLS_MEMORY_DEBUG */ - -/** - * \brief Verifies that all headers in the memory buffer are correct - * and contain sane values. Helps debug buffer-overflow errors. - * - * Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined. - * Prints out full header information if MBEDTLS_MEMORY_DEBUG - * is defined. (Includes stack trace information for each block if - * MBEDTLS_MEMORY_BACKTRACE is defined as well). - * - * \return 0 if verified, 1 otherwise - */ -int mbedtls_memory_buffer_alloc_verify(void); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if a test failed - */ -int mbedtls_memory_buffer_alloc_self_test(int verbose); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* memory_buffer_alloc.h */ diff --git a/vendor/mbedtls/include/mbedtls/net_sockets.h b/vendor/mbedtls/include/mbedtls/net_sockets.h deleted file mode 100644 index 8e69bc0fb..000000000 --- a/vendor/mbedtls/include/mbedtls/net_sockets.h +++ /dev/null @@ -1,299 +0,0 @@ -/** - * \file net_sockets.h - * - * \brief Network sockets abstraction layer to integrate Mbed TLS into a - * BSD-style sockets API. - * - * The network sockets module provides an example integration of the - * Mbed TLS library into a BSD sockets implementation. The module is - * intended to be an example of how Mbed TLS can be integrated into a - * networking stack, as well as to be Mbed TLS's network integration - * for its supported platforms. - * - * The module is intended only to be used with the Mbed TLS library and - * is not intended to be used by third party application software - * directly. - * - * The supported platforms are as follows: - * * Microsoft Windows and Windows CE - * * POSIX/Unix platforms including Linux, OS X - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_NET_SOCKETS_H -#define MBEDTLS_NET_SOCKETS_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/ssl.h" - -#include -#include - -/** Failed to open a socket. */ -#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 -/** The connection to the given server / port failed. */ -#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 -/** Binding of the socket failed. */ -#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 -/** Could not listen on the socket. */ -#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 -/** Could not accept the incoming connection. */ -#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A -/** Reading information from the socket failed. */ -#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C -/** Sending information through the socket failed. */ -#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E -/** Connection was reset by peer. */ -#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 -/** Failed to get an IP address for the given hostname. */ -#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 -/** Buffer is too small to hold the data. */ -#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 -/** The context is invalid, eg because it was free()ed. */ -#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 -/** Polling the net context failed. */ -#define MBEDTLS_ERR_NET_POLL_FAILED -0x0047 -/** Input invalid. */ -#define MBEDTLS_ERR_NET_BAD_INPUT_DATA -0x0049 - -#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ - -#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ -#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ - -#define MBEDTLS_NET_POLL_READ 1 /**< Used in \c mbedtls_net_poll to check for pending data */ -#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Wrapper type for sockets. - * - * Currently backed by just a file descriptor, but might be more in the future - * (eg two file descriptors for combined IPv4 + IPv6 support, or additional - * structures for hand-made UDP demultiplexing). - */ -typedef struct mbedtls_net_context { - /** The underlying file descriptor. - * - * This field is only guaranteed to be present on POSIX/Unix-like platforms. - * On other platforms, it may have a different type, have a different - * meaning, or be absent altogether. - */ - int fd; -} -mbedtls_net_context; - -/** - * \brief Initialize a context - * Just makes the context ready to be used or freed safely. - * - * \param ctx Context to initialize - */ -void mbedtls_net_init(mbedtls_net_context *ctx); - -/** - * \brief Initiate a connection with host:port in the given protocol - * - * \param ctx Socket to use - * \param host Host to connect to - * \param port Port to connect to - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_UNKNOWN_HOST, - * MBEDTLS_ERR_NET_CONNECT_FAILED - * - * \note Sets the socket in connected mode even with UDP. - */ -int mbedtls_net_connect(mbedtls_net_context *ctx, const char *host, const char *port, int proto); - -/** - * \brief Create a receiving socket on bind_ip:port in the chosen - * protocol. If bind_ip == NULL, all interfaces are bound. - * - * \param ctx Socket to use - * \param bind_ip IP to bind to, can be NULL - * \param port Port number to use - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_UNKNOWN_HOST, - * MBEDTLS_ERR_NET_BIND_FAILED, - * MBEDTLS_ERR_NET_LISTEN_FAILED - * - * \note Regardless of the protocol, opens the sockets and binds it. - * In addition, make the socket listening if protocol is TCP. - */ -int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto); - -/** - * \brief Accept a connection from a remote client - * - * \param bind_ctx Relevant socket - * \param client_ctx Will contain the connected client socket - * \param client_ip Will contain the client IP address, can be NULL - * \param buf_size Size of the client_ip buffer - * \param cip_len Will receive the size of the client IP written, - * can be NULL if client_ip is null - * - * \return 0 if successful, or - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_BIND_FAILED, - * MBEDTLS_ERR_NET_ACCEPT_FAILED, or - * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, - * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to - * non-blocking and accept() would block. - */ -int mbedtls_net_accept(mbedtls_net_context *bind_ctx, - mbedtls_net_context *client_ctx, - void *client_ip, size_t buf_size, size_t *cip_len); - -/** - * \brief Check and wait for the context to be ready for read/write - * - * \note The current implementation of this function uses - * select() and returns an error if the file descriptor - * is \c FD_SETSIZE or greater. - * - * \param ctx Socket to check - * \param rw Bitflag composed of MBEDTLS_NET_POLL_READ and - * MBEDTLS_NET_POLL_WRITE specifying the events - * to wait for: - * - If MBEDTLS_NET_POLL_READ is set, the function - * will return as soon as the net context is available - * for reading. - * - If MBEDTLS_NET_POLL_WRITE is set, the function - * will return as soon as the net context is available - * for writing. - * \param timeout Maximal amount of time to wait before returning, - * in milliseconds. If \c timeout is zero, the - * function returns immediately. If \c timeout is - * -1u, the function blocks potentially indefinitely. - * - * \return Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE - * on success or timeout, or a negative return code otherwise. - */ -int mbedtls_net_poll(mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout); - -/** - * \brief Set the socket blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_block(mbedtls_net_context *ctx); - -/** - * \brief Set the socket non-blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_nonblock(mbedtls_net_context *ctx); - -/** - * \brief Portable usleep helper - * - * \param usec Amount of microseconds to sleep - * - * \note Real amount of time slept will not be less than - * select()'s timeout granularity (typically, 10ms). - */ -void mbedtls_net_usleep(unsigned long usec); - -/** - * \brief Read at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * - * \return the number of bytes received, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. - */ -int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len); - -/** - * \brief Write at most 'len' characters. If no error occurs, - * the actual amount written is returned. - * - * \param ctx Socket - * \param buf The buffer to read from - * \param len The length of the buffer - * - * \return the number of bytes sent, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. - */ -int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len); - -/** - * \brief Read at most 'len' characters, blocking for at most - * 'timeout' seconds. If no error occurs, the actual amount - * read is returned. - * - * \note The current implementation of this function uses - * select() and returns an error if the file descriptor - * is \c FD_SETSIZE or greater. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * \param timeout Maximum number of milliseconds to wait for data - * 0 means no timeout (wait forever) - * - * \return The number of bytes received if successful. - * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out. - * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * Another negative error code (MBEDTLS_ERR_NET_xxx) - * for other failures. - * - * \note This function will block (until data becomes available or - * timeout is reached) even if the socket is set to - * non-blocking. Handling timeouts with non-blocking reads - * requires a different strategy. - */ -int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, - uint32_t timeout); - -/** - * \brief Closes down the connection and free associated data - * - * \param ctx The context to close - * - * \note This function frees and clears data associated with the - * context but does not free the memory pointed to by \p ctx. - * This memory is the responsibility of the caller. - */ -void mbedtls_net_close(mbedtls_net_context *ctx); - -/** - * \brief Gracefully shutdown the connection and free associated data - * - * \param ctx The context to free - * - * \note This function frees and clears data associated with the - * context but does not free the memory pointed to by \p ctx. - * This memory is the responsibility of the caller. - */ -void mbedtls_net_free(mbedtls_net_context *ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* net_sockets.h */ diff --git a/vendor/mbedtls/include/mbedtls/nist_kw.h b/vendor/mbedtls/include/mbedtls/nist_kw.h deleted file mode 100644 index d353f3d1a..000000000 --- a/vendor/mbedtls/include/mbedtls/nist_kw.h +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file nist_kw.h - * - * \brief This file provides an API for key wrapping (KW) and key wrapping with - * padding (KWP) as defined in NIST SP 800-38F. - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf - * - * Key wrapping specifies a deterministic authenticated-encryption mode - * of operation, according to NIST SP 800-38F: Recommendation for - * Block Cipher Modes of Operation: Methods for Key Wrapping. Its - * purpose is to protect cryptographic keys. - * - * Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP. - * https://tools.ietf.org/html/rfc3394 - * https://tools.ietf.org/html/rfc5649 - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_NIST_KW_H -#define MBEDTLS_NIST_KW_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MBEDTLS_KW_MODE_KW = 0, - MBEDTLS_KW_MODE_KWP = 1 -} mbedtls_nist_kw_mode_t; - -#if !defined(MBEDTLS_NIST_KW_ALT) -// Regular implementation -// - -/** - * \brief The key wrapping context-type definition. The key wrapping context is passed - * to the APIs called. - * - * \note The definition of this type may change in future library versions. - * Don't make any assumptions on this context! - */ -typedef struct { - mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ -} mbedtls_nist_kw_context; - -#else /* MBEDTLS_NIST_key wrapping_ALT */ -#include "nist_kw_alt.h" -#endif /* MBEDTLS_NIST_KW_ALT */ - -/** - * \brief This function initializes the specified key wrapping context - * to make references valid and prepare the context - * for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free(). - * - * \param ctx The key wrapping context to initialize. - * - */ -void mbedtls_nist_kw_init(mbedtls_nist_kw_context *ctx); - -/** - * \brief This function initializes the key wrapping context set in the - * \p ctx parameter and sets the encryption key. - * - * \param ctx The key wrapping context. - * \param cipher The 128-bit block cipher to use. Only AES is supported. - * \param key The Key Encryption Key (KEK). - * \param keybits The KEK size in bits. This must be acceptable by the cipher. - * \param is_wrap Specify whether the operation within the context is wrapping or unwrapping - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input. - * \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers - * which are not supported. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_setkey(mbedtls_nist_kw_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits, - const int is_wrap); - -/** - * \brief This function releases and clears the specified key wrapping context - * and underlying cipher sub-context. - * - * \param ctx The key wrapping context to clear. - */ -void mbedtls_nist_kw_free(mbedtls_nist_kw_context *ctx); - -/** - * \brief This function encrypts a buffer using key wrapping. - * - * \param ctx The key wrapping context to use for encryption. - * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * The input uses units of 8 Bytes called semiblocks. - *
  • For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive.
  • - *
  • For KWP mode: any length between 1 and 2^32-1 inclusive.
- * \param[out] output The buffer holding the output data. - *
  • For KW mode: Must be at least 8 bytes larger than \p in_len.
  • - *
  • For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of - * 8 bytes for KWP (15 bytes at most).
- * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. - * \param[in] out_size The capacity of the output buffer. - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_wrap(mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size); - -/** - * \brief This function decrypts a buffer using key wrapping. - * - * \param ctx The key wrapping context to use for decryption. - * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) - * \param input The buffer holding the input data. - * \param in_len The length of the input data in Bytes. - * The input uses units of 8 Bytes called semiblocks. - * The input must be a multiple of semiblocks. - *
  • For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive.
  • - *
  • For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.
- * \param[out] output The buffer holding the output data. - * The output buffer's minimal length is 8 bytes shorter than \p in_len. - * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. - * For KWP mode, the length could be up to 15 bytes shorter than \p in_len, - * depending on how much padding was added to the data. - * \param[in] out_size The capacity of the output buffer. - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. - * \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext. - * \return cipher-specific error code on failure of the underlying cipher. - */ -int mbedtls_nist_kw_unwrap(mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size); - - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/** - * \brief The key wrapping checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_nist_kw_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_NIST_KW_H */ diff --git a/vendor/mbedtls/include/mbedtls/oid.h b/vendor/mbedtls/include/mbedtls/oid.h deleted file mode 100644 index fdc25ebf8..000000000 --- a/vendor/mbedtls/include/mbedtls/oid.h +++ /dev/null @@ -1,727 +0,0 @@ -/** - * \file oid.h - * - * \brief Object Identifier (OID) database - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_OID_H -#define MBEDTLS_OID_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/asn1.h" -#include "mbedtls/pk.h" - -#include - -#if defined(MBEDTLS_CIPHER_C) -#include "mbedtls/cipher.h" -#endif - -#include "mbedtls/md.h" - -/** OID is not found. */ -#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E -/** output buffer is too small */ -#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B - -/* This is for the benefit of X.509, but defined here in order to avoid - * having a "backwards" include of x.509.h here */ -/* - * X.509 extension types (internal, arbitrary values for bitsets) - */ -#define MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0) -#define MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1) -#define MBEDTLS_OID_X509_EXT_KEY_USAGE (1 << 2) -#define MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES (1 << 3) -#define MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS (1 << 4) -#define MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME (1 << 5) -#define MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME (1 << 6) -#define MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7) -#define MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS (1 << 8) -#define MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS (1 << 9) -#define MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS (1 << 10) -#define MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE (1 << 11) -#define MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12) -#define MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13) -#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14) -#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16) - -/* - * Maximum number of OID components allowed - */ -#define MBEDTLS_OID_MAX_COMPONENTS 128 - -/* - * Top level OID tuples - */ -#define MBEDTLS_OID_ISO_MEMBER_BODIES "\x2a" /* {iso(1) member-body(2)} */ -#define MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x2b" /* {iso(1) identified-organization(3)} */ -#define MBEDTLS_OID_ISO_CCITT_DS "\x55" /* {joint-iso-ccitt(2) ds(5)} */ -#define MBEDTLS_OID_ISO_ITU_COUNTRY "\x60" /* {joint-iso-itu-t(2) country(16)} */ - -/* - * ISO Member bodies OID parts - */ -#define MBEDTLS_OID_COUNTRY_US "\x86\x48" /* {us(840)} */ -#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */ -#define MBEDTLS_OID_RSA_COMPANY MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \ - MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */ -#define MBEDTLS_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */ -#define MBEDTLS_OID_ANSI_X9_62 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \ - MBEDTLS_OID_ORG_ANSI_X9_62 - -/* - * ISO Identified organization OID parts - */ -#define MBEDTLS_OID_ORG_DOD "\x06" /* {dod(6)} */ -#define MBEDTLS_OID_ORG_OIW "\x0e" -#define MBEDTLS_OID_OIW_SECSIG MBEDTLS_OID_ORG_OIW "\x03" -#define MBEDTLS_OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG "\x02" -#define MBEDTLS_OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_ALG "\x1a" -#define MBEDTLS_OID_ORG_THAWTE "\x65" /* thawte(101) */ -#define MBEDTLS_OID_THAWTE MBEDTLS_OID_ISO_IDENTIFIED_ORG \ - MBEDTLS_OID_ORG_THAWTE -#define MBEDTLS_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */ -#define MBEDTLS_OID_CERTICOM MBEDTLS_OID_ISO_IDENTIFIED_ORG \ - MBEDTLS_OID_ORG_CERTICOM -#define MBEDTLS_OID_ORG_TELETRUST "\x24" /* teletrust(36) */ -#define MBEDTLS_OID_TELETRUST MBEDTLS_OID_ISO_IDENTIFIED_ORG \ - MBEDTLS_OID_ORG_TELETRUST - -/* - * ISO ITU OID parts - */ -#define MBEDTLS_OID_ORGANIZATION "\x01" /* {organization(1)} */ -#define MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_COUNTRY MBEDTLS_OID_COUNTRY_US \ - MBEDTLS_OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */ - -#define MBEDTLS_OID_ORG_GOV "\x65" /* {gov(101)} */ -#define MBEDTLS_OID_GOV MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */ - -#define MBEDTLS_OID_ORG_NETSCAPE "\x86\xF8\x42" /* {netscape(113730)} */ -#define MBEDTLS_OID_NETSCAPE MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */ - -/* ISO arc for standard certificate and CRL extensions */ -#define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */ - -#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */ - -/** - * Private Internet Extensions - * { iso(1) identified-organization(3) dod(6) internet(1) - * security(5) mechanisms(5) pkix(7) } - */ -#define MBEDTLS_OID_INTERNET MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD \ - "\x01" -#define MBEDTLS_OID_PKIX MBEDTLS_OID_INTERNET "\x05\x05\x07" - -/* - * Arc for standard naming attributes - */ -#define MBEDTLS_OID_AT MBEDTLS_OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */ -#define MBEDTLS_OID_AT_CN MBEDTLS_OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */ -#define MBEDTLS_OID_AT_SUR_NAME MBEDTLS_OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */ -#define MBEDTLS_OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */ -#define MBEDTLS_OID_AT_COUNTRY MBEDTLS_OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */ -#define MBEDTLS_OID_AT_LOCALITY MBEDTLS_OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */ -#define MBEDTLS_OID_AT_STATE MBEDTLS_OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */ -#define MBEDTLS_OID_AT_ORGANIZATION MBEDTLS_OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */ -#define MBEDTLS_OID_AT_ORG_UNIT MBEDTLS_OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */ -#define MBEDTLS_OID_AT_TITLE MBEDTLS_OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */ -#define MBEDTLS_OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */ -#define MBEDTLS_OID_AT_POSTAL_CODE MBEDTLS_OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */ -#define MBEDTLS_OID_AT_GIVEN_NAME MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */ -#define MBEDTLS_OID_AT_INITIALS MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */ -#define MBEDTLS_OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */ -#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributeType:= {id-at 45} */ -#define MBEDTLS_OID_AT_DN_QUALIFIER MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */ -#define MBEDTLS_OID_AT_PSEUDONYM MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */ - -#define MBEDTLS_OID_UID "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) uid(1)} */ -#define MBEDTLS_OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */ - -/* - * OIDs for standard certificate extensions - */ -#define MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */ -#define MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */ -#define MBEDTLS_OID_KEY_USAGE MBEDTLS_OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */ -#define MBEDTLS_OID_CERTIFICATE_POLICIES MBEDTLS_OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */ -#define MBEDTLS_OID_POLICY_MAPPINGS MBEDTLS_OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */ -#define MBEDTLS_OID_SUBJECT_ALT_NAME MBEDTLS_OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */ -#define MBEDTLS_OID_ISSUER_ALT_NAME MBEDTLS_OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */ -#define MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */ -#define MBEDTLS_OID_BASIC_CONSTRAINTS MBEDTLS_OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */ -#define MBEDTLS_OID_NAME_CONSTRAINTS MBEDTLS_OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */ -#define MBEDTLS_OID_POLICY_CONSTRAINTS MBEDTLS_OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */ -#define MBEDTLS_OID_EXTENDED_KEY_USAGE MBEDTLS_OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */ -#define MBEDTLS_OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */ -#define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */ -#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */ - -/* - * Certificate policies - */ -#define MBEDTLS_OID_ANY_POLICY MBEDTLS_OID_CERTIFICATE_POLICIES "\x00" /**< anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } */ - -/* - * Netscape certificate extensions - */ -#define MBEDTLS_OID_NS_CERT MBEDTLS_OID_NETSCAPE "\x01" -#define MBEDTLS_OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT "\x01" -#define MBEDTLS_OID_NS_BASE_URL MBEDTLS_OID_NS_CERT "\x02" -#define MBEDTLS_OID_NS_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x03" -#define MBEDTLS_OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x04" -#define MBEDTLS_OID_NS_RENEWAL_URL MBEDTLS_OID_NS_CERT "\x07" -#define MBEDTLS_OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CERT "\x08" -#define MBEDTLS_OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_CERT "\x0C" -#define MBEDTLS_OID_NS_COMMENT MBEDTLS_OID_NS_CERT "\x0D" -#define MBEDTLS_OID_NS_DATA_TYPE MBEDTLS_OID_NETSCAPE "\x02" -#define MBEDTLS_OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_DATA_TYPE "\x05" - -/* - * OIDs for CRL extensions - */ -#define MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_ID_CE "\x10" -#define MBEDTLS_OID_CRL_NUMBER MBEDTLS_OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */ - -/* - * X.509 v3 Extended key usage OIDs - */ -#define MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */ - -#define MBEDTLS_OID_KP MBEDTLS_OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */ -#define MBEDTLS_OID_SERVER_AUTH MBEDTLS_OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */ -#define MBEDTLS_OID_CLIENT_AUTH MBEDTLS_OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */ -#define MBEDTLS_OID_CODE_SIGNING MBEDTLS_OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */ -#define MBEDTLS_OID_EMAIL_PROTECTION MBEDTLS_OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */ -#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */ -#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */ - -/** - * Wi-SUN Alliance Field Area Network - * { iso(1) identified-organization(3) dod(6) internet(1) - * private(4) enterprise(1) WiSUN(45605) FieldAreaNetwork(1) } - */ -#define MBEDTLS_OID_WISUN_FAN MBEDTLS_OID_INTERNET "\x04\x01\x82\xe4\x25\x01" - -#define MBEDTLS_OID_ON MBEDTLS_OID_PKIX "\x08" /**< id-on OBJECT IDENTIFIER ::= { id-pkix 8 } */ -#define MBEDTLS_OID_ON_HW_MODULE_NAME MBEDTLS_OID_ON "\x04" /**< id-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-on 4 } */ - -/* - * PKCS definition OIDs - */ - -#define MBEDTLS_OID_PKCS MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */ -#define MBEDTLS_OID_PKCS1 MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */ -#define MBEDTLS_OID_PKCS5 MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */ -#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07" /**< pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } */ -#define MBEDTLS_OID_PKCS9 MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */ -#define MBEDTLS_OID_PKCS12 MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */ - -/* - * PKCS#1 OIDs - */ -#define MBEDTLS_OID_PKCS1_RSA MBEDTLS_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */ -#define MBEDTLS_OID_PKCS1_MD5 MBEDTLS_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */ -#define MBEDTLS_OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */ -#define MBEDTLS_OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */ -#define MBEDTLS_OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */ -#define MBEDTLS_OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */ -#define MBEDTLS_OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */ - -#define MBEDTLS_OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D" - -#define MBEDTLS_OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */ - -/* RFC 4055 */ -#define MBEDTLS_OID_RSASSA_PSS MBEDTLS_OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */ -#define MBEDTLS_OID_MGF1 MBEDTLS_OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */ - -/* - * Digest algorithms - */ -#define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG \ - MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ - -#define MBEDTLS_OID_DIGEST_ALG_RIPEMD160 MBEDTLS_OID_TELETRUST "\x03\x02\x01" /**< id-ripemd160 OBJECT IDENTIFIER :: { iso(1) identified-organization(3) teletrust(36) algorithm(3) hashAlgorithm(2) ripemd160(1) } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA3_224 MBEDTLS_OID_NIST_ALG "\x02\x07" /**< id-sha3-224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-224(7) } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA3_256 MBEDTLS_OID_NIST_ALG "\x02\x08" /**< id-sha3-256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-256(8) } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA3_384 MBEDTLS_OID_NIST_ALG "\x02\x09" /**< id-sha3-384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-384(9) } */ - -#define MBEDTLS_OID_DIGEST_ALG_SHA3_512 MBEDTLS_OID_NIST_ALG "\x02\x0a" /**< id-sha3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-512(10) } */ - - -#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */ - -#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */ - -#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */ - -#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */ - -#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */ - -#define MBEDTLS_OID_HMAC_SHA3_224 MBEDTLS_OID_NIST_ALG "\x02\x0d" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-224(13) } */ - -#define MBEDTLS_OID_HMAC_SHA3_256 MBEDTLS_OID_NIST_ALG "\x02\x0e" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-256(14) } */ - -#define MBEDTLS_OID_HMAC_SHA3_384 MBEDTLS_OID_NIST_ALG "\x02\x0f" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-384(15) } */ - -#define MBEDTLS_OID_HMAC_SHA3_512 MBEDTLS_OID_NIST_ALG "\x02\x10" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-512(16) } */ - -#define MBEDTLS_OID_HMAC_RIPEMD160 MBEDTLS_OID_INTERNET "\x05\x05\x08\x01\x04" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) iso-identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1) hmacRIPEMD160(4)} */ - -/* - * Encryption algorithms, - * the following standardized object identifiers are specified at - * https://datatracker.ietf.org/doc/html/rfc8018#appendix-C. - */ -#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG \ - MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */ -#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */ -#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */ -#define MBEDTLS_OID_AES_128_CBC MBEDTLS_OID_AES "\x02" /** aes128-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes128-CBC-PAD(2) } */ -#define MBEDTLS_OID_AES_192_CBC MBEDTLS_OID_AES "\x16" /** aes192-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes192-CBC-PAD(22) } */ -#define MBEDTLS_OID_AES_256_CBC MBEDTLS_OID_AES "\x2a" /** aes256-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes256-CBC-PAD(42) } */ - -/* - * Key Wrapping algorithms - */ -/* - * RFC 5649 - */ -#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */ -#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */ -#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */ -#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */ -#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */ -#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */ -/* - * PKCS#5 OIDs - */ -#define MBEDTLS_OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */ -#define MBEDTLS_OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */ -#define MBEDTLS_OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */ - -/* - * PKCS#5 PBES1 algorithms - */ -#define MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */ -#define MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */ -#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */ -#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */ - -/* - * PKCS#7 OIDs - */ -#define MBEDTLS_OID_PKCS7_DATA MBEDTLS_OID_PKCS7 "\x01" /**< Content type is Data OBJECT IDENTIFIER ::= {pkcs-7 1} */ -#define MBEDTLS_OID_PKCS7_SIGNED_DATA MBEDTLS_OID_PKCS7 "\x02" /**< Content type is Signed Data OBJECT IDENTIFIER ::= {pkcs-7 2} */ -#define MBEDTLS_OID_PKCS7_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x03" /**< Content type is Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 3} */ -#define MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x04" /**< Content type is Signed and Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 4} */ -#define MBEDTLS_OID_PKCS7_DIGESTED_DATA MBEDTLS_OID_PKCS7 "\x05" /**< Content type is Digested Data OBJECT IDENTIFIER ::= {pkcs-7 5} */ -#define MBEDTLS_OID_PKCS7_ENCRYPTED_DATA MBEDTLS_OID_PKCS7 "\x06" /**< Content type is Encrypted Data OBJECT IDENTIFIER ::= {pkcs-7 6} */ - -/* - * PKCS#8 OIDs - */ -#define MBEDTLS_OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */ - -/* - * PKCS#12 PBE OIDs - */ -#define MBEDTLS_OID_PKCS12_PBE MBEDTLS_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */ - -#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */ -#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */ - -/* - * EC key algorithms from RFC 5480 - */ - -/* id-ecPublicKey OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */ -#define MBEDTLS_OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_ANSI_X9_62 "\x02\01" - -/* id-ecDH OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) - * schemes(1) ecdh(12) } */ -#define MBEDTLS_OID_EC_ALG_ECDH MBEDTLS_OID_CERTICOM "\x01\x0c" - -/* - * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2 - */ - -/* secp192r1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */ -#define MBEDTLS_OID_EC_GRP_SECP192R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x01" - -/* secp224r1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 33 } */ -#define MBEDTLS_OID_EC_GRP_SECP224R1 MBEDTLS_OID_CERTICOM "\x00\x21" - -/* secp256r1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */ -#define MBEDTLS_OID_EC_GRP_SECP256R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x07" - -/* secp384r1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 34 } */ -#define MBEDTLS_OID_EC_GRP_SECP384R1 MBEDTLS_OID_CERTICOM "\x00\x22" - -/* secp521r1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 35 } */ -#define MBEDTLS_OID_EC_GRP_SECP521R1 MBEDTLS_OID_CERTICOM "\x00\x23" - -/* secp192k1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 31 } */ -#define MBEDTLS_OID_EC_GRP_SECP192K1 MBEDTLS_OID_CERTICOM "\x00\x1f" - -/* secp224k1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 32 } */ -#define MBEDTLS_OID_EC_GRP_SECP224K1 MBEDTLS_OID_CERTICOM "\x00\x20" - -/* secp256k1 OBJECT IDENTIFIER ::= { - * iso(1) identified-organization(3) certicom(132) curve(0) 10 } */ -#define MBEDTLS_OID_EC_GRP_SECP256K1 MBEDTLS_OID_CERTICOM "\x00\x0a" - -/* RFC 5639 4.1 - * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1) - * identified-organization(3) teletrust(36) algorithm(3) signature- - * algorithm(3) ecSign(2) 8} - * ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1} - * versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */ -#define MBEDTLS_OID_EC_BRAINPOOL_V1 MBEDTLS_OID_TELETRUST "\x03\x03\x02\x08\x01\x01" - -/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */ -#define MBEDTLS_OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x07" - -/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */ -#define MBEDTLS_OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0B" - -/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */ -#define MBEDTLS_OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0D" - -/* - * SEC1 C.1 - * - * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } - * id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)} - */ -#define MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62 "\x01" -#define MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE "\x01" - -/* - * ECDSA signature identifiers, from RFC 5480 - */ -#define MBEDTLS_OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62 "\x04" /* signatures(4) */ -#define MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */ - -/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */ -#define MBEDTLS_OID_ECDSA_SHA1 MBEDTLS_OID_ANSI_X9_62_SIG "\x01" - -/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 1 } */ -#define MBEDTLS_OID_ECDSA_SHA224 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x01" - -/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 2 } */ -#define MBEDTLS_OID_ECDSA_SHA256 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x02" - -/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 3 } */ -#define MBEDTLS_OID_ECDSA_SHA384 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x03" - -/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { - * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) - * ecdsa-with-SHA2(3) 4 } */ -#define MBEDTLS_OID_ECDSA_SHA512 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04" - -/* - * EC key algorithms from RFC 8410 - */ - -#define MBEDTLS_OID_X25519 MBEDTLS_OID_THAWTE "\x6e" /**< id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 } */ -#define MBEDTLS_OID_X448 MBEDTLS_OID_THAWTE "\x6f" /**< id-X448 OBJECT IDENTIFIER ::= { 1 3 101 111 } */ -#define MBEDTLS_OID_ED25519 MBEDTLS_OID_THAWTE "\x70" /**< id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } */ -#define MBEDTLS_OID_ED448 MBEDTLS_OID_THAWTE "\x71" /**< id-Ed448 OBJECT IDENTIFIER ::= { 1 3 101 113 } */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Base OID descriptor structure - */ -typedef struct mbedtls_oid_descriptor_t { - const char *MBEDTLS_PRIVATE(asn1); /*!< OID ASN.1 representation */ - size_t MBEDTLS_PRIVATE(asn1_len); /*!< length of asn1 */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) - const char *MBEDTLS_PRIVATE(name); /*!< official name (e.g. from RFC) */ - const char *MBEDTLS_PRIVATE(description); /*!< human friendly description */ -#endif -} mbedtls_oid_descriptor_t; - -/** - * \brief Translate an ASN.1 OID into its numeric representation - * (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549") - * - * \param buf buffer to put representation in - * \param size size of the buffer - * \param oid OID to translate - * - * \return Length of the string written (excluding final NULL) or - * MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error - */ -int mbedtls_oid_get_numeric_string(char *buf, size_t size, const mbedtls_asn1_buf *oid); - -/** - * \brief Translate a string containing a dotted-decimal - * representation of an ASN.1 OID into its encoded form - * (e.g. "1.2.840.113549" into "\x2A\x86\x48\x86\xF7\x0D"). - * On success, this function allocates oid->buf from the - * heap. It must be freed by the caller using mbedtls_free(). - * - * \param oid #mbedtls_asn1_buf to populate with the DER-encoded OID - * \param oid_str string representation of the OID to parse - * \param size length of the OID string, not including any null terminator - * - * \return 0 if successful - * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if \p oid_str does not - * represent a valid OID - * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if the function fails to - * allocate oid->buf - */ -int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid, const char *oid_str, size_t size); - -/** - * \brief Translate an X.509 extension OID into local values - * - * \param oid OID to use - * \param ext_type place to store the extension type - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_x509_ext_type(const mbedtls_asn1_buf *oid, int *ext_type); - -/** - * \brief Translate an X.509 attribute type OID into the short name - * (e.g. the OID for an X520 Common Name into "CN") - * - * \param oid OID to use - * \param short_name place to store the string pointer - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **short_name); - -/** - * \brief Translate PublicKeyAlgorithm OID into pk_type - * - * \param oid OID to use - * \param pk_alg place to store public key algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_pk_alg(const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg); - -/** - * \brief Translate pk_type into PublicKeyAlgorithm OID - * - * \param pk_alg Public key type to look for - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_type_t pk_alg, - const char **oid, size_t *olen); - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -/** - * \brief Translate NamedCurve OID into an EC group identifier - * - * \param oid OID to use - * \param grp_id place to store group id - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_ec_grp(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id); - -/** - * \brief Translate EC group identifier into NamedCurve OID - * - * \param grp_id EC group identifier - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_ec_grp(mbedtls_ecp_group_id grp_id, - const char **oid, size_t *olen); - -/** - * \brief Translate AlgorithmIdentifier OID into an EC group identifier, - * for curves that are directly encoded at this level - * - * \param oid OID to use - * \param grp_id place to store group id - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_ec_grp_algid(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id); - -/** - * \brief Translate EC group identifier into AlgorithmIdentifier OID, - * for curves that are directly encoded at this level - * - * \param grp_id EC group identifier - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_ec_grp_algid(mbedtls_ecp_group_id grp_id, - const char **oid, size_t *olen); -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -/** - * \brief Translate SignatureAlgorithm OID into md_type and pk_type - * - * \param oid OID to use - * \param md_alg place to store message digest algorithm - * \param pk_alg place to store public key algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_sig_alg(const mbedtls_asn1_buf *oid, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg); - -/** - * \brief Translate SignatureAlgorithm OID into description - * - * \param oid OID to use - * \param desc place to store string pointer - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_sig_alg_desc(const mbedtls_asn1_buf *oid, const char **desc); - -/** - * \brief Translate md_type and pk_type into SignatureAlgorithm OID - * - * \param md_alg message digest algorithm - * \param pk_alg public key algorithm - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_sig_alg(mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const char **oid, size_t *olen); - -/** - * \brief Translate hmac algorithm OID into md_type - * - * \param oid OID to use - * \param md_hmac place to store message hmac algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_md_hmac(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac); - -/** - * \brief Translate hash algorithm OID into md_type - * - * \param oid OID to use - * \param md_alg place to store message digest algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_md_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg); - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -/** - * \brief Translate Extended Key Usage OID into description - * - * \param oid OID to use - * \param desc place to store string pointer - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_extended_key_usage(const mbedtls_asn1_buf *oid, const char **desc); -#endif - -/** - * \brief Translate certificate policies OID into description - * - * \param oid OID to use - * \param desc place to store string pointer - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_certificate_policies(const mbedtls_asn1_buf *oid, const char **desc); - -/** - * \brief Translate md_type into hash algorithm OID - * - * \param md_alg message digest algorithm - * \param oid place to store ASN.1 OID string pointer - * \param olen length of the OID - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_oid_by_md(mbedtls_md_type_t md_alg, const char **oid, size_t *olen); - -#if defined(MBEDTLS_CIPHER_C) -/** - * \brief Translate encryption algorithm OID into cipher_type - * - * \param oid OID to use - * \param cipher_alg place to store cipher algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_cipher_alg(const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg); - -#if defined(MBEDTLS_PKCS12_C) -/** - * \brief Translate PKCS#12 PBE algorithm OID into md_type and - * cipher_type - * - * \param oid OID to use - * \param md_alg place to store message digest algorithm - * \param cipher_alg place to store cipher algorithm - * - * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND - */ -int mbedtls_oid_get_pkcs12_pbe_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg, - mbedtls_cipher_type_t *cipher_alg); -#endif /* MBEDTLS_PKCS12_C */ -#endif /* MBEDTLS_CIPHER_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* oid.h */ diff --git a/vendor/mbedtls/include/mbedtls/pem.h b/vendor/mbedtls/include/mbedtls/pem.h deleted file mode 100644 index 3c6a28d98..000000000 --- a/vendor/mbedtls/include/mbedtls/pem.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - * \file pem.h - * - * \brief Privacy Enhanced Mail (PEM) decoding - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PEM_H -#define MBEDTLS_PEM_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include - -/** - * \name PEM Error codes - * These error codes are returned in case of errors reading the - * PEM data. - * \{ - */ -/** No PEM header or footer found. */ -#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 -/** PEM string is not as expected. */ -#define MBEDTLS_ERR_PEM_INVALID_DATA -0x1100 -/** Failed to allocate memory. */ -#define MBEDTLS_ERR_PEM_ALLOC_FAILED -0x1180 -/** RSA IV is not in hex-format. */ -#define MBEDTLS_ERR_PEM_INVALID_ENC_IV -0x1200 -/** Unsupported key encryption algorithm. */ -#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 -/** Private key password can't be empty. */ -#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED -0x1300 -/** Given private key password does not allow for correct decryption. */ -#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH -0x1380 -/** Unavailable feature, e.g. hashing/encryption combination. */ -#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA -0x1480 -/** \} name PEM Error codes */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) -/** - * \brief PEM context structure - */ -typedef struct mbedtls_pem_context { - unsigned char *MBEDTLS_PRIVATE(buf); /*!< buffer for decoded data */ - size_t MBEDTLS_PRIVATE(buflen); /*!< length of the buffer */ - unsigned char *MBEDTLS_PRIVATE(info); /*!< buffer for extra header information */ -} -mbedtls_pem_context; - -/** - * \brief PEM context setup - * - * \param ctx context to be initialized - */ -void mbedtls_pem_init(mbedtls_pem_context *ctx); - -/** - * \brief Read a buffer for PEM information and store the resulting - * data into the specified context buffers. - * - * \param ctx context to use - * \param header header string to seek and expect - * \param footer footer string to seek and expect - * \param data source data to look in (must be nul-terminated) - * \param pwd password for decryption (can be NULL) - * \param pwdlen length of password - * \param use_len destination for total length used from data buffer. It is - * set after header is correctly read, so unless you get - * MBEDTLS_ERR_PEM_BAD_INPUT_DATA or - * MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is - * the length to skip. - * - * \note Attempts to check password correctness by verifying if - * the decrypted text starts with an ASN.1 sequence of - * appropriate length - * - * \note \c mbedtls_pem_free must be called on PEM context before - * the PEM context can be reused in another call to - * \c mbedtls_pem_read_buffer - * - * \return 0 on success, or a specific PEM error code - */ -int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer, - const unsigned char *data, - const unsigned char *pwd, - size_t pwdlen, size_t *use_len); - -/** - * \brief Get the pointer to the decoded binary data in a PEM context. - * - * \param ctx PEM context to access. - * \param buflen On success, this will contain the length of the binary data. - * This must be a valid (non-null) pointer. - * - * \return A pointer to the decoded binary data. - * - * \note The returned pointer remains valid only until \p ctx is - modified or freed. - */ -static inline const unsigned char *mbedtls_pem_get_buffer(mbedtls_pem_context *ctx, size_t *buflen) -{ - *buflen = ctx->MBEDTLS_PRIVATE(buflen); - return ctx->MBEDTLS_PRIVATE(buf); -} - - -/** - * \brief PEM context memory freeing - * - * \param ctx context to be freed - */ -void mbedtls_pem_free(mbedtls_pem_context *ctx); -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a buffer of PEM information from a DER encoded - * buffer. - * - * \param header The header string to write. - * \param footer The footer string to write. - * \param der_data The DER data to encode. - * \param der_len The length of the DER data \p der_data in Bytes. - * \param buf The buffer to write to. - * \param buf_len The length of the output buffer \p buf in Bytes. - * \param olen The address at which to store the total length written - * or required (if \p buf_len is not enough). - * - * \note You may pass \c NULL for \p buf and \c 0 for \p buf_len - * to request the length of the resulting PEM buffer in - * `*olen`. - * - * \note This function may be called with overlapping \p der_data - * and \p buf buffers. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large - * enough to hold the PEM buffer. In this case, `*olen` holds - * the required minimum size of \p buf. - * \return Another PEM or BASE64 error code on other kinds of failure. - */ -int mbedtls_pem_write_buffer(const char *header, const char *footer, - const unsigned char *der_data, size_t der_len, - unsigned char *buf, size_t buf_len, size_t *olen); -#endif /* MBEDTLS_PEM_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* pem.h */ diff --git a/vendor/mbedtls/include/mbedtls/pk.h b/vendor/mbedtls/include/mbedtls/pk.h deleted file mode 100644 index 68b0f4bef..000000000 --- a/vendor/mbedtls/include/mbedtls/pk.h +++ /dev/null @@ -1,1299 +0,0 @@ -/** - * \file pk.h - * - * \brief Public Key abstraction layer - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_PK_H -#define MBEDTLS_PK_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/md.h" - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#include "psa/crypto.h" -#endif - -/** Memory allocation failed. */ -#define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 -/** Type mismatch, eg attempt to encrypt with an ECDSA key */ -#define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 -/** Read/write of file failed. */ -#define MBEDTLS_ERR_PK_FILE_IO_ERROR -0x3E00 -/** Unsupported key version */ -#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80 -/** Invalid key tag or value. */ -#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT -0x3D00 -/** Key algorithm is unsupported (only RSA and EC are supported). */ -#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG -0x3C80 -/** Private key password can't be empty. */ -#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED -0x3C00 -/** Given private key password does not allow for correct decryption. */ -#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH -0x3B80 -/** The pubkey tag or value is invalid (only RSA and EC are supported). */ -#define MBEDTLS_ERR_PK_INVALID_PUBKEY -0x3B00 -/** The algorithm tag or value is invalid. */ -#define MBEDTLS_ERR_PK_INVALID_ALG -0x3A80 -/** Elliptic curve is unsupported (only NIST curves are supported). */ -#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 -/** Unavailable feature, e.g. RSA disabled for RSA key. */ -#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 -/** The buffer contains a valid signature followed by more data. */ -#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 -/** The output buffer is too small. */ -#define MBEDTLS_ERR_PK_BUFFER_TOO_SMALL -0x3880 - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Public key types - */ -typedef enum { - MBEDTLS_PK_NONE=0, - MBEDTLS_PK_RSA, - MBEDTLS_PK_ECKEY, - MBEDTLS_PK_ECKEY_DH, - MBEDTLS_PK_ECDSA, - MBEDTLS_PK_RSA_ALT, - MBEDTLS_PK_RSASSA_PSS, - MBEDTLS_PK_OPAQUE, -} mbedtls_pk_type_t; - -/** - * \brief Options for RSASSA-PSS signature verification. - * See \c mbedtls_rsa_rsassa_pss_verify_ext() - */ -typedef struct mbedtls_pk_rsassa_pss_options { - /** The digest to use for MGF1 in PSS. - * - * \note When #MBEDTLS_USE_PSA_CRYPTO is enabled and #MBEDTLS_RSA_C is - * disabled, this must be equal to the \c md_alg argument passed - * to mbedtls_pk_verify_ext(). In a future version of the library, - * this constraint may apply whenever #MBEDTLS_USE_PSA_CRYPTO is - * enabled regardless of the status of #MBEDTLS_RSA_C. - */ - mbedtls_md_type_t mgf1_hash_id; - - /** The expected length of the salt, in bytes. This may be - * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. - * - * \note When #MBEDTLS_USE_PSA_CRYPTO is enabled, only - * #MBEDTLS_RSA_SALT_LEN_ANY is valid. Any other value may be - * ignored (allowing any salt length). - */ - int expected_salt_len; - -} mbedtls_pk_rsassa_pss_options; - -/** - * \brief Maximum size of a signature made by mbedtls_pk_sign(). - */ -/* We need to set MBEDTLS_PK_SIGNATURE_MAX_SIZE to the maximum signature - * size among the supported signature types. Do it by starting at 0, - * then incrementally increasing to be large enough for each supported - * signature mechanism. - * - * The resulting value can be 0, for example if MBEDTLS_ECDH_C is enabled - * (which allows the pk module to be included) but neither MBEDTLS_ECDSA_C - * nor MBEDTLS_RSA_C nor any opaque signature mechanism (PSA or RSA_ALT). - */ -#define MBEDTLS_PK_SIGNATURE_MAX_SIZE 0 - -#if (defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_RSA_ALT_SUPPORT)) && \ - MBEDTLS_MPI_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE -/* For RSA, the signature can be as large as the bignum module allows. - * For RSA_ALT, the signature size is not necessarily tied to what the - * bignum module can do, but in the absence of any specific setting, - * we use that (rsa_alt_sign_wrap in library/pk_wrap.h will check). */ -#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE -#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -#endif - -#if defined(MBEDTLS_ECDSA_C) && \ - MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_PK_SIGNATURE_MAX_SIZE -/* For ECDSA, the ecdsa module exports a constant for the maximum - * signature size. */ -#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE -#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if PSA_SIGNATURE_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE -/* PSA_SIGNATURE_MAX_SIZE is the maximum size of a signature made - * through the PSA API in the PSA representation. */ -#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE -#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_SIGNATURE_MAX_SIZE -#endif - -#if PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 > MBEDTLS_PK_SIGNATURE_MAX_SIZE -/* The Mbed TLS representation is different for ECDSA signatures: - * PSA uses the raw concatenation of r and s, - * whereas Mbed TLS uses the ASN.1 representation (SEQUENCE of two INTEGERs). - * Add the overhead of ASN.1: up to (1+2) + 2 * (1+2+1) for the - * types, lengths (represented by up to 2 bytes), and potential leading - * zeros of the INTEGERs and the SEQUENCE. */ -#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE -#define MBEDTLS_PK_SIGNATURE_MAX_SIZE (PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11) -#endif -#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */ - -/* Internal helper to define which fields in the pk_context structure below - * should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly) - * format. It should be noted that this only affects how data is stored, not - * which functions are used for various operations. The overall picture looks - * like this: - * - if USE_PSA is not defined and ECP_C is defined then use ecp_keypair data - * structure and legacy functions - * - if USE_PSA is defined and - * - if ECP_C then use ecp_keypair structure, convert data to a PSA friendly - * format and use PSA functions - * - if !ECP_C then use new raw data and PSA functions directly. - * - * The main reason for the "intermediate" (USE_PSA + ECP_C) above is that as long - * as ECP_C is defined mbedtls_pk_ec() gives the user a read/write access to the - * ecp_keypair structure inside the pk_context so they can modify it using - * ECP functions which are not under PK module's control. - */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \ - !defined(MBEDTLS_ECP_C) -#define MBEDTLS_PK_USE_PSA_EC_DATA -#endif - -/** - * \brief Types for interfacing with the debug module - */ -typedef enum { - MBEDTLS_PK_DEBUG_NONE = 0, - MBEDTLS_PK_DEBUG_MPI, - MBEDTLS_PK_DEBUG_ECP, - MBEDTLS_PK_DEBUG_PSA_EC, -} mbedtls_pk_debug_type; - -/** - * \brief Item to send to the debug module - */ -typedef struct mbedtls_pk_debug_item { - mbedtls_pk_debug_type MBEDTLS_PRIVATE(type); - const char *MBEDTLS_PRIVATE(name); - void *MBEDTLS_PRIVATE(value); -} mbedtls_pk_debug_item; - -/** Maximum number of item send for debugging, plus 1 */ -#define MBEDTLS_PK_DEBUG_MAX_ITEMS 3 - -/** - * \brief Public key information and operations - * - * \note The library does not support custom pk info structures, - * only built-in structures returned by - * mbedtls_cipher_info_from_type(). - */ -typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; - -#define MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) -/** - * \brief Public key container - */ -typedef struct mbedtls_pk_context { - /** Method table */ - const mbedtls_pk_info_t *MBEDTLS_PRIVATE(pk_info); - /** Underlying type-specific key context */ - void *MBEDTLS_PRIVATE(pk_ctx); - - /* The following field is used to store the ID of a private key in the - * following cases: - * - opaque key when MBEDTLS_USE_PSA_CRYPTO is defined - * - normal key when MBEDTLS_PK_USE_PSA_EC_DATA is defined. In this case: - * - the pk_ctx above is not not used to store the private key anymore. - * Actually that field not populated at all in this case because also - * the public key will be stored in raw format as explained below - * - this ID is used for all private key operations (ex: sign, check - * key pair, key write, etc) using PSA functions - * - * Note: this private key storing solution only affects EC keys, not the - * other ones. The latters still use the pk_ctx to store their own - * context. */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_svc_key_id_t MBEDTLS_PRIVATE(priv_id); /**< Key ID for opaque keys */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - /* The following fields are meant for storing the public key in raw format - * which is handy for: - * - easily importing it into the PSA context - * - reducing the ECP module dependencies in the PK one. - * - * When MBEDTLS_PK_USE_PSA_EC_DATA is enabled: - * - the pk_ctx above is not used anymore for storing the public key - * inside the ecp_keypair structure - * - the following fields are used for all public key operations: signature - * verify, key pair check and key write. - * - For a key pair, priv_id contains the private key. For a public key, - * priv_id is null. - * Of course, when MBEDTLS_PK_USE_PSA_EC_DATA is not enabled, the legacy - * ecp_keypair structure is used for storing the public key and performing - * all the operations. - * - * Note: This new public key storing solution only works for EC keys, not - * other ones. The latters still use pk_ctx to store their own - * context. - */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - uint8_t MBEDTLS_PRIVATE(pub_raw)[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN]; /**< Raw public key */ - size_t MBEDTLS_PRIVATE(pub_raw_len); /**< Valid bytes in "pub_raw" */ - psa_ecc_family_t MBEDTLS_PRIVATE(ec_family); /**< EC family of pk */ - size_t MBEDTLS_PRIVATE(ec_bits); /**< Curve's bits of pk */ -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} mbedtls_pk_context; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Context for resuming operations - */ -typedef struct { - const mbedtls_pk_info_t *MBEDTLS_PRIVATE(pk_info); /**< Public key information */ - void *MBEDTLS_PRIVATE(rs_ctx); /**< Underlying restart context */ -} mbedtls_pk_restart_ctx; -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_pk_restart_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/** - * \brief Types for RSA-alt abstraction - */ -typedef int (*mbedtls_pk_rsa_alt_decrypt_func)(void *ctx, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len); -typedef int (*mbedtls_pk_rsa_alt_sign_func)(void *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig); -typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)(void *ctx); -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/** - * \brief Return information associated with the given PK type - * - * \param pk_type PK type to search for. - * - * \return The PK info associated with the type or NULL if not found. - */ -const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type); - -/** - * \brief Initialize a #mbedtls_pk_context (as NONE). - * - * \param ctx The context to initialize. - * This must not be \c NULL. - */ -void mbedtls_pk_init(mbedtls_pk_context *ctx); - -/** - * \brief Free the components of a #mbedtls_pk_context. - * - * \param ctx The context to clear. It must have been initialized. - * If this is \c NULL, this function does nothing. - * - * \note For contexts that have been set up with - * mbedtls_pk_setup_opaque(), this does not free the underlying - * PSA key and you still need to call psa_destroy_key() - * independently if you want to destroy that key. - */ -void mbedtls_pk_free(mbedtls_pk_context *ctx); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context - * - * \param ctx The context to initialize. - * This must not be \c NULL. - */ -void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx); - -/** - * \brief Free the components of a restart context - * - * \param ctx The context to clear. It must have been initialized. - * If this is \c NULL, this function does nothing. - */ -void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/** - * \brief Initialize a PK context with the information given - * and allocates the type-specific PK subcontext. - * - * \param ctx Context to initialize. It must not have been set - * up yet (type #MBEDTLS_PK_NONE). - * \param info Information to use - * - * \return 0 on success, - * MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input, - * MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure. - * - * \note For contexts holding an RSA-alt key, use - * \c mbedtls_pk_setup_rsa_alt() instead. - */ -int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * \brief Initialize a PK context to wrap a PSA key. - * - * This function creates a PK context which wraps a PSA key. The PSA wrapped - * key must be an EC or RSA key pair (DH is not suported in the PK module). - * - * Under the hood PSA functions will be used to perform the required - * operations and, based on the key type, used algorithms will be: - * * EC: - * * verify, verify_ext, sign, sign_ext: ECDSA. - * * RSA: - * * sign, decrypt: use the primary algorithm in the wrapped PSA key; - * * sign_ext: RSA PSS if the pk_type is #MBEDTLS_PK_RSASSA_PSS, otherwise - * it falls back to the sign() case; - * * verify, verify_ext, encrypt: not supported. - * - * In order for the above operations to succeed, the policy of the wrapped PSA - * key must allow the specified algorithm. - * - * Opaque PK contexts wrapping an EC keys also support \c mbedtls_pk_check_pair(), - * whereas RSA ones do not. - * - * \warning The PSA wrapped key must remain valid as long as the wrapping PK - * context is in use, that is at least between the point this function - * is called and the point mbedtls_pk_free() is called on this context. - * - * \param ctx The context to initialize. It must be empty (type NONE). - * \param key The PSA key to wrap, which must hold an ECC or RSA key pair. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input (context already - * used, invalid key identifier). - * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an ECC or - * RSA key pair. - * \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure. - */ -int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, - const mbedtls_svc_key_id_t key); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/** - * \brief Initialize an RSA-alt context - * - * \param ctx Context to initialize. It must not have been set - * up yet (type #MBEDTLS_PK_NONE). - * \param key RSA key pointer - * \param decrypt_func Decryption function - * \param sign_func Signing function - * \param key_len_func Function returning key length in bytes - * - * \return 0 on success, or MBEDTLS_ERR_PK_BAD_INPUT_DATA if the - * context wasn't already initialized as RSA_ALT. - * - * \note This function replaces \c mbedtls_pk_setup() for RSA-alt. - */ -int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key, - mbedtls_pk_rsa_alt_decrypt_func decrypt_func, - mbedtls_pk_rsa_alt_sign_func sign_func, - mbedtls_pk_rsa_alt_key_len_func key_len_func); -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/** - * \brief Get the size in bits of the underlying key - * - * \param ctx The context to query. It must have been initialized. - * - * \return Key size in bits, or 0 on error - */ -size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx); - -/** - * \brief Get the length in bytes of the underlying key - * - * \param ctx The context to query. It must have been initialized. - * - * \return Key length in bytes, or 0 on error - */ -static inline size_t mbedtls_pk_get_len(const mbedtls_pk_context *ctx) -{ - return (mbedtls_pk_get_bitlen(ctx) + 7) / 8; -} - -/** - * \brief Tell if a context can do the operation given by type - * - * \param ctx The context to query. It must have been initialized. - * \param type The desired type. - * - * \return 1 if the context can do operations on the given type. - * \return 0 if the context cannot do the operations on the given - * type. This is always the case for a context that has - * been initialized but not set up, or that has been - * cleared with mbedtls_pk_free(). - */ -int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * \brief Tell if context can do the operation given by PSA algorithm - * - * \param ctx The context to query. It must have been initialized. - * \param alg PSA algorithm to check against, the following are allowed: - * PSA_ALG_RSA_PKCS1V15_SIGN(hash), - * PSA_ALG_RSA_PSS(hash), - * PSA_ALG_RSA_PKCS1V15_CRYPT, - * PSA_ALG_ECDSA(hash), - * PSA_ALG_ECDH, where hash is a specific hash. - * \param usage PSA usage flag to check against, must be composed of: - * PSA_KEY_USAGE_SIGN_HASH - * PSA_KEY_USAGE_DECRYPT - * PSA_KEY_USAGE_DERIVE. - * Context key must match all passed usage flags. - * - * \warning Since the set of allowed algorithms and usage flags may be - * expanded in the future, the return value \c 0 should not - * be taken in account for non-allowed algorithms and usage - * flags. - * - * \return 1 if the context can do operations on the given type. - * \return 0 if the context cannot do the operations on the given - * type, for non-allowed algorithms and usage flags, or - * for a context that has been initialized but not set up - * or that has been cleared with mbedtls_pk_free(). - */ -int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, - psa_key_usage_t usage); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -/** - * \brief Determine valid PSA attributes that can be used to - * import a key into PSA. - * - * The attributes determined by this function are suitable - * for calling mbedtls_pk_import_into_psa() to create - * a PSA key with the same key material. - * - * The typical flow of operations involving this function is - * ``` - * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - * int ret = mbedtls_pk_get_psa_attributes(pk, &attributes); - * if (ret != 0) ...; // error handling omitted - * // Tweak attributes if desired - * psa_key_id_t key_id = 0; - * ret = mbedtls_pk_import_into_psa(pk, &attributes, &key_id); - * if (ret != 0) ...; // error handling omitted - * ``` - * - * \note This function does not support RSA-alt contexts - * (set up with mbedtls_pk_setup_rsa_alt()). - * - * \param[in] pk The PK context to use. It must have been set up. - * It can either contain a key pair or just a public key. - * \param usage A single `PSA_KEY_USAGE_xxx` flag among the following: - * - #PSA_KEY_USAGE_DECRYPT: \p pk must contain a - * key pair. The output \p attributes will contain a - * key pair type, and the usage policy will allow - * #PSA_KEY_USAGE_ENCRYPT as well as - * #PSA_KEY_USAGE_DECRYPT. - * - #PSA_KEY_USAGE_DERIVE: \p pk must contain a - * key pair. The output \p attributes will contain a - * key pair type. - * - #PSA_KEY_USAGE_ENCRYPT: The output - * \p attributes will contain a public key type. - * - #PSA_KEY_USAGE_SIGN_HASH: \p pk must contain a - * key pair. The output \p attributes will contain a - * key pair type, and the usage policy will allow - * #PSA_KEY_USAGE_VERIFY_HASH as well as - * #PSA_KEY_USAGE_SIGN_HASH. - * - #PSA_KEY_USAGE_SIGN_MESSAGE: \p pk must contain a - * key pair. The output \p attributes will contain a - * key pair type, and the usage policy will allow - * #PSA_KEY_USAGE_VERIFY_MESSAGE as well as - * #PSA_KEY_USAGE_SIGN_MESSAGE. - * - #PSA_KEY_USAGE_VERIFY_HASH: The output - * \p attributes will contain a public key type. - * - #PSA_KEY_USAGE_VERIFY_MESSAGE: The output - * \p attributes will contain a public key type. - * \param[out] attributes - * On success, valid attributes to import the key into PSA. - * - The lifetime and key identifier are unchanged. If the - * attribute structure was initialized or reset before - * calling this function, this will result in a volatile - * key. Call psa_set_key_identifier() before or after this - * function if you wish to create a persistent key. Call - * psa_set_key_lifetime() before or after this function if - * you wish to import the key in a secure element. - * - The key type and bit-size are determined by the contents - * of the PK context. If the PK context contains a key - * pair, the key type can be either a key pair type or - * the corresponding public key type, depending on - * \p usage. If the PK context contains a public key, - * the key type is a public key type. - * - The key's policy is determined by the key type and - * the \p usage parameter. The usage always allows - * \p usage, exporting and copying the key, and - * possibly other permissions as documented for the - * \p usage parameter. - * The permitted algorithm policy is determined as follows - * based on the #mbedtls_pk_type_t type of \p pk, - * the chosen \p usage and other factors: - * - #MBEDTLS_PK_RSA whose underlying - * #mbedtls_rsa_context has the padding mode - * #MBEDTLS_RSA_PKCS_V15: - * #PSA_ALG_RSA_PKCS1V15_SIGN(#PSA_ALG_ANY_HASH) - * if \p usage is SIGN/VERIFY, and - * #PSA_ALG_RSA_PKCS1V15_CRYPT - * if \p usage is ENCRYPT/DECRYPT. - * - #MBEDTLS_PK_RSA whose underlying - * #mbedtls_rsa_context has the padding mode - * #MBEDTLS_RSA_PKCS_V21 and the digest type - * corresponding to the PSA algorithm \c hash: - * #PSA_ALG_RSA_PSS_ANY_SALT(#PSA_ALG_ANY_HASH) - * if \p usage is SIGN/VERIFY, and - * #PSA_ALG_RSA_OAEP(\c hash) - * if \p usage is ENCRYPT/DECRYPT. - * - #MBEDTLS_PK_RSA_ALT: not supported. - * - #MBEDTLS_PK_ECDSA or #MBEDTLS_PK_ECKEY - * if \p usage is SIGN/VERIFY: - * #PSA_ALG_DETERMINISTIC_ECDSA(#PSA_ALG_ANY_HASH) - * if #MBEDTLS_ECDSA_DETERMINISTIC is enabled, - * otherwise #PSA_ALG_ECDSA(#PSA_ALG_ANY_HASH). - * - #MBEDTLS_PK_ECKEY_DH or #MBEDTLS_PK_ECKEY - * if \p usage is DERIVE: - * #PSA_ALG_ECDH. - * - #MBEDTLS_PK_OPAQUE: same as the primary algorithm - * set for the underlying PSA key, except that - * sign/decrypt flags are removed if the type is - * set to a public key type. - * The underlying key must allow \p usage. - * Note that the enrollment algorithm set with - * psa_set_key_enrollment_algorithm() is not copied. - * - * \return 0 on success. - * #MBEDTLS_ERR_PK_TYPE_MISMATCH if \p pk does not contain - * a key of the type identified in \p attributes. - * Another error code on other failures. - */ -int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, - psa_key_usage_t usage, - psa_key_attributes_t *attributes); - -/** - * \brief Import a key into the PSA key store. - * - * This function is equivalent to calling psa_import_key() - * with the key material from \p pk. - * - * The typical way to use this function is: - * -# Call mbedtls_pk_get_psa_attributes() to obtain - * attributes for the given key. - * -# If desired, modify the attributes, for example: - * - To create a persistent key, call - * psa_set_key_identifier() and optionally - * psa_set_key_lifetime(). - * - To import only the public part of a key pair: - * - * psa_set_key_type(&attributes, - * PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( - * psa_get_key_type(&attributes))); - * - Restrict the key usage if desired. - * -# Call mbedtls_pk_import_into_psa(). - * - * \note This function does not support RSA-alt contexts - * (set up with mbedtls_pk_setup_rsa_alt()). - * - * \param[in] pk The PK context to use. It must have been set up. - * It can either contain a key pair or just a public key. - * \param[in] attributes - * The attributes to use for the new key. They must be - * compatible with \p pk. In particular, the key type - * must match the content of \p pk. - * If \p pk contains a key pair, the key type in - * attributes can be either the key pair type or the - * corresponding public key type (to import only the - * public part). - * \param[out] key_id - * On success, the identifier of the newly created key. - * On error, this is #MBEDTLS_SVC_KEY_ID_INIT. - * - * \return 0 on success. - * #MBEDTLS_ERR_PK_TYPE_MISMATCH if \p pk does not contain - * a key of the type identified in \p attributes. - * Another error code on other failures. - */ -int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key_id); - -/** - * \brief Create a PK context starting from a key stored in PSA. - * This key: - * - must be exportable and - * - must be an RSA or EC key pair or public key (FFDH is not supported in PK). - * - * The resulting PK object will be a transparent type: - * - #MBEDTLS_PK_RSA for RSA keys or - * - #MBEDTLS_PK_ECKEY for EC keys. - * - * Once this functions returns the PK object will be completely - * independent from the original PSA key that it was generated - * from. - * Calling mbedtls_pk_sign(), mbedtls_pk_verify(), - * mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting - * PK context will perform the corresponding algorithm for that - * PK context type. - * * For ECDSA, the choice of deterministic vs randomized will - * be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC. - * * For an RSA key, the output PK context will allow both - * encrypt/decrypt and sign/verify regardless of the original - * key's policy. - * The original key's policy determines the output key's padding - * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, - * otherwise PKCS1 v1.5 is set. - * - * \param key_id The key identifier of the key stored in PSA. - * \param pk The PK context that will be filled. It must be initialized, - * but not set up. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input - * parameters are not correct. - */ -int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); - -/** - * \brief Create a PK context for the public key of a PSA key. - * - * The key must be an RSA or ECC key. It can be either a - * public key or a key pair, and only the public key is copied. - * The resulting PK object will be a transparent type: - * - #MBEDTLS_PK_RSA for RSA keys or - * - #MBEDTLS_PK_ECKEY for EC keys. - * - * Once this functions returns the PK object will be completely - * independent from the original PSA key that it was generated - * from. - * Calling mbedtls_pk_verify() or - * mbedtls_pk_encrypt() on the resulting - * PK context will perform the corresponding algorithm for that - * PK context type. - * - * For an RSA key, the output PK context will allow both - * encrypt and verify regardless of the original key's policy. - * The original key's policy determines the output key's padding - * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, - * otherwise PKCS1 v1.5 is set. - * - * \param key_id The key identifier of the key stored in PSA. - * \param pk The PK context that will be filled. It must be initialized, - * but not set up. - * - * \return 0 on success. - * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input - * parameters are not correct. - */ -int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ - -/** - * \brief Verify signature (including padding if relevant). - * - * \param ctx The PK context to use. It must have been set up. - * \param md_alg Hash algorithm used. - * This can be #MBEDTLS_MD_NONE if the signature algorithm - * does not rely on a hash algorithm (non-deterministic - * ECDSA, RSA PKCS#1 v1.5). - * For PKCS#1 v1.5, if \p md_alg is #MBEDTLS_MD_NONE, then - * \p hash is the DigestInfo structure used by RFC 8017 - * §9.2 steps 3–6. If \p md_alg is a valid hash - * algorithm then \p hash is the digest itself, and this - * function calculates the DigestInfo encoding internally. - * \param hash Hash of the message to sign - * \param hash_len Hash length - * \param sig Signature to verify - * \param sig_len Signature length - * - * \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is - * either PKCS#1 v1.5 or PSS (accepting any salt length), - * depending on the padding mode in the underlying RSA context. - * For a pk object constructed by parsing, this is PKCS#1 v1.5 - * by default. Use mbedtls_pk_verify_ext() to explicitly select - * a different algorithm. - * - * \return 0 on success (signature is valid), - * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig but its length is less than \p sig_len, - * or a specific error code. - */ -int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len); - -/** - * \brief Restartable version of \c mbedtls_pk_verify() - * - * \note Performs the same job as \c mbedtls_pk_verify(), but can - * return early and restart according to the limit set with - * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC - * operations. For RSA, same as \c mbedtls_pk_verify(). - * - * \param ctx The PK context to use. It must have been set up. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Signature to verify - * \param sig_len Signature length - * \param rs_ctx Restart context (NULL to disable restart) - * - * \return See \c mbedtls_pk_verify(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - mbedtls_pk_restart_ctx *rs_ctx); - -/** - * \brief Verify signature, with options. - * (Includes verification of the padding depending on type.) - * - * \param type Signature type (inc. possible padding type) to verify - * \param options Pointer to type-specific options, or NULL - * \param ctx The PK context to use. It must have been set up. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length or 0 (see notes) - * \param sig Signature to verify - * \param sig_len Signature length - * - * \return 0 on success (signature is valid), - * #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be - * used for this type of signatures, - * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid - * signature in \p sig but its length is less than \p sig_len, - * or a specific error code. - * - * \note If hash_len is 0, then the length associated with md_alg - * is used instead, or an error returned if it is invalid. - * - * \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0 - * - * \note If type is MBEDTLS_PK_RSASSA_PSS, then options must point - * to a mbedtls_pk_rsassa_pss_options structure, - * otherwise it must be NULL. Note that if - * #MBEDTLS_USE_PSA_CRYPTO is defined, the salt length is not - * verified as PSA_ALG_RSA_PSS_ANY_SALT is used. - */ -int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, - mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len); - -/** - * \brief Make signature, including padding if relevant. - * - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length - * \param sig Place to write the signature. - * It must have enough room for the signature. - * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough. - * You may use a smaller buffer if it is large enough - * given the key type. - * \param sig_size The size of the \p sig buffer in bytes. - * \param sig_len On successful return, - * the number of bytes written to \p sig. - * \param f_rng RNG function, must not be \c NULL. - * \param p_rng RNG parameter - * - * \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is - * either PKCS#1 v1.5 or PSS (using the largest possible salt - * length up to the hash length), depending on the padding mode - * in the underlying RSA context. For a pk object constructed - * by parsing, this is PKCS#1 v1.5 by default. Use - * mbedtls_pk_sign_ext() to explicitly select a different - * algorithm. - * - * \return 0 on success, or a specific error code. - * - * \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. - * For ECDSA, md_alg may never be MBEDTLS_MD_NONE. - */ -int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** - * \brief Make signature given a signature type. - * - * \param pk_type Signature type. - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param md_alg Hash algorithm used (see notes) - * \param hash Hash of the message to sign - * \param hash_len Hash length - * \param sig Place to write the signature. - * It must have enough room for the signature. - * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough. - * You may use a smaller buffer if it is large enough - * given the key type. - * \param sig_size The size of the \p sig buffer in bytes. - * \param sig_len On successful return, - * the number of bytes written to \p sig. - * \param f_rng RNG function, must not be \c NULL. - * \param p_rng RNG parameter - * - * \return 0 on success, or a specific error code. - * - * \note When \p pk_type is #MBEDTLS_PK_RSASSA_PSS, - * see #PSA_ALG_RSA_PSS for a description of PSS options used. - * - * \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. - * For ECDSA, md_alg may never be MBEDTLS_MD_NONE. - * - */ -int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, - mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Restartable version of \c mbedtls_pk_sign() - * - * \note Performs the same job as \c mbedtls_pk_sign(), but can - * return early and restart according to the limit set with - * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC - * operations. For RSA, same as \c mbedtls_pk_sign(). - * - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param md_alg Hash algorithm used (see notes for mbedtls_pk_sign()) - * \param hash Hash of the message to sign - * \param hash_len Hash length - * \param sig Place to write the signature. - * It must have enough room for the signature. - * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough. - * You may use a smaller buffer if it is large enough - * given the key type. - * \param sig_size The size of the \p sig buffer in bytes. - * \param sig_len On successful return, - * the number of bytes written to \p sig. - * \param f_rng RNG function, must not be \c NULL. - * \param p_rng RNG parameter - * \param rs_ctx Restart context (NULL to disable restart) - * - * \return See \c mbedtls_pk_sign(). - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - mbedtls_f_rng_t *f_rng, void *p_rng, - mbedtls_pk_restart_ctx *rs_ctx); - -/** - * \brief Decrypt message (including padding if relevant). - * - * \param ctx The PK context to use. It must have been set up - * with a private key. - * \param input Input to decrypt - * \param ilen Input size - * \param output Decrypted output - * \param olen Decrypted message length - * \param osize Size of the output buffer - * \param f_rng RNG function, must not be \c NULL. - * \param p_rng RNG parameter - * - * \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is - * either PKCS#1 v1.5 or OAEP, depending on the padding mode in - * the underlying RSA context. For a pk object constructed by - * parsing, this is PKCS#1 v1.5 by default. - * - * \return 0 on success, or a specific error code. - */ -int mbedtls_pk_decrypt(mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** - * \brief Encrypt message (including padding if relevant). - * - * \param ctx The PK context to use. It must have been set up. - * \param input Message to encrypt - * \param ilen Message size - * \param output Encrypted output - * \param olen Encrypted output length - * \param osize Size of the output buffer - * \param f_rng RNG function, must not be \c NULL. - * \param p_rng RNG parameter - * - * \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is - * either PKCS#1 v1.5 or OAEP, depending on the padding mode in - * the underlying RSA context. For a pk object constructed by - * parsing, this is PKCS#1 v1.5 by default. - * - * \note \p f_rng is used for padding generation. - * - * \return 0 on success, or a specific error code. - */ -int mbedtls_pk_encrypt(mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** - * \brief Check if a public-private pair of keys matches. - * - * \param pub Context holding a public key. - * \param prv Context holding a private (and public) key. - * \param f_rng RNG function, must not be \c NULL. - * \param p_rng RNG parameter - * - * \return \c 0 on success (keys were checked and match each other). - * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not - * be checked - in that case they may or may not match. - * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid. - * \return Another non-zero value if the keys do not match. - */ -int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, - const mbedtls_pk_context *prv, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Export debug information - * - * \param ctx The PK context to use. It must have been initialized. - * \param items Place to write debug items - * - * \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA - */ -int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items); - -/** - * \brief Access the type name - * - * \param ctx The PK context to use. It must have been initialized. - * - * \return Type name on success, or "invalid PK" - */ -const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx); - -/** - * \brief Get the key type - * - * \param ctx The PK context to use. It must have been initialized. - * - * \return Type on success. - * \return #MBEDTLS_PK_NONE for a context that has not been set up. - */ -mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx); - -#if defined(MBEDTLS_RSA_C) -/** - * Quick access to an RSA context inside a PK context. - * - * \warning This function can only be used when the type of the context, as - * returned by mbedtls_pk_get_type(), is #MBEDTLS_PK_RSA. - * Ensuring that is the caller's responsibility. - * Alternatively, you can check whether this function returns NULL. - * - * \return The internal RSA context held by the PK context, or NULL. - */ -static inline mbedtls_rsa_context *mbedtls_pk_rsa(const mbedtls_pk_context pk) -{ - switch (mbedtls_pk_get_type(&pk)) { - case MBEDTLS_PK_RSA: - return (mbedtls_rsa_context *) (pk).MBEDTLS_PRIVATE(pk_ctx); - default: - return NULL; - } -} -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_ECP_C) -/** - * Quick access to an EC context inside a PK context. - * - * \warning This function can only be used when the type of the context, as - * returned by mbedtls_pk_get_type(), is #MBEDTLS_PK_ECKEY, - * #MBEDTLS_PK_ECKEY_DH, or #MBEDTLS_PK_ECDSA. - * Ensuring that is the caller's responsibility. - * Alternatively, you can check whether this function returns NULL. - * - * \return The internal EC context held by the PK context, or NULL. - */ -static inline mbedtls_ecp_keypair *mbedtls_pk_ec(const mbedtls_pk_context pk) -{ - switch (mbedtls_pk_get_type(&pk)) { - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: - return (mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx); - default: - return NULL; - } -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_PK_PARSE_C) -/** \ingroup pk_module */ -/** - * \brief Parse a private key in PEM or DER format - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param key Input buffer to parse. - * The buffer must contain the input exactly, with no - * extra trailing material. For PEM, the buffer must - * contain a null-terminated string. - * \param keylen Size of \b key in bytes. - * For PEM data, this includes the terminating null byte, - * so \p keylen must be equal to `strlen(key) + 1`. - * \param pwd Optional password for decryption. - * Pass \c NULL if expecting a non-encrypted key. - * Pass a string of \p pwdlen bytes if expecting an encrypted - * key; a non-encrypted key will also be accepted. - * The empty password is not supported. - * \param pwdlen Size of the password in bytes. - * Ignored if \p pwd is \c NULL. - * \param f_rng RNG function, must not be \c NULL. Used for blinding. - * \param p_rng RNG parameter - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a - * specific key type, check the result with mbedtls_pk_can_do(). - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_key(mbedtls_pk_context *ctx, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** \ingroup pk_module */ -/** - * \brief Parse a public key in PEM or DER format - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param key Input buffer to parse. - * The buffer must contain the input exactly, with no - * extra trailing material. For PEM, the buffer must - * contain a null-terminated string. - * \param keylen Size of \b key in bytes. - * For PEM data, this includes the terminating null byte, - * so \p keylen must be equal to `strlen(key) + 1`. - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a - * specific key type, check the result with mbedtls_pk_can_do(). - * - * \note For compressed points, see #MBEDTLS_ECP_PF_COMPRESSED for - * limitations. - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx, - const unsigned char *key, size_t keylen); - -#if defined(MBEDTLS_FS_IO) -/** \ingroup pk_module */ -/** - * \brief Load and parse a private key - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param path filename to read the private key from - * \param password Optional password to decrypt the file. - * Pass \c NULL if expecting a non-encrypted key. - * Pass a null-terminated string if expecting an encrypted - * key; a non-encrypted key will also be accepted. - * The empty password is not supported. - * \param f_rng RNG function, must not be \c NULL. Used for blinding. - * \param p_rng RNG parameter - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a - * specific key type, check the result with mbedtls_pk_can_do(). - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx, - const char *path, const char *password, - mbedtls_f_rng_t *f_rng, void *p_rng); - -/** \ingroup pk_module */ -/** - * \brief Load and parse a public key - * - * \param ctx The PK context to fill. It must have been initialized - * but not set up. - * \param path filename to read the public key from - * - * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If - * you need a specific key type, check the result with - * mbedtls_pk_can_do(). - * - * \note The key is also checked for correctness. - * - * \return 0 if successful, or a specific PK or PEM error code - */ -int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path); -#endif /* MBEDTLS_FS_IO */ -#endif /* MBEDTLS_PK_PARSE_C */ - -#if defined(MBEDTLS_PK_WRITE_C) -/** - * \brief Write a private key to a PKCS#1 or SEC1 DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx PK context which must contain a valid private key. - * \param buf buffer to write to - * \param size size of the buffer - * - * \return length of data written if successful, or a specific - * error code - */ -int mbedtls_pk_write_key_der(const mbedtls_pk_context *ctx, unsigned char *buf, size_t size); - -/** - * \brief Write a public key to a SubjectPublicKeyInfo DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx PK context which must contain a valid public or private key. - * \param buf buffer to write to - * \param size size of the buffer - * - * \return length of data written if successful, or a specific - * error code - */ -int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *ctx, unsigned char *buf, size_t size); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a public key to a PEM string - * - * \param ctx PK context which must contain a valid public or private key. - * \param buf Buffer to write to. The output includes a - * terminating null byte. - * \param size Size of the buffer in bytes. - * - * \return 0 if successful, or a specific error code - */ -int mbedtls_pk_write_pubkey_pem(const mbedtls_pk_context *ctx, unsigned char *buf, size_t size); - -/** - * \brief Write a private key to a PKCS#1 or SEC1 PEM string - * - * \param ctx PK context which must contain a valid private key. - * \param buf Buffer to write to. The output includes a - * terminating null byte. - * \param size Size of the buffer in bytes. - * - * \return 0 if successful, or a specific error code - */ -int mbedtls_pk_write_key_pem(const mbedtls_pk_context *ctx, unsigned char *buf, size_t size); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_PK_WRITE_C */ - -/* - * WARNING: Low-level functions. You probably do not want to use these unless - * you are certain you do ;) - */ - -#if defined(MBEDTLS_PK_PARSE_C) -/** - * \brief Parse a SubjectPublicKeyInfo DER structure - * - * \param p the position in the ASN.1 data - * \param end end of the buffer - * \param pk The PK context to fill. It must have been initialized - * but not set up. - * - * \return 0 if successful, or a specific PK error code - */ -int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end, - mbedtls_pk_context *pk); -#endif /* MBEDTLS_PK_PARSE_C */ - -#if defined(MBEDTLS_PK_WRITE_C) -/** - * \brief Write a subjectPublicKey to ASN.1 data - * Note: function works backwards in data buffer - * - * \param p reference to current position pointer - * \param start start of the buffer (for bounds-checking) - * \param key PK context which must contain a valid public or private key. - * - * \return the length written or a negative error code - */ -int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *key); -#endif /* MBEDTLS_PK_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PK_H */ diff --git a/vendor/mbedtls/include/mbedtls/pkcs12.h b/vendor/mbedtls/include/mbedtls/pkcs12.h deleted file mode 100644 index 87f7681f2..000000000 --- a/vendor/mbedtls/include/mbedtls/pkcs12.h +++ /dev/null @@ -1,186 +0,0 @@ -/** - * \file pkcs12.h - * - * \brief PKCS#12 Personal Information Exchange Syntax - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PKCS12_H -#define MBEDTLS_PKCS12_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/md.h" -#include "mbedtls/cipher.h" -#include "mbedtls/asn1.h" - -#include - -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA -0x1F80 -/** Feature not available, e.g. unsupported encryption scheme. */ -#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00 -/** PBE ASN.1 data not as expected. */ -#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 -/** Given private key password does not allow for correct decryption. */ -#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 - -#define MBEDTLS_PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */ -#define MBEDTLS_PKCS12_DERIVE_IV 2 /**< initialization vector */ -#define MBEDTLS_PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */ - -#define MBEDTLS_PKCS12_PBE_DECRYPT MBEDTLS_DECRYPT -#define MBEDTLS_PKCS12_PBE_ENCRYPT MBEDTLS_ENCRYPT - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief PKCS12 Password Based function (encryption / decryption) - * for cipher-based and mbedtls_md-based PBE's - * - * \note When encrypting, #MBEDTLS_CIPHER_PADDING_PKCS7 must - * be enabled at compile time. - * - * \deprecated This function is deprecated and will be removed in a - * future version of the library. - * Please use mbedtls_pkcs12_pbe_ext() instead. - * - * \warning When decrypting: - * - if #MBEDTLS_CIPHER_PADDING_PKCS7 is enabled at compile - * time, this function validates the CBC padding and returns - * #MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH if the padding is - * invalid. Note that this can help active adversaries - * attempting to brute-forcing the password. Note also that - * there is no guarantee that an invalid password will be - * detected (the chances of a valid padding with a random - * password are about 1/255). - * - if #MBEDTLS_CIPHER_PADDING_PKCS7 is disabled at compile - * time, this function does not validate the CBC padding. - * - * \param pbe_params an ASN1 buffer containing the pkcs-12 PbeParams structure - * \param mode either #MBEDTLS_PKCS12_PBE_ENCRYPT or - * #MBEDTLS_PKCS12_PBE_DECRYPT - * \param cipher_type the cipher used - * \param md_type the mbedtls_md used - * \param pwd Latin1-encoded password used. This may only be \c NULL when - * \p pwdlen is 0. No null terminator should be used. - * \param pwdlen length of the password (may be 0) - * \param data the input data - * \param len data length - * \param output Output buffer. - * On success, it contains the encrypted or decrypted data, - * possibly followed by the CBC padding. - * On failure, the content is indeterminate. - * For decryption, there must be enough room for \p len - * bytes. - * For encryption, there must be enough room for - * \p len + 1 bytes, rounded up to the block size of - * the block cipher identified by \p pbe_params. - * - * \return 0 if successful, or a MBEDTLS_ERR_XXX code - */ -int MBEDTLS_DEPRECATED mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, - mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - -/** - * \brief PKCS12 Password Based function (encryption / decryption) - * for cipher-based and mbedtls_md-based PBE's - * - * - * \warning When decrypting: - * - This function validates the CBC padding and returns - * #MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH if the padding is - * invalid. Note that this can help active adversaries - * attempting to brute-forcing the password. Note also that - * there is no guarantee that an invalid password will be - * detected (the chances of a valid padding with a random - * password are about 1/255). - * - * \param pbe_params an ASN1 buffer containing the pkcs-12 PbeParams structure - * \param mode either #MBEDTLS_PKCS12_PBE_ENCRYPT or - * #MBEDTLS_PKCS12_PBE_DECRYPT - * \param cipher_type the cipher used - * \param md_type the mbedtls_md used - * \param pwd Latin1-encoded password used. This may only be \c NULL when - * \p pwdlen is 0. No null terminator should be used. - * \param pwdlen length of the password (may be 0) - * \param data the input data - * \param len data length - * \param output Output buffer. - * On success, it contains the encrypted or decrypted data, - * possibly followed by the CBC padding. - * On failure, the content is indeterminate. - * For decryption, there must be enough room for \p len - * bytes. - * For encryption, there must be enough room for - * \p len + 1 bytes, rounded up to the block size of - * the block cipher identified by \p pbe_params. - * \param output_size size of output buffer. - * This must be big enough to accommodate for output plus - * padding data. - * \param output_len On success, length of actual data written to the output buffer. - * - * \return 0 if successful, or a MBEDTLS_ERR_XXX code - */ -int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output, size_t output_size, - size_t *output_len); - -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ - -#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C */ - -/** - * \brief The PKCS#12 derivation function uses a password and a salt - * to produce pseudo-random bits for a particular "purpose". - * - * Depending on the given id, this function can produce an - * encryption/decryption key, an initialization vector or an - * integrity key. - * - * \param data buffer to store the derived data in - * \param datalen length of buffer to fill - * \param pwd The password to use. For compliance with PKCS#12 §B.1, this - * should be a BMPString, i.e. a Unicode string where each - * character is encoded as 2 bytes in big-endian order, with - * no byte order mark and with a null terminator (i.e. the - * last two bytes should be 0x00 0x00). - * \param pwdlen length of the password (may be 0). - * \param salt Salt buffer to use. This may only be \c NULL when - * \p saltlen is 0. - * \param saltlen length of the salt (may be zero) - * \param mbedtls_md mbedtls_md type to use during the derivation - * \param id id that describes the purpose (can be - * #MBEDTLS_PKCS12_DERIVE_KEY, #MBEDTLS_PKCS12_DERIVE_IV or - * #MBEDTLS_PKCS12_DERIVE_MAC_KEY) - * \param iterations number of iterations - * - * \return 0 if successful, or a MD, BIGNUM type error. - */ -int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *salt, size_t saltlen, - mbedtls_md_type_t mbedtls_md, int id, int iterations); - -#ifdef __cplusplus -} -#endif - -#endif /* pkcs12.h */ diff --git a/vendor/mbedtls/include/mbedtls/pkcs5.h b/vendor/mbedtls/include/mbedtls/pkcs5.h deleted file mode 100644 index 9ba5689d4..000000000 --- a/vendor/mbedtls/include/mbedtls/pkcs5.h +++ /dev/null @@ -1,198 +0,0 @@ -/** - * \file pkcs5.h - * - * \brief PKCS#5 functions - * - * \author Mathias Olsson - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PKCS5_H -#define MBEDTLS_PKCS5_H - -#include "mbedtls/build_info.h" -#include "mbedtls/platform_util.h" - -#include "mbedtls/asn1.h" -#include "mbedtls/md.h" -#include "mbedtls/cipher.h" - -#include -#include - -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA -0x2f80 -/** Unexpected ASN.1 data. */ -#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT -0x2f00 -/** Requested encryption or digest alg not available. */ -#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE -0x2e80 -/** Given private key password does not allow for correct decryption. */ -#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00 - -#define MBEDTLS_PKCS5_DECRYPT MBEDTLS_DECRYPT -#define MBEDTLS_PKCS5_ENCRYPT MBEDTLS_ENCRYPT - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief PKCS#5 PBES2 function - * - * \note When encrypting, #MBEDTLS_CIPHER_PADDING_PKCS7 must - * be enabled at compile time. - * - * \deprecated This function is deprecated and will be removed in a - * future version of the library. - * Please use mbedtls_pkcs5_pbes2_ext() instead. - * - * \warning When decrypting: - * - if #MBEDTLS_CIPHER_PADDING_PKCS7 is enabled at compile - * time, this function validates the CBC padding and returns - * #MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH if the padding is - * invalid. Note that this can help active adversaries - * attempting to brute-forcing the password. Note also that - * there is no guarantee that an invalid password will be - * detected (the chances of a valid padding with a random - * password are about 1/255). - * - if #MBEDTLS_CIPHER_PADDING_PKCS7 is disabled at compile - * time, this function does not validate the CBC padding. - * - * \param pbe_params the ASN.1 algorithm parameters - * \param mode either #MBEDTLS_PKCS5_DECRYPT or #MBEDTLS_PKCS5_ENCRYPT - * \param pwd password to use when generating key - * \param pwdlen length of password - * \param data data to process - * \param datalen length of data - * \param output Output buffer. - * On success, it contains the encrypted or decrypted data, - * possibly followed by the CBC padding. - * On failure, the content is indeterminate. - * For decryption, there must be enough room for \p datalen - * bytes. - * For encryption, there must be enough room for - * \p datalen + 1 bytes, rounded up to the block size of - * the block cipher identified by \p pbe_params. - * - * \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. - */ -int MBEDTLS_DEPRECATED mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - -/** - * \brief PKCS#5 PBES2 function - * - * \warning When decrypting: - * - This function validates the CBC padding and returns - * #MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH if the padding is - * invalid. Note that this can help active adversaries - * attempting to brute-forcing the password. Note also that - * there is no guarantee that an invalid password will be - * detected (the chances of a valid padding with a random - * password are about 1/255). - * - * \param pbe_params the ASN.1 algorithm parameters - * \param mode either #MBEDTLS_PKCS5_DECRYPT or #MBEDTLS_PKCS5_ENCRYPT - * \param pwd password to use when generating key - * \param pwdlen length of password - * \param data data to process - * \param datalen length of data - * \param output Output buffer. - * On success, it contains the decrypted data. - * On failure, the content is indetermidate. - * For decryption, there must be enough room for \p datalen - * bytes. - * For encryption, there must be enough room for - * \p datalen + 1 bytes, rounded up to the block size of - * the block cipher identified by \p pbe_params. - * \param output_size size of output buffer. - * This must be big enough to accommodate for output plus - * padding data. - * \param output_len On success, length of actual data written to the output buffer. - * - * \returns 0 on success, or a MBEDTLS_ERR_XXX code if parsing or decryption fails. - */ -int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output, size_t output_size, - size_t *output_len); - -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ - -#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C*/ - -/** - * \brief PKCS#5 PBKDF2 using HMAC without using the HMAC context - * - * \param md_type Hash algorithm used - * \param password Password to use when generating key - * \param plen Length of password - * \param salt Salt to use when generating key - * \param slen Length of salt - * \param iteration_count Iteration count - * \param key_length Length of generated key in bytes - * \param output Generated key. Must be at least as big as key_length - * - * \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. - */ -int mbedtls_pkcs5_pbkdf2_hmac_ext(mbedtls_md_type_t md_type, - const unsigned char *password, - size_t plen, const unsigned char *salt, size_t slen, - unsigned int iteration_count, - uint32_t key_length, unsigned char *output); - -#if defined(MBEDTLS_MD_C) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief PKCS#5 PBKDF2 using HMAC - * - * \deprecated Superseded by mbedtls_pkcs5_pbkdf2_hmac_ext(). - * - * \param ctx Generic HMAC context - * \param password Password to use when generating key - * \param plen Length of password - * \param salt Salt to use when generating key - * \param slen Length of salt - * \param iteration_count Iteration count - * \param key_length Length of generated key in bytes - * \param output Generated key. Must be at least as big as key_length - * - * \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails. - */ -int MBEDTLS_DEPRECATED mbedtls_pkcs5_pbkdf2_hmac(mbedtls_md_context_t *ctx, - const unsigned char *password, - size_t plen, - const unsigned char *salt, - size_t slen, - unsigned int iteration_count, - uint32_t key_length, - unsigned char *output); -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_MD_C */ -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_pkcs5_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* pkcs5.h */ diff --git a/vendor/mbedtls/include/mbedtls/pkcs7.h b/vendor/mbedtls/include/mbedtls/pkcs7.h deleted file mode 100644 index e9b482208..000000000 --- a/vendor/mbedtls/include/mbedtls/pkcs7.h +++ /dev/null @@ -1,240 +0,0 @@ -/** - * \file pkcs7.h - * - * \brief PKCS #7 generic defines and structures - * https://tools.ietf.org/html/rfc2315 - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/** - * Note: For the time being, this implementation of the PKCS #7 cryptographic - * message syntax is a partial implementation of RFC 2315. - * Differences include: - * - The RFC specifies 6 different content types. The only type currently - * supported in Mbed TLS is the signed-data content type. - * - The only supported PKCS #7 Signed Data syntax version is version 1 - * - The RFC specifies support for BER. This implementation is limited to - * DER only. - * - The RFC specifies that multiple digest algorithms can be specified - * in the Signed Data type. Only one digest algorithm is supported in Mbed TLS. - * - The RFC specifies the Signed Data type can contain multiple X.509 or PKCS #6 extended - * certificates. In Mbed TLS, this list can only contain 0 or 1 certificates - * and they must be in X.509 format. - * - The RFC specifies the Signed Data type can contain - * certificate-revocation lists (CRLs). This implementation has no support - * for CRLs so it is assumed to be an empty list. - * - The RFC allows for SignerInfo structure to optionally contain - * unauthenticatedAttributes and authenticatedAttributes. In Mbed TLS it is - * assumed these fields are empty. - * - The RFC allows for the signed Data type to contain contentInfo. This - * implementation assumes the type is DATA and the content is empty. - */ - -#ifndef MBEDTLS_PKCS7_H -#define MBEDTLS_PKCS7_H - -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/asn1.h" -#include "mbedtls/x509_crt.h" - -/** - * \name PKCS #7 Module Error codes - * \{ - */ -#define MBEDTLS_ERR_PKCS7_INVALID_FORMAT -0x5300 /**< The format is invalid, e.g. different type expected. */ -#define MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE -0x5380 /**< Unavailable feature, e.g. anything other than signed data. */ -#define MBEDTLS_ERR_PKCS7_INVALID_VERSION -0x5400 /**< The PKCS #7 version element is invalid or cannot be parsed. */ -#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO -0x5480 /**< The PKCS #7 content info is invalid or cannot be parsed. */ -#define MBEDTLS_ERR_PKCS7_INVALID_ALG -0x5500 /**< The algorithm tag or value is invalid or cannot be parsed. */ -#define MBEDTLS_ERR_PKCS7_INVALID_CERT -0x5580 /**< The certificate tag or value is invalid or cannot be parsed. */ -#define MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE -0x5600 /**< Error parsing the signature */ -#define MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO -0x5680 /**< Error parsing the signer's info */ -#define MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA -0x5700 /**< Input invalid. */ -#define MBEDTLS_ERR_PKCS7_ALLOC_FAILED -0x5780 /**< Allocation of memory failed. */ -#define MBEDTLS_ERR_PKCS7_VERIFY_FAIL -0x5800 /**< Verification Failed */ -#define MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID -0x5880 /**< The PKCS #7 date issued/expired dates are invalid */ -/* \} name */ - -/** - * \name PKCS #7 Supported Version - * \{ - */ -#define MBEDTLS_PKCS7_SUPPORTED_VERSION 0x01 -/* \} name */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Type-length-value structure that allows for ASN.1 using DER. - */ -typedef mbedtls_asn1_buf mbedtls_pkcs7_buf; - -/** - * Container for ASN.1 named information objects. - * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.). - */ -typedef mbedtls_asn1_named_data mbedtls_pkcs7_name; - -/** - * Container for a sequence of ASN.1 items - */ -typedef mbedtls_asn1_sequence mbedtls_pkcs7_sequence; - -/** - * PKCS #7 types - */ -typedef enum { - MBEDTLS_PKCS7_NONE=0, - MBEDTLS_PKCS7_DATA, - MBEDTLS_PKCS7_SIGNED_DATA, - MBEDTLS_PKCS7_ENVELOPED_DATA, - MBEDTLS_PKCS7_SIGNED_AND_ENVELOPED_DATA, - MBEDTLS_PKCS7_DIGESTED_DATA, - MBEDTLS_PKCS7_ENCRYPTED_DATA, -} -mbedtls_pkcs7_type; - -/** - * Structure holding PKCS #7 signer info - */ -typedef struct mbedtls_pkcs7_signer_info { - int MBEDTLS_PRIVATE(version); - mbedtls_x509_buf MBEDTLS_PRIVATE(serial); - mbedtls_x509_name MBEDTLS_PRIVATE(issuer); - mbedtls_x509_buf MBEDTLS_PRIVATE(issuer_raw); - mbedtls_x509_buf MBEDTLS_PRIVATE(alg_identifier); - mbedtls_x509_buf MBEDTLS_PRIVATE(sig_alg_identifier); - mbedtls_x509_buf MBEDTLS_PRIVATE(sig); - struct mbedtls_pkcs7_signer_info *MBEDTLS_PRIVATE(next); -} -mbedtls_pkcs7_signer_info; - -/** - * Structure holding the signed data section - */ -typedef struct mbedtls_pkcs7_signed_data { - int MBEDTLS_PRIVATE(version); - mbedtls_pkcs7_buf MBEDTLS_PRIVATE(digest_alg_identifiers); - int MBEDTLS_PRIVATE(no_of_certs); - mbedtls_x509_crt MBEDTLS_PRIVATE(certs); - int MBEDTLS_PRIVATE(no_of_crls); - mbedtls_x509_crl MBEDTLS_PRIVATE(crl); - int MBEDTLS_PRIVATE(no_of_signers); - mbedtls_pkcs7_signer_info MBEDTLS_PRIVATE(signers); -} -mbedtls_pkcs7_signed_data; - -/** - * Structure holding PKCS #7 structure, only signed data for now - */ -typedef struct mbedtls_pkcs7 { - mbedtls_pkcs7_buf MBEDTLS_PRIVATE(raw); - mbedtls_pkcs7_signed_data MBEDTLS_PRIVATE(signed_data); -} -mbedtls_pkcs7; - -/** - * \brief Initialize mbedtls_pkcs7 structure. - * - * \param pkcs7 mbedtls_pkcs7 structure. - */ -void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7); - -/** - * \brief Parse a single DER formatted PKCS #7 detached signature. - * - * \param pkcs7 The mbedtls_pkcs7 structure to be filled by the parser. - * \param buf The buffer holding only the DER encoded PKCS #7 content. - * \param buflen The size in bytes of \p buf. The size must be exactly the - * length of the DER encoded PKCS #7 content. - * - * \note This function makes an internal copy of the PKCS #7 buffer - * \p buf. In particular, \p buf may be destroyed or reused - * after this call returns. - * \note Signatures with internal data are not supported. - * - * \return The \c mbedtls_pkcs7_type of \p buf, if successful. - * \return A negative error code on failure. - */ -int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf, - const size_t buflen); - -/** - * \brief Verification of PKCS #7 signature against a caller-supplied - * certificate. - * - * For each signer in the PKCS structure, this function computes - * a signature over the supplied data, using the supplied - * certificate and the same digest algorithm as specified by the - * signer. It then compares this signature against the - * signer's signature; verification succeeds if any comparison - * matches. - * - * This function does not use the certificates held within the - * PKCS #7 structure itself, and does not check that the - * certificate is signed by a trusted certification authority. - * - * \param pkcs7 mbedtls_pkcs7 structure containing signature. - * \param cert Certificate containing key to verify signature. - * \param data Plain data on which signature has to be verified. - * \param datalen Length of the data. - * - * \note This function internally calculates the hash on the supplied - * plain data for signature verification. - * - * \return 0 if the signature verifies, or a negative error code on failure. - */ -int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7, - const mbedtls_x509_crt *cert, - const unsigned char *data, - size_t datalen); - -/** - * \brief Verification of PKCS #7 signature against a caller-supplied - * certificate. - * - * For each signer in the PKCS structure, this function - * validates a signature over the supplied hash, using the - * supplied certificate and the same digest algorithm as - * specified by the signer. Verification succeeds if any - * signature is good. - * - * This function does not use the certificates held within the - * PKCS #7 structure itself, and does not check that the - * certificate is signed by a trusted certification authority. - * - * \param pkcs7 PKCS #7 structure containing signature. - * \param cert Certificate containing key to verify signature. - * \param hash Hash of the plain data on which signature has to be verified. - * \param hashlen Length of the hash. - * - * \note This function is different from mbedtls_pkcs7_signed_data_verify() - * in that it is directly passed the hash of the data. - * - * \return 0 if the signature verifies, or a negative error code on failure. - */ -int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7, - const mbedtls_x509_crt *cert, - const unsigned char *hash, size_t hashlen); - -/** - * \brief Unallocate all PKCS #7 data and zeroize the memory. - * It doesn't free \p pkcs7 itself. This should be done by the caller. - * - * \param pkcs7 mbedtls_pkcs7 structure to free. - */ -void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7); - -#ifdef __cplusplus -} -#endif - -#endif /* pkcs7.h */ diff --git a/vendor/mbedtls/include/mbedtls/platform.h b/vendor/mbedtls/include/mbedtls/platform.h deleted file mode 100644 index f1ec9975e..000000000 --- a/vendor/mbedtls/include/mbedtls/platform.h +++ /dev/null @@ -1,516 +0,0 @@ -/** - * \file platform.h - * - * \brief This file contains the definitions and functions of the - * Mbed TLS platform abstraction layer. - * - * The platform abstraction layer removes the need for the library - * to directly link to standard C library functions or operating - * system services, making the library easier to port and embed. - * Application developers and users of the library can provide their own - * implementations of these functions, or implementations specific to - * their platform, which can be statically linked to the library or - * dynamically configured at runtime. - * - * When all compilation options related to platform abstraction are - * disabled, this header just defines `mbedtls_xxx` function names - * as aliases to the standard `xxx` function. - * - * Most modules in the library and example programs are expected to - * include this header. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PLATFORM_H -#define MBEDTLS_PLATFORM_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them on the compiler command line. - * \{ - */ - -/* The older Microsoft Windows common runtime provides non-conforming - * implementations of some standard library functions, including snprintf - * and vsnprintf. This affects MSVC and MinGW builds. - */ -#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) -#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF -#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF -#endif - -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#include -#include -#if defined(MBEDTLS_HAVE_TIME) -#include -#endif -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) -#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ -#else -#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */ -#endif -#endif -#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) -#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */ -#else -#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */ -#endif -#endif -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_SETBUF) -#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< The default \c setbuf function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */ -#endif -#if defined(MBEDTLS_FS_IO) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" -#endif -#endif /* MBEDTLS_FS_IO */ -#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) -#include MBEDTLS_PLATFORM_STD_MEM_HDR -#endif -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - -/* Enable certain documented defines only when generating doxygen to avoid - * an "unrecognized define" error. */ -#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_CALLOC) -#define MBEDTLS_PLATFORM_STD_CALLOC -#endif - -#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_FREE) -#define MBEDTLS_PLATFORM_STD_FREE -#endif - -/** \} name SECTION: Module settings */ - -/* - * The function pointers for calloc and free. - * Please see MBEDTLS_PLATFORM_STD_CALLOC and MBEDTLS_PLATFORM_STD_FREE - * in mbedtls_config.h for more information about behaviour and requirements. - */ -#if defined(MBEDTLS_PLATFORM_MEMORY) -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ - defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#undef mbedtls_free -#undef mbedtls_calloc -#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO -#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO -#else -/* For size_t */ -#include -extern void *mbedtls_calloc(size_t n, size_t size); -extern void mbedtls_free(void *ptr); - -/** - * \brief This function dynamically sets the memory-management - * functions used by the library, during runtime. - * - * \param calloc_func The \c calloc function implementation. - * \param free_func The \c free function implementation. - * - * \return \c 0. - */ -int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t), - void (*free_func)(void *)); -#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ -#else /* !MBEDTLS_PLATFORM_MEMORY */ -#undef mbedtls_free -#undef mbedtls_calloc -#define mbedtls_free free -#define mbedtls_calloc calloc -#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ - -/* - * The function pointers for fprintf - */ -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -/* We need FILE * */ -#include -extern int (*mbedtls_fprintf)(FILE *stream, const char *format, ...); - -/** - * \brief This function dynamically configures the fprintf - * function that is called when the - * mbedtls_fprintf() function is invoked by the library. - * - * \param fprintf_func The \c fprintf function implementation. - * - * \return \c 0. - */ -int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *stream, const char *, - ...)); -#else -#undef mbedtls_fprintf -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) -#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO -#else -#define mbedtls_fprintf fprintf -#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -/* - * The function pointers for printf - */ -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -extern int (*mbedtls_printf)(const char *format, ...); - -/** - * \brief This function dynamically configures the snprintf - * function that is called when the mbedtls_snprintf() - * function is invoked by the library. - * - * \param printf_func The \c printf function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...)); -#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ -#undef mbedtls_printf -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) -#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO -#else -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -/* - * The function pointers for snprintf - * - * The snprintf implementation should conform to C99: - * - it *must* always correctly zero-terminate the buffer - * (except when n == 0, then it must leave the buffer untouched) - * - however it is acceptable to return -1 instead of the required length when - * the destination buffer is too short. - */ -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) -/* For Windows (inc. MSYS2), we provide our own fixed implementation */ -int mbedtls_platform_win32_snprintf(char *s, size_t n, const char *fmt, ...); -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -extern int (*mbedtls_snprintf)(char *s, size_t n, const char *format, ...); - -/** - * \brief This function allows configuring a custom - * \c snprintf function pointer. - * - * \param snprintf_func The \c snprintf function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n, - const char *format, ...)); -#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ -#undef mbedtls_snprintf -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO -#else -#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF -#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -/* - * The function pointers for vsnprintf - * - * The vsnprintf implementation should conform to C99: - * - it *must* always correctly zero-terminate the buffer - * (except when n == 0, then it must leave the buffer untouched) - * - however it is acceptable to return -1 instead of the required length when - * the destination buffer is too short. - */ -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) -#include -/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */ -int mbedtls_platform_win32_vsnprintf(char *s, size_t n, const char *fmt, va_list arg); -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) -#include -extern int (*mbedtls_vsnprintf)(char *s, size_t n, const char *format, va_list arg); - -/** - * \brief Set your own snprintf function pointer - * - * \param vsnprintf_func The \c vsnprintf function implementation - * - * \return \c 0 - */ -int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n, - const char *format, va_list arg)); -#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ -#undef mbedtls_vsnprintf -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) -#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO -#else -#define mbedtls_vsnprintf vsnprintf -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ - -/* - * The function pointers for setbuf - */ -#if defined(MBEDTLS_PLATFORM_SETBUF_ALT) -#include -/** - * \brief Function pointer to call for `setbuf()` functionality - * (changing the internal buffering on stdio calls). - * - * \note The library calls this function to disable - * buffering when reading or writing sensitive data, - * to avoid having extra copies of sensitive data - * remaining in stdio buffers after the file is - * closed. If this is not a concern, for example if - * your platform's stdio doesn't have any buffering, - * you can set mbedtls_setbuf to a function that - * does nothing. - * - * The library always calls this function with - * `buf` equal to `NULL`. - */ -extern void (*mbedtls_setbuf)(FILE *stream, char *buf); - -/** - * \brief Dynamically configure the function that is called - * when the mbedtls_setbuf() function is called by the - * library. - * - * \param setbuf_func The \c setbuf function implementation - * - * \return \c 0 - */ -int mbedtls_platform_set_setbuf(void (*setbuf_func)( - FILE *stream, char *buf)); -#else -#undef mbedtls_setbuf -#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO) -/** - * \brief Macro defining the function for the library to - * call for `setbuf` functionality (changing the - * internal buffering on stdio calls). - * - * \note See extra comments on the mbedtls_setbuf() function - * pointer above. - * - * \return \c 0 on success, negative on error. - */ -#define mbedtls_setbuf MBEDTLS_PLATFORM_SETBUF_MACRO -#else -#define mbedtls_setbuf setbuf -#endif /* MBEDTLS_PLATFORM_SETBUF_MACRO */ -#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */ - -/* - * The function pointers for exit - */ -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -extern void (*mbedtls_exit)(int status); - -/** - * \brief This function dynamically configures the exit - * function that is called when the mbedtls_exit() - * function is invoked by the library. - * - * \param exit_func The \c exit function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_exit(void (*exit_func)(int status)); -#else -#undef mbedtls_exit -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) -#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO -#else -#define mbedtls_exit exit -#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -/* - * The default exit values - */ -#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS -#else -#define MBEDTLS_EXIT_SUCCESS 0 -#endif -#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE -#else -#define MBEDTLS_EXIT_FAILURE 1 -#endif - -#if defined(MBEDTLS_ENTROPY_C) && \ - !defined(MBEDTLS_NO_PLATFORM_ENTROPY) && \ - !(defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)) -/* Platforms where MBEDTLS_PLATFORM_DEV_RANDOM is used - * unless a dedicated system call is available both at - * compile time and at run time. */ -#define MBEDTLS_PLATFORM_HAVE_DEV_RANDOM -#endif - -#if !defined(MBEDTLS_PLATFORM_DEV_RANDOM) -#define MBEDTLS_PLATFORM_DEV_RANDOM "/dev/random" -#endif - -/* Arrange for mbedtls_platform_dev_random to always be visible to - * Doxygen, because it's linked from the documentation of - * MBEDTLS_PLATFORM_DEV_RANDOM and that documentation can be visible - * even in configurations where it isn't used. */ -#if defined(MBEDTLS_PLATFORM_HAVE_DEV_RANDOM) || defined(__DOXYGEN__) -/** - * Path to a special file that returns cryptographic-quality random bytes - * when read. - * - * This variable is only declared on platforms where it is used. - * It is available when the macro `MBEDTLS_PLATFORM_HAVE_DEV_RANDOM` is defined. - * - * The default value is #MBEDTLS_PLATFORM_DEV_RANDOM. - * See the documentation of this option for guidance. - */ -extern const char *mbedtls_platform_dev_random; -#endif - -/* - * The function pointers for reading from and writing a seed file to - * Non-Volatile storage (NV) in a platform-independent way - * - * Only enabled when the NV seed entropy source is enabled - */ -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Internal standard platform definitions */ -int mbedtls_platform_std_nv_seed_read(unsigned char *buf, size_t buf_len); -int mbedtls_platform_std_nv_seed_write(unsigned char *buf, size_t buf_len); -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -extern int (*mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len); -extern int (*mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len); - -/** - * \brief This function allows configuring custom seed file writing and - * reading functions. - * - * \param nv_seed_read_func The seed reading function implementation. - * \param nv_seed_write_func The seed writing function implementation. - * - * \return \c 0 on success. - */ -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)(unsigned char *buf, size_t buf_len), - int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len) - ); -#else -#undef mbedtls_nv_seed_read -#undef mbedtls_nv_seed_write -#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ - defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) -#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO -#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO -#else -#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read -#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write -#endif -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) - -/** - * \brief The platform context structure. - * - * \note This structure may be used to assist platform-specific - * setup or teardown operations. - */ -typedef struct mbedtls_platform_context { - char MBEDTLS_PRIVATE(dummy); /**< A placeholder member, as empty structs are not portable. */ -} -mbedtls_platform_context; - -#else -#include "platform_alt.h" -#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ - -/** - * \brief This function performs any platform-specific initialization - * operations. - * - * \note This function should be called before any other library functions. - * - * Its implementation is platform-specific, and unless - * platform-specific code is provided, it does nothing. - * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. - * - * \return \c 0 on success. - */ -int mbedtls_platform_setup(mbedtls_platform_context *ctx); -/** - * \brief This function performs any platform teardown operations. - * - * \note This function should be called after every other Mbed TLS module - * has been correctly freed using the appropriate free function. - * - * Its implementation is platform-specific, and unless - * platform-specific code is provided, it does nothing. - * - * \note The usage and necessity of this function is dependent on the platform. - * - * \param ctx The platform context. - * - */ -void mbedtls_platform_teardown(mbedtls_platform_context *ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* platform.h */ diff --git a/vendor/mbedtls/include/mbedtls/platform_time.h b/vendor/mbedtls/include/mbedtls/platform_time.h deleted file mode 100644 index 97f1963ab..000000000 --- a/vendor/mbedtls/include/mbedtls/platform_time.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * \file platform_time.h - * - * \brief Mbed TLS Platform time abstraction - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PLATFORM_TIME_H -#define MBEDTLS_PLATFORM_TIME_H - -#include "mbedtls/build_info.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The time_t datatype - */ -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) -typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; -#else -/* For time_t */ -#include -typedef time_t mbedtls_time_t; -#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ - -#if defined(MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO) -typedef MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO mbedtls_ms_time_t; -#else -#include -#include -typedef int64_t mbedtls_ms_time_t; -#endif /* MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO */ - -/** - * \brief Get time in milliseconds. - * - * \return Monotonically-increasing current time in milliseconds. - * - * \note Define MBEDTLS_PLATFORM_MS_TIME_ALT to be able to provide an - * alternative implementation - * - * \warning This function returns a monotonically-increasing time value from a - * start time that will differ from platform to platform, and possibly - * from run to run of the process. - * - */ -mbedtls_ms_time_t mbedtls_ms_time(void); - -/* - * The function pointers for time - */ -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -extern mbedtls_time_t (*mbedtls_time)(mbedtls_time_t *time); - -/** - * \brief Set your own time function pointer - * - * \param time_func the time function implementation - * - * \return 0 - */ -int mbedtls_platform_set_time(mbedtls_time_t (*time_func)(mbedtls_time_t *time)); -#else -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) -#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO -#else -#define mbedtls_time time -#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#ifdef __cplusplus -} -#endif - -#endif /* platform_time.h */ diff --git a/vendor/mbedtls/include/mbedtls/platform_util.h b/vendor/mbedtls/include/mbedtls/platform_util.h deleted file mode 100644 index adad6bc3f..000000000 --- a/vendor/mbedtls/include/mbedtls/platform_util.h +++ /dev/null @@ -1,247 +0,0 @@ -/** - * \file platform_util.h - * - * \brief Common and shared functions used by multiple modules in the Mbed TLS - * library. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PLATFORM_UTIL_H -#define MBEDTLS_PLATFORM_UTIL_H - -#include "mbedtls/build_info.h" - -#include -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "mbedtls/platform_time.h" -#include -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Internal helper macros for deprecating API constants. */ -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -MBEDTLS_DEPRECATED typedef char const *mbedtls_deprecated_string_constant_t; -#define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) \ - ((mbedtls_deprecated_string_constant_t) (VAL)) -MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) \ - ((mbedtls_deprecated_numeric_constant_t) (VAL)) -#else /* MBEDTLS_DEPRECATED_WARNING */ -#define MBEDTLS_DEPRECATED -#define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) VAL -#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) VAL -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/* Implementation of the check-return facility. - * See the user documentation in mbedtls_config.h. - * - * Do not use this macro directly to annotate function: instead, - * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL - * depending on how important it is to check the return value. - */ -#if !defined(MBEDTLS_CHECK_RETURN) -#if defined(__GNUC__) -#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) -#elif defined(_MSC_VER) && _MSC_VER >= 1700 -#include -#define MBEDTLS_CHECK_RETURN _Check_return_ -#else -#define MBEDTLS_CHECK_RETURN -#endif -#endif - -/** Critical-failure function - * - * This macro appearing at the beginning of the declaration of a function - * indicates that its return value should be checked in all applications. - * Omitting the check is very likely to indicate a bug in the application - * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN - * is implemented for the compiler in use. - * - * \note The use of this macro is a work in progress. - * This macro may be added to more functions in the future. - * Such an extension is not considered an API break, provided that - * there are near-unavoidable circumstances under which the function - * can fail. For example, signature/MAC/AEAD verification functions, - * and functions that require a random generator, are considered - * return-check-critical. - */ -#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN - -/** Ordinary-failure function - * - * This macro appearing at the beginning of the declaration of a function - * indicates that its return value should be generally be checked in portable - * applications. Omitting the check will result in a compile-time warning if - * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and - * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration. - * - * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value - * of a function that is annotated with #MBEDTLS_CHECK_RETURN. - * - * \note The use of this macro is a work in progress. - * This macro will be added to more functions in the future. - * Eventually this should appear before most functions returning - * an error code (as \c int in the \c mbedtls_xxx API or - * as ::psa_status_t in the \c psa_xxx API). - */ -#if defined(MBEDTLS_CHECK_RETURN_WARNING) -#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN -#else -#define MBEDTLS_CHECK_RETURN_TYPICAL -#endif - -/** Benign-failure function - * - * This macro appearing at the beginning of the declaration of a function - * indicates that it is rarely useful to check its return value. - * - * This macro has an empty expansion. It exists for documentation purposes: - * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function - * has been analyzed for return-check usefulness, whereas the lack of - * an annotation indicates that the function has not been analyzed and its - * return-check usefulness is unknown. - */ -#define MBEDTLS_CHECK_RETURN_OPTIONAL - -/** \def MBEDTLS_IGNORE_RETURN - * - * Call this macro with one argument, a function call, to suppress a warning - * from #MBEDTLS_CHECK_RETURN due to that function call. - */ -#if !defined(MBEDTLS_IGNORE_RETURN) -/* GCC doesn't silence the warning with just (void)(result). - * (void)!(result) is known to work up at least up to GCC 10, as well - * as with Clang and MSVC. - * - * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html - * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34 - */ -#define MBEDTLS_IGNORE_RETURN(result) ((void) !(result)) -#endif - -/* If the following macro is defined, the library is being built by the test - * framework, and the framework is going to provide a replacement - * mbedtls_platform_zeroize() using a preprocessor macro, so the function - * declaration should be omitted. */ -#if !defined(MBEDTLS_TEST_DEFINES_ZEROIZE) //no-check-names -/** - * \brief Securely zeroize a buffer - * - * The function is meant to wipe the data contained in a buffer so - * that it can no longer be recovered even if the program memory - * is later compromised. Call this function on sensitive data - * stored on the stack before returning from a function, and on - * sensitive data stored on the heap before freeing the heap - * object. - * - * It is extremely difficult to guarantee that calls to - * mbedtls_platform_zeroize() are not removed by aggressive - * compiler optimizations in a portable way. For this reason, Mbed - * TLS provides the configuration option - * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for - * their platform and needs - * - * \param buf Buffer to be zeroized - * \param len Length of the buffer in bytes - * - */ -void mbedtls_platform_zeroize(void *buf, size_t len); -#endif - -/** \brief The type of custom random generator (RNG) callbacks. - * - * Many Mbed TLS functions take two parameters - * `mbedtls_f_rng_t *f_rng, void *p_rng`. The - * library will call \c f_rng to generate - * random values. - * - * \note This is typically one of the following: - * - mbedtls_ctr_drbg_random() with \c p_rng - * pointing to a #mbedtls_ctr_drbg_context; - * - mbedtls_hmac_drbg_random() with \c p_rng - * pointing to a #mbedtls_hmac_drbg_context; - * - mbedtls_psa_get_random() with - * `prng = MBEDTLS_PSA_RANDOM_STATE`. - * - * \note Generally, given a call - * `mbedtls_foo(f_rng, p_rng, ....)`, the RNG callback - * and the context only need to remain valid until - * the call to `mbedtls_foo` returns. However, there - * are a few exceptions where the callback is stored - * in for future use. Check the documentation of - * the calling function. - * - * \warning In a multithreaded environment, calling the - * function should be thread-safe. The standard - * functions provided by the library are thread-safe - * when #MBEDTLS_THREADING_C is enabled. - * - * \warning This function must either provide as many - * bytes as requested of **cryptographic quality** - * random data, or return a negative error code. - * - * \param p_rng The \c p_rng argument that was passed along \c f_rng. - * The library always passes \c p_rng unchanged. - * This is typically a pointer to the random generator - * state, or \c NULL if the custom random generator - * doesn't need a context-specific state. - * \param[out] output On success, this must be filled with \p output_size - * bytes of cryptographic-quality random data. - * \param output_size The number of bytes to output. - * - * \return \c 0 on success, or a negative error code on failure. - * Library functions will generally propagate this - * error code, so \c MBEDTLS_ERR_xxx values are - * recommended. #MBEDTLS_ERR_ENTROPY_SOURCE_FAILED is - * typically sensible for RNG failures. - */ -typedef int mbedtls_f_rng_t(void *p_rng, - unsigned char *output, size_t output_size); - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/** - * \brief Platform-specific implementation of gmtime_r() - * - * The function is a thread-safe abstraction that behaves - * similarly to the gmtime_r() function from Unix/POSIX. - * - * Mbed TLS will try to identify the underlying platform and - * make use of an appropriate underlying implementation (e.g. - * gmtime_r() for POSIX and gmtime_s() for Windows). If this is - * not possible, then gmtime() will be used. In this case, calls - * from the library to gmtime() will be guarded by the mutex - * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is - * enabled. It is recommended that calls from outside the library - * are also guarded by this mutex. - * - * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will - * unconditionally use the alternative implementation for - * mbedtls_platform_gmtime_r() supplied by the user at compile time. - * - * \param tt Pointer to an object containing time (in seconds) since the - * epoch to be converted - * \param tm_buf Pointer to an object where the results will be stored - * - * \return Pointer to an object of type struct tm on success, otherwise - * NULL - */ -struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt, - struct tm *tm_buf); -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PLATFORM_UTIL_H */ diff --git a/vendor/mbedtls/include/mbedtls/poly1305.h b/vendor/mbedtls/include/mbedtls/poly1305.h deleted file mode 100644 index 61bcaa6b6..000000000 --- a/vendor/mbedtls/include/mbedtls/poly1305.h +++ /dev/null @@ -1,168 +0,0 @@ -/** - * \file poly1305.h - * - * \brief This file contains Poly1305 definitions and functions. - * - * Poly1305 is a one-time message authenticator that can be used to - * authenticate messages. Poly1305-AES was created by Daniel - * Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic - * Poly1305 algorithm (not tied to AES) was also standardized in RFC - * 7539. - * - * \author Daniel King - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_POLY1305_H -#define MBEDTLS_POLY1305_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -/** Invalid input parameter(s). */ -#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0057 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_POLY1305_ALT) - -typedef struct mbedtls_poly1305_context { - uint32_t MBEDTLS_PRIVATE(r)[4]; /** The value for 'r' (low 128 bits of the key). */ - uint32_t MBEDTLS_PRIVATE(s)[4]; /** The value for 's' (high 128 bits of the key). */ - uint32_t MBEDTLS_PRIVATE(acc)[5]; /** The accumulator number. */ - uint8_t MBEDTLS_PRIVATE(queue)[16]; /** The current partial block of data. */ - size_t MBEDTLS_PRIVATE(queue_len); /** The number of bytes stored in 'queue'. */ -} -mbedtls_poly1305_context; - -#else /* MBEDTLS_POLY1305_ALT */ -#include "poly1305_alt.h" -#endif /* MBEDTLS_POLY1305_ALT */ - -/** - * \brief This function initializes the specified Poly1305 context. - * - * It must be the first API called before using - * the context. - * - * It is usually followed by a call to - * \c mbedtls_poly1305_starts(), then one or more calls to - * \c mbedtls_poly1305_update(), then one call to - * \c mbedtls_poly1305_finish(), then finally - * \c mbedtls_poly1305_free(). - * - * \param ctx The Poly1305 context to initialize. This must - * not be \c NULL. - */ -void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx); - -/** - * \brief This function releases and clears the specified - * Poly1305 context. - * - * \param ctx The Poly1305 context to clear. This may be \c NULL, in which - * case this function is a no-op. If it is not \c NULL, it must - * point to an initialized Poly1305 context. - */ -void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx); - -/** - * \brief This function sets the one-time authentication key. - * - * \warning The key must be unique and unpredictable for each - * invocation of Poly1305. - * - * \param ctx The Poly1305 context to which the key should be bound. - * This must be initialized. - * \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx, - const unsigned char key[32]); - -/** - * \brief This functions feeds an input buffer into an ongoing - * Poly1305 computation. - * - * It is called between \c mbedtls_cipher_poly1305_starts() and - * \c mbedtls_cipher_poly1305_finish(). - * It can be called repeatedly to process a stream of data. - * - * \param ctx The Poly1305 context to use for the Poly1305 operation. - * This must be initialized and bound to a key. - * \param ilen The length of the input data in Bytes. - * Any value is accepted. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `ilen == 0`. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx, - const unsigned char *input, - size_t ilen); - -/** - * \brief This function generates the Poly1305 Message - * Authentication Code (MAC). - * - * \param ctx The Poly1305 context to use for the Poly1305 operation. - * This must be initialized and bound to a key. - * \param mac The buffer to where the MAC is written. This must - * be a writable buffer of length \c 16 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx, - unsigned char mac[16]); - -/** - * \brief This function calculates the Poly1305 MAC of the input - * buffer with the provided key. - * - * \warning The key must be unique and unpredictable for each - * invocation of Poly1305. - * - * \param key The buffer containing the \c 32 Byte (\c 256 Bit) key. - * \param ilen The length of the input data in Bytes. - * Any value is accepted. - * \param input The buffer holding the input data. - * This pointer can be \c NULL if `ilen == 0`. - * \param mac The buffer to where the MAC is written. This must be - * a writable buffer of length \c 16 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_poly1305_mac(const unsigned char key[32], - const unsigned char *input, - size_t ilen, - unsigned char mac[16]); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief The Poly1305 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_poly1305_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_POLY1305_H */ diff --git a/vendor/mbedtls/include/mbedtls/private_access.h b/vendor/mbedtls/include/mbedtls/private_access.h deleted file mode 100644 index 580f3eb44..000000000 --- a/vendor/mbedtls/include/mbedtls/private_access.h +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \file private_access.h - * - * \brief Macro wrapper for struct's members. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_PRIVATE_ACCESS_H -#define MBEDTLS_PRIVATE_ACCESS_H - -#ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS -#define MBEDTLS_PRIVATE(member) private_##member -#else -#define MBEDTLS_PRIVATE(member) member -#endif - -#endif /* MBEDTLS_PRIVATE_ACCESS_H */ diff --git a/vendor/mbedtls/include/mbedtls/psa_util.h b/vendor/mbedtls/include/mbedtls/psa_util.h deleted file mode 100644 index b898f1f8d..000000000 --- a/vendor/mbedtls/include/mbedtls/psa_util.h +++ /dev/null @@ -1,207 +0,0 @@ -/** - * \file psa_util.h - * - * \brief Utility functions for the use of the PSA Crypto library. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_PSA_UTIL_H -#define MBEDTLS_PSA_UTIL_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "psa/crypto.h" - -/* ASN1 defines used in the ECDSA conversion functions. - * Note: intentionally not adding MBEDTLS_ASN1_[PARSE|WRITE]_C guards here - * otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/ -#include - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) - -/** The random generator function for the PSA subsystem. - * - * This function is suitable as the `f_rng` random generator function - * parameter of many `mbedtls_xxx` functions. - * - * The implementation of this function depends on the configuration of the - * library. - * - * \note This function may only be used if the PSA crypto subsystem is active. - * This means that you must call psa_crypto_init() before any call to - * this function, and you must not call this function after calling - * mbedtls_psa_crypto_free(). - * - * \param p_rng This parameter is only kept for backward compatibility - * reasons with legacy `f_rng` functions and it's ignored. - * Set to #MBEDTLS_PSA_RANDOM_STATE or NULL. - * \param output The buffer to fill. It must have room for - * \c output_size bytes. - * \param output_size The number of bytes to write to \p output. - * This function may fail if \p output_size is too - * large. It is guaranteed to accept any output size - * requested by Mbed TLS library functions. The - * maximum request size depends on the library - * configuration. - * - * \return \c 0 on success. - * \return An `MBEDTLS_ERR_ENTROPY_xxx`, - * `MBEDTLS_ERR_PLATFORM_xxx, - * `MBEDTLS_ERR_CTR_DRBG_xxx` or - * `MBEDTLS_ERR_HMAC_DRBG_xxx` on error. - */ -int mbedtls_psa_get_random(void *p_rng, - unsigned char *output, - size_t output_size); - -/** The random generator state for the PSA subsystem. - * - * This macro always expands to NULL because the `p_rng` parameter is unused - * in mbedtls_psa_get_random(), but it's kept for interface's backward - * compatibility. - */ -#define MBEDTLS_PSA_RANDOM_STATE NULL - -/** \defgroup psa_tls_helpers TLS helper functions - * @{ - */ -#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -#include - -/** Convert an ECC curve identifier from the Mbed TLS encoding to PSA. - * - * \param grpid An Mbed TLS elliptic curve identifier - * (`MBEDTLS_ECP_DP_xxx`). - * \param[out] bits On success the bit size of the curve; 0 on failure. - * - * \return If the curve is supported in the PSA API, this function - * returns the proper PSA curve identifier - * (`PSA_ECC_FAMILY_xxx`). This holds even if the curve is - * not supported by the ECP module. - * \return \c 0 if the curve is not supported in the PSA API. - */ -psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, - size_t *bits); - -/** Convert an ECC curve identifier from the PSA encoding to Mbed TLS. - * - * \param family A PSA elliptic curve family identifier - * (`PSA_ECC_FAMILY_xxx`). - * \param bits The bit-length of a private key on \p curve. - * - * \return If the curve is supported in the PSA API, this function - * returns the corresponding Mbed TLS elliptic curve - * identifier (`MBEDTLS_ECP_DP_xxx`). - * \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve - * and \p bits is not supported. - */ -mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family, - size_t bits); -#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ - -/** - * \brief This function returns the PSA algorithm identifier - * associated with the given digest type. - * - * \param md_type The type of digest to search for. Must not be NONE. - * - * \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will - * not return \c PSA_ALG_NONE, but an invalid algorithm. - * - * \warning This function does not check if the algorithm is - * supported, it always returns the corresponding identifier. - * - * \return The PSA algorithm identifier associated with \p md_type, - * regardless of whether it is supported or not. - */ -static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type) -{ - return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type; -} - -/** - * \brief This function returns the given digest type - * associated with the PSA algorithm identifier. - * - * \param psa_alg The PSA algorithm identifier to search for. - * - * \warning This function does not check if the algorithm is - * supported, it always returns the corresponding identifier. - * - * \return The MD type associated with \p psa_alg, - * regardless of whether it is supported or not. - */ -static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg) -{ - return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK); -} -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ - -#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) - -/** Convert an ECDSA signature from raw format to DER ASN.1 format. - * - * \param bits Size of each coordinate in bits. - * \param raw Buffer that contains the signature in raw format. - * \param raw_len Length of \p raw in bytes. This must be - * PSA_BITS_TO_BYTES(bits) bytes. - * \param[out] der Buffer that will be filled with the converted DER - * output. It can overlap with raw buffer. - * \param der_size Size of \p der in bytes. It is enough if \p der_size - * is at least the size of the actual output. (The size - * of the output can vary depending on the presence of - * leading zeros in the data.) You can use - * #MBEDTLS_ECDSA_MAX_SIG_LEN(\p bits) to determine a - * size that is large enough for all signatures for a - * given value of \p bits. - * \param[out] der_len On success it contains the amount of valid data - * (in bytes) written to \p der. It's undefined - * in case of failure. - * - * \note The behavior is undefined if \p der is null, - * even if \p der_size is 0. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if \p der_size - * is too small or if \p bits is larger than the - * largest supported curve. - * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if one of the - * numbers in the signature is 0. - */ -int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len, - unsigned char *der, size_t der_size, size_t *der_len); - -/** Convert an ECDSA signature from DER ASN.1 format to raw format. - * - * \param bits Size of each coordinate in bits. - * \param der Buffer that contains the signature in DER format. - * \param der_len Size of \p der in bytes. - * \param[out] raw Buffer that will be filled with the converted raw - * signature. It can overlap with der buffer. - * \param raw_size Size of \p raw in bytes. Must be at least - * 2 * PSA_BITS_TO_BYTES(bits) bytes. - * \param[out] raw_len On success it is updated with the amount of valid - * data (in bytes) written to \p raw. It's undefined - * in case of failure. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if \p raw_size - * is too small or if \p bits is larger than the - * largest supported curve. - * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the data in - * \p der is inconsistent with \p bits. - * \return An \c MBEDTLS_ERR_ASN1_xxx error code if - * \p der is malformed. - */ -int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len, - unsigned char *raw, size_t raw_size, size_t *raw_len); - -#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ - -/**@}*/ - -#endif /* MBEDTLS_PSA_UTIL_H */ diff --git a/vendor/mbedtls/include/mbedtls/ripemd160.h b/vendor/mbedtls/include/mbedtls/ripemd160.h deleted file mode 100644 index 279f92b51..000000000 --- a/vendor/mbedtls/include/mbedtls/ripemd160.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * \file ripemd160.h - * - * \brief RIPE MD-160 message digest - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_RIPEMD160_H -#define MBEDTLS_RIPEMD160_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_RIPEMD160_ALT) -// Regular implementation -// - -/** - * \brief RIPEMD-160 context structure - */ -typedef struct mbedtls_ripemd160_context { - uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< number of bytes processed */ - uint32_t MBEDTLS_PRIVATE(state)[5]; /*!< intermediate digest state */ - unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< data block being processed */ -} -mbedtls_ripemd160_context; - -#else /* MBEDTLS_RIPEMD160_ALT */ -#include "ripemd160_alt.h" -#endif /* MBEDTLS_RIPEMD160_ALT */ - -/** - * \brief Initialize RIPEMD-160 context - * - * \param ctx RIPEMD-160 context to be initialized - */ -void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx); - -/** - * \brief Clear RIPEMD-160 context - * - * \param ctx RIPEMD-160 context to be cleared - */ -void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx); - -/** - * \brief Clone (the state of) a RIPEMD-160 context - * - * \param dst The destination context - * \param src The context to be cloned - */ -void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst, - const mbedtls_ripemd160_context *src); - -/** - * \brief RIPEMD-160 context setup - * - * \param ctx context to be initialized - * - * \return 0 if successful - */ -int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx); - -/** - * \brief RIPEMD-160 process buffer - * - * \param ctx RIPEMD-160 context - * \param input buffer holding the data - * \param ilen length of the input data - * - * \return 0 if successful - */ -int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen); - -/** - * \brief RIPEMD-160 final digest - * - * \param ctx RIPEMD-160 context - * \param output RIPEMD-160 checksum result - * - * \return 0 if successful - */ -int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx, - unsigned char output[20]); - -/** - * \brief RIPEMD-160 process data block (internal use only) - * - * \param ctx RIPEMD-160 context - * \param data buffer holding one block of data - * - * \return 0 if successful - */ -int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx, - const unsigned char data[64]); - -/** - * \brief Output = RIPEMD-160( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output RIPEMD-160 checksum result - * - * \return 0 if successful - */ -int mbedtls_ripemd160(const unsigned char *input, - size_t ilen, - unsigned char output[20]); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_ripemd160_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_ripemd160.h */ diff --git a/vendor/mbedtls/include/mbedtls/rsa.h b/vendor/mbedtls/include/mbedtls/rsa.h deleted file mode 100644 index 3f0881a43..000000000 --- a/vendor/mbedtls/include/mbedtls/rsa.h +++ /dev/null @@ -1,1164 +0,0 @@ -/** - * \file rsa.h - * - * \brief This file provides an API for the RSA public-key cryptosystem. - * - * The RSA public-key cryptosystem is defined in Public-Key - * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption - * and Public-Key Cryptography Standards (PKCS) #1 v2.1: - * RSA Cryptography Specifications. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_RSA_H -#define MBEDTLS_RSA_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/bignum.h" -#include "mbedtls/md.h" - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -/* - * RSA Error codes - */ -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA -0x4080 -/** Input data contains invalid padding and is rejected. */ -#define MBEDTLS_ERR_RSA_INVALID_PADDING -0x4100 -/** Something failed during generation of a key. */ -#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED -0x4180 -/** Key failed to pass the validity check of the library. */ -#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -0x4200 -/** The public key operation failed. */ -#define MBEDTLS_ERR_RSA_PUBLIC_FAILED -0x4280 -/** The private key operation failed. */ -#define MBEDTLS_ERR_RSA_PRIVATE_FAILED -0x4300 -/** The PKCS#1 verification failed. */ -#define MBEDTLS_ERR_RSA_VERIFY_FAILED -0x4380 -/** The output buffer for decryption is not large enough. */ -#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 -/** The random generator failed to generate non-zeros. */ -#define MBEDTLS_ERR_RSA_RNG_FAILED -0x4480 - -/* - * RSA constants - */ - -#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */ -#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */ - -#define MBEDTLS_RSA_SIGN 1 /**< Identifier for RSA signature operations. */ -#define MBEDTLS_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */ - -#define MBEDTLS_RSA_SALT_LEN_ANY -1 - -/* - * The above constants may be used even if the RSA module is compile out, - * eg for alternative (PKCS#11) RSA implementations in the PK layers. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_RSA_ALT) -// Regular implementation -// - -#if !defined(MBEDTLS_RSA_GEN_KEY_MIN_BITS) -#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024 -#elif MBEDTLS_RSA_GEN_KEY_MIN_BITS < 128 -#error "MBEDTLS_RSA_GEN_KEY_MIN_BITS must be at least 128 bits" -#endif - -/** - * \brief The RSA context structure. - */ -typedef struct mbedtls_rsa_context { - int MBEDTLS_PRIVATE(ver); /*!< Reserved for internal purposes. - * Do not set this field in application - * code. Its meaning might change without - * notice. */ - size_t MBEDTLS_PRIVATE(len); /*!< The size of \p N in Bytes. */ - - mbedtls_mpi MBEDTLS_PRIVATE(N); /*!< The public modulus. */ - mbedtls_mpi MBEDTLS_PRIVATE(E); /*!< The public exponent. */ - - mbedtls_mpi MBEDTLS_PRIVATE(D); /*!< The private exponent. */ - mbedtls_mpi MBEDTLS_PRIVATE(P); /*!< The first prime factor. */ - mbedtls_mpi MBEDTLS_PRIVATE(Q); /*!< The second prime factor. */ - - mbedtls_mpi MBEDTLS_PRIVATE(DP); /*!< D % (P - 1). */ - mbedtls_mpi MBEDTLS_PRIVATE(DQ); /*!< D % (Q - 1). */ - mbedtls_mpi MBEDTLS_PRIVATE(QP); /*!< 1 / (Q % P). */ - - mbedtls_mpi MBEDTLS_PRIVATE(RN); /*!< cached R^2 mod N. */ - - mbedtls_mpi MBEDTLS_PRIVATE(RP); /*!< cached R^2 mod P. */ - mbedtls_mpi MBEDTLS_PRIVATE(RQ); /*!< cached R^2 mod Q. */ - - mbedtls_mpi MBEDTLS_PRIVATE(Vi); /*!< The cached blinding value. */ - mbedtls_mpi MBEDTLS_PRIVATE(Vf); /*!< The cached un-blinding value. */ - - int MBEDTLS_PRIVATE(padding); /*!< Selects padding mode: - #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and - #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */ - int MBEDTLS_PRIVATE(hash_id); /*!< Hash identifier of mbedtls_md_type_t type, - as specified in md.h for use in the MGF - mask generating function used in the - EME-OAEP and EMSA-PSS encodings. */ -#if defined(MBEDTLS_THREADING_C) - /* Invariant: the mutex is initialized iff ver != 0. */ - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); /*!< Thread-safety mutex. */ -#endif -} -mbedtls_rsa_context; - -#else /* MBEDTLS_RSA_ALT */ -#include "rsa_alt.h" -#endif /* MBEDTLS_RSA_ALT */ - -/** - * \brief This function initializes an RSA context. - * - * \note This function initializes the padding and the hash - * identifier to respectively #MBEDTLS_RSA_PKCS_V15 and - * #MBEDTLS_MD_NONE. See mbedtls_rsa_set_padding() for more - * information about those parameters. - * - * \param ctx The RSA context to initialize. This must not be \c NULL. - */ -void mbedtls_rsa_init(mbedtls_rsa_context *ctx); - -/** - * \brief This function sets padding for an already initialized RSA - * context. - * - * \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP - * encryption scheme and the RSASSA-PSS signature scheme. - * - * \note The \p hash_id parameter is ignored when using - * #MBEDTLS_RSA_PKCS_V15 padding. - * - * \note The choice of padding mode is strictly enforced for private - * key operations, since there might be security concerns in - * mixing padding modes. For public key operations it is - * a default value, which can be overridden by calling specific - * \c mbedtls_rsa_rsaes_xxx or \c mbedtls_rsa_rsassa_xxx - * functions. - * - * \note The hash selected in \p hash_id is always used for OEAP - * encryption. For PSS signatures, it is always used for - * making signatures, but can be overridden for verifying them. - * If set to #MBEDTLS_MD_NONE, it is always overridden. - * - * \param ctx The initialized RSA context to be configured. - * \param padding The padding mode to use. This must be either - * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. - * \param hash_id The hash identifier for PSS or OAEP, if \p padding is - * #MBEDTLS_RSA_PKCS_V21. #MBEDTLS_MD_NONE is accepted by this - * function but may be not suitable for some operations. - * Ignored if \p padding is #MBEDTLS_RSA_PKCS_V15. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_RSA_INVALID_PADDING failure: - * \p padding or \p hash_id is invalid. - */ -int mbedtls_rsa_set_padding(mbedtls_rsa_context *ctx, int padding, - mbedtls_md_type_t hash_id); - -/** - * \brief This function retrieves padding mode of initialized - * RSA context. - * - * \param ctx The initialized RSA context. - * - * \return RSA padding mode. - * - */ -int mbedtls_rsa_get_padding_mode(const mbedtls_rsa_context *ctx); - -/** - * \brief This function retrieves hash identifier of mbedtls_md_type_t - * type. - * - * \param ctx The initialized RSA context. - * - * \return Hash identifier of mbedtls_md_type_t type. - * - */ -int mbedtls_rsa_get_md_alg(const mbedtls_rsa_context *ctx); - -/** - * \brief This function imports a set of core parameters into an - * RSA context. - * - * \note This function can be called multiple times for successive - * imports, if the parameters are not simultaneously present. - * - * Any sequence of calls to this function should be followed - * by a call to mbedtls_rsa_complete(), which checks and - * completes the provided information to a ready-for-use - * public or private RSA key. - * - * \note See mbedtls_rsa_complete() for more information on which - * parameters are necessary to set up a private or public - * RSA key. - * - * \note The imported parameters are copied and need not be preserved - * for the lifetime of the RSA context being set up. - * - * \param ctx The initialized RSA context to store the parameters in. - * \param N The RSA modulus. This may be \c NULL. - * \param P The first prime factor of \p N. This may be \c NULL. - * \param Q The second prime factor of \p N. This may be \c NULL. - * \param D The private exponent. This may be \c NULL. - * \param E The public exponent. This may be \c NULL. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_rsa_import(mbedtls_rsa_context *ctx, - const mbedtls_mpi *N, - const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *E); - -/** - * \brief This function imports core RSA parameters, in raw big-endian - * binary format, into an RSA context. - * - * \note This function can be called multiple times for successive - * imports, if the parameters are not simultaneously present. - * - * Any sequence of calls to this function should be followed - * by a call to mbedtls_rsa_complete(), which checks and - * completes the provided information to a ready-for-use - * public or private RSA key. - * - * \note See mbedtls_rsa_complete() for more information on which - * parameters are necessary to set up a private or public - * RSA key. - * - * \note The imported parameters are copied and need not be preserved - * for the lifetime of the RSA context being set up. - * - * \param ctx The initialized RSA context to store the parameters in. - * \param N The RSA modulus. This may be \c NULL. - * \param N_len The Byte length of \p N; it is ignored if \p N == NULL. - * \param P The first prime factor of \p N. This may be \c NULL. - * \param P_len The Byte length of \p P; it is ignored if \p P == NULL. - * \param Q The second prime factor of \p N. This may be \c NULL. - * \param Q_len The Byte length of \p Q; it is ignored if \p Q == NULL. - * \param D The private exponent. This may be \c NULL. - * \param D_len The Byte length of \p D; it is ignored if \p D == NULL. - * \param E The public exponent. This may be \c NULL. - * \param E_len The Byte length of \p E; it is ignored if \p E == NULL. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx, - unsigned char const *N, size_t N_len, - unsigned char const *P, size_t P_len, - unsigned char const *Q, size_t Q_len, - unsigned char const *D, size_t D_len, - unsigned char const *E, size_t E_len); - -/** - * \brief This function completes an RSA context from - * a set of imported core parameters. - * - * To setup an RSA public key, precisely \c N and \c E - * must have been imported. - * - * To setup an RSA private key, sufficient information must - * be present for the other parameters to be derivable. - * - * The default implementation supports the following: - *
  • Derive \c P, \c Q from \c N, \c D, \c E.
  • - *
  • Derive \c N, \c D from \c P, \c Q, \c E.
- * Alternative implementations need not support these. - * - * If this function runs successfully, it guarantees that - * the RSA context can be used for RSA operations without - * the risk of failure or crash. - * - * \warning This function need not perform consistency checks - * for the imported parameters. In particular, parameters that - * are not needed by the implementation might be silently - * discarded and left unchecked. To check the consistency - * of the key material, see mbedtls_rsa_check_privkey(). - * - * \param ctx The initialized RSA context holding imported parameters. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations - * failed. - * - */ -int mbedtls_rsa_complete(mbedtls_rsa_context *ctx); - -/** - * \brief This function exports the core parameters of an RSA key. - * - * If this function runs successfully, the non-NULL buffers - * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully - * written, with additional unused space filled leading by - * zero Bytes. - * - * Possible reasons for returning - * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
    - *
  • An alternative RSA implementation is in use, which - * stores the key externally, and either cannot or should - * not export it into RAM.
  • - *
  • A SW or HW implementation might not support a certain - * deduction. For example, \p P, \p Q from \p N, \p D, - * and \p E if the former are not part of the - * implementation.
- * - * If the function fails due to an unsupported operation, - * the RSA context stays intact and remains usable. - * - * \param ctx The initialized RSA context. - * \param N The MPI to hold the RSA modulus. - * This may be \c NULL if this field need not be exported. - * \param P The MPI to hold the first prime factor of \p N. - * This may be \c NULL if this field need not be exported. - * \param Q The MPI to hold the second prime factor of \p N. - * This may be \c NULL if this field need not be exported. - * \param D The MPI to hold the private exponent. - * This may be \c NULL if this field need not be exported. - * \param E The MPI to hold the public exponent. - * This may be \c NULL if this field need not be exported. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the - * requested parameters cannot be done due to missing - * functionality or because of security policies. - * \return A non-zero return code on any other failure. - * - */ -int mbedtls_rsa_export(const mbedtls_rsa_context *ctx, - mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, - mbedtls_mpi *D, mbedtls_mpi *E); - -/** - * \brief This function exports core parameters of an RSA key - * in raw big-endian binary format. - * - * If this function runs successfully, the non-NULL buffers - * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully - * written, with additional unused space filled leading by - * zero Bytes. - * - * Possible reasons for returning - * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
    - *
  • An alternative RSA implementation is in use, which - * stores the key externally, and either cannot or should - * not export it into RAM.
  • - *
  • A SW or HW implementation might not support a certain - * deduction. For example, \p P, \p Q from \p N, \p D, - * and \p E if the former are not part of the - * implementation.
- * If the function fails due to an unsupported operation, - * the RSA context stays intact and remains usable. - * - * \note The length parameters are ignored if the corresponding - * buffer pointers are NULL. - * - * \param ctx The initialized RSA context. - * \param N The Byte array to store the RSA modulus, - * or \c NULL if this field need not be exported. - * \param N_len The size of the buffer for the modulus. - * \param P The Byte array to hold the first prime factor of \p N, - * or \c NULL if this field need not be exported. - * \param P_len The size of the buffer for the first prime factor. - * \param Q The Byte array to hold the second prime factor of \p N, - * or \c NULL if this field need not be exported. - * \param Q_len The size of the buffer for the second prime factor. - * \param D The Byte array to hold the private exponent, - * or \c NULL if this field need not be exported. - * \param D_len The size of the buffer for the private exponent. - * \param E The Byte array to hold the public exponent, - * or \c NULL if this field need not be exported. - * \param E_len The size of the buffer for the public exponent. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the - * requested parameters cannot be done due to missing - * functionality or because of security policies. - * \return A non-zero return code on any other failure. - */ -int mbedtls_rsa_export_raw(const mbedtls_rsa_context *ctx, - unsigned char *N, size_t N_len, - unsigned char *P, size_t P_len, - unsigned char *Q, size_t Q_len, - unsigned char *D, size_t D_len, - unsigned char *E, size_t E_len); - -/** - * \brief This function exports CRT parameters of a private RSA key. - * - * \note Alternative RSA implementations not using CRT-parameters - * internally can implement this function based on - * mbedtls_rsa_deduce_opt(). - * - * \param ctx The initialized RSA context. - * \param DP The MPI to hold \c D modulo `P-1`, - * or \c NULL if it need not be exported. - * \param DQ The MPI to hold \c D modulo `Q-1`, - * or \c NULL if it need not be exported. - * \param QP The MPI to hold modular inverse of \c Q modulo \c P, - * or \c NULL if it need not be exported. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - * - */ -int mbedtls_rsa_export_crt(const mbedtls_rsa_context *ctx, - mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP); - -/** - * \brief This function retrieves the length of the RSA modulus in bits. - * - * \param ctx The initialized RSA context. - * - * \return The length of the RSA modulus in bits. - * - */ -size_t mbedtls_rsa_get_bitlen(const mbedtls_rsa_context *ctx); - -/** - * \brief This function retrieves the length of RSA modulus in Bytes. - * - * \param ctx The initialized RSA context. - * - * \return The length of the RSA modulus in Bytes. - * - */ -size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx); - -/** - * \brief This function generates an RSA keypair. - * - * \note mbedtls_rsa_init() must be called before this function, - * to set up the RSA context. - * - * \param ctx The initialized RSA context used to hold the key. - * \param f_rng The RNG function to be used for key generation. - * This is mandatory and must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. - * This may be \c NULL if \p f_rng doesn't need a context. - * \param nbits The size of the public key in bits. - * \param exponent The public exponent to use. For example, \c 65537. - * This must be odd and greater than \c 1. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - unsigned int nbits, int exponent); - -/** - * \brief This function checks if a context contains at least an RSA - * public key. - * - * If the function runs successfully, it is guaranteed that - * enough information is present to perform an RSA public key - * operation using mbedtls_rsa_public(). - * - * \param ctx The initialized RSA context to check. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - * - */ -int mbedtls_rsa_check_pubkey(const mbedtls_rsa_context *ctx); - -/** - * \brief This function checks if a context contains an RSA private key - * and perform basic consistency checks. - * - * \note The consistency checks performed by this function not only - * ensure that mbedtls_rsa_private() can be called successfully - * on the given context, but that the various parameters are - * mutually consistent with high probability, in the sense that - * mbedtls_rsa_public() and mbedtls_rsa_private() are inverses. - * - * \warning This function should catch accidental misconfigurations - * like swapping of parameters, but it cannot establish full - * trust in neither the quality nor the consistency of the key - * material that was used to setup the given RSA context: - *
  • Consistency: Imported parameters that are irrelevant - * for the implementation might be silently dropped. If dropped, - * the current function does not have access to them, - * and therefore cannot check them. See mbedtls_rsa_complete(). - * If you want to check the consistency of the entire - * content of a PKCS1-encoded RSA private key, for example, you - * should use mbedtls_rsa_validate_params() before setting - * up the RSA context. - * Additionally, if the implementation performs empirical checks, - * these checks substantiate but do not guarantee consistency.
  • - *
  • Quality: This function is not expected to perform - * extended quality assessments like checking that the prime - * factors are safe. Additionally, it is the responsibility of the - * user to ensure the trustworthiness of the source of his RSA - * parameters, which goes beyond what is effectively checkable - * by the library.
- * - * \param ctx The initialized RSA context to check. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_check_privkey(const mbedtls_rsa_context *ctx); - -/** - * \brief This function checks a public-private RSA key pair. - * - * It checks each of the contexts, and makes sure they match. - * - * \param pub The initialized RSA context holding the public key. - * \param prv The initialized RSA context holding the private key. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub, - const mbedtls_rsa_context *prv); - -/** - * \brief This function performs an RSA public key operation. - * - * \param ctx The initialized RSA context to use. - * \param input The input buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \note This function does not handle message padding. - * - * \note Make sure to set \p input[0] = 0 or ensure that - * input is smaller than \c N. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_public(mbedtls_rsa_context *ctx, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function performs an RSA private key operation. - * - * \note Blinding is used if and only if a PRNG is provided. - * - * \note If blinding is used, both the base of exponentiation - * and the exponent are blinded, providing protection - * against some side-channel attacks. - * - * \warning It is deprecated and a security risk to not provide - * a PRNG here and thereby prevent the use of blinding. - * Future versions of the library may enforce the presence - * of a PRNG. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function, used for blinding. It is mandatory. - * \param p_rng The RNG context to pass to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context. - * \param input The input buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - * - */ -int mbedtls_rsa_private(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function adds the message padding, then performs an RSA - * operation. - * - * It is the generic wrapper for performing a PKCS#1 encryption - * operation. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG to use. It is used for padding generation - * and it is mandatory. - * \param p_rng The RNG context to be passed to \p f_rng. May be - * \c NULL if \p f_rng doesn't need a context argument. - * \param ilen The length of the plaintext in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. It may be \c NULL if - * `ilen == 0`. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - size_t ilen, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function performs a PKCS#1 v1.5 encryption operation - * (RSAES-PKCS1-v1_5-ENCRYPT). - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function to use. It is mandatory and used for - * padding generation. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * \param ilen The length of the plaintext in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. It may be \c NULL if - * `ilen == 0`. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - size_t ilen, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function performs a PKCS#1 v2.1 OAEP encryption - * operation (RSAES-OAEP-ENCRYPT). - * - * \note The output buffer must be as large as the size - * of ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function to use. This is needed for padding - * generation and is mandatory. - * \param p_rng The RNG context to be passed to \p f_rng. This may - * be \c NULL if \p f_rng doesn't need a context argument. - * \param label The buffer holding the custom label to use. - * This must be a readable buffer of length \p label_len - * Bytes. It may be \c NULL if \p label_len is \c 0. - * \param label_len The length of the label in Bytes. - * \param ilen The length of the plaintext buffer \p input in Bytes. - * \param input The input data to encrypt. This must be a readable - * buffer of size \p ilen Bytes. It may be \c NULL if - * `ilen == 0`. - * \param output The output buffer. This must be a writable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - const unsigned char *label, size_t label_len, - size_t ilen, - const unsigned char *input, - unsigned char *output); - -/** - * \brief This function performs an RSA operation, then removes the - * message padding. - * - * It is the generic wrapper for performing a PKCS#1 decryption - * operation. - * - * \warning When \p ctx->padding is set to #MBEDTLS_RSA_PKCS_V15, - * mbedtls_rsa_rsaes_pkcs1_v15_decrypt() is called, which is an - * inherently dangerous function (CWE-242). - * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N (for example, - * 128 Bytes if RSA-1024 is used) to be able to hold an - * arbitrary decrypted message. If it is not large enough to - * hold the decryption of the particular ciphertext provided, - * the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. This is used for blinding and is - * mandatory; see mbedtls_rsa_private() for more. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context. - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len); - -/** - * \brief This function performs a PKCS#1 v1.5 decryption - * operation (RSAES-PKCS1-v1_5-DECRYPT). - * - * \warning This is an inherently dangerous function (CWE-242). Unless - * it is used in a side channel free and safe way (eg. - * implementing the TLS protocol as per 7.4.7.1 of RFC 5246), - * the calling code is vulnerable. - * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N, for example, - * 128 Bytes if RSA-1024 is used, to be able to hold an - * arbitrary decrypted message. If it is not large enough to - * hold the decryption of the particular ciphertext provided, - * the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. This is used for blinding and is - * mandatory; see mbedtls_rsa_private() for more. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context. - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - * - */ -int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len); - -/** - * \brief This function performs a PKCS#1 v2.1 OAEP decryption - * operation (RSAES-OAEP-DECRYPT). - * - * \note The output buffer length \c output_max_len should be - * as large as the size \p ctx->len of \p ctx->N, for - * example, 128 Bytes if RSA-1024 is used, to be able to - * hold an arbitrary decrypted message. If it is not - * large enough to hold the decryption of the particular - * ciphertext provided, the function returns - * #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. This is used for blinding and is - * mandatory. - * \param p_rng The RNG context to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context. - * \param label The buffer holding the custom label to use. - * This must be a readable buffer of length \p label_len - * Bytes. It may be \c NULL if \p label_len is \c 0. - * \param label_len The length of the label in Bytes. - * \param olen The address at which to store the length of - * the plaintext. This must not be \c NULL. - * \param input The ciphertext buffer. This must be a readable buffer - * of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * \param output The buffer used to hold the plaintext. This must - * be a writable buffer of length \p output_max_len Bytes. - * \param output_max_len The length in Bytes of the output buffer \p output. - * - * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - const unsigned char *label, size_t label_len, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len); - -/** - * \brief This function performs a private RSA operation to sign - * a message digest using PKCS#1. - * - * It is the generic wrapper for performing a PKCS#1 - * signature. - * - * \note The \p sig buffer must be as large as the size - * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \note For PKCS#1 v2.1 encoding, see comments on - * mbedtls_rsa_rsassa_pss_sign() for details on - * \p md_alg and \p hash_id. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function to use. This is mandatory and - * must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. - * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig); - -/** - * \brief This function performs a PKCS#1 v1.5 signature - * operation (RSASSA-PKCS1-v1_5-SIGN). - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. This is used for blinding and is - * mandatory; see mbedtls_rsa_private() for more. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. - * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig); - -#if defined(MBEDTLS_PKCS1_V21) -/** - * \brief This function performs a PKCS#1 v2.1 PSS signature - * operation (RSASSA-PSS-SIGN). - * - * \note The \c hash_id set in \p ctx by calling - * mbedtls_rsa_set_padding() selects the hash used for the - * encoding operation and for the mask generation function - * (MGF1). For more details on the encoding operation and the - * mask generation function, consult RFC-3447: Public-Key - * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography - * Specifications. - * - * \note This function enforces that the provided salt length complies - * with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 v2.2) §9.1.1 - * step 3. The constraint is that the hash length plus the salt - * length plus 2 bytes must be at most the key length. If this - * constraint is not met, this function returns - * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. It is mandatory and must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param saltlen The length of the salt that should be used. - * If passed #MBEDTLS_RSA_SALT_LEN_ANY, the function will use - * the largest possible salt length up to the hash length, - * which is the largest permitted by some standards including - * FIPS 186-4 §5.5. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. - * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - int saltlen, - unsigned char *sig); - -/** - * \brief This function performs a PKCS#1 v2.1 PSS signature - * operation (RSASSA-PSS-SIGN). - * - * \note The \c hash_id set in \p ctx by calling - * mbedtls_rsa_set_padding() selects the hash used for the - * encoding operation and for the mask generation function - * (MGF1). For more details on the encoding operation and the - * mask generation function, consult RFC-3447: Public-Key - * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography - * Specifications. - * - * \note This function always uses the maximum possible salt size, - * up to the length of the payload hash. This choice of salt - * size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 - * v2.2) §9.1.1 step 3. Furthermore this function enforces a - * minimum salt size which is the hash size minus 2 bytes. If - * this minimum size is too large given the key size (the salt - * size, plus the hash size, plus 2 bytes must be no more than - * the key size in bytes), this function returns - * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. - * - * \param ctx The initialized RSA context to use. - * \param f_rng The RNG function. It is mandatory and must not be \c NULL. - * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL - * if \p f_rng doesn't need a context argument. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param sig The buffer to hold the signature. This must be a writable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. A buffer length of - * #MBEDTLS_MPI_MAX_SIZE is always safe. - * - * \return \c 0 if the signing operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig); -#endif /* MBEDTLS_PKCS1_V21 */ - -/** - * \brief This function performs a public RSA operation and checks - * the message digest. - * - * This is the generic wrapper for performing a PKCS#1 - * verification. - * - * \note For PKCS#1 v2.1 encoding, see comments on - * mbedtls_rsa_rsassa_pss_verify() about \c md_alg and - * \c hash_id. - * - * \param ctx The initialized RSA public key context to use. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig); - -/** - * \brief This function performs a PKCS#1 v1.5 verification - * operation (RSASSA-PKCS1-v1_5-VERIFY). - * - * \param ctx The initialized RSA public key context to use. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig); - -/** - * \brief This function performs a PKCS#1 v2.1 PSS verification - * operation (RSASSA-PSS-VERIFY). - * - * \note The \c hash_id set in \p ctx by calling - * mbedtls_rsa_set_padding() selects the hash used for the - * encoding operation and for the mask generation function - * (MGF1). For more details on the encoding operation and the - * mask generation function, consult RFC-3447: Public-Key - * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography - * Specifications. If the \c hash_id set in \p ctx by - * mbedtls_rsa_set_padding() is #MBEDTLS_MD_NONE, the \p md_alg - * parameter is used. - * - * \param ctx The initialized RSA public key context to use. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig); - -/** - * \brief This function performs a PKCS#1 v2.1 PSS verification - * operation (RSASSA-PSS-VERIFY). - * - * \note The \p sig buffer must be as large as the size - * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. - * - * \note The \c hash_id set in \p ctx by mbedtls_rsa_set_padding() is - * ignored. - * - * \param ctx The initialized RSA public key context to use. - * \param md_alg The message-digest algorithm used to hash the original data. - * Use #MBEDTLS_MD_NONE for signing raw data. - * \param hashlen The length of the message digest or raw data in Bytes. - * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the - * output length of the corresponding hash algorithm. - * \param hash The buffer holding the message digest or raw data. - * This must be a readable buffer of at least \p hashlen Bytes. - * \param mgf1_hash_id The message digest algorithm used for the - * verification operation and the mask generation - * function (MGF1). For more details on the encoding - * operation and the mask generation function, consult - * RFC-3447: Public-Key Cryptography Standards - * (PKCS) #1 v2.1: RSA Cryptography - * Specifications. - * \param expected_salt_len The length of the salt used in padding. Use - * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. - * \param sig The buffer holding the signature. This must be a readable - * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes - * for an 2048-bit RSA modulus. - * - * \return \c 0 if the verify operation was successful. - * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. - */ -int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - mbedtls_md_type_t mgf1_hash_id, - int expected_salt_len, - const unsigned char *sig); - -/** - * \brief This function copies the components of an RSA context. - * - * \param dst The destination context. This must be initialized. - * \param src The source context. This must be initialized. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure. - */ -int mbedtls_rsa_copy(mbedtls_rsa_context *dst, const mbedtls_rsa_context *src); - -/** - * \brief This function frees the components of an RSA key. - * - * \param ctx The RSA context to free. May be \c NULL, in which case - * this function is a no-op. If it is not \c NULL, it must - * point to an initialized RSA context. - */ -void mbedtls_rsa_free(mbedtls_rsa_context *ctx); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The RSA checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_rsa_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* rsa.h */ diff --git a/vendor/mbedtls/include/mbedtls/sha1.h b/vendor/mbedtls/include/mbedtls/sha1.h deleted file mode 100644 index 592ffd13f..000000000 --- a/vendor/mbedtls/include/mbedtls/sha1.h +++ /dev/null @@ -1,219 +0,0 @@ -/** - * \file sha1.h - * - * \brief This file contains SHA-1 definitions and functions. - * - * The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in - * FIPS 180-4: Secure Hash Standard (SHS). - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. We recommend considering stronger message - * digests instead. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SHA1_H -#define MBEDTLS_SHA1_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -/** SHA-1 input data was malformed. */ -#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA -0x0073 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_SHA1_ALT) -// Regular implementation -// - -/** - * \brief The SHA-1 context structure. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - */ -typedef struct mbedtls_sha1_context { - uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */ - uint32_t MBEDTLS_PRIVATE(state)[5]; /*!< The intermediate digest state. */ - unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< The data block being processed. */ -} -mbedtls_sha1_context; - -#else /* MBEDTLS_SHA1_ALT */ -#include "sha1_alt.h" -#endif /* MBEDTLS_SHA1_ALT */ - -/** - * \brief This function initializes a SHA-1 context. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to initialize. - * This must not be \c NULL. - * - */ -void mbedtls_sha1_init(mbedtls_sha1_context *ctx); - -/** - * \brief This function clears a SHA-1 context. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to clear. This may be \c NULL, - * in which case this function does nothing. If it is - * not \c NULL, it must point to an initialized - * SHA-1 context. - * - */ -void mbedtls_sha1_free(mbedtls_sha1_context *ctx); - -/** - * \brief This function clones the state of a SHA-1 context. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param dst The SHA-1 context to clone to. This must be initialized. - * \param src The SHA-1 context to clone from. This must be initialized. - * - */ -void mbedtls_sha1_clone(mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src); - -/** - * \brief This function starts a SHA-1 checksum calculation. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to initialize. This must be initialized. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * - */ -int mbedtls_sha1_starts(mbedtls_sha1_context *ctx); - -/** - * \brief This function feeds an input buffer into an ongoing SHA-1 - * checksum calculation. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha1_update(mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen); - -/** - * \brief This function finishes the SHA-1 operation, and writes - * the result to the output buffer. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to use. This must be initialized and - * have a hash operation started. - * \param output The SHA-1 checksum result. This must be a writable - * buffer of length \c 20 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha1_finish(mbedtls_sha1_context *ctx, - unsigned char output[20]); - -/** - * \brief SHA-1 process data block (internal use only). - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param ctx The SHA-1 context to use. This must be initialized. - * \param data The data block being processed. This must be a - * readable buffer of length \c 64 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * - */ -int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, - const unsigned char data[64]); - -/** - * \brief This function calculates the SHA-1 checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-1 result is calculated as - * output = SHA-1(input buffer). - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \param input The buffer holding the input data. - * This must be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data \p input in Bytes. - * \param output The SHA-1 checksum result. - * This must be a writable buffer of length \c 20 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - * - */ -int mbedtls_sha1(const unsigned char *input, - size_t ilen, - unsigned char output[20]); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief The SHA-1 checkup routine. - * - * \warning SHA-1 is considered a weak message digest and its use - * constitutes a security risk. We recommend considering - * stronger message digests instead. - * - * \return \c 0 on success. - * \return \c 1 on failure. - * - */ -int mbedtls_sha1_self_test(int verbose); - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha1.h */ diff --git a/vendor/mbedtls/include/mbedtls/sha256.h b/vendor/mbedtls/include/mbedtls/sha256.h deleted file mode 100644 index ca568e291..000000000 --- a/vendor/mbedtls/include/mbedtls/sha256.h +++ /dev/null @@ -1,200 +0,0 @@ -/** - * \file sha256.h - * - * \brief This file contains SHA-224 and SHA-256 definitions and functions. - * - * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic - * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SHA256_H -#define MBEDTLS_SHA256_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -/** SHA-256 input data was malformed. */ -#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA -0x0074 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_SHA256_ALT) -// Regular implementation -// - -/** - * \brief The SHA-256 context structure. - * - * The structure is used both for SHA-256 and for SHA-224 - * checksum calculations. The choice between these two is - * made in the call to mbedtls_sha256_starts(). - */ -typedef struct mbedtls_sha256_context { - unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< The data block being processed. */ - uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */ - uint32_t MBEDTLS_PRIVATE(state)[8]; /*!< The intermediate digest state. */ -#if defined(MBEDTLS_SHA224_C) - int MBEDTLS_PRIVATE(is224); /*!< Determines which function to use: - 0: Use SHA-256, or 1: Use SHA-224. */ -#endif -} -mbedtls_sha256_context; - -#else /* MBEDTLS_SHA256_ALT */ -#include "sha256_alt.h" -#endif /* MBEDTLS_SHA256_ALT */ - -/** - * \brief This function initializes a SHA-256 context. - * - * \param ctx The SHA-256 context to initialize. This must not be \c NULL. - */ -void mbedtls_sha256_init(mbedtls_sha256_context *ctx); - -/** - * \brief This function clears a SHA-256 context. - * - * \param ctx The SHA-256 context to clear. This may be \c NULL, in which - * case this function returns immediately. If it is not \c NULL, - * it must point to an initialized SHA-256 context. - */ -void mbedtls_sha256_free(mbedtls_sha256_context *ctx); - -/** - * \brief This function clones the state of a SHA-256 context. - * - * \param dst The destination context. This must be initialized. - * \param src The context to clone. This must be initialized. - */ -void mbedtls_sha256_clone(mbedtls_sha256_context *dst, - const mbedtls_sha256_context *src); - -/** - * \brief This function starts a SHA-224 or SHA-256 checksum - * calculation. - * - * \param ctx The context to use. This must be initialized. - * \param is224 This determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - * - * \note is224 must be defined accordingly to the enabled - * MBEDTLS_SHA224_C/MBEDTLS_SHA256_C symbols otherwise the - * function will return #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224); - -/** - * \brief This function feeds an input buffer into an ongoing - * SHA-256 checksum calculation. - * - * \param ctx The SHA-256 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha256_update(mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen); - -/** - * \brief This function finishes the SHA-256 operation, and writes - * the result to the output buffer. - * - * \param ctx The SHA-256 context. This must be initialized - * and have a hash operation started. - * \param output The SHA-224 or SHA-256 checksum result. - * This must be a writable buffer of length \c 32 bytes - * for SHA-256, \c 28 bytes for SHA-224. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, - unsigned char *output); - -/** - * \brief This function processes a single data block within - * the ongoing SHA-256 computation. This function is for - * internal use only. - * - * \param ctx The SHA-256 context. This must be initialized. - * \param data The buffer holding one block of data. This must - * be a readable buffer of length \c 64 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, - const unsigned char data[64]); - -/** - * \brief This function calculates the SHA-224 or SHA-256 - * checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-256 result is calculated as - * output = SHA-256(input buffer). - * - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-224 or SHA-256 checksum result. - * This must be a writable buffer of length \c 32 bytes - * for SHA-256, \c 28 bytes for SHA-224. - * \param is224 Determines which function to use. This must be - * either \c 0 for SHA-256, or \c 1 for SHA-224. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha256(const unsigned char *input, - size_t ilen, - unsigned char *output, - int is224); - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_SHA224_C) -/** - * \brief The SHA-224 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_sha224_self_test(int verbose); -#endif /* MBEDTLS_SHA224_C */ - -#if defined(MBEDTLS_SHA256_C) -/** - * \brief The SHA-256 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_sha256_self_test(int verbose); -#endif /* MBEDTLS_SHA256_C */ - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha256.h */ diff --git a/vendor/mbedtls/include/mbedtls/sha3.h b/vendor/mbedtls/include/mbedtls/sha3.h deleted file mode 100644 index 3eeee65e6..000000000 --- a/vendor/mbedtls/include/mbedtls/sha3.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * \file sha3.h - * - * \brief This file contains SHA-3 definitions and functions. - * - * The Secure Hash Algorithms cryptographic - * hash functions are defined in FIPS 202: SHA-3 Standard: - * Permutation-Based Hash and Extendable-Output Functions . - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_SHA3_H -#define MBEDTLS_SHA3_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** SHA-3 input data was malformed. */ -#define MBEDTLS_ERR_SHA3_BAD_INPUT_DATA -0x0076 - -/** - * SHA-3 family id. - * - * It identifies the family (SHA3-256, SHA3-512, etc.) - */ - -typedef enum { - MBEDTLS_SHA3_NONE = 0, /*!< Operation not defined. */ - MBEDTLS_SHA3_224, /*!< SHA3-224 */ - MBEDTLS_SHA3_256, /*!< SHA3-256 */ - MBEDTLS_SHA3_384, /*!< SHA3-384 */ - MBEDTLS_SHA3_512, /*!< SHA3-512 */ -} mbedtls_sha3_id; - -/** - * \brief The SHA-3 context structure. - * - * The structure is used SHA-3 checksum calculations. - */ -typedef struct { - uint64_t MBEDTLS_PRIVATE(state[25]); - uint32_t MBEDTLS_PRIVATE(index); - uint16_t MBEDTLS_PRIVATE(olen); - uint16_t MBEDTLS_PRIVATE(max_block_size); -} -mbedtls_sha3_context; - -/** - * \brief This function initializes a SHA-3 context. - * - * \param ctx The SHA-3 context to initialize. This must not be \c NULL. - */ -void mbedtls_sha3_init(mbedtls_sha3_context *ctx); - -/** - * \brief This function clears a SHA-3 context. - * - * \param ctx The SHA-3 context to clear. This may be \c NULL, in which - * case this function returns immediately. If it is not \c NULL, - * it must point to an initialized SHA-3 context. - */ -void mbedtls_sha3_free(mbedtls_sha3_context *ctx); - -/** - * \brief This function clones the state of a SHA-3 context. - * - * \param dst The destination context. This must be initialized. - * \param src The context to clone. This must be initialized. - */ -void mbedtls_sha3_clone(mbedtls_sha3_context *dst, - const mbedtls_sha3_context *src); - -/** - * \brief This function starts a SHA-3 checksum - * calculation. - * - * \param ctx The context to use. This must be initialized. - * \param id The id of the SHA-3 family. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id); - -/** - * \brief This function feeds an input buffer into an ongoing - * SHA-3 checksum calculation. - * - * \param ctx The SHA-3 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha3_update(mbedtls_sha3_context *ctx, - const uint8_t *input, - size_t ilen); - -/** - * \brief This function finishes the SHA-3 operation, and writes - * the result to the output buffer. - * - * \param ctx The SHA-3 context. This must be initialized - * and have a hash operation started. - * \param output The SHA-3 checksum result. - * This must be a writable buffer of length \c olen bytes. - * \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256, - * SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64, - * respectively. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha3_finish(mbedtls_sha3_context *ctx, - uint8_t *output, size_t olen); - -/** - * \brief This function calculates the SHA-3 - * checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-3 result is calculated as - * output = SHA-3(id, input buffer, d). - * - * \param id The id of the SHA-3 family. - * \param input The buffer holding the data. This must be a readable - * buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-3 checksum result. - * This must be a writable buffer of length \c olen bytes. - * \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256, - * SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64, - * respectively. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input, - size_t ilen, - uint8_t *output, - size_t olen); - -#if defined(MBEDTLS_SELF_TEST) -/** - * \brief Checkup routine for the algorithms implemented - * by this module: SHA3-224, SHA3-256, SHA3-384, SHA3-512. - * - * \return 0 if successful, or 1 if the test failed. - */ -int mbedtls_sha3_self_test(int verbose); -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha3.h */ diff --git a/vendor/mbedtls/include/mbedtls/sha512.h b/vendor/mbedtls/include/mbedtls/sha512.h deleted file mode 100644 index 1c20e4c22..000000000 --- a/vendor/mbedtls/include/mbedtls/sha512.h +++ /dev/null @@ -1,208 +0,0 @@ -/** - * \file sha512.h - * \brief This file contains SHA-384 and SHA-512 definitions and functions. - * - * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic - * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SHA512_H -#define MBEDTLS_SHA512_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include -#include - -/** SHA-512 input data was malformed. */ -#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA -0x0075 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_SHA512_ALT) -// Regular implementation -// - -/** - * \brief The SHA-512 context structure. - * - * The structure is used both for SHA-384 and for SHA-512 - * checksum calculations. The choice between these two is - * made in the call to mbedtls_sha512_starts(). - */ -typedef struct mbedtls_sha512_context { - uint64_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */ - uint64_t MBEDTLS_PRIVATE(state)[8]; /*!< The intermediate digest state. */ - unsigned char MBEDTLS_PRIVATE(buffer)[128]; /*!< The data block being processed. */ -#if defined(MBEDTLS_SHA384_C) - int MBEDTLS_PRIVATE(is384); /*!< Determines which function to use: - 0: Use SHA-512, or 1: Use SHA-384. */ -#endif -} -mbedtls_sha512_context; - -#else /* MBEDTLS_SHA512_ALT */ -#include "sha512_alt.h" -#endif /* MBEDTLS_SHA512_ALT */ - -/** - * \brief This function initializes a SHA-512 context. - * - * \param ctx The SHA-512 context to initialize. This must - * not be \c NULL. - */ -void mbedtls_sha512_init(mbedtls_sha512_context *ctx); - -/** - * \brief This function clears a SHA-512 context. - * - * \param ctx The SHA-512 context to clear. This may be \c NULL, - * in which case this function does nothing. If it - * is not \c NULL, it must point to an initialized - * SHA-512 context. - */ -void mbedtls_sha512_free(mbedtls_sha512_context *ctx); - -/** - * \brief This function clones the state of a SHA-512 context. - * - * \param dst The destination context. This must be initialized. - * \param src The context to clone. This must be initialized. - */ -void mbedtls_sha512_clone(mbedtls_sha512_context *dst, - const mbedtls_sha512_context *src); - -/** - * \brief This function starts a SHA-384 or SHA-512 checksum - * calculation. - * - * \param ctx The SHA-512 context to use. This must be initialized. - * \param is384 Determines which function to use. This must be - * either \c 0 for SHA-512, or \c 1 for SHA-384. - * - * \note is384 must be defined accordingly to the enabled - * MBEDTLS_SHA384_C/MBEDTLS_SHA512_C symbols otherwise the - * function will return #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384); - -/** - * \brief This function feeds an input buffer into an ongoing - * SHA-512 checksum calculation. - * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param input The buffer holding the input data. This must - * be a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512_update(mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen); - -/** - * \brief This function finishes the SHA-512 operation, and writes - * the result to the output buffer. - * - * \param ctx The SHA-512 context. This must be initialized - * and have a hash operation started. - * \param output The SHA-384 or SHA-512 checksum result. - * This must be a writable buffer of length \c 64 bytes - * for SHA-512, \c 48 bytes for SHA-384. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512_finish(mbedtls_sha512_context *ctx, - unsigned char *output); - -/** - * \brief This function processes a single data block within - * the ongoing SHA-512 computation. - * This function is for internal use only. - * - * \param ctx The SHA-512 context. This must be initialized. - * \param data The buffer holding one block of data. This - * must be a readable buffer of length \c 128 Bytes. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx, - const unsigned char data[128]); - -/** - * \brief This function calculates the SHA-512 or SHA-384 - * checksum of a buffer. - * - * The function allocates the context, performs the - * calculation, and frees the context. - * - * The SHA-512 result is calculated as - * output = SHA-512(input buffer). - * - * \param input The buffer holding the input data. This must be - * a readable buffer of length \p ilen Bytes. - * \param ilen The length of the input data in Bytes. - * \param output The SHA-384 or SHA-512 checksum result. - * This must be a writable buffer of length \c 64 bytes - * for SHA-512, \c 48 bytes for SHA-384. - * \param is384 Determines which function to use. This must be either - * \c 0 for SHA-512, or \c 1 for SHA-384. - * - * \note is384 must be defined accordingly with the supported - * symbols in the config file. If: - * - is384 is 0, but \c MBEDTLS_SHA384_C is not defined, or - * - is384 is 1, but \c MBEDTLS_SHA512_C is not defined - * then the function will return - * #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_sha512(const unsigned char *input, - size_t ilen, - unsigned char *output, - int is384); - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_SHA384_C) -/** - * \brief The SHA-384 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_sha384_self_test(int verbose); -#endif /* MBEDTLS_SHA384_C */ - -#if defined(MBEDTLS_SHA512_C) -/** - * \brief The SHA-512 checkup routine. - * - * \return \c 0 on success. - * \return \c 1 on failure. - */ -int mbedtls_sha512_self_test(int verbose); -#endif /* MBEDTLS_SHA512_C */ - -#endif /* MBEDTLS_SELF_TEST */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_sha512.h */ diff --git a/vendor/mbedtls/include/mbedtls/ssl.h b/vendor/mbedtls/include/mbedtls/ssl.h deleted file mode 100644 index 43d817598..000000000 --- a/vendor/mbedtls/include/mbedtls/ssl.h +++ /dev/null @@ -1,5882 +0,0 @@ -/** - * \file ssl.h - * - * \brief SSL/TLS functions. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SSL_H -#define MBEDTLS_SSL_H -#include "mbedtls/platform_util.h" -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/bignum.h" -#include "mbedtls/ecp.h" - -#include "mbedtls/ssl_ciphersuites.h" - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#include "mbedtls/x509_crt.h" -#include "mbedtls/x509_crl.h" -#endif - -#if defined(MBEDTLS_DHM_C) -#include "mbedtls/dhm.h" -#endif - -#include "mbedtls/md.h" - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) -#include "mbedtls/ecdh.h" -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#include "psa/crypto.h" - -/* - * SSL Error codes - */ -/** A cryptographic operation is in progress. Try again later. */ -#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 -/** The requested feature is not available. */ -#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE -0x7080 -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA -0x7100 -/** Verification of the message MAC failed. */ -#define MBEDTLS_ERR_SSL_INVALID_MAC -0x7180 -/** An invalid SSL record was received. */ -#define MBEDTLS_ERR_SSL_INVALID_RECORD -0x7200 -/** The connection indicated an EOF. */ -#define MBEDTLS_ERR_SSL_CONN_EOF -0x7280 -/** A message could not be parsed due to a syntactic error. */ -#define MBEDTLS_ERR_SSL_DECODE_ERROR -0x7300 -/* Error space gap */ -/** No RNG was provided to the SSL module. */ -#define MBEDTLS_ERR_SSL_NO_RNG -0x7400 -/** No client certification received from the client, but required by the authentication mode. */ -#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 -/** Client received an extended server hello containing an unsupported extension */ -#define MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION -0x7500 -/** No ALPN protocols supported that the client advertises */ -#define MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL -0x7580 -/** The own private key or pre-shared key is not set, but needed. */ -#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED -0x7600 -/** No CA Chain is set, but required to operate. */ -#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED -0x7680 -/** An unexpected message was received from our peer. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE -0x7700 -/** A fatal alert message was received from our peer. */ -#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 -/** No server could be identified matching the client's SNI. */ -#define MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME -0x7800 -/** The peer notified us that the connection is going to be closed. */ -#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY -0x7880 -/* Error space gap */ -/* Error space gap */ -/** Processing of the Certificate handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_CERTIFICATE -0x7A00 -/* Error space gap */ -/** A TLS 1.3 NewSessionTicket message has been received. */ -#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00 -/** Not possible to read early data */ -#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80 -/** - * Early data has been received as part of an on-going handshake. - * This error code can be returned only on server side if and only if early - * data has been enabled by means of the mbedtls_ssl_conf_early_data() API. - * This error code can then be returned by mbedtls_ssl_handshake(), - * mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write() if - * early data has been received as part of the handshake sequence they - * triggered. To read the early data, call mbedtls_ssl_read_early_data(). - */ -#define MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA -0x7C00 -/** Not possible to write early data */ -#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C80 -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/** Cache entry not found */ -#define MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND -0x7E80 -/** Memory allocation failed */ -#define MBEDTLS_ERR_SSL_ALLOC_FAILED -0x7F00 -/** Hardware acceleration function returned with error */ -#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -0x7F80 -/** Hardware acceleration function skipped / left alone data */ -#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 -/** Handshake protocol not within min/max boundaries */ -#define MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION -0x6E80 -/** The handshake negotiation failed. */ -#define MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE -0x6E00 -/** Session ticket has expired. */ -#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 -/** Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */ -#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 -/** Unknown identity received (eg, PSK identity) */ -#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 -/** Internal error (eg, unexpected failure in lower-level module) */ -#define MBEDTLS_ERR_SSL_INTERNAL_ERROR -0x6C00 -/** A counter would wrap (eg, too many messages exchanged). */ -#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING -0x6B80 -/** Unexpected message at ServerHello in renegotiation. */ -#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 -/** DTLS client must retry for hello verification */ -#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 -/** A buffer is too small to receive or write a message */ -#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 -/* Error space gap */ -/** No data of requested type currently available on underlying transport. */ -#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 -/** Connection requires a write call. */ -#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 -/** The operation timed out. */ -#define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 -/** The client initiated a reconnect from the same port. */ -#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 -/** Record header looks valid but is not expected. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 -/** The alert message received indicates a non-fatal error. */ -#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 -/** A field in a message was incorrect or inconsistent with other fields. */ -#define MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER -0x6600 -/** Internal-only message signaling that further message-processing should be done */ -#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 -/** The asynchronous operation is not completed yet. */ -#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 -/** Internal-only message signaling that a message arrived early. */ -#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/** An encrypted DTLS-frame with an unexpected CID was received. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000 -/** An operation failed due to an unexpected version or configuration. */ -#define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00 -/** Invalid value in SSL config */ -#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 -/* Error space gap */ -/** Attempt to verify a certificate without an expected hostname. - * This is usually insecure. - * - * In TLS clients, when a client authenticates a server through its - * certificate, the client normally checks three things: - * - the certificate chain must be valid; - * - the chain must start from a trusted CA; - * - the certificate must cover the server name that is expected by the client. - * - * Omitting any of these checks is generally insecure, and can allow a - * malicious server to impersonate a legitimate server. - * - * The third check may be safely skipped in some unusual scenarios, - * such as networks where eavesdropping is a risk but not active attacks, - * or a private PKI where the client equally trusts all servers that are - * accredited by the root CA. - * - * You should call mbedtls_ssl_set_hostname() with the expected server name - * before starting a TLS handshake on a client (unless the client is - * set up to only use PSK-based authentication, which does not rely on the - * host name). If you have determined that server name verification is not - * required for security in your scenario, call mbedtls_ssl_set_hostname() - * with \p NULL as the server name. - * - * This error is raised if all of the following conditions are met: - * - * - A TLS client is configured with the authentication mode - * #MBEDTLS_SSL_VERIFY_REQUIRED (default). - * - Certificate authentication is enabled. - * - The client does not call mbedtls_ssl_set_hostname(). - * - The configuration option - * #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME - * is not enabled. - */ -#define MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME -0x5D80 - -/* - * Constants from RFC 8446 for TLS 1.3 PSK modes - * - * Those are used in the Pre-Shared Key Exchange Modes extension. - * See Section 4.2.9 in RFC 8446. - */ -#define MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE 0 /* Pure PSK-based exchange */ -#define MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE 1 /* PSK+ECDHE-based exchange */ - -/* - * TLS 1.3 NamedGroup values - * - * From RF 8446 - * enum { - * // Elliptic Curve Groups (ECDHE) - * secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019), - * x25519(0x001D), x448(0x001E), - * // Finite Field Groups (DHE) - * ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102), - * ffdhe6144(0x0103), ffdhe8192(0x0104), - * // Reserved Code Points - * ffdhe_private_use(0x01FC..0x01FF), - * ecdhe_private_use(0xFE00..0xFEFF), - * (0xFFFF) - * } NamedGroup; - * - */ - -/* Elliptic Curve Groups (ECDHE) */ -#define MBEDTLS_SSL_IANA_TLS_GROUP_NONE 0 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP192K1 0x0012 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP192R1 0x0013 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP224K1 0x0014 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP224R1 0x0015 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP256K1 0x0016 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 0x0017 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 0x0018 -#define MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1 0x0019 -#define MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1 0x001A -#define MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1 0x001B -#define MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1 0x001C -#define MBEDTLS_SSL_IANA_TLS_GROUP_X25519 0x001D -#define MBEDTLS_SSL_IANA_TLS_GROUP_X448 0x001E -/* Finite Field Groups (DHE) */ -#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048 0x0100 -#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE3072 0x0101 -#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE4096 0x0102 -#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE6144 0x0103 -#define MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192 0x0104 - -/* - * TLS 1.3 Key Exchange Modes - * - * Mbed TLS internal identifiers for use with the SSL configuration API - * mbedtls_ssl_conf_tls13_key_exchange_modes(). - */ - -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK (1u << 0) /*!< Pure-PSK TLS 1.3 key exchange, - * encompassing both externally agreed PSKs - * as well as resumption PSKs. */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL (1u << 1) /*!< Pure-Ephemeral TLS 1.3 key exchanges, - * including for example ECDHE and DHE - * key exchanges. */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL (1u << 2) /*!< PSK-Ephemeral TLS 1.3 key exchanges, - * using both a PSK and an ephemeral - * key exchange. */ - -/* Convenience macros for sets of key exchanges. */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL \ - (MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK | \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL | \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) /*!< All TLS 1.3 key exchanges */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL \ - (MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK | \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) /*!< All PSK-based TLS 1.3 key exchanges */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL \ - (MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL | \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) /*!< All ephemeral TLS 1.3 key exchanges */ - -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE (0) - -/* - * Various constants - */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/* These are the high and low bytes of ProtocolVersion as defined by: - * - RFC 5246: ProtocolVersion version = { 3, 3 }; // TLS v1.2 - * - RFC 8446: see section 4.2.1 - */ -#define MBEDTLS_SSL_MAJOR_VERSION_3 3 -#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ -#define MBEDTLS_SSL_MINOR_VERSION_4 4 /*!< TLS v1.3 */ -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ -#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ - -#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ -#define MBEDTLS_SSL_MAX_ALPN_NAME_LEN 255 /*!< Maximum size in bytes of a protocol name in alpn ext., RFC 7301 */ - -#define MBEDTLS_SSL_MAX_ALPN_LIST_LEN 65535 /*!< Maximum size in bytes of list in alpn ext., RFC 7301 */ - -/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c - * NONE must be zero so that memset()ing structure to zero works */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_512 1 /*!< MaxFragmentLength 2^9 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */ - -#define MBEDTLS_SSL_IS_CLIENT 0 -#define MBEDTLS_SSL_IS_SERVER 1 - -#define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0 -#define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1 - -#define MBEDTLS_SSL_CID_DISABLED 0 -#define MBEDTLS_SSL_CID_ENABLED 1 - -#define MBEDTLS_SSL_ETM_DISABLED 0 -#define MBEDTLS_SSL_ETM_ENABLED 1 - -#define MBEDTLS_SSL_COMPRESS_NULL 0 - -#define MBEDTLS_SSL_VERIFY_NONE 0 -#define MBEDTLS_SSL_VERIFY_OPTIONAL 1 -#define MBEDTLS_SSL_VERIFY_REQUIRED 2 -#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */ - -#define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0 -#define MBEDTLS_SSL_SECURE_RENEGOTIATION 1 - -#define MBEDTLS_SSL_RENEGOTIATION_DISABLED 0 -#define MBEDTLS_SSL_RENEGOTIATION_ENABLED 1 - -#define MBEDTLS_SSL_ANTI_REPLAY_DISABLED 0 -#define MBEDTLS_SSL_ANTI_REPLAY_ENABLED 1 - -#define MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED -1 -#define MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT 16 - -#define MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION 0 -#define MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION 1 -#define MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE 2 - -#define MBEDTLS_SSL_TRUNC_HMAC_DISABLED 0 -#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED 1 -#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */ - -#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0 -#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1 - -#define MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED 0 -#define MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED 1 - -#define MBEDTLS_SSL_PRESET_DEFAULT 0 -#define MBEDTLS_SSL_PRESET_SUITEB 2 - -#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 -#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 - -#define MBEDTLS_SSL_EARLY_DATA_DISABLED 0 -#define MBEDTLS_SSL_EARLY_DATA_ENABLED 1 - -#define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED 0 -#define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED 1 - -#define MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT 1 -#define MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER 0 - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(PSA_WANT_ALG_SHA_384) -#define MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN 48 -#elif defined(PSA_WANT_ALG_SHA_256) -#define MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN 32 -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ -/* - * Default range for DTLS retransmission timer value, in milliseconds. - * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. - */ -#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN 1000 -#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX 60000 - -/* - * Whether early data record should be discarded or not and how. - * - * The client has indicated early data and the server has rejected them. - * The server has then to skip past early data by either: - * - attempting to deprotect received records using the handshake traffic - * key, discarding records which fail deprotection (up to the configured - * max_early_data_size). Once a record is deprotected successfully, - * it is treated as the start of the client's second flight and the - * server proceeds as with an ordinary 1-RTT handshake. - * - skipping all records with an external content type of - * "application_data" (indicating that they are encrypted), up to the - * configured max_early_data_size. This is the expected behavior if the - * server has sent an HelloRetryRequest message. The server ignores - * application data message before 2nd ClientHello. - */ -#define MBEDTLS_SSL_EARLY_DATA_NO_DISCARD 0 -#define MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD 1 -#define MBEDTLS_SSL_EARLY_DATA_DISCARD 2 - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them on the compiler command line. - * \{ - */ - -/* - * Maximum fragment length in bytes, - * determines the size of each of the two internal I/O buffers. - * - * Note: the RFC defines the default size of SSL / TLS messages. If you - * change the value here, other clients / servers may not be able to - * communicate with you anymore. Only change this value if you control - * both sides of the connection and have it reduced at both sides, or - * if you're using the Max Fragment Length extension and you know all your - * peers are using it too! - */ -#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN) -#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 -#endif - -#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 -#endif - -/* - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - */ -#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING) -#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 -#endif - -/* - * Maximum length of CIDs for incoming and outgoing messages. - */ -#if !defined(MBEDTLS_SSL_CID_IN_LEN_MAX) -#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 -#endif - -#if !defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) -#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 -#endif - -#if !defined(MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY) -#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 -#endif - -#if !defined(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE) -#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024 -#endif - -#if !defined(MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) -#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000 -#endif - -#if !defined(MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH) -#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32 -#endif - -#if !defined(MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS) -#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1 -#endif - -/** \} name SECTION: Module settings */ - -/* - * Default to standard CID mode - */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) -#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0 -#endif - -/* - * Length of the verify data for secure renegotiation - */ -#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 12 - -/* - * Signaling ciphersuite values (SCSV) - */ -#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ - -/* - * Supported Signature and Hash algorithms (For TLS 1.2) - * RFC 5246 section 7.4.1.4.1 - */ -#define MBEDTLS_SSL_HASH_NONE 0 -#define MBEDTLS_SSL_HASH_MD5 1 -#define MBEDTLS_SSL_HASH_SHA1 2 -#define MBEDTLS_SSL_HASH_SHA224 3 -#define MBEDTLS_SSL_HASH_SHA256 4 -#define MBEDTLS_SSL_HASH_SHA384 5 -#define MBEDTLS_SSL_HASH_SHA512 6 - -#define MBEDTLS_SSL_SIG_ANON 0 -#define MBEDTLS_SSL_SIG_RSA 1 -#define MBEDTLS_SSL_SIG_ECDSA 3 - -/* - * TLS 1.3 signature algorithms - * RFC 8446, Section 4.2.3 - */ - -/* RSASSA-PKCS1-v1_5 algorithms */ -#define MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256 0x0401 -#define MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384 0x0501 -#define MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512 0x0601 - -/* ECDSA algorithms */ -#define MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256 0x0403 -#define MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384 0x0503 -#define MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512 0x0603 - -/* RSASSA-PSS algorithms with public key OID rsaEncryption */ -#define MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256 0x0804 -#define MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384 0x0805 -#define MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512 0x0806 - -/* EdDSA algorithms */ -#define MBEDTLS_TLS1_3_SIG_ED25519 0x0807 -#define MBEDTLS_TLS1_3_SIG_ED448 0x0808 - -/* RSASSA-PSS algorithms with public key OID RSASSA-PSS */ -#define MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA256 0x0809 -#define MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA384 0x080A -#define MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA512 0x080B - -/* LEGACY ALGORITHMS */ -#define MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA1 0x0201 -#define MBEDTLS_TLS1_3_SIG_ECDSA_SHA1 0x0203 - -#define MBEDTLS_TLS1_3_SIG_NONE 0x0 - -/* - * Client Certificate Types - * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5 - */ -#define MBEDTLS_SSL_CERT_TYPE_RSA_SIGN 1 -#define MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN 64 - -/* - * Message, alert and handshake types - */ -#define MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC 20 -#define MBEDTLS_SSL_MSG_ALERT 21 -#define MBEDTLS_SSL_MSG_HANDSHAKE 22 -#define MBEDTLS_SSL_MSG_APPLICATION_DATA 23 -#define MBEDTLS_SSL_MSG_CID 25 - -#define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1 -#define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2 - -#define MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY 0 /* 0x00 */ -#define MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10 /* 0x0A */ -#define MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC 20 /* 0x14 */ -#define MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED 21 /* 0x15 */ -#define MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW 22 /* 0x16 */ -#define MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30 /* 0x1E */ -#define MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE 40 /* 0x28 */ -#define MBEDTLS_SSL_ALERT_MSG_NO_CERT 41 /* 0x29 */ -#define MBEDTLS_SSL_ALERT_MSG_BAD_CERT 42 /* 0x2A */ -#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT 43 /* 0x2B */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED 44 /* 0x2C */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED 45 /* 0x2D */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN 46 /* 0x2E */ -#define MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER 47 /* 0x2F */ -#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA 48 /* 0x30 */ -#define MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED 49 /* 0x31 */ -#define MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR 50 /* 0x32 */ -#define MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR 51 /* 0x33 */ -#define MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION 60 /* 0x3C */ -#define MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */ -#define MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */ -#define MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */ -#define MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86 /* 0x56 */ -#define MBEDTLS_SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */ -#define MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ -#define MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION 109 /* 0x6d -- new in TLS 1.3 */ -#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ -#define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ -#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_REQUIRED 116 /* 0x74 */ -#define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ - -#define MBEDTLS_SSL_HS_HELLO_REQUEST 0 -#define MBEDTLS_SSL_HS_CLIENT_HELLO 1 -#define MBEDTLS_SSL_HS_SERVER_HELLO 2 -#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3 -#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4 -#define MBEDTLS_SSL_HS_END_OF_EARLY_DATA 5 -#define MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS 8 -#define MBEDTLS_SSL_HS_CERTIFICATE 11 -#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12 -#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13 -#define MBEDTLS_SSL_HS_SERVER_HELLO_DONE 14 -#define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY 15 -#define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE 16 -#define MBEDTLS_SSL_HS_FINISHED 20 -#define MBEDTLS_SSL_HS_MESSAGE_HASH 254 - -/* - * TLS extensions - */ -#define MBEDTLS_TLS_EXT_SERVERNAME 0 -#define MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME 0 - -#define MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH 1 - -#define MBEDTLS_TLS_EXT_TRUNCATED_HMAC 4 -#define MBEDTLS_TLS_EXT_STATUS_REQUEST 5 /* RFC 6066 TLS 1.2 and 1.3 */ - -#define MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10 -#define MBEDTLS_TLS_EXT_SUPPORTED_GROUPS 10 /* RFC 8422,7919 TLS 1.2 and 1.3 */ -#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS 11 - -#define MBEDTLS_TLS_EXT_SIG_ALG 13 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_USE_SRTP 14 -#define MBEDTLS_TLS_EXT_HEARTBEAT 15 /* RFC 6520 TLS 1.2 and 1.3 */ -#define MBEDTLS_TLS_EXT_ALPN 16 - -#define MBEDTLS_TLS_EXT_SCT 18 /* RFC 6962 TLS 1.2 and 1.3 */ -#define MBEDTLS_TLS_EXT_CLI_CERT_TYPE 19 /* RFC 7250 TLS 1.2 and 1.3 */ -#define MBEDTLS_TLS_EXT_SERV_CERT_TYPE 20 /* RFC 7250 TLS 1.2 and 1.3 */ -#define MBEDTLS_TLS_EXT_PADDING 21 /* RFC 7685 TLS 1.2 and 1.3 */ -#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */ -#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET 0x0017 /* 23 */ - -#define MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT 28 /* RFC 8449 (implemented for TLS 1.3 only) */ - -#define MBEDTLS_TLS_EXT_SESSION_TICKET 35 - -#define MBEDTLS_TLS_EXT_PRE_SHARED_KEY 41 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_EARLY_DATA 42 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS 43 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_COOKIE 44 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES 45 /* RFC 8446 TLS 1.3 */ - -#define MBEDTLS_TLS_EXT_CERT_AUTH 47 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_OID_FILTERS 48 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_POST_HANDSHAKE_AUTH 49 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_SIG_ALG_CERT 50 /* RFC 8446 TLS 1.3 */ -#define MBEDTLS_TLS_EXT_KEY_SHARE 51 /* RFC 8446 TLS 1.3 */ - -#if MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0 -#define MBEDTLS_TLS_EXT_CID 54 /* RFC 9146 DTLS 1.2 CID */ -#else -#define MBEDTLS_TLS_EXT_CID 254 /* Pre-RFC 9146 DTLS 1.2 CID */ -#endif - -#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */ - -#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 - -/* - * Size defines - */ -#if !defined(MBEDTLS_PSK_MAX_LEN) -/* - * If the library supports TLS 1.3 tickets and the cipher suite - * TLS1-3-AES-256-GCM-SHA384, set the PSK maximum length to 48 instead of 32. - * That way, the TLS 1.3 client and server are able to resume sessions where - * the cipher suite is TLS1-3-AES-256-GCM-SHA384 (pre-shared keys are 48 - * bytes long in that case). - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM) && \ - defined(MBEDTLS_MD_CAN_SHA384) -#define MBEDTLS_PSK_MAX_LEN 48 /* 384 bits */ -#else -#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */ -#endif -#endif /* !MBEDTLS_PSK_MAX_LEN */ - -/* Dummy type used only for its size */ -union mbedtls_ssl_premaster_secret { - unsigned char dummy; /* Make the union non-empty even with SSL disabled */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - unsigned char _pms_dhm[MBEDTLS_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - unsigned char _pms_dhe_psk[4 + MBEDTLS_MPI_MAX_SIZE - + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 3 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 4 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES - + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */ -#endif -}; - -#define MBEDTLS_PREMASTER_SIZE sizeof(union mbedtls_ssl_premaster_secret) - -#define MBEDTLS_TLS1_3_MD_MAX_SIZE PSA_HASH_MAX_SIZE - - -/* Length in number of bytes of the TLS sequence number */ -#define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8 - -/* Helper to state that client_random and server_random need to be stored - * after the handshake is complete. This is required for context serialization - * and for the keying material exporter in TLS 1.2. */ -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || \ - (defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) && defined(MBEDTLS_SSL_PROTO_TLS1_2)) -#define MBEDTLS_SSL_KEEP_RANDBYTES -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * SSL state machine - */ -typedef enum { - MBEDTLS_SSL_HELLO_REQUEST, - MBEDTLS_SSL_CLIENT_HELLO, - MBEDTLS_SSL_SERVER_HELLO, - MBEDTLS_SSL_SERVER_CERTIFICATE, - MBEDTLS_SSL_SERVER_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_REQUEST, - MBEDTLS_SSL_SERVER_HELLO_DONE, - MBEDTLS_SSL_CLIENT_CERTIFICATE, - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_VERIFY, - MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_CLIENT_FINISHED, - MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_SERVER_FINISHED, - MBEDTLS_SSL_FLUSH_BUFFERS, - MBEDTLS_SSL_HANDSHAKE_WRAPUP, - MBEDTLS_SSL_NEW_SESSION_TICKET, - MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, - MBEDTLS_SSL_HELLO_RETRY_REQUEST, - MBEDTLS_SSL_ENCRYPTED_EXTENSIONS, - MBEDTLS_SSL_END_OF_EARLY_DATA, - MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY, - MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED, - MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO, - MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO, - MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO, - MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST, - MBEDTLS_SSL_HANDSHAKE_OVER, - MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET, - MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH, -} -mbedtls_ssl_states; - -/* - * Early data status, client side only. - */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) -typedef enum { -/* - * See documentation of mbedtls_ssl_get_early_data_status(). - */ - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED, - MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, -} mbedtls_ssl_early_data_status; -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ - -/** - * \brief Callback type: send data on the network. - * - * \note That callback may be either blocking or non-blocking. - * - * \param ctx Context for the send callback (typically a file descriptor) - * \param buf Buffer holding the data to send - * \param len Length of the data to send - * - * \return The callback must return the number of bytes sent if any, - * or a non-zero error code. - * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE - * must be returned when the operation would block. - * - * \note The callback is allowed to send fewer bytes than requested. - * It must always return the number of bytes actually sent. - */ -typedef int mbedtls_ssl_send_t(void *ctx, - const unsigned char *buf, - size_t len); - -/** - * \brief Callback type: receive data from the network. - * - * \note That callback may be either blocking or non-blocking. - * - * \param ctx Context for the receive callback (typically a file - * descriptor) - * \param buf Buffer to write the received data to - * \param len Length of the receive buffer - * - * \returns If data has been received, the positive number of bytes received. - * \returns \c 0 if the connection has been closed. - * \returns If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ - * must be returned when the operation would block. - * \returns Another negative error code on other kinds of failures. - * - * \note The callback may receive fewer bytes than the length of the - * buffer. It must always return the number of bytes actually - * received and written to the buffer. - */ -typedef int mbedtls_ssl_recv_t(void *ctx, - unsigned char *buf, - size_t len); - -/** - * \brief Callback type: receive data from the network, with timeout - * - * \note That callback must block until data is received, or the - * timeout delay expires, or the operation is interrupted by a - * signal. - * - * \param ctx Context for the receive callback (typically a file descriptor) - * \param buf Buffer to write the received data to - * \param len Length of the receive buffer - * \param timeout Maximum number of milliseconds to wait for data - * 0 means no timeout (potentially waiting forever) - * - * \return The callback must return the number of bytes received, - * or a non-zero error code: - * \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, - * \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * - * \note The callback may receive fewer bytes than the length of the - * buffer. It must always return the number of bytes actually - * received and written to the buffer. - */ -typedef int mbedtls_ssl_recv_timeout_t(void *ctx, - unsigned char *buf, - size_t len, - uint32_t timeout); -/** - * \brief Callback type: set a pair of timers/delays to watch - * - * \param ctx Context pointer - * \param int_ms Intermediate delay in milliseconds - * \param fin_ms Final delay in milliseconds - * 0 cancels the current timer. - * - * \note This callback must at least store the necessary information - * for the associated \c mbedtls_ssl_get_timer_t callback to - * return correct information. - * - * \note If using an event-driven style of programming, an event must - * be generated when the final delay is passed. The event must - * cause a call to \c mbedtls_ssl_handshake() with the proper - * SSL context to be scheduled. Care must be taken to ensure - * that at most one such call happens at a time. - * - * \note Only one timer at a time must be running. Calling this - * function while a timer is running must cancel it. Cancelled - * timers must not generate any event. - */ -typedef void mbedtls_ssl_set_timer_t(void *ctx, - uint32_t int_ms, - uint32_t fin_ms); - -/** - * \brief Callback type: get status of timers/delays - * - * \param ctx Context pointer - * - * \return This callback must return: - * -1 if cancelled (fin_ms == 0), - * 0 if none of the delays have passed, - * 1 if only the intermediate delay has passed, - * 2 if the final delay has passed. - */ -typedef int mbedtls_ssl_get_timer_t(void *ctx); - -/* Defined below */ -typedef struct mbedtls_ssl_session mbedtls_ssl_session; -typedef struct mbedtls_ssl_context mbedtls_ssl_context; -typedef struct mbedtls_ssl_config mbedtls_ssl_config; - -/* Defined in library/ssl_misc.h */ -typedef struct mbedtls_ssl_transform mbedtls_ssl_transform; -typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params; -typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t; -#if defined(MBEDTLS_X509_CRT_PARSE_C) -typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; -#endif -#if defined(MBEDTLS_SSL_PROTO_DTLS) -typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK /* 1U << 0 */ -#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL /* 1U << 2 */ -#define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA (1U << 3) - -#define MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK \ - (MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION | \ - MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION | \ - MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA) -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ - -/** - * \brief Callback type: server-side session cache getter - * - * The session cache is logically a key value store, with - * keys being session IDs and values being instances of - * mbedtls_ssl_session. - * - * This callback retrieves an entry in this key-value store. - * - * \param data The address of the session cache structure to query. - * \param session_id The buffer holding the session ID to query. - * \param session_id_len The length of \p session_id in Bytes. - * \param session The address of the session structure to populate. - * It is initialized with mbdtls_ssl_session_init(), - * and the callback must always leave it in a state - * where it can safely be freed via - * mbedtls_ssl_session_free() independent of the - * return code of this function. - * - * \return \c 0 on success - * \return A non-zero return value on failure. - * - */ -typedef int mbedtls_ssl_cache_get_t(void *data, - unsigned char const *session_id, - size_t session_id_len, - mbedtls_ssl_session *session); -/** - * \brief Callback type: server-side session cache setter - * - * The session cache is logically a key value store, with - * keys being session IDs and values being instances of - * mbedtls_ssl_session. - * - * This callback sets an entry in this key-value store. - * - * \param data The address of the session cache structure to modify. - * \param session_id The buffer holding the session ID to query. - * \param session_id_len The length of \p session_id in Bytes. - * \param session The address of the session to be stored in the - * session cache. - * - * \return \c 0 on success - * \return A non-zero return value on failure. - */ -typedef int mbedtls_ssl_cache_set_t(void *data, - unsigned char const *session_id, - size_t session_id_len, - const mbedtls_ssl_session *session); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Callback type: start external signature operation. - * - * This callback is called during an SSL handshake to start - * a signature decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p hash if the value - * is needed for later processing, because the \p hash buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \note For RSA signatures, this function must produce output - * that is consistent with PKCS#1 v1.5 in the same way as - * mbedtls_rsa_pkcs1_sign(). Before the private key operation, - * apply the padding steps described in RFC 8017, section 9.2 - * "EMSA-PKCS1-v1_5" as follows. - * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the DigestInfo to be - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 3, with `T = hash` and `tLen = hash_len`. - * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the hash to be encoded and - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 2, with `digestAlgorithm` obtained by calling - * mbedtls_oid_get_oid_by_md() on \p md_alg. - * - * \note For ECDSA signatures, the output format is the DER encoding - * `Ecdsa-Sig-Value` defined in - * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4). - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param md_alg Hash algorithm. - * \param hash Buffer containing the hash. This buffer is - * no longer valid when the function returns. - * \param hash_len Size of the \c hash buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_sign_t(mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - mbedtls_md_type_t md_alg, - const unsigned char *hash, - size_t hash_len); - -/** - * \brief Callback type: start external decryption operation. - * - * This callback is called during an SSL handshake to start - * an RSA decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p input if the value - * is needed for later processing, because the \p input buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \warning RSA decryption as used in TLS is subject to a potential - * timing side channel attack first discovered by Bleichenbacher - * in 1998. This attack can be remotely exploitable - * in practice. To avoid this attack, you must ensure that - * if the callback performs an RSA decryption, the time it - * takes to execute and return the result does not depend - * on whether the RSA decryption succeeded or reported - * invalid padding. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param input Buffer containing the input ciphertext. This buffer - * is no longer valid when the function returns. - * \param input_len Size of the \p input buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_decrypt_t(mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - const unsigned char *input, - size_t input_len); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Callback type: resume external operation. - * - * This callback is called during an SSL handshake to resume - * an external operation started by the - * ::mbedtls_ssl_async_sign_t or - * ::mbedtls_ssl_async_decrypt_t callback. - * - * This function typically checks the status of a pending - * request or causes the request queue to make progress, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * It may call mbedtls_ssl_set_async_operation_data() to modify - * this context. - * - * Note that when this function returns a status other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any - * resources associated with the operation. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param output Buffer containing the output (signature or decrypted - * data) on success. - * \param output_len On success, number of bytes written to \p output. - * \param output_size Size of the \p output buffer in bytes. - * - * \return 0 if output of the operation is available in the - * \p output buffer. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * is still in progress. Subsequent requests for progress - * on the SSL connection will call the resume callback - * again. - * \return Any other error means that the operation is aborted. - * The SSL handshake is aborted. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_resume_t(mbedtls_ssl_context *ssl, - unsigned char *output, - size_t *output_len, - size_t output_size); - -/** - * \brief Callback type: cancel external operation. - * - * This callback is called if an SSL connection is closed - * while an asynchronous operation is in progress. Note that - * this callback is not called if the - * ::mbedtls_ssl_async_resume_t callback has run and has - * returned a value other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case - * the asynchronous operation has already completed. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * - * \param ssl The SSL connection instance. It should not be - * modified. - */ -typedef void mbedtls_ssl_async_cancel_t(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN 48 -#if defined(MBEDTLS_MD_CAN_SHA256) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA256 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 32 -#elif defined(MBEDTLS_MD_CAN_SHA384) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA384 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 48 -#elif defined(MBEDTLS_MD_CAN_SHA1) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA1 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 20 -#else -/* This is already checked in check_config.h, but be sure. */ -#error "Bad configuration - need SHA-1, SHA-256 or SHA-512 enabled to compute digest of peer CRT." -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && - !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -typedef struct { - unsigned char client_application_traffic_secret_N[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char server_application_traffic_secret_N[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char exporter_master_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char resumption_master_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; -} mbedtls_ssl_tls13_application_secrets; - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - -#define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH 255 -#define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 4 -/* - * For code readability use a typedef for DTLS-SRTP profiles - * - * Use_srtp extension protection profiles values as defined in - * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml - * - * Reminder: if this list is expanded mbedtls_ssl_check_srtp_profile_value - * must be updated too. - */ -#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 ((uint16_t) 0x0001) -#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 ((uint16_t) 0x0002) -#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 ((uint16_t) 0x0005) -#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 ((uint16_t) 0x0006) -/* This one is not iana defined, but for code readability. */ -#define MBEDTLS_TLS_SRTP_UNSET ((uint16_t) 0x0000) - -typedef uint16_t mbedtls_ssl_srtp_profile; - -typedef struct mbedtls_dtls_srtp_info_t { - /*! The SRTP profile that was negotiated. */ - mbedtls_ssl_srtp_profile MBEDTLS_PRIVATE(chosen_dtls_srtp_profile); - /*! The length of mki_value. */ - uint16_t MBEDTLS_PRIVATE(mki_len); - /*! The mki_value used, with max size of 256 bytes. */ - unsigned char MBEDTLS_PRIVATE(mki_value)[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH]; -} -mbedtls_dtls_srtp_info; - -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -/** Human-friendly representation of the (D)TLS protocol version. */ -typedef enum { - MBEDTLS_SSL_VERSION_UNKNOWN, /*!< Context not in use or version not yet negotiated. */ - MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303, /*!< (D)TLS 1.2 */ - MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304, /*!< (D)TLS 1.3 */ -} mbedtls_ssl_protocol_version; - -/* - * This structure is used for storing current session data. - * - * Note: when changing this definition, we need to check and update: - * - in tests/suites/test_suite_ssl.function: - * ssl_populate_session() and ssl_serialize_session_save_load() - * - in library/ssl_tls.c: - * mbedtls_ssl_session_init() and mbedtls_ssl_session_free() - * mbedtls_ssl_session_save() and ssl_session_load() - * ssl_session_copy() - */ -struct mbedtls_ssl_session { -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - unsigned char MBEDTLS_PRIVATE(mfl_code); /*!< MaxFragmentLength negotiated by peer */ -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -/*!< RecordSizeLimit received from the peer */ -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - uint16_t MBEDTLS_PRIVATE(record_size_limit); -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - - unsigned char MBEDTLS_PRIVATE(exported); - uint8_t MBEDTLS_PRIVATE(endpoint); /*!< 0: client, 1: server */ - - /** TLS version negotiated in the session. Used if and when renegotiating - * or resuming a session instead of the configured minor TLS version. - */ - mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version); - -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< start time of current session */ -#endif - int MBEDTLS_PRIVATE(ciphersuite); /*!< chosen ciphersuite */ - size_t MBEDTLS_PRIVATE(id_len); /*!< session id length */ - unsigned char MBEDTLS_PRIVATE(id)[32]; /*!< session identifier */ - unsigned char MBEDTLS_PRIVATE(master)[48]; /*!< the master secret */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_x509_crt *MBEDTLS_PRIVATE(peer_cert); /*!< peer X.509 cert chain */ -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /*! The digest of the peer's end-CRT. This must be kept to detect CRT - * changes during renegotiation, mitigating the triple handshake attack. */ - unsigned char *MBEDTLS_PRIVATE(peer_cert_digest); - size_t MBEDTLS_PRIVATE(peer_cert_digest_len); - mbedtls_md_type_t MBEDTLS_PRIVATE(peer_cert_digest_type); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - uint32_t MBEDTLS_PRIVATE(verify_result); /*!< verification result */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - unsigned char *MBEDTLS_PRIVATE(ticket); /*!< RFC 5077 session ticket */ - size_t MBEDTLS_PRIVATE(ticket_len); /*!< session ticket length */ - uint32_t MBEDTLS_PRIVATE(ticket_lifetime); /*!< ticket lifetime hint */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_HAVE_TIME) - /*! When a ticket is created by a TLS server as part of an established TLS - * session, the ticket creation time may need to be saved for the ticket - * module to be able to check the ticket age when the ticket is used. - * That's the purpose of this field. - * Before creating a new ticket, an Mbed TLS server set this field with - * its current time in milliseconds. This time may then be saved in the - * session ticket data by the session ticket writing function and - * recovered by the ticket parsing function later when the ticket is used. - * The ticket module may then use this time to compute the ticket age and - * determine if it has expired or not. - * The Mbed TLS implementations of the session ticket writing and parsing - * functions save and retrieve the ticket creation time as part of the - * session ticket data. The session ticket parsing function relies on - * the mbedtls_ssl_session_get_ticket_creation_time() API to get the - * ticket creation time from the session ticket data. - */ - mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) - uint32_t MBEDTLS_PRIVATE(ticket_age_add); /*!< Randomly generated value used to obscure the age of the ticket */ - uint8_t MBEDTLS_PRIVATE(ticket_flags); /*!< Ticket flags */ - uint8_t MBEDTLS_PRIVATE(resumption_key_len); /*!< resumption_key length */ - unsigned char MBEDTLS_PRIVATE(resumption_key)[MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN]; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && defined(MBEDTLS_SSL_CLI_C) - char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */ -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - char *ticket_alpn; /*!< ALPN negotiated in the session - during which the ticket was generated. */ -#endif - -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C) - /*! Time in milliseconds when the last ticket was received. */ - mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) - uint32_t MBEDTLS_PRIVATE(max_early_data_size); /*!< maximum amount of early data in tickets */ -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - int MBEDTLS_PRIVATE(encrypt_then_mac); /*!< flag for EtM activation */ -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_tls13_application_secrets MBEDTLS_PRIVATE(app_secrets); -#endif -}; - -/* - * Identifiers for PRFs used in various versions of TLS. - */ -typedef enum { - MBEDTLS_SSL_TLS_PRF_NONE, - MBEDTLS_SSL_TLS_PRF_SHA384, - MBEDTLS_SSL_TLS_PRF_SHA256, - MBEDTLS_SSL_HKDF_EXPAND_SHA384, - MBEDTLS_SSL_HKDF_EXPAND_SHA256 -} -mbedtls_tls_prf_types; - -typedef enum { - MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET = 0, -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_EARLY_EXPORTER_SECRET, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET, -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -} mbedtls_ssl_key_export_type; - -/** - * \brief Callback type: Export key alongside random values for - * session identification, and PRF for - * implementation of TLS key exporters. - * - * \param p_expkey Context for the callback. - * \param type The type of the key that is being exported. - * \param secret The address of the buffer holding the secret - * that's being exporterd. - * \param secret_len The length of \p secret in bytes. - * \param client_random The client random bytes. - * \param server_random The server random bytes. - * \param tls_prf_type The identifier for the PRF used in the handshake - * to which the key belongs. - */ -typedef void mbedtls_ssl_export_keys_t(void *p_expkey, - mbedtls_ssl_key_export_type type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type); - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Callback type: generic handshake callback - * - * \note Callbacks may use user_data funcs to set/get app user data. - * See \c mbedtls_ssl_get_user_data_p() - * \c mbedtls_ssl_get_user_data_n() - * \c mbedtls_ssl_conf_get_user_data_p() - * \c mbedtls_ssl_conf_get_user_data_n() - * - * \param ssl \c mbedtls_ssl_context on which the callback is run - * - * \return The return value of the callback is 0 if successful, - * or a specific MBEDTLS_ERR_XXX code, which will cause - * the handshake to be aborted. - */ -typedef int (*mbedtls_ssl_hs_cb_t)(mbedtls_ssl_context *ssl); -#endif - -/* A type for storing user data in a library structure. - * - * The representation of type may change in future versions of the library. - * Only the behaviors guaranteed by documented accessor functions are - * guaranteed to remain stable. - */ -typedef union { - uintptr_t n; /* typically a handle to an associated object */ - void *p; /* typically a pointer to extra data */ -} mbedtls_ssl_user_data_t; - -/** - * SSL/TLS configuration to be shared between mbedtls_ssl_context structures. - */ -struct mbedtls_ssl_config { - /* Group items mostly by size. This helps to reduce memory wasted to - * padding. It also helps to keep smaller fields early in the structure, - * so that elements tend to be in the 128-element direct access window - * on Arm Thumb, which reduces the code size. */ - - mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(max_tls_version); /*!< max. TLS version used */ - mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(min_tls_version); /*!< min. TLS version used */ - - /* - * Flags (could be bit-fields to save RAM, but separate bytes make - * the code smaller on architectures with an instruction for direct - * byte access). - */ - - uint8_t MBEDTLS_PRIVATE(endpoint); /*!< 0: client, 1: server */ - uint8_t MBEDTLS_PRIVATE(transport); /*!< 0: stream (TLS), 1: datagram (DTLS) */ - uint8_t MBEDTLS_PRIVATE(authmode); /*!< MBEDTLS_SSL_VERIFY_XXX */ - /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ - uint8_t MBEDTLS_PRIVATE(allow_legacy_renegotiation); /*!< MBEDTLS_LEGACY_XXX */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - uint8_t MBEDTLS_PRIVATE(mfl_code); /*!< desired fragment length indicator - (MBEDTLS_SSL_MAX_FRAG_LEN_XXX) */ -#endif -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - uint8_t MBEDTLS_PRIVATE(encrypt_then_mac); /*!< negotiate encrypt-then-mac? */ -#endif -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - uint8_t MBEDTLS_PRIVATE(extended_ms); /*!< negotiate extended master secret? */ -#endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - uint8_t MBEDTLS_PRIVATE(anti_replay); /*!< detect and prevent replay? */ -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - uint8_t MBEDTLS_PRIVATE(disable_renegotiation); /*!< disable renegotiation? */ -#endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_CLI_C) - /** Encodes two booleans, one stating whether TLS 1.2 session tickets are - * enabled or not, the other one whether the handling of TLS 1.3 - * NewSessionTicket messages is enabled or not. They are respectively set - * by mbedtls_ssl_conf_session_tickets() and - * mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(). - */ - uint8_t MBEDTLS_PRIVATE(session_tickets); /*!< use session tickets? */ -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_3) - uint16_t MBEDTLS_PRIVATE(new_session_tickets_count); /*!< number of NewSessionTicket */ -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - uint8_t MBEDTLS_PRIVATE(cert_req_ca_list); /*!< enable sending CA list in - Certificate Request messages? */ - uint8_t MBEDTLS_PRIVATE(respect_cli_pref); /*!< pick the ciphersuite according to - the client's preferences rather - than ours? */ -#endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - uint8_t MBEDTLS_PRIVATE(ignore_unexpected_cid); /*!< Should DTLS record with - * unexpected CID - * lead to failure? */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#if defined(MBEDTLS_SSL_DTLS_SRTP) - uint8_t MBEDTLS_PRIVATE(dtls_srtp_mki_support); /* support having mki_value - in the use_srtp extension? */ -#endif - - /* - * Pointers - */ - - /** Allowed ciphersuites for (D)TLS 1.2 (0-terminated) */ - const int *MBEDTLS_PRIVATE(ciphersuite_list); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - /** Allowed TLS 1.3 key exchange modes. */ - int MBEDTLS_PRIVATE(tls13_kex_modes); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - /** Callback for printing debug output */ - void(*MBEDTLS_PRIVATE(f_dbg))(void *, int, const char *, int, const char *); - void *MBEDTLS_PRIVATE(p_dbg); /*!< context for the debug function */ - - /** Callback for getting (pseudo-)random numbers */ - int(*MBEDTLS_PRIVATE(f_rng))(void *, unsigned char *, size_t); - void *MBEDTLS_PRIVATE(p_rng); /*!< context for the RNG function */ - - /** Callback to retrieve a session from the cache */ - mbedtls_ssl_cache_get_t *MBEDTLS_PRIVATE(f_get_cache); - /** Callback to store a session into the cache */ - mbedtls_ssl_cache_set_t *MBEDTLS_PRIVATE(f_set_cache); - void *MBEDTLS_PRIVATE(p_cache); /*!< context for cache callbacks */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - /** Callback for setting cert according to SNI extension */ - int(*MBEDTLS_PRIVATE(f_sni))(void *, mbedtls_ssl_context *, const unsigned char *, size_t); - void *MBEDTLS_PRIVATE(p_sni); /*!< context for SNI callback */ -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /** Callback to customize X.509 certificate chain verification */ - int(*MBEDTLS_PRIVATE(f_vrfy))(void *, mbedtls_x509_crt *, int, uint32_t *); - void *MBEDTLS_PRIVATE(p_vrfy); /*!< context for X.509 verify calllback */ -#endif - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -#if defined(MBEDTLS_SSL_SRV_C) - /** Callback to retrieve PSK key from identity */ - int(*MBEDTLS_PRIVATE(f_psk))(void *, mbedtls_ssl_context *, const unsigned char *, size_t); - void *MBEDTLS_PRIVATE(p_psk); /*!< context for PSK callback */ -#endif -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - /** Callback to create & write a cookie for ClientHello verification */ - int(*MBEDTLS_PRIVATE(f_cookie_write))(void *, unsigned char **, unsigned char *, - const unsigned char *, size_t); - /** Callback to verify validity of a ClientHello cookie */ - int(*MBEDTLS_PRIVATE(f_cookie_check))(void *, const unsigned char *, size_t, - const unsigned char *, size_t); - void *MBEDTLS_PRIVATE(p_cookie); /*!< context for the cookie callbacks */ -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) - /** Callback to create & write a session ticket */ - int(*MBEDTLS_PRIVATE(f_ticket_write))(void *, const mbedtls_ssl_session *, - unsigned char *, const unsigned char *, size_t *, - uint32_t *); - /** Callback to parse a session ticket into a session structure */ - int(*MBEDTLS_PRIVATE(f_ticket_parse))(void *, mbedtls_ssl_session *, unsigned char *, size_t); - void *MBEDTLS_PRIVATE(p_ticket); /*!< context for the ticket callbacks */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - size_t MBEDTLS_PRIVATE(cid_len); /*!< The length of CIDs for incoming DTLS records. */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - const mbedtls_x509_crt_profile *MBEDTLS_PRIVATE(cert_profile); /*!< verification profile */ - mbedtls_ssl_key_cert *MBEDTLS_PRIVATE(key_cert); /*!< own certificate/key pair(s) */ - mbedtls_x509_crt *MBEDTLS_PRIVATE(ca_chain); /*!< trusted CAs */ - mbedtls_x509_crl *MBEDTLS_PRIVATE(ca_crl); /*!< trusted CAs CRLs */ -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - mbedtls_x509_crt_ca_cb_t MBEDTLS_PRIVATE(f_ca_cb); - void *MBEDTLS_PRIVATE(p_ca_cb); -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_async_sign_t *MBEDTLS_PRIVATE(f_async_sign_start); /*!< start asynchronous signature operation */ - mbedtls_ssl_async_decrypt_t *MBEDTLS_PRIVATE(f_async_decrypt_start); /*!< start asynchronous decryption operation */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - mbedtls_ssl_async_resume_t *MBEDTLS_PRIVATE(f_async_resume); /*!< resume asynchronous operation */ - mbedtls_ssl_async_cancel_t *MBEDTLS_PRIVATE(f_async_cancel); /*!< cancel asynchronous operation */ - void *MBEDTLS_PRIVATE(p_async_config_data); /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - const int *MBEDTLS_PRIVATE(sig_hashes); /*!< allowed signature hashes */ -#endif - const uint16_t *MBEDTLS_PRIVATE(sig_algs); /*!< allowed signature algorithms */ -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) - const mbedtls_ecp_group_id *MBEDTLS_PRIVATE(curve_list); /*!< allowed curves */ -#endif - - const uint16_t *MBEDTLS_PRIVATE(group_list); /*!< allowed IANA NamedGroups */ - -#if defined(MBEDTLS_DHM_C) - mbedtls_mpi MBEDTLS_PRIVATE(dhm_P); /*!< prime modulus for DHM */ - mbedtls_mpi MBEDTLS_PRIVATE(dhm_G); /*!< generator for DHM */ -#endif - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_svc_key_id_t MBEDTLS_PRIVATE(psk_opaque); /*!< PSA key slot holding opaque PSK. This field - * should only be set via - * mbedtls_ssl_conf_psk_opaque(). - * If either no PSK or a raw PSK have been - * configured, this has value \c 0. - */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - unsigned char *MBEDTLS_PRIVATE(psk); /*!< The raw pre-shared key. This field should - * only be set via mbedtls_ssl_conf_psk(). - * If either no PSK or an opaque PSK - * have been configured, this has value NULL. */ - size_t MBEDTLS_PRIVATE(psk_len); /*!< The length of the raw pre-shared key. - * This field should only be set via - * mbedtls_ssl_conf_psk(). - * Its value is non-zero if and only if - * \c psk is not \c NULL. */ - - unsigned char *MBEDTLS_PRIVATE(psk_identity); /*!< The PSK identity for PSK negotiation. - * This field should only be set via - * mbedtls_ssl_conf_psk(). - * This is set if and only if either - * \c psk or \c psk_opaque are set. */ - size_t MBEDTLS_PRIVATE(psk_identity_len);/*!< The length of PSK identity. - * This field should only be set via - * mbedtls_ssl_conf_psk(). - * Its value is non-zero if and only if - * \c psk is not \c NULL or \c psk_opaque - * is not \c 0. */ -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) - int MBEDTLS_PRIVATE(early_data_enabled); /*!< Early data enablement: - * - MBEDTLS_SSL_EARLY_DATA_DISABLED, - * - MBEDTLS_SSL_EARLY_DATA_ENABLED */ - -#if defined(MBEDTLS_SSL_SRV_C) - /* The maximum amount of 0-RTT data. RFC 8446 section 4.6.1 */ - uint32_t MBEDTLS_PRIVATE(max_early_data_size); -#endif /* MBEDTLS_SSL_SRV_C */ - -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_ALPN) - const char **MBEDTLS_PRIVATE(alpn_list); /*!< ordered list of protocols */ -#endif - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - /*! ordered list of supported srtp profile */ - const mbedtls_ssl_srtp_profile *MBEDTLS_PRIVATE(dtls_srtp_profile_list); - /*! number of supported profiles */ - size_t MBEDTLS_PRIVATE(dtls_srtp_profile_list_len); -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - - /* - * Numerical settings (int) - */ - - uint32_t MBEDTLS_PRIVATE(read_timeout); /*!< timeout for mbedtls_ssl_read (ms) */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint32_t MBEDTLS_PRIVATE(hs_timeout_min); /*!< initial value of the handshake - retransmission timeout (ms) */ - uint32_t MBEDTLS_PRIVATE(hs_timeout_max); /*!< maximum value of the handshake - retransmission timeout (ms) */ -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int MBEDTLS_PRIVATE(renego_max_records); /*!< grace period for renegotiation */ - unsigned char MBEDTLS_PRIVATE(renego_period)[8]; /*!< value of the record counters - that triggers renegotiation */ -#endif - - unsigned int MBEDTLS_PRIVATE(badmac_limit); /*!< limit of records with a bad MAC */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - unsigned int MBEDTLS_PRIVATE(dhm_min_bitlen); /*!< min. bit length of the DHM prime */ -#endif - - /** User data pointer or handle. - * - * The library sets this to \p 0 when creating a context and does not - * access it afterwards. - */ - mbedtls_ssl_user_data_t MBEDTLS_PRIVATE(user_data); - -#if defined(MBEDTLS_SSL_SRV_C) - mbedtls_ssl_hs_cb_t MBEDTLS_PRIVATE(f_cert_cb); /*!< certificate selection callback */ -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) - const mbedtls_x509_crt *MBEDTLS_PRIVATE(dn_hints);/*!< acceptable client cert issuers */ -#endif -}; - -struct mbedtls_ssl_context { - const mbedtls_ssl_config *MBEDTLS_PRIVATE(conf); /*!< configuration information */ - - /* - * Miscellaneous - */ - int MBEDTLS_PRIVATE(state); /*!< SSL handshake: current state */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int MBEDTLS_PRIVATE(renego_status); /*!< Initial, in progress, pending? */ - int MBEDTLS_PRIVATE(renego_records_seen); /*!< Records since renego request, or with DTLS, - number of retransmissions of request if - renego_max_records is < 0 */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - /** - * Maximum TLS version to be negotiated, then negotiated TLS version. - * - * It is initialized as the configured maximum TLS version to be - * negotiated by mbedtls_ssl_setup(). - * - * When renegotiating or resuming a session, it is overwritten in the - * ClientHello writing preparation stage with the previously negotiated - * TLS version. - * - * On client side, it is updated to the TLS version selected by the server - * for the handshake when the ServerHello is received. - * - * On server side, it is updated to the TLS version the server selects for - * the handshake when the ClientHello is received. - */ - mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version); - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) - /** - * State of the negotiation and transfer of early data. Reset to - * MBEDTLS_SSL_EARLY_DATA_STATE_IDLE when the context is reset. - */ - int MBEDTLS_PRIVATE(early_data_state); -#endif - - /** Multipurpose field. - * - * - DTLS: records with a bad MAC received. - * - TLS: accumulated length of handshake fragments (up to \c in_hslen). - * - * This field is multipurpose in order to preserve the ABI in the - * Mbed TLS 3.6 LTS branch. Until 3.6.2, it was only used in DTLS - * and called `badmac_seen`. - */ - unsigned MBEDTLS_PRIVATE(badmac_seen_or_in_hsfraglen); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /** Callback to customize X.509 certificate chain verification */ - int(*MBEDTLS_PRIVATE(f_vrfy))(void *, mbedtls_x509_crt *, int, uint32_t *); - void *MBEDTLS_PRIVATE(p_vrfy); /*!< context for X.509 verify callback */ -#endif - - mbedtls_ssl_send_t *MBEDTLS_PRIVATE(f_send); /*!< Callback for network send */ - mbedtls_ssl_recv_t *MBEDTLS_PRIVATE(f_recv); /*!< Callback for network receive */ - mbedtls_ssl_recv_timeout_t *MBEDTLS_PRIVATE(f_recv_timeout); - /*!< Callback for network receive with timeout */ - - void *MBEDTLS_PRIVATE(p_bio); /*!< context for I/O operations */ - - /* - * Session layer - */ - mbedtls_ssl_session *MBEDTLS_PRIVATE(session_in); /*!< current session data (in) */ - mbedtls_ssl_session *MBEDTLS_PRIVATE(session_out); /*!< current session data (out) */ - mbedtls_ssl_session *MBEDTLS_PRIVATE(session); /*!< negotiated session data */ - mbedtls_ssl_session *MBEDTLS_PRIVATE(session_negotiate); /*!< session data in negotiation */ - - mbedtls_ssl_handshake_params *MBEDTLS_PRIVATE(handshake); /*!< params required only during - the handshake process */ - - /* - * Record layer transformations - */ - mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_in); /*!< current transform params (in) - * This is always a reference, - * never an owning pointer. */ - mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_out); /*!< current transform params (out) - * This is always a reference, - * never an owning pointer. */ - mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform); /*!< negotiated transform params - * This pointer owns the transform - * it references. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_negotiate); /*!< transform params in negotiation - * This pointer owns the transform - * it references. */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - /*! The application data transform in TLS 1.3. - * This pointer owns the transform it references. */ - mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_application); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - /* - * Timers - */ - void *MBEDTLS_PRIVATE(p_timer); /*!< context for the timer callbacks */ - - mbedtls_ssl_set_timer_t *MBEDTLS_PRIVATE(f_set_timer); /*!< set timer callback */ - mbedtls_ssl_get_timer_t *MBEDTLS_PRIVATE(f_get_timer); /*!< get timer callback */ - - /* - * Record layer (incoming data) - */ - unsigned char *MBEDTLS_PRIVATE(in_buf); /*!< input buffer */ - unsigned char *MBEDTLS_PRIVATE(in_ctr); /*!< 64-bit incoming message counter - TLS: maintained by us - DTLS: read from peer */ - unsigned char *MBEDTLS_PRIVATE(in_hdr); /*!< start of record header */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char *MBEDTLS_PRIVATE(in_cid); /*!< The start of the CID; - * (the end is marked by in_len). */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - unsigned char *MBEDTLS_PRIVATE(in_len); /*!< two-bytes message length field */ - unsigned char *MBEDTLS_PRIVATE(in_iv); /*!< ivlen-byte IV */ - unsigned char *MBEDTLS_PRIVATE(in_msg); /*!< message contents (in_iv+ivlen) */ - unsigned char *MBEDTLS_PRIVATE(in_offt); /*!< read offset in application data */ - - int MBEDTLS_PRIVATE(in_msgtype); /*!< record header: message type */ - size_t MBEDTLS_PRIVATE(in_msglen); /*!< record header: message length */ - size_t MBEDTLS_PRIVATE(in_left); /*!< amount of data read so far */ -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t MBEDTLS_PRIVATE(in_buf_len); /*!< length of input buffer */ -#endif -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint16_t MBEDTLS_PRIVATE(in_epoch); /*!< DTLS epoch for incoming records */ - size_t MBEDTLS_PRIVATE(next_record_offset); /*!< offset of the next record in datagram - (equal to in_left if none) */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - uint64_t MBEDTLS_PRIVATE(in_window_top); /*!< last validated record seq_num */ - uint64_t MBEDTLS_PRIVATE(in_window); /*!< bitmask for replay detection */ -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - - size_t MBEDTLS_PRIVATE(in_hslen); /*!< current handshake message length, - including the handshake header */ - int MBEDTLS_PRIVATE(nb_zero); /*!< # of 0-length encrypted messages */ - - int MBEDTLS_PRIVATE(keep_current_message); /*!< drop or reuse current message - on next call to record layer? */ - - /* The following three variables indicate if and, if yes, - * what kind of alert is pending to be sent. - */ - unsigned char MBEDTLS_PRIVATE(send_alert); /*!< Determines if a fatal alert - should be sent. Values: - - \c 0 , no alert is to be sent. - - \c 1 , alert is to be sent. */ - unsigned char MBEDTLS_PRIVATE(alert_type); /*!< Type of alert if send_alert - != 0 */ - int MBEDTLS_PRIVATE(alert_reason); /*!< The error code to be returned - to the user once the fatal alert - has been sent. */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint8_t MBEDTLS_PRIVATE(disable_datagram_packing); /*!< Disable packing multiple records - * within a single datagram. */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) -#if defined(MBEDTLS_SSL_SRV_C) - /* - * One of: - * MBEDTLS_SSL_EARLY_DATA_NO_DISCARD - * MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD - * MBEDTLS_SSL_EARLY_DATA_DISCARD - */ - uint8_t MBEDTLS_PRIVATE(discard_early_data_record); -#endif - uint32_t MBEDTLS_PRIVATE(total_early_data_size); /*!< Number of received/written early data bytes */ -#endif /* MBEDTLS_SSL_EARLY_DATA */ - - /* - * Record layer (outgoing data) - */ - unsigned char *MBEDTLS_PRIVATE(out_buf); /*!< output buffer */ - unsigned char *MBEDTLS_PRIVATE(out_ctr); /*!< 64-bit outgoing message counter */ - unsigned char *MBEDTLS_PRIVATE(out_hdr); /*!< start of record header */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char *MBEDTLS_PRIVATE(out_cid); /*!< The start of the CID; - * (the end is marked by in_len). */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - unsigned char *MBEDTLS_PRIVATE(out_len); /*!< two-bytes message length field */ - unsigned char *MBEDTLS_PRIVATE(out_iv); /*!< ivlen-byte IV */ - unsigned char *MBEDTLS_PRIVATE(out_msg); /*!< message contents (out_iv+ivlen) */ - - int MBEDTLS_PRIVATE(out_msgtype); /*!< record header: message type */ - size_t MBEDTLS_PRIVATE(out_msglen); /*!< record header: message length */ - size_t MBEDTLS_PRIVATE(out_left); /*!< amount of data not yet written */ -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t MBEDTLS_PRIVATE(out_buf_len); /*!< length of output buffer */ -#endif - - unsigned char MBEDTLS_PRIVATE(cur_out_ctr)[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!< Outgoing record sequence number. */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint16_t MBEDTLS_PRIVATE(mtu); /*!< path mtu, used to fragment outgoing messages */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * User settings - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /** Expected peer CN for verification. - * - * Also used on clients for SNI, - * and for TLS 1.3 session resumption using tickets. - * - * The value of this field can be: - * - \p NULL in a newly initialized or reset context. - * - A heap-allocated copy of the last value passed to - * mbedtls_ssl_set_hostname(), if the last call had a non-null - * \p hostname argument. - * - A special value to indicate that mbedtls_ssl_set_hostname() - * was called with \p NULL (as opposed to never having been called). - * See `mbedtls_ssl_get_hostname_pointer()` in `ssl_tls.c`. - * - * If this field contains the value \p NULL and the configuration option - * #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME - * is unset, on a TLS client, attempting to verify a server certificate - * results in the error - * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME. - * - * If this field contains the special value described above, or if - * the value is \p NULL and the configuration option - * #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME - * is set, then the peer name verification is skipped, which may be - * insecure, especially on a client. Furthermore, on a client, the - * server_name extension is not sent, and the server name is ignored - * in TLS 1.3 session resumption using tickets. - */ - char *MBEDTLS_PRIVATE(hostname); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_ALPN) - const char *MBEDTLS_PRIVATE(alpn_chosen); /*!< negotiated protocol */ -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - /* - * use_srtp extension - */ - mbedtls_dtls_srtp_info MBEDTLS_PRIVATE(dtls_srtp_info); -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - - /* - * Information for DTLS hello verify - */ -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - unsigned char *MBEDTLS_PRIVATE(cli_id); /*!< transport-level ID of the client */ - size_t MBEDTLS_PRIVATE(cli_id_len); /*!< length of cli_id */ -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - - /* - * Secure renegotiation - */ - /* needed to know when to send extension on server */ - int MBEDTLS_PRIVATE(secure_renegotiation); /*!< does peer support legacy or - secure renegotiation */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - size_t MBEDTLS_PRIVATE(verify_data_len); /*!< length of verify data stored */ - char MBEDTLS_PRIVATE(own_verify_data)[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ - char MBEDTLS_PRIVATE(peer_verify_data)[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* CID configuration to use in subsequent handshakes. */ - - /*! The next incoming CID, chosen by the user and applying to - * all subsequent handshakes. This may be different from the - * CID currently used in case the user has re-configured the CID - * after an initial handshake. */ - unsigned char MBEDTLS_PRIVATE(own_cid)[MBEDTLS_SSL_CID_IN_LEN_MAX]; - uint8_t MBEDTLS_PRIVATE(own_cid_len); /*!< The length of \c own_cid. */ - uint8_t MBEDTLS_PRIVATE(negotiate_cid); /*!< This indicates whether the CID extension should - * be negotiated in the next handshake or not. - * Possible values are #MBEDTLS_SSL_CID_ENABLED - * and #MBEDTLS_SSL_CID_DISABLED. */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /** Callback to export key block and master secret */ - mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); - void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ - - /** User data pointer or handle. - * - * The library sets this to \p 0 when creating a context and does not - * access it afterwards. - * - * \warning Serializing and restoring an SSL context with - * mbedtls_ssl_context_save() and mbedtls_ssl_context_load() - * does not currently restore the user data. - */ - mbedtls_ssl_user_data_t MBEDTLS_PRIVATE(user_data); -}; - -/** - * \brief Return the name of the ciphersuite associated with the - * given ID - * - * \param ciphersuite_id SSL ciphersuite ID - * - * \return a string containing the ciphersuite name - */ -const char *mbedtls_ssl_get_ciphersuite_name(const int ciphersuite_id); - -/** - * \brief Return the ID of the ciphersuite associated with the - * given name - * - * \param ciphersuite_name SSL ciphersuite name - * - * \return the ID with the ciphersuite or 0 if not found - */ -int mbedtls_ssl_get_ciphersuite_id(const char *ciphersuite_name); - -/** - * \brief Initialize an SSL context - * Just makes the context ready for mbedtls_ssl_setup() or - * mbedtls_ssl_free() - * - * \param ssl SSL context - */ -void mbedtls_ssl_init(mbedtls_ssl_context *ssl); - -/** - * \brief Set up an SSL context for use - * - * \note No copy of the configuration context is made, it can be - * shared by many mbedtls_ssl_context structures. - * - * \warning The conf structure will be accessed during the session. - * It must not be modified or freed as long as the session - * is active. - * - * \warning This function must be called exactly once per context. - * Calling mbedtls_ssl_setup again is not supported, even - * if no session is active. - * - * \warning After setting up a client context, if certificate-based - * authentication is enabled, you should call - * mbedtls_ssl_set_hostname() to specifiy the expected - * name of the server. Without this, in most scenarios, - * the TLS connection is insecure. See - * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME - * for more information. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param ssl SSL context - * \param conf SSL configuration to use - * - * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED if - * memory allocation failed - */ -int mbedtls_ssl_setup(mbedtls_ssl_context *ssl, - const mbedtls_ssl_config *conf); - -/** - * \brief Reset an already initialized SSL context for re-use - * while retaining application-set variables, function - * pointers and data. - * - * \param ssl SSL context - * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED or - MBEDTLS_ERR_SSL_HW_ACCEL_FAILED - */ -int mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl); - -/** - * \brief Set the current endpoint type - * - * \param conf SSL configuration - * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER - */ -void mbedtls_ssl_conf_endpoint(mbedtls_ssl_config *conf, int endpoint); - -/** - * \brief Get the current endpoint type - * - * \param conf SSL configuration - * - * \return Endpoint type, either MBEDTLS_SSL_IS_CLIENT - * or MBEDTLS_SSL_IS_SERVER - */ -static inline int mbedtls_ssl_conf_get_endpoint(const mbedtls_ssl_config *conf) -{ - return conf->MBEDTLS_PRIVATE(endpoint); -} - -/** - * \brief Set the transport type (TLS or DTLS). - * Default: TLS - * - * \note For DTLS, you must either provide a recv callback that - * doesn't block, or one that handles timeouts, see - * \c mbedtls_ssl_set_bio(). You also need to provide timer - * callbacks with \c mbedtls_ssl_set_timer_cb(). - * - * \param conf SSL configuration - * \param transport transport type: - * MBEDTLS_SSL_TRANSPORT_STREAM for TLS, - * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS. - */ -void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport); - -/** - * \brief Set the certificate verification mode - * Default: NONE on server, REQUIRED on client - * - * \param conf SSL configuration - * \param authmode can be: - * - * MBEDTLS_SSL_VERIFY_NONE: peer certificate is not checked - * (default on server) - * (insecure on client) - * - * MBEDTLS_SSL_VERIFY_OPTIONAL: peer certificate is checked, however the - * handshake continues even if verification failed; - * mbedtls_ssl_get_verify_result() can be called after the - * handshake is complete. - * - * MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, - * handshake is aborted if verification failed. - * (default on client) - * - * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode. - * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at - * the right time(s), which may not be obvious, while REQUIRED always perform - * the verification as soon as possible. For example, REQUIRED was protecting - * against the "triple handshake" attack even before it was found. - */ -void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode); - -#if defined(MBEDTLS_SSL_EARLY_DATA) -/** - * \brief Set the early data mode - * Default: disabled on server and client - * - * \param conf The SSL configuration to use. - * \param early_data_enabled can be: - * - * MBEDTLS_SSL_EARLY_DATA_DISABLED: - * Early data functionality is disabled. This is the default on client and - * server. - * - * MBEDTLS_SSL_EARLY_DATA_ENABLED: - * Early data functionality is enabled and may be negotiated in the handshake. - * Application using early data functionality needs to be aware that the - * security properties for early data (also refered to as 0-RTT data) are - * weaker than those for other kinds of TLS data. See the documentation of - * mbedtls_ssl_write_early_data() and mbedtls_ssl_read_early_data() for more - * information. - * When early data functionality is enabled on server and only in that case, - * the call to one of the APIs that trigger or resume an handshake sequence, - * namely mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), - * mbedtls_ssl_read() or mbedtls_ssl_write() may return with the error code - * MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have - * been received. To read the early data, call mbedtls_ssl_read_early_data() - * before calling the original function again. - */ -void mbedtls_ssl_conf_early_data(mbedtls_ssl_config *conf, - int early_data_enabled); - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Set the maximum amount of 0-RTT data in bytes - * Default: #MBEDTLS_SSL_MAX_EARLY_DATA_SIZE - * - * This function sets the value of the max_early_data_size - * field of the early data indication extension included in - * the NewSessionTicket messages that the server may send. - * - * The value defines the maximum amount of 0-RTT data - * in bytes that a client will be allowed to send when using - * one of the tickets defined by the NewSessionTicket messages. - * - * \note When resuming a session using a ticket, if the server receives more - * early data than allowed for the ticket, it terminates the connection. - * The maximum amount of 0-RTT data should thus be large enough - * to allow a minimum of early data to be exchanged. - * - * \param[in] conf The SSL configuration to use. - * \param[in] max_early_data_size The maximum amount of 0-RTT data. - * - * \warning This interface DOES NOT influence/limit the amount of early data - * that can be received through previously created and issued tickets, - * which clients may have stored. - */ -void mbedtls_ssl_conf_max_early_data_size( - mbedtls_ssl_config *conf, uint32_t max_early_data_size); -#endif /* MBEDTLS_SSL_SRV_C */ - -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set the verification callback (Optional). - * - * If set, the provided verify callback is called for each - * certificate in the peer's CRT chain, including the trusted - * root. For more information, please see the documentation of - * \c mbedtls_x509_crt_verify(). - * - * \note For per context callbacks and contexts, please use - * mbedtls_ssl_set_verify() instead. - * - * \param conf The SSL configuration to use. - * \param f_vrfy The verification callback to use during CRT verification. - * \param p_vrfy The opaque context to be passed to the callback. - */ -void mbedtls_ssl_conf_verify(mbedtls_ssl_config *conf, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Set the random number generator callback - * - * \note The callback with its parameter must remain valid as - * long as there is an SSL context that uses the - * SSL configuration. - * - * \param conf SSL configuration - * \param f_rng RNG function (mandatory) - * \param p_rng RNG parameter - */ -void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Set the debug callback - * - * The callback has the following argument: - * void * opaque context for the callback - * int debug level - * const char * file name - * int line number - * const char * message - * - * \param conf SSL configuration - * \param f_dbg debug function - * \param p_dbg debug parameter - */ -void mbedtls_ssl_conf_dbg(mbedtls_ssl_config *conf, - void (*f_dbg)(void *, int, const char *, int, const char *), - void *p_dbg); - -/** - * \brief Return the SSL configuration structure associated - * with the given SSL context. - * - * \note The pointer returned by this function is guaranteed to - * remain valid until the context is freed. - * - * \param ssl The SSL context to query. - * \return Pointer to the SSL configuration associated with \p ssl. - */ -static inline const mbedtls_ssl_config *mbedtls_ssl_context_get_config( - const mbedtls_ssl_context *ssl) -{ - return ssl->MBEDTLS_PRIVATE(conf); -} - -/** - * \brief Set the underlying BIO callbacks for write, read and - * read-with-timeout. - * - * \param ssl SSL context - * \param p_bio parameter (context) shared by BIO callbacks - * \param f_send write callback - * \param f_recv read callback - * \param f_recv_timeout blocking read callback with timeout. - * - * \note One of f_recv or f_recv_timeout can be NULL, in which case - * the other is used. If both are non-NULL, f_recv_timeout is - * used and f_recv is ignored (as if it were NULL). - * - * \note The two most common use cases are: - * - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL - * - blocking I/O, f_recv == NULL, f_recv_timeout != NULL - * - * \note For DTLS, you need to provide either a non-NULL - * f_recv_timeout callback, or a f_recv that doesn't block. - * - * \note See the documentations of \c mbedtls_ssl_send_t, - * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for - * the conventions those callbacks must follow. - * - * \note On some platforms, net_sockets.c provides - * \c mbedtls_net_send(), \c mbedtls_net_recv() and - * \c mbedtls_net_recv_timeout() that are suitable to be used - * here. - */ -void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl, - void *p_bio, - mbedtls_ssl_send_t *f_send, - mbedtls_ssl_recv_t *f_recv, - mbedtls_ssl_recv_timeout_t *f_recv_timeout); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - - -/** - * \brief Configure the use of the Connection ID (CID) - * extension in the next handshake. - * - * Reference: RFC 9146 (or draft-ietf-tls-dtls-connection-id-05 - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 - * for legacy version) - * - * The DTLS CID extension allows the reliable association of - * DTLS records to DTLS connections across changes in the - * underlying transport (changed IP and Port metadata) by - * adding explicit connection identifiers (CIDs) to the - * headers of encrypted DTLS records. The desired CIDs are - * configured by the application layer and are exchanged in - * new `ClientHello` / `ServerHello` extensions during the - * handshake, where each side indicates the CID it wants the - * peer to use when writing encrypted messages. The CIDs are - * put to use once records get encrypted: the stack discards - * any incoming records that don't include the configured CID - * in their header, and adds the peer's requested CID to the - * headers of outgoing messages. - * - * This API enables or disables the use of the CID extension - * in the next handshake and sets the value of the CID to - * be used for incoming messages. - * - * \param ssl The SSL context to configure. This must be initialized. - * \param enable This value determines whether the CID extension should - * be used or not. Possible values are: - * - MBEDTLS_SSL_CID_ENABLED to enable the use of the CID. - * - MBEDTLS_SSL_CID_DISABLED (default) to disable the use - * of the CID. - * \param own_cid The address of the readable buffer holding the CID we want - * the peer to use when sending encrypted messages to us. - * This may be \c NULL if \p own_cid_len is \c 0. - * This parameter is unused if \p enable is set to - * MBEDTLS_SSL_CID_DISABLED. - * \param own_cid_len The length of \p own_cid. - * This parameter is unused if \p enable is set to - * MBEDTLS_SSL_CID_DISABLED. - * - * \note The value of \p own_cid_len must match the value of the - * \c len parameter passed to mbedtls_ssl_conf_cid() - * when configuring the ::mbedtls_ssl_config that \p ssl - * is bound to. - * - * \note This CID configuration applies to subsequent handshakes - * performed on the SSL context \p ssl, but does not trigger - * one. You still have to call `mbedtls_ssl_handshake()` - * (for the initial handshake) or `mbedtls_ssl_renegotiate()` - * (for a renegotiation handshake) explicitly after a - * successful call to this function to run the handshake. - * - * \note This call cannot guarantee that the use of the CID - * will be successfully negotiated in the next handshake, - * because the peer might not support it. Specifically: - * - On the Client, enabling the use of the CID through - * this call implies that the `ClientHello` in the next - * handshake will include the CID extension, thereby - * offering the use of the CID to the server. Only if - * the `ServerHello` contains the CID extension, too, - * the CID extension will actually be put to use. - * - On the Server, enabling the use of the CID through - * this call implies that the server will look for - * the CID extension in a `ClientHello` from the client, - * and, if present, reply with a CID extension in its - * `ServerHello`. - * - * \note To check whether the use of the CID was negotiated - * after the subsequent handshake has completed, please - * use the API mbedtls_ssl_get_peer_cid(). - * - * \warning If the use of the CID extension is enabled in this call - * and the subsequent handshake negotiates its use, Mbed TLS - * will silently drop every packet whose CID does not match - * the CID configured in \p own_cid. It is the responsibility - * of the user to adapt the underlying transport to take care - * of CID-based demultiplexing before handing datagrams to - * Mbed TLS. - * - * \return \c 0 on success. In this case, the CID configuration - * applies to the next handshake. - * \return A negative error code on failure. - */ -int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl, - int enable, - unsigned char const *own_cid, - size_t own_cid_len); - -/** - * \brief Get information about our request for usage of the CID - * extension in the current connection. - * - * \param ssl The SSL context to query. - * \param enabled The address at which to store whether the CID extension - * is requested to be used or not. If the CID is - * requested, `*enabled` is set to - * MBEDTLS_SSL_CID_ENABLED; otherwise, it is set to - * MBEDTLS_SSL_CID_DISABLED. - * \param own_cid The address of the buffer in which to store our own - * CID (if the CID extension is requested). This may be - * \c NULL in case the value of our CID isn't needed. If - * it is not \c NULL, \p own_cid_len must not be \c NULL. - * \param own_cid_len The address at which to store the size of our own CID - * (if the CID extension is requested). This is also the - * number of Bytes in \p own_cid that have been written. - * This may be \c NULL in case the length of our own CID - * isn't needed. If it is \c NULL, \p own_cid must be - * \c NULL, too. - * - *\note If we are requesting an empty CID this function sets - * `*enabled` to #MBEDTLS_SSL_CID_DISABLED (the rationale - * for this is that the resulting outcome is the - * same as if the CID extensions wasn't requested). - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_ssl_get_own_cid(mbedtls_ssl_context *ssl, - int *enabled, - unsigned char own_cid[MBEDTLS_SSL_CID_IN_LEN_MAX], - size_t *own_cid_len); - -/** - * \brief Get information about the use of the CID extension - * in the current connection. - * - * \param ssl The SSL context to query. - * \param enabled The address at which to store whether the CID extension - * is currently in use or not. If the CID is in use, - * `*enabled` is set to MBEDTLS_SSL_CID_ENABLED; - * otherwise, it is set to MBEDTLS_SSL_CID_DISABLED. - * \param peer_cid The address of the buffer in which to store the CID - * chosen by the peer (if the CID extension is used). - * This may be \c NULL in case the value of peer CID - * isn't needed. If it is not \c NULL, \p peer_cid_len - * must not be \c NULL. - * \param peer_cid_len The address at which to store the size of the CID - * chosen by the peer (if the CID extension is used). - * This is also the number of Bytes in \p peer_cid that - * have been written. - * This may be \c NULL in case the length of the peer CID - * isn't needed. If it is \c NULL, \p peer_cid must be - * \c NULL, too. - * - * \note This applies to the state of the CID negotiated in - * the last complete handshake. If a handshake is in - * progress, this function will attempt to complete - * the handshake first. - * - * \note If CID extensions have been exchanged but both client - * and server chose to use an empty CID, this function - * sets `*enabled` to #MBEDTLS_SSL_CID_DISABLED - * (the rationale for this is that the resulting - * communication is the same as if the CID extensions - * hadn't been used). - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_ssl_get_peer_cid(mbedtls_ssl_context *ssl, - int *enabled, - unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX], - size_t *peer_cid_len); - -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -/** - * \brief Set the Maximum Transport Unit (MTU). - * Special value: 0 means unset (no limit). - * This represents the maximum size of a datagram payload - * handled by the transport layer (usually UDP) as determined - * by the network link and stack. In practice, this controls - * the maximum size datagram the DTLS layer will pass to the - * \c f_send() callback set using \c mbedtls_ssl_set_bio(). - * - * \note The limit on datagram size is converted to a limit on - * record payload by subtracting the current overhead of - * encapsulation and encryption/authentication if any. - * - * \note This can be called at any point during the connection, for - * example when a Path Maximum Transfer Unit (PMTU) - * estimate becomes available from other sources, - * such as lower (or higher) protocol layers. - * - * \note This setting only controls the size of the packets we send, - * and does not restrict the size of the datagrams we're - * willing to receive. Client-side, you can request the - * server to use smaller records with \c - * mbedtls_ssl_conf_max_frag_len(). - * - * \note If both a MTU and a maximum fragment length have been - * configured (or negotiated with the peer), the resulting - * lower limit on record payload (see first note) is used. - * - * \note This can only be used to decrease the maximum size - * of datagrams (hence records, see first note) sent. It - * cannot be used to increase the maximum size of records over - * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. - * - * \note Values lower than the current record layer expansion will - * result in an error when trying to send data. - * - * \param ssl SSL context - * \param mtu Value of the path MTU in bytes - */ -void mbedtls_ssl_set_mtu(mbedtls_ssl_context *ssl, uint16_t mtu); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set a connection-specific verification callback (optional). - * - * If set, the provided verify callback is called for each - * certificate in the peer's CRT chain, including the trusted - * root. For more information, please see the documentation of - * \c mbedtls_x509_crt_verify(). - * - * \note This call is analogous to mbedtls_ssl_conf_verify() but - * binds the verification callback and context to an SSL context - * as opposed to an SSL configuration. - * If mbedtls_ssl_conf_verify() and mbedtls_ssl_set_verify() - * are both used, mbedtls_ssl_set_verify() takes precedence. - * - * \param ssl The SSL context to use. - * \param f_vrfy The verification callback to use during CRT verification. - * \param p_vrfy The opaque context to be passed to the callback. - */ -void mbedtls_ssl_set_verify(mbedtls_ssl_context *ssl, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Set the timeout period for mbedtls_ssl_read() - * (Default: no timeout.) - * - * \param conf SSL configuration context - * \param timeout Timeout value in milliseconds. - * Use 0 for no timeout (default). - * - * \note With blocking I/O, this will only work if a non-NULL - * \c f_recv_timeout was set with \c mbedtls_ssl_set_bio(). - * With non-blocking I/O, this will only work if timer - * callbacks were set with \c mbedtls_ssl_set_timer_cb(). - * - * \note With non-blocking I/O, you may also skip this function - * altogether and handle timeouts at the application layer. - */ -void mbedtls_ssl_conf_read_timeout(mbedtls_ssl_config *conf, uint32_t timeout); - -/** - * \brief Check whether a buffer contains a valid and authentic record - * that has not been seen before. (DTLS only). - * - * This function does not change the user-visible state - * of the SSL context. Its sole purpose is to provide - * an indication of the legitimacy of an incoming record. - * - * This can be useful e.g. in distributed server environments - * using the DTLS Connection ID feature, in which connections - * might need to be passed between service instances on a change - * of peer address, but where such disruptive operations should - * only happen after the validity of incoming records has been - * confirmed. - * - * \param ssl The SSL context to use. - * \param buf The address of the buffer holding the record to be checked. - * This must be a read/write buffer of length \p buflen Bytes. - * \param buflen The length of \p buf in Bytes. - * - * \note This routine only checks whether the provided buffer begins - * with a valid and authentic record that has not been seen - * before, but does not check potential data following the - * initial record. In particular, it is possible to pass DTLS - * datagrams containing multiple records, in which case only - * the first record is checked. - * - * \note This function modifies the input buffer \p buf. If you need - * to preserve the original record, you have to maintain a copy. - * - * \return \c 0 if the record is valid and authentic and has not been - * seen before. - * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed - * successfully but the record was found to be not authentic. - * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed - * successfully but the record was found to be invalid for - * a reason different from authenticity checking. - * \return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD if the check completed - * successfully but the record was found to be unexpected - * in the state of the SSL context, including replayed records. - * \return Another negative error code on different kinds of failure. - * In this case, the SSL context becomes unusable and needs - * to be freed or reset before reuse. - */ -int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t buflen); - -/** - * \brief Set the timer callbacks (Mandatory for DTLS.) - * - * \param ssl SSL context - * \param p_timer parameter (context) shared by timer callbacks - * \param f_set_timer set timer callback - * \param f_get_timer get timer callback. Must return: - * - * \note See the documentation of \c mbedtls_ssl_set_timer_t and - * \c mbedtls_ssl_get_timer_t for the conventions this pair of - * callbacks must follow. - * - * \note On some platforms, timing.c provides - * \c mbedtls_timing_set_delay() and - * \c mbedtls_timing_get_delay() that are suitable for using - * here, except if using an event-driven style. - * - * \note See also the "DTLS tutorial" article in our knowledge base. - * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/dtls-tutorial - */ -void mbedtls_ssl_set_timer_cb(mbedtls_ssl_context *ssl, - void *p_timer, - mbedtls_ssl_set_timer_t *f_set_timer, - mbedtls_ssl_get_timer_t *f_get_timer); - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Set the certificate selection callback (server-side only). - * - * If set, the callback is always called for each handshake, - * after `ClientHello` processing has finished. - * - * \param conf The SSL configuration to register the callback with. - * \param f_cert_cb The callback for selecting server certificate after - * `ClientHello` processing has finished. - */ -static inline void mbedtls_ssl_conf_cert_cb(mbedtls_ssl_config *conf, - mbedtls_ssl_hs_cb_t f_cert_cb) -{ - conf->MBEDTLS_PRIVATE(f_cert_cb) = f_cert_cb; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -/** - * \brief Callback type: generate and write session ticket - * - * \note This describes what a callback implementation should do. - * This callback should generate an encrypted and - * authenticated ticket for the session and write it to the - * output buffer. Here, ticket means the opaque ticket part - * of the NewSessionTicket structure of RFC 5077. - * - * \param p_ticket Context for the callback - * \param session SSL session to be written in the ticket - * \param start Start of the output buffer - * \param end End of the output buffer - * \param tlen On exit, holds the length written - * \param lifetime On exit, holds the lifetime of the ticket in seconds - * - * \return 0 if successful, or - * a specific MBEDTLS_ERR_XXX code. - */ -typedef int mbedtls_ssl_ticket_write_t(void *p_ticket, - const mbedtls_ssl_session *session, - unsigned char *start, - const unsigned char *end, - size_t *tlen, - uint32_t *lifetime); - -/** - * \brief Callback type: parse and load session ticket - * - * \note This describes what a callback implementation should do. - * This callback should parse a session ticket as generated - * by the corresponding mbedtls_ssl_ticket_write_t function, - * and, if the ticket is authentic and valid, load the - * session. - * - * \note The implementation is allowed to modify the first len - * bytes of the input buffer, eg to use it as a temporary - * area for the decrypted ticket contents. - * - * \param p_ticket Context for the callback - * \param session SSL session to be loaded - * \param buf Start of the buffer containing the ticket - * \param len Length of the ticket. - * - * \return 0 if successful, or - * MBEDTLS_ERR_SSL_INVALID_MAC if not authentic, or - * MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED if expired, or - * any other non-zero code for other failures. - */ -typedef int mbedtls_ssl_ticket_parse_t(void *p_ticket, - mbedtls_ssl_session *session, - unsigned char *buf, - size_t len); - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Configure SSL session ticket callbacks (server only). - * (Default: none.) - * - * \note On server, session tickets are enabled by providing - * non-NULL callbacks. - * - * \note On client, use \c mbedtls_ssl_conf_session_tickets(). - * - * \param conf SSL configuration context - * \param f_ticket_write Callback for writing a ticket - * \param f_ticket_parse Callback for parsing a ticket - * \param p_ticket Context shared by the two callbacks - */ -void mbedtls_ssl_conf_session_tickets_cb(mbedtls_ssl_config *conf, - mbedtls_ssl_ticket_write_t *f_ticket_write, - mbedtls_ssl_ticket_parse_t *f_ticket_parse, - void *p_ticket); - -#if defined(MBEDTLS_HAVE_TIME) -/** - * \brief Get the creation time of a session ticket. - * - * \note See the documentation of \c ticket_creation_time for information about - * the intended usage of this function. - * - * \param session SSL session - * \param ticket_creation_time On exit, holds the ticket creation time in - * milliseconds. - * - * \return 0 on success, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if an input is not valid. - */ -static inline int mbedtls_ssl_session_get_ticket_creation_time( - mbedtls_ssl_session *session, mbedtls_ms_time_t *ticket_creation_time) -{ - if (session == NULL || ticket_creation_time == NULL || - session->MBEDTLS_PRIVATE(endpoint) != MBEDTLS_SSL_IS_SERVER) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - *ticket_creation_time = session->MBEDTLS_PRIVATE(ticket_creation_time); - - return 0; -} -#endif /* MBEDTLS_HAVE_TIME */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ - -/** - * \brief Get the session-id buffer. - * - * \param session SSL session. - * - * \return The address of the session-id buffer. - */ -static inline unsigned const char (*mbedtls_ssl_session_get_id(const mbedtls_ssl_session * - session))[32] -{ - return &session->MBEDTLS_PRIVATE(id); -} - -/** - * \brief Get the size of the session-id. - * - * \param session SSL session. - * - * \return size_t size of session-id buffer. - */ -static inline size_t mbedtls_ssl_session_get_id_len(const mbedtls_ssl_session *session) -{ - return session->MBEDTLS_PRIVATE(id_len); -} - -/** - * \brief Get the ciphersuite-id. - * - * \param session SSL session. - * - * \return int represetation for ciphersuite. - */ -static inline int mbedtls_ssl_session_get_ciphersuite_id(const mbedtls_ssl_session *session) -{ - return session->MBEDTLS_PRIVATE(ciphersuite); -} - -/** - * \brief Configure a key export callback. - * (Default: none.) - * - * This API can be used for two purposes: - * - Debugging: Use this API to e.g. generate an NSSKeylog - * file and use it to inspect encrypted traffic in tools - * such as Wireshark. - * - Application-specific export: Use this API to implement - * key exporters, e.g. for EAP-TLS or DTLS-SRTP. - * - * - * \param ssl The SSL context to which the export - * callback should be attached. - * \param f_export_keys The callback for the key export. - * \param p_export_keys The opaque context pointer to be passed to the - * callback \p f_export_keys. - */ -void mbedtls_ssl_set_export_keys_cb(mbedtls_ssl_context *ssl, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys); - -/** \brief Set the user data in an SSL configuration to a pointer. - * - * You can retrieve this value later with mbedtls_ssl_conf_get_user_data_p(). - * - * \note The library stores \c p without accessing it. It is the responsibility - * of the caller to ensure that the pointer remains valid. - * - * \param conf The SSL configuration context to modify. - * \param p The new value of the user data. - */ -static inline void mbedtls_ssl_conf_set_user_data_p( - mbedtls_ssl_config *conf, - void *p) -{ - conf->MBEDTLS_PRIVATE(user_data).p = p; -} - -/** \brief Set the user data in an SSL configuration to an integer. - * - * You can retrieve this value later with mbedtls_ssl_conf_get_user_data_n(). - * - * \param conf The SSL configuration context to modify. - * \param n The new value of the user data. - */ -static inline void mbedtls_ssl_conf_set_user_data_n( - mbedtls_ssl_config *conf, - uintptr_t n) -{ - conf->MBEDTLS_PRIVATE(user_data).n = n; -} - -/** \brief Retrieve the user data in an SSL configuration as a pointer. - * - * This is the value last set with mbedtls_ssl_conf_set_user_data_p(), or - * \c NULL if mbedtls_ssl_conf_set_user_data_p() has not previously been - * called. The value is undefined if mbedtls_ssl_conf_set_user_data_n() has - * been called without a subsequent call to mbedtls_ssl_conf_set_user_data_p(). - * - * \param conf The SSL configuration context to modify. - * \return The current value of the user data. - */ -static inline void *mbedtls_ssl_conf_get_user_data_p( - mbedtls_ssl_config *conf) -{ - return conf->MBEDTLS_PRIVATE(user_data).p; -} - -/** \brief Retrieve the user data in an SSL configuration as an integer. - * - * This is the value last set with mbedtls_ssl_conf_set_user_data_n(), or - * \c 0 if mbedtls_ssl_conf_set_user_data_n() has not previously been - * called. The value is undefined if mbedtls_ssl_conf_set_user_data_p() has - * been called without a subsequent call to mbedtls_ssl_conf_set_user_data_n(). - * - * \param conf The SSL configuration context to modify. - * \return The current value of the user data. - */ -static inline uintptr_t mbedtls_ssl_conf_get_user_data_n( - mbedtls_ssl_config *conf) -{ - return conf->MBEDTLS_PRIVATE(user_data).n; -} - -/** \brief Set the user data in an SSL context to a pointer. - * - * You can retrieve this value later with mbedtls_ssl_get_user_data_p(). - * - * \note The library stores \c p without accessing it. It is the responsibility - * of the caller to ensure that the pointer remains valid. - * - * \param ssl The SSL context to modify. - * \param p The new value of the user data. - */ -static inline void mbedtls_ssl_set_user_data_p( - mbedtls_ssl_context *ssl, - void *p) -{ - ssl->MBEDTLS_PRIVATE(user_data).p = p; -} - -/** \brief Set the user data in an SSL context to an integer. - * - * You can retrieve this value later with mbedtls_ssl_get_user_data_n(). - * - * \param ssl The SSL context to modify. - * \param n The new value of the user data. - */ -static inline void mbedtls_ssl_set_user_data_n( - mbedtls_ssl_context *ssl, - uintptr_t n) -{ - ssl->MBEDTLS_PRIVATE(user_data).n = n; -} - -/** \brief Retrieve the user data in an SSL context as a pointer. - * - * This is the value last set with mbedtls_ssl_set_user_data_p(), or - * \c NULL if mbedtls_ssl_set_user_data_p() has not previously been - * called. The value is undefined if mbedtls_ssl_set_user_data_n() has - * been called without a subsequent call to mbedtls_ssl_set_user_data_p(). - * - * \param ssl The SSL context to modify. - * \return The current value of the user data. - */ -static inline void *mbedtls_ssl_get_user_data_p( - mbedtls_ssl_context *ssl) -{ - return ssl->MBEDTLS_PRIVATE(user_data).p; -} - -/** \brief Retrieve the user data in an SSL context as an integer. - * - * This is the value last set with mbedtls_ssl_set_user_data_n(), or - * \c 0 if mbedtls_ssl_set_user_data_n() has not previously been - * called. The value is undefined if mbedtls_ssl_set_user_data_p() has - * been called without a subsequent call to mbedtls_ssl_set_user_data_n(). - * - * \param ssl The SSL context to modify. - * \return The current value of the user data. - */ -static inline uintptr_t mbedtls_ssl_get_user_data_n( - mbedtls_ssl_context *ssl) -{ - return ssl->MBEDTLS_PRIVATE(user_data).n; -} - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -/** - * \brief Configure asynchronous private key operation callbacks. - * - * \param conf SSL configuration context - * \param f_async_sign Callback to start a signature operation. See - * the description of ::mbedtls_ssl_async_sign_t - * for more information. This may be \c NULL if the - * external processor does not support any signature - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_decrypt Callback to start a decryption operation. See - * the description of ::mbedtls_ssl_async_decrypt_t - * for more information. This may be \c NULL if the - * external processor does not support any decryption - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_resume Callback to resume an asynchronous operation. See - * the description of ::mbedtls_ssl_async_resume_t - * for more information. This may not be \c NULL unless - * \p f_async_sign and \p f_async_decrypt are both - * \c NULL. - * \param f_async_cancel Callback to cancel an asynchronous operation. See - * the description of ::mbedtls_ssl_async_cancel_t - * for more information. This may be \c NULL if - * no cleanup is needed. - * \param config_data A pointer to configuration data which can be - * retrieved with - * mbedtls_ssl_conf_get_async_config_data(). The - * library stores this value without dereferencing it. - */ -void mbedtls_ssl_conf_async_private_cb(mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *config_data); - -/** - * \brief Retrieve the configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - * - * \param conf SSL configuration context - * \return The configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - */ -void *mbedtls_ssl_conf_get_async_config_data(const mbedtls_ssl_config *conf); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * - * \return The asynchronous operation user context that was last - * set during the current handshake. If - * mbedtls_ssl_set_async_operation_data() has not yet been - * called during the current handshake, this function returns - * \c NULL. - */ -void *mbedtls_ssl_get_async_operation_data(const mbedtls_ssl_context *ssl); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * \param ctx The new value of the asynchronous operation user context. - * Call mbedtls_ssl_get_async_operation_data() later during the - * same handshake to retrieve this value. - */ -void mbedtls_ssl_set_async_operation_data(mbedtls_ssl_context *ssl, - void *ctx); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -/** - * \brief Callback type: generate a cookie - * - * \param ctx Context for the callback - * \param p Buffer to write to, - * must be updated to point right after the cookie - * \param end Pointer to one past the end of the output buffer - * \param info Client ID info that was passed to - * \c mbedtls_ssl_set_client_transport_id() - * \param ilen Length of info in bytes - * - * \return The callback must return 0 on success, - * or a negative error code. - */ -typedef int mbedtls_ssl_cookie_write_t(void *ctx, - unsigned char **p, unsigned char *end, - const unsigned char *info, size_t ilen); - -/** - * \brief Callback type: verify a cookie - * - * \param ctx Context for the callback - * \param cookie Cookie to verify - * \param clen Length of cookie - * \param info Client ID info that was passed to - * \c mbedtls_ssl_set_client_transport_id() - * \param ilen Length of info in bytes - * - * \return The callback must return 0 if cookie is valid, - * or a negative error code. - */ -typedef int mbedtls_ssl_cookie_check_t(void *ctx, - const unsigned char *cookie, size_t clen, - const unsigned char *info, size_t ilen); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Register callbacks for DTLS cookies - * (Server only. DTLS only.) - * - * Default: dummy callbacks that fail, in order to force you to - * register working callbacks (and initialize their context). - * - * To disable HelloVerifyRequest, register NULL callbacks. - * - * \warning Disabling hello verification allows your server to be used - * for amplification in DoS attacks against other hosts. - * Only disable if you known this can't happen in your - * particular environment. - * - * \note See comments on \c mbedtls_ssl_handshake() about handling - * the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected - * on the first handshake attempt when this is enabled. - * - * \note This is also necessary to handle client reconnection from - * the same port as described in RFC 6347 section 4.2.8 (only - * the variant with cookies is supported currently). See - * comments on \c mbedtls_ssl_read() for details. - * - * \param conf SSL configuration - * \param f_cookie_write Cookie write callback - * \param f_cookie_check Cookie check callback - * \param p_cookie Context for both callbacks - */ -void mbedtls_ssl_conf_dtls_cookies(mbedtls_ssl_config *conf, - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie); - -/** - * \brief Set client's transport-level identification info. - * (Server only. DTLS only.) - * - * This is usually the IP address (and port), but could be - * anything identify the client depending on the underlying - * network stack. Used for HelloVerifyRequest with DTLS. - * This is *not* used to route the actual packets. - * - * \param ssl SSL context - * \param info Transport-level info identifying the client (eg IP + port) - * \param ilen Length of info in bytes - * - * \note An internal copy is made, so the info buffer can be reused. - * - * \return 0 on success, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used on client, - * MBEDTLS_ERR_SSL_ALLOC_FAILED if out of memory. - */ -int mbedtls_ssl_set_client_transport_id(mbedtls_ssl_context *ssl, - const unsigned char *info, - size_t ilen); - -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -/** - * \brief Enable or disable anti-replay protection for DTLS. - * (DTLS only, no effect on TLS.) - * Default: enabled. - * - * \param conf SSL configuration - * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. - * - * \warning Disabling this is a security risk unless the application - * protocol handles duplicated packets in a safe way. You - * should not disable this without careful consideration. - * However, if your application already detects duplicated - * packets and needs information about them to adjust its - * transmission strategy, then you'll want to disable this. - */ -void mbedtls_ssl_conf_dtls_anti_replay(mbedtls_ssl_config *conf, char mode); -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -/** - * \brief Set a limit on the number of records with a bad MAC - * before terminating the connection. - * (DTLS only, no effect on TLS.) - * Default: 0 (disabled). - * - * \param conf SSL configuration - * \param limit Limit, or 0 to disable. - * - * \note If the limit is N, then the connection is terminated when - * the Nth non-authentic record is seen. - * - * \note Records with an invalid header are not counted, only the - * ones going through the authentication-decryption phase. - * - * \note This is a security trade-off related to the fact that it's - * often relatively easy for an active attacker to inject UDP - * datagrams. On one hand, setting a low limit here makes it - * easier for such an attacker to forcibly terminated a - * connection. On the other hand, a high limit or no limit - * might make us waste resources checking authentication on - * many bogus packets. - */ -void mbedtls_ssl_conf_dtls_badmac_limit(mbedtls_ssl_config *conf, unsigned limit); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -/** - * \brief Allow or disallow packing of multiple handshake records - * within a single datagram. - * - * \param ssl The SSL context to configure. - * \param allow_packing This determines whether datagram packing may - * be used or not. A value of \c 0 means that every - * record will be sent in a separate datagram; a - * value of \c 1 means that, if space permits, - * multiple handshake messages (including CCS) belonging to - * a single flight may be packed within a single datagram. - * - * \note This is enabled by default and should only be disabled - * for test purposes, or if datagram packing causes - * interoperability issues with peers that don't support it. - * - * \note Allowing datagram packing reduces the network load since - * there's less overhead if multiple messages share the same - * datagram. Also, it increases the handshake efficiency - * since messages belonging to a single datagram will not - * be reordered in transit, and so future message buffering - * or flight retransmission (if no buffering is used) as - * means to deal with reordering are needed less frequently. - * - * \note Application records are not affected by this option and - * are currently always sent in separate datagrams. - * - */ -void mbedtls_ssl_set_datagram_packing(mbedtls_ssl_context *ssl, - unsigned allow_packing); - -/** - * \brief Set retransmit timeout values for the DTLS handshake. - * (DTLS only, no effect on TLS.) - * - * \param conf SSL configuration - * \param min Initial timeout value in milliseconds. - * Default: 1000 (1 second). - * \param max Maximum timeout value in milliseconds. - * Default: 60000 (60 seconds). - * - * \note Default values are from RFC 6347 section 4.2.4.1. - * - * \note The 'min' value should typically be slightly above the - * expected round-trip time to your peer, plus whatever time - * it takes for the peer to process the message. For example, - * if your RTT is about 600ms and you peer needs up to 1s to - * do the cryptographic operations in the handshake, then you - * should set 'min' slightly above 1600. Lower values of 'min' - * might cause spurious resends which waste network resources, - * while larger value of 'min' will increase overall latency - * on unreliable network links. - * - * \note The more unreliable your network connection is, the larger - * your max / min ratio needs to be in order to achieve - * reliable handshakes. - * - * \note Messages are retransmitted up to log2(ceil(max/min)) times. - * For example, if min = 1s and max = 5s, the retransmit plan - * goes: send ... 1s -> resend ... 2s -> resend ... 4s -> - * resend ... 5s -> give up and return a timeout error. - */ -void mbedtls_ssl_conf_handshake_timeout(mbedtls_ssl_config *conf, uint32_t min, uint32_t max); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Set the session cache callbacks (server-side only) - * If not set, no session resuming is done (except if session - * tickets are enabled too). - * - * The session cache has the responsibility to check for stale - * entries based on timeout. See RFC 5246 for recommendations. - * - * Warning: session.peer_cert is cleared by the SSL/TLS layer on - * connection shutdown, so do not cache the pointer! Either set - * it to NULL or make a full copy of the certificate. - * - * The get callback is called once during the initial handshake - * to enable session resuming. The get function has the - * following parameters: (void *parameter, mbedtls_ssl_session *session) - * If a valid entry is found, it should fill the master of - * the session object with the cached values and return 0, - * return 1 otherwise. Optionally peer_cert can be set as well - * if it is properly present in cache entry. - * - * The set callback is called once during the initial handshake - * to enable session resuming after the entire handshake has - * been finished. The set function has the following parameters: - * (void *parameter, const mbedtls_ssl_session *session). The function - * should create a cache entry for future retrieval based on - * the data in the session structure and should keep in mind - * that the mbedtls_ssl_session object presented (and all its referenced - * data) is cleared by the SSL/TLS layer when the connection is - * terminated. It is recommended to add metadata to determine if - * an entry is still valid in the future. Return 0 if - * successfully cached, return 1 otherwise. - * - * \param conf SSL configuration - * \param p_cache parameter (context) for both callbacks - * \param f_get_cache session get callback - * \param f_set_cache session set callback - */ -void mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf, - void *p_cache, - mbedtls_ssl_cache_get_t *f_get_cache, - mbedtls_ssl_cache_set_t *f_set_cache); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Load a session for session resumption. - * - * Sessions loaded through this call will be considered - * for session resumption in the next handshake. - * - * \note Even if this call succeeds, it is not guaranteed that - * the next handshake will indeed be shortened through the - * use of session resumption: The server is always free - * to reject any attempt for resumption and fall back to - * a full handshake. - * - * \note This function can handle a variety of mechanisms for session - * resumption: For TLS 1.2, both session ID-based resumption - * and ticket-based resumption will be considered. For TLS 1.3, - * sessions equate to tickets, and loading one session by - * calling this function will lead to its corresponding ticket - * being advertised as resumption PSK by the client. This - * depends on session tickets being enabled (see - * #MBEDTLS_SSL_SESSION_TICKETS configuration option) though. - * If session tickets are disabled, a call to this function - * with a TLS 1.3 session, will not have any effect on the next - * handshake for the SSL context \p ssl. - * - * \param ssl The SSL context representing the connection which should - * be attempted to be setup using session resumption. This - * must be initialized via mbedtls_ssl_init() and bound to - * an SSL configuration via mbedtls_ssl_setup(), but - * the handshake must not yet have been started. - * \param session The session to be considered for session resumption. - * This must be a session previously exported via - * mbedtls_ssl_get_session(), and potentially serialized and - * deserialized through mbedtls_ssl_session_save() and - * mbedtls_ssl_session_load() in the meantime. - * - * \return \c 0 if successful. - * \return \c MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if the session - * could not be loaded because one session has already been - * loaded. This error is non-fatal, and has no observable - * effect on the SSL context or the session that was attempted - * to be loaded. - * \return Another negative error code on other kinds of failure. - * - * \sa mbedtls_ssl_get_session() - * \sa mbedtls_ssl_session_load() - */ -int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session); -#endif /* MBEDTLS_SSL_CLI_C */ - -/** - * \brief Load serialized session data into a session structure. - * On client, this can be used for loading saved sessions - * before resuming them with mbedtls_ssl_set_session(). - * On server, this can be used for alternative implementations - * of session cache or session tickets. - * - * \warning The serialized data contains highly sensitive material, - * including a resumption key (TLS 1.3) or the master secret - * (TLS 1.2) from which the session's traffic keys are derived. - * - * The serialized data is not cryptographically protected. - * It is the responsibility of the user of the - * mbedtls_ssl_session_save() and - * mbedtls_ssl_session_load() APIs to ensure both its - * confidentiality and integrity while stored or transported. - * - * A breach of confidentiality could result in full compromise - * of the associated TLS session, including loss of - * confidentiality and integrity of past and future - * application data protected under that session. - * - * A breach of integrity may allow modification of the - * serialized data prior to restoration. As it represents - * trusted internal context, tampering could potentially result - * in arbitrary code execution or other severe compromise of - * the hosting process. - * - * \warning If a peer certificate chain is associated with the session, - * the serialized state will only contain the peer's - * end-entity certificate and the result of the chain - * verification (unless verification was disabled), but not - * the rest of the chain. - * - * \see mbedtls_ssl_session_save() - * \see mbedtls_ssl_set_session() - * - * \param session The session structure to be populated. It must have been - * initialised with mbedtls_ssl_session_init() but not - * populated yet. - * \param buf The buffer holding the serialized session data. It must be a - * readable buffer of at least \p len bytes. - * \param len The size of the serialized data in bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. - * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data - * was generated in a different version or configuration of - * Mbed TLS. - * \return Another negative value for other kinds of errors (for - * example, unsupported features in the embedded certificate). - */ -int mbedtls_ssl_session_load(mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len); - -/** - * \brief Save session structure as serialized data in a buffer. - * On client, this can be used for saving session data, - * potentially in non-volatile storage, for resuming later. - * On server, this can be used for alternative implementations - * of session cache or session tickets. - * - * \see mbedtls_ssl_session_load() - * - * \warning The serialized data contains highly sensitive material, - * including a resumption key (TLS 1.3) or the master secret - * (TLS 1.2) from which the session's traffic keys are derived. - * - * The serialized data is not cryptographically protected. - * It is the responsibility of the user of the - * mbedtls_ssl_session_save() and - * mbedtls_ssl_session_load() APIs to ensure both its - * confidentiality and integrity while stored or transported. - * - * See the mbedtls_ssl_session_load() documentation for - * additional information. - * - * \param session The session structure to be saved. - * \param buf The buffer to write the serialized data to. It must be a - * writeable buffer of at least \p buf_len bytes, or may be \c - * NULL if \p buf_len is \c 0. - * \param buf_len The number of bytes available for writing in \p buf. - * \param olen The size in bytes of the data that has been or would have - * been written. It must point to a valid \c size_t. - * - * \note \p olen is updated to the correct value regardless of - * whether \p buf_len was large enough. This makes it possible - * to determine the necessary size by calling this function - * with \p buf set to \c NULL and \p buf_len to \c 0. - * - * \note For TLS 1.3 sessions, this feature is supported only if the - * MBEDTLS_SSL_SESSION_TICKETS configuration option is enabled, - * as in TLS 1.3 session resumption is possible only with - * tickets. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small. - * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if the - * MBEDTLS_SSL_SESSION_TICKETS configuration option is disabled - * and the session is a TLS 1.3 session. - */ -int mbedtls_ssl_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen); - -/** - * \brief Set the list of allowed ciphersuites and the preference - * order. First in the list has the highest preference. - * - * For TLS 1.2, the notion of ciphersuite determines both - * the key exchange mechanism and the suite of symmetric - * algorithms to be used during and after the handshake. - * - * For TLS 1.3 (in development), the notion of ciphersuite - * only determines the suite of symmetric algorithms to be - * used during and after the handshake, while key exchange - * mechanisms are configured separately. - * - * In Mbed TLS, ciphersuites for both TLS 1.2 and TLS 1.3 - * are configured via this function. For users of TLS 1.3, - * there will be separate API for the configuration of key - * exchange mechanisms. - * - * The list of ciphersuites passed to this function may - * contain a mixture of TLS 1.2 and TLS 1.3 ciphersuite - * identifiers. This is useful if negotiation of TLS 1.3 - * should be attempted, but a fallback to TLS 1.2 would - * be tolerated. - * - * \note By default, the server chooses its preferred - * ciphersuite among those that the client supports. If - * mbedtls_ssl_conf_preference_order() is called to prefer - * the client's preferences, the server instead chooses - * the client's preferred ciphersuite among those that - * the server supports. - * - * \warning The ciphersuites array \p ciphersuites is not copied. - * It must remain valid for the lifetime of the SSL - * configuration \p conf. - * - * \param conf The SSL configuration to modify. - * \param ciphersuites A 0-terminated list of IANA identifiers of supported - * ciphersuites, accessible through \c MBEDTLS_TLS_XXX - * and \c MBEDTLS_TLS1_3_XXX macros defined in - * ssl_ciphersuites.h. - */ -void mbedtls_ssl_conf_ciphersuites(mbedtls_ssl_config *conf, - const int *ciphersuites); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -/** - * \brief Set the supported key exchange modes for TLS 1.3 connections. - * - * In contrast to TLS 1.2, the ciphersuite concept in TLS 1.3 does not - * include the choice of key exchange mechanism. It is therefore not - * covered by the API mbedtls_ssl_conf_ciphersuites(). See the - * documentation of mbedtls_ssl_conf_ciphersuites() for more - * information on the ciphersuite concept in TLS 1.2 and TLS 1.3. - * - * The present function is specific to TLS 1.3 and allows users to - * configure the set of supported key exchange mechanisms in TLS 1.3. - * - * \param conf The SSL configuration the change should apply to. - * \param kex_modes A bitwise combination of one or more of the following: - * - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK - * This flag enables pure-PSK key exchanges. - * - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL - * This flag enables combined PSK-ephemeral key exchanges. - * - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL - * This flag enables pure-ephemeral key exchanges. - * For convenience, the following pre-defined macros are - * available for combinations of the above: - * - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL - * Includes all of pure-PSK, PSK-ephemeral and pure-ephemeral. - * - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL - * Includes both pure-PSK and combined PSK-ephemeral - * key exchanges, but excludes pure-ephemeral key exchanges. - * - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL - * Includes both pure-ephemeral and combined PSK-ephemeral - * key exchanges. - * - * \note If a PSK-based key exchange mode shall be supported, applications - * must also use the APIs mbedtls_ssl_conf_psk() or - * mbedtls_ssl_conf_psk_cb() or mbedtls_ssl_conf_psk_opaque() - * to configure the PSKs to be used. - * - * \note If a pure-ephemeral key exchange mode shall be supported, - * server-side applications must also provide a certificate via - * mbedtls_ssl_conf_own_cert(). - * - */ - -void mbedtls_ssl_conf_tls13_key_exchange_modes(mbedtls_ssl_config *conf, - const int kex_modes); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0 -#define MBEDTLS_SSL_UNEXPECTED_CID_FAIL 1 -/** - * \brief Specify the length of Connection IDs for incoming - * encrypted DTLS records, as well as the behaviour - * on unexpected CIDs. - * - * By default, the CID length is set to \c 0, - * and unexpected CIDs are silently ignored. - * - * \param conf The SSL configuration to modify. - * \param len The length in Bytes of the CID fields in encrypted - * DTLS records using the CID mechanism. This must - * not be larger than #MBEDTLS_SSL_CID_OUT_LEN_MAX. - * \param ignore_other_cids This determines the stack's behaviour when - * receiving a record with an unexpected CID. - * Possible values are: - * - #MBEDTLS_SSL_UNEXPECTED_CID_IGNORE - * In this case, the record is silently ignored. - * - #MBEDTLS_SSL_UNEXPECTED_CID_FAIL - * In this case, the stack fails with the specific - * error code #MBEDTLS_ERR_SSL_UNEXPECTED_CID. - * - * \note The CID specification allows implementations to either - * use a common length for all incoming connection IDs or - * allow variable-length incoming IDs. Mbed TLS currently - * requires a common length for all connections sharing the - * same SSL configuration; this allows simpler parsing of - * record headers. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p len - * is too large. - */ -int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf, size_t len, - int ignore_other_cids); -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set the X.509 security profile used for verification - * - * \note The restrictions are enforced for all certificates in the - * chain. However, signatures in the handshake are not covered - * by this setting but by \b mbedtls_ssl_conf_sig_hashes(). - * - * \param conf SSL configuration - * \param profile Profile to use - */ -void mbedtls_ssl_conf_cert_profile(mbedtls_ssl_config *conf, - const mbedtls_x509_crt_profile *profile); - -/** - * \brief Set the data required to verify peer certificate - * - * \note See \c mbedtls_x509_crt_verify() for notes regarding the - * parameters ca_chain (maps to trust_ca for that function) - * and ca_crl. - * - * \param conf SSL configuration - * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) - * \param ca_crl trusted CA CRLs - */ -void mbedtls_ssl_conf_ca_chain(mbedtls_ssl_config *conf, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl); - -#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -/** - * \brief Set DN hints sent to client in CertificateRequest message - * - * \note If not set, subject distinguished names (DNs) are taken - * from \c mbedtls_ssl_conf_ca_chain() - * or \c mbedtls_ssl_set_hs_ca_chain()) - * - * \param conf SSL configuration - * \param crt crt chain whose subject DNs are issuer DNs of client certs - * from which the client should select client peer certificate. - */ -static inline -void mbedtls_ssl_conf_dn_hints(mbedtls_ssl_config *conf, - const mbedtls_x509_crt *crt) -{ - conf->MBEDTLS_PRIVATE(dn_hints) = crt; -} -#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -/** - * \brief Set the trusted certificate callback. - * - * This API allows to register the set of trusted certificates - * through a callback, instead of a linked list as configured - * by mbedtls_ssl_conf_ca_chain(). - * - * This is useful for example in contexts where a large number - * of CAs are used, and the inefficiency of maintaining them - * in a linked list cannot be tolerated. It is also useful when - * the set of trusted CAs needs to be modified frequently. - * - * See the documentation of `mbedtls_x509_crt_ca_cb_t` for - * more information. - * - * \param conf The SSL configuration to register the callback with. - * \param f_ca_cb The trusted certificate callback to use when verifying - * certificate chains. - * \param p_ca_cb The context to be passed to \p f_ca_cb (for example, - * a reference to a trusted CA database). - * - * \note This API is incompatible with mbedtls_ssl_conf_ca_chain(): - * Any call to this function overwrites the values set through - * earlier calls to mbedtls_ssl_conf_ca_chain() or - * mbedtls_ssl_conf_ca_cb(). - * - * \note This API is incompatible with CA indication in - * CertificateRequest messages: A server-side SSL context which - * is bound to an SSL configuration that uses a CA callback - * configured via mbedtls_ssl_conf_ca_cb(), and which requires - * client authentication, will send an empty CA list in the - * corresponding CertificateRequest message. - * - * \note This API is incompatible with mbedtls_ssl_set_hs_ca_chain(): - * If an SSL context is bound to an SSL configuration which uses - * CA callbacks configured via mbedtls_ssl_conf_ca_cb(), then - * calls to mbedtls_ssl_set_hs_ca_chain() have no effect. - * - * \note The use of this API disables the use of restartable ECC - * during X.509 CRT signature verification (but doesn't affect - * other uses). - * - * \warning This API is incompatible with the use of CRLs. Any call to - * mbedtls_ssl_conf_ca_cb() unsets CRLs configured through - * earlier calls to mbedtls_ssl_conf_ca_chain(). - * - * \warning In multi-threaded environments, the callback \p f_ca_cb - * must be thread-safe, and it is the user's responsibility - * to guarantee this (for example through a mutex - * contained in the callback context pointed to by \p p_ca_cb). - */ -void mbedtls_ssl_conf_ca_cb(mbedtls_ssl_config *conf, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb); -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -/** - * \brief Set own certificate chain and private key - * - * \note own_cert should contain in order from the bottom up your - * certificate chain. The top certificate (self-signed) - * can be omitted. - * - * \note On server, this function can be called multiple times to - * provision more than one cert/key pair (eg one ECDSA, one - * RSA with SHA-256, one RSA with SHA-1). An adequate - * certificate will be selected according to the client's - * advertised capabilities. In case multiple certificates are - * adequate, preference is given to the one set by the first - * call to this function, then second, etc. - * - * \note On client, only the first call has any effect. That is, - * only one client certificate can be provisioned. The - * server's preferences in its CertificateRequest message will - * be ignored and our only cert will be sent regardless of - * whether it matches those preferences - the server can then - * decide what it wants to do with it. - * - * \note The provided \p pk_key needs to match the public key in the - * first certificate in \p own_cert, or all handshakes using - * that certificate will fail. It is your responsibility - * to ensure that; this function will not perform any check. - * You may use mbedtls_pk_check_pair() in order to perform - * this check yourself, but be aware that this function can - * be computationally expensive on some key types. - * - * \param conf SSL configuration - * \param own_cert own public certificate chain - * \param pk_key own private key - * - * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_conf_own_cert(mbedtls_ssl_config *conf, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -/** - * \brief Configure pre-shared keys (PSKs) and their - * identities to be used in PSK-based ciphersuites. - * - * Only one PSK can be registered, through either - * mbedtls_ssl_conf_psk() or mbedtls_ssl_conf_psk_opaque(). - * If you attempt to register more than one PSK, this function - * fails, though this may change in future versions, which - * may add support for multiple PSKs. - * - * \note This is mainly useful for clients. Servers will usually - * want to use \c mbedtls_ssl_conf_psk_cb() instead. - * - * \note A PSK set by \c mbedtls_ssl_set_hs_psk() in the PSK callback - * takes precedence over a PSK configured by this function. - * - * \param conf The SSL configuration to register the PSK with. - * \param psk The pointer to the pre-shared key to use. - * \param psk_len The length of the pre-shared key in bytes. - * \param psk_identity The pointer to the pre-shared key identity. - * \param psk_identity_len The length of the pre-shared key identity - * in bytes. - * - * \note The PSK and its identity are copied internally and - * hence need not be preserved by the caller for the lifetime - * of the SSL configuration. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if no more PSKs - * can be configured. In this case, the old PSK(s) remain intact. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ssl_conf_psk(mbedtls_ssl_config *conf, - const unsigned char *psk, size_t psk_len, - const unsigned char *psk_identity, size_t psk_identity_len); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * \brief Configure one or more opaque pre-shared keys (PSKs) and - * their identities to be used in PSK-based ciphersuites. - * - * Only one PSK can be registered, through either - * mbedtls_ssl_conf_psk() or mbedtls_ssl_conf_psk_opaque(). - * If you attempt to register more than one PSK, this function - * fails, though this may change in future versions, which - * may add support for multiple PSKs. - * - * \note This is mainly useful for clients. Servers will usually - * want to use \c mbedtls_ssl_conf_psk_cb() instead. - * - * \note An opaque PSK set by \c mbedtls_ssl_set_hs_psk_opaque() in - * the PSK callback takes precedence over an opaque PSK - * configured by this function. - * - * \param conf The SSL configuration to register the PSK with. - * \param psk The identifier of the key slot holding the PSK. - * Until \p conf is destroyed or this function is successfully - * called again, the key slot \p psk must be populated with a - * key of type PSA_ALG_CATEGORY_KEY_DERIVATION whose policy - * allows its use for the key derivation algorithm applied - * in the handshake. - * \param psk_identity The pointer to the pre-shared key identity. - * \param psk_identity_len The length of the pre-shared key identity - * in bytes. - * - * \note The PSK identity hint is copied internally and hence need - * not be preserved by the caller for the lifetime of the - * SSL configuration. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if no more PSKs - * can be configured. In this case, the old PSK(s) remain intact. - * \return Another negative error code on other kinds of failure. - */ -int mbedtls_ssl_conf_psk_opaque(mbedtls_ssl_config *conf, - mbedtls_svc_key_id_t psk, - const unsigned char *psk_identity, - size_t psk_identity_len); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/** - * \brief Set the pre-shared Key (PSK) for the current handshake. - * - * \note This should only be called inside the PSK callback, - * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb(). - * - * \note A PSK set by this function takes precedence over a PSK - * configured by \c mbedtls_ssl_conf_psk(). - * - * \param ssl The SSL context to configure a PSK for. - * \param psk The pointer to the pre-shared key. - * \param psk_len The length of the pre-shared key in bytes. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. - */ -int mbedtls_ssl_set_hs_psk(mbedtls_ssl_context *ssl, - const unsigned char *psk, size_t psk_len); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * \brief Set an opaque pre-shared Key (PSK) for the current handshake. - * - * \note This should only be called inside the PSK callback, - * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb(). - * - * \note An opaque PSK set by this function takes precedence over an - * opaque PSK configured by \c mbedtls_ssl_conf_psk_opaque(). - * - * \param ssl The SSL context to configure a PSK for. - * \param psk The identifier of the key slot holding the PSK. - * For the duration of the current handshake, the key slot - * must be populated with a key of type - * PSA_ALG_CATEGORY_KEY_DERIVATION whose policy allows its - * use for the key derivation algorithm - * applied in the handshake. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. - */ -int mbedtls_ssl_set_hs_psk_opaque(mbedtls_ssl_context *ssl, - mbedtls_svc_key_id_t psk); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Set the PSK callback (server-side only). - * - * If set, the PSK callback is called for each - * handshake where a PSK-based ciphersuite was negotiated. - * The caller provides the identity received and wants to - * receive the actual PSK data and length. - * - * The callback has the following parameters: - * - \c void*: The opaque pointer \p p_psk. - * - \c mbedtls_ssl_context*: The SSL context to which - * the operation applies. - * - \c const unsigned char*: The PSK identity - * selected by the client. - * - \c size_t: The length of the PSK identity - * selected by the client. - * - * If a valid PSK identity is found, the callback should use - * \c mbedtls_ssl_set_hs_psk() or - * \c mbedtls_ssl_set_hs_psk_opaque() - * on the SSL context to set the correct PSK and return \c 0. - * Any other return value will result in a denied PSK identity. - * - * \note A dynamic PSK (i.e. set by the PSK callback) takes - * precedence over a static PSK (i.e. set by - * \c mbedtls_ssl_conf_psk() or - * \c mbedtls_ssl_conf_psk_opaque()). - * This means that if you set a PSK callback using this - * function, you don't need to set a PSK using - * \c mbedtls_ssl_conf_psk() or - * \c mbedtls_ssl_conf_psk_opaque()). - * - * \param conf The SSL configuration to register the callback with. - * \param f_psk The callback for selecting and setting the PSK based - * in the PSK identity chosen by the client. - * \param p_psk A pointer to an opaque structure to be passed to - * the callback, for example a PSK store. - */ -void mbedtls_ssl_conf_psk_cb(mbedtls_ssl_config *conf, - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_psk); -#endif /* MBEDTLS_SSL_SRV_C */ -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Set the Diffie-Hellman public P and G values - * from big-endian binary presentations. - * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN) - * - * \param conf SSL configuration - * \param dhm_P Diffie-Hellman-Merkle modulus in big-endian binary form - * \param P_len Length of DHM modulus - * \param dhm_G Diffie-Hellman-Merkle generator in big-endian binary form - * \param G_len Length of DHM generator - * - * \return 0 if successful - */ -int mbedtls_ssl_conf_dh_param_bin(mbedtls_ssl_config *conf, - const unsigned char *dhm_P, size_t P_len, - const unsigned char *dhm_G, size_t G_len); - -/** - * \brief Set the Diffie-Hellman public P and G values, - * read from existing context (server-side only) - * - * \param conf SSL configuration - * \param dhm_ctx Diffie-Hellman-Merkle context - * - * \return 0 if successful - */ -int mbedtls_ssl_conf_dh_param_ctx(mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx); -#endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Set the minimum length for Diffie-Hellman parameters. - * (Client-side only.) - * (Default: 1024 bits.) - * - * \param conf SSL configuration - * \param bitlen Minimum bit length of the DHM prime - */ -void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf, - unsigned int bitlen); -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief Set the allowed curves in order of preference. - * - * On server: this only affects selection of the ECDHE curve; - * the curves used for ECDH and ECDSA are determined by the - * list of available certificates instead. - * - * On client: this affects the list of curves offered for any - * use. The server can override our preference order. - * - * Both sides: limits the set of curves accepted for use in - * ECDHE and in the peer's end-entity certificate. - * - * \deprecated Superseded by mbedtls_ssl_conf_groups(). - * - * \note This has no influence on which curves are allowed inside the - * certificate chains, see \c mbedtls_ssl_conf_cert_profile() - * for that. For the end-entity certificate however, the key - * will be accepted only if it is allowed both by this list - * and by the cert profile. - * - * \note This list should be ordered by decreasing preference - * (preferred curve first). - * - * \note The default list is the same set of curves that - * #mbedtls_x509_crt_profile_default allows, plus - * ECDHE-only curves selected according to the same criteria. - * The order favors curves with the lowest resource usage. - * - * \note New minor versions of Mbed TLS may extend this list, - * for example if new curves are added to the library. - * New minor versions of Mbed TLS will not remove items - * from this list unless serious security concerns require it. - * New minor versions of Mbed TLS may change the order in - * keeping with the general principle of favoring the lowest - * resource usage. - * - * \param conf SSL configuration - * \param curves Ordered list of allowed curves, - * terminated by MBEDTLS_ECP_DP_NONE. - */ -void MBEDTLS_DEPRECATED mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf, - const mbedtls_ecp_group_id *curves); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_ECP_C */ - -/** - * \brief Set the allowed groups in order of preference. - * - * On server: This only affects the choice of key agreement mechanism - * - * On client: this affects the list of groups offered for any - * use. The server can override our preference order. - * - * Both sides: limits the set of groups accepted for use in - * key sharing. - * - * \note This function replaces the deprecated mbedtls_ssl_conf_curves(), - * which only allows ECP curves to be configured. - * - * \note The most recent invocation of either mbedtls_ssl_conf_curves() - * or mbedtls_ssl_conf_groups() nullifies all previous invocations - * of both. - * - * \note This list should be ordered by decreasing preference - * (preferred group first). - * - * \note When this function is not called, a default list is used, - * consisting of all supported curves at 255 bits and above, - * and all supported finite fields at 2048 bits and above. - * The order favors groups with the lowest resource usage. - * - * \note New minor versions of Mbed TLS will not remove items - * from the default list unless serious security concerns require it. - * New minor versions of Mbed TLS may change the order in - * keeping with the general principle of favoring the lowest - * resource usage. - * - * \param conf SSL configuration - * \param groups List of allowed groups ordered by preference, terminated by 0. - * Must contain valid IANA NamedGroup IDs (provided via either an integer - * or using MBEDTLS_TLS1_3_NAMED_GROUP_XXX macros). - */ -void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf, - const uint16_t *groups); - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SSL_PROTO_TLS1_2) -/** - * \brief Set the allowed hashes for signatures during the handshake. - * - * \note This only affects which hashes are offered and can be used - * for signatures during the handshake. Hashes for message - * authentication and the TLS PRF are controlled by the - * ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes - * used for certificate signature are controlled by the - * verification profile, see \c mbedtls_ssl_conf_cert_profile(). - * - * \deprecated Superseded by mbedtls_ssl_conf_sig_algs(). - * - * \note This list should be ordered by decreasing preference - * (preferred hash first). - * - * \note By default, all supported hashes whose length is at least - * 256 bits are allowed. This is the same set as the default - * for certificate verification - * (#mbedtls_x509_crt_profile_default). - * The preference order is currently unspecified and may - * change in future versions. - * - * \note New minor versions of Mbed TLS may extend this list, - * for example if new curves are added to the library. - * New minor versions of Mbed TLS will not remove items - * from this list unless serious security concerns require it. - * - * \param conf SSL configuration - * \param hashes Ordered list of allowed signature hashes, - * terminated by \c MBEDTLS_MD_NONE. - */ -void MBEDTLS_DEPRECATED mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf, - const int *hashes); -#endif /* !MBEDTLS_DEPRECATED_REMOVED && MBEDTLS_SSL_PROTO_TLS1_2 */ - -/** - * \brief Configure allowed signature algorithms for use in TLS - * - * \param conf The SSL configuration to use. - * \param sig_algs List of allowed IANA values for TLS 1.3 signature algorithms, - * terminated by #MBEDTLS_TLS1_3_SIG_NONE. The list must remain - * available throughout the lifetime of the conf object. - * - For TLS 1.3, values of \c MBEDTLS_TLS1_3_SIG_XXXX should be - * used. - * - For TLS 1.2, values should be given as - * "(HashAlgorithm << 8) | SignatureAlgorithm". - */ -void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf, - const uint16_t *sig_algs); -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set or reset the hostname to check against the received - * peer certificate. On a client, this also sets the - * ServerName TLS extension, if that extension is enabled. - * On a TLS 1.3 client, this also sets the server name in - * the session resumption ticket, if that feature is enabled. - * - * \param ssl SSL context - * \param hostname The server hostname. This may be \c NULL to clear - * the hostname. - * - * \note Maximum hostname length #MBEDTLS_SSL_MAX_HOST_NAME_LEN. - * - * \note If the hostname is \c NULL on a client, then the server - * is not authenticated: it only needs to have a valid - * certificate, not a certificate matching its name. - * Therefore you should always call this function on a client, - * unless the connection is set up to only allow - * pre-shared keys, or in scenarios where server - * impersonation is not a concern. See the documentation of - * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME - * for more details. - * - * \return 0 if successful, #MBEDTLS_ERR_SSL_ALLOC_FAILED on - * allocation failure, #MBEDTLS_ERR_SSL_BAD_INPUT_DATA on - * too long input hostname. - * - * Hostname set to the one provided on success (cleared - * when NULL). On allocation failure hostname is cleared. - * On too long input failure, old hostname is unchanged. - */ -int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname); - -/** - * \brief Get the hostname that checked against the received - * server certificate. It is used to set the ServerName - * TLS extension, too, if that extension is enabled. - * (client-side only) - * - * \param ssl SSL context - * - * \return const pointer to the hostname value - */ -static inline const char *mbedtls_ssl_get_hostname(mbedtls_ssl_context *ssl) -{ - return ssl->MBEDTLS_PRIVATE(hostname); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -/** - * \brief Retrieve SNI extension value for the current handshake. - * Available in \c f_cert_cb of \c mbedtls_ssl_conf_cert_cb(), - * this is the same value passed to \c f_sni callback of - * \c mbedtls_ssl_conf_sni() and may be used instead of - * \c mbedtls_ssl_conf_sni(). - * - * \param ssl SSL context - * \param name_len pointer into which to store length of returned value. - * 0 if SNI extension is not present or not yet processed. - * - * \return const pointer to SNI extension value. - * - value is valid only when called in \c f_cert_cb - * registered with \c mbedtls_ssl_conf_cert_cb(). - * - value is NULL if SNI extension is not present. - * - value is not '\0'-terminated. Use \c name_len for len. - * - value must not be freed. - */ -const unsigned char *mbedtls_ssl_get_hs_sni(mbedtls_ssl_context *ssl, - size_t *name_len); - -/** - * \brief Set own certificate and key for the current handshake - * - * \note Same as \c mbedtls_ssl_conf_own_cert() but for use within - * the SNI callback or the certificate selection callback. - * - * \note Passing null \c own_cert clears the certificate list for - * the current handshake. - * - * \param ssl SSL context - * \param own_cert own public certificate chain - * \param pk_key own private key - * - * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_set_hs_own_cert(mbedtls_ssl_context *ssl, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key); - -/** - * \brief Set the data required to verify peer certificate for the - * current handshake - * - * \note Same as \c mbedtls_ssl_conf_ca_chain() but for use within - * the SNI callback or the certificate selection callback. - * - * \param ssl SSL context - * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) - * \param ca_crl trusted CA CRLs - */ -void mbedtls_ssl_set_hs_ca_chain(mbedtls_ssl_context *ssl, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl); - -#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -/** - * \brief Set DN hints sent to client in CertificateRequest message - * - * \note Same as \c mbedtls_ssl_conf_dn_hints() but for use within - * the SNI callback or the certificate selection callback. - * - * \param ssl SSL context - * \param crt crt chain whose subject DNs are issuer DNs of client certs - * from which the client should select client peer certificate. - */ -void mbedtls_ssl_set_hs_dn_hints(mbedtls_ssl_context *ssl, - const mbedtls_x509_crt *crt); -#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ - -/** - * \brief Set authmode for the current handshake. - * - * \note Same as \c mbedtls_ssl_conf_authmode() but for use within - * the SNI callback or the certificate selection callback. - * - * \param ssl SSL context - * \param authmode MBEDTLS_SSL_VERIFY_NONE, MBEDTLS_SSL_VERIFY_OPTIONAL or - * MBEDTLS_SSL_VERIFY_REQUIRED - */ -void mbedtls_ssl_set_hs_authmode(mbedtls_ssl_context *ssl, - int authmode); - -/** - * \brief Set server side ServerName TLS extension callback - * (optional, server-side only). - * - * If set, the ServerName callback is called whenever the - * server receives a ServerName TLS extension from the client - * during a handshake. The ServerName callback has the - * following parameters: (void *parameter, mbedtls_ssl_context *ssl, - * const unsigned char *hostname, size_t len). If a suitable - * certificate is found, the callback must set the - * certificate(s) and key(s) to use with \c - * mbedtls_ssl_set_hs_own_cert() (can be called repeatedly), - * and may optionally adjust the CA and associated CRL with \c - * mbedtls_ssl_set_hs_ca_chain() as well as the client - * authentication mode with \c mbedtls_ssl_set_hs_authmode(), - * then must return 0. If no matching name is found, the - * callback may return non-zero to abort the handshake. - * - * \param conf SSL configuration - * \param f_sni verification function - * \param p_sni verification parameter - */ -void mbedtls_ssl_conf_sni(mbedtls_ssl_config *conf, - int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_sni); -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -/** - * \brief Set the EC J-PAKE password for current handshake. - * - * \note An internal copy is made, and destroyed as soon as the - * handshake is completed, or when the SSL context is reset or - * freed. - * - * \note The SSL context needs to be already set up. The right place - * to call this function is between \c mbedtls_ssl_setup() or - * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake(). - * Password cannot be empty (see RFC 8236). - * - * \param ssl SSL context - * \param pw EC J-PAKE password (pre-shared secret). It cannot be empty - * \param pw_len length of pw in bytes - * - * \return 0 on success, or a negative error code. - */ -int mbedtls_ssl_set_hs_ecjpake_password(mbedtls_ssl_context *ssl, - const unsigned char *pw, - size_t pw_len); - -/** - * \brief Set the EC J-PAKE opaque password for current handshake. - * - * \note The key must remain valid until the handshake is over. - * - * \note The SSL context needs to be already set up. The right place - * to call this function is between \c mbedtls_ssl_setup() or - * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake(). - * - * \param ssl SSL context - * \param pwd EC J-PAKE opaque password - * - * \return 0 on success, or a negative error code. - */ -int mbedtls_ssl_set_hs_ecjpake_password_opaque(mbedtls_ssl_context *ssl, - mbedtls_svc_key_id_t pwd); -#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) -/** - * \brief Set the supported Application Layer Protocols. - * - * \param conf SSL configuration - * \param protos Pointer to a NULL-terminated list of supported protocols, - * in decreasing preference order. The pointer to the list is - * recorded by the library for later reference as required, so - * the lifetime of the table must be at least as long as the - * lifetime of the SSL configuration structure. - * - * \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA. - */ -int mbedtls_ssl_conf_alpn_protocols(mbedtls_ssl_config *conf, const char **protos); - -/** - * \brief Get the name of the negotiated Application Layer Protocol. - * This function should be called after the handshake is - * completed. - * - * \param ssl SSL context - * - * \return Protocol name, or NULL if no protocol was negotiated. - */ -const char *mbedtls_ssl_get_alpn_protocol(const mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) -#if defined(MBEDTLS_DEBUG_C) -static inline const char *mbedtls_ssl_get_srtp_profile_as_string(mbedtls_ssl_srtp_profile profile) -{ - switch (profile) { - case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: - return "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80"; - case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: - return "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32"; - case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: - return "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80"; - case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: - return "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32"; - default: break; - } - return ""; -} -#endif /* MBEDTLS_DEBUG_C */ -/** - * \brief Manage support for mki(master key id) value - * in use_srtp extension. - * MKI is an optional part of SRTP used for key management - * and re-keying. See RFC3711 section 3.1 for details. - * The default value is - * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED. - * - * \param conf The SSL configuration to manage mki support. - * \param support_mki_value Enable or disable mki usage. Values are - * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED - * or #MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED. - */ -void mbedtls_ssl_conf_srtp_mki_value_supported(mbedtls_ssl_config *conf, - int support_mki_value); - -/** - * \brief Set the supported DTLS-SRTP protection profiles. - * - * \param conf SSL configuration - * \param profiles Pointer to a List of MBEDTLS_TLS_SRTP_UNSET terminated - * supported protection profiles - * in decreasing preference order. - * The pointer to the list is recorded by the library - * for later reference as required, so the lifetime - * of the table must be at least as long as the lifetime - * of the SSL configuration structure. - * The list must not hold more than - * MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements - * (excluding the terminating MBEDTLS_TLS_SRTP_UNSET). - * - * \return 0 on success - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of - * protection profiles is incorrect. - */ -int mbedtls_ssl_conf_dtls_srtp_protection_profiles - (mbedtls_ssl_config *conf, - const mbedtls_ssl_srtp_profile *profiles); - -/** - * \brief Set the mki_value for the current DTLS-SRTP session. - * - * \param ssl SSL context to use. - * \param mki_value The MKI value to set. - * \param mki_len The length of the MKI value. - * - * \note This function is relevant on client side only. - * The server discovers the mki value during handshake. - * A mki value set on server side using this function - * is ignored. - * - * \return 0 on success - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA - * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE - */ -int mbedtls_ssl_dtls_srtp_set_mki_value(mbedtls_ssl_context *ssl, - unsigned char *mki_value, - uint16_t mki_len); -/** - * \brief Get the negotiated DTLS-SRTP information: - * Protection profile and MKI value. - * - * \warning This function must be called after the handshake is - * completed. The value returned by this function must - * not be trusted or acted upon before the handshake completes. - * - * \param ssl The SSL context to query. - * \param dtls_srtp_info The negotiated DTLS-SRTP information: - * - Protection profile in use. - * A direct mapping of the iana defined value for protection - * profile on an uint16_t. - http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml - * #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated - * or peer's Hello packet was not parsed yet. - * - mki size and value( if size is > 0 ). - */ -void mbedtls_ssl_get_dtls_srtp_negotiation_result(const mbedtls_ssl_context *ssl, - mbedtls_dtls_srtp_info *dtls_srtp_info); -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief Set the maximum supported version sent from the client side - * and/or accepted at the server side. - * - * See also the documentation of mbedtls_ssl_conf_min_version(). - * - * \note This ignores ciphersuites from higher versions. - * - * \note This function is deprecated and has been replaced by - * \c mbedtls_ssl_conf_max_tls_version(). - * - * \param conf SSL configuration - * \param major Major version number (#MBEDTLS_SSL_MAJOR_VERSION_3) - * \param minor Minor version number - * (#MBEDTLS_SSL_MINOR_VERSION_3 for (D)TLS 1.2, - * #MBEDTLS_SSL_MINOR_VERSION_4 for TLS 1.3) - */ -void MBEDTLS_DEPRECATED mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, int major, - int minor); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Set the maximum supported version sent from the client side - * and/or accepted at the server side. - * - * \note After the handshake, you can call - * mbedtls_ssl_get_version_number() to see what version was - * negotiated. - * - * \param conf SSL configuration - * \param tls_version TLS protocol version number (\c mbedtls_ssl_protocol_version) - * (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid) - */ -static inline void mbedtls_ssl_conf_max_tls_version(mbedtls_ssl_config *conf, - mbedtls_ssl_protocol_version tls_version) -{ - conf->MBEDTLS_PRIVATE(max_tls_version) = tls_version; -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief Set the minimum accepted SSL/TLS protocol version - * - * \note By default, all supported versions are accepted. - * Future versions of the library may disable older - * protocol versions by default if they become deprecated. - * - * \note The following versions are supported (if enabled at - * compile time): - * - (D)TLS 1.2: \p major = #MBEDTLS_SSL_MAJOR_VERSION_3, - * \p minor = #MBEDTLS_SSL_MINOR_VERSION_3 - * - TLS 1.3: \p major = #MBEDTLS_SSL_MAJOR_VERSION_3, - * \p minor = #MBEDTLS_SSL_MINOR_VERSION_4 - * - * Note that the numbers in the constant names are the - * TLS internal protocol numbers, and the minor versions - * differ by one from the human-readable versions! - * - * \note Input outside of the SSL_MAX_XXXXX_VERSION and - * SSL_MIN_XXXXX_VERSION range is ignored. - * - * \note After the handshake, you can call - * mbedtls_ssl_get_version_number() to see what version was - * negotiated. - * - * \note This function is deprecated and has been replaced by - * \c mbedtls_ssl_conf_min_tls_version(). - * - * \param conf SSL configuration - * \param major Major version number (#MBEDTLS_SSL_MAJOR_VERSION_3) - * \param minor Minor version number - * (#MBEDTLS_SSL_MINOR_VERSION_3 for (D)TLS 1.2, - * #MBEDTLS_SSL_MINOR_VERSION_4 for TLS 1.3) - */ -void MBEDTLS_DEPRECATED mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, int major, - int minor); -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Set the minimum supported version sent from the client side - * and/or accepted at the server side. - * - * \note After the handshake, you can call - * mbedtls_ssl_get_version_number() to see what version was - * negotiated. - * - * \param conf SSL configuration - * \param tls_version TLS protocol version number (\c mbedtls_ssl_protocol_version) - * (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid) - */ -static inline void mbedtls_ssl_conf_min_tls_version(mbedtls_ssl_config *conf, - mbedtls_ssl_protocol_version tls_version) -{ - conf->MBEDTLS_PRIVATE(min_tls_version) = tls_version; -} - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -/** - * \brief Enable or disable Encrypt-then-MAC - * (Default: MBEDTLS_SSL_ETM_ENABLED) - * - * \note This should always be enabled, it is a security - * improvement, and should not cause any interoperability - * issue (used only if the peer supports it too). - * - * \param conf SSL configuration - * \param etm MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED - */ -void mbedtls_ssl_conf_encrypt_then_mac(mbedtls_ssl_config *conf, char etm); -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -/** - * \brief Enable or disable Extended Master Secret negotiation. - * (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED) - * - * \note This should always be enabled, it is a security fix to the - * protocol, and should not cause any interoperability issue - * (used only if the peer supports it too). - * - * \param conf SSL configuration - * \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED - */ -void mbedtls_ssl_conf_extended_master_secret(mbedtls_ssl_config *conf, char ems); -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Whether to send a list of acceptable CAs in - * CertificateRequest messages. - * (Default: do send) - * - * \param conf SSL configuration - * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or - * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED - */ -void mbedtls_ssl_conf_cert_req_ca_list(mbedtls_ssl_config *conf, - char cert_req_ca_list); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/** - * \brief Set the maximum fragment length to emit and/or negotiate. - * (Typical: the smaller of #MBEDTLS_SSL_IN_CONTENT_LEN and - * #MBEDTLS_SSL_OUT_CONTENT_LEN, usually `2^14` bytes) - * (Server: set maximum fragment length to emit, - * usually negotiated by the client during handshake) - * (Client: set maximum fragment length to emit *and* - * negotiate with the server during handshake) - * (Default: #MBEDTLS_SSL_MAX_FRAG_LEN_NONE) - * - * \note On the client side, the maximum fragment length extension - * *will not* be used, unless the maximum fragment length has - * been set via this function to a value different than - * #MBEDTLS_SSL_MAX_FRAG_LEN_NONE. - * - * \note With TLS, this currently only affects ApplicationData (sent - * with \c mbedtls_ssl_read()), not handshake messages. - * With DTLS, this affects both ApplicationData and handshake. - * - * \note Defragmentation of TLS handshake messages is supported - * with some limitations. See the documentation of - * mbedtls_ssl_handshake() for details. - * - * \note This sets the maximum length for a record's payload, - * excluding record overhead that will be added to it, see - * \c mbedtls_ssl_get_record_expansion(). - * - * \note For DTLS, it is also possible to set a limit for the total - * size of datagrams passed to the transport layer, including - * record overhead, see \c mbedtls_ssl_set_mtu(). - * - * \param conf SSL configuration - * \param mfl_code Code for maximum fragment length (allowed values: - * MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024, - * MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096) - * - * \return 0 if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA - */ -int mbedtls_ssl_conf_max_frag_len(mbedtls_ssl_config *conf, unsigned char mfl_code); -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Pick the ciphersuites order according to the second parameter - * in the SSL Server module (MBEDTLS_SSL_SRV_C). - * (Default, if never called: MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER) - * - * \param conf SSL configuration - * \param order Server or client (MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER - * or MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) - */ -void mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Enable / Disable TLS 1.2 session tickets (client only, - * TLS 1.2 only). Enabled by default. - * - * \note On server, use \c mbedtls_ssl_conf_session_tickets_cb(). - * - * \param conf SSL configuration - * \param use_tickets Enable or disable (#MBEDTLS_SSL_SESSION_TICKETS_ENABLED or - * #MBEDTLS_SSL_SESSION_TICKETS_DISABLED) - */ -void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -/** - * \brief Enable / Disable handling of TLS 1.3 NewSessionTicket messages - * (client only, TLS 1.3 only). - * - * The handling of TLS 1.3 NewSessionTicket messages is disabled by - * default. - * - * In TLS 1.3, servers may send a NewSessionTicket message at any time, - * and may send multiple NewSessionTicket messages. By default, TLS 1.3 - * clients ignore NewSessionTicket messages. - * - * To support session tickets in TLS 1.3 clients, call this function - * with #MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED. When - * this is enabled, when a client receives a NewSessionTicket message, - * the next call to a message processing functions (notably - * mbedtls_ssl_handshake() and mbedtls_ssl_read()) will return - * #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET. The client should then - * call mbedtls_ssl_get_session() to retrieve the session ticket before - * calling the same message processing function again. - * - * \param conf SSL configuration - * \param signal_new_session_tickets Enable or disable - * (#MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED or - * #MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED) - */ -void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets( - mbedtls_ssl_config *conf, int signal_new_session_tickets); - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_3) -/** - * \brief Number of NewSessionTicket messages for the server to send - * after handshake completion. - * - * \note The default value is - * \c MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS. - * - * \note In case of a session resumption, this setting only partially apply. - * At most one ticket is sent in that case to just renew the pool of - * tickets of the client. The rationale is to avoid the number of - * tickets on the server to become rapidly out of control when the - * server has the same configuration for all its connection instances. - * - * \param conf SSL configuration - * \param num_tickets Number of NewSessionTicket. - * - */ -void mbedtls_ssl_conf_new_session_tickets(mbedtls_ssl_config *conf, - uint16_t num_tickets); -#endif /* MBEDTLS_SSL_SESSION_TICKETS && - MBEDTLS_SSL_SRV_C && - MBEDTLS_SSL_PROTO_TLS1_3*/ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Enable / Disable renegotiation support for connection when - * initiated by peer - * (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED) - * - * \warning It is recommended to always disable renegotiation unless you - * know you need it and you know what you're doing. In the - * past, there have been several issues associated with - * renegotiation or a poor understanding of its properties. - * - * \note Server-side, enabling renegotiation also makes the server - * susceptible to a resource DoS by a malicious client. - * - * \param conf SSL configuration - * \param renegotiation Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or - * MBEDTLS_SSL_RENEGOTIATION_DISABLED) - */ -void mbedtls_ssl_conf_renegotiation(mbedtls_ssl_config *conf, int renegotiation); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Prevent or allow legacy renegotiation. - * (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) - * - * MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION allows connections to - * be established even if the peer does not support - * secure renegotiation, but does not allow renegotiation - * to take place if not secure. - * (Interoperable and secure option) - * - * MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations - * with non-upgraded peers. Allowing legacy renegotiation - * makes the connection vulnerable to specific man in the - * middle attacks. (See RFC 5746) - * (Most interoperable and least secure option) - * - * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE breaks off connections - * if peer does not support secure renegotiation. Results - * in interoperability issues with non-upgraded peers - * that do not support renegotiation altogether. - * (Most secure option, interoperability issues) - * - * \param conf SSL configuration - * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, - * SSL_ALLOW_LEGACY_RENEGOTIATION or - * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) - */ -void mbedtls_ssl_conf_legacy_renegotiation(mbedtls_ssl_config *conf, int allow_legacy); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Enforce renegotiation requests. - * (Default: enforced, max_records = 16) - * - * When we request a renegotiation, the peer can comply or - * ignore the request. This function allows us to decide - * whether to enforce our renegotiation requests by closing - * the connection if the peer doesn't comply. - * - * However, records could already be in transit from the peer - * when the request is emitted. In order to increase - * reliability, we can accept a number of records before the - * expected handshake records. - * - * The optimal value is highly dependent on the specific usage - * scenario. - * - * \note With DTLS and server-initiated renegotiation, the - * HelloRequest is retransmitted every time mbedtls_ssl_read() times - * out or receives Application Data, until: - * - max_records records have beens seen, if it is >= 0, or - * - the number of retransmits that would happen during an - * actual handshake has been reached. - * Please remember the request might be lost a few times - * if you consider setting max_records to a really low value. - * - * \warning On client, the grace period can only happen during - * mbedtls_ssl_read(), as opposed to mbedtls_ssl_write() and mbedtls_ssl_renegotiate() - * which always behave as if max_record was 0. The reason is, - * if we receive application data from the server, we need a - * place to write it, which only happens during mbedtls_ssl_read(). - * - * \param conf SSL configuration - * \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to - * enforce renegotiation, or a non-negative value to enforce - * it but allow for a grace period of max_records records. - */ -void mbedtls_ssl_conf_renegotiation_enforced(mbedtls_ssl_config *conf, int max_records); - -/** - * \brief Set record counter threshold for periodic renegotiation. - * (Default: 2^48 - 1) - * - * Renegotiation is automatically triggered when a record - * counter (outgoing or incoming) crosses the defined - * threshold. The default value is meant to prevent the - * connection from being closed when the counter is about to - * reached its maximal value (it is not allowed to wrap). - * - * Lower values can be used to enforce policies such as "keys - * must be refreshed every N packets with cipher X". - * - * The renegotiation period can be disabled by setting - * conf->disable_renegotiation to - * MBEDTLS_SSL_RENEGOTIATION_DISABLED. - * - * \note When the configured transport is - * MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation - * period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM, - * the maximum renegotiation period is 2^64 - 1. - * - * \param conf SSL configuration - * \param period The threshold value: a big-endian 64-bit number. - */ -void mbedtls_ssl_conf_renegotiation_period(mbedtls_ssl_config *conf, - const unsigned char period[8]); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Check if there is data already read from the - * underlying transport but not yet processed. - * - * \param ssl SSL context - * - * \return 0 if nothing's pending, 1 otherwise. - * - * \note This is different in purpose and behaviour from - * \c mbedtls_ssl_get_bytes_avail in that it considers - * any kind of unprocessed data, not only unread - * application data. If \c mbedtls_ssl_get_bytes - * returns a non-zero value, this function will - * also signal pending data, but the converse does - * not hold. For example, in DTLS there might be - * further records waiting to be processed from - * the current underlying transport's datagram. - * - * \note If this function returns 1 (data pending), this - * does not imply that a subsequent call to - * \c mbedtls_ssl_read will provide any data; - * e.g., the unprocessed data might turn out - * to be an alert or a handshake message. - * - * \note This function is useful in the following situation: - * If the SSL/TLS module successfully returns from an - * operation - e.g. a handshake or an application record - * read - and you're awaiting incoming data next, you - * must not immediately idle on the underlying transport - * to have data ready, but you need to check the value - * of this function first. The reason is that the desired - * data might already be read but not yet processed. - * If, in contrast, a previous call to the SSL/TLS module - * returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary - * to call this function, as the latter error code entails - * that all internal data has been processed. - * - */ -int mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the number of application data bytes - * remaining to be read from the current record. - * - * \param ssl SSL context - * - * \return How many bytes are available in the application - * data record read buffer. - * - * \note When working over a datagram transport, this is - * useful to detect the current datagram's boundary - * in case \c mbedtls_ssl_read has written the maximal - * amount of data fitting into the input buffer. - * - */ -size_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the result of the certificate verification - * - * \param ssl The SSL context to use. - * - * \return \c 0 if the certificate verification was successful. - * \return \c -1u if the result is not available. This may happen - * e.g. if the handshake aborts early, or a verification - * callback returned a fatal error. - * \return A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX - * and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h. - */ -uint32_t mbedtls_ssl_get_verify_result(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the id of the current ciphersuite - * - * \param ssl SSL context - * - * \return a ciphersuite id - */ -int mbedtls_ssl_get_ciphersuite_id_from_ssl(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the name of the current ciphersuite - * - * \param ssl SSL context - * - * \return a string containing the ciphersuite name - */ -const char *mbedtls_ssl_get_ciphersuite(const mbedtls_ssl_context *ssl); - - -/** - * \brief Return the (D)TLS protocol version negotiated in the - * given connection. - * - * \note If you call this function too early during the initial - * handshake, before the two sides have agreed on a version, - * this function returns #MBEDTLS_SSL_VERSION_UNKNOWN. - * - * \param ssl The SSL context to query. - * \return The negotiated protocol version. - */ -static inline mbedtls_ssl_protocol_version mbedtls_ssl_get_version_number( - const mbedtls_ssl_context *ssl) -{ - return ssl->MBEDTLS_PRIVATE(tls_version); -} - -/** - * \brief Return the current TLS version - * - * \param ssl SSL context - * - * \return a string containing the TLS version - */ -const char *mbedtls_ssl_get_version(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the (maximum) number of bytes added by the record - * layer: header + encryption/MAC overhead (inc. padding) - * - * \param ssl SSL context - * - * \return Current maximum record expansion in bytes - */ -int mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the current maximum outgoing record payload in bytes. - * - * \note The logic to determine the maximum outgoing record payload is - * version-specific. It takes into account various factors, such as - * the mbedtls_config.h setting \c MBEDTLS_SSL_OUT_CONTENT_LEN, extensions - * such as the max fragment length or record size limit extension if - * used, and for DTLS the path MTU as configured and current - * record expansion. - * - * \note With DTLS, \c mbedtls_ssl_write() will return an error if - * called with a larger length value. - * With TLS, \c mbedtls_ssl_write() will fragment the input if - * necessary and return the number of bytes written; it is up - * to the caller to call \c mbedtls_ssl_write() again in - * order to send the remaining bytes if any. - * - * \sa mbedtls_ssl_get_max_out_record_payload() - * \sa mbedtls_ssl_get_record_expansion() - * - * \param ssl SSL context - * - * \return Current maximum payload for an outgoing record, - * or a negative error code. - */ -int mbedtls_ssl_get_max_out_record_payload(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the current maximum incoming record payload in bytes. - * - * \note The logic to determine the maximum incoming record payload is - * version-specific. It takes into account various factors, such as - * the mbedtls_config.h setting \c MBEDTLS_SSL_IN_CONTENT_LEN, extensions - * such as the max fragment length extension or record size limit - * extension if used, and the current record expansion. - * - * \sa mbedtls_ssl_set_mtu() - * \sa mbedtls_ssl_get_max_in_record_payload() - * \sa mbedtls_ssl_get_record_expansion() - * - * \param ssl SSL context - * - * \return Current maximum payload for an incoming record, - * or a negative error code. - */ -int mbedtls_ssl_get_max_in_record_payload(const mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Return the peer certificate from the current connection. - * - * \param ssl The SSL context to use. This must be initialized and setup. - * - * \return The current peer certificate, if available. - * The returned certificate is owned by the SSL context and - * is valid only until the next call to the SSL API. - * \return \c NULL if no peer certificate is available. This might - * be because the chosen ciphersuite doesn't use CRTs - * (PSK-based ciphersuites, for example), or because - * #MBEDTLS_SSL_KEEP_PEER_CERTIFICATE has been disabled, - * allowing the stack to free the peer's CRT to save memory. - * - * \note For one-time inspection of the peer's certificate during - * the handshake, consider registering an X.509 CRT verification - * callback through mbedtls_ssl_conf_verify() instead of calling - * this function. Using mbedtls_ssl_conf_verify() also comes at - * the benefit of allowing you to influence the verification - * process, for example by masking expected and tolerated - * verification failures. - * - * \warning You must not use the pointer returned by this function - * after any further call to the SSL API, including - * mbedtls_ssl_read() and mbedtls_ssl_write(); this is - * because the pointer might change during renegotiation, - * which happens transparently to the user. - * If you want to use the certificate across API calls, - * you must make a copy. - */ -const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Export a session in order to resume it later. - * - * \param ssl The SSL context representing the connection for which to - * to export a session structure for later resumption. - * \param session The target structure in which to store the exported session. - * This must have been initialized with mbedtls_ssl_session_init() - * but otherwise be unused. - * - * \note This function can handle a variety of mechanisms for session - * resumption: For TLS 1.2, both session ID-based resumption and - * ticket-based resumption will be considered. For TLS 1.3, - * sessions equate to tickets, and if session tickets are - * enabled (see #MBEDTLS_SSL_SESSION_TICKETS configuration - * option), this function exports the last received ticket and - * the exported session may be used to resume the TLS 1.3 - * session. If session tickets are disabled, exported sessions - * cannot be used to resume a TLS 1.3 session. - * - * \return \c 0 if successful. In this case, \p session can be used for - * session resumption by passing it to mbedtls_ssl_set_session(), - * and serialized for storage via mbedtls_ssl_session_save(). - * \return Another negative error code on other kinds of failure. - * - * \sa mbedtls_ssl_set_session() - * \sa mbedtls_ssl_session_save() - */ -int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, - mbedtls_ssl_session *session); -#endif /* MBEDTLS_SSL_CLI_C */ - -/** - * \brief Perform the SSL handshake - * - * \param ssl SSL context - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use - * and the client did not demonstrate reachability yet - in - * this case you must stop using the context (see below). - * \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3 - * NewSessionTicket message has been received. See the - * documentation of mbedtls_ssl_read() for more information - * about this error code. - * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as - * defined in RFC 8446 (TLS 1.3 specification), has been - * received as part of the handshake. This is server specific - * and may occur only if the early data feature has been - * enabled on server (see mbedtls_ssl_conf_early_data() - * documentation). You must call mbedtls_ssl_read_early_data() - * to read the early data before resuming the handshake. - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or - * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note If DTLS is in use, then you may choose to handle - * #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging - * purposes, as it is an expected return value rather than an - * actual error, but you still need to reset/free the context. - * - * \note Remarks regarding event-driven DTLS: - * If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. This is not true for a successful handshake, - * in which case the datagram of the underlying transport that is - * currently being processed might or might not contain further - * DTLS records. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * Otherwise, the handshake may call psa_crypto_init() - * if a negotiation involving TLS 1.3 takes place (this may - * be the case even if TLS 1.3 is offered but eventually - * not selected). - * - * \note In TLS, reception of fragmented handshake messages is - * supported with some limitations (those limitations do - * not apply to DTLS, where defragmentation is fully - * supported): - * - The first fragment of a handshake message must be - * at least 4 bytes long. - * - Non-handshake records must not be interleaved between - * the fragments of a handshake message. (This is permitted - * in TLS 1.2 but not in TLS 1.3, but Mbed TLS rejects it - * even in TLS 1.2.) - */ -int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl); - -/** - * \brief After calling mbedtls_ssl_handshake() to start the SSL - * handshake you can call this function to check whether the - * handshake is over for a given SSL context. This function - * should be also used to determine when to stop calling - * mbedtls_handshake_step() for that context. - * - * \param ssl SSL context - * - * \return \c 1 if handshake is over, \c 0 if it is still ongoing. - */ -static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl) -{ - return ssl->MBEDTLS_PRIVATE(state) >= MBEDTLS_SSL_HANDSHAKE_OVER; -} - -/** - * \brief Perform a single step of the SSL handshake - * - * \note The state of the context (ssl->state) will be at - * the next state after this function returns \c 0. Do not - * call this function if mbedtls_ssl_is_handshake_over() - * returns \c 1. - * - * \warning Whilst in the past you may have used direct access to the - * context state (ssl->state) in order to ascertain when to - * stop calling this function and although you can still do - * so with something like ssl->MBEDTLS_PRIVATE(state) or by - * defining MBEDTLS_ALLOW_PRIVATE_ACCESS, this is now - * considered deprecated and could be broken in any future - * release. If you still find you have good reason for such - * direct access, then please do contact the team to explain - * this (raise an issue or post to the mailing list), so that - * we can add a solution to your problem that will be - * guaranteed to work in the future. - * - * \param ssl SSL context - * - * \return See mbedtls_ssl_handshake(). - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or - * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. - */ -int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Initiate an SSL renegotiation on the running connection. - * Client: perform the renegotiation right now. - * Server: request renegotiation, which will be performed - * during the next call to mbedtls_ssl_read() if honored by - * client. - * - * \param ssl SSL context - * - * \return 0 if successful, or any mbedtls_ssl_handshake() return - * value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't - * happen during a renegotiation. - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. - * - */ -int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Read at most 'len' application data bytes - * - * \param ssl SSL context - * \param buf buffer that will hold the data - * \param len maximum number of bytes to read - * - * \return The (positive) number of bytes read if successful. - * \return \c 0 if the read end of the underlying transport was closed - * without sending a CloseNotify beforehand, which might happen - * because of various reasons (internal error of an underlying - * stack, non-conformant peer not sending a CloseNotify and - * such) - in this case you must stop using the context - * (see below). - * \return #MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY if the underlying - * transport is still functional, but the peer has - * acknowledged to not send anything anymore. - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server - * side of a DTLS connection and the client is initiating a - * new connection using the same source port. See below. - * \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3 - * NewSessionTicket message has been received. - * This error code is only returned on the client side. It is - * only returned if handling of TLS 1.3 NewSessionTicket - * messages has been enabled through - * mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(). - * This error code indicates that a TLS 1.3 NewSessionTicket - * message has been received and parsed successfully by the - * client. The ticket data can be retrieved from the SSL - * context by calling mbedtls_ssl_get_session(). It remains - * available until the next call to mbedtls_ssl_read(). - * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as - * defined in RFC 8446 (TLS 1.3 specification), has been - * received as part of the handshake. This is server specific - * and may occur only if the early data feature has been - * enabled on server (see mbedtls_ssl_conf_early_data() - * documentation). You must call mbedtls_ssl_read_early_data() - * to read the early data before resuming the handshake. - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * a positive value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or - * #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or - * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT - * (which can only happen server-side), it means that a client - * is initiating a new connection using the same source port. - * You can either treat that as a connection close and wait - * for the client to resend a ClientHello, or directly - * continue with \c mbedtls_ssl_handshake() with the same - * context (as it has been reset internally). Either way, you - * must make sure this is seen by the application as a new - * connection: application state, if any, should be reset, and - * most importantly the identity of the client must be checked - * again. WARNING: not validating the identity of the client - * again, or not transmitting the new identity to the - * application layer, would allow authentication bypass! - * - * \note Remarks regarding event-driven DTLS: - * - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. - * - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was - * initially available on the underlying transport, as this data may have - * been only e.g. duplicated messages or a renegotiation request. - * Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even - * when reacting to an incoming-data event from the underlying transport. - * - On success, the datagram of the underlying transport that is currently - * being processed may contain further DTLS records. You should call - * \c mbedtls_ssl_check_pending to check for remaining records. - * - */ -int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); - -/** - * \brief Try to write exactly 'len' application data bytes - * - * \warning This function will do partial writes in some cases. If the - * return value is non-negative but less than length, the - * function must be called again with updated arguments: - * buf + ret, len - ret (if ret is the return value) until - * it returns a value equal to the last 'len' argument. - * - * \param ssl SSL context - * \param buf buffer holding the data - * \param len how many bytes must be written - * - * \return The (non-negative) number of bytes actually written if - * successful (may be less than \p len). - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3 - * NewSessionTicket message has been received. See the - * documentation of mbedtls_ssl_read() for more information - * about this error code. - * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as - * defined in RFC 8446 (TLS 1.3 specification), has been - * received as part of the handshake. This is server specific - * and may occur only if the early data feature has been - * enabled on server (see mbedtls_ssl_conf_early_data() - * documentation). You must call mbedtls_ssl_read_early_data() - * to read the early data before resuming the handshake. - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * a non-negative value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or - * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ, - * it must be called later with the *same* arguments, - * until it returns a value greater than or equal to 0. When - * the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be - * some partial data in the output buffer, however this is not - * yet sent. - * - * \note If the requested length is greater than the maximum - * fragment length (either the built-in limit or the one set - * or negotiated with the peer), then: - * - with TLS, less bytes than requested are written. - * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. - * \c mbedtls_ssl_get_max_out_record_payload() may be used to - * query the active maximum fragment length. - * - * \note Attempting to write 0 bytes will result in an empty TLS - * application record being sent. - */ -int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len); - -/** - * \brief Send an alert message - * - * \param ssl SSL context - * \param level The alert level of the message - * (MBEDTLS_SSL_ALERT_LEVEL_WARNING or MBEDTLS_SSL_ALERT_LEVEL_FATAL) - * \param message The alert message (SSL_ALERT_MSG_*) - * - * \return 0 if successful, or a specific SSL error code. - * - * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. - */ -int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, - unsigned char level, - unsigned char message); -/** - * \brief Notify the peer that the connection is being closed - * - * \param ssl SSL context - * - * \return 0 if successful, or a specific SSL error code. - * - * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. - */ -int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_EARLY_DATA) - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Read at most 'len' bytes of early data - * - * \note This API is server specific. - * - * \warning Early data is defined in the TLS 1.3 specification, RFC 8446. - * IMPORTANT NOTE from section 2.3 of the specification: - * - * The security properties for 0-RTT data are weaker than - * those for other kinds of TLS data. Specifically: - * - This data is not forward secret, as it is encrypted - * solely under keys derived using the offered PSK. - * - There are no guarantees of non-replay between connections. - * Protection against replay for ordinary TLS 1.3 1-RTT data - * is provided via the server's Random value, but 0-RTT data - * does not depend on the ServerHello and therefore has - * weaker guarantees. This is especially relevant if the - * data is authenticated either with TLS client - * authentication or inside the application protocol. The - * same warnings apply to any use of the - * early_exporter_master_secret. - * - * \warning Mbed TLS does not implement any of the anti-replay defenses - * defined in section 8 of the TLS 1.3 specification: - * single-use of tickets or ClientHello recording within a - * given time window. - * - * \note This function is used in conjunction with - * mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), - * mbedtls_ssl_read() and mbedtls_ssl_write() to read early - * data when these functions return - * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. - * - * \param ssl SSL context, it must have been initialized and set up. - * \param buf buffer that will hold the data - * \param len maximum number of bytes to read - * - * \return The (positive) number of bytes read if successful. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. - * \return #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA if it is not - * possible to read early data for the SSL context \p ssl. Note - * that this function is intended to be called for an SSL - * context \p ssl only after a call to mbedtls_ssl_handshake(), - * mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or - * mbedtls_ssl_write() for \p ssl that has returned - * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. - */ -int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, - unsigned char *buf, size_t len); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Try to write exactly 'len' application data bytes while - * performing the handshake (early data). - * - * \warning Early data is defined in the TLS 1.3 specification, RFC 8446. - * IMPORTANT NOTE from section 2.3 of the specification: - * - * The security properties for 0-RTT data are weaker than - * those for other kinds of TLS data. Specifically: - * - This data is not forward secret, as it is encrypted - * solely under keys derived using the offered PSK. - * - There are no guarantees of non-replay between connections. - * Protection against replay for ordinary TLS 1.3 1-RTT data - * is provided via the server's Random value, but 0-RTT data - * does not depend on the ServerHello and therefore has - * weaker guarantees. This is especially relevant if the - * data is authenticated either with TLS client - * authentication or inside the application protocol. The - * same warnings apply to any use of the - * early_exporter_master_secret. - * - * \note This function behaves mainly as mbedtls_ssl_write(). The - * specification of mbedtls_ssl_write() relevant to TLS 1.3 - * (thus not the parts specific to (D)TLS1.2) applies to this - * function and the present documentation is mainly restricted - * to the differences with mbedtls_ssl_write(). One noticeable - * difference though is that mbedtls_ssl_write() aims to - * complete the handshake before to write application data - * while mbedtls_ssl_write_early() aims to drive the handshake - * just past the point where it is not possible to send early - * data anymore. - * - * \param ssl SSL context - * \param buf buffer holding the data - * \param len how many bytes must be written - * - * \return The (non-negative) number of bytes actually written if - * successful (may be less than \p len). - * - * \return One additional specific error code compared to - * mbedtls_ssl_write(): - * #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA. - * - * #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA is returned when it - * is not possible to write early data for the SSL context - * \p ssl. - * - * It may have been possible and it is not possible - * anymore because the client received the server Finished - * message, the server rejected early data or the maximum - * number of allowed early data for the PSK in use has been - * reached. - * - * It may never have been possible and will never be possible - * for the SSL context \p ssl because the use of early data - * is disabled for that context or more generally the context - * is not suitably configured to enable early data or the first - * call to the function was done while the handshake was - * already completed. - * - * It is not possible to write early data for the SSL context - * \p ssl and any subsequent call to this API will return this - * error code. But this does not preclude for using it with - * mbedtls_ssl_write(), mbedtls_ssl_read() or - * mbedtls_ssl_handshake() and the handshake can be - * completed by calling one of these APIs. - * - * \note This function may write early data only if the SSL context - * has been configured for the handshake with a PSK for which - * early data is allowed. - * - * \note To maximize the number of early data that can be written in - * the course of the handshake, it is expected that this - * function starts the handshake for the SSL context \p ssl. - * But this is not mandatory. - * - * \note This function does not provide any information on whether - * the server has accepted or will accept early data or not. - * When it returns a positive value, it just means that it - * has written early data to the server. To know whether the - * server has accepted early data or not, you should call - * mbedtls_ssl_get_early_data_status() with the handshake - * completed. - */ -int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len); - -/** - * \brief Get the status of the negotiation of the use of early data. - * - * \param ssl The SSL context to query - * - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called - * from the server-side. - * - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called - * prior to completion of the handshake. - * - * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED if the client - * has not indicated the use of early data to the server. - * - * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED if the client has - * indicated the use of early data and the server has accepted - * it. - * - * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED if the client has - * indicated the use of early data but the server has rejected - * it. In this situation, the client may want to re-send the - * early data it may have tried to send by calling - * mbedtls_ssl_write_early_data() as ordinary post-handshake - * application data by calling mbedtls_ssl_write(). - * - */ -int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_CLI_C */ - -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -/** - * \brief Free referenced items in an SSL context and clear memory - * - * \param ssl SSL context - */ -void mbedtls_ssl_free(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) -/** - * \brief Save an active connection as serialized data in a buffer. - * This allows the freeing or re-using of the SSL context - * while still picking up the connection later in a way that - * it entirely transparent to the peer. - * - * \see mbedtls_ssl_context_load() - * - * \warning The serialized data contains highly sensitive material, - * including the master secret from which the session's traffic - * keys are derived. - * - * The serialized data is not cryptographically protected. - * It is the responsibility of the user of the - * mbedtls_ssl_context_save() and - * mbedtls_ssl_context_load() APIs to ensure both its - * confidentiality and integrity while stored or transported. - * - * See the mbedtls_ssl_context_load() documentation for - * additional information. - * - * \note The serialized data only contains the data that is - * necessary to resume the connection: negotiated protocol - * options, session identifier, keys, etc. - * Loading a saved SSL context does not restore settings and - * state related to how the application accesses the context, - * such as configured callback functions, user data, pending - * incoming or outgoing data, etc. - * - * \note This feature is currently only available under certain - * conditions, see the documentation of the return value - * #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details. - * - * \note When this function succeeds, it calls - * mbedtls_ssl_session_reset() on \p ssl which as a result is - * no longer associated with the connection that has been - * serialized. This avoids creating copies of the connection - * state. You're then free to either re-use the context - * structure for a different connection, or call - * mbedtls_ssl_free() on it. See the documentation of - * mbedtls_ssl_session_reset() for more details. - * - * \param ssl The SSL context to save. On success, it is no longer - * associated with the connection that has been serialized. - * \param buf The buffer to write the serialized data to. It must be a - * writeable buffer of at least \p buf_len bytes, or may be \c - * NULL if \p buf_len is \c 0. - * \param buf_len The number of bytes available for writing in \p buf. - * \param olen The size in bytes of the data that has been or would have - * been written. It must point to a valid \c size_t. - * - * \note \p olen is updated to the correct value regardless of - * whether \p buf_len was large enough. This makes it possible - * to determine the necessary size by calling this function - * with \p buf set to \c NULL and \p buf_len to \c 0. However, - * the value of \p olen is only guaranteed to be correct when - * the function returns #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL or - * \c 0. If the return value is different, then the value of - * \p olen is undefined. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small. - * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed - * while resetting the context. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in - * progress, or there is pending data for reading or sending, - * or the connection does not use DTLS 1.2 with an AEAD - * ciphersuite, or renegotiation is enabled. - */ -int mbedtls_ssl_context_save(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buf_len, - size_t *olen); - -/** - * \brief Load serialized connection data to an SSL context. - * - * \see mbedtls_ssl_context_save() - * - * \warning The same serialized data must never be loaded into more - * that one context. In order to ensure that, after - * successfully loading serialized data to an SSL context, you - * should immediately destroy or invalidate all copies of the - * serialized data that was loaded. Loading the same data in - * more than one context would cause severe security failures - * including but not limited to loss of confidentiality. - * - * \warning The serialized data contains highly sensitive material, - * including the master secret from which the session's traffic - * keys are derived. - * - * The serialized data is not cryptographically protected. - * It is the responsibility of the user of the - * mbedtls_ssl_context_save() and - * mbedtls_ssl_context_load() APIs to ensure both its - * confidentiality and integrity while stored or transported. - * - * A breach of confidentiality could result in full compromise - * of the associated TLS session, including loss of - * confidentiality and integrity of past and future - * application data protected under that session. - * - * A breach of integrity may allow modification of the - * serialized data prior to restoration. As it represents - * trusted internal context, tampering could potentially result - * in arbitrary code execution or other severe compromise of - * the hosting process. - * - * \note Before calling this function, the SSL context must be - * prepared in one of the two following ways. The first way is - * to take a context freshly initialised with - * mbedtls_ssl_init() and call mbedtls_ssl_setup() on it with - * the same ::mbedtls_ssl_config structure that was used in - * the original connection. The second way is to - * call mbedtls_ssl_session_reset() on a context that was - * previously prepared as above but used in the meantime. - * Either way, you must not use the context to perform a - * handshake between calling mbedtls_ssl_setup() or - * mbedtls_ssl_session_reset() and calling this function. You - * may however call other setter functions in that time frame - * as indicated in the note below. - * - * \note Before or after calling this function successfully, you - * also need to configure some connection-specific callbacks - * and settings before you can use the connection again - * (unless they were already set before calling - * mbedtls_ssl_session_reset() and the values are suitable for - * the present connection). Specifically, you want to call - * at least mbedtls_ssl_set_bio(), - * mbedtls_ssl_set_timer_cb(), and - * mbedtls_ssl_set_user_data_n() or - * mbedtls_ssl_set_user_data_p() if they were set originally. - * All other SSL setter functions - * are not necessary to call, either because they're only used - * in handshakes, or because the setting is already saved. You - * might choose to call them anyway, for example in order to - * share code between the cases of establishing a new - * connection and the case of loading an already-established - * connection. - * - * \note If you have new information about the path MTU, you want to - * call mbedtls_ssl_set_mtu() after calling this function, as - * otherwise this function would overwrite your - * newly-configured value with the value that was active when - * the context was saved. - * - * \note When this function returns an error code, it calls - * mbedtls_ssl_free() on \p ssl. In this case, you need to - * prepare the context with the usual sequence starting with a - * call to mbedtls_ssl_init() if you want to use it again. - * - * \param ssl The SSL context structure to be populated. It must have - * been prepared as described in the note above. - * \param buf The buffer holding the serialized connection data. It must - * be a readable buffer of at least \p len bytes. - * \param len The size of the serialized data in bytes. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed. - * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data - * comes from a different Mbed TLS version or build. - * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. - */ -int mbedtls_ssl_context_load(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len); -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ - -/** - * \brief Initialize an SSL configuration context - * Just makes the context ready for - * mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free(). - * - * \note You need to call mbedtls_ssl_config_defaults() unless you - * manually set all of the relevant fields yourself. - * - * \param conf SSL configuration context - */ -void mbedtls_ssl_config_init(mbedtls_ssl_config *conf); - -/** - * \brief Load reasonable default SSL configuration values. - * (You need to call mbedtls_ssl_config_init() first.) - * - * \param conf SSL configuration context - * \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER - * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or - * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS - * \param preset a MBEDTLS_SSL_PRESET_XXX value - * - * \note See \c mbedtls_ssl_conf_transport() for notes on DTLS. - * - * \return 0 if successful, or - * MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error. - */ -int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf, - int endpoint, int transport, int preset); - -/** - * \brief Free an SSL configuration context - * - * \param conf SSL configuration context - */ -void mbedtls_ssl_config_free(mbedtls_ssl_config *conf); - -/** - * \brief Initialize SSL session structure - * - * \param session SSL session - */ -void mbedtls_ssl_session_init(mbedtls_ssl_session *session); - -/** - * \brief Free referenced items in an SSL session including the - * peer certificate and clear memory - * - * \note A session object can be freed even if the SSL context - * that was used to retrieve the session is still in use. - * - * \param session SSL session - */ -void mbedtls_ssl_session_free(mbedtls_ssl_session *session); - -/** - * \brief TLS-PRF function for key derivation. - * - * \param prf The tls_prf type function type to be used. - * \param secret Secret for the key derivation function. - * \param slen Length of the secret. - * \param label String label for the key derivation function, - * terminated with null character. - * \param random Random bytes. - * \param rlen Length of the random bytes buffer. - * \param dstbuf The buffer holding the derived key. - * \param dlen Length of the output buffer. - * - * \return 0 on success. An SSL specific error on failure. - */ -int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, - const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen); - -#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) -/* Maximum value for key_len in mbedtls_ssl_export_keying material. Depending on the TLS - * version and the negotiated ciphersuite, larger keys could in principle be exported, - * but for simplicity, we define one limit that works in all cases. TLS 1.3 with SHA256 - * has the strictest limit: 255 blocks of SHA256 output, or 8160 bytes. */ -#define MBEDTLS_SSL_EXPORT_MAX_KEY_LEN 8160 - -/** - * \brief TLS-Exporter to derive shared symmetric keys between server and client. - * - * \param ssl SSL context from which to export keys. Must have finished the handshake. - * \param out Output buffer of length at least key_len bytes. - * \param key_len Length of the key to generate in bytes, must be at most - * MBEDTLS_SSL_EXPORT_MAX_KEY_LEN (8160). - * \param label Label for which to generate the key of length label_len. - * \param label_len Length of label in bytes. Must be at most 249 in TLS 1.3. - * \param context Context of the key. Can be NULL if context_len or use_context is 0. - * \param context_len Length of context. Must be < 2^16 in TLS 1.2. - * \param use_context Indicates if a context should be used in deriving the key. - * - * \note TLS 1.2 makes a distinction between a 0-length context and no context. - * This is why the use_context argument exists. TLS 1.3 does not make - * this distinction. If use_context is 0 and TLS 1.3 is used, context and - * context_len are ignored and a 0-length context is used. - * - * \return 0 on success. - * \return MBEDTLS_ERR_SSL_BAD_INPUT_DATA if the handshake is not yet completed. - * \return An SSL-specific error on failure. - */ -int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, - uint8_t *out, const size_t key_len, - const char *label, const size_t label_len, - const unsigned char *context, const size_t context_len, - const int use_context); -#endif -#ifdef __cplusplus -} -#endif - -#endif /* ssl.h */ diff --git a/vendor/mbedtls/include/mbedtls/ssl_cache.h b/vendor/mbedtls/include/mbedtls/ssl_cache.h deleted file mode 100644 index a1307b450..000000000 --- a/vendor/mbedtls/include/mbedtls/ssl_cache.h +++ /dev/null @@ -1,187 +0,0 @@ -/** - * \file ssl_cache.h - * - * \brief SSL session cache implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SSL_CACHE_H -#define MBEDTLS_SSL_CACHE_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/ssl.h" - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT) -#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ -#endif - -#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES) -#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */ -#endif - -/** \} name SECTION: Module settings */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct mbedtls_ssl_cache_context mbedtls_ssl_cache_context; -typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry; - -/** - * \brief This structure is used for storing cache entries - */ -struct mbedtls_ssl_cache_entry { -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t MBEDTLS_PRIVATE(timestamp); /*!< entry timestamp */ -#endif - - unsigned char MBEDTLS_PRIVATE(session_id)[32]; /*!< session ID */ - size_t MBEDTLS_PRIVATE(session_id_len); - - unsigned char *MBEDTLS_PRIVATE(session); /*!< serialized session */ - size_t MBEDTLS_PRIVATE(session_len); - - mbedtls_ssl_cache_entry *MBEDTLS_PRIVATE(next); /*!< chain pointer */ -}; - -/** - * \brief Cache context - */ -struct mbedtls_ssl_cache_context { - mbedtls_ssl_cache_entry *MBEDTLS_PRIVATE(chain); /*!< start of the chain */ - int MBEDTLS_PRIVATE(timeout); /*!< cache entry timeout */ - int MBEDTLS_PRIVATE(max_entries); /*!< maximum entries */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); /*!< mutex */ -#endif -}; - -/** - * \brief Initialize an SSL cache context - * - * \param cache SSL cache context - */ -void mbedtls_ssl_cache_init(mbedtls_ssl_cache_context *cache); - -/** - * \brief Cache get callback implementation - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data The SSL cache context to use. - * \param session_id The pointer to the buffer holding the session ID - * for the session to load. - * \param session_id_len The length of \p session_id in bytes. - * \param session The address at which to store the session - * associated with \p session_id, if present. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND if there is - * no cache entry with specified session ID found, or - * any other negative error code for other failures. - */ -int mbedtls_ssl_cache_get(void *data, - unsigned char const *session_id, - size_t session_id_len, - mbedtls_ssl_session *session); - -/** - * \brief Cache set callback implementation - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data The SSL cache context to use. - * \param session_id The pointer to the buffer holding the session ID - * associated to \p session. - * \param session_id_len The length of \p session_id in bytes. - * \param session The session to store. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -int mbedtls_ssl_cache_set(void *data, - unsigned char const *session_id, - size_t session_id_len, - const mbedtls_ssl_session *session); - -/** - * \brief Remove the cache entry by the session ID - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data The SSL cache context to use. - * \param session_id The pointer to the buffer holding the session ID - * associated to session. - * \param session_id_len The length of \p session_id in bytes. - * - * \return \c 0 on success. This indicates the cache entry for - * the session with provided ID is removed or does not - * exist. - * \return A negative error code on failure. - */ -int mbedtls_ssl_cache_remove(void *data, - unsigned char const *session_id, - size_t session_id_len); - -#if defined(MBEDTLS_HAVE_TIME) -/** - * \brief Set the cache timeout - * (Default: MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT (1 day)) - * - * A timeout of 0 indicates no timeout. - * - * \param cache SSL cache context - * \param timeout cache entry timeout in seconds - */ -void mbedtls_ssl_cache_set_timeout(mbedtls_ssl_cache_context *cache, int timeout); - -/** - * \brief Get the cache timeout - * - * A timeout of 0 indicates no timeout. - * - * \param cache SSL cache context - * - * \return cache entry timeout in seconds - */ -static inline int mbedtls_ssl_cache_get_timeout(mbedtls_ssl_cache_context *cache) -{ - return cache->MBEDTLS_PRIVATE(timeout); -} -#endif /* MBEDTLS_HAVE_TIME */ - -/** - * \brief Set the maximum number of cache entries - * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) - * - * \param cache SSL cache context - * \param max cache entry maximum - */ -void mbedtls_ssl_cache_set_max_entries(mbedtls_ssl_cache_context *cache, int max); - -/** - * \brief Free referenced items in a cache context and clear memory - * - * \param cache SSL cache context - */ -void mbedtls_ssl_cache_free(mbedtls_ssl_cache_context *cache); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_cache.h */ diff --git a/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h b/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h deleted file mode 100644 index 12d446200..000000000 --- a/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +++ /dev/null @@ -1,482 +0,0 @@ -/** - * \file ssl_ciphersuites.h - * - * \brief SSL Ciphersuites for Mbed TLS - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SSL_CIPHERSUITES_H -#define MBEDTLS_SSL_CIPHERSUITES_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/pk.h" -#include "mbedtls/cipher.h" -#include "mbedtls/md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Supported ciphersuites (Official IANA names) - */ -#define MBEDTLS_TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */ - -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA 0x2C /**< Weak! */ -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA 0x2D /**< Weak! */ -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA 0x2E /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA 0x2F - -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 -#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA 0x35 -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 - -#define MBEDTLS_TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41 -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 - -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 - -#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA 0x8C -#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA 0x8D - -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90 -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91 - -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95 - -#define MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE -#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */ -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */ - -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */ -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */ -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A - -#define MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F - -#define MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B - -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 0xC03C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 0xC03D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC044 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC045 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC04A /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC04B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC04C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC04D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 0xC04E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 0xC04F /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 0xC050 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 0xC051 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC052 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC053 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC060 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC061 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0xC062 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0xC063 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 0xC064 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 0xC065 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC066 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC067 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 0xC068 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 0xC069 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 0xC06A /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 0xC06B /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0xC06C /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0xC06D /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0xC06E /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0xC06F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC070 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC071 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B - -#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ -/* The last two are named with PSK_DHE in the RFC, which looks like a typo */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */ - -/* RFC 7905 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ - -/* RFC 8446, Appendix B.4 */ -#define MBEDTLS_TLS1_3_AES_128_GCM_SHA256 0x1301 /**< TLS 1.3 */ -#define MBEDTLS_TLS1_3_AES_256_GCM_SHA384 0x1302 /**< TLS 1.3 */ -#define MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256 0x1303 /**< TLS 1.3 */ -#define MBEDTLS_TLS1_3_AES_128_CCM_SHA256 0x1304 /**< TLS 1.3 */ -#define MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256 0x1305 /**< TLS 1.3 */ - -/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. - * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below - */ -typedef enum { - MBEDTLS_KEY_EXCHANGE_NONE = 0, - MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_KEY_EXCHANGE_ECJPAKE, -} mbedtls_key_exchange_type_t; - -/* Key exchanges using a certificate */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED -#endif - -/* Key exchanges in either TLS 1.2 or 1.3 which are using an ECDSA - * signature */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_WITH_ECDSA_ANY_ENABLED -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -#define MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED -#endif - -/* Key exchanges allowing client certificate requests. - * - * Note: that's almost the same as MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED - * above, except RSA-PSK uses a server certificate but no client cert. - * - * Note: this difference is specific to TLS 1.2, as with TLS 1.3, things are - * more symmetrical: client certs and server certs are either both allowed - * (Ephemeral mode) or both disallowed (PSK and PKS-Ephemeral modes). - */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED -#endif - -/* Helper to state that certificate-based client authentication through ECDSA - * is supported in TLS 1.2 */ -#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) && \ - defined(MBEDTLS_PK_CAN_ECDSA_SIGN) && defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) -#define MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED -#endif - -/* ECDSA required for certificates in either TLS 1.2 or 1.3 */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED -#endif - -/* Key exchanges involving server signature in ServerKeyExchange */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED -#endif - -/* Key exchanges using ECDH */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED -#endif - -/* Key exchanges that don't involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED -#endif - -/* Key exchanges that involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED -#endif - -/* Key exchanges using a PSK */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED -#endif - -/* Key exchanges using DHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED -#endif - -/* Key exchanges using ECDHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED -#endif - -/* TLS 1.2 key exchanges using ECDH or ECDHE*/ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED -#endif - -/* TLS 1.3 PSK key exchanges */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED -#endif - -/* TLS 1.2 or 1.3 key exchanges with PSK */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -#define MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED -#endif - -/* TLS 1.3 ephemeral key exchanges */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED -#endif - -/* TLS 1.3 key exchanges using ECDHE */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \ - defined(PSA_WANT_ALG_ECDH) -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_ECDHE_ENABLED -#endif - -/* TLS 1.2 or 1.3 key exchanges using ECDH or ECDHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_ECDHE_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED -#endif - -/* TLS 1.2 XXDH key exchanges: ECDH or ECDHE or FFDH */ -#if (defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)) -#define MBEDTLS_KEY_EXCHANGE_SOME_XXDH_1_2_ENABLED -#endif - -/* The handshake params structure has a set of fields called xxdh_psa which are used: - * - by TLS 1.2 with `USE_PSA` to do ECDH or ECDHE; - * - by TLS 1.3 to do ECDHE or FFDHE. - * The following macros can be used to guard their declaration and use. - */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) && \ - defined(MBEDTLS_USE_PSA_CRYPTO) -#define MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_1_2_ENABLED -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_1_2_ENABLED) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) -#define MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED -#endif - -typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; - -#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ -#define MBEDTLS_CIPHERSUITE_SHORT_TAG 0x02 /**< Short authentication tag, - eg for CCM_8 */ -#define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */ - -/** - * \brief This structure is used for storing ciphersuite information - * - * \note members are defined using integral types instead of enums - * in order to pack structure and reduce memory usage by internal - * \c ciphersuite_definitions[] - */ -struct mbedtls_ssl_ciphersuite_t { - int MBEDTLS_PRIVATE(id); - const char *MBEDTLS_PRIVATE(name); - - uint8_t MBEDTLS_PRIVATE(cipher); /* mbedtls_cipher_type_t */ - uint8_t MBEDTLS_PRIVATE(mac); /* mbedtls_md_type_t */ - uint8_t MBEDTLS_PRIVATE(key_exchange); /* mbedtls_key_exchange_type_t */ - uint8_t MBEDTLS_PRIVATE(flags); - - uint16_t MBEDTLS_PRIVATE(min_tls_version); /* mbedtls_ssl_protocol_version */ - uint16_t MBEDTLS_PRIVATE(max_tls_version); /* mbedtls_ssl_protocol_version */ -}; - -const int *mbedtls_ssl_list_ciphersuites(void); - -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string(const char *ciphersuite_name); -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id(int ciphersuite_id); - -static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_ciphersuite_t *info) -{ - return info->MBEDTLS_PRIVATE(name); -} - -static inline int mbedtls_ssl_ciphersuite_get_id(const mbedtls_ssl_ciphersuite_t *info) -{ - return info->MBEDTLS_PRIVATE(id); -} - -size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_ciphersuites.h */ diff --git a/vendor/mbedtls/include/mbedtls/ssl_cookie.h b/vendor/mbedtls/include/mbedtls/ssl_cookie.h deleted file mode 100644 index 0f211e632..000000000 --- a/vendor/mbedtls/include/mbedtls/ssl_cookie.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * \file ssl_cookie.h - * - * \brief DTLS cookie callbacks implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SSL_COOKIE_H -#define MBEDTLS_SSL_COOKIE_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/ssl.h" - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in mbedtls_config.h or define them on the compiler command line. - * \{ - */ -#ifndef MBEDTLS_SSL_COOKIE_TIMEOUT -#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ -#endif - -/** \} name SECTION: Module settings */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Context for the default cookie functions. - */ -typedef struct mbedtls_ssl_cookie_ctx { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_svc_key_id_t MBEDTLS_PRIVATE(psa_hmac_key); /*!< key id for the HMAC portion */ - psa_algorithm_t MBEDTLS_PRIVATE(psa_hmac_alg); /*!< key algorithm for the HMAC portion */ -#else - mbedtls_md_context_t MBEDTLS_PRIVATE(hmac_ctx); /*!< context for the HMAC portion */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if !defined(MBEDTLS_HAVE_TIME) - unsigned long MBEDTLS_PRIVATE(serial); /*!< serial number for expiration */ -#endif - unsigned long MBEDTLS_PRIVATE(timeout); /*!< timeout delay, in seconds if HAVE_TIME, - or in number of tickets issued */ - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); -#endif -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ -} mbedtls_ssl_cookie_ctx; - -/** - * \brief Initialize cookie context - */ -void mbedtls_ssl_cookie_init(mbedtls_ssl_cookie_ctx *ctx); - -/** - * \brief Setup cookie context (generate keys) - */ -int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -/** - * \brief Set expiration delay for cookies - * (Default MBEDTLS_SSL_COOKIE_TIMEOUT) - * - * \param ctx Cookie context - * \param delay Delay, in seconds if HAVE_TIME, or in number of cookies - * issued in the meantime. - * 0 to disable expiration (NOT recommended) - */ -void mbedtls_ssl_cookie_set_timeout(mbedtls_ssl_cookie_ctx *ctx, unsigned long delay); - -/** - * \brief Free cookie context - */ -void mbedtls_ssl_cookie_free(mbedtls_ssl_cookie_ctx *ctx); - -/** - * \brief Generate cookie, see \c mbedtls_ssl_cookie_write_t - */ -mbedtls_ssl_cookie_write_t mbedtls_ssl_cookie_write; - -/** - * \brief Verify cookie, see \c mbedtls_ssl_cookie_write_t - */ -mbedtls_ssl_cookie_check_t mbedtls_ssl_cookie_check; - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_cookie.h */ diff --git a/vendor/mbedtls/include/mbedtls/ssl_ticket.h b/vendor/mbedtls/include/mbedtls/ssl_ticket.h deleted file mode 100644 index 9f7e44029..000000000 --- a/vendor/mbedtls/include/mbedtls/ssl_ticket.h +++ /dev/null @@ -1,199 +0,0 @@ -/** - * \file ssl_ticket.h - * - * \brief TLS server ticket callbacks implementation - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SSL_TICKET_H -#define MBEDTLS_SSL_TICKET_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -/* - * This implementation of the session ticket callbacks includes key - * management, rotating the keys periodically in order to preserve forward - * secrecy, when MBEDTLS_HAVE_TIME is defined. - */ - -#include "mbedtls/ssl.h" -#include "mbedtls/cipher.h" - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define MBEDTLS_SSL_TICKET_MAX_KEY_BYTES 32 /*!< Max supported key length in bytes */ -#define MBEDTLS_SSL_TICKET_KEY_NAME_BYTES 4 /*!< key name length in bytes */ - -/** - * \brief Information for session ticket protection - */ -typedef struct mbedtls_ssl_ticket_key { - unsigned char MBEDTLS_PRIVATE(name)[MBEDTLS_SSL_TICKET_KEY_NAME_BYTES]; - /*!< random key identifier */ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t MBEDTLS_PRIVATE(generation_time); /*!< key generation timestamp (seconds) */ -#endif - /*! Lifetime of the key in seconds. This is also the lifetime of the - * tickets created under that key. - */ - uint32_t MBEDTLS_PRIVATE(lifetime); -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_cipher_context_t MBEDTLS_PRIVATE(ctx); /*!< context for auth enc/decryption */ -#else - mbedtls_svc_key_id_t MBEDTLS_PRIVATE(key); /*!< key used for auth enc/decryption */ - psa_algorithm_t MBEDTLS_PRIVATE(alg); /*!< algorithm of auth enc/decryption */ - psa_key_type_t MBEDTLS_PRIVATE(key_type); /*!< key type */ - size_t MBEDTLS_PRIVATE(key_bits); /*!< key length in bits */ -#endif -} -mbedtls_ssl_ticket_key; - -/** - * \brief Context for session ticket handling functions - */ -typedef struct mbedtls_ssl_ticket_context { - mbedtls_ssl_ticket_key MBEDTLS_PRIVATE(keys)[2]; /*!< ticket protection keys */ - unsigned char MBEDTLS_PRIVATE(active); /*!< index of the currently active key */ - - uint32_t MBEDTLS_PRIVATE(ticket_lifetime); /*!< lifetime of tickets in seconds */ - - /** Callback for getting (pseudo-)random numbers */ - int(*MBEDTLS_PRIVATE(f_rng))(void *, unsigned char *, size_t); - void *MBEDTLS_PRIVATE(p_rng); /*!< context for the RNG function */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); -#endif -} -mbedtls_ssl_ticket_context; - -/** - * \brief Initialize a ticket context. - * (Just make it ready for mbedtls_ssl_ticket_setup() - * or mbedtls_ssl_ticket_free().) - * - * \param ctx Context to be initialized - */ -void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx); - -/** - * \brief Prepare context to be actually used - * - * \param ctx Context to be set up - * \param f_rng RNG callback function (mandatory) - * \param p_rng RNG callback context. - * Note that the RNG callback must remain valid - * until the ticket context is freed. - * \param cipher AEAD cipher to use for ticket protection. - * Recommended value: MBEDTLS_CIPHER_AES_256_GCM. - * \param lifetime Tickets lifetime in seconds - * Recommended value: 86400 (one day). - * - * \note It is highly recommended to select a cipher that is at - * least as strong as the strongest ciphersuite - * supported. Usually that means a 256-bit key. - * - * \note It is recommended to pick a reasonable lifetime so as not - * to negate the benefits of forward secrecy. - * - * \note The TLS 1.3 specification states that ticket lifetime must - * be smaller than seven days. If ticket lifetime has been - * set to a value greater than seven days in this module then - * if the TLS 1.3 is configured to send tickets after the - * handshake it will fail the connection when trying to send - * the first ticket. - * - * \return 0 if successful, - * or a specific MBEDTLS_ERR_XXX error code - */ -int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx, - mbedtls_f_rng_t *f_rng, void *p_rng, - mbedtls_cipher_type_t cipher, - uint32_t lifetime); - -/** - * \brief Rotate session ticket encryption key to new specified key. - * Provides for external control of session ticket encryption - * key rotation, e.g. for synchronization between different - * machines. If this function is not used, or if not called - * before ticket lifetime expires, then a new session ticket - * encryption key is generated internally in order to avoid - * unbounded session ticket encryption key lifetimes. - * - * \param ctx Context to be set up - * \param name Session ticket encryption key name - * \param nlength Session ticket encryption key name length in bytes - * \param k Session ticket encryption key - * \param klength Session ticket encryption key length in bytes - * \param lifetime Tickets lifetime in seconds - * Recommended value: 86400 (one day). - * - * \note \c name and \c k are recommended to be cryptographically - * random data. - * - * \note \c nlength must match sizeof( ctx->name ) - * - * \note \c klength must be sufficient for use by cipher specified - * to \c mbedtls_ssl_ticket_setup - * - * \note It is recommended to pick a reasonable lifetime so as not - * to negate the benefits of forward secrecy. - * - * \note The TLS 1.3 specification states that ticket lifetime must - * be smaller than seven days. If ticket lifetime has been - * set to a value greater than seven days in this module then - * if the TLS 1.3 is configured to send tickets after the - * handshake it will fail the connection when trying to send - * the first ticket. - * - * \return 0 if successful, - * or a specific MBEDTLS_ERR_XXX error code - */ -int mbedtls_ssl_ticket_rotate(mbedtls_ssl_ticket_context *ctx, - const unsigned char *name, size_t nlength, - const unsigned char *k, size_t klength, - uint32_t lifetime); - -/** - * \brief Implementation of the ticket write callback - * - * \note See \c mbedtls_ssl_ticket_write_t for description - */ -mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write; - -/** - * \brief Implementation of the ticket parse callback - * - * \note See \c mbedtls_ssl_ticket_parse_t for description - */ -mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse; - -/** - * \brief Free a context's content and zeroize it. - * - * \param ctx Context to be cleaned up - */ -void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_ticket.h */ diff --git a/vendor/mbedtls/include/mbedtls/threading.h b/vendor/mbedtls/include/mbedtls/threading.h deleted file mode 100644 index 7b55a4649..000000000 --- a/vendor/mbedtls/include/mbedtls/threading.h +++ /dev/null @@ -1,167 +0,0 @@ -/** - * \file threading.h - * - * \brief Threading abstraction layer - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_THREADING_H -#define MBEDTLS_THREADING_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Bad input parameters to function. */ -#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C -/** Locking / unlocking / free failed with error code. */ -#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E - -#if defined(MBEDTLS_THREADING_PTHREAD) -#include -typedef struct mbedtls_threading_mutex_t { - pthread_mutex_t MBEDTLS_PRIVATE(mutex); - - /* WARNING - state should only be accessed when holding the mutex lock in - * framework/tests/src/threading_helpers.c, otherwise corruption can occur. - * state will be 0 after a failed init or a free, and nonzero after a - * successful init. This field is for testing only and thus not considered - * part of the public API of Mbed TLS and may change without notice.*/ - char MBEDTLS_PRIVATE(state); - -} mbedtls_threading_mutex_t; -#endif - -#if defined(MBEDTLS_THREADING_ALT) -/* You should define the mbedtls_threading_mutex_t type in your header */ -#include "threading_alt.h" - -/** - * \brief Set your alternate threading implementation function - * pointers and initialize global mutexes. If used, this - * function must be called once in the main thread before any - * other Mbed TLS function is called, and - * mbedtls_threading_free_alt() must be called once in the main - * thread after all other Mbed TLS functions. - * - * \warning \p mutex_init and \p mutex_free don't return a status code. - * If \p mutex_init fails, it should leave the mutex in - * a state such that \p mutex_lock will reliably return - * #MBEDTLS_ERR_THREADING_MUTEX_ERROR called on this mutex, - * and \p mutex_free will do nothing. - * - * \param mutex_init The init function implementation.
- * The behavior is undefined if the mutex is already - * initialized and has not been destroyed. - * On platforms where mutex initialization can fail, - * since this function does not return a status code, - * it must leave the mutex object in a safe state where - * subsequent function calls will not cause undefined - * behavior: after a call to \p mutex_init, the - * function \p mutex_lock must either succeed or - * fail with a nonzero status code, and the function - * \p mutex_free must free any resources associated - * with the mutex.. - * \param mutex_free The destroy function implementation.
- * This function must free any resources associated - * with the mutex object.
- * This function must work reliably if \p mutex_init - * has been called on the mutex and \p mutex_free - * has not yet been called.
- * The behavior is undefined if the mutex was not - * initialized, if it has already been destroyed, - * if it is currently locked, or if this function - * is called concurrently from multiple threads. - * \param mutex_lock The lock function implementation.
- * This function must work reliably on any mutex - * which is not currently locked and on which - * \p mutex_init has already been called but - * \p mutex_free has not been called yet.
- * The behavior is undefined if the mutex was not - * initialized, if it has already been destroyed, or if - * it is currently locked by the calling thread. - * \param mutex_unlock The unlock function implementation.
- * The behavior is undefined if the mutex is not - * currently locked by the calling thread. - */ -void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), - void (*mutex_free)(mbedtls_threading_mutex_t *), - int (*mutex_lock)(mbedtls_threading_mutex_t *), - int (*mutex_unlock)(mbedtls_threading_mutex_t *)); - -/** - * \brief Free global mutexes. - */ -void mbedtls_threading_free_alt(void); -#endif /* MBEDTLS_THREADING_ALT */ - -#if defined(MBEDTLS_THREADING_C) -/* - * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock - * - * All these functions are expected to work or the result will be undefined. - */ -extern void (*mbedtls_mutex_init)(mbedtls_threading_mutex_t *mutex); -extern void (*mbedtls_mutex_free)(mbedtls_threading_mutex_t *mutex); -extern int (*mbedtls_mutex_lock)(mbedtls_threading_mutex_t *mutex); -extern int (*mbedtls_mutex_unlock)(mbedtls_threading_mutex_t *mutex); - -/* - * Global mutexes - */ -#if defined(MBEDTLS_FS_IO) -extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; -#endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -/* This mutex may or may not be used in the default definition of - * mbedtls_platform_gmtime_r(), but in order to determine that, - * we need to check POSIX features, hence modify _POSIX_C_SOURCE. - * With the current approach, this declaration is orphaned, lacking - * an accompanying definition, in case mbedtls_platform_gmtime_r() - * doesn't need it, but that's not a problem. */ -extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#if defined(MBEDTLS_PSA_CRYPTO_C) -/* - * A mutex used to make the PSA subsystem thread safe. - * - * key_slot_mutex protects the registered_readers and - * state variable for all key slots in &global_data.key_slots. - * - * This mutex must be held when any read from or write to a state or - * registered_readers field is performed, i.e. when calling functions: - * psa_key_slot_state_transition(), psa_register_read(), psa_unregister_read(), - * psa_key_slot_has_readers() and psa_wipe_key_slot(). */ -extern mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex; - -/* - * A mutex used to make the non-rng PSA global_data struct members thread safe. - * - * This mutex must be held when reading or writing to any of the PSA global_data - * structure members, other than the rng_state or rng struct. */ -extern mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex; - -/* - * A mutex used to make the PSA global_data rng data thread safe. - * - * This mutex must be held when reading or writing to the PSA - * global_data rng_state or rng struct members. */ -extern mbedtls_threading_mutex_t mbedtls_threading_psa_rngdata_mutex; -#endif - -#endif /* MBEDTLS_THREADING_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* threading.h */ diff --git a/vendor/mbedtls/include/mbedtls/timing.h b/vendor/mbedtls/include/mbedtls/timing.h deleted file mode 100644 index 62ae1022d..000000000 --- a/vendor/mbedtls/include/mbedtls/timing.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * \file timing.h - * - * \brief Portable interface to timeouts and to the CPU cycle counter - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_TIMING_H -#define MBEDTLS_TIMING_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(MBEDTLS_TIMING_ALT) -// Regular implementation -// - -/** - * \brief timer structure - */ -struct mbedtls_timing_hr_time { - uint64_t MBEDTLS_PRIVATE(opaque)[4]; -}; - -/** - * \brief Context for mbedtls_timing_set/get_delay() - */ -typedef struct mbedtls_timing_delay_context { - struct mbedtls_timing_hr_time MBEDTLS_PRIVATE(timer); - uint32_t MBEDTLS_PRIVATE(int_ms); - uint32_t MBEDTLS_PRIVATE(fin_ms); -} mbedtls_timing_delay_context; - -#else /* MBEDTLS_TIMING_ALT */ -#include "timing_alt.h" -#endif /* MBEDTLS_TIMING_ALT */ - -/* Internal use */ -unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset); - -/** - * \brief Set a pair of delays to watch - * (See \c mbedtls_timing_get_delay().) - * - * \param data Pointer to timing data. - * Must point to a valid \c mbedtls_timing_delay_context struct. - * \param int_ms First (intermediate) delay in milliseconds. - * The effect if int_ms > fin_ms is unspecified. - * \param fin_ms Second (final) delay in milliseconds. - * Pass 0 to cancel the current delay. - * - * \note To set a single delay, either use \c mbedtls_timing_set_timer - * directly or use this function with int_ms == fin_ms. - */ -void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms); - -/** - * \brief Get the status of delays - * (Memory helper: number of delays passed.) - * - * \param data Pointer to timing data - * Must point to a valid \c mbedtls_timing_delay_context struct. - * - * \return -1 if cancelled (fin_ms = 0), - * 0 if none of the delays are passed, - * 1 if only the intermediate delay is passed, - * 2 if the final delay is passed. - */ -int mbedtls_timing_get_delay(void *data); - -/** - * \brief Get the final timing delay - * - * \param data Pointer to timing data - * Must point to a valid \c mbedtls_timing_delay_context struct. - * - * \return Final timing delay in milliseconds. - */ -uint32_t mbedtls_timing_get_final_delay( - const mbedtls_timing_delay_context *data); - -#ifdef __cplusplus -} -#endif - -#endif /* timing.h */ diff --git a/vendor/mbedtls/include/mbedtls/version.h b/vendor/mbedtls/include/mbedtls/version.h deleted file mode 100644 index 637f9d38b..000000000 --- a/vendor/mbedtls/include/mbedtls/version.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * \file version.h - * - * \brief Run-time version information - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * This set of run-time variables can be used to determine the version number of - * the Mbed TLS library used. Compile-time version defines for the same can be - * found in build_info.h - */ -#ifndef MBEDTLS_VERSION_H -#define MBEDTLS_VERSION_H - -#include "mbedtls/build_info.h" - -#if defined(MBEDTLS_VERSION_C) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Get the version number. - * - * \return The constructed version number in the format - * MMNNPP00 (Major, Minor, Patch). - */ -unsigned int mbedtls_version_get_number(void); - -/** - * Get the version string ("x.y.z"). - * - * \param string The string that will receive the value. - * (Should be at least 9 bytes in size) - */ -void mbedtls_version_get_string(char *string); - -/** - * Get the full version string ("Mbed TLS x.y.z"). - * - * \param string The string that will receive the value. The Mbed TLS version - * string will use 18 bytes AT MOST including a terminating - * null byte. - * (So the buffer should be at least 18 bytes to receive this - * version string). - */ -void mbedtls_version_get_string_full(char *string); - -/** - * \brief Check if support for a feature was compiled into this - * Mbed TLS binary. This allows you to see at runtime if the - * library was for instance compiled with or without - * Multi-threading support. - * - * \note only checks against defines in the sections "System - * support", "Mbed TLS modules" and "Mbed TLS feature - * support" in mbedtls_config.h - * - * \param feature The string for the define to check (e.g. "MBEDTLS_AES_C") - * - * \return 0 if the feature is present, - * -1 if the feature is not present and - * -2 if support for feature checking as a whole was not - * compiled in. - */ -int mbedtls_version_check_feature(const char *feature); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_VERSION_C */ - -#endif /* version.h */ diff --git a/vendor/mbedtls/include/mbedtls/x509.h b/vendor/mbedtls/include/mbedtls/x509.h deleted file mode 100644 index 6b104613d..000000000 --- a/vendor/mbedtls/include/mbedtls/x509.h +++ /dev/null @@ -1,500 +0,0 @@ -/** - * \file x509.h - * - * \brief X.509 generic defines and structures - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_X509_H -#define MBEDTLS_X509_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/asn1.h" -#include "mbedtls/pk.h" - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif - -/** - * \addtogroup x509_module - * \{ - */ - -#if !defined(MBEDTLS_X509_MAX_INTERMEDIATE_CA) -/** - * Maximum number of intermediate CAs in a verification chain. - * That is, maximum length of the chain, excluding the end-entity certificate - * and the trusted root certificate. - * - * Set this to a low value to prevent an adversary from making you waste - * resources verifying an overlong certificate chain. - */ -#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 -#endif - -/** - * \name X509 Error codes - * \{ - */ -/** Unavailable feature, e.g. RSA hashing/encryption combination. */ -#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -0x2080 -/** Requested OID is unknown. */ -#define MBEDTLS_ERR_X509_UNKNOWN_OID -0x2100 -/** The CRT/CRL/CSR format is invalid, e.g. different type expected. */ -#define MBEDTLS_ERR_X509_INVALID_FORMAT -0x2180 -/** The CRT/CRL/CSR version element is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_VERSION -0x2200 -/** The serial tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_SERIAL -0x2280 -/** The algorithm tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_ALG -0x2300 -/** The name tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_NAME -0x2380 -/** The date tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_DATE -0x2400 -/** The signature tag or value invalid. */ -#define MBEDTLS_ERR_X509_INVALID_SIGNATURE -0x2480 -/** The extension tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS -0x2500 -/** CRT/CRL/CSR has an unsupported version number. */ -#define MBEDTLS_ERR_X509_UNKNOWN_VERSION -0x2580 -/** Signature algorithm (oid) is unsupported. */ -#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -0x2600 -/** Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */ -#define MBEDTLS_ERR_X509_SIG_MISMATCH -0x2680 -/** Certificate verification failed, e.g. CRL, CA or signature check failed. */ -#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -0x2700 -/** Format not recognized as DER or PEM. */ -#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 -/** Input invalid. */ -#define MBEDTLS_ERR_X509_BAD_INPUT_DATA -0x2800 -/** Allocation of memory failed. */ -#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 -/** Read/write of file failed. */ -#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 -/** Destination buffer is too small. */ -#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 -/** A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ -#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 -/** \} name X509 Error codes */ - -/** - * \name X509 Verify codes - * \{ - */ -/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */ -#define MBEDTLS_X509_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */ -#define MBEDTLS_X509_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */ -#define MBEDTLS_X509_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */ -#define MBEDTLS_X509_BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */ -#define MBEDTLS_X509_BADCRL_NOT_TRUSTED 0x10 /**< The CRL is not correctly signed by the trusted CA. */ -#define MBEDTLS_X509_BADCRL_EXPIRED 0x20 /**< The CRL is expired. */ -#define MBEDTLS_X509_BADCERT_MISSING 0x40 /**< Certificate was missing. */ -#define MBEDTLS_X509_BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ -#define MBEDTLS_X509_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ -#define MBEDTLS_X509_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ -#define MBEDTLS_X509_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ -#define MBEDTLS_X509_BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */ -#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */ -#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */ -#define MBEDTLS_X509_BADCERT_BAD_MD 0x4000 /**< The certificate is signed with an unacceptable hash. */ -#define MBEDTLS_X509_BADCERT_BAD_PK 0x8000 /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ -#define MBEDTLS_X509_BADCERT_BAD_KEY 0x010000 /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */ -#define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */ -#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ -#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */ - -/** \} name X509 Verify codes */ -/** \} addtogroup x509_module */ - -/* - * X.509 v3 Subject Alternative Name types. - * otherName [0] OtherName, - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * iPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER - */ -#define MBEDTLS_X509_SAN_OTHER_NAME 0 -#define MBEDTLS_X509_SAN_RFC822_NAME 1 -#define MBEDTLS_X509_SAN_DNS_NAME 2 -#define MBEDTLS_X509_SAN_X400_ADDRESS_NAME 3 -#define MBEDTLS_X509_SAN_DIRECTORY_NAME 4 -#define MBEDTLS_X509_SAN_EDI_PARTY_NAME 5 -#define MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER 6 -#define MBEDTLS_X509_SAN_IP_ADDRESS 7 -#define MBEDTLS_X509_SAN_REGISTERED_ID 8 - -/* - * X.509 v3 Key Usage Extension flags - * Reminder: update mbedtls_x509_info_key_usage() when adding new flags. - */ -#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ -#define MBEDTLS_X509_KU_NON_REPUDIATION (0x40) /* bit 1 */ -#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ -#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ -#define MBEDTLS_X509_KU_KEY_AGREEMENT (0x08) /* bit 4 */ -#define MBEDTLS_X509_KU_KEY_CERT_SIGN (0x04) /* bit 5 */ -#define MBEDTLS_X509_KU_CRL_SIGN (0x02) /* bit 6 */ -#define MBEDTLS_X509_KU_ENCIPHER_ONLY (0x01) /* bit 7 */ -#define MBEDTLS_X509_KU_DECIPHER_ONLY (0x8000) /* bit 8 */ - -/* - * Netscape certificate types - * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html) - */ - -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ -#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ -#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ -#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ -#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ -#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ - -/* - * X.509 extension types - * - * Comments refer to the status for using certificates. Status can be - * different for writing certificates or reading CRLs or CSRs. - * - * Those are defined in oid.h as oid.c needs them in a data structure. Since - * these were previously defined here, let's have aliases for compatibility. - */ -#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER -#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER -#define MBEDTLS_X509_EXT_KEY_USAGE MBEDTLS_OID_X509_EXT_KEY_USAGE -#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES -#define MBEDTLS_X509_EXT_POLICY_MAPPINGS MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS -#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME /* Supported (DNS) */ -#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME -#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS -#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS /* Supported */ -#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS -#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS -#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE -#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS -#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY -#define MBEDTLS_X509_EXT_FRESHEST_CRL MBEDTLS_OID_X509_EXT_FRESHEST_CRL -#define MBEDTLS_X509_EXT_NS_CERT_TYPE MBEDTLS_OID_X509_EXT_NS_CERT_TYPE - -/* - * Storage format identifiers - * Recognized formats: PEM and DER - */ -#define MBEDTLS_X509_FORMAT_DER 1 -#define MBEDTLS_X509_FORMAT_PEM 2 - -#define MBEDTLS_X509_MAX_DN_NAME_SIZE 256 /**< Maximum value size of a DN entry */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures for parsing X.509 certificates, CRLs and CSRs - * \{ - */ - -/** - * Type-length-value structure that allows for ASN1 using DER. - */ -typedef mbedtls_asn1_buf mbedtls_x509_buf; - -/** - * Container for ASN1 bit strings. - */ -typedef mbedtls_asn1_bitstring mbedtls_x509_bitstring; - -/** - * Container for ASN1 named information objects. - * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.). - */ -typedef mbedtls_asn1_named_data mbedtls_x509_name; - -/** - * Container for a sequence of ASN.1 items - */ -typedef mbedtls_asn1_sequence mbedtls_x509_sequence; - -/* - * Container for the fields of the Authority Key Identifier object - */ -typedef struct mbedtls_x509_authority { - mbedtls_x509_buf keyIdentifier; - mbedtls_x509_sequence authorityCertIssuer; - mbedtls_x509_buf authorityCertSerialNumber; - mbedtls_x509_buf raw; -} -mbedtls_x509_authority; - -/** Container for date and time (precision in seconds). */ -typedef struct mbedtls_x509_time { - int year, mon, day; /**< Date. */ - int hour, min, sec; /**< Time. */ -} -mbedtls_x509_time; - -/** - * From RFC 5280 section 4.2.1.6: - * OtherName ::= SEQUENCE { - * type-id OBJECT IDENTIFIER, - * value [0] EXPLICIT ANY DEFINED BY type-id } - * - * Future versions of the library may add new fields to this structure or - * to its embedded union and structure. - */ -typedef struct mbedtls_x509_san_other_name { - /** - * The type_id is an OID as defined in RFC 5280. - * To check the value of the type id, you should use - * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf. - */ - mbedtls_x509_buf type_id; /**< The type id. */ - union { - /** - * From RFC 4108 section 5: - * HardwareModuleName ::= SEQUENCE { - * hwType OBJECT IDENTIFIER, - * hwSerialNum OCTET STRING } - */ - struct { - mbedtls_x509_buf oid; /**< The object identifier. */ - mbedtls_x509_buf val; /**< The named value. */ - } - hardware_module_name; - } - value; -} -mbedtls_x509_san_other_name; - -/** - * A structure for holding the parsed Subject Alternative Name, - * according to type. - * - * Future versions of the library may add new fields to this structure or - * to its embedded union and structure. - */ -typedef struct mbedtls_x509_subject_alternative_name { - int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */ - union { - mbedtls_x509_san_other_name other_name; - mbedtls_x509_name directory_name; - mbedtls_x509_buf unstructured_name; /**< The buffer for the unstructured types. rfc822Name, dnsName and uniformResourceIdentifier are currently supported. */ - } - san; /**< A union of the supported SAN types */ -} -mbedtls_x509_subject_alternative_name; - -typedef struct mbedtls_x509_san_list { - mbedtls_x509_subject_alternative_name node; - struct mbedtls_x509_san_list *next; -} -mbedtls_x509_san_list; - -/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */ -/** \} addtogroup x509_module */ - -/** - * \brief Store the certificate DN in printable form into buf; - * no more than size characters will be written. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param dn The X509 name to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn); - -/** - * \brief Convert the certificate DN string \p name into - * a linked list of mbedtls_x509_name (equivalent to - * mbedtls_asn1_named_data). - * - * \note This function allocates a linked list, and places the head - * pointer in \p head. This list must later be freed by a - * call to mbedtls_asn1_free_named_data_list(). - * - * \param[out] head Address in which to store the pointer to the head of the - * allocated list of mbedtls_x509_name. Must point to NULL on - * entry. - * \param[in] name The string representation of a DN to convert - * - * \return 0 on success, or a negative error code. - */ -int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name); - -/** - * \brief Return the next relative DN in an X509 name. - * - * \note Intended use is to compare function result to dn->next - * in order to detect boundaries of multi-valued RDNs. - * - * \param dn Current node in the X509 name - * - * \return Pointer to the first attribute-value pair of the - * next RDN in sequence, or NULL if end is reached. - */ -static inline mbedtls_x509_name *mbedtls_x509_dn_get_next( - mbedtls_x509_name *dn) -{ - while (dn->MBEDTLS_PRIVATE(next_merged) && dn->next != NULL) { - dn = dn->next; - } - return dn->next; -} - -/** - * \brief Store the certificate serial in printable form into buf; - * no more than size characters will be written. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param serial The X509 serial to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial); - -/** - * \brief Compare pair of mbedtls_x509_time. - * - * \param t1 mbedtls_x509_time to compare - * \param t2 mbedtls_x509_time to compare - * - * \return < 0 if t1 is before t2 - * 0 if t1 equals t2 - * > 0 if t1 is after t2 - */ -int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, const mbedtls_x509_time *t2); - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/** - * \brief Fill mbedtls_x509_time with provided mbedtls_time_t. - * - * \param tt mbedtls_time_t to convert - * \param now mbedtls_x509_time to fill with converted mbedtls_time_t - * - * \return \c 0 on success - * \return A non-zero return value on failure. - */ -int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now); -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the past. - * - * \note Intended usage is "if( is_past( valid_to ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param to mbedtls_x509_time to check - * - * \return 1 if the given time is in the past or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_past(const mbedtls_x509_time *to); - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the future. - * - * \note Intended usage is "if( is_future( valid_from ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param from mbedtls_x509_time to check - * - * \return 1 if the given time is in the future or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_future(const mbedtls_x509_time *from); - -/** - * \brief This function parses an item in the SubjectAlternativeNames - * extension. Please note that this function might allocate - * additional memory for a subject alternative name, thus - * mbedtls_x509_free_subject_alt_name has to be called - * to dispose of this additional memory afterwards. - * - * \param san_buf The buffer holding the raw data item of the subject - * alternative name. - * \param san The target structure to populate with the parsed presentation - * of the subject alternative name encoded in \p san_buf. - * - * \note Supported GeneralName types, as defined in RFC 5280: - * "rfc822Name", "dnsName", "directoryName", - * "uniformResourceIdentifier" and "hardware_module_name" - * of type "otherName", as defined in RFC 4108. - * - * \note This function should be called on a single raw data of - * subject alternative name. For example, after successful - * certificate parsing, one must iterate on every item in the - * \c crt->subject_alt_names sequence, and pass it to - * this function. - * - * \warning The target structure contains pointers to the raw data of the - * parsed certificate, and its lifetime is restricted by the - * lifetime of the certificate. - * - * \return \c 0 on success - * \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported - * SAN type. - * \return Another negative value for any other failure. - */ -int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, - mbedtls_x509_subject_alternative_name *san); -/** - * \brief Unallocate all data related to subject alternative name - * - * \param san SAN structure - extra memory owned by this structure will be freed - */ -void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san); - -/** - * \brief This function parses a CN string as an IP address. - * - * \param cn The CN string to parse. CN string MUST be null-terminated. - * \param dst The target buffer to populate with the binary IP address. - * The buffer MUST be 16 bytes to save IPv6, and should be - * 4-byte aligned if the result will be used as struct in_addr. - * e.g. uint32_t dst[4] - * - * \note \p cn is parsed as an IPv6 address if string contains ':', - * else \p cn is parsed as an IPv4 address. - * - * \return Length of binary IP address; num bytes written to target. - * \return \c 0 on failure to parse CN string as an IP address. - */ -size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst); - -#define MBEDTLS_X509_SAFE_SNPRINTF \ - do { \ - if (ret < 0 || (size_t) ret >= n) \ - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; \ - \ - n -= (size_t) ret; \ - p += (size_t) ret; \ - } while (0) - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_X509_H */ diff --git a/vendor/mbedtls/include/mbedtls/x509_crl.h b/vendor/mbedtls/include/mbedtls/x509_crl.h deleted file mode 100644 index 6625a44f4..000000000 --- a/vendor/mbedtls/include/mbedtls/x509_crl.h +++ /dev/null @@ -1,184 +0,0 @@ -/** - * \file x509_crl.h - * - * \brief X.509 certificate revocation list parsing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_X509_CRL_H -#define MBEDTLS_X509_CRL_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures and functions for parsing CRLs - * \{ - */ - -/** - * Certificate revocation list entry. - * Contains the CA-specific serial numbers and revocation dates. - * - * Some fields of this structure are publicly readable. Do not modify - * them except via Mbed TLS library functions: the effect of modifying - * those fields or the data that those fields points to is unspecified. - */ -typedef struct mbedtls_x509_crl_entry { - /** Direct access to the whole entry inside the containing buffer. */ - mbedtls_x509_buf raw; - /** The serial number of the revoked certificate. */ - mbedtls_x509_buf serial; - /** The revocation date of this entry. */ - mbedtls_x509_time revocation_date; - /** Direct access to the list of CRL entry extensions - * (an ASN.1 constructed sequence). - * - * If there are no extensions, `entry_ext.len == 0` and - * `entry_ext.p == NULL`. */ - mbedtls_x509_buf entry_ext; - - /** Next element in the linked list of entries. - * \p NULL indicates the end of the list. - * Do not modify this field directly. */ - struct mbedtls_x509_crl_entry *next; -} -mbedtls_x509_crl_entry; - -/** - * Certificate revocation list structure. - * Every CRL may have multiple entries. - */ -typedef struct mbedtls_x509_crl { - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ - mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - - int version; /**< CRL version (1=v1, 2=v2) */ - mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */ - - mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */ - - mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ - - mbedtls_x509_time this_update; - mbedtls_x509_time next_update; - - mbedtls_x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */ - - mbedtls_x509_buf crl_ext; - - mbedtls_x509_buf MBEDTLS_PRIVATE(sig_oid2); - mbedtls_x509_buf MBEDTLS_PRIVATE(sig); - mbedtls_md_type_t MBEDTLS_PRIVATE(sig_md); /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk); /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *MBEDTLS_PRIVATE(sig_opts); /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - /** Next element in the linked list of CRL. - * \p NULL indicates the end of the list. - * Do not modify this field directly. */ - struct mbedtls_x509_crl *next; -} -mbedtls_x509_crl; - -/** - * \brief Parse a DER-encoded CRL and append it to the chained list - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain points to the start of the chain - * \param buf buffer holding the CRL data in DER format - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse_der(mbedtls_x509_crl *chain, - const unsigned char *buf, size_t buflen); -/** - * \brief Parse one or more CRLs and append them to the chained list - * - * \note Multiple CRLs are accepted only if using PEM format - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain points to the start of the chain - * \param buf buffer holding the CRL data in PEM or DER format - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load one or more CRLs and append them to the chained list - * - * \note Multiple CRLs are accepted only if using PEM format - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain points to the start of the chain - * \param path filename to read the CRLs from (in PEM or DER encoding) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path); -#endif /* MBEDTLS_FS_IO */ - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -/** - * \brief Returns an informational string about the CRL. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param crl The X509 CRL to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix, - const mbedtls_x509_crl *crl); -#endif /* !MBEDTLS_X509_REMOVE_INFO */ - -/** - * \brief Initialize a CRL (chain) - * - * \param crl CRL chain to initialize - */ -void mbedtls_x509_crl_init(mbedtls_x509_crl *crl); - -/** - * \brief Unallocate all CRL data - * - * \param crl CRL chain to free - */ -void mbedtls_x509_crl_free(mbedtls_x509_crl *crl); - -/** \} name Structures and functions for parsing CRLs */ -/** \} addtogroup x509_module */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_crl.h */ diff --git a/vendor/mbedtls/include/mbedtls/x509_crt.h b/vendor/mbedtls/include/mbedtls/x509_crt.h deleted file mode 100644 index 6b9603959..000000000 --- a/vendor/mbedtls/include/mbedtls/x509_crt.h +++ /dev/null @@ -1,1208 +0,0 @@ -/** - * \file x509_crt.h - * - * \brief X.509 certificate parsing and writing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_X509_CRT_H -#define MBEDTLS_X509_CRT_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/x509.h" -#include "mbedtls/x509_crl.h" -#include "mbedtls/bignum.h" - -/** - * \addtogroup x509_module - * \{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Structures and functions for parsing and writing X.509 certificates - * \{ - */ - -/** - * Container for an X.509 certificate. The certificate may be chained. - * - * Some fields of this structure are publicly readable. Do not modify - * them except via Mbed TLS library functions: the effect of modifying - * those fields or the data that those fields points to is unspecified. - */ -typedef struct mbedtls_x509_crt { - int MBEDTLS_PRIVATE(own_buffer); /**< Indicates if \c raw is owned - * by the structure or not. */ - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ - mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - - int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ - mbedtls_x509_buf serial; /**< Unique id for certificate issued by a specific CA. */ - mbedtls_x509_buf sig_oid; /**< Signature algorithm, e.g. sha1RSA */ - - mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ - mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ - - mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ - mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ - - mbedtls_x509_time valid_from; /**< Start time of certificate validity. */ - mbedtls_x509_time valid_to; /**< End time of certificate validity. */ - - mbedtls_x509_buf pk_raw; - mbedtls_pk_context pk; /**< Container for the public key context. */ - - mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ - mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ - mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ - mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension. These can be later parsed by mbedtls_x509_parse_subject_alt_name. */ - mbedtls_x509_buf subject_key_id; /**< Optional X.509 v3 extension subject key identifier. */ - mbedtls_x509_authority authority_key_id; /**< Optional X.509 v3 extension authority key identifier. */ - - mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */ - - int MBEDTLS_PRIVATE(ext_types); /**< Bit string containing detected and parsed extensions */ - int MBEDTLS_PRIVATE(ca_istrue); /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ - int MBEDTLS_PRIVATE(max_pathlen); /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */ - - unsigned int MBEDTLS_PRIVATE(key_usage); /**< Optional key usage extension value: See the values in x509.h */ - - mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ - - unsigned char MBEDTLS_PRIVATE(ns_cert_type); /**< Optional Netscape certificate type extension value: See the values in x509.h */ - - mbedtls_x509_buf MBEDTLS_PRIVATE(sig); /**< Signature: hash of the tbs part signed with the private key. */ - mbedtls_md_type_t MBEDTLS_PRIVATE(sig_md); /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk); /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *MBEDTLS_PRIVATE(sig_opts); /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - /** Next certificate in the linked list that constitutes the CA chain. - * \p NULL indicates the end of the list. - * Do not modify this field directly. */ - struct mbedtls_x509_crt *next; -} -mbedtls_x509_crt; - -/** - * Build flag from an algorithm/curve identifier (pk, md, ecp) - * Since 0 is always XXX_NONE, ignore it. - */ -#define MBEDTLS_X509_ID_FLAG(id) (1 << ((id) - 1)) - -/** - * Security profile for certificate verification. - * - * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). - * - * The fields of this structure are part of the public API and can be - * manipulated directly by applications. Future versions of the library may - * add extra fields or reorder existing fields. - * - * You can create custom profiles by starting from a copy of - * an existing profile, such as mbedtls_x509_crt_profile_default or - * mbedtls_x509_ctr_profile_none and then tune it to your needs. - * - * For example to allow SHA-224 in addition to the default: - * - * mbedtls_x509_crt_profile my_profile = mbedtls_x509_crt_profile_default; - * my_profile.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ); - * - * Or to allow only RSA-3072+ with SHA-256: - * - * mbedtls_x509_crt_profile my_profile = mbedtls_x509_crt_profile_none; - * my_profile.allowed_mds = MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ); - * my_profile.allowed_pks = MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_RSA ); - * my_profile.rsa_min_bitlen = 3072; - */ -typedef struct mbedtls_x509_crt_profile { - uint32_t allowed_mds; /**< MDs for signatures */ - uint32_t allowed_pks; /**< PK algs for public keys; - * this applies to all certificates - * in the provided chain. */ - uint32_t allowed_curves; /**< Elliptic curves for ECDSA */ - uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */ -} -mbedtls_x509_crt_profile; - -#define MBEDTLS_X509_CRT_VERSION_1 0 -#define MBEDTLS_X509_CRT_VERSION_2 1 -#define MBEDTLS_X509_CRT_VERSION_3 2 - -#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 20 -#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 - -#if !defined(MBEDTLS_X509_MAX_FILE_PATH_LEN) -#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 -#endif - -/* This macro unfolds to the concatenation of macro invocations - * X509_CRT_ERROR_INFO( error code, - * error code as string, - * human readable description ) - * where X509_CRT_ERROR_INFO is defined by the user. - * See x509_crt.c for an example of how to use this. */ -#define MBEDTLS_X509_CRT_ERROR_INFO_LIST \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_EXPIRED, \ - "MBEDTLS_X509_BADCERT_EXPIRED", \ - "The certificate validity has expired") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_REVOKED, \ - "MBEDTLS_X509_BADCERT_REVOKED", \ - "The certificate has been revoked (is on a CRL)") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_CN_MISMATCH, \ - "MBEDTLS_X509_BADCERT_CN_MISMATCH", \ - "The certificate Common Name (CN) does not match with the expected CN") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_NOT_TRUSTED, \ - "MBEDTLS_X509_BADCERT_NOT_TRUSTED", \ - "The certificate is not correctly signed by the trusted CA") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCRL_NOT_TRUSTED, \ - "MBEDTLS_X509_BADCRL_NOT_TRUSTED", \ - "The CRL is not correctly signed by the trusted CA") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCRL_EXPIRED, \ - "MBEDTLS_X509_BADCRL_EXPIRED", \ - "The CRL is expired") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_MISSING, \ - "MBEDTLS_X509_BADCERT_MISSING", \ - "Certificate was missing") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_SKIP_VERIFY, \ - "MBEDTLS_X509_BADCERT_SKIP_VERIFY", \ - "Certificate verification was skipped") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_OTHER, \ - "MBEDTLS_X509_BADCERT_OTHER", \ - "Other reason (can be used by verify callback)") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_FUTURE, \ - "MBEDTLS_X509_BADCERT_FUTURE", \ - "The certificate validity starts in the future") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCRL_FUTURE, \ - "MBEDTLS_X509_BADCRL_FUTURE", \ - "The CRL is from the future") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_KEY_USAGE, \ - "MBEDTLS_X509_BADCERT_KEY_USAGE", \ - "Usage does not match the keyUsage extension") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, \ - "MBEDTLS_X509_BADCERT_EXT_KEY_USAGE", \ - "Usage does not match the extendedKeyUsage extension") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_NS_CERT_TYPE, \ - "MBEDTLS_X509_BADCERT_NS_CERT_TYPE", \ - "Usage does not match the nsCertType extension") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_BAD_MD, \ - "MBEDTLS_X509_BADCERT_BAD_MD", \ - "The certificate is signed with an unacceptable hash.") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_BAD_PK, \ - "MBEDTLS_X509_BADCERT_BAD_PK", \ - "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA).") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCERT_BAD_KEY, \ - "MBEDTLS_X509_BADCERT_BAD_KEY", \ - "The certificate is signed with an unacceptable key (eg bad curve, RSA too short).") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCRL_BAD_MD, \ - "MBEDTLS_X509_BADCRL_BAD_MD", \ - "The CRL is signed with an unacceptable hash.") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCRL_BAD_PK, \ - "MBEDTLS_X509_BADCRL_BAD_PK", \ - "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA).") \ - X509_CRT_ERROR_INFO(MBEDTLS_X509_BADCRL_BAD_KEY, \ - "MBEDTLS_X509_BADCRL_BAD_KEY", \ - "The CRL is signed with an unacceptable key (eg bad curve, RSA too short).") - -/** - * Container for writing a certificate (CRT) - */ -typedef struct mbedtls_x509write_cert { - int MBEDTLS_PRIVATE(version); - unsigned char MBEDTLS_PRIVATE(serial)[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN]; - size_t MBEDTLS_PRIVATE(serial_len); - mbedtls_pk_context *MBEDTLS_PRIVATE(subject_key); - mbedtls_pk_context *MBEDTLS_PRIVATE(issuer_key); - mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject); - mbedtls_asn1_named_data *MBEDTLS_PRIVATE(issuer); - mbedtls_md_type_t MBEDTLS_PRIVATE(md_alg); - char MBEDTLS_PRIVATE(not_before)[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; - char MBEDTLS_PRIVATE(not_after)[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; - mbedtls_asn1_named_data *MBEDTLS_PRIVATE(extensions); -} -mbedtls_x509write_cert; - -/** - * \brief Set Subject Alternative Name - * - * \param ctx Certificate context to use - * \param san_list List of SAN values - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - * - * \note "dnsName", "uniformResourceIdentifier", "IP address", - * "otherName", and "DirectoryName", as defined in RFC 5280, - * are supported. - */ -int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx, - const mbedtls_x509_san_list *san_list); - -/** - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *MBEDTLS_PRIVATE(crt); - uint32_t MBEDTLS_PRIVATE(flags); -} mbedtls_x509_crt_verify_chain_item; - -/** - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE (MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2) - -/** - * Verification chain as built by \c mbedtls_crt_verify_chain() - */ -typedef struct { - mbedtls_x509_crt_verify_chain_item MBEDTLS_PRIVATE(items)[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE]; - unsigned MBEDTLS_PRIVATE(len); - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - /* This stores the list of potential trusted signers obtained from - * the CA callback used for the CRT verification, if configured. - * We must track it somewhere because the callback passes its - * ownership to the caller. */ - mbedtls_x509_crt *MBEDTLS_PRIVATE(trust_ca_cb_result); -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -} mbedtls_x509_crt_verify_chain; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Context for resuming X.509 verify operations - */ -typedef struct { - /* for check_signature() */ - mbedtls_pk_restart_ctx MBEDTLS_PRIVATE(pk); - - /* for find_parent_in() */ - mbedtls_x509_crt *MBEDTLS_PRIVATE(parent); /* non-null iff parent_in in progress */ - mbedtls_x509_crt *MBEDTLS_PRIVATE(fallback_parent); - int MBEDTLS_PRIVATE(fallback_signature_is_good); - - /* for find_parent() */ - int MBEDTLS_PRIVATE(parent_is_trusted); /* -1 if find_parent is not in progress */ - - /* for verify_chain() */ - enum { - x509_crt_rs_none, - x509_crt_rs_find_parent, - } MBEDTLS_PRIVATE(in_progress); /* none if no operation is in progress */ - int MBEDTLS_PRIVATE(self_cnt); - mbedtls_x509_crt_verify_chain MBEDTLS_PRIVATE(ver_chain); - -} mbedtls_x509_crt_restart_ctx; - -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_x509_crt_restart_ctx; - -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * Default security profile. Should provide a good balance between security - * and compatibility with current deployments. - * - * This profile permits: - * - SHA2 hashes with at least 256 bits: SHA-256, SHA-384, SHA-512. - * - Elliptic curves with 255 bits and above except secp256k1. - * - RSA with 2048 bits and above. - * - * New minor versions of Mbed TLS may extend this profile, for example if - * new algorithms are added to the library. New minor versions of Mbed TLS will - * not reduce this profile unless serious security concerns require it. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default; - -/** - * Expected next default profile. Recommended for new deployments. - * Currently targets a 128-bit security level, except for allowing RSA-2048. - * This profile may change at any time. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next; - -/** - * NSA Suite B profile. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb; - -/** - * Empty profile that allows nothing. Useful as a basis for constructing - * custom profiles. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none; - -/** - * \brief Parse a single DER formatted certificate and add it - * to the end of the provided chained list. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain The pointer to the start of the CRT chain to attach to. - * When parsing the first CRT in a chain, this should point - * to an instance of ::mbedtls_x509_crt initialized through - * mbedtls_x509_crt_init(). - * \param buf The buffer holding the DER encoded certificate. - * \param buflen The size in Bytes of \p buf. - * - * \note This function makes an internal copy of the CRT buffer - * \p buf. In particular, \p buf may be destroyed or reused - * after this call returns. To avoid duplicating the CRT - * buffer (at the cost of stricter lifetime constraints), - * use mbedtls_x509_crt_parse_der_nocopy() instead. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_parse_der(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen); - -/** - * \brief The type of certificate extension callbacks. - * - * Callbacks of this type are passed to and used by the - * mbedtls_x509_crt_parse_der_with_ext_cb() routine when - * it encounters either an unsupported extension or a - * "certificate policies" extension containing any - * unsupported certificate policies. - * Future versions of the library may invoke the callback - * in other cases, if and when the need arises. - * - * \param p_ctx An opaque context passed to the callback. - * \param crt The certificate being parsed. - * \param oid The OID of the extension. - * \param critical Whether the extension is critical. - * \param p Pointer to the start of the extension value - * (the content of the OCTET STRING). - * \param end End of extension value. - * - * \note The callback must fail and return a negative error code - * if it can not parse or does not support the extension. - * When the callback fails to parse a critical extension - * mbedtls_x509_crt_parse_der_with_ext_cb() also fails. - * When the callback fails to parse a non critical extension - * mbedtls_x509_crt_parse_der_with_ext_cb() simply skips - * the extension and continues parsing. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -typedef int (*mbedtls_x509_crt_ext_cb_t)(void *p_ctx, - mbedtls_x509_crt const *crt, - mbedtls_x509_buf const *oid, - int critical, - const unsigned char *p, - const unsigned char *end); - -/** - * \brief Parse a single DER formatted certificate and add it - * to the end of the provided chained list. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain The pointer to the start of the CRT chain to attach to. - * When parsing the first CRT in a chain, this should point - * to an instance of ::mbedtls_x509_crt initialized through - * mbedtls_x509_crt_init(). - * \param buf The buffer holding the DER encoded certificate. - * \param buflen The size in Bytes of \p buf. - * \param make_copy When not zero this function makes an internal copy of the - * CRT buffer \p buf. In particular, \p buf may be destroyed - * or reused after this call returns. - * When zero this function avoids duplicating the CRT buffer - * by taking temporary ownership thereof until the CRT - * is destroyed (like mbedtls_x509_crt_parse_der_nocopy()) - * \param cb A callback invoked for every unsupported certificate - * extension. - * \param p_ctx An opaque context passed to the callback. - * - * \note This call is functionally equivalent to - * mbedtls_x509_crt_parse_der(), and/or - * mbedtls_x509_crt_parse_der_nocopy() - * but it calls the callback with every unsupported - * certificate extension and additionally the - * "certificate policies" extension if it contains any - * unsupported certificate policies. - * The callback must return a negative error code if it - * does not know how to handle such an extension. - * When the callback fails to parse a critical extension - * mbedtls_x509_crt_parse_der_with_ext_cb() also fails. - * When the callback fails to parse a non critical extension - * mbedtls_x509_crt_parse_der_with_ext_cb() simply skips - * the extension and continues parsing. - * Future versions of the library may invoke the callback - * in other cases, if and when the need arises. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_parse_der_with_ext_cb(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen, - int make_copy, - mbedtls_x509_crt_ext_cb_t cb, - void *p_ctx); - -/** - * \brief Parse a single DER formatted certificate and add it - * to the end of the provided chained list. This is a - * variant of mbedtls_x509_crt_parse_der() which takes - * temporary ownership of the CRT buffer until the CRT - * is destroyed. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain The pointer to the start of the CRT chain to attach to. - * When parsing the first CRT in a chain, this should point - * to an instance of ::mbedtls_x509_crt initialized through - * mbedtls_x509_crt_init(). - * \param buf The address of the readable buffer holding the DER encoded - * certificate to use. On success, this buffer must be - * retained and not be changed for the lifetime of the - * CRT chain \p chain, that is, until \p chain is destroyed - * through a call to mbedtls_x509_crt_free(). - * \param buflen The size in Bytes of \p buf. - * - * \note This call is functionally equivalent to - * mbedtls_x509_crt_parse_der(), but it avoids creating a - * copy of the input buffer at the cost of stronger lifetime - * constraints. This is useful in constrained environments - * where duplication of the CRT cannot be tolerated. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_parse_der_nocopy(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen); - -/** - * \brief Parse one DER-encoded or one or more concatenated PEM-encoded - * certificates and add them to the chained list. - * - * For CRTs in PEM encoding, the function parses permissively: - * if at least one certificate can be parsed, the function - * returns the number of certificates for which parsing failed - * (hence \c 0 if all certificates were parsed successfully). - * If no certificate could be parsed, the function returns - * the first (negative) error encountered during parsing. - * - * PEM encoded certificates may be interleaved by other data - * such as human readable descriptions of their content, as - * long as the certificates are enclosed in the PEM specific - * '-----{BEGIN/END} CERTIFICATE-----' delimiters. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain The chain to which to add the parsed certificates. - * \param buf The buffer holding the certificate data in PEM or DER format. - * For certificates in PEM encoding, this may be a concatenation - * of multiple certificates; for DER encoding, the buffer must - * comprise exactly one certificate. - * \param buflen The size of \p buf, including the terminating \c NULL byte - * in case of PEM encoded data. - * - * \return \c 0 if all certificates were parsed successfully. - * \return The (positive) number of certificates that couldn't - * be parsed if parsing was partly successful (see above). - * \return A negative X509 or PEM error code otherwise. - * - */ -int mbedtls_x509_crt_parse(mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load one or more certificates and add them - * to the chained list. Parses permissively. If some - * certificates can be parsed, the result is the number - * of failed certificates it encountered. If none complete - * correctly, the first error is returned. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param chain points to the start of the chain - * \param path filename to read the certificates from - * - * \return 0 if all certificates parsed successfully, a positive number - * if partly successful or a specific X509 or PEM error code - */ -int mbedtls_x509_crt_parse_file(mbedtls_x509_crt *chain, const char *path); - -/** - * \brief Load one or more certificate files from a path and add them - * to the chained list. Parses permissively. If some - * certificates can be parsed, the result is the number - * of failed certificates it encountered. If none complete - * correctly, the first error is returned. - * - * \param chain points to the start of the chain - * \param path directory / folder to read the certificate files from - * - * \return 0 if all certificates parsed successfully, a positive number - * if partly successful or a specific X509 or PEM error code - */ -int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path); - -#endif /* MBEDTLS_FS_IO */ - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -/** - * \brief Returns an informational string about the - * certificate. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param crt The X509 certificate to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt); - -/** - * \brief Returns an informational string about the - * verification status of a certificate. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param flags Verification flags created by mbedtls_x509_crt_verify() - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crt_verify_info(char *buf, size_t size, const char *prefix, - uint32_t flags); -#endif /* !MBEDTLS_X509_REMOVE_INFO */ - -/** - * \brief Verify a chain of certificates. - * - * The verify callback is a user-supplied callback that - * can clear / modify / add flags for a certificate. If set, - * the verification callback is called for each - * certificate in the chain (from the trust-ca down to the - * presented crt). The parameters for the callback are: - * (void *parameter, mbedtls_x509_crt *crt, int certificate_depth, - * int *flags). With the flags representing current flags for - * that specific certificate and the certificate depth from - * the bottom (Peer cert depth = 0). - * - * All flags left after returning from the callback - * are also returned to the application. The function should - * return 0 for anything (including invalid certificates) - * other than fatal error, as a non-zero return code - * immediately aborts the verification process. For fatal - * errors, a specific error code should be used (different - * from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not - * be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR - * can be used if no better code is available. - * - * \note In case verification failed, the results can be displayed - * using \c mbedtls_x509_crt_verify_info() - * - * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the - * default security profile. - * - * \note It is your responsibility to provide up-to-date CRLs for - * all trusted CAs. If no CRL is provided for the CA that was - * used to sign the certificate, CRL verification is skipped - * silently, that is *without* setting any flag. - * - * \note The \c trust_ca list can contain two types of certificates: - * (1) those of trusted root CAs, so that certificates - * chaining up to those CAs will be trusted, and (2) - * self-signed end-entity certificates to be trusted (for - * specific peers you know) - in that case, the self-signed - * certificate doesn't need to have the CA bit set. - * - * \param crt The certificate chain to be verified. - * \param trust_ca The list of trusted CAs. - * \param ca_crl The list of CRLs for trusted CAs. - * \param cn The expected Common Name. This will be checked to be - * present in the certificate's subjectAltNames extension or, - * if this extension is absent, as a CN component in its - * Subject name. DNS names and IP addresses are fully - * supported, while the URI subtype is partially supported: - * only exact matching, without any normalization procedures - * described in 7.4 of RFC5280, will result in a positive - * URI verification. - * This may be \c NULL if the CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * - * \return \c 0 if the chain is valid with respect to the - * passed CN, CAs, CRLs and security profile. - * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the - * certificate chain verification failed. In this case, - * \c *flags will have one or more - * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX - * flags set. - * \return Another negative error code in case of a fatal error - * encountered during the verification process. - */ -int mbedtls_x509_crt_verify(mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy); - -/** - * \brief Verify a chain of certificates with respect to - * a configurable security profile. - * - * \note Same as \c mbedtls_x509_crt_verify(), but with explicit - * security profile. - * - * \note The restrictions on keys (RSA minimum size, allowed curves - * for ECDSA) apply to all certificates: trusted root, - * intermediate CAs if any, and end entity certificate. - * - * \param crt The certificate chain to be verified. - * \param trust_ca The list of trusted CAs. - * \param ca_crl The list of CRLs for trusted CAs. - * \param profile The security profile to use for the verification. - * \param cn The expected Common Name. This may be \c NULL if the - * CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * - * \return \c 0 if the chain is valid with respect to the - * passed CN, CAs, CRLs and security profile. - * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the - * certificate chain verification failed. In this case, - * \c *flags will have one or more - * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX - * flags set. - * \return Another negative error code in case of a fatal error - * encountered during the verification process. - */ -int mbedtls_x509_crt_verify_with_profile(mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy); - -/** - * \brief Restartable version of \c mbedtls_crt_verify_with_profile() - * - * \note Performs the same job as \c mbedtls_crt_verify_with_profile() - * but can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param crt The certificate chain to be verified. - * \param trust_ca The list of trusted CAs. - * \param ca_crl The list of CRLs for trusted CAs. - * \param profile The security profile to use for the verification. - * \param cn The expected Common Name. This may be \c NULL if the - * CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * \param rs_ctx The restart context to use. This may be set to \c NULL - * to disable restartable ECC. - * - * \return See \c mbedtls_crt_verify_with_profile(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_x509_crt_verify_restartable(mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx); - -/** - * \brief The type of trusted certificate callbacks. - * - * Callbacks of this type are passed to and used by the CRT - * verification routine mbedtls_x509_crt_verify_with_ca_cb() - * when looking for trusted signers of a given certificate. - * - * On success, the callback returns a list of trusted - * certificates to be considered as potential signers - * for the input certificate. - * - * \param p_ctx An opaque context passed to the callback. - * \param child The certificate for which to search a potential signer. - * This will point to a readable certificate. - * \param candidate_cas The address at which to store the address of the first - * entry in the generated linked list of candidate signers. - * This will not be \c NULL. - * - * \note The callback must only return a non-zero value on a - * fatal error. If, in contrast, the search for a potential - * signer completes without a single candidate, the - * callback must return \c 0 and set \c *candidate_cas - * to \c NULL. - * - * \return \c 0 on success. In this case, \c *candidate_cas points - * to a heap-allocated linked list of instances of - * ::mbedtls_x509_crt, and ownership of this list is passed - * to the caller. - * \return A negative error code on failure. - */ -typedef int (*mbedtls_x509_crt_ca_cb_t)(void *p_ctx, - mbedtls_x509_crt const *child, - mbedtls_x509_crt **candidate_cas); - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -/** - * \brief Version of \c mbedtls_x509_crt_verify_with_profile() which - * uses a callback to acquire the list of trusted CA - * certificates. - * - * \param crt The certificate chain to be verified. - * \param f_ca_cb The callback to be used to query for potential signers - * of a given child certificate. See the documentation of - * ::mbedtls_x509_crt_ca_cb_t for more information. - * \param p_ca_cb The opaque context to be passed to \p f_ca_cb. - * \param profile The security profile for the verification. - * \param cn The expected Common Name. This may be \c NULL if the - * CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * - * \return See \c mbedtls_crt_verify_with_profile(). - */ -int mbedtls_x509_crt_verify_with_ca_cb(mbedtls_x509_crt *crt, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy); - -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -/** - * \brief Check usage of certificate against keyUsage extension. - * - * \param crt Leaf certificate used. - * \param usage Intended usage(s) (eg MBEDTLS_X509_KU_KEY_ENCIPHERMENT - * before using the certificate to perform an RSA key - * exchange). - * - * \note Except for decipherOnly and encipherOnly, a bit set in the - * usage argument means this bit MUST be set in the - * certificate. For decipherOnly and encipherOnly, it means - * that bit MAY be set. - * - * \return 0 is these uses of the certificate are allowed, - * MBEDTLS_ERR_X509_BAD_INPUT_DATA if the keyUsage extension - * is present but does not match the usage argument. - * - * \note You should only call this function on leaf certificates, on - * (intermediate) CAs the keyUsage extension is automatically - * checked by \c mbedtls_x509_crt_verify(). - */ -int mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt *crt, - unsigned int usage); - -/** - * \brief Check usage of certificate against extendedKeyUsage. - * - * \param crt Leaf certificate used. - * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or - * MBEDTLS_OID_CLIENT_AUTH). - * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()). - * - * \return 0 if this use of the certificate is allowed, - * MBEDTLS_ERR_X509_BAD_INPUT_DATA if not. - * - * \note Usually only makes sense on leaf certificates. - */ -int mbedtls_x509_crt_check_extended_key_usage(const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len); - -#if defined(MBEDTLS_X509_CRL_PARSE_C) -/** - * \brief Verify the certificate revocation status - * - * \param crt a certificate to be verified - * \param crl the CRL to verify against - * - * \return 1 if the certificate is revoked, 0 otherwise - * - */ -int mbedtls_x509_crt_is_revoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl); -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - -/** - * \brief Initialize a certificate (chain) - * - * \param crt Certificate chain to initialize - */ -void mbedtls_x509_crt_init(mbedtls_x509_crt *crt); - -/** - * \brief Unallocate all certificate data - * - * \param crt Certificate chain to free - */ -void mbedtls_x509_crt_free(mbedtls_x509_crt *crt); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context - */ -void mbedtls_x509_crt_restart_init(mbedtls_x509_crt_restart_ctx *ctx); - -/** - * \brief Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Query certificate for given extension type - * - * \param[in] ctx Certificate context to be queried, must not be \c NULL - * \param ext_type Extension type being queried for, must be a valid - * extension type. Must be one of the MBEDTLS_X509_EXT_XXX - * values - * - * \return 0 if the given extension type is not present, - * non-zero otherwise - */ -static inline int mbedtls_x509_crt_has_ext_type(const mbedtls_x509_crt *ctx, - int ext_type) -{ - return ctx->MBEDTLS_PRIVATE(ext_types) & ext_type; -} - -/** - * \brief Access the ca_istrue field - * - * \param[in] crt Certificate to be queried, must not be \c NULL - * - * \return \c 1 if this a CA certificate \c 0 otherwise. - * \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not contain - * the Optional Basic Constraint extension. - * - */ -int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt); - -/** \} name Structures and functions for parsing and writing X.509 certificates */ - -#if defined(MBEDTLS_X509_CRT_WRITE_C) -/** - * \brief Initialize a CRT writing context - * - * \param ctx CRT context to initialize - */ -void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx); - -/** - * \brief Set the version for a Certificate - * Default: MBEDTLS_X509_CRT_VERSION_3 - * - * \param ctx CRT context to use - * \param version version to set (MBEDTLS_X509_CRT_VERSION_1, MBEDTLS_X509_CRT_VERSION_2 or - * MBEDTLS_X509_CRT_VERSION_3) - */ -void mbedtls_x509write_crt_set_version(mbedtls_x509write_cert *ctx, int version); - -#if defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief Set the serial number for a Certificate. - * - * \deprecated This function is deprecated and will be removed in a - * future version of the library. Please use - * mbedtls_x509write_crt_set_serial_raw() instead. - * - * \note Even though the MBEDTLS_BIGNUM_C guard looks redundant since - * X509 depends on PK and PK depends on BIGNUM, this emphasizes - * a direct dependency between X509 and BIGNUM which is going - * to be deprecated in the future. - * - * \param ctx CRT context to use - * \param serial serial number to set - * - * \return 0 if successful - */ -int MBEDTLS_DEPRECATED mbedtls_x509write_crt_set_serial( - mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial); -#endif // MBEDTLS_BIGNUM_C && !MBEDTLS_DEPRECATED_REMOVED - -/** - * \brief Set the serial number for a Certificate. - * - * \param ctx CRT context to use - * \param serial A raw array of bytes containing the serial number in big - * endian format - * \param serial_len Length of valid bytes (expressed in bytes) in \p serial - * input buffer - * - * \return 0 if successful, or - * MBEDTLS_ERR_X509_BAD_INPUT_DATA if the provided input buffer - * is too big (longer than MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) - */ -int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx, - unsigned char *serial, size_t serial_len); - -/** - * \brief Set the validity period for a Certificate - * Timestamps should be in string format for UTC timezone - * i.e. "YYYYMMDDhhmmss" - * e.g. "20131231235959" for December 31st 2013 - * at 23:59:59 - * - * \param ctx CRT context to use - * \param not_before not_before timestamp - * \param not_after not_after timestamp - * - * \return 0 if timestamp was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx, const char *not_before, - const char *not_after); - -/** - * \brief Set the issuer name for a Certificate - * Issuer names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=Mbed TLS CA" - * - * \param ctx CRT context to use - * \param issuer_name issuer name to set - * - * \return 0 if issuer name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx, - const char *issuer_name); - -/** - * \brief Set the subject name for a Certificate - * Subject names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=Mbed TLS Server 1" - * - * \param ctx CRT context to use - * \param subject_name subject name to set - * - * \return 0 if subject name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx, - const char *subject_name); - -/** - * \brief Set the subject public key for the certificate - * - * \param ctx CRT context to use - * \param key public key to include - */ -void mbedtls_x509write_crt_set_subject_key(mbedtls_x509write_cert *ctx, mbedtls_pk_context *key); - -/** - * \brief Set the issuer key used for signing the certificate - * - * \param ctx CRT context to use - * \param key private key to sign with - */ -void mbedtls_x509write_crt_set_issuer_key(mbedtls_x509write_cert *ctx, mbedtls_pk_context *key); - -/** - * \brief Set the MD algorithm to use for the signature - * (e.g. MBEDTLS_MD_SHA1) - * - * \param ctx CRT context to use - * \param md_alg MD algorithm to use - */ -void mbedtls_x509write_crt_set_md_alg(mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg); - -/** - * \brief Generic function to add to or replace an extension in the - * CRT - * - * \param ctx CRT context to use - * \param oid OID of the extension - * \param oid_len length of the OID - * \param critical if the extension is critical (per the RFC's definition) - * \param val value of the extension OCTET STRING - * \param val_len length of the value data - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_extension(mbedtls_x509write_cert *ctx, - const char *oid, size_t oid_len, - int critical, - const unsigned char *val, size_t val_len); - -/** - * \brief Set the basicConstraints extension for a CRT - * - * \param ctx CRT context to use - * \param is_ca is this a CA certificate - * \param max_pathlen maximum length of certificate chains below this - * certificate (only for CA certificates, -1 is - * unlimited) - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_basic_constraints(mbedtls_x509write_cert *ctx, - int is_ca, int max_pathlen); - -#if defined(MBEDTLS_MD_CAN_SHA1) -/** - * \brief Set the subjectKeyIdentifier extension for a CRT - * Requires that mbedtls_x509write_crt_set_subject_key() has been - * called before - * - * \param ctx CRT context to use - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_subject_key_identifier(mbedtls_x509write_cert *ctx); - -/** - * \brief Set the authorityKeyIdentifier extension for a CRT - * Requires that mbedtls_x509write_crt_set_issuer_key() has been - * called before - * - * \param ctx CRT context to use - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_authority_key_identifier(mbedtls_x509write_cert *ctx); -#endif /* MBEDTLS_MD_CAN_SHA1 */ - -/** - * \brief Set the Key Usage Extension flags - * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) - * - * \param ctx CRT context to use - * \param key_usage key usage flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_key_usage(mbedtls_x509write_cert *ctx, - unsigned int key_usage); - -/** - * \brief Set the Extended Key Usage Extension - * (e.g. MBEDTLS_OID_SERVER_AUTH) - * - * \param ctx CRT context to use - * \param exts extended key usage extensions to set, a sequence of - * MBEDTLS_ASN1_OID objects - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_ext_key_usage(mbedtls_x509write_cert *ctx, - const mbedtls_asn1_sequence *exts); - -/** - * \brief Set the Netscape Cert Type flags - * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) - * - * \param ctx CRT context to use - * \param ns_cert_type Netscape Cert Type flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_ns_cert_type(mbedtls_x509write_cert *ctx, - unsigned char ns_cert_type); - -/** - * \brief Free the contents of a CRT write context - * - * \param ctx CRT context to free - */ -void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx); - -/** - * \brief Write a built up certificate to a X509 DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx certificate to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function. This must not be \c NULL. - * \param p_rng RNG parameter - * - * \return length of data written if successful, or a specific - * error code - * - * \note \p f_rng is used for the signature operation. - */ -int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a built up certificate to a X509 PEM string - * - * \param ctx certificate to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function. This must not be \c NULL. - * \param p_rng RNG parameter - * - * \return 0 if successful, or a specific error code - * - * \note \p f_rng is used for the signature operation. - */ -int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, - mbedtls_f_rng_t *f_rng, - void *p_rng); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_X509_CRT_WRITE_C */ - -/** \} addtogroup x509_module */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_crt.h */ diff --git a/vendor/mbedtls/include/mbedtls/x509_csr.h b/vendor/mbedtls/include/mbedtls/x509_csr.h deleted file mode 100644 index c4bd7f122..000000000 --- a/vendor/mbedtls/include/mbedtls/x509_csr.h +++ /dev/null @@ -1,382 +0,0 @@ -/** - * \file x509_csr.h - * - * \brief X.509 certificate signing request parsing and writing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_X509_CSR_H -#define MBEDTLS_X509_CSR_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures and functions for X.509 Certificate Signing Requests (CSR) - * \{ - */ - -/** - * Certificate Signing Request (CSR) structure. - * - * Some fields of this structure are publicly readable. Do not modify - * them except via Mbed TLS library functions: the effect of modifying - * those fields or the data that those fields point to is unspecified. - */ -typedef struct mbedtls_x509_csr { - mbedtls_x509_buf raw; /**< The raw CSR data (DER). */ - mbedtls_x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */ - - int version; /**< CSR version (1=v1). */ - - mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). */ - mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ - - mbedtls_pk_context pk; /**< Container for the public key context. */ - - unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */ - unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ - mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension. These can be later parsed by mbedtls_x509_parse_subject_alt_name. */ - - int MBEDTLS_PRIVATE(ext_types); /**< Bit string containing detected and parsed extensions */ - - mbedtls_x509_buf sig_oid; - mbedtls_x509_buf MBEDTLS_PRIVATE(sig); - mbedtls_md_type_t MBEDTLS_PRIVATE(sig_md); /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t MBEDTLS_PRIVATE(sig_pk); /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *MBEDTLS_PRIVATE(sig_opts); /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ -} -mbedtls_x509_csr; - -/** - * Container for writing a CSR - */ -typedef struct mbedtls_x509write_csr { - mbedtls_pk_context *MBEDTLS_PRIVATE(key); - mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject); - mbedtls_md_type_t MBEDTLS_PRIVATE(md_alg); - mbedtls_asn1_named_data *MBEDTLS_PRIVATE(extensions); -} -mbedtls_x509write_csr; - -#if defined(MBEDTLS_X509_CSR_PARSE_C) -/** - * \brief Load a Certificate Signing Request (CSR) in DER format - * - * \note Any unsupported requested extensions are silently - * ignored, unless the critical flag is set, in which case - * the CSR is rejected. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param csr CSR context to fill - * \param buf buffer holding the CRL data - * \param buflen size of the buffer - * - * \return 0 if successful, or a specific X509 error code - */ -int mbedtls_x509_csr_parse_der(mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen); - -/** - * \brief The type of certificate extension callbacks. - * - * Callbacks of this type are passed to and used by the - * mbedtls_x509_csr_parse_der_with_ext_cb() routine when - * it encounters either an unsupported extension. - * Future versions of the library may invoke the callback - * in other cases, if and when the need arises. - * - * \param p_ctx An opaque context passed to the callback. - * \param csr The CSR being parsed. - * \param oid The OID of the extension. - * \param critical Whether the extension is critical. - * \param p Pointer to the start of the extension value - * (the content of the OCTET STRING). - * \param end End of extension value. - * - * \note The callback must fail and return a negative error code - * if it can not parse or does not support the extension. - * When the callback fails to parse a critical extension - * mbedtls_x509_csr_parse_der_with_ext_cb() also fails. - * When the callback fails to parse a non critical extension - * mbedtls_x509_csr_parse_der_with_ext_cb() simply skips - * the extension and continues parsing. - * - * \return \c 0 on success. - * \return A negative error code on failure. - */ -typedef int (*mbedtls_x509_csr_ext_cb_t)(void *p_ctx, - mbedtls_x509_csr const *csr, - mbedtls_x509_buf const *oid, - int critical, - const unsigned char *p, - const unsigned char *end); - -/** - * \brief Load a Certificate Signing Request (CSR) in DER format - * - * \note Any unsupported requested extensions are silently - * ignored, unless the critical flag is set, in which case - * the result of the callback function decides whether - * CSR is rejected. - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param csr CSR context to fill - * \param buf buffer holding the CRL data - * \param buflen size of the buffer - * \param cb A callback invoked for every unsupported certificate - * extension. - * \param p_ctx An opaque context passed to the callback. - * - * \return 0 if successful, or a specific X509 error code - */ -int mbedtls_x509_csr_parse_der_with_ext_cb(mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen, - mbedtls_x509_csr_ext_cb_t cb, - void *p_ctx); - -/** - * \brief Load a Certificate Signing Request (CSR), DER or PEM format - * - * \note See notes for \c mbedtls_x509_csr_parse_der() - * - * \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto - * subsystem must have been initialized by calling - * psa_crypto_init() before calling this function. - * - * \param csr CSR context to fill - * \param buf buffer holding the CRL data - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_csr_parse(mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load a Certificate Signing Request (CSR) - * - * \note See notes for \c mbedtls_x509_csr_parse() - * - * \param csr CSR context to fill - * \param path filename to read the CSR from - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_csr_parse_file(mbedtls_x509_csr *csr, const char *path); -#endif /* MBEDTLS_FS_IO */ - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -/** - * \brief Returns an informational string about the - * CSR. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param csr The X509 CSR to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix, - const mbedtls_x509_csr *csr); -#endif /* !MBEDTLS_X509_REMOVE_INFO */ - -/** - * \brief Initialize a CSR - * - * \param csr CSR to initialize - */ -void mbedtls_x509_csr_init(mbedtls_x509_csr *csr); - -/** - * \brief Unallocate all CSR data - * - * \param csr CSR to free - */ -void mbedtls_x509_csr_free(mbedtls_x509_csr *csr); -#endif /* MBEDTLS_X509_CSR_PARSE_C */ - -/** \} name Structures and functions for X.509 Certificate Signing Requests (CSR) */ - -#if defined(MBEDTLS_X509_CSR_WRITE_C) -/** - * \brief Initialize a CSR context - * - * \param ctx CSR context to initialize - */ -void mbedtls_x509write_csr_init(mbedtls_x509write_csr *ctx); - -/** - * \brief Set the subject name for a CSR - * Subject names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=Mbed TLS Server 1" - * - * \param ctx CSR context to use - * \param subject_name subject name to set - * - * \return 0 if subject name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx, - const char *subject_name); - -/** - * \brief Set the key for a CSR (public key will be included, - * private key used to sign the CSR when writing it) - * - * \param ctx CSR context to use - * \param key Asymmetric key to include - */ -void mbedtls_x509write_csr_set_key(mbedtls_x509write_csr *ctx, mbedtls_pk_context *key); - -/** - * \brief Set the MD algorithm to use for the signature - * (e.g. MBEDTLS_MD_SHA1) - * - * \param ctx CSR context to use - * \param md_alg MD algorithm to use - */ -void mbedtls_x509write_csr_set_md_alg(mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg); - -/** - * \brief Set the Key Usage Extension flags - * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) - * - * \param ctx CSR context to use - * \param key_usage key usage flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - * - * \note The decipherOnly flag from the Key Usage - * extension is represented by bit 8 (i.e. - * 0x8000), which cannot typically be represented - * in an unsigned char. Therefore, the flag - * decipherOnly (i.e. - * #MBEDTLS_X509_KU_DECIPHER_ONLY) cannot be set using this - * function. - */ -int mbedtls_x509write_csr_set_key_usage(mbedtls_x509write_csr *ctx, unsigned char key_usage); - -/** - * \brief Set Subject Alternative Name - * - * \param ctx CSR context to use - * \param san_list List of SAN values - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - * - * \note Only "dnsName", "uniformResourceIdentifier" and "otherName", - * as defined in RFC 5280, are supported. - */ -int mbedtls_x509write_csr_set_subject_alternative_name(mbedtls_x509write_csr *ctx, - const mbedtls_x509_san_list *san_list); - -/** - * \brief Set the Netscape Cert Type flags - * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) - * - * \param ctx CSR context to use - * \param ns_cert_type Netscape Cert Type flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_csr_set_ns_cert_type(mbedtls_x509write_csr *ctx, - unsigned char ns_cert_type); - -/** - * \brief Generic function to add to or replace an extension in the - * CSR - * - * \param ctx CSR context to use - * \param oid OID of the extension - * \param oid_len length of the OID - * \param critical Set to 1 to mark the extension as critical, 0 otherwise. - * \param val value of the extension OCTET STRING - * \param val_len length of the value data - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_csr_set_extension(mbedtls_x509write_csr *ctx, - const char *oid, size_t oid_len, - int critical, - const unsigned char *val, size_t val_len); - -/** - * \brief Free the contents of a CSR context - * - * \param ctx CSR context to free - */ -void mbedtls_x509write_csr_free(mbedtls_x509write_csr *ctx); - -/** - * \brief Write a CSR (Certificate Signing Request) to a - * DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx CSR to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function. This must not be \c NULL. - * \param p_rng RNG parameter - * - * \return length of data written if successful, or a specific - * error code - * - * \note \p f_rng is used for the signature operation. - */ -int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - mbedtls_f_rng_t *f_rng, - void *p_rng); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a CSR (Certificate Signing Request) to a - * PEM string - * - * \param ctx CSR to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function. This must not be \c NULL. - * \param p_rng RNG parameter - * - * \return 0 if successful, or a specific error code - * - * \note \p f_rng is used for the signature operation. - */ -int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - mbedtls_f_rng_t *f_rng, - void *p_rng); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_X509_CSR_WRITE_C */ - -/** \} addtogroup x509_module */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_csr.h */ diff --git a/vendor/mbedtls/include/psa/build_info.h b/vendor/mbedtls/include/psa/build_info.h deleted file mode 100644 index 3ee6cd7b1..000000000 --- a/vendor/mbedtls/include/psa/build_info.h +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \file psa/build_info.h - * - * \brief Build-time PSA configuration info - * - * Include this file if you need to depend on the - * configuration options defined in mbedtls_config.h or MBEDTLS_CONFIG_FILE - * in PSA cryptography core specific files. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_BUILD_INFO_H -#define PSA_CRYPTO_BUILD_INFO_H - -#include "mbedtls/build_info.h" - -#endif /* PSA_CRYPTO_BUILD_INFO_H */ diff --git a/vendor/mbedtls/include/psa/crypto.h b/vendor/mbedtls/include/psa/crypto.h deleted file mode 100644 index 2fe9f35ec..000000000 --- a/vendor/mbedtls/include/psa/crypto.h +++ /dev/null @@ -1,4977 +0,0 @@ -/** - * \file psa/crypto.h - * \brief Platform Security Architecture cryptography module - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_H -#define PSA_CRYPTO_H - -#if defined(MBEDTLS_PSA_CRYPTO_PLATFORM_FILE) -#include MBEDTLS_PSA_CRYPTO_PLATFORM_FILE -#else -#include "crypto_platform.h" -#endif - -#include - -#ifdef __DOXYGEN_ONLY__ -/* This __DOXYGEN_ONLY__ block contains mock definitions for things that - * must be defined in the crypto_platform.h header. These mock definitions - * are present in this file as a convenience to generate pretty-printed - * documentation that includes those definitions. */ - -/** \defgroup platform Implementation-specific definitions - * @{ - */ - -/**@}*/ -#endif /* __DOXYGEN_ONLY__ */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* The file "crypto_types.h" declares types that encode errors, - * algorithms, key types, policies, etc. */ -#include "crypto_types.h" - -/** \defgroup version API version - * @{ - */ - -/** - * The major version of this implementation of the PSA Crypto API - */ -#define PSA_CRYPTO_API_VERSION_MAJOR 1 - -/** - * The minor version of this implementation of the PSA Crypto API - */ -#define PSA_CRYPTO_API_VERSION_MINOR 0 - -/**@}*/ - -/* The file "crypto_values.h" declares macros to build and analyze values - * of integral types defined in "crypto_types.h". */ -#include "crypto_values.h" - -/* The file "crypto_sizes.h" contains definitions for size calculation - * macros whose definitions are implementation-specific. */ -#include "crypto_sizes.h" - -/* The file "crypto_struct.h" contains definitions for - * implementation-specific structs that are declared above. */ -#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE) -#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE -#else -#include "crypto_struct.h" -#endif - -/** \defgroup initialization Library initialization - * @{ - */ - -/** - * \brief Library initialization. - * - * Applications must call this function before calling any other - * function in this module. - * - * Applications may call this function more than once. Once a call - * succeeds, subsequent calls are guaranteed to succeed. - * - * If the application calls other functions before calling psa_crypto_init(), - * the behavior is undefined. Implementations are encouraged to either perform - * the operation as if the library had been initialized or to return - * #PSA_ERROR_BAD_STATE or some other applicable error. In particular, - * implementations should not return a success status if the lack of - * initialization may have security implications, for example due to improper - * seeding of the random number generator. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - */ -psa_status_t psa_crypto_init(void); - -/**@}*/ - -/** \addtogroup attributes - * @{ - */ - -/** \def PSA_KEY_ATTRIBUTES_INIT - * - * This macro returns a suitable initializer for a key attribute structure - * of type #psa_key_attributes_t. - */ - -/** Return an initial value for a key attributes structure. - */ -static psa_key_attributes_t psa_key_attributes_init(void); - -/** Declare a key as persistent and set its key identifier. - * - * If the attribute structure currently declares the key as volatile (which - * is the default content of an attribute structure), this function sets - * the lifetime attribute to #PSA_KEY_LIFETIME_PERSISTENT. - * - * This function does not access storage, it merely stores the given - * value in the structure. - * The persistent key will be written to storage when the attribute - * structure is passed to a key creation function such as - * psa_import_key(), psa_generate_key(), psa_generate_key_custom(), - * psa_key_derivation_output_key(), psa_key_derivation_output_key_custom() - * or psa_copy_key(). - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate each of its arguments exactly once. - * - * \param[out] attributes The attribute structure to write to. - * \param key The persistent identifier for the key. - * This can be any value in the range from - * #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX - * inclusive. - */ -static void psa_set_key_id(psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t key); - -#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -/** Set the owner identifier of a key. - * - * When key identifiers encode key owner identifiers, psa_set_key_id() does - * not allow to define in key attributes the owner of volatile keys as - * psa_set_key_id() enforces the key to be persistent. - * - * This function allows to set in key attributes the owner identifier of a - * key. It is intended to be used for volatile keys. For persistent keys, - * it is recommended to use the PSA Cryptography API psa_set_key_id() to define - * the owner of a key. - * - * \param[out] attributes The attribute structure to write to. - * \param owner The key owner identifier. - */ -static void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes, - mbedtls_key_owner_id_t owner); -#endif - -/** Set the location of a persistent key. - * - * To make a key persistent, you must give it a persistent key identifier - * with psa_set_key_id(). By default, a key that has a persistent identifier - * is stored in the default storage area identifier by - * #PSA_KEY_LIFETIME_PERSISTENT. Call this function to choose a storage - * area, or to explicitly declare the key as volatile. - * - * This function does not access storage, it merely stores the given - * value in the structure. - * The persistent key will be written to storage when the attribute - * structure is passed to a key creation function such as - * psa_import_key(), psa_generate_key(), psa_generate_key_custom(), - * psa_key_derivation_output_key(), psa_key_derivation_output_key_custom() - * or psa_copy_key(). - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate each of its arguments exactly once. - * - * \param[out] attributes The attribute structure to write to. - * \param lifetime The lifetime for the key. - * If this is #PSA_KEY_LIFETIME_VOLATILE, the - * key will be volatile, and the key identifier - * attribute is reset to 0. - */ -static void psa_set_key_lifetime(psa_key_attributes_t *attributes, - psa_key_lifetime_t lifetime); - -/** Retrieve the key identifier from key attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate its argument exactly once. - * - * \param[in] attributes The key attribute structure to query. - * - * \return The persistent identifier stored in the attribute structure. - * This value is unspecified if the attribute structure declares - * the key as volatile. - */ -static mbedtls_svc_key_id_t psa_get_key_id( - const psa_key_attributes_t *attributes); - -/** Retrieve the lifetime from key attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate its argument exactly once. - * - * \param[in] attributes The key attribute structure to query. - * - * \return The lifetime value stored in the attribute structure. - */ -static psa_key_lifetime_t psa_get_key_lifetime( - const psa_key_attributes_t *attributes); - -/** Declare usage flags for a key. - * - * Usage flags are part of a key's usage policy. They encode what - * kind of operations are permitted on the key. For more details, - * refer to the documentation of the type #psa_key_usage_t. - * - * This function overwrites any usage flags - * previously set in \p attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate each of its arguments exactly once. - * - * \param[out] attributes The attribute structure to write to. - * \param usage_flags The usage flags to write. - */ -static void psa_set_key_usage_flags(psa_key_attributes_t *attributes, - psa_key_usage_t usage_flags); - -/** Retrieve the usage flags from key attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate its argument exactly once. - * - * \param[in] attributes The key attribute structure to query. - * - * \return The usage flags stored in the attribute structure. - */ -static psa_key_usage_t psa_get_key_usage_flags( - const psa_key_attributes_t *attributes); - -/** Declare the permitted algorithm policy for a key. - * - * The permitted algorithm policy of a key encodes which algorithm or - * algorithms are permitted to be used with this key. The following - * algorithm policies are supported: - * - 0 does not allow any cryptographic operation with the key. The key - * may be used for non-cryptographic actions such as exporting (if - * permitted by the usage flags). - * - An algorithm value permits this particular algorithm. - * - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified - * signature scheme with any hash algorithm. - * - An algorithm built from #PSA_ALG_AT_LEAST_THIS_LENGTH_MAC allows - * any MAC algorithm from the same base class (e.g. CMAC) which - * generates/verifies a MAC length greater than or equal to the length - * encoded in the wildcard algorithm. - * - An algorithm built from #PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG - * allows any AEAD algorithm from the same base class (e.g. CCM) which - * generates/verifies a tag length greater than or equal to the length - * encoded in the wildcard algorithm. - * - * This function overwrites any algorithm policy - * previously set in \p attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate each of its arguments exactly once. - * - * \param[out] attributes The attribute structure to write to. - * \param alg The permitted algorithm policy to write. - */ -static void psa_set_key_algorithm(psa_key_attributes_t *attributes, - psa_algorithm_t alg); - - -/** Retrieve the algorithm policy from key attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate its argument exactly once. - * - * \param[in] attributes The key attribute structure to query. - * - * \return The algorithm stored in the attribute structure. - */ -static psa_algorithm_t psa_get_key_algorithm( - const psa_key_attributes_t *attributes); - -/** Declare the type of a key. - * - * This function overwrites any key type - * previously set in \p attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate each of its arguments exactly once. - * - * \param[out] attributes The attribute structure to write to. - * \param type The key type to write. - * If this is 0, the key type in \p attributes - * becomes unspecified. - */ -static void psa_set_key_type(psa_key_attributes_t *attributes, - psa_key_type_t type); - - -/** Declare the size of a key. - * - * This function overwrites any key size previously set in \p attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate each of its arguments exactly once. - * - * \param[out] attributes The attribute structure to write to. - * \param bits The key size in bits. - * If this is 0, the key size in \p attributes - * becomes unspecified. Keys of size 0 are - * not supported. - */ -static void psa_set_key_bits(psa_key_attributes_t *attributes, - size_t bits); - -/** Retrieve the key type from key attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate its argument exactly once. - * - * \param[in] attributes The key attribute structure to query. - * - * \return The key type stored in the attribute structure. - */ -static psa_key_type_t psa_get_key_type(const psa_key_attributes_t *attributes); - -/** Retrieve the key size from key attributes. - * - * This function may be declared as `static` (i.e. without external - * linkage). This function may be provided as a function-like macro, - * but in this case it must evaluate its argument exactly once. - * - * \param[in] attributes The key attribute structure to query. - * - * \return The key size stored in the attribute structure, in bits. - */ -static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); - -/** Retrieve the attributes of a key. - * - * This function first resets the attribute structure as with - * psa_reset_key_attributes(). It then copies the attributes of - * the given key into the given attribute structure. - * - * \note This function may allocate memory or other resources. - * Once you have called this function on an attribute structure, - * you must call psa_reset_key_attributes() to free these resources. - * - * \param[in] key Identifier of the key to query. - * \param[in,out] attributes On success, the attributes of the key. - * On failure, equivalent to a - * freshly-initialized structure. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, - psa_key_attributes_t *attributes); - -/** Reset a key attribute structure to a freshly initialized state. - * - * You must initialize the attribute structure as described in the - * documentation of the type #psa_key_attributes_t before calling this - * function. Once the structure has been initialized, you may call this - * function at any time. - * - * This function frees any auxiliary resources that the structure - * may contain. - * - * \param[in,out] attributes The attribute structure to reset. - */ -void psa_reset_key_attributes(psa_key_attributes_t *attributes); - -/**@}*/ - -/** \defgroup key_management Key management - * @{ - */ - -/** Remove non-essential copies of key material from memory. - * - * If the key identifier designates a volatile key, this functions does not do - * anything and returns successfully. - * - * If the key identifier designates a persistent key, then this function will - * free all resources associated with the key in volatile memory. The key - * data in persistent storage is not affected and the key can still be used. - * - * \param key Identifier of the key to purge. - * - * \retval #PSA_SUCCESS - * The key material will have been removed from memory if it is not - * currently required. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not a valid key identifier. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); - -/** Make a copy of a key. - * - * Copy key material from one location to another. - * - * This function is primarily useful to copy a key from one location - * to another, since it populates a key using the material from - * another key which may have a different lifetime. - * - * This function may be used to share a key with a different party, - * subject to implementation-defined restrictions on key sharing. - * - * The policy on the source key must have the usage flag - * #PSA_KEY_USAGE_COPY set. - * This flag is sufficient to permit the copy if the key has the lifetime - * #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT. - * Some secure elements do not provide a way to copy a key without - * making it extractable from the secure element. If a key is located - * in such a secure element, then the key must have both usage flags - * #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make - * a copy of the key outside the secure element. - * - * The resulting key may only be used in a way that conforms to - * both the policy of the original key and the policy specified in - * the \p attributes parameter: - * - The usage flags on the resulting key are the bitwise-and of the - * usage flags on the source policy and the usage flags in \p attributes. - * - If both allow the same algorithm or wildcard-based - * algorithm policy, the resulting key has the same algorithm policy. - * - If either of the policies allows an algorithm and the other policy - * allows a wildcard-based algorithm policy that includes this algorithm, - * the resulting key allows the same algorithm. - * - If the policies do not allow any algorithm in common, this function - * fails with the status #PSA_ERROR_INVALID_ARGUMENT. - * - * The effect of this function on implementation-defined attributes is - * implementation-defined. - * - * \param source_key The key to copy. It must allow the usage - * #PSA_KEY_USAGE_COPY. If a private or secret key is - * being copied outside of a secure element it must - * also allow #PSA_KEY_USAGE_EXPORT. - * \param[in] attributes The attributes for the new key. - * They are used as follows: - * - The key type and size may be 0. If either is - * nonzero, it must match the corresponding - * attribute of the source key. - * - The key location (the lifetime and, for - * persistent keys, the key identifier) is - * used directly. - * - The policy constraints (usage flags and - * algorithm policy) are combined from - * the source key and \p attributes so that - * both sets of restrictions apply, as - * described in the documentation of this function. - * \param[out] target_key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE - * \p source_key is invalid. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The lifetime or identifier in \p attributes are invalid, or - * the policy constraints on the source and specified in - * \p attributes are incompatible, or - * \p attributes specifies a key type or key size - * which does not match the attributes of the source key. - * \retval #PSA_ERROR_NOT_PERMITTED - * The source key does not have the #PSA_KEY_USAGE_COPY usage flag, or - * the source key is not exportable and its lifetime does not - * allow copying it to the target's lifetime. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *target_key); - - -/** - * \brief Destroy a key. - * - * This function destroys a key from both volatile - * memory and, if applicable, non-volatile storage. Implementations shall - * make a best effort to ensure that the key material cannot be recovered. - * - * This function also erases any metadata such as policies and frees - * resources associated with the key. - * - * If a key is currently in use in a multipart operation, then destroying the - * key will cause the multipart operation to fail. - * - * \warning We can only guarantee that the the key material will - * eventually be wiped from memory. With threading enabled - * and during concurrent execution, copies of the key material may - * still exist until all threads have finished using the key. - * - * \param key Identifier of the key to erase. If this is \c 0, do nothing and - * return #PSA_SUCCESS. - * - * \retval #PSA_SUCCESS - * \p key was a valid identifier and the key material that it - * referred to has been erased. Alternatively, \p key is \c 0. - * \retval #PSA_ERROR_NOT_PERMITTED - * The key cannot be erased because it is - * read-only, either due to a policy or due to physical restrictions. - * \retval #PSA_ERROR_INVALID_HANDLE - * \p key is not a valid identifier nor \c 0. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * There was a failure in communication with the cryptoprocessor. - * The key material may still be present in the cryptoprocessor. - * \retval #PSA_ERROR_DATA_INVALID - * This error is typically a result of either storage corruption on a - * cleartext storage backend, or an attempt to read data that was - * written by an incompatible version of the library. - * \retval #PSA_ERROR_STORAGE_FAILURE - * The storage is corrupted. Implementations shall make a best effort - * to erase key material even in this stage, however applications - * should be aware that it may be impossible to guarantee that the - * key material is not recoverable in such cases. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * An unexpected condition which is not a storage corruption or - * a communication failure occurred. The cryptoprocessor may have - * been compromised. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); - -/**@}*/ - -/** \defgroup import_export Key import and export - * @{ - */ - -/** - * \brief Import a key in binary format. - * - * This function supports any output from psa_export_key(). Refer to the - * documentation of psa_export_public_key() for the format of public keys - * and to the documentation of psa_export_key() for the format for - * other key types. - * - * The key data determines the key size. The attributes may optionally - * specify a key size; in this case it must match the size determined - * from the key data. A key size of 0 in \p attributes indicates that - * the key size is solely determined by the key data. - * - * Implementations must reject an attempt to import a key of size 0. - * - * This specification supports a single format for each key type. - * Implementations may support other formats as long as the standard - * format is supported. Implementations that support other formats - * should ensure that the formats are clearly unambiguous so as to - * minimize the risk that an invalid input is accidentally interpreted - * according to a different format. - * - * \param[in] attributes The attributes for the new key. - * The key size is always determined from the - * \p data buffer. - * If the key size in \p attributes is nonzero, - * it must be equal to the size from \p data. - * \param[out] key On success, an identifier to the newly created key. - * For persistent keys, this is the key identifier - * defined in \p attributes. - * \c 0 on failure. - * \param[in] data Buffer containing the key data. The content of this - * buffer is interpreted according to the type declared - * in \p attributes. - * All implementations must support at least the format - * described in the documentation - * of psa_export_key() or psa_export_public_key() for - * the chosen type. Implementations may allow other - * formats, but should be conservative: implementations - * should err on the side of rejecting content if it - * may be erroneous (e.g. wrong type or truncated data). - * \param data_length Size of the \p data buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size is not supported, either by the - * implementation in general or in this particular persistent location. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key attributes, as a whole, are invalid, or - * the key data is not correctly formatted, or - * the size in \p attributes is nonzero and does not match the size - * of the key data. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_import_key(const psa_key_attributes_t *attributes, - const uint8_t *data, - size_t data_length, - mbedtls_svc_key_id_t *key); - - - -/** - * \brief Export a key in binary format. - * - * The output of this function can be passed to psa_import_key() to - * create an equivalent object. - * - * If the implementation of psa_import_key() supports other formats - * beyond the format specified here, the output from psa_export_key() - * must use the representation specified here, not the original - * representation. - * - * For standard key types, the output format is as follows: - * - * - For symmetric keys (including MAC keys), the format is the - * raw bytes of the key. - * - For DES, the key data consists of 8 bytes. The parity bits must be - * correct. - * - For Triple-DES, the format is the concatenation of the - * two or three DES keys. - * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEY_PAIR), the format - * is the non-encrypted DER encoding of the representation defined by - * PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0. - * ``` - * RSAPrivateKey ::= SEQUENCE { - * version INTEGER, -- must be 0 - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * } - * ``` - * - For elliptic curve key pairs (key types for which - * #PSA_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is - * a representation of the private value as a `ceiling(m/8)`-byte string - * where `m` is the bit size associated with the curve, i.e. the bit size - * of the order of the curve's coordinate field. This byte string is - * in little-endian order for Montgomery curves (curve types - * `PSA_ECC_FAMILY_CURVEXXX`), and in big-endian order for Weierstrass - * curves (curve types `PSA_ECC_FAMILY_SECTXXX`, `PSA_ECC_FAMILY_SECPXXX` - * and `PSA_ECC_FAMILY_BRAINPOOL_PXXX`). - * For Weierstrass curves, this is the content of the `privateKey` field of - * the `ECPrivateKey` format defined by RFC 5915. For Montgomery curves, - * the format is defined by RFC 7748, and output is masked according to §5. - * For twisted Edwards curves, the private key is as defined by RFC 8032 - * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). - * - For Diffie-Hellman key exchange key pairs (key types for which - * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the - * format is the representation of the private key `x` as a big-endian byte - * string. The length of the byte string is the private key size in bytes - * (leading zeroes are not stripped). - * - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is - * true), the format is the same as for psa_export_public_key(). - * - * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set. - * - * \param key Identifier of the key to export. It must allow the - * usage #PSA_KEY_USAGE_EXPORT, unless it is a public - * key. - * \param[out] data Buffer where the key data is to be written. - * \param data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes - * that make up the key data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_EXPORT flag. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p data buffer is too small. You can determine a - * sufficient buffer size by calling - * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits) - * where \c type is the key type - * and \c bits is the key size in bits. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_export_key(mbedtls_svc_key_id_t key, - uint8_t *data, - size_t data_size, - size_t *data_length); - -/** - * \brief Export a public key or the public part of a key pair in binary format. - * - * The output of this function can be passed to psa_import_key() to - * create an object that is equivalent to the public key. - * - * This specification supports a single format for each key type. - * Implementations may support other formats as long as the standard - * format is supported. Implementations that support other formats - * should ensure that the formats are clearly unambiguous so as to - * minimize the risk that an invalid input is accidentally interpreted - * according to a different format. - * - * For standard key types, the output format is as follows: - * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of - * the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`. - * ``` - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER } -- e - * ``` - * - For elliptic curve keys on a twisted Edwards curve (key types for which - * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true and #PSA_KEY_TYPE_ECC_GET_FAMILY - * returns #PSA_ECC_FAMILY_TWISTED_EDWARDS), the public key is as defined - * by RFC 8032 - * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). - * - For other elliptic curve public keys (key types for which - * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed - * representation defined by SEC1 §2.3.3 as the content of an ECPoint. - * Let `m` be the bit size associated with the curve, i.e. the bit size of - * `q` for a curve over `F_q`. The representation consists of: - * - The byte 0x04; - * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; - * - `y_P` as a `ceiling(m/8)`-byte string, big-endian. - * - For Diffie-Hellman key exchange public keys (key types for which - * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true), - * the format is the representation of the public key `y = g^x mod p` as a - * big-endian byte string. The length of the byte string is the length of the - * base prime `p` in bytes. - * - * Exporting a public key object or the public part of a key pair is - * always permitted, regardless of the key's usage flags. - * - * \param key Identifier of the key to export. - * \param[out] data Buffer where the key data is to be written. - * \param data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes - * that make up the key data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key is neither a public key nor a key pair. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p data buffer is too small. You can determine a - * sufficient buffer size by calling - * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits) - * where \c type is the key type - * and \c bits is the key size in bits. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, - uint8_t *data, - size_t data_size, - size_t *data_length); - - - -/**@}*/ - -/** \defgroup hash Message digests - * @{ - */ - -/** Calculate the hash (digest) of a message. - * - * \note To verify the hash of a message against an - * expected value, use psa_hash_compare() instead. - * - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * \param[in] input Buffer containing the message to hash. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] hash Buffer where the hash is to be written. - * \param hash_size Size of the \p hash buffer in bytes. - * \param[out] hash_length On success, the number of bytes - * that make up the hash value. This is always - * #PSA_HASH_LENGTH(\p alg). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a hash algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p hash_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_compute(psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *hash, - size_t hash_size, - size_t *hash_length); - -/** Calculate the hash (digest) of a message and compare it with a - * reference value. - * - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * \param[in] input Buffer containing the message to hash. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] hash Buffer containing the expected hash value. - * \param hash_length Size of the \p hash buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected hash is identical to the actual hash of the input. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The hash of the message was calculated successfully, but it - * differs from the expected hash. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a hash algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p input_length or \p hash_length do not match the hash size for \p alg - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_compare(psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *hash, - size_t hash_length); - -/** The type of the state data structure for multipart hash operations. - * - * Before calling any function on a hash operation object, the application must - * initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_hash_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_hash_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_HASH_OPERATION_INIT, - * for example: - * \code - * psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_hash_operation_init() - * to the structure, for example: - * \code - * psa_hash_operation_t operation; - * operation = psa_hash_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_hash_operation_s psa_hash_operation_t; - -/** \def PSA_HASH_OPERATION_INIT - * - * This macro returns a suitable initializer for a hash operation object - * of type #psa_hash_operation_t. - */ - -/** Return an initial value for a hash operation object. - */ -static psa_hash_operation_t psa_hash_operation_init(void); - -/** Set up a multipart hash operation. - * - * The sequence of operations to calculate a hash (message digest) - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_hash_operation_t, e.g. #PSA_HASH_OPERATION_INIT. - * -# Call psa_hash_setup() to specify the algorithm. - * -# Call psa_hash_update() zero, one or more times, passing a fragment - * of the message each time. The hash that is calculated is the hash - * of the concatenation of these messages in order. - * -# To calculate the hash, call psa_hash_finish(). - * To compare the hash with an expected value, call psa_hash_verify(). - * - * If an error occurs at any step after a call to psa_hash_setup(), the - * operation will need to be reset by a call to psa_hash_abort(). The - * application may call psa_hash_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_hash_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_hash_finish() or psa_hash_verify(). - * - A call to psa_hash_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_hash_operation_t and not yet in use. - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not a supported hash algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p alg is not a hash algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_setup(psa_hash_operation_t *operation, - psa_algorithm_t alg); - -/** Add a message fragment to a multipart hash operation. - * - * The application must call psa_hash_setup() before calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_hash_abort(). - * - * \param[in,out] operation Active hash operation. - * \param[in] input Buffer containing the message fragment to hash. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_update(psa_hash_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Finish the calculation of the hash of a message. - * - * The application must call psa_hash_setup() before calling this function. - * This function calculates the hash of the message formed by concatenating - * the inputs passed to preceding calls to psa_hash_update(). - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_hash_abort(). - * - * \warning Applications should not call this function if they expect - * a specific value for the hash. Call psa_hash_verify() instead. - * Beware that comparing integrity or authenticity data such as - * hash values with a function such as \c memcmp is risky - * because the time taken by the comparison may leak information - * about the hashed data which could allow an attacker to guess - * a valid hash and thereby bypass security controls. - * - * \param[in,out] operation Active hash operation. - * \param[out] hash Buffer where the hash is to be written. - * \param hash_size Size of the \p hash buffer in bytes. - * \param[out] hash_length On success, the number of bytes - * that make up the hash value. This is always - * #PSA_HASH_LENGTH(\c alg) where \c alg is the - * hash algorithm that is calculated. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p hash buffer is too small. You can determine a - * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) - * where \c alg is the hash algorithm that is calculated. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_finish(psa_hash_operation_t *operation, - uint8_t *hash, - size_t hash_size, - size_t *hash_length); - -/** Finish the calculation of the hash of a message and compare it with - * an expected value. - * - * The application must call psa_hash_setup() before calling this function. - * This function calculates the hash of the message formed by concatenating - * the inputs passed to preceding calls to psa_hash_update(). It then - * compares the calculated hash with the expected hash passed as a - * parameter to this function. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_hash_abort(). - * - * \note Implementations shall make the best effort to ensure that the - * comparison between the actual hash and the expected hash is performed - * in constant time. - * - * \param[in,out] operation Active hash operation. - * \param[in] hash Buffer containing the expected hash value. - * \param hash_length Size of the \p hash buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected hash is identical to the actual hash of the message. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The hash of the message was calculated successfully, but it - * differs from the expected hash. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_verify(psa_hash_operation_t *operation, - const uint8_t *hash, - size_t hash_length); - -/** Abort a hash operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_hash_setup() again. - * - * You may call this function any time after the operation object has - * been initialized by one of the methods described in #psa_hash_operation_t. - * - * In particular, calling psa_hash_abort() after the operation has been - * terminated by a call to psa_hash_abort(), psa_hash_finish() or - * psa_hash_verify() is safe and has no effect. - * - * \param[in,out] operation Initialized hash operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_abort(psa_hash_operation_t *operation); - -/** Clone a hash operation. - * - * This function copies the state of an ongoing hash operation to - * a new operation object. In other words, this function is equivalent - * to calling psa_hash_setup() on \p target_operation with the same - * algorithm that \p source_operation was set up for, then - * psa_hash_update() on \p target_operation with the same input that - * that was passed to \p source_operation. After this function returns, the - * two objects are independent, i.e. subsequent calls involving one of - * the objects do not affect the other object. - * - * \param[in] source_operation The active hash operation to clone. - * \param[in,out] target_operation The operation object to set up. - * It must be initialized but not active. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The \p source_operation state is not valid (it must be active), or - * the \p target_operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, - psa_hash_operation_t *target_operation); - -/**@}*/ - -/** \defgroup MAC Message authentication codes - * @{ - */ - -/** Calculate the MAC (message authentication code) of a message. - * - * \note To verify the MAC of a message against an - * expected value, use psa_mac_verify() instead. - * Beware that comparing integrity or authenticity data such as - * MAC values with a function such as \c memcmp is risky - * because the time taken by the comparison may leak information - * about the MAC value which could allow an attacker to guess - * a valid MAC and thereby bypass security controls. - * - * \param key Identifier of the key to use for the operation. It - * must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * \param[in] input Buffer containing the input message. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] mac Buffer where the MAC value is to be written. - * \param mac_size Size of the \p mac buffer in bytes. - * \param[out] mac_length On success, the number of bytes - * that make up the MAC value. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p mac_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length); - -/** Calculate the MAC of a message and compare it with a reference value. - * - * \param key Identifier of the key to use for the operation. It - * must allow the usage PSA_KEY_USAGE_VERIFY_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * \param[in] input Buffer containing the input message. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] mac Buffer containing the expected MAC value. - * \param mac_length Size of the \p mac buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected MAC is identical to the actual MAC of the input. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The MAC of the message was calculated successfully, but it - * differs from the expected value. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *mac, - size_t mac_length); - -/** The type of the state data structure for multipart MAC operations. - * - * Before calling any function on a MAC operation object, the application must - * initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_mac_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_mac_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_MAC_OPERATION_INIT, - * for example: - * \code - * psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_mac_operation_init() - * to the structure, for example: - * \code - * psa_mac_operation_t operation; - * operation = psa_mac_operation_init(); - * \endcode - * - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_mac_operation_s psa_mac_operation_t; - -/** \def PSA_MAC_OPERATION_INIT - * - * This macro returns a suitable initializer for a MAC operation object of type - * #psa_mac_operation_t. - */ - -/** Return an initial value for a MAC operation object. - */ -static psa_mac_operation_t psa_mac_operation_init(void); - -/** Set up a multipart MAC calculation operation. - * - * This function sets up the calculation of the MAC - * (message authentication code) of a byte string. - * To verify the MAC of a message against an - * expected value, use psa_mac_verify_setup() instead. - * - * The sequence of operations to calculate a MAC is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. - * -# Call psa_mac_sign_setup() to specify the algorithm and key. - * -# Call psa_mac_update() zero, one or more times, passing a fragment - * of the message each time. The MAC that is calculated is the MAC - * of the concatenation of these messages in order. - * -# At the end of the message, call psa_mac_sign_finish() to finish - * calculating the MAC value and retrieve it. - * - * If an error occurs at any step after a call to psa_mac_sign_setup(), the - * operation will need to be reset by a call to psa_mac_abort(). The - * application may call psa_mac_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_mac_sign_setup(), the application must - * eventually terminate the operation through one of the following methods: - * - A successful call to psa_mac_sign_finish(). - * - A call to psa_mac_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_mac_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. It - * must remain valid until the operation terminates. - * It must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Set up a multipart MAC verification operation. - * - * This function sets up the verification of the MAC - * (message authentication code) of a byte string against an expected value. - * - * The sequence of operations to verify a MAC is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. - * -# Call psa_mac_verify_setup() to specify the algorithm and key. - * -# Call psa_mac_update() zero, one or more times, passing a fragment - * of the message each time. The MAC that is calculated is the MAC - * of the concatenation of these messages in order. - * -# At the end of the message, call psa_mac_verify_finish() to finish - * calculating the actual MAC of the message and verify it against - * the expected value. - * - * If an error occurs at any step after a call to psa_mac_verify_setup(), the - * operation will need to be reset by a call to psa_mac_abort(). The - * application may call psa_mac_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_mac_verify_setup(), the application must - * eventually terminate the operation through one of the following methods: - * - A successful call to psa_mac_verify_finish(). - * - A call to psa_mac_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_mac_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. It - * must remain valid until the operation terminates. - * It must allow the usage - * PSA_KEY_USAGE_VERIFY_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c key is not compatible with \c alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \c alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Add a message fragment to a multipart MAC operation. - * - * The application must call psa_mac_sign_setup() or psa_mac_verify_setup() - * before calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_mac_abort(). - * - * \param[in,out] operation Active MAC operation. - * \param[in] input Buffer containing the message fragment to add to - * the MAC calculation. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_update(psa_mac_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Finish the calculation of the MAC of a message. - * - * The application must call psa_mac_sign_setup() before calling this function. - * This function calculates the MAC of the message formed by concatenating - * the inputs passed to preceding calls to psa_mac_update(). - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_mac_abort(). - * - * \warning Applications should not call this function if they expect - * a specific value for the MAC. Call psa_mac_verify_finish() instead. - * Beware that comparing integrity or authenticity data such as - * MAC values with a function such as \c memcmp is risky - * because the time taken by the comparison may leak information - * about the MAC value which could allow an attacker to guess - * a valid MAC and thereby bypass security controls. - * - * \param[in,out] operation Active MAC operation. - * \param[out] mac Buffer where the MAC value is to be written. - * \param mac_size Size of the \p mac buffer in bytes. - * \param[out] mac_length On success, the number of bytes - * that make up the MAC value. This is always - * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg) - * where \c key_type and \c key_bits are the type and - * bit-size respectively of the key and \c alg is the - * MAC algorithm that is calculated. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p mac buffer is too small. You can determine a - * sufficient buffer size by calling PSA_MAC_LENGTH(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active mac sign - * operation), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, - uint8_t *mac, - size_t mac_size, - size_t *mac_length); - -/** Finish the calculation of the MAC of a message and compare it with - * an expected value. - * - * The application must call psa_mac_verify_setup() before calling this function. - * This function calculates the MAC of the message formed by concatenating - * the inputs passed to preceding calls to psa_mac_update(). It then - * compares the calculated MAC with the expected MAC passed as a - * parameter to this function. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_mac_abort(). - * - * \note Implementations shall make the best effort to ensure that the - * comparison between the actual MAC and the expected MAC is performed - * in constant time. - * - * \param[in,out] operation Active MAC operation. - * \param[in] mac Buffer containing the expected MAC value. - * \param mac_length Size of the \p mac buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected MAC is identical to the actual MAC of the message. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The MAC of the message was calculated successfully, but it - * differs from the expected MAC. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active mac verify - * operation), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, - const uint8_t *mac, - size_t mac_length); - -/** Abort a MAC operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_mac_sign_setup() or psa_mac_verify_setup() again. - * - * You may call this function any time after the operation object has - * been initialized by one of the methods described in #psa_mac_operation_t. - * - * In particular, calling psa_mac_abort() after the operation has been - * terminated by a call to psa_mac_abort(), psa_mac_sign_finish() or - * psa_mac_verify_finish() is safe and has no effect. - * - * \param[in,out] operation Initialized MAC operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_abort(psa_mac_operation_t *operation); - -/**@}*/ - -/** \defgroup cipher Symmetric ciphers - * @{ - */ - -/** Encrypt a message using a symmetric cipher. - * - * This function encrypts a message with a random IV (initialization - * vector). Use the multipart operation interface with a - * #psa_cipher_operation_t object to provide other forms of IV. - * - * \param key Identifier of the key to use for the operation. - * It must allow the usage #PSA_KEY_USAGE_ENCRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param[in] input Buffer containing the message to encrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * The output contains the IV followed by - * the ciphertext proper. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Decrypt a message using a symmetric cipher. - * - * This function decrypts a message encrypted with a symmetric cipher. - * - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param[in] input Buffer containing the message to decrypt. - * This consists of the IV followed by the - * ciphertext proper. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the plaintext is to be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** The type of the state data structure for multipart cipher operations. - * - * Before calling any function on a cipher operation object, the application - * must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_cipher_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_cipher_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_CIPHER_OPERATION_INIT, - * for example: - * \code - * psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_cipher_operation_init() - * to the structure, for example: - * \code - * psa_cipher_operation_t operation; - * operation = psa_cipher_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_cipher_operation_s psa_cipher_operation_t; - -/** \def PSA_CIPHER_OPERATION_INIT - * - * This macro returns a suitable initializer for a cipher operation object of - * type #psa_cipher_operation_t. - */ - -/** Return an initial value for a cipher operation object. - */ -static psa_cipher_operation_t psa_cipher_operation_init(void); - -/** Set the key for a multipart symmetric encryption operation. - * - * The sequence of operations to encrypt a message with a symmetric cipher - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_cipher_operation_t, e.g. - * #PSA_CIPHER_OPERATION_INIT. - * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key. - * -# Call either psa_cipher_generate_iv() or psa_cipher_set_iv() to - * generate or set the IV (initialization vector). You should use - * psa_cipher_generate_iv() unless the protocol you are implementing - * requires a specific IV value. - * -# Call psa_cipher_update() zero, one or more times, passing a fragment - * of the message each time. - * -# Call psa_cipher_finish(). - * - * If an error occurs at any step after a call to psa_cipher_encrypt_setup(), - * the operation will need to be reset by a call to psa_cipher_abort(). The - * application may call psa_cipher_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_cipher_encrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_cipher_finish(). - * - A call to psa_cipher_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_cipher_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Set the key for a multipart symmetric decryption operation. - * - * The sequence of operations to decrypt a message with a symmetric cipher - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_cipher_operation_t, e.g. - * #PSA_CIPHER_OPERATION_INIT. - * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key. - * -# Call psa_cipher_set_iv() with the IV (initialization vector) for the - * decryption. If the IV is prepended to the ciphertext, you can call - * psa_cipher_update() on a buffer containing the IV followed by the - * beginning of the message. - * -# Call psa_cipher_update() zero, one or more times, passing a fragment - * of the message each time. - * -# Call psa_cipher_finish(). - * - * If an error occurs at any step after a call to psa_cipher_decrypt_setup(), - * the operation will need to be reset by a call to psa_cipher_abort(). The - * application may call psa_cipher_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_cipher_decrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_cipher_finish(). - * - A call to psa_cipher_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_cipher_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Generate an IV for a symmetric encryption operation. - * - * This function generates a random IV (initialization vector), nonce - * or initial counter value for the encryption operation as appropriate - * for the chosen algorithm, key type and key size. - * - * The application must call psa_cipher_encrypt_setup() before - * calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \param[in,out] operation Active cipher operation. - * \param[out] iv Buffer where the generated IV is to be written. - * \param iv_size Size of the \p iv buffer in bytes. - * \param[out] iv_length On success, the number of bytes of the - * generated IV. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p iv buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with no IV set), - * or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, - uint8_t *iv, - size_t iv_size, - size_t *iv_length); - -/** Set the IV for a symmetric encryption or decryption operation. - * - * This function sets the IV (initialization vector), nonce - * or initial counter value for the encryption or decryption operation. - * - * The application must call psa_cipher_encrypt_setup() before - * calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \note When encrypting, applications should use psa_cipher_generate_iv() - * instead of this function, unless implementing a protocol that requires - * a non-random IV. - * - * \param[in,out] operation Active cipher operation. - * \param[in] iv Buffer containing the IV to use. - * \param iv_length Size of the IV in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size of \p iv is not acceptable for the chosen algorithm, - * or the chosen algorithm does not use an IV. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active cipher - * encrypt operation, with no IV set), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, - const uint8_t *iv, - size_t iv_length); - -/** Encrypt or decrypt a message fragment in an active cipher operation. - * - * Before calling this function, you must: - * 1. Call either psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup(). - * The choice of setup function determines whether this function - * encrypts or decrypts its input. - * 2. If the algorithm requires an IV, call psa_cipher_generate_iv() - * (recommended when encrypting) or psa_cipher_set_iv(). - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \param[in,out] operation Active cipher operation. - * \param[in] input Buffer containing the message fragment to - * encrypt or decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with an IV set - * if required for the algorithm), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Finish encrypting or decrypting a message in a cipher operation. - * - * The application must call psa_cipher_encrypt_setup() or - * psa_cipher_decrypt_setup() before calling this function. The choice - * of setup function determines whether this function encrypts or - * decrypts its input. - * - * This function finishes the encryption or decryption of the message - * formed by concatenating the inputs passed to preceding calls to - * psa_cipher_update(). - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \param[in,out] operation Active cipher operation. - * \param[out] output Buffer where the output is to be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total input size passed to this operation is not valid for - * this particular algorithm. For example, the algorithm is a based - * on block cipher and requires a whole number of blocks, but the - * total input size is not a multiple of the block size. - * \retval #PSA_ERROR_INVALID_PADDING - * This is a decryption operation for an algorithm that includes - * padding, and the ciphertext does not contain valid padding. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with an IV set - * if required for the algorithm), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Abort a cipher operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup() again. - * - * You may call this function any time after the operation object has - * been initialized as described in #psa_cipher_operation_t. - * - * In particular, calling psa_cipher_abort() after the operation has been - * terminated by a call to psa_cipher_abort() or psa_cipher_finish() - * is safe and has no effect. - * - * \param[in,out] operation Initialized cipher operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); - -/**@}*/ - -/** \defgroup aead Authenticated encryption with associated data (AEAD) - * @{ - */ - -/** Process an authenticated encryption operation. - * - * \param key Identifier of the key to use for the - * operation. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * \param[in] nonce Nonce or IV to use. - * \param nonce_length Size of the \p nonce buffer in bytes. - * \param[in] additional_data Additional data that will be authenticated - * but not encrypted. - * \param additional_data_length Size of \p additional_data in bytes. - * \param[in] plaintext Data that will be authenticated and - * encrypted. - * \param plaintext_length Size of \p plaintext in bytes. - * \param[out] ciphertext Output buffer for the authenticated and - * encrypted data. The additional data is not - * part of this output. For algorithms where the - * encrypted data and the authentication tag - * are defined as separate outputs, the - * authentication tag is appended to the - * encrypted data. - * \param ciphertext_size Size of the \p ciphertext buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, - * \p alg, \p plaintext_length) where - * \c key_type is the type of \p key. - * - #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p - * plaintext_length) evaluates to the maximum - * ciphertext size of any supported AEAD - * encryption. - * \param[out] ciphertext_length On success, the size of the output - * in the \p ciphertext buffer. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p ciphertext_size is too small. - * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, \p alg, - * \p plaintext_length) or - * #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length) can be used to - * determine the required buffer size. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *plaintext, - size_t plaintext_length, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length); - -/** Process an authenticated decryption operation. - * - * \param key Identifier of the key to use for the - * operation. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * \param[in] nonce Nonce or IV to use. - * \param nonce_length Size of the \p nonce buffer in bytes. - * \param[in] additional_data Additional data that has been authenticated - * but not encrypted. - * \param additional_data_length Size of \p additional_data in bytes. - * \param[in] ciphertext Data that has been authenticated and - * encrypted. For algorithms where the - * encrypted data and the authentication tag - * are defined as separate inputs, the buffer - * must contain the encrypted data followed - * by the authentication tag. - * \param ciphertext_length Size of \p ciphertext in bytes. - * \param[out] plaintext Output buffer for the decrypted data. - * \param plaintext_size Size of the \p plaintext buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, - * \p alg, \p ciphertext_length) where - * \c key_type is the type of \p key. - * - #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p - * ciphertext_length) evaluates to the maximum - * plaintext size of any supported AEAD - * decryption. - * \param[out] plaintext_length On success, the size of the output - * in the \p plaintext buffer. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The ciphertext is not authentic. - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p plaintext_size is too small. - * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, \p alg, - * \p ciphertext_length) or - * #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length) can be used - * to determine the required buffer size. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *ciphertext, - size_t ciphertext_length, - uint8_t *plaintext, - size_t plaintext_size, - size_t *plaintext_length); - -/** The type of the state data structure for multipart AEAD operations. - * - * Before calling any function on an AEAD operation object, the application - * must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_aead_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_aead_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_AEAD_OPERATION_INIT, - * for example: - * \code - * psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_aead_operation_init() - * to the structure, for example: - * \code - * psa_aead_operation_t operation; - * operation = psa_aead_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_aead_operation_s psa_aead_operation_t; - -/** \def PSA_AEAD_OPERATION_INIT - * - * This macro returns a suitable initializer for an AEAD operation object of - * type #psa_aead_operation_t. - */ - -/** Return an initial value for an AEAD operation object. - */ -static psa_aead_operation_t psa_aead_operation_init(void); - -/** Set the key for a multipart authenticated encryption operation. - * - * The sequence of operations to encrypt a message with authentication - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_aead_operation_t, e.g. - * #PSA_AEAD_OPERATION_INIT. - * -# Call psa_aead_encrypt_setup() to specify the algorithm and key. - * -# If needed, call psa_aead_set_lengths() to specify the length of the - * inputs to the subsequent calls to psa_aead_update_ad() and - * psa_aead_update(). See the documentation of psa_aead_set_lengths() - * for details. - * -# Call either psa_aead_generate_nonce() or psa_aead_set_nonce() to - * generate or set the nonce. You should use - * psa_aead_generate_nonce() unless the protocol you are implementing - * requires a specific nonce value. - * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment - * of the non-encrypted additional authenticated data each time. - * -# Call psa_aead_update() zero, one or more times, passing a fragment - * of the message to encrypt each time. - * -# Call psa_aead_finish(). - * - * If an error occurs at any step after a call to psa_aead_encrypt_setup(), - * the operation will need to be reset by a call to psa_aead_abort(). The - * application may call psa_aead_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_aead_encrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_aead_finish(). - * - A call to psa_aead_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_aead_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Set the key for a multipart authenticated decryption operation. - * - * The sequence of operations to decrypt a message with authentication - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_aead_operation_t, e.g. - * #PSA_AEAD_OPERATION_INIT. - * -# Call psa_aead_decrypt_setup() to specify the algorithm and key. - * -# If needed, call psa_aead_set_lengths() to specify the length of the - * inputs to the subsequent calls to psa_aead_update_ad() and - * psa_aead_update(). See the documentation of psa_aead_set_lengths() - * for details. - * -# Call psa_aead_set_nonce() with the nonce for the decryption. - * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment - * of the non-encrypted additional authenticated data each time. - * -# Call psa_aead_update() zero, one or more times, passing a fragment - * of the ciphertext to decrypt each time. - * -# Call psa_aead_verify(). - * - * If an error occurs at any step after a call to psa_aead_decrypt_setup(), - * the operation will need to be reset by a call to psa_aead_abort(). The - * application may call psa_aead_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_aead_decrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_aead_verify(). - * - A call to psa_aead_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_aead_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or the - * library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Generate a random nonce for an authenticated encryption operation. - * - * This function generates a random nonce for the authenticated encryption - * operation with an appropriate size for the chosen algorithm, key type - * and key size. - * - * The application must call psa_aead_encrypt_setup() before - * calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param[out] nonce Buffer where the generated nonce is to be - * written. - * \param nonce_size Size of the \p nonce buffer in bytes. - * \param[out] nonce_length On success, the number of bytes of the - * generated nonce. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p nonce buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active aead encrypt - * operation, with no nonce set), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, - uint8_t *nonce, - size_t nonce_size, - size_t *nonce_length); - -/** Set the nonce for an authenticated encryption or decryption operation. - * - * This function sets the nonce for the authenticated - * encryption or decryption operation. - * - * The application must call psa_aead_encrypt_setup() or - * psa_aead_decrypt_setup() before calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \note When encrypting, applications should use psa_aead_generate_nonce() - * instead of this function, unless implementing a protocol that requires - * a non-random IV. - * - * \param[in,out] operation Active AEAD operation. - * \param[in] nonce Buffer containing the nonce to use. - * \param nonce_length Size of the nonce in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size of \p nonce is not acceptable for the chosen algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with no nonce - * set), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, - const uint8_t *nonce, - size_t nonce_length); - -/** Declare the lengths of the message and additional data for AEAD. - * - * The application must call this function before calling - * psa_aead_update_ad() or psa_aead_update() if the algorithm for - * the operation requires it. If the algorithm does not require it, - * calling this function is optional, but if this function is called - * then the implementation must enforce the lengths. - * - * You may call this function before or after setting the nonce with - * psa_aead_set_nonce() or psa_aead_generate_nonce(). - * - * - For #PSA_ALG_CCM, calling this function is required. - * - For the other AEAD algorithms defined in this specification, calling - * this function is not required. - * - For vendor-defined algorithm, refer to the vendor documentation. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param ad_length Size of the non-encrypted additional - * authenticated data in bytes. - * \param plaintext_length Size of the plaintext to encrypt in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * At least one of the lengths is not acceptable for the chosen - * algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, and - * psa_aead_update_ad() and psa_aead_update() must not have been - * called yet), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, - size_t ad_length, - size_t plaintext_length); - -/** Pass additional data to an active AEAD operation. - * - * Additional data is authenticated, but not encrypted. - * - * You may call this function multiple times to pass successive fragments - * of the additional data. You may not call this function after passing - * data to encrypt or decrypt with psa_aead_update(). - * - * Before calling this function, you must: - * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). - * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, - * there is no guarantee that the input is valid. Therefore, until - * you have called psa_aead_verify() and it has returned #PSA_SUCCESS, - * treat the input as untrusted and prepare to undo any action that - * depends on the input if psa_aead_verify() returns an error status. - * - * \param[in,out] operation Active AEAD operation. - * \param[in] input Buffer containing the fragment of - * additional data. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total input length overflows the additional data length that - * was previously specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, have a nonce - * set, have lengths set if required by the algorithm, and - * psa_aead_update() must not have been called yet), or the library - * has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Encrypt or decrypt a message fragment in an active AEAD operation. - * - * Before calling this function, you must: - * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). - * The choice of setup function determines whether this function - * encrypts or decrypts its input. - * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). - * 3. Call psa_aead_update_ad() to pass all the additional data. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, - * there is no guarantee that the input is valid. Therefore, until - * you have called psa_aead_verify() and it has returned #PSA_SUCCESS: - * - Do not use the output in any way other than storing it in a - * confidential location. If you take any action that depends - * on the tentative decrypted data, this action will need to be - * undone if the input turns out not to be valid. Furthermore, - * if an adversary can observe that this action took place - * (for example through timing), they may be able to use this - * fact as an oracle to decrypt any message encrypted with the - * same key. - * - In particular, do not copy the output anywhere but to a - * memory or storage space that you have exclusive access to. - * - * This function does not require the input to be aligned to any - * particular block boundary. If the implementation can only process - * a whole block at a time, it must consume all the input provided, but - * it may delay the end of the corresponding output until a subsequent - * call to psa_aead_update(), psa_aead_finish() or psa_aead_verify() - * provides sufficient input. The amount of data that can be delayed - * in this way is bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE. - * - * \param[in,out] operation Active AEAD operation. - * \param[in] input Buffer containing the message fragment to - * encrypt or decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * \param output_size Size of the \p output buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, - * \c alg, \p input_length) where - * \c key_type is the type of key and \c alg is - * the algorithm that were used to set up the - * operation. - * - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p - * input_length) evaluates to the maximum - * output size of any supported AEAD - * algorithm. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or - * #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to - * determine the required buffer size. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total length of input to psa_aead_update_ad() so far is - * less than the additional data length that was previously - * specified with psa_aead_set_lengths(), or - * the total input length overflows the plaintext length that - * was previously specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, have a nonce - * set, and have lengths set if required by the algorithm), or the - * library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_update(psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Finish encrypting a message in an AEAD operation. - * - * The operation must have been set up with psa_aead_encrypt_setup(). - * - * This function finishes the authentication of the additional data - * formed by concatenating the inputs passed to preceding calls to - * psa_aead_update_ad() with the plaintext formed by concatenating the - * inputs passed to preceding calls to psa_aead_update(). - * - * This function has two output buffers: - * - \p ciphertext contains trailing ciphertext that was buffered from - * preceding calls to psa_aead_update(). - * - \p tag contains the authentication tag. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param[out] ciphertext Buffer where the last part of the ciphertext - * is to be written. - * \param ciphertext_size Size of the \p ciphertext buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, - * \c alg) where \c key_type is the type of key - * and \c alg is the algorithm that were used to - * set up the operation. - * - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to - * the maximum output size of any supported AEAD - * algorithm. - * \param[out] ciphertext_length On success, the number of bytes of - * returned ciphertext. - * \param[out] tag Buffer where the authentication tag is - * to be written. - * \param tag_size Size of the \p tag buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c - * key_type, \c key_bits, \c alg) where - * \c key_type and \c key_bits are the type and - * bit-size of the key, and \c alg is the - * algorithm that were used in the call to - * psa_aead_encrypt_setup(). - * - #PSA_AEAD_TAG_MAX_SIZE evaluates to the - * maximum tag size of any supported AEAD - * algorithm. - * \param[out] tag_length On success, the number of bytes - * that make up the returned tag. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p ciphertext or \p tag buffer is too small. - * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, \c alg) or - * #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE can be used to determine the - * required \p ciphertext buffer size. #PSA_AEAD_TAG_LENGTH(\c key_type, - * \c key_bits, \c alg) or #PSA_AEAD_TAG_MAX_SIZE can be used to - * determine the required \p tag buffer size. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total length of input to psa_aead_update_ad() so far is - * less than the additional data length that was previously - * specified with psa_aead_set_lengths(), or - * the total length of input to psa_aead_update() so far is - * less than the plaintext length that was previously - * specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active encryption - * operation with a nonce set), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_finish(psa_aead_operation_t *operation, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length, - uint8_t *tag, - size_t tag_size, - size_t *tag_length); - -/** Finish authenticating and decrypting a message in an AEAD operation. - * - * The operation must have been set up with psa_aead_decrypt_setup(). - * - * This function finishes the authenticated decryption of the message - * components: - * - * - The additional data consisting of the concatenation of the inputs - * passed to preceding calls to psa_aead_update_ad(). - * - The ciphertext consisting of the concatenation of the inputs passed to - * preceding calls to psa_aead_update(). - * - The tag passed to this function call. - * - * If the authentication tag is correct, this function outputs any remaining - * plaintext and reports success. If the authentication tag is not correct, - * this function returns #PSA_ERROR_INVALID_SIGNATURE. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \note Implementations shall make the best effort to ensure that the - * comparison between the actual tag and the expected tag is performed - * in constant time. - * - * \param[in,out] operation Active AEAD operation. - * \param[out] plaintext Buffer where the last part of the plaintext - * is to be written. This is the remaining data - * from previous calls to psa_aead_update() - * that could not be processed until the end - * of the input. - * \param plaintext_size Size of the \p plaintext buffer in bytes. - * This must be appropriate for the selected algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, - * \c alg) where \c key_type is the type of key - * and \c alg is the algorithm that were used to - * set up the operation. - * - #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE evaluates to - * the maximum output size of any supported AEAD - * algorithm. - * \param[out] plaintext_length On success, the number of bytes of - * returned plaintext. - * \param[in] tag Buffer containing the authentication tag. - * \param tag_length Size of the \p tag buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculations were successful, but the authentication tag is - * not correct. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p plaintext buffer is too small. - * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, \c alg) or - * #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE can be used to determine the - * required buffer size. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total length of input to psa_aead_update_ad() so far is - * less than the additional data length that was previously - * specified with psa_aead_set_lengths(), or - * the total length of input to psa_aead_update() so far is - * less than the plaintext length that was previously - * specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active decryption - * operation with a nonce set), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_verify(psa_aead_operation_t *operation, - uint8_t *plaintext, - size_t plaintext_size, - size_t *plaintext_length, - const uint8_t *tag, - size_t tag_length); - -/** Abort an AEAD operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_aead_encrypt_setup() or psa_aead_decrypt_setup() again. - * - * You may call this function any time after the operation object has - * been initialized as described in #psa_aead_operation_t. - * - * In particular, calling psa_aead_abort() after the operation has been - * terminated by a call to psa_aead_abort(), psa_aead_finish() or - * psa_aead_verify() is safe and has no effect. - * - * \param[in,out] operation Initialized AEAD operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_abort(psa_aead_operation_t *operation); - -/**@}*/ - -/** \defgroup asymmetric Asymmetric cryptography - * @{ - */ - -/** - * \brief Sign a message with a private key. For hash-and-sign algorithms, - * this includes the hashing step. - * - * \note To perform a multi-part hash-and-sign signature algorithm, first use - * a multi-part hash operation and then pass the resulting hash to - * psa_sign_hash(). PSA_ALG_GET_HASH(\p alg) can be used to determine the - * hash algorithm to use. - * - * \param[in] key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. The key must - * allow the usage #PSA_KEY_USAGE_SIGN_MESSAGE. - * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) - * is true), that is compatible with the type of - * \p key. - * \param[in] input The input message to sign. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param[in] signature_size Size of the \p signature buffer in bytes. This - * must be appropriate for the selected - * algorithm and key: - * - The required signature size is - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and - * bit-size respectively of key. - * - #PSA_SIGNATURE_MAX_SIZE evaluates to the - * maximum signature size of any supported - * signature algorithm. - * \param[out] signature_length On success, the number of bytes that make up - * the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, - * or it does not permit the requested algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length); - -/** \brief Verify the signature of a message with a public key, using - * a hash-and-sign verification algorithm. - * - * \note To perform a multi-part hash-and-sign signature verification - * algorithm, first use a multi-part hash operation to hash the message - * and then pass the resulting hash to psa_verify_hash(). - * PSA_ALG_GET_HASH(\p alg) can be used to determine the hash algorithm - * to use. - * - * \param[in] key Identifier of the key to use for the operation. - * It must be a public key or an asymmetric key - * pair. The key must allow the usage - * #PSA_KEY_USAGE_VERIFY_MESSAGE. - * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) - * is true), that is compatible with the type of - * \p key. - * \param[in] input The message whose signature is to be verified. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param[in] signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, - * or it does not permit the requested algorithm. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed signature - * is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *signature, - size_t signature_length); - -/** - * \brief Sign a hash or short message with a private key. - * - * Note that to perform a hash-and-sign signature algorithm, you must - * first calculate the hash by calling psa_hash_setup(), psa_hash_update() - * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). - * Then pass the resulting hash as the \p hash - * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) - * to determine the hash algorithm to use. - * - * \param key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. The key must - * allow the usage #PSA_KEY_USAGE_SIGN_HASH. - * \param alg A signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash or message to sign. - * \param hash_length Size of the \p hash buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param signature_size Size of the \p signature buffer in bytes. - * \param[out] signature_length On success, the number of bytes - * that make up the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length); - -/** - * \brief Verify the signature of a hash or short message using a public key. - * - * Note that to perform a hash-and-sign signature algorithm, you must - * first calculate the hash by calling psa_hash_setup(), psa_hash_update() - * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). - * Then pass the resulting hash as the \p hash - * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) - * to determine the hash algorithm to use. - * - * \param key Identifier of the key to use for the operation. It - * must be a public key or an asymmetric key pair. The - * key must allow the usage - * #PSA_KEY_USAGE_VERIFY_HASH. - * \param alg A signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash or message whose signature is to be - * verified. - * \param hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The signature is valid. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - const uint8_t *signature, - size_t signature_length); - -/** - * \brief Encrypt a short message with a public key. - * - * \param key Identifier of the key to use for the operation. - * It must be a public key or an asymmetric key - * pair. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg An asymmetric encryption algorithm that is - * compatible with the type of \p key. - * \param[in] input The message to encrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] salt A salt or label, if supported by the - * encryption algorithm. - * If the algorithm does not support a - * salt, pass \c NULL. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass \c NULL. - * - * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param salt_length Size of the \p salt buffer in bytes. - * If \p salt is \c NULL, pass 0. - * \param[out] output Buffer where the encrypted message is to - * be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** - * \brief Decrypt a short message with a private key. - * - * \param key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. It must - * allow the usage #PSA_KEY_USAGE_DECRYPT. - * \param alg An asymmetric encryption algorithm that is - * compatible with the type of \p key. - * \param[in] input The message to decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] salt A salt or label, if supported by the - * encryption algorithm. - * If the algorithm does not support a - * salt, pass \c NULL. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass \c NULL. - * - * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param salt_length Size of the \p salt buffer in bytes. - * If \p salt is \c NULL, pass 0. - * \param[out] output Buffer where the decrypted message is to - * be written. - * \param output_size Size of the \c output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_INVALID_PADDING \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/**@}*/ - -/** \defgroup key_derivation Key derivation and pseudorandom generation - * @{ - */ - -/** The type of the state data structure for key derivation operations. - * - * Before calling any function on a key derivation operation object, the - * application must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_key_derivation_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_key_derivation_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_KEY_DERIVATION_OPERATION_INIT, - * for example: - * \code - * psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_key_derivation_operation_init() - * to the structure, for example: - * \code - * psa_key_derivation_operation_t operation; - * operation = psa_key_derivation_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. - */ -typedef struct psa_key_derivation_s psa_key_derivation_operation_t; - -/** \def PSA_KEY_DERIVATION_OPERATION_INIT - * - * This macro returns a suitable initializer for a key derivation operation - * object of type #psa_key_derivation_operation_t. - */ - -/** Return an initial value for a key derivation operation object. - */ -static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); - -/** Set up a key derivation operation. - * - * A key derivation algorithm takes some inputs and uses them to generate - * a byte stream in a deterministic way. - * This byte stream can be used to produce keys and other - * cryptographic material. - * - * To derive a key: - * -# Start with an initialized object of type #psa_key_derivation_operation_t. - * -# Call psa_key_derivation_setup() to select the algorithm. - * -# Provide the inputs for the key derivation by calling - * psa_key_derivation_input_bytes() or psa_key_derivation_input_key() - * as appropriate. Which inputs are needed, in what order, and whether - * they may be keys and if so of what type depends on the algorithm. - * -# Optionally set the operation's maximum capacity with - * psa_key_derivation_set_capacity(). You may do this before, in the middle - * of or after providing inputs. For some algorithms, this step is mandatory - * because the output depends on the maximum capacity. - * -# To derive a key, call psa_key_derivation_output_key() or - * psa_key_derivation_output_key_custom(). - * To derive a byte string for a different purpose, call - * psa_key_derivation_output_bytes(). - * Successive calls to these functions use successive output bytes - * calculated by the key derivation algorithm. - * -# Clean up the key derivation operation object with - * psa_key_derivation_abort(). - * - * If this function returns an error, the key derivation operation object is - * not changed. - * - * If an error occurs at any step after a call to psa_key_derivation_setup(), - * the operation will need to be reset by a call to psa_key_derivation_abort(). - * - * Implementations must reject an attempt to derive a key of size 0. - * - * \param[in,out] operation The key derivation operation object - * to set up. It must - * have been initialized but not set up yet. - * \param alg The key derivation algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c alg is not a key derivation algorithm. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \c alg is not supported or is not a key derivation algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_setup( - psa_key_derivation_operation_t *operation, - psa_algorithm_t alg); - -/** Retrieve the current capacity of a key derivation operation. - * - * The capacity of a key derivation is the maximum number of bytes that it can - * return. When you get *N* bytes of output from a key derivation operation, - * this reduces its capacity by *N*. - * - * \param[in] operation The operation to query. - * \param[out] capacity On success, the capacity of the operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_get_capacity( - const psa_key_derivation_operation_t *operation, - size_t *capacity); - -/** Set the maximum capacity of a key derivation operation. - * - * The capacity of a key derivation operation is the maximum number of bytes - * that the key derivation operation can return from this point onwards. - * - * \param[in,out] operation The key derivation operation object to modify. - * \param capacity The new capacity of the operation. - * It must be less or equal to the operation's - * current capacity. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p capacity is larger than the operation's current capacity. - * In this case, the operation object remains valid and its capacity - * remains unchanged. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or the - * library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_set_capacity( - psa_key_derivation_operation_t *operation, - size_t capacity); - -/** Use the maximum possible capacity for a key derivation operation. - * - * Use this value as the capacity argument when setting up a key derivation - * to indicate that the operation should have the maximum possible capacity. - * The value of the maximum possible capacity depends on the key derivation - * algorithm. - */ -#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY ((size_t) (-1)) - -/** Provide an input for key derivation or key agreement. - * - * Which inputs are required and in what order depends on the algorithm. - * Refer to the documentation of each key derivation or key agreement - * algorithm for information. - * - * This function passes direct inputs, which is usually correct for - * non-secret inputs. To pass a secret input, which should be in a key - * object, call psa_key_derivation_input_key() instead of this function. - * Refer to the documentation of individual step types - * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) - * for more information. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() and must not - * have produced any output yet. - * \param step Which step the input data is for. - * \param[in] data Input data to use. - * \param data_length Size of the \p data buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c step is not compatible with the operation's algorithm, or - * \c step does not allow direct inputs. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this input \p step, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_input_bytes( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - const uint8_t *data, - size_t data_length); - -/** Provide a numeric input for key derivation or key agreement. - * - * Which inputs are required and in what order depends on the algorithm. - * However, when an algorithm requires a particular order, numeric inputs - * usually come first as they tend to be configuration parameters. - * Refer to the documentation of each key derivation or key agreement - * algorithm for information. - * - * This function is used for inputs which are fixed-size non-negative - * integers. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() and must not - * have produced any output yet. - * \param step Which step the input data is for. - * \param[in] value The value of the numeric input. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c step is not compatible with the operation's algorithm, or - * \c step does not allow numeric inputs. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this input \p step, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_input_integer( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - uint64_t value); - -/** Provide an input for key derivation in the form of a key. - * - * Which inputs are required and in what order depends on the algorithm. - * Refer to the documentation of each key derivation or key agreement - * algorithm for information. - * - * This function obtains input from a key object, which is usually correct for - * secret inputs or for non-secret personalization strings kept in the key - * store. To pass a non-secret parameter which is not in the key store, - * call psa_key_derivation_input_bytes() instead of this function. - * Refer to the documentation of individual step types - * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) - * for more information. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() and must not - * have produced any output yet. - * \param step Which step the input data is for. - * \param key Identifier of the key. It must have an - * appropriate type for step and must allow the - * usage #PSA_KEY_USAGE_DERIVE or - * #PSA_KEY_USAGE_VERIFY_DERIVATION (see note) - * and the algorithm used by the operation. - * - * \note Once all inputs steps are completed, the operations will allow: - * - psa_key_derivation_output_bytes() if each input was either a direct input - * or a key with #PSA_KEY_USAGE_DERIVE set; - * - psa_key_derivation_output_key() or psa_key_derivation_output_key_custom() - * if the input for step - * #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD - * was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was - * either a direct input or a key with #PSA_KEY_USAGE_DERIVE set; - * - psa_key_derivation_verify_bytes() if each input was either a direct input - * or a key with #PSA_KEY_USAGE_VERIFY_DERIVATION set; - * - psa_key_derivation_verify_key() under the same conditions as - * psa_key_derivation_verify_bytes(). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key allows neither #PSA_KEY_USAGE_DERIVE nor - * #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this - * algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c step is not compatible with the operation's algorithm, or - * \c step does not allow key inputs of the given type - * or does not allow key inputs at all. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this input \p step, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_input_key( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - mbedtls_svc_key_id_t key); - -/** Perform a key agreement and use the shared secret as input to a key - * derivation. - * - * A key agreement algorithm takes two inputs: a private key \p private_key - * a public key \p peer_key. - * The result of this function is passed as input to a key derivation. - * The output of this key derivation can be extracted by reading from the - * resulting operation to produce keys and other cryptographic material. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() with a - * key agreement and derivation algorithm - * \c alg (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_KEY_AGREEMENT(\c alg) is true - * and #PSA_ALG_IS_RAW_KEY_AGREEMENT(\c alg) - * is false). - * The operation must be ready for an - * input of the type given by \p step. - * \param step Which step the input data is for. - * \param private_key Identifier of the private key to use. It must - * allow the usage #PSA_KEY_USAGE_DERIVE. - * \param[in] peer_key Public key of the peer. The peer key must be in the - * same format that psa_import_key() accepts for the - * public key type corresponding to the type of - * private_key. That is, this function performs the - * equivalent of - * #psa_import_key(..., - * `peer_key`, `peer_key_length`) where - * with key attributes indicating the public key - * type corresponding to the type of `private_key`. - * For example, for EC keys, this means that peer_key - * is interpreted as a point on the curve that the - * private key is on. The standard formats for public - * keys are documented in the documentation of - * psa_export_public_key(). - * \param peer_key_length Size of \p peer_key in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c private_key is not compatible with \c alg, - * or \p peer_key is not valid for \c alg or not compatible with - * \c private_key, or \c step does not allow an input resulting - * from a key agreement. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \c alg is not supported or is not a key derivation algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this key agreement \p step, - * or the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_key_agreement( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key, - size_t peer_key_length); - -/** Read some data from a key derivation operation. - * - * This function calculates output bytes from a key derivation algorithm and - * return those bytes. - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads the requested number of bytes from the - * stream. - * The operation's capacity decreases by the number of bytes read. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to read from. - * \param[out] output Buffer where the output will be written. - * \param output_length Number of bytes to output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * One of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * The operation's capacity was less than - * \p output_length bytes. Note that in this case, - * no output is written to the output buffer. - * The operation's capacity is set to 0, thus - * subsequent calls to this function will not - * succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_output_bytes( - psa_key_derivation_operation_t *operation, - uint8_t *output, - size_t output_length); - -/** Derive a key from an ongoing key derivation operation. - * - * This function calculates output bytes from a key derivation algorithm - * and uses those bytes to generate a key deterministically. - * The key's location, usage policy, type and size are taken from - * \p attributes. - * - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads as many bytes as required from the - * stream. - * The operation's capacity decreases by the number of bytes read. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * How much output is produced and consumed from the operation, and how - * the key is derived, depends on the key type and on the key size - * (denoted \c bits below): - * - * - For key types for which the key is an arbitrary sequence of bytes - * of a given size, this function is functionally equivalent to - * calling #psa_key_derivation_output_bytes - * and passing the resulting output to #psa_import_key. - * However, this function has a security benefit: - * if the implementation provides an isolation boundary then - * the key material is not exposed outside the isolation boundary. - * As a consequence, for these key types, this function always consumes - * exactly (\c bits / 8) bytes from the operation. - * The following key types defined in this specification follow this scheme: - * - * - #PSA_KEY_TYPE_AES; - * - #PSA_KEY_TYPE_ARIA; - * - #PSA_KEY_TYPE_CAMELLIA; - * - #PSA_KEY_TYPE_DERIVE; - * - #PSA_KEY_TYPE_HMAC; - * - #PSA_KEY_TYPE_PASSWORD_HASH. - * - * - For ECC keys on a Montgomery elliptic curve - * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a - * Montgomery curve), this function always draws a byte string whose - * length is determined by the curve, and sets the mandatory bits - * accordingly. That is: - * - * - Curve25519 (#PSA_ECC_FAMILY_MONTGOMERY, 255 bits): draw a 32-byte - * string and process it as specified in RFC 7748 §5. - * - Curve448 (#PSA_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte - * string and process it as specified in RFC 7748 §5. - * - * - For key types for which the key is represented by a single sequence of - * \c bits bits with constraints as to which bit sequences are acceptable, - * this function draws a byte string of length (\c bits / 8) bytes rounded - * up to the nearest whole number of bytes. If the resulting byte string - * is acceptable, it becomes the key, otherwise the drawn bytes are discarded. - * This process is repeated until an acceptable byte string is drawn. - * The byte string drawn from the operation is interpreted as specified - * for the output produced by psa_export_key(). - * The following key types defined in this specification follow this scheme: - * - * - #PSA_KEY_TYPE_DES. - * Force-set the parity bits, but discard forbidden weak keys. - * For 2-key and 3-key triple-DES, the three keys are generated - * successively (for example, for 3-key triple-DES, - * if the first 8 bytes specify a weak key and the next 8 bytes do not, - * discard the first 8 bytes, use the next 8 bytes as the first key, - * and continue reading output from the operation to derive the other - * two keys). - * - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEY_PAIR(\c group) - * where \c group designates any Diffie-Hellman group) and - * ECC keys on a Weierstrass elliptic curve - * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a - * Weierstrass curve). - * For these key types, interpret the byte string as integer - * in big-endian order. Discard it if it is not in the range - * [0, *N* - 2] where *N* is the boundary of the private key domain - * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA, - * or the order of the curve's base point for ECC). - * Add 1 to the resulting integer and use this as the private key *x*. - * This method allows compliance to NIST standards, specifically - * the methods titled "key-pair generation by testing candidates" - * in NIST SP 800-56A §5.6.1.1.4 for Diffie-Hellman, - * in FIPS 186-4 §B.1.2 for DSA, and - * in NIST SP 800-56A §5.6.1.2.2 or - * FIPS 186-4 §B.4.2 for elliptic curve keys. - * - * - For other key types, including #PSA_KEY_TYPE_RSA_KEY_PAIR, - * the way in which the operation output is consumed is - * implementation-defined. - * - * In all cases, the data that is read is discarded from the operation. - * The operation's capacity is decreased by the number of bytes read. - * - * For algorithms that take an input step #PSA_KEY_DERIVATION_INPUT_SECRET, - * the input to that step must be provided with psa_key_derivation_input_key(). - * Future versions of this specification may include additional restrictions - * on the derived key based on the attributes and strength of the secret key. - * - * \note This function is equivalent to calling - * psa_key_derivation_output_key_custom() - * with the custom production parameters #PSA_CUSTOM_KEY_PARAMETERS_INIT - * and `custom_data_length == 0` (i.e. `custom_data` is empty). - * - * \param[in] attributes The attributes for the new key. - * If the key type to be created is - * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in - * the policy must be the same as in the current - * operation. - * \param[in,out] operation The key derivation operation object to read from. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * There was not enough data to create the desired key. - * Note that in this case, no output is written to the output buffer. - * The operation's capacity is set to 0, thus subsequent calls to - * this function will not succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size is not supported, either by the - * implementation in general or in this particular location. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The provided key attributes are not valid for the operation. - * \retval #PSA_ERROR_NOT_PERMITTED - * The #PSA_KEY_DERIVATION_INPUT_SECRET or - * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a - * key; or one of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_output_key( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t *key); - -/** Derive a key from an ongoing key derivation operation with custom - * production parameters. - * - * See the description of psa_key_derivation_out_key() for the operation of - * this function with the default production parameters. - * Mbed TLS currently does not currently support any non-default production - * parameters. - * - * \note This function is experimental and may change in future minor - * versions of Mbed TLS. - * - * \param[in] attributes The attributes for the new key. - * If the key type to be created is - * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in - * the policy must be the same as in the current - * operation. - * \param[in,out] operation The key derivation operation object to read from. - * \param[in] custom Customization parameters for the key generation. - * When this is #PSA_CUSTOM_KEY_PARAMETERS_INIT - * with \p custom_data_length = 0, - * this function is equivalent to - * psa_key_derivation_output_key(). - * \param[in] custom_data Variable-length data associated with \c custom. - * \param custom_data_length - * Length of `custom_data` in bytes. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * There was not enough data to create the desired key. - * Note that in this case, no output is written to the output buffer. - * The operation's capacity is set to 0, thus subsequent calls to - * this function will not succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size is not supported, either by the - * implementation in general or in this particular location. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The provided key attributes are not valid for the operation. - * \retval #PSA_ERROR_NOT_PERMITTED - * The #PSA_KEY_DERIVATION_INPUT_SECRET or - * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a - * key; or one of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_output_key_custom( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - const psa_custom_key_parameters_t *custom, - const uint8_t *custom_data, - size_t custom_data_length, - mbedtls_svc_key_id_t *key); - -#ifndef __cplusplus -/* Omitted when compiling in C++, because one of the parameters is a - * pointer to a struct with a flexible array member, and that is not - * standard C++. - * https://github.com/Mbed-TLS/mbedtls/issues/9020 - */ -/** Derive a key from an ongoing key derivation operation with custom - * production parameters. - * - * \note - * This is a deprecated variant of psa_key_derivation_output_key_custom(). - * It is equivalent except that the associated variable-length data - * is passed in `params->data` instead of a separate parameter. - * This function will be removed in a future version of Mbed TLS. - * - * \param[in] attributes The attributes for the new key. - * If the key type to be created is - * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in - * the policy must be the same as in the current - * operation. - * \param[in,out] operation The key derivation operation object to read from. - * \param[in] params Customization parameters for the key derivation. - * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT - * with \p params_data_length = 0, - * this function is equivalent to - * psa_key_derivation_output_key(). - * Mbed TLS currently only supports the default - * production parameters, i.e. - * #PSA_KEY_PRODUCTION_PARAMETERS_INIT, - * for all key types. - * \param params_data_length - * Length of `params->data` in bytes. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * There was not enough data to create the desired key. - * Note that in this case, no output is written to the output buffer. - * The operation's capacity is set to 0, thus subsequent calls to - * this function will not succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size is not supported, either by the - * implementation in general or in this particular location. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The provided key attributes are not valid for the operation. - * \retval #PSA_ERROR_NOT_PERMITTED - * The #PSA_KEY_DERIVATION_INPUT_SECRET or - * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a - * key; or one of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_output_key_ext( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - const psa_key_production_parameters_t *params, - size_t params_data_length, - mbedtls_svc_key_id_t *key); -#endif /* !__cplusplus */ - -/** Compare output data from a key derivation operation to an expected value. - * - * This function calculates output bytes from a key derivation algorithm and - * compares those bytes to an expected value in constant time. - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads the expected number of bytes from the - * stream before comparing them. - * The operation's capacity decreases by the number of bytes read. - * - * This is functionally equivalent to the following code: - * \code - * psa_key_derivation_output_bytes(operation, tmp, output_length); - * if (memcmp(output, tmp, output_length) != 0) - * return PSA_ERROR_INVALID_SIGNATURE; - * \endcode - * except (1) it works even if the key's policy does not allow outputting the - * bytes, and (2) the comparison will be done in constant time. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, - * the operation enters an error state and must be aborted by calling - * psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to read from. - * \param[in] expected Buffer containing the expected derivation output. - * \param expected_length Length of the expected output; this is also the - * number of bytes that will be read. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The output was read successfully, but it differs from the expected - * output. - * \retval #PSA_ERROR_NOT_PERMITTED - * One of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_VERIFY_DERIVATION. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * The operation's capacity was less than - * \p output_length bytes. Note that in this case, - * the operation's capacity is set to 0, thus - * subsequent calls to this function will not - * succeed, even with a smaller expected output. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_verify_bytes( - psa_key_derivation_operation_t *operation, - const uint8_t *expected, - size_t expected_length); - -/** Compare output data from a key derivation operation to an expected value - * stored in a key object. - * - * This function calculates output bytes from a key derivation algorithm and - * compares those bytes to an expected value, provided as key of type - * #PSA_KEY_TYPE_PASSWORD_HASH. - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads the number of bytes corresponding to the - * length of the expected value from the stream before comparing them. - * The operation's capacity decreases by the number of bytes read. - * - * This is functionally equivalent to exporting the key and calling - * psa_key_derivation_verify_bytes() on the result, except that it - * works even if the key cannot be exported. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, - * the operation enters an error state and must be aborted by calling - * psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to read from. - * \param[in] expected A key of type #PSA_KEY_TYPE_PASSWORD_HASH - * containing the expected output. Its policy must - * include the #PSA_KEY_USAGE_VERIFY_DERIVATION flag - * and the permitted algorithm must match the - * operation. The value of this key was likely - * computed by a previous call to - * psa_key_derivation_output_key() or - * psa_key_derivation_output_key_custom(). - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The output was read successfully, but if differs from the expected - * output. - * \retval #PSA_ERROR_INVALID_HANDLE - * The key passed as the expected value does not exist. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key passed as the expected value has an invalid type. - * \retval #PSA_ERROR_NOT_PERMITTED - * The key passed as the expected value does not allow this usage or - * this algorithm; or one of the inputs was a key whose policy didn't - * allow #PSA_KEY_USAGE_VERIFY_DERIVATION. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * The operation's capacity was less than - * the length of the expected value. In this case, - * the operation's capacity is set to 0, thus - * subsequent calls to this function will not - * succeed, even with a smaller expected output. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_verify_key( - psa_key_derivation_operation_t *operation, - psa_key_id_t expected); - -/** Abort a key derivation operation. - * - * Aborting an operation frees all associated resources except for the \c - * operation structure itself. Once aborted, the operation object can be reused - * for another operation by calling psa_key_derivation_setup() again. - * - * This function may be called at any time after the operation - * object has been initialized as described in #psa_key_derivation_operation_t. - * - * In particular, it is valid to call psa_key_derivation_abort() twice, or to - * call psa_key_derivation_abort() on an operation that has not been set up. - * - * \param[in,out] operation The operation to abort. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_abort( - psa_key_derivation_operation_t *operation); - -/** Perform a key agreement and return the raw shared secret. - * - * \warning The raw result of a key agreement algorithm such as finite-field - * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should - * not be used directly as key material. It should instead be passed as - * input to a key derivation algorithm. To chain a key agreement with - * a key derivation, use psa_key_derivation_key_agreement() and other - * functions from the key derivation interface. - * - * \param alg The key agreement algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg) - * is true). - * \param private_key Identifier of the private key to use. It must - * allow the usage #PSA_KEY_USAGE_DERIVE. - * \param[in] peer_key Public key of the peer. It must be - * in the same format that psa_import_key() - * accepts. The standard formats for public - * keys are documented in the documentation - * of psa_export_public_key(). - * \param peer_key_length Size of \p peer_key in bytes. - * \param[out] output Buffer where the decrypted message is to - * be written. - * \param output_size Size of the \c output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p alg is not a key agreement algorithm, or - * \p private_key is not compatible with \p alg, - * or \p peer_key is not valid for \p alg or not compatible with - * \p private_key. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p output_size is too small - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not a supported key agreement algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, - mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key, - size_t peer_key_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/**@}*/ - -/** \defgroup random Random generation - * @{ - */ - -/** - * \brief Generate random bytes. - * - * \warning This function **can** fail! Callers MUST check the return status - * and MUST NOT use the content of the output buffer if the return - * status is not #PSA_SUCCESS. - * - * \note To generate a key, use psa_generate_key() instead. - * - * \param[out] output Output buffer for the generated data. - * \param output_size Number of bytes to generate and output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_generate_random(uint8_t *output, - size_t output_size); - -/** - * \brief Generate a key or key pair. - * - * The key is generated randomly. - * Its location, usage policy, type and size are taken from \p attributes. - * - * Implementations must reject an attempt to generate a key of size 0. - * - * The following type-specific considerations apply: - * - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR), - * the public exponent is 65537. - * The modulus is a product of two probabilistic primes - * between 2^{n-1} and 2^n where n is the bit size specified in the - * attributes. - * - * \note This function is equivalent to calling psa_generate_key_custom() - * with the custom production parameters #PSA_CUSTOM_KEY_PARAMETERS_INIT - * and `custom_data_length == 0` (i.e. `custom_data` is empty). - * - * \param[in] attributes The attributes for the new key. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key); - -/** - * \brief Generate a key or key pair using custom production parameters. - * - * See the description of psa_generate_key() for the operation of this - * function with the default production parameters. In addition, this function - * supports the following production customizations, described in more detail - * in the documentation of ::psa_custom_key_parameters_t: - * - * - RSA keys: generation with a custom public exponent. - * - * \note This function is experimental and may change in future minor - * versions of Mbed TLS. - * - * \param[in] attributes The attributes for the new key. - * \param[in] custom Customization parameters for the key generation. - * When this is #PSA_CUSTOM_KEY_PARAMETERS_INIT - * with \p custom_data_length = 0, - * this function is equivalent to - * psa_generate_key(). - * \param[in] custom_data Variable-length data associated with \c custom. - * \param custom_data_length - * Length of `custom_data` in bytes. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes, - const psa_custom_key_parameters_t *custom, - const uint8_t *custom_data, - size_t custom_data_length, - mbedtls_svc_key_id_t *key); - -#ifndef __cplusplus -/* Omitted when compiling in C++, because one of the parameters is a - * pointer to a struct with a flexible array member, and that is not - * standard C++. - * https://github.com/Mbed-TLS/mbedtls/issues/9020 - */ -/** - * \brief Generate a key or key pair using custom production parameters. - * - * \note - * This is a deprecated variant of psa_key_derivation_output_key_custom(). - * It is equivalent except that the associated variable-length data - * is passed in `params->data` instead of a separate parameter. - * This function will be removed in a future version of Mbed TLS. - * - * \param[in] attributes The attributes for the new key. - * \param[in] params Customization parameters for the key generation. - * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT - * with \p params_data_length = 0, - * this function is equivalent to - * psa_generate_key(). - * \param params_data_length - * Length of `params->data` in bytes. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, - const psa_key_production_parameters_t *params, - size_t params_data_length, - mbedtls_svc_key_id_t *key); -#endif /* !__cplusplus */ - -/**@}*/ - -/** \defgroup interruptible_hash Interruptible sign/verify hash - * @{ - */ - -/** The type of the state data structure for interruptible hash - * signing operations. - * - * Before calling any function on a sign hash operation object, the - * application must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_sign_hash_interruptible_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_sign_hash_interruptible_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer - * #PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT, for example: - * \code - * psa_sign_hash_interruptible_operation_t operation = - * PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT; - * \endcode - * - Assign the result of the function - * psa_sign_hash_interruptible_operation_init() to the structure, for - * example: - * \code - * psa_sign_hash_interruptible_operation_t operation; - * operation = psa_sign_hash_interruptible_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_sign_hash_interruptible_operation_s psa_sign_hash_interruptible_operation_t; - -/** The type of the state data structure for interruptible hash - * verification operations. - * - * Before calling any function on a sign hash operation object, the - * application must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_verify_hash_interruptible_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_verify_hash_interruptible_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer - * #PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT, for example: - * \code - * psa_verify_hash_interruptible_operation_t operation = - * PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT; - * \endcode - * - Assign the result of the function - * psa_verify_hash_interruptible_operation_init() to the structure, for - * example: - * \code - * psa_verify_hash_interruptible_operation_t operation; - * operation = psa_verify_hash_interruptible_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_verify_hash_interruptible_operation_s psa_verify_hash_interruptible_operation_t; - -/** - * \brief Set the maximum number of ops allowed to be - * executed by an interruptible function in a - * single call. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note The time taken to execute a single op is - * implementation specific and depends on - * software, hardware, the algorithm, key type and - * curve chosen. Even within a single operation, - * successive ops can take differing amounts of - * time. The only guarantee is that lower values - * for \p max_ops means functions will block for a - * lesser maximum amount of time. The functions - * \c psa_sign_interruptible_get_num_ops() and - * \c psa_verify_interruptible_get_num_ops() are - * provided to help with tuning this value. - * - * \note This value defaults to - * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, which - * means the whole operation will be done in one - * go, regardless of the number of ops required. - * - * \note If more ops are needed to complete a - * computation, #PSA_OPERATION_INCOMPLETE will be - * returned by the function performing the - * computation. It is then the caller's - * responsibility to either call again with the - * same operation context until it returns 0 or an - * error code; or to call the relevant abort - * function if the answer is no longer required. - * - * \note The interpretation of \p max_ops is also - * implementation defined. On a hard real time - * system, this can indicate a hard deadline, as a - * real-time system needs a guarantee of not - * spending more than X time, however care must be - * taken in such an implementation to avoid the - * situation whereby calls just return, not being - * able to do any actual work within the allotted - * time. On a non-real-time system, the - * implementation can be more relaxed, but again - * whether this number should be interpreted as as - * hard or soft limit or even whether a less than - * or equals as regards to ops executed in a - * single call is implementation defined. - * - * \note For keys in local storage when no accelerator - * driver applies, please see also the - * documentation for \c mbedtls_ecp_set_max_ops(), - * which is the internal implementation in these - * cases. - * - * \warning With implementations that interpret this number - * as a hard limit, setting this number too small - * may result in an infinite loop, whereby each - * call results in immediate return with no ops - * done (as there is not enough time to execute - * any), and thus no result will ever be achieved. - * - * \note This only applies to functions whose - * documentation mentions they may return - * #PSA_OPERATION_INCOMPLETE. - * - * \param max_ops The maximum number of ops to be executed in a - * single call. This can be a number from 0 to - * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0 - * is the least amount of work done per call. - */ -void psa_interruptible_set_max_ops(uint32_t max_ops); - -/** - * \brief Get the maximum number of ops allowed to be - * executed by an interruptible function in a - * single call. This will return the last - * value set by - * \c psa_interruptible_set_max_ops() or - * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED if - * that function has never been called. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \return Maximum number of ops allowed to be - * executed by an interruptible function in a - * single call. - */ -uint32_t psa_interruptible_get_max_ops(void); - -/** - * \brief Get the number of ops that a hash signing - * operation has taken so far. If the operation - * has completed, then this will represent the - * number of ops required for the entire - * operation. After initialization or calling - * \c psa_sign_hash_interruptible_abort() on - * the operation, a value of 0 will be returned. - * - * \note This interface is guaranteed re-entrant and - * thus may be called from driver code. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * This is a helper provided to help you tune the - * value passed to \c - * psa_interruptible_set_max_ops(). - * - * \param operation The \c psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \return Number of ops that the operation has taken so - * far. - */ -uint32_t psa_sign_hash_get_num_ops( - const psa_sign_hash_interruptible_operation_t *operation); - -/** - * \brief Get the number of ops that a hash verification - * operation has taken so far. If the operation - * has completed, then this will represent the - * number of ops required for the entire - * operation. After initialization or calling \c - * psa_verify_hash_interruptible_abort() on the - * operation, a value of 0 will be returned. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * This is a helper provided to help you tune the - * value passed to \c - * psa_interruptible_set_max_ops(). - * - * \param operation The \c - * psa_verify_hash_interruptible_operation_t to - * use. This must be initialized first. - * - * \return Number of ops that the operation has taken so - * far. - */ -uint32_t psa_verify_hash_get_num_ops( - const psa_verify_hash_interruptible_operation_t *operation); - -/** - * \brief Start signing a hash or short message with a - * private key, in an interruptible manner. - * - * \see \c psa_sign_hash_complete() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_sign_hash_complete() is equivalent to - * \c psa_sign_hash() but - * \c psa_sign_hash_complete() can return early and - * resume according to the limit set with \c - * psa_interruptible_set_max_ops() to reduce the - * maximum time spent in a function call. - * - * \note Users should call \c psa_sign_hash_complete() - * repeatedly on the same context after a - * successful call to this function until \c - * psa_sign_hash_complete() either returns 0 or an - * error. \c psa_sign_hash_complete() will return - * #PSA_OPERATION_INCOMPLETE if there is more work - * to do. Alternatively users can call - * \c psa_sign_hash_abort() at any point if they no - * longer want the result. - * - * \note If this function returns an error status, the - * operation enters an error state and must be - * aborted by calling \c psa_sign_hash_abort(). - * - * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \param key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. The key must - * allow the usage #PSA_KEY_USAGE_SIGN_HASH. - * \param alg A signature algorithm (\c PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash or message to sign. - * \param hash_length Size of the \p hash buffer in bytes. - * - * \retval #PSA_SUCCESS - * The operation started successfully - call \c psa_sign_hash_complete() - * with the same context to complete the operation - * - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_SIGN_HASH flag, or it does - * not permit the requested algorithm. - * \retval #PSA_ERROR_BAD_STATE - * An operation has previously been started on this context, and is - * still in progress. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_hash_start( - psa_sign_hash_interruptible_operation_t *operation, - mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length); - -/** - * \brief Continue and eventually complete the action of - * signing a hash or short message with a private - * key, in an interruptible manner. - * - * \see \c psa_sign_hash_start() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_sign_hash_start() is equivalent to - * \c psa_sign_hash() but this function can return - * early and resume according to the limit set with - * \c psa_interruptible_set_max_ops() to reduce the - * maximum time spent in a function call. - * - * \note Users should call this function on the same - * operation object repeatedly until it either - * returns 0 or an error. This function will return - * #PSA_OPERATION_INCOMPLETE if there is more work - * to do. Alternatively users can call - * \c psa_sign_hash_abort() at any point if they no - * longer want the result. - * - * \note When this function returns successfully, the - * operation becomes inactive. If this function - * returns an error status, the operation enters an - * error state and must be aborted by calling - * \c psa_sign_hash_abort(). - * - * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first, and have - * had \c psa_sign_hash_start() called with it - * first. - * - * \param[out] signature Buffer where the signature is to be written. - * \param signature_size Size of the \p signature buffer in bytes. This - * must be appropriate for the selected - * algorithm and key: - * - The required signature size is - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c - * key_bits, \c alg) where \c key_type and \c - * key_bits are the type and bit-size - * respectively of key. - * - #PSA_SIGNATURE_MAX_SIZE evaluates to the - * maximum signature size of any supported - * signature algorithm. - * \param[out] signature_length On success, the number of bytes that make up - * the returned signature value. - * - * \retval #PSA_SUCCESS - * Operation completed successfully - * - * \retval #PSA_OPERATION_INCOMPLETE - * Operation was interrupted due to the setting of \c - * psa_interruptible_set_max_ops(). There is still work to be done. - * Call this function again with the same operation object. - * - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \c alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \c key. - * - * \retval #PSA_ERROR_BAD_STATE - * An operation was not previously started on this context via - * \c psa_sign_hash_start(). - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has either not been previously initialized by - * psa_crypto_init() or you did not previously call - * psa_sign_hash_start() with this operation object. It is - * implementation-dependent whether a failure to initialize results in - * this error code. - */ -psa_status_t psa_sign_hash_complete( - psa_sign_hash_interruptible_operation_t *operation, - uint8_t *signature, size_t signature_size, - size_t *signature_length); - -/** - * \brief Abort a sign hash operation. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function is the only function that clears - * the number of ops completed as part of the - * operation. Please ensure you copy this value via - * \c psa_sign_hash_get_num_ops() if required - * before calling. - * - * \note Aborting an operation frees all associated - * resources except for the \p operation structure - * itself. Once aborted, the operation object can - * be reused for another operation by calling \c - * psa_sign_hash_start() again. - * - * \note You may call this function any time after the - * operation object has been initialized. In - * particular, calling \c psa_sign_hash_abort() - * after the operation has already been terminated - * by a call to \c psa_sign_hash_abort() or - * psa_sign_hash_complete() is safe. - * - * \param[in,out] operation Initialized sign hash operation. - * - * \retval #PSA_SUCCESS - * The operation was aborted successfully. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_hash_abort( - psa_sign_hash_interruptible_operation_t *operation); - -/** - * \brief Start reading and verifying a hash or short - * message, in an interruptible manner. - * - * \see \c psa_verify_hash_complete() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_verify_hash_complete() is equivalent to - * \c psa_verify_hash() but \c - * psa_verify_hash_complete() can return early and - * resume according to the limit set with \c - * psa_interruptible_set_max_ops() to reduce the - * maximum time spent in a function. - * - * \note Users should call \c psa_verify_hash_complete() - * repeatedly on the same operation object after a - * successful call to this function until \c - * psa_verify_hash_complete() either returns 0 or - * an error. \c psa_verify_hash_complete() will - * return #PSA_OPERATION_INCOMPLETE if there is - * more work to do. Alternatively users can call - * \c psa_verify_hash_abort() at any point if they - * no longer want the result. - * - * \note If this function returns an error status, the - * operation enters an error state and must be - * aborted by calling \c psa_verify_hash_abort(). - * - * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \param key Identifier of the key to use for the operation. - * The key must allow the usage - * #PSA_KEY_USAGE_VERIFY_HASH. - * \param alg A signature algorithm (\c PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash whose signature is to be verified. - * \param hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The operation started successfully - please call \c - * psa_verify_hash_complete() with the same context to complete the - * operation. - * - * \retval #PSA_ERROR_BAD_STATE - * Another operation has already been started on this context, and is - * still in progress. - * - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_VERIFY_HASH flag, or it does - * not permit the requested algorithm. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_hash_start( - psa_verify_hash_interruptible_operation_t *operation, - mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length); - -/** - * \brief Continue and eventually complete the action of - * reading and verifying a hash or short message - * signed with a private key, in an interruptible - * manner. - * - * \see \c psa_verify_hash_start() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_verify_hash_start() is equivalent to - * \c psa_verify_hash() but this function can - * return early and resume according to the limit - * set with \c psa_interruptible_set_max_ops() to - * reduce the maximum time spent in a function - * call. - * - * \note Users should call this function on the same - * operation object repeatedly until it either - * returns 0 or an error. This function will return - * #PSA_OPERATION_INCOMPLETE if there is more work - * to do. Alternatively users can call - * \c psa_verify_hash_abort() at any point if they - * no longer want the result. - * - * \note When this function returns successfully, the - * operation becomes inactive. If this function - * returns an error status, the operation enters an - * error state and must be aborted by calling - * \c psa_verify_hash_abort(). - * - * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t - * to use. This must be initialized first, and have - * had \c psa_verify_hash_start() called with it - * first. - * - * \retval #PSA_SUCCESS - * Operation completed successfully, and the passed signature is valid. - * - * \retval #PSA_OPERATION_INCOMPLETE - * Operation was interrupted due to the setting of \c - * psa_interruptible_set_max_ops(). There is still work to be done. - * Call this function again with the same operation object. - * - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_BAD_STATE - * An operation was not previously started on this context via - * \c psa_verify_hash_start(). - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has either not been previously initialized by - * psa_crypto_init() or you did not previously call - * psa_verify_hash_start() on this object. It is - * implementation-dependent whether a failure to initialize results in - * this error code. - */ -psa_status_t psa_verify_hash_complete( - psa_verify_hash_interruptible_operation_t *operation); - -/** - * \brief Abort a verify hash operation. - * - * \warning This is a beta API, and thus subject to change at - * any point. It is not bound by the usual interface - * stability promises. - * - * \note This function is the only function that clears the - * number of ops completed as part of the operation. - * Please ensure you copy this value via - * \c psa_verify_hash_get_num_ops() if required - * before calling. - * - * \note Aborting an operation frees all associated - * resources except for the operation structure - * itself. Once aborted, the operation object can be - * reused for another operation by calling \c - * psa_verify_hash_start() again. - * - * \note You may call this function any time after the - * operation object has been initialized. - * In particular, calling \c psa_verify_hash_abort() - * after the operation has already been terminated by - * a call to \c psa_verify_hash_abort() or - * psa_verify_hash_complete() is safe. - * - * \param[in,out] operation Initialized verify hash operation. - * - * \retval #PSA_SUCCESS - * The operation was aborted successfully. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_hash_abort( - psa_verify_hash_interruptible_operation_t *operation); - - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -/* The file "crypto_extra.h" contains vendor-specific definitions. This - * can include vendor-defined algorithms, extra functions, etc. */ -#include "crypto_extra.h" - -#endif /* PSA_CRYPTO_H */ diff --git a/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h b/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h deleted file mode 100644 index 3a2af1518..000000000 --- a/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * \file psa/crypto_adjust_auto_enabled.h - * \brief Adjust PSA configuration: enable always-on features - * - * This is an internal header. Do not include it directly. - * - * Always enable certain features which require a negligible amount of code - * to implement, to avoid some edge cases in the configuration combinatorics. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_ADJUST_AUTO_ENABLED_H -#define PSA_CRYPTO_ADJUST_AUTO_ENABLED_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -#define PSA_WANT_KEY_TYPE_DERIVE 1 -#define PSA_WANT_KEY_TYPE_PASSWORD 1 -#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1 -#define PSA_WANT_KEY_TYPE_RAW_DATA 1 - -#endif /* PSA_CRYPTO_ADJUST_AUTO_ENABLED_H */ diff --git a/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h b/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h deleted file mode 100644 index 92e9c4de2..000000000 --- a/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * \file psa/crypto_adjust_config_dependencies.h - * \brief Adjust PSA configuration by resolving some dependencies. - * - * This is an internal header. Do not include it directly. - * - * See docs/proposed/psa-conditional-inclusion-c.md. - * If the Mbed TLS implementation of a cryptographic mechanism A depends on a - * cryptographic mechanism B then if the cryptographic mechanism A is enabled - * and not accelerated enable B. Note that if A is enabled and accelerated, it - * is not necessary to enable B for A support. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_ADJUST_CONFIG_DEPENDENCIES_H -#define PSA_CRYPTO_ADJUST_CONFIG_DEPENDENCIES_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -#if (defined(PSA_WANT_ALG_TLS12_PRF) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)) || \ - (defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS)) || \ - (defined(PSA_WANT_ALG_HKDF) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)) || \ - (defined(PSA_WANT_ALG_HKDF_EXTRACT) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT)) || \ - (defined(PSA_WANT_ALG_HKDF_EXPAND) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND)) || \ - (defined(PSA_WANT_ALG_PBKDF2_HMAC) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC)) -#define PSA_WANT_ALG_HMAC 1 -#define PSA_WANT_KEY_TYPE_HMAC 1 -#endif - -#if (defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) && \ - !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128)) -#define PSA_WANT_KEY_TYPE_AES 1 -#define PSA_WANT_ALG_CMAC 1 -#endif - -#endif /* PSA_CRYPTO_ADJUST_CONFIG_DEPENDENCIES_H */ diff --git a/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h b/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h deleted file mode 100644 index cec39e01c..000000000 --- a/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * \file psa/crypto_adjust_config_key_pair_types.h - * \brief Adjust PSA configuration for key pair types. - * - * This is an internal header. Do not include it directly. - * - * See docs/proposed/psa-conditional-inclusion-c.md. - * - Support non-basic operations in a keypair type implicitly enables basic - * support for that keypair type. - * - Support for a keypair type implicitly enables the corresponding public - * key type. - * - Basic support for a keypair type implicilty enables import/export support - * for that keypair type. Warning: this is implementation-specific (mainly - * for the benefit of testing) and may change in the future! - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_ADJUST_KEYPAIR_TYPES_H -#define PSA_CRYPTO_ADJUST_KEYPAIR_TYPES_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -/***************************************************************** - * ANYTHING -> BASIC - ****************************************************************/ - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ - defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \ - defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 -#endif - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE) -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 -#endif - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ - defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ - defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) || \ - defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE) -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC 1 -#endif - -/***************************************************************** - * BASIC -> corresponding PUBLIC - ****************************************************************/ - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 -#endif - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 -#endif - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY 1 -#endif - -/***************************************************************** - * BASIC -> IMPORT+EXPORT - * - * (Implementation-specific, may change in the future.) - ****************************************************************/ - -/* Even though KEY_PAIR symbols' feature several level of support (BASIC, IMPORT, - * EXPORT, GENERATE, DERIVE) we're not planning to have support only for BASIC - * without IMPORT/EXPORT since these last 2 features are strongly used in tests. - * In general it is allowed to include more feature than what is strictly - * requested. - * As a consequence IMPORT and EXPORT features will be automatically enabled - * as soon as the BASIC one is. */ -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 -#endif - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 -#endif - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 -#endif - -#endif /* PSA_CRYPTO_ADJUST_KEYPAIR_TYPES_H */ diff --git a/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h b/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h deleted file mode 100644 index 54b116f43..000000000 --- a/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * \file psa/crypto_adjust_config_synonyms.h - * \brief Adjust PSA configuration: enable quasi-synonyms - * - * This is an internal header. Do not include it directly. - * - * When two features require almost the same code, we automatically enable - * both when either one is requested, to reduce the combinatorics of - * possible configurations. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_ADJUST_CONFIG_SYNONYMS_H -#define PSA_CRYPTO_ADJUST_CONFIG_SYNONYMS_H - -#if !defined(MBEDTLS_CONFIG_FILES_READ) -#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \ - "up to and including runtime errors such as buffer overflows. " \ - "If you're trying to fix a complaint from check_config.h, just remove " \ - "it from your configuration file: since Mbed TLS 3.0, it is included " \ - "automatically at the right point." -#endif /* */ - -/****************************************************************/ -/* De facto synonyms */ -/****************************************************************/ - -#if defined(PSA_WANT_ALG_ECDSA_ANY) && !defined(PSA_WANT_ALG_ECDSA) -#define PSA_WANT_ALG_ECDSA PSA_WANT_ALG_ECDSA_ANY -#elif !defined(PSA_WANT_ALG_ECDSA_ANY) && defined(PSA_WANT_ALG_ECDSA) -#define PSA_WANT_ALG_ECDSA_ANY PSA_WANT_ALG_ECDSA -#endif - -#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) -#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW -#elif !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) -#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW PSA_WANT_ALG_RSA_PKCS1V15_SIGN -#endif - -#if defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT) && !defined(PSA_WANT_ALG_RSA_PSS) -#define PSA_WANT_ALG_RSA_PSS PSA_WANT_ALG_RSA_PSS_ANY_SALT -#elif !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT) && defined(PSA_WANT_ALG_RSA_PSS) -#define PSA_WANT_ALG_RSA_PSS_ANY_SALT PSA_WANT_ALG_RSA_PSS -#endif - -#endif /* PSA_CRYPTO_ADJUST_CONFIG_SYNONYMS_H */ diff --git a/vendor/mbedtls/include/psa/crypto_builtin_composites.h b/vendor/mbedtls/include/psa/crypto_builtin_composites.h deleted file mode 100644 index c14f5dd11..000000000 --- a/vendor/mbedtls/include/psa/crypto_builtin_composites.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Context structure declaration of the Mbed TLS software-based PSA drivers - * called through the PSA Crypto driver dispatch layer. - * This file contains the context structures of those algorithms which need to - * rely on other algorithms, i.e. are 'composite' algorithms. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * \note This header and its content are not part of the Mbed TLS API and - * applications must not depend on it. Its main purpose is to define the - * multi-part state objects of the Mbed TLS software-based PSA drivers. The - * definitions of these objects are then used by crypto_struct.h to define the - * implementation-defined types of PSA multi-part state objects. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_BUILTIN_COMPOSITES_H -#define PSA_CRYPTO_BUILTIN_COMPOSITES_H -#include "mbedtls/private_access.h" - -#include - -#include "mbedtls/cmac.h" -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) -#include "mbedtls/gcm.h" -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) -#include "mbedtls/ccm.h" -#endif -#include "mbedtls/chachapoly.h" - -/* - * MAC multi-part operation definitions. - */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) -#define MBEDTLS_PSA_BUILTIN_MAC -#endif - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) -typedef struct { - /** The HMAC algorithm in use */ - psa_algorithm_t MBEDTLS_PRIVATE(alg); - /** The hash context. */ - struct psa_hash_operation_s hash_ctx; - /** The HMAC part of the context. */ - uint8_t MBEDTLS_PRIVATE(opad)[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; -} mbedtls_psa_hmac_operation_t; - -#define MBEDTLS_PSA_HMAC_OPERATION_INIT { 0, PSA_HASH_OPERATION_INIT, { 0 } } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - -typedef struct { - psa_algorithm_t MBEDTLS_PRIVATE(alg); - union { - unsigned MBEDTLS_PRIVATE(dummy); /* Make the union non-empty even with no supported algorithms. */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_psa_hmac_operation_t MBEDTLS_PRIVATE(hmac); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_cipher_context_t MBEDTLS_PRIVATE(cmac); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ - } MBEDTLS_PRIVATE(ctx); -} mbedtls_psa_mac_operation_t; - -#define MBEDTLS_PSA_MAC_OPERATION_INIT { 0, { 0 } } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) -#define MBEDTLS_PSA_BUILTIN_AEAD 1 -#endif - -/* Context structure for the Mbed TLS AEAD implementation. */ -typedef struct { - psa_algorithm_t MBEDTLS_PRIVATE(alg); - psa_key_type_t MBEDTLS_PRIVATE(key_type); - - unsigned int MBEDTLS_PRIVATE(is_encrypt) : 1; - - uint8_t MBEDTLS_PRIVATE(tag_length); - - union { - unsigned dummy; /* Enable easier initializing of the union. */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - mbedtls_ccm_context MBEDTLS_PRIVATE(ccm); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - mbedtls_gcm_context MBEDTLS_PRIVATE(gcm); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - mbedtls_chachapoly_context MBEDTLS_PRIVATE(chachapoly); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - - } ctx; - -} mbedtls_psa_aead_operation_t; - -#define MBEDTLS_PSA_AEAD_OPERATION_INIT { 0, 0, 0, 0, { 0 } } - -#include "mbedtls/ecdsa.h" - -/* Context structure for the Mbed TLS interruptible sign hash implementation. */ -typedef struct { -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx); - mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx); - - uint32_t MBEDTLS_PRIVATE(num_ops); - - size_t MBEDTLS_PRIVATE(coordinate_bytes); - psa_algorithm_t MBEDTLS_PRIVATE(alg); - mbedtls_md_type_t MBEDTLS_PRIVATE(md_alg); - uint8_t MBEDTLS_PRIVATE(hash)[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - size_t MBEDTLS_PRIVATE(hash_length); - -#else - /* Make the struct non-empty if algs not supported. */ - unsigned MBEDTLS_PRIVATE(dummy); - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} mbedtls_psa_sign_hash_interruptible_operation_t; - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) -#define MBEDTLS_PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, 0, 0, 0 } -#else -#define MBEDTLS_PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 } -#endif - -/* Context structure for the Mbed TLS interruptible verify hash - * implementation.*/ -typedef struct { -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx); - mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx); - - uint32_t MBEDTLS_PRIVATE(num_ops); - - uint8_t MBEDTLS_PRIVATE(hash)[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - size_t MBEDTLS_PRIVATE(hash_length); - - mbedtls_mpi MBEDTLS_PRIVATE(r); - mbedtls_mpi MBEDTLS_PRIVATE(s); - -#else - /* Make the struct non-empty if algs not supported. */ - unsigned MBEDTLS_PRIVATE(dummy); - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ - -} mbedtls_psa_verify_hash_interruptible_operation_t; - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) -#define MBEDTLS_VERIFY_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, 0, { 0 }, \ - { 0 } } -#else -#define MBEDTLS_VERIFY_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 } -#endif - - -/* EC-JPAKE operation definitions */ - -#include "mbedtls/ecjpake.h" - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) -#define MBEDTLS_PSA_BUILTIN_PAKE 1 -#endif - -/* Note: the format for mbedtls_ecjpake_read/write function has an extra - * length byte for each step, plus an extra 3 bytes for ECParameters in the - * server's 2nd round. */ -#define MBEDTLS_PSA_JPAKE_BUFFER_SIZE ((3 + 1 + 65 + 1 + 65 + 1 + 32) * 2) - -typedef struct { - psa_algorithm_t MBEDTLS_PRIVATE(alg); - - uint8_t *MBEDTLS_PRIVATE(password); - size_t MBEDTLS_PRIVATE(password_len); -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) - mbedtls_ecjpake_role MBEDTLS_PRIVATE(role); - uint8_t MBEDTLS_PRIVATE(buffer[MBEDTLS_PSA_JPAKE_BUFFER_SIZE]); - size_t MBEDTLS_PRIVATE(buffer_length); - size_t MBEDTLS_PRIVATE(buffer_offset); -#endif - /* Context structure for the Mbed TLS EC-JPAKE implementation. */ - union { - unsigned int MBEDTLS_PRIVATE(dummy); -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) - mbedtls_ecjpake_context MBEDTLS_PRIVATE(jpake); -#endif - } MBEDTLS_PRIVATE(ctx); - -} mbedtls_psa_pake_operation_t; - -#define MBEDTLS_PSA_PAKE_OPERATION_INIT { { 0 } } - -#endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */ diff --git a/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h b/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h deleted file mode 100644 index 6b91ae73f..000000000 --- a/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Context structure declaration of the Mbed TLS software-based PSA drivers - * called through the PSA Crypto driver dispatch layer. - * This file contains the context structures of key derivation algorithms - * which need to rely on other algorithms. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * \note This header and its content are not part of the Mbed TLS API and - * applications must not depend on it. Its main purpose is to define the - * multi-part state objects of the Mbed TLS software-based PSA drivers. The - * definitions of these objects are then used by crypto_struct.h to define the - * implementation-defined types of PSA multi-part state objects. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_BUILTIN_KEY_DERIVATION_H -#define PSA_CRYPTO_BUILTIN_KEY_DERIVATION_H -#include "mbedtls/private_access.h" - -#include - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) -typedef struct { - uint8_t *MBEDTLS_PRIVATE(info); - size_t MBEDTLS_PRIVATE(info_length); -#if PSA_HASH_MAX_SIZE > 0xff -#error "PSA_HASH_MAX_SIZE does not fit in uint8_t" -#endif - uint8_t MBEDTLS_PRIVATE(offset_in_block); - uint8_t MBEDTLS_PRIVATE(block_number); - unsigned int MBEDTLS_PRIVATE(state) : 2; - unsigned int MBEDTLS_PRIVATE(info_set) : 1; - uint8_t MBEDTLS_PRIVATE(output_block)[PSA_HASH_MAX_SIZE]; - uint8_t MBEDTLS_PRIVATE(prk)[PSA_HASH_MAX_SIZE]; - struct psa_mac_operation_s MBEDTLS_PRIVATE(hmac); -} psa_hkdf_key_derivation_t; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF || - MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT || - MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) -typedef struct { - uint8_t MBEDTLS_PRIVATE(data)[PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE]; -} psa_tls12_ecjpake_to_pms_t; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) -typedef enum { - PSA_TLS12_PRF_STATE_INIT, /* no input provided */ - PSA_TLS12_PRF_STATE_SEED_SET, /* seed has been set */ - PSA_TLS12_PRF_STATE_OTHER_KEY_SET, /* other key has been set - optional */ - PSA_TLS12_PRF_STATE_KEY_SET, /* key has been set */ - PSA_TLS12_PRF_STATE_LABEL_SET, /* label has been set */ - PSA_TLS12_PRF_STATE_OUTPUT /* output has been started */ -} psa_tls12_prf_key_derivation_state_t; - -typedef struct psa_tls12_prf_key_derivation_s { -#if PSA_HASH_MAX_SIZE > 0xff -#error "PSA_HASH_MAX_SIZE does not fit in uint8_t" -#endif - - /* Indicates how many bytes in the current HMAC block have - * not yet been read by the user. */ - uint8_t MBEDTLS_PRIVATE(left_in_block); - - /* The 1-based number of the block. */ - uint8_t MBEDTLS_PRIVATE(block_number); - - psa_tls12_prf_key_derivation_state_t MBEDTLS_PRIVATE(state); - - uint8_t *MBEDTLS_PRIVATE(secret); - size_t MBEDTLS_PRIVATE(secret_length); - uint8_t *MBEDTLS_PRIVATE(seed); - size_t MBEDTLS_PRIVATE(seed_length); - uint8_t *MBEDTLS_PRIVATE(label); - size_t MBEDTLS_PRIVATE(label_length); -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - uint8_t *MBEDTLS_PRIVATE(other_secret); - size_t MBEDTLS_PRIVATE(other_secret_length); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ - - uint8_t MBEDTLS_PRIVATE(Ai)[PSA_HASH_MAX_SIZE]; - - /* `HMAC_hash( prk, A( i ) + seed )` in the notation of RFC 5246, Sect. 5. */ - uint8_t MBEDTLS_PRIVATE(output_block)[PSA_HASH_MAX_SIZE]; -} psa_tls12_prf_key_derivation_t; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || - * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ -#if defined(PSA_HAVE_SOFT_PBKDF2) -typedef enum { - PSA_PBKDF2_STATE_INIT, /* no input provided */ - PSA_PBKDF2_STATE_INPUT_COST_SET, /* input cost has been set */ - PSA_PBKDF2_STATE_SALT_SET, /* salt has been set */ - PSA_PBKDF2_STATE_PASSWORD_SET, /* password has been set */ - PSA_PBKDF2_STATE_OUTPUT /* output has been started */ -} psa_pbkdf2_key_derivation_state_t; - -typedef struct { - psa_pbkdf2_key_derivation_state_t MBEDTLS_PRIVATE(state); - uint64_t MBEDTLS_PRIVATE(input_cost); - uint8_t *MBEDTLS_PRIVATE(salt); - size_t MBEDTLS_PRIVATE(salt_length); - uint8_t MBEDTLS_PRIVATE(password)[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; - size_t MBEDTLS_PRIVATE(password_length); - uint8_t MBEDTLS_PRIVATE(output_block)[PSA_HASH_MAX_SIZE]; - uint8_t MBEDTLS_PRIVATE(bytes_used); - uint32_t MBEDTLS_PRIVATE(block_number); -} psa_pbkdf2_key_derivation_t; -#endif /* PSA_HAVE_SOFT_PBKDF2 */ - -#endif /* PSA_CRYPTO_BUILTIN_KEY_DERIVATION_H */ diff --git a/vendor/mbedtls/include/psa/crypto_builtin_primitives.h b/vendor/mbedtls/include/psa/crypto_builtin_primitives.h deleted file mode 100644 index 98ab4d333..000000000 --- a/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Context structure declaration of the Mbed TLS software-based PSA drivers - * called through the PSA Crypto driver dispatch layer. - * This file contains the context structures of those algorithms which do not - * rely on other algorithms, i.e. are 'primitive' algorithms. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * \note This header and its content are not part of the Mbed TLS API and - * applications must not depend on it. Its main purpose is to define the - * multi-part state objects of the Mbed TLS software-based PSA drivers. The - * definitions of these objects are then used by crypto_struct.h to define the - * implementation-defined types of PSA multi-part state objects. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_BUILTIN_PRIMITIVES_H -#define PSA_CRYPTO_BUILTIN_PRIMITIVES_H -#include "mbedtls/private_access.h" - -#include - -/* - * Hash multi-part operation definitions. - */ - -#include "mbedtls/md5.h" -#include "mbedtls/ripemd160.h" -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" -#include "mbedtls/sha512.h" -#include "mbedtls/sha3.h" - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) -#define MBEDTLS_PSA_BUILTIN_HASH -#endif - -typedef struct { - psa_algorithm_t MBEDTLS_PRIVATE(alg); - union { - unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) - mbedtls_md5_context md5; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) - mbedtls_ripemd160_context ripemd160; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) - mbedtls_sha1_context sha1; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) - mbedtls_sha256_context sha256; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) - mbedtls_sha512_context sha512; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - mbedtls_sha3_context sha3; -#endif - } MBEDTLS_PRIVATE(ctx); -} mbedtls_psa_hash_operation_t; - -#define MBEDTLS_PSA_HASH_OPERATION_INIT { 0, { 0 } } - -/* - * Cipher multi-part operation definitions. - */ - -#include "mbedtls/cipher.h" - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG) -#define MBEDTLS_PSA_BUILTIN_CIPHER 1 -#endif - -typedef struct { - /* Context structure for the Mbed TLS cipher implementation. */ - psa_algorithm_t MBEDTLS_PRIVATE(alg); - uint8_t MBEDTLS_PRIVATE(iv_length); - uint8_t MBEDTLS_PRIVATE(block_length); - union { - unsigned int MBEDTLS_PRIVATE(dummy); - mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher); - } MBEDTLS_PRIVATE(ctx); -} mbedtls_psa_cipher_operation_t; - -#define MBEDTLS_PSA_CIPHER_OPERATION_INIT { 0, 0, 0, { 0 } } - -#endif /* PSA_CRYPTO_BUILTIN_PRIMITIVES_H */ diff --git a/vendor/mbedtls/include/psa/crypto_compat.h b/vendor/mbedtls/include/psa/crypto_compat.h deleted file mode 100644 index 2a226c01a..000000000 --- a/vendor/mbedtls/include/psa/crypto_compat.h +++ /dev/null @@ -1,230 +0,0 @@ -/** - * \file psa/crypto_compat.h - * - * \brief PSA cryptography module: Backward compatibility aliases - * - * This header declares alternative names for macro and functions. - * New application code should not use these names. - * These names may be removed in a future version of Mbed TLS. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_COMPAT_H -#define PSA_CRYPTO_COMPAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * To support both openless APIs and psa_open_key() temporarily, define - * psa_key_handle_t to be equal to mbedtls_svc_key_id_t. Do not mark the - * type and its utility macros and functions deprecated yet. This will be done - * in a subsequent phase. - */ -typedef mbedtls_svc_key_id_t psa_key_handle_t; - -#define PSA_KEY_HANDLE_INIT MBEDTLS_SVC_KEY_ID_INIT - -/** Check whether a handle is null. - * - * \param handle Handle - * - * \return Non-zero if the handle is null, zero otherwise. - */ -static inline int psa_key_handle_is_null(psa_key_handle_t handle) -{ - return mbedtls_svc_key_id_is_null(handle); -} - -/** Open a handle to an existing persistent key. - * - * Open a handle to a persistent key. A key is persistent if it was created - * with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key - * always has a nonzero key identifier, set with psa_set_key_id() when - * creating the key. Implementations may provide additional pre-provisioned - * keys that can be opened with psa_open_key(). Such keys have an application - * key identifier in the vendor range, as documented in the description of - * #psa_key_id_t. - * - * The application must eventually close the handle with psa_close_key() or - * psa_destroy_key() to release associated resources. If the application dies - * without calling one of these functions, the implementation should perform - * the equivalent of a call to psa_close_key(). - * - * Some implementations permit an application to open the same key multiple - * times. If this is successful, each call to psa_open_key() will return a - * different key handle. - * - * \note This API is not part of the PSA Cryptography API Release 1.0.0 - * specification. It was defined in the 1.0 Beta 3 version of the - * specification but was removed in the 1.0.0 released version. This API is - * kept for the time being to not break applications relying on it. It is not - * deprecated yet but will be in the near future. - * - * \note Applications that rely on opening a key multiple times will not be - * portable to implementations that only permit a single key handle to be - * opened. See also :ref:\`key-handles\`. - * - * - * \param key The persistent identifier of the key. - * \param[out] handle On success, a handle to the key. - * - * \retval #PSA_SUCCESS - * Success. The application can now use the value of `*handle` - * to access the key. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * The implementation does not have sufficient resources to open the - * key. This can be due to reaching an implementation limit on the - * number of open keys, the number of open key handles, or available - * memory. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * There is no persistent key with key identifier \p key. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not a valid persistent key identifier. - * \retval #PSA_ERROR_NOT_PERMITTED - * The specified key exists, but the application does not have the - * permission to access it. Note that this specification does not - * define any way to create such a key, but it may be possible - * through implementation-specific means. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_open_key(mbedtls_svc_key_id_t key, - psa_key_handle_t *handle); - -/** Close a key handle. - * - * If the handle designates a volatile key, this will destroy the key material - * and free all associated resources, just like psa_destroy_key(). - * - * If this is the last open handle to a persistent key, then closing the handle - * will free all resources associated with the key in volatile memory. The key - * data in persistent storage is not affected and can be opened again later - * with a call to psa_open_key(). - * - * Closing the key handle makes the handle invalid, and the key handle - * must not be used again by the application. - * - * \note This API is not part of the PSA Cryptography API Release 1.0.0 - * specification. It was defined in the 1.0 Beta 3 version of the - * specification but was removed in the 1.0.0 released version. This API is - * kept for the time being to not break applications relying on it. It is not - * deprecated yet but will be in the near future. - * - * \note If the key handle was used to set up an active - * :ref:\`multipart operation \`, then closing the - * key handle can cause the multipart operation to fail. Applications should - * maintain the key handle until after the multipart operation has finished. - * - * \param handle The key handle to close. - * If this is \c 0, do nothing and return \c PSA_SUCCESS. - * - * \retval #PSA_SUCCESS - * \p handle was a valid handle or \c 0. It is now closed. - * \retval #PSA_ERROR_INVALID_HANDLE - * \p handle is not a valid handle nor \c 0. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_close_key(psa_key_handle_t handle); - -/** \addtogroup attributes - * @{ - */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** Custom Diffie-Hellman group. - * - * Mbed TLS does not support custom DH groups. - * - * \deprecated This value is not useful, so this macro will be removed in - * a future version of the library. - */ -#define PSA_DH_FAMILY_CUSTOM \ - ((psa_dh_family_t) MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(0x7e)) - -/** - * \brief Set domain parameters for a key. - * - * \deprecated Mbed TLS no longer supports any domain parameters. - * This function only does the equivalent of - * psa_set_key_type() and will be removed in a future version - * of the library. - * - * \param[in,out] attributes Attribute structure where \p type will be set. - * \param type Key type (a \c PSA_KEY_TYPE_XXX value). - * \param[in] data Ignored. - * \param data_length Must be 0. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - */ -static inline psa_status_t MBEDTLS_DEPRECATED psa_set_key_domain_parameters( - psa_key_attributes_t *attributes, - psa_key_type_t type, const uint8_t *data, size_t data_length) -{ - (void) data; - if (data_length != 0) { - return PSA_ERROR_NOT_SUPPORTED; - } - psa_set_key_type(attributes, type); - return PSA_SUCCESS; -} - -/** - * \brief Get domain parameters for a key. - * - * \deprecated Mbed TLS no longer supports any domain parameters. - * This function alwaya has an empty output and will be - * removed in a future version of the library. - - * \param[in] attributes Ignored. - * \param[out] data Ignored. - * \param data_size Ignored. - * \param[out] data_length Set to 0. - * - * \retval #PSA_SUCCESS \emptydescription - */ -static inline psa_status_t MBEDTLS_DEPRECATED psa_get_key_domain_parameters( - const psa_key_attributes_t *attributes, - uint8_t *data, size_t data_size, size_t *data_length) -{ - (void) attributes; - (void) data; - (void) data_size; - *data_length = 0; - return PSA_SUCCESS; -} - -/** Safe output buffer size for psa_get_key_domain_parameters(). - * - */ -#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \ - MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(1u) -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif /* PSA_CRYPTO_COMPAT_H */ diff --git a/vendor/mbedtls/include/psa/crypto_config.h b/vendor/mbedtls/include/psa/crypto_config.h deleted file mode 100644 index e0a8d6060..000000000 --- a/vendor/mbedtls/include/psa/crypto_config.h +++ /dev/null @@ -1,145 +0,0 @@ -/** - * \file psa/crypto_config.h - * \brief PSA crypto configuration options (set of defines) - * - */ -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) -/** - * When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in mbedtls_config.h, - * this file determines which cryptographic mechanisms are enabled - * through the PSA Cryptography API (\c psa_xxx() functions). - * - * To enable a cryptographic mechanism, uncomment the definition of - * the corresponding \c PSA_WANT_xxx preprocessor symbol. - * To disable a cryptographic mechanism, comment out the definition of - * the corresponding \c PSA_WANT_xxx preprocessor symbol. - * The names of cryptographic mechanisms correspond to values - * defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead - * of \c PSA_. - * - * Note that many cryptographic mechanisms involve two symbols: one for - * the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm - * (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve - * additional symbols. - */ -#else -/** - * When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in mbedtls_config.h, - * this file is not used, and cryptographic mechanisms are supported - * through the PSA API if and only if they are supported through the - * mbedtls_xxx API. - */ -#endif -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_CONFIG_H -#define PSA_CRYPTO_CONFIG_H - -#define PSA_WANT_ALG_CBC_NO_PADDING 1 -#define PSA_WANT_ALG_CBC_PKCS7 1 -#define PSA_WANT_ALG_CCM 1 -#define PSA_WANT_ALG_CCM_STAR_NO_TAG 1 -#define PSA_WANT_ALG_CMAC 1 -#define PSA_WANT_ALG_CFB 1 -#define PSA_WANT_ALG_CHACHA20_POLY1305 1 -#define PSA_WANT_ALG_CTR 1 -#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 -#define PSA_WANT_ALG_ECB_NO_PADDING 1 -#define PSA_WANT_ALG_ECDH 1 -#define PSA_WANT_ALG_FFDH 1 -#define PSA_WANT_ALG_ECDSA 1 -#define PSA_WANT_ALG_JPAKE 1 -#define PSA_WANT_ALG_GCM 1 -#define PSA_WANT_ALG_HKDF 1 -#define PSA_WANT_ALG_HKDF_EXTRACT 1 -#define PSA_WANT_ALG_HKDF_EXPAND 1 -#define PSA_WANT_ALG_HMAC 1 -#define PSA_WANT_ALG_MD5 1 -#define PSA_WANT_ALG_OFB 1 -#define PSA_WANT_ALG_PBKDF2_HMAC 1 -#define PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 1 -#define PSA_WANT_ALG_RIPEMD160 1 -#define PSA_WANT_ALG_RSA_OAEP 1 -#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1 -#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1 -#define PSA_WANT_ALG_RSA_PSS 1 -#define PSA_WANT_ALG_SHA_1 1 -#define PSA_WANT_ALG_SHA_224 1 -#define PSA_WANT_ALG_SHA_256 1 -#define PSA_WANT_ALG_SHA_384 1 -#define PSA_WANT_ALG_SHA_512 1 -#define PSA_WANT_ALG_SHA3_224 1 -#define PSA_WANT_ALG_SHA3_256 1 -#define PSA_WANT_ALG_SHA3_384 1 -#define PSA_WANT_ALG_SHA3_512 1 -#define PSA_WANT_ALG_STREAM_CIPHER 1 -#define PSA_WANT_ALG_TLS12_PRF 1 -#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1 -#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1 - -#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1 -#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1 -#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1 -#define PSA_WANT_ECC_MONTGOMERY_255 1 -#define PSA_WANT_ECC_MONTGOMERY_448 1 -#define PSA_WANT_ECC_SECP_K1_192 1 -#define PSA_WANT_ECC_SECP_K1_256 1 -#define PSA_WANT_ECC_SECP_R1_192 1 -#define PSA_WANT_ECC_SECP_R1_224 1 -/* For secp256r1, consider enabling #MBEDTLS_PSA_P256M_DRIVER_ENABLED - * (see the description in mbedtls/mbedtls_config.h for details). */ -#define PSA_WANT_ECC_SECP_R1_256 1 -#define PSA_WANT_ECC_SECP_R1_384 1 -#define PSA_WANT_ECC_SECP_R1_521 1 - -#define PSA_WANT_DH_RFC7919_2048 1 -#define PSA_WANT_DH_RFC7919_3072 1 -#define PSA_WANT_DH_RFC7919_4096 1 -#define PSA_WANT_DH_RFC7919_6144 1 -#define PSA_WANT_DH_RFC7919_8192 1 - -#define PSA_WANT_KEY_TYPE_DERIVE 1 -#define PSA_WANT_KEY_TYPE_PASSWORD 1 -#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1 -#define PSA_WANT_KEY_TYPE_HMAC 1 -#define PSA_WANT_KEY_TYPE_AES 1 -#define PSA_WANT_KEY_TYPE_ARIA 1 -#define PSA_WANT_KEY_TYPE_CAMELLIA 1 -#define PSA_WANT_KEY_TYPE_CHACHA20 1 -#define PSA_WANT_KEY_TYPE_DES 1 -//#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1 /* Deprecated */ -#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 -#define PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY 1 -#define PSA_WANT_KEY_TYPE_RAW_DATA 1 -//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 /* Deprecated */ -#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 - -/* - * The following symbols extend and deprecate the legacy - * PSA_WANT_KEY_TYPE_xxx_KEY_PAIR ones. They include the usage of that key in - * the name's suffix. "_USE" is the most generic and it can be used to describe - * a generic suport, whereas other ones add more features on top of that and - * they are more specific. - */ -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 - -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 -//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE 1 /* Not supported */ - -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC 1 -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 -#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE 1 -//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE 1 /* Not supported */ - -#endif /* PSA_CRYPTO_CONFIG_H */ diff --git a/vendor/mbedtls/include/psa/crypto_driver_common.h b/vendor/mbedtls/include/psa/crypto_driver_common.h deleted file mode 100644 index cc11d3b9a..000000000 --- a/vendor/mbedtls/include/psa/crypto_driver_common.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * \file psa/crypto_driver_common.h - * \brief Definitions for all PSA crypto drivers - * - * This file contains common definitions shared by all PSA crypto drivers. - * Do not include it directly: instead, include the header file(s) for - * the type(s) of driver that you are implementing. For example, if - * you are writing a dynamically registered driver for a secure element, - * include `psa/crypto_se_driver.h`. - * - * This file is part of the PSA Crypto Driver Model, containing functions for - * driver developers to implement to enable hardware to be called in a - * standardized way by a PSA Cryptographic API implementation. The functions - * comprising the driver model, which driver authors implement, are not - * intended to be called by application developers. - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef PSA_CRYPTO_DRIVER_COMMON_H -#define PSA_CRYPTO_DRIVER_COMMON_H - -#include -#include - -/* Include type definitions (psa_status_t, psa_algorithm_t, - * psa_key_type_t, etc.) and macros to build and analyze values - * of these types. */ -#include "crypto_types.h" -#include "crypto_values.h" -/* Include size definitions which are used to size some arrays in operation - * structures. */ -#include - -/** For encrypt-decrypt functions, whether the operation is an encryption - * or a decryption. */ -typedef enum { - PSA_CRYPTO_DRIVER_DECRYPT, - PSA_CRYPTO_DRIVER_ENCRYPT -} psa_encrypt_or_decrypt_t; - -#endif /* PSA_CRYPTO_DRIVER_COMMON_H */ diff --git a/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h b/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h deleted file mode 100644 index d717c5190..000000000 --- a/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Declaration of context structures for use with the PSA driver wrapper - * interface. This file contains the context structures for 'composite' - * operations, i.e. those operations which need to make use of other operations - * from the primitives (crypto_driver_contexts_primitives.h) - * - * Warning: This file will be auto-generated in the future. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * \note This header and its content are not part of the Mbed TLS API and - * applications must not depend on it. Its main purpose is to define the - * multi-part state objects of the PSA drivers included in the cryptographic - * library. The definitions of these objects are then used by crypto_struct.h - * to define the implementation-defined types of PSA multi-part state objects. - */ -/* Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H -#define PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H - -#include "psa/crypto_driver_common.h" - -/* Include the context structure definitions for the Mbed TLS software drivers */ -#include "psa/crypto_builtin_composites.h" - -/* Include the context structure definitions for those drivers that were - * declared during the autogeneration process. */ - -#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) -#include -#endif - -#if defined(PSA_CRYPTO_DRIVER_TEST) -#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ - defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_MAC) -typedef libtestdriver1_mbedtls_psa_mac_operation_t - mbedtls_transparent_test_driver_mac_operation_t; -typedef libtestdriver1_mbedtls_psa_mac_operation_t - mbedtls_opaque_test_driver_mac_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_MAC_OPERATION_INIT \ - LIBTESTDRIVER1_MBEDTLS_PSA_MAC_OPERATION_INIT -#define MBEDTLS_OPAQUE_TEST_DRIVER_MAC_OPERATION_INIT \ - LIBTESTDRIVER1_MBEDTLS_PSA_MAC_OPERATION_INIT - -#else -typedef mbedtls_psa_mac_operation_t - mbedtls_transparent_test_driver_mac_operation_t; -typedef mbedtls_psa_mac_operation_t - mbedtls_opaque_test_driver_mac_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_MAC_OPERATION_INIT \ - MBEDTLS_PSA_MAC_OPERATION_INIT -#define MBEDTLS_OPAQUE_TEST_DRIVER_MAC_OPERATION_INIT \ - MBEDTLS_PSA_MAC_OPERATION_INIT - -#endif /* MBEDTLS_TEST_LIBTESTDRIVER1 && LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_MAC */ - -#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ - defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_AEAD) -typedef libtestdriver1_mbedtls_psa_aead_operation_t - mbedtls_transparent_test_driver_aead_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_AEAD_OPERATION_INIT \ - LIBTESTDRIVER1_MBEDTLS_PSA_AEAD_OPERATION_INIT -#else -typedef mbedtls_psa_aead_operation_t - mbedtls_transparent_test_driver_aead_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_AEAD_OPERATION_INIT \ - MBEDTLS_PSA_AEAD_OPERATION_INIT - -#endif /* MBEDTLS_TEST_LIBTESTDRIVER1 && LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ - defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE) - -typedef libtestdriver1_mbedtls_psa_pake_operation_t - mbedtls_transparent_test_driver_pake_operation_t; -typedef libtestdriver1_mbedtls_psa_pake_operation_t - mbedtls_opaque_test_driver_pake_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_PAKE_OPERATION_INIT \ - LIBTESTDRIVER1_MBEDTLS_PSA_PAKE_OPERATION_INIT -#define MBEDTLS_OPAQUE_TEST_DRIVER_PAKE_OPERATION_INIT \ - LIBTESTDRIVER1_MBEDTLS_PSA_PAKE_OPERATION_INIT - -#else -typedef mbedtls_psa_pake_operation_t - mbedtls_transparent_test_driver_pake_operation_t; -typedef mbedtls_psa_pake_operation_t - mbedtls_opaque_test_driver_pake_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_PAKE_OPERATION_INIT \ - MBEDTLS_PSA_PAKE_OPERATION_INIT -#define MBEDTLS_OPAQUE_TEST_DRIVER_PAKE_OPERATION_INIT \ - MBEDTLS_PSA_PAKE_OPERATION_INIT - -#endif /* MBEDTLS_TEST_LIBTESTDRIVER1 && LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_PAKE */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ - -/* Define the context to be used for an operation that is executed through the - * PSA Driver wrapper layer as the union of all possible driver's contexts. - * - * The union members are the driver's context structures, and the member names - * are formatted as `'drivername'_ctx`. This allows for procedural generation - * of both this file and the content of psa_crypto_driver_wrappers.h */ - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ - mbedtls_psa_mac_operation_t mbedtls_ctx; -#if defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_transparent_test_driver_mac_operation_t transparent_test_driver_ctx; - mbedtls_opaque_test_driver_mac_operation_t opaque_test_driver_ctx; -#endif -} psa_driver_mac_context_t; - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ - mbedtls_psa_aead_operation_t mbedtls_ctx; -#if defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_transparent_test_driver_aead_operation_t transparent_test_driver_ctx; -#endif -} psa_driver_aead_context_t; - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ - mbedtls_psa_sign_hash_interruptible_operation_t mbedtls_ctx; -} psa_driver_sign_hash_interruptible_context_t; - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ - mbedtls_psa_verify_hash_interruptible_operation_t mbedtls_ctx; -} psa_driver_verify_hash_interruptible_context_t; - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ - mbedtls_psa_pake_operation_t mbedtls_ctx; -#if defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_transparent_test_driver_pake_operation_t transparent_test_driver_ctx; - mbedtls_opaque_test_driver_pake_operation_t opaque_test_driver_ctx; -#endif -} psa_driver_pake_context_t; - -#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */ -/* End of automatically generated file. */ diff --git a/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h b/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h deleted file mode 100644 index 21190515c..000000000 --- a/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Declaration of context structures for use with the PSA driver wrapper - * interface. This file contains the context structures for key derivation - * operations. - * - * Warning: This file will be auto-generated in the future. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * \note This header and its content are not part of the Mbed TLS API and - * applications must not depend on it. Its main purpose is to define the - * multi-part state objects of the PSA drivers included in the cryptographic - * library. The definitions of these objects are then used by crypto_struct.h - * to define the implementation-defined types of PSA multi-part state objects. - */ -/* Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_DRIVER_CONTEXTS_KEY_DERIVATION_H -#define PSA_CRYPTO_DRIVER_CONTEXTS_KEY_DERIVATION_H - -#include "psa/crypto_driver_common.h" - -/* Include the context structure definitions for the Mbed TLS software drivers */ -#include "psa/crypto_builtin_key_derivation.h" - -/* Include the context structure definitions for those drivers that were - * declared during the autogeneration process. */ - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) - psa_hkdf_key_derivation_t MBEDTLS_PRIVATE(hkdf); -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - psa_tls12_prf_key_derivation_t MBEDTLS_PRIVATE(tls12_prf); -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) - psa_tls12_ecjpake_to_pms_t MBEDTLS_PRIVATE(tls12_ecjpake_to_pms); -#endif -#if defined(PSA_HAVE_SOFT_PBKDF2) - psa_pbkdf2_key_derivation_t MBEDTLS_PRIVATE(pbkdf2); -#endif -} psa_driver_key_derivation_context_t; - -#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_KEY_DERIVATION_H */ -/* End of automatically generated file. */ diff --git a/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h b/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h deleted file mode 100644 index c90a5fbe7..000000000 --- a/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Declaration of context structures for use with the PSA driver wrapper - * interface. This file contains the context structures for 'primitive' - * operations, i.e. those operations which do not rely on other contexts. - * - * Warning: This file will be auto-generated in the future. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * \note This header and its content are not part of the Mbed TLS API and - * applications must not depend on it. Its main purpose is to define the - * multi-part state objects of the PSA drivers included in the cryptographic - * library. The definitions of these objects are then used by crypto_struct.h - * to define the implementation-defined types of PSA multi-part state objects. - */ -/* Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H -#define PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H - -#include "psa/crypto_driver_common.h" - -/* Include the context structure definitions for the Mbed TLS software drivers */ -#include "psa/crypto_builtin_primitives.h" - -/* Include the context structure definitions for those drivers that were - * declared during the autogeneration process. */ - -#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) -#include -#endif - -#if defined(PSA_CRYPTO_DRIVER_TEST) - -#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ - defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_CIPHER) -typedef libtestdriver1_mbedtls_psa_cipher_operation_t - mbedtls_transparent_test_driver_cipher_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT \ - LIBTESTDRIVER1_MBEDTLS_PSA_CIPHER_OPERATION_INIT -#else -typedef mbedtls_psa_cipher_operation_t - mbedtls_transparent_test_driver_cipher_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT \ - MBEDTLS_PSA_CIPHER_OPERATION_INIT -#endif /* MBEDTLS_TEST_LIBTESTDRIVER1 && - LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_CIPHER */ - -#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ - defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_HASH) -typedef libtestdriver1_mbedtls_psa_hash_operation_t - mbedtls_transparent_test_driver_hash_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_HASH_OPERATION_INIT \ - LIBTESTDRIVER1_MBEDTLS_PSA_HASH_OPERATION_INIT -#else -typedef mbedtls_psa_hash_operation_t - mbedtls_transparent_test_driver_hash_operation_t; - -#define MBEDTLS_TRANSPARENT_TEST_DRIVER_HASH_OPERATION_INIT \ - MBEDTLS_PSA_HASH_OPERATION_INIT -#endif /* MBEDTLS_TEST_LIBTESTDRIVER1 && - LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_HASH */ - -typedef struct { - unsigned int initialised : 1; - mbedtls_transparent_test_driver_cipher_operation_t ctx; -} mbedtls_opaque_test_driver_cipher_operation_t; - -#define MBEDTLS_OPAQUE_TEST_DRIVER_CIPHER_OPERATION_INIT \ - { 0, MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT } - -#endif /* PSA_CRYPTO_DRIVER_TEST */ - -/* Define the context to be used for an operation that is executed through the - * PSA Driver wrapper layer as the union of all possible driver's contexts. - * - * The union members are the driver's context structures, and the member names - * are formatted as `'drivername'_ctx`. This allows for procedural generation - * of both this file and the content of psa_crypto_driver_wrappers.h */ - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ - mbedtls_psa_hash_operation_t mbedtls_ctx; -#if defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_transparent_test_driver_hash_operation_t test_driver_ctx; -#endif -} psa_driver_hash_context_t; - -typedef union { - unsigned dummy; /* Make sure this union is always non-empty */ - mbedtls_psa_cipher_operation_t mbedtls_ctx; -#if defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_transparent_test_driver_cipher_operation_t transparent_test_driver_ctx; - mbedtls_opaque_test_driver_cipher_operation_t opaque_test_driver_ctx; -#endif -} psa_driver_cipher_context_t; - -#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H */ -/* End of automatically generated file. */ diff --git a/vendor/mbedtls/include/psa/crypto_extra.h b/vendor/mbedtls/include/psa/crypto_extra.h deleted file mode 100644 index 03566305d..000000000 --- a/vendor/mbedtls/include/psa/crypto_extra.h +++ /dev/null @@ -1,2145 +0,0 @@ -/** - * \file psa/crypto_extra.h - * - * \brief PSA cryptography module: Mbed TLS vendor extensions - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * This file is reserved for vendor-specific definitions. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_EXTRA_H -#define PSA_CRYPTO_EXTRA_H -#include "mbedtls/private_access.h" - -#include "crypto_types.h" -#include "crypto_compat.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* UID for secure storage seed */ -#define PSA_CRYPTO_ITS_RANDOM_SEED_UID 0xFFFFFF52 - -/* See mbedtls_config.h for definition */ -#if !defined(MBEDTLS_PSA_KEY_SLOT_COUNT) -#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 -#endif - -/* If the size of static key slots is not explicitly defined by the user, then - * try to guess it based on some of the most common the key types enabled in the build. - * See mbedtls_config.h for the definition of MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE. */ -#if !defined(MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE) - -#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE 1 - -#if PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE > MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE -#undef MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE -#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE -#endif - -/* This covers ciphers, AEADs and CMAC. */ -#if PSA_CIPHER_MAX_KEY_LENGTH > MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE -#undef MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE -#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE PSA_CIPHER_MAX_KEY_LENGTH -#endif - -/* For HMAC, it's typical but not mandatory to use a key size that is equal to - * the hash size. */ -#if defined(PSA_WANT_ALG_HMAC) -#if PSA_HASH_MAX_SIZE > MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE -#undef MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE -#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE PSA_HASH_MAX_SIZE -#endif -#endif /* PSA_WANT_ALG_HMAC */ - -#endif /* !MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE*/ - -/** \addtogroup attributes - * @{ - */ - -/** \brief Declare the enrollment algorithm for a key. - * - * An operation on a key may indifferently use the algorithm set with - * psa_set_key_algorithm() or with this function. - * - * \param[out] attributes The attribute structure to write to. - * \param alg2 A second algorithm that the key may be used - * for, in addition to the algorithm set with - * psa_set_key_algorithm(). - * - * \warning Setting an enrollment algorithm is not recommended, because - * using the same key with different algorithms can allow some - * attacks based on arithmetic relations between different - * computations made with the same key, or can escalate harmless - * side channels into exploitable ones. Use this function only - * if it is necessary to support a protocol for which it has been - * verified that the usage of the key with multiple algorithms - * is safe. - */ -static inline void psa_set_key_enrollment_algorithm( - psa_key_attributes_t *attributes, - psa_algorithm_t alg2) -{ - attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2; -} - -/** Retrieve the enrollment algorithm policy from key attributes. - * - * \param[in] attributes The key attribute structure to query. - * - * \return The enrollment algorithm stored in the attribute structure. - */ -static inline psa_algorithm_t psa_get_key_enrollment_algorithm( - const psa_key_attributes_t *attributes) -{ - return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2); -} - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - -/** Retrieve the slot number where a key is stored. - * - * A slot number is only defined for keys that are stored in a secure - * element. - * - * This information is only useful if the secure element is not entirely - * managed through the PSA Cryptography API. It is up to the secure - * element driver to decide how PSA slot numbers map to any other interface - * that the secure element may have. - * - * \param[in] attributes The key attribute structure to query. - * \param[out] slot_number On success, the slot number containing the key. - * - * \retval #PSA_SUCCESS - * The key is located in a secure element, and \p *slot_number - * indicates the slot number that contains it. - * \retval #PSA_ERROR_NOT_PERMITTED - * The caller is not permitted to query the slot number. - * Mbed TLS currently does not return this error. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key is not located in a secure element. - */ -psa_status_t psa_get_key_slot_number( - const psa_key_attributes_t *attributes, - psa_key_slot_number_t *slot_number); - -/** Choose the slot number where a key is stored. - * - * This function declares a slot number in the specified attribute - * structure. - * - * A slot number is only meaningful for keys that are stored in a secure - * element. It is up to the secure element driver to decide how PSA slot - * numbers map to any other interface that the secure element may have. - * - * \note Setting a slot number in key attributes for a key creation can - * cause the following errors when creating the key: - * - #PSA_ERROR_NOT_SUPPORTED if the selected secure element does - * not support choosing a specific slot number. - * - #PSA_ERROR_NOT_PERMITTED if the caller is not permitted to - * choose slot numbers in general or to choose this specific slot. - * - #PSA_ERROR_INVALID_ARGUMENT if the chosen slot number is not - * valid in general or not valid for this specific key. - * - #PSA_ERROR_ALREADY_EXISTS if there is already a key in the - * selected slot. - * - * \param[out] attributes The attribute structure to write to. - * \param slot_number The slot number to set. - */ -static inline void psa_set_key_slot_number( - psa_key_attributes_t *attributes, - psa_key_slot_number_t slot_number) -{ - attributes->MBEDTLS_PRIVATE(has_slot_number) = 1; - attributes->MBEDTLS_PRIVATE(slot_number) = slot_number; -} - -/** Remove the slot number attribute from a key attribute structure. - * - * This function undoes the action of psa_set_key_slot_number(). - * - * \param[out] attributes The attribute structure to write to. - */ -static inline void psa_clear_key_slot_number( - psa_key_attributes_t *attributes) -{ - attributes->MBEDTLS_PRIVATE(has_slot_number) = 0; -} - -/** Register a key that is already present in a secure element. - * - * The key must be located in a secure element designated by the - * lifetime field in \p attributes, in the slot set with - * psa_set_key_slot_number() in the attribute structure. - * This function makes the key available through the key identifier - * specified in \p attributes. - * - * \param[in] attributes The attributes of the existing key. - * - The lifetime must be a persistent lifetime - * in a secure element. Volatile lifetimes are - * not currently supported. - * - The key identifier must be in the valid - * range for persistent keys. - * - The key type and size must be specified and - * must be consistent with the key material - * in the secure element. - * - * \retval #PSA_SUCCESS - * The key was successfully registered. - * Note that depending on the design of the driver, this may or may - * not guarantee that a key actually exists in the designated slot - * and is compatible with the specified attributes. - * \retval #PSA_ERROR_ALREADY_EXISTS - * There is already a key with the identifier specified in - * \p attributes. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The secure element driver for the specified lifetime does not - * support registering a key. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The identifier in \p attributes is invalid, namely the identifier is - * not in the user range, or - * \p attributes specifies a lifetime which is not located - * in a secure element, or no slot number is specified in \p attributes, - * or the specified slot number is not valid. - * \retval #PSA_ERROR_NOT_PERMITTED - * The caller is not authorized to register the specified key slot. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t mbedtls_psa_register_se_key( - const psa_key_attributes_t *attributes); - -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - -/**@}*/ - -/** - * \brief Library deinitialization. - * - * This function clears all data associated with the PSA layer, - * including the whole key store. - * This function is not thread safe, it wipes every key slot regardless of - * state and reader count. It should only be called when no slot is in use. - * - * This is an Mbed TLS extension. - */ -void mbedtls_psa_crypto_free(void); - -/** \brief Statistics about - * resource consumption related to the PSA keystore. - * - * \note The content of this structure is not part of the stable API and ABI - * of Mbed TLS and may change arbitrarily from version to version. - */ -typedef struct mbedtls_psa_stats_s { - /** Number of slots containing key material for a volatile key. */ - size_t MBEDTLS_PRIVATE(volatile_slots); - /** Number of slots containing key material for a key which is in - * internal persistent storage. */ - size_t MBEDTLS_PRIVATE(persistent_slots); - /** Number of slots containing a reference to a key in a - * secure element. */ - size_t MBEDTLS_PRIVATE(external_slots); - /** Number of slots which are occupied, but do not contain - * key material yet. */ - size_t MBEDTLS_PRIVATE(half_filled_slots); - /** Number of slots that contain cache data. */ - size_t MBEDTLS_PRIVATE(cache_slots); - /** Number of slots that are not used for anything. */ - size_t MBEDTLS_PRIVATE(empty_slots); - /** Number of slots that are locked. */ - size_t MBEDTLS_PRIVATE(locked_slots); - /** Largest key id value among open keys in internal persistent storage. */ - psa_key_id_t MBEDTLS_PRIVATE(max_open_internal_key_id); - /** Largest key id value among open keys in secure elements. */ - psa_key_id_t MBEDTLS_PRIVATE(max_open_external_key_id); -} mbedtls_psa_stats_t; - -/** \brief Get statistics about - * resource consumption related to the PSA keystore. - * - * \note When Mbed TLS is built as part of a service, with isolation - * between the application and the keystore, the service may or - * may not expose this function. - */ -void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats); - -/** - * \brief Inject an initial entropy seed for the random generator into - * secure storage. - * - * This function injects data to be used as a seed for the random generator - * used by the PSA Crypto implementation. On devices that lack a trusted - * entropy source (preferably a hardware random number generator), - * the Mbed PSA Crypto implementation uses this value to seed its - * random generator. - * - * On devices without a trusted entropy source, this function must be - * called exactly once in the lifetime of the device. On devices with - * a trusted entropy source, calling this function is optional. - * In all cases, this function may only be called before calling any - * other function in the PSA Crypto API, including psa_crypto_init(). - * - * When this function returns successfully, it populates a file in - * persistent storage. Once the file has been created, this function - * can no longer succeed. - * - * If any error occurs, this function does not change the system state. - * You can call this function again after correcting the reason for the - * error if possible. - * - * \warning This function **can** fail! Callers MUST check the return status. - * - * \warning If you use this function, you should use it as part of a - * factory provisioning process. The value of the injected seed - * is critical to the security of the device. It must be - * *secret*, *unpredictable* and (statistically) *unique per device*. - * You should be generate it randomly using a cryptographically - * secure random generator seeded from trusted entropy sources. - * You should transmit it securely to the device and ensure - * that its value is not leaked or stored anywhere beyond the - * needs of transmitting it from the point of generation to - * the call of this function, and erase all copies of the value - * once this function returns. - * - * This is an Mbed TLS extension. - * - * \note This function is only available on the following platforms: - * * If the compile-time option MBEDTLS_PSA_INJECT_ENTROPY is enabled. - * Note that you must provide compatible implementations of - * mbedtls_nv_seed_read and mbedtls_nv_seed_write. - * * In a client-server integration of PSA Cryptography, on the client side, - * if the server supports this feature. - * \param[in] seed Buffer containing the seed value to inject. - * \param[in] seed_size Size of the \p seed buffer. - * The size of the seed in bytes must be greater - * or equal to both #MBEDTLS_ENTROPY_BLOCK_SIZE - * and the value of \c MBEDTLS_ENTROPY_MIN_PLATFORM - * in `library/entropy_poll.h` in the Mbed TLS source - * code. - * It must be less or equal to - * #MBEDTLS_ENTROPY_MAX_SEED_SIZE. - * - * \retval #PSA_SUCCESS - * The seed value was injected successfully. The random generator - * of the PSA Crypto implementation is now ready for use. - * You may now call psa_crypto_init() and use the PSA Crypto - * implementation. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p seed_size is out of range. - * \retval #PSA_ERROR_STORAGE_FAILURE - * There was a failure reading or writing from storage. - * \retval #PSA_ERROR_NOT_PERMITTED - * The library has already been initialized. It is no longer - * possible to call this function. - */ -psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, - size_t seed_size); - -/** \addtogroup crypto_types - * @{ - */ - -/** DSA public key. - * - * The import and export format is the - * representation of the public key `y = g^x mod p` as a big-endian byte - * string. The length of the byte string is the length of the base prime `p` - * in bytes. - */ -#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t) 0x4002) - -/** DSA key pair (private and public key). - * - * The import and export format is the - * representation of the private key `x` as a big-endian byte string. The - * length of the byte string is the private key size in bytes (leading zeroes - * are not stripped). - * - * Deterministic DSA key derivation with psa_generate_derived_key follows - * FIPS 186-4 §B.1.2: interpret the byte string as integer - * in big-endian order. Discard it if it is not in the range - * [0, *N* - 2] where *N* is the boundary of the private key domain - * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA, - * or the order of the curve's base point for ECC). - * Add 1 to the resulting integer and use this as the private key *x*. - * - */ -#define PSA_KEY_TYPE_DSA_KEY_PAIR ((psa_key_type_t) 0x7002) - -/** Whether a key type is a DSA key (pair or public-only). */ -#define PSA_KEY_TYPE_IS_DSA(type) \ - (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY) - -#define PSA_ALG_DSA_BASE ((psa_algorithm_t) 0x06000400) -/** DSA signature with hashing. - * - * This is the signature scheme defined by FIPS 186-4, - * with a random per-message secret number (*k*). - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * This includes #PSA_ALG_ANY_HASH - * when specifying the algorithm in a usage policy. - * - * \return The corresponding DSA signature algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_DSA(hash_alg) \ - (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t) 0x06000500) -#define PSA_ALG_DSA_DETERMINISTIC_FLAG PSA_ALG_ECDSA_DETERMINISTIC_FLAG -/** Deterministic DSA signature with hashing. - * - * This is the deterministic variant defined by RFC 6979 of - * the signature scheme defined by FIPS 186-4. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * This includes #PSA_ALG_ANY_HASH - * when specifying the algorithm in a usage policy. - * - * \return The corresponding DSA signature algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \ - (PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_IS_DSA(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \ - PSA_ALG_DSA_BASE) -#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \ - (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0) -#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \ - (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg)) -#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \ - (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg)) - - -/* We need to expand the sample definition of this macro from - * the API definition. */ -#undef PSA_ALG_IS_VENDOR_HASH_AND_SIGN -#define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) \ - PSA_ALG_IS_DSA(alg) - -/**@}*/ - -/** \addtogroup attributes - * @{ - */ - -/** PAKE operation stages. */ -#define PSA_PAKE_OPERATION_STAGE_SETUP 0 -#define PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS 1 -#define PSA_PAKE_OPERATION_STAGE_COMPUTATION 2 - -/**@}*/ - - -/** \defgroup psa_rng Random generator - * @{ - */ - -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -/** External random generator function, implemented by the platform. - * - * When the compile-time option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, - * this function replaces Mbed TLS's entropy and DRBG modules for all - * random generation triggered via PSA crypto interfaces. - * - * \note This random generator must deliver random numbers with cryptographic - * quality and high performance. It must supply unpredictable numbers - * with a uniform distribution. The implementation of this function - * is responsible for ensuring that the random generator is seeded - * with sufficient entropy. If you have a hardware TRNG which is slow - * or delivers non-uniform output, declare it as an entropy source - * with mbedtls_entropy_add_source() instead of enabling this option. - * - * \param[in,out] context Pointer to the random generator context. - * This is all-bits-zero on the first call - * and preserved between successive calls. - * \param[out] output Output buffer. On success, this buffer - * contains random data with a uniform - * distribution. - * \param output_size The size of the \p output buffer in bytes. - * \param[out] output_length On success, set this value to \p output_size. - * - * \retval #PSA_SUCCESS - * Success. The output buffer contains \p output_size bytes of - * cryptographic-quality random data, and \c *output_length is - * set to \p output_size. - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * The random generator requires extra entropy and there is no - * way to obtain entropy under current environment conditions. - * This error should not happen under normal circumstances since - * this function is responsible for obtaining as much entropy as - * it needs. However implementations of this function may return - * #PSA_ERROR_INSUFFICIENT_ENTROPY if there is no way to obtain - * entropy without blocking indefinitely. - * \retval #PSA_ERROR_HARDWARE_FAILURE - * A failure of the random generator hardware that isn't covered - * by #PSA_ERROR_INSUFFICIENT_ENTROPY. - */ -psa_status_t mbedtls_psa_external_get_random( - mbedtls_psa_external_random_context_t *context, - uint8_t *output, size_t output_size, size_t *output_length); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - -/** Force an immediate reseed of the PSA random generator. - * - * The entropy source(s) are the ones configured at compile time. - * - * The random generator is always seeded automatically before use, and - * it is reseeded as needed based on the configured policy, so most - * applications do not need to call this function. - * - * The main reason to call this function is in scenarios where the process - * state is cloned (i.e. duplicated) while the random generator is active. - * In such scenarios, you must call this function in every clone of - * the original process before performing any cryptographic operation - * that uses randomness. (Note that any operation that uses a private or - * secret key may use randomness internally even if the result is not - * randomized, but hashing and signature verification are ok.) For example: - * - * - If the process is part of a live virtual machine that is cloned, - * call this function after cloning so that the new instance has a - * distinct random generator state. - * - If the process is part of a hibernated image that may be resumed - * multiple times, call this function after resuming so that each - * resumed instance has a distinct random generator state. - * - If the process is cloned through the fork() system call, the - * child process should call this function before using the random - * generator. - * - * An additional consideration applies in configurations where there is no - * actual entropy source, only a nonvolatile seed (i.e. - * #MBEDTLS_ENTROPY_NV_SEED is enabled, #MBEDTLS_NO_PLATFORM_ENTROPY is - * enabled and #MBEDTLS_ENTROPY_HARDWARE_ALT is disabled). - * In such configurations, simply calling psa_random_reseed() in multiple - * cloned processes would result in the same random generator state in - * all the clones. To avoid this, in such configurations, you must pass - * a unique \p perso string in every clone. - * - * \note This function has no effect when the compilation option - * #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. - * - * \note In client-server builds, this function may not be available - * from clients, since the decision to reseed is generally based - * on the server state. - * - * \note If the entropy source fails, the random generator remains usable: - * subsequent calls to generate random data will succeed until - * the random generator itself decides to reseed. If you want to - * force a reseed, either treat the failure as a fatal error, - * or call psa_random_deplete() instead of this function (or in - * addition). - * - * \param[in] perso A personalization string, i.e. a byte string to - * inject into the random generator state in addition - * to entropy obtained from the normal source(s). - * In most cases, it is fine for \c perso to be - * empty. The main use case for a personalization - * string is when the random generator state is cloned, - * as described above, and there is no actual entropy - * source. - * \param perso_size Length of \c perso in bytes. - * - * \retval #PSA_SUCCESS - * The reseed succeeded. - * \retval #PSA_ERROR_BAD_STATE - * The PSA random generator is not active. - * \retval #PSA_ERROR_NOT_SUPPORTED - * PSA uses an external random generator because the compilation - * option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. This - * configuration does not support explicit reseeding. - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * The entropy source failed. - */ -psa_status_t psa_random_reseed(const uint8_t *perso, size_t perso_size); - -/** Force a reseed of the PSA random generator the next time it is used. - * - * The entropy source(s) are the ones configured at compile time. - * - * The random generator is always seeded automatically before use, and - * it is reseeded as needed based on the configured policy, so most - * applications do not need to call this function. - * - * This function has a similar purpose as psa_random_reseed(), - * but the reseed will happen the next time the random generator is used. - * The advantage of this function is that it does not fail unless the - * system is in an unintended state, so it can be used in contexts where - * propagating errors is difficult. - * - * \note This function has no effect when #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - * is enabled. - * - * \note If prediction resistance is enabled (either explicitly, or because - * the reseed interval is set to 1), calling this function is - * unnecessary since the random generator will always reseed anyway. - * - * \retval #PSA_SUCCESS - * The reseed succeeded. - * \retval #PSA_ERROR_BAD_STATE - * The PSA random generator is not active. - * \retval #PSA_ERROR_NOT_SUPPORTED - * PSA uses an external random generator because the compilation - * option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. This - * configuration does not support explicit reseeding. - */ -psa_status_t psa_random_deplete(void); - -/** Enable or disable prediction resistance in the PSA random generator. - * - * When prediction resistance is enabled, the random generator - * injects extra entropy before each request regardless of its size. - * As a consequence, a temporary compromise of the random generator - * state does not, by itself, compromise future steps. - * Furthermore, duplicating the random generator state (because the - * running application instance is cloned) is safe since it will - * not lead to identical random generator outputs in the clones. - * - * When prediction resistance is disabled, the random generator injects - * extra entropy periodically only as determined by - * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL if #MBEDTLS_CTR_DRBG_C - * is enabled, or #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL otherwise. - * - * Prediction resistance is disabled by default, although setting - * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL or #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL - * to \c 1 satisfies the prediction resistance property even when the - * option is disabled. - * - * \note This function has no effect when #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - * is enabled. - * - * \note Prediction resistance cannot be enabled when the only entropy source - * is a nonvolatile seed, since prediction resistance is effectively - * impossible to achieve without actual entropy. - * - * \param enabled \c 1 to enable prediction resistance. - * \c 0 to disable prediction resistance. - * - * \retval #PSA_SUCCESS - * The PSA random generator is active, and prediction resistance - * has been changed to the desired option. - * \retval #PSA_ERROR_BAD_STATE - * The PSA random generator is not active. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p enabled is not valid. - * \retval #PSA_ERROR_NOT_SUPPORTED - * PSA uses an external random generator because the compilation - * option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled. - * Or, the random generator only has a nonvolatile seed but no entropy - * source, and prediction resistance has been requested. - */ -psa_status_t psa_random_set_prediction_resistance(unsigned enabled); - -/**@}*/ - -/** \defgroup psa_builtin_keys Built-in keys - * @{ - */ - -/** The minimum value for a key identifier that is built into the - * implementation. - * - * The range of key identifiers from #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - * to #MBEDTLS_PSA_KEY_ID_BUILTIN_MAX within the range from - * #PSA_KEY_ID_VENDOR_MIN and #PSA_KEY_ID_VENDOR_MAX and must not intersect - * with any other set of implementation-chosen key identifiers. - * - * This value is part of the library's API since changing it would invalidate - * the values of built-in key identifiers in applications. - */ -#define MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ((psa_key_id_t) 0x7fff0000) - -/** The maximum value for a key identifier that is built into the - * implementation. - * - * See #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN for more information. - */ -#define MBEDTLS_PSA_KEY_ID_BUILTIN_MAX ((psa_key_id_t) 0x7fffefff) - -/** A slot number identifying a key in a driver. - * - * Values of this type are used to identify built-in keys. - */ -typedef uint64_t psa_drv_slot_number_t; - -#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) -/** Test whether a key identifier belongs to the builtin key range. - * - * \param key_id Key identifier to test. - * - * \retval 1 - * The key identifier is a builtin key identifier. - * \retval 0 - * The key identifier is not a builtin key identifier. - */ -static inline int psa_key_id_is_builtin(psa_key_id_t key_id) -{ - return (key_id >= MBEDTLS_PSA_KEY_ID_BUILTIN_MIN) && - (key_id <= MBEDTLS_PSA_KEY_ID_BUILTIN_MAX); -} - -/** Platform function to obtain the location and slot number of a built-in key. - * - * An application-specific implementation of this function must be provided if - * #MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS is enabled. This would typically be provided - * as part of a platform's system image. - * - * #MBEDTLS_SVC_KEY_ID_GET_KEY_ID(\p key_id) needs to be in the range from - * #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN to #MBEDTLS_PSA_KEY_ID_BUILTIN_MAX. - * - * In a multi-application configuration - * (\c MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER is defined), - * this function should check that #MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(\p key_id) - * is allowed to use the given key. - * - * \param key_id The key ID for which to retrieve the - * location and slot attributes. - * \param[out] lifetime On success, the lifetime associated with the key - * corresponding to \p key_id. Lifetime is a - * combination of which driver contains the key, - * and with what persistence level the key is - * intended to be used. If the platform - * implementation does not contain specific - * information about the intended key persistence - * level, the persistence level may be reported as - * #PSA_KEY_PERSISTENCE_DEFAULT. - * \param[out] slot_number On success, the slot number known to the driver - * registered at the lifetime location reported - * through \p lifetime which corresponds to the - * requested built-in key. - * - * \retval #PSA_SUCCESS - * The requested key identifier designates a built-in key. - * In a multi-application configuration, the requested owner - * is allowed to access it. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * The requested key identifier is not a built-in key which is known - * to this function. If a key exists in the key storage with this - * identifier, the data from the storage will be used. - * \return (any other error) - * Any other error is propagated to the function that requested the key. - * Common errors include: - * - #PSA_ERROR_NOT_PERMITTED: the key exists but the requested owner - * is not allowed to access it. - */ -psa_status_t mbedtls_psa_platform_get_builtin_key( - mbedtls_svc_key_id_t key_id, - psa_key_lifetime_t *lifetime, - psa_drv_slot_number_t *slot_number); -#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ - -/** @} */ - -/** \defgroup psa_crypto_client Functions defined by a client provider - * - * The functions in this group are meant to be implemented by providers of - * the PSA Crypto client interface. They are provided by the library when - * #MBEDTLS_PSA_CRYPTO_C is enabled. - * - * \note All functions in this group are experimental, as using - * alternative client interface providers is experimental. - * - * @{ - */ - -/** Check if PSA is capable of handling the specified hash algorithm. - * - * This means that PSA core was built with the corresponding PSA_WANT_ALG_xxx - * set and that psa_crypto_init has already been called. - * - * \note When using the built-in version of the PSA core (i.e. - * #MBEDTLS_PSA_CRYPTO_C is set), for now, this function only checks - * the state of the driver subsystem, not the algorithm. - * This might be improved in the future. - * - * \param hash_alg The hash algorithm. - * - * \return 1 if the PSA can handle \p hash_alg, 0 otherwise. - */ -int psa_can_do_hash(psa_algorithm_t hash_alg); - -/** - * Tell if PSA is ready for this cipher. - * - * \note When using the built-in version of the PSA core (i.e. - * #MBEDTLS_PSA_CRYPTO_C is set), for now, this function only checks - * the state of the driver subsystem, not the key type and algorithm. - * This might be improved in the future. - * - * \param key_type The key type. - * \param cipher_alg The cipher algorithm. - * - * \return 1 if the PSA can handle \p cipher_alg, 0 otherwise. - */ -int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg); - -/**@}*/ - -/** \addtogroup crypto_types - * @{ - */ - -#define PSA_ALG_CATEGORY_PAKE ((psa_algorithm_t) 0x0a000000) - -/** Whether the specified algorithm is a password-authenticated key exchange. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a password-authenticated key exchange (PAKE) - * algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_PAKE(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_PAKE) - -/** The Password-authenticated key exchange by juggling (J-PAKE) algorithm. - * - * This is J-PAKE as defined by RFC 8236, instantiated with the following - * parameters: - * - * - The group can be either an elliptic curve or defined over a finite field. - * - Schnorr NIZK proof as defined by RFC 8235 and using the same group as the - * J-PAKE algorithm. - * - A cryptographic hash function. - * - * To select these parameters and set up the cipher suite, call these functions - * in any order: - * - * \code - * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_JPAKE); - * psa_pake_cs_set_primitive(cipher_suite, - * PSA_PAKE_PRIMITIVE(type, family, bits)); - * psa_pake_cs_set_hash(cipher_suite, hash); - * \endcode - * - * For more information on how to set a specific curve or field, refer to the - * documentation of the individual \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants. - * - * After initializing a J-PAKE operation, call - * - * \code - * psa_pake_setup(operation, cipher_suite); - * psa_pake_set_user(operation, ...); - * psa_pake_set_peer(operation, ...); - * psa_pake_set_password_key(operation, ...); - * \endcode - * - * The password is provided as a key. This can be the password text itself, - * in an agreed character encoding, or some value derived from the password - * as required by a higher level protocol. - * - * (The implementation converts the key material to a number as described in - * Section 2.3.8 of _SEC 1: Elliptic Curve Cryptography_ - * (https://www.secg.org/sec1-v2.pdf), before reducing it modulo \c q. Here - * \c q is order of the group defined by the primitive set in the cipher suite. - * The \c psa_pake_set_password_key() function returns an error if the result - * of the reduction is 0.) - * - * The key exchange flow for J-PAKE is as follows: - * -# To get the first round data that needs to be sent to the peer, call - * \code - * // Get g1 - * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); - * // Get the ZKP public key for x1 - * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); - * // Get the ZKP proof for x1 - * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); - * // Get g2 - * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); - * // Get the ZKP public key for x2 - * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); - * // Get the ZKP proof for x2 - * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); - * \endcode - * -# To provide the first round data received from the peer to the operation, - * call - * \code - * // Set g3 - * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); - * // Set the ZKP public key for x3 - * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); - * // Set the ZKP proof for x3 - * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); - * // Set g4 - * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); - * // Set the ZKP public key for x4 - * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); - * // Set the ZKP proof for x4 - * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); - * \endcode - * -# To get the second round data that needs to be sent to the peer, call - * \code - * // Get A - * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); - * // Get ZKP public key for x2*s - * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); - * // Get ZKP proof for x2*s - * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); - * \endcode - * -# To provide the second round data received from the peer to the operation, - * call - * \code - * // Set B - * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); - * // Set ZKP public key for x4*s - * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); - * // Set ZKP proof for x4*s - * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); - * \endcode - * -# To access the shared secret call - * \code - * // Get Ka=Kb=K - * psa_pake_get_implicit_key() - * \endcode - * - * For more information consult the documentation of the individual - * \c PSA_PAKE_STEP_XXX constants. - * - * At this point there is a cryptographic guarantee that only the authenticated - * party who used the same password is able to compute the key. But there is no - * guarantee that the peer is the party it claims to be and was able to do so. - * - * That is, the authentication is only implicit (the peer is not authenticated - * at this point, and no action should be taken that assume that they are - like - * for example accessing restricted files). - * - * To make the authentication explicit there are various methods, see Section 5 - * of RFC 8236 for two examples. - * - * \note The JPAKE implementation has the following limitations: - * - The only supported primitive is ECC on the curve secp256r1, i.e. - * `PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, - * PSA_ECC_FAMILY_SECP_R1, 256)`. - * - The only supported hash algorithm is SHA-256, i.e. - * `PSA_ALG_SHA_256`. - * - When using the built-in implementation, the user ID and the peer ID - * must be `"client"` (6-byte string) and `"server"` (6-byte string), - * or the other way round. - * Third-party drivers may or may not have this limitation. - * - */ -#define PSA_ALG_JPAKE ((psa_algorithm_t) 0x0a000100) - -/** @} */ - -/** \defgroup pake Password-authenticated key exchange (PAKE) - * - * This is a proposed PAKE interface for the PSA Crypto API. It is not part of - * the official PSA Crypto API yet. - * - * \note The content of this section is not part of the stable API and ABI - * of Mbed TLS and may change arbitrarily from version to version. - * Same holds for the corresponding macros #PSA_ALG_CATEGORY_PAKE and - * #PSA_ALG_JPAKE. - * @{ - */ - -/** \brief Encoding of the application role of PAKE - * - * Encodes the application's role in the algorithm is being executed. For more - * information see the documentation of individual \c PSA_PAKE_ROLE_XXX - * constants. - */ -typedef uint8_t psa_pake_role_t; - -/** Encoding of input and output indicators for PAKE. - * - * Some PAKE algorithms need to exchange more data than just a single key share. - * This type is for encoding additional input and output data for such - * algorithms. - */ -typedef uint8_t psa_pake_step_t; - -/** Encoding of the type of the PAKE's primitive. - * - * Values defined by this standard will never be in the range 0x80-0xff. - * Vendors who define additional types must use an encoding in this range. - * - * For more information see the documentation of individual - * \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants. - */ -typedef uint8_t psa_pake_primitive_type_t; - -/** \brief Encoding of the family of the primitive associated with the PAKE. - * - * For more information see the documentation of individual - * \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants. - */ -typedef uint8_t psa_pake_family_t; - -/** \brief Encoding of the primitive associated with the PAKE. - * - * For more information see the documentation of the #PSA_PAKE_PRIMITIVE macro. - */ -typedef uint32_t psa_pake_primitive_t; - -/** A value to indicate no role in a PAKE algorithm. - * This value can be used in a call to psa_pake_set_role() for symmetric PAKE - * algorithms which do not assign roles. - */ -#define PSA_PAKE_ROLE_NONE ((psa_pake_role_t) 0x00) - -/** The first peer in a balanced PAKE. - * - * Although balanced PAKE algorithms are symmetric, some of them needs an - * ordering of peers for the transcript calculations. If the algorithm does not - * need this, both #PSA_PAKE_ROLE_FIRST and #PSA_PAKE_ROLE_SECOND are - * accepted. - */ -#define PSA_PAKE_ROLE_FIRST ((psa_pake_role_t) 0x01) - -/** The second peer in a balanced PAKE. - * - * Although balanced PAKE algorithms are symmetric, some of them needs an - * ordering of peers for the transcript calculations. If the algorithm does not - * need this, either #PSA_PAKE_ROLE_FIRST or #PSA_PAKE_ROLE_SECOND are - * accepted. - */ -#define PSA_PAKE_ROLE_SECOND ((psa_pake_role_t) 0x02) - -/** The client in an augmented PAKE. - * - * Augmented PAKE algorithms need to differentiate between client and server. - */ -#define PSA_PAKE_ROLE_CLIENT ((psa_pake_role_t) 0x11) - -/** The server in an augmented PAKE. - * - * Augmented PAKE algorithms need to differentiate between client and server. - */ -#define PSA_PAKE_ROLE_SERVER ((psa_pake_role_t) 0x12) - -/** The PAKE primitive type indicating the use of elliptic curves. - * - * The values of the \c family and \c bits fields of the cipher suite identify a - * specific elliptic curve, using the same mapping that is used for ECC - * (::psa_ecc_family_t) keys. - * - * (Here \c family means the value returned by psa_pake_cs_get_family() and - * \c bits means the value returned by psa_pake_cs_get_bits().) - * - * Input and output during the operation can involve group elements and scalar - * values: - * -# The format for group elements is the same as for public keys on the - * specific curve would be. For more information, consult the documentation of - * psa_export_public_key(). - * -# The format for scalars is the same as for private keys on the specific - * curve would be. For more information, consult the documentation of - * psa_export_key(). - */ -#define PSA_PAKE_PRIMITIVE_TYPE_ECC ((psa_pake_primitive_type_t) 0x01) - -/** The PAKE primitive type indicating the use of Diffie-Hellman groups. - * - * The values of the \c family and \c bits fields of the cipher suite identify - * a specific Diffie-Hellman group, using the same mapping that is used for - * Diffie-Hellman (::psa_dh_family_t) keys. - * - * (Here \c family means the value returned by psa_pake_cs_get_family() and - * \c bits means the value returned by psa_pake_cs_get_bits().) - * - * Input and output during the operation can involve group elements and scalar - * values: - * -# The format for group elements is the same as for public keys on the - * specific group would be. For more information, consult the documentation of - * psa_export_public_key(). - * -# The format for scalars is the same as for private keys on the specific - * group would be. For more information, consult the documentation of - * psa_export_key(). - */ -#define PSA_PAKE_PRIMITIVE_TYPE_DH ((psa_pake_primitive_type_t) 0x02) - -/** Construct a PAKE primitive from type, family and bit-size. - * - * \param pake_type The type of the primitive - * (value of type ::psa_pake_primitive_type_t). - * \param pake_family The family of the primitive - * (the type and interpretation of this parameter depends - * on \p pake_type, for more information consult the - * documentation of individual ::psa_pake_primitive_type_t - * constants). - * \param pake_bits The bit-size of the primitive - * (Value of type \c size_t. The interpretation - * of this parameter depends on \p pake_family, for more - * information consult the documentation of individual - * ::psa_pake_primitive_type_t constants). - * - * \return The constructed primitive value of type ::psa_pake_primitive_t. - * Return 0 if the requested primitive can't be encoded as - * ::psa_pake_primitive_t. - */ -#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \ - ((pake_bits & 0xFFFF) != pake_bits) ? 0 : \ - ((psa_pake_primitive_t) (((pake_type) << 24 | \ - (pake_family) << 16) | (pake_bits))) - -/** The key share being sent to or received from the peer. - * - * The format for both input and output at this step is the same as for public - * keys on the group determined by the primitive (::psa_pake_primitive_t) would - * be. - * - * For more information on the format, consult the documentation of - * psa_export_public_key(). - * - * For information regarding how the group is determined, consult the - * documentation #PSA_PAKE_PRIMITIVE. - */ -#define PSA_PAKE_STEP_KEY_SHARE ((psa_pake_step_t) 0x01) - -/** A Schnorr NIZKP public key. - * - * This is the ephemeral public key in the Schnorr Non-Interactive - * Zero-Knowledge Proof (the value denoted by the letter 'V' in RFC 8235). - * - * The format for both input and output at this step is the same as for public - * keys on the group determined by the primitive (::psa_pake_primitive_t) would - * be. - * - * For more information on the format, consult the documentation of - * psa_export_public_key(). - * - * For information regarding how the group is determined, consult the - * documentation #PSA_PAKE_PRIMITIVE. - */ -#define PSA_PAKE_STEP_ZK_PUBLIC ((psa_pake_step_t) 0x02) - -/** A Schnorr NIZKP proof. - * - * This is the proof in the Schnorr Non-Interactive Zero-Knowledge Proof (the - * value denoted by the letter 'r' in RFC 8235). - * - * Both for input and output, the value at this step is an integer less than - * the order of the group selected in the cipher suite. The format depends on - * the group as well: - * - * - For Montgomery curves, the encoding is little endian. - * - For everything else the encoding is big endian (see Section 2.3.8 of - * _SEC 1: Elliptic Curve Cryptography_ at https://www.secg.org/sec1-v2.pdf). - * - * In both cases leading zeroes are allowed as long as the length in bytes does - * not exceed the byte length of the group order. - * - * For information regarding how the group is determined, consult the - * documentation #PSA_PAKE_PRIMITIVE. - */ -#define PSA_PAKE_STEP_ZK_PROOF ((psa_pake_step_t) 0x03) - -/**@}*/ - -/** A sufficient output buffer size for psa_pake_output(). - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_pake_output() will not fail due to an insufficient output buffer - * size. The actual size of the output might be smaller in any given call. - * - * See also #PSA_PAKE_OUTPUT_MAX_SIZE - * - * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_PAKE(\p alg) is true). - * \param primitive A primitive of type ::psa_pake_primitive_t that is - * compatible with algorithm \p alg. - * \param output_step A value of type ::psa_pake_step_t that is valid for the - * algorithm \p alg. - * \return A sufficient output buffer size for the specified - * PAKE algorithm, primitive, and output step. If the - * PAKE algorithm, primitive, or output step is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \ - (alg == PSA_ALG_JPAKE && \ - primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ - PSA_ECC_FAMILY_SECP_R1, 256) ? \ - ( \ - output_step == PSA_PAKE_STEP_KEY_SHARE ? 65 : \ - output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 : \ - 32 \ - ) : \ - 0) - -/** A sufficient input buffer size for psa_pake_input(). - * - * The value returned by this macro is guaranteed to be large enough for any - * valid input to psa_pake_input() in an operation with the specified - * parameters. - * - * See also #PSA_PAKE_INPUT_MAX_SIZE - * - * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_PAKE(\p alg) is true). - * \param primitive A primitive of type ::psa_pake_primitive_t that is - * compatible with algorithm \p alg. - * \param input_step A value of type ::psa_pake_step_t that is valid for the - * algorithm \p alg. - * \return A sufficient input buffer size for the specified - * input, cipher suite and algorithm. If the cipher suite, - * the input type or PAKE algorithm is not recognized, or - * the parameters are incompatible, return 0. - */ -#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \ - (alg == PSA_ALG_JPAKE && \ - primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \ - PSA_ECC_FAMILY_SECP_R1, 256) ? \ - ( \ - input_step == PSA_PAKE_STEP_KEY_SHARE ? 65 : \ - input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 : \ - 32 \ - ) : \ - 0) - -/** Output buffer size for psa_pake_output() for any of the supported PAKE - * algorithm and primitive suites and output step. - * - * This macro must expand to a compile-time constant integer. - * - * The value of this macro must be at least as large as the largest value - * returned by PSA_PAKE_OUTPUT_SIZE() - * - * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step). - */ -#define PSA_PAKE_OUTPUT_MAX_SIZE 65 - -/** Input buffer size for psa_pake_input() for any of the supported PAKE - * algorithm and primitive suites and input step. - * - * This macro must expand to a compile-time constant integer. - * - * The value of this macro must be at least as large as the largest value - * returned by PSA_PAKE_INPUT_SIZE() - * - * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step). - */ -#define PSA_PAKE_INPUT_MAX_SIZE 65 - -/** Returns a suitable initializer for a PAKE cipher suite object of type - * psa_pake_cipher_suite_t. - */ -#define PSA_PAKE_CIPHER_SUITE_INIT { PSA_ALG_NONE, 0, 0, 0, PSA_ALG_NONE } - -/** Returns a suitable initializer for a PAKE operation object of type - * psa_pake_operation_t. - */ -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_PAKE_OPERATION_INIT { 0 } -#else -#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, 0, PSA_PAKE_OPERATION_STAGE_SETUP, \ - { 0 }, { { 0 } } } -#endif - -struct psa_pake_cipher_suite_s { - psa_algorithm_t algorithm; - psa_pake_primitive_type_t type; - psa_pake_family_t family; - uint16_t bits; - psa_algorithm_t hash; -}; - -struct psa_crypto_driver_pake_inputs_s { - uint8_t *MBEDTLS_PRIVATE(password); - size_t MBEDTLS_PRIVATE(password_len); - uint8_t *MBEDTLS_PRIVATE(user); - size_t MBEDTLS_PRIVATE(user_len); - uint8_t *MBEDTLS_PRIVATE(peer); - size_t MBEDTLS_PRIVATE(peer_len); - psa_key_attributes_t MBEDTLS_PRIVATE(attributes); - struct psa_pake_cipher_suite_s MBEDTLS_PRIVATE(cipher_suite); -}; - -typedef enum psa_crypto_driver_pake_step { - PSA_JPAKE_STEP_INVALID = 0, /* Invalid step */ - PSA_JPAKE_X1_STEP_KEY_SHARE = 1, /* Round 1: input/output key share (for ephemeral private key X1).*/ - PSA_JPAKE_X1_STEP_ZK_PUBLIC = 2, /* Round 1: input/output Schnorr NIZKP public key for the X1 key */ - PSA_JPAKE_X1_STEP_ZK_PROOF = 3, /* Round 1: input/output Schnorr NIZKP proof for the X1 key */ - PSA_JPAKE_X2_STEP_KEY_SHARE = 4, /* Round 1: input/output key share (for ephemeral private key X2).*/ - PSA_JPAKE_X2_STEP_ZK_PUBLIC = 5, /* Round 1: input/output Schnorr NIZKP public key for the X2 key */ - PSA_JPAKE_X2_STEP_ZK_PROOF = 6, /* Round 1: input/output Schnorr NIZKP proof for the X2 key */ - PSA_JPAKE_X2S_STEP_KEY_SHARE = 7, /* Round 2: output X2S key (our key) */ - PSA_JPAKE_X2S_STEP_ZK_PUBLIC = 8, /* Round 2: output Schnorr NIZKP public key for the X2S key (our key) */ - PSA_JPAKE_X2S_STEP_ZK_PROOF = 9, /* Round 2: output Schnorr NIZKP proof for the X2S key (our key) */ - PSA_JPAKE_X4S_STEP_KEY_SHARE = 10, /* Round 2: input X4S key (from peer) */ - PSA_JPAKE_X4S_STEP_ZK_PUBLIC = 11, /* Round 2: input Schnorr NIZKP public key for the X4S key (from peer) */ - PSA_JPAKE_X4S_STEP_ZK_PROOF = 12 /* Round 2: input Schnorr NIZKP proof for the X4S key (from peer) */ -} psa_crypto_driver_pake_step_t; - -typedef enum psa_jpake_round { - PSA_JPAKE_FIRST = 0, - PSA_JPAKE_SECOND = 1, - PSA_JPAKE_FINISHED = 2 -} psa_jpake_round_t; - -typedef enum psa_jpake_io_mode { - PSA_JPAKE_INPUT = 0, - PSA_JPAKE_OUTPUT = 1 -} psa_jpake_io_mode_t; - -struct psa_jpake_computation_stage_s { - /* The J-PAKE round we are currently on */ - psa_jpake_round_t MBEDTLS_PRIVATE(round); - /* The 'mode' we are currently in (inputting or outputting) */ - psa_jpake_io_mode_t MBEDTLS_PRIVATE(io_mode); - /* The number of completed inputs so far this round */ - uint8_t MBEDTLS_PRIVATE(inputs); - /* The number of completed outputs so far this round */ - uint8_t MBEDTLS_PRIVATE(outputs); - /* The next expected step (KEY_SHARE, ZK_PUBLIC or ZK_PROOF) */ - psa_pake_step_t MBEDTLS_PRIVATE(step); -}; - -#define PSA_JPAKE_EXPECTED_INPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \ - ((round) == PSA_JPAKE_FIRST ? 2 : 1)) -#define PSA_JPAKE_EXPECTED_OUTPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \ - ((round) == PSA_JPAKE_FIRST ? 2 : 1)) - -struct psa_pake_operation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_crypto_driver_wrappers.h - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. none of the driver contexts are active). */ - unsigned int MBEDTLS_PRIVATE(id); - /* Algorithm of the PAKE operation */ - psa_algorithm_t MBEDTLS_PRIVATE(alg); - /* A primitive of type compatible with algorithm */ - psa_pake_primitive_t MBEDTLS_PRIVATE(primitive); - /* Stage of the PAKE operation: waiting for the setup, collecting inputs - * or computing. */ - uint8_t MBEDTLS_PRIVATE(stage); - /* Holds computation stage of the PAKE algorithms. */ - union { - uint8_t MBEDTLS_PRIVATE(dummy); -#if defined(PSA_WANT_ALG_JPAKE) - struct psa_jpake_computation_stage_s MBEDTLS_PRIVATE(jpake); -#endif - } MBEDTLS_PRIVATE(computation_stage); - union { - psa_driver_pake_context_t MBEDTLS_PRIVATE(ctx); - struct psa_crypto_driver_pake_inputs_s MBEDTLS_PRIVATE(inputs); - } MBEDTLS_PRIVATE(data); -#endif -}; - -/** \addtogroup pake - * @{ - */ - -/** The type of the data structure for PAKE cipher suites. - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. - */ -typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t; - -/** Return an initial value for a PAKE cipher suite object. - */ -static psa_pake_cipher_suite_t psa_pake_cipher_suite_init(void); - -/** Retrieve the PAKE algorithm from a PAKE cipher suite. - * - * \param[in] cipher_suite The cipher suite structure to query. - * - * \return The PAKE algorithm stored in the cipher suite structure. - */ -static psa_algorithm_t psa_pake_cs_get_algorithm( - const psa_pake_cipher_suite_t *cipher_suite); - -/** Declare the PAKE algorithm for the cipher suite. - * - * This function overwrites any PAKE algorithm - * previously set in \p cipher_suite. - * - * \note For #PSA_ALG_JPAKE, the only supported hash algorithm is SHA-256. - * - * \param[out] cipher_suite The cipher suite structure to write to. - * \param algorithm The PAKE algorithm to write. - * (`PSA_ALG_XXX` values of type ::psa_algorithm_t - * such that #PSA_ALG_IS_PAKE(\c alg) is true.) - * If this is 0, the PAKE algorithm in - * \p cipher_suite becomes unspecified. - */ -static void psa_pake_cs_set_algorithm(psa_pake_cipher_suite_t *cipher_suite, - psa_algorithm_t algorithm); - -/** Retrieve the primitive from a PAKE cipher suite. - * - * \param[in] cipher_suite The cipher suite structure to query. - * - * \return The primitive stored in the cipher suite structure. - */ -static psa_pake_primitive_t psa_pake_cs_get_primitive( - const psa_pake_cipher_suite_t *cipher_suite); - -/** Declare the primitive for a PAKE cipher suite. - * - * This function overwrites any primitive previously set in \p cipher_suite. - * - * \note For #PSA_ALG_JPAKE, the only supported primitive is ECC on the curve - * secp256r1, i.e. `PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, - * PSA_ECC_FAMILY_SECP_R1, 256)`. - * - * \param[out] cipher_suite The cipher suite structure to write to. - * \param primitive The primitive to write. If this is 0, the - * primitive type in \p cipher_suite becomes - * unspecified. - */ -static void psa_pake_cs_set_primitive(psa_pake_cipher_suite_t *cipher_suite, - psa_pake_primitive_t primitive); - -/** Retrieve the PAKE family from a PAKE cipher suite. - * - * \param[in] cipher_suite The cipher suite structure to query. - * - * \return The PAKE family stored in the cipher suite structure. - */ -static psa_pake_family_t psa_pake_cs_get_family( - const psa_pake_cipher_suite_t *cipher_suite); - -/** Retrieve the PAKE primitive bit-size from a PAKE cipher suite. - * - * \param[in] cipher_suite The cipher suite structure to query. - * - * \return The PAKE primitive bit-size stored in the cipher suite structure. - */ -static uint16_t psa_pake_cs_get_bits( - const psa_pake_cipher_suite_t *cipher_suite); - -/** Retrieve the hash algorithm from a PAKE cipher suite. - * - * \param[in] cipher_suite The cipher suite structure to query. - * - * \return The hash algorithm stored in the cipher suite structure. The return - * value is 0 if the PAKE is not parametrised by a hash algorithm or if - * the hash algorithm is not set. - */ -static psa_algorithm_t psa_pake_cs_get_hash( - const psa_pake_cipher_suite_t *cipher_suite); - -/** Declare the hash algorithm for a PAKE cipher suite. - * - * This function overwrites any hash algorithm - * previously set in \p cipher_suite. - * - * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` - * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) - * for more information. - * - * \param[out] cipher_suite The cipher suite structure to write to. - * \param hash The hash involved in the cipher suite. - * (`PSA_ALG_XXX` values of type ::psa_algorithm_t - * such that #PSA_ALG_IS_HASH(\c alg) is true.) - * If this is 0, the hash algorithm in - * \p cipher_suite becomes unspecified. - */ -static void psa_pake_cs_set_hash(psa_pake_cipher_suite_t *cipher_suite, - psa_algorithm_t hash); - -/** The type of the state data structure for PAKE operations. - * - * Before calling any function on a PAKE operation object, the application - * must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_pake_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_pake_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_PAKE_OPERATION_INIT, - * for example: - * \code - * psa_pake_operation_t operation = PSA_PAKE_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_pake_operation_init() - * to the structure, for example: - * \code - * psa_pake_operation_t operation; - * operation = psa_pake_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_pake_operation_s psa_pake_operation_t; - -/** The type of input values for PAKE operations. */ -typedef struct psa_crypto_driver_pake_inputs_s psa_crypto_driver_pake_inputs_t; - -/** The type of computation stage for J-PAKE operations. */ -typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t; - -/** Return an initial value for a PAKE operation object. - */ -static psa_pake_operation_t psa_pake_operation_init(void); - -/** Get the length of the password in bytes from given inputs. - * - * \param[in] inputs Operation inputs. - * \param[out] password_len Password length. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * Password hasn't been set yet. - */ -psa_status_t psa_crypto_driver_pake_get_password_len( - const psa_crypto_driver_pake_inputs_t *inputs, - size_t *password_len); - -/** Get the password from given inputs. - * - * \param[in] inputs Operation inputs. - * \param[out] buffer Return buffer for password. - * \param buffer_size Size of the return buffer in bytes. - * \param[out] buffer_length Actual size of the password in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * Password hasn't been set yet. - */ -psa_status_t psa_crypto_driver_pake_get_password( - const psa_crypto_driver_pake_inputs_t *inputs, - uint8_t *buffer, size_t buffer_size, size_t *buffer_length); - -/** Get the length of the user id in bytes from given inputs. - * - * \param[in] inputs Operation inputs. - * \param[out] user_len User id length. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * User id hasn't been set yet. - */ -psa_status_t psa_crypto_driver_pake_get_user_len( - const psa_crypto_driver_pake_inputs_t *inputs, - size_t *user_len); - -/** Get the length of the peer id in bytes from given inputs. - * - * \param[in] inputs Operation inputs. - * \param[out] peer_len Peer id length. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * Peer id hasn't been set yet. - */ -psa_status_t psa_crypto_driver_pake_get_peer_len( - const psa_crypto_driver_pake_inputs_t *inputs, - size_t *peer_len); - -/** Get the user id from given inputs. - * - * \param[in] inputs Operation inputs. - * \param[out] user_id User id. - * \param user_id_size Size of \p user_id in bytes. - * \param[out] user_id_len Size of the user id in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * User id hasn't been set yet. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p user_id is too small. - */ -psa_status_t psa_crypto_driver_pake_get_user( - const psa_crypto_driver_pake_inputs_t *inputs, - uint8_t *user_id, size_t user_id_size, size_t *user_id_len); - -/** Get the peer id from given inputs. - * - * \param[in] inputs Operation inputs. - * \param[out] peer_id Peer id. - * \param peer_id_size Size of \p peer_id in bytes. - * \param[out] peer_id_length Size of the peer id in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * Peer id hasn't been set yet. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p peer_id is too small. - */ -psa_status_t psa_crypto_driver_pake_get_peer( - const psa_crypto_driver_pake_inputs_t *inputs, - uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length); - -/** Get the cipher suite from given inputs. - * - * \param[in] inputs Operation inputs. - * \param[out] cipher_suite Return buffer for role. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * Cipher_suite hasn't been set yet. - */ -psa_status_t psa_crypto_driver_pake_get_cipher_suite( - const psa_crypto_driver_pake_inputs_t *inputs, - psa_pake_cipher_suite_t *cipher_suite); - -/** Set the session information for a password-authenticated key exchange. - * - * The sequence of operations to set up a password-authenticated key exchange - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_pake_operation_t, e.g. - * #PSA_PAKE_OPERATION_INIT. - * -# Call psa_pake_setup() to specify the cipher suite. - * -# Call \c psa_pake_set_xxx() functions on the operation to complete the - * setup. The exact sequence of \c psa_pake_set_xxx() functions that needs - * to be called depends on the algorithm in use. - * - * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` - * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) - * for more information. - * - * A typical sequence of calls to perform a password-authenticated key - * exchange: - * -# Call psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to get the - * key share that needs to be sent to the peer. - * -# Call psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to provide - * the key share that was received from the peer. - * -# Depending on the algorithm additional calls to psa_pake_output() and - * psa_pake_input() might be necessary. - * -# Call psa_pake_get_implicit_key() for accessing the shared secret. - * - * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` - * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) - * for more information. - * - * If an error occurs at any step after a call to psa_pake_setup(), - * the operation will need to be reset by a call to psa_pake_abort(). The - * application may call psa_pake_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_pake_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A call to psa_pake_abort(). - * - A successful call to psa_pake_get_implicit_key(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized but not set up yet. - * \param[in] cipher_suite The cipher suite to use. (A cipher suite fully - * characterizes a PAKE algorithm and determines - * the algorithm as well.) - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The algorithm in \p cipher_suite is not a PAKE algorithm, or the - * PAKE primitive in \p cipher_suite is not compatible with the - * PAKE algorithm, or the hash algorithm in \p cipher_suite is invalid - * or not compatible with the PAKE algorithm and primitive. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The algorithm in \p cipher_suite is not a supported PAKE algorithm, - * or the PAKE primitive in \p cipher_suite is not supported or not - * compatible with the PAKE algorithm, or the hash algorithm in - * \p cipher_suite is not supported or not compatible with the PAKE - * algorithm and primitive. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_setup(psa_pake_operation_t *operation, - const psa_pake_cipher_suite_t *cipher_suite); - -/** Set the password for a password-authenticated key exchange from key ID. - * - * Call this function when the password, or a value derived from the password, - * is already present in the key store. - * - * \param[in,out] operation The operation object to set the password for. It - * must have been set up by psa_pake_setup() and - * not yet in use (neither psa_pake_output() nor - * psa_pake_input() has been called yet). It must - * be on operation for which the password hasn't - * been set yet (psa_pake_set_password_key() - * hasn't been called yet). - * \param password Identifier of the key holding the password or a - * value derived from the password (eg. by a - * memory-hard function). It must remain valid - * until the operation terminates. It must be of - * type #PSA_KEY_TYPE_PASSWORD or - * #PSA_KEY_TYPE_PASSWORD_HASH. It has to allow - * the usage #PSA_KEY_USAGE_DERIVE. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \p password is not a valid key identifier. - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_DERIVE flag, or it does not - * permit the \p operation's algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key type for \p password is not #PSA_KEY_TYPE_PASSWORD or - * #PSA_KEY_TYPE_PASSWORD_HASH, or \p password is not compatible with - * the \p operation's cipher suite. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size of \p password is not supported with the - * \p operation's cipher suite. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must have been set up.), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_set_password_key(psa_pake_operation_t *operation, - mbedtls_svc_key_id_t password); - -/** Set the user ID for a password-authenticated key exchange. - * - * Call this function to set the user ID. For PAKE algorithms that associate a - * user identifier with each side of the session you need to call - * psa_pake_set_peer() as well. For PAKE algorithms that associate a single - * user identifier with the session, call psa_pake_set_user() only. - * - * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` - * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) - * for more information. - * - * \note When using the built-in implementation of #PSA_ALG_JPAKE, the user ID - * must be `"client"` (6-byte string) or `"server"` (6-byte string). - * Third-party drivers may or may not have this limitation. - * - * \param[in,out] operation The operation object to set the user ID for. It - * must have been set up by psa_pake_setup() and - * not yet in use (neither psa_pake_output() nor - * psa_pake_input() has been called yet). It must - * be on operation for which the user ID hasn't - * been set (psa_pake_set_user() hasn't been - * called yet). - * \param[in] user_id The user ID to authenticate with. - * \param user_id_len Size of the \p user_id buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p user_id is not valid for the \p operation's algorithm and cipher - * suite. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The value of \p user_id is not supported by the implementation. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_set_user(psa_pake_operation_t *operation, - const uint8_t *user_id, - size_t user_id_len); - -/** Set the peer ID for a password-authenticated key exchange. - * - * Call this function in addition to psa_pake_set_user() for PAKE algorithms - * that associate a user identifier with each side of the session. For PAKE - * algorithms that associate a single user identifier with the session, call - * psa_pake_set_user() only. - * - * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` - * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) - * for more information. - * - * \note When using the built-in implementation of #PSA_ALG_JPAKE, the peer ID - * must be `"client"` (6-byte string) or `"server"` (6-byte string). - * Third-party drivers may or may not have this limitation. - * - * \param[in,out] operation The operation object to set the peer ID for. It - * must have been set up by psa_pake_setup() and - * not yet in use (neither psa_pake_output() nor - * psa_pake_input() has been called yet). It must - * be on operation for which the peer ID hasn't - * been set (psa_pake_set_peer() hasn't been - * called yet). - * \param[in] peer_id The peer's ID to authenticate. - * \param peer_id_len Size of the \p peer_id buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p peer_id is not valid for the \p operation's algorithm and cipher - * suite. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The algorithm doesn't associate a second identity with the session. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * Calling psa_pake_set_peer() is invalid with the \p operation's - * algorithm, the operation state is not valid, or the library has not - * been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation, - const uint8_t *peer_id, - size_t peer_id_len); - -/** Set the application role for a password-authenticated key exchange. - * - * Not all PAKE algorithms need to differentiate the communicating entities. - * It is optional to call this function for PAKEs that don't require a role - * to be specified. For such PAKEs the application role parameter is ignored, - * or #PSA_PAKE_ROLE_NONE can be passed as \c role. - * - * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` - * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) - * for more information. - * - * \param[in,out] operation The operation object to specify the - * application's role for. It must have been set up - * by psa_pake_setup() and not yet in use (neither - * psa_pake_output() nor psa_pake_input() has been - * called yet). It must be on operation for which - * the application's role hasn't been specified - * (psa_pake_set_role() hasn't been called yet). - * \param role A value of type ::psa_pake_role_t indicating the - * application's role in the PAKE the algorithm - * that is being set up. For more information see - * the documentation of \c PSA_PAKE_ROLE_XXX - * constants. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The \p role is not a valid PAKE role in the \p operation’s algorithm. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The \p role for this algorithm is not supported or is not valid. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_set_role(psa_pake_operation_t *operation, - psa_pake_role_t role); - -/** Get output for a step of a password-authenticated key exchange. - * - * Depending on the algorithm being executed, you might need to call this - * function several times or you might not need to call this at all. - * - * The exact sequence of calls to perform a password-authenticated key - * exchange depends on the algorithm in use. Refer to the documentation of - * individual PAKE algorithm types (`PSA_ALG_XXX` values of type - * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more - * information. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_pake_abort(). - * - * \param[in,out] operation Active PAKE operation. - * \param step The step of the algorithm for which the output is - * requested. - * \param[out] output Buffer where the output is to be written in the - * format appropriate for this \p step. Refer to - * the documentation of the individual - * \c PSA_PAKE_STEP_XXX constants for more - * information. - * \param output_size Size of the \p output buffer in bytes. This must - * be at least #PSA_PAKE_OUTPUT_SIZE(\c alg, \c - * primitive, \p output_step) where \c alg and - * \p primitive are the PAKE algorithm and primitive - * in the operation's cipher suite, and \p step is - * the output step. - * - * \param[out] output_length On success, the number of bytes of the returned - * output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p step is not compatible with the operation's algorithm. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p step is not supported with the operation's algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, and fully set - * up, and this call must conform to the algorithm's requirements - * for ordering of input and output steps), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_output(psa_pake_operation_t *operation, - psa_pake_step_t step, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Provide input for a step of a password-authenticated key exchange. - * - * Depending on the algorithm being executed, you might need to call this - * function several times or you might not need to call this at all. - * - * The exact sequence of calls to perform a password-authenticated key - * exchange depends on the algorithm in use. Refer to the documentation of - * individual PAKE algorithm types (`PSA_ALG_XXX` values of type - * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more - * information. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_pake_abort(). - * - * \param[in,out] operation Active PAKE operation. - * \param step The step for which the input is provided. - * \param[in] input Buffer containing the input in the format - * appropriate for this \p step. Refer to the - * documentation of the individual - * \c PSA_PAKE_STEP_XXX constants for more - * information. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The verification fails for a #PSA_PAKE_STEP_ZK_PROOF input step. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p input_length is not compatible with the \p operation’s algorithm, - * or the \p input is not valid for the \p operation's algorithm, - * cipher suite or \p step. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p step p is not supported with the \p operation's algorithm, or the - * \p input is not supported for the \p operation's algorithm, cipher - * suite or \p step. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, and fully set - * up, and this call must conform to the algorithm's requirements - * for ordering of input and output steps), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_input(psa_pake_operation_t *operation, - psa_pake_step_t step, - const uint8_t *input, - size_t input_length); - -/** Get implicitly confirmed shared secret from a PAKE. - * - * At this point there is a cryptographic guarantee that only the authenticated - * party who used the same password is able to compute the key. But there is no - * guarantee that the peer is the party it claims to be and was able to do so. - * - * That is, the authentication is only implicit. Since the peer is not - * authenticated yet, no action should be taken yet that assumes that the peer - * is who it claims to be. For example, do not access restricted files on the - * peer's behalf until an explicit authentication has succeeded. - * - * This function can be called after the key exchange phase of the operation - * has completed. It imports the shared secret output of the PAKE into the - * provided derivation operation. The input step - * #PSA_KEY_DERIVATION_INPUT_SECRET is used when placing the shared key - * material in the key derivation operation. - * - * The exact sequence of calls to perform a password-authenticated key - * exchange depends on the algorithm in use. Refer to the documentation of - * individual PAKE algorithm types (`PSA_ALG_XXX` values of type - * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more - * information. - * - * When this function returns successfully, \p operation becomes inactive. - * If this function returns an error status, both \p operation - * and \c key_derivation operations enter an error state and must be aborted by - * calling psa_pake_abort() and psa_key_derivation_abort() respectively. - * - * \param[in,out] operation Active PAKE operation. - * \param[out] output A key derivation operation that is ready - * for an input step of type - * #PSA_KEY_DERIVATION_INPUT_SECRET. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * #PSA_KEY_DERIVATION_INPUT_SECRET is not compatible with the - * algorithm in the \p output key derivation operation. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Input from a PAKE is not supported by the algorithm in the \p output - * key derivation operation. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The PAKE operation state is not valid (it must be active, but beyond - * that validity is specific to the algorithm), or - * the library has not been previously initialized by psa_crypto_init(), - * or the state of \p output is not valid for - * the #PSA_KEY_DERIVATION_INPUT_SECRET step. This can happen if the - * step is out of order or the application has done this step already - * and it may not be repeated. - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, - psa_key_derivation_operation_t *output); - -/** Abort a PAKE operation. - * - * Aborting an operation frees all associated resources except for the \c - * operation structure itself. Once aborted, the operation object can be reused - * for another operation by calling psa_pake_setup() again. - * - * This function may be called at any time after the operation - * object has been initialized as described in #psa_pake_operation_t. - * - * In particular, calling psa_pake_abort() after the operation has been - * terminated by a call to psa_pake_abort() or psa_pake_get_implicit_key() - * is safe and has no effect. - * - * \param[in,out] operation The operation to abort. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_pake_abort(psa_pake_operation_t *operation); - -/**@}*/ - -static inline psa_algorithm_t psa_pake_cs_get_algorithm( - const psa_pake_cipher_suite_t *cipher_suite) -{ - return cipher_suite->algorithm; -} - -static inline void psa_pake_cs_set_algorithm( - psa_pake_cipher_suite_t *cipher_suite, - psa_algorithm_t algorithm) -{ - if (!PSA_ALG_IS_PAKE(algorithm)) { - cipher_suite->algorithm = 0; - } else { - cipher_suite->algorithm = algorithm; - } -} - -static inline psa_pake_primitive_t psa_pake_cs_get_primitive( - const psa_pake_cipher_suite_t *cipher_suite) -{ - return PSA_PAKE_PRIMITIVE(cipher_suite->type, cipher_suite->family, - cipher_suite->bits); -} - -static inline void psa_pake_cs_set_primitive( - psa_pake_cipher_suite_t *cipher_suite, - psa_pake_primitive_t primitive) -{ - cipher_suite->type = (psa_pake_primitive_type_t) (primitive >> 24); - cipher_suite->family = (psa_pake_family_t) (0xFF & (primitive >> 16)); - cipher_suite->bits = (uint16_t) (0xFFFF & primitive); -} - -static inline psa_pake_family_t psa_pake_cs_get_family( - const psa_pake_cipher_suite_t *cipher_suite) -{ - return cipher_suite->family; -} - -static inline uint16_t psa_pake_cs_get_bits( - const psa_pake_cipher_suite_t *cipher_suite) -{ - return cipher_suite->bits; -} - -static inline psa_algorithm_t psa_pake_cs_get_hash( - const psa_pake_cipher_suite_t *cipher_suite) -{ - return cipher_suite->hash; -} - -static inline void psa_pake_cs_set_hash(psa_pake_cipher_suite_t *cipher_suite, - psa_algorithm_t hash) -{ - if (!PSA_ALG_IS_HASH(hash)) { - cipher_suite->hash = 0; - } else { - cipher_suite->hash = hash; - } -} - -static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void) -{ - const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT; - return v; -} - -static inline struct psa_pake_operation_s psa_pake_operation_init(void) -{ - const struct psa_pake_operation_s v = PSA_PAKE_OPERATION_INIT; - return v; -} - -#ifdef __cplusplus -} -#endif - -#endif /* PSA_CRYPTO_EXTRA_H */ diff --git a/vendor/mbedtls/include/psa/crypto_legacy.h b/vendor/mbedtls/include/psa/crypto_legacy.h deleted file mode 100644 index 7df3614d6..000000000 --- a/vendor/mbedtls/include/psa/crypto_legacy.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * \file psa/crypto_legacy.h - * - * \brief Add temporary suppport for deprecated symbols before they are - * removed from the library. - * - * PSA_WANT_KEY_TYPE_xxx_KEY_PAIR and MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR - * symbols are deprecated. - * New symols add a suffix to that base name in order to clearly state what is - * the expected use for the key (use, import, export, generate, derive). - * Here we define some backward compatibility support for uses stil using - * the legacy symbols. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_PSA_CRYPTO_LEGACY_H -#define MBEDTLS_PSA_CRYPTO_LEGACY_H - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) //no-check-names -#if !defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 -#endif -#if !defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 -#endif -#if !defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 -#endif -#if !defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 -#endif -#if !defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 -#endif -#endif - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) //no-check-names -#if !defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 -#endif -#if !defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 -#endif -#if !defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 -#endif -#if !defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) -#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 -#endif -#endif - -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) //no-check-names -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC -#endif -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT -#endif -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT -#endif -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE -#endif -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE -#endif -#endif - -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) //no-check-names -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC -#endif -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT -#endif -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT -#endif -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE) -#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE -#endif -#endif - -#endif /* MBEDTLS_PSA_CRYPTO_LEGACY_H */ diff --git a/vendor/mbedtls/include/psa/crypto_platform.h b/vendor/mbedtls/include/psa/crypto_platform.h deleted file mode 100644 index a871ee124..000000000 --- a/vendor/mbedtls/include/psa/crypto_platform.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * \file psa/crypto_platform.h - * - * \brief PSA cryptography module: Mbed TLS platform definitions - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * This file contains platform-dependent type definitions. - * - * In implementations with isolation between the application and the - * cryptography module, implementers should take care to ensure that - * the definitions that are exposed to applications match what the - * module implements. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_PLATFORM_H -#define PSA_CRYPTO_PLATFORM_H -#include "mbedtls/private_access.h" - -/* - * Include the build-time configuration information header. Here, we do not - * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which - * is basically just an alias to it. This is to ease the maintenance of the - * TF-PSA-Crypto repository which has a different build system and - * configuration. - */ -#include "psa/build_info.h" - -/* PSA requires several types which C99 provides in stdint.h. */ -#include - -#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) - -/* Building for the PSA Crypto service on a PSA platform, a key owner is a PSA - * partition identifier. - * - * The function psa_its_identifier_of_slot() in psa_crypto_storage.c that - * translates a key identifier to a key storage file name assumes that - * mbedtls_key_owner_id_t is a 32-bit integer. This function thus needs - * reworking if mbedtls_key_owner_id_t is not defined as a 32-bit integer - * here anymore. - */ -typedef int32_t mbedtls_key_owner_id_t; - -/** Compare two key owner identifiers. - * - * \param id1 First key owner identifier. - * \param id2 Second key owner identifier. - * - * \return Non-zero if the two key owner identifiers are equal, zero otherwise. - */ -static inline int mbedtls_key_owner_id_equal(mbedtls_key_owner_id_t id1, - mbedtls_key_owner_id_t id2) -{ - return id1 == id2; -} - -#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ - -/* - * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM - * (Secure Partition Manager) integration which separates the code into two - * parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing - * Environment). When building for the SPE, an additional header file should be - * included. - */ -#if defined(MBEDTLS_PSA_CRYPTO_SPM) -#define PSA_CRYPTO_SECURE 1 -#include "crypto_spe.h" -#endif // MBEDTLS_PSA_CRYPTO_SPM - -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -/** The type of the context passed to mbedtls_psa_external_get_random(). - * - * Mbed TLS initializes the context to all-bits-zero before calling - * mbedtls_psa_external_get_random() for the first time. - * - * The definition of this type in the Mbed TLS source code is for - * demonstration purposes. Implementers of mbedtls_psa_external_get_random() - * are expected to replace it with a custom definition. - */ -typedef struct { - uintptr_t MBEDTLS_PRIVATE(opaque)[2]; -} mbedtls_psa_external_random_context_t; -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -/** The type of the client handle used in context structures - * - * When a client view of the multipart context structures is required, - * this handle is used to keep a mapping with the service side of the - * context which contains the actual data. - */ -typedef uint32_t mbedtls_psa_client_handle_t; -#endif - -#endif /* PSA_CRYPTO_PLATFORM_H */ diff --git a/vendor/mbedtls/include/psa/crypto_se_driver.h b/vendor/mbedtls/include/psa/crypto_se_driver.h deleted file mode 100644 index 9ce14bba6..000000000 --- a/vendor/mbedtls/include/psa/crypto_se_driver.h +++ /dev/null @@ -1,1383 +0,0 @@ -/** - * \file psa/crypto_se_driver.h - * \brief PSA external cryptoprocessor driver module - * - * This header declares types and function signatures for cryptography - * drivers that access key material via opaque references. - * This is meant for cryptoprocessors that have a separate key storage from the - * space in which the PSA Crypto implementation runs, typically secure - * elements (SEs). - * - * This file is part of the PSA Crypto Driver HAL (hardware abstraction layer), - * containing functions for driver developers to implement to enable hardware - * to be called in a standardized way by a PSA Cryptography API - * implementation. The functions comprising the driver HAL, which driver - * authors implement, are not intended to be called by application developers. - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef PSA_CRYPTO_SE_DRIVER_H -#define PSA_CRYPTO_SE_DRIVER_H -#include "mbedtls/private_access.h" - -#include "crypto_driver_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup se_init Secure element driver initialization - */ -/**@{*/ - -/** \brief Driver context structure - * - * Driver functions receive a pointer to this structure. - * Each registered driver has one instance of this structure. - * - * Implementations must include the fields specified here and - * may include other fields. - */ -typedef struct { - /** A read-only pointer to the driver's persistent data. - * - * Drivers typically use this persistent data to keep track of - * which slot numbers are available. This is only a guideline: - * drivers may use the persistent data for any purpose, keeping - * in mind the restrictions on when the persistent data is saved - * to storage: the persistent data is only saved after calling - * certain functions that receive a writable pointer to the - * persistent data. - * - * The core allocates a memory buffer for the persistent data. - * The pointer is guaranteed to be suitably aligned for any data type, - * like a pointer returned by `malloc` (but the core can use any - * method to allocate the buffer, not necessarily `malloc`). - * - * The size of this buffer is in the \c persistent_data_size field of - * this structure. - * - * Before the driver is initialized for the first time, the content of - * the persistent data is all-bits-zero. After a driver upgrade, if the - * size of the persistent data has increased, the original data is padded - * on the right with zeros; if the size has decreased, the original data - * is truncated to the new size. - * - * This pointer is to read-only data. Only a few driver functions are - * allowed to modify the persistent data. These functions receive a - * writable pointer. These functions are: - * - psa_drv_se_t::p_init - * - psa_drv_se_key_management_t::p_allocate - * - psa_drv_se_key_management_t::p_destroy - * - * The PSA Cryptography core saves the persistent data from one - * session to the next. It does this before returning from API functions - * that call a driver method that is allowed to modify the persistent - * data, specifically: - * - psa_crypto_init() causes a call to psa_drv_se_t::p_init, and may call - * psa_drv_se_key_management_t::p_destroy to complete an action - * that was interrupted by a power failure. - * - Key creation functions cause a call to - * psa_drv_se_key_management_t::p_allocate, and may cause a call to - * psa_drv_se_key_management_t::p_destroy in case an error occurs. - * - psa_destroy_key() causes a call to - * psa_drv_se_key_management_t::p_destroy. - */ - const void *const MBEDTLS_PRIVATE(persistent_data); - - /** The size of \c persistent_data in bytes. - * - * This is always equal to the value of the `persistent_data_size` field - * of the ::psa_drv_se_t structure when the driver is registered. - */ - const size_t MBEDTLS_PRIVATE(persistent_data_size); - - /** Driver transient data. - * - * The core initializes this value to 0 and does not read or modify it - * afterwards. The driver may store whatever it wants in this field. - */ - uintptr_t MBEDTLS_PRIVATE(transient_data); -} psa_drv_se_context_t; - -/** \brief A driver initialization function. - * - * \param[in,out] drv_context The driver context structure. - * \param[in,out] persistent_data A pointer to the persistent data - * that allows writing. - * \param location The location value for which this driver - * is registered. The driver will be invoked - * for all keys whose lifetime is in this - * location. - * - * \retval #PSA_SUCCESS - * The driver is operational. - * The core will update the persistent data in storage. - * \return - * Any other return value prevents the driver from being used in - * this session. - * The core will NOT update the persistent data in storage. - */ -typedef psa_status_t (*psa_drv_se_init_t)(psa_drv_se_context_t *drv_context, - void *persistent_data, - psa_key_location_t location); - -#if defined(__DOXYGEN_ONLY__) || !defined(MBEDTLS_PSA_CRYPTO_SE_C) -/* Mbed TLS with secure element support enabled defines this type in - * crypto_types.h because it is also visible to applications through an - * implementation-specific extension. - * For the PSA Cryptography specification, this type is only visible - * via crypto_se_driver.h. */ -/** An internal designation of a key slot between the core part of the - * PSA Crypto implementation and the driver. The meaning of this value - * is driver-dependent. */ -typedef uint64_t psa_key_slot_number_t; -#endif /* __DOXYGEN_ONLY__ || !MBEDTLS_PSA_CRYPTO_SE_C */ - -/**@}*/ - -/** \defgroup se_mac Secure Element Message Authentication Codes - * Generation and authentication of Message Authentication Codes (MACs) using - * a secure element can be done either as a single function call (via the - * `psa_drv_se_mac_generate_t` or `psa_drv_se_mac_verify_t` functions), or in - * parts using the following sequence: - * - `psa_drv_se_mac_setup_t` - * - `psa_drv_se_mac_update_t` - * - `psa_drv_se_mac_update_t` - * - ... - * - `psa_drv_se_mac_finish_t` or `psa_drv_se_mac_finish_verify_t` - * - * If a previously started secure element MAC operation needs to be terminated, - * it should be done so by the `psa_drv_se_mac_abort_t`. Failure to do so may - * result in allocated resources not being freed or in other undefined - * behavior. - */ -/**@{*/ -/** \brief A function that starts a secure element MAC operation for a PSA - * Crypto Driver implementation - * - * \param[in,out] drv_context The driver context structure. - * \param[in,out] op_context A structure that will contain the - * hardware-specific MAC context - * \param[in] key_slot The slot of the key to be used for the - * operation - * \param[in] algorithm The algorithm to be used to underly the MAC - * operation - * - * \retval #PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_se_mac_setup_t)(psa_drv_se_context_t *drv_context, - void *op_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t algorithm); - -/** \brief A function that continues a previously started secure element MAC - * operation - * - * \param[in,out] op_context A hardware-specific structure for the - * previously-established MAC operation to be - * updated - * \param[in] p_input A buffer containing the message to be appended - * to the MAC operation - * \param[in] input_length The size in bytes of the input message buffer - */ -typedef psa_status_t (*psa_drv_se_mac_update_t)(void *op_context, - const uint8_t *p_input, - size_t input_length); - -/** \brief a function that completes a previously started secure element MAC - * operation by returning the resulting MAC. - * - * \param[in,out] op_context A hardware-specific structure for the - * previously started MAC operation to be - * finished - * \param[out] p_mac A buffer where the generated MAC will be - * placed - * \param[in] mac_size The size in bytes of the buffer that has been - * allocated for the `output` buffer - * \param[out] p_mac_length After completion, will contain the number of - * bytes placed in the `p_mac` buffer - * - * \retval #PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *op_context, - uint8_t *p_mac, - size_t mac_size, - size_t *p_mac_length); - -/** \brief A function that completes a previously started secure element MAC - * operation by comparing the resulting MAC against a provided value - * - * \param[in,out] op_context A hardware-specific structure for the previously - * started MAC operation to be finished - * \param[in] p_mac The MAC value against which the resulting MAC - * will be compared against - * \param[in] mac_length The size in bytes of the value stored in `p_mac` - * - * \retval #PSA_SUCCESS - * The operation completed successfully and the MACs matched each - * other - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The operation completed successfully, but the calculated MAC did - * not match the provided MAC - */ -typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *op_context, - const uint8_t *p_mac, - size_t mac_length); - -/** \brief A function that aborts a previous started secure element MAC - * operation - * - * \param[in,out] op_context A hardware-specific structure for the previously - * started MAC operation to be aborted - */ -typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *op_context); - -/** \brief A function that performs a secure element MAC operation in one - * command and returns the calculated MAC - * - * \param[in,out] drv_context The driver context structure. - * \param[in] p_input A buffer containing the message to be MACed - * \param[in] input_length The size in bytes of `p_input` - * \param[in] key_slot The slot of the key to be used - * \param[in] alg The algorithm to be used to underlie the MAC - * operation - * \param[out] p_mac A buffer where the generated MAC will be - * placed - * \param[in] mac_size The size in bytes of the `p_mac` buffer - * \param[out] p_mac_length After completion, will contain the number of - * bytes placed in the `output` buffer - * - * \retval #PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_se_mac_generate_t)(psa_drv_se_context_t *drv_context, - const uint8_t *p_input, - size_t input_length, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - uint8_t *p_mac, - size_t mac_size, - size_t *p_mac_length); - -/** \brief A function that performs a secure element MAC operation in one - * command and compares the resulting MAC against a provided value - * - * \param[in,out] drv_context The driver context structure. - * \param[in] p_input A buffer containing the message to be MACed - * \param[in] input_length The size in bytes of `input` - * \param[in] key_slot The slot of the key to be used - * \param[in] alg The algorithm to be used to underlie the MAC - * operation - * \param[in] p_mac The MAC value against which the resulting MAC will - * be compared against - * \param[in] mac_length The size in bytes of `mac` - * - * \retval #PSA_SUCCESS - * The operation completed successfully and the MACs matched each - * other - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The operation completed successfully, but the calculated MAC did - * not match the provided MAC - */ -typedef psa_status_t (*psa_drv_se_mac_verify_t)(psa_drv_se_context_t *drv_context, - const uint8_t *p_input, - size_t input_length, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - const uint8_t *p_mac, - size_t mac_length); - -/** \brief A struct containing all of the function pointers needed to - * perform secure element MAC operations - * - * PSA Crypto API implementations should populate the table as appropriate - * upon startup. - * - * If one of the functions is not implemented (such as - * `psa_drv_se_mac_generate_t`), it should be set to NULL. - * - * Driver implementers should ensure that they implement all of the functions - * that make sense for their hardware, and that they provide a full solution - * (for example, if they support `p_setup`, they should also support - * `p_update` and at least one of `p_finish` or `p_finish_verify`). - * - */ -typedef struct { - /**The size in bytes of the hardware-specific secure element MAC context - * structure - */ - size_t MBEDTLS_PRIVATE(context_size); - /** Function that performs a MAC setup operation - */ - psa_drv_se_mac_setup_t MBEDTLS_PRIVATE(p_setup); - /** Function that performs a MAC update operation - */ - psa_drv_se_mac_update_t MBEDTLS_PRIVATE(p_update); - /** Function that completes a MAC operation - */ - psa_drv_se_mac_finish_t MBEDTLS_PRIVATE(p_finish); - /** Function that completes a MAC operation with a verify check - */ - psa_drv_se_mac_finish_verify_t MBEDTLS_PRIVATE(p_finish_verify); - /** Function that aborts a previously started MAC operation - */ - psa_drv_se_mac_abort_t MBEDTLS_PRIVATE(p_abort); - /** Function that performs a MAC operation in one call - */ - psa_drv_se_mac_generate_t MBEDTLS_PRIVATE(p_mac); - /** Function that performs a MAC and verify operation in one call - */ - psa_drv_se_mac_verify_t MBEDTLS_PRIVATE(p_mac_verify); -} psa_drv_se_mac_t; -/**@}*/ - -/** \defgroup se_cipher Secure Element Symmetric Ciphers - * - * Encryption and Decryption using secure element keys in block modes other - * than ECB must be done in multiple parts, using the following flow: - * - `psa_drv_se_cipher_setup_t` - * - `psa_drv_se_cipher_set_iv_t` (optional depending upon block mode) - * - `psa_drv_se_cipher_update_t` - * - `psa_drv_se_cipher_update_t` - * - ... - * - `psa_drv_se_cipher_finish_t` - * - * If a previously started secure element Cipher operation needs to be - * terminated, it should be done so by the `psa_drv_se_cipher_abort_t`. Failure - * to do so may result in allocated resources not being freed or in other - * undefined behavior. - * - * In situations where a PSA Cryptographic API implementation is using a block - * mode not-supported by the underlying hardware or driver, it can construct - * the block mode itself, while calling the `psa_drv_se_cipher_ecb_t` function - * for the cipher operations. - */ -/**@{*/ - -/** \brief A function that provides the cipher setup function for a - * secure element driver - * - * \param[in,out] drv_context The driver context structure. - * \param[in,out] op_context A structure that will contain the - * hardware-specific cipher context. - * \param[in] key_slot The slot of the key to be used for the - * operation - * \param[in] algorithm The algorithm to be used in the cipher - * operation - * \param[in] direction Indicates whether the operation is an encrypt - * or decrypt - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - */ -typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context, - void *op_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t algorithm, - psa_encrypt_or_decrypt_t direction); - -/** \brief A function that sets the initialization vector (if - * necessary) for a secure element cipher operation - * - * Rationale: The `psa_se_cipher_*` operation in the PSA Cryptographic API has - * two IV functions: one to set the IV, and one to generate it internally. The - * generate function is not necessary for the drivers to implement as the PSA - * Crypto implementation can do the generation using its RNG features. - * - * \param[in,out] op_context A structure that contains the previously set up - * hardware-specific cipher context - * \param[in] p_iv A buffer containing the initialization vector - * \param[in] iv_length The size (in bytes) of the `p_iv` buffer - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context, - const uint8_t *p_iv, - size_t iv_length); - -/** \brief A function that continues a previously started secure element cipher - * operation - * - * \param[in,out] op_context A hardware-specific structure for the - * previously started cipher operation - * \param[in] p_input A buffer containing the data to be - * encrypted/decrypted - * \param[in] input_size The size in bytes of the buffer pointed to - * by `p_input` - * \param[out] p_output The caller-allocated buffer where the - * output will be placed - * \param[in] output_size The allocated size in bytes of the - * `p_output` buffer - * \param[out] p_output_length After completion, will contain the number - * of bytes placed in the `p_output` buffer - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context, - const uint8_t *p_input, - size_t input_size, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** \brief A function that completes a previously started secure element cipher - * operation - * - * \param[in,out] op_context A hardware-specific structure for the - * previously started cipher operation - * \param[out] p_output The caller-allocated buffer where the output - * will be placed - * \param[in] output_size The allocated size in bytes of the `p_output` - * buffer - * \param[out] p_output_length After completion, will contain the number of - * bytes placed in the `p_output` buffer - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** \brief A function that aborts a previously started secure element cipher - * operation - * - * \param[in,out] op_context A hardware-specific structure for the - * previously started cipher operation - */ -typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context); - -/** \brief A function that performs the ECB block mode for secure element - * cipher operations - * - * Note: this function should only be used with implementations that do not - * provide a needed higher-level operation. - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key_slot The slot of the key to be used for the operation - * \param[in] algorithm The algorithm to be used in the cipher operation - * \param[in] direction Indicates whether the operation is an encrypt or - * decrypt - * \param[in] p_input A buffer containing the data to be - * encrypted/decrypted - * \param[in] input_size The size in bytes of the buffer pointed to by - * `p_input` - * \param[out] p_output The caller-allocated buffer where the output - * will be placed - * \param[in] output_size The allocated size in bytes of the `p_output` - * buffer - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - */ -typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t algorithm, - psa_encrypt_or_decrypt_t direction, - const uint8_t *p_input, - size_t input_size, - uint8_t *p_output, - size_t output_size); - -/** - * \brief A struct containing all of the function pointers needed to implement - * cipher operations using secure elements. - * - * PSA Crypto API implementations should populate instances of the table as - * appropriate upon startup or at build time. - * - * If one of the functions is not implemented (such as - * `psa_drv_se_cipher_ecb_t`), it should be set to NULL. - */ -typedef struct { - /** The size in bytes of the hardware-specific secure element cipher - * context structure - */ - size_t MBEDTLS_PRIVATE(context_size); - /** Function that performs a cipher setup operation */ - psa_drv_se_cipher_setup_t MBEDTLS_PRIVATE(p_setup); - /** Function that sets a cipher IV (if necessary) */ - psa_drv_se_cipher_set_iv_t MBEDTLS_PRIVATE(p_set_iv); - /** Function that performs a cipher update operation */ - psa_drv_se_cipher_update_t MBEDTLS_PRIVATE(p_update); - /** Function that completes a cipher operation */ - psa_drv_se_cipher_finish_t MBEDTLS_PRIVATE(p_finish); - /** Function that aborts a cipher operation */ - psa_drv_se_cipher_abort_t MBEDTLS_PRIVATE(p_abort); - /** Function that performs ECB mode for a cipher operation - * (Danger: ECB mode should not be used directly by clients of the PSA - * Crypto Client API) - */ - psa_drv_se_cipher_ecb_t MBEDTLS_PRIVATE(p_ecb); -} psa_drv_se_cipher_t; - -/**@}*/ - -/** \defgroup se_asymmetric Secure Element Asymmetric Cryptography - * - * Since the amount of data that can (or should) be encrypted or signed using - * asymmetric keys is limited by the key size, asymmetric key operations using - * keys in a secure element must be done in single function calls. - */ -/**@{*/ - -/** - * \brief A function that signs a hash or short message with a private key in - * a secure element - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key_slot Key slot of an asymmetric key pair - * \param[in] alg A signature algorithm that is compatible - * with the type of `key` - * \param[in] p_hash The hash to sign - * \param[in] hash_length Size of the `p_hash` buffer in bytes - * \param[out] p_signature Buffer where the signature is to be written - * \param[in] signature_size Size of the `p_signature` buffer in bytes - * \param[out] p_signature_length On success, the number of bytes - * that make up the returned signature value - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - const uint8_t *p_hash, - size_t hash_length, - uint8_t *p_signature, - size_t signature_size, - size_t *p_signature_length); - -/** - * \brief A function that verifies the signature a hash or short message using - * an asymmetric public key in a secure element - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key_slot Key slot of a public key or an asymmetric key - * pair - * \param[in] alg A signature algorithm that is compatible with - * the type of `key` - * \param[in] p_hash The hash whose signature is to be verified - * \param[in] hash_length Size of the `p_hash` buffer in bytes - * \param[in] p_signature Buffer containing the signature to verify - * \param[in] signature_length Size of the `p_signature` buffer in bytes - * - * \retval #PSA_SUCCESS - * The signature is valid. - */ -typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - const uint8_t *p_hash, - size_t hash_length, - const uint8_t *p_signature, - size_t signature_length); - -/** - * \brief A function that encrypts a short message with an asymmetric public - * key in a secure element - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key_slot Key slot of a public key or an asymmetric key - * pair - * \param[in] alg An asymmetric encryption algorithm that is - * compatible with the type of `key` - * \param[in] p_input The message to encrypt - * \param[in] input_length Size of the `p_input` buffer in bytes - * \param[in] p_salt A salt or label, if supported by the - * encryption algorithm - * If the algorithm does not support a - * salt, pass `NULL`. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass `NULL`. - * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param[in] salt_length Size of the `p_salt` buffer in bytes - * If `p_salt` is `NULL`, pass 0. - * \param[out] p_output Buffer where the encrypted message is to - * be written - * \param[in] output_size Size of the `p_output` buffer in bytes - * \param[out] p_output_length On success, the number of bytes that make up - * the returned output - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - const uint8_t *p_input, - size_t input_length, - const uint8_t *p_salt, - size_t salt_length, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** - * \brief A function that decrypts a short message with an asymmetric private - * key in a secure element. - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key_slot Key slot of an asymmetric key pair - * \param[in] alg An asymmetric encryption algorithm that is - * compatible with the type of `key` - * \param[in] p_input The message to decrypt - * \param[in] input_length Size of the `p_input` buffer in bytes - * \param[in] p_salt A salt or label, if supported by the - * encryption algorithm - * If the algorithm does not support a - * salt, pass `NULL`. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass `NULL`. - * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param[in] salt_length Size of the `p_salt` buffer in bytes - * If `p_salt` is `NULL`, pass 0. - * \param[out] p_output Buffer where the decrypted message is to - * be written - * \param[in] output_size Size of the `p_output` buffer in bytes - * \param[out] p_output_length On success, the number of bytes - * that make up the returned output - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t alg, - const uint8_t *p_input, - size_t input_length, - const uint8_t *p_salt, - size_t salt_length, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** - * \brief A struct containing all of the function pointers needed to implement - * asymmetric cryptographic operations using secure elements. - * - * PSA Crypto API implementations should populate instances of the table as - * appropriate upon startup or at build time. - * - * If one of the functions is not implemented, it should be set to NULL. - */ -typedef struct { - /** Function that performs an asymmetric sign operation */ - psa_drv_se_asymmetric_sign_t MBEDTLS_PRIVATE(p_sign); - /** Function that performs an asymmetric verify operation */ - psa_drv_se_asymmetric_verify_t MBEDTLS_PRIVATE(p_verify); - /** Function that performs an asymmetric encrypt operation */ - psa_drv_se_asymmetric_encrypt_t MBEDTLS_PRIVATE(p_encrypt); - /** Function that performs an asymmetric decrypt operation */ - psa_drv_se_asymmetric_decrypt_t MBEDTLS_PRIVATE(p_decrypt); -} psa_drv_se_asymmetric_t; - -/**@}*/ - -/** \defgroup se_aead Secure Element Authenticated Encryption with Additional Data - * Authenticated Encryption with Additional Data (AEAD) operations with secure - * elements must be done in one function call. While this creates a burden for - * implementers as there must be sufficient space in memory for the entire - * message, it prevents decrypted data from being made available before the - * authentication operation is complete and the data is known to be authentic. - */ -/**@{*/ - -/** \brief A function that performs a secure element authenticated encryption - * operation - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key_slot Slot containing the key to use. - * \param[in] algorithm The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(`alg`) is true) - * \param[in] p_nonce Nonce or IV to use - * \param[in] nonce_length Size of the `p_nonce` buffer in bytes - * \param[in] p_additional_data Additional data that will be - * authenticated but not encrypted - * \param[in] additional_data_length Size of `p_additional_data` in bytes - * \param[in] p_plaintext Data that will be authenticated and - * encrypted - * \param[in] plaintext_length Size of `p_plaintext` in bytes - * \param[out] p_ciphertext Output buffer for the authenticated and - * encrypted data. The additional data is - * not part of this output. For algorithms - * where the encrypted data and the - * authentication tag are defined as - * separate outputs, the authentication - * tag is appended to the encrypted data. - * \param[in] ciphertext_size Size of the `p_ciphertext` buffer in - * bytes - * \param[out] p_ciphertext_length On success, the size of the output in - * the `p_ciphertext` buffer - * - * \retval #PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t algorithm, - const uint8_t *p_nonce, - size_t nonce_length, - const uint8_t *p_additional_data, - size_t additional_data_length, - const uint8_t *p_plaintext, - size_t plaintext_length, - uint8_t *p_ciphertext, - size_t ciphertext_size, - size_t *p_ciphertext_length); - -/** A function that performs a secure element authenticated decryption operation - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key_slot Slot containing the key to use - * \param[in] algorithm The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(`alg`) is true) - * \param[in] p_nonce Nonce or IV to use - * \param[in] nonce_length Size of the `p_nonce` buffer in bytes - * \param[in] p_additional_data Additional data that has been - * authenticated but not encrypted - * \param[in] additional_data_length Size of `p_additional_data` in bytes - * \param[in] p_ciphertext Data that has been authenticated and - * encrypted. - * For algorithms where the encrypted data - * and the authentication tag are defined - * as separate inputs, the buffer must - * contain the encrypted data followed by - * the authentication tag. - * \param[in] ciphertext_length Size of `p_ciphertext` in bytes - * \param[out] p_plaintext Output buffer for the decrypted data - * \param[in] plaintext_size Size of the `p_plaintext` buffer in - * bytes - * \param[out] p_plaintext_length On success, the size of the output in - * the `p_plaintext` buffer - * - * \retval #PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - psa_algorithm_t algorithm, - const uint8_t *p_nonce, - size_t nonce_length, - const uint8_t *p_additional_data, - size_t additional_data_length, - const uint8_t *p_ciphertext, - size_t ciphertext_length, - uint8_t *p_plaintext, - size_t plaintext_size, - size_t *p_plaintext_length); - -/** - * \brief A struct containing all of the function pointers needed to implement - * secure element Authenticated Encryption with Additional Data operations - * - * PSA Crypto API implementations should populate instances of the table as - * appropriate upon startup. - * - * If one of the functions is not implemented, it should be set to NULL. - */ -typedef struct { - /** Function that performs the AEAD encrypt operation */ - psa_drv_se_aead_encrypt_t MBEDTLS_PRIVATE(p_encrypt); - /** Function that performs the AEAD decrypt operation */ - psa_drv_se_aead_decrypt_t MBEDTLS_PRIVATE(p_decrypt); -} psa_drv_se_aead_t; -/**@}*/ - -/** \defgroup se_key_management Secure Element Key Management - * Currently, key management is limited to importing keys in the clear, - * destroying keys, and exporting keys in the clear. - * Whether a key may be exported is determined by the key policies in place - * on the key slot. - */ -/**@{*/ - -/** An enumeration indicating how a key is created. - */ -typedef enum { - PSA_KEY_CREATION_IMPORT, /**< During psa_import_key() */ - PSA_KEY_CREATION_GENERATE, /**< During psa_generate_key() */ - PSA_KEY_CREATION_DERIVE, /**< During psa_key_derivation_output_key() */ - PSA_KEY_CREATION_COPY, /**< During psa_copy_key() */ - -#ifndef __DOXYGEN_ONLY__ - /** A key is being registered with mbedtls_psa_register_se_key(). - * - * The core only passes this value to - * psa_drv_se_key_management_t::p_validate_slot_number, not to - * psa_drv_se_key_management_t::p_allocate. The call to - * `p_validate_slot_number` is not followed by any other call to the - * driver: the key is considered successfully registered if the call to - * `p_validate_slot_number` succeeds, or if `p_validate_slot_number` is - * null. - * - * With this creation method, the driver must return #PSA_SUCCESS if - * the given attributes are compatible with the existing key in the slot, - * and #PSA_ERROR_DOES_NOT_EXIST if the driver can determine that there - * is no key with the specified slot number. - * - * This is an Mbed TLS extension. - */ - PSA_KEY_CREATION_REGISTER, -#endif -} psa_key_creation_method_t; - -/** \brief A function that allocates a slot for a key. - * - * To create a key in a specific slot in a secure element, the core - * first calls this function to determine a valid slot number, - * then calls a function to create the key material in that slot. - * In nominal conditions (that is, if no error occurs), - * the effect of a call to a key creation function in the PSA Cryptography - * API with a lifetime that places the key in a secure element is the - * following: - * -# The core calls psa_drv_se_key_management_t::p_allocate - * (or in some implementations - * psa_drv_se_key_management_t::p_validate_slot_number). The driver - * selects (or validates) a suitable slot number given the key attributes - * and the state of the secure element. - * -# The core calls a key creation function in the driver. - * - * The key creation functions in the PSA Cryptography API are: - * - psa_import_key(), which causes - * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_IMPORT - * then a call to psa_drv_se_key_management_t::p_import. - * - psa_generate_key(), which causes - * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_GENERATE - * then a call to psa_drv_se_key_management_t::p_import. - * - psa_key_derivation_output_key(), which causes - * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_DERIVE - * then a call to psa_drv_se_key_derivation_t::p_derive. - * - psa_copy_key(), which causes - * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_COPY - * then a call to psa_drv_se_key_management_t::p_export. - * - * In case of errors, other behaviors are possible. - * - If the PSA Cryptography subsystem dies after the first step, - * for example because the device has lost power abruptly, - * the second step may never happen, or may happen after a reset - * and re-initialization. Alternatively, after a reset and - * re-initialization, the core may call - * psa_drv_se_key_management_t::p_destroy on the slot number that - * was allocated (or validated) instead of calling a key creation function. - * - If an error occurs, the core may call - * psa_drv_se_key_management_t::p_destroy on the slot number that - * was allocated (or validated) instead of calling a key creation function. - * - * Errors and system resets also have an impact on the driver's persistent - * data. If a reset happens before the overall key creation process is - * completed (before or after the second step above), it is unspecified - * whether the persistent data after the reset is identical to what it - * was before or after the call to `p_allocate` (or `p_validate_slot_number`). - * - * \param[in,out] drv_context The driver context structure. - * \param[in,out] persistent_data A pointer to the persistent data - * that allows writing. - * \param[in] attributes Attributes of the key. - * \param method The way in which the key is being created. - * \param[out] key_slot Slot where the key will be stored. - * This must be a valid slot for a key of the - * chosen type. It must be unoccupied. - * - * \retval #PSA_SUCCESS - * Success. - * The core will record \c *key_slot as the key slot where the key - * is stored and will update the persistent data in storage. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - */ -typedef psa_status_t (*psa_drv_se_allocate_key_t)( - psa_drv_se_context_t *drv_context, - void *persistent_data, - const psa_key_attributes_t *attributes, - psa_key_creation_method_t method, - psa_key_slot_number_t *key_slot); - -/** \brief A function that determines whether a slot number is valid - * for a key. - * - * To create a key in a specific slot in a secure element, the core - * first calls this function to validate the choice of slot number, - * then calls a function to create the key material in that slot. - * See the documentation of #psa_drv_se_allocate_key_t for more details. - * - * As of the PSA Cryptography API specification version 1.0, there is no way - * for applications to trigger a call to this function. However some - * implementations offer the capability to create or declare a key in - * a specific slot via implementation-specific means, generally for the - * sake of initial device provisioning or onboarding. Such a mechanism may - * be added to a future version of the PSA Cryptography API specification. - * - * This function may update the driver's persistent data through - * \p persistent_data. The core will save the updated persistent data at the - * end of the key creation process. See the description of - * ::psa_drv_se_allocate_key_t for more information. - * - * \param[in,out] drv_context The driver context structure. - * \param[in,out] persistent_data A pointer to the persistent data - * that allows writing. - * \param[in] attributes Attributes of the key. - * \param method The way in which the key is being created. - * \param[in] key_slot Slot where the key is to be stored. - * - * \retval #PSA_SUCCESS - * The given slot number is valid for a key with the given - * attributes. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The given slot number is not valid for a key with the - * given attributes. This includes the case where the slot - * number is not valid at all. - * \retval #PSA_ERROR_ALREADY_EXISTS - * There is already a key with the specified slot number. - * Drivers may choose to return this error from the key - * creation function instead. - */ -typedef psa_status_t (*psa_drv_se_validate_slot_number_t)( - psa_drv_se_context_t *drv_context, - void *persistent_data, - const psa_key_attributes_t *attributes, - psa_key_creation_method_t method, - psa_key_slot_number_t key_slot); - -/** \brief A function that imports a key into a secure element in binary format - * - * This function can support any output from psa_export_key(). Refer to the - * documentation of psa_export_key() for the format for each key type. - * - * \param[in,out] drv_context The driver context structure. - * \param key_slot Slot where the key will be stored. - * This must be a valid slot for a key of the - * chosen type. It must be unoccupied. - * \param[in] attributes The key attributes, including the lifetime, - * the key type and the usage policy. - * Drivers should not access the key size stored - * in the attributes: it may not match the - * data passed in \p data. - * Drivers can call psa_get_key_lifetime(), - * psa_get_key_type(), - * psa_get_key_usage_flags() and - * psa_get_key_algorithm() to access this - * information. - * \param[in] data Buffer containing the key data. - * \param[in] data_length Size of the \p data buffer in bytes. - * \param[out] bits On success, the key size in bits. The driver - * must determine this value after parsing the - * key according to the key type. - * This value is not used if the function fails. - * - * \retval #PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_se_import_key_t)( - psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - const psa_key_attributes_t *attributes, - const uint8_t *data, - size_t data_length, - size_t *bits); - -/** - * \brief A function that destroys a secure element key and restore the slot to - * its default state - * - * This function destroys the content of the key from a secure element. - * Implementations shall make a best effort to ensure that any previous content - * of the slot is unrecoverable. - * - * This function returns the specified slot to its default state. - * - * \param[in,out] drv_context The driver context structure. - * \param[in,out] persistent_data A pointer to the persistent data - * that allows writing. - * \param key_slot The key slot to erase. - * - * \retval #PSA_SUCCESS - * The slot's content, if any, has been erased. - */ -typedef psa_status_t (*psa_drv_se_destroy_key_t)( - psa_drv_se_context_t *drv_context, - void *persistent_data, - psa_key_slot_number_t key_slot); - -/** - * \brief A function that exports a secure element key in binary format - * - * The output of this function can be passed to psa_import_key() to - * create an equivalent object. - * - * If a key is created with `psa_import_key()` and then exported with - * this function, it is not guaranteed that the resulting data is - * identical: the implementation may choose a different representation - * of the same key if the format permits it. - * - * This function should generate output in the same format that - * `psa_export_key()` does. Refer to the - * documentation of `psa_export_key()` for the format for each key type. - * - * \param[in,out] drv_context The driver context structure. - * \param[in] key Slot whose content is to be exported. This must - * be an occupied key slot. - * \param[out] p_data Buffer where the key data is to be written. - * \param[in] data_size Size of the `p_data` buffer in bytes. - * \param[out] p_data_length On success, the number of bytes - * that make up the key data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key, - uint8_t *p_data, - size_t data_size, - size_t *p_data_length); - -/** - * \brief A function that generates a symmetric or asymmetric key on a secure - * element - * - * If the key type \c type recorded in \p attributes - * is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\c type) = 1), - * the driver may export the public key at the time of generation, - * in the format documented for psa_export_public_key() by writing it - * to the \p pubkey buffer. - * This is optional, intended for secure elements that output the - * public key at generation time and that cannot export the public key - * later. Drivers that do not need this feature should leave - * \p *pubkey_length set to 0 and should - * implement the psa_drv_key_management_t::p_export_public function. - * Some implementations do not support this feature, in which case - * \p pubkey is \c NULL and \p pubkey_size is 0. - * - * \param[in,out] drv_context The driver context structure. - * \param key_slot Slot where the key will be stored. - * This must be a valid slot for a key of the - * chosen type. It must be unoccupied. - * \param[in] attributes The key attributes, including the lifetime, - * the key type and size, and the usage policy. - * Drivers can call psa_get_key_lifetime(), - * psa_get_key_type(), psa_get_key_bits(), - * psa_get_key_usage_flags() and - * psa_get_key_algorithm() to access this - * information. - * \param[out] pubkey A buffer where the driver can write the - * public key, when generating an asymmetric - * key pair. - * This is \c NULL when generating a symmetric - * key or if the core does not support - * exporting the public key at generation time. - * \param pubkey_size The size of the `pubkey` buffer in bytes. - * This is 0 when generating a symmetric - * key or if the core does not support - * exporting the public key at generation time. - * \param[out] pubkey_length On entry, this is always 0. - * On success, the number of bytes written to - * \p pubkey. If this is 0 or unchanged on return, - * the core will not read the \p pubkey buffer, - * and will instead call the driver's - * psa_drv_key_management_t::p_export_public - * function to export the public key when needed. - */ -typedef psa_status_t (*psa_drv_se_generate_key_t)( - psa_drv_se_context_t *drv_context, - psa_key_slot_number_t key_slot, - const psa_key_attributes_t *attributes, - uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length); - -/** - * \brief A struct containing all of the function pointers needed to for secure - * element key management - * - * PSA Crypto API implementations should populate instances of the table as - * appropriate upon startup or at build time. - * - * If one of the functions is not implemented, it should be set to NULL. - */ -typedef struct { - /** Function that allocates a slot for a key. */ - psa_drv_se_allocate_key_t MBEDTLS_PRIVATE(p_allocate); - /** Function that checks the validity of a slot for a key. */ - psa_drv_se_validate_slot_number_t MBEDTLS_PRIVATE(p_validate_slot_number); - /** Function that performs a key import operation */ - psa_drv_se_import_key_t MBEDTLS_PRIVATE(p_import); - /** Function that performs a generation */ - psa_drv_se_generate_key_t MBEDTLS_PRIVATE(p_generate); - /** Function that performs a key destroy operation */ - psa_drv_se_destroy_key_t MBEDTLS_PRIVATE(p_destroy); - /** Function that performs a key export operation */ - psa_drv_se_export_key_t MBEDTLS_PRIVATE(p_export); - /** Function that performs a public key export operation */ - psa_drv_se_export_key_t MBEDTLS_PRIVATE(p_export_public); -} psa_drv_se_key_management_t; - -/**@}*/ - -/** \defgroup driver_derivation Secure Element Key Derivation and Agreement - * Key derivation is the process of generating new key material using an - * existing key and additional parameters, iterating through a basic - * cryptographic function, such as a hash. - * Key agreement is a part of cryptographic protocols that allows two parties - * to agree on the same key value, but starting from different original key - * material. - * The flows are similar, and the PSA Crypto Driver Model uses the same functions - * for both of the flows. - * - * There are two different final functions for the flows, - * `psa_drv_se_key_derivation_derive` and `psa_drv_se_key_derivation_export`. - * `psa_drv_se_key_derivation_derive` is used when the key material should be - * placed in a slot on the hardware and not exposed to the caller. - * `psa_drv_se_key_derivation_export` is used when the key material should be - * returned to the PSA Cryptographic API implementation. - * - * Different key derivation algorithms require a different number of inputs. - * Instead of having an API that takes as input variable length arrays, which - * can be problematic to manage on embedded platforms, the inputs are passed - * to the driver via a function, `psa_drv_se_key_derivation_collateral`, that - * is called multiple times with different `collateral_id`s. Thus, for a key - * derivation algorithm that required 3 parameter inputs, the flow would look - * something like: - * ~~~~~~~~~~~~~{.c} - * psa_drv_se_key_derivation_setup(kdf_algorithm, source_key, dest_key_size_bytes); - * psa_drv_se_key_derivation_collateral(kdf_algorithm_collateral_id_0, - * p_collateral_0, - * collateral_0_size); - * psa_drv_se_key_derivation_collateral(kdf_algorithm_collateral_id_1, - * p_collateral_1, - * collateral_1_size); - * psa_drv_se_key_derivation_collateral(kdf_algorithm_collateral_id_2, - * p_collateral_2, - * collateral_2_size); - * psa_drv_se_key_derivation_derive(); - * ~~~~~~~~~~~~~ - * - * key agreement example: - * ~~~~~~~~~~~~~{.c} - * psa_drv_se_key_derivation_setup(alg, source_key. dest_key_size_bytes); - * psa_drv_se_key_derivation_collateral(DHE_PUBKEY, p_pubkey, pubkey_size); - * psa_drv_se_key_derivation_export(p_session_key, - * session_key_size, - * &session_key_length); - * ~~~~~~~~~~~~~ - */ -/**@{*/ - -/** \brief A function that Sets up a secure element key derivation operation by - * specifying the algorithm and the source key sot - * - * \param[in,out] drv_context The driver context structure. - * \param[in,out] op_context A hardware-specific structure containing any - * context information for the implementation - * \param[in] kdf_alg The algorithm to be used for the key derivation - * \param[in] source_key The key to be used as the source material for - * the key derivation - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context, - void *op_context, - psa_algorithm_t kdf_alg, - psa_key_slot_number_t source_key); - -/** \brief A function that provides collateral (parameters) needed for a secure - * element key derivation or key agreement operation - * - * Since many key derivation algorithms require multiple parameters, it is - * expected that this function may be called multiple times for the same - * operation, each with a different algorithm-specific `collateral_id` - * - * \param[in,out] op_context A hardware-specific structure containing any - * context information for the implementation - * \param[in] collateral_id An ID for the collateral being provided - * \param[in] p_collateral A buffer containing the collateral data - * \param[in] collateral_size The size in bytes of the collateral - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context, - uint32_t collateral_id, - const uint8_t *p_collateral, - size_t collateral_size); - -/** \brief A function that performs the final secure element key derivation - * step and place the generated key material in a slot - * - * \param[in,out] op_context A hardware-specific structure containing any - * context information for the implementation - * \param[in] dest_key The slot where the generated key material - * should be placed - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context, - psa_key_slot_number_t dest_key); - -/** \brief A function that performs the final step of a secure element key - * agreement and place the generated key material in a buffer - * - * \param[out] p_output Buffer in which to place the generated key - * material - * \param[in] output_size The size in bytes of `p_output` - * \param[out] p_output_length Upon success, contains the number of bytes of - * key material placed in `p_output` - * - * \retval #PSA_SUCCESS \emptydescription - */ -typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** - * \brief A struct containing all of the function pointers needed to for secure - * element key derivation and agreement - * - * PSA Crypto API implementations should populate instances of the table as - * appropriate upon startup. - * - * If one of the functions is not implemented, it should be set to NULL. - */ -typedef struct { - /** The driver-specific size of the key derivation context */ - size_t MBEDTLS_PRIVATE(context_size); - /** Function that performs a key derivation setup */ - psa_drv_se_key_derivation_setup_t MBEDTLS_PRIVATE(p_setup); - /** Function that sets key derivation collateral */ - psa_drv_se_key_derivation_collateral_t MBEDTLS_PRIVATE(p_collateral); - /** Function that performs a final key derivation step */ - psa_drv_se_key_derivation_derive_t MBEDTLS_PRIVATE(p_derive); - /** Function that performs a final key derivation or agreement and - * exports the key */ - psa_drv_se_key_derivation_export_t MBEDTLS_PRIVATE(p_export); -} psa_drv_se_key_derivation_t; - -/**@}*/ - -/** \defgroup se_registration Secure element driver registration - */ -/**@{*/ - -/** A structure containing pointers to all the entry points of a - * secure element driver. - * - * Future versions of this specification may add extra substructures at - * the end of this structure. - */ -typedef struct { - /** The version of the driver HAL that this driver implements. - * This is a protection against loading driver binaries built against - * a different version of this specification. - * Use #PSA_DRV_SE_HAL_VERSION. - */ - uint32_t MBEDTLS_PRIVATE(hal_version); - - /** The size of the driver's persistent data in bytes. - * - * This can be 0 if the driver does not need persistent data. - * - * See the documentation of psa_drv_se_context_t::persistent_data - * for more information about why and how a driver can use - * persistent data. - */ - size_t MBEDTLS_PRIVATE(persistent_data_size); - - /** The driver initialization function. - * - * This function is called once during the initialization of the - * PSA Cryptography subsystem, before any other function of the - * driver is called. If this function returns a failure status, - * the driver will be unusable, at least until the next system reset. - * - * If this field is \c NULL, it is equivalent to a function that does - * nothing and returns #PSA_SUCCESS. - */ - psa_drv_se_init_t MBEDTLS_PRIVATE(p_init); - - const psa_drv_se_key_management_t *MBEDTLS_PRIVATE(key_management); - const psa_drv_se_mac_t *MBEDTLS_PRIVATE(mac); - const psa_drv_se_cipher_t *MBEDTLS_PRIVATE(cipher); - const psa_drv_se_aead_t *MBEDTLS_PRIVATE(aead); - const psa_drv_se_asymmetric_t *MBEDTLS_PRIVATE(asymmetric); - const psa_drv_se_key_derivation_t *MBEDTLS_PRIVATE(derivation); -} psa_drv_se_t; - -/** The current version of the secure element driver HAL. - */ -/* 0.0.0 patchlevel 5 */ -#define PSA_DRV_SE_HAL_VERSION 0x00000005 - -/** Register an external cryptoprocessor (secure element) driver. - * - * This function is only intended to be used by driver code, not by - * application code. In implementations with separation between the - * PSA cryptography module and applications, this function should - * only be available to callers that run in the same memory space as - * the cryptography module, and should not be exposed to applications - * running in a different memory space. - * - * This function may be called before psa_crypto_init(). It is - * implementation-defined whether this function may be called - * after psa_crypto_init(). - * - * \note Implementations store metadata about keys including the lifetime - * value, which contains the driver's location indicator. Therefore, - * from one instantiation of the PSA Cryptography - * library to the next one, if there is a key in storage with a certain - * lifetime value, you must always register the same driver (or an - * updated version that communicates with the same secure element) - * with the same location value. - * - * \param location The location value through which this driver will - * be exposed to applications. - * This driver will be used for all keys such that - * `location == #PSA_KEY_LIFETIME_GET_LOCATION( lifetime )`. - * The value #PSA_KEY_LOCATION_LOCAL_STORAGE is reserved - * and may not be used for drivers. Implementations - * may reserve other values. - * \param[in] methods The method table of the driver. This structure must - * remain valid for as long as the cryptography - * module keeps running. It is typically a global - * constant. - * - * \return #PSA_SUCCESS - * The driver was successfully registered. Applications can now - * use \p location to access keys through the methods passed to - * this function. - * \return #PSA_ERROR_BAD_STATE - * This function was called after the initialization of the - * cryptography module, and this implementation does not support - * driver registration at this stage. - * \return #PSA_ERROR_ALREADY_EXISTS - * There is already a registered driver for this value of \p location. - * \return #PSA_ERROR_INVALID_ARGUMENT - * \p location is a reserved value. - * \return #PSA_ERROR_NOT_SUPPORTED - * `methods->hal_version` is not supported by this implementation. - * \return #PSA_ERROR_INSUFFICIENT_MEMORY - * \return #PSA_ERROR_NOT_PERMITTED - * \return #PSA_ERROR_STORAGE_FAILURE - * \return #PSA_ERROR_DATA_CORRUPT - */ -psa_status_t psa_register_se_driver( - psa_key_location_t location, - const psa_drv_se_t *methods); - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif /* PSA_CRYPTO_SE_DRIVER_H */ diff --git a/vendor/mbedtls/include/psa/crypto_sizes.h b/vendor/mbedtls/include/psa/crypto_sizes.h deleted file mode 100644 index 1bf84de8c..000000000 --- a/vendor/mbedtls/include/psa/crypto_sizes.h +++ /dev/null @@ -1,1319 +0,0 @@ -/** - * \file psa/crypto_sizes.h - * - * \brief PSA cryptography module: Mbed TLS buffer size macros - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * This file contains the definitions of macros that are useful to - * compute buffer sizes. The signatures and semantics of these macros - * are standardized, but the definitions are not, because they depend on - * the available algorithms and, in some cases, on permitted tolerances - * on buffer sizes. - * - * In implementations with isolation between the application and the - * cryptography module, implementers should take care to ensure that - * the definitions that are exposed to applications match what the - * module implements. - * - * Macros that compute sizes whose values do not depend on the - * implementation are in crypto.h. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_SIZES_H -#define PSA_CRYPTO_SIZES_H - -/* - * Include the build-time configuration information header. Here, we do not - * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which - * is basically just an alias to it. This is to ease the maintenance of the - * TF-PSA-Crypto repository which has a different build system and - * configuration. - */ -#include "psa/build_info.h" - -#define PSA_BITS_TO_BYTES(bits) (((bits) + 7u) / 8u) -#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8u) -#define PSA_MAX_OF_THREE(a, b, c) ((a) <= (b) ? (b) <= (c) ? \ - (c) : (b) : (a) <= (c) ? (c) : (a)) - -#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \ - (((length) + (block_size) - 1) / (block_size) * (block_size)) - -/** The size of the output of psa_hash_finish(), in bytes. - * - * This is also the hash size that psa_hash_verify() expects. - * - * \param alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm - * (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a - * hash algorithm). - * - * \return The hash size for the specified hash algorithm. - * If the hash algorithm is not recognized, return 0. - */ -#define PSA_HASH_LENGTH(alg) \ - ( \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64u : \ - 0u) - -/** The input block size of a hash algorithm, in bytes. - * - * Hash algorithms process their input data in blocks. Hash operations will - * retain any partial blocks until they have enough input to fill the block or - * until the operation is finished. - * This affects the output from psa_hash_suspend(). - * - * \param alg A hash algorithm (\c PSA_ALG_XXX value such that - * PSA_ALG_IS_HASH(\p alg) is true). - * - * \return The block size in bytes for the specified hash algorithm. - * If the hash algorithm is not recognized, return 0. - * An implementation can return either 0 or the correct size for a - * hash algorithm that it recognizes, but does not support. - */ -#define PSA_HASH_BLOCK_LENGTH(alg) \ - ( \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104u : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72u : \ - 0u) - -/** \def PSA_HASH_MAX_SIZE - * - * Maximum size of a hash. - * - * This macro expands to a compile-time constant integer. This value - * is the maximum size of a hash in bytes. - */ -/* Note: for HMAC-SHA-3, the block size is 144 bytes for HMAC-SHA3-224, - * 136 bytes for HMAC-SHA3-256, 104 bytes for SHA3-384, 72 bytes for - * HMAC-SHA3-512. */ -/* Note: PSA_HASH_MAX_SIZE should be kept in sync with MBEDTLS_MD_MAX_SIZE, - * see the note on MBEDTLS_MD_MAX_SIZE for details. */ -#if defined(PSA_WANT_ALG_SHA3_224) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 144u -#elif defined(PSA_WANT_ALG_SHA3_256) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 136u -#elif defined(PSA_WANT_ALG_SHA_512) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128u -#elif defined(PSA_WANT_ALG_SHA_384) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128u -#elif defined(PSA_WANT_ALG_SHA3_384) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 104u -#elif defined(PSA_WANT_ALG_SHA3_512) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 72u -#elif defined(PSA_WANT_ALG_SHA_256) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64u -#elif defined(PSA_WANT_ALG_SHA_224) -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64u -#else /* SHA-1 or smaller */ -#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64u -#endif - -#if defined(PSA_WANT_ALG_SHA_512) || defined(PSA_WANT_ALG_SHA3_512) -#define PSA_HASH_MAX_SIZE 64u -#elif defined(PSA_WANT_ALG_SHA_384) || defined(PSA_WANT_ALG_SHA3_384) -#define PSA_HASH_MAX_SIZE 48u -#elif defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA3_256) -#define PSA_HASH_MAX_SIZE 32u -#elif defined(PSA_WANT_ALG_SHA_224) || defined(PSA_WANT_ALG_SHA3_224) -#define PSA_HASH_MAX_SIZE 28u -#else /* SHA-1 or smaller */ -#define PSA_HASH_MAX_SIZE 20u -#endif - -/** \def PSA_MAC_MAX_SIZE - * - * Maximum size of a MAC. - * - * This macro expands to a compile-time constant integer. This value - * is the maximum size of a MAC in bytes. - */ -/* All non-HMAC MACs have a maximum size that's smaller than the - * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */ -/* Note that the encoding of truncated MAC algorithms limits this value - * to 64 bytes. - */ -#define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE - -/** The length of a tag for an AEAD algorithm, in bytes. - * - * This macro can be used to allocate a buffer of sufficient size to store the - * tag output from psa_aead_finish(). - * - * See also #PSA_AEAD_TAG_MAX_SIZE. - * - * \param key_type The type of the AEAD key. - * \param key_bits The size of the AEAD key in bits. - * \param alg An AEAD algorithm - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \return The tag length for the specified algorithm and key. - * If the AEAD algorithm does not have an identified - * tag that can be distinguished from the rest of - * the ciphertext, return 0. - * If the key type or AEAD algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ - PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ - ((void) (key_bits), 0u)) - -/** The maximum tag size for all supported AEAD algorithms, in bytes. - * - * See also #PSA_AEAD_TAG_LENGTH(\p key_type, \p key_bits, \p alg). - */ -#define PSA_AEAD_TAG_MAX_SIZE 16u - -/* The maximum size of an RSA key on this implementation, in bits. - * This is a vendor-specific macro. - * - * Mbed TLS does not set a hard limit on the size of RSA keys: any key - * whose parameters fit in a bignum is accepted. However large keys can - * induce a large memory usage and long computation times. Unlike other - * auxiliary macros in this file and in crypto.h, which reflect how the - * library is configured, this macro defines how the library is - * configured. This implementation refuses to import or generate an - * RSA key whose size is larger than the value defined here. - * - * Note that an implementation may set different size limits for different - * operations, and does not need to accept all key sizes up to the limit. */ -#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096u - -/* The minimum size of an RSA key on this implementation, in bits. - * This is a vendor-specific macro. - * - * Limits RSA key generation to a minimum due to avoid accidental misuse. - * This value cannot be less than 128 bits. - */ -#if defined(MBEDTLS_RSA_GEN_KEY_MIN_BITS) -#define PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS MBEDTLS_RSA_GEN_KEY_MIN_BITS -#else -#define PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS 1024 -#endif - -/* The maximum size of an DH key on this implementation, in bits. - * This is a vendor-specific macro.*/ -#if defined(PSA_WANT_DH_RFC7919_8192) -#define PSA_VENDOR_FFDH_MAX_KEY_BITS 8192u -#elif defined(PSA_WANT_DH_RFC7919_6144) -#define PSA_VENDOR_FFDH_MAX_KEY_BITS 6144u -#elif defined(PSA_WANT_DH_RFC7919_4096) -#define PSA_VENDOR_FFDH_MAX_KEY_BITS 4096u -#elif defined(PSA_WANT_DH_RFC7919_3072) -#define PSA_VENDOR_FFDH_MAX_KEY_BITS 3072u -#elif defined(PSA_WANT_DH_RFC7919_2048) -#define PSA_VENDOR_FFDH_MAX_KEY_BITS 2048u -#else -#define PSA_VENDOR_FFDH_MAX_KEY_BITS 0u -#endif - -/* The maximum size of an ECC key on this implementation, in bits. - * This is a vendor-specific macro. */ -#if defined(PSA_WANT_ECC_SECP_R1_521) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521u -#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 512u -#elif defined(PSA_WANT_ECC_MONTGOMERY_448) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 448u -#elif defined(PSA_WANT_ECC_SECP_R1_384) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384u -#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384u -#elif defined(PSA_WANT_ECC_SECP_R1_256) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256u -#elif defined(PSA_WANT_ECC_SECP_K1_256) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256u -#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256u -#elif defined(PSA_WANT_ECC_MONTGOMERY_255) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 255u -#elif defined(PSA_WANT_ECC_SECP_R1_224) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224u -#elif defined(PSA_WANT_ECC_SECP_K1_224) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224u -#elif defined(PSA_WANT_ECC_SECP_R1_192) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192u -#elif defined(PSA_WANT_ECC_SECP_K1_192) -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192u -#else -#define PSA_VENDOR_ECC_MAX_CURVE_BITS 0u -#endif - -/** This macro returns the maximum supported length of the PSK for the - * TLS-1.2 PSK-to-MS key derivation - * (#PSA_ALG_TLS12_PSK_TO_MS(\c hash_alg)). - * - * The maximum supported length does not depend on the chosen hash algorithm. - * - * Quoting RFC 4279, Sect 5.3: - * TLS implementations supporting these ciphersuites MUST support - * arbitrary PSK identities up to 128 octets in length, and arbitrary - * PSKs up to 64 octets in length. Supporting longer identities and - * keys is RECOMMENDED. - * - * Therefore, no implementation should define a value smaller than 64 - * for #PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE. - */ -#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE 128u - -/* The expected size of input passed to psa_tls12_ecjpake_to_pms_input, - * which is expected to work with P-256 curve only. */ -#define PSA_TLS12_ECJPAKE_TO_PMS_INPUT_SIZE 65u - -/* The size of a serialized K.X coordinate to be used in - * psa_tls12_ecjpake_to_pms_input. This function only accepts the P-256 - * curve. */ -#define PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE 32u - -/* The maximum number of iterations for PBKDF2 on this implementation, in bits. - * This is a vendor-specific macro. This can be configured if necessary */ -#define PSA_VENDOR_PBKDF2_MAX_ITERATIONS 0xffffffffU - -/** The maximum size of a block cipher. */ -#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16u - -/** The size of the output of psa_mac_sign_finish(), in bytes. - * - * This is also the MAC size that psa_mac_verify_finish() expects. - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type The type of the MAC key. - * \param key_bits The size of the MAC key in bits. - * \param alg A MAC algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_MAC(\p alg) is true). - * - * \return The MAC size for the specified algorithm with - * the specified key parameters. - * \return 0 if the MAC algorithm is not recognized. - * \return Either 0 or the correct size for a MAC algorithm that - * the implementation recognizes, but does not support. - * \return Unspecified if the key parameters are not consistent - * with the algorithm. - */ -#define PSA_MAC_LENGTH(key_type, key_bits, alg) \ - ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \ - PSA_ALG_IS_HMAC(alg) ? PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)) : \ - PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ - ((void) (key_type), (void) (key_bits), 0u)) - -/** The maximum size of the output of psa_aead_encrypt(), in bytes. - * - * If the size of the ciphertext buffer is at least this large, it is - * guaranteed that psa_aead_encrypt() will not fail due to an - * insufficient buffer size. Depending on the algorithm, the actual size of - * the ciphertext may be smaller. - * - * See also #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length). - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type A symmetric key type that is - * compatible with algorithm \p alg. - * \param alg An AEAD algorithm - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * \param plaintext_length Size of the plaintext in bytes. - * - * \return The AEAD ciphertext size for the specified - * algorithm. - * If the key type or AEAD algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext_length) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ - (plaintext_length) + PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ - 0u) - -/** A sufficient output buffer size for psa_aead_encrypt(), for any of the - * supported key types and AEAD algorithms. - * - * If the size of the ciphertext buffer is at least this large, it is guaranteed - * that psa_aead_encrypt() will not fail due to an insufficient buffer size. - * - * \note This macro returns a compile-time constant if its arguments are - * compile-time constants. - * - * See also #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, - * \p plaintext_length). - * - * \param plaintext_length Size of the plaintext in bytes. - * - * \return A sufficient output buffer size for any of the - * supported key types and AEAD algorithms. - * - */ -#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \ - ((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE) - - -/** The maximum size of the output of psa_aead_decrypt(), in bytes. - * - * If the size of the plaintext buffer is at least this large, it is - * guaranteed that psa_aead_decrypt() will not fail due to an - * insufficient buffer size. Depending on the algorithm, the actual size of - * the plaintext may be smaller. - * - * See also #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length). - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type A symmetric key type that is - * compatible with algorithm \p alg. - * \param alg An AEAD algorithm - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * \param ciphertext_length Size of the plaintext in bytes. - * - * \return The AEAD ciphertext size for the specified - * algorithm. - * If the key type or AEAD algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ - (ciphertext_length) > PSA_ALG_AEAD_GET_TAG_LENGTH(alg) ? \ - (ciphertext_length) - PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ - 0u) - -/** A sufficient output buffer size for psa_aead_decrypt(), for any of the - * supported key types and AEAD algorithms. - * - * If the size of the plaintext buffer is at least this large, it is guaranteed - * that psa_aead_decrypt() will not fail due to an insufficient buffer size. - * - * \note This macro returns a compile-time constant if its arguments are - * compile-time constants. - * - * See also #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, - * \p ciphertext_length). - * - * \param ciphertext_length Size of the ciphertext in bytes. - * - * \return A sufficient output buffer size for any of the - * supported key types and AEAD algorithms. - * - */ -#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \ - (ciphertext_length) - -/** The default nonce size for an AEAD algorithm, in bytes. - * - * This macro can be used to allocate a buffer of sufficient size to - * store the nonce output from #psa_aead_generate_nonce(). - * - * See also #PSA_AEAD_NONCE_MAX_SIZE. - * - * \note This is not the maximum size of nonce supported as input to - * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(), - * just the default size that is generated by #psa_aead_generate_nonce(). - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type A symmetric key type that is compatible with - * algorithm \p alg. - * - * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \return The default nonce size for the specified key type and algorithm. - * If the key type or AEAD algorithm is not recognized, - * or the parameters are incompatible, return 0. - */ -#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ - (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 ? \ - MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CCM) ? 13u : \ - MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_GCM) ? 12u : \ - 0u : \ - (key_type) == PSA_KEY_TYPE_CHACHA20 && \ - MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CHACHA20_POLY1305) ? 12u : \ - 0u) - -/** The maximum default nonce size among all supported pairs of key types and - * AEAD algorithms, in bytes. - * - * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() - * may return. - * - * \note This is not the maximum size of nonce supported as input to - * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(), - * just the largest size that may be generated by - * #psa_aead_generate_nonce(). - */ -#define PSA_AEAD_NONCE_MAX_SIZE 13u - -/** A sufficient output buffer size for psa_aead_update(). - * - * If the size of the output buffer is at least this large, it is - * guaranteed that psa_aead_update() will not fail due to an - * insufficient buffer size. The actual size of the output may be smaller - * in any given call. - * - * See also #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length). - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type A symmetric key type that is - * compatible with algorithm \p alg. - * \param alg An AEAD algorithm - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * \param input_length Size of the input in bytes. - * - * \return A sufficient output buffer size for the specified - * algorithm. - * If the key type or AEAD algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -/* For all the AEAD modes defined in this specification, it is possible - * to emit output without delay. However, hardware may not always be - * capable of this. So for modes based on a block cipher, allow the - * implementation to delay the output until it has a full block. */ -#define PSA_AEAD_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ - PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ - PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), (input_length)) : \ - (input_length) : \ - 0u) - -/** A sufficient output buffer size for psa_aead_update(), for any of the - * supported key types and AEAD algorithms. - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_aead_update() will not fail due to an insufficient buffer size. - * - * See also #PSA_AEAD_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). - * - * \param input_length Size of the input in bytes. - */ -#define PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_length) \ - (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length))) - -/** A sufficient ciphertext buffer size for psa_aead_finish(). - * - * If the size of the ciphertext buffer is at least this large, it is - * guaranteed that psa_aead_finish() will not fail due to an - * insufficient ciphertext buffer size. The actual size of the output may - * be smaller in any given call. - * - * See also #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE. - * - * \param key_type A symmetric key type that is - compatible with algorithm \p alg. - * \param alg An AEAD algorithm - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \return A sufficient ciphertext buffer size for the - * specified algorithm. - * If the key type or AEAD algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_AEAD_FINISH_OUTPUT_SIZE(key_type, alg) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ - PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ - 0u) - -/** A sufficient ciphertext buffer size for psa_aead_finish(), for any of the - * supported key types and AEAD algorithms. - * - * See also #PSA_AEAD_FINISH_OUTPUT_SIZE(\p key_type, \p alg). - */ -#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) - -/** A sufficient plaintext buffer size for psa_aead_verify(). - * - * If the size of the plaintext buffer is at least this large, it is - * guaranteed that psa_aead_verify() will not fail due to an - * insufficient plaintext buffer size. The actual size of the output may - * be smaller in any given call. - * - * See also #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE. - * - * \param key_type A symmetric key type that is - * compatible with algorithm \p alg. - * \param alg An AEAD algorithm - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \return A sufficient plaintext buffer size for the - * specified algorithm. - * If the key type or AEAD algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_AEAD_VERIFY_OUTPUT_SIZE(key_type, alg) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ - PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ - 0u) - -/** A sufficient plaintext buffer size for psa_aead_verify(), for any of the - * supported key types and AEAD algorithms. - * - * See also #PSA_AEAD_VERIFY_OUTPUT_SIZE(\p key_type, \p alg). - */ -#define PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) - -#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \ - (PSA_ALG_IS_RSA_OAEP(alg) ? \ - 2u * PSA_HASH_LENGTH(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1u : \ - 11u /*PKCS#1v1.5*/) - -/** - * \brief ECDSA signature size for a given curve bit size - * - * \param curve_bits Curve size in bits. - * \return Signature size in bytes. - * - * \note This macro returns a compile-time constant if its argument is one. - */ -#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \ - (PSA_BITS_TO_BYTES(curve_bits) * 2u) - -/** Sufficient signature buffer size for psa_sign_hash(). - * - * This macro returns a sufficient buffer size for a signature using a key - * of the specified type and size, with the specified algorithm. - * Note that the actual size of the signature may be smaller - * (some algorithms produce a variable-size signature). - * - * \warning This function may call its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type An asymmetric key type (this may indifferently be a - * key pair type or a public key type). - * \param key_bits The size of the key in bits. - * \param alg The signature algorithm. - * - * \return If the parameters are valid and supported, return - * a buffer size in bytes that guarantees that - * psa_sign_hash() will not fail with - * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported, - * return either a sensible size or 0. - * If the parameters are not valid, the - * return value is unspecified. - */ -#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \ - (PSA_KEY_TYPE_IS_RSA(key_type) ? ((void) alg, PSA_BITS_TO_BYTES(key_bits)) : \ - PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \ - ((void) alg, 0u)) - -#define PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE \ - PSA_ECDSA_SIGNATURE_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) - -/** \def PSA_SIGNATURE_MAX_SIZE - * - * Maximum size of an asymmetric signature. - * - * This macro expands to a compile-time constant integer. This value - * is the maximum size of a signature in bytes. - */ -#define PSA_SIGNATURE_MAX_SIZE 1 - -#if (defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) && \ - (PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE > PSA_SIGNATURE_MAX_SIZE) -#undef PSA_SIGNATURE_MAX_SIZE -#define PSA_SIGNATURE_MAX_SIZE PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE -#endif -#if (defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) || defined(PSA_WANT_ALG_RSA_PSS)) && \ - (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_SIGNATURE_MAX_SIZE) -#undef PSA_SIGNATURE_MAX_SIZE -#define PSA_SIGNATURE_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) -#endif - -/** Sufficient output buffer size for psa_asymmetric_encrypt(). - * - * This macro returns a sufficient buffer size for a ciphertext produced using - * a key of the specified type and size, with the specified algorithm. - * Note that the actual size of the ciphertext may be smaller, depending - * on the algorithm. - * - * \warning This function may call its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type An asymmetric key type (this may indifferently be a - * key pair type or a public key type). - * \param key_bits The size of the key in bits. - * \param alg The asymmetric encryption algorithm. - * - * \return If the parameters are valid and supported, return - * a buffer size in bytes that guarantees that - * psa_asymmetric_encrypt() will not fail with - * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported, - * return either a sensible size or 0. - * If the parameters are not valid, the - * return value is unspecified. - */ -#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ - (PSA_KEY_TYPE_IS_RSA(key_type) ? \ - ((void) alg, PSA_BITS_TO_BYTES(key_bits)) : \ - 0u) - -/** A sufficient output buffer size for psa_asymmetric_encrypt(), for any - * supported asymmetric encryption. - * - * See also #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg). - */ -/* This macro assumes that RSA is the only supported asymmetric encryption. */ -#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE \ - (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)) - -/** Sufficient output buffer size for psa_asymmetric_decrypt(). - * - * This macro returns a sufficient buffer size for a plaintext produced using - * a key of the specified type and size, with the specified algorithm. - * Note that the actual size of the plaintext may be smaller, depending - * on the algorithm. - * - * \warning This function may call its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type An asymmetric key type (this may indifferently be a - * key pair type or a public key type). - * \param key_bits The size of the key in bits. - * \param alg The asymmetric encryption algorithm. - * - * \return If the parameters are valid and supported, return - * a buffer size in bytes that guarantees that - * psa_asymmetric_decrypt() will not fail with - * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported, - * return either a sensible size or 0. - * If the parameters are not valid, the - * return value is unspecified. - */ -#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ - (PSA_KEY_TYPE_IS_RSA(key_type) ? \ - PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \ - 0u) - -/** A sufficient output buffer size for psa_asymmetric_decrypt(), for any - * supported asymmetric decryption. - * - * This macro assumes that RSA is the only supported asymmetric encryption. - * - * See also #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg). - */ -#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE \ - (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)) - -/* Maximum size of the ASN.1 encoding of an INTEGER with the specified - * number of bits. - * - * This definition assumes that bits <= 2^19 - 9 so that the length field - * is at most 3 bytes. The length of the encoding is the length of the - * bit string padded to a whole number of bytes plus: - * - 1 type byte; - * - 1 to 3 length bytes; - * - 0 to 1 bytes of leading 0 due to the sign bit. - */ -#define PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(bits) \ - ((bits) / 8u + 5u) - -/* Maximum size of the export encoding of an RSA public key. - * Assumes that the public exponent is less than 2^32. - * - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER } -- e - * - * - 4 bytes of SEQUENCE overhead; - * - n : INTEGER; - * - 7 bytes for the public exponent. - */ -#define PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) \ - (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 11u) - -/* Maximum size of the export encoding of an RSA key pair. - * Assumes that the public exponent is less than 2^32 and that the size - * difference between the two primes is at most 1 bit. - * - * RSAPrivateKey ::= SEQUENCE { - * version Version, -- 0 - * modulus INTEGER, -- N-bit - * publicExponent INTEGER, -- 32-bit - * privateExponent INTEGER, -- N-bit - * prime1 INTEGER, -- N/2-bit - * prime2 INTEGER, -- N/2-bit - * exponent1 INTEGER, -- N/2-bit - * exponent2 INTEGER, -- N/2-bit - * coefficient INTEGER, -- N/2-bit - * } - * - * - 4 bytes of SEQUENCE overhead; - * - 3 bytes of version; - * - 7 half-size INTEGERs plus 2 full-size INTEGERs, - * overapproximated as 9 half-size INTEGERS; - * - 7 bytes for the public exponent. - */ -#define PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) \ - (9u * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2u + 1u) + 14u) - -/* Maximum size of the export encoding of a DSA public key. - * - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } -- contains DSAPublicKey - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters Dss-Params } -- SEQUENCE of 3 INTEGERs - * DSAPublicKey ::= INTEGER -- public key, Y - * - * - 3 * 4 bytes of SEQUENCE overhead; - * - 1 + 1 + 7 bytes of algorithm (DSA OID); - * - 4 bytes of BIT STRING overhead; - * - 3 full-size INTEGERs (p, g, y); - * - 1 + 1 + 32 bytes for 1 sub-size INTEGER (q <= 256 bits). - */ -#define PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) \ - (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3u + 59u) - -/* Maximum size of the export encoding of a DSA key pair. - * - * DSAPrivateKey ::= SEQUENCE { - * version Version, -- 0 - * prime INTEGER, -- p - * subprime INTEGER, -- q - * generator INTEGER, -- g - * public INTEGER, -- y - * private INTEGER, -- x - * } - * - * - 4 bytes of SEQUENCE overhead; - * - 3 bytes of version; - * - 3 full-size INTEGERs (p, g, y); - * - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits). - */ -#define PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) \ - (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3u + 75u) - -/* Maximum size of the export encoding of an ECC public key. - * - * The representation of an ECC public key is: - * - The byte 0x04; - * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; - * - `y_P` as a `ceiling(m/8)`-byte string, big-endian; - * - where m is the bit size associated with the curve. - * - * - 1 byte + 2 * point size. - */ -#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \ - (2u * PSA_BITS_TO_BYTES(key_bits) + 1u) - -/* Maximum size of the export encoding of an ECC key pair. - * - * An ECC key pair is represented by the secret value. - */ -#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \ - (PSA_BITS_TO_BYTES(key_bits)) - -/* Maximum size of the export encoding of an DH key pair. - * - * An DH key pair is represented by the secret value. - */ -#define PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(key_bits) \ - (PSA_BITS_TO_BYTES(key_bits)) - -/* Maximum size of the export encoding of an DH public key. - */ -#define PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(key_bits) \ - (PSA_BITS_TO_BYTES(key_bits)) - -/** Sufficient output buffer size for psa_export_key() or - * psa_export_public_key(). - * - * This macro returns a compile-time constant if its arguments are - * compile-time constants. - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * The following code illustrates how to allocate enough memory to export - * a key by querying the key type and size at runtime. - * \code{c} - * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - * psa_status_t status; - * status = psa_get_key_attributes(key, &attributes); - * if (status != PSA_SUCCESS) handle_error(...); - * psa_key_type_t key_type = psa_get_key_type(&attributes); - * size_t key_bits = psa_get_key_bits(&attributes); - * size_t buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); - * psa_reset_key_attributes(&attributes); - * uint8_t *buffer = malloc(buffer_size); - * if (buffer == NULL) handle_error(...); - * size_t buffer_length; - * status = psa_export_key(key, buffer, buffer_size, &buffer_length); - * if (status != PSA_SUCCESS) handle_error(...); - * \endcode - * - * \param key_type A supported key type. - * \param key_bits The size of the key in bits. - * - * \return If the parameters are valid and supported, return - * a buffer size in bytes that guarantees that - * psa_export_key() or psa_export_public_key() will not fail with - * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not supported, - * return either a sensible size or 0. - * If the parameters are not valid, the return value is unspecified. - */ -#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \ - ((key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \ - (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \ - PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - PSA_BITS_TO_BYTES(key_bits)) /*unstructured; FFDH public or private*/ - -/** Sufficient output buffer size for psa_export_public_key(). - * - * This macro returns a compile-time constant if its arguments are - * compile-time constants. - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * The following code illustrates how to allocate enough memory to export - * a public key by querying the key type and size at runtime. - * \code{c} - * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - * psa_status_t status; - * status = psa_get_key_attributes(key, &attributes); - * if (status != PSA_SUCCESS) handle_error(...); - * psa_key_type_t key_type = psa_get_key_type(&attributes); - * size_t key_bits = psa_get_key_bits(&attributes); - * size_t buffer_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits); - * psa_reset_key_attributes(&attributes); - * uint8_t *buffer = malloc(buffer_size); - * if (buffer == NULL) handle_error(...); - * size_t buffer_length; - * status = psa_export_public_key(key, buffer, buffer_size, &buffer_length); - * if (status != PSA_SUCCESS) handle_error(...); - * \endcode - * - * \param key_type A public key or key pair key type. - * \param key_bits The size of the key in bits. - * - * \return If the parameters are valid and supported, return - * a buffer size in bytes that guarantees that - * psa_export_public_key() will not fail with - * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that is not - * supported, return either a sensible size or 0. - * If the parameters are not valid, - * the return value is unspecified. - * - * If the parameters are valid and supported, - * return the same result as - * #PSA_EXPORT_KEY_OUTPUT_SIZE( - * \p #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\p key_type), - * \p key_bits). - */ -#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \ - (PSA_KEY_TYPE_IS_RSA(key_type) ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ - PSA_KEY_TYPE_IS_DH(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ - 0u) - -/** Sufficient buffer size for exporting any asymmetric key pair. - * - * This macro expands to a compile-time constant integer. This value is - * a sufficient buffer size when calling psa_export_key() to export any - * asymmetric key pair, regardless of the exact key type and key size. - * - * See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). - */ -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE 1 - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \ - (PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \ - PSA_EXPORT_KEY_PAIR_MAX_SIZE) -#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ - PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) -#endif -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) && \ - (PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \ - PSA_EXPORT_KEY_PAIR_MAX_SIZE) -#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ - PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) -#endif -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) && \ - (PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \ - PSA_EXPORT_KEY_PAIR_MAX_SIZE) -#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ - PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) -#endif - -/** Sufficient buffer size for exporting any asymmetric public key. - * - * This macro expands to a compile-time constant integer. This value is - * a sufficient buffer size when calling psa_export_key() or - * psa_export_public_key() to export any asymmetric public key, - * regardless of the exact key type and key size. - * - * See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). - */ -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 1 - -#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \ - (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \ - PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) -#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) -#endif -#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) && \ - (PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \ - PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) -#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ - PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) -#endif -#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) && \ - (PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \ - PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) -#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ - PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) -#endif - -/* This is the name that was standardized in PSA Crypto v1.3 */ -#define PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE \ - ((PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \ - PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) - -/* This is our old custom name from before it was in the spec, - * keep it around in case users were relying on it. */ -#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \ - PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE - -/** Sufficient output buffer size for psa_raw_key_agreement(). - * - * This macro returns a compile-time constant if its arguments are - * compile-time constants. - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE. - * - * \param key_type A supported key type. - * \param key_bits The size of the key in bits. - * - * \return If the parameters are valid and supported, return - * a buffer size in bytes that guarantees that - * psa_raw_key_agreement() will not fail with - * #PSA_ERROR_BUFFER_TOO_SMALL. - * If the parameters are a valid combination that - * is not supported, return either a sensible size or 0. - * If the parameters are not valid, - * the return value is unspecified. - */ -#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \ - ((PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || \ - PSA_KEY_TYPE_IS_DH_KEY_PAIR(key_type)) ? PSA_BITS_TO_BYTES(key_bits) : 0u) - -/** Maximum size of the output from psa_raw_key_agreement(). - * - * This macro expands to a compile-time constant integer. This value is the - * maximum size of the output any raw key agreement algorithm, in bytes. - * - * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits). - */ -#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE 1 - -#if defined(PSA_WANT_ALG_ECDH) && \ - (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) -#undef PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE -#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) -#endif -#if defined(PSA_WANT_ALG_FFDH) && \ - (PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) -#undef PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE -#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) -#endif - -/** Maximum key length for ciphers. - * - * Since there is no additional PSA_WANT_xxx symbol to specifiy the size of - * the key once a cipher is enabled (as it happens for asymmetric keys for - * example), the maximum key length is taken into account for each cipher. - * The resulting value will be the maximum cipher's key length given depending - * on which ciphers are enabled. - * - * Note: max value for AES used below would be doubled if XTS were enabled, but - * this mode is currently not supported in Mbed TLS implementation of PSA - * APIs. - */ -#if (defined(PSA_WANT_KEY_TYPE_AES) || defined(PSA_WANT_KEY_TYPE_ARIA) || \ - defined(PSA_WANT_KEY_TYPE_CAMELLIA) || defined(PSA_WANT_KEY_TYPE_CHACHA20)) -#define PSA_CIPHER_MAX_KEY_LENGTH 32u -#elif defined(PSA_WANT_KEY_TYPE_DES) -#define PSA_CIPHER_MAX_KEY_LENGTH 24u -#else -#define PSA_CIPHER_MAX_KEY_LENGTH 0u -#endif - -/** The default IV size for a cipher algorithm, in bytes. - * - * The IV that is generated as part of a call to #psa_cipher_encrypt() is always - * the default IV length for the algorithm. - * - * This macro can be used to allocate a buffer of sufficient size to - * store the IV output from #psa_cipher_generate_iv() when using - * a multi-part cipher operation. - * - * See also #PSA_CIPHER_IV_MAX_SIZE. - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type A symmetric key type that is compatible with algorithm \p alg. - * - * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that #PSA_ALG_IS_CIPHER(\p alg) is true). - * - * \return The default IV size for the specified key type and algorithm. - * If the algorithm does not use an IV, return 0. - * If the key type or cipher algorithm is not recognized, - * or the parameters are incompatible, return 0. - */ -#define PSA_CIPHER_IV_LENGTH(key_type, alg) \ - (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \ - ((alg) == PSA_ALG_CTR || \ - (alg) == PSA_ALG_CFB || \ - (alg) == PSA_ALG_OFB || \ - (alg) == PSA_ALG_XTS || \ - (alg) == PSA_ALG_CBC_NO_PADDING || \ - (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ - (key_type) == PSA_KEY_TYPE_CHACHA20 && \ - (alg) == PSA_ALG_STREAM_CIPHER ? 12u : \ - (alg) == PSA_ALG_CCM_STAR_NO_TAG ? 13u : \ - 0u) - -/** The maximum IV size for all supported cipher algorithms, in bytes. - * - * See also #PSA_CIPHER_IV_LENGTH(). - */ -#define PSA_CIPHER_IV_MAX_SIZE 16u - -/** The maximum size of the output of psa_cipher_encrypt(), in bytes. - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_cipher_encrypt() will not fail due to an insufficient buffer size. - * Depending on the algorithm, the actual size of the output might be smaller. - * - * See also #PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(\p input_length). - * - * \warning This macro may evaluate its arguments multiple times or - * zero times, so you should not pass arguments that contain - * side effects. - * - * \param key_type A symmetric key type that is compatible with algorithm - * alg. - * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param input_length Size of the input in bytes. - * - * \return A sufficient output size for the specified key type and - * algorithm. If the key type or cipher algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (alg == PSA_ALG_CBC_PKCS7 ? \ - (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) != 0 ? \ - PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ - (input_length) + 1u) + \ - PSA_CIPHER_IV_LENGTH((key_type), (alg)) : 0u) : \ - (PSA_ALG_IS_CIPHER(alg) ? \ - (input_length) + PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \ - 0u)) - -/** A sufficient output buffer size for psa_cipher_encrypt(), for any of the - * supported key types and cipher algorithms. - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_cipher_encrypt() will not fail due to an insufficient buffer size. - * - * See also #PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). - * - * \param input_length Size of the input in bytes. - * - */ -#define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \ - (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, \ - (input_length) + 1u) + \ - PSA_CIPHER_IV_MAX_SIZE) - -/** The maximum size of the output of psa_cipher_decrypt(), in bytes. - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_cipher_decrypt() will not fail due to an insufficient buffer size. - * Depending on the algorithm, the actual size of the output might be smaller. - * - * See also #PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(\p input_length). - * - * \param key_type A symmetric key type that is compatible with algorithm - * alg. - * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param input_length Size of the input in bytes. - * - * \return A sufficient output size for the specified key type and - * algorithm. If the key type or cipher algorithm is not - * recognized, or the parameters are incompatible, - * return 0. - */ -#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (PSA_ALG_IS_CIPHER(alg) && \ - ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ - (input_length) : \ - 0u) - -/** A sufficient output buffer size for psa_cipher_decrypt(), for any of the - * supported key types and cipher algorithms. - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_cipher_decrypt() will not fail due to an insufficient buffer size. - * - * See also #PSA_CIPHER_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). - * - * \param input_length Size of the input in bytes. - */ -#define PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(input_length) \ - (input_length) - -/** A sufficient output buffer size for psa_cipher_update(). - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_cipher_update() will not fail due to an insufficient buffer size. - * The actual size of the output might be smaller in any given call. - * - * See also #PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(\p input_length). - * - * \param key_type A symmetric key type that is compatible with algorithm - * alg. - * \param alg A cipher algorithm (PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param input_length Size of the input in bytes. - * - * \return A sufficient output size for the specified key type and - * algorithm. If the key type or cipher algorithm is not - * recognized, or the parameters are incompatible, return 0. - */ -#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ - (PSA_ALG_IS_CIPHER(alg) ? \ - (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) != 0 ? \ - (((alg) == PSA_ALG_CBC_PKCS7 || \ - (alg) == PSA_ALG_CBC_NO_PADDING || \ - (alg) == PSA_ALG_ECB_NO_PADDING) ? \ - PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ - input_length) : \ - (input_length)) : 0u) : \ - 0u) - -/** A sufficient output buffer size for psa_cipher_update(), for any of the - * supported key types and cipher algorithms. - * - * If the size of the output buffer is at least this large, it is guaranteed - * that psa_cipher_update() will not fail due to an insufficient buffer size. - * - * See also #PSA_CIPHER_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). - * - * \param input_length Size of the input in bytes. - */ -#define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \ - (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, input_length)) - -/** A sufficient ciphertext buffer size for psa_cipher_finish(). - * - * If the size of the ciphertext buffer is at least this large, it is - * guaranteed that psa_cipher_finish() will not fail due to an insufficient - * ciphertext buffer size. The actual size of the output might be smaller in - * any given call. - * - * See also #PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE(). - * - * \param key_type A symmetric key type that is compatible with algorithm - * alg. - * \param alg A cipher algorithm (PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \return A sufficient output size for the specified key type and - * algorithm. If the key type or cipher algorithm is not - * recognized, or the parameters are incompatible, return 0. - */ -#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \ - (PSA_ALG_IS_CIPHER(alg) ? \ - (alg == PSA_ALG_CBC_PKCS7 ? \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ - 0u) : \ - 0u) - -/** A sufficient ciphertext buffer size for psa_cipher_finish(), for any of the - * supported key types and cipher algorithms. - * - * See also #PSA_CIPHER_FINISH_OUTPUT_SIZE(\p key_type, \p alg). - */ -#define PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE \ - (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) - -#endif /* PSA_CRYPTO_SIZES_H */ diff --git a/vendor/mbedtls/include/psa/crypto_struct.h b/vendor/mbedtls/include/psa/crypto_struct.h deleted file mode 100644 index 362e921a3..000000000 --- a/vendor/mbedtls/include/psa/crypto_struct.h +++ /dev/null @@ -1,527 +0,0 @@ -/** - * \file psa/crypto_struct.h - * - * \brief PSA cryptography module: Mbed TLS structured type implementations - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. - * - * This file contains the definitions of some data structures with - * implementation-specific definitions. - * - * In implementations with isolation between the application and the - * cryptography module, it is expected that the front-end and the back-end - * would have different versions of this file. - * - *

Design notes about multipart operation structures

- * - * For multipart operations without driver delegation support, each multipart - * operation structure contains a `psa_algorithm_t alg` field which indicates - * which specific algorithm the structure is for. When the structure is not in - * use, `alg` is 0. Most of the structure consists of a union which is - * discriminated by `alg`. - * - * For multipart operations with driver delegation support, each multipart - * operation structure contains an `unsigned int id` field indicating which - * driver got assigned to do the operation. When the structure is not in use, - * 'id' is 0. The structure contains also a driver context which is the union - * of the contexts of all drivers able to handle the type of multipart - * operation. - * - * Note that when `alg` or `id` is 0, the content of other fields is undefined. - * In particular, it is not guaranteed that a freshly-initialized structure - * is all-zero: we initialize structures to something like `{0, 0}`, which - * is only guaranteed to initializes the first member of the union; - * GCC and Clang initialize the whole structure to 0 (at the time of writing), - * but MSVC and CompCert don't. - * - * In Mbed TLS, multipart operation structures live independently from - * the key. This allows Mbed TLS to free the key objects when destroying - * a key slot. If a multipart operation needs to remember the key after - * the setup function returns, the operation structure needs to contain a - * copy of the key. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_STRUCT_H -#define PSA_CRYPTO_STRUCT_H -#include "mbedtls/private_access.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Include the build-time configuration information header. Here, we do not - * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which - * is basically just an alias to it. This is to ease the maintenance of the - * TF-PSA-Crypto repository which has a different build system and - * configuration. - */ -#include "psa/build_info.h" - -/* Include the context definition for the compiled-in drivers for the primitive - * algorithms. */ -#include "psa/crypto_driver_contexts_primitives.h" - -struct psa_hash_operation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_driver_wrappers.h. - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. the driver context is not active, in use). */ - unsigned int MBEDTLS_PRIVATE(id); - psa_driver_hash_context_t MBEDTLS_PRIVATE(ctx); -#endif -}; -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_HASH_OPERATION_INIT { 0 } -#else -#define PSA_HASH_OPERATION_INIT { 0, { 0 } } -#endif -static inline struct psa_hash_operation_s psa_hash_operation_init(void) -{ - const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT; - return v; -} - -struct psa_cipher_operation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_crypto_driver_wrappers.h - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. none of the driver contexts are active). */ - unsigned int MBEDTLS_PRIVATE(id); - - unsigned int MBEDTLS_PRIVATE(iv_required) : 1; - unsigned int MBEDTLS_PRIVATE(iv_set) : 1; - - uint8_t MBEDTLS_PRIVATE(default_iv_length); - - psa_driver_cipher_context_t MBEDTLS_PRIVATE(ctx); -#endif -}; - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_CIPHER_OPERATION_INIT { 0 } -#else -#define PSA_CIPHER_OPERATION_INIT { 0, 0, 0, 0, { 0 } } -#endif -static inline struct psa_cipher_operation_s psa_cipher_operation_init(void) -{ - const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; - return v; -} - -/* Include the context definition for the compiled-in drivers for the composite - * algorithms. */ -#include "psa/crypto_driver_contexts_composites.h" - -struct psa_mac_operation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_driver_wrappers.h - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. none of the driver contexts are active). */ - unsigned int MBEDTLS_PRIVATE(id); - uint8_t MBEDTLS_PRIVATE(mac_size); - unsigned int MBEDTLS_PRIVATE(is_sign) : 1; - psa_driver_mac_context_t MBEDTLS_PRIVATE(ctx); -#endif -}; - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_MAC_OPERATION_INIT { 0 } -#else -#define PSA_MAC_OPERATION_INIT { 0, 0, 0, { 0 } } -#endif -static inline struct psa_mac_operation_s psa_mac_operation_init(void) -{ - const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT; - return v; -} - -struct psa_aead_operation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_crypto_driver_wrappers.h - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. none of the driver contexts are active). */ - unsigned int MBEDTLS_PRIVATE(id); - - psa_algorithm_t MBEDTLS_PRIVATE(alg); - psa_key_type_t MBEDTLS_PRIVATE(key_type); - - size_t MBEDTLS_PRIVATE(ad_remaining); - size_t MBEDTLS_PRIVATE(body_remaining); - - unsigned int MBEDTLS_PRIVATE(nonce_set) : 1; - unsigned int MBEDTLS_PRIVATE(lengths_set) : 1; - unsigned int MBEDTLS_PRIVATE(ad_started) : 1; - unsigned int MBEDTLS_PRIVATE(body_started) : 1; - unsigned int MBEDTLS_PRIVATE(is_encrypt) : 1; - - psa_driver_aead_context_t MBEDTLS_PRIVATE(ctx); -#endif -}; - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_AEAD_OPERATION_INIT { 0 } -#else -#define PSA_AEAD_OPERATION_INIT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } } -#endif -static inline struct psa_aead_operation_s psa_aead_operation_init(void) -{ - const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT; - return v; -} - -/* Include the context definition for the compiled-in drivers for the key - * derivation algorithms. */ -#include "psa/crypto_driver_contexts_key_derivation.h" - -struct psa_key_derivation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - psa_algorithm_t MBEDTLS_PRIVATE(alg); - unsigned int MBEDTLS_PRIVATE(can_output_key) : 1; - size_t MBEDTLS_PRIVATE(capacity); - psa_driver_key_derivation_context_t MBEDTLS_PRIVATE(ctx); -#endif -}; - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_KEY_DERIVATION_OPERATION_INIT { 0 } -#else -/* This only zeroes out the first byte in the union, the rest is unspecified. */ -#define PSA_KEY_DERIVATION_OPERATION_INIT { 0, 0, 0, { 0 } } -#endif -static inline struct psa_key_derivation_s psa_key_derivation_operation_init( - void) -{ - const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT; - return v; -} - -struct psa_custom_key_parameters_s { - /* Future versions may add other fields in this structure. */ - uint32_t flags; -}; - -/** The default production parameters for key generation or key derivation. - * - * Calling psa_generate_key_custom() or psa_key_derivation_output_key_custom() - * with `custom=PSA_CUSTOM_KEY_PARAMETERS_INIT` and `custom_data_length=0` is - * equivalent to calling psa_generate_key() or psa_key_derivation_output_key() - * respectively. - */ -#define PSA_CUSTOM_KEY_PARAMETERS_INIT { 0 } - -#ifndef __cplusplus -/* Omitted when compiling in C++, because one of the parameters is a - * pointer to a struct with a flexible array member, and that is not - * standard C++. - * https://github.com/Mbed-TLS/mbedtls/issues/9020 - */ -/* This is a deprecated variant of `struct psa_custom_key_parameters_s`. - * It has exactly the same layout, plus an extra field which is a flexible - * array member. Thus a `const struct psa_key_production_parameters_s *` - * can be passed to any function that reads a - * `const struct psa_custom_key_parameters_s *`. - */ -struct psa_key_production_parameters_s { - uint32_t flags; - uint8_t data[]; -}; - -/** The default production parameters for key generation or key derivation. - * - * Calling psa_generate_key_ext() or psa_key_derivation_output_key_ext() - * with `params=PSA_KEY_PRODUCTION_PARAMETERS_INIT` and - * `params_data_length == 0` is equivalent to - * calling psa_generate_key() or psa_key_derivation_output_key() - * respectively. - */ -#define PSA_KEY_PRODUCTION_PARAMETERS_INIT { 0 } -#endif /* !__cplusplus */ - -struct psa_key_policy_s { - psa_key_usage_t MBEDTLS_PRIVATE(usage); - psa_algorithm_t MBEDTLS_PRIVATE(alg); - psa_algorithm_t MBEDTLS_PRIVATE(alg2); -}; -typedef struct psa_key_policy_s psa_key_policy_t; - -#define PSA_KEY_POLICY_INIT { 0, 0, 0 } -static inline struct psa_key_policy_s psa_key_policy_init(void) -{ - const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT; - return v; -} - -/* The type used internally for key sizes. - * Public interfaces use size_t, but internally we use a smaller type. */ -typedef uint16_t psa_key_bits_t; -/* The maximum value of the type used to represent bit-sizes. - * This is used to mark an invalid key size. */ -#define PSA_KEY_BITS_TOO_LARGE ((psa_key_bits_t) -1) -/* The maximum size of a key in bits. - * Currently defined as the maximum that can be represented, rounded down - * to a whole number of bytes. - * This is an uncast value so that it can be used in preprocessor - * conditionals. */ -#define PSA_MAX_KEY_BITS 0xfff8 - -struct psa_key_attributes_s { -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); - int MBEDTLS_PRIVATE(has_slot_number); -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - psa_key_type_t MBEDTLS_PRIVATE(type); - psa_key_bits_t MBEDTLS_PRIVATE(bits); - psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime); - psa_key_policy_t MBEDTLS_PRIVATE(policy); - /* This type has a different layout in the client view wrt the - * service view of the key id, i.e. in service view usually is - * expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined - * thus adding an owner field to the standard psa_key_id_t. For - * implementations with client/service separation, this means the - * object will be marshalled through a transport channel and - * interpreted differently at each side of the transport. Placing - * it at the end of structures allows to interpret the structure - * at the client without reorganizing the memory layout of the - * struct - */ - mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id); -}; - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, 0, -#else -#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER -#endif -#define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \ - PSA_KEY_TYPE_NONE, 0, \ - PSA_KEY_LIFETIME_VOLATILE, \ - PSA_KEY_POLICY_INIT, \ - MBEDTLS_SVC_KEY_ID_INIT } - -static inline struct psa_key_attributes_s psa_key_attributes_init(void) -{ - const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT; - return v; -} - -static inline void psa_set_key_id(psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t key) -{ - psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(lifetime); - - attributes->MBEDTLS_PRIVATE(id) = key; - - if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { - attributes->MBEDTLS_PRIVATE(lifetime) = - PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( - PSA_KEY_LIFETIME_PERSISTENT, - PSA_KEY_LIFETIME_GET_LOCATION(lifetime)); - } -} - -static inline mbedtls_svc_key_id_t psa_get_key_id( - const psa_key_attributes_t *attributes) -{ - return attributes->MBEDTLS_PRIVATE(id); -} - -#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -static inline void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes, - mbedtls_key_owner_id_t owner) -{ - attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner; -} -#endif - -static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, - psa_key_lifetime_t lifetime) -{ - attributes->MBEDTLS_PRIVATE(lifetime) = lifetime; - if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { -#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0; -#else - attributes->MBEDTLS_PRIVATE(id) = 0; -#endif - } -} - -static inline psa_key_lifetime_t psa_get_key_lifetime( - const psa_key_attributes_t *attributes) -{ - return attributes->MBEDTLS_PRIVATE(lifetime); -} - -static inline void psa_extend_key_usage_flags(psa_key_usage_t *usage_flags) -{ - if (*usage_flags & PSA_KEY_USAGE_SIGN_HASH) { - *usage_flags |= PSA_KEY_USAGE_SIGN_MESSAGE; - } - - if (*usage_flags & PSA_KEY_USAGE_VERIFY_HASH) { - *usage_flags |= PSA_KEY_USAGE_VERIFY_MESSAGE; - } -} - -static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes, - psa_key_usage_t usage_flags) -{ - psa_extend_key_usage_flags(&usage_flags); - attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags; -} - -static inline psa_key_usage_t psa_get_key_usage_flags( - const psa_key_attributes_t *attributes) -{ - return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage); -} - -static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes, - psa_algorithm_t alg) -{ - attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg; -} - -static inline psa_algorithm_t psa_get_key_algorithm( - const psa_key_attributes_t *attributes) -{ - return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg); -} - -static inline void psa_set_key_type(psa_key_attributes_t *attributes, - psa_key_type_t type) -{ - attributes->MBEDTLS_PRIVATE(type) = type; -} - -static inline psa_key_type_t psa_get_key_type( - const psa_key_attributes_t *attributes) -{ - return attributes->MBEDTLS_PRIVATE(type); -} - -static inline void psa_set_key_bits(psa_key_attributes_t *attributes, - size_t bits) -{ - if (bits > PSA_MAX_KEY_BITS) { - attributes->MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE; - } else { - attributes->MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits; - } -} - -static inline size_t psa_get_key_bits( - const psa_key_attributes_t *attributes) -{ - return attributes->MBEDTLS_PRIVATE(bits); -} - -/** - * \brief The context for PSA interruptible hash signing. - */ -struct psa_sign_hash_interruptible_operation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_crypto_driver_wrappers.h - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. none of the driver contexts are active). */ - unsigned int MBEDTLS_PRIVATE(id); - - psa_driver_sign_hash_interruptible_context_t MBEDTLS_PRIVATE(ctx); - - unsigned int MBEDTLS_PRIVATE(error_occurred) : 1; - - uint32_t MBEDTLS_PRIVATE(num_ops); -#endif -}; - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 } -#else -#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 } -#endif - -static inline struct psa_sign_hash_interruptible_operation_s -psa_sign_hash_interruptible_operation_init(void) -{ - const struct psa_sign_hash_interruptible_operation_s v = - PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT; - - return v; -} - -/** - * \brief The context for PSA interruptible hash verification. - */ -struct psa_verify_hash_interruptible_operation_s { -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_psa_client_handle_t handle; -#else - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_crypto_driver_wrappers.h - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. none of the driver contexts are active). */ - unsigned int MBEDTLS_PRIVATE(id); - - psa_driver_verify_hash_interruptible_context_t MBEDTLS_PRIVATE(ctx); - - unsigned int MBEDTLS_PRIVATE(error_occurred) : 1; - - uint32_t MBEDTLS_PRIVATE(num_ops); -#endif -}; - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) -#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 } -#else -#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 } -#endif - -static inline struct psa_verify_hash_interruptible_operation_s -psa_verify_hash_interruptible_operation_init(void) -{ - const struct psa_verify_hash_interruptible_operation_s v = - PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT; - - return v; -} - -#ifdef __cplusplus -} -#endif - -#endif /* PSA_CRYPTO_STRUCT_H */ diff --git a/vendor/mbedtls/include/psa/crypto_types.h b/vendor/mbedtls/include/psa/crypto_types.h deleted file mode 100644 index f831486f4..000000000 --- a/vendor/mbedtls/include/psa/crypto_types.h +++ /dev/null @@ -1,508 +0,0 @@ -/** - * \file psa/crypto_types.h - * - * \brief PSA cryptography module: type aliases. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. Drivers must include the appropriate driver - * header file. - * - * This file contains portable definitions of integral types for properties - * of cryptographic keys, designations of cryptographic algorithms, and - * error codes returned by the library. - * - * This header file does not declare any function. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_TYPES_H -#define PSA_CRYPTO_TYPES_H - -/* - * Include the build-time configuration information header. Here, we do not - * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which - * is basically just an alias to it. This is to ease the maintenance of the - * TF-PSA-Crypto repository which has a different build system and - * configuration. - */ -#include "psa/build_info.h" - -/* Define the MBEDTLS_PRIVATE macro. */ -#include "mbedtls/private_access.h" - -#if defined(MBEDTLS_PSA_CRYPTO_PLATFORM_FILE) -#include MBEDTLS_PSA_CRYPTO_PLATFORM_FILE -#else -#include "crypto_platform.h" -#endif - -#include - -/** \defgroup error Error codes - * @{ - */ - -/** - * \brief Function return status. - * - * This is either #PSA_SUCCESS (which is zero), indicating success, - * or a small negative value indicating that an error occurred. Errors are - * encoded as one of the \c PSA_ERROR_xxx values defined here. */ -/* If #PSA_SUCCESS is already defined, it means that #psa_status_t - * is also defined in an external header, so prevent its multiple - * definition. - */ -#ifndef PSA_SUCCESS -typedef int32_t psa_status_t; -#endif - -/**@}*/ - -/** \defgroup crypto_types Key and algorithm types - * @{ - */ - -/** \brief Encoding of a key type. - * - * Values of this type are generally constructed by macros called - * `PSA_KEY_TYPE_xxx`. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint16_t psa_key_type_t; - -/** The type of PSA elliptic curve family identifiers. - * - * Values of this type are generally constructed by macros called - * `PSA_ECC_FAMILY_xxx`. - * - * The curve identifier is required to create an ECC key using the - * PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY() - * macros. - * - * Values defined by this standard will never be in the range 0x80-0xff. - * Vendors who define additional families must use an encoding in this range. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint8_t psa_ecc_family_t; - -/** The type of PSA Diffie-Hellman group family identifiers. - * - * Values of this type are generally constructed by macros called - * `PSA_DH_FAMILY_xxx`. - * - * The group identifier is required to create a Diffie-Hellman key using the - * PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY() - * macros. - * - * Values defined by this standard will never be in the range 0x80-0xff. - * Vendors who define additional families must use an encoding in this range. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint8_t psa_dh_family_t; - -/** \brief Encoding of a cryptographic algorithm. - * - * Values of this type are generally constructed by macros called - * `PSA_ALG_xxx`. - * - * For algorithms that can be applied to multiple key types, this type - * does not encode the key type. For example, for symmetric ciphers - * based on a block cipher, #psa_algorithm_t encodes the block cipher - * mode and the padding mode while the block cipher itself is encoded - * via #psa_key_type_t. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint32_t psa_algorithm_t; - -/**@}*/ - -/** \defgroup key_lifetimes Key lifetimes - * @{ - */ - -/** Encoding of key lifetimes. - * - * The lifetime of a key indicates where it is stored and what system actions - * may create and destroy it. - * - * Lifetime values have the following structure: - * - Bits 0-7 (#PSA_KEY_LIFETIME_GET_PERSISTENCE(\c lifetime)): - * persistence level. This value indicates what device management - * actions can cause it to be destroyed. In particular, it indicates - * whether the key is _volatile_ or _persistent_. - * See ::psa_key_persistence_t for more information. - * - Bits 8-31 (#PSA_KEY_LIFETIME_GET_LOCATION(\c lifetime)): - * location indicator. This value indicates which part of the system - * has access to the key material and can perform operations using the key. - * See ::psa_key_location_t for more information. - * - * Volatile keys are automatically destroyed when the application instance - * terminates or on a power reset of the device. Persistent keys are - * preserved until the application explicitly destroys them or until an - * integration-specific device management event occurs (for example, - * a factory reset). - * - * Persistent keys have a key identifier of type #mbedtls_svc_key_id_t. - * This identifier remains valid throughout the lifetime of the key, - * even if the application instance that created the key terminates. - * The application can call psa_open_key() to open a persistent key that - * it created previously. - * - * The default lifetime of a key is #PSA_KEY_LIFETIME_VOLATILE. The lifetime - * #PSA_KEY_LIFETIME_PERSISTENT is supported if persistent storage is - * available. Other lifetime values may be supported depending on the - * library configuration. - * - * Values of this type are generally constructed by macros called - * `PSA_KEY_LIFETIME_xxx`. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint32_t psa_key_lifetime_t; - -/** Encoding of key persistence levels. - * - * What distinguishes different persistence levels is what device management - * events may cause keys to be destroyed. _Volatile_ keys are destroyed - * by a power reset. Persistent keys may be destroyed by events such as - * a transfer of ownership or a factory reset. What management events - * actually affect persistent keys at different levels is outside the - * scope of the PSA Cryptography specification. - * - * The PSA Cryptography specification defines the following values of - * persistence levels: - * - \c 0 = #PSA_KEY_PERSISTENCE_VOLATILE: volatile key. - * A volatile key is automatically destroyed by the implementation when - * the application instance terminates. In particular, a volatile key - * is automatically destroyed on a power reset of the device. - * - \c 1 = #PSA_KEY_PERSISTENCE_DEFAULT: - * persistent key with a default lifetime. - * - \c 2-254: currently not supported by Mbed TLS. - * - \c 255 = #PSA_KEY_PERSISTENCE_READ_ONLY: - * read-only or write-once key. - * A key with this persistence level cannot be destroyed. - * Mbed TLS does not currently offer a way to create such keys, but - * integrations of Mbed TLS can use it for built-in keys that the - * application cannot modify (for example, a hardware unique key (HUK)). - * - * \note Key persistence levels are 8-bit values. Key management - * interfaces operate on lifetimes (type ::psa_key_lifetime_t) which - * encode the persistence as the lower 8 bits of a 32-bit value. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint8_t psa_key_persistence_t; - -/** Encoding of key location indicators. - * - * If an integration of Mbed TLS can make calls to external - * cryptoprocessors such as secure elements, the location of a key - * indicates which secure element performs the operations on the key. - * Depending on the design of the secure element, the key - * material may be stored either in the secure element, or - * in wrapped (encrypted) form alongside the key metadata in the - * primary local storage. - * - * The PSA Cryptography API specification defines the following values of - * location indicators: - * - \c 0: primary local storage. - * This location is always available. - * The primary local storage is typically the same storage area that - * contains the key metadata. - * - \c 1: primary secure element. - * Integrations of Mbed TLS should support this value if there is a secure - * element attached to the operating environment. - * As a guideline, secure elements may provide higher resistance against - * side channel and physical attacks than the primary local storage, but may - * have restrictions on supported key types, sizes, policies and operations - * and may have different performance characteristics. - * - \c 2-0x7fffff: other locations defined by a PSA specification. - * The PSA Cryptography API does not currently assign any meaning to these - * locations, but future versions of that specification or other PSA - * specifications may do so. - * - \c 0x800000-0xffffff: vendor-defined locations. - * No PSA specification will assign a meaning to locations in this range. - * - * \note Key location indicators are 24-bit values. Key management - * interfaces operate on lifetimes (type ::psa_key_lifetime_t) which - * encode the location as the upper 24 bits of a 32-bit value. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint32_t psa_key_location_t; - -/** Encoding of identifiers of persistent keys. - * - * - Applications may freely choose key identifiers in the range - * #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX. - * - The implementation may define additional key identifiers in the range - * #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX. - * - 0 is reserved as an invalid key identifier. - * - Key identifiers outside these ranges are reserved for future use. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to how values are allocated must require careful - * consideration to allow backward compatibility. - */ -typedef uint32_t psa_key_id_t; - -/** Encoding of key identifiers as seen inside the PSA Crypto implementation. - * - * When PSA Crypto is built as a library inside an application, this type - * is identical to #psa_key_id_t. When PSA Crypto is built as a service - * that can store keys on behalf of multiple clients, this type - * encodes the #psa_key_id_t value seen by each client application as - * well as extra information that identifies the client that owns - * the key. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) -typedef psa_key_id_t mbedtls_svc_key_id_t; - -#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ -/* Implementation-specific: The Mbed TLS library can be built as - * part of a multi-client service that exposes the PSA Cryptography API in each - * client and encodes the client identity in the key identifier argument of - * functions such as psa_open_key(). - */ -typedef struct { - psa_key_id_t MBEDTLS_PRIVATE(key_id); - mbedtls_key_owner_id_t MBEDTLS_PRIVATE(owner); -} mbedtls_svc_key_id_t; - -#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ - -/**@}*/ - -/** \defgroup policy Key policies - * @{ - */ - -/** \brief Encoding of permitted usage on a key. - * - * Values of this type are generally constructed as bitwise-ors of macros - * called `PSA_KEY_USAGE_xxx`. - * - * \note Values of this type are encoded in the persistent key store. - * Any changes to existing values will require bumping the storage - * format version and providing a translation when reading the old - * format. - */ -typedef uint32_t psa_key_usage_t; - -/**@}*/ - -/** \defgroup attributes Key attributes - * @{ - */ - -/** The type of a structure containing key attributes. - * - * This is an opaque structure that can represent the metadata of a key - * object. Metadata that can be stored in attributes includes: - * - The location of the key in storage, indicated by its key identifier - * and its lifetime. - * - The key's policy, comprising usage flags and a specification of - * the permitted algorithm(s). - * - Information about the key itself: the key type and its size. - * - Additional implementation-defined attributes. - * - * The actual key material is not considered an attribute of a key. - * Key attributes do not contain information that is generally considered - * highly confidential. - * - * An attribute structure works like a simple data structure where each function - * `psa_set_key_xxx` sets a field and the corresponding function - * `psa_get_key_xxx` retrieves the value of the corresponding field. - * However, a future version of the library may report values that are - * equivalent to the original one, but have a different encoding. Invalid - * values may be mapped to different, also invalid values. - * - * An attribute structure may contain references to auxiliary resources, - * for example pointers to allocated memory or indirect references to - * pre-calculated values. In order to free such resources, the application - * must call psa_reset_key_attributes(). As an exception, calling - * psa_reset_key_attributes() on an attribute structure is optional if - * the structure has only been modified by the following functions - * since it was initialized or last reset with psa_reset_key_attributes(): - * - psa_set_key_id() - * - psa_set_key_lifetime() - * - psa_set_key_type() - * - psa_set_key_bits() - * - psa_set_key_usage_flags() - * - psa_set_key_algorithm() - * - * Before calling any function on a key attribute structure, the application - * must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_key_attributes_t attributes; - * memset(&attributes, 0, sizeof(attributes)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_key_attributes_t attributes = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT, - * for example: - * \code - * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - * \endcode - * - Assign the result of the function psa_key_attributes_init() - * to the structure, for example: - * \code - * psa_key_attributes_t attributes; - * attributes = psa_key_attributes_init(); - * \endcode - * - * A freshly initialized attribute structure contains the following - * values: - * - * - lifetime: #PSA_KEY_LIFETIME_VOLATILE. - * - key identifier: 0 (which is not a valid key identifier). - * - type: \c 0 (meaning that the type is unspecified). - * - key size: \c 0 (meaning that the size is unspecified). - * - usage flags: \c 0 (which allows no usage except exporting a public key). - * - algorithm: \c 0 (which allows no cryptographic usage, but allows - * exporting). - * - * A typical sequence to create a key is as follows: - * -# Create and initialize an attribute structure. - * -# If the key is persistent, call psa_set_key_id(). - * Also call psa_set_key_lifetime() to place the key in a non-default - * location. - * -# Set the key policy with psa_set_key_usage_flags() and - * psa_set_key_algorithm(). - * -# Set the key type with psa_set_key_type(). - * Skip this step if copying an existing key with psa_copy_key(). - * -# When generating a random key with psa_generate_key() or deriving a key - * with psa_key_derivation_output_key(), set the desired key size with - * psa_set_key_bits(). - * -# Call a key creation function: psa_import_key(), psa_generate_key(), - * psa_key_derivation_output_key() or psa_copy_key(). This function reads - * the attribute structure, creates a key with these attributes, and - * outputs a key identifier to the newly created key. - * -# The attribute structure is now no longer necessary. - * You may call psa_reset_key_attributes(), although this is optional - * with the workflow presented here because the attributes currently - * defined in this specification do not require any additional resources - * beyond the structure itself. - * - * A typical sequence to query a key's attributes is as follows: - * -# Call psa_get_key_attributes(). - * -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that - * you are interested in. - * -# Call psa_reset_key_attributes() to free any resources that may be - * used by the attribute structure. - * - * Once a key has been created, it is impossible to change its attributes. - */ -typedef struct psa_key_attributes_s psa_key_attributes_t; - - -#ifndef __DOXYGEN_ONLY__ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -/* Mbed TLS defines this type in crypto_types.h because it is also - * visible to applications through an implementation-specific extension. - * For the PSA Cryptography specification, this type is only visible - * via crypto_se_driver.h. */ -typedef uint64_t psa_key_slot_number_t; -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ -#endif /* !__DOXYGEN_ONLY__ */ - -/**@}*/ - -/** \defgroup derivation Key derivation - * @{ - */ - -/** \brief Encoding of the step of a key derivation. - * - * Values of this type are generally constructed by macros called - * `PSA_KEY_DERIVATION_INPUT_xxx`. - */ -typedef uint16_t psa_key_derivation_step_t; - -/** \brief Custom parameters for key generation or key derivation. - * - * This is a structure type with at least the following field: - * - * - \c flags: an unsigned integer type. 0 for the default production parameters. - * - * Functions that take such a structure as input also take an associated - * input buffer \c custom_data of length \c custom_data_length. - * - * The interpretation of this structure and the associated \c custom_data - * parameter depend on the type of the created key. - * - * - #PSA_KEY_TYPE_RSA_KEY_PAIR: - * - \c flags: must be 0. - * - \c custom_data: the public exponent, in little-endian order. - * This must be an odd integer and must not be 1. - * Implementations must support 65537, should support 3 and may - * support other values. - * When not using a driver, Mbed TLS supports values up to \c INT_MAX. - * If this is empty, the default value 65537 is used. - * - Other key types: reserved for future use. \c flags must be 0. - */ -typedef struct psa_custom_key_parameters_s psa_custom_key_parameters_t; - -/** \brief Custom parameters for key generation or key derivation. - * - * This is a structure type with at least the following fields: - * - * - \c flags: an unsigned integer type. 0 for the default production parameters. - * - \c data: a flexible array of bytes. - * - * The interpretation of this structure depend on the type of the - * created key. - * - * - #PSA_KEY_TYPE_RSA_KEY_PAIR: - * - \c flags: must be 0. - * - \c data: the public exponent, in little-endian order. - * This must be an odd integer and must not be 1. - * Implementations must support 65537, should support 3 and may - * support other values. - * When not using a driver, Mbed TLS supports values up to \c INT_MAX. - * If this is empty or if the custom production parameters are omitted - * altogether, the default value 65537 is used. - * - Other key types: reserved for future use. \c flags must be 0. - * - */ -typedef struct psa_key_production_parameters_s psa_key_production_parameters_t; - -/**@}*/ - -#endif /* PSA_CRYPTO_TYPES_H */ diff --git a/vendor/mbedtls/include/psa/crypto_values.h b/vendor/mbedtls/include/psa/crypto_values.h deleted file mode 100644 index 1d678dbfc..000000000 --- a/vendor/mbedtls/include/psa/crypto_values.h +++ /dev/null @@ -1,2783 +0,0 @@ -/** - * \file psa/crypto_values.h - * - * \brief PSA cryptography module: macros to build and analyze integer values. - * - * \note This file may not be included directly. Applications must - * include psa/crypto.h. Drivers must include the appropriate driver - * header file. - * - * This file contains portable definitions of macros to build and analyze - * values of integral types that encode properties of cryptographic keys, - * designations of cryptographic algorithms, and error codes returned by - * the library. - * - * Note that many of the constants defined in this file are embedded in - * the persistent key store, as part of key metadata (including usage - * policies). As a consequence, they must not be changed (unless the storage - * format version changes). - * - * This header file only defines preprocessor macros. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_VALUES_H -#define PSA_CRYPTO_VALUES_H -#include "mbedtls/private_access.h" - -/** \defgroup error Error codes - * @{ - */ - -/* PSA error codes */ - -/* Error codes are standardized across PSA domains (framework, crypto, storage, - * etc.). Do not change the values in this section or even the expansions - * of each macro: it must be possible to `#include` both this header - * and some other PSA component's headers in the same C source, - * which will lead to duplicate definitions of the `PSA_SUCCESS` and - * `PSA_ERROR_xxx` macros, which is ok if and only if the macros expand - * to the same sequence of tokens. - * - * If you must add a new - * value, check with the Arm PSA framework group to pick one that other - * domains aren't already using. */ - -/* Tell uncrustify not to touch the constant definitions, otherwise - * it might change the spacing to something that is not PSA-compliant - * (e.g. adding a space after casts). - * - * *INDENT-OFF* - */ - -/** The action was completed successfully. */ -#define PSA_SUCCESS ((psa_status_t)0) - -/** An error occurred that does not correspond to any defined - * failure cause. - * - * Implementations may use this error code if none of the other standard - * error codes are applicable. */ -#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132) - -/** The requested operation or a parameter is not supported - * by this implementation. - * - * Implementations should return this error code when an enumeration - * parameter such as a key type, algorithm, etc. is not recognized. - * If a combination of parameters is recognized and identified as - * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */ -#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134) - -/** The requested action is denied by a policy. - * - * Implementations should return this error code when the parameters - * are recognized as valid and supported, and a policy explicitly - * denies the requested operation. - * - * If a subset of the parameters of a function call identify a - * forbidden operation, and another subset of the parameters are - * not valid or not supported, it is unspecified whether the function - * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or - * #PSA_ERROR_INVALID_ARGUMENT. */ -#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133) - -/** An output buffer is too small. - * - * Applications can call the \c PSA_xxx_SIZE macro listed in the function - * description to determine a sufficient buffer size. - * - * Implementations should preferably return this error code only - * in cases when performing the operation with a larger output - * buffer would succeed. However implementations may return this - * error if a function has invalid or unsupported parameters in addition - * to the parameters that determine the necessary output buffer size. */ -#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138) - -/** Asking for an item that already exists - * - * Implementations should return this error, when attempting - * to write an item (like a key) that already exists. */ -#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139) - -/** Asking for an item that doesn't exist - * - * Implementations should return this error, if a requested item (like - * a key) does not exist. */ -#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140) - -/** The requested action cannot be performed in the current state. - * - * Multipart operations return this error when one of the - * functions is called out of sequence. Refer to the function - * descriptions for permitted sequencing of functions. - * - * Implementations shall not return this error code to indicate - * that a key either exists or not, - * but shall instead return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST - * as applicable. - * - * Implementations shall not return this error code to indicate that a - * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE - * instead. */ -#define PSA_ERROR_BAD_STATE ((psa_status_t)-137) - -/** The parameters passed to the function are invalid. - * - * Implementations may return this error any time a parameter or - * combination of parameters are recognized as invalid. - * - * Implementations shall not return this error code to indicate that a - * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE - * instead. - */ -#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135) - -/** There is not enough runtime memory. - * - * If the action is carried out across multiple security realms, this - * error can refer to available memory in any of the security realms. */ -#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141) - -/** There is not enough persistent storage. - * - * Functions that modify the key storage return this error code if - * there is insufficient storage space on the host media. In addition, - * many functions that do not otherwise access storage may return this - * error code if the implementation requires a mandatory log entry for - * the requested action and the log storage space is full. */ -#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142) - -/** There was a communication failure inside the implementation. - * - * This can indicate a communication failure between the application - * and an external cryptoprocessor or between the cryptoprocessor and - * an external volatile or persistent memory. A communication failure - * may be transient or permanent depending on the cause. - * - * \warning If a function returns this error, it is undetermined - * whether the requested action has completed or not. Implementations - * should return #PSA_SUCCESS on successful completion whenever - * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE - * if the requested action was completed successfully in an external - * cryptoprocessor but there was a breakdown of communication before - * the cryptoprocessor could report the status to the application. - */ -#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145) - -/** There was a storage failure that may have led to data loss. - * - * This error indicates that some persistent storage is corrupted. - * It should not be used for a corruption of volatile memory - * (use #PSA_ERROR_CORRUPTION_DETECTED), for a communication error - * between the cryptoprocessor and its external storage (use - * #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is - * in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE). - * - * Note that a storage failure does not indicate that any data that was - * previously read is invalid. However this previously read data may no - * longer be readable from storage. - * - * When a storage failure occurs, it is no longer possible to ensure - * the global integrity of the keystore. Depending on the global - * integrity guarantees offered by the implementation, access to other - * data may or may not fail even if the data is still readable but - * its integrity cannot be guaranteed. - * - * Implementations should only use this error code to report a - * permanent storage corruption. However application writers should - * keep in mind that transient errors while reading the storage may be - * reported using this error code. */ -#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146) - -/** A hardware failure was detected. - * - * A hardware failure may be transient or permanent depending on the - * cause. */ -#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147) - -/** A tampering attempt was detected. - * - * If an application receives this error code, there is no guarantee - * that previously accessed or computed data was correct and remains - * confidential. Applications should not perform any security function - * and should enter a safe failure state. - * - * Implementations may return this error code if they detect an invalid - * state that cannot happen during normal operation and that indicates - * that the implementation's security guarantees no longer hold. Depending - * on the implementation architecture and on its security and safety goals, - * the implementation may forcibly terminate the application. - * - * This error code is intended as a last resort when a security breach - * is detected and it is unsure whether the keystore data is still - * protected. Implementations shall only return this error code - * to report an alarm from a tampering detector, to indicate that - * the confidentiality of stored data can no longer be guaranteed, - * or to indicate that the integrity of previously returned data is now - * considered compromised. Implementations shall not use this error code - * to indicate a hardware failure that merely makes it impossible to - * perform the requested operation (use #PSA_ERROR_COMMUNICATION_FAILURE, - * #PSA_ERROR_STORAGE_FAILURE, #PSA_ERROR_HARDWARE_FAILURE, - * #PSA_ERROR_INSUFFICIENT_ENTROPY or other applicable error code - * instead). - * - * This error indicates an attack against the application. Implementations - * shall not return this error code as a consequence of the behavior of - * the application itself. */ -#define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151) - -/** There is not enough entropy to generate random data needed - * for the requested action. - * - * This error indicates a failure of a hardware random generator. - * Application writers should note that this error can be returned not - * only by functions whose purpose is to generate random data, such - * as key, IV or nonce generation, but also by functions that execute - * an algorithm with a randomized result, as well as functions that - * use randomization of intermediate computations as a countermeasure - * to certain attacks. - * - * Implementations should avoid returning this error after psa_crypto_init() - * has succeeded. Implementations should generate sufficient - * entropy during initialization and subsequently use a cryptographically - * secure pseudorandom generator (PRNG). However implementations may return - * this error at any time if a policy requires the PRNG to be reseeded - * during normal operation. */ -#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)-148) - -/** The signature, MAC or hash is incorrect. - * - * Verification functions return this error if the verification - * calculations completed successfully, and the value to be verified - * was determined to be incorrect. - * - * If the value to verify has an invalid size, implementations may return - * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */ -#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149) - -/** The decrypted padding is incorrect. - * - * \warning In some protocols, when decrypting data, it is essential that - * the behavior of the application does not depend on whether the padding - * is correct, down to precise timing. Applications should prefer - * protocols that use authenticated encryption rather than plain - * encryption. If the application must perform a decryption of - * unauthenticated data, the application writer should take care not - * to reveal whether the padding is invalid. - * - * Implementations should strive to make valid and invalid padding - * as close as possible to indistinguishable to an external observer. - * In particular, the timing of a decryption operation should not - * depend on the validity of the padding. */ -#define PSA_ERROR_INVALID_PADDING ((psa_status_t)-150) - -/** Return this error when there's insufficient data when attempting - * to read from a resource. */ -#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143) - -/** This can be returned if a function can no longer operate correctly. - * For example, if an essential initialization operation failed or - * a mutex operation failed. */ -#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144) - -/** The key identifier is not valid. See also :ref:\`key-handles\`. - */ -#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) - -/** Stored data has been corrupted. - * - * This error indicates that some persistent storage has suffered corruption. - * It does not indicate the following situations, which have specific error - * codes: - * - * - A corruption of volatile memory - use #PSA_ERROR_CORRUPTION_DETECTED. - * - A communication error between the cryptoprocessor and its external - * storage - use #PSA_ERROR_COMMUNICATION_FAILURE. - * - When the storage is in a valid state but is full - use - * #PSA_ERROR_INSUFFICIENT_STORAGE. - * - When the storage fails for other reasons - use - * #PSA_ERROR_STORAGE_FAILURE. - * - When the stored data is not valid - use #PSA_ERROR_DATA_INVALID. - * - * \note A storage corruption does not indicate that any data that was - * previously read is invalid. However this previously read data might no - * longer be readable from storage. - * - * When a storage failure occurs, it is no longer possible to ensure the - * global integrity of the keystore. - */ -#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152) - -/** Data read from storage is not valid for the implementation. - * - * This error indicates that some data read from storage does not have a valid - * format. It does not indicate the following situations, which have specific - * error codes: - * - * - When the storage or stored data is corrupted - use #PSA_ERROR_DATA_CORRUPT - * - When the storage fails for other reasons - use #PSA_ERROR_STORAGE_FAILURE - * - An invalid argument to the API - use #PSA_ERROR_INVALID_ARGUMENT - * - * This error is typically a result of either storage corruption on a - * cleartext storage backend, or an attempt to read data that was - * written by an incompatible version of the library. - */ -#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153) - -/** The function that returns this status is defined as interruptible and - * still has work to do, thus the user should call the function again with the - * same operation context until it either returns #PSA_SUCCESS or any other - * error. This is not an error per se, more a notification of status. - */ -#define PSA_OPERATION_INCOMPLETE ((psa_status_t)-248) - -/* *INDENT-ON* */ - -/**@}*/ - -/** \defgroup crypto_types Key and algorithm types - * @{ - */ - -/* Note that key type values, including ECC family and DH group values, are - * embedded in the persistent key store, as part of key metadata. As a - * consequence, they must not be changed (unless the storage format version - * changes). - */ - -/** An invalid key type value. - * - * Zero is not the encoding of any key type. - */ -#define PSA_KEY_TYPE_NONE ((psa_key_type_t) 0x0000) - -/** Vendor-defined key type flag. - * - * Key types defined by this standard will never have the - * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types - * must use an encoding with the #PSA_KEY_TYPE_VENDOR_FLAG bit set and should - * respect the bitwise structure used by standard encodings whenever practical. - */ -#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t) 0x8000) - -#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t) 0x7000) -#define PSA_KEY_TYPE_CATEGORY_RAW ((psa_key_type_t) 0x1000) -#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t) 0x2000) -#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY ((psa_key_type_t) 0x4000) -#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR ((psa_key_type_t) 0x7000) - -#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR ((psa_key_type_t) 0x3000) - -/** Whether a key type is vendor-defined. - * - * See also #PSA_KEY_TYPE_VENDOR_FLAG. - */ -#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \ - (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0) - -/** Whether a key type is an unstructured array of bytes. - * - * This encompasses both symmetric keys and non-key data. - */ -#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_RAW || \ - ((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC) - -/** Whether a key type is asymmetric: either a key pair or a public key. */ -#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK \ - & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) == \ - PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY) -/** Whether a key type is the public part of a key pair. */ -#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY) -/** Whether a key type is a key pair containing a private part and a public - * part. */ -#define PSA_KEY_TYPE_IS_KEY_PAIR(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR) -/** The key pair type corresponding to a public key type. - * - * You may also pass a key pair type as \p type, it will be left unchanged. - * - * \param type A public key type or key pair type. - * - * \return The corresponding key pair type. - * If \p type is not a public key or a key pair, - * the return value is undefined. - */ -#define PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(type) \ - ((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) -/** The public key type corresponding to a key pair type. - * - * You may also pass a public key type as \p type, it will be left unchanged. - * - * \param type A public key type or key pair type. - * - * \return The corresponding public key type. - * If \p type is not a public key or a key pair, - * the return value is undefined. - */ -#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) \ - ((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) - -/** Raw data. - * - * A "key" of this type cannot be used for any cryptographic operation. - * Applications may use this type to store arbitrary data in the keystore. */ -#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t) 0x1001) - -/** HMAC key. - * - * The key policy determines which underlying hash algorithm the key can be - * used for. - * - * HMAC keys should generally have the same size as the underlying hash. - * This size can be calculated with #PSA_HASH_LENGTH(\c alg) where - * \c alg is the HMAC algorithm or the underlying hash algorithm. */ -#define PSA_KEY_TYPE_HMAC ((psa_key_type_t) 0x1100) - -/** A secret for key derivation. - * - * This key type is for high-entropy secrets only. For low-entropy secrets, - * #PSA_KEY_TYPE_PASSWORD should be used instead. - * - * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_SECRET or - * #PSA_KEY_DERIVATION_INPUT_PASSWORD input of key derivation algorithms. - * - * The key policy determines which key derivation algorithm the key - * can be used for. - */ -#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t) 0x1200) - -/** A low-entropy secret for password hashing or key derivation. - * - * This key type is suitable for passwords and passphrases which are typically - * intended to be memorizable by humans, and have a low entropy relative to - * their size. It can be used for randomly generated or derived keys with - * maximum or near-maximum entropy, but #PSA_KEY_TYPE_DERIVE is more suitable - * for such keys. It is not suitable for passwords with extremely low entropy, - * such as numerical PINs. - * - * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_PASSWORD input of - * key derivation algorithms. Algorithms that accept such an input were - * designed to accept low-entropy secret and are known as password hashing or - * key stretching algorithms. - * - * These keys cannot be used as the #PSA_KEY_DERIVATION_INPUT_SECRET input of - * key derivation algorithms, as the algorithms that take such an input expect - * it to be high-entropy. - * - * The key policy determines which key derivation algorithm the key can be - * used for, among the permissible subset defined above. - */ -#define PSA_KEY_TYPE_PASSWORD ((psa_key_type_t) 0x1203) - -/** A secret value that can be used to verify a password hash. - * - * The key policy determines which key derivation algorithm the key - * can be used for, among the same permissible subset as for - * #PSA_KEY_TYPE_PASSWORD. - */ -#define PSA_KEY_TYPE_PASSWORD_HASH ((psa_key_type_t) 0x1205) - -/** A secret value that can be used in when computing a password hash. - * - * The key policy determines which key derivation algorithm the key - * can be used for, among the subset of algorithms that can use pepper. - */ -#define PSA_KEY_TYPE_PEPPER ((psa_key_type_t) 0x1206) - -/** Key for a cipher, AEAD or MAC algorithm based on the AES block cipher. - * - * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or - * 32 bytes (AES-256). - */ -#define PSA_KEY_TYPE_AES ((psa_key_type_t) 0x2400) - -/** Key for a cipher, AEAD or MAC algorithm based on the - * ARIA block cipher. */ -#define PSA_KEY_TYPE_ARIA ((psa_key_type_t) 0x2406) - -/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES). - * - * The size of the key can be 64 bits (single DES), 128 bits (2-key 3DES) or - * 192 bits (3-key 3DES). - * - * Note that single DES and 2-key 3DES are weak and strongly - * deprecated and should only be used to decrypt legacy data. 3-key 3DES - * is weak and deprecated and should only be used in legacy protocols. - */ -#define PSA_KEY_TYPE_DES ((psa_key_type_t) 0x2301) - -/** Key for a cipher, AEAD or MAC algorithm based on the - * Camellia block cipher. */ -#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t) 0x2403) - -/** Key for the ChaCha20 stream cipher or the Chacha20-Poly1305 AEAD algorithm. - * - * ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539. - * - * \note For ChaCha20 and ChaCha20_Poly1305, Mbed TLS only supports - * 12-byte nonces. - * - * \note For ChaCha20, the initial counter value is 0. To encrypt or decrypt - * with the initial counter value 1, you can process and discard a - * 64-byte block before the real data. - */ -#define PSA_KEY_TYPE_CHACHA20 ((psa_key_type_t) 0x2004) - -/** RSA public key. - * - * The size of an RSA key is the bit size of the modulus. - */ -#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t) 0x4001) -/** RSA key pair (private and public key). - * - * The size of an RSA key is the bit size of the modulus. - */ -#define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t) 0x7001) -/** Whether a key type is an RSA key (pair or public-only). */ -#define PSA_KEY_TYPE_IS_RSA(type) \ - (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY) - -#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4100) -#define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t) 0x7100) -#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t) 0x00ff) -/** Elliptic curve key pair. - * - * The size of an elliptic curve key is the bit size associated with the curve, - * i.e. the bit size of *q* for a curve over a field *Fq*. - * See the documentation of `PSA_ECC_FAMILY_xxx` curve families for details. - * - * \param curve A value of type ::psa_ecc_family_t that - * identifies the ECC curve to be used. - */ -#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \ - (PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve)) -/** Elliptic curve public key. - * - * The size of an elliptic curve public key is the same as the corresponding - * private key (see #PSA_KEY_TYPE_ECC_KEY_PAIR and the documentation of - * `PSA_ECC_FAMILY_xxx` curve families). - * - * \param curve A value of type ::psa_ecc_family_t that - * identifies the ECC curve to be used. - */ -#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \ - (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve)) - -/** Whether a key type is an elliptic curve key (pair or public-only). */ -#define PSA_KEY_TYPE_IS_ECC(type) \ - ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \ - ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE) -/** Whether a key type is an elliptic curve key pair. */ -#define PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type) \ - (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \ - PSA_KEY_TYPE_ECC_KEY_PAIR_BASE) -/** Whether a key type is an elliptic curve public key. */ -#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \ - (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \ - PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE) - -/** Extract the curve from an elliptic curve key type. */ -#define PSA_KEY_TYPE_ECC_GET_FAMILY(type) \ - ((psa_ecc_family_t) (PSA_KEY_TYPE_IS_ECC(type) ? \ - ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \ - 0)) - -/** Check if the curve of given family is Weierstrass elliptic curve. */ -#define PSA_ECC_FAMILY_IS_WEIERSTRASS(family) ((family & 0xc0) == 0) - -/** SEC Koblitz curves over prime fields. - * - * This family comprises the following curves: - * secp192k1, secp224k1, secp256k1. - * They are defined in _Standards for Efficient Cryptography_, - * _SEC 2: Recommended Elliptic Curve Domain Parameters_. - * https://www.secg.org/sec2-v2.pdf - * - * \note For secp224k1, the bit-size is 225 (size of a private value). - * - * \note Mbed TLS only supports secp192k1 and secp256k1. - */ -#define PSA_ECC_FAMILY_SECP_K1 ((psa_ecc_family_t) 0x17) - -/** SEC random curves over prime fields. - * - * This family comprises the following curves: - * secp192r1, secp224r1, secp256r1, secp384r1, secp521r1. - * They are defined in _Standards for Efficient Cryptography_, - * _SEC 2: Recommended Elliptic Curve Domain Parameters_. - * https://www.secg.org/sec2-v2.pdf - */ -#define PSA_ECC_FAMILY_SECP_R1 ((psa_ecc_family_t) 0x12) -/* SECP160R2 (SEC2 v1, obsolete, not supported in Mbed TLS) */ -#define PSA_ECC_FAMILY_SECP_R2 ((psa_ecc_family_t) 0x1b) - -/** SEC Koblitz curves over binary fields. - * - * This family comprises the following curves: - * sect163k1, sect233k1, sect239k1, sect283k1, sect409k1, sect571k1. - * They are defined in _Standards for Efficient Cryptography_, - * _SEC 2: Recommended Elliptic Curve Domain Parameters_. - * https://www.secg.org/sec2-v2.pdf - * - * \note Mbed TLS does not support any curve in this family. - */ -#define PSA_ECC_FAMILY_SECT_K1 ((psa_ecc_family_t) 0x27) - -/** SEC random curves over binary fields. - * - * This family comprises the following curves: - * sect163r1, sect233r1, sect283r1, sect409r1, sect571r1. - * They are defined in _Standards for Efficient Cryptography_, - * _SEC 2: Recommended Elliptic Curve Domain Parameters_. - * https://www.secg.org/sec2-v2.pdf - * - * \note Mbed TLS does not support any curve in this family. - */ -#define PSA_ECC_FAMILY_SECT_R1 ((psa_ecc_family_t) 0x22) - -/** SEC additional random curves over binary fields. - * - * This family comprises the following curve: - * sect163r2. - * It is defined in _Standards for Efficient Cryptography_, - * _SEC 2: Recommended Elliptic Curve Domain Parameters_. - * https://www.secg.org/sec2-v2.pdf - * - * \note Mbed TLS does not support any curve in this family. - */ -#define PSA_ECC_FAMILY_SECT_R2 ((psa_ecc_family_t) 0x2b) - -/** Brainpool P random curves. - * - * This family comprises the following curves: - * brainpoolP160r1, brainpoolP192r1, brainpoolP224r1, brainpoolP256r1, - * brainpoolP320r1, brainpoolP384r1, brainpoolP512r1. - * It is defined in RFC 5639. - * - * \note Mbed TLS only supports the 256-bit, 384-bit and 512-bit curves - * in this family. - */ -#define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30) - -/** Curve25519 and Curve448. - * - * This family comprises the following Montgomery curves: - * - 255-bit: Bernstein et al., - * _Curve25519: new Diffie-Hellman speed records_, LNCS 3958, 2006. - * The algorithm #PSA_ALG_ECDH performs X25519 when used with this curve. - * - 448-bit: Hamburg, - * _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015. - * The algorithm #PSA_ALG_ECDH performs X448 when used with this curve. - */ -#define PSA_ECC_FAMILY_MONTGOMERY ((psa_ecc_family_t) 0x41) - -/** The twisted Edwards curves Ed25519 and Ed448. - * - * These curves are suitable for EdDSA (#PSA_ALG_PURE_EDDSA for both curves, - * #PSA_ALG_ED25519PH for the 255-bit curve, - * #PSA_ALG_ED448PH for the 448-bit curve). - * - * This family comprises the following twisted Edwards curves: - * - 255-bit: Edwards25519, the twisted Edwards curve birationally equivalent - * to Curve25519. - * Bernstein et al., _Twisted Edwards curves_, Africacrypt 2008. - * - 448-bit: Edwards448, the twisted Edwards curve birationally equivalent - * to Curve448. - * Hamburg, _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015. - * - * \note Mbed TLS does not support Edwards curves yet. - */ -#define PSA_ECC_FAMILY_TWISTED_EDWARDS ((psa_ecc_family_t) 0x42) - -#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4200) -#define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t) 0x7200) -#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t) 0x00ff) -/** Diffie-Hellman key pair. - * - * \param group A value of type ::psa_dh_family_t that identifies the - * Diffie-Hellman group to be used. - */ -#define PSA_KEY_TYPE_DH_KEY_PAIR(group) \ - (PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group)) -/** Diffie-Hellman public key. - * - * \param group A value of type ::psa_dh_family_t that identifies the - * Diffie-Hellman group to be used. - */ -#define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \ - (PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group)) - -/** Whether a key type is a Diffie-Hellman key (pair or public-only). */ -#define PSA_KEY_TYPE_IS_DH(type) \ - ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \ - ~PSA_KEY_TYPE_DH_GROUP_MASK) == PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE) -/** Whether a key type is a Diffie-Hellman key pair. */ -#define PSA_KEY_TYPE_IS_DH_KEY_PAIR(type) \ - (((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \ - PSA_KEY_TYPE_DH_KEY_PAIR_BASE) -/** Whether a key type is a Diffie-Hellman public key. */ -#define PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) \ - (((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \ - PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE) - -/** Extract the group from a Diffie-Hellman key type. */ -#define PSA_KEY_TYPE_DH_GET_FAMILY(type) \ - ((psa_dh_family_t) (PSA_KEY_TYPE_IS_DH(type) ? \ - ((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \ - 0)) - -/** Diffie-Hellman groups defined in RFC 7919 Appendix A. - * - * This family includes groups with the following key sizes (in bits): - * 2048, 3072, 4096, 6144, 8192. A given implementation may support - * all of these sizes or only a subset. - */ -#define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03) - -#define PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) \ - (((type) >> 8) & 7) -/** The block size of a block cipher. - * - * \param type A cipher key type (value of type #psa_key_type_t). - * - * \return The block size for a block cipher, or 1 for a stream cipher. - * The return value is undefined if \p type is not a supported - * cipher key type. - * - * \note It is possible to build stream cipher algorithms on top of a block - * cipher, for example CTR mode (#PSA_ALG_CTR). - * This macro only takes the key type into account, so it cannot be - * used to determine the size of the data that #psa_cipher_update() - * might buffer for future processing in general. - * - * \note This macro returns a compile-time constant if its argument is one. - * - * \warning This macro may evaluate its argument multiple times. - */ -#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ - 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \ - 0u) - -/* Note that algorithm values are embedded in the persistent key store, - * as part of key metadata. As a consequence, they must not be changed - * (unless the storage format version changes). - */ - -/** Vendor-defined algorithm flag. - * - * Algorithms defined by this standard will never have the #PSA_ALG_VENDOR_FLAG - * bit set. Vendors who define additional algorithms must use an encoding with - * the #PSA_ALG_VENDOR_FLAG bit set and should respect the bitwise structure - * used by standard encodings whenever practical. - */ -#define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t) 0x80000000) - -#define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t) 0x7f000000) -#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t) 0x02000000) -#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t) 0x03000000) -#define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t) 0x04000000) -#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t) 0x05000000) -#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t) 0x06000000) -#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t) 0x07000000) -#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t) 0x08000000) -#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t) 0x09000000) - -/** Whether an algorithm is vendor-defined. - * - * See also #PSA_ALG_VENDOR_FLAG. - */ -#define PSA_ALG_IS_VENDOR_DEFINED(alg) \ - (((alg) & PSA_ALG_VENDOR_FLAG) != 0) - -/** Whether the specified algorithm is a hash algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a hash algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_HASH(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH) - -/** Whether the specified algorithm is a MAC algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a MAC algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_MAC(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC) - -/** Whether the specified algorithm is a symmetric cipher algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a symmetric cipher algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_CIPHER(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER) - -/** Whether the specified algorithm is an authenticated encryption - * with associated data (AEAD) algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is an AEAD algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_AEAD(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD) - -/** Whether the specified algorithm is an asymmetric signature algorithm, - * also known as public-key signature algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is an asymmetric signature algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_SIGN(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN) - -/** Whether the specified algorithm is an asymmetric encryption algorithm, - * also known as public-key encryption algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is an asymmetric encryption algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION) - -/** Whether the specified algorithm is a key agreement algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a key agreement algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_KEY_AGREEMENT(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT) - -/** Whether the specified algorithm is a key derivation algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a key derivation algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_KEY_DERIVATION(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) - -/** Whether the specified algorithm is a key stretching / password hashing - * algorithm. - * - * A key stretching / password hashing algorithm is a key derivation algorithm - * that is suitable for use with a low-entropy secret such as a password. - * Equivalently, it's a key derivation algorithm that uses a - * #PSA_KEY_DERIVATION_INPUT_PASSWORD input step. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a key stretching / password hashing algorithm, 0 - * otherwise. This macro may return either 0 or 1 if \p alg is not a - * supported algorithm identifier. - */ -#define PSA_ALG_IS_KEY_DERIVATION_STRETCHING(alg) \ - (PSA_ALG_IS_KEY_DERIVATION(alg) && \ - (alg) & PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG) - -/** An invalid algorithm identifier value. */ -/* *INDENT-OFF* (https://github.com/ARM-software/psa-arch-tests/issues/337) */ -#define PSA_ALG_NONE ((psa_algorithm_t)0) -/* *INDENT-ON* */ - -#define PSA_ALG_HASH_MASK ((psa_algorithm_t) 0x000000ff) -/** MD5 */ -#define PSA_ALG_MD5 ((psa_algorithm_t) 0x02000003) -/** PSA_ALG_RIPEMD160 */ -#define PSA_ALG_RIPEMD160 ((psa_algorithm_t) 0x02000004) -/** SHA1 */ -#define PSA_ALG_SHA_1 ((psa_algorithm_t) 0x02000005) -/** SHA2-224 */ -#define PSA_ALG_SHA_224 ((psa_algorithm_t) 0x02000008) -/** SHA2-256 */ -#define PSA_ALG_SHA_256 ((psa_algorithm_t) 0x02000009) -/** SHA2-384 */ -#define PSA_ALG_SHA_384 ((psa_algorithm_t) 0x0200000a) -/** SHA2-512 */ -#define PSA_ALG_SHA_512 ((psa_algorithm_t) 0x0200000b) -/** SHA2-512/224 */ -#define PSA_ALG_SHA_512_224 ((psa_algorithm_t) 0x0200000c) -/** SHA2-512/256 */ -#define PSA_ALG_SHA_512_256 ((psa_algorithm_t) 0x0200000d) -/** SHA3-224 */ -#define PSA_ALG_SHA3_224 ((psa_algorithm_t) 0x02000010) -/** SHA3-256 */ -#define PSA_ALG_SHA3_256 ((psa_algorithm_t) 0x02000011) -/** SHA3-384 */ -#define PSA_ALG_SHA3_384 ((psa_algorithm_t) 0x02000012) -/** SHA3-512 */ -#define PSA_ALG_SHA3_512 ((psa_algorithm_t) 0x02000013) -/** The first 512 bits (64 bytes) of the SHAKE256 output. - * - * This is the prehashing for Ed448ph (see #PSA_ALG_ED448PH). For other - * scenarios where a hash function based on SHA3/SHAKE is desired, SHA3-512 - * has the same output size and a (theoretically) higher security strength. - */ -#define PSA_ALG_SHAKE256_512 ((psa_algorithm_t) 0x02000015) - -/** In a hash-and-sign algorithm policy, allow any hash algorithm. - * - * This value may be used to form the algorithm usage field of a policy - * for a signature algorithm that is parametrized by a hash. The key - * may then be used to perform operations using the same signature - * algorithm parametrized with any supported hash. - * - * That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros: - * - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS, #PSA_ALG_RSA_PSS_ANY_SALT, - * - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA. - * Then you may create and use a key as follows: - * - Set the key usage field using #PSA_ALG_ANY_HASH, for example: - * ``` - * psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); // or VERIFY - * psa_set_key_algorithm(&attributes, PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH)); - * ``` - * - Import or generate key material. - * - Call psa_sign_hash() or psa_verify_hash(), passing - * an algorithm built from `PSA_xxx_SIGNATURE` and a specific hash. Each - * call to sign or verify a message may use a different hash. - * ``` - * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_256), ...); - * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_512), ...); - * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA3_256), ...); - * ``` - * - * This value may not be used to build other algorithms that are - * parametrized over a hash. For any valid use of this macro to build - * an algorithm \c alg, #PSA_ALG_IS_HASH_AND_SIGN(\c alg) is true. - * - * This value may not be used to build an algorithm specification to - * perform an operation. It is only valid to build policies. - */ -#define PSA_ALG_ANY_HASH ((psa_algorithm_t) 0x020000ff) - -#define PSA_ALG_MAC_SUBCATEGORY_MASK ((psa_algorithm_t) 0x00c00000) -#define PSA_ALG_HMAC_BASE ((psa_algorithm_t) 0x03800000) -/** Macro to build an HMAC algorithm. - * - * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding HMAC algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_HMAC(hash_alg) \ - (PSA_ALG_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -#define PSA_ALG_HMAC_GET_HASH(hmac_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is an HMAC algorithm. - * - * HMAC is a family of MAC algorithms that are based on a hash function. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is an HMAC algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_HMAC(alg) \ - (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ - PSA_ALG_HMAC_BASE) - -/* In the encoding of a MAC algorithm, the bits corresponding to - * PSA_ALG_MAC_TRUNCATION_MASK encode the length to which the MAC is - * truncated. As an exception, the value 0 means the untruncated algorithm, - * whatever its length is. The length is encoded in 6 bits, so it can - * reach up to 63; the largest MAC is 64 bytes so its trivial truncation - * to full length is correctly encoded as 0 and any non-trivial truncation - * is correctly encoded as a value between 1 and 63. */ -#define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t) 0x003f0000) -#define PSA_MAC_TRUNCATION_OFFSET 16 - -/* In the encoding of a MAC algorithm, the bit corresponding to - * #PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm - * is a wildcard algorithm. A key with such wildcard algorithm as permitted - * algorithm policy can be used with any algorithm corresponding to the - * same base class and having a (potentially truncated) MAC length greater or - * equal than the one encoded in #PSA_ALG_MAC_TRUNCATION_MASK. */ -#define PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t) 0x00008000) - -/** Macro to build a truncated MAC algorithm. - * - * A truncated MAC algorithm is identical to the corresponding MAC - * algorithm except that the MAC value for the truncated algorithm - * consists of only the first \p mac_length bytes of the MAC value - * for the untruncated algorithm. - * - * \note This macro may allow constructing algorithm identifiers that - * are not valid, either because the specified length is larger - * than the untruncated MAC or because the specified length is - * smaller than permitted by the implementation. - * - * \note It is implementation-defined whether a truncated MAC that - * is truncated to the same length as the MAC of the untruncated - * algorithm is considered identical to the untruncated algorithm - * for policy comparison purposes. - * - * \param mac_alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) - * is true). This may be a truncated or untruncated - * MAC algorithm. - * \param mac_length Desired length of the truncated MAC in bytes. - * This must be at most the full length of the MAC - * and must be at least an implementation-specified - * minimum. The implementation-specified minimum - * shall not be zero. - * - * \return The corresponding MAC algorithm with the specified - * length. - * \return Unspecified if \p mac_alg is not a supported - * MAC algorithm or if \p mac_length is too small or - * too large for the specified MAC algorithm. - */ -#define PSA_ALG_TRUNCATED_MAC(mac_alg, mac_length) \ - (((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \ - PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) | \ - ((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK)) - -/** Macro to build the base MAC algorithm corresponding to a truncated - * MAC algorithm. - * - * \param mac_alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) - * is true). This may be a truncated or untruncated - * MAC algorithm. - * - * \return The corresponding base MAC algorithm. - * \return Unspecified if \p mac_alg is not a supported - * MAC algorithm. - */ -#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \ - ((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \ - PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) - -/** Length to which a MAC algorithm is truncated. - * - * \param mac_alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) - * is true). - * - * \return Length of the truncated MAC in bytes. - * \return 0 if \p mac_alg is a non-truncated MAC algorithm. - * \return Unspecified if \p mac_alg is not a supported - * MAC algorithm. - */ -#define PSA_MAC_TRUNCATED_LENGTH(mac_alg) \ - (((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET) - -/** Macro to build a MAC minimum-MAC-length wildcard algorithm. - * - * A minimum-MAC-length MAC wildcard algorithm permits all MAC algorithms - * sharing the same base algorithm, and where the (potentially truncated) MAC - * length of the specific algorithm is equal to or larger then the wildcard - * algorithm's minimum MAC length. - * - * \note When setting the minimum required MAC length to less than the - * smallest MAC length allowed by the base algorithm, this effectively - * becomes an 'any-MAC-length-allowed' policy for that base algorithm. - * - * \param mac_alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) - * is true). - * \param min_mac_length Desired minimum length of the message authentication - * code in bytes. This must be at most the untruncated - * length of the MAC and must be at least 1. - * - * \return The corresponding MAC wildcard algorithm with the - * specified minimum length. - * \return Unspecified if \p mac_alg is not a supported MAC - * algorithm or if \p min_mac_length is less than 1 or - * too large for the specified MAC algorithm. - */ -#define PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(mac_alg, min_mac_length) \ - (PSA_ALG_TRUNCATED_MAC(mac_alg, min_mac_length) | \ - PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) - -#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t) 0x03c00000) -/** The CBC-MAC construction over a block cipher - * - * \warning CBC-MAC is insecure in many cases. - * A more secure mode, such as #PSA_ALG_CMAC, is recommended. - */ -#define PSA_ALG_CBC_MAC ((psa_algorithm_t) 0x03c00100) -/** The CMAC construction over a block cipher */ -#define PSA_ALG_CMAC ((psa_algorithm_t) 0x03c00200) - -/** Whether the specified algorithm is a MAC algorithm based on a block cipher. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a MAC algorithm based on a block cipher, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) \ - (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ - PSA_ALG_CIPHER_MAC_BASE) - -#define PSA_ALG_CIPHER_STREAM_FLAG ((psa_algorithm_t) 0x00800000) -#define PSA_ALG_CIPHER_FROM_BLOCK_FLAG ((psa_algorithm_t) 0x00400000) - -/** Whether the specified algorithm is a stream cipher. - * - * A stream cipher is a symmetric cipher that encrypts or decrypts messages - * by applying a bitwise-xor with a stream of bytes that is generated - * from a key. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a stream cipher algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier or if it is not a symmetric cipher algorithm. - */ -#define PSA_ALG_IS_STREAM_CIPHER(alg) \ - (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \ - (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG)) - -/** The stream cipher mode of a stream cipher algorithm. - * - * The underlying stream cipher is determined by the key type. - * - To use ChaCha20, use a key type of #PSA_KEY_TYPE_CHACHA20. - */ -#define PSA_ALG_STREAM_CIPHER ((psa_algorithm_t) 0x04800100) - -/** The CTR stream cipher mode. - * - * CTR is a stream cipher which is built from a block cipher. - * The underlying block cipher is determined by the key type. - * For example, to use AES-128-CTR, use this algorithm with - * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes). - */ -#define PSA_ALG_CTR ((psa_algorithm_t) 0x04c01000) - -/** The CFB stream cipher mode. - * - * The underlying block cipher is determined by the key type. - */ -#define PSA_ALG_CFB ((psa_algorithm_t) 0x04c01100) - -/** The OFB stream cipher mode. - * - * The underlying block cipher is determined by the key type. - */ -#define PSA_ALG_OFB ((psa_algorithm_t) 0x04c01200) - -/** The XTS cipher mode. - * - * XTS is a cipher mode which is built from a block cipher. It requires at - * least one full block of input, but beyond this minimum the input - * does not need to be a whole number of blocks. - */ -#define PSA_ALG_XTS ((psa_algorithm_t) 0x0440ff00) - -/** The Electronic Code Book (ECB) mode of a block cipher, with no padding. - * - * \warning ECB mode does not protect the confidentiality of the encrypted data - * except in extremely narrow circumstances. It is recommended that applications - * only use ECB if they need to construct an operating mode that the - * implementation does not provide. Implementations are encouraged to provide - * the modes that applications need in preference to supporting direct access - * to ECB. - * - * The underlying block cipher is determined by the key type. - * - * This symmetric cipher mode can only be used with messages whose lengths are a - * multiple of the block size of the chosen block cipher. - * - * ECB mode does not accept an initialization vector (IV). When using a - * multi-part cipher operation with this algorithm, psa_cipher_generate_iv() - * and psa_cipher_set_iv() must not be called. - */ -#define PSA_ALG_ECB_NO_PADDING ((psa_algorithm_t) 0x04404400) - -/** The CBC block cipher chaining mode, with no padding. - * - * The underlying block cipher is determined by the key type. - * - * This symmetric cipher mode can only be used with messages whose lengths - * are whole number of blocks for the chosen block cipher. - */ -#define PSA_ALG_CBC_NO_PADDING ((psa_algorithm_t) 0x04404000) - -/** The CBC block cipher chaining mode with PKCS#7 padding. - * - * The underlying block cipher is determined by the key type. - * - * This is the padding method defined by PKCS#7 (RFC 2315) §10.3. - */ -#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t) 0x04404100) - -#define PSA_ALG_AEAD_FROM_BLOCK_FLAG ((psa_algorithm_t) 0x00400000) - -/** Whether the specified algorithm is an AEAD mode on a block cipher. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is an AEAD algorithm which is an AEAD mode based on - * a block cipher, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) \ - (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) == \ - (PSA_ALG_CATEGORY_AEAD | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) - -/** The CCM authenticated encryption algorithm. - * - * The underlying block cipher is determined by the key type. - */ -#define PSA_ALG_CCM ((psa_algorithm_t) 0x05500100) - -/** The CCM* cipher mode without authentication. - * - * This is CCM* as specified in IEEE 802.15.4 §7, with a tag length of 0. - * For CCM* with a nonzero tag length, use the AEAD algorithm #PSA_ALG_CCM. - * - * The underlying block cipher is determined by the key type. - * - * Currently only 13-byte long IV's are supported. - */ -#define PSA_ALG_CCM_STAR_NO_TAG ((psa_algorithm_t) 0x04c01300) - -/** The GCM authenticated encryption algorithm. - * - * The underlying block cipher is determined by the key type. - */ -#define PSA_ALG_GCM ((psa_algorithm_t) 0x05500200) - -/** The Chacha20-Poly1305 AEAD algorithm. - * - * The ChaCha20_Poly1305 construction is defined in RFC 7539. - * - * Implementations must support 12-byte nonces, may support 8-byte nonces, - * and should reject other sizes. - * - * Implementations must support 16-byte tags and should reject other sizes. - */ -#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t) 0x05100500) - -/* In the encoding of an AEAD algorithm, the bits corresponding to - * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag. - * The constants for default lengths follow this encoding. - */ -#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t) 0x003f0000) -#define PSA_AEAD_TAG_LENGTH_OFFSET 16 - -/* In the encoding of an AEAD algorithm, the bit corresponding to - * #PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm - * is a wildcard algorithm. A key with such wildcard algorithm as permitted - * algorithm policy can be used with any algorithm corresponding to the - * same base class and having a tag length greater than or equal to the one - * encoded in #PSA_ALG_AEAD_TAG_LENGTH_MASK. */ -#define PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t) 0x00008000) - -/** Macro to build a shortened AEAD algorithm. - * - * A shortened AEAD algorithm is similar to the corresponding AEAD - * algorithm, but has an authentication tag that consists of fewer bytes. - * Depending on the algorithm, the tag length may affect the calculation - * of the ciphertext. - * - * \param aead_alg An AEAD algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_alg) - * is true). - * \param tag_length Desired length of the authentication tag in bytes. - * - * \return The corresponding AEAD algorithm with the specified - * length. - * \return Unspecified if \p aead_alg is not a supported - * AEAD algorithm or if \p tag_length is not valid - * for the specified AEAD algorithm. - */ -#define PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, tag_length) \ - (((aead_alg) & ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | \ - PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG)) | \ - ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \ - PSA_ALG_AEAD_TAG_LENGTH_MASK)) - -/** Retrieve the tag length of a specified AEAD algorithm - * - * \param aead_alg An AEAD algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_alg) - * is true). - * - * \return The tag length specified by the input algorithm. - * \return Unspecified if \p aead_alg is not a supported - * AEAD algorithm. - */ -#define PSA_ALG_AEAD_GET_TAG_LENGTH(aead_alg) \ - (((aead_alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> \ - PSA_AEAD_TAG_LENGTH_OFFSET) - -/** Calculate the corresponding AEAD algorithm with the default tag length. - * - * \param aead_alg An AEAD algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p aead_alg) is true). - * - * \return The corresponding AEAD algorithm with the default - * tag length for that algorithm. - */ -#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(aead_alg) \ - ( \ - PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CCM) \ - PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_GCM) \ - PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \ - 0) -#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, ref) \ - PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, 0) == \ - PSA_ALG_AEAD_WITH_SHORTENED_TAG(ref, 0) ? \ - ref : - -/** Macro to build an AEAD minimum-tag-length wildcard algorithm. - * - * A minimum-tag-length AEAD wildcard algorithm permits all AEAD algorithms - * sharing the same base algorithm, and where the tag length of the specific - * algorithm is equal to or larger then the minimum tag length specified by the - * wildcard algorithm. - * - * \note When setting the minimum required tag length to less than the - * smallest tag length allowed by the base algorithm, this effectively - * becomes an 'any-tag-length-allowed' policy for that base algorithm. - * - * \param aead_alg An AEAD algorithm identifier (value of type - * #psa_algorithm_t such that - * #PSA_ALG_IS_AEAD(\p aead_alg) is true). - * \param min_tag_length Desired minimum length of the authentication tag in - * bytes. This must be at least 1 and at most the largest - * allowed tag length of the algorithm. - * - * \return The corresponding AEAD wildcard algorithm with the - * specified minimum length. - * \return Unspecified if \p aead_alg is not a supported - * AEAD algorithm or if \p min_tag_length is less than 1 - * or too large for the specified AEAD algorithm. - */ -#define PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(aead_alg, min_tag_length) \ - (PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, min_tag_length) | \ - PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) - -#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t) 0x06000200) -/** RSA PKCS#1 v1.5 signature with hashing. - * - * This is the signature scheme defined by RFC 8017 - * (PKCS#1: RSA Cryptography Specifications) under the name - * RSASSA-PKCS1-v1_5. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * This includes #PSA_ALG_ANY_HASH - * when specifying the algorithm in a usage policy. - * - * \return The corresponding RSA PKCS#1 v1.5 signature algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \ - (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** Raw PKCS#1 v1.5 signature. - * - * The input to this algorithm is the DigestInfo structure used by - * RFC 8017 (PKCS#1: RSA Cryptography Specifications), §9.2 - * steps 3–6. - */ -#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE -#define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE) - -#define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t) 0x06000300) -#define PSA_ALG_RSA_PSS_ANY_SALT_BASE ((psa_algorithm_t) 0x06001300) -/** RSA PSS signature with hashing. - * - * This is the signature scheme defined by RFC 8017 - * (PKCS#1: RSA Cryptography Specifications) under the name - * RSASSA-PSS, with the message generation function MGF1, and with - * a salt length equal to the length of the hash, or the largest - * possible salt length for the algorithm and key size if that is - * smaller than the hash length. The specified hash algorithm is - * used to hash the input message, to create the salted hash, and - * for the mask generation. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * This includes #PSA_ALG_ANY_HASH - * when specifying the algorithm in a usage policy. - * - * \return The corresponding RSA PSS signature algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_RSA_PSS(hash_alg) \ - (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -/** RSA PSS signature with hashing with relaxed verification. - * - * This algorithm has the same behavior as #PSA_ALG_RSA_PSS when signing, - * but allows an arbitrary salt length (including \c 0) when verifying a - * signature. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * This includes #PSA_ALG_ANY_HASH - * when specifying the algorithm in a usage policy. - * - * \return The corresponding RSA PSS signature algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_RSA_PSS_ANY_SALT(hash_alg) \ - (PSA_ALG_RSA_PSS_ANY_SALT_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is RSA PSS with standard salt. - * - * \param alg An algorithm value or an algorithm policy wildcard. - * - * \return 1 if \p alg is of the form - * #PSA_ALG_RSA_PSS(\c hash_alg), - * where \c hash_alg is a hash algorithm or - * #PSA_ALG_ANY_HASH. 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not - * a supported algorithm identifier or policy. - */ -#define PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE) - -/** Whether the specified algorithm is RSA PSS with any salt. - * - * \param alg An algorithm value or an algorithm policy wildcard. - * - * \return 1 if \p alg is of the form - * #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg), - * where \c hash_alg is a hash algorithm or - * #PSA_ALG_ANY_HASH. 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not - * a supported algorithm identifier or policy. - */ -#define PSA_ALG_IS_RSA_PSS_ANY_SALT(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_ANY_SALT_BASE) - -/** Whether the specified algorithm is RSA PSS. - * - * This includes any of the RSA PSS algorithm variants, regardless of the - * constraints on salt length. - * - * \param alg An algorithm value or an algorithm policy wildcard. - * - * \return 1 if \p alg is of the form - * #PSA_ALG_RSA_PSS(\c hash_alg) or - * #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg), - * where \c hash_alg is a hash algorithm or - * #PSA_ALG_ANY_HASH. 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not - * a supported algorithm identifier or policy. - */ -#define PSA_ALG_IS_RSA_PSS(alg) \ - (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg) || \ - PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) - -#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t) 0x06000600) -/** ECDSA signature with hashing. - * - * This is the ECDSA signature scheme defined by ANSI X9.62, - * with a random per-message secret number (*k*). - * - * The representation of the signature as a byte string consists of - * the concatenation of the signature values *r* and *s*. Each of - * *r* and *s* is encoded as an *N*-octet string, where *N* is the length - * of the base point of the curve in octets. Each value is represented - * in big-endian order (most significant octet first). - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * This includes #PSA_ALG_ANY_HASH - * when specifying the algorithm in a usage policy. - * - * \return The corresponding ECDSA signature algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_ECDSA(hash_alg) \ - (PSA_ALG_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** ECDSA signature without hashing. - * - * This is the same signature scheme as #PSA_ALG_ECDSA(), but - * without specifying a hash algorithm. This algorithm may only be - * used to sign or verify a sequence of bytes that should be an - * already-calculated hash. Note that the input is padded with - * zeros on the left or truncated on the left as required to fit - * the curve size. - */ -#define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE -#define PSA_ALG_DETERMINISTIC_ECDSA_BASE ((psa_algorithm_t) 0x06000700) -/** Deterministic ECDSA signature with hashing. - * - * This is the deterministic ECDSA signature scheme defined by RFC 6979. - * - * The representation of a signature is the same as with #PSA_ALG_ECDSA(). - * - * Note that when this algorithm is used for verification, signatures - * made with randomized ECDSA (#PSA_ALG_ECDSA(\p hash_alg)) with the - * same private key are accepted. In other words, - * #PSA_ALG_DETERMINISTIC_ECDSA(\p hash_alg) differs from - * #PSA_ALG_ECDSA(\p hash_alg) only for signature, not for verification. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * This includes #PSA_ALG_ANY_HASH - * when specifying the algorithm in a usage policy. - * - * \return The corresponding deterministic ECDSA signature - * algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \ - (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_ECDSA_DETERMINISTIC_FLAG ((psa_algorithm_t) 0x00000100) -#define PSA_ALG_IS_ECDSA(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_ECDSA_DETERMINISTIC_FLAG) == \ - PSA_ALG_ECDSA_BASE) -#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg) \ - (((alg) & PSA_ALG_ECDSA_DETERMINISTIC_FLAG) != 0) -#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) \ - (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) -#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) \ - (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) - -/** Edwards-curve digital signature algorithm without prehashing (PureEdDSA), - * using standard parameters. - * - * Contexts are not supported in the current version of this specification - * because there is no suitable signature interface that can take the - * context as a parameter. A future version of this specification may add - * suitable functions and extend this algorithm to support contexts. - * - * PureEdDSA requires an elliptic curve key on a twisted Edwards curve. - * In this specification, the following curves are supported: - * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 255-bit: Ed25519 as specified - * in RFC 8032. - * The curve is Edwards25519. - * The hash function used internally is SHA-512. - * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 448-bit: Ed448 as specified - * in RFC 8032. - * The curve is Edwards448. - * The hash function used internally is the first 114 bytes of the - * SHAKE256 output. - * - * This algorithm can be used with psa_sign_message() and - * psa_verify_message(). Since there is no prehashing, it cannot be used - * with psa_sign_hash() or psa_verify_hash(). - * - * The signature format is the concatenation of R and S as defined by - * RFC 8032 §5.1.6 and §5.2.6 (a 64-byte string for Ed25519, a 114-byte - * string for Ed448). - */ -#define PSA_ALG_PURE_EDDSA ((psa_algorithm_t) 0x06000800) - -#define PSA_ALG_HASH_EDDSA_BASE ((psa_algorithm_t) 0x06000900) -#define PSA_ALG_IS_HASH_EDDSA(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HASH_EDDSA_BASE) - -/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA), - * using SHA-512 and the Edwards25519 curve. - * - * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format. - * - * This algorithm is Ed25519 as specified in RFC 8032. - * The curve is Edwards25519. - * The prehash is SHA-512. - * The hash function used internally is SHA-512. - * - * This is a hash-and-sign algorithm: to calculate a signature, - * you can either: - * - call psa_sign_message() on the message; - * - or calculate the SHA-512 hash of the message - * with psa_hash_compute() - * or with a multi-part hash operation started with psa_hash_setup(), - * using the hash algorithm #PSA_ALG_SHA_512, - * then sign the calculated hash with psa_sign_hash(). - * Verifying a signature is similar, using psa_verify_message() or - * psa_verify_hash() instead of the signature function. - */ -#define PSA_ALG_ED25519PH \ - (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHA_512 & PSA_ALG_HASH_MASK)) - -/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA), - * using SHAKE256 and the Edwards448 curve. - * - * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format. - * - * This algorithm is Ed448 as specified in RFC 8032. - * The curve is Edwards448. - * The prehash is the first 64 bytes of the SHAKE256 output. - * The hash function used internally is the first 114 bytes of the - * SHAKE256 output. - * - * This is a hash-and-sign algorithm: to calculate a signature, - * you can either: - * - call psa_sign_message() on the message; - * - or calculate the first 64 bytes of the SHAKE256 output of the message - * with psa_hash_compute() - * or with a multi-part hash operation started with psa_hash_setup(), - * using the hash algorithm #PSA_ALG_SHAKE256_512, - * then sign the calculated hash with psa_sign_hash(). - * Verifying a signature is similar, using psa_verify_message() or - * psa_verify_hash() instead of the signature function. - */ -#define PSA_ALG_ED448PH \ - (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHAKE256_512 & PSA_ALG_HASH_MASK)) - -/* Default definition, to be overridden if the library is extended with - * more hash-and-sign algorithms that we want to keep out of this header - * file. */ -#define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) 0 - -/** Whether the specified algorithm is a signature algorithm that can be used - * with psa_sign_hash() and psa_verify_hash(). - * - * This encompasses all strict hash-and-sign algorithms categorized by - * PSA_ALG_IS_HASH_AND_SIGN(), as well as algorithms that follow the - * paradigm more loosely: - * - #PSA_ALG_RSA_PKCS1V15_SIGN_RAW (expects its input to be an encoded hash) - * - #PSA_ALG_ECDSA_ANY (doesn't specify what kind of hash the input is) - * - * \param alg An algorithm identifier (value of type psa_algorithm_t). - * - * \return 1 if alg is a signature algorithm that can be used to sign a - * hash. 0 if alg is a signature algorithm that can only be used - * to sign a message. 0 if alg is not a signature algorithm. - * This macro can return either 0 or 1 if alg is not a - * supported algorithm identifier. - */ -#define PSA_ALG_IS_SIGN_HASH(alg) \ - (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ - PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ - PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg)) - -/** Whether the specified algorithm is a signature algorithm that can be used - * with psa_sign_message() and psa_verify_message(). - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if alg is a signature algorithm that can be used to sign a - * message. 0 if \p alg is a signature algorithm that can only be used - * to sign an already-calculated hash. 0 if \p alg is not a signature - * algorithm. This macro can return either 0 or 1 if \p alg is not a - * supported algorithm identifier. - */ -#define PSA_ALG_IS_SIGN_MESSAGE(alg) \ - (PSA_ALG_IS_SIGN_HASH(alg) || (alg) == PSA_ALG_PURE_EDDSA) - -/** Whether the specified algorithm is a hash-and-sign algorithm. - * - * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms - * structured in two parts: first the calculation of a hash in a way that - * does not depend on the key, then the calculation of a signature from the - * hash value and the key. Hash-and-sign algorithms encode the hash - * used for the hashing step, and you can call #PSA_ALG_SIGN_GET_HASH - * to extract this algorithm. - * - * Thus, for a hash-and-sign algorithm, - * `psa_sign_message(key, alg, input, ...)` is equivalent to - * ``` - * psa_hash_compute(PSA_ALG_SIGN_GET_HASH(alg), input, ..., hash, ...); - * psa_sign_hash(key, alg, hash, ..., signature, ...); - * ``` - * Most usefully, separating the hash from the signature allows the hash - * to be calculated in multiple steps with psa_hash_setup(), psa_hash_update() - * and psa_hash_finish(). Likewise psa_verify_message() is equivalent to - * calculating the hash and then calling psa_verify_hash(). - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a hash-and-sign algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_HASH_AND_SIGN(alg) \ - (PSA_ALG_IS_SIGN_HASH(alg) && \ - ((alg) & PSA_ALG_HASH_MASK) != 0) - -/** Get the hash used by a hash-and-sign signature algorithm. - * - * A hash-and-sign algorithm is a signature algorithm which is - * composed of two phases: first a hashing phase which does not use - * the key and produces a hash of the input message, then a signing - * phase which only uses the hash and the key and not the message - * itself. - * - * \param alg A signature algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_SIGN(\p alg) is true). - * - * \return The underlying hash algorithm if \p alg is a hash-and-sign - * algorithm. - * \return 0 if \p alg is a signature algorithm that does not - * follow the hash-and-sign structure. - * \return Unspecified if \p alg is not a signature algorithm or - * if it is not supported by the implementation. - */ -#define PSA_ALG_SIGN_GET_HASH(alg) \ - (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \ - ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ - 0) - -/** RSA PKCS#1 v1.5 encryption. - * - * \warning Calling psa_asymmetric_decrypt() with this algorithm as a - * parameter is considered an inherently dangerous function - * (CWE-242). Unless it is used in a side channel free and safe - * way (eg. implementing the TLS protocol as per 7.4.7.1 of - * RFC 5246), the calling code is vulnerable. - * - */ -#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t) 0x07000200) - -#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t) 0x07000300) -/** RSA OAEP encryption. - * - * This is the encryption scheme defined by RFC 8017 - * (PKCS#1: RSA Cryptography Specifications) under the name - * RSAES-OAEP, with the message generation function MGF1. - * - * \param hash_alg The hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true) to use - * for MGF1. - * - * \return The corresponding RSA OAEP encryption algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_RSA_OAEP(hash_alg) \ - (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_IS_RSA_OAEP(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE) -#define PSA_ALG_RSA_OAEP_GET_HASH(alg) \ - (PSA_ALG_IS_RSA_OAEP(alg) ? \ - ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ - 0) - -#define PSA_ALG_HKDF_BASE ((psa_algorithm_t) 0x08000100) -/** Macro to build an HKDF algorithm. - * - * For example, `PSA_ALG_HKDF(PSA_ALG_SHA_256)` is HKDF using HMAC-SHA-256. - * - * This key derivation algorithm uses the following inputs: - * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt used in the "extract" step. - * It is optional; if omitted, the derivation uses an empty salt. - * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key used in the "extract" step. - * - #PSA_KEY_DERIVATION_INPUT_INFO is the info string used in the "expand" step. - * You must pass #PSA_KEY_DERIVATION_INPUT_SALT before #PSA_KEY_DERIVATION_INPUT_SECRET. - * You may pass #PSA_KEY_DERIVATION_INPUT_INFO at any time after steup and before - * starting to generate output. - * - * \warning HKDF processes the salt as follows: first hash it with hash_alg - * if the salt is longer than the block size of the hash algorithm; then - * pad with null bytes up to the block size. As a result, it is possible - * for distinct salt inputs to result in the same outputs. To ensure - * unique outputs, it is recommended to use a fixed length for salt values. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding HKDF algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_HKDF(hash_alg) \ - (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** Whether the specified algorithm is an HKDF algorithm. - * - * HKDF is a family of key derivation algorithms that are based on a hash - * function and the HMAC construction. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is an HKDF algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_HKDF(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE) -#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) - -#define PSA_ALG_HKDF_EXTRACT_BASE ((psa_algorithm_t) 0x08000400) -/** Macro to build an HKDF-Extract algorithm. - * - * For example, `PSA_ALG_HKDF_EXTRACT(PSA_ALG_SHA_256)` is - * HKDF-Extract using HMAC-SHA-256. - * - * This key derivation algorithm uses the following inputs: - * - PSA_KEY_DERIVATION_INPUT_SALT is the salt. - * - PSA_KEY_DERIVATION_INPUT_SECRET is the input keying material used in the - * "extract" step. - * The inputs are mandatory and must be passed in the order above. - * Each input may only be passed once. - * - * \warning HKDF-Extract is not meant to be used on its own. PSA_ALG_HKDF - * should be used instead if possible. PSA_ALG_HKDF_EXTRACT is provided - * as a separate algorithm for the sake of protocols that use it as a - * building block. It may also be a slight performance optimization - * in applications that use HKDF with the same salt and key but many - * different info strings. - * - * \warning HKDF processes the salt as follows: first hash it with hash_alg - * if the salt is longer than the block size of the hash algorithm; then - * pad with null bytes up to the block size. As a result, it is possible - * for distinct salt inputs to result in the same outputs. To ensure - * unique outputs, it is recommended to use a fixed length for salt values. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding HKDF-Extract algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_HKDF_EXTRACT(hash_alg) \ - (PSA_ALG_HKDF_EXTRACT_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** Whether the specified algorithm is an HKDF-Extract algorithm. - * - * HKDF-Extract is a family of key derivation algorithms that are based - * on a hash function and the HMAC construction. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is an HKDF-Extract algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_HKDF_EXTRACT(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXTRACT_BASE) - -#define PSA_ALG_HKDF_EXPAND_BASE ((psa_algorithm_t) 0x08000500) -/** Macro to build an HKDF-Expand algorithm. - * - * For example, `PSA_ALG_HKDF_EXPAND(PSA_ALG_SHA_256)` is - * HKDF-Expand using HMAC-SHA-256. - * - * This key derivation algorithm uses the following inputs: - * - PSA_KEY_DERIVATION_INPUT_SECRET is the pseudorandom key (PRK). - * - PSA_KEY_DERIVATION_INPUT_INFO is the info string. - * - * The inputs are mandatory and must be passed in the order above. - * Each input may only be passed once. - * - * \warning HKDF-Expand is not meant to be used on its own. `PSA_ALG_HKDF` - * should be used instead if possible. `PSA_ALG_HKDF_EXPAND` is provided as - * a separate algorithm for the sake of protocols that use it as a building - * block. It may also be a slight performance optimization in applications - * that use HKDF with the same salt and key but many different info strings. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding HKDF-Expand algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_HKDF_EXPAND(hash_alg) \ - (PSA_ALG_HKDF_EXPAND_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** Whether the specified algorithm is an HKDF-Expand algorithm. - * - * HKDF-Expand is a family of key derivation algorithms that are based - * on a hash function and the HMAC construction. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is an HKDF-Expand algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_HKDF_EXPAND(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXPAND_BASE) - -/** Whether the specified algorithm is an HKDF or HKDF-Extract or - * HKDF-Expand algorithm. - * - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is any HKDF type algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_ANY_HKDF(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE || \ - ((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXTRACT_BASE || \ - ((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXPAND_BASE) - -#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t) 0x08000200) -/** Macro to build a TLS-1.2 PRF algorithm. - * - * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule, - * specified in Section 5 of RFC 5246. It is based on HMAC and can be - * used with either SHA-256 or SHA-384. - * - * This key derivation algorithm uses the following inputs, which must be - * passed in the order given here: - * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed. - * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key. - * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label. - * - * For the application to TLS-1.2 key expansion, the seed is the - * concatenation of ServerHello.Random + ClientHello.Random, - * and the label is "key expansion". - * - * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)` represents the - * TLS 1.2 PRF using HMAC-SHA-256. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding TLS-1.2 PRF algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_TLS12_PRF(hash_alg) \ - (PSA_ALG_TLS12_PRF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is a TLS-1.2 PRF algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a TLS-1.2 PRF algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_TLS12_PRF(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PRF_BASE) -#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) - -#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t) 0x08000300) -/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm. - * - * In a pure-PSK handshake in TLS 1.2, the master secret is derived - * from the PreSharedKey (PSK) through the application of padding - * (RFC 4279, Section 2) and the TLS-1.2 PRF (RFC 5246, Section 5). - * The latter is based on HMAC and can be used with either SHA-256 - * or SHA-384. - * - * This key derivation algorithm uses the following inputs, which must be - * passed in the order given here: - * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed. - * - #PSA_KEY_DERIVATION_INPUT_OTHER_SECRET is the other secret for the - * computation of the premaster secret. This input is optional; - * if omitted, it defaults to a string of null bytes with the same length - * as the secret (PSK) input. - * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key. - * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label. - * - * For the application to TLS-1.2, the seed (which is - * forwarded to the TLS-1.2 PRF) is the concatenation of the - * ClientHello.Random + ServerHello.Random, - * the label is "master secret" or "extended master secret" and - * the other secret depends on the key exchange specified in the cipher suite: - * - for a plain PSK cipher suite (RFC 4279, Section 2), omit - * PSA_KEY_DERIVATION_INPUT_OTHER_SECRET - * - for a DHE-PSK (RFC 4279, Section 3) or ECDHE-PSK cipher suite - * (RFC 5489, Section 2), the other secret should be the output of the - * PSA_ALG_FFDH or PSA_ALG_ECDH key agreement performed with the peer. - * The recommended way to pass this input is to use a key derivation - * algorithm constructed as - * PSA_ALG_KEY_AGREEMENT(ka_alg, PSA_ALG_TLS12_PSK_TO_MS(hash_alg)) - * and to call psa_key_derivation_key_agreement(). Alternatively, - * this input may be an output of `psa_raw_key_agreement()` passed with - * psa_key_derivation_input_bytes(), or an equivalent input passed with - * psa_key_derivation_input_bytes() or psa_key_derivation_input_key(). - * - for a RSA-PSK cipher suite (RFC 4279, Section 4), the other secret - * should be the 48-byte client challenge (the PreMasterSecret of - * (RFC 5246, Section 7.4.7.1)) concatenation of the TLS version and - * a 46-byte random string chosen by the client. On the server, this is - * typically an output of psa_asymmetric_decrypt() using - * PSA_ALG_RSA_PKCS1V15_CRYPT, passed to the key derivation operation - * with `psa_key_derivation_input_bytes()`. - * - * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256)` represents the - * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding TLS-1.2 PSK to MS algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \ - (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a TLS-1.2 PSK to MS algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PSK_TO_MS_BASE) -#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) - -/* The TLS 1.2 ECJPAKE-to-PMS KDF. It takes the shared secret K (an EC point - * in case of EC J-PAKE) and calculates SHA256(K.X) that the rest of TLS 1.2 - * will use to derive the session secret, as defined by step 2 of - * https://datatracker.ietf.org/doc/html/draft-cragie-tls-ecjpake-01#section-8.7. - * Uses PSA_ALG_SHA_256. - * This function takes a single input: - * #PSA_KEY_DERIVATION_INPUT_SECRET is the shared secret K from EC J-PAKE. - * The only supported curve is secp256r1 (the 256-bit curve in - * #PSA_ECC_FAMILY_SECP_R1), so the input must be exactly 65 bytes. - * The output has to be read as a single chunk of 32 bytes, defined as - * PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE. - */ -#define PSA_ALG_TLS12_ECJPAKE_TO_PMS ((psa_algorithm_t) 0x08000609) - -/* This flag indicates whether the key derivation algorithm is suitable for - * use on low-entropy secrets such as password - these algorithms are also - * known as key stretching or password hashing schemes. These are also the - * algorithms that accepts inputs of type #PSA_KEY_DERIVATION_INPUT_PASSWORD. - * - * Those algorithms cannot be combined with a key agreement algorithm. - */ -#define PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG ((psa_algorithm_t) 0x00800000) - -#define PSA_ALG_PBKDF2_HMAC_BASE ((psa_algorithm_t) 0x08800100) -/** Macro to build a PBKDF2-HMAC password hashing / key stretching algorithm. - * - * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2). - * This macro specifies the PBKDF2 algorithm constructed using a PRF based on - * HMAC with the specified hash. - * For example, `PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256)` specifies PBKDF2 - * using the PRF HMAC-SHA-256. - * - * This key derivation algorithm uses the following inputs, which must be - * provided in the following order: - * - #PSA_KEY_DERIVATION_INPUT_COST is the iteration count. - * This input step must be used exactly once. - * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt. - * This input step must be used one or more times; if used several times, the - * inputs will be concatenated. This can be used to build the final salt - * from multiple sources, both public and secret (also known as pepper). - * - #PSA_KEY_DERIVATION_INPUT_PASSWORD is the password to be hashed. - * This input step must be used exactly once. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding PBKDF2-HMAC-XXX algorithm. - * \return Unspecified if \p hash_alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_PBKDF2_HMAC(hash_alg) \ - (PSA_ALG_PBKDF2_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is a PBKDF2-HMAC algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a PBKDF2-HMAC algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_PBKDF2_HMAC(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_PBKDF2_HMAC_BASE) -#define PSA_ALG_PBKDF2_HMAC_GET_HASH(pbkdf2_alg) \ - (PSA_ALG_CATEGORY_HASH | ((pbkdf2_alg) & PSA_ALG_HASH_MASK)) -/** The PBKDF2-AES-CMAC-PRF-128 password hashing / key stretching algorithm. - * - * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2). - * This macro specifies the PBKDF2 algorithm constructed using the - * AES-CMAC-PRF-128 PRF specified by RFC 4615. - * - * This key derivation algorithm uses the same inputs as - * #PSA_ALG_PBKDF2_HMAC() with the same constraints. - */ -#define PSA_ALG_PBKDF2_AES_CMAC_PRF_128 ((psa_algorithm_t) 0x08800200) - -#define PSA_ALG_IS_PBKDF2(kdf_alg) \ - (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg) || \ - ((kdf_alg) == PSA_ALG_PBKDF2_AES_CMAC_PRF_128)) - -#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t) 0xfe00ffff) -#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t) 0xffff0000) - -/** Macro to build a combined algorithm that chains a key agreement with - * a key derivation. - * - * \param ka_alg A key agreement algorithm (\c PSA_ALG_XXX value such - * that #PSA_ALG_IS_KEY_AGREEMENT(\p ka_alg) is true). - * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such - * that #PSA_ALG_IS_KEY_DERIVATION(\p kdf_alg) is true). - * - * \return The corresponding key agreement and derivation - * algorithm. - * \return Unspecified if \p ka_alg is not a supported - * key agreement algorithm or \p kdf_alg is not a - * supported key derivation algorithm. - */ -#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \ - ((ka_alg) | (kdf_alg)) - -#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \ - (((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION) - -#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \ - (((alg) & PSA_ALG_KEY_AGREEMENT_MASK) | PSA_ALG_CATEGORY_KEY_AGREEMENT) - -/** Whether the specified algorithm is a raw key agreement algorithm. - * - * A raw key agreement algorithm is one that does not specify - * a key derivation function. - * Usually, raw key agreement algorithms are constructed directly with - * a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are - * constructed with #PSA_ALG_KEY_AGREEMENT(). - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a raw key agreement algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) \ - (PSA_ALG_IS_KEY_AGREEMENT(alg) && \ - PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) == PSA_ALG_CATEGORY_KEY_DERIVATION) - -#define PSA_ALG_IS_KEY_DERIVATION_OR_AGREEMENT(alg) \ - ((PSA_ALG_IS_KEY_DERIVATION(alg) || PSA_ALG_IS_KEY_AGREEMENT(alg))) - -/** The finite-field Diffie-Hellman (DH) key agreement algorithm. - * - * The shared secret produced by key agreement is - * `g^{ab}` in big-endian format. - * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p` - * in bits. - */ -#define PSA_ALG_FFDH ((psa_algorithm_t) 0x09010000) - -/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm. - * - * This includes the raw finite field Diffie-Hellman algorithm as well as - * finite-field Diffie-Hellman followed by any supporter key derivation - * algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a finite field Diffie-Hellman algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key agreement algorithm identifier. - */ -#define PSA_ALG_IS_FFDH(alg) \ - (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH) - -/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm. - * - * The shared secret produced by key agreement is the x-coordinate of - * the shared secret point. It is always `ceiling(m / 8)` bytes long where - * `m` is the bit size associated with the curve, i.e. the bit size of the - * order of the curve's coordinate field. When `m` is not a multiple of 8, - * the byte containing the most significant bit of the shared secret - * is padded with zero bits. The byte order is either little-endian - * or big-endian depending on the curve type. - * - * - For Montgomery curves (curve types `PSA_ECC_FAMILY_CURVEXXX`), - * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` - * in little-endian byte order. - * The bit size is 448 for Curve448 and 255 for Curve25519. - * - For Weierstrass curves over prime fields (curve types - * `PSA_ECC_FAMILY_SECPXXX` and `PSA_ECC_FAMILY_BRAINPOOL_PXXX`), - * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` - * in big-endian byte order. - * The bit size is `m = ceiling(log_2(p))` for the field `F_p`. - * - For Weierstrass curves over binary fields (curve types - * `PSA_ECC_FAMILY_SECTXXX`), - * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` - * in big-endian byte order. - * The bit size is `m` for the field `F_{2^m}`. - */ -#define PSA_ALG_ECDH ((psa_algorithm_t) 0x09020000) - -/** Whether the specified algorithm is an elliptic curve Diffie-Hellman - * algorithm. - * - * This includes the raw elliptic curve Diffie-Hellman algorithm as well as - * elliptic curve Diffie-Hellman followed by any supporter key derivation - * algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is an elliptic curve Diffie-Hellman algorithm, - * 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key agreement algorithm identifier. - */ -#define PSA_ALG_IS_ECDH(alg) \ - (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH) - -/** Whether the specified algorithm encoding is a wildcard. - * - * Wildcard values may only be used to set the usage algorithm field in - * a policy, not to perform an operation. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a wildcard algorithm encoding. - * \return 0 if \c alg is a non-wildcard algorithm encoding (suitable for - * an operation). - * \return This macro may return either 0 or 1 if \c alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_WILDCARD(alg) \ - (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \ - PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \ - PSA_ALG_IS_MAC(alg) ? \ - (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \ - PSA_ALG_IS_AEAD(alg) ? \ - (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \ - (alg) == PSA_ALG_ANY_HASH) - -/** Get the hash used by a composite algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return The underlying hash algorithm if alg is a composite algorithm that - * uses a hash algorithm. - * - * \return \c 0 if alg is not a composite algorithm that uses a hash. - */ -#define PSA_ALG_GET_HASH(alg) \ - (((alg) & 0x000000ff) == 0 ? ((psa_algorithm_t) 0) : 0x02000000 | ((alg) & 0x000000ff)) - -/**@}*/ - -/** \defgroup key_lifetimes Key lifetimes - * @{ - */ - -/* Note that location and persistence level values are embedded in the - * persistent key store, as part of key metadata. As a consequence, they - * must not be changed (unless the storage format version changes). - */ - -/** The default lifetime for volatile keys. - * - * A volatile key only exists as long as the identifier to it is not destroyed. - * The key material is guaranteed to be erased on a power reset. - * - * A key with this lifetime is typically stored in the RAM area of the - * PSA Crypto subsystem. However this is an implementation choice. - * If an implementation stores data about the key in a non-volatile memory, - * it must release all the resources associated with the key and erase the - * key material if the calling application terminates. - */ -#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t) 0x00000000) - -/** The default lifetime for persistent keys. - * - * A persistent key remains in storage until it is explicitly destroyed or - * until the corresponding storage area is wiped. This specification does - * not define any mechanism to wipe a storage area, but integrations may - * provide their own mechanism (for example to perform a factory reset, - * to prepare for device refurbishment, or to uninstall an application). - * - * This lifetime value is the default storage area for the calling - * application. Integrations of Mbed TLS may support other persistent lifetimes. - * See ::psa_key_lifetime_t for more information. - */ -#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t) 0x00000001) - -/** The persistence level of volatile keys. - * - * See ::psa_key_persistence_t for more information. - */ -#define PSA_KEY_PERSISTENCE_VOLATILE ((psa_key_persistence_t) 0x00) - -/** The default persistence level for persistent keys. - * - * See ::psa_key_persistence_t for more information. - */ -#define PSA_KEY_PERSISTENCE_DEFAULT ((psa_key_persistence_t) 0x01) - -/** A persistence level indicating that a key is never destroyed. - * - * See ::psa_key_persistence_t for more information. - */ -#define PSA_KEY_PERSISTENCE_READ_ONLY ((psa_key_persistence_t) 0xff) - -#define PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) \ - ((psa_key_persistence_t) ((lifetime) & 0x000000ff)) - -#define PSA_KEY_LIFETIME_GET_LOCATION(lifetime) \ - ((psa_key_location_t) ((lifetime) >> 8)) - -/** Whether a key lifetime indicates that the key is volatile. - * - * A volatile key is automatically destroyed by the implementation when - * the application instance terminates. In particular, a volatile key - * is automatically destroyed on a power reset of the device. - * - * A key that is not volatile is persistent. Persistent keys are - * preserved until the application explicitly destroys them or until an - * implementation-specific device management event occurs (for example, - * a factory reset). - * - * \param lifetime The lifetime value to query (value of type - * ::psa_key_lifetime_t). - * - * \return \c 1 if the key is volatile, otherwise \c 0. - */ -#define PSA_KEY_LIFETIME_IS_VOLATILE(lifetime) \ - (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \ - PSA_KEY_PERSISTENCE_VOLATILE) - -/** Whether a key lifetime indicates that the key is read-only. - * - * Read-only keys cannot be created or destroyed through the PSA Crypto API. - * They must be created through platform-specific means that bypass the API. - * - * Some platforms may offer ways to destroy read-only keys. For example, - * consider a platform with multiple levels of privilege, where a - * low-privilege application can use a key but is not allowed to destroy - * it, and the platform exposes the key to the application with a read-only - * lifetime. High-privilege code can destroy the key even though the - * application sees the key as read-only. - * - * \param lifetime The lifetime value to query (value of type - * ::psa_key_lifetime_t). - * - * \return \c 1 if the key is read-only, otherwise \c 0. - */ -#define PSA_KEY_LIFETIME_IS_READ_ONLY(lifetime) \ - (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \ - PSA_KEY_PERSISTENCE_READ_ONLY) - -/** Construct a lifetime from a persistence level and a location. - * - * \param persistence The persistence level - * (value of type ::psa_key_persistence_t). - * \param location The location indicator - * (value of type ::psa_key_location_t). - * - * \return The constructed lifetime value. - */ -#define PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(persistence, location) \ - ((location) << 8 | (persistence)) - -/** The local storage area for persistent keys. - * - * This storage area is available on all systems that can store persistent - * keys without delegating the storage to a third-party cryptoprocessor. - * - * See ::psa_key_location_t for more information. - */ -#define PSA_KEY_LOCATION_LOCAL_STORAGE ((psa_key_location_t) 0x000000) - -#define PSA_KEY_LOCATION_VENDOR_FLAG ((psa_key_location_t) 0x800000) - -/* Note that key identifier values are embedded in the - * persistent key store, as part of key metadata. As a consequence, they - * must not be changed (unless the storage format version changes). - */ - -/** The null key identifier. - */ -/* *INDENT-OFF* (https://github.com/ARM-software/psa-arch-tests/issues/337) */ -#define PSA_KEY_ID_NULL ((psa_key_id_t)0) -/* *INDENT-ON* */ -/** The minimum value for a key identifier chosen by the application. - */ -#define PSA_KEY_ID_USER_MIN ((psa_key_id_t) 0x00000001) -/** The maximum value for a key identifier chosen by the application. - */ -#define PSA_KEY_ID_USER_MAX ((psa_key_id_t) 0x3fffffff) -/** The minimum value for a key identifier chosen by the implementation. - */ -#define PSA_KEY_ID_VENDOR_MIN ((psa_key_id_t) 0x40000000) -/** The maximum value for a key identifier chosen by the implementation. - */ -#define PSA_KEY_ID_VENDOR_MAX ((psa_key_id_t) 0x7fffffff) - - -#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) - -#define MBEDTLS_SVC_KEY_ID_INIT ((psa_key_id_t) 0) -#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) (id) -#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(id) (0) - -/** Utility to initialize a key identifier at runtime. - * - * \param unused Unused parameter. - * \param key_id Identifier of the key. - */ -static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make( - unsigned int unused, psa_key_id_t key_id) -{ - (void) unused; - - return key_id; -} - -/** Compare two key identifiers. - * - * \param id1 First key identifier. - * \param id2 Second key identifier. - * - * \return Non-zero if the two key identifier are equal, zero otherwise. - */ -static inline int mbedtls_svc_key_id_equal(mbedtls_svc_key_id_t id1, - mbedtls_svc_key_id_t id2) -{ - return id1 == id2; -} - -/** Check whether a key identifier is null. - * - * \param key Key identifier. - * - * \return Non-zero if the key identifier is null, zero otherwise. - */ -static inline int mbedtls_svc_key_id_is_null(mbedtls_svc_key_id_t key) -{ - return key == 0; -} - -#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ - -#define MBEDTLS_SVC_KEY_ID_INIT ((mbedtls_svc_key_id_t){ 0, 0 }) -#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) ((id).MBEDTLS_PRIVATE(key_id)) -#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(id) ((id).MBEDTLS_PRIVATE(owner)) - -/** Utility to initialize a key identifier at runtime. - * - * \param owner_id Identifier of the key owner. - * \param key_id Identifier of the key. - */ -static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make( - mbedtls_key_owner_id_t owner_id, psa_key_id_t key_id) -{ - return (mbedtls_svc_key_id_t){ .MBEDTLS_PRIVATE(key_id) = key_id, - .MBEDTLS_PRIVATE(owner) = owner_id }; -} - -/** Compare two key identifiers. - * - * \param id1 First key identifier. - * \param id2 Second key identifier. - * - * \return Non-zero if the two key identifier are equal, zero otherwise. - */ -static inline int mbedtls_svc_key_id_equal(mbedtls_svc_key_id_t id1, - mbedtls_svc_key_id_t id2) -{ - return (id1.MBEDTLS_PRIVATE(key_id) == id2.MBEDTLS_PRIVATE(key_id)) && - mbedtls_key_owner_id_equal(id1.MBEDTLS_PRIVATE(owner), id2.MBEDTLS_PRIVATE(owner)); -} - -/** Check whether a key identifier is null. - * - * \param key Key identifier. - * - * \return Non-zero if the key identifier is null, zero otherwise. - */ -static inline int mbedtls_svc_key_id_is_null(mbedtls_svc_key_id_t key) -{ - return key.MBEDTLS_PRIVATE(key_id) == 0; -} - -#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ - -/**@}*/ - -/** \defgroup policy Key policies - * @{ - */ - -/* Note that key usage flags are embedded in the - * persistent key store, as part of key metadata. As a consequence, they - * must not be changed (unless the storage format version changes). - */ - -/** Whether the key may be exported. - * - * A public key or the public part of a key pair may always be exported - * regardless of the value of this permission flag. - * - * If a key does not have export permission, implementations shall not - * allow the key to be exported in plain form from the cryptoprocessor, - * whether through psa_export_key() or through a proprietary interface. - * The key may however be exportable in a wrapped form, i.e. in a form - * where it is encrypted by another key. - */ -#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t) 0x00000001) - -/** Whether the key may be copied. - * - * This flag allows the use of psa_copy_key() to make a copy of the key - * with the same policy or a more restrictive policy. - * - * For lifetimes for which the key is located in a secure element which - * enforce the non-exportability of keys, copying a key outside the secure - * element also requires the usage flag #PSA_KEY_USAGE_EXPORT. - * Copying the key inside the secure element is permitted with just - * #PSA_KEY_USAGE_COPY if the secure element supports it. - * For keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE or - * #PSA_KEY_LIFETIME_PERSISTENT, the usage flag #PSA_KEY_USAGE_COPY - * is sufficient to permit the copy. - */ -#define PSA_KEY_USAGE_COPY ((psa_key_usage_t) 0x00000002) - -/** Whether the key may be used to encrypt a message. - * - * This flag allows the key to be used for a symmetric encryption operation, - * for an AEAD encryption-and-authentication operation, - * or for an asymmetric encryption operation, - * if otherwise permitted by the key's type and policy. - * - * For a key pair, this concerns the public key. - */ -#define PSA_KEY_USAGE_ENCRYPT ((psa_key_usage_t) 0x00000100) - -/** Whether the key may be used to decrypt a message. - * - * This flag allows the key to be used for a symmetric decryption operation, - * for an AEAD decryption-and-verification operation, - * or for an asymmetric decryption operation, - * if otherwise permitted by the key's type and policy. - * - * For a key pair, this concerns the private key. - */ -#define PSA_KEY_USAGE_DECRYPT ((psa_key_usage_t) 0x00000200) - -/** Whether the key may be used to sign a message. - * - * This flag allows the key to be used for a MAC calculation operation or for - * an asymmetric message signature operation, if otherwise permitted by the - * key’s type and policy. - * - * For a key pair, this concerns the private key. - */ -#define PSA_KEY_USAGE_SIGN_MESSAGE ((psa_key_usage_t) 0x00000400) - -/** Whether the key may be used to verify a message. - * - * This flag allows the key to be used for a MAC verification operation or for - * an asymmetric message signature verification operation, if otherwise - * permitted by the key’s type and policy. - * - * For a key pair, this concerns the public key. - */ -#define PSA_KEY_USAGE_VERIFY_MESSAGE ((psa_key_usage_t) 0x00000800) - -/** Whether the key may be used to sign a message. - * - * This flag allows the key to be used for a MAC calculation operation - * or for an asymmetric signature operation, - * if otherwise permitted by the key's type and policy. - * - * For a key pair, this concerns the private key. - */ -#define PSA_KEY_USAGE_SIGN_HASH ((psa_key_usage_t) 0x00001000) - -/** Whether the key may be used to verify a message signature. - * - * This flag allows the key to be used for a MAC verification operation - * or for an asymmetric signature verification operation, - * if otherwise permitted by the key's type and policy. - * - * For a key pair, this concerns the public key. - */ -#define PSA_KEY_USAGE_VERIFY_HASH ((psa_key_usage_t) 0x00002000) - -/** Whether the key may be used to derive other keys or produce a password - * hash. - * - * This flag allows the key to be used for a key derivation operation or for - * a key agreement operation, if otherwise permitted by the key's type and - * policy. - * - * If this flag is present on all keys used in calls to - * psa_key_derivation_input_key() for a key derivation operation, then it - * permits calling psa_key_derivation_output_bytes() or - * psa_key_derivation_output_key() at the end of the operation. - */ -#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t) 0x00004000) - -/** Whether the key may be used to verify the result of a key derivation, - * including password hashing. - * - * This flag allows the key to be used: - * - * This flag allows the key to be used in a key derivation operation, if - * otherwise permitted by the key's type and policy. - * - * If this flag is present on all keys used in calls to - * psa_key_derivation_input_key() for a key derivation operation, then it - * permits calling psa_key_derivation_verify_bytes() or - * psa_key_derivation_verify_key() at the end of the operation. - */ -#define PSA_KEY_USAGE_VERIFY_DERIVATION ((psa_key_usage_t) 0x00008000) - -/**@}*/ - -/** \defgroup derivation Key derivation - * @{ - */ - -/* Key input steps are not embedded in the persistent storage, so you can - * change them if needed: it's only an ABI change. */ - -/** A secret input for key derivation. - * - * This should be a key of type #PSA_KEY_TYPE_DERIVE - * (passed to psa_key_derivation_input_key()) - * or the shared secret resulting from a key agreement - * (obtained via psa_key_derivation_key_agreement()). - * - * The secret can also be a direct input (passed to - * key_derivation_input_bytes()). In this case, the derivation operation - * may not be used to derive keys: the operation will only allow - * psa_key_derivation_output_bytes(), - * psa_key_derivation_verify_bytes(), or - * psa_key_derivation_verify_key(), but not - * psa_key_derivation_output_key(). - */ -#define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t) 0x0101) - -/** A low-entropy secret input for password hashing / key stretching. - * - * This is usually a key of type #PSA_KEY_TYPE_PASSWORD (passed to - * psa_key_derivation_input_key()) or a direct input (passed to - * psa_key_derivation_input_bytes()) that is a password or passphrase. It can - * also be high-entropy secret such as a key of type #PSA_KEY_TYPE_DERIVE or - * the shared secret resulting from a key agreement. - * - * The secret can also be a direct input (passed to - * key_derivation_input_bytes()). In this case, the derivation operation - * may not be used to derive keys: the operation will only allow - * psa_key_derivation_output_bytes(), - * psa_key_derivation_verify_bytes(), or - * psa_key_derivation_verify_key(), but not - * psa_key_derivation_output_key(). - */ -#define PSA_KEY_DERIVATION_INPUT_PASSWORD ((psa_key_derivation_step_t) 0x0102) - -/** A high-entropy additional secret input for key derivation. - * - * This is typically the shared secret resulting from a key agreement obtained - * via `psa_key_derivation_key_agreement()`. It may alternatively be a key of - * type `PSA_KEY_TYPE_DERIVE` passed to `psa_key_derivation_input_key()`, or - * a direct input passed to `psa_key_derivation_input_bytes()`. - */ -#define PSA_KEY_DERIVATION_INPUT_OTHER_SECRET \ - ((psa_key_derivation_step_t) 0x0103) - -/** A label for key derivation. - * - * This should be a direct input. - * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. - */ -#define PSA_KEY_DERIVATION_INPUT_LABEL ((psa_key_derivation_step_t) 0x0201) - -/** A salt for key derivation. - * - * This should be a direct input. - * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA or - * #PSA_KEY_TYPE_PEPPER. - */ -#define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t) 0x0202) - -/** An information string for key derivation. - * - * This should be a direct input. - * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. - */ -#define PSA_KEY_DERIVATION_INPUT_INFO ((psa_key_derivation_step_t) 0x0203) - -/** A seed for key derivation. - * - * This should be a direct input. - * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. - */ -#define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t) 0x0204) - -/** A cost parameter for password hashing / key stretching. - * - * This must be a direct input, passed to psa_key_derivation_input_integer(). - */ -#define PSA_KEY_DERIVATION_INPUT_COST ((psa_key_derivation_step_t) 0x0205) - -/**@}*/ - -/** \defgroup helper_macros Helper macros - * @{ - */ - -/* Helper macros */ - -/** Check if two AEAD algorithm identifiers refer to the same AEAD algorithm - * regardless of the tag length they encode. - * - * \param aead_alg_1 An AEAD algorithm identifier. - * \param aead_alg_2 An AEAD algorithm identifier. - * - * \return 1 if both identifiers refer to the same AEAD algorithm, - * 0 otherwise. - * Unspecified if neither \p aead_alg_1 nor \p aead_alg_2 are - * a supported AEAD algorithm. - */ -#define MBEDTLS_PSA_ALG_AEAD_EQUAL(aead_alg_1, aead_alg_2) \ - (!(((aead_alg_1) ^ (aead_alg_2)) & \ - ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG))) - -/**@}*/ - -/**@}*/ - -/** \defgroup interruptible Interruptible operations - * @{ - */ - -/** Maximum value for use with \c psa_interruptible_set_max_ops() to determine - * the maximum number of ops allowed to be executed by an interruptible - * function in a single call. - */ -#define PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED UINT32_MAX - -/**@}*/ - -#endif /* PSA_CRYPTO_VALUES_H */ diff --git a/vendor/mbedtls/library/aes.c b/vendor/mbedtls/library/aes.c deleted file mode 100644 index b1a5c3ed1..000000000 --- a/vendor/mbedtls/library/aes.c +++ /dev/null @@ -1,2294 +0,0 @@ -/* - * FIPS-197 compliant AES implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. - * - * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf - * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_AES_C) - -#include - -#include "mbedtls/aes.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -#if !((defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_AESCE_C)) || \ - (defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \ - (defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C))) -#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites" -#endif -#endif - -#if defined(MBEDTLS_ARCH_IS_X86) -#if defined(MBEDTLS_PADLOCK_C) -#if !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" -#endif -#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \ - "MBEDTLS_PADLOCK_C is set" -#endif -#endif -#endif - -#if defined(MBEDTLS_PADLOCK_C) -#include "padlock.h" -#endif -#if defined(MBEDTLS_AESNI_C) -#include "aesni.h" -#endif -#if defined(MBEDTLS_AESCE_C) -#include "aesce.h" -#endif - -#include "mbedtls/platform.h" -#include "ctr.h" - -/* - * This is a convenience shorthand macro to check if we need reverse S-box and - * reverse tables. It's private and only defined in this file. - */ -#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \ - (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \ - !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -#define MBEDTLS_AES_NEED_REVERSE_TABLES -#endif - -#if !defined(MBEDTLS_AES_ALT) - -#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) -static int aes_padlock_ace = -1; -#endif - -#if defined(MBEDTLS_AES_ROM_TABLES) -/* - * Forward S-box - */ -MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* - * Forward tables - */ -#define FT \ -\ - V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \ - V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \ - V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \ - V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \ - V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \ - V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \ - V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \ - V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \ - V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \ - V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \ - V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \ - V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \ - V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \ - V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \ - V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \ - V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \ - V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \ - V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \ - V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \ - V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \ - V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \ - V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \ - V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \ - V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \ - V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \ - V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \ - V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \ - V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \ - V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \ - V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \ - V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \ - V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \ - V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \ - V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \ - V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \ - V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \ - V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \ - V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \ - V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \ - V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \ - V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \ - V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \ - V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \ - V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \ - V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \ - V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \ - V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \ - V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \ - V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \ - V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \ - V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \ - V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \ - V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \ - V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \ - V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \ - V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \ - V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \ - V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \ - V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \ - V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \ - V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \ - V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \ - V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \ - V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C) - -#define V(a, b, c, d) 0x##a##b##c##d -MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT }; -#undef V - -#define V(a, b, c, d) 0x##b##c##d##a -MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT }; -#undef V - -#define V(a, b, c, d) 0x##c##d##a##b -MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT }; -#undef V - -#define V(a, b, c, d) 0x##d##a##b##c -MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT }; -#undef V - -#undef FT - -/* - * Reverse S-box - */ -MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* - * Reverse tables - */ -#define RT \ -\ - V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \ - V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \ - V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \ - V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \ - V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \ - V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \ - V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \ - V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \ - V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \ - V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \ - V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \ - V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \ - V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \ - V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \ - V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \ - V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \ - V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \ - V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \ - V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \ - V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \ - V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \ - V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \ - V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \ - V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \ - V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \ - V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \ - V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \ - V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \ - V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \ - V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \ - V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \ - V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \ - V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \ - V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \ - V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \ - V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \ - V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \ - V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \ - V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \ - V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \ - V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \ - V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \ - V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \ - V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \ - V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \ - V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \ - V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \ - V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \ - V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \ - V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \ - V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \ - V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \ - V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \ - V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \ - V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \ - V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \ - V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \ - V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \ - V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \ - V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \ - V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \ - V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \ - V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \ - V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0) - - -#define V(a, b, c, d) 0x##a##b##c##d -MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT }; -#undef V - -#define V(a, b, c, d) 0x##b##c##d##a -MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT }; -#undef V - -#define V(a, b, c, d) 0x##c##d##a##b -MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT }; -#undef V - -#define V(a, b, c, d) 0x##d##a##b##c -MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT }; -#undef V - -#undef RT - -/* - * Round constants - */ -MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] = -{ - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x0000001B, 0x00000036 -}; - -#else /* MBEDTLS_AES_ROM_TABLES */ - -/* - * Forward S-box & tables - */ -MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256]; -MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256]; -MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256]; -MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256]; -MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256]; - -/* - * Reverse S-box & tables - */ -MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256]; - -MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256]; -MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256]; -MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256]; -MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256]; - -/* - * Round constants - */ -MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10]; - -/* - * Tables generation code - */ -#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24) -#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00)) -#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0) - -MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0; - -MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void) -{ - int i; - uint8_t x, y, z; - uint8_t pow[256]; - uint8_t log[256]; - - /* - * compute pow and log tables over GF(2^8) - */ - for (i = 0, x = 1; i < 256; i++) { - pow[i] = x; - log[x] = (uint8_t) i; - x ^= XTIME(x); - } - - /* - * calculate the round constants - */ - for (i = 0, x = 1; i < 10; i++) { - round_constants[i] = x; - x = XTIME(x); - } - - /* - * generate the forward and reverse S-boxes - */ - FSb[0x00] = 0x63; -#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES) - RSb[0x63] = 0x00; -#endif - - for (i = 1; i < 256; i++) { - x = pow[255 - log[i]]; - - y = x; y = (y << 1) | (y >> 7); - x ^= y; y = (y << 1) | (y >> 7); - x ^= y; y = (y << 1) | (y >> 7); - x ^= y; y = (y << 1) | (y >> 7); - x ^= y ^ 0x63; - - FSb[i] = x; -#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES) - RSb[x] = (unsigned char) i; -#endif - } - - /* - * generate the forward and reverse tables - */ - for (i = 0; i < 256; i++) { - x = FSb[i]; - y = XTIME(x); - z = y ^ x; - - FT0[i] = ((uint32_t) y) ^ - ((uint32_t) x << 8) ^ - ((uint32_t) x << 16) ^ - ((uint32_t) z << 24); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - FT1[i] = ROTL8(FT0[i]); - FT2[i] = ROTL8(FT1[i]); - FT3[i] = ROTL8(FT2[i]); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ - -#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES) - x = RSb[i]; - - RT0[i] = ((uint32_t) MUL(0x0E, x)) ^ - ((uint32_t) MUL(0x09, x) << 8) ^ - ((uint32_t) MUL(0x0D, x) << 16) ^ - ((uint32_t) MUL(0x0B, x) << 24); - -#if !defined(MBEDTLS_AES_FEWER_TABLES) - RT1[i] = ROTL8(RT0[i]); - RT2[i] = ROTL8(RT1[i]); - RT3[i] = ROTL8(RT2[i]); -#endif /* !MBEDTLS_AES_FEWER_TABLES */ -#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */ - } -} - -#undef ROTL8 - -#endif /* MBEDTLS_AES_ROM_TABLES */ - -#if defined(MBEDTLS_AES_FEWER_TABLES) - -#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24)) -#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16)) -#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8)) - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) ROTL8(RT0[idx]) -#define AES_RT2(idx) ROTL16(RT0[idx]) -#define AES_RT3(idx) ROTL24(RT0[idx]) - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) ROTL8(FT0[idx]) -#define AES_FT2(idx) ROTL16(FT0[idx]) -#define AES_FT3(idx) ROTL24(FT0[idx]) - -#else /* MBEDTLS_AES_FEWER_TABLES */ - -#define AES_RT0(idx) RT0[idx] -#define AES_RT1(idx) RT1[idx] -#define AES_RT2(idx) RT2[idx] -#define AES_RT3(idx) RT3[idx] - -#define AES_FT0(idx) FT0[idx] -#define AES_FT1(idx) FT1[idx] -#define AES_FT2(idx) FT2[idx] -#define AES_FT3(idx) FT3[idx] - -#endif /* MBEDTLS_AES_FEWER_TABLES */ - -void mbedtls_aes_init(mbedtls_aes_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_aes_context)); -} - -void mbedtls_aes_free(mbedtls_aes_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context)); -} - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx) -{ - mbedtls_aes_init(&ctx->crypt); - mbedtls_aes_init(&ctx->tweak); -} - -void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_aes_free(&ctx->crypt); - mbedtls_aes_free(&ctx->tweak); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* Some implementations need the round keys to be aligned. - * Return an offset to be added to buf, such that (buf + offset) is - * correctly aligned. - * Note that the offset is in units of elements of buf, i.e. 32-bit words, - * i.e. an offset of 1 means 4 bytes and so on. - */ -#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \ - (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2) -#define MAY_NEED_TO_ALIGN -#endif - -MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf) -{ -#if defined(MAY_NEED_TO_ALIGN) - int align_16_bytes = 0; - -#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) - if (aes_padlock_ace == -1) { - aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE); - } - if (aes_padlock_ace) { - align_16_bytes = 1; - } -#endif - -#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2 - if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { - align_16_bytes = 1; - } -#endif - - if (align_16_bytes) { - /* These implementations needs 16-byte alignment - * for the round key array. */ - unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4; - if (delta == 0) { - return 0; - } else { - return 4 - delta; // 16 bytes = 4 uint32_t - } - } -#else /* MAY_NEED_TO_ALIGN */ - (void) buf; -#endif /* MAY_NEED_TO_ALIGN */ - - return 0; -} - -/* - * AES key schedule (encryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) -int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits) -{ - uint32_t *RK; - - switch (keybits) { - case 128: ctx->nr = 10; break; -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; - } - -#if !defined(MBEDTLS_AES_ROM_TABLES) - if (aes_init_done == 0) { - aes_gen_tables(); - aes_init_done = 1; - } -#endif - - ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf); - RK = ctx->buf + ctx->rk_offset; - -#if defined(MBEDTLS_AESNI_HAVE_CODE) - if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { - return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits); - } -#endif - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - if (MBEDTLS_AESCE_HAS_SUPPORT()) { - return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits); - } -#endif - -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) - for (unsigned int i = 0; i < (keybits >> 5); i++) { - RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2); - } - - switch (ctx->nr) { - case 10: - - for (unsigned int i = 0; i < 10; i++, RK += 4) { - RK[4] = RK[0] ^ round_constants[i] ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - case 12: - - for (unsigned int i = 0; i < 8; i++, RK += 6) { - RK[6] = RK[0] ^ round_constants[i] ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 14: - - for (unsigned int i = 0; i < 7; i++, RK += 8) { - RK[8] = RK[0] ^ round_constants[i] ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - } - - return 0; -#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */ -} -#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ - -/* - * AES key schedule (decryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits) -{ -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) - uint32_t *SK; -#endif - int ret; - mbedtls_aes_context cty; - uint32_t *RK; - - - mbedtls_aes_init(&cty); - - ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf); - RK = ctx->buf + ctx->rk_offset; - - /* Also checks keybits */ - if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) { - goto exit; - } - - ctx->nr = cty.nr; - -#if defined(MBEDTLS_AESNI_HAVE_CODE) - if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { - mbedtls_aesni_inverse_key((unsigned char *) RK, - (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr); - goto exit; - } -#endif - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - if (MBEDTLS_AESCE_HAS_SUPPORT()) { - mbedtls_aesce_inverse_key( - (unsigned char *) RK, - (const unsigned char *) (cty.buf + cty.rk_offset), - ctx->nr); - goto exit; - } -#endif - -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) - SK = cty.buf + cty.rk_offset + cty.nr * 4; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - SK -= 8; - for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) { - for (int j = 0; j < 4; j++, SK++) { - *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^ - AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^ - AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^ - AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]); - } - } - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; -#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */ -exit: - mbedtls_aes_free(&cty); - - return ret; -} -#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int mbedtls_aes_xts_decode_keys(const unsigned char *key, - unsigned int keybits, - const unsigned char **key1, - unsigned int *key1bits, - const unsigned char **key2, - unsigned int *key2bits) -{ - const unsigned int half_keybits = keybits / 2; - const unsigned int half_keybytes = half_keybits / 8; - - switch (keybits) { - case 256: break; - case 512: break; - default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; - } - - *key1bits = half_keybits; - *key2bits = half_keybits; - *key1 = &key[0]; - *key2 = &key[half_keybytes]; - - return 0; -} - -int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits, - &key2, &key2bits); - if (ret != 0) { - return ret; - } - - /* Set the tweak key. Always set tweak key for the encryption mode. */ - ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits); - if (ret != 0) { - return ret; - } - - /* Set crypt key for encryption. */ - return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits); -} - -int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *key1, *key2; - unsigned int key1bits, key2bits; - - ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits, - &key2, &key2bits); - if (ret != 0) { - return ret; - } - - /* Set the tweak key. Always set tweak key for encryption. */ - ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits); - if (ret != 0) { - return ret; - } - - /* Set crypt key for decryption. */ - return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \ - AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \ - AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \ - AES_FT3(MBEDTLS_BYTE_3(Y3)); \ - \ - (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \ - AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \ - AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \ - AES_FT3(MBEDTLS_BYTE_3(Y0)); \ - \ - (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \ - AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \ - AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \ - AES_FT3(MBEDTLS_BYTE_3(Y1)); \ - \ - (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \ - AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \ - AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \ - AES_FT3(MBEDTLS_BYTE_3(Y2)); \ - } while (0) - -#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ - do \ - { \ - (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \ - AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \ - AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \ - AES_RT3(MBEDTLS_BYTE_3(Y1)); \ - \ - (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \ - AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \ - AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \ - AES_RT3(MBEDTLS_BYTE_3(Y2)); \ - \ - (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \ - AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \ - AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \ - AES_RT3(MBEDTLS_BYTE_3(Y3)); \ - \ - (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \ - AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \ - AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \ - AES_RT3(MBEDTLS_BYTE_3(Y0)); \ - } while (0) - -/* - * AES-ECB block encryption - */ -#if !defined(MBEDTLS_AES_ENCRYPT_ALT) -int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16]) -{ - int i; - uint32_t *RK = ctx->buf + ctx->rk_offset; - struct { - uint32_t X[4]; - uint32_t Y[4]; - } t; - - t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++; - t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++; - t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++; - t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++; - - for (i = (ctx->nr >> 1) - 1; i > 0; i--) { - AES_FROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); - AES_FROUND(t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3]); - } - - AES_FROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); - - t.X[0] = *RK++ ^ \ - ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24); - - t.X[1] = *RK++ ^ \ - ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24); - - t.X[2] = *RK++ ^ \ - ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24); - - t.X[3] = *RK++ ^ \ - ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^ - ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24); - - MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0); - MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4); - MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8); - MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12); - - mbedtls_platform_zeroize(&t, sizeof(t)); - - return 0; -} -#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ - -/* - * AES-ECB block decryption - */ -#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16]) -{ - int i; - uint32_t *RK = ctx->buf + ctx->rk_offset; - struct { - uint32_t X[4]; - uint32_t Y[4]; - } t; - - t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++; - t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++; - t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++; - t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++; - - for (i = (ctx->nr >> 1) - 1; i > 0; i--) { - AES_RROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); - AES_RROUND(t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3]); - } - - AES_RROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); - - t.X[0] = *RK++ ^ \ - ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24); - - t.X[1] = *RK++ ^ \ - ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24); - - t.X[2] = *RK++ ^ \ - ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24); - - t.X[3] = *RK++ ^ \ - ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^ - ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24); - - MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0); - MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4); - MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8); - MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12); - - mbedtls_platform_zeroize(&t, sizeof(t)); - - return 0; -} -#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -/* VIA Padlock and our intrinsics-based implementation of AESNI require - * the round keys to be aligned on a 16-byte boundary. We take care of this - * before creating them, but the AES context may have moved (this can happen - * if the library is called from a language with managed memory), and in later - * calls it might have a different alignment with respect to 16-byte memory. - * So we may need to realign. - */ -MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx) -{ - unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf); - if (new_offset != ctx->rk_offset) { - memmove(ctx->buf + new_offset, // new address - ctx->buf + ctx->rk_offset, // current address - (ctx->nr + 1) * 16); // number of round keys * bytes per rk - ctx->rk_offset = new_offset; - } -} - -/* - * AES-ECB block encryption/decryption - */ -int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]) -{ - if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - -#if defined(MAY_NEED_TO_ALIGN) - aes_maybe_realign(ctx); -#endif - -#if defined(MBEDTLS_AESNI_HAVE_CODE) - if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { - return mbedtls_aesni_crypt_ecb(ctx, mode, input, output); - } -#endif - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - if (MBEDTLS_AESCE_HAS_SUPPORT()) { - return mbedtls_aesce_crypt_ecb(ctx, mode, input, output); - } -#endif - -#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) - if (aes_padlock_ace > 0) { - return mbedtls_padlock_xcryptecb(ctx, mode, input, output); - } -#endif - -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (mode == MBEDTLS_AES_DECRYPT) { - return mbedtls_internal_aes_decrypt(ctx, input, output); - } else -#endif - { - return mbedtls_internal_aes_encrypt(ctx, input, output); - } -#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */ -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - -/* - * AES-CBC buffer encryption/decryption - */ -int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char temp[16]; - - if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - - /* Nothing to do if length is zero. */ - if (length == 0) { - return 0; - } - - if (length % 16) { - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - } - -#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) - if (aes_padlock_ace > 0) { - if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) { - return 0; - } - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - const unsigned char *ivp = iv; - - if (mode == MBEDTLS_AES_DECRYPT) { - while (length > 0) { - memcpy(temp, input, 16); - ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output); - if (ret != 0) { - goto exit; - } - /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on - * the result for the next block in CBC, and the cost of transferring that data from - * NEON registers, NEON is slower on aarch64. */ - mbedtls_xor_no_simd(output, output, iv, 16); - - memcpy(iv, temp, 16); - - input += 16; - output += 16; - length -= 16; - } - } else { - while (length > 0) { - mbedtls_xor_no_simd(output, input, ivp, 16); - - ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output); - if (ret != 0) { - goto exit; - } - ivp = output; - - input += 16; - output += 16; - length -= 16; - } - memcpy(iv, ivp, 16); - } - ret = 0; - -exit: - return ret; -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - -typedef unsigned char mbedtls_be128[16]; - -/* - * GF(2^128) multiplication function - * - * This function multiplies a field element by x in the polynomial field - * representation. It uses 64-bit word operations to gain speed but compensates - * for machine endianness and hence works correctly on both big and little - * endian machines. - */ -#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C) -MBEDTLS_OPTIMIZE_FOR_PERFORMANCE -#endif -static inline void mbedtls_gf128mul_x_ble(unsigned char r[16], - const unsigned char x[16]) -{ - uint64_t a, b, ra, rb; - - a = MBEDTLS_GET_UINT64_LE(x, 0); - b = MBEDTLS_GET_UINT64_LE(x, 8); - - ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3)); - rb = (a >> 63) | (b << 1); - - MBEDTLS_PUT_UINT64_LE(ra, r, 0); - MBEDTLS_PUT_UINT64_LE(rb, r, 8); -} - -/* - * AES-XTS buffer encryption/decryption - * - * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble() - * is a 3x performance improvement for gcc -Os, if we have hardware AES support. - */ -#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C) -MBEDTLS_OPTIMIZE_FOR_PERFORMANCE -#endif -int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx, - int mode, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t blocks = length / 16; - size_t leftover = length % 16; - unsigned char tweak[16]; - unsigned char prev_tweak[16]; - unsigned char tmp[16]; - - if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - - /* Data units must be at least 16 bytes long. */ - if (length < 16) { - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - } - - /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ - if (length > (1 << 20) * 16) { - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; - } - - /* Compute the tweak. */ - ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT, - data_unit, tweak); - if (ret != 0) { - return ret; - } - - while (blocks--) { - if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) { - /* We are on the last block in a decrypt operation that has - * leftover bytes, so we need to use the next tweak for this block, - * and this tweak for the leftover bytes. Save the current tweak for - * the leftovers and then update the current tweak for use on this, - * the last full block. */ - memcpy(prev_tweak, tweak, sizeof(tweak)); - mbedtls_gf128mul_x_ble(tweak, tweak); - } - - mbedtls_xor(tmp, input, tweak, 16); - - ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp); - if (ret != 0) { - return ret; - } - - mbedtls_xor(output, tmp, tweak, 16); - - /* Update the tweak for the next block. */ - mbedtls_gf128mul_x_ble(tweak, tweak); - - output += 16; - input += 16; - } - - if (leftover) { - /* If we are on the leftover bytes in a decrypt operation, we need to - * use the previous tweak for these bytes (as saved in prev_tweak). */ - unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; - - /* We are now on the final part of the data unit, which doesn't divide - * evenly by 16. It's time for ciphertext stealing. */ - size_t i; - unsigned char *prev_output = output - 16; - - /* Copy ciphertext bytes from the previous block to our output for each - * byte of ciphertext we won't steal. */ - for (i = 0; i < leftover; i++) { - output[i] = prev_output[i]; - } - - /* Copy the remainder of the input for this final round. */ - mbedtls_xor(tmp, input, t, leftover); - - /* Copy ciphertext bytes from the previous block for input in this - * round. */ - mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i); - - ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp); - if (ret != 0) { - return ret; - } - - /* Write the result back to the previous block, overriding the previous - * output we copied. */ - mbedtls_xor(prev_output, tmp, t, 16); - } - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output) -{ - int c; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - - if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - - n = *iv_off; - - if (n > 15) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - - if (mode == MBEDTLS_AES_DECRYPT) { - while (length--) { - if (n == 0) { - ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); - if (ret != 0) { - goto exit; - } - } - - c = *input++; - *output++ = (unsigned char) (c ^ iv[n]); - iv[n] = (unsigned char) c; - - n = (n + 1) & 0x0F; - } - } else { - while (length--) { - if (n == 0) { - ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); - if (ret != 0) { - goto exit; - } - } - - iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++); - - n = (n + 1) & 0x0F; - } - } - - *iv_off = n; - ret = 0; - -exit: - return ret; -} - -/* - * AES-CFB8 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char c; - unsigned char ov[17]; - - if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - while (length--) { - memcpy(ov, iv, 16); - ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); - if (ret != 0) { - goto exit; - } - - if (mode == MBEDTLS_AES_DECRYPT) { - ov[16] = *input; - } - - c = *output++ = (unsigned char) (iv[0] ^ *input++); - - if (mode == MBEDTLS_AES_ENCRYPT) { - ov[16] = c; - } - - memcpy(iv, ov + 1, 16); - } - ret = 0; - -exit: - return ret; -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB (Output Feedback Mode) buffer encryption/decryption - */ -int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output) -{ - int ret = 0; - size_t n; - - n = *iv_off; - - if (n > 15) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - - while (length--) { - if (n == 0) { - ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); - if (ret != 0) { - goto exit; - } - } - *output++ = *input++ ^ iv[n]; - - n = (n + 1) & 0x0F; - } - - *iv_off = n; - -exit: - return ret; -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR buffer encryption/decryption - */ -int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - size_t offset = *nc_off; - - if (offset > 0x0F) { - return MBEDTLS_ERR_AES_BAD_INPUT_DATA; - } - - for (size_t i = 0; i < length;) { - size_t n = 16; - if (offset == 0) { - ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block); - if (ret != 0) { - goto exit; - } - mbedtls_ctr_increment_counter(nonce_counter); - } else { - n -= offset; - } - - if (n > (length - i)) { - n = (length - i); - } - mbedtls_xor(&output[i], &input[i], &stream_block[offset], n); - // offset might be non-zero for the last block, but in that case, we don't use it again - offset = 0; - i += n; - } - - // capture offset for future resumption - *nc_off = (*nc_off + length) % 16; - - ret = 0; - -exit: - return ret; -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#endif /* !MBEDTLS_AES_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * AES test vectors from: - * - * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip - */ -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -static const unsigned char aes_test_ecb_dec[][16] = -{ - { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, - 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, - 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, - { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, - 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } -#endif -}; -#endif - -static const unsigned char aes_test_ecb_enc[][16] = -{ - { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, - 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, - 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, - { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, - 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } -#endif -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const unsigned char aes_test_cbc_dec[][16] = -{ - { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, - 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, - 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, - { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, - 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } -#endif -}; - -static const unsigned char aes_test_cbc_enc[][16] = -{ - { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, - 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, - 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, - { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, - 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } -#endif -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 test vectors from: - * - * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf - */ -static const unsigned char aes_test_cfb128_key[][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -#endif -}; - -static const unsigned char aes_test_cfb128_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_cfb128_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_cfb128_ct[][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, - 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, - 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, - 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, - 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, - 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, - 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, - 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, - 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, - 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, - 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, - 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, - 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, - 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, - 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, - 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } -#endif -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -/* - * AES-OFB test vectors from: - * - * https://csrc.nist.gov/publications/detail/sp/800-38a/final - */ -static const unsigned char aes_test_ofb_key[][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -#endif -}; - -static const unsigned char aes_test_ofb_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_ofb_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_ofb_ct[][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, - 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, - 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, - 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, - 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, - 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, - 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, - 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, - 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, - 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, - 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, - 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, - 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, - 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, - 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, - 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } -#endif -}; -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc3686.html - */ - -static const unsigned char aes_test_ctr_key[][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char aes_test_ctr_nonce_counter[][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char aes_test_ctr_pt[][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char aes_test_ctr_ct[][48] = -{ - { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, - 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, - { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, - 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, - 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, - 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, - { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, - 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, - 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, - 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, - 0x25, 0xB2, 0x07, 0x2F } -}; - -static const int aes_test_ctr_len[3] = -{ 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -/* - * AES-XTS test vectors from: - * - * IEEE P1619/D16 Annex B - * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf - * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) - */ -static const unsigned char aes_test_xts_key[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, - { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, - 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, -}; - -static const unsigned char aes_test_xts_pt32[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, - { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, -}; - -static const unsigned char aes_test_xts_ct32[][32] = -{ - { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, - 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, - 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, - 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, - { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, - 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, - 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, - 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, - { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, - 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, - 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, - 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, -}; - -static const unsigned char aes_test_xts_data_unit[][16] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -}; - -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -/* - * Checkup routine - */ -int mbedtls_aes_self_test(int verbose) -{ - int ret = 0, i, j, u, mode; - unsigned int keybits; - unsigned char key[32]; - unsigned char buf[64]; - const unsigned char *aes_tests; -#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_OFB) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_OFB) - size_t offset; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) - int len; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - mbedtls_aes_context ctx; - - memset(key, 0, 32); - mbedtls_aes_init(&ctx); - - if (verbose != 0) { -#if defined(MBEDTLS_AES_ALT) - mbedtls_printf(" AES note: alternative implementation.\n"); -#else /* MBEDTLS_AES_ALT */ -#if defined(MBEDTLS_AESNI_HAVE_CODE) -#if MBEDTLS_AESNI_HAVE_CODE == 1 - mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n"); -#elif MBEDTLS_AESNI_HAVE_CODE == 2 - mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n"); -#else -#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE" -#endif - if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { - mbedtls_printf(" AES note: using AESNI.\n"); - } else -#endif -#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) - if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) { - mbedtls_printf(" AES note: using VIA Padlock.\n"); - } else -#endif -#if defined(MBEDTLS_AESCE_HAVE_CODE) - if (MBEDTLS_AESCE_HAS_SUPPORT()) { - mbedtls_printf(" AES note: using AESCE.\n"); - } else -#endif - { -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) - mbedtls_printf(" AES note: built-in implementation.\n"); -#endif - } -#endif /* MBEDTLS_AES_ALT */ - } - - /* - * ECB mode - */ - { - static const int num_tests = - sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc); - - for (i = 0; i < num_tests << 1; i++) { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if (verbose != 0) { - mbedtls_printf(" AES-ECB-%3u (%s): ", keybits, - (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); - } -#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (mode == MBEDTLS_AES_DECRYPT) { - if (verbose != 0) { - mbedtls_printf("skipped\n"); - } - continue; - } -#endif - - memset(buf, 0, 16); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (mode == MBEDTLS_AES_DECRYPT) { - ret = mbedtls_aes_setkey_dec(&ctx, key, keybits); - aes_tests = aes_test_ecb_dec[u]; - } else -#endif - { - ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); - aes_tests = aes_test_ecb_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { - mbedtls_printf("skipped\n"); - continue; - } else if (ret != 0) { - goto exit; - } - - for (j = 0; j < 10000; j++) { - ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf); - if (ret != 0) { - goto exit; - } - } - - if (memcmp(buf, aes_tests, 16) != 0) { - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - { - static const int num_tests = - sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec); - - for (i = 0; i < num_tests << 1; i++) { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if (verbose != 0) { - mbedtls_printf(" AES-CBC-%3u (%s): ", keybits, - (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); - } - - memset(iv, 0, 16); - memset(prv, 0, 16); - memset(buf, 0, 16); - - if (mode == MBEDTLS_AES_DECRYPT) { - ret = mbedtls_aes_setkey_dec(&ctx, key, keybits); - aes_tests = aes_test_cbc_dec[u]; - } else { - ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); - aes_tests = aes_test_cbc_enc[u]; - } - - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { - mbedtls_printf("skipped\n"); - continue; - } else if (ret != 0) { - goto exit; - } - - for (j = 0; j < 10000; j++) { - if (mode == MBEDTLS_AES_ENCRYPT) { - unsigned char tmp[16]; - - memcpy(tmp, prv, 16); - memcpy(prv, buf, 16); - memcpy(buf, tmp, 16); - } - - ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf); - if (ret != 0) { - goto exit; - } - - } - - if (memcmp(buf, aes_tests, 16) != 0) { - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /* - * CFB128 mode - */ - { - static const int num_tests = - sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key); - - for (i = 0; i < num_tests << 1; i++) { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if (verbose != 0) { - mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits, - (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); - } - - memcpy(iv, aes_test_cfb128_iv, 16); - memcpy(key, aes_test_cfb128_key[u], keybits / 8); - - offset = 0; - ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { - mbedtls_printf("skipped\n"); - continue; - } else if (ret != 0) { - goto exit; - } - - if (mode == MBEDTLS_AES_DECRYPT) { - memcpy(buf, aes_test_cfb128_ct[u], 64); - aes_tests = aes_test_cfb128_pt; - } else { - memcpy(buf, aes_test_cfb128_pt, 64); - aes_tests = aes_test_cfb128_ct[u]; - } - - ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf); - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, aes_tests, 64) != 0) { - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /* - * OFB mode - */ - { - static const int num_tests = - sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key); - - for (i = 0; i < num_tests << 1; i++) { - u = i >> 1; - keybits = 128 + u * 64; - mode = i & 1; - - if (verbose != 0) { - mbedtls_printf(" AES-OFB-%3u (%s): ", keybits, - (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); - } - - memcpy(iv, aes_test_ofb_iv, 16); - memcpy(key, aes_test_ofb_key[u], keybits / 8); - - offset = 0; - ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { - mbedtls_printf("skipped\n"); - continue; - } else if (ret != 0) { - goto exit; - } - - if (mode == MBEDTLS_AES_DECRYPT) { - memcpy(buf, aes_test_ofb_ct[u], 64); - aes_tests = aes_test_ofb_pt; - } else { - memcpy(buf, aes_test_ofb_pt, 64); - aes_tests = aes_test_ofb_ct[u]; - } - - ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf); - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, aes_tests, 64) != 0) { - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - } -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - { - static const int num_tests = - sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key); - - for (i = 0; i < num_tests << 1; i++) { - u = i >> 1; - mode = i & 1; - - if (verbose != 0) { - mbedtls_printf(" AES-CTR-128 (%s): ", - (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); - } - - memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16); - memcpy(key, aes_test_ctr_key[u], 16); - - offset = 0; - if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) { - goto exit; - } - - len = aes_test_ctr_len[u]; - - if (mode == MBEDTLS_AES_DECRYPT) { - memcpy(buf, aes_test_ctr_ct[u], len); - aes_tests = aes_test_ctr_pt[u]; - } else { - memcpy(buf, aes_test_ctr_pt[u], len); - aes_tests = aes_test_ctr_ct[u]; - } - - ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter, - stream_block, buf, buf); - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, aes_tests, len) != 0) { - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - /* - * XTS mode - */ - { - static const int num_tests = - sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); - mbedtls_aes_xts_context ctx_xts; - - mbedtls_aes_xts_init(&ctx_xts); - - for (i = 0; i < num_tests << 1; i++) { - const unsigned char *data_unit; - u = i >> 1; - mode = i & 1; - - if (verbose != 0) { - mbedtls_printf(" AES-XTS-128 (%s): ", - (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); - } - - memset(key, 0, sizeof(key)); - memcpy(key, aes_test_xts_key[u], 32); - data_unit = aes_test_xts_data_unit[u]; - - len = sizeof(*aes_test_xts_ct32); - - if (mode == MBEDTLS_AES_DECRYPT) { - ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256); - if (ret != 0) { - goto exit; - } - memcpy(buf, aes_test_xts_ct32[u], len); - aes_tests = aes_test_xts_pt32[u]; - } else { - ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256); - if (ret != 0) { - goto exit; - } - memcpy(buf, aes_test_xts_pt32[u], len); - aes_tests = aes_test_xts_ct32[u]; - } - - - ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit, - buf, buf); - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, aes_tests, len) != 0) { - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - mbedtls_aes_xts_free(&ctx_xts); - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - - ret = 0; - -exit: - if (ret != 0 && verbose != 0) { - mbedtls_printf("failed\n"); - } - - mbedtls_aes_free(&ctx); - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_AES_C */ diff --git a/vendor/mbedtls/library/aesce.c b/vendor/mbedtls/library/aesce.c deleted file mode 100644 index 06a8bdc0a..000000000 --- a/vendor/mbedtls/library/aesce.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Armv8-A Cryptographic Extension support functions for Aarch64 - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#if defined(__clang__) && (__clang_major__ >= 4) - -/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if, - * but that is defined by build_info.h, and we need this block to happen first. */ -#if defined(__ARM_ARCH) -#if __ARM_ARCH >= 8 -#define MBEDTLS_AESCE_ARCH_IS_ARMV8_A -#endif -#endif - -#if defined(MBEDTLS_AESCE_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO) -/* The intrinsic declaration are guarded by predefined ACLE macros in clang: - * these are normally only enabled by the -march option on the command line. - * By defining the macros ourselves we gain access to those declarations without - * requiring -march on the command line. - * - * `arm_neon.h` is included by common.h, so we put these defines - * at the top of this file, before any includes. This is necessary with - * Clang <=15.x. With Clang 16.0 and above, these macro definitions are - * no longer required, but they're harmless. See - * https://reviews.llvm.org/D131064 - */ -#define __ARM_FEATURE_CRYPTO 1 -/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions - * - * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it - * for older compilers. - */ -#define __ARM_FEATURE_AES 1 -#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG -#endif - -#endif /* defined(__clang__) && (__clang_major__ >= 4) */ - -#include "common.h" - -#if defined(MBEDTLS_AESCE_C) - -#include - -#include "aesce.h" - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - -/* Compiler version checks. */ -#if defined(__clang__) -# if defined(MBEDTLS_ARCH_IS_ARM32) && (__clang_major__ < 11) -# error "Minimum version of Clang for MBEDTLS_AESCE_C on 32-bit Arm or Thumb is 11.0." -# elif defined(MBEDTLS_ARCH_IS_ARM64) && (__clang_major__ < 4) -# error "Minimum version of Clang for MBEDTLS_AESCE_C on aarch64 is 4.0." -# endif -#elif defined(__GNUC__) -# if __GNUC__ < 6 -# error "Minimum version of GCC for MBEDTLS_AESCE_C is 6.0." -# endif -#elif defined(_MSC_VER) -/* TODO: We haven't verified MSVC from 1920 to 1928. If someone verified that, - * please update this and document of `MBEDTLS_AESCE_C` in - * `mbedtls_config.h`. */ -# if _MSC_VER < 1929 -# error "Minimum version of MSVC for MBEDTLS_AESCE_C is 2019 version 16.11.2." -# endif -#elif defined(__ARMCC_VERSION) -# if defined(MBEDTLS_ARCH_IS_ARM32) && (__ARMCC_VERSION < 6200002) -/* TODO: We haven't verified armclang for 32-bit Arm/Thumb prior to 6.20. - * If someone verified that, please update this and document of - * `MBEDTLS_AESCE_C` in `mbedtls_config.h`. */ -# error "Minimum version of armclang for MBEDTLS_AESCE_C on 32-bit Arm is 6.20." -# elif defined(MBEDTLS_ARCH_IS_ARM64) && (__ARMCC_VERSION < 6060000) -# error "Minimum version of armclang for MBEDTLS_AESCE_C on aarch64 is 6.6." -# endif -#endif - -#if !(defined(__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES)) || \ - defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG) -# if defined(__ARMCOMPILER_VERSION) -# if __ARMCOMPILER_VERSION <= 6090000 -# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_AESCE_C" -# else -# pragma clang attribute push (__attribute__((target("aes"))), apply_to=function) -# define MBEDTLS_POP_TARGET_PRAGMA -# endif -# elif defined(__clang__) -# if __clang_major__ < 7 -# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function) -# else -# pragma clang attribute push (__attribute__((target("aes"))), apply_to=function) -# endif -# define MBEDTLS_POP_TARGET_PRAGMA -# elif defined(__GNUC__) -# pragma GCC push_options -# pragma GCC target ("+crypto") -# define MBEDTLS_POP_TARGET_PRAGMA -# elif defined(_MSC_VER) -# error "Required feature(__ARM_FEATURE_AES) is not enabled." -# endif -#endif /* !(__ARM_FEATURE_CRYPTO || __ARM_FEATURE_AES) || - MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */ - -#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) - -#include -#if !defined(HWCAP_NEON) -#define HWCAP_NEON (1 << 12) -#endif -#if !defined(HWCAP2_AES) -#define HWCAP2_AES (1 << 0) -#endif -#if !defined(HWCAP_AES) -#define HWCAP_AES (1 << 3) -#endif -#if !defined(HWCAP_ASIMD) -#define HWCAP_ASIMD (1 << 1) -#endif - -signed char mbedtls_aesce_has_support_result = -1; - -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -/* - * AES instruction support detection routine - */ -int mbedtls_aesce_has_support_impl(void) -{ - /* To avoid many calls to getauxval, cache the result. This is - * thread-safe, because we store the result in a char so cannot - * be vulnerable to non-atomic updates. - * It is possible that we could end up setting result more than - * once, but that is harmless. - */ - if (mbedtls_aesce_has_support_result == -1) { -#if defined(MBEDTLS_ARCH_IS_ARM32) - unsigned long auxval = getauxval(AT_HWCAP); - unsigned long auxval2 = getauxval(AT_HWCAP2); - if (((auxval & HWCAP_NEON) == HWCAP_NEON) && - ((auxval2 & HWCAP2_AES) == HWCAP2_AES)) { - mbedtls_aesce_has_support_result = 1; - } else { - mbedtls_aesce_has_support_result = 0; - } -#else - unsigned long auxval = getauxval(AT_HWCAP); - if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) == - (HWCAP_ASIMD | HWCAP_AES)) { - mbedtls_aesce_has_support_result = 1; - } else { - mbedtls_aesce_has_support_result = 0; - } -#endif - } - return mbedtls_aesce_has_support_result; -} -#endif - -#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */ - -/* Single round of AESCE encryption */ -#define AESCE_ENCRYPT_ROUND \ - block = vaeseq_u8(block, vld1q_u8(keys)); \ - block = vaesmcq_u8(block); \ - keys += 16 -/* Two rounds of AESCE encryption */ -#define AESCE_ENCRYPT_ROUND_X2 AESCE_ENCRYPT_ROUND; AESCE_ENCRYPT_ROUND - -MBEDTLS_OPTIMIZE_FOR_PERFORMANCE -static uint8x16_t aesce_encrypt_block(uint8x16_t block, - unsigned char *keys, - int rounds) -{ - /* 10, 12 or 14 rounds. Unroll loop. */ - if (rounds == 10) { - goto rounds_10; - } - if (rounds == 12) { - goto rounds_12; - } - AESCE_ENCRYPT_ROUND_X2; -rounds_12: - AESCE_ENCRYPT_ROUND_X2; -rounds_10: - AESCE_ENCRYPT_ROUND_X2; - AESCE_ENCRYPT_ROUND_X2; - AESCE_ENCRYPT_ROUND_X2; - AESCE_ENCRYPT_ROUND_X2; - AESCE_ENCRYPT_ROUND; - - /* AES AddRoundKey for the previous round. - * SubBytes, ShiftRows for the final round. */ - block = vaeseq_u8(block, vld1q_u8(keys)); - keys += 16; - - /* Final round: no MixColumns */ - - /* Final AddRoundKey */ - block = veorq_u8(block, vld1q_u8(keys)); - - return block; -} - -/* Single round of AESCE decryption - * - * AES AddRoundKey, SubBytes, ShiftRows - * - * block = vaesdq_u8(block, vld1q_u8(keys)); - * - * AES inverse MixColumns for the next round. - * - * This means that we switch the order of the inverse AddRoundKey and - * inverse MixColumns operations. We have to do this as AddRoundKey is - * done in an atomic instruction together with the inverses of SubBytes - * and ShiftRows. - * - * It works because MixColumns is a linear operation over GF(2^8) and - * AddRoundKey is an exclusive or, which is equivalent to addition over - * GF(2^8). (The inverse of MixColumns needs to be applied to the - * affected round keys separately which has been done when the - * decryption round keys were calculated.) - * - * block = vaesimcq_u8(block); - */ -#define AESCE_DECRYPT_ROUND \ - block = vaesdq_u8(block, vld1q_u8(keys)); \ - block = vaesimcq_u8(block); \ - keys += 16 -/* Two rounds of AESCE decryption */ -#define AESCE_DECRYPT_ROUND_X2 AESCE_DECRYPT_ROUND; AESCE_DECRYPT_ROUND - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -static uint8x16_t aesce_decrypt_block(uint8x16_t block, - unsigned char *keys, - int rounds) -{ - /* 10, 12 or 14 rounds. Unroll loop. */ - if (rounds == 10) { - goto rounds_10; - } - if (rounds == 12) { - goto rounds_12; - } - AESCE_DECRYPT_ROUND_X2; -rounds_12: - AESCE_DECRYPT_ROUND_X2; -rounds_10: - AESCE_DECRYPT_ROUND_X2; - AESCE_DECRYPT_ROUND_X2; - AESCE_DECRYPT_ROUND_X2; - AESCE_DECRYPT_ROUND_X2; - AESCE_DECRYPT_ROUND; - - /* The inverses of AES AddRoundKey, SubBytes, ShiftRows finishing up the - * last full round. */ - block = vaesdq_u8(block, vld1q_u8(keys)); - keys += 16; - - /* Inverse AddRoundKey for inverting the initial round key addition. */ - block = veorq_u8(block, vld1q_u8(keys)); - - return block; -} -#endif - -/* - * AES-ECB block en(de)cryption - */ -int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]) -{ - uint8x16_t block = vld1q_u8(&input[0]); - unsigned char *keys = (unsigned char *) (ctx->buf + ctx->rk_offset); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (mode == MBEDTLS_AES_DECRYPT) { - block = aesce_decrypt_block(block, keys, ctx->nr); - } else -#else - (void) mode; -#endif - { - block = aesce_encrypt_block(block, keys, ctx->nr); - } - vst1q_u8(&output[0], block); - - return 0; -} - -/* - * Compute decryption round keys from encryption round keys - */ -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -void mbedtls_aesce_inverse_key(unsigned char *invkey, - const unsigned char *fwdkey, - int nr) -{ - int i, j; - j = nr; - vst1q_u8(invkey, vld1q_u8(fwdkey + j * 16)); - for (i = 1, j--; j > 0; i++, j--) { - vst1q_u8(invkey + i * 16, - vaesimcq_u8(vld1q_u8(fwdkey + j * 16))); - } - vst1q_u8(invkey + i * 16, vld1q_u8(fwdkey + j * 16)); - -} -#endif - -static inline uint32_t aes_rot_word(uint32_t word) -{ - return (word << (32 - 8)) | (word >> 8); -} - -static inline uint32_t aes_sub_word(uint32_t in) -{ - uint8x16_t v = vreinterpretq_u8_u32(vdupq_n_u32(in)); - uint8x16_t zero = vdupq_n_u8(0); - - /* vaeseq_u8 does both SubBytes and ShiftRows. Taking the first row yields - * the correct result as ShiftRows doesn't change the first row. */ - v = vaeseq_u8(zero, v); - return vgetq_lane_u32(vreinterpretq_u32_u8(v), 0); -} - -/* - * Key expansion function - */ -static void aesce_setkey_enc(unsigned char *rk, - const unsigned char *key, - const size_t key_bit_length) -{ - static uint8_t const rcon[] = { 0x01, 0x02, 0x04, 0x08, 0x10, - 0x20, 0x40, 0x80, 0x1b, 0x36 }; - /* See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf - * - Section 5, Nr = Nk + 6 - * - Section 5.2, the length of round keys is Nb*(Nr+1) - */ - const size_t key_len_in_words = key_bit_length / 32; /* Nk */ - const size_t round_key_len_in_words = 4; /* Nb */ - const size_t rounds_needed = key_len_in_words + 6; /* Nr */ - const size_t round_keys_len_in_words = - round_key_len_in_words * (rounds_needed + 1); /* Nb*(Nr+1) */ - const uint32_t *rko_end = (uint32_t *) rk + round_keys_len_in_words; - - memcpy(rk, key, key_len_in_words * 4); - - for (uint32_t *rki = (uint32_t *) rk; - rki + key_len_in_words < rko_end; - rki += key_len_in_words) { - - size_t iteration = (size_t) (rki - (uint32_t *) rk) / key_len_in_words; - uint32_t *rko; - rko = rki + key_len_in_words; - rko[0] = aes_rot_word(aes_sub_word(rki[key_len_in_words - 1])); - rko[0] ^= rcon[iteration] ^ rki[0]; - rko[1] = rko[0] ^ rki[1]; - rko[2] = rko[1] ^ rki[2]; - rko[3] = rko[2] ^ rki[3]; - if (rko + key_len_in_words > rko_end) { - /* Do not write overflow words.*/ - continue; - } -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - switch (key_bit_length) { - case 128: - break; - case 192: - rko[4] = rko[3] ^ rki[4]; - rko[5] = rko[4] ^ rki[5]; - break; - case 256: - rko[4] = aes_sub_word(rko[3]) ^ rki[4]; - rko[5] = rko[4] ^ rki[5]; - rko[6] = rko[5] ^ rki[6]; - rko[7] = rko[6] ^ rki[7]; - break; - } -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - } -} - -/* - * Key expansion, wrapper - */ -int mbedtls_aesce_setkey_enc(unsigned char *rk, - const unsigned char *key, - size_t bits) -{ - switch (bits) { - case 128: - case 192: - case 256: - aesce_setkey_enc(rk, key, bits); - break; - default: - return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; - } - - return 0; -} - -#if defined(MBEDTLS_GCM_C) - -#if defined(MBEDTLS_ARCH_IS_ARM32) - -#if defined(__clang__) -/* On clang for A32/T32, work around some missing intrinsics and types which are listed in - * [ACLE](https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#polynomial-1) - * These are only required for GCM. - */ -#define vreinterpretq_u64_p64(a) ((uint64x2_t) a) - -typedef uint8x16_t poly128_t; - -static inline poly128_t vmull_p64(poly64_t a, poly64_t b) -{ - poly128_t r; - asm ("vmull.p64 %[r], %[a], %[b]" : [r] "=w" (r) : [a] "w" (a), [b] "w" (b) :); - return r; -} - -/* This is set to cause some more missing intrinsics to be defined below */ -#define COMMON_MISSING_INTRINSICS - -static inline poly128_t vmull_high_p64(poly64x2_t a, poly64x2_t b) -{ - return vmull_p64((poly64_t) (vget_high_u64((uint64x2_t) a)), - (poly64_t) (vget_high_u64((uint64x2_t) b))); -} - -#endif /* defined(__clang__) */ - -static inline uint8x16_t vrbitq_u8(uint8x16_t x) -{ - /* There is no vrbitq_u8 instruction in A32/T32, so provide - * an equivalent non-Neon implementation. Reverse bit order in each - * byte with 4x rbit, rev. */ - asm ("ldm %[p], { r2-r5 } \n\t" - "rbit r2, r2 \n\t" - "rev r2, r2 \n\t" - "rbit r3, r3 \n\t" - "rev r3, r3 \n\t" - "rbit r4, r4 \n\t" - "rev r4, r4 \n\t" - "rbit r5, r5 \n\t" - "rev r5, r5 \n\t" - "stm %[p], { r2-r5 } \n\t" - : - /* Output: 16 bytes of memory pointed to by &x */ - "+m" (*(uint8_t(*)[16]) &x) - : - [p] "r" (&x) - : - "r2", "r3", "r4", "r5" - ); - return x; -} - -#endif /* defined(MBEDTLS_ARCH_IS_ARM32) */ - -#if defined(MBEDTLS_COMPILER_IS_GCC) && __GNUC__ == 5 -/* Some intrinsics are not available for GCC 5.X. */ -#define COMMON_MISSING_INTRINSICS -#endif /* MBEDTLS_COMPILER_IS_GCC && __GNUC__ == 5 */ - - -#if defined(COMMON_MISSING_INTRINSICS) - -/* Missing intrinsics common to both GCC 5, and Clang on 32-bit */ - -#define vreinterpretq_p64_u8(a) ((poly64x2_t) a) -#define vreinterpretq_u8_p128(a) ((uint8x16_t) a) - -static inline poly64x1_t vget_low_p64(poly64x2_t a) -{ - uint64x1_t r = vget_low_u64(vreinterpretq_u64_p64(a)); - return (poly64x1_t) r; - -} - -#endif /* COMMON_MISSING_INTRINSICS */ - -/* vmull_p64/vmull_high_p64 wrappers. - * - * Older compilers miss some intrinsic functions for `poly*_t`. We use - * uint8x16_t and uint8x16x3_t as input/output parameters. - */ -#if defined(MBEDTLS_COMPILER_IS_GCC) -/* GCC reports incompatible type error without cast. GCC think poly64_t and - * poly64x1_t are different, that is different with MSVC and Clang. */ -#define MBEDTLS_VMULL_P64(a, b) vmull_p64((poly64_t) a, (poly64_t) b) -#else -/* MSVC reports `error C2440: 'type cast'` with cast. Clang does not report - * error with/without cast. And I think poly64_t and poly64x1_t are same, no - * cast for clang also. */ -#define MBEDTLS_VMULL_P64(a, b) vmull_p64(a, b) -#endif /* MBEDTLS_COMPILER_IS_GCC */ - -static inline uint8x16_t pmull_low(uint8x16_t a, uint8x16_t b) -{ - - return vreinterpretq_u8_p128( - MBEDTLS_VMULL_P64( - (poly64_t) vget_low_p64(vreinterpretq_p64_u8(a)), - (poly64_t) vget_low_p64(vreinterpretq_p64_u8(b)) - )); -} - -static inline uint8x16_t pmull_high(uint8x16_t a, uint8x16_t b) -{ - return vreinterpretq_u8_p128( - vmull_high_p64(vreinterpretq_p64_u8(a), - vreinterpretq_p64_u8(b))); -} - -/* GHASH does 128b polynomial multiplication on block in GF(2^128) defined by - * `x^128 + x^7 + x^2 + x + 1`. - * - * Arm64 only has 64b->128b polynomial multipliers, we need to do 4 64b - * multiplies to generate a 128b. - * - * `poly_mult_128` executes polynomial multiplication and outputs 256b that - * represented by 3 128b due to code size optimization. - * - * Output layout: - * | | | | - * |------------|-------------|-------------| - * | ret.val[0] | h3:h2:00:00 | high 128b | - * | ret.val[1] | :m2:m1:00 | middle 128b | - * | ret.val[2] | : :l1:l0 | low 128b | - */ -static inline uint8x16x3_t poly_mult_128(uint8x16_t a, uint8x16_t b) -{ - uint8x16x3_t ret; - uint8x16_t h, m, l; /* retval high/middle/low */ - uint8x16_t c, d, e; - - h = pmull_high(a, b); /* h3:h2:00:00 = a1*b1 */ - l = pmull_low(a, b); /* : :l1:l0 = a0*b0 */ - c = vextq_u8(b, b, 8); /* :c1:c0 = b0:b1 */ - d = pmull_high(a, c); /* :d2:d1:00 = a1*b0 */ - e = pmull_low(a, c); /* :e2:e1:00 = a0*b1 */ - m = veorq_u8(d, e); /* :m2:m1:00 = d + e */ - - ret.val[0] = h; - ret.val[1] = m; - ret.val[2] = l; - return ret; -} - -/* - * Modulo reduction. - * - * See: https://www.researchgate.net/publication/285612706_Implementing_GCM_on_ARMv8 - * - * Section 4.3 - * - * Modular reduction is slightly more complex. Write the GCM modulus as f(z) = - * z^128 +r(z), where r(z) = z^7+z^2+z+ 1. The well known approach is to - * consider that z^128 ≡r(z) (mod z^128 +r(z)), allowing us to write the 256-bit - * operand to be reduced as a(z) = h(z)z^128 +l(z)≡h(z)r(z) + l(z). That is, we - * simply multiply the higher part of the operand by r(z) and add it to l(z). If - * the result is still larger than 128 bits, we reduce again. - */ -static inline uint8x16_t poly_mult_reduce(uint8x16x3_t input) -{ - uint8x16_t const ZERO = vdupq_n_u8(0); - - uint64x2_t r = vreinterpretq_u64_u8(vdupq_n_u8(0x87)); -#if defined(__GNUC__) - /* use 'asm' as an optimisation barrier to prevent loading MODULO from - * memory. It is for GNUC compatible compilers. - */ - asm volatile ("" : "+w" (r)); -#endif - uint8x16_t const MODULO = vreinterpretq_u8_u64(vshrq_n_u64(r, 64 - 8)); - uint8x16_t h, m, l; /* input high/middle/low 128b */ - uint8x16_t c, d, e, f, g, n, o; - h = input.val[0]; /* h3:h2:00:00 */ - m = input.val[1]; /* :m2:m1:00 */ - l = input.val[2]; /* : :l1:l0 */ - c = pmull_high(h, MODULO); /* :c2:c1:00 = reduction of h3 */ - d = pmull_low(h, MODULO); /* : :d1:d0 = reduction of h2 */ - e = veorq_u8(c, m); /* :e2:e1:00 = m2:m1:00 + c2:c1:00 */ - f = pmull_high(e, MODULO); /* : :f1:f0 = reduction of e2 */ - g = vextq_u8(ZERO, e, 8); /* : :g1:00 = e1:00 */ - n = veorq_u8(d, l); /* : :n1:n0 = d1:d0 + l1:l0 */ - o = veorq_u8(n, f); /* o1:o0 = f1:f0 + n1:n0 */ - return veorq_u8(o, g); /* = o1:o0 + g1:00 */ -} - -/* - * GCM multiplication: c = a times b in GF(2^128) - */ -void mbedtls_aesce_gcm_mult(unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16]) -{ - uint8x16_t va, vb, vc; - va = vrbitq_u8(vld1q_u8(&a[0])); - vb = vrbitq_u8(vld1q_u8(&b[0])); - vc = vrbitq_u8(poly_mult_reduce(poly_mult_128(va, vb))); - vst1q_u8(&c[0], vc); -} - -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_POP_TARGET_PRAGMA) -#if defined(__clang__) -#pragma clang attribute pop -#elif defined(__GNUC__) -#pragma GCC pop_options -#endif -#undef MBEDTLS_POP_TARGET_PRAGMA -#endif - -#endif /* MBEDTLS_AESCE_HAVE_CODE */ - -#endif /* MBEDTLS_AESCE_C */ diff --git a/vendor/mbedtls/library/aesce.h b/vendor/mbedtls/library/aesce.h deleted file mode 100644 index a14d085ef..000000000 --- a/vendor/mbedtls/library/aesce.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * \file aesce.h - * - * \brief Support hardware AES acceleration on Armv8-A processors with - * the Armv8-A Cryptographic Extension. - * - * \warning These functions are only for internal use by other library - * functions; you must not call them directly. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_AESCE_H -#define MBEDTLS_AESCE_H - -#include "mbedtls/build_info.h" -#include "common.h" - -#include "mbedtls/aes.h" - - -#if defined(MBEDTLS_AESCE_C) \ - && defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_HAVE_NEON_INTRINSICS) \ - && (defined(MBEDTLS_COMPILER_IS_GCC) || defined(__clang__) || defined(MSC_VER)) - -/* MBEDTLS_AESCE_HAVE_CODE is defined if we have a suitable target platform, and a - * potentially suitable compiler (compiler version & flags are not checked when defining - * this). */ -#define MBEDTLS_AESCE_HAVE_CODE - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) - -extern signed char mbedtls_aesce_has_support_result; - -/** - * \brief Internal function to detect the crypto extension in CPUs. - * - * \return 1 if CPU has support for the feature, 0 otherwise - */ -int mbedtls_aesce_has_support_impl(void); - -#define MBEDTLS_AESCE_HAS_SUPPORT() (mbedtls_aesce_has_support_result == -1 ? \ - mbedtls_aesce_has_support_impl() : \ - mbedtls_aesce_has_support_result) - -#else /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */ - -/* If we are not on Linux, we can't detect support so assume that it's supported. - * Similarly, assume support if MBEDTLS_AES_USE_HARDWARE_ONLY is set. - */ -#define MBEDTLS_AESCE_HAS_SUPPORT() 1 - -#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */ - -/** - * \brief Internal AES-ECB block encryption and decryption - * - * \warning This assumes that the context specifies either 10, 12 or 14 - * rounds and will behave incorrectly if this is not the case. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 on success (cannot fail) - */ -int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]); - -/** - * \brief Internal GCM multiplication: c = a * b in GF(2^128) - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param c Result - * \param a First operand - * \param b Second operand - * - * \note Both operands and result are bit strings interpreted as - * elements of GF(2^128) as per the GCM spec. - */ -void mbedtls_aesce_gcm_mult(unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16]); - - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -/** - * \brief Internal round key inversion. This function computes - * decryption round keys from the encryption round keys. - * - * \param invkey Round keys for the equivalent inverse cipher - * \param fwdkey Original round keys (for encryption) - * \param nr Number of rounds (that is, number of round keys minus one) - */ -void mbedtls_aesce_inverse_key(unsigned char *invkey, - const unsigned char *fwdkey, - int nr); -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -/** - * \brief Internal key expansion for encryption - * - * \param rk Destination buffer where the round keys are written - * \param key Encryption key - * \param bits Key size in bits (must be 128, 192 or 256) - * - * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH - */ -int mbedtls_aesce_setkey_enc(unsigned char *rk, - const unsigned char *key, - size_t bits); - -#ifdef __cplusplus -} -#endif - -#else - -#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && defined(MBEDTLS_ARCH_IS_ARMV8_A) -#error "AES hardware acceleration not supported on this platform / compiler" -#endif - -#endif /* MBEDTLS_AESCE_C && MBEDTLS_ARCH_IS_ARMV8_A && MBEDTLS_HAVE_NEON_INTRINSICS && - (MBEDTLS_COMPILER_IS_GCC || __clang__ || MSC_VER) */ - -#endif /* MBEDTLS_AESCE_H */ diff --git a/vendor/mbedtls/library/aesni.c b/vendor/mbedtls/library/aesni.c deleted file mode 100644 index 285706824..000000000 --- a/vendor/mbedtls/library/aesni.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - * AES-NI support functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * [AES-WP] https://www.intel.com/content/www/us/en/developer/articles/tool/intel-advanced-encryption-standard-aes-instructions-set.html - * [CLMUL-WP] https://www.intel.com/content/www/us/en/develop/download/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode.html - */ - -#include "common.h" - -#if defined(MBEDTLS_AESNI_C) - -#include "aesni.h" - -#include - -#if defined(MBEDTLS_AESNI_HAVE_CODE) - -#if MBEDTLS_AESNI_HAVE_CODE == 2 -#if defined(__GNUC__) -#include -#elif defined(_MSC_VER) -#include -#else -#error "`__cpuid` required by MBEDTLS_AESNI_C is not supported by the compiler" -#endif -#include -#endif - -#if defined(MBEDTLS_ARCH_IS_X86) -#if defined(MBEDTLS_COMPILER_IS_GCC) -#pragma GCC push_options -#pragma GCC target ("pclmul,sse2,aes") -#define MBEDTLS_POP_TARGET_PRAGMA -#elif defined(__clang__) && (__clang_major__ >= 5) -#pragma clang attribute push (__attribute__((target("pclmul,sse2,aes"))), apply_to=function) -#define MBEDTLS_POP_TARGET_PRAGMA -#endif -#endif - -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -/* - * AES-NI support detection routine - */ -int mbedtls_aesni_has_support(unsigned int what) -{ - /* To avoid a race condition, tell the compiler that the assignment - * `done = 1` and the assignment to `c` may not be reordered. - * https://github.com/Mbed-TLS/mbedtls/issues/9840 - * - * Note that we may also be worried about memory access reordering, - * but fortunately the x86 memory model is not too wild: stores - * from the same thread are observed consistently by other threads. - * (See example 8-1 in Sewell et al., "x86-TSO: A Rigorous and Usable - * Programmer’s Model for x86 Multiprocessors", CACM, 2010, - * https://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf) - */ - static volatile int done = 0; - static volatile unsigned int c = 0; - - if (!done) { -#if MBEDTLS_AESNI_HAVE_CODE == 2 - static int info[4] = { 0, 0, 0, 0 }; -#if defined(_MSC_VER) - __cpuid(info, 1); -#else - __cpuid(1, info[0], info[1], info[2], info[3]); -#endif - c = info[2]; -#else /* AESNI using asm */ - asm ("movl $1, %%eax \n\t" - "cpuid \n\t" - : "=c" (c) - : - : "eax", "ebx", "edx"); -#endif /* MBEDTLS_AESNI_HAVE_CODE */ - done = 1; - } - - return (c & what) != 0; -} -#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */ - -#if MBEDTLS_AESNI_HAVE_CODE == 2 - -/* - * AES-NI AES-ECB block en(de)cryption - */ -int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]) -{ - const __m128i *rk = (const __m128i *) (ctx->buf + ctx->rk_offset); - unsigned nr = ctx->nr; // Number of remaining rounds - - // Load round key 0 - __m128i state; - memcpy(&state, input, 16); - state = _mm_xor_si128(state, rk[0]); // state ^= *rk; - ++rk; - --nr; - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (mode == MBEDTLS_AES_DECRYPT) { - while (nr != 0) { - state = _mm_aesdec_si128(state, *rk); - ++rk; - --nr; - } - state = _mm_aesdeclast_si128(state, *rk); - } else -#else - (void) mode; -#endif - { - while (nr != 0) { - state = _mm_aesenc_si128(state, *rk); - ++rk; - --nr; - } - state = _mm_aesenclast_si128(state, *rk); - } - - memcpy(output, &state, 16); - return 0; -} - -/* - * GCM multiplication: c = a times b in GF(2^128) - * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. - */ - -static void gcm_clmul(const __m128i aa, const __m128i bb, - __m128i *cc, __m128i *dd) -{ - /* - * Caryless multiplication dd:cc = aa * bb - * using [CLMUL-WP] algorithm 1 (p. 12). - */ - *cc = _mm_clmulepi64_si128(aa, bb, 0x00); // a0*b0 = c1:c0 - *dd = _mm_clmulepi64_si128(aa, bb, 0x11); // a1*b1 = d1:d0 - __m128i ee = _mm_clmulepi64_si128(aa, bb, 0x10); // a0*b1 = e1:e0 - __m128i ff = _mm_clmulepi64_si128(aa, bb, 0x01); // a1*b0 = f1:f0 - ff = _mm_xor_si128(ff, ee); // e1+f1:e0+f0 - ee = ff; // e1+f1:e0+f0 - ff = _mm_srli_si128(ff, 8); // 0:e1+f1 - ee = _mm_slli_si128(ee, 8); // e0+f0:0 - *dd = _mm_xor_si128(*dd, ff); // d1:d0+e1+f1 - *cc = _mm_xor_si128(*cc, ee); // c1+e0+f0:c0 -} - -static void gcm_shift(__m128i *cc, __m128i *dd) -{ - /* [CMUCL-WP] Algorithm 5 Step 1: shift cc:dd one bit to the left, - * taking advantage of [CLMUL-WP] eq 27 (p. 18). */ - // // *cc = r1:r0 - // // *dd = r3:r2 - __m128i cc_lo = _mm_slli_epi64(*cc, 1); // r1<<1:r0<<1 - __m128i dd_lo = _mm_slli_epi64(*dd, 1); // r3<<1:r2<<1 - __m128i cc_hi = _mm_srli_epi64(*cc, 63); // r1>>63:r0>>63 - __m128i dd_hi = _mm_srli_epi64(*dd, 63); // r3>>63:r2>>63 - __m128i xmm5 = _mm_srli_si128(cc_hi, 8); // 0:r1>>63 - cc_hi = _mm_slli_si128(cc_hi, 8); // r0>>63:0 - dd_hi = _mm_slli_si128(dd_hi, 8); // 0:r1>>63 - - *cc = _mm_or_si128(cc_lo, cc_hi); // r1<<1|r0>>63:r0<<1 - *dd = _mm_or_si128(_mm_or_si128(dd_lo, dd_hi), xmm5); // r3<<1|r2>>62:r2<<1|r1>>63 -} - -static __m128i gcm_reduce(__m128i xx) -{ - // // xx = x1:x0 - /* [CLMUL-WP] Algorithm 5 Step 2 */ - __m128i aa = _mm_slli_epi64(xx, 63); // x1<<63:x0<<63 = stuff:a - __m128i bb = _mm_slli_epi64(xx, 62); // x1<<62:x0<<62 = stuff:b - __m128i cc = _mm_slli_epi64(xx, 57); // x1<<57:x0<<57 = stuff:c - __m128i dd = _mm_slli_si128(_mm_xor_si128(_mm_xor_si128(aa, bb), cc), 8); // a+b+c:0 - return _mm_xor_si128(dd, xx); // x1+a+b+c:x0 = d:x0 -} - -static __m128i gcm_mix(__m128i dx) -{ - /* [CLMUL-WP] Algorithm 5 Steps 3 and 4 */ - __m128i ee = _mm_srli_epi64(dx, 1); // e1:x0>>1 = e1:e0' - __m128i ff = _mm_srli_epi64(dx, 2); // f1:x0>>2 = f1:f0' - __m128i gg = _mm_srli_epi64(dx, 7); // g1:x0>>7 = g1:g0' - - // e0'+f0'+g0' is almost e0+f0+g0, except for some missing - // bits carried from d. Now get those bits back in. - __m128i eh = _mm_slli_epi64(dx, 63); // d<<63:stuff - __m128i fh = _mm_slli_epi64(dx, 62); // d<<62:stuff - __m128i gh = _mm_slli_epi64(dx, 57); // d<<57:stuff - __m128i hh = _mm_srli_si128(_mm_xor_si128(_mm_xor_si128(eh, fh), gh), 8); // 0:missing bits of d - - return _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(_mm_xor_si128(ee, ff), gg), hh), dx); -} - -void mbedtls_aesni_gcm_mult(unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16]) -{ - __m128i aa = { 0 }, bb = { 0 }, cc, dd; - - /* The inputs are in big-endian order, so byte-reverse them */ - for (size_t i = 0; i < 16; i++) { - ((uint8_t *) &aa)[i] = a[15 - i]; - ((uint8_t *) &bb)[i] = b[15 - i]; - } - - gcm_clmul(aa, bb, &cc, &dd); - gcm_shift(&cc, &dd); - /* - * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 - * using [CLMUL-WP] algorithm 5 (p. 18). - * Currently dd:cc holds x3:x2:x1:x0 (already shifted). - */ - __m128i dx = gcm_reduce(cc); - __m128i xh = gcm_mix(dx); - cc = _mm_xor_si128(xh, dd); // x3+h1:x2+h0 - - /* Now byte-reverse the outputs */ - for (size_t i = 0; i < 16; i++) { - c[i] = ((uint8_t *) &cc)[15 - i]; - } - - return; -} - -/* - * Compute decryption round keys from encryption round keys - */ -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -void mbedtls_aesni_inverse_key(unsigned char *invkey, - const unsigned char *fwdkey, int nr) -{ - __m128i *ik = (__m128i *) invkey; - const __m128i *fk = (const __m128i *) fwdkey + nr; - - *ik = *fk; - for (--fk, ++ik; fk > (const __m128i *) fwdkey; --fk, ++ik) { - *ik = _mm_aesimc_si128(*fk); - } - *ik = *fk; -} -#endif - -/* - * Key expansion, 128-bit case - */ -static __m128i aesni_set_rk_128(__m128i state, __m128i xword) -{ - /* - * Finish generating the next round key. - * - * On entry state is r3:r2:r1:r0 and xword is X:stuff:stuff:stuff - * with X = rot( sub( r3 ) ) ^ RCON (obtained with AESKEYGENASSIST). - * - * On exit, xword is r7:r6:r5:r4 - * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 - * and this is returned, to be written to the round key buffer. - */ - xword = _mm_shuffle_epi32(xword, 0xff); // X:X:X:X - xword = _mm_xor_si128(xword, state); // X+r3:X+r2:X+r1:r4 - state = _mm_slli_si128(state, 4); // r2:r1:r0:0 - xword = _mm_xor_si128(xword, state); // X+r3+r2:X+r2+r1:r5:r4 - state = _mm_slli_si128(state, 4); // r1:r0:0:0 - xword = _mm_xor_si128(xword, state); // X+r3+r2+r1:r6:r5:r4 - state = _mm_slli_si128(state, 4); // r0:0:0:0 - state = _mm_xor_si128(xword, state); // r7:r6:r5:r4 - return state; -} - -static void aesni_setkey_enc_128(unsigned char *rk_bytes, - const unsigned char *key) -{ - __m128i *rk = (__m128i *) rk_bytes; - - memcpy(&rk[0], key, 16); - rk[1] = aesni_set_rk_128(rk[0], _mm_aeskeygenassist_si128(rk[0], 0x01)); - rk[2] = aesni_set_rk_128(rk[1], _mm_aeskeygenassist_si128(rk[1], 0x02)); - rk[3] = aesni_set_rk_128(rk[2], _mm_aeskeygenassist_si128(rk[2], 0x04)); - rk[4] = aesni_set_rk_128(rk[3], _mm_aeskeygenassist_si128(rk[3], 0x08)); - rk[5] = aesni_set_rk_128(rk[4], _mm_aeskeygenassist_si128(rk[4], 0x10)); - rk[6] = aesni_set_rk_128(rk[5], _mm_aeskeygenassist_si128(rk[5], 0x20)); - rk[7] = aesni_set_rk_128(rk[6], _mm_aeskeygenassist_si128(rk[6], 0x40)); - rk[8] = aesni_set_rk_128(rk[7], _mm_aeskeygenassist_si128(rk[7], 0x80)); - rk[9] = aesni_set_rk_128(rk[8], _mm_aeskeygenassist_si128(rk[8], 0x1B)); - rk[10] = aesni_set_rk_128(rk[9], _mm_aeskeygenassist_si128(rk[9], 0x36)); -} - -/* - * Key expansion, 192-bit case - */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static void aesni_set_rk_192(__m128i *state0, __m128i *state1, __m128i xword, - unsigned char *rk) -{ - /* - * Finish generating the next 6 quarter-keys. - * - * On entry state0 is r3:r2:r1:r0, state1 is stuff:stuff:r5:r4 - * and xword is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON - * (obtained with AESKEYGENASSIST). - * - * On exit, state0 is r9:r8:r7:r6 and state1 is stuff:stuff:r11:r10 - * and those are written to the round key buffer. - */ - xword = _mm_shuffle_epi32(xword, 0x55); // X:X:X:X - xword = _mm_xor_si128(xword, *state0); // X+r3:X+r2:X+r1:X+r0 - *state0 = _mm_slli_si128(*state0, 4); // r2:r1:r0:0 - xword = _mm_xor_si128(xword, *state0); // X+r3+r2:X+r2+r1:X+r1+r0:X+r0 - *state0 = _mm_slli_si128(*state0, 4); // r1:r0:0:0 - xword = _mm_xor_si128(xword, *state0); // X+r3+r2+r1:X+r2+r1+r0:X+r1+r0:X+r0 - *state0 = _mm_slli_si128(*state0, 4); // r0:0:0:0 - xword = _mm_xor_si128(xword, *state0); // X+r3+r2+r1+r0:X+r2+r1+r0:X+r1+r0:X+r0 - *state0 = xword; // = r9:r8:r7:r6 - - xword = _mm_shuffle_epi32(xword, 0xff); // r9:r9:r9:r9 - xword = _mm_xor_si128(xword, *state1); // stuff:stuff:r9+r5:r9+r4 - *state1 = _mm_slli_si128(*state1, 4); // stuff:stuff:r4:0 - xword = _mm_xor_si128(xword, *state1); // stuff:stuff:r9+r5+r4:r9+r4 - *state1 = xword; // = stuff:stuff:r11:r10 - - /* Store state0 and the low half of state1 into rk, which is conceptually - * an array of 24-byte elements. Since 24 is not a multiple of 16, - * rk is not necessarily aligned so just `*rk = *state0` doesn't work. */ - memcpy(rk, state0, 16); - memcpy(rk + 16, state1, 8); -} - -static void aesni_setkey_enc_192(unsigned char *rk, - const unsigned char *key) -{ - /* First round: use original key */ - memcpy(rk, key, 24); - /* aes.c guarantees that rk is aligned on a 16-byte boundary. */ - __m128i state0 = ((__m128i *) rk)[0]; - __m128i state1 = _mm_loadl_epi64(((__m128i *) rk) + 1); - - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x01), rk + 24 * 1); - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x02), rk + 24 * 2); - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x04), rk + 24 * 3); - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x08), rk + 24 * 4); - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x10), rk + 24 * 5); - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x20), rk + 24 * 6); - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x40), rk + 24 * 7); - aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x80), rk + 24 * 8); -} -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - -/* - * Key expansion, 256-bit case - */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static void aesni_set_rk_256(__m128i state0, __m128i state1, __m128i xword, - __m128i *rk0, __m128i *rk1) -{ - /* - * Finish generating the next two round keys. - * - * On entry state0 is r3:r2:r1:r0, state1 is r7:r6:r5:r4 and - * xword is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON - * (obtained with AESKEYGENASSIST). - * - * On exit, *rk0 is r11:r10:r9:r8 and *rk1 is r15:r14:r13:r12 - */ - xword = _mm_shuffle_epi32(xword, 0xff); - xword = _mm_xor_si128(xword, state0); - state0 = _mm_slli_si128(state0, 4); - xword = _mm_xor_si128(xword, state0); - state0 = _mm_slli_si128(state0, 4); - xword = _mm_xor_si128(xword, state0); - state0 = _mm_slli_si128(state0, 4); - state0 = _mm_xor_si128(state0, xword); - *rk0 = state0; - - /* Set xword to stuff:Y:stuff:stuff with Y = subword( r11 ) - * and proceed to generate next round key from there */ - xword = _mm_aeskeygenassist_si128(state0, 0x00); - xword = _mm_shuffle_epi32(xword, 0xaa); - xword = _mm_xor_si128(xword, state1); - state1 = _mm_slli_si128(state1, 4); - xword = _mm_xor_si128(xword, state1); - state1 = _mm_slli_si128(state1, 4); - xword = _mm_xor_si128(xword, state1); - state1 = _mm_slli_si128(state1, 4); - state1 = _mm_xor_si128(state1, xword); - *rk1 = state1; -} - -static void aesni_setkey_enc_256(unsigned char *rk_bytes, - const unsigned char *key) -{ - __m128i *rk = (__m128i *) rk_bytes; - - memcpy(&rk[0], key, 16); - memcpy(&rk[1], key + 16, 16); - - /* - * Main "loop" - Generating one more key than necessary, - * see definition of mbedtls_aes_context.buf - */ - aesni_set_rk_256(rk[0], rk[1], _mm_aeskeygenassist_si128(rk[1], 0x01), &rk[2], &rk[3]); - aesni_set_rk_256(rk[2], rk[3], _mm_aeskeygenassist_si128(rk[3], 0x02), &rk[4], &rk[5]); - aesni_set_rk_256(rk[4], rk[5], _mm_aeskeygenassist_si128(rk[5], 0x04), &rk[6], &rk[7]); - aesni_set_rk_256(rk[6], rk[7], _mm_aeskeygenassist_si128(rk[7], 0x08), &rk[8], &rk[9]); - aesni_set_rk_256(rk[8], rk[9], _mm_aeskeygenassist_si128(rk[9], 0x10), &rk[10], &rk[11]); - aesni_set_rk_256(rk[10], rk[11], _mm_aeskeygenassist_si128(rk[11], 0x20), &rk[12], &rk[13]); - aesni_set_rk_256(rk[12], rk[13], _mm_aeskeygenassist_si128(rk[13], 0x40), &rk[14], &rk[15]); -} -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - -#if defined(MBEDTLS_POP_TARGET_PRAGMA) -#if defined(__clang__) -#pragma clang attribute pop -#elif defined(__GNUC__) -#pragma GCC pop_options -#endif -#undef MBEDTLS_POP_TARGET_PRAGMA -#endif - -#else /* MBEDTLS_AESNI_HAVE_CODE == 1 */ - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) -#warning \ - "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code." -#endif -#endif - -/* - * Binutils needs to be at least 2.19 to support AES-NI instructions. - * Unfortunately, a lot of users have a lower version now (2014-04). - * Emit bytecode directly in order to support "old" version of gas. - * - * Opcodes from the Intel architecture reference manual, vol. 3. - * We always use registers, so we don't need prefixes for memory operands. - * Operand macros are in gas order (src, dst) as opposed to Intel order - * (dst, src) in order to blend better into the surrounding assembly code. - */ -#define AESDEC(regs) ".byte 0x66,0x0F,0x38,0xDE," regs "\n\t" -#define AESDECLAST(regs) ".byte 0x66,0x0F,0x38,0xDF," regs "\n\t" -#define AESENC(regs) ".byte 0x66,0x0F,0x38,0xDC," regs "\n\t" -#define AESENCLAST(regs) ".byte 0x66,0x0F,0x38,0xDD," regs "\n\t" -#define AESIMC(regs) ".byte 0x66,0x0F,0x38,0xDB," regs "\n\t" -#define AESKEYGENA(regs, imm) ".byte 0x66,0x0F,0x3A,0xDF," regs "," imm "\n\t" -#define PCLMULQDQ(regs, imm) ".byte 0x66,0x0F,0x3A,0x44," regs "," imm "\n\t" - -#define xmm0_xmm0 "0xC0" -#define xmm0_xmm1 "0xC8" -#define xmm0_xmm2 "0xD0" -#define xmm0_xmm3 "0xD8" -#define xmm0_xmm4 "0xE0" -#define xmm1_xmm0 "0xC1" -#define xmm1_xmm2 "0xD1" - -/* - * AES-NI AES-ECB block en(de)cryption - */ -int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]) -{ - asm ("movdqu (%3), %%xmm0 \n\t" // load input - "movdqu (%1), %%xmm1 \n\t" // load round key 0 - "pxor %%xmm1, %%xmm0 \n\t" // round 0 - "add $16, %1 \n\t" // point to next round key - "subl $1, %0 \n\t" // normal rounds = nr - 1 - "test %2, %2 \n\t" // mode? - "jz 2f \n\t" // 0 = decrypt - - "1: \n\t" // encryption loop - "movdqu (%1), %%xmm1 \n\t" // load round key - AESENC(xmm1_xmm0) // do round - "add $16, %1 \n\t" // point to next round key - "subl $1, %0 \n\t" // loop - "jnz 1b \n\t" - "movdqu (%1), %%xmm1 \n\t" // load round key - AESENCLAST(xmm1_xmm0) // last round -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - "jmp 3f \n\t" - - "2: \n\t" // decryption loop - "movdqu (%1), %%xmm1 \n\t" - AESDEC(xmm1_xmm0) // do round - "add $16, %1 \n\t" - "subl $1, %0 \n\t" - "jnz 2b \n\t" - "movdqu (%1), %%xmm1 \n\t" // load round key - AESDECLAST(xmm1_xmm0) // last round -#endif - - "3: \n\t" - "movdqu %%xmm0, (%4) \n\t" // export output - : - : "r" (ctx->nr), "r" (ctx->buf + ctx->rk_offset), "r" (mode), "r" (input), "r" (output) - : "memory", "cc", "xmm0", "xmm1", "0", "1"); - - - return 0; -} - -/* - * GCM multiplication: c = a times b in GF(2^128) - * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. - */ -void mbedtls_aesni_gcm_mult(unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16]) -{ - unsigned char aa[16], bb[16], cc[16]; - size_t i; - - /* The inputs are in big-endian order, so byte-reverse them */ - for (i = 0; i < 16; i++) { - aa[i] = a[15 - i]; - bb[i] = b[15 - i]; - } - - asm ("movdqu (%0), %%xmm0 \n\t" // a1:a0 - "movdqu (%1), %%xmm1 \n\t" // b1:b0 - - /* - * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 - * using [CLMUL-WP] algorithm 1 (p. 12). - */ - "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 - "movdqa %%xmm1, %%xmm3 \n\t" // same - "movdqa %%xmm1, %%xmm4 \n\t" // same - PCLMULQDQ(xmm0_xmm1, "0x00") // a0*b0 = c1:c0 - PCLMULQDQ(xmm0_xmm2, "0x11") // a1*b1 = d1:d0 - PCLMULQDQ(xmm0_xmm3, "0x10") // a0*b1 = e1:e0 - PCLMULQDQ(xmm0_xmm4, "0x01") // a1*b0 = f1:f0 - "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 - "movdqa %%xmm4, %%xmm3 \n\t" // same - "psrldq $8, %%xmm4 \n\t" // 0:e1+f1 - "pslldq $8, %%xmm3 \n\t" // e0+f0:0 - "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 - "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 - - /* - * Now shift the result one bit to the left, - * taking advantage of [CLMUL-WP] eq 27 (p. 18) - */ - "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 - "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 - "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 - "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 - "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 - "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 - "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 - "pslldq $8, %%xmm3 \n\t" // r0>>63:0 - "pslldq $8, %%xmm4 \n\t" // r2>>63:0 - "psrldq $8, %%xmm5 \n\t" // 0:r1>>63 - "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 - "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 - "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 - - /* - * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 - * using [CLMUL-WP] algorithm 5 (p. 18). - * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). - */ - /* Step 2 (1) */ - "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 - "movdqa %%xmm1, %%xmm4 \n\t" // same - "movdqa %%xmm1, %%xmm5 \n\t" // same - "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a - "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b - "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c - - /* Step 2 (2) */ - "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b - "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c - "pslldq $8, %%xmm3 \n\t" // a+b+c:0 - "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 - - /* Steps 3 and 4 */ - "movdqa %%xmm1,%%xmm0 \n\t" // d:x0 - "movdqa %%xmm1,%%xmm4 \n\t" // same - "movdqa %%xmm1,%%xmm5 \n\t" // same - "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' - "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' - "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' - "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' - "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' - // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing - // bits carried from d. Now get those\t bits back in. - "movdqa %%xmm1,%%xmm3 \n\t" // d:x0 - "movdqa %%xmm1,%%xmm4 \n\t" // same - "movdqa %%xmm1,%%xmm5 \n\t" // same - "psllq $63, %%xmm3 \n\t" // d<<63:stuff - "psllq $62, %%xmm4 \n\t" // d<<62:stuff - "psllq $57, %%xmm5 \n\t" // d<<57:stuff - "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff - "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff - "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d - "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 - "pxor %%xmm1, %%xmm0 \n\t" // h1:h0 - "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 - - "movdqu %%xmm0, (%2) \n\t" // done - : - : "r" (aa), "r" (bb), "r" (cc) - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); - - /* Now byte-reverse the outputs */ - for (i = 0; i < 16; i++) { - c[i] = cc[15 - i]; - } - - return; -} - -/* - * Compute decryption round keys from encryption round keys - */ -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -void mbedtls_aesni_inverse_key(unsigned char *invkey, - const unsigned char *fwdkey, int nr) -{ - unsigned char *ik = invkey; - const unsigned char *fk = fwdkey + 16 * nr; - - memcpy(ik, fk, 16); - - for (fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16) { - asm ("movdqu (%0), %%xmm0 \n\t" - AESIMC(xmm0_xmm0) - "movdqu %%xmm0, (%1) \n\t" - : - : "r" (fk), "r" (ik) - : "memory", "xmm0"); - } - - memcpy(ik, fk, 16); -} -#endif - -/* - * Key expansion, 128-bit case - */ -static void aesni_setkey_enc_128(unsigned char *rk, - const unsigned char *key) -{ - asm ("movdqu (%1), %%xmm0 \n\t" // copy the original key - "movdqu %%xmm0, (%0) \n\t" // as round key 0 - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next round key. - * - * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff - * with X = rot( sub( r3 ) ) ^ RCON. - * - * On exit, xmm0 is r7:r6:r5:r4 - * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 - * and those are written to the round key buffer. - */ - "1: \n\t" - "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X - "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 - "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 - "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 - "pslldq $4, %%xmm0 \n\t" // etc - "pxor %%xmm0, %%xmm1 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! - "add $16, %0 \n\t" // point to next round key - "movdqu %%xmm0, (%0) \n\t" // write it - "ret \n\t" - - /* Main "loop" */ - "2: \n\t" - AESKEYGENA(xmm0_xmm1, "0x01") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x02") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x04") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x08") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x10") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x20") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x40") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x80") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x1B") "call 1b \n\t" - AESKEYGENA(xmm0_xmm1, "0x36") "call 1b \n\t" - : - : "r" (rk), "r" (key) - : "memory", "cc", "xmm0", "xmm1", "0"); -} - -/* - * Key expansion, 192-bit case - */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static void aesni_setkey_enc_192(unsigned char *rk, - const unsigned char *key) -{ - asm ("movdqu (%1), %%xmm0 \n\t" // copy original round key - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "movq 16(%1), %%xmm1 \n\t" - "movq %%xmm1, (%0) \n\t" - "add $8, %0 \n\t" - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next 6 quarter-keys. - * - * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 - * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. - * - * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 - * and those are written to the round key buffer. - */ - "1: \n\t" - "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X - "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 - "pslldq $4, %%xmm0 \n\t" // etc - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 - "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 - "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 - "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 - "movq %%xmm1, (%0) \n\t" - "add $8, %0 \n\t" - "ret \n\t" - - "2: \n\t" - AESKEYGENA(xmm1_xmm2, "0x01") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x02") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x04") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x08") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x10") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x20") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x40") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x80") "call 1b \n\t" - - : - : "r" (rk), "r" (key) - : "memory", "cc", "xmm0", "xmm1", "xmm2", "0"); -} -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - -/* - * Key expansion, 256-bit case - */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static void aesni_setkey_enc_256(unsigned char *rk, - const unsigned char *key) -{ - asm ("movdqu (%1), %%xmm0 \n\t" - "movdqu %%xmm0, (%0) \n\t" - "add $16, %0 \n\t" - "movdqu 16(%1), %%xmm1 \n\t" - "movdqu %%xmm1, (%0) \n\t" - "jmp 2f \n\t" // skip auxiliary routine - - /* - * Finish generating the next two round keys. - * - * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and - * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON - * - * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 - * and those have been written to the output buffer. - */ - "1: \n\t" - "pshufd $0xff, %%xmm2, %%xmm2 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm0, %%xmm2 \n\t" - "pslldq $4, %%xmm0 \n\t" - "pxor %%xmm2, %%xmm0 \n\t" - "add $16, %0 \n\t" - "movdqu %%xmm0, (%0) \n\t" - - /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) - * and proceed to generate next round key from there */ - AESKEYGENA(xmm0_xmm2, "0x00") - "pshufd $0xaa, %%xmm2, %%xmm2 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm1, %%xmm2 \n\t" - "pslldq $4, %%xmm1 \n\t" - "pxor %%xmm2, %%xmm1 \n\t" - "add $16, %0 \n\t" - "movdqu %%xmm1, (%0) \n\t" - "ret \n\t" - - /* - * Main "loop" - Generating one more key than necessary, - * see definition of mbedtls_aes_context.buf - */ - "2: \n\t" - AESKEYGENA(xmm1_xmm2, "0x01") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x02") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x04") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x08") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x10") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x20") "call 1b \n\t" - AESKEYGENA(xmm1_xmm2, "0x40") "call 1b \n\t" - : - : "r" (rk), "r" (key) - : "memory", "cc", "xmm0", "xmm1", "xmm2", "0"); -} -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - -#endif /* MBEDTLS_AESNI_HAVE_CODE */ - -/* - * Key expansion, wrapper - */ -int mbedtls_aesni_setkey_enc(unsigned char *rk, - const unsigned char *key, - size_t bits) -{ - switch (bits) { - case 128: aesni_setkey_enc_128(rk, key); break; -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - case 192: aesni_setkey_enc_192(rk, key); break; - case 256: aesni_setkey_enc_256(rk, key); break; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; - } - - return 0; -} - -#endif /* MBEDTLS_AESNI_HAVE_CODE */ - -#endif /* MBEDTLS_AESNI_C */ diff --git a/vendor/mbedtls/library/aesni.h b/vendor/mbedtls/library/aesni.h deleted file mode 100644 index 59e27afd3..000000000 --- a/vendor/mbedtls/library/aesni.h +++ /dev/null @@ -1,162 +0,0 @@ -/** - * \file aesni.h - * - * \brief AES-NI for hardware AES acceleration on some Intel processors - * - * \warning These functions are only for internal use by other library - * functions; you must not call them directly. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_AESNI_H -#define MBEDTLS_AESNI_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/aes.h" - -#define MBEDTLS_AESNI_AES 0x02000000u -#define MBEDTLS_AESNI_CLMUL 0x00000002u - -#if defined(MBEDTLS_AESNI_C) && \ - (defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_X86)) - -/* Can we do AESNI with intrinsics? - * (Only implemented with certain compilers, only for certain targets.) - */ -#undef MBEDTLS_AESNI_HAVE_INTRINSICS -#if defined(_MSC_VER) && !defined(__clang__) -/* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support - * VS 2013 and up for other reasons anyway, so no need to check the version. */ -#define MBEDTLS_AESNI_HAVE_INTRINSICS -#endif -/* GCC-like compilers: currently, we only support intrinsics if the requisite - * target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2` - * or `clang -maes -mpclmul`). */ -#if (defined(__GNUC__) || defined(__clang__)) && defined(__AES__) && defined(__PCLMUL__) -#define MBEDTLS_AESNI_HAVE_INTRINSICS -#endif -/* For 32-bit, we only support intrinsics */ -#if defined(MBEDTLS_ARCH_IS_X86) && (defined(__GNUC__) || defined(__clang__)) -#define MBEDTLS_AESNI_HAVE_INTRINSICS -#endif - -/* Choose the implementation of AESNI, if one is available. - * - * Favor the intrinsics-based implementation if it's available, for better - * maintainability. - * Performance is about the same (see #7380). - * In the long run, we will likely remove the assembly implementation. */ -#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS) -#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics -#elif defined(MBEDTLS_HAVE_ASM) && \ - (defined(__GNUC__) || defined(__clang__)) && defined(MBEDTLS_ARCH_IS_X64) -/* Can we do AESNI with inline assembly? - * (Only implemented with gas syntax, only for 64-bit.) - */ -#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly -#else -#error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available" -#endif - -#if defined(MBEDTLS_AESNI_HAVE_CODE) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Internal function to detect the AES-NI feature in CPUs. - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param what The feature to detect - * (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL) - * - * \return 1 if CPU has support for the feature, 0 otherwise - */ -#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) -int mbedtls_aesni_has_support(unsigned int what); -#else -#define mbedtls_aesni_has_support(what) 1 -#endif - -/** - * \brief Internal AES-NI AES-ECB block encryption and decryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 on success (cannot fail) - */ -int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]); - -/** - * \brief Internal GCM multiplication: c = a * b in GF(2^128) - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param c Result - * \param a First operand - * \param b Second operand - * - * \note Both operands and result are bit strings interpreted as - * elements of GF(2^128) as per the GCM spec. - */ -void mbedtls_aesni_gcm_mult(unsigned char c[16], - const unsigned char a[16], - const unsigned char b[16]); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -/** - * \brief Internal round key inversion. This function computes - * decryption round keys from the encryption round keys. - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param invkey Round keys for the equivalent inverse cipher - * \param fwdkey Original round keys (for encryption) - * \param nr Number of rounds (that is, number of round keys minus one) - */ -void mbedtls_aesni_inverse_key(unsigned char *invkey, - const unsigned char *fwdkey, - int nr); -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -/** - * \brief Internal key expansion for encryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param rk Destination buffer where the round keys are written - * \param key Encryption key - * \param bits Key size in bits (must be 128, 192 or 256) - * - * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH - */ -int mbedtls_aesni_setkey_enc(unsigned char *rk, - const unsigned char *key, - size_t bits); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_AESNI_HAVE_CODE */ -#endif /* MBEDTLS_AESNI_C && (MBEDTLS_ARCH_IS_X64 || MBEDTLS_ARCH_IS_X86) */ - -#endif /* MBEDTLS_AESNI_H */ diff --git a/vendor/mbedtls/library/alignment.h b/vendor/mbedtls/library/alignment.h deleted file mode 100644 index d30413338..000000000 --- a/vendor/mbedtls/library/alignment.h +++ /dev/null @@ -1,687 +0,0 @@ -/** - * \file alignment.h - * - * \brief Utility code for dealing with unaligned memory accesses - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H -#define MBEDTLS_LIBRARY_ALIGNMENT_H - -#include -#include -#include - -#if !defined(MBEDTLS_ALIGNMENT_DISABLE_EFFICENT_UNALIGNED_ACCESS) //no-check-names -/* - * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory - * accesses are known to be efficient. - * - * All functions defined here will behave correctly regardless, but might be less - * efficient when this is not defined. - */ -#if defined(__ARM_FEATURE_UNALIGNED) \ - || defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \ - || defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) -/* - * __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9 - * (and later versions) for Arm v7 and later; all x86 platforms should have - * efficient unaligned access. - * - * https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment - * specifies that on Windows-on-Arm64, unaligned access is safe (except for uncached - * device memory). - */ -#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS -#endif /* __ARM_FEATURE_UNALIGNED || MBEDTLS_ARCH_IS_X86 || MBEDTLS_ARCH_IS_X64 || - * MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64 */ -#endif /* MBEDTLS_ALIGNMENT_DISABLE_EFFICENT_UNALIGNED_ACCESS */ //no-check-names - -#if defined(__IAR_SYSTEMS_ICC__) && \ - (defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \ - || defined(__ICCRX__) || defined(__ICCRL78__) || defined(__ICCRISCV__)) -#pragma language=save -#pragma language=extended -#define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA -/* IAR recommend this technique for accessing unaligned data in - * https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data - * This results in a single load / store instruction (if unaligned access is supported). - * According to that document, this is only supported on certain architectures. - */ - #define UINT_UNALIGNED -typedef uint16_t __packed mbedtls_uint16_unaligned_t; -typedef uint32_t __packed mbedtls_uint32_unaligned_t; -typedef uint64_t __packed mbedtls_uint64_unaligned_t; -#elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \ - ((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS))) -/* - * gcc may generate a branch to memcpy for calls like `memcpy(dest, src, 4)` rather than - * generating some LDR or LDRB instructions (similar for stores). - * - * This is architecture dependent: x86-64 seems fine even with old gcc; 32-bit Arm - * is affected. To keep it simple, we enable for all architectures. - * - * For versions of gcc < 5.4.0 this issue always happens. - * For gcc < 6.3.0, this issue happens at -O0 - * For all versions, this issue happens iff unaligned access is not supported. - * - * For gcc 4.x, this implementation will generate byte-by-byte loads even if unaligned access is - * supported, which is correct but not optimal. - * - * For performance (and code size, in some cases), we want to avoid the branch and just generate - * some inline load/store instructions since the access is small and constant-size. - * - * The manual states: - * "The packed attribute specifies that a variable or structure field should have the smallest - * possible alignment—one byte for a variable" - * https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Variable-Attributes.html - * - * Previous implementations used __attribute__((__aligned__(1)), but had issues with a gcc bug: - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662 - * - * Tested with several versions of GCC from 4.5.0 up to 13.2.0 - * We don't enable for older than 4.5.0 as this has not been tested. - */ - #define UINT_UNALIGNED_STRUCT -typedef struct { - uint16_t x; -} __attribute__((packed, may_alias)) mbedtls_uint16_unaligned_t; -typedef struct { - uint32_t x; -} __attribute__((packed, may_alias)) mbedtls_uint32_unaligned_t; -typedef struct { - uint64_t x; -} __attribute__((packed, may_alias)) mbedtls_uint64_unaligned_t; - #endif - -/* - * We try to force mbedtls_(get|put)_unaligned_uintXX to be always inline, because this results - * in code that is both smaller and faster. IAR and gcc both benefit from this when optimising - * for size. - */ - -/** - * Read the unsigned 16 bits integer from the given address, which need not - * be aligned. - * - * \param p pointer to 2 bytes of data - * \return Data at the given address - */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -static inline uint16_t mbedtls_get_unaligned_uint16(const void *p) -{ - uint16_t r; -#if defined(UINT_UNALIGNED) - mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p; - r = *p16; -#elif defined(UINT_UNALIGNED_STRUCT) - mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p; - r = p16->x; -#else - memcpy(&r, p, sizeof(r)); -#endif - return r; -} - -/** - * Write the unsigned 16 bits integer to the given address, which need not - * be aligned. - * - * \param p pointer to 2 bytes of data - * \param x data to write - */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x) -{ -#if defined(UINT_UNALIGNED) - mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p; - *p16 = x; -#elif defined(UINT_UNALIGNED_STRUCT) - mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p; - p16->x = x; -#else - memcpy(p, &x, sizeof(x)); -#endif -} - -/** - * Read the unsigned 32 bits integer from the given address, which need not - * be aligned. - * - * \param p pointer to 4 bytes of data - * \return Data at the given address - */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -static inline uint32_t mbedtls_get_unaligned_uint32(const void *p) -{ - uint32_t r; -#if defined(UINT_UNALIGNED) - mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; - r = *p32; -#elif defined(UINT_UNALIGNED_STRUCT) - mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; - r = p32->x; -#else - memcpy(&r, p, sizeof(r)); -#endif - return r; -} - -/** - * Write the unsigned 32 bits integer to the given address, which need not - * be aligned. - * - * \param p pointer to 4 bytes of data - * \param x data to write - */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) -{ -#if defined(UINT_UNALIGNED) - mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; - *p32 = x; -#elif defined(UINT_UNALIGNED_STRUCT) - mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; - p32->x = x; -#else - memcpy(p, &x, sizeof(x)); -#endif -} - -/** - * Read the unsigned 64 bits integer from the given address, which need not - * be aligned. - * - * \param p pointer to 8 bytes of data - * \return Data at the given address - */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -static inline uint64_t mbedtls_get_unaligned_uint64(const void *p) -{ - uint64_t r; -#if defined(UINT_UNALIGNED) - mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p; - r = *p64; -#elif defined(UINT_UNALIGNED_STRUCT) - mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p; - r = p64->x; -#else - memcpy(&r, p, sizeof(r)); -#endif - return r; -} - -/** - * Write the unsigned 64 bits integer to the given address, which need not - * be aligned. - * - * \param p pointer to 8 bytes of data - * \param x data to write - */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) -{ -#if defined(UINT_UNALIGNED) - mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p; - *p64 = x; -#elif defined(UINT_UNALIGNED_STRUCT) - mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p; - p64->x = x; -#else - memcpy(p, &x, sizeof(x)); -#endif -} - -#if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA) -#pragma language=restore -#endif - -/** Byte Reading Macros - * - * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th - * byte from x, where byte 0 is the least significant byte. - */ -#define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff)) -#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff)) -#define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff)) -#define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff)) -#define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff)) -#define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff)) -#define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff)) -#define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff)) - -/* - * Detect GCC built-in byteswap routines - */ -#if defined(__GNUC__) -#if MBEDTLS_GCC_VERSION >= 40800 -#define MBEDTLS_BSWAP16 __builtin_bswap16 -#endif -#if MBEDTLS_GCC_VERSION >= 40300 -#define MBEDTLS_BSWAP32 __builtin_bswap32 -#define MBEDTLS_BSWAP64 __builtin_bswap64 -#endif -#endif /* defined(__GNUC__) */ - -/* - * Detect Clang built-in byteswap routines - */ -#if defined(__clang__) && defined(__has_builtin) -#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16) -#define MBEDTLS_BSWAP16 __builtin_bswap16 -#endif /* __has_builtin(__builtin_bswap16) */ -#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32) -#define MBEDTLS_BSWAP32 __builtin_bswap32 -#endif /* __has_builtin(__builtin_bswap32) */ -#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64) -#define MBEDTLS_BSWAP64 __builtin_bswap64 -#endif /* __has_builtin(__builtin_bswap64) */ -#endif /* defined(__clang__) && defined(__has_builtin) */ - -/* - * Detect MSVC built-in byteswap routines - */ -#if defined(_MSC_VER) -#if !defined(MBEDTLS_BSWAP16) -#define MBEDTLS_BSWAP16 _byteswap_ushort -#endif -#if !defined(MBEDTLS_BSWAP32) -#define MBEDTLS_BSWAP32 _byteswap_ulong -#endif -#if !defined(MBEDTLS_BSWAP64) -#define MBEDTLS_BSWAP64 _byteswap_uint64 -#endif -#endif /* defined(_MSC_VER) */ - -/* Detect armcc built-in byteswap routine */ -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32) -#if defined(__ARM_ACLE) /* ARM Compiler 6 - earlier versions don't need a header */ -#include -#endif -#define MBEDTLS_BSWAP32 __rev -#endif - -/* Detect IAR built-in byteswap routine */ -#if defined(__IAR_SYSTEMS_ICC__) -#if defined(__ARM_ACLE) -#include -#define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x))) -#define MBEDTLS_BSWAP32 __rev -#define MBEDTLS_BSWAP64 __revll -#endif -#endif - -/* - * Where compiler built-ins are not present, fall back to C code that the - * compiler may be able to detect and transform into the relevant bswap or - * similar instruction. - */ -#if !defined(MBEDTLS_BSWAP16) -static inline uint16_t mbedtls_bswap16(uint16_t x) -{ - return - (x & 0x00ff) << 8 | - (x & 0xff00) >> 8; -} -#define MBEDTLS_BSWAP16 mbedtls_bswap16 -#endif /* !defined(MBEDTLS_BSWAP16) */ - -#if !defined(MBEDTLS_BSWAP32) -static inline uint32_t mbedtls_bswap32(uint32_t x) -{ - return - (x & 0x000000ff) << 24 | - (x & 0x0000ff00) << 8 | - (x & 0x00ff0000) >> 8 | - (x & 0xff000000) >> 24; -} -#define MBEDTLS_BSWAP32 mbedtls_bswap32 -#endif /* !defined(MBEDTLS_BSWAP32) */ - -#if !defined(MBEDTLS_BSWAP64) -static inline uint64_t mbedtls_bswap64(uint64_t x) -{ - return - (x & 0x00000000000000ffULL) << 56 | - (x & 0x000000000000ff00ULL) << 40 | - (x & 0x0000000000ff0000ULL) << 24 | - (x & 0x00000000ff000000ULL) << 8 | - (x & 0x000000ff00000000ULL) >> 8 | - (x & 0x0000ff0000000000ULL) >> 24 | - (x & 0x00ff000000000000ULL) >> 40 | - (x & 0xff00000000000000ULL) >> 56; -} -#define MBEDTLS_BSWAP64 mbedtls_bswap64 -#endif /* !defined(MBEDTLS_BSWAP64) */ - -#if !defined(__BYTE_ORDER__) - -#if defined(__LITTLE_ENDIAN__) -/* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */ -#define MBEDTLS_IS_BIG_ENDIAN 0 -#elif defined(__BIG_ENDIAN__) -#define MBEDTLS_IS_BIG_ENDIAN 1 -#else -static const uint16_t mbedtls_byte_order_detector = { 0x100 }; -#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01) -#endif - -#else - -#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__) -#define MBEDTLS_IS_BIG_ENDIAN 1 -#else -#define MBEDTLS_IS_BIG_ENDIAN 0 -#endif - -#endif /* !defined(__BYTE_ORDER__) */ - -/** - * Get the unsigned 32 bits integer corresponding to four bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the four bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the four bytes to build the 32 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT32_BE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ - ? mbedtls_get_unaligned_uint32((data) + (offset)) \ - : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \ - ) - -/** - * Put in memory a 32 bits unsigned integer in big-endian order. - * - * \param n 32 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 32 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 32 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \ - { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ - { \ - mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \ - } \ - else \ - { \ - mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \ - } \ - } - -/** - * Get the unsigned 32 bits integer corresponding to four bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the four bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the four bytes to build the 32 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT32_LE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ - ? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \ - : mbedtls_get_unaligned_uint32((data) + (offset)) \ - ) - - -/** - * Put in memory a 32 bits unsigned integer in little-endian order. - * - * \param n 32 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 32 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 32 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \ - { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ - { \ - mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \ - } \ - else \ - { \ - mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \ - } \ - } - -/** - * Get the unsigned 16 bits integer corresponding to two bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the two bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the two bytes to build the 16 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT16_LE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ - ? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \ - : mbedtls_get_unaligned_uint16((data) + (offset)) \ - ) - -/** - * Put in memory a 16 bits unsigned integer in little-endian order. - * - * \param n 16 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 16 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 16 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \ - { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ - { \ - mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \ - } \ - else \ - { \ - mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ - } \ - } - -/** - * Get the unsigned 16 bits integer corresponding to two bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the two bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the two bytes to build the 16 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT16_BE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ - ? mbedtls_get_unaligned_uint16((data) + (offset)) \ - : MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \ - ) - -/** - * Put in memory a 16 bits unsigned integer in big-endian order. - * - * \param n 16 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 16 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 16 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \ - { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ - { \ - mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ - } \ - else \ - { \ - mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \ - } \ - } - -/** - * Get the unsigned 24 bits integer corresponding to three bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the three bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the three bytes to build the 24 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT24_BE(data, offset) \ - ( \ - ((uint32_t) (data)[(offset)] << 16) \ - | ((uint32_t) (data)[(offset) + 1] << 8) \ - | ((uint32_t) (data)[(offset) + 2]) \ - ) - -/** - * Put in memory a 24 bits unsigned integer in big-endian order. - * - * \param n 24 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 24 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 24 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT24_BE(n, data, offset) \ - { \ - (data)[(offset)] = MBEDTLS_BYTE_2(n); \ - (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \ - (data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \ - } - -/** - * Get the unsigned 24 bits integer corresponding to three bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the three bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the three bytes to build the 24 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT24_LE(data, offset) \ - ( \ - ((uint32_t) (data)[(offset)]) \ - | ((uint32_t) (data)[(offset) + 1] << 8) \ - | ((uint32_t) (data)[(offset) + 2] << 16) \ - ) - -/** - * Put in memory a 24 bits unsigned integer in little-endian order. - * - * \param n 24 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 24 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 24 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT24_LE(n, data, offset) \ - { \ - (data)[(offset)] = MBEDTLS_BYTE_0(n); \ - (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \ - (data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \ - } - -/** - * Get the unsigned 64 bits integer corresponding to eight bytes in - * big-endian order (MSB first). - * - * \param data Base address of the memory to get the eight bytes from. - * \param offset Offset from \p data of the first and most significant - * byte of the eight bytes to build the 64 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT64_BE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ - ? mbedtls_get_unaligned_uint64((data) + (offset)) \ - : MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \ - ) - -/** - * Put in memory a 64 bits unsigned integer in big-endian order. - * - * \param n 64 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 64 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the most significant - * byte of the 64 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \ - { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ - { \ - mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ - } \ - else \ - { \ - mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \ - } \ - } - -/** - * Get the unsigned 64 bits integer corresponding to eight bytes in - * little-endian order (LSB first). - * - * \param data Base address of the memory to get the eight bytes from. - * \param offset Offset from \p data of the first and least significant - * byte of the eight bytes to build the 64 bits unsigned - * integer from. - */ -#define MBEDTLS_GET_UINT64_LE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ - ? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \ - : mbedtls_get_unaligned_uint64((data) + (offset)) \ - ) - -/** - * Put in memory a 64 bits unsigned integer in little-endian order. - * - * \param n 64 bits unsigned integer to put in memory. - * \param data Base address of the memory where to put the 64 - * bits unsigned integer in. - * \param offset Offset from \p data where to put the least significant - * byte of the 64 bits unsigned integer \p n. - */ -#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \ - { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ - { \ - mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \ - } \ - else \ - { \ - mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ - } \ - } - -#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */ diff --git a/vendor/mbedtls/library/aria.c b/vendor/mbedtls/library/aria.c deleted file mode 100644 index d9f84cc59..000000000 --- a/vendor/mbedtls/library/aria.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * ARIA implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * This implementation is based on the following standards: - * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf - * [2] https://tools.ietf.org/html/rfc5794 - */ - -#include "common.h" - -#if defined(MBEDTLS_ARIA_C) - -#include "mbedtls/aria.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_ARIA_ALT) - -#include "mbedtls/platform_util.h" - -/* - * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes - * - * This is submatrix P1 in [1] Appendix B.1 - * - * Common compilers fail to translate this to minimal number of instructions, - * so let's provide asm versions for common platforms with C fallback. - */ -#if defined(MBEDTLS_HAVE_ASM) -#if defined(__arm__) /* rev16 available from v6 up */ -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - (!defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000) && \ - __ARM_ARCH >= 6 -static inline uint32_t aria_p1(uint32_t x) -{ - uint32_t r; - __asm("rev16 %0, %1" : "=l" (r) : "l" (x)); - return r; -} -#define ARIA_P1 aria_p1 -#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \ - (__TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3) -static inline uint32_t aria_p1(uint32_t x) -{ - uint32_t r; - __asm("rev16 r, x"); - return r; -} -#define ARIA_P1 aria_p1 -#endif -#endif /* arm */ -#if defined(__GNUC__) && \ - defined(__i386__) || defined(__amd64__) || defined(__x86_64__) -/* I couldn't find an Intel equivalent of rev16, so two instructions */ -#define ARIA_P1(x) ARIA_P2(ARIA_P3(x)) -#endif /* x86 gnuc */ -#endif /* MBEDTLS_HAVE_ASM && GNUC */ -#if !defined(ARIA_P1) -#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8)) -#endif - -/* - * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits - * - * This is submatrix P2 in [1] Appendix B.1 - * - * Common compilers will translate this to a single instruction. - */ -#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16)) - -/* - * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness - * - * This is submatrix P3 in [1] Appendix B.1 - */ -#define ARIA_P3(x) MBEDTLS_BSWAP32(x) - -/* - * ARIA Affine Transform - * (a, b, c, d) = state in/out - * - * If we denote the first byte of input by 0, ..., the last byte by f, - * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef. - * - * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple - * rearrangements on adjacent pairs, output is: - * - * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe - * = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd - * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd - * = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc - * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe - * = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc - * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef - * = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef - * - * Note: another presentation of the A transform can be found as the first - * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4. - * The implementation below uses only P1 and P2 as they are sufficient. - */ -static inline void aria_a(uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d) -{ - uint32_t ta, tb, tc; - ta = *b; // 4567 - *b = *a; // 0123 - *a = ARIA_P2(ta); // 6745 - tb = ARIA_P2(*d); // efcd - *d = ARIA_P1(*c); // 98ba - *c = ARIA_P1(tb); // fedc - ta ^= *d; // 4567+98ba - tc = ARIA_P2(*b); // 2301 - ta = ARIA_P1(ta) ^ tc ^ *c; // 2301+5476+89ab+fedc - tb ^= ARIA_P2(*d); // ba98+efcd - tc ^= ARIA_P1(*a); // 2301+7654 - *b ^= ta ^ tb; // 0123+2301+5476+89ab+ba98+efcd+fedc OUT - tb = ARIA_P2(tb) ^ ta; // 2301+5476+89ab+98ba+cdef+fedc - *a ^= ARIA_P1(tb); // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT - ta = ARIA_P2(ta); // 0123+7654+ab89+dcfe - *d ^= ARIA_P1(ta) ^ tc; // 1032+2301+6745+7654+98ba+ba98+cdef OUT - tc = ARIA_P2(tc); // 0123+5476 - *c ^= ARIA_P1(tc) ^ ta; // 0123+1032+4567+7654+ab89+dcfe+fedc OUT -} - -/* - * ARIA Substitution Layer SL1 / SL2 - * (a, b, c, d) = state in/out - * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below) - * - * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1 - * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2 - */ -static inline void aria_sl(uint32_t *a, uint32_t *b, - uint32_t *c, uint32_t *d, - const uint8_t sa[256], const uint8_t sb[256], - const uint8_t sc[256], const uint8_t sd[256]) -{ - *a = ((uint32_t) sa[MBEDTLS_BYTE_0(*a)]) ^ - (((uint32_t) sb[MBEDTLS_BYTE_1(*a)]) << 8) ^ - (((uint32_t) sc[MBEDTLS_BYTE_2(*a)]) << 16) ^ - (((uint32_t) sd[MBEDTLS_BYTE_3(*a)]) << 24); - *b = ((uint32_t) sa[MBEDTLS_BYTE_0(*b)]) ^ - (((uint32_t) sb[MBEDTLS_BYTE_1(*b)]) << 8) ^ - (((uint32_t) sc[MBEDTLS_BYTE_2(*b)]) << 16) ^ - (((uint32_t) sd[MBEDTLS_BYTE_3(*b)]) << 24); - *c = ((uint32_t) sa[MBEDTLS_BYTE_0(*c)]) ^ - (((uint32_t) sb[MBEDTLS_BYTE_1(*c)]) << 8) ^ - (((uint32_t) sc[MBEDTLS_BYTE_2(*c)]) << 16) ^ - (((uint32_t) sd[MBEDTLS_BYTE_3(*c)]) << 24); - *d = ((uint32_t) sa[MBEDTLS_BYTE_0(*d)]) ^ - (((uint32_t) sb[MBEDTLS_BYTE_1(*d)]) << 8) ^ - (((uint32_t) sc[MBEDTLS_BYTE_2(*d)]) << 16) ^ - (((uint32_t) sd[MBEDTLS_BYTE_3(*d)]) << 24); -} - -/* - * S-Boxes - */ -static const uint8_t aria_sb1[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, - 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, - 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, - 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, - 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, - 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, - 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, - 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, - 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, - 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, - 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, - 0xB0, 0x54, 0xBB, 0x16 -}; - -static const uint8_t aria_sb2[256] = -{ - 0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46, - 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, - 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B, - 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB, - 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA, - 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, - 0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38, - 0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53, - 0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, - 0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, - 0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD, - 0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC, - 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E, - 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A, - 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5, - 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8, - 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, - 0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, - 0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33, - 0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D, - 0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, - 0xAF, 0xBA, 0xB5, 0x81 -}; - -static const uint8_t aria_is1[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D -}; - -static const uint8_t aria_is2[256] = -{ - 0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1, - 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3, - 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89, - 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D, - 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98, - 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, - 0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F, - 0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE, - 0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, - 0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, - 0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55, - 0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A, - 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE, - 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0, - 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6, - 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5, - 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, - 0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, - 0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94, - 0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3, - 0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, - 0x03, 0xA2, 0xAC, 0x60 -}; - -/* - * Helper for key schedule: r = FO( p, k ) ^ x - */ -static void aria_fo_xor(uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4]) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2); - aria_a(&a, &b, &c, &d); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Helper for key schedule: r = FE( p, k ) ^ x - */ -static void aria_fe_xor(uint32_t r[4], const uint32_t p[4], - const uint32_t k[4], const uint32_t x[4]) -{ - uint32_t a, b, c, d; - - a = p[0] ^ k[0]; - b = p[1] ^ k[1]; - c = p[2] ^ k[2]; - d = p[3] ^ k[3]; - - aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2); - aria_a(&a, &b, &c, &d); - - r[0] = a ^ x[0]; - r[1] = b ^ x[1]; - r[2] = c ^ x[2]; - r[3] = d ^ x[3]; -} - -/* - * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup. - * - * We chose to store bytes into 32-bit words in little-endian format (see - * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse - * bytes here. - */ -static void aria_rot128(uint32_t r[4], const uint32_t a[4], - const uint32_t b[4], uint8_t n) -{ - uint8_t i, j; - uint32_t t, u; - - const uint8_t n1 = n % 32; // bit offset - const uint8_t n2 = n1 ? 32 - n1 : 0; // reverse bit offset - - j = (n / 32) % 4; // initial word offset - t = ARIA_P3(b[j]); // big endian - for (i = 0; i < 4; i++) { - j = (j + 1) % 4; // get next word, big endian - u = ARIA_P3(b[j]); - t <<= n1; // rotate - t |= u >> n2; - t = ARIA_P3(t); // back to little endian - r[i] = a[i] ^ t; // store - t = u; // move to next word - } -} - -/* - * Set encryption key - */ -int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits) -{ - /* round constant masks */ - const uint32_t rc[3][4] = - { - { 0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA }, - { 0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF }, - { 0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804 } - }; - - int i; - uint32_t w[4][4], *w2; - - if (keybits != 128 && keybits != 192 && keybits != 256) { - return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA; - } - - /* Copy key to W0 (and potential remainder to W1) */ - w[0][0] = MBEDTLS_GET_UINT32_LE(key, 0); - w[0][1] = MBEDTLS_GET_UINT32_LE(key, 4); - w[0][2] = MBEDTLS_GET_UINT32_LE(key, 8); - w[0][3] = MBEDTLS_GET_UINT32_LE(key, 12); - - memset(w[1], 0, 16); - if (keybits >= 192) { - w[1][0] = MBEDTLS_GET_UINT32_LE(key, 16); // 192 bit key - w[1][1] = MBEDTLS_GET_UINT32_LE(key, 20); - } - if (keybits == 256) { - w[1][2] = MBEDTLS_GET_UINT32_LE(key, 24); // 256 bit key - w[1][3] = MBEDTLS_GET_UINT32_LE(key, 28); - } - - i = (keybits - 128) >> 6; // index: 0, 1, 2 - ctx->nr = 12 + 2 * i; // no. rounds: 12, 14, 16 - - aria_fo_xor(w[1], w[0], rc[i], w[1]); // W1 = FO(W0, CK1) ^ KR - i = i < 2 ? i + 1 : 0; - aria_fe_xor(w[2], w[1], rc[i], w[0]); // W2 = FE(W1, CK2) ^ W0 - i = i < 2 ? i + 1 : 0; - aria_fo_xor(w[3], w[2], rc[i], w[1]); // W3 = FO(W2, CK3) ^ W1 - - for (i = 0; i < 4; i++) { // create round keys - w2 = w[(i + 1) & 3]; - aria_rot128(ctx->rk[i], w[i], w2, 128 - 19); - aria_rot128(ctx->rk[i + 4], w[i], w2, 128 - 31); - aria_rot128(ctx->rk[i + 8], w[i], w2, 61); - aria_rot128(ctx->rk[i + 12], w[i], w2, 31); - } - aria_rot128(ctx->rk[16], w[0], w[1], 19); - - /* w holds enough info to reconstruct the round keys */ - mbedtls_platform_zeroize(w, sizeof(w)); - - return 0; -} - -/* - * Set decryption key - */ -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx, - const unsigned char *key, unsigned int keybits) -{ - int i, j, k, ret; - - ret = mbedtls_aria_setkey_enc(ctx, key, keybits); - if (ret != 0) { - return ret; - } - - /* flip the order of round keys */ - for (i = 0, j = ctx->nr; i < j; i++, j--) { - for (k = 0; k < 4; k++) { - uint32_t t = ctx->rk[i][k]; - ctx->rk[i][k] = ctx->rk[j][k]; - ctx->rk[j][k] = t; - } - } - - /* apply affine transform to middle keys */ - for (i = 1; i < ctx->nr; i++) { - aria_a(&ctx->rk[i][0], &ctx->rk[i][1], - &ctx->rk[i][2], &ctx->rk[i][3]); - } - - return 0; -} -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -/* - * Encrypt a block - */ -int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx, - const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char output[MBEDTLS_ARIA_BLOCKSIZE]) -{ - int i; - - uint32_t a, b, c, d; - - a = MBEDTLS_GET_UINT32_LE(input, 0); - b = MBEDTLS_GET_UINT32_LE(input, 4); - c = MBEDTLS_GET_UINT32_LE(input, 8); - d = MBEDTLS_GET_UINT32_LE(input, 12); - - i = 0; - while (1) { - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl(&a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2); - aria_a(&a, &b, &c, &d); - - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - i++; - - aria_sl(&a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2); - if (i >= ctx->nr) { - break; - } - aria_a(&a, &b, &c, &d); - } - - /* final key mixing */ - a ^= ctx->rk[i][0]; - b ^= ctx->rk[i][1]; - c ^= ctx->rk[i][2]; - d ^= ctx->rk[i][3]; - - MBEDTLS_PUT_UINT32_LE(a, output, 0); - MBEDTLS_PUT_UINT32_LE(b, output, 4); - MBEDTLS_PUT_UINT32_LE(c, output, 8); - MBEDTLS_PUT_UINT32_LE(d, output, 12); - - return 0; -} - -/* Initialize context */ -void mbedtls_aria_init(mbedtls_aria_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_aria_context)); -} - -/* Clear context */ -void mbedtls_aria_free(mbedtls_aria_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aria_context)); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * ARIA-CBC buffer encryption/decryption - */ -int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx, - int mode, - size_t length, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output) -{ - unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE]; - - if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) { - return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA; - } - - if (length % MBEDTLS_ARIA_BLOCKSIZE) { - return MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH; - } - - if (mode == MBEDTLS_ARIA_DECRYPT) { - while (length > 0) { - memcpy(temp, input, MBEDTLS_ARIA_BLOCKSIZE); - mbedtls_aria_crypt_ecb(ctx, input, output); - - mbedtls_xor(output, output, iv, MBEDTLS_ARIA_BLOCKSIZE); - - memcpy(iv, temp, MBEDTLS_ARIA_BLOCKSIZE); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } else { - while (length > 0) { - mbedtls_xor(output, input, iv, MBEDTLS_ARIA_BLOCKSIZE); - - mbedtls_aria_crypt_ecb(ctx, output, output); - memcpy(iv, output, MBEDTLS_ARIA_BLOCKSIZE); - - input += MBEDTLS_ARIA_BLOCKSIZE; - output += MBEDTLS_ARIA_BLOCKSIZE; - length -= MBEDTLS_ARIA_BLOCKSIZE; - } - } - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * ARIA-CFB128 buffer encryption/decryption - */ -int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output) -{ - unsigned char c; - size_t n; - - if ((mode != MBEDTLS_ARIA_ENCRYPT) && (mode != MBEDTLS_ARIA_DECRYPT)) { - return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA; - } - - n = *iv_off; - - /* An overly large value of n can lead to an unlimited - * buffer overflow. */ - if (n >= MBEDTLS_ARIA_BLOCKSIZE) { - return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA; - } - - if (mode == MBEDTLS_ARIA_DECRYPT) { - while (length--) { - if (n == 0) { - mbedtls_aria_crypt_ecb(ctx, iv, iv); - } - - c = *input++; - *output++ = c ^ iv[n]; - iv[n] = c; - - n = (n + 1) & 0x0F; - } - } else { - while (length--) { - if (n == 0) { - mbedtls_aria_crypt_ecb(ctx, iv, iv); - } - - iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++); - - n = (n + 1) & 0x0F; - } - } - - *iv_off = n; - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * ARIA-CTR buffer encryption/decryption - */ -int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE], - unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE], - const unsigned char *input, - unsigned char *output) -{ - int c, i; - size_t n; - - n = *nc_off; - /* An overly large value of n can lead to an unlimited - * buffer overflow. */ - if (n >= MBEDTLS_ARIA_BLOCKSIZE) { - return MBEDTLS_ERR_ARIA_BAD_INPUT_DATA; - } - - while (length--) { - if (n == 0) { - mbedtls_aria_crypt_ecb(ctx, nonce_counter, - stream_block); - - for (i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i--) { - if (++nonce_counter[i - 1] != 0) { - break; - } - } - } - c = *input++; - *output++ = (unsigned char) (c ^ stream_block[n]); - - n = (n + 1) & 0x0F; - } - - *nc_off = n; - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* !MBEDTLS_ARIA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Basic ARIA ECB test vectors from RFC 5794 - */ -static const uint8_t aria_test1_ecb_key[32] = // test key -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 128 bit - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // 192 bit - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 256 bit -}; - -static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] = // plaintext -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // same for all - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF // key sizes -}; - -static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] = // ciphertext -{ - { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73, // 128 bit - 0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 }, - { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA, // 192 bit - 0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 }, - { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F, // 256 bit - 0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC } -}; - -/* - * Mode tests from "Test Vectors for ARIA" Version 1.0 - * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf - */ -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) -static const uint8_t aria_test2_key[32] = -{ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 128 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 192 bit - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff // 256 bit -}; - -static const uint8_t aria_test2_pt[48] = -{ - 0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa, // same for all - 0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb, - 0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc, - 0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd, - 0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa, - 0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb, -}; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)) -static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] = -{ - 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78, // same for CBC, CFB - 0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0 // CTR has zero IV -}; -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const uint8_t aria_test2_cbc_ct[3][48] = // CBC ciphertext -{ - { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10, // 128-bit key - 0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34, - 0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64, - 0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38, - 0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c, - 0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 }, - { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c, // 192-bit key - 0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f, - 0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1, - 0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5, - 0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92, - 0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e }, - { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1, // 256-bit key - 0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab, - 0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef, - 0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52, - 0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5, - 0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const uint8_t aria_test2_cfb_ct[3][48] = // CFB ciphertext -{ - { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38, // 128-bit key - 0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00, - 0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a, - 0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01, - 0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96, - 0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b }, - { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54, // 192-bit key - 0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c, - 0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94, - 0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59, - 0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86, - 0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b }, - { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2, // 256-bit key - 0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35, - 0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70, - 0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa, - 0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c, - 0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext -{ - { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c, // 128-bit key - 0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1, - 0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1, - 0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f, - 0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71, - 0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 }, - { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19, // 192-bit key - 0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce, - 0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde, - 0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79, - 0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce, - 0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf }, - { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17, // 256-bit key - 0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2, - 0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89, - 0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f, - 0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7, - 0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#define ARIA_SELF_TEST_ASSERT(cond) \ - do { \ - if (cond) { \ - if (verbose) \ - mbedtls_printf("failed\n"); \ - goto exit; \ - } else { \ - if (verbose) \ - mbedtls_printf("passed\n"); \ - } \ - } while (0) - -/* - * Checkup routine - */ -int mbedtls_aria_self_test(int verbose) -{ - int i; - uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE]; - mbedtls_aria_context ctx; - int ret = 1; - -#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR)) - size_t j; -#endif - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \ - defined(MBEDTLS_CIPHER_MODE_CFB) || \ - defined(MBEDTLS_CIPHER_MODE_CTR)) - uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE]; -#endif - - mbedtls_aria_init(&ctx); - - /* - * Test set 1 - */ - for (i = 0; i < 3; i++) { - /* test ECB encryption */ - if (verbose) { - mbedtls_printf(" ARIA-ECB-%d (enc): ", 128 + 64 * i); - } - mbedtls_aria_setkey_enc(&ctx, aria_test1_ecb_key, 128 + 64 * i); - mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_pt, blk); - ARIA_SELF_TEST_ASSERT( - memcmp(blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE) - != 0); - - /* test ECB decryption */ - if (verbose) { - mbedtls_printf(" ARIA-ECB-%d (dec): ", 128 + 64 * i); -#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - mbedtls_printf("skipped\n"); -#endif - } - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - mbedtls_aria_setkey_dec(&ctx, aria_test1_ecb_key, 128 + 64 * i); - mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_ct[i], blk); - ARIA_SELF_TEST_ASSERT( - memcmp(blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE) - != 0); -#endif - } - if (verbose) { - mbedtls_printf("\n"); - } - - /* - * Test set 2 - */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) - for (i = 0; i < 3; i++) { - /* Test CBC encryption */ - if (verbose) { - mbedtls_printf(" ARIA-CBC-%d (enc): ", 128 + 64 * i); - } - mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i); - memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE); - memset(buf, 0x55, sizeof(buf)); - mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv, - aria_test2_pt, buf); - ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cbc_ct[i], 48) - != 0); - - /* Test CBC decryption */ - if (verbose) { - mbedtls_printf(" ARIA-CBC-%d (dec): ", 128 + 64 * i); - } - mbedtls_aria_setkey_dec(&ctx, aria_test2_key, 128 + 64 * i); - memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE); - memset(buf, 0xAA, sizeof(buf)); - mbedtls_aria_crypt_cbc(&ctx, MBEDTLS_ARIA_DECRYPT, 48, iv, - aria_test2_cbc_ct[i], buf); - ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0); - } - if (verbose) { - mbedtls_printf("\n"); - } - -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - for (i = 0; i < 3; i++) { - /* Test CFB encryption */ - if (verbose) { - mbedtls_printf(" ARIA-CFB-%d (enc): ", 128 + 64 * i); - } - mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i); - memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE); - memset(buf, 0x55, sizeof(buf)); - j = 0; - mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv, - aria_test2_pt, buf); - ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_cfb_ct[i], 48) != 0); - - /* Test CFB decryption */ - if (verbose) { - mbedtls_printf(" ARIA-CFB-%d (dec): ", 128 + 64 * i); - } - mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i); - memcpy(iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE); - memset(buf, 0xAA, sizeof(buf)); - j = 0; - mbedtls_aria_crypt_cfb128(&ctx, MBEDTLS_ARIA_DECRYPT, 48, &j, - iv, aria_test2_cfb_ct[i], buf); - ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0); - } - if (verbose) { - mbedtls_printf("\n"); - } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - for (i = 0; i < 3; i++) { - /* Test CTR encryption */ - if (verbose) { - mbedtls_printf(" ARIA-CTR-%d (enc): ", 128 + 64 * i); - } - mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i); - memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE); // IV = 0 - memset(buf, 0x55, sizeof(buf)); - j = 0; - mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk, - aria_test2_pt, buf); - ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_ctr_ct[i], 48) != 0); - - /* Test CTR decryption */ - if (verbose) { - mbedtls_printf(" ARIA-CTR-%d (dec): ", 128 + 64 * i); - } - mbedtls_aria_setkey_enc(&ctx, aria_test2_key, 128 + 64 * i); - memset(iv, 0, MBEDTLS_ARIA_BLOCKSIZE); // IV = 0 - memset(buf, 0xAA, sizeof(buf)); - j = 0; - mbedtls_aria_crypt_ctr(&ctx, 48, &j, iv, blk, - aria_test2_ctr_ct[i], buf); - ARIA_SELF_TEST_ASSERT(memcmp(buf, aria_test2_pt, 48) != 0); - } - if (verbose) { - mbedtls_printf("\n"); - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - ret = 0; - -exit: - mbedtls_aria_free(&ctx); - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ARIA_C */ diff --git a/vendor/mbedtls/library/asn1parse.c b/vendor/mbedtls/library/asn1parse.c deleted file mode 100644 index e33fdf71d..000000000 --- a/vendor/mbedtls/library/asn1parse.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Generic ASN.1 parsing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \ - defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) - -#include "mbedtls/asn1.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -#include "mbedtls/platform.h" - -/* - * ASN.1 DER decoding routines - */ -int mbedtls_asn1_get_len(unsigned char **p, - const unsigned char *end, - size_t *len) -{ - if ((end - *p) < 1) { - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - - if ((**p & 0x80) == 0) { - *len = *(*p)++; - } else { - int n = (**p) & 0x7F; - if (n == 0 || n > 4) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - if ((end - *p) <= n) { - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - *len = 0; - (*p)++; - while (n--) { - *len = (*len << 8) | **p; - (*p)++; - } - } - - if (*len > (size_t) (end - *p)) { - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - - return 0; -} - -int mbedtls_asn1_get_tag(unsigned char **p, - const unsigned char *end, - size_t *len, int tag) -{ - if ((end - *p) < 1) { - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - - if (**p != tag) { - return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; - } - - (*p)++; - - return mbedtls_asn1_get_len(p, end, len); -} -#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */ - -#if defined(MBEDTLS_ASN1_PARSE_C) -int mbedtls_asn1_get_bool(unsigned char **p, - const unsigned char *end, - int *val) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) { - return ret; - } - - if (len != 1) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - - *val = (**p != 0) ? 1 : 0; - (*p)++; - - return 0; -} - -static int asn1_get_tagged_int(unsigned char **p, - const unsigned char *end, - int tag, int *val) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) { - return ret; - } - - /* - * len==0 is malformed (0 must be represented as 020100 for INTEGER, - * or 0A0100 for ENUMERATED tags - */ - if (len == 0) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - /* This is a cryptography library. Reject negative integers. */ - if ((**p & 0x80) != 0) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - - /* Skip leading zeros. */ - while (len > 0 && **p == 0) { - ++(*p); - --len; - } - - /* Reject integers that don't fit in an int. This code assumes that - * the int type has no padding bit. */ - if (len > sizeof(int)) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - if (len == sizeof(int) && (**p & 0x80) != 0) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - - *val = 0; - while (len-- > 0) { - *val = (*val << 8) | **p; - (*p)++; - } - - return 0; -} - -int mbedtls_asn1_get_int(unsigned char **p, - const unsigned char *end, - int *val) -{ - return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val); -} - -int mbedtls_asn1_get_enum(unsigned char **p, - const unsigned char *end, - int *val) -{ - return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val); -} - -#if defined(MBEDTLS_BIGNUM_C) -int mbedtls_asn1_get_mpi(unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { - return ret; - } - - ret = mbedtls_mpi_read_binary(X, *p, len); - - *p += len; - - return ret; -} -#endif /* MBEDTLS_BIGNUM_C */ - -int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end, - mbedtls_asn1_bitstring *bs) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Certificate type is a single byte bitstring */ - if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) { - return ret; - } - - /* Check length, subtract one for actual bit string length */ - if (bs->len < 1) { - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - bs->len -= 1; - - /* Get number of unused bits, ensure unused bits <= 7 */ - bs->unused_bits = **p; - if (bs->unused_bits > 7) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - (*p)++; - - /* Get actual bitstring */ - bs->p = *p; - *p += bs->len; - - if (*p != end) { - return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } - - return 0; -} - -/* - * Traverse an ASN.1 "SEQUENCE OF " - * and call a callback for each entry found. - */ -int mbedtls_asn1_traverse_sequence_of( - unsigned char **p, - const unsigned char *end, - unsigned char tag_must_mask, unsigned char tag_must_val, - unsigned char tag_may_mask, unsigned char tag_may_val, - int (*cb)(void *ctx, int tag, - unsigned char *start, size_t len), - void *ctx) -{ - int ret; - size_t len; - - /* Get main sequence tag */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return ret; - } - - if (*p + len != end) { - return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } - - while (*p < end) { - unsigned char const tag = *(*p)++; - - if ((tag & tag_must_mask) != tag_must_val) { - return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; - } - - if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) { - return ret; - } - - if ((tag & tag_may_mask) == tag_may_val) { - if (cb != NULL) { - ret = cb(ctx, tag, *p, len); - if (ret != 0) { - return ret; - } - } - } - - *p += len; - } - - return 0; -} - -/* - * Get a bit string without unused bits - */ -int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, - size_t *len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) { - return ret; - } - - if (*len == 0) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - --(*len); - - if (**p != 0) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - ++(*p); - - return 0; -} - -void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq) -{ - while (seq != NULL) { - mbedtls_asn1_sequence *next = seq->next; - mbedtls_free(seq); - seq = next; - } -} - -typedef struct { - int tag; - mbedtls_asn1_sequence *cur; -} asn1_get_sequence_of_cb_ctx_t; - -static int asn1_get_sequence_of_cb(void *ctx, - int tag, - unsigned char *start, - size_t len) -{ - asn1_get_sequence_of_cb_ctx_t *cb_ctx = - (asn1_get_sequence_of_cb_ctx_t *) ctx; - mbedtls_asn1_sequence *cur = - cb_ctx->cur; - - if (cur->buf.p != NULL) { - cur->next = - mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); - - if (cur->next == NULL) { - return MBEDTLS_ERR_ASN1_ALLOC_FAILED; - } - - cur = cur->next; - } - - cur->buf.p = start; - cur->buf.len = len; - cur->buf.tag = tag; - - cb_ctx->cur = cur; - return 0; -} - -/* - * Parses and splits an ASN.1 "SEQUENCE OF " - */ -int mbedtls_asn1_get_sequence_of(unsigned char **p, - const unsigned char *end, - mbedtls_asn1_sequence *cur, - int tag) -{ - asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur }; - memset(cur, 0, sizeof(mbedtls_asn1_sequence)); - return mbedtls_asn1_traverse_sequence_of( - p, end, 0xFF, tag, 0, 0, - asn1_get_sequence_of_cb, &cb_ctx); -} - -int mbedtls_asn1_get_alg(unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return ret; - } - - if ((end - *p) < 1) { - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - - alg->tag = **p; - end = *p + len; - - if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) { - return ret; - } - - alg->p = *p; - *p += alg->len; - - if (*p == end) { - mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf)); - return 0; - } - - params->tag = **p; - (*p)++; - - if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0) { - return ret; - } - - params->p = *p; - *p += params->len; - - if (*p != end) { - return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } - - return 0; -} - -int mbedtls_asn1_get_alg_null(unsigned char **p, - const unsigned char *end, - mbedtls_asn1_buf *alg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_asn1_buf params; - - memset(¶ms, 0, sizeof(mbedtls_asn1_buf)); - - if ((ret = mbedtls_asn1_get_alg(p, end, alg, ¶ms)) != 0) { - return ret; - } - - if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - - return 0; -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur) -{ - if (cur == NULL) { - return; - } - - mbedtls_free(cur->oid.p); - mbedtls_free(cur->val.p); - - mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data)); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head) -{ - mbedtls_asn1_named_data *cur; - - while ((cur = *head) != NULL) { - *head = cur->next; - mbedtls_free(cur->oid.p); - mbedtls_free(cur->val.p); - mbedtls_free(cur); - } -} - -void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name) -{ - for (mbedtls_asn1_named_data *next; name != NULL; name = next) { - next = name->next; - mbedtls_free(name); - } -} - -const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list, - const char *oid, size_t len) -{ - while (list != NULL) { - if (list->oid.len == len && - memcmp(list->oid.p, oid, len) == 0) { - break; - } - - list = list->next; - } - - return list; -} - -#endif /* MBEDTLS_ASN1_PARSE_C */ diff --git a/vendor/mbedtls/library/asn1write.c b/vendor/mbedtls/library/asn1write.c deleted file mode 100644 index 97f9db039..000000000 --- a/vendor/mbedtls/library/asn1write.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * ASN.1 buffer writing functionality - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \ - defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) - -#include "mbedtls/asn1write.h" -#include "mbedtls/error.h" - -#include - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#endif - -int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start, size_t len) -{ -#if SIZE_MAX > 0xFFFFFFFF - if (len > 0xFFFFFFFF) { - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } -#endif - - int required = 1; - - if (len >= 0x80) { - for (size_t l = len; l != 0; l >>= 8) { - required++; - } - } - - if (required > (*p - start)) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - do { - *--(*p) = MBEDTLS_BYTE_0(len); - len >>= 8; - } while (len); - - if (required > 1) { - *--(*p) = (unsigned char) (0x80 + required - 1); - } - - return required; -} - -int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, unsigned char tag) -{ - if (*p - start < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - *--(*p) = tag; - - return 1; -} -#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */ - -#if defined(MBEDTLS_ASN1_WRITE_C) -static int mbedtls_asn1_write_len_and_tag(unsigned char **p, - const unsigned char *start, - size_t len, - unsigned char tag) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, tag)); - - return (int) len; -} - -int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start, - const unsigned char *buf, size_t size) -{ - size_t len = 0; - - if (*p < start || (size_t) (*p - start) < size) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - len = size; - (*p) -= len; - if (len != 0) { - memcpy(*p, buf, len); - } - - return (int) len; -} - -#if defined(MBEDTLS_BIGNUM_C) -int mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start, const mbedtls_mpi *X) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - // Write the MPI - // - len = mbedtls_mpi_size(X); - - /* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not - * as 0 digits. We need to end up with 020100, not with 0200. */ - if (len == 0) { - len = 1; - } - - if (*p < start || (size_t) (*p - start) < len) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - (*p) -= len; - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(X, *p, len)); - - // DER format assumes 2s complement for numbers, so the leftmost bit - // should be 0 for positive numbers and 1 for negative numbers. - // - if (X->s == 1 && **p & 0x80) { - if (*p - start < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - *--(*p) = 0x00; - len += 1; - } - - ret = mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_INTEGER); - -cleanup: - return ret; -} -#endif /* MBEDTLS_BIGNUM_C */ - -int mbedtls_asn1_write_null(unsigned char **p, const unsigned char *start) -{ - // Write NULL - // - return mbedtls_asn1_write_len_and_tag(p, start, 0, MBEDTLS_ASN1_NULL); -} - -int mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start, - const char *oid, size_t oid_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, - (const unsigned char *) oid, oid_len)); - return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OID); -} - -int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, const unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len) -{ - return mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, par_len, 1); -} - -int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, const unsigned char *start, - const char *oid, size_t oid_len, - size_t par_len, int has_par) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - if (has_par) { - if (par_len == 0) { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start)); - } else { - len += par_len; - } - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); - - return mbedtls_asn1_write_len_and_tag(p, start, len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -} - -int mbedtls_asn1_write_bool(unsigned char **p, const unsigned char *start, int boolean) -{ - size_t len = 0; - - if (*p - start < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - *--(*p) = (boolean) ? 255 : 0; - len++; - - return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BOOLEAN); -} - -static int asn1_write_tagged_int(unsigned char **p, const unsigned char *start, int val, int tag) -{ - size_t len = 0; - - do { - if (*p - start < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - len += 1; - *--(*p) = val & 0xff; - val >>= 8; - } while (val > 0); - - if (**p & 0x80) { - if (*p - start < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - *--(*p) = 0x00; - len += 1; - } - - return mbedtls_asn1_write_len_and_tag(p, start, len, tag); -} - -int mbedtls_asn1_write_int(unsigned char **p, const unsigned char *start, int val) -{ - return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_INTEGER); -} - -int mbedtls_asn1_write_enum(unsigned char **p, const unsigned char *start, int val) -{ - return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_ENUMERATED); -} - -int mbedtls_asn1_write_tagged_string(unsigned char **p, const unsigned char *start, int tag, - const char *text, size_t text_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, - (const unsigned char *) text, - text_len)); - - return mbedtls_asn1_write_len_and_tag(p, start, len, tag); -} - -int mbedtls_asn1_write_utf8_string(unsigned char **p, const unsigned char *start, - const char *text, size_t text_len) -{ - return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len); -} - -int mbedtls_asn1_write_printable_string(unsigned char **p, const unsigned char *start, - const char *text, size_t text_len) -{ - return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, - text_len); -} - -int mbedtls_asn1_write_ia5_string(unsigned char **p, const unsigned char *start, - const char *text, size_t text_len) -{ - return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len); -} - -int mbedtls_asn1_write_named_bitstring(unsigned char **p, - const unsigned char *start, - const unsigned char *buf, - size_t bits) -{ - size_t unused_bits, byte_len; - const unsigned char *cur_byte; - unsigned char cur_byte_shifted; - unsigned char bit; - - byte_len = (bits + 7) / 8; - unused_bits = (byte_len * 8) - bits; - - /* - * Named bitstrings require that trailing 0s are excluded in the encoding - * of the bitstring. Trailing 0s are considered part of the 'unused' bits - * when encoding this value in the first content octet - */ - if (bits != 0) { - cur_byte = buf + byte_len - 1; - cur_byte_shifted = *cur_byte >> unused_bits; - - for (;;) { - bit = cur_byte_shifted & 0x1; - cur_byte_shifted >>= 1; - - if (bit != 0) { - break; - } - - bits--; - if (bits == 0) { - break; - } - - if (bits % 8 == 0) { - cur_byte_shifted = *--cur_byte; - } - } - } - - return mbedtls_asn1_write_bitstring(p, start, buf, bits); -} - -int mbedtls_asn1_write_bitstring(unsigned char **p, const unsigned char *start, - const unsigned char *buf, size_t bits) -{ - size_t len = 0; - size_t unused_bits, byte_len; - - byte_len = (bits + 7) / 8; - unused_bits = (byte_len * 8) - bits; - - if (*p < start || (size_t) (*p - start) < byte_len + 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - len = byte_len + 1; - - /* Write the bitstring. Ensure the unused bits are zeroed */ - if (byte_len > 0) { - byte_len--; - *--(*p) = buf[byte_len] & ~((0x1 << unused_bits) - 1); - (*p) -= byte_len; - memcpy(*p, buf, byte_len); - } - - /* Write unused bits */ - *--(*p) = (unsigned char) unused_bits; - - return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BIT_STRING); -} - -int mbedtls_asn1_write_octet_string(unsigned char **p, const unsigned char *start, - const unsigned char *buf, size_t size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, buf, size)); - - return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OCTET_STRING); -} - - -#if !defined(MBEDTLS_ASN1_PARSE_C) -/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(), - * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */ -static mbedtls_asn1_named_data *asn1_find_named_data( - mbedtls_asn1_named_data *list, - const char *oid, size_t len) -{ - while (list != NULL) { - if (list->oid.len == len && - memcmp(list->oid.p, oid, len) == 0) { - break; - } - - list = list->next; - } - - return list; -} -#else -#define asn1_find_named_data(list, oid, len) \ - ((mbedtls_asn1_named_data *) mbedtls_asn1_find_named_data(list, oid, len)) -#endif - -mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( - mbedtls_asn1_named_data **head, - const char *oid, size_t oid_len, - const unsigned char *val, - size_t val_len) -{ - mbedtls_asn1_named_data *cur; - - if ((cur = asn1_find_named_data(*head, oid, oid_len)) == NULL) { - // Add new entry if not present yet based on OID - // - cur = (mbedtls_asn1_named_data *) mbedtls_calloc(1, - sizeof(mbedtls_asn1_named_data)); - if (cur == NULL) { - return NULL; - } - - cur->oid.len = oid_len; - cur->oid.p = mbedtls_calloc(1, oid_len); - if (cur->oid.p == NULL) { - mbedtls_free(cur); - return NULL; - } - - memcpy(cur->oid.p, oid, oid_len); - - cur->val.len = val_len; - if (val_len != 0) { - cur->val.p = mbedtls_calloc(1, val_len); - if (cur->val.p == NULL) { - mbedtls_free(cur->oid.p); - mbedtls_free(cur); - return NULL; - } - } - - cur->next = *head; - *head = cur; - } else if (val_len == 0) { - mbedtls_free(cur->val.p); - cur->val.p = NULL; - cur->val.len = 0; - } else if (cur->val.len != val_len) { - /* - * Enlarge existing value buffer if needed - * Preserve old data until the allocation succeeded, to leave list in - * a consistent state in case allocation fails. - */ - void *p = mbedtls_calloc(1, val_len); - if (p == NULL) { - return NULL; - } - - mbedtls_free(cur->val.p); - cur->val.p = p; - cur->val.len = val_len; - } - - if (val != NULL && val_len != 0) { - memcpy(cur->val.p, val, val_len); - } - - return cur; -} -#endif /* MBEDTLS_ASN1_WRITE_C */ diff --git a/vendor/mbedtls/library/base64.c b/vendor/mbedtls/library/base64.c deleted file mode 100644 index 25c960a8c..000000000 --- a/vendor/mbedtls/library/base64.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * RFC 1521 base64 encoding/decoding - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_BASE64_C) - -#include "mbedtls/base64.h" -#include "base64_internal.h" -#include "constant_time_internal.h" -#include "mbedtls/error.h" - -#include -#include - -#if defined(MBEDTLS_SELF_TEST) -#include -#include "mbedtls/platform.h" -#endif /* MBEDTLS_SELF_TEST */ - -MBEDTLS_STATIC_TESTABLE -unsigned char mbedtls_ct_base64_enc_char(unsigned char value) -{ - unsigned char digit = 0; - /* For each range of values, if value is in that range, mask digit with - * the corresponding value. Since value can only be in a single range, - * only at most one masking will change digit. */ - digit |= mbedtls_ct_uchar_in_range_if(0, 25, value, 'A' + value); - digit |= mbedtls_ct_uchar_in_range_if(26, 51, value, 'a' + value - 26); - digit |= mbedtls_ct_uchar_in_range_if(52, 61, value, '0' + value - 52); - digit |= mbedtls_ct_uchar_in_range_if(62, 62, value, '+'); - digit |= mbedtls_ct_uchar_in_range_if(63, 63, value, '/'); - return digit; -} - -MBEDTLS_STATIC_TESTABLE -signed char mbedtls_ct_base64_dec_value(unsigned char c) -{ - unsigned char val = 0; - /* For each range of digits, if c is in that range, mask val with - * the corresponding value. Since c can only be in a single range, - * only at most one masking will change val. Set val to one plus - * the desired value so that it stays 0 if c is in none of the ranges. */ - val |= mbedtls_ct_uchar_in_range_if('A', 'Z', c, c - 'A' + 0 + 1); - val |= mbedtls_ct_uchar_in_range_if('a', 'z', c, c - 'a' + 26 + 1); - val |= mbedtls_ct_uchar_in_range_if('0', '9', c, c - '0' + 52 + 1); - val |= mbedtls_ct_uchar_in_range_if('+', '+', c, c - '+' + 62 + 1); - val |= mbedtls_ct_uchar_in_range_if('/', '/', c, c - '/' + 63 + 1); - /* At this point, val is 0 if c is an invalid digit and v+1 if c is - * a digit with the value v. */ - return val - 1; -} - -/* - * Encode a buffer into base64 format - */ -int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen) -{ - size_t i, n; - int C1, C2, C3; - unsigned char *p; - - if (slen == 0) { - *olen = 0; - return 0; - } - - n = slen / 3 + (slen % 3 != 0); - - if (n > (SIZE_MAX - 1) / 4) { - *olen = SIZE_MAX; - return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; - } - - n *= 4; - - if ((dlen < n + 1) || (NULL == dst)) { - *olen = n + 1; - return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; - } - - n = (slen / 3) * 3; - - for (i = 0, p = dst; i < n; i += 3) { - C1 = *src++; - C2 = *src++; - C3 = *src++; - - *p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F); - *p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4)) - & 0x3F); - *p++ = mbedtls_ct_base64_enc_char((((C2 & 15) << 2) + (C3 >> 6)) - & 0x3F); - *p++ = mbedtls_ct_base64_enc_char(C3 & 0x3F); - } - - if (i < slen) { - C1 = *src++; - C2 = ((i + 1) < slen) ? *src++ : 0; - - *p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F); - *p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4)) - & 0x3F); - - if ((i + 1) < slen) { - *p++ = mbedtls_ct_base64_enc_char(((C2 & 15) << 2) & 0x3F); - } else { - *p++ = '='; - } - - *p++ = '='; - } - - *olen = (size_t) (p - dst); - *p = 0; - - return 0; -} - -/* - * Decode a base64-formatted buffer - */ -int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen, - const unsigned char *src, size_t slen) -{ - size_t i; /* index in source */ - size_t n; /* number of digits or trailing = in source */ - uint32_t x; /* value accumulator */ - unsigned accumulated_digits = 0; - unsigned equals = 0; - int spaces_present = 0; - unsigned char *p; - - /* First pass: check for validity and get output length */ - for (i = n = 0; i < slen; i++) { - /* Skip spaces before checking for EOL */ - spaces_present = 0; - while (i < slen && src[i] == ' ') { - ++i; - spaces_present = 1; - } - - /* Spaces at end of buffer are OK */ - if (i == slen) { - break; - } - - if ((slen - i) >= 2 && - src[i] == '\r' && src[i + 1] == '\n') { - continue; - } - - if (src[i] == '\n') { - continue; - } - - /* Space inside a line is an error */ - if (spaces_present) { - return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; - } - - if (src[i] > 127) { - return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; - } - - if (src[i] == '=') { - if (++equals > 2) { - return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; - } - } else { - if (equals != 0) { - return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; - } - if (mbedtls_ct_base64_dec_value(src[i]) < 0) { - return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; - } - } - n++; - } - - /* In valid base64, the number of digits (n-equals) is always of the form - * 4*k, 4*k+2 or *4k+3. Also, the number n of digits plus the number of - * equal signs at the end is always a multiple of 4. */ - if ((n - equals) % 4 == 1) { - return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; - } - if (n % 4 != 0) { - return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; - } - - /* We've determined that the input is valid, and that it contains - * exactly k blocks of digits-or-equals, with n = 4 * k, - * and equals only present at the end of the last block if at all. - * Now we can calculate the length of the output. - * - * Each block of 4 digits in the input map to 3 bytes of output. - * For the last block: - * - abcd (where abcd are digits) is a full 3-byte block; - * - abc= means 1 byte less than a full 3-byte block of output; - * - ab== means 2 bytes less than a full 3-byte block of output; - * - a==== and ==== is rejected above. - */ - *olen = (n / 4) * 3 - equals; - - /* If the output buffer is too small, signal this and stop here. - * Also, as documented, stop here if `dst` is null, independently of - * `dlen`. - * - * There is an edge case when the output is empty: in this case, - * `dlen == 0` with `dst == NULL` is valid (on some platforms, - * `malloc(0)` returns `NULL`). Since the call is valid, we return - * 0 in this case. - */ - if ((*olen != 0 && dst == NULL) || dlen < *olen) { - return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; - } - - for (x = 0, p = dst; i > 0; i--, src++) { - if (*src == '\r' || *src == '\n' || *src == ' ') { - continue; - } - if (*src == '=') { - /* We already know from the first loop that equal signs are - * only at the end. */ - break; - } - x = x << 6; - x |= mbedtls_ct_base64_dec_value(*src); - - if (++accumulated_digits == 4) { - accumulated_digits = 0; - *p++ = MBEDTLS_BYTE_2(x); - *p++ = MBEDTLS_BYTE_1(x); - *p++ = MBEDTLS_BYTE_0(x); - } - } - if (accumulated_digits == 3) { - *p++ = MBEDTLS_BYTE_2(x << 6); - *p++ = MBEDTLS_BYTE_1(x << 6); - } else if (accumulated_digits == 2) { - *p++ = MBEDTLS_BYTE_2(x << 12); - } - - if (*olen != (size_t) (p - dst)) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - - return 0; -} - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char base64_test_dec[64] = -{ - 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, - 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, - 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, - 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, - 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, - 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, - 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, - 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 -}; - -static const unsigned char base64_test_enc[] = - "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" - "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; - -/* - * Checkup routine - */ -int mbedtls_base64_self_test(int verbose) -{ - size_t len; - const unsigned char *src; - unsigned char buffer[128]; - - if (verbose != 0) { - mbedtls_printf(" Base64 encoding test: "); - } - - src = base64_test_dec; - - if (mbedtls_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 || - memcmp(base64_test_enc, buffer, 88) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return 1; - } - - if (verbose != 0) { - mbedtls_printf("passed\n Base64 decoding test: "); - } - - src = base64_test_enc; - - if (mbedtls_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 || - memcmp(base64_test_dec, buffer, 64) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return 1; - } - - if (verbose != 0) { - mbedtls_printf("passed\n\n"); - } - - return 0; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_BASE64_C */ diff --git a/vendor/mbedtls/library/base64_internal.h b/vendor/mbedtls/library/base64_internal.h deleted file mode 100644 index a09bd2377..000000000 --- a/vendor/mbedtls/library/base64_internal.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * \file base64_internal.h - * - * \brief RFC 1521 base64 encoding/decoding: interfaces for invasive testing - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_BASE64_INTERNAL -#define MBEDTLS_BASE64_INTERNAL - -#include "common.h" - -#if defined(MBEDTLS_TEST_HOOKS) - -/** Given a value in the range 0..63, return the corresponding Base64 digit. - * - * The implementation assumes that letters are consecutive (e.g. ASCII - * but not EBCDIC). - * - * \param value A value in the range 0..63. - * - * \return A base64 digit converted from \p value. - */ -unsigned char mbedtls_ct_base64_enc_char(unsigned char value); - -/** Given a Base64 digit, return its value. - * - * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'), - * return -1. - * - * The implementation assumes that letters are consecutive (e.g. ASCII - * but not EBCDIC). - * - * \param c A base64 digit. - * - * \return The value of the base64 digit \p c. - */ -signed char mbedtls_ct_base64_dec_value(unsigned char c); - -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* MBEDTLS_BASE64_INTERNAL */ diff --git a/vendor/mbedtls/library/bignum.c b/vendor/mbedtls/library/bignum.c deleted file mode 100644 index f6b8f9998..000000000 --- a/vendor/mbedtls/library/bignum.c +++ /dev/null @@ -1,2558 +0,0 @@ -/* - * Multi-precision integer library - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The following sources were referenced in the design of this Multi-precision - * Integer library: - * - * [1] Handbook of Applied Cryptography - 1997 - * Menezes, van Oorschot and Vanstone - * - * [2] Multi-Precision Math - * Tom St Denis - * https://github.com/libtom/libtommath/blob/develop/tommath.pdf - * - * [3] GNU Multi-Precision Arithmetic Library - * https://gmplib.org/manual/index.html - * - */ - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) - -#include "mbedtls/bignum.h" -#include "bignum_core.h" -#include "bignum_internal.h" -#include "bn_mul.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "constant_time_internal.h" - -#include -#include - -#include "mbedtls/platform.h" - - - -/* - * Conditionally select an MPI sign in constant time. - * (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid - * values.) - */ -static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond, - signed short sign1, signed short sign2) -{ - return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1; -} - -/* - * Compare signed values in constant time - */ -int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X, - const mbedtls_mpi *Y, - unsigned *ret) -{ - mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result; - - if (X->n != Y->n) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - /* - * Set N_is_negative to MBEDTLS_CT_FALSE if N >= 0, MBEDTLS_CT_TRUE if N < 0. - * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0. - */ - X_is_negative = mbedtls_ct_bool((X->s & 2) >> 1); - Y_is_negative = mbedtls_ct_bool((Y->s & 2) >> 1); - - /* - * If the signs are different, then the positive operand is the bigger. - * That is if X is negative (X_is_negative == 1), then X < Y is true and it - * is false if X is positive (X_is_negative == 0). - */ - different_sign = mbedtls_ct_bool_ne(X_is_negative, Y_is_negative); // true if different sign - result = mbedtls_ct_bool_and(different_sign, X_is_negative); - - /* - * Assuming signs are the same, compare X and Y. We switch the comparison - * order if they are negative so that we get the right result, regardles of - * sign. - */ - - /* This array is used to conditionally swap the pointers in const time */ - void * const p[2] = { X->p, Y->p }; - size_t i = mbedtls_ct_size_if_else_0(X_is_negative, 1); - mbedtls_ct_condition_t lt = mbedtls_mpi_core_lt_ct(p[i], p[i ^ 1], X->n); - - /* - * Store in result iff the signs are the same (i.e., iff different_sign == false). If - * the signs differ, result has already been set, so we don't change it. - */ - result = mbedtls_ct_bool_or(result, - mbedtls_ct_bool_and(mbedtls_ct_bool_not(different_sign), lt)); - - *ret = mbedtls_ct_uint_if_else_0(result, 1); - - return 0; -} - -/* - * Conditionally assign X = Y, without leaking information - * about whether the assignment was made or not. - * (Leaking information about the respective sizes of X and Y is ok however.) - */ -#if defined(_MSC_VER) && defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \ - (_MSC_FULL_VER < 193131103) -/* - * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See: - * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989 - */ -__declspec(noinline) -#endif -int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X, - const mbedtls_mpi *Y, - unsigned char assign) -{ - int ret = 0; - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n)); - - { - mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign); - - X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s); - - mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign); - - mbedtls_ct_condition_t do_not_assign = mbedtls_ct_bool_not(do_assign); - for (size_t i = Y->n; i < X->n; i++) { - X->p[i] = mbedtls_ct_mpi_uint_if_else_0(do_not_assign, X->p[i]); - } - } - -cleanup: - return ret; -} - -/* - * Conditionally swap X and Y, without leaking information - * about whether the swap was made or not. - * Here it is not ok to simply swap the pointers, which would lead to - * different memory access patterns when X and Y are used afterwards. - */ -int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X, - mbedtls_mpi *Y, - unsigned char swap) -{ - int ret = 0; - int s; - - if (X == Y) { - return 0; - } - - mbedtls_ct_condition_t do_swap = mbedtls_ct_bool(swap); - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n)); - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n)); - - s = X->s; - X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s); - Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s); - - mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap); - -cleanup: - return ret; -} - -/* Implementation that should never be optimized out by the compiler */ -#define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n)) - -/* - * Initialize one MPI - */ -void mbedtls_mpi_init(mbedtls_mpi *X) -{ - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Unallocate one MPI - */ -void mbedtls_mpi_free(mbedtls_mpi *X) -{ - if (X == NULL) { - return; - } - - if (X->p != NULL) { - mbedtls_mpi_zeroize_and_free(X->p, X->n); - } - - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Enlarge to the specified number of limbs - */ -int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs) -{ - mbedtls_mpi_uint *p; - - if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - if (X->n < nblimbs) { - if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL)) == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - if (X->p != NULL) { - memcpy(p, X->p, X->n * ciL); - mbedtls_mpi_zeroize_and_free(X->p, X->n); - } - - /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS - * fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */ - X->n = (unsigned short) nblimbs; - X->p = p; - } - - return 0; -} - -/* - * Resize down as much as possible, - * while keeping at least the specified number of limbs - */ -int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs) -{ - mbedtls_mpi_uint *p; - size_t i; - - if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - /* Actually resize up if there are currently fewer than nblimbs limbs. */ - if (X->n <= nblimbs) { - return mbedtls_mpi_grow(X, nblimbs); - } - /* After this point, then X->n > nblimbs and in particular X->n > 0. */ - - for (i = X->n - 1; i > 0; i--) { - if (X->p[i] != 0) { - break; - } - } - i++; - - if (i < nblimbs) { - i = nblimbs; - } - - if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - if (X->p != NULL) { - memcpy(p, X->p, i * ciL); - mbedtls_mpi_zeroize_and_free(X->p, X->n); - } - - /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS - * fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */ - X->n = (unsigned short) i; - X->p = p; - - return 0; -} - -/* Resize X to have exactly n limbs and set it to 0. */ -static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs) -{ - if (limbs == 0) { - mbedtls_mpi_free(X); - return 0; - } else if (X->n == limbs) { - memset(X->p, 0, limbs * ciL); - X->s = 1; - return 0; - } else { - mbedtls_mpi_free(X); - return mbedtls_mpi_grow(X, limbs); - } -} - -/* - * Copy the contents of Y into X. - * - * This function is not constant-time. Leading zeros in Y may be removed. - * - * Ensure that X does not shrink. This is not guaranteed by the public API, - * but some code in the bignum module might still rely on this property. - */ -int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y) -{ - int ret = 0; - size_t i; - - if (X == Y) { - return 0; - } - - if (Y->n == 0) { - if (X->n != 0) { - X->s = 1; - memset(X->p, 0, X->n * ciL); - } - return 0; - } - - for (i = Y->n - 1; i > 0; i--) { - if (Y->p[i] != 0) { - break; - } - } - i++; - - X->s = Y->s; - - if (X->n < i) { - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i)); - } else { - memset(X->p + i, 0, (X->n - i) * ciL); - } - - memcpy(X->p, Y->p, i * ciL); - -cleanup: - - return ret; -} - -/* - * Swap the contents of X and Y - */ -void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y) -{ - mbedtls_mpi T; - - memcpy(&T, X, sizeof(mbedtls_mpi)); - memcpy(X, Y, sizeof(mbedtls_mpi)); - memcpy(Y, &T, sizeof(mbedtls_mpi)); -} - -static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z) -{ - if (z >= 0) { - return z; - } - /* Take care to handle the most negative value (-2^(biL-1)) correctly. - * A naive -z would have undefined behavior. - * Write this in a way that makes popular compilers happy (GCC, Clang, - * MSVC). */ - return (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z; -} - -/* Convert x to a sign, i.e. to 1, if x is positive, or -1, if x is negative. - * This looks awkward but generates smaller code than (x < 0 ? -1 : 1) */ -#define TO_SIGN(x) ((mbedtls_mpi_sint) (((mbedtls_mpi_uint) x) >> (biL - 1)) * -2 + 1) - -/* - * Set value from integer - */ -int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1)); - memset(X->p, 0, X->n * ciL); - - X->p[0] = mpi_sint_abs(z); - X->s = TO_SIGN(z); - -cleanup: - - return ret; -} - -/* - * Get a specific bit - */ -int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos) -{ - if (X->n * biL <= pos) { - return 0; - } - - return (X->p[pos / biL] >> (pos % biL)) & 0x01; -} - -/* - * Set a bit to a specific value of 0 or 1 - */ -int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val) -{ - int ret = 0; - size_t off = pos / biL; - size_t idx = pos % biL; - - if (val != 0 && val != 1) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (X->n * biL <= pos) { - if (val == 0) { - return 0; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, off + 1)); - } - - X->p[off] &= ~((mbedtls_mpi_uint) 0x01 << idx); - X->p[off] |= (mbedtls_mpi_uint) val << idx; - -cleanup: - - return ret; -} - -#if defined(__has_builtin) -#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz) - #define mbedtls_mpi_uint_ctz __builtin_ctz -#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl) - #define mbedtls_mpi_uint_ctz __builtin_ctzl -#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll) - #define mbedtls_mpi_uint_ctz __builtin_ctzll -#endif -#endif - -#if !defined(mbedtls_mpi_uint_ctz) -static size_t mbedtls_mpi_uint_ctz(mbedtls_mpi_uint x) -{ - size_t count = 0; - mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE; - - for (size_t i = 0; i < biL; i++) { - mbedtls_ct_condition_t non_zero = mbedtls_ct_bool((x >> i) & 1); - done = mbedtls_ct_bool_or(done, non_zero); - count = mbedtls_ct_size_if(done, count, i + 1); - } - - return count; -} -#endif - -/* - * Return the number of less significant zero-bits - */ -size_t mbedtls_mpi_lsb(const mbedtls_mpi *X) -{ - size_t i; - - for (i = 0; i < X->n; i++) { - if (X->p[i] != 0) { - return i * biL + mbedtls_mpi_uint_ctz(X->p[i]); - } - } - - return 0; -} - -/* - * Return the number of bits - */ -size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X) -{ - return mbedtls_mpi_core_bitlen(X->p, X->n); -} - -/* - * Return the total size in bytes - */ -size_t mbedtls_mpi_size(const mbedtls_mpi *X) -{ - return (mbedtls_mpi_bitlen(X) + 7) >> 3; -} - -/* - * Convert an ASCII character to digit value - */ -static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c) -{ - *d = 255; - - if (c >= 0x30 && c <= 0x39) { - *d = c - 0x30; - } - if (c >= 0x41 && c <= 0x46) { - *d = c - 0x37; - } - if (c >= 0x61 && c <= 0x66) { - *d = c - 0x57; - } - - if (*d >= (mbedtls_mpi_uint) radix) { - return MBEDTLS_ERR_MPI_INVALID_CHARACTER; - } - - return 0; -} - -/* - * Import from an ASCII string - */ -int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, j, slen, n; - int sign = 1; - mbedtls_mpi_uint d; - mbedtls_mpi T; - - if (radix < 2 || radix > 16) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_init(&T); - - if (s[0] == 0) { - mbedtls_mpi_free(X); - return 0; - } - - if (s[0] == '-') { - ++s; - sign = -1; - } - - slen = strlen(s); - - if (radix == 16) { - if (slen > SIZE_MAX >> 2) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - n = BITS_TO_LIMBS(slen << 2); - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0)); - - for (i = slen, j = 0; i > 0; i--, j++) { - MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1])); - X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2); - } - } else { - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0)); - - for (i = 0; i < slen; i++) { - MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i])); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d)); - } - } - - if (sign < 0 && mbedtls_mpi_bitlen(X) != 0) { - X->s = -1; - } - -cleanup: - - mbedtls_mpi_free(&T); - - return ret; -} - -/* - * Helper to write the digits high-order first. - */ -static int mpi_write_hlp(mbedtls_mpi *X, int radix, - char **p, const size_t buflen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi_uint r; - size_t length = 0; - char *p_end = *p + buflen; - - do { - if (length >= buflen) { - return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix)); - MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix)); - /* - * Write the residue in the current position, as an ASCII character. - */ - if (r < 0xA) { - *(--p_end) = (char) ('0' + r); - } else { - *(--p_end) = (char) ('A' + (r - 0xA)); - } - - length++; - } while (mbedtls_mpi_cmp_int(X, 0) != 0); - - memmove(*p, p_end, length); - *p += length; - -cleanup: - - return ret; -} - -/* - * Export into an ASCII string - */ -int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix, - char *buf, size_t buflen, size_t *olen) -{ - int ret = 0; - size_t n; - char *p; - mbedtls_mpi T; - - if (radix < 2 || radix > 16) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - n = mbedtls_mpi_bitlen(X); /* Number of bits necessary to present `n`. */ - if (radix >= 4) { - n >>= 1; /* Number of 4-adic digits necessary to present - * `n`. If radix > 4, this might be a strict - * overapproximation of the number of - * radix-adic digits needed to present `n`. */ - } - if (radix >= 16) { - n >>= 1; /* Number of hexadecimal digits necessary to - * present `n`. */ - - } - n += 1; /* Terminating null byte */ - n += 1; /* Compensate for the divisions above, which round down `n` - * in case it's not even. */ - n += 1; /* Potential '-'-sign. */ - n += (n & 1); /* Make n even to have enough space for hexadecimal writing, - * which always uses an even number of hex-digits. */ - - if (buflen < n) { - *olen = n; - return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; - } - - p = buf; - mbedtls_mpi_init(&T); - - if (X->s == -1) { - *p++ = '-'; - buflen--; - } - - if (radix == 16) { - int c; - size_t i, j, k; - - for (i = X->n, k = 0; i > 0; i--) { - for (j = ciL; j > 0; j--) { - c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF; - - if (c == 0 && k == 0 && (i + j) != 2) { - continue; - } - - *(p++) = "0123456789ABCDEF" [c / 16]; - *(p++) = "0123456789ABCDEF" [c % 16]; - k = 1; - } - } - } else { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X)); - - if (T.s == -1) { - T.s = 1; - } - - MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen)); - } - - *p++ = '\0'; - *olen = (size_t) (p - buf); - -cleanup: - - mbedtls_mpi_free(&T); - - return ret; -} - -#if defined(MBEDTLS_FS_IO) -/* - * Read X from an opened file - */ -int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin) -{ - mbedtls_mpi_uint d; - size_t slen; - char *p; - /* - * Buffer should have space for (short) label and decimal formatted MPI, - * newline characters and '\0' - */ - char s[MBEDTLS_MPI_RW_BUFFER_SIZE]; - - if (radix < 2 || radix > 16) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - memset(s, 0, sizeof(s)); - if (fgets(s, sizeof(s) - 1, fin) == NULL) { - return MBEDTLS_ERR_MPI_FILE_IO_ERROR; - } - - slen = strlen(s); - if (slen == sizeof(s) - 2) { - return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; - } - - if (slen > 0 && s[slen - 1] == '\n') { - slen--; s[slen] = '\0'; - } - if (slen > 0 && s[slen - 1] == '\r') { - slen--; s[slen] = '\0'; - } - - p = s + slen; - while (p-- > s) { - if (mpi_get_digit(&d, radix, *p) != 0) { - break; - } - } - - return mbedtls_mpi_read_string(X, radix, p + 1); -} - -/* - * Write X into an opened file (or stdout if fout == NULL) - */ -int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n, slen, plen; - /* - * Buffer should have space for (short) label and decimal formatted MPI, - * newline characters and '\0' - */ - char s[MBEDTLS_MPI_RW_BUFFER_SIZE]; - - if (radix < 2 || radix > 16) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - memset(s, 0, sizeof(s)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n)); - - if (p == NULL) { - p = ""; - } - - plen = strlen(p); - slen = strlen(s); - s[slen++] = '\r'; - s[slen++] = '\n'; - - if (fout != NULL) { - if (fwrite(p, 1, plen, fout) != plen || - fwrite(s, 1, slen, fout) != slen) { - return MBEDTLS_ERR_MPI_FILE_IO_ERROR; - } - } else { - mbedtls_printf("%s%s", p, s); - } - -cleanup: - - return ret; -} -#endif /* MBEDTLS_FS_IO */ - -/* - * Import X from unsigned binary data, little endian - * - * This function is guaranteed to return an MPI with exactly the necessary - * number of limbs (in particular, it does not skip 0s in the input). - */ -int mbedtls_mpi_read_binary_le(mbedtls_mpi *X, - const unsigned char *buf, size_t buflen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const size_t limbs = CHARS_TO_LIMBS(buflen); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_le(X->p, X->n, buf, buflen)); - -cleanup: - - /* - * This function is also used to import keys. However, wiping the buffers - * upon failure is not necessary because failure only can happen before any - * input is copied. - */ - return ret; -} - -/* - * Import X from unsigned binary data, big endian - * - * This function is guaranteed to return an MPI with exactly the necessary - * number of limbs (in particular, it does not skip 0s in the input). - */ -int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const size_t limbs = CHARS_TO_LIMBS(buflen); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_be(X->p, X->n, buf, buflen)); - -cleanup: - - /* - * This function is also used to import keys. However, wiping the buffers - * upon failure is not necessary because failure only can happen before any - * input is copied. - */ - return ret; -} - -/* - * Export X into unsigned binary data, little endian - */ -int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X, - unsigned char *buf, size_t buflen) -{ - return mbedtls_mpi_core_write_le(X->p, X->n, buf, buflen); -} - -/* - * Export X into unsigned binary data, big endian - */ -int mbedtls_mpi_write_binary(const mbedtls_mpi *X, - unsigned char *buf, size_t buflen) -{ - return mbedtls_mpi_core_write_be(X->p, X->n, buf, buflen); -} - -/* - * Left-shift: X <<= count - */ -int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - - i = mbedtls_mpi_bitlen(X) + count; - - if (X->n * biL < i) { - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i))); - } - - ret = 0; - - mbedtls_mpi_core_shift_l(X->p, X->n, count); -cleanup: - - return ret; -} - -/* - * Right-shift: X >>= count - */ -int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count) -{ - if (X->n != 0) { - mbedtls_mpi_core_shift_r(X->p, X->n, count); - } - return 0; -} - -/* - * Compare unsigned values - */ -int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y) -{ - size_t i, j; - - for (i = X->n; i > 0; i--) { - if (X->p[i - 1] != 0) { - break; - } - } - - for (j = Y->n; j > 0; j--) { - if (Y->p[j - 1] != 0) { - break; - } - } - - /* If i == j == 0, i.e. abs(X) == abs(Y), - * we end up returning 0 at the end of the function. */ - - if (i > j) { - return 1; - } - if (j > i) { - return -1; - } - - for (; i > 0; i--) { - if (X->p[i - 1] > Y->p[i - 1]) { - return 1; - } - if (X->p[i - 1] < Y->p[i - 1]) { - return -1; - } - } - - return 0; -} - -/* - * Compare signed values - */ -int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y) -{ - size_t i, j; - - for (i = X->n; i > 0; i--) { - if (X->p[i - 1] != 0) { - break; - } - } - - for (j = Y->n; j > 0; j--) { - if (Y->p[j - 1] != 0) { - break; - } - } - - if (i == 0 && j == 0) { - return 0; - } - - if (i > j) { - return X->s; - } - if (j > i) { - return -Y->s; - } - - if (X->s > 0 && Y->s < 0) { - return 1; - } - if (Y->s > 0 && X->s < 0) { - return -1; - } - - for (; i > 0; i--) { - if (X->p[i - 1] > Y->p[i - 1]) { - return X->s; - } - if (X->p[i - 1] < Y->p[i - 1]) { - return -X->s; - } - } - - return 0; -} - -/* - * Compare signed values - */ -int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z) -{ - mbedtls_mpi Y; - mbedtls_mpi_uint p[1]; - - *p = mpi_sint_abs(z); - Y.s = TO_SIGN(z); - Y.n = 1; - Y.p = p; - - return mbedtls_mpi_cmp_mpi(X, &Y); -} - -/* - * Unsigned addition: X = |A| + |B| (HAC 14.7) - */ -int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t j; - mbedtls_mpi_uint *p; - mbedtls_mpi_uint c; - - if (X == B) { - const mbedtls_mpi *T = A; A = X; B = T; - } - - if (X != A) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A)); - } - - /* - * X must always be positive as a result of unsigned additions. - */ - X->s = 1; - - for (j = B->n; j > 0; j--) { - if (B->p[j - 1] != 0) { - break; - } - } - - /* Exit early to avoid undefined behavior on NULL+0 when X->n == 0 - * and B is 0 (of any size). */ - if (j == 0) { - return 0; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j)); - - /* j is the number of non-zero limbs of B. Add those to X. */ - - p = X->p; - - c = mbedtls_mpi_core_add(p, p, B->p, j); - - p += j; - - /* Now propagate any carry */ - - while (c != 0) { - if (j >= X->n) { - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j + 1)); - p = X->p + j; - } - - *p += c; c = (*p < c); j++; p++; - } - -cleanup: - - return ret; -} - -/* - * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10) - */ -int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - mbedtls_mpi_uint carry; - - for (n = B->n; n > 0; n--) { - if (B->p[n - 1] != 0) { - break; - } - } - if (n > A->n) { - /* B >= (2^ciL)^n > A */ - ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, A->n)); - - /* Set the high limbs of X to match A. Don't touch the lower limbs - * because X might be aliased to B, and we must not overwrite the - * significant digits of B. */ - if (A->n > n && A != X) { - memcpy(X->p + n, A->p + n, (A->n - n) * ciL); - } - if (X->n > A->n) { - memset(X->p + A->n, 0, (X->n - A->n) * ciL); - } - - carry = mbedtls_mpi_core_sub(X->p, A->p, B->p, n); - if (carry != 0) { - /* Propagate the carry through the rest of X. */ - carry = mbedtls_mpi_core_sub_int(X->p + n, X->p + n, carry, X->n - n); - - /* If we have further carry/borrow, the result is negative. */ - if (carry != 0) { - ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; - goto cleanup; - } - } - - /* X should always be positive as a result of unsigned subtractions. */ - X->s = 1; - -cleanup: - return ret; -} - -/* Common function for signed addition and subtraction. - * Calculate A + B * flip_B where flip_B is 1 or -1. - */ -static int add_sub_mpi(mbedtls_mpi *X, - const mbedtls_mpi *A, const mbedtls_mpi *B, - int flip_B) -{ - int ret, s; - - s = A->s; - if (A->s * B->s * flip_B < 0) { - int cmp = mbedtls_mpi_cmp_abs(A, B); - if (cmp >= 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B)); - /* If |A| = |B|, the result is 0 and we must set the sign bit - * to +1 regardless of which of A or B was negative. Otherwise, - * since |A| > |B|, the sign is the sign of A. */ - X->s = cmp == 0 ? 1 : s; - } else { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A)); - /* Since |A| < |B|, the sign is the opposite of A. */ - X->s = -s; - } - } else { - MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B)); - X->s = s; - } - -cleanup: - - return ret; -} - -/* - * Signed addition: X = A + B - */ -int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) -{ - return add_sub_mpi(X, A, B, 1); -} - -/* - * Signed subtraction: X = A - B - */ -int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) -{ - return add_sub_mpi(X, A, B, -1); -} - -/* - * Signed addition: X = A + b - */ -int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b) -{ - mbedtls_mpi B; - mbedtls_mpi_uint p[1]; - - p[0] = mpi_sint_abs(b); - B.s = TO_SIGN(b); - B.n = 1; - B.p = p; - - return mbedtls_mpi_add_mpi(X, A, &B); -} - -/* - * Signed subtraction: X = A - b - */ -int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b) -{ - mbedtls_mpi B; - mbedtls_mpi_uint p[1]; - - p[0] = mpi_sint_abs(b); - B.s = TO_SIGN(b); - B.n = 1; - B.p = p; - - return mbedtls_mpi_sub_mpi(X, A, &B); -} - -/* - * Baseline multiplication: X = A * B (HAC 14.12) - */ -int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, j; - mbedtls_mpi TA, TB; - int result_is_zero = 0; - - mbedtls_mpi_init(&TA); - mbedtls_mpi_init(&TB); - - if (X == A) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA; - } - if (X == B) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB; - } - - for (i = A->n; i > 0; i--) { - if (A->p[i - 1] != 0) { - break; - } - } - if (i == 0) { - result_is_zero = 1; - } - - for (j = B->n; j > 0; j--) { - if (B->p[j - 1] != 0) { - break; - } - } - if (j == 0) { - result_is_zero = 1; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0)); - - mbedtls_mpi_core_mul(X->p, A->p, i, B->p, j); - - /* If the result is 0, we don't shortcut the operation, which reduces - * but does not eliminate side channels leaking the zero-ness. We do - * need to take care to set the sign bit properly since the library does - * not fully support an MPI object with a value of 0 and s == -1. */ - if (result_is_zero) { - X->s = 1; - } else { - X->s = A->s * B->s; - } - -cleanup: - - mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TA); - - return ret; -} - -/* - * Baseline multiplication: X = A * b - */ -int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b) -{ - size_t n = A->n; - while (n > 0 && A->p[n - 1] == 0) { - --n; - } - - /* The general method below doesn't work if b==0. */ - if (b == 0 || n == 0) { - return mbedtls_mpi_lset(X, 0); - } - - /* Calculate A*b as A + A*(b-1) to take advantage of mbedtls_mpi_core_mla */ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - /* In general, A * b requires 1 limb more than b. If - * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same - * number of limbs as A and the call to grow() is not required since - * copy() will take care of the growth if needed. However, experimentally, - * making the call to grow() unconditional causes slightly fewer - * calls to calloc() in ECP code, presumably because it reuses the - * same mpi for a while and this way the mpi is more likely to directly - * grow to its final size. - * - * Note that calculating A*b as 0 + A*b doesn't work as-is because - * A,X can be the same. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n + 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A)); - mbedtls_mpi_core_mla(X->p, X->n, A->p, n, b - 1); - -cleanup: - return ret; -} - -/* - * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and - * mbedtls_mpi_uint divisor, d - */ -static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1, - mbedtls_mpi_uint u0, - mbedtls_mpi_uint d, - mbedtls_mpi_uint *r) -{ -#if defined(MBEDTLS_HAVE_UDBL) - mbedtls_t_udbl dividend, quotient; -#else - const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH; - const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1; - mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient; - mbedtls_mpi_uint u0_msw, u0_lsw; - size_t s; -#endif - - /* - * Check for overflow - */ - if (0 == d || u1 >= d) { - if (r != NULL) { - *r = ~(mbedtls_mpi_uint) 0u; - } - - return ~(mbedtls_mpi_uint) 0u; - } - -#if defined(MBEDTLS_HAVE_UDBL) - dividend = (mbedtls_t_udbl) u1 << biL; - dividend |= (mbedtls_t_udbl) u0; - quotient = dividend / d; - if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1) { - quotient = ((mbedtls_t_udbl) 1 << biL) - 1; - } - - if (r != NULL) { - *r = (mbedtls_mpi_uint) (dividend - (quotient * d)); - } - - return (mbedtls_mpi_uint) quotient; -#else - - /* - * Algorithm D, Section 4.3.1 - The Art of Computer Programming - * Vol. 2 - Seminumerical Algorithms, Knuth - */ - - /* - * Normalize the divisor, d, and dividend, u0, u1 - */ - s = mbedtls_mpi_core_clz(d); - d = d << s; - - u1 = u1 << s; - u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint) s >> (biL - 1)); - u0 = u0 << s; - - d1 = d >> biH; - d0 = d & uint_halfword_mask; - - u0_msw = u0 >> biH; - u0_lsw = u0 & uint_halfword_mask; - - /* - * Find the first quotient and remainder - */ - q1 = u1 / d1; - r0 = u1 - d1 * q1; - - while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) { - q1 -= 1; - r0 += d1; - - if (r0 >= radix) { - break; - } - } - - rAX = (u1 * radix) + (u0_msw - q1 * d); - q0 = rAX / d1; - r0 = rAX - q0 * d1; - - while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) { - q0 -= 1; - r0 += d1; - - if (r0 >= radix) { - break; - } - } - - if (r != NULL) { - *r = (rAX * radix + u0_lsw - q0 * d) >> s; - } - - quotient = q1 * radix + q0; - - return quotient; -#endif -} - -/* - * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) - */ -int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, - const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, n, t, k; - mbedtls_mpi X, Y, Z, T1, T2; - mbedtls_mpi_uint TP2[3]; - - if (mbedtls_mpi_cmp_int(B, 0) == 0) { - return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO; - } - - mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); - mbedtls_mpi_init(&T1); - /* - * Avoid dynamic memory allocations for constant-size T2. - * - * T2 is used for comparison only and the 3 limbs are assigned explicitly, - * so nobody increase the size of the MPI and we're safe to use an on-stack - * buffer. - */ - T2.s = 1; - T2.n = sizeof(TP2) / sizeof(*TP2); - T2.p = TP2; - - if (mbedtls_mpi_cmp_abs(A, B) < 0) { - if (Q != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0)); - } - if (R != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A)); - } - return 0; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B)); - X.s = Y.s = 1; - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z, 0)); - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, A->n + 2)); - - k = mbedtls_mpi_bitlen(&Y) % biL; - if (k < biL - 1) { - k = biL - 1 - k; - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k)); - } else { - k = 0; - } - - n = X.n - 1; - t = Y.n - 1; - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t))); - - while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) { - Z.p[n - t]++; - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y)); - } - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t))); - - for (i = n; i > t; i--) { - if (X.p[i] >= Y.p[t]) { - Z.p[i - t - 1] = ~(mbedtls_mpi_uint) 0u; - } else { - Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1], - Y.p[t], NULL); - } - - T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; - T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; - T2.p[2] = X.p[i]; - - Z.p[i - t - 1]++; - do { - Z.p[i - t - 1]--; - - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0)); - T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; - T1.p[1] = Y.p[t]; - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1])); - } while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1])); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1))); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1)); - - if (mbedtls_mpi_cmp_int(&X, 0) < 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1))); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1)); - Z.p[i - t - 1]--; - } - } - - if (Q != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z)); - Q->s = A->s * B->s; - } - - if (R != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k)); - X.s = A->s; - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X)); - - if (mbedtls_mpi_cmp_int(R, 0) == 0) { - R->s = 1; - } - } - -cleanup: - - mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); - mbedtls_mpi_free(&T1); - mbedtls_platform_zeroize(TP2, sizeof(TP2)); - - return ret; -} - -/* - * Division by int: A = Q * b + R - */ -int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R, - const mbedtls_mpi *A, - mbedtls_mpi_sint b) -{ - mbedtls_mpi B; - mbedtls_mpi_uint p[1]; - - p[0] = mpi_sint_abs(b); - B.s = TO_SIGN(b); - B.n = 1; - B.p = p; - - return mbedtls_mpi_div_mpi(Q, R, A, &B); -} - -/* - * Modulo: R = A mod B - */ -int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (mbedtls_mpi_cmp_int(B, 0) < 0) { - return MBEDTLS_ERR_MPI_NEGATIVE_VALUE; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B)); - - while (mbedtls_mpi_cmp_int(R, 0) < 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B)); - } - - while (mbedtls_mpi_cmp_mpi(R, B) >= 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B)); - } - -cleanup: - - return ret; -} - -/* - * Modulo: r = A mod b - */ -int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b) -{ - size_t i; - mbedtls_mpi_uint x, y, z; - - if (b == 0) { - return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO; - } - - if (b < 0) { - return MBEDTLS_ERR_MPI_NEGATIVE_VALUE; - } - - /* - * handle trivial cases - */ - if (b == 1 || A->n == 0) { - *r = 0; - return 0; - } - - if (b == 2) { - *r = A->p[0] & 1; - return 0; - } - - /* - * general case - */ - for (i = A->n, y = 0; i > 0; i--) { - x = A->p[i - 1]; - y = (y << biH) | (x >> biH); - z = y / b; - y -= z * b; - - x <<= biH; - y = (y << biH) | (x >> biH); - z = y / b; - y -= z * b; - } - - /* - * If A is negative, then the current y represents a negative value. - * Flipping it to the positive side. - */ - if (A->s < 0 && y != 0) { - y = b - y; - } - - *r = y; - - return 0; -} - -/* - * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value, - * this function is not constant time with respect to the exponent (parameter E). - */ -static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, int E_public, - const mbedtls_mpi *N, mbedtls_mpi *prec_RR) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (mbedtls_mpi_cmp_int(E, 0) < 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS || - mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - /* - * Ensure that the exponent that we are passing to the core is not NULL. - */ - if (E->n == 0) { - ret = mbedtls_mpi_lset(X, 1); - return ret; - } - - /* - * Allocate working memory for mbedtls_mpi_core_exp_mod() - */ - size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n); - mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint)); - if (T == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - mbedtls_mpi RR; - mbedtls_mpi_init(&RR); - - /* - * If 1st call, pre-compute R^2 mod N - */ - if (prec_RR == NULL || prec_RR->p == NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N)); - - if (prec_RR != NULL) { - *prec_RR = RR; - } - } else { - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n)); - RR = *prec_RR; - } - - /* - * To preserve constness we need to make a copy of A. Using X for this to - * save memory. - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A)); - - /* - * Compensate for negative A (and correct at the end). - */ - X->s = 1; - - /* - * Make sure that X is in a form that is safe for consumption by - * the core functions. - * - * - The core functions will not touch the limbs of X above N->n. The - * result will be correct if those limbs are 0, which the mod call - * ensures. - * - Also, X must have at least as many limbs as N for the calls to the - * core functions. - */ - if (mbedtls_mpi_cmp_mpi(X, N) >= 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N)); - } - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n)); - - /* - * Convert to and from Montgomery around mbedtls_mpi_core_exp_mod(). - */ - { - mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); - mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T); - if (E_public == MBEDTLS_MPI_IS_PUBLIC) { - mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T); - } else { - mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T); - } - mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T); - } - - /* - * Correct for negative A. - */ - if (A->s == -1 && (E->p[0] & 1) != 0) { - mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n); - X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1); - - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X)); - } - -cleanup: - - mbedtls_mpi_zeroize_and_free(T, T_limbs); - - if (prec_RR == NULL || prec_RR->p == NULL) { - mbedtls_mpi_free(&RR); - } - - return ret; -} - -int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR) -{ - return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR); -} - -int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR) -{ - return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR); -} - -/* Constant-time GCD and/or modinv with odd modulus and A <= N */ -int mbedtls_mpi_gcd_modinv_odd(mbedtls_mpi *G, - mbedtls_mpi *I, - const mbedtls_mpi *A, - const mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi local_g; - mbedtls_mpi_uint *T = NULL; - const size_t T_factor = I != NULL ? 5 : 4; - const mbedtls_mpi_uint zero = 0; - - /* Check requirements on A and N */ - if (mbedtls_mpi_cmp_int(A, 0) < 0 || - mbedtls_mpi_cmp_mpi(A, N) > 0 || - mbedtls_mpi_get_bit(N, 0) != 1 || - (I != NULL && mbedtls_mpi_cmp_int(N, 1) == 0)) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - /* Check aliasing requirements */ - if (A == N || (I != NULL && (I == N || G == N))) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_init(&local_g); - - if (G == NULL) { - G = &local_g; - } - - /* We can't modify the values of G or I before use in the main function, - * as they could be aliased to A or N. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(G, N->n)); - if (I != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(I, N->n)); - } - - T = mbedtls_calloc(sizeof(mbedtls_mpi_uint) * N->n, T_factor); - if (T == NULL) { - ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; - goto cleanup; - } - - mbedtls_mpi_uint *Ip = I != NULL ? I->p : NULL; - /* If A is 0 (null), then A->p would be null, and A->n would be 0, - * which would be an issue if A->p and A->n were passed to - * mbedtls_mpi_core_gcd_modinv_odd below. */ - const mbedtls_mpi_uint *Ap = A->p != NULL ? A->p : &zero; - size_t An = A->n >= N->n ? N->n : A->p != NULL ? A->n : 1; - mbedtls_mpi_core_gcd_modinv_odd(G->p, Ip, Ap, An, N->p, N->n, T); - - G->s = 1; - if (I != NULL) { - I->s = 1; - } - - if (G->n > N->n) { - memset(G->p + N->n, 0, ciL * (G->n - N->n)); - } - if (I != NULL && I->n > N->n) { - memset(I->p + N->n, 0, ciL * (I->n - N->n)); - } - -cleanup: - mbedtls_mpi_free(&local_g); - mbedtls_free(T); - return ret; -} - -/* - * Greatest common divisor: G = gcd(A, B) - * Wrapper around mbedtls_mpi_gcd_modinv() that removes its restrictions. - */ -int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi TA, TB; - - mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB); - - /* Make copies and take absolute values */ - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); - TA.s = TB.s = 1; - - /* Make the two values the same (non-zero) number of limbs. - * This is needed to use mbedtls_mpi_core functions below. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TA, TB.n != 0 ? TB.n : 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TB, TA.n)); // non-zero from above - - /* Handle special cases (that don't happen in crypto usage) */ - if (mbedtls_mpi_core_check_zero_ct(TA.p, TA.n) == MBEDTLS_CT_FALSE) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB)); // GCD(0, B) = abs(B) - goto cleanup; - } - if (mbedtls_mpi_core_check_zero_ct(TB.p, TB.n) == MBEDTLS_CT_FALSE) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TA)); // GCD(A, 0) = abs(A) - goto cleanup; - } - - /* Make boths inputs odd by putting powers of 2 on the side */ - const size_t za = mbedtls_mpi_lsb(&TA); - const size_t zb = mbedtls_mpi_lsb(&TB); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, za)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, zb)); - - /* Ensure A <= B: if B < A, swap them */ - mbedtls_ct_condition_t swap = mbedtls_mpi_core_lt_ct(TB.p, TA.p, TA.n); - mbedtls_mpi_core_cond_swap(TA.p, TB.p, TA.n, swap); - - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(G, NULL, &TA, &TB)); - - /* Re-inject the power of 2 we had previously put aside */ - size_t zg = za > zb ? zb : za; // zg = min(za, zb) - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(G, zg)); - -cleanup: - - mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TB); - - return ret; -} - -/* - * Fill X with size bytes of random. - * The bytes returned from the RNG are used in a specific order which - * is suitable for deterministic ECDSA (see the specification of - * mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()). - */ -int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const size_t limbs = CHARS_TO_LIMBS(size); - - /* Ensure that target MPI has exactly the necessary number of limbs */ - MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs)); - if (size == 0) { - return 0; - } - - ret = mbedtls_mpi_core_fill_random(X->p, X->n, size, f_rng, p_rng); - -cleanup: - return ret; -} - -int mbedtls_mpi_random(mbedtls_mpi *X, - mbedtls_mpi_sint min, - const mbedtls_mpi *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - if (min < 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - if (mbedtls_mpi_cmp_int(N, min) <= 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - /* Ensure that target MPI has exactly the same number of limbs - * as the upper bound, even if the upper bound has leading zeros. - * This is necessary for mbedtls_mpi_core_random. */ - int ret = mbedtls_mpi_resize_clear(X, N->n); - if (ret != 0) { - return ret; - } - - return mbedtls_mpi_core_random(X->p, min, N->p, X->n, f_rng, p_rng); -} - -/* - * Modular inverse: X = A^-1 mod N with N odd (and A any range) - */ -int mbedtls_mpi_inv_mod_odd(mbedtls_mpi *X, - const mbedtls_mpi *A, - const mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi T, G; - - mbedtls_mpi_init(&T); - mbedtls_mpi_init(&G); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, A, N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &T, &T, N)); - if (mbedtls_mpi_cmp_int(&G, 1) != 0) { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &T)); - -cleanup: - mbedtls_mpi_free(&T); - mbedtls_mpi_free(&G); - - return ret; -} - -/* - * Compute X = A^-1 mod N with N even, A odd and 1 < A < N. - * - * This is not obvious because our constant-time modinv function only works with - * an odd modulus, and here the modulus is even. The idea is that computing a - * a^-1 mod b is really just computing the u coefficient in the Bézout relation - * a*u + b*v = 1 (assuming gcd(a,b) = 1, i.e. the inverse exists). But if we know - * one of u, v in this relation then the other is easy to find. So we can - * actually start by computing N^-1 mod A with gives us "the wrong half" of the - * Bézout relation, from which we'll deduce the interesting half A^-1 mod N. - * - * Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist. - */ -int mbedtls_mpi_inv_mod_even_in_range(mbedtls_mpi *X, - mbedtls_mpi const *A, - mbedtls_mpi const *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi I, G; - - mbedtls_mpi_init(&I); - mbedtls_mpi_init(&G); - - /* Set I = N^-1 mod A */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&I, N, A)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &I, &I, A)); - if (mbedtls_mpi_cmp_int(&G, 1) != 0) { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - /* We know N * I = 1 + k * A for some k, which we can easily compute - * as k = (N*I - 1) / A (we know there will be no remainder). */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&I, &I, N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&I, &I, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&G, NULL, &I, A)); - - /* Now we have a Bézout relation N * (previous value of I) - G * A = 1, - * so A^-1 mod N is -G mod N, which is N - G. - * Note that 0 < k < N since 0 < I < A, so G (k) is already in range. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(X, N, &G)); - -cleanup: - mbedtls_mpi_free(&I); - mbedtls_mpi_free(&G); - return ret; -} - -/* - * Compute X = A^-1 mod N with N even and A odd (but in any range). - * - * Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist. - */ -static int mbedtls_mpi_inv_mod_even(mbedtls_mpi *X, - mbedtls_mpi const *A, - mbedtls_mpi const *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi AA; - - mbedtls_mpi_init(&AA); - - /* Bring A in the range [0, N). */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&AA, A, N)); - - /* We know A >= 0 but the next function wants A > 1 */ - int cmp = mbedtls_mpi_cmp_int(&AA, 1); - if (cmp < 0) { // AA == 0 - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - if (cmp == 0) { // AA = 1 - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1)); - goto cleanup; - } - - /* Now we know 1 < A < N, N is even and AA is still odd */ - MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_even_in_range(X, &AA, N)); - -cleanup: - mbedtls_mpi_free(&AA); - return ret; -} - -/* - * Modular inverse: X = A^-1 mod N - * - * Wrapper around mbedtls_mpi_gcd_modinv_odd() that lifts its limitations. - */ -int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N) -{ - if (mbedtls_mpi_cmp_int(N, 1) <= 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (mbedtls_mpi_get_bit(N, 0) == 1) { - return mbedtls_mpi_inv_mod_odd(X, A, N); - } - - if (mbedtls_mpi_get_bit(A, 0) == 1) { - return mbedtls_mpi_inv_mod_even(X, A, N); - } - - /* If A and N are both even, 2 divides their GCD, so no inverse. */ - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; -} - -#if defined(MBEDTLS_GENPRIME) - -/* Gaps between primes, starting at 3. https://oeis.org/A001223 */ -static const unsigned char small_prime_gaps[] = { - 2, 2, 4, 2, 4, 2, 4, 6, - 2, 6, 4, 2, 4, 6, 6, 2, - 6, 4, 2, 6, 4, 6, 8, 4, - 2, 4, 2, 4, 14, 4, 6, 2, - 10, 2, 6, 6, 4, 6, 6, 2, - 10, 2, 4, 2, 12, 12, 4, 2, - 4, 6, 2, 10, 6, 6, 6, 2, - 6, 4, 2, 10, 14, 4, 2, 4, - 14, 6, 10, 2, 4, 6, 8, 6, - 6, 4, 6, 8, 4, 8, 10, 2, - 10, 2, 6, 4, 6, 8, 4, 2, - 4, 12, 8, 4, 8, 4, 6, 12, - 2, 18, 6, 10, 6, 6, 2, 6, - 10, 6, 6, 2, 6, 6, 4, 2, - 12, 10, 2, 4, 6, 6, 2, 12, - 4, 6, 8, 10, 8, 10, 8, 6, - 6, 4, 8, 6, 4, 8, 4, 14, - 10, 12, 2, 10, 2, 4, 2, 10, - 14, 4, 2, 4, 14, 4, 2, 4, - 20, 4, 8, 10, 8, 4, 6, 6, - 14, 4, 6, 6, 8, 6, /*reaches 997*/ - 0 /* the last entry is effectively unused */ -}; - -/* - * Small divisors test (X must be positive) - * - * Return values: - * 0: no small factor (possible prime, more tests needed) - * 1: certain prime - * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime - * other negative: error - */ -static int mpi_check_small_factors(const mbedtls_mpi *X) -{ - int ret = 0; - size_t i; - mbedtls_mpi_uint r; - unsigned p = 3; /* The first odd prime */ - - if ((X->p[0] & 1) == 0) { - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - } - - for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) { - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p)); - if (r == 0) { - if (mbedtls_mpi_cmp_int(X, p) == 0) { - return 1; - } else { - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - } - } - } - -cleanup: - return ret; -} - -/* - * Miller-Rabin pseudo-primality test (HAC 4.24) - */ -static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret, count; - size_t i, j, k, s; - mbedtls_mpi W, R, T, A, RR; - - mbedtls_mpi_init(&W); mbedtls_mpi_init(&R); - mbedtls_mpi_init(&T); mbedtls_mpi_init(&A); - mbedtls_mpi_init(&RR); - - /* - * W = |X| - 1 - * R = W >> lsb( W ) - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1)); - s = mbedtls_mpi_lsb(&W); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s)); - - for (i = 0; i < rounds; i++) { - /* - * pick a random A, 1 < A < |X| - 1 - */ - count = 0; - do { - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng)); - - j = mbedtls_mpi_bitlen(&A); - k = mbedtls_mpi_bitlen(&W); - if (j > k) { - A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1; - } - - if (count++ > 30) { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - } while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 || - mbedtls_mpi_cmp_int(&A, 1) <= 0); - - /* - * A = A^R mod |X| - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR)); - - if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 || - mbedtls_mpi_cmp_int(&A, 1) == 0) { - continue; - } - - j = 1; - while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) { - /* - * A = A * A mod |X| - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X)); - - if (mbedtls_mpi_cmp_int(&A, 1) == 0) { - break; - } - - j++; - } - - /* - * not prime if A != |X| - 1 or A == 1 - */ - if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 || - mbedtls_mpi_cmp_int(&A, 1) == 0) { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - break; - } - } - -cleanup: - mbedtls_mpi_free(&W); mbedtls_mpi_free(&R); - mbedtls_mpi_free(&T); mbedtls_mpi_free(&A); - mbedtls_mpi_free(&RR); - - return ret; -} - -/* - * Pseudo-primality test: small factors, then Miller-Rabin - */ -int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi XX; - - XX.s = 1; - XX.n = X->n; - XX.p = X->p; - - if (mbedtls_mpi_cmp_int(&XX, 0) == 0 || - mbedtls_mpi_cmp_int(&XX, 1) == 0) { - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - } - - if (mbedtls_mpi_cmp_int(&XX, 2) == 0) { - return 0; - } - - if ((ret = mpi_check_small_factors(&XX)) != 0) { - if (ret == 1) { - return 0; - } - - return ret; - } - - return mpi_miller_rabin(&XX, rounds, f_rng, p_rng); -} - -/* - * Prime number generation - * - * To generate an RSA key in a way recommended by FIPS 186-4, both primes must - * be either 1024 bits or 1536 bits long, and flags must contain - * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR. - */ -int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ -#ifdef MBEDTLS_HAVE_INT64 -// ceil(2^63.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL -#else -// ceil(2^31.5) -#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U -#endif - int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - size_t k, n; - int rounds; - mbedtls_mpi_uint r; - mbedtls_mpi Y; - - if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_init(&Y); - - n = BITS_TO_LIMBS(nbits); - - if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) { - /* - * 2^-80 error probability, number of rounds chosen per HAC, table 4.4 - */ - rounds = ((nbits >= 1300) ? 2 : (nbits >= 850) ? 3 : - (nbits >= 650) ? 4 : (nbits >= 350) ? 8 : - (nbits >= 250) ? 12 : (nbits >= 150) ? 18 : 27); - } else { - /* - * 2^-100 error probability, number of rounds computed based on HAC, - * fact 4.48 - */ - rounds = ((nbits >= 1450) ? 4 : (nbits >= 1150) ? 5 : - (nbits >= 1000) ? 6 : (nbits >= 850) ? 7 : - (nbits >= 750) ? 8 : (nbits >= 500) ? 13 : - (nbits >= 250) ? 28 : (nbits >= 150) ? 40 : 51); - } - - while (1) { - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng)); - /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */ - if (X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2) { - continue; - } - - k = n * biL; - if (k > nbits) { - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits)); - } - X->p[0] |= 1; - - if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) { - ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng); - - if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { - goto cleanup; - } - } else { - /* - * A necessary condition for Y and X = 2Y + 1 to be prime - * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). - * Make sure it is satisfied, while keeping X = 3 mod 4 - */ - - X->p[0] |= 2; - - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3)); - if (r == 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8)); - } else if (r == 1) { - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4)); - } - - /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1)); - - while (1) { - /* - * First, check small factors for X and Y - * before doing Miller-Rabin on any of them - */ - if ((ret = mpi_check_small_factors(X)) == 0 && - (ret = mpi_check_small_factors(&Y)) == 0 && - (ret = mpi_miller_rabin(X, rounds, f_rng, p_rng)) - == 0 && - (ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng)) - == 0) { - goto cleanup; - } - - if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { - goto cleanup; - } - - /* - * Next candidates. We want to preserve Y = (X-1) / 2 and - * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) - * so up Y by 6 and X by 12. - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 12)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6)); - } - } - } - -cleanup: - - mbedtls_mpi_free(&Y); - - return ret; -} - -#endif /* MBEDTLS_GENPRIME */ - -#if defined(MBEDTLS_SELF_TEST) - -#define GCD_PAIR_COUNT 3 - -static const int gcd_pairs[GCD_PAIR_COUNT][3] = -{ - { 693, 609, 21 }, - { 1764, 868, 28 }, - { 768454923, 542167814, 1 } -}; - -/* - * Checkup routine - */ -int mbedtls_mpi_self_test(int verbose) -{ - int ret, i; - mbedtls_mpi A, E, N, X, Y, U, V; - - mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X); - mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16, - "EFE021C2645FD1DC586E69184AF4A31E" \ - "D5F53E93B5F123FA41680867BA110131" \ - "944FE7952E2517337780CB0DB80E61AA" \ - "E7C8DDC6C5C6AADEB34EB38A2F40D5E6")); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16, - "B2E7EFD37075B9F03FF989C7C5051C20" \ - "34D2A323810251127E7BF8625A4F49A5" \ - "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ - "5B5C25763222FEFCCFC38B832366C29E")); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16, - "0066A198186C18C10B2F5ED9B522752A" \ - "9830B69916E535C8F047518A889A43A5" \ - "94B6BED27A168D31D4A52F88925AA8F5")); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, - "602AB7ECA597A3D6B56FF9829A5E8B85" \ - "9E857EA95A03512E2BAE7391688D264A" \ - "A5663B0341DB9CCFD2C4C5F421FEC814" \ - "8001B72E848A38CAE1C65F78E56ABDEF" \ - "E12D3C039B8A02D6BE593F0BBBDA56F1" \ - "ECF677152EF804370C1A305CAF3B5BF1" \ - "30879B56C61DE584A0F53A2447A51E")); - - if (verbose != 0) { - mbedtls_printf(" MPI test #1 (mul_mpi): "); - } - - if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, - "256567336059E52CAE22925474705F39A94")); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16, - "6613F26162223DF488E9CD48CC132C7A" \ - "0AC93C701B001B092E4E5B9F73BCD27B" \ - "9EE50D0657C77F374E903CDFA4C642")); - - if (verbose != 0) { - mbedtls_printf(" MPI test #2 (div_mpi): "); - } - - if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 || - mbedtls_mpi_cmp_mpi(&Y, &V) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, - "36E139AEA55215609D2816998ED020BB" \ - "BD96C37890F65171D948E9BC7CBAA4D9" \ - "325D24D6A3C12710F10A09FA08AB87")); - - if (verbose != 0) { - mbedtls_printf(" MPI test #3 (exp_mod): "); - } - - if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, - "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ - "C3DBA76456363A10869622EAC2DD84EC" \ - "C5B8A74DAC4D09E03B5E0BE779F2DF61")); - - if (verbose != 0) { - mbedtls_printf(" MPI test #4 (inv_mod): "); - } - - if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - if (verbose != 0) { - mbedtls_printf(" MPI test #5 (simple gcd): "); - } - - for (i = 0; i < GCD_PAIR_COUNT; i++) { - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0])); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1])); - - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y)); - - if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed at %d\n", i); - } - - ret = 1; - goto cleanup; - } - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - -cleanup: - - if (ret != 0 && verbose != 0) { - mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret); - } - - mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N); mbedtls_mpi_free(&X); - mbedtls_mpi_free(&Y); mbedtls_mpi_free(&U); mbedtls_mpi_free(&V); - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_BIGNUM_C */ diff --git a/vendor/mbedtls/library/bignum_core.c b/vendor/mbedtls/library/bignum_core.c deleted file mode 100644 index 809169461..000000000 --- a/vendor/mbedtls/library/bignum_core.c +++ /dev/null @@ -1,1240 +0,0 @@ -/* - * Core bignum functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) - -#include - -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" -#include "constant_time_internal.h" - -#include "mbedtls/platform.h" - -#include "bignum_core.h" -#include "bignum_core_invasive.h" -#include "bn_mul.h" -#include "constant_time_internal.h" - -size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a) -{ -#if defined(__has_builtin) -#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_clz) - #define core_clz __builtin_clz -#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_clzl) - #define core_clz __builtin_clzl -#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_clzll) - #define core_clz __builtin_clzll -#endif -#endif -#if defined(core_clz) - return (size_t) core_clz(a); -#else - size_t j; - mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); - - for (j = 0; j < biL; j++) { - if (a & mask) { - break; - } - - mask >>= 1; - } - - return j; -#endif -} - -size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs) -{ - int i; - size_t j; - - for (i = ((int) A_limbs) - 1; i >= 0; i--) { - if (A[i] != 0) { - j = biL - mbedtls_mpi_core_clz(A[i]); - return (i * biL) + j; - } - } - - return 0; -} - -static mbedtls_mpi_uint mpi_bigendian_to_host(mbedtls_mpi_uint a) -{ - if (MBEDTLS_IS_BIG_ENDIAN) { - /* Nothing to do on bigendian systems. */ - return a; - } else { -#if defined(MBEDTLS_HAVE_INT32) - return (mbedtls_mpi_uint) MBEDTLS_BSWAP32(a); -#elif defined(MBEDTLS_HAVE_INT64) - return (mbedtls_mpi_uint) MBEDTLS_BSWAP64(a); -#endif - } -} - -void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A, - size_t A_limbs) -{ - mbedtls_mpi_uint *cur_limb_left; - mbedtls_mpi_uint *cur_limb_right; - if (A_limbs == 0) { - return; - } - - /* - * Traverse limbs and - * - adapt byte-order in each limb - * - swap the limbs themselves. - * For that, simultaneously traverse the limbs from left to right - * and from right to left, as long as the left index is not bigger - * than the right index (it's not a problem if limbs is odd and the - * indices coincide in the last iteration). - */ - for (cur_limb_left = A, cur_limb_right = A + (A_limbs - 1); - cur_limb_left <= cur_limb_right; - cur_limb_left++, cur_limb_right--) { - mbedtls_mpi_uint tmp; - /* Note that if cur_limb_left == cur_limb_right, - * this code effectively swaps the bytes only once. */ - tmp = mpi_bigendian_to_host(*cur_limb_left); - *cur_limb_left = mpi_bigendian_to_host(*cur_limb_right); - *cur_limb_right = tmp; - } -} - -/* Whether min <= A, in constant time. - * A_limbs must be at least 1. */ -mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min, - const mbedtls_mpi_uint *A, - size_t A_limbs) -{ - /* min <= least significant limb? */ - mbedtls_ct_condition_t min_le_lsl = mbedtls_ct_uint_ge(A[0], min); - - /* limbs other than the least significant one are all zero? */ - mbedtls_ct_condition_t msll_mask = MBEDTLS_CT_FALSE; - for (size_t i = 1; i < A_limbs; i++) { - msll_mask = mbedtls_ct_bool_or(msll_mask, mbedtls_ct_bool(A[i])); - } - - /* min <= A iff the lowest limb of A is >= min or the other limbs - * are not all zero. */ - return mbedtls_ct_bool_or(msll_mask, min_le_lsl); -} - -mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - size_t limbs) -{ - mbedtls_ct_condition_t ret = MBEDTLS_CT_FALSE, cond = MBEDTLS_CT_FALSE, done = MBEDTLS_CT_FALSE; - - for (size_t i = limbs; i > 0; i--) { - /* - * If B[i - 1] < A[i - 1] then A < B is false and the result must - * remain 0. - * - * Again even if we can make a decision, we just mark the result and - * the fact that we are done and continue looping. - */ - cond = mbedtls_ct_uint_lt(B[i - 1], A[i - 1]); - done = mbedtls_ct_bool_or(done, cond); - - /* - * If A[i - 1] < B[i - 1] then A < B is true. - * - * Again even if we can make a decision, we just mark the result and - * the fact that we are done and continue looping. - */ - cond = mbedtls_ct_uint_lt(A[i - 1], B[i - 1]); - ret = mbedtls_ct_bool_or(ret, mbedtls_ct_bool_and(cond, mbedtls_ct_bool_not(done))); - done = mbedtls_ct_bool_or(done, cond); - } - - /* - * If all the limbs were equal, then the numbers are equal, A < B is false - * and leaving the result 0 is correct. - */ - - return ret; -} - -void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - size_t limbs, - mbedtls_ct_condition_t assign) -{ - if (X == A) { - return; - } - - /* This function is very performance-sensitive for RSA. For this reason - * we have the loop below, instead of calling mbedtls_ct_memcpy_if - * (this is more optimal since here we don't have to handle the case where - * we copy awkwardly sized data). - */ - for (size_t i = 0; i < limbs; i++) { - X[i] = mbedtls_ct_mpi_uint_if(assign, A[i], X[i]); - } -} - -void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X, - mbedtls_mpi_uint *Y, - size_t limbs, - mbedtls_ct_condition_t swap) -{ - if (X == Y) { - return; - } - - for (size_t i = 0; i < limbs; i++) { - mbedtls_mpi_uint tmp = X[i]; - X[i] = mbedtls_ct_mpi_uint_if(swap, Y[i], X[i]); - Y[i] = mbedtls_ct_mpi_uint_if(swap, tmp, Y[i]); - } -} - -int mbedtls_mpi_core_read_le(mbedtls_mpi_uint *X, - size_t X_limbs, - const unsigned char *input, - size_t input_length) -{ - const size_t limbs = CHARS_TO_LIMBS(input_length); - - if (X_limbs < limbs) { - return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; - } - - if (X != NULL) { - memset(X, 0, X_limbs * ciL); - - for (size_t i = 0; i < input_length; i++) { - size_t offset = ((i % ciL) << 3); - X[i / ciL] |= ((mbedtls_mpi_uint) input[i]) << offset; - } - } - - return 0; -} - -int mbedtls_mpi_core_read_be(mbedtls_mpi_uint *X, - size_t X_limbs, - const unsigned char *input, - size_t input_length) -{ - const size_t limbs = CHARS_TO_LIMBS(input_length); - - if (X_limbs < limbs) { - return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; - } - - /* If X_limbs is 0, input_length must also be 0 (from previous test). - * Nothing to do. */ - if (X_limbs == 0) { - return 0; - } - - memset(X, 0, X_limbs * ciL); - - /* memcpy() with (NULL, 0) is undefined behaviour */ - if (input_length != 0) { - size_t overhead = (X_limbs * ciL) - input_length; - unsigned char *Xp = (unsigned char *) X; - memcpy(Xp + overhead, input, input_length); - } - - mbedtls_mpi_core_bigendian_to_host(X, X_limbs); - - return 0; -} - -int mbedtls_mpi_core_write_le(const mbedtls_mpi_uint *A, - size_t A_limbs, - unsigned char *output, - size_t output_length) -{ - size_t stored_bytes = A_limbs * ciL; - size_t bytes_to_copy; - - if (stored_bytes < output_length) { - bytes_to_copy = stored_bytes; - } else { - bytes_to_copy = output_length; - - /* The output buffer is smaller than the allocated size of A. - * However A may fit if its leading bytes are zero. */ - for (size_t i = bytes_to_copy; i < stored_bytes; i++) { - if (GET_BYTE(A, i) != 0) { - return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; - } - } - } - - for (size_t i = 0; i < bytes_to_copy; i++) { - output[i] = GET_BYTE(A, i); - } - - if (stored_bytes < output_length) { - /* Write trailing 0 bytes */ - memset(output + stored_bytes, 0, output_length - stored_bytes); - } - - return 0; -} - -int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *X, - size_t X_limbs, - unsigned char *output, - size_t output_length) -{ - size_t stored_bytes; - size_t bytes_to_copy; - unsigned char *p; - - stored_bytes = X_limbs * ciL; - - if (stored_bytes < output_length) { - /* There is enough space in the output buffer. Write initial - * null bytes and record the position at which to start - * writing the significant bytes. In this case, the execution - * trace of this function does not depend on the value of the - * number. */ - bytes_to_copy = stored_bytes; - p = output + output_length - stored_bytes; - memset(output, 0, output_length - stored_bytes); - } else { - /* The output buffer is smaller than the allocated size of X. - * However X may fit if its leading bytes are zero. */ - bytes_to_copy = output_length; - p = output; - for (size_t i = bytes_to_copy; i < stored_bytes; i++) { - if (GET_BYTE(X, i) != 0) { - return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; - } - } - } - - for (size_t i = 0; i < bytes_to_copy; i++) { - p[bytes_to_copy - i - 1] = GET_BYTE(X, i); - } - - return 0; -} - -void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs, - size_t count) -{ - size_t i, v0, v1; - mbedtls_mpi_uint r0 = 0, r1; - - v0 = count / biL; - v1 = count & (biL - 1); - - if (v0 > limbs || (v0 == limbs && v1 > 0)) { - memset(X, 0, limbs * ciL); - return; - } - - /* - * shift by count / limb_size - */ - if (v0 > 0) { - for (i = 0; i < limbs - v0; i++) { - X[i] = X[i + v0]; - } - - for (; i < limbs; i++) { - X[i] = 0; - } - } - - /* - * shift by count % limb_size - */ - if (v1 > 0) { - for (i = limbs; i > 0; i--) { - r1 = X[i - 1] << (biL - v1); - X[i - 1] >>= v1; - X[i - 1] |= r0; - r0 = r1; - } - } -} - -void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs, - size_t count) -{ - size_t i, v0, v1; - mbedtls_mpi_uint r0 = 0, r1; - - v0 = count / (biL); - v1 = count & (biL - 1); - - /* - * shift by count / limb_size - */ - if (v0 > 0) { - for (i = limbs; i > v0; i--) { - X[i - 1] = X[i - v0 - 1]; - } - - for (; i > 0; i--) { - X[i - 1] = 0; - } - } - - /* - * shift by count % limb_size - */ - if (v1 > 0) { - for (i = v0; i < limbs; i++) { - r1 = X[i] >> (biL - v1); - X[i] <<= v1; - X[i] |= r0; - r0 = r1; - } - } -} - -mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - size_t limbs) -{ - mbedtls_mpi_uint c = 0; - - for (size_t i = 0; i < limbs; i++) { - mbedtls_mpi_uint t = c + A[i]; - c = (t < A[i]); - t += B[i]; - c += (t < B[i]); - X[i] = t; - } - - return c; -} - -mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - size_t limbs, - unsigned cond) -{ - mbedtls_mpi_uint c = 0; - - mbedtls_ct_condition_t do_add = mbedtls_ct_bool(cond); - - for (size_t i = 0; i < limbs; i++) { - mbedtls_mpi_uint add = mbedtls_ct_mpi_uint_if_else_0(do_add, A[i]); - mbedtls_mpi_uint t = c + X[i]; - c = (t < X[i]); - t += add; - c += (t < add); - X[i] = t; - } - - return c; -} - -mbedtls_mpi_uint mbedtls_mpi_core_sub(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - size_t limbs) -{ - mbedtls_mpi_uint c = 0; - - for (size_t i = 0; i < limbs; i++) { - mbedtls_mpi_uint z = (A[i] < c); - mbedtls_mpi_uint t = A[i] - c; - c = (t < B[i]) + z; - X[i] = t - B[i]; - } - - return c; -} - -mbedtls_mpi_uint mbedtls_mpi_core_mla(mbedtls_mpi_uint *d, size_t d_len, - const mbedtls_mpi_uint *s, size_t s_len, - mbedtls_mpi_uint b) -{ - mbedtls_mpi_uint c = 0; /* carry */ - /* - * It is a documented precondition of this function that d_len >= s_len. - * If that's not the case, we swap these round: this turns what would be - * a buffer overflow into an incorrect result. - */ - if (d_len < s_len) { - s_len = d_len; - } - size_t excess_len = d_len - s_len; - size_t steps_x8 = s_len / 8; - size_t steps_x1 = s_len & 7; - - while (steps_x8--) { - MULADDC_X8_INIT - MULADDC_X8_CORE - MULADDC_X8_STOP - } - - while (steps_x1--) { - MULADDC_X1_INIT - MULADDC_X1_CORE - MULADDC_X1_STOP - } - - while (excess_len--) { - *d += c; - c = (*d < c); - d++; - } - - return c; -} - -void mbedtls_mpi_core_mul(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, size_t A_limbs, - const mbedtls_mpi_uint *B, size_t B_limbs) -{ - memset(X, 0, (A_limbs + B_limbs) * ciL); - - for (size_t i = 0; i < B_limbs; i++) { - (void) mbedtls_mpi_core_mla(X + i, A_limbs + 1, A, A_limbs, B[i]); - } -} - -/* - * Fast Montgomery initialization (thanks to Tom St Denis). - */ -mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N) -{ - mbedtls_mpi_uint x = N[0]; - - x += ((N[0] + 2) & 4) << 1; - - for (unsigned int i = biL; i >= 8; i /= 2) { - x *= (2 - (N[0] * x)); - } - - return ~x + 1; -} - -void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - size_t B_limbs, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - mbedtls_mpi_uint mm, - mbedtls_mpi_uint *T) -{ - memset(T, 0, (2 * AN_limbs + 1) * ciL); - - for (size_t i = 0; i < AN_limbs; i++) { - /* T = (T + u0*B + u1*N) / 2^biL */ - mbedtls_mpi_uint u0 = A[i]; - mbedtls_mpi_uint u1 = (T[0] + u0 * B[0]) * mm; - - (void) mbedtls_mpi_core_mla(T, AN_limbs + 2, B, B_limbs, u0); - (void) mbedtls_mpi_core_mla(T, AN_limbs + 2, N, AN_limbs, u1); - - T++; - } - - /* - * The result we want is (T >= N) ? T - N : T. - * - * For better constant-time properties in this function, we always do the - * subtraction, with the result in X. - * - * We also look to see if there was any carry in the final additions in the - * loop above. - */ - - mbedtls_mpi_uint carry = T[AN_limbs]; - mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, T, N, AN_limbs); - - /* - * Using R as the Montgomery radix (auxiliary modulus) i.e. 2^(biL*AN_limbs): - * - * T can be in one of 3 ranges: - * - * 1) T < N : (carry, borrow) = (0, 1): we want T - * 2) N <= T < R : (carry, borrow) = (0, 0): we want X - * 3) T >= R : (carry, borrow) = (1, 1): we want X - * - * and (carry, borrow) = (1, 0) can't happen. - * - * So the correct return value is already in X if (carry ^ borrow) = 0, - * but is in (the lower AN_limbs limbs of) T if (carry ^ borrow) = 1. - */ - mbedtls_ct_memcpy_if(mbedtls_ct_bool(carry ^ borrow), - (unsigned char *) X, - (unsigned char *) T, - NULL, - AN_limbs * sizeof(mbedtls_mpi_uint)); -} - -int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X, - const mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, N->n * 2 * biL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(X, N->n)); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest, - const mbedtls_mpi_uint *table, - size_t limbs, - size_t count, - size_t index) -{ - for (size_t i = 0; i < count; i++, table += limbs) { - mbedtls_ct_condition_t assign = mbedtls_ct_uint_eq(i, index); - mbedtls_mpi_core_cond_assign(dest, table, limbs, assign); - } -} - -/* Fill X with n_bytes random bytes. - * X must already have room for those bytes. - * The ordering of the bytes returned from the RNG is suitable for - * deterministic ECDSA (see RFC 6979 §3.3 and the specification of - * mbedtls_mpi_core_random()). - */ -int mbedtls_mpi_core_fill_random( - mbedtls_mpi_uint *X, size_t X_limbs, - size_t n_bytes, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const size_t limbs = CHARS_TO_LIMBS(n_bytes); - const size_t overhead = (limbs * ciL) - n_bytes; - - if (X_limbs < limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - memset(X, 0, overhead); - memset((unsigned char *) X + limbs * ciL, 0, (X_limbs - limbs) * ciL); - MBEDTLS_MPI_CHK(f_rng(p_rng, (unsigned char *) X + overhead, n_bytes)); - mbedtls_mpi_core_bigendian_to_host(X, limbs); - -cleanup: - return ret; -} - -int mbedtls_mpi_core_random(mbedtls_mpi_uint *X, - mbedtls_mpi_uint min, - const mbedtls_mpi_uint *N, - size_t limbs, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - mbedtls_ct_condition_t ge_lower = MBEDTLS_CT_TRUE, lt_upper = MBEDTLS_CT_FALSE; - size_t n_bits = mbedtls_mpi_core_bitlen(N, limbs); - size_t n_bytes = (n_bits + 7) / 8; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* - * When min == 0, each try has at worst a probability 1/2 of failing - * (the msb has a probability 1/2 of being 0, and then the result will - * be < N), so after 30 tries failure probability is a most 2**(-30). - * - * When N is just below a power of 2, as is the case when generating - * a random scalar on most elliptic curves, 1 try is enough with - * overwhelming probability. When N is just above a power of 2, - * as when generating a random scalar on secp224k1, each try has - * a probability of failing that is almost 1/2. - * - * The probabilities are almost the same if min is nonzero but negligible - * compared to N. This is always the case when N is crypto-sized, but - * it's convenient to support small N for testing purposes. When N - * is small, use a higher repeat count, otherwise the probability of - * failure is macroscopic. - */ - int count = (n_bytes > 4 ? 30 : 250); - - /* - * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA) - * when f_rng is a suitably parametrized instance of HMAC_DRBG: - * - use the same byte ordering; - * - keep the leftmost n_bits bits of the generated octet string; - * - try until result is in the desired range. - * This also avoids any bias, which is especially important for ECDSA. - */ - do { - MBEDTLS_MPI_CHK(mbedtls_mpi_core_fill_random(X, limbs, - n_bytes, - f_rng, p_rng)); - mbedtls_mpi_core_shift_r(X, limbs, 8 * n_bytes - n_bits); - - if (--count == 0) { - ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - ge_lower = mbedtls_mpi_core_uint_le_mpi(min, X, limbs); - lt_upper = mbedtls_mpi_core_lt_ct(X, N, limbs); - } while (mbedtls_ct_bool_and(ge_lower, lt_upper) == MBEDTLS_CT_FALSE); - -cleanup: - return ret; -} - -static size_t exp_mod_get_window_size(size_t Ebits) -{ -#if MBEDTLS_MPI_WINDOW_SIZE >= 6 - return (Ebits > 671) ? 6 : (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1; -#elif MBEDTLS_MPI_WINDOW_SIZE == 5 - return (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1; -#elif MBEDTLS_MPI_WINDOW_SIZE > 1 - return (Ebits > 79) ? MBEDTLS_MPI_WINDOW_SIZE : 1; -#else - (void) Ebits; - return 1; -#endif -} - -size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs) -{ - const size_t wsize = exp_mod_get_window_size(E_limbs * biL); - const size_t welem = ((size_t) 1) << wsize; - - /* How big does each part of the working memory pool need to be? */ - const size_t table_limbs = welem * AN_limbs; - const size_t select_limbs = AN_limbs; - const size_t temp_limbs = 2 * AN_limbs + 1; - - return table_limbs + select_limbs + temp_limbs; -} - -static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - mbedtls_mpi_uint mm, - const mbedtls_mpi_uint *RR, - size_t welem, - mbedtls_mpi_uint *Wtable, - mbedtls_mpi_uint *temp) -{ - /* W[0] = 1 (in Montgomery presentation) */ - memset(Wtable, 0, AN_limbs * ciL); - Wtable[0] = 1; - mbedtls_mpi_core_montmul(Wtable, Wtable, RR, AN_limbs, N, AN_limbs, mm, temp); - - /* W[1] = A (already in Montgomery presentation) */ - mbedtls_mpi_uint *W1 = Wtable + AN_limbs; - memcpy(W1, A, AN_limbs * ciL); - - /* W[i+1] = W[i] * W[1], i >= 2 */ - mbedtls_mpi_uint *Wprev = W1; - for (size_t i = 2; i < welem; i++) { - mbedtls_mpi_uint *Wcur = Wprev + AN_limbs; - mbedtls_mpi_core_montmul(Wcur, Wprev, W1, AN_limbs, N, AN_limbs, mm, temp); - Wprev = Wcur; - } -} - -#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) -void (*mbedtls_safe_codepath_hook)(void) = NULL; -void (*mbedtls_unsafe_codepath_hook)(void) = NULL; -#endif - -/* - * This function calculates the indices of the exponent where the exponentiation algorithm should - * start processing. - * - * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value, - * this function is not constant time with respect to the exponent (parameter E). - */ -static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E, - size_t E_limbs, - int E_public, - size_t *E_limb_index, - size_t *E_bit_index) -{ - if (E_public == MBEDTLS_MPI_IS_PUBLIC) { - /* - * Skip leading zero bits. - */ - size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs); - if (E_bits == 0) { - /* - * If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want - * to represent it as a single 0 bit and as such the bitlength will be 1. - */ - E_bits = 1; - } - - *E_limb_index = E_bits / biL; - *E_bit_index = E_bits % biL; - -#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) - if (mbedtls_unsafe_codepath_hook != NULL) { - mbedtls_unsafe_codepath_hook(); - } -#endif - } else { - /* - * Here we need to be constant time with respect to E and can't do anything better than - * start at the first allocated bit. - */ - *E_limb_index = E_limbs; - *E_bit_index = 0; -#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) - if (mbedtls_safe_codepath_hook != NULL) { - mbedtls_safe_codepath_hook(); - } -#endif - } -} - -/* - * Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is - * not constant time with respect to the window parameter and consequently the exponent of the - * exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe). - */ -static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect, - mbedtls_mpi_uint *Wtable, - size_t AN_limbs, size_t welem, - mbedtls_mpi_uint window, - int window_public) -{ - if (window_public == MBEDTLS_MPI_IS_PUBLIC) { - memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL); -#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) - if (mbedtls_unsafe_codepath_hook != NULL) { - mbedtls_unsafe_codepath_hook(); - } -#endif - } else { - /* Select Wtable[window] without leaking window through - * memory access patterns. */ - mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, - AN_limbs, welem, window); -#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) - if (mbedtls_safe_codepath_hook != NULL) { - mbedtls_safe_codepath_hook(); - } -#endif - } -} - -/* Exponentiation: X := A^E mod N. - * - * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value, - * this function is not constant time with respect to the exponent (parameter E). - * - * A must already be in Montgomery form. - * - * As in other bignum functions, assume that AN_limbs and E_limbs are nonzero. - * - * RR must contain 2^{2*biL} mod N. - * - * The algorithm is a variant of Left-to-right k-ary exponentiation: HAC 14.82 - * (The difference is that the body in our loop processes a single bit instead - * of a full window.) - */ -static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - const mbedtls_mpi_uint *E, - size_t E_limbs, - int E_public, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T) -{ - /* We'll process the bits of E from most significant - * (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant - * (limb_index=0, E_bit_index=0). */ - size_t E_limb_index = E_limbs; - size_t E_bit_index = 0; - exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public, - &E_limb_index, &E_bit_index); - - const size_t wsize = exp_mod_get_window_size(E_limb_index * biL); - const size_t welem = ((size_t) 1) << wsize; - - /* This is how we will use the temporary storage T, which must have space - * for table_limbs, select_limbs and (2 * AN_limbs + 1) for montmul. */ - const size_t table_limbs = welem * AN_limbs; - const size_t select_limbs = AN_limbs; - - /* Pointers to specific parts of the temporary working memory pool */ - mbedtls_mpi_uint *const Wtable = T; - mbedtls_mpi_uint *const Wselect = Wtable + table_limbs; - mbedtls_mpi_uint *const temp = Wselect + select_limbs; - - /* - * Window precomputation - */ - - const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N); - - /* Set Wtable[i] = A^i (in Montgomery representation) */ - exp_mod_precompute_window(A, N, AN_limbs, - mm, RR, - welem, Wtable, temp); - - /* - * Fixed window exponentiation - */ - - /* X = 1 (in Montgomery presentation) initially */ - memcpy(X, Wtable, AN_limbs * ciL); - - /* At any given time, window contains window_bits bits from E. - * window_bits can go up to wsize. */ - size_t window_bits = 0; - mbedtls_mpi_uint window = 0; - - do { - /* Square */ - mbedtls_mpi_core_montmul(X, X, X, AN_limbs, N, AN_limbs, mm, temp); - - /* Move to the next bit of the exponent */ - if (E_bit_index == 0) { - --E_limb_index; - E_bit_index = biL - 1; - } else { - --E_bit_index; - } - /* Insert next exponent bit into window */ - ++window_bits; - window <<= 1; - window |= (E[E_limb_index] >> E_bit_index) & 1; - - /* Clear window if it's full. Also clear the window at the end, - * when we've finished processing the exponent. */ - if (window_bits == wsize || - (E_bit_index == 0 && E_limb_index == 0)) { - - exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem, - window, E_public); - /* Multiply X by the selected element. */ - mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm, - temp); - window = 0; - window_bits = 0; - } - } while (!(E_bit_index == 0 && E_limb_index == 0)); -} - -void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, size_t AN_limbs, - const mbedtls_mpi_uint *E, size_t E_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T) -{ - mbedtls_mpi_core_exp_mod_optionally_safe(X, - A, - N, - AN_limbs, - E, - E_limbs, - MBEDTLS_MPI_IS_SECRET, - RR, - T); -} - -void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, size_t AN_limbs, - const mbedtls_mpi_uint *E, size_t E_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T) -{ - mbedtls_mpi_core_exp_mod_optionally_safe(X, - A, - N, - AN_limbs, - E, - E_limbs, - MBEDTLS_MPI_IS_PUBLIC, - RR, - T); -} - -mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - mbedtls_mpi_uint c, /* doubles as carry */ - size_t limbs) -{ - for (size_t i = 0; i < limbs; i++) { - mbedtls_mpi_uint s = A[i]; - mbedtls_mpi_uint t = s - c; - c = (t > s); - X[i] = t; - } - - return c; -} - -mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A, - size_t limbs) -{ - volatile const mbedtls_mpi_uint *force_read_A = A; - mbedtls_mpi_uint bits = 0; - - for (size_t i = 0; i < limbs; i++) { - bits |= force_read_A[i]; - } - - return mbedtls_ct_bool(bits); -} - -void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - mbedtls_mpi_uint mm, - const mbedtls_mpi_uint *rr, - mbedtls_mpi_uint *T) -{ - mbedtls_mpi_core_montmul(X, A, rr, AN_limbs, N, AN_limbs, mm, T); -} - -void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - mbedtls_mpi_uint mm, - mbedtls_mpi_uint *T) -{ - const mbedtls_mpi_uint Rinv = 1; /* 1/R in Mont. rep => 1 */ - - mbedtls_mpi_core_montmul(X, A, &Rinv, 1, N, AN_limbs, mm, T); -} - -/* - * Compute X = A - B mod N. - * Both A and B must be in [0, N) and so will the output. - */ -static void mpi_core_sub_mod(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - const mbedtls_mpi_uint *N, - size_t limbs) -{ - mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, A, B, limbs); - (void) mbedtls_mpi_core_add_if(X, N, limbs, (unsigned) c); -} - -/* - * Divide X by 2 mod N in place, assuming N is odd. - * The input must be in [0, N) and so will the output. - */ -MBEDTLS_STATIC_TESTABLE -void mbedtls_mpi_core_div2_mod_odd(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *N, - size_t limbs) -{ - /* If X is odd, add N to make it even before shifting. */ - unsigned odd = (unsigned) X[0] & 1; - mbedtls_mpi_uint c = mbedtls_mpi_core_add_if(X, N, limbs, odd); - mbedtls_mpi_core_shift_r(X, limbs, 1); - X[limbs - 1] |= c << (biL - 1); -} - -/* - * Constant-time GCD and modular inversion - odd modulus. - * - * Pre-conditions: see public documentation. - * - * See https://www.jstage.jst.go.jp/article/transinf/E106.D/9/E106.D_2022ICP0009/_pdf - * - * The paper gives two computationally equivalent algorithms: Alg 7 (readable) - * and Alg 8 (constant-time). We use a third version that's hopefully both: - * - * u, v = A, N # N is called p in the paper but doesn't have to be prime - * q, r = 0, 1 - * repeat bits(A_limbs + N_limbs) times: - * d = v - u # t1 in Alg 7 - * t1 = (u and v both odd) ? u : d # t1 in Alg 8 - * t2 = (u and v both odd) ? d : (u odd) ? v : u # t2 in Alg 8 - * t2 >>= 1 - * swap = t1 > t2 # similar to s, z in Alg 8 - * u, v = (swap) ? t2, t1 : t1, t2 - * - * d = r - q mod N # t2 in Alg 7 - * t1 = (u and v both odd) ? q : d # t3 in Alg 8 - * t2 = (u and v both odd) ? d : (u odd) ? r : q # t4 Alg 8 - * t2 /= 2 mod N # see below (pre_com) - * q, r = (swap) ? t2, t1 : t1, t2 - * return v, q # v: GCD, see Alg 6; q: no mult by pre_com, see below - * - * The ternary operators in the above pseudo-code need to be realised in a - * constant-time fashion. We use conditional assign for t1, t2 and conditional - * swap for the final update. (Note: the similarity between branches of Alg 7 - * are highlighted in tables 2 and 3 and the surrounding text.) - * - * Also, we re-order operations, grouping things related to the inverse, which - * facilitates making its computation optional, and requires fewer temporaries. - * - * The only actual change from the paper is dropping the trick with pre_com, - * which I think complicates things for no benefit. - * See the comment on the big I != NULL block below for details. - */ -void mbedtls_mpi_core_gcd_modinv_odd(mbedtls_mpi_uint *G, - mbedtls_mpi_uint *I, - const mbedtls_mpi_uint *A, - size_t A_limbs, - const mbedtls_mpi_uint *N, - size_t N_limbs, - mbedtls_mpi_uint *T) -{ - /* GCD and modinv, names common to Alg 7 and Alg 8 */ - mbedtls_mpi_uint *u = T + 0 * N_limbs; - mbedtls_mpi_uint *v = G; - - /* GCD and modinv, my name (t1, t2 from Alg 7) */ - mbedtls_mpi_uint *d = T + 1 * N_limbs; - - /* GCD and modinv, names from Alg 8 (note: t1, t2 from Alg 7 are d above) */ - mbedtls_mpi_uint *t1 = T + 2 * N_limbs; - mbedtls_mpi_uint *t2 = T + 3 * N_limbs; - - /* modinv only, names common to Alg 7 and Alg 8 */ - mbedtls_mpi_uint *q = I; - mbedtls_mpi_uint *r = I != NULL ? T + 4 * N_limbs : NULL; - - /* - * Initial values: - * u, v = A, N - * q, r = 0, 1 - * - * We only write to G (aka v) after reading from inputs (A and N), which - * allows aliasing, except with N when I != NULL, as then we'll be operating - * mod N on q and r later - see the public documentation. - */ - if (A_limbs > N_limbs) { - /* Violating this precondition should not result in memory errors. */ - A_limbs = N_limbs; - } - memcpy(u, A, A_limbs * ciL); - memset((char *) u + A_limbs * ciL, 0, (N_limbs - A_limbs) * ciL); - - /* Avoid possible UB with memcpy when src == dst. */ - if (v != N) { - memcpy(v, N, N_limbs * ciL); - } - - if (I != NULL) { - memset(q, 0, N_limbs * ciL); - - memset(r, 0, N_limbs * ciL); - r[0] = 1; - } - - /* - * At each step, out of u, v, v - u we keep one, shift another, and discard - * the third, then update (u, v) with the ordered result. - * Then we mirror those actions with q, r, r - q mod N. - * - * Loop invariants: - * u <= v (on entry: A <= N) - * GCD(u, v) == GCD(A, N) (on entry: trivial) - * v = A * q mod N (on entry: N = A * 0 mod N) - * u = A * r mod N (on entry: A = A * 1 mod N) - * q, r in [0, N) (on entry: 0, 1) - * - * On exit: - * u = 0 - * v = GCD(A, N) = A * q mod N - * if v == 1 then 1 = A * q mod N ie q is A's inverse mod N - * r = 0 - * - * The exit state is a fixed point of the loop's body. - * Alg 7 and Alg 8 use 2 * bitlen(N) iterations but Theorem 2 (above in the - * paper) says bitlen(A) + bitlen(N) is actually enough. - */ - for (size_t i = 0; i < (A_limbs + N_limbs) * biL; i++) { - /* s, z in Alg 8 - use meaningful names instead */ - mbedtls_ct_condition_t u_odd = mbedtls_ct_bool(u[0] & 1); - mbedtls_ct_condition_t v_odd = mbedtls_ct_bool(v[0] & 1); - - /* Other conditions that will be useful below */ - mbedtls_ct_condition_t u_odd_v_odd = mbedtls_ct_bool_and(u_odd, v_odd); - mbedtls_ct_condition_t v_even = mbedtls_ct_bool_not(v_odd); - mbedtls_ct_condition_t u_odd_v_even = mbedtls_ct_bool_and(u_odd, v_even); - - /* This is called t1 in Alg 7 (no name in Alg 8). - * We know that u <= v so there is no carry */ - (void) mbedtls_mpi_core_sub(d, v, u, N_limbs); - - /* t1 (the thing that's kept) can be d (default) or u (if t2 is d) */ - memcpy(t1, d, N_limbs * ciL); - mbedtls_mpi_core_cond_assign(t1, u, N_limbs, u_odd_v_odd); - - /* t2 (the thing that's shifted) can be u (if even), or v (if even), - * or d (which is even if both u and v were odd) */ - memcpy(t2, u, N_limbs * ciL); - mbedtls_mpi_core_cond_assign(t2, v, N_limbs, u_odd_v_even); - mbedtls_mpi_core_cond_assign(t2, d, N_limbs, u_odd_v_odd); - - mbedtls_mpi_core_shift_r(t2, N_limbs, 1); // t2 is even - - /* Update u, v and re-order them if needed */ - memcpy(u, t1, N_limbs * ciL); - memcpy(v, t2, N_limbs * ciL); - mbedtls_ct_condition_t swap = mbedtls_mpi_core_lt_ct(v, u, N_limbs); - mbedtls_mpi_core_cond_swap(u, v, N_limbs, swap); - - /* Now, if modinv was requested, do the same with q, r, but: - * - decisions still based on u and v (their initial values); - * - operations are now mod N; - * - we re-use t1, t2 for what the paper calls t3, t4 in Alg 8. - * - * Here we slightly diverge from the paper and instead do the obvious - * thing that preserves the invariants involving q and r: mirror - * operations on u and v, ie also divide by 2 here (mod N). - * - * The paper uses a trick where it replaces division by 2 with - * multiplication by 2 here, and compensates in the end by multiplying - * by pre_com, which is probably intended as an optimisation. - * - * However I believe it's not actually an optimisation, since - * constant-time modular multiplication by 2 (left-shift + conditional - * subtract) is just as costly as constant-time modular division by 2 - * (conditional add + right-shift). So, skip it and keep things simple. - */ - if (I != NULL) { - /* This is called t2 in Alg 7 (no name in Alg 8). */ - mpi_core_sub_mod(d, q, r, N, N_limbs); - - /* t3 (the thing that's kept) */ - memcpy(t1, d, N_limbs * ciL); - mbedtls_mpi_core_cond_assign(t1, r, N_limbs, u_odd_v_odd); - - /* t4 (the thing that's shifted) */ - memcpy(t2, r, N_limbs * ciL); - mbedtls_mpi_core_cond_assign(t2, q, N_limbs, u_odd_v_even); - mbedtls_mpi_core_cond_assign(t2, d, N_limbs, u_odd_v_odd); - - mbedtls_mpi_core_div2_mod_odd(t2, N, N_limbs); - - /* Update and possibly swap */ - memcpy(r, t1, N_limbs * ciL); - memcpy(q, t2, N_limbs * ciL); - mbedtls_mpi_core_cond_swap(r, q, N_limbs, swap); - } - } - - /* G and I already hold the correct values by virtue of being aliased */ -} - -#endif /* MBEDTLS_BIGNUM_C */ diff --git a/vendor/mbedtls/library/bignum_core.h b/vendor/mbedtls/library/bignum_core.h deleted file mode 100644 index f044b33f9..000000000 --- a/vendor/mbedtls/library/bignum_core.h +++ /dev/null @@ -1,866 +0,0 @@ -/** - * Core bignum functions - * - * This interface should only be used by the legacy bignum module (bignum.h) - * and the modular bignum modules (bignum_mod.c, bignum_mod_raw.c). All other - * modules should use the high-level modular bignum interface (bignum_mod.h) - * or the legacy bignum interface (bignum.h). - * - * This module is about processing non-negative integers with a fixed upper - * bound that's of the form 2^n-1 where n is a multiple of #biL. - * These can be thought of integers written in base 2^#biL with a fixed - * number of digits. Digits in this base are called *limbs*. - * Many operations treat these numbers as the principal representation of - * a number modulo 2^n or a smaller bound. - * - * The functions in this module obey the following conventions unless - * explicitly indicated otherwise: - * - * - **Overflow**: some functions indicate overflow from the range - * [0, 2^n-1] by returning carry parameters, while others operate - * modulo and so cannot overflow. This should be clear from the function - * documentation. - * - **Bignum parameters**: Bignums are passed as pointers to an array of - * limbs. A limb has the type #mbedtls_mpi_uint. Unless otherwise specified: - * - Bignum parameters called \p A, \p B, ... are inputs, and are - * not modified by the function. - * - For operations modulo some number, the modulus is called \p N - * and is input-only. - * - Bignum parameters called \p X, \p Y are outputs or input-output. - * The initial content of output-only parameters is ignored. - * - Some functions use different names that reflect traditional - * naming of operands of certain operations (e.g. - * divisor/dividend/quotient/remainder). - * - \p T is a temporary storage area. The initial content of such - * parameter is ignored and the final content is unspecified. - * - **Bignum sizes**: bignum sizes are always expressed in limbs. - * Most functions work on bignums of a given size and take a single - * \p limbs parameter that applies to all parameters that are limb arrays. - * All bignum sizes must be at least 1 and must be significantly less than - * #SIZE_MAX. The behavior if a size is 0 is undefined. The behavior if the - * total size of all parameters overflows #SIZE_MAX is undefined. - * - **Parameter ordering**: for bignum parameters, outputs come before inputs. - * Temporaries come last. - * - **Aliasing**: in general, output bignums may be aliased to one or more - * inputs. As an exception, parameters that are documented as a modulus value - * may not be aliased to an output. Outputs may not be aliased to one another. - * Temporaries may not be aliased to any other parameter. - * - **Overlap**: apart from aliasing of limb array pointers (where two - * arguments are equal pointers), overlap is not supported and may result - * in undefined behavior. - * - **Error handling**: This is a low-level module. Functions generally do not - * try to protect against invalid arguments such as nonsensical sizes or - * null pointers. Note that some functions that operate on bignums of - * different sizes have constraints about their size, and violating those - * constraints may lead to buffer overflows. - * - **Modular representatives**: functions that operate modulo \p N expect - * all modular inputs to be in the range [0, \p N - 1] and guarantee outputs - * in the range [0, \p N - 1]. If an input is out of range, outputs are - * fully unspecified, though bignum values out of range should not cause - * buffer overflows (beware that this is not extensively tested). - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_BIGNUM_CORE_H -#define MBEDTLS_BIGNUM_CORE_H - -#include "common.h" - -#include "mbedtls/bignum.h" - -#include "constant_time_internal.h" - -#define ciL (sizeof(mbedtls_mpi_uint)) /** chars in limb */ -#define biL (ciL << 3) /** bits in limb */ -#define biH (ciL << 2) /** half limb size */ - -/* - * Convert between bits/chars and number of limbs - * Divide first in order to avoid potential overflows - */ -#define BITS_TO_LIMBS(i) ((i) / biL + ((i) % biL != 0)) -#define CHARS_TO_LIMBS(i) ((i) / ciL + ((i) % ciL != 0)) -/* Get a specific byte, without range checks. */ -#define GET_BYTE(X, i) \ - (((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff) - -/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by - * this constant, the function must be constant time with respect to the parameter. - * - * This is only needed for functions with the _optionally_safe postfix. All other functions have - * fixed behavior that can't be changed at runtime and are constant time with respect to their - * parameters as prescribed by their documentation or by conventions in their module's documentation. - * - * Parameters should be named X_public where X is the name of the - * corresponding input parameter. - * - * Implementation should always check using - * if (X_public == MBEDTLS_MPI_IS_PUBLIC) { - * // unsafe path - * } else { - * // safe path - * } - * not the other way round, in order to prevent misuse. (That is, if a value - * other than the two below is passed, default to the safe path.) - * - * The value of MBEDTLS_MPI_IS_PUBLIC is chosen in a way that is unlikely to happen by accident, but - * which can be used as an immediate value in a Thumb2 comparison (for code size). */ -#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a2a2a -#define MBEDTLS_MPI_IS_SECRET 0 -#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) -// Default value for testing that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET -#define MBEDTLS_MPI_IS_TEST 1 -#endif - -/** Count leading zero bits in a given integer. - * - * \warning The result is undefined if \p a == 0 - * - * \param a Integer to count leading zero bits. - * - * \return The number of leading zero bits in \p a, if \p a != 0. - * If \p a == 0, the result is undefined. - */ -size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a); - -/** Return the minimum number of bits required to represent the value held - * in the MPI. - * - * \note This function returns 0 if all the limbs of \p A are 0. - * - * \param[in] A The address of the MPI. - * \param A_limbs The number of limbs of \p A. - * - * \return The number of bits in \p A. - */ -size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs); - -/** Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint - * into the storage form used by mbedtls_mpi. - * - * \param[in,out] A The address of the MPI. - * \param A_limbs The number of limbs of \p A. - */ -void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A, - size_t A_limbs); - -/** \brief Compare a machine integer with an MPI. - * - * This function operates in constant time with respect - * to the values of \p min and \p A. - * - * \param min A machine integer. - * \param[in] A An MPI. - * \param A_limbs The number of limbs of \p A. - * This must be at least 1. - * - * \return MBEDTLS_CT_TRUE if \p min is less than or equal to \p A, otherwise MBEDTLS_CT_FALSE. - */ -mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min, - const mbedtls_mpi_uint *A, - size_t A_limbs); - -/** - * \brief Check if one unsigned MPI is less than another in constant - * time. - * - * \param A The left-hand MPI. This must point to an array of limbs - * with the same allocated length as \p B. - * \param B The right-hand MPI. This must point to an array of limbs - * with the same allocated length as \p A. - * \param limbs The number of limbs in \p A and \p B. - * This must not be 0. - * - * \return MBEDTLS_CT_TRUE if \p A is less than \p B. - * MBEDTLS_CT_FALSE if \p A is greater than or equal to \p B. - */ -mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - size_t limbs); - -/** - * \brief Perform a safe conditional copy of an MPI which doesn't reveal - * whether assignment was done or not. - * - * \param[out] X The address of the destination MPI. - * This must be initialized. Must have enough limbs to - * store the full value of \p A. - * \param[in] A The address of the source MPI. This must be initialized. - * \param limbs The number of limbs of \p A. - * \param assign The condition deciding whether to perform the - * assignment or not. Callers will need to use - * the constant time interface (e.g. `mbedtls_ct_bool()`) - * to construct this argument. - * - * \note This function avoids leaking any information about whether - * the assignment was done or not. - */ -void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - size_t limbs, - mbedtls_ct_condition_t assign); - -/** - * \brief Perform a safe conditional swap of two MPIs which doesn't reveal - * whether the swap was done or not. - * - * \param[in,out] X The address of the first MPI. - * This must be initialized. - * \param[in,out] Y The address of the second MPI. - * This must be initialized. - * \param limbs The number of limbs of \p X and \p Y. - * \param swap The condition deciding whether to perform - * the swap or not. - * - * \note This function avoids leaking any information about whether - * the swap was done or not. - */ -void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X, - mbedtls_mpi_uint *Y, - size_t limbs, - mbedtls_ct_condition_t swap); - -/** Import X from unsigned binary data, little-endian. - * - * The MPI needs to have enough limbs to store the full value (including any - * most significant zero bytes in the input). - * - * \param[out] X The address of the MPI. - * \param X_limbs The number of limbs of \p X. - * \param[in] input The input buffer to import from. - * \param input_length The length bytes of \p input. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't - * large enough to hold the value in \p input. - */ -int mbedtls_mpi_core_read_le(mbedtls_mpi_uint *X, - size_t X_limbs, - const unsigned char *input, - size_t input_length); - -/** Import X from unsigned binary data, big-endian. - * - * The MPI needs to have enough limbs to store the full value (including any - * most significant zero bytes in the input). - * - * \param[out] X The address of the MPI. - * May only be #NULL if \p X_limbs is 0 and \p input_length - * is 0. - * \param X_limbs The number of limbs of \p X. - * \param[in] input The input buffer to import from. - * May only be #NULL if \p input_length is 0. - * \param input_length The length in bytes of \p input. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't - * large enough to hold the value in \p input. - */ -int mbedtls_mpi_core_read_be(mbedtls_mpi_uint *X, - size_t X_limbs, - const unsigned char *input, - size_t input_length); - -/** Export A into unsigned binary data, little-endian. - * - * \note If \p output is shorter than \p A the export is still successful if the - * value held in \p A fits in the buffer (that is, if enough of the most - * significant bytes of \p A are 0). - * - * \param[in] A The address of the MPI. - * \param A_limbs The number of limbs of \p A. - * \param[out] output The output buffer to export to. - * \param output_length The length in bytes of \p output. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't - * large enough to hold the value of \p A. - */ -int mbedtls_mpi_core_write_le(const mbedtls_mpi_uint *A, - size_t A_limbs, - unsigned char *output, - size_t output_length); - -/** Export A into unsigned binary data, big-endian. - * - * \note If \p output is shorter than \p A the export is still successful if the - * value held in \p A fits in the buffer (that is, if enough of the most - * significant bytes of \p A are 0). - * - * \param[in] A The address of the MPI. - * \param A_limbs The number of limbs of \p A. - * \param[out] output The output buffer to export to. - * \param output_length The length in bytes of \p output. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't - * large enough to hold the value of \p A. - */ -int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *A, - size_t A_limbs, - unsigned char *output, - size_t output_length); - -/** \brief Shift an MPI in-place right by a number of bits. - * - * Shifting by more bits than there are bit positions - * in \p X is valid and results in setting \p X to 0. - * - * This function's execution time depends on the value - * of \p count (and of course \p limbs). - * - * \param[in,out] X The number to shift. - * \param limbs The number of limbs of \p X. This must be at least 1. - * \param count The number of bits to shift by. - */ -void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs, - size_t count); - -/** - * \brief Shift an MPI in-place left by a number of bits. - * - * Shifting by more bits than there are bit positions - * in \p X will produce an unspecified result. - * - * This function's execution time depends on the value - * of \p count (and of course \p limbs). - * \param[in,out] X The number to shift. - * \param limbs The number of limbs of \p X. This must be at least 1. - * \param count The number of bits to shift by. - */ -void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs, - size_t count); - -/** - * \brief Add two fixed-size large unsigned integers, returning the carry. - * - * Calculates `A + B` where `A` and `B` have the same size. - * - * This function operates modulo `2^(biL*limbs)` and returns the carry - * (1 if there was a wraparound, and 0 otherwise). - * - * \p X may be aliased to \p A or \p B. - * - * \param[out] X The result of the addition. - * \param[in] A Little-endian presentation of the left operand. - * \param[in] B Little-endian presentation of the right operand. - * \param limbs Number of limbs of \p X, \p A and \p B. - * - * \return 1 if `A + B >= 2^(biL*limbs)`, 0 otherwise. - */ -mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - size_t limbs); - -/** - * \brief Conditional addition of two fixed-size large unsigned integers, - * returning the carry. - * - * Functionally equivalent to - * - * ``` - * if( cond ) - * X += A; - * return carry; - * ``` - * - * This function operates modulo `2^(biL*limbs)`. - * - * \param[in,out] X The pointer to the (little-endian) array - * representing the bignum to accumulate onto. - * \param[in] A The pointer to the (little-endian) array - * representing the bignum to conditionally add - * to \p X. This may be aliased to \p X but may not - * overlap otherwise. - * \param limbs Number of limbs of \p X and \p A. - * \param cond Condition bit dictating whether addition should - * happen or not. This must be \c 0 or \c 1. - * - * \warning If \p cond is neither 0 nor 1, the result of this function - * is unspecified, and the resulting value in \p X might be - * neither its original value nor \p X + \p A. - * - * \return 1 if `X + cond * A >= 2^(biL*limbs)`, 0 otherwise. - */ -mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - size_t limbs, - unsigned cond); - -/** - * \brief Subtract two fixed-size large unsigned integers, returning the borrow. - * - * Calculate `A - B` where \p A and \p B have the same size. - * This function operates modulo `2^(biL*limbs)` and returns the carry - * (1 if there was a wraparound, i.e. if `A < B`, and 0 otherwise). - * - * \p X may be aliased to \p A or \p B, or even both, but may not overlap - * either otherwise. - * - * \param[out] X The result of the subtraction. - * \param[in] A Little-endian presentation of left operand. - * \param[in] B Little-endian presentation of right operand. - * \param limbs Number of limbs of \p X, \p A and \p B. - * - * \return 1 if `A < B`. - * 0 if `A >= B`. - */ -mbedtls_mpi_uint mbedtls_mpi_core_sub(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - size_t limbs); - -/** - * \brief Perform a fixed-size multiply accumulate operation: X += b * A - * - * \p X may be aliased to \p A (when \p X_limbs == \p A_limbs), but may not - * otherwise overlap. - * - * This function operates modulo `2^(biL*X_limbs)`. - * - * \param[in,out] X The pointer to the (little-endian) array - * representing the bignum to accumulate onto. - * \param X_limbs The number of limbs of \p X. This must be - * at least \p A_limbs. - * \param[in] A The pointer to the (little-endian) array - * representing the bignum to multiply with. - * This may be aliased to \p X but may not overlap - * otherwise. - * \param A_limbs The number of limbs of \p A. - * \param b X scalar to multiply with. - * - * \return The carry at the end of the operation. - */ -mbedtls_mpi_uint mbedtls_mpi_core_mla(mbedtls_mpi_uint *X, size_t X_limbs, - const mbedtls_mpi_uint *A, size_t A_limbs, - mbedtls_mpi_uint b); - -/** - * \brief Perform a known-size multiplication - * - * \p X may not be aliased to any of the inputs for this function. - * \p A may be aliased to \p B. - * - * \param[out] X The pointer to the (little-endian) array to receive - * the product of \p A_limbs and \p B_limbs. - * This must be of length \p A_limbs + \p B_limbs. - * \param[in] A The pointer to the (little-endian) array - * representing the first factor. - * \param A_limbs The number of limbs in \p A. - * \param[in] B The pointer to the (little-endian) array - * representing the second factor. - * \param B_limbs The number of limbs in \p B. - */ -void mbedtls_mpi_core_mul(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, size_t A_limbs, - const mbedtls_mpi_uint *B, size_t B_limbs); - -/** - * \brief Calculate initialisation value for fast Montgomery modular - * multiplication - * - * \param[in] N Little-endian presentation of the modulus. This must have - * at least one limb. - * - * \return The initialisation value for fast Montgomery modular multiplication - */ -mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N); - -/** - * \brief Montgomery multiplication: X = A * B * R^-1 mod N (HAC 14.36) - * - * \p A and \p B must be in canonical form. That is, < \p N. - * - * \p X may be aliased to \p A or \p N, or even \p B (if \p AN_limbs == - * \p B_limbs) but may not overlap any parameters otherwise. - * - * \p A and \p B may alias each other, if \p AN_limbs == \p B_limbs. They may - * not alias \p N (since they must be in canonical form, they cannot == \p N). - * - * \param[out] X The destination MPI, as a little-endian array of - * length \p AN_limbs. - * On successful completion, X contains the result of - * the multiplication `A * B * R^-1` mod N where - * `R = 2^(biL*AN_limbs)`. - * \param[in] A Little-endian presentation of first operand. - * Must have the same number of limbs as \p N. - * \param[in] B Little-endian presentation of second operand. - * \param[in] B_limbs The number of limbs in \p B. - * Must be <= \p AN_limbs. - * \param[in] N Little-endian presentation of the modulus. - * This must be odd, and have exactly the same number - * of limbs as \p A. - * It may alias \p X, but must not alias or otherwise - * overlap any of the other parameters. - * \param[in] AN_limbs The number of limbs in \p X, \p A and \p N. - * \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL. - * This can be calculated by `mbedtls_mpi_core_montmul_init()`. - * \param[in,out] T Temporary storage of size at least 2*AN_limbs+1 limbs. - * Its initial content is unused and - * its final content is indeterminate. - * It must not alias or otherwise overlap any of the - * other parameters. - */ -void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, size_t B_limbs, - const mbedtls_mpi_uint *N, size_t AN_limbs, - mbedtls_mpi_uint mm, mbedtls_mpi_uint *T); - -/** - * \brief Calculate the square of the Montgomery constant. (Needed - * for conversion and operations in Montgomery form.) - * - * \param[out] X A pointer to the result of the calculation of - * the square of the Montgomery constant: - * 2^{2*n*biL} mod N. - * \param[in] N Little-endian presentation of the modulus, which must be odd. - * - * \return 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if there is not enough space - * to store the value of Montgomery constant squared. - * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p N modulus is zero. - * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p N modulus is negative. - */ -int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X, - const mbedtls_mpi *N); - -#if defined(MBEDTLS_TEST_HOOKS) -/** - * Copy an MPI from a table without leaking the index. - * - * \param dest The destination buffer. This must point to a writable - * buffer of at least \p limbs limbs. - * \param table The address of the table. This must point to a readable - * array of \p count elements of \p limbs limbs each. - * \param limbs The number of limbs in each table entry. - * \param count The number of entries in \p table. - * \param index The (secret) table index to look up. This must be in the - * range `0 .. count-1`. - */ -void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest, - const mbedtls_mpi_uint *table, - size_t limbs, - size_t count, - size_t index); -#endif /* MBEDTLS_TEST_HOOKS */ - -/** - * \brief Fill an integer with a number of random bytes. - * - * \param X The destination MPI. - * \param X_limbs The number of limbs of \p X. - * \param bytes The number of random bytes to generate. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. This may be - * \c NULL if \p f_rng doesn't need a context argument. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p X does not have - * enough room for \p bytes bytes. - * \return A negative error code on RNG failure. - * - * \note The bytes obtained from the RNG are interpreted - * as a big-endian representation of an MPI; this can - * be relevant in applications like deterministic ECDSA. - */ -int mbedtls_mpi_core_fill_random(mbedtls_mpi_uint *X, size_t X_limbs, - size_t bytes, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - -/** Generate a random number uniformly in a range. - * - * This function generates a random number between \p min inclusive and - * \p N exclusive. - * - * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA) - * when the RNG is a suitably parametrized instance of HMAC_DRBG - * and \p min is \c 1. - * - * \note There are `N - min` possible outputs. The lower bound - * \p min can be reached, but the upper bound \p N cannot. - * - * \param X The destination MPI, with \p limbs limbs. - * It must not be aliased with \p N or otherwise overlap it. - * \param min The minimum value to return. - * \param N The upper bound of the range, exclusive, with \p limbs limbs. - * In other words, this is one plus the maximum value to return. - * \p N must be strictly larger than \p min. - * \param limbs The number of limbs of \p N and \p X. - * This must not be 0. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was - * unable to find a suitable value within a limited number - * of attempts. This has a negligible probability if \p N - * is significantly larger than \p min, which is the case - * for all usual cryptographic applications. - */ -int mbedtls_mpi_core_random(mbedtls_mpi_uint *X, - mbedtls_mpi_uint min, - const mbedtls_mpi_uint *N, - size_t limbs, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - -/** - * \brief Returns the number of limbs of working memory required for - * a call to `mbedtls_mpi_core_exp_mod()`. - * - * \note This will always be at least - * `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)`, - * i.e. sufficient for a call to `mbedtls_mpi_core_montmul()`. - * - * \param AN_limbs The number of limbs in the input `A` and the modulus `N` - * (they must be the same size) that will be given to - * `mbedtls_mpi_core_exp_mod()`. - * \param E_limbs The number of limbs in the exponent `E` that will be given - * to `mbedtls_mpi_core_exp_mod()`. - * - * \return The number of limbs of working memory required by - * `mbedtls_mpi_core_exp_mod()`. - */ -size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs); - -/** - * \brief Perform a modular exponentiation with public or secret exponent: - * X = A^E mod N, where \p A is already in Montgomery form. - * - * \warning This function is not constant time with respect to \p E (the exponent). - * - * \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs == - * \p AN_limbs. - * - * \param[out] X The destination MPI, as a little endian array of length - * \p AN_limbs. - * \param[in] A The base MPI, as a little endian array of length \p AN_limbs. - * Must be in Montgomery form. - * \param[in] N The modulus, as a little endian array of length \p AN_limbs. - * \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR. - * \param[in] E The exponent, as a little endian array of length \p E_limbs. - * \param E_limbs The number of limbs in \p E. - * \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little - * endian array of length \p AN_limbs. - * \param[in,out] T Temporary storage of at least the number of limbs returned - * by `mbedtls_mpi_core_exp_mod_working_limbs()`. - * Its initial content is unused and its final content is - * indeterminate. - * It must not alias or otherwise overlap any of the other - * parameters. - * It is up to the caller to zeroize \p T when it is no - * longer needed, and before freeing it if it was dynamically - * allocated. - */ -void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, size_t AN_limbs, - const mbedtls_mpi_uint *E, size_t E_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T); - -/** - * \brief Perform a modular exponentiation with secret exponent: - * X = A^E mod N, where \p A is already in Montgomery form. - * - * \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs == - * \p AN_limbs. - * - * \param[out] X The destination MPI, as a little endian array of length - * \p AN_limbs. - * \param[in] A The base MPI, as a little endian array of length \p AN_limbs. - * Must be in Montgomery form. - * \param[in] N The modulus, as a little endian array of length \p AN_limbs. - * \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR. - * \param[in] E The exponent, as a little endian array of length \p E_limbs. - * \param E_limbs The number of limbs in \p E. - * \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little - * endian array of length \p AN_limbs. - * \param[in,out] T Temporary storage of at least the number of limbs returned - * by `mbedtls_mpi_core_exp_mod_working_limbs()`. - * Its initial content is unused and its final content is - * indeterminate. - * It must not alias or otherwise overlap any of the other - * parameters. - * It is up to the caller to zeroize \p T when it is no - * longer needed, and before freeing it if it was dynamically - * allocated. - */ -void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, size_t AN_limbs, - const mbedtls_mpi_uint *E, size_t E_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T); - -/** - * \brief Subtract unsigned integer from known-size large unsigned integers. - * Return the borrow. - * - * \param[out] X The result of the subtraction. - * \param[in] A The left operand. - * \param b The unsigned scalar to subtract. - * \param limbs Number of limbs of \p X and \p A. - * - * \return 1 if `A < b`. - * 0 if `A >= b`. - */ -mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - mbedtls_mpi_uint b, - size_t limbs); - -/** - * \brief Determine if a given MPI has the value \c 0 in constant time with - * respect to the value (but not with respect to the number of limbs). - * - * \param[in] A The MPI to test. - * \param limbs Number of limbs in \p A. - * - * \return MBEDTLS_CT_FALSE if `A == 0` - * MBEDTLS_CT_TRUE if `A != 0`. - */ -mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A, - size_t limbs); - -/** - * \brief Returns the number of limbs of working memory required for - * a call to `mbedtls_mpi_core_montmul()`. - * - * \param AN_limbs The number of limbs in the input `A` and the modulus `N` - * (they must be the same size) that will be given to - * `mbedtls_mpi_core_montmul()` or one of the other functions - * that specifies this as the amount of working memory needed. - * - * \return The number of limbs of working memory required by - * `mbedtls_mpi_core_montmul()` (or other similar function). - */ -static inline size_t mbedtls_mpi_core_montmul_working_limbs(size_t AN_limbs) -{ - return 2 * AN_limbs + 1; -} - -/** Convert an MPI into Montgomery form. - * - * \p X may be aliased to \p A, but may not otherwise overlap it. - * - * \p X may not alias \p N (it is in canonical form, so must be strictly less - * than \p N). Nor may it alias or overlap \p rr (this is unlikely to be - * required in practice.) - * - * This function is a thin wrapper around `mbedtls_mpi_core_montmul()` that is - * an alternative to calling `mbedtls_mpi_mod_raw_to_mont_rep()` when we - * don't want to allocate memory. - * - * \param[out] X The result of the conversion. - * Must have the same number of limbs as \p A. - * \param[in] A The MPI to convert into Montgomery form. - * Must have the same number of limbs as the modulus. - * \param[in] N The address of the modulus, which gives the size of - * the base `R` = 2^(biL*N->limbs). - * \param[in] AN_limbs The number of limbs in \p X, \p A, \p N and \p rr. - * \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL. - * This can be determined by calling - * `mbedtls_mpi_core_montmul_init()`. - * \param[in] rr The residue for `2^{2*n*biL} mod N`. - * \param[in,out] T Temporary storage of size at least - * `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)` - * limbs. - * Its initial content is unused and - * its final content is indeterminate. - * It must not alias or otherwise overlap any of the - * other parameters. - */ -void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - mbedtls_mpi_uint mm, - const mbedtls_mpi_uint *rr, - mbedtls_mpi_uint *T); - -/** Convert an MPI from Montgomery form. - * - * \p X may be aliased to \p A, but may not otherwise overlap it. - * - * \p X may not alias \p N (it is in canonical form, so must be strictly less - * than \p N). - * - * This function is a thin wrapper around `mbedtls_mpi_core_montmul()` that is - * an alternative to calling `mbedtls_mpi_mod_raw_from_mont_rep()` when we - * don't want to allocate memory. - * - * \param[out] X The result of the conversion. - * Must have the same number of limbs as \p A. - * \param[in] A The MPI to convert from Montgomery form. - * Must have the same number of limbs as the modulus. - * \param[in] N The address of the modulus, which gives the size of - * the base `R` = 2^(biL*N->limbs). - * \param[in] AN_limbs The number of limbs in \p X, \p A and \p N. - * \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL. - * This can be determined by calling - * `mbedtls_mpi_core_montmul_init()`. - * \param[in,out] T Temporary storage of size at least - * `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)` - * limbs. - * Its initial content is unused and - * its final content is indeterminate. - * It must not alias or otherwise overlap any of the - * other parameters. - */ -void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - mbedtls_mpi_uint mm, - mbedtls_mpi_uint *T); - -/** Compute GCD(A, N) and optionally the inverse of A mod N if it exists. - * - * Requires N to be odd, 0 <= A <= N and A_limbs <= N_limbs. - * When I != NULL, N (the modulus) must be greater than 1. - * - * A and N may not alias each other. - * When I == NULL (computing only the GCD), G may alias A or N. - * When I != NULL (computing the modular inverse), G or I may alias A - * but none of them may alias N (the modulus). - * - * If any of the above preconditions is not met, output values are unspecified. - * - * \param[out] G The GCD of \p A and \p N. - * Must have the same number of limbs as \p N. - * \param[out] I The inverse of \p A modulo \p N if it exists (that is, - * if \p G above is 1 on exit); indeterminate otherwise. - * This must either be NULL (to only compute the GCD), - * or have the same number of limbs as \p N. - * \param[in] A The 1st operand of GCD and number to invert. - * This value must be less than or equal to \p N. - * \param A_limbs The number of limbs of \p A. - * Must be less than or equal to \p N_limbs. - * \param[in] N The 2nd operand of GCD and modulus for inversion. - * This value must be odd. - * If I != NULL this value must be greater than 1. - * \param N_limbs The number of limbs of \p N. - * \param[in,out] T Temporary storage of size at least 5 * N_limbs limbs, - * or 4 * N_limbs if \p I is NULL (GCD only). - * Its initial content is unused and - * its final content is indeterminate. - * It must not alias or otherwise overlap any of the - * other parameters. - */ -void mbedtls_mpi_core_gcd_modinv_odd(mbedtls_mpi_uint *G, - mbedtls_mpi_uint *I, - const mbedtls_mpi_uint *A, - size_t A_limbs, - const mbedtls_mpi_uint *N, - size_t N_limbs, - mbedtls_mpi_uint *T); - -#endif /* MBEDTLS_BIGNUM_CORE_H */ diff --git a/vendor/mbedtls/library/bignum_core_invasive.h b/vendor/mbedtls/library/bignum_core_invasive.h deleted file mode 100644 index a9d447f79..000000000 --- a/vendor/mbedtls/library/bignum_core_invasive.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * \file bignum_core_invasive.h - * - * \brief Function declarations for invasive functions of bignum core. - */ -/** - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_BIGNUM_CORE_INVASIVE_H -#define MBEDTLS_BIGNUM_CORE_INVASIVE_H - -#include "bignum_core.h" - -#if defined(MBEDTLS_TEST_HOOKS) - -#if !defined(MBEDTLS_THREADING_C) - -extern void (*mbedtls_safe_codepath_hook)(void); -extern void (*mbedtls_unsafe_codepath_hook)(void); - -#endif /* !MBEDTLS_THREADING_C */ - -/** Divide X by 2 mod N in place, assuming N is odd. - * - * \param[in,out] X The value to divide by 2 mod \p N. - * \param[in] N The modulus. Must be odd. - * \param[in] limbs The number of limbs in \p X and \p N. - */ -MBEDTLS_STATIC_TESTABLE -void mbedtls_mpi_core_div2_mod_odd(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *N, - size_t limbs); - -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* MBEDTLS_BIGNUM_CORE_INVASIVE_H */ diff --git a/vendor/mbedtls/library/bignum_internal.h b/vendor/mbedtls/library/bignum_internal.h deleted file mode 100644 index ba1c69d6b..000000000 --- a/vendor/mbedtls/library/bignum_internal.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * \file bignum_internal.h - * - * \brief Internal-only bignum public-key cryptosystem API. - * - * This file declares bignum-related functions that are to be used - * only from within the Mbed TLS library itself. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_BIGNUM_INTERNAL_H -#define MBEDTLS_BIGNUM_INTERNAL_H - -/** - * \brief Perform a modular exponentiation: X = A^E mod N - * - * \warning This function is not constant time with respect to \p E (the exponent). - * - * \param X The destination MPI. This must point to an initialized MPI. - * This must not alias E or N. - * \param A The base of the exponentiation. - * This must point to an initialized MPI. - * \param E The exponent MPI. This must point to an initialized MPI. - * \param N The base for the modular reduction. This must point to an - * initialized MPI. - * \param prec_RR A helper MPI depending solely on \p N which can be used to - * speed-up multiple modular exponentiations for the same value - * of \p N. This may be \c NULL. If it is not \c NULL, it must - * point to an initialized MPI. If it hasn't been used after - * the call to mbedtls_mpi_init(), this function will compute - * the helper value and store it in \p prec_RR for reuse on - * subsequent calls to this function. Otherwise, the function - * will assume that \p prec_RR holds the helper value set by a - * previous call to mbedtls_mpi_exp_mod(), and reuse it. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or - * even, or if \c E is negative. - * \return Another negative error code on different kinds of failures. - * - */ -int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A, - const mbedtls_mpi *E, const mbedtls_mpi *N, - mbedtls_mpi *prec_RR); - -/** - * \brief A wrapper around a constant time function to compute - * GCD(A, N) and/or A^-1 mod N if it exists. - * - * \warning Requires N to be odd, and 0 <= A <= N. Additionally, if - * I != NULL, requires N > 1. - * The wrapper part of this function is not constant time. - * - * \note A and N must not alias each other. - * When I == NULL (computing only the GCD), G can alias A or N. - * When I != NULL (computing the modular inverse), G or I can - * alias A, but neither of them can alias N (the modulus). - * - * \param[out] G The GCD of \p A and \p N. - * This may be NULL, to only compute I. - * \param[out] I The inverse of \p A modulo \p N if it exists (that is, - * if \p G above is 1 on exit), in the range [1, \p N); - * indeterminate otherwise. - * This may be NULL, to only compute G. - * \param[in] A The 1st operand of GCD and number to invert. - * This value must be less than or equal to \p N. - * \param[in] N The 2nd operand of GCD and modulus for inversion. - * Must be odd or the results are indeterminate. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if preconditions were not - * met. - */ -int mbedtls_mpi_gcd_modinv_odd(mbedtls_mpi *G, - mbedtls_mpi *I, - const mbedtls_mpi *A, - const mbedtls_mpi *N); - -/** - * \brief Modular inverse: X = A^-1 mod N with N odd - * - * \param[out] X The inverse of \p A modulo \p N in the range [1, \p N) - * on success; indeterminate otherwise. - * \param[in] A The number to invert. - * \param[in] N The modulus. Must be odd and greater than 1. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if preconditions were not - * met. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A is not invertible mod N. - */ -int mbedtls_mpi_inv_mod_odd(mbedtls_mpi *X, - const mbedtls_mpi *A, - const mbedtls_mpi *N); - -/** - * \brief Modular inverse: X = A^-1 mod N with N even, - * A odd and 1 < A < N. - * - * \param[out] X The inverse of \p A modulo \p N in the range [1, \p N) - * on success; indeterminate otherwise. - * \param[in] A The number to invert. Must be odd, greated than 1 - * and less than \p N. - * \param[in] N The modulus. Must be even and greater than 1. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if preconditions were not - * met. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A is not invertible mod N. - */ -int mbedtls_mpi_inv_mod_even_in_range(mbedtls_mpi *X, - mbedtls_mpi const *A, - mbedtls_mpi const *N); - -#endif /* bignum_internal.h */ diff --git a/vendor/mbedtls/library/bignum_mod.c b/vendor/mbedtls/library/bignum_mod.c deleted file mode 100644 index dfd332a70..000000000 --- a/vendor/mbedtls/library/bignum_mod.c +++ /dev/null @@ -1,394 +0,0 @@ -/** - * Modular bignum functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT) - -#include - -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/bignum.h" - -#include "mbedtls/platform.h" - -#include "bignum_core.h" -#include "bignum_mod.h" -#include "bignum_mod_raw.h" -#include "constant_time_internal.h" - -int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *p, - size_t p_limbs) -{ - if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - r->limbs = N->limbs; - r->p = p; - - return 0; -} - -void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r) -{ - if (r == NULL) { - return; - } - - r->limbs = 0; - r->p = NULL; -} - -void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N) -{ - if (N == NULL) { - return; - } - - N->p = NULL; - N->limbs = 0; - N->bits = 0; - N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID; -} - -void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N) -{ - if (N == NULL) { - return; - } - - switch (N->int_rep) { - case MBEDTLS_MPI_MOD_REP_MONTGOMERY: - if (N->rep.mont.rr != NULL) { - mbedtls_zeroize_and_free((mbedtls_mpi_uint *) N->rep.mont.rr, - N->limbs * sizeof(mbedtls_mpi_uint)); - N->rep.mont.rr = NULL; - } - N->rep.mont.mm = 0; - break; - case MBEDTLS_MPI_MOD_REP_OPT_RED: - N->rep.ored.modp = NULL; - break; - case MBEDTLS_MPI_MOD_REP_INVALID: - break; - } - - N->p = NULL; - N->limbs = 0; - N->bits = 0; - N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID; -} - -static int set_mont_const_square(const mbedtls_mpi_uint **X, - const mbedtls_mpi_uint *A, - size_t limbs) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi N; - mbedtls_mpi RR; - *X = NULL; - - mbedtls_mpi_init(&N); - mbedtls_mpi_init(&RR); - - if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) { - goto cleanup; - } - - if (mbedtls_mpi_grow(&N, limbs)) { - goto cleanup; - } - - memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs); - - ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N); - - if (ret == 0) { - *X = RR.p; - RR.p = NULL; - } - -cleanup: - mbedtls_mpi_free(&N); - mbedtls_mpi_free(&RR); - ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0; - return ret; -} - -static inline void standard_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs, - mbedtls_mpi_mod_rep_selector int_rep) -{ - N->p = p; - N->limbs = p_limbs; - N->bits = mbedtls_mpi_core_bitlen(p, p_limbs); - N->int_rep = int_rep; -} - -int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs) -{ - int ret = 0; - standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_MONTGOMERY); - N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p); - ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs); - - if (ret != 0) { - mbedtls_mpi_mod_modulus_free(N); - } - - return ret; -} - -int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs, - mbedtls_mpi_modp_fn modp) -{ - standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_OPT_RED); - N->rep.ored.modp = modp; - return 0; -} - -int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N) -{ - if (N->limbs == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL); - if (T == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T); - - mbedtls_free(T); - - return 0; -} - -int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N) -{ - if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N); - - return 0; -} - -static int mbedtls_mpi_mod_inv_mont(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *working_memory) -{ - /* Input already in Montgomery form, so there's little to do */ - mbedtls_mpi_mod_raw_inv_prime(X->p, A->p, - N->p, N->limbs, - N->rep.mont.rr, - working_memory); - return 0; -} - -static int mbedtls_mpi_mod_inv_non_mont(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *working_memory) -{ - /* Need to convert input into Montgomery form */ - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_mpi_mod_modulus Nmont; - mbedtls_mpi_mod_modulus_init(&Nmont); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs)); - - /* We'll use X->p to hold the Montgomery form of the input A->p */ - mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs, - Nmont.rep.mont.mm, Nmont.rep.mont.rr, - working_memory); - - mbedtls_mpi_mod_raw_inv_prime(X->p, X->p, - Nmont.p, Nmont.limbs, - Nmont.rep.mont.rr, - working_memory); - - /* And convert back from Montgomery form */ - - mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs, - Nmont.rep.mont.mm, working_memory); - -cleanup: - mbedtls_mpi_mod_modulus_free(&Nmont); - return ret; -} - -int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_modulus *N) -{ - if (X->limbs != N->limbs || A->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - /* Zero has the same value regardless of Montgomery form or not */ - if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - size_t working_limbs = - mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs); - - mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs, - sizeof(mbedtls_mpi_uint)); - if (working_memory == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - switch (N->int_rep) { - case MBEDTLS_MPI_MOD_REP_MONTGOMERY: - ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory); - break; - case MBEDTLS_MPI_MOD_REP_OPT_RED: - ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory); - break; - default: - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - break; - } - - mbedtls_zeroize_and_free(working_memory, - working_limbs * sizeof(mbedtls_mpi_uint)); - - return ret; -} - -int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N) -{ - if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N); - - return 0; -} - -int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X, - mbedtls_mpi_uint min, - const mbedtls_mpi_mod_modulus *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - if (X->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - return mbedtls_mpi_mod_raw_random(X->p, min, N, f_rng, p_rng); -} - -int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - const unsigned char *buf, - size_t buflen, - mbedtls_mpi_mod_ext_rep ext_rep) -{ - int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - - /* Do our best to check if r and m have been set up */ - if (r->limbs == 0 || N->limbs == 0) { - goto cleanup; - } - if (r->limbs != N->limbs) { - goto cleanup; - } - - ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep); - if (ret != 0) { - goto cleanup; - } - - r->limbs = N->limbs; - - ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N); - -cleanup: - return ret; -} - -int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - unsigned char *buf, - size_t buflen, - mbedtls_mpi_mod_ext_rep ext_rep) -{ - /* Do our best to check if r and m have been set up */ - if (r->limbs == 0 || N->limbs == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - if (r->limbs != N->limbs) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi_uint *working_memory = r->p; - size_t working_memory_len = sizeof(mbedtls_mpi_uint) * r->limbs; - - if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { - - working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint)); - - if (working_memory == NULL) { - ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; - goto cleanup; - } - - memcpy(working_memory, r->p, working_memory_len); - - ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N); - if (ret != 0) { - goto cleanup; - } - } - - ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep); - -cleanup: - - if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY && - working_memory != NULL) { - - mbedtls_zeroize_and_free(working_memory, working_memory_len); - } - - return ret; -} - -#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */ diff --git a/vendor/mbedtls/library/bignum_mod.h b/vendor/mbedtls/library/bignum_mod.h deleted file mode 100644 index 963d8881a..000000000 --- a/vendor/mbedtls/library/bignum_mod.h +++ /dev/null @@ -1,452 +0,0 @@ -/** - * Modular bignum functions - * - * This module implements operations on integers modulo some fixed modulus. - * - * The functions in this module obey the following conventions unless - * explicitly indicated otherwise: - * - * - **Modulus parameters**: the modulus is passed as a pointer to a structure - * of type #mbedtls_mpi_mod_modulus. The structure must be set up with an - * array of limbs storing the bignum value of the modulus. The modulus must - * be odd and is assumed to have no leading zeroes. The modulus is usually - * named \c N and is usually input-only. Functions which take a parameter - * of type \c const #mbedtls_mpi_mod_modulus* must not modify its value. - * - **Bignum parameters**: Bignums are passed as pointers to an array of - * limbs or to a #mbedtls_mpi_mod_residue structure. A limb has the type - * #mbedtls_mpi_uint. Residues must be initialized before use, and must be - * associated with the modulus \c N. Unless otherwise specified: - * - Bignum parameters called \c A, \c B, ... are inputs and are not - * modified by the function. Functions which take a parameter of - * type \c const #mbedtls_mpi_mod_residue* must not modify its value. - * - Bignum parameters called \c X, \c Y, ... are outputs or input-output. - * The initial bignum value of output-only parameters is ignored, but - * they must be set up and associated with the modulus \c N. Some - * functions (typically constant-flow) require that the limbs in an - * output residue are initialized. - * - Bignum parameters called \c p are inputs used to set up a modulus or - * residue. These must be pointers to an array of limbs. - * - \c T is a temporary storage area. The initial content of such a - * parameter is ignored and the final content is unspecified. - * - Some functions use different names, such as \c r for the residue. - * - **Bignum sizes**: bignum sizes are always expressed in limbs. Both - * #mbedtls_mpi_mod_modulus and #mbedtls_mpi_mod_residue have a \c limbs - * member storing its size. All bignum parameters must have the same - * number of limbs as the modulus. All bignum sizes must be at least 1 and - * must be significantly less than #SIZE_MAX. The behavior if a size is 0 is - * undefined. - * - **Bignum representation**: the representation of inputs and outputs is - * specified by the \c int_rep field of the modulus. - * - **Parameter ordering**: for bignum parameters, outputs come before inputs. - * The modulus is passed after residues. Temporaries come last. - * - **Aliasing**: in general, output bignums may be aliased to one or more - * inputs. Modulus values may not be aliased to any other parameter. Outputs - * may not be aliased to one another. Temporaries may not be aliased to any - * other parameter. - * - **Overlap**: apart from aliasing of residue pointers (where two residue - * arguments are equal pointers), overlap is not supported and may result - * in undefined behavior. - * - **Error handling**: functions generally check compatibility of input - * sizes. Most functions will not check that input values are in canonical - * form (i.e. that \c A < \c N), this is only checked during setup of a - * residue structure. - * - **Modular representatives**: all functions expect inputs to be in the - * range [0, \c N - 1] and guarantee outputs in the range [0, \c N - 1]. - * Residues are set up with an associated modulus, and operations are only - * guaranteed to work if the modulus is associated with all residue - * parameters. If a residue is passed with a modulus other than the one it - * is associated with, then it may be out of range. If an input is out of - * range, outputs are fully unspecified, though bignum values out of range - * should not cause buffer overflows (beware that this is not extensively - * tested). - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_BIGNUM_MOD_H -#define MBEDTLS_BIGNUM_MOD_H - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -/** How residues associated with a modulus are represented. - * - * This also determines which fields of the modulus structure are valid and - * what their contents are (see #mbedtls_mpi_mod_modulus). - */ -typedef enum { - /** Representation not chosen (makes the modulus structure invalid). */ - MBEDTLS_MPI_MOD_REP_INVALID = 0, - /* Skip 1 as it is slightly easier to accidentally pass to functions. */ - /** Montgomery representation. */ - MBEDTLS_MPI_MOD_REP_MONTGOMERY = 2, - /* Optimised reduction available. This indicates a coordinate modulus (P) - * and one or more of the following have been configured: - * - A nist curve (MBEDTLS_ECP_DP_SECPXXXR1_ENABLED) & MBEDTLS_ECP_NIST_OPTIM. - * - A Kobliz Curve. - * - A Fast Reduction Curve CURVE25519 or CURVE448. */ - MBEDTLS_MPI_MOD_REP_OPT_RED, -} mbedtls_mpi_mod_rep_selector; - -/* Make mbedtls_mpi_mod_rep_selector and mbedtls_mpi_mod_ext_rep disjoint to - * make it easier to catch when they are accidentally swapped. */ -typedef enum { - MBEDTLS_MPI_MOD_EXT_REP_INVALID = 0, - MBEDTLS_MPI_MOD_EXT_REP_LE = 8, - MBEDTLS_MPI_MOD_EXT_REP_BE -} mbedtls_mpi_mod_ext_rep; - -typedef struct { - mbedtls_mpi_uint *p; - size_t limbs; -} mbedtls_mpi_mod_residue; - -typedef struct { - mbedtls_mpi_uint const *rr; /* The residue for 2^{2*n*biL} mod N */ - mbedtls_mpi_uint mm; /* Montgomery const for -N^{-1} mod 2^{ciL} */ -} mbedtls_mpi_mont_struct; - -typedef int (*mbedtls_mpi_modp_fn)(mbedtls_mpi_uint *X, size_t X_limbs); - -typedef struct { - mbedtls_mpi_modp_fn modp; /* The optimised reduction function pointer */ -} mbedtls_mpi_opt_red_struct; - -typedef struct { - const mbedtls_mpi_uint *p; - size_t limbs; // number of limbs - size_t bits; // bitlen of p - mbedtls_mpi_mod_rep_selector int_rep; // selector to signal the active member of the union - union rep { - /* if int_rep == #MBEDTLS_MPI_MOD_REP_MONTGOMERY */ - mbedtls_mpi_mont_struct mont; - /* if int_rep == #MBEDTLS_MPI_MOD_REP_OPT_RED */ - mbedtls_mpi_opt_red_struct ored; - } rep; -} mbedtls_mpi_mod_modulus; - -/** Setup a residue structure. - * - * The residue will be set up with the buffer \p p and modulus \p N. - * - * The memory pointed to by \p p will be used by the resulting residue structure. - * The value at the pointed-to memory will be the initial value of \p r and must - * hold a value that is less than the modulus. This value will be used as-is - * and interpreted according to the value of the `N->int_rep` field. - * - * The modulus \p N will be the modulus associated with \p r. The residue \p r - * should only be used in operations where the modulus is \p N. - * - * \param[out] r The address of the residue to setup. - * \param[in] N The address of the modulus related to \p r. - * \param[in] p The address of the limb array containing the value of \p r. - * The memory pointed to by \p p will be used by \p r and must - * not be modified in any way until after - * mbedtls_mpi_mod_residue_release() is called. The data - * pointed to by \p p must be less than the modulus (the value - * pointed to by `N->p`) and already in the representation - * indicated by `N->int_rep`. - * \param p_limbs The number of limbs of \p p. Must be the same as the number - * of limbs in the modulus \p N. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p p_limbs is less than the - * limbs in \p N or if \p p is not less than \p N. - */ -int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *p, - size_t p_limbs); - -/** Unbind elements of a residue structure. - * - * This function removes the reference to the limb array that was passed to - * mbedtls_mpi_mod_residue_setup() to make it safe to free or use again. - * - * This function invalidates \p r and it must not be used until after - * mbedtls_mpi_mod_residue_setup() is called on it again. - * - * \param[out] r The address of residue to release. - */ -void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r); - -/** Initialize a modulus structure. - * - * \param[out] N The address of the modulus structure to initialize. - */ -void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N); - -/** Setup a modulus structure. - * - * \param[out] N The address of the modulus structure to populate. - * \param[in] p The address of the limb array storing the value of \p N. - * The memory pointed to by \p p will be used by \p N and must - * not be modified in any way until after - * mbedtls_mpi_mod_modulus_free() is called. - * \param p_limbs The number of limbs of \p p. - * - * \return \c 0 if successful. - */ -int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs); - -/** Setup an optimised-reduction compatible modulus structure. - * - * \param[out] N The address of the modulus structure to populate. - * \param[in] p The address of the limb array storing the value of \p N. - * The memory pointed to by \p p will be used by \p N and must - * not be modified in any way until after - * mbedtls_mpi_mod_modulus_free() is called. - * \param p_limbs The number of limbs of \p p. - * \param modp A pointer to the optimised reduction function to use. \p p. - * - * \return \c 0 if successful. - */ -int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_mpi_uint *p, - size_t p_limbs, - mbedtls_mpi_modp_fn modp); - -/** Free elements of a modulus structure. - * - * This function frees any memory allocated by mbedtls_mpi_mod_modulus_setup(). - * - * \warning This function does not free the limb array passed to - * mbedtls_mpi_mod_modulus_setup() only removes the reference to it, - * making it safe to free or to use it again. - * - * \param[in,out] N The address of the modulus structure to free. - */ -void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N); - -/** \brief Multiply two residues, returning the residue modulo the specified - * modulus. - * - * \note Currently handles the case when `N->int_rep` is - * MBEDTLS_MPI_MOD_REP_MONTGOMERY. - * - * The size of the operation is determined by \p N. \p A, \p B and \p X must - * all be associated with the modulus \p N and must all have the same number - * of limbs as \p N. - * - * \p X may be aliased to \p A or \p B, or even both, but may not overlap - * either otherwise. They may not alias \p N (since they must be in canonical - * form, they cannot == \p N). - * - * \param[out] X The address of the result MPI. Must have the same - * number of limbs as \p N. - * On successful completion, \p X contains the result of - * the multiplication `A * B * R^-1` mod N where - * `R = 2^(biL * N->limbs)`. - * \param[in] A The address of the first MPI. - * \param[in] B The address of the second MPI. - * \param[in] N The address of the modulus. Used to perform a modulo - * operation on the result of the multiplication. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if all the parameters do not - * have the same number of limbs or \p N is invalid. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. - */ -int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N); - -/** - * \brief Perform a fixed-size modular subtraction. - * - * Calculate `A - B modulo N`. - * - * \p A, \p B and \p X must all have the same number of limbs as \p N. - * - * \p X may be aliased to \p A or \p B, or even both, but may not overlap - * either otherwise. - * - * \note This function does not check that \p A or \p B are in canonical - * form (that is, are < \p N) - that will have been done by - * mbedtls_mpi_mod_residue_setup(). - * - * \param[out] X The address of the result MPI. Must be initialized. - * Must have the same number of limbs as the modulus \p N. - * \param[in] A The address of the first MPI. - * \param[in] B The address of the second MPI. - * \param[in] N The address of the modulus. Used to perform a modulo - * operation on the result of the subtraction. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not - * have the correct number of limbs. - */ -int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N); - -/** - * \brief Perform modular inversion of an MPI with respect to a modulus \p N. - * - * \p A and \p X must be associated with the modulus \p N and will therefore - * have the same number of limbs as \p N. - * - * \p X may be aliased to \p A. - * - * \warning Currently only supports prime moduli, but does not check for them. - * - * \param[out] X The modular inverse of \p A with respect to \p N. - * \param[in] A The number to calculate the modular inverse of. - * Must not be 0. - * \param[in] N The modulus to use. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p A and \p N do not - * have the same number of limbs. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p A is zero. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if couldn't allocate enough - * memory (needed for conversion to and from Mongtomery form - * when not in Montgomery form already, and for temporary use - * by the inversion calculation itself). - */ - -int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_modulus *N); -/** - * \brief Perform a fixed-size modular addition. - * - * Calculate `A + B modulo N`. - * - * \p A, \p B and \p X must all be associated with the modulus \p N and must - * all have the same number of limbs as \p N. - * - * \p X may be aliased to \p A or \p B, or even both, but may not overlap - * either otherwise. - * - * \note This function does not check that \p A or \p B are in canonical - * form (that is, are < \p N) - that will have been done by - * mbedtls_mpi_mod_residue_setup(). - * - * \param[out] X The address of the result residue. Must be initialized. - * Must have the same number of limbs as the modulus \p N. - * \param[in] A The address of the first input residue. - * \param[in] B The address of the second input residue. - * \param[in] N The address of the modulus. Used to perform a modulo - * operation on the result of the addition. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not - * have the correct number of limbs. - */ -int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X, - const mbedtls_mpi_mod_residue *A, - const mbedtls_mpi_mod_residue *B, - const mbedtls_mpi_mod_modulus *N); - -/** Generate a random number uniformly in a range. - * - * This function generates a random number between \p min inclusive and - * \p N exclusive. - * - * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA) - * when the RNG is a suitably parametrized instance of HMAC_DRBG - * and \p min is \c 1. - * - * \note There are `N - min` possible outputs. The lower bound - * \p min can be reached, but the upper bound \p N cannot. - * - * \param X The destination residue. - * \param min The minimum value to return. It must be strictly smaller - * than \b N. - * \param N The modulus. - * This is the upper bound of the output range, exclusive. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was - * unable to find a suitable value within a limited number - * of attempts. This has a negligible probability if \p N - * is significantly larger than \p min, which is the case - * for all usual cryptographic applications. - */ -int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X, - mbedtls_mpi_uint min, - const mbedtls_mpi_mod_modulus *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - -/** Read a residue from a byte buffer. - * - * The residue will be automatically converted to the internal representation - * based on the value of the `N->int_rep` field. - * - * The modulus \p N will be the modulus associated with \p r. The residue \p r - * should only be used in operations where the modulus is \p N or a modulus - * equivalent to \p N (in the sense that all their fields or memory pointed by - * their fields hold the same value). - * - * \param[out] r The address of the residue. It must have exactly the same - * number of limbs as the modulus \p N. - * \param[in] N The address of the modulus. - * \param[in] buf The input buffer to import from. - * \param buflen The length in bytes of \p buf. - * \param ext_rep The endianness of the number in the input buffer. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p r isn't - * large enough to hold the value in \p buf. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep - * is invalid or the value in the buffer is not less than \p N. - */ -int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - const unsigned char *buf, - size_t buflen, - mbedtls_mpi_mod_ext_rep ext_rep); - -/** Write a residue into a byte buffer. - * - * The modulus \p N must be the modulus associated with \p r (see - * mbedtls_mpi_mod_residue_setup() and mbedtls_mpi_mod_read()). - * - * The residue will be automatically converted from the internal representation - * based on the value of `N->int_rep` field. - * - * \warning If the buffer is smaller than `N->bits`, the number of - * leading zeroes is leaked through timing. If \p r is - * secret, the caller must ensure that \p buflen is at least - * (`N->bits`+7)/8. - * - * \param[in] r The address of the residue. It must have the same number of - * limbs as the modulus \p N. (\p r is an input parameter, but - * its value will be modified during execution and restored - * before the function returns.) - * \param[in] N The address of the modulus associated with \p r. - * \param[out] buf The output buffer to export to. - * \param buflen The length in bytes of \p buf. - * \param ext_rep The endianness in which the number should be written into - * the output buffer. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't - * large enough to hold the value of \p r (without leading - * zeroes). - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep is invalid. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if couldn't allocate enough - * memory for conversion. Can occur only for moduli with - * MBEDTLS_MPI_MOD_REP_MONTGOMERY. - */ -int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r, - const mbedtls_mpi_mod_modulus *N, - unsigned char *buf, - size_t buflen, - mbedtls_mpi_mod_ext_rep ext_rep); - -#endif /* MBEDTLS_BIGNUM_MOD_H */ diff --git a/vendor/mbedtls/library/bignum_mod_raw.c b/vendor/mbedtls/library/bignum_mod_raw.c deleted file mode 100644 index 5343bc650..000000000 --- a/vendor/mbedtls/library/bignum_mod_raw.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Low-level modular bignum functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT) - -#include - -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" - -#include "mbedtls/platform.h" - -#include "bignum_core.h" -#include "bignum_mod_raw.h" -#include "bignum_mod.h" -#include "constant_time_internal.h" - -#include "bignum_mod_raw_invasive.h" - -void mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_mod_modulus *N, - unsigned char assign) -{ - mbedtls_mpi_core_cond_assign(X, A, N->limbs, mbedtls_ct_bool(assign)); -} - -void mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint *X, - mbedtls_mpi_uint *Y, - const mbedtls_mpi_mod_modulus *N, - unsigned char swap) -{ - mbedtls_mpi_core_cond_swap(X, Y, N->limbs, mbedtls_ct_bool(swap)); -} - -int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N, - const unsigned char *input, - size_t input_length, - mbedtls_mpi_mod_ext_rep ext_rep) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - switch (ext_rep) { - case MBEDTLS_MPI_MOD_EXT_REP_LE: - ret = mbedtls_mpi_core_read_le(X, N->limbs, - input, input_length); - break; - case MBEDTLS_MPI_MOD_EXT_REP_BE: - ret = mbedtls_mpi_core_read_be(X, N->limbs, - input, input_length); - break; - default: - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (ret != 0) { - goto cleanup; - } - - if (!mbedtls_mpi_core_lt_ct(X, N->p, N->limbs)) { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - -cleanup: - - return ret; -} - -int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A, - const mbedtls_mpi_mod_modulus *N, - unsigned char *output, - size_t output_length, - mbedtls_mpi_mod_ext_rep ext_rep) -{ - switch (ext_rep) { - case MBEDTLS_MPI_MOD_EXT_REP_LE: - return mbedtls_mpi_core_write_le(A, N->limbs, - output, output_length); - case MBEDTLS_MPI_MOD_EXT_REP_BE: - return mbedtls_mpi_core_write_be(A, N->limbs, - output, output_length); - default: - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } -} - -void mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - const mbedtls_mpi_mod_modulus *N) -{ - mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, A, B, N->limbs); - - (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c); -} - -MBEDTLS_STATIC_TESTABLE -void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N) -{ - mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N->p, N->limbs); - - (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c); -} - - -void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *T) -{ - /* Standard (A * B) multiplication stored into pre-allocated T - * buffer of fixed limb size of (2N + 1). - * - * The space may not not fully filled by when - * MBEDTLS_MPI_MOD_REP_OPT_RED is used. */ - const size_t T_limbs = BITS_TO_LIMBS(N->bits) * 2; - switch (N->int_rep) { - case MBEDTLS_MPI_MOD_REP_MONTGOMERY: - mbedtls_mpi_core_montmul(X, A, B, N->limbs, N->p, N->limbs, - N->rep.mont.mm, T); - break; - case MBEDTLS_MPI_MOD_REP_OPT_RED: - mbedtls_mpi_core_mul(T, A, N->limbs, B, N->limbs); - - /* Optimised Reduction */ - (*N->rep.ored.modp)(T, T_limbs); - - /* Convert back to canonical representation */ - mbedtls_mpi_mod_raw_fix_quasi_reduction(T, N); - memcpy(X, T, N->limbs * sizeof(mbedtls_mpi_uint)); - break; - default: - break; - } - -} - -size_t mbedtls_mpi_mod_raw_inv_prime_working_limbs(size_t AN_limbs) -{ - /* mbedtls_mpi_mod_raw_inv_prime() needs a temporary for the exponent, - * which will be the same size as the modulus and input (AN_limbs), - * and additional space to pass to mbedtls_mpi_core_exp_mod(). */ - return AN_limbs + - mbedtls_mpi_core_exp_mod_working_limbs(AN_limbs, AN_limbs); -} - -void mbedtls_mpi_mod_raw_inv_prime(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T) -{ - /* Inversion by power: g^|G| = 1 => g^(-1) = g^(|G|-1), and - * |G| = N - 1, so we want - * g^(|G|-1) = g^(N - 2) - */ - - /* Use the first AN_limbs of T to hold N - 2 */ - mbedtls_mpi_uint *Nminus2 = T; - (void) mbedtls_mpi_core_sub_int(Nminus2, N, 2, AN_limbs); - - /* Rest of T is given to exp_mod for its working space */ - mbedtls_mpi_core_exp_mod(X, - A, N, AN_limbs, Nminus2, AN_limbs, - RR, T + AN_limbs); -} - -void mbedtls_mpi_mod_raw_add(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - const mbedtls_mpi_mod_modulus *N) -{ - mbedtls_mpi_uint carry, borrow; - carry = mbedtls_mpi_core_add(X, A, B, N->limbs); - borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs); - (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) (carry ^ borrow)); -} - -int mbedtls_mpi_mod_raw_canonical_to_modulus_rep( - mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N) -{ - switch (N->int_rep) { - case MBEDTLS_MPI_MOD_REP_MONTGOMERY: - return mbedtls_mpi_mod_raw_to_mont_rep(X, N); - case MBEDTLS_MPI_MOD_REP_OPT_RED: - return 0; - default: - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } -} - -int mbedtls_mpi_mod_raw_modulus_to_canonical_rep( - mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N) -{ - switch (N->int_rep) { - case MBEDTLS_MPI_MOD_REP_MONTGOMERY: - return mbedtls_mpi_mod_raw_from_mont_rep(X, N); - case MBEDTLS_MPI_MOD_REP_OPT_RED: - return 0; - default: - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } -} - -int mbedtls_mpi_mod_raw_random(mbedtls_mpi_uint *X, - mbedtls_mpi_uint min, - const mbedtls_mpi_mod_modulus *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = mbedtls_mpi_core_random(X, min, N->p, N->limbs, f_rng, p_rng); - if (ret != 0) { - return ret; - } - return mbedtls_mpi_mod_raw_canonical_to_modulus_rep(X, N); -} - -int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N) -{ - mbedtls_mpi_uint *T; - const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs); - - if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - mbedtls_mpi_core_to_mont_rep(X, X, N->p, N->limbs, - N->rep.mont.mm, N->rep.mont.rr, T); - - mbedtls_zeroize_and_free(T, t_limbs * ciL); - return 0; -} - -int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N) -{ - const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs); - mbedtls_mpi_uint *T; - - if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - mbedtls_mpi_core_from_mont_rep(X, X, N->p, N->limbs, N->rep.mont.mm, T); - - mbedtls_zeroize_and_free(T, t_limbs * ciL); - return 0; -} - -void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_mod_modulus *N) -{ - mbedtls_mpi_core_sub(X, N->p, A, N->limbs); - - /* If A=0 initially, then X=N now. Detect this by - * subtracting N and catching the carry. */ - mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs); - (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) borrow); -} - -#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */ diff --git a/vendor/mbedtls/library/bignum_mod_raw.h b/vendor/mbedtls/library/bignum_mod_raw.h deleted file mode 100644 index 7bb4ca3cf..000000000 --- a/vendor/mbedtls/library/bignum_mod_raw.h +++ /dev/null @@ -1,416 +0,0 @@ -/** - * Low-level modular bignum functions - * - * This interface should only be used by the higher-level modular bignum - * module (bignum_mod.c) and the ECP module (ecp.c, ecp_curves.c). All other - * modules should use the high-level modular bignum interface (bignum_mod.h) - * or the legacy bignum interface (bignum.h). - * - * This is a low-level interface to operations on integers modulo which - * has no protection against passing invalid arguments such as arrays of - * the wrong size. The functions in bignum_mod.h provide a higher-level - * interface that includes protections against accidental misuse, at the - * expense of code size and sometimes more cumbersome memory management. - * - * The functions in this module obey the following conventions unless - * explicitly indicated otherwise: - * - **Modulus parameters**: the modulus is passed as a pointer to a structure - * of type #mbedtls_mpi_mod_modulus. The structure must be set up with an - * array of limbs storing the bignum value of the modulus. The modulus must - * be odd and is assumed to have no leading zeroes. The modulus is usually - * named \c N and is usually input-only. - * - **Bignum parameters**: Bignums are passed as pointers to an array of - * limbs. A limb has the type #mbedtls_mpi_uint. Unless otherwise specified: - * - Bignum parameters called \c A, \c B, ... are inputs, and are not - * modified by the function. - * - Bignum parameters called \c X, \c Y are outputs or input-output. - * The initial content of output-only parameters is ignored. - * - \c T is a temporary storage area. The initial content of such a - * parameter is ignored and the final content is unspecified. - * - **Bignum sizes**: bignum sizes are usually expressed by the \c limbs - * member of the modulus argument. All bignum parameters must have the same - * number of limbs as the modulus. All bignum sizes must be at least 1 and - * must be significantly less than #SIZE_MAX. The behavior if a size is 0 is - * undefined. - * - **Bignum representation**: the representation of inputs and outputs is - * specified by the \c int_rep field of the modulus for arithmetic - * functions. Utility functions may allow for different representation. - * - **Parameter ordering**: for bignum parameters, outputs come before inputs. - * The modulus is passed after other bignum input parameters. Temporaries - * come last. - * - **Aliasing**: in general, output bignums may be aliased to one or more - * inputs. Modulus values may not be aliased to any other parameter. Outputs - * may not be aliased to one another. Temporaries may not be aliased to any - * other parameter. - * - **Overlap**: apart from aliasing of limb array pointers (where two - * arguments are equal pointers), overlap is not supported and may result - * in undefined behavior. - * - **Error handling**: This is a low-level module. Functions generally do not - * try to protect against invalid arguments such as nonsensical sizes or - * null pointers. Note that passing bignums with a different size than the - * modulus may lead to buffer overflows. Some functions which allocate - * memory or handle reading/writing of bignums will return an error if - * memory allocation fails or if buffer sizes are invalid. - * - **Modular representatives**: all functions expect inputs to be in the - * range [0, \c N - 1] and guarantee outputs in the range [0, \c N - 1]. If - * an input is out of range, outputs are fully unspecified, though bignum - * values out of range should not cause buffer overflows (beware that this is - * not extensively tested). - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_BIGNUM_MOD_RAW_H -#define MBEDTLS_BIGNUM_MOD_RAW_H - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -#include "bignum_mod.h" - -/** - * \brief Perform a safe conditional copy of an MPI which doesn't reveal - * whether the assignment was done or not. - * - * The size to copy is determined by \p N. - * - * \param[out] X The address of the destination MPI. - * This must be initialized. Must have enough limbs to - * store the full value of \p A. - * \param[in] A The address of the source MPI. This must be initialized. - * \param[in] N The address of the modulus related to \p X and \p A. - * \param assign The condition deciding whether to perform the - * assignment or not. Must be either 0 or 1: - * * \c 1: Perform the assignment `X = A`. - * * \c 0: Keep the original value of \p X. - * - * \note This function avoids leaking any information about whether - * the assignment was done or not. - * - * \warning If \p assign is neither 0 nor 1, the result of this function - * is indeterminate, and the resulting value in \p X might be - * neither its original value nor the value in \p A. - */ -void mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_mod_modulus *N, - unsigned char assign); - -/** - * \brief Perform a safe conditional swap of two MPIs which doesn't reveal - * whether the swap was done or not. - * - * The size to swap is determined by \p N. - * - * \param[in,out] X The address of the first MPI. This must be initialized. - * \param[in,out] Y The address of the second MPI. This must be initialized. - * \param[in] N The address of the modulus related to \p X and \p Y. - * \param swap The condition deciding whether to perform - * the swap or not. Must be either 0 or 1: - * * \c 1: Swap the values of \p X and \p Y. - * * \c 0: Keep the original values of \p X and \p Y. - * - * \note This function avoids leaking any information about whether - * the swap was done or not. - * - * \warning If \p swap is neither 0 nor 1, the result of this function - * is indeterminate, and both \p X and \p Y might end up with - * values different to either of the original ones. - */ -void mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint *X, - mbedtls_mpi_uint *Y, - const mbedtls_mpi_mod_modulus *N, - unsigned char swap); - -/** Import X from unsigned binary data. - * - * The MPI needs to have enough limbs to store the full value (including any - * most significant zero bytes in the input). - * - * \param[out] X The address of the MPI. The size is determined by \p N. - * (In particular, it must have at least as many limbs as - * the modulus \p N.) - * \param[in] N The address of the modulus related to \p X. - * \param[in] input The input buffer to import from. - * \param input_length The length in bytes of \p input. - * \param ext_rep The endianness of the number in the input buffer. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't - * large enough to hold the value in \p input. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation - * of \p N is invalid or \p X is not less than \p N. - */ -int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N, - const unsigned char *input, - size_t input_length, - mbedtls_mpi_mod_ext_rep ext_rep); - -/** Export A into unsigned binary data. - * - * \param[in] A The address of the MPI. The size is determined by \p N. - * (In particular, it must have at least as many limbs as - * the modulus \p N.) - * \param[in] N The address of the modulus related to \p A. - * \param[out] output The output buffer to export to. - * \param output_length The length in bytes of \p output. - * \param ext_rep The endianness in which the number should be written into the output buffer. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't - * large enough to hold the value of \p A. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation - * of \p N is invalid. - */ -int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A, - const mbedtls_mpi_mod_modulus *N, - unsigned char *output, - size_t output_length, - mbedtls_mpi_mod_ext_rep ext_rep); - -/** \brief Subtract two MPIs, returning the residue modulo the specified - * modulus. - * - * The size of the operation is determined by \p N. \p A and \p B must have - * the same number of limbs as \p N. - * - * \p X may be aliased to \p A or \p B, or even both, but may not overlap - * either otherwise. - * - * \param[out] X The address of the result MPI. - * This must be initialized. Must have enough limbs to - * store the full value of the result. - * \param[in] A The address of the first MPI. This must be initialized. - * \param[in] B The address of the second MPI. This must be initialized. - * \param[in] N The address of the modulus. Used to perform a modulo - * operation on the result of the subtraction. - */ -void mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - const mbedtls_mpi_mod_modulus *N); - -/** \brief Multiply two MPIs, returning the residue modulo the specified - * modulus. - * - * \note Currently handles the case when `N->int_rep` is - * MBEDTLS_MPI_MOD_REP_MONTGOMERY. - * - * The size of the operation is determined by \p N. \p A, \p B and \p X must - * all be associated with the modulus \p N and must all have the same number - * of limbs as \p N. - * - * \p X may be aliased to \p A or \p B, or even both, but may not overlap - * either otherwise. They may not alias \p N (since they must be in canonical - * form, they cannot == \p N). - * - * \param[out] X The address of the result MPI. Must have the same - * number of limbs as \p N. - * On successful completion, \p X contains the result of - * the multiplication `A * B * R^-1` mod N where - * `R = 2^(biL * N->limbs)`. - * \param[in] A The address of the first MPI. - * \param[in] B The address of the second MPI. - * \param[in] N The address of the modulus. Used to perform a modulo - * operation on the result of the multiplication. - * \param[in,out] T Temporary storage of size at least 2 * N->limbs + 1 - * limbs. Its initial content is unused and - * its final content is indeterminate. - * It must not alias or otherwise overlap any of the - * other parameters. - */ -void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - const mbedtls_mpi_mod_modulus *N, - mbedtls_mpi_uint *T); - -/** - * \brief Returns the number of limbs of working memory required for - * a call to `mbedtls_mpi_mod_raw_inv_prime()`. - * - * \note This will always be at least - * `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)`, - * i.e. sufficient for a call to `mbedtls_mpi_core_montmul()`. - * - * \param AN_limbs The number of limbs in the input `A` and the modulus `N` - * (they must be the same size) that will be given to - * `mbedtls_mpi_mod_raw_inv_prime()`. - * - * \return The number of limbs of working memory required by - * `mbedtls_mpi_mod_raw_inv_prime()`. - */ -size_t mbedtls_mpi_mod_raw_inv_prime_working_limbs(size_t AN_limbs); - -/** - * \brief Perform fixed-width modular inversion of a Montgomery-form MPI with - * respect to a modulus \p N that must be prime. - * - * \p X may be aliased to \p A, but not to \p N or \p RR. - * - * \param[out] X The modular inverse of \p A with respect to \p N. - * Will be in Montgomery form. - * \param[in] A The number to calculate the modular inverse of. - * Must be in Montgomery form. Must not be 0. - * \param[in] N The modulus, as a little-endian array of length \p AN_limbs. - * Must be prime. - * \param AN_limbs The number of limbs in \p A, \p N and \p RR. - * \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little- - * endian array of length \p AN_limbs. - * \param[in,out] T Temporary storage of at least the number of limbs returned - * by `mbedtls_mpi_mod_raw_inv_prime_working_limbs()`. - * Its initial content is unused and its final content is - * indeterminate. - * It must not alias or otherwise overlap any of the other - * parameters. - * It is up to the caller to zeroize \p T when it is no - * longer needed, and before freeing it if it was dynamically - * allocated. - */ -void mbedtls_mpi_mod_raw_inv_prime(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *N, - size_t AN_limbs, - const mbedtls_mpi_uint *RR, - mbedtls_mpi_uint *T); - -/** - * \brief Perform a known-size modular addition. - * - * Calculate `A + B modulo N`. - * - * The number of limbs in each operand, and the result, is given by the - * modulus \p N. - * - * \p X may be aliased to \p A or \p B, or even both, but may not overlap - * either otherwise. - * - * \param[out] X The result of the modular addition. - * \param[in] A Little-endian presentation of the left operand. This - * must be smaller than \p N. - * \param[in] B Little-endian presentation of the right operand. This - * must be smaller than \p N. - * \param[in] N The address of the modulus. - */ -void mbedtls_mpi_mod_raw_add(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_uint *B, - const mbedtls_mpi_mod_modulus *N); - -/** Convert an MPI from canonical representation (little-endian limb array) - * to the representation associated with the modulus. - * - * \param[in,out] X The limb array to convert. - * It must have as many limbs as \p N. - * It is converted in place. - * If this function returns an error, the content of \p X - * is unspecified. - * \param[in] N The modulus structure. - * - * \return \c 0 if successful. - * Otherwise an \c MBEDTLS_ERR_MPI_xxx error code. - */ -int mbedtls_mpi_mod_raw_canonical_to_modulus_rep( - mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N); - -/** Convert an MPI from the representation associated with the modulus - * to canonical representation (little-endian limb array). - * - * \param[in,out] X The limb array to convert. - * It must have as many limbs as \p N. - * It is converted in place. - * If this function returns an error, the content of \p X - * is unspecified. - * \param[in] N The modulus structure. - * - * \return \c 0 if successful. - * Otherwise an \c MBEDTLS_ERR_MPI_xxx error code. - */ -int mbedtls_mpi_mod_raw_modulus_to_canonical_rep( - mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N); - -/** Generate a random number uniformly in a range. - * - * This function generates a random number between \p min inclusive and - * \p N exclusive. - * - * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA) - * when the RNG is a suitably parametrized instance of HMAC_DRBG - * and \p min is \c 1. - * - * \note There are `N - min` possible outputs. The lower bound - * \p min can be reached, but the upper bound \p N cannot. - * - * \param X The destination MPI, in canonical representation modulo \p N. - * It must not be aliased with \p N or otherwise overlap it. - * \param min The minimum value to return. It must be strictly smaller - * than \b N. - * \param N The modulus. - * This is the upper bound of the output range, exclusive. - * \param f_rng The RNG function to use. This must not be \c NULL. - * \param p_rng The RNG parameter to be passed to \p f_rng. - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was - * unable to find a suitable value within a limited number - * of attempts. This has a negligible probability if \p N - * is significantly larger than \p min, which is the case - * for all usual cryptographic applications. - */ -int mbedtls_mpi_mod_raw_random(mbedtls_mpi_uint *X, - mbedtls_mpi_uint min, - const mbedtls_mpi_mod_modulus *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - -/** Convert an MPI into Montgomery form. - * - * \param X The address of the MPI. - * Must have the same number of limbs as \p N. - * \param N The address of the modulus, which gives the size of - * the base `R` = 2^(biL*N->limbs). - * - * \return \c 0 if successful. - */ -int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N); - -/** Convert an MPI back from Montgomery representation. - * - * \param X The address of the MPI. - * Must have the same number of limbs as \p N. - * \param N The address of the modulus, which gives the size of - * the base `R`= 2^(biL*N->limbs). - * - * \return \c 0 if successful. - */ -int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N); - -/** \brief Perform fixed width modular negation. - * - * The size of the operation is determined by \p N. \p A must have - * the same number of limbs as \p N. - * - * \p X may be aliased to \p A. - * - * \param[out] X The result of the modular negation. - * This must be initialized. - * \param[in] A Little-endian presentation of the input operand. This - * must be less than or equal to \p N. - * \param[in] N The modulus to use. - */ -void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X, - const mbedtls_mpi_uint *A, - const mbedtls_mpi_mod_modulus *N); - -#endif /* MBEDTLS_BIGNUM_MOD_RAW_H */ diff --git a/vendor/mbedtls/library/bignum_mod_raw_invasive.h b/vendor/mbedtls/library/bignum_mod_raw_invasive.h deleted file mode 100644 index 94a0d06cf..000000000 --- a/vendor/mbedtls/library/bignum_mod_raw_invasive.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * \file bignum_mod_raw_invasive.h - * - * \brief Function declarations for invasive functions of Low-level - * modular bignum. - */ -/** - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H -#define MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H - -#include "common.h" -#include "mbedtls/bignum.h" -#include "bignum_mod.h" - -#if defined(MBEDTLS_TEST_HOOKS) - -/** Convert the result of a quasi-reduction to its canonical representative. - * - * \param[in,out] X The address of the MPI to be converted. Must have the - * same number of limbs as \p N. The input value must - * be in range 0 <= X < 2N. - * \param[in] N The address of the modulus. - */ -MBEDTLS_STATIC_TESTABLE -void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X, - const mbedtls_mpi_mod_modulus *N); - -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H */ diff --git a/vendor/mbedtls/library/block_cipher.c b/vendor/mbedtls/library/block_cipher.c deleted file mode 100644 index 51cdcdf46..000000000 --- a/vendor/mbedtls/library/block_cipher.c +++ /dev/null @@ -1,207 +0,0 @@ -/** - * \file block_cipher.c - * - * \brief Lightweight abstraction layer for block ciphers with 128 bit blocks, - * for use by the GCM and CCM modules. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -#include "psa/crypto.h" -#include "psa_crypto_core.h" -#include "psa_util_internal.h" -#endif - -#include "block_cipher_internal.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id) -{ - switch (cipher_id) { -#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - return PSA_KEY_TYPE_AES; -#endif -#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - return PSA_KEY_TYPE_ARIA; -#endif -#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - return PSA_KEY_TYPE_CAMELLIA; -#endif - default: - return PSA_KEY_TYPE_NONE; - } -} - -static int mbedtls_cipher_error_from_psa(psa_status_t status) -{ - return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors, - psa_generic_status_to_mbedtls); -} -#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ - -void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { - psa_destroy_key(ctx->psa_key_id); - return; - } -#endif - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - mbedtls_aes_free(&ctx->ctx.aes); - break; -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - mbedtls_aria_free(&ctx->ctx.aria); - break; -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - mbedtls_camellia_free(&ctx->ctx.camellia); - break; -#endif - default: - break; - } - ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; -} - -int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, - mbedtls_cipher_id_t cipher_id) -{ - ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES : - (cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA : - (cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA : - MBEDTLS_BLOCK_CIPHER_ID_NONE; - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id); - if (psa_key_type != PSA_KEY_TYPE_NONE && - psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) { - ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA; - return 0; - } - ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY; -#endif - - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - mbedtls_aes_init(&ctx->ctx.aes); - return 0; -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - mbedtls_aria_init(&ctx->ctx.aria); - return 0; -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - mbedtls_camellia_init(&ctx->ctx.camellia); - return 0; -#endif - default: - ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE; - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } -} - -int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx, - const unsigned char *key, - unsigned key_bitlen) -{ -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; - - psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id)); - psa_set_key_bits(&key_attr, key_bitlen); - psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING); - psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT); - - status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id); - if (status != PSA_SUCCESS) { - return mbedtls_cipher_error_from_psa(status); - } - psa_reset_key_attributes(&key_attr); - - return 0; - } -#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ - - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen); -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen); -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen); -#endif - default: - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } -} - -int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx, - const unsigned char input[16], - unsigned char output[16]) -{ -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) - if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) { - psa_status_t status; - size_t olen; - - status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING, - input, 16, output, 16, &olen); - if (status != PSA_SUCCESS) { - return mbedtls_cipher_error_from_psa(status); - } - return 0; - } -#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */ - - switch (ctx->id) { -#if defined(MBEDTLS_AES_C) - case MBEDTLS_BLOCK_CIPHER_ID_AES: - return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT, - input, output); -#endif -#if defined(MBEDTLS_ARIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_ARIA: - return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output); -#endif -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA: - return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia, - MBEDTLS_CAMELLIA_ENCRYPT, - input, output); -#endif - default: - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } -} - -#endif /* MBEDTLS_BLOCK_CIPHER_C */ diff --git a/vendor/mbedtls/library/block_cipher_internal.h b/vendor/mbedtls/library/block_cipher_internal.h deleted file mode 100644 index c57338b75..000000000 --- a/vendor/mbedtls/library/block_cipher_internal.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * \file block_cipher_internal.h - * - * \brief Lightweight abstraction layer for block ciphers with 128 bit blocks, - * for use by the GCM and CCM modules. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_BLOCK_CIPHER_INTERNAL_H -#define MBEDTLS_BLOCK_CIPHER_INTERNAL_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/cipher.h" - -#include "mbedtls/block_cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Initialize the context. - * This must be the first API call before using the context. - * - * \param ctx The context to initialize. - */ -static inline void mbedtls_block_cipher_init(mbedtls_block_cipher_context_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -/** - * \brief Set the block cipher to use with this context. - * This must be called after mbedtls_block_cipher_init(). - * - * \param ctx The context to set up. - * \param cipher_id The identifier of the cipher to use. - * This must be either AES, ARIA or Camellia. - * Warning: this is a ::mbedtls_cipher_id_t, - * not a ::mbedtls_block_cipher_id_t! - * - * \retval \c 0 on success. - * \retval #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if \p cipher_id was - * invalid. - */ -int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx, - mbedtls_cipher_id_t cipher_id); - -/** - * \brief Set the key into the context. - * - * \param ctx The context to configure. - * \param key The buffer holding the key material. - * \param key_bitlen The size of the key in bits. - * - * \retval \c 0 on success. - * \retval #MBEDTLS_ERR_CIPHER_INVALID_CONTEXT if the context was not - * properly set up before calling this function. - * \retval One of #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH, - * #MBEDTLS_ERR_ARIA_BAD_INPUT_DATA, - * #MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA if \p key_bitlen is - * invalid. - */ -int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx, - const unsigned char *key, - unsigned key_bitlen); - -/** - * \brief Encrypt one block (16 bytes) with the configured key. - * - * \param ctx The context holding the key. - * \param input The buffer holding the input block. Must be 16 bytes. - * \param output The buffer to which the output block will be written. - * Must be writable and 16 bytes long. - * This must either not overlap with \p input, or be equal. - * - * \retval \c 0 on success. - * \retval #MBEDTLS_ERR_CIPHER_INVALID_CONTEXT if the context was not - * properly set up before calling this function. - * \retval Another negative value if encryption failed. - */ -int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx, - const unsigned char input[16], - unsigned char output[16]); -/** - * \brief Clear the context. - * - * \param ctx The context to clear. - */ -void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_BLOCK_CIPHER_INTERNAL_H */ diff --git a/vendor/mbedtls/library/bn_mul.h b/vendor/mbedtls/library/bn_mul.h deleted file mode 100644 index 0738469db..000000000 --- a/vendor/mbedtls/library/bn_mul.h +++ /dev/null @@ -1,1094 +0,0 @@ -/** - * \file bn_mul.h - * - * \brief Multi-precision integer library - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * Multiply source vector [s] with b, add result - * to destination vector [d] and set carry c. - * - * Currently supports: - * - * . IA-32 (386+) . AMD64 / EM64T - * . IA-32 (SSE2) . Motorola 68000 - * . PowerPC, 32-bit . MicroBlaze - * . PowerPC, 64-bit . TriCore - * . SPARC v8 . ARM v3+ - * . Alpha . MIPS32 - * . C, longlong . C, generic - */ -#ifndef MBEDTLS_BN_MUL_H -#define MBEDTLS_BN_MUL_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/bignum.h" - - -/* - * Conversion macros for embedded constants: - * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 - */ -#if defined(MBEDTLS_HAVE_INT32) - -#define MBEDTLS_BYTES_TO_T_UINT_4(a, b, c, d) \ - ((mbedtls_mpi_uint) (a) << 0) | \ - ((mbedtls_mpi_uint) (b) << 8) | \ - ((mbedtls_mpi_uint) (c) << 16) | \ - ((mbedtls_mpi_uint) (d) << 24) - -#define MBEDTLS_BYTES_TO_T_UINT_2(a, b) \ - MBEDTLS_BYTES_TO_T_UINT_4(a, b, 0, 0) - -#define MBEDTLS_BYTES_TO_T_UINT_8(a, b, c, d, e, f, g, h) \ - MBEDTLS_BYTES_TO_T_UINT_4(a, b, c, d), \ - MBEDTLS_BYTES_TO_T_UINT_4(e, f, g, h) - -#else /* 64-bits */ - -#define MBEDTLS_BYTES_TO_T_UINT_8(a, b, c, d, e, f, g, h) \ - ((mbedtls_mpi_uint) (a) << 0) | \ - ((mbedtls_mpi_uint) (b) << 8) | \ - ((mbedtls_mpi_uint) (c) << 16) | \ - ((mbedtls_mpi_uint) (d) << 24) | \ - ((mbedtls_mpi_uint) (e) << 32) | \ - ((mbedtls_mpi_uint) (f) << 40) | \ - ((mbedtls_mpi_uint) (g) << 48) | \ - ((mbedtls_mpi_uint) (h) << 56) - -#define MBEDTLS_BYTES_TO_T_UINT_4(a, b, c, d) \ - MBEDTLS_BYTES_TO_T_UINT_8(a, b, c, d, 0, 0, 0, 0) - -#define MBEDTLS_BYTES_TO_T_UINT_2(a, b) \ - MBEDTLS_BYTES_TO_T_UINT_8(a, b, 0, 0, 0, 0, 0, 0) - -#endif /* bits in mbedtls_mpi_uint */ - -/* *INDENT-OFF* */ -#if defined(MBEDTLS_HAVE_ASM) - -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(__GNUC__) && \ - ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) - -/* - * GCC < 5.0 treated the x86 ebx (which is used for the GOT) as a - * fixed reserved register when building as PIC, leading to errors - * like: bn_mul.h:46:13: error: PIC register clobbered by 'ebx' in 'asm' - * - * This is fixed by an improved register allocator in GCC 5+. From the - * release notes: - * Register allocation improvements: Reuse of the PIC hard register, - * instead of using a fixed register, was implemented on x86/x86-64 - * targets. This improves generated PIC code performance as more hard - * registers can be used. - */ -#if defined(__GNUC__) && __GNUC__ < 5 && defined(__PIC__) -#define MULADDC_CANNOT_USE_EBX -#endif - -/* - * Disable use of the i386 assembly code below if option -O0, to disable all - * compiler optimisations, is passed, detected with __OPTIMIZE__ - * This is done as the number of registers used in the assembly code doesn't - * work with the -O0 option. - */ -#if defined(__i386__) && defined(__OPTIMIZE__) && !defined(MULADDC_CANNOT_USE_EBX) - -#define MULADDC_X1_INIT \ - { mbedtls_mpi_uint t; \ - asm( \ - "movl %%ebx, %0 \n\t" \ - "movl %5, %%esi \n\t" \ - "movl %6, %%edi \n\t" \ - "movl %7, %%ecx \n\t" \ - "movl %8, %%ebx \n\t" - -#define MULADDC_X1_CORE \ - "lodsl \n\t" \ - "mull %%ebx \n\t" \ - "addl %%ecx, %%eax \n\t" \ - "adcl $0, %%edx \n\t" \ - "addl (%%edi), %%eax \n\t" \ - "adcl $0, %%edx \n\t" \ - "movl %%edx, %%ecx \n\t" \ - "stosl \n\t" - -#define MULADDC_X1_STOP \ - "movl %4, %%ebx \n\t" \ - "movl %%ecx, %1 \n\t" \ - "movl %%edi, %2 \n\t" \ - "movl %%esi, %3 \n\t" \ - : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ - : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ebx", "ecx", "edx", "esi", "edi" \ - ); } - -#if defined(MBEDTLS_HAVE_SSE2) - -#define MULADDC_X8_INIT MULADDC_X1_INIT - -#define MULADDC_X8_CORE \ - "movd %%ecx, %%mm1 \n\t" \ - "movd %%ebx, %%mm0 \n\t" \ - "movd (%%edi), %%mm3 \n\t" \ - "paddq %%mm3, %%mm1 \n\t" \ - "movd (%%esi), %%mm2 \n\t" \ - "pmuludq %%mm0, %%mm2 \n\t" \ - "movd 4(%%esi), %%mm4 \n\t" \ - "pmuludq %%mm0, %%mm4 \n\t" \ - "movd 8(%%esi), %%mm6 \n\t" \ - "pmuludq %%mm0, %%mm6 \n\t" \ - "movd 12(%%esi), %%mm7 \n\t" \ - "pmuludq %%mm0, %%mm7 \n\t" \ - "paddq %%mm2, %%mm1 \n\t" \ - "movd 4(%%edi), %%mm3 \n\t" \ - "paddq %%mm4, %%mm3 \n\t" \ - "movd 8(%%edi), %%mm5 \n\t" \ - "paddq %%mm6, %%mm5 \n\t" \ - "movd 12(%%edi), %%mm4 \n\t" \ - "paddq %%mm4, %%mm7 \n\t" \ - "movd %%mm1, (%%edi) \n\t" \ - "movd 16(%%esi), %%mm2 \n\t" \ - "pmuludq %%mm0, %%mm2 \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "movd 20(%%esi), %%mm4 \n\t" \ - "pmuludq %%mm0, %%mm4 \n\t" \ - "paddq %%mm3, %%mm1 \n\t" \ - "movd 24(%%esi), %%mm6 \n\t" \ - "pmuludq %%mm0, %%mm6 \n\t" \ - "movd %%mm1, 4(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "movd 28(%%esi), %%mm3 \n\t" \ - "pmuludq %%mm0, %%mm3 \n\t" \ - "paddq %%mm5, %%mm1 \n\t" \ - "movd 16(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm2 \n\t" \ - "movd %%mm1, 8(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm7, %%mm1 \n\t" \ - "movd 20(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm4 \n\t" \ - "movd %%mm1, 12(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm2, %%mm1 \n\t" \ - "movd 24(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm6 \n\t" \ - "movd %%mm1, 16(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm4, %%mm1 \n\t" \ - "movd 28(%%edi), %%mm5 \n\t" \ - "paddq %%mm5, %%mm3 \n\t" \ - "movd %%mm1, 20(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm6, %%mm1 \n\t" \ - "movd %%mm1, 24(%%edi) \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "paddq %%mm3, %%mm1 \n\t" \ - "movd %%mm1, 28(%%edi) \n\t" \ - "addl $32, %%edi \n\t" \ - "addl $32, %%esi \n\t" \ - "psrlq $32, %%mm1 \n\t" \ - "movd %%mm1, %%ecx \n\t" - -#define MULADDC_X8_STOP \ - "emms \n\t" \ - "movl %4, %%ebx \n\t" \ - "movl %%ecx, %1 \n\t" \ - "movl %%edi, %2 \n\t" \ - "movl %%esi, %3 \n\t" \ - : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ - : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ebx", "ecx", "edx", "esi", "edi" \ - ); } \ - -#endif /* SSE2 */ - -#endif /* i386 */ - -#if defined(__amd64__) || defined (__x86_64__) - -#define MULADDC_X1_INIT \ - asm( \ - "xorq %%r8, %%r8\n" - -#define MULADDC_X1_CORE \ - "movq (%%rsi), %%rax\n" \ - "mulq %%rbx\n" \ - "addq $8, %%rsi\n" \ - "addq %%rcx, %%rax\n" \ - "movq %%r8, %%rcx\n" \ - "adcq $0, %%rdx\n" \ - "nop \n" \ - "addq %%rax, (%%rdi)\n" \ - "adcq %%rdx, %%rcx\n" \ - "addq $8, %%rdi\n" - -#define MULADDC_X1_STOP \ - : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \ - : "b" (b), "m" (*(const uint64_t (*)[16]) s) \ - : "rax", "rdx", "r8" \ - ); - -#endif /* AMD64 */ - -// The following assembly code assumes that a pointer will fit in a 64-bit register -// (including ILP32 __aarch64__ ABIs such as on watchOS, hence the 2^32 - 1) -#if defined(__aarch64__) && (UINTPTR_MAX == 0xfffffffful || UINTPTR_MAX == 0xfffffffffffffffful) - -/* - * There are some issues around different compilers requiring different constraint - * syntax for updating pointers from assembly code (see notes for - * MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT in common.h), especially on aarch64_32 (aka ILP32). - * - * For this reason we cast the pointers to/from uintptr_t here. - */ -#define MULADDC_X1_INIT \ - do { uintptr_t muladdc_d = (uintptr_t) d, muladdc_s = (uintptr_t) s; asm( - -#define MULADDC_X1_CORE \ - "ldr x4, [%x2], #8 \n\t" \ - "ldr x5, [%x1] \n\t" \ - "mul x6, x4, %4 \n\t" \ - "umulh x7, x4, %4 \n\t" \ - "adds x5, x5, x6 \n\t" \ - "adc x7, x7, xzr \n\t" \ - "adds x5, x5, %0 \n\t" \ - "adc %0, x7, xzr \n\t" \ - "str x5, [%x1], #8 \n\t" - -#define MULADDC_X1_STOP \ - : "+r" (c), \ - "+r" (muladdc_d), \ - "+r" (muladdc_s), \ - "+m" (*(uint64_t (*)[16]) d) \ - : "r" (b), "m" (*(const uint64_t (*)[16]) s) \ - : "x4", "x5", "x6", "x7", "cc" \ - ); d = (mbedtls_mpi_uint *)muladdc_d; s = (mbedtls_mpi_uint *)muladdc_s; } while (0); - -#endif /* Aarch64 */ - -#if defined(__mc68020__) || defined(__mcpu32__) - -#define MULADDC_X1_INIT \ - asm( \ - "movl %3, %%a2 \n\t" \ - "movl %4, %%a3 \n\t" \ - "movl %5, %%d3 \n\t" \ - "movl %6, %%d2 \n\t" \ - "moveq #0, %%d0 \n\t" - -#define MULADDC_X1_CORE \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "moveq #0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "addxl %%d4, %%d3 \n\t" - -#define MULADDC_X1_STOP \ - "movl %%d3, %0 \n\t" \ - "movl %%a3, %1 \n\t" \ - "movl %%a2, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \ - ); - -#define MULADDC_X8_INIT MULADDC_X1_INIT - -#define MULADDC_X8_CORE \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d4:%%d1 \n\t" \ - "addxl %%d3, %%d1 \n\t" \ - "addxl %%d0, %%d4 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "movel %%a2@+, %%d1 \n\t" \ - "mulul %%d2, %%d3:%%d1 \n\t" \ - "addxl %%d4, %%d1 \n\t" \ - "addxl %%d0, %%d3 \n\t" \ - "addl %%d1, %%a3@+ \n\t" \ - "addxl %%d0, %%d3 \n\t" - -#define MULADDC_X8_STOP MULADDC_X1_STOP - -#endif /* MC68000 */ - -#if defined(__powerpc64__) || defined(__ppc64__) - -#if defined(__MACH__) && defined(__APPLE__) - -#define MULADDC_X1_INIT \ - asm( \ - "ld r3, %3 \n\t" \ - "ld r4, %4 \n\t" \ - "ld r5, %5 \n\t" \ - "ld r6, %6 \n\t" \ - "addi r3, r3, -8 \n\t" \ - "addi r4, r4, -8 \n\t" \ - "addic r5, r5, 0 \n\t" - -#define MULADDC_X1_CORE \ - "ldu r7, 8(r3) \n\t" \ - "mulld r8, r7, r6 \n\t" \ - "mulhdu r9, r7, r6 \n\t" \ - "adde r8, r8, r5 \n\t" \ - "ld r7, 8(r4) \n\t" \ - "addze r5, r9 \n\t" \ - "addc r8, r8, r7 \n\t" \ - "stdu r8, 8(r4) \n\t" - -#define MULADDC_X1_STOP \ - "addze r5, r5 \n\t" \ - "addi r4, r4, 8 \n\t" \ - "addi r3, r3, 8 \n\t" \ - "std r5, %0 \n\t" \ - "std r4, %1 \n\t" \ - "std r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - - -#else /* __MACH__ && __APPLE__ */ - -#define MULADDC_X1_INIT \ - asm( \ - "ld %%r3, %3 \n\t" \ - "ld %%r4, %4 \n\t" \ - "ld %%r5, %5 \n\t" \ - "ld %%r6, %6 \n\t" \ - "addi %%r3, %%r3, -8 \n\t" \ - "addi %%r4, %%r4, -8 \n\t" \ - "addic %%r5, %%r5, 0 \n\t" - -#define MULADDC_X1_CORE \ - "ldu %%r7, 8(%%r3) \n\t" \ - "mulld %%r8, %%r7, %%r6 \n\t" \ - "mulhdu %%r9, %%r7, %%r6 \n\t" \ - "adde %%r8, %%r8, %%r5 \n\t" \ - "ld %%r7, 8(%%r4) \n\t" \ - "addze %%r5, %%r9 \n\t" \ - "addc %%r8, %%r8, %%r7 \n\t" \ - "stdu %%r8, 8(%%r4) \n\t" - -#define MULADDC_X1_STOP \ - "addze %%r5, %%r5 \n\t" \ - "addi %%r4, %%r4, 8 \n\t" \ - "addi %%r3, %%r3, 8 \n\t" \ - "std %%r5, %0 \n\t" \ - "std %%r4, %1 \n\t" \ - "std %%r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - -#endif /* __MACH__ && __APPLE__ */ - -#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */ - -#if defined(__MACH__) && defined(__APPLE__) - -#define MULADDC_X1_INIT \ - asm( \ - "lwz r3, %3 \n\t" \ - "lwz r4, %4 \n\t" \ - "lwz r5, %5 \n\t" \ - "lwz r6, %6 \n\t" \ - "addi r3, r3, -4 \n\t" \ - "addi r4, r4, -4 \n\t" \ - "addic r5, r5, 0 \n\t" - -#define MULADDC_X1_CORE \ - "lwzu r7, 4(r3) \n\t" \ - "mullw r8, r7, r6 \n\t" \ - "mulhwu r9, r7, r6 \n\t" \ - "adde r8, r8, r5 \n\t" \ - "lwz r7, 4(r4) \n\t" \ - "addze r5, r9 \n\t" \ - "addc r8, r8, r7 \n\t" \ - "stwu r8, 4(r4) \n\t" - -#define MULADDC_X1_STOP \ - "addze r5, r5 \n\t" \ - "addi r4, r4, 4 \n\t" \ - "addi r3, r3, 4 \n\t" \ - "stw r5, %0 \n\t" \ - "stw r4, %1 \n\t" \ - "stw r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - -#else /* __MACH__ && __APPLE__ */ - -#define MULADDC_X1_INIT \ - asm( \ - "lwz %%r3, %3 \n\t" \ - "lwz %%r4, %4 \n\t" \ - "lwz %%r5, %5 \n\t" \ - "lwz %%r6, %6 \n\t" \ - "addi %%r3, %%r3, -4 \n\t" \ - "addi %%r4, %%r4, -4 \n\t" \ - "addic %%r5, %%r5, 0 \n\t" - -#define MULADDC_X1_CORE \ - "lwzu %%r7, 4(%%r3) \n\t" \ - "mullw %%r8, %%r7, %%r6 \n\t" \ - "mulhwu %%r9, %%r7, %%r6 \n\t" \ - "adde %%r8, %%r8, %%r5 \n\t" \ - "lwz %%r7, 4(%%r4) \n\t" \ - "addze %%r5, %%r9 \n\t" \ - "addc %%r8, %%r8, %%r7 \n\t" \ - "stwu %%r8, 4(%%r4) \n\t" - -#define MULADDC_X1_STOP \ - "addze %%r5, %%r5 \n\t" \ - "addi %%r4, %%r4, 4 \n\t" \ - "addi %%r3, %%r3, 4 \n\t" \ - "stw %%r5, %0 \n\t" \ - "stw %%r4, %1 \n\t" \ - "stw %%r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ - ); - -#endif /* __MACH__ && __APPLE__ */ - -#endif /* PPC32 */ - -/* - * The Sparc(64) assembly is reported to be broken. - * Disable it for now, until we're able to fix it. - */ -#if 0 && defined(__sparc__) -#if defined(__sparc64__) - -#define MULADDC_X1_INIT \ - asm( \ - "ldx %3, %%o0 \n\t" \ - "ldx %4, %%o1 \n\t" \ - "ld %5, %%o2 \n\t" \ - "ld %6, %%o3 \n\t" - -#define MULADDC_X1_CORE \ - "ld [%%o0], %%o4 \n\t" \ - "inc 4, %%o0 \n\t" \ - "ld [%%o1], %%o5 \n\t" \ - "umul %%o3, %%o4, %%o4 \n\t" \ - "addcc %%o4, %%o2, %%o4 \n\t" \ - "rd %%y, %%g1 \n\t" \ - "addx %%g1, 0, %%g1 \n\t" \ - "addcc %%o4, %%o5, %%o4 \n\t" \ - "st %%o4, [%%o1] \n\t" \ - "addx %%g1, 0, %%o2 \n\t" \ - "inc 4, %%o1 \n\t" - -#define MULADDC_X1_STOP \ - "st %%o2, %0 \n\t" \ - "stx %%o1, %1 \n\t" \ - "stx %%o0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "g1", "o0", "o1", "o2", "o3", "o4", \ - "o5" \ - ); - -#else /* __sparc64__ */ - -#define MULADDC_X1_INIT \ - asm( \ - "ld %3, %%o0 \n\t" \ - "ld %4, %%o1 \n\t" \ - "ld %5, %%o2 \n\t" \ - "ld %6, %%o3 \n\t" - -#define MULADDC_X1_CORE \ - "ld [%%o0], %%o4 \n\t" \ - "inc 4, %%o0 \n\t" \ - "ld [%%o1], %%o5 \n\t" \ - "umul %%o3, %%o4, %%o4 \n\t" \ - "addcc %%o4, %%o2, %%o4 \n\t" \ - "rd %%y, %%g1 \n\t" \ - "addx %%g1, 0, %%g1 \n\t" \ - "addcc %%o4, %%o5, %%o4 \n\t" \ - "st %%o4, [%%o1] \n\t" \ - "addx %%g1, 0, %%o2 \n\t" \ - "inc 4, %%o1 \n\t" - -#define MULADDC_X1_STOP \ - "st %%o2, %0 \n\t" \ - "st %%o1, %1 \n\t" \ - "st %%o0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "g1", "o0", "o1", "o2", "o3", "o4", \ - "o5" \ - ); - -#endif /* __sparc64__ */ -#endif /* __sparc__ */ - -#if defined(__microblaze__) || defined(microblaze) - -#define MULADDC_X1_INIT \ - asm( \ - "lwi r3, %3 \n\t" \ - "lwi r4, %4 \n\t" \ - "lwi r5, %5 \n\t" \ - "lwi r6, %6 \n\t" \ - "andi r7, r6, 0xffff \n\t" \ - "bsrli r6, r6, 16 \n\t" - -#if(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define MULADDC_LHUI \ - "lhui r9, r3, 0 \n\t" \ - "addi r3, r3, 2 \n\t" \ - "lhui r8, r3, 0 \n\t" -#else -#define MULADDC_LHUI \ - "lhui r8, r3, 0 \n\t" \ - "addi r3, r3, 2 \n\t" \ - "lhui r9, r3, 0 \n\t" -#endif - -#define MULADDC_X1_CORE \ - MULADDC_LHUI \ - "addi r3, r3, 2 \n\t" \ - "mul r10, r9, r6 \n\t" \ - "mul r11, r8, r7 \n\t" \ - "mul r12, r9, r7 \n\t" \ - "mul r13, r8, r6 \n\t" \ - "bsrli r8, r10, 16 \n\t" \ - "bsrli r9, r11, 16 \n\t" \ - "add r13, r13, r8 \n\t" \ - "add r13, r13, r9 \n\t" \ - "bslli r10, r10, 16 \n\t" \ - "bslli r11, r11, 16 \n\t" \ - "add r12, r12, r10 \n\t" \ - "addc r13, r13, r0 \n\t" \ - "add r12, r12, r11 \n\t" \ - "addc r13, r13, r0 \n\t" \ - "lwi r10, r4, 0 \n\t" \ - "add r12, r12, r10 \n\t" \ - "addc r13, r13, r0 \n\t" \ - "add r12, r12, r5 \n\t" \ - "addc r5, r13, r0 \n\t" \ - "swi r12, r4, 0 \n\t" \ - "addi r4, r4, 4 \n\t" - -#define MULADDC_X1_STOP \ - "swi r5, %0 \n\t" \ - "swi r4, %1 \n\t" \ - "swi r3, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r3", "r4", "r5", "r6", "r7", "r8", \ - "r9", "r10", "r11", "r12", "r13" \ - ); - -#endif /* MicroBlaze */ - -#if defined(__tricore__) - -#define MULADDC_X1_INIT \ - asm( \ - "ld.a %%a2, %3 \n\t" \ - "ld.a %%a3, %4 \n\t" \ - "ld.w %%d4, %5 \n\t" \ - "ld.w %%d1, %6 \n\t" \ - "xor %%d5, %%d5 \n\t" - -#define MULADDC_X1_CORE \ - "ld.w %%d0, [%%a2+] \n\t" \ - "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \ - "ld.w %%d0, [%%a3] \n\t" \ - "addx %%d2, %%d2, %%d0 \n\t" \ - "addc %%d3, %%d3, 0 \n\t" \ - "mov %%d4, %%d3 \n\t" \ - "st.w [%%a3+], %%d2 \n\t" - -#define MULADDC_X1_STOP \ - "st.w %0, %%d4 \n\t" \ - "st.a %1, %%a3 \n\t" \ - "st.a %2, %%a2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "d0", "d1", "e2", "d4", "a2", "a3" \ - ); - -#endif /* TriCore */ - -#if defined(__arm__) - -#if defined(__thumb__) && !defined(__thumb2__) -#if defined(MBEDTLS_COMPILER_IS_GCC) -/* - * Thumb 1 ISA. This code path has only been tested successfully on gcc; - * it does not compile on clang or armclang. - */ - -#if !defined(__OPTIMIZE__) && defined(__GNUC__) -/* - * Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about - * our use of r7 below, unless -fomit-frame-pointer is passed. - * - * On the other hand, -fomit-frame-pointer is implied by any -Ox options with - * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by - * clang and armcc5 under the same conditions). - * - * If gcc needs to use r7, we use r1 as a scratch register and have a few extra - * instructions to preserve/restore it; otherwise, we can use r7 and avoid - * the preserve/restore overhead. - */ -#define MULADDC_SCRATCH "RS .req r1 \n\t" -#define MULADDC_PRESERVE_SCRATCH "mov r10, r1 \n\t" -#define MULADDC_RESTORE_SCRATCH "mov r1, r10 \n\t" -#define MULADDC_SCRATCH_CLOBBER "r10" -#else /* !defined(__OPTIMIZE__) && defined(__GNUC__) */ -#define MULADDC_SCRATCH "RS .req r7 \n\t" -#define MULADDC_PRESERVE_SCRATCH "" -#define MULADDC_RESTORE_SCRATCH "" -#define MULADDC_SCRATCH_CLOBBER "r7" -#endif /* !defined(__OPTIMIZE__) && defined(__GNUC__) */ - -#define MULADDC_X1_INIT \ - asm( \ - MULADDC_SCRATCH \ - "ldr r0, %3 \n\t" \ - "ldr r1, %4 \n\t" \ - "ldr r2, %5 \n\t" \ - "ldr r3, %6 \n\t" \ - "lsr r4, r3, #16 \n\t" \ - "mov r9, r4 \n\t" \ - "lsl r4, r3, #16 \n\t" \ - "lsr r4, r4, #16 \n\t" \ - "mov r8, r4 \n\t" \ - - -#define MULADDC_X1_CORE \ - MULADDC_PRESERVE_SCRATCH \ - "ldmia r0!, {r6} \n\t" \ - "lsr RS, r6, #16 \n\t" \ - "lsl r6, r6, #16 \n\t" \ - "lsr r6, r6, #16 \n\t" \ - "mov r4, r8 \n\t" \ - "mul r4, r6 \n\t" \ - "mov r3, r9 \n\t" \ - "mul r6, r3 \n\t" \ - "mov r5, r9 \n\t" \ - "mul r5, RS \n\t" \ - "mov r3, r8 \n\t" \ - "mul RS, r3 \n\t" \ - "lsr r3, r6, #16 \n\t" \ - "add r5, r5, r3 \n\t" \ - "lsr r3, RS, #16 \n\t" \ - "add r5, r5, r3 \n\t" \ - "add r4, r4, r2 \n\t" \ - "mov r2, #0 \n\t" \ - "adc r5, r2 \n\t" \ - "lsl r3, r6, #16 \n\t" \ - "add r4, r4, r3 \n\t" \ - "adc r5, r2 \n\t" \ - "lsl r3, RS, #16 \n\t" \ - "add r4, r4, r3 \n\t" \ - "adc r5, r2 \n\t" \ - MULADDC_RESTORE_SCRATCH \ - "ldr r3, [r1] \n\t" \ - "add r4, r4, r3 \n\t" \ - "adc r2, r5 \n\t" \ - "stmia r1!, {r4} \n\t" - -#define MULADDC_X1_STOP \ - "str r2, %0 \n\t" \ - "str r1, %1 \n\t" \ - "str r0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r0", "r1", "r2", "r3", "r4", "r5", \ - "r6", MULADDC_SCRATCH_CLOBBER, "r8", "r9", "cc" \ - ); -#endif /* !defined(__ARMCC_VERSION) && !defined(__clang__) */ - -#elif (__ARM_ARCH >= 6) && \ - defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1) -/* Armv6-M (or later) with DSP Instruction Set Extensions. - * Requires support for either Thumb 2 or Arm ISA. - */ - -#define MULADDC_X1_INIT \ - { \ - mbedtls_mpi_uint tmp_a, tmp_b; \ - asm volatile ( - -#define MULADDC_X1_CORE \ - ".p2align 2 \n\t" \ - "ldr %[a], [%[in]], #4 \n\t" \ - "ldr %[b], [%[acc]] \n\t" \ - "umaal %[b], %[carry], %[scalar], %[a] \n\t" \ - "str %[b], [%[acc]], #4 \n\t" - -#define MULADDC_X1_STOP \ - : [a] "=&r" (tmp_a), \ - [b] "=&r" (tmp_b), \ - [in] "+r" (s), \ - [acc] "+r" (d), \ - [carry] "+l" (c) \ - : [scalar] "r" (b) \ - : "memory" \ - ); \ - } - -#define MULADDC_X2_INIT \ - { \ - mbedtls_mpi_uint tmp_a0, tmp_b0; \ - mbedtls_mpi_uint tmp_a1, tmp_b1; \ - asm volatile ( - - /* - Make sure loop is 4-byte aligned to avoid stalls - * upon repeated non-word aligned instructions in - * some microarchitectures. - * - Don't use ldm with post-increment or back-to-back - * loads with post-increment and same address register - * to avoid stalls on some microarchitectures. - * - Bunch loads and stores to reduce latency on some - * microarchitectures. E.g., on Cortex-M4, the first - * in a series of load/store operations has latency - * 2 cycles, while subsequent loads/stores are single-cycle. */ -#define MULADDC_X2_CORE \ - ".p2align 2 \n\t" \ - "ldr %[a0], [%[in]], #+8 \n\t" \ - "ldr %[b0], [%[acc]], #+8 \n\t" \ - "ldr %[a1], [%[in], #-4] \n\t" \ - "ldr %[b1], [%[acc], #-4] \n\t" \ - "umaal %[b0], %[carry], %[scalar], %[a0] \n\t" \ - "umaal %[b1], %[carry], %[scalar], %[a1] \n\t" \ - "str %[b0], [%[acc], #-8] \n\t" \ - "str %[b1], [%[acc], #-4] \n\t" - -#define MULADDC_X2_STOP \ - : [a0] "=&r" (tmp_a0), \ - [b0] "=&r" (tmp_b0), \ - [a1] "=&r" (tmp_a1), \ - [b1] "=&r" (tmp_b1), \ - [in] "+r" (s), \ - [acc] "+r" (d), \ - [carry] "+l" (c) \ - : [scalar] "r" (b) \ - : "memory" \ - ); \ - } - -#else /* Thumb 2 or Arm ISA, without DSP extensions */ - -#define MULADDC_X1_INIT \ - asm( \ - "ldr r0, %3 \n\t" \ - "ldr r1, %4 \n\t" \ - "ldr r2, %5 \n\t" \ - "ldr r3, %6 \n\t" - -#define MULADDC_X1_CORE \ - "ldr r4, [r0], #4 \n\t" \ - "mov r5, #0 \n\t" \ - "ldr r6, [r1] \n\t" \ - "umlal r2, r5, r3, r4 \n\t" \ - "adds r4, r6, r2 \n\t" \ - "adc r2, r5, #0 \n\t" \ - "str r4, [r1], #4 \n\t" - -#define MULADDC_X1_STOP \ - "str r2, %0 \n\t" \ - "str r1, %1 \n\t" \ - "str r0, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "r0", "r1", "r2", "r3", "r4", "r5", \ - "r6", "cc" \ - ); - -#endif /* ISA codepath selection */ - -#endif /* defined(__arm__) */ - -#if defined(__alpha__) - -#define MULADDC_X1_INIT \ - asm( \ - "ldq $1, %3 \n\t" \ - "ldq $2, %4 \n\t" \ - "ldq $3, %5 \n\t" \ - "ldq $4, %6 \n\t" - -#define MULADDC_X1_CORE \ - "ldq $6, 0($1) \n\t" \ - "addq $1, 8, $1 \n\t" \ - "mulq $6, $4, $7 \n\t" \ - "umulh $6, $4, $6 \n\t" \ - "addq $7, $3, $7 \n\t" \ - "cmpult $7, $3, $3 \n\t" \ - "ldq $5, 0($2) \n\t" \ - "addq $7, $5, $7 \n\t" \ - "cmpult $7, $5, $5 \n\t" \ - "stq $7, 0($2) \n\t" \ - "addq $2, 8, $2 \n\t" \ - "addq $6, $3, $3 \n\t" \ - "addq $5, $3, $3 \n\t" - -#define MULADDC_X1_STOP \ - "stq $3, %0 \n\t" \ - "stq $2, %1 \n\t" \ - "stq $1, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \ - ); -#endif /* Alpha */ - -#if defined(__mips__) && !defined(__mips64) - -#define MULADDC_X1_INIT \ - asm( \ - "lw $10, %3 \n\t" \ - "lw $11, %4 \n\t" \ - "lw $12, %5 \n\t" \ - "lw $13, %6 \n\t" - -#define MULADDC_X1_CORE \ - "lw $14, 0($10) \n\t" \ - "multu $13, $14 \n\t" \ - "addi $10, $10, 4 \n\t" \ - "mflo $14 \n\t" \ - "mfhi $9 \n\t" \ - "addu $14, $12, $14 \n\t" \ - "lw $15, 0($11) \n\t" \ - "sltu $12, $14, $12 \n\t" \ - "addu $15, $14, $15 \n\t" \ - "sltu $14, $15, $14 \n\t" \ - "addu $12, $12, $9 \n\t" \ - "sw $15, 0($11) \n\t" \ - "addu $12, $12, $14 \n\t" \ - "addi $11, $11, 4 \n\t" - -#define MULADDC_X1_STOP \ - "sw $12, %0 \n\t" \ - "sw $11, %1 \n\t" \ - "sw $10, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \ - ); - -#endif /* MIPS */ -#endif /* GNUC */ - -#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) - -#define MULADDC_X1_INIT \ - __asm mov esi, s \ - __asm mov edi, d \ - __asm mov ecx, c \ - __asm mov ebx, b - -#define MULADDC_X1_CORE \ - __asm lodsd \ - __asm mul ebx \ - __asm add eax, ecx \ - __asm adc edx, 0 \ - __asm add eax, [edi] \ - __asm adc edx, 0 \ - __asm mov ecx, edx \ - __asm stosd - -#define MULADDC_X1_STOP \ - __asm mov c, ecx \ - __asm mov d, edi \ - __asm mov s, esi - -#if defined(MBEDTLS_HAVE_SSE2) - -#define EMIT __asm _emit - -#define MULADDC_X8_INIT MULADDC_X1_INIT - -#define MULADDC_X8_CORE \ - EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ - EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ - EMIT 0x0F EMIT 0x6E EMIT 0x1F \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x6E EMIT 0x16 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ - EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ - EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ - EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ - EMIT 0x0F EMIT 0x7E EMIT 0x0F \ - EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ - EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ - EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ - EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x7E EMIT 0xC9 - -#define MULADDC_X8_STOP \ - EMIT 0x0F EMIT 0x77 \ - __asm mov c, ecx \ - __asm mov d, edi \ - __asm mov s, esi - -#endif /* SSE2 */ -#endif /* MSVC */ - -#endif /* MBEDTLS_HAVE_ASM */ - -#if !defined(MULADDC_X1_CORE) -#if defined(MBEDTLS_HAVE_UDBL) - -#define MULADDC_X1_INIT \ -{ \ - mbedtls_t_udbl r; \ - mbedtls_mpi_uint r0, r1; - -#define MULADDC_X1_CORE \ - r = *(s++) * (mbedtls_t_udbl) b; \ - r0 = (mbedtls_mpi_uint) r; \ - r1 = (mbedtls_mpi_uint)( r >> biL ); \ - r0 += c; r1 += (r0 < c); \ - r0 += *d; r1 += (r0 < *d); \ - c = r1; *(d++) = r0; - -#define MULADDC_X1_STOP \ -} - -#else /* MBEDTLS_HAVE_UDBL */ - -#define MULADDC_X1_INIT \ -{ \ - mbedtls_mpi_uint s0, s1, b0, b1; \ - mbedtls_mpi_uint r0, r1, rx, ry; \ - b0 = ( b << biH ) >> biH; \ - b1 = ( b >> biH ); - -#define MULADDC_X1_CORE \ - s0 = ( *s << biH ) >> biH; \ - s1 = ( *s >> biH ); s++; \ - rx = s0 * b1; r0 = s0 * b0; \ - ry = s1 * b0; r1 = s1 * b1; \ - r1 += ( rx >> biH ); \ - r1 += ( ry >> biH ); \ - rx <<= biH; ry <<= biH; \ - r0 += rx; r1 += (r0 < rx); \ - r0 += ry; r1 += (r0 < ry); \ - r0 += c; r1 += (r0 < c); \ - r0 += *d; r1 += (r0 < *d); \ - c = r1; *(d++) = r0; - -#define MULADDC_X1_STOP \ -} - -#endif /* C (longlong) */ -#endif /* C (generic) */ - -#if !defined(MULADDC_X2_CORE) -#define MULADDC_X2_INIT MULADDC_X1_INIT -#define MULADDC_X2_STOP MULADDC_X1_STOP -#define MULADDC_X2_CORE MULADDC_X1_CORE MULADDC_X1_CORE -#endif /* MULADDC_X2_CORE */ - -#if !defined(MULADDC_X4_CORE) -#define MULADDC_X4_INIT MULADDC_X2_INIT -#define MULADDC_X4_STOP MULADDC_X2_STOP -#define MULADDC_X4_CORE MULADDC_X2_CORE MULADDC_X2_CORE -#endif /* MULADDC_X4_CORE */ - -#if !defined(MULADDC_X8_CORE) -#define MULADDC_X8_INIT MULADDC_X4_INIT -#define MULADDC_X8_STOP MULADDC_X4_STOP -#define MULADDC_X8_CORE MULADDC_X4_CORE MULADDC_X4_CORE -#endif /* MULADDC_X8_CORE */ - -/* *INDENT-ON* */ -#endif /* bn_mul.h */ diff --git a/vendor/mbedtls/library/camellia.c b/vendor/mbedtls/library/camellia.c deleted file mode 100644 index b1c0a08ca..000000000 --- a/vendor/mbedtls/library/camellia.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * Camellia implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The Camellia block cipher was designed by NTT and Mitsubishi Electric - * Corporation. - * - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_CAMELLIA_C) - -#include "mbedtls/camellia.h" -#include "mbedtls/platform_util.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_CAMELLIA_ALT) - -static const unsigned char SIGMA_CHARS[6][8] = -{ - { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b }, - { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 }, - { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe }, - { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c }, - { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d }, - { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd } -}; - -#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) - -static const unsigned char FSb[256] = -{ - 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, - 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, - 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, - 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, - 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, - 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, - 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, - 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, - 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, - 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, - 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, - 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, - 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, - 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, - 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, - 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 -}; - -#define SBOX1(n) FSb[(n)] -#define SBOX2(n) (unsigned char) ((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff) -#define SBOX3(n) (unsigned char) ((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff) -#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff] - -#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ - -static const unsigned char FSb[256] = -{ - 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, - 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, - 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, - 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, - 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, - 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, - 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, - 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, - 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, - 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, - 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, - 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, - 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, - 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, - 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, - 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 -}; - -static const unsigned char FSb2[256] = -{ - 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, - 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, - 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, - 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, - 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, - 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, - 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, - 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, - 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, - 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, - 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, - 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, - 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, - 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, - 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, - 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 -}; - -static const unsigned char FSb3[256] = -{ - 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, - 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, - 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, - 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, - 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, - 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, - 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, - 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, - 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, - 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, - 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, - 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, - 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, - 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, - 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, - 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 -}; - -static const unsigned char FSb4[256] = -{ - 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, - 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, - 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, - 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, - 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, - 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, - 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, - 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, - 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, - 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, - 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, - 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, - 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, - 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, - 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, - 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 -}; - -#define SBOX1(n) FSb[(n)] -#define SBOX2(n) FSb2[(n)] -#define SBOX3(n) FSb3[(n)] -#define SBOX4(n) FSb4[(n)] - -#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ - -static const unsigned char shifts[2][4][4] = -{ - { - { 1, 1, 1, 1 }, /* KL */ - { 0, 0, 0, 0 }, /* KR */ - { 1, 1, 1, 1 }, /* KA */ - { 0, 0, 0, 0 } /* KB */ - }, - { - { 1, 0, 1, 1 }, /* KL */ - { 1, 1, 0, 1 }, /* KR */ - { 1, 1, 1, 0 }, /* KA */ - { 1, 1, 0, 1 } /* KB */ - } -}; - -static const signed char indexes[2][4][20] = -{ - { - { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39, - 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */ - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */ - { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, - 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ - { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */ - }, - { - { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1, - -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */ - { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, - 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */ - { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, - 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */ - { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, - 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */ - } -}; - -static const signed char transposes[2][20] = -{ - { - 21, 22, 23, 20, - -1, -1, -1, -1, - 18, 19, 16, 17, - 11, 8, 9, 10, - 15, 12, 13, 14 - }, - { - 25, 26, 27, 24, - 29, 30, 31, 28, - 18, 19, 16, 17, - -1, -1, -1, -1, - -1, -1, -1, -1 - } -}; - -/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */ -#define ROTL(DEST, SRC, SHIFT) \ - { \ - (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \ - (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \ - (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \ - (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \ - } - -#define FL(XL, XR, KL, KR) \ - { \ - (XR) = ((((XL) &(KL)) << 1) | (((XL) &(KL)) >> 31)) ^ (XR); \ - (XL) = ((XR) | (KR)) ^ (XL); \ - } - -#define FLInv(YL, YR, KL, KR) \ - { \ - (YL) = ((YR) | (KR)) ^ (YL); \ - (YR) = ((((YL) &(KL)) << 1) | (((YL) &(KL)) >> 31)) ^ (YR); \ - } - -#define SHIFT_AND_PLACE(INDEX, OFFSET) \ - { \ - TK[0] = KC[(OFFSET) * 4 + 0]; \ - TK[1] = KC[(OFFSET) * 4 + 1]; \ - TK[2] = KC[(OFFSET) * 4 + 2]; \ - TK[3] = KC[(OFFSET) * 4 + 3]; \ - \ - for (i = 1; i <= 4; i++) \ - if (shifts[(INDEX)][(OFFSET)][i -1]) \ - ROTL(TK + i * 4, TK, (15 * i) % 32); \ - \ - for (i = 0; i < 20; i++) \ - if (indexes[(INDEX)][(OFFSET)][i] != -1) { \ - RK[indexes[(INDEX)][(OFFSET)][i]] = TK[i]; \ - } \ - } - -static void camellia_feistel(const uint32_t x[2], const uint32_t k[2], - uint32_t z[2]) -{ - uint32_t I0, I1; - I0 = x[0] ^ k[0]; - I1 = x[1] ^ k[1]; - - I0 = ((uint32_t) SBOX1(MBEDTLS_BYTE_3(I0)) << 24) | - ((uint32_t) SBOX2(MBEDTLS_BYTE_2(I0)) << 16) | - ((uint32_t) SBOX3(MBEDTLS_BYTE_1(I0)) << 8) | - ((uint32_t) SBOX4(MBEDTLS_BYTE_0(I0))); - I1 = ((uint32_t) SBOX2(MBEDTLS_BYTE_3(I1)) << 24) | - ((uint32_t) SBOX3(MBEDTLS_BYTE_2(I1)) << 16) | - ((uint32_t) SBOX4(MBEDTLS_BYTE_1(I1)) << 8) | - ((uint32_t) SBOX1(MBEDTLS_BYTE_0(I1))); - - I0 ^= (I1 << 8) | (I1 >> 24); - I1 ^= (I0 << 16) | (I0 >> 16); - I0 ^= (I1 >> 8) | (I1 << 24); - I1 ^= (I0 >> 8) | (I0 << 24); - - z[0] ^= I1; - z[1] ^= I0; -} - -void mbedtls_camellia_init(mbedtls_camellia_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_camellia_context)); -} - -void mbedtls_camellia_free(mbedtls_camellia_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_camellia_context)); -} - -/* - * Camellia key schedule (encryption) - */ -int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int idx; - size_t i; - uint32_t *RK; - unsigned char t[64]; - uint32_t SIGMA[6][2]; - uint32_t KC[16]; - uint32_t TK[20]; - - RK = ctx->rk; - - memset(t, 0, 64); - memset(RK, 0, sizeof(ctx->rk)); - - switch (keybits) { - case 128: ctx->nr = 3; idx = 0; break; - case 192: - case 256: ctx->nr = 4; idx = 1; break; - default: return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA; - } - - for (i = 0; i < keybits / 8; ++i) { - t[i] = key[i]; - } - - if (keybits == 192) { - for (i = 0; i < 8; i++) { - t[24 + i] = ~t[16 + i]; - } - } - - /* - * Prepare SIGMA values - */ - for (i = 0; i < 6; i++) { - SIGMA[i][0] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 0); - SIGMA[i][1] = MBEDTLS_GET_UINT32_BE(SIGMA_CHARS[i], 4); - } - - /* - * Key storage in KC - * Order: KL, KR, KA, KB - */ - memset(KC, 0, sizeof(KC)); - - /* Store KL, KR */ - for (i = 0; i < 8; i++) { - KC[i] = MBEDTLS_GET_UINT32_BE(t, i * 4); - } - - /* Generate KA */ - for (i = 0; i < 4; ++i) { - KC[8 + i] = KC[i] ^ KC[4 + i]; - } - - camellia_feistel(KC + 8, SIGMA[0], KC + 10); - camellia_feistel(KC + 10, SIGMA[1], KC + 8); - - for (i = 0; i < 4; ++i) { - KC[8 + i] ^= KC[i]; - } - - camellia_feistel(KC + 8, SIGMA[2], KC + 10); - camellia_feistel(KC + 10, SIGMA[3], KC + 8); - - if (keybits > 128) { - /* Generate KB */ - for (i = 0; i < 4; ++i) { - KC[12 + i] = KC[4 + i] ^ KC[8 + i]; - } - - camellia_feistel(KC + 12, SIGMA[4], KC + 14); - camellia_feistel(KC + 14, SIGMA[5], KC + 12); - } - - /* - * Generating subkeys - */ - - /* Manipulating KL */ - SHIFT_AND_PLACE(idx, 0); - - /* Manipulating KR */ - if (keybits > 128) { - SHIFT_AND_PLACE(idx, 1); - } - - /* Manipulating KA */ - SHIFT_AND_PLACE(idx, 2); - - /* Manipulating KB */ - if (keybits > 128) { - SHIFT_AND_PLACE(idx, 3); - } - - /* Do transpositions */ - for (i = 0; i < 20; i++) { - if (transposes[idx][i] != -1) { - RK[32 + 12 * idx + i] = RK[transposes[idx][i]]; - } - } - - return 0; -} - -/* - * Camellia key schedule (decryption) - */ -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx, - const unsigned char *key, - unsigned int keybits) -{ - int idx, ret; - size_t i; - mbedtls_camellia_context cty; - uint32_t *RK; - uint32_t *SK; - - mbedtls_camellia_init(&cty); - - /* Also checks keybits */ - if ((ret = mbedtls_camellia_setkey_enc(&cty, key, keybits)) != 0) { - goto exit; - } - - ctx->nr = cty.nr; - idx = (ctx->nr == 4); - - RK = ctx->rk; - SK = cty.rk + 24 * 2 + 8 * idx * 2; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for (i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4) { - *RK++ = *SK++; - *RK++ = *SK++; - } - - SK -= 2; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - -exit: - mbedtls_camellia_free(&cty); - - return ret; -} -#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ - -/* - * Camellia-ECB block encryption/decryption - */ -int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]) -{ - int NR; - uint32_t *RK, X[4]; - if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) { - return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA; - } - - ((void) mode); - - NR = ctx->nr; - RK = ctx->rk; - - X[0] = MBEDTLS_GET_UINT32_BE(input, 0); - X[1] = MBEDTLS_GET_UINT32_BE(input, 4); - X[2] = MBEDTLS_GET_UINT32_BE(input, 8); - X[3] = MBEDTLS_GET_UINT32_BE(input, 12); - - X[0] ^= *RK++; - X[1] ^= *RK++; - X[2] ^= *RK++; - X[3] ^= *RK++; - - while (NR) { - --NR; - camellia_feistel(X, RK, X + 2); - RK += 2; - camellia_feistel(X + 2, RK, X); - RK += 2; - camellia_feistel(X, RK, X + 2); - RK += 2; - camellia_feistel(X + 2, RK, X); - RK += 2; - camellia_feistel(X, RK, X + 2); - RK += 2; - camellia_feistel(X + 2, RK, X); - RK += 2; - - if (NR) { - FL(X[0], X[1], RK[0], RK[1]); - RK += 2; - FLInv(X[2], X[3], RK[0], RK[1]); - RK += 2; - } - } - - X[2] ^= *RK++; - X[3] ^= *RK++; - X[0] ^= *RK++; - X[1] ^= *RK++; - - MBEDTLS_PUT_UINT32_BE(X[2], output, 0); - MBEDTLS_PUT_UINT32_BE(X[3], output, 4); - MBEDTLS_PUT_UINT32_BE(X[0], output, 8); - MBEDTLS_PUT_UINT32_BE(X[1], output, 12); - - return 0; -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * Camellia-CBC buffer encryption/decryption - */ -int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output) -{ - unsigned char temp[16]; - if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) { - return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA; - } - - if (length % 16) { - return MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH; - } - - if (mode == MBEDTLS_CAMELLIA_DECRYPT) { - while (length > 0) { - memcpy(temp, input, 16); - mbedtls_camellia_crypt_ecb(ctx, mode, input, output); - - mbedtls_xor(output, output, iv, 16); - - memcpy(iv, temp, 16); - - input += 16; - output += 16; - length -= 16; - } - } else { - while (length > 0) { - mbedtls_xor(output, input, iv, 16); - - mbedtls_camellia_crypt_ecb(ctx, mode, output, output); - memcpy(iv, output, 16); - - input += 16; - output += 16; - length -= 16; - } - } - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * Camellia-CFB128 buffer encryption/decryption - */ -int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output) -{ - int c; - size_t n; - if (mode != MBEDTLS_CAMELLIA_ENCRYPT && mode != MBEDTLS_CAMELLIA_DECRYPT) { - return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA; - } - - n = *iv_off; - if (n >= 16) { - return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA; - } - - if (mode == MBEDTLS_CAMELLIA_DECRYPT) { - while (length--) { - if (n == 0) { - mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv); - } - - c = *input++; - *output++ = (unsigned char) (c ^ iv[n]); - iv[n] = (unsigned char) c; - - n = (n + 1) & 0x0F; - } - } else { - while (length--) { - if (n == 0) { - mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv); - } - - iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++); - - n = (n + 1) & 0x0F; - } - } - - *iv_off = n; - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Camellia-CTR buffer encryption/decryption - */ -int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output) -{ - int c, i; - size_t n; - - n = *nc_off; - if (n >= 16) { - return MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA; - } - - while (length--) { - if (n == 0) { - mbedtls_camellia_crypt_ecb(ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter, - stream_block); - - for (i = 16; i > 0; i--) { - if (++nonce_counter[i - 1] != 0) { - break; - } - } - } - c = *input++; - *output++ = (unsigned char) (c ^ stream_block[n]); - - n = (n + 1) & 0x0F; - } - - *nc_off = n; - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* !MBEDTLS_CAMELLIA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -/* - * Camellia test vectors from: - * - * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html: - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt - * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt - * (For each bitlength: Key 0, Nr 39) - */ -#define CAMELLIA_TESTS_ECB 2 - -static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = -{ - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, - { - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - }, -}; - -static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] = -{ - { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] = -{ - { - { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, - 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, - { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE, - 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 } - }, - { - { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, - 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, - { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9, - 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 } - }, - { - { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, - 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, - { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C, - 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 } - } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define CAMELLIA_TESTS_CBC 3 - -static const unsigned char camellia_test_cbc_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } - , - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B } - , - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char camellia_test_cbc_iv[16] = - -{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F } -; - -static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] = -{ - { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A }, - { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 }, - { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF } - -}; - -static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] = -{ - { - { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0, - 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB }, - { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78, - 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 }, - { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B, - 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 } - }, - { - { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2, - 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 }, - { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42, - 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 }, - { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8, - 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 } - }, - { - { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A, - 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA }, - { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40, - 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 }, - { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA, - 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 } - } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * Camellia-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc5528.html - */ - -static const unsigned char camellia_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char camellia_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char camellia_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char camellia_test_ctr_ct[3][48] = -{ - { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A, - 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F }, - { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4, - 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44, - 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7, - 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 }, - { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88, - 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73, - 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1, - 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD, - 0xDF, 0x50, 0x86, 0x96 } -}; - -static const int camellia_test_ctr_len[3] = -{ 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/* - * Checkup routine - */ -int mbedtls_camellia_self_test(int verbose) -{ - int i, j, u, v; - unsigned char key[32]; - unsigned char buf[64]; - unsigned char src[16]; - unsigned char dst[16]; -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - size_t offset, len; - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - int ret = 1; - - mbedtls_camellia_context ctx; - - mbedtls_camellia_init(&ctx); - memset(key, 0, 32); - - for (j = 0; j < 6; j++) { - u = j >> 1; - v = j & 1; - - if (verbose != 0) { - mbedtls_printf(" CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, - (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc"); - } - -#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (v == MBEDTLS_CAMELLIA_DECRYPT) { - if (verbose != 0) { - mbedtls_printf("skipped\n"); - } - continue; - } -#endif - - for (i = 0; i < CAMELLIA_TESTS_ECB; i++) { - memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (v == MBEDTLS_CAMELLIA_DECRYPT) { - mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64); - memcpy(src, camellia_test_ecb_cipher[u][i], 16); - memcpy(dst, camellia_test_ecb_plain[i], 16); - } else -#endif - { /* MBEDTLS_CAMELLIA_ENCRYPT */ - mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64); - memcpy(src, camellia_test_ecb_plain[i], 16); - memcpy(dst, camellia_test_ecb_cipher[u][i], 16); - } - - mbedtls_camellia_crypt_ecb(&ctx, v, src, buf); - - if (memcmp(buf, dst, 16) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - goto exit; - } - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for (j = 0; j < 6; j++) { - u = j >> 1; - v = j & 1; - - if (verbose != 0) { - mbedtls_printf(" CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, - (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc"); - } - - memcpy(src, camellia_test_cbc_iv, 16); - memcpy(dst, camellia_test_cbc_iv, 16); - memcpy(key, camellia_test_cbc_key[u], 16 + 8 * u); - - if (v == MBEDTLS_CAMELLIA_DECRYPT) { - mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64); - } else { - mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64); - } - - for (i = 0; i < CAMELLIA_TESTS_CBC; i++) { - - if (v == MBEDTLS_CAMELLIA_DECRYPT) { - memcpy(iv, src, 16); - memcpy(src, camellia_test_cbc_cipher[u][i], 16); - memcpy(dst, camellia_test_cbc_plain[i], 16); - } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ - memcpy(iv, dst, 16); - memcpy(src, camellia_test_cbc_plain[i], 16); - memcpy(dst, camellia_test_cbc_cipher[u][i], 16); - } - - mbedtls_camellia_crypt_cbc(&ctx, v, 16, iv, src, buf); - - if (memcmp(buf, dst, 16) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - goto exit; - } - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - if (verbose != 0) { - mbedtls_printf("\n"); - } - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for (i = 0; i < 6; i++) { - u = i >> 1; - v = i & 1; - - if (verbose != 0) { - mbedtls_printf(" CAMELLIA-CTR-128 (%s): ", - (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc"); - } - - memcpy(nonce_counter, camellia_test_ctr_nonce_counter[u], 16); - memcpy(key, camellia_test_ctr_key[u], 16); - - offset = 0; - mbedtls_camellia_setkey_enc(&ctx, key, 128); - - if (v == MBEDTLS_CAMELLIA_DECRYPT) { - len = camellia_test_ctr_len[u]; - memcpy(buf, camellia_test_ctr_ct[u], len); - - mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block, - buf, buf); - - if (memcmp(buf, camellia_test_ctr_pt[u], len) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - goto exit; - } - } else { - len = camellia_test_ctr_len[u]; - memcpy(buf, camellia_test_ctr_pt[u], len); - - mbedtls_camellia_crypt_ctr(&ctx, len, &offset, nonce_counter, stream_block, - buf, buf); - - if (memcmp(buf, camellia_test_ctr_ct[u], len) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - goto exit; - } - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - ret = 0; - -exit: - mbedtls_camellia_free(&ctx); - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CAMELLIA_C */ diff --git a/vendor/mbedtls/library/ccm.c b/vendor/mbedtls/library/ccm.c deleted file mode 100644 index 6a4fbb0a0..000000000 --- a/vendor/mbedtls/library/ccm.c +++ /dev/null @@ -1,777 +0,0 @@ -/* - * NIST SP800-38C compliant CCM implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * Definition of CCM: - * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - * RFC 3610 "Counter with CBC-MAC (CCM)" - * - * Related: - * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" - */ - -#include "common.h" - -#if defined(MBEDTLS_CCM_C) - -#include "mbedtls/ccm.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/constant_time.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_C) -#include "block_cipher_internal.h" -#endif - -#include - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ -#endif /* MBEDTLS_PLATFORM_C */ - -#if !defined(MBEDTLS_CCM_ALT) - - -/* - * Initialize context - */ -void mbedtls_ccm_init(mbedtls_ccm_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_ccm_context)); -} - -int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - mbedtls_block_cipher_free(&ctx->block_cipher_ctx); - - if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } -#else - const mbedtls_cipher_info_t *cipher_info; - - cipher_info = mbedtls_cipher_info_from_values(cipher, keybits, - MBEDTLS_MODE_ECB); - if (cipher_info == NULL) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - mbedtls_cipher_free(&ctx->cipher_ctx); - - if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) { - return ret; - } - - if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT)) != 0) { - return ret; - } -#endif - - return ret; -} - -/* - * Free context - */ -void mbedtls_ccm_free(mbedtls_ccm_context *ctx) -{ - if (ctx == NULL) { - return; - } -#if defined(MBEDTLS_BLOCK_CIPHER_C) - mbedtls_block_cipher_free(&ctx->block_cipher_ctx); -#else - mbedtls_cipher_free(&ctx->cipher_ctx); -#endif - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ccm_context)); -} - -#define CCM_STATE__CLEAR 0 -#define CCM_STATE__STARTED (1 << 0) -#define CCM_STATE__LENGTHS_SET (1 << 1) -#define CCM_STATE__AUTH_DATA_STARTED (1 << 2) -#define CCM_STATE__AUTH_DATA_FINISHED (1 << 3) -#define CCM_STATE__ERROR (1 << 4) - -/* - * Encrypt or decrypt a partial block with CTR - */ -static int mbedtls_ccm_crypt(mbedtls_ccm_context *ctx, - size_t offset, size_t use_len, - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char tmp_buf[16] = { 0 }; - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->ctr, tmp_buf); -#else - size_t olen = 0; - ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->ctr, 16, tmp_buf, &olen); -#endif - if (ret != 0) { - ctx->state |= CCM_STATE__ERROR; - mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf)); - return ret; - } - - mbedtls_xor(output, input, tmp_buf + offset, use_len); - - mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf)); - return ret; -} - -static void mbedtls_ccm_clear_state(mbedtls_ccm_context *ctx) -{ - ctx->state = CCM_STATE__CLEAR; - memset(ctx->y, 0, 16); - memset(ctx->ctr, 0, 16); -} - -static int ccm_calculate_first_block_if_ready(mbedtls_ccm_context *ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char i; - size_t len_left; -#if !defined(MBEDTLS_BLOCK_CIPHER_C) - size_t olen; -#endif - - /* length calculation can be done only after both - * mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed - */ - if (!(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGTHS_SET)) { - return 0; - } - - /* CCM expects non-empty tag. - * CCM* allows empty tag. For CCM* without tag, the tag calculation is skipped. - */ - if (ctx->tag_len == 0) { - if (ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT || ctx->mode == MBEDTLS_CCM_STAR_DECRYPT) { - ctx->plaintext_len = 0; - return 0; - } else { - ctx->state |= CCM_STATE__ERROR; - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - } - - /* - * First block: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - set by: mbedtls_ccm_starts() - * iv_len+1 .. 15 length - * - * With flags as (bits): - * 7 0 - * 6 add present? - * 5 .. 3 (t - 2) / 2 - * 2 .. 0 q - 1 - */ - ctx->y[0] |= (ctx->add_len > 0) << 6; - ctx->y[0] |= ((ctx->tag_len - 2) / 2) << 3; - ctx->y[0] |= ctx->q - 1; - - for (i = 0, len_left = ctx->plaintext_len; i < ctx->q; i++, len_left >>= 8) { - ctx->y[15-i] = MBEDTLS_BYTE_0(len_left); - } - - if (len_left > 0) { - ctx->state |= CCM_STATE__ERROR; - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - /* Start CBC-MAC with first block*/ -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y); -#else - ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen); -#endif - if (ret != 0) { - ctx->state |= CCM_STATE__ERROR; - return ret; - } - - return 0; -} - -int mbedtls_ccm_starts(mbedtls_ccm_context *ctx, - int mode, - const unsigned char *iv, - size_t iv_len) -{ - /* Also implies q is within bounds */ - if (iv_len < 7 || iv_len > 13) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - ctx->mode = mode; - ctx->q = 16 - 1 - (unsigned char) iv_len; - - /* - * Prepare counter block for encryption: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - * iv_len+1 .. 15 counter (initially 1) - * - * With flags as (bits): - * 7 .. 3 0 - * 2 .. 0 q - 1 - */ - memset(ctx->ctr, 0, 16); - ctx->ctr[0] = ctx->q - 1; - memcpy(ctx->ctr + 1, iv, iv_len); - memset(ctx->ctr + 1 + iv_len, 0, ctx->q); - ctx->ctr[15] = 1; - - /* - * See ccm_calculate_first_block_if_ready() for block layout description - */ - memcpy(ctx->y + 1, iv, iv_len); - - ctx->state |= CCM_STATE__STARTED; - return ccm_calculate_first_block_if_ready(ctx); -} - -int mbedtls_ccm_set_lengths(mbedtls_ccm_context *ctx, - size_t total_ad_len, - size_t plaintext_len, - size_t tag_len) -{ - /* - * Check length requirements: SP800-38C A.1 - * Additional requirement: a < 2^16 - 2^8 to simplify the code. - * 'length' checked later (when writing it to the first block) - * - * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4). - */ - if (tag_len == 2 || tag_len > 16 || tag_len % 2 != 0) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (total_ad_len >= 0xFF00) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - ctx->plaintext_len = plaintext_len; - ctx->add_len = total_ad_len; - ctx->tag_len = tag_len; - ctx->processed = 0; - - ctx->state |= CCM_STATE__LENGTHS_SET; - return ccm_calculate_first_block_if_ready(ctx); -} - -int mbedtls_ccm_update_ad(mbedtls_ccm_context *ctx, - const unsigned char *add, - size_t add_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t use_len, offset; -#if !defined(MBEDTLS_BLOCK_CIPHER_C) - size_t olen; -#endif - - if (ctx->state & CCM_STATE__ERROR) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (add_len > 0) { - if (ctx->state & CCM_STATE__AUTH_DATA_FINISHED) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (!(ctx->state & CCM_STATE__AUTH_DATA_STARTED)) { - if (add_len > ctx->add_len) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - ctx->y[0] ^= (unsigned char) ((ctx->add_len >> 8) & 0xFF); - ctx->y[1] ^= (unsigned char) ((ctx->add_len) & 0xFF); - - ctx->state |= CCM_STATE__AUTH_DATA_STARTED; - } else if (ctx->processed + add_len > ctx->add_len) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - while (add_len > 0) { - offset = (ctx->processed + 2) % 16; /* account for y[0] and y[1] - * holding total auth data length */ - use_len = 16 - offset; - - if (use_len > add_len) { - use_len = add_len; - } - - mbedtls_xor(ctx->y + offset, ctx->y + offset, add, use_len); - - ctx->processed += use_len; - add_len -= use_len; - add += use_len; - - if (use_len + offset == 16 || ctx->processed == ctx->add_len) { -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y); -#else - ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen); -#endif - if (ret != 0) { - ctx->state |= CCM_STATE__ERROR; - return ret; - } - } - } - - if (ctx->processed == ctx->add_len) { - ctx->state |= CCM_STATE__AUTH_DATA_FINISHED; - ctx->processed = 0; // prepare for mbedtls_ccm_update() - } - } - - return 0; -} - -int mbedtls_ccm_update(mbedtls_ccm_context *ctx, - const unsigned char *input, size_t input_len, - unsigned char *output, size_t output_size, - size_t *output_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char i; - size_t use_len, offset; -#if !defined(MBEDTLS_BLOCK_CIPHER_C) - size_t olen; -#endif - - unsigned char local_output[16]; - - if (ctx->state & CCM_STATE__ERROR) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - /* Check against plaintext length only if performing operation with - * authentication - */ - if (ctx->tag_len != 0 && ctx->processed + input_len > ctx->plaintext_len) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (output_size < input_len) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - *output_len = input_len; - - ret = 0; - - while (input_len > 0) { - offset = ctx->processed % 16; - - use_len = 16 - offset; - - if (use_len > input_len) { - use_len = input_len; - } - - ctx->processed += use_len; - - if (ctx->mode == MBEDTLS_CCM_ENCRYPT || \ - ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT) { - mbedtls_xor(ctx->y + offset, ctx->y + offset, input, use_len); - - if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) { -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y); -#else - ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen); -#endif - if (ret != 0) { - ctx->state |= CCM_STATE__ERROR; - goto exit; - } - } - - ret = mbedtls_ccm_crypt(ctx, offset, use_len, input, output); - if (ret != 0) { - goto exit; - } - } - - if (ctx->mode == MBEDTLS_CCM_DECRYPT || \ - ctx->mode == MBEDTLS_CCM_STAR_DECRYPT) { - /* Since output may be in shared memory, we cannot be sure that - * it will contain what we wrote to it. Therefore, we should avoid using - * it as input to any operations. - * Write decrypted data to local_output to avoid using output variable as - * input in the XOR operation for Y. - */ - ret = mbedtls_ccm_crypt(ctx, offset, use_len, input, local_output); - if (ret != 0) { - goto exit; - } - - mbedtls_xor(ctx->y + offset, ctx->y + offset, local_output, use_len); - - memcpy(output, local_output, use_len); - - if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) { -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y); -#else - ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen); -#endif - if (ret != 0) { - ctx->state |= CCM_STATE__ERROR; - goto exit; - } - } - } - - if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) { - for (i = 0; i < ctx->q; i++) { - if (++(ctx->ctr)[15-i] != 0) { - break; - } - } - } - - input_len -= use_len; - input += use_len; - output += use_len; - } - -exit: - mbedtls_platform_zeroize(local_output, 16); - - return ret; -} - -int mbedtls_ccm_finish(mbedtls_ccm_context *ctx, - unsigned char *tag, size_t tag_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char i; - - if (ctx->state & CCM_STATE__ERROR) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - - if (!(ctx->state & CCM_STATE__STARTED)) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (!(ctx->state & CCM_STATE__LENGTHS_SET)) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (ctx->add_len > 0 && !(ctx->state & CCM_STATE__AUTH_DATA_FINISHED)) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (ctx->plaintext_len > 0 && ctx->processed != ctx->plaintext_len) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - if (tag_len != ctx->tag_len) { - return MBEDTLS_ERR_CCM_BAD_INPUT; - } - - /* - * Authentication: reset counter and crypt/mask internal tag - */ - for (i = 0; i < ctx->q; i++) { - ctx->ctr[15-i] = 0; - } - - ret = mbedtls_ccm_crypt(ctx, 0, 16, ctx->y, ctx->y); - if (ret != 0) { - return ret; - } - if (tag != NULL) { - memcpy(tag, ctx->y, tag_len); - } - mbedtls_ccm_clear_state(ctx); - - return 0; -} - -/* - * Authenticated encryption or decryption - */ -static int ccm_auth_crypt(mbedtls_ccm_context *ctx, int mode, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen; - - if ((ret = mbedtls_ccm_starts(ctx, mode, iv, iv_len)) != 0) { - return ret; - } - - if ((ret = mbedtls_ccm_set_lengths(ctx, add_len, length, tag_len)) != 0) { - return ret; - } - - if ((ret = mbedtls_ccm_update_ad(ctx, add, add_len)) != 0) { - return ret; - } - - if ((ret = mbedtls_ccm_update(ctx, input, length, - output, length, &olen)) != 0) { - return ret; - } - - if ((ret = mbedtls_ccm_finish(ctx, tag, tag_len)) != 0) { - return ret; - } - - return 0; -} - -/* - * Authenticated encryption - */ -int mbedtls_ccm_star_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len) -{ - return ccm_auth_crypt(ctx, MBEDTLS_CCM_STAR_ENCRYPT, length, iv, iv_len, - add, add_len, input, output, tag, tag_len); -} - -int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len) -{ - return ccm_auth_crypt(ctx, MBEDTLS_CCM_ENCRYPT, length, iv, iv_len, - add, add_len, input, output, tag, tag_len); -} - -/* - * Authenticated decryption - */ -static int mbedtls_ccm_compare_tags(const unsigned char *tag1, - const unsigned char *tag2, - size_t tag_len) -{ - /* Check tag in "constant-time" */ - int diff = mbedtls_ct_memcmp(tag1, tag2, tag_len); - - if (diff != 0) { - return MBEDTLS_ERR_CCM_AUTH_FAILED; - } - - return 0; -} - -static int ccm_auth_decrypt(mbedtls_ccm_context *ctx, int mode, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char check_tag[16]; - - if ((ret = ccm_auth_crypt(ctx, mode, length, - iv, iv_len, add, add_len, - input, output, check_tag, tag_len)) != 0) { - return ret; - } - - if ((ret = mbedtls_ccm_compare_tags(tag, check_tag, tag_len)) != 0) { - mbedtls_platform_zeroize(output, length); - return ret; - } - - return 0; -} - -int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len) -{ - return ccm_auth_decrypt(ctx, MBEDTLS_CCM_STAR_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, tag, tag_len); -} - -int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len) -{ - return ccm_auth_decrypt(ctx, MBEDTLS_CCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, tag, tag_len); -} -#endif /* !MBEDTLS_CCM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES) -/* - * Examples 1 to 3 from SP800-38C Appendix C - */ - -#define NB_TESTS 3 -#define CCM_SELFTEST_PT_MAX_LEN 24 -#define CCM_SELFTEST_CT_MAX_LEN 32 -/* - * The data is the same for all tests, only the used length changes - */ -static const unsigned char key_test_data[] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f -}; - -static const unsigned char iv_test_data[] = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b -}; - -static const unsigned char ad_test_data[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 -}; - -static const unsigned char msg_test_data[CCM_SELFTEST_PT_MAX_LEN] = { - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -}; - -static const size_t iv_len_test_data[NB_TESTS] = { 7, 8, 12 }; -static const size_t add_len_test_data[NB_TESTS] = { 8, 16, 20 }; -static const size_t msg_len_test_data[NB_TESTS] = { 4, 16, 24 }; -static const size_t tag_len_test_data[NB_TESTS] = { 4, 6, 8 }; - -static const unsigned char res_test_data[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = { - { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, - { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, - 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, - 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, - { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, - 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, - 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, - 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } -}; - -int mbedtls_ccm_self_test(int verbose) -{ - mbedtls_ccm_context ctx; - /* - * Some hardware accelerators require the input and output buffers - * would be in RAM, because the flash is not accessible. - * Use buffers on the stack to hold the test vectors data. - */ - unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN]; - unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN]; - size_t i; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_ccm_init(&ctx); - - if (mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key_test_data, - 8 * sizeof(key_test_data)) != 0) { - if (verbose != 0) { - mbedtls_printf(" CCM: setup failed"); - } - - return 1; - } - - for (i = 0; i < NB_TESTS; i++) { - if (verbose != 0) { - mbedtls_printf(" CCM-AES #%u: ", (unsigned int) i + 1); - } - - memset(plaintext, 0, CCM_SELFTEST_PT_MAX_LEN); - memset(ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN); - memcpy(plaintext, msg_test_data, msg_len_test_data[i]); - - ret = mbedtls_ccm_encrypt_and_tag(&ctx, msg_len_test_data[i], - iv_test_data, iv_len_test_data[i], - ad_test_data, add_len_test_data[i], - plaintext, ciphertext, - ciphertext + msg_len_test_data[i], - tag_len_test_data[i]); - - if (ret != 0 || - memcmp(ciphertext, res_test_data[i], - msg_len_test_data[i] + tag_len_test_data[i]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return 1; - } - memset(plaintext, 0, CCM_SELFTEST_PT_MAX_LEN); - - ret = mbedtls_ccm_auth_decrypt(&ctx, msg_len_test_data[i], - iv_test_data, iv_len_test_data[i], - ad_test_data, add_len_test_data[i], - ciphertext, plaintext, - ciphertext + msg_len_test_data[i], - tag_len_test_data[i]); - - if (ret != 0 || - memcmp(plaintext, msg_test_data, msg_len_test_data[i]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return 1; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - mbedtls_ccm_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_CCM_C */ diff --git a/vendor/mbedtls/library/chacha20.c b/vendor/mbedtls/library/chacha20.c deleted file mode 100644 index acaae5b2e..000000000 --- a/vendor/mbedtls/library/chacha20.c +++ /dev/null @@ -1,497 +0,0 @@ -/** - * \file chacha20.c - * - * \brief ChaCha20 cipher. - * - * \author Daniel King - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_CHACHA20_C) - -#include "mbedtls/chacha20.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_CHACHA20_ALT) - -#define ROTL32(value, amount) \ - ((uint32_t) ((value) << (amount)) | ((value) >> (32 - (amount)))) - -#define CHACHA20_CTR_INDEX (12U) - -#define CHACHA20_BLOCK_SIZE_BYTES (4U * 16U) - -/** - * \brief ChaCha20 quarter round operation. - * - * The quarter round is defined as follows (from RFC 7539): - * 1. a += b; d ^= a; d <<<= 16; - * 2. c += d; b ^= c; b <<<= 12; - * 3. a += b; d ^= a; d <<<= 8; - * 4. c += d; b ^= c; b <<<= 7; - * - * \param state ChaCha20 state to modify. - * \param a The index of 'a' in the state. - * \param b The index of 'b' in the state. - * \param c The index of 'c' in the state. - * \param d The index of 'd' in the state. - */ -static inline void chacha20_quarter_round(uint32_t state[16], - size_t a, - size_t b, - size_t c, - size_t d) -{ - /* a += b; d ^= a; d <<<= 16; */ - state[a] += state[b]; - state[d] ^= state[a]; - state[d] = ROTL32(state[d], 16); - - /* c += d; b ^= c; b <<<= 12 */ - state[c] += state[d]; - state[b] ^= state[c]; - state[b] = ROTL32(state[b], 12); - - /* a += b; d ^= a; d <<<= 8; */ - state[a] += state[b]; - state[d] ^= state[a]; - state[d] = ROTL32(state[d], 8); - - /* c += d; b ^= c; b <<<= 7; */ - state[c] += state[d]; - state[b] ^= state[c]; - state[b] = ROTL32(state[b], 7); -} - -/** - * \brief Perform the ChaCha20 inner block operation. - * - * This function performs two rounds: the column round and the - * diagonal round. - * - * \param state The ChaCha20 state to update. - */ -static void chacha20_inner_block(uint32_t state[16]) -{ - chacha20_quarter_round(state, 0, 4, 8, 12); - chacha20_quarter_round(state, 1, 5, 9, 13); - chacha20_quarter_round(state, 2, 6, 10, 14); - chacha20_quarter_round(state, 3, 7, 11, 15); - - chacha20_quarter_round(state, 0, 5, 10, 15); - chacha20_quarter_round(state, 1, 6, 11, 12); - chacha20_quarter_round(state, 2, 7, 8, 13); - chacha20_quarter_round(state, 3, 4, 9, 14); -} - -/** - * \brief Generates a keystream block. - * - * \param initial_state The initial ChaCha20 state (key, nonce, counter). - * \param keystream Generated keystream bytes are written to this buffer. - */ -static void chacha20_block(const uint32_t initial_state[16], - unsigned char keystream[64]) -{ - uint32_t working_state[16]; - size_t i; - - memcpy(working_state, - initial_state, - CHACHA20_BLOCK_SIZE_BYTES); - - for (i = 0U; i < 10U; i++) { - chacha20_inner_block(working_state); - } - - working_state[0] += initial_state[0]; - working_state[1] += initial_state[1]; - working_state[2] += initial_state[2]; - working_state[3] += initial_state[3]; - working_state[4] += initial_state[4]; - working_state[5] += initial_state[5]; - working_state[6] += initial_state[6]; - working_state[7] += initial_state[7]; - working_state[8] += initial_state[8]; - working_state[9] += initial_state[9]; - working_state[10] += initial_state[10]; - working_state[11] += initial_state[11]; - working_state[12] += initial_state[12]; - working_state[13] += initial_state[13]; - working_state[14] += initial_state[14]; - working_state[15] += initial_state[15]; - - for (i = 0U; i < 16; i++) { - size_t offset = i * 4U; - - MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset); - } - - mbedtls_platform_zeroize(working_state, sizeof(working_state)); -} - -void mbedtls_chacha20_init(mbedtls_chacha20_context *ctx) -{ - mbedtls_platform_zeroize(ctx->state, sizeof(ctx->state)); - mbedtls_platform_zeroize(ctx->keystream8, sizeof(ctx->keystream8)); - - /* Initially, there's no keystream bytes available */ - ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; -} - -void mbedtls_chacha20_free(mbedtls_chacha20_context *ctx) -{ - if (ctx != NULL) { - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_chacha20_context)); - } -} - -int mbedtls_chacha20_setkey(mbedtls_chacha20_context *ctx, - const unsigned char key[32]) -{ - /* ChaCha20 constants - the string "expand 32-byte k" */ - ctx->state[0] = 0x61707865; - ctx->state[1] = 0x3320646e; - ctx->state[2] = 0x79622d32; - ctx->state[3] = 0x6b206574; - - /* Set key */ - ctx->state[4] = MBEDTLS_GET_UINT32_LE(key, 0); - ctx->state[5] = MBEDTLS_GET_UINT32_LE(key, 4); - ctx->state[6] = MBEDTLS_GET_UINT32_LE(key, 8); - ctx->state[7] = MBEDTLS_GET_UINT32_LE(key, 12); - ctx->state[8] = MBEDTLS_GET_UINT32_LE(key, 16); - ctx->state[9] = MBEDTLS_GET_UINT32_LE(key, 20); - ctx->state[10] = MBEDTLS_GET_UINT32_LE(key, 24); - ctx->state[11] = MBEDTLS_GET_UINT32_LE(key, 28); - - return 0; -} - -int mbedtls_chacha20_starts(mbedtls_chacha20_context *ctx, - const unsigned char nonce[12], - uint32_t counter) -{ - /* Counter */ - ctx->state[12] = counter; - - /* Nonce */ - ctx->state[13] = MBEDTLS_GET_UINT32_LE(nonce, 0); - ctx->state[14] = MBEDTLS_GET_UINT32_LE(nonce, 4); - ctx->state[15] = MBEDTLS_GET_UINT32_LE(nonce, 8); - - mbedtls_platform_zeroize(ctx->keystream8, sizeof(ctx->keystream8)); - - /* Initially, there's no keystream bytes available */ - ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; - - return 0; -} - -int mbedtls_chacha20_update(mbedtls_chacha20_context *ctx, - size_t size, - const unsigned char *input, - unsigned char *output) -{ - size_t offset = 0U; - - /* Use leftover keystream bytes, if available */ - while (size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES) { - output[offset] = input[offset] - ^ ctx->keystream8[ctx->keystream_bytes_used]; - - ctx->keystream_bytes_used++; - offset++; - size--; - } - - /* Process full blocks */ - while (size >= CHACHA20_BLOCK_SIZE_BYTES) { - /* Generate new keystream block and increment counter */ - chacha20_block(ctx->state, ctx->keystream8); - ctx->state[CHACHA20_CTR_INDEX]++; - - mbedtls_xor(output + offset, input + offset, ctx->keystream8, 64U); - - offset += CHACHA20_BLOCK_SIZE_BYTES; - size -= CHACHA20_BLOCK_SIZE_BYTES; - } - - /* Last (partial) block */ - if (size > 0U) { - /* Generate new keystream block and increment counter */ - chacha20_block(ctx->state, ctx->keystream8); - ctx->state[CHACHA20_CTR_INDEX]++; - - mbedtls_xor(output + offset, input + offset, ctx->keystream8, size); - - ctx->keystream_bytes_used = size; - - } - - return 0; -} - -int mbedtls_chacha20_crypt(const unsigned char key[32], - const unsigned char nonce[12], - uint32_t counter, - size_t data_len, - const unsigned char *input, - unsigned char *output) -{ - mbedtls_chacha20_context ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_chacha20_init(&ctx); - - ret = mbedtls_chacha20_setkey(&ctx, key); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_chacha20_starts(&ctx, nonce, counter); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_chacha20_update(&ctx, data_len, input, output); - -cleanup: - mbedtls_chacha20_free(&ctx); - return ret; -} - -#endif /* !MBEDTLS_CHACHA20_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_keys[2][32] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 - } -}; - -static const unsigned char test_nonces[2][12] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02 - } -}; - -static const uint32_t test_counters[2] = -{ - 0U, - 1U -}; - -static const unsigned char test_input[2][375] = -{ - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, - 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, - 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, - 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, - 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, - 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, - 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, - 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, - 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, - 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, - 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, - 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, - 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, - 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, - 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, - 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63, - 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, - 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, - 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, - 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, - 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f - } -}; - -static const unsigned char test_output[2][375] = -{ - { - 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, - 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, - 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, - 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, - 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, - 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, - 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, - 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86 - }, - { - 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde, - 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70, - 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd, - 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec, - 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15, - 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05, - 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f, - 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d, - 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa, - 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e, - 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7, - 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50, - 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05, - 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c, - 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05, - 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a, - 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0, - 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66, - 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4, - 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d, - 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91, - 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28, - 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87, - 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b, - 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2, - 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f, - 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76, - 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c, - 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b, - 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84, - 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd, - 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b, - 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe, - 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0, - 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80, - 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f, - 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3, - 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62, - 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91, - 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6, - 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64, - 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85, - 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41, - 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab, - 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba, - 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd, - 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21 - } -}; - -static const size_t test_lengths[2] = -{ - 64U, - 375U -}; - -/* Make sure no other definition is already present. */ -#undef ASSERT - -#define ASSERT(cond, args) \ - do \ - { \ - if (!(cond)) \ - { \ - if (verbose != 0) \ - mbedtls_printf args; \ - \ - return -1; \ - } \ - } \ - while (0) - -int mbedtls_chacha20_self_test(int verbose) -{ - unsigned char output[381]; - unsigned i; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - for (i = 0U; i < 2U; i++) { - if (verbose != 0) { - mbedtls_printf(" ChaCha20 test %u ", i); - } - - ret = mbedtls_chacha20_crypt(test_keys[i], - test_nonces[i], - test_counters[i], - test_lengths[i], - test_input[i], - output); - - ASSERT(0 == ret, ("error code: %i\n", ret)); - - ASSERT(0 == memcmp(output, test_output[i], test_lengths[i]), - ("failed (output)\n")); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* !MBEDTLS_CHACHA20_C */ diff --git a/vendor/mbedtls/library/chachapoly.c b/vendor/mbedtls/library/chachapoly.c deleted file mode 100644 index a1314eab6..000000000 --- a/vendor/mbedtls/library/chachapoly.c +++ /dev/null @@ -1,478 +0,0 @@ -/** - * \file chachapoly.c - * - * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#include "common.h" - -#if defined(MBEDTLS_CHACHAPOLY_C) - -#include "mbedtls/chachapoly.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/constant_time.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_CHACHAPOLY_ALT) - -#define CHACHAPOLY_STATE_INIT (0) -#define CHACHAPOLY_STATE_AAD (1) -#define CHACHAPOLY_STATE_CIPHERTEXT (2) /* Encrypting or decrypting */ -#define CHACHAPOLY_STATE_FINISHED (3) - -/** - * \brief Adds nul bytes to pad the AAD for Poly1305. - * - * \param ctx The ChaCha20-Poly1305 context. - */ -static int chachapoly_pad_aad(mbedtls_chachapoly_context *ctx) -{ - uint32_t partial_block_len = (uint32_t) (ctx->aad_len % 16U); - unsigned char zeroes[15]; - - if (partial_block_len == 0U) { - return 0; - } - - memset(zeroes, 0, sizeof(zeroes)); - - return mbedtls_poly1305_update(&ctx->poly1305_ctx, - zeroes, - 16U - partial_block_len); -} - -/** - * \brief Adds nul bytes to pad the ciphertext for Poly1305. - * - * \param ctx The ChaCha20-Poly1305 context. - */ -static int chachapoly_pad_ciphertext(mbedtls_chachapoly_context *ctx) -{ - uint32_t partial_block_len = (uint32_t) (ctx->ciphertext_len % 16U); - unsigned char zeroes[15]; - - if (partial_block_len == 0U) { - return 0; - } - - memset(zeroes, 0, sizeof(zeroes)); - return mbedtls_poly1305_update(&ctx->poly1305_ctx, - zeroes, - 16U - partial_block_len); -} - -void mbedtls_chachapoly_init(mbedtls_chachapoly_context *ctx) -{ - mbedtls_chacha20_init(&ctx->chacha20_ctx); - mbedtls_poly1305_init(&ctx->poly1305_ctx); - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_INIT; - ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; -} - -void mbedtls_chachapoly_free(mbedtls_chachapoly_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_chacha20_free(&ctx->chacha20_ctx); - mbedtls_poly1305_free(&ctx->poly1305_ctx); - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_INIT; - ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; -} - -int mbedtls_chachapoly_setkey(mbedtls_chachapoly_context *ctx, - const unsigned char key[32]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_chacha20_setkey(&ctx->chacha20_ctx, key); - - return ret; -} - -int mbedtls_chachapoly_starts(mbedtls_chachapoly_context *ctx, - const unsigned char nonce[12], - mbedtls_chachapoly_mode_t mode) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char poly1305_key[64]; - - /* Set counter = 0, will be update to 1 when generating Poly1305 key */ - ret = mbedtls_chacha20_starts(&ctx->chacha20_ctx, nonce, 0U); - if (ret != 0) { - goto cleanup; - } - - /* Generate the Poly1305 key by getting the ChaCha20 keystream output with - * counter = 0. This is the same as encrypting a buffer of zeroes. - * Only the first 256-bits (32 bytes) of the key is used for Poly1305. - * The other 256 bits are discarded. - */ - memset(poly1305_key, 0, sizeof(poly1305_key)); - ret = mbedtls_chacha20_update(&ctx->chacha20_ctx, sizeof(poly1305_key), - poly1305_key, poly1305_key); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_poly1305_starts(&ctx->poly1305_ctx, poly1305_key); - - if (ret == 0) { - ctx->aad_len = 0U; - ctx->ciphertext_len = 0U; - ctx->state = CHACHAPOLY_STATE_AAD; - ctx->mode = mode; - } - -cleanup: - mbedtls_platform_zeroize(poly1305_key, 64U); - return ret; -} - -int mbedtls_chachapoly_update_aad(mbedtls_chachapoly_context *ctx, - const unsigned char *aad, - size_t aad_len) -{ - if (ctx->state != CHACHAPOLY_STATE_AAD) { - return MBEDTLS_ERR_CHACHAPOLY_BAD_STATE; - } - - ctx->aad_len += aad_len; - - return mbedtls_poly1305_update(&ctx->poly1305_ctx, aad, aad_len); -} - -int mbedtls_chachapoly_update(mbedtls_chachapoly_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ctx->state != CHACHAPOLY_STATE_AAD) && - (ctx->state != CHACHAPOLY_STATE_CIPHERTEXT)) { - return MBEDTLS_ERR_CHACHAPOLY_BAD_STATE; - } - - if (ctx->state == CHACHAPOLY_STATE_AAD) { - ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; - - ret = chachapoly_pad_aad(ctx); - if (ret != 0) { - return ret; - } - } - - ctx->ciphertext_len += len; - - if (ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT) { - ret = mbedtls_chacha20_update(&ctx->chacha20_ctx, len, input, output); - if (ret != 0) { - return ret; - } - - ret = mbedtls_poly1305_update(&ctx->poly1305_ctx, output, len); - if (ret != 0) { - return ret; - } - } else { /* DECRYPT */ - ret = mbedtls_poly1305_update(&ctx->poly1305_ctx, input, len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_chacha20_update(&ctx->chacha20_ctx, len, input, output); - if (ret != 0) { - return ret; - } - } - - return 0; -} - -int mbedtls_chachapoly_finish(mbedtls_chachapoly_context *ctx, - unsigned char mac[16]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char len_block[16]; - - if (ctx->state == CHACHAPOLY_STATE_INIT) { - return MBEDTLS_ERR_CHACHAPOLY_BAD_STATE; - } - - if (ctx->state == CHACHAPOLY_STATE_AAD) { - ret = chachapoly_pad_aad(ctx); - if (ret != 0) { - return ret; - } - } else if (ctx->state == CHACHAPOLY_STATE_CIPHERTEXT) { - ret = chachapoly_pad_ciphertext(ctx); - if (ret != 0) { - return ret; - } - } - - ctx->state = CHACHAPOLY_STATE_FINISHED; - - /* The lengths of the AAD and ciphertext are processed by - * Poly1305 as the final 128-bit block, encoded as little-endian integers. - */ - MBEDTLS_PUT_UINT64_LE(ctx->aad_len, len_block, 0); - MBEDTLS_PUT_UINT64_LE(ctx->ciphertext_len, len_block, 8); - - ret = mbedtls_poly1305_update(&ctx->poly1305_ctx, len_block, 16U); - if (ret != 0) { - return ret; - } - - ret = mbedtls_poly1305_finish(&ctx->poly1305_ctx, mac); - - return ret; -} - -static int chachapoly_crypt_and_tag(mbedtls_chachapoly_context *ctx, - mbedtls_chachapoly_mode_t mode, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_chachapoly_starts(ctx, nonce, mode); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_chachapoly_update_aad(ctx, aad, aad_len); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_chachapoly_update(ctx, length, input, output); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_chachapoly_finish(ctx, tag); - -cleanup: - return ret; -} - -int mbedtls_chachapoly_encrypt_and_tag(mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char *input, - unsigned char *output, - unsigned char tag[16]) -{ - return chachapoly_crypt_and_tag(ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, - length, nonce, aad, aad_len, - input, output, tag); -} - -int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx, - size_t length, - const unsigned char nonce[12], - const unsigned char *aad, - size_t aad_len, - const unsigned char tag[16], - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char check_tag[16]; - int diff; - - if ((ret = chachapoly_crypt_and_tag(ctx, - MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, - aad, aad_len, input, output, check_tag)) != 0) { - return ret; - } - - /* Check tag in "constant-time" */ - diff = mbedtls_ct_memcmp(tag, check_tag, sizeof(check_tag)); - - if (diff != 0) { - mbedtls_platform_zeroize(output, length); - return MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED; - } - - return 0; -} - -#endif /* MBEDTLS_CHACHAPOLY_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_key[1][32] = -{ - { - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f - } -}; - -static const unsigned char test_nonce[1][12] = -{ - { - 0x07, 0x00, 0x00, 0x00, /* 32-bit common part */ - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */ - } -}; - -static const unsigned char test_aad[1][12] = -{ - { - 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7 - } -}; - -static const size_t test_aad_len[1] = -{ - 12U -}; - -static const unsigned char test_input[1][114] = -{ - { - 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, - 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, - 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, - 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, - 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, - 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, - 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, - 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, - 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, - 0x74, 0x2e - } -}; - -static const unsigned char test_output[1][114] = -{ - { - 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, - 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, - 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, - 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, - 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, - 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, - 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, - 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, - 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, - 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, - 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, - 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, - 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, - 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, - 0x61, 0x16 - } -}; - -static const size_t test_input_len[1] = -{ - 114U -}; - -static const unsigned char test_mac[1][16] = -{ - { - 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, - 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 - } -}; - -/* Make sure no other definition is already present. */ -#undef ASSERT - -#define ASSERT(cond, args) \ - do \ - { \ - if (!(cond)) \ - { \ - if (verbose != 0) \ - mbedtls_printf args; \ - \ - return -1; \ - } \ - } \ - while (0) - -int mbedtls_chachapoly_self_test(int verbose) -{ - mbedtls_chachapoly_context ctx; - unsigned i; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char output[200]; - unsigned char mac[16]; - - for (i = 0U; i < 1U; i++) { - if (verbose != 0) { - mbedtls_printf(" ChaCha20-Poly1305 test %u ", i); - } - - mbedtls_chachapoly_init(&ctx); - - ret = mbedtls_chachapoly_setkey(&ctx, test_key[i]); - ASSERT(0 == ret, ("setkey() error code: %i\n", ret)); - - ret = mbedtls_chachapoly_encrypt_and_tag(&ctx, - test_input_len[i], - test_nonce[i], - test_aad[i], - test_aad_len[i], - test_input[i], - output, - mac); - - ASSERT(0 == ret, ("crypt_and_tag() error code: %i\n", ret)); - - ASSERT(0 == memcmp(output, test_output[i], test_input_len[i]), - ("failure (wrong output)\n")); - - ASSERT(0 == memcmp(mac, test_mac[i], 16U), - ("failure (wrong MAC)\n")); - - mbedtls_chachapoly_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CHACHAPOLY_C */ diff --git a/vendor/mbedtls/library/check_crypto_config.h b/vendor/mbedtls/library/check_crypto_config.h deleted file mode 100644 index f1ed7f53e..000000000 --- a/vendor/mbedtls/library/check_crypto_config.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * \file check_crypto_config.h - * - * \brief Consistency checks for PSA configuration options - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * It is recommended to include this file from your crypto_config.h - * in order to catch dependency issues early. - */ - -#ifndef MBEDTLS_CHECK_CRYPTO_CONFIG_H -#define MBEDTLS_CHECK_CRYPTO_CONFIG_H - -#if defined(PSA_WANT_ALG_CCM) && \ - !(defined(PSA_WANT_KEY_TYPE_AES) || \ - defined(PSA_WANT_KEY_TYPE_CAMELLIA)) -#error "PSA_WANT_ALG_CCM defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_CMAC) && \ - !(defined(PSA_WANT_KEY_TYPE_AES) || \ - defined(PSA_WANT_KEY_TYPE_CAMELLIA) || \ - defined(PSA_WANT_KEY_TYPE_DES)) -#error "PSA_WANT_ALG_CMAC defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \ - !(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) -#error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_ECDSA) && \ - !(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) -#error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_GCM) && \ - !(defined(PSA_WANT_KEY_TYPE_AES) || \ - defined(PSA_WANT_KEY_TYPE_CAMELLIA)) -#error "PSA_WANT_ALG_GCM defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \ - !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) -#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \ - !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) -#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_RSA_OAEP) && \ - !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) -#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_ALG_RSA_PSS) && \ - !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) -#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites" -#endif - -#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ - defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \ - defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE)) && \ - !defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx defined, but not all prerequisites" -#endif - -#if (defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)) && \ - !defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) -#error "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx defined, but not all prerequisites" -#endif - -#if (defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) || \ - defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ - defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ - defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)) && \ - !defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) -#error "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_xxx defined, but not all prerequisites" -#endif - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) -#if defined(MBEDTLS_DEPRECATED_REMOVED) -#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR is deprecated and will be removed in a \ - future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx \ - symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE" -#elif defined(MBEDTLS_DEPRECATED_WARNING) -#warning "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR is deprecated and will be removed in a \ - future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx \ - symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE" -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR */ - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) -#if defined(MBEDTLS_DEPRECATED_REMOVED) -#error "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR is deprecated and will be removed in a \ - future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx \ - symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE" -#elif defined(MBEDTLS_DEPRECATED_WARNING) -#warning "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR is deprecated and will be removed in a \ - future version of Mbed TLS. Please switch to new PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_xxx \ - symbols, where xxx can be: USE, IMPORT, EXPORT, GENERATE, DERIVE" -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */ - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE) -#error "PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE defined, but feature is not supported" -#endif - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE) -#error "PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE defined, but feature is not supported" -#endif - -#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) && \ - !defined(PSA_WANT_ALG_SHA_256) -#error "PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS defined, but not all prerequisites" -#endif - -#endif /* MBEDTLS_CHECK_CRYPTO_CONFIG_H */ diff --git a/vendor/mbedtls/library/cipher.c b/vendor/mbedtls/library/cipher.c deleted file mode 100644 index f9d46213d..000000000 --- a/vendor/mbedtls/library/cipher.c +++ /dev/null @@ -1,1712 +0,0 @@ -/** - * \file cipher.c - * - * \brief Generic cipher wrapper for Mbed TLS - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_CIPHER_C) - -#include "mbedtls/cipher.h" -#include "cipher_invasive.h" -#include "cipher_wrap.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/constant_time.h" -#include "constant_time_internal.h" - -#include -#include - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_CMAC_C) -#include "mbedtls/cmac.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) -#include "psa/crypto.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_NIST_KW_C) -#include "mbedtls/nist_kw.h" -#endif - -#include "mbedtls/platform.h" - -static int supported_init = 0; - -static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base( - const mbedtls_cipher_info_t *info) -{ - return mbedtls_cipher_base_lookup_table[info->base_idx]; -} - -const int *mbedtls_cipher_list(void) -{ - const mbedtls_cipher_definition_t *def; - int *type; - - if (!supported_init) { - def = mbedtls_cipher_definitions; - type = mbedtls_cipher_supported; - - while (def->type != 0) { - *type++ = (*def++).type; - } - - *type = 0; - - supported_init = 1; - } - - return mbedtls_cipher_supported; -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( - const mbedtls_cipher_type_t cipher_type) -{ - const mbedtls_cipher_definition_t *def; - - for (def = mbedtls_cipher_definitions; def->info != NULL; def++) { - if (def->type == cipher_type) { - return def->info; - } - } - - return NULL; -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( - const char *cipher_name) -{ - const mbedtls_cipher_definition_t *def; - - if (NULL == cipher_name) { - return NULL; - } - - for (def = mbedtls_cipher_definitions; def->info != NULL; def++) { - if (!strcmp(def->info->name, cipher_name)) { - return def->info; - } - } - - return NULL; -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( - const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode) -{ - const mbedtls_cipher_definition_t *def; - - for (def = mbedtls_cipher_definitions; def->info != NULL; def++) { - if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id && - mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen && - def->info->mode == mode) { - return def->info; - } - } - - return NULL; -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) -static inline psa_key_type_t mbedtls_psa_translate_cipher_type( - mbedtls_cipher_type_t cipher) -{ - switch (cipher) { - case MBEDTLS_CIPHER_AES_128_CCM: - case MBEDTLS_CIPHER_AES_192_CCM: - case MBEDTLS_CIPHER_AES_256_CCM: - case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG: - case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG: - case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG: - case MBEDTLS_CIPHER_AES_128_GCM: - case MBEDTLS_CIPHER_AES_192_GCM: - case MBEDTLS_CIPHER_AES_256_GCM: - case MBEDTLS_CIPHER_AES_128_CBC: - case MBEDTLS_CIPHER_AES_192_CBC: - case MBEDTLS_CIPHER_AES_256_CBC: - case MBEDTLS_CIPHER_AES_128_ECB: - case MBEDTLS_CIPHER_AES_192_ECB: - case MBEDTLS_CIPHER_AES_256_ECB: - return PSA_KEY_TYPE_AES; - - /* ARIA not yet supported in PSA. */ - /* case MBEDTLS_CIPHER_ARIA_128_CCM: - case MBEDTLS_CIPHER_ARIA_192_CCM: - case MBEDTLS_CIPHER_ARIA_256_CCM: - case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG: - case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG: - case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG: - case MBEDTLS_CIPHER_ARIA_128_GCM: - case MBEDTLS_CIPHER_ARIA_192_GCM: - case MBEDTLS_CIPHER_ARIA_256_GCM: - case MBEDTLS_CIPHER_ARIA_128_CBC: - case MBEDTLS_CIPHER_ARIA_192_CBC: - case MBEDTLS_CIPHER_ARIA_256_CBC: - return( PSA_KEY_TYPE_ARIA ); */ - - default: - return 0; - } -} - -static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode( - mbedtls_cipher_mode_t mode, size_t taglen) -{ - switch (mode) { - case MBEDTLS_MODE_ECB: - return PSA_ALG_ECB_NO_PADDING; - case MBEDTLS_MODE_GCM: - return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen); - case MBEDTLS_MODE_CCM: - return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen); - case MBEDTLS_MODE_CCM_STAR_NO_TAG: - return PSA_ALG_CCM_STAR_NO_TAG; - case MBEDTLS_MODE_CBC: - if (taglen == 0) { - return PSA_ALG_CBC_NO_PADDING; - } else { - return 0; - } - default: - return 0; - } -} -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); -} - -void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - if (ctx->cipher_ctx != NULL) { - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - if (cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED) { - /* xxx_free() doesn't allow to return failures. */ - (void) psa_destroy_key(cipher_psa->slot); - } - - mbedtls_zeroize_and_free(cipher_psa, sizeof(*cipher_psa)); - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t)); - return; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_CMAC_C) - if (ctx->cmac_ctx) { - mbedtls_zeroize_and_free(ctx->cmac_ctx, - sizeof(mbedtls_cmac_context_t)); - } -#endif - - if (ctx->cipher_ctx) { - mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx); - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t)); -} - -int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info) -{ - if (cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); - - if (mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func != NULL) { - ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func(); - if (ctx->cipher_ctx == NULL) { - return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; - } - } - - ctx->cipher_info = cipher_info; - - return 0; -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info, - size_t taglen) -{ - psa_algorithm_t alg; - mbedtls_cipher_context_psa *cipher_psa; - - if (NULL == cipher_info || NULL == ctx) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - /* Check that the underlying cipher mode and cipher type are - * supported by the underlying PSA Crypto implementation. */ - alg = mbedtls_psa_translate_cipher_mode(((mbedtls_cipher_mode_t) cipher_info->mode), taglen); - if (alg == 0) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - if (mbedtls_psa_translate_cipher_type(((mbedtls_cipher_type_t) cipher_info->type)) == 0) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); - - cipher_psa = mbedtls_calloc(1, sizeof(mbedtls_cipher_context_psa)); - if (cipher_psa == NULL) { - return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; - } - cipher_psa->alg = alg; - ctx->cipher_ctx = cipher_psa; - ctx->cipher_info = cipher_info; - ctx->psa_enabled = 1; - return 0; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, - const unsigned char *key, - int key_bitlen, - const mbedtls_operation_t operation) -{ - if (operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } -#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) && - MBEDTLS_DECRYPT == operation) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - size_t const key_bytelen = ((size_t) key_bitlen + 7) / 8; - - psa_status_t status; - psa_key_type_t key_type; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - - /* PSA Crypto API only accepts byte-aligned keys. */ - if (key_bitlen % 8 != 0) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - /* Don't allow keys to be set multiple times. */ - if (cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - key_type = mbedtls_psa_translate_cipher_type( - ((mbedtls_cipher_type_t) ctx->cipher_info->type)); - if (key_type == 0) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - psa_set_key_type(&attributes, key_type); - - /* Mbed TLS' cipher layer doesn't enforce the mode of operation - * (encrypt vs. decrypt): it is possible to setup a key for encryption - * and use it for AEAD decryption. Until tests relying on this - * are changed, allow any usage in PSA. */ - psa_set_key_usage_flags(&attributes, - PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, cipher_psa->alg); - - status = psa_import_key(&attributes, key, key_bytelen, - &cipher_psa->slot); - switch (status) { - case PSA_SUCCESS: - break; - case PSA_ERROR_INSUFFICIENT_MEMORY: - return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - default: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - /* Indicate that we own the key slot and need to - * destroy it in mbedtls_cipher_free(). */ - cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED; - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - return 0; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 && - (int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - /* - * For OFB, CFB and CTR mode always use the encryption key schedule - */ - if (MBEDTLS_ENCRYPT == operation || - MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key, - ctx->key_bitlen); - } - - if (MBEDTLS_DECRYPT == operation) { - return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key, - ctx->key_bitlen); - } -#else - if (operation == MBEDTLS_ENCRYPT || operation == MBEDTLS_DECRYPT) { - return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key, - ctx->key_bitlen); - } -#endif - - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; -} - -int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, - size_t iv_len) -{ - size_t actual_iv_size; - - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - /* avoid buffer overflow in ctx->iv */ - if (iv_len > MBEDTLS_MAX_IV_LENGTH) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) { - actual_iv_size = iv_len; - } else { - actual_iv_size = mbedtls_cipher_info_get_iv_size(ctx->cipher_info); - - /* avoid reading past the end of input buffer */ - if (actual_iv_size > iv_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - } - -#if defined(MBEDTLS_CHACHA20_C) - if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20) { - /* Even though the actual_iv_size is overwritten with a correct value - * of 12 from the cipher info, return an error to indicate that - * the input iv_len is wrong. */ - if (iv_len != 12) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (0 != mbedtls_chacha20_starts((mbedtls_chacha20_context *) ctx->cipher_ctx, - iv, - 0U)) { /* Initial counter value */ - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - } -#if defined(MBEDTLS_CHACHAPOLY_C) - if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 && - iv_len != 12) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } -#endif -#endif - -#if defined(MBEDTLS_GCM_C) - if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx, - ctx->operation, - iv, iv_len); - } -#endif - -#if defined(MBEDTLS_CCM_C) - if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - int set_lengths_result; - int ccm_star_mode; - - set_lengths_result = mbedtls_ccm_set_lengths( - (mbedtls_ccm_context *) ctx->cipher_ctx, - 0, 0, 0); - if (set_lengths_result != 0) { - return set_lengths_result; - } - - if (ctx->operation == MBEDTLS_DECRYPT) { - ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT; - } else if (ctx->operation == MBEDTLS_ENCRYPT) { - ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT; - } else { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return mbedtls_ccm_starts((mbedtls_ccm_context *) ctx->cipher_ctx, - ccm_star_mode, - iv, iv_len); - } -#endif - - if (actual_iv_size != 0) { - memcpy(ctx->iv, iv, actual_iv_size); - ctx->iv_size = actual_iv_size; - } - - return 0; -} - -int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx) -{ - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* We don't support resetting PSA-based - * cipher contexts, yet. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - ctx->unprocessed_len = 0; - - return 0; -} - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len) -{ - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_GCM_C) - if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx, - ad, ad_len); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { - int result; - mbedtls_chachapoly_mode_t mode; - - mode = (ctx->operation == MBEDTLS_ENCRYPT) - ? MBEDTLS_CHACHAPOLY_ENCRYPT - : MBEDTLS_CHACHAPOLY_DECRYPT; - - result = mbedtls_chachapoly_starts((mbedtls_chachapoly_context *) ctx->cipher_ctx, - ctx->iv, - mode); - if (result != 0) { - return result; - } - - return mbedtls_chachapoly_update_aad((mbedtls_chachapoly_context *) ctx->cipher_ctx, - ad, ad_len); - } -#endif - - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input, - size_t ilen, unsigned char *output, size_t *olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t block_size; - - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - *olen = 0; - block_size = mbedtls_cipher_get_block_size(ctx); - if (0 == block_size) { - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } - - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) { - if (ilen != block_size) { - return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; - } - - *olen = ilen; - - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx, - ctx->operation, input, - output))) { - return ret; - } - - return 0; - } - -#if defined(MBEDTLS_GCM_C) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) { - return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx, - input, ilen, - output, ilen, olen); - } -#endif - -#if defined(MBEDTLS_CCM_C) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) { - return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx, - input, ilen, - output, ilen, olen); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) { - *olen = ilen; - return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx, - ilen, input, output); - } -#endif - - if (input == output && - (ctx->unprocessed_len != 0 || ilen % block_size)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CBC) { - size_t copy_len = 0; - - /* - * If there is not enough data for a full block, cache it. - */ - if ((ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && - ilen <= block_size - ctx->unprocessed_len) || - (ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && - ilen < block_size - ctx->unprocessed_len) || - (ctx->operation == MBEDTLS_ENCRYPT && - ilen < block_size - ctx->unprocessed_len)) { - memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, - ilen); - - ctx->unprocessed_len += ilen; - return 0; - } - - /* - * Process cached data first - */ - if (0 != ctx->unprocessed_len) { - copy_len = block_size - ctx->unprocessed_len; - - memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, - copy_len); - - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, - ctx->operation, - block_size, ctx->iv, - ctx-> - unprocessed_data, - output))) { - return ret; - } - - *olen += block_size; - output += block_size; - ctx->unprocessed_len = 0; - - input += copy_len; - ilen -= copy_len; - } - - /* - * Cache final, incomplete block - */ - if (0 != ilen) { - /* Encryption: only cache partial blocks - * Decryption w/ padding: always keep at least one whole block - * Decryption w/o padding: only cache partial blocks - */ - copy_len = ilen % block_size; - if (copy_len == 0 && - ctx->operation == MBEDTLS_DECRYPT && - NULL != ctx->add_padding) { - copy_len = block_size; - } - - memcpy(ctx->unprocessed_data, &(input[ilen - copy_len]), - copy_len); - - ctx->unprocessed_len += copy_len; - ilen -= copy_len; - } - - /* - * Process remaining full blocks - */ - if (ilen) { - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, - ctx->operation, - ilen, ctx->iv, - input, - output))) { - return ret; - } - - *olen += ilen; - } - - return 0; - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CFB) { - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cfb_func(ctx->cipher_ctx, - ctx->operation, ilen, - &ctx->unprocessed_len, - ctx->iv, - input, output))) { - return ret; - } - - *olen = ilen; - - return 0; - } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_OFB) { - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ofb_func(ctx->cipher_ctx, - ilen, - &ctx->unprocessed_len, - ctx->iv, - input, output))) { - return ret; - } - - *olen = ilen; - - return 0; - } -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CTR) { - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx, - ilen, - &ctx->unprocessed_len, - ctx->iv, - ctx->unprocessed_data, - input, output))) { - return ret; - } - - *olen = ilen; - - return 0; - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_XTS) { - if (ctx->unprocessed_len > 0) { - /* We can only process an entire data unit at a time. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - ret = mbedtls_cipher_get_base(ctx->cipher_info)->xts_func(ctx->cipher_ctx, - ctx->operation, - ilen, - ctx->iv, - input, - output); - if (ret != 0) { - return ret; - } - - *olen = ilen; - - return 0; - } -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) { - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx, - ilen, input, - output))) { - return ret; - } - - *olen = ilen; - - return 0; - } -#endif /* MBEDTLS_CIPHER_MODE_STREAM */ - - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) -/* - * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len - */ -static void add_pkcs_padding(unsigned char *output, size_t output_len, - size_t data_len) -{ - size_t padding_len = output_len - data_len; - unsigned char i; - - for (i = 0; i < padding_len; i++) { - output[data_len + i] = (unsigned char) padding_len; - } -} - -/* - * Get the length of the PKCS7 padding. - * - * Note: input_len must be the block size of the cipher. - */ -MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input, - size_t input_len, - size_t *data_len, - size_t *invalid_padding) -{ - size_t i, pad_idx; - unsigned char padding_len; - - if (NULL == input || NULL == data_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - padding_len = input[input_len - 1]; - - mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len); - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0)); - - /* The number of bytes checked must be independent of padding_len, - * so pick input_len, which is usually 8 or 16 (one block) */ - pad_idx = input_len - padding_len; - for (i = 0; i < input_len; i++) { - mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx); - mbedtls_ct_condition_t different = mbedtls_ct_uint_ne(input[i], padding_len); - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different)); - } - - /* If the padding is invalid, set the output length to 0 */ - *data_len = mbedtls_ct_if(bad, 0, input_len - padding_len); - - *invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX); - return 0; -} -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ - -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) -/* - * One and zeros padding: fill with 80 00 ... 00 - */ -static void add_one_and_zeros_padding(unsigned char *output, - size_t output_len, size_t data_len) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - output[data_len] = 0x80; - for (i = 1; i < padding_len; i++) { - output[data_len + i] = 0x00; - } -} - -static int get_one_and_zeros_padding(unsigned char *input, size_t input_len, - size_t *data_len, size_t *invalid_padding) -{ - if (NULL == input || NULL == data_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - mbedtls_ct_condition_t in_padding = MBEDTLS_CT_TRUE; - mbedtls_ct_condition_t bad = MBEDTLS_CT_TRUE; - - *data_len = 0; - - for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) { - mbedtls_ct_condition_t is_nonzero = mbedtls_ct_bool(input[i]); - - mbedtls_ct_condition_t hit_first_nonzero = mbedtls_ct_bool_and(is_nonzero, in_padding); - - *data_len = mbedtls_ct_size_if(hit_first_nonzero, i, *data_len); - - bad = mbedtls_ct_bool_if(hit_first_nonzero, mbedtls_ct_uint_ne(input[i], 0x80), bad); - - in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero)); - } - - *invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX); - return 0; -} -#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) -/* - * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length - */ -static void add_zeros_and_len_padding(unsigned char *output, - size_t output_len, size_t data_len) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - for (i = 1; i < padding_len; i++) { - output[data_len + i - 1] = 0x00; - } - output[output_len - 1] = (unsigned char) padding_len; -} - -static int get_zeros_and_len_padding(unsigned char *input, size_t input_len, - size_t *data_len, size_t *invalid_padding) -{ - size_t i, pad_idx; - unsigned char padding_len; - mbedtls_ct_condition_t bad; - - if (NULL == input || NULL == data_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad = mbedtls_ct_uint_gt(padding_len, input_len); - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0)); - - /* The number of bytes checked must be independent of padding_len */ - pad_idx = input_len - padding_len; - for (i = 0; i < input_len - 1; i++) { - mbedtls_ct_condition_t is_padding = mbedtls_ct_uint_ge(i, pad_idx); - mbedtls_ct_condition_t nonzero_pad_byte; - nonzero_pad_byte = mbedtls_ct_bool_if_else_0(is_padding, mbedtls_ct_bool(input[i])); - bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte); - } - - *invalid_padding = mbedtls_ct_size_if_else_0(bad, SIZE_MAX); - return 0; -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) -/* - * Zero padding: fill with 00 ... 00 - */ -static void add_zeros_padding(unsigned char *output, - size_t output_len, size_t data_len) -{ - memset(output + data_len, 0, output_len - data_len); -} - -static int get_zeros_padding(unsigned char *input, size_t input_len, - size_t *data_len, size_t *invalid_padding) -{ - size_t i; - mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done; - - if (NULL == input || NULL == data_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - *data_len = 0; - for (i = input_len; i > 0; i--) { - prev_done = done; - done = mbedtls_ct_bool_or(done, mbedtls_ct_uint_ne(input[i-1], 0)); - *data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len); - } - - *invalid_padding = 0; - return 0; -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ - -/* - * No padding: don't pad :) - * - * There is no add_padding function (check for NULL in mbedtls_cipher_finish) - * but a trivial get_padding function - */ -static int get_no_padding(unsigned char *input, size_t input_len, - size_t *data_len, size_t *invalid_padding) -{ - if (NULL == input || NULL == data_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - *data_len = input_len; - *invalid_padding = 0; - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen, - size_t *invalid_padding) -{ - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - *olen = 0; - *invalid_padding = 0; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /* CBC mode requires padding so we make sure a call to - * mbedtls_cipher_set_padding_mode has been done successfully. */ - if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - if (ctx->get_padding == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - } -#endif - - if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - return 0; - } - - if ((MBEDTLS_CIPHER_CHACHA20 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) || - (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) { - return 0; - } - - if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - if (ctx->unprocessed_len != 0) { - return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; - } - - return 0; - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - int ret = 0; - - if (MBEDTLS_ENCRYPT == ctx->operation) { - /* check for 'no padding' mode */ - if (NULL == ctx->add_padding) { - if (0 != ctx->unprocessed_len) { - return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; - } - - return 0; - } - - ctx->add_padding(ctx->unprocessed_data, mbedtls_cipher_get_iv_size(ctx), - ctx->unprocessed_len); - } else if (mbedtls_cipher_get_block_size(ctx) != ctx->unprocessed_len) { - /* - * For decrypt operations, expect a full block, - * or an empty block if no padding - */ - if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) { - return 0; - } - - return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; - } - - /* cipher block */ - if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, - ctx->operation, - mbedtls_cipher_get_block_size( - ctx), - ctx->iv, - ctx->unprocessed_data, - output))) { - return ret; - } - - /* Set output size for decryption */ - if (MBEDTLS_DECRYPT == ctx->operation) { - return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx), - olen, invalid_padding); - } - - /* Set output size for encryption */ - *olen = mbedtls_cipher_get_block_size(ctx); - return 0; - } -#else - ((void) output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -} - -int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen) -{ - size_t invalid_padding = 0; - int ret = mbedtls_cipher_finish_padded(ctx, output, olen, - &invalid_padding); - if (ret == 0) { - ret = mbedtls_ct_error_if_else_0(invalid_padding, - MBEDTLS_ERR_CIPHER_INVALID_PADDING); - } - return ret; -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, - mbedtls_cipher_padding_t mode) -{ - if (NULL == ctx->cipher_info || - MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* While PSA Crypto knows about CBC padding - * schemes, we currently don't make them - * accessible through the cipher layer. */ - if (mode != MBEDTLS_PADDING_NONE) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - return 0; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - switch (mode) { -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - case MBEDTLS_PADDING_PKCS7: - ctx->add_padding = add_pkcs_padding; - ctx->get_padding = mbedtls_get_pkcs_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) - case MBEDTLS_PADDING_ONE_AND_ZEROS: - ctx->add_padding = add_one_and_zeros_padding; - ctx->get_padding = get_one_and_zeros_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) - case MBEDTLS_PADDING_ZEROS_AND_LEN: - ctx->add_padding = add_zeros_and_len_padding; - ctx->get_padding = get_zeros_and_len_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) - case MBEDTLS_PADDING_ZEROS: - ctx->add_padding = add_zeros_padding; - ctx->get_padding = get_zeros_padding; - break; -#endif - case MBEDTLS_PADDING_NONE: - ctx->add_padding = NULL; - ctx->get_padding = get_no_padding; - break; - - default: - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len) -{ - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (MBEDTLS_ENCRYPT != ctx->operation) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_GCM_C) - if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - size_t output_length; - /* The code here doesn't yet support alternative implementations - * that can delay up to a block of output. */ - return mbedtls_gcm_finish((mbedtls_gcm_context *) ctx->cipher_ctx, - NULL, 0, &output_length, - tag, tag_len); - } -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { - /* Don't allow truncated MAC for Poly1305 */ - if (tag_len != 16U) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return mbedtls_chachapoly_finish( - (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag); - } -#endif - - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -} - -int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len) -{ - unsigned char check_tag[16]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ctx->cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (MBEDTLS_DECRYPT != ctx->operation) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* While PSA Crypto has an API for multipart - * operations, we currently don't make it - * accessible through the cipher layer. */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - /* Status to return on a non-authenticated algorithm. */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - -#if defined(MBEDTLS_GCM_C) - if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - size_t output_length; - /* The code here doesn't yet support alternative implementations - * that can delay up to a block of output. */ - - if (tag_len > sizeof(check_tag)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (0 != (ret = mbedtls_gcm_finish( - (mbedtls_gcm_context *) ctx->cipher_ctx, - NULL, 0, &output_length, - check_tag, tag_len))) { - return ret; - } - - /* Check the tag in "constant-time" */ - if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - goto exit; - } - } -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { - /* Don't allow truncated MAC for Poly1305 */ - if (tag_len != sizeof(check_tag)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - ret = mbedtls_chachapoly_finish( - (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag); - if (ret != 0) { - return ret; - } - - /* Check the tag in "constant-time" */ - if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - goto exit; - } - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - -exit: - mbedtls_platform_zeroize(check_tag, tag_len); - return ret; -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - -/* - * Packet-oriented wrapper for non-AEAD modes - */ -int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t finish_olen; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; - size_t part_len; - - if (ctx->operation == MBEDTLS_DECRYPT) { - status = psa_cipher_decrypt_setup(&cipher_op, - cipher_psa->slot, - cipher_psa->alg); - } else if (ctx->operation == MBEDTLS_ENCRYPT) { - status = psa_cipher_encrypt_setup(&cipher_op, - cipher_psa->slot, - cipher_psa->alg); - } else { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - /* In the following, we can immediately return on an error, - * because the PSA Crypto API guarantees that cipher operations - * are terminated by unsuccessful calls to psa_cipher_update(), - * and by any call to psa_cipher_finish(). */ - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - - if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) { - status = psa_cipher_set_iv(&cipher_op, iv, iv_len); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - } - - status = psa_cipher_update(&cipher_op, - input, ilen, - output, ilen, olen); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - - status = psa_cipher_finish(&cipher_op, - output + *olen, ilen - *olen, - &part_len); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - - *olen += part_len; - return 0; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - - if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) { - return ret; - } - - if ((ret = mbedtls_cipher_reset(ctx)) != 0) { - return ret; - } - - if ((ret = mbedtls_cipher_update(ctx, input, ilen, - output, olen)) != 0) { - return ret; - } - - size_t invalid_padding = 0; - if ((ret = mbedtls_cipher_finish_padded(ctx, output + *olen, - &finish_olen, - &invalid_padding)) != 0) { - return ret; - } - *olen += finish_olen; - - ret = mbedtls_ct_error_if_else_0(invalid_padding, - MBEDTLS_ERR_CIPHER_INVALID_PADDING); - return ret; -} - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/* - * Packet-oriented encryption for AEAD modes: internal function used by - * mbedtls_cipher_auth_encrypt_ext(). - */ -static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - - /* PSA Crypto API always writes the authentication tag - * at the end of the encrypted message. */ - if (output == NULL || tag != output + ilen) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - status = psa_aead_encrypt(cipher_psa->slot, - cipher_psa->alg, - iv, iv_len, - ad, ad_len, - input, ilen, - output, ilen + tag_len, olen); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - - *olen -= tag_len; - return 0; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_GCM_C) - if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - *olen = ilen; - return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, - ilen, iv, iv_len, ad, ad_len, - input, output, tag_len, tag); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - *olen = ilen; - return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, input, output, - tag, tag_len); - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) || - (tag_len != 16U)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - *olen = ilen; - return mbedtls_chachapoly_encrypt_and_tag(ctx->cipher_ctx, - ilen, iv, ad, ad_len, input, output, tag); - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -} - -/* - * Packet-oriented encryption for AEAD modes: internal function used by - * mbedtls_cipher_auth_encrypt_ext(). - */ -static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ctx->psa_enabled == 1) { - /* As in the non-PSA case, we don't check that - * a key has been set. If not, the key slot will - * still be in its default state of 0, which is - * guaranteed to be invalid, hence the PSA-call - * below will gracefully fail. */ - mbedtls_cipher_context_psa * const cipher_psa = - (mbedtls_cipher_context_psa *) ctx->cipher_ctx; - - psa_status_t status; - - /* PSA Crypto API always writes the authentication tag - * at the end of the encrypted message. */ - if (input == NULL || tag != input + ilen) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - status = psa_aead_decrypt(cipher_psa->slot, - cipher_psa->alg, - iv, iv_len, - ad, ad_len, - input, ilen + tag_len, - output, ilen, olen); - if (status == PSA_ERROR_INVALID_SIGNATURE) { - return MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } else if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - - return 0; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_GCM_C) - if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - *olen = ilen; - ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - tag, tag_len, input, output); - - if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - return ret; - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - *olen = ilen; - ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - input, output, tag, tag_len); - - if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - return ret; - } -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* ChachaPoly has fixed length nonce and MAC (tag) */ - if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) || - (tag_len != 16U)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - *olen = ilen; - ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen, - iv, ad, ad_len, tag, input, output); - - if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - return ret; - } -#endif /* MBEDTLS_CHACHAPOLY_C */ - - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -} -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C) -/* - * Packet-oriented encryption for AEAD/NIST_KW: public function. - */ -int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t output_len, - size_t *olen, size_t tag_len) -{ -#if defined(MBEDTLS_NIST_KW_C) - if ( -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - ctx->psa_enabled == 0 && -#endif - (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) { - mbedtls_nist_kw_mode_t mode = - (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ? - MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - - /* There is no iv, tag or ad associated with KW and KWP, - * so these length should be 0 as documented. */ - if (iv_len != 0 || tag_len != 0 || ad_len != 0) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - (void) iv; - (void) ad; - - return mbedtls_nist_kw_wrap(ctx->cipher_ctx, mode, input, ilen, - output, olen, output_len); - } -#endif /* MBEDTLS_NIST_KW_C */ - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) - /* AEAD case: check length before passing on to shared function */ - if (output_len < ilen + tag_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - int ret = mbedtls_cipher_aead_encrypt(ctx, iv, iv_len, ad, ad_len, - input, ilen, output, olen, - output + ilen, tag_len); - *olen += tag_len; - return ret; -#else - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ -} - -/* - * Packet-oriented decryption for AEAD/NIST_KW: public function. - */ -int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t output_len, - size_t *olen, size_t tag_len) -{ -#if defined(MBEDTLS_NIST_KW_C) - if ( -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) - ctx->psa_enabled == 0 && -#endif - (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || - MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) { - mbedtls_nist_kw_mode_t mode = - (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ? - MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - - /* There is no iv, tag or ad associated with KW and KWP, - * so these length should be 0 as documented. */ - if (iv_len != 0 || tag_len != 0 || ad_len != 0) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - (void) iv; - (void) ad; - - return mbedtls_nist_kw_unwrap(ctx->cipher_ctx, mode, input, ilen, - output, olen, output_len); - } -#endif /* MBEDTLS_NIST_KW_C */ - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) - /* AEAD case: check length before passing on to shared function */ - if (ilen < tag_len || output_len < ilen - tag_len) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len, - input, ilen - tag_len, output, olen, - input + ilen - tag_len, tag_len); -#else - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ -} -#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */ - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/vendor/mbedtls/library/cipher_invasive.h b/vendor/mbedtls/library/cipher_invasive.h deleted file mode 100644 index e82a0a7f9..000000000 --- a/vendor/mbedtls/library/cipher_invasive.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * \file cipher_invasive.h - * - * \brief Cipher module: interfaces for invasive testing only. - * - * The interfaces in this file are intended for testing purposes only. - * They SHOULD NOT be made available in library integrations except when - * building the library for testing. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_CIPHER_INVASIVE_H -#define MBEDTLS_CIPHER_INVASIVE_H - -#include "common.h" - -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_CIPHER_C) - -MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input, - size_t input_len, - size_t *data_len, - size_t *invalid_padding); - -#endif - -#endif /* MBEDTLS_CIPHER_INVASIVE_H */ diff --git a/vendor/mbedtls/library/cipher_wrap.c b/vendor/mbedtls/library/cipher_wrap.c deleted file mode 100644 index b4c21ee39..000000000 --- a/vendor/mbedtls/library/cipher_wrap.c +++ /dev/null @@ -1,2482 +0,0 @@ -/** - * \file cipher_wrap.c - * - * \brief Generic cipher wrapper for Mbed TLS - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_CIPHER_C) - -#include "cipher_wrap.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_NIST_KW_C) -#include "mbedtls/nist_kw.h" -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#include -#endif - -#include "mbedtls/platform.h" - -enum mbedtls_cipher_base_index { -#if defined(MBEDTLS_AES_C) - MBEDTLS_CIPHER_BASE_INDEX_AES, -#endif -#if defined(MBEDTLS_ARIA_C) - MBEDTLS_CIPHER_BASE_INDEX_ARIA, -#endif -#if defined(MBEDTLS_CAMELLIA_C) - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA, -#endif -#if defined(MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA) - MBEDTLS_CIPHER_BASE_INDEX_CCM_AES, -#endif -#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_ARIA_C) - MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA, -#endif -#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_CAMELLIA_C) - MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA, -#endif -#if defined(MBEDTLS_CHACHA20_C) - MBEDTLS_CIPHER_BASE_INDEX_CHACHA20_BASE, -#endif -#if defined(MBEDTLS_CHACHAPOLY_C) - MBEDTLS_CIPHER_BASE_INDEX_CHACHAPOLY_BASE, -#endif -#if defined(MBEDTLS_DES_C) - MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3, -#endif -#if defined(MBEDTLS_DES_C) - MBEDTLS_CIPHER_BASE_INDEX_DES_EDE, -#endif -#if defined(MBEDTLS_DES_C) - MBEDTLS_CIPHER_BASE_INDEX_DES, -#endif -#if defined(MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA) - MBEDTLS_CIPHER_BASE_INDEX_GCM_AES, -#endif -#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_ARIA_C) - MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA, -#endif -#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_CAMELLIA_C) - MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA, -#endif -#if defined(MBEDTLS_NIST_KW_C) - MBEDTLS_CIPHER_BASE_INDEX_KW_AES, -#endif -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - MBEDTLS_CIPHER_BASE_INDEX_NULL_BASE, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) && defined(MBEDTLS_AES_C) - MBEDTLS_CIPHER_BASE_INDEX_XTS_AES, -#endif - /* Prevent compile failure due to empty enum */ - MBEDTLS_CIPHER_BASE_PREVENT_EMPTY_ENUM -}; - -#if defined(MBEDTLS_GCM_C) && \ - (defined(MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA) || \ - defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)) -/* shared by all GCM ciphers */ -static void *gcm_ctx_alloc(void) -{ - void *ctx = mbedtls_calloc(1, sizeof(mbedtls_gcm_context)); - - if (ctx != NULL) { - mbedtls_gcm_init((mbedtls_gcm_context *) ctx); - } - - return ctx; -} - -static void gcm_ctx_free(void *ctx) -{ - mbedtls_gcm_free(ctx); - mbedtls_free(ctx); -} -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) && \ - (defined(MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA) || \ - defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)) -/* shared by all CCM ciphers */ -static void *ccm_ctx_alloc(void) -{ - void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ccm_context)); - - if (ctx != NULL) { - mbedtls_ccm_init((mbedtls_ccm_context *) ctx); - } - - return ctx; -} - -static void ccm_ctx_free(void *ctx) -{ - mbedtls_ccm_free(ctx); - mbedtls_free(ctx); -} -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_AES_C) - -static int aes_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_aes_crypt_ecb((mbedtls_aes_context *) ctx, operation, input, output); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aes_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output) -{ - return mbedtls_aes_crypt_cbc((mbedtls_aes_context *) ctx, operation, length, iv, input, - output); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aes_crypt_cfb128_wrap(void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_aes_crypt_cfb128((mbedtls_aes_context *) ctx, operation, length, iv_off, iv, - input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static int aes_crypt_ofb_wrap(void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, unsigned char *output) -{ - return mbedtls_aes_crypt_ofb((mbedtls_aes_context *) ctx, length, iv_off, - iv, input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aes_crypt_ctr_wrap(void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_aes_crypt_ctr((mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, - stream_block, input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int aes_crypt_xts_wrap(void *ctx, mbedtls_operation_t operation, - size_t length, - const unsigned char data_unit[16], - const unsigned char *input, - unsigned char *output) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - int mode; - - switch (operation) { - case MBEDTLS_ENCRYPT: - mode = MBEDTLS_AES_ENCRYPT; - break; - case MBEDTLS_DECRYPT: - mode = MBEDTLS_AES_DECRYPT; - break; - default: - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return mbedtls_aes_crypt_xts(xts_ctx, mode, length, - data_unit, input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_XTS */ - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -static int aes_setkey_dec_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_aes_setkey_dec((mbedtls_aes_context *) ctx, key, key_bitlen); -} -#endif - -static int aes_setkey_enc_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_aes_setkey_enc((mbedtls_aes_context *) ctx, key, key_bitlen); -} - -static void *aes_ctx_alloc(void) -{ - mbedtls_aes_context *aes = mbedtls_calloc(1, sizeof(mbedtls_aes_context)); - - if (aes == NULL) { - return NULL; - } - - mbedtls_aes_init(aes); - - return aes; -} - -static void aes_ctx_free(void *ctx) -{ - mbedtls_aes_free((mbedtls_aes_context *) ctx); - mbedtls_free(ctx); -} - -static const mbedtls_cipher_base_t aes_info = { - MBEDTLS_CIPHER_ID_AES, - aes_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aes_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aes_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - aes_crypt_ofb_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aes_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aes_setkey_enc_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - aes_setkey_dec_wrap, -#endif - aes_ctx_alloc, - aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_ecb_info = { - "AES-128-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_AES_128_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_ecb_info = { - "AES-192-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_AES_192_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -static const mbedtls_cipher_info_t aes_256_ecb_info = { - "AES-256-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_AES_256_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aes_128_cbc_info = { - "AES-128-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_AES_128_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_cbc_info = { - "AES-192-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_AES_192_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -static const mbedtls_cipher_info_t aes_256_cbc_info = { - "AES-256-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_AES_256_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aes_128_cfb128_info = { - "AES-128-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_AES_128_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_cfb128_info = { - "AES-192-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_AES_192_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -static const mbedtls_cipher_info_t aes_256_cfb128_info = { - "AES-256-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_AES_256_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_OFB) -static const mbedtls_cipher_info_t aes_128_ofb_info = { - "AES-128-OFB", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_OFB, - MBEDTLS_CIPHER_AES_128_OFB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_ofb_info = { - "AES-192-OFB", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_OFB, - MBEDTLS_CIPHER_AES_192_OFB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -static const mbedtls_cipher_info_t aes_256_ofb_info = { - "AES-256-OFB", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_OFB, - MBEDTLS_CIPHER_AES_256_OFB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_MODE_OFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aes_128_ctr_info = { - "AES-128-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_AES_128_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_ctr_info = { - "AES-192-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_AES_192_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; - -static const mbedtls_cipher_info_t aes_256_ctr_info = { - "AES-256-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_AES_256_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_XTS) -static int xts_aes_setkey_enc_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return mbedtls_aes_xts_setkey_enc(xts_ctx, key, key_bitlen); -} - -static int xts_aes_setkey_dec_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - return mbedtls_aes_xts_setkey_dec(xts_ctx, key, key_bitlen); -} - -static void *xts_aes_ctx_alloc(void) -{ - mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc(1, sizeof(*xts_ctx)); - - if (xts_ctx != NULL) { - mbedtls_aes_xts_init(xts_ctx); - } - - return xts_ctx; -} - -static void xts_aes_ctx_free(void *ctx) -{ - mbedtls_aes_xts_context *xts_ctx = ctx; - - if (xts_ctx == NULL) { - return; - } - - mbedtls_aes_xts_free(xts_ctx); - mbedtls_free(xts_ctx); -} - -static const mbedtls_cipher_base_t xts_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - aes_crypt_xts_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - xts_aes_setkey_enc_wrap, - xts_aes_setkey_dec_wrap, - xts_aes_ctx_alloc, - xts_aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_xts_info = { - "AES-128-XTS", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_XTS, - MBEDTLS_CIPHER_AES_128_XTS, - 0, - MBEDTLS_CIPHER_BASE_INDEX_XTS_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_256_xts_info = { - "AES-256-XTS", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 512 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_XTS, - MBEDTLS_CIPHER_AES_256_XTS, - 0, - MBEDTLS_CIPHER_BASE_INDEX_XTS_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_MODE_XTS */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_CCM_GCM_CAN_AES) -static int gcm_aes_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_gcm_setkey((mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen); -} -#endif /* MBEDTLS_GCM_C && MBEDTLS_CCM_GCM_CAN_AES */ - -#if defined(MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA) -static const mbedtls_cipher_base_t gcm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif -#if defined(MBEDTLS_GCM_C) - gcm_aes_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - gcm_aes_setkey_wrap, -#endif - gcm_ctx_alloc, - gcm_ctx_free, -#else - NULL, - NULL, - NULL, - NULL, -#endif /* MBEDTLS_GCM_C */ -}; -#endif /* MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA */ - -#if defined(MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA) -static const mbedtls_cipher_info_t aes_128_gcm_info = { - "AES-128-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_AES_128_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_gcm_info = { - "AES-192-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_AES_192_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_AES -}; - -static const mbedtls_cipher_info_t aes_256_gcm_info = { - "AES-256-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_AES_256_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA */ - -#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_CCM_GCM_CAN_AES) -static int ccm_aes_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_ccm_setkey((mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen); -} -#endif /* MBEDTLS_CCM_C && MBEDTLS_CCM_GCM_CAN_AES */ - -#if defined(MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA) -static const mbedtls_cipher_base_t ccm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif -#if defined(MBEDTLS_CCM_C) - ccm_aes_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - ccm_aes_setkey_wrap, -#endif - ccm_ctx_alloc, - ccm_ctx_free, -#else - NULL, - NULL, - NULL, - NULL, -#endif -}; -#endif /* MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA */ - -#if defined(MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA) -static const mbedtls_cipher_info_t aes_128_ccm_info = { - "AES-128-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_AES_128_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_ccm_info = { - "AES-192-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_AES_192_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_AES -}; - -static const mbedtls_cipher_info_t aes_256_ccm_info = { - "AES-256-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_AES_256_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA */ - -#if defined(MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_AES_VIA_LEGACY_OR_USE_PSA) -static const mbedtls_cipher_info_t aes_128_ccm_star_no_tag_info = { - "AES-128-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_ccm_star_no_tag_info = { - "AES-192-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_AES -}; - -static const mbedtls_cipher_info_t aes_256_ccm_star_no_tag_info = { - "AES-256-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_AES -}; -#endif -#endif /* MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_AES_VIA_LEGACY_OR_USE_PSA */ - - -#if defined(MBEDTLS_CAMELLIA_C) - -static int camellia_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_camellia_crypt_ecb((mbedtls_camellia_context *) ctx, operation, input, - output); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int camellia_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_camellia_crypt_cbc((mbedtls_camellia_context *) ctx, operation, length, iv, - input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int camellia_crypt_cfb128_wrap(void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_camellia_crypt_cfb128((mbedtls_camellia_context *) ctx, operation, length, - iv_off, iv, input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int camellia_crypt_ctr_wrap(void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_camellia_crypt_ctr((mbedtls_camellia_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -static int camellia_setkey_dec_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_camellia_setkey_dec((mbedtls_camellia_context *) ctx, key, key_bitlen); -} -#endif - -static int camellia_setkey_enc_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_camellia_setkey_enc((mbedtls_camellia_context *) ctx, key, key_bitlen); -} - -static void *camellia_ctx_alloc(void) -{ - mbedtls_camellia_context *ctx; - ctx = mbedtls_calloc(1, sizeof(mbedtls_camellia_context)); - - if (ctx == NULL) { - return NULL; - } - - mbedtls_camellia_init(ctx); - - return ctx; -} - -static void camellia_ctx_free(void *ctx) -{ - mbedtls_camellia_free((mbedtls_camellia_context *) ctx); - mbedtls_free(ctx); -} - -static const mbedtls_cipher_base_t camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - camellia_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - camellia_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - camellia_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - camellia_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - camellia_setkey_enc_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - camellia_setkey_dec_wrap, -#endif - camellia_ctx_alloc, - camellia_ctx_free -}; - -static const mbedtls_cipher_info_t camellia_128_ecb_info = { - "CAMELLIA-128-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_CAMELLIA_128_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_192_ecb_info = { - "CAMELLIA-192-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_CAMELLIA_192_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_256_ecb_info = { - "CAMELLIA-256-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_CAMELLIA_256_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t camellia_128_cbc_info = { - "CAMELLIA-128-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_CAMELLIA_128_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_192_cbc_info = { - "CAMELLIA-192-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_CAMELLIA_192_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_256_cbc_info = { - "CAMELLIA-256-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_CAMELLIA_256_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t camellia_128_cfb128_info = { - "CAMELLIA-128-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_192_cfb128_info = { - "CAMELLIA-192-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_256_cfb128_info = { - "CAMELLIA-256-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t camellia_128_ctr_info = { - "CAMELLIA-128-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_CAMELLIA_128_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_192_ctr_info = { - "CAMELLIA-192-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_CAMELLIA_192_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_256_ctr_info = { - "CAMELLIA-256-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_CAMELLIA_256_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_camellia_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_gcm_setkey((mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen); -} - -static const mbedtls_cipher_base_t gcm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_camellia_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - gcm_camellia_setkey_wrap, -#endif - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_gcm_info = { - "CAMELLIA-128-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_CAMELLIA_128_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_192_gcm_info = { - "CAMELLIA-192-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_CAMELLIA_192_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_256_gcm_info = { - "CAMELLIA-256-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_CAMELLIA_256_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_camellia_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_ccm_setkey((mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen); -} - -static const mbedtls_cipher_base_t ccm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_camellia_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - ccm_camellia_setkey_wrap, -#endif - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_ccm_info = { - "CAMELLIA-128-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_CAMELLIA_128_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_192_ccm_info = { - "CAMELLIA-192-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_CAMELLIA_192_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_256_ccm_info = { - "CAMELLIA-256-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_CAMELLIA_256_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_128_ccm_star_no_tag_info = { - "CAMELLIA-128-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_192_ccm_star_no_tag_info = { - "CAMELLIA-192-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA -}; - -static const mbedtls_cipher_info_t camellia_256_ccm_star_no_tag_info = { - "CAMELLIA-256-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - -static int aria_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output) -{ - (void) operation; - return mbedtls_aria_crypt_ecb((mbedtls_aria_context *) ctx, input, - output); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aria_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_aria_crypt_cbc((mbedtls_aria_context *) ctx, operation, length, iv, - input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aria_crypt_cfb128_wrap(void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_aria_crypt_cfb128((mbedtls_aria_context *) ctx, operation, length, - iv_off, iv, input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aria_crypt_ctr_wrap(void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output) -{ - return mbedtls_aria_crypt_ctr((mbedtls_aria_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) -static int aria_setkey_dec_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_aria_setkey_dec((mbedtls_aria_context *) ctx, key, key_bitlen); -} -#endif - -static int aria_setkey_enc_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_aria_setkey_enc((mbedtls_aria_context *) ctx, key, key_bitlen); -} - -static void *aria_ctx_alloc(void) -{ - mbedtls_aria_context *ctx; - ctx = mbedtls_calloc(1, sizeof(mbedtls_aria_context)); - - if (ctx == NULL) { - return NULL; - } - - mbedtls_aria_init(ctx); - - return ctx; -} - -static void aria_ctx_free(void *ctx) -{ - mbedtls_aria_free((mbedtls_aria_context *) ctx); - mbedtls_free(ctx); -} - -static const mbedtls_cipher_base_t aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - aria_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aria_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aria_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aria_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aria_setkey_enc_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - aria_setkey_dec_wrap, -#endif - aria_ctx_alloc, - aria_ctx_free -}; - -static const mbedtls_cipher_info_t aria_128_ecb_info = { - "ARIA-128-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_ARIA_128_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_192_ecb_info = { - "ARIA-192-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_ARIA_192_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_256_ecb_info = { - "ARIA-256-ECB", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_ARIA_256_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aria_128_cbc_info = { - "ARIA-128-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_ARIA_128_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_192_cbc_info = { - "ARIA-192-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_ARIA_192_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_256_cbc_info = { - "ARIA-256-CBC", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_ARIA_256_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aria_128_cfb128_info = { - "ARIA-128-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_ARIA_128_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_192_cfb128_info = { - "ARIA-192-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_ARIA_192_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_256_cfb128_info = { - "ARIA-256-CFB128", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CFB, - MBEDTLS_CIPHER_ARIA_256_CFB128, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aria_128_ctr_info = { - "ARIA-128-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_ARIA_128_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_192_ctr_info = { - "ARIA-192-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_ARIA_192_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; - -static const mbedtls_cipher_info_t aria_256_ctr_info = { - "ARIA-256-CTR", - 16, - 16 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CTR, - MBEDTLS_CIPHER_ARIA_256_CTR, - 0, - MBEDTLS_CIPHER_BASE_INDEX_ARIA -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aria_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_gcm_setkey((mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen); -} - -static const mbedtls_cipher_base_t gcm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aria_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - gcm_aria_setkey_wrap, -#endif - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_gcm_info = { - "ARIA-128-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_ARIA_128_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA -}; - -static const mbedtls_cipher_info_t aria_192_gcm_info = { - "ARIA-192-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_ARIA_192_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA -}; - -static const mbedtls_cipher_info_t aria_256_gcm_info = { - "ARIA-256-GCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_GCM, - MBEDTLS_CIPHER_ARIA_256_GCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aria_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_ccm_setkey((mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, - key, key_bitlen); -} - -static const mbedtls_cipher_base_t ccm_aria_info = { - MBEDTLS_CIPHER_ID_ARIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aria_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - ccm_aria_setkey_wrap, -#endif - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aria_128_ccm_info = { - "ARIA-128-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_ARIA_128_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA -}; - -static const mbedtls_cipher_info_t aria_192_ccm_info = { - "ARIA-192-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_ARIA_192_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA -}; - -static const mbedtls_cipher_info_t aria_256_ccm_info = { - "ARIA-256-CCM", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM, - MBEDTLS_CIPHER_ARIA_256_CCM, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA -}; - -static const mbedtls_cipher_info_t aria_128_ccm_star_no_tag_info = { - "ARIA-128-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA -}; - -static const mbedtls_cipher_info_t aria_192_ccm_star_no_tag_info = { - "ARIA-192-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA -}; - -static const mbedtls_cipher_info_t aria_256_ccm_star_no_tag_info = { - "ARIA-256-CCM*-NO-TAG", - 16, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - -static int des_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output) -{ - ((void) operation); - return mbedtls_des_crypt_ecb((mbedtls_des_context *) ctx, input, output); -} - -static int des3_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output) -{ - ((void) operation); - return mbedtls_des3_crypt_ecb((mbedtls_des3_context *) ctx, input, output); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output) -{ - return mbedtls_des_crypt_cbc((mbedtls_des_context *) ctx, operation, length, iv, input, - output); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des3_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output) -{ - return mbedtls_des3_crypt_cbc((mbedtls_des3_context *) ctx, operation, length, iv, input, - output); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static int des_setkey_dec_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_dec((mbedtls_des_context *) ctx, key); -} - -static int des_setkey_enc_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_enc((mbedtls_des_context *) ctx, key); -} - -static int des3_set2key_dec_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_dec((mbedtls_des3_context *) ctx, key); -} - -static int des3_set2key_enc_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_enc((mbedtls_des3_context *) ctx, key); -} - -static int des3_set3key_dec_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_dec((mbedtls_des3_context *) ctx, key); -} - -static int des3_set3key_enc_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_enc((mbedtls_des3_context *) ctx, key); -} - -static void *des_ctx_alloc(void) -{ - mbedtls_des_context *des = mbedtls_calloc(1, sizeof(mbedtls_des_context)); - - if (des == NULL) { - return NULL; - } - - mbedtls_des_init(des); - - return des; -} - -static void des_ctx_free(void *ctx) -{ - mbedtls_des_free((mbedtls_des_context *) ctx); - mbedtls_free(ctx); -} - -static void *des3_ctx_alloc(void) -{ - mbedtls_des3_context *des3; - des3 = mbedtls_calloc(1, sizeof(mbedtls_des3_context)); - - if (des3 == NULL) { - return NULL; - } - - mbedtls_des3_init(des3); - - return des3; -} - -static void des3_ctx_free(void *ctx) -{ - mbedtls_des3_free((mbedtls_des3_context *) ctx); - mbedtls_free(ctx); -} - -static const mbedtls_cipher_base_t des_info = { - MBEDTLS_CIPHER_ID_DES, - des_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des_setkey_enc_wrap, - des_setkey_dec_wrap, - des_ctx_alloc, - des_ctx_free -}; - -static const mbedtls_cipher_info_t des_ecb_info = { - "DES-ECB", - 8, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - MBEDTLS_KEY_LENGTH_DES >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_DES_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_DES -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_cbc_info = { - "DES-CBC", - 8, - 8 >> MBEDTLS_IV_SIZE_SHIFT, - MBEDTLS_KEY_LENGTH_DES >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_DES_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_DES -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede_info = { - MBEDTLS_CIPHER_ID_DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set2key_enc_wrap, - des3_set2key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede_ecb_info = { - "DES-EDE-ECB", - 8, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - MBEDTLS_KEY_LENGTH_DES_EDE >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_DES_EDE_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_DES_EDE -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede_cbc_info = { - "DES-EDE-CBC", - 8, - 8 >> MBEDTLS_IV_SIZE_SHIFT, - MBEDTLS_KEY_LENGTH_DES_EDE >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_DES_EDE_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_DES_EDE -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede3_info = { - MBEDTLS_CIPHER_ID_3DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set3key_enc_wrap, - des3_set3key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede3_ecb_info = { - "DES-EDE3-ECB", - 8, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - MBEDTLS_KEY_LENGTH_DES_EDE3 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_ECB, - MBEDTLS_CIPHER_DES_EDE3_ECB, - 0, - MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3 -}; -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede3_cbc_info = { - "DES-EDE3-CBC", - 8, - 8 >> MBEDTLS_IV_SIZE_SHIFT, - MBEDTLS_KEY_LENGTH_DES_EDE3 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CBC, - MBEDTLS_CIPHER_DES_EDE3_CBC, - 0, - MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3 -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_CHACHA20_C) - -static int chacha20_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - if (key_bitlen != 256U) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (0 != mbedtls_chacha20_setkey((mbedtls_chacha20_context *) ctx, key)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return 0; -} - -static int chacha20_stream_wrap(void *ctx, size_t length, - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_chacha20_update(ctx, length, input, output); - if (ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return ret; -} - -static void *chacha20_ctx_alloc(void) -{ - mbedtls_chacha20_context *ctx; - ctx = mbedtls_calloc(1, sizeof(mbedtls_chacha20_context)); - - if (ctx == NULL) { - return NULL; - } - - mbedtls_chacha20_init(ctx); - - return ctx; -} - -static void chacha20_ctx_free(void *ctx) -{ - mbedtls_chacha20_free((mbedtls_chacha20_context *) ctx); - mbedtls_free(ctx); -} - -static const mbedtls_cipher_base_t chacha20_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - chacha20_stream_wrap, -#endif - chacha20_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - chacha20_setkey_wrap, -#endif - chacha20_ctx_alloc, - chacha20_ctx_free -}; -static const mbedtls_cipher_info_t chacha20_info = { - "CHACHA20", - 1, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_STREAM, - MBEDTLS_CIPHER_CHACHA20, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CHACHA20_BASE -}; -#endif /* MBEDTLS_CHACHA20_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - -static int chachapoly_setkey_wrap(void *ctx, - const unsigned char *key, - unsigned int key_bitlen) -{ - if (key_bitlen != 256U) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (0 != mbedtls_chachapoly_setkey((mbedtls_chachapoly_context *) ctx, key)) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - return 0; -} - -static void *chachapoly_ctx_alloc(void) -{ - mbedtls_chachapoly_context *ctx; - ctx = mbedtls_calloc(1, sizeof(mbedtls_chachapoly_context)); - - if (ctx == NULL) { - return NULL; - } - - mbedtls_chachapoly_init(ctx); - - return ctx; -} - -static void chachapoly_ctx_free(void *ctx) -{ - mbedtls_chachapoly_free((mbedtls_chachapoly_context *) ctx); - mbedtls_free(ctx); -} - -static const mbedtls_cipher_base_t chachapoly_base_info = { - MBEDTLS_CIPHER_ID_CHACHA20, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - chachapoly_setkey_wrap, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - chachapoly_setkey_wrap, -#endif - chachapoly_ctx_alloc, - chachapoly_ctx_free -}; -static const mbedtls_cipher_info_t chachapoly_info = { - "CHACHA20-POLY1305", - 1, - 12 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_CHACHAPOLY, - MBEDTLS_CIPHER_CHACHA20_POLY1305, - 0, - MBEDTLS_CIPHER_BASE_INDEX_CHACHAPOLY_BASE -}; -#endif /* MBEDTLS_CHACHAPOLY_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -static int null_crypt_stream(void *ctx, size_t length, - const unsigned char *input, - unsigned char *output) -{ - ((void) ctx); - memmove(output, input, length); - return 0; -} - -static int null_setkey(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - ((void) ctx); - ((void) key); - ((void) key_bitlen); - - return 0; -} - -static void *null_ctx_alloc(void) -{ - return (void *) 1; -} - -static void null_ctx_free(void *ctx) -{ - ((void) ctx); -} - -static const mbedtls_cipher_base_t null_base_info = { - MBEDTLS_CIPHER_ID_NULL, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - null_crypt_stream, -#endif - null_setkey, -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - null_setkey, -#endif - null_ctx_alloc, - null_ctx_free -}; - -static const mbedtls_cipher_info_t null_cipher_info = { - "NULL", - 1, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 0 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_STREAM, - MBEDTLS_CIPHER_NULL, - 0, - MBEDTLS_CIPHER_BASE_INDEX_NULL_BASE -}; -#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ - -#if defined(MBEDTLS_NIST_KW_C) -static void *kw_ctx_alloc(void) -{ - void *ctx = mbedtls_calloc(1, sizeof(mbedtls_nist_kw_context)); - - if (ctx != NULL) { - mbedtls_nist_kw_init((mbedtls_nist_kw_context *) ctx); - } - - return ctx; -} - -static void kw_ctx_free(void *ctx) -{ - mbedtls_nist_kw_free(ctx); - mbedtls_free(ctx); -} - -static int kw_aes_setkey_wrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_nist_kw_setkey((mbedtls_nist_kw_context *) ctx, - MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1); -} - -static int kw_aes_setkey_unwrap(void *ctx, const unsigned char *key, - unsigned int key_bitlen) -{ - return mbedtls_nist_kw_setkey((mbedtls_nist_kw_context *) ctx, - MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0); -} - -static const mbedtls_cipher_base_t kw_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - kw_aes_setkey_wrap, - kw_aes_setkey_unwrap, - kw_ctx_alloc, - kw_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_nist_kw_info = { - "AES-128-KW", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_KW, - MBEDTLS_CIPHER_AES_128_KW, - 0, - MBEDTLS_CIPHER_BASE_INDEX_KW_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_nist_kw_info = { - "AES-192-KW", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_KW, - MBEDTLS_CIPHER_AES_192_KW, - 0, - MBEDTLS_CIPHER_BASE_INDEX_KW_AES -}; - -static const mbedtls_cipher_info_t aes_256_nist_kw_info = { - "AES-256-KW", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_KW, - MBEDTLS_CIPHER_AES_256_KW, - 0, - MBEDTLS_CIPHER_BASE_INDEX_KW_AES -}; -#endif - -static const mbedtls_cipher_info_t aes_128_nist_kwp_info = { - "AES-128-KWP", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 128 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_KWP, - MBEDTLS_CIPHER_AES_128_KWP, - 0, - MBEDTLS_CIPHER_BASE_INDEX_KW_AES -}; - -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const mbedtls_cipher_info_t aes_192_nist_kwp_info = { - "AES-192-KWP", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 192 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_KWP, - MBEDTLS_CIPHER_AES_192_KWP, - 0, - MBEDTLS_CIPHER_BASE_INDEX_KW_AES -}; - -static const mbedtls_cipher_info_t aes_256_nist_kwp_info = { - "AES-256-KWP", - 16, - 0 >> MBEDTLS_IV_SIZE_SHIFT, - 256 >> MBEDTLS_KEY_BITLEN_SHIFT, - MBEDTLS_MODE_KWP, - MBEDTLS_CIPHER_AES_256_KWP, - 0, - MBEDTLS_CIPHER_BASE_INDEX_KW_AES -}; -#endif -#endif /* MBEDTLS_NIST_KW_C */ - -const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = -{ -#if defined(MBEDTLS_AES_C) - { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, - { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, - { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, -#endif -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, - { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, -#endif -#endif -#if defined(MBEDTLS_CIPHER_MODE_OFB) - { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, - { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, -#endif -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, - { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, -#endif -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) - { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, -#endif -#endif -#endif /* MBEDTLS_AES_C */ -#if defined(MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA) - { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, - { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, -#endif -#endif -#if defined(MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA) - { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, - { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, -#endif -#endif -#if defined(MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_AES_VIA_LEGACY_OR_USE_PSA) - { MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG, &aes_128_ccm_star_no_tag_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG, &aes_192_ccm_star_no_tag_info }, - { MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG, &aes_256_ccm_star_no_tag_info }, -#endif -#endif - -#if defined(MBEDTLS_CAMELLIA_C) - { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG, &camellia_128_ccm_star_no_tag_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG, &camellia_192_ccm_star_no_tag_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG, &camellia_256_ccm_star_no_tag_info }, -#endif -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_ARIA_C) - { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info }, - { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info }, - { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info }, - { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info }, - { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info }, - { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info }, - { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info }, - { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info }, - { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info }, - { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info }, - { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info }, - { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info }, - { MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG, &aria_128_ccm_star_no_tag_info }, - { MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG, &aria_192_ccm_star_no_tag_info }, - { MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG, &aria_256_ccm_star_no_tag_info }, -#endif -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_DES_C) - { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, -#endif -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_CHACHA20_C) - { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, -#endif - -#if defined(MBEDTLS_NIST_KW_C) - { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info }, - { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info }, -#endif - { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info }, - { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info }, -#endif -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - { MBEDTLS_CIPHER_NULL, &null_cipher_info }, -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - - { MBEDTLS_CIPHER_NONE, NULL } -}; - -#define NUM_CIPHERS (sizeof(mbedtls_cipher_definitions) / \ - sizeof(mbedtls_cipher_definitions[0])) -int mbedtls_cipher_supported[NUM_CIPHERS]; - -const mbedtls_cipher_base_t * const mbedtls_cipher_base_lookup_table[] = { -#if defined(MBEDTLS_AES_C) - [MBEDTLS_CIPHER_BASE_INDEX_AES] = &aes_info, -#endif -#if defined(MBEDTLS_ARIA_C) - [MBEDTLS_CIPHER_BASE_INDEX_ARIA] = &aria_info, -#endif -#if defined(MBEDTLS_CAMELLIA_C) - [MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA] = &camellia_info, -#endif -#if defined(MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA) - [MBEDTLS_CIPHER_BASE_INDEX_CCM_AES] = &ccm_aes_info, -#endif -#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_ARIA_C) - [MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA] = &ccm_aria_info, -#endif -#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_CAMELLIA_C) - [MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA] = &ccm_camellia_info, -#endif -#if defined(MBEDTLS_CHACHA20_C) - [MBEDTLS_CIPHER_BASE_INDEX_CHACHA20_BASE] = &chacha20_base_info, -#endif -#if defined(MBEDTLS_CHACHAPOLY_C) - [MBEDTLS_CIPHER_BASE_INDEX_CHACHAPOLY_BASE] = &chachapoly_base_info, -#endif -#if defined(MBEDTLS_DES_C) - [MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3] = &des_ede3_info, -#endif -#if defined(MBEDTLS_DES_C) - [MBEDTLS_CIPHER_BASE_INDEX_DES_EDE] = &des_ede_info, -#endif -#if defined(MBEDTLS_DES_C) - [MBEDTLS_CIPHER_BASE_INDEX_DES] = &des_info, -#endif -#if defined(MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA) - [MBEDTLS_CIPHER_BASE_INDEX_GCM_AES] = &gcm_aes_info, -#endif -#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_ARIA_C) - [MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA] = &gcm_aria_info, -#endif -#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_CAMELLIA_C) - [MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA] = &gcm_camellia_info, -#endif -#if defined(MBEDTLS_NIST_KW_C) - [MBEDTLS_CIPHER_BASE_INDEX_KW_AES] = &kw_aes_info, -#endif -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - [MBEDTLS_CIPHER_BASE_INDEX_NULL_BASE] = &null_base_info, -#endif -#if defined(MBEDTLS_CIPHER_MODE_XTS) && defined(MBEDTLS_AES_C) - [MBEDTLS_CIPHER_BASE_INDEX_XTS_AES] = &xts_aes_info -#endif -}; - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/vendor/mbedtls/library/cipher_wrap.h b/vendor/mbedtls/library/cipher_wrap.h deleted file mode 100644 index 9564c5efe..000000000 --- a/vendor/mbedtls/library/cipher_wrap.h +++ /dev/null @@ -1,178 +0,0 @@ -/** - * \file cipher_wrap.h - * - * \brief Cipher wrappers. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_CIPHER_WRAP_H -#define MBEDTLS_CIPHER_WRAP_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/cipher.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Support for GCM either through Mbed TLS SW implementation or PSA */ -#if defined(MBEDTLS_GCM_C) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM)) -#define MBEDTLS_CIPHER_HAVE_GCM_VIA_LEGACY_OR_USE_PSA -#endif - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM) && defined(PSA_WANT_KEY_TYPE_AES)) -#define MBEDTLS_CIPHER_HAVE_GCM_AES_VIA_LEGACY_OR_USE_PSA -#endif - -#if defined(MBEDTLS_CCM_C) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM)) -#define MBEDTLS_CIPHER_HAVE_CCM_VIA_LEGACY_OR_USE_PSA -#endif - -#if (defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM) && defined(PSA_WANT_KEY_TYPE_AES)) -#define MBEDTLS_CIPHER_HAVE_CCM_AES_VIA_LEGACY_OR_USE_PSA -#endif - -#if defined(MBEDTLS_CCM_C) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)) -#define MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_VIA_LEGACY_OR_USE_PSA -#endif - -#if (defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C)) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && \ - defined(PSA_WANT_KEY_TYPE_AES)) -#define MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_AES_VIA_LEGACY_OR_USE_PSA -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CHACHA20_POLY1305)) -#define MBEDTLS_CIPHER_HAVE_CHACHAPOLY_VIA_LEGACY_OR_USE_PSA -#endif - -#if defined(MBEDTLS_CIPHER_HAVE_GCM_VIA_LEGACY_OR_USE_PSA) || \ - defined(MBEDTLS_CIPHER_HAVE_CCM_VIA_LEGACY_OR_USE_PSA) || \ - defined(MBEDTLS_CIPHER_HAVE_CCM_STAR_NO_TAG_VIA_LEGACY_OR_USE_PSA) || \ - defined(MBEDTLS_CIPHER_HAVE_CHACHAPOLY_VIA_LEGACY_OR_USE_PSA) -#define MBEDTLS_CIPHER_HAVE_SOME_AEAD_VIA_LEGACY_OR_USE_PSA -#endif - -/** - * Base cipher information. The non-mode specific functions and values. - */ -struct mbedtls_cipher_base_t { - /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ - mbedtls_cipher_id_t cipher; - - /** Encrypt using ECB */ - int (*ecb_func)(void *ctx, mbedtls_operation_t mode, - const unsigned char *input, unsigned char *output); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /** Encrypt using CBC */ - int (*cbc_func)(void *ctx, mbedtls_operation_t mode, size_t length, - unsigned char *iv, const unsigned char *input, - unsigned char *output); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /** Encrypt using CFB (Full length) */ - int (*cfb_func)(void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, - unsigned char *output); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_OFB) - /** Encrypt using OFB (Full length) */ - int (*ofb_func)(void *ctx, size_t length, size_t *iv_off, - unsigned char *iv, - const unsigned char *input, - unsigned char *output); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /** Encrypt using CTR */ - int (*ctr_func)(void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_XTS) - /** Encrypt or decrypt using XTS. */ - int (*xts_func)(void *ctx, mbedtls_operation_t mode, size_t length, - const unsigned char data_unit[16], - const unsigned char *input, unsigned char *output); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - /** Encrypt using STREAM */ - int (*stream_func)(void *ctx, size_t length, - const unsigned char *input, unsigned char *output); -#endif - - /** Set key for encryption purposes */ - int (*setkey_enc_func)(void *ctx, const unsigned char *key, - unsigned int key_bitlen); - -#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - /** Set key for decryption purposes */ - int (*setkey_dec_func)(void *ctx, const unsigned char *key, - unsigned int key_bitlen); -#endif - - /** Allocate a new context */ - void * (*ctx_alloc_func)(void); - - /** Free the given context */ - void (*ctx_free_func)(void *ctx); - -}; - -typedef struct { - mbedtls_cipher_type_t type; - const mbedtls_cipher_info_t *info; -} mbedtls_cipher_definition_t; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -typedef enum { - MBEDTLS_CIPHER_PSA_KEY_UNSET = 0, - MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */ - /* use raw key material internally imported */ - /* as a volatile key, and which hence need */ - /* to destroy that key when the context is */ - /* freed. */ - MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */ - /* which use a key provided by the */ - /* user, and which hence will not be */ - /* destroyed when the context is freed. */ -} mbedtls_cipher_psa_key_ownership; - -typedef struct { - psa_algorithm_t alg; - mbedtls_svc_key_id_t slot; - mbedtls_cipher_psa_key_ownership slot_state; -} mbedtls_cipher_context_psa; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; - -extern int mbedtls_cipher_supported[]; - -extern const mbedtls_cipher_base_t * const mbedtls_cipher_base_lookup_table[]; - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/vendor/mbedtls/library/cmac.c b/vendor/mbedtls/library/cmac.c deleted file mode 100644 index eda10d0b3..000000000 --- a/vendor/mbedtls/library/cmac.c +++ /dev/null @@ -1,1067 +0,0 @@ -/** - * \file cmac.c - * - * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * References: - * - * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The - * CMAC Mode for Authentication - * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf - * - * - RFC 4493 - The AES-CMAC Algorithm - * https://tools.ietf.org/html/rfc4493 - * - * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message - * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) - * Algorithm for the Internet Key Exchange Protocol (IKE) - * https://tools.ietf.org/html/rfc4615 - * - * Additional test vectors: ISO/IEC 9797-1 - * - */ - -#include "common.h" - -#if defined(MBEDTLS_CMAC_C) - -#include "mbedtls/cmac.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/platform.h" -#include "constant_time_internal.h" - -#include - -#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) - -/* - * Multiplication by u in the Galois field of GF(2^n) - * - * As explained in NIST SP 800-38B, this can be computed: - * - * If MSB(p) = 0, then p = (p << 1) - * If MSB(p) = 1, then p = (p << 1) ^ R_n - * with R_64 = 0x1B and R_128 = 0x87 - * - * Input and output MUST NOT point to the same buffer - * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. - */ -static int cmac_multiply_by_u(unsigned char *output, - const unsigned char *input, - size_t blocksize) -{ - const unsigned char R_128 = 0x87; - unsigned char R_n; - uint32_t overflow = 0x00; - int i; - - if (blocksize == MBEDTLS_AES_BLOCK_SIZE) { - R_n = R_128; - } -#if defined(MBEDTLS_DES_C) - else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) { - const unsigned char R_64 = 0x1B; - R_n = R_64; - } -#endif - else { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - for (i = (int) blocksize - 4; i >= 0; i -= 4) { - uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0); - uint32_t new_overflow = i32 >> 31; - i32 = (i32 << 1) | overflow; - MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0); - overflow = new_overflow; - } - - R_n = (unsigned char) mbedtls_ct_uint_if_else_0(mbedtls_ct_bool(input[0] >> 7), R_n); - output[blocksize - 1] ^= R_n; - - return 0; -} - -/* - * Generate subkeys - * - * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm - */ -static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx, - unsigned char *K1, unsigned char *K2) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char L[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - size_t olen, block_size; - - mbedtls_platform_zeroize(L, sizeof(L)); - - block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); - - /* Calculate Ek(0) */ - if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) { - goto exit; - } - - /* - * Generate K1 and K2 - */ - if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) { - goto exit; - } - - if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) { - goto exit; - } - -exit: - mbedtls_platform_zeroize(L, sizeof(L)); - - return ret; -} -#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */ - -#if !defined(MBEDTLS_CMAC_ALT) - -/* - * Create padded last block from (partial) last block. - * - * We can't use the padding option from the cipher layer, as it only works for - * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. - */ -static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE], - size_t padded_block_len, - const unsigned char *last_block, - size_t last_block_len) -{ - size_t j; - - for (j = 0; j < padded_block_len; j++) { - if (j < last_block_len) { - padded_block[j] = last_block[j]; - } else if (j == last_block_len) { - padded_block[j] = 0x80; - } else { - padded_block[j] = 0x00; - } - } -} - -int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx, - const unsigned char *key, size_t keybits) -{ - mbedtls_cipher_type_t type; - mbedtls_cmac_context_t *cmac_ctx; - int retval; - - if (ctx == NULL || ctx->cipher_info == NULL || key == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if ((retval = mbedtls_cipher_setkey(ctx, key, (int) keybits, - MBEDTLS_ENCRYPT)) != 0) { - return retval; - } - - type = mbedtls_cipher_info_get_type(ctx->cipher_info); - - switch (type) { - case MBEDTLS_CIPHER_AES_128_ECB: - case MBEDTLS_CIPHER_AES_192_ECB: - case MBEDTLS_CIPHER_AES_256_ECB: - case MBEDTLS_CIPHER_DES_EDE3_ECB: - break; - default: - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - /* Allocated and initialise in the cipher context memory for the CMAC - * context */ - cmac_ctx = mbedtls_calloc(1, sizeof(mbedtls_cmac_context_t)); - if (cmac_ctx == NULL) { - return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; - } - - ctx->cmac_ctx = cmac_ctx; - - mbedtls_platform_zeroize(cmac_ctx->state, sizeof(cmac_ctx->state)); - - return 0; -} - -int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx, - const unsigned char *input, size_t ilen) -{ - mbedtls_cmac_context_t *cmac_ctx; - unsigned char *state; - int ret = 0; - size_t n, j, olen, block_size; - - if (ctx == NULL || ctx->cipher_info == NULL || input == NULL || - ctx->cmac_ctx == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - cmac_ctx = ctx->cmac_ctx; - block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); - state = ctx->cmac_ctx->state; - - /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form - * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */ - MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); - - /* Is there data still to process from the last call, that's greater in - * size than a block? */ - if (cmac_ctx->unprocessed_len > 0 && - ilen > block_size - cmac_ctx->unprocessed_len) { - memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], - input, - block_size - cmac_ctx->unprocessed_len); - - mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size); - - if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, - &olen)) != 0) { - goto exit; - } - - input += block_size - cmac_ctx->unprocessed_len; - ilen -= block_size - cmac_ctx->unprocessed_len; - cmac_ctx->unprocessed_len = 0; - } - - /* n is the number of blocks including any final partial block */ - n = (ilen + block_size - 1) / block_size; - - /* Iterate across the input data in block sized chunks, excluding any - * final partial or complete block */ - for (j = 1; j < n; j++) { - mbedtls_xor_no_simd(state, input, state, block_size); - - if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, - &olen)) != 0) { - goto exit; - } - - ilen -= block_size; - input += block_size; - } - - /* If there is data left over that wasn't aligned to a block */ - if (ilen > 0) { - memcpy(&cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], - input, - ilen); - cmac_ctx->unprocessed_len += ilen; - } - -exit: - return ret; -} - -int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx, - unsigned char *output) -{ - mbedtls_cmac_context_t *cmac_ctx; - unsigned char *state, *last_block; - unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - unsigned char M_last[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen, block_size; - - if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || - output == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - cmac_ctx = ctx->cmac_ctx; - block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); - MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning - state = cmac_ctx->state; - - mbedtls_platform_zeroize(K1, sizeof(K1)); - mbedtls_platform_zeroize(K2, sizeof(K2)); - cmac_generate_subkeys(ctx, K1, K2); - - last_block = cmac_ctx->unprocessed_block; - - /* Calculate last block */ - if (cmac_ctx->unprocessed_len < block_size) { - cmac_pad(M_last, block_size, last_block, cmac_ctx->unprocessed_len); - mbedtls_xor(M_last, M_last, K2, block_size); - } else { - /* Last block is complete block */ - mbedtls_xor(M_last, last_block, K1, block_size); - } - - - mbedtls_xor(state, M_last, state, block_size); - if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, - &olen)) != 0) { - goto exit; - } - - memcpy(output, state, block_size); - -exit: - /* Wipe the generated keys on the stack, and any other transients to avoid - * side channel leakage */ - mbedtls_platform_zeroize(K1, sizeof(K1)); - mbedtls_platform_zeroize(K2, sizeof(K2)); - - cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize(cmac_ctx->unprocessed_block, - sizeof(cmac_ctx->unprocessed_block)); - - mbedtls_platform_zeroize(state, MBEDTLS_CMAC_MAX_BLOCK_SIZE); - return ret; -} - -int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx) -{ - mbedtls_cmac_context_t *cmac_ctx; - - if (ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - cmac_ctx = ctx->cmac_ctx; - - /* Reset the internal state */ - cmac_ctx->unprocessed_len = 0; - mbedtls_platform_zeroize(cmac_ctx->unprocessed_block, - sizeof(cmac_ctx->unprocessed_block)); - mbedtls_platform_zeroize(cmac_ctx->state, - sizeof(cmac_ctx->state)); - - return 0; -} - -int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output) -{ - mbedtls_cipher_context_t ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - mbedtls_cipher_init(&ctx); - - if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) { - goto exit; - } - - ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_cipher_cmac_update(&ctx, input, ilen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_cipher_cmac_finish(&ctx, output); - -exit: - mbedtls_cipher_free(&ctx); - - return ret; -} - -#if defined(MBEDTLS_AES_C) -/* - * Implementation of AES-CMAC-PRF-128 defined in RFC 4615 - */ -int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length, - const unsigned char *input, size_t in_len, - unsigned char output[16]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_cipher_info_t *cipher_info; - unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; - unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; - - if (key == NULL || input == NULL || output == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); - if (cipher_info == NULL) { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto exit; - } - - if (key_length == MBEDTLS_AES_BLOCK_SIZE) { - /* Use key as is */ - memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE); - } else { - memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE); - - ret = mbedtls_cipher_cmac(cipher_info, zero_key, 128, key, - key_length, int_key); - if (ret != 0) { - goto exit; - } - } - - ret = mbedtls_cipher_cmac(cipher_info, int_key, 128, input, in_len, - output); - -exit: - mbedtls_platform_zeroize(int_key, sizeof(int_key)); - - return ret; -} -#endif /* MBEDTLS_AES_C */ - -#endif /* !MBEDTLS_CMAC_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * CMAC test data for SP800-38B - * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf - * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf - * - * AES-CMAC-PRF-128 test data from RFC 4615 - * https://tools.ietf.org/html/rfc4615#page-4 - */ - -#define NB_CMAC_TESTS_PER_KEY 4 -#define NB_PRF_TESTS 3 - -#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) -/* All CMAC test inputs are truncated from the same 64 byte buffer. */ -static const unsigned char test_message[] = { - /* PT */ - 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, - 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, - 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, - 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, - 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, - 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, - 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, - 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 -}; -#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* Truncation point of message for AES CMAC tests */ -static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { - /* Mlen */ - 0, - 16, - 20, - 64 -}; - -/* CMAC-AES128 Test Data */ -static const unsigned char aes_128_key[16] = { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c -}; -static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, - 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde - }, - { - /* K2 */ - 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, - 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b - } -}; -static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = -{ - { - /* Example #1 */ - 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, - 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 - }, - { - /* Example #2 */ - 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, - 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c - }, - { - /* Example #3 */ - 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, - 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde - }, - { - /* Example #4 */ - 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, - 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe - } -}; - -/* CMAC-AES192 Test Data */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const unsigned char aes_192_key[24] = { - 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, - 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, - 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b -}; -static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, - 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 - }, - { - /* K2 */ - 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, - 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c - } -}; -static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = -{ - { - /* Example #1 */ - 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, - 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 - }, - { - /* Example #2 */ - 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, - 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 - }, - { - /* Example #3 */ - 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, - 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 - }, - { - /* Example #4 */ - 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, - 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 - } -}; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - -/* CMAC-AES256 Test Data */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) -static const unsigned char aes_256_key[32] = { - 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, - 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, - 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, - 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 -}; -static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { - { - /* K1 */ - 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, - 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f - }, - { - /* K2 */ - 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, - 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 - } -}; -static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = -{ - { - /* Example #1 */ - 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, - 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 - }, - { - /* Example #2 */ - 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, - 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c - }, - { - /* Example #3 */ - 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, - 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 - }, - { - /* Example #4 */ - 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, - 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 - } -}; -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_DES_C) -/* Truncation point of message for 3DES CMAC tests */ -static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { - 0, - 16, - 20, - 32 -}; - -/* CMAC-TDES (Generation) - 2 Key Test Data */ -static const unsigned char des3_2key_key[24] = { - /* Key1 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - /* Key2 */ - 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, - /* Key3 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef -}; -static const unsigned char des3_2key_subkeys[2][8] = { - { - /* K1 */ - 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 - }, - { - /* K2 */ - 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 - } -}; -static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] - = { - { - /* Sample #1 */ - 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 - }, - { - /* Sample #2 */ - 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b - }, - { - /* Sample #3 */ - 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 - }, - { - /* Sample #4 */ - 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb - } - }; - -/* CMAC-TDES (Generation) - 3 Key Test Data */ -static const unsigned char des3_3key_key[24] = { - /* Key1 */ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, - /* Key2 */ - 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, - /* Key3 */ - 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 -}; -static const unsigned char des3_3key_subkeys[2][8] = { - { - /* K1 */ - 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 - }, - { - /* K2 */ - 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b - } -}; -static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] - = { - { - /* Sample #1 */ - 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 - }, - { - /* Sample #2 */ - 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 - }, - { - /* Sample #3 */ - 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 - }, - { - /* Sample #4 */ - 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 - } - }; - -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* AES AES-CMAC-PRF-128 Test Data */ -static const unsigned char PRFK[] = { - /* Key */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0xed, 0xcb -}; - -/* Sizes in bytes */ -static const size_t PRFKlen[NB_PRF_TESTS] = { - 18, - 16, - 10 -}; - -/* Message */ -static const unsigned char PRFM[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 -}; - -static const unsigned char PRFT[NB_PRF_TESTS][16] = { - { - 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, - 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a - }, - { - 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, - 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d - }, - { - 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, - 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d - } -}; -#endif /* MBEDTLS_AES_C */ - -static int cmac_test_subkeys(int verbose, - const char *testname, - const unsigned char *key, - int keybits, - const unsigned char *subkeys, - mbedtls_cipher_type_t cipher_type, - int block_size, - int num_tests) -{ - int i, ret = 0; - mbedtls_cipher_context_t ctx; - const mbedtls_cipher_info_t *cipher_info; - unsigned char K1[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - unsigned char K2[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) { - /* Failing at this point must be due to a build issue */ - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - for (i = 0; i < num_tests; i++) { - if (verbose != 0) { - mbedtls_printf(" %s CMAC subkey #%d: ", testname, i + 1); - } - - mbedtls_cipher_init(&ctx); - - if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) { - if (verbose != 0) { - mbedtls_printf("test execution failed\n"); - } - - goto cleanup; - } - - if ((ret = mbedtls_cipher_setkey(&ctx, key, keybits, - MBEDTLS_ENCRYPT)) != 0) { - /* When CMAC is implemented by an alternative implementation, or - * the underlying primitive itself is implemented alternatively, - * AES-192 may be unavailable. This should not cause the selftest - * function to fail. */ - if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED || - ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) && - cipher_type == MBEDTLS_CIPHER_AES_192_ECB) { - if (verbose != 0) { - mbedtls_printf("skipped\n"); - } - goto next_test; - } - - if (verbose != 0) { - mbedtls_printf("test execution failed\n"); - } - - goto cleanup; - } - - ret = cmac_generate_subkeys(&ctx, K1, K2); - if (ret != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - goto cleanup; - } - - if ((ret = memcmp(K1, subkeys, block_size)) != 0 || - (ret = memcmp(K2, &subkeys[block_size], block_size)) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - -next_test: - mbedtls_cipher_free(&ctx); - } - - ret = 0; - goto exit; - -cleanup: - mbedtls_cipher_free(&ctx); - -exit: - return ret; -} - -static int cmac_test_wth_cipher(int verbose, - const char *testname, - const unsigned char *key, - int keybits, - const unsigned char *messages, - const unsigned int message_lengths[4], - const unsigned char *expected_result, - mbedtls_cipher_type_t cipher_type, - int block_size, - int num_tests) -{ - const mbedtls_cipher_info_t *cipher_info; - int i, ret = 0; - unsigned char output[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; - - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto exit; - } - - for (i = 0; i < num_tests; i++) { - if (verbose != 0) { - mbedtls_printf(" %s CMAC #%d: ", testname, i + 1); - } - - if ((ret = mbedtls_cipher_cmac(cipher_info, key, keybits, messages, - message_lengths[i], output)) != 0) { - /* When CMAC is implemented by an alternative implementation, or - * the underlying primitive itself is implemented alternatively, - * AES-192 and/or 3DES may be unavailable. This should not cause - * the selftest function to fail. */ - if ((ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED || - ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) && - (cipher_type == MBEDTLS_CIPHER_AES_192_ECB || - cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB)) { - if (verbose != 0) { - mbedtls_printf("skipped\n"); - } - continue; - } - - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - goto exit; - } - - if ((ret = memcmp(output, &expected_result[i * block_size], block_size)) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - ret = 0; - -exit: - return ret; -} - -#if defined(MBEDTLS_AES_C) -static int test_aes128_cmac_prf(int verbose) -{ - int i; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; - - for (i = 0; i < NB_PRF_TESTS; i++) { - mbedtls_printf(" AES CMAC 128 PRF #%d: ", i); - ret = mbedtls_aes_cmac_prf_128(PRFK, PRFKlen[i], PRFM, 20, output); - if (ret != 0 || - memcmp(output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE) != 0) { - - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return ret; - } else if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - return ret; -} -#endif /* MBEDTLS_AES_C */ - -int mbedtls_cmac_self_test(int verbose) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_AES_C) - /* AES-128 */ - if ((ret = cmac_test_subkeys(verbose, - "AES 128", - aes_128_key, - 128, - (const unsigned char *) aes_128_subkeys, - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } - - if ((ret = cmac_test_wth_cipher(verbose, - "AES 128", - aes_128_key, - 128, - test_message, - aes_message_lengths, - (const unsigned char *) aes_128_expected_result, - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } - - /* AES-192 */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - if ((ret = cmac_test_subkeys(verbose, - "AES 192", - aes_192_key, - 192, - (const unsigned char *) aes_192_subkeys, - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } - - if ((ret = cmac_test_wth_cipher(verbose, - "AES 192", - aes_192_key, - 192, - test_message, - aes_message_lengths, - (const unsigned char *) aes_192_expected_result, - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ - - /* AES-256 */ -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - if ((ret = cmac_test_subkeys(verbose, - "AES 256", - aes_256_key, - 256, - (const unsigned char *) aes_256_subkeys, - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } - - if ((ret = cmac_test_wth_cipher(verbose, - "AES 256", - aes_256_key, - 256, - test_message, - aes_message_lengths, - (const unsigned char *) aes_256_expected_result, - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_AES_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_DES_C) - /* 3DES 2 key */ - if ((ret = cmac_test_subkeys(verbose, - "3DES 2 key", - des3_2key_key, - 192, - (const unsigned char *) des3_2key_subkeys, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } - - if ((ret = cmac_test_wth_cipher(verbose, - "3DES 2 key", - des3_2key_key, - 192, - test_message, - des3_message_lengths, - (const unsigned char *) des3_2key_expected_result, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } - - /* 3DES 3 key */ - if ((ret = cmac_test_subkeys(verbose, - "3DES 3 key", - des3_3key_key, - 192, - (const unsigned char *) des3_3key_subkeys, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } - - if ((ret = cmac_test_wth_cipher(verbose, - "3DES 3 key", - des3_3key_key, - 192, - test_message, - des3_message_lengths, - (const unsigned char *) des3_3key_expected_result, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_DES3_BLOCK_SIZE, - NB_CMAC_TESTS_PER_KEY)) != 0) { - return ret; - } -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if ((ret = test_aes128_cmac_prf(verbose)) != 0) { - return ret; - } -#endif /* MBEDTLS_AES_C */ - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CMAC_C */ diff --git a/vendor/mbedtls/library/common.h b/vendor/mbedtls/library/common.h deleted file mode 100644 index 1f59b3242..000000000 --- a/vendor/mbedtls/library/common.h +++ /dev/null @@ -1,487 +0,0 @@ -/** - * \file common.h - * - * \brief Utility macros for internal use in the library - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_LIBRARY_COMMON_H -#define MBEDTLS_LIBRARY_COMMON_H - -#include "mbedtls/build_info.h" -#include "alignment.h" - -#include -#include -#include -#include - -#if defined(__ARM_NEON) -#include -#define MBEDTLS_HAVE_NEON_INTRINSICS -#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) -#include -#define MBEDTLS_HAVE_NEON_INTRINSICS -#endif - -/* Decide whether we're built for a Unix-like platform. - */ -#if defined(MBEDTLS_TEST_PLATFORM_IS_NOT_UNIXLIKE) //no-check-names -/* We may be building on a Unix-like platform, but for test purposes, - * do not try to use Unix features. */ -#elif defined(_WIN32) -/* If Windows platform interfaces are available, we use them, even if - * a Unix-like might also to be available. */ -/* defined(_WIN32) ==> we can include */ -#elif defined(unix) || defined(__unix) || defined(__unix__) || \ - (defined(__APPLE__) && defined(__MACH__)) || \ - defined(__HAIKU__) || \ - defined(__midipix__) || \ - /* Add other Unix-like platform indicators here ^^^^ */ 0 -/* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) ==> we can include */ -#define MBEDTLS_PLATFORM_IS_UNIXLIKE -#endif - -/** Helper to define a function as static except when building invasive tests. - * - * If a function is only used inside its own source file and should be - * declared `static` to allow the compiler to optimize for code size, - * but that function has unit tests, define it with - * ``` - * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... } - * ``` - * and declare it in a header in the `library/` directory with - * ``` - * #if defined(MBEDTLS_TEST_HOOKS) - * int mbedtls_foo(...); - * #endif - * ``` - */ -#if defined(MBEDTLS_TEST_HOOKS) -#define MBEDTLS_STATIC_TESTABLE -#else -#define MBEDTLS_STATIC_TESTABLE static -#endif - -#if defined(MBEDTLS_TEST_HOOKS) -extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file); -#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \ - do { \ - if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \ - { \ - (*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \ - } \ - } while (0) -#else -#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) -#endif /* defined(MBEDTLS_TEST_HOOKS) */ - -/** \def ARRAY_LENGTH - * Return the number of elements of a static or stack array. - * - * \param array A value of array (not pointer) type. - * - * \return The number of elements of the array. - */ -/* A correct implementation of ARRAY_LENGTH, but which silently gives - * a nonsensical result if called with a pointer rather than an array. */ -#define ARRAY_LENGTH_UNSAFE(array) \ - (sizeof(array) / sizeof(*(array))) - -#if defined(__GNUC__) -/* Test if arg and &(arg)[0] have the same type. This is true if arg is - * an array but not if it's a pointer. */ -#define IS_ARRAY_NOT_POINTER(arg) \ - (!__builtin_types_compatible_p(__typeof__(arg), \ - __typeof__(&(arg)[0]))) -/* A compile-time constant with the value 0. If `const_expr` is not a - * compile-time constant with a nonzero value, cause a compile-time error. */ -#define STATIC_ASSERT_EXPR(const_expr) \ - (0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); })) - -/* Return the scalar value `value` (possibly promoted). This is a compile-time - * constant if `value` is. `condition` must be a compile-time constant. - * If `condition` is false, arrange to cause a compile-time error. */ -#define STATIC_ASSERT_THEN_RETURN(condition, value) \ - (STATIC_ASSERT_EXPR(condition) ? 0 : (value)) - -#define ARRAY_LENGTH(array) \ - (STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \ - ARRAY_LENGTH_UNSAFE(array))) - -#else -/* If we aren't sure the compiler supports our non-standard tricks, - * fall back to the unsafe implementation. */ -#define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array) -#endif - -#if defined(__has_builtin) -#define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x) -#else -#define MBEDTLS_HAS_BUILTIN(x) 0 -#endif - -/** Allow library to access its structs' private members. - * - * Although structs defined in header files are publicly available, - * their members are private and should not be accessed by the user. - */ -#define MBEDTLS_ALLOW_PRIVATE_ACCESS - -/** - * \brief Securely zeroize a buffer then free it. - * - * Similar to making consecutive calls to - * \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has - * code size savings, and potential for optimisation in the future. - * - * Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0. - * - * \param buf Buffer to be zeroized then freed. - * \param len Length of the buffer in bytes - */ -void mbedtls_zeroize_and_free(void *buf, size_t len); - -/** Return an offset into a buffer. - * - * This is just the addition of an offset to a pointer, except that this - * function also accepts an offset of 0 into a buffer whose pointer is null. - * (`p + n` has undefined behavior when `p` is null, even when `n == 0`. - * A null pointer is a valid buffer pointer when the size is 0, for example - * as the result of `malloc(0)` on some platforms.) - * - * \param p Pointer to a buffer of at least n bytes. - * This may be \p NULL if \p n is zero. - * \param n An offset in bytes. - * \return Pointer to offset \p n in the buffer \p p. - * Note that this is only a valid pointer if the size of the - * buffer is at least \p n + 1. - */ -static inline unsigned char *mbedtls_buffer_offset( - unsigned char *p, size_t n) -{ - return p == NULL ? NULL : p + n; -} - -/** Return an offset into a read-only buffer. - * - * Similar to mbedtls_buffer_offset(), but for const pointers. - * - * \param p Pointer to a buffer of at least n bytes. - * This may be \p NULL if \p n is zero. - * \param n An offset in bytes. - * \return Pointer to offset \p n in the buffer \p p. - * Note that this is only a valid pointer if the size of the - * buffer is at least \p n + 1. - */ -static inline const unsigned char *mbedtls_buffer_offset_const( - const unsigned char *p, size_t n) -{ - return p == NULL ? NULL : p + n; -} - -/* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -/** - * Perform a fast block XOR operation, such that - * r[i] = a[i] ^ b[i] where 0 <= i < n - * - * \param r Pointer to result (buffer of at least \p n bytes). \p r - * may be equal to either \p a or \p b, but behaviour when - * it overlaps in other ways is undefined. - * \param a Pointer to input (buffer of at least \p n bytes) - * \param b Pointer to input (buffer of at least \p n bytes) - * \param n Number of bytes to process. - * - * \note Depending on the situation, it may be faster to use either mbedtls_xor() or - * mbedtls_xor_no_simd() (these are functionally equivalent). - * If the result is used immediately after the xor operation in non-SIMD code (e.g, in - * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar - * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where - * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster. - * For targets without SIMD support, they will behave the same. - */ -static inline void mbedtls_xor(unsigned char *r, - const unsigned char *a, - const unsigned char *b, - size_t n) -{ - size_t i = 0; -#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) -#if defined(MBEDTLS_HAVE_NEON_INTRINSICS) && \ - (!(defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_GCC_VERSION < 70300)) - /* Old GCC versions generate a warning here, so disable the NEON path for these compilers */ - for (; (i + 16) <= n; i += 16) { - uint8x16_t v1 = vld1q_u8(a + i); - uint8x16_t v2 = vld1q_u8(b + i); - uint8x16_t x = veorq_u8(v1, v2); - vst1q_u8(r + i, x); - } -#if defined(__IAR_SYSTEMS_ICC__) - /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case - * where n is a constant multiple of 16. - * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time - * constant, and is a very small perf regression if n is not a compile-time constant. */ - if (n % 16 == 0) { - return; - } -#endif -#if defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_HAS_BUILTIN(__builtin_constant_p) - if (__builtin_constant_p(n) && n % 16 == 0) { - return; - } -#endif -#elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) - /* This codepath probably only makes sense on architectures with 64-bit registers */ - for (; (i + 8) <= n; i += 8) { - uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); - mbedtls_put_unaligned_uint64(r + i, x); - } -#if defined(__IAR_SYSTEMS_ICC__) - if (n % 8 == 0) { - return; - } -#endif -#if defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_HAS_BUILTIN(__builtin_constant_p) - if (__builtin_constant_p(n) && n % 8 == 0) { - return; - } -#endif -#else - for (; (i + 4) <= n; i += 4) { - uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); - mbedtls_put_unaligned_uint32(r + i, x); - } -#if defined(__IAR_SYSTEMS_ICC__) - if (n % 4 == 0) { - return; - } -#endif -#if defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_HAS_BUILTIN(__builtin_constant_p) - if (__builtin_constant_p(n) && n % 4 == 0) { - return; - } -#endif -#endif -#endif - for (; i < n; i++) { - r[i] = a[i] ^ b[i]; - } -} - -/* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get - * inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */ -#if defined(__IAR_SYSTEMS_ICC__) -#pragma inline = forced -#elif defined(__GNUC__) -__attribute__((always_inline)) -#endif -/** - * Perform a fast block XOR operation, such that - * r[i] = a[i] ^ b[i] where 0 <= i < n - * - * In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5% - * better in AES-CBC). - * - * \param r Pointer to result (buffer of at least \p n bytes). \p r - * may be equal to either \p a or \p b, but behaviour when - * it overlaps in other ways is undefined. - * \param a Pointer to input (buffer of at least \p n bytes) - * \param b Pointer to input (buffer of at least \p n bytes) - * \param n Number of bytes to process. - * - * \note Depending on the situation, it may be faster to use either mbedtls_xor() or - * mbedtls_xor_no_simd() (these are functionally equivalent). - * If the result is used immediately after the xor operation in non-SIMD code (e.g, in - * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar - * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where - * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster. - * For targets without SIMD support, they will behave the same. - */ -static inline void mbedtls_xor_no_simd(unsigned char *r, - const unsigned char *a, - const unsigned char *b, - size_t n) -{ - size_t i = 0; -#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) -#if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) - /* This codepath probably only makes sense on architectures with 64-bit registers */ - for (; (i + 8) <= n; i += 8) { - uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); - mbedtls_put_unaligned_uint64(r + i, x); - } -#if defined(__IAR_SYSTEMS_ICC__) - /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case - * where n is a constant multiple of 8. - * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time - * constant, and is a very small perf regression if n is not a compile-time constant. */ - if (n % 8 == 0) { - return; - } -#endif -#else - for (; (i + 4) <= n; i += 4) { - uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); - mbedtls_put_unaligned_uint32(r + i, x); - } -#if defined(__IAR_SYSTEMS_ICC__) - if (n % 4 == 0) { - return; - } -#endif -#endif -#endif - for (; i < n; i++) { - r[i] = a[i] ^ b[i]; - } -} - -/* Fix MSVC C99 compatible issue - * MSVC support __func__ from visual studio 2015( 1900 ) - * Use MSVC predefine macro to avoid name check fail. - */ -#if (defined(_MSC_VER) && (_MSC_VER <= 1900)) -#define /*no-check-names*/ __func__ __FUNCTION__ -#endif - -/* Define `asm` for compilers which don't define it. */ -/* *INDENT-OFF* */ -#ifndef asm -#if defined(__IAR_SYSTEMS_ICC__) -#define asm __asm -#else -#define asm __asm__ -#endif -#endif -/* *INDENT-ON* */ - -/* - * Define the constraint used for read-only pointer operands to aarch64 asm. - * - * This is normally the usual "r", but for aarch64_32 (aka ILP32, - * as found in watchos), "p" is required to avoid warnings from clang. - * - * Note that clang does not recognise '+p' or '=p', and armclang - * does not recognise 'p' at all. Therefore, to update a pointer from - * aarch64 assembly, it is necessary to use something like: - * - * uintptr_t uptr = (uintptr_t) ptr; - * asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : ) - * ptr = (void*) uptr; - * - * Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings. - */ -#if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM) -#if UINTPTR_MAX == 0xfffffffful -/* ILP32: Specify the pointer operand slightly differently, as per #7787. */ -#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p" -#elif UINTPTR_MAX == 0xfffffffffffffffful -/* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */ -#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r" -#else -#error "Unrecognised pointer size for aarch64" -#endif -#endif - -/* Always provide a static assert macro, so it can be used unconditionally. - * It does nothing on systems where we don't know how to define a static assert. - */ -/* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it - * defines static_assert even with -std=c99, but then complains about it. - */ -#if defined(static_assert) && !defined(__FreeBSD__) -#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg) -#else -/* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and - * outside a function. We choose a struct declaration, which can be repeated - * any number of times and does not need a matching definition. */ -#define MBEDTLS_STATIC_ASSERT(expr, msg) \ - struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function -#endif - -/* Define compiler branch hints */ -#if MBEDTLS_HAS_BUILTIN(__builtin_expect) -#define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1) -#define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0) -#else -#define MBEDTLS_LIKELY(x) x -#define MBEDTLS_UNLIKELY(x) x -#endif - -/* MBEDTLS_ASSUME may be used to provide additional information to the compiler - * which can result in smaller code-size. */ -#if MBEDTLS_HAS_BUILTIN(__builtin_assume) -/* clang provides __builtin_assume */ -#define MBEDTLS_ASSUME(x) __builtin_assume(x) -#elif MBEDTLS_HAS_BUILTIN(__builtin_unreachable) -/* gcc and IAR can use __builtin_unreachable */ -#define MBEDTLS_ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while (0) -#elif defined(_MSC_VER) -/* Supported by MSVC since VS 2005 */ -#define MBEDTLS_ASSUME(x) __assume(x) -#else -#define MBEDTLS_ASSUME(x) do { } while (0) -#endif - -/* For gcc -Os, override with -O2 for a given function. - * - * This will not affect behaviour for other optimisation settings, e.g. -O0. - */ -#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__) -#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2"))) -#else -#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE -#endif - -/* Suppress compiler warnings for unused functions and variables. */ -#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__has_attribute) -# if __has_attribute(unused) -# define MBEDTLS_MAYBE_UNUSED __attribute__((unused)) -# endif -#endif -#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__GNUC__) -# define MBEDTLS_MAYBE_UNUSED __attribute__((unused)) -#endif -#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__IAR_SYSTEMS_ICC__) && defined(__VER__) -/* IAR does support __attribute__((unused)), but only if the -e flag (extended language support) - * is given; the pragma always works. - * Unfortunately the pragma affects the rest of the file where it is used, but this is harmless. - * Check for version 5.2 or later - this pragma may be supported by earlier versions, but I wasn't - * able to find documentation). - */ -# if (__VER__ >= 5020000) -# define MBEDTLS_MAYBE_UNUSED _Pragma("diag_suppress=Pe177") -# endif -#endif -#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(_MSC_VER) -# define MBEDTLS_MAYBE_UNUSED __pragma(warning(suppress:4189)) -#endif -#if !defined(MBEDTLS_MAYBE_UNUSED) -# define MBEDTLS_MAYBE_UNUSED -#endif - -/* GCC >= 15 has a warning 'unterminated-string-initialization' which complains if you initialize - * a string into an array without space for a terminating NULL character. In some places in the - * codebase this behaviour is intended, so we add the macro MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING - * to suppress the warning in these places. - */ -#if defined(__has_attribute) -#if __has_attribute(nonstring) -#define MBEDTLS_HAS_ATTRIBUTE_NONSTRING -#endif /* __has_attribute(nonstring) */ -#endif /* __has_attribute */ -#if defined(MBEDTLS_HAS_ATTRIBUTE_NONSTRING) -#define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING __attribute__((nonstring)) -#else -#define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING -#endif /* MBEDTLS_HAS_ATTRIBUTE_NONSTRING */ - -#endif /* MBEDTLS_LIBRARY_COMMON_H */ diff --git a/vendor/mbedtls/library/constant_time.c b/vendor/mbedtls/library/constant_time.c deleted file mode 100644 index afea99c7e..000000000 --- a/vendor/mbedtls/library/constant_time.c +++ /dev/null @@ -1,247 +0,0 @@ -/** - * Constant-time functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The following functions are implemented without using comparison operators, as those - * might be translated to branches by some compilers on some platforms. - */ - -#include "common.h" -#include "constant_time_internal.h" -#include "mbedtls/constant_time.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" - -#include -#include -#include - -#if !defined(MBEDTLS_CT_ASM) -/* - * Define an object with the value zero, such that the compiler cannot prove that it - * has the value zero (because it is volatile, it "may be modified in ways unknown to - * the implementation"). - */ -volatile mbedtls_ct_uint_t mbedtls_ct_zero = 0; -#endif - -/* - * Define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS where assembly is present to - * perform fast unaligned access to volatile data. - * - * This is needed because mbedtls_get_unaligned_uintXX etc don't support volatile - * memory accesses. - * - * Some of these definitions could be moved into alignment.h but for now they are - * only used here. - */ -#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && \ - ((defined(MBEDTLS_CT_ARM_ASM) && (UINTPTR_MAX == 0xfffffffful)) || \ - defined(MBEDTLS_CT_AARCH64_ASM)) -/* We check pointer sizes to avoid issues with them not matching register size requirements */ -#define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS - -static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsigned char *p) -{ - /* This is UB, even where it's safe: - * return *((volatile uint32_t*)p); - * so instead the same thing is expressed in assembly below. - */ - uint32_t r; -#if defined(MBEDTLS_CT_ARM_ASM) - asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); -#elif defined(MBEDTLS_CT_AARCH64_ASM) - asm volatile ("ldr %w0, [%1]" : "=r" (r) : MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT(p) :); -#else -#error "No assembly defined for mbedtls_get_unaligned_volatile_uint32" -#endif - return r; -} -#endif /* defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && - (defined(MBEDTLS_CT_ARM_ASM) || defined(MBEDTLS_CT_AARCH64_ASM)) */ - -int mbedtls_ct_memcmp(const void *a, - const void *b, - size_t n) -{ - size_t i = 0; - /* - * `A` and `B` are cast to volatile to ensure that the compiler - * generates code that always fully reads both buffers. - * Otherwise it could generate a test to exit early if `diff` has all - * bits set early in the loop. - */ - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - uint32_t diff = 0; - -#if defined(MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS) - for (; (i + 4) <= n; i += 4) { - uint32_t x = mbedtls_get_unaligned_volatile_uint32(A + i); - uint32_t y = mbedtls_get_unaligned_volatile_uint32(B + i); - diff |= x ^ y; - } -#endif - - for (; i < n; i++) { - /* Read volatile data in order before computing diff. - * This avoids IAR compiler warning: - * 'the order of volatile accesses is undefined ..' */ - unsigned char x = A[i], y = B[i]; - diff |= x ^ y; - } - - -#if (INT_MAX < INT32_MAX) - /* We don't support int smaller than 32-bits, but if someone tried to build - * with this configuration, there is a risk that, for differing data, the - * only bits set in diff are in the top 16-bits, and would be lost by a - * simple cast from uint32 to int. - * This would have significant security implications, so protect against it. */ -#error "mbedtls_ct_memcmp() requires minimum 32-bit ints" -#else - /* The bit-twiddling ensures that when we cast uint32_t to int, we are casting - * a value that is in the range 0..INT_MAX - a value larger than this would - * result in implementation defined behaviour. - * - * This ensures that the value returned by the function is non-zero iff - * diff is non-zero. - */ - return (int) ((diff & 0xffff) | (diff >> 16)); -#endif -} - -#if defined(MBEDTLS_NIST_KW_C) - -int mbedtls_ct_memcmp_partial(const void *a, - const void *b, - size_t n, - size_t skip_head, - size_t skip_tail) -{ - unsigned int diff = 0; - - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - - size_t valid_end = n - skip_tail; - - for (size_t i = 0; i < n; i++) { - unsigned char x = A[i], y = B[i]; - unsigned int d = x ^ y; - mbedtls_ct_condition_t valid = mbedtls_ct_bool_and(mbedtls_ct_uint_ge(i, skip_head), - mbedtls_ct_uint_lt(i, valid_end)); - diff |= mbedtls_ct_uint_if_else_0(valid, d); - } - - /* Since we go byte-by-byte, the only bits set will be in the bottom 8 bits, so the - * cast from uint to int is safe. */ - return (int) diff; -} - -#endif - -#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) - -void mbedtls_ct_memmove_left(void *start, size_t total, size_t offset) -{ - volatile unsigned char *buf = start; - for (size_t i = 0; i < total; i++) { - mbedtls_ct_condition_t no_op = mbedtls_ct_uint_gt(total - offset, i); - /* The first `total - offset` passes are a no-op. The last - * `offset` passes shift the data one byte to the left and - * zero out the last byte. */ - for (size_t n = 0; n < total - 1; n++) { - unsigned char current = buf[n]; - unsigned char next = buf[n+1]; - buf[n] = mbedtls_ct_uint_if(no_op, current, next); - } - buf[total-1] = mbedtls_ct_uint_if_else_0(no_op, buf[total-1]); - } -} - -#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */ - -void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, - unsigned char *dest, - const unsigned char *src1, - const unsigned char *src2, - size_t len) -{ -#if defined(MBEDTLS_CT_SIZE_64) - const uint64_t mask = (uint64_t) condition; - const uint64_t not_mask = (uint64_t) ~mbedtls_ct_compiler_opaque(condition); -#else - const uint32_t mask = (uint32_t) condition; - const uint32_t not_mask = (uint32_t) ~mbedtls_ct_compiler_opaque(condition); -#endif - - /* If src2 is NULL, setup src2 so that we read from the destination address. - * - * This means that if src2 == NULL && condition is false, the result will be a - * no-op because we read from dest and write the same data back into dest. - */ - if (src2 == NULL) { - src2 = dest; - } - - /* dest[i] = c1 == c2 ? src[i] : dest[i] */ - size_t i = 0; -#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) -#if defined(MBEDTLS_CT_SIZE_64) - for (; (i + 8) <= len; i += 8) { - uint64_t a = mbedtls_get_unaligned_uint64(src1 + i) & mask; - uint64_t b = mbedtls_get_unaligned_uint64(src2 + i) & not_mask; - mbedtls_put_unaligned_uint64(dest + i, a | b); - } -#else - for (; (i + 4) <= len; i += 4) { - uint32_t a = mbedtls_get_unaligned_uint32(src1 + i) & mask; - uint32_t b = mbedtls_get_unaligned_uint32(src2 + i) & not_mask; - mbedtls_put_unaligned_uint32(dest + i, a | b); - } -#endif /* defined(MBEDTLS_CT_SIZE_64) */ -#endif /* MBEDTLS_EFFICIENT_UNALIGNED_ACCESS */ - for (; i < len; i++) { - dest[i] = (src1[i] & mask) | (src2[i] & not_mask); - } -} - -void mbedtls_ct_memcpy_offset(unsigned char *dest, - const unsigned char *src, - size_t offset, - size_t offset_min, - size_t offset_max, - size_t len) -{ - size_t offsetval; - - for (offsetval = offset_min; offsetval <= offset_max; offsetval++) { - mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offsetval, offset), dest, src + offsetval, NULL, - len); - } -} - -#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) - -void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len) -{ - uint32_t mask = (uint32_t) ~condition; - uint8_t *p = (uint8_t *) buf; - size_t i = 0; -#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) - for (; (i + 4) <= len; i += 4) { - mbedtls_put_unaligned_uint32((void *) (p + i), - mbedtls_get_unaligned_uint32((void *) (p + i)) & mask); - } -#endif - for (; i < len; i++) { - p[i] = p[i] & mask; - } -} - -#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */ diff --git a/vendor/mbedtls/library/constant_time_impl.h b/vendor/mbedtls/library/constant_time_impl.h deleted file mode 100644 index aeaeecb7d..000000000 --- a/vendor/mbedtls/library/constant_time_impl.h +++ /dev/null @@ -1,541 +0,0 @@ -/** - * Constant-time functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONSTANT_TIME_IMPL_H -#define MBEDTLS_CONSTANT_TIME_IMPL_H - -#include - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -/* - * To improve readability of constant_time_internal.h, the static inline - * definitions are here, and constant_time_internal.h has only the declarations. - * - * This results in duplicate declarations of the form: - * static inline void f(); // from constant_time_internal.h - * static inline void f() { ... } // from constant_time_impl.h - * when constant_time_internal.h is included. - * - * This appears to behave as if the declaration-without-definition was not present - * (except for warnings if gcc -Wredundant-decls or similar is used). - * - * Disable -Wredundant-decls so that gcc does not warn about this. This is re-enabled - * at the bottom of this file. - */ -#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wredundant-decls" -#endif - -/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ -#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && (!defined(__ARMCC_VERSION) || \ - __ARMCC_VERSION >= 6000000) -#define MBEDTLS_CT_ASM -#if (defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) -#define MBEDTLS_CT_ARM_ASM -#elif defined(__aarch64__) -#define MBEDTLS_CT_AARCH64_ASM -#elif defined(__amd64__) || defined(__x86_64__) -#define MBEDTLS_CT_X86_64_ASM -#elif defined(__i386__) -#define MBEDTLS_CT_X86_ASM -#endif -#endif - -#define MBEDTLS_CT_SIZE (sizeof(mbedtls_ct_uint_t) * 8) - - -/* ============================================================================ - * Core const-time primitives - */ - -/* Ensure that the compiler cannot know the value of x (i.e., cannot optimise - * based on its value) after this function is called. - * - * If we are not using assembly, this will be fairly inefficient, so its use - * should be minimised. - */ - -#if !defined(MBEDTLS_CT_ASM) -extern volatile mbedtls_ct_uint_t mbedtls_ct_zero; -#endif - -/** - * \brief Ensure that a value cannot be known at compile time. - * - * \param x The value to hide from the compiler. - * \return The same value that was passed in, such that the compiler - * cannot prove its value (even for calls of the form - * x = mbedtls_ct_compiler_opaque(1), x will be unknown). - * - * \note This is mainly used in constructing mbedtls_ct_condition_t - * values and performing operations over them, to ensure that - * there is no way for the compiler to ever know anything about - * the value of an mbedtls_ct_condition_t. - */ -static inline mbedtls_ct_uint_t mbedtls_ct_compiler_opaque(mbedtls_ct_uint_t x) -{ -#if defined(MBEDTLS_CT_ASM) - asm volatile ("" : [x] "+r" (x) :); - return x; -#else - return x ^ mbedtls_ct_zero; -#endif -} - -/* - * Selecting unified syntax is needed for gcc, and harmless on clang. - * - * This is needed because on Thumb 1, condition flags are always set, so - * e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist). - * - * Under Thumb 1 unified syntax, only the "negs" form is accepted, and - * under divided syntax, only the "neg" form is accepted. clang only - * supports unified syntax. - * - * On Thumb 2 and Arm, both compilers are happy with the "s" suffix, - * although we don't actually care about setting the flags. - * - * For old versions of gcc (see #8516 for details), restore divided - * syntax afterwards - otherwise old versions of gcc seem to apply - * unified syntax globally, which breaks other asm code. - */ -#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__thumb__) && !defined(__thumb2__) && \ - (__GNUC__ < 11) && !defined(__ARM_ARCH_2__) -#define RESTORE_ASM_SYNTAX ".syntax divided \n\t" -#else -#define RESTORE_ASM_SYNTAX -#endif - -/* Convert a number into a condition in constant time. */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) -{ - /* - * Define mask-generation code that, as far as possible, will not use branches or conditional instructions. - * - * For some platforms / type sizes, we define assembly to assure this. - * - * Otherwise, we define a plain C fallback which (in May 2023) does not get optimised into - * conditional instructions or branches by trunk clang, gcc, or MSVC v19. - */ -#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) - mbedtls_ct_uint_t s; - asm volatile ("neg %x[s], %x[x] \n\t" - "orr %x[x], %x[s], %x[x] \n\t" - "asr %x[x], %x[x], 63 \n\t" - : - [s] "=&r" (s), - [x] "+&r" (x) - : - : - ); - return (mbedtls_ct_condition_t) x; -#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) - uint32_t s; - asm volatile (".syntax unified \n\t" - "negs %[s], %[x] \n\t" - "orrs %[x], %[x], %[s] \n\t" - "asrs %[x], %[x], #31 \n\t" - RESTORE_ASM_SYNTAX - : - [s] "=&l" (s), - [x] "+&l" (x) - : - : - "cc" /* clobbers flag bits */ - ); - return (mbedtls_ct_condition_t) x; -#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) - uint64_t s; - asm volatile ("mov %[x], %[s] \n\t" - "neg %[s] \n\t" - "or %[x], %[s] \n\t" - "sar $63, %[s] \n\t" - : - [s] "=&a" (s) - : - [x] "D" (x) - : - ); - return (mbedtls_ct_condition_t) s; -#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32) - uint32_t s; - asm volatile ("mov %[x], %[s] \n\t" - "neg %[s] \n\t" - "or %[s], %[x] \n\t" - "sar $31, %[x] \n\t" - : - [s] "=&c" (s), - [x] "+&a" (x) - : - : - ); - return (mbedtls_ct_condition_t) x; -#else - const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); -#if defined(_MSC_VER) - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - // y is negative (i.e., top bit set) iff x is non-zero - mbedtls_ct_int_t y = (-xo) | -(xo >> 1); - - // extract only the sign bit of y so that y == 1 (if x is non-zero) or 0 (if x is zero) - y = (((mbedtls_ct_uint_t) y) >> (MBEDTLS_CT_SIZE - 1)); - - // -y has all bits set (if x is non-zero), or all bits clear (if x is zero) - return (mbedtls_ct_condition_t) (-y); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif -#endif -} - -static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition, - mbedtls_ct_uint_t if1, - mbedtls_ct_uint_t if0) -{ -#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) - asm volatile ("and %x[if1], %x[if1], %x[condition] \n\t" - "mvn %x[condition], %x[condition] \n\t" - "and %x[condition], %x[condition], %x[if0] \n\t" - "orr %x[condition], %x[if1], %x[condition]" - : - [condition] "+&r" (condition), - [if1] "+&r" (if1) - : - [if0] "r" (if0) - : - ); - return (mbedtls_ct_uint_t) condition; -#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) - asm volatile (".syntax unified \n\t" - "ands %[if1], %[if1], %[condition] \n\t" - "mvns %[condition], %[condition] \n\t" - "ands %[condition], %[condition], %[if0] \n\t" - "orrs %[condition], %[if1], %[condition] \n\t" - RESTORE_ASM_SYNTAX - : - [condition] "+&l" (condition), - [if1] "+&l" (if1) - : - [if0] "l" (if0) - : - "cc" - ); - return (mbedtls_ct_uint_t) condition; -#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) - asm volatile ("and %[condition], %[if1] \n\t" - "not %[condition] \n\t" - "and %[condition], %[if0] \n\t" - "or %[if1], %[if0] \n\t" - : - [condition] "+&D" (condition), - [if1] "+&S" (if1), - [if0] "+&a" (if0) - : - : - ); - return if0; -#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32) - asm volatile ("and %[condition], %[if1] \n\t" - "not %[condition] \n\t" - "and %[if0], %[condition] \n\t" - "or %[condition], %[if1] \n\t" - : - [condition] "+&c" (condition), - [if1] "+&a" (if1) - : - [if0] "b" (if0) - : - ); - return if1; -#else - mbedtls_ct_condition_t not_cond = - (mbedtls_ct_condition_t) (~mbedtls_ct_compiler_opaque(condition)); - return (mbedtls_ct_uint_t) ((condition & if1) | (not_cond & if0)); -#endif -} - -static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) -{ -#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) - uint64_t s1; - asm volatile ("eor %x[s1], %x[y], %x[x] \n\t" - "sub %x[x], %x[x], %x[y] \n\t" - "bic %x[x], %x[x], %x[s1] \n\t" - "and %x[s1], %x[s1], %x[y] \n\t" - "orr %x[s1], %x[x], %x[s1] \n\t" - "asr %x[x], %x[s1], 63" - : - [s1] "=&r" (s1), - [x] "+&r" (x) - : - [y] "r" (y) - : - ); - return (mbedtls_ct_condition_t) x; -#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) - uint32_t s1; - asm volatile ( - ".syntax unified \n\t" -#if defined(__thumb__) && !defined(__thumb2__) - "movs %[s1], %[x] \n\t" - "eors %[s1], %[s1], %[y] \n\t" -#else - "eors %[s1], %[x], %[y] \n\t" -#endif - "subs %[x], %[x], %[y] \n\t" - "bics %[x], %[x], %[s1] \n\t" - "ands %[y], %[s1], %[y] \n\t" - "orrs %[x], %[x], %[y] \n\t" - "asrs %[x], %[x], #31 \n\t" - RESTORE_ASM_SYNTAX - : - [s1] "=&l" (s1), - [x] "+&l" (x), - [y] "+&l" (y) - : - : - "cc" - ); - return (mbedtls_ct_condition_t) x; -#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) - uint64_t s; - asm volatile ("mov %[x], %[s] \n\t" - "xor %[y], %[s] \n\t" - "sub %[y], %[x] \n\t" - "and %[s], %[y] \n\t" - "not %[s] \n\t" - "and %[s], %[x] \n\t" - "or %[y], %[x] \n\t" - "sar $63, %[x] \n\t" - : - [s] "=&a" (s), - [x] "+&D" (x), - [y] "+&S" (y) - : - : - ); - return (mbedtls_ct_condition_t) x; -#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32) - uint32_t s; - asm volatile ("mov %[x], %[s] \n\t" - "xor %[y], %[s] \n\t" - "sub %[y], %[x] \n\t" - "and %[s], %[y] \n\t" - "not %[s] \n\t" - "and %[s], %[x] \n\t" - "or %[y], %[x] \n\t" - "sar $31, %[x] \n\t" - : - [s] "=&b" (s), - [x] "+&a" (x), - [y] "+&c" (y) - : - : - ); - return (mbedtls_ct_condition_t) x; -#else - /* Ensure that the compiler cannot optimise the following operations over x and y, - * even if it knows the value of x and y. - */ - const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); - const mbedtls_ct_uint_t yo = mbedtls_ct_compiler_opaque(y); - /* - * Check if the most significant bits (MSB) of the operands are different. - * cond is true iff the MSBs differ. - */ - mbedtls_ct_condition_t cond = mbedtls_ct_bool((xo ^ yo) >> (MBEDTLS_CT_SIZE - 1)); - - /* - * If the MSB are the same then the difference x-y will be negative (and - * have its MSB set to 1 during conversion to unsigned) if and only if x> (MBEDTLS_CT_SIZE - 1); - - // Convert to a condition (i.e., all bits set iff non-zero) - return mbedtls_ct_bool(ret); -#endif -} - -static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) -{ - /* diff = 0 if x == y, non-zero otherwise */ - const mbedtls_ct_uint_t diff = mbedtls_ct_compiler_opaque(x) ^ mbedtls_ct_compiler_opaque(y); - - /* all ones if x != y, 0 otherwise */ - return mbedtls_ct_bool(diff); -} - -static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low, - unsigned char high, - unsigned char c, - unsigned char t) -{ - const unsigned char co = (unsigned char) mbedtls_ct_compiler_opaque(c); - const unsigned char to = (unsigned char) mbedtls_ct_compiler_opaque(t); - - /* low_mask is: 0 if low <= c, 0x...ff if low > c */ - unsigned low_mask = ((unsigned) co - low) >> 8; - /* high_mask is: 0 if c <= high, 0x...ff if c > high */ - unsigned high_mask = ((unsigned) high - co) >> 8; - - return (unsigned char) (~(low_mask | high_mask)) & to; -} - -/* ============================================================================ - * Everything below here is trivial wrapper functions - */ - -static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition, - size_t if1, - size_t if0) -{ - return (size_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0); -} - -static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition, - unsigned if1, - unsigned if0) -{ - return (unsigned) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition, - mbedtls_ct_condition_t if1, - mbedtls_ct_condition_t if0) -{ - return (mbedtls_ct_condition_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, - (mbedtls_ct_uint_t) if0); -} - -#if defined(MBEDTLS_BIGNUM_C) - -static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, - mbedtls_mpi_uint if1, - mbedtls_mpi_uint if0) -{ - return (mbedtls_mpi_uint) mbedtls_ct_if(condition, - (mbedtls_ct_uint_t) if1, - (mbedtls_ct_uint_t) if0); -} - -#endif - -static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1) -{ - return (size_t) (condition & if1); -} - -static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1) -{ - return (unsigned) (condition & if1); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition, - mbedtls_ct_condition_t if1) -{ - return (mbedtls_ct_condition_t) (condition & if1); -} - -#if defined(MBEDTLS_BIGNUM_C) - -static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition, - mbedtls_mpi_uint if1) -{ - return (mbedtls_mpi_uint) (condition & if1); -} - -#endif /* MBEDTLS_BIGNUM_C */ - -static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0) -{ - /* Coverting int -> uint -> int here is safe, because we require if1 and if0 to be - * in the range -32767..0, and we require 32-bit int and uint types. - * - * This means that (0 <= -if0 < INT_MAX), so negating if0 is safe, and similarly for - * converting back to int. - */ - return -((int) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) (-if1), - (mbedtls_ct_uint_t) (-if0))); -} - -static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1) -{ - return -((int) (condition & (-if1))); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y) -{ - return ~mbedtls_ct_uint_ne(x, y); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y) -{ - return mbedtls_ct_uint_lt(y, x); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y) -{ - return ~mbedtls_ct_uint_lt(x, y); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y) -{ - return ~mbedtls_ct_uint_gt(x, y); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x, - mbedtls_ct_condition_t y) -{ - return (mbedtls_ct_condition_t) (x ^ y); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x, - mbedtls_ct_condition_t y) -{ - return (mbedtls_ct_condition_t) (x & y); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x, - mbedtls_ct_condition_t y) -{ - return (mbedtls_ct_condition_t) (x | y); -} - -static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x) -{ - return (mbedtls_ct_condition_t) (~x); -} - -#if defined(MBEDTLS_COMPILER_IS_GCC) && (__GNUC__ > 4) -/* Restore warnings for -Wredundant-decls on gcc */ - #pragma GCC diagnostic pop -#endif - -#endif /* MBEDTLS_CONSTANT_TIME_IMPL_H */ diff --git a/vendor/mbedtls/library/constant_time_internal.h b/vendor/mbedtls/library/constant_time_internal.h deleted file mode 100644 index 61a5c6d4e..000000000 --- a/vendor/mbedtls/library/constant_time_internal.h +++ /dev/null @@ -1,579 +0,0 @@ -/** - * Constant-time functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H -#define MBEDTLS_CONSTANT_TIME_INTERNAL_H - -#include -#include - -#include "common.h" - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -/* The constant-time interface provides various operations that are likely - * to result in constant-time code that does not branch or use conditional - * instructions for secret data (for secret pointers, this also applies to - * the data pointed to). - * - * It has three main parts: - * - * - boolean operations - * These are all named mbedtls_ct__. - * They operate over and return mbedtls_ct_condition_t. - * All arguments are considered secret. - * example: bool x = y | z => x = mbedtls_ct_bool_or(y, z) - * example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z) - * - * - conditional data selection - * These are all named mbedtls_ct__if and mbedtls_ct__if_else_0 - * All arguments are considered secret. - * example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c) - * example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b) - * - * - block memory operations - * Only some arguments are considered secret, as documented for each - * function. - * example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...) - * - * mbedtls_ct_condition_t must be treated as opaque and only created and - * manipulated via the functions in this header. The compiler should never - * be able to prove anything about its value at compile-time. - * - * mbedtls_ct_uint_t is an unsigned integer type over which constant time - * operations may be performed via the functions in this header. It is as big - * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast - * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other - * not-larger integer types). - * - * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations - * are used to ensure that the generated code is constant time. For other - * architectures, it uses a plain C fallback designed to yield constant-time code - * (this has been observed to be constant-time on latest gcc, clang and MSVC - * as of May 2023). - * - * For readability, the static inline definitions are separated out into - * constant_time_impl.h. - */ - -#if (SIZE_MAX > 0xffffffffffffffffULL) -/* Pointer size > 64-bit */ -typedef size_t mbedtls_ct_condition_t; -typedef size_t mbedtls_ct_uint_t; -typedef ptrdiff_t mbedtls_ct_int_t; -#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX)) -#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64) -/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */ -typedef uint64_t mbedtls_ct_condition_t; -typedef uint64_t mbedtls_ct_uint_t; -typedef int64_t mbedtls_ct_int_t; -#define MBEDTLS_CT_SIZE_64 -#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX)) -#else -/* Pointer size <= 32-bit, and no 64-bit MPIs */ -typedef uint32_t mbedtls_ct_condition_t; -typedef uint32_t mbedtls_ct_uint_t; -typedef int32_t mbedtls_ct_int_t; -#define MBEDTLS_CT_SIZE_32 -#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX)) -#endif -#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0)) - -/* ============================================================================ - * Boolean operations - */ - -/** Convert a number into a mbedtls_ct_condition_t. - * - * \param x Number to convert. - * - * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0 - * - */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x); - -/** Boolean "not equal" operation. - * - * Functionally equivalent to: - * - * \p x != \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); - -/** Boolean "equals" operation. - * - * Functionally equivalent to: - * - * \p x == \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y); - -/** Boolean "less than" operation. - * - * Functionally equivalent to: - * - * \p x < \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); - -/** Boolean "greater than" operation. - * - * Functionally equivalent to: - * - * \p x > \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y); - -/** Boolean "greater or equal" operation. - * - * Functionally equivalent to: - * - * \p x >= \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x >= \p y, - * otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y); - -/** Boolean "less than or equal" operation. - * - * Functionally equivalent to: - * - * \p x <= \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x <= \p y, - * otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x, - mbedtls_ct_uint_t y); - -/** Boolean not-equals operation. - * - * Functionally equivalent to: - * - * \p x != \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \note This is more efficient than mbedtls_ct_uint_ne if both arguments are - * mbedtls_ct_condition_t. - * - * \return MBEDTLS_CT_TRUE if \p x != \p y, - * otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x, - mbedtls_ct_condition_t y); - -/** Boolean "and" operation. - * - * Functionally equivalent to: - * - * \p x && \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x && \p y, - * otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x, - mbedtls_ct_condition_t y); - -/** Boolean "or" operation. - * - * Functionally equivalent to: - * - * \p x || \p y - * - * \param x The first value to analyze. - * \param y The second value to analyze. - * - * \return MBEDTLS_CT_TRUE if \p x || \p y, - * otherwise MBEDTLS_CT_FALSE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x, - mbedtls_ct_condition_t y); - -/** Boolean "not" operation. - * - * Functionally equivalent to: - * - * ! \p x - * - * \param x The value to invert - * - * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x); - - -/* ============================================================================ - * Data selection operations - */ - -/** Choose between two size_t values. - * - * Functionally equivalent to: - * - * condition ? if1 : if0. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. - */ -static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition, - size_t if1, - size_t if0); - -/** Choose between two unsigned values. - * - * Functionally equivalent to: - * - * condition ? if1 : if0. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. - */ -static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition, - unsigned if1, - unsigned if0); - -/** Choose between two mbedtls_ct_condition_t values. - * - * Functionally equivalent to: - * - * condition ? if1 : if0. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition, - mbedtls_ct_condition_t if1, - mbedtls_ct_condition_t if0); - -#if defined(MBEDTLS_BIGNUM_C) - -/** Choose between two mbedtls_mpi_uint values. - * - * Functionally equivalent to: - * - * condition ? if1 : if0. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. - */ -static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \ - mbedtls_mpi_uint if1, \ - mbedtls_mpi_uint if0); - -#endif - -/** Choose between an unsigned value and 0. - * - * Functionally equivalent to: - * - * condition ? if1 : 0. - * - * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but - * results in smaller code size. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. - */ -static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1); - -/** Choose between an mbedtls_ct_condition_t and 0. - * - * Functionally equivalent to: - * - * condition ? if1 : 0. - * - * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but - * results in smaller code size. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. - */ -static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition, - mbedtls_ct_condition_t if1); - -/** Choose between a size_t value and 0. - * - * Functionally equivalent to: - * - * condition ? if1 : 0. - * - * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but - * results in smaller code size. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. - */ -static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1); - -#if defined(MBEDTLS_BIGNUM_C) - -/** Choose between an mbedtls_mpi_uint value and 0. - * - * Functionally equivalent to: - * - * condition ? if1 : 0. - * - * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but - * results in smaller code size. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. - */ -static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition, - mbedtls_mpi_uint if1); - -#endif - -/** Constant-flow char selection - * - * \param low Secret. Bottom of range - * \param high Secret. Top of range - * \param c Secret. Value to compare to range - * \param t Secret. Value to return, if in range - * - * \return \p t if \p low <= \p c <= \p high, 0 otherwise. - */ -static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low, - unsigned char high, - unsigned char c, - unsigned char t); - -/** Choose between two error values. The values must be in the range [-32767..0]. - * - * Functionally equivalent to: - * - * condition ? if1 : if0. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. - */ -static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0); - -/** Choose between an error value and 0. The error value must be in the range [-32767..0]. - * - * Functionally equivalent to: - * - * condition ? if1 : 0. - * - * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but - * results in smaller code size. - * - * \param condition Condition to test. - * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. - * - * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. - */ -static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1); - -/* ============================================================================ - * Block memory operations - */ - -#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) - -/** Conditionally set a block of memory to zero. - * - * Regardless of the condition, every byte will be read once and written to - * once. - * - * \param condition Secret. Condition to test. - * \param buf Secret. Pointer to the start of the buffer. - * \param len Number of bytes to set to zero. - * - * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees - * about not being optimised away if the memory is never read again. - */ -void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len); - -/** Shift some data towards the left inside a buffer. - * - * Functionally equivalent to: - * - * memmove(start, start + offset, total - offset); - * memset(start + (total - offset), 0, offset); - * - * Timing independence comes at the expense of performance. - * - * \param start Secret. Pointer to the start of the buffer. - * \param total Total size of the buffer. - * \param offset Secret. Offset from which to copy \p total - \p offset bytes. - */ -void mbedtls_ct_memmove_left(void *start, - size_t total, - size_t offset); - -#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */ - -/** Conditional memcpy. - * - * Functionally equivalent to: - * - * if (condition) { - * memcpy(dest, src1, len); - * } else { - * if (src2 != NULL) - * memcpy(dest, src2, len); - * } - * - * It will always read len bytes from src1. - * If src2 != NULL, it will always read len bytes from src2. - * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest). - * - * \param condition The condition - * \param dest Secret. Destination pointer. - * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE). - * This may be equal to \p dest, but may not overlap in other ways. - * \param src2 Secret (contents only - may branch to determine if this parameter is NULL). - * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL. - * This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1. - * \param len Number of bytes to copy. - */ -void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, - unsigned char *dest, - const unsigned char *src1, - const unsigned char *src2, - size_t len - ); - -/** Copy data from a secret position. - * - * Functionally equivalent to: - * - * memcpy(dst, src + offset, len) - * - * This function copies \p len bytes from \p src + \p offset to - * \p dst, with a code flow and memory access pattern that does not depend on - * \p offset, but only on \p offset_min, \p offset_max and \p len. - * - * \note This function reads from \p dest, but the value that - * is read does not influence the result and this - * function's behavior is well-defined regardless of the - * contents of the buffers. This may result in false - * positives from static or dynamic analyzers, especially - * if \p dest is not initialized. - * - * \param dest Secret. The destination buffer. This must point to a writable - * buffer of at least \p len bytes. - * \param src Secret. The base of the source buffer. This must point to a - * readable buffer of at least \p offset_max + \p len - * bytes. Shouldn't overlap with \p dest - * \param offset Secret. The offset in the source buffer from which to copy. - * This must be no less than \p offset_min and no greater - * than \p offset_max. - * \param offset_min The minimal value of \p offset. - * \param offset_max The maximal value of \p offset. - * \param len The number of bytes to copy. - */ -void mbedtls_ct_memcpy_offset(unsigned char *dest, - const unsigned char *src, - size_t offset, - size_t offset_min, - size_t offset_max, - size_t len); - -/* Documented in include/mbedtls/constant_time.h. a and b are secret. - - int mbedtls_ct_memcmp(const void *a, - const void *b, - size_t n); - */ - -#if defined(MBEDTLS_NIST_KW_C) - -/** Constant-time buffer comparison without branches. - * - * Similar to mbedtls_ct_memcmp, except that the result only depends on part of - * the input data - differences in the head or tail are ignored. Functionally equivalent to: - * - * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail) - * - * Time taken depends on \p n, but not on \p skip_head or \p skip_tail . - * - * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n. - * - * \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL. - * \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL. - * \param n The number of bytes to examine (total size of the buffers). - * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer. - * These bytes will still be read. - * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer. - * These bytes will still be read. - * - * \return Zero if the contents of the two buffers are the same, otherwise non-zero. - */ -int mbedtls_ct_memcmp_partial(const void *a, - const void *b, - size_t n, - size_t skip_head, - size_t skip_tail); - -#endif - -/* Include the implementation of static inline functions above. */ -#include "constant_time_impl.h" - -#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */ diff --git a/vendor/mbedtls/library/ctr.h b/vendor/mbedtls/library/ctr.h deleted file mode 100644 index aa48fb9e7..000000000 --- a/vendor/mbedtls/library/ctr.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * \file ctr.h - * - * \brief This file contains common functionality for counter algorithms. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_CTR_H -#define MBEDTLS_CTR_H - -#include "common.h" - -/** - * \brief Increment a big-endian 16-byte value. - * This is quite performance-sensitive for AES-CTR and CTR-DRBG. - * - * \param n A 16-byte value to be incremented. - */ -static inline void mbedtls_ctr_increment_counter(uint8_t n[16]) -{ - // The 32-bit version seems to perform about the same as a 64-bit version - // on 64-bit architectures, so no need to define a 64-bit version. - for (int i = 3;; i--) { - uint32_t x = MBEDTLS_GET_UINT32_BE(n, i << 2); - x += 1; - MBEDTLS_PUT_UINT32_BE(x, n, i << 2); - if (x != 0 || i == 0) { - break; - } - } -} - -#endif /* MBEDTLS_CTR_H */ diff --git a/vendor/mbedtls/library/ctr_drbg.c b/vendor/mbedtls/library/ctr_drbg.c deleted file mode 100644 index bbbfdacf3..000000000 --- a/vendor/mbedtls/library/ctr_drbg.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The NIST SP 800-90 DRBGs are described in the following publication. - * - * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-90r.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_CTR_DRBG_C) - -#include "ctr.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -/* Using error translation functions from PSA to MbedTLS */ -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) -#include "psa_util_internal.h" -#endif - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) -static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx, - unsigned char *key, size_t key_len) -{ - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; - - psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING); - psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES); - status = psa_import_key(&key_attr, key, key_len, &psa_ctx->key_id); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_cipher_encrypt_setup(&psa_ctx->operation, psa_ctx->key_id, PSA_ALG_ECB_NO_PADDING); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - psa_reset_key_attributes(&key_attr); - return status; -} - -static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx) -{ - psa_cipher_abort(&psa_ctx->operation); - psa_destroy_key(psa_ctx->key_id); - - psa_ctx->operation = psa_cipher_operation_init(); - psa_ctx->key_id = MBEDTLS_SVC_KEY_ID_INIT; -} -#endif - -/* - * CTR_DRBG context initialization - */ -void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context)); -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT; - ctx->psa_ctx.operation = psa_cipher_operation_init(); -#else - mbedtls_aes_init(&ctx->aes_ctx); -#endif - /* Indicate that the entropy nonce length is not set explicitly. - * See mbedtls_ctr_drbg_set_nonce_len(). */ - ctx->reseed_counter = -1; - - ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; -} - -/* - * This function resets CTR_DRBG context to the state immediately - * after initial call of mbedtls_ctr_drbg_init(). - */ -void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_THREADING_C) - /* The mutex is initialized iff f_entropy is set. */ - if (ctx->f_entropy != NULL) { - mbedtls_mutex_free(&ctx->mutex); - } -#endif -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - ctr_drbg_destroy_psa_contex(&ctx->psa_ctx); -#else - mbedtls_aes_free(&ctx->aes_ctx); -#endif - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context)); - ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; - ctx->reseed_counter = -1; -} - -void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx, - int resistance) -{ - ctx->prediction_resistance = resistance; -} - -void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx, - size_t len) -{ - ctx->entropy_len = len; -} - -int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx, - size_t len) -{ - /* If mbedtls_ctr_drbg_seed() has already been called, it's - * too late. Return the error code that's closest to making sense. */ - if (ctx->f_entropy != NULL) { - return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; - } - - if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) { - return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - } - - /* This shouldn't be an issue because - * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible - * configuration, but make sure anyway. */ - if (len > INT_MAX) { - return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - } - - /* For backward compatibility with Mbed TLS <= 2.19, store the - * entropy nonce length in a field that already exists, but isn't - * used until after the initial seeding. */ - /* Due to the capping of len above, the value fits in an int. */ - ctx->reseed_counter = (int) len; - return 0; -} - -void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx, - int interval) -{ - ctx->reseed_interval = interval; -} - -static int block_cipher_df(unsigned char *output, - const unsigned char *data, size_t data_len) -{ - unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + - MBEDTLS_CTR_DRBG_BLOCKSIZE + 16]; - unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; - unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; - unsigned char *p, *iv; - int ret = 0; -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - psa_status_t status; - size_t tmp_len; - mbedtls_ctr_drbg_psa_context psa_ctx; - - psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_ctx.operation = psa_cipher_operation_init(); -#else - mbedtls_aes_context aes_ctx; -#endif - - int i, j; - size_t buf_len, use_len; - - if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) { - return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - } - - memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + - MBEDTLS_CTR_DRBG_BLOCKSIZE + 16); - - /* - * Construct IV (16 bytes) and S in buffer - * IV = Counter (in 32-bits) padded to 16 with zeroes - * S = Length input string (in 32-bits) || Length of output (in 32-bits) || - * data || 0x80 - * (Total is padded to a multiple of 16-bytes with zeroes) - */ - p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE; - MBEDTLS_PUT_UINT32_BE(data_len, p, 0); - p += 4 + 3; - *p++ = MBEDTLS_CTR_DRBG_SEEDLEN; - memcpy(p, data, data_len); - p[data_len] = 0x80; - - buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; - - for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) { - key[i] = i; - } - -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key)); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } -#else - mbedtls_aes_init(&aes_ctx); - - if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key, - MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { - goto exit; - } -#endif - - /* - * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data - */ - for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { - p = buf; - memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE); - use_len = buf_len; - - while (use_len > 0) { - mbedtls_xor(chain, chain, p, MBEDTLS_CTR_DRBG_BLOCKSIZE); - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ? - MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; - -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, - chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } -#else - if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, - chain, chain)) != 0) { - goto exit; - } -#endif - } - - memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE); - - /* - * Update IV - */ - buf[3]++; - } - - /* - * Do final encryption with reduced data - */ -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - ctr_drbg_destroy_psa_contex(&psa_ctx); - - status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } -#else - if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp, - MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { - goto exit; - } -#endif - iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; - p = output; - - for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, - iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } -#else - if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, - iv, iv)) != 0) { - goto exit; - } -#endif - memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE); - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - } -exit: -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - ctr_drbg_destroy_psa_contex(&psa_ctx); -#else - mbedtls_aes_free(&aes_ctx); -#endif - /* - * tidy up the stack - */ - mbedtls_platform_zeroize(buf, sizeof(buf)); - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - mbedtls_platform_zeroize(key, sizeof(key)); - mbedtls_platform_zeroize(chain, sizeof(chain)); - if (0 != ret) { - /* - * wipe partial seed from memory - */ - mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN); - } - - return ret; -} - -/* CTR_DRBG_Update (SP 800-90A §10.2.1.2) - * ctr_drbg_update_internal(ctx, provided_data) - * implements - * CTR_DRBG_Update(provided_data, Key, V) - * with inputs and outputs - * ctx->aes_ctx = Key - * ctx->counter = V - */ -static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, - const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN]) -{ - unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char *p = tmp; - int j; - int ret = 0; -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - psa_status_t status; - size_t tmp_len; -#endif - - memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN); - - for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { - /* - * Increase counter - */ - mbedtls_ctr_increment_counter(ctx->counter); - - /* - * Crypt counter block - */ -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter), - p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } -#else - if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, - ctx->counter, p)) != 0) { - goto exit; - } -#endif - - p += MBEDTLS_CTR_DRBG_BLOCKSIZE; - } - - mbedtls_xor(tmp, tmp, data, MBEDTLS_CTR_DRBG_SEEDLEN); - - /* - * Update key and counter - */ -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - ctr_drbg_destroy_psa_contex(&ctx->psa_ctx); - - status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } -#else - if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp, - MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { - goto exit; - } -#endif - memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, - MBEDTLS_CTR_DRBG_BLOCKSIZE); - -exit: - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - return ret; -} - -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_update(ctx, additional, add_len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * ctx->counter = all-bits-0 - * ctx->aes_ctx = context from all-bits-0 key - * additional[:add_len] = entropy_input || nonce || personalization_string - * and with outputs - * ctx = initial_working_state - */ -int mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t add_len) -{ - unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (add_len == 0) { - return 0; - } - - if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) { - goto exit; - } - if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) { - goto exit; - } - -exit: - mbedtls_platform_zeroize(add_input, sizeof(add_input)); - return ret; -} - -/* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2) - * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional_input) - * -> new_working_state - * with inputs - * ctx contains working_state - * additional[:len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * for (ctx->entropy_len + nonce_len) bytes - * and with output - * ctx contains new_working_state - */ -static int mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, - size_t len, - size_t nonce_len) -{ - unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; - size_t seedlen = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) { - return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - } - if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) { - return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - } - if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) { - return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - } - - memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT); - - /* Gather entropy_len bytes of entropy to seed state. */ - if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) { - return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; - } - seedlen += ctx->entropy_len; - - /* Gather entropy for a nonce if requested. */ - if (nonce_len != 0) { - if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) { - return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; - } - seedlen += nonce_len; - } - - /* Add additional data if provided. */ - if (additional != NULL && len != 0) { - memcpy(seed + seedlen, additional, len); - seedlen += len; - } - - /* Reduce to 384 bits. */ - if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) { - goto exit; - } - - /* Update state. */ - if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) { - goto exit; - } - ctx->reseed_counter = 0; - -exit: - mbedtls_platform_zeroize(seed, sizeof(seed)); - return ret; -} - -int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, size_t len) -{ - return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0); -} - -/* Return a "good" nonce length for CTR_DRBG. The chosen nonce length - * is sufficient to achieve the maximum security strength given the key - * size and entropy length. If there is enough entropy in the initial - * call to the entropy function to serve as both the entropy input and - * the nonce, don't make a second call to get a nonce. */ -static size_t good_nonce_len(size_t entropy_len) -{ - if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) { - return 0; - } else { - return (entropy_len + 1) / 2; - } -} - -/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2) - * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len) - * implements - * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string, - * security_strength) -> initial_working_state - * with inputs - * custom[:len] = nonce || personalization_string - * where entropy_input comes from f_entropy for ctx->entropy_len bytes - * and with outputs - * ctx = initial_working_state - */ -int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; - size_t nonce_len; - - memset(key, 0, MBEDTLS_CTR_DRBG_KEYSIZE); - - /* The mutex is initialized iff f_entropy is set. */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&ctx->mutex); -#endif - - ctx->f_entropy = f_entropy; - ctx->p_entropy = p_entropy; - - if (ctx->entropy_len == 0) { - ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN; - } - /* ctx->reseed_counter contains the desired amount of entropy to - * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()). - * If it's -1, indicating that the entropy nonce length was not set - * explicitly, use a sufficiently large nonce for security. */ - nonce_len = (ctx->reseed_counter >= 0 ? - (size_t) ctx->reseed_counter : - good_nonce_len(ctx->entropy_len)); - - /* Initialize with an empty key. */ -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - psa_status_t status; - - status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - return status; - } -#else - if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, - MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { - return ret; - } -#endif - - /* Do the initial seeding. */ - if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len, - nonce_len)) != 0) { - return ret; - } - return 0; -} - -/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2) - * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len) - * implements - * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len]) - * -> working_state_after_reseed - * if required, then - * CTR_DRBG_Generate(working_state_after_reseed, - * requested_number_of_bits, additional_input) - * -> status, returned_bits, new_working_state - * with inputs - * ctx contains working_state - * requested_number_of_bits = 8 * output_len - * additional[:add_len] = additional_input - * and entropy_input comes from calling ctx->f_entropy - * and with outputs - * status = SUCCESS (this function does the reseed internally) - * returned_bits = output[:output_len] - * ctx contains new_working_state - */ -int mbedtls_ctr_drbg_random_with_add(void *p_rng, - unsigned char *output, size_t output_len, - const unsigned char *additional, size_t add_len) -{ - int ret = 0; - mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; - unsigned char *p = output; - struct { - unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; - unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; - } locals; - size_t use_len; - - if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) { - return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG; - } - - if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) { - return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - } - - memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN); - - if (ctx->reseed_counter >= ctx->reseed_interval || - ctx->prediction_resistance) { - if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) { - return ret; - } - add_len = 0; - } - - if (add_len > 0) { - if ((ret = block_cipher_df(locals.add_input, additional, add_len)) != 0) { - goto exit; - } - if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) { - goto exit; - } - } - - while (output_len > 0) { - /* - * Increase counter (treat it as a 128-bit big-endian integer). - */ - mbedtls_ctr_increment_counter(ctx->counter); - - /* - * Crypt counter block - */ -#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - psa_status_t status; - size_t tmp_len; - - status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter), - locals.tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); - if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); - goto exit; - } -#else - if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, - ctx->counter, locals.tmp)) != 0) { - goto exit; - } -#endif - - use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE) - ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len; - /* - * Copy random block to destination - */ - memcpy(p, locals.tmp, use_len); - p += use_len; - output_len -= use_len; - } - - if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) { - goto exit; - } - - ctx->reseed_counter++; - -exit: - mbedtls_platform_zeroize(&locals, sizeof(locals)); - return ret; -} - -int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output, - size_t output_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - ret = mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, NULL, 0); - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx, - const char *path) -{ - int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - FILE *f; - unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT]; - - if ((f = fopen(path, "wb")) == NULL) { - return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - if ((ret = mbedtls_ctr_drbg_random(ctx, buf, - MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) { - goto exit; - } - - if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) != - MBEDTLS_CTR_DRBG_MAX_INPUT) { - ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - } else { - ret = 0; - } - -exit: - mbedtls_platform_zeroize(buf, sizeof(buf)); - - fclose(f); - return ret; -} - -int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx, - const char *path) -{ - int ret = 0; - FILE *f = NULL; - size_t n; - unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT]; - unsigned char c; - - if ((f = fopen(path, "rb")) == NULL) { - return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - n = fread(buf, 1, sizeof(buf), f); - if (fread(&c, 1, 1, f) != 0) { - ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; - goto exit; - } - if (n == 0 || ferror(f)) { - ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; - goto exit; - } - fclose(f); - f = NULL; - - ret = mbedtls_ctr_drbg_update(ctx, buf, n); - -exit: - mbedtls_platform_zeroize(buf, sizeof(buf)); - if (f != NULL) { - fclose(f); - } - if (ret != 0) { - return ret; - } - return mbedtls_ctr_drbg_write_seed_file(ctx, path); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) - -/* The CTR_DRBG NIST test vectors used here are available at - * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip - * - * The parameters used to derive the test data are: - * - * [AES-128 use df] - * [PredictionResistance = True/False] - * [EntropyInputLen = 128] - * [NonceLen = 64] - * [PersonalizationStringLen = 128] - * [AdditionalInputLen = 0] - * [ReturnedBitsLen = 512] - * - * [AES-256 use df] - * [PredictionResistance = True/False] - * [EntropyInputLen = 256] - * [NonceLen = 128] - * [PersonalizationStringLen = 256] - * [AdditionalInputLen = 0] - * [ReturnedBitsLen = 512] - * - */ - -#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -static const unsigned char entropy_source_pr[] = -{ 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb, - 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92, - 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8, - 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20, - 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0, - 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad, - 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 }; - -static const unsigned char entropy_source_nopr[] = -{ 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45, - 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9, - 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20, - 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f, - 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c }; - -static const unsigned char pers_pr[] = -{ 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a, - 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad }; - -static const unsigned char pers_nopr[] = -{ 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c, - 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f }; - -static const unsigned char result_pr[] = -{ 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66, - 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff, - 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10, - 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30, - 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4, - 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc, - 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06, - 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf }; - -static const unsigned char result_nopr[] = -{ 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13, - 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0, - 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf, - 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2, - 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7, - 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2, - 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02, - 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 }; -#else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ - -static const unsigned char entropy_source_pr[] = -{ 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49, - 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a, - 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85, - 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e, - 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15, - 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45, - 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8, - 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c, - 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3, - 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce, - 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e, - 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76, - 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77, - 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe }; - -static const unsigned char entropy_source_nopr[] = -{ 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d, - 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0, - 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73, - 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c, - 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2, - 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1, - 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a, - 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb, - 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a, - 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 }; - -static const unsigned char pers_pr[] = -{ 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33, - 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e, - 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0, - 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 }; - -static const unsigned char pers_nopr[] = -{ 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29, - 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf, - 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb, - 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b }; - -static const unsigned char result_pr[] = -{ 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85, - 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d, - 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62, - 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d, - 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb, - 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39, - 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40, - 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 }; - -static const unsigned char result_nopr[] = -{ 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad, - 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3, - 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b, - 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14, - 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54, - 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30, - 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a, - 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 }; -#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ - -static size_t test_offset; -static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf, - size_t len) -{ - const unsigned char *p = data; - memcpy(buf, p + test_offset, len); - test_offset += len; - return 0; -} - -#define CHK(c) if ((c) != 0) \ - { \ - if (verbose != 0) \ - mbedtls_printf("failed\n"); \ - return 1; \ - } - -#define SELF_TEST_OUTPUT_DISCARD_LENGTH 64 - -/* - * Checkup routine - */ -int mbedtls_ctr_drbg_self_test(int verbose) -{ - mbedtls_ctr_drbg_context ctx; - unsigned char buf[sizeof(result_pr)]; - - mbedtls_ctr_drbg_init(&ctx); - - /* - * Based on a NIST CTR_DRBG test vector (PR = True) - */ - if (verbose != 0) { - mbedtls_printf(" CTR_DRBG (PR = TRUE) : "); - } - - test_offset = 0; - mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE); - mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2); - CHK(mbedtls_ctr_drbg_seed(&ctx, - ctr_drbg_self_test_entropy, - (void *) entropy_source_pr, - pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE)); - mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON); - CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH)); - CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr))); - CHK(memcmp(buf, result_pr, sizeof(result_pr))); - - mbedtls_ctr_drbg_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - /* - * Based on a NIST CTR_DRBG test vector (PR = FALSE) - */ - if (verbose != 0) { - mbedtls_printf(" CTR_DRBG (PR = FALSE): "); - } - - mbedtls_ctr_drbg_init(&ctx); - - test_offset = 0; - mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE); - mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2); - CHK(mbedtls_ctr_drbg_seed(&ctx, - ctr_drbg_self_test_entropy, - (void *) entropy_source_nopr, - pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE)); - CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0)); - CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH)); - CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr))); - CHK(memcmp(buf, result_nopr, sizeof(result_nopr))); - - mbedtls_ctr_drbg_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_CTR_DRBG_C */ diff --git a/vendor/mbedtls/library/debug.c b/vendor/mbedtls/library/debug.c deleted file mode 100644 index 24c6253c4..000000000 --- a/vendor/mbedtls/library/debug.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Debugging routines - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_DEBUG_C) - -#include "mbedtls/platform.h" - -#include "debug_internal.h" -#include "mbedtls/error.h" - -#include -#include -#include - -/* DEBUG_BUF_SIZE must be at least 2 */ -#define DEBUG_BUF_SIZE 512 - -int mbedtls_debug_snprintf(char *dest, size_t maxlen, - const char *format, ...) -{ - va_list argp; - va_start(argp, format); - int ret = mbedtls_vsnprintf(dest, maxlen, format, argp); - va_end(argp); - return ret; -} - -static int debug_threshold = 0; - -void mbedtls_debug_set_threshold(int threshold) -{ - debug_threshold = threshold; -} - -/* - * All calls to f_dbg must be made via this function - */ -static inline void debug_send_line(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *str) -{ - /* - * If in a threaded environment, we need a thread identifier. - * Since there is no portable way to get one, use the address of the ssl - * context instead, as it shouldn't be shared between threads. - */ -#if defined(MBEDTLS_THREADING_C) - char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */ - mbedtls_snprintf(idstr, sizeof(idstr), "%p: %s", (void *) ssl, str); - ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, idstr); -#else - ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, str); -#endif -} - -MBEDTLS_PRINTF_ATTRIBUTE(5, 6) -void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *format, ...) -{ - va_list argp; - char str[DEBUG_BUF_SIZE]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_STATIC_ASSERT(DEBUG_BUF_SIZE >= 2, "DEBUG_BUF_SIZE too small"); - - if (NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold) { - return; - } - - va_start(argp, format); - ret = mbedtls_vsnprintf(str, DEBUG_BUF_SIZE, format, argp); - va_end(argp); - - if (ret < 0) { - ret = 0; - } else { - if (ret >= DEBUG_BUF_SIZE - 1) { - ret = DEBUG_BUF_SIZE - 2; - } - } - str[ret] = '\n'; - str[ret + 1] = '\0'; - - debug_send_line(ssl, level, file, line, str); -} - -void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, int ret) -{ - char str[DEBUG_BUF_SIZE]; - - if (NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold) { - return; - } - - /* - * With non-blocking I/O and examples that just retry immediately, - * the logs would be quickly flooded with WANT_READ, so ignore that. - * Don't ignore WANT_WRITE however, since it is usually rare. - */ - if (ret == MBEDTLS_ERR_SSL_WANT_READ) { - return; - } - - mbedtls_snprintf(str, sizeof(str), "%s() returned %d (-0x%04x)\n", - text, ret, (unsigned int) -ret); - - debug_send_line(ssl, level, file, line, str); -} - -void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text, - const unsigned char *buf, size_t len) -{ - char str[DEBUG_BUF_SIZE]; - char txt[17]; - size_t i, idx = 0; - - if (NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold) { - return; - } - - mbedtls_snprintf(str + idx, sizeof(str) - idx, "dumping '%s' (%u bytes)\n", - text, (unsigned int) len); - - debug_send_line(ssl, level, file, line, str); - - memset(txt, 0, sizeof(txt)); - for (i = 0; i < len; i++) { - if (i >= 4096) { - break; - } - - if (i % 16 == 0) { - if (i > 0) { - mbedtls_snprintf(str + idx, sizeof(str) - idx, " %s\n", txt); - debug_send_line(ssl, level, file, line, str); - - idx = 0; - memset(txt, 0, sizeof(txt)); - } - - idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, "%04x: ", - (unsigned int) i); - - } - - idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x", - (unsigned int) buf[i]); - txt[i % 16] = (buf[i] > 31 && buf[i] < 127) ? buf[i] : '.'; - } - - if (len > 0) { - for (/* i = i */; i % 16 != 0; i++) { - idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " "); - } - - mbedtls_snprintf(str + idx, sizeof(str) - idx, " %s\n", txt); - debug_send_line(ssl, level, file, line, str); - } -} - -#if defined(MBEDTLS_ECP_LIGHT) -void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_ecp_point *X) -{ - char str[DEBUG_BUF_SIZE]; - - if (NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold) { - return; - } - - mbedtls_snprintf(str, sizeof(str), "%s(X)", text); - mbedtls_debug_print_mpi(ssl, level, file, line, str, &X->X); - - mbedtls_snprintf(str, sizeof(str), "%s(Y)", text); - mbedtls_debug_print_mpi(ssl, level, file, line, str, &X->Y); -} -#endif /* MBEDTLS_ECP_LIGHT */ - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -static void mbedtls_debug_print_ec_coord(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text, - const unsigned char *buf, size_t len) -{ - char str[DEBUG_BUF_SIZE]; - size_t i, idx = 0; - - mbedtls_snprintf(str + idx, sizeof(str) - idx, "value of '%s' (%u bits) is:\n", - text, (unsigned int) len * 8); - - debug_send_line(ssl, level, file, line, str); - - for (i = 0; i < len; i++) { - if (i >= 4096) { - break; - } - - if (i % 16 == 0) { - if (i > 0) { - mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n"); - debug_send_line(ssl, level, file, line, str); - - idx = 0; - } - } - - idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x", - (unsigned int) buf[i]); - } - - if (len > 0) { - for (/* i = i */; i % 16 != 0; i++) { - idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " "); - } - - mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n"); - debug_send_line(ssl, level, file, line, str); - } -} - -void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_pk_context *pk) -{ - char str[DEBUG_BUF_SIZE]; - const uint8_t *coord_start; - size_t coord_len; - - if (NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold) { - return; - } - - /* For the description of pk->pk_raw content please refer to the description - * psa_export_public_key() function. */ - coord_len = (pk->pub_raw_len - 1)/2; - - /* X coordinate */ - coord_start = pk->pub_raw + 1; - mbedtls_snprintf(str, sizeof(str), "%s(X)", text); - mbedtls_debug_print_ec_coord(ssl, level, file, line, str, coord_start, coord_len); - - /* Y coordinate */ - coord_start = coord_start + coord_len; - mbedtls_snprintf(str, sizeof(str), "%s(Y)", text); - mbedtls_debug_print_ec_coord(ssl, level, file, line, str, coord_start, coord_len); -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - -#if defined(MBEDTLS_BIGNUM_C) -void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_mpi *X) -{ - char str[DEBUG_BUF_SIZE]; - size_t bitlen; - size_t idx = 0; - - if (NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - NULL == X || - level > debug_threshold) { - return; - } - - bitlen = mbedtls_mpi_bitlen(X); - - mbedtls_snprintf(str, sizeof(str), "value of '%s' (%u bits) is:\n", - text, (unsigned) bitlen); - debug_send_line(ssl, level, file, line, str); - - if (bitlen == 0) { - str[0] = ' '; str[1] = '0'; str[2] = '0'; - idx = 3; - } else { - int n; - for (n = (int) ((bitlen - 1) / 8); n >= 0; n--) { - size_t limb_offset = n / sizeof(mbedtls_mpi_uint); - size_t offset_in_limb = n % sizeof(mbedtls_mpi_uint); - unsigned char octet = - (X->p[limb_offset] >> (offset_in_limb * 8)) & 0xff; - mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x", octet); - idx += 3; - /* Wrap lines after 16 octets that each take 3 columns */ - if (idx >= 3 * 16) { - mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n"); - debug_send_line(ssl, level, file, line, str); - idx = 0; - } - } - } - - if (idx != 0) { - mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n"); - debug_send_line(ssl, level, file, line, str); - } -} -#endif /* MBEDTLS_BIGNUM_C */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO) -static void debug_print_pk(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_pk_context *pk) -{ - size_t i; - mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS]; - char name[16]; - - memset(items, 0, sizeof(items)); - - if (mbedtls_pk_debug(pk, items) != 0) { - debug_send_line(ssl, level, file, line, - "invalid PK context\n"); - return; - } - - for (i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++) { - if (items[i].type == MBEDTLS_PK_DEBUG_NONE) { - return; - } - - mbedtls_snprintf(name, sizeof(name), "%s%s", text, items[i].name); - name[sizeof(name) - 1] = '\0'; - -#if defined(MBEDTLS_RSA_C) - if (items[i].type == MBEDTLS_PK_DEBUG_MPI) { - mbedtls_debug_print_mpi(ssl, level, file, line, name, items[i].value); - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_LIGHT) - if (items[i].type == MBEDTLS_PK_DEBUG_ECP) { - mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value); - } else -#endif /* MBEDTLS_ECP_LIGHT */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - if (items[i].type == MBEDTLS_PK_DEBUG_PSA_EC) { - mbedtls_debug_print_psa_ec(ssl, level, file, line, name, items[i].value); - } else -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - { debug_send_line(ssl, level, file, line, - "should not happen\n"); } - } -} - -static void debug_print_line_by_line(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text) -{ - char str[DEBUG_BUF_SIZE]; - const char *start, *cur; - - start = text; - for (cur = text; *cur != '\0'; cur++) { - if (*cur == '\n') { - size_t len = (size_t) (cur - start) + 1; - if (len > DEBUG_BUF_SIZE - 1) { - len = DEBUG_BUF_SIZE - 1; - } - - memcpy(str, start, len); - str[len] = '\0'; - - debug_send_line(ssl, level, file, line, str); - - start = cur + 1; - } - } -} - -void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_x509_crt *crt) -{ - char str[DEBUG_BUF_SIZE]; - int i = 0; - - if (NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - NULL == crt || - level > debug_threshold) { - return; - } - - while (crt != NULL) { - char buf[1024]; - - mbedtls_snprintf(str, sizeof(str), "%s #%d:\n", text, ++i); - debug_send_line(ssl, level, file, line, str); - - mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt); - debug_print_line_by_line(ssl, level, file, line, buf); - - debug_print_pk(ssl, level, file, line, "crt->", &crt->pk); - - crt = crt->next; - } -} -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_X509_REMOVE_INFO */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \ - defined(MBEDTLS_ECDH_C) -static void mbedtls_debug_printf_ecdh_internal(const mbedtls_ssl_context *ssl, - int level, const char *file, - int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - const mbedtls_ecdh_context *ctx = ecdh; -#else - const mbedtls_ecdh_context_mbed *ctx = &ecdh->ctx.mbed_ecdh; -#endif - - switch (attr) { - case MBEDTLS_DEBUG_ECDH_Q: - mbedtls_debug_print_ecp(ssl, level, file, line, "ECDH: Q", - &ctx->Q); - break; - case MBEDTLS_DEBUG_ECDH_QP: - mbedtls_debug_print_ecp(ssl, level, file, line, "ECDH: Qp", - &ctx->Qp); - break; - case MBEDTLS_DEBUG_ECDH_Z: - mbedtls_debug_print_mpi(ssl, level, file, line, "ECDH: z", - &ctx->z); - break; - default: - break; - } -} - -void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_debug_printf_ecdh_internal(ssl, level, file, line, ecdh, attr); -#else - switch (ecdh->var) { - default: - mbedtls_debug_printf_ecdh_internal(ssl, level, file, line, ecdh, - attr); - } -#endif -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED && - MBEDTLS_ECDH_C */ - -#endif /* MBEDTLS_DEBUG_C */ diff --git a/vendor/mbedtls/library/debug_internal.h b/vendor/mbedtls/library/debug_internal.h deleted file mode 100644 index 2dd2599c1..000000000 --- a/vendor/mbedtls/library/debug_internal.h +++ /dev/null @@ -1,185 +0,0 @@ -/** - * \file debug_internal.h - * - * \brief Internal part of the public "debug.h". - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_DEBUG_INTERNAL_H -#define MBEDTLS_DEBUG_INTERNAL_H - -#include "mbedtls/debug.h" - -/* This should be equivalent to mbedtls_snprintf(). But it might not be due - * to platform shenanigans. For example, Mbed TLS and TF-PSA-Crypto could - * have inconsistent platform definitions. On Mingw, some code might - * be built with a different setting of __USE_MINGW_ANSI_STDIO, resulting - * in an old non-C99 printf being used somewhere. - * - * Our library assumes that mbedtls_snprintf() and other printf functions - * are consistent throughout. This function is not an official API and - * is not meant to be used inside the library. It is provided to help - * debugging printf inconsistencies issues. If you need it, good luck! - */ -int mbedtls_debug_snprintf(char *dest, size_t maxlen, - const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(3, 4); -/** - * \brief Print a message to the debug output. This function is always used - * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl - * context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the message has occurred in - * \param line line number the message has occurred at - * \param format format specifier, in printf format - * \param ... variables used by the format specifier - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6); - -/** - * \brief Print the return value of a function to the debug output. This - * function is always used through the MBEDTLS_SSL_DEBUG_RET() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text the name of the function that returned the error - * \param ret the return code value - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, int ret); - -/** - * \brief Output a buffer of size len bytes to the debug output. This function - * is always used through the MBEDTLS_SSL_DEBUG_BUF() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the buffer being dumped. Normally the - * variable or buffer name - * \param buf the buffer to be outputted - * \param len length of the buffer - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text, - const unsigned char *buf, size_t len); - -#if defined(MBEDTLS_BIGNUM_C) -/** - * \brief Print a MPI variable to the debug output. This function is always - * used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the - * ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the MPI being output. Normally the - * variable name - * \param X the MPI variable - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_mpi *X); -#endif - -#if defined(MBEDTLS_ECP_LIGHT) -/** - * \brief Print an ECP point to the debug output. This function is always - * used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the - * ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the ECP point being output. Normally the - * variable name - * \param X the ECP point - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_ecp_point *X); -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO) -/** - * \brief Print a X.509 certificate structure to the debug output. This - * function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the certificate being output - * \param crt X.509 certificate structure - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_x509_crt *crt); -#endif - -/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function - only works for the built-in implementation. */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \ - defined(MBEDTLS_ECDH_C) -typedef enum { - MBEDTLS_DEBUG_ECDH_Q, - MBEDTLS_DEBUG_ECDH_QP, - MBEDTLS_DEBUG_ECDH_Z, -} mbedtls_debug_ecdh_attr; - -/** - * \brief Print a field of the ECDH structure in the SSL context to the debug - * output. This function is always used through the - * MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file - * and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param ecdh the ECDH context - * \param attr the identifier of the attribute being output - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr); -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED && - MBEDTLS_ECDH_C */ - -#endif /* MBEDTLS_DEBUG_INTERNAL_H */ diff --git a/vendor/mbedtls/library/des.c b/vendor/mbedtls/library/des.c deleted file mode 100644 index f0032b3b5..000000000 --- a/vendor/mbedtls/library/des.c +++ /dev/null @@ -1,1042 +0,0 @@ -/* - * FIPS-46-3 compliant Triple-DES implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * DES, on which TDES is based, was originally designed by Horst Feistel - * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). - * - * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_DES_C) - -#include "mbedtls/des.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_DES_ALT) - -/* - * Expanded DES S-boxes - */ -static const uint32_t SB1[64] = -{ - 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 -}; - -static const uint32_t SB2[64] = -{ - 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 -}; - -static const uint32_t SB3[64] = -{ - 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 -}; - -static const uint32_t SB4[64] = -{ - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 -}; - -static const uint32_t SB5[64] = -{ - 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 -}; - -static const uint32_t SB6[64] = -{ - 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 -}; - -static const uint32_t SB7[64] = -{ - 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 -}; - -static const uint32_t SB8[64] = -{ - 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 -}; - -/* - * PC1: left and right halves bit-swap - */ -static const uint32_t LHs[16] = -{ - 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00010000, 0x00010001, 0x00010100, 0x00010101, - 0x01000000, 0x01000001, 0x01000100, 0x01000101, - 0x01010000, 0x01010001, 0x01010100, 0x01010101 -}; - -static const uint32_t RHs[16] = -{ - 0x00000000, 0x01000000, 0x00010000, 0x01010000, - 0x00000100, 0x01000100, 0x00010100, 0x01010100, - 0x00000001, 0x01000001, 0x00010001, 0x01010001, - 0x00000101, 0x01000101, 0x00010101, 0x01010101, -}; - -/* - * Initial Permutation macro - */ -#define DES_IP(X, Y) \ - do \ - { \ - T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ - T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ - T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ - T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ - (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \ - T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \ - (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \ - } while (0) - -/* - * Final Permutation macro - */ -#define DES_FP(X, Y) \ - do \ - { \ - (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \ - T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \ - (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \ - T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ - T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ - T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ - T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ - } while (0) - -/* - * DES round macro - */ -#define DES_ROUND(X, Y) \ - do \ - { \ - T = *SK++ ^ (X); \ - (Y) ^= SB8[(T) & 0x3F] ^ \ - SB6[(T >> 8) & 0x3F] ^ \ - SB4[(T >> 16) & 0x3F] ^ \ - SB2[(T >> 24) & 0x3F]; \ - \ - T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \ - (Y) ^= SB7[(T) & 0x3F] ^ \ - SB5[(T >> 8) & 0x3F] ^ \ - SB3[(T >> 16) & 0x3F] ^ \ - SB1[(T >> 24) & 0x3F]; \ - } while (0) - -#define SWAP(a, b) \ - do \ - { \ - uint32_t t = (a); (a) = (b); (b) = t; t = 0; \ - } while (0) - -void mbedtls_des_init(mbedtls_des_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_des_context)); -} - -void mbedtls_des_free(mbedtls_des_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context)); -} - -void mbedtls_des3_init(mbedtls_des3_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_des3_context)); -} - -void mbedtls_des3_free(mbedtls_des3_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des3_context)); -} - -static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, - 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, - 35, 37, 38, 41, 42, 44, - 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, - 70, 73, 74, 76, 79, 81, - 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, - 104, 107, 109, 110, 112, - 115, 117, 118, 121, 122, 124, 127, 128, 131, - 133, 134, 137, 138, 140, - 143, 145, 146, 148, 151, 152, 155, 157, 158, - 161, 162, 164, 167, 168, - 171, 173, 174, 176, 179, 181, 182, 185, 186, - 188, 191, 193, 194, 196, - 199, 200, 203, 205, 206, 208, 211, 213, 214, - 217, 218, 220, 223, 224, - 227, 229, 230, 233, 234, 236, 239, 241, 242, - 244, 247, 248, 251, 253, - 254 }; - -void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]) -{ - int i; - - for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) { - key[i] = odd_parity_table[key[i] / 2]; - } -} - -/* - * Check the given key's parity, returns 1 on failure, 0 on SUCCESS - */ -int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE]) -{ - int i; - - for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) { - if (key[i] != odd_parity_table[key[i] / 2]) { - return 1; - } - } - - return 0; -} - -/* - * Table of weak and semi-weak keys - * - * Source: http://en.wikipedia.org/wiki/Weak_key - * - * Weak: - * Alternating ones + zeros (0x0101010101010101) - * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) - * '0xE0E0E0E0F1F1F1F1' - * '0x1F1F1F1F0E0E0E0E' - * - * Semi-weak: - * 0x011F011F010E010E and 0x1F011F010E010E01 - * 0x01E001E001F101F1 and 0xE001E001F101F101 - * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 - * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E - * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E - * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 - * - */ - -#define WEAK_KEY_COUNT 16 - -static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = -{ - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, - { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, - { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, - { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, - - { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, - { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, - { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, - { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, - { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, - { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, - { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, - { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, - { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, - { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, - { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, - { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } -}; - -int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]) -{ - int i; - - for (i = 0; i < WEAK_KEY_COUNT; i++) { - if (memcmp(weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0) { - return 1; - } - } - - return 0; -} - -#if !defined(MBEDTLS_DES_SETKEY_ALT) -void mbedtls_des_setkey(uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE]) -{ - int i; - uint32_t X, Y, T; - - X = MBEDTLS_GET_UINT32_BE(key, 0); - Y = MBEDTLS_GET_UINT32_BE(key, 4); - - /* - * Permuted Choice 1 - */ - T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); - T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T); - - X = (LHs[(X) & 0xF] << 3) | (LHs[(X >> 8) & 0xF] << 2) - | (LHs[(X >> 16) & 0xF] << 1) | (LHs[(X >> 24) & 0xF]) - | (LHs[(X >> 5) & 0xF] << 7) | (LHs[(X >> 13) & 0xF] << 6) - | (LHs[(X >> 21) & 0xF] << 5) | (LHs[(X >> 29) & 0xF] << 4); - - Y = (RHs[(Y >> 1) & 0xF] << 3) | (RHs[(Y >> 9) & 0xF] << 2) - | (RHs[(Y >> 17) & 0xF] << 1) | (RHs[(Y >> 25) & 0xF]) - | (RHs[(Y >> 4) & 0xF] << 7) | (RHs[(Y >> 12) & 0xF] << 6) - | (RHs[(Y >> 20) & 0xF] << 5) | (RHs[(Y >> 28) & 0xF] << 4); - - X &= 0x0FFFFFFF; - Y &= 0x0FFFFFFF; - - /* - * calculate subkeys - */ - for (i = 0; i < 16; i++) { - if (i < 2 || i == 8 || i == 15) { - X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; - Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; - } else { - X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; - Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; - } - - *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) - | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) - | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) - | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) - | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) - | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) - | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) - | ((Y >> 14) & 0x00000200) | ((Y) & 0x00000100) - | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) - | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) - | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); - - *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) - | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) - | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) - | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) - | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) - | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) - | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) - | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) - | ((Y) & 0x00000200) | ((Y << 7) & 0x00000100) - | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) - | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); - } -} -#endif /* !MBEDTLS_DES_SETKEY_ALT */ - -/* - * DES key schedule (56-bit, encryption) - */ -int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]) -{ - mbedtls_des_setkey(ctx->sk, key); - - return 0; -} - -/* - * DES key schedule (56-bit, decryption) - */ -int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]) -{ - int i; - - mbedtls_des_setkey(ctx->sk, key); - - for (i = 0; i < 16; i += 2) { - SWAP(ctx->sk[i], ctx->sk[30 - i]); - SWAP(ctx->sk[i + 1], ctx->sk[31 - i]); - } - - return 0; -} - -static void des3_set2key(uint32_t esk[96], - uint32_t dsk[96], - const unsigned char key[MBEDTLS_DES_KEY_SIZE*2]) -{ - int i; - - mbedtls_des_setkey(esk, key); - mbedtls_des_setkey(dsk + 32, key + 8); - - for (i = 0; i < 32; i += 2) { - dsk[i] = esk[30 - i]; - dsk[i + 1] = esk[31 - i]; - - esk[i + 32] = dsk[62 - i]; - esk[i + 33] = dsk[63 - i]; - - esk[i + 64] = esk[i]; - esk[i + 65] = esk[i + 1]; - - dsk[i + 64] = dsk[i]; - dsk[i + 65] = dsk[i + 1]; - } -} - -/* - * Triple-DES key schedule (112-bit, encryption) - */ -int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]) -{ - uint32_t sk[96]; - - des3_set2key(ctx->sk, sk, key); - mbedtls_platform_zeroize(sk, sizeof(sk)); - - return 0; -} - -/* - * Triple-DES key schedule (112-bit, decryption) - */ -int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]) -{ - uint32_t sk[96]; - - des3_set2key(sk, ctx->sk, key); - mbedtls_platform_zeroize(sk, sizeof(sk)); - - return 0; -} - -static void des3_set3key(uint32_t esk[96], - uint32_t dsk[96], - const unsigned char key[24]) -{ - int i; - - mbedtls_des_setkey(esk, key); - mbedtls_des_setkey(dsk + 32, key + 8); - mbedtls_des_setkey(esk + 64, key + 16); - - for (i = 0; i < 32; i += 2) { - dsk[i] = esk[94 - i]; - dsk[i + 1] = esk[95 - i]; - - esk[i + 32] = dsk[62 - i]; - esk[i + 33] = dsk[63 - i]; - - dsk[i + 64] = esk[30 - i]; - dsk[i + 65] = esk[31 - i]; - } -} - -/* - * Triple-DES key schedule (168-bit, encryption) - */ -int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]) -{ - uint32_t sk[96]; - - des3_set3key(ctx->sk, sk, key); - mbedtls_platform_zeroize(sk, sizeof(sk)); - - return 0; -} - -/* - * Triple-DES key schedule (168-bit, decryption) - */ -int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx, - const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]) -{ - uint32_t sk[96]; - - des3_set3key(sk, ctx->sk, key); - mbedtls_platform_zeroize(sk, sizeof(sk)); - - return 0; -} - -/* - * DES-ECB block encryption/decryption - */ -#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT) -int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, - const unsigned char input[8], - unsigned char output[8]) -{ - int i; - uint32_t X, Y, T, *SK; - - SK = ctx->sk; - - X = MBEDTLS_GET_UINT32_BE(input, 0); - Y = MBEDTLS_GET_UINT32_BE(input, 4); - - DES_IP(X, Y); - - for (i = 0; i < 8; i++) { - DES_ROUND(Y, X); - DES_ROUND(X, Y); - } - - DES_FP(Y, X); - - MBEDTLS_PUT_UINT32_BE(Y, output, 0); - MBEDTLS_PUT_UINT32_BE(X, output, 4); - - return 0; -} -#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * DES-CBC buffer encryption/decryption - */ -int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char temp[8]; - - if (length % 8) { - return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH; - } - - if (mode == MBEDTLS_DES_ENCRYPT) { - while (length > 0) { - mbedtls_xor(output, input, iv, 8); - - ret = mbedtls_des_crypt_ecb(ctx, output, output); - if (ret != 0) { - goto exit; - } - memcpy(iv, output, 8); - - input += 8; - output += 8; - length -= 8; - } - } else { /* MBEDTLS_DES_DECRYPT */ - while (length > 0) { - memcpy(temp, input, 8); - ret = mbedtls_des_crypt_ecb(ctx, input, output); - if (ret != 0) { - goto exit; - } - - mbedtls_xor(output, output, iv, 8); - - memcpy(iv, temp, 8); - - input += 8; - output += 8; - length -= 8; - } - } - ret = 0; - -exit: - return ret; -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/* - * 3DES-ECB block encryption/decryption - */ -#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT) -int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, - const unsigned char input[8], - unsigned char output[8]) -{ - int i; - uint32_t X, Y, T, *SK; - - SK = ctx->sk; - - X = MBEDTLS_GET_UINT32_BE(input, 0); - Y = MBEDTLS_GET_UINT32_BE(input, 4); - - DES_IP(X, Y); - - for (i = 0; i < 8; i++) { - DES_ROUND(Y, X); - DES_ROUND(X, Y); - } - - for (i = 0; i < 8; i++) { - DES_ROUND(X, Y); - DES_ROUND(Y, X); - } - - for (i = 0; i < 8; i++) { - DES_ROUND(Y, X); - DES_ROUND(X, Y); - } - - DES_FP(Y, X); - - MBEDTLS_PUT_UINT32_BE(Y, output, 0); - MBEDTLS_PUT_UINT32_BE(X, output, 4); - - return 0; -} -#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * 3DES-CBC buffer encryption/decryption - */ -int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx, - int mode, - size_t length, - unsigned char iv[8], - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char temp[8]; - - if (length % 8) { - return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH; - } - - if (mode == MBEDTLS_DES_ENCRYPT) { - while (length > 0) { - mbedtls_xor(output, input, iv, 8); - - ret = mbedtls_des3_crypt_ecb(ctx, output, output); - if (ret != 0) { - goto exit; - } - memcpy(iv, output, 8); - - input += 8; - output += 8; - length -= 8; - } - } else { /* MBEDTLS_DES_DECRYPT */ - while (length > 0) { - memcpy(temp, input, 8); - ret = mbedtls_des3_crypt_ecb(ctx, input, output); - if (ret != 0) { - goto exit; - } - - mbedtls_xor(output, output, iv, 8); - - memcpy(iv, temp, 8); - - input += 8; - output += 8; - length -= 8; - } - } - ret = 0; - -exit: - return ret; -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#endif /* !MBEDTLS_DES_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * DES and 3DES test vectors from: - * - * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip - */ -static const unsigned char des3_test_keys[24] = -{ - 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, - 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, - 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 -}; - -static const unsigned char des3_test_buf[8] = -{ - 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 -}; - -static const unsigned char des3_test_ecb_dec[3][8] = -{ - { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 }, - { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 }, - { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D } -}; - -static const unsigned char des3_test_ecb_enc[3][8] = -{ - { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB }, - { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 }, - { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const unsigned char des3_test_iv[8] = -{ - 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, -}; - -static const unsigned char des3_test_cbc_dec[3][8] = -{ - { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A }, - { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 }, - { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF } -}; - -static const unsigned char des3_test_cbc_enc[3][8] = -{ - { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D }, - { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 }, - { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -/* - * Checkup routine - */ -int mbedtls_des_self_test(int verbose) -{ - int i, j, u, v, ret = 0; - mbedtls_des_context ctx; - mbedtls_des3_context ctx3; - unsigned char buf[8]; -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[8]; - unsigned char iv[8]; -#endif - - mbedtls_des_init(&ctx); - mbedtls_des3_init(&ctx3); - /* - * ECB mode - */ - for (i = 0; i < 6; i++) { - u = i >> 1; - v = i & 1; - - if (verbose != 0) { - mbedtls_printf(" DES%c-ECB-%3d (%s): ", - (u == 0) ? ' ' : '3', 56 + u * 56, - (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc"); - } - - memcpy(buf, des3_test_buf, 8); - - switch (i) { - case 0: - ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys); - break; - - case 1: - ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys); - break; - - case 2: - ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys); - break; - - case 3: - ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys); - break; - - case 4: - ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys); - break; - - case 5: - ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys); - break; - - default: - return 1; - } - if (ret != 0) { - goto exit; - } - - for (j = 0; j < 100; j++) { - if (u == 0) { - ret = mbedtls_des_crypt_ecb(&ctx, buf, buf); - } else { - ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf); - } - if (ret != 0) { - goto exit; - } - } - - if ((v == MBEDTLS_DES_DECRYPT && - memcmp(buf, des3_test_ecb_dec[u], 8) != 0) || - (v != MBEDTLS_DES_DECRYPT && - memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for (i = 0; i < 6; i++) { - u = i >> 1; - v = i & 1; - - if (verbose != 0) { - mbedtls_printf(" DES%c-CBC-%3d (%s): ", - (u == 0) ? ' ' : '3', 56 + u * 56, - (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc"); - } - - memcpy(iv, des3_test_iv, 8); - memcpy(prv, des3_test_iv, 8); - memcpy(buf, des3_test_buf, 8); - - switch (i) { - case 0: - ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys); - break; - - case 1: - ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys); - break; - - case 2: - ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys); - break; - - case 3: - ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys); - break; - - case 4: - ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys); - break; - - case 5: - ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys); - break; - - default: - return 1; - } - if (ret != 0) { - goto exit; - } - - if (v == MBEDTLS_DES_DECRYPT) { - for (j = 0; j < 100; j++) { - if (u == 0) { - ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf); - } else { - ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf); - } - if (ret != 0) { - goto exit; - } - } - } else { - for (j = 0; j < 100; j++) { - unsigned char tmp[8]; - - if (u == 0) { - ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf); - } else { - ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf); - } - if (ret != 0) { - goto exit; - } - - memcpy(tmp, prv, 8); - memcpy(prv, buf, 8); - memcpy(buf, tmp, 8); - } - - memcpy(buf, prv, 8); - } - - if ((v == MBEDTLS_DES_DECRYPT && - memcmp(buf, des3_test_cbc_dec[u], 8) != 0) || - (v != MBEDTLS_DES_DECRYPT && - memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - if (verbose != 0) { - mbedtls_printf("\n"); - } - -exit: - mbedtls_des_free(&ctx); - mbedtls_des3_free(&ctx3); - - if (ret != 0) { - ret = 1; - } - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_DES_C */ diff --git a/vendor/mbedtls/library/dhm.c b/vendor/mbedtls/library/dhm.c deleted file mode 100644 index 941a89da8..000000000 --- a/vendor/mbedtls/library/dhm.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * Diffie-Hellman-Merkle key exchange - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The following sources were referenced in the design of this implementation - * of the Diffie-Hellman-Merkle algorithm: - * - * [1] Handbook of Applied Cryptography - 1997, Chapter 12 - * Menezes, van Oorschot and Vanstone - * - */ - -#include "common.h" - -#if defined(MBEDTLS_DHM_C) - -#include "mbedtls/dhm.h" -#include "bignum_internal.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#endif - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_DHM_ALT) - -/* - * helper to validate the mbedtls_mpi size and import it - */ -static int dhm_read_bignum(mbedtls_mpi *X, - unsigned char **p, - const unsigned char *end) -{ - int ret, n; - - if (end - *p < 2) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - - n = MBEDTLS_GET_UINT16_BE(*p, 0); - (*p) += 2; - - if ((size_t) (end - *p) < (size_t) n) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret); - } - - (*p) += n; - - return 0; -} - -/* - * Verify sanity of parameter with regards to P - * - * Parameter should be: 2 <= public_param <= P - 2 - * - * This means that we need to return an error if - * public_param < 2 or public_param > P-2 - * - * For more information on the attack, see: - * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf - * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 - */ -static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P) -{ - mbedtls_mpi U; - int ret = 0; - - mbedtls_mpi_init(&U); - - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2)); - - if (mbedtls_mpi_cmp_int(param, 2) < 0 || - mbedtls_mpi_cmp_mpi(param, &U) > 0) { - ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - -cleanup: - mbedtls_mpi_free(&U); - return ret; -} - -void mbedtls_dhm_init(mbedtls_dhm_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_dhm_context)); -} - -size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx) -{ - return mbedtls_mpi_bitlen(&ctx->P); -} - -size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx) -{ - return mbedtls_mpi_size(&ctx->P); -} - -int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx, - mbedtls_dhm_parameter param, - mbedtls_mpi *dest) -{ - const mbedtls_mpi *src = NULL; - switch (param) { - case MBEDTLS_DHM_PARAM_P: - src = &ctx->P; - break; - case MBEDTLS_DHM_PARAM_G: - src = &ctx->G; - break; - case MBEDTLS_DHM_PARAM_X: - src = &ctx->X; - break; - case MBEDTLS_DHM_PARAM_GX: - src = &ctx->GX; - break; - case MBEDTLS_DHM_PARAM_GY: - src = &ctx->GY; - break; - case MBEDTLS_DHM_PARAM_K: - src = &ctx->K; - break; - default: - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - return mbedtls_mpi_copy(dest, src); -} - -/* - * Parse the ServerKeyExchange parameters - */ -int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx, - unsigned char **p, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 || - (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 || - (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) { - return ret; - } - - if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) { - return ret; - } - - return 0; -} - -/* - * Pick a random R in the range [2, M-2] for blinding or key generation. - */ -static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret; - - MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1)); - -cleanup: - return ret; -} - -static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = 0; - - if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - if (x_size < 0) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - - if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) { - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng)); - } else { - /* Generate X as large as possible ( <= P - 2 ) */ - ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng); - if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { - return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED; - } - if (ret != 0) { - return ret; - } - } - - /* - * Calculate GX = G^X mod P - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X, - &ctx->P, &ctx->RP)); - - if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) { - return ret; - } - -cleanup: - return ret; -} - -/* - * Setup and write the ServerKeyExchange parameters - */ -int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret; - size_t n1, n2, n3; - unsigned char *p; - - ret = dhm_make_common(ctx, x_size, f_rng, p_rng); - if (ret != 0) { - goto cleanup; - } - - /* - * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are - * not required". We omit leading zeros for compactness. - */ -#define DHM_MPI_EXPORT(X, n) \ - do { \ - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \ - p + 2, \ - (n))); \ - *p++ = MBEDTLS_BYTE_1(n); \ - *p++ = MBEDTLS_BYTE_0(n); \ - p += (n); \ - } while (0) - - n1 = mbedtls_mpi_size(&ctx->P); - n2 = mbedtls_mpi_size(&ctx->G); - n3 = mbedtls_mpi_size(&ctx->GX); - - p = output; - DHM_MPI_EXPORT(&ctx->P, n1); - DHM_MPI_EXPORT(&ctx->G, n2); - DHM_MPI_EXPORT(&ctx->GX, n3); - - *olen = (size_t) (p - output); - -cleanup: - if (ret != 0 && ret > -128) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret); - } - return ret; -} - -/* - * Set prime modulus and generator - */ -int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx, - const mbedtls_mpi *P, - const mbedtls_mpi *G) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 || - (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret); - } - - return 0; -} - -/* - * Import the peer's public value G^Y - */ -int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx, - const unsigned char *input, size_t ilen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ilen < 1 || ilen > mbedtls_dhm_get_len(ctx)) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret); - } - - return 0; -} - -/* - * Create own private value X and export G^X - */ -int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size, - unsigned char *output, size_t olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret; - - if (olen < 1 || olen > mbedtls_dhm_get_len(ctx)) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - - ret = dhm_make_common(ctx, x_size, f_rng, p_rng); - if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) { - return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED; - } - if (ret != 0) { - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen)); - -cleanup: - if (ret != 0 && ret > -128) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret); - } - return ret; -} - - -/* - * Use the blinding method and optimisation suggested in section 10 of: - * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, - * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer - * Berlin Heidelberg, 1996. p. 104-113. - */ -static int dhm_update_blinding(mbedtls_dhm_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret; - - /* - * Don't use any blinding the first time a particular X is used, - * but remember it to use blinding next time. - */ - if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1)); - - return 0; - } - - /* - * Ok, we need blinding. Can we re-use existing values? - * If yes, just update them by squaring them. - */ - if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P)); - - return 0; - } - - /* - * We need to generate blinding values from scratch - */ - - /* Vi = random( 2, P-2 ) */ - MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng)); - - /* Vf = Vi^-X = (Vi^-1)^X mod P */ - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &ctx->Vf, &ctx->Vi, &ctx->P)); - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP)); - -cleanup: - return ret; -} - -/* - * Derive and export the shared secret (G^Y)^X mod P - */ -int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx, - unsigned char *output, size_t output_size, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi GYb; - - if (f_rng == NULL) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - - if (output_size < mbedtls_dhm_get_len(ctx)) { - return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; - } - - if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) { - return ret; - } - - mbedtls_mpi_init(&GYb); - - /* Blind peer's value */ - MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P)); - - /* Do modular exponentiation */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X, - &ctx->P, &ctx->RP)); - - /* Unblind secret value */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P)); - - /* Output the secret without any leading zero byte. This is mandatory - * for TLS per RFC 5246 §8.1.2. */ - *olen = mbedtls_mpi_size(&ctx->K); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen)); - -cleanup: - mbedtls_mpi_free(&GYb); - - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret); - } - - return 0; -} - -/* - * Free the components of a DHM key - */ -void mbedtls_dhm_free(mbedtls_dhm_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_mpi_free(&ctx->pX); - mbedtls_mpi_free(&ctx->Vf); - mbedtls_mpi_free(&ctx->Vi); - mbedtls_mpi_free(&ctx->RP); - mbedtls_mpi_free(&ctx->K); - mbedtls_mpi_free(&ctx->GY); - mbedtls_mpi_free(&ctx->GX); - mbedtls_mpi_free(&ctx->X); - mbedtls_mpi_free(&ctx->G); - mbedtls_mpi_free(&ctx->P); - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context)); -} - -#if defined(MBEDTLS_ASN1_PARSE_C) -/* - * Parse DHM parameters - */ -int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin, - size_t dhminlen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - unsigned char *p, *end; -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_context pem; -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init(&pem); - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN DH PARAMETERS-----", - "-----END DH PARAMETERS-----", - dhmin, NULL, 0, &dhminlen); - } - - if (ret == 0) { - /* - * Was PEM encoded - */ - dhminlen = pem.buflen; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - goto exit; - } - - p = (ret == 0) ? pem.buf : (unsigned char *) dhmin; -#else - p = (unsigned char *) dhmin; -#endif /* MBEDTLS_PEM_PARSE_C */ - end = p + dhminlen; - - /* - * DHParams ::= SEQUENCE { - * prime INTEGER, -- P - * generator INTEGER, -- g - * privateValueLength INTEGER OPTIONAL - * } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret); - goto exit; - } - - end = p + len; - - if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 || - (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret); - goto exit; - } - - if (p != end) { - /* This might be the optional privateValueLength. - * If so, we can cleanly discard it */ - mbedtls_mpi rec; - mbedtls_mpi_init(&rec); - ret = mbedtls_asn1_get_mpi(&p, end, &rec); - mbedtls_mpi_free(&rec); - if (ret != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret); - goto exit; - } - if (p != end) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - goto exit; - } - } - - ret = 0; - -exit: -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_free(&pem); -#endif - if (ret != 0) { - mbedtls_dhm_free(dhm); - } - - return ret; -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load all data from a file into a given buffer. - * - * The file is expected to contain either PEM or DER encoded data. - * A terminating null byte is always appended. It is included in the announced - * length only if the data looks like it is PEM encoded. - */ -static int load_file(const char *path, unsigned char **buf, size_t *n) -{ - FILE *f; - long size; - - if ((f = fopen(path, "rb")) == NULL) { - return MBEDTLS_ERR_DHM_FILE_IO_ERROR; - } - /* The data loaded here is public, so don't bother disabling buffering. */ - - fseek(f, 0, SEEK_END); - if ((size = ftell(f)) == -1) { - fclose(f); - return MBEDTLS_ERR_DHM_FILE_IO_ERROR; - } - fseek(f, 0, SEEK_SET); - - *n = (size_t) size; - - if (*n + 1 == 0 || - (*buf = mbedtls_calloc(1, *n + 1)) == NULL) { - fclose(f); - return MBEDTLS_ERR_DHM_ALLOC_FAILED; - } - - if (fread(*buf, 1, *n, f) != *n) { - fclose(f); - - mbedtls_zeroize_and_free(*buf, *n + 1); - - return MBEDTLS_ERR_DHM_FILE_IO_ERROR; - } - - fclose(f); - - (*buf)[*n] = '\0'; - - if (strstr((const char *) *buf, "-----BEGIN ") != NULL) { - ++*n; - } - - return 0; -} - -/* - * Load and parse DHM parameters - */ -int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - unsigned char *buf; - - if ((ret = load_file(path, &buf, &n)) != 0) { - return ret; - } - - ret = mbedtls_dhm_parse_dhm(dhm, buf, n); - - mbedtls_zeroize_and_free(buf, n); - - return ret; -} -#endif /* MBEDTLS_FS_IO */ -#endif /* MBEDTLS_ASN1_PARSE_C */ -#endif /* MBEDTLS_DHM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_PEM_PARSE_C) -static const char mbedtls_test_dhm_params[] = - "-----BEGIN DH PARAMETERS-----\r\n" - "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" - "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" - "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" - "-----END DH PARAMETERS-----\r\n"; -#else /* MBEDTLS_PEM_PARSE_C */ -static const char mbedtls_test_dhm_params[] = { - 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, - 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, - 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, - 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, - 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, - 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, - 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, - 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, - 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, - 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, - 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, - 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 -}; -#endif /* MBEDTLS_PEM_PARSE_C */ - -static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params); - -/* - * Checkup routine - */ -int mbedtls_dhm_self_test(int verbose) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_dhm_context dhm; - - mbedtls_dhm_init(&dhm); - - if (verbose != 0) { - mbedtls_printf(" DHM parameter load: "); - } - - if ((ret = mbedtls_dhm_parse_dhm(&dhm, - (const unsigned char *) mbedtls_test_dhm_params, - mbedtls_test_dhm_params_len)) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n\n"); - } - -exit: - mbedtls_dhm_free(&dhm); - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_DHM_C */ diff --git a/vendor/mbedtls/library/ecdh.c b/vendor/mbedtls/library/ecdh.c deleted file mode 100644 index b276c6ada..000000000 --- a/vendor/mbedtls/library/ecdh.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Elliptic curve Diffie-Hellman - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * References: - * - * SEC1 https://www.secg.org/sec1-v2.pdf - * RFC 4492 - */ - -#include "common.h" - -#if defined(MBEDTLS_ECDH_C) - -#include "mbedtls/ecdh.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) -typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; -#endif - -static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( - const mbedtls_ecdh_context *ctx) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ctx->grp.id; -#else - return ctx->grp_id; -#endif -} - -int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid) -{ - /* At this time, all groups support ECDH. */ - (void) gid; - return 1; -} - -#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) -/* - * Generate public key (restartable version) - * - * Note: this internal function relies on its caller preserving the value of - * the output parameter 'd' across continuation calls. This would not be - * acceptable for a public function but is OK here as we control call sites. - */ -static int ecdh_gen_public_restartable(mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - int restarting = 0; -#if defined(MBEDTLS_ECP_RESTARTABLE) - restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL); -#endif - /* If multiplication is in progress, we already generated a privkey */ - if (!restarting) { - MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng)); - } - - MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, Q, d, &grp->G, - f_rng, p_rng, rs_ctx)); - -cleanup: - return ret; -} - -/* - * Generate public key - */ -int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - return ecdh_gen_public_restartable(grp, d, Q, f_rng, p_rng, NULL); -} -#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */ - -#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) -/* - * Compute shared secret (SEC1 3.3.1) - */ -static int ecdh_compute_shared_restartable(mbedtls_ecp_group *grp, - mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point P; - - mbedtls_ecp_point_init(&P); - - MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &P, d, Q, - f_rng, p_rng, rs_ctx)); - - if (mbedtls_ecp_is_zero(&P)) { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(z, &P.X)); - -cleanup: - mbedtls_ecp_point_free(&P); - - return ret; -} - -/* - * Compute shared secret (SEC1 3.3.1) - */ -int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, - const mbedtls_ecp_point *Q, const mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - return ecdh_compute_shared_restartable(grp, z, Q, d, - f_rng, p_rng, NULL); -} -#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ - -static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx) -{ - mbedtls_ecp_group_init(&ctx->grp); - mbedtls_mpi_init(&ctx->d); - mbedtls_ecp_point_init(&ctx->Q); - mbedtls_ecp_point_init(&ctx->Qp); - mbedtls_mpi_init(&ctx->z); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_init(&ctx->rs); -#endif -} - -mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ctx->MBEDTLS_PRIVATE(grp).id; -#else - return ctx->MBEDTLS_PRIVATE(grp_id); -#endif -} - -/* - * Initialize context - */ -void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - ecdh_init_internal(ctx); - mbedtls_ecp_point_init(&ctx->Vi); - mbedtls_ecp_point_init(&ctx->Vf); - mbedtls_mpi_init(&ctx->_d); -#else - memset(ctx, 0, sizeof(mbedtls_ecdh_context)); - - ctx->var = MBEDTLS_ECDH_VARIANT_NONE; -#endif - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; -#if defined(MBEDTLS_ECP_RESTARTABLE) - ctx->restart_enabled = 0; -#endif -} - -static int ecdh_setup_internal(mbedtls_ecdh_context_mbed *ctx, - mbedtls_ecp_group_id grp_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_ecp_group_load(&ctx->grp, grp_id); - if (ret != 0) { - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } - - return 0; -} - -/* - * Setup context - */ -int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ecdh_setup_internal(ctx, grp_id); -#else - switch (grp_id) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED; - ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST; - ctx->grp_id = grp_id; - return mbedtls_everest_setup(&ctx->ctx.everest_ecdh, grp_id); -#endif - default: - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; - ctx->grp_id = grp_id; - ecdh_init_internal(&ctx->ctx.mbed_ecdh); - return ecdh_setup_internal(&ctx->ctx.mbed_ecdh, grp_id); - } -#endif -} - -static void ecdh_free_internal(mbedtls_ecdh_context_mbed *ctx) -{ - mbedtls_ecp_group_free(&ctx->grp); - mbedtls_mpi_free(&ctx->d); - mbedtls_ecp_point_free(&ctx->Q); - mbedtls_ecp_point_free(&ctx->Qp); - mbedtls_mpi_free(&ctx->z); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_free(&ctx->rs); -#endif -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Enable restartable operations for context - */ -void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx) -{ - ctx->restart_enabled = 1; -} -#endif - -/* - * Free context - */ -void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_ecp_point_free(&ctx->Vi); - mbedtls_ecp_point_free(&ctx->Vf); - mbedtls_mpi_free(&ctx->_d); - ecdh_free_internal(ctx); -#else - switch (ctx->var) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECDH_VARIANT_EVEREST: - mbedtls_everest_free(&ctx->ctx.everest_ecdh); - break; -#endif - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - ecdh_free_internal(&ctx->ctx.mbed_ecdh); - break; - default: - break; - } - - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - ctx->var = MBEDTLS_ECDH_VARIANT_NONE; - ctx->grp_id = MBEDTLS_ECP_DP_NONE; -#endif -} - -static int ecdh_make_params_internal(mbedtls_ecdh_context_mbed *ctx, - size_t *olen, int point_format, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t grp_len, pt_len; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if (ctx->grp.pbits == 0) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (restart_enabled) { - rs_ctx = &ctx->rs; - } -#else - (void) restart_enabled; -#endif - - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng, rs_ctx)) != 0) { - return ret; - } -#else - if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng)) != 0) { - return ret; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - if ((ret = mbedtls_ecp_tls_write_group(&ctx->grp, &grp_len, buf, - blen)) != 0) { - return ret; - } - - buf += grp_len; - blen -= grp_len; - - if ((ret = mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, - &pt_len, buf, blen)) != 0) { - return ret; - } - - *olen = grp_len + pt_len; - return 0; -} - -/* - * Setup and write the ServerKeyExchange parameters (RFC 4492) - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ -int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int restart_enabled = 0; -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ecdh_make_params_internal(ctx, olen, ctx->point_format, buf, blen, - f_rng, p_rng, restart_enabled); -#else - switch (ctx->var) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECDH_VARIANT_EVEREST: - return mbedtls_everest_make_params(&ctx->ctx.everest_ecdh, olen, - buf, blen, f_rng, p_rng); -#endif - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return ecdh_make_params_internal(&ctx->ctx.mbed_ecdh, olen, - ctx->point_format, buf, blen, - f_rng, p_rng, - restart_enabled); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_read_params_internal(mbedtls_ecdh_context_mbed *ctx, - const unsigned char **buf, - const unsigned char *end) -{ - return mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, buf, - (size_t) (end - *buf)); -} - -/* - * Read the ServerKeyExchange parameters (RFC 4492) - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ -int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx, - const unsigned char **buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_group_id grp_id; - if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, (size_t) (end - *buf))) - != 0) { - return ret; - } - - if ((ret = mbedtls_ecdh_setup(ctx, grp_id)) != 0) { - return ret; - } - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ecdh_read_params_internal(ctx, buf, end); -#else - switch (ctx->var) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECDH_VARIANT_EVEREST: - return mbedtls_everest_read_params(&ctx->ctx.everest_ecdh, - buf, end); -#endif - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return ecdh_read_params_internal(&ctx->ctx.mbed_ecdh, - buf, end); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* If it's not our key, just import the public part as Qp */ - if (side == MBEDTLS_ECDH_THEIRS) { - return mbedtls_ecp_copy(&ctx->Qp, &key->Q); - } - - /* Our key: import public (as Q) and private parts */ - if (side != MBEDTLS_ECDH_OURS) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0 || - (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0) { - return ret; - } - - return 0; -} - -/* - * Get parameters from a keypair - */ -int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, - const mbedtls_ecp_keypair *key, - mbedtls_ecdh_side side) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if (side != MBEDTLS_ECDH_OURS && side != MBEDTLS_ECDH_THEIRS) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - if (mbedtls_ecdh_grp_id(ctx) == MBEDTLS_ECP_DP_NONE) { - /* This is the first call to get_params(). Set up the context - * for use with the group. */ - if ((ret = mbedtls_ecdh_setup(ctx, key->grp.id)) != 0) { - return ret; - } - } else { - /* This is not the first call to get_params(). Check that the - * current key's group is the same as the context's, which was set - * from the first key's group. */ - if (mbedtls_ecdh_grp_id(ctx) != key->grp.id) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - } - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ecdh_get_params_internal(ctx, key, side); -#else - switch (ctx->var) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECDH_VARIANT_EVEREST: - { - mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ? - MBEDTLS_EVEREST_ECDH_OURS : - MBEDTLS_EVEREST_ECDH_THEIRS; - return mbedtls_everest_get_params(&ctx->ctx.everest_ecdh, - key, s); - } -#endif - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return ecdh_get_params_internal(&ctx->ctx.mbed_ecdh, - key, side); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_make_public_internal(mbedtls_ecdh_context_mbed *ctx, - size_t *olen, int point_format, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if (ctx->grp.pbits == 0) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (restart_enabled) { - rs_ctx = &ctx->rs; - } -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng, rs_ctx)) != 0) { - return ret; - } -#else - if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, - f_rng, p_rng)) != 0) { - return ret; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - return mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, olen, - buf, blen); -} - -/* - * Setup and export the client public value - */ -int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int restart_enabled = 0; -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ecdh_make_public_internal(ctx, olen, ctx->point_format, buf, blen, - f_rng, p_rng, restart_enabled); -#else - switch (ctx->var) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECDH_VARIANT_EVEREST: - return mbedtls_everest_make_public(&ctx->ctx.everest_ecdh, olen, - buf, blen, f_rng, p_rng); -#endif - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return ecdh_make_public_internal(&ctx->ctx.mbed_ecdh, olen, - ctx->point_format, buf, blen, - f_rng, p_rng, - restart_enabled); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_read_public_internal(mbedtls_ecdh_context_mbed *ctx, - const unsigned char *buf, size_t blen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - - if ((ret = mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, &p, - blen)) != 0) { - return ret; - } - - if ((size_t) (p - buf) != blen) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return 0; -} - -/* - * Parse and import the client's public value - */ -int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx, - const unsigned char *buf, size_t blen) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ecdh_read_public_internal(ctx, buf, blen); -#else - switch (ctx->var) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECDH_VARIANT_EVEREST: - return mbedtls_everest_read_public(&ctx->ctx.everest_ecdh, - buf, blen); -#endif - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return ecdh_read_public_internal(&ctx->ctx.mbed_ecdh, - buf, blen); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} - -static int ecdh_calc_secret_internal(mbedtls_ecdh_context_mbed *ctx, - size_t *olen, unsigned char *buf, - size_t blen, - int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng, - int restart_enabled) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_ECP_RESTARTABLE) - mbedtls_ecp_restart_ctx *rs_ctx = NULL; -#endif - - if (ctx == NULL || ctx->grp.pbits == 0) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (restart_enabled) { - rs_ctx = &ctx->rs; - } -#else - (void) restart_enabled; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if ((ret = ecdh_compute_shared_restartable(&ctx->grp, &ctx->z, &ctx->Qp, - &ctx->d, f_rng, p_rng, - rs_ctx)) != 0) { - return ret; - } -#else - if ((ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp, - &ctx->d, f_rng, p_rng)) != 0) { - return ret; - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - if (mbedtls_mpi_size(&ctx->z) > blen) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - *olen = ctx->grp.pbits / 8 + ((ctx->grp.pbits % 8) != 0); - - if (mbedtls_ecp_get_type(&ctx->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - return mbedtls_mpi_write_binary_le(&ctx->z, buf, *olen); - } - - return mbedtls_mpi_write_binary(&ctx->z, buf, *olen); -} - -/* - * Derive and export the shared secret - */ -int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen, - unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int restart_enabled = 0; -#if defined(MBEDTLS_ECP_RESTARTABLE) - restart_enabled = ctx->restart_enabled; -#endif - -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - return ecdh_calc_secret_internal(ctx, olen, buf, blen, f_rng, p_rng, - restart_enabled); -#else - switch (ctx->var) { -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - case MBEDTLS_ECDH_VARIANT_EVEREST: - return mbedtls_everest_calc_secret(&ctx->ctx.everest_ecdh, olen, - buf, blen, f_rng, p_rng); -#endif - case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: - return ecdh_calc_secret_internal(&ctx->ctx.mbed_ecdh, olen, buf, - blen, f_rng, p_rng, - restart_enabled); - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -#endif -} -#endif /* MBEDTLS_ECDH_C */ diff --git a/vendor/mbedtls/library/ecdsa.c b/vendor/mbedtls/library/ecdsa.c deleted file mode 100644 index a2d1eea6d..000000000 --- a/vendor/mbedtls/library/ecdsa.c +++ /dev/null @@ -1,858 +0,0 @@ -/* - * Elliptic curve DSA - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * References: - * - * SEC1 https://www.secg.org/sec1-v2.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_ECDSA_C) - -#include "mbedtls/ecdsa.h" -#include "mbedtls/asn1write.h" -#include "bignum_internal.h" - -#include - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -#include "mbedtls/hmac_drbg.h" -#endif - -#include "mbedtls/platform.h" - -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_ECP_RESTARTABLE) - -/* - * Sub-context for ecdsa_verify() - */ -struct mbedtls_ecdsa_restart_ver { - mbedtls_mpi u1, u2; /* intermediate values */ - enum { /* what to do next? */ - ecdsa_ver_init = 0, /* getting started */ - ecdsa_ver_muladd, /* muladd step */ - } state; -}; - -/* - * Init verify restart sub-context - */ -static void ecdsa_restart_ver_init(mbedtls_ecdsa_restart_ver_ctx *ctx) -{ - mbedtls_mpi_init(&ctx->u1); - mbedtls_mpi_init(&ctx->u2); - ctx->state = ecdsa_ver_init; -} - -/* - * Free the components of a verify restart sub-context - */ -static void ecdsa_restart_ver_free(mbedtls_ecdsa_restart_ver_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_mpi_free(&ctx->u1); - mbedtls_mpi_free(&ctx->u2); - - ecdsa_restart_ver_init(ctx); -} - -/* - * Sub-context for ecdsa_sign() - */ -struct mbedtls_ecdsa_restart_sig { - int sign_tries; - int key_tries; - mbedtls_mpi k; /* per-signature random */ - mbedtls_mpi r; /* r value */ - enum { /* what to do next? */ - ecdsa_sig_init = 0, /* getting started */ - ecdsa_sig_mul, /* doing ecp_mul() */ - ecdsa_sig_modn, /* mod N computations */ - } state; -}; - -/* - * Init verify sign sub-context - */ -static void ecdsa_restart_sig_init(mbedtls_ecdsa_restart_sig_ctx *ctx) -{ - ctx->sign_tries = 0; - ctx->key_tries = 0; - mbedtls_mpi_init(&ctx->k); - mbedtls_mpi_init(&ctx->r); - ctx->state = ecdsa_sig_init; -} - -/* - * Free the components of a sign restart sub-context - */ -static void ecdsa_restart_sig_free(mbedtls_ecdsa_restart_sig_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_mpi_free(&ctx->k); - mbedtls_mpi_free(&ctx->r); -} - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/* - * Sub-context for ecdsa_sign_det() - */ -struct mbedtls_ecdsa_restart_det { - mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */ - enum { /* what to do next? */ - ecdsa_det_init = 0, /* getting started */ - ecdsa_det_sign, /* make signature */ - } state; -}; - -/* - * Init verify sign_det sub-context - */ -static void ecdsa_restart_det_init(mbedtls_ecdsa_restart_det_ctx *ctx) -{ - mbedtls_hmac_drbg_init(&ctx->rng_ctx); - ctx->state = ecdsa_det_init; -} - -/* - * Free the components of a sign_det restart sub-context - */ -static void ecdsa_restart_det_free(mbedtls_ecdsa_restart_det_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_hmac_drbg_free(&ctx->rng_ctx); - - ecdsa_restart_det_init(ctx); -} -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#define ECDSA_RS_ECP (rs_ctx == NULL ? NULL : &rs_ctx->ecp) - -/* Utility macro for checking and updating ops budget */ -#define ECDSA_BUDGET(ops) \ - MBEDTLS_MPI_CHK(mbedtls_ecp_check_budget(grp, ECDSA_RS_ECP, ops)); - -/* Call this when entering a function that needs its own sub-context */ -#define ECDSA_RS_ENTER(SUB) do { \ - /* reset ops count for this call if top-level */ \ - if (rs_ctx != NULL && rs_ctx->ecp.depth++ == 0) \ - rs_ctx->ecp.ops_done = 0; \ - \ - /* set up our own sub-context if needed */ \ - if (mbedtls_ecp_restart_is_enabled() && \ - rs_ctx != NULL && rs_ctx->SUB == NULL) \ - { \ - rs_ctx->SUB = mbedtls_calloc(1, sizeof(*rs_ctx->SUB)); \ - if (rs_ctx->SUB == NULL) \ - return MBEDTLS_ERR_ECP_ALLOC_FAILED; \ - \ - ecdsa_restart_## SUB ##_init(rs_ctx->SUB); \ - } \ -} while (0) - -/* Call this when leaving a function that needs its own sub-context */ -#define ECDSA_RS_LEAVE(SUB) do { \ - /* clear our sub-context when not in progress (done or error) */ \ - if (rs_ctx != NULL && rs_ctx->SUB != NULL && \ - ret != MBEDTLS_ERR_ECP_IN_PROGRESS) \ - { \ - ecdsa_restart_## SUB ##_free(rs_ctx->SUB); \ - mbedtls_free(rs_ctx->SUB); \ - rs_ctx->SUB = NULL; \ - } \ - \ - if (rs_ctx != NULL) \ - rs_ctx->ecp.depth--; \ -} while (0) - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define ECDSA_RS_ECP NULL - -#define ECDSA_BUDGET(ops) /* no-op; for compatibility */ - -#define ECDSA_RS_ENTER(SUB) (void) rs_ctx -#define ECDSA_RS_LEAVE(SUB) (void) rs_ctx - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \ - !defined(MBEDTLS_ECDSA_SIGN_ALT) || \ - !defined(MBEDTLS_ECDSA_VERIFY_ALT) -/* - * Derive a suitable integer for group grp from a buffer of length len - * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 - */ -static int derive_mpi(const mbedtls_ecp_group *grp, mbedtls_mpi *x, - const unsigned char *buf, size_t blen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n_size = (grp->nbits + 7) / 8; - size_t use_size = blen > n_size ? n_size : blen; - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(x, buf, use_size)); - if (use_size * 8 > grp->nbits) { - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(x, use_size * 8 - grp->nbits)); - } - - /* While at it, reduce modulo N */ - if (mbedtls_mpi_cmp_mpi(x, &grp->N) >= 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(x, x, &grp->N)); - } - -cleanup: - return ret; -} -#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */ - -int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid) -{ - switch (gid) { -#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED - case MBEDTLS_ECP_DP_CURVE25519: return 0; -#endif -#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED - case MBEDTLS_ECP_DP_CURVE448: return 0; -#endif - default: return 1; - } -} - -#if !defined(MBEDTLS_ECDSA_SIGN_ALT) -/* - * Compute ECDSA signature of a hashed message (SEC1 4.1.3) - * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) - */ -int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int (*f_rng_blind)(void *, unsigned char *, size_t), - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx) -{ - int ret, key_tries, sign_tries; - int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries; - mbedtls_ecp_point R; - mbedtls_mpi k, e; - mbedtls_mpi *pk = &k, *pr = r; - - /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ - if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* Make sure d is in range 1..n-1 */ - if (mbedtls_mpi_cmp_int(d, 1) < 0 || mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - mbedtls_ecp_point_init(&R); - mbedtls_mpi_init(&k); mbedtls_mpi_init(&e); - - ECDSA_RS_ENTER(sig); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->sig != NULL) { - /* redirect to our context */ - p_sign_tries = &rs_ctx->sig->sign_tries; - p_key_tries = &rs_ctx->sig->key_tries; - pk = &rs_ctx->sig->k; - pr = &rs_ctx->sig->r; - - /* jump to current step */ - if (rs_ctx->sig->state == ecdsa_sig_mul) { - goto mul; - } - if (rs_ctx->sig->state == ecdsa_sig_modn) { - goto modn; - } - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - *p_sign_tries = 0; - do { - if ((*p_sign_tries)++ > 10) { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - /* - * Steps 1-3: generate a suitable ephemeral keypair - * and set r = xR mod n - */ - *p_key_tries = 0; - do { - if ((*p_key_tries)++ > 10) { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, pk, f_rng, p_rng)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->sig != NULL) { - rs_ctx->sig->state = ecdsa_sig_mul; - } - -mul: -#endif - MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &R, pk, &grp->G, - f_rng_blind, - p_rng_blind, - ECDSA_RS_ECP)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pr, &R.X, &grp->N)); - } while (mbedtls_mpi_cmp_int(pr, 0) == 0); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->sig != NULL) { - rs_ctx->sig->state = ecdsa_sig_modn; - } - -modn: -#endif - /* - * Accounting for everything up to the end of the loop - * (step 6, but checking now avoids saving e and t) - */ - ECDSA_BUDGET(MBEDTLS_ECP_OPS_INV + 4); - - /* - * Step 5: derive MPI from hashed message - */ - MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen)); - - /* - * Step 6: compute s = (e + r * d) / k - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, pr, d)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&e, &e, s)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, s, pk, &grp->N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, s, &e)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(s, s, &grp->N)); - } while (mbedtls_mpi_cmp_int(s, 0) == 0); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->sig != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(r, pr)); - } -#endif - -cleanup: - mbedtls_ecp_point_free(&R); - mbedtls_mpi_free(&k); mbedtls_mpi_free(&e); - - ECDSA_RS_LEAVE(sig); - - return ret; -} - -/* - * Compute ECDSA signature of a hashed message - */ -int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - /* Use the same RNG for both blinding and ephemeral key generation */ - return mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, - f_rng, p_rng, f_rng, p_rng, NULL); -} -#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -/* - * Deterministic signature wrapper - * - * note: The f_rng_blind parameter must not be NULL. - * - */ -int mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - int (*f_rng_blind)(void *, unsigned char *, size_t), - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_hmac_drbg_context rng_ctx; - mbedtls_hmac_drbg_context *p_rng = &rng_ctx; - unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; - size_t grp_len = (grp->nbits + 7) / 8; - const mbedtls_md_info_t *md_info; - mbedtls_mpi h; - - if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - mbedtls_mpi_init(&h); - mbedtls_hmac_drbg_init(&rng_ctx); - - ECDSA_RS_ENTER(det); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->det != NULL) { - /* redirect to our context */ - p_rng = &rs_ctx->det->rng_ctx; - - /* jump to current step */ - if (rs_ctx->det->state == ecdsa_det_sign) { - goto sign; - } - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(d, data, grp_len)); - MBEDTLS_MPI_CHK(derive_mpi(grp, &h, buf, blen)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, data + grp_len, grp_len)); - MBEDTLS_MPI_CHK(mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->det != NULL) { - rs_ctx->det->state = ecdsa_det_sign; - } - -sign: -#endif -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - (void) f_rng_blind; - (void) p_rng_blind; - ret = mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng); -#else - ret = mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng, - f_rng_blind, p_rng_blind, rs_ctx); -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ - -cleanup: - mbedtls_hmac_drbg_free(&rng_ctx); - mbedtls_mpi_free(&h); - - ECDSA_RS_LEAVE(det); - - return ret; -} - -/* - * Deterministic signature wrapper - */ -int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, - mbedtls_mpi *s, const mbedtls_mpi *d, - const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - int (*f_rng_blind)(void *, unsigned char *, - size_t), - void *p_rng_blind) -{ - return mbedtls_ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg, - f_rng_blind, p_rng_blind, NULL); -} -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - -#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) -/* - * Verify ECDSA signature of hashed message (SEC1 4.1.4) - * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) - */ -int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, - const mbedtls_mpi *s, - mbedtls_ecdsa_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi e, s_inv, u1, u2; - mbedtls_ecp_point R; - mbedtls_mpi *pu1 = &u1, *pu2 = &u2; - - mbedtls_ecp_point_init(&R); - mbedtls_mpi_init(&e); mbedtls_mpi_init(&s_inv); - mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2); - - /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ - if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - ECDSA_RS_ENTER(ver); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->ver != NULL) { - /* redirect to our context */ - pu1 = &rs_ctx->ver->u1; - pu2 = &rs_ctx->ver->u2; - - /* jump to current step */ - if (rs_ctx->ver->state == ecdsa_ver_muladd) { - goto muladd; - } - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - /* - * Step 1: make sure r and s are in range 1..n-1 - */ - if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 || - mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0) { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - - /* - * Step 3: derive MPI from hashed message - */ - MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen)); - - /* - * Step 4: u1 = e / s mod n, u2 = r / s mod n - */ - ECDSA_BUDGET(MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2); - - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &s_inv, s, &grp->N)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu1, &e, &s_inv)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu1, pu1, &grp->N)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu2, r, &s_inv)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu2, pu2, &grp->N)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->ver != NULL) { - rs_ctx->ver->state = ecdsa_ver_muladd; - } - -muladd: -#endif - /* - * Step 5: R = u1 G + u2 Q - */ - MBEDTLS_MPI_CHK(mbedtls_ecp_muladd_restartable(grp, - &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP)); - - if (mbedtls_ecp_is_zero(&R)) { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - - /* - * Step 6: convert xR to an integer (no-op) - * Step 7: reduce xR mod n (gives v) - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&R.X, &R.X, &grp->N)); - - /* - * Step 8: check if v (that is, R.X) is equal to r - */ - if (mbedtls_mpi_cmp_mpi(&R.X, r) != 0) { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free(&R); - mbedtls_mpi_free(&e); mbedtls_mpi_free(&s_inv); - mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2); - - ECDSA_RS_LEAVE(ver); - - return ret; -} - -/* - * Verify ECDSA signature of hashed message - */ -int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, - const mbedtls_mpi *s) -{ - return mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL); -} -#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ - -/* - * Convert a signature (given by context) to ASN.1 - */ -static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, - unsigned char *sig, size_t sig_size, - size_t *slen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 }; - unsigned char *p = buf + sizeof(buf); - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - if (len > sig_size) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - memcpy(sig, p, len); - *slen = len; - - return 0; -} - -/* - * Compute and write signature - */ -int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t sig_size, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecdsa_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi r, s; - if (f_rng == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d, - hash, hlen, md_alg, f_rng, - p_rng, rs_ctx)); -#else - (void) md_alg; - -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - (void) rs_ctx; - - MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ctx->grp, &r, &s, &ctx->d, - hash, hlen, f_rng, p_rng)); -#else - /* Use the same RNG for both blinding and ephemeral key generation */ - MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d, - hash, hlen, f_rng, p_rng, f_rng, - p_rng, rs_ctx)); -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ - - MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen)); - -cleanup: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - - return ret; -} - -/* - * Compute and write signature - */ -int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hlen, - unsigned char *sig, size_t sig_size, size_t *slen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - return mbedtls_ecdsa_write_signature_restartable( - ctx, md_alg, hash, hlen, sig, sig_size, slen, - f_rng, p_rng, NULL); -} - -/* - * Read and check signature - */ -int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen) -{ - return mbedtls_ecdsa_read_signature_restartable( - ctx, hash, hlen, sig, slen, NULL); -} - -/* - * Restartable read and check signature - */ -int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, - const unsigned char *hash, size_t hlen, - const unsigned char *sig, size_t slen, - mbedtls_ecdsa_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = (unsigned char *) sig; - const unsigned char *end = sig + slen; - size_t len; - mbedtls_mpi r, s; - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - if (p + len != end) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - goto cleanup; - } - - if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 || - (ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) { - ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } -#if defined(MBEDTLS_ECDSA_VERIFY_ALT) - (void) rs_ctx; - - if ((ret = mbedtls_ecdsa_verify(&ctx->grp, hash, hlen, - &ctx->Q, &r, &s)) != 0) { - goto cleanup; - } -#else - if ((ret = mbedtls_ecdsa_verify_restartable(&ctx->grp, hash, hlen, - &ctx->Q, &r, &s, rs_ctx)) != 0) { - goto cleanup; - } -#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ - - /* At this point we know that the buffer starts with a valid signature. - * Return 0 if the buffer just contains the signature, and a specific - * error code if the valid signature is followed by more data. */ - if (p != end) { - ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; - } - -cleanup: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - - return ret; -} - -#if !defined(MBEDTLS_ECDSA_GENKEY_ALT) -/* - * Generate key pair - */ -int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = 0; - ret = mbedtls_ecp_group_load(&ctx->grp, gid); - if (ret != 0) { - return ret; - } - - return mbedtls_ecp_gen_keypair(&ctx->grp, &ctx->d, - &ctx->Q, f_rng, p_rng); -} -#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */ - -/* - * Set context from an mbedtls_ecp_keypair - */ -int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if ((ret = mbedtls_ecp_group_copy(&ctx->grp, &key->grp)) != 0 || - (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0 || - (ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0) { - mbedtls_ecdsa_free(ctx); - } - - return ret; -} - -/* - * Initialize context - */ -void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx) -{ - mbedtls_ecp_keypair_init(ctx); -} - -/* - * Free context - */ -void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_ecp_keypair_free(ctx); -} - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx) -{ - mbedtls_ecp_restart_init(&ctx->ecp); - - ctx->ver = NULL; - ctx->sig = NULL; -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - ctx->det = NULL; -#endif -} - -/* - * Free the components of a restart context - */ -void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_ecp_restart_free(&ctx->ecp); - - ecdsa_restart_ver_free(ctx->ver); - mbedtls_free(ctx->ver); - ctx->ver = NULL; - - ecdsa_restart_sig_free(ctx->sig); - mbedtls_free(ctx->sig); - ctx->sig = NULL; - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - ecdsa_restart_det_free(ctx->det); - mbedtls_free(ctx->det); - ctx->det = NULL; -#endif -} -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#endif /* MBEDTLS_ECDSA_C */ diff --git a/vendor/mbedtls/library/ecjpake.c b/vendor/mbedtls/library/ecjpake.c deleted file mode 100644 index cdf5d7ea4..000000000 --- a/vendor/mbedtls/library/ecjpake.c +++ /dev/null @@ -1,1216 +0,0 @@ -/* - * Elliptic curve J-PAKE - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * References in the code are to the Thread v1.0 Specification, - * available to members of the Thread Group http://threadgroup.org/ - */ - -#include "common.h" - -#if defined(MBEDTLS_ECJPAKE_C) - -#include "mbedtls/ecjpake.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if !defined(MBEDTLS_ECJPAKE_ALT) - -/* - * Convert a mbedtls_ecjpake_role to identifier string - */ -static const char * const ecjpake_id[] = { - "client", - "server" -}; - -#define ID_MINE (ecjpake_id[ctx->role]) -#define ID_PEER (ecjpake_id[1 - ctx->role]) - -/** - * Helper to Compute a hash from md_type - */ -static int mbedtls_ecjpake_compute_hash(mbedtls_md_type_t md_type, - const unsigned char *input, size_t ilen, - unsigned char *output) -{ - return mbedtls_md(mbedtls_md_info_from_type(md_type), - input, ilen, output); -} - -/* - * Initialize context - */ -void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx) -{ - ctx->md_type = MBEDTLS_MD_NONE; - mbedtls_ecp_group_init(&ctx->grp); - ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; - - mbedtls_ecp_point_init(&ctx->Xm1); - mbedtls_ecp_point_init(&ctx->Xm2); - mbedtls_ecp_point_init(&ctx->Xp1); - mbedtls_ecp_point_init(&ctx->Xp2); - mbedtls_ecp_point_init(&ctx->Xp); - - mbedtls_mpi_init(&ctx->xm1); - mbedtls_mpi_init(&ctx->xm2); - mbedtls_mpi_init(&ctx->s); -} - -/* - * Free context - */ -void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx) -{ - if (ctx == NULL) { - return; - } - - ctx->md_type = MBEDTLS_MD_NONE; - mbedtls_ecp_group_free(&ctx->grp); - - mbedtls_ecp_point_free(&ctx->Xm1); - mbedtls_ecp_point_free(&ctx->Xm2); - mbedtls_ecp_point_free(&ctx->Xp1); - mbedtls_ecp_point_free(&ctx->Xp2); - mbedtls_ecp_point_free(&ctx->Xp); - - mbedtls_mpi_free(&ctx->xm1); - mbedtls_mpi_free(&ctx->xm2); - mbedtls_mpi_free(&ctx->s); -} - -/* - * Setup context - */ -int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx, - mbedtls_ecjpake_role role, - mbedtls_md_type_t hash, - mbedtls_ecp_group_id curve, - const unsigned char *secret, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (role != MBEDTLS_ECJPAKE_CLIENT && role != MBEDTLS_ECJPAKE_SERVER) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - ctx->role = role; - - if ((mbedtls_md_info_from_type(hash)) == NULL) { - return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; - } - - ctx->md_type = hash; - - MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ctx->grp, curve)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->s, secret, len)); - -cleanup: - if (ret != 0) { - mbedtls_ecjpake_free(ctx); - } - - return ret; -} - -int mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx, - int point_format) -{ - switch (point_format) { - case MBEDTLS_ECP_PF_UNCOMPRESSED: - case MBEDTLS_ECP_PF_COMPRESSED: - ctx->point_format = point_format; - return 0; - default: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } -} - -/* - * Check if context is ready for use - */ -int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx) -{ - if (ctx->md_type == MBEDTLS_MD_NONE || - ctx->grp.id == MBEDTLS_ECP_DP_NONE || - ctx->s.p == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return 0; -} - -/* - * Write a point plus its length to a buffer - */ -static int ecjpake_write_len_point(unsigned char **p, - const unsigned char *end, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *P) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - /* Need at least 4 for length plus 1 for point */ - if (end < *p || end - *p < 5) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - ret = mbedtls_ecp_point_write_binary(grp, P, pf, - &len, *p + 4, (size_t) (end - (*p + 4))); - if (ret != 0) { - return ret; - } - - MBEDTLS_PUT_UINT32_BE(len, *p, 0); - - *p += 4 + len; - - return 0; -} - -/* - * Size of the temporary buffer for ecjpake_hash: - * 3 EC points plus their length, plus ID and its length (4 + 6 bytes) - */ -#define ECJPAKE_HASH_BUF_LEN (3 * (4 + MBEDTLS_ECP_MAX_PT_LEN) + 4 + 6) - -/* - * Compute hash for ZKP (7.4.2.2.2.1) - */ -static int ecjpake_hash(const mbedtls_md_type_t md_type, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_ecp_point *V, - const mbedtls_ecp_point *X, - const char *id, - mbedtls_mpi *h) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char buf[ECJPAKE_HASH_BUF_LEN]; - unsigned char *p = buf; - const unsigned char *end = buf + sizeof(buf); - const size_t id_len = strlen(id); - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - - /* Write things to temporary buffer */ - MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, G)); - MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, V)); - MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, X)); - - if (end - p < 4) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - MBEDTLS_PUT_UINT32_BE(id_len, p, 0); - p += 4; - - if (end < p || (size_t) (end - p) < id_len) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - memcpy(p, id, id_len); - p += id_len; - - /* Compute hash */ - MBEDTLS_MPI_CHK(mbedtls_ecjpake_compute_hash(md_type, - buf, (size_t) (p - buf), hash)); - - /* Turn it into an integer mod n */ - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(h, hash, - mbedtls_md_get_size_from_type(md_type))); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(h, h, &grp->N)); - -cleanup: - return ret; -} - -/* - * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) - */ -static int ecjpake_zkp_read(const mbedtls_md_type_t md_type, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_ecp_point *X, - const char *id, - const unsigned char **p, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point V, VV; - mbedtls_mpi r, h; - size_t r_len; - - mbedtls_ecp_point_init(&V); - mbedtls_ecp_point_init(&VV); - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&h); - - /* - * struct { - * ECPoint V; - * opaque r<1..2^8-1>; - * } ECSchnorrZKP; - */ - if (end < *p) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, &V, p, (size_t) (end - *p))); - - if (end < *p || (size_t) (end - *p) < 1) { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - r_len = *(*p)++; - - if (end < *p || (size_t) (end - *p) < r_len || r_len == 0) { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&r, *p, r_len)); - *p += r_len; - - /* - * Verification - */ - MBEDTLS_MPI_CHK(ecjpake_hash(md_type, grp, pf, G, &V, X, id, &h)); - MBEDTLS_MPI_CHK(mbedtls_ecp_muladd((mbedtls_ecp_group *) grp, - &VV, &h, X, &r, G)); - - if (mbedtls_ecp_point_cmp(&VV, &V) != 0) { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free(&V); - mbedtls_ecp_point_free(&VV); - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&h); - - return ret; -} - -/* - * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) - */ -static int ecjpake_zkp_write(const mbedtls_md_type_t md_type, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - const mbedtls_mpi *x, - const mbedtls_ecp_point *X, - const char *id, - unsigned char **p, - const unsigned char *end, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point V; - mbedtls_mpi v; - mbedtls_mpi h; /* later recycled to hold r */ - size_t len; - - if (end < *p) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - mbedtls_ecp_point_init(&V); - mbedtls_mpi_init(&v); - mbedtls_mpi_init(&h); - - /* Compute signature */ - MBEDTLS_MPI_CHK(mbedtls_ecp_gen_keypair_base((mbedtls_ecp_group *) grp, - G, &v, &V, f_rng, p_rng)); - MBEDTLS_MPI_CHK(ecjpake_hash(md_type, grp, pf, G, &V, X, id, &h)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&h, &h, x)); /* x*h */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&h, &v, &h)); /* v - x*h */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&h, &h, &grp->N)); /* r */ - - /* Write it out */ - MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(grp, &V, - pf, &len, *p, (size_t) (end - *p))); - *p += len; - - len = mbedtls_mpi_size(&h); /* actually r */ - if (end < *p || (size_t) (end - *p) < 1 + len || len > 255) { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - - *(*p)++ = MBEDTLS_BYTE_0(len); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, *p, len)); /* r */ - *p += len; - -cleanup: - mbedtls_ecp_point_free(&V); - mbedtls_mpi_free(&v); - mbedtls_mpi_free(&h); - - return ret; -} - -/* - * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof - * Output: verified public key X - */ -static int ecjpake_kkp_read(const mbedtls_md_type_t md_type, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_ecp_point *X, - const char *id, - const unsigned char **p, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (end < *p) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* - * struct { - * ECPoint X; - * ECSchnorrZKP zkp; - * } ECJPAKEKeyKP; - */ - MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, X, p, (size_t) (end - *p))); - if (mbedtls_ecp_is_zero(X)) { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - - MBEDTLS_MPI_CHK(ecjpake_zkp_read(md_type, grp, pf, G, X, id, p, end)); - -cleanup: - return ret; -} - -/* - * Generate an ECJPAKEKeyKP - * Output: the serialized structure, plus private/public key pair - */ -static int ecjpake_kkp_write(const mbedtls_md_type_t md_type, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_mpi *x, - mbedtls_ecp_point *X, - const char *id, - unsigned char **p, - const unsigned char *end, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if (end < *p) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - /* Generate key (7.4.2.3.1) and write it out */ - MBEDTLS_MPI_CHK(mbedtls_ecp_gen_keypair_base((mbedtls_ecp_group *) grp, G, x, X, - f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(grp, X, - pf, &len, *p, (size_t) (end - *p))); - *p += len; - - /* Generate and write proof */ - MBEDTLS_MPI_CHK(ecjpake_zkp_write(md_type, grp, pf, G, x, X, id, - p, end, f_rng, p_rng)); - -cleanup: - return ret; -} - -/* - * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs - * Outputs: verified peer public keys Xa, Xb - */ -static int ecjpake_kkpp_read(const mbedtls_md_type_t md_type, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_ecp_point *Xa, - mbedtls_ecp_point *Xb, - const char *id, - const unsigned char *buf, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - const unsigned char *end = buf + len; - - /* - * struct { - * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; - * } ECJPAKEKeyKPPairList; - */ - MBEDTLS_MPI_CHK(ecjpake_kkp_read(md_type, grp, pf, G, Xa, id, &p, end)); - MBEDTLS_MPI_CHK(ecjpake_kkp_read(md_type, grp, pf, G, Xb, id, &p, end)); - - if (p != end) { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - -cleanup: - return ret; -} - -/* - * Generate a ECJPAKEKeyKPPairList - * Outputs: the serialized structure, plus two private/public key pairs - */ -static int ecjpake_kkpp_write(const mbedtls_md_type_t md_type, - const mbedtls_ecp_group *grp, - const int pf, - const mbedtls_ecp_point *G, - mbedtls_mpi *xm1, - mbedtls_ecp_point *Xa, - mbedtls_mpi *xm2, - mbedtls_ecp_point *Xb, - const char *id, - unsigned char *buf, - size_t len, - size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - const unsigned char *end = buf + len; - - MBEDTLS_MPI_CHK(ecjpake_kkp_write(md_type, grp, pf, G, xm1, Xa, id, - &p, end, f_rng, p_rng)); - MBEDTLS_MPI_CHK(ecjpake_kkp_write(md_type, grp, pf, G, xm2, Xb, id, - &p, end, f_rng, p_rng)); - - *olen = (size_t) (p - buf); - -cleanup: - return ret; -} - -/* - * Read and process the first round message - */ -int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len) -{ - return ecjpake_kkpp_read(ctx->md_type, &ctx->grp, ctx->point_format, - &ctx->grp.G, - &ctx->Xp1, &ctx->Xp2, ID_PEER, - buf, len); -} - -/* - * Generate and write the first round message - */ -int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - return ecjpake_kkpp_write(ctx->md_type, &ctx->grp, ctx->point_format, - &ctx->grp.G, - &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, - ID_MINE, buf, len, olen, f_rng, p_rng); -} - -/* - * Compute the sum of three points R = A + B + C - */ -static int ecjpake_ecp_add3(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *A, - const mbedtls_ecp_point *B, - const mbedtls_ecp_point *C) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi one; - - mbedtls_mpi_init(&one); - - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&one, 1)); - MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(grp, R, &one, A, &one, B)); - MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(grp, R, &one, R, &one, C)); - -cleanup: - mbedtls_mpi_free(&one); - - return ret; -} - -/* - * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) - */ -int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx, - const unsigned char *buf, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - const unsigned char *end = buf + len; - mbedtls_ecp_group grp; - mbedtls_ecp_point G; /* C: GB, S: GA */ - - mbedtls_ecp_group_init(&grp); - mbedtls_ecp_point_init(&G); - - /* - * Server: GA = X3 + X4 + X1 (7.4.2.6.1) - * Client: GB = X1 + X2 + X3 (7.4.2.5.1) - * Unified: G = Xm1 + Xm2 + Xp1 - * We need that before parsing in order to check Xp as we read it - */ - MBEDTLS_MPI_CHK(ecjpake_ecp_add3(&ctx->grp, &G, - &ctx->Xm1, &ctx->Xm2, &ctx->Xp1)); - - /* - * struct { - * ECParameters curve_params; // only client reading server msg - * ECJPAKEKeyKP ecjpake_key_kp; - * } Client/ServerECJPAKEParams; - */ - if (ctx->role == MBEDTLS_ECJPAKE_CLIENT) { - MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_group(&grp, &p, len)); - if (grp.id != ctx->grp.id) { - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - goto cleanup; - } - } - - MBEDTLS_MPI_CHK(ecjpake_kkp_read(ctx->md_type, &ctx->grp, - ctx->point_format, - &G, &ctx->Xp, ID_PEER, &p, end)); - - if (p != end) { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - -cleanup: - mbedtls_ecp_group_free(&grp); - mbedtls_ecp_point_free(&G); - - return ret; -} - -/* - * Compute R = +/- X * S mod N, taking care not to leak S - */ -static int ecjpake_mul_secret(mbedtls_mpi *R, int sign, - const mbedtls_mpi *X, - const mbedtls_mpi *S, - const mbedtls_mpi *N, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi b; /* Blinding value, then s + N * blinding */ - - mbedtls_mpi_init(&b); - - /* b = s + rnd-128-bit * N */ - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&b, 16, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&b, &b, N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&b, &b, S)); - - /* R = sign * X * b mod N */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(R, X, &b)); - R->s *= sign; - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(R, R, N)); - -cleanup: - mbedtls_mpi_free(&b); - - return ret; -} - -/* - * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) - */ -int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point G; /* C: GA, S: GB */ - mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ - mbedtls_mpi xm; /* C: xc, S: xs */ - unsigned char *p = buf; - const unsigned char *end = buf + len; - size_t ec_len; - - mbedtls_ecp_point_init(&G); - mbedtls_ecp_point_init(&Xm); - mbedtls_mpi_init(&xm); - - /* - * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) - * - * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA - * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB - * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G - */ - MBEDTLS_MPI_CHK(ecjpake_ecp_add3(&ctx->grp, &G, - &ctx->Xp1, &ctx->Xp2, &ctx->Xm1)); - MBEDTLS_MPI_CHK(ecjpake_mul_secret(&xm, 1, &ctx->xm2, &ctx->s, - &ctx->grp.N, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &Xm, &xm, &G, f_rng, p_rng)); - - /* - * Now write things out - * - * struct { - * ECParameters curve_params; // only server writing its message - * ECJPAKEKeyKP ecjpake_key_kp; - * } Client/ServerECJPAKEParams; - */ - if (ctx->role == MBEDTLS_ECJPAKE_SERVER) { - if (end < p) { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_group(&ctx->grp, &ec_len, - p, (size_t) (end - p))); - p += ec_len; - } - - if (end < p) { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(&ctx->grp, &Xm, - ctx->point_format, &ec_len, p, (size_t) (end - p))); - p += ec_len; - - MBEDTLS_MPI_CHK(ecjpake_zkp_write(ctx->md_type, &ctx->grp, - ctx->point_format, - &G, &xm, &Xm, ID_MINE, - &p, end, f_rng, p_rng)); - - *olen = (size_t) (p - buf); - -cleanup: - mbedtls_ecp_point_free(&G); - mbedtls_ecp_point_free(&Xm); - mbedtls_mpi_free(&xm); - - return ret; -} - -/* - * Derive PMS (7.4.2.7 / 7.4.2.8) - */ -static int mbedtls_ecjpake_derive_k(mbedtls_ecjpake_context *ctx, - mbedtls_ecp_point *K, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi m_xm2_s, one; - - mbedtls_mpi_init(&m_xm2_s); - mbedtls_mpi_init(&one); - - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&one, 1)); - - /* - * Client: K = ( Xs - X4 * x2 * s ) * x2 - * Server: K = ( Xc - X2 * x4 * s ) * x4 - * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 - */ - MBEDTLS_MPI_CHK(ecjpake_mul_secret(&m_xm2_s, -1, &ctx->xm2, &ctx->s, - &ctx->grp.N, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(&ctx->grp, K, - &one, &ctx->Xp, - &m_xm2_s, &ctx->Xp2)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, K, &ctx->xm2, K, - f_rng, p_rng)); - -cleanup: - mbedtls_mpi_free(&m_xm2_s); - mbedtls_mpi_free(&one); - - return ret; -} - -int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point K; - unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; - size_t x_bytes; - - *olen = mbedtls_md_get_size_from_type(ctx->md_type); - if (len < *olen) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - mbedtls_ecp_point_init(&K); - - ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng); - if (ret) { - goto cleanup; - } - - /* PMS = SHA-256( K.X ) */ - x_bytes = (ctx->grp.pbits + 7) / 8; - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K.X, kx, x_bytes)); - MBEDTLS_MPI_CHK(mbedtls_ecjpake_compute_hash(ctx->md_type, - kx, x_bytes, buf)); - -cleanup: - mbedtls_ecp_point_free(&K); - - return ret; -} - -int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx, - unsigned char *buf, size_t len, size_t *olen, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point K; - - mbedtls_ecp_point_init(&K); - - ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng); - if (ret) { - goto cleanup; - } - - ret = mbedtls_ecp_point_write_binary(&ctx->grp, &K, ctx->point_format, - olen, buf, len); - if (ret != 0) { - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free(&K); - - return ret; -} - -#undef ID_MINE -#undef ID_PEER - -#endif /* ! MBEDTLS_ECJPAKE_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - !defined(MBEDTLS_MD_CAN_SHA256) -int mbedtls_ecjpake_self_test(int verbose) -{ - (void) verbose; - return 0; -} -#else - -static const unsigned char ecjpake_test_password[] = { - 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, - 0x65, 0x73, 0x74 -}; - -#if !defined(MBEDTLS_ECJPAKE_ALT) - -static const unsigned char ecjpake_test_x1[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, - 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 -}; - -static const unsigned char ecjpake_test_x2[] = { - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 -}; - -static const unsigned char ecjpake_test_x3[] = { - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 -}; - -static const unsigned char ecjpake_test_x4[] = { - 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, - 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 -}; - -static const unsigned char ecjpake_test_cli_one[] = { - 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, - 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, - 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, - 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, - 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, - 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, - 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, - 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, - 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, - 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, - 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, - 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, - 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, - 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, - 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, - 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, - 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, - 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, - 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, - 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, - 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, - 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, - 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, - 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, - 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, - 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, - 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, - 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 -}; - -static const unsigned char ecjpake_test_srv_one[] = { - 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, - 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, - 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, - 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, - 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, - 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, - 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, - 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, - 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, - 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, - 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, - 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, - 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, - 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, - 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, - 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, - 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, - 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, - 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, - 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, - 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, - 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, - 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, - 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, - 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, - 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, - 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, - 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 -}; - -static const unsigned char ecjpake_test_srv_two[] = { - 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, - 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, - 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, - 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, - 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, - 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, - 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, - 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, - 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, - 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, - 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, - 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, - 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, - 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c -}; - -static const unsigned char ecjpake_test_cli_two[] = { - 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, - 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, - 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, - 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, - 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, - 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, - 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, - 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, - 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, - 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, - 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, - 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, - 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, - 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c -}; - -static const unsigned char ecjpake_test_shared_key[] = { - 0x04, 0x01, 0xab, 0xe9, 0xf2, 0xc7, 0x3a, 0x99, 0x14, 0xcb, 0x1f, 0x80, - 0xfb, 0x9d, 0xdb, 0x7e, 0x00, 0x12, 0xa8, 0x9c, 0x2f, 0x39, 0x27, 0x79, - 0xf9, 0x64, 0x40, 0x14, 0x75, 0xea, 0xc1, 0x31, 0x28, 0x43, 0x8f, 0xe1, - 0x12, 0x41, 0xd6, 0xc1, 0xe5, 0x5f, 0x7b, 0x80, 0x88, 0x94, 0xc9, 0xc0, - 0x27, 0xa3, 0x34, 0x41, 0xf5, 0xcb, 0xa1, 0xfe, 0x6c, 0xc7, 0xe6, 0x12, - 0x17, 0xc3, 0xde, 0x27, 0xb4, -}; - -static const unsigned char ecjpake_test_pms[] = { - 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, - 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, - 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 -}; - -/* - * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!! - * - * This is the linear congruential generator from numerical recipes, - * except we only use the low byte as the output. See - * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use - */ -static int self_test_rng(void *ctx, unsigned char *out, size_t len) -{ - static uint32_t state = 42; - - (void) ctx; - - for (size_t i = 0; i < len; i++) { - state = state * 1664525u + 1013904223u; - out[i] = (unsigned char) state; - } - - return 0; -} - -/* Load my private keys and generate the corresponding public keys */ -static int ecjpake_test_load(mbedtls_ecjpake_context *ctx, - const unsigned char *xm1, size_t len1, - const unsigned char *xm2, size_t len2) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->xm1, xm1, len1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->xm2, xm2, len2)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &ctx->Xm1, &ctx->xm1, - &ctx->grp.G, self_test_rng, NULL)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &ctx->Xm2, &ctx->xm2, - &ctx->grp.G, self_test_rng, NULL)); - -cleanup: - return ret; -} - -#endif /* ! MBEDTLS_ECJPAKE_ALT */ - -/* For tests we don't need a secure RNG; - * use the LGC from Numerical Recipes for simplicity */ -static int ecjpake_lgc(void *p, unsigned char *out, size_t len) -{ - static uint32_t x = 42; - (void) p; - - while (len > 0) { - size_t use_len = len > 4 ? 4 : len; - x = 1664525 * x + 1013904223; - memcpy(out, &x, use_len); - out += use_len; - len -= use_len; - } - - return 0; -} - -#define TEST_ASSERT(x) \ - do { \ - if (x) \ - ret = 0; \ - else \ - { \ - ret = 1; \ - goto cleanup; \ - } \ - } while (0) - -/* - * Checkup routine - */ -int mbedtls_ecjpake_self_test(int verbose) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecjpake_context cli; - mbedtls_ecjpake_context srv; - unsigned char buf[512], pms[32]; - size_t len, pmslen; - - mbedtls_ecjpake_init(&cli); - mbedtls_ecjpake_init(&srv); - - if (verbose != 0) { - mbedtls_printf(" ECJPAKE test #0 (setup): "); - } - - TEST_ASSERT(mbedtls_ecjpake_setup(&cli, MBEDTLS_ECJPAKE_CLIENT, - MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, - ecjpake_test_password, - sizeof(ecjpake_test_password)) == 0); - - TEST_ASSERT(mbedtls_ecjpake_setup(&srv, MBEDTLS_ECJPAKE_SERVER, - MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, - ecjpake_test_password, - sizeof(ecjpake_test_password)) == 0); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - if (verbose != 0) { - mbedtls_printf(" ECJPAKE test #1 (random handshake): "); - } - - TEST_ASSERT(mbedtls_ecjpake_write_round_one(&cli, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(mbedtls_ecjpake_read_round_one(&srv, buf, len) == 0); - - TEST_ASSERT(mbedtls_ecjpake_write_round_one(&srv, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(mbedtls_ecjpake_read_round_one(&cli, buf, len) == 0); - - TEST_ASSERT(mbedtls_ecjpake_write_round_two(&srv, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(mbedtls_ecjpake_read_round_two(&cli, buf, len) == 0); - - TEST_ASSERT(mbedtls_ecjpake_derive_secret(&cli, - pms, sizeof(pms), &pmslen, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(mbedtls_ecjpake_write_round_two(&cli, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(mbedtls_ecjpake_read_round_two(&srv, buf, len) == 0); - - TEST_ASSERT(mbedtls_ecjpake_derive_secret(&srv, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(len == pmslen); - TEST_ASSERT(memcmp(buf, pms, len) == 0); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - -#if !defined(MBEDTLS_ECJPAKE_ALT) - /* 'reference handshake' tests can only be run against implementations - * for which we have 100% control over how the random ephemeral keys - * are generated. This is only the case for the internal Mbed TLS - * implementation, so these tests are skipped in case the internal - * implementation is swapped out for an alternative one. */ - if (verbose != 0) { - mbedtls_printf(" ECJPAKE test #2 (reference handshake): "); - } - - /* Simulate generation of round one */ - MBEDTLS_MPI_CHK(ecjpake_test_load(&cli, - ecjpake_test_x1, sizeof(ecjpake_test_x1), - ecjpake_test_x2, sizeof(ecjpake_test_x2))); - - MBEDTLS_MPI_CHK(ecjpake_test_load(&srv, - ecjpake_test_x3, sizeof(ecjpake_test_x3), - ecjpake_test_x4, sizeof(ecjpake_test_x4))); - - /* Read round one */ - TEST_ASSERT(mbedtls_ecjpake_read_round_one(&srv, - ecjpake_test_cli_one, - sizeof(ecjpake_test_cli_one)) == 0); - - TEST_ASSERT(mbedtls_ecjpake_read_round_one(&cli, - ecjpake_test_srv_one, - sizeof(ecjpake_test_srv_one)) == 0); - - /* Skip generation of round two, read round two */ - TEST_ASSERT(mbedtls_ecjpake_read_round_two(&cli, - ecjpake_test_srv_two, - sizeof(ecjpake_test_srv_two)) == 0); - - TEST_ASSERT(mbedtls_ecjpake_read_round_two(&srv, - ecjpake_test_cli_two, - sizeof(ecjpake_test_cli_two)) == 0); - - /* Server derives PMS */ - TEST_ASSERT(mbedtls_ecjpake_derive_secret(&srv, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(len == sizeof(ecjpake_test_pms)); - TEST_ASSERT(memcmp(buf, ecjpake_test_pms, len) == 0); - - /* Server derives K as unsigned binary data */ - TEST_ASSERT(mbedtls_ecjpake_write_shared_key(&srv, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(len == sizeof(ecjpake_test_shared_key)); - TEST_ASSERT(memcmp(buf, ecjpake_test_shared_key, len) == 0); - - memset(buf, 0, len); /* Avoid interferences with next step */ - - /* Client derives PMS */ - TEST_ASSERT(mbedtls_ecjpake_derive_secret(&cli, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(len == sizeof(ecjpake_test_pms)); - TEST_ASSERT(memcmp(buf, ecjpake_test_pms, len) == 0); - - /* Client derives K as unsigned binary data */ - TEST_ASSERT(mbedtls_ecjpake_write_shared_key(&cli, - buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); - - TEST_ASSERT(len == sizeof(ecjpake_test_shared_key)); - TEST_ASSERT(memcmp(buf, ecjpake_test_shared_key, len) == 0); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } -#endif /* ! MBEDTLS_ECJPAKE_ALT */ - -cleanup: - mbedtls_ecjpake_free(&cli); - mbedtls_ecjpake_free(&srv); - - if (ret != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return ret; -} - -#undef TEST_ASSERT - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_MD_CAN_SHA256 */ - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ECJPAKE_C */ diff --git a/vendor/mbedtls/library/ecp.c b/vendor/mbedtls/library/ecp.c deleted file mode 100644 index 6af516c0a..000000000 --- a/vendor/mbedtls/library/ecp.c +++ /dev/null @@ -1,3677 +0,0 @@ -/* - * Elliptic curves over GF(p): generic functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * References: - * - * SEC1 https://www.secg.org/sec1-v2.pdf - * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone - * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf - * RFC 4492 for the related TLS structures and constants - * - https://www.rfc-editor.org/rfc/rfc4492 - * RFC 7748 for the Curve448 and Curve25519 curve definitions - * - https://www.rfc-editor.org/rfc/rfc7748 - * - * [Curve25519] https://cr.yp.to/ecdh/curve25519-20060209.pdf - * - * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis - * for elliptic curve cryptosystems. In : Cryptographic Hardware and - * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. - * - * - * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to - * render ECC resistant against Side Channel Attacks. IACR Cryptology - * ePrint Archive, 2004, vol. 2004, p. 342. - * - */ - -#include "common.h" - -/** - * \brief Function level alternative implementation. - * - * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to - * replace certain functions in this module. The alternative implementations are - * typically hardware accelerators and need to activate the hardware before the - * computation starts and deactivate it after it finishes. The - * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve - * this purpose. - * - * To preserve the correct functionality the following conditions must hold: - * - * - The alternative implementation must be activated by - * mbedtls_internal_ecp_init() before any of the replaceable functions is - * called. - * - mbedtls_internal_ecp_free() must \b only be called when the alternative - * implementation is activated. - * - mbedtls_internal_ecp_init() must \b not be called when the alternative - * implementation is activated. - * - Public functions must not return while the alternative implementation is - * activated. - * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and - * before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) ) - * \endcode ensures that the alternative implementation supports the current - * group. - */ -#if defined(MBEDTLS_ECP_INTERNAL_ALT) -#endif - -#if defined(MBEDTLS_ECP_LIGHT) - -#include "mbedtls/ecp.h" -#include "mbedtls/threading.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include "bn_mul.h" -#include "bignum_internal.h" -#include "ecp_invasive.h" - -#include - -#if !defined(MBEDTLS_ECP_ALT) - -#include "mbedtls/platform.h" - -#include "ecp_internal_alt.h" - -#if defined(MBEDTLS_SELF_TEST) -/* - * Counts of point addition and doubling, and field multiplications. - * Used to test resistance of point multiplication to simple timing attacks. - */ -#if defined(MBEDTLS_ECP_C) -static unsigned long add_count, dbl_count; -#endif /* MBEDTLS_ECP_C */ -static unsigned long mul_count; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Maximum number of "basic operations" to be done in a row. - * - * Default value 0 means that ECC operations will not yield. - * Note that regardless of the value of ecp_max_ops, always at - * least one step is performed before yielding. - * - * Setting ecp_max_ops=1 can be suitable for testing purposes - * as it will interrupt computation at all possible points. - */ -static unsigned ecp_max_ops = 0; - -/* - * Set ecp_max_ops - */ -void mbedtls_ecp_set_max_ops(unsigned max_ops) -{ - ecp_max_ops = max_ops; -} - -/* - * Check if restart is enabled - */ -int mbedtls_ecp_restart_is_enabled(void) -{ - return ecp_max_ops != 0; -} - -/* - * Restart sub-context for ecp_mul_comb() - */ -struct mbedtls_ecp_restart_mul { - mbedtls_ecp_point R; /* current intermediate result */ - size_t i; /* current index in various loops, 0 outside */ - mbedtls_ecp_point *T; /* table for precomputed points */ - unsigned char T_size; /* number of points in table T */ - enum { /* what were we doing last time we returned? */ - ecp_rsm_init = 0, /* nothing so far, dummy initial state */ - ecp_rsm_pre_dbl, /* precompute 2^n multiples */ - ecp_rsm_pre_norm_dbl, /* normalize precomputed 2^n multiples */ - ecp_rsm_pre_add, /* precompute remaining points by adding */ - ecp_rsm_pre_norm_add, /* normalize all precomputed points */ - ecp_rsm_comb_core, /* ecp_mul_comb_core() */ - ecp_rsm_final_norm, /* do the final normalization */ - } state; -}; - -/* - * Init restart_mul sub-context - */ -static void ecp_restart_rsm_init(mbedtls_ecp_restart_mul_ctx *ctx) -{ - mbedtls_ecp_point_init(&ctx->R); - ctx->i = 0; - ctx->T = NULL; - ctx->T_size = 0; - ctx->state = ecp_rsm_init; -} - -/* - * Free the components of a restart_mul sub-context - */ -static void ecp_restart_rsm_free(mbedtls_ecp_restart_mul_ctx *ctx) -{ - unsigned char i; - - if (ctx == NULL) { - return; - } - - mbedtls_ecp_point_free(&ctx->R); - - if (ctx->T != NULL) { - for (i = 0; i < ctx->T_size; i++) { - mbedtls_ecp_point_free(ctx->T + i); - } - mbedtls_free(ctx->T); - } - - ecp_restart_rsm_init(ctx); -} - -/* - * Restart context for ecp_muladd() - */ -struct mbedtls_ecp_restart_muladd { - mbedtls_ecp_point mP; /* mP value */ - mbedtls_ecp_point R; /* R intermediate result */ - enum { /* what should we do next? */ - ecp_rsma_mul1 = 0, /* first multiplication */ - ecp_rsma_mul2, /* second multiplication */ - ecp_rsma_add, /* addition */ - ecp_rsma_norm, /* normalization */ - } state; -}; - -/* - * Init restart_muladd sub-context - */ -static void ecp_restart_ma_init(mbedtls_ecp_restart_muladd_ctx *ctx) -{ - mbedtls_ecp_point_init(&ctx->mP); - mbedtls_ecp_point_init(&ctx->R); - ctx->state = ecp_rsma_mul1; -} - -/* - * Free the components of a restart_muladd sub-context - */ -static void ecp_restart_ma_free(mbedtls_ecp_restart_muladd_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_ecp_point_free(&ctx->mP); - mbedtls_ecp_point_free(&ctx->R); - - ecp_restart_ma_init(ctx); -} - -/* - * Initialize a restart context - */ -void mbedtls_ecp_restart_init(mbedtls_ecp_restart_ctx *ctx) -{ - ctx->ops_done = 0; - ctx->depth = 0; - ctx->rsm = NULL; - ctx->ma = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_ecp_restart_free(mbedtls_ecp_restart_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - - ecp_restart_rsm_free(ctx->rsm); - mbedtls_free(ctx->rsm); - - ecp_restart_ma_free(ctx->ma); - mbedtls_free(ctx->ma); - - mbedtls_ecp_restart_init(ctx); -} - -/* - * Check if we can do the next step - */ -int mbedtls_ecp_check_budget(const mbedtls_ecp_group *grp, - mbedtls_ecp_restart_ctx *rs_ctx, - unsigned ops) -{ - if (rs_ctx != NULL && ecp_max_ops != 0) { - /* scale depending on curve size: the chosen reference is 256-bit, - * and multiplication is quadratic. Round to the closest integer. */ - if (grp->pbits >= 512) { - ops *= 4; - } else if (grp->pbits >= 384) { - ops *= 2; - } - - /* Avoid infinite loops: always allow first step. - * Because of that, however, it's not generally true - * that ops_done <= ecp_max_ops, so the check - * ops_done > ecp_max_ops below is mandatory. */ - if ((rs_ctx->ops_done != 0) && - (rs_ctx->ops_done > ecp_max_ops || - ops > ecp_max_ops - rs_ctx->ops_done)) { - return MBEDTLS_ERR_ECP_IN_PROGRESS; - } - - /* update running count */ - rs_ctx->ops_done += ops; - } - - return 0; -} - -/* Call this when entering a function that needs its own sub-context */ -#define ECP_RS_ENTER(SUB) do { \ - /* reset ops count for this call if top-level */ \ - if (rs_ctx != NULL && rs_ctx->depth++ == 0) \ - rs_ctx->ops_done = 0; \ - \ - /* set up our own sub-context if needed */ \ - if (mbedtls_ecp_restart_is_enabled() && \ - rs_ctx != NULL && rs_ctx->SUB == NULL) \ - { \ - rs_ctx->SUB = mbedtls_calloc(1, sizeof(*rs_ctx->SUB)); \ - if (rs_ctx->SUB == NULL) \ - return MBEDTLS_ERR_ECP_ALLOC_FAILED; \ - \ - ecp_restart_## SUB ##_init(rs_ctx->SUB); \ - } \ -} while (0) - -/* Call this when leaving a function that needs its own sub-context */ -#define ECP_RS_LEAVE(SUB) do { \ - /* clear our sub-context when not in progress (done or error) */ \ - if (rs_ctx != NULL && rs_ctx->SUB != NULL && \ - ret != MBEDTLS_ERR_ECP_IN_PROGRESS) \ - { \ - ecp_restart_## SUB ##_free(rs_ctx->SUB); \ - mbedtls_free(rs_ctx->SUB); \ - rs_ctx->SUB = NULL; \ - } \ - \ - if (rs_ctx != NULL) \ - rs_ctx->depth--; \ -} while (0) - -#else /* MBEDTLS_ECP_RESTARTABLE */ - -#define ECP_RS_ENTER(sub) (void) rs_ctx; -#define ECP_RS_LEAVE(sub) (void) rs_ctx; - -#endif /* MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_ECP_C) -static void mpi_init_many(mbedtls_mpi *arr, size_t size) -{ - while (size--) { - mbedtls_mpi_init(arr++); - } -} - -static void mpi_free_many(mbedtls_mpi *arr, size_t size) -{ - while (size--) { - mbedtls_mpi_free(arr++); - } -} -#endif /* MBEDTLS_ECP_C */ - -/* - * List of supported curves: - * - internal ID - * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2, RFC 8446 sec. 4.2.7) - * - size in bits - * - readable name - * - * Curves are listed in order: largest curves first, and for a given size, - * fastest curves first. - * - * Reminder: update profiles in x509_crt.c and ssl_tls.c when adding a new curve! - */ -static const mbedtls_ecp_curve_info ecp_supported_curves[] = -{ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, -#endif -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, -#endif -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - { MBEDTLS_ECP_DP_CURVE25519, 29, 256, "x25519" }, -#endif -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - { MBEDTLS_ECP_DP_CURVE448, 30, 448, "x448" }, -#endif - { MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, -}; - -#define ECP_NB_CURVES sizeof(ecp_supported_curves) / \ - sizeof(ecp_supported_curves[0]) - -static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; - -/* - * List of supported curves and associated info - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list(void) -{ - return ecp_supported_curves; -} - -/* - * List of supported curves, group ID only - */ -const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list(void) -{ - static int init_done = 0; - - if (!init_done) { - size_t i = 0; - const mbedtls_ecp_curve_info *curve_info; - - for (curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++) { - ecp_supported_grp_id[i++] = curve_info->grp_id; - } - ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE; - - init_done = 1; - } - - return ecp_supported_grp_id; -} - -/* - * Get the curve info for the internal identifier - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id(mbedtls_ecp_group_id grp_id) -{ - const mbedtls_ecp_curve_info *curve_info; - - for (curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++) { - if (curve_info->grp_id == grp_id) { - return curve_info; - } - } - - return NULL; -} - -/* - * Get the curve info from the TLS identifier - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id(uint16_t tls_id) -{ - const mbedtls_ecp_curve_info *curve_info; - - for (curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++) { - if (curve_info->tls_id == tls_id) { - return curve_info; - } - } - - return NULL; -} - -/* - * Get the curve info from the name - */ -const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name(const char *name) -{ - const mbedtls_ecp_curve_info *curve_info; - - if (name == NULL) { - return NULL; - } - - for (curve_info = mbedtls_ecp_curve_list(); - curve_info->grp_id != MBEDTLS_ECP_DP_NONE; - curve_info++) { - if (strcmp(curve_info->name, name) == 0) { - return curve_info; - } - } - - return NULL; -} - -/* - * Get the type of a curve - */ -mbedtls_ecp_curve_type mbedtls_ecp_get_type(const mbedtls_ecp_group *grp) -{ - if (grp->G.X.p == NULL) { - return MBEDTLS_ECP_TYPE_NONE; - } - - if (grp->G.Y.p == NULL) { - return MBEDTLS_ECP_TYPE_MONTGOMERY; - } else { - return MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS; - } -} - -/* - * Initialize (the components of) a point - */ -void mbedtls_ecp_point_init(mbedtls_ecp_point *pt) -{ - mbedtls_mpi_init(&pt->X); - mbedtls_mpi_init(&pt->Y); - mbedtls_mpi_init(&pt->Z); -} - -/* - * Initialize (the components of) a group - */ -void mbedtls_ecp_group_init(mbedtls_ecp_group *grp) -{ - grp->id = MBEDTLS_ECP_DP_NONE; - mbedtls_mpi_init(&grp->P); - mbedtls_mpi_init(&grp->A); - mbedtls_mpi_init(&grp->B); - mbedtls_ecp_point_init(&grp->G); - mbedtls_mpi_init(&grp->N); - grp->pbits = 0; - grp->nbits = 0; - grp->h = 0; - grp->modp = NULL; - grp->t_pre = NULL; - grp->t_post = NULL; - grp->t_data = NULL; - grp->T = NULL; - grp->T_size = 0; -} - -/* - * Initialize (the components of) a key pair - */ -void mbedtls_ecp_keypair_init(mbedtls_ecp_keypair *key) -{ - mbedtls_ecp_group_init(&key->grp); - mbedtls_mpi_init(&key->d); - mbedtls_ecp_point_init(&key->Q); -} - -/* - * Unallocate (the components of) a point - */ -void mbedtls_ecp_point_free(mbedtls_ecp_point *pt) -{ - if (pt == NULL) { - return; - } - - mbedtls_mpi_free(&(pt->X)); - mbedtls_mpi_free(&(pt->Y)); - mbedtls_mpi_free(&(pt->Z)); -} - -/* - * Check that the comb table (grp->T) is static initialized. - */ -static int ecp_group_is_static_comb_table(const mbedtls_ecp_group *grp) -{ -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 - return grp->T != NULL && grp->T_size == 0; -#else - (void) grp; - return 0; -#endif -} - -/* - * Unallocate (the components of) a group - */ -void mbedtls_ecp_group_free(mbedtls_ecp_group *grp) -{ - size_t i; - - if (grp == NULL) { - return; - } - - if (grp->h != 1) { - mbedtls_mpi_free(&grp->A); - mbedtls_mpi_free(&grp->B); - mbedtls_ecp_point_free(&grp->G); - -#if !defined(MBEDTLS_ECP_WITH_MPI_UINT) - mbedtls_mpi_free(&grp->N); - mbedtls_mpi_free(&grp->P); -#endif - } - - if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) { - for (i = 0; i < grp->T_size; i++) { - mbedtls_ecp_point_free(&grp->T[i]); - } - mbedtls_free(grp->T); - } - - mbedtls_platform_zeroize(grp, sizeof(mbedtls_ecp_group)); -} - -/* - * Unallocate (the components of) a key pair - */ -void mbedtls_ecp_keypair_free(mbedtls_ecp_keypair *key) -{ - if (key == NULL) { - return; - } - - mbedtls_ecp_group_free(&key->grp); - mbedtls_mpi_free(&key->d); - mbedtls_ecp_point_free(&key->Q); -} - -/* - * Copy the contents of a point - */ -int mbedtls_ecp_copy(mbedtls_ecp_point *P, const mbedtls_ecp_point *Q) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->X, &Q->X)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->Y, &Q->Y)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->Z, &Q->Z)); - -cleanup: - return ret; -} - -/* - * Copy the contents of a group object - */ -int mbedtls_ecp_group_copy(mbedtls_ecp_group *dst, const mbedtls_ecp_group *src) -{ - return mbedtls_ecp_group_load(dst, src->id); -} - -/* - * Set point to zero - */ -int mbedtls_ecp_set_zero(mbedtls_ecp_point *pt) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->X, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Y, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 0)); - -cleanup: - return ret; -} - -/* - * Tell if a point is zero - */ -int mbedtls_ecp_is_zero(mbedtls_ecp_point *pt) -{ - return mbedtls_mpi_cmp_int(&pt->Z, 0) == 0; -} - -/* - * Compare two points lazily - */ -int mbedtls_ecp_point_cmp(const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q) -{ - if (mbedtls_mpi_cmp_mpi(&P->X, &Q->X) == 0 && - mbedtls_mpi_cmp_mpi(&P->Y, &Q->Y) == 0 && - mbedtls_mpi_cmp_mpi(&P->Z, &Q->Z) == 0) { - return 0; - } - - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -} - -/* - * Import a non-zero point from ASCII strings - */ -int mbedtls_ecp_point_read_string(mbedtls_ecp_point *P, int radix, - const char *x, const char *y) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&P->X, radix, x)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&P->Y, radix, y)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&P->Z, 1)); - -cleanup: - return ret; -} - -/* - * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748) - */ -int mbedtls_ecp_point_write_binary(const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *P, - int format, size_t *olen, - unsigned char *buf, size_t buflen) -{ - int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - size_t plen; - if (format != MBEDTLS_ECP_PF_UNCOMPRESSED && - format != MBEDTLS_ECP_PF_COMPRESSED) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - plen = mbedtls_mpi_size(&grp->P); - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - (void) format; /* Montgomery curves always use the same point format */ - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - *olen = plen; - if (buflen < *olen) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&P->X, buf, plen)); - } -#endif -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - /* - * Common case: P == 0 - */ - if (mbedtls_mpi_cmp_int(&P->Z, 0) == 0) { - if (buflen < 1) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - buf[0] = 0x00; - *olen = 1; - - return 0; - } - - if (format == MBEDTLS_ECP_PF_UNCOMPRESSED) { - *olen = 2 * plen + 1; - - if (buflen < *olen) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - buf[0] = 0x04; - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->X, buf + 1, plen)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->Y, buf + 1 + plen, plen)); - } else if (format == MBEDTLS_ECP_PF_COMPRESSED) { - *olen = plen + 1; - - if (buflen < *olen) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - buf[0] = 0x02 + mbedtls_mpi_get_bit(&P->Y, 0); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->X, buf + 1, plen)); - } - } -#endif - -cleanup: - return ret; -} - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -static int mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group *grp, - const mbedtls_mpi *X, - mbedtls_mpi *Y, - int parity_bit); -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -/* - * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748) - */ -int mbedtls_ecp_point_read_binary(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char *buf, size_t ilen) -{ - int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - size_t plen; - if (ilen < 1) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - plen = mbedtls_mpi_size(&grp->P); - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - if (plen != ilen) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&pt->X, buf, plen)); - mbedtls_mpi_free(&pt->Y); - - if (grp->id == MBEDTLS_ECP_DP_CURVE25519) { - /* Set most significant bit to 0 as prescribed in RFC7748 §5 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&pt->X, plen * 8 - 1, 0)); - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 1)); - } -#endif -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - if (buf[0] == 0x00) { - if (ilen == 1) { - return mbedtls_ecp_set_zero(pt); - } else { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - } - - if (ilen < 1 + plen) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->X, buf + 1, plen)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 1)); - - if (buf[0] == 0x04) { - /* format == MBEDTLS_ECP_PF_UNCOMPRESSED */ - if (ilen != 1 + plen * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - return mbedtls_mpi_read_binary(&pt->Y, buf + 1 + plen, plen); - } else if (buf[0] == 0x02 || buf[0] == 0x03) { - /* format == MBEDTLS_ECP_PF_COMPRESSED */ - if (ilen != 1 + plen) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - return mbedtls_ecp_sw_derive_y(grp, &pt->X, &pt->Y, - (buf[0] & 1)); - } else { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - } -#endif - -cleanup: - return ret; -} - -/* - * Import a point from a TLS ECPoint record (RFC 4492) - * struct { - * opaque point <1..2^8-1>; - * } ECPoint; - */ -int mbedtls_ecp_tls_read_point(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, - const unsigned char **buf, size_t buf_len) -{ - unsigned char data_len; - const unsigned char *buf_start; - /* - * We must have at least two bytes (1 for length, at least one for data) - */ - if (buf_len < 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - data_len = *(*buf)++; - if (data_len < 1 || data_len > buf_len - 1) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* - * Save buffer start for read_binary and update buf - */ - buf_start = *buf; - *buf += data_len; - - return mbedtls_ecp_point_read_binary(grp, pt, buf_start, data_len); -} - -/* - * Export a point as a TLS ECPoint record (RFC 4492) - * struct { - * opaque point <1..2^8-1>; - * } ECPoint; - */ -int mbedtls_ecp_tls_write_point(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, - int format, size_t *olen, - unsigned char *buf, size_t blen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if (format != MBEDTLS_ECP_PF_UNCOMPRESSED && - format != MBEDTLS_ECP_PF_COMPRESSED) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* - * buffer length must be at least one, for our length byte - */ - if (blen < 1) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_ecp_point_write_binary(grp, pt, format, - olen, buf + 1, blen - 1)) != 0) { - return ret; - } - - /* - * write length to the first byte and update total length - */ - buf[0] = (unsigned char) *olen; - ++*olen; - - return 0; -} - -/* - * Set a group from an ECParameters record (RFC 4492) - */ -int mbedtls_ecp_tls_read_group(mbedtls_ecp_group *grp, - const unsigned char **buf, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_group_id grp_id; - if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, len)) != 0) { - return ret; - } - - return mbedtls_ecp_group_load(grp, grp_id); -} - -/* - * Read a group id from an ECParameters record (RFC 4492) and convert it to - * mbedtls_ecp_group_id. - */ -int mbedtls_ecp_tls_read_group_id(mbedtls_ecp_group_id *grp, - const unsigned char **buf, size_t len) -{ - uint16_t tls_id; - const mbedtls_ecp_curve_info *curve_info; - /* - * We expect at least three bytes (see below) - */ - if (len < 3) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* - * First byte is curve_type; only named_curve is handled - */ - if (*(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* - * Next two bytes are the namedcurve value - */ - tls_id = MBEDTLS_GET_UINT16_BE(*buf, 0); - *buf += 2; - - if ((curve_info = mbedtls_ecp_curve_info_from_tls_id(tls_id)) == NULL) { - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } - - *grp = curve_info->grp_id; - - return 0; -} - -/* - * Write the ECParameters record corresponding to a group (RFC 4492) - */ -int mbedtls_ecp_tls_write_group(const mbedtls_ecp_group *grp, size_t *olen, - unsigned char *buf, size_t blen) -{ - const mbedtls_ecp_curve_info *curve_info; - if ((curve_info = mbedtls_ecp_curve_info_from_grp_id(grp->id)) == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* - * We are going to write 3 bytes (see below) - */ - *olen = 3; - if (blen < *olen) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - /* - * First byte is curve_type, always named_curve - */ - *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE; - - /* - * Next two bytes are the namedcurve value - */ - MBEDTLS_PUT_UINT16_BE(curve_info->tls_id, buf, 0); - - return 0; -} - -/* - * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi. - * See the documentation of struct mbedtls_ecp_group. - * - * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf. - */ -static int ecp_modp(mbedtls_mpi *N, const mbedtls_ecp_group *grp) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (grp->modp == NULL) { - return mbedtls_mpi_mod_mpi(N, N, &grp->P); - } - - /* N->s < 0 is a much faster test, which fails only if N is 0 */ - if ((N->s < 0 && mbedtls_mpi_cmp_int(N, 0) != 0) || - mbedtls_mpi_bitlen(N) > 2 * grp->pbits) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - MBEDTLS_MPI_CHK(grp->modp(N)); - - /* N->s < 0 is a much faster test, which fails only if N is 0 */ - while (N->s < 0 && mbedtls_mpi_cmp_int(N, 0) != 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &grp->P)); - } - - while (mbedtls_mpi_cmp_mpi(N, &grp->P) >= 0) { - /* we known P, N and the result are positive */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(N, N, &grp->P)); - } - -cleanup: - return ret; -} - -/* - * Fast mod-p functions expect their argument to be in the 0..p^2 range. - * - * In order to guarantee that, we need to ensure that operands of - * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will - * bring the result back to this range. - * - * The following macros are shortcuts for doing that. - */ - -/* - * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi - */ -#if defined(MBEDTLS_SELF_TEST) -#define INC_MUL_COUNT mul_count++; -#else -#define INC_MUL_COUNT -#endif - -#define MOD_MUL(N) \ - do \ - { \ - MBEDTLS_MPI_CHK(ecp_modp(&(N), grp)); \ - INC_MUL_COUNT \ - } while (0) - -static inline int mbedtls_mpi_mul_mod(const mbedtls_ecp_group *grp, - mbedtls_mpi *X, - const mbedtls_mpi *A, - const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(X, A, B)); - MOD_MUL(*X); -cleanup: - return ret; -} - -/* - * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi - * N->s < 0 is a very fast test, which fails only if N is 0 - */ -#define MOD_SUB(N) \ - do { \ - while ((N)->s < 0 && mbedtls_mpi_cmp_int((N), 0) != 0) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi((N), (N), &grp->P)); \ - } while (0) - -MBEDTLS_MAYBE_UNUSED -static inline int mbedtls_mpi_sub_mod(const mbedtls_ecp_group *grp, - mbedtls_mpi *X, - const mbedtls_mpi *A, - const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(X, A, B)); - MOD_SUB(X); -cleanup: - return ret; -} - -/* - * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. - * We known P, N and the result are positive, so sub_abs is correct, and - * a bit faster. - */ -#define MOD_ADD(N) \ - while (mbedtls_mpi_cmp_mpi((N), &grp->P) >= 0) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs((N), (N), &grp->P)) - -static inline int mbedtls_mpi_add_mod(const mbedtls_ecp_group *grp, - mbedtls_mpi *X, - const mbedtls_mpi *A, - const mbedtls_mpi *B) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, A, B)); - MOD_ADD(X); -cleanup: - return ret; -} - -MBEDTLS_MAYBE_UNUSED -static inline int mbedtls_mpi_mul_int_mod(const mbedtls_ecp_group *grp, - mbedtls_mpi *X, - const mbedtls_mpi *A, - mbedtls_mpi_uint c) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(X, A, c)); - MOD_ADD(X); -cleanup: - return ret; -} - -MBEDTLS_MAYBE_UNUSED -static inline int mbedtls_mpi_sub_int_mod(const mbedtls_ecp_group *grp, - mbedtls_mpi *X, - const mbedtls_mpi *A, - mbedtls_mpi_uint c) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(X, A, c)); - MOD_SUB(X); -cleanup: - return ret; -} - -#define MPI_ECP_SUB_INT(X, A, c) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int_mod(grp, X, A, c)) - -MBEDTLS_MAYBE_UNUSED -static inline int mbedtls_mpi_shift_l_mod(const mbedtls_ecp_group *grp, - mbedtls_mpi *X, - size_t count) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, count)); - MOD_ADD(X); -cleanup: - return ret; -} - -/* - * Macro wrappers around ECP modular arithmetic - * - * Currently, these wrappers are defined via the bignum module. - */ - -#define MPI_ECP_ADD(X, A, B) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mod(grp, X, A, B)) - -#define MPI_ECP_SUB(X, A, B) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mod(grp, X, A, B)) - -#define MPI_ECP_MUL(X, A, B) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mod(grp, X, A, B)) - -#define MPI_ECP_SQR(X, A) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mod(grp, X, A, A)) - -#define MPI_ECP_MUL_INT(X, A, c) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int_mod(grp, X, A, c)) - -#define MPI_ECP_INV(dst, src) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, (dst), (src), &grp->P)) - -#define MPI_ECP_MOV(X, A) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A)) - -#define MPI_ECP_SHIFT_L(X, count) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l_mod(grp, X, count)) - -#define MPI_ECP_LSET(X, c) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, c)) - -#define MPI_ECP_CMP_INT(X, c) \ - mbedtls_mpi_cmp_int(X, c) - -#define MPI_ECP_CMP(X, Y) \ - mbedtls_mpi_cmp_mpi(X, Y) - -/* Needs f_rng, p_rng to be defined. */ -#define MPI_ECP_RAND(X) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_random((X), 2, &grp->P, f_rng, p_rng)) - -/* Conditional negation - * Needs grp and a temporary MPI tmp to be defined. */ -#define MPI_ECP_COND_NEG(X, cond) \ - do \ - { \ - unsigned char nonzero = mbedtls_mpi_cmp_int((X), 0) != 0; \ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&tmp, &grp->P, (X))); \ - MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign((X), &tmp, \ - nonzero & cond)); \ - } while (0) - -#define MPI_ECP_NEG(X) MPI_ECP_COND_NEG((X), 1) - -#define MPI_ECP_VALID(X) \ - ((X)->p != NULL) - -#define MPI_ECP_COND_ASSIGN(X, Y, cond) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign((X), (Y), (cond))) - -#define MPI_ECP_COND_SWAP(X, Y, cond) \ - MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_swap((X), (Y), (cond))) - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - -/* - * Computes the right-hand side of the Short Weierstrass equation - * RHS = X^3 + A X + B - */ -static int ecp_sw_rhs(const mbedtls_ecp_group *grp, - mbedtls_mpi *rhs, - const mbedtls_mpi *X) -{ - int ret; - - /* Compute X^3 + A X + B as X (X^2 + A) + B */ - MPI_ECP_SQR(rhs, X); - - /* Special case for A = -3 */ - if (mbedtls_ecp_group_a_is_minus_3(grp)) { - MPI_ECP_SUB_INT(rhs, rhs, 3); - } else { - MPI_ECP_ADD(rhs, rhs, &grp->A); - } - - MPI_ECP_MUL(rhs, rhs, X); - MPI_ECP_ADD(rhs, rhs, &grp->B); - -cleanup: - return ret; -} - -/* - * Derive Y from X and a parity bit - */ -static int mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group *grp, - const mbedtls_mpi *X, - mbedtls_mpi *Y, - int parity_bit) -{ - /* w = y^2 = x^3 + ax + b - * y = sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) - * - * Note: this method for extracting square root does not validate that w - * was indeed a square so this function will return garbage in Y if X - * does not correspond to a point on the curve. - */ - - /* Check prerequisite p = 3 mod 4 */ - if (mbedtls_mpi_get_bit(&grp->P, 0) != 1 || - mbedtls_mpi_get_bit(&grp->P, 1) != 1) { - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } - - int ret; - mbedtls_mpi exp; - mbedtls_mpi_init(&exp); - - /* use Y to store intermediate result, actually w above */ - MBEDTLS_MPI_CHK(ecp_sw_rhs(grp, Y, X)); - - /* w = y^2 */ /* Y contains y^2 intermediate result */ - /* exp = ((p+1)/4) */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&exp, &grp->P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&exp, 2)); - /* sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(Y, Y /*y^2*/, &exp, &grp->P, NULL)); - - /* check parity bit match or else invert Y */ - /* This quick inversion implementation is valid because Y != 0 for all - * Short Weierstrass curves supported by mbedtls, as each supported curve - * has an order that is a large prime, so each supported curve does not - * have any point of order 2, and a point with Y == 0 would be of order 2 */ - if (mbedtls_mpi_get_bit(Y, 0) != parity_bit) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(Y, &grp->P, Y)); - } - -cleanup: - - mbedtls_mpi_free(&exp); - return ret; -} -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -#if defined(MBEDTLS_ECP_C) -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -/* - * For curves in short Weierstrass form, we do all the internal operations in - * Jacobian coordinates. - * - * For multiplication, we'll use a comb method with countermeasures against - * SPA, hence timing attacks. - */ - -/* - * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) - * Cost: 1N := 1I + 3M + 1S - */ -static int ecp_normalize_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt) -{ - if (MPI_ECP_CMP_INT(&pt->Z, 0) == 0) { - return 0; - } - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_normalize_jac(grp, pt); - } -#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi T; - mbedtls_mpi_init(&T); - - MPI_ECP_INV(&T, &pt->Z); /* T <- 1 / Z */ - MPI_ECP_MUL(&pt->Y, &pt->Y, &T); /* Y' <- Y*T = Y / Z */ - MPI_ECP_SQR(&T, &T); /* T <- T^2 = 1 / Z^2 */ - MPI_ECP_MUL(&pt->X, &pt->X, &T); /* X <- X * T = X / Z^2 */ - MPI_ECP_MUL(&pt->Y, &pt->Y, &T); /* Y'' <- Y' * T = Y / Z^3 */ - - MPI_ECP_LSET(&pt->Z, 1); - -cleanup: - - mbedtls_mpi_free(&T); - - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */ -} - -/* - * Normalize jacobian coordinates of an array of (pointers to) points, - * using Montgomery's trick to perform only one inversion mod P. - * (See for example Cohen's "A Course in Computational Algebraic Number - * Theory", Algorithm 10.3.4.) - * - * Warning: fails (returning an error) if one of the points is zero! - * This should never happen, see choice of w in ecp_mul_comb(). - * - * Cost: 1N(t) := 1I + (6t - 3)M + 1S - */ -static int ecp_normalize_jac_many(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *T[], size_t T_size) -{ - if (T_size < 2) { - return ecp_normalize_jac(grp, *T); - } - -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_normalize_jac_many(grp, T, T_size); - } -#endif - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - mbedtls_mpi *c, t; - - if ((c = mbedtls_calloc(T_size, sizeof(mbedtls_mpi))) == NULL) { - return MBEDTLS_ERR_ECP_ALLOC_FAILED; - } - - mbedtls_mpi_init(&t); - - mpi_init_many(c, T_size); - /* - * c[i] = Z_0 * ... * Z_i, i = 0,..,n := T_size-1 - */ - MPI_ECP_MOV(&c[0], &T[0]->Z); - for (i = 1; i < T_size; i++) { - MPI_ECP_MUL(&c[i], &c[i-1], &T[i]->Z); - } - - /* - * c[n] = 1 / (Z_0 * ... * Z_n) mod P - */ - MPI_ECP_INV(&c[T_size-1], &c[T_size-1]); - - for (i = T_size - 1;; i--) { - /* At the start of iteration i (note that i decrements), we have - * - c[j] = Z_0 * .... * Z_j for j < i, - * - c[j] = 1 / (Z_0 * .... * Z_j) for j == i, - * - * This is maintained via - * - c[i-1] <- c[i] * Z_i - * - * We also derive 1/Z_i = c[i] * c[i-1] for i>0 and use that - * to do the actual normalization. For i==0, we already have - * c[0] = 1 / Z_0. - */ - - if (i > 0) { - /* Compute 1/Z_i and establish invariant for the next iteration. */ - MPI_ECP_MUL(&t, &c[i], &c[i-1]); - MPI_ECP_MUL(&c[i-1], &c[i], &T[i]->Z); - } else { - MPI_ECP_MOV(&t, &c[0]); - } - - /* Now t holds 1 / Z_i; normalize as in ecp_normalize_jac() */ - MPI_ECP_MUL(&T[i]->Y, &T[i]->Y, &t); - MPI_ECP_SQR(&t, &t); - MPI_ECP_MUL(&T[i]->X, &T[i]->X, &t); - MPI_ECP_MUL(&T[i]->Y, &T[i]->Y, &t); - - /* - * Post-precessing: reclaim some memory by shrinking coordinates - * - not storing Z (always 1) - * - shrinking other coordinates, but still keeping the same number of - * limbs as P, as otherwise it will too likely be regrown too fast. - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(&T[i]->X, grp->P.n)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(&T[i]->Y, grp->P.n)); - - MPI_ECP_LSET(&T[i]->Z, 1); - - if (i == 0) { - break; - } - } - -cleanup: - - mbedtls_mpi_free(&t); - mpi_free_many(c, T_size); - mbedtls_free(c); - - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) */ -} - -/* - * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. - * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid - */ -static int ecp_safe_invert_jac(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *Q, - unsigned char inv) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi tmp; - mbedtls_mpi_init(&tmp); - - MPI_ECP_COND_NEG(&Q->Y, inv); - -cleanup: - mbedtls_mpi_free(&tmp); - return ret; -} - -/* - * Point doubling R = 2 P, Jacobian coordinates - * - * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 . - * - * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR - * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring. - * - * Standard optimizations are applied when curve parameter A is one of { 0, -3 }. - * - * Cost: 1D := 3M + 4S (A == 0) - * 4M + 4S (A == -3) - * 3M + 6S + 1a otherwise - */ -static int ecp_double_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P, - mbedtls_mpi tmp[4]) -{ -#if defined(MBEDTLS_SELF_TEST) - dbl_count++; -#endif - -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_double_jac(grp, R, P); - } -#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Special case for A = -3 */ - if (mbedtls_ecp_group_a_is_minus_3(grp)) { - /* tmp[0] <- M = 3(X + Z^2)(X - Z^2) */ - MPI_ECP_SQR(&tmp[1], &P->Z); - MPI_ECP_ADD(&tmp[2], &P->X, &tmp[1]); - MPI_ECP_SUB(&tmp[3], &P->X, &tmp[1]); - MPI_ECP_MUL(&tmp[1], &tmp[2], &tmp[3]); - MPI_ECP_MUL_INT(&tmp[0], &tmp[1], 3); - } else { - /* tmp[0] <- M = 3.X^2 + A.Z^4 */ - MPI_ECP_SQR(&tmp[1], &P->X); - MPI_ECP_MUL_INT(&tmp[0], &tmp[1], 3); - - /* Optimize away for "koblitz" curves with A = 0 */ - if (MPI_ECP_CMP_INT(&grp->A, 0) != 0) { - /* M += A.Z^4 */ - MPI_ECP_SQR(&tmp[1], &P->Z); - MPI_ECP_SQR(&tmp[2], &tmp[1]); - MPI_ECP_MUL(&tmp[1], &tmp[2], &grp->A); - MPI_ECP_ADD(&tmp[0], &tmp[0], &tmp[1]); - } - } - - /* tmp[1] <- S = 4.X.Y^2 */ - MPI_ECP_SQR(&tmp[2], &P->Y); - MPI_ECP_SHIFT_L(&tmp[2], 1); - MPI_ECP_MUL(&tmp[1], &P->X, &tmp[2]); - MPI_ECP_SHIFT_L(&tmp[1], 1); - - /* tmp[3] <- U = 8.Y^4 */ - MPI_ECP_SQR(&tmp[3], &tmp[2]); - MPI_ECP_SHIFT_L(&tmp[3], 1); - - /* tmp[2] <- T = M^2 - 2.S */ - MPI_ECP_SQR(&tmp[2], &tmp[0]); - MPI_ECP_SUB(&tmp[2], &tmp[2], &tmp[1]); - MPI_ECP_SUB(&tmp[2], &tmp[2], &tmp[1]); - - /* tmp[1] <- S = M(S - T) - U */ - MPI_ECP_SUB(&tmp[1], &tmp[1], &tmp[2]); - MPI_ECP_MUL(&tmp[1], &tmp[1], &tmp[0]); - MPI_ECP_SUB(&tmp[1], &tmp[1], &tmp[3]); - - /* tmp[3] <- U = 2.Y.Z */ - MPI_ECP_MUL(&tmp[3], &P->Y, &P->Z); - MPI_ECP_SHIFT_L(&tmp[3], 1); - - /* Store results */ - MPI_ECP_MOV(&R->X, &tmp[2]); - MPI_ECP_MOV(&R->Y, &tmp[1]); - MPI_ECP_MOV(&R->Z, &tmp[3]); - -cleanup: - - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */ -} - -/* - * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) - * - * The coordinates of Q must be normalized (= affine), - * but those of P don't need to. R is not normalized. - * - * P,Q,R may alias, but only at the level of EC points: they must be either - * equal as pointers, or disjoint (including the coordinate data buffers). - * Fine-grained aliasing at the level of coordinates is not supported. - * - * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. - * None of these cases can happen as intermediate step in ecp_mul_comb(): - * - at each step, P, Q and R are multiples of the base point, the factor - * being less than its order, so none of them is zero; - * - Q is an odd multiple of the base point, P an even multiple, - * due to the choice of precomputed points in the modified comb method. - * So branches for these cases do not leak secret information. - * - * Cost: 1A := 8M + 3S - */ -static int ecp_add_mixed(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, - mbedtls_mpi tmp[4]) -{ -#if defined(MBEDTLS_SELF_TEST) - add_count++; -#endif - -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_add_mixed(grp, R, P, Q); - } -#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_ADD_MIXED_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* NOTE: Aliasing between input and output is allowed, so one has to make - * sure that at the point X,Y,Z are written, {P,Q}->{X,Y,Z} are no - * longer read from. */ - mbedtls_mpi * const X = &R->X; - mbedtls_mpi * const Y = &R->Y; - mbedtls_mpi * const Z = &R->Z; - - if (!MPI_ECP_VALID(&Q->Z)) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* - * Trivial cases: P == 0 or Q == 0 (case 1) - */ - if (MPI_ECP_CMP_INT(&P->Z, 0) == 0) { - return mbedtls_ecp_copy(R, Q); - } - - if (MPI_ECP_CMP_INT(&Q->Z, 0) == 0) { - return mbedtls_ecp_copy(R, P); - } - - /* - * Make sure Q coordinates are normalized - */ - if (MPI_ECP_CMP_INT(&Q->Z, 1) != 0) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - MPI_ECP_SQR(&tmp[0], &P->Z); - MPI_ECP_MUL(&tmp[1], &tmp[0], &P->Z); - MPI_ECP_MUL(&tmp[0], &tmp[0], &Q->X); - MPI_ECP_MUL(&tmp[1], &tmp[1], &Q->Y); - MPI_ECP_SUB(&tmp[0], &tmp[0], &P->X); - MPI_ECP_SUB(&tmp[1], &tmp[1], &P->Y); - - /* Special cases (2) and (3) */ - if (MPI_ECP_CMP_INT(&tmp[0], 0) == 0) { - if (MPI_ECP_CMP_INT(&tmp[1], 0) == 0) { - ret = ecp_double_jac(grp, R, P, tmp); - goto cleanup; - } else { - ret = mbedtls_ecp_set_zero(R); - goto cleanup; - } - } - - /* {P,Q}->Z no longer used, so OK to write to Z even if there's aliasing. */ - MPI_ECP_MUL(Z, &P->Z, &tmp[0]); - MPI_ECP_SQR(&tmp[2], &tmp[0]); - MPI_ECP_MUL(&tmp[3], &tmp[2], &tmp[0]); - MPI_ECP_MUL(&tmp[2], &tmp[2], &P->X); - - MPI_ECP_MOV(&tmp[0], &tmp[2]); - MPI_ECP_SHIFT_L(&tmp[0], 1); - - /* {P,Q}->X no longer used, so OK to write to X even if there's aliasing. */ - MPI_ECP_SQR(X, &tmp[1]); - MPI_ECP_SUB(X, X, &tmp[0]); - MPI_ECP_SUB(X, X, &tmp[3]); - MPI_ECP_SUB(&tmp[2], &tmp[2], X); - MPI_ECP_MUL(&tmp[2], &tmp[2], &tmp[1]); - MPI_ECP_MUL(&tmp[3], &tmp[3], &P->Y); - /* {P,Q}->Y no longer used, so OK to write to Y even if there's aliasing. */ - MPI_ECP_SUB(Y, &tmp[2], &tmp[3]); - -cleanup: - - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */ -} - -/* - * Randomize jacobian coordinates: - * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l - * This is sort of the reverse operation of ecp_normalize_jac(). - * - * This countermeasure was first suggested in [2]. - */ -static int ecp_randomize_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_randomize_jac(grp, pt, f_rng, p_rng); - } -#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi l; - - mbedtls_mpi_init(&l); - - /* Generate l such that 1 < l < p */ - MPI_ECP_RAND(&l); - - /* Z' = l * Z */ - MPI_ECP_MUL(&pt->Z, &pt->Z, &l); - - /* Y' = l * Y */ - MPI_ECP_MUL(&pt->Y, &pt->Y, &l); - - /* X' = l^2 * X */ - MPI_ECP_SQR(&l, &l); - MPI_ECP_MUL(&pt->X, &pt->X, &l); - - /* Y'' = l^2 * Y' = l^3 * Y */ - MPI_ECP_MUL(&pt->Y, &pt->Y, &l); - -cleanup: - mbedtls_mpi_free(&l); - - if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - } - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */ -} - -/* - * Check and define parameters used by the comb method (see below for details) - */ -#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7 -#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds" -#endif - -/* d = ceil( n / w ) */ -#define COMB_MAX_D (MBEDTLS_ECP_MAX_BITS + 1) / 2 - -/* number of precomputed points */ -#define COMB_MAX_PRE (1 << (MBEDTLS_ECP_WINDOW_SIZE - 1)) - -/* - * Compute the representation of m that will be used with our comb method. - * - * The basic comb method is described in GECC 3.44 for example. We use a - * modified version that provides resistance to SPA by avoiding zero - * digits in the representation as in [3]. We modify the method further by - * requiring that all K_i be odd, which has the small cost that our - * representation uses one more K_i, due to carries, but saves on the size of - * the precomputed table. - * - * Summary of the comb method and its modifications: - * - * - The goal is to compute m*P for some w*d-bit integer m. - * - * - The basic comb method splits m into the w-bit integers - * x[0] .. x[d-1] where x[i] consists of the bits in m whose - * index has residue i modulo d, and computes m * P as - * S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where - * S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P. - * - * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by - * .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] .., - * thereby successively converting it into a form where all summands - * are nonzero, at the cost of negative summands. This is the basic idea of [3]. - * - * - More generally, even if x[i+1] != 0, we can first transform the sum as - * .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] .., - * and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]]. - * Performing and iterating this procedure for those x[i] that are even - * (keeping track of carry), we can transform the original sum into one of the form - * S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]] - * with all x'[i] odd. It is therefore only necessary to know S at odd indices, - * which is why we are only computing half of it in the first place in - * ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb. - * - * - For the sake of compactness, only the seven low-order bits of x[i] - * are used to represent its absolute value (K_i in the paper), and the msb - * of x[i] encodes the sign (s_i in the paper): it is set if and only if - * if s_i == -1; - * - * Calling conventions: - * - x is an array of size d + 1 - * - w is the size, ie number of teeth, of the comb, and must be between - * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE) - * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d - * (the result will be incorrect if these assumptions are not satisfied) - */ -static void ecp_comb_recode_core(unsigned char x[], size_t d, - unsigned char w, const mbedtls_mpi *m) -{ - size_t i, j; - unsigned char c, cc, adjust; - - memset(x, 0, d+1); - - /* First get the classical comb values (except for x_d = 0) */ - for (i = 0; i < d; i++) { - for (j = 0; j < w; j++) { - x[i] |= mbedtls_mpi_get_bit(m, i + d * j) << j; - } - } - - /* Now make sure x_1 .. x_d are odd */ - c = 0; - for (i = 1; i <= d; i++) { - /* Add carry and update it */ - cc = x[i] & c; - x[i] = x[i] ^ c; - c = cc; - - /* Adjust if needed, avoiding branches */ - adjust = 1 - (x[i] & 0x01); - c |= x[i] & (x[i-1] * adjust); - x[i] = x[i] ^ (x[i-1] * adjust); - x[i-1] |= adjust << 7; - } -} - -/* - * Precompute points for the adapted comb method - * - * Assumption: T must be able to hold 2^{w - 1} elements. - * - * Operation: If i = i_{w-1} ... i_1 is the binary representation of i, - * sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P. - * - * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) - * - * Note: Even comb values (those where P would be omitted from the - * sum defining T[i] above) are not needed in our adaption - * the comb method. See ecp_comb_recode_core(). - * - * This function currently works in four steps: - * (1) [dbl] Computation of intermediate T[i] for 2-power values of i - * (2) [norm_dbl] Normalization of coordinates of these T[i] - * (3) [add] Computation of all T[i] - * (4) [norm_add] Normalization of all T[i] - * - * Step 1 can be interrupted but not the others; together with the final - * coordinate normalization they are the largest steps done at once, depending - * on the window size. Here are operation counts for P-256: - * - * step (2) (3) (4) - * w = 5 142 165 208 - * w = 4 136 77 160 - * w = 3 130 33 136 - * w = 2 124 11 124 - * - * So if ECC operations are blocking for too long even with a low max_ops - * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order - * to minimize maximum blocking time. - */ -static int ecp_precompute_comb(const mbedtls_ecp_group *grp, - mbedtls_ecp_point T[], const mbedtls_ecp_point *P, - unsigned char w, size_t d, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char i; - size_t j = 0; - const unsigned char T_size = 1U << (w - 1); - mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1] = { NULL }; - - mbedtls_mpi tmp[4]; - - mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - if (rs_ctx->rsm->state == ecp_rsm_pre_dbl) { - goto dbl; - } - if (rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl) { - goto norm_dbl; - } - if (rs_ctx->rsm->state == ecp_rsm_pre_add) { - goto add; - } - if (rs_ctx->rsm->state == ecp_rsm_pre_norm_add) { - goto norm_add; - } - } -#else - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - rs_ctx->rsm->state = ecp_rsm_pre_dbl; - - /* initial state for the loop */ - rs_ctx->rsm->i = 0; - } - -dbl: -#endif - /* - * Set T[0] = P and - * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) - */ - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(&T[0], P)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0) { - j = rs_ctx->rsm->i; - } else -#endif - j = 0; - - for (; j < d * (w - 1); j++) { - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_DBL); - - i = 1U << (j / d); - cur = T + i; - - if (j % d == 0) { - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(cur, T + (i >> 1))); - } - - MBEDTLS_MPI_CHK(ecp_double_jac(grp, cur, cur, tmp)); - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl; - } - -norm_dbl: -#endif - /* - * Normalize current elements in T to allow them to be used in - * ecp_add_mixed() below, which requires one normalized input. - * - * As T has holes, use an auxiliary array of pointers to elements in T. - * - */ - j = 0; - for (i = 1; i < T_size; i <<= 1) { - TT[j++] = T + i; - } - - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV + 6 * j - 2); - - MBEDTLS_MPI_CHK(ecp_normalize_jac_many(grp, TT, j)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - rs_ctx->rsm->state = ecp_rsm_pre_add; - } - -add: -#endif - /* - * Compute the remaining ones using the minimal number of additions - * Be careful to update T[2^l] only after using it! - */ - MBEDTLS_ECP_BUDGET((T_size - 1) * MBEDTLS_ECP_OPS_ADD); - - for (i = 1; i < T_size; i <<= 1) { - j = i; - while (j--) { - MBEDTLS_MPI_CHK(ecp_add_mixed(grp, &T[i + j], &T[j], &T[i], tmp)); - } - } - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - rs_ctx->rsm->state = ecp_rsm_pre_norm_add; - } - -norm_add: -#endif - /* - * Normalize final elements in T. Even though there are no holes now, we - * still need the auxiliary array for homogeneity with the previous - * call. Also, skip T[0] which is already normalised, being a copy of P. - */ - for (j = 0; j + 1 < T_size; j++) { - TT[j] = T + j + 1; - } - - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV + 6 * j - 2); - - MBEDTLS_MPI_CHK(ecp_normalize_jac_many(grp, TT, j)); - - /* Free Z coordinate (=1 after normalization) to save RAM. - * This makes T[i] invalid as mbedtls_ecp_points, but this is OK - * since from this point onwards, they are only accessed indirectly - * via the getter function ecp_select_comb() which does set the - * target's Z coordinate to 1. */ - for (i = 0; i < T_size; i++) { - mbedtls_mpi_free(&T[i].Z); - } - -cleanup: - - mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - if (rs_ctx->rsm->state == ecp_rsm_pre_dbl) { - rs_ctx->rsm->i = j; - } - } -#endif - - return ret; -} - -/* - * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] - * - * See ecp_comb_recode_core() for background - */ -static int ecp_select_comb(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, - unsigned char i) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char ii, j; - - /* Ignore the "sign" bit and scale down */ - ii = (i & 0x7Fu) >> 1; - - /* Read the whole table to thwart cache-based timing attacks */ - for (j = 0; j < T_size; j++) { - MPI_ECP_COND_ASSIGN(&R->X, &T[j].X, j == ii); - MPI_ECP_COND_ASSIGN(&R->Y, &T[j].Y, j == ii); - } - - /* Safely invert result if i is "negative" */ - MBEDTLS_MPI_CHK(ecp_safe_invert_jac(grp, R, i >> 7)); - - MPI_ECP_LSET(&R->Z, 1); - -cleanup: - return ret; -} - -/* - * Core multiplication algorithm for the (modified) comb method. - * This part is actually common with the basic comb method (GECC 3.44) - * - * Cost: d A + d D + 1 R - */ -static int ecp_mul_comb_core(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point T[], unsigned char T_size, - const unsigned char x[], size_t d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point Txi; - mbedtls_mpi tmp[4]; - size_t i; - - mbedtls_ecp_point_init(&Txi); - mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - -#if !defined(MBEDTLS_ECP_RESTARTABLE) - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL && - rs_ctx->rsm->state != ecp_rsm_comb_core) { - rs_ctx->rsm->i = 0; - rs_ctx->rsm->state = ecp_rsm_comb_core; - } - - /* new 'if' instead of nested for the sake of the 'else' branch */ - if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0) { - /* restore current index (R already pointing to rs_ctx->rsm->R) */ - i = rs_ctx->rsm->i; - } else -#endif - { - /* Start with a non-zero point and randomize its coordinates */ - i = d; - MBEDTLS_MPI_CHK(ecp_select_comb(grp, R, T, T_size, x[i])); - if (f_rng != 0) { - MBEDTLS_MPI_CHK(ecp_randomize_jac(grp, R, f_rng, p_rng)); - } - } - - while (i != 0) { - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD); - --i; - - MBEDTLS_MPI_CHK(ecp_double_jac(grp, R, R, tmp)); - MBEDTLS_MPI_CHK(ecp_select_comb(grp, &Txi, T, T_size, x[i])); - MBEDTLS_MPI_CHK(ecp_add_mixed(grp, R, R, &Txi, tmp)); - } - -cleanup: - - mbedtls_ecp_point_free(&Txi); - mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL && - ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - rs_ctx->rsm->i = i; - /* no need to save R, already pointing to rs_ctx->rsm->R */ - } -#endif - - return ret; -} - -/* - * Recode the scalar to get constant-time comb multiplication - * - * As the actual scalar recoding needs an odd scalar as a starting point, - * this wrapper ensures that by replacing m by N - m if necessary, and - * informs the caller that the result of multiplication will be negated. - * - * This works because we only support large prime order for Short Weierstrass - * curves, so N is always odd hence either m or N - m is. - * - * See ecp_comb_recode_core() for background. - */ -static int ecp_comb_recode_scalar(const mbedtls_ecp_group *grp, - const mbedtls_mpi *m, - unsigned char k[COMB_MAX_D + 1], - size_t d, - unsigned char w, - unsigned char *parity_trick) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi M, mm; - - mbedtls_mpi_init(&M); - mbedtls_mpi_init(&mm); - - /* N is always odd (see above), just make extra sure */ - if (mbedtls_mpi_get_bit(&grp->N, 0) != 1) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* do we need the parity trick? */ - *parity_trick = (mbedtls_mpi_get_bit(m, 0) == 0); - - /* execute parity fix in constant time */ - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&M, m)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&mm, &grp->N, m)); - MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(&M, &mm, *parity_trick)); - - /* actual scalar recoding */ - ecp_comb_recode_core(k, d, w, &M); - -cleanup: - mbedtls_mpi_free(&mm); - mbedtls_mpi_free(&M); - - return ret; -} - -/* - * Perform comb multiplication (for short Weierstrass curves) - * once the auxiliary table has been pre-computed. - * - * Scalar recoding may use a parity trick that makes us compute -m * P, - * if that is the case we'll need to recover m * P at the end. - */ -static int ecp_mul_comb_after_precomp(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - const mbedtls_mpi *m, - const mbedtls_ecp_point *T, - unsigned char T_size, - unsigned char w, - size_t d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char parity_trick; - unsigned char k[COMB_MAX_D + 1]; - mbedtls_ecp_point *RR = R; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - RR = &rs_ctx->rsm->R; - - if (rs_ctx->rsm->state == ecp_rsm_final_norm) { - goto final_norm; - } - } -#endif - - MBEDTLS_MPI_CHK(ecp_comb_recode_scalar(grp, m, k, d, w, - &parity_trick)); - MBEDTLS_MPI_CHK(ecp_mul_comb_core(grp, RR, T, T_size, k, d, - f_rng, p_rng, rs_ctx)); - MBEDTLS_MPI_CHK(ecp_safe_invert_jac(grp, RR, parity_trick)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - rs_ctx->rsm->state = ecp_rsm_final_norm; - } - -final_norm: - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV); -#endif - MBEDTLS_MPI_CHK(ecp_normalize_jac(grp, RR)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL) { - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, RR)); - } -#endif - -cleanup: - return ret; -} - -/* - * Pick window size based on curve size and whether we optimize for base point - */ -static unsigned char ecp_pick_window_size(const mbedtls_ecp_group *grp, - unsigned char p_eq_g) -{ - unsigned char w; - - /* - * Minimize the number of multiplications, that is minimize - * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) - * (see costs of the various parts, with 1S = 1M) - */ - w = grp->nbits >= 384 ? 5 : 4; - - /* - * If P == G, pre-compute a bit more, since this may be re-used later. - * Just adding one avoids upping the cost of the first mul too much, - * and the memory cost too. - */ - if (p_eq_g) { - w++; - } - - /* - * If static comb table may not be used (!p_eq_g) or static comb table does - * not exists, make sure w is within bounds. - * (The last test is useful only for very small curves in the test suite.) - * - * The user reduces MBEDTLS_ECP_WINDOW_SIZE does not changes the size of - * static comb table, because the size of static comb table is fixed when - * it is generated. - */ -#if (MBEDTLS_ECP_WINDOW_SIZE < 6) - if ((!p_eq_g || !ecp_group_is_static_comb_table(grp)) && w > MBEDTLS_ECP_WINDOW_SIZE) { - w = MBEDTLS_ECP_WINDOW_SIZE; - } -#endif - if (w >= grp->nbits) { - w = 2; - } - - return w; -} - -/* - * Multiplication using the comb method - for curves in short Weierstrass form - * - * This function is mainly responsible for administrative work: - * - managing the restart context if enabled - * - managing the table of precomputed points (passed between the below two - * functions): allocation, computation, ownership transfer, freeing. - * - * It delegates the actual arithmetic work to: - * ecp_precompute_comb() and ecp_mul_comb_with_precomp() - * - * See comments on ecp_comb_recode_core() regarding the computation strategy. - */ -static int ecp_mul_comb(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char w, p_eq_g, i; - size_t d; - unsigned char T_size = 0, T_ok = 0; - mbedtls_ecp_point *T = NULL; - - ECP_RS_ENTER(rsm); - - /* Is P the base point ? */ -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 - p_eq_g = (MPI_ECP_CMP(&P->Y, &grp->G.Y) == 0 && - MPI_ECP_CMP(&P->X, &grp->G.X) == 0); -#else - p_eq_g = 0; -#endif - - /* Pick window size and deduce related sizes */ - w = ecp_pick_window_size(grp, p_eq_g); - T_size = 1U << (w - 1); - d = (grp->nbits + w - 1) / w; - - /* Pre-computed table: do we have it already for the base point? */ - if (p_eq_g && grp->T != NULL) { - /* second pointer to the same table, will be deleted on exit */ - T = grp->T; - T_ok = 1; - } else -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* Pre-computed table: do we have one in progress? complete? */ - if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL) { - /* transfer ownership of T from rsm to local function */ - T = rs_ctx->rsm->T; - rs_ctx->rsm->T = NULL; - rs_ctx->rsm->T_size = 0; - - /* This effectively jumps to the call to mul_comb_after_precomp() */ - T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core; - } else -#endif - /* Allocate table if we didn't have any */ - { - T = mbedtls_calloc(T_size, sizeof(mbedtls_ecp_point)); - if (T == NULL) { - ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; - goto cleanup; - } - - for (i = 0; i < T_size; i++) { - mbedtls_ecp_point_init(&T[i]); - } - - T_ok = 0; - } - - /* Compute table (or finish computing it) if not done already */ - if (!T_ok) { - MBEDTLS_MPI_CHK(ecp_precompute_comb(grp, T, P, w, d, rs_ctx)); - - if (p_eq_g) { - /* almost transfer ownership of T to the group, but keep a copy of - * the pointer to use for calling the next function more easily */ - grp->T = T; - grp->T_size = T_size; - } - } - - /* Actual comb multiplication using precomputed points */ - MBEDTLS_MPI_CHK(ecp_mul_comb_after_precomp(grp, R, m, - T, T_size, w, d, - f_rng, p_rng, rs_ctx)); - -cleanup: - - /* does T belong to the group? */ - if (T == grp->T) { - T = NULL; - } - - /* does T belong to the restart context? */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL) { - /* transfer ownership of T from local function to rsm */ - rs_ctx->rsm->T_size = T_size; - rs_ctx->rsm->T = T; - T = NULL; - } -#endif - - /* did T belong to us? then let's destroy it! */ - if (T != NULL) { - for (i = 0; i < T_size; i++) { - mbedtls_ecp_point_free(&T[i]); - } - mbedtls_free(T); - } - - /* prevent caller from using invalid value */ - int should_free_R = (ret != 0); -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* don't free R while in progress in case R == P */ - if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - should_free_R = 0; - } -#endif - if (should_free_R) { - mbedtls_ecp_point_free(R); - } - - ECP_RS_LEAVE(rsm); - - return ret; -} - -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) -/* - * For Montgomery curves, we do all the internal arithmetic in projective - * coordinates. Import/export of points uses only the x coordinates, which is - * internally represented as X / Z. - * - * For scalar multiplication, we'll use a Montgomery ladder. - */ - -/* - * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 - * Cost: 1M + 1I - */ -static int ecp_normalize_mxz(const mbedtls_ecp_group *grp, mbedtls_ecp_point *P) -{ -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_normalize_mxz(grp, P); - } -#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MPI_ECP_INV(&P->Z, &P->Z); - MPI_ECP_MUL(&P->X, &P->X, &P->Z); - MPI_ECP_LSET(&P->Z, 1); - -cleanup: - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) */ -} - -/* - * Randomize projective x/z coordinates: - * (X, Z) -> (l X, l Z) for random l - * This is sort of the reverse operation of ecp_normalize_mxz(). - * - * This countermeasure was first suggested in [2]. - * Cost: 2M - */ -static int ecp_randomize_mxz(const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_randomize_mxz(grp, P, f_rng, p_rng); - } -#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi l; - mbedtls_mpi_init(&l); - - /* Generate l such that 1 < l < p */ - MPI_ECP_RAND(&l); - - MPI_ECP_MUL(&P->X, &P->X, &l); - MPI_ECP_MUL(&P->Z, &P->Z, &l); - -cleanup: - mbedtls_mpi_free(&l); - - if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { - ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; - } - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */ -} - -/* - * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), - * for Montgomery curves in x/z coordinates. - * - * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 - * with - * d = X1 - * P = (X2, Z2) - * Q = (X3, Z3) - * R = (X4, Z4) - * S = (X5, Z5) - * and eliminating temporary variables tO, ..., t4. - * - * Cost: 5M + 4S - */ -static int ecp_double_add_mxz(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, mbedtls_ecp_point *S, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, - const mbedtls_mpi *d, - mbedtls_mpi T[4]) -{ -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) - if (mbedtls_internal_ecp_grp_capable(grp)) { - return mbedtls_internal_ecp_double_add_mxz(grp, R, S, P, Q, d); - } -#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ - -#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MPI_ECP_ADD(&T[0], &P->X, &P->Z); /* Pp := PX + PZ */ - MPI_ECP_SUB(&T[1], &P->X, &P->Z); /* Pm := PX - PZ */ - MPI_ECP_ADD(&T[2], &Q->X, &Q->Z); /* Qp := QX + XZ */ - MPI_ECP_SUB(&T[3], &Q->X, &Q->Z); /* Qm := QX - QZ */ - MPI_ECP_MUL(&T[3], &T[3], &T[0]); /* Qm * Pp */ - MPI_ECP_MUL(&T[2], &T[2], &T[1]); /* Qp * Pm */ - MPI_ECP_SQR(&T[0], &T[0]); /* Pp^2 */ - MPI_ECP_SQR(&T[1], &T[1]); /* Pm^2 */ - MPI_ECP_MUL(&R->X, &T[0], &T[1]); /* Pp^2 * Pm^2 */ - MPI_ECP_SUB(&T[0], &T[0], &T[1]); /* Pp^2 - Pm^2 */ - MPI_ECP_MUL(&R->Z, &grp->A, &T[0]); /* A * (Pp^2 - Pm^2) */ - MPI_ECP_ADD(&R->Z, &T[1], &R->Z); /* [ A * (Pp^2-Pm^2) ] + Pm^2 */ - MPI_ECP_ADD(&S->X, &T[3], &T[2]); /* Qm*Pp + Qp*Pm */ - MPI_ECP_SQR(&S->X, &S->X); /* (Qm*Pp + Qp*Pm)^2 */ - MPI_ECP_SUB(&S->Z, &T[3], &T[2]); /* Qm*Pp - Qp*Pm */ - MPI_ECP_SQR(&S->Z, &S->Z); /* (Qm*Pp - Qp*Pm)^2 */ - MPI_ECP_MUL(&S->Z, d, &S->Z); /* d * ( Qm*Pp - Qp*Pm )^2 */ - MPI_ECP_MUL(&R->Z, &T[0], &R->Z); /* [A*(Pp^2-Pm^2)+Pm^2]*(Pp^2-Pm^2) */ - -cleanup: - - return ret; -#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */ -} - -/* - * Multiplication with Montgomery ladder in x/z coordinates, - * for curves in Montgomery form - */ -static int ecp_mul_mxz(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - unsigned char b; - mbedtls_ecp_point RP; - mbedtls_mpi PX; - mbedtls_mpi tmp[4]; - mbedtls_ecp_point_init(&RP); mbedtls_mpi_init(&PX); - - mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - - if (f_rng == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* Save PX and read from P before writing to R, in case P == R */ - MPI_ECP_MOV(&PX, &P->X); - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(&RP, P)); - - /* Set R to zero in modified x/z coordinates */ - MPI_ECP_LSET(&R->X, 1); - MPI_ECP_LSET(&R->Z, 0); - mbedtls_mpi_free(&R->Y); - - /* RP.X might be slightly larger than P, so reduce it */ - MOD_ADD(&RP.X); - - /* Randomize coordinates of the starting point */ - MBEDTLS_MPI_CHK(ecp_randomize_mxz(grp, &RP, f_rng, p_rng)); - - /* Loop invariant: R = result so far, RP = R + P */ - i = grp->nbits + 1; /* one past the (zero-based) required msb for private keys */ - while (i-- > 0) { - b = mbedtls_mpi_get_bit(m, i); - /* - * if (b) R = 2R + P else R = 2R, - * which is: - * if (b) double_add( RP, R, RP, R ) - * else double_add( R, RP, R, RP ) - * but using safe conditional swaps to avoid leaks - */ - MPI_ECP_COND_SWAP(&R->X, &RP.X, b); - MPI_ECP_COND_SWAP(&R->Z, &RP.Z, b); - MBEDTLS_MPI_CHK(ecp_double_add_mxz(grp, R, &RP, R, &RP, &PX, tmp)); - MPI_ECP_COND_SWAP(&R->X, &RP.X, b); - MPI_ECP_COND_SWAP(&R->Z, &RP.Z, b); - } - - MBEDTLS_MPI_CHK(ecp_normalize_mxz(grp, R)); - -cleanup: - mbedtls_ecp_point_free(&RP); mbedtls_mpi_free(&PX); - - mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - return ret; -} - -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - -/* - * Restartable multiplication R = m * P - * - * This internal function can be called without an RNG in case where we know - * the inputs are not sensitive. - */ -static int ecp_mul_restartable_internal(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - -#if defined(MBEDTLS_ECP_RESTARTABLE) - /* reset ops count for this call if top-level */ - if (rs_ctx != NULL && rs_ctx->depth++ == 0) { - rs_ctx->ops_done = 0; - } -#else - (void) rs_ctx; -#endif - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if ((is_grp_capable = mbedtls_internal_ecp_grp_capable(grp))) { - MBEDTLS_MPI_CHK(mbedtls_internal_ecp_init(grp)); - } -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - - int restarting = 0; -#if defined(MBEDTLS_ECP_RESTARTABLE) - restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL); -#endif - /* skip argument check when restarting */ - if (!restarting) { - /* check_privkey is free */ - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_CHK); - - /* Common sanity checks */ - MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(grp, m)); - MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); - } - - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - MBEDTLS_MPI_CHK(ecp_mul_mxz(grp, R, m, P, f_rng, p_rng)); - } -#endif -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - MBEDTLS_MPI_CHK(ecp_mul_comb(grp, R, m, P, f_rng, p_rng, rs_ctx)); - } -#endif - -cleanup: - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if (is_grp_capable) { - mbedtls_internal_ecp_free(grp); - } -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL) { - rs_ctx->depth--; - } -#endif - - return ret; -} - -/* - * Restartable multiplication R = m * P - */ -int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - if (f_rng == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return ecp_mul_restartable_internal(grp, R, m, P, f_rng, p_rng, rs_ctx); -} - -/* - * Multiplication R = m * P - */ -int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - return mbedtls_ecp_mul_restartable(grp, R, m, P, f_rng, p_rng, NULL); -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -/* - * Check that an affine point is valid as a public key, - * short weierstrass curves (SEC1 3.2.3.1) - */ -static int ecp_check_pubkey_sw(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi YY, RHS; - - /* pt coordinates must be normalized for our checks */ - if (mbedtls_mpi_cmp_int(&pt->X, 0) < 0 || - mbedtls_mpi_cmp_int(&pt->Y, 0) < 0 || - mbedtls_mpi_cmp_mpi(&pt->X, &grp->P) >= 0 || - mbedtls_mpi_cmp_mpi(&pt->Y, &grp->P) >= 0) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - mbedtls_mpi_init(&YY); mbedtls_mpi_init(&RHS); - - /* - * YY = Y^2 - * RHS = X^3 + A X + B - */ - MPI_ECP_SQR(&YY, &pt->Y); - MBEDTLS_MPI_CHK(ecp_sw_rhs(grp, &RHS, &pt->X)); - - if (MPI_ECP_CMP(&YY, &RHS) != 0) { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - } - -cleanup: - - mbedtls_mpi_free(&YY); mbedtls_mpi_free(&RHS); - - return ret; -} -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -#if defined(MBEDTLS_ECP_C) -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -/* - * R = m * P with shortcuts for m == 0, m == 1 and m == -1 - * NOT constant-time - ONLY for short Weierstrass! - */ -static int mbedtls_ecp_mul_shortcuts(mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - const mbedtls_mpi *m, - const mbedtls_ecp_point *P, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi tmp; - mbedtls_mpi_init(&tmp); - - if (mbedtls_mpi_cmp_int(m, 0) == 0) { - MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); - MBEDTLS_MPI_CHK(mbedtls_ecp_set_zero(R)); - } else if (mbedtls_mpi_cmp_int(m, 1) == 0) { - MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P)); - } else if (mbedtls_mpi_cmp_int(m, -1) == 0) { - MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P)); - MPI_ECP_NEG(&R->Y); - } else { - MBEDTLS_MPI_CHK(ecp_mul_restartable_internal(grp, R, m, P, - NULL, NULL, rs_ctx)); - } - -cleanup: - mbedtls_mpi_free(&tmp); - - return ret; -} - -/* - * Restartable linear combination - * NOT constant-time - */ -int mbedtls_ecp_muladd_restartable( - mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q, - mbedtls_ecp_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point mP; - mbedtls_ecp_point *pmP = &mP; - mbedtls_ecp_point *pR = R; - mbedtls_mpi tmp[4]; -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - char is_grp_capable = 0; -#endif - if (mbedtls_ecp_get_type(grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } - - mbedtls_ecp_point_init(&mP); - mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - - ECP_RS_ENTER(ma); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->ma != NULL) { - /* redirect intermediate results to restart context */ - pmP = &rs_ctx->ma->mP; - pR = &rs_ctx->ma->R; - - /* jump to next operation */ - if (rs_ctx->ma->state == ecp_rsma_mul2) { - goto mul2; - } - if (rs_ctx->ma->state == ecp_rsma_add) { - goto add; - } - if (rs_ctx->ma->state == ecp_rsma_norm) { - goto norm; - } - } -#endif /* MBEDTLS_ECP_RESTARTABLE */ - - MBEDTLS_MPI_CHK(mbedtls_ecp_mul_shortcuts(grp, pmP, m, P, rs_ctx)); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->ma != NULL) { - rs_ctx->ma->state = ecp_rsma_mul2; - } - -mul2: -#endif - MBEDTLS_MPI_CHK(mbedtls_ecp_mul_shortcuts(grp, pR, n, Q, rs_ctx)); - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if ((is_grp_capable = mbedtls_internal_ecp_grp_capable(grp))) { - MBEDTLS_MPI_CHK(mbedtls_internal_ecp_init(grp)); - } -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->ma != NULL) { - rs_ctx->ma->state = ecp_rsma_add; - } - -add: -#endif - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_ADD); - MBEDTLS_MPI_CHK(ecp_add_mixed(grp, pR, pmP, pR, tmp)); -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->ma != NULL) { - rs_ctx->ma->state = ecp_rsma_norm; - } - -norm: -#endif - MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV); - MBEDTLS_MPI_CHK(ecp_normalize_jac(grp, pR)); - -#if defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && rs_ctx->ma != NULL) { - MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, pR)); - } -#endif - -cleanup: - - mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - if (is_grp_capable) { - mbedtls_internal_ecp_free(grp); - } -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - - mbedtls_ecp_point_free(&mP); - - ECP_RS_LEAVE(ma); - - return ret; -} - -/* - * Linear combination - * NOT constant-time - */ -int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_mpi *m, const mbedtls_ecp_point *P, - const mbedtls_mpi *n, const mbedtls_ecp_point *Q) -{ - return mbedtls_ecp_muladd_restartable(grp, R, m, P, n, Q, NULL); -} -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } -#define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) -/* - * Constants for the two points other than 0, 1, -1 (mod p) in - * https://cr.yp.to/ecdh.html#validate - * See ecp_check_pubkey_x25519(). - */ -static const mbedtls_mpi_uint x25519_bad_point_1[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a), - MBEDTLS_BYTES_TO_T_UINT_8(0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00), -}; -static const mbedtls_mpi_uint x25519_bad_point_2[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57), -}; -static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY( - x25519_bad_point_1); -static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY( - x25519_bad_point_2); -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -/* - * Check that the input point is not one of the low-order points. - * This is recommended by the "May the Fourth" paper: - * https://eprint.iacr.org/2017/806.pdf - * Those points are never sent by an honest peer. - */ -static int ecp_check_bad_points_mx(const mbedtls_mpi *X, const mbedtls_mpi *P, - const mbedtls_ecp_group_id grp_id) -{ - int ret; - mbedtls_mpi XmP; - - mbedtls_mpi_init(&XmP); - - /* Reduce X mod P so that we only need to check values less than P. - * We know X < 2^256 so we can proceed by subtraction. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&XmP, X)); - while (mbedtls_mpi_cmp_mpi(&XmP, P) >= 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&XmP, &XmP, P)); - } - - /* Check against the known bad values that are less than P. For Curve448 - * these are 0, 1 and -1. For Curve25519 we check the values less than P - * from the following list: https://cr.yp.to/ecdh.html#validate */ - if (mbedtls_mpi_cmp_int(&XmP, 1) <= 0) { /* takes care of 0 and 1 */ - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - if (grp_id == MBEDTLS_ECP_DP_CURVE25519) { - if (mbedtls_mpi_cmp_mpi(&XmP, &ecp_x25519_bad_point_1) == 0) { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - - if (mbedtls_mpi_cmp_mpi(&XmP, &ecp_x25519_bad_point_2) == 0) { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - } -#else - (void) grp_id; -#endif - - /* Final check: check if XmP + 1 is P (final because it changes XmP!) */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&XmP, &XmP, 1)); - if (mbedtls_mpi_cmp_mpi(&XmP, P) == 0) { - ret = MBEDTLS_ERR_ECP_INVALID_KEY; - goto cleanup; - } - - ret = 0; - -cleanup: - mbedtls_mpi_free(&XmP); - - return ret; -} - -/* - * Check validity of a public key for Montgomery curves with x-only schemes - */ -static int ecp_check_pubkey_mx(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt) -{ - /* [Curve25519 p. 5] Just check X is the correct number of bytes */ - /* Allow any public value, if it's too big then we'll just reduce it mod p - * (RFC 7748 sec. 5 para. 3). */ - if (mbedtls_mpi_size(&pt->X) > (grp->nbits + 7) / 8) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - /* Implicit in all standards (as they don't consider negative numbers): - * X must be non-negative. This is normally ensured by the way it's - * encoded for transmission, but let's be extra sure. */ - if (mbedtls_mpi_cmp_int(&pt->X, 0) < 0) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - return ecp_check_bad_points_mx(&pt->X, &grp->P, grp->id); -} -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - -/* - * Check that a point is valid as a public key - */ -int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp, - const mbedtls_ecp_point *pt) -{ - /* Must use affine coordinates */ - if (mbedtls_mpi_cmp_int(&pt->Z, 1) != 0) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - return ecp_check_pubkey_mx(grp, pt); - } -#endif -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - return ecp_check_pubkey_sw(grp, pt); - } -#endif - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -} - -/* - * Check that an mbedtls_mpi is valid as a private key - */ -int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp, - const mbedtls_mpi *d) -{ -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - /* see RFC 7748 sec. 5 para. 5 */ - if (mbedtls_mpi_get_bit(d, 0) != 0 || - mbedtls_mpi_get_bit(d, 1) != 0 || - mbedtls_mpi_bitlen(d) != grp->nbits + 1) { /* mbedtls_mpi_bitlen is one-based! */ - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - /* see [Curve25519] page 5 */ - if (grp->nbits == 254 && mbedtls_mpi_get_bit(d, 2) != 0) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - return 0; - } -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - /* see SEC1 3.2 */ - if (mbedtls_mpi_cmp_int(d, 1) < 0 || - mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } else { - return 0; - } - } -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -} - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_gen_privkey_mx(size_t high_bit, - mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - size_t n_random_bytes = high_bit / 8 + 1; - - /* [Curve25519] page 5 */ - /* Generate a (high_bit+1)-bit random number by generating just enough - * random bytes, then shifting out extra bits from the top (necessary - * when (high_bit+1) is not a multiple of 8). */ - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(d, n_random_bytes, - f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(d, 8 * n_random_bytes - high_bit - 1)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, high_bit, 1)); - - /* Make sure the last two bits are unset for Curve448, three bits for - Curve25519 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 0, 0)); - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 1, 0)); - if (high_bit == 254) { - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 2, 0)); - } - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -static int mbedtls_ecp_gen_privkey_sw( - const mbedtls_mpi *N, mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = mbedtls_mpi_random(d, 1, N, f_rng, p_rng); - switch (ret) { - case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: - return MBEDTLS_ERR_ECP_RANDOM_FAILED; - default: - return ret; - } -} -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -/* - * Generate a private key - */ -int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp, - mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - return mbedtls_ecp_gen_privkey_mx(grp->nbits, d, f_rng, p_rng); - } -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - return mbedtls_ecp_gen_privkey_sw(&grp->N, d, f_rng, p_rng); - } -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; -} - -#if defined(MBEDTLS_ECP_C) -/* - * Generate a keypair with configurable base point - */ -int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, Q, d, G, f_rng, p_rng)); - -cleanup: - return ret; -} - -/* - * Generate key pair, wrapper for conventional base point - */ -int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - return mbedtls_ecp_gen_keypair_base(grp, &grp->G, d, Q, f_rng, p_rng); -} - -/* - * Generate a keypair, prettier wrapper - */ -int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) { - return ret; - } - - return mbedtls_ecp_gen_keypair(&key->grp, &key->d, &key->Q, f_rng, p_rng); -} -#endif /* MBEDTLS_ECP_C */ - -int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id, - mbedtls_ecp_keypair *key, - const mbedtls_ecp_point *Q) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (key->grp.id == MBEDTLS_ECP_DP_NONE) { - /* Group not set yet */ - if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) { - return ret; - } - } else if (key->grp.id != grp_id) { - /* Group mismatch */ - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - return mbedtls_ecp_copy(&key->Q, Q); -} - - -#define ECP_CURVE25519_KEY_SIZE 32 -#define ECP_CURVE448_KEY_SIZE 56 -/* - * Read a private key. - */ -int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - const unsigned char *buf, size_t buflen) -{ - int ret = 0; - - if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) { - return ret; - } - - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - /* - * Mask the key as mandated by RFC7748 for Curve25519 and Curve448. - */ - if (grp_id == MBEDTLS_ECP_DP_CURVE25519) { - if (buflen != ECP_CURVE25519_KEY_SIZE) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&key->d, buf, buflen)); - - /* Set the three least significant bits to 0 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 0, 0)); - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 1, 0)); - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 2, 0)); - - /* Set the most significant bit to 0 */ - MBEDTLS_MPI_CHK( - mbedtls_mpi_set_bit(&key->d, - ECP_CURVE25519_KEY_SIZE * 8 - 1, 0) - ); - - /* Set the second most significant bit to 1 */ - MBEDTLS_MPI_CHK( - mbedtls_mpi_set_bit(&key->d, - ECP_CURVE25519_KEY_SIZE * 8 - 2, 1) - ); - } else if (grp_id == MBEDTLS_ECP_DP_CURVE448) { - if (buflen != ECP_CURVE448_KEY_SIZE) { - return MBEDTLS_ERR_ECP_INVALID_KEY; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&key->d, buf, buflen)); - - /* Set the two least significant bits to 0 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 0, 0)); - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 1, 0)); - - /* Set the most significant bit to 1 */ - MBEDTLS_MPI_CHK( - mbedtls_mpi_set_bit(&key->d, - ECP_CURVE448_KEY_SIZE * 8 - 1, 1) - ); - } - } -#endif -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&key->d, buf, buflen)); - } -#endif - - if (ret == 0) { - MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(&key->grp, &key->d)); - } - -cleanup: - - if (ret != 0) { - mbedtls_mpi_free(&key->d); - } - - return ret; -} - -/* - * Write a private key. - */ -#if !defined MBEDTLS_DEPRECATED_REMOVED -int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, - unsigned char *buf, size_t buflen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - if (key->grp.id == MBEDTLS_ECP_DP_CURVE25519) { - if (buflen < ECP_CURVE25519_KEY_SIZE) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - - } else if (key->grp.id == MBEDTLS_ECP_DP_CURVE448) { - if (buflen < ECP_CURVE448_KEY_SIZE) { - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - } - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&key->d, buf, buflen)); - } -#endif -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&key->d, buf, buflen)); - } - -#endif -cleanup: - - return ret; -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key, - size_t *olen, unsigned char *buf, size_t buflen) -{ - size_t len = (key->grp.nbits + 7) / 8; - if (len > buflen) { - /* For robustness, ensure *olen <= buflen even on error. */ - *olen = 0; - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - } - *olen = len; - - /* Private key not set */ - if (key->d.n == 0) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { - return mbedtls_mpi_write_binary_le(&key->d, buf, len); - } -#endif - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { - return mbedtls_mpi_write_binary(&key->d, buf, len); - } -#endif - - /* Private key set but no recognized curve type? This shouldn't happen. */ - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -} - -/* - * Write a public key. - */ -int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key, - int format, size_t *olen, - unsigned char *buf, size_t buflen) -{ - return mbedtls_ecp_point_write_binary(&key->grp, &key->Q, - format, olen, buf, buflen); -} - - -#if defined(MBEDTLS_ECP_C) -/* - * Check a public-private key pair - */ -int mbedtls_ecp_check_pub_priv( - const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_point Q; - mbedtls_ecp_group grp; - if (pub->grp.id == MBEDTLS_ECP_DP_NONE || - pub->grp.id != prv->grp.id || - mbedtls_mpi_cmp_mpi(&pub->Q.X, &prv->Q.X) || - mbedtls_mpi_cmp_mpi(&pub->Q.Y, &prv->Q.Y) || - mbedtls_mpi_cmp_mpi(&pub->Q.Z, &prv->Q.Z)) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - mbedtls_ecp_point_init(&Q); - mbedtls_ecp_group_init(&grp); - - /* mbedtls_ecp_mul() needs a non-const group... */ - mbedtls_ecp_group_copy(&grp, &prv->grp); - - /* Also checks d is valid */ - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&grp, &Q, &prv->d, &prv->grp.G, f_rng, p_rng)); - - if (mbedtls_mpi_cmp_mpi(&Q.X, &prv->Q.X) || - mbedtls_mpi_cmp_mpi(&Q.Y, &prv->Q.Y) || - mbedtls_mpi_cmp_mpi(&Q.Z, &prv->Q.Z)) { - ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - goto cleanup; - } - -cleanup: - mbedtls_ecp_point_free(&Q); - mbedtls_ecp_group_free(&grp); - - return ret; -} - -int mbedtls_ecp_keypair_calc_public(mbedtls_ecp_keypair *key, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - return mbedtls_ecp_mul(&key->grp, &key->Q, &key->d, &key->grp.G, - f_rng, p_rng); -} -#endif /* MBEDTLS_ECP_C */ - -mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id( - const mbedtls_ecp_keypair *key) -{ - return key->grp.id; -} - -/* - * Export generic key-pair parameters. - */ -int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp, - mbedtls_mpi *d, mbedtls_ecp_point *Q) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (grp != NULL && (ret = mbedtls_ecp_group_copy(grp, &key->grp)) != 0) { - return ret; - } - - if (d != NULL && (ret = mbedtls_mpi_copy(d, &key->d)) != 0) { - return ret; - } - - if (Q != NULL && (ret = mbedtls_ecp_copy(Q, &key->Q)) != 0) { - return ret; - } - - return 0; -} - -#if defined(MBEDTLS_SELF_TEST) - -#if defined(MBEDTLS_ECP_C) -/* - * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!! - * - * This is the linear congruential generator from numerical recipes, - * except we only use the low byte as the output. See - * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use - */ -static int self_test_rng(void *ctx, unsigned char *out, size_t len) -{ - static uint32_t state = 42; - - (void) ctx; - - for (size_t i = 0; i < len; i++) { - state = state * 1664525u + 1013904223u; - out[i] = (unsigned char) state; - } - - return 0; -} - -/* Adjust the exponent to be a valid private point for the specified curve. - * This is sometimes necessary because we use a single set of exponents - * for all curves but the validity of values depends on the curve. */ -static int self_test_adjust_exponent(const mbedtls_ecp_group *grp, - mbedtls_mpi *m) -{ - int ret = 0; - switch (grp->id) { - /* If Curve25519 is available, then that's what we use for the - * Montgomery test, so we don't need the adjustment code. */ -#if !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - /* Move highest bit from 254 to N-1. Setting bit N-1 is - * necessary to enforce the highest-bit-set constraint. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(m, 254, 0)); - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(m, grp->nbits, 1)); - /* Copy second-highest bit from 253 to N-2. This is not - * necessary but improves the test variety a bit. */ - MBEDTLS_MPI_CHK( - mbedtls_mpi_set_bit(m, grp->nbits - 1, - mbedtls_mpi_get_bit(m, 253))); - break; -#endif -#endif /* ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) */ - default: - /* Non-Montgomery curves and Curve25519 need no adjustment. */ - (void) grp; - (void) m; - goto cleanup; - } -cleanup: - return ret; -} - -/* Calculate R = m.P for each m in exponents. Check that the number of - * basic operations doesn't depend on the value of m. */ -static int self_test_point(int verbose, - mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - mbedtls_mpi *m, - const mbedtls_ecp_point *P, - const char *const *exponents, - size_t n_exponents) -{ - int ret = 0; - size_t i = 0; - unsigned long add_c_prev, dbl_c_prev, mul_c_prev; - add_count = 0; - dbl_count = 0; - mul_count = 0; - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(m, 16, exponents[0])); - MBEDTLS_MPI_CHK(self_test_adjust_exponent(grp, m)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, R, m, P, self_test_rng, NULL)); - - for (i = 1; i < n_exponents; i++) { - add_c_prev = add_count; - dbl_c_prev = dbl_count; - mul_c_prev = mul_count; - add_count = 0; - dbl_count = 0; - mul_count = 0; - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(m, 16, exponents[i])); - MBEDTLS_MPI_CHK(self_test_adjust_exponent(grp, m)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, R, m, P, self_test_rng, NULL)); - - if (add_count != add_c_prev || - dbl_count != dbl_c_prev || - mul_count != mul_c_prev) { - ret = 1; - break; - } - } - -cleanup: - if (verbose != 0) { - if (ret != 0) { - mbedtls_printf("failed (%u)\n", (unsigned int) i); - } else { - mbedtls_printf("passed\n"); - } - } - return ret; -} -#endif /* MBEDTLS_ECP_C */ - -/* - * Checkup routine - */ -int mbedtls_ecp_self_test(int verbose) -{ -#if defined(MBEDTLS_ECP_C) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_group grp; - mbedtls_ecp_point R, P; - mbedtls_mpi m; - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - /* Exponents especially adapted for secp192k1, which has the lowest - * order n of all supported curves (secp192r1 is in a slightly larger - * field but the order of its base point is slightly smaller). */ - const char *sw_exponents[] = - { - "000000000000000000000000000000000000000000000001", /* one */ - "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8C", /* n - 1 */ - "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ - "400000000000000000000000000000000000000000000000", /* one and zeros */ - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ - "555555555555555555555555555555555555555555555555", /* 101010... */ - }; -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - const char *m_exponents[] = - { - /* Valid private values for Curve25519. In a build with Curve448 - * but not Curve25519, they will be adjusted in - * self_test_adjust_exponent(). */ - "4000000000000000000000000000000000000000000000000000000000000000", - "5C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C30", - "5715ECCE24583F7A7023C24164390586842E816D7280A49EF6DF4EAE6B280BF8", - "41A2B017516F6D254E1F002BCCBADD54BE30F8CEC737A0E912B4963B6BA74460", - "5555555555555555555555555555555555555555555555555555555555555550", - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8", - }; -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - - mbedtls_ecp_group_init(&grp); - mbedtls_ecp_point_init(&R); - mbedtls_ecp_point_init(&P); - mbedtls_mpi_init(&m); - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - /* Use secp192r1 if available, or any available curve */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP192R1)); -#else - MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, mbedtls_ecp_curve_list()->grp_id)); -#endif - - if (verbose != 0) { - mbedtls_printf(" ECP SW test #1 (constant op_count, base point G): "); - } - /* Do a dummy multiplication first to trigger precomputation */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&m, 2)); - MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&grp, &P, &m, &grp.G, self_test_rng, NULL)); - ret = self_test_point(verbose, - &grp, &R, &m, &grp.G, - sw_exponents, - sizeof(sw_exponents) / sizeof(sw_exponents[0])); - if (ret != 0) { - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf(" ECP SW test #2 (constant op_count, other point): "); - } - /* We computed P = 2G last time, use it */ - ret = self_test_point(verbose, - &grp, &R, &m, &P, - sw_exponents, - sizeof(sw_exponents) / sizeof(sw_exponents[0])); - if (ret != 0) { - goto cleanup; - } - - mbedtls_ecp_group_free(&grp); - mbedtls_ecp_point_free(&R); -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (verbose != 0) { - mbedtls_printf(" ECP Montgomery test (constant op_count): "); - } -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_CURVE25519)); -#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_CURVE448)); -#else -#error "MBEDTLS_ECP_MONTGOMERY_ENABLED is defined, but no curve is supported for self-test" -#endif - ret = self_test_point(verbose, - &grp, &R, &m, &grp.G, - m_exponents, - sizeof(m_exponents) / sizeof(m_exponents[0])); - if (ret != 0) { - goto cleanup; - } -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - -cleanup: - - if (ret < 0 && verbose != 0) { - mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret); - } - - mbedtls_ecp_group_free(&grp); - mbedtls_ecp_point_free(&R); - mbedtls_ecp_point_free(&P); - mbedtls_mpi_free(&m); - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return ret; -#else /* MBEDTLS_ECP_C */ - (void) verbose; - return 0; -#endif /* MBEDTLS_ECP_C */ -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* !MBEDTLS_ECP_ALT */ - -#endif /* MBEDTLS_ECP_LIGHT */ diff --git a/vendor/mbedtls/library/ecp_curves.c b/vendor/mbedtls/library/ecp_curves.c deleted file mode 100644 index c3cd33f47..000000000 --- a/vendor/mbedtls/library/ecp_curves.c +++ /dev/null @@ -1,5460 +0,0 @@ -/* - * Elliptic curves over GF(p): curve-specific data and functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if !defined(MBEDTLS_ECP_WITH_MPI_UINT) - -#if defined(MBEDTLS_ECP_LIGHT) - -#include "mbedtls/ecp.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include "bn_mul.h" -#include "bignum_core.h" -#include "ecp_invasive.h" - -#include - -#if !defined(MBEDTLS_ECP_ALT) - -#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } - -#define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) - -#define ECP_POINT_INIT_XY_Z0(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(NULL, 0) } -#define ECP_POINT_INIT_XY_Z1(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(mpi_one, 1) } - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* For these curves, we build the group parameters dynamically. */ -#define ECP_LOAD_GROUP -static const mbedtls_mpi_uint mpi_one[] = { 1 }; -#endif - -/* - * Note: the constants are in little-endian order - * to be directly usable in MPIs - */ - -/* - * Domain parameters for secp192r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static const mbedtls_mpi_uint secp192r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp192r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64), -}; -static const mbedtls_mpi_uint secp192r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), -}; -static const mbedtls_mpi_uint secp192r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), -}; -static const mbedtls_mpi_uint secp192r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp192r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), -}; -static const mbedtls_mpi_uint secp192r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), -}; -static const mbedtls_mpi_uint secp192r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x9E, 0xE3, 0x60, 0x59, 0xD1, 0xC4, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBD, 0x22, 0xD7, 0x2D, 0x07, 0xBD, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x2A, 0xCF, 0x33, 0xF0, 0xBE, 0xD1, 0xED), -}; -static const mbedtls_mpi_uint secp192r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x71, 0x4B, 0xA8, 0xED, 0x7E, 0xC9, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x2A, 0xF6, 0xDF, 0x0E, 0xE8, 0x4C, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x35, 0xF7, 0x8A, 0xC3, 0xEC, 0xDE, 0x1E), -}; -static const mbedtls_mpi_uint secp192r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0xC2, 0x1D, 0x32, 0x8F, 0x10, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x2D, 0x17, 0xF3, 0xE4, 0xFE, 0xD8, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x45, 0x10, 0x70, 0x2C, 0x3E, 0x52, 0x3E), -}; -static const mbedtls_mpi_uint secp192r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF1, 0x04, 0x5D, 0xEE, 0xD4, 0x56, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xB7, 0x38, 0x27, 0x61, 0xAA, 0x81, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0xD7, 0x0E, 0x29, 0x0E, 0x11, 0x14), -}; -static const mbedtls_mpi_uint secp192r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x35, 0x52, 0xC6, 0x31, 0xB7, 0x27, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xD4, 0x15, 0x98, 0x0F, 0xE7, 0xF3, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x31, 0x70, 0x35, 0x09, 0xA0, 0x2B, 0xC2), -}; -static const mbedtls_mpi_uint secp192r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x75, 0xA7, 0x4C, 0x88, 0xCF, 0x5B, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x17, 0x48, 0x8D, 0xF2, 0xF0, 0x86, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCF, 0xFE, 0x6B, 0xB0, 0xA5, 0x06, 0xAB), -}; -static const mbedtls_mpi_uint secp192r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x6A, 0xDC, 0x9A, 0x6D, 0x7B, 0x47, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xFC, 0x51, 0x12, 0x62, 0x66, 0x0B, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x40, 0x93, 0xA0, 0xB5, 0x5A, 0x58, 0xD7), -}; -static const mbedtls_mpi_uint secp192r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCB, 0xAF, 0xDC, 0x0B, 0xA1, 0x26, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x36, 0x9D, 0xA3, 0xD7, 0x3B, 0xAD, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x3B, 0x05, 0x9A, 0xA8, 0xAA, 0x69, 0xB2), -}; -static const mbedtls_mpi_uint secp192r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD9, 0xD1, 0x4D, 0x4A, 0x6E, 0x96, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x66, 0x32, 0x39, 0xC6, 0x57, 0x7D, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xA0, 0x36, 0xC2, 0x45, 0xF9, 0x00, 0x62), -}; -static const mbedtls_mpi_uint secp192r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xEF, 0x59, 0x46, 0xDC, 0x60, 0xD9, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xB0, 0xE9, 0x41, 0xA4, 0x87, 0x76, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xD4, 0x0E, 0xB2, 0xFA, 0x16, 0x56, 0xDC), -}; -static const mbedtls_mpi_uint secp192r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x62, 0xD2, 0xB1, 0x34, 0xB2, 0xF1, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xED, 0x55, 0xC5, 0x47, 0xB5, 0x07, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF6, 0x2F, 0x94, 0xC3, 0xDD, 0x54, 0x2F), -}; -static const mbedtls_mpi_uint secp192r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xA6, 0xD4, 0x8C, 0xA9, 0xCE, 0x4D, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x4B, 0x46, 0xCC, 0xB2, 0x55, 0xC8, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x31, 0xED, 0x89, 0x65, 0x59, 0x55), -}; -static const mbedtls_mpi_uint secp192r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x0A, 0xD1, 0x1A, 0xC5, 0xF6, 0xEA, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xFC, 0x0C, 0x1A, 0xFB, 0xA0, 0xC8, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xFD, 0x53, 0x6F, 0x6D, 0xBF, 0xBA, 0xAF), -}; -static const mbedtls_mpi_uint secp192r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xB0, 0x7D, 0x83, 0x96, 0xE3, 0xCB, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x6E, 0x55, 0x2C, 0x20, 0x53, 0x2F, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x66, 0x00, 0x17, 0x08, 0xFE, 0xAC, 0x31), -}; -static const mbedtls_mpi_uint secp192r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x12, 0x97, 0x3A, 0xC7, 0x57, 0x45, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x25, 0x99, 0x00, 0xF6, 0x97, 0xB4, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x74, 0xE6, 0xE6, 0xA3, 0xDF, 0x9C, 0xCC), -}; -static const mbedtls_mpi_uint secp192r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xF4, 0x76, 0xD5, 0x5F, 0x2A, 0xFD, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x80, 0x7E, 0x3E, 0xE5, 0xE8, 0xD6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xAD, 0x1E, 0x70, 0x79, 0x3E, 0x3D, 0x83), -}; -static const mbedtls_mpi_uint secp192r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x15, 0xBB, 0xB3, 0x42, 0x6A, 0xA1, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x58, 0xCB, 0x43, 0x25, 0x00, 0x14, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x4E, 0x93, 0x11, 0xE0, 0x32, 0x54, 0x98), -}; -static const mbedtls_mpi_uint secp192r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x52, 0xA2, 0xB4, 0x57, 0x32, 0xB9, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x43, 0xA1, 0xB1, 0xFB, 0x01, 0xE1, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xFB, 0x5A, 0x11, 0xB8, 0xC2, 0x03, 0xE5), -}; -static const mbedtls_mpi_uint secp192r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x2B, 0x71, 0x26, 0x4E, 0x7C, 0xC5, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF5, 0xD3, 0xA8, 0xE4, 0x95, 0x48, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAE, 0xD9, 0x5D, 0x9F, 0x6A, 0x22, 0xAD), -}; -static const mbedtls_mpi_uint secp192r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xCC, 0xA3, 0x4D, 0xA0, 0x1C, 0x34, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x3C, 0x62, 0xF8, 0x5E, 0xA6, 0x58, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x6E, 0x66, 0x8A, 0x3D, 0x17, 0xFF, 0x0F), -}; -static const mbedtls_mpi_uint secp192r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xCD, 0xA8, 0xDD, 0xD1, 0x20, 0x5C, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xFE, 0x17, 0xE2, 0xCF, 0xEA, 0x63, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x51, 0xC9, 0x16, 0xDE, 0xB4, 0xB2, 0xDD), -}; -static const mbedtls_mpi_uint secp192r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBE, 0x12, 0xD7, 0xA3, 0x0A, 0x50, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x87, 0xC5, 0x8A, 0x76, 0x57, 0x07, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x1F, 0xC6, 0x1B, 0x66, 0xC4, 0x3D, 0x8A), -}; -static const mbedtls_mpi_uint secp192r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xA4, 0x85, 0x13, 0x8F, 0xA7, 0x35, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x0D, 0xFD, 0xFF, 0x1B, 0xD1, 0xD6, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x7A, 0xD0, 0xC3, 0xB4, 0xEF, 0x39, 0x66), -}; -static const mbedtls_mpi_uint secp192r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xFE, 0xA5, 0x9C, 0x34, 0x30, 0x49, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xC5, 0x39, 0x26, 0x06, 0xE3, 0x01, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x2B, 0x66, 0xFC, 0x95, 0x5F, 0x35, 0xF7), -}; -static const mbedtls_mpi_uint secp192r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xCF, 0x54, 0x63, 0x99, 0x57, 0x05, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x6F, 0x00, 0x5F, 0x65, 0x08, 0x47, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x2A, 0x90, 0x6D, 0x67, 0xC6, 0xBC, 0x45), -}; -static const mbedtls_mpi_uint secp192r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x4D, 0x88, 0x0A, 0x35, 0x9E, 0x33, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x17, 0x0C, 0xF8, 0xE1, 0x7A, 0x49, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x44, 0x06, 0x8F, 0x0B, 0x70, 0x2F, 0x71), -}; -static const mbedtls_mpi_uint secp192r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4B, 0xCB, 0xF9, 0x8E, 0x6A, 0xDA, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x43, 0xA1, 0x3F, 0xCE, 0x17, 0xD2, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x0D, 0xD2, 0x6C, 0x82, 0x37, 0xE5, 0xFC), -}; -static const mbedtls_mpi_uint secp192r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x3C, 0xF4, 0x92, 0xB4, 0x8A, 0x95, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x96, 0xF1, 0x0A, 0x34, 0x2F, 0x74, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0xAA, 0xBA, 0x86, 0x77, 0x4F, 0xA2), -}; -static const mbedtls_mpi_uint secp192r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x7F, 0xEF, 0x60, 0x50, 0x80, 0xD7, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xAC, 0xC9, 0xFE, 0xEC, 0x0A, 0x1A, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x2F, 0xBE, 0x91, 0xD7, 0xB7, 0x38, 0x48), -}; -static const mbedtls_mpi_uint secp192r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xAE, 0x85, 0x98, 0xFE, 0x05, 0x7F, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBE, 0xFD, 0x11, 0x31, 0x3D, 0x14, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x75, 0xE8, 0x30, 0x01, 0xCB, 0x9B, 0x1C), -}; -static const mbedtls_ecp_point secp192r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp192r1_T_0_X, secp192r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_1_X, secp192r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_2_X, secp192r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_3_X, secp192r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_4_X, secp192r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_5_X, secp192r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_6_X, secp192r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_7_X, secp192r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_8_X, secp192r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_9_X, secp192r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_10_X, secp192r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_11_X, secp192r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_12_X, secp192r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_13_X, secp192r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_14_X, secp192r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_15_X, secp192r1_T_15_Y), -}; -#else -#define secp192r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -/* - * Domain parameters for secp224r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static const mbedtls_mpi_uint secp224r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_4(0x85, 0x0A, 0x05, 0xB4), -}; -static const mbedtls_mpi_uint secp224r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_4(0xBD, 0x0C, 0x0E, 0xB7), -}; -static const mbedtls_mpi_uint secp224r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_4(0x88, 0x63, 0x37, 0xBD), -}; -static const mbedtls_mpi_uint secp224r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp224r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x0C, 0x0E, 0xB7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x63, 0x37, 0xBD, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF9, 0xB8, 0xD0, 0x3D, 0xD2, 0xD3, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xFD, 0x99, 0x26, 0x19, 0xFE, 0x13, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x0E, 0x4C, 0x48, 0x7C, 0xA2, 0x17, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA3, 0x13, 0x57, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x16, 0x5C, 0x8F, 0xAA, 0xED, 0x0F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xC5, 0x43, 0x34, 0x93, 0x05, 0x2A, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE3, 0x6C, 0xCA, 0xC6, 0x14, 0xC2, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x43, 0x6C, 0xD7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x5A, 0x98, 0x1E, 0xC8, 0xA5, 0x42, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x49, 0x56, 0x78, 0xF8, 0xEF, 0xED, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xBB, 0x64, 0xB6, 0x4C, 0x54, 0x5F, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x0C, 0x33, 0xCC, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x79, 0xCB, 0x2E, 0x08, 0xFF, 0xD8, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x1F, 0xD4, 0xD7, 0x57, 0xE9, 0x39, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xD6, 0x3B, 0x0A, 0x1C, 0x87, 0xB7, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x30, 0xD8, 0x05, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x79, 0x74, 0x9A, 0xE6, 0xBB, 0xC2, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x5B, 0xA6, 0x67, 0xC1, 0x91, 0xE7, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xDF, 0x38, 0x82, 0x19, 0x2C, 0x4C, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x2E, 0x39, 0xC5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x36, 0x78, 0x4E, 0xAE, 0x5B, 0x02, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF6, 0x8B, 0xF8, 0xF4, 0x92, 0x6B, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x4D, 0x71, 0x35, 0xE7, 0x0C, 0x2C, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xA5, 0x1F, 0xAE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x1C, 0x4B, 0xDF, 0x5B, 0xF2, 0x51, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0xB1, 0x5A, 0xC6, 0x0F, 0x0E, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x24, 0x09, 0x62, 0xAF, 0xFC, 0xDB, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xE1, 0x80, 0x55, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x82, 0xFE, 0xAD, 0xC3, 0xE5, 0xCF, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xA2, 0x62, 0x17, 0x76, 0xF0, 0x5A, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB8, 0xE5, 0xAC, 0xB7, 0x66, 0x38, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xFD, 0x86, 0x05, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0x0C, 0x3C, 0xD1, 0x66, 0xB0, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x59, 0xB4, 0x8D, 0x90, 0x10, 0xB7, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x47, 0x9B, 0xE6, 0x55, 0x8A, 0xE4, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x49, 0xDB, 0x78, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x97, 0xED, 0xDE, 0xFF, 0xB3, 0xDF, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xB9, 0x83, 0xB7, 0xEB, 0xBE, 0x40, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xD3, 0xD3, 0xCD, 0x0E, 0x82, 0x79, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x83, 0x1B, 0xF0, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x22, 0xBB, 0x54, 0xD3, 0x31, 0x56, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0xE5, 0xE0, 0x89, 0x96, 0x8E, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xEF, 0x0A, 0xED, 0xD0, 0x11, 0x4A, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x00, 0x57, 0x27, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCA, 0x3D, 0xF7, 0x64, 0x9B, 0x6E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xE3, 0x70, 0x6B, 0x41, 0xD7, 0xED, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x44, 0x44, 0x80, 0xCE, 0x13, 0x37, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x73, 0x80, 0x79, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x4D, 0x70, 0x7D, 0x31, 0x0F, 0x1C, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x35, 0x88, 0x47, 0xC4, 0x24, 0x78, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF0, 0xCD, 0x91, 0x81, 0xB3, 0xDE, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xCE, 0xC6, 0xF7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x9C, 0x2D, 0xE8, 0xD2, 0x00, 0x8F, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x5E, 0x7C, 0x0E, 0x0C, 0x6E, 0x58, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x81, 0x21, 0xCE, 0x43, 0xF4, 0x24, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xBC, 0xF0, 0xF4, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x10, 0xC2, 0x74, 0x4A, 0x8F, 0x8A, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x67, 0xF4, 0x2B, 0x38, 0x2B, 0x35, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0C, 0xA9, 0xFA, 0x77, 0x5C, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x19, 0x2B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x3E, 0x96, 0x22, 0x53, 0xE1, 0xE9, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x13, 0xBC, 0xA1, 0x16, 0xEC, 0x01, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x00, 0xC9, 0x7A, 0xC3, 0x73, 0xA5, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xF4, 0x5E, 0xC1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x95, 0xD6, 0xD9, 0x32, 0x30, 0x2B, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x42, 0x09, 0x05, 0x61, 0x2A, 0x7E, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x84, 0xA2, 0x05, 0x88, 0x64, 0x65, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2D, 0x90, 0xB3, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE7, 0x2E, 0x85, 0x55, 0x80, 0x7C, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC1, 0xAC, 0x78, 0xB4, 0xAF, 0xFB, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xC3, 0x28, 0x8E, 0x79, 0x18, 0x1F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x46, 0xCF, 0x49, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x5F, 0xA8, 0x6C, 0x46, 0x83, 0x43, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xA9, 0x93, 0x11, 0xB6, 0x07, 0x57, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x2A, 0x9D, 0x03, 0x89, 0x7E, 0xD7, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x8C, 0x62, 0xCF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x2C, 0x13, 0x59, 0xCC, 0xFA, 0x84, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB9, 0x48, 0xBC, 0x57, 0xC7, 0xB3, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x0A, 0x38, 0x24, 0x2E, 0x3A, 0x28, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x0A, 0x43, 0xB8, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x25, 0xAB, 0xC1, 0xEE, 0x70, 0x3C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xDB, 0x45, 0x1D, 0x4A, 0x80, 0x75, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1F, 0x4D, 0x2D, 0x9A, 0x05, 0xF4, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x10, 0xF0, 0x5A, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x95, 0xE1, 0xDC, 0x15, 0x86, 0xC3, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xDC, 0x27, 0xD1, 0x56, 0xA1, 0x14, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x0B, 0xD6, 0x77, 0x4E, 0x44, 0xA2, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x42, 0x71, 0x1F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x86, 0xB2, 0xB0, 0xC8, 0x2F, 0x7B, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xEF, 0xCB, 0xDB, 0xBC, 0x9E, 0x3B, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x03, 0x86, 0xDD, 0x5B, 0xF5, 0x8D, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x95, 0x79, 0xD6, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x32, 0x14, 0xDA, 0x9B, 0x4F, 0x07, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x3E, 0xFB, 0x06, 0xEE, 0xA7, 0x40, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x1F, 0xDF, 0x71, 0x61, 0xFD, 0x8B, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x8B, 0xAB, 0x8B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x34, 0xB3, 0xB4, 0xBC, 0x9F, 0xB0, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x58, 0x48, 0xA8, 0x77, 0xBB, 0x13, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC6, 0xF7, 0x34, 0xCC, 0x89, 0x21, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x33, 0xDD, 0x1F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x81, 0xEF, 0xA4, 0xF2, 0x10, 0x0B, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF7, 0x6E, 0x72, 0x4A, 0xDF, 0xDD, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x23, 0x0A, 0x53, 0x03, 0x16, 0x62, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x76, 0xFD, 0x3C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x14, 0xA1, 0xFA, 0xA0, 0x18, 0xBE, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2A, 0xE1, 0xD7, 0xB0, 0x6C, 0xA0, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xC0, 0xB0, 0xC6, 0x63, 0x24, 0xCD, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x38, 0x2C, 0xB1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCD, 0x7D, 0x20, 0x0C, 0xFE, 0xAC, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x9F, 0xA2, 0xB6, 0x45, 0xF7, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x99, 0xF3, 0xD2, 0x20, 0x02, 0xEB, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x5B, 0x7B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xDD, 0x77, 0x91, 0x60, 0xEA, 0xFD, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xD3, 0xB5, 0xD6, 0x90, 0x17, 0x0E, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xF4, 0x28, 0xC1, 0xF2, 0x53, 0xF6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x58, 0xDC, 0x61, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x20, 0x01, 0xFB, 0xF1, 0xBD, 0x5F, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x7F, 0x06, 0xDA, 0x11, 0xCB, 0xBA, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x41, 0x00, 0xA4, 0x1B, 0x30, 0x33, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xFF, 0x27, 0xCA, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp224r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp224r1_T_0_X, secp224r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_1_X, secp224r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_2_X, secp224r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_3_X, secp224r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_4_X, secp224r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_5_X, secp224r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_6_X, secp224r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_7_X, secp224r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_8_X, secp224r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_9_X, secp224r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_10_X, secp224r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_11_X, secp224r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_12_X, secp224r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_13_X, secp224r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_14_X, secp224r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_15_X, secp224r1_T_15_Y), -}; -#else -#define secp224r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -/* - * Domain parameters for secp256r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static const mbedtls_mpi_uint secp256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A), -}; -static const mbedtls_mpi_uint secp256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), -}; -static const mbedtls_mpi_uint secp256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), -}; -static const mbedtls_mpi_uint secp256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp256r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), -}; -static const mbedtls_mpi_uint secp256r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), -}; -static const mbedtls_mpi_uint secp256r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xC8, 0xBA, 0x04, 0xB7, 0x4B, 0xD2, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC6, 0x23, 0x3A, 0xA0, 0x09, 0x3A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x9D, 0x4C, 0xF9, 0x58, 0x23, 0xCC, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xED, 0x7B, 0x29, 0x87, 0x0F, 0xFA, 0x3C), -}; -static const mbedtls_mpi_uint secp256r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x69, 0xF2, 0x40, 0x0B, 0xA3, 0x98, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xA8, 0x48, 0x02, 0x0D, 0x1C, 0x12, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xAF, 0x09, 0x83, 0x80, 0xAA, 0x58, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x12, 0xBE, 0x70, 0x94, 0x76, 0xE3, 0xE4), -}; -static const mbedtls_mpi_uint secp256r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x7D, 0xEF, 0x86, 0xFF, 0xE3, 0x37, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x86, 0x8B, 0x08, 0x27, 0x7C, 0xD7, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x54, 0x4C, 0x25, 0x4F, 0x9A, 0xFE, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xFD, 0xF0, 0x6D, 0x37, 0x03, 0x69, 0xD6), -}; -static const mbedtls_mpi_uint secp256r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xD5, 0xDA, 0xAD, 0x92, 0x49, 0xF0, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x73, 0x43, 0x9E, 0xAF, 0xA7, 0xD1, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x41, 0x07, 0xDF, 0x78, 0x95, 0x3E, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x3D, 0xD1, 0xE6, 0x3C, 0xA5, 0xE2, 0x20), -}; -static const mbedtls_mpi_uint secp256r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x6A, 0x5D, 0x52, 0x35, 0xD7, 0xBF, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xA2, 0xBE, 0x96, 0xF4, 0xF8, 0x02, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x20, 0x49, 0x54, 0xEA, 0xB3, 0x82, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0xDB, 0xEA, 0x02, 0xD1, 0x75, 0x1C, 0x62), -}; -static const mbedtls_mpi_uint secp256r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x85, 0xF4, 0x9E, 0x4C, 0xDC, 0x39, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x6D, 0xC4, 0x57, 0xD8, 0x03, 0x5D, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x7F, 0x2D, 0x52, 0x6F, 0xC9, 0xDA, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x64, 0xFA, 0xB4, 0xFE, 0xA4, 0xC4, 0xD7), -}; -static const mbedtls_mpi_uint secp256r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x37, 0xB9, 0xC0, 0xAA, 0x59, 0xC6, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x58, 0xD9, 0xED, 0x58, 0x99, 0x65, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x7D, 0x26, 0x8C, 0x4A, 0xF9, 0x05, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x73, 0x9A, 0xC9, 0xE7, 0x46, 0xDC, 0x00), -}; -static const mbedtls_mpi_uint secp256r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xD0, 0x55, 0xDF, 0x00, 0x0A, 0xF5, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xBF, 0x56, 0x81, 0x2D, 0x20, 0xEB, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC1, 0x28, 0x52, 0xAB, 0xE3, 0xD1, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x34, 0x79, 0x45, 0x57, 0xA5, 0x12, 0x03), -}; -static const mbedtls_mpi_uint secp256r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCF, 0xB8, 0x7E, 0xF7, 0x92, 0x96, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x01, 0x8C, 0x0D, 0x23, 0xF2, 0xE3, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x2E, 0xE3, 0x84, 0x52, 0x7A, 0x34, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xA1, 0xB0, 0x15, 0x90, 0xE2, 0x53, 0x3C), -}; -static const mbedtls_mpi_uint secp256r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x98, 0xE7, 0xFA, 0xA5, 0x7D, 0x8B, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x35, 0xD2, 0x00, 0xD1, 0x1B, 0x9F, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x69, 0x08, 0x9A, 0x72, 0xF0, 0xA9, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xFE, 0x0E, 0x14, 0xDA, 0x7C, 0x0E, 0xD3), -}; -static const mbedtls_mpi_uint secp256r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF6, 0xE8, 0xF8, 0x87, 0xF7, 0xFC, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xBE, 0x7F, 0x3F, 0x7A, 0x2B, 0xD7, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x32, 0xF2, 0x2D, 0x94, 0x6D, 0x42, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x9A, 0xE3, 0x5F, 0x42, 0xBB, 0x84, 0xED), -}; -static const mbedtls_mpi_uint secp256r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x95, 0x29, 0x73, 0xA1, 0x67, 0x3E, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x30, 0x54, 0x35, 0x8E, 0x0A, 0xDD, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xD7, 0xA1, 0x97, 0x61, 0x3B, 0xF8, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x33, 0x3C, 0x58, 0x55, 0x34, 0x23, 0xA3), -}; -static const mbedtls_mpi_uint secp256r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x5D, 0x16, 0x5F, 0x7B, 0xBC, 0xBB, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xEE, 0x4E, 0x8A, 0xC1, 0x51, 0xCC, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0D, 0x4D, 0x1B, 0x53, 0x23, 0x1D, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x2A, 0x38, 0x66, 0x52, 0x84, 0xE1, 0x95), -}; -static const mbedtls_mpi_uint secp256r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x9B, 0x83, 0x0A, 0x81, 0x4F, 0xAD, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xFF, 0x42, 0x41, 0x6E, 0xA9, 0xA2, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA1, 0x4F, 0x1F, 0x89, 0x82, 0xAA, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xB8, 0x0F, 0x6B, 0x8F, 0x8C, 0xD6, 0x68), -}; -static const mbedtls_mpi_uint secp256r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0xB3, 0xBB, 0x51, 0x69, 0xA2, 0x11, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x4F, 0x0F, 0x8D, 0xBD, 0x26, 0x0F, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xCB, 0xEC, 0x6B, 0x34, 0xC3, 0x3D, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x5D, 0x1E, 0x10, 0xD5, 0x44, 0xE2, 0x54), -}; -static const mbedtls_mpi_uint secp256r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x9E, 0xB1, 0xF1, 0x6E, 0x4C, 0xAD, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE3, 0xC2, 0x58, 0xC0, 0xFB, 0x34, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x9C, 0xDF, 0x35, 0x07, 0x41, 0xBD, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x10, 0xEC, 0x0E, 0xEC, 0xBB, 0xD6), -}; -static const mbedtls_mpi_uint secp256r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xCF, 0xEF, 0x3F, 0x83, 0x1A, 0x88, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x29, 0xB5, 0xB9, 0xE0, 0xC9, 0xA3, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x46, 0x1E, 0x77, 0xCD, 0x7E, 0xB3, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x21, 0xD0, 0xD4, 0xA3, 0x16, 0x08, 0xEE), -}; -static const mbedtls_mpi_uint secp256r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xCA, 0xA8, 0xB3, 0xBF, 0x29, 0x99, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF2, 0x05, 0xC1, 0xCF, 0x5D, 0x91, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x01, 0x49, 0xDB, 0x82, 0xDF, 0x5F, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x06, 0x90, 0xAD, 0xE3, 0x38, 0xA4, 0xC4), -}; -static const mbedtls_mpi_uint secp256r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xD2, 0x3A, 0xE8, 0x03, 0xC5, 0x6D, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x35, 0xD0, 0xAE, 0x1D, 0x7A, 0x9F, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x1E, 0xD2, 0xCB, 0xAC, 0x88, 0x27, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x9C, 0xE0, 0x31, 0xDD, 0x99, 0x86), -}; -static const mbedtls_mpi_uint secp256r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF9, 0x9B, 0x32, 0x96, 0x41, 0x58, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x5A, 0x2A, 0xB8, 0x96, 0x0E, 0xB2, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x78, 0x2C, 0xC7, 0x08, 0x99, 0x19, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x59, 0x28, 0xE9, 0x84, 0x54, 0xE6, 0x16), -}; -static const mbedtls_mpi_uint secp256r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x38, 0x30, 0xDB, 0x70, 0x2C, 0x0A, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x5C, 0x9D, 0xE9, 0xD5, 0x46, 0x0B, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x0B, 0x60, 0x4B, 0x37, 0x7D, 0xB9, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x24, 0xF3, 0x3D, 0x79, 0x7F, 0x6C, 0x18), -}; -static const mbedtls_mpi_uint secp256r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7F, 0xE5, 0x1C, 0x4F, 0x60, 0x24, 0xF7, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xD8, 0xE2, 0x91, 0x7F, 0x89, 0x49, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xA7, 0x2E, 0x8D, 0x6A, 0xB3, 0x39, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x89, 0xB5, 0x9A, 0xB8, 0x8D, 0x42, 0x9C), -}; -static const mbedtls_mpi_uint secp256r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x45, 0xE6, 0x4B, 0x3F, 0x4F, 0x1E, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x65, 0x5E, 0x59, 0x22, 0xCC, 0x72, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x93, 0x1A, 0x27, 0x1E, 0x34, 0xC5, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xF2, 0xA5, 0x58, 0x5C, 0x15, 0x2E, 0xC6), -}; -static const mbedtls_mpi_uint secp256r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x7F, 0xBA, 0x58, 0x5A, 0x84, 0x6F, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA6, 0x36, 0x7E, 0xDC, 0xF7, 0xE1, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x4D, 0xAA, 0xEE, 0x57, 0x76, 0x3A, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x7E, 0x26, 0x18, 0x22, 0x23, 0x9F, 0xFF), -}; -static const mbedtls_mpi_uint secp256r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x4C, 0x64, 0xC7, 0x55, 0x02, 0x3F, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x02, 0x90, 0xBB, 0xC3, 0xEC, 0x30, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x6F, 0x64, 0xF4, 0x16, 0x69, 0x48, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x44, 0x9C, 0x95, 0x0C, 0x7D, 0x67, 0x5E), -}; -static const mbedtls_mpi_uint secp256r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x91, 0x8B, 0xD8, 0xD0, 0xD7, 0xE7, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF9, 0x48, 0x62, 0x6F, 0xA8, 0x93, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x3A, 0x99, 0x02, 0xD5, 0x0B, 0x3D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xD3, 0x00, 0x31, 0xE6, 0x0C, 0x9F, 0x44), -}; -static const mbedtls_mpi_uint secp256r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xB2, 0xAA, 0xFD, 0x88, 0x15, 0xDF, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0x35, 0x27, 0x31, 0x44, 0xCD, 0xC0, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xF8, 0x91, 0xA5, 0x71, 0x94, 0x84, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xCB, 0xD0, 0x93, 0xE9, 0x88, 0xDA, 0xE4), -}; -static const mbedtls_mpi_uint secp256r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC6, 0x39, 0x16, 0x5D, 0xA3, 0x1E, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x07, 0x37, 0x26, 0x36, 0x2A, 0xFE, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xBC, 0xF3, 0xD0, 0xDE, 0x50, 0xFC, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x2E, 0x06, 0x10, 0x15, 0x4D, 0xFA, 0xF7), -}; -static const mbedtls_mpi_uint secp256r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x65, 0x69, 0x5B, 0x66, 0xA2, 0x75, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x16, 0x00, 0x5A, 0xB0, 0x30, 0x25, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xFB, 0x86, 0x42, 0x80, 0xC1, 0xC4, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x1D, 0x83, 0x8E, 0x94, 0x01, 0x5F, 0x82), -}; -static const mbedtls_mpi_uint secp256r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x37, 0x70, 0xEF, 0x1F, 0xA1, 0xF0, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x5B, 0xCE, 0xC4, 0x9B, 0x6F, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x11, 0x11, 0x24, 0x4F, 0x4C, 0x79, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x3A, 0x72, 0xBC, 0xFE, 0x72, 0x58, 0x43), -}; -static const mbedtls_ecp_point secp256r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp256r1_T_0_X, secp256r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_1_X, secp256r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_2_X, secp256r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_3_X, secp256r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_4_X, secp256r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_5_X, secp256r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_6_X, secp256r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_7_X, secp256r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_8_X, secp256r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_9_X, secp256r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_10_X, secp256r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_11_X, secp256r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_12_X, secp256r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_13_X, secp256r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_14_X, secp256r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_15_X, secp256r1_T_15_Y), -}; -#else -#define secp256r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -/* - * Domain parameters for secp384r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static const mbedtls_mpi_uint secp384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3), -}; -static const mbedtls_mpi_uint secp384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), -}; -static const mbedtls_mpi_uint secp384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp384r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), -}; -static const mbedtls_mpi_uint secp384r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x92, 0x00, 0x2C, 0x78, 0xDB, 0x1F, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF3, 0xEB, 0xB7, 0x06, 0xF7, 0xB6, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBC, 0x2C, 0xCF, 0xD8, 0xED, 0x53, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x75, 0x7B, 0xA3, 0xAB, 0xC3, 0x2C, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x9D, 0x78, 0x41, 0xF6, 0x76, 0x84, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x56, 0xE8, 0x52, 0xB3, 0xCB, 0xA8, 0xBD), -}; -static const mbedtls_mpi_uint secp384r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xF2, 0xAE, 0xA4, 0xB6, 0x89, 0x1B, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0xCE, 0x1C, 0x7C, 0xF6, 0x50, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xEB, 0x90, 0xE6, 0x4D, 0xC7, 0xD4, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x49, 0x2D, 0x8A, 0x01, 0x99, 0x60, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x80, 0x9B, 0x9B, 0x6A, 0xB0, 0x07, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xA2, 0xEE, 0x59, 0xBE, 0x95, 0xBC, 0x23), -}; -static const mbedtls_mpi_uint secp384r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x9D, 0x56, 0xAE, 0x59, 0xFB, 0x1F, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xAC, 0x91, 0x80, 0x87, 0xA8, 0x6E, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x08, 0xA7, 0x08, 0x94, 0x32, 0xFC, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x29, 0x9E, 0x84, 0xF4, 0xE5, 0x6E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x21, 0xB9, 0x50, 0x24, 0xF8, 0x9C, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x04, 0x01, 0xC2, 0xFB, 0x77, 0x3E, 0xDE), -}; -static const mbedtls_mpi_uint secp384r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x38, 0xEE, 0xE3, 0xC7, 0x9D, 0xEC, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x88, 0xCF, 0x43, 0xFA, 0x92, 0x5E, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xCA, 0x43, 0xF8, 0x3B, 0x49, 0x7E, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xE7, 0xEB, 0x17, 0x45, 0x86, 0xC2, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x69, 0x57, 0x32, 0xE0, 0x9C, 0xD1, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x10, 0xB8, 0x4D, 0xB8, 0xF4, 0x0D, 0xE3), -}; -static const mbedtls_mpi_uint secp384r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0xDC, 0x9A, 0xB2, 0x79, 0x39, 0x27, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x71, 0xE4, 0x3B, 0x4D, 0x60, 0x0C, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xBD, 0x19, 0x40, 0xFA, 0x19, 0x2A, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xF8, 0x1E, 0x43, 0xA1, 0x50, 0x8D, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x18, 0x7C, 0x41, 0xFA, 0x7C, 0x1B, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x24, 0xC4, 0xE9, 0xB7, 0xD3, 0xAD), -}; -static const mbedtls_mpi_uint secp384r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x01, 0x3D, 0x63, 0x54, 0x45, 0x6F, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xB2, 0x19, 0xA3, 0x86, 0x1D, 0x42, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x02, 0x87, 0x18, 0x92, 0x52, 0x1A, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x18, 0xB1, 0x5D, 0x18, 0x1B, 0x37, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x74, 0x61, 0xBA, 0x18, 0xAF, 0x40, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7D, 0x3C, 0x52, 0x0F, 0x07, 0xB0, 0x6F), -}; -static const mbedtls_mpi_uint secp384r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x39, 0x13, 0xAA, 0x60, 0x15, 0x99, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x00, 0xCB, 0xC6, 0xB1, 0xDB, 0x97, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xFA, 0x60, 0xB8, 0x24, 0xE4, 0x7D, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x75, 0xB3, 0x70, 0xB2, 0x83, 0xB1, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xE3, 0x6C, 0xCD, 0x33, 0x62, 0x7A, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x30, 0xDC, 0x0F, 0x9F, 0xBB, 0xB8, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD5, 0x0A, 0x60, 0x81, 0xB9, 0xC5, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xAA, 0x2F, 0xD6, 0xF2, 0x73, 0xDF, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x7B, 0x74, 0xC9, 0xB3, 0x5B, 0x95, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x04, 0xEB, 0x15, 0xC8, 0x5F, 0x00, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x50, 0x20, 0x28, 0xD1, 0x01, 0xAF, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x4F, 0x31, 0x81, 0x2F, 0x94, 0x48), -}; -static const mbedtls_mpi_uint secp384r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2F, 0xD8, 0xB6, 0x63, 0x7C, 0xE9, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x8C, 0xB9, 0x14, 0xD9, 0x37, 0x63, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x02, 0xB8, 0x46, 0xAD, 0xCE, 0x7B, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x47, 0x2D, 0x66, 0xA7, 0xE9, 0x33, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF9, 0x93, 0x94, 0xA8, 0x48, 0xB3, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x4A, 0xAC, 0x51, 0x08, 0x72, 0x2F, 0x1A), -}; -static const mbedtls_mpi_uint secp384r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xAD, 0xA0, 0xF9, 0x81, 0xE1, 0x78, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9A, 0x63, 0xD8, 0xBA, 0x79, 0x1A, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x31, 0x7B, 0x7A, 0x5A, 0x5D, 0x7D, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x96, 0x12, 0x4B, 0x19, 0x09, 0xE0, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8A, 0x57, 0xEE, 0x4E, 0x6E, 0x7E, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x9D, 0x69, 0xDC, 0xB3, 0xDA, 0xD8, 0x08), -}; -static const mbedtls_mpi_uint secp384r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x49, 0x03, 0x03, 0x33, 0x6F, 0x28, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xDB, 0xA7, 0x05, 0x8C, 0xF3, 0x4D, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x92, 0xB1, 0xA8, 0xEC, 0x0D, 0x64, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0xFC, 0xFD, 0xD0, 0x4B, 0x88, 0x1B, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x9C, 0x51, 0x69, 0xCE, 0x71, 0x73, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5A, 0x14, 0x23, 0x1A, 0x46, 0x63, 0x5F), -}; -static const mbedtls_mpi_uint secp384r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x4C, 0x70, 0x44, 0x18, 0xCD, 0xEF, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x49, 0xDD, 0x64, 0x7E, 0x7E, 0x4D, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x32, 0x7C, 0x09, 0xD0, 0x3F, 0xD6, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE0, 0x4F, 0x65, 0x0C, 0x7A, 0x54, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFA, 0xFB, 0x4A, 0xB4, 0x79, 0x5A, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x1B, 0x2B, 0xDA, 0xBC, 0x9A, 0x74), -}; -static const mbedtls_mpi_uint secp384r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xAC, 0x56, 0xF7, 0x5F, 0x51, 0x68, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xE0, 0x1D, 0xBC, 0x13, 0x4E, 0xAC, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF5, 0xC5, 0xE6, 0xD2, 0x88, 0xBA, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x0E, 0x28, 0x23, 0x58, 0x67, 0xFA, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x80, 0x4B, 0xD8, 0xC4, 0xDF, 0x15, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x0E, 0x58, 0xE6, 0x2C, 0x59, 0xC2, 0x03), -}; -static const mbedtls_mpi_uint secp384r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x26, 0x27, 0x99, 0x16, 0x2B, 0x22, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF3, 0x8F, 0xC3, 0x2A, 0x9B, 0xFC, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2E, 0x83, 0x3D, 0xFE, 0x9E, 0x3C, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0xCD, 0x2D, 0xC1, 0x49, 0x38, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x42, 0x8B, 0x33, 0x89, 0x1F, 0xEA, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x1D, 0x13, 0xD7, 0x50, 0xBB, 0x3E, 0xEB), -}; -static const mbedtls_mpi_uint secp384r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x9A, 0x52, 0xD2, 0x54, 0x7C, 0x97, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x6E, 0xED, 0xD9, 0x87, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x35, 0x7E, 0x16, 0x40, 0x15, 0x83, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x2B, 0xA4, 0xAB, 0x03, 0x91, 0xEA, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x47, 0x39, 0xEF, 0x05, 0x59, 0xD0, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x24, 0x0D, 0x76, 0x11, 0x53, 0x08, 0xAF), -}; -static const mbedtls_mpi_uint secp384r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x2F, 0xDD, 0xBD, 0x50, 0x48, 0xB1, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x1C, 0x84, 0x55, 0x78, 0x14, 0xEB, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x5E, 0x3E, 0xA6, 0xAF, 0xF6, 0xC7, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x11, 0xE2, 0x65, 0xCA, 0x41, 0x95, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x83, 0xD8, 0xE6, 0x4D, 0x22, 0x06, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x7F, 0x25, 0x2A, 0xAA, 0x28, 0x46, 0x97), -}; -static const mbedtls_mpi_uint secp384r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xDB, 0x15, 0x56, 0x84, 0xCB, 0xC0, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xDB, 0x0E, 0x08, 0xC9, 0xF5, 0xD4, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x62, 0xD0, 0x1A, 0x7C, 0x13, 0xD5, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xAD, 0x53, 0xE0, 0x32, 0x21, 0xA0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x38, 0x81, 0x21, 0x23, 0x0E, 0xD2, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x51, 0x05, 0xD0, 0x1E, 0x82, 0xA9, 0x71), -}; -static const mbedtls_mpi_uint secp384r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xC3, 0x27, 0xBF, 0xC6, 0xAA, 0xB7, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x65, 0x45, 0xDF, 0xB9, 0x46, 0x17, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x38, 0x3F, 0xB2, 0xB1, 0x5D, 0xCA, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x29, 0x6C, 0x63, 0xE9, 0xD7, 0x48, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xF1, 0xD7, 0x99, 0x8C, 0xC2, 0x05, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE6, 0x5E, 0x82, 0x6D, 0xE5, 0x7E, 0xD5), -}; -static const mbedtls_mpi_uint secp384r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x61, 0xFA, 0x7D, 0x01, 0xDB, 0xB6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC6, 0x58, 0x39, 0xF4, 0xC6, 0x82, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0x7A, 0x80, 0x08, 0xCD, 0xAA, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x8C, 0xC6, 0x3F, 0x3C, 0xA5, 0x68, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xF5, 0xD5, 0x17, 0xAE, 0x36, 0xD8, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xAD, 0x92, 0xC5, 0x57, 0x6C, 0xDA, 0x91), -}; -static const mbedtls_mpi_uint secp384r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x67, 0x17, 0xC0, 0x40, 0x78, 0x8C, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x9F, 0xF4, 0xAA, 0xDA, 0x5C, 0x7E, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xDB, 0x42, 0x3E, 0x72, 0x64, 0xA0, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xF9, 0x41, 0x17, 0x43, 0xE3, 0xE8, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xDD, 0xCC, 0x43, 0x7E, 0x16, 0x05, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x4B, 0xCF, 0x48, 0x8F, 0x41, 0x90, 0xE5), -}; -static const mbedtls_mpi_uint secp384r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x0C, 0x6B, 0x9D, 0x22, 0x04, 0xBC, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x63, 0x79, 0x2F, 0x6A, 0x0E, 0x8A, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x67, 0x3F, 0x02, 0xB8, 0x91, 0x7F, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x14, 0x64, 0xA0, 0x33, 0xF4, 0x6B, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x44, 0x71, 0x87, 0xB8, 0x88, 0x3F, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x2B, 0x85, 0x05, 0xC5, 0x44, 0x53, 0x15), -}; -static const mbedtls_mpi_uint secp384r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x2B, 0xFE, 0xD1, 0x1C, 0x73, 0xE3, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x33, 0xA1, 0xD3, 0x69, 0x1C, 0x9D, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x5A, 0xBA, 0xB6, 0xAE, 0x1B, 0x94, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x74, 0x90, 0x5C, 0x57, 0xB0, 0x3A, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x2F, 0x93, 0x20, 0x24, 0x54, 0x1D, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x78, 0x9D, 0x71, 0x67, 0x5D, 0x49, 0x98), -}; -static const mbedtls_mpi_uint secp384r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xC8, 0x0E, 0x11, 0x8D, 0xE0, 0x8F, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x7F, 0x79, 0x6C, 0x5F, 0xB7, 0xBC, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xE1, 0x83, 0x3C, 0x12, 0xBB, 0xEE, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC2, 0xC4, 0x1B, 0x41, 0x71, 0xB9, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0xEE, 0xBB, 0x1D, 0x89, 0x50, 0x88, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x1C, 0x55, 0x74, 0xEB, 0xDE, 0x92, 0x3F), -}; -static const mbedtls_mpi_uint secp384r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x38, 0x92, 0x06, 0x19, 0xD0, 0xB3, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x99, 0x26, 0xA3, 0x5F, 0xE2, 0xC1, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xFC, 0xFD, 0xC3, 0xB6, 0x26, 0x24, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xAD, 0xE7, 0x49, 0xB7, 0x64, 0x4B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x4E, 0x95, 0xAD, 0x07, 0xFE, 0xB6, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x15, 0xE7, 0x2D, 0x19, 0xA9, 0x08, 0x10), -}; -static const mbedtls_mpi_uint secp384r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xBD, 0xAC, 0x0A, 0x3F, 0x6B, 0xFF, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xE4, 0x74, 0x14, 0xD9, 0x70, 0x1D, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xB0, 0x71, 0xBB, 0xD8, 0x18, 0x96, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xB8, 0x19, 0x90, 0x80, 0xB5, 0xEE, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x21, 0x20, 0xA6, 0x17, 0x48, 0x03, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0xBB, 0x6D, 0x94, 0x20, 0x34, 0xF1), -}; -static const mbedtls_mpi_uint secp384r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x82, 0x67, 0x4B, 0x8E, 0x4E, 0xBE, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xDA, 0x77, 0xF8, 0x23, 0x55, 0x2B, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x02, 0xDE, 0x25, 0x35, 0x2D, 0x74, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0C, 0xB8, 0x0B, 0x39, 0xBA, 0xAD, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x0E, 0x28, 0x4D, 0xE1, 0x3D, 0xE4, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xEC, 0x0A, 0xD4, 0xB8, 0xC4, 0x8D, 0xB0), -}; -static const mbedtls_mpi_uint secp384r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x68, 0xCE, 0xC2, 0x55, 0x4D, 0x0C, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x20, 0x93, 0x32, 0x90, 0xD6, 0xAE, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x78, 0xAB, 0x43, 0x9E, 0xEB, 0x73, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x97, 0xC3, 0x83, 0xA6, 0x3C, 0xF1, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x25, 0x25, 0x66, 0x08, 0x26, 0xFA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xFB, 0x44, 0x5D, 0x82, 0xEC, 0x3B, 0xAC), -}; -static const mbedtls_mpi_uint secp384r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x90, 0xEA, 0xB5, 0x04, 0x99, 0xD0, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0xF2, 0x22, 0xA0, 0xEB, 0xFD, 0x45, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA4, 0x81, 0x32, 0xFC, 0xFA, 0xEE, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xBB, 0xA4, 0x6A, 0x77, 0x41, 0x5C, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x1E, 0xAA, 0x4F, 0xF0, 0x10, 0xB3, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x74, 0x13, 0x14, 0x9E, 0x90, 0xD7, 0xE6), -}; -static const mbedtls_mpi_uint secp384r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xBD, 0x70, 0x4F, 0xA8, 0xD1, 0x06, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4E, 0x2E, 0x68, 0xFC, 0x35, 0xFA, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x53, 0x75, 0xED, 0xF2, 0x5F, 0xC2, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x87, 0x6B, 0x9F, 0x05, 0xE2, 0x22, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x1A, 0xA8, 0xB7, 0x03, 0x9E, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD0, 0x69, 0x88, 0xA8, 0x39, 0x9E, 0x3A), -}; -static const mbedtls_mpi_uint secp384r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xEF, 0x68, 0xFE, 0xEC, 0x24, 0x08, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x4B, 0x92, 0x0D, 0xB7, 0x34, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF4, 0xDD, 0x1A, 0xA0, 0x4A, 0xE4, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x63, 0x4F, 0x4F, 0xCE, 0xBB, 0xD6, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xEE, 0x8D, 0xDF, 0x3F, 0x73, 0xB7, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x06, 0xB6, 0x80, 0x4D, 0x81, 0xD9, 0x53), -}; -static const mbedtls_mpi_uint secp384r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF5, 0x13, 0xDF, 0x13, 0x19, 0x97, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xF9, 0xB3, 0x33, 0x66, 0x82, 0x21, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xFC, 0x39, 0x16, 0x23, 0x43, 0x76, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x48, 0x25, 0xA1, 0x64, 0x95, 0x1C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xAC, 0x15, 0x57, 0xD9, 0xDE, 0xA0, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x5F, 0xB8, 0x3D, 0x48, 0x91, 0x24, 0xCC), -}; -static const mbedtls_mpi_uint secp384r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xF2, 0xC8, 0x54, 0xD1, 0x32, 0xBD, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x3B, 0xF0, 0xAA, 0x9D, 0xD8, 0xF4, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xC3, 0xBB, 0x6C, 0x66, 0xAC, 0x25, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x25, 0x10, 0xB2, 0xE1, 0x41, 0xDE, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xE8, 0x30, 0xB8, 0x37, 0xBC, 0x2A, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x57, 0x01, 0x4A, 0x1E, 0x78, 0x9F, 0x85), -}; -static const mbedtls_mpi_uint secp384r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x19, 0xCD, 0x12, 0x0B, 0x51, 0x4F, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x4B, 0x3D, 0x24, 0xA4, 0x16, 0x59, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xEB, 0xD3, 0x59, 0x2E, 0x75, 0x7C, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB9, 0xB4, 0xA5, 0xD9, 0x2E, 0x29, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x16, 0x05, 0x75, 0x02, 0xB3, 0x06, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x7C, 0x9F, 0x79, 0x91, 0xF1, 0x4F, 0x23), -}; -static const mbedtls_mpi_uint secp384r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x98, 0x7C, 0x84, 0xE1, 0xFF, 0x30, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE2, 0xC2, 0x5F, 0x55, 0x40, 0xBD, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x65, 0x87, 0x3F, 0xC4, 0xC2, 0x24, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x30, 0x0A, 0x60, 0x15, 0xD1, 0x24, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x99, 0xD9, 0xB6, 0xAE, 0xB1, 0xAF, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x80, 0xEE, 0xA2, 0x0F, 0x74, 0xB9, 0xF3), -}; -static const mbedtls_mpi_uint secp384r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xE6, 0x0F, 0x37, 0xC1, 0x10, 0x99, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xAD, 0x9D, 0x5D, 0x80, 0x01, 0xA6, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x0F, 0x10, 0x2A, 0x9D, 0x20, 0x38, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x60, 0xCB, 0xCE, 0x5A, 0xA0, 0xA7, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xCF, 0x14, 0xDF, 0xBF, 0xE5, 0x74, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x12, 0x1A, 0xDD, 0x59, 0x02, 0x5D, 0xC6), -}; -static const mbedtls_mpi_uint secp384r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0xF8, 0xF5, 0xB6, 0x13, 0x4D, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x45, 0xB1, 0x93, 0xB3, 0xA2, 0x79, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xF6, 0xCF, 0xF7, 0xE6, 0x29, 0x9C, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x50, 0x65, 0x80, 0xBC, 0x59, 0x0A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xF0, 0x24, 0x35, 0xA2, 0x46, 0xF0, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x26, 0xC0, 0x9D, 0x61, 0x56, 0x62, 0x67), -}; -static const mbedtls_mpi_uint secp384r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xBB, 0xC2, 0x24, 0x43, 0x2E, 0x37, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xF7, 0xCE, 0x35, 0xFC, 0x77, 0xF3, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x34, 0x96, 0xD5, 0x4A, 0x76, 0x9D, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x3B, 0x0F, 0xEA, 0xA8, 0x12, 0x0B, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x3F, 0x5D, 0x2D, 0x1C, 0xD4, 0x9E, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x2E, 0xDD, 0xC7, 0x6E, 0xAB, 0xAF, 0xDC), -}; -static const mbedtls_mpi_uint secp384r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB2, 0x7B, 0x0C, 0x9A, 0x83, 0x8E, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x51, 0x90, 0x92, 0x79, 0x32, 0x19, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x89, 0xF9, 0xD0, 0xCF, 0x2C, 0xA5, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x50, 0x21, 0xDE, 0x50, 0x41, 0x9D, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x7D, 0x2B, 0x9E, 0x9D, 0x95, 0xA8, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA5, 0x20, 0x87, 0x88, 0x97, 0x5F, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x59, 0xB4, 0x66, 0x7E, 0xE8, 0x5A, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x5C, 0x7E, 0xB2, 0xAD, 0xD9, 0xC9, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x97, 0x49, 0xA3, 0x13, 0x83, 0x07, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x26, 0xC7, 0x13, 0x35, 0x0D, 0xB0, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x60, 0xAB, 0xFA, 0x4B, 0x93, 0x18, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2D, 0x1C, 0x31, 0x4C, 0xE4, 0x61, 0xAE), -}; -static const mbedtls_mpi_uint secp384r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x4D, 0x1E, 0x51, 0x59, 0x6E, 0x91, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x54, 0x4D, 0x51, 0xED, 0x36, 0xCC, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xA8, 0x56, 0xC7, 0x78, 0x27, 0x33, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB7, 0x95, 0xC9, 0x8B, 0xC8, 0x6A, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xE9, 0x13, 0x96, 0xB3, 0xE1, 0xF9, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x46, 0xB0, 0x5E, 0xC3, 0x94, 0x03, 0x05), -}; -static const mbedtls_mpi_uint secp384r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x5B, 0x29, 0x30, 0x41, 0x1A, 0x9E, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xCA, 0x83, 0x31, 0x5B, 0xA7, 0xCB, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x41, 0x50, 0x44, 0x4D, 0x64, 0x31, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x84, 0xC2, 0x5D, 0x97, 0xA5, 0x3C, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x0F, 0xA5, 0xFD, 0x8E, 0x5A, 0x47, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x58, 0x02, 0x2D, 0x40, 0xB1, 0x0B, 0xBA), -}; -static const mbedtls_mpi_uint secp384r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x33, 0x8C, 0x67, 0xCE, 0x23, 0x43, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x53, 0x47, 0x72, 0x44, 0x1F, 0x5B, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xC1, 0xD9, 0xA4, 0x50, 0x88, 0x63, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xF2, 0x75, 0x69, 0x73, 0x00, 0xC4, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x90, 0x1D, 0xDF, 0x1A, 0x00, 0xD8, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xB1, 0x89, 0x48, 0xA8, 0x70, 0x62, 0xEF), -}; -static const mbedtls_mpi_uint secp384r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x8A, 0x55, 0x50, 0x7B, 0xEF, 0x8A, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1B, 0x23, 0x48, 0x23, 0x63, 0x91, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x04, 0x54, 0x3C, 0x24, 0x9B, 0xC7, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x38, 0xC3, 0x84, 0xFB, 0xFF, 0x9F, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x2A, 0xE0, 0x6D, 0x68, 0x8A, 0x5C, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x93, 0x53, 0x85, 0xA1, 0x0D, 0xAF, 0x63), -}; -static const mbedtls_mpi_uint secp384r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x88, 0x95, 0x4C, 0x0B, 0xD0, 0x06, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xAF, 0x8D, 0x49, 0xA2, 0xC8, 0xB4, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x76, 0x53, 0x09, 0x88, 0x43, 0x87, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA4, 0x77, 0x3F, 0x5E, 0x21, 0xB4, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x9E, 0x86, 0x64, 0xCC, 0x91, 0xC1, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x17, 0x56, 0xCB, 0xC3, 0x7D, 0x5B, 0xB1), -}; -static const mbedtls_mpi_uint secp384r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x74, 0x9F, 0xB5, 0x91, 0x21, 0xB1, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xED, 0xE1, 0x11, 0xEF, 0x45, 0xAF, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x31, 0xBE, 0xB2, 0xBC, 0x72, 0x65, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x4B, 0x8C, 0x77, 0xCE, 0x1E, 0x42, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC9, 0xAA, 0xB9, 0xD9, 0x86, 0x99, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x23, 0x80, 0xC6, 0x4E, 0x35, 0x0B, 0x6D), -}; -static const mbedtls_mpi_uint secp384r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xD8, 0xA2, 0x0A, 0x39, 0x32, 0x1D, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xC8, 0x86, 0xF1, 0x12, 0x9A, 0x4A, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xF1, 0x7C, 0xAA, 0x70, 0x8E, 0xBC, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x01, 0x47, 0x8F, 0xDD, 0x8B, 0xA5, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x08, 0x21, 0xF4, 0xAB, 0xC7, 0xF5, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x76, 0xA5, 0x95, 0xC4, 0x0F, 0x88, 0x1D), -}; -static const mbedtls_mpi_uint secp384r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x42, 0x2A, 0x52, 0xCD, 0x75, 0x51, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x36, 0xE5, 0x04, 0x2B, 0x44, 0xC6, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xEE, 0x16, 0x13, 0x07, 0x83, 0xB5, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x59, 0xC6, 0xA2, 0x19, 0x05, 0xD3, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8B, 0xA8, 0x16, 0x09, 0xB7, 0xEA, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xEE, 0x14, 0xAF, 0xB5, 0xFD, 0xD0, 0xEF), -}; -static const mbedtls_mpi_uint secp384r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x7C, 0xCA, 0x71, 0x3E, 0x6E, 0x66, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x31, 0x0E, 0x3F, 0xE5, 0x91, 0xC4, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x3D, 0xC2, 0x3E, 0x95, 0x37, 0x58, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x1F, 0x02, 0x03, 0xF3, 0xEF, 0xEE, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x5B, 0x1A, 0xFC, 0x38, 0xCD, 0xE8, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x57, 0x42, 0x85, 0xC6, 0x21, 0x68, 0x71), -}; -static const mbedtls_mpi_uint secp384r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA2, 0x4A, 0x66, 0xB1, 0x0A, 0xE6, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x0C, 0x94, 0x9D, 0x5E, 0x99, 0xB2, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x03, 0x40, 0xCA, 0xB2, 0xB3, 0x30, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0x48, 0x27, 0x34, 0x1E, 0xE2, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x72, 0x5B, 0xAC, 0xC1, 0x6D, 0xE3, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAB, 0x46, 0xCB, 0xEA, 0x5E, 0x4B, 0x0B), -}; -static const mbedtls_mpi_uint secp384r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x08, 0xAD, 0x4E, 0x51, 0x9F, 0x2A, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5C, 0x7D, 0x4C, 0xD6, 0xCF, 0xDD, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x76, 0x26, 0xE0, 0x8B, 0x10, 0xD9, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA7, 0x23, 0x4E, 0x5F, 0xD2, 0x42, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xE5, 0xA4, 0xEC, 0x77, 0x21, 0x34, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x14, 0x65, 0xEA, 0x4A, 0x85, 0xC3, 0x2F), -}; -static const mbedtls_mpi_uint secp384r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xD8, 0x40, 0x27, 0x73, 0x15, 0x7E, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xBB, 0x53, 0x7E, 0x0F, 0x40, 0xC8, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x37, 0x19, 0x73, 0xEF, 0x5A, 0x5E, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x73, 0x2B, 0x49, 0x7E, 0xAC, 0x97, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xB2, 0xC3, 0x1E, 0x0E, 0xE7, 0xD2, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x08, 0xD6, 0xDD, 0xAC, 0x21, 0xD6, 0x3E), -}; -static const mbedtls_mpi_uint secp384r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x26, 0xBE, 0x6D, 0x6D, 0xF2, 0x38, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6C, 0x31, 0xA7, 0x49, 0x50, 0x3A, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x99, 0xC6, 0xF5, 0xD2, 0xC2, 0x30, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE4, 0xF6, 0x8B, 0x8B, 0x97, 0xE9, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x21, 0xB7, 0x0D, 0xFC, 0x15, 0x54, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x83, 0x1C, 0xA4, 0xCD, 0x6B, 0x9D, 0xF2), -}; -static const mbedtls_mpi_uint secp384r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE8, 0x4C, 0x48, 0xE4, 0xAA, 0x69, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x7A, 0x27, 0xFC, 0x37, 0x96, 0x1A, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xE7, 0x30, 0xA5, 0xCF, 0x13, 0x46, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xD8, 0xAF, 0x74, 0x23, 0x4D, 0x56, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3D, 0x44, 0x14, 0x1B, 0x97, 0x83, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x47, 0xD7, 0x5F, 0xFD, 0x98, 0x38, 0xF7), -}; -static const mbedtls_mpi_uint secp384r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x73, 0x64, 0x36, 0xFD, 0x7B, 0xC1, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x5D, 0x32, 0xD2, 0x47, 0x94, 0x89, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xE9, 0x30, 0xAC, 0x06, 0xC8, 0x65, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x6C, 0xB9, 0x1B, 0xF7, 0x61, 0x49, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xFF, 0x32, 0x43, 0x80, 0xDA, 0xA6, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF8, 0x04, 0x01, 0x95, 0x35, 0xCE, 0x21), -}; -static const mbedtls_mpi_uint secp384r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x06, 0x46, 0x0D, 0x51, 0xE2, 0xD8, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x57, 0x1D, 0x6F, 0x79, 0xA0, 0xCD, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xFB, 0x36, 0xCA, 0xAD, 0xF5, 0x9E, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x7A, 0x1D, 0x9E, 0x1D, 0x95, 0x48, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x26, 0xA5, 0xB7, 0x15, 0x2C, 0xC2, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x42, 0x72, 0xAA, 0x11, 0xDC, 0xC9, 0xB6), -}; -static const mbedtls_mpi_uint secp384r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x6C, 0x64, 0xA7, 0x62, 0x3C, 0xAB, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x6A, 0x44, 0xD8, 0x60, 0xC0, 0xA8, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x76, 0x58, 0x12, 0x57, 0x3C, 0x89, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x4F, 0x83, 0xCE, 0xCB, 0xB8, 0xD0, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0x04, 0xB0, 0xAD, 0xEB, 0xFA, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA4, 0xC3, 0x41, 0x44, 0x4E, 0x65, 0x3E), -}; -static const mbedtls_mpi_uint secp384r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x16, 0xA9, 0x1C, 0xE7, 0x65, 0x20, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x53, 0x32, 0xF8, 0xC0, 0xA6, 0xBD, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF0, 0xE6, 0x57, 0x31, 0xCC, 0x26, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xE3, 0x54, 0x1C, 0x34, 0xD3, 0x17, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xAE, 0xED, 0xFB, 0xCD, 0xE7, 0x1E, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x16, 0x1C, 0x34, 0x40, 0x00, 0x1F, 0xB6), -}; -static const mbedtls_mpi_uint secp384r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x32, 0x00, 0xC2, 0xD4, 0x3B, 0x1A, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xE0, 0x99, 0x8F, 0x0C, 0x4A, 0x16, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x73, 0x18, 0x1B, 0xD4, 0x94, 0x29, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA4, 0x2D, 0xB1, 0x9D, 0x74, 0x32, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xF4, 0xB1, 0x0C, 0x37, 0x62, 0x8B, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xFF, 0xDA, 0xE2, 0x35, 0xA3, 0xB6, 0x42), -}; -static const mbedtls_mpi_uint secp384r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x49, 0x99, 0x65, 0xC5, 0xED, 0x16, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x42, 0x9A, 0xF3, 0xA7, 0x4E, 0x6F, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x0A, 0x7E, 0xC0, 0xD7, 0x4E, 0x07, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x7A, 0x31, 0x69, 0xA6, 0xB9, 0x15, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xE0, 0x72, 0xA4, 0x3F, 0xB9, 0xF8, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x75, 0x32, 0x85, 0xA2, 0xDE, 0x37, 0x12), -}; -static const mbedtls_mpi_uint secp384r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC0, 0x0D, 0xCF, 0x25, 0x41, 0xA4, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xFC, 0xB2, 0x48, 0xC3, 0x85, 0x83, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBE, 0x0B, 0x58, 0x2D, 0x7A, 0x9A, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xF3, 0x81, 0x18, 0x1B, 0x74, 0x4F, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x43, 0xA3, 0x0A, 0x16, 0x8B, 0xA3, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x18, 0x81, 0x7B, 0x8D, 0xA2, 0x35, 0x77), -}; -static const mbedtls_mpi_uint secp384r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xC4, 0x3F, 0x2C, 0xE7, 0x5F, 0x99, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2B, 0xB7, 0xB6, 0xAD, 0x5A, 0x56, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x00, 0xA4, 0x48, 0xC8, 0xE8, 0xBA, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xA1, 0xB5, 0x13, 0x5A, 0xCD, 0x99, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x95, 0xAD, 0xFC, 0xE2, 0x7E, 0xE7, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x6B, 0xD1, 0x34, 0x99, 0x53, 0x63, 0x0B), -}; -static const mbedtls_mpi_uint secp384r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x8A, 0x77, 0x5D, 0x2B, 0xAB, 0x01, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x85, 0xD0, 0xD5, 0x49, 0x83, 0x4D, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xC6, 0x91, 0x30, 0x3B, 0x00, 0xAF, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x61, 0x07, 0xE1, 0xB6, 0xE2, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x43, 0x41, 0xFE, 0x9B, 0xB6, 0xF0, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x97, 0xAE, 0xAD, 0x89, 0x88, 0x9E, 0x41), -}; -static const mbedtls_ecp_point secp384r1_T[32] = { - ECP_POINT_INIT_XY_Z1(secp384r1_T_0_X, secp384r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_1_X, secp384r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_2_X, secp384r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_3_X, secp384r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_4_X, secp384r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_5_X, secp384r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_6_X, secp384r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_7_X, secp384r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_8_X, secp384r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_9_X, secp384r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_10_X, secp384r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_11_X, secp384r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_12_X, secp384r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_13_X, secp384r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_14_X, secp384r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_15_X, secp384r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_16_X, secp384r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_17_X, secp384r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_18_X, secp384r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_19_X, secp384r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_20_X, secp384r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_21_X, secp384r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_22_X, secp384r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_23_X, secp384r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_24_X, secp384r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_25_X, secp384r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_26_X, secp384r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_27_X, secp384r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_28_X, secp384r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_29_X, secp384r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_30_X, secp384r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_31_X, secp384r1_T_31_Y), -}; -#else -#define secp384r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* - * Domain parameters for secp521r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static const mbedtls_mpi_uint secp521r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), -}; -static const mbedtls_mpi_uint secp521r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95), - MBEDTLS_BYTES_TO_T_UINT_2(0x51, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_2(0xC6, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), - MBEDTLS_BYTES_TO_T_UINT_2(0x18, 0x01), -}; -static const mbedtls_mpi_uint secp521r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp521r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xB1, 0x2D, 0xEB, 0x27, 0x2F, 0xE8, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x4B, 0x44, 0x25, 0xDB, 0x5C, 0x5F, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x85, 0x28, 0x78, 0x2E, 0x75, 0x34, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x57, 0x0F, 0x73, 0x78, 0x7A, 0xE3, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD8, 0xEC, 0xDC, 0xDA, 0x04, 0xAD, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x8A, 0x09, 0xF3, 0x58, 0x79, 0xD8, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x03, 0xCB, 0x50, 0x1A, 0x7F, 0x56, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA6, 0x78, 0x38, 0x85, 0x67, 0x0B, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xD5, 0xD2, 0x22, 0xC4, 0x00, 0x3B, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x93, 0x0E, 0x7B, 0x85, 0x51, 0xC3, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA6, 0x5F, 0x54, 0x49, 0x02, 0x81, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xE9, 0x6B, 0x3A, 0x92, 0xE7, 0x72, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x5F, 0x28, 0x9E, 0x91, 0x27, 0x88, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x28, 0x31, 0xB3, 0x84, 0xCA, 0x12, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xF9, 0xAC, 0x22, 0x10, 0x0A, 0x64, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xC6, 0x33, 0x1F, 0x69, 0x19, 0x18, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x48, 0xB8, 0xC7, 0x37, 0x5A, 0x00, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xCC, 0x32, 0xE0, 0xEE, 0x03, 0xC2, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x29, 0xC2, 0xE4, 0x6E, 0x24, 0x20, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x6B, 0x7F, 0x7B, 0xF9, 0xB0, 0xB8, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x7B, 0x3C, 0xE1, 0x19, 0xA1, 0x23, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE3, 0xC2, 0x53, 0xC0, 0x07, 0x13, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFE, 0x36, 0x35, 0x9F, 0x5E, 0x59, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x55, 0x89, 0x84, 0xBC, 0xEF, 0xA2, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x1A, 0x08, 0x67, 0xB4, 0xE7, 0x22, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x26, 0xDF, 0x81, 0x3C, 0x5F, 0x1C, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x4D, 0xD0, 0x0A, 0x48, 0x06, 0xF4, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x18, 0x39, 0xF7, 0xD1, 0x20, 0x77, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x8F, 0x44, 0x13, 0xCB, 0x78, 0x11, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE2, 0x49, 0xEA, 0x43, 0x79, 0x08, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xD1, 0xD8, 0x73, 0x2C, 0x71, 0x2F, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE5, 0xE7, 0xF4, 0x46, 0xAB, 0x20, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x0B, 0xB9, 0x71, 0x1A, 0x27, 0xB7, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xA2, 0x2C, 0xD1, 0xDA, 0xBC, 0xC1, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xA3, 0x10, 0x1F, 0x90, 0xF2, 0xA5, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xFB, 0x20, 0xF4, 0xC0, 0x70, 0xC0, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xA7, 0x99, 0xF0, 0xA5, 0xD3, 0x09, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xE8, 0x14, 0x39, 0xBE, 0xCB, 0x60, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD6, 0x14, 0xA9, 0xC9, 0x20, 0xC3, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x5B, 0xFD, 0x2D, 0x96, 0xBC, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x04, 0x45, 0xBE, 0xCE, 0x75, 0x95, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xDA, 0x58, 0x49, 0x35, 0x09, 0x8D, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xF0, 0xC0, 0x36, 0xF2, 0xA6, 0x2D, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFC, 0x3D, 0xA8, 0xFB, 0x3C, 0xD2, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x4D, 0x71, 0x09, 0x18, 0x42, 0xF0, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xC1, 0xCE, 0x9E, 0x6A, 0x49, 0x60, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xB1, 0x00, 0xF7, 0xA1, 0x7A, 0x31, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC3, 0x86, 0xCD, 0x20, 0x4A, 0x17, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xAB, 0x8B, 0x47, 0x8D, 0xAA, 0xA6, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x97, 0xF0, 0xBC, 0x2D, 0xDC, 0x9D, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x86, 0xB0, 0x74, 0xB2, 0xF4, 0xF6, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBD, 0xAC, 0xE3, 0x8F, 0x43, 0x5C, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xC3, 0xE2, 0x6E, 0x25, 0x49, 0xCD, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5E, 0x08, 0xB3, 0xB9, 0xAC, 0x5F, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xB7, 0xD1, 0xF4, 0xDC, 0x19, 0xE9, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xE4, 0xFA, 0xE1, 0x36, 0x3E, 0xED, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0x92, 0x84, 0x6E, 0x48, 0x03, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x95, 0xEF, 0x8F, 0xB2, 0x82, 0x6B, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFA, 0xB9, 0x55, 0x23, 0xFE, 0x09, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x79, 0x85, 0x4B, 0x0E, 0xD4, 0x35, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x27, 0x45, 0x81, 0xE0, 0x88, 0x52, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x63, 0xA2, 0x4B, 0xBC, 0x5D, 0xB1, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x8C, 0x83, 0xD9, 0x3E, 0xD3, 0x42, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x03, 0x3A, 0x31, 0xBA, 0xE9, 0x3A, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x10, 0xCD, 0x2D, 0x00, 0xFE, 0x32, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x6E, 0x1F, 0xDA, 0xF8, 0x6F, 0x4D, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x79, 0x7D, 0x09, 0xE5, 0xD3, 0x03, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC3, 0xBE, 0xDF, 0x07, 0x65, 0x49, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0x33, 0xEF, 0xAE, 0x4F, 0x04, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xE9, 0x9B, 0xFE, 0xBF, 0xE6, 0x85, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xBA, 0xAA, 0x06, 0xC4, 0xC6, 0xB8, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x83, 0x01, 0xA9, 0xF6, 0x51, 0xE7, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xA6, 0x15, 0x8E, 0xAB, 0x1F, 0x10, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x08, 0x27, 0x1A, 0xA1, 0x21, 0xAD, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x09, 0x90, 0x6E, 0x50, 0x90, 0x9A, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x9A, 0xFE, 0xD7, 0xA1, 0xF5, 0xA2, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x7D, 0xE3, 0xDC, 0x21, 0xFB, 0xA4, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBF, 0x07, 0xFF, 0x45, 0xDF, 0x51, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x5C, 0x34, 0x02, 0x62, 0x9B, 0x08, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xCE, 0x9A, 0x6A, 0xEC, 0x75, 0xF6, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x59, 0xF4, 0x78, 0x3C, 0x60, 0xB1, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x37, 0x84, 0x6A, 0xDC, 0xF2, 0x9A, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9A, 0x9A, 0x15, 0x36, 0xE0, 0x2B, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x38, 0x9C, 0x50, 0x3D, 0x1E, 0x37, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x79, 0xF0, 0x92, 0xF2, 0x8B, 0x18, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE0, 0x82, 0x1E, 0x80, 0x82, 0x4B, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xBB, 0x59, 0x6B, 0x8A, 0x77, 0x41, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xF9, 0xD4, 0xB8, 0x4A, 0x82, 0xCF, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x8C, 0xC8, 0x9B, 0x72, 0x9E, 0xF7, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xCE, 0xE9, 0x77, 0x0A, 0x19, 0x59, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xA1, 0x41, 0x6A, 0x72, 0x4B, 0xB4, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x35, 0x43, 0xE2, 0x8C, 0xBE, 0x0D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xEB, 0xAD, 0xF3, 0xA9, 0xA6, 0x68, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2F, 0xE2, 0x48, 0x0C, 0xDB, 0x1F, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x1E, 0x60, 0x9B, 0x2A, 0xD2, 0xC1, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x64, 0xB5, 0xD2, 0xF6, 0xF6, 0x6E, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x3D, 0x30, 0x78, 0x10, 0x18, 0x41, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x1D, 0x1C, 0xE0, 0x6D, 0x83, 0xD1, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x03, 0x0B, 0xF5, 0x2F, 0x6C, 0x04, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x3E, 0xD5, 0xFC, 0x31, 0x5B, 0x3A, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x82, 0x2F, 0xFB, 0xFE, 0xF8, 0x76, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x26, 0xDA, 0x9C, 0x36, 0xF5, 0x93, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xE7, 0x6E, 0xD2, 0x7D, 0x81, 0x09, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x03, 0xF9, 0x58, 0x48, 0x24, 0xA2, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x79, 0x0C, 0x8E, 0x6B, 0x95, 0xF3, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x10, 0x5C, 0x87, 0x03, 0x39, 0xCF, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xF0, 0xF7, 0xC1, 0x07, 0xA4, 0xF4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE8, 0x02, 0x89, 0x65, 0xC4, 0x72, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x88, 0xEA, 0x96, 0x67, 0x0B, 0x5D, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x75, 0x60, 0xA8, 0xBD, 0x74, 0xDF, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xE5, 0x71, 0x50, 0x67, 0xD0, 0xD2, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFC, 0xE5, 0xC7, 0x77, 0xB0, 0x7F, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x86, 0x69, 0xCD, 0x0D, 0x9A, 0xBD, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x17, 0xBC, 0xBB, 0x59, 0x85, 0x7D, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA8, 0x76, 0xAC, 0x80, 0xA9, 0x72, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0xC1, 0xE2, 0x4D, 0xAF, 0xF9, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x97, 0x8E, 0x74, 0xC4, 0x4B, 0xB2, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD8, 0xF6, 0xF3, 0xAF, 0x2F, 0x52, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x57, 0xF4, 0xCE, 0xEE, 0x43, 0xED, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x46, 0x38, 0xDE, 0x20, 0xFD, 0x59, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x18, 0xE8, 0x58, 0xB9, 0x76, 0x2C, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x54, 0xE4, 0xFE, 0xC7, 0xBC, 0x31, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF8, 0x89, 0xEE, 0x70, 0xB5, 0xB0, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x22, 0x26, 0x9A, 0x53, 0xB9, 0x38, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xA7, 0x19, 0x8C, 0x74, 0x7E, 0x88, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xDA, 0x0A, 0xE8, 0xDA, 0xA5, 0xBE, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x5C, 0xF7, 0xB1, 0x0C, 0x72, 0xFB, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xE2, 0x23, 0xE7, 0x46, 0xB7, 0xE0, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x36, 0xBC, 0xBD, 0x48, 0x11, 0x8E, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xBB, 0xA1, 0xF7, 0x0B, 0x9E, 0xBF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x28, 0xE1, 0xA2, 0x8F, 0xFC, 0xFC, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xFE, 0x19, 0x0A, 0xE5, 0xE7, 0x69, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xCD, 0x12, 0xF5, 0xBE, 0xD3, 0x04, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA8, 0x0D, 0x81, 0x59, 0xC4, 0x79, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xF3, 0x4B, 0x92, 0x65, 0xC3, 0x31, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xB5, 0x4F, 0x4D, 0x91, 0xD4, 0xE2, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x09, 0x41, 0x79, 0x1D, 0x4D, 0x0D, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x31, 0x18, 0xBA, 0xA0, 0xF2, 0x6E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x5B, 0x4D, 0x4F, 0xAF, 0xC9, 0x8C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x9C, 0x06, 0x68, 0xDE, 0xD8, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x04, 0xE1, 0xB5, 0x9D, 0x00, 0xBC, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x95, 0x92, 0x8D, 0x72, 0xD3, 0x37, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x4B, 0x27, 0xA2, 0xE8, 0xA4, 0x26, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x45, 0x9C, 0xA9, 0xCB, 0x9F, 0xBA, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x7E, 0x1B, 0x64, 0xF4, 0xE8, 0xA5, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x20, 0xA9, 0xCA, 0xF3, 0x89, 0xE5, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xED, 0xFC, 0xAB, 0xD9, 0x0A, 0xB9, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6F, 0x46, 0x7C, 0xCD, 0x78, 0xFF, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAB, 0x71, 0x5A, 0x94, 0xAB, 0x20, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x2E, 0xEE, 0x87, 0x57, 0x1F, 0xAD, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x4C, 0x3D, 0xFB, 0x7E, 0xA1, 0x8B, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xCF, 0x07, 0x86, 0xBA, 0x53, 0x37, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x26, 0xB2, 0xB9, 0xE2, 0x91, 0xE3, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xC9, 0x54, 0x84, 0x08, 0x3D, 0x0B, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x77, 0x2F, 0x64, 0x45, 0x99, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x96, 0x16, 0x1F, 0xDB, 0x96, 0x28, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x2B, 0x8D, 0xFF, 0xA2, 0x4F, 0x55, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE6, 0x48, 0xBD, 0x99, 0x3D, 0x12, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x84, 0x59, 0xDA, 0xB9, 0xB6, 0x66, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x78, 0x41, 0x92, 0xDF, 0xF4, 0x3F, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x86, 0x6F, 0x4F, 0xBF, 0x67, 0xDF, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x2B, 0x1E, 0x5F, 0x00, 0xEA, 0xF6, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xB9, 0x6A, 0x89, 0xD8, 0xC0, 0xD7, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x9A, 0x32, 0x23, 0xA0, 0x02, 0x91, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x7F, 0x6A, 0x15, 0x64, 0x6A, 0x8B, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x57, 0x82, 0x58, 0xA9, 0x56, 0xB5, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x50, 0x92, 0x60, 0xCC, 0x81, 0x24, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x3D, 0xAD, 0xDA, 0xD9, 0x51, 0x3E, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xFE, 0x8F, 0xB0, 0x0B, 0xDE, 0x2E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xD2, 0xBE, 0xEF, 0xAC, 0x76, 0x71, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xE8, 0x72, 0x0B, 0xAC, 0xFE, 0xCA, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0xC7, 0xFC, 0xE3, 0x3C, 0x7C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x04, 0xA7, 0xB9, 0x9B, 0x93, 0xC0, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x48, 0x4B, 0x8E, 0x32, 0xC5, 0xF0, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x42, 0x07, 0xC1, 0xF2, 0xF1, 0x72, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x37, 0x54, 0x9C, 0x88, 0xD2, 0x62, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x19, 0x8A, 0x89, 0x58, 0xA2, 0x0F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xCC, 0x4C, 0x97, 0x30, 0x66, 0x34, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x6A, 0x1E, 0x1F, 0xDB, 0xC9, 0x5E, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x4D, 0x49, 0xFF, 0x9B, 0x9C, 0xAC, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xE4, 0x4B, 0xF2, 0xD4, 0x1A, 0xD2, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xDA, 0xE8, 0x61, 0x9F, 0xC8, 0x49, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xCB, 0xF2, 0x2D, 0x85, 0xF6, 0x8D, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xC5, 0xCD, 0x2C, 0x79, 0xC6, 0x0E, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x1D, 0x55, 0x0F, 0xF8, 0x22, 0x9F, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x56, 0xBA, 0xE7, 0x57, 0x32, 0xEC, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x9A, 0xC6, 0x4C, 0x09, 0xC4, 0x52, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x1E, 0x6F, 0xF4, 0x7D, 0x27, 0xDD, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x11, 0x16, 0xEC, 0x79, 0x83, 0xAD, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x4E, 0x92, 0x1F, 0x19, 0x7D, 0x65, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xFF, 0x78, 0x15, 0x45, 0x63, 0x32, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x91, 0xD0, 0x78, 0x58, 0xDA, 0x50, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xDE, 0x40, 0xF6, 0x41, 0xB4, 0x3B, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x8D, 0xE0, 0xE1, 0xA9, 0xF0, 0x35, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xD4, 0xBA, 0x7B, 0xCC, 0x1B, 0x3A, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x5A, 0x2E, 0x74, 0x47, 0x14, 0xC3, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xF0, 0x8B, 0x06, 0x15, 0x8E, 0x0E, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xD2, 0xEB, 0x97, 0x50, 0x7D, 0x31, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x93, 0x4C, 0xDB, 0x97, 0x79, 0x44, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xA2, 0xA0, 0x0B, 0xC8, 0x3A, 0x8A, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x50, 0x92, 0x9E, 0x24, 0x1F, 0xCB, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x16, 0xC9, 0xC5, 0x3D, 0x5A, 0xAF, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xE3, 0x97, 0xE4, 0xA8, 0x50, 0xF6, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x57, 0x97, 0x42, 0x78, 0x92, 0x49, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEB, 0x62, 0x24, 0xFB, 0x8F, 0x32, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x0C, 0x36, 0x6E, 0x8F, 0xE8, 0xE8, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xD3, 0x7C, 0xC7, 0x8D, 0x3F, 0x5C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x64, 0x6A, 0x73, 0x10, 0x79, 0xB8, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xF9, 0xEF, 0xA5, 0x20, 0x4A, 0x5C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xF3, 0xF4, 0x49, 0x5B, 0x73, 0xAA, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xF2, 0xEA, 0x0F, 0x00, 0xAD, 0x53, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xB8, 0x66, 0xED, 0xC4, 0x2B, 0x4C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x2F, 0xC1, 0x9A, 0x37, 0xD2, 0x7F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA7, 0x81, 0x38, 0x64, 0xC9, 0x37, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x3B, 0x6C, 0x9F, 0x5B, 0xD9, 0x8B, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x14, 0xD9, 0x08, 0xD8, 0xD2, 0x7E, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x71, 0xE6, 0x3D, 0xD1, 0xB0, 0xE7, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x81, 0x23, 0xEC, 0x2D, 0x42, 0x45, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x5B, 0x44, 0x6B, 0x89, 0x03, 0x67, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x27, 0xAE, 0x80, 0x5A, 0x33, 0xBE, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB6, 0x64, 0x1A, 0xDF, 0xD3, 0x85, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x8C, 0x22, 0xBA, 0xD0, 0xBD, 0xCC, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x3C, 0x01, 0x3A, 0xFF, 0x9D, 0xC7, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC7, 0x64, 0xB4, 0x59, 0x4E, 0x9F, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x34, 0x0A, 0x41, 0x94, 0xA8, 0xF2, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD4, 0xE4, 0xF0, 0x97, 0x45, 0x6D, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x1F, 0x4D, 0x6D, 0xFE, 0xA0, 0xC4, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x28, 0x5C, 0x40, 0xBB, 0x65, 0xD4, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xA8, 0x87, 0x35, 0x20, 0x3A, 0x89, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFD, 0x4F, 0xAB, 0x2D, 0xD1, 0xD0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE8, 0x00, 0xFC, 0x69, 0x52, 0xF8, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x9A, 0x99, 0xE1, 0xDC, 0x9C, 0x3F, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x08, 0x98, 0xD9, 0xCA, 0x73, 0xD5, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x2C, 0xE0, 0xA7, 0x3E, 0x91, 0xD7, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x04, 0xB0, 0x54, 0x09, 0xF4, 0x72, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xEE, 0x28, 0xCC, 0xE8, 0x50, 0x78, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x91, 0x03, 0x76, 0xDB, 0x68, 0x24, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xE0, 0x56, 0xB2, 0x5D, 0x12, 0xD3, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x42, 0x59, 0x8B, 0xDF, 0x67, 0xB5, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xCC, 0xE5, 0x31, 0x53, 0x7A, 0x46, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8D, 0x59, 0xB5, 0x1B, 0x0F, 0xF4, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x2F, 0xD1, 0x2C, 0xE0, 0xD8, 0x04, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0xD7, 0xBA, 0xB0, 0xA3, 0x7E, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x08, 0x51, 0x56, 0xA6, 0x76, 0x67, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x17, 0x63, 0xFE, 0x56, 0xD0, 0xD9, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xF6, 0xC3, 0x14, 0x47, 0xC5, 0xA7, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x4C, 0x80, 0xF6, 0xA2, 0x57, 0xA7, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xB3, 0x7B, 0xF8, 0x2F, 0xE1, 0x3E, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xF4, 0xF9, 0x6B, 0x7B, 0x90, 0xDF, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x82, 0xEF, 0x62, 0xA1, 0x4C, 0x53, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x99, 0x76, 0x01, 0xBA, 0x8D, 0x0F, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xF4, 0x58, 0x73, 0x56, 0xFE, 0xDD, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xCE, 0xF9, 0xE8, 0xA1, 0x34, 0xC3, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x5F, 0xDC, 0x6A, 0x3D, 0xD8, 0x7F, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xF4, 0x51, 0xB8, 0xB8, 0xC1, 0xD7, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x7D, 0x58, 0xD1, 0xD4, 0x1B, 0x4D, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x95, 0xDF, 0x00, 0xD8, 0x21, 0xDE, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x47, 0x3C, 0xC3, 0xB2, 0x01, 0x53, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x17, 0x43, 0x23, 0xBD, 0xCA, 0x71, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xBA, 0x0F, 0x4F, 0xDC, 0x41, 0x54, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x39, 0x26, 0x70, 0x53, 0x32, 0x18, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x46, 0x07, 0x97, 0x3A, 0x57, 0xE0, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x92, 0x4F, 0xCE, 0xDF, 0x25, 0x80, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x6F, 0x9A, 0x03, 0x05, 0x4B, 0xD1, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x01, 0x72, 0x30, 0x90, 0x17, 0x51, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xFB, 0x41, 0x65, 0x5C, 0xB4, 0x2D, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xCD, 0xCD, 0xAA, 0x41, 0xCC, 0xBB, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xCE, 0x08, 0x0A, 0x63, 0xE9, 0xA2, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA8, 0x21, 0x7F, 0x7A, 0x5B, 0x9B, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x6B, 0x89, 0x44, 0x0A, 0x7F, 0x85, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xDE, 0x7C, 0x19, 0x5C, 0x65, 0x26, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xAC, 0x62, 0x29, 0x4A, 0xF1, 0xD0, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x00, 0x40, 0x87, 0xEB, 0xA9, 0x58, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x51, 0x0B, 0xFF, 0x56, 0x35, 0x51, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xAC, 0x08, 0x94, 0x71, 0xDA, 0xEC, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x4D, 0xC5, 0x7B, 0x31, 0x8B, 0x8D, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x05, 0xF1, 0x3E, 0x9E, 0x8F, 0x17, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x9C, 0x4B, 0x62, 0x94, 0xAD, 0x49, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC9, 0xC6, 0x8F, 0xFD, 0x33, 0x44, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x96, 0x17, 0x7F, 0x42, 0xBE, 0xF7, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x29, 0x39, 0x13, 0x08, 0x8D, 0x91, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x79, 0xF9, 0x2F, 0xA9, 0x0A, 0xCF, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x87, 0x7A, 0xA3, 0x19, 0xAB, 0x55, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x0B, 0x01, 0xC5, 0x56, 0x19, 0x9D, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xDE, 0x82, 0x3B, 0xEA, 0xD3, 0x0B, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x6B, 0xC7, 0xF3, 0x0F, 0x82, 0x87, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x2E, 0x23, 0xF2, 0x39, 0x9D, 0x49, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xDE, 0xAF, 0x7A, 0xEE, 0xB0, 0xDA, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x4E, 0x2A, 0x50, 0xFD, 0x8E, 0xC0, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x0F, 0x7C, 0x76, 0x63, 0xD8, 0x89, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x2D, 0xB9, 0x4E, 0xF4, 0xEE, 0x85, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x95, 0x5C, 0x96, 0x5D, 0xAA, 0x59, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xDB, 0xD2, 0x68, 0x8E, 0x5A, 0x94, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x02, 0xBF, 0x77, 0x9F, 0xB9, 0x4C, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xDC, 0xC0, 0xCF, 0x81, 0x1E, 0xC4, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xCC, 0x37, 0x86, 0xDC, 0xE2, 0x64, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x30, 0xB1, 0x59, 0x20, 0x9D, 0x98, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x0C, 0x9D, 0xF8, 0x20, 0xDC, 0x90, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xA0, 0xF4, 0xE7, 0x3E, 0x9C, 0x9E, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x25, 0xA2, 0xB0, 0x54, 0xCD, 0x2E, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD9, 0x42, 0xB0, 0x80, 0xB0, 0xA3, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xFE, 0x9D, 0x8D, 0x40, 0xFF, 0x27, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9D, 0xA6, 0x88, 0x3A, 0x8B, 0x6F, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x39, 0xEE, 0x1F, 0x3F, 0xB1, 0x4F, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD7, 0x9E, 0xFF, 0xD2, 0x35, 0x67, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x4F, 0x15, 0x5D, 0xE3, 0xE8, 0x53, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF7, 0x24, 0x98, 0xA2, 0xCB, 0x11, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x2E, 0x25, 0xE1, 0x94, 0xC5, 0xA3, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x82, 0x6E, 0xBA, 0xE7, 0x43, 0x25, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x65, 0xB4, 0x49, 0x73, 0x18, 0x35, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x5B, 0xBC, 0x62, 0x86, 0x4C, 0xC1, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xF2, 0x95, 0xA2, 0xBB, 0xA2, 0x35, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x59, 0x62, 0xB0, 0x4B, 0x1E, 0xB4, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x55, 0xCE, 0xB0, 0x69, 0xBA, 0x63, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x69, 0x86, 0xDB, 0x34, 0x7D, 0x68, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x06, 0xCA, 0x55, 0x44, 0x36, 0x2B, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xD4, 0xC4, 0x3D, 0xCD, 0x9E, 0x69, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x44, 0xE4, 0xBF, 0x31, 0xE6, 0x40, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x4F, 0xFA, 0x75, 0xE3, 0xFB, 0x97, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xC0, 0xBD, 0x1C, 0x48, 0xB0, 0x26, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x7B, 0x32, 0xFA, 0xF2, 0x6D, 0x84, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x21, 0x03, 0x1D, 0x0D, 0x22, 0x55, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xF9, 0x42, 0x03, 0x9C, 0xC2, 0xCB, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xA1, 0x96, 0xD9, 0x9D, 0x11, 0x6F, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x40, 0x57, 0xEB, 0x40, 0x2D, 0xC0, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x96, 0xBB, 0x4F, 0x2F, 0x23, 0xA8, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x29, 0x85, 0x21, 0xA5, 0x50, 0x62, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x7D, 0x92, 0xCF, 0x87, 0x0C, 0x22, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x0E, 0xA5, 0x32, 0x5B, 0xDF, 0x9C, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x96, 0x37, 0x2C, 0x88, 0x35, 0x30, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xB4, 0x69, 0xFF, 0xEB, 0xC6, 0x94, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x55, 0x60, 0xAD, 0xAA, 0x58, 0x14, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xFF, 0xF2, 0xB2, 0xD5, 0xA7, 0xD9, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xAE, 0x54, 0xD2, 0x60, 0x31, 0xF3, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x92, 0x83, 0xE3, 0xF1, 0x42, 0x83, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD2, 0xC8, 0xB7, 0x76, 0x45, 0x7F, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x11, 0xA4, 0xFB, 0x7A, 0x01, 0xBC, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x27, 0x73, 0x8D, 0x02, 0x91, 0x27, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x62, 0xF6, 0xDD, 0x6B, 0xFA, 0x5B, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCA, 0xA2, 0x44, 0x2C, 0xF0, 0x28, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xF1, 0x7A, 0xA2, 0x42, 0x4C, 0x50, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x83, 0x3E, 0x50, 0xAB, 0x9C, 0xF7, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xED, 0x78, 0xCB, 0x76, 0x69, 0xDA, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x1E, 0x43, 0x27, 0x47, 0x6E, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x4F, 0x54, 0xB9, 0x3E, 0xBD, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x40, 0x69, 0x7F, 0x74, 0x9D, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x06, 0x6F, 0x67, 0x68, 0x2B, 0x4D, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x65, 0x41, 0xFC, 0x7C, 0x1E, 0xE8, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x79, 0x37, 0xAF, 0xFD, 0xD2, 0xDA, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xA8, 0x69, 0x56, 0x62, 0xA4, 0xE4, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x71, 0x73, 0x21, 0x8A, 0x17, 0x81, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x55, 0x8F, 0x7B, 0xB8, 0xAF, 0xF7, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xD1, 0xBD, 0xBE, 0x8C, 0xBC, 0x60, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA6, 0x57, 0x8C, 0xAE, 0x5C, 0x19, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x43, 0xE4, 0xD9, 0xD8, 0x7B, 0xE7, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xB9, 0xE4, 0x85, 0x7C, 0x2E, 0xFC, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2E, 0x01, 0x2A, 0x6D, 0x56, 0xBE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x0C, 0x25, 0x9B, 0xAE, 0x86, 0x37, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x22, 0xB3, 0xCB, 0x99, 0x66, 0xB7, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xF7, 0x90, 0xF0, 0x1B, 0x09, 0x27, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x16, 0x08, 0xEF, 0x39, 0x64, 0x49, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA0, 0xE3, 0x97, 0xA9, 0x07, 0x54, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xFF, 0xE2, 0x00, 0x07, 0x21, 0x88, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFD, 0x59, 0x53, 0x05, 0x6C, 0x42, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xF7, 0x39, 0x5C, 0x82, 0x36, 0xE8, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x83, 0xA8, 0xE2, 0xA8, 0x43, 0x07, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xAF, 0x2B, 0x79, 0xED, 0xD8, 0x39, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x20, 0x91, 0x7A, 0xC4, 0x07, 0xEF, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x2F, 0xAA, 0x0C, 0x94, 0x0E, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x81, 0x87, 0x41, 0x23, 0xEB, 0x55, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x53, 0xCC, 0x79, 0xB6, 0xEB, 0x6C, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x77, 0x73, 0x9D, 0xFC, 0x64, 0x6F, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x40, 0xE3, 0x6D, 0x1C, 0x16, 0x71, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xF4, 0x1B, 0xFF, 0x1C, 0x2F, 0xA5, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x0E, 0x0B, 0x11, 0xF4, 0x8D, 0x93, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC5, 0x64, 0x6F, 0x24, 0x19, 0xF2, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xB3, 0xAF, 0xA5, 0x0E, 0x4F, 0x5E, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x77, 0xCA, 0xF2, 0x6D, 0xC5, 0xF6, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x18, 0x8E, 0x33, 0x68, 0x6C, 0xE8, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x8B, 0x80, 0x90, 0x19, 0x7F, 0x90, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x80, 0x6B, 0x68, 0xE2, 0x7D, 0xD4, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC1, 0x67, 0xB3, 0x72, 0xCB, 0xBF, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xD5, 0xD3, 0x1D, 0x14, 0x58, 0x0A, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x7A, 0x65, 0x98, 0xB3, 0x07, 0x4B, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x87, 0x0F, 0x5F, 0xCF, 0xA2, 0x01, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC9, 0xC8, 0x6E, 0x35, 0x87, 0xA5, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x3E, 0x91, 0xA0, 0xAB, 0x24, 0x1E, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBC, 0x02, 0x35, 0x70, 0xC1, 0x5F, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x59, 0xA0, 0x50, 0x04, 0x80, 0x52, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x56, 0x6E, 0x42, 0x8F, 0x8C, 0x91, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xA2, 0xCB, 0xA5, 0xDE, 0x14, 0x24, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xCB, 0x74, 0x28, 0xE6, 0xA7, 0xE7, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x73, 0xA8, 0x8F, 0x9E, 0x0E, 0x63, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x1B, 0x77, 0xC7, 0xC1, 0x38, 0xF9, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x3C, 0xCF, 0xA8, 0x7A, 0xD7, 0xF3, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x5F, 0x9A, 0xC9, 0xAD, 0xE9, 0x1A, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0x2B, 0x5E, 0xD5, 0x81, 0x95, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x88, 0x75, 0x29, 0x1F, 0xC7, 0xC7, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA9, 0x5A, 0x4D, 0x63, 0x95, 0xF9, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xCD, 0x04, 0x8F, 0xCD, 0x91, 0xDE, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xD4, 0xFD, 0x25, 0x11, 0x99, 0x6E, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x83, 0x01, 0x3D, 0xFB, 0x56, 0xA5, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x3A, 0xDC, 0x74, 0xC2, 0xD7, 0xCF, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xBD, 0xF1, 0xDD, 0xA3, 0x07, 0x03, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xBE, 0xE9, 0x2E, 0x58, 0x84, 0x66, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x20, 0x78, 0x37, 0x79, 0x0B, 0xA6, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xF2, 0xAC, 0x65, 0xC8, 0xC9, 0x2F, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x93, 0xE5, 0x0D, 0x0C, 0xC6, 0xB8, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAD, 0x5C, 0x19, 0x12, 0x61, 0x0E, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x4F, 0x0B, 0x1F, 0x49, 0x7E, 0xCD, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2E, 0x30, 0x61, 0xDB, 0x08, 0x68, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x78, 0xAF, 0xB3, 0x08, 0xC1, 0x69, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x5F, 0x5D, 0xC1, 0x57, 0x6F, 0xD8, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xD3, 0x6A, 0xF7, 0xFD, 0x86, 0xE5, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x63, 0xBD, 0x70, 0x7B, 0x47, 0xE8, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x62, 0xC8, 0x7E, 0x9D, 0x11, 0x2B, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x84, 0xFD, 0xD5, 0x9A, 0x56, 0x7F, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBB, 0xA4, 0x6F, 0x12, 0x6E, 0x4D, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x08, 0xA1, 0x82, 0x9C, 0x62, 0x74, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x22, 0x05, 0x1D, 0x15, 0x35, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x88, 0xCF, 0x5C, 0x05, 0x78, 0xFB, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x6B, 0x2F, 0x79, 0x09, 0x73, 0x67, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA0, 0x80, 0xD8, 0xE8, 0xEC, 0xFB, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0B, 0xB7, 0x81, 0x48, 0x7B, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x53, 0xA9, 0xED, 0x61, 0x92, 0xD7, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x49, 0xD9, 0x5D, 0x9B, 0x4E, 0x89, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x12, 0xEB, 0x9A, 0xC9, 0xCB, 0xC1, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xDC, 0x95, 0x16, 0xFE, 0x29, 0x70, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x33, 0xB1, 0xD6, 0x78, 0xB9, 0xE2, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xCE, 0x88, 0xC3, 0xFD, 0x7A, 0x6B, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x1E, 0x50, 0x1E, 0xAF, 0xB1, 0x25, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xE7, 0xD7, 0xD5, 0xBD, 0x7A, 0x12, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xAA, 0xA2, 0x80, 0x5D, 0x8F, 0xCD, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x39, 0x79, 0x64, 0xA1, 0x67, 0x3C, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xC7, 0x49, 0xFF, 0x7F, 0xAC, 0xAB, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x54, 0x3E, 0x83, 0xF0, 0x3D, 0xBC, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x92, 0x4A, 0x38, 0x42, 0x8A, 0xAB, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x0B, 0x4F, 0xEE, 0x9E, 0x92, 0xA5, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xDD, 0x19, 0x96, 0xF2, 0xF0, 0x6B, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xFC, 0xDD, 0xB2, 0x8A, 0xE5, 0x4C, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x06, 0x49, 0xAC, 0x99, 0x7E, 0xF8, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xC8, 0x01, 0x51, 0xEA, 0xF6, 0x52, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x89, 0x66, 0x2B, 0x1F, 0x9B, 0x2A, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x0F, 0x95, 0x07, 0x2B, 0x6C, 0x6E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC3, 0xB4, 0xBB, 0x91, 0x1F, 0xA3, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x6E, 0x54, 0x28, 0x7B, 0x9C, 0x79, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x45, 0xFF, 0xA6, 0xDA, 0xA2, 0x83, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xDE, 0x8F, 0x17, 0x37, 0x82, 0xCB, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x94, 0x3F, 0x26, 0xC9, 0x1D, 0xD9, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x28, 0x20, 0xCD, 0xC1, 0xF3, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC9, 0xB5, 0x60, 0x9B, 0x1E, 0xDC, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xB9, 0x5B, 0x7D, 0xA0, 0xB2, 0x8C, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xD1, 0x42, 0xE6, 0x39, 0x33, 0x6D, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xC0, 0xFC, 0xD2, 0x14, 0x5D, 0x3E, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x4A, 0x3E, 0x40, 0x16, 0x93, 0x15, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x24, 0xC1, 0x27, 0x27, 0xE5, 0x4B, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x50, 0xD8, 0xBC, 0xC1, 0x46, 0x22, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x0E, 0x60, 0xA1, 0xB3, 0x50, 0xD4, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xB1, 0x26, 0xB6, 0x6D, 0x47, 0x5A, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0xAC, 0x11, 0x35, 0x3E, 0xB9, 0xF4, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x97, 0xFA, 0xBB, 0x6B, 0x39, 0x13, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x34, 0x12, 0x75, 0x8E, 0x9B, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x9E, 0xCD, 0x29, 0xB6, 0xEF, 0x8D, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xAC, 0xE9, 0x25, 0x27, 0xBB, 0x78, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x7A, 0xA8, 0xD3, 0xE3, 0x66, 0xE5, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x4C, 0xC4, 0x2C, 0x76, 0x81, 0x50, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x71, 0x08, 0xB8, 0x52, 0x7C, 0xAF, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x59, 0x24, 0xDD, 0xFB, 0x2F, 0xD0, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCD, 0x56, 0xE9, 0xAC, 0x91, 0xE6, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x64, 0x20, 0xC6, 0x9F, 0xE4, 0xEF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x2C, 0x8F, 0x8C, 0x97, 0xF6, 0x22, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0x88, 0xAA, 0xA8, 0xD7, 0xA5, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x6C, 0xAE, 0x83, 0xB1, 0x55, 0x55, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x67, 0x84, 0x47, 0x7C, 0x83, 0x5C, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x10, 0x4D, 0xDD, 0x30, 0x60, 0xB0, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xA7, 0x36, 0x76, 0x24, 0x32, 0x9F, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x42, 0x81, 0xFB, 0xA4, 0x2E, 0x13, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x94, 0x91, 0xFF, 0x99, 0xA0, 0x09, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x83, 0xA1, 0x76, 0xAF, 0x37, 0x5C, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA8, 0x04, 0x86, 0xC4, 0xA9, 0x79, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8C, 0xC2, 0x34, 0xFB, 0x83, 0x28, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x03, 0x7D, 0x5E, 0x9E, 0x0E, 0xB0, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x02, 0x46, 0x7F, 0xB9, 0xAC, 0xBB, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xED, 0x48, 0xC2, 0x96, 0x4D, 0x56, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xC5, 0xD1, 0xE6, 0x1C, 0x7E, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x2E, 0x18, 0x71, 0x2D, 0x7B, 0xD7, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x46, 0x9D, 0xDE, 0xAA, 0x78, 0x8E, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD7, 0x69, 0x2E, 0xE1, 0xD9, 0x48, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFF, 0x9E, 0x09, 0x22, 0x22, 0xE6, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x14, 0x28, 0x13, 0x1B, 0x62, 0x12, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x7F, 0x67, 0x03, 0xB0, 0xC0, 0xF3, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xC3, 0x0F, 0xFB, 0x25, 0x48, 0x3E, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x6E, 0x53, 0x98, 0x36, 0xB3, 0xD3, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x81, 0x54, 0x22, 0xA4, 0xCC, 0xC1, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xBA, 0xFC, 0xA9, 0xDF, 0x68, 0x86, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x92, 0x0E, 0xC3, 0xF2, 0x58, 0xE8, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp521r1_T[32] = { - ECP_POINT_INIT_XY_Z1(secp521r1_T_0_X, secp521r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_1_X, secp521r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_2_X, secp521r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_3_X, secp521r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_4_X, secp521r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_5_X, secp521r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_6_X, secp521r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_7_X, secp521r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_8_X, secp521r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_9_X, secp521r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_10_X, secp521r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_11_X, secp521r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_12_X, secp521r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_13_X, secp521r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_14_X, secp521r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_15_X, secp521r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_16_X, secp521r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_17_X, secp521r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_18_X, secp521r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_19_X, secp521r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_20_X, secp521r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_21_X, secp521r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_22_X, secp521r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_23_X, secp521r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_24_X, secp521r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_25_X, secp521r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_26_X, secp521r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_27_X, secp521r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_28_X, secp521r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_29_X, secp521r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_30_X, secp521r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_31_X, secp521r1_T_31_Y), -}; -#else -#define secp521r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static const mbedtls_mpi_uint secp192k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp192k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp192k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x03, 0x00), -}; -static const mbedtls_mpi_uint secp192k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), -}; -static const mbedtls_mpi_uint secp192k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), -}; -static const mbedtls_mpi_uint secp192k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp192k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), -}; -static const mbedtls_mpi_uint secp192k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), -}; -static const mbedtls_mpi_uint secp192k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x77, 0x3D, 0x0D, 0x85, 0x48, 0xA8, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x07, 0xDF, 0x1D, 0xB3, 0xB3, 0x01, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x86, 0xF6, 0xAF, 0x19, 0x2A, 0x88, 0x2E), -}; -static const mbedtls_mpi_uint secp192k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x90, 0xB6, 0x2F, 0x48, 0x36, 0x4C, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x11, 0x14, 0xA6, 0xCB, 0xBA, 0x15, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB0, 0xF2, 0xD4, 0xC9, 0xDA, 0xBA, 0xD7), -}; -static const mbedtls_mpi_uint secp192k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xC1, 0x9C, 0xE6, 0xBB, 0xFB, 0xCF, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x19, 0xAC, 0x5A, 0xC9, 0x8A, 0x1C, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xF6, 0x76, 0x86, 0x89, 0x27, 0x8D, 0x28), -}; -static const mbedtls_mpi_uint secp192k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xE0, 0x6F, 0x34, 0xBA, 0x5E, 0xD3, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xDC, 0xA6, 0x87, 0xC9, 0x9D, 0xC0, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x11, 0x7E, 0xD6, 0xF7, 0x33, 0xFC, 0xE4), -}; -static const mbedtls_mpi_uint secp192k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x37, 0x3E, 0xC0, 0x7F, 0x62, 0xE7, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3B, 0x69, 0x9D, 0x44, 0xBC, 0x82, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x84, 0xB3, 0x5F, 0x2B, 0xA5, 0x9E, 0x2C), -}; -static const mbedtls_mpi_uint secp192k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x95, 0xEB, 0x4C, 0x04, 0xB4, 0xF4, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAD, 0x4B, 0xD5, 0x9A, 0xEB, 0xC4, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xB1, 0xC5, 0x59, 0xE3, 0xD5, 0x16, 0x2A), -}; -static const mbedtls_mpi_uint secp192k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x2A, 0xCC, 0xAC, 0xD0, 0xEE, 0x50, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x83, 0xE0, 0x5B, 0x14, 0x44, 0x52, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x15, 0x2D, 0x78, 0xF6, 0x51, 0x32, 0xCF), -}; -static const mbedtls_mpi_uint secp192k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x36, 0x9B, 0xDD, 0xF8, 0xDD, 0xEF, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xB1, 0x6A, 0x2B, 0xAF, 0xEB, 0x2B, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x87, 0x7A, 0x66, 0x5D, 0x5B, 0xDF, 0x8F), -}; -static const mbedtls_mpi_uint secp192k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x45, 0xE5, 0x81, 0x9B, 0xEB, 0x37, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x29, 0xE2, 0x20, 0x64, 0x23, 0x6B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1D, 0x41, 0xE1, 0x9B, 0x61, 0x7B, 0xD9), -}; -static const mbedtls_mpi_uint secp192k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x57, 0xA3, 0x0A, 0x13, 0xE4, 0x59, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x6E, 0x4A, 0x48, 0x84, 0x90, 0xAC, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB8, 0xF5, 0xF3, 0xDE, 0xA0, 0xA1, 0x1D), -}; -static const mbedtls_mpi_uint secp192k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x32, 0x81, 0xA9, 0x91, 0x5A, 0x4E, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xA8, 0x90, 0xBE, 0x0F, 0xEC, 0xC0, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x30, 0xD7, 0x08, 0xAE, 0xC4, 0x3A, 0xA5), -}; -static const mbedtls_mpi_uint secp192k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x55, 0xE3, 0x76, 0xB3, 0x64, 0x74, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x75, 0xD4, 0xDB, 0x98, 0xD7, 0x39, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xEB, 0x8A, 0xAB, 0x16, 0xD9, 0xD4, 0x0B), -}; -static const mbedtls_mpi_uint secp192k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xBE, 0xF9, 0xC7, 0xC7, 0xBA, 0xF3, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x85, 0x59, 0xF3, 0x60, 0x41, 0x02, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x1C, 0x4A, 0xA4, 0xC7, 0xED, 0x66, 0xBC), -}; -static const mbedtls_mpi_uint secp192k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x2E, 0x46, 0x52, 0x18, 0x87, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x35, 0x5A, 0x75, 0xAC, 0x4D, 0x75, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x2F, 0xAC, 0xFC, 0xBC, 0xE6, 0x93, 0x5E), -}; -static const mbedtls_mpi_uint secp192k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x4D, 0xC9, 0x18, 0xE9, 0x00, 0xEB, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x69, 0x72, 0x07, 0x5A, 0x59, 0xA8, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x65, 0x83, 0x20, 0x10, 0xF9, 0x69, 0x82), -}; -static const mbedtls_mpi_uint secp192k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x56, 0x7F, 0x9F, 0xBF, 0x46, 0x0C, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0xF0, 0xDC, 0xDF, 0x2D, 0xE6, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xF0, 0x72, 0x3A, 0x7A, 0x03, 0xE5, 0x22), -}; -static const mbedtls_mpi_uint secp192k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xAA, 0x57, 0x13, 0x37, 0xA7, 0x2C, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xAC, 0xA2, 0x23, 0xF9, 0x84, 0x60, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xEB, 0x51, 0x70, 0x64, 0x78, 0xCA, 0x05), -}; -static const mbedtls_mpi_uint secp192k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xCC, 0x30, 0x62, 0x93, 0x46, 0x13, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x26, 0xCC, 0x6C, 0x3D, 0x5C, 0xDA, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xAA, 0xB8, 0x03, 0xA4, 0x1A, 0x00, 0x96), -}; -static const mbedtls_mpi_uint secp192k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x9D, 0xE6, 0xCC, 0x4E, 0x2E, 0xC2, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xC3, 0x8A, 0xAE, 0x6F, 0x40, 0x05, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x8F, 0x4A, 0x4D, 0x35, 0xD3, 0x50, 0x9D), -}; -static const mbedtls_mpi_uint secp192k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xFD, 0x98, 0xAB, 0xC7, 0x03, 0xB4, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x40, 0xD2, 0x9F, 0xCA, 0xD0, 0x53, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x84, 0x00, 0x6F, 0xC8, 0xAD, 0xED, 0x8D), -}; -static const mbedtls_mpi_uint secp192k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xD3, 0x57, 0xD7, 0xC3, 0x07, 0xBD, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xBA, 0x47, 0x1D, 0x3D, 0xEF, 0x98, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC0, 0x6C, 0x7F, 0x12, 0xEE, 0x9F, 0x67), -}; -static const mbedtls_mpi_uint secp192k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x02, 0xDA, 0x79, 0xAA, 0xC9, 0x27, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x79, 0xC7, 0x71, 0x84, 0xCB, 0xE5, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x37, 0x06, 0xBA, 0xB5, 0xD5, 0x18, 0x4C), -}; -static const mbedtls_mpi_uint secp192k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x65, 0x72, 0x6C, 0xF2, 0x63, 0x27, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xBC, 0x71, 0xDF, 0x75, 0xF8, 0x98, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x70, 0x9B, 0xDC, 0xE7, 0x18, 0x71, 0xFF), -}; -static const mbedtls_mpi_uint secp192k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x5B, 0x9F, 0x00, 0x5A, 0xB6, 0x80, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE0, 0xBB, 0xFC, 0x5E, 0x78, 0x9C, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x03, 0x68, 0x83, 0x3D, 0x2E, 0x4C, 0xDD), -}; -static const mbedtls_mpi_uint secp192k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x49, 0x23, 0xA8, 0xCB, 0x3B, 0x1A, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x3D, 0xA7, 0x46, 0xCF, 0x75, 0xB6, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xFD, 0x30, 0x01, 0xB6, 0xEF, 0xF9, 0xE8), -}; -static const mbedtls_mpi_uint secp192k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xFA, 0xDA, 0xB8, 0x29, 0x42, 0xC9, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xD7, 0xA0, 0xE6, 0x6B, 0x86, 0x61, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xE9, 0xD3, 0x37, 0xD8, 0xE7, 0x35, 0xA9), -}; -static const mbedtls_mpi_uint secp192k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC8, 0x8E, 0xB1, 0xCB, 0xB1, 0xB5, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xD7, 0x46, 0x7D, 0xAF, 0xE2, 0xDC, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x46, 0xE7, 0xD8, 0x76, 0x31, 0x90, 0x76), -}; -static const mbedtls_mpi_uint secp192k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD3, 0xF4, 0x74, 0xE1, 0x67, 0xD8, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x70, 0x3C, 0xC8, 0xAF, 0x5F, 0xF4, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x4E, 0xED, 0x5C, 0x43, 0xB3, 0x16, 0x35), -}; -static const mbedtls_mpi_uint secp192k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAE, 0xD1, 0xDD, 0x31, 0x14, 0xD3, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x14, 0x06, 0x13, 0x12, 0x1C, 0x81, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xF9, 0x0C, 0x91, 0xF7, 0x67, 0x59, 0x63), -}; -static const mbedtls_mpi_uint secp192k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x91, 0xE2, 0xF4, 0x9D, 0xEB, 0x88, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x82, 0x30, 0x9C, 0xAE, 0x18, 0x4D, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x79, 0xCF, 0x17, 0xA5, 0x1E, 0xE8, 0xC8), -}; -static const mbedtls_ecp_point secp192k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp192k1_T_0_X, secp192k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_1_X, secp192k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_2_X, secp192k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_3_X, secp192k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_4_X, secp192k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_5_X, secp192k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_6_X, secp192k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_7_X, secp192k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_8_X, secp192k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_9_X, secp192k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_10_X, secp192k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_11_X, secp192k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_12_X, secp192k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_13_X, secp192k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_14_X, secp192k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_15_X, secp192k1_T_15_Y), -}; -#else -#define secp192k1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static const mbedtls_mpi_uint secp224k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp224k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x05, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_4(0x33, 0x5B, 0x45, 0xA1), -}; -static const mbedtls_mpi_uint secp224k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_4(0xED, 0x9F, 0x08, 0x7E), -}; -static const mbedtls_mpi_uint secp224k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp224k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x5B, 0x45, 0xA1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x9F, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x6C, 0x22, 0x22, 0x40, 0x89, 0xAE, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x92, 0xE1, 0x87, 0x56, 0x35, 0xAF, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xAF, 0x08, 0x35, 0x27, 0xEA, 0x04, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x53, 0xFD, 0xCF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xD0, 0x9F, 0x8D, 0xF3, 0x63, 0x54, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xDB, 0x0F, 0x61, 0x54, 0x26, 0xD1, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x21, 0xF7, 0x1B, 0xB5, 0x1D, 0xF6, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x05, 0xDA, 0x8F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x26, 0x73, 0xBC, 0xE4, 0x29, 0x62, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x95, 0x17, 0x8B, 0xC3, 0x9B, 0xAC, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xDB, 0x77, 0xDF, 0xDD, 0x13, 0x04, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xFC, 0x22, 0x93, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0xF1, 0x5A, 0x37, 0xEF, 0x79, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x37, 0xAC, 0x9A, 0x5B, 0x51, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x75, 0x13, 0xA9, 0x4A, 0xAD, 0xFE, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x82, 0x6F, 0x66, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x5E, 0xF0, 0x40, 0xC3, 0xA6, 0xE2, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x9A, 0x6F, 0xCF, 0x11, 0x26, 0x66, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x73, 0xA8, 0xCF, 0x2B, 0x12, 0x36, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xB3, 0x0A, 0x58, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x79, 0x00, 0x55, 0x04, 0x34, 0x90, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x54, 0x1C, 0xC2, 0x45, 0x0C, 0x1B, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x19, 0xAB, 0xA8, 0xFC, 0x73, 0xDC, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xFB, 0x93, 0xCE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x75, 0xD0, 0x66, 0x95, 0x86, 0xCA, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xEA, 0x29, 0x16, 0x6A, 0x38, 0xDF, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA2, 0x36, 0x2F, 0xDC, 0xBB, 0x5E, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x89, 0x59, 0x49, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xA3, 0x99, 0x9D, 0xB8, 0x77, 0x9D, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x93, 0x43, 0x47, 0xC6, 0x5C, 0xF9, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x00, 0x79, 0x42, 0x64, 0xB8, 0x25, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x54, 0xB4, 0x33, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x0C, 0x42, 0x90, 0x83, 0x0B, 0x31, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2E, 0xAE, 0xC8, 0xC7, 0x5F, 0xD2, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xBC, 0xAD, 0x41, 0xE7, 0x32, 0x3A, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x97, 0x52, 0x83, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x13, 0x7A, 0xBD, 0xAE, 0x94, 0x60, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x9B, 0x95, 0xB4, 0x6E, 0x68, 0xB2, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x49, 0xBE, 0x51, 0xFE, 0x66, 0x15, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x37, 0xE4, 0xFE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x9B, 0xEE, 0x64, 0xC9, 0x1B, 0xBD, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x5F, 0x34, 0xA9, 0x0B, 0xB7, 0x25, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x13, 0xB1, 0x38, 0xFB, 0x9D, 0x78, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xE7, 0x1B, 0xFA, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xB3, 0xB7, 0x44, 0x92, 0x6B, 0x00, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x82, 0x44, 0x3E, 0x18, 0x1A, 0x58, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF8, 0xC0, 0xE4, 0xEE, 0xC1, 0xBF, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x32, 0x27, 0xB2, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x9A, 0x42, 0x62, 0x8B, 0x26, 0x54, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x85, 0x74, 0xA0, 0x79, 0xA8, 0xEE, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0x60, 0xB3, 0x28, 0x4D, 0x55, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x27, 0x82, 0x29, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xFC, 0x73, 0x77, 0xAF, 0x5C, 0xAC, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xED, 0xE5, 0xF6, 0x1D, 0xA8, 0x67, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xDE, 0x33, 0x1C, 0xF1, 0x80, 0x73, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE2, 0xDE, 0x3C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x3E, 0x6B, 0xFE, 0xF0, 0x04, 0x28, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xB2, 0x14, 0x9D, 0x18, 0x11, 0x7D, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC4, 0xD6, 0x2E, 0x6E, 0x57, 0x4D, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x55, 0x1B, 0xDE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xF7, 0x17, 0xBC, 0x45, 0xAB, 0x16, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xB0, 0xEF, 0x61, 0xE3, 0x20, 0x7C, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x85, 0x41, 0x4D, 0xF1, 0x7E, 0x4D, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC2, 0x9B, 0x5E, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x2E, 0x49, 0x3D, 0x3E, 0x4B, 0xD3, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x2B, 0x9D, 0xD5, 0x27, 0xFA, 0xCA, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xB3, 0x6A, 0xE0, 0x79, 0x14, 0x28, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x1E, 0xDC, 0xF5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x44, 0x56, 0xCD, 0xFC, 0x9F, 0x09, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x8C, 0x59, 0xA4, 0x64, 0x2A, 0x3A, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xA0, 0xB5, 0x86, 0x4E, 0x69, 0xDA, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x8B, 0x11, 0x38, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x17, 0x16, 0x12, 0x17, 0xDC, 0x00, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x76, 0x24, 0x6C, 0x97, 0x2C, 0xB5, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x71, 0xE3, 0xB0, 0xBB, 0x4E, 0x50, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x48, 0x26, 0xD5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x5F, 0x28, 0xF6, 0x01, 0x5A, 0x60, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x95, 0xFE, 0xD0, 0xAD, 0x15, 0xD4, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0x7A, 0xFD, 0x80, 0xF7, 0x9F, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xBC, 0x1B, 0xDF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xE6, 0xDF, 0x14, 0x29, 0xF4, 0xD4, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x12, 0xDD, 0xEC, 0x5B, 0x8A, 0x59, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x92, 0x3E, 0x35, 0x08, 0xE9, 0xCF, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x35, 0x29, 0x97, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xDB, 0xD6, 0x6A, 0xC5, 0x43, 0xA4, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x33, 0x50, 0x61, 0x70, 0xA1, 0xE9, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x15, 0x6E, 0x5F, 0x01, 0x0C, 0x8C, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xA1, 0x9A, 0x9D, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xC6, 0xF7, 0xE2, 0x4A, 0xCD, 0x9B, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x4D, 0x5A, 0xB8, 0xE2, 0x6D, 0xA6, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3F, 0xB6, 0x17, 0xE3, 0x2C, 0x6F, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA4, 0x59, 0x51, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x4F, 0x7C, 0x49, 0xCD, 0x6E, 0xEB, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xC9, 0x1F, 0xB7, 0x4D, 0x98, 0xC7, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xFD, 0x98, 0x20, 0x95, 0xBB, 0x20, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF2, 0x73, 0x92, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xEF, 0xFB, 0x30, 0xFA, 0x12, 0x1A, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x4C, 0x24, 0xB4, 0x5B, 0xC9, 0x4C, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xDD, 0x5E, 0x84, 0x95, 0x4D, 0x26, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xFA, 0xF9, 0x3A, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xA3, 0x2E, 0x7A, 0xDC, 0xA7, 0x53, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x9F, 0x81, 0x84, 0xB2, 0x0D, 0xFE, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x89, 0x1B, 0x77, 0x0C, 0x89, 0x71, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0x7F, 0xB2, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xE9, 0x2C, 0x79, 0xA6, 0x3C, 0xAD, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE0, 0x23, 0x02, 0x86, 0x0F, 0x77, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x93, 0x6D, 0xE9, 0xF9, 0x3C, 0xBE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xE7, 0x24, 0x92, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x3C, 0x5B, 0x4B, 0x1B, 0x25, 0x37, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xE8, 0x38, 0x1B, 0xA1, 0x5A, 0x2E, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x19, 0xFD, 0xF4, 0x78, 0x01, 0x6B, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x69, 0x37, 0x4F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xE2, 0xBF, 0xD3, 0xEC, 0x95, 0x9C, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x7B, 0xFC, 0xD5, 0xD3, 0x25, 0x5E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x55, 0x09, 0xA2, 0x58, 0x6A, 0xC9, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xCC, 0x3B, 0xD9, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x08, 0x65, 0x5E, 0xCB, 0xAB, 0x48, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x79, 0x8B, 0xC0, 0x11, 0xC0, 0x69, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xE8, 0x8C, 0x4C, 0xC5, 0x28, 0xE4, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x1F, 0x34, 0x5C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp224k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp224k1_T_0_X, secp224k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_1_X, secp224k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_2_X, secp224k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_3_X, secp224k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_4_X, secp224k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_5_X, secp224k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_6_X, secp224k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_7_X, secp224k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_8_X, secp224k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_9_X, secp224k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_10_X, secp224k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_11_X, secp224k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_12_X, secp224k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_13_X, secp224k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_14_X, secp224k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_15_X, secp224k1_T_15_Y), -}; -#else -#define secp224k1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static const mbedtls_mpi_uint secp256k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp256k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp256k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x07, 0x00), -}; -static const mbedtls_mpi_uint secp256k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), -}; -static const mbedtls_mpi_uint secp256k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), -}; -static const mbedtls_mpi_uint secp256k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp256k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), -}; -static const mbedtls_mpi_uint secp256k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), -}; -static const mbedtls_mpi_uint secp256k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xEE, 0xD7, 0x1E, 0x67, 0x86, 0x32, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0xB1, 0xA9, 0xD5, 0xCC, 0x27, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0E, 0x11, 0x01, 0x71, 0xFE, 0x92, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x28, 0x63, 0x6D, 0x72, 0x09, 0xA6, 0xC0), -}; -static const mbedtls_mpi_uint secp256k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0x69, 0xDC, 0x3E, 0x2C, 0x75, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xB7, 0x3F, 0x30, 0x26, 0x3C, 0xDF, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBE, 0xB9, 0x5D, 0x0E, 0xE8, 0x5E, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xC3, 0x05, 0xD6, 0xB7, 0xD5, 0x24, 0xFC), -}; -static const mbedtls_mpi_uint secp256k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCF, 0x7B, 0xDC, 0xCD, 0xC3, 0x39, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xDA, 0xB9, 0xE5, 0x64, 0xA7, 0x47, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x46, 0xA8, 0x61, 0xF6, 0x23, 0xEB, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xC1, 0xFF, 0xE4, 0x55, 0xD5, 0xC2, 0xBF), -}; -static const mbedtls_mpi_uint secp256k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xBE, 0xB9, 0x59, 0x24, 0x13, 0x4A, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x45, 0x12, 0xDE, 0xBA, 0x4F, 0xEF, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x08, 0xBF, 0xC1, 0x66, 0xAA, 0x0A, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xFE, 0x30, 0x55, 0x31, 0x86, 0xA7, 0xB4), -}; -static const mbedtls_mpi_uint secp256k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBF, 0x18, 0x81, 0x67, 0x27, 0x42, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x05, 0x83, 0xA4, 0xDD, 0x57, 0xD3, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x63, 0xAB, 0xE4, 0x90, 0x70, 0xD0, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x5D, 0xFD, 0xA0, 0xEF, 0xCF, 0x1C, 0x54), -}; -static const mbedtls_mpi_uint secp256k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x80, 0xE4, 0xF6, 0x09, 0xBC, 0x57, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x9F, 0x6E, 0x88, 0x54, 0x6E, 0x51, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x5F, 0x85, 0xFB, 0x84, 0x3E, 0x4A, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x19, 0xF5, 0x55, 0xC9, 0x07, 0xD8, 0xCE), -}; -static const mbedtls_mpi_uint secp256k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xB4, 0xC3, 0xD9, 0x5C, 0xA0, 0xD4, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x30, 0xAF, 0x59, 0x9B, 0xF8, 0x04, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xA6, 0xFD, 0x66, 0x7B, 0xC3, 0x39, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xBF, 0xF0, 0xC2, 0xE9, 0x71, 0xA4, 0x9E), -}; -static const mbedtls_mpi_uint secp256k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x2D, 0xB9, 0x88, 0x28, 0xF1, 0xBE, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF3, 0x1A, 0x0E, 0xB9, 0x01, 0x66, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0xA4, 0xF4, 0x05, 0xD0, 0xAA, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x39, 0x1E, 0x47, 0xE5, 0x68, 0xC8, 0xC0), -}; -static const mbedtls_mpi_uint secp256k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xB9, 0xFC, 0xE0, 0x33, 0x8A, 0x7D, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x93, 0xA5, 0x53, 0x55, 0x16, 0xB4, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x5F, 0xEA, 0x9B, 0x29, 0x52, 0x71, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xF0, 0x24, 0xB8, 0x7D, 0xB7, 0xA0, 0x9B), -}; -static const mbedtls_mpi_uint secp256k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x00, 0x27, 0xB2, 0xDF, 0x73, 0xA2, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x2E, 0x4D, 0x7C, 0xDE, 0x7A, 0x23, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0x60, 0xC7, 0x97, 0x1E, 0xA4, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x13, 0x5B, 0x77, 0x59, 0xCB, 0x36, 0xE1), -}; -static const mbedtls_mpi_uint secp256k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xBC, 0x9F, 0x9E, 0x2D, 0x53, 0x2A, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x5F, 0x64, 0x9F, 0x1A, 0x19, 0xE6, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x7B, 0x39, 0xD2, 0xDB, 0x85, 0x84, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xC7, 0x0D, 0x58, 0x6E, 0x3F, 0x52, 0x15), -}; -static const mbedtls_mpi_uint secp256k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x68, 0x19, 0x0B, 0x68, 0xC9, 0x1E, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x4E, 0x21, 0x49, 0x3D, 0x55, 0xCC, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF9, 0x25, 0x45, 0x54, 0x45, 0xB1, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xF7, 0xCD, 0x80, 0xA4, 0x04, 0x05), -}; -static const mbedtls_mpi_uint secp256k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x1E, 0x88, 0xC4, 0xAA, 0x18, 0x7E, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xAC, 0xD9, 0xB2, 0xA1, 0xC0, 0x71, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xA2, 0xF1, 0x15, 0xA6, 0x5F, 0x6C, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x5B, 0x05, 0xBC, 0xB7, 0xC6, 0x4E, 0x72), -}; -static const mbedtls_mpi_uint secp256k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x80, 0xF8, 0x5C, 0x20, 0x2A, 0xE1, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x48, 0x2E, 0x68, 0x82, 0x7F, 0xEB, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x3B, 0x25, 0xDB, 0x32, 0x4D, 0x88, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x6E, 0xA6, 0xB6, 0x6D, 0x62, 0x78, 0x22), -}; -static const mbedtls_mpi_uint secp256k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4D, 0x3E, 0x86, 0x58, 0xC3, 0xEB, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x89, 0x33, 0x18, 0x21, 0x1D, 0x9B, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x9D, 0xFF, 0xC3, 0x79, 0xC1, 0x88, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xD4, 0x48, 0x53, 0xE8, 0xAD, 0x21, 0x16), -}; -static const mbedtls_mpi_uint secp256k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x7B, 0xDE, 0xCB, 0xD8, 0x39, 0x17, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xF3, 0x03, 0xF2, 0x5C, 0xBC, 0xC8, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xAE, 0x4C, 0xB0, 0x16, 0xA4, 0x93, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8B, 0x6B, 0xDC, 0xD7, 0x9A, 0x3E, 0x7E), -}; -static const mbedtls_mpi_uint secp256k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x2D, 0x7A, 0xD2, 0x59, 0x05, 0xA2, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x56, 0x09, 0x32, 0xF1, 0xE8, 0xE3, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xCA, 0xE5, 0x2E, 0xF0, 0xFB, 0x18, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x85, 0xA9, 0x23, 0x15, 0x31, 0x1F, 0x0E), -}; -static const mbedtls_mpi_uint secp256k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xE5, 0xB1, 0x86, 0xB9, 0x6E, 0x8D, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x77, 0xFC, 0xC9, 0xA3, 0x3F, 0x89, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x6A, 0xDC, 0x25, 0xB0, 0xC7, 0x41, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x11, 0x6B, 0xA6, 0x11, 0x62, 0xD4, 0x2D), -}; -static const mbedtls_mpi_uint secp256k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7D, 0x34, 0xB3, 0x20, 0x7F, 0x37, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xD4, 0x45, 0xE8, 0xC2, 0xE9, 0xC5, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x32, 0x3B, 0x25, 0x7E, 0x79, 0xAF, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xE4, 0x54, 0x71, 0xBE, 0x35, 0x4E, 0xD0), -}; -static const mbedtls_mpi_uint secp256k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x94, 0xDD, 0x8F, 0xB5, 0xC2, 0xDD, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x49, 0xE9, 0x1C, 0x2F, 0x08, 0x49, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xB6, 0x03, 0x88, 0x6F, 0xB8, 0x15, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xD3, 0x1C, 0xF3, 0xA5, 0xEB, 0x79, 0x01), -}; -static const mbedtls_mpi_uint secp256k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF9, 0x43, 0x88, 0x89, 0x0D, 0x06, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2D, 0xF5, 0x98, 0x32, 0xF6, 0xB1, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0x8F, 0x2B, 0x50, 0x27, 0x0A, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE3, 0xBD, 0x16, 0x05, 0xC8, 0x93, 0x12), -}; -static const mbedtls_mpi_uint secp256k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x6A, 0xF7, 0xE3, 0x3D, 0xDE, 0x5F, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA3, 0x9C, 0x22, 0x3C, 0x33, 0x36, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x24, 0x4C, 0x69, 0x45, 0x78, 0x14, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xF8, 0xD4, 0xBF, 0xB8, 0xC0, 0xA1, 0x25), -}; -static const mbedtls_mpi_uint secp256k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x88, 0xE1, 0x91, 0x03, 0xEB, 0xB3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x11, 0xA1, 0xEF, 0x14, 0x0D, 0xC4, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xD4, 0x0D, 0x1D, 0x96, 0x33, 0x5C, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x45, 0x2A, 0x1A, 0xE6, 0x57, 0x04, 0x9B), -}; -static const mbedtls_mpi_uint secp256k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xB5, 0xA7, 0x80, 0xE9, 0x93, 0x97, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xB9, 0x7C, 0xA0, 0xC9, 0x57, 0x26, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xEF, 0x56, 0xDA, 0x66, 0xF6, 0x1B, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x89, 0x6B, 0x91, 0xE0, 0xA9, 0x65, 0x2B), -}; -static const mbedtls_mpi_uint secp256k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x98, 0x96, 0x9B, 0x06, 0x7D, 0x5E, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xFA, 0xC1, 0x5F, 0x19, 0x37, 0x94, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xBE, 0x6B, 0x1A, 0x05, 0xE4, 0xBF, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xCD, 0x5D, 0x35, 0xB4, 0x51, 0xF7, 0x64), -}; -static const mbedtls_mpi_uint secp256k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xEF, 0x96, 0xDB, 0xF2, 0x61, 0x63, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x04, 0x88, 0xC9, 0x9F, 0x1B, 0x94, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x30, 0x79, 0x7E, 0x24, 0xE7, 0x5F, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xB8, 0x90, 0xB7, 0x94, 0x25, 0xBB, 0x0F), -}; -static const mbedtls_mpi_uint secp256k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x79, 0xEA, 0xAD, 0xC0, 0x6D, 0x18, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xA4, 0x58, 0x2A, 0x8D, 0x95, 0xB3, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC4, 0xC2, 0x12, 0x0D, 0x79, 0xE2, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6F, 0xBE, 0x97, 0x4D, 0xA4, 0x20, 0x07), -}; -static const mbedtls_mpi_uint secp256k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x31, 0x71, 0xC6, 0xA6, 0x91, 0xEB, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x9B, 0xA8, 0x4A, 0xE7, 0x77, 0xE1, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x06, 0xD3, 0x3D, 0x94, 0x30, 0xEF, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xDF, 0xCA, 0xFA, 0xF5, 0x28, 0xF8, 0xC9), -}; -static const mbedtls_mpi_uint secp256k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xE1, 0x32, 0xFD, 0x3E, 0x81, 0xF8, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xF2, 0x4B, 0x1D, 0x19, 0xC9, 0x0F, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB1, 0x8A, 0x22, 0x8B, 0x05, 0x6B, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x21, 0xEF, 0x30, 0xEC, 0x09, 0x2A, 0x89), -}; -static const mbedtls_mpi_uint secp256k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x84, 0x4A, 0x46, 0x07, 0x6C, 0x3C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x18, 0x3A, 0xF4, 0xCC, 0xF5, 0xB2, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x8F, 0xCD, 0x0A, 0x9C, 0xF4, 0xBD, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x89, 0x7F, 0x8A, 0xB1, 0x52, 0x3A, 0xAB), -}; -static const mbedtls_ecp_point secp256k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp256k1_T_0_X, secp256k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_1_X, secp256k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_2_X, secp256k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_3_X, secp256k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_4_X, secp256k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_5_X, secp256k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_6_X, secp256k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_7_X, secp256k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_8_X, secp256k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_9_X, secp256k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_10_X, secp256k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_11_X, secp256k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_12_X, secp256k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_13_X, secp256k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_14_X, secp256k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_15_X, secp256k1_T_15_Y), -}; -#else -#define secp256k1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -/* - * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) - */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), -}; -static const mbedtls_mpi_uint brainpoolP256r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP256r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xA2, 0xED, 0x52, 0xC9, 0x8C, 0xE3, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xC9, 0xC4, 0x87, 0x3F, 0x93, 0x7A, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x12, 0x53, 0x61, 0x3E, 0x76, 0x08, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x8C, 0x74, 0xF4, 0x08, 0xC3, 0x76, 0x80), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xDD, 0x09, 0xA6, 0xED, 0xEE, 0xC4, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xD9, 0xBE, 0x4B, 0xA5, 0xB7, 0x2B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x20, 0x12, 0xCA, 0x0A, 0x38, 0x24, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x72, 0x71, 0x90, 0x7A, 0x2E, 0xB7, 0x23), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0xA1, 0x93, 0x10, 0x2A, 0x51, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x10, 0x11, 0x12, 0xBC, 0xB0, 0xB6, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x58, 0xD7, 0x0A, 0x84, 0x05, 0xA3, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x8E, 0x95, 0x61, 0xD3, 0x0B, 0xDF, 0x36), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x92, 0x12, 0x0F, 0x5E, 0x87, 0x70, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xE9, 0x9B, 0xEB, 0x3A, 0xFB, 0xCF, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0x92, 0xB9, 0xF7, 0x45, 0xD3, 0x06, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x28, 0x65, 0xE1, 0xC5, 0x6C, 0x57, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x0E, 0x77, 0x01, 0x81, 0x9E, 0x38, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xF0, 0xD5, 0xA5, 0x91, 0x2B, 0xDF, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xEE, 0xB6, 0x25, 0xD6, 0x98, 0xDE, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0x55, 0x63, 0x39, 0xEB, 0xB5, 0x47), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD6, 0xB8, 0xE3, 0x13, 0xED, 0x7F, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xE8, 0xAE, 0x36, 0xB8, 0xCD, 0x19, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x82, 0x83, 0x7A, 0x7B, 0x46, 0x56, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x60, 0x46, 0x15, 0x5A, 0xAC, 0x99, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x61, 0x50, 0xC6, 0xFF, 0x10, 0x7D, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x51, 0xDF, 0xA9, 0x7D, 0x78, 0x26, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x15, 0x9A, 0xF7, 0x01, 0xC1, 0xBB, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x0F, 0xE6, 0x2A, 0xBD, 0x4A, 0x9E, 0x87), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF8, 0xD1, 0x77, 0xD2, 0x49, 0xB3, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x86, 0xFB, 0x9E, 0x1F, 0x5A, 0x60, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xC4, 0x8D, 0xCD, 0x86, 0x61, 0x2F, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xF6, 0xB9, 0xAC, 0x37, 0x9D, 0xE9, 0x28), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x77, 0xAA, 0x97, 0x9C, 0x0B, 0x04, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xA6, 0x60, 0x81, 0xCE, 0x25, 0x13, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x00, 0xF3, 0xBB, 0x82, 0x99, 0x95, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0xCE, 0x90, 0x71, 0x38, 0x2F, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x1A, 0xC0, 0x84, 0x27, 0xD6, 0x9D, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x37, 0x52, 0x16, 0x13, 0x0E, 0xCE, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBF, 0x5A, 0xDB, 0xDB, 0x6E, 0x1E, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB7, 0x5E, 0xF9, 0x86, 0xDD, 0x8A, 0x5C), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xAB, 0x5C, 0x8D, 0x1D, 0xF2, 0x2D, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC5, 0xF8, 0xF7, 0x1D, 0x96, 0x0B, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x4C, 0xA7, 0x45, 0x20, 0x6A, 0x1E, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x5D, 0xEF, 0xDE, 0xEE, 0x39, 0x44, 0x19), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x2F, 0x6D, 0x52, 0xC9, 0x58, 0x60, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xC9, 0x62, 0xCB, 0x38, 0x3C, 0x55, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xA5, 0x09, 0x10, 0x88, 0xDB, 0xE3, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xE0, 0x3C, 0xCE, 0x06, 0x0B, 0x4B, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x1D, 0xB4, 0x10, 0x76, 0x8F, 0xBA, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x70, 0x5A, 0x07, 0xF5, 0x1A, 0x74, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xE9, 0x94, 0xA8, 0xC0, 0xD5, 0x4A, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x6D, 0xD4, 0xE8, 0x9B, 0xE9, 0x6D, 0x0E), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x00, 0x32, 0x41, 0x57, 0x84, 0x89, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC7, 0x14, 0xEC, 0xE9, 0x27, 0xFF, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x67, 0x9E, 0xFB, 0xB6, 0xB8, 0x96, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x4A, 0xE3, 0x97, 0x4B, 0x58, 0xDE, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x1E, 0x5C, 0xF5, 0x7F, 0xD5, 0xD4, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x08, 0x7A, 0xF1, 0xBD, 0x89, 0xC7, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xF9, 0x11, 0x1B, 0xF5, 0x3C, 0x6D, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x50, 0xE5, 0x69, 0x1D, 0x59, 0xFC, 0x0C), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x2F, 0xF8, 0x3F, 0xEC, 0x55, 0x99, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xA7, 0x29, 0x90, 0x43, 0x81, 0x31, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x18, 0x44, 0x50, 0x5D, 0x76, 0xCB, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xC5, 0x5B, 0x9A, 0x03, 0xE6, 0x17, 0x39), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x89, 0xFC, 0x55, 0x94, 0x91, 0x6A, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x46, 0x35, 0xF2, 0x3A, 0x42, 0x08, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xD2, 0x76, 0x49, 0x42, 0x87, 0xD3, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xEA, 0xA0, 0x52, 0xF1, 0x6A, 0x30, 0x57), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xB2, 0x57, 0xA3, 0x8A, 0x4D, 0x1B, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xA3, 0x99, 0x94, 0xB5, 0x3D, 0x64, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC3, 0xD7, 0x53, 0xF6, 0x49, 0x1C, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x23, 0x41, 0x4D, 0xFB, 0x7A, 0x5C, 0x53), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xB8, 0x15, 0x65, 0x5C, 0x85, 0x94, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x37, 0xC7, 0xF8, 0x7E, 0xAE, 0x6C, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xD8, 0x11, 0x54, 0x98, 0x44, 0xE3, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x4D, 0xA6, 0x4B, 0x28, 0xF2, 0x57, 0x9E), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD0, 0xEB, 0x1E, 0xAA, 0x30, 0xD3, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x9B, 0x4D, 0xA7, 0x73, 0x6E, 0xB6, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x47, 0xF6, 0xED, 0x37, 0xEF, 0x71, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xB5, 0x49, 0x61, 0x5E, 0x45, 0xF6, 0x4A), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x0E, 0xB3, 0x84, 0x3A, 0x63, 0x72, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x53, 0x5C, 0xA7, 0xC6, 0x2E, 0xAB, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x0F, 0x8F, 0x87, 0x50, 0x28, 0xB4, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x98, 0x4A, 0x98, 0x31, 0x86, 0xCA, 0x51), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC9, 0xE2, 0xFD, 0x5D, 0x1F, 0xE8, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x90, 0x91, 0xC4, 0x84, 0xF0, 0xBA, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5A, 0xB3, 0x4E, 0xFB, 0xE0, 0x57, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x0B, 0x90, 0xA6, 0xFD, 0x9D, 0x8E, 0x02), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x41, 0x8F, 0x31, 0xFA, 0x5A, 0xF6, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xE9, 0xE3, 0xF6, 0xE0, 0x4A, 0xE7, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x4E, 0xCD, 0xA2, 0x22, 0x14, 0xD4, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xED, 0x21, 0xB7, 0x0F, 0x53, 0x10, 0x17), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x06, 0x24, 0x2C, 0x4E, 0xD1, 0x1E, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x3F, 0xC1, 0x9F, 0xAB, 0xF0, 0x37, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x5E, 0x12, 0xCE, 0x83, 0x1B, 0x2A, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x65, 0xCF, 0xE8, 0x5C, 0xA5, 0xA2, 0x70), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x86, 0x76, 0x3A, 0x94, 0xF6, 0x1D, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xDA, 0xC9, 0xA6, 0x29, 0x93, 0x15, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x61, 0x6A, 0x7D, 0xC7, 0xA9, 0xF3, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x03, 0x71, 0xA2, 0x15, 0xCE, 0x50, 0x72), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD0, 0xA8, 0x1E, 0x91, 0xC4, 0x4F, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x4B, 0x7E, 0xD7, 0x71, 0x58, 0x7E, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x45, 0xAF, 0x2A, 0x18, 0x93, 0x95, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x8F, 0xC7, 0xFA, 0x4C, 0x7A, 0x86, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xAF, 0x68, 0x3A, 0x23, 0xC1, 0x2E, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x50, 0x11, 0x67, 0x39, 0xB9, 0xAF, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x86, 0xAA, 0x1E, 0x88, 0x21, 0x29, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x28, 0xA4, 0x9D, 0x89, 0xA9, 0x9A, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBA, 0x04, 0x67, 0xB7, 0x01, 0x40, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xE9, 0x09, 0xA3, 0xCA, 0xA6, 0x37, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x97, 0xA8, 0xB6, 0x3C, 0xEE, 0x90, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xED, 0xC4, 0xF7, 0xC3, 0x95, 0xEC, 0x85), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x84, 0xBD, 0xEB, 0xD5, 0x64, 0xBB, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x9B, 0xE2, 0x28, 0x50, 0xC2, 0x72, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xF2, 0x74, 0xD1, 0x26, 0xBF, 0x32, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xCB, 0xAF, 0x72, 0xDB, 0x6D, 0x30, 0x98), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x50, 0x85, 0xF4, 0x2B, 0x48, 0xC1, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x28, 0xBB, 0x11, 0xBA, 0x5B, 0x22, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA1, 0xE5, 0x5C, 0xC9, 0x1D, 0x44, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xE8, 0xE6, 0x6F, 0xBB, 0xC1, 0x81, 0x7F), -}; -static const mbedtls_ecp_point brainpoolP256r1_T[16] = { - ECP_POINT_INIT_XY_Z1(brainpoolP256r1_T_0_X, brainpoolP256r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_1_X, brainpoolP256r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_2_X, brainpoolP256r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_3_X, brainpoolP256r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_4_X, brainpoolP256r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_5_X, brainpoolP256r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_6_X, brainpoolP256r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_7_X, brainpoolP256r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_8_X, brainpoolP256r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_9_X, brainpoolP256r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_10_X, brainpoolP256r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_11_X, brainpoolP256r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_12_X, brainpoolP256r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_13_X, brainpoolP256r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_14_X, brainpoolP256r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_15_X, brainpoolP256r1_T_15_Y), -}; -#else -#define brainpoolP256r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -/* - * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) - */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), -}; -static const mbedtls_mpi_uint brainpoolP384r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP384r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xD8, 0x8A, 0x54, 0x41, 0xD6, 0x6B, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x3B, 0xF1, 0x22, 0xFD, 0x2D, 0x4B, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x55, 0xE3, 0x33, 0xF0, 0x73, 0x52, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x3F, 0x30, 0x26, 0xCA, 0x7F, 0x52, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x6E, 0x17, 0x9B, 0xD5, 0x2A, 0x4A, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xDA, 0x6B, 0xE5, 0x03, 0x07, 0x1D, 0x2E), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x7A, 0xAF, 0x98, 0xE3, 0xA4, 0xF6, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x7D, 0xFE, 0x51, 0x40, 0x3B, 0x47, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x88, 0xEC, 0xC4, 0xE2, 0x8F, 0xCB, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xE2, 0x88, 0x2D, 0x4E, 0x50, 0xEB, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x54, 0x94, 0x5E, 0xF4, 0x7F, 0x3A, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x07, 0x1C, 0xE1, 0xBD, 0x0F, 0xF8, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x92, 0x28, 0x2E, 0x32, 0x04, 0xB1, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x82, 0x44, 0x43, 0x76, 0x0D, 0x55, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xE3, 0xFF, 0x89, 0x46, 0xDE, 0x4E, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x22, 0xBB, 0x67, 0x1A, 0x81, 0xEE, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x54, 0xE2, 0x7A, 0xAE, 0xDA, 0x2C, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x9A, 0x90, 0xAA, 0x6E, 0x8B, 0xCC, 0x5F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x40, 0xAC, 0xED, 0x7D, 0x37, 0x87, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xF8, 0xB1, 0x80, 0x4C, 0x8C, 0x04, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x98, 0x2C, 0xAD, 0x30, 0x69, 0x35, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x2E, 0x00, 0x2F, 0x44, 0x8C, 0xF0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x58, 0x07, 0xD7, 0xCD, 0x60, 0xA1, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFB, 0x7B, 0x03, 0x05, 0x5E, 0x79, 0x73), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x17, 0xCE, 0x38, 0x4B, 0x5E, 0x5B, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x0E, 0x0A, 0x61, 0x9D, 0x7C, 0x62, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF0, 0x98, 0x71, 0x7F, 0x17, 0x26, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xD3, 0xFA, 0x3C, 0xF0, 0x70, 0x07, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x47, 0x5C, 0x09, 0x43, 0xB7, 0x65, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xA7, 0x3E, 0xFA, 0xF3, 0xEC, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x78, 0x22, 0x2B, 0x58, 0x71, 0xFA, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x30, 0xCE, 0x6A, 0xB3, 0xB0, 0x4F, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x95, 0x20, 0xA9, 0x23, 0xC2, 0x65, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xCF, 0x03, 0x5B, 0x8A, 0x80, 0x44, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xF8, 0x91, 0xF7, 0xD5, 0xED, 0xEA, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x5B, 0x16, 0x10, 0x25, 0xAC, 0x2A, 0x17), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEC, 0xDC, 0xC4, 0x7B, 0x8C, 0x6B, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBB, 0x1C, 0xD3, 0x5A, 0xEE, 0xD9, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5D, 0x30, 0x5E, 0xF7, 0xB2, 0x41, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xCE, 0x0F, 0x1A, 0xC6, 0x41, 0x64, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x18, 0xE1, 0xE3, 0x82, 0x15, 0x66, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xE2, 0x24, 0x04, 0x72, 0x39, 0xA0, 0x7C), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x51, 0xA2, 0x58, 0x88, 0x62, 0xE1, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xD2, 0x65, 0x14, 0xE9, 0x4C, 0x82, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE1, 0xAC, 0x87, 0xAE, 0x31, 0x1A, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4F, 0x96, 0x1E, 0x85, 0x7A, 0xC3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x86, 0xBB, 0xF0, 0xC0, 0x9D, 0x08, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x53, 0x03, 0x09, 0x80, 0x91, 0xEF, 0x68), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xD7, 0xAF, 0x6F, 0x69, 0x7B, 0x88, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x13, 0xE4, 0x30, 0xA2, 0x47, 0xB5, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD2, 0xC0, 0xDD, 0x8A, 0x1C, 0x3C, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x8C, 0xB3, 0x4C, 0xBA, 0x8B, 0x6D, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xC7, 0xA1, 0xA8, 0x6E, 0x3C, 0x4F, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x4A, 0x97, 0xC8, 0x03, 0x6F, 0x01, 0x82), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x18, 0x12, 0xA9, 0x39, 0xD5, 0x22, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA7, 0xC0, 0xBD, 0x9D, 0x8D, 0x78, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xD0, 0x7F, 0xDF, 0xD0, 0x30, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x73, 0x96, 0xEC, 0xA8, 0x1D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xD1, 0x65, 0x66, 0xDC, 0xD9, 0xCF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xED, 0x7B, 0x37, 0xAD, 0xE2, 0xBE, 0x2D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x79, 0x42, 0x6A, 0x07, 0x66, 0xB1, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x53, 0x62, 0x65, 0x92, 0x09, 0x4C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xAF, 0xC3, 0x03, 0xF6, 0xF4, 0x2D, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xCA, 0x41, 0xD9, 0xA2, 0x69, 0x9B, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xB2, 0xA6, 0x8D, 0xE1, 0xAA, 0x61, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xBA, 0x4D, 0x12, 0xB6, 0xBE, 0xF3, 0x7E), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x92, 0x22, 0x07, 0xCE, 0xC9, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA1, 0x7C, 0x91, 0xDB, 0x32, 0xF7, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x49, 0x4B, 0x6D, 0xFB, 0xD9, 0x70, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xFB, 0x4E, 0x4C, 0x5E, 0x66, 0x81, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xB3, 0xE1, 0x00, 0xB7, 0xD9, 0xCC, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x36, 0x8B, 0xC4, 0x39, 0x20, 0xFD, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x1F, 0x60, 0x03, 0xBB, 0xD7, 0x60, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x3C, 0x62, 0xDD, 0x71, 0x95, 0xE9, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x5B, 0x7A, 0x5F, 0x68, 0x81, 0xC5, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xB5, 0xB9, 0x98, 0x42, 0x28, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x29, 0x8E, 0x11, 0x49, 0xB4, 0xD7, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x3E, 0xD2, 0x30, 0xA1, 0xBA, 0xCA, 0x03), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x37, 0x64, 0x44, 0x2F, 0x03, 0xE5, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x42, 0xBC, 0xFF, 0xA2, 0x1A, 0x5F, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x04, 0xAB, 0x04, 0xE0, 0x24, 0xAD, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x45, 0x17, 0x67, 0x1F, 0x3E, 0x53, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x0F, 0xB3, 0x1B, 0x57, 0x54, 0xC2, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0xF8, 0xC4, 0x1B, 0x9B, 0xFA, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x90, 0xFD, 0xFB, 0xCA, 0x49, 0x38, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xCF, 0xC6, 0xDD, 0xF0, 0xFF, 0x8C, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x69, 0x9D, 0xBD, 0x5F, 0x33, 0xE9, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x19, 0x82, 0x3D, 0xAC, 0x1C, 0x40, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC7, 0x02, 0x46, 0x14, 0x77, 0x00, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x05, 0xF2, 0x77, 0x3A, 0x66, 0x5C, 0x39), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xE6, 0x17, 0xDE, 0xB2, 0xA1, 0xE5, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x71, 0xEC, 0x9D, 0xD8, 0xF5, 0xD4, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xC6, 0x42, 0x5E, 0xE7, 0x18, 0xBA, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x21, 0x68, 0x5A, 0x26, 0xFB, 0xD7, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x00, 0x5C, 0xBA, 0x8A, 0x34, 0xEC, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x3C, 0xAF, 0x53, 0xE8, 0x65, 0x35), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xEF, 0x28, 0xDC, 0x67, 0x05, 0xC8, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x78, 0xC3, 0x85, 0x49, 0xA0, 0xBC, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x3E, 0x2D, 0xA0, 0xCF, 0xD4, 0x7A, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x93, 0xFE, 0x60, 0xB3, 0x6E, 0x99, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xAD, 0x04, 0xE7, 0x49, 0xAF, 0x5E, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x7A, 0xED, 0xA6, 0x9E, 0x18, 0x09, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x05, 0x94, 0x44, 0xDC, 0xB8, 0x85, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xB7, 0x37, 0xC2, 0x50, 0x75, 0x15, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xC6, 0x0F, 0xB2, 0xA9, 0x91, 0x3E, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x81, 0xAD, 0x25, 0xA1, 0x26, 0x73, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xF1, 0xD1, 0x61, 0x7C, 0x76, 0x8F, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xDB, 0x4A, 0xFF, 0x14, 0xA7, 0x48, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x73, 0xC6, 0xC2, 0xCC, 0xF1, 0x57, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xED, 0x73, 0x27, 0x70, 0x82, 0xB6, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xBA, 0xAC, 0x3A, 0xCF, 0xF4, 0xEA, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xD6, 0xB1, 0x8F, 0x0E, 0x08, 0x2C, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE3, 0x8F, 0x2F, 0x0E, 0xA1, 0xF3, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xF5, 0x7C, 0x9B, 0x29, 0x0A, 0xF6, 0x28), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xEE, 0x17, 0x47, 0x34, 0x15, 0xA3, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBE, 0x88, 0x48, 0xE7, 0xA2, 0xBB, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xAD, 0xDC, 0x65, 0x61, 0x37, 0x0F, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x67, 0xAD, 0xA2, 0x3A, 0x1C, 0x91, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x07, 0x0C, 0x3A, 0x41, 0x6E, 0x13, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBD, 0x7E, 0xED, 0xAA, 0x14, 0xDD, 0x61), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xDC, 0x20, 0x01, 0x72, 0x11, 0x48, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xC4, 0x7B, 0xF8, 0x62, 0x3D, 0xF0, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xC2, 0x3D, 0x2E, 0x52, 0xA3, 0x4A, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE2, 0x53, 0x46, 0x5E, 0x21, 0xF8, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xC7, 0x8F, 0xA9, 0x26, 0x42, 0x32, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xA6, 0xA0, 0x8D, 0x4B, 0x9A, 0x19, 0x03), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xAB, 0x6D, 0x1E, 0xFB, 0xEE, 0x60, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x56, 0x3C, 0xC5, 0x5D, 0x10, 0x79, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xBC, 0x41, 0x9F, 0x71, 0xEF, 0x02, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x36, 0xC4, 0xD0, 0x88, 0x9B, 0x32, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xD4, 0x5D, 0x17, 0x39, 0xE6, 0x22, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x26, 0x01, 0xCE, 0xBE, 0x4A, 0x9C, 0x27), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x6D, 0x11, 0xCA, 0x6C, 0x5A, 0x93, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x96, 0x26, 0xAF, 0x2F, 0xE4, 0x30, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC1, 0x4C, 0xC6, 0x30, 0x1F, 0x5C, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB3, 0xE8, 0xFC, 0x35, 0xEB, 0x63, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x1D, 0xCA, 0xFC, 0x50, 0x36, 0x4B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0E, 0x23, 0x5B, 0xAF, 0xEB, 0x2D, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x88, 0xB6, 0xD7, 0x74, 0x4A, 0x23, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x66, 0xE2, 0xBB, 0x29, 0xA6, 0x4F, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x6F, 0x7E, 0x68, 0x6E, 0xA0, 0x14, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x73, 0xD4, 0xE8, 0xAB, 0x5B, 0xF6, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xE0, 0x3C, 0x24, 0x00, 0x95, 0xE9, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x0D, 0x4F, 0x81, 0xD0, 0xF2, 0x3F, 0x00), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x1D, 0xCD, 0x78, 0x39, 0xC4, 0x6B, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x45, 0xC7, 0xB8, 0x2F, 0xAA, 0x5D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x8C, 0x6E, 0xA3, 0x24, 0xB2, 0xDB, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x2D, 0xD9, 0xF1, 0xC7, 0x9B, 0x8A, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xE1, 0x2C, 0xB9, 0x40, 0x37, 0x91, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2C, 0xB5, 0x23, 0x03, 0x2B, 0xAF, 0x2F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x9D, 0x5A, 0x20, 0x10, 0xA9, 0x84, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x30, 0x89, 0x20, 0x13, 0xE9, 0xB2, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x52, 0xEB, 0x03, 0x18, 0x1F, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x9E, 0x1C, 0x35, 0x87, 0x92, 0x69, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xC9, 0x88, 0xAF, 0xC6, 0x6C, 0x83, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD5, 0x7A, 0x54, 0x34, 0x99, 0xB6, 0x6F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xAD, 0x45, 0x9B, 0x4B, 0x41, 0x4D, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x5D, 0xAB, 0x7F, 0x35, 0x34, 0xE9, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBE, 0x78, 0x34, 0x44, 0xF3, 0x4A, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xDE, 0xE3, 0xC4, 0xEE, 0x0B, 0xF9, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x86, 0x16, 0x48, 0x32, 0xB8, 0x74, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEE, 0x7C, 0xBA, 0xBD, 0x81, 0xE3, 0x55), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x6A, 0xFA, 0x84, 0xDA, 0xB8, 0xD5, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x9F, 0x8A, 0xD5, 0x1B, 0x2E, 0x1A, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0C, 0x61, 0xE2, 0xFF, 0x5B, 0xE6, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x62, 0xC1, 0x87, 0x53, 0x1B, 0x92, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x90, 0x00, 0xD1, 0x6A, 0x0C, 0x0E, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x2E, 0xB5, 0x3B, 0x44, 0xB5, 0xA0, 0x78), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5D, 0x02, 0x58, 0xB5, 0xBE, 0x45, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xEF, 0x8E, 0x90, 0x4D, 0x2A, 0x32, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x75, 0x5C, 0x0A, 0x33, 0x8F, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x6C, 0x95, 0xD4, 0x1F, 0xF3, 0xEB, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xE4, 0x4C, 0x91, 0x20, 0xF3, 0x25, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x95, 0xEB, 0x29, 0x6F, 0x20, 0x34, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x15, 0xE5, 0x13, 0x7E, 0x64, 0x8B, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xBC, 0x0D, 0x18, 0x7E, 0x37, 0x9E, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x82, 0x20, 0xF7, 0x2D, 0x7A, 0x77, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x29, 0xA2, 0xDB, 0x7A, 0xE6, 0x6F, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xC6, 0x50, 0x5C, 0xBC, 0xE6, 0x4F, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x9F, 0xD5, 0xE8, 0xC5, 0x3D, 0xB7, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x03, 0x55, 0x10, 0xDB, 0xA6, 0x8B, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x17, 0xAE, 0x78, 0xC9, 0x1D, 0x43, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x35, 0x49, 0xD4, 0x47, 0x84, 0x8D, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x95, 0x2F, 0xEA, 0xBC, 0xB4, 0x18, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x48, 0xAE, 0x89, 0xF5, 0x65, 0x3D, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xF2, 0x2B, 0x20, 0xD1, 0x75, 0x50, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xE6, 0x5C, 0x2C, 0xE0, 0x7D, 0xDF, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x07, 0x3E, 0xCE, 0x9F, 0x18, 0xB6, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xF8, 0xF0, 0xD5, 0xFA, 0x42, 0x1D, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x6C, 0x1D, 0x03, 0xC9, 0x0E, 0x2B, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x52, 0xA5, 0xB4, 0x63, 0xE1, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0xD9, 0xC4, 0xFD, 0x16, 0x60, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x7D, 0xDE, 0xDF, 0x4B, 0x4A, 0xB0, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x4E, 0x8C, 0x94, 0xC1, 0xE2, 0x85, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xF0, 0xEA, 0xB5, 0x9B, 0x70, 0xEF, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xC2, 0x39, 0x5D, 0xF3, 0x2C, 0xD9, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x1C, 0x2E, 0xCC, 0x2F, 0x54, 0x87, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x72, 0xC7, 0xB5, 0x50, 0xA3, 0x84, 0x77), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xD1, 0xAF, 0xA9, 0xB4, 0x8B, 0x5D, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xF6, 0x52, 0x8A, 0xC3, 0x56, 0xA5, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x52, 0xFF, 0xEA, 0x05, 0x42, 0x77, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x08, 0x90, 0x72, 0x86, 0xC4, 0xC3, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x15, 0xF8, 0xF1, 0x16, 0x67, 0xC6, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x87, 0xAC, 0x8F, 0x71, 0xEC, 0x83, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xE1, 0xE6, 0x2D, 0x0E, 0x11, 0xA1, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xE2, 0xA8, 0x32, 0xE6, 0xE3, 0x83, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x56, 0xE5, 0xCD, 0xB7, 0x2B, 0x67, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xED, 0xC9, 0x65, 0x6D, 0x87, 0xE1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xFD, 0x9A, 0x53, 0x0E, 0xFA, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x4C, 0x4A, 0xE2, 0x23, 0x84, 0xFA, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFE, 0x49, 0x81, 0xD1, 0x3E, 0xF4, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x72, 0xE0, 0xEF, 0x0D, 0xB8, 0x3E, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x00, 0x0F, 0x5F, 0xCE, 0x60, 0x72, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCC, 0xD8, 0x03, 0x07, 0x6E, 0x5A, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x3A, 0x35, 0x50, 0x4E, 0x1F, 0xCA, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xEA, 0x88, 0x55, 0xBD, 0x6E, 0x05, 0x7F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x6D, 0xF1, 0x97, 0xA6, 0x69, 0x39, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x41, 0x99, 0xFF, 0x3B, 0xA1, 0x26, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x2F, 0x95, 0x80, 0x12, 0x4A, 0x1B, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xBF, 0x51, 0xAA, 0xAE, 0x2D, 0xDA, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1C, 0xB3, 0x52, 0x36, 0x49, 0xD4, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC1, 0x1F, 0x3A, 0xD3, 0x3E, 0x5C, 0x1A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x51, 0xF7, 0x2B, 0xC8, 0xA9, 0xA7, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x4E, 0x7F, 0x98, 0x41, 0x66, 0xB0, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x1D, 0xC0, 0x42, 0xCD, 0xF8, 0xC3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x41, 0x91, 0x7D, 0xCC, 0x8B, 0xCC, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xAE, 0x76, 0xED, 0x56, 0x18, 0xC5, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x6A, 0x06, 0xA3, 0x7F, 0x65, 0x10, 0x1F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xEC, 0x3C, 0x05, 0x05, 0xCA, 0xF6, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0xCD, 0x02, 0x51, 0x12, 0x16, 0x3C, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xEB, 0xB3, 0x43, 0x7B, 0xDD, 0xB2, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x90, 0x41, 0xDB, 0xE4, 0xF5, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0E, 0x18, 0x2A, 0x5A, 0x83, 0x7C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x37, 0xA1, 0x0D, 0xF1, 0x2F, 0x63, 0x79), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC0, 0xFA, 0x6F, 0x1F, 0x67, 0xCF, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x34, 0x45, 0xBB, 0xF4, 0xF9, 0x9B, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x69, 0xFE, 0x67, 0x1D, 0x64, 0x8F, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x39, 0xBF, 0xD8, 0xB3, 0xC7, 0xAD, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x93, 0xFF, 0xF3, 0x28, 0xFA, 0x39, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF9, 0xC3, 0x85, 0x26, 0x7A, 0x88, 0x89), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD5, 0x79, 0xD8, 0x11, 0xDE, 0xEB, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x46, 0xA4, 0x6A, 0xDA, 0x74, 0x34, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBD, 0xD3, 0xF5, 0x14, 0xEE, 0xFE, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4C, 0xA3, 0x71, 0x43, 0x65, 0xF8, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x6C, 0x35, 0xFA, 0x90, 0x25, 0xD8, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x34, 0x84, 0x96, 0xA1, 0x43, 0x03, 0x4D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x3B, 0x3B, 0x2F, 0xCA, 0x59, 0xF2, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x48, 0x24, 0x74, 0xD8, 0x72, 0x90, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x42, 0x74, 0x8C, 0x6F, 0x52, 0x19, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9E, 0x41, 0x63, 0x68, 0x78, 0x4C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x94, 0xB6, 0x6B, 0x38, 0x52, 0xA8, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x30, 0x25, 0x93, 0xA1, 0x6F, 0x6E, 0x68), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2F, 0x4B, 0x64, 0x79, 0x50, 0xFF, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x36, 0xED, 0x57, 0x39, 0x3B, 0xE7, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x85, 0xEA, 0x35, 0xD6, 0xC0, 0xA0, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x89, 0x3A, 0xCC, 0x22, 0x1C, 0x46, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x7A, 0xB0, 0xA1, 0x1B, 0x69, 0x62, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xB8, 0x8A, 0x6C, 0x18, 0x85, 0x0D, 0x88), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB6, 0x50, 0xE9, 0x4E, 0x7F, 0xE8, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5B, 0x5C, 0xD1, 0x4B, 0x11, 0x9A, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x25, 0x56, 0x74, 0x51, 0x9C, 0xEC, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x7F, 0xB6, 0x8A, 0xCB, 0x3A, 0x10, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x33, 0x07, 0x01, 0xE9, 0x49, 0x59, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xA5, 0x2E, 0xF2, 0xBA, 0x32, 0x63, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x06, 0x0B, 0xA5, 0x44, 0x27, 0x7F, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x74, 0xAC, 0x0F, 0xCC, 0x4F, 0x13, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB1, 0xBF, 0x97, 0x49, 0xA5, 0x1C, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x64, 0x68, 0x7B, 0x0F, 0xCC, 0x77, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x39, 0xF9, 0x4E, 0x84, 0x9C, 0xF6, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xCF, 0x6D, 0xE2, 0xA1, 0x2D, 0xF9, 0x2B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC4, 0x90, 0x57, 0x31, 0x01, 0x05, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x1E, 0xBB, 0xBF, 0x98, 0xA4, 0x7C, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xE3, 0xA0, 0xB2, 0xCD, 0x39, 0x9A, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x34, 0x60, 0x7A, 0x89, 0x98, 0xB5, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x20, 0x3D, 0x3A, 0x04, 0x8F, 0x5A, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x26, 0xB6, 0x49, 0x09, 0x9C, 0x0F, 0x59), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x66, 0xD2, 0x38, 0x2A, 0x62, 0x81, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xC8, 0x20, 0x5E, 0x28, 0xA3, 0x81, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x31, 0xA4, 0xF1, 0xEA, 0x7D, 0x87, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x2C, 0x99, 0x09, 0x6F, 0x63, 0xEB, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x76, 0xDA, 0x1A, 0x06, 0xBE, 0xDE, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x09, 0x2E, 0x75, 0x39, 0x30, 0x2D, 0x42), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x9B, 0xC1, 0x5A, 0x17, 0xC3, 0x8C, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x8D, 0x94, 0x4D, 0x3D, 0xAB, 0x60, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFD, 0x1E, 0x0F, 0x43, 0xAE, 0x9D, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF2, 0xF3, 0x20, 0x1B, 0xAA, 0xB7, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x5B, 0xA4, 0xF4, 0x90, 0x3B, 0xE3, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x78, 0x72, 0xBD, 0x65, 0x09, 0x0B, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x37, 0x2A, 0x6C, 0x16, 0x4F, 0x64, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xCE, 0xA3, 0x90, 0xB4, 0x9A, 0xBC, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x55, 0x63, 0x1D, 0x3A, 0x6E, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xB4, 0xAA, 0x99, 0x22, 0x45, 0x89, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x7C, 0x8C, 0xA6, 0x3D, 0xA7, 0x3E, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x06, 0x42, 0xDC, 0xA6, 0xE3, 0xC6, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8C, 0x3D, 0x5D, 0x47, 0x31, 0x7C, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x85, 0xEE, 0x46, 0x7E, 0x13, 0x04, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x3C, 0x8B, 0x43, 0x2E, 0x74, 0xF5, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x88, 0x8E, 0x07, 0x29, 0x08, 0x03, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x9B, 0x89, 0xEB, 0x08, 0xE8, 0x43, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x07, 0x67, 0xFD, 0xD9, 0x73, 0x6F, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xEB, 0x21, 0x8D, 0x98, 0x43, 0x74, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xCC, 0x14, 0xD8, 0x08, 0xBB, 0xA6, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x98, 0xF2, 0x6A, 0x18, 0xC3, 0xDD, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x38, 0x91, 0xA0, 0x03, 0xF2, 0x04, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xAF, 0xE8, 0xFD, 0xFB, 0x13, 0x70, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x93, 0x87, 0x98, 0x4A, 0xE0, 0x00, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x2E, 0x69, 0x9C, 0xA2, 0x2D, 0x03, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFE, 0xF3, 0xB9, 0xC1, 0x85, 0x2A, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xFD, 0x86, 0xB1, 0xCD, 0xBF, 0x41, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xD8, 0x9A, 0x21, 0xF3, 0xFE, 0xCB, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x78, 0x04, 0x60, 0xB7, 0xA9, 0xA2, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1E, 0x66, 0x2A, 0x54, 0x51, 0xBD, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x16, 0x36, 0xEF, 0x61, 0x2D, 0xEE, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x5F, 0x88, 0xA0, 0x13, 0x12, 0xF7, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xC6, 0xAD, 0x4A, 0x4A, 0x07, 0x01, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x74, 0xB1, 0x4F, 0xEB, 0xBD, 0xD5, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF9, 0x71, 0xA2, 0x06, 0x4F, 0xD7, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x8B, 0x4D, 0x48, 0xE0, 0x98, 0xFB, 0x6A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xBA, 0x10, 0xA3, 0x0D, 0x52, 0xAC, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xD0, 0xE0, 0x36, 0xE6, 0x07, 0x3A, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x80, 0xF0, 0xAA, 0x49, 0x22, 0x4B, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC7, 0xAB, 0x1C, 0x89, 0xCD, 0x24, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x2A, 0xFC, 0xB3, 0x6D, 0x45, 0x96, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xE4, 0xDB, 0x52, 0x3F, 0xC4, 0xB4, 0x19), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xCC, 0xC8, 0x7F, 0xBB, 0x6B, 0x87, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x21, 0x3C, 0x69, 0x7D, 0x38, 0x57, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x4C, 0x18, 0x3C, 0x53, 0xA5, 0x48, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC3, 0x64, 0x45, 0xDB, 0xC4, 0x6D, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCC, 0xD1, 0xBB, 0x17, 0xB8, 0x34, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x69, 0x71, 0xFA, 0xA0, 0x28, 0x4A, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xE8, 0x9E, 0x39, 0xEA, 0x8D, 0x38, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x9C, 0xBB, 0xCD, 0x80, 0x1A, 0xEE, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA0, 0x45, 0xBF, 0xD9, 0x22, 0x11, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7C, 0x5C, 0xD9, 0xC0, 0x9F, 0x69, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x8A, 0xA6, 0x79, 0x4E, 0x35, 0xB9, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8B, 0x9A, 0x3E, 0xA1, 0xB8, 0x28, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x2F, 0xEF, 0xBB, 0xA9, 0x72, 0x7F, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x34, 0xB7, 0x12, 0xB9, 0xE7, 0xC3, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x1D, 0xD9, 0x42, 0x77, 0x0C, 0x71, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x01, 0x59, 0xA7, 0x56, 0x03, 0x91, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x91, 0x99, 0x33, 0x30, 0x3E, 0xEF, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xC9, 0x5A, 0x9A, 0x54, 0x66, 0xF1, 0x70), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x2C, 0xB7, 0x6E, 0x71, 0x7D, 0x35, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x0D, 0xEF, 0xD1, 0x2D, 0x99, 0x63, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x31, 0xAF, 0x2D, 0xC9, 0xC6, 0xC2, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xC0, 0xDF, 0x80, 0x54, 0xC4, 0xAC, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x6B, 0xA0, 0x84, 0x96, 0xF7, 0x31, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xE2, 0x7C, 0x7A, 0x41, 0x45, 0x75, 0x6A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xEE, 0x58, 0x31, 0xE8, 0x68, 0xD6, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x2E, 0x48, 0xB7, 0x09, 0x9F, 0xD4, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA9, 0x5C, 0xE7, 0x64, 0x43, 0x5D, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x9F, 0x50, 0xAB, 0x68, 0xFF, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x88, 0x2D, 0xBA, 0x12, 0xBF, 0x8D, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xDF, 0x6F, 0xB3, 0x75, 0xA4, 0x55, 0x73), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x17, 0x92, 0x39, 0xB7, 0x13, 0x37, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x43, 0x71, 0xA7, 0xCA, 0x17, 0x1B, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xB9, 0xB0, 0x78, 0xEF, 0xA0, 0xDA, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0xF2, 0x0F, 0x85, 0xA2, 0xB6, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x65, 0x2E, 0x6E, 0x45, 0xB9, 0x4C, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x6A, 0x8C, 0x2B, 0x77, 0x96, 0x36, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x7A, 0x13, 0x4A, 0x97, 0x63, 0x02, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x1E, 0x06, 0x03, 0x8F, 0xB9, 0xEE, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0xEE, 0x8B, 0x89, 0xA9, 0x70, 0xDB, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x81, 0xC9, 0x70, 0x8D, 0x62, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xDA, 0x46, 0xF8, 0xF9, 0x3A, 0xBE, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x9C, 0x7A, 0x97, 0x62, 0xEB, 0xFA, 0x0F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x03, 0x3D, 0x3C, 0x46, 0x27, 0x9E, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x08, 0x1C, 0xD5, 0x25, 0xAF, 0xE9, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x69, 0xDC, 0x59, 0xF4, 0x8A, 0x7C, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x9A, 0x7A, 0x99, 0x21, 0x0C, 0x4E, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xCE, 0x85, 0x5F, 0xAC, 0xAA, 0x82, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x57, 0x69, 0x90, 0x76, 0xF3, 0x53, 0x3F), -}; -static const mbedtls_ecp_point brainpoolP384r1_T[32] = { - ECP_POINT_INIT_XY_Z1(brainpoolP384r1_T_0_X, brainpoolP384r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_1_X, brainpoolP384r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_2_X, brainpoolP384r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_3_X, brainpoolP384r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_4_X, brainpoolP384r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_5_X, brainpoolP384r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_6_X, brainpoolP384r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_7_X, brainpoolP384r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_8_X, brainpoolP384r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_9_X, brainpoolP384r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_10_X, brainpoolP384r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_11_X, brainpoolP384r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_12_X, brainpoolP384r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_13_X, brainpoolP384r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_14_X, brainpoolP384r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_15_X, brainpoolP384r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_16_X, brainpoolP384r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_17_X, brainpoolP384r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_18_X, brainpoolP384r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_19_X, brainpoolP384r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_20_X, brainpoolP384r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_21_X, brainpoolP384r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_22_X, brainpoolP384r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_23_X, brainpoolP384r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_24_X, brainpoolP384r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_25_X, brainpoolP384r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_26_X, brainpoolP384r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_27_X, brainpoolP384r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_28_X, brainpoolP384r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_29_X, brainpoolP384r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_30_X, brainpoolP384r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_31_X, brainpoolP384r1_T_31_Y), -}; -#else -#define brainpoolP384r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -/* - * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) - */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP512r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), -}; -static const mbedtls_mpi_uint brainpoolP512r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78), -}; -static const mbedtls_mpi_uint brainpoolP512r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP512r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xE9, 0x6B, 0x8C, 0x6F, 0x9D, 0x88, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x4F, 0x86, 0x96, 0xA7, 0x56, 0xD1, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xAB, 0xFA, 0xEE, 0xA7, 0xF5, 0x0E, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x40, 0xEF, 0x9E, 0x6D, 0xD6, 0x32, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xED, 0x56, 0x14, 0x57, 0x1A, 0x8D, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xED, 0x4D, 0x3A, 0xFA, 0x71, 0x75, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xC5, 0x76, 0x1C, 0x14, 0xBE, 0xB5, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x5A, 0xCB, 0xE7, 0x36, 0x1D, 0x52, 0x1C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8D, 0x7A, 0xEB, 0xA3, 0x8B, 0xD5, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xA3, 0x41, 0xF8, 0xAC, 0x9E, 0xAB, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xE3, 0x65, 0x0D, 0x1C, 0xFE, 0x09, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xCA, 0x13, 0x3F, 0xC5, 0xF9, 0x7E, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x5D, 0x63, 0x28, 0xA6, 0x89, 0xD3, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x95, 0x3F, 0x7A, 0x82, 0xD4, 0x77, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xBB, 0x92, 0x32, 0x00, 0xF4, 0x66, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x58, 0x31, 0xD1, 0x17, 0x9F, 0x2A, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x36, 0xA9, 0xCD, 0x80, 0xA5, 0x2D, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x44, 0xAB, 0xCE, 0x71, 0xFF, 0x0C, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x24, 0x58, 0x35, 0x5A, 0x21, 0x32, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xA6, 0x28, 0xF8, 0x7A, 0x97, 0xAE, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xE7, 0x08, 0xFA, 0x47, 0xC9, 0x55, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xAC, 0x2E, 0x84, 0xA4, 0xF5, 0x52, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x58, 0x05, 0x9D, 0xA7, 0xC8, 0x71, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x92, 0xB4, 0x92, 0xC1, 0x92, 0xEC, 0x6B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x48, 0x2D, 0x79, 0x5E, 0x58, 0xE5, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x85, 0x26, 0xEC, 0xE9, 0x6E, 0xD4, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x68, 0x26, 0x87, 0x38, 0xA2, 0xD2, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x17, 0x60, 0xCE, 0x75, 0xF8, 0xA5, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x51, 0xDB, 0xA9, 0xAE, 0x87, 0xF1, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x49, 0x92, 0x3B, 0x19, 0x96, 0xF5, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xD5, 0x52, 0x52, 0x8C, 0xCE, 0xFD, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x18, 0x0A, 0xE6, 0xF6, 0xAE, 0x08, 0x41), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x2B, 0xD8, 0x54, 0xCE, 0xB0, 0x57, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xB0, 0xF8, 0x9E, 0x03, 0x03, 0x3C, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x0E, 0x29, 0x29, 0x00, 0xF3, 0x70, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x33, 0x99, 0x0E, 0x00, 0x5D, 0xFE, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2D, 0xF2, 0x59, 0x32, 0xCF, 0x03, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xC9, 0x72, 0xAE, 0x0C, 0xEF, 0xD1, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x5A, 0x27, 0xBF, 0x2F, 0x45, 0xF9, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xBE, 0xE5, 0x2C, 0xFF, 0x5B, 0x1E, 0x88), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xAC, 0xBB, 0xD8, 0x83, 0xC2, 0x46, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xDC, 0xCE, 0x15, 0xB4, 0xEF, 0xCF, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xDB, 0x5E, 0x94, 0x31, 0x0B, 0xB2, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xB9, 0xE3, 0xE3, 0x11, 0x71, 0x41, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xE3, 0x01, 0xB7, 0x7D, 0xBC, 0x65, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x07, 0x65, 0x87, 0xA7, 0xE8, 0x48, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x48, 0x8F, 0xD4, 0x30, 0x8E, 0xB4, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE0, 0x73, 0xBE, 0x1E, 0xBF, 0x56, 0x36), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x0E, 0x5E, 0x87, 0xC5, 0xAB, 0x0E, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xF9, 0x5F, 0x80, 0x24, 0x4C, 0x2A, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x15, 0x21, 0x54, 0x92, 0x84, 0x8D, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x8A, 0x47, 0x74, 0xDC, 0x42, 0xB1, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xF7, 0x30, 0xFD, 0xC1, 0x9B, 0x0C, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x6C, 0xCC, 0xDF, 0xC5, 0xE3, 0xA9, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x67, 0x59, 0x10, 0x5C, 0x51, 0x54, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x37, 0xFB, 0x6E, 0xB0, 0x78, 0x63, 0x8E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEF, 0xC4, 0x39, 0x20, 0xF1, 0x46, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x62, 0xAE, 0xFF, 0x10, 0xE4, 0xE2, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x5C, 0xF5, 0x2E, 0x22, 0x89, 0xE5, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x0C, 0x29, 0xA8, 0x62, 0xAE, 0xDB, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x9E, 0x0F, 0xCA, 0x87, 0x2A, 0x6F, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xDC, 0x9B, 0x9F, 0x65, 0xD4, 0xAD, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xC3, 0x08, 0x0F, 0xCF, 0x67, 0xE9, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5C, 0xD7, 0xFF, 0x41, 0x9C, 0xCB, 0x26), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x05, 0x12, 0xAD, 0x73, 0x63, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x99, 0x07, 0x86, 0x57, 0xE7, 0x94, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x4B, 0xA5, 0xBF, 0x18, 0xA9, 0xEF, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x4C, 0xC4, 0x09, 0xF2, 0x2F, 0x0C, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x3A, 0x04, 0xEA, 0x89, 0x6C, 0x91, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0x3A, 0xE7, 0xA3, 0xEC, 0x24, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xA1, 0x26, 0x21, 0x04, 0xE3, 0xB9, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x71, 0x4B, 0x7B, 0xC2, 0x89, 0xCD, 0xA2), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xB9, 0xA8, 0x9D, 0xFD, 0x00, 0x3A, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x41, 0x6C, 0xBB, 0x5A, 0xCA, 0x1F, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xD7, 0xE2, 0x6C, 0x6B, 0xA7, 0x48, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x19, 0xAD, 0xA7, 0xC1, 0x7E, 0x4F, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF7, 0x19, 0x3C, 0x06, 0x74, 0x2C, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x23, 0x4F, 0x0C, 0x09, 0xB0, 0x80, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x74, 0x34, 0x08, 0x44, 0x7E, 0xA3, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xCC, 0x8D, 0x12, 0x6E, 0xE1, 0x3D, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x18, 0xB1, 0x71, 0x02, 0x93, 0xC2, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x89, 0x40, 0xE2, 0x1F, 0xE7, 0x5E, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xAE, 0x89, 0x01, 0xD4, 0x0C, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xDA, 0x58, 0x70, 0x24, 0xF2, 0xE4, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xC7, 0x1D, 0xD6, 0x4A, 0x6F, 0x66, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x1D, 0x7E, 0x4A, 0x2C, 0xCA, 0xEC, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x7F, 0xA8, 0x99, 0xE4, 0xD3, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x1D, 0x5A, 0xDF, 0x5E, 0x58, 0x36, 0x49), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB9, 0x32, 0x69, 0x1F, 0x72, 0x2A, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x73, 0xE2, 0x03, 0x39, 0x35, 0xAA, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x5E, 0x5D, 0x48, 0xEF, 0xAE, 0x30, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x7F, 0x60, 0x19, 0xAF, 0xEC, 0x9D, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x19, 0xE4, 0x1B, 0x56, 0x15, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xD7, 0x33, 0x59, 0x1F, 0x43, 0x59, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xCE, 0xEE, 0xCA, 0xA4, 0x7F, 0x63, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x40, 0xC0, 0xF6, 0x19, 0x89, 0x43, 0x20), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x92, 0xEA, 0x07, 0x65, 0x79, 0x86, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xB7, 0x13, 0x75, 0xD3, 0xC5, 0x0A, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x9E, 0xFA, 0xE1, 0x1F, 0x0C, 0xF9, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x8C, 0xED, 0x5C, 0x21, 0xE9, 0x09, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x4D, 0xD8, 0x18, 0xC4, 0xF6, 0x36, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xC9, 0xAC, 0x5C, 0xFA, 0x69, 0xA4, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8C, 0x94, 0x1C, 0x7B, 0x71, 0x36, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBD, 0x46, 0xCE, 0xB7, 0x1D, 0x9C, 0x5E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD6, 0x96, 0x4B, 0xA6, 0x47, 0xEB, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xF1, 0x5F, 0x15, 0xDE, 0x99, 0x6F, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xBD, 0xE5, 0x04, 0xB8, 0xE6, 0xC0, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD3, 0xF0, 0x04, 0x00, 0xE4, 0x05, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xF3, 0x06, 0xA3, 0x1A, 0xFF, 0xEA, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x32, 0xAA, 0x99, 0x33, 0x09, 0xB6, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xEF, 0xFC, 0x61, 0x10, 0x42, 0x31, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF1, 0xF4, 0x33, 0xCF, 0x28, 0x90, 0x9C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xDE, 0xF9, 0x88, 0x87, 0x7B, 0xEB, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xB8, 0xDA, 0xFA, 0xDA, 0x3D, 0xA6, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF0, 0x62, 0x82, 0x53, 0x32, 0x55, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA5, 0x32, 0x4A, 0x19, 0x11, 0x9C, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xB3, 0x27, 0xE9, 0x75, 0x90, 0x05, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x1C, 0x90, 0x48, 0x77, 0x01, 0x85, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD6, 0x9B, 0x84, 0xA8, 0xD7, 0xC5, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x7A, 0xCB, 0xB3, 0x11, 0x46, 0xD7, 0x99), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x23, 0xBF, 0x75, 0x75, 0xA1, 0x95, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x66, 0x5D, 0x34, 0x13, 0xA9, 0x03, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x80, 0x9D, 0x5F, 0xD2, 0x44, 0xE1, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x5D, 0xBD, 0xA8, 0xBF, 0xB4, 0x25, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x99, 0x1F, 0x53, 0xF1, 0x57, 0xDB, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x7C, 0xE5, 0xC5, 0x51, 0x0B, 0x4C, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xB0, 0x1A, 0x9C, 0x16, 0xB0, 0x32, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xE3, 0xCF, 0xDD, 0x48, 0xB4, 0x7B, 0x33), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xDD, 0x9E, 0x3C, 0x98, 0x0E, 0x77, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xAB, 0x01, 0xD3, 0x87, 0x74, 0x25, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xA3, 0xE3, 0x76, 0x43, 0x87, 0x12, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0xB1, 0x3B, 0x60, 0x66, 0xEB, 0x98, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x78, 0xC8, 0xD7, 0x4E, 0x75, 0xCA, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xDF, 0x71, 0x19, 0xE7, 0x07, 0x36, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC9, 0xA8, 0x5F, 0x91, 0xBF, 0x47, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x96, 0x58, 0x96, 0x18, 0xB6, 0xFA, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x2D, 0xA9, 0x9B, 0x86, 0xDB, 0x0C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0B, 0x2D, 0x56, 0x4A, 0xD3, 0x93, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x15, 0xE2, 0x65, 0x12, 0x86, 0x0E, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x41, 0x4D, 0xC1, 0xCB, 0xE4, 0xC3, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x53, 0x10, 0xCA, 0xA3, 0xAC, 0x83, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x01, 0x22, 0x96, 0x10, 0xAD, 0x69, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x46, 0x4E, 0xD8, 0xEA, 0xD6, 0x9D, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x2F, 0x7F, 0x62, 0x62, 0x80, 0xD0, 0x14), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xDA, 0x00, 0x63, 0x09, 0xBD, 0x6A, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD4, 0x6E, 0x48, 0x05, 0xB7, 0xF7, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x4D, 0xD7, 0x00, 0x4A, 0x15, 0x27, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x15, 0xAA, 0x37, 0x27, 0x34, 0x18, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x20, 0x2C, 0x84, 0x1B, 0x88, 0xBA, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x09, 0xD6, 0x04, 0xA2, 0x60, 0x84, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x04, 0x94, 0x08, 0xD4, 0xED, 0x47, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xF3, 0xE4, 0x3E, 0xB9, 0x5B, 0x35, 0x42), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xD8, 0xB6, 0x80, 0xD6, 0xF1, 0x30, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x14, 0xA6, 0x85, 0xEE, 0xA7, 0xD8, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x49, 0x2A, 0x1E, 0x7C, 0xE9, 0x2D, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x87, 0x56, 0x91, 0x03, 0x77, 0x4D, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x52, 0xD4, 0xAA, 0xF7, 0xFA, 0xB0, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x11, 0x39, 0xB1, 0xE7, 0x76, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x13, 0xBC, 0x37, 0x5D, 0x74, 0xCD, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x48, 0x14, 0x23, 0x30, 0xF8, 0x46, 0x37), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x27, 0xB0, 0xD9, 0xB2, 0x74, 0xB4, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xA6, 0xB9, 0x6F, 0x9F, 0x64, 0x36, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x2B, 0x78, 0x40, 0x05, 0x2B, 0x7B, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x68, 0x3A, 0xB6, 0x4A, 0xE2, 0xDB, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x33, 0xD7, 0x34, 0x8B, 0x25, 0x45, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xCE, 0xA8, 0xC9, 0x01, 0xFB, 0x0E, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF9, 0x51, 0x4C, 0x12, 0x9F, 0x60, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x85, 0xBD, 0x30, 0x37, 0x84, 0x39, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x33, 0xAF, 0x2E, 0xB8, 0x2E, 0xCC, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xB1, 0x73, 0x59, 0x4E, 0x0C, 0x09, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x24, 0x89, 0x81, 0x12, 0xFF, 0xBB, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0x1A, 0x66, 0xEE, 0xED, 0xB6, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xBD, 0x04, 0x20, 0x5D, 0xFB, 0xBF, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF8, 0x34, 0xA3, 0xFF, 0x45, 0xDE, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x18, 0x73, 0xF1, 0x32, 0x25, 0x58, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xC1, 0x14, 0xE3, 0x9E, 0x40, 0x0F, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0x9D, 0x9C, 0x00, 0xF7, 0x56, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBA, 0x87, 0xF9, 0x15, 0x0C, 0x66, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x1F, 0xC1, 0x28, 0xB0, 0x47, 0x0D, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xCA, 0x27, 0xEE, 0x4B, 0x23, 0x2B, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB5, 0x68, 0xC8, 0x17, 0x5D, 0xC3, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x02, 0x08, 0xEE, 0x20, 0x9D, 0xEA, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x14, 0x50, 0xD4, 0x7D, 0x5F, 0xCF, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFA, 0xF8, 0xA7, 0xC6, 0xDC, 0x14, 0x8C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xBD, 0x0A, 0x1A, 0x18, 0x98, 0xDC, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x63, 0x02, 0xB7, 0xD5, 0x5B, 0x5A, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB1, 0xD7, 0x4B, 0x15, 0x39, 0x61, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x32, 0xE1, 0x9E, 0x70, 0x1B, 0xCE, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD8, 0x18, 0x83, 0x52, 0x9B, 0x6D, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x55, 0x56, 0x19, 0x34, 0xA4, 0xEA, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA9, 0x55, 0x80, 0xE3, 0x15, 0x36, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x06, 0xC8, 0x1D, 0x17, 0x0D, 0xAD, 0x16), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xD6, 0xF0, 0xCC, 0xF3, 0x63, 0x53, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x5A, 0xDC, 0x46, 0xBD, 0x0D, 0xAD, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x2F, 0x11, 0x60, 0x15, 0x51, 0x4A, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE3, 0x93, 0x38, 0xD5, 0x83, 0xAA, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA6, 0xCC, 0xB1, 0xFD, 0xBB, 0x1A, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x54, 0xC8, 0x54, 0x6F, 0x79, 0x1A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4A, 0xDA, 0x28, 0x92, 0x97, 0x9D, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x4B, 0xDB, 0xC7, 0x52, 0xC5, 0x66, 0x34), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7E, 0x92, 0x53, 0x30, 0x93, 0xFD, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0x6A, 0xB1, 0x91, 0x0A, 0xB4, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x9D, 0x40, 0x3F, 0xE3, 0xF1, 0x01, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x0E, 0xD8, 0xED, 0x11, 0x8E, 0x4C, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x4A, 0x1B, 0x88, 0xDF, 0x8D, 0x29, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x23, 0x21, 0x11, 0xAB, 0x77, 0x81, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xAF, 0x11, 0xFA, 0xBA, 0x40, 0x63, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x6F, 0x8D, 0x80, 0xDF, 0x67, 0xF5, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x8B, 0xB7, 0x08, 0xF4, 0xD7, 0x2D, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x2B, 0x30, 0x02, 0x45, 0x71, 0x08, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x3A, 0xCA, 0x50, 0xF6, 0xC2, 0x19, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xB9, 0x9B, 0x3E, 0x73, 0x95, 0x1D, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x60, 0x59, 0x48, 0xCB, 0xD8, 0xD6, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x6C, 0x89, 0xAB, 0x99, 0xA8, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xA1, 0x8B, 0x4E, 0x06, 0x19, 0xEC, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x95, 0x04, 0xCF, 0xD5, 0x94, 0xB3, 0x02), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x35, 0x93, 0x7C, 0xB3, 0xB8, 0x9E, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x45, 0x5C, 0x7E, 0xBF, 0x75, 0x81, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE8, 0x24, 0xDF, 0xEC, 0x2F, 0x7D, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x8B, 0xD5, 0x6A, 0x9B, 0xA0, 0xE0, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE3, 0x27, 0x82, 0xDE, 0xDD, 0xCA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x57, 0x56, 0x46, 0x05, 0x06, 0x01, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x35, 0xA7, 0x47, 0xE2, 0x6B, 0x2C, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x9D, 0x4C, 0xEC, 0x1F, 0x11, 0x75, 0x2B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xAA, 0x41, 0xC1, 0xE9, 0x0E, 0xE9, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xCF, 0x9C, 0x4B, 0xE8, 0xED, 0x0A, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x73, 0xCA, 0x0C, 0x46, 0x0A, 0x9C, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE1, 0x9E, 0xBC, 0xFE, 0x44, 0x63, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x43, 0x71, 0xEE, 0xF8, 0xC1, 0x8C, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x4B, 0xF0, 0x69, 0x25, 0xBD, 0x71, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x9A, 0xFE, 0x82, 0xE7, 0xC1, 0xC1, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x5A, 0x6E, 0x5E, 0x97, 0x6A, 0x35, 0x8D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x18, 0x6C, 0x7E, 0xB8, 0x9E, 0x57, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xB9, 0xC1, 0xD0, 0xFE, 0x78, 0xFB, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x08, 0xAE, 0x46, 0x34, 0xEA, 0x7A, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1C, 0x56, 0xA9, 0x18, 0x37, 0xD4, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x63, 0xE9, 0x0A, 0xB6, 0x38, 0x3C, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x4F, 0xA4, 0x6E, 0x85, 0x31, 0x23, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xAD, 0xC4, 0xC3, 0xB1, 0x4B, 0x1C, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x56, 0x4A, 0x38, 0xB3, 0x6B, 0x6F, 0x2C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xC7, 0x19, 0xDE, 0x21, 0xED, 0x89, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xBE, 0xA6, 0xAE, 0xEB, 0x9D, 0xA7, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x0E, 0x13, 0x1E, 0x86, 0x57, 0xC3, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4B, 0x30, 0x46, 0x52, 0xC1, 0xEC, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xD5, 0x44, 0x31, 0x96, 0x3B, 0x26, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x68, 0xA8, 0x67, 0x78, 0x39, 0xE8, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x78, 0xB7, 0xDD, 0xF2, 0x58, 0xB6, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x3C, 0xB3, 0x26, 0xC4, 0x2C, 0x8C, 0xA5), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x24, 0xE5, 0x73, 0xEE, 0x9A, 0x02, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x6A, 0x65, 0x60, 0xF3, 0x62, 0xE3, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x07, 0x84, 0xE6, 0x3B, 0x46, 0x65, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x8F, 0x0C, 0xB0, 0xE1, 0x04, 0x82, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x13, 0xBF, 0x3D, 0xA0, 0x48, 0xA2, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x26, 0x76, 0x74, 0xAB, 0x0B, 0x29, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x6E, 0x5F, 0x03, 0x34, 0x7C, 0x38, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x72, 0xF9, 0x3B, 0x3C, 0xA4, 0xBC, 0x7C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xCE, 0x18, 0x80, 0xB8, 0x24, 0x45, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x09, 0x03, 0xB8, 0x06, 0x64, 0xF7, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x26, 0xB1, 0x10, 0x6D, 0x71, 0x12, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x12, 0xC6, 0x6E, 0x1E, 0x6A, 0xC3, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xD3, 0x0A, 0xDE, 0xD8, 0x6B, 0x04, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x87, 0x5B, 0xAE, 0xDB, 0x3C, 0xC0, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF5, 0xF9, 0xC1, 0x9A, 0x89, 0xBB, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x69, 0x72, 0x8B, 0xAE, 0x32, 0x13, 0x11), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x16, 0x07, 0x50, 0xFA, 0x4C, 0xCF, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x50, 0x21, 0xE9, 0xDE, 0xEC, 0x7E, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x2F, 0xE8, 0x83, 0x30, 0x0B, 0x65, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x0B, 0x99, 0xAC, 0xC9, 0xBA, 0x6C, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x59, 0x5A, 0x0D, 0x7B, 0x9E, 0x08, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x91, 0xB2, 0xDC, 0x90, 0xCE, 0x67, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x93, 0x60, 0x0C, 0xD7, 0x1F, 0x2F, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7F, 0x9D, 0x40, 0xF8, 0x78, 0x7A, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x22, 0x95, 0xE8, 0xEF, 0x31, 0x57, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x88, 0x53, 0xFE, 0xAF, 0x7C, 0x47, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xCE, 0xCC, 0x79, 0xE8, 0x9F, 0x8C, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x16, 0xDD, 0x77, 0x6E, 0x8A, 0x73, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x07, 0x97, 0x21, 0x3B, 0xF8, 0x5F, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xB5, 0xD2, 0x81, 0x84, 0xF0, 0xE7, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x8F, 0x75, 0x09, 0x6A, 0x0E, 0x53, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x4F, 0x70, 0x97, 0xC7, 0xAC, 0x7D, 0x3F), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x3C, 0x6A, 0xB4, 0x10, 0xA9, 0xC8, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC5, 0xD6, 0x69, 0x16, 0xB8, 0xAC, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x44, 0xDC, 0xEB, 0x48, 0x54, 0x5D, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x48, 0x9B, 0xD7, 0x72, 0x69, 0xA4, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x0D, 0x36, 0x9A, 0x66, 0x0B, 0xEC, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC6, 0xD4, 0xB6, 0x60, 0xE5, 0xC3, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x29, 0x42, 0xE0, 0x9D, 0xFD, 0x7C, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x10, 0xBA, 0x55, 0xBC, 0x3B, 0x38, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x66, 0xFA, 0x05, 0x73, 0x03, 0x1B, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xA4, 0x66, 0x12, 0x96, 0x7B, 0x02, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xDE, 0x6D, 0x98, 0xD1, 0xD5, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF5, 0x44, 0xB8, 0x8E, 0xF6, 0x8C, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x15, 0x2B, 0x72, 0xBC, 0x49, 0xE5, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x44, 0xD7, 0xDF, 0x8F, 0xEB, 0x8D, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x64, 0x88, 0xAA, 0xB7, 0xE4, 0x70, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x14, 0xBB, 0xE9, 0x9B, 0xB9, 0x65, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x8E, 0x88, 0xF5, 0xF1, 0xC1, 0x89, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x30, 0x53, 0xE6, 0xFB, 0x2D, 0x82, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE4, 0xFF, 0xBA, 0x31, 0x79, 0xAB, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x09, 0xF7, 0xB7, 0x09, 0x78, 0x4C, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xAE, 0xC2, 0x44, 0xDC, 0x17, 0x78, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD4, 0x17, 0x43, 0x19, 0x74, 0x9E, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x64, 0x3B, 0x73, 0xA2, 0x99, 0x27, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0x36, 0x5F, 0xD3, 0x14, 0xB1, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x07, 0xAB, 0xFD, 0x9B, 0x03, 0xC5, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xBE, 0xB0, 0x1D, 0xF2, 0x0C, 0x73, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE7, 0x7B, 0x87, 0xD3, 0x34, 0xFD, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x25, 0x3D, 0xC7, 0x36, 0x83, 0x53, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x7C, 0xCF, 0x63, 0x55, 0x12, 0x11, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x34, 0x4D, 0x27, 0x92, 0xAC, 0x18, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x42, 0x61, 0x9D, 0x2E, 0xFF, 0x13, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xDE, 0x92, 0x65, 0x57, 0x0D, 0xBC, 0x0A), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x7B, 0x6E, 0xC6, 0x2A, 0x21, 0x74, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xA7, 0x53, 0x4D, 0x29, 0x36, 0xEF, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xD6, 0x41, 0xC7, 0x99, 0xAD, 0x50, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xAC, 0x41, 0x9F, 0xFB, 0x4C, 0x86, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xBB, 0xE6, 0x25, 0x28, 0xAA, 0xEB, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x04, 0xA2, 0xC3, 0xAA, 0x08, 0x8A, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x2B, 0x5B, 0xE2, 0x8D, 0x76, 0xEA, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x33, 0xD2, 0x21, 0x4D, 0x62, 0xE3, 0x8E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x06, 0x8B, 0x2B, 0xC2, 0xC4, 0xB1, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF5, 0xA1, 0xC0, 0x03, 0x6A, 0x29, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA9, 0xEF, 0x55, 0xB6, 0x1A, 0x9F, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x54, 0x32, 0xBE, 0x06, 0x43, 0xB5, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xD6, 0xD9, 0x20, 0x89, 0xBE, 0xD4, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x26, 0x95, 0x10, 0xCE, 0xB4, 0x88, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xA6, 0x27, 0xAC, 0x32, 0xBA, 0xBD, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xA6, 0xAE, 0x9C, 0x7B, 0xBE, 0xA1, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xCD, 0x4D, 0x3D, 0xDF, 0x96, 0xBB, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0x11, 0x06, 0xCC, 0x0E, 0x31, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xE4, 0xF4, 0xAD, 0x7B, 0x5F, 0xF1, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x54, 0xBE, 0xF4, 0x8A, 0x03, 0x47, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x53, 0x00, 0x7F, 0xB0, 0x8A, 0x68, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0xB1, 0x73, 0x6F, 0x5B, 0x0E, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x32, 0xE3, 0x43, 0x64, 0x75, 0xFB, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x18, 0x55, 0x8A, 0x4E, 0x6E, 0x35, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x97, 0x15, 0x1E, 0xCB, 0xF2, 0x9C, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xD1, 0xBB, 0xF3, 0x70, 0xAD, 0x13, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x96, 0xA4, 0xC5, 0x5E, 0xDA, 0xD5, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x81, 0xE9, 0x65, 0x66, 0x76, 0x47, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x87, 0x06, 0x73, 0xCF, 0x34, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x81, 0x15, 0x42, 0xA2, 0x79, 0x5B, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA2, 0x7D, 0x09, 0x14, 0x64, 0xC6, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x6D, 0xC4, 0xED, 0xF1, 0xD6, 0xE9, 0x24), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xD5, 0xBB, 0x25, 0xA3, 0xDD, 0xA3, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xF2, 0x68, 0x67, 0x39, 0x8F, 0x73, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x76, 0x28, 0x89, 0xAD, 0x32, 0xE0, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x90, 0xCC, 0x57, 0x58, 0xAA, 0xC9, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD7, 0x43, 0xD2, 0xCE, 0x5E, 0xA0, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xB0, 0xB8, 0xA4, 0x9E, 0x96, 0x26, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x61, 0x1D, 0xF3, 0x65, 0x5E, 0x60, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x1E, 0x65, 0xED, 0xCF, 0x07, 0x60, 0x20), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x30, 0x17, 0x8A, 0x91, 0x88, 0x0A, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7D, 0x18, 0xA4, 0xAC, 0x59, 0xFC, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x31, 0x8B, 0x25, 0x65, 0x39, 0x9A, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x16, 0x4B, 0x68, 0xBA, 0x59, 0x13, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xD3, 0xC5, 0x56, 0xC9, 0x8C, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC6, 0x9F, 0xF4, 0xE6, 0xF7, 0xB4, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x7C, 0x03, 0x00, 0x26, 0x9F, 0xD8, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x1D, 0x6E, 0x00, 0xB9, 0x00, 0x6E, 0x93), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x63, 0xDA, 0x03, 0x2B, 0xD5, 0x0B, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xFC, 0xE2, 0xC8, 0x47, 0xF0, 0xAE, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x4C, 0xF7, 0x50, 0x0C, 0x48, 0x06, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2B, 0x32, 0x98, 0x0E, 0x7E, 0x61, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x02, 0x27, 0xFE, 0x75, 0x86, 0xDF, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x30, 0xB1, 0x22, 0x32, 0x1B, 0xFE, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x27, 0xF7, 0x78, 0x6F, 0xD7, 0xFD, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x78, 0xCC, 0xEA, 0xC0, 0x50, 0x24, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x2B, 0x4F, 0x7F, 0x58, 0xE6, 0xC2, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x43, 0xD5, 0xA7, 0x35, 0x3C, 0x80, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x6D, 0x4B, 0x12, 0x00, 0x7B, 0xE6, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x15, 0xBD, 0xD0, 0x9B, 0xCA, 0xAA, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xCE, 0x9C, 0xE3, 0x8B, 0x60, 0x7A, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xDA, 0x4B, 0x03, 0xA7, 0x8D, 0x43, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAF, 0x00, 0x2B, 0x32, 0xF0, 0x22, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xD9, 0x99, 0x99, 0xBE, 0x43, 0x99, 0x3E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x71, 0x41, 0xF4, 0xB5, 0xFD, 0xDD, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xE2, 0x20, 0x4C, 0xD1, 0x2E, 0x1F, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x43, 0x48, 0x76, 0x8A, 0x49, 0xAC, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1A, 0x55, 0xA8, 0xA3, 0xD4, 0x57, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xA6, 0x84, 0x39, 0xC9, 0x13, 0xBB, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xFA, 0xA9, 0x70, 0xDE, 0x83, 0xDD, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xC9, 0xD9, 0x3E, 0x44, 0x91, 0x68, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x9F, 0x85, 0x6D, 0xF7, 0x54, 0x36, 0x82), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x6B, 0xA6, 0xA3, 0xE5, 0xD4, 0x46, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x3E, 0xDC, 0x84, 0x7C, 0x7B, 0x24, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xED, 0x7F, 0x86, 0x07, 0x6C, 0x57, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x06, 0xFE, 0x52, 0x12, 0x79, 0x69, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xD1, 0x44, 0x5F, 0x21, 0x3A, 0xC3, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD9, 0x4A, 0xC0, 0x75, 0xAB, 0x17, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x81, 0x94, 0xB6, 0x80, 0x6B, 0x6F, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBE, 0x8E, 0xA5, 0xAA, 0xBC, 0x1E, 0x3E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xC7, 0x85, 0xA6, 0x59, 0x9B, 0xB1, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xCE, 0x40, 0xD1, 0xFB, 0xDF, 0x94, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xB8, 0x5E, 0xBF, 0x45, 0xA8, 0x2D, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9C, 0x06, 0x1B, 0xA9, 0x57, 0xB9, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xE9, 0xCE, 0xA2, 0xD3, 0x74, 0xA1, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x5F, 0x34, 0x78, 0xDB, 0xAE, 0x3A, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x32, 0x84, 0x3E, 0x68, 0x6A, 0x43, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xBC, 0x39, 0x36, 0xA4, 0xC5, 0xBB, 0x11), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x07, 0xA2, 0xB5, 0xC9, 0x0F, 0x4D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0x67, 0xE6, 0xF1, 0x46, 0xEB, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x41, 0x23, 0x95, 0xE7, 0xE0, 0x10, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x69, 0xFE, 0x68, 0x8C, 0xC6, 0x5F, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB9, 0x2B, 0x3D, 0xD2, 0x4F, 0xD8, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x09, 0xF5, 0x5F, 0xCF, 0xF6, 0x91, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x15, 0x42, 0x6B, 0x6D, 0xB5, 0xF3, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x56, 0x9D, 0xC5, 0xFF, 0xCA, 0x13, 0x9B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x38, 0xE6, 0x23, 0x63, 0x48, 0x3C, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x68, 0x3C, 0xD1, 0x3B, 0xE9, 0x3B, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x08, 0x54, 0x49, 0xD1, 0x46, 0x45, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x70, 0x52, 0x6E, 0x79, 0xC4, 0x5E, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xDF, 0xE8, 0x5A, 0x32, 0x81, 0xDA, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x2D, 0x94, 0x5B, 0xB5, 0x35, 0x9F, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x12, 0x8D, 0xC3, 0x36, 0x36, 0xB2, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x2F, 0x22, 0x38, 0x5B, 0x18, 0x4C, 0x35), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC1, 0x22, 0x0E, 0xF0, 0x73, 0x11, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xAE, 0xA4, 0x56, 0x18, 0x61, 0x66, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFB, 0x72, 0x08, 0x84, 0x38, 0x51, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x86, 0xA8, 0xB9, 0x31, 0x99, 0x29, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xFB, 0xC3, 0x42, 0xB3, 0xC7, 0x6F, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xF8, 0xE1, 0x09, 0xBE, 0x75, 0xB0, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x7D, 0xFF, 0xF4, 0x99, 0xFC, 0x13, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x1B, 0x84, 0x81, 0x42, 0x22, 0xC6, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE0, 0x37, 0xA4, 0xA0, 0x2F, 0x38, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x3D, 0xB7, 0x40, 0x2F, 0x39, 0x3C, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x3B, 0x8A, 0x51, 0xAE, 0x40, 0x49, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x20, 0x9F, 0xDD, 0xA9, 0xD0, 0x77, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x1D, 0x64, 0xDA, 0xA0, 0x53, 0xC7, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x7B, 0x66, 0x55, 0x94, 0xD1, 0x51, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xB5, 0x5B, 0x38, 0x35, 0x40, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0x0F, 0xF0, 0x73, 0x79, 0x43, 0x61), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x47, 0x45, 0x69, 0x80, 0x72, 0x72, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x11, 0x99, 0x59, 0xDB, 0x48, 0x80, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x6E, 0x3D, 0xFC, 0x37, 0x15, 0xF4, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xBB, 0x5B, 0xA6, 0x35, 0x8D, 0x28, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x1A, 0x3B, 0x2C, 0x8F, 0xD3, 0xAA, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x1C, 0x1A, 0xF8, 0x02, 0xD9, 0x7B, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x69, 0xAC, 0xF8, 0x54, 0x31, 0x14, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x8A, 0xE6, 0xDE, 0x58, 0xB9, 0xC4, 0x7A), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x83, 0x52, 0xFE, 0xF9, 0x7B, 0xE9, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xA2, 0x55, 0x46, 0x15, 0x49, 0xC1, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBC, 0x5C, 0x91, 0xBD, 0xB9, 0x9C, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xFD, 0xB1, 0x4E, 0x5F, 0x74, 0xEE, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x8B, 0xD8, 0x8B, 0x17, 0x73, 0x1B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x92, 0xD7, 0x67, 0x06, 0xAD, 0x25, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0x80, 0x24, 0xE2, 0x27, 0x5F, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x1C, 0xCE, 0xD0, 0x67, 0xCA, 0xD4, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xF1, 0xDD, 0x33, 0x66, 0xF9, 0x05, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xE5, 0x6B, 0x79, 0xBD, 0x48, 0x42, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x14, 0x52, 0xE3, 0x53, 0xB4, 0x50, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x84, 0x6C, 0xCF, 0xDA, 0xB2, 0x20, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xD6, 0x1A, 0xE5, 0xE2, 0x29, 0x70, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x61, 0xFE, 0xBB, 0x21, 0x82, 0xD1, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0xF0, 0x9C, 0x8B, 0x1A, 0x42, 0x30, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xD6, 0x49, 0x81, 0x92, 0xF1, 0xD0, 0x90), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x91, 0x93, 0x6A, 0xA6, 0x22, 0xE9, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xDC, 0xC3, 0x69, 0x11, 0x95, 0x7D, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xA3, 0x9D, 0x87, 0x5E, 0x64, 0x41, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x87, 0x5A, 0x15, 0xBD, 0x6E, 0x3C, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x8D, 0x50, 0xCC, 0xCF, 0xB7, 0x8F, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x65, 0xCD, 0x31, 0x30, 0xF1, 0x68, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x5C, 0x66, 0x67, 0x92, 0x30, 0x57, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x9B, 0x01, 0x3D, 0x20, 0x8B, 0xD1, 0x0D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC0, 0xE6, 0x4F, 0xDE, 0x62, 0xAB, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x48, 0xB3, 0x1C, 0x0F, 0x16, 0x93, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x63, 0xBD, 0x1F, 0x16, 0x50, 0x56, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x06, 0xBC, 0xE9, 0x27, 0x1C, 0x9A, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xFE, 0x21, 0xC5, 0x39, 0x55, 0xE1, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA8, 0xD0, 0x96, 0x0E, 0xB5, 0xB2, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xE7, 0x4B, 0xF3, 0x11, 0x0C, 0xC9, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x3A, 0xC4, 0x87, 0x71, 0xEE, 0xFA, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x77, 0xEE, 0x81, 0x5E, 0x96, 0xEA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xDF, 0xA9, 0xF4, 0x4F, 0x7C, 0xB2, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD4, 0xDF, 0x35, 0x63, 0x47, 0x25, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3D, 0xFF, 0xA4, 0x02, 0xC3, 0x95, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x10, 0x78, 0xD1, 0x2B, 0xB7, 0xBE, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE9, 0x57, 0xF9, 0xE0, 0xD8, 0xFC, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xC4, 0x01, 0xD6, 0xB4, 0xE7, 0x78, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6C, 0xB9, 0x13, 0xA4, 0xE8, 0x6D, 0x6F), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xB0, 0xC9, 0xCD, 0xBF, 0xA2, 0x1E, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x4F, 0x86, 0x22, 0x9B, 0xEA, 0xE8, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x46, 0xDF, 0x43, 0xB9, 0x82, 0x2D, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x32, 0xF1, 0x4E, 0x95, 0x41, 0xAE, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x93, 0x26, 0xFC, 0xD3, 0x90, 0xDC, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x05, 0x45, 0xCA, 0xF9, 0x5A, 0x89, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x82, 0x63, 0x4E, 0x55, 0x1D, 0x3A, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x69, 0x52, 0x49, 0xE9, 0xED, 0x57, 0x34), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x64, 0xE9, 0xAC, 0x4C, 0x4A, 0xEA, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xE9, 0x0B, 0x99, 0xE7, 0xF9, 0xA9, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x0C, 0xC1, 0xF4, 0x8D, 0x07, 0xB6, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x68, 0xFA, 0x35, 0xE4, 0x9E, 0xAE, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2D, 0x1A, 0x13, 0x8E, 0x02, 0xE2, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x28, 0x86, 0x46, 0x7B, 0x3A, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4C, 0x64, 0x59, 0x0A, 0xF9, 0x02, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x4F, 0x23, 0xA2, 0xC3, 0xD5, 0xEF, 0x42), -}; -static const mbedtls_ecp_point brainpoolP512r1_T[32] = { - ECP_POINT_INIT_XY_Z1(brainpoolP512r1_T_0_X, brainpoolP512r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_1_X, brainpoolP512r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_2_X, brainpoolP512r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_3_X, brainpoolP512r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_4_X, brainpoolP512r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_5_X, brainpoolP512r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_6_X, brainpoolP512r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_7_X, brainpoolP512r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_8_X, brainpoolP512r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_9_X, brainpoolP512r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_10_X, brainpoolP512r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_11_X, brainpoolP512r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_12_X, brainpoolP512r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_13_X, brainpoolP512r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_14_X, brainpoolP512r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_15_X, brainpoolP512r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_16_X, brainpoolP512r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_17_X, brainpoolP512r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_18_X, brainpoolP512r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_19_X, brainpoolP512r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_20_X, brainpoolP512r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_21_X, brainpoolP512r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_22_X, brainpoolP512r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_23_X, brainpoolP512r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_24_X, brainpoolP512r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_25_X, brainpoolP512r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_26_X, brainpoolP512r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_27_X, brainpoolP512r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_28_X, brainpoolP512r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_29_X, brainpoolP512r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_30_X, brainpoolP512r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_31_X, brainpoolP512r1_T_31_Y), -}; -#else -#define brainpoolP512r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -#if defined(ECP_LOAD_GROUP) -/* - * Create an MPI from embedded constants - * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint)) - */ -static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len) -{ - X->s = 1; - X->n = (unsigned short) (len / sizeof(mbedtls_mpi_uint)); - X->p = (mbedtls_mpi_uint *) p; -} - -/* - * Set an MPI to static value 1 - */ -static inline void ecp_mpi_set1(mbedtls_mpi *X) -{ - X->s = 1; - X->n = 1; - X->p = (mbedtls_mpi_uint *) mpi_one; /* X->p will not be modified so the cast is safe */ -} - -/* - * Make group available from embedded constants - */ -static int ecp_group_load(mbedtls_ecp_group *grp, - const mbedtls_mpi_uint *p, size_t plen, - const mbedtls_mpi_uint *a, size_t alen, - const mbedtls_mpi_uint *b, size_t blen, - const mbedtls_mpi_uint *gx, size_t gxlen, - const mbedtls_mpi_uint *gy, size_t gylen, - const mbedtls_mpi_uint *n, size_t nlen, - const mbedtls_ecp_point *T) -{ - ecp_mpi_load(&grp->P, p, plen); - if (a != NULL) { - ecp_mpi_load(&grp->A, a, alen); - } - ecp_mpi_load(&grp->B, b, blen); - ecp_mpi_load(&grp->N, n, nlen); - - ecp_mpi_load(&grp->G.X, gx, gxlen); - ecp_mpi_load(&grp->G.Y, gy, gylen); - ecp_mpi_set1(&grp->G.Z); - - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - grp->nbits = mbedtls_mpi_bitlen(&grp->N); - - grp->h = 1; - - grp->T = (mbedtls_ecp_point *) T; - /* - * Set T_size to 0 to prevent T free by mbedtls_ecp_group_free. - */ - grp->T_size = 0; - - return 0; -} -#endif /* ECP_LOAD_GROUP */ - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* Forward declarations */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static int ecp_mod_p192(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static int ecp_mod_p224(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static int ecp_mod_p256(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static int ecp_mod_p384(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static int ecp_mod_p521(mbedtls_mpi *); -#endif - -#define NIST_MODP(P) grp->modp = ecp_mod_ ## P; -#else -#define NIST_MODP(P) -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -/* Additional forward declarations */ -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -static int ecp_mod_p255(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -static int ecp_mod_p448(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static int ecp_mod_p192k1(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static int ecp_mod_p224k1(mbedtls_mpi *); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static int ecp_mod_p256k1(mbedtls_mpi *); -#endif - -#if defined(ECP_LOAD_GROUP) -#define LOAD_GROUP_A(G) ecp_group_load(grp, \ - G ## _p, sizeof(G ## _p), \ - G ## _a, sizeof(G ## _a), \ - G ## _b, sizeof(G ## _b), \ - G ## _gx, sizeof(G ## _gx), \ - G ## _gy, sizeof(G ## _gy), \ - G ## _n, sizeof(G ## _n), \ - G ## _T \ - ) - -#define LOAD_GROUP(G) ecp_group_load(grp, \ - G ## _p, sizeof(G ## _p), \ - NULL, 0, \ - G ## _b, sizeof(G ## _b), \ - G ## _gx, sizeof(G ## _gx), \ - G ## _gy, sizeof(G ## _gy), \ - G ## _n, sizeof(G ## _n), \ - G ## _T \ - ) -#endif /* ECP_LOAD_GROUP */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -/* Constants used by ecp_use_curve25519() */ -static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42; -static const unsigned char curve25519_part_of_n[] = { - 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, - 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED, -}; - -/* - * Specialized function for creating the Curve25519 group - */ -static int ecp_use_curve25519(mbedtls_ecp_group *grp) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24)); - - /* P = 2^255 - 19 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 255)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 19)); - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - - /* N = 2^252 + 27742317777372353535851937790883648493 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&grp->N, - curve25519_part_of_n, sizeof(curve25519_part_of_n))); - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 252, 1)); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 9)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); - mbedtls_mpi_free(&grp->G.Y); - - /* Actually, the required msb for private keys */ - grp->nbits = 254; - -cleanup: - if (ret != 0) { - mbedtls_ecp_group_free(grp); - } - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -/* Constants used by ecp_use_curve448() */ -static const mbedtls_mpi_sint curve448_a24 = 0x98AA; -static const unsigned char curve448_part_of_n[] = { - 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24, - 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93, - 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC, - 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D, -}; - -/* - * Specialized function for creating the Curve448 group - */ -static int ecp_use_curve448(mbedtls_ecp_group *grp) -{ - mbedtls_mpi Ns; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_mpi_init(&Ns); - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24)); - - /* P = 2^448 - 2^224 - 1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1)); - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 5)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); - mbedtls_mpi_free(&grp->G.Y); - - /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 446, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&Ns, - curve448_part_of_n, sizeof(curve448_part_of_n))); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&grp->N, &grp->N, &Ns)); - - /* Actually, the required msb for private keys */ - grp->nbits = 447; - -cleanup: - mbedtls_mpi_free(&Ns); - if (ret != 0) { - mbedtls_ecp_group_free(grp); - } - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -/* - * Set a group using well-known domain parameters - */ -int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id) -{ - mbedtls_ecp_group_free(grp); - - mbedtls_ecp_group_init(grp); - - grp->id = id; - - switch (id) { -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - case MBEDTLS_ECP_DP_SECP192R1: - NIST_MODP(p192); - return LOAD_GROUP(secp192r1); -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - case MBEDTLS_ECP_DP_SECP224R1: - NIST_MODP(p224); - return LOAD_GROUP(secp224r1); -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - case MBEDTLS_ECP_DP_SECP256R1: - NIST_MODP(p256); - return LOAD_GROUP(secp256r1); -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - case MBEDTLS_ECP_DP_SECP384R1: - NIST_MODP(p384); - return LOAD_GROUP(secp384r1); -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - case MBEDTLS_ECP_DP_SECP521R1: - NIST_MODP(p521); - return LOAD_GROUP(secp521r1); -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - case MBEDTLS_ECP_DP_SECP192K1: - grp->modp = ecp_mod_p192k1; - return LOAD_GROUP_A(secp192k1); -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - case MBEDTLS_ECP_DP_SECP224K1: - grp->modp = ecp_mod_p224k1; - return LOAD_GROUP_A(secp224k1); -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - case MBEDTLS_ECP_DP_SECP256K1: - grp->modp = ecp_mod_p256k1; - return LOAD_GROUP_A(secp256k1); -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - case MBEDTLS_ECP_DP_BP256R1: - return LOAD_GROUP_A(brainpoolP256r1); -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - case MBEDTLS_ECP_DP_BP384R1: - return LOAD_GROUP_A(brainpoolP384r1); -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - case MBEDTLS_ECP_DP_BP512R1: - return LOAD_GROUP_A(brainpoolP512r1); -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - grp->modp = ecp_mod_p255; - return ecp_use_curve25519(grp); -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - grp->modp = ecp_mod_p448; - return ecp_use_curve448(grp); -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - - default: - grp->id = MBEDTLS_ECP_DP_NONE; - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } -} - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* - * Fast reduction modulo the primes used by the NIST curves. - * - * These functions are critical for speed, but not needed for correct - * operations. So, we make the choice to heavily rely on the internals of our - * bignum library, which creates a tight coupling between these functions and - * our MPI implementation. However, the coupling between the ECP module and - * MPI remains loose, since these functions can be deactivated at will. - */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -/* - * Compared to the way things are presented in FIPS 186-3 D.2, - * we proceed in columns, from right (least significant chunk) to left, - * adding chunks to N in place, and keeping a carry for the next chunk. - * This avoids moving things around in memory, and uselessly adding zeros, - * compared to the more straightforward, line-oriented approach. - * - * For this prime we need to handle data in chunks of 64 bits. - * Since this is always a multiple of our basic mbedtls_mpi_uint, we can - * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. - */ - -/* Add 64-bit chunks (dst += src) and update carry */ -static inline void add64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry) -{ - unsigned char i; - mbedtls_mpi_uint c = 0; - for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++, src++) { - *dst += c; c = (*dst < c); - *dst += *src; c += (*dst < *src); - } - *carry += c; -} - -/* Add carry to a 64-bit chunk and update carry */ -static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry) -{ - unsigned char i; - for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) { - *dst += *carry; - *carry = (*dst < *carry); - } -} - -#define WIDTH 8 / sizeof(mbedtls_mpi_uint) -#define A(i) N->p + (i) * WIDTH -#define ADD(i) add64(p, A(i), &c) -#define NEXT p += WIDTH; carry64(p, &c) -#define LAST p += WIDTH; *p = c; while (++p < end) *p = 0 - -/* - * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) - */ -static int ecp_mod_p192(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi_uint c = 0; - mbedtls_mpi_uint *p, *end; - - /* Make sure we have enough blocks so that A(5) is legal */ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, 6 * WIDTH)); - - p = N->p; - end = p + N->n; - - ADD(3); ADD(5); NEXT; // A0 += A3 + A5 - ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5 - ADD(4); ADD(5); LAST; // A2 += A4 + A5 - -cleanup: - return ret; -} - -#undef WIDTH -#undef A -#undef ADD -#undef NEXT -#undef LAST -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A(i); - -#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ - -#define MAX32 N->n -#define A(j) N->p[j] -#define STORE32 N->p[i] = cur; - -#else /* 64-bit */ - -#define MAX32 N->n * 2 -#define A(j) (j) % 2 ? (uint32_t) (N->p[(j)/2] >> 32) : \ - (uint32_t) (N->p[(j)/2]) -#define STORE32 \ - if (i % 2) { \ - N->p[i/2] &= 0x00000000FFFFFFFF; \ - N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ - } else { \ - N->p[i/2] &= 0xFFFFFFFF00000000; \ - N->p[i/2] |= (mbedtls_mpi_uint) cur; \ - } - -#endif /* sizeof( mbedtls_mpi_uint ) */ - -/* - * Helpers for addition and subtraction of chunks, with signed carry. - */ -static inline void add32(uint32_t *dst, uint32_t src, signed char *carry) -{ - *dst += src; - *carry += (*dst < src); -} - -static inline void sub32(uint32_t *dst, uint32_t src, signed char *carry) -{ - *carry -= (*dst < src); - *dst -= src; -} - -#define ADD(j) add32(&cur, A(j), &c); -#define SUB(j) sub32(&cur, A(j), &c); - -/* - * Helpers for the main 'loop' - */ -#define INIT(b) \ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \ - signed char c = 0, cc; \ - uint32_t cur; \ - size_t i = 0, bits = (b); \ - /* N is the size of the product of two b-bit numbers, plus one */ \ - /* limb for fix_negative */ \ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, (b) * 2 / biL + 1)); \ - LOAD32; - -#define NEXT \ - STORE32; i++; LOAD32; \ - cc = c; c = 0; \ - if (cc < 0) \ - sub32(&cur, -cc, &c); \ - else \ - add32(&cur, cc, &c); \ - -#define LAST \ - STORE32; i++; \ - cur = c > 0 ? c : 0; STORE32; \ - cur = 0; while (++i < MAX32) { STORE32; } \ - if (c < 0) mbedtls_ecp_fix_negative(N, c, bits); - -/* - * If the result is negative, we get it in the form - * c * 2^bits + N, with c negative and N positive shorter than 'bits' - */ -static void mbedtls_ecp_fix_negative(mbedtls_mpi *N, signed char c, size_t bits) -{ - size_t i; - - /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so - * set the absolute value to 0xfff...fff - N. There is no carry - * since we're subtracting from all-bits-one. */ - for (i = 0; i <= bits / 8 / sizeof(mbedtls_mpi_uint); i++) { - N->p[i] = ~(mbedtls_mpi_uint) 0 - N->p[i]; - } - /* Add 1, taking care of the carry. */ - i = 0; - do { - ++N->p[i]; - } while (N->p[i++] == 0 && i <= bits / 8 / sizeof(mbedtls_mpi_uint)); - /* Invert the sign. - * Now N = N0 - 2^bits where N0 is the initial value of N. */ - N->s = -1; - - /* Add |c| * 2^bits to the absolute value. Since c and N are - * negative, this adds c * 2^bits. */ - mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c; -#if defined(MBEDTLS_HAVE_INT64) - if (bits == 224) { - msw <<= 32; - } -#endif - N->p[bits / 8 / sizeof(mbedtls_mpi_uint)] += msw; -} - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224(mbedtls_mpi *N) -{ - INIT(224); - - SUB(7); SUB(11); NEXT; // A0 += -A7 - A11 - SUB(8); SUB(12); NEXT; // A1 += -A8 - A12 - SUB(9); SUB(13); NEXT; // A2 += -A9 - A13 - SUB(10); ADD(7); ADD(11); NEXT; // A3 += -A10 + A7 + A11 - SUB(11); ADD(8); ADD(12); NEXT; // A4 += -A11 + A8 + A12 - SUB(12); ADD(9); ADD(13); NEXT; // A5 += -A12 + A9 + A13 - SUB(13); ADD(10); LAST; // A6 += -A13 + A10 - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -/* - * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) - */ -static int ecp_mod_p256(mbedtls_mpi *N) -{ - INIT(256); - - ADD(8); ADD(9); - SUB(11); SUB(12); SUB(13); SUB(14); NEXT; // A0 - - ADD(9); ADD(10); - SUB(12); SUB(13); SUB(14); SUB(15); NEXT; // A1 - - ADD(10); ADD(11); - SUB(13); SUB(14); SUB(15); NEXT; // A2 - - ADD(11); ADD(11); ADD(12); ADD(12); ADD(13); - SUB(15); SUB(8); SUB(9); NEXT; // A3 - - ADD(12); ADD(12); ADD(13); ADD(13); ADD(14); - SUB(9); SUB(10); NEXT; // A4 - - ADD(13); ADD(13); ADD(14); ADD(14); ADD(15); - SUB(10); SUB(11); NEXT; // A5 - - ADD(14); ADD(14); ADD(15); ADD(15); ADD(14); ADD(13); - SUB(8); SUB(9); NEXT; // A6 - - ADD(15); ADD(15); ADD(15); ADD(8); - SUB(10); SUB(11); SUB(12); SUB(13); LAST; // A7 - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) - */ -static int ecp_mod_p384(mbedtls_mpi *N) -{ - INIT(384); - - ADD(12); ADD(21); ADD(20); - SUB(23); NEXT; // A0 - - ADD(13); ADD(22); ADD(23); - SUB(12); SUB(20); NEXT; // A2 - - ADD(14); ADD(23); - SUB(13); SUB(21); NEXT; // A2 - - ADD(15); ADD(12); ADD(20); ADD(21); - SUB(14); SUB(22); SUB(23); NEXT; // A3 - - ADD(21); ADD(21); ADD(16); ADD(13); ADD(12); ADD(20); ADD(22); - SUB(15); SUB(23); SUB(23); NEXT; // A4 - - ADD(22); ADD(22); ADD(17); ADD(14); ADD(13); ADD(21); ADD(23); - SUB(16); NEXT; // A5 - - ADD(23); ADD(23); ADD(18); ADD(15); ADD(14); ADD(22); - SUB(17); NEXT; // A6 - - ADD(19); ADD(16); ADD(15); ADD(23); - SUB(18); NEXT; // A7 - - ADD(20); ADD(17); ADD(16); - SUB(19); NEXT; // A8 - - ADD(21); ADD(18); ADD(17); - SUB(20); NEXT; // A9 - - ADD(22); ADD(19); ADD(18); - SUB(21); NEXT; // A10 - - ADD(23); ADD(20); ADD(19); - SUB(22); LAST; // A11 - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#undef A -#undef LOAD32 -#undef STORE32 -#undef MAX32 -#undef INIT -#undef NEXT -#undef LAST - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || - MBEDTLS_ECP_DP_SECP256R1_ENABLED || - MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -/* - * Here we have an actual Mersenne prime, so things are more straightforward. - * However, chunks are aligned on a 'weird' boundary (521 bits). - */ - -/* Size of p521 in terms of mbedtls_mpi_uint */ -#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1) - -/* Bits to keep in the most significant mbedtls_mpi_uint */ -#define P521_MASK 0x01FF - -/* - * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) - * Write N as A1 + 2^521 A0, return A0 + A1 - */ -static int ecp_mod_p521(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - mbedtls_mpi M; - mbedtls_mpi_uint Mp[P521_WIDTH + 1]; - /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: - * we need to hold bits 513 to 1056, which is 34 limbs, that is - * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ - - if (N->n < P521_WIDTH) { - return 0; - } - - /* M = A1 */ - M.s = 1; - M.n = N->n - (P521_WIDTH - 1); - if (M.n > P521_WIDTH + 1) { - M.n = P521_WIDTH + 1; - } - M.p = Mp; - memcpy(Mp, N->p + P521_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 521 % (8 * sizeof(mbedtls_mpi_uint)))); - - /* N = A0 */ - N->p[P521_WIDTH - 1] &= P521_MASK; - for (i = P521_WIDTH; i < N->n; i++) { - N->p[i] = 0; - } - - /* N = A0 + A1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); - -cleanup: - return ret; -} - -#undef P521_WIDTH -#undef P521_MASK -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - -/* Size of p255 in terms of mbedtls_mpi_uint */ -#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1) - -/* - * Fast quasi-reduction modulo p255 = 2^255 - 19 - * Write N as A0 + 2^256 A1, return A0 + 38 * A1 - */ -static int ecp_mod_p255(mbedtls_mpi *N) -{ - mbedtls_mpi_uint Mp[P255_WIDTH]; - - /* Helper references for top part of N */ - mbedtls_mpi_uint * const NT_p = N->p + P255_WIDTH; - const size_t NT_n = N->n - P255_WIDTH; - if (N->n <= P255_WIDTH) { - return 0; - } - if (NT_n > P255_WIDTH) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* Split N as N + 2^256 M */ - memcpy(Mp, NT_p, sizeof(mbedtls_mpi_uint) * NT_n); - memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); - - /* N = A0 + 38 * A1 */ - mbedtls_mpi_core_mla(N->p, P255_WIDTH + 1, - Mp, NT_n, - 38); - - return 0; -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - -/* Size of p448 in terms of mbedtls_mpi_uint */ -#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint)) - -/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */ -#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y)) -#define P224_SIZE (224 / 8) -#define P224_WIDTH_MIN (P224_SIZE / sizeof(mbedtls_mpi_uint)) -#define P224_WIDTH_MAX DIV_ROUND_UP(P224_SIZE, sizeof(mbedtls_mpi_uint)) -#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224) - -/* - * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 - * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return - * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference - * implementation of Curve448, which uses its own special 56-bit limbs rather - * than a generic bignum library. We could squeeze some extra speed out on - * 32-bit machines by splitting N up into 32-bit limbs and doing the - * arithmetic using the limbs directly as we do for the NIST primes above, - * but for 64-bit targets it should use half the number of operations if we do - * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds. - */ -static int ecp_mod_p448(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - mbedtls_mpi M, Q; - mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH]; - - if (N->n <= P448_WIDTH) { - return 0; - } - - /* M = A1 */ - M.s = 1; - M.n = N->n - (P448_WIDTH); - if (M.n > P448_WIDTH) { - /* Shouldn't be called with N larger than 2^896! */ - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - M.p = Mp; - memset(Mp, 0, sizeof(Mp)); - memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint)); - - /* N = A0 */ - for (i = P448_WIDTH; i < N->n; i++) { - N->p[i] = 0; - } - - /* N += A1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M)); - - /* Q = B1, N += B1 */ - Q = M; - Q.p = Qp; - memcpy(Qp, Mp, sizeof(Qp)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Q, 224)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &Q)); - - /* M = (B0 + B1) * 2^224, N += M */ - if (sizeof(mbedtls_mpi_uint) > 4) { - Mp[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS); - } - for (i = P224_WIDTH_MAX; i < M.n; ++i) { - Mp[i] = 0; - } - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q)); - M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */ - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M)); - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* - * Fast quasi-reduction modulo P = 2^s - R, - * with R about 33 bits, used by the Koblitz curves. - * - * Write N as A0 + 2^224 A1, return A0 + R * A1. - * Actually do two passes, since R is big. - */ -#define P_KOBLITZ_MAX (256 / 8 / sizeof(mbedtls_mpi_uint)) // Max limbs in P -#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R -static inline int ecp_mod_koblitz(mbedtls_mpi *N, const mbedtls_mpi_uint *Rp, size_t p_limbs, - size_t adjust, size_t shift, mbedtls_mpi_uint mask) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - mbedtls_mpi M, R; - mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; - - if (N->n < p_limbs) { - return 0; - } - - /* Init R */ - R.s = 1; - R.p = (mbedtls_mpi_uint *) Rp; /* R.p will not be modified so the cast is safe */ - R.n = P_KOBLITZ_R; - - /* Common setup for M */ - M.s = 1; - M.p = Mp; - - /* M = A1 */ - M.n = (unsigned short) (N->n - (p_limbs - adjust)); - if (M.n > p_limbs + adjust) { - M.n = (unsigned short) (p_limbs + adjust); - } - memset(Mp, 0, sizeof(Mp)); - memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint)); - if (shift != 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift)); - } - M.n += R.n; /* Make room for multiplication by R */ - - /* N = A0 */ - if (mask != 0) { - N->p[p_limbs - 1] &= mask; - } - for (i = p_limbs; i < N->n; i++) { - N->p[i] = 0; - } - - /* N = A0 + R * A1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); - - /* Second pass */ - - /* M = A1 */ - M.n = (unsigned short) (N->n - (p_limbs - adjust)); - if (M.n > p_limbs + adjust) { - M.n = (unsigned short) (p_limbs + adjust); - } - memset(Mp, 0, sizeof(Mp)); - memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint)); - if (shift != 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift)); - } - M.n += R.n; /* Make room for multiplication by R */ - - /* N = A0 */ - if (mask != 0) { - N->p[p_limbs - 1] &= mask; - } - for (i = p_limbs; i < N->n; i++) { - N->p[i] = 0; - } - - /* N = A0 + R * A1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || - MBEDTLS_ECP_DP_SECP224K1_ENABLED) || - MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -/* - * Fast quasi-reduction modulo p192k1 = 2^192 - R, - * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9 - */ -static int ecp_mod_p192k1(mbedtls_mpi *N) -{ - static const mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00) - }; - - return ecp_mod_koblitz(N, Rp, 192 / 8 / sizeof(mbedtls_mpi_uint), 0, 0, - 0); -} -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -/* - * Fast quasi-reduction modulo p224k1 = 2^224 - R, - * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 - */ -static int ecp_mod_p224k1(mbedtls_mpi *N) -{ - static const mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00) - }; - -#if defined(MBEDTLS_HAVE_INT64) - return ecp_mod_koblitz(N, Rp, 4, 1, 32, 0xFFFFFFFF); -#else - return ecp_mod_koblitz(N, Rp, 224 / 8 / sizeof(mbedtls_mpi_uint), 0, 0, - 0); -#endif -} - -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* - * Fast quasi-reduction modulo p256k1 = 2^256 - R, - * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 - */ -static int ecp_mod_p256k1(mbedtls_mpi *N) -{ - static const mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00) - }; - return ecp_mod_koblitz(N, Rp, 256 / 8 / sizeof(mbedtls_mpi_uint), 0, 0, - 0); -} -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_TEST_HOOKS) - -MBEDTLS_STATIC_TESTABLE -mbedtls_ecp_variant mbedtls_ecp_get_variant(void) -{ - return MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT; -} - -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* !MBEDTLS_ECP_ALT */ - -#endif /* MBEDTLS_ECP_LIGHT */ -#endif /* MBEDTLS_ECP_WITH_MPI_UINT */ diff --git a/vendor/mbedtls/library/ecp_curves_new.c b/vendor/mbedtls/library/ecp_curves_new.c deleted file mode 100644 index 035b23a1b..000000000 --- a/vendor/mbedtls/library/ecp_curves_new.c +++ /dev/null @@ -1,6036 +0,0 @@ -/* - * Elliptic curves over GF(p): curve-specific data and functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_ECP_WITH_MPI_UINT) - -#if defined(MBEDTLS_ECP_LIGHT) - -#include "mbedtls/ecp.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include "mbedtls/platform.h" - -#include "constant_time_internal.h" - -#include "bn_mul.h" -#include "bignum_core.h" -#include "ecp_invasive.h" - -#include - -#if !defined(MBEDTLS_ECP_ALT) - -#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } - -#define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) - -#define ECP_POINT_INIT_XY_Z0(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(NULL, 0) } -#define ECP_POINT_INIT_XY_Z1(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(mpi_one, 1) } - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -/* For these curves, we build the group parameters dynamically. */ -#define ECP_LOAD_GROUP -static mbedtls_mpi_uint mpi_one[] = { 1 }; -#endif - -/* - * Note: the constants are in little-endian order - * to be directly usable in MPIs - */ - -/* - * Domain parameters for secp192r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static const mbedtls_mpi_uint secp192r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp192r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64), -}; -static const mbedtls_mpi_uint secp192r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), -}; -static const mbedtls_mpi_uint secp192r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), -}; -static const mbedtls_mpi_uint secp192r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp192r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), -}; -static const mbedtls_mpi_uint secp192r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), -}; -static const mbedtls_mpi_uint secp192r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x9E, 0xE3, 0x60, 0x59, 0xD1, 0xC4, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBD, 0x22, 0xD7, 0x2D, 0x07, 0xBD, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x2A, 0xCF, 0x33, 0xF0, 0xBE, 0xD1, 0xED), -}; -static const mbedtls_mpi_uint secp192r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x71, 0x4B, 0xA8, 0xED, 0x7E, 0xC9, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x2A, 0xF6, 0xDF, 0x0E, 0xE8, 0x4C, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x35, 0xF7, 0x8A, 0xC3, 0xEC, 0xDE, 0x1E), -}; -static const mbedtls_mpi_uint secp192r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0xC2, 0x1D, 0x32, 0x8F, 0x10, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x2D, 0x17, 0xF3, 0xE4, 0xFE, 0xD8, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x45, 0x10, 0x70, 0x2C, 0x3E, 0x52, 0x3E), -}; -static const mbedtls_mpi_uint secp192r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF1, 0x04, 0x5D, 0xEE, 0xD4, 0x56, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xB7, 0x38, 0x27, 0x61, 0xAA, 0x81, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0xD7, 0x0E, 0x29, 0x0E, 0x11, 0x14), -}; -static const mbedtls_mpi_uint secp192r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x35, 0x52, 0xC6, 0x31, 0xB7, 0x27, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xD4, 0x15, 0x98, 0x0F, 0xE7, 0xF3, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x31, 0x70, 0x35, 0x09, 0xA0, 0x2B, 0xC2), -}; -static const mbedtls_mpi_uint secp192r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x75, 0xA7, 0x4C, 0x88, 0xCF, 0x5B, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x17, 0x48, 0x8D, 0xF2, 0xF0, 0x86, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCF, 0xFE, 0x6B, 0xB0, 0xA5, 0x06, 0xAB), -}; -static const mbedtls_mpi_uint secp192r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x6A, 0xDC, 0x9A, 0x6D, 0x7B, 0x47, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xFC, 0x51, 0x12, 0x62, 0x66, 0x0B, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x40, 0x93, 0xA0, 0xB5, 0x5A, 0x58, 0xD7), -}; -static const mbedtls_mpi_uint secp192r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCB, 0xAF, 0xDC, 0x0B, 0xA1, 0x26, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x36, 0x9D, 0xA3, 0xD7, 0x3B, 0xAD, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x3B, 0x05, 0x9A, 0xA8, 0xAA, 0x69, 0xB2), -}; -static const mbedtls_mpi_uint secp192r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD9, 0xD1, 0x4D, 0x4A, 0x6E, 0x96, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x66, 0x32, 0x39, 0xC6, 0x57, 0x7D, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xA0, 0x36, 0xC2, 0x45, 0xF9, 0x00, 0x62), -}; -static const mbedtls_mpi_uint secp192r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xEF, 0x59, 0x46, 0xDC, 0x60, 0xD9, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xB0, 0xE9, 0x41, 0xA4, 0x87, 0x76, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xD4, 0x0E, 0xB2, 0xFA, 0x16, 0x56, 0xDC), -}; -static const mbedtls_mpi_uint secp192r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x62, 0xD2, 0xB1, 0x34, 0xB2, 0xF1, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xED, 0x55, 0xC5, 0x47, 0xB5, 0x07, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF6, 0x2F, 0x94, 0xC3, 0xDD, 0x54, 0x2F), -}; -static const mbedtls_mpi_uint secp192r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xA6, 0xD4, 0x8C, 0xA9, 0xCE, 0x4D, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x4B, 0x46, 0xCC, 0xB2, 0x55, 0xC8, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x31, 0xED, 0x89, 0x65, 0x59, 0x55), -}; -static const mbedtls_mpi_uint secp192r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x0A, 0xD1, 0x1A, 0xC5, 0xF6, 0xEA, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xFC, 0x0C, 0x1A, 0xFB, 0xA0, 0xC8, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xFD, 0x53, 0x6F, 0x6D, 0xBF, 0xBA, 0xAF), -}; -static const mbedtls_mpi_uint secp192r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xB0, 0x7D, 0x83, 0x96, 0xE3, 0xCB, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x6E, 0x55, 0x2C, 0x20, 0x53, 0x2F, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x66, 0x00, 0x17, 0x08, 0xFE, 0xAC, 0x31), -}; -static const mbedtls_mpi_uint secp192r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x12, 0x97, 0x3A, 0xC7, 0x57, 0x45, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x25, 0x99, 0x00, 0xF6, 0x97, 0xB4, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x74, 0xE6, 0xE6, 0xA3, 0xDF, 0x9C, 0xCC), -}; -static const mbedtls_mpi_uint secp192r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xF4, 0x76, 0xD5, 0x5F, 0x2A, 0xFD, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x80, 0x7E, 0x3E, 0xE5, 0xE8, 0xD6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xAD, 0x1E, 0x70, 0x79, 0x3E, 0x3D, 0x83), -}; -static const mbedtls_mpi_uint secp192r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x15, 0xBB, 0xB3, 0x42, 0x6A, 0xA1, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x58, 0xCB, 0x43, 0x25, 0x00, 0x14, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x4E, 0x93, 0x11, 0xE0, 0x32, 0x54, 0x98), -}; -static const mbedtls_mpi_uint secp192r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x52, 0xA2, 0xB4, 0x57, 0x32, 0xB9, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x43, 0xA1, 0xB1, 0xFB, 0x01, 0xE1, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xFB, 0x5A, 0x11, 0xB8, 0xC2, 0x03, 0xE5), -}; -static const mbedtls_mpi_uint secp192r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x2B, 0x71, 0x26, 0x4E, 0x7C, 0xC5, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF5, 0xD3, 0xA8, 0xE4, 0x95, 0x48, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAE, 0xD9, 0x5D, 0x9F, 0x6A, 0x22, 0xAD), -}; -static const mbedtls_mpi_uint secp192r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xCC, 0xA3, 0x4D, 0xA0, 0x1C, 0x34, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x3C, 0x62, 0xF8, 0x5E, 0xA6, 0x58, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x6E, 0x66, 0x8A, 0x3D, 0x17, 0xFF, 0x0F), -}; -static const mbedtls_mpi_uint secp192r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xCD, 0xA8, 0xDD, 0xD1, 0x20, 0x5C, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xFE, 0x17, 0xE2, 0xCF, 0xEA, 0x63, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x51, 0xC9, 0x16, 0xDE, 0xB4, 0xB2, 0xDD), -}; -static const mbedtls_mpi_uint secp192r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBE, 0x12, 0xD7, 0xA3, 0x0A, 0x50, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x87, 0xC5, 0x8A, 0x76, 0x57, 0x07, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x1F, 0xC6, 0x1B, 0x66, 0xC4, 0x3D, 0x8A), -}; -static const mbedtls_mpi_uint secp192r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xA4, 0x85, 0x13, 0x8F, 0xA7, 0x35, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x0D, 0xFD, 0xFF, 0x1B, 0xD1, 0xD6, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x7A, 0xD0, 0xC3, 0xB4, 0xEF, 0x39, 0x66), -}; -static const mbedtls_mpi_uint secp192r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xFE, 0xA5, 0x9C, 0x34, 0x30, 0x49, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xC5, 0x39, 0x26, 0x06, 0xE3, 0x01, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x2B, 0x66, 0xFC, 0x95, 0x5F, 0x35, 0xF7), -}; -static const mbedtls_mpi_uint secp192r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xCF, 0x54, 0x63, 0x99, 0x57, 0x05, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x6F, 0x00, 0x5F, 0x65, 0x08, 0x47, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x2A, 0x90, 0x6D, 0x67, 0xC6, 0xBC, 0x45), -}; -static const mbedtls_mpi_uint secp192r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x4D, 0x88, 0x0A, 0x35, 0x9E, 0x33, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x17, 0x0C, 0xF8, 0xE1, 0x7A, 0x49, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x44, 0x06, 0x8F, 0x0B, 0x70, 0x2F, 0x71), -}; -static const mbedtls_mpi_uint secp192r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4B, 0xCB, 0xF9, 0x8E, 0x6A, 0xDA, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x43, 0xA1, 0x3F, 0xCE, 0x17, 0xD2, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x0D, 0xD2, 0x6C, 0x82, 0x37, 0xE5, 0xFC), -}; -static const mbedtls_mpi_uint secp192r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x3C, 0xF4, 0x92, 0xB4, 0x8A, 0x95, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x96, 0xF1, 0x0A, 0x34, 0x2F, 0x74, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0xAA, 0xBA, 0x86, 0x77, 0x4F, 0xA2), -}; -static const mbedtls_mpi_uint secp192r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x7F, 0xEF, 0x60, 0x50, 0x80, 0xD7, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xAC, 0xC9, 0xFE, 0xEC, 0x0A, 0x1A, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x2F, 0xBE, 0x91, 0xD7, 0xB7, 0x38, 0x48), -}; -static const mbedtls_mpi_uint secp192r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xAE, 0x85, 0x98, 0xFE, 0x05, 0x7F, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBE, 0xFD, 0x11, 0x31, 0x3D, 0x14, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x75, 0xE8, 0x30, 0x01, 0xCB, 0x9B, 0x1C), -}; -static const mbedtls_ecp_point secp192r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp192r1_T_0_X, secp192r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_1_X, secp192r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_2_X, secp192r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_3_X, secp192r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_4_X, secp192r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_5_X, secp192r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_6_X, secp192r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_7_X, secp192r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_8_X, secp192r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_9_X, secp192r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_10_X, secp192r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_11_X, secp192r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_12_X, secp192r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_13_X, secp192r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_14_X, secp192r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp192r1_T_15_X, secp192r1_T_15_Y), -}; -#else -#define secp192r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -/* - * Domain parameters for secp224r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static const mbedtls_mpi_uint secp224r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_4(0x85, 0x0A, 0x05, 0xB4), -}; -static const mbedtls_mpi_uint secp224r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_4(0xBD, 0x0C, 0x0E, 0xB7), -}; -static const mbedtls_mpi_uint secp224r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_4(0x88, 0x63, 0x37, 0xBD), -}; -static const mbedtls_mpi_uint secp224r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp224r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x0C, 0x0E, 0xB7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x63, 0x37, 0xBD, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF9, 0xB8, 0xD0, 0x3D, 0xD2, 0xD3, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xFD, 0x99, 0x26, 0x19, 0xFE, 0x13, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x0E, 0x4C, 0x48, 0x7C, 0xA2, 0x17, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA3, 0x13, 0x57, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x16, 0x5C, 0x8F, 0xAA, 0xED, 0x0F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xC5, 0x43, 0x34, 0x93, 0x05, 0x2A, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE3, 0x6C, 0xCA, 0xC6, 0x14, 0xC2, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x43, 0x6C, 0xD7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x5A, 0x98, 0x1E, 0xC8, 0xA5, 0x42, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x49, 0x56, 0x78, 0xF8, 0xEF, 0xED, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xBB, 0x64, 0xB6, 0x4C, 0x54, 0x5F, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x0C, 0x33, 0xCC, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x79, 0xCB, 0x2E, 0x08, 0xFF, 0xD8, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x1F, 0xD4, 0xD7, 0x57, 0xE9, 0x39, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xD6, 0x3B, 0x0A, 0x1C, 0x87, 0xB7, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x30, 0xD8, 0x05, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x79, 0x74, 0x9A, 0xE6, 0xBB, 0xC2, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x5B, 0xA6, 0x67, 0xC1, 0x91, 0xE7, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xDF, 0x38, 0x82, 0x19, 0x2C, 0x4C, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x2E, 0x39, 0xC5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x36, 0x78, 0x4E, 0xAE, 0x5B, 0x02, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF6, 0x8B, 0xF8, 0xF4, 0x92, 0x6B, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x4D, 0x71, 0x35, 0xE7, 0x0C, 0x2C, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xA5, 0x1F, 0xAE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x1C, 0x4B, 0xDF, 0x5B, 0xF2, 0x51, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0xB1, 0x5A, 0xC6, 0x0F, 0x0E, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x24, 0x09, 0x62, 0xAF, 0xFC, 0xDB, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xE1, 0x80, 0x55, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x82, 0xFE, 0xAD, 0xC3, 0xE5, 0xCF, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xA2, 0x62, 0x17, 0x76, 0xF0, 0x5A, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB8, 0xE5, 0xAC, 0xB7, 0x66, 0x38, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xFD, 0x86, 0x05, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0x0C, 0x3C, 0xD1, 0x66, 0xB0, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x59, 0xB4, 0x8D, 0x90, 0x10, 0xB7, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x47, 0x9B, 0xE6, 0x55, 0x8A, 0xE4, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x49, 0xDB, 0x78, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x97, 0xED, 0xDE, 0xFF, 0xB3, 0xDF, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xB9, 0x83, 0xB7, 0xEB, 0xBE, 0x40, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xD3, 0xD3, 0xCD, 0x0E, 0x82, 0x79, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x83, 0x1B, 0xF0, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x22, 0xBB, 0x54, 0xD3, 0x31, 0x56, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0xE5, 0xE0, 0x89, 0x96, 0x8E, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xEF, 0x0A, 0xED, 0xD0, 0x11, 0x4A, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x00, 0x57, 0x27, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCA, 0x3D, 0xF7, 0x64, 0x9B, 0x6E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xE3, 0x70, 0x6B, 0x41, 0xD7, 0xED, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x44, 0x44, 0x80, 0xCE, 0x13, 0x37, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x73, 0x80, 0x79, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x4D, 0x70, 0x7D, 0x31, 0x0F, 0x1C, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x35, 0x88, 0x47, 0xC4, 0x24, 0x78, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF0, 0xCD, 0x91, 0x81, 0xB3, 0xDE, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xCE, 0xC6, 0xF7, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x9C, 0x2D, 0xE8, 0xD2, 0x00, 0x8F, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x5E, 0x7C, 0x0E, 0x0C, 0x6E, 0x58, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x81, 0x21, 0xCE, 0x43, 0xF4, 0x24, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xBC, 0xF0, 0xF4, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x10, 0xC2, 0x74, 0x4A, 0x8F, 0x8A, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x67, 0xF4, 0x2B, 0x38, 0x2B, 0x35, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0C, 0xA9, 0xFA, 0x77, 0x5C, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x19, 0x2B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x3E, 0x96, 0x22, 0x53, 0xE1, 0xE9, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x13, 0xBC, 0xA1, 0x16, 0xEC, 0x01, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x00, 0xC9, 0x7A, 0xC3, 0x73, 0xA5, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xF4, 0x5E, 0xC1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x95, 0xD6, 0xD9, 0x32, 0x30, 0x2B, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x42, 0x09, 0x05, 0x61, 0x2A, 0x7E, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x84, 0xA2, 0x05, 0x88, 0x64, 0x65, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2D, 0x90, 0xB3, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE7, 0x2E, 0x85, 0x55, 0x80, 0x7C, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC1, 0xAC, 0x78, 0xB4, 0xAF, 0xFB, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xC3, 0x28, 0x8E, 0x79, 0x18, 0x1F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x46, 0xCF, 0x49, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x5F, 0xA8, 0x6C, 0x46, 0x83, 0x43, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xA9, 0x93, 0x11, 0xB6, 0x07, 0x57, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x2A, 0x9D, 0x03, 0x89, 0x7E, 0xD7, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x8C, 0x62, 0xCF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x2C, 0x13, 0x59, 0xCC, 0xFA, 0x84, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB9, 0x48, 0xBC, 0x57, 0xC7, 0xB3, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x0A, 0x38, 0x24, 0x2E, 0x3A, 0x28, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x0A, 0x43, 0xB8, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x25, 0xAB, 0xC1, 0xEE, 0x70, 0x3C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xDB, 0x45, 0x1D, 0x4A, 0x80, 0x75, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1F, 0x4D, 0x2D, 0x9A, 0x05, 0xF4, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x10, 0xF0, 0x5A, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x95, 0xE1, 0xDC, 0x15, 0x86, 0xC3, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xDC, 0x27, 0xD1, 0x56, 0xA1, 0x14, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x0B, 0xD6, 0x77, 0x4E, 0x44, 0xA2, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x42, 0x71, 0x1F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x86, 0xB2, 0xB0, 0xC8, 0x2F, 0x7B, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xEF, 0xCB, 0xDB, 0xBC, 0x9E, 0x3B, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x03, 0x86, 0xDD, 0x5B, 0xF5, 0x8D, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x95, 0x79, 0xD6, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x32, 0x14, 0xDA, 0x9B, 0x4F, 0x07, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x3E, 0xFB, 0x06, 0xEE, 0xA7, 0x40, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x1F, 0xDF, 0x71, 0x61, 0xFD, 0x8B, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x8B, 0xAB, 0x8B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x34, 0xB3, 0xB4, 0xBC, 0x9F, 0xB0, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x58, 0x48, 0xA8, 0x77, 0xBB, 0x13, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC6, 0xF7, 0x34, 0xCC, 0x89, 0x21, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x33, 0xDD, 0x1F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x81, 0xEF, 0xA4, 0xF2, 0x10, 0x0B, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF7, 0x6E, 0x72, 0x4A, 0xDF, 0xDD, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x23, 0x0A, 0x53, 0x03, 0x16, 0x62, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x76, 0xFD, 0x3C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x14, 0xA1, 0xFA, 0xA0, 0x18, 0xBE, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2A, 0xE1, 0xD7, 0xB0, 0x6C, 0xA0, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xC0, 0xB0, 0xC6, 0x63, 0x24, 0xCD, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x38, 0x2C, 0xB1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCD, 0x7D, 0x20, 0x0C, 0xFE, 0xAC, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x9F, 0xA2, 0xB6, 0x45, 0xF7, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x99, 0xF3, 0xD2, 0x20, 0x02, 0xEB, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x5B, 0x7B, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xDD, 0x77, 0x91, 0x60, 0xEA, 0xFD, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xD3, 0xB5, 0xD6, 0x90, 0x17, 0x0E, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xF4, 0x28, 0xC1, 0xF2, 0x53, 0xF6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x58, 0xDC, 0x61, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x20, 0x01, 0xFB, 0xF1, 0xBD, 0x5F, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x7F, 0x06, 0xDA, 0x11, 0xCB, 0xBA, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x41, 0x00, 0xA4, 0x1B, 0x30, 0x33, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xFF, 0x27, 0xCA, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp224r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp224r1_T_0_X, secp224r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_1_X, secp224r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_2_X, secp224r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_3_X, secp224r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_4_X, secp224r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_5_X, secp224r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_6_X, secp224r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_7_X, secp224r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_8_X, secp224r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_9_X, secp224r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_10_X, secp224r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_11_X, secp224r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_12_X, secp224r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_13_X, secp224r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_14_X, secp224r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp224r1_T_15_X, secp224r1_T_15_Y), -}; -#else -#define secp224r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -/* - * Domain parameters for secp256r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static const mbedtls_mpi_uint secp256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A), -}; -static const mbedtls_mpi_uint secp256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), -}; -static const mbedtls_mpi_uint secp256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), -}; -static const mbedtls_mpi_uint secp256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp256r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), -}; -static const mbedtls_mpi_uint secp256r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), -}; -static const mbedtls_mpi_uint secp256r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xC8, 0xBA, 0x04, 0xB7, 0x4B, 0xD2, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC6, 0x23, 0x3A, 0xA0, 0x09, 0x3A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x9D, 0x4C, 0xF9, 0x58, 0x23, 0xCC, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xED, 0x7B, 0x29, 0x87, 0x0F, 0xFA, 0x3C), -}; -static const mbedtls_mpi_uint secp256r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x69, 0xF2, 0x40, 0x0B, 0xA3, 0x98, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xA8, 0x48, 0x02, 0x0D, 0x1C, 0x12, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xAF, 0x09, 0x83, 0x80, 0xAA, 0x58, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x12, 0xBE, 0x70, 0x94, 0x76, 0xE3, 0xE4), -}; -static const mbedtls_mpi_uint secp256r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x7D, 0xEF, 0x86, 0xFF, 0xE3, 0x37, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x86, 0x8B, 0x08, 0x27, 0x7C, 0xD7, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x54, 0x4C, 0x25, 0x4F, 0x9A, 0xFE, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xFD, 0xF0, 0x6D, 0x37, 0x03, 0x69, 0xD6), -}; -static const mbedtls_mpi_uint secp256r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xD5, 0xDA, 0xAD, 0x92, 0x49, 0xF0, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x73, 0x43, 0x9E, 0xAF, 0xA7, 0xD1, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x41, 0x07, 0xDF, 0x78, 0x95, 0x3E, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x3D, 0xD1, 0xE6, 0x3C, 0xA5, 0xE2, 0x20), -}; -static const mbedtls_mpi_uint secp256r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x6A, 0x5D, 0x52, 0x35, 0xD7, 0xBF, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xA2, 0xBE, 0x96, 0xF4, 0xF8, 0x02, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x20, 0x49, 0x54, 0xEA, 0xB3, 0x82, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0xDB, 0xEA, 0x02, 0xD1, 0x75, 0x1C, 0x62), -}; -static const mbedtls_mpi_uint secp256r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x85, 0xF4, 0x9E, 0x4C, 0xDC, 0x39, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x6D, 0xC4, 0x57, 0xD8, 0x03, 0x5D, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x7F, 0x2D, 0x52, 0x6F, 0xC9, 0xDA, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x64, 0xFA, 0xB4, 0xFE, 0xA4, 0xC4, 0xD7), -}; -static const mbedtls_mpi_uint secp256r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x37, 0xB9, 0xC0, 0xAA, 0x59, 0xC6, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x58, 0xD9, 0xED, 0x58, 0x99, 0x65, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x7D, 0x26, 0x8C, 0x4A, 0xF9, 0x05, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x73, 0x9A, 0xC9, 0xE7, 0x46, 0xDC, 0x00), -}; -static const mbedtls_mpi_uint secp256r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xD0, 0x55, 0xDF, 0x00, 0x0A, 0xF5, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xBF, 0x56, 0x81, 0x2D, 0x20, 0xEB, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC1, 0x28, 0x52, 0xAB, 0xE3, 0xD1, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x34, 0x79, 0x45, 0x57, 0xA5, 0x12, 0x03), -}; -static const mbedtls_mpi_uint secp256r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCF, 0xB8, 0x7E, 0xF7, 0x92, 0x96, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x01, 0x8C, 0x0D, 0x23, 0xF2, 0xE3, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x2E, 0xE3, 0x84, 0x52, 0x7A, 0x34, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xA1, 0xB0, 0x15, 0x90, 0xE2, 0x53, 0x3C), -}; -static const mbedtls_mpi_uint secp256r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x98, 0xE7, 0xFA, 0xA5, 0x7D, 0x8B, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x35, 0xD2, 0x00, 0xD1, 0x1B, 0x9F, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x69, 0x08, 0x9A, 0x72, 0xF0, 0xA9, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xFE, 0x0E, 0x14, 0xDA, 0x7C, 0x0E, 0xD3), -}; -static const mbedtls_mpi_uint secp256r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF6, 0xE8, 0xF8, 0x87, 0xF7, 0xFC, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xBE, 0x7F, 0x3F, 0x7A, 0x2B, 0xD7, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x32, 0xF2, 0x2D, 0x94, 0x6D, 0x42, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x9A, 0xE3, 0x5F, 0x42, 0xBB, 0x84, 0xED), -}; -static const mbedtls_mpi_uint secp256r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x95, 0x29, 0x73, 0xA1, 0x67, 0x3E, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x30, 0x54, 0x35, 0x8E, 0x0A, 0xDD, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xD7, 0xA1, 0x97, 0x61, 0x3B, 0xF8, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x33, 0x3C, 0x58, 0x55, 0x34, 0x23, 0xA3), -}; -static const mbedtls_mpi_uint secp256r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x5D, 0x16, 0x5F, 0x7B, 0xBC, 0xBB, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xEE, 0x4E, 0x8A, 0xC1, 0x51, 0xCC, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0D, 0x4D, 0x1B, 0x53, 0x23, 0x1D, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x2A, 0x38, 0x66, 0x52, 0x84, 0xE1, 0x95), -}; -static const mbedtls_mpi_uint secp256r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x9B, 0x83, 0x0A, 0x81, 0x4F, 0xAD, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xFF, 0x42, 0x41, 0x6E, 0xA9, 0xA2, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA1, 0x4F, 0x1F, 0x89, 0x82, 0xAA, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xB8, 0x0F, 0x6B, 0x8F, 0x8C, 0xD6, 0x68), -}; -static const mbedtls_mpi_uint secp256r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0xB3, 0xBB, 0x51, 0x69, 0xA2, 0x11, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x4F, 0x0F, 0x8D, 0xBD, 0x26, 0x0F, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xCB, 0xEC, 0x6B, 0x34, 0xC3, 0x3D, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x5D, 0x1E, 0x10, 0xD5, 0x44, 0xE2, 0x54), -}; -static const mbedtls_mpi_uint secp256r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x9E, 0xB1, 0xF1, 0x6E, 0x4C, 0xAD, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE3, 0xC2, 0x58, 0xC0, 0xFB, 0x34, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x9C, 0xDF, 0x35, 0x07, 0x41, 0xBD, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x10, 0xEC, 0x0E, 0xEC, 0xBB, 0xD6), -}; -static const mbedtls_mpi_uint secp256r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xCF, 0xEF, 0x3F, 0x83, 0x1A, 0x88, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x29, 0xB5, 0xB9, 0xE0, 0xC9, 0xA3, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x46, 0x1E, 0x77, 0xCD, 0x7E, 0xB3, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x21, 0xD0, 0xD4, 0xA3, 0x16, 0x08, 0xEE), -}; -static const mbedtls_mpi_uint secp256r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xCA, 0xA8, 0xB3, 0xBF, 0x29, 0x99, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF2, 0x05, 0xC1, 0xCF, 0x5D, 0x91, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x01, 0x49, 0xDB, 0x82, 0xDF, 0x5F, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x06, 0x90, 0xAD, 0xE3, 0x38, 0xA4, 0xC4), -}; -static const mbedtls_mpi_uint secp256r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xD2, 0x3A, 0xE8, 0x03, 0xC5, 0x6D, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x35, 0xD0, 0xAE, 0x1D, 0x7A, 0x9F, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x1E, 0xD2, 0xCB, 0xAC, 0x88, 0x27, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x9C, 0xE0, 0x31, 0xDD, 0x99, 0x86), -}; -static const mbedtls_mpi_uint secp256r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF9, 0x9B, 0x32, 0x96, 0x41, 0x58, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x5A, 0x2A, 0xB8, 0x96, 0x0E, 0xB2, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x78, 0x2C, 0xC7, 0x08, 0x99, 0x19, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x59, 0x28, 0xE9, 0x84, 0x54, 0xE6, 0x16), -}; -static const mbedtls_mpi_uint secp256r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x38, 0x30, 0xDB, 0x70, 0x2C, 0x0A, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x5C, 0x9D, 0xE9, 0xD5, 0x46, 0x0B, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x0B, 0x60, 0x4B, 0x37, 0x7D, 0xB9, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x24, 0xF3, 0x3D, 0x79, 0x7F, 0x6C, 0x18), -}; -static const mbedtls_mpi_uint secp256r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7F, 0xE5, 0x1C, 0x4F, 0x60, 0x24, 0xF7, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xD8, 0xE2, 0x91, 0x7F, 0x89, 0x49, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xA7, 0x2E, 0x8D, 0x6A, 0xB3, 0x39, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x89, 0xB5, 0x9A, 0xB8, 0x8D, 0x42, 0x9C), -}; -static const mbedtls_mpi_uint secp256r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x45, 0xE6, 0x4B, 0x3F, 0x4F, 0x1E, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x65, 0x5E, 0x59, 0x22, 0xCC, 0x72, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x93, 0x1A, 0x27, 0x1E, 0x34, 0xC5, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xF2, 0xA5, 0x58, 0x5C, 0x15, 0x2E, 0xC6), -}; -static const mbedtls_mpi_uint secp256r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x7F, 0xBA, 0x58, 0x5A, 0x84, 0x6F, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA6, 0x36, 0x7E, 0xDC, 0xF7, 0xE1, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x4D, 0xAA, 0xEE, 0x57, 0x76, 0x3A, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x7E, 0x26, 0x18, 0x22, 0x23, 0x9F, 0xFF), -}; -static const mbedtls_mpi_uint secp256r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x4C, 0x64, 0xC7, 0x55, 0x02, 0x3F, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x02, 0x90, 0xBB, 0xC3, 0xEC, 0x30, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x6F, 0x64, 0xF4, 0x16, 0x69, 0x48, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x44, 0x9C, 0x95, 0x0C, 0x7D, 0x67, 0x5E), -}; -static const mbedtls_mpi_uint secp256r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x91, 0x8B, 0xD8, 0xD0, 0xD7, 0xE7, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF9, 0x48, 0x62, 0x6F, 0xA8, 0x93, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x3A, 0x99, 0x02, 0xD5, 0x0B, 0x3D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xD3, 0x00, 0x31, 0xE6, 0x0C, 0x9F, 0x44), -}; -static const mbedtls_mpi_uint secp256r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xB2, 0xAA, 0xFD, 0x88, 0x15, 0xDF, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0x35, 0x27, 0x31, 0x44, 0xCD, 0xC0, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xF8, 0x91, 0xA5, 0x71, 0x94, 0x84, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xCB, 0xD0, 0x93, 0xE9, 0x88, 0xDA, 0xE4), -}; -static const mbedtls_mpi_uint secp256r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC6, 0x39, 0x16, 0x5D, 0xA3, 0x1E, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x07, 0x37, 0x26, 0x36, 0x2A, 0xFE, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xBC, 0xF3, 0xD0, 0xDE, 0x50, 0xFC, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x2E, 0x06, 0x10, 0x15, 0x4D, 0xFA, 0xF7), -}; -static const mbedtls_mpi_uint secp256r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x65, 0x69, 0x5B, 0x66, 0xA2, 0x75, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x16, 0x00, 0x5A, 0xB0, 0x30, 0x25, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xFB, 0x86, 0x42, 0x80, 0xC1, 0xC4, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x1D, 0x83, 0x8E, 0x94, 0x01, 0x5F, 0x82), -}; -static const mbedtls_mpi_uint secp256r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x37, 0x70, 0xEF, 0x1F, 0xA1, 0xF0, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x5B, 0xCE, 0xC4, 0x9B, 0x6F, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x11, 0x11, 0x24, 0x4F, 0x4C, 0x79, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x3A, 0x72, 0xBC, 0xFE, 0x72, 0x58, 0x43), -}; -static const mbedtls_ecp_point secp256r1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp256r1_T_0_X, secp256r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_1_X, secp256r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_2_X, secp256r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_3_X, secp256r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_4_X, secp256r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_5_X, secp256r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_6_X, secp256r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_7_X, secp256r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_8_X, secp256r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_9_X, secp256r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_10_X, secp256r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_11_X, secp256r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_12_X, secp256r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_13_X, secp256r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_14_X, secp256r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp256r1_T_15_X, secp256r1_T_15_Y), -}; -#else -#define secp256r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -/* - * Domain parameters for secp384r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static const mbedtls_mpi_uint secp384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3), -}; -static const mbedtls_mpi_uint secp384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), -}; -static const mbedtls_mpi_uint secp384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp384r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), -}; -static const mbedtls_mpi_uint secp384r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x92, 0x00, 0x2C, 0x78, 0xDB, 0x1F, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF3, 0xEB, 0xB7, 0x06, 0xF7, 0xB6, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBC, 0x2C, 0xCF, 0xD8, 0xED, 0x53, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x75, 0x7B, 0xA3, 0xAB, 0xC3, 0x2C, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x9D, 0x78, 0x41, 0xF6, 0x76, 0x84, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x56, 0xE8, 0x52, 0xB3, 0xCB, 0xA8, 0xBD), -}; -static const mbedtls_mpi_uint secp384r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xF2, 0xAE, 0xA4, 0xB6, 0x89, 0x1B, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0xCE, 0x1C, 0x7C, 0xF6, 0x50, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xEB, 0x90, 0xE6, 0x4D, 0xC7, 0xD4, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x49, 0x2D, 0x8A, 0x01, 0x99, 0x60, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x80, 0x9B, 0x9B, 0x6A, 0xB0, 0x07, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xA2, 0xEE, 0x59, 0xBE, 0x95, 0xBC, 0x23), -}; -static const mbedtls_mpi_uint secp384r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x9D, 0x56, 0xAE, 0x59, 0xFB, 0x1F, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xAC, 0x91, 0x80, 0x87, 0xA8, 0x6E, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x08, 0xA7, 0x08, 0x94, 0x32, 0xFC, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x29, 0x9E, 0x84, 0xF4, 0xE5, 0x6E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x21, 0xB9, 0x50, 0x24, 0xF8, 0x9C, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x04, 0x01, 0xC2, 0xFB, 0x77, 0x3E, 0xDE), -}; -static const mbedtls_mpi_uint secp384r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x38, 0xEE, 0xE3, 0xC7, 0x9D, 0xEC, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x88, 0xCF, 0x43, 0xFA, 0x92, 0x5E, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xCA, 0x43, 0xF8, 0x3B, 0x49, 0x7E, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xE7, 0xEB, 0x17, 0x45, 0x86, 0xC2, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x69, 0x57, 0x32, 0xE0, 0x9C, 0xD1, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x10, 0xB8, 0x4D, 0xB8, 0xF4, 0x0D, 0xE3), -}; -static const mbedtls_mpi_uint secp384r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0xDC, 0x9A, 0xB2, 0x79, 0x39, 0x27, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x71, 0xE4, 0x3B, 0x4D, 0x60, 0x0C, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xBD, 0x19, 0x40, 0xFA, 0x19, 0x2A, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xF8, 0x1E, 0x43, 0xA1, 0x50, 0x8D, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x18, 0x7C, 0x41, 0xFA, 0x7C, 0x1B, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x24, 0xC4, 0xE9, 0xB7, 0xD3, 0xAD), -}; -static const mbedtls_mpi_uint secp384r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x01, 0x3D, 0x63, 0x54, 0x45, 0x6F, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xB2, 0x19, 0xA3, 0x86, 0x1D, 0x42, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x02, 0x87, 0x18, 0x92, 0x52, 0x1A, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x18, 0xB1, 0x5D, 0x18, 0x1B, 0x37, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x74, 0x61, 0xBA, 0x18, 0xAF, 0x40, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7D, 0x3C, 0x52, 0x0F, 0x07, 0xB0, 0x6F), -}; -static const mbedtls_mpi_uint secp384r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x39, 0x13, 0xAA, 0x60, 0x15, 0x99, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x00, 0xCB, 0xC6, 0xB1, 0xDB, 0x97, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xFA, 0x60, 0xB8, 0x24, 0xE4, 0x7D, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x75, 0xB3, 0x70, 0xB2, 0x83, 0xB1, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xE3, 0x6C, 0xCD, 0x33, 0x62, 0x7A, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x30, 0xDC, 0x0F, 0x9F, 0xBB, 0xB8, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD5, 0x0A, 0x60, 0x81, 0xB9, 0xC5, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xAA, 0x2F, 0xD6, 0xF2, 0x73, 0xDF, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x7B, 0x74, 0xC9, 0xB3, 0x5B, 0x95, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x04, 0xEB, 0x15, 0xC8, 0x5F, 0x00, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x50, 0x20, 0x28, 0xD1, 0x01, 0xAF, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x4F, 0x31, 0x81, 0x2F, 0x94, 0x48), -}; -static const mbedtls_mpi_uint secp384r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2F, 0xD8, 0xB6, 0x63, 0x7C, 0xE9, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x8C, 0xB9, 0x14, 0xD9, 0x37, 0x63, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x02, 0xB8, 0x46, 0xAD, 0xCE, 0x7B, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x47, 0x2D, 0x66, 0xA7, 0xE9, 0x33, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF9, 0x93, 0x94, 0xA8, 0x48, 0xB3, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x4A, 0xAC, 0x51, 0x08, 0x72, 0x2F, 0x1A), -}; -static const mbedtls_mpi_uint secp384r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xAD, 0xA0, 0xF9, 0x81, 0xE1, 0x78, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9A, 0x63, 0xD8, 0xBA, 0x79, 0x1A, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x31, 0x7B, 0x7A, 0x5A, 0x5D, 0x7D, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x96, 0x12, 0x4B, 0x19, 0x09, 0xE0, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8A, 0x57, 0xEE, 0x4E, 0x6E, 0x7E, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x9D, 0x69, 0xDC, 0xB3, 0xDA, 0xD8, 0x08), -}; -static const mbedtls_mpi_uint secp384r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x49, 0x03, 0x03, 0x33, 0x6F, 0x28, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xDB, 0xA7, 0x05, 0x8C, 0xF3, 0x4D, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x92, 0xB1, 0xA8, 0xEC, 0x0D, 0x64, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0xFC, 0xFD, 0xD0, 0x4B, 0x88, 0x1B, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x9C, 0x51, 0x69, 0xCE, 0x71, 0x73, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5A, 0x14, 0x23, 0x1A, 0x46, 0x63, 0x5F), -}; -static const mbedtls_mpi_uint secp384r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x4C, 0x70, 0x44, 0x18, 0xCD, 0xEF, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x49, 0xDD, 0x64, 0x7E, 0x7E, 0x4D, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x32, 0x7C, 0x09, 0xD0, 0x3F, 0xD6, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE0, 0x4F, 0x65, 0x0C, 0x7A, 0x54, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFA, 0xFB, 0x4A, 0xB4, 0x79, 0x5A, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x1B, 0x2B, 0xDA, 0xBC, 0x9A, 0x74), -}; -static const mbedtls_mpi_uint secp384r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xAC, 0x56, 0xF7, 0x5F, 0x51, 0x68, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xE0, 0x1D, 0xBC, 0x13, 0x4E, 0xAC, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF5, 0xC5, 0xE6, 0xD2, 0x88, 0xBA, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x0E, 0x28, 0x23, 0x58, 0x67, 0xFA, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x80, 0x4B, 0xD8, 0xC4, 0xDF, 0x15, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x0E, 0x58, 0xE6, 0x2C, 0x59, 0xC2, 0x03), -}; -static const mbedtls_mpi_uint secp384r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x26, 0x27, 0x99, 0x16, 0x2B, 0x22, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF3, 0x8F, 0xC3, 0x2A, 0x9B, 0xFC, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2E, 0x83, 0x3D, 0xFE, 0x9E, 0x3C, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0xCD, 0x2D, 0xC1, 0x49, 0x38, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x42, 0x8B, 0x33, 0x89, 0x1F, 0xEA, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x1D, 0x13, 0xD7, 0x50, 0xBB, 0x3E, 0xEB), -}; -static const mbedtls_mpi_uint secp384r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x9A, 0x52, 0xD2, 0x54, 0x7C, 0x97, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x6E, 0xED, 0xD9, 0x87, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x35, 0x7E, 0x16, 0x40, 0x15, 0x83, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x2B, 0xA4, 0xAB, 0x03, 0x91, 0xEA, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x47, 0x39, 0xEF, 0x05, 0x59, 0xD0, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x24, 0x0D, 0x76, 0x11, 0x53, 0x08, 0xAF), -}; -static const mbedtls_mpi_uint secp384r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x2F, 0xDD, 0xBD, 0x50, 0x48, 0xB1, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x1C, 0x84, 0x55, 0x78, 0x14, 0xEB, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x5E, 0x3E, 0xA6, 0xAF, 0xF6, 0xC7, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x11, 0xE2, 0x65, 0xCA, 0x41, 0x95, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x83, 0xD8, 0xE6, 0x4D, 0x22, 0x06, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x7F, 0x25, 0x2A, 0xAA, 0x28, 0x46, 0x97), -}; -static const mbedtls_mpi_uint secp384r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xDB, 0x15, 0x56, 0x84, 0xCB, 0xC0, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xDB, 0x0E, 0x08, 0xC9, 0xF5, 0xD4, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x62, 0xD0, 0x1A, 0x7C, 0x13, 0xD5, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xAD, 0x53, 0xE0, 0x32, 0x21, 0xA0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x38, 0x81, 0x21, 0x23, 0x0E, 0xD2, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x51, 0x05, 0xD0, 0x1E, 0x82, 0xA9, 0x71), -}; -static const mbedtls_mpi_uint secp384r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xC3, 0x27, 0xBF, 0xC6, 0xAA, 0xB7, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x65, 0x45, 0xDF, 0xB9, 0x46, 0x17, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x38, 0x3F, 0xB2, 0xB1, 0x5D, 0xCA, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x29, 0x6C, 0x63, 0xE9, 0xD7, 0x48, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xF1, 0xD7, 0x99, 0x8C, 0xC2, 0x05, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE6, 0x5E, 0x82, 0x6D, 0xE5, 0x7E, 0xD5), -}; -static const mbedtls_mpi_uint secp384r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x61, 0xFA, 0x7D, 0x01, 0xDB, 0xB6, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC6, 0x58, 0x39, 0xF4, 0xC6, 0x82, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0x7A, 0x80, 0x08, 0xCD, 0xAA, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x8C, 0xC6, 0x3F, 0x3C, 0xA5, 0x68, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xF5, 0xD5, 0x17, 0xAE, 0x36, 0xD8, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xAD, 0x92, 0xC5, 0x57, 0x6C, 0xDA, 0x91), -}; -static const mbedtls_mpi_uint secp384r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x67, 0x17, 0xC0, 0x40, 0x78, 0x8C, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x9F, 0xF4, 0xAA, 0xDA, 0x5C, 0x7E, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xDB, 0x42, 0x3E, 0x72, 0x64, 0xA0, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xF9, 0x41, 0x17, 0x43, 0xE3, 0xE8, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xDD, 0xCC, 0x43, 0x7E, 0x16, 0x05, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x4B, 0xCF, 0x48, 0x8F, 0x41, 0x90, 0xE5), -}; -static const mbedtls_mpi_uint secp384r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x0C, 0x6B, 0x9D, 0x22, 0x04, 0xBC, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x63, 0x79, 0x2F, 0x6A, 0x0E, 0x8A, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x67, 0x3F, 0x02, 0xB8, 0x91, 0x7F, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x14, 0x64, 0xA0, 0x33, 0xF4, 0x6B, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x44, 0x71, 0x87, 0xB8, 0x88, 0x3F, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x2B, 0x85, 0x05, 0xC5, 0x44, 0x53, 0x15), -}; -static const mbedtls_mpi_uint secp384r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x2B, 0xFE, 0xD1, 0x1C, 0x73, 0xE3, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x33, 0xA1, 0xD3, 0x69, 0x1C, 0x9D, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x5A, 0xBA, 0xB6, 0xAE, 0x1B, 0x94, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x74, 0x90, 0x5C, 0x57, 0xB0, 0x3A, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x2F, 0x93, 0x20, 0x24, 0x54, 0x1D, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x78, 0x9D, 0x71, 0x67, 0x5D, 0x49, 0x98), -}; -static const mbedtls_mpi_uint secp384r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xC8, 0x0E, 0x11, 0x8D, 0xE0, 0x8F, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x7F, 0x79, 0x6C, 0x5F, 0xB7, 0xBC, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xE1, 0x83, 0x3C, 0x12, 0xBB, 0xEE, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC2, 0xC4, 0x1B, 0x41, 0x71, 0xB9, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0xEE, 0xBB, 0x1D, 0x89, 0x50, 0x88, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x1C, 0x55, 0x74, 0xEB, 0xDE, 0x92, 0x3F), -}; -static const mbedtls_mpi_uint secp384r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x38, 0x92, 0x06, 0x19, 0xD0, 0xB3, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x99, 0x26, 0xA3, 0x5F, 0xE2, 0xC1, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xFC, 0xFD, 0xC3, 0xB6, 0x26, 0x24, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xAD, 0xE7, 0x49, 0xB7, 0x64, 0x4B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x4E, 0x95, 0xAD, 0x07, 0xFE, 0xB6, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x15, 0xE7, 0x2D, 0x19, 0xA9, 0x08, 0x10), -}; -static const mbedtls_mpi_uint secp384r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xBD, 0xAC, 0x0A, 0x3F, 0x6B, 0xFF, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xE4, 0x74, 0x14, 0xD9, 0x70, 0x1D, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xB0, 0x71, 0xBB, 0xD8, 0x18, 0x96, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xB8, 0x19, 0x90, 0x80, 0xB5, 0xEE, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x21, 0x20, 0xA6, 0x17, 0x48, 0x03, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0xBB, 0x6D, 0x94, 0x20, 0x34, 0xF1), -}; -static const mbedtls_mpi_uint secp384r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x82, 0x67, 0x4B, 0x8E, 0x4E, 0xBE, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xDA, 0x77, 0xF8, 0x23, 0x55, 0x2B, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x02, 0xDE, 0x25, 0x35, 0x2D, 0x74, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0C, 0xB8, 0x0B, 0x39, 0xBA, 0xAD, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x0E, 0x28, 0x4D, 0xE1, 0x3D, 0xE4, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xEC, 0x0A, 0xD4, 0xB8, 0xC4, 0x8D, 0xB0), -}; -static const mbedtls_mpi_uint secp384r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x68, 0xCE, 0xC2, 0x55, 0x4D, 0x0C, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x20, 0x93, 0x32, 0x90, 0xD6, 0xAE, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x78, 0xAB, 0x43, 0x9E, 0xEB, 0x73, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x97, 0xC3, 0x83, 0xA6, 0x3C, 0xF1, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x25, 0x25, 0x66, 0x08, 0x26, 0xFA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xFB, 0x44, 0x5D, 0x82, 0xEC, 0x3B, 0xAC), -}; -static const mbedtls_mpi_uint secp384r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x90, 0xEA, 0xB5, 0x04, 0x99, 0xD0, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0xF2, 0x22, 0xA0, 0xEB, 0xFD, 0x45, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA4, 0x81, 0x32, 0xFC, 0xFA, 0xEE, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xBB, 0xA4, 0x6A, 0x77, 0x41, 0x5C, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x1E, 0xAA, 0x4F, 0xF0, 0x10, 0xB3, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x74, 0x13, 0x14, 0x9E, 0x90, 0xD7, 0xE6), -}; -static const mbedtls_mpi_uint secp384r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xBD, 0x70, 0x4F, 0xA8, 0xD1, 0x06, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4E, 0x2E, 0x68, 0xFC, 0x35, 0xFA, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x53, 0x75, 0xED, 0xF2, 0x5F, 0xC2, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x87, 0x6B, 0x9F, 0x05, 0xE2, 0x22, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x1A, 0xA8, 0xB7, 0x03, 0x9E, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD0, 0x69, 0x88, 0xA8, 0x39, 0x9E, 0x3A), -}; -static const mbedtls_mpi_uint secp384r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xEF, 0x68, 0xFE, 0xEC, 0x24, 0x08, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x4B, 0x92, 0x0D, 0xB7, 0x34, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF4, 0xDD, 0x1A, 0xA0, 0x4A, 0xE4, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x63, 0x4F, 0x4F, 0xCE, 0xBB, 0xD6, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xEE, 0x8D, 0xDF, 0x3F, 0x73, 0xB7, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x06, 0xB6, 0x80, 0x4D, 0x81, 0xD9, 0x53), -}; -static const mbedtls_mpi_uint secp384r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF5, 0x13, 0xDF, 0x13, 0x19, 0x97, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xF9, 0xB3, 0x33, 0x66, 0x82, 0x21, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xFC, 0x39, 0x16, 0x23, 0x43, 0x76, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x48, 0x25, 0xA1, 0x64, 0x95, 0x1C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xAC, 0x15, 0x57, 0xD9, 0xDE, 0xA0, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x5F, 0xB8, 0x3D, 0x48, 0x91, 0x24, 0xCC), -}; -static const mbedtls_mpi_uint secp384r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xF2, 0xC8, 0x54, 0xD1, 0x32, 0xBD, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x3B, 0xF0, 0xAA, 0x9D, 0xD8, 0xF4, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xC3, 0xBB, 0x6C, 0x66, 0xAC, 0x25, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x25, 0x10, 0xB2, 0xE1, 0x41, 0xDE, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xE8, 0x30, 0xB8, 0x37, 0xBC, 0x2A, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x57, 0x01, 0x4A, 0x1E, 0x78, 0x9F, 0x85), -}; -static const mbedtls_mpi_uint secp384r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x19, 0xCD, 0x12, 0x0B, 0x51, 0x4F, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x4B, 0x3D, 0x24, 0xA4, 0x16, 0x59, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xEB, 0xD3, 0x59, 0x2E, 0x75, 0x7C, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB9, 0xB4, 0xA5, 0xD9, 0x2E, 0x29, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x16, 0x05, 0x75, 0x02, 0xB3, 0x06, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x7C, 0x9F, 0x79, 0x91, 0xF1, 0x4F, 0x23), -}; -static const mbedtls_mpi_uint secp384r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x98, 0x7C, 0x84, 0xE1, 0xFF, 0x30, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE2, 0xC2, 0x5F, 0x55, 0x40, 0xBD, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x65, 0x87, 0x3F, 0xC4, 0xC2, 0x24, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x30, 0x0A, 0x60, 0x15, 0xD1, 0x24, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x99, 0xD9, 0xB6, 0xAE, 0xB1, 0xAF, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x80, 0xEE, 0xA2, 0x0F, 0x74, 0xB9, 0xF3), -}; -static const mbedtls_mpi_uint secp384r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xE6, 0x0F, 0x37, 0xC1, 0x10, 0x99, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xAD, 0x9D, 0x5D, 0x80, 0x01, 0xA6, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x0F, 0x10, 0x2A, 0x9D, 0x20, 0x38, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x60, 0xCB, 0xCE, 0x5A, 0xA0, 0xA7, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xCF, 0x14, 0xDF, 0xBF, 0xE5, 0x74, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x12, 0x1A, 0xDD, 0x59, 0x02, 0x5D, 0xC6), -}; -static const mbedtls_mpi_uint secp384r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0xF8, 0xF5, 0xB6, 0x13, 0x4D, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x45, 0xB1, 0x93, 0xB3, 0xA2, 0x79, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xF6, 0xCF, 0xF7, 0xE6, 0x29, 0x9C, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x50, 0x65, 0x80, 0xBC, 0x59, 0x0A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xF0, 0x24, 0x35, 0xA2, 0x46, 0xF0, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x26, 0xC0, 0x9D, 0x61, 0x56, 0x62, 0x67), -}; -static const mbedtls_mpi_uint secp384r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xBB, 0xC2, 0x24, 0x43, 0x2E, 0x37, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xF7, 0xCE, 0x35, 0xFC, 0x77, 0xF3, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x34, 0x96, 0xD5, 0x4A, 0x76, 0x9D, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x3B, 0x0F, 0xEA, 0xA8, 0x12, 0x0B, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x3F, 0x5D, 0x2D, 0x1C, 0xD4, 0x9E, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x2E, 0xDD, 0xC7, 0x6E, 0xAB, 0xAF, 0xDC), -}; -static const mbedtls_mpi_uint secp384r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB2, 0x7B, 0x0C, 0x9A, 0x83, 0x8E, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x51, 0x90, 0x92, 0x79, 0x32, 0x19, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x89, 0xF9, 0xD0, 0xCF, 0x2C, 0xA5, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x50, 0x21, 0xDE, 0x50, 0x41, 0x9D, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x7D, 0x2B, 0x9E, 0x9D, 0x95, 0xA8, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA5, 0x20, 0x87, 0x88, 0x97, 0x5F, 0xAA), -}; -static const mbedtls_mpi_uint secp384r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x59, 0xB4, 0x66, 0x7E, 0xE8, 0x5A, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x5C, 0x7E, 0xB2, 0xAD, 0xD9, 0xC9, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x97, 0x49, 0xA3, 0x13, 0x83, 0x07, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x26, 0xC7, 0x13, 0x35, 0x0D, 0xB0, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x60, 0xAB, 0xFA, 0x4B, 0x93, 0x18, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2D, 0x1C, 0x31, 0x4C, 0xE4, 0x61, 0xAE), -}; -static const mbedtls_mpi_uint secp384r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x4D, 0x1E, 0x51, 0x59, 0x6E, 0x91, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x54, 0x4D, 0x51, 0xED, 0x36, 0xCC, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xA8, 0x56, 0xC7, 0x78, 0x27, 0x33, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB7, 0x95, 0xC9, 0x8B, 0xC8, 0x6A, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xE9, 0x13, 0x96, 0xB3, 0xE1, 0xF9, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x46, 0xB0, 0x5E, 0xC3, 0x94, 0x03, 0x05), -}; -static const mbedtls_mpi_uint secp384r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x5B, 0x29, 0x30, 0x41, 0x1A, 0x9E, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xCA, 0x83, 0x31, 0x5B, 0xA7, 0xCB, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x41, 0x50, 0x44, 0x4D, 0x64, 0x31, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x84, 0xC2, 0x5D, 0x97, 0xA5, 0x3C, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x0F, 0xA5, 0xFD, 0x8E, 0x5A, 0x47, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x58, 0x02, 0x2D, 0x40, 0xB1, 0x0B, 0xBA), -}; -static const mbedtls_mpi_uint secp384r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x33, 0x8C, 0x67, 0xCE, 0x23, 0x43, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x53, 0x47, 0x72, 0x44, 0x1F, 0x5B, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xC1, 0xD9, 0xA4, 0x50, 0x88, 0x63, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xF2, 0x75, 0x69, 0x73, 0x00, 0xC4, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x90, 0x1D, 0xDF, 0x1A, 0x00, 0xD8, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xB1, 0x89, 0x48, 0xA8, 0x70, 0x62, 0xEF), -}; -static const mbedtls_mpi_uint secp384r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x8A, 0x55, 0x50, 0x7B, 0xEF, 0x8A, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1B, 0x23, 0x48, 0x23, 0x63, 0x91, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x04, 0x54, 0x3C, 0x24, 0x9B, 0xC7, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x38, 0xC3, 0x84, 0xFB, 0xFF, 0x9F, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x2A, 0xE0, 0x6D, 0x68, 0x8A, 0x5C, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x93, 0x53, 0x85, 0xA1, 0x0D, 0xAF, 0x63), -}; -static const mbedtls_mpi_uint secp384r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x88, 0x95, 0x4C, 0x0B, 0xD0, 0x06, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xAF, 0x8D, 0x49, 0xA2, 0xC8, 0xB4, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x76, 0x53, 0x09, 0x88, 0x43, 0x87, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA4, 0x77, 0x3F, 0x5E, 0x21, 0xB4, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x9E, 0x86, 0x64, 0xCC, 0x91, 0xC1, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x17, 0x56, 0xCB, 0xC3, 0x7D, 0x5B, 0xB1), -}; -static const mbedtls_mpi_uint secp384r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x74, 0x9F, 0xB5, 0x91, 0x21, 0xB1, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xED, 0xE1, 0x11, 0xEF, 0x45, 0xAF, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x31, 0xBE, 0xB2, 0xBC, 0x72, 0x65, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x4B, 0x8C, 0x77, 0xCE, 0x1E, 0x42, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC9, 0xAA, 0xB9, 0xD9, 0x86, 0x99, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x23, 0x80, 0xC6, 0x4E, 0x35, 0x0B, 0x6D), -}; -static const mbedtls_mpi_uint secp384r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xD8, 0xA2, 0x0A, 0x39, 0x32, 0x1D, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xC8, 0x86, 0xF1, 0x12, 0x9A, 0x4A, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xF1, 0x7C, 0xAA, 0x70, 0x8E, 0xBC, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x01, 0x47, 0x8F, 0xDD, 0x8B, 0xA5, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x08, 0x21, 0xF4, 0xAB, 0xC7, 0xF5, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x76, 0xA5, 0x95, 0xC4, 0x0F, 0x88, 0x1D), -}; -static const mbedtls_mpi_uint secp384r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x42, 0x2A, 0x52, 0xCD, 0x75, 0x51, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x36, 0xE5, 0x04, 0x2B, 0x44, 0xC6, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xEE, 0x16, 0x13, 0x07, 0x83, 0xB5, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x59, 0xC6, 0xA2, 0x19, 0x05, 0xD3, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8B, 0xA8, 0x16, 0x09, 0xB7, 0xEA, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xEE, 0x14, 0xAF, 0xB5, 0xFD, 0xD0, 0xEF), -}; -static const mbedtls_mpi_uint secp384r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x7C, 0xCA, 0x71, 0x3E, 0x6E, 0x66, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x31, 0x0E, 0x3F, 0xE5, 0x91, 0xC4, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x3D, 0xC2, 0x3E, 0x95, 0x37, 0x58, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x1F, 0x02, 0x03, 0xF3, 0xEF, 0xEE, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x5B, 0x1A, 0xFC, 0x38, 0xCD, 0xE8, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x57, 0x42, 0x85, 0xC6, 0x21, 0x68, 0x71), -}; -static const mbedtls_mpi_uint secp384r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA2, 0x4A, 0x66, 0xB1, 0x0A, 0xE6, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x0C, 0x94, 0x9D, 0x5E, 0x99, 0xB2, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x03, 0x40, 0xCA, 0xB2, 0xB3, 0x30, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0x48, 0x27, 0x34, 0x1E, 0xE2, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x72, 0x5B, 0xAC, 0xC1, 0x6D, 0xE3, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAB, 0x46, 0xCB, 0xEA, 0x5E, 0x4B, 0x0B), -}; -static const mbedtls_mpi_uint secp384r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x08, 0xAD, 0x4E, 0x51, 0x9F, 0x2A, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5C, 0x7D, 0x4C, 0xD6, 0xCF, 0xDD, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x76, 0x26, 0xE0, 0x8B, 0x10, 0xD9, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA7, 0x23, 0x4E, 0x5F, 0xD2, 0x42, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xE5, 0xA4, 0xEC, 0x77, 0x21, 0x34, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x14, 0x65, 0xEA, 0x4A, 0x85, 0xC3, 0x2F), -}; -static const mbedtls_mpi_uint secp384r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xD8, 0x40, 0x27, 0x73, 0x15, 0x7E, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xBB, 0x53, 0x7E, 0x0F, 0x40, 0xC8, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x37, 0x19, 0x73, 0xEF, 0x5A, 0x5E, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x73, 0x2B, 0x49, 0x7E, 0xAC, 0x97, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xB2, 0xC3, 0x1E, 0x0E, 0xE7, 0xD2, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x08, 0xD6, 0xDD, 0xAC, 0x21, 0xD6, 0x3E), -}; -static const mbedtls_mpi_uint secp384r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x26, 0xBE, 0x6D, 0x6D, 0xF2, 0x38, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6C, 0x31, 0xA7, 0x49, 0x50, 0x3A, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x99, 0xC6, 0xF5, 0xD2, 0xC2, 0x30, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE4, 0xF6, 0x8B, 0x8B, 0x97, 0xE9, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x21, 0xB7, 0x0D, 0xFC, 0x15, 0x54, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x83, 0x1C, 0xA4, 0xCD, 0x6B, 0x9D, 0xF2), -}; -static const mbedtls_mpi_uint secp384r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE8, 0x4C, 0x48, 0xE4, 0xAA, 0x69, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x7A, 0x27, 0xFC, 0x37, 0x96, 0x1A, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xE7, 0x30, 0xA5, 0xCF, 0x13, 0x46, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xD8, 0xAF, 0x74, 0x23, 0x4D, 0x56, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3D, 0x44, 0x14, 0x1B, 0x97, 0x83, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x47, 0xD7, 0x5F, 0xFD, 0x98, 0x38, 0xF7), -}; -static const mbedtls_mpi_uint secp384r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x73, 0x64, 0x36, 0xFD, 0x7B, 0xC1, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x5D, 0x32, 0xD2, 0x47, 0x94, 0x89, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xE9, 0x30, 0xAC, 0x06, 0xC8, 0x65, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x6C, 0xB9, 0x1B, 0xF7, 0x61, 0x49, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xFF, 0x32, 0x43, 0x80, 0xDA, 0xA6, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF8, 0x04, 0x01, 0x95, 0x35, 0xCE, 0x21), -}; -static const mbedtls_mpi_uint secp384r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x06, 0x46, 0x0D, 0x51, 0xE2, 0xD8, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x57, 0x1D, 0x6F, 0x79, 0xA0, 0xCD, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xFB, 0x36, 0xCA, 0xAD, 0xF5, 0x9E, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x7A, 0x1D, 0x9E, 0x1D, 0x95, 0x48, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x26, 0xA5, 0xB7, 0x15, 0x2C, 0xC2, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x42, 0x72, 0xAA, 0x11, 0xDC, 0xC9, 0xB6), -}; -static const mbedtls_mpi_uint secp384r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x6C, 0x64, 0xA7, 0x62, 0x3C, 0xAB, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x6A, 0x44, 0xD8, 0x60, 0xC0, 0xA8, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x76, 0x58, 0x12, 0x57, 0x3C, 0x89, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x4F, 0x83, 0xCE, 0xCB, 0xB8, 0xD0, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0x04, 0xB0, 0xAD, 0xEB, 0xFA, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA4, 0xC3, 0x41, 0x44, 0x4E, 0x65, 0x3E), -}; -static const mbedtls_mpi_uint secp384r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x16, 0xA9, 0x1C, 0xE7, 0x65, 0x20, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x53, 0x32, 0xF8, 0xC0, 0xA6, 0xBD, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF0, 0xE6, 0x57, 0x31, 0xCC, 0x26, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xE3, 0x54, 0x1C, 0x34, 0xD3, 0x17, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xAE, 0xED, 0xFB, 0xCD, 0xE7, 0x1E, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x16, 0x1C, 0x34, 0x40, 0x00, 0x1F, 0xB6), -}; -static const mbedtls_mpi_uint secp384r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x32, 0x00, 0xC2, 0xD4, 0x3B, 0x1A, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xE0, 0x99, 0x8F, 0x0C, 0x4A, 0x16, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x73, 0x18, 0x1B, 0xD4, 0x94, 0x29, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA4, 0x2D, 0xB1, 0x9D, 0x74, 0x32, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xF4, 0xB1, 0x0C, 0x37, 0x62, 0x8B, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xFF, 0xDA, 0xE2, 0x35, 0xA3, 0xB6, 0x42), -}; -static const mbedtls_mpi_uint secp384r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x49, 0x99, 0x65, 0xC5, 0xED, 0x16, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x42, 0x9A, 0xF3, 0xA7, 0x4E, 0x6F, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x0A, 0x7E, 0xC0, 0xD7, 0x4E, 0x07, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x7A, 0x31, 0x69, 0xA6, 0xB9, 0x15, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xE0, 0x72, 0xA4, 0x3F, 0xB9, 0xF8, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x75, 0x32, 0x85, 0xA2, 0xDE, 0x37, 0x12), -}; -static const mbedtls_mpi_uint secp384r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC0, 0x0D, 0xCF, 0x25, 0x41, 0xA4, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xFC, 0xB2, 0x48, 0xC3, 0x85, 0x83, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBE, 0x0B, 0x58, 0x2D, 0x7A, 0x9A, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xF3, 0x81, 0x18, 0x1B, 0x74, 0x4F, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x43, 0xA3, 0x0A, 0x16, 0x8B, 0xA3, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x18, 0x81, 0x7B, 0x8D, 0xA2, 0x35, 0x77), -}; -static const mbedtls_mpi_uint secp384r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xC4, 0x3F, 0x2C, 0xE7, 0x5F, 0x99, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2B, 0xB7, 0xB6, 0xAD, 0x5A, 0x56, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x00, 0xA4, 0x48, 0xC8, 0xE8, 0xBA, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xA1, 0xB5, 0x13, 0x5A, 0xCD, 0x99, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x95, 0xAD, 0xFC, 0xE2, 0x7E, 0xE7, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x6B, 0xD1, 0x34, 0x99, 0x53, 0x63, 0x0B), -}; -static const mbedtls_mpi_uint secp384r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x8A, 0x77, 0x5D, 0x2B, 0xAB, 0x01, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x85, 0xD0, 0xD5, 0x49, 0x83, 0x4D, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xC6, 0x91, 0x30, 0x3B, 0x00, 0xAF, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x61, 0x07, 0xE1, 0xB6, 0xE2, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x43, 0x41, 0xFE, 0x9B, 0xB6, 0xF0, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x97, 0xAE, 0xAD, 0x89, 0x88, 0x9E, 0x41), -}; -static const mbedtls_ecp_point secp384r1_T[32] = { - ECP_POINT_INIT_XY_Z1(secp384r1_T_0_X, secp384r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_1_X, secp384r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_2_X, secp384r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_3_X, secp384r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_4_X, secp384r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_5_X, secp384r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_6_X, secp384r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_7_X, secp384r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_8_X, secp384r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_9_X, secp384r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_10_X, secp384r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_11_X, secp384r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_12_X, secp384r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_13_X, secp384r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_14_X, secp384r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_15_X, secp384r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_16_X, secp384r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_17_X, secp384r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_18_X, secp384r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_19_X, secp384r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_20_X, secp384r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_21_X, secp384r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_22_X, secp384r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_23_X, secp384r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_24_X, secp384r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_25_X, secp384r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_26_X, secp384r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_27_X, secp384r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_28_X, secp384r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_29_X, secp384r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_30_X, secp384r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(secp384r1_T_31_X, secp384r1_T_31_Y), -}; -#else -#define secp384r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -/* - * Domain parameters for secp521r1 - */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static const mbedtls_mpi_uint secp521r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), -}; -static const mbedtls_mpi_uint secp521r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95), - MBEDTLS_BYTES_TO_T_UINT_2(0x51, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_2(0xC6, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), - MBEDTLS_BYTES_TO_T_UINT_2(0x18, 0x01), -}; -static const mbedtls_mpi_uint secp521r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), -}; -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp521r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xB1, 0x2D, 0xEB, 0x27, 0x2F, 0xE8, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x4B, 0x44, 0x25, 0xDB, 0x5C, 0x5F, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x85, 0x28, 0x78, 0x2E, 0x75, 0x34, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x57, 0x0F, 0x73, 0x78, 0x7A, 0xE3, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD8, 0xEC, 0xDC, 0xDA, 0x04, 0xAD, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x8A, 0x09, 0xF3, 0x58, 0x79, 0xD8, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x03, 0xCB, 0x50, 0x1A, 0x7F, 0x56, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA6, 0x78, 0x38, 0x85, 0x67, 0x0B, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xD5, 0xD2, 0x22, 0xC4, 0x00, 0x3B, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x93, 0x0E, 0x7B, 0x85, 0x51, 0xC3, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA6, 0x5F, 0x54, 0x49, 0x02, 0x81, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xE9, 0x6B, 0x3A, 0x92, 0xE7, 0x72, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x5F, 0x28, 0x9E, 0x91, 0x27, 0x88, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x28, 0x31, 0xB3, 0x84, 0xCA, 0x12, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xF9, 0xAC, 0x22, 0x10, 0x0A, 0x64, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xC6, 0x33, 0x1F, 0x69, 0x19, 0x18, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x48, 0xB8, 0xC7, 0x37, 0x5A, 0x00, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xCC, 0x32, 0xE0, 0xEE, 0x03, 0xC2, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x29, 0xC2, 0xE4, 0x6E, 0x24, 0x20, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x6B, 0x7F, 0x7B, 0xF9, 0xB0, 0xB8, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x7B, 0x3C, 0xE1, 0x19, 0xA1, 0x23, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE3, 0xC2, 0x53, 0xC0, 0x07, 0x13, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFE, 0x36, 0x35, 0x9F, 0x5E, 0x59, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x55, 0x89, 0x84, 0xBC, 0xEF, 0xA2, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x1A, 0x08, 0x67, 0xB4, 0xE7, 0x22, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x26, 0xDF, 0x81, 0x3C, 0x5F, 0x1C, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x4D, 0xD0, 0x0A, 0x48, 0x06, 0xF4, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x18, 0x39, 0xF7, 0xD1, 0x20, 0x77, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x8F, 0x44, 0x13, 0xCB, 0x78, 0x11, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE2, 0x49, 0xEA, 0x43, 0x79, 0x08, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xD1, 0xD8, 0x73, 0x2C, 0x71, 0x2F, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE5, 0xE7, 0xF4, 0x46, 0xAB, 0x20, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x0B, 0xB9, 0x71, 0x1A, 0x27, 0xB7, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xA2, 0x2C, 0xD1, 0xDA, 0xBC, 0xC1, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xA3, 0x10, 0x1F, 0x90, 0xF2, 0xA5, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xFB, 0x20, 0xF4, 0xC0, 0x70, 0xC0, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xA7, 0x99, 0xF0, 0xA5, 0xD3, 0x09, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xE8, 0x14, 0x39, 0xBE, 0xCB, 0x60, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD6, 0x14, 0xA9, 0xC9, 0x20, 0xC3, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x5B, 0xFD, 0x2D, 0x96, 0xBC, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x04, 0x45, 0xBE, 0xCE, 0x75, 0x95, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xDA, 0x58, 0x49, 0x35, 0x09, 0x8D, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xF0, 0xC0, 0x36, 0xF2, 0xA6, 0x2D, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFC, 0x3D, 0xA8, 0xFB, 0x3C, 0xD2, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x4D, 0x71, 0x09, 0x18, 0x42, 0xF0, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xC1, 0xCE, 0x9E, 0x6A, 0x49, 0x60, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xB1, 0x00, 0xF7, 0xA1, 0x7A, 0x31, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC3, 0x86, 0xCD, 0x20, 0x4A, 0x17, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xAB, 0x8B, 0x47, 0x8D, 0xAA, 0xA6, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x97, 0xF0, 0xBC, 0x2D, 0xDC, 0x9D, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x86, 0xB0, 0x74, 0xB2, 0xF4, 0xF6, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBD, 0xAC, 0xE3, 0x8F, 0x43, 0x5C, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xC3, 0xE2, 0x6E, 0x25, 0x49, 0xCD, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5E, 0x08, 0xB3, 0xB9, 0xAC, 0x5F, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xB7, 0xD1, 0xF4, 0xDC, 0x19, 0xE9, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xE4, 0xFA, 0xE1, 0x36, 0x3E, 0xED, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0x92, 0x84, 0x6E, 0x48, 0x03, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x95, 0xEF, 0x8F, 0xB2, 0x82, 0x6B, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFA, 0xB9, 0x55, 0x23, 0xFE, 0x09, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x79, 0x85, 0x4B, 0x0E, 0xD4, 0x35, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x27, 0x45, 0x81, 0xE0, 0x88, 0x52, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x63, 0xA2, 0x4B, 0xBC, 0x5D, 0xB1, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x8C, 0x83, 0xD9, 0x3E, 0xD3, 0x42, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x03, 0x3A, 0x31, 0xBA, 0xE9, 0x3A, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x10, 0xCD, 0x2D, 0x00, 0xFE, 0x32, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x6E, 0x1F, 0xDA, 0xF8, 0x6F, 0x4D, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x79, 0x7D, 0x09, 0xE5, 0xD3, 0x03, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC3, 0xBE, 0xDF, 0x07, 0x65, 0x49, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0x33, 0xEF, 0xAE, 0x4F, 0x04, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xE9, 0x9B, 0xFE, 0xBF, 0xE6, 0x85, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xBA, 0xAA, 0x06, 0xC4, 0xC6, 0xB8, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x83, 0x01, 0xA9, 0xF6, 0x51, 0xE7, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xA6, 0x15, 0x8E, 0xAB, 0x1F, 0x10, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x08, 0x27, 0x1A, 0xA1, 0x21, 0xAD, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x09, 0x90, 0x6E, 0x50, 0x90, 0x9A, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x9A, 0xFE, 0xD7, 0xA1, 0xF5, 0xA2, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x7D, 0xE3, 0xDC, 0x21, 0xFB, 0xA4, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBF, 0x07, 0xFF, 0x45, 0xDF, 0x51, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x5C, 0x34, 0x02, 0x62, 0x9B, 0x08, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xCE, 0x9A, 0x6A, 0xEC, 0x75, 0xF6, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x59, 0xF4, 0x78, 0x3C, 0x60, 0xB1, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x37, 0x84, 0x6A, 0xDC, 0xF2, 0x9A, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9A, 0x9A, 0x15, 0x36, 0xE0, 0x2B, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x38, 0x9C, 0x50, 0x3D, 0x1E, 0x37, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x79, 0xF0, 0x92, 0xF2, 0x8B, 0x18, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE0, 0x82, 0x1E, 0x80, 0x82, 0x4B, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xBB, 0x59, 0x6B, 0x8A, 0x77, 0x41, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xF9, 0xD4, 0xB8, 0x4A, 0x82, 0xCF, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x8C, 0xC8, 0x9B, 0x72, 0x9E, 0xF7, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xCE, 0xE9, 0x77, 0x0A, 0x19, 0x59, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xA1, 0x41, 0x6A, 0x72, 0x4B, 0xB4, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x35, 0x43, 0xE2, 0x8C, 0xBE, 0x0D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xEB, 0xAD, 0xF3, 0xA9, 0xA6, 0x68, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2F, 0xE2, 0x48, 0x0C, 0xDB, 0x1F, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x1E, 0x60, 0x9B, 0x2A, 0xD2, 0xC1, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x64, 0xB5, 0xD2, 0xF6, 0xF6, 0x6E, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x3D, 0x30, 0x78, 0x10, 0x18, 0x41, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x1D, 0x1C, 0xE0, 0x6D, 0x83, 0xD1, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x03, 0x0B, 0xF5, 0x2F, 0x6C, 0x04, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x3E, 0xD5, 0xFC, 0x31, 0x5B, 0x3A, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x82, 0x2F, 0xFB, 0xFE, 0xF8, 0x76, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x26, 0xDA, 0x9C, 0x36, 0xF5, 0x93, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xE7, 0x6E, 0xD2, 0x7D, 0x81, 0x09, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x03, 0xF9, 0x58, 0x48, 0x24, 0xA2, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x79, 0x0C, 0x8E, 0x6B, 0x95, 0xF3, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x10, 0x5C, 0x87, 0x03, 0x39, 0xCF, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xF0, 0xF7, 0xC1, 0x07, 0xA4, 0xF4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE8, 0x02, 0x89, 0x65, 0xC4, 0x72, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x88, 0xEA, 0x96, 0x67, 0x0B, 0x5D, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x75, 0x60, 0xA8, 0xBD, 0x74, 0xDF, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xE5, 0x71, 0x50, 0x67, 0xD0, 0xD2, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFC, 0xE5, 0xC7, 0x77, 0xB0, 0x7F, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x86, 0x69, 0xCD, 0x0D, 0x9A, 0xBD, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x17, 0xBC, 0xBB, 0x59, 0x85, 0x7D, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA8, 0x76, 0xAC, 0x80, 0xA9, 0x72, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0xC1, 0xE2, 0x4D, 0xAF, 0xF9, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x97, 0x8E, 0x74, 0xC4, 0x4B, 0xB2, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD8, 0xF6, 0xF3, 0xAF, 0x2F, 0x52, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x57, 0xF4, 0xCE, 0xEE, 0x43, 0xED, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x46, 0x38, 0xDE, 0x20, 0xFD, 0x59, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x18, 0xE8, 0x58, 0xB9, 0x76, 0x2C, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x54, 0xE4, 0xFE, 0xC7, 0xBC, 0x31, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF8, 0x89, 0xEE, 0x70, 0xB5, 0xB0, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x22, 0x26, 0x9A, 0x53, 0xB9, 0x38, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xA7, 0x19, 0x8C, 0x74, 0x7E, 0x88, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xDA, 0x0A, 0xE8, 0xDA, 0xA5, 0xBE, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x5C, 0xF7, 0xB1, 0x0C, 0x72, 0xFB, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xE2, 0x23, 0xE7, 0x46, 0xB7, 0xE0, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x36, 0xBC, 0xBD, 0x48, 0x11, 0x8E, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xBB, 0xA1, 0xF7, 0x0B, 0x9E, 0xBF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x28, 0xE1, 0xA2, 0x8F, 0xFC, 0xFC, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xFE, 0x19, 0x0A, 0xE5, 0xE7, 0x69, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xCD, 0x12, 0xF5, 0xBE, 0xD3, 0x04, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA8, 0x0D, 0x81, 0x59, 0xC4, 0x79, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xF3, 0x4B, 0x92, 0x65, 0xC3, 0x31, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xB5, 0x4F, 0x4D, 0x91, 0xD4, 0xE2, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x09, 0x41, 0x79, 0x1D, 0x4D, 0x0D, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x31, 0x18, 0xBA, 0xA0, 0xF2, 0x6E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x5B, 0x4D, 0x4F, 0xAF, 0xC9, 0x8C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x9C, 0x06, 0x68, 0xDE, 0xD8, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x04, 0xE1, 0xB5, 0x9D, 0x00, 0xBC, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x95, 0x92, 0x8D, 0x72, 0xD3, 0x37, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x4B, 0x27, 0xA2, 0xE8, 0xA4, 0x26, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x45, 0x9C, 0xA9, 0xCB, 0x9F, 0xBA, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x7E, 0x1B, 0x64, 0xF4, 0xE8, 0xA5, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x20, 0xA9, 0xCA, 0xF3, 0x89, 0xE5, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xED, 0xFC, 0xAB, 0xD9, 0x0A, 0xB9, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6F, 0x46, 0x7C, 0xCD, 0x78, 0xFF, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAB, 0x71, 0x5A, 0x94, 0xAB, 0x20, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x2E, 0xEE, 0x87, 0x57, 0x1F, 0xAD, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x4C, 0x3D, 0xFB, 0x7E, 0xA1, 0x8B, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xCF, 0x07, 0x86, 0xBA, 0x53, 0x37, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x26, 0xB2, 0xB9, 0xE2, 0x91, 0xE3, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xC9, 0x54, 0x84, 0x08, 0x3D, 0x0B, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x77, 0x2F, 0x64, 0x45, 0x99, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x96, 0x16, 0x1F, 0xDB, 0x96, 0x28, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x2B, 0x8D, 0xFF, 0xA2, 0x4F, 0x55, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE6, 0x48, 0xBD, 0x99, 0x3D, 0x12, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x84, 0x59, 0xDA, 0xB9, 0xB6, 0x66, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x78, 0x41, 0x92, 0xDF, 0xF4, 0x3F, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x86, 0x6F, 0x4F, 0xBF, 0x67, 0xDF, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x2B, 0x1E, 0x5F, 0x00, 0xEA, 0xF6, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xB9, 0x6A, 0x89, 0xD8, 0xC0, 0xD7, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x9A, 0x32, 0x23, 0xA0, 0x02, 0x91, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x7F, 0x6A, 0x15, 0x64, 0x6A, 0x8B, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x57, 0x82, 0x58, 0xA9, 0x56, 0xB5, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x50, 0x92, 0x60, 0xCC, 0x81, 0x24, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x3D, 0xAD, 0xDA, 0xD9, 0x51, 0x3E, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xFE, 0x8F, 0xB0, 0x0B, 0xDE, 0x2E, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xD2, 0xBE, 0xEF, 0xAC, 0x76, 0x71, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xE8, 0x72, 0x0B, 0xAC, 0xFE, 0xCA, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0xC7, 0xFC, 0xE3, 0x3C, 0x7C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x04, 0xA7, 0xB9, 0x9B, 0x93, 0xC0, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x48, 0x4B, 0x8E, 0x32, 0xC5, 0xF0, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x42, 0x07, 0xC1, 0xF2, 0xF1, 0x72, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x37, 0x54, 0x9C, 0x88, 0xD2, 0x62, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x19, 0x8A, 0x89, 0x58, 0xA2, 0x0F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xCC, 0x4C, 0x97, 0x30, 0x66, 0x34, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x6A, 0x1E, 0x1F, 0xDB, 0xC9, 0x5E, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x4D, 0x49, 0xFF, 0x9B, 0x9C, 0xAC, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xE4, 0x4B, 0xF2, 0xD4, 0x1A, 0xD2, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xDA, 0xE8, 0x61, 0x9F, 0xC8, 0x49, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xCB, 0xF2, 0x2D, 0x85, 0xF6, 0x8D, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xC5, 0xCD, 0x2C, 0x79, 0xC6, 0x0E, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x1D, 0x55, 0x0F, 0xF8, 0x22, 0x9F, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x56, 0xBA, 0xE7, 0x57, 0x32, 0xEC, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x9A, 0xC6, 0x4C, 0x09, 0xC4, 0x52, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x1E, 0x6F, 0xF4, 0x7D, 0x27, 0xDD, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x11, 0x16, 0xEC, 0x79, 0x83, 0xAD, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x4E, 0x92, 0x1F, 0x19, 0x7D, 0x65, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xFF, 0x78, 0x15, 0x45, 0x63, 0x32, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x91, 0xD0, 0x78, 0x58, 0xDA, 0x50, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xDE, 0x40, 0xF6, 0x41, 0xB4, 0x3B, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x8D, 0xE0, 0xE1, 0xA9, 0xF0, 0x35, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xD4, 0xBA, 0x7B, 0xCC, 0x1B, 0x3A, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x5A, 0x2E, 0x74, 0x47, 0x14, 0xC3, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xF0, 0x8B, 0x06, 0x15, 0x8E, 0x0E, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xD2, 0xEB, 0x97, 0x50, 0x7D, 0x31, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x93, 0x4C, 0xDB, 0x97, 0x79, 0x44, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xA2, 0xA0, 0x0B, 0xC8, 0x3A, 0x8A, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x50, 0x92, 0x9E, 0x24, 0x1F, 0xCB, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x16, 0xC9, 0xC5, 0x3D, 0x5A, 0xAF, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xE3, 0x97, 0xE4, 0xA8, 0x50, 0xF6, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x57, 0x97, 0x42, 0x78, 0x92, 0x49, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEB, 0x62, 0x24, 0xFB, 0x8F, 0x32, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x0C, 0x36, 0x6E, 0x8F, 0xE8, 0xE8, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xD3, 0x7C, 0xC7, 0x8D, 0x3F, 0x5C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x64, 0x6A, 0x73, 0x10, 0x79, 0xB8, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xF9, 0xEF, 0xA5, 0x20, 0x4A, 0x5C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xF3, 0xF4, 0x49, 0x5B, 0x73, 0xAA, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xF2, 0xEA, 0x0F, 0x00, 0xAD, 0x53, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xB8, 0x66, 0xED, 0xC4, 0x2B, 0x4C, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x2F, 0xC1, 0x9A, 0x37, 0xD2, 0x7F, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA7, 0x81, 0x38, 0x64, 0xC9, 0x37, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x3B, 0x6C, 0x9F, 0x5B, 0xD9, 0x8B, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x14, 0xD9, 0x08, 0xD8, 0xD2, 0x7E, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x71, 0xE6, 0x3D, 0xD1, 0xB0, 0xE7, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x81, 0x23, 0xEC, 0x2D, 0x42, 0x45, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x5B, 0x44, 0x6B, 0x89, 0x03, 0x67, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x27, 0xAE, 0x80, 0x5A, 0x33, 0xBE, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB6, 0x64, 0x1A, 0xDF, 0xD3, 0x85, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x8C, 0x22, 0xBA, 0xD0, 0xBD, 0xCC, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x3C, 0x01, 0x3A, 0xFF, 0x9D, 0xC7, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC7, 0x64, 0xB4, 0x59, 0x4E, 0x9F, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x34, 0x0A, 0x41, 0x94, 0xA8, 0xF2, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD4, 0xE4, 0xF0, 0x97, 0x45, 0x6D, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x1F, 0x4D, 0x6D, 0xFE, 0xA0, 0xC4, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x28, 0x5C, 0x40, 0xBB, 0x65, 0xD4, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xA8, 0x87, 0x35, 0x20, 0x3A, 0x89, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFD, 0x4F, 0xAB, 0x2D, 0xD1, 0xD0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE8, 0x00, 0xFC, 0x69, 0x52, 0xF8, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x9A, 0x99, 0xE1, 0xDC, 0x9C, 0x3F, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x08, 0x98, 0xD9, 0xCA, 0x73, 0xD5, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x2C, 0xE0, 0xA7, 0x3E, 0x91, 0xD7, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x04, 0xB0, 0x54, 0x09, 0xF4, 0x72, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xEE, 0x28, 0xCC, 0xE8, 0x50, 0x78, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x91, 0x03, 0x76, 0xDB, 0x68, 0x24, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xE0, 0x56, 0xB2, 0x5D, 0x12, 0xD3, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x42, 0x59, 0x8B, 0xDF, 0x67, 0xB5, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xCC, 0xE5, 0x31, 0x53, 0x7A, 0x46, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8D, 0x59, 0xB5, 0x1B, 0x0F, 0xF4, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x2F, 0xD1, 0x2C, 0xE0, 0xD8, 0x04, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0xD7, 0xBA, 0xB0, 0xA3, 0x7E, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x08, 0x51, 0x56, 0xA6, 0x76, 0x67, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x17, 0x63, 0xFE, 0x56, 0xD0, 0xD9, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xF6, 0xC3, 0x14, 0x47, 0xC5, 0xA7, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x4C, 0x80, 0xF6, 0xA2, 0x57, 0xA7, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xB3, 0x7B, 0xF8, 0x2F, 0xE1, 0x3E, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xF4, 0xF9, 0x6B, 0x7B, 0x90, 0xDF, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x82, 0xEF, 0x62, 0xA1, 0x4C, 0x53, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x99, 0x76, 0x01, 0xBA, 0x8D, 0x0F, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xF4, 0x58, 0x73, 0x56, 0xFE, 0xDD, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xCE, 0xF9, 0xE8, 0xA1, 0x34, 0xC3, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x5F, 0xDC, 0x6A, 0x3D, 0xD8, 0x7F, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xF4, 0x51, 0xB8, 0xB8, 0xC1, 0xD7, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x7D, 0x58, 0xD1, 0xD4, 0x1B, 0x4D, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x95, 0xDF, 0x00, 0xD8, 0x21, 0xDE, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x47, 0x3C, 0xC3, 0xB2, 0x01, 0x53, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x17, 0x43, 0x23, 0xBD, 0xCA, 0x71, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xBA, 0x0F, 0x4F, 0xDC, 0x41, 0x54, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x39, 0x26, 0x70, 0x53, 0x32, 0x18, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x46, 0x07, 0x97, 0x3A, 0x57, 0xE0, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x92, 0x4F, 0xCE, 0xDF, 0x25, 0x80, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x6F, 0x9A, 0x03, 0x05, 0x4B, 0xD1, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x01, 0x72, 0x30, 0x90, 0x17, 0x51, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xFB, 0x41, 0x65, 0x5C, 0xB4, 0x2D, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xCD, 0xCD, 0xAA, 0x41, 0xCC, 0xBB, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xCE, 0x08, 0x0A, 0x63, 0xE9, 0xA2, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA8, 0x21, 0x7F, 0x7A, 0x5B, 0x9B, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x6B, 0x89, 0x44, 0x0A, 0x7F, 0x85, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xDE, 0x7C, 0x19, 0x5C, 0x65, 0x26, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xAC, 0x62, 0x29, 0x4A, 0xF1, 0xD0, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x00, 0x40, 0x87, 0xEB, 0xA9, 0x58, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x51, 0x0B, 0xFF, 0x56, 0x35, 0x51, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xAC, 0x08, 0x94, 0x71, 0xDA, 0xEC, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x4D, 0xC5, 0x7B, 0x31, 0x8B, 0x8D, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x05, 0xF1, 0x3E, 0x9E, 0x8F, 0x17, 0x8F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x9C, 0x4B, 0x62, 0x94, 0xAD, 0x49, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC9, 0xC6, 0x8F, 0xFD, 0x33, 0x44, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x96, 0x17, 0x7F, 0x42, 0xBE, 0xF7, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x29, 0x39, 0x13, 0x08, 0x8D, 0x91, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x79, 0xF9, 0x2F, 0xA9, 0x0A, 0xCF, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x87, 0x7A, 0xA3, 0x19, 0xAB, 0x55, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x0B, 0x01, 0xC5, 0x56, 0x19, 0x9D, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xDE, 0x82, 0x3B, 0xEA, 0xD3, 0x0B, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x6B, 0xC7, 0xF3, 0x0F, 0x82, 0x87, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x2E, 0x23, 0xF2, 0x39, 0x9D, 0x49, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xDE, 0xAF, 0x7A, 0xEE, 0xB0, 0xDA, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x4E, 0x2A, 0x50, 0xFD, 0x8E, 0xC0, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x0F, 0x7C, 0x76, 0x63, 0xD8, 0x89, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x2D, 0xB9, 0x4E, 0xF4, 0xEE, 0x85, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x95, 0x5C, 0x96, 0x5D, 0xAA, 0x59, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xDB, 0xD2, 0x68, 0x8E, 0x5A, 0x94, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x02, 0xBF, 0x77, 0x9F, 0xB9, 0x4C, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xDC, 0xC0, 0xCF, 0x81, 0x1E, 0xC4, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xCC, 0x37, 0x86, 0xDC, 0xE2, 0x64, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x30, 0xB1, 0x59, 0x20, 0x9D, 0x98, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x0C, 0x9D, 0xF8, 0x20, 0xDC, 0x90, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xA0, 0xF4, 0xE7, 0x3E, 0x9C, 0x9E, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x25, 0xA2, 0xB0, 0x54, 0xCD, 0x2E, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD9, 0x42, 0xB0, 0x80, 0xB0, 0xA3, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xFE, 0x9D, 0x8D, 0x40, 0xFF, 0x27, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9D, 0xA6, 0x88, 0x3A, 0x8B, 0x6F, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x39, 0xEE, 0x1F, 0x3F, 0xB1, 0x4F, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD7, 0x9E, 0xFF, 0xD2, 0x35, 0x67, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x4F, 0x15, 0x5D, 0xE3, 0xE8, 0x53, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF7, 0x24, 0x98, 0xA2, 0xCB, 0x11, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x2E, 0x25, 0xE1, 0x94, 0xC5, 0xA3, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x82, 0x6E, 0xBA, 0xE7, 0x43, 0x25, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x65, 0xB4, 0x49, 0x73, 0x18, 0x35, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x5B, 0xBC, 0x62, 0x86, 0x4C, 0xC1, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xF2, 0x95, 0xA2, 0xBB, 0xA2, 0x35, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x59, 0x62, 0xB0, 0x4B, 0x1E, 0xB4, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x55, 0xCE, 0xB0, 0x69, 0xBA, 0x63, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x69, 0x86, 0xDB, 0x34, 0x7D, 0x68, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x06, 0xCA, 0x55, 0x44, 0x36, 0x2B, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xD4, 0xC4, 0x3D, 0xCD, 0x9E, 0x69, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x44, 0xE4, 0xBF, 0x31, 0xE6, 0x40, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x4F, 0xFA, 0x75, 0xE3, 0xFB, 0x97, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xC0, 0xBD, 0x1C, 0x48, 0xB0, 0x26, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x7B, 0x32, 0xFA, 0xF2, 0x6D, 0x84, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x21, 0x03, 0x1D, 0x0D, 0x22, 0x55, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xF9, 0x42, 0x03, 0x9C, 0xC2, 0xCB, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xA1, 0x96, 0xD9, 0x9D, 0x11, 0x6F, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x40, 0x57, 0xEB, 0x40, 0x2D, 0xC0, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x96, 0xBB, 0x4F, 0x2F, 0x23, 0xA8, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x29, 0x85, 0x21, 0xA5, 0x50, 0x62, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x7D, 0x92, 0xCF, 0x87, 0x0C, 0x22, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x0E, 0xA5, 0x32, 0x5B, 0xDF, 0x9C, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x96, 0x37, 0x2C, 0x88, 0x35, 0x30, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xB4, 0x69, 0xFF, 0xEB, 0xC6, 0x94, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x55, 0x60, 0xAD, 0xAA, 0x58, 0x14, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xFF, 0xF2, 0xB2, 0xD5, 0xA7, 0xD9, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xAE, 0x54, 0xD2, 0x60, 0x31, 0xF3, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x92, 0x83, 0xE3, 0xF1, 0x42, 0x83, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD2, 0xC8, 0xB7, 0x76, 0x45, 0x7F, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x11, 0xA4, 0xFB, 0x7A, 0x01, 0xBC, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x27, 0x73, 0x8D, 0x02, 0x91, 0x27, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x62, 0xF6, 0xDD, 0x6B, 0xFA, 0x5B, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCA, 0xA2, 0x44, 0x2C, 0xF0, 0x28, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xF1, 0x7A, 0xA2, 0x42, 0x4C, 0x50, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x83, 0x3E, 0x50, 0xAB, 0x9C, 0xF7, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xED, 0x78, 0xCB, 0x76, 0x69, 0xDA, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x1E, 0x43, 0x27, 0x47, 0x6E, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x4F, 0x54, 0xB9, 0x3E, 0xBD, 0xD5, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x40, 0x69, 0x7F, 0x74, 0x9D, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x06, 0x6F, 0x67, 0x68, 0x2B, 0x4D, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x65, 0x41, 0xFC, 0x7C, 0x1E, 0xE8, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x79, 0x37, 0xAF, 0xFD, 0xD2, 0xDA, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xA8, 0x69, 0x56, 0x62, 0xA4, 0xE4, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x71, 0x73, 0x21, 0x8A, 0x17, 0x81, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x55, 0x8F, 0x7B, 0xB8, 0xAF, 0xF7, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xD1, 0xBD, 0xBE, 0x8C, 0xBC, 0x60, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA6, 0x57, 0x8C, 0xAE, 0x5C, 0x19, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x43, 0xE4, 0xD9, 0xD8, 0x7B, 0xE7, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xB9, 0xE4, 0x85, 0x7C, 0x2E, 0xFC, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2E, 0x01, 0x2A, 0x6D, 0x56, 0xBE, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x0C, 0x25, 0x9B, 0xAE, 0x86, 0x37, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x22, 0xB3, 0xCB, 0x99, 0x66, 0xB7, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xF7, 0x90, 0xF0, 0x1B, 0x09, 0x27, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x16, 0x08, 0xEF, 0x39, 0x64, 0x49, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA0, 0xE3, 0x97, 0xA9, 0x07, 0x54, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xFF, 0xE2, 0x00, 0x07, 0x21, 0x88, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFD, 0x59, 0x53, 0x05, 0x6C, 0x42, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xF7, 0x39, 0x5C, 0x82, 0x36, 0xE8, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x83, 0xA8, 0xE2, 0xA8, 0x43, 0x07, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xAF, 0x2B, 0x79, 0xED, 0xD8, 0x39, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x20, 0x91, 0x7A, 0xC4, 0x07, 0xEF, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x2F, 0xAA, 0x0C, 0x94, 0x0E, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x81, 0x87, 0x41, 0x23, 0xEB, 0x55, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x53, 0xCC, 0x79, 0xB6, 0xEB, 0x6C, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x77, 0x73, 0x9D, 0xFC, 0x64, 0x6F, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x40, 0xE3, 0x6D, 0x1C, 0x16, 0x71, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xF4, 0x1B, 0xFF, 0x1C, 0x2F, 0xA5, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x0E, 0x0B, 0x11, 0xF4, 0x8D, 0x93, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC5, 0x64, 0x6F, 0x24, 0x19, 0xF2, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xB3, 0xAF, 0xA5, 0x0E, 0x4F, 0x5E, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x77, 0xCA, 0xF2, 0x6D, 0xC5, 0xF6, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x18, 0x8E, 0x33, 0x68, 0x6C, 0xE8, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x8B, 0x80, 0x90, 0x19, 0x7F, 0x90, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x80, 0x6B, 0x68, 0xE2, 0x7D, 0xD4, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC1, 0x67, 0xB3, 0x72, 0xCB, 0xBF, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xD5, 0xD3, 0x1D, 0x14, 0x58, 0x0A, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x7A, 0x65, 0x98, 0xB3, 0x07, 0x4B, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x87, 0x0F, 0x5F, 0xCF, 0xA2, 0x01, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC9, 0xC8, 0x6E, 0x35, 0x87, 0xA5, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x3E, 0x91, 0xA0, 0xAB, 0x24, 0x1E, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBC, 0x02, 0x35, 0x70, 0xC1, 0x5F, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x59, 0xA0, 0x50, 0x04, 0x80, 0x52, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x56, 0x6E, 0x42, 0x8F, 0x8C, 0x91, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xA2, 0xCB, 0xA5, 0xDE, 0x14, 0x24, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xCB, 0x74, 0x28, 0xE6, 0xA7, 0xE7, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x73, 0xA8, 0x8F, 0x9E, 0x0E, 0x63, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x1B, 0x77, 0xC7, 0xC1, 0x38, 0xF9, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x3C, 0xCF, 0xA8, 0x7A, 0xD7, 0xF3, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x5F, 0x9A, 0xC9, 0xAD, 0xE9, 0x1A, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0x2B, 0x5E, 0xD5, 0x81, 0x95, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x88, 0x75, 0x29, 0x1F, 0xC7, 0xC7, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA9, 0x5A, 0x4D, 0x63, 0x95, 0xF9, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xCD, 0x04, 0x8F, 0xCD, 0x91, 0xDE, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xD4, 0xFD, 0x25, 0x11, 0x99, 0x6E, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x83, 0x01, 0x3D, 0xFB, 0x56, 0xA5, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x3A, 0xDC, 0x74, 0xC2, 0xD7, 0xCF, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xBD, 0xF1, 0xDD, 0xA3, 0x07, 0x03, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xBE, 0xE9, 0x2E, 0x58, 0x84, 0x66, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x20, 0x78, 0x37, 0x79, 0x0B, 0xA6, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xF2, 0xAC, 0x65, 0xC8, 0xC9, 0x2F, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x93, 0xE5, 0x0D, 0x0C, 0xC6, 0xB8, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAD, 0x5C, 0x19, 0x12, 0x61, 0x0E, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x4F, 0x0B, 0x1F, 0x49, 0x7E, 0xCD, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2E, 0x30, 0x61, 0xDB, 0x08, 0x68, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x78, 0xAF, 0xB3, 0x08, 0xC1, 0x69, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x5F, 0x5D, 0xC1, 0x57, 0x6F, 0xD8, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xD3, 0x6A, 0xF7, 0xFD, 0x86, 0xE5, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x63, 0xBD, 0x70, 0x7B, 0x47, 0xE8, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x62, 0xC8, 0x7E, 0x9D, 0x11, 0x2B, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x84, 0xFD, 0xD5, 0x9A, 0x56, 0x7F, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBB, 0xA4, 0x6F, 0x12, 0x6E, 0x4D, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x08, 0xA1, 0x82, 0x9C, 0x62, 0x74, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x22, 0x05, 0x1D, 0x15, 0x35, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x88, 0xCF, 0x5C, 0x05, 0x78, 0xFB, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x6B, 0x2F, 0x79, 0x09, 0x73, 0x67, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA0, 0x80, 0xD8, 0xE8, 0xEC, 0xFB, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0B, 0xB7, 0x81, 0x48, 0x7B, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x53, 0xA9, 0xED, 0x61, 0x92, 0xD7, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x49, 0xD9, 0x5D, 0x9B, 0x4E, 0x89, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x12, 0xEB, 0x9A, 0xC9, 0xCB, 0xC1, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xDC, 0x95, 0x16, 0xFE, 0x29, 0x70, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x33, 0xB1, 0xD6, 0x78, 0xB9, 0xE2, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xCE, 0x88, 0xC3, 0xFD, 0x7A, 0x6B, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x1E, 0x50, 0x1E, 0xAF, 0xB1, 0x25, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xE7, 0xD7, 0xD5, 0xBD, 0x7A, 0x12, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xAA, 0xA2, 0x80, 0x5D, 0x8F, 0xCD, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x39, 0x79, 0x64, 0xA1, 0x67, 0x3C, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xC7, 0x49, 0xFF, 0x7F, 0xAC, 0xAB, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x54, 0x3E, 0x83, 0xF0, 0x3D, 0xBC, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x92, 0x4A, 0x38, 0x42, 0x8A, 0xAB, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x0B, 0x4F, 0xEE, 0x9E, 0x92, 0xA5, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xDD, 0x19, 0x96, 0xF2, 0xF0, 0x6B, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xFC, 0xDD, 0xB2, 0x8A, 0xE5, 0x4C, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x06, 0x49, 0xAC, 0x99, 0x7E, 0xF8, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xC8, 0x01, 0x51, 0xEA, 0xF6, 0x52, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x89, 0x66, 0x2B, 0x1F, 0x9B, 0x2A, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x0F, 0x95, 0x07, 0x2B, 0x6C, 0x6E, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC3, 0xB4, 0xBB, 0x91, 0x1F, 0xA3, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x6E, 0x54, 0x28, 0x7B, 0x9C, 0x79, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x45, 0xFF, 0xA6, 0xDA, 0xA2, 0x83, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xDE, 0x8F, 0x17, 0x37, 0x82, 0xCB, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x94, 0x3F, 0x26, 0xC9, 0x1D, 0xD9, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x28, 0x20, 0xCD, 0xC1, 0xF3, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC9, 0xB5, 0x60, 0x9B, 0x1E, 0xDC, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xB9, 0x5B, 0x7D, 0xA0, 0xB2, 0x8C, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xD1, 0x42, 0xE6, 0x39, 0x33, 0x6D, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xC0, 0xFC, 0xD2, 0x14, 0x5D, 0x3E, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x4A, 0x3E, 0x40, 0x16, 0x93, 0x15, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x24, 0xC1, 0x27, 0x27, 0xE5, 0x4B, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x50, 0xD8, 0xBC, 0xC1, 0x46, 0x22, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x0E, 0x60, 0xA1, 0xB3, 0x50, 0xD4, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xB1, 0x26, 0xB6, 0x6D, 0x47, 0x5A, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0xAC, 0x11, 0x35, 0x3E, 0xB9, 0xF4, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x97, 0xFA, 0xBB, 0x6B, 0x39, 0x13, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x34, 0x12, 0x75, 0x8E, 0x9B, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x9E, 0xCD, 0x29, 0xB6, 0xEF, 0x8D, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xAC, 0xE9, 0x25, 0x27, 0xBB, 0x78, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x7A, 0xA8, 0xD3, 0xE3, 0x66, 0xE5, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x4C, 0xC4, 0x2C, 0x76, 0x81, 0x50, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x71, 0x08, 0xB8, 0x52, 0x7C, 0xAF, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x59, 0x24, 0xDD, 0xFB, 0x2F, 0xD0, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCD, 0x56, 0xE9, 0xAC, 0x91, 0xE6, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x64, 0x20, 0xC6, 0x9F, 0xE4, 0xEF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x2C, 0x8F, 0x8C, 0x97, 0xF6, 0x22, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0x88, 0xAA, 0xA8, 0xD7, 0xA5, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x6C, 0xAE, 0x83, 0xB1, 0x55, 0x55, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x67, 0x84, 0x47, 0x7C, 0x83, 0x5C, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x10, 0x4D, 0xDD, 0x30, 0x60, 0xB0, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xA7, 0x36, 0x76, 0x24, 0x32, 0x9F, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x42, 0x81, 0xFB, 0xA4, 0x2E, 0x13, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x94, 0x91, 0xFF, 0x99, 0xA0, 0x09, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x83, 0xA1, 0x76, 0xAF, 0x37, 0x5C, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA8, 0x04, 0x86, 0xC4, 0xA9, 0x79, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8C, 0xC2, 0x34, 0xFB, 0x83, 0x28, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x03, 0x7D, 0x5E, 0x9E, 0x0E, 0xB0, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x02, 0x46, 0x7F, 0xB9, 0xAC, 0xBB, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xED, 0x48, 0xC2, 0x96, 0x4D, 0x56, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xC5, 0xD1, 0xE6, 0x1C, 0x7E, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x2E, 0x18, 0x71, 0x2D, 0x7B, 0xD7, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x46, 0x9D, 0xDE, 0xAA, 0x78, 0x8E, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD7, 0x69, 0x2E, 0xE1, 0xD9, 0x48, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp521r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFF, 0x9E, 0x09, 0x22, 0x22, 0xE6, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x14, 0x28, 0x13, 0x1B, 0x62, 0x12, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x7F, 0x67, 0x03, 0xB0, 0xC0, 0xF3, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xC3, 0x0F, 0xFB, 0x25, 0x48, 0x3E, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x6E, 0x53, 0x98, 0x36, 0xB3, 0xD3, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x81, 0x54, 0x22, 0xA4, 0xCC, 0xC1, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xBA, 0xFC, 0xA9, 0xDF, 0x68, 0x86, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x92, 0x0E, 0xC3, 0xF2, 0x58, 0xE8, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp521r1_T[32] = { - ECP_POINT_INIT_XY_Z1(secp521r1_T_0_X, secp521r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_1_X, secp521r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_2_X, secp521r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_3_X, secp521r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_4_X, secp521r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_5_X, secp521r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_6_X, secp521r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_7_X, secp521r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_8_X, secp521r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_9_X, secp521r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_10_X, secp521r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_11_X, secp521r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_12_X, secp521r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_13_X, secp521r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_14_X, secp521r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_15_X, secp521r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_16_X, secp521r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_17_X, secp521r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_18_X, secp521r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_19_X, secp521r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_20_X, secp521r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_21_X, secp521r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_22_X, secp521r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_23_X, secp521r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_24_X, secp521r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_25_X, secp521r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_26_X, secp521r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_27_X, secp521r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_28_X, secp521r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_29_X, secp521r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_30_X, secp521r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(secp521r1_T_31_X, secp521r1_T_31_Y), -}; -#else -#define secp521r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static const mbedtls_mpi_uint secp192k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp192k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp192k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x03, 0x00), -}; -static const mbedtls_mpi_uint secp192k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), -}; -static const mbedtls_mpi_uint secp192k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), -}; -static const mbedtls_mpi_uint secp192k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp192k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), -}; -static const mbedtls_mpi_uint secp192k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), -}; -static const mbedtls_mpi_uint secp192k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x77, 0x3D, 0x0D, 0x85, 0x48, 0xA8, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x07, 0xDF, 0x1D, 0xB3, 0xB3, 0x01, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x86, 0xF6, 0xAF, 0x19, 0x2A, 0x88, 0x2E), -}; -static const mbedtls_mpi_uint secp192k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x90, 0xB6, 0x2F, 0x48, 0x36, 0x4C, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x11, 0x14, 0xA6, 0xCB, 0xBA, 0x15, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB0, 0xF2, 0xD4, 0xC9, 0xDA, 0xBA, 0xD7), -}; -static const mbedtls_mpi_uint secp192k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xC1, 0x9C, 0xE6, 0xBB, 0xFB, 0xCF, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x19, 0xAC, 0x5A, 0xC9, 0x8A, 0x1C, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xF6, 0x76, 0x86, 0x89, 0x27, 0x8D, 0x28), -}; -static const mbedtls_mpi_uint secp192k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xE0, 0x6F, 0x34, 0xBA, 0x5E, 0xD3, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xDC, 0xA6, 0x87, 0xC9, 0x9D, 0xC0, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x11, 0x7E, 0xD6, 0xF7, 0x33, 0xFC, 0xE4), -}; -static const mbedtls_mpi_uint secp192k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x37, 0x3E, 0xC0, 0x7F, 0x62, 0xE7, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3B, 0x69, 0x9D, 0x44, 0xBC, 0x82, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x84, 0xB3, 0x5F, 0x2B, 0xA5, 0x9E, 0x2C), -}; -static const mbedtls_mpi_uint secp192k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x95, 0xEB, 0x4C, 0x04, 0xB4, 0xF4, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAD, 0x4B, 0xD5, 0x9A, 0xEB, 0xC4, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xB1, 0xC5, 0x59, 0xE3, 0xD5, 0x16, 0x2A), -}; -static const mbedtls_mpi_uint secp192k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x2A, 0xCC, 0xAC, 0xD0, 0xEE, 0x50, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x83, 0xE0, 0x5B, 0x14, 0x44, 0x52, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x15, 0x2D, 0x78, 0xF6, 0x51, 0x32, 0xCF), -}; -static const mbedtls_mpi_uint secp192k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x36, 0x9B, 0xDD, 0xF8, 0xDD, 0xEF, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xB1, 0x6A, 0x2B, 0xAF, 0xEB, 0x2B, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x87, 0x7A, 0x66, 0x5D, 0x5B, 0xDF, 0x8F), -}; -static const mbedtls_mpi_uint secp192k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x45, 0xE5, 0x81, 0x9B, 0xEB, 0x37, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x29, 0xE2, 0x20, 0x64, 0x23, 0x6B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1D, 0x41, 0xE1, 0x9B, 0x61, 0x7B, 0xD9), -}; -static const mbedtls_mpi_uint secp192k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x57, 0xA3, 0x0A, 0x13, 0xE4, 0x59, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x6E, 0x4A, 0x48, 0x84, 0x90, 0xAC, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB8, 0xF5, 0xF3, 0xDE, 0xA0, 0xA1, 0x1D), -}; -static const mbedtls_mpi_uint secp192k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x32, 0x81, 0xA9, 0x91, 0x5A, 0x4E, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xA8, 0x90, 0xBE, 0x0F, 0xEC, 0xC0, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x30, 0xD7, 0x08, 0xAE, 0xC4, 0x3A, 0xA5), -}; -static const mbedtls_mpi_uint secp192k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x55, 0xE3, 0x76, 0xB3, 0x64, 0x74, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x75, 0xD4, 0xDB, 0x98, 0xD7, 0x39, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xEB, 0x8A, 0xAB, 0x16, 0xD9, 0xD4, 0x0B), -}; -static const mbedtls_mpi_uint secp192k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xBE, 0xF9, 0xC7, 0xC7, 0xBA, 0xF3, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x85, 0x59, 0xF3, 0x60, 0x41, 0x02, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x1C, 0x4A, 0xA4, 0xC7, 0xED, 0x66, 0xBC), -}; -static const mbedtls_mpi_uint secp192k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x2E, 0x46, 0x52, 0x18, 0x87, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x35, 0x5A, 0x75, 0xAC, 0x4D, 0x75, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x2F, 0xAC, 0xFC, 0xBC, 0xE6, 0x93, 0x5E), -}; -static const mbedtls_mpi_uint secp192k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x4D, 0xC9, 0x18, 0xE9, 0x00, 0xEB, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x69, 0x72, 0x07, 0x5A, 0x59, 0xA8, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x65, 0x83, 0x20, 0x10, 0xF9, 0x69, 0x82), -}; -static const mbedtls_mpi_uint secp192k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x56, 0x7F, 0x9F, 0xBF, 0x46, 0x0C, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0xF0, 0xDC, 0xDF, 0x2D, 0xE6, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xF0, 0x72, 0x3A, 0x7A, 0x03, 0xE5, 0x22), -}; -static const mbedtls_mpi_uint secp192k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xAA, 0x57, 0x13, 0x37, 0xA7, 0x2C, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xAC, 0xA2, 0x23, 0xF9, 0x84, 0x60, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xEB, 0x51, 0x70, 0x64, 0x78, 0xCA, 0x05), -}; -static const mbedtls_mpi_uint secp192k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xCC, 0x30, 0x62, 0x93, 0x46, 0x13, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x26, 0xCC, 0x6C, 0x3D, 0x5C, 0xDA, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xAA, 0xB8, 0x03, 0xA4, 0x1A, 0x00, 0x96), -}; -static const mbedtls_mpi_uint secp192k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x9D, 0xE6, 0xCC, 0x4E, 0x2E, 0xC2, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xC3, 0x8A, 0xAE, 0x6F, 0x40, 0x05, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x8F, 0x4A, 0x4D, 0x35, 0xD3, 0x50, 0x9D), -}; -static const mbedtls_mpi_uint secp192k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xFD, 0x98, 0xAB, 0xC7, 0x03, 0xB4, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x40, 0xD2, 0x9F, 0xCA, 0xD0, 0x53, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x84, 0x00, 0x6F, 0xC8, 0xAD, 0xED, 0x8D), -}; -static const mbedtls_mpi_uint secp192k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xD3, 0x57, 0xD7, 0xC3, 0x07, 0xBD, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xBA, 0x47, 0x1D, 0x3D, 0xEF, 0x98, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC0, 0x6C, 0x7F, 0x12, 0xEE, 0x9F, 0x67), -}; -static const mbedtls_mpi_uint secp192k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x02, 0xDA, 0x79, 0xAA, 0xC9, 0x27, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x79, 0xC7, 0x71, 0x84, 0xCB, 0xE5, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x37, 0x06, 0xBA, 0xB5, 0xD5, 0x18, 0x4C), -}; -static const mbedtls_mpi_uint secp192k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x65, 0x72, 0x6C, 0xF2, 0x63, 0x27, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xBC, 0x71, 0xDF, 0x75, 0xF8, 0x98, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x70, 0x9B, 0xDC, 0xE7, 0x18, 0x71, 0xFF), -}; -static const mbedtls_mpi_uint secp192k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x5B, 0x9F, 0x00, 0x5A, 0xB6, 0x80, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE0, 0xBB, 0xFC, 0x5E, 0x78, 0x9C, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x03, 0x68, 0x83, 0x3D, 0x2E, 0x4C, 0xDD), -}; -static const mbedtls_mpi_uint secp192k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x49, 0x23, 0xA8, 0xCB, 0x3B, 0x1A, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x3D, 0xA7, 0x46, 0xCF, 0x75, 0xB6, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xFD, 0x30, 0x01, 0xB6, 0xEF, 0xF9, 0xE8), -}; -static const mbedtls_mpi_uint secp192k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xFA, 0xDA, 0xB8, 0x29, 0x42, 0xC9, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xD7, 0xA0, 0xE6, 0x6B, 0x86, 0x61, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xE9, 0xD3, 0x37, 0xD8, 0xE7, 0x35, 0xA9), -}; -static const mbedtls_mpi_uint secp192k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC8, 0x8E, 0xB1, 0xCB, 0xB1, 0xB5, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xD7, 0x46, 0x7D, 0xAF, 0xE2, 0xDC, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x46, 0xE7, 0xD8, 0x76, 0x31, 0x90, 0x76), -}; -static const mbedtls_mpi_uint secp192k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD3, 0xF4, 0x74, 0xE1, 0x67, 0xD8, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x70, 0x3C, 0xC8, 0xAF, 0x5F, 0xF4, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x4E, 0xED, 0x5C, 0x43, 0xB3, 0x16, 0x35), -}; -static const mbedtls_mpi_uint secp192k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAE, 0xD1, 0xDD, 0x31, 0x14, 0xD3, 0xF0), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x14, 0x06, 0x13, 0x12, 0x1C, 0x81, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xF9, 0x0C, 0x91, 0xF7, 0x67, 0x59, 0x63), -}; -static const mbedtls_mpi_uint secp192k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x91, 0xE2, 0xF4, 0x9D, 0xEB, 0x88, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x82, 0x30, 0x9C, 0xAE, 0x18, 0x4D, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x79, 0xCF, 0x17, 0xA5, 0x1E, 0xE8, 0xC8), -}; -static const mbedtls_ecp_point secp192k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp192k1_T_0_X, secp192k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_1_X, secp192k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_2_X, secp192k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_3_X, secp192k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_4_X, secp192k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_5_X, secp192k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_6_X, secp192k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_7_X, secp192k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_8_X, secp192k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_9_X, secp192k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_10_X, secp192k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_11_X, secp192k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_12_X, secp192k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_13_X, secp192k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_14_X, secp192k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp192k1_T_15_X, secp192k1_T_15_Y), -}; -#else -#define secp192k1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static const mbedtls_mpi_uint secp224k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp224k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x05, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_4(0x33, 0x5B, 0x45, 0xA1), -}; -static const mbedtls_mpi_uint secp224k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_4(0xED, 0x9F, 0x08, 0x7E), -}; -static const mbedtls_mpi_uint secp224k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp224k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x5B, 0x45, 0xA1, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x9F, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x6C, 0x22, 0x22, 0x40, 0x89, 0xAE, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x92, 0xE1, 0x87, 0x56, 0x35, 0xAF, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xAF, 0x08, 0x35, 0x27, 0xEA, 0x04, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x53, 0xFD, 0xCF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xD0, 0x9F, 0x8D, 0xF3, 0x63, 0x54, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xDB, 0x0F, 0x61, 0x54, 0x26, 0xD1, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x21, 0xF7, 0x1B, 0xB5, 0x1D, 0xF6, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x05, 0xDA, 0x8F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x26, 0x73, 0xBC, 0xE4, 0x29, 0x62, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x95, 0x17, 0x8B, 0xC3, 0x9B, 0xAC, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xDB, 0x77, 0xDF, 0xDD, 0x13, 0x04, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xFC, 0x22, 0x93, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0xF1, 0x5A, 0x37, 0xEF, 0x79, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x37, 0xAC, 0x9A, 0x5B, 0x51, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x75, 0x13, 0xA9, 0x4A, 0xAD, 0xFE, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x82, 0x6F, 0x66, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x5E, 0xF0, 0x40, 0xC3, 0xA6, 0xE2, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x9A, 0x6F, 0xCF, 0x11, 0x26, 0x66, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x73, 0xA8, 0xCF, 0x2B, 0x12, 0x36, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xB3, 0x0A, 0x58, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x79, 0x00, 0x55, 0x04, 0x34, 0x90, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x54, 0x1C, 0xC2, 0x45, 0x0C, 0x1B, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x19, 0xAB, 0xA8, 0xFC, 0x73, 0xDC, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xFB, 0x93, 0xCE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x75, 0xD0, 0x66, 0x95, 0x86, 0xCA, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xEA, 0x29, 0x16, 0x6A, 0x38, 0xDF, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA2, 0x36, 0x2F, 0xDC, 0xBB, 0x5E, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x89, 0x59, 0x49, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xA3, 0x99, 0x9D, 0xB8, 0x77, 0x9D, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x93, 0x43, 0x47, 0xC6, 0x5C, 0xF9, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x00, 0x79, 0x42, 0x64, 0xB8, 0x25, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x54, 0xB4, 0x33, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x0C, 0x42, 0x90, 0x83, 0x0B, 0x31, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2E, 0xAE, 0xC8, 0xC7, 0x5F, 0xD2, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xBC, 0xAD, 0x41, 0xE7, 0x32, 0x3A, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x97, 0x52, 0x83, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x13, 0x7A, 0xBD, 0xAE, 0x94, 0x60, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x9B, 0x95, 0xB4, 0x6E, 0x68, 0xB2, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x49, 0xBE, 0x51, 0xFE, 0x66, 0x15, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x37, 0xE4, 0xFE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x9B, 0xEE, 0x64, 0xC9, 0x1B, 0xBD, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x5F, 0x34, 0xA9, 0x0B, 0xB7, 0x25, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x13, 0xB1, 0x38, 0xFB, 0x9D, 0x78, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xE7, 0x1B, 0xFA, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xB3, 0xB7, 0x44, 0x92, 0x6B, 0x00, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x82, 0x44, 0x3E, 0x18, 0x1A, 0x58, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF8, 0xC0, 0xE4, 0xEE, 0xC1, 0xBF, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x32, 0x27, 0xB2, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x9A, 0x42, 0x62, 0x8B, 0x26, 0x54, 0x21), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x85, 0x74, 0xA0, 0x79, 0xA8, 0xEE, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0x60, 0xB3, 0x28, 0x4D, 0x55, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x27, 0x82, 0x29, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xFC, 0x73, 0x77, 0xAF, 0x5C, 0xAC, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xED, 0xE5, 0xF6, 0x1D, 0xA8, 0x67, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xDE, 0x33, 0x1C, 0xF1, 0x80, 0x73, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE2, 0xDE, 0x3C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x3E, 0x6B, 0xFE, 0xF0, 0x04, 0x28, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xB2, 0x14, 0x9D, 0x18, 0x11, 0x7D, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC4, 0xD6, 0x2E, 0x6E, 0x57, 0x4D, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x55, 0x1B, 0xDE, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xF7, 0x17, 0xBC, 0x45, 0xAB, 0x16, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xB0, 0xEF, 0x61, 0xE3, 0x20, 0x7C, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x85, 0x41, 0x4D, 0xF1, 0x7E, 0x4D, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC2, 0x9B, 0x5E, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x2E, 0x49, 0x3D, 0x3E, 0x4B, 0xD3, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x2B, 0x9D, 0xD5, 0x27, 0xFA, 0xCA, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xB3, 0x6A, 0xE0, 0x79, 0x14, 0x28, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x1E, 0xDC, 0xF5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x44, 0x56, 0xCD, 0xFC, 0x9F, 0x09, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x8C, 0x59, 0xA4, 0x64, 0x2A, 0x3A, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xA0, 0xB5, 0x86, 0x4E, 0x69, 0xDA, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x8B, 0x11, 0x38, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x17, 0x16, 0x12, 0x17, 0xDC, 0x00, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x76, 0x24, 0x6C, 0x97, 0x2C, 0xB5, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x71, 0xE3, 0xB0, 0xBB, 0x4E, 0x50, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x48, 0x26, 0xD5, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x5F, 0x28, 0xF6, 0x01, 0x5A, 0x60, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x95, 0xFE, 0xD0, 0xAD, 0x15, 0xD4, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0x7A, 0xFD, 0x80, 0xF7, 0x9F, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xBC, 0x1B, 0xDF, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xE6, 0xDF, 0x14, 0x29, 0xF4, 0xD4, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x12, 0xDD, 0xEC, 0x5B, 0x8A, 0x59, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x92, 0x3E, 0x35, 0x08, 0xE9, 0xCF, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x35, 0x29, 0x97, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xDB, 0xD6, 0x6A, 0xC5, 0x43, 0xA4, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x33, 0x50, 0x61, 0x70, 0xA1, 0xE9, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x15, 0x6E, 0x5F, 0x01, 0x0C, 0x8C, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xA1, 0x9A, 0x9D, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xC6, 0xF7, 0xE2, 0x4A, 0xCD, 0x9B, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x4D, 0x5A, 0xB8, 0xE2, 0x6D, 0xA6, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3F, 0xB6, 0x17, 0xE3, 0x2C, 0x6F, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA4, 0x59, 0x51, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x4F, 0x7C, 0x49, 0xCD, 0x6E, 0xEB, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xC9, 0x1F, 0xB7, 0x4D, 0x98, 0xC7, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xFD, 0x98, 0x20, 0x95, 0xBB, 0x20, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF2, 0x73, 0x92, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xEF, 0xFB, 0x30, 0xFA, 0x12, 0x1A, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x4C, 0x24, 0xB4, 0x5B, 0xC9, 0x4C, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xDD, 0x5E, 0x84, 0x95, 0x4D, 0x26, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xFA, 0xF9, 0x3A, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xA3, 0x2E, 0x7A, 0xDC, 0xA7, 0x53, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x9F, 0x81, 0x84, 0xB2, 0x0D, 0xFE, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x89, 0x1B, 0x77, 0x0C, 0x89, 0x71, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0x7F, 0xB2, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xE9, 0x2C, 0x79, 0xA6, 0x3C, 0xAD, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE0, 0x23, 0x02, 0x86, 0x0F, 0x77, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x93, 0x6D, 0xE9, 0xF9, 0x3C, 0xBE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xE7, 0x24, 0x92, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x3C, 0x5B, 0x4B, 0x1B, 0x25, 0x37, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xE8, 0x38, 0x1B, 0xA1, 0x5A, 0x2E, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x19, 0xFD, 0xF4, 0x78, 0x01, 0x6B, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x69, 0x37, 0x4F, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xE2, 0xBF, 0xD3, 0xEC, 0x95, 0x9C, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x7B, 0xFC, 0xD5, 0xD3, 0x25, 0x5E, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x55, 0x09, 0xA2, 0x58, 0x6A, 0xC9, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xCC, 0x3B, 0xD9, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_mpi_uint secp224k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x08, 0x65, 0x5E, 0xCB, 0xAB, 0x48, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x79, 0x8B, 0xC0, 0x11, 0xC0, 0x69, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xE8, 0x8C, 0x4C, 0xC5, 0x28, 0xE4, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x1F, 0x34, 0x5C, 0x00, 0x00, 0x00, 0x00), -}; -static const mbedtls_ecp_point secp224k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp224k1_T_0_X, secp224k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_1_X, secp224k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_2_X, secp224k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_3_X, secp224k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_4_X, secp224k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_5_X, secp224k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_6_X, secp224k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_7_X, secp224k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_8_X, secp224k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_9_X, secp224k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_10_X, secp224k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_11_X, secp224k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_12_X, secp224k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_13_X, secp224k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_14_X, secp224k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp224k1_T_15_X, secp224k1_T_15_Y), -}; -#else -#define secp224k1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static const mbedtls_mpi_uint secp256k1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; -static const mbedtls_mpi_uint secp256k1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), -}; -static const mbedtls_mpi_uint secp256k1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_2(0x07, 0x00), -}; -static const mbedtls_mpi_uint secp256k1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), -}; -static const mbedtls_mpi_uint secp256k1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), -}; -static const mbedtls_mpi_uint secp256k1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint secp256k1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), -}; -static const mbedtls_mpi_uint secp256k1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), -}; -static const mbedtls_mpi_uint secp256k1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xEE, 0xD7, 0x1E, 0x67, 0x86, 0x32, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0xB1, 0xA9, 0xD5, 0xCC, 0x27, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0E, 0x11, 0x01, 0x71, 0xFE, 0x92, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x28, 0x63, 0x6D, 0x72, 0x09, 0xA6, 0xC0), -}; -static const mbedtls_mpi_uint secp256k1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0x69, 0xDC, 0x3E, 0x2C, 0x75, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xB7, 0x3F, 0x30, 0x26, 0x3C, 0xDF, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBE, 0xB9, 0x5D, 0x0E, 0xE8, 0x5E, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xC3, 0x05, 0xD6, 0xB7, 0xD5, 0x24, 0xFC), -}; -static const mbedtls_mpi_uint secp256k1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCF, 0x7B, 0xDC, 0xCD, 0xC3, 0x39, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xDA, 0xB9, 0xE5, 0x64, 0xA7, 0x47, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x46, 0xA8, 0x61, 0xF6, 0x23, 0xEB, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xC1, 0xFF, 0xE4, 0x55, 0xD5, 0xC2, 0xBF), -}; -static const mbedtls_mpi_uint secp256k1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xBE, 0xB9, 0x59, 0x24, 0x13, 0x4A, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x45, 0x12, 0xDE, 0xBA, 0x4F, 0xEF, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x08, 0xBF, 0xC1, 0x66, 0xAA, 0x0A, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xFE, 0x30, 0x55, 0x31, 0x86, 0xA7, 0xB4), -}; -static const mbedtls_mpi_uint secp256k1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBF, 0x18, 0x81, 0x67, 0x27, 0x42, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x05, 0x83, 0xA4, 0xDD, 0x57, 0xD3, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x63, 0xAB, 0xE4, 0x90, 0x70, 0xD0, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x5D, 0xFD, 0xA0, 0xEF, 0xCF, 0x1C, 0x54), -}; -static const mbedtls_mpi_uint secp256k1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x80, 0xE4, 0xF6, 0x09, 0xBC, 0x57, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x9F, 0x6E, 0x88, 0x54, 0x6E, 0x51, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x5F, 0x85, 0xFB, 0x84, 0x3E, 0x4A, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x19, 0xF5, 0x55, 0xC9, 0x07, 0xD8, 0xCE), -}; -static const mbedtls_mpi_uint secp256k1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xB4, 0xC3, 0xD9, 0x5C, 0xA0, 0xD4, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x30, 0xAF, 0x59, 0x9B, 0xF8, 0x04, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xA6, 0xFD, 0x66, 0x7B, 0xC3, 0x39, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xBF, 0xF0, 0xC2, 0xE9, 0x71, 0xA4, 0x9E), -}; -static const mbedtls_mpi_uint secp256k1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x2D, 0xB9, 0x88, 0x28, 0xF1, 0xBE, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF3, 0x1A, 0x0E, 0xB9, 0x01, 0x66, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0xA4, 0xF4, 0x05, 0xD0, 0xAA, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x39, 0x1E, 0x47, 0xE5, 0x68, 0xC8, 0xC0), -}; -static const mbedtls_mpi_uint secp256k1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xB9, 0xFC, 0xE0, 0x33, 0x8A, 0x7D, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x93, 0xA5, 0x53, 0x55, 0x16, 0xB4, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x5F, 0xEA, 0x9B, 0x29, 0x52, 0x71, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xF0, 0x24, 0xB8, 0x7D, 0xB7, 0xA0, 0x9B), -}; -static const mbedtls_mpi_uint secp256k1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x00, 0x27, 0xB2, 0xDF, 0x73, 0xA2, 0xE0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x2E, 0x4D, 0x7C, 0xDE, 0x7A, 0x23, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0x60, 0xC7, 0x97, 0x1E, 0xA4, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x13, 0x5B, 0x77, 0x59, 0xCB, 0x36, 0xE1), -}; -static const mbedtls_mpi_uint secp256k1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xBC, 0x9F, 0x9E, 0x2D, 0x53, 0x2A, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x5F, 0x64, 0x9F, 0x1A, 0x19, 0xE6, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x7B, 0x39, 0xD2, 0xDB, 0x85, 0x84, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xC7, 0x0D, 0x58, 0x6E, 0x3F, 0x52, 0x15), -}; -static const mbedtls_mpi_uint secp256k1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x68, 0x19, 0x0B, 0x68, 0xC9, 0x1E, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x4E, 0x21, 0x49, 0x3D, 0x55, 0xCC, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF9, 0x25, 0x45, 0x54, 0x45, 0xB1, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xF7, 0xCD, 0x80, 0xA4, 0x04, 0x05), -}; -static const mbedtls_mpi_uint secp256k1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x1E, 0x88, 0xC4, 0xAA, 0x18, 0x7E, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xAC, 0xD9, 0xB2, 0xA1, 0xC0, 0x71, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xA2, 0xF1, 0x15, 0xA6, 0x5F, 0x6C, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x5B, 0x05, 0xBC, 0xB7, 0xC6, 0x4E, 0x72), -}; -static const mbedtls_mpi_uint secp256k1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x80, 0xF8, 0x5C, 0x20, 0x2A, 0xE1, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x48, 0x2E, 0x68, 0x82, 0x7F, 0xEB, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x3B, 0x25, 0xDB, 0x32, 0x4D, 0x88, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x6E, 0xA6, 0xB6, 0x6D, 0x62, 0x78, 0x22), -}; -static const mbedtls_mpi_uint secp256k1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4D, 0x3E, 0x86, 0x58, 0xC3, 0xEB, 0xBA), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x89, 0x33, 0x18, 0x21, 0x1D, 0x9B, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x9D, 0xFF, 0xC3, 0x79, 0xC1, 0x88, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xD4, 0x48, 0x53, 0xE8, 0xAD, 0x21, 0x16), -}; -static const mbedtls_mpi_uint secp256k1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x7B, 0xDE, 0xCB, 0xD8, 0x39, 0x17, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xF3, 0x03, 0xF2, 0x5C, 0xBC, 0xC8, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xAE, 0x4C, 0xB0, 0x16, 0xA4, 0x93, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8B, 0x6B, 0xDC, 0xD7, 0x9A, 0x3E, 0x7E), -}; -static const mbedtls_mpi_uint secp256k1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x2D, 0x7A, 0xD2, 0x59, 0x05, 0xA2, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x56, 0x09, 0x32, 0xF1, 0xE8, 0xE3, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xCA, 0xE5, 0x2E, 0xF0, 0xFB, 0x18, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x85, 0xA9, 0x23, 0x15, 0x31, 0x1F, 0x0E), -}; -static const mbedtls_mpi_uint secp256k1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xE5, 0xB1, 0x86, 0xB9, 0x6E, 0x8D, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x77, 0xFC, 0xC9, 0xA3, 0x3F, 0x89, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x6A, 0xDC, 0x25, 0xB0, 0xC7, 0x41, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x11, 0x6B, 0xA6, 0x11, 0x62, 0xD4, 0x2D), -}; -static const mbedtls_mpi_uint secp256k1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7D, 0x34, 0xB3, 0x20, 0x7F, 0x37, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xD4, 0x45, 0xE8, 0xC2, 0xE9, 0xC5, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x32, 0x3B, 0x25, 0x7E, 0x79, 0xAF, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xE4, 0x54, 0x71, 0xBE, 0x35, 0x4E, 0xD0), -}; -static const mbedtls_mpi_uint secp256k1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x94, 0xDD, 0x8F, 0xB5, 0xC2, 0xDD, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x49, 0xE9, 0x1C, 0x2F, 0x08, 0x49, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xB6, 0x03, 0x88, 0x6F, 0xB8, 0x15, 0x67), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xD3, 0x1C, 0xF3, 0xA5, 0xEB, 0x79, 0x01), -}; -static const mbedtls_mpi_uint secp256k1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF9, 0x43, 0x88, 0x89, 0x0D, 0x06, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2D, 0xF5, 0x98, 0x32, 0xF6, 0xB1, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0x8F, 0x2B, 0x50, 0x27, 0x0A, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE3, 0xBD, 0x16, 0x05, 0xC8, 0x93, 0x12), -}; -static const mbedtls_mpi_uint secp256k1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x6A, 0xF7, 0xE3, 0x3D, 0xDE, 0x5F, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA3, 0x9C, 0x22, 0x3C, 0x33, 0x36, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x24, 0x4C, 0x69, 0x45, 0x78, 0x14, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xF8, 0xD4, 0xBF, 0xB8, 0xC0, 0xA1, 0x25), -}; -static const mbedtls_mpi_uint secp256k1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x88, 0xE1, 0x91, 0x03, 0xEB, 0xB3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x11, 0xA1, 0xEF, 0x14, 0x0D, 0xC4, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xD4, 0x0D, 0x1D, 0x96, 0x33, 0x5C, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x45, 0x2A, 0x1A, 0xE6, 0x57, 0x04, 0x9B), -}; -static const mbedtls_mpi_uint secp256k1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xB5, 0xA7, 0x80, 0xE9, 0x93, 0x97, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xB9, 0x7C, 0xA0, 0xC9, 0x57, 0x26, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xEF, 0x56, 0xDA, 0x66, 0xF6, 0x1B, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x89, 0x6B, 0x91, 0xE0, 0xA9, 0x65, 0x2B), -}; -static const mbedtls_mpi_uint secp256k1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x98, 0x96, 0x9B, 0x06, 0x7D, 0x5E, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xFA, 0xC1, 0x5F, 0x19, 0x37, 0x94, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xBE, 0x6B, 0x1A, 0x05, 0xE4, 0xBF, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xCD, 0x5D, 0x35, 0xB4, 0x51, 0xF7, 0x64), -}; -static const mbedtls_mpi_uint secp256k1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xEF, 0x96, 0xDB, 0xF2, 0x61, 0x63, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x04, 0x88, 0xC9, 0x9F, 0x1B, 0x94, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x30, 0x79, 0x7E, 0x24, 0xE7, 0x5F, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xB8, 0x90, 0xB7, 0x94, 0x25, 0xBB, 0x0F), -}; -static const mbedtls_mpi_uint secp256k1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x79, 0xEA, 0xAD, 0xC0, 0x6D, 0x18, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xA4, 0x58, 0x2A, 0x8D, 0x95, 0xB3, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC4, 0xC2, 0x12, 0x0D, 0x79, 0xE2, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6F, 0xBE, 0x97, 0x4D, 0xA4, 0x20, 0x07), -}; -static const mbedtls_mpi_uint secp256k1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x31, 0x71, 0xC6, 0xA6, 0x91, 0xEB, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x9B, 0xA8, 0x4A, 0xE7, 0x77, 0xE1, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x06, 0xD3, 0x3D, 0x94, 0x30, 0xEF, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xDF, 0xCA, 0xFA, 0xF5, 0x28, 0xF8, 0xC9), -}; -static const mbedtls_mpi_uint secp256k1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xE1, 0x32, 0xFD, 0x3E, 0x81, 0xF8, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xF2, 0x4B, 0x1D, 0x19, 0xC9, 0x0F, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB1, 0x8A, 0x22, 0x8B, 0x05, 0x6B, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x21, 0xEF, 0x30, 0xEC, 0x09, 0x2A, 0x89), -}; -static const mbedtls_mpi_uint secp256k1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x84, 0x4A, 0x46, 0x07, 0x6C, 0x3C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x18, 0x3A, 0xF4, 0xCC, 0xF5, 0xB2, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x8F, 0xCD, 0x0A, 0x9C, 0xF4, 0xBD, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x89, 0x7F, 0x8A, 0xB1, 0x52, 0x3A, 0xAB), -}; -static const mbedtls_ecp_point secp256k1_T[16] = { - ECP_POINT_INIT_XY_Z1(secp256k1_T_0_X, secp256k1_T_0_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_1_X, secp256k1_T_1_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_2_X, secp256k1_T_2_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_3_X, secp256k1_T_3_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_4_X, secp256k1_T_4_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_5_X, secp256k1_T_5_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_6_X, secp256k1_T_6_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_7_X, secp256k1_T_7_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_8_X, secp256k1_T_8_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_9_X, secp256k1_T_9_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_10_X, secp256k1_T_10_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_11_X, secp256k1_T_11_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_12_X, secp256k1_T_12_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_13_X, secp256k1_T_13_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_14_X, secp256k1_T_14_Y), - ECP_POINT_INIT_XY_Z0(secp256k1_T_15_X, secp256k1_T_15_Y), -}; -#else -#define secp256k1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -/* - * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) - */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP256r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), -}; -static const mbedtls_mpi_uint brainpoolP256r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP256r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP256r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xA2, 0xED, 0x52, 0xC9, 0x8C, 0xE3, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xC9, 0xC4, 0x87, 0x3F, 0x93, 0x7A, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x12, 0x53, 0x61, 0x3E, 0x76, 0x08, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x8C, 0x74, 0xF4, 0x08, 0xC3, 0x76, 0x80), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xDD, 0x09, 0xA6, 0xED, 0xEE, 0xC4, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xD9, 0xBE, 0x4B, 0xA5, 0xB7, 0x2B, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x20, 0x12, 0xCA, 0x0A, 0x38, 0x24, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x72, 0x71, 0x90, 0x7A, 0x2E, 0xB7, 0x23), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0xA1, 0x93, 0x10, 0x2A, 0x51, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x10, 0x11, 0x12, 0xBC, 0xB0, 0xB6, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x58, 0xD7, 0x0A, 0x84, 0x05, 0xA3, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x8E, 0x95, 0x61, 0xD3, 0x0B, 0xDF, 0x36), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x92, 0x12, 0x0F, 0x5E, 0x87, 0x70, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xE9, 0x9B, 0xEB, 0x3A, 0xFB, 0xCF, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0x92, 0xB9, 0xF7, 0x45, 0xD3, 0x06, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x28, 0x65, 0xE1, 0xC5, 0x6C, 0x57, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x0E, 0x77, 0x01, 0x81, 0x9E, 0x38, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xF0, 0xD5, 0xA5, 0x91, 0x2B, 0xDF, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xEE, 0xB6, 0x25, 0xD6, 0x98, 0xDE, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0x55, 0x63, 0x39, 0xEB, 0xB5, 0x47), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD6, 0xB8, 0xE3, 0x13, 0xED, 0x7F, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xE8, 0xAE, 0x36, 0xB8, 0xCD, 0x19, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x82, 0x83, 0x7A, 0x7B, 0x46, 0x56, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x60, 0x46, 0x15, 0x5A, 0xAC, 0x99, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x61, 0x50, 0xC6, 0xFF, 0x10, 0x7D, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x51, 0xDF, 0xA9, 0x7D, 0x78, 0x26, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x15, 0x9A, 0xF7, 0x01, 0xC1, 0xBB, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x0F, 0xE6, 0x2A, 0xBD, 0x4A, 0x9E, 0x87), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF8, 0xD1, 0x77, 0xD2, 0x49, 0xB3, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x86, 0xFB, 0x9E, 0x1F, 0x5A, 0x60, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xC4, 0x8D, 0xCD, 0x86, 0x61, 0x2F, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xF6, 0xB9, 0xAC, 0x37, 0x9D, 0xE9, 0x28), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x77, 0xAA, 0x97, 0x9C, 0x0B, 0x04, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xA6, 0x60, 0x81, 0xCE, 0x25, 0x13, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x00, 0xF3, 0xBB, 0x82, 0x99, 0x95, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0xCE, 0x90, 0x71, 0x38, 0x2F, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x1A, 0xC0, 0x84, 0x27, 0xD6, 0x9D, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x37, 0x52, 0x16, 0x13, 0x0E, 0xCE, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBF, 0x5A, 0xDB, 0xDB, 0x6E, 0x1E, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB7, 0x5E, 0xF9, 0x86, 0xDD, 0x8A, 0x5C), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xAB, 0x5C, 0x8D, 0x1D, 0xF2, 0x2D, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC5, 0xF8, 0xF7, 0x1D, 0x96, 0x0B, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x4C, 0xA7, 0x45, 0x20, 0x6A, 0x1E, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x5D, 0xEF, 0xDE, 0xEE, 0x39, 0x44, 0x19), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x2F, 0x6D, 0x52, 0xC9, 0x58, 0x60, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xC9, 0x62, 0xCB, 0x38, 0x3C, 0x55, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xA5, 0x09, 0x10, 0x88, 0xDB, 0xE3, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xE0, 0x3C, 0xCE, 0x06, 0x0B, 0x4B, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x1D, 0xB4, 0x10, 0x76, 0x8F, 0xBA, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x70, 0x5A, 0x07, 0xF5, 0x1A, 0x74, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xE9, 0x94, 0xA8, 0xC0, 0xD5, 0x4A, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x6D, 0xD4, 0xE8, 0x9B, 0xE9, 0x6D, 0x0E), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x00, 0x32, 0x41, 0x57, 0x84, 0x89, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC7, 0x14, 0xEC, 0xE9, 0x27, 0xFF, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x67, 0x9E, 0xFB, 0xB6, 0xB8, 0x96, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x4A, 0xE3, 0x97, 0x4B, 0x58, 0xDE, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x1E, 0x5C, 0xF5, 0x7F, 0xD5, 0xD4, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x08, 0x7A, 0xF1, 0xBD, 0x89, 0xC7, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xF9, 0x11, 0x1B, 0xF5, 0x3C, 0x6D, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x50, 0xE5, 0x69, 0x1D, 0x59, 0xFC, 0x0C), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x2F, 0xF8, 0x3F, 0xEC, 0x55, 0x99, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xA7, 0x29, 0x90, 0x43, 0x81, 0x31, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x18, 0x44, 0x50, 0x5D, 0x76, 0xCB, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xC5, 0x5B, 0x9A, 0x03, 0xE6, 0x17, 0x39), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x89, 0xFC, 0x55, 0x94, 0x91, 0x6A, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x46, 0x35, 0xF2, 0x3A, 0x42, 0x08, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xD2, 0x76, 0x49, 0x42, 0x87, 0xD3, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xEA, 0xA0, 0x52, 0xF1, 0x6A, 0x30, 0x57), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xB2, 0x57, 0xA3, 0x8A, 0x4D, 0x1B, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xA3, 0x99, 0x94, 0xB5, 0x3D, 0x64, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC3, 0xD7, 0x53, 0xF6, 0x49, 0x1C, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x23, 0x41, 0x4D, 0xFB, 0x7A, 0x5C, 0x53), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xB8, 0x15, 0x65, 0x5C, 0x85, 0x94, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x37, 0xC7, 0xF8, 0x7E, 0xAE, 0x6C, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xD8, 0x11, 0x54, 0x98, 0x44, 0xE3, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x4D, 0xA6, 0x4B, 0x28, 0xF2, 0x57, 0x9E), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD0, 0xEB, 0x1E, 0xAA, 0x30, 0xD3, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x9B, 0x4D, 0xA7, 0x73, 0x6E, 0xB6, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x47, 0xF6, 0xED, 0x37, 0xEF, 0x71, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xB5, 0x49, 0x61, 0x5E, 0x45, 0xF6, 0x4A), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x0E, 0xB3, 0x84, 0x3A, 0x63, 0x72, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x53, 0x5C, 0xA7, 0xC6, 0x2E, 0xAB, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x0F, 0x8F, 0x87, 0x50, 0x28, 0xB4, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x98, 0x4A, 0x98, 0x31, 0x86, 0xCA, 0x51), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC9, 0xE2, 0xFD, 0x5D, 0x1F, 0xE8, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x90, 0x91, 0xC4, 0x84, 0xF0, 0xBA, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5A, 0xB3, 0x4E, 0xFB, 0xE0, 0x57, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x0B, 0x90, 0xA6, 0xFD, 0x9D, 0x8E, 0x02), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x41, 0x8F, 0x31, 0xFA, 0x5A, 0xF6, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xE9, 0xE3, 0xF6, 0xE0, 0x4A, 0xE7, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x4E, 0xCD, 0xA2, 0x22, 0x14, 0xD4, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xED, 0x21, 0xB7, 0x0F, 0x53, 0x10, 0x17), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x06, 0x24, 0x2C, 0x4E, 0xD1, 0x1E, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x3F, 0xC1, 0x9F, 0xAB, 0xF0, 0x37, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x5E, 0x12, 0xCE, 0x83, 0x1B, 0x2A, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x65, 0xCF, 0xE8, 0x5C, 0xA5, 0xA2, 0x70), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x86, 0x76, 0x3A, 0x94, 0xF6, 0x1D, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xDA, 0xC9, 0xA6, 0x29, 0x93, 0x15, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x61, 0x6A, 0x7D, 0xC7, 0xA9, 0xF3, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x03, 0x71, 0xA2, 0x15, 0xCE, 0x50, 0x72), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD0, 0xA8, 0x1E, 0x91, 0xC4, 0x4F, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x4B, 0x7E, 0xD7, 0x71, 0x58, 0x7E, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x45, 0xAF, 0x2A, 0x18, 0x93, 0x95, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x8F, 0xC7, 0xFA, 0x4C, 0x7A, 0x86, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xAF, 0x68, 0x3A, 0x23, 0xC1, 0x2E, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x50, 0x11, 0x67, 0x39, 0xB9, 0xAF, 0x48), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x86, 0xAA, 0x1E, 0x88, 0x21, 0x29, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x28, 0xA4, 0x9D, 0x89, 0xA9, 0x9A, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBA, 0x04, 0x67, 0xB7, 0x01, 0x40, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xE9, 0x09, 0xA3, 0xCA, 0xA6, 0x37, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x97, 0xA8, 0xB6, 0x3C, 0xEE, 0x90, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xED, 0xC4, 0xF7, 0xC3, 0x95, 0xEC, 0x85), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x84, 0xBD, 0xEB, 0xD5, 0x64, 0xBB, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x9B, 0xE2, 0x28, 0x50, 0xC2, 0x72, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xF2, 0x74, 0xD1, 0x26, 0xBF, 0x32, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xCB, 0xAF, 0x72, 0xDB, 0x6D, 0x30, 0x98), -}; -static const mbedtls_mpi_uint brainpoolP256r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x50, 0x85, 0xF4, 0x2B, 0x48, 0xC1, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x28, 0xBB, 0x11, 0xBA, 0x5B, 0x22, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA1, 0xE5, 0x5C, 0xC9, 0x1D, 0x44, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xE8, 0xE6, 0x6F, 0xBB, 0xC1, 0x81, 0x7F), -}; -static const mbedtls_ecp_point brainpoolP256r1_T[16] = { - ECP_POINT_INIT_XY_Z1(brainpoolP256r1_T_0_X, brainpoolP256r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_1_X, brainpoolP256r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_2_X, brainpoolP256r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_3_X, brainpoolP256r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_4_X, brainpoolP256r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_5_X, brainpoolP256r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_6_X, brainpoolP256r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_7_X, brainpoolP256r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_8_X, brainpoolP256r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_9_X, brainpoolP256r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_10_X, brainpoolP256r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_11_X, brainpoolP256r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_12_X, brainpoolP256r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_13_X, brainpoolP256r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_14_X, brainpoolP256r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_15_X, brainpoolP256r1_T_15_Y), -}; -#else -#define brainpoolP256r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -/* - * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) - */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP384r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), -}; -static const mbedtls_mpi_uint brainpoolP384r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP384r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xD8, 0x8A, 0x54, 0x41, 0xD6, 0x6B, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x3B, 0xF1, 0x22, 0xFD, 0x2D, 0x4B, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x55, 0xE3, 0x33, 0xF0, 0x73, 0x52, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x3F, 0x30, 0x26, 0xCA, 0x7F, 0x52, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x6E, 0x17, 0x9B, 0xD5, 0x2A, 0x4A, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xDA, 0x6B, 0xE5, 0x03, 0x07, 0x1D, 0x2E), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x7A, 0xAF, 0x98, 0xE3, 0xA4, 0xF6, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x7D, 0xFE, 0x51, 0x40, 0x3B, 0x47, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x88, 0xEC, 0xC4, 0xE2, 0x8F, 0xCB, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xE2, 0x88, 0x2D, 0x4E, 0x50, 0xEB, 0x9A), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x54, 0x94, 0x5E, 0xF4, 0x7F, 0x3A, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x07, 0x1C, 0xE1, 0xBD, 0x0F, 0xF8, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x92, 0x28, 0x2E, 0x32, 0x04, 0xB1, 0x4D), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x82, 0x44, 0x43, 0x76, 0x0D, 0x55, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xE3, 0xFF, 0x89, 0x46, 0xDE, 0x4E, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x22, 0xBB, 0x67, 0x1A, 0x81, 0xEE, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x54, 0xE2, 0x7A, 0xAE, 0xDA, 0x2C, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x9A, 0x90, 0xAA, 0x6E, 0x8B, 0xCC, 0x5F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x40, 0xAC, 0xED, 0x7D, 0x37, 0x87, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xF8, 0xB1, 0x80, 0x4C, 0x8C, 0x04, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x98, 0x2C, 0xAD, 0x30, 0x69, 0x35, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x2E, 0x00, 0x2F, 0x44, 0x8C, 0xF0, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x58, 0x07, 0xD7, 0xCD, 0x60, 0xA1, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFB, 0x7B, 0x03, 0x05, 0x5E, 0x79, 0x73), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x17, 0xCE, 0x38, 0x4B, 0x5E, 0x5B, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x0E, 0x0A, 0x61, 0x9D, 0x7C, 0x62, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF0, 0x98, 0x71, 0x7F, 0x17, 0x26, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xD3, 0xFA, 0x3C, 0xF0, 0x70, 0x07, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x47, 0x5C, 0x09, 0x43, 0xB7, 0x65, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xA7, 0x3E, 0xFA, 0xF3, 0xEC, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x78, 0x22, 0x2B, 0x58, 0x71, 0xFA, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x30, 0xCE, 0x6A, 0xB3, 0xB0, 0x4F, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x95, 0x20, 0xA9, 0x23, 0xC2, 0x65, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xCF, 0x03, 0x5B, 0x8A, 0x80, 0x44, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xF8, 0x91, 0xF7, 0xD5, 0xED, 0xEA, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x5B, 0x16, 0x10, 0x25, 0xAC, 0x2A, 0x17), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEC, 0xDC, 0xC4, 0x7B, 0x8C, 0x6B, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBB, 0x1C, 0xD3, 0x5A, 0xEE, 0xD9, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5D, 0x30, 0x5E, 0xF7, 0xB2, 0x41, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xCE, 0x0F, 0x1A, 0xC6, 0x41, 0x64, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x18, 0xE1, 0xE3, 0x82, 0x15, 0x66, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xE2, 0x24, 0x04, 0x72, 0x39, 0xA0, 0x7C), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x51, 0xA2, 0x58, 0x88, 0x62, 0xE1, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xD2, 0x65, 0x14, 0xE9, 0x4C, 0x82, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE1, 0xAC, 0x87, 0xAE, 0x31, 0x1A, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4F, 0x96, 0x1E, 0x85, 0x7A, 0xC3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x86, 0xBB, 0xF0, 0xC0, 0x9D, 0x08, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x53, 0x03, 0x09, 0x80, 0x91, 0xEF, 0x68), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xD7, 0xAF, 0x6F, 0x69, 0x7B, 0x88, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x13, 0xE4, 0x30, 0xA2, 0x47, 0xB5, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD2, 0xC0, 0xDD, 0x8A, 0x1C, 0x3C, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x8C, 0xB3, 0x4C, 0xBA, 0x8B, 0x6D, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xC7, 0xA1, 0xA8, 0x6E, 0x3C, 0x4F, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x4A, 0x97, 0xC8, 0x03, 0x6F, 0x01, 0x82), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x18, 0x12, 0xA9, 0x39, 0xD5, 0x22, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA7, 0xC0, 0xBD, 0x9D, 0x8D, 0x78, 0x38), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xD0, 0x7F, 0xDF, 0xD0, 0x30, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x73, 0x96, 0xEC, 0xA8, 0x1D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xD1, 0x65, 0x66, 0xDC, 0xD9, 0xCF, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xED, 0x7B, 0x37, 0xAD, 0xE2, 0xBE, 0x2D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x79, 0x42, 0x6A, 0x07, 0x66, 0xB1, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x53, 0x62, 0x65, 0x92, 0x09, 0x4C, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xAF, 0xC3, 0x03, 0xF6, 0xF4, 0x2D, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xCA, 0x41, 0xD9, 0xA2, 0x69, 0x9B, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xB2, 0xA6, 0x8D, 0xE1, 0xAA, 0x61, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xBA, 0x4D, 0x12, 0xB6, 0xBE, 0xF3, 0x7E), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x92, 0x22, 0x07, 0xCE, 0xC9, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA1, 0x7C, 0x91, 0xDB, 0x32, 0xF7, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x49, 0x4B, 0x6D, 0xFB, 0xD9, 0x70, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xFB, 0x4E, 0x4C, 0x5E, 0x66, 0x81, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xB3, 0xE1, 0x00, 0xB7, 0xD9, 0xCC, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x36, 0x8B, 0xC4, 0x39, 0x20, 0xFD, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x1F, 0x60, 0x03, 0xBB, 0xD7, 0x60, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x3C, 0x62, 0xDD, 0x71, 0x95, 0xE9, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x5B, 0x7A, 0x5F, 0x68, 0x81, 0xC5, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xB5, 0xB9, 0x98, 0x42, 0x28, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x29, 0x8E, 0x11, 0x49, 0xB4, 0xD7, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x3E, 0xD2, 0x30, 0xA1, 0xBA, 0xCA, 0x03), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x37, 0x64, 0x44, 0x2F, 0x03, 0xE5, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x42, 0xBC, 0xFF, 0xA2, 0x1A, 0x5F, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x04, 0xAB, 0x04, 0xE0, 0x24, 0xAD, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x45, 0x17, 0x67, 0x1F, 0x3E, 0x53, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x0F, 0xB3, 0x1B, 0x57, 0x54, 0xC2, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0xF8, 0xC4, 0x1B, 0x9B, 0xFA, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x90, 0xFD, 0xFB, 0xCA, 0x49, 0x38, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xCF, 0xC6, 0xDD, 0xF0, 0xFF, 0x8C, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x69, 0x9D, 0xBD, 0x5F, 0x33, 0xE9, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x19, 0x82, 0x3D, 0xAC, 0x1C, 0x40, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC7, 0x02, 0x46, 0x14, 0x77, 0x00, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x05, 0xF2, 0x77, 0x3A, 0x66, 0x5C, 0x39), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xE6, 0x17, 0xDE, 0xB2, 0xA1, 0xE5, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x71, 0xEC, 0x9D, 0xD8, 0xF5, 0xD4, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xC6, 0x42, 0x5E, 0xE7, 0x18, 0xBA, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x21, 0x68, 0x5A, 0x26, 0xFB, 0xD7, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x00, 0x5C, 0xBA, 0x8A, 0x34, 0xEC, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x3C, 0xAF, 0x53, 0xE8, 0x65, 0x35), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xEF, 0x28, 0xDC, 0x67, 0x05, 0xC8, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x78, 0xC3, 0x85, 0x49, 0xA0, 0xBC, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x3E, 0x2D, 0xA0, 0xCF, 0xD4, 0x7A, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x93, 0xFE, 0x60, 0xB3, 0x6E, 0x99, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xAD, 0x04, 0xE7, 0x49, 0xAF, 0x5E, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x7A, 0xED, 0xA6, 0x9E, 0x18, 0x09, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x05, 0x94, 0x44, 0xDC, 0xB8, 0x85, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xB7, 0x37, 0xC2, 0x50, 0x75, 0x15, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xC6, 0x0F, 0xB2, 0xA9, 0x91, 0x3E, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x81, 0xAD, 0x25, 0xA1, 0x26, 0x73, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xF1, 0xD1, 0x61, 0x7C, 0x76, 0x8F, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xDB, 0x4A, 0xFF, 0x14, 0xA7, 0x48, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x73, 0xC6, 0xC2, 0xCC, 0xF1, 0x57, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xED, 0x73, 0x27, 0x70, 0x82, 0xB6, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xBA, 0xAC, 0x3A, 0xCF, 0xF4, 0xEA, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xD6, 0xB1, 0x8F, 0x0E, 0x08, 0x2C, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE3, 0x8F, 0x2F, 0x0E, 0xA1, 0xF3, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xF5, 0x7C, 0x9B, 0x29, 0x0A, 0xF6, 0x28), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xEE, 0x17, 0x47, 0x34, 0x15, 0xA3, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBE, 0x88, 0x48, 0xE7, 0xA2, 0xBB, 0xDE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xAD, 0xDC, 0x65, 0x61, 0x37, 0x0F, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x67, 0xAD, 0xA2, 0x3A, 0x1C, 0x91, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x07, 0x0C, 0x3A, 0x41, 0x6E, 0x13, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBD, 0x7E, 0xED, 0xAA, 0x14, 0xDD, 0x61), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xDC, 0x20, 0x01, 0x72, 0x11, 0x48, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xC4, 0x7B, 0xF8, 0x62, 0x3D, 0xF0, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xC2, 0x3D, 0x2E, 0x52, 0xA3, 0x4A, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE2, 0x53, 0x46, 0x5E, 0x21, 0xF8, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xC7, 0x8F, 0xA9, 0x26, 0x42, 0x32, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xA6, 0xA0, 0x8D, 0x4B, 0x9A, 0x19, 0x03), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xAB, 0x6D, 0x1E, 0xFB, 0xEE, 0x60, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x56, 0x3C, 0xC5, 0x5D, 0x10, 0x79, 0x1C), - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xBC, 0x41, 0x9F, 0x71, 0xEF, 0x02, 0xF9), - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x36, 0xC4, 0xD0, 0x88, 0x9B, 0x32, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xD4, 0x5D, 0x17, 0x39, 0xE6, 0x22, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x26, 0x01, 0xCE, 0xBE, 0x4A, 0x9C, 0x27), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x6D, 0x11, 0xCA, 0x6C, 0x5A, 0x93, 0x0C), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x96, 0x26, 0xAF, 0x2F, 0xE4, 0x30, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC1, 0x4C, 0xC6, 0x30, 0x1F, 0x5C, 0x04), - MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB3, 0xE8, 0xFC, 0x35, 0xEB, 0x63, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x1D, 0xCA, 0xFC, 0x50, 0x36, 0x4B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0E, 0x23, 0x5B, 0xAF, 0xEB, 0x2D, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x88, 0xB6, 0xD7, 0x74, 0x4A, 0x23, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x66, 0xE2, 0xBB, 0x29, 0xA6, 0x4F, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x6F, 0x7E, 0x68, 0x6E, 0xA0, 0x14, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x73, 0xD4, 0xE8, 0xAB, 0x5B, 0xF6, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xE0, 0x3C, 0x24, 0x00, 0x95, 0xE9, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x0D, 0x4F, 0x81, 0xD0, 0xF2, 0x3F, 0x00), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x1D, 0xCD, 0x78, 0x39, 0xC4, 0x6B, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x45, 0xC7, 0xB8, 0x2F, 0xAA, 0x5D, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x8C, 0x6E, 0xA3, 0x24, 0xB2, 0xDB, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x2D, 0xD9, 0xF1, 0xC7, 0x9B, 0x8A, 0xAF), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xE1, 0x2C, 0xB9, 0x40, 0x37, 0x91, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2C, 0xB5, 0x23, 0x03, 0x2B, 0xAF, 0x2F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x9D, 0x5A, 0x20, 0x10, 0xA9, 0x84, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x30, 0x89, 0x20, 0x13, 0xE9, 0xB2, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x52, 0xEB, 0x03, 0x18, 0x1F, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x9E, 0x1C, 0x35, 0x87, 0x92, 0x69, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xC9, 0x88, 0xAF, 0xC6, 0x6C, 0x83, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD5, 0x7A, 0x54, 0x34, 0x99, 0xB6, 0x6F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xAD, 0x45, 0x9B, 0x4B, 0x41, 0x4D, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x5D, 0xAB, 0x7F, 0x35, 0x34, 0xE9, 0x29), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBE, 0x78, 0x34, 0x44, 0xF3, 0x4A, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xDE, 0xE3, 0xC4, 0xEE, 0x0B, 0xF9, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x86, 0x16, 0x48, 0x32, 0xB8, 0x74, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEE, 0x7C, 0xBA, 0xBD, 0x81, 0xE3, 0x55), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x6A, 0xFA, 0x84, 0xDA, 0xB8, 0xD5, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x9F, 0x8A, 0xD5, 0x1B, 0x2E, 0x1A, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0C, 0x61, 0xE2, 0xFF, 0x5B, 0xE6, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x62, 0xC1, 0x87, 0x53, 0x1B, 0x92, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x90, 0x00, 0xD1, 0x6A, 0x0C, 0x0E, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x2E, 0xB5, 0x3B, 0x44, 0xB5, 0xA0, 0x78), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5D, 0x02, 0x58, 0xB5, 0xBE, 0x45, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xEF, 0x8E, 0x90, 0x4D, 0x2A, 0x32, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x75, 0x5C, 0x0A, 0x33, 0x8F, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x6C, 0x95, 0xD4, 0x1F, 0xF3, 0xEB, 0xDA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xE4, 0x4C, 0x91, 0x20, 0xF3, 0x25, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x95, 0xEB, 0x29, 0x6F, 0x20, 0x34, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x15, 0xE5, 0x13, 0x7E, 0x64, 0x8B, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xBC, 0x0D, 0x18, 0x7E, 0x37, 0x9E, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x82, 0x20, 0xF7, 0x2D, 0x7A, 0x77, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x29, 0xA2, 0xDB, 0x7A, 0xE6, 0x6F, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xC6, 0x50, 0x5C, 0xBC, 0xE6, 0x4F, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x9F, 0xD5, 0xE8, 0xC5, 0x3D, 0xB7, 0x30), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x03, 0x55, 0x10, 0xDB, 0xA6, 0x8B, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x17, 0xAE, 0x78, 0xC9, 0x1D, 0x43, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x35, 0x49, 0xD4, 0x47, 0x84, 0x8D, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x95, 0x2F, 0xEA, 0xBC, 0xB4, 0x18, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x48, 0xAE, 0x89, 0xF5, 0x65, 0x3D, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xF2, 0x2B, 0x20, 0xD1, 0x75, 0x50, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xE6, 0x5C, 0x2C, 0xE0, 0x7D, 0xDF, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x07, 0x3E, 0xCE, 0x9F, 0x18, 0xB6, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xF8, 0xF0, 0xD5, 0xFA, 0x42, 0x1D, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x6C, 0x1D, 0x03, 0xC9, 0x0E, 0x2B, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x52, 0xA5, 0xB4, 0x63, 0xE1, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0xD9, 0xC4, 0xFD, 0x16, 0x60, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x7D, 0xDE, 0xDF, 0x4B, 0x4A, 0xB0, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x4E, 0x8C, 0x94, 0xC1, 0xE2, 0x85, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xF0, 0xEA, 0xB5, 0x9B, 0x70, 0xEF, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xC2, 0x39, 0x5D, 0xF3, 0x2C, 0xD9, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x1C, 0x2E, 0xCC, 0x2F, 0x54, 0x87, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x72, 0xC7, 0xB5, 0x50, 0xA3, 0x84, 0x77), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xD1, 0xAF, 0xA9, 0xB4, 0x8B, 0x5D, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xF6, 0x52, 0x8A, 0xC3, 0x56, 0xA5, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x52, 0xFF, 0xEA, 0x05, 0x42, 0x77, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x08, 0x90, 0x72, 0x86, 0xC4, 0xC3, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x15, 0xF8, 0xF1, 0x16, 0x67, 0xC6, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x87, 0xAC, 0x8F, 0x71, 0xEC, 0x83, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xE1, 0xE6, 0x2D, 0x0E, 0x11, 0xA1, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xE2, 0xA8, 0x32, 0xE6, 0xE3, 0x83, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x56, 0xE5, 0xCD, 0xB7, 0x2B, 0x67, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xED, 0xC9, 0x65, 0x6D, 0x87, 0xE1, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xFD, 0x9A, 0x53, 0x0E, 0xFA, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x4C, 0x4A, 0xE2, 0x23, 0x84, 0xFA, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFE, 0x49, 0x81, 0xD1, 0x3E, 0xF4, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x72, 0xE0, 0xEF, 0x0D, 0xB8, 0x3E, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x00, 0x0F, 0x5F, 0xCE, 0x60, 0x72, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCC, 0xD8, 0x03, 0x07, 0x6E, 0x5A, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x3A, 0x35, 0x50, 0x4E, 0x1F, 0xCA, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xEA, 0x88, 0x55, 0xBD, 0x6E, 0x05, 0x7F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x6D, 0xF1, 0x97, 0xA6, 0x69, 0x39, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x41, 0x99, 0xFF, 0x3B, 0xA1, 0x26, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x2F, 0x95, 0x80, 0x12, 0x4A, 0x1B, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xBF, 0x51, 0xAA, 0xAE, 0x2D, 0xDA, 0xCF), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1C, 0xB3, 0x52, 0x36, 0x49, 0xD4, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC1, 0x1F, 0x3A, 0xD3, 0x3E, 0x5C, 0x1A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x51, 0xF7, 0x2B, 0xC8, 0xA9, 0xA7, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x4E, 0x7F, 0x98, 0x41, 0x66, 0xB0, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x1D, 0xC0, 0x42, 0xCD, 0xF8, 0xC3, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x41, 0x91, 0x7D, 0xCC, 0x8B, 0xCC, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xAE, 0x76, 0xED, 0x56, 0x18, 0xC5, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x6A, 0x06, 0xA3, 0x7F, 0x65, 0x10, 0x1F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xEC, 0x3C, 0x05, 0x05, 0xCA, 0xF6, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0xCD, 0x02, 0x51, 0x12, 0x16, 0x3C, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xEB, 0xB3, 0x43, 0x7B, 0xDD, 0xB2, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x90, 0x41, 0xDB, 0xE4, 0xF5, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0E, 0x18, 0x2A, 0x5A, 0x83, 0x7C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x37, 0xA1, 0x0D, 0xF1, 0x2F, 0x63, 0x79), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC0, 0xFA, 0x6F, 0x1F, 0x67, 0xCF, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x34, 0x45, 0xBB, 0xF4, 0xF9, 0x9B, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x69, 0xFE, 0x67, 0x1D, 0x64, 0x8F, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x39, 0xBF, 0xD8, 0xB3, 0xC7, 0xAD, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x93, 0xFF, 0xF3, 0x28, 0xFA, 0x39, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF9, 0xC3, 0x85, 0x26, 0x7A, 0x88, 0x89), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD5, 0x79, 0xD8, 0x11, 0xDE, 0xEB, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x46, 0xA4, 0x6A, 0xDA, 0x74, 0x34, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBD, 0xD3, 0xF5, 0x14, 0xEE, 0xFE, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4C, 0xA3, 0x71, 0x43, 0x65, 0xF8, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x6C, 0x35, 0xFA, 0x90, 0x25, 0xD8, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x34, 0x84, 0x96, 0xA1, 0x43, 0x03, 0x4D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x3B, 0x3B, 0x2F, 0xCA, 0x59, 0xF2, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x48, 0x24, 0x74, 0xD8, 0x72, 0x90, 0xA3), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x42, 0x74, 0x8C, 0x6F, 0x52, 0x19, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9E, 0x41, 0x63, 0x68, 0x78, 0x4C, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x94, 0xB6, 0x6B, 0x38, 0x52, 0xA8, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x30, 0x25, 0x93, 0xA1, 0x6F, 0x6E, 0x68), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2F, 0x4B, 0x64, 0x79, 0x50, 0xFF, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x36, 0xED, 0x57, 0x39, 0x3B, 0xE7, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x85, 0xEA, 0x35, 0xD6, 0xC0, 0xA0, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x89, 0x3A, 0xCC, 0x22, 0x1C, 0x46, 0x02), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x7A, 0xB0, 0xA1, 0x1B, 0x69, 0x62, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xB8, 0x8A, 0x6C, 0x18, 0x85, 0x0D, 0x88), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB6, 0x50, 0xE9, 0x4E, 0x7F, 0xE8, 0x07), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5B, 0x5C, 0xD1, 0x4B, 0x11, 0x9A, 0xD8), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x25, 0x56, 0x74, 0x51, 0x9C, 0xEC, 0x9C), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x7F, 0xB6, 0x8A, 0xCB, 0x3A, 0x10, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x33, 0x07, 0x01, 0xE9, 0x49, 0x59, 0xE6), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xA5, 0x2E, 0xF2, 0xBA, 0x32, 0x63, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x06, 0x0B, 0xA5, 0x44, 0x27, 0x7F, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x74, 0xAC, 0x0F, 0xCC, 0x4F, 0x13, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB1, 0xBF, 0x97, 0x49, 0xA5, 0x1C, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x64, 0x68, 0x7B, 0x0F, 0xCC, 0x77, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x39, 0xF9, 0x4E, 0x84, 0x9C, 0xF6, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xCF, 0x6D, 0xE2, 0xA1, 0x2D, 0xF9, 0x2B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC4, 0x90, 0x57, 0x31, 0x01, 0x05, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x1E, 0xBB, 0xBF, 0x98, 0xA4, 0x7C, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xE3, 0xA0, 0xB2, 0xCD, 0x39, 0x9A, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x34, 0x60, 0x7A, 0x89, 0x98, 0xB5, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x20, 0x3D, 0x3A, 0x04, 0x8F, 0x5A, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x26, 0xB6, 0x49, 0x09, 0x9C, 0x0F, 0x59), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x66, 0xD2, 0x38, 0x2A, 0x62, 0x81, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xC8, 0x20, 0x5E, 0x28, 0xA3, 0x81, 0xA7), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x31, 0xA4, 0xF1, 0xEA, 0x7D, 0x87, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x2C, 0x99, 0x09, 0x6F, 0x63, 0xEB, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x76, 0xDA, 0x1A, 0x06, 0xBE, 0xDE, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x09, 0x2E, 0x75, 0x39, 0x30, 0x2D, 0x42), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x9B, 0xC1, 0x5A, 0x17, 0xC3, 0x8C, 0x31), - MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x8D, 0x94, 0x4D, 0x3D, 0xAB, 0x60, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFD, 0x1E, 0x0F, 0x43, 0xAE, 0x9D, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF2, 0xF3, 0x20, 0x1B, 0xAA, 0xB7, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x5B, 0xA4, 0xF4, 0x90, 0x3B, 0xE3, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x78, 0x72, 0xBD, 0x65, 0x09, 0x0B, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x37, 0x2A, 0x6C, 0x16, 0x4F, 0x64, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xCE, 0xA3, 0x90, 0xB4, 0x9A, 0xBC, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x55, 0x63, 0x1D, 0x3A, 0x6E, 0x18), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xB4, 0xAA, 0x99, 0x22, 0x45, 0x89, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x7C, 0x8C, 0xA6, 0x3D, 0xA7, 0x3E, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x06, 0x42, 0xDC, 0xA6, 0xE3, 0xC6, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8C, 0x3D, 0x5D, 0x47, 0x31, 0x7C, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x85, 0xEE, 0x46, 0x7E, 0x13, 0x04, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x3C, 0x8B, 0x43, 0x2E, 0x74, 0xF5, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x88, 0x8E, 0x07, 0x29, 0x08, 0x03, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x9B, 0x89, 0xEB, 0x08, 0xE8, 0x43, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x07, 0x67, 0xFD, 0xD9, 0x73, 0x6F, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xEB, 0x21, 0x8D, 0x98, 0x43, 0x74, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xCC, 0x14, 0xD8, 0x08, 0xBB, 0xA6, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x98, 0xF2, 0x6A, 0x18, 0xC3, 0xDD, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x38, 0x91, 0xA0, 0x03, 0xF2, 0x04, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xAF, 0xE8, 0xFD, 0xFB, 0x13, 0x70, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x93, 0x87, 0x98, 0x4A, 0xE0, 0x00, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x2E, 0x69, 0x9C, 0xA2, 0x2D, 0x03, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFE, 0xF3, 0xB9, 0xC1, 0x85, 0x2A, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xFD, 0x86, 0xB1, 0xCD, 0xBF, 0x41, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xD8, 0x9A, 0x21, 0xF3, 0xFE, 0xCB, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x78, 0x04, 0x60, 0xB7, 0xA9, 0xA2, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1E, 0x66, 0x2A, 0x54, 0x51, 0xBD, 0x8B), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x16, 0x36, 0xEF, 0x61, 0x2D, 0xEE, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x5F, 0x88, 0xA0, 0x13, 0x12, 0xF7, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xC6, 0xAD, 0x4A, 0x4A, 0x07, 0x01, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x74, 0xB1, 0x4F, 0xEB, 0xBD, 0xD5, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF9, 0x71, 0xA2, 0x06, 0x4F, 0xD7, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x8B, 0x4D, 0x48, 0xE0, 0x98, 0xFB, 0x6A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xBA, 0x10, 0xA3, 0x0D, 0x52, 0xAC, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xD0, 0xE0, 0x36, 0xE6, 0x07, 0x3A, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x80, 0xF0, 0xAA, 0x49, 0x22, 0x4B, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC7, 0xAB, 0x1C, 0x89, 0xCD, 0x24, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x2A, 0xFC, 0xB3, 0x6D, 0x45, 0x96, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xE4, 0xDB, 0x52, 0x3F, 0xC4, 0xB4, 0x19), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xCC, 0xC8, 0x7F, 0xBB, 0x6B, 0x87, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x21, 0x3C, 0x69, 0x7D, 0x38, 0x57, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x4C, 0x18, 0x3C, 0x53, 0xA5, 0x48, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC3, 0x64, 0x45, 0xDB, 0xC4, 0x6D, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCC, 0xD1, 0xBB, 0x17, 0xB8, 0x34, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x69, 0x71, 0xFA, 0xA0, 0x28, 0x4A, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xE8, 0x9E, 0x39, 0xEA, 0x8D, 0x38, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x9C, 0xBB, 0xCD, 0x80, 0x1A, 0xEE, 0xB7), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA0, 0x45, 0xBF, 0xD9, 0x22, 0x11, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7C, 0x5C, 0xD9, 0xC0, 0x9F, 0x69, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x8A, 0xA6, 0x79, 0x4E, 0x35, 0xB9, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8B, 0x9A, 0x3E, 0xA1, 0xB8, 0x28, 0x10), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x2F, 0xEF, 0xBB, 0xA9, 0x72, 0x7F, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x34, 0xB7, 0x12, 0xB9, 0xE7, 0xC3, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x1D, 0xD9, 0x42, 0x77, 0x0C, 0x71, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x01, 0x59, 0xA7, 0x56, 0x03, 0x91, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x91, 0x99, 0x33, 0x30, 0x3E, 0xEF, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xC9, 0x5A, 0x9A, 0x54, 0x66, 0xF1, 0x70), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x2C, 0xB7, 0x6E, 0x71, 0x7D, 0x35, 0x30), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x0D, 0xEF, 0xD1, 0x2D, 0x99, 0x63, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x31, 0xAF, 0x2D, 0xC9, 0xC6, 0xC2, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xC0, 0xDF, 0x80, 0x54, 0xC4, 0xAC, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x6B, 0xA0, 0x84, 0x96, 0xF7, 0x31, 0xC8), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xE2, 0x7C, 0x7A, 0x41, 0x45, 0x75, 0x6A), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xEE, 0x58, 0x31, 0xE8, 0x68, 0xD6, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x2E, 0x48, 0xB7, 0x09, 0x9F, 0xD4, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA9, 0x5C, 0xE7, 0x64, 0x43, 0x5D, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x9F, 0x50, 0xAB, 0x68, 0xFF, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x88, 0x2D, 0xBA, 0x12, 0xBF, 0x8D, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xDF, 0x6F, 0xB3, 0x75, 0xA4, 0x55, 0x73), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x17, 0x92, 0x39, 0xB7, 0x13, 0x37, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x43, 0x71, 0xA7, 0xCA, 0x17, 0x1B, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xB9, 0xB0, 0x78, 0xEF, 0xA0, 0xDA, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0xF2, 0x0F, 0x85, 0xA2, 0xB6, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x65, 0x2E, 0x6E, 0x45, 0xB9, 0x4C, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x6A, 0x8C, 0x2B, 0x77, 0x96, 0x36, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x7A, 0x13, 0x4A, 0x97, 0x63, 0x02, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x1E, 0x06, 0x03, 0x8F, 0xB9, 0xEE, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0xEE, 0x8B, 0x89, 0xA9, 0x70, 0xDB, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x81, 0xC9, 0x70, 0x8D, 0x62, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xDA, 0x46, 0xF8, 0xF9, 0x3A, 0xBE, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x9C, 0x7A, 0x97, 0x62, 0xEB, 0xFA, 0x0F), -}; -static const mbedtls_mpi_uint brainpoolP384r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x03, 0x3D, 0x3C, 0x46, 0x27, 0x9E, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x08, 0x1C, 0xD5, 0x25, 0xAF, 0xE9, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x69, 0xDC, 0x59, 0xF4, 0x8A, 0x7C, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x9A, 0x7A, 0x99, 0x21, 0x0C, 0x4E, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xCE, 0x85, 0x5F, 0xAC, 0xAA, 0x82, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x57, 0x69, 0x90, 0x76, 0xF3, 0x53, 0x3F), -}; -static const mbedtls_ecp_point brainpoolP384r1_T[32] = { - ECP_POINT_INIT_XY_Z1(brainpoolP384r1_T_0_X, brainpoolP384r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_1_X, brainpoolP384r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_2_X, brainpoolP384r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_3_X, brainpoolP384r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_4_X, brainpoolP384r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_5_X, brainpoolP384r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_6_X, brainpoolP384r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_7_X, brainpoolP384r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_8_X, brainpoolP384r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_9_X, brainpoolP384r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_10_X, brainpoolP384r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_11_X, brainpoolP384r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_12_X, brainpoolP384r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_13_X, brainpoolP384r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_14_X, brainpoolP384r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_15_X, brainpoolP384r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_16_X, brainpoolP384r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_17_X, brainpoolP384r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_18_X, brainpoolP384r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_19_X, brainpoolP384r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_20_X, brainpoolP384r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_21_X, brainpoolP384r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_22_X, brainpoolP384r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_23_X, brainpoolP384r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_24_X, brainpoolP384r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_25_X, brainpoolP384r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_26_X, brainpoolP384r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_27_X, brainpoolP384r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_28_X, brainpoolP384r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_29_X, brainpoolP384r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_30_X, brainpoolP384r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_31_X, brainpoolP384r1_T_31_Y), -}; -#else -#define brainpoolP384r1_T NULL -#endif - -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -/* - * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) - */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) -static const mbedtls_mpi_uint brainpoolP512r1_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), -}; -static const mbedtls_mpi_uint brainpoolP512r1_a[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78), -}; -static const mbedtls_mpi_uint brainpoolP512r1_b[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), -}; - -#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 -static const mbedtls_mpi_uint brainpoolP512r1_T_0_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_0_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_1_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xE9, 0x6B, 0x8C, 0x6F, 0x9D, 0x88, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x4F, 0x86, 0x96, 0xA7, 0x56, 0xD1, 0x37), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xAB, 0xFA, 0xEE, 0xA7, 0xF5, 0x0E, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x40, 0xEF, 0x9E, 0x6D, 0xD6, 0x32, 0x33), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xED, 0x56, 0x14, 0x57, 0x1A, 0x8D, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xED, 0x4D, 0x3A, 0xFA, 0x71, 0x75, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xC5, 0x76, 0x1C, 0x14, 0xBE, 0xB5, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x5A, 0xCB, 0xE7, 0x36, 0x1D, 0x52, 0x1C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_1_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8D, 0x7A, 0xEB, 0xA3, 0x8B, 0xD5, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xA3, 0x41, 0xF8, 0xAC, 0x9E, 0xAB, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xE3, 0x65, 0x0D, 0x1C, 0xFE, 0x09, 0x2B), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xCA, 0x13, 0x3F, 0xC5, 0xF9, 0x7E, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x5D, 0x63, 0x28, 0xA6, 0x89, 0xD3, 0x91), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x95, 0x3F, 0x7A, 0x82, 0xD4, 0x77, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xBB, 0x92, 0x32, 0x00, 0xF4, 0x66, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x58, 0x31, 0xD1, 0x17, 0x9F, 0x2A, 0x22), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_2_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x36, 0xA9, 0xCD, 0x80, 0xA5, 0x2D, 0x78), - MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x44, 0xAB, 0xCE, 0x71, 0xFF, 0x0C, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x24, 0x58, 0x35, 0x5A, 0x21, 0x32, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xA6, 0x28, 0xF8, 0x7A, 0x97, 0xAE, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xE7, 0x08, 0xFA, 0x47, 0xC9, 0x55, 0x09), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xAC, 0x2E, 0x84, 0xA4, 0xF5, 0x52, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x58, 0x05, 0x9D, 0xA7, 0xC8, 0x71, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x92, 0xB4, 0x92, 0xC1, 0x92, 0xEC, 0x6B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_2_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x48, 0x2D, 0x79, 0x5E, 0x58, 0xE5, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x85, 0x26, 0xEC, 0xE9, 0x6E, 0xD4, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x68, 0x26, 0x87, 0x38, 0xA2, 0xD2, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x17, 0x60, 0xCE, 0x75, 0xF8, 0xA5, 0x6F), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x51, 0xDB, 0xA9, 0xAE, 0x87, 0xF1, 0x15), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x49, 0x92, 0x3B, 0x19, 0x96, 0xF5, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xD5, 0x52, 0x52, 0x8C, 0xCE, 0xFD, 0xFA), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x18, 0x0A, 0xE6, 0xF6, 0xAE, 0x08, 0x41), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_3_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x2B, 0xD8, 0x54, 0xCE, 0xB0, 0x57, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xB0, 0xF8, 0x9E, 0x03, 0x03, 0x3C, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x0E, 0x29, 0x29, 0x00, 0xF3, 0x70, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x33, 0x99, 0x0E, 0x00, 0x5D, 0xFE, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2D, 0xF2, 0x59, 0x32, 0xCF, 0x03, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xC9, 0x72, 0xAE, 0x0C, 0xEF, 0xD1, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x5A, 0x27, 0xBF, 0x2F, 0x45, 0xF9, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xBE, 0xE5, 0x2C, 0xFF, 0x5B, 0x1E, 0x88), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_3_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xAC, 0xBB, 0xD8, 0x83, 0xC2, 0x46, 0xF6), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xDC, 0xCE, 0x15, 0xB4, 0xEF, 0xCF, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xDB, 0x5E, 0x94, 0x31, 0x0B, 0xB2, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xB9, 0xE3, 0xE3, 0x11, 0x71, 0x41, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xE3, 0x01, 0xB7, 0x7D, 0xBC, 0x65, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x07, 0x65, 0x87, 0xA7, 0xE8, 0x48, 0xE3), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x48, 0x8F, 0xD4, 0x30, 0x8E, 0xB4, 0x6C), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE0, 0x73, 0xBE, 0x1E, 0xBF, 0x56, 0x36), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_4_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x0E, 0x5E, 0x87, 0xC5, 0xAB, 0x0E, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xF9, 0x5F, 0x80, 0x24, 0x4C, 0x2A, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x15, 0x21, 0x54, 0x92, 0x84, 0x8D, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x8A, 0x47, 0x74, 0xDC, 0x42, 0xB1, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xF7, 0x30, 0xFD, 0xC1, 0x9B, 0x0C, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x6C, 0xCC, 0xDF, 0xC5, 0xE3, 0xA9, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x67, 0x59, 0x10, 0x5C, 0x51, 0x54, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x37, 0xFB, 0x6E, 0xB0, 0x78, 0x63, 0x8E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_4_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEF, 0xC4, 0x39, 0x20, 0xF1, 0x46, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x62, 0xAE, 0xFF, 0x10, 0xE4, 0xE2, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x5C, 0xF5, 0x2E, 0x22, 0x89, 0xE5, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x0C, 0x29, 0xA8, 0x62, 0xAE, 0xDB, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x9E, 0x0F, 0xCA, 0x87, 0x2A, 0x6F, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xDC, 0x9B, 0x9F, 0x65, 0xD4, 0xAD, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xC3, 0x08, 0x0F, 0xCF, 0x67, 0xE9, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5C, 0xD7, 0xFF, 0x41, 0x9C, 0xCB, 0x26), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_5_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x05, 0x12, 0xAD, 0x73, 0x63, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x99, 0x07, 0x86, 0x57, 0xE7, 0x94, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x4B, 0xA5, 0xBF, 0x18, 0xA9, 0xEF, 0x6A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x4C, 0xC4, 0x09, 0xF2, 0x2F, 0x0C, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x3A, 0x04, 0xEA, 0x89, 0x6C, 0x91, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0x3A, 0xE7, 0xA3, 0xEC, 0x24, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xA1, 0x26, 0x21, 0x04, 0xE3, 0xB9, 0x40), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x71, 0x4B, 0x7B, 0xC2, 0x89, 0xCD, 0xA2), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_5_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xB9, 0xA8, 0x9D, 0xFD, 0x00, 0x3A, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x41, 0x6C, 0xBB, 0x5A, 0xCA, 0x1F, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xD7, 0xE2, 0x6C, 0x6B, 0xA7, 0x48, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x19, 0xAD, 0xA7, 0xC1, 0x7E, 0x4F, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF7, 0x19, 0x3C, 0x06, 0x74, 0x2C, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x23, 0x4F, 0x0C, 0x09, 0xB0, 0x80, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x74, 0x34, 0x08, 0x44, 0x7E, 0xA3, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xCC, 0x8D, 0x12, 0x6E, 0xE1, 0x3D, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_6_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x18, 0xB1, 0x71, 0x02, 0x93, 0xC2, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x89, 0x40, 0xE2, 0x1F, 0xE7, 0x5E, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xAE, 0x89, 0x01, 0xD4, 0x0C, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xDA, 0x58, 0x70, 0x24, 0xF2, 0xE4, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xC7, 0x1D, 0xD6, 0x4A, 0x6F, 0x66, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x1D, 0x7E, 0x4A, 0x2C, 0xCA, 0xEC, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x7F, 0xA8, 0x99, 0xE4, 0xD3, 0x4E), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x1D, 0x5A, 0xDF, 0x5E, 0x58, 0x36, 0x49), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_6_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB9, 0x32, 0x69, 0x1F, 0x72, 0x2A, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x73, 0xE2, 0x03, 0x39, 0x35, 0xAA, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x5E, 0x5D, 0x48, 0xEF, 0xAE, 0x30, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x7F, 0x60, 0x19, 0xAF, 0xEC, 0x9D, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x19, 0xE4, 0x1B, 0x56, 0x15, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xD7, 0x33, 0x59, 0x1F, 0x43, 0x59, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xCE, 0xEE, 0xCA, 0xA4, 0x7F, 0x63, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x40, 0xC0, 0xF6, 0x19, 0x89, 0x43, 0x20), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_7_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x92, 0xEA, 0x07, 0x65, 0x79, 0x86, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xB7, 0x13, 0x75, 0xD3, 0xC5, 0x0A, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x9E, 0xFA, 0xE1, 0x1F, 0x0C, 0xF9, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x8C, 0xED, 0x5C, 0x21, 0xE9, 0x09, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x4D, 0xD8, 0x18, 0xC4, 0xF6, 0x36, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xC9, 0xAC, 0x5C, 0xFA, 0x69, 0xA4, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8C, 0x94, 0x1C, 0x7B, 0x71, 0x36, 0x58), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBD, 0x46, 0xCE, 0xB7, 0x1D, 0x9C, 0x5E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_7_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD6, 0x96, 0x4B, 0xA6, 0x47, 0xEB, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xF1, 0x5F, 0x15, 0xDE, 0x99, 0x6F, 0x66), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xBD, 0xE5, 0x04, 0xB8, 0xE6, 0xC0, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD3, 0xF0, 0x04, 0x00, 0xE4, 0x05, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xF3, 0x06, 0xA3, 0x1A, 0xFF, 0xEA, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x32, 0xAA, 0x99, 0x33, 0x09, 0xB6, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xEF, 0xFC, 0x61, 0x10, 0x42, 0x31, 0x94), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF1, 0xF4, 0x33, 0xCF, 0x28, 0x90, 0x9C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_8_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xDE, 0xF9, 0x88, 0x87, 0x7B, 0xEB, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xB8, 0xDA, 0xFA, 0xDA, 0x3D, 0xA6, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF0, 0x62, 0x82, 0x53, 0x32, 0x55, 0x03), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA5, 0x32, 0x4A, 0x19, 0x11, 0x9C, 0x10), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xB3, 0x27, 0xE9, 0x75, 0x90, 0x05, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x1C, 0x90, 0x48, 0x77, 0x01, 0x85, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD6, 0x9B, 0x84, 0xA8, 0xD7, 0xC5, 0x28), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x7A, 0xCB, 0xB3, 0x11, 0x46, 0xD7, 0x99), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_8_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x23, 0xBF, 0x75, 0x75, 0xA1, 0x95, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x66, 0x5D, 0x34, 0x13, 0xA9, 0x03, 0xBE), - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x80, 0x9D, 0x5F, 0xD2, 0x44, 0xE1, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x5D, 0xBD, 0xA8, 0xBF, 0xB4, 0x25, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x99, 0x1F, 0x53, 0xF1, 0x57, 0xDB, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x7C, 0xE5, 0xC5, 0x51, 0x0B, 0x4C, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xB0, 0x1A, 0x9C, 0x16, 0xB0, 0x32, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xE3, 0xCF, 0xDD, 0x48, 0xB4, 0x7B, 0x33), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_9_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xDD, 0x9E, 0x3C, 0x98, 0x0E, 0x77, 0x65), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xAB, 0x01, 0xD3, 0x87, 0x74, 0x25, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xA3, 0xE3, 0x76, 0x43, 0x87, 0x12, 0xBD), - MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0xB1, 0x3B, 0x60, 0x66, 0xEB, 0x98, 0x54), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x78, 0xC8, 0xD7, 0x4E, 0x75, 0xCA, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xDF, 0x71, 0x19, 0xE7, 0x07, 0x36, 0xB5), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC9, 0xA8, 0x5F, 0x91, 0xBF, 0x47, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x96, 0x58, 0x96, 0x18, 0xB6, 0xFA, 0x01), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_9_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x2D, 0xA9, 0x9B, 0x86, 0xDB, 0x0C, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0B, 0x2D, 0x56, 0x4A, 0xD3, 0x93, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x15, 0xE2, 0x65, 0x12, 0x86, 0x0E, 0xB2), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x41, 0x4D, 0xC1, 0xCB, 0xE4, 0xC3, 0xD7), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x53, 0x10, 0xCA, 0xA3, 0xAC, 0x83, 0x26), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x01, 0x22, 0x96, 0x10, 0xAD, 0x69, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x46, 0x4E, 0xD8, 0xEA, 0xD6, 0x9D, 0xF3), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x2F, 0x7F, 0x62, 0x62, 0x80, 0xD0, 0x14), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_10_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xDA, 0x00, 0x63, 0x09, 0xBD, 0x6A, 0x83), - MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD4, 0x6E, 0x48, 0x05, 0xB7, 0xF7, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x4D, 0xD7, 0x00, 0x4A, 0x15, 0x27, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x15, 0xAA, 0x37, 0x27, 0x34, 0x18, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x20, 0x2C, 0x84, 0x1B, 0x88, 0xBA, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x09, 0xD6, 0x04, 0xA2, 0x60, 0x84, 0x72), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x04, 0x94, 0x08, 0xD4, 0xED, 0x47, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xF3, 0xE4, 0x3E, 0xB9, 0x5B, 0x35, 0x42), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_10_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xD8, 0xB6, 0x80, 0xD6, 0xF1, 0x30, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x14, 0xA6, 0x85, 0xEE, 0xA7, 0xD8, 0x61), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x49, 0x2A, 0x1E, 0x7C, 0xE9, 0x2D, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x87, 0x56, 0x91, 0x03, 0x77, 0x4D, 0x55), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x52, 0xD4, 0xAA, 0xF7, 0xFA, 0xB0, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x11, 0x39, 0xB1, 0xE7, 0x76, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x13, 0xBC, 0x37, 0x5D, 0x74, 0xCD, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x48, 0x14, 0x23, 0x30, 0xF8, 0x46, 0x37), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_11_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x27, 0xB0, 0xD9, 0xB2, 0x74, 0xB4, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xA6, 0xB9, 0x6F, 0x9F, 0x64, 0x36, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x2B, 0x78, 0x40, 0x05, 0x2B, 0x7B, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x68, 0x3A, 0xB6, 0x4A, 0xE2, 0xDB, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x33, 0xD7, 0x34, 0x8B, 0x25, 0x45, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xCE, 0xA8, 0xC9, 0x01, 0xFB, 0x0E, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF9, 0x51, 0x4C, 0x12, 0x9F, 0x60, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x85, 0xBD, 0x30, 0x37, 0x84, 0x39, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_11_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x33, 0xAF, 0x2E, 0xB8, 0x2E, 0xCC, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xB1, 0x73, 0x59, 0x4E, 0x0C, 0x09, 0x4A), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x24, 0x89, 0x81, 0x12, 0xFF, 0xBB, 0x6E), - MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0x1A, 0x66, 0xEE, 0xED, 0xB6, 0x9B), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xBD, 0x04, 0x20, 0x5D, 0xFB, 0xBF, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF8, 0x34, 0xA3, 0xFF, 0x45, 0xDE, 0x92), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x18, 0x73, 0xF1, 0x32, 0x25, 0x58, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xC1, 0x14, 0xE3, 0x9E, 0x40, 0x0F, 0x12), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_12_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0x9D, 0x9C, 0x00, 0xF7, 0x56, 0x19), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBA, 0x87, 0xF9, 0x15, 0x0C, 0x66, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x1F, 0xC1, 0x28, 0xB0, 0x47, 0x0D, 0xF5), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xCA, 0x27, 0xEE, 0x4B, 0x23, 0x2B, 0x89), - MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB5, 0x68, 0xC8, 0x17, 0x5D, 0xC3, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x02, 0x08, 0xEE, 0x20, 0x9D, 0xEA, 0x64), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x14, 0x50, 0xD4, 0x7D, 0x5F, 0xCF, 0xA0), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFA, 0xF8, 0xA7, 0xC6, 0xDC, 0x14, 0x8C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_12_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xBD, 0x0A, 0x1A, 0x18, 0x98, 0xDC, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x63, 0x02, 0xB7, 0xD5, 0x5B, 0x5A, 0xC6), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB1, 0xD7, 0x4B, 0x15, 0x39, 0x61, 0x5D), - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x32, 0xE1, 0x9E, 0x70, 0x1B, 0xCE, 0x51), - MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD8, 0x18, 0x83, 0x52, 0x9B, 0x6D, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x55, 0x56, 0x19, 0x34, 0xA4, 0xEA, 0xFC), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA9, 0x55, 0x80, 0xE3, 0x15, 0x36, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x06, 0xC8, 0x1D, 0x17, 0x0D, 0xAD, 0x16), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_13_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xD6, 0xF0, 0xCC, 0xF3, 0x63, 0x53, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x5A, 0xDC, 0x46, 0xBD, 0x0D, 0xAD, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x2F, 0x11, 0x60, 0x15, 0x51, 0x4A, 0xEA), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE3, 0x93, 0x38, 0xD5, 0x83, 0xAA, 0x0D), - MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA6, 0xCC, 0xB1, 0xFD, 0xBB, 0x1A, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x54, 0xC8, 0x54, 0x6F, 0x79, 0x1A, 0x59), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4A, 0xDA, 0x28, 0x92, 0x97, 0x9D, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x4B, 0xDB, 0xC7, 0x52, 0xC5, 0x66, 0x34), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_13_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7E, 0x92, 0x53, 0x30, 0x93, 0xFD, 0xFF), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0x6A, 0xB1, 0x91, 0x0A, 0xB4, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x9D, 0x40, 0x3F, 0xE3, 0xF1, 0x01, 0x46), - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x0E, 0xD8, 0xED, 0x11, 0x8E, 0x4C, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x4A, 0x1B, 0x88, 0xDF, 0x8D, 0x29, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x23, 0x21, 0x11, 0xAB, 0x77, 0x81, 0x62), - MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xAF, 0x11, 0xFA, 0xBA, 0x40, 0x63, 0xE7), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x6F, 0x8D, 0x80, 0xDF, 0x67, 0xF5, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_14_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x8B, 0xB7, 0x08, 0xF4, 0xD7, 0x2D, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x2B, 0x30, 0x02, 0x45, 0x71, 0x08, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x3A, 0xCA, 0x50, 0xF6, 0xC2, 0x19, 0x8C), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xB9, 0x9B, 0x3E, 0x73, 0x95, 0x1D, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x60, 0x59, 0x48, 0xCB, 0xD8, 0xD6, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x6C, 0x89, 0xAB, 0x99, 0xA8, 0xF8), - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xA1, 0x8B, 0x4E, 0x06, 0x19, 0xEC, 0x99), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x95, 0x04, 0xCF, 0xD5, 0x94, 0xB3, 0x02), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_14_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x35, 0x93, 0x7C, 0xB3, 0xB8, 0x9E, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x45, 0x5C, 0x7E, 0xBF, 0x75, 0x81, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE8, 0x24, 0xDF, 0xEC, 0x2F, 0x7D, 0xB9), - MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x8B, 0xD5, 0x6A, 0x9B, 0xA0, 0xE0, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE3, 0x27, 0x82, 0xDE, 0xDD, 0xCA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x57, 0x56, 0x46, 0x05, 0x06, 0x01, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x35, 0xA7, 0x47, 0xE2, 0x6B, 0x2C, 0x4F), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x9D, 0x4C, 0xEC, 0x1F, 0x11, 0x75, 0x2B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_15_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xAA, 0x41, 0xC1, 0xE9, 0x0E, 0xE9, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xCF, 0x9C, 0x4B, 0xE8, 0xED, 0x0A, 0x49), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x73, 0xCA, 0x0C, 0x46, 0x0A, 0x9C, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE1, 0x9E, 0xBC, 0xFE, 0x44, 0x63, 0x6D), - MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x43, 0x71, 0xEE, 0xF8, 0xC1, 0x8C, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x4B, 0xF0, 0x69, 0x25, 0xBD, 0x71, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x9A, 0xFE, 0x82, 0xE7, 0xC1, 0xC1, 0xEE), - MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x5A, 0x6E, 0x5E, 0x97, 0x6A, 0x35, 0x8D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_15_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x18, 0x6C, 0x7E, 0xB8, 0x9E, 0x57, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xB9, 0xC1, 0xD0, 0xFE, 0x78, 0xFB, 0x32), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x08, 0xAE, 0x46, 0x34, 0xEA, 0x7A, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1C, 0x56, 0xA9, 0x18, 0x37, 0xD4, 0x9E), - MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x63, 0xE9, 0x0A, 0xB6, 0x38, 0x3C, 0xC1), - MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x4F, 0xA4, 0x6E, 0x85, 0x31, 0x23, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xAD, 0xC4, 0xC3, 0xB1, 0x4B, 0x1C, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x56, 0x4A, 0x38, 0xB3, 0x6B, 0x6F, 0x2C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_16_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xC7, 0x19, 0xDE, 0x21, 0xED, 0x89, 0xD0), - MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xBE, 0xA6, 0xAE, 0xEB, 0x9D, 0xA7, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x0E, 0x13, 0x1E, 0x86, 0x57, 0xC3, 0x3B), - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4B, 0x30, 0x46, 0x52, 0xC1, 0xEC, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xD5, 0x44, 0x31, 0x96, 0x3B, 0x26, 0x27), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x68, 0xA8, 0x67, 0x78, 0x39, 0xE8, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x78, 0xB7, 0xDD, 0xF2, 0x58, 0xB6, 0x3D), - MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x3C, 0xB3, 0x26, 0xC4, 0x2C, 0x8C, 0xA5), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_16_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x24, 0xE5, 0x73, 0xEE, 0x9A, 0x02, 0xA9), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x6A, 0x65, 0x60, 0xF3, 0x62, 0xE3, 0xE9), - MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x07, 0x84, 0xE6, 0x3B, 0x46, 0x65, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x8F, 0x0C, 0xB0, 0xE1, 0x04, 0x82, 0x9D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x13, 0xBF, 0x3D, 0xA0, 0x48, 0xA2, 0x74), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x26, 0x76, 0x74, 0xAB, 0x0B, 0x29, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x6E, 0x5F, 0x03, 0x34, 0x7C, 0x38, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x72, 0xF9, 0x3B, 0x3C, 0xA4, 0xBC, 0x7C), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_17_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xCE, 0x18, 0x80, 0xB8, 0x24, 0x45, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x09, 0x03, 0xB8, 0x06, 0x64, 0xF7, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x26, 0xB1, 0x10, 0x6D, 0x71, 0x12, 0x2E), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x12, 0xC6, 0x6E, 0x1E, 0x6A, 0xC3, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xD3, 0x0A, 0xDE, 0xD8, 0x6B, 0x04, 0x5C), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x87, 0x5B, 0xAE, 0xDB, 0x3C, 0xC0, 0xC5), - MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF5, 0xF9, 0xC1, 0x9A, 0x89, 0xBB, 0x7E), - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x69, 0x72, 0x8B, 0xAE, 0x32, 0x13, 0x11), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_17_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x16, 0x07, 0x50, 0xFA, 0x4C, 0xCF, 0xE8), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x50, 0x21, 0xE9, 0xDE, 0xEC, 0x7E, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x2F, 0xE8, 0x83, 0x30, 0x0B, 0x65, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x0B, 0x99, 0xAC, 0xC9, 0xBA, 0x6C, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x59, 0x5A, 0x0D, 0x7B, 0x9E, 0x08, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x91, 0xB2, 0xDC, 0x90, 0xCE, 0x67, 0xED), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x93, 0x60, 0x0C, 0xD7, 0x1F, 0x2F, 0x17), - MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7F, 0x9D, 0x40, 0xF8, 0x78, 0x7A, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_18_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x22, 0x95, 0xE8, 0xEF, 0x31, 0x57, 0x35), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x88, 0x53, 0xFE, 0xAF, 0x7C, 0x47, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xCE, 0xCC, 0x79, 0xE8, 0x9F, 0x8C, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x16, 0xDD, 0x77, 0x6E, 0x8A, 0x73, 0x97), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x07, 0x97, 0x21, 0x3B, 0xF8, 0x5F, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xB5, 0xD2, 0x81, 0x84, 0xF0, 0xE7, 0x9F), - MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x8F, 0x75, 0x09, 0x6A, 0x0E, 0x53, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x4F, 0x70, 0x97, 0xC7, 0xAC, 0x7D, 0x3F), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_18_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x3C, 0x6A, 0xB4, 0x10, 0xA9, 0xC8, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC5, 0xD6, 0x69, 0x16, 0xB8, 0xAC, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x44, 0xDC, 0xEB, 0x48, 0x54, 0x5D, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x48, 0x9B, 0xD7, 0x72, 0x69, 0xA4, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x0D, 0x36, 0x9A, 0x66, 0x0B, 0xEC, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC6, 0xD4, 0xB6, 0x60, 0xE5, 0xC3, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x29, 0x42, 0xE0, 0x9D, 0xFD, 0x7C, 0x3E), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x10, 0xBA, 0x55, 0xBC, 0x3B, 0x38, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_19_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x66, 0xFA, 0x05, 0x73, 0x03, 0x1B, 0x69), - MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xA4, 0x66, 0x12, 0x96, 0x7B, 0x02, 0x4C), - MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xDE, 0x6D, 0x98, 0xD1, 0xD5, 0xA8), - MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF5, 0x44, 0xB8, 0x8E, 0xF6, 0x8C, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x15, 0x2B, 0x72, 0xBC, 0x49, 0xE5, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x44, 0xD7, 0xDF, 0x8F, 0xEB, 0x8D, 0x80), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x64, 0x88, 0xAA, 0xB7, 0xE4, 0x70, 0x1D), - MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x14, 0xBB, 0xE9, 0x9B, 0xB9, 0x65, 0x5D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_19_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x8E, 0x88, 0xF5, 0xF1, 0xC1, 0x89, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x30, 0x53, 0xE6, 0xFB, 0x2D, 0x82, 0xB4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE4, 0xFF, 0xBA, 0x31, 0x79, 0xAB, 0xC2), - MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x09, 0xF7, 0xB7, 0x09, 0x78, 0x4C, 0x90), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xAE, 0xC2, 0x44, 0xDC, 0x17, 0x78, 0x47), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD4, 0x17, 0x43, 0x19, 0x74, 0x9E, 0x23), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x64, 0x3B, 0x73, 0xA2, 0x99, 0x27, 0x76), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0x36, 0x5F, 0xD3, 0x14, 0xB1, 0x31), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_20_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x07, 0xAB, 0xFD, 0x9B, 0x03, 0xC5, 0xD5), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xBE, 0xB0, 0x1D, 0xF2, 0x0C, 0x73, 0x73), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE7, 0x7B, 0x87, 0xD3, 0x34, 0xFD, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x25, 0x3D, 0xC7, 0x36, 0x83, 0x53, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x7C, 0xCF, 0x63, 0x55, 0x12, 0x11, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x34, 0x4D, 0x27, 0x92, 0xAC, 0x18, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x42, 0x61, 0x9D, 0x2E, 0xFF, 0x13, 0x16), - MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xDE, 0x92, 0x65, 0x57, 0x0D, 0xBC, 0x0A), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_20_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x7B, 0x6E, 0xC6, 0x2A, 0x21, 0x74, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xA7, 0x53, 0x4D, 0x29, 0x36, 0xEF, 0xE5), - MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xD6, 0x41, 0xC7, 0x99, 0xAD, 0x50, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xAC, 0x41, 0x9F, 0xFB, 0x4C, 0x86, 0xF1), - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xBB, 0xE6, 0x25, 0x28, 0xAA, 0xEB, 0x1E), - MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x04, 0xA2, 0xC3, 0xAA, 0x08, 0x8A, 0xCC), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x2B, 0x5B, 0xE2, 0x8D, 0x76, 0xEA, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x33, 0xD2, 0x21, 0x4D, 0x62, 0xE3, 0x8E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_21_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x06, 0x8B, 0x2B, 0xC2, 0xC4, 0xB1, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF5, 0xA1, 0xC0, 0x03, 0x6A, 0x29, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA9, 0xEF, 0x55, 0xB6, 0x1A, 0x9F, 0x6B), - MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x54, 0x32, 0xBE, 0x06, 0x43, 0xB5, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xD6, 0xD9, 0x20, 0x89, 0xBE, 0xD4, 0x1B), - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x26, 0x95, 0x10, 0xCE, 0xB4, 0x88, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xA6, 0x27, 0xAC, 0x32, 0xBA, 0xBD, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xA6, 0xAE, 0x9C, 0x7B, 0xBE, 0xA1, 0x63), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_21_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xCD, 0x4D, 0x3D, 0xDF, 0x96, 0xBB, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0x11, 0x06, 0xCC, 0x0E, 0x31, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xE4, 0xF4, 0xAD, 0x7B, 0x5F, 0xF1, 0xEF), - MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x54, 0xBE, 0xF4, 0x8A, 0x03, 0x47, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x53, 0x00, 0x7F, 0xB0, 0x8A, 0x68, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0xB1, 0x73, 0x6F, 0x5B, 0x0E, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x32, 0xE3, 0x43, 0x64, 0x75, 0xFB, 0xFB), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x18, 0x55, 0x8A, 0x4E, 0x6E, 0x35, 0x54), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_22_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x97, 0x15, 0x1E, 0xCB, 0xF2, 0x9C, 0xA5), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xD1, 0xBB, 0xF3, 0x70, 0xAD, 0x13, 0xAD), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x96, 0xA4, 0xC5, 0x5E, 0xDA, 0xD5, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x81, 0xE9, 0x65, 0x66, 0x76, 0x47, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x87, 0x06, 0x73, 0xCF, 0x34, 0xD2), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x81, 0x15, 0x42, 0xA2, 0x79, 0x5B, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA2, 0x7D, 0x09, 0x14, 0x64, 0xC6, 0xAE), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x6D, 0xC4, 0xED, 0xF1, 0xD6, 0xE9, 0x24), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_22_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xD5, 0xBB, 0x25, 0xA3, 0xDD, 0xA3, 0x88), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xF2, 0x68, 0x67, 0x39, 0x8F, 0x73, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x76, 0x28, 0x89, 0xAD, 0x32, 0xE0, 0xDF), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x90, 0xCC, 0x57, 0x58, 0xAA, 0xC9, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD7, 0x43, 0xD2, 0xCE, 0x5E, 0xA0, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xB0, 0xB8, 0xA4, 0x9E, 0x96, 0x26, 0x86), - MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x61, 0x1D, 0xF3, 0x65, 0x5E, 0x60, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x1E, 0x65, 0xED, 0xCF, 0x07, 0x60, 0x20), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_23_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x30, 0x17, 0x8A, 0x91, 0x88, 0x0A, 0xA4), - MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7D, 0x18, 0xA4, 0xAC, 0x59, 0xFC, 0x5F), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x31, 0x8B, 0x25, 0x65, 0x39, 0x9A, 0xDC), - MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x16, 0x4B, 0x68, 0xBA, 0x59, 0x13, 0x2F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xD3, 0xC5, 0x56, 0xC9, 0x8C, 0x5E), - MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC6, 0x9F, 0xF4, 0xE6, 0xF7, 0xB4, 0x01), - MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x7C, 0x03, 0x00, 0x26, 0x9F, 0xD8, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x1D, 0x6E, 0x00, 0xB9, 0x00, 0x6E, 0x93), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_23_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x63, 0xDA, 0x03, 0x2B, 0xD5, 0x0B, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xFC, 0xE2, 0xC8, 0x47, 0xF0, 0xAE, 0xF2), - MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x4C, 0xF7, 0x50, 0x0C, 0x48, 0x06, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2B, 0x32, 0x98, 0x0E, 0x7E, 0x61, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x02, 0x27, 0xFE, 0x75, 0x86, 0xDF, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x30, 0xB1, 0x22, 0x32, 0x1B, 0xFE, 0x24), - MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x27, 0xF7, 0x78, 0x6F, 0xD7, 0xFD, 0xE4), - MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x78, 0xCC, 0xEA, 0xC0, 0x50, 0x24, 0x44), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_24_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x2B, 0x4F, 0x7F, 0x58, 0xE6, 0xC2, 0x70), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x43, 0xD5, 0xA7, 0x35, 0x3C, 0x80, 0xB8), - MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x6D, 0x4B, 0x12, 0x00, 0x7B, 0xE6, 0xA6), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x15, 0xBD, 0xD0, 0x9B, 0xCA, 0xAA, 0x81), - MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xCE, 0x9C, 0xE3, 0x8B, 0x60, 0x7A, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xDA, 0x4B, 0x03, 0xA7, 0x8D, 0x43, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAF, 0x00, 0x2B, 0x32, 0xF0, 0x22, 0x68), - MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xD9, 0x99, 0x99, 0xBE, 0x43, 0x99, 0x3E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_24_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x71, 0x41, 0xF4, 0xB5, 0xFD, 0xDD, 0x36), - MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xE2, 0x20, 0x4C, 0xD1, 0x2E, 0x1F, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x43, 0x48, 0x76, 0x8A, 0x49, 0xAC, 0x87), - MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1A, 0x55, 0xA8, 0xA3, 0xD4, 0x57, 0x75), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xA6, 0x84, 0x39, 0xC9, 0x13, 0xBB, 0x60), - MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xFA, 0xA9, 0x70, 0xDE, 0x83, 0xDD, 0xC9), - MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xC9, 0xD9, 0x3E, 0x44, 0x91, 0x68, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x9F, 0x85, 0x6D, 0xF7, 0x54, 0x36, 0x82), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_25_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x6B, 0xA6, 0xA3, 0xE5, 0xD4, 0x46, 0xDB), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x3E, 0xDC, 0x84, 0x7C, 0x7B, 0x24, 0x34), - MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xED, 0x7F, 0x86, 0x07, 0x6C, 0x57, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x06, 0xFE, 0x52, 0x12, 0x79, 0x69, 0x56), - MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xD1, 0x44, 0x5F, 0x21, 0x3A, 0xC3, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD9, 0x4A, 0xC0, 0x75, 0xAB, 0x17, 0xAC), - MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x81, 0x94, 0xB6, 0x80, 0x6B, 0x6F, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBE, 0x8E, 0xA5, 0xAA, 0xBC, 0x1E, 0x3E), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_25_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xC7, 0x85, 0xA6, 0x59, 0x9B, 0xB1, 0x52), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xCE, 0x40, 0xD1, 0xFB, 0xDF, 0x94, 0xF7), - MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xB8, 0x5E, 0xBF, 0x45, 0xA8, 0x2D, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9C, 0x06, 0x1B, 0xA9, 0x57, 0xB9, 0x79), - MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xE9, 0xCE, 0xA2, 0xD3, 0x74, 0xA1, 0x3C), - MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x5F, 0x34, 0x78, 0xDB, 0xAE, 0x3A, 0x14), - MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x32, 0x84, 0x3E, 0x68, 0x6A, 0x43, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xBC, 0x39, 0x36, 0xA4, 0xC5, 0xBB, 0x11), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_26_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x07, 0xA2, 0xB5, 0xC9, 0x0F, 0x4D, 0x0F), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0x67, 0xE6, 0xF1, 0x46, 0xEB, 0x71), - MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x41, 0x23, 0x95, 0xE7, 0xE0, 0x10, 0xDD), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x69, 0xFE, 0x68, 0x8C, 0xC6, 0x5F, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB9, 0x2B, 0x3D, 0xD2, 0x4F, 0xD8, 0x1A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x09, 0xF5, 0x5F, 0xCF, 0xF6, 0x91, 0x57), - MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x15, 0x42, 0x6B, 0x6D, 0xB5, 0xF3, 0xB6), - MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x56, 0x9D, 0xC5, 0xFF, 0xCA, 0x13, 0x9B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_26_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x38, 0xE6, 0x23, 0x63, 0x48, 0x3C, 0xCA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x68, 0x3C, 0xD1, 0x3B, 0xE9, 0x3B, 0x82), - MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x08, 0x54, 0x49, 0xD1, 0x46, 0x45, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x70, 0x52, 0x6E, 0x79, 0xC4, 0x5E, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xDF, 0xE8, 0x5A, 0x32, 0x81, 0xDA, 0xD3), - MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x2D, 0x94, 0x5B, 0xB5, 0x35, 0x9F, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x12, 0x8D, 0xC3, 0x36, 0x36, 0xB2, 0x2A), - MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x2F, 0x22, 0x38, 0x5B, 0x18, 0x4C, 0x35), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_27_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC1, 0x22, 0x0E, 0xF0, 0x73, 0x11, 0x05), - MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xAE, 0xA4, 0x56, 0x18, 0x61, 0x66, 0x12), - MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFB, 0x72, 0x08, 0x84, 0x38, 0x51, 0xB0), - MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x86, 0xA8, 0xB9, 0x31, 0x99, 0x29, 0xC3), - MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xFB, 0xC3, 0x42, 0xB3, 0xC7, 0x6F, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xF8, 0xE1, 0x09, 0xBE, 0x75, 0xB0, 0x22), - MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x7D, 0xFF, 0xF4, 0x99, 0xFC, 0x13, 0xAB), - MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x1B, 0x84, 0x81, 0x42, 0x22, 0xC6, 0x3D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_27_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE0, 0x37, 0xA4, 0xA0, 0x2F, 0x38, 0x7F), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x3D, 0xB7, 0x40, 0x2F, 0x39, 0x3C, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x3B, 0x8A, 0x51, 0xAE, 0x40, 0x49, 0x7A), - MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x20, 0x9F, 0xDD, 0xA9, 0xD0, 0x77, 0xC7), - MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x1D, 0x64, 0xDA, 0xA0, 0x53, 0xC7, 0x7D), - MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x7B, 0x66, 0x55, 0x94, 0xD1, 0x51, 0x44), - MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xB5, 0x5B, 0x38, 0x35, 0x40, 0xC0), - MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0x0F, 0xF0, 0x73, 0x79, 0x43, 0x61), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_28_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x47, 0x45, 0x69, 0x80, 0x72, 0x72, 0x42), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x11, 0x99, 0x59, 0xDB, 0x48, 0x80, 0x39), - MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x6E, 0x3D, 0xFC, 0x37, 0x15, 0xF4, 0xBF), - MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xBB, 0x5B, 0xA6, 0x35, 0x8D, 0x28, 0x20), - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x1A, 0x3B, 0x2C, 0x8F, 0xD3, 0xAA, 0x2D), - MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x1C, 0x1A, 0xF8, 0x02, 0xD9, 0x7B, 0x41), - MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x69, 0xAC, 0xF8, 0x54, 0x31, 0x14, 0xA1), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x8A, 0xE6, 0xDE, 0x58, 0xB9, 0xC4, 0x7A), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_28_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x83, 0x52, 0xFE, 0xF9, 0x7B, 0xE9, 0x1F), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xA2, 0x55, 0x46, 0x15, 0x49, 0xC1, 0x3A), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBC, 0x5C, 0x91, 0xBD, 0xB9, 0x9C, 0xF4), - MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xFD, 0xB1, 0x4E, 0x5F, 0x74, 0xEE, 0x53), - MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x8B, 0xD8, 0x8B, 0x17, 0x73, 0x1B, 0x96), - MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x92, 0xD7, 0x67, 0x06, 0xAD, 0x25, 0xCD), - MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0x80, 0x24, 0xE2, 0x27, 0x5F, 0x8B), - MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x1C, 0xCE, 0xD0, 0x67, 0xCA, 0xD4, 0x0B), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_29_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xF1, 0xDD, 0x33, 0x66, 0xF9, 0x05, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xE5, 0x6B, 0x79, 0xBD, 0x48, 0x42, 0xAA), - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x14, 0x52, 0xE3, 0x53, 0xB4, 0x50, 0xD4), - MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x84, 0x6C, 0xCF, 0xDA, 0xB2, 0x20, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xD6, 0x1A, 0xE5, 0xE2, 0x29, 0x70, 0xCE), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x61, 0xFE, 0xBB, 0x21, 0x82, 0xD1, 0xFE), - MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0xF0, 0x9C, 0x8B, 0x1A, 0x42, 0x30, 0x06), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xD6, 0x49, 0x81, 0x92, 0xF1, 0xD0, 0x90), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_29_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x91, 0x93, 0x6A, 0xA6, 0x22, 0xE9, 0xD6), - MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xDC, 0xC3, 0x69, 0x11, 0x95, 0x7D, 0xEC), - MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xA3, 0x9D, 0x87, 0x5E, 0x64, 0x41, 0xA2), - MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x87, 0x5A, 0x15, 0xBD, 0x6E, 0x3C, 0x8D), - MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x8D, 0x50, 0xCC, 0xCF, 0xB7, 0x8F, 0x0B), - MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x65, 0xCD, 0x31, 0x30, 0xF1, 0x68, 0x13), - MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x5C, 0x66, 0x67, 0x92, 0x30, 0x57, 0x95), - MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x9B, 0x01, 0x3D, 0x20, 0x8B, 0xD1, 0x0D), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_30_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC0, 0xE6, 0x4F, 0xDE, 0x62, 0xAB, 0xB3), - MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x48, 0xB3, 0x1C, 0x0F, 0x16, 0x93, 0x45), - MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x63, 0xBD, 0x1F, 0x16, 0x50, 0x56, 0x98), - MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x06, 0xBC, 0xE9, 0x27, 0x1C, 0x9A, 0x7B), - MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xFE, 0x21, 0xC5, 0x39, 0x55, 0xE1, 0xFD), - MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA8, 0xD0, 0x96, 0x0E, 0xB5, 0xB2, 0x84), - MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xE7, 0x4B, 0xF3, 0x11, 0x0C, 0xC9, 0x5B), - MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x3A, 0xC4, 0x87, 0x71, 0xEE, 0xFA, 0x18), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_30_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x77, 0xEE, 0x81, 0x5E, 0x96, 0xEA, 0x4B), - MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xDF, 0xA9, 0xF4, 0x4F, 0x7C, 0xB2, 0x43), - MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD4, 0xDF, 0x35, 0x63, 0x47, 0x25, 0x8A), - MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3D, 0xFF, 0xA4, 0x02, 0xC3, 0x95, 0x11), - MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x10, 0x78, 0xD1, 0x2B, 0xB7, 0xBE, 0x0E), - MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE9, 0x57, 0xF9, 0xE0, 0xD8, 0xFC, 0xBC), - MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xC4, 0x01, 0xD6, 0xB4, 0xE7, 0x78, 0xE2), - MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6C, 0xB9, 0x13, 0xA4, 0xE8, 0x6D, 0x6F), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_31_X[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xB0, 0xC9, 0xCD, 0xBF, 0xA2, 0x1E, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x4F, 0x86, 0x22, 0x9B, 0xEA, 0xE8, 0xBB), - MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x46, 0xDF, 0x43, 0xB9, 0x82, 0x2D, 0x0A), - MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x32, 0xF1, 0x4E, 0x95, 0x41, 0xAE, 0x8E), - MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x93, 0x26, 0xFC, 0xD3, 0x90, 0xDC, 0xEB), - MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x05, 0x45, 0xCA, 0xF9, 0x5A, 0x89, 0x93), - MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x82, 0x63, 0x4E, 0x55, 0x1D, 0x3A, 0x08), - MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x69, 0x52, 0x49, 0xE9, 0xED, 0x57, 0x34), -}; -static const mbedtls_mpi_uint brainpoolP512r1_T_31_Y[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x64, 0xE9, 0xAC, 0x4C, 0x4A, 0xEA, 0x25), - MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xE9, 0x0B, 0x99, 0xE7, 0xF9, 0xA9, 0x2C), - MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x0C, 0xC1, 0xF4, 0x8D, 0x07, 0xB6, 0xB1), - MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x68, 0xFA, 0x35, 0xE4, 0x9E, 0xAE, 0xD9), - MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2D, 0x1A, 0x13, 0x8E, 0x02, 0xE2, 0x63), - MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x28, 0x86, 0x46, 0x7B, 0x3A, 0xE1), - MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4C, 0x64, 0x59, 0x0A, 0xF9, 0x02, 0xC4), - MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x4F, 0x23, 0xA2, 0xC3, 0xD5, 0xEF, 0x42), -}; -static const mbedtls_ecp_point brainpoolP512r1_T[32] = { - ECP_POINT_INIT_XY_Z1(brainpoolP512r1_T_0_X, brainpoolP512r1_T_0_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_1_X, brainpoolP512r1_T_1_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_2_X, brainpoolP512r1_T_2_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_3_X, brainpoolP512r1_T_3_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_4_X, brainpoolP512r1_T_4_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_5_X, brainpoolP512r1_T_5_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_6_X, brainpoolP512r1_T_6_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_7_X, brainpoolP512r1_T_7_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_8_X, brainpoolP512r1_T_8_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_9_X, brainpoolP512r1_T_9_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_10_X, brainpoolP512r1_T_10_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_11_X, brainpoolP512r1_T_11_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_12_X, brainpoolP512r1_T_12_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_13_X, brainpoolP512r1_T_13_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_14_X, brainpoolP512r1_T_14_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_15_X, brainpoolP512r1_T_15_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_16_X, brainpoolP512r1_T_16_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_17_X, brainpoolP512r1_T_17_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_18_X, brainpoolP512r1_T_18_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_19_X, brainpoolP512r1_T_19_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_20_X, brainpoolP512r1_T_20_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_21_X, brainpoolP512r1_T_21_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_22_X, brainpoolP512r1_T_22_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_23_X, brainpoolP512r1_T_23_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_24_X, brainpoolP512r1_T_24_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_25_X, brainpoolP512r1_T_25_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_26_X, brainpoolP512r1_T_26_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_27_X, brainpoolP512r1_T_27_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_28_X, brainpoolP512r1_T_28_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_29_X, brainpoolP512r1_T_29_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_30_X, brainpoolP512r1_T_30_Y), - ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_31_X, brainpoolP512r1_T_31_Y), -}; -#else -#define brainpoolP512r1_T NULL -#endif -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - - -#if defined(ECP_LOAD_GROUP) || defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ - defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -/* - * Create an MPI from embedded constants - * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint) and - * len < 1048576) - */ -static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len) -{ - X->s = 1; - X->n = (unsigned short) (len / sizeof(mbedtls_mpi_uint)); - X->p = (mbedtls_mpi_uint *) p; -} -#endif - -#if defined(ECP_LOAD_GROUP) -/* - * Set an MPI to static value 1 - */ -static inline void ecp_mpi_set1(mbedtls_mpi *X) -{ - X->s = 1; - X->n = 1; - X->p = mpi_one; -} - -/* - * Make group available from embedded constants - */ -static int ecp_group_load(mbedtls_ecp_group *grp, - const mbedtls_mpi_uint *p, size_t plen, - const mbedtls_mpi_uint *a, size_t alen, - const mbedtls_mpi_uint *b, size_t blen, - const mbedtls_mpi_uint *gx, size_t gxlen, - const mbedtls_mpi_uint *gy, size_t gylen, - const mbedtls_mpi_uint *n, size_t nlen, - const mbedtls_ecp_point *T) -{ - ecp_mpi_load(&grp->P, p, plen); - if (a != NULL) { - ecp_mpi_load(&grp->A, a, alen); - } - ecp_mpi_load(&grp->B, b, blen); - ecp_mpi_load(&grp->N, n, nlen); - - ecp_mpi_load(&grp->G.X, gx, gxlen); - ecp_mpi_load(&grp->G.Y, gy, gylen); - ecp_mpi_set1(&grp->G.Z); - - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - grp->nbits = mbedtls_mpi_bitlen(&grp->N); - - grp->h = 1; - - grp->T = (mbedtls_ecp_point *) T; - /* - * Set T_size to 0 to prevent T free by mbedtls_ecp_group_free. - */ - grp->T_size = 0; - - return 0; -} -#endif /* ECP_LOAD_GROUP */ - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* Forward declarations */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -static int ecp_mod_p192(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -static int ecp_mod_p224(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) -static int ecp_mod_p256(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -static int ecp_mod_p384(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -static int ecp_mod_p521(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); -#endif - -#define NIST_MODP(P) grp->modp = ecp_mod_ ## P; -#else -#define NIST_MODP(P) -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -/* Additional forward declarations */ -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -static int ecp_mod_p255(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -static int ecp_mod_p448(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *, size_t); -#endif -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) -static int ecp_mod_p192k1(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) -static int ecp_mod_p224k1(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) -static int ecp_mod_p256k1(mbedtls_mpi *); -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); -#endif - -#if defined(ECP_LOAD_GROUP) -#define LOAD_GROUP_A(G) ecp_group_load(grp, \ - G ## _p, sizeof(G ## _p), \ - G ## _a, sizeof(G ## _a), \ - G ## _b, sizeof(G ## _b), \ - G ## _gx, sizeof(G ## _gx), \ - G ## _gy, sizeof(G ## _gy), \ - G ## _n, sizeof(G ## _n), \ - G ## _T \ - ) - -#define LOAD_GROUP(G) ecp_group_load(grp, \ - G ## _p, sizeof(G ## _p), \ - NULL, 0, \ - G ## _b, sizeof(G ## _b), \ - G ## _gx, sizeof(G ## _gx), \ - G ## _gy, sizeof(G ## _gy), \ - G ## _n, sizeof(G ## _n), \ - G ## _T \ - ) -#endif /* ECP_LOAD_GROUP */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -/* Constants used by ecp_use_curve25519() */ -static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42; - -/* P = 2^255 - 19 */ -static const mbedtls_mpi_uint curve25519_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X7F) -}; - -/* N = 2^252 + 27742317777372353535851937790883648493 */ -static const mbedtls_mpi_uint curve25519_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0XED, 0XD3, 0XF5, 0X5C, 0X1A, 0X63, 0X12, 0X58), - MBEDTLS_BYTES_TO_T_UINT_8(0XD6, 0X9C, 0XF7, 0XA2, 0XDE, 0XF9, 0XDE, 0X14), - MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0x00, 0x00, 0x00, 0x00), - MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10) -}; - -/* - * Specialized function for creating the Curve25519 group - */ -static int ecp_use_curve25519(mbedtls_ecp_group *grp) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24)); - - ecp_mpi_load(&grp->P, curve25519_p, sizeof(curve25519_p)); - - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - - ecp_mpi_load(&grp->N, curve25519_n, sizeof(curve25519_n)); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 9)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); - mbedtls_mpi_free(&grp->G.Y); - - /* Actually, the required msb for private keys */ - grp->nbits = 254; - -cleanup: - if (ret != 0) { - mbedtls_ecp_group_free(grp); - } - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) -/* Constants used by ecp_use_curve448() */ -static const mbedtls_mpi_sint curve448_a24 = 0x98AA; - -/* P = 2^448 - 2^224 - 1 */ -static const mbedtls_mpi_uint curve448_p[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFE, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00) -}; - -/* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */ -static const mbedtls_mpi_uint curve448_n[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0XF3, 0X44, 0X58, 0XAB, 0X92, 0XC2, 0X78, 0X23), - MBEDTLS_BYTES_TO_T_UINT_8(0X55, 0X8F, 0XC5, 0X8D, 0X72, 0XC2, 0X6C, 0X21), - MBEDTLS_BYTES_TO_T_UINT_8(0X90, 0X36, 0XD6, 0XAE, 0X49, 0XDB, 0X4E, 0XC4), - MBEDTLS_BYTES_TO_T_UINT_8(0XE9, 0X23, 0XCA, 0X7C, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF), - MBEDTLS_BYTES_TO_T_UINT_8(0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X3F), - MBEDTLS_BYTES_TO_T_UINT_8(0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00) -}; - -/* - * Specialized function for creating the Curve448 group - */ -static int ecp_use_curve448(mbedtls_ecp_group *grp) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Actually ( A + 2 ) / 4 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24)); - - ecp_mpi_load(&grp->P, curve448_p, sizeof(curve448_p)); - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - - /* Y intentionally not set, since we use x/z coordinates. - * This is used as a marker to identify Montgomery curves! */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 5)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); - mbedtls_mpi_free(&grp->G.Y); - - ecp_mpi_load(&grp->N, curve448_n, sizeof(curve448_n)); - - /* Actually, the required msb for private keys */ - grp->nbits = 447; - -cleanup: - if (ret != 0) { - mbedtls_ecp_group_free(grp); - } - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -/* - * Set a group using well-known domain parameters - */ -int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id) -{ - mbedtls_ecp_group_free(grp); - - mbedtls_ecp_group_init(grp); - - grp->id = id; - - switch (id) { -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - case MBEDTLS_ECP_DP_SECP192R1: - NIST_MODP(p192); - return LOAD_GROUP(secp192r1); -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - case MBEDTLS_ECP_DP_SECP224R1: - NIST_MODP(p224); - return LOAD_GROUP(secp224r1); -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - case MBEDTLS_ECP_DP_SECP256R1: - NIST_MODP(p256); - return LOAD_GROUP(secp256r1); -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - case MBEDTLS_ECP_DP_SECP384R1: - NIST_MODP(p384); - return LOAD_GROUP(secp384r1); -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - case MBEDTLS_ECP_DP_SECP521R1: - NIST_MODP(p521); - return LOAD_GROUP(secp521r1); -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - case MBEDTLS_ECP_DP_SECP192K1: - grp->modp = ecp_mod_p192k1; - return LOAD_GROUP_A(secp192k1); -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - case MBEDTLS_ECP_DP_SECP224K1: - grp->modp = ecp_mod_p224k1; - return LOAD_GROUP_A(secp224k1); -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - case MBEDTLS_ECP_DP_SECP256K1: - grp->modp = ecp_mod_p256k1; - return LOAD_GROUP_A(secp256k1); -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - case MBEDTLS_ECP_DP_BP256R1: - return LOAD_GROUP_A(brainpoolP256r1); -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - case MBEDTLS_ECP_DP_BP384R1: - return LOAD_GROUP_A(brainpoolP384r1); -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - case MBEDTLS_ECP_DP_BP512R1: - return LOAD_GROUP_A(brainpoolP512r1); -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - grp->modp = ecp_mod_p255; - return ecp_use_curve25519(grp); -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - grp->modp = ecp_mod_p448; - return ecp_use_curve448(grp); -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - - default: - grp->id = MBEDTLS_ECP_DP_NONE; - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } -} - -#if defined(MBEDTLS_ECP_NIST_OPTIM) -/* - * Fast reduction modulo the primes used by the NIST curves. - * - * These functions are critical for speed, but not needed for correct - * operations. So, we make the choice to heavily rely on the internals of our - * bignum library, which creates a tight coupling between these functions and - * our MPI implementation. However, the coupling between the ECP module and - * MPI remains loose, since these functions can be deactivated at will. - */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) -/* - * Compared to the way things are presented in FIPS 186-3 D.2, - * we proceed in columns, from right (least significant chunk) to left, - * adding chunks to N in place, and keeping a carry for the next chunk. - * This avoids moving things around in memory, and uselessly adding zeros, - * compared to the more straightforward, line-oriented approach. - * - * For this prime we need to handle data in chunks of 64 bits. - * Since this is always a multiple of our basic mbedtls_mpi_uint, we can - * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. - */ - -/* Add 64-bit chunks (dst += src) and update carry */ -static inline void add64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry) -{ - unsigned char i; - mbedtls_mpi_uint c = 0; - for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++, src++) { - *dst += c; c = (*dst < c); - *dst += *src; c += (*dst < *src); - } - *carry += c; -} - -/* Add carry to a 64-bit chunk and update carry */ -static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry) -{ - unsigned char i; - for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) { - *dst += *carry; - *carry = (*dst < *carry); - } -} - -#define WIDTH 8 / sizeof(mbedtls_mpi_uint) -#define A(i) Np + (i) * WIDTH -#define ADD(i) add64(p, A(i), &c) -#define NEXT p += WIDTH; carry64(p, &c) -#define LAST p += WIDTH; do *p = 0; while (++p < end) -#define RESET last_carry[0] = c; c = 0; p = Np -#define ADD_LAST add64(p, last_carry, &c) - -/* - * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) - */ -static int ecp_mod_p192(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(192) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p192_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn) -{ - mbedtls_mpi_uint c = 0, last_carry[WIDTH] = { 0 }; - mbedtls_mpi_uint *p, *end; - - if (Nn != BITS_TO_LIMBS(192) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - p = Np; - end = p + Nn; - - ADD(3); ADD(5); NEXT; // A0 += A3 + A5 - ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5 - ADD(4); ADD(5); // A2 += A4 + A5 - - RESET; - - /* Use the reduction for the carry as well: - * 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192 - * It can generate a carry. */ - ADD_LAST; NEXT; // A0 += last_carry - ADD_LAST; NEXT; // A1 += last_carry - // A2 += carry - - RESET; - - /* Use the reduction for the carry as well: - * 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192 - */ - ADD_LAST; NEXT; // A0 += last_carry - ADD_LAST; NEXT; // A1 += last_carry - // A2 += carry - - LAST; - - return 0; -} - -#undef WIDTH -#undef A -#undef ADD -#undef NEXT -#undef LAST -#undef RESET -#undef ADD_LAST -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A(i); - -#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ - -#define MAX32 X_limbs -#define A(j) X[j] -#define STORE32 X[i] = (mbedtls_mpi_uint) cur; -#define STORE0 X[i] = 0; - -#else /* 64 bit */ - -#define MAX32 X_limbs * 2 -#define A(j) \ - (j) % 2 ? \ - (uint32_t) (X[(j) / 2] >> 32) : \ - (uint32_t) (X[(j) / 2]) -#define STORE32 \ - if (i % 2) { \ - X[i/2] &= 0x00000000FFFFFFFF; \ - X[i/2] |= (uint64_t) (cur) << 32; \ - } else { \ - X[i/2] &= 0xFFFFFFFF00000000; \ - X[i/2] |= (uint32_t) cur; \ - } - -#define STORE0 \ - if (i % 2) { \ - X[i/2] &= 0x00000000FFFFFFFF; \ - } else { \ - X[i/2] &= 0xFFFFFFFF00000000; \ - } - -#endif - -static inline int8_t extract_carry(int64_t cur) -{ - return (int8_t) (cur >> 32); -} - -#define ADD(j) cur += A(j) -#define SUB(j) cur -= A(j) - -#define ADD_CARRY(cc) cur += (cc) -#define SUB_CARRY(cc) cur -= (cc) - -#define ADD_LAST ADD_CARRY(last_c) -#define SUB_LAST SUB_CARRY(last_c) - -/* - * Helpers for the main 'loop' - */ -#define INIT(b) \ - int8_t c = 0, last_c; \ - int64_t cur; \ - size_t i = 0; \ - LOAD32; - -#define NEXT \ - c = extract_carry(cur); \ - STORE32; i++; LOAD32; \ - ADD_CARRY(c); - -#define RESET \ - c = extract_carry(cur); \ - last_c = c; \ - STORE32; i = 0; LOAD32; \ - c = 0; \ - -#define LAST \ - c = extract_carry(cur); \ - STORE32; i++; \ - if (c != 0) \ - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; \ - while (i < MAX32) { STORE0; i++; } - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(224) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p224_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - if (X_limbs != BITS_TO_LIMBS(224) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - INIT(224); - - SUB(7); SUB(11); NEXT; // A0 += -A7 - A11 - SUB(8); SUB(12); NEXT; // A1 += -A8 - A12 - SUB(9); SUB(13); NEXT; // A2 += -A9 - A13 - SUB(10); ADD(7); ADD(11); NEXT; // A3 += -A10 + A7 + A11 - SUB(11); ADD(8); ADD(12); NEXT; // A4 += -A11 + A8 + A12 - SUB(12); ADD(9); ADD(13); NEXT; // A5 += -A12 + A9 + A13 - SUB(13); ADD(10); // A6 += -A13 + A10 - - RESET; - - /* Use 2^224 = P + 2^96 - 1 to modulo reduce the final carry */ - SUB_LAST; NEXT; // A0 -= last_c - ; NEXT; // A1 - ; NEXT; // A2 - ADD_LAST; NEXT; // A3 += last_c - ; NEXT; // A4 - ; NEXT; // A5 - // A6 - - /* The carry reduction cannot generate a carry - * (see commit 73e8553 for details)*/ - - LAST; - - return 0; -} - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - -/* - * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) - */ -static int ecp_mod_p256(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(256) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p256_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - if (X_limbs != BITS_TO_LIMBS(256) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - INIT(256); - - ADD(8); ADD(9); - SUB(11); SUB(12); SUB(13); SUB(14); NEXT; // A0 - - ADD(9); ADD(10); - SUB(12); SUB(13); SUB(14); SUB(15); NEXT; // A1 - - ADD(10); ADD(11); - SUB(13); SUB(14); SUB(15); NEXT; // A2 - - ADD(11); ADD(11); ADD(12); ADD(12); ADD(13); - SUB(15); SUB(8); SUB(9); NEXT; // A3 - - ADD(12); ADD(12); ADD(13); ADD(13); ADD(14); - SUB(9); SUB(10); NEXT; // A4 - - ADD(13); ADD(13); ADD(14); ADD(14); ADD(15); - SUB(10); SUB(11); NEXT; // A5 - - ADD(14); ADD(14); ADD(15); ADD(15); ADD(14); ADD(13); - SUB(8); SUB(9); NEXT; // A6 - - ADD(15); ADD(15); ADD(15); ADD(8); - SUB(10); SUB(11); SUB(12); SUB(13); // A7 - - RESET; - - /* Use 2^224 * (2^32 - 1) + 2^192 + 2^96 - 1 - * to modulo reduce the final carry. */ - ADD_LAST; NEXT; // A0 - ; NEXT; // A1 - ; NEXT; // A2 - SUB_LAST; NEXT; // A3 - ; NEXT; // A4 - ; NEXT; // A5 - SUB_LAST; NEXT; // A6 - ADD_LAST; // A7 - - RESET; - - /* Use 2^224 * (2^32 - 1) + 2^192 + 2^96 - 1 - * to modulo reduce the carry generated by the previous reduction. */ - ADD_LAST; NEXT; // A0 - ; NEXT; // A1 - ; NEXT; // A2 - SUB_LAST; NEXT; // A3 - ; NEXT; // A4 - ; NEXT; // A5 - SUB_LAST; NEXT; // A6 - ADD_LAST; // A7 - - LAST; - - return 0; -} - -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) - */ -static int ecp_mod_p384(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(384) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p384_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - if (X_limbs != BITS_TO_LIMBS(384) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - INIT(384); - - ADD(12); ADD(21); ADD(20); - SUB(23); NEXT; // A0 - - ADD(13); ADD(22); ADD(23); - SUB(12); SUB(20); NEXT; // A1 - - ADD(14); ADD(23); - SUB(13); SUB(21); NEXT; // A2 - - ADD(15); ADD(12); ADD(20); ADD(21); - SUB(14); SUB(22); SUB(23); NEXT; // A3 - - ADD(21); ADD(21); ADD(16); ADD(13); ADD(12); ADD(20); ADD(22); - SUB(15); SUB(23); SUB(23); NEXT; // A4 - - ADD(22); ADD(22); ADD(17); ADD(14); ADD(13); ADD(21); ADD(23); - SUB(16); NEXT; // A5 - - ADD(23); ADD(23); ADD(18); ADD(15); ADD(14); ADD(22); - SUB(17); NEXT; // A6 - - ADD(19); ADD(16); ADD(15); ADD(23); - SUB(18); NEXT; // A7 - - ADD(20); ADD(17); ADD(16); - SUB(19); NEXT; // A8 - - ADD(21); ADD(18); ADD(17); - SUB(20); NEXT; // A9 - - ADD(22); ADD(19); ADD(18); - SUB(21); NEXT; // A10 - - ADD(23); ADD(20); ADD(19); - SUB(22); // A11 - - RESET; - - /* Use 2^384 = P + 2^128 + 2^96 - 2^32 + 1 to modulo reduce the final carry */ - ADD_LAST; NEXT; // A0 - SUB_LAST; NEXT; // A1 - ; NEXT; // A2 - ADD_LAST; NEXT; // A3 - ADD_LAST; NEXT; // A4 - ; NEXT; // A5 - ; NEXT; // A6 - ; NEXT; // A7 - ; NEXT; // A8 - ; NEXT; // A9 - ; NEXT; // A10 - // A11 - - RESET; - - ADD_LAST; NEXT; // A0 - SUB_LAST; NEXT; // A1 - ; NEXT; // A2 - ADD_LAST; NEXT; // A3 - ADD_LAST; NEXT; // A4 - ; NEXT; // A5 - ; NEXT; // A6 - ; NEXT; // A7 - ; NEXT; // A8 - ; NEXT; // A9 - ; NEXT; // A10 - // A11 - - LAST; - - return 0; -} -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#undef LOAD32 -#undef MAX32 -#undef A -#undef STORE32 -#undef STORE0 -#undef ADD -#undef SUB -#undef ADD_CARRY -#undef SUB_CARRY -#undef ADD_LAST -#undef SUB_LAST -#undef INIT -#undef NEXT -#undef RESET -#undef LAST - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || - MBEDTLS_ECP_DP_SECP256R1_ENABLED || - MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -/* Size of p521 in terms of mbedtls_mpi_uint */ -#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1) - -/* Bits to keep in the most significant mbedtls_mpi_uint */ -#define P521_MASK 0x01FF - -/* - * Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) - */ -static int ecp_mod_p521(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(521) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p521_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - mbedtls_mpi_uint carry = 0; - - if (X_limbs != BITS_TO_LIMBS(521) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* Step 1: Reduction to P521_WIDTH limbs */ - /* Helper references for bottom part of X */ - mbedtls_mpi_uint *X0 = X; - size_t X0_limbs = P521_WIDTH; - /* Helper references for top part of X */ - mbedtls_mpi_uint *X1 = X + X0_limbs; - size_t X1_limbs = X_limbs - X0_limbs; - /* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1. - * (We are using that 2^P521_WIDTH = 2^(512 + biL) and that - * 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.) - * The high order limb of the result will be held in carry and the rest - * in X0 (that is the result will be represented as - * 2^P521_WIDTH carry + X0). - * - * Also, note that the resulting carry is either 0 or 1: - * X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512 - * therefore - * X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9) - * which in turn is less than 2 * 2^(512 + biL). - */ - mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); - carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift); - /* Set X to X0 (by clearing the top part). */ - memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint)); - - /* Step 2: Reduction modulo P521 - * - * At this point X is reduced to P521_WIDTH limbs. What remains is to add - * the carry (that is 2^P521_WIDTH carry) and to reduce mod P521. */ - - /* 2^P521_WIDTH carry = 2^(512 + biL) carry = 2^(biL - 9) carry mod P521. - * Also, recall that carry is either 0 or 1. */ - mbedtls_mpi_uint addend = carry << (biL - 9); - /* Keep the top 9 bits and reduce the rest, using 2^521 = 1 mod P521. */ - addend += (X[P521_WIDTH - 1] >> 9); - X[P521_WIDTH - 1] &= P521_MASK; - - /* Reuse the top part of X (already zeroed) as a helper array for - * carrying out the addition. */ - mbedtls_mpi_uint *addend_arr = X + P521_WIDTH; - addend_arr[0] = addend; - (void) mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH); - /* Both addends were less than P521 therefore X < 2 * P521. (This also means - * that the result fit in P521_WIDTH limbs and there won't be any carry.) */ - - /* Clear the reused part of X. */ - addend_arr[0] = 0; - - return 0; -} - -#undef P521_WIDTH -#undef P521_MASK - -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#endif /* MBEDTLS_ECP_NIST_OPTIM */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - -/* Size of p255 in terms of mbedtls_mpi_uint */ -#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1) - -/* - * Fast quasi-reduction modulo p255 = 2^255 - 19 - * Write N as A0 + 2^256 A1, return A0 + 38 * A1 - */ -static int ecp_mod_p255(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(255) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width); -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) -{ - - if (X_Limbs != BITS_TO_LIMBS(255) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL); - if (carry == NULL) { - return MBEDTLS_ERR_ECP_ALLOC_FAILED; - } - - /* Step 1: Reduction to P255_WIDTH limbs */ - if (X_Limbs > P255_WIDTH) { - /* Helper references for top part of X */ - mbedtls_mpi_uint * const A1 = X + P255_WIDTH; - const size_t A1_limbs = X_Limbs - P255_WIDTH; - - /* X = A0 + 38 * A1, capture carry out */ - *carry = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38); - /* Clear top part */ - memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs); - } - - /* Step 2: Reduce to <2p - * Split as A0 + 2^255*c, with c a scalar, and compute A0 + 19*c */ - *carry <<= 1; - *carry += (X[P255_WIDTH - 1] >> (biL - 1)); - *carry *= 19; - - /* Clear top bit */ - X[P255_WIDTH - 1] <<= 1; X[P255_WIDTH - 1] >>= 1; - /* Since the top bit for X has been cleared 0 + 0 + Carry - * will not overflow. - * - * Furthermore for 2p = 2^256-38. When a carry propagation on the highest - * limb occurs, X > 2^255 and all the remaining bits on the limb are zero. - * - If X < 2^255 ==> X < 2p - * - If X > 2^255 ==> X < 2^256 - 2^255 < 2p */ - (void) mbedtls_mpi_core_add(X, X, carry, P255_WIDTH); - - mbedtls_free(carry); - return 0; -} -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - -/* Size of p448 in terms of mbedtls_mpi_uint */ -#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint)) - -/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */ -#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y)) -#define P224_SIZE (224 / 8) -#define P224_WIDTH_MIN (P224_SIZE / sizeof(mbedtls_mpi_uint)) -#define P224_WIDTH_MAX DIV_ROUND_UP(P224_SIZE, sizeof(mbedtls_mpi_uint)) -#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224) - -static int ecp_mod_p448(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(448) * 2; - - /* This is required as some tests and use cases do not pass in a Bignum of - * the correct size, and expect the growth to be done automatically, which - * will no longer happen. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - - ret = mbedtls_ecp_mod_p448_raw(N->p, N->n); - -cleanup: - return ret; -} - -/* - * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 - * Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 + - * (B0 + B1) * 2^224. This is different to the reference implementation of - * Curve448, which uses its own special 56-bit limbs rather than a generic - * bignum library. We could squeeze some extra speed out on 32-bit machines by - * splitting N up into 32-bit limbs and doing the arithmetic using the limbs - * directly as we do for the NIST primes above, but for 64-bit targets it should - * use half the number of operations if we do the reduction with 224-bit limbs, - * since mpi_core_add will then use 64-bit adds. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - size_t round; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (X_limbs != BITS_TO_LIMBS(448) * 2) { - return 0; - } - - size_t M_limbs = X_limbs - (P448_WIDTH); - - if (M_limbs > P448_WIDTH) { - /* Shouldn't be called with X larger than 2^896! */ - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - /* Both M and Q require an extra limb to catch carries. */ - M_limbs++; - - const size_t Q_limbs = M_limbs; - mbedtls_mpi_uint *M = NULL; - mbedtls_mpi_uint *Q = NULL; - - M = mbedtls_calloc(M_limbs, ciL); - - if (M == NULL) { - return MBEDTLS_ERR_ECP_ALLOC_FAILED; - } - - Q = mbedtls_calloc(Q_limbs, ciL); - - if (Q == NULL) { - ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; - goto cleanup; - } - - /* M = A1 */ - memset(M, 0, (M_limbs * ciL)); - /* Do not copy into the overflow limb, as this would read past the end of - * X. */ - memcpy(M, X + P448_WIDTH, ((M_limbs - 1) * ciL)); - - /* X = A0 */ - memset(X + P448_WIDTH, 0, ((M_limbs - 1) * ciL)); - - /* X = X + M = A0 + A1 */ - /* Carry here fits in oversize X. Oversize M means it will get - * added in, not returned as carry. */ - (void) mbedtls_mpi_core_add(X, X, M, M_limbs); - - /* Q = B1 = M >> 224 */ - memcpy(Q, (char *) M + P224_SIZE, P224_SIZE); - memset((char *) Q + P224_SIZE, 0, P224_SIZE); - - /* X = X + Q = (A0 + A1) + B1 - * Oversize Q catches potential carry here when X is already max 448 bits. - */ - (void) mbedtls_mpi_core_add(X, X, Q, Q_limbs); - - /* M = B0 */ -#ifdef MBEDTLS_HAVE_INT64 - M[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS); - #endif - memset(M + P224_WIDTH_MAX, 0, ((M_limbs - P224_WIDTH_MAX) * ciL)); - - /* M = M + Q = B0 + B1 */ - (void) mbedtls_mpi_core_add(M, M, Q, Q_limbs); - - /* M = (B0 + B1) * 2^224 */ - /* Shifted carry bit from the addition fits in oversize M. */ - memmove((char *) M + P224_SIZE, M, P224_SIZE + ciL); - memset(M, 0, P224_SIZE); - - /* X = X + M = (A0 + A1 + B1) + (B0 + B1) * 2^224 */ - (void) mbedtls_mpi_core_add(X, X, M, M_limbs); - - /* In the second and third rounds A1 and B0 have at most 1 non-zero limb and - * B1=0. - * Using this we need to calculate: - * A0 + A1 + B1 + (B0 + B1) * 2^224 = A0 + A1 + B0 * 2^224. */ - for (round = 0; round < 2; ++round) { - - /* M = A1 */ - memset(M, 0, (M_limbs * ciL)); - memcpy(M, X + P448_WIDTH, ((M_limbs - 1) * ciL)); - - /* X = A0 */ - memset(X + P448_WIDTH, 0, ((M_limbs - 1) * ciL)); - - /* M = A1 + B0 * 2^224 - * We know that only one limb of A1 will be non-zero and that it will be - * limb 0. We also know that B0 is the bottom 224 bits of A1 (which is - * then shifted up 224 bits), so, given M is currently A1 this turns - * into: - * M = M + (M << 224) - * As the single non-zero limb in B0 will be A1 limb 0 shifted up by 224 - * bits, we can just move that into the right place, shifted up - * accordingly.*/ - M[P224_WIDTH_MIN] = M[0] << (224 & (biL - 1)); - - /* X = A0 + (A1 + B0 * 2^224) */ - (void) mbedtls_mpi_core_add(X, X, M, M_limbs); - } - - ret = 0; - -cleanup: - mbedtls_free(M); - mbedtls_free(Q); - - return ret; -} -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - -/* - * Fast quasi-reduction modulo P = 2^s - R, - * with R about 33 bits, used by the Koblitz curves. - * - * Write X as A0 + 2^224 A1, return A0 + R * A1. - */ -#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R - -static inline int ecp_mod_koblitz(mbedtls_mpi_uint *X, - size_t X_limbs, - mbedtls_mpi_uint *R, - size_t bits) -{ - int ret = 0; - - /* Determine if A1 is aligned to limb bitsize. If not then the used limbs - * of P, A0 and A1 must be set accordingly and there is a middle limb - * which is shared by A0 and A1 and need to handle accordingly. - */ - size_t shift = bits % biL; - size_t adjust = (shift + biL - 1) / biL; - size_t P_limbs = bits / biL + adjust; - - mbedtls_mpi_uint *A1 = mbedtls_calloc(P_limbs, ciL); - if (A1 == NULL) { - return MBEDTLS_ERR_ECP_ALLOC_FAILED; - } - - /* Create a buffer to store the value of `R * A1` */ - size_t R_limbs = P_KOBLITZ_R; - size_t M_limbs = P_limbs + R_limbs; - mbedtls_mpi_uint *M = mbedtls_calloc(M_limbs, ciL); - if (M == NULL) { - ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; - goto cleanup; - } - - mbedtls_mpi_uint mask = 0; - if (adjust != 0) { - mask = ((mbedtls_mpi_uint) 1 << shift) - 1; - } - - /* Two passes are needed to reduce the value of `A0 + R * A1` and then - * we need an additional one to reduce the possible overflow during - * the addition. - */ - for (size_t pass = 0; pass < 3; pass++) { - /* Copy A1 */ - memcpy(A1, X + P_limbs - adjust, P_limbs * ciL); - - /* Shift A1 to be aligned */ - if (shift != 0) { - mbedtls_mpi_core_shift_r(A1, P_limbs, shift); - } - - /* Zeroize the A1 part of the shared limb */ - if (mask != 0) { - X[P_limbs - 1] &= mask; - } - - /* X = A0 - * Zeroize the A1 part of X to keep only the A0 part. - */ - for (size_t i = P_limbs; i < X_limbs; i++) { - X[i] = 0; - } - - /* X = A0 + R * A1 */ - mbedtls_mpi_core_mul(M, A1, P_limbs, R, R_limbs); - (void) mbedtls_mpi_core_add(X, X, M, P_limbs + R_limbs); - - /* Carry can not be generated since R is a 33-bit value and stored in - * 64 bits. The result value of the multiplication is at most - * P length + 33 bits in length and the result value of the addition - * is at most P length + 34 bits in length. So the result of the - * addition always fits in P length + 64 bits. - */ - } - -cleanup: - mbedtls_free(M); - mbedtls_free(A1); - - return ret; -} - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || - MBEDTLS_ECP_DP_SECP224K1_ENABLED) || - MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - -/* - * Fast quasi-reduction modulo p192k1 = 2^192 - R, - * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9 - */ -static int ecp_mod_p192k1(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(192) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p192k1_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00) - }; - - if (X_limbs != BITS_TO_LIMBS(192) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return ecp_mod_koblitz(X, X_limbs, Rp, 192); -} - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - -/* - * Fast quasi-reduction modulo p224k1 = 2^224 - R, - * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 - */ -static int ecp_mod_p224k1(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(224) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p224k1_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00) - }; - - if (X_limbs != BITS_TO_LIMBS(224) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return ecp_mod_koblitz(X, X_limbs, Rp, 224); -} - -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - -/* - * Fast quasi-reduction modulo p256k1 = 2^256 - R, - * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 - */ -static int ecp_mod_p256k1(mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = BITS_TO_LIMBS(256) * 2; - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = mbedtls_ecp_mod_p256k1_raw(N->p, expected_width); - -cleanup: - return ret; -} - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs) -{ - static mbedtls_mpi_uint Rp[] = { - MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00) - }; - - if (X_limbs != BITS_TO_LIMBS(256) * 2) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - return ecp_mod_koblitz(X, X_limbs, Rp, 256); -} - -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_TEST_HOOKS) -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_ecp_group_id id, - const mbedtls_ecp_modulus_type ctype) -{ - mbedtls_mpi_modp_fn modp = NULL; - mbedtls_mpi_uint *p = NULL; - size_t p_limbs; - - if (!(ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE || \ - ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_SCALAR)) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - switch (id) { -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - case MBEDTLS_ECP_DP_SECP192R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p192_raw; -#endif - p = (mbedtls_mpi_uint *) secp192r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp192r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - case MBEDTLS_ECP_DP_SECP224R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p224_raw; -#endif - p = (mbedtls_mpi_uint *) secp224r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp224r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - case MBEDTLS_ECP_DP_SECP256R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p256_raw; -#endif - p = (mbedtls_mpi_uint *) secp256r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp256r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - case MBEDTLS_ECP_DP_SECP384R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p384_raw; -#endif - p = (mbedtls_mpi_uint *) secp384r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp384r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - case MBEDTLS_ECP_DP_SECP521R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { -#if defined(MBEDTLS_ECP_NIST_OPTIM) - modp = &mbedtls_ecp_mod_p521_raw; -#endif - p = (mbedtls_mpi_uint *) secp521r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_p)); - } else { - p = (mbedtls_mpi_uint *) secp521r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - case MBEDTLS_ECP_DP_BP256R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - p = (mbedtls_mpi_uint *) brainpoolP256r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_p)); - } else { - p = (mbedtls_mpi_uint *) brainpoolP256r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - case MBEDTLS_ECP_DP_BP384R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - p = (mbedtls_mpi_uint *) brainpoolP384r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_p)); - } else { - p = (mbedtls_mpi_uint *) brainpoolP384r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - case MBEDTLS_ECP_DP_BP512R1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - p = (mbedtls_mpi_uint *) brainpoolP512r1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_p)); - } else { - p = (mbedtls_mpi_uint *) brainpoolP512r1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - case MBEDTLS_ECP_DP_CURVE25519: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p255_raw; - p = (mbedtls_mpi_uint *) curve25519_p; - p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_p)); - } else { - p = (mbedtls_mpi_uint *) curve25519_n; - p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - case MBEDTLS_ECP_DP_SECP192K1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p192k1_raw; - p = (mbedtls_mpi_uint *) secp192k1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_p)); - } else { - p = (mbedtls_mpi_uint *) secp192k1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - case MBEDTLS_ECP_DP_SECP224K1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p224k1_raw; - p = (mbedtls_mpi_uint *) secp224k1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_p)); - } else { - p = (mbedtls_mpi_uint *) secp224k1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - case MBEDTLS_ECP_DP_SECP256K1: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p256k1_raw; - p = (mbedtls_mpi_uint *) secp256k1_p; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_p)); - } else { - p = (mbedtls_mpi_uint *) secp256k1_n; - p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_n)); - } - break; -#endif - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - case MBEDTLS_ECP_DP_CURVE448: - if (ctype == (mbedtls_ecp_modulus_type) MBEDTLS_ECP_MOD_COORDINATE) { - modp = &mbedtls_ecp_mod_p448_raw; - p = (mbedtls_mpi_uint *) curve448_p; - p_limbs = CHARS_TO_LIMBS(sizeof(curve448_p)); - } else { - p = (mbedtls_mpi_uint *) curve448_n; - p_limbs = CHARS_TO_LIMBS(sizeof(curve448_n)); - } - break; -#endif - - default: - case MBEDTLS_ECP_DP_NONE: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - if (modp != NULL) { - if (mbedtls_mpi_mod_optred_modulus_setup(N, p, p_limbs, modp)) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - } else { - if (mbedtls_mpi_mod_modulus_setup(N, p, p_limbs)) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - } - return 0; -} -#endif /* MBEDTLS_TEST_HOOKS */ - -#if defined(MBEDTLS_TEST_HOOKS) - -MBEDTLS_STATIC_TESTABLE -mbedtls_ecp_variant mbedtls_ecp_get_variant(void) -{ - return MBEDTLS_ECP_VARIANT_WITH_MPI_UINT; -} - -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* !MBEDTLS_ECP_ALT */ -#endif /* MBEDTLS_ECP_LIGHT */ -#endif /* MBEDTLS_ECP_WITH_MPI_UINT */ diff --git a/vendor/mbedtls/library/ecp_internal_alt.h b/vendor/mbedtls/library/ecp_internal_alt.h deleted file mode 100644 index 668edc74c..000000000 --- a/vendor/mbedtls/library/ecp_internal_alt.h +++ /dev/null @@ -1,287 +0,0 @@ -/** - * \file ecp_internal_alt.h - * - * \brief Function declarations for alternative implementation of elliptic curve - * point arithmetic. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * References: - * - * [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records. - * - * - * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis - * for elliptic curve cryptosystems. In : Cryptographic Hardware and - * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. - * - * - * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to - * render ECC resistant against Side Channel Attacks. IACR Cryptology - * ePrint Archive, 2004, vol. 2004, p. 342. - * - * - * [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters. - * - * - * [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic - * Curve Cryptography. - * - * [6] Digital Signature Standard (DSS), FIPS 186-4. - * - * - * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer - * Security (TLS), RFC 4492. - * - * - * [8] - * - * [9] COHEN, Henri. A Course in Computational Algebraic Number Theory. - * Springer Science & Business Media, 1 Aug 2000 - */ - -#ifndef MBEDTLS_ECP_INTERNAL_H -#define MBEDTLS_ECP_INTERNAL_H - -#include "mbedtls/build_info.h" - -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - -/** - * \brief Indicate if the Elliptic Curve Point module extension can - * handle the group. - * - * \param grp The pointer to the elliptic curve group that will be the - * basis of the cryptographic computations. - * - * \return Non-zero if successful. - */ -unsigned char mbedtls_internal_ecp_grp_capable(const mbedtls_ecp_group *grp); - -/** - * \brief Initialise the Elliptic Curve Point module extension. - * - * If mbedtls_internal_ecp_grp_capable returns true for a - * group, this function has to be able to initialise the - * module for it. - * - * This module can be a driver to a crypto hardware - * accelerator, for which this could be an initialise function. - * - * \param grp The pointer to the group the module needs to be - * initialised for. - * - * \return 0 if successful. - */ -int mbedtls_internal_ecp_init(const mbedtls_ecp_group *grp); - -/** - * \brief Frees and deallocates the Elliptic Curve Point module - * extension. - * - * \param grp The pointer to the group the module was initialised for. - */ -void mbedtls_internal_ecp_free(const mbedtls_ecp_group *grp); - -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) -/** - * \brief Randomize jacobian coordinates: - * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l. - * - * \param grp Pointer to the group representing the curve. - * - * \param pt The point on the curve to be randomised, given with Jacobian - * coordinates. - * - * \param f_rng A function pointer to the random number generator. - * - * \param p_rng A pointer to the random number generator state. - * - * \return 0 if successful. - */ -int mbedtls_internal_ecp_randomize_jac(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt, int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng); -#endif - -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) -/** - * \brief Addition: R = P + Q, mixed affine-Jacobian coordinates. - * - * The coordinates of Q must be normalized (= affine), - * but those of P don't need to. R is not normalized. - * - * This function is used only as a subrutine of - * ecp_mul_comb(). - * - * Special cases: (1) P or Q is zero, (2) R is zero, - * (3) P == Q. - * None of these cases can happen as intermediate step in - * ecp_mul_comb(): - * - at each step, P, Q and R are multiples of the base - * point, the factor being less than its order, so none of - * them is zero; - * - Q is an odd multiple of the base point, P an even - * multiple, due to the choice of precomputed points in the - * modified comb method. - * So branches for these cases do not leak secret information. - * - * We accept Q->Z being unset (saving memory in tables) as - * meaning 1. - * - * Cost in field operations if done by [5] 3.22: - * 1A := 8M + 3S - * - * \param grp Pointer to the group representing the curve. - * - * \param R Pointer to a point structure to hold the result. - * - * \param P Pointer to the first summand, given with Jacobian - * coordinates - * - * \param Q Pointer to the second summand, given with affine - * coordinates. - * - * \return 0 if successful. - */ -int mbedtls_internal_ecp_add_mixed(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q); -#endif - -/** - * \brief Point doubling R = 2 P, Jacobian coordinates. - * - * Cost: 1D := 3M + 4S (A == 0) - * 4M + 4S (A == -3) - * 3M + 6S + 1a otherwise - * when the implementation is based on the "dbl-1998-cmo-2" - * doubling formulas in [8] and standard optimizations are - * applied when curve parameter A is one of { 0, -3 }. - * - * \param grp Pointer to the group representing the curve. - * - * \param R Pointer to a point structure to hold the result. - * - * \param P Pointer to the point that has to be doubled, given with - * Jacobian coordinates. - * - * \return 0 if successful. - */ -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) -int mbedtls_internal_ecp_double_jac(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, const mbedtls_ecp_point *P); -#endif - -/** - * \brief Normalize jacobian coordinates of an array of (pointers to) - * points. - * - * Using Montgomery's trick to perform only one inversion mod P - * the cost is: - * 1N(t) := 1I + (6t - 3)M + 1S - * (See for example Algorithm 10.3.4. in [9]) - * - * This function is used only as a subrutine of - * ecp_mul_comb(). - * - * Warning: fails (returning an error) if one of the points is - * zero! - * This should never happen, see choice of w in ecp_mul_comb(). - * - * \param grp Pointer to the group representing the curve. - * - * \param T Array of pointers to the points to normalise. - * - * \param t_len Number of elements in the array. - * - * \return 0 if successful, - * an error if one of the points is zero. - */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) -int mbedtls_internal_ecp_normalize_jac_many(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *T[], size_t t_len); -#endif - -/** - * \brief Normalize jacobian coordinates so that Z == 0 || Z == 1. - * - * Cost in field operations if done by [5] 3.2.1: - * 1N := 1I + 3M + 1S - * - * \param grp Pointer to the group representing the curve. - * - * \param pt pointer to the point to be normalised. This is an - * input/output parameter. - * - * \return 0 if successful. - */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) -int mbedtls_internal_ecp_normalize_jac(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *pt); -#endif - -#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) -int mbedtls_internal_ecp_double_add_mxz(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *R, - mbedtls_ecp_point *S, - const mbedtls_ecp_point *P, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *d); -#endif - -/** - * \brief Randomize projective x/z coordinates: - * (X, Z) -> (l X, l Z) for random l - * - * \param grp pointer to the group representing the curve - * - * \param P the point on the curve to be randomised given with - * projective coordinates. This is an input/output parameter. - * - * \param f_rng a function pointer to the random number generator - * - * \param p_rng a pointer to the random number generator state - * - * \return 0 if successful - */ -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) -int mbedtls_internal_ecp_randomize_mxz(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *P, int (*f_rng)(void *, - unsigned char *, - size_t), - void *p_rng); -#endif - -/** - * \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1. - * - * \param grp pointer to the group representing the curve - * - * \param P pointer to the point to be normalised. This is an - * input/output parameter. - * - * \return 0 if successful - */ -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) -int mbedtls_internal_ecp_normalize_mxz(const mbedtls_ecp_group *grp, - mbedtls_ecp_point *P); -#endif - -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ - -#endif /* ecp_internal_alt.h */ diff --git a/vendor/mbedtls/library/ecp_invasive.h b/vendor/mbedtls/library/ecp_invasive.h deleted file mode 100644 index ff9f9ecf1..000000000 --- a/vendor/mbedtls/library/ecp_invasive.h +++ /dev/null @@ -1,325 +0,0 @@ -/** - * \file ecp_invasive.h - * - * \brief ECP module: interfaces for invasive testing only. - * - * The interfaces in this file are intended for testing purposes only. - * They SHOULD NOT be made available in library integrations except when - * building the library for testing. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_ECP_INVASIVE_H -#define MBEDTLS_ECP_INVASIVE_H - -#include "common.h" -#include "mbedtls/bignum.h" -#include "bignum_mod.h" -#include "mbedtls/ecp.h" - -/* - * Curve modulus types - */ -typedef enum { - MBEDTLS_ECP_MOD_NONE = 0, - MBEDTLS_ECP_MOD_COORDINATE, - MBEDTLS_ECP_MOD_SCALAR -} mbedtls_ecp_modulus_type; - -typedef enum { - MBEDTLS_ECP_VARIANT_NONE = 0, - MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT, - MBEDTLS_ECP_VARIANT_WITH_MPI_UINT -} mbedtls_ecp_variant; - -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT) - -/** Queries the ecp variant. - * - * \return The id of the ecp variant. - */ -MBEDTLS_STATIC_TESTABLE -mbedtls_ecp_variant mbedtls_ecp_get_variant(void); - -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) -/** Generate a private key on a Montgomery curve (Curve25519 or Curve448). - * - * This function implements key generation for the set of secret keys - * specified in [Curve25519] p. 5 and in [Curve448]. The resulting value - * has the lower bits masked but is not necessarily canonical. - * - * \note - [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf - * - [RFC7748] https://tools.ietf.org/html/rfc7748 - * - * \p high_bit The position of the high-order bit of the key to generate. - * This is the bit-size of the key minus 1: - * 254 for Curve25519 or 447 for Curve448. - * \param d The randomly generated key. This is a number of size - * exactly \p high_bit + 1 bits, with the least significant bits - * masked as specified in [Curve25519] and in [RFC7748] §5. - * \param f_rng The RNG function. - * \param p_rng The RNG context to be passed to \p f_rng. - * - * \return \c 0 on success. - * \return \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure. - */ -int mbedtls_ecp_gen_privkey_mx(size_t high_bit, - mbedtls_mpi *d, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - -#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - -/** Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) - * - * This operation expects a 384 bit MPI and the result of the reduction - * is a 192 bit MPI. - * - * \param[in,out] Np The address of the MPI to be converted. - * Must have twice as many limbs as the modulus. - * Upon return this holds the reduced value. The bitlength - * of the reduced value is the same as that of the modulus - * (192 bits). - * \param[in] Nn The length of \p Np in limbs. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); - -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - -/** Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 448-bit MPI - * (double the bitlength of the modulus). - * Upon return holds the reduced value which is - * in range `0 <= X < 2 * N` (where N is the modulus). - * The bitlength of the reduced value is the same as - * that of the modulus (224 bits). - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the - * limb size that sores a 448-bit MPI. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - -/** Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 512-bit MPI - * (double the bitlength of the modulus). - * Upon return holds the reduced value which is - * in range `0 <= X < 2 * N` (where N is the modulus). - * The bitlength of the reduced value is the same as - * that of the modulus (256 bits). - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the - * limb size that sores a 512-bit MPI. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif - -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - -/** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) - * - * \param[in,out] X The address of the MPI to be converted. - * Must have twice as many limbs as the modulus - * (the modulus is 521 bits long). Upon return this - * holds the reduced value. The reduced value is - * in range `0 <= X < 2 * N` (where N is the modulus). - * and its the bitlength is one plus the bitlength - * of the modulus. - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs does not have - * twice as many limbs as the modulus. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - -/** Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 768-bit MPI - * (double the bitlength of the modulus). - * Upon return holds the reduced value which is - * in range `0 <= X < 2 * N` (where N is the modulus). - * The bitlength of the reduced value is the same as - * that of the modulus (384 bits). - * \param[in] X_limbs The length of \p N in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p N_n does not have - * twice as many limbs as the modulus. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - -/** Fast quasi-reduction modulo p192k1 = 2^192 - R, - * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9 - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 384-bit MPI - * (double the bitlength of the modulus). - * Upon return holds the reduced value which is - * in range `0 <= X < 2 * N` (where N is the modulus). - * The bitlength of the reduced value is the same as - * that of the modulus (192 bits). - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have - * twice as many limbs as the modulus. - * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - -/** Fast quasi-reduction modulo p224k1 = 2^224 - R, - * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 448-bit MPI - * (double the bitlength of the modulus). - * Upon return holds the reduced value which is - * in range `0 <= X < 2 * N` (where N is the modulus). - * The bitlength of the reduced value is the same as - * that of the modulus (224 bits). - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have - * twice as many limbs as the modulus. - * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - -/** Fast quasi-reduction modulo p256k1 = 2^256 - R, - * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 512-bit MPI - * (double the bitlength of the modulus). - * Upon return holds the reduced value which is - * in range `0 <= X < 2 * N` (where N is the modulus). - * The bitlength of the reduced value is the same as - * that of the modulus (256 bits). - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have - * twice as many limbs as the modulus. - * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - -/** Fast quasi-reduction modulo p255 = 2^255 - 19 - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 510-bit MPI - * (double the bitlength of the modulus). - * Upon return holds the reduced value which is - * in range `0 <= X < 2 * N` (where N is the modulus). - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have - * twice as many limbs as the modulus. - * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - -/** Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 - * Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 + - * (B0 + B1) * 2^224. - * - * \param[in,out] X The address of the MPI to be converted. - * Must have exact limb size that stores a 896-bit MPI - * (double the bitlength of the modulus). Upon return - * holds the reduced value which is in range `0 <= X < - * N` (where N is the modulus). The bitlength of the - * reduced value is the same as that of the modulus - * (448 bits). - * \param[in] X_limbs The length of \p X in limbs. - * - * \return \c 0 on Success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have - * twice as many limbs as the modulus. - * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation - * failed. - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs); - -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ - -/** Initialise a modulus with hard-coded const curve data. - * - * \note The caller is responsible for the \p N modulus' memory. - * mbedtls_mpi_mod_modulus_free(&N) should be invoked at the - * end of its lifecycle. - * - * \param[in,out] N The address of the modulus structure to populate. - * Must be initialized. - * \param[in] id The mbedtls_ecp_group_id for which to initialise the modulus. - * \param[in] ctype The mbedtls_ecp_modulus_type identifier for a coordinate modulus (P) - * or a scalar modulus (N). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the given MPIs do not - * have the correct number of limbs. - * - */ -MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, - const mbedtls_ecp_group_id id, - const mbedtls_ecp_modulus_type ctype); - -#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */ - -#endif /* MBEDTLS_ECP_INVASIVE_H */ diff --git a/vendor/mbedtls/library/entropy.c b/vendor/mbedtls/library/entropy.c deleted file mode 100644 index 7dcf067a5..000000000 --- a/vendor/mbedtls/library/entropy.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * Entropy accumulator implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_ENTROPY_C) - -#include "mbedtls/entropy.h" -#include "entropy_poll.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#include "mbedtls/platform.h" - -#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ - -void mbedtls_entropy_init(mbedtls_entropy_context *ctx) -{ - ctx->source_count = 0; - memset(ctx->source, 0, sizeof(ctx->source)); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&ctx->mutex); -#endif - - ctx->accumulator_started = 0; - mbedtls_md_init(&ctx->accumulator); - - /* Reminder: Update ENTROPY_HAVE_STRONG in the test files - * when adding more strong entropy sources here. */ - -#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) - mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL, - MBEDTLS_ENTROPY_MIN_PLATFORM, - MBEDTLS_ENTROPY_SOURCE_STRONG); -#endif -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL, - MBEDTLS_ENTROPY_MIN_HARDWARE, - MBEDTLS_ENTROPY_SOURCE_STRONG); -#endif -#if defined(MBEDTLS_ENTROPY_NV_SEED) - mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL, - MBEDTLS_ENTROPY_BLOCK_SIZE, - MBEDTLS_ENTROPY_SOURCE_STRONG); - ctx->initial_entropy_run = 0; -#endif -#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ -} - -void mbedtls_entropy_free(mbedtls_entropy_context *ctx) -{ - if (ctx == NULL) { - return; - } - - /* If the context was already free, don't call free() again. - * This is important for mutexes which don't allow double-free. */ - if (ctx->accumulator_started == -1) { - return; - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free(&ctx->mutex); -#endif - mbedtls_md_free(&ctx->accumulator); -#if defined(MBEDTLS_ENTROPY_NV_SEED) - ctx->initial_entropy_run = 0; -#endif - ctx->source_count = 0; - mbedtls_platform_zeroize(ctx->source, sizeof(ctx->source)); - ctx->accumulator_started = -1; -} - -int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx, - mbedtls_entropy_f_source_ptr f_source, void *p_source, - size_t threshold, int strong) -{ - int idx, ret = 0; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - idx = ctx->source_count; - if (idx >= MBEDTLS_ENTROPY_MAX_SOURCES) { - ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES; - goto exit; - } - - ctx->source[idx].f_source = f_source; - ctx->source[idx].p_source = p_source; - ctx->source[idx].threshold = threshold; - ctx->source[idx].strong = strong; - - ctx->source_count++; - -exit: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -/* - * Entropy accumulator update - */ -static int entropy_update(mbedtls_entropy_context *ctx, unsigned char source_id, - const unsigned char *data, size_t len) -{ - unsigned char header[2]; - unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; - size_t use_len = len; - const unsigned char *p = data; - int ret = 0; - - if (use_len > MBEDTLS_ENTROPY_BLOCK_SIZE) { - if ((ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD), - data, len, tmp)) != 0) { - goto cleanup; - } - p = tmp; - use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; - } - - header[0] = source_id; - header[1] = use_len & 0xFF; - - /* - * Start the accumulator if this has not already happened. Note that - * it is sufficient to start the accumulator here only because all calls to - * gather entropy eventually execute this code. - */ - if (ctx->accumulator_started == 0) { - ret = mbedtls_md_setup(&ctx->accumulator, - mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD), 0); - if (ret != 0) { - goto cleanup; - } - ret = mbedtls_md_starts(&ctx->accumulator); - if (ret != 0) { - goto cleanup; - } - ctx->accumulator_started = 1; - } - if ((ret = mbedtls_md_update(&ctx->accumulator, header, 2)) != 0) { - goto cleanup; - } - ret = mbedtls_md_update(&ctx->accumulator, p, use_len); - -cleanup: - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - - return ret; -} - -int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx, - const unsigned char *data, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - ret = entropy_update(ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len); - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -/* - * Run through the different sources to add entropy to our accumulator - */ -static int entropy_gather_internal(mbedtls_entropy_context *ctx) -{ - int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - int i; - int have_one_strong = 0; - unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; - size_t olen; - - if (ctx->source_count == 0) { - return MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED; - } - - /* - * Run through our entropy sources - */ - for (i = 0; i < ctx->source_count; i++) { - if (ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG) { - have_one_strong = 1; - } - - olen = 0; - if ((ret = ctx->source[i].f_source(ctx->source[i].p_source, - buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen)) != 0) { - goto cleanup; - } - - /* - * Add if we actually gathered something - */ - if (olen > 0) { - if ((ret = entropy_update(ctx, (unsigned char) i, - buf, olen)) != 0) { - return ret; - } - ctx->source[i].size += olen; - } - } - - if (have_one_strong == 0) { - ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE; - } - -cleanup: - mbedtls_platform_zeroize(buf, sizeof(buf)); - - return ret; -} - -/* - * Thread-safe wrapper for entropy_gather_internal() - */ -int mbedtls_entropy_gather(mbedtls_entropy_context *ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - ret = entropy_gather_internal(ctx); - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -int mbedtls_entropy_func(void *data, unsigned char *output, size_t len) -{ - int ret, count = 0, i, thresholds_reached; - size_t strong_size; - mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - if (len > MBEDTLS_ENTROPY_BLOCK_SIZE) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - -#if defined(MBEDTLS_ENTROPY_NV_SEED) - /* Update the NV entropy seed before generating any entropy for outside - * use. - */ - if (ctx->initial_entropy_run == 0) { - ctx->initial_entropy_run = 1; - if ((ret = mbedtls_entropy_update_nv_seed(ctx)) != 0) { - return ret; - } - } -#endif - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - /* - * Always gather extra entropy before a call - */ - do { - if (count++ > ENTROPY_MAX_LOOP) { - ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - goto exit; - } - - if ((ret = entropy_gather_internal(ctx)) != 0) { - goto exit; - } - - thresholds_reached = 1; - strong_size = 0; - for (i = 0; i < ctx->source_count; i++) { - if (ctx->source[i].size < ctx->source[i].threshold) { - thresholds_reached = 0; - } - if (ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG) { - strong_size += ctx->source[i].size; - } - } - } while (!thresholds_reached || strong_size < MBEDTLS_ENTROPY_BLOCK_SIZE); - - memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); - - /* - * Note that at this stage it is assumed that the accumulator was started - * in a previous call to entropy_update(). If this is not guaranteed, the - * code below will fail. - */ - if ((ret = mbedtls_md_finish(&ctx->accumulator, buf)) != 0) { - goto exit; - } - - /* - * Reset accumulator and counters and recycle existing entropy - */ - mbedtls_md_free(&ctx->accumulator); - mbedtls_md_init(&ctx->accumulator); - ret = mbedtls_md_setup(&ctx->accumulator, - mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD), 0); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_starts(&ctx->accumulator); - if (ret != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&ctx->accumulator, buf, - MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) { - goto exit; - } - - /* - * Perform second hashing on entropy - */ - if ((ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_ENTROPY_MD), - buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf)) != 0) { - goto exit; - } - - for (i = 0; i < ctx->source_count; i++) { - ctx->source[i].size = 0; - } - - memcpy(output, buf, len); - - ret = 0; - -exit: - mbedtls_platform_zeroize(buf, sizeof(buf)); - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx) -{ - int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - /* Read new seed and write it to NV */ - if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) { - return ret; - } - - if (mbedtls_nv_seed_write(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) < 0) { - return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - } - - /* Manually update the remaining stream with a separator value to diverge */ - memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); - ret = mbedtls_entropy_update_manual(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE); - - return ret; -} -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if defined(MBEDTLS_FS_IO) -int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - FILE *f = NULL; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - - if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) { - ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - goto exit; - } - - if ((f = fopen(path, "wb")) == NULL) { - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - goto exit; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - if (fwrite(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) != MBEDTLS_ENTROPY_BLOCK_SIZE) { - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - goto exit; - } - - ret = 0; - -exit: - mbedtls_platform_zeroize(buf, sizeof(buf)); - - if (f != NULL) { - fclose(f); - } - - return ret; -} - -int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path) -{ - int ret = 0; - FILE *f; - size_t n; - unsigned char buf[MBEDTLS_ENTROPY_MAX_SEED_SIZE]; - - if ((f = fopen(path, "rb")) == NULL) { - return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - fseek(f, 0, SEEK_END); - n = (size_t) ftell(f); - fseek(f, 0, SEEK_SET); - - if (n > MBEDTLS_ENTROPY_MAX_SEED_SIZE) { - n = MBEDTLS_ENTROPY_MAX_SEED_SIZE; - } - - if (fread(buf, 1, n, f) != n) { - ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; - } else { - ret = mbedtls_entropy_update_manual(ctx, buf, n); - } - - fclose(f); - - mbedtls_platform_zeroize(buf, sizeof(buf)); - - if (ret != 0) { - return ret; - } - - return mbedtls_entropy_write_seed_file(ctx, path); -} -#endif /* MBEDTLS_FS_IO */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * Dummy source function - */ -static int entropy_dummy_source(void *data, unsigned char *output, - size_t len, size_t *olen) -{ - ((void) data); - - memset(output, 0x2a, len); - *olen = len; - - return 0; -} - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - -static int mbedtls_entropy_source_self_test_gather(unsigned char *buf, size_t buf_len) -{ - int ret = 0; - size_t entropy_len = 0; - size_t olen = 0; - size_t attempts = buf_len; - - while (attempts > 0 && entropy_len < buf_len) { - if ((ret = mbedtls_hardware_poll(NULL, buf + entropy_len, - buf_len - entropy_len, &olen)) != 0) { - return ret; - } - - entropy_len += olen; - attempts--; - } - - if (entropy_len < buf_len) { - ret = 1; - } - - return ret; -} - - -static int mbedtls_entropy_source_self_test_check_bits(const unsigned char *buf, - size_t buf_len) -{ - unsigned char set = 0xFF; - unsigned char unset = 0x00; - size_t i; - - for (i = 0; i < buf_len; i++) { - set &= buf[i]; - unset |= buf[i]; - } - - return set == 0xFF || unset == 0x00; -} - -/* - * A test to ensure that the entropy sources are functioning correctly - * and there is no obvious failure. The test performs the following checks: - * - The entropy source is not providing only 0s (all bits unset) or 1s (all - * bits set). - * - The entropy source is not providing values in a pattern. Because the - * hardware could be providing data in an arbitrary length, this check polls - * the hardware entropy source twice and compares the result to ensure they - * are not equal. - * - The error code returned by the entropy source is not an error. - */ -int mbedtls_entropy_source_self_test(int verbose) -{ - int ret = 0; - unsigned char buf0[2 * sizeof(unsigned long long int)]; - unsigned char buf1[2 * sizeof(unsigned long long int)]; - - if (verbose != 0) { - mbedtls_printf(" ENTROPY_BIAS test: "); - } - - memset(buf0, 0x00, sizeof(buf0)); - memset(buf1, 0x00, sizeof(buf1)); - - if ((ret = mbedtls_entropy_source_self_test_gather(buf0, sizeof(buf0))) != 0) { - goto cleanup; - } - if ((ret = mbedtls_entropy_source_self_test_gather(buf1, sizeof(buf1))) != 0) { - goto cleanup; - } - - /* Make sure that the returned values are not all 0 or 1 */ - if ((ret = mbedtls_entropy_source_self_test_check_bits(buf0, sizeof(buf0))) != 0) { - goto cleanup; - } - if ((ret = mbedtls_entropy_source_self_test_check_bits(buf1, sizeof(buf1))) != 0) { - goto cleanup; - } - - /* Make sure that the entropy source is not returning values in a - * pattern */ - ret = memcmp(buf0, buf1, sizeof(buf0)) == 0; - -cleanup: - if (verbose != 0) { - if (ret != 0) { - mbedtls_printf("failed\n"); - } else { - mbedtls_printf("passed\n"); - } - - mbedtls_printf("\n"); - } - - return ret != 0; -} - -#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ - -/* - * The actual entropy quality is hard to test, but we can at least - * test that the functions don't cause errors and write the correct - * amount of data to buffers. - */ -int mbedtls_entropy_self_test(int verbose) -{ - int ret = 1; - mbedtls_entropy_context ctx; - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; - unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; - size_t i, j; - - if (verbose != 0) { - mbedtls_printf(" ENTROPY test: "); - } - - mbedtls_entropy_init(&ctx); - - /* First do a gather to make sure we have default sources */ - if ((ret = mbedtls_entropy_gather(&ctx)) != 0) { - goto cleanup; - } - - ret = mbedtls_entropy_add_source(&ctx, entropy_dummy_source, NULL, 16, - MBEDTLS_ENTROPY_SOURCE_WEAK); - if (ret != 0) { - goto cleanup; - } - - if ((ret = mbedtls_entropy_update_manual(&ctx, buf, sizeof(buf))) != 0) { - goto cleanup; - } - - /* - * To test that mbedtls_entropy_func writes correct number of bytes: - * - use the whole buffer and rely on ASan to detect overruns - * - collect entropy 8 times and OR the result in an accumulator: - * any byte should then be 0 with probably 2^(-64), so requiring - * each of the 32 or 64 bytes to be non-zero has a false failure rate - * of at most 2^(-58) which is acceptable. - */ - for (i = 0; i < 8; i++) { - if ((ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf))) != 0) { - goto cleanup; - } - - for (j = 0; j < sizeof(buf); j++) { - acc[j] |= buf[j]; - } - } - - for (j = 0; j < sizeof(buf); j++) { - if (acc[j] == 0) { - ret = 1; - goto cleanup; - } - } - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - if ((ret = mbedtls_entropy_source_self_test(0)) != 0) { - goto cleanup; - } -#endif - -cleanup: - mbedtls_entropy_free(&ctx); - - if (verbose != 0) { - if (ret != 0) { - mbedtls_printf("failed\n"); - } else { - mbedtls_printf("passed\n"); - } - - mbedtls_printf("\n"); - } - - return ret != 0; -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_ENTROPY_C */ diff --git a/vendor/mbedtls/library/entropy_poll.c b/vendor/mbedtls/library/entropy_poll.c deleted file mode 100644 index 1c8a29d6e..000000000 --- a/vendor/mbedtls/library/entropy_poll.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Platform-specific and custom entropy polling functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#if defined(__linux__) || defined(__midipix__) -/* Ensure that syscall() is available even when compiling with -std=c99 */ -#if !defined(_GNU_SOURCE) -#define _GNU_SOURCE -#endif -#endif - -#include "common.h" - -#include - -#if defined(MBEDTLS_ENTROPY_C) - -#include "mbedtls/entropy.h" -#include "entropy_poll.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_TIMING_C) -#include "mbedtls/timing.h" -#endif -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) - -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) && !defined(__midipix__) && !defined(__MVS__) -#error \ - "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in mbedtls_config.h" -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -#include -#include -#include - -int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, - size_t *olen) -{ - ((void) data); - *olen = 0; - - /* - * BCryptGenRandom takes ULONG for size, which is smaller than size_t on - * 64-bit Windows platforms. Extract entropy in chunks of len (dependent - * on ULONG_MAX) size. - */ - while (len != 0) { - unsigned long ulong_bytes = - (len > ULONG_MAX) ? ULONG_MAX : (unsigned long) len; - - if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, ulong_bytes, - BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - - *olen += ulong_bytes; - len -= ulong_bytes; - } - - return 0; -} -#else /* _WIN32 && !EFIX64 && !EFI32 */ - -/* - * Test for Linux getrandom() support. - * Since there is no wrapper in the libc yet, use the generic syscall wrapper - * available in GNU libc and compatible libc's (eg uClibc). - */ -#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__midipix__)) -#include -#include -#if defined(SYS_getrandom) -#define HAVE_GETRANDOM -#include - -static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags) -{ - /* MemSan cannot understand that the syscall writes to the buffer */ -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) - memset(buf, 0, buflen); -#endif -#endif - return (int) syscall(SYS_getrandom, buf, buflen, flags); -} -#endif /* SYS_getrandom */ -#endif /* __linux__ || __midipix__ */ - -#if defined(__FreeBSD__) || defined(__DragonFly__) -#include -#if (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || \ - (defined(__DragonFly__) && __DragonFly_version >= 500700) -#include -#include -#define HAVE_GETRANDOM -static int getrandom_wrapper(void *buf, size_t buflen, unsigned int flags) -{ - return (int) getrandom(buf, buflen, flags); -} -#endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) || - (__DragonFly__ && __DragonFly_version >= 500700) */ -#endif /* __FreeBSD__ || __DragonFly__ */ - -/* - * Some BSD systems provide KERN_ARND. - * This is equivalent to reading from /dev/urandom, only it doesn't require an - * open file descriptor, and provides up to 256 bytes per call (basically the - * same as getentropy(), but with a longer history). - * - * Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7 - */ -#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM) -#include -#include -#if defined(KERN_ARND) -#define HAVE_SYSCTL_ARND - -static int sysctl_arnd_wrapper(unsigned char *buf, size_t buflen) -{ - int name[2]; - size_t len; - - name[0] = CTL_KERN; - name[1] = KERN_ARND; - - while (buflen > 0) { - len = buflen > 256 ? 256 : buflen; - if (sysctl(name, 2, buf, &len, NULL, 0) == -1) { - return -1; - } - buflen -= len; - buf += len; - } - return 0; -} -#endif /* KERN_ARND */ -#endif /* __FreeBSD__ || __NetBSD__ */ - -#include - -const char *mbedtls_platform_dev_random = MBEDTLS_PLATFORM_DEV_RANDOM; - -int mbedtls_platform_entropy_poll(void *data, - unsigned char *output, size_t len, size_t *olen) -{ - FILE *file; - size_t read_len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ((void) data); - -#if defined(HAVE_GETRANDOM) - ret = getrandom_wrapper(output, len, 0); - if (ret >= 0) { - *olen = (size_t) ret; - return 0; - } else if (errno != ENOSYS) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - /* Fall through if the system call isn't known. */ -#else - ((void) ret); -#endif /* HAVE_GETRANDOM */ - -#if defined(HAVE_SYSCTL_ARND) - ((void) file); - ((void) read_len); - if (sysctl_arnd_wrapper(output, len) == -1) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - *olen = len; - return 0; -#else - - *olen = 0; - - file = fopen(mbedtls_platform_dev_random, "rb"); - if (file == NULL) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(file, NULL); - - read_len = fread(output, 1, len, file); - if (read_len != len) { - fclose(file); - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - - fclose(file); - *olen = len; - - return 0; -#endif /* HAVE_SYSCTL_ARND */ -} -#endif /* _WIN32 && !EFIX64 && !EFI32 */ -#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -int mbedtls_nv_seed_poll(void *data, - unsigned char *output, size_t len, size_t *olen) -{ - unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; - size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; - ((void) data); - - memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); - - if (mbedtls_nv_seed_read(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) < 0) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } - - if (len < use_len) { - use_len = len; - } - - memcpy(output, buf, use_len); - *olen = use_len; - - return 0; -} -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#endif /* MBEDTLS_ENTROPY_C */ diff --git a/vendor/mbedtls/library/entropy_poll.h b/vendor/mbedtls/library/entropy_poll.h deleted file mode 100644 index 6b4aec03e..000000000 --- a/vendor/mbedtls/library/entropy_poll.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * \file entropy_poll.h - * - * \brief Platform-specific and custom entropy polling functions - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_ENTROPY_POLL_H -#define MBEDTLS_ENTROPY_POLL_H - -#include "mbedtls/build_info.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Default thresholds for built-in sources, in bytes - */ -#define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */ -#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE) -#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */ -#endif - -#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) -/** - * \brief Platform-specific entropy poll callback - */ -int mbedtls_platform_entropy_poll(void *data, - unsigned char *output, size_t len, size_t *olen); -#endif - -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) -/** - * \brief Entropy poll callback for a hardware source - * - * \warning This is not provided by Mbed TLS! - * See \c MBEDTLS_ENTROPY_HARDWARE_ALT in mbedtls_config.h. - * - * \note This must accept NULL as its first argument. - */ -int mbedtls_hardware_poll(void *data, - unsigned char *output, size_t len, size_t *olen); -#endif - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -/** - * \brief Entropy poll callback for a non-volatile seed file - * - * \note This must accept NULL as its first argument. - */ -int mbedtls_nv_seed_poll(void *data, - unsigned char *output, size_t len, size_t *olen); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* entropy_poll.h */ diff --git a/vendor/mbedtls/library/error.c b/vendor/mbedtls/library/error.c deleted file mode 100644 index 297eccd03..000000000 --- a/vendor/mbedtls/library/error.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * Error message information - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#include "mbedtls/error.h" - -#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) - -#if defined(MBEDTLS_ERROR_C) - -#include "mbedtls/platform.h" - -#include -#include - -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#endif - -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#endif - -#if defined(MBEDTLS_BASE64_C) -#include "mbedtls/base64.h" -#endif - -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" -#endif - -#if defined(MBEDTLS_CIPHER_C) -#include "mbedtls/cipher.h" -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) -#include "mbedtls/ctr_drbg.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_DHM_C) -#include "mbedtls/dhm.h" -#endif - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_ENTROPY_C) -#include "mbedtls/entropy.h" -#endif - -#if defined(MBEDTLS_ERROR_C) -#include "mbedtls/error.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_HKDF_C) -#include "mbedtls/hkdf.h" -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) -#include "mbedtls/hmac_drbg.h" -#endif - -#if defined(MBEDTLS_LMS_C) -#include "mbedtls/lms.h" -#endif - -#if defined(MBEDTLS_MD_C) -#include "mbedtls/md.h" -#endif - -#if defined(MBEDTLS_NET_C) -#include "mbedtls/net_sockets.h" -#endif - -#if defined(MBEDTLS_OID_C) -#include "mbedtls/oid.h" -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk.h" -#endif - -#if defined(MBEDTLS_PKCS12_C) -#include "mbedtls/pkcs12.h" -#endif - -#if defined(MBEDTLS_PKCS5_C) -#include "mbedtls/pkcs5.h" -#endif - -#if defined(MBEDTLS_PKCS7_C) -#include "mbedtls/pkcs7.h" -#endif - -#if defined(MBEDTLS_POLY1305_C) -#include "mbedtls/poly1305.h" -#endif - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "mbedtls/sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "mbedtls/sha256.h" -#endif - -#if defined(MBEDTLS_SHA3_C) -#include "mbedtls/sha3.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "mbedtls/sha512.h" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) -#include "mbedtls/ssl.h" -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -#include "mbedtls/x509.h" -#endif - - -const char *mbedtls_high_level_strerr(int error_code) -{ - int high_level_error_code; - - if (error_code < 0) { - error_code = -error_code; - } - - /* Extract the high-level part from the error code. */ - high_level_error_code = error_code & 0xFF80; - - switch (high_level_error_code) { - /* Begin Auto-Generated Code. */ - #if defined(MBEDTLS_CIPHER_C) - case -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE): - return( "CIPHER - The selected feature is not available" ); - case -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA): - return( "CIPHER - Bad input parameters" ); - case -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED): - return( "CIPHER - Failed to allocate memory" ); - case -(MBEDTLS_ERR_CIPHER_INVALID_PADDING): - return( "CIPHER - Input data contains invalid padding and is rejected" ); - case -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED): - return( "CIPHER - Decryption of block requires a full block" ); - case -(MBEDTLS_ERR_CIPHER_AUTH_FAILED): - return( "CIPHER - Authentication failed (for AEAD modes)" ); - case -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT): - return( "CIPHER - The context is invalid. For example, because it was freed" ); -#endif /* MBEDTLS_CIPHER_C */ - -#if defined(MBEDTLS_DHM_C) - case -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA): - return( "DHM - Bad input parameters" ); - case -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED): - return( "DHM - Reading of the DHM parameters failed" ); - case -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED): - return( "DHM - Making of the DHM parameters failed" ); - case -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED): - return( "DHM - Reading of the public values failed" ); - case -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED): - return( "DHM - Making of the public value failed" ); - case -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED): - return( "DHM - Calculation of the DHM secret failed" ); - case -(MBEDTLS_ERR_DHM_INVALID_FORMAT): - return( "DHM - The ASN.1 data is not formatted correctly" ); - case -(MBEDTLS_ERR_DHM_ALLOC_FAILED): - return( "DHM - Allocation of memory failed" ); - case -(MBEDTLS_ERR_DHM_FILE_IO_ERROR): - return( "DHM - Read or write of file failed" ); - case -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED): - return( "DHM - Setting the modulus and generator failed" ); -#endif /* MBEDTLS_DHM_C */ - -#if defined(MBEDTLS_ECP_C) - case -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA): - return( "ECP - Bad input parameters to function" ); - case -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL): - return( "ECP - The buffer is too small to write to" ); - case -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE): - return( "ECP - The requested feature is not available, for example, the requested curve is not supported" ); - case -(MBEDTLS_ERR_ECP_VERIFY_FAILED): - return( "ECP - The signature is not valid" ); - case -(MBEDTLS_ERR_ECP_ALLOC_FAILED): - return( "ECP - Memory allocation failed" ); - case -(MBEDTLS_ERR_ECP_RANDOM_FAILED): - return( "ECP - Generation of random value, such as ephemeral key, failed" ); - case -(MBEDTLS_ERR_ECP_INVALID_KEY): - return( "ECP - Invalid private or public key" ); - case -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH): - return( "ECP - The buffer contains a valid signature followed by more data" ); - case -(MBEDTLS_ERR_ECP_IN_PROGRESS): - return( "ECP - Operation in progress, call again with the same parameters to continue" ); -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_MD_C) - case -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE): - return( "MD - The selected feature is not available" ); - case -(MBEDTLS_ERR_MD_BAD_INPUT_DATA): - return( "MD - Bad input parameters to function" ); - case -(MBEDTLS_ERR_MD_ALLOC_FAILED): - return( "MD - Failed to allocate memory" ); - case -(MBEDTLS_ERR_MD_FILE_IO_ERROR): - return( "MD - Opening or reading of file failed" ); -#endif /* MBEDTLS_MD_C */ - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) - case -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT): - return( "PEM - No PEM header or footer found" ); - case -(MBEDTLS_ERR_PEM_INVALID_DATA): - return( "PEM - PEM string is not as expected" ); - case -(MBEDTLS_ERR_PEM_ALLOC_FAILED): - return( "PEM - Failed to allocate memory" ); - case -(MBEDTLS_ERR_PEM_INVALID_ENC_IV): - return( "PEM - RSA IV is not in hex-format" ); - case -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG): - return( "PEM - Unsupported key encryption algorithm" ); - case -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED): - return( "PEM - Private key password can't be empty" ); - case -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH): - return( "PEM - Given private key password does not allow for correct decryption" ); - case -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE): - return( "PEM - Unavailable feature, e.g. hashing/encryption combination" ); - case -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA): - return( "PEM - Bad input parameters to function" ); -#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ - -#if defined(MBEDTLS_PK_C) - case -(MBEDTLS_ERR_PK_ALLOC_FAILED): - return( "PK - Memory allocation failed" ); - case -(MBEDTLS_ERR_PK_TYPE_MISMATCH): - return( "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" ); - case -(MBEDTLS_ERR_PK_BAD_INPUT_DATA): - return( "PK - Bad input parameters to function" ); - case -(MBEDTLS_ERR_PK_FILE_IO_ERROR): - return( "PK - Read/write of file failed" ); - case -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION): - return( "PK - Unsupported key version" ); - case -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT): - return( "PK - Invalid key tag or value" ); - case -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG): - return( "PK - Key algorithm is unsupported (only RSA and EC are supported)" ); - case -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED): - return( "PK - Private key password can't be empty" ); - case -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH): - return( "PK - Given private key password does not allow for correct decryption" ); - case -(MBEDTLS_ERR_PK_INVALID_PUBKEY): - return( "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" ); - case -(MBEDTLS_ERR_PK_INVALID_ALG): - return( "PK - The algorithm tag or value is invalid" ); - case -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE): - return( "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); - case -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE): - return( "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); - case -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH): - return( "PK - The buffer contains a valid signature followed by more data" ); - case -(MBEDTLS_ERR_PK_BUFFER_TOO_SMALL): - return( "PK - The output buffer is too small" ); -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_PKCS12_C) - case -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA): - return( "PKCS12 - Bad input parameters to function" ); - case -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE): - return( "PKCS12 - Feature not available, e.g. unsupported encryption scheme" ); - case -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT): - return( "PKCS12 - PBE ASN.1 data not as expected" ); - case -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH): - return( "PKCS12 - Given private key password does not allow for correct decryption" ); -#endif /* MBEDTLS_PKCS12_C */ - -#if defined(MBEDTLS_PKCS5_C) - case -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA): - return( "PKCS5 - Bad input parameters to function" ); - case -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT): - return( "PKCS5 - Unexpected ASN.1 data" ); - case -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE): - return( "PKCS5 - Requested encryption or digest alg not available" ); - case -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH): - return( "PKCS5 - Given private key password does not allow for correct decryption" ); -#endif /* MBEDTLS_PKCS5_C */ - -#if defined(MBEDTLS_PKCS7_C) - case -(MBEDTLS_ERR_PKCS7_INVALID_FORMAT): - return( "PKCS7 - The format is invalid, e.g. different type expected" ); - case -(MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE): - return( "PKCS7 - Unavailable feature, e.g. anything other than signed data" ); - case -(MBEDTLS_ERR_PKCS7_INVALID_VERSION): - return( "PKCS7 - The PKCS #7 version element is invalid or cannot be parsed" ); - case -(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO): - return( "PKCS7 - The PKCS #7 content info is invalid or cannot be parsed" ); - case -(MBEDTLS_ERR_PKCS7_INVALID_ALG): - return( "PKCS7 - The algorithm tag or value is invalid or cannot be parsed" ); - case -(MBEDTLS_ERR_PKCS7_INVALID_CERT): - return( "PKCS7 - The certificate tag or value is invalid or cannot be parsed" ); - case -(MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE): - return( "PKCS7 - Error parsing the signature" ); - case -(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO): - return( "PKCS7 - Error parsing the signer's info" ); - case -(MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA): - return( "PKCS7 - Input invalid" ); - case -(MBEDTLS_ERR_PKCS7_ALLOC_FAILED): - return( "PKCS7 - Allocation of memory failed" ); - case -(MBEDTLS_ERR_PKCS7_VERIFY_FAIL): - return( "PKCS7 - Verification Failed" ); - case -(MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID): - return( "PKCS7 - The PKCS #7 date issued/expired dates are invalid" ); -#endif /* MBEDTLS_PKCS7_C */ - -#if defined(MBEDTLS_RSA_C) - case -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA): - return( "RSA - Bad input parameters to function" ); - case -(MBEDTLS_ERR_RSA_INVALID_PADDING): - return( "RSA - Input data contains invalid padding and is rejected" ); - case -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED): - return( "RSA - Something failed during generation of a key" ); - case -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED): - return( "RSA - Key failed to pass the validity check of the library" ); - case -(MBEDTLS_ERR_RSA_PUBLIC_FAILED): - return( "RSA - The public key operation failed" ); - case -(MBEDTLS_ERR_RSA_PRIVATE_FAILED): - return( "RSA - The private key operation failed" ); - case -(MBEDTLS_ERR_RSA_VERIFY_FAILED): - return( "RSA - The PKCS#1 verification failed" ); - case -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE): - return( "RSA - The output buffer for decryption is not large enough" ); - case -(MBEDTLS_ERR_RSA_RNG_FAILED): - return( "RSA - The random generator failed to generate non-zeros" ); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_SSL_TLS_C) - case -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS): - return( "SSL - A cryptographic operation is in progress. Try again later" ); - case -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE): - return( "SSL - The requested feature is not available" ); - case -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA): - return( "SSL - Bad input parameters to function" ); - case -(MBEDTLS_ERR_SSL_INVALID_MAC): - return( "SSL - Verification of the message MAC failed" ); - case -(MBEDTLS_ERR_SSL_INVALID_RECORD): - return( "SSL - An invalid SSL record was received" ); - case -(MBEDTLS_ERR_SSL_CONN_EOF): - return( "SSL - The connection indicated an EOF" ); - case -(MBEDTLS_ERR_SSL_DECODE_ERROR): - return( "SSL - A message could not be parsed due to a syntactic error" ); - case -(MBEDTLS_ERR_SSL_NO_RNG): - return( "SSL - No RNG was provided to the SSL module" ); - case -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE): - return( "SSL - No client certification received from the client, but required by the authentication mode" ); - case -(MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION): - return( "SSL - Client received an extended server hello containing an unsupported extension" ); - case -(MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL): - return( "SSL - No ALPN protocols supported that the client advertises" ); - case -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED): - return( "SSL - The own private key or pre-shared key is not set, but needed" ); - case -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED): - return( "SSL - No CA Chain is set, but required to operate" ); - case -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE): - return( "SSL - An unexpected message was received from our peer" ); - case -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE): - return( "SSL - A fatal alert message was received from our peer" ); - case -(MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME): - return( "SSL - No server could be identified matching the client's SNI" ); - case -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY): - return( "SSL - The peer notified us that the connection is going to be closed" ); - case -(MBEDTLS_ERR_SSL_BAD_CERTIFICATE): - return( "SSL - Processing of the Certificate handshake message failed" ); - case -(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET): - return( "SSL - A TLS 1.3 NewSessionTicket message has been received" ); - case -(MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA): - return( "SSL - Not possible to read early data" ); - case -(MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA): - return( "SSL - * Early data has been received as part of an on-going handshake. This error code can be returned only on server side if and only if early data has been enabled by means of the mbedtls_ssl_conf_early_data() API. This error code can then be returned by mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write() if early data has been received as part of the handshake sequence they triggered. To read the early data, call mbedtls_ssl_read_early_data()" ); - case -(MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA): - return( "SSL - Not possible to write early data" ); - case -(MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND): - return( "SSL - Cache entry not found" ); - case -(MBEDTLS_ERR_SSL_ALLOC_FAILED): - return( "SSL - Memory allocation failed" ); - case -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED): - return( "SSL - Hardware acceleration function returned with error" ); - case -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH): - return( "SSL - Hardware acceleration function skipped / left alone data" ); - case -(MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION): - return( "SSL - Handshake protocol not within min/max boundaries" ); - case -(MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE): - return( "SSL - The handshake negotiation failed" ); - case -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED): - return( "SSL - Session ticket has expired" ); - case -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH): - return( "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); - case -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY): - return( "SSL - Unknown identity received (eg, PSK identity)" ); - case -(MBEDTLS_ERR_SSL_INTERNAL_ERROR): - return( "SSL - Internal error (eg, unexpected failure in lower-level module)" ); - case -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING): - return( "SSL - A counter would wrap (eg, too many messages exchanged)" ); - case -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO): - return( "SSL - Unexpected message at ServerHello in renegotiation" ); - case -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED): - return( "SSL - DTLS client must retry for hello verification" ); - case -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL): - return( "SSL - A buffer is too small to receive or write a message" ); - case -(MBEDTLS_ERR_SSL_WANT_READ): - return( "SSL - No data of requested type currently available on underlying transport" ); - case -(MBEDTLS_ERR_SSL_WANT_WRITE): - return( "SSL - Connection requires a write call" ); - case -(MBEDTLS_ERR_SSL_TIMEOUT): - return( "SSL - The operation timed out" ); - case -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT): - return( "SSL - The client initiated a reconnect from the same port" ); - case -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD): - return( "SSL - Record header looks valid but is not expected" ); - case -(MBEDTLS_ERR_SSL_NON_FATAL): - return( "SSL - The alert message received indicates a non-fatal error" ); - case -(MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER): - return( "SSL - A field in a message was incorrect or inconsistent with other fields" ); - case -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING): - return( "SSL - Internal-only message signaling that further message-processing should be done" ); - case -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS): - return( "SSL - The asynchronous operation is not completed yet" ); - case -(MBEDTLS_ERR_SSL_EARLY_MESSAGE): - return( "SSL - Internal-only message signaling that a message arrived early" ); - case -(MBEDTLS_ERR_SSL_UNEXPECTED_CID): - return( "SSL - An encrypted DTLS-frame with an unexpected CID was received" ); - case -(MBEDTLS_ERR_SSL_VERSION_MISMATCH): - return( "SSL - An operation failed due to an unexpected version or configuration" ); - case -(MBEDTLS_ERR_SSL_BAD_CONFIG): - return( "SSL - Invalid value in SSL config" ); - case -(MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME): - return( "SSL - Attempt to verify a certificate without an expected hostname. This is usually insecure. In TLS clients, when a client authenticates a server through its certificate, the client normally checks three things: - the certificate chain must be valid; - the chain must start from a trusted CA; - the certificate must cover the server name that is expected by the client. Omitting any of these checks is generally insecure, and can allow a malicious server to impersonate a legitimate server. The third check may be safely skipped in some unusual scenarios, such as networks where eavesdropping is a risk but not active attacks, or a private PKI where the client equally trusts all servers that are accredited by the root CA. You should call mbedtls_ssl_set_hostname() with the expected server name before starting a TLS handshake on a client (unless the client is set up to only use PSK-based authentication, which does not rely on the host name). If you have determined that server name verification is not required for security in your scenario, call mbedtls_ssl_set_hostname() with \\p NULL as the server name. This error is raised if all of the following conditions are met: - A TLS client is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED (default). - Certificate authentication is enabled. - The client does not call mbedtls_ssl_set_hostname(). - The configuration option #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME is not enabled" ); -#endif /* MBEDTLS_SSL_TLS_C */ - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) - case -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE): - return( "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" ); - case -(MBEDTLS_ERR_X509_UNKNOWN_OID): - return( "X509 - Requested OID is unknown" ); - case -(MBEDTLS_ERR_X509_INVALID_FORMAT): - return( "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" ); - case -(MBEDTLS_ERR_X509_INVALID_VERSION): - return( "X509 - The CRT/CRL/CSR version element is invalid" ); - case -(MBEDTLS_ERR_X509_INVALID_SERIAL): - return( "X509 - The serial tag or value is invalid" ); - case -(MBEDTLS_ERR_X509_INVALID_ALG): - return( "X509 - The algorithm tag or value is invalid" ); - case -(MBEDTLS_ERR_X509_INVALID_NAME): - return( "X509 - The name tag or value is invalid" ); - case -(MBEDTLS_ERR_X509_INVALID_DATE): - return( "X509 - The date tag or value is invalid" ); - case -(MBEDTLS_ERR_X509_INVALID_SIGNATURE): - return( "X509 - The signature tag or value invalid" ); - case -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS): - return( "X509 - The extension tag or value is invalid" ); - case -(MBEDTLS_ERR_X509_UNKNOWN_VERSION): - return( "X509 - CRT/CRL/CSR has an unsupported version number" ); - case -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG): - return( "X509 - Signature algorithm (oid) is unsupported" ); - case -(MBEDTLS_ERR_X509_SIG_MISMATCH): - return( "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" ); - case -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED): - return( "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" ); - case -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT): - return( "X509 - Format not recognized as DER or PEM" ); - case -(MBEDTLS_ERR_X509_BAD_INPUT_DATA): - return( "X509 - Input invalid" ); - case -(MBEDTLS_ERR_X509_ALLOC_FAILED): - return( "X509 - Allocation of memory failed" ); - case -(MBEDTLS_ERR_X509_FILE_IO_ERROR): - return( "X509 - Read/write of file failed" ); - case -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL): - return( "X509 - Destination buffer is too small" ); - case -(MBEDTLS_ERR_X509_FATAL_ERROR): - return( "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" ); -#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ - /* End Auto-Generated Code. */ - - default: - break; - } - - return NULL; -} - -const char *mbedtls_low_level_strerr(int error_code) -{ - int low_level_error_code; - - if (error_code < 0) { - error_code = -error_code; - } - - /* Extract the low-level part from the error code. */ - low_level_error_code = error_code & ~0xFF80; - - switch (low_level_error_code) { - /* Begin Auto-Generated Code. */ - #if defined(MBEDTLS_AES_C) - case -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH): - return( "AES - Invalid key length" ); - case -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH): - return( "AES - Invalid data input length" ); - case -(MBEDTLS_ERR_AES_BAD_INPUT_DATA): - return( "AES - Invalid input data" ); -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_ARIA_C) - case -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA): - return( "ARIA - Bad input data" ); - case -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH): - return( "ARIA - Invalid data input length" ); -#endif /* MBEDTLS_ARIA_C */ - -#if defined(MBEDTLS_ASN1_PARSE_C) - case -(MBEDTLS_ERR_ASN1_OUT_OF_DATA): - return( "ASN1 - Out of data when parsing an ASN1 data structure" ); - case -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG): - return( "ASN1 - ASN1 tag was of an unexpected value" ); - case -(MBEDTLS_ERR_ASN1_INVALID_LENGTH): - return( "ASN1 - Error when trying to determine the length or invalid length" ); - case -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH): - return( "ASN1 - Actual length differs from expected length" ); - case -(MBEDTLS_ERR_ASN1_INVALID_DATA): - return( "ASN1 - Data is invalid" ); - case -(MBEDTLS_ERR_ASN1_ALLOC_FAILED): - return( "ASN1 - Memory allocation failed" ); - case -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL): - return( "ASN1 - Buffer too small when writing ASN.1 data structure" ); -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#if defined(MBEDTLS_BASE64_C) - case -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL): - return( "BASE64 - Output buffer too small" ); - case -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER): - return( "BASE64 - Invalid character in input" ); -#endif /* MBEDTLS_BASE64_C */ - -#if defined(MBEDTLS_BIGNUM_C) - case -(MBEDTLS_ERR_MPI_FILE_IO_ERROR): - return( "BIGNUM - An error occurred while reading from or writing to a file" ); - case -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA): - return( "BIGNUM - Bad input parameters to function" ); - case -(MBEDTLS_ERR_MPI_INVALID_CHARACTER): - return( "BIGNUM - There is an invalid character in the digit string" ); - case -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL): - return( "BIGNUM - The buffer is too small to write to" ); - case -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE): - return( "BIGNUM - The input arguments are negative or result in illegal output" ); - case -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO): - return( "BIGNUM - The input argument for division is zero, which is not allowed" ); - case -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE): - return( "BIGNUM - The input arguments are not acceptable" ); - case -(MBEDTLS_ERR_MPI_ALLOC_FAILED): - return( "BIGNUM - Memory allocation failed" ); -#endif /* MBEDTLS_BIGNUM_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - case -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA): - return( "CAMELLIA - Bad input data" ); - case -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH): - return( "CAMELLIA - Invalid data input length" ); -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_CCM_C) - case -(MBEDTLS_ERR_CCM_BAD_INPUT): - return( "CCM - Bad input parameters to the function" ); - case -(MBEDTLS_ERR_CCM_AUTH_FAILED): - return( "CCM - Authenticated decryption failed" ); -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_CHACHA20_C) - case -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA): - return( "CHACHA20 - Invalid input parameter(s)" ); -#endif /* MBEDTLS_CHACHA20_C */ - -#if defined(MBEDTLS_CHACHAPOLY_C) - case -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE): - return( "CHACHAPOLY - The requested operation is not permitted in the current state" ); - case -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED): - return( "CHACHAPOLY - Authenticated decryption failed: data was not authentic" ); -#endif /* MBEDTLS_CHACHAPOLY_C */ - -#if defined(MBEDTLS_CTR_DRBG_C) - case -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED): - return( "CTR_DRBG - The entropy source failed" ); - case -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG): - return( "CTR_DRBG - The requested random buffer length is too big" ); - case -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG): - return( "CTR_DRBG - The input (entropy + additional data) is too large" ); - case -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR): - return( "CTR_DRBG - Read or write error in file" ); -#endif /* MBEDTLS_CTR_DRBG_C */ - -#if defined(MBEDTLS_DES_C) - case -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH): - return( "DES - The data input has an invalid length" ); -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ENTROPY_C) - case -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED): - return( "ENTROPY - Critical entropy source failure" ); - case -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES): - return( "ENTROPY - No more sources can be added" ); - case -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED): - return( "ENTROPY - No sources have been added to poll" ); - case -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE): - return( "ENTROPY - No strong sources have been added to poll" ); - case -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR): - return( "ENTROPY - Read/write error in file" ); -#endif /* MBEDTLS_ENTROPY_C */ - -#if defined(MBEDTLS_ERROR_C) - case -(MBEDTLS_ERR_ERROR_GENERIC_ERROR): - return( "ERROR - Generic error" ); - case -(MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED): - return( "ERROR - This is a bug in the library" ); -#endif /* MBEDTLS_ERROR_C */ - -#if defined(MBEDTLS_PLATFORM_C) - case -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED): - return( "PLATFORM - Hardware accelerator failed" ); - case -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED): - return( "PLATFORM - The requested feature is not supported by the platform" ); -#endif /* MBEDTLS_PLATFORM_C */ - -#if defined(MBEDTLS_GCM_C) - case -(MBEDTLS_ERR_GCM_AUTH_FAILED): - return( "GCM - Authenticated decryption failed" ); - case -(MBEDTLS_ERR_GCM_BAD_INPUT): - return( "GCM - Bad input parameters to function" ); - case -(MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL): - return( "GCM - An output buffer is too small" ); -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_HKDF_C) - case -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA): - return( "HKDF - Bad input parameters to function" ); -#endif /* MBEDTLS_HKDF_C */ - -#if defined(MBEDTLS_HMAC_DRBG_C) - case -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG): - return( "HMAC_DRBG - Too many random requested in single call" ); - case -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG): - return( "HMAC_DRBG - Input too large (Entropy + additional)" ); - case -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR): - return( "HMAC_DRBG - Read/write error in file" ); - case -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED): - return( "HMAC_DRBG - The entropy source failed" ); -#endif /* MBEDTLS_HMAC_DRBG_C */ - -#if defined(MBEDTLS_LMS_C) - case -(MBEDTLS_ERR_LMS_BAD_INPUT_DATA): - return( "LMS - Bad data has been input to an LMS function" ); - case -(MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS): - return( "LMS - Specified LMS key has utilised all of its private keys" ); - case -(MBEDTLS_ERR_LMS_VERIFY_FAILED): - return( "LMS - LMS signature verification failed" ); - case -(MBEDTLS_ERR_LMS_ALLOC_FAILED): - return( "LMS - LMS failed to allocate space for a private key" ); - case -(MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL): - return( "LMS - Input/output buffer is too small to contain requited data" ); -#endif /* MBEDTLS_LMS_C */ - -#if defined(MBEDTLS_NET_C) - case -(MBEDTLS_ERR_NET_SOCKET_FAILED): - return( "NET - Failed to open a socket" ); - case -(MBEDTLS_ERR_NET_CONNECT_FAILED): - return( "NET - The connection to the given server / port failed" ); - case -(MBEDTLS_ERR_NET_BIND_FAILED): - return( "NET - Binding of the socket failed" ); - case -(MBEDTLS_ERR_NET_LISTEN_FAILED): - return( "NET - Could not listen on the socket" ); - case -(MBEDTLS_ERR_NET_ACCEPT_FAILED): - return( "NET - Could not accept the incoming connection" ); - case -(MBEDTLS_ERR_NET_RECV_FAILED): - return( "NET - Reading information from the socket failed" ); - case -(MBEDTLS_ERR_NET_SEND_FAILED): - return( "NET - Sending information through the socket failed" ); - case -(MBEDTLS_ERR_NET_CONN_RESET): - return( "NET - Connection was reset by peer" ); - case -(MBEDTLS_ERR_NET_UNKNOWN_HOST): - return( "NET - Failed to get an IP address for the given hostname" ); - case -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL): - return( "NET - Buffer is too small to hold the data" ); - case -(MBEDTLS_ERR_NET_INVALID_CONTEXT): - return( "NET - The context is invalid, eg because it was free()ed" ); - case -(MBEDTLS_ERR_NET_POLL_FAILED): - return( "NET - Polling the net context failed" ); - case -(MBEDTLS_ERR_NET_BAD_INPUT_DATA): - return( "NET - Input invalid" ); -#endif /* MBEDTLS_NET_C */ - -#if defined(MBEDTLS_OID_C) - case -(MBEDTLS_ERR_OID_NOT_FOUND): - return( "OID - OID is not found" ); - case -(MBEDTLS_ERR_OID_BUF_TOO_SMALL): - return( "OID - output buffer is too small" ); -#endif /* MBEDTLS_OID_C */ - -#if defined(MBEDTLS_POLY1305_C) - case -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA): - return( "POLY1305 - Invalid input parameter(s)" ); -#endif /* MBEDTLS_POLY1305_C */ - -#if defined(MBEDTLS_SHA1_C) - case -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA): - return( "SHA1 - SHA-1 input data was malformed" ); -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - case -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA): - return( "SHA256 - SHA-256 input data was malformed" ); -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA3_C) - case -(MBEDTLS_ERR_SHA3_BAD_INPUT_DATA): - return( "SHA3 - SHA-3 input data was malformed" ); -#endif /* MBEDTLS_SHA3_C */ - -#if defined(MBEDTLS_SHA512_C) - case -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA): - return( "SHA512 - SHA-512 input data was malformed" ); -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_THREADING_C) - case -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA): - return( "THREADING - Bad input parameters to function" ); - case -(MBEDTLS_ERR_THREADING_MUTEX_ERROR): - return( "THREADING - Locking / unlocking / free failed with error code" ); -#endif /* MBEDTLS_THREADING_C */ - /* End Auto-Generated Code. */ - - default: - break; - } - - return NULL; -} - -void mbedtls_strerror(int ret, char *buf, size_t buflen) -{ - size_t len; - int use_ret; - const char *high_level_error_description = NULL; - const char *low_level_error_description = NULL; - - if (buflen == 0) { - return; - } - - memset(buf, 0x00, buflen); - - if (ret < 0) { - ret = -ret; - } - - if (ret & 0xFF80) { - use_ret = ret & 0xFF80; - - // Translate high level error code. - high_level_error_description = mbedtls_high_level_strerr(ret); - - if (high_level_error_description == NULL) { - mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret); - } else { - mbedtls_snprintf(buf, buflen, "%s", high_level_error_description); - } - -#if defined(MBEDTLS_SSL_TLS_C) - // Early return in case of a fatal error - do not try to translate low - // level code. - if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { - return; - } -#endif /* MBEDTLS_SSL_TLS_C */ - } - - use_ret = ret & ~0xFF80; - - if (use_ret == 0) { - return; - } - - // If high level code is present, make a concatenation between both - // error strings. - // - len = strlen(buf); - - if (len > 0) { - if (buflen - len < 5) { - return; - } - - mbedtls_snprintf(buf + len, buflen - len, " : "); - - buf += len + 3; - buflen -= len + 3; - } - - // Translate low level error code. - low_level_error_description = mbedtls_low_level_strerr(ret); - - if (low_level_error_description == NULL) { - mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret); - } else { - mbedtls_snprintf(buf, buflen, "%s", low_level_error_description); - } -} - -#else /* MBEDTLS_ERROR_C */ - -/* - * Provide a dummy implementation when MBEDTLS_ERROR_C is not defined - */ -void mbedtls_strerror(int ret, char *buf, size_t buflen) -{ - ((void) ret); - - if (buflen > 0) { - buf[0] = '\0'; - } -} - -#endif /* MBEDTLS_ERROR_C */ - -#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */ diff --git a/vendor/mbedtls/library/gcm.c b/vendor/mbedtls/library/gcm.c deleted file mode 100644 index 5dfac2349..000000000 --- a/vendor/mbedtls/library/gcm.c +++ /dev/null @@ -1,1330 +0,0 @@ -/* - * NIST SP800-38D compliant GCM implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf - * - * See also: - * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf - * - * We use the algorithm described as Shoup's method with 4-bit tables in - * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. - */ - -#include "common.h" - -#if defined(MBEDTLS_GCM_C) - -#include "mbedtls/gcm.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/constant_time.h" - -#if defined(MBEDTLS_BLOCK_CIPHER_C) -#include "block_cipher_internal.h" -#endif - -#include - -#if defined(MBEDTLS_AESNI_C) -#include "aesni.h" -#endif - -#if defined(MBEDTLS_AESCE_C) -#include "aesce.h" -#endif - -#if !defined(MBEDTLS_GCM_ALT) - -/* Used to select the acceleration mechanism */ -#define MBEDTLS_GCM_ACC_SMALLTABLE 0 -#define MBEDTLS_GCM_ACC_LARGETABLE 1 -#define MBEDTLS_GCM_ACC_AESNI 2 -#define MBEDTLS_GCM_ACC_AESCE 3 - -/* - * Initialize a context - */ -void mbedtls_gcm_init(mbedtls_gcm_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_gcm_context)); -} - -static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx) -{ -#if defined(MBEDTLS_GCM_LARGE_TABLE) - ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE; -#else - ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE; -#endif - -#if defined(MBEDTLS_AESNI_HAVE_CODE) - /* With CLMUL support, we need only h, not the rest of the table */ - if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { - ctx->acceleration = MBEDTLS_GCM_ACC_AESNI; - } -#endif - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - if (MBEDTLS_AESCE_HAS_SUPPORT()) { - ctx->acceleration = MBEDTLS_GCM_ACC_AESCE; - } -#endif -} - -static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2]) -{ - uint8_t *u8Dst = (uint8_t *) dst; - uint8_t *u8Src = (uint8_t *) src; - - MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0); - u8Dst[8] |= (u8Src[7] & 0x01) << 7; - MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0); - u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0; -} - -/* - * Precompute small multiples of H, that is set - * HH[i] || HL[i] = H times i, - * where i is seen as a field element as in [MGV], ie high-order bits - * correspond to low powers of P. The result is stored in the same way, that - * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL - * corresponds to P^127. - */ -static int gcm_gen_table(mbedtls_gcm_context *ctx) -{ - int ret, i, j; - uint64_t u64h[2] = { 0 }; - uint8_t *h = (uint8_t *) u64h; - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h); -#else - size_t olen = 0; - ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen); -#endif - if (ret != 0) { - return ret; - } - - gcm_set_acceleration(ctx); - - /* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */ - ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0]; - ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1]; - - switch (ctx->acceleration) { -#if defined(MBEDTLS_AESNI_HAVE_CODE) - case MBEDTLS_GCM_ACC_AESNI: - return 0; -#endif - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - case MBEDTLS_GCM_ACC_AESCE: - return 0; -#endif - - default: - /* 0 corresponds to 0 in GF(2^128) */ - ctx->H[0][0] = 0; - ctx->H[0][1] = 0; - - for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) { - gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]); - } - -#if !defined(MBEDTLS_GCM_LARGE_TABLE) - /* pack elements of H as 64-bits ints, big-endian */ - for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) { - MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0); - MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0); - } -#endif - - for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) { - for (j = 1; j < i; j++) { - mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j], - (unsigned char *) ctx->H[i], - (unsigned char *) ctx->H[j], - 16); - } - } - } - - return 0; -} - -int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (keybits != 128 && keybits != 192 && keybits != 256) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - mbedtls_block_cipher_free(&ctx->block_cipher_ctx); - - if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) { - return ret; - } - - if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) { - return ret; - } -#else - const mbedtls_cipher_info_t *cipher_info; - - cipher_info = mbedtls_cipher_info_from_values(cipher, keybits, - MBEDTLS_MODE_ECB); - if (cipher_info == NULL) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - - if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - - mbedtls_cipher_free(&ctx->cipher_ctx); - - if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) { - return ret; - } - - if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT)) != 0) { - return ret; - } -#endif - - if ((ret = gcm_gen_table(ctx)) != 0) { - return ret; - } - - return 0; -} - -#if defined(MBEDTLS_GCM_LARGE_TABLE) -static const uint16_t last8[256] = { - 0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05, - 0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b, - 0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19, - 0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17, - 0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d, - 0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33, - 0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21, - 0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f, - 0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75, - 0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b, - 0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69, - 0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67, - 0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d, - 0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43, - 0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51, - 0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f, - 0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4, - 0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea, - 0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8, - 0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6, - 0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc, - 0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2, - 0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0, - 0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece, - 0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94, - 0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a, - 0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88, - 0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86, - 0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac, - 0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2, - 0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0, - 0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe -}; - -static void gcm_mult_largetable(uint8_t *output, const uint8_t *x, uint64_t H[256][2]) -{ - int i; - uint64_t u64z[2]; - uint16_t *u16z = (uint16_t *) u64z; - uint8_t *u8z = (uint8_t *) u64z; - uint8_t rem; - - u64z[0] = 0; - u64z[1] = 0; - - if (MBEDTLS_IS_BIG_ENDIAN) { - for (i = 15; i > 0; i--) { - mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16); - rem = u8z[15]; - - u64z[1] >>= 8; - u8z[8] = u8z[7]; - u64z[0] >>= 8; - - u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0); - } - } else { - for (i = 15; i > 0; i--) { - mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16); - rem = u8z[15]; - - u64z[1] <<= 8; - u8z[8] = u8z[7]; - u64z[0] <<= 8; - - u16z[0] ^= last8[rem]; - } - } - - mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16); -} -#else -/* - * Shoup's method for multiplication use this table with - * last4[x] = x times P^128 - * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] - */ -static const uint16_t last4[16] = -{ - 0x0000, 0x1c20, 0x3840, 0x2460, - 0x7080, 0x6ca0, 0x48c0, 0x54e0, - 0xe100, 0xfd20, 0xd940, 0xc560, - 0x9180, 0x8da0, 0xa9c0, 0xb5e0 -}; - -static void gcm_mult_smalltable(uint8_t *output, const uint8_t *x, uint64_t H[16][2]) -{ - int i = 0; - unsigned char lo, hi, rem; - uint64_t u64z[2]; - const uint64_t *pu64z = NULL; - uint8_t *u8z = (uint8_t *) u64z; - - lo = x[15] & 0xf; - hi = (x[15] >> 4) & 0xf; - - pu64z = H[lo]; - - rem = (unsigned char) pu64z[1] & 0xf; - u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4); - u64z[0] = (pu64z[0] >> 4); - u64z[0] ^= (uint64_t) last4[rem] << 48; - mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16); - - for (i = 14; i >= 0; i--) { - lo = x[i] & 0xf; - hi = (x[i] >> 4) & 0xf; - - rem = (unsigned char) u64z[1] & 0xf; - u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4); - u64z[0] = (u64z[0] >> 4); - u64z[0] ^= (uint64_t) last4[rem] << 48; - mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16); - - rem = (unsigned char) u64z[1] & 0xf; - u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4); - u64z[0] = (u64z[0] >> 4); - u64z[0] ^= (uint64_t) last4[rem] << 48; - mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16); - } - - MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0); - MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8); -} -#endif - -/* - * Sets output to x times H using the precomputed tables. - * x and output are seen as elements of GF(2^128) as in [MGV]. - */ -static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16], - unsigned char output[16]) -{ - switch (ctx->acceleration) { -#if defined(MBEDTLS_AESNI_HAVE_CODE) - case MBEDTLS_GCM_ACC_AESNI: - mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]); - break; -#endif - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - case MBEDTLS_GCM_ACC_AESCE: - mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]); - break; -#endif - -#if defined(MBEDTLS_GCM_LARGE_TABLE) - case MBEDTLS_GCM_ACC_LARGETABLE: - gcm_mult_largetable(output, x, ctx->H); - break; -#else - case MBEDTLS_GCM_ACC_SMALLTABLE: - gcm_mult_smalltable(output, x, ctx->H); - break; -#endif - } - - return; -} - -int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, - int mode, - const unsigned char *iv, size_t iv_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char work_buf[16]; - const unsigned char *p; - size_t use_len; - uint64_t iv_bits; -#if !defined(MBEDTLS_BLOCK_CIPHER_C) - size_t olen = 0; -#endif - - /* IV is limited to 2^64 bits, so 2^61 bytes */ - /* IV is not allowed to be zero length */ - if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - - memset(ctx->y, 0x00, sizeof(ctx->y)); - memset(ctx->buf, 0x00, sizeof(ctx->buf)); - - ctx->mode = mode; - ctx->len = 0; - ctx->add_len = 0; - - if (iv_len == 12) { - memcpy(ctx->y, iv, iv_len); - ctx->y[15] = 1; - } else { - memset(work_buf, 0x00, 16); - iv_bits = (uint64_t) iv_len * 8; - MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8); - - p = iv; - while (iv_len > 0) { - use_len = (iv_len < 16) ? iv_len : 16; - -#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110) -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wstringop-overflow=0" -#endif - - mbedtls_xor(ctx->y, ctx->y, p, use_len); - -#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110) -#pragma GCC diagnostic pop -#endif - - gcm_mult(ctx, ctx->y, ctx->y); - - iv_len -= use_len; - p += use_len; - } - - mbedtls_xor(ctx->y, ctx->y, work_buf, 16); - - gcm_mult(ctx, ctx->y, ctx->y); - } - - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr); -#else - ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen); -#endif - if (ret != 0) { - return ret; - } - - return 0; -} - -/** - * mbedtls_gcm_context::buf contains the partial state of the computation of - * the authentication tag. - * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate - * different stages of the computation: - * * len == 0 && add_len == 0: initial state - * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have - * a partial block of AD that has been - * xored in but not yet multiplied in. - * * len == 0 && add_len % 16 == 0: the authentication tag is correct if - * the data ends now. - * * len % 16 != 0: the first `len % 16` bytes have - * a partial block of ciphertext that has - * been xored in but not yet multiplied in. - * * len > 0 && len % 16 == 0: the authentication tag is correct if - * the data ends now. - */ -int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, - const unsigned char *add, size_t add_len) -{ - const unsigned char *p; - size_t use_len, offset; - uint64_t new_add_len; - - /* AD is limited to 2^64 bits, ie 2^61 bytes - * Also check for possible overflow */ -#if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL - if (add_len > 0xFFFFFFFFFFFFFFFFULL) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } -#endif - new_add_len = ctx->add_len + (uint64_t) add_len; - if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - - offset = ctx->add_len % 16; - p = add; - - if (offset != 0) { - use_len = 16 - offset; - if (use_len > add_len) { - use_len = add_len; - } - - mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len); - - if (offset + use_len == 16) { - gcm_mult(ctx, ctx->buf, ctx->buf); - } - - ctx->add_len += use_len; - add_len -= use_len; - p += use_len; - } - - ctx->add_len += add_len; - - while (add_len >= 16) { - mbedtls_xor(ctx->buf, ctx->buf, p, 16); - - gcm_mult(ctx, ctx->buf, ctx->buf); - - add_len -= 16; - p += 16; - } - - if (add_len > 0) { - mbedtls_xor(ctx->buf, ctx->buf, p, add_len); - } - - return 0; -} - -/* Increment the counter. */ -static void gcm_incr(unsigned char y[16]) -{ - uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12); - x++; - MBEDTLS_PUT_UINT32_BE(x, y, 12); -} - -/* Calculate and apply the encryption mask. Process use_len bytes of data, - * starting at position offset in the mask block. */ -static int gcm_mask(mbedtls_gcm_context *ctx, - unsigned char ectr[16], - size_t offset, size_t use_len, - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_BLOCK_CIPHER_C) - ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr); -#else - size_t olen = 0; - ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen); -#endif - if (ret != 0) { - mbedtls_platform_zeroize(ectr, 16); - return ret; - } - - if (ctx->mode == MBEDTLS_GCM_DECRYPT) { - mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len); - } - mbedtls_xor(output, ectr + offset, input, use_len); - if (ctx->mode == MBEDTLS_GCM_ENCRYPT) { - mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len); - } - - return 0; -} - -int mbedtls_gcm_update(mbedtls_gcm_context *ctx, - const unsigned char *input, size_t input_length, - unsigned char *output, size_t output_size, - size_t *output_length) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = input; - unsigned char *out_p = output; - size_t offset; - unsigned char ectr[16] = { 0 }; - - if (output_size < input_length) { - return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL; - } - *output_length = input_length; - - /* Exit early if input_length==0 so that we don't do any pointer arithmetic - * on a potentially null pointer. - * Returning early also means that the last partial block of AD remains - * untouched for mbedtls_gcm_finish */ - if (input_length == 0) { - return 0; - } - - if (output > input && (size_t) (output - input) < input_length) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - - /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes - * Also check for possible overflow */ - if (ctx->len + input_length < ctx->len || - (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - - if (ctx->len == 0 && ctx->add_len % 16 != 0) { - gcm_mult(ctx, ctx->buf, ctx->buf); - } - - offset = ctx->len % 16; - if (offset != 0) { - size_t use_len = 16 - offset; - if (use_len > input_length) { - use_len = input_length; - } - - if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) { - return ret; - } - - if (offset + use_len == 16) { - gcm_mult(ctx, ctx->buf, ctx->buf); - } - - ctx->len += use_len; - input_length -= use_len; - p += use_len; - out_p += use_len; - } - - ctx->len += input_length; - - while (input_length >= 16) { - gcm_incr(ctx->y); - if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) { - return ret; - } - - gcm_mult(ctx, ctx->buf, ctx->buf); - - input_length -= 16; - p += 16; - out_p += 16; - } - - if (input_length > 0) { - gcm_incr(ctx->y); - if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) { - return ret; - } - } - - mbedtls_platform_zeroize(ectr, sizeof(ectr)); - return 0; -} - -int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, - unsigned char *output, size_t output_size, - size_t *output_length, - unsigned char *tag, size_t tag_len) -{ - unsigned char work_buf[16]; - uint64_t orig_len; - uint64_t orig_add_len; - - /* We never pass any output in finish(). The output parameter exists only - * for the sake of alternative implementations. */ - (void) output; - (void) output_size; - *output_length = 0; - - /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes - * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of - * the two multiplications would overflow. */ - orig_len = ctx->len * 8; - orig_add_len = ctx->add_len * 8; - - if (ctx->len == 0 && ctx->add_len % 16 != 0) { - gcm_mult(ctx, ctx->buf, ctx->buf); - } - - if (tag_len > 16 || tag_len < 4) { - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - - if (ctx->len % 16 != 0) { - gcm_mult(ctx, ctx->buf, ctx->buf); - } - - memcpy(tag, ctx->base_ectr, tag_len); - - if (orig_len || orig_add_len) { - memset(work_buf, 0x00, 16); - - MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0); - MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4); - MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8); - MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12); - - mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16); - - gcm_mult(ctx, ctx->buf, ctx->buf); - - mbedtls_xor(tag, tag, ctx->buf, tag_len); - } - - return 0; -} - -int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen; - - if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) { - return ret; - } - - if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) { - return ret; - } - - if ((ret = mbedtls_gcm_update(ctx, input, length, - output, length, &olen)) != 0) { - return ret; - } - - if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) { - return ret; - } - - return 0; -} - -int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char check_tag[16]; - int diff; - - if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, tag_len, check_tag)) != 0) { - return ret; - } - - /* Check tag in "constant-time" */ - diff = mbedtls_ct_memcmp(tag, check_tag, tag_len); - - if (diff != 0) { - mbedtls_platform_zeroize(output, length); - return MBEDTLS_ERR_GCM_AUTH_FAILED; - } - - return 0; -} - -void mbedtls_gcm_free(mbedtls_gcm_context *ctx) -{ - if (ctx == NULL) { - return; - } -#if defined(MBEDTLS_BLOCK_CIPHER_C) - mbedtls_block_cipher_free(&ctx->block_cipher_ctx); -#else - mbedtls_cipher_free(&ctx->cipher_ctx); -#endif - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context)); -} - -#endif /* !MBEDTLS_GCM_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES) -/* - * AES-GCM test vectors from: - * - * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip - */ -#define MAX_TESTS 6 - -static const int key_index_test_data[MAX_TESTS] = -{ 0, 0, 1, 1, 1, 1 }; - -static const unsigned char key_test_data[][32] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, -}; - -static const size_t iv_len_test_data[MAX_TESTS] = -{ 12, 12, 12, 12, 8, 60 }; - -static const int iv_index_test_data[MAX_TESTS] = -{ 0, 0, 1, 1, 1, 2 }; - -static const unsigned char iv_test_data[][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }, - { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 }, - { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, - 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, - 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, - 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, - 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, - 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, - 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, - 0xa6, 0x37, 0xb3, 0x9b }, -}; - -static const size_t add_len_test_data[MAX_TESTS] = -{ 0, 0, 0, 20, 20, 20 }; - -static const int add_index_test_data[MAX_TESTS] = -{ 0, 0, 0, 1, 1, 1 }; - -static const unsigned char additional_test_data[][64] = -{ - { 0x00 }, - { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 }, -}; - -static const size_t pt_len_test_data[MAX_TESTS] = -{ 0, 16, 64, 60, 60, 60 }; - -static const int pt_index_test_data[MAX_TESTS] = -{ 0, 0, 1, 1, 1, 1 }; - -static const unsigned char pt_test_data[][64] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, -}; - -static const unsigned char ct_test_data[][64] = -{ - { 0x00 }, - { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, - 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, - { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 }, - { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, - 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, - 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, - 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, - 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, - 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, - 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, - 0xc2, 0x3f, 0x45, 0x98 }, - { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, - 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, - 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, - 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, - 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, - 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, - 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, - 0x4c, 0x34, 0xae, 0xe5 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x00 }, - { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, - 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, - { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10 }, - { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, - 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, - 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, - 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, - 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, - 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, - 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, - 0xa0, 0xf0, 0x62, 0xf7 }, - { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, - 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, - 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, - 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, - 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, - 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, - 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, - 0xe9, 0xb7, 0x37, 0x3b }, - { 0x00 }, - { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, - 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, - { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62 }, - { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, - 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, - 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, - 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, - 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, - 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, - 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, - 0xf4, 0x7c, 0x9b, 0x1f }, - { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, - 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, - 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, - 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, - 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, - 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, - 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, - 0x44, 0xae, 0x7e, 0x3f }, -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ -}; - -static const unsigned char tag_test_data[][16] = -{ - { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, - 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, - { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, - 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, - { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, - 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, - { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, - 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, - { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, - 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, - { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, - 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, - 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, - { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, - 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, - { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, - 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, - { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, - 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, - { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, - 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, - { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, - 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, - { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, - 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, - { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, - 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, - { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, - 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, - { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, - 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, - { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, - 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, - { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, - 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, -#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ -}; - -int mbedtls_gcm_self_test(int verbose) -{ - mbedtls_gcm_context ctx; - unsigned char buf[64]; - unsigned char tag_buf[16]; - int i, j, ret; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - size_t olen; - - if (verbose != 0) { -#if defined(MBEDTLS_GCM_ALT) - mbedtls_printf(" GCM note: alternative implementation.\n"); -#else /* MBEDTLS_GCM_ALT */ -#if defined(MBEDTLS_AESNI_HAVE_CODE) - if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { - mbedtls_printf(" GCM note: using AESNI.\n"); - } else -#endif - -#if defined(MBEDTLS_AESCE_HAVE_CODE) - if (MBEDTLS_AESCE_HAS_SUPPORT()) { - mbedtls_printf(" GCM note: using AESCE.\n"); - } else -#endif - - mbedtls_printf(" GCM note: built-in implementation.\n"); -#endif /* MBEDTLS_GCM_ALT */ - } - - static const int loop_limit = - (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS; - - for (j = 0; j < loop_limit; j++) { - int key_len = 128 + 64 * j; - - for (i = 0; i < MAX_TESTS; i++) { - if (verbose != 0) { - mbedtls_printf(" AES-GCM-%3d #%d (%s): ", - key_len, i, "enc"); - } - - mbedtls_gcm_init(&ctx); - - ret = mbedtls_gcm_setkey(&ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len); - /* - * AES-192 is an optional feature that may be unavailable when - * there is an alternative underlying implementation i.e. when - * MBEDTLS_AES_ALT is defined. - */ - if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) { - mbedtls_printf("skipped\n"); - break; - } else if (ret != 0) { - goto exit; - } - - ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, - pt_len_test_data[i], - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i], - pt_test_data[pt_index_test_data[i]], - buf, 16, tag_buf); -#if defined(MBEDTLS_GCM_ALT) - /* Allow alternative implementations to only support 12-byte nonces. */ - if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && - iv_len_test_data[i] != 12) { - mbedtls_printf("skipped\n"); - break; - } -#endif /* defined(MBEDTLS_GCM_ALT) */ - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, ct_test_data[j * 6 + i], - pt_len_test_data[i]) != 0 || - memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { - ret = 1; - goto exit; - } - - mbedtls_gcm_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - mbedtls_gcm_init(&ctx); - - if (verbose != 0) { - mbedtls_printf(" AES-GCM-%3d #%d (%s): ", - key_len, i, "dec"); - } - - ret = mbedtls_gcm_setkey(&ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT, - pt_len_test_data[i], - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i], - additional_test_data[add_index_test_data[i]], - add_len_test_data[i], - ct_test_data[j * 6 + i], buf, 16, tag_buf); - - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, pt_test_data[pt_index_test_data[i]], - pt_len_test_data[i]) != 0 || - memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { - ret = 1; - goto exit; - } - - mbedtls_gcm_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - mbedtls_gcm_init(&ctx); - - if (verbose != 0) { - mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", - key_len, i, "enc"); - } - - ret = mbedtls_gcm_setkey(&ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT, - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i]); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_gcm_update_ad(&ctx, - additional_test_data[add_index_test_data[i]], - add_len_test_data[i]); - if (ret != 0) { - goto exit; - } - - if (pt_len_test_data[i] > 32) { - size_t rest_len = pt_len_test_data[i] - 32; - ret = mbedtls_gcm_update(&ctx, - pt_test_data[pt_index_test_data[i]], - 32, - buf, sizeof(buf), &olen); - if (ret != 0) { - goto exit; - } - if (olen != 32) { - goto exit; - } - - ret = mbedtls_gcm_update(&ctx, - pt_test_data[pt_index_test_data[i]] + 32, - rest_len, - buf + 32, sizeof(buf) - 32, &olen); - if (ret != 0) { - goto exit; - } - if (olen != rest_len) { - goto exit; - } - } else { - ret = mbedtls_gcm_update(&ctx, - pt_test_data[pt_index_test_data[i]], - pt_len_test_data[i], - buf, sizeof(buf), &olen); - if (ret != 0) { - goto exit; - } - if (olen != pt_len_test_data[i]) { - goto exit; - } - } - - ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, ct_test_data[j * 6 + i], - pt_len_test_data[i]) != 0 || - memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { - ret = 1; - goto exit; - } - - mbedtls_gcm_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - mbedtls_gcm_init(&ctx); - - if (verbose != 0) { - mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", - key_len, i, "dec"); - } - - ret = mbedtls_gcm_setkey(&ctx, cipher, - key_test_data[key_index_test_data[i]], - key_len); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, - iv_test_data[iv_index_test_data[i]], - iv_len_test_data[i]); - if (ret != 0) { - goto exit; - } - ret = mbedtls_gcm_update_ad(&ctx, - additional_test_data[add_index_test_data[i]], - add_len_test_data[i]); - if (ret != 0) { - goto exit; - } - - if (pt_len_test_data[i] > 32) { - size_t rest_len = pt_len_test_data[i] - 32; - ret = mbedtls_gcm_update(&ctx, - ct_test_data[j * 6 + i], 32, - buf, sizeof(buf), &olen); - if (ret != 0) { - goto exit; - } - if (olen != 32) { - goto exit; - } - - ret = mbedtls_gcm_update(&ctx, - ct_test_data[j * 6 + i] + 32, - rest_len, - buf + 32, sizeof(buf) - 32, &olen); - if (ret != 0) { - goto exit; - } - if (olen != rest_len) { - goto exit; - } - } else { - ret = mbedtls_gcm_update(&ctx, - ct_test_data[j * 6 + i], - pt_len_test_data[i], - buf, sizeof(buf), &olen); - if (ret != 0) { - goto exit; - } - if (olen != pt_len_test_data[i]) { - goto exit; - } - } - - ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); - if (ret != 0) { - goto exit; - } - - if (memcmp(buf, pt_test_data[pt_index_test_data[i]], - pt_len_test_data[i]) != 0 || - memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { - ret = 1; - goto exit; - } - - mbedtls_gcm_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - ret = 0; - -exit: - if (ret != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - mbedtls_gcm_free(&ctx); - } - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_GCM_C */ diff --git a/vendor/mbedtls/library/hkdf.c b/vendor/mbedtls/library/hkdf.c deleted file mode 100644 index 631ac24e5..000000000 --- a/vendor/mbedtls/library/hkdf.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * HKDF implementation -- RFC 5869 - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#include "common.h" - -#if defined(MBEDTLS_HKDF_C) - -#include -#include "mbedtls/hkdf.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -int mbedtls_hkdf(const mbedtls_md_info_t *md, const unsigned char *salt, - size_t salt_len, const unsigned char *ikm, size_t ikm_len, - const unsigned char *info, size_t info_len, - unsigned char *okm, size_t okm_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char prk[MBEDTLS_MD_MAX_SIZE]; - - ret = mbedtls_hkdf_extract(md, salt, salt_len, ikm, ikm_len, prk); - - if (ret == 0) { - ret = mbedtls_hkdf_expand(md, prk, mbedtls_md_get_size(md), - info, info_len, okm, okm_len); - } - - mbedtls_platform_zeroize(prk, sizeof(prk)); - - return ret; -} - -int mbedtls_hkdf_extract(const mbedtls_md_info_t *md, - const unsigned char *salt, size_t salt_len, - const unsigned char *ikm, size_t ikm_len, - unsigned char *prk) -{ - unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' }; - - if (salt == NULL) { - size_t hash_len; - - if (salt_len != 0) { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - hash_len = mbedtls_md_get_size(md); - - if (hash_len == 0) { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - salt = null_salt; - salt_len = hash_len; - } - - return mbedtls_md_hmac(md, salt, salt_len, ikm, ikm_len, prk); -} - -int mbedtls_hkdf_expand(const mbedtls_md_info_t *md, const unsigned char *prk, - size_t prk_len, const unsigned char *info, - size_t info_len, unsigned char *okm, size_t okm_len) -{ - size_t hash_len; - size_t where = 0; - size_t n; - size_t t_len = 0; - size_t i; - int ret = 0; - mbedtls_md_context_t ctx; - unsigned char t[MBEDTLS_MD_MAX_SIZE]; - - if (okm == NULL) { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - hash_len = mbedtls_md_get_size(md); - - if (prk_len < hash_len || hash_len == 0) { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - if (info == NULL) { - info = (const unsigned char *) ""; - info_len = 0; - } - - n = okm_len / hash_len; - - if (okm_len % hash_len != 0) { - n++; - } - - /* - * Per RFC 5869 Section 2.3, okm_len must not exceed - * 255 times the hash length - */ - if (n > 255) { - return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; - } - - mbedtls_md_init(&ctx); - - if ((ret = mbedtls_md_setup(&ctx, md, 1)) != 0) { - goto exit; - } - - memset(t, 0, hash_len); - - /* - * Compute T = T(1) | T(2) | T(3) | ... | T(N) - * Where T(N) is defined in RFC 5869 Section 2.3 - */ - for (i = 1; i <= n; i++) { - size_t num_to_copy; - unsigned char c = i & 0xff; - - ret = mbedtls_md_hmac_starts(&ctx, prk, prk_len); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_md_hmac_update(&ctx, t, t_len); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_md_hmac_update(&ctx, info, info_len); - if (ret != 0) { - goto exit; - } - - /* The constant concatenated to the end of each T(n) is a single octet. - * */ - ret = mbedtls_md_hmac_update(&ctx, &c, 1); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_md_hmac_finish(&ctx, t); - if (ret != 0) { - goto exit; - } - - num_to_copy = i != n ? hash_len : okm_len - where; - memcpy(okm + where, t, num_to_copy); - where += hash_len; - t_len = hash_len; - } - -exit: - mbedtls_md_free(&ctx); - mbedtls_platform_zeroize(t, sizeof(t)); - - return ret; -} - -#endif /* MBEDTLS_HKDF_C */ diff --git a/vendor/mbedtls/library/hmac_drbg.c b/vendor/mbedtls/library/hmac_drbg.c deleted file mode 100644 index d51962832..000000000 --- a/vendor/mbedtls/library/hmac_drbg.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * HMAC_DRBG implementation (NIST SP 800-90) - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The NIST SP 800-90A DRBGs are described in the following publication. - * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf - * References below are based on rev. 1 (January 2012). - */ - -#include "common.h" - -#if defined(MBEDTLS_HMAC_DRBG_C) - -#include "mbedtls/hmac_drbg.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -#include "mbedtls/platform.h" - -/* - * HMAC_DRBG context initialization - */ -void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_hmac_drbg_context)); - - ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; -} - -/* - * HMAC_DRBG update, using optional additional data (10.1.2.2) - */ -int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, - size_t add_len) -{ - size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info); - unsigned char rounds = (additional != NULL && add_len != 0) ? 2 : 1; - unsigned char sep[1]; - unsigned char K[MBEDTLS_MD_MAX_SIZE]; - int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA; - - for (sep[0] = 0; sep[0] < rounds; sep[0]++) { - /* Step 1 or 4 */ - if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, - ctx->V, md_len)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, - sep, 1)) != 0) { - goto exit; - } - if (rounds == 2) { - if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, - additional, add_len)) != 0) { - goto exit; - } - } - if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, K)) != 0) { - goto exit; - } - - /* Step 2 or 5 */ - if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, K, md_len)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, - ctx->V, md_len)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) { - goto exit; - } - } - -exit: - mbedtls_platform_zeroize(K, sizeof(K)); - return ret; -} - -/* - * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) - */ -int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t *md_info, - const unsigned char *data, size_t data_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) { - return ret; - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&ctx->mutex); -#endif - - /* - * Set initial working state. - * Use the V memory location, which is currently all 0, to initialize the - * MD context with an all-zero key. Then set V to its initial value. - */ - if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, - mbedtls_md_get_size(md_info))) != 0) { - return ret; - } - memset(ctx->V, 0x01, mbedtls_md_get_size(md_info)); - - if ((ret = mbedtls_hmac_drbg_update(ctx, data, data_len)) != 0) { - return ret; - } - - return 0; -} - -/* - * Internal function used both for seeding and reseeding the DRBG. - * Comments starting with arabic numbers refer to section 10.1.2.4 - * of SP800-90A, while roman numbers refer to section 9.2. - */ -static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t len, - int use_nonce) -{ - unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; - size_t seedlen = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - { - size_t total_entropy_len; - - if (use_nonce == 0) { - total_entropy_len = ctx->entropy_len; - } else { - total_entropy_len = ctx->entropy_len * 3 / 2; - } - - /* III. Check input length */ - if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT || - total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) { - return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; - } - } - - memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT); - - /* IV. Gather entropy_len bytes of entropy for the seed */ - if ((ret = ctx->f_entropy(ctx->p_entropy, - seed, ctx->entropy_len)) != 0) { - return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED; - } - seedlen += ctx->entropy_len; - - /* For initial seeding, allow adding of nonce generated - * from the entropy source. See Sect 8.6.7 in SP800-90A. */ - if (use_nonce) { - /* Note: We don't merge the two calls to f_entropy() in order - * to avoid requesting too much entropy from f_entropy() - * at once. Specifically, if the underlying digest is not - * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which - * is larger than the maximum of 32 Bytes that our own - * entropy source implementation can emit in a single - * call in configurations disabling SHA-512. */ - if ((ret = ctx->f_entropy(ctx->p_entropy, - seed + seedlen, - ctx->entropy_len / 2)) != 0) { - return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED; - } - - seedlen += ctx->entropy_len / 2; - } - - - /* 1. Concatenate entropy and additional data if any */ - if (additional != NULL && len != 0) { - memcpy(seed + seedlen, additional, len); - seedlen += len; - } - - /* 2. Update state */ - if ((ret = mbedtls_hmac_drbg_update(ctx, seed, seedlen)) != 0) { - goto exit; - } - - /* 3. Reset reseed_counter */ - ctx->reseed_counter = 0; - -exit: - /* 4. Done */ - mbedtls_platform_zeroize(seed, seedlen); - return ret; -} - -/* - * HMAC_DRBG reseeding: 10.1.2.4 + 9.2 - */ -int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx, - const unsigned char *additional, size_t len) -{ - return hmac_drbg_reseed_core(ctx, additional, len, 0); -} - -/* - * HMAC_DRBG initialisation (10.1.2.3 + 9.1) - * - * The nonce is not passed as a separate parameter but extracted - * from the entropy source as suggested in 8.6.7. - */ -int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx, - const mbedtls_md_info_t *md_info, - int (*f_entropy)(void *, unsigned char *, size_t), - void *p_entropy, - const unsigned char *custom, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t md_size; - - if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) { - return ret; - } - - /* The mutex is initialized iff the md context is set up. */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&ctx->mutex); -#endif - - md_size = mbedtls_md_get_size(md_info); - - /* - * Set initial working state. - * Use the V memory location, which is currently all 0, to initialize the - * MD context with an all-zero key. Then set V to its initial value. - */ - if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0) { - return ret; - } - memset(ctx->V, 0x01, md_size); - - ctx->f_entropy = f_entropy; - ctx->p_entropy = p_entropy; - - if (ctx->entropy_len == 0) { - /* - * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by - * each hash function, then according to SP800-90A rev1 10.1 table 2, - * min_entropy_len (in bits) is security_strength. - * - * (This also matches the sizes used in the NIST test vectors.) - */ - ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ - md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ - 32; /* better (256+) -> 256 bits */ - } - - if ((ret = hmac_drbg_reseed_core(ctx, custom, len, - 1 /* add nonce */)) != 0) { - return ret; - } - - return 0; -} - -/* - * Set prediction resistance - */ -void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx, - int resistance) -{ - ctx->prediction_resistance = resistance; -} - -/* - * Set entropy length grabbed for seeding - */ -void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, size_t len) -{ - ctx->entropy_len = len; -} - -/* - * Set reseed interval - */ -void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, int interval) -{ - ctx->reseed_interval = interval; -} - -/* - * HMAC_DRBG random function with optional additional data: - * 10.1.2.5 (arabic) + 9.3 (Roman) - */ -int mbedtls_hmac_drbg_random_with_add(void *p_rng, - unsigned char *output, size_t out_len, - const unsigned char *additional, size_t add_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; - size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info); - size_t left = out_len; - unsigned char *out = output; - - /* II. Check request length */ - if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST) { - return MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG; - } - - /* III. Check input length */ - if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT) { - return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; - } - - /* 1. (aka VII and IX) Check reseed counter and PR */ - if (ctx->f_entropy != NULL && /* For no-reseeding instances */ - (ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || - ctx->reseed_counter >= ctx->reseed_interval)) { - if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0) { - return ret; - } - - add_len = 0; /* VII.4 */ - } - - /* 2. Use additional data if any */ - if (additional != NULL && add_len != 0) { - if ((ret = mbedtls_hmac_drbg_update(ctx, - additional, add_len)) != 0) { - goto exit; - } - } - - /* 3, 4, 5. Generate bytes */ - while (left != 0) { - size_t use_len = left > md_len ? md_len : left; - - if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, - ctx->V, md_len)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) { - goto exit; - } - - memcpy(out, ctx->V, use_len); - out += use_len; - left -= use_len; - } - - /* 6. Update */ - if ((ret = mbedtls_hmac_drbg_update(ctx, - additional, add_len)) != 0) { - goto exit; - } - - /* 7. Update reseed counter */ - ctx->reseed_counter++; - -exit: - /* 8. Done */ - return ret; -} - -/* - * HMAC_DRBG random function - */ -int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0); - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -/* - * This function resets HMAC_DRBG context to the state immediately - * after initial call of mbedtls_hmac_drbg_init(). - */ -void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_THREADING_C) - /* The mutex is initialized iff the md context is set up. */ - if (ctx->md_ctx.md_info != NULL) { - mbedtls_mutex_free(&ctx->mutex); - } -#endif - mbedtls_md_free(&ctx->md_ctx); - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context)); - ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - FILE *f; - unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT]; - - if ((f = fopen(path, "wb")) == NULL) { - return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0) { - goto exit; - } - - if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) { - ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - goto exit; - } - - ret = 0; - -exit: - fclose(f); - mbedtls_platform_zeroize(buf, sizeof(buf)); - - return ret; -} - -int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path) -{ - int ret = 0; - FILE *f = NULL; - size_t n; - unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT]; - unsigned char c; - - if ((f = fopen(path, "rb")) == NULL) { - return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - n = fread(buf, 1, sizeof(buf), f); - if (fread(&c, 1, 1, f) != 0) { - ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG; - goto exit; - } - if (n == 0 || ferror(f)) { - ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; - goto exit; - } - fclose(f); - f = NULL; - - ret = mbedtls_hmac_drbg_update(ctx, buf, n); - -exit: - mbedtls_platform_zeroize(buf, sizeof(buf)); - if (f != NULL) { - fclose(f); - } - if (ret != 0) { - return ret; - } - return mbedtls_hmac_drbg_write_seed_file(ctx, path); -} -#endif /* MBEDTLS_FS_IO */ - - -#if defined(MBEDTLS_SELF_TEST) - -#if !defined(MBEDTLS_MD_CAN_SHA1) -/* Dummy checkup routine */ -int mbedtls_hmac_drbg_self_test(int verbose) -{ - (void) verbose; - return 0; -} -#else - -#define OUTPUT_LEN 80 - -/* From a NIST PR=true test vector */ -static const unsigned char entropy_pr[] = { - 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, - 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, - 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, - 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, - 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 -}; -static const unsigned char result_pr[OUTPUT_LEN] = { - 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, - 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, - 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, - 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, - 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, - 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, - 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 -}; - -/* From a NIST PR=false test vector */ -static const unsigned char entropy_nopr[] = { - 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, - 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, - 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, - 0xe9, 0x9d, 0xfe, 0xdf -}; -static const unsigned char result_nopr[OUTPUT_LEN] = { - 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, - 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, - 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, - 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, - 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, - 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, - 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 -}; - -/* "Entropy" from buffer */ -static size_t test_offset; -static int hmac_drbg_self_test_entropy(void *data, - unsigned char *buf, size_t len) -{ - const unsigned char *p = data; - memcpy(buf, p + test_offset, len); - test_offset += len; - return 0; -} - -#define CHK(c) if ((c) != 0) \ - { \ - if (verbose != 0) \ - mbedtls_printf("failed\n"); \ - return 1; \ - } - -/* - * Checkup routine for HMAC_DRBG with SHA-1 - */ -int mbedtls_hmac_drbg_self_test(int verbose) -{ - mbedtls_hmac_drbg_context ctx; - unsigned char buf[OUTPUT_LEN]; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); - - mbedtls_hmac_drbg_init(&ctx); - - /* - * PR = True - */ - if (verbose != 0) { - mbedtls_printf(" HMAC_DRBG (PR = True) : "); - } - - test_offset = 0; - CHK(mbedtls_hmac_drbg_seed(&ctx, md_info, - hmac_drbg_self_test_entropy, (void *) entropy_pr, - NULL, 0)); - mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON); - CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN)); - CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN)); - CHK(memcmp(buf, result_pr, OUTPUT_LEN)); - mbedtls_hmac_drbg_free(&ctx); - - mbedtls_hmac_drbg_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - /* - * PR = False - */ - if (verbose != 0) { - mbedtls_printf(" HMAC_DRBG (PR = False) : "); - } - - mbedtls_hmac_drbg_init(&ctx); - - test_offset = 0; - CHK(mbedtls_hmac_drbg_seed(&ctx, md_info, - hmac_drbg_self_test_entropy, (void *) entropy_nopr, - NULL, 0)); - CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0)); - CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN)); - CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN)); - CHK(memcmp(buf, result_nopr, OUTPUT_LEN)); - mbedtls_hmac_drbg_free(&ctx); - - mbedtls_hmac_drbg_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_HMAC_DRBG_C */ diff --git a/vendor/mbedtls/library/lmots.c b/vendor/mbedtls/library/lmots.c deleted file mode 100644 index 404aa80da..000000000 --- a/vendor/mbedtls/library/lmots.c +++ /dev/null @@ -1,789 +0,0 @@ -/* - * The LM-OTS one-time public-key signature scheme - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The following sources were referenced in the design of this implementation - * of the LM-OTS algorithm: - * - * [1] IETF RFC8554 - * D. McGrew, M. Curcio, S.Fluhrer - * https://datatracker.ietf.org/doc/html/rfc8554 - * - * [2] NIST Special Publication 800-208 - * David A. Cooper et. al. - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_LMS_C) - -#include - -#include "lmots.h" - -#include "mbedtls/lms.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "psa_util_internal.h" - -#include "psa/crypto.h" - -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_lms_errors, - ARRAY_LENGTH(psa_to_lms_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) - -#define PUBLIC_KEY_TYPE_OFFSET (0) -#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \ - MBEDTLS_LMOTS_TYPE_LEN) -#define PUBLIC_KEY_Q_LEAF_ID_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \ - MBEDTLS_LMOTS_I_KEY_ID_LEN) -#define PUBLIC_KEY_KEY_HASH_OFFSET (PUBLIC_KEY_Q_LEAF_ID_OFFSET + \ - MBEDTLS_LMOTS_Q_LEAF_ID_LEN) - -/* We only support parameter sets that use 8-bit digits, as it does not require - * translation logic between digits and bytes */ -#define W_WINTERNITZ_PARAMETER (8u) -#define CHECKSUM_LEN (2) -#define I_DIGIT_IDX_LEN (2) -#define J_HASH_IDX_LEN (1) -#define D_CONST_LEN (2) - -#define DIGIT_MAX_VALUE ((1u << W_WINTERNITZ_PARAMETER) - 1u) - -#define D_CONST_LEN (2) -static const unsigned char D_PUBLIC_CONSTANT_BYTES[D_CONST_LEN] = { 0x80, 0x80 }; -static const unsigned char D_MESSAGE_CONSTANT_BYTES[D_CONST_LEN] = { 0x81, 0x81 }; - -#if defined(MBEDTLS_TEST_HOOKS) -int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *) = NULL; -#endif /* defined(MBEDTLS_TEST_HOOKS) */ - -/* Calculate the checksum digits that are appended to the end of the LMOTS digit - * string. See NIST SP800-208 section 3.1 or RFC8554 Algorithm 2 for details of - * the checksum algorithm. - * - * params The LMOTS parameter set, I and q values which - * describe the key being used. - * - * digest The digit string to create the digest from. As - * this does not contain a checksum, it is the same - * size as a hash output. - */ -static unsigned short lmots_checksum_calculate(const mbedtls_lmots_parameters_t *params, - const unsigned char *digest) -{ - size_t idx; - unsigned sum = 0; - - for (idx = 0; idx < MBEDTLS_LMOTS_N_HASH_LEN(params->type); idx++) { - sum += DIGIT_MAX_VALUE - digest[idx]; - } - - return sum; -} - -/* Create the string of digest digits (in the base determined by the Winternitz - * parameter with the checksum appended to the end (Q || cksm(Q)). See NIST - * SP800-208 section 3.1 or RFC8554 Algorithm 3 step 5 (also used in Algorithm - * 4b step 3) for details. - * - * params The LMOTS parameter set, I and q values which - * describe the key being used. - * - * msg The message that will be hashed to create the - * digest. - * - * msg_size The size of the message. - * - * C_random_value The random value that will be combined with the - * message digest. This is always the same size as a - * hash output for whichever hash algorithm is - * determined by the parameter set. - * - * output An output containing the digit string (+ - * checksum) of length P digits (in the case of - * MBEDTLS_LMOTS_SHA256_N32_W8, this means it is of - * size P bytes). - */ -static int create_digit_array_with_checksum(const mbedtls_lmots_parameters_t *params, - const unsigned char *msg, - size_t msg_len, - const unsigned char *C_random_value, - unsigned char *out) -{ - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned short checksum; - - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_MESSAGE_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, C_random_value, - MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, msg, msg_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, out, - MBEDTLS_LMOTS_N_HASH_LEN(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - checksum = lmots_checksum_calculate(params, out); - MBEDTLS_PUT_UINT16_BE(checksum, out, MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -/* Hash each element of the string of digits (+ checksum), producing a hash - * output for each element. This is used in several places (by varying the - * hash_idx_min/max_values) in order to calculate a public key from a private - * key (RFC8554 Algorithm 1 step 4), in order to sign a message (RFC8554 - * Algorithm 3 step 5), and to calculate a public key candidate from a - * signature and message (RFC8554 Algorithm 4b step 3). - * - * params The LMOTS parameter set, I and q values which - * describe the key being used. - * - * x_digit_array The array of digits (of size P, 34 in the case of - * MBEDTLS_LMOTS_SHA256_N32_W8). - * - * hash_idx_min_values An array of the starting values of the j iterator - * for each of the members of the digit array. If - * this value in NULL, then all iterators will start - * at 0. - * - * hash_idx_max_values An array of the upper bound values of the j - * iterator for each of the members of the digit - * array. If this value in NULL, then iterator is - * bounded to be less than 2^w - 1 (255 in the case - * of MBEDTLS_LMOTS_SHA256_N32_W8) - * - * output An array containing a hash output for each member - * of the digit string P. In the case of - * MBEDTLS_LMOTS_SHA256_N32_W8, this is of size 32 * - * 34. - */ -static int hash_digit_array(const mbedtls_lmots_parameters_t *params, - const unsigned char *x_digit_array, - const unsigned char *hash_idx_min_values, - const unsigned char *hash_idx_max_values, - unsigned char *output) -{ - unsigned int i_digit_idx; - unsigned char i_digit_idx_bytes[I_DIGIT_IDX_LEN]; - unsigned int j_hash_idx; - unsigned char j_hash_idx_bytes[J_HASH_IDX_LEN]; - unsigned int j_hash_idx_min; - unsigned int j_hash_idx_max; - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned char tmp_hash[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - - for (i_digit_idx = 0; - i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type); - i_digit_idx++) { - - memcpy(tmp_hash, - &x_digit_array[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)], - MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - - j_hash_idx_min = hash_idx_min_values != NULL ? - hash_idx_min_values[i_digit_idx] : 0; - j_hash_idx_max = hash_idx_max_values != NULL ? - hash_idx_max_values[i_digit_idx] : DIGIT_MAX_VALUE; - - for (j_hash_idx = j_hash_idx_min; - j_hash_idx < j_hash_idx_max; - j_hash_idx++) { - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - params->q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0); - status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - j_hash_idx_bytes[0] = (uint8_t) j_hash_idx; - status = psa_hash_update(&op, j_hash_idx_bytes, J_HASH_IDX_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, tmp_hash, - MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, tmp_hash, sizeof(tmp_hash), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - psa_hash_abort(&op); - } - - memcpy(&output[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)], - tmp_hash, MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - } - -exit: - psa_hash_abort(&op); - mbedtls_platform_zeroize(tmp_hash, sizeof(tmp_hash)); - - return PSA_TO_MBEDTLS_ERR(status); -} - -/* Combine the hashes of the digit array into a public key. This is used in - * in order to calculate a public key from a private key (RFC8554 Algorithm 1 - * step 4), and to calculate a public key candidate from a signature and message - * (RFC8554 Algorithm 4b step 3). - * - * params The LMOTS parameter set, I and q values which describe - * the key being used. - * y_hashed_digits The array of hashes, one hash for each digit of the - * symbol array (which is of size P, 34 in the case of - * MBEDTLS_LMOTS_SHA256_N32_W8) - * - * pub_key The output public key (or candidate public key in - * case this is being run as part of signature - * verification), in the form of a hash output. - */ -static int public_key_from_hashed_digit_array(const mbedtls_lmots_parameters_t *params, - const unsigned char *y_hashed_digits, - unsigned char *pub_key) -{ - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_PUBLIC_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, y_hashed_digits, - MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type) * - MBEDTLS_LMOTS_N_HASH_LEN(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, pub_key, - MBEDTLS_LMOTS_N_HASH_LEN(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - -exit: - psa_hash_abort(&op); - } - - return PSA_TO_MBEDTLS_ERR(status); -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_lms_error_from_psa(psa_status_t status) -{ - switch (status) { - case PSA_SUCCESS: - return 0; - case PSA_ERROR_HARDWARE_FAILURE: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - case PSA_ERROR_INVALID_ARGUMENT: - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - default: - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(*ctx)); -} - -int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx, - const unsigned char *key, size_t key_len) -{ - if (key_len < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - uint32_t type = MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET); - if (type != (uint32_t) MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - ctx->params.type = (mbedtls_lmots_algorithm_type_t) type; - - if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - memcpy(ctx->params.I_key_identifier, - key + PUBLIC_KEY_I_KEY_ID_OFFSET, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - - memcpy(ctx->params.q_leaf_identifier, - key + PUBLIC_KEY_Q_LEAF_ID_OFFSET, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - - memcpy(ctx->public_key, - key + PUBLIC_KEY_KEY_HASH_OFFSET, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - - ctx->have_public_key = 1; - - return 0; -} - -int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx, - unsigned char *key, size_t key_size, - size_t *key_len) -{ - if (key_size < MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET); - - memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - - memcpy(key + PUBLIC_KEY_Q_LEAF_ID_OFFSET, - ctx->params.q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - - memcpy(key + PUBLIC_KEY_KEY_HASH_OFFSET, ctx->public_key, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - - if (key_len != NULL) { - *key_len = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type); - } - - return 0; -} - -int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params, - const unsigned char *msg, - size_t msg_size, - const unsigned char *sig, - size_t sig_size, - unsigned char *out, - size_t out_size, - size_t *out_len) -{ - unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX]; - unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (msg == NULL && msg_size != 0) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size != MBEDTLS_LMOTS_SIG_LEN(params->type) || - out_size < MBEDTLS_LMOTS_N_HASH_LEN(params->type)) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = create_digit_array_with_checksum(params, msg, msg_size, - sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, - tmp_digit_array); - if (ret) { - return ret; - } - - ret = hash_digit_array(params, - sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(params->type), - tmp_digit_array, NULL, (unsigned char *) y_hashed_digits); - if (ret) { - return ret; - } - - ret = public_key_from_hashed_digit_array(params, - (unsigned char *) y_hashed_digits, - out); - if (ret) { - return ret; - } - - if (out_len != NULL) { - *out_len = MBEDTLS_LMOTS_N_HASH_LEN(params->type); - } - - return 0; -} - -int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx, - const unsigned char *msg, size_t msg_size, - const unsigned char *sig, size_t sig_size) -{ - unsigned char Kc_public_key_candidate[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (msg == NULL && msg_size != 0) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.type != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (MBEDTLS_GET_UINT32_BE(sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET) != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - ret = mbedtls_lmots_calculate_public_key_candidate(&ctx->params, - msg, msg_size, sig, sig_size, - Kc_public_key_candidate, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type), - NULL); - if (ret) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (memcmp(&Kc_public_key_candidate, ctx->public_key, - sizeof(ctx->public_key))) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - return 0; -} - -#if defined(MBEDTLS_LMS_PRIVATE) - -void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, - sizeof(*ctx)); -} - -int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx, - mbedtls_lmots_algorithm_type_t type, - const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN], - uint32_t q_leaf_identifier, - const unsigned char *seed, - size_t seed_size) -{ - psa_hash_operation_t op = PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned int i_digit_idx; - unsigned char i_digit_idx_bytes[2]; - unsigned char const_bytes[1] = { 0xFF }; - - if (ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (type != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ctx->params.type = type; - - memcpy(ctx->params.I_key_identifier, - I_key_identifier, - sizeof(ctx->params.I_key_identifier)); - - MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ctx->params.q_leaf_identifier, 0); - - for (i_digit_idx = 0; - i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type); - i_digit_idx++) { - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - ctx->params.I_key_identifier, - sizeof(ctx->params.I_key_identifier)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, - ctx->params.q_leaf_identifier, - MBEDTLS_LMOTS_Q_LEAF_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0); - status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, const_bytes, sizeof(const_bytes)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, seed, seed_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, - ctx->private_key[i_digit_idx], - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - - psa_hash_abort(&op); - } - - ctx->have_private_key = 1; - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx, - const mbedtls_lmots_private_t *priv_ctx) -{ - unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Check that a private key is loaded */ - if (!priv_ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = hash_digit_array(&priv_ctx->params, - (unsigned char *) priv_ctx->private_key, NULL, - NULL, (unsigned char *) y_hashed_digits); - if (ret) { - goto exit; - } - - ret = public_key_from_hashed_digit_array(&priv_ctx->params, - (unsigned char *) y_hashed_digits, - ctx->public_key); - if (ret) { - goto exit; - } - - memcpy(&ctx->params, &priv_ctx->params, - sizeof(ctx->params)); - - ctx->have_public_key = 1; - -exit: - mbedtls_platform_zeroize(y_hashed_digits, sizeof(y_hashed_digits)); - - return ret; -} - -int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, const unsigned char *msg, size_t msg_size, - unsigned char *sig, size_t sig_size, size_t *sig_len) -{ - unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX]; - /* Create a temporary buffer to prepare the signature in. This allows us to - * finish creating a signature (ensuring the process doesn't fail), and then - * erase the private key **before** writing any data into the sig parameter - * buffer. If data were directly written into the sig buffer, it might leak - * a partial signature on failure, which effectively compromises the private - * key. - */ - unsigned char tmp_sig[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - unsigned char tmp_c_random[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (msg == NULL && msg_size != 0) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size < MBEDTLS_LMOTS_SIG_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - /* Check that a private key is loaded */ - if (!ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = f_rng(p_rng, tmp_c_random, - MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - if (ret) { - return ret; - } - - ret = create_digit_array_with_checksum(&ctx->params, - msg, msg_size, - tmp_c_random, - tmp_digit_array); - if (ret) { - goto exit; - } - - ret = hash_digit_array(&ctx->params, (unsigned char *) ctx->private_key, - NULL, tmp_digit_array, (unsigned char *) tmp_sig); - if (ret) { - goto exit; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET); - - /* Test hook to check if sig is being written to before we invalidate the - * private key. - */ -#if defined(MBEDTLS_TEST_HOOKS) - if (mbedtls_lmots_sign_private_key_invalidated_hook != NULL) { - ret = (*mbedtls_lmots_sign_private_key_invalidated_hook)(sig); - if (ret != 0) { - return ret; - } - } -#endif /* defined(MBEDTLS_TEST_HOOKS) */ - - /* We've got a valid signature now, so it's time to make sure the private - * key can't be reused. - */ - ctx->have_private_key = 0; - mbedtls_platform_zeroize(ctx->private_key, - sizeof(ctx->private_key)); - - memcpy(sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, tmp_c_random, - MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(ctx->params.type)); - - memcpy(sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(ctx->params.type), tmp_sig, - MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type) - * MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type)); - - if (sig_len != NULL) { - *sig_len = MBEDTLS_LMOTS_SIG_LEN(ctx->params.type); - } - - ret = 0; - -exit: - mbedtls_platform_zeroize(tmp_digit_array, sizeof(tmp_digit_array)); - mbedtls_platform_zeroize(tmp_sig, sizeof(tmp_sig)); - - return ret; -} - -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ -#endif /* defined(MBEDTLS_LMS_C) */ diff --git a/vendor/mbedtls/library/lmots.h b/vendor/mbedtls/library/lmots.h deleted file mode 100644 index cf92d326c..000000000 --- a/vendor/mbedtls/library/lmots.h +++ /dev/null @@ -1,288 +0,0 @@ -/** - * \file lmots.h - * - * \brief This file provides an API for the LM-OTS post-quantum-safe one-time - * public-key signature scheme as defined in RFC8554 and NIST.SP.200-208. - * This implementation currently only supports a single parameter set - * MBEDTLS_LMOTS_SHA256_N32_W8 in order to reduce complexity. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_LMOTS_H -#define MBEDTLS_LMOTS_H - -#include "mbedtls/build_info.h" - -#include "psa/crypto.h" - -#include "mbedtls/lms.h" - -#include -#include - - -#define MBEDTLS_LMOTS_PUBLIC_KEY_LEN(type) (MBEDTLS_LMOTS_TYPE_LEN + \ - MBEDTLS_LMOTS_I_KEY_ID_LEN + \ - MBEDTLS_LMOTS_Q_LEAF_ID_LEN + \ - MBEDTLS_LMOTS_N_HASH_LEN(type)) - -#define MBEDTLS_LMOTS_SIG_TYPE_OFFSET (0) -#define MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET (MBEDTLS_LMOTS_SIG_TYPE_OFFSET + \ - MBEDTLS_LMOTS_TYPE_LEN) -#define MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(type) (MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET + \ - MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type)) - -#ifdef __cplusplus -extern "C" { -#endif - - -#if defined(MBEDTLS_TEST_HOOKS) -extern int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *); -#endif /* defined(MBEDTLS_TEST_HOOKS) */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief This function converts a \ref psa_status_t to a - * low-level LMS error code. - * - * \param status The psa_status_t to convert - * - * \return The corresponding LMS error code. - */ -int MBEDTLS_DEPRECATED mbedtls_lms_error_from_psa(psa_status_t status); -#endif - -/** - * \brief This function initializes a public LMOTS context - * - * \param ctx The uninitialized LMOTS context that will then be - * initialized. - */ -void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx); - -/** - * \brief This function uninitializes a public LMOTS context - * - * \param ctx The initialized LMOTS context that will then be - * uninitialized. - */ -void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx); - -/** - * \brief This function imports an LMOTS public key into a - * LMOTS context. - * - * \note Before this function is called, the context must - * have been initialized. - * - * \note See IETF RFC8554 for details of the encoding of - * this public key. - * - * \param ctx The initialized LMOTS context store the key in. - * \param key The buffer from which the key will be read. - * #MBEDTLS_LMOTS_PUBLIC_KEY_LEN bytes will be read - * from this. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx, - const unsigned char *key, size_t key_size); - -/** - * \brief This function exports an LMOTS public key from a - * LMOTS context that already contains a public key. - * - * \note Before this function is called, the context must - * have been initialized and the context must contain - * a public key. - * - * \note See IETF RFC8554 for details of the encoding of - * this public key. - * - * \param ctx The initialized LMOTS context that contains the - * public key. - * \param key The buffer into which the key will be output. Must - * be at least #MBEDTLS_LMOTS_PUBLIC_KEY_LEN in size. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx, - unsigned char *key, size_t key_size, - size_t *key_len); - -/** - * \brief This function creates a candidate public key from - * an LMOTS signature. This can then be compared to - * the real public key to determine the validity of - * the signature. - * - * \note This function is exposed publicly to be used in LMS - * signature verification, it is expected that - * mbedtls_lmots_verify will be used for LMOTS - * signature verification. - * - * \param params The LMOTS parameter set, q and I values as an - * mbedtls_lmots_parameters_t struct. - * \param msg The buffer from which the message will be read. - * \param msg_size The size of the message that will be read. - * \param sig The buffer from which the signature will be read. - * #MBEDTLS_LMOTS_SIG_LEN bytes will be read from - * this. - * \param out The buffer where the candidate public key will be - * stored. Must be at least #MBEDTLS_LMOTS_N_HASH_LEN - * bytes in size. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params, - const unsigned char *msg, - size_t msg_size, - const unsigned char *sig, - size_t sig_size, - unsigned char *out, - size_t out_size, - size_t *out_len); - -/** - * \brief This function verifies a LMOTS signature, using a - * LMOTS context that contains a public key. - * - * \warning This function is **not intended for use in - * production**, due to as-yet unsolved problems with - * handling stateful keys. The API for this function - * may change considerably in future versions. - * - * \note Before this function is called, the context must - * have been initialized and must contain a public key - * (either by import or calculation from a private - * key). - * - * \param ctx The initialized LMOTS context from which the public - * key will be read. - * \param msg The buffer from which the message will be read. - * \param msg_size The size of the message that will be read. - * \param sig The buf from which the signature will be read. - * #MBEDTLS_LMOTS_SIG_LEN bytes will be read from - * this. - * - * \return \c 0 on successful verification. - * \return A non-zero error code on failure. - */ -int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx, - const unsigned char *msg, - size_t msg_size, const unsigned char *sig, - size_t sig_size); - -#if defined(MBEDTLS_LMS_PRIVATE) - -/** - * \brief This function initializes a private LMOTS context - * - * \param ctx The uninitialized LMOTS context that will then be - * initialized. - */ -void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx); - -/** - * \brief This function uninitializes a private LMOTS context - * - * \param ctx The initialized LMOTS context that will then be - * uninitialized. - */ -void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx); - -/** - * \brief This function calculates an LMOTS private key, and - * stores in into an LMOTS context. - * - * \warning This function is **not intended for use in - * production**, due to as-yet unsolved problems with - * handling stateful keys. The API for this function - * may change considerably in future versions. - * - * \note The seed must have at least 256 bits of entropy. - * - * \param ctx The initialized LMOTS context to generate the key - * into. - * \param I_key_identifier The key identifier of the key, as a 16-byte string. - * \param q_leaf_identifier The leaf identifier of key. If this LMOTS key is - * not being used as part of an LMS key, this should - * be set to 0. - * \param seed The seed used to deterministically generate the - * key. - * \param seed_size The length of the seed. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx, - mbedtls_lmots_algorithm_type_t type, - const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN], - uint32_t q_leaf_identifier, - const unsigned char *seed, - size_t seed_size); - -/** - * \brief This function generates an LMOTS public key from a - * LMOTS context that already contains a private key. - * - * \note Before this function is called, the context must - * have been initialized and the context must contain - * a private key. - * - * \param ctx The initialized LMOTS context to generate the key - * from and store it into. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx, - const mbedtls_lmots_private_t *priv_ctx); - -/** - * \brief This function creates a LMOTS signature, using a - * LMOTS context that contains a private key. - * - * \note Before this function is called, the context must - * have been initialized and must contain a private - * key. - * - * \note LMOTS private keys can only be used once, otherwise - * attackers may be able to create forged signatures. - * If the signing operation is successful, the private - * key in the context will be erased, and no further - * signing will be possible until another private key - * is loaded - * - * \param ctx The initialized LMOTS context from which the - * private key will be read. - * \param f_rng The RNG function to be used for signature - * generation. - * \param p_rng The RNG context to be passed to f_rng - * \param msg The buffer from which the message will be read. - * \param msg_size The size of the message that will be read. - * \param sig The buf into which the signature will be stored. - * Must be at least #MBEDTLS_LMOTS_SIG_LEN in size. - * - * \return \c 0 on success. - * \return A non-zero error code on failure. - */ -int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, const unsigned char *msg, size_t msg_size, - unsigned char *sig, size_t sig_size, size_t *sig_len); - -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_LMOTS_H */ diff --git a/vendor/mbedtls/library/lms.c b/vendor/mbedtls/library/lms.c deleted file mode 100644 index 41d34bfe1..000000000 --- a/vendor/mbedtls/library/lms.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - * The LMS stateful-hash public-key signature scheme - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The following sources were referenced in the design of this implementation - * of the LMS algorithm: - * - * [1] IETF RFC8554 - * D. McGrew, M. Curcio, S.Fluhrer - * https://datatracker.ietf.org/doc/html/rfc8554 - * - * [2] NIST Special Publication 800-208 - * David A. Cooper et. al. - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_LMS_C) - -#include - -#include "lmots.h" - -#include "psa/crypto.h" -#include "psa_util_internal.h" -#include "mbedtls/lms.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" - -#include "mbedtls/platform.h" - -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_lms_errors, - ARRAY_LENGTH(psa_to_lms_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) - -#define SIG_Q_LEAF_ID_OFFSET (0) -#define SIG_OTS_SIG_OFFSET (SIG_Q_LEAF_ID_OFFSET + \ - MBEDTLS_LMOTS_Q_LEAF_ID_LEN) -#define SIG_TYPE_OFFSET(otstype) (SIG_OTS_SIG_OFFSET + \ - MBEDTLS_LMOTS_SIG_LEN(otstype)) -#define SIG_PATH_OFFSET(otstype) (SIG_TYPE_OFFSET(otstype) + \ - MBEDTLS_LMS_TYPE_LEN) - -#define PUBLIC_KEY_TYPE_OFFSET (0) -#define PUBLIC_KEY_OTSTYPE_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \ - MBEDTLS_LMS_TYPE_LEN) -#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_OTSTYPE_OFFSET + \ - MBEDTLS_LMOTS_TYPE_LEN) -#define PUBLIC_KEY_ROOT_NODE_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \ - MBEDTLS_LMOTS_I_KEY_ID_LEN) - - -/* Currently only support H=10 */ -#define H_TREE_HEIGHT_MAX 10 -#define MERKLE_TREE_NODE_AM(type) ((size_t) 1 << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u)) -#define MERKLE_TREE_LEAF_NODE_AM(type) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type)) -#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((unsigned int) \ - (1u << MBEDTLS_LMS_H_TREE_HEIGHT(type))) - -#define D_CONST_LEN (2) -static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = { 0x82, 0x82 }; -static const unsigned char D_INTR_CONSTANT_BYTES[D_CONST_LEN] = { 0x83, 0x83 }; - - -/* Calculate the value of a leaf node of the Merkle tree (which is a hash of a - * public key and some other parameters like the leaf index). This function - * implements RFC8554 section 5.3, in the case where r >= 2^h. - * - * params The LMS parameter set, the underlying LMOTS - * parameter set, and I value which describe the key - * being used. - * - * pub_key The public key of the private whose index - * corresponds to the index of this leaf node. This - * is a hash output. - * - * r_node_idx The index of this node in the Merkle tree. Note - * that the root node of the Merkle tree is - * 1-indexed. - * - * out The output node value, which is a hash output. - */ -static int create_merkle_leaf_value(const mbedtls_lms_parameters_t *params, - unsigned char *pub_key, - unsigned int r_node_idx, - unsigned char *out) -{ - psa_hash_operation_t op; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned char r_node_idx_bytes[4]; - - /* Always zeroize the output buffer because it may contain data from the previous invocation */ - memset(out, 0, MBEDTLS_LMS_M_NODE_BYTES(params->type)); - - op = psa_hash_operation_init(); - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0); - status = psa_hash_update(&op, r_node_idx_bytes, 4); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_LEAF_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, pub_key, - MBEDTLS_LMOTS_N_HASH_LEN(params->otstype)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -/* Calculate the value of an internal node of the Merkle tree (which is a hash - * of a public key and some other parameters like the node index). This function - * implements RFC8554 section 5.3, in the case where r < 2^h. - * - * params The LMS parameter set, the underlying LMOTS - * parameter set, and I value which describe the key - * being used. - * - * left_node The value of the child of this node which is on - * the left-hand side. As with all nodes on the - * Merkle tree, this is a hash output. - * - * right_node The value of the child of this node which is on - * the right-hand side. As with all nodes on the - * Merkle tree, this is a hash output. - * - * r_node_idx The index of this node in the Merkle tree. Note - * that the root node of the Merkle tree is - * 1-indexed. - * - * out The output node value, which is a hash output. - */ -static int create_merkle_internal_value(const mbedtls_lms_parameters_t *params, - const unsigned char *left_node, - const unsigned char *right_node, - unsigned int r_node_idx, - unsigned char *out) -{ - psa_hash_operation_t op; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_hash_len; - unsigned char r_node_idx_bytes[4]; - - op = psa_hash_operation_init(); - status = psa_hash_setup(&op, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, params->I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0); - status = psa_hash_update(&op, r_node_idx_bytes, 4); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, D_INTR_CONSTANT_BYTES, D_CONST_LEN); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, left_node, - MBEDTLS_LMS_M_NODE_BYTES(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&op, right_node, - MBEDTLS_LMS_M_NODE_BYTES(params->type)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type), - &output_hash_len); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - psa_hash_abort(&op); - - return PSA_TO_MBEDTLS_ERR(status); -} - -void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(*ctx)); -} - -int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx, - const unsigned char *key, size_t key_size) -{ - if (key_size < 4) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - uint32_t type = MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET); - if (type != (uint32_t) MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - ctx->params.type = (mbedtls_lms_algorithm_type_t) type; - - if (key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - uint32_t otstype = MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET); - if (otstype != (uint32_t) MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - ctx->params.otstype = (mbedtls_lmots_algorithm_type_t) otstype; - - memcpy(ctx->params.I_key_identifier, - key + PUBLIC_KEY_I_KEY_ID_OFFSET, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - memcpy(ctx->T_1_pub_key, key + PUBLIC_KEY_ROOT_NODE_OFFSET, - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)); - - ctx->have_public_key = 1; - - return 0; -} - -int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx, - unsigned char *key, - size_t key_size, size_t *key_len) -{ - if (key_size < MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, PUBLIC_KEY_TYPE_OFFSET); - MBEDTLS_PUT_UINT32_BE(ctx->params.otstype, key, PUBLIC_KEY_OTSTYPE_OFFSET); - memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - memcpy(key +PUBLIC_KEY_ROOT_NODE_OFFSET, - ctx->T_1_pub_key, - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)); - - if (key_len != NULL) { - *key_len = MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type); - } - - return 0; -} - -int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx, - const unsigned char *msg, size_t msg_size, - const unsigned char *sig, size_t sig_size) -{ - unsigned int q_leaf_identifier; - unsigned char Kc_candidate_ots_pub_key[MBEDTLS_LMOTS_N_HASH_LEN_MAX]; - unsigned char Tc_candidate_root_node[MBEDTLS_LMS_M_NODE_BYTES_MAX]; - unsigned int height; - unsigned int curr_node_id; - unsigned int parent_node_id; - const unsigned char *left_node; - const unsigned char *right_node; - mbedtls_lmots_parameters_t ots_params; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (!ctx->have_public_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.type - != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.otstype - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size != MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (sig_size < SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (MBEDTLS_GET_UINT32_BE(sig, SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_SIG_TYPE_OFFSET) - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (sig_size < SIG_TYPE_OFFSET(ctx->params.otstype) + MBEDTLS_LMS_TYPE_LEN) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - if (MBEDTLS_GET_UINT32_BE(sig, SIG_TYPE_OFFSET(ctx->params.otstype)) - != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - - q_leaf_identifier = MBEDTLS_GET_UINT32_BE(sig, SIG_Q_LEAF_ID_OFFSET); - - if (q_leaf_identifier >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - memcpy(ots_params.I_key_identifier, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ots_params.q_leaf_identifier, 0); - ots_params.type = ctx->params.otstype; - - ret = mbedtls_lmots_calculate_public_key_candidate(&ots_params, - msg, - msg_size, - sig + SIG_OTS_SIG_OFFSET, - MBEDTLS_LMOTS_SIG_LEN(ctx->params.otstype), - Kc_candidate_ots_pub_key, - sizeof(Kc_candidate_ots_pub_key), - NULL); - if (ret != 0) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - ret = create_merkle_leaf_value( - &ctx->params, - Kc_candidate_ots_pub_key, - MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier, - Tc_candidate_root_node); - - if (ret != 0) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + - q_leaf_identifier; - - for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type); - height++) { - parent_node_id = curr_node_id / 2; - - /* Left/right node ordering matters for the hash */ - if (curr_node_id & 1) { - left_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) + - height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type); - right_node = Tc_candidate_root_node; - } else { - left_node = Tc_candidate_root_node; - right_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) + - height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type); - } - - ret = create_merkle_internal_value(&ctx->params, left_node, right_node, - parent_node_id, Tc_candidate_root_node); - if (ret != 0) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - curr_node_id /= 2; - } - - if (memcmp(Tc_candidate_root_node, ctx->T_1_pub_key, - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type))) { - return MBEDTLS_ERR_LMS_VERIFY_FAILED; - } - - return 0; -} - -#if defined(MBEDTLS_LMS_PRIVATE) - -/* Calculate a full Merkle tree based on a private key. This function - * implements RFC8554 section 5.3, and is used to generate a public key (as the - * public key is the root node of the Merkle tree). - * - * ctx The LMS private context, containing a parameter - * set and private key material consisting of both - * public and private OTS. - * - * tree The output tree, which is 2^(H + 1) hash outputs. - * In the case of H=10 we have 2048 tree nodes (of - * which 1024 of them are leaf nodes). Note that - * because the Merkle tree root is 1-indexed, the 0 - * index tree node is never used. - */ -static int calculate_merkle_tree(const mbedtls_lms_private_t *ctx, - unsigned char *tree) -{ - unsigned int priv_key_idx; - unsigned int r_node_idx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* First create the leaf nodes, in ascending order */ - for (priv_key_idx = 0; - priv_key_idx < MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type); - priv_key_idx++) { - r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + priv_key_idx; - - ret = create_merkle_leaf_value(&ctx->params, - ctx->ots_public_keys[priv_key_idx].public_key, - r_node_idx, - &tree[r_node_idx * MBEDTLS_LMS_M_NODE_BYTES( - ctx->params.type)]); - if (ret != 0) { - return ret; - } - } - - /* Then the internal nodes, in reverse order so that we can guarantee the - * parent has been created */ - for (r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) - 1; - r_node_idx > 0; - r_node_idx--) { - ret = create_merkle_internal_value(&ctx->params, - &tree[(r_node_idx * 2) * - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)], - &tree[(r_node_idx * 2 + 1) * - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)], - r_node_idx, - &tree[r_node_idx * - MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)]); - if (ret != 0) { - return ret; - } - } - - return 0; -} - -/* Calculate a path from a leaf node of the Merkle tree to the root of the tree, - * and return the full path. This function implements RFC8554 section 5.4.1, as - * the Merkle path is the main component of an LMS signature. - * - * ctx The LMS private context, containing a parameter - * set and private key material consisting of both - * public and private OTS. - * - * leaf_node_id Which leaf node to calculate the path from. - * - * path The output path, which is H hash outputs. - */ -static int get_merkle_path(mbedtls_lms_private_t *ctx, - unsigned int leaf_node_id, - unsigned char *path) -{ - const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type); - unsigned int curr_node_id = leaf_node_id; - unsigned int adjacent_node_id; - unsigned char *tree = NULL; - unsigned int height; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(ctx->params.type), - node_bytes); - if (tree == NULL) { - return MBEDTLS_ERR_LMS_ALLOC_FAILED; - } - - ret = calculate_merkle_tree(ctx, tree); - if (ret != 0) { - goto exit; - } - - for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type); - height++) { - adjacent_node_id = curr_node_id ^ 1; - - memcpy(&path[height * node_bytes], - &tree[adjacent_node_id * node_bytes], node_bytes); - - curr_node_id >>= 1; - } - - ret = 0; - -exit: - mbedtls_zeroize_and_free(tree, node_bytes * - (size_t) MERKLE_TREE_NODE_AM(ctx->params.type)); - - return ret; -} - -void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx) -{ - if (ctx == NULL) { - return; - } - - unsigned int idx; - - if (ctx->have_private_key) { - if (ctx->ots_private_keys != NULL) { - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - mbedtls_lmots_private_free(&ctx->ots_private_keys[idx]); - } - } - - if (ctx->ots_public_keys != NULL) { - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - mbedtls_lmots_public_free(&ctx->ots_public_keys[idx]); - } - } - - mbedtls_free(ctx->ots_private_keys); - mbedtls_free(ctx->ots_public_keys); - } - - mbedtls_platform_zeroize(ctx, sizeof(*ctx)); -} - - -int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx, - mbedtls_lms_algorithm_type_t type, - mbedtls_lmots_algorithm_type_t otstype, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, const unsigned char *seed, - size_t seed_size) -{ - unsigned int idx = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (type != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ctx->params.type = type; - ctx->params.otstype = otstype; - ctx->have_private_key = 1; - - ret = f_rng(p_rng, - ctx->params.I_key_identifier, - MBEDTLS_LMOTS_I_KEY_ID_LEN); - if (ret != 0) { - goto exit; - } - - /* Requires a cast to size_t to avoid an implicit cast warning on certain - * platforms (particularly Windows) */ - ctx->ots_private_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type), - sizeof(*ctx->ots_private_keys)); - if (ctx->ots_private_keys == NULL) { - ret = MBEDTLS_ERR_LMS_ALLOC_FAILED; - goto exit; - } - - /* Requires a cast to size_t to avoid an implicit cast warning on certain - * platforms (particularly Windows) */ - ctx->ots_public_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type), - sizeof(*ctx->ots_public_keys)); - if (ctx->ots_public_keys == NULL) { - ret = MBEDTLS_ERR_LMS_ALLOC_FAILED; - goto exit; - } - - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - mbedtls_lmots_private_init(&ctx->ots_private_keys[idx]); - mbedtls_lmots_public_init(&ctx->ots_public_keys[idx]); - } - - - for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) { - ret = mbedtls_lmots_generate_private_key(&ctx->ots_private_keys[idx], - otstype, - ctx->params.I_key_identifier, - idx, seed, seed_size); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_lmots_calculate_public_key(&ctx->ots_public_keys[idx], - &ctx->ots_private_keys[idx]); - if (ret != 0) { - goto exit; - } - } - - ctx->q_next_usable_key = 0; - -exit: - if (ret != 0) { - mbedtls_lms_private_free(ctx); - } - - return ret; -} - -int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx, - const mbedtls_lms_private_t *priv_ctx) -{ - const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(priv_ctx->params.type); - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *tree = NULL; - - if (!priv_ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (priv_ctx->params.type - != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (priv_ctx->params.otstype - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type), - node_bytes); - if (tree == NULL) { - return MBEDTLS_ERR_LMS_ALLOC_FAILED; - } - - memcpy(&ctx->params, &priv_ctx->params, - sizeof(mbedtls_lmots_parameters_t)); - - ret = calculate_merkle_tree(priv_ctx, tree); - if (ret != 0) { - goto exit; - } - - /* Root node is always at position 1, due to 1-based indexing */ - memcpy(ctx->T_1_pub_key, &tree[node_bytes], node_bytes); - - ctx->have_public_key = 1; - - ret = 0; - -exit: - mbedtls_zeroize_and_free(tree, node_bytes * - (size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type)); - - return ret; -} - - -int mbedtls_lms_sign(mbedtls_lms_private_t *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, const unsigned char *msg, - unsigned int msg_size, unsigned char *sig, size_t sig_size, - size_t *sig_len) -{ - uint32_t q_leaf_identifier; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (!ctx->have_private_key) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (sig_size < MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) { - return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL; - } - - if (ctx->params.type != MBEDTLS_LMS_SHA256_M32_H10) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->params.otstype - != MBEDTLS_LMOTS_SHA256_N32_W8) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - if (ctx->q_next_usable_key >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) { - return MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS; - } - - - q_leaf_identifier = ctx->q_next_usable_key; - /* This new value must _always_ be written back to the disk before the - * signature is returned. - */ - ctx->q_next_usable_key += 1; - - if (MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype) - < SIG_OTS_SIG_OFFSET) { - return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; - } - - ret = mbedtls_lmots_sign(&ctx->ots_private_keys[q_leaf_identifier], - f_rng, - p_rng, - msg, - msg_size, - sig + SIG_OTS_SIG_OFFSET, - MBEDTLS_LMS_SIG_LEN(ctx->params.type, - ctx->params.otstype) - SIG_OTS_SIG_OFFSET, - NULL); - if (ret != 0) { - return ret; - } - - MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, SIG_TYPE_OFFSET(ctx->params.otstype)); - MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, sig, SIG_Q_LEAF_ID_OFFSET); - - ret = get_merkle_path(ctx, - MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier, - sig + SIG_PATH_OFFSET(ctx->params.otstype)); - if (ret != 0) { - return ret; - } - - if (sig_len != NULL) { - *sig_len = MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype); - } - - - return 0; -} - -#endif /* defined(MBEDTLS_LMS_PRIVATE) */ -#endif /* defined(MBEDTLS_LMS_C) */ diff --git a/vendor/mbedtls/library/md.c b/vendor/mbedtls/library/md.c deleted file mode 100644 index c95846aa0..000000000 --- a/vendor/mbedtls/library/md.c +++ /dev/null @@ -1,1108 +0,0 @@ -/** - * \file md.c - * - * \brief Generic message digest wrapper for Mbed TLS - * - * \author Adriaan de Jong - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -/* - * Availability of functions in this module is controlled by two - * feature macros: - * - MBEDTLS_MD_C enables the whole module; - * - MBEDTLS_MD_LIGHT enables only functions for hashing and accessing - * most hash metadata (everything except string names); is it - * automatically set whenever MBEDTLS_MD_C is defined. - * - * In this file, functions from MD_LIGHT are at the top, MD_C at the end. - * - * In the future we may want to change the contract of some functions - * (behaviour with NULL arguments) depending on whether MD_C is defined or - * only MD_LIGHT. Also, the exact scope of MD_LIGHT might vary. - * - * For these reasons, we're keeping MD_LIGHT internal for now. - */ -#if defined(MBEDTLS_MD_LIGHT) - -#include "mbedtls/md.h" -#include "md_wrap.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include "mbedtls/md5.h" -#include "mbedtls/ripemd160.h" -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" -#include "mbedtls/sha512.h" -#include "mbedtls/sha3.h" - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#include -#include "md_psa.h" -#include "psa_util_internal.h" -#endif - -#if defined(MBEDTLS_MD_SOME_PSA) -#include "psa_crypto_core.h" -#endif - -#include "mbedtls/platform.h" - -#include - -#if defined(MBEDTLS_FS_IO) -#include -#endif - -/* See comment above MBEDTLS_MD_MAX_SIZE in md.h */ -#if defined(MBEDTLS_PSA_CRYPTO_C) && MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE -#error "Internal error: MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE" -#endif - -#if defined(MBEDTLS_MD_C) -#define MD_INFO(type, out_size, block_size) type, out_size, block_size, -#else -#define MD_INFO(type, out_size, block_size) type, out_size, -#endif - -#if defined(MBEDTLS_MD_CAN_MD5) -static const mbedtls_md_info_t mbedtls_md5_info = { - MD_INFO(MBEDTLS_MD_MD5, 16, 64) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_RIPEMD160) -static const mbedtls_md_info_t mbedtls_ripemd160_info = { - MD_INFO(MBEDTLS_MD_RIPEMD160, 20, 64) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA1) -static const mbedtls_md_info_t mbedtls_sha1_info = { - MD_INFO(MBEDTLS_MD_SHA1, 20, 64) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA224) -static const mbedtls_md_info_t mbedtls_sha224_info = { - MD_INFO(MBEDTLS_MD_SHA224, 28, 64) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA256) -static const mbedtls_md_info_t mbedtls_sha256_info = { - MD_INFO(MBEDTLS_MD_SHA256, 32, 64) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) -static const mbedtls_md_info_t mbedtls_sha384_info = { - MD_INFO(MBEDTLS_MD_SHA384, 48, 128) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA512) -static const mbedtls_md_info_t mbedtls_sha512_info = { - MD_INFO(MBEDTLS_MD_SHA512, 64, 128) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_224) -static const mbedtls_md_info_t mbedtls_sha3_224_info = { - MD_INFO(MBEDTLS_MD_SHA3_224, 28, 144) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_256) -static const mbedtls_md_info_t mbedtls_sha3_256_info = { - MD_INFO(MBEDTLS_MD_SHA3_256, 32, 136) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_384) -static const mbedtls_md_info_t mbedtls_sha3_384_info = { - MD_INFO(MBEDTLS_MD_SHA3_384, 48, 104) -}; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_512) -static const mbedtls_md_info_t mbedtls_sha3_512_info = { - MD_INFO(MBEDTLS_MD_SHA3_512, 64, 72) -}; -#endif - -const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) -{ - switch (md_type) { -#if defined(MBEDTLS_MD_CAN_MD5) - case MBEDTLS_MD_MD5: - return &mbedtls_md5_info; -#endif -#if defined(MBEDTLS_MD_CAN_RIPEMD160) - case MBEDTLS_MD_RIPEMD160: - return &mbedtls_ripemd160_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA1) - case MBEDTLS_MD_SHA1: - return &mbedtls_sha1_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA224) - case MBEDTLS_MD_SHA224: - return &mbedtls_sha224_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_MD_SHA256: - return &mbedtls_sha256_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_MD_SHA384: - return &mbedtls_sha384_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA512) - case MBEDTLS_MD_SHA512: - return &mbedtls_sha512_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_224) - case MBEDTLS_MD_SHA3_224: - return &mbedtls_sha3_224_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_256) - case MBEDTLS_MD_SHA3_256: - return &mbedtls_sha3_256_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_384) - case MBEDTLS_MD_SHA3_384: - return &mbedtls_sha3_384_info; -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_512) - case MBEDTLS_MD_SHA3_512: - return &mbedtls_sha3_512_info; -#endif - default: - return NULL; - } -} - -#if defined(MBEDTLS_MD_SOME_PSA) -static psa_algorithm_t psa_alg_of_md(const mbedtls_md_info_t *info) -{ - switch (info->type) { -#if defined(MBEDTLS_MD_MD5_VIA_PSA) - case MBEDTLS_MD_MD5: - return PSA_ALG_MD5; -#endif -#if defined(MBEDTLS_MD_RIPEMD160_VIA_PSA) - case MBEDTLS_MD_RIPEMD160: - return PSA_ALG_RIPEMD160; -#endif -#if defined(MBEDTLS_MD_SHA1_VIA_PSA) - case MBEDTLS_MD_SHA1: - return PSA_ALG_SHA_1; -#endif -#if defined(MBEDTLS_MD_SHA224_VIA_PSA) - case MBEDTLS_MD_SHA224: - return PSA_ALG_SHA_224; -#endif -#if defined(MBEDTLS_MD_SHA256_VIA_PSA) - case MBEDTLS_MD_SHA256: - return PSA_ALG_SHA_256; -#endif -#if defined(MBEDTLS_MD_SHA384_VIA_PSA) - case MBEDTLS_MD_SHA384: - return PSA_ALG_SHA_384; -#endif -#if defined(MBEDTLS_MD_SHA512_VIA_PSA) - case MBEDTLS_MD_SHA512: - return PSA_ALG_SHA_512; -#endif -#if defined(MBEDTLS_MD_SHA3_224_VIA_PSA) - case MBEDTLS_MD_SHA3_224: - return PSA_ALG_SHA3_224; -#endif -#if defined(MBEDTLS_MD_SHA3_256_VIA_PSA) - case MBEDTLS_MD_SHA3_256: - return PSA_ALG_SHA3_256; -#endif -#if defined(MBEDTLS_MD_SHA3_384_VIA_PSA) - case MBEDTLS_MD_SHA3_384: - return PSA_ALG_SHA3_384; -#endif -#if defined(MBEDTLS_MD_SHA3_512_VIA_PSA) - case MBEDTLS_MD_SHA3_512: - return PSA_ALG_SHA3_512; -#endif - default: - return PSA_ALG_NONE; - } -} - -static int md_can_use_psa(const mbedtls_md_info_t *info) -{ - psa_algorithm_t alg = psa_alg_of_md(info); - if (alg == PSA_ALG_NONE) { - return 0; - } - - return psa_can_do_hash(alg); -} -#endif /* MBEDTLS_MD_SOME_PSA */ - -void mbedtls_md_init(mbedtls_md_context_t *ctx) -{ - /* Note: this sets engine (if present) to MBEDTLS_MD_ENGINE_LEGACY */ - memset(ctx, 0, sizeof(mbedtls_md_context_t)); -} - -void mbedtls_md_free(mbedtls_md_context_t *ctx) -{ - if (ctx == NULL || ctx->md_info == NULL) { - return; - } - - if (ctx->md_ctx != NULL) { -#if defined(MBEDTLS_MD_SOME_PSA) - if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { - psa_hash_abort(ctx->md_ctx); - } else -#endif - switch (ctx->md_info->type) { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - mbedtls_md5_free(ctx->md_ctx); - break; -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - mbedtls_ripemd160_free(ctx->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - mbedtls_sha1_free(ctx->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA224_C) - case MBEDTLS_MD_SHA224: - mbedtls_sha256_free(ctx->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA256: - mbedtls_sha256_free(ctx->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA384_C) - case MBEDTLS_MD_SHA384: - mbedtls_sha512_free(ctx->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA512: - mbedtls_sha512_free(ctx->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA3_C) - case MBEDTLS_MD_SHA3_224: - case MBEDTLS_MD_SHA3_256: - case MBEDTLS_MD_SHA3_384: - case MBEDTLS_MD_SHA3_512: - mbedtls_sha3_free(ctx->md_ctx); - break; -#endif - default: - /* Shouldn't happen */ - break; - } - mbedtls_free(ctx->md_ctx); - } - -#if defined(MBEDTLS_MD_C) - if (ctx->hmac_ctx != NULL) { - mbedtls_zeroize_and_free(ctx->hmac_ctx, - 2 * ctx->md_info->block_size); - } -#endif - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md_context_t)); -} - -int mbedtls_md_clone(mbedtls_md_context_t *dst, - const mbedtls_md_context_t *src) -{ - if (dst == NULL || dst->md_info == NULL || - src == NULL || src->md_info == NULL || - dst->md_info != src->md_info) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_MD_SOME_PSA) - if (src->engine != dst->engine) { - /* This can happen with src set to legacy because PSA wasn't ready - * yet, and dst to PSA because it became ready in the meantime. - * We currently don't support that case (we'd need to re-allocate - * md_ctx to the size of the appropriate MD context). */ - return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; - } - - if (src->engine == MBEDTLS_MD_ENGINE_PSA) { - psa_status_t status = psa_hash_clone(src->md_ctx, dst->md_ctx); - return mbedtls_md_error_from_psa(status); - } -#endif - - switch (src->md_info->type) { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - mbedtls_md5_clone(dst->md_ctx, src->md_ctx); - break; -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - mbedtls_ripemd160_clone(dst->md_ctx, src->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - mbedtls_sha1_clone(dst->md_ctx, src->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA224_C) - case MBEDTLS_MD_SHA224: - mbedtls_sha256_clone(dst->md_ctx, src->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA256: - mbedtls_sha256_clone(dst->md_ctx, src->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA384_C) - case MBEDTLS_MD_SHA384: - mbedtls_sha512_clone(dst->md_ctx, src->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA512: - mbedtls_sha512_clone(dst->md_ctx, src->md_ctx); - break; -#endif -#if defined(MBEDTLS_SHA3_C) - case MBEDTLS_MD_SHA3_224: - case MBEDTLS_MD_SHA3_256: - case MBEDTLS_MD_SHA3_384: - case MBEDTLS_MD_SHA3_512: - mbedtls_sha3_clone(dst->md_ctx, src->md_ctx); - break; -#endif - default: - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - return 0; -} - -#define ALLOC(type) \ - do { \ - ctx->md_ctx = mbedtls_calloc(1, sizeof(mbedtls_##type##_context)); \ - if (ctx->md_ctx == NULL) \ - return MBEDTLS_ERR_MD_ALLOC_FAILED; \ - mbedtls_##type##_init(ctx->md_ctx); \ - } \ - while (0) - -int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac) -{ -#if defined(MBEDTLS_MD_C) - if (ctx == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -#endif - if (md_info == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - ctx->md_info = md_info; - ctx->md_ctx = NULL; -#if defined(MBEDTLS_MD_C) - ctx->hmac_ctx = NULL; -#else - if (hmac != 0) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -#endif - -#if defined(MBEDTLS_MD_SOME_PSA) - if (md_can_use_psa(ctx->md_info)) { - ctx->md_ctx = mbedtls_calloc(1, sizeof(psa_hash_operation_t)); - if (ctx->md_ctx == NULL) { - return MBEDTLS_ERR_MD_ALLOC_FAILED; - } - ctx->engine = MBEDTLS_MD_ENGINE_PSA; - } else -#endif - switch (md_info->type) { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - ALLOC(md5); - break; -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - ALLOC(ripemd160); - break; -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - ALLOC(sha1); - break; -#endif -#if defined(MBEDTLS_SHA224_C) - case MBEDTLS_MD_SHA224: - ALLOC(sha256); - break; -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA256: - ALLOC(sha256); - break; -#endif -#if defined(MBEDTLS_SHA384_C) - case MBEDTLS_MD_SHA384: - ALLOC(sha512); - break; -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA512: - ALLOC(sha512); - break; -#endif -#if defined(MBEDTLS_SHA3_C) - case MBEDTLS_MD_SHA3_224: - case MBEDTLS_MD_SHA3_256: - case MBEDTLS_MD_SHA3_384: - case MBEDTLS_MD_SHA3_512: - ALLOC(sha3); - break; -#endif - default: - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_MD_C) - if (hmac != 0) { - ctx->hmac_ctx = mbedtls_calloc(2, md_info->block_size); - if (ctx->hmac_ctx == NULL) { - mbedtls_md_free(ctx); - return MBEDTLS_ERR_MD_ALLOC_FAILED; - } - } -#endif - - return 0; -} -#undef ALLOC - -int mbedtls_md_starts(mbedtls_md_context_t *ctx) -{ -#if defined(MBEDTLS_MD_C) - if (ctx == NULL || ctx->md_info == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -#endif - -#if defined(MBEDTLS_MD_SOME_PSA) - if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { - psa_algorithm_t alg = psa_alg_of_md(ctx->md_info); - psa_hash_abort(ctx->md_ctx); - psa_status_t status = psa_hash_setup(ctx->md_ctx, alg); - return mbedtls_md_error_from_psa(status); - } -#endif - - switch (ctx->md_info->type) { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return mbedtls_md5_starts(ctx->md_ctx); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - return mbedtls_ripemd160_starts(ctx->md_ctx); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return mbedtls_sha1_starts(ctx->md_ctx); -#endif -#if defined(MBEDTLS_SHA224_C) - case MBEDTLS_MD_SHA224: - return mbedtls_sha256_starts(ctx->md_ctx, 1); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA256: - return mbedtls_sha256_starts(ctx->md_ctx, 0); -#endif -#if defined(MBEDTLS_SHA384_C) - case MBEDTLS_MD_SHA384: - return mbedtls_sha512_starts(ctx->md_ctx, 1); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA512: - return mbedtls_sha512_starts(ctx->md_ctx, 0); -#endif -#if defined(MBEDTLS_SHA3_C) - case MBEDTLS_MD_SHA3_224: - return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_224); - case MBEDTLS_MD_SHA3_256: - return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_256); - case MBEDTLS_MD_SHA3_384: - return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_384); - case MBEDTLS_MD_SHA3_512: - return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_512); -#endif - default: - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -} - -int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen) -{ -#if defined(MBEDTLS_MD_C) - if (ctx == NULL || ctx->md_info == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -#endif - -#if defined(MBEDTLS_MD_SOME_PSA) - if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { - psa_status_t status = psa_hash_update(ctx->md_ctx, input, ilen); - return mbedtls_md_error_from_psa(status); - } -#endif - - switch (ctx->md_info->type) { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return mbedtls_md5_update(ctx->md_ctx, input, ilen); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - return mbedtls_ripemd160_update(ctx->md_ctx, input, ilen); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return mbedtls_sha1_update(ctx->md_ctx, input, ilen); -#endif -#if defined(MBEDTLS_SHA224_C) - case MBEDTLS_MD_SHA224: - return mbedtls_sha256_update(ctx->md_ctx, input, ilen); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA256: - return mbedtls_sha256_update(ctx->md_ctx, input, ilen); -#endif -#if defined(MBEDTLS_SHA384_C) - case MBEDTLS_MD_SHA384: - return mbedtls_sha512_update(ctx->md_ctx, input, ilen); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA512: - return mbedtls_sha512_update(ctx->md_ctx, input, ilen); -#endif -#if defined(MBEDTLS_SHA3_C) - case MBEDTLS_MD_SHA3_224: - case MBEDTLS_MD_SHA3_256: - case MBEDTLS_MD_SHA3_384: - case MBEDTLS_MD_SHA3_512: - return mbedtls_sha3_update(ctx->md_ctx, input, ilen); -#endif - default: - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -} - -int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output) -{ -#if defined(MBEDTLS_MD_C) - if (ctx == NULL || ctx->md_info == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -#endif - -#if defined(MBEDTLS_MD_SOME_PSA) - if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { - size_t size = ctx->md_info->size; - psa_status_t status = psa_hash_finish(ctx->md_ctx, - output, size, &size); - return mbedtls_md_error_from_psa(status); - } -#endif - - switch (ctx->md_info->type) { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return mbedtls_md5_finish(ctx->md_ctx, output); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - return mbedtls_ripemd160_finish(ctx->md_ctx, output); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return mbedtls_sha1_finish(ctx->md_ctx, output); -#endif -#if defined(MBEDTLS_SHA224_C) - case MBEDTLS_MD_SHA224: - return mbedtls_sha256_finish(ctx->md_ctx, output); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA256: - return mbedtls_sha256_finish(ctx->md_ctx, output); -#endif -#if defined(MBEDTLS_SHA384_C) - case MBEDTLS_MD_SHA384: - return mbedtls_sha512_finish(ctx->md_ctx, output); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA512: - return mbedtls_sha512_finish(ctx->md_ctx, output); -#endif -#if defined(MBEDTLS_SHA3_C) - case MBEDTLS_MD_SHA3_224: - case MBEDTLS_MD_SHA3_256: - case MBEDTLS_MD_SHA3_384: - case MBEDTLS_MD_SHA3_512: - return mbedtls_sha3_finish(ctx->md_ctx, output, ctx->md_info->size); -#endif - default: - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -} - -int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, - unsigned char *output) -{ - if (md_info == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_MD_SOME_PSA) - if (md_can_use_psa(md_info)) { - size_t size = md_info->size; - psa_status_t status = psa_hash_compute(psa_alg_of_md(md_info), - input, ilen, - output, size, &size); - return mbedtls_md_error_from_psa(status); - } -#endif - - switch (md_info->type) { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return mbedtls_md5(input, ilen, output); -#endif -#if defined(MBEDTLS_RIPEMD160_C) - case MBEDTLS_MD_RIPEMD160: - return mbedtls_ripemd160(input, ilen, output); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return mbedtls_sha1(input, ilen, output); -#endif -#if defined(MBEDTLS_SHA224_C) - case MBEDTLS_MD_SHA224: - return mbedtls_sha256(input, ilen, output, 1); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA256: - return mbedtls_sha256(input, ilen, output, 0); -#endif -#if defined(MBEDTLS_SHA384_C) - case MBEDTLS_MD_SHA384: - return mbedtls_sha512(input, ilen, output, 1); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA512: - return mbedtls_sha512(input, ilen, output, 0); -#endif -#if defined(MBEDTLS_SHA3_C) - case MBEDTLS_MD_SHA3_224: - return mbedtls_sha3(MBEDTLS_SHA3_224, input, ilen, output, md_info->size); - case MBEDTLS_MD_SHA3_256: - return mbedtls_sha3(MBEDTLS_SHA3_256, input, ilen, output, md_info->size); - case MBEDTLS_MD_SHA3_384: - return mbedtls_sha3(MBEDTLS_SHA3_384, input, ilen, output, md_info->size); - case MBEDTLS_MD_SHA3_512: - return mbedtls_sha3(MBEDTLS_SHA3_512, input, ilen, output, md_info->size); -#endif - default: - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } -} - -unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info) -{ - if (md_info == NULL) { - return 0; - } - - return md_info->size; -} - -mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info) -{ - if (md_info == NULL) { - return MBEDTLS_MD_NONE; - } - - return md_info->type; -} - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -int mbedtls_md_error_from_psa(psa_status_t status) -{ - return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors, - psa_generic_status_to_mbedtls); -} -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ - - -/************************************************************************ - * Functions above this separator are part of MBEDTLS_MD_LIGHT, * - * functions below are only available when MBEDTLS_MD_C is set. * - ************************************************************************/ -#if defined(MBEDTLS_MD_C) - -/* - * Reminder: update profiles in x509_crt.c when adding a new hash! - */ -static const int supported_digests[] = { - -#if defined(MBEDTLS_MD_CAN_SHA512) - MBEDTLS_MD_SHA512, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) - MBEDTLS_MD_SHA384, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA256) - MBEDTLS_MD_SHA256, -#endif -#if defined(MBEDTLS_MD_CAN_SHA224) - MBEDTLS_MD_SHA224, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA1) - MBEDTLS_MD_SHA1, -#endif - -#if defined(MBEDTLS_MD_CAN_RIPEMD160) - MBEDTLS_MD_RIPEMD160, -#endif - -#if defined(MBEDTLS_MD_CAN_MD5) - MBEDTLS_MD_MD5, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_224) - MBEDTLS_MD_SHA3_224, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_256) - MBEDTLS_MD_SHA3_256, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_384) - MBEDTLS_MD_SHA3_384, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA3_512) - MBEDTLS_MD_SHA3_512, -#endif - - MBEDTLS_MD_NONE -}; - -const int *mbedtls_md_list(void) -{ - return supported_digests; -} - -typedef struct { - const char *md_name; - mbedtls_md_type_t md_type; -} md_name_entry; - -static const md_name_entry md_names[] = { -#if defined(MBEDTLS_MD_CAN_MD5) - { "MD5", MBEDTLS_MD_MD5 }, -#endif -#if defined(MBEDTLS_MD_CAN_RIPEMD160) - { "RIPEMD160", MBEDTLS_MD_RIPEMD160 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA1) - { "SHA1", MBEDTLS_MD_SHA1 }, - { "SHA", MBEDTLS_MD_SHA1 }, // compatibility fallback -#endif -#if defined(MBEDTLS_MD_CAN_SHA224) - { "SHA224", MBEDTLS_MD_SHA224 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - { "SHA256", MBEDTLS_MD_SHA256 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) - { "SHA384", MBEDTLS_MD_SHA384 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA512) - { "SHA512", MBEDTLS_MD_SHA512 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_224) - { "SHA3-224", MBEDTLS_MD_SHA3_224 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_256) - { "SHA3-256", MBEDTLS_MD_SHA3_256 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_384) - { "SHA3-384", MBEDTLS_MD_SHA3_384 }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_512) - { "SHA3-512", MBEDTLS_MD_SHA3_512 }, -#endif - { NULL, MBEDTLS_MD_NONE }, -}; - -const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name) -{ - if (NULL == md_name) { - return NULL; - } - - const md_name_entry *entry = md_names; - while (entry->md_name != NULL && - strcmp(entry->md_name, md_name) != 0) { - ++entry; - } - - return mbedtls_md_info_from_type(entry->md_type); -} - -const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info) -{ - if (md_info == NULL) { - return NULL; - } - - const md_name_entry *entry = md_names; - while (entry->md_type != MBEDTLS_MD_NONE && - entry->md_type != md_info->type) { - ++entry; - } - - return entry->md_name; -} - -const mbedtls_md_info_t *mbedtls_md_info_from_ctx( - const mbedtls_md_context_t *ctx) -{ - if (ctx == NULL) { - return NULL; - } - - return ctx->MBEDTLS_PRIVATE(md_info); -} - -#if defined(MBEDTLS_FS_IO) -int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - FILE *f; - size_t n; - mbedtls_md_context_t ctx; - unsigned char buf[1024]; - - if (md_info == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - if ((f = fopen(path, "rb")) == NULL) { - return MBEDTLS_ERR_MD_FILE_IO_ERROR; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - mbedtls_md_init(&ctx); - - if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_md_starts(&ctx)) != 0) { - goto cleanup; - } - - while ((n = fread(buf, 1, sizeof(buf), f)) > 0) { - if ((ret = mbedtls_md_update(&ctx, buf, n)) != 0) { - goto cleanup; - } - } - - if (ferror(f) != 0) { - ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; - } else { - ret = mbedtls_md_finish(&ctx, output); - } - -cleanup: - mbedtls_platform_zeroize(buf, sizeof(buf)); - fclose(f); - mbedtls_md_free(&ctx); - - return ret; -} -#endif /* MBEDTLS_FS_IO */ - -int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char sum[MBEDTLS_MD_MAX_SIZE]; - unsigned char *ipad, *opad; - - if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - if (keylen > (size_t) ctx->md_info->block_size) { - if ((ret = mbedtls_md_starts(ctx)) != 0) { - goto cleanup; - } - if ((ret = mbedtls_md_update(ctx, key, keylen)) != 0) { - goto cleanup; - } - if ((ret = mbedtls_md_finish(ctx, sum)) != 0) { - goto cleanup; - } - - keylen = ctx->md_info->size; - key = sum; - } - - ipad = (unsigned char *) ctx->hmac_ctx; - opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - - memset(ipad, 0x36, ctx->md_info->block_size); - memset(opad, 0x5C, ctx->md_info->block_size); - - mbedtls_xor(ipad, ipad, key, keylen); - mbedtls_xor(opad, opad, key, keylen); - - if ((ret = mbedtls_md_starts(ctx)) != 0) { - goto cleanup; - } - if ((ret = mbedtls_md_update(ctx, ipad, - ctx->md_info->block_size)) != 0) { - goto cleanup; - } - -cleanup: - mbedtls_platform_zeroize(sum, sizeof(sum)); - - return ret; -} - -int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen) -{ - if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - return mbedtls_md_update(ctx, input, ilen); -} - -int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; - unsigned char *opad; - - if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - - if ((ret = mbedtls_md_finish(ctx, tmp)) != 0) { - return ret; - } - if ((ret = mbedtls_md_starts(ctx)) != 0) { - return ret; - } - if ((ret = mbedtls_md_update(ctx, opad, - ctx->md_info->block_size)) != 0) { - return ret; - } - if ((ret = mbedtls_md_update(ctx, tmp, - ctx->md_info->size)) != 0) { - return ret; - } - return mbedtls_md_finish(ctx, output); -} - -int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *ipad; - - if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - ipad = (unsigned char *) ctx->hmac_ctx; - - if ((ret = mbedtls_md_starts(ctx)) != 0) { - return ret; - } - return mbedtls_md_update(ctx, ipad, ctx->md_info->block_size); -} - -int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, - const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output) -{ - mbedtls_md_context_t ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (md_info == NULL) { - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - mbedtls_md_init(&ctx); - - if ((ret = mbedtls_md_setup(&ctx, md_info, 1)) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_md_hmac_starts(&ctx, key, keylen)) != 0) { - goto cleanup; - } - if ((ret = mbedtls_md_hmac_update(&ctx, input, ilen)) != 0) { - goto cleanup; - } - if ((ret = mbedtls_md_hmac_finish(&ctx, output)) != 0) { - goto cleanup; - } - -cleanup: - mbedtls_md_free(&ctx); - - return ret; -} - -#endif /* MBEDTLS_MD_C */ - -#endif /* MBEDTLS_MD_LIGHT */ diff --git a/vendor/mbedtls/library/md5.c b/vendor/mbedtls/library/md5.c deleted file mode 100644 index e4a87a2e0..000000000 --- a/vendor/mbedtls/library/md5.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -#include "common.h" - -#if defined(MBEDTLS_MD5_C) - -#include "mbedtls/md5.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_MD5_ALT) - -void mbedtls_md5_init(mbedtls_md5_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_md5_context)); -} - -void mbedtls_md5_free(mbedtls_md5_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md5_context)); -} - -void mbedtls_md5_clone(mbedtls_md5_context *dst, - const mbedtls_md5_context *src) -{ - *dst = *src; -} - -/* - * MD5 context setup - */ -int mbedtls_md5_starts(mbedtls_md5_context *ctx) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - - return 0; -} - -#if !defined(MBEDTLS_MD5_PROCESS_ALT) -int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, - const unsigned char data[64]) -{ - struct { - uint32_t X[16], A, B, C, D; - } local; - - local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0); - local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4); - local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8); - local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12); - local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16); - local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20); - local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24); - local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28); - local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32); - local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36); - local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40); - local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44); - local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48); - local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52); - local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56); - local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60); - -#define S(x, n) \ - (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - -#define P(a, b, c, d, k, s, t) \ - do \ - { \ - (a) += F((b), (c), (d)) + local.X[(k)] + (t); \ - (a) = S((a), (s)) + (b); \ - } while (0) - - local.A = ctx->state[0]; - local.B = ctx->state[1]; - local.C = ctx->state[2]; - local.D = ctx->state[3]; - -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) - - P(local.A, local.B, local.C, local.D, 0, 7, 0xD76AA478); - P(local.D, local.A, local.B, local.C, 1, 12, 0xE8C7B756); - P(local.C, local.D, local.A, local.B, 2, 17, 0x242070DB); - P(local.B, local.C, local.D, local.A, 3, 22, 0xC1BDCEEE); - P(local.A, local.B, local.C, local.D, 4, 7, 0xF57C0FAF); - P(local.D, local.A, local.B, local.C, 5, 12, 0x4787C62A); - P(local.C, local.D, local.A, local.B, 6, 17, 0xA8304613); - P(local.B, local.C, local.D, local.A, 7, 22, 0xFD469501); - P(local.A, local.B, local.C, local.D, 8, 7, 0x698098D8); - P(local.D, local.A, local.B, local.C, 9, 12, 0x8B44F7AF); - P(local.C, local.D, local.A, local.B, 10, 17, 0xFFFF5BB1); - P(local.B, local.C, local.D, local.A, 11, 22, 0x895CD7BE); - P(local.A, local.B, local.C, local.D, 12, 7, 0x6B901122); - P(local.D, local.A, local.B, local.C, 13, 12, 0xFD987193); - P(local.C, local.D, local.A, local.B, 14, 17, 0xA679438E); - P(local.B, local.C, local.D, local.A, 15, 22, 0x49B40821); - -#undef F - -#define F(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) - - P(local.A, local.B, local.C, local.D, 1, 5, 0xF61E2562); - P(local.D, local.A, local.B, local.C, 6, 9, 0xC040B340); - P(local.C, local.D, local.A, local.B, 11, 14, 0x265E5A51); - P(local.B, local.C, local.D, local.A, 0, 20, 0xE9B6C7AA); - P(local.A, local.B, local.C, local.D, 5, 5, 0xD62F105D); - P(local.D, local.A, local.B, local.C, 10, 9, 0x02441453); - P(local.C, local.D, local.A, local.B, 15, 14, 0xD8A1E681); - P(local.B, local.C, local.D, local.A, 4, 20, 0xE7D3FBC8); - P(local.A, local.B, local.C, local.D, 9, 5, 0x21E1CDE6); - P(local.D, local.A, local.B, local.C, 14, 9, 0xC33707D6); - P(local.C, local.D, local.A, local.B, 3, 14, 0xF4D50D87); - P(local.B, local.C, local.D, local.A, 8, 20, 0x455A14ED); - P(local.A, local.B, local.C, local.D, 13, 5, 0xA9E3E905); - P(local.D, local.A, local.B, local.C, 2, 9, 0xFCEFA3F8); - P(local.C, local.D, local.A, local.B, 7, 14, 0x676F02D9); - P(local.B, local.C, local.D, local.A, 12, 20, 0x8D2A4C8A); - -#undef F - -#define F(x, y, z) ((x) ^ (y) ^ (z)) - - P(local.A, local.B, local.C, local.D, 5, 4, 0xFFFA3942); - P(local.D, local.A, local.B, local.C, 8, 11, 0x8771F681); - P(local.C, local.D, local.A, local.B, 11, 16, 0x6D9D6122); - P(local.B, local.C, local.D, local.A, 14, 23, 0xFDE5380C); - P(local.A, local.B, local.C, local.D, 1, 4, 0xA4BEEA44); - P(local.D, local.A, local.B, local.C, 4, 11, 0x4BDECFA9); - P(local.C, local.D, local.A, local.B, 7, 16, 0xF6BB4B60); - P(local.B, local.C, local.D, local.A, 10, 23, 0xBEBFBC70); - P(local.A, local.B, local.C, local.D, 13, 4, 0x289B7EC6); - P(local.D, local.A, local.B, local.C, 0, 11, 0xEAA127FA); - P(local.C, local.D, local.A, local.B, 3, 16, 0xD4EF3085); - P(local.B, local.C, local.D, local.A, 6, 23, 0x04881D05); - P(local.A, local.B, local.C, local.D, 9, 4, 0xD9D4D039); - P(local.D, local.A, local.B, local.C, 12, 11, 0xE6DB99E5); - P(local.C, local.D, local.A, local.B, 15, 16, 0x1FA27CF8); - P(local.B, local.C, local.D, local.A, 2, 23, 0xC4AC5665); - -#undef F - -#define F(x, y, z) ((y) ^ ((x) | ~(z))) - - P(local.A, local.B, local.C, local.D, 0, 6, 0xF4292244); - P(local.D, local.A, local.B, local.C, 7, 10, 0x432AFF97); - P(local.C, local.D, local.A, local.B, 14, 15, 0xAB9423A7); - P(local.B, local.C, local.D, local.A, 5, 21, 0xFC93A039); - P(local.A, local.B, local.C, local.D, 12, 6, 0x655B59C3); - P(local.D, local.A, local.B, local.C, 3, 10, 0x8F0CCC92); - P(local.C, local.D, local.A, local.B, 10, 15, 0xFFEFF47D); - P(local.B, local.C, local.D, local.A, 1, 21, 0x85845DD1); - P(local.A, local.B, local.C, local.D, 8, 6, 0x6FA87E4F); - P(local.D, local.A, local.B, local.C, 15, 10, 0xFE2CE6E0); - P(local.C, local.D, local.A, local.B, 6, 15, 0xA3014314); - P(local.B, local.C, local.D, local.A, 13, 21, 0x4E0811A1); - P(local.A, local.B, local.C, local.D, 4, 6, 0xF7537E82); - P(local.D, local.A, local.B, local.C, 11, 10, 0xBD3AF235); - P(local.C, local.D, local.A, local.B, 2, 15, 0x2AD7D2BB); - P(local.B, local.C, local.D, local.A, 9, 21, 0xEB86D391); - -#undef F - - ctx->state[0] += local.A; - ctx->state[1] += local.B; - ctx->state[2] += local.C; - ctx->state[3] += local.D; - - /* Zeroise variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize(&local, sizeof(local)); - - return 0; -} - -#endif /* !MBEDTLS_MD5_PROCESS_ALT */ - -/* - * MD5 process buffer - */ -int mbedtls_md5_update(mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t fill; - uint32_t left; - - if (ilen == 0) { - return 0; - } - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if (ctx->total[0] < (uint32_t) ilen) { - ctx->total[1]++; - } - - if (left && ilen >= fill) { - memcpy((void *) (ctx->buffer + left), input, fill); - if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0) { - return ret; - } - - input += fill; - ilen -= fill; - left = 0; - } - - while (ilen >= 64) { - if ((ret = mbedtls_internal_md5_process(ctx, input)) != 0) { - return ret; - } - - input += 64; - ilen -= 64; - } - - if (ilen > 0) { - memcpy((void *) (ctx->buffer + left), input, ilen); - } - - return 0; -} - -/* - * MD5 final digest - */ -int mbedtls_md5_finish(mbedtls_md5_context *ctx, - unsigned char output[16]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint32_t used; - uint32_t high, low; - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if (used <= 56) { - /* Enough room for padding + length in current block */ - memset(ctx->buffer + used, 0, 56 - used); - } else { - /* We'll need an extra block */ - memset(ctx->buffer + used, 0, 64 - used); - - if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - memset(ctx->buffer, 0, 56); - } - - /* - * Add message length - */ - high = (ctx->total[0] >> 29) - | (ctx->total[1] << 3); - low = (ctx->total[0] << 3); - - MBEDTLS_PUT_UINT32_LE(low, ctx->buffer, 56); - MBEDTLS_PUT_UINT32_LE(high, ctx->buffer, 60); - - if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - /* - * Output final state - */ - MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0); - MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4); - MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8); - MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12); - - ret = 0; - -exit: - mbedtls_md5_free(ctx); - return ret; -} - -#endif /* !MBEDTLS_MD5_ALT */ - -/* - * output = MD5( input buffer ) - */ -int mbedtls_md5(const unsigned char *input, - size_t ilen, - unsigned char output[16]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md5_context ctx; - - mbedtls_md5_init(&ctx); - - if ((ret = mbedtls_md5_starts(&ctx)) != 0) { - goto exit; - } - - if ((ret = mbedtls_md5_update(&ctx, input, ilen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_md5_finish(&ctx, output)) != 0) { - goto exit; - } - -exit: - mbedtls_md5_free(&ctx); - - return ret; -} - -#if defined(MBEDTLS_SELF_TEST) -/* - * RFC 1321 test vectors - */ -static const unsigned char md5_test_buf[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" } -}; - -static const size_t md5_test_buflen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md5_test_sum[7][16] = -{ - { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, - 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, - { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, - 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, - { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, - 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, - { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, - 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, - { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, - 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, - { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, - 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, - { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, - 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } -}; - -/* - * Checkup routine - */ -int mbedtls_md5_self_test(int verbose) -{ - int i, ret = 0; - unsigned char md5sum[16]; - - for (i = 0; i < 7; i++) { - if (verbose != 0) { - mbedtls_printf(" MD5 test #%d: ", i + 1); - } - - ret = mbedtls_md5(md5_test_buf[i], md5_test_buflen[i], md5sum); - if (ret != 0) { - goto fail; - } - - if (memcmp(md5sum, md5_test_sum[i], 16) != 0) { - ret = 1; - goto fail; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; - -fail: - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MD5_C */ diff --git a/vendor/mbedtls/library/md_psa.h b/vendor/mbedtls/library/md_psa.h deleted file mode 100644 index 028ba2409..000000000 --- a/vendor/mbedtls/library/md_psa.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Translation between MD and PSA identifiers (algorithms, errors). - * - * Note: this internal module will go away when everything becomes based on - * PSA Crypto; it is a helper for the transition period. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_MD_PSA_H -#define MBEDTLS_MD_PSA_H - -#include "common.h" - -#include "mbedtls/md.h" -#include "psa/crypto.h" - -/** Convert PSA status to MD error code. - * - * \param status PSA status. - * - * \return The corresponding MD error code, - */ -int mbedtls_md_error_from_psa(psa_status_t status); - -#endif /* MBEDTLS_MD_PSA_H */ diff --git a/vendor/mbedtls/library/md_wrap.h b/vendor/mbedtls/library/md_wrap.h deleted file mode 100644 index dad123540..000000000 --- a/vendor/mbedtls/library/md_wrap.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * \file md_wrap.h - * - * \brief Message digest wrappers. - * - * \warning This in an internal header. Do not include directly. - * - * \author Adriaan de Jong - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_MD_WRAP_H -#define MBEDTLS_MD_WRAP_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Message digest information. - * Allows message digest functions to be called in a generic way. - */ -struct mbedtls_md_info_t { - /** Digest identifier */ - mbedtls_md_type_t type; - - /** Output length of the digest function in bytes */ - unsigned char size; - -#if defined(MBEDTLS_MD_C) - /** Block length of the digest function in bytes */ - unsigned char block_size; -#endif -}; - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_MD_WRAP_H */ diff --git a/vendor/mbedtls/library/memory_buffer_alloc.c b/vendor/mbedtls/library/memory_buffer_alloc.c deleted file mode 100644 index 79b0a8b8f..000000000 --- a/vendor/mbedtls/library/memory_buffer_alloc.c +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Buffer-based memory allocator - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) -#include "mbedtls/memory_buffer_alloc.h" - -/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C - is dependent upon MBEDTLS_PLATFORM_C */ -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_MEMORY_BACKTRACE) -#include -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#define MAGIC1 0xFF00AA55 -#define MAGIC2 0xEE119966 -#define MAX_BT 20 - -typedef struct _memory_header memory_header; -struct _memory_header { - size_t magic1; - size_t size; - size_t alloc; - memory_header *prev; - memory_header *next; - memory_header *prev_free; - memory_header *next_free; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - char **trace; - size_t trace_count; -#endif - size_t magic2; -}; - -typedef struct { - unsigned char *buf; - size_t len; - memory_header *first; - memory_header *first_free; - int verify; -#if defined(MBEDTLS_MEMORY_DEBUG) - size_t alloc_count; - size_t free_count; - size_t total_used; - size_t maximum_used; - size_t header_count; - size_t maximum_header_count; -#endif -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; -#endif -} -buffer_alloc_ctx; - -static buffer_alloc_ctx heap; - -#if defined(MBEDTLS_MEMORY_DEBUG) -static void debug_header(memory_header *hdr) -{ -#if defined(MBEDTLS_MEMORY_BACKTRACE) - size_t i; -#endif - - mbedtls_fprintf(stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), " - "ALLOC(%zu), SIZE(%10zu)\n", - (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, - hdr->alloc, hdr->size); - mbedtls_fprintf(stderr, " FPREV(%10zu), FNEXT(%10zu)\n", - (size_t) hdr->prev_free, (size_t) hdr->next_free); - -#if defined(MBEDTLS_MEMORY_BACKTRACE) - mbedtls_fprintf(stderr, "TRACE: \n"); - for (i = 0; i < hdr->trace_count; i++) { - mbedtls_fprintf(stderr, "%s\n", hdr->trace[i]); - } - mbedtls_fprintf(stderr, "\n"); -#endif -} - -static void debug_chain(void) -{ - memory_header *cur = heap.first; - - mbedtls_fprintf(stderr, "\nBlock list\n"); - while (cur != NULL) { - debug_header(cur); - cur = cur->next; - } - - mbedtls_fprintf(stderr, "Free list\n"); - cur = heap.first_free; - - while (cur != NULL) { - debug_header(cur); - cur = cur->next_free; - } -} -#endif /* MBEDTLS_MEMORY_DEBUG */ - -static int verify_header(memory_header *hdr) -{ - if (hdr->magic1 != MAGIC1) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: MAGIC1 mismatch\n"); -#endif - return 1; - } - - if (hdr->magic2 != MAGIC2) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: MAGIC2 mismatch\n"); -#endif - return 1; - } - - if (hdr->alloc > 1) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: alloc has illegal value\n"); -#endif - return 1; - } - - if (hdr->prev != NULL && hdr->prev == hdr->next) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: prev == next\n"); -#endif - return 1; - } - - if (hdr->prev_free != NULL && hdr->prev_free == hdr->next_free) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: prev_free == next_free\n"); -#endif - return 1; - } - - return 0; -} - -static int verify_chain(void) -{ - memory_header *prv = heap.first, *cur; - - if (prv == NULL || verify_header(prv) != 0) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: verification of first header " - "failed\n"); -#endif - return 1; - } - - if (heap.first->prev != NULL) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: verification failed: " - "first->prev != NULL\n"); -#endif - return 1; - } - - cur = heap.first->next; - - while (cur != NULL) { - if (verify_header(cur) != 0) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: verification of header " - "failed\n"); -#endif - return 1; - } - - if (cur->prev != prv) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: verification failed: " - "cur->prev != prv\n"); -#endif - return 1; - } - - prv = cur; - cur = cur->next; - } - - return 0; -} - -static void *buffer_alloc_calloc(size_t n, size_t size) -{ - memory_header *new, *cur = heap.first_free; - unsigned char *p; - void *ret; - size_t original_len, len; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - void *trace_buffer[MAX_BT]; - size_t trace_cnt; -#endif - - if (heap.buf == NULL || heap.first == NULL) { - return NULL; - } - - original_len = len = n * size; - - if (n == 0 || size == 0 || len / n != size) { - return NULL; - } else if (len > (size_t) -MBEDTLS_MEMORY_ALIGN_MULTIPLE) { - return NULL; - } - - if (len % MBEDTLS_MEMORY_ALIGN_MULTIPLE) { - len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - len += MBEDTLS_MEMORY_ALIGN_MULTIPLE; - } - - // Find block that fits - // - while (cur != NULL) { - if (cur->size >= len) { - break; - } - - cur = cur->next_free; - } - - if (cur == NULL) { - return NULL; - } - - if (cur->alloc != 0) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: block in free_list but allocated " - "data\n"); -#endif - mbedtls_exit(1); - } - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.alloc_count++; -#endif - - // Found location, split block if > memory_header + 4 room left - // - if (cur->size - len < sizeof(memory_header) + - MBEDTLS_MEMORY_ALIGN_MULTIPLE) { - cur->alloc = 1; - - // Remove from free_list - // - if (cur->prev_free != NULL) { - cur->prev_free->next_free = cur->next_free; - } else { - heap.first_free = cur->next_free; - } - - if (cur->next_free != NULL) { - cur->next_free->prev_free = cur->prev_free; - } - - cur->prev_free = NULL; - cur->next_free = NULL; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.total_used += cur->size; - if (heap.total_used > heap.maximum_used) { - heap.maximum_used = heap.total_used; - } -#endif -#if defined(MBEDTLS_MEMORY_BACKTRACE) - trace_cnt = backtrace(trace_buffer, MAX_BT); - cur->trace = backtrace_symbols(trace_buffer, trace_cnt); - cur->trace_count = trace_cnt; -#endif - - if ((heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC) && verify_chain() != 0) { - mbedtls_exit(1); - } - - ret = (unsigned char *) cur + sizeof(memory_header); - memset(ret, 0, original_len); - - return ret; - } - - p = ((unsigned char *) cur) + sizeof(memory_header) + len; - new = (memory_header *) p; - - new->size = cur->size - len - sizeof(memory_header); - new->alloc = 0; - new->prev = cur; - new->next = cur->next; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - new->trace = NULL; - new->trace_count = 0; -#endif - new->magic1 = MAGIC1; - new->magic2 = MAGIC2; - - if (new->next != NULL) { - new->next->prev = new; - } - - // Replace cur with new in free_list - // - new->prev_free = cur->prev_free; - new->next_free = cur->next_free; - if (new->prev_free != NULL) { - new->prev_free->next_free = new; - } else { - heap.first_free = new; - } - - if (new->next_free != NULL) { - new->next_free->prev_free = new; - } - - cur->alloc = 1; - cur->size = len; - cur->next = new; - cur->prev_free = NULL; - cur->next_free = NULL; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count++; - if (heap.header_count > heap.maximum_header_count) { - heap.maximum_header_count = heap.header_count; - } - heap.total_used += cur->size; - if (heap.total_used > heap.maximum_used) { - heap.maximum_used = heap.total_used; - } -#endif -#if defined(MBEDTLS_MEMORY_BACKTRACE) - trace_cnt = backtrace(trace_buffer, MAX_BT); - cur->trace = backtrace_symbols(trace_buffer, trace_cnt); - cur->trace_count = trace_cnt; -#endif - - if ((heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC) && verify_chain() != 0) { - mbedtls_exit(1); - } - - ret = (unsigned char *) cur + sizeof(memory_header); - memset(ret, 0, original_len); - - return ret; -} - -static void buffer_alloc_free(void *ptr) -{ - memory_header *hdr, *old = NULL; - unsigned char *p = (unsigned char *) ptr; - - if (ptr == NULL || heap.buf == NULL || heap.first == NULL) { - return; - } - - if (p < heap.buf || p >= heap.buf + heap.len) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: mbedtls_free() outside of managed " - "space\n"); -#endif - mbedtls_exit(1); - } - - p -= sizeof(memory_header); - hdr = (memory_header *) p; - - if (verify_header(hdr) != 0) { - mbedtls_exit(1); - } - - if (hdr->alloc != 1) { -#if defined(MBEDTLS_MEMORY_DEBUG) - mbedtls_fprintf(stderr, "FATAL: mbedtls_free() on unallocated " - "data\n"); -#endif - mbedtls_exit(1); - } - - hdr->alloc = 0; - -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.free_count++; - heap.total_used -= hdr->size; -#endif - -#if defined(MBEDTLS_MEMORY_BACKTRACE) - free(hdr->trace); - hdr->trace = NULL; - hdr->trace_count = 0; -#endif - - // Regroup with block before - // - if (hdr->prev != NULL && hdr->prev->alloc == 0) { -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count--; -#endif - hdr->prev->size += sizeof(memory_header) + hdr->size; - hdr->prev->next = hdr->next; - old = hdr; - hdr = hdr->prev; - - if (hdr->next != NULL) { - hdr->next->prev = hdr; - } - - memset(old, 0, sizeof(memory_header)); - } - - // Regroup with block after - // - if (hdr->next != NULL && hdr->next->alloc == 0) { -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.header_count--; -#endif - hdr->size += sizeof(memory_header) + hdr->next->size; - old = hdr->next; - hdr->next = hdr->next->next; - - if (hdr->prev_free != NULL || hdr->next_free != NULL) { - if (hdr->prev_free != NULL) { - hdr->prev_free->next_free = hdr->next_free; - } else { - heap.first_free = hdr->next_free; - } - - if (hdr->next_free != NULL) { - hdr->next_free->prev_free = hdr->prev_free; - } - } - - hdr->prev_free = old->prev_free; - hdr->next_free = old->next_free; - - if (hdr->prev_free != NULL) { - hdr->prev_free->next_free = hdr; - } else { - heap.first_free = hdr; - } - - if (hdr->next_free != NULL) { - hdr->next_free->prev_free = hdr; - } - - if (hdr->next != NULL) { - hdr->next->prev = hdr; - } - - memset(old, 0, sizeof(memory_header)); - } - - // Prepend to free_list if we have not merged - // (Does not have to stay in same order as prev / next list) - // - if (old == NULL) { - hdr->next_free = heap.first_free; - if (heap.first_free != NULL) { - heap.first_free->prev_free = hdr; - } - heap.first_free = hdr; - } - - if ((heap.verify & MBEDTLS_MEMORY_VERIFY_FREE) && verify_chain() != 0) { - mbedtls_exit(1); - } -} - -void mbedtls_memory_buffer_set_verify(int verify) -{ - heap.verify = verify; -} - -int mbedtls_memory_buffer_alloc_verify(void) -{ - return verify_chain(); -} - -#if defined(MBEDTLS_MEMORY_DEBUG) -void mbedtls_memory_buffer_alloc_status(void) -{ - mbedtls_fprintf(stderr, - "Current use: %zu blocks / %zu bytes, max: %zu blocks / " - "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n", - heap.header_count, heap.total_used, - heap.maximum_header_count, heap.maximum_used, - heap.maximum_header_count * sizeof(memory_header) - + heap.maximum_used, - heap.alloc_count, heap.free_count); - - if (heap.first->next == NULL) { - mbedtls_fprintf(stderr, "All memory de-allocated in stack buffer\n"); - } else { - mbedtls_fprintf(stderr, "Memory currently allocated:\n"); - debug_chain(); - } -} - -void mbedtls_memory_buffer_alloc_count_get(size_t *alloc_count, size_t *free_count) -{ - *alloc_count = heap.alloc_count; - *free_count = heap.free_count; -} - -void mbedtls_memory_buffer_alloc_max_get(size_t *max_used, size_t *max_blocks) -{ - *max_used = heap.maximum_used; - *max_blocks = heap.maximum_header_count; -} - -void mbedtls_memory_buffer_alloc_max_reset(void) -{ - heap.maximum_used = 0; - heap.maximum_header_count = 0; -} - -void mbedtls_memory_buffer_alloc_cur_get(size_t *cur_used, size_t *cur_blocks) -{ - *cur_used = heap.total_used; - *cur_blocks = heap.header_count; -} -#endif /* MBEDTLS_MEMORY_DEBUG */ - -#if defined(MBEDTLS_THREADING_C) -static void *buffer_alloc_calloc_mutexed(size_t n, size_t size) -{ - void *buf; - if (mbedtls_mutex_lock(&heap.mutex) != 0) { - return NULL; - } - buf = buffer_alloc_calloc(n, size); - if (mbedtls_mutex_unlock(&heap.mutex)) { - return NULL; - } - return buf; -} - -static void buffer_alloc_free_mutexed(void *ptr) -{ - /* We have no good option here, but corrupting the heap seems - * worse than losing memory. */ - if (mbedtls_mutex_lock(&heap.mutex)) { - return; - } - buffer_alloc_free(ptr); - (void) mbedtls_mutex_unlock(&heap.mutex); -} -#endif /* MBEDTLS_THREADING_C */ - -void mbedtls_memory_buffer_alloc_init(unsigned char *buf, size_t len) -{ - memset(&heap, 0, sizeof(buffer_alloc_ctx)); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&heap.mutex); - mbedtls_platform_set_calloc_free(buffer_alloc_calloc_mutexed, - buffer_alloc_free_mutexed); -#else - mbedtls_platform_set_calloc_free(buffer_alloc_calloc, buffer_alloc_free); -#endif - - if (len < sizeof(memory_header) + MBEDTLS_MEMORY_ALIGN_MULTIPLE) { - return; - } else if ((size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE) { - /* Adjust len first since buf is used in the computation */ - len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; - } - - memset(buf, 0, len); - - heap.buf = buf; - heap.len = len; - - heap.first = (memory_header *) buf; - heap.first->size = len - sizeof(memory_header); - heap.first->magic1 = MAGIC1; - heap.first->magic2 = MAGIC2; - heap.first_free = heap.first; -} - -void mbedtls_memory_buffer_alloc_free(void) -{ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free(&heap.mutex); -#endif - mbedtls_platform_zeroize(&heap, sizeof(buffer_alloc_ctx)); -} - -#if defined(MBEDTLS_SELF_TEST) -static int check_pointer(void *p) -{ - if (p == NULL) { - return -1; - } - - if ((size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0) { - return -1; - } - - return 0; -} - -static int check_all_free(void) -{ - if ( -#if defined(MBEDTLS_MEMORY_DEBUG) - heap.total_used != 0 || -#endif - heap.first != heap.first_free || - (void *) heap.first != (void *) heap.buf) { - return -1; - } - - return 0; -} - -#define TEST_ASSERT(condition) \ - if (!(condition)) \ - { \ - if (verbose != 0) \ - mbedtls_printf("failed\n"); \ - \ - ret = 1; \ - goto cleanup; \ - } - -int mbedtls_memory_buffer_alloc_self_test(int verbose) -{ - unsigned char buf[1024]; - unsigned char *p, *q, *r, *end; - int ret = 0; - - if (verbose != 0) { - mbedtls_printf(" MBA test #1 (basic alloc-free cycle): "); - } - - mbedtls_memory_buffer_alloc_init(buf, sizeof(buf)); - - p = mbedtls_calloc(1, 1); - q = mbedtls_calloc(1, 128); - r = mbedtls_calloc(1, 16); - - TEST_ASSERT(check_pointer(p) == 0 && - check_pointer(q) == 0 && - check_pointer(r) == 0); - - mbedtls_free(r); - mbedtls_free(q); - mbedtls_free(p); - - TEST_ASSERT(check_all_free() == 0); - - /* Memorize end to compare with the next test */ - end = heap.buf + heap.len; - - mbedtls_memory_buffer_alloc_free(); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - if (verbose != 0) { - mbedtls_printf(" MBA test #2 (buf not aligned): "); - } - - mbedtls_memory_buffer_alloc_init(buf + 1, sizeof(buf) - 1); - - TEST_ASSERT(heap.buf + heap.len == end); - - p = mbedtls_calloc(1, 1); - q = mbedtls_calloc(1, 128); - r = mbedtls_calloc(1, 16); - - TEST_ASSERT(check_pointer(p) == 0 && - check_pointer(q) == 0 && - check_pointer(r) == 0); - - mbedtls_free(r); - mbedtls_free(q); - mbedtls_free(p); - - TEST_ASSERT(check_all_free() == 0); - - mbedtls_memory_buffer_alloc_free(); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - - if (verbose != 0) { - mbedtls_printf(" MBA test #3 (full): "); - } - - mbedtls_memory_buffer_alloc_init(buf, sizeof(buf)); - - p = mbedtls_calloc(1, sizeof(buf) - sizeof(memory_header)); - - TEST_ASSERT(check_pointer(p) == 0); - TEST_ASSERT(mbedtls_calloc(1, 1) == NULL); - - mbedtls_free(p); - - p = mbedtls_calloc(1, sizeof(buf) - 2 * sizeof(memory_header) - 16); - q = mbedtls_calloc(1, 16); - - TEST_ASSERT(check_pointer(p) == 0 && check_pointer(q) == 0); - TEST_ASSERT(mbedtls_calloc(1, 1) == NULL); - - mbedtls_free(q); - - TEST_ASSERT(mbedtls_calloc(1, 17) == NULL); - - mbedtls_free(p); - - TEST_ASSERT(check_all_free() == 0); - - mbedtls_memory_buffer_alloc_free(); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - -cleanup: - mbedtls_memory_buffer_alloc_free(); - - return ret; -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ diff --git a/vendor/mbedtls/library/mps_common.h b/vendor/mbedtls/library/mps_common.h deleted file mode 100644 index f9fe09988..000000000 --- a/vendor/mbedtls/library/mps_common.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/** - * \file mps_common.h - * - * \brief Common functions and macros used by MPS - */ - -#ifndef MBEDTLS_MPS_COMMON_H -#define MBEDTLS_MPS_COMMON_H - -#include "mps_error.h" - -#include - -/** - * \name SECTION: MPS Configuration - * - * \{ - */ - -/*! This flag controls whether the MPS-internal components - * (reader, writer, Layer 1-3) perform validation of the - * expected abstract state at the entry of API calls. - * - * Context: All MPS API functions impose assumptions/preconditions on the - * context on which they operate. For example, every structure has a notion of - * state integrity which is established by `xxx_init()` and preserved by any - * calls to the MPS API which satisfy their preconditions and either succeed, - * or fail with an error code which is explicitly documented to not corrupt - * structure integrity (such as WANT_READ and WANT_WRITE); - * apart from `xxx_init()` any function assumes state integrity as a - * precondition (but usually more). If any of the preconditions is violated, - * the function's behavior is entirely undefined. - * In addition to state integrity, all MPS structures have a more refined - * notion of abstract state that the API operates on. For example, all layers - * have a notion of 'abstract read state' which indicates if incoming data has - * been passed to the user, e.g. through mps_l2_read_start() for Layer 2 - * or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to - * call these reading functions again until the incoming data has been - * explicitly 'consumed', e.g. through mps_l2_read_consume() for Layer 2 or - * mps_l3_read_consume() on Layer 3. However, even if it doesn't make sense, - * it's a design choice whether the API should fail gracefully on such - * non-sensical calls or not, and that's what this option is about: - * - * This option determines whether the expected abstract state - * is part of the API preconditions or not: If the option is set, - * then the abstract state is not part of the precondition and is - * thus required to be validated by the implementation. If an unexpected - * abstract state is encountered, the implementation must fail gracefully - * with error #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED. - * Conversely, if this option is not set, then the expected abstract state - * is included in the preconditions of the respective API calls, and - * an implementation's behaviour is undefined if the abstract state is - * not as expected. - * - * For example: Enabling this makes mps_l2_read_done() fail if - * no incoming record is currently open; disabling this would - * lead to undefined behavior in this case. - * - * Comment this to remove state validation. - */ -#define MBEDTLS_MPS_STATE_VALIDATION - -/*! This flag enables/disables assertions on the internal state of MPS. - * - * Assertions are sanity checks that should never trigger when MPS - * is used within the bounds of its API and preconditions. - * - * Enabling this increases security by limiting the scope of - * potential bugs, but comes at the cost of increased code size. - * - * Note: So far, there is no guiding principle as to what - * expected conditions merit an assertion, and which don't. - * - * Comment this to disable assertions. - */ -#define MBEDTLS_MPS_ENABLE_ASSERTIONS - -/*! This flag controls whether tracing for MPS should be enabled. */ -//#define MBEDTLS_MPS_ENABLE_TRACE - -#if defined(MBEDTLS_MPS_STATE_VALIDATION) - -#define MBEDTLS_MPS_STATE_VALIDATE_RAW(cond, string) \ - do \ - { \ - if (!(cond)) \ - { \ - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, string); \ - MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED); \ - } \ - } while (0) - -#else /* MBEDTLS_MPS_STATE_VALIDATION */ - -#define MBEDTLS_MPS_STATE_VALIDATE_RAW(cond, string) \ - do \ - { \ - (cond); \ - } while (0) - -#endif /* MBEDTLS_MPS_STATE_VALIDATION */ - -#if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS) - -#define MBEDTLS_MPS_ASSERT_RAW(cond, string) \ - do \ - { \ - if (!(cond)) \ - { \ - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, string); \ - MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_INTERNAL_ERROR); \ - } \ - } while (0) - -#else /* MBEDTLS_MPS_ENABLE_ASSERTIONS */ - -#define MBEDTLS_MPS_ASSERT_RAW(cond, string) do {} while (0) - -#endif /* MBEDTLS_MPS_ENABLE_ASSERTIONS */ - - -/* \} name SECTION: MPS Configuration */ - -/** - * \name SECTION: Common types - * - * Various common types used throughout MPS. - * \{ - */ - -/** \brief The type of buffer sizes and offsets used in MPS structures. - * - * This is an unsigned integer type that should be large enough to - * hold the length of any buffer or message processed by MPS. - * - * The reason to pick a value as small as possible here is - * to reduce the size of MPS structures. - * - * \warning Care has to be taken when using a narrower type - * than ::mbedtls_mps_size_t here because of - * potential truncation during conversion. - * - * \warning Handshake messages in TLS may be up to 2^24 ~ 16Mb in size. - * If mbedtls_mps_[opt_]stored_size_t is smaller than that, the - * maximum handshake message is restricted accordingly. - * - * For now, we use the default type of size_t throughout, and the use of - * smaller types or different types for ::mbedtls_mps_size_t and - * ::mbedtls_mps_stored_size_t is not yet supported. - * - */ -typedef size_t mbedtls_mps_stored_size_t; -#define MBEDTLS_MPS_STORED_SIZE_MAX (SIZE_MAX) - -/** \brief The type of buffer sizes and offsets used in the MPS API - * and implementation. - * - * This must be at least as wide as ::mbedtls_stored_size_t but - * may be chosen to be strictly larger if more suitable for the - * target architecture. - * - * For example, in a test build for ARM Thumb, using uint_fast16_t - * instead of uint16_t reduced the code size from 1060 Byte to 962 Byte, - * so almost 10%. - */ -typedef size_t mbedtls_mps_size_t; -#define MBEDTLS_MPS_SIZE_MAX (SIZE_MAX) - -#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX -#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t." -#endif - -/* \} SECTION: Common types */ - - -#endif /* MBEDTLS_MPS_COMMON_H */ diff --git a/vendor/mbedtls/library/mps_error.h b/vendor/mbedtls/library/mps_error.h deleted file mode 100644 index 016a84ce4..000000000 --- a/vendor/mbedtls/library/mps_error.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/** - * \file mps_error.h - * - * \brief Error codes used by MPS - */ - -#ifndef MBEDTLS_MPS_ERROR_H -#define MBEDTLS_MPS_ERROR_H - - -/* TODO: The error code allocation needs to be revisited: - * - * - Should we make (some of) the MPS Reader error codes public? - * If so, we need to adjust MBEDTLS_MPS_READER_MAKE_ERROR() to hit - * a gap in the Mbed TLS public error space. - * If not, we have to make sure we don't forward those errors - * at the level of the public API -- no risk at the moment as - * long as MPS is an experimental component not accessible from - * public API. - */ - -/** - * \name SECTION: MPS general error codes - * - * \{ - */ - -#ifndef MBEDTLS_MPS_ERR_BASE -#define MBEDTLS_MPS_ERR_BASE (0) -#endif - -#define MBEDTLS_MPS_MAKE_ERROR(code) \ - (-(MBEDTLS_MPS_ERR_BASE | (code))) - -#define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR(0x1) -#define MBEDTLS_ERR_MPS_INTERNAL_ERROR MBEDTLS_MPS_MAKE_ERROR(0x2) - -/* \} name SECTION: MPS general error codes */ - -/** - * \name SECTION: MPS Reader error codes - * - * \{ - */ - -#ifndef MBEDTLS_MPS_READER_ERR_BASE -#define MBEDTLS_MPS_READER_ERR_BASE (1 << 8) -#endif - -#define MBEDTLS_MPS_READER_MAKE_ERROR(code) \ - (-(MBEDTLS_MPS_READER_ERR_BASE | (code))) - -/*! An attempt to reclaim the data buffer from a reader failed because - * the user hasn't yet read and committed all of it. */ -#define MBEDTLS_ERR_MPS_READER_DATA_LEFT MBEDTLS_MPS_READER_MAKE_ERROR(0x1) - -/*! An invalid argument was passed to the reader. */ -#define MBEDTLS_ERR_MPS_READER_INVALID_ARG MBEDTLS_MPS_READER_MAKE_ERROR(0x2) - -/*! An attempt to move a reader to consuming mode through mbedtls_mps_reader_feed() - * after pausing failed because the provided data is not sufficient to serve the - * read requests that led to the pausing. */ -#define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR(0x3) - -/*! A get request failed because not enough data is available in the reader. */ -#define MBEDTLS_ERR_MPS_READER_OUT_OF_DATA MBEDTLS_MPS_READER_MAKE_ERROR(0x4) - -/*!< A get request after pausing and reactivating the reader failed because - * the request is not in line with the request made prior to pausing. The user - * must not change it's 'strategy' after pausing and reactivating a reader. */ -#define MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS MBEDTLS_MPS_READER_MAKE_ERROR(0x5) - -/*! An attempt to reclaim the data buffer from a reader failed because the reader - * has no accumulator it can use to backup the data that hasn't been processed. */ -#define MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR MBEDTLS_MPS_READER_MAKE_ERROR(0x6) - -/*! An attempt to reclaim the data buffer from a reader failed because the - * accumulator passed to the reader is not large enough to hold both the - * data that hasn't been processed and the excess of the last read-request. */ -#define MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL MBEDTLS_MPS_READER_MAKE_ERROR(0x7) - -/* \} name SECTION: MPS Reader error codes */ - -#endif /* MBEDTLS_MPS_ERROR_H */ diff --git a/vendor/mbedtls/library/mps_reader.c b/vendor/mbedtls/library/mps_reader.c deleted file mode 100644 index 27d0c04c1..000000000 --- a/vendor/mbedtls/library/mps_reader.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Message Processing Stack, Reader implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#include "mps_reader.h" -#include "mps_common.h" -#include "mps_trace.h" - -#include - -#if defined(MBEDTLS_MPS_ENABLE_TRACE) -static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER; -#endif /* MBEDTLS_MPS_ENABLE_TRACE */ - -/* - * GENERAL NOTE ON CODING STYLE - * - * The following code intentionally separates memory loads - * and stores from other operations (arithmetic or branches). - * This leads to the introduction of many local variables - * and significantly increases the C-code line count, but - * should not increase the size of generated assembly. - * - * The reason for this is twofold: - * (1) It will ease verification efforts using the VST - * (Verified Software Toolchain) - * whose program logic cannot directly reason - * about instructions containing a load or store in - * addition to other operations (e.g. *p = *q or - * tmp = *p + 42). - * (2) Operating on local variables and writing the results - * back to the target contexts on success only - * allows to maintain structure invariants even - * on failure - this in turn has two benefits: - * (2.a) If for some reason an error code is not caught - * and operation continues, functions are nonetheless - * called with sane contexts, reducing the risk - * of dangerous behavior. - * (2.b) Randomized testing is easier if structures - * remain intact even in the face of failing - * and/or non-sensical calls. - * Moreover, it might even reduce code-size because - * the compiler need not write back temporary results - * to memory in case of failure. - * - */ - -static inline int mps_reader_is_accumulating( - mbedtls_mps_reader const *rd) -{ - mbedtls_mps_size_t acc_remaining; - if (rd->acc == NULL) { - return 0; - } - - acc_remaining = rd->acc_share.acc_remaining; - return acc_remaining > 0; -} - -static inline int mps_reader_is_producing( - mbedtls_mps_reader const *rd) -{ - unsigned char *frag = rd->frag; - return frag == NULL; -} - -static inline int mps_reader_is_consuming( - mbedtls_mps_reader const *rd) -{ - return !mps_reader_is_producing(rd); -} - -static inline mbedtls_mps_size_t mps_reader_get_fragment_offset( - mbedtls_mps_reader const *rd) -{ - unsigned char *acc = rd->acc; - mbedtls_mps_size_t frag_offset; - - if (acc == NULL) { - return 0; - } - - frag_offset = rd->acc_share.frag_offset; - return frag_offset; -} - -static inline mbedtls_mps_size_t mps_reader_serving_from_accumulator( - mbedtls_mps_reader const *rd) -{ - mbedtls_mps_size_t frag_offset, end; - - frag_offset = mps_reader_get_fragment_offset(rd); - end = rd->end; - - return end < frag_offset; -} - -static inline void mps_reader_zero(mbedtls_mps_reader *rd) -{ - /* A plain memset() would likely be more efficient, - * but the current way of zeroing makes it harder - * to overlook fields which should not be zero-initialized. - * It's also more suitable for FV efforts since it - * doesn't require reasoning about structs being - * interpreted as unstructured binary blobs. */ - static mbedtls_mps_reader const zero = - { .frag = NULL, - .frag_len = 0, - .commit = 0, - .end = 0, - .pending = 0, - .acc = NULL, - .acc_len = 0, - .acc_available = 0, - .acc_share = { .acc_remaining = 0 } }; - *rd = zero; -} - -int mbedtls_mps_reader_init(mbedtls_mps_reader *rd, - unsigned char *acc, - mbedtls_mps_size_t acc_len) -{ - MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_init"); - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "* Accumulator size: %u bytes", (unsigned) acc_len); - mps_reader_zero(rd); - rd->acc = acc; - rd->acc_len = acc_len; - MBEDTLS_MPS_TRACE_RETURN(0); -} - -int mbedtls_mps_reader_free(mbedtls_mps_reader *rd) -{ - MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_free"); - mps_reader_zero(rd); - MBEDTLS_MPS_TRACE_RETURN(0); -} - -int mbedtls_mps_reader_feed(mbedtls_mps_reader *rd, - unsigned char *new_frag, - mbedtls_mps_size_t new_frag_len) -{ - mbedtls_mps_size_t copy_to_acc; - MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_feed"); - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "* Fragment length: %u bytes", (unsigned) new_frag_len); - - if (new_frag == NULL) { - MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_INVALID_ARG); - } - - MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_producing( - rd), - "mbedtls_mps_reader_feed() requires reader to be in producing mode"); - - if (mps_reader_is_accumulating(rd)) { - unsigned char *acc = rd->acc; - mbedtls_mps_size_t acc_remaining = rd->acc_share.acc_remaining; - mbedtls_mps_size_t acc_available = rd->acc_available; - - /* Skip over parts of the accumulator that have already been filled. */ - acc += acc_available; - - copy_to_acc = acc_remaining; - if (copy_to_acc > new_frag_len) { - copy_to_acc = new_frag_len; - } - - /* Copy new contents to accumulator. */ - memcpy(acc, new_frag, copy_to_acc); - - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Copy new data of size %u of %u into accumulator at offset %u", - (unsigned) copy_to_acc, (unsigned) new_frag_len, - (unsigned) acc_available); - - /* Check if, with the new fragment, we have enough data. */ - acc_remaining -= copy_to_acc; - if (acc_remaining > 0) { - /* We need to accumulate more data. Stay in producing mode. */ - acc_available += copy_to_acc; - rd->acc_share.acc_remaining = acc_remaining; - rd->acc_available = acc_available; - MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_NEED_MORE); - } - - /* We have filled the accumulator: Move to consuming mode. */ - - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Enough data available to serve user request"); - - /* Remember overlap of accumulator and fragment. */ - rd->acc_share.frag_offset = acc_available; - acc_available += copy_to_acc; - rd->acc_available = acc_available; - } else { /* Not accumulating */ - rd->acc_share.frag_offset = 0; - } - - rd->frag = new_frag; - rd->frag_len = new_frag_len; - rd->commit = 0; - rd->end = 0; - MBEDTLS_MPS_TRACE_RETURN(0); -} - - -int mbedtls_mps_reader_get(mbedtls_mps_reader *rd, - mbedtls_mps_size_t desired, - unsigned char **buffer, - mbedtls_mps_size_t *buflen) -{ - unsigned char *frag; - mbedtls_mps_size_t frag_len, frag_offset, end, frag_fetched, frag_remaining; - MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_get"); - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "* Bytes requested: %u", (unsigned) desired); - - MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_consuming( - rd), - "mbedtls_mps_reader_get() requires reader to be in consuming mode"); - - end = rd->end; - frag_offset = mps_reader_get_fragment_offset(rd); - - /* Check if we're still serving from the accumulator. */ - if (mps_reader_serving_from_accumulator(rd)) { - /* Illustration of supported and unsupported cases: - * - * - Allowed #1 - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end+desired - * | | - * +-----v-------v-------------+ - * | acc | - * +---------------------------+ - * | | - * frag_offset acc_available - * - * - Allowed #2 - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end+desired - * | | - * +----------v----------------v - * | acc | - * +---------------------------+ - * | | - * frag_offset acc_available - * - * - Not allowed #1 (could be served, but we don't actually use it): - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end+desired - * | | - * +------v-------------v------+ - * | acc | - * +---------------------------+ - * | | - * frag_offset acc_available - * - * - * - Not allowed #2 (can't be served with a contiguous buffer): - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end + desired - * | | - * +------v--------------------+ v - * | acc | - * +---------------------------+ - * | | - * frag_offset acc_available - * - * In case of Allowed #2 we're switching to serve from - * `frag` starting from the next call to mbedtls_mps_reader_get(). - */ - - unsigned char *acc; - - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Serve the request from the accumulator"); - if (frag_offset - end < desired) { - mbedtls_mps_size_t acc_available; - acc_available = rd->acc_available; - if (acc_available - end != desired) { - /* It might be possible to serve some of these situations by - * making additional space in the accumulator, removing those - * parts that have already been committed. - * On the other hand, this brings additional complexity and - * enlarges the code size, while there doesn't seem to be a use - * case where we don't attempt exactly the same `get` calls when - * resuming on a reader than what we tried before pausing it. - * If we believe we adhere to this restricted usage throughout - * the library, this check is a good opportunity to - * validate this. */ - MBEDTLS_MPS_TRACE_RETURN( - MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS); - } - } - - acc = rd->acc; - acc += end; - - *buffer = acc; - if (buflen != NULL) { - *buflen = desired; - } - - end += desired; - rd->end = end; - rd->pending = 0; - - MBEDTLS_MPS_TRACE_RETURN(0); - } - - /* Attempt to serve the request from the current fragment */ - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Serve the request from the current fragment."); - - frag_len = rd->frag_len; - frag_fetched = end - frag_offset; /* The amount of data from the current - * fragment that has already been passed - * to the user. */ - frag_remaining = frag_len - frag_fetched; /* Remaining data in fragment */ - - /* Check if we can serve the read request from the fragment. */ - if (frag_remaining < desired) { - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "There's not enough data in the current fragment " - "to serve the request."); - /* There's not enough data in the current fragment, - * so either just RETURN what we have or fail. */ - if (buflen == NULL) { - if (frag_remaining > 0) { - rd->pending = desired - frag_remaining; - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Remember to collect %u bytes before re-opening", - (unsigned) rd->pending); - } - MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_OUT_OF_DATA); - } - - desired = frag_remaining; - } - - /* There's enough data in the current fragment to serve the - * (potentially modified) read request. */ - - frag = rd->frag; - frag += frag_fetched; - - *buffer = frag; - if (buflen != NULL) { - *buflen = desired; - } - - end += desired; - rd->end = end; - rd->pending = 0; - MBEDTLS_MPS_TRACE_RETURN(0); -} - -int mbedtls_mps_reader_commit(mbedtls_mps_reader *rd) -{ - mbedtls_mps_size_t end; - MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_commit"); - MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_consuming( - rd), - "mbedtls_mps_reader_commit() requires reader to be in consuming mode"); - - end = rd->end; - rd->commit = end; - - MBEDTLS_MPS_TRACE_RETURN(0); -} - -int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *rd, - int *paused) -{ - unsigned char *frag, *acc; - mbedtls_mps_size_t pending, commit; - mbedtls_mps_size_t acc_len, frag_offset, frag_len; - MBEDTLS_MPS_TRACE_INIT("mbedtls_mps_reader_reclaim"); - - if (paused != NULL) { - *paused = 0; - } - - MBEDTLS_MPS_STATE_VALIDATE_RAW(mps_reader_is_consuming( - rd), - "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode"); - - frag = rd->frag; - acc = rd->acc; - pending = rd->pending; - commit = rd->commit; - frag_len = rd->frag_len; - - frag_offset = mps_reader_get_fragment_offset(rd); - - if (pending == 0) { - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "No unsatisfied read-request has been logged."); - - /* Check if there's data left to be consumed. */ - if (commit < frag_offset || commit - frag_offset < frag_len) { - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "There is data left to be consumed."); - rd->end = commit; - MBEDTLS_MPS_TRACE_RETURN(MBEDTLS_ERR_MPS_READER_DATA_LEFT); - } - - rd->acc_available = 0; - rd->acc_share.acc_remaining = 0; - - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Fragment has been fully processed and committed."); - } else { - int overflow; - - mbedtls_mps_size_t acc_backup_offset; - mbedtls_mps_size_t acc_backup_len; - mbedtls_mps_size_t frag_backup_offset; - mbedtls_mps_size_t frag_backup_len; - - mbedtls_mps_size_t backup_len; - mbedtls_mps_size_t acc_len_needed; - - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "There has been an unsatisfied read with %u bytes overhead.", - (unsigned) pending); - - if (acc == NULL) { - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "No accumulator present"); - MBEDTLS_MPS_TRACE_RETURN( - MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR); - } - acc_len = rd->acc_len; - - /* Check if the upper layer has already fetched - * and committed the contents of the accumulator. */ - if (commit < frag_offset) { - /* No, accumulator is still being processed. */ - frag_backup_offset = 0; - frag_backup_len = frag_len; - acc_backup_offset = commit; - acc_backup_len = frag_offset - commit; - } else { - /* Yes, the accumulator is already processed. */ - frag_backup_offset = commit - frag_offset; - frag_backup_len = frag_len - frag_backup_offset; - acc_backup_offset = 0; - acc_backup_len = 0; - } - - backup_len = acc_backup_len + frag_backup_len; - acc_len_needed = backup_len + pending; - - overflow = 0; - overflow |= (backup_len < acc_backup_len); - overflow |= (acc_len_needed < backup_len); - - if (overflow || acc_len < acc_len_needed) { - /* Except for the different return code, we behave as if - * there hadn't been a call to mbedtls_mps_reader_get() - * since the last commit. */ - rd->end = commit; - rd->pending = 0; - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, - "The accumulator is too small to handle the backup."); - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, - "* Size: %u", (unsigned) acc_len); - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_ERROR, - "* Needed: %u (%u + %u)", - (unsigned) acc_len_needed, - (unsigned) backup_len, (unsigned) pending); - MBEDTLS_MPS_TRACE_RETURN( - MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL); - } - - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Fragment backup: %u", (unsigned) frag_backup_len); - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Accumulator backup: %u", (unsigned) acc_backup_len); - - /* Move uncommitted parts from the accumulator to the front - * of the accumulator. */ - memmove(acc, acc + acc_backup_offset, acc_backup_len); - - /* Copy uncommitted parts of the current fragment to the - * accumulator. */ - memcpy(acc + acc_backup_len, - frag + frag_backup_offset, frag_backup_len); - - rd->acc_available = backup_len; - rd->acc_share.acc_remaining = pending; - - if (paused != NULL) { - *paused = 1; - } - } - - rd->frag = NULL; - rd->frag_len = 0; - - rd->commit = 0; - rd->end = 0; - rd->pending = 0; - - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_COMMENT, - "Final state: aa %u, al %u, ar %u", - (unsigned) rd->acc_available, (unsigned) rd->acc_len, - (unsigned) rd->acc_share.acc_remaining); - MBEDTLS_MPS_TRACE_RETURN(0); -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/vendor/mbedtls/library/mps_reader.h b/vendor/mbedtls/library/mps_reader.h deleted file mode 100644 index 3193a5e33..000000000 --- a/vendor/mbedtls/library/mps_reader.h +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/** - * \file mps_reader.h - * - * \brief This file defines reader objects, which together with their - * sibling writer objects form the basis for the communication - * between the various layers of the Mbed TLS messaging stack, - * as well as the communication between the messaging stack and - * the (D)TLS handshake protocol implementation. - * - * Readers provide a means of transferring incoming data from - * a 'producer' providing it in chunks of arbitrary size, to - * a 'consumer' which fetches and processes it in chunks of - * again arbitrary, and potentially different, size. - * - * Readers can thus be seen as datagram-to-stream converters, - * and they abstract away the following two tasks from the user: - * 1. The pointer arithmetic of stepping through a producer- - * provided chunk in smaller chunks. - * 2. The merging of incoming data chunks in case the - * consumer requests data in larger chunks than what the - * producer provides. - * - * The basic abstract flow of operation is the following: - * - Initially, the reader is in 'producing mode'. - * - The producer hands an incoming data buffer to the reader, - * moving it from 'producing' to 'consuming' mode. - * - The consumer subsequently fetches and processes the buffer - * content. Once that's done -- or partially done and a consumer's - * request can't be fulfilled -- the producer revokes the reader's - * access to the incoming data buffer, putting the reader back to - * producing mode. - * - The producer subsequently gathers more incoming data and hands - * it to the reader until it switches back to consuming mode - * if enough data is available for the last consumer request to - * be satisfiable. - * - Repeat the above. - * - * The abstract states of the reader from the producer's and - * consumer's perspective are as follows: - * - * - From the perspective of the consumer, the state of the - * reader consists of the following: - * - A byte stream representing (concatenation of) the data - * received through calls to mbedtls_mps_reader_get(), - * - A marker within that byte stream indicating which data - * can be considered processed, and hence need not be retained, - * when the reader is passed back to the producer via - * mbedtls_mps_reader_reclaim(). - * The marker is set via mbedtls_mps_reader_commit() - * which places it at the end of the current byte stream. - * The consumer need not be aware of the distinction between consumer - * and producer mode, because it only interfaces with the reader - * when the latter is in consuming mode. - * - * - From the perspective of the producer, the reader's state is one of: - * - Attached: The reader is in consuming mode. - * - Unset: No incoming data buffer is currently managed by the reader, - * and all previously handed incoming data buffers have been - * fully processed. More data needs to be fed into the reader - * via mbedtls_mps_reader_feed(). - * - * - Accumulating: No incoming data buffer is currently managed by the - * reader, but some data from the previous incoming data - * buffer hasn't been processed yet and is internally - * held back. - * The Attached state belongs to consuming mode, while the Unset and - * Accumulating states belong to producing mode. - * - * Transitioning from the Unset or Accumulating state to Attached is - * done via successful calls to mbedtls_mps_reader_feed(), while - * transitioning from Attached to either Unset or Accumulating (depending - * on what has been processed) is done via mbedtls_mps_reader_reclaim(). - * - * The following diagram depicts the producer-state progression: - * - * +------------------+ reclaim - * | Unset +<-------------------------------------+ get - * +--------|---------+ | +------+ - * | | | | - * | | | | - * | feed +---------+---+--+ | - * +--------------------------------------> <---+ - * | Attached | - * +--------------------------------------> <---+ - * | feed, enough data available +---------+---+--+ | - * | to serve previous consumer request | | | - * | | | | - * +--------+---------+ | +------+ - * +----> Accumulating |<-------------------------------------+ commit - * | +---+--------------+ reclaim, previous read request - * | | couldn't be fulfilled - * | | - * +--------+ - * feed, need more data to serve - * previous consumer request - * | - * | - * producing mode | consuming mode - * | - * - */ - -#ifndef MBEDTLS_READER_H -#define MBEDTLS_READER_H - -#include - -#include "mps_common.h" -#include "mps_error.h" - -struct mbedtls_mps_reader; -typedef struct mbedtls_mps_reader mbedtls_mps_reader; - -/* - * Structure definitions - */ - -struct mbedtls_mps_reader { - unsigned char *frag; /*!< The fragment of incoming data managed by - * the reader; it is provided to the reader - * through mbedtls_mps_reader_feed(). The reader - * does not own the fragment and does not - * perform any allocation operations on it, - * but does have read and write access to it. - * - * The reader is in consuming mode if - * and only if \c frag is not \c NULL. */ - mbedtls_mps_stored_size_t frag_len; - /*!< The length of the current fragment. - * Must be 0 if \c frag == \c NULL. */ - mbedtls_mps_stored_size_t commit; - /*!< The offset of the last commit, relative - * to the first byte in the fragment, if - * no accumulator is present. If an accumulator - * is present, it is viewed as a prefix to the - * current fragment, and this variable contains - * an offset from the beginning of the accumulator. - * - * This is only used when the reader is in - * consuming mode, i.e. \c frag != \c NULL; - * otherwise, its value is \c 0. */ - mbedtls_mps_stored_size_t end; - /*!< The offset of the end of the last chunk - * passed to the user through a call to - * mbedtls_mps_reader_get(), relative to the first - * byte in the fragment, if no accumulator is - * present. If an accumulator is present, it is - * viewed as a prefix to the current fragment, and - * this variable contains an offset from the - * beginning of the accumulator. - * - * This is only used when the reader is in - * consuming mode, i.e. \c frag != \c NULL; - * otherwise, its value is \c 0. */ - mbedtls_mps_stored_size_t pending; - /*!< The amount of incoming data missing on the - * last call to mbedtls_mps_reader_get(). - * In particular, it is \c 0 if the last call - * was successful. - * If a reader is reclaimed after an - * unsuccessful call to mbedtls_mps_reader_get(), - * this variable is used to have the reader - * remember how much data should be accumulated - * so that the call to mbedtls_mps_reader_get() - * succeeds next time. - * This is only used when the reader is in - * consuming mode, i.e. \c frag != \c NULL; - * otherwise, its value is \c 0. */ - - /* The accumulator is only needed if we need to be able to pause - * the reader. A few bytes could be saved by moving this to a - * separate struct and using a pointer here. */ - - unsigned char *acc; /*!< The accumulator is used to gather incoming - * data if a read-request via mbedtls_mps_reader_get() - * cannot be served from the current fragment. */ - mbedtls_mps_stored_size_t acc_len; - /*!< The total size of the accumulator. */ - mbedtls_mps_stored_size_t acc_available; - /*!< The number of bytes currently gathered in - * the accumulator. This is both used in - * producing and in consuming mode: - * While producing, it is increased until - * it reaches the value of \c acc_remaining below. - * While consuming, it is used to judge if a - * get request can be served from the - * accumulator or not. - * Must not be larger than \c acc_len. */ - union { - mbedtls_mps_stored_size_t acc_remaining; - /*!< This indicates the amount of data still - * to be gathered in the accumulator. It is - * only used in producing mode. - * Must be at most acc_len - acc_available. */ - mbedtls_mps_stored_size_t frag_offset; - /*!< If an accumulator is present and in use, this - * field indicates the offset of the current - * fragment from the beginning of the - * accumulator. If no accumulator is present - * or the accumulator is not in use, this is \c 0. - * It is only used in consuming mode. - * Must not be larger than \c acc_available. */ - } acc_share; -}; - -/* - * API organization: - * A reader object is usually prepared and maintained - * by some lower layer and passed for usage to an upper - * layer, and the API naturally splits according to which - * layer is supposed to use the respective functions. - */ - -/* - * Maintenance API (Lower layer) - */ - -/** - * \brief Initialize a reader object - * - * \param reader The reader to be initialized. - * \param acc The buffer to be used as a temporary accumulator - * in case get requests through mbedtls_mps_reader_get() - * exceed the buffer provided by mbedtls_mps_reader_feed(). - * This buffer is owned by the caller and exclusive use - * for reading and writing is given to the reader for the - * duration of the reader's lifetime. It is thus the caller's - * responsibility to maintain (and not touch) the buffer for - * the lifetime of the reader, and to properly zeroize and - * free the memory after the reader has been destroyed. - * \param acc_len The size in Bytes of \p acc. - * - * \return \c 0 on success. - * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. - */ -int mbedtls_mps_reader_init(mbedtls_mps_reader *reader, - unsigned char *acc, - mbedtls_mps_size_t acc_len); - -/** - * \brief Free a reader object - * - * \param reader The reader to be freed. - * - * \return \c 0 on success. - * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. - */ -int mbedtls_mps_reader_free(mbedtls_mps_reader *reader); - -/** - * \brief Pass chunk of data for the reader to manage. - * - * \param reader The reader context to use. The reader must be - * in producing mode. - * \param buf The buffer to be managed by the reader. - * \param buflen The size in Bytes of \p buffer. - * - * \return \c 0 on success. In this case, the reader will be - * moved to consuming mode and obtains read access - * of \p buf until mbedtls_mps_reader_reclaim() - * is called. It is the responsibility of the caller - * to ensure that the \p buf persists and is not changed - * between successful calls to mbedtls_mps_reader_feed() - * and mbedtls_mps_reader_reclaim(). - * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is - * required to fulfill a previous request to mbedtls_mps_reader_get(). - * In this case, the reader remains in producing mode and - * takes no ownership of the provided buffer (an internal copy - * is made instead). - * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on - * different kinds of failures. - */ -int mbedtls_mps_reader_feed(mbedtls_mps_reader *reader, - unsigned char *buf, - mbedtls_mps_size_t buflen); - -/** - * \brief Reclaim reader's access to the current input buffer. - * - * \param reader The reader context to use. The reader must be - * in consuming mode. - * \param paused If not \c NULL, the integer at address \p paused will be - * modified to indicate whether the reader has been paused - * (value \c 1) or not (value \c 0). Pausing happens if there - * is uncommitted data and a previous request to - * mbedtls_mps_reader_get() has exceeded the bounds of the - * input buffer. - * - * \return \c 0 on success. - * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. - */ -int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *reader, - int *paused); - -/* - * Usage API (Upper layer) - */ - -/** - * \brief Request data from the reader. - * - * \param reader The reader context to use. The reader must - * be in consuming mode. - * \param desired The desired amount of data to be read, in Bytes. - * \param buffer The address to store the buffer pointer in. - * This must not be \c NULL. - * \param buflen The address to store the actual buffer - * length in, or \c NULL. - * - * \return \c 0 on success. In this case, \c *buf holds the - * address of a buffer of size \c *buflen - * (if \c buflen != \c NULL) or \c desired - * (if \c buflen == \c NULL). The user has read access - * to the buffer and guarantee of stability of the data - * until the next call to mbedtls_mps_reader_reclaim(). - * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough - * data available to serve the get request. In this case, the - * reader remains intact and in consuming mode, and the consumer - * should retry the call after a successful cycle of - * mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed(). - * If, after such a cycle, the consumer requests a different - * amount of data, the result is implementation-defined; - * progress is guaranteed only if the same amount of data - * is requested after a mbedtls_mps_reader_reclaim() and - * mbedtls_mps_reader_feed() cycle. - * \return Another negative \c MBEDTLS_ERR_READER_XXX error - * code for different kinds of failure. - * - * \note Passing \c NULL as \p buflen is a convenient way to - * indicate that fragmentation is not tolerated. - * It's functionally equivalent to passing a valid - * address as buflen and checking \c *buflen == \c desired - * afterwards. - */ -int mbedtls_mps_reader_get(mbedtls_mps_reader *reader, - mbedtls_mps_size_t desired, - unsigned char **buffer, - mbedtls_mps_size_t *buflen); - -/** - * \brief Mark data obtained from mbedtls_mps_reader_get() as processed. - * - * This call indicates that all data received from prior calls to - * mbedtls_mps_reader_get() has been or will have been - * processed when mbedtls_mps_reader_reclaim() is called, - * and thus need not be backed up. - * - * This function has no user observable effect until - * mbedtls_mps_reader_reclaim() is called. In particular, - * buffers received from mbedtls_mps_reader_get() remain - * valid until mbedtls_mps_reader_reclaim() is called. - * - * \param reader The reader context to use. - * - * \return \c 0 on success. - * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. - * - */ -int mbedtls_mps_reader_commit(mbedtls_mps_reader *reader); - -#endif /* MBEDTLS_READER_H */ diff --git a/vendor/mbedtls/library/mps_trace.c b/vendor/mbedtls/library/mps_trace.c deleted file mode 100644 index 69f6e5a0f..000000000 --- a/vendor/mbedtls/library/mps_trace.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Message Processing Stack, Trace module - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#include "mps_common.h" - -#if defined(MBEDTLS_MPS_ENABLE_TRACE) - -#include "mps_trace.h" -#include - -static int trace_depth = 0; - -#define color_default "\x1B[0m" -#define color_red "\x1B[1;31m" -#define color_green "\x1B[1;32m" -#define color_yellow "\x1B[1;33m" -#define color_blue "\x1B[1;34m" -#define color_magenta "\x1B[1;35m" -#define color_cyan "\x1B[1;36m" -#define color_white "\x1B[1;37m" - -static char const *colors[] = -{ - color_default, - color_green, - color_yellow, - color_magenta, - color_cyan, - color_blue, - color_white -}; - -#define MPS_TRACE_BUF_SIZE 100 - -void mbedtls_mps_trace_print_msg(int id, int line, const char *format, ...) -{ - int ret; - char str[MPS_TRACE_BUF_SIZE]; - va_list argp; - va_start(argp, format); - ret = mbedtls_vsnprintf(str, MPS_TRACE_BUF_SIZE, format, argp); - va_end(argp); - - if (ret >= 0 && ret < MPS_TRACE_BUF_SIZE) { - str[ret] = '\0'; - mbedtls_printf("[%d|L%d]: %s\n", id, line, str); - } -} - -int mbedtls_mps_trace_get_depth() -{ - return trace_depth; -} -void mbedtls_mps_trace_dec_depth() -{ - trace_depth--; -} -void mbedtls_mps_trace_inc_depth() -{ - trace_depth++; -} - -void mbedtls_mps_trace_color(int id) -{ - if (id > (int) (sizeof(colors) / sizeof(*colors))) { - return; - } - printf("%s", colors[id]); -} - -void mbedtls_mps_trace_indent(int level, mbedtls_mps_trace_type ty) -{ - if (level > 0) { - while (--level) { - printf("| "); - } - - printf("| "); - } - - switch (ty) { - case MBEDTLS_MPS_TRACE_TYPE_COMMENT: - mbedtls_printf("@ "); - break; - - case MBEDTLS_MPS_TRACE_TYPE_CALL: - mbedtls_printf("+--> "); - break; - - case MBEDTLS_MPS_TRACE_TYPE_ERROR: - mbedtls_printf("E "); - break; - - case MBEDTLS_MPS_TRACE_TYPE_RETURN: - mbedtls_printf("< "); - break; - - default: - break; - } -} - -#endif /* MBEDTLS_MPS_ENABLE_TRACE */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/vendor/mbedtls/library/mps_trace.h b/vendor/mbedtls/library/mps_trace.h deleted file mode 100644 index b456b2ffd..000000000 --- a/vendor/mbedtls/library/mps_trace.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/** - * \file mps_trace.h - * - * \brief Tracing module for MPS - */ - -#ifndef MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H -#define MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H - -#include "common.h" -#include "mps_common.h" -#include "mps_trace.h" - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_MPS_ENABLE_TRACE) - -/* - * Adapt this to enable/disable tracing output - * from the various layers of the MPS. - */ - -#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_1 -#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_2 -#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_3 -#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_4 -#define MBEDTLS_MPS_TRACE_ENABLE_READER -#define MBEDTLS_MPS_TRACE_ENABLE_WRITER - -/* - * To use the existing trace module, only change - * MBEDTLS_MPS_TRACE_ENABLE_XXX above, but don't modify the - * rest of this file. - */ - -typedef enum { - MBEDTLS_MPS_TRACE_TYPE_COMMENT, - MBEDTLS_MPS_TRACE_TYPE_CALL, - MBEDTLS_MPS_TRACE_TYPE_ERROR, - MBEDTLS_MPS_TRACE_TYPE_RETURN -} mbedtls_mps_trace_type; - -#define MBEDTLS_MPS_TRACE_BIT_LAYER_1 1 -#define MBEDTLS_MPS_TRACE_BIT_LAYER_2 2 -#define MBEDTLS_MPS_TRACE_BIT_LAYER_3 3 -#define MBEDTLS_MPS_TRACE_BIT_LAYER_4 4 -#define MBEDTLS_MPS_TRACE_BIT_WRITER 5 -#define MBEDTLS_MPS_TRACE_BIT_READER 6 - -#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_1) -#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_1) -#else -#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 0 -#endif - -#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_2) -#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_2) -#else -#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 0 -#endif - -#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_3) -#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_3) -#else -#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 0 -#endif - -#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_4) -#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_4) -#else -#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 0 -#endif - -#if defined(MBEDTLS_MPS_TRACE_ENABLE_READER) -#define MBEDTLS_MPS_TRACE_MASK_READER (1u << MBEDTLS_MPS_TRACE_BIT_READER) -#else -#define MBEDTLS_MPS_TRACE_MASK_READER 0 -#endif - -#if defined(MBEDTLS_MPS_TRACE_ENABLE_WRITER) -#define MBEDTLS_MPS_TRACE_MASK_WRITER (1u << MBEDTLS_MPS_TRACE_BIT_WRITER) -#else -#define MBEDTLS_MPS_TRACE_MASK_WRITER 0 -#endif - -#define MBEDTLS_MPS_TRACE_MASK (MBEDTLS_MPS_TRACE_MASK_LAYER_1 | \ - MBEDTLS_MPS_TRACE_MASK_LAYER_2 | \ - MBEDTLS_MPS_TRACE_MASK_LAYER_3 | \ - MBEDTLS_MPS_TRACE_MASK_LAYER_4 | \ - MBEDTLS_MPS_TRACE_MASK_READER | \ - MBEDTLS_MPS_TRACE_MASK_WRITER) - -/* We have to avoid globals because E-ACSL chokes on them... - * Wrap everything in stub functions. */ -int mbedtls_mps_trace_get_depth(void); -void mbedtls_mps_trace_inc_depth(void); -void mbedtls_mps_trace_dec_depth(void); - -void mbedtls_mps_trace_color(int id); -void mbedtls_mps_trace_indent(int level, mbedtls_mps_trace_type ty); - -void mbedtls_mps_trace_print_msg(int id, int line, const char *format, ...); - -#define MBEDTLS_MPS_TRACE(type, ...) \ - do { \ - if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \ - break; \ - mbedtls_mps_trace_indent(mbedtls_mps_trace_get_depth(), type); \ - mbedtls_mps_trace_color(mbedtls_mps_trace_id); \ - mbedtls_mps_trace_print_msg(mbedtls_mps_trace_id, __LINE__, __VA_ARGS__); \ - mbedtls_mps_trace_color(0); \ - } while (0) - -#define MBEDTLS_MPS_TRACE_INIT(...) \ - do { \ - if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \ - break; \ - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_CALL, __VA_ARGS__); \ - mbedtls_mps_trace_inc_depth(); \ - } while (0) - -#define MBEDTLS_MPS_TRACE_END(val) \ - do { \ - if (!(MBEDTLS_MPS_TRACE_MASK & (1u << mbedtls_mps_trace_id))) \ - break; \ - MBEDTLS_MPS_TRACE(MBEDTLS_MPS_TRACE_TYPE_RETURN, "%d (-%#04x)", \ - (int) (val), -((unsigned) (val))); \ - mbedtls_mps_trace_dec_depth(); \ - } while (0) - -#define MBEDTLS_MPS_TRACE_RETURN(val) \ - do { \ - /* Breaks tail recursion. */ \ - int ret__ = val; \ - MBEDTLS_MPS_TRACE_END(ret__); \ - return ret__; \ - } while (0) - -#else /* MBEDTLS_MPS_TRACE */ - -#define MBEDTLS_MPS_TRACE(type, ...) do { } while (0) -#define MBEDTLS_MPS_TRACE_INIT(...) do { } while (0) -#define MBEDTLS_MPS_TRACE_END do { } while (0) - -#define MBEDTLS_MPS_TRACE_RETURN(val) return val; - -#endif /* MBEDTLS_MPS_TRACE */ - -#endif /* MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H */ diff --git a/vendor/mbedtls/library/net_sockets.c b/vendor/mbedtls/library/net_sockets.c deleted file mode 100644 index c919f6f57..000000000 --- a/vendor/mbedtls/library/net_sockets.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * TCP/IP or UDP/IP networking functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must - * be set before mbedtls_config.h, which pulls in glibc's features.h indirectly. - * Harmless on other platforms. */ -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200112L -#endif -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 /* sockaddr_storage */ -#endif - -#include "common.h" - -#if defined(MBEDTLS_NET_C) - -#if !defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) && !defined(_WIN32) -#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in mbedtls_config.h" -#endif - -#include "mbedtls/platform.h" - -#include "mbedtls/net_sockets.h" -#include "mbedtls/error.h" - -#include - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - -#define IS_EINTR(ret) ((ret) == WSAEINTR) - -#include - -#include -#include -#if (_WIN32_WINNT < 0x0501) -#include -#endif - -#if defined(_MSC_VER) -#if defined(_WIN32_WCE) -#pragma comment( lib, "ws2.lib" ) -#else -#pragma comment( lib, "ws2_32.lib" ) -#endif -#endif /* _MSC_VER */ - -#define read(fd, buf, len) recv(fd, (char *) (buf), (int) (len), 0) -#define write(fd, buf, len) send(fd, (char *) (buf), (int) (len), 0) -#define close(fd) closesocket(fd) - -static int wsa_init_done = 0; - -#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IS_EINTR(ret) ((ret) == EINTR) -#define SOCKET int - -#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ - -/* Some MS functions want int and MSVC warns if we pass size_t, - * but the standard functions use socklen_t, so cast only for MSVC */ -#if defined(_MSC_VER) -#define MSVC_INT_CAST (int) -#else -#define MSVC_INT_CAST -#endif - -#include - -#if defined(MBEDTLS_HAVE_TIME) -#include -#endif - -#include - -/* - * Prepare for using the sockets interface - */ -static int net_prepare(void) -{ -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - WSADATA wsaData; - - if (wsa_init_done == 0) { - if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { - return MBEDTLS_ERR_NET_SOCKET_FAILED; - } - - wsa_init_done = 1; - } -#else -#if !defined(EFIX64) && !defined(EFI32) - signal(SIGPIPE, SIG_IGN); -#endif -#endif - return 0; -} - -/* - * Return 0 if the file descriptor is valid, an error otherwise. - * If for_select != 0, check whether the file descriptor is within the range - * allowed for fd_set used for the FD_xxx macros and the select() function. - */ -static int check_fd(int fd, int for_select) -{ - if (fd < 0) { - return MBEDTLS_ERR_NET_INVALID_CONTEXT; - } - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - (void) for_select; -#else - /* A limitation of select() is that it only works with file descriptors - * that are strictly less than FD_SETSIZE. This is a limitation of the - * fd_set type. Error out early, because attempting to call FD_SET on a - * large file descriptor is a buffer overflow on typical platforms. */ - if (for_select && fd >= FD_SETSIZE) { - return MBEDTLS_ERR_NET_POLL_FAILED; - } -#endif - - return 0; -} - -/* - * Initialize a context - */ -void mbedtls_net_init(mbedtls_net_context *ctx) -{ - ctx->fd = -1; -} - -/* - * Initiate a TCP connection with host:port and the given protocol - */ -int mbedtls_net_connect(mbedtls_net_context *ctx, const char *host, - const char *port, int proto) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - struct addrinfo hints, *addr_list, *cur; - - if ((ret = net_prepare()) != 0) { - return ret; - } - - /* Do name resolution with both IPv6 and IPv4 */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; - - if (getaddrinfo(host, port, &hints, &addr_list) != 0) { - return MBEDTLS_ERR_NET_UNKNOWN_HOST; - } - - /* Try the sockaddrs until a connection succeeds */ - ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; - for (cur = addr_list; cur != NULL; cur = cur->ai_next) { - ctx->fd = (int) socket(cur->ai_family, cur->ai_socktype, - cur->ai_protocol); - if (ctx->fd < 0) { - ret = MBEDTLS_ERR_NET_SOCKET_FAILED; - continue; - } - - if (connect(ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen) == 0) { - ret = 0; - break; - } - - mbedtls_net_close(ctx); - ret = MBEDTLS_ERR_NET_CONNECT_FAILED; - } - - freeaddrinfo(addr_list); - - return ret; -} - -/* - * Create a listening socket on bind_ip:port - */ -int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto) -{ - int n, ret; - struct addrinfo hints, *addr_list, *cur; - - if ((ret = net_prepare()) != 0) { - return ret; - } - - /* Bind to IPv6 and/or IPv4, but only in the desired protocol */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; - if (bind_ip == NULL) { - hints.ai_flags = AI_PASSIVE; - } - - if (getaddrinfo(bind_ip, port, &hints, &addr_list) != 0) { - return MBEDTLS_ERR_NET_UNKNOWN_HOST; - } - - /* Try the sockaddrs until a binding succeeds */ - ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; - for (cur = addr_list; cur != NULL; cur = cur->ai_next) { - ctx->fd = (int) socket(cur->ai_family, cur->ai_socktype, - cur->ai_protocol); - if (ctx->fd < 0) { - ret = MBEDTLS_ERR_NET_SOCKET_FAILED; - continue; - } - - n = 1; - if (setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR, - (const char *) &n, sizeof(n)) != 0) { - mbedtls_net_close(ctx); - ret = MBEDTLS_ERR_NET_SOCKET_FAILED; - continue; - } - - if (bind(ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen) != 0) { - mbedtls_net_close(ctx); - ret = MBEDTLS_ERR_NET_BIND_FAILED; - continue; - } - - /* Listen only makes sense for TCP */ - if (proto == MBEDTLS_NET_PROTO_TCP) { - if (listen(ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG) != 0) { - mbedtls_net_close(ctx); - ret = MBEDTLS_ERR_NET_LISTEN_FAILED; - continue; - } - } - - /* Bind was successful */ - ret = 0; - break; - } - - freeaddrinfo(addr_list); - - return ret; - -} - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) -/* - * Check if the requested operation would be blocking on a non-blocking socket - * and thus 'failed' with a negative return value. - */ -static int net_would_block(const mbedtls_net_context *ctx) -{ - ((void) ctx); - return WSAGetLastError() == WSAEWOULDBLOCK; -} -#else -/* - * Check if the requested operation would be blocking on a non-blocking socket - * and thus 'failed' with a negative return value. - * - * Note: on a blocking socket this function always returns 0! - */ -static int net_would_block(const mbedtls_net_context *ctx) -{ - int err = errno; - - /* - * Never return 'WOULD BLOCK' on a blocking socket - */ - if ((fcntl(ctx->fd, F_GETFL) & O_NONBLOCK) != O_NONBLOCK) { - errno = err; - return 0; - } - - switch (errno = err) { -#if defined EAGAIN - case EAGAIN: -#endif -#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - return 1; - } - return 0; -} -#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ - -/* - * Accept a connection from a remote client - */ -int mbedtls_net_accept(mbedtls_net_context *bind_ctx, - mbedtls_net_context *client_ctx, - void *client_ip, size_t buf_size, size_t *cip_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int type; - - struct sockaddr_storage client_addr; - -#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ - defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \ - defined(socklen_t) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) - socklen_t n = (socklen_t) sizeof(client_addr); - socklen_t type_len = (socklen_t) sizeof(type); -#else - int n = (int) sizeof(client_addr); - int type_len = (int) sizeof(type); -#endif - - /* Is this a TCP or UDP socket? */ - if (getsockopt(bind_ctx->fd, SOL_SOCKET, SO_TYPE, - (void *) &type, &type_len) != 0 || - (type != SOCK_STREAM && type != SOCK_DGRAM)) { - return MBEDTLS_ERR_NET_ACCEPT_FAILED; - } - - if (type == SOCK_STREAM) { - /* TCP: actual accept() */ - ret = client_ctx->fd = (int) accept(bind_ctx->fd, - (struct sockaddr *) &client_addr, &n); - } else { - /* UDP: wait for a message, but keep it in the queue */ - char buf[1] = { 0 }; - - ret = (int) recvfrom(bind_ctx->fd, buf, sizeof(buf), MSG_PEEK, - (struct sockaddr *) &client_addr, &n); - -#if defined(_WIN32) - if (ret == SOCKET_ERROR && - WSAGetLastError() == WSAEMSGSIZE) { - /* We know buf is too small, thanks, just peeking here */ - ret = 0; - } -#endif - } - - if (ret < 0) { - if (net_would_block(bind_ctx) != 0) { - return MBEDTLS_ERR_SSL_WANT_READ; - } - - return MBEDTLS_ERR_NET_ACCEPT_FAILED; - } - - /* UDP: hijack the listening socket to communicate with the client, - * then bind a new socket to accept new connections */ - if (type != SOCK_STREAM) { - struct sockaddr_storage local_addr; - int one = 1; - - if (connect(bind_ctx->fd, (struct sockaddr *) &client_addr, n) != 0) { - return MBEDTLS_ERR_NET_ACCEPT_FAILED; - } - - client_ctx->fd = bind_ctx->fd; - bind_ctx->fd = -1; /* In case we exit early */ - - n = sizeof(struct sockaddr_storage); - if (getsockname(client_ctx->fd, - (struct sockaddr *) &local_addr, &n) != 0 || - (bind_ctx->fd = (int) socket(local_addr.ss_family, - SOCK_DGRAM, IPPROTO_UDP)) < 0 || - setsockopt(bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, - (const char *) &one, sizeof(one)) != 0) { - return MBEDTLS_ERR_NET_SOCKET_FAILED; - } - - if (bind(bind_ctx->fd, (struct sockaddr *) &local_addr, n) != 0) { - return MBEDTLS_ERR_NET_BIND_FAILED; - } - } - - if (client_ip != NULL) { - if (client_addr.ss_family == AF_INET) { - struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; - *cip_len = sizeof(addr4->sin_addr.s_addr); - - if (buf_size < *cip_len) { - return MBEDTLS_ERR_NET_BUFFER_TOO_SMALL; - } - - memcpy(client_ip, &addr4->sin_addr.s_addr, *cip_len); - } else { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; - *cip_len = sizeof(addr6->sin6_addr.s6_addr); - - if (buf_size < *cip_len) { - return MBEDTLS_ERR_NET_BUFFER_TOO_SMALL; - } - - memcpy(client_ip, &addr6->sin6_addr.s6_addr, *cip_len); - } - } - - return 0; -} - -/* - * Set the socket blocking or non-blocking - */ -int mbedtls_net_set_block(mbedtls_net_context *ctx) -{ -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - u_long n = 0; - return ioctlsocket(ctx->fd, FIONBIO, &n); -#else - return fcntl(ctx->fd, F_SETFL, fcntl(ctx->fd, F_GETFL) & ~O_NONBLOCK); -#endif -} - -int mbedtls_net_set_nonblock(mbedtls_net_context *ctx) -{ -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - u_long n = 1; - return ioctlsocket(ctx->fd, FIONBIO, &n); -#else - return fcntl(ctx->fd, F_SETFL, fcntl(ctx->fd, F_GETFL) | O_NONBLOCK); -#endif -} - -/* - * Check if data is available on the socket - */ - -int mbedtls_net_poll(mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - struct timeval tv; - - fd_set read_fds; - fd_set write_fds; - - int fd = ctx->fd; - - ret = check_fd(fd, 1); - if (ret != 0) { - return ret; - } - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) - /* Ensure that memory sanitizers consider read_fds and write_fds as - * initialized even on platforms such as Glibc/x86_64 where FD_ZERO - * is implemented in assembly. */ - memset(&read_fds, 0, sizeof(read_fds)); - memset(&write_fds, 0, sizeof(write_fds)); -#endif -#endif - - FD_ZERO(&read_fds); - if (rw & MBEDTLS_NET_POLL_READ) { - rw &= ~MBEDTLS_NET_POLL_READ; - FD_SET((SOCKET) fd, &read_fds); - } - - FD_ZERO(&write_fds); - if (rw & MBEDTLS_NET_POLL_WRITE) { - rw &= ~MBEDTLS_NET_POLL_WRITE; - FD_SET((SOCKET) fd, &write_fds); - } - - if (rw != 0) { - return MBEDTLS_ERR_NET_BAD_INPUT_DATA; - } - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - - do { - ret = select(fd + 1, &read_fds, &write_fds, NULL, - timeout == (uint32_t) -1 ? NULL : &tv); - } while (IS_EINTR(ret)); - - if (ret < 0) { - return MBEDTLS_ERR_NET_POLL_FAILED; - } - - ret = 0; - if (FD_ISSET(fd, &read_fds)) { - ret |= MBEDTLS_NET_POLL_READ; - } - if (FD_ISSET(fd, &write_fds)) { - ret |= MBEDTLS_NET_POLL_WRITE; - } - - return ret; -} - -/* - * Portable usleep helper - */ -void mbedtls_net_usleep(unsigned long usec) -{ -#if defined(_WIN32) - Sleep((usec + 999) / 1000); -#else - struct timeval tv; - tv.tv_sec = usec / 1000000; -#if (defined(__unix__) || defined(__unix) || \ - (defined(__APPLE__) && defined(__MACH__))) && !defined(__DJGPP__) - tv.tv_usec = (suseconds_t) usec % 1000000; -#else - tv.tv_usec = usec % 1000000; -#endif - select(0, NULL, NULL, NULL, &tv); -#endif -} - -/* - * Read at most 'len' characters - */ -int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int fd = ((mbedtls_net_context *) ctx)->fd; - - ret = check_fd(fd, 0); - if (ret != 0) { - return ret; - } - - ret = (int) read(fd, buf, len); - - if (ret < 0) { - if (net_would_block(ctx) != 0) { - return MBEDTLS_ERR_SSL_WANT_READ; - } - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - if (WSAGetLastError() == WSAECONNRESET) { - return MBEDTLS_ERR_NET_CONN_RESET; - } -#else - if (errno == EPIPE || errno == ECONNRESET) { - return MBEDTLS_ERR_NET_CONN_RESET; - } - - if (errno == EINTR) { - return MBEDTLS_ERR_SSL_WANT_READ; - } -#endif - - return MBEDTLS_ERR_NET_RECV_FAILED; - } - - return ret; -} - -/* - * Read at most 'len' characters, blocking for at most 'timeout' ms - */ -int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, - size_t len, uint32_t timeout) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - struct timeval tv; - fd_set read_fds; - int fd = ((mbedtls_net_context *) ctx)->fd; - - ret = check_fd(fd, 1); - if (ret != 0) { - return ret; - } - - FD_ZERO(&read_fds); - FD_SET((SOCKET) fd, &read_fds); - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - - ret = select(fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv); - - /* Zero fds ready means we timed out */ - if (ret == 0) { - return MBEDTLS_ERR_SSL_TIMEOUT; - } - - if (ret < 0) { -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - if (WSAGetLastError() == WSAEINTR) { - return MBEDTLS_ERR_SSL_WANT_READ; - } -#else - if (errno == EINTR) { - return MBEDTLS_ERR_SSL_WANT_READ; - } -#endif - - return MBEDTLS_ERR_NET_RECV_FAILED; - } - - /* This call will not block */ - return mbedtls_net_recv(ctx, buf, len); -} - -/* - * Write at most 'len' characters - */ -int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int fd = ((mbedtls_net_context *) ctx)->fd; - - ret = check_fd(fd, 0); - if (ret != 0) { - return ret; - } - - ret = (int) write(fd, buf, len); - - if (ret < 0) { - if (net_would_block(ctx) != 0) { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - if (WSAGetLastError() == WSAECONNRESET) { - return MBEDTLS_ERR_NET_CONN_RESET; - } -#else - if (errno == EPIPE || errno == ECONNRESET) { - return MBEDTLS_ERR_NET_CONN_RESET; - } - - if (errno == EINTR) { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } -#endif - - return MBEDTLS_ERR_NET_SEND_FAILED; - } - - return ret; -} - -/* - * Close the connection - */ -void mbedtls_net_close(mbedtls_net_context *ctx) -{ - if (ctx->fd == -1) { - return; - } - - close(ctx->fd); - - ctx->fd = -1; -} - -/* - * Gracefully close the connection - */ -void mbedtls_net_free(mbedtls_net_context *ctx) -{ - if (ctx == NULL || ctx->fd == -1) { - return; - } - - shutdown(ctx->fd, 2); - close(ctx->fd); - - ctx->fd = -1; -} - -#endif /* MBEDTLS_NET_C */ diff --git a/vendor/mbedtls/library/nist_kw.c b/vendor/mbedtls/library/nist_kw.c deleted file mode 100644 index 8faafe43f..000000000 --- a/vendor/mbedtls/library/nist_kw.c +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes - * only - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * Definition of Key Wrapping: - * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf - * RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm" - * RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm" - * - * Note: RFC 3394 defines different methodology for intermediate operations for - * the wrapping and unwrapping operation than the definition in NIST SP 800-38F. - */ - -#include "common.h" - -#if defined(MBEDTLS_NIST_KW_C) - -#include "mbedtls/nist_kw.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/constant_time.h" -#include "constant_time_internal.h" - -#include -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_NIST_KW_ALT) - -#define KW_SEMIBLOCK_LENGTH 8 -#define MIN_SEMIBLOCKS_COUNT 3 - -/*! The 64-bit default integrity check value (ICV) for KW mode. */ -static const unsigned char NIST_KW_ICV1[] = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 }; -/*! The 32-bit default integrity check value (ICV) for KWP mode. */ -static const unsigned char NIST_KW_ICV2[] = { 0xA6, 0x59, 0x59, 0xA6 }; - -/* - * Initialize context - */ -void mbedtls_nist_kw_init(mbedtls_nist_kw_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_nist_kw_context)); -} - -int mbedtls_nist_kw_setkey(mbedtls_nist_kw_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits, - const int is_wrap) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_cipher_info_t *cipher_info; - - cipher_info = mbedtls_cipher_info_from_values(cipher, - keybits, - MBEDTLS_MODE_ECB); - if (cipher_info == NULL) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - /* - * SP 800-38F currently defines AES cipher as the only block cipher allowed: - * "For KW and KWP, the underlying block cipher shall be approved, and the - * block size shall be 128 bits. Currently, the AES block cipher, with key - * lengths of 128, 192, or 256 bits, is the only block cipher that fits - * this profile." - * Currently we don't support other 128 bit block ciphers for key wrapping, - * such as Camellia and Aria. - */ - if (cipher != MBEDTLS_CIPHER_ID_AES) { - return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - } - - mbedtls_cipher_free(&ctx->cipher_ctx); - - if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) { - return ret; - } - - if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits, - is_wrap ? MBEDTLS_ENCRYPT : - MBEDTLS_DECRYPT) - ) != 0) { - return ret; - } - - return 0; -} - -/* - * Free context - */ -void mbedtls_nist_kw_free(mbedtls_nist_kw_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_cipher_free(&ctx->cipher_ctx); - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_nist_kw_context)); -} - -/* - * Helper function for Xoring the uint64_t "t" with the encrypted A. - * Defined in NIST SP 800-38F section 6.1 - */ -static void calc_a_xor_t(unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t) -{ - size_t i = 0; - for (i = 0; i < sizeof(t); i++) { - A[i] ^= (t >> ((sizeof(t) - 1 - i) * 8)) & 0xff; - } -} - -/* - * KW-AE as defined in SP 800-38F section 6.2 - * KWP-AE as defined in SP 800-38F section 6.3 - */ -int mbedtls_nist_kw_wrap(mbedtls_nist_kw_context *ctx, - mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size) -{ - int ret = 0; - size_t semiblocks = 0; - size_t s; - size_t olen, padlen = 0; - uint64_t t = 0; - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; - - *out_len = 0; - /* - * Generate the String to work on - */ - if (mode == MBEDTLS_KW_MODE_KW) { - if (out_size < in_len + KW_SEMIBLOCK_LENGTH) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - /* - * According to SP 800-38F Table 1, the plaintext length for KW - * must be between 2 to 2^54-1 semiblocks inclusive. - */ - if (in_len < 16 || -#if SIZE_MAX > 0x1FFFFFFFFFFFFF8 - in_len > 0x1FFFFFFFFFFFFF8 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - memcpy(output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH); - memmove(output + KW_SEMIBLOCK_LENGTH, input, in_len); - } else { - if (in_len % 8 != 0) { - padlen = (8 - (in_len % 8)); - } - - if (out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - /* - * According to SP 800-38F Table 1, the plaintext length for KWP - * must be between 1 and 2^32-1 octets inclusive. - */ - if (in_len < 1 -#if SIZE_MAX > 0xFFFFFFFF - || in_len > 0xFFFFFFFF -#endif - ) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - memcpy(output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2); - MBEDTLS_PUT_UINT32_BE((in_len & 0xffffffff), output, - KW_SEMIBLOCK_LENGTH / 2); - - memcpy(output + KW_SEMIBLOCK_LENGTH, input, in_len); - memset(output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen); - } - semiblocks = ((in_len + padlen) / KW_SEMIBLOCK_LENGTH) + 1; - - s = 6 * (semiblocks - 1); - - if (mode == MBEDTLS_KW_MODE_KWP - && in_len <= KW_SEMIBLOCK_LENGTH) { - memcpy(inbuff, output, 16); - ret = mbedtls_cipher_update(&ctx->cipher_ctx, - inbuff, 16, output, &olen); - if (ret != 0) { - goto cleanup; - } - } else { - unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH; - unsigned char *A = output; - - /* - * Do the wrapping function W, as defined in RFC 3394 section 2.2.1 - */ - if (semiblocks < MIN_SEMIBLOCKS_COUNT) { - ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - goto cleanup; - } - - /* Calculate intermediate values */ - for (t = 1; t <= s; t++) { - memcpy(inbuff, A, KW_SEMIBLOCK_LENGTH); - memcpy(inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH); - - ret = mbedtls_cipher_update(&ctx->cipher_ctx, - inbuff, 16, outbuff, &olen); - if (ret != 0) { - goto cleanup; - } - - memcpy(A, outbuff, KW_SEMIBLOCK_LENGTH); - calc_a_xor_t(A, t); - - memcpy(R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH); - R2 += KW_SEMIBLOCK_LENGTH; - if (R2 >= output + (semiblocks * KW_SEMIBLOCK_LENGTH)) { - R2 = output + KW_SEMIBLOCK_LENGTH; - } - } - } - - *out_len = semiblocks * KW_SEMIBLOCK_LENGTH; - -cleanup: - - if (ret != 0) { - memset(output, 0, semiblocks * KW_SEMIBLOCK_LENGTH); - } - mbedtls_platform_zeroize(inbuff, KW_SEMIBLOCK_LENGTH * 2); - mbedtls_platform_zeroize(outbuff, KW_SEMIBLOCK_LENGTH * 2); - - return ret; -} - -/* - * W-1 function as defined in RFC 3394 section 2.2.2 - * This function assumes the following: - * 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH. - * 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH. - * 3. Minimal number of semiblocks is 3. - * 4. A is a buffer to hold the first semiblock of the input buffer. - */ -static int unwrap(mbedtls_nist_kw_context *ctx, - const unsigned char *input, size_t semiblocks, - unsigned char A[KW_SEMIBLOCK_LENGTH], - unsigned char *output, size_t *out_len) -{ - int ret = 0; - const size_t s = 6 * (semiblocks - 1); - size_t olen; - uint64_t t = 0; - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; - unsigned char *R = NULL; - *out_len = 0; - - if (semiblocks < MIN_SEMIBLOCKS_COUNT) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - memcpy(A, input, KW_SEMIBLOCK_LENGTH); - memmove(output, input + KW_SEMIBLOCK_LENGTH, (semiblocks - 1) * KW_SEMIBLOCK_LENGTH); - R = output + (semiblocks - 2) * KW_SEMIBLOCK_LENGTH; - - /* Calculate intermediate values */ - for (t = s; t >= 1; t--) { - calc_a_xor_t(A, t); - - memcpy(inbuff, A, KW_SEMIBLOCK_LENGTH); - memcpy(inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH); - - ret = mbedtls_cipher_update(&ctx->cipher_ctx, - inbuff, 16, outbuff, &olen); - if (ret != 0) { - goto cleanup; - } - - memcpy(A, outbuff, KW_SEMIBLOCK_LENGTH); - - /* Set R as LSB64 of outbuff */ - memcpy(R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH); - - if (R == output) { - R = output + (semiblocks - 2) * KW_SEMIBLOCK_LENGTH; - } else { - R -= KW_SEMIBLOCK_LENGTH; - } - } - - *out_len = (semiblocks - 1) * KW_SEMIBLOCK_LENGTH; - -cleanup: - if (ret != 0) { - memset(output, 0, (semiblocks - 1) * KW_SEMIBLOCK_LENGTH); - } - mbedtls_platform_zeroize(inbuff, sizeof(inbuff)); - mbedtls_platform_zeroize(outbuff, sizeof(outbuff)); - - return ret; -} - -/* - * KW-AD as defined in SP 800-38F section 6.2 - * KWP-AD as defined in SP 800-38F section 6.3 - */ -int mbedtls_nist_kw_unwrap(mbedtls_nist_kw_context *ctx, - mbedtls_nist_kw_mode_t mode, - const unsigned char *input, size_t in_len, - unsigned char *output, size_t *out_len, size_t out_size) -{ - int ret = 0; - size_t olen; - unsigned char A[KW_SEMIBLOCK_LENGTH]; - int diff; - - *out_len = 0; - if (out_size < in_len - KW_SEMIBLOCK_LENGTH) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (mode == MBEDTLS_KW_MODE_KW) { - /* - * According to SP 800-38F Table 1, the ciphertext length for KW - * must be between 3 to 2^54 semiblocks inclusive. - */ - if (in_len < 24 || -#if SIZE_MAX > 0x200000000000000 - in_len > 0x200000000000000 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - ret = unwrap(ctx, input, in_len / KW_SEMIBLOCK_LENGTH, - A, output, out_len); - if (ret != 0) { - goto cleanup; - } - - /* Check ICV in "constant-time" */ - diff = mbedtls_ct_memcmp(NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH); - - if (diff != 0) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - goto cleanup; - } - - } else if (mode == MBEDTLS_KW_MODE_KWP) { - size_t padlen = 0; - uint32_t Plen; - /* - * According to SP 800-38F Table 1, the ciphertext length for KWP - * must be between 2 to 2^29 semiblocks inclusive. - */ - if (in_len < KW_SEMIBLOCK_LENGTH * 2 || -#if SIZE_MAX > 0x100000000 - in_len > 0x100000000 || -#endif - in_len % KW_SEMIBLOCK_LENGTH != 0) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - - if (in_len == KW_SEMIBLOCK_LENGTH * 2) { - unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; - ret = mbedtls_cipher_update(&ctx->cipher_ctx, - input, 16, outbuff, &olen); - if (ret != 0) { - goto cleanup; - } - - memcpy(A, outbuff, KW_SEMIBLOCK_LENGTH); - memcpy(output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH); - mbedtls_platform_zeroize(outbuff, sizeof(outbuff)); - *out_len = KW_SEMIBLOCK_LENGTH; - } else { - /* in_len >= KW_SEMIBLOCK_LENGTH * 3 */ - ret = unwrap(ctx, input, in_len / KW_SEMIBLOCK_LENGTH, - A, output, out_len); - if (ret != 0) { - goto cleanup; - } - } - - /* Check ICV in "constant-time" */ - diff = mbedtls_ct_memcmp(NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2); - - if (diff != 0) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - Plen = MBEDTLS_GET_UINT32_BE(A, KW_SEMIBLOCK_LENGTH / 2); - - /* - * Plen is the length of the plaintext, when the input is valid. - * If Plen is larger than the plaintext and padding, padlen will be - * larger than 8, because of the type wrap around. - */ - padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen; - ret = mbedtls_ct_error_if(mbedtls_ct_uint_gt(padlen, 7), - MBEDTLS_ERR_CIPHER_AUTH_FAILED, ret); - padlen &= 7; - - /* Check padding in "constant-time" */ - const uint8_t zero[KW_SEMIBLOCK_LENGTH] = { 0 }; - diff = mbedtls_ct_memcmp_partial( - &output[*out_len - KW_SEMIBLOCK_LENGTH], zero, - KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH - padlen, 0); - - if (diff != 0) { - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - } - - if (ret != 0) { - goto cleanup; - } - memset(output + Plen, 0, padlen); - *out_len = Plen; - } else { - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto cleanup; - } - -cleanup: - if (ret != 0) { - memset(output, 0, *out_len); - *out_len = 0; - } - - mbedtls_platform_zeroize(&diff, sizeof(diff)); - mbedtls_platform_zeroize(A, sizeof(A)); - - return ret; -} - -#endif /* !MBEDTLS_NIST_KW_ALT */ - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) - -/* - * Test vectors taken from NIST - * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW - */ -static const unsigned int key_len[] = { - 16, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - 24, - 32 -#endif -}; - -static const unsigned char kw_key[][32] = { - { 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2, - 0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b, - 0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d, - 0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 }, - { 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25, - 0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33, - 0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d, - 0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 } -#endif -}; - -static const unsigned char kw_msg[][40] = { - { 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea, - 0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb, - 0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d, - 0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45, - 0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d, - 0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c }, - { 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7, - 0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8, - 0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 } -#endif -}; - -static const size_t kw_msg_len[] = { - 16, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - 40, - 24 -#endif -}; -static const size_t kw_out_len[] = { - 24, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - 48, - 32 -#endif -}; -static const unsigned char kw_res[][48] = { - { 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d, - 0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3, - 0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91, - 0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec, - 0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d, - 0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8, - 0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19, - 0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d }, - { 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d, - 0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87, - 0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9, - 0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 } -#endif -}; - -static const unsigned char kwp_key[][32] = { - { 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a, - 0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98, - 0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7, - 0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 }, - { 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5, - 0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f, - 0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae, - 0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a } -#endif -}; - -static const unsigned char kwp_msg[][31] = { - { 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8, - 0x96 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb, - 0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19, - 0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66, - 0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f }, - { 0xd1 } -#endif -}; -static const size_t kwp_msg_len[] = { - 9, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - 31, - 1 -#endif -}; - -static const unsigned char kwp_res[][48] = { - { 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e, - 0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7, - 0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 }, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - { 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13, - 0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88, - 0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63, - 0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90, - 0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 }, - { 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd, - 0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 } -#endif -}; -static const size_t kwp_out_len[] = { - 24, -#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - 40, - 16 -#endif -}; - -int mbedtls_nist_kw_self_test(int verbose) -{ - mbedtls_nist_kw_context ctx; - unsigned char out[48]; - size_t olen; - int i; - int ret = 0; - mbedtls_nist_kw_init(&ctx); - - /* - * KW mode - */ - { - static const int num_tests = sizeof(kw_key) / sizeof(*kw_key); - - for (i = 0; i < num_tests; i++) { - if (verbose != 0) { - mbedtls_printf(" KW-AES-%u ", (unsigned int) key_len[i] * 8); - } - - ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, - kw_key[i], key_len[i] * 8, 1); - if (ret != 0) { - if (verbose != 0) { - mbedtls_printf(" KW: setup failed "); - } - - goto end; - } - - ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, kw_msg[i], - kw_msg_len[i], out, &olen, sizeof(out)); - if (ret != 0 || kw_out_len[i] != olen || - memcmp(out, kw_res[i], kw_out_len[i]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed. "); - } - - ret = 1; - goto end; - } - - if ((ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, - kw_key[i], key_len[i] * 8, 0)) - != 0) { - if (verbose != 0) { - mbedtls_printf(" KW: setup failed "); - } - - goto end; - } - - ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, - out, olen, out, &olen, sizeof(out)); - - if (ret != 0 || olen != kw_msg_len[i] || - memcmp(out, kw_msg[i], kw_msg_len[i]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto end; - } - - if (verbose != 0) { - mbedtls_printf(" passed\n"); - } - } - } - - /* - * KWP mode - */ - { - static const int num_tests = sizeof(kwp_key) / sizeof(*kwp_key); - - for (i = 0; i < num_tests; i++) { - olen = sizeof(out); - if (verbose != 0) { - mbedtls_printf(" KWP-AES-%u ", (unsigned int) key_len[i] * 8); - } - - ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i], - key_len[i] * 8, 1); - if (ret != 0) { - if (verbose != 0) { - mbedtls_printf(" KWP: setup failed "); - } - - goto end; - } - ret = mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i], - kwp_msg_len[i], out, &olen, sizeof(out)); - - if (ret != 0 || kwp_out_len[i] != olen || - memcmp(out, kwp_res[i], kwp_out_len[i]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed. "); - } - - ret = 1; - goto end; - } - - if ((ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, - kwp_key[i], key_len[i] * 8, 0)) - != 0) { - if (verbose != 0) { - mbedtls_printf(" KWP: setup failed "); - } - - goto end; - } - - ret = mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KWP, out, - olen, out, &olen, sizeof(out)); - - if (ret != 0 || olen != kwp_msg_len[i] || - memcmp(out, kwp_msg[i], kwp_msg_len[i]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed. "); - } - - ret = 1; - goto end; - } - - if (verbose != 0) { - mbedtls_printf(" passed\n"); - } - } - } -end: - mbedtls_nist_kw_free(&ctx); - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_NIST_KW_C */ diff --git a/vendor/mbedtls/library/oid.c b/vendor/mbedtls/library/oid.c deleted file mode 100644 index 1d6b1eb86..000000000 --- a/vendor/mbedtls/library/oid.c +++ /dev/null @@ -1,1166 +0,0 @@ -/** - * \file oid.c - * - * \brief Object Identifier (OID) database - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_OID_C) - -#include "mbedtls/oid.h" -#include "mbedtls/rsa.h" -#include "mbedtls/error.h" -#include "mbedtls/pk.h" - -#include -#include - -#include "mbedtls/platform.h" - -/* - * Macro to automatically add the size of #define'd OIDs - */ -#define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s) - -/* - * Macro to generate mbedtls_oid_descriptor_t - */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) -#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s), name, description } -#define NULL_OID_DESCRIPTOR { NULL, 0, NULL, NULL } -#else -#define OID_DESCRIPTOR(s, name, description) { ADD_LEN(s) } -#define NULL_OID_DESCRIPTOR { NULL, 0 } -#endif - -/* - * Macro to generate an internal function for oid_XXX_from_asn1() (used by - * the other functions) - */ -#define FN_OID_TYPED_FROM_ASN1(TYPE_T, NAME, LIST) \ - static const TYPE_T *oid_ ## NAME ## _from_asn1( \ - const mbedtls_asn1_buf *oid) \ - { \ - const TYPE_T *p = (LIST); \ - const mbedtls_oid_descriptor_t *cur = \ - (const mbedtls_oid_descriptor_t *) p; \ - if (p == NULL || oid == NULL) return NULL; \ - while (cur->asn1 != NULL) { \ - if (cur->asn1_len == oid->len && \ - memcmp(cur->asn1, oid->p, oid->len) == 0) { \ - return p; \ - } \ - p++; \ - cur = (const mbedtls_oid_descriptor_t *) p; \ - } \ - return NULL; \ - } - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -/* - * Macro to generate a function for retrieving a single attribute from the - * descriptor of an mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ - int FN_NAME(const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1) \ - { \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1(oid); \ - if (data == NULL) return MBEDTLS_ERR_OID_NOT_FOUND; \ - *ATTR1 = data->descriptor.ATTR1; \ - return 0; \ - } -#endif /* MBEDTLS_X509_REMOVE_INFO */ - -/* - * Macro to generate a function for retrieving a single attribute from an - * mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ - int FN_NAME(const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1) \ - { \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1(oid); \ - if (data == NULL) return MBEDTLS_ERR_OID_NOT_FOUND; \ - *ATTR1 = data->ATTR1; \ - return 0; \ - } - -/* - * Macro to generate a function for retrieving two attributes from an - * mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ - ATTR2_TYPE, ATTR2) \ - int FN_NAME(const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \ - ATTR2_TYPE * ATTR2) \ - { \ - const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1(oid); \ - if (data == NULL) return MBEDTLS_ERR_OID_NOT_FOUND; \ - *(ATTR1) = data->ATTR1; \ - *(ATTR2) = data->ATTR2; \ - return 0; \ - } - -/* - * Macro to generate a function for retrieving the OID based on a single - * attribute from a mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ - int FN_NAME(ATTR1_TYPE ATTR1, const char **oid, size_t *olen) \ - { \ - const TYPE_T *cur = (LIST); \ - while (cur->descriptor.asn1 != NULL) { \ - if (cur->ATTR1 == (ATTR1)) { \ - *oid = cur->descriptor.asn1; \ - *olen = cur->descriptor.asn1_len; \ - return 0; \ - } \ - cur++; \ - } \ - return MBEDTLS_ERR_OID_NOT_FOUND; \ - } - -/* - * Macro to generate a function for retrieving the OID based on two - * attributes from a mbedtls_oid_descriptor_t wrapper. - */ -#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \ - ATTR2_TYPE, ATTR2) \ - int FN_NAME(ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid, \ - size_t *olen) \ - { \ - const TYPE_T *cur = (LIST); \ - while (cur->descriptor.asn1 != NULL) { \ - if (cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2)) { \ - *oid = cur->descriptor.asn1; \ - *olen = cur->descriptor.asn1_len; \ - return 0; \ - } \ - cur++; \ - } \ - return MBEDTLS_ERR_OID_NOT_FOUND; \ - } - -/* - * For X520 attribute types - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - const char *short_name; -} oid_x520_attr_t; - -static const oid_x520_attr_t oid_x520_attr_type[] = -{ - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_CN, "id-at-commonName", "Common Name"), - "CN", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_COUNTRY, "id-at-countryName", "Country"), - "C", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_LOCALITY, "id-at-locality", "Locality"), - "L", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_STATE, "id-at-state", "State"), - "ST", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_ORGANIZATION, "id-at-organizationName", - "Organization"), - "O", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_ORG_UNIT, "id-at-organizationalUnitName", "Org Unit"), - "OU", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS9_EMAIL, - "emailAddress", - "E-mail address"), - "emailAddress", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_SERIAL_NUMBER, - "id-at-serialNumber", - "Serial number"), - "serialNumber", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_POSTAL_ADDRESS, - "id-at-postalAddress", - "Postal address"), - "postalAddress", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_POSTAL_CODE, "id-at-postalCode", "Postal code"), - "postalCode", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_SUR_NAME, "id-at-surName", "Surname"), - "SN", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_GIVEN_NAME, "id-at-givenName", "Given name"), - "GN", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_INITIALS, "id-at-initials", "Initials"), - "initials", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_GENERATION_QUALIFIER, - "id-at-generationQualifier", - "Generation qualifier"), - "generationQualifier", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_TITLE, "id-at-title", "Title"), - "title", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_DN_QUALIFIER, - "id-at-dnQualifier", - "Distinguished Name qualifier"), - "dnQualifier", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_PSEUDONYM, "id-at-pseudonym", "Pseudonym"), - "pseudonym", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_UID, "id-uid", "User Id"), - "uid", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_DOMAIN_COMPONENT, - "id-domainComponent", - "Domain component"), - "DC", - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AT_UNIQUE_IDENTIFIER, - "id-at-uniqueIdentifier", - "Unique Identifier"), - "uniqueIdentifier", - }, - { - NULL_OID_DESCRIPTOR, - NULL, - } -}; - -FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) -FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, - oid_x520_attr_t, - x520_attr, - const char *, - short_name) - -/* - * For X509 extensions - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - int ext_type; -} oid_x509_ext_t; - -static const oid_x509_ext_t oid_x509_ext[] = -{ - { - OID_DESCRIPTOR(MBEDTLS_OID_BASIC_CONSTRAINTS, - "id-ce-basicConstraints", - "Basic Constraints"), - MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_KEY_USAGE, "id-ce-keyUsage", "Key Usage"), - MBEDTLS_OID_X509_EXT_KEY_USAGE, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_EXTENDED_KEY_USAGE, - "id-ce-extKeyUsage", - "Extended Key Usage"), - MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_SUBJECT_ALT_NAME, - "id-ce-subjectAltName", - "Subject Alt Name"), - MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_NS_CERT_TYPE, - "id-netscape-certtype", - "Netscape Certificate Type"), - MBEDTLS_OID_X509_EXT_NS_CERT_TYPE, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_CERTIFICATE_POLICIES, - "id-ce-certificatePolicies", - "Certificate Policies"), - MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, - "id-ce-subjectKeyIdentifier", - "Subject Key Identifier"), - MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, - "id-ce-authorityKeyIdentifier", - "Authority Key Identifier"), - MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER, - }, - { - NULL_OID_DESCRIPTOR, - 0, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext) -FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type) - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = -{ - OID_DESCRIPTOR(MBEDTLS_OID_SERVER_AUTH, - "id-kp-serverAuth", - "TLS Web Server Authentication"), - OID_DESCRIPTOR(MBEDTLS_OID_CLIENT_AUTH, - "id-kp-clientAuth", - "TLS Web Client Authentication"), - OID_DESCRIPTOR(MBEDTLS_OID_CODE_SIGNING, "id-kp-codeSigning", "Code Signing"), - OID_DESCRIPTOR(MBEDTLS_OID_EMAIL_PROTECTION, "id-kp-emailProtection", "E-mail Protection"), - OID_DESCRIPTOR(MBEDTLS_OID_TIME_STAMPING, "id-kp-timeStamping", "Time Stamping"), - OID_DESCRIPTOR(MBEDTLS_OID_OCSP_SIGNING, "id-kp-OCSPSigning", "OCSP Signing"), - OID_DESCRIPTOR(MBEDTLS_OID_WISUN_FAN, - "id-kp-wisun-fan-device", - "Wi-SUN Alliance Field Area Network (FAN)"), - NULL_OID_DESCRIPTOR, -}; - -FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage) -FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, - mbedtls_oid_descriptor_t, - ext_key_usage, - const char *, - description) - -static const mbedtls_oid_descriptor_t oid_certificate_policies[] = -{ - OID_DESCRIPTOR(MBEDTLS_OID_ANY_POLICY, "anyPolicy", "Any Policy"), - NULL_OID_DESCRIPTOR, -}; - -FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, certificate_policies, oid_certificate_policies) -FN_OID_GET_ATTR1(mbedtls_oid_get_certificate_policies, - mbedtls_oid_descriptor_t, - certificate_policies, - const char *, - description) -#endif /* MBEDTLS_X509_REMOVE_INFO */ - -/* - * For SignatureAlgorithmIdentifier - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; - mbedtls_pk_type_t pk_alg; -} oid_sig_alg_t; - -static const oid_sig_alg_t oid_sig_alg[] = -{ -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_MD_CAN_MD5) - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_MD5, "md5WithRSAEncryption", "RSA with MD5"), - MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD_CAN_MD5 */ -#if defined(MBEDTLS_MD_CAN_SHA1) - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA1, "sha-1WithRSAEncryption", "RSA with SHA1"), - MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_MD_CAN_SHA224) - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA224, "sha224WithRSAEncryption", - "RSA with SHA-224"), - MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA224 */ -#if defined(MBEDTLS_MD_CAN_SHA256) - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA256, "sha256WithRSAEncryption", - "RSA with SHA-256"), - MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA384, "sha384WithRSAEncryption", - "RSA with SHA-384"), - MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_MD_CAN_SHA512) - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_SHA512, "sha512WithRSAEncryption", - "RSA with SHA-512"), - MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA512 */ -#if defined(MBEDTLS_MD_CAN_SHA1) - { - OID_DESCRIPTOR(MBEDTLS_OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1"), - MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) -#if defined(MBEDTLS_MD_CAN_SHA1) - { - OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA1, "ecdsa-with-SHA1", "ECDSA with SHA1"), - MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_MD_CAN_SHA224) - { - OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA224, "ecdsa-with-SHA224", "ECDSA with SHA224"), - MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - { - OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA256, "ecdsa-with-SHA256", "ECDSA with SHA256"), - MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { - OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA384, "ecdsa-with-SHA384", "ECDSA with SHA384"), - MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_MD_CAN_SHA512) - { - OID_DESCRIPTOR(MBEDTLS_OID_ECDSA_SHA512, "ecdsa-with-SHA512", "ECDSA with SHA512"), - MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, - }, -#endif /* MBEDTLS_MD_CAN_SHA512 */ -#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ -#if defined(MBEDTLS_RSA_C) - { - OID_DESCRIPTOR(MBEDTLS_OID_RSASSA_PSS, "RSASSA-PSS", "RSASSA-PSS"), - MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, - }, -#endif /* MBEDTLS_RSA_C */ - { - NULL_OID_DESCRIPTOR, - MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg) - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, - oid_sig_alg_t, - sig_alg, - const char *, - description) -#endif - -FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, - oid_sig_alg_t, - sig_alg, - mbedtls_md_type_t, - md_alg, - mbedtls_pk_type_t, - pk_alg) -FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, - oid_sig_alg_t, - oid_sig_alg, - mbedtls_pk_type_t, - pk_alg, - mbedtls_md_type_t, - md_alg) - -/* - * For PublicKeyInfo (PKCS1, RFC 5480) - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_pk_type_t pk_alg; -} oid_pk_alg_t; - -static const oid_pk_alg_t oid_pk_alg[] = -{ - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS1_RSA, "rsaEncryption", "RSA"), - MBEDTLS_PK_RSA, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_ALG_UNRESTRICTED, "id-ecPublicKey", "Generic EC key"), - MBEDTLS_PK_ECKEY, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_ALG_ECDH, "id-ecDH", "EC key for ECDH"), - MBEDTLS_PK_ECKEY_DH, - }, - { - NULL_OID_DESCRIPTOR, - MBEDTLS_PK_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, - oid_pk_alg_t, - oid_pk_alg, - mbedtls_pk_type_t, - pk_alg) - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -/* - * For elliptic curves that use namedCurve inside ECParams (RFC 5480) - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_ecp_group_id grp_id; -} oid_ecp_grp_t; - -static const oid_ecp_grp_t oid_ecp_grp[] = -{ -#if defined(MBEDTLS_ECP_HAVE_SECP192R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP192R1, "secp192r1", "secp192r1"), - MBEDTLS_ECP_DP_SECP192R1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP192R1 */ -#if defined(MBEDTLS_ECP_HAVE_SECP224R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP224R1, "secp224r1", "secp224r1"), - MBEDTLS_ECP_DP_SECP224R1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP224R1 */ -#if defined(MBEDTLS_ECP_HAVE_SECP256R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP256R1, "secp256r1", "secp256r1"), - MBEDTLS_ECP_DP_SECP256R1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP256R1 */ -#if defined(MBEDTLS_ECP_HAVE_SECP384R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP384R1, "secp384r1", "secp384r1"), - MBEDTLS_ECP_DP_SECP384R1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP384R1 */ -#if defined(MBEDTLS_ECP_HAVE_SECP521R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP521R1, "secp521r1", "secp521r1"), - MBEDTLS_ECP_DP_SECP521R1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP521R1 */ -#if defined(MBEDTLS_ECP_HAVE_SECP192K1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP192K1, "secp192k1", "secp192k1"), - MBEDTLS_ECP_DP_SECP192K1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP192K1 */ -#if defined(MBEDTLS_ECP_HAVE_SECP224K1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP224K1, "secp224k1", "secp224k1"), - MBEDTLS_ECP_DP_SECP224K1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP224K1 */ -#if defined(MBEDTLS_ECP_HAVE_SECP256K1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_SECP256K1, "secp256k1", "secp256k1"), - MBEDTLS_ECP_DP_SECP256K1, - }, -#endif /* MBEDTLS_ECP_HAVE_SECP256K1 */ -#if defined(MBEDTLS_ECP_HAVE_BP256R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_BP256R1, "brainpoolP256r1", "brainpool256r1"), - MBEDTLS_ECP_DP_BP256R1, - }, -#endif /* MBEDTLS_ECP_HAVE_BP256R1 */ -#if defined(MBEDTLS_ECP_HAVE_BP384R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_BP384R1, "brainpoolP384r1", "brainpool384r1"), - MBEDTLS_ECP_DP_BP384R1, - }, -#endif /* MBEDTLS_ECP_HAVE_BP384R1 */ -#if defined(MBEDTLS_ECP_HAVE_BP512R1) - { - OID_DESCRIPTOR(MBEDTLS_OID_EC_GRP_BP512R1, "brainpoolP512r1", "brainpool512r1"), - MBEDTLS_ECP_DP_BP512R1, - }, -#endif /* MBEDTLS_ECP_HAVE_BP512R1 */ - { - NULL_OID_DESCRIPTOR, - MBEDTLS_ECP_DP_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp) -FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, - oid_ecp_grp_t, - oid_ecp_grp, - mbedtls_ecp_group_id, - grp_id) - -/* - * For Elliptic Curve algorithms that are directly - * encoded in the AlgorithmIdentifier (RFC 8410) - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_ecp_group_id grp_id; -} oid_ecp_grp_algid_t; - -static const oid_ecp_grp_algid_t oid_ecp_grp_algid[] = -{ -#if defined(MBEDTLS_ECP_HAVE_CURVE25519) - { - OID_DESCRIPTOR(MBEDTLS_OID_X25519, "X25519", "X25519"), - MBEDTLS_ECP_DP_CURVE25519, - }, -#endif /* MBEDTLS_ECP_HAVE_CURVE25519 */ -#if defined(MBEDTLS_ECP_HAVE_CURVE448) - { - OID_DESCRIPTOR(MBEDTLS_OID_X448, "X448", "X448"), - MBEDTLS_ECP_DP_CURVE448, - }, -#endif /* MBEDTLS_ECP_HAVE_CURVE448 */ - { - NULL_OID_DESCRIPTOR, - MBEDTLS_ECP_DP_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_algid_t, grp_id_algid, oid_ecp_grp_algid) -FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp_algid, - oid_ecp_grp_algid_t, - grp_id_algid, - mbedtls_ecp_group_id, - grp_id) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp_algid, - oid_ecp_grp_algid_t, - oid_ecp_grp_algid, - mbedtls_ecp_group_id, - grp_id) -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_CIPHER_C) -/* - * For PKCS#5 PBES2 encryption algorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_cipher_type_t cipher_alg; -} oid_cipher_alg_t; - -static const oid_cipher_alg_t oid_cipher_alg[] = -{ - { - OID_DESCRIPTOR(MBEDTLS_OID_DES_CBC, "desCBC", "DES-CBC"), - MBEDTLS_CIPHER_DES_CBC, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_DES_EDE3_CBC, "des-ede3-cbc", "DES-EDE3-CBC"), - MBEDTLS_CIPHER_DES_EDE3_CBC, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AES_128_CBC, "aes128-cbc", "AES128-CBC"), - MBEDTLS_CIPHER_AES_128_CBC, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AES_192_CBC, "aes192-cbc", "AES192-CBC"), - MBEDTLS_CIPHER_AES_192_CBC, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_AES_256_CBC, "aes256-cbc", "AES256-CBC"), - MBEDTLS_CIPHER_AES_256_CBC, - }, - { - NULL_OID_DESCRIPTOR, - MBEDTLS_CIPHER_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_cipher_alg, - oid_cipher_alg_t, - cipher_alg, - mbedtls_cipher_type_t, - cipher_alg) -#endif /* MBEDTLS_CIPHER_C */ - -/* - * For digestAlgorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; -} oid_md_alg_t; - -static const oid_md_alg_t oid_md_alg[] = -{ -#if defined(MBEDTLS_MD_CAN_MD5) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_MD5, "id-md5", "MD5"), - MBEDTLS_MD_MD5, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA1) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1"), - MBEDTLS_MD_SHA1, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA224) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA224, "id-sha224", "SHA-224"), - MBEDTLS_MD_SHA224, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA256, "id-sha256", "SHA-256"), - MBEDTLS_MD_SHA256, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA384, "id-sha384", "SHA-384"), - MBEDTLS_MD_SHA384, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA512) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA512, "id-sha512", "SHA-512"), - MBEDTLS_MD_SHA512, - }, -#endif -#if defined(MBEDTLS_MD_CAN_RIPEMD160) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_RIPEMD160, "id-ripemd160", "RIPEMD-160"), - MBEDTLS_MD_RIPEMD160, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_224) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_224, "id-sha3-224", "SHA-3-224"), - MBEDTLS_MD_SHA3_224, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_256) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_256, "id-sha3-256", "SHA-3-256"), - MBEDTLS_MD_SHA3_256, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_384) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_384, "id-sha3-384", "SHA-3-384"), - MBEDTLS_MD_SHA3_384, - }, -#endif -#if defined(MBEDTLS_MD_CAN_SHA3_512) - { - OID_DESCRIPTOR(MBEDTLS_OID_DIGEST_ALG_SHA3_512, "id-sha3-512", "SHA-3-512"), - MBEDTLS_MD_SHA3_512, - }, -#endif - { - NULL_OID_DESCRIPTOR, - MBEDTLS_MD_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) -FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) -FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, - oid_md_alg_t, - oid_md_alg, - mbedtls_md_type_t, - md_alg) - -/* - * For HMAC digestAlgorithm - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_hmac; -} oid_md_hmac_t; - -static const oid_md_hmac_t oid_md_hmac[] = -{ -#if defined(MBEDTLS_MD_CAN_SHA1) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA1, "hmacSHA1", "HMAC-SHA-1"), - MBEDTLS_MD_SHA1, - }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_MD_CAN_SHA224) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA224, "hmacSHA224", "HMAC-SHA-224"), - MBEDTLS_MD_SHA224, - }, -#endif /* MBEDTLS_MD_CAN_SHA224 */ -#if defined(MBEDTLS_MD_CAN_SHA256) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA256, "hmacSHA256", "HMAC-SHA-256"), - MBEDTLS_MD_SHA256, - }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA384, "hmacSHA384", "HMAC-SHA-384"), - MBEDTLS_MD_SHA384, - }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_MD_CAN_SHA512) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA512, "hmacSHA512", "HMAC-SHA-512"), - MBEDTLS_MD_SHA512, - }, -#endif /* MBEDTLS_MD_CAN_SHA512 */ -#if defined(MBEDTLS_MD_CAN_SHA3_224) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA3_224, "hmacSHA3-224", "HMAC-SHA3-224"), - MBEDTLS_MD_SHA3_224, - }, -#endif /* MBEDTLS_MD_CAN_SHA3_224 */ -#if defined(MBEDTLS_MD_CAN_SHA3_256) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA3_256, "hmacSHA3-256", "HMAC-SHA3-256"), - MBEDTLS_MD_SHA3_256, - }, -#endif /* MBEDTLS_MD_CAN_SHA3_256 */ -#if defined(MBEDTLS_MD_CAN_SHA3_384) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA3_384, "hmacSHA3-384", "HMAC-SHA3-384"), - MBEDTLS_MD_SHA3_384, - }, -#endif /* MBEDTLS_MD_CAN_SHA3_384 */ -#if defined(MBEDTLS_MD_CAN_SHA3_512) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_SHA3_512, "hmacSHA3-512", "HMAC-SHA3-512"), - MBEDTLS_MD_SHA3_512, - }, -#endif /* MBEDTLS_MD_CAN_SHA3_512 */ -#if defined(MBEDTLS_MD_CAN_RIPEMD160) - { - OID_DESCRIPTOR(MBEDTLS_OID_HMAC_RIPEMD160, "hmacRIPEMD160", "HMAC-RIPEMD160"), - MBEDTLS_MD_RIPEMD160, - }, -#endif /* MBEDTLS_MD_CAN_RIPEMD160 */ - { - NULL_OID_DESCRIPTOR, - MBEDTLS_MD_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac) -FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac) - -#if defined(MBEDTLS_PKCS12_C) && defined(MBEDTLS_CIPHER_C) -/* - * For PKCS#12 PBEs - */ -typedef struct { - mbedtls_oid_descriptor_t descriptor; - mbedtls_md_type_t md_alg; - mbedtls_cipher_type_t cipher_alg; -} oid_pkcs12_pbe_alg_t; - -static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = -{ - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC, - "pbeWithSHAAnd3-KeyTripleDES-CBC", - "PBE with SHA1 and 3-Key 3DES"), - MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC, - }, - { - OID_DESCRIPTOR(MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC, - "pbeWithSHAAnd2-KeyTripleDES-CBC", - "PBE with SHA1 and 2-Key 3DES"), - MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC, - }, - { - NULL_OID_DESCRIPTOR, - MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE, - }, -}; - -FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg) -FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, - oid_pkcs12_pbe_alg_t, - pkcs12_pbe_alg, - mbedtls_md_type_t, - md_alg, - mbedtls_cipher_type_t, - cipher_alg) -#endif /* MBEDTLS_PKCS12_C && MBEDTLS_CIPHER_C */ - -/* Return the x.y.z.... style numeric string for the given OID */ -int mbedtls_oid_get_numeric_string(char *buf, size_t size, - const mbedtls_asn1_buf *oid) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - char *p = buf; - size_t n = size; - unsigned int value = 0; - - if (size > INT_MAX) { - /* Avoid overflow computing return value */ - return MBEDTLS_ERR_ASN1_INVALID_LENGTH; - } - - if (oid->len <= 0) { - /* OID must not be empty */ - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - - for (size_t i = 0; i < oid->len; i++) { - /* Prevent overflow in value. */ - if (value > (UINT_MAX >> 7)) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - if ((value == 0) && ((oid->p[i]) == 0x80)) { - /* Overlong encoding is not allowed */ - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - - value <<= 7; - value |= oid->p[i] & 0x7F; - - if (!(oid->p[i] & 0x80)) { - /* Last byte */ - if (n == size) { - int component1; - unsigned int component2; - /* First subidentifier contains first two OID components */ - if (value >= 80) { - component1 = '2'; - component2 = value - 80; - } else if (value >= 40) { - component1 = '1'; - component2 = value - 40; - } else { - component1 = '0'; - component2 = value; - } - ret = mbedtls_snprintf(p, n, "%c.%u", component1, component2); - } else { - ret = mbedtls_snprintf(p, n, ".%u", value); - } - if (ret < 2 || (size_t) ret >= n) { - return MBEDTLS_ERR_OID_BUF_TOO_SMALL; - } - n -= (size_t) ret; - p += ret; - value = 0; - } - } - - if (value != 0) { - /* Unterminated subidentifier */ - return MBEDTLS_ERR_ASN1_OUT_OF_DATA; - } - - return (int) (size - n); -} - -static int oid_parse_number(unsigned int *num, const char **p, const char *bound) -{ - int ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - - *num = 0; - - while (*p < bound && **p >= '0' && **p <= '9') { - ret = 0; - if (*num > (UINT_MAX / 10)) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - *num *= 10; - *num += **p - '0'; - (*p)++; - } - return ret; -} - -static size_t oid_subidentifier_num_bytes(unsigned int value) -{ - size_t num_bytes = 0; - - do { - value >>= 7; - num_bytes++; - } while (value != 0); - - return num_bytes; -} - -static int oid_subidentifier_encode_into(unsigned char **p, - unsigned char *bound, - unsigned int value) -{ - size_t num_bytes = oid_subidentifier_num_bytes(value); - - if ((size_t) (bound - *p) < num_bytes) { - return MBEDTLS_ERR_OID_BUF_TOO_SMALL; - } - (*p)[num_bytes - 1] = (unsigned char) (value & 0x7f); - value >>= 7; - - for (size_t i = 2; i <= num_bytes; i++) { - (*p)[num_bytes - i] = 0x80 | (unsigned char) (value & 0x7f); - value >>= 7; - } - *p += num_bytes; - - return 0; -} - -/* Return the OID for the given x.y.z.... style numeric string */ -int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid, - const char *oid_str, size_t size) -{ - int ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - const char *str_ptr = oid_str; - const char *str_bound = oid_str + size; - unsigned int val = 0; - unsigned int component1, component2; - size_t encoded_len; - unsigned char *resized_mem; - - /* Count the number of dots to get a worst-case allocation size. */ - size_t num_dots = 0; - for (size_t i = 0; i < size; i++) { - if (oid_str[i] == '.') { - num_dots++; - } - } - /* Allocate maximum possible required memory: - * There are (num_dots + 1) integer components, but the first 2 share the - * same subidentifier, so we only need num_dots subidentifiers maximum. */ - if (num_dots == 0 || (num_dots > MBEDTLS_OID_MAX_COMPONENTS - 1)) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - /* Each byte can store 7 bits, calculate number of bytes for a - * subidentifier: - * - * bytes = ceil(subidentifer_size * 8 / 7) - */ - size_t bytes_per_subidentifier = (((sizeof(unsigned int) * 8) - 1) / 7) - + 1; - size_t max_possible_bytes = num_dots * bytes_per_subidentifier; - oid->p = mbedtls_calloc(max_possible_bytes, 1); - if (oid->p == NULL) { - return MBEDTLS_ERR_ASN1_ALLOC_FAILED; - } - unsigned char *out_ptr = oid->p; - unsigned char *out_bound = oid->p + max_possible_bytes; - - ret = oid_parse_number(&component1, &str_ptr, str_bound); - if (ret != 0) { - goto error; - } - if (component1 > 2) { - /* First component can't be > 2 */ - ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - goto error; - } - if (str_ptr >= str_bound || *str_ptr != '.') { - ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - goto error; - } - str_ptr++; - - ret = oid_parse_number(&component2, &str_ptr, str_bound); - if (ret != 0) { - goto error; - } - if ((component1 < 2) && (component2 > 39)) { - /* Root nodes 0 and 1 may have up to 40 children, numbered 0-39 */ - ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - goto error; - } - if (str_ptr < str_bound) { - if (*str_ptr == '.') { - str_ptr++; - } else { - ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - goto error; - } - } - - if (component2 > (UINT_MAX - (component1 * 40))) { - ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - goto error; - } - ret = oid_subidentifier_encode_into(&out_ptr, out_bound, - (component1 * 40) + component2); - if (ret != 0) { - goto error; - } - - while (str_ptr < str_bound) { - ret = oid_parse_number(&val, &str_ptr, str_bound); - if (ret != 0) { - goto error; - } - if (str_ptr < str_bound) { - if (*str_ptr == '.') { - str_ptr++; - } else { - ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - goto error; - } - } - - ret = oid_subidentifier_encode_into(&out_ptr, out_bound, val); - if (ret != 0) { - goto error; - } - } - - encoded_len = (size_t) (out_ptr - oid->p); - resized_mem = mbedtls_calloc(encoded_len, 1); - if (resized_mem == NULL) { - ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED; - goto error; - } - memcpy(resized_mem, oid->p, encoded_len); - mbedtls_free(oid->p); - oid->p = resized_mem; - oid->len = encoded_len; - - oid->tag = MBEDTLS_ASN1_OID; - - return 0; - -error: - mbedtls_free(oid->p); - oid->p = NULL; - oid->len = 0; - return ret; -} - -#endif /* MBEDTLS_OID_C */ diff --git a/vendor/mbedtls/library/padlock.c b/vendor/mbedtls/library/padlock.c deleted file mode 100644 index 1f006910c..000000000 --- a/vendor/mbedtls/library/padlock.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * VIA PadLock support functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * This implementation is based on the VIA PadLock Programming Guide: - * - * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ - * programming_guide.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_PADLOCK_C) - -#include "padlock.h" - -#include - -#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) - -/* - * PadLock detection routine - */ -int mbedtls_padlock_has_support(int feature) -{ - static int flags = -1; - int ebx = 0, edx = 0; - - if (flags == -1) { - asm ("movl %%ebx, %0 \n\t" - "movl $0xC0000000, %%eax \n\t" - "cpuid \n\t" - "cmpl $0xC0000001, %%eax \n\t" - "movl $0, %%edx \n\t" - "jb 1f \n\t" - "movl $0xC0000001, %%eax \n\t" - "cpuid \n\t" - "1: \n\t" - "movl %%edx, %1 \n\t" - "movl %2, %%ebx \n\t" - : "=m" (ebx), "=m" (edx) - : "m" (ebx) - : "eax", "ecx", "edx"); - - flags = edx; - } - - return flags & feature; -} - -/* - * PadLock AES-ECB block en(de)cryption - */ -int mbedtls_padlock_xcryptecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]) -{ - int ebx = 0; - uint32_t *rk; - uint32_t *blk; - uint32_t *ctrl; - unsigned char buf[256]; - - rk = ctx->buf + ctx->rk_offset; - - if (((long) rk & 15) != 0) { - return MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED; - } - - blk = MBEDTLS_PADLOCK_ALIGN16(buf); - memcpy(blk, input, 16); - - ctrl = blk + 4; - *ctrl = 0x80 | ctx->nr | ((ctx->nr + (mode^1) - 10) << 9); - - asm ("pushfl \n\t" - "popfl \n\t" - "movl %%ebx, %0 \n\t" - "movl $1, %%ecx \n\t" - "movl %2, %%edx \n\t" - "movl %3, %%ebx \n\t" - "movl %4, %%esi \n\t" - "movl %4, %%edi \n\t" - ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" - "movl %1, %%ebx \n\t" - : "=m" (ebx) - : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) - : "memory", "ecx", "edx", "esi", "edi"); - - memcpy(output, blk, 16); - - return 0; -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * PadLock AES-CBC buffer en(de)cryption - */ -int mbedtls_padlock_xcryptcbc(mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output) -{ - int ebx = 0; - size_t count; - uint32_t *rk; - uint32_t *iw; - uint32_t *ctrl; - unsigned char buf[256]; - - rk = ctx->buf + ctx->rk_offset; - - if (((long) input & 15) != 0 || - ((long) output & 15) != 0 || - ((long) rk & 15) != 0) { - return MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED; - } - - iw = MBEDTLS_PADLOCK_ALIGN16(buf); - memcpy(iw, iv, 16); - - ctrl = iw + 4; - *ctrl = 0x80 | ctx->nr | ((ctx->nr + (mode ^ 1) - 10) << 9); - - count = (length + 15) >> 4; - - asm ("pushfl \n\t" - "popfl \n\t" - "movl %%ebx, %0 \n\t" - "movl %2, %%ecx \n\t" - "movl %3, %%edx \n\t" - "movl %4, %%ebx \n\t" - "movl %5, %%esi \n\t" - "movl %6, %%edi \n\t" - "movl %7, %%eax \n\t" - ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" - "movl %1, %%ebx \n\t" - : "=m" (ebx) - : "m" (ebx), "m" (count), "m" (ctrl), - "m" (rk), "m" (input), "m" (output), "m" (iw) - : "memory", "eax", "ecx", "edx", "esi", "edi"); - - memcpy(iv, iw, 16); - - return 0; -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#endif /* MBEDTLS_VIA_PADLOCK_HAVE_CODE */ - -#endif /* MBEDTLS_PADLOCK_C */ diff --git a/vendor/mbedtls/library/padlock.h b/vendor/mbedtls/library/padlock.h deleted file mode 100644 index 92d72af51..000000000 --- a/vendor/mbedtls/library/padlock.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * \file padlock.h - * - * \brief VIA PadLock ACE for HW encryption/decryption supported by some - * processors - * - * \warning These functions are only for internal use by other library - * functions; you must not call them directly. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PADLOCK_H -#define MBEDTLS_PADLOCK_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/aes.h" - -#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ - -#if defined(__has_feature) -#if __has_feature(address_sanitizer) -#define MBEDTLS_HAVE_ASAN -#endif -#endif - -/* - * - `padlock` is implements with GNUC assembly for x86 target. - * - Some versions of ASan result in errors about not enough registers. - */ -#if defined(MBEDTLS_PADLOCK_C) && \ - defined(__GNUC__) && defined(MBEDTLS_ARCH_IS_X86) && \ - defined(MBEDTLS_HAVE_ASM) && \ - !defined(MBEDTLS_HAVE_ASAN) - -#define MBEDTLS_VIA_PADLOCK_HAVE_CODE - -#include - -#define MBEDTLS_PADLOCK_RNG 0x000C -#define MBEDTLS_PADLOCK_ACE 0x00C0 -#define MBEDTLS_PADLOCK_PHE 0x0C00 -#define MBEDTLS_PADLOCK_PMM 0x3000 - -#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15)) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Internal PadLock detection routine - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param feature The feature to detect - * - * \return non-zero if CPU has support for the feature, 0 otherwise - */ -int mbedtls_padlock_has_support(int feature); - -/** - * \brief Internal PadLock AES-ECB block en(de)cryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 if success, 1 if operation failed - */ -int mbedtls_padlock_xcryptecb(mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16]); - -/** - * \brief Internal PadLock AES-CBC buffer en(de)cryption - * - * \note This function is only for internal use by other library - * functions; you must not call it directly. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if success, 1 if operation failed - */ -int mbedtls_padlock_xcryptcbc(mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output); - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_X86 */ - -#endif /* padlock.h */ diff --git a/vendor/mbedtls/library/pem.c b/vendor/mbedtls/library/pem.c deleted file mode 100644 index 119fd59e1..000000000 --- a/vendor/mbedtls/library/pem.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Privacy Enhanced Mail (PEM) decoding - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) - -#include "mbedtls/pem.h" -#include "mbedtls/base64.h" -#include "mbedtls/des.h" -#include "mbedtls/aes.h" -#include "mbedtls/md.h" -#include "mbedtls/cipher.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif - -#if defined(MBEDTLS_MD_CAN_MD5) && \ - defined(MBEDTLS_CIPHER_MODE_CBC) && \ - (defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)) -#define PEM_RFC1421 -#endif /* MBEDTLS_MD_CAN_MD5 && - MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ - -#if defined(MBEDTLS_PEM_PARSE_C) -void mbedtls_pem_init(mbedtls_pem_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_pem_context)); -} - -#if defined(PEM_RFC1421) -/* - * Read a 16-byte hex string and convert it to binary - */ -static int pem_get_iv(const unsigned char *s, unsigned char *iv, - size_t iv_len) -{ - size_t i, j, k; - - memset(iv, 0, iv_len); - - for (i = 0; i < iv_len * 2; i++, s++) { - if (*s >= '0' && *s <= '9') { - j = *s - '0'; - } else - if (*s >= 'A' && *s <= 'F') { - j = *s - '7'; - } else - if (*s >= 'a' && *s <= 'f') { - j = *s - 'W'; - } else { - return MBEDTLS_ERR_PEM_INVALID_ENC_IV; - } - - k = ((i & 1) != 0) ? j : j << 4; - - iv[i >> 1] = (unsigned char) (iv[i >> 1] | k); - } - - return 0; -} - -static int pem_pbkdf1(unsigned char *key, size_t keylen, - unsigned char *iv, - const unsigned char *pwd, size_t pwdlen) -{ - mbedtls_md_context_t md5_ctx; - const mbedtls_md_info_t *md5_info; - unsigned char md5sum[16]; - size_t use_len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_md_init(&md5_ctx); - - /* Prepare the context. (setup() errors gracefully on NULL info.) */ - md5_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); - if ((ret = mbedtls_md_setup(&md5_ctx, md5_info, 0)) != 0) { - goto exit; - } - - /* - * key[ 0..15] = MD5(pwd || IV) - */ - if ((ret = mbedtls_md_starts(&md5_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md5_ctx, pwd, pwdlen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md5_ctx, iv, 8)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_finish(&md5_ctx, md5sum)) != 0) { - goto exit; - } - - if (keylen <= 16) { - memcpy(key, md5sum, keylen); - goto exit; - } - - memcpy(key, md5sum, 16); - - /* - * key[16..23] = MD5(key[ 0..15] || pwd || IV]) - */ - if ((ret = mbedtls_md_starts(&md5_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md5_ctx, md5sum, 16)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md5_ctx, pwd, pwdlen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md5_ctx, iv, 8)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_finish(&md5_ctx, md5sum)) != 0) { - goto exit; - } - - use_len = 16; - if (keylen < 32) { - use_len = keylen - 16; - } - - memcpy(key + 16, md5sum, use_len); - -exit: - mbedtls_md_free(&md5_ctx); - mbedtls_platform_zeroize(md5sum, 16); - - return ret; -} - -#if defined(MBEDTLS_DES_C) -/* - * Decrypt with DES-CBC, using PBKDF1 for key derivation - */ -static int pem_des_decrypt(unsigned char des_iv[8], - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen) -{ - mbedtls_des_context des_ctx; - unsigned char des_key[8]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_des_init(&des_ctx); - - if ((ret = pem_pbkdf1(des_key, 8, des_iv, pwd, pwdlen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_des_setkey_dec(&des_ctx, des_key)) != 0) { - goto exit; - } - ret = mbedtls_des_crypt_cbc(&des_ctx, MBEDTLS_DES_DECRYPT, buflen, - des_iv, buf, buf); - -exit: - mbedtls_des_free(&des_ctx); - mbedtls_platform_zeroize(des_key, 8); - - return ret; -} - -/* - * Decrypt with 3DES-CBC, using PBKDF1 for key derivation - */ -static int pem_des3_decrypt(unsigned char des3_iv[8], - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen) -{ - mbedtls_des3_context des3_ctx; - unsigned char des3_key[24]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_des3_init(&des3_ctx); - - if ((ret = pem_pbkdf1(des3_key, 24, des3_iv, pwd, pwdlen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_des3_set3key_dec(&des3_ctx, des3_key)) != 0) { - goto exit; - } - ret = mbedtls_des3_crypt_cbc(&des3_ctx, MBEDTLS_DES_DECRYPT, buflen, - des3_iv, buf, buf); - -exit: - mbedtls_des3_free(&des3_ctx); - mbedtls_platform_zeroize(des3_key, 24); - - return ret; -} -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) -/* - * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation - */ -static int pem_aes_decrypt(unsigned char aes_iv[16], unsigned int keylen, - unsigned char *buf, size_t buflen, - const unsigned char *pwd, size_t pwdlen) -{ - mbedtls_aes_context aes_ctx; - unsigned char aes_key[32]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_aes_init(&aes_ctx); - - if ((ret = pem_pbkdf1(aes_key, keylen, aes_iv, pwd, pwdlen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_aes_setkey_dec(&aes_ctx, aes_key, keylen * 8)) != 0) { - goto exit; - } - ret = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, buflen, - aes_iv, buf, buf); - -exit: - mbedtls_aes_free(&aes_ctx); - mbedtls_platform_zeroize(aes_key, keylen); - - return ret; -} -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) -static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len) -{ - /* input_len > 0 is not guaranteed by mbedtls_pem_read_buffer(). */ - if (input_len < 1) { - return MBEDTLS_ERR_PEM_INVALID_DATA; - } - size_t pad_len = input[input_len - 1]; - size_t i; - - if (pad_len > input_len) { - return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH; - } - - *data_len = input_len - pad_len; - - for (i = *data_len; i < input_len; i++) { - if (input[i] != pad_len) { - return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH; - } - } - - return 0; -} -#endif /* MBEDTLS_DES_C || MBEDTLS_AES_C */ - -#endif /* PEM_RFC1421 */ - -int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer, - const unsigned char *data, const unsigned char *pwd, - size_t pwdlen, size_t *use_len) -{ - int ret, enc; - size_t len; - unsigned char *buf; - const unsigned char *s1, *s2, *end; -#if defined(PEM_RFC1421) - unsigned char pem_iv[16]; - mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE; -#else - ((void) pwd); - ((void) pwdlen); -#endif /* PEM_RFC1421 */ - - if (ctx == NULL) { - return MBEDTLS_ERR_PEM_BAD_INPUT_DATA; - } - - s1 = (unsigned char *) strstr((const char *) data, header); - - if (s1 == NULL) { - return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } - - s2 = (unsigned char *) strstr((const char *) data, footer); - - if (s2 == NULL || s2 <= s1) { - return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } - - s1 += strlen(header); - if (*s1 == ' ') { - s1++; - } - if (*s1 == '\r') { - s1++; - } - if (*s1 == '\n') { - s1++; - } else { - return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } - - end = s2; - end += strlen(footer); - if (*end == ' ') { - end++; - } - if (*end == '\r') { - end++; - } - if (*end == '\n') { - end++; - } - *use_len = (size_t) (end - data); - - enc = 0; - - if (s2 - s1 >= 22 && memcmp(s1, "Proc-Type: 4,ENCRYPTED", 22) == 0) { -#if defined(PEM_RFC1421) - enc++; - - s1 += 22; - if (*s1 == '\r') { - s1++; - } - if (*s1 == '\n') { - s1++; - } else { - return MBEDTLS_ERR_PEM_INVALID_DATA; - } - - -#if defined(MBEDTLS_DES_C) - if (s2 - s1 >= 23 && memcmp(s1, "DEK-Info: DES-EDE3-CBC,", 23) == 0) { - enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; - - s1 += 23; - if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0) { - return MBEDTLS_ERR_PEM_INVALID_ENC_IV; - } - - s1 += 16; - } else if (s2 - s1 >= 18 && memcmp(s1, "DEK-Info: DES-CBC,", 18) == 0) { - enc_alg = MBEDTLS_CIPHER_DES_CBC; - - s1 += 18; - if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0) { - return MBEDTLS_ERR_PEM_INVALID_ENC_IV; - } - - s1 += 16; - } -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if (s2 - s1 >= 14 && memcmp(s1, "DEK-Info: AES-", 14) == 0) { - if (s2 - s1 < 22) { - return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG; - } else if (memcmp(s1, "DEK-Info: AES-128-CBC,", 22) == 0) { - enc_alg = MBEDTLS_CIPHER_AES_128_CBC; - } else if (memcmp(s1, "DEK-Info: AES-192-CBC,", 22) == 0) { - enc_alg = MBEDTLS_CIPHER_AES_192_CBC; - } else if (memcmp(s1, "DEK-Info: AES-256-CBC,", 22) == 0) { - enc_alg = MBEDTLS_CIPHER_AES_256_CBC; - } else { - return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG; - } - - s1 += 22; - if (s2 - s1 < 32 || pem_get_iv(s1, pem_iv, 16) != 0) { - return MBEDTLS_ERR_PEM_INVALID_ENC_IV; - } - - s1 += 32; - } -#endif /* MBEDTLS_AES_C */ - - if (enc_alg == MBEDTLS_CIPHER_NONE) { - return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG; - } - - if (*s1 == '\r') { - s1++; - } - if (*s1 == '\n') { - s1++; - } else { - return MBEDTLS_ERR_PEM_INVALID_DATA; - } -#else - return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE; -#endif /* PEM_RFC1421 */ - } - - if (s1 >= s2) { - return MBEDTLS_ERR_PEM_INVALID_DATA; - } - - ret = mbedtls_base64_decode(NULL, 0, &len, s1, (size_t) (s2 - s1)); - - if (ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret); - } - - if (len == 0) { - return MBEDTLS_ERR_PEM_BAD_INPUT_DATA; - } - - if ((buf = mbedtls_calloc(1, len)) == NULL) { - return MBEDTLS_ERR_PEM_ALLOC_FAILED; - } - - if ((ret = mbedtls_base64_decode(buf, len, &len, s1, (size_t) (s2 - s1))) != 0) { - mbedtls_zeroize_and_free(buf, len); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret); - } - - if (enc != 0) { -#if defined(PEM_RFC1421) - if (pwd == NULL) { - mbedtls_zeroize_and_free(buf, len); - return MBEDTLS_ERR_PEM_PASSWORD_REQUIRED; - } - - ret = 0; - -#if defined(MBEDTLS_DES_C) - if (enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC) { - ret = pem_des3_decrypt(pem_iv, buf, len, pwd, pwdlen); - } else if (enc_alg == MBEDTLS_CIPHER_DES_CBC) { - ret = pem_des_decrypt(pem_iv, buf, len, pwd, pwdlen); - } -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_AES_C) - if (enc_alg == MBEDTLS_CIPHER_AES_128_CBC) { - ret = pem_aes_decrypt(pem_iv, 16, buf, len, pwd, pwdlen); - } else if (enc_alg == MBEDTLS_CIPHER_AES_192_CBC) { - ret = pem_aes_decrypt(pem_iv, 24, buf, len, pwd, pwdlen); - } else if (enc_alg == MBEDTLS_CIPHER_AES_256_CBC) { - ret = pem_aes_decrypt(pem_iv, 32, buf, len, pwd, pwdlen); - } -#endif /* MBEDTLS_AES_C */ - - if (ret != 0) { - mbedtls_zeroize_and_free(buf, len); - return ret; - } - - /* Check PKCS padding and update data length based on padding info. - * This can be used to detect invalid padding data and password - * mismatches. */ - size_t unpadded_len; - ret = pem_check_pkcs_padding(buf, len, &unpadded_len); - if (ret != 0) { - mbedtls_zeroize_and_free(buf, len); - return ret; - } - len = unpadded_len; -#else - mbedtls_zeroize_and_free(buf, len); - return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE; -#endif /* PEM_RFC1421 */ - } - - ctx->buf = buf; - ctx->buflen = len; - - return 0; -} - -void mbedtls_pem_free(mbedtls_pem_context *ctx) -{ - if (ctx == NULL) { - return; - } - - if (ctx->buf != NULL) { - mbedtls_zeroize_and_free(ctx->buf, ctx->buflen); - } - mbedtls_free(ctx->info); - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pem_context)); -} -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_pem_write_buffer(const char *header, const char *footer, - const unsigned char *der_data, size_t der_len, - unsigned char *buf, size_t buf_len, size_t *olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *encode_buf = NULL, *c, *p = buf; - size_t len = 0, use_len, add_len = 0; - - mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len); - add_len = strlen(header) + strlen(footer) + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; - - if (use_len + add_len > buf_len) { - *olen = use_len + add_len; - return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; - } - - if (use_len != 0 && - ((encode_buf = mbedtls_calloc(1, use_len)) == NULL)) { - return MBEDTLS_ERR_PEM_ALLOC_FAILED; - } - - if ((ret = mbedtls_base64_encode(encode_buf, use_len, &use_len, der_data, - der_len)) != 0) { - mbedtls_free(encode_buf); - return ret; - } - - memcpy(p, header, strlen(header)); - p += strlen(header); - c = encode_buf; - - while (use_len) { - len = (use_len > 64) ? 64 : use_len; - memcpy(p, c, len); - use_len -= len; - p += len; - c += len; - *p++ = '\n'; - } - - memcpy(p, footer, strlen(footer)); - p += strlen(footer); - - *p++ = '\0'; - *olen = (size_t) (p - buf); - - /* Clean any remaining data previously written to the buffer */ - memset(buf + *olen, 0, buf_len - *olen); - - mbedtls_free(encode_buf); - return 0; -} -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ diff --git a/vendor/mbedtls/library/pk.c b/vendor/mbedtls/library/pk.c deleted file mode 100644 index b5d76dbd9..000000000 --- a/vendor/mbedtls/library/pk.c +++ /dev/null @@ -1,1602 +0,0 @@ -/* - * Public Key abstraction layer - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk.h" -#include "pk_wrap.h" -#include "pkwrite.h" -#include "pk_internal.h" - -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#include "rsa_internal.h" -#endif -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#include "mbedtls/ecp.h" -#endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#include "psa_util_internal.h" -#include "mbedtls/psa_util.h" -#endif - -#include -#include - -#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) -#include "mbedtls/platform.h" // for calloc/free -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#define MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) - -#define MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN \ - PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) - -#define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN 0 -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && \ - MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN > MBEDTLS_PK_MAX_PUBKEY_RAW_LEN -#undef MBEDTLS_PK_MAX_PUBKEY_RAW_LEN -#define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN -#endif -#if (defined(MBEDTLS_RSA_C) || \ - (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))) && \ - MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN > MBEDTLS_PK_MAX_PUBKEY_RAW_LEN -#undef MBEDTLS_PK_MAX_PUBKEY_RAW_LEN -#define MBEDTLS_PK_MAX_PUBKEY_RAW_LEN MBEDTLS_PK_MAX_RSA_PUBKEY_RAW_LEN -#endif -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ - -/* - * Initialise a mbedtls_pk_context - */ -void mbedtls_pk_init(mbedtls_pk_context *ctx) -{ - ctx->pk_info = NULL; - ctx->pk_ctx = NULL; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); - ctx->pub_raw_len = 0; - ctx->ec_family = 0; - ctx->ec_bits = 0; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -/* - * Free (the components of) a mbedtls_pk_context - */ -void mbedtls_pk_free(mbedtls_pk_context *ctx) -{ - if (ctx == NULL) { - return; - } - - if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) { - ctx->pk_info->ctx_free_func(ctx->pk_ctx); - } - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - /* The ownership of the priv_id key for opaque keys is external of the PK - * module. It's the user responsibility to clear it after use. */ - if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) { - psa_destroy_key(ctx->priv_id); - } -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context)); -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_pk_restart_init(mbedtls_pk_restart_ctx *ctx) -{ - ctx->pk_info = NULL; - ctx->rs_ctx = NULL; -} - -/* - * Free the components of a restart context - */ -void mbedtls_pk_restart_free(mbedtls_pk_restart_ctx *ctx) -{ - if (ctx == NULL || ctx->pk_info == NULL || - ctx->pk_info->rs_free_func == NULL) { - return; - } - - ctx->pk_info->rs_free_func(ctx->rs_ctx); - - ctx->pk_info = NULL; - ctx->rs_ctx = NULL; -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* - * Get pk_info structure from type - */ -const mbedtls_pk_info_t *mbedtls_pk_info_from_type(mbedtls_pk_type_t pk_type) -{ - switch (pk_type) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_PK_RSA: - return &mbedtls_rsa_info; -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - case MBEDTLS_PK_ECKEY: - return &mbedtls_eckey_info; - case MBEDTLS_PK_ECKEY_DH: - return &mbedtls_eckeydh_info; -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ -#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) - case MBEDTLS_PK_ECDSA: - return &mbedtls_ecdsa_info; -#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ - /* MBEDTLS_PK_RSA_ALT omitted on purpose */ - default: - return NULL; - } -} - -/* - * Initialise context - */ -int mbedtls_pk_setup(mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info) -{ - if (info == NULL || ctx->pk_info != NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if ((info->ctx_alloc_func != NULL) && - ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - - ctx->pk_info = info; - - return 0; -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* - * Initialise a PSA-wrapping context - */ -int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, - const mbedtls_svc_key_id_t key) -{ - const mbedtls_pk_info_t *info = NULL; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t type; - - if (ctx == NULL || ctx->pk_info != NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (PSA_SUCCESS != psa_get_key_attributes(key, &attributes)) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - type = psa_get_key_type(&attributes); - psa_reset_key_attributes(&attributes); - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { - info = &mbedtls_ecdsa_opaque_info; - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - info = &mbedtls_rsa_opaque_info; - } else { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } - - ctx->pk_info = info; - ctx->priv_id = key; - - return 0; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* - * Initialize an RSA-alt context - */ -int mbedtls_pk_setup_rsa_alt(mbedtls_pk_context *ctx, void *key, - mbedtls_pk_rsa_alt_decrypt_func decrypt_func, - mbedtls_pk_rsa_alt_sign_func sign_func, - mbedtls_pk_rsa_alt_key_len_func key_len_func) -{ - mbedtls_rsa_alt_context *rsa_alt; - const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; - - if (ctx->pk_info != NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - - ctx->pk_info = info; - - rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; - - rsa_alt->key = key; - rsa_alt->decrypt_func = decrypt_func; - rsa_alt->sign_func = sign_func; - rsa_alt->key_len_func = key_len_func; - - return 0; -} -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -/* - * Tell if a PK can do the operations of the given type - */ -int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type) -{ - /* A context with null pk_info is not set up yet and can't do anything. - * For backward compatibility, also accept NULL instead of a context - * pointer. */ - if (ctx == NULL || ctx->pk_info == NULL) { - return 0; - } - - return ctx->pk_info->can_do(type); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* - * Tell if a PK can do the operations of the given PSA algorithm - */ -int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, - psa_key_usage_t usage) -{ - psa_key_usage_t key_usage; - - /* A context with null pk_info is not set up yet and can't do anything. - * For backward compatibility, also accept NULL instead of a context - * pointer. */ - if (ctx == NULL || ctx->pk_info == NULL) { - return 0; - } - - /* Filter out non allowed algorithms */ - if (PSA_ALG_IS_ECDSA(alg) == 0 && - PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) == 0 && - PSA_ALG_IS_RSA_PSS(alg) == 0 && - alg != PSA_ALG_RSA_PKCS1V15_CRYPT && - PSA_ALG_IS_ECDH(alg) == 0) { - return 0; - } - - /* Filter out non allowed usage flags */ - if (usage == 0 || - (usage & ~(PSA_KEY_USAGE_SIGN_HASH | - PSA_KEY_USAGE_DECRYPT | - PSA_KEY_USAGE_DERIVE)) != 0) { - return 0; - } - - /* Wildcard hash is not allowed */ - if (PSA_ALG_IS_SIGN_HASH(alg) && - PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH) { - return 0; - } - - if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_OPAQUE) { - mbedtls_pk_type_t type; - - if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_ECDH(alg)) { - type = MBEDTLS_PK_ECKEY; - } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || - alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { - type = MBEDTLS_PK_RSA; - } else if (PSA_ALG_IS_RSA_PSS(alg)) { - type = MBEDTLS_PK_RSASSA_PSS; - } else { - return 0; - } - - if (ctx->pk_info->can_do(type) == 0) { - return 0; - } - - switch (type) { - case MBEDTLS_PK_ECKEY: - key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_DERIVE; - break; - case MBEDTLS_PK_RSA: - case MBEDTLS_PK_RSASSA_PSS: - key_usage = PSA_KEY_USAGE_SIGN_HASH | - PSA_KEY_USAGE_SIGN_MESSAGE | - PSA_KEY_USAGE_DECRYPT; - break; - default: - /* Should never happen */ - return 0; - } - - return (key_usage & usage) == usage; - } - - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; - - status = psa_get_key_attributes(ctx->priv_id, &attributes); - if (status != PSA_SUCCESS) { - return 0; - } - - psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes); - /* Key's enrollment is available only when an Mbed TLS implementation of PSA - * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. - * Even though we don't officially support using other implementations of PSA - * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations - * separated. */ -#if defined(MBEDTLS_PSA_CRYPTO_C) - psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes); -#endif /* MBEDTLS_PSA_CRYPTO_C */ - key_usage = psa_get_key_usage_flags(&attributes); - psa_reset_key_attributes(&attributes); - - if ((key_usage & usage) != usage) { - return 0; - } - - /* - * Common case: the key alg [or alg2] only allows alg. - * This will match PSA_ALG_RSA_PKCS1V15_CRYPT & PSA_ALG_IS_ECDH - * directly. - * This would also match ECDSA/RSA_PKCS1V15_SIGN/RSA_PSS with - * a fixed hash on key_alg [or key_alg2]. - */ - if (alg == key_alg) { - return 1; - } -#if defined(MBEDTLS_PSA_CRYPTO_C) - if (alg == key_alg2) { - return 1; - } -#endif /* MBEDTLS_PSA_CRYPTO_C */ - - /* - * If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash, - * and alg is the same hash-and-sign family with any hash, - * then alg is compliant with this key alg - */ - if (PSA_ALG_IS_SIGN_HASH(alg)) { - if (PSA_ALG_IS_SIGN_HASH(key_alg) && - PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH && - (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) { - return 1; - } -#if defined(MBEDTLS_PSA_CRYPTO_C) - if (PSA_ALG_IS_SIGN_HASH(key_alg2) && - PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH && - (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) { - return 1; - } -#endif /* MBEDTLS_PSA_CRYPTO_C */ - } - - return 0; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#if defined(MBEDTLS_RSA_C) -static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa, - int want_crypt) -{ - if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { - if (want_crypt) { - mbedtls_md_type_t md_type = (mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa); - return PSA_ALG_RSA_OAEP(mbedtls_md_psa_alg_from_type(md_type)); - } else { - return PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH); - } - } else { - if (want_crypt) { - return PSA_ALG_RSA_PKCS1V15_CRYPT; - } else { - return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH); - } - } -} -#endif /* MBEDTLS_RSA_C */ - -int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, - psa_key_usage_t usage, - psa_key_attributes_t *attributes) -{ - mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk); - - psa_key_usage_t more_usage = usage; - if (usage == PSA_KEY_USAGE_SIGN_MESSAGE) { - more_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE; - } else if (usage == PSA_KEY_USAGE_SIGN_HASH) { - more_usage |= PSA_KEY_USAGE_VERIFY_HASH; - } else if (usage == PSA_KEY_USAGE_DECRYPT) { - more_usage |= PSA_KEY_USAGE_ENCRYPT; - } - more_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; - - int want_private = !(usage == PSA_KEY_USAGE_VERIFY_MESSAGE || - usage == PSA_KEY_USAGE_VERIFY_HASH || - usage == PSA_KEY_USAGE_ENCRYPT); - - switch (pk_type) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_PK_RSA: - { - int want_crypt = 0; /* 0: sign/verify; 1: encrypt/decrypt */ - switch (usage) { - case PSA_KEY_USAGE_SIGN_MESSAGE: - case PSA_KEY_USAGE_SIGN_HASH: - case PSA_KEY_USAGE_VERIFY_MESSAGE: - case PSA_KEY_USAGE_VERIFY_HASH: - /* Nothing to do. */ - break; - case PSA_KEY_USAGE_DECRYPT: - case PSA_KEY_USAGE_ENCRYPT: - want_crypt = 1; - break; - default: - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - /* Detect the presence of a private key in a way that works both - * in CRT and non-CRT configurations. */ - mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk); - int has_private = (mbedtls_rsa_check_privkey(rsa) == 0); - if (want_private && !has_private) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - psa_set_key_type(attributes, (want_private ? - PSA_KEY_TYPE_RSA_KEY_PAIR : - PSA_KEY_TYPE_RSA_PUBLIC_KEY)); - psa_set_key_bits(attributes, mbedtls_pk_get_bitlen(pk)); - psa_set_key_algorithm(attributes, - psa_algorithm_for_rsa(rsa, want_crypt)); - break; - } -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: - { - int sign_ok = (pk_type != MBEDTLS_PK_ECKEY_DH); - int derive_ok = (pk_type != MBEDTLS_PK_ECDSA); -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - psa_ecc_family_t family = pk->ec_family; - size_t bits = pk->ec_bits; - int has_private = 0; - if (pk->priv_id != MBEDTLS_SVC_KEY_ID_INIT) { - has_private = 1; - } -#else - const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); - int has_private = (ec->d.n != 0); - size_t bits = 0; - psa_ecc_family_t family = - mbedtls_ecc_group_to_psa(ec->grp.id, &bits); -#endif - psa_algorithm_t alg = 0; - switch (usage) { - case PSA_KEY_USAGE_SIGN_MESSAGE: - case PSA_KEY_USAGE_SIGN_HASH: - case PSA_KEY_USAGE_VERIFY_MESSAGE: - case PSA_KEY_USAGE_VERIFY_HASH: - if (!sign_ok) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH); -#else - alg = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH); -#endif - break; - case PSA_KEY_USAGE_DERIVE: - alg = PSA_ALG_ECDH; - if (!derive_ok) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - break; - default: - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - if (want_private && !has_private) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - psa_set_key_type(attributes, (want_private ? - PSA_KEY_TYPE_ECC_KEY_PAIR(family) : - PSA_KEY_TYPE_ECC_PUBLIC_KEY(family))); - psa_set_key_bits(attributes, bits); - psa_set_key_algorithm(attributes, alg); - break; - } -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) - case MBEDTLS_PK_RSA_ALT: - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - case MBEDTLS_PK_OPAQUE: - { - psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - status = psa_get_key_attributes(pk->priv_id, &old_attributes); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - psa_key_type_t old_type = psa_get_key_type(&old_attributes); - switch (usage) { - case PSA_KEY_USAGE_SIGN_MESSAGE: - case PSA_KEY_USAGE_SIGN_HASH: - case PSA_KEY_USAGE_VERIFY_MESSAGE: - case PSA_KEY_USAGE_VERIFY_HASH: - if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type) || - old_type == PSA_KEY_TYPE_RSA_KEY_PAIR)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - break; - case PSA_KEY_USAGE_DECRYPT: - case PSA_KEY_USAGE_ENCRYPT: - if (old_type != PSA_KEY_TYPE_RSA_KEY_PAIR) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - break; - case PSA_KEY_USAGE_DERIVE: - if (!(PSA_KEY_TYPE_IS_ECC_KEY_PAIR(old_type))) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - break; - default: - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - psa_key_type_t new_type = old_type; - /* Opaque keys are always key pairs, so we don't need a check - * on the input if the required usage is private. We just need - * to adjust the type correctly if the required usage is public. */ - if (!want_private) { - new_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(new_type); - } - more_usage = psa_get_key_usage_flags(&old_attributes); - if ((usage & more_usage) == 0) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - psa_set_key_type(attributes, new_type); - psa_set_key_bits(attributes, psa_get_key_bits(&old_attributes)); - psa_set_key_algorithm(attributes, psa_get_key_algorithm(&old_attributes)); - break; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - default: - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - psa_set_key_usage_flags(attributes, more_usage); - /* Key's enrollment is available only when an Mbed TLS implementation of PSA - * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. - * Even though we don't officially support using other implementations of PSA - * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations - * separated. */ -#if defined(MBEDTLS_PSA_CRYPTO_C) - psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE); -#endif - - return 0; -} - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO) -static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id, - psa_key_type_t old_type, size_t old_bits, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *new_key_id) -{ -#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) - unsigned char *key_buffer = NULL; - size_t key_buffer_size = 0; -#else - unsigned char key_buffer[PK_EXPORT_KEY_STACK_BUFFER_SIZE]; - const size_t key_buffer_size = sizeof(key_buffer); -#endif - size_t key_length = 0; - - /* We are exporting from a PK object, so we know key type is valid for PK */ -#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) - key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(old_type, old_bits); - key_buffer = mbedtls_calloc(1, key_buffer_size); - if (key_buffer == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } -#else - (void) old_type; - (void) old_bits; -#endif - - psa_status_t status = psa_export_key(old_key_id, - key_buffer, key_buffer_size, - &key_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_import_key(attributes, key_buffer, key_length, new_key_id); - mbedtls_platform_zeroize(key_buffer, key_length); - -cleanup: -#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) - mbedtls_free(key_buffer); -#endif - return status; -} - -static int copy_into_psa(mbedtls_svc_key_id_t old_key_id, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *new_key_id) -{ - /* Normally, we prefer copying: it's more efficient and works even - * for non-exportable keys. */ - psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id); - if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ || - status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) { - /* There are edge cases where copying won't work, but export+import - * might: - * - If the old key does not allow PSA_KEY_USAGE_COPY. - * - If the old key's usage does not allow what attributes wants. - * Because the key was intended for use in the pk module, and may - * have had a policy chosen solely for what pk needs rather than - * based on a detailed understanding of PSA policies, we are a bit - * more liberal than psa_copy_key() here. - */ - /* Here we need to check that the types match, otherwise we risk - * importing nonsensical data. */ - psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; - status = psa_get_key_attributes(old_key_id, &old_attributes); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - psa_key_type_t old_type = psa_get_key_type(&old_attributes); - size_t old_bits = psa_get_key_bits(&old_attributes); - psa_reset_key_attributes(&old_attributes); - if (old_type != psa_get_key_type(attributes)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - status = export_import_into_psa(old_key_id, old_type, old_bits, - attributes, new_key_id); - } - return PSA_PK_TO_MBEDTLS_ERR(status); -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */ - -static int import_pair_into_psa(const mbedtls_pk_context *pk, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key_id) -{ - switch (mbedtls_pk_get_type(pk)) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_PK_RSA: - { - if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - size_t key_bits = psa_get_key_bits(attributes); - size_t key_buffer_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits); - unsigned char *key_buffer = mbedtls_calloc(1, key_buffer_size); - if (key_buffer == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - unsigned char *const key_end = key_buffer + key_buffer_size; - unsigned char *key_data = key_end; - int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), - key_buffer, &key_data); - if (ret < 0) { - goto cleanup_rsa; - } - size_t key_length = key_end - key_data; - ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, - key_data, key_length, - key_id)); -cleanup_rsa: - mbedtls_zeroize_and_free(key_buffer, key_buffer_size); - return ret; - } -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: - { - /* We need to check the curve family, otherwise the import could - * succeed with nonsensical data. - * We don't check the bit-size: it's optional in attributes, - * and if it's specified, psa_import_key() will know from the key - * data length and will check that the bit-size matches. */ - psa_key_type_t to_type = psa_get_key_type(attributes); -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - psa_ecc_family_t from_family = pk->ec_family; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); - size_t from_bits = 0; - psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, - &from_bits); -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - if (mbedtls_svc_key_id_is_null(pk->priv_id)) { - /* We have a public key and want a key pair. */ - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - return copy_into_psa(pk->priv_id, attributes, key_id); -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - if (ec->d.n == 0) { - /* Private key not set. Assume the input is a public key only. - * (The other possibility is that it's an incomplete object - * where the group is set but neither the public key nor - * the private key. This is not possible through ecp.h - * functions, so we don't bother reporting a more suitable - * error in that case.) */ - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - size_t key_length = 0; - int ret = mbedtls_ecp_write_key_ext(ec, &key_length, - key_buffer, sizeof(key_buffer)); - if (ret < 0) { - return ret; - } - ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, - key_buffer, key_length, - key_id)); - mbedtls_platform_zeroize(key_buffer, key_length); - return ret; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - } -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - case MBEDTLS_PK_OPAQUE: - return copy_into_psa(pk->priv_id, attributes, key_id); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - default: - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } -} - -static int import_public_into_psa(const mbedtls_pk_context *pk, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key_id) -{ - psa_key_type_t psa_type = psa_get_key_type(attributes); - -#if defined(MBEDTLS_RSA_C) || \ - (defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \ - defined(MBEDTLS_USE_PSA_CRYPTO) - unsigned char key_buffer[MBEDTLS_PK_MAX_PUBKEY_RAW_LEN]; -#endif - unsigned char *key_data = NULL; - size_t key_length = 0; - - switch (mbedtls_pk_get_type(pk)) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_PK_RSA: - { - if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - unsigned char *const key_end = key_buffer + sizeof(key_buffer); - key_data = key_end; - int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk), - key_buffer, &key_data); - if (ret < 0) { - return ret; - } - key_length = (size_t) ret; - break; - } -#endif /*MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: - { - /* We need to check the curve family, otherwise the import could - * succeed with nonsensical data. - * We don't check the bit-size: it's optional in attributes, - * and if it's specified, psa_import_key() will know from the key - * data length and will check that the bit-size matches. */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - key_data = (unsigned char *) pk->pub_raw; - key_length = pk->pub_raw_len; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); - size_t from_bits = 0; - psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, - &from_bits); - if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - int ret = mbedtls_ecp_write_public_key( - ec, MBEDTLS_ECP_PF_UNCOMPRESSED, - &key_length, key_buffer, sizeof(key_buffer)); - if (ret < 0) { - return ret; - } - key_data = key_buffer; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - break; - } -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - case MBEDTLS_PK_OPAQUE: - { - psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = - psa_get_key_attributes(pk->priv_id, &old_attributes); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - psa_key_type_t old_type = psa_get_key_type(&old_attributes); - psa_reset_key_attributes(&old_attributes); - if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - status = psa_export_public_key(pk->priv_id, - key_buffer, sizeof(key_buffer), - &key_length); - if (status != PSA_SUCCESS) { - return PSA_PK_TO_MBEDTLS_ERR(status); - } - key_data = key_buffer; - break; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - default: - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes, - key_data, key_length, - key_id)); -} - -int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key_id) -{ - /* Set the output immediately so that it won't contain garbage even - * if we error out before calling psa_import_key(). */ - *key_id = MBEDTLS_SVC_KEY_ID_INIT; - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - - int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes)); - if (want_public) { - return import_public_into_psa(pk, attributes, key_id); - } else { - return import_pair_into_psa(pk, attributes, key_id); - } -} - -static int is_valid_for_pk(psa_key_type_t key_type) -{ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (PSA_KEY_TYPE_IS_ECC(key_type)) { - return 1; - } -#endif -#if defined(MBEDTLS_RSA_C) - if (PSA_KEY_TYPE_IS_RSA(key_type)) { - return 1; - } -#endif - return 0; -} - -static int copy_from_psa(mbedtls_svc_key_id_t key_id, - mbedtls_pk_context *pk, - int public_only) -{ - psa_status_t status; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t key_type; - size_t key_bits; -#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) - unsigned char *exp_key = NULL; - size_t exp_key_size = 0; -#else - unsigned char exp_key[PK_EXPORT_KEY_STACK_BUFFER_SIZE]; - const size_t exp_key_size = sizeof(exp_key); -#endif - size_t exp_key_len; - int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - - if (pk == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - status = psa_get_key_attributes(key_id, &key_attr); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - key_type = psa_get_key_type(&key_attr); - if (!is_valid_for_pk(key_type)) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (public_only) { - key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); - } - key_bits = psa_get_key_bits(&key_attr); - -#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) - exp_key_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); - exp_key = mbedtls_calloc(1, exp_key_size); - if (exp_key == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } -#endif - - if (public_only) { - status = psa_export_public_key(key_id, exp_key, exp_key_size, &exp_key_len); - } else { - status = psa_export_key(key_id, exp_key, exp_key_size, &exp_key_len); - } - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto exit; - } - - key_type = psa_get_key_type(&key_attr); - if (public_only) { - key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); - } - key_bits = psa_get_key_bits(&key_attr); - -#if defined(MBEDTLS_RSA_C) - if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || - (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { - - ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); - if (ret != 0) { - goto exit; - } - - if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); - } else { - ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); - } - if (ret != 0) { - goto exit; - } - - psa_algorithm_t alg_type = psa_get_key_algorithm(&key_attr); - mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; - if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { - md_type = mbedtls_md_type_from_psa_alg(alg_type); - } - - if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { - ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); - } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || - alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { - ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); - } - if (ret != 0) { - goto exit; - } - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || - PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { - mbedtls_ecp_group_id grp_id; - - ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); - if (ret != 0) { - goto exit; - } - - grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); - ret = mbedtls_pk_ecc_set_group(pk, grp_id); - if (ret != 0) { - goto exit; - } - - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { - ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); - if (ret != 0) { - goto exit; - } - ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE); - } else { - ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); - } - if (ret != 0) { - goto exit; - } - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - { - (void) key_bits; - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - goto exit; - } - -exit: - mbedtls_platform_zeroize(exp_key, exp_key_size); -#if !defined(PK_EXPORT_KEYS_ON_THE_STACK) - mbedtls_free(exp_key); -#endif - psa_reset_key_attributes(&key_attr); - - return ret; -} - -int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, - mbedtls_pk_context *pk) -{ - return copy_from_psa(key_id, pk, 0); -} - -int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, - mbedtls_pk_context *pk) -{ - return copy_from_psa(key_id, pk, 1); -} -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ - -/* - * Helper for mbedtls_pk_sign and mbedtls_pk_verify - */ -static inline int pk_hashlen_helper(mbedtls_md_type_t md_alg, size_t *hash_len) -{ - if (*hash_len != 0) { - return 0; - } - - *hash_len = mbedtls_md_get_size_from_type(md_alg); - - if (*hash_len == 0) { - return -1; - } - - return 0; -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Helper to set up a restart context if needed - */ -static int pk_restart_setup(mbedtls_pk_restart_ctx *ctx, - const mbedtls_pk_info_t *info) -{ - /* Don't do anything if already set up or invalid */ - if (ctx == NULL || ctx->pk_info != NULL) { - return 0; - } - - /* Should never happen when we're called */ - if (info->rs_alloc_func == NULL || info->rs_free_func == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if ((ctx->rs_ctx = info->rs_alloc_func()) == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - - ctx->pk_info = info; - - return 0; -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* - * Verify a signature (restartable) - */ -int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - mbedtls_pk_restart_ctx *rs_ctx) -{ - if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (ctx->pk_info == NULL || - pk_hashlen_helper(md_alg, &hash_len) != 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if (rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->verify_rs_func != NULL) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { - return ret; - } - - ret = ctx->pk_info->verify_rs_func(ctx, - md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx); - - if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { - mbedtls_pk_restart_free(rs_ctx); - } - - return ret; - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - if (ctx->pk_info->verify_func == NULL) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - - return ctx->pk_info->verify_func(ctx, md_alg, hash, hash_len, - sig, sig_len); -} - -/* - * Verify a signature - */ -int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - return mbedtls_pk_verify_restartable(ctx, md_alg, hash, hash_len, - sig, sig_len, NULL); -} - -/* - * Verify a signature with options - */ -int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, - mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (ctx->pk_info == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (!mbedtls_pk_can_do(ctx, type)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - - if (type != MBEDTLS_PK_RSASSA_PSS) { - /* General case: no options */ - if (options != NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len); - } - - /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa() - * below would return a NULL pointer. */ - if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } - -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_pk_rsassa_pss_options *pss_opts; - -#if SIZE_MAX > UINT_MAX - if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } -#endif - - if (options == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (pss_opts->mgf1_hash_id == md_alg) { - unsigned char buf[PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; - unsigned char *p; - int key_len; - size_t signature_length; - psa_status_t status = PSA_ERROR_DATA_CORRUPT; - psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT; - - psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg); - p = buf + sizeof(buf); - key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p); - - if (key_len < 0) { - return key_len; - } - - psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); - psa_set_key_algorithm(&attributes, psa_sig_alg); - - status = psa_import_key(&attributes, - buf + sizeof(buf) - key_len, key_len, - &key_id); - if (status != PSA_SUCCESS) { - psa_destroy_key(key_id); - return PSA_PK_TO_MBEDTLS_ERR(status); - } - - /* This function requires returning MBEDTLS_ERR_PK_SIG_LEN_MISMATCH - * on a valid signature with trailing data in a buffer, but - * mbedtls_psa_rsa_verify_hash requires the sig_len to be exact, - * so for this reason the passed sig_len is overwritten. Smaller - * signature lengths should not be accepted for verification. */ - signature_length = sig_len > mbedtls_pk_get_len(ctx) ? - mbedtls_pk_get_len(ctx) : sig_len; - status = psa_verify_hash(key_id, psa_sig_alg, hash, - hash_len, sig, signature_length); - destruction_status = psa_destroy_key(key_id); - - if (status == PSA_SUCCESS && sig_len > mbedtls_pk_get_len(ctx)) { - return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; - } - - if (status == PSA_SUCCESS) { - status = destruction_status; - } - - return PSA_PK_RSA_TO_MBEDTLS_ERR(status); - } else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - { - if (sig_len < mbedtls_pk_get_len(ctx)) { - return MBEDTLS_ERR_RSA_VERIFY_FAILED; - } - - ret = mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_pk_rsa(*ctx), - md_alg, (unsigned int) hash_len, hash, - pss_opts->mgf1_hash_id, - pss_opts->expected_salt_len, - sig); - if (ret != 0) { - return ret; - } - - if (sig_len > mbedtls_pk_get_len(ctx)) { - return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; - } - - return 0; - } -#else - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; -#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ -} - -/* - * Make a signature (restartable) - */ -int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_pk_restart_ctx *rs_ctx) -{ - if ((md_alg != MBEDTLS_MD_NONE || hash_len != 0) && hash == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (ctx->pk_info == NULL || pk_hashlen_helper(md_alg, &hash_len) != 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* optimization: use non-restartable version if restart disabled */ - if (rs_ctx != NULL && - mbedtls_ecp_restart_is_enabled() && - ctx->pk_info->sign_rs_func != NULL) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = pk_restart_setup(rs_ctx, ctx->pk_info)) != 0) { - return ret; - } - - ret = ctx->pk_info->sign_rs_func(ctx, md_alg, - hash, hash_len, - sig, sig_size, sig_len, - f_rng, p_rng, rs_ctx->rs_ctx); - - if (ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { - mbedtls_pk_restart_free(rs_ctx); - } - - return ret; - } -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - (void) rs_ctx; -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - if (ctx->pk_info->sign_func == NULL) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - - return ctx->pk_info->sign_func(ctx, md_alg, - hash, hash_len, - sig, sig_size, sig_len, - f_rng, p_rng); -} - -/* - * Make a signature - */ -int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - return mbedtls_pk_sign_restartable(ctx, md_alg, hash, hash_len, - sig, sig_size, sig_len, - f_rng, p_rng, NULL); -} - -/* - * Make a signature given a signature type. - */ -int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, - mbedtls_pk_context *ctx, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - if (ctx->pk_info == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (!mbedtls_pk_can_do(ctx, pk_type)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - - if (pk_type != MBEDTLS_PK_RSASSA_PSS) { - return mbedtls_pk_sign(ctx, md_alg, hash, hash_len, - sig, sig_size, sig_len, f_rng, p_rng); - } - -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - const psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); - if (psa_md_alg == 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) { - psa_status_t status; - - /* PSA_ALG_RSA_PSS() behaves the same as PSA_ALG_RSA_PSS_ANY_SALT() when - * performing a signature, but they are encoded differently. Instead of - * extracting the proper one from the wrapped key policy, just try both. */ - status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg), - hash, hash_len, - sig, sig_size, sig_len); - if (status == PSA_ERROR_NOT_PERMITTED) { - status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg), - hash, hash_len, - sig, sig_size, sig_len); - } - return PSA_PK_RSA_TO_MBEDTLS_ERR(status); - } - - return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg), - ctx->pk_ctx, hash, hash_len, - sig, sig_size, sig_len); -#else /* MBEDTLS_USE_PSA_CRYPTO */ - - if (sig_size < mbedtls_pk_get_len(ctx)) { - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - } - - if (pk_hashlen_helper(md_alg, &hash_len) != 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx); - - const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg, - (unsigned int) hash_len, hash, sig); - if (ret == 0) { - *sig_len = rsa_ctx->len; - } - return ret; - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#else - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; -#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ -} - -/* - * Decrypt message - */ -int mbedtls_pk_decrypt(mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - if (ctx->pk_info == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (ctx->pk_info->decrypt_func == NULL) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - - return ctx->pk_info->decrypt_func(ctx, input, ilen, - output, olen, osize, f_rng, p_rng); -} - -/* - * Encrypt message - */ -int mbedtls_pk_encrypt(mbedtls_pk_context *ctx, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - if (ctx->pk_info == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (ctx->pk_info->encrypt_func == NULL) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - - return ctx->pk_info->encrypt_func(ctx, input, ilen, - output, olen, osize, f_rng, p_rng); -} - -/* - * Check public-private key pair - */ -int mbedtls_pk_check_pair(const mbedtls_pk_context *pub, - const mbedtls_pk_context *prv, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - if (pub->pk_info == NULL || - prv->pk_info == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (f_rng == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (prv->pk_info->check_pair_func == NULL) { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } - - if (prv->pk_info->type == MBEDTLS_PK_RSA_ALT) { - if (pub->pk_info->type != MBEDTLS_PK_RSA) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - } else { - if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) && - (pub->pk_info != prv->pk_info)) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - } - - return prv->pk_info->check_pair_func((mbedtls_pk_context *) pub, - (mbedtls_pk_context *) prv, - f_rng, p_rng); -} - -/* - * Get key size in bits - */ -size_t mbedtls_pk_get_bitlen(const mbedtls_pk_context *ctx) -{ - /* For backward compatibility, accept NULL or a context that - * isn't set up yet, and return a fake value that should be safe. */ - if (ctx == NULL || ctx->pk_info == NULL) { - return 0; - } - - return ctx->pk_info->get_bitlen((mbedtls_pk_context *) ctx); -} - -/* - * Export debug information - */ -int mbedtls_pk_debug(const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items) -{ - if (ctx->pk_info == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (ctx->pk_info->debug_func == NULL) { - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - } - - ctx->pk_info->debug_func((mbedtls_pk_context *) ctx, items); - return 0; -} - -/* - * Access the PK type name - */ -const char *mbedtls_pk_get_name(const mbedtls_pk_context *ctx) -{ - if (ctx == NULL || ctx->pk_info == NULL) { - return "invalid PK"; - } - - return ctx->pk_info->name; -} - -/* - * Access the PK type - */ -mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) -{ - if (ctx == NULL || ctx->pk_info == NULL) { - return MBEDTLS_PK_NONE; - } - - return ctx->pk_info->type; -} - -#endif /* MBEDTLS_PK_C */ diff --git a/vendor/mbedtls/library/pk_ecc.c b/vendor/mbedtls/library/pk_ecc.c deleted file mode 100644 index 86218fffc..000000000 --- a/vendor/mbedtls/library/pk_ecc.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * ECC setters for PK. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#include "mbedtls/pk.h" -#include "mbedtls/error.h" -#include "mbedtls/ecp.h" -#include "pk_internal.h" - -#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_HAVE_ECC_KEYS) - -int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - size_t ec_bits; - psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits); - - /* group may already be initialized; if so, make sure IDs match */ - if ((pk->ec_family != 0 && pk->ec_family != ec_family) || - (pk->ec_bits != 0 && pk->ec_bits != ec_bits)) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - - /* set group */ - pk->ec_family = ec_family; - pk->ec_bits = ec_bits; - - return 0; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk); - - /* grp may already be initialized; if so, make sure IDs match */ - if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE && - mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - - /* set group */ - return mbedtls_ecp_group_load(&(ecp->grp), grp_id); -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_usage_t flags; - psa_status_t status; - - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family)); - if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) { - /* Do not set algorithm here because Montgomery keys cannot do ECDSA and - * the PK module cannot do ECDH. When the key will be used in TLS for - * ECDH, it will be exported and then re-imported with proper flags - * and algorithm. */ - flags = PSA_KEY_USAGE_EXPORT; - } else { - psa_set_key_algorithm(&attributes, - MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH)); - flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | - PSA_KEY_USAGE_EXPORT; - } - psa_set_key_usage_flags(&attributes, flags); - - status = psa_import_key(&attributes, key, key_len, &pk->priv_id); - return psa_pk_status_to_mbedtls(status); - -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - - mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk); - int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - return 0; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, - const unsigned char *prv, size_t prv_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - - (void) f_rng; - (void) p_rng; - (void) prv; - (void) prv_len; - psa_status_t status; - - status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw), - &pk->pub_raw_len); - return psa_pk_status_to_mbedtls(status); - -#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */ - - (void) f_rng; - (void) p_rng; - psa_status_t status; - - mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; - size_t curve_bits; - psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits); - - /* Import private key into PSA, from serialized input */ - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); - psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT); - status = psa_import_key(&key_attr, prv, prv_len, &key_id); - if (status != PSA_SUCCESS) { - return psa_pk_status_to_mbedtls(status); - } - - /* Export public key from PSA */ - unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t pub_len; - status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len); - psa_status_t destruction_status = psa_destroy_key(key_id); - if (status != PSA_SUCCESS) { - return psa_pk_status_to_mbedtls(status); - } else if (destruction_status != PSA_SUCCESS) { - return psa_pk_status_to_mbedtls(destruction_status); - } - - /* Load serialized public key into ecp_keypair structure */ - return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len); - -#else /* MBEDTLS_USE_PSA_CRYPTO */ - - (void) prv; - (void) prv_len; - - mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; - return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng); - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -/* - * Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case. - * - * Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA - * functions to handle keys. However, currently psa_import_key() does not - * support compressed points. In case that support was explicitly requested, - * this fallback uses ECP functions to get the job done. This is the reason - * why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT. - * - * [in/out] pk: in: must have the group set, see mbedtls_pk_ecc_set_group(). - * out: will have the public key set. - * [in] pub, pub_len: the public key as an ECPoint, - * in any format supported by ECP. - * - * Return: - * - 0 on success; - * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid - * but not supported; - * - another error code otherwise. - */ -static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk, - const unsigned char *pub, - size_t pub_len) -{ -#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) - (void) pk; - (void) pub; - (void) pub_len; - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */ - mbedtls_ecp_keypair ecp_key; - mbedtls_ecp_group_id ecp_group_id; - int ret; - - ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits); - - mbedtls_ecp_keypair_init(&ecp_key); - ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id); - if (ret != 0) { - goto exit; - } - ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q, - pub, pub_len); - if (ret != 0) { - goto exit; - } - ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &pk->pub_raw_len, pk->pub_raw, - sizeof(pk->pub_raw)); - -exit: - mbedtls_ecp_keypair_free(&ecp_key); - return ret; -#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */ -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - -int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - - /* Load the key */ - if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) { - /* Format directly supported by PSA: - * - non-Weierstrass curves that only have one format; - * - uncompressed format for Weierstrass curves. */ - if (pub_len > sizeof(pk->pub_raw)) { - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - } - memcpy(pk->pub_raw, pub, pub_len); - pk->pub_raw_len = pub_len; - } else { - /* Other format, try the fallback */ - int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len); - if (ret != 0) { - return ret; - } - } - - /* Validate the key by trying to import it */ - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT; - - psa_set_key_usage_flags(&key_attrs, 0); - psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)); - psa_set_key_bits(&key_attrs, pk->ec_bits); - - if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len, - &key_id) != PSA_SUCCESS) || - (psa_destroy_key(key_id) != PSA_SUCCESS)) { - return MBEDTLS_ERR_PK_INVALID_PUBKEY; - } - - return 0; - -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - - int ret; - mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx; - ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len); - if (ret != 0) { - return ret; - } - return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q); - -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -#endif /* MBEDTLS_PK_C && MBEDTLS_PK_HAVE_ECC_KEYS */ diff --git a/vendor/mbedtls/library/pk_internal.h b/vendor/mbedtls/library/pk_internal.h deleted file mode 100644 index d1c26421d..000000000 --- a/vendor/mbedtls/library/pk_internal.h +++ /dev/null @@ -1,241 +0,0 @@ -/** - * \file pk_internal.h - * - * \brief Public Key abstraction layer: internal (i.e. library only) functions - * and definitions. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_PK_INTERNAL_H -#define MBEDTLS_PK_INTERNAL_H - -#include "mbedtls/pk.h" - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) -#include "psa/crypto.h" - -#include "psa_util_internal.h" -#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status) -#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_pk_rsa_errors, \ - psa_pk_status_to_mbedtls) -#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_pk_ecdsa_errors, \ - psa_pk_status_to_mbedtls) -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ - -/* Headers/footers for PEM files */ -#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----" -#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----" -#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----" -#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----" -#define PEM_BEGIN_PUBLIC_KEY_RSA "-----BEGIN RSA PUBLIC KEY-----" -#define PEM_END_PUBLIC_KEY_RSA "-----END RSA PUBLIC KEY-----" -#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----" -#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----" -#define PEM_BEGIN_PRIVATE_KEY_PKCS8 "-----BEGIN PRIVATE KEY-----" -#define PEM_END_PRIVATE_KEY_PKCS8 "-----END PRIVATE KEY-----" -#define PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----BEGIN ENCRYPTED PRIVATE KEY-----" -#define PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----END ENCRYPTED PRIVATE KEY-----" - -/* - * We're trying to statisfy two kinds of users: - * - those who don't want to use the heap; - * - those who can't afford large stack buffers. - * - * The current compromise is that if ECC is the only key type supported in PK, - * then we export keys on the stack, and otherwise we use the heap. - * - * RSA can either be used directly or indirectly via opaque keys if enabled. - * (RSA_ALT is not relevant here as we can't export from such contexts.) - */ -#if !defined(MBEDTLS_RSA_C) && \ - !(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) -#define PK_EXPORT_KEYS_ON_THE_STACK -#endif - -#if defined(PK_EXPORT_KEYS_ON_THE_STACK) -/* We know for ECC, pubkey are longer than privkeys, but double check. - * Also, take the maximum size of legacy and PSA, as PSA might be disabled. */ -#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH -#if PK_EXPORT_KEY_STACK_BUFFER_SIZE < MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH -#undef PK_EXPORT_KEY_STACK_BUFFER_SIZE -#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH -#endif -#if PK_EXPORT_KEY_STACK_BUFFER_SIZE < MBEDTLS_ECP_MAX_BYTES -#undef PK_EXPORT_KEY_STACK_BUFFER_SIZE -#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_ECP_MAX_BYTES -#endif -#if PK_EXPORT_KEY_STACK_BUFFER_SIZE < MBEDTLS_ECP_MAX_PT_LEN -#undef PK_EXPORT_KEY_STACK_BUFFER_SIZE -#define PK_EXPORT_KEY_STACK_BUFFER_SIZE MBEDTLS_ECP_MAX_PT_LEN -#endif -#endif - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA) -/** - * Public function mbedtls_pk_ec() can be used to get direct access to the - * wrapped ecp_keypair structure pointed to the pk_ctx. However this is not - * ideal because it bypasses the PK module on the control of its internal - * structure (pk_context) fields. - * For backward compatibility we keep mbedtls_pk_ec() when ECP_C is defined, but - * we provide 2 very similar functions when only ECP_LIGHT is enabled and not - * ECP_C. - * These variants embed the "ro" or "rw" keywords in their name to make the - * usage of the returned pointer explicit. Of course the returned value is - * const or non-const accordingly. - */ -static inline const mbedtls_ecp_keypair *mbedtls_pk_ec_ro(const mbedtls_pk_context pk) -{ - switch (mbedtls_pk_get_type(&pk)) { - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: - return (const mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx); - default: - return NULL; - } -} - -static inline mbedtls_ecp_keypair *mbedtls_pk_ec_rw(const mbedtls_pk_context pk) -{ - switch (mbedtls_pk_get_type(&pk)) { - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: - return (mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx); - default: - return NULL; - } -} -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_context *pk) -{ - mbedtls_ecp_group_id id; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t opaque_key_type; - psa_ecc_family_t curve; - - if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) { - return MBEDTLS_ECP_DP_NONE; - } - opaque_key_type = psa_get_key_type(&opaque_attrs); - curve = PSA_KEY_TYPE_ECC_GET_FAMILY(opaque_key_type); - id = mbedtls_ecc_group_from_psa(curve, psa_get_key_bits(&opaque_attrs)); - psa_reset_key_attributes(&opaque_attrs); - } else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - { -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits); -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - id = mbedtls_pk_ec_ro(*pk)->grp.id; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - } - - return id; -} - -/* Helper for Montgomery curves */ -#if defined(MBEDTLS_ECP_HAVE_CURVE25519) || defined(MBEDTLS_ECP_HAVE_CURVE448) -#define MBEDTLS_PK_HAVE_RFC8410_CURVES -#endif /* MBEDTLS_ECP_HAVE_CURVE25519 || MBEDTLS_ECP_DP_CURVE448 */ - -#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \ - ((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448)) - -static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) -{ - mbedtls_ecp_group_id id = mbedtls_pk_get_ec_group_id(pk); - - return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id); -} - -/* - * Set the group used by this key. - * - * [in/out] pk: in: must have been pk_setup() to an ECC type - * out: will have group (curve) information set - * [in] grp_in: a supported group ID (not NONE) - */ -int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id); - -/* - * Set the private key material - * - * [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group(). - * out: will have the private key set. - * [in] key, key_len: the raw private key (no ASN.1 wrapping). - */ -int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len); - -/* - * Set the public key. - * - * [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group(). - * out: will have the public key set. - * [in] pub, pub_len: the raw public key (an ECPoint). - * - * Return: - * - 0 on success; - * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid - * but not supported; - * - another error code otherwise. - */ -int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len); - -/* - * Derive a public key from its private counterpart. - * Computationally intensive, only use when public key is not available. - * - * [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key(). - * out: will have the public key set. - * [in] prv, prv_len: the raw private key (see note below). - * [in] f_rng, p_rng: RNG function and context. - * - * Note: the private key information is always available from pk, - * however for convenience the serialized version is also passed, - * as it's available at each calling site, and useful in some configs - * (as otherwise we would have to re-serialize it from the pk context). - * - * There are three implementations of this function: - * 1. MBEDTLS_PK_USE_PSA_EC_DATA, - * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA, - * 3. not MBEDTLS_USE_PSA_CRYPTO. - */ -int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, - const unsigned char *prv, size_t prv_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -/* Helper for (deterministic) ECDSA */ -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) -#define MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET PSA_ALG_DETERMINISTIC_ECDSA -#else -#define MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET PSA_ALG_ECDSA -#endif - -#if defined(MBEDTLS_TEST_HOOKS) -MBEDTLS_STATIC_TESTABLE int mbedtls_pk_parse_key_pkcs8_encrypted_der( - mbedtls_pk_context *pk, - unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); -#endif - -#if defined(MBEDTLS_FS_IO) -int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n); -#endif - -#endif /* MBEDTLS_PK_INTERNAL_H */ diff --git a/vendor/mbedtls/library/pk_wrap.c b/vendor/mbedtls/library/pk_wrap.c deleted file mode 100644 index 526546934..000000000 --- a/vendor/mbedtls/library/pk_wrap.c +++ /dev/null @@ -1,1595 +0,0 @@ -/* - * Public Key abstraction layer: wrapper functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_PK_C) -#include "pk_wrap.h" -#include "pk_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/psa_util.h" - -/* Even if RSA not activated, for the sake of RSA-alt */ -#include "mbedtls/rsa.h" - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa_util_internal.h" -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" - -#if defined(MBEDTLS_RSA_C) -#include "pkwrite.h" -#include "rsa_internal.h" -#endif - -#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) -#include "mbedtls/asn1write.h" -#include "mbedtls/asn1.h" -#endif -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#include "mbedtls/platform.h" - -#include -#include -#include - -#if defined(MBEDTLS_RSA_C) -static int rsa_can_do(mbedtls_pk_type_t type) -{ - return type == MBEDTLS_PK_RSA || - type == MBEDTLS_PK_RSASSA_PSS; -} - -static size_t rsa_get_bitlen(mbedtls_pk_context *pk) -{ - const mbedtls_rsa_context *rsa = (const mbedtls_rsa_context *) pk->pk_ctx; - return mbedtls_rsa_get_bitlen(rsa); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_status_t status; - int key_len; - unsigned char buf[PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; - unsigned char *p = buf + sizeof(buf); - psa_algorithm_t psa_alg_md; - size_t rsa_len = mbedtls_rsa_get_len(rsa); - -#if SIZE_MAX > UINT_MAX - if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } -#endif - - if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { - psa_alg_md = PSA_ALG_RSA_PSS(mbedtls_md_psa_alg_from_type(md_alg)); - } else { - psa_alg_md = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg)); - } - - if (sig_len < rsa_len) { - return MBEDTLS_ERR_RSA_VERIFY_FAILED; - } - - key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p); - if (key_len <= 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); - psa_set_key_algorithm(&attributes, psa_alg_md); - psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); - - status = psa_import_key(&attributes, - buf + sizeof(buf) - key_len, key_len, - &key_id); - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - status = psa_verify_hash(key_id, psa_alg_md, hash, hash_len, - sig, sig_len); - if (status != PSA_SUCCESS) { - ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); - goto cleanup; - } - ret = 0; - -cleanup: - status = psa_destroy_key(key_id); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - } - - return ret; -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - size_t rsa_len = mbedtls_rsa_get_len(rsa); - -#if SIZE_MAX > UINT_MAX - if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } -#endif - - if (sig_len < rsa_len) { - return MBEDTLS_ERR_RSA_VERIFY_FAILED; - } - - if ((ret = mbedtls_rsa_pkcs1_verify(rsa, md_alg, - (unsigned int) hash_len, - hash, sig)) != 0) { - return ret; - } - - /* The buffer contains a valid signature followed by extra data. - * We have a special error code for that so that so that callers can - * use mbedtls_pk_verify() to check "Does the buffer start with a - * valid signature?" and not just "Does the buffer contain a valid - * signature?". */ - if (sig_len > rsa_len) { - return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; - } - - return 0; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg, - mbedtls_rsa_context *rsa_ctx, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, - size_t *sig_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_status_t status; - int key_len; - unsigned char *buf = NULL; - unsigned char *p; - - buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES); - if (buf == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - p = buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES; - - *sig_len = mbedtls_rsa_get_len(rsa_ctx); - if (sig_size < *sig_len) { - mbedtls_free(buf); - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - } - - key_len = mbedtls_rsa_write_key(rsa_ctx, buf, &p); - if (key_len <= 0) { - mbedtls_free(buf); - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); - - status = psa_import_key(&attributes, - buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES - key_len, key_len, - &key_id); - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto cleanup; - } - status = psa_sign_hash(key_id, alg, hash, hash_len, - sig, sig_size, sig_len); - if (status != PSA_SUCCESS) { - ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - ret = 0; - -cleanup: - mbedtls_free(buf); - status = psa_destroy_key(key_id); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - } - return ret; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - ((void) f_rng); - ((void) p_rng); - - psa_algorithm_t psa_md_alg; - psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); - if (psa_md_alg == 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - psa_algorithm_t psa_alg; - if (mbedtls_rsa_get_padding_mode(mbedtls_pk_rsa(*pk)) == MBEDTLS_RSA_PKCS_V21) { - psa_alg = PSA_ALG_RSA_PSS(psa_md_alg); - } else { - psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg); - } - - return mbedtls_pk_psa_rsa_sign_ext(psa_alg, pk->pk_ctx, hash, hash_len, - sig, sig_size, sig_len); -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - -#if SIZE_MAX > UINT_MAX - if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } -#endif - - *sig_len = mbedtls_rsa_get_len(rsa); - if (sig_size < *sig_len) { - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - } - - return mbedtls_rsa_pkcs1_sign(rsa, f_rng, p_rng, - md_alg, (unsigned int) hash_len, - hash, sig); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int rsa_decrypt_wrap(mbedtls_pk_context *pk, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_algorithm_t psa_md_alg, decrypt_alg; - psa_status_t status; - int key_len; - ((void) f_rng); - ((void) p_rng); - - if (ilen != mbedtls_rsa_get_len(rsa)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - const size_t key_bits = mbedtls_pk_get_bitlen(pk); - /* mbedtls_rsa_write_key() uses the same format as PSA export, which - * actually calls it under the hood, so we can use the PSA size macro. */ - const size_t buf_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits); - unsigned char *buf = mbedtls_calloc(1, buf_size); - - unsigned char *p = buf + buf_size; - key_len = mbedtls_rsa_write_key(rsa, buf, &p); - if (key_len <= 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); - if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { - psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa)); - decrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg); - } else { - decrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT; - } - psa_set_key_algorithm(&attributes, decrypt_alg); - - status = psa_import_key(&attributes, - buf + buf_size - key_len, key_len, - &key_id); - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - status = psa_asymmetric_decrypt(key_id, decrypt_alg, - input, ilen, - NULL, 0, - output, osize, olen); - if (status != PSA_SUCCESS) { - ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - ret = 0; - -cleanup: - mbedtls_zeroize_and_free(buf, buf_size); - status = psa_destroy_key(key_id); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - } - - return ret; -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int rsa_decrypt_wrap(mbedtls_pk_context *pk, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - - if (ilen != mbedtls_rsa_get_len(rsa)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - return mbedtls_rsa_pkcs1_decrypt(rsa, f_rng, p_rng, - olen, input, output, osize); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int rsa_encrypt_wrap(mbedtls_pk_context *pk, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_algorithm_t psa_md_alg, psa_encrypt_alg; - psa_status_t status; - int key_len; - unsigned char buf[PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)]; - unsigned char *p = buf + sizeof(buf); - - ((void) f_rng); - ((void) p_rng); - - if (mbedtls_rsa_get_len(rsa) > osize) { - return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; - } - - key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p); - if (key_len <= 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { - psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa)); - psa_encrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg); - } else { - psa_encrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT; - } - psa_set_key_algorithm(&attributes, psa_encrypt_alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); - - status = psa_import_key(&attributes, - buf + sizeof(buf) - key_len, key_len, - &key_id); - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - status = psa_asymmetric_encrypt(key_id, psa_encrypt_alg, - input, ilen, - NULL, 0, - output, osize, olen); - if (status != PSA_SUCCESS) { - ret = PSA_PK_RSA_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - ret = 0; - -cleanup: - status = psa_destroy_key(key_id); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - } - - return ret; -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int rsa_encrypt_wrap(mbedtls_pk_context *pk, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - *olen = mbedtls_rsa_get_len(rsa); - - if (*olen > osize) { - return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; - } - - return mbedtls_rsa_pkcs1_encrypt(rsa, f_rng, p_rng, - ilen, input, output); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -static int rsa_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - (void) f_rng; - (void) p_rng; - return mbedtls_rsa_check_pub_priv((const mbedtls_rsa_context *) pub->pk_ctx, - (const mbedtls_rsa_context *) prv->pk_ctx); -} - -static void *rsa_alloc_wrap(void) -{ - void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_context)); - - if (ctx != NULL) { - mbedtls_rsa_init((mbedtls_rsa_context *) ctx); - } - - return ctx; -} - -static void rsa_free_wrap(void *ctx) -{ - mbedtls_rsa_free((mbedtls_rsa_context *) ctx); - mbedtls_free(ctx); -} - -static void rsa_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items) -{ -#if defined(MBEDTLS_RSA_ALT) - /* Not supported */ - (void) pk; - (void) items; -#else - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) pk->pk_ctx; - - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.N"; - items->value = &(rsa->N); - - items++; - - items->type = MBEDTLS_PK_DEBUG_MPI; - items->name = "rsa.E"; - items->value = &(rsa->E); -#endif -} - -const mbedtls_pk_info_t mbedtls_rsa_info = { - .type = MBEDTLS_PK_RSA, - .name = "RSA", - .get_bitlen = rsa_get_bitlen, - .can_do = rsa_can_do, - .verify_func = rsa_verify_wrap, - .sign_func = rsa_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - .verify_rs_func = NULL, - .sign_rs_func = NULL, - .rs_alloc_func = NULL, - .rs_free_func = NULL, -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - .decrypt_func = rsa_decrypt_wrap, - .encrypt_func = rsa_encrypt_wrap, - .check_pair_func = rsa_check_pair_wrap, - .ctx_alloc_func = rsa_alloc_wrap, - .ctx_free_func = rsa_free_wrap, - .debug_func = rsa_debug, -}; -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -/* - * Generic EC key - */ -static int eckey_can_do(mbedtls_pk_type_t type) -{ - return type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH || - type == MBEDTLS_PK_ECDSA; -} - -static size_t eckey_get_bitlen(mbedtls_pk_context *pk) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - return pk->ec_bits; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx; - return ecp->grp.pbits; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* Common helper for ECDSA verify using PSA functions. */ -static int ecdsa_verify_psa(unsigned char *key, size_t key_len, - psa_ecc_family_t curve, size_t curve_bits, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY; - size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits); - size_t converted_sig_len; - unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE]; - unsigned char *p; - psa_status_t status; - - if (curve == 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); - psa_set_key_algorithm(&attributes, psa_sig_md); - - status = psa_import_key(&attributes, key, key_len, &key_id); - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - if (signature_len > sizeof(extracted_sig)) { - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - goto cleanup; - } - - p = (unsigned char *) sig; - ret = mbedtls_ecdsa_der_to_raw(curve_bits, p, sig_len, extracted_sig, - sizeof(extracted_sig), &converted_sig_len); - if (ret != 0) { - goto cleanup; - } - - if (converted_sig_len != signature_len) { - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - goto cleanup; - } - - status = psa_verify_hash(key_id, psa_sig_md, hash, hash_len, - extracted_sig, signature_len); - if (status != PSA_SUCCESS) { - ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - ret = 0; - -cleanup: - status = psa_destroy_key(key_id); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - } - - return ret; -} - -static int ecdsa_opaque_verify_wrap(mbedtls_pk_context *pk, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - (void) md_alg; - unsigned char key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN]; - size_t key_len; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_ecc_family_t curve; - size_t curve_bits; - psa_status_t status; - - status = psa_get_key_attributes(pk->priv_id, &key_attr); - if (status != PSA_SUCCESS) { - return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - } - curve = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attr)); - curve_bits = psa_get_key_bits(&key_attr); - psa_reset_key_attributes(&key_attr); - - status = psa_export_public_key(pk->priv_id, key, sizeof(key), &key_len); - if (status != PSA_SUCCESS) { - return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - } - - return ecdsa_verify_psa(key, key_len, curve, curve_bits, - hash, hash_len, sig, sig_len); -} - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -static int ecdsa_verify_wrap(mbedtls_pk_context *pk, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - (void) md_alg; - psa_ecc_family_t curve = pk->ec_family; - size_t curve_bits = pk->ec_bits; - - return ecdsa_verify_psa(pk->pub_raw, pk->pub_raw_len, curve, curve_bits, - hash, hash_len, sig, sig_len); -} -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ -static int ecdsa_verify_wrap(mbedtls_pk_context *pk, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - (void) md_alg; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_keypair *ctx = pk->pk_ctx; - unsigned char key[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t key_len; - size_t curve_bits; - psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits); - - ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &key_len, key, sizeof(key)); - if (ret != 0) { - return ret; - } - - return ecdsa_verify_psa(key, key_len, curve, curve_bits, - hash, hash_len, sig, sig_len); -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int ecdsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature((mbedtls_ecdsa_context *) pk->pk_ctx, - hash, hash_len, sig, sig_len); - - if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) { - return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; - } - - return ret; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ - -#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* Common helper for ECDSA sign using PSA functions. - * Instead of extracting key's properties in order to check which kind of ECDSA - * signature it supports, we try both deterministic and non-deterministic. - */ -static int ecdsa_sign_psa(mbedtls_svc_key_id_t key_id, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - size_t key_bits = 0; - - status = psa_get_key_attributes(key_id, &key_attr); - if (status != PSA_SUCCESS) { - return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - } - key_bits = psa_get_key_bits(&key_attr); - psa_reset_key_attributes(&key_attr); - - status = psa_sign_hash(key_id, - PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)), - hash, hash_len, sig, sig_size, sig_len); - if (status == PSA_SUCCESS) { - goto done; - } else if (status != PSA_ERROR_NOT_PERMITTED) { - return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - } - - status = psa_sign_hash(key_id, - PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)), - hash, hash_len, sig, sig_size, sig_len); - if (status != PSA_SUCCESS) { - return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - } - -done: - ret = mbedtls_ecdsa_raw_to_der(key_bits, sig, *sig_len, sig, sig_size, sig_len); - - return ret; -} - -static int ecdsa_opaque_sign_wrap(mbedtls_pk_context *pk, - mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, - size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - ((void) f_rng); - ((void) p_rng); - - return ecdsa_sign_psa(pk->priv_id, md_alg, hash, hash_len, sig, sig_size, - sig_len); -} - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -/* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up - * using the same function. */ -#define ecdsa_sign_wrap ecdsa_opaque_sign_wrap -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ -static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_status_t status; - mbedtls_ecp_keypair *ctx = pk->pk_ctx; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; - size_t curve_bits; - psa_ecc_family_t curve = - mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits); - size_t key_len = PSA_BITS_TO_BYTES(curve_bits); - psa_algorithm_t psa_hash = mbedtls_md_psa_alg_from_type(md_alg); - psa_algorithm_t psa_sig_md = MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(psa_hash); - ((void) f_rng); - ((void) p_rng); - - if (curve == 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (key_len > sizeof(buf)) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - ret = mbedtls_mpi_write_binary(&ctx->d, buf, key_len); - if (ret != 0) { - goto cleanup; - } - - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); - psa_set_key_algorithm(&attributes, psa_sig_md); - - status = psa_import_key(&attributes, buf, key_len, &key_id); - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto cleanup; - } - - ret = ecdsa_sign_psa(key_id, md_alg, hash, hash_len, sig, sig_size, sig_len); - -cleanup: - mbedtls_platform_zeroize(buf, sizeof(buf)); - status = psa_destroy_key(key_id); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - } - - return ret; -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int ecdsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - return mbedtls_ecdsa_write_signature((mbedtls_ecdsa_context *) pk->pk_ctx, - md_alg, hash, hash_len, - sig, sig_size, sig_len, - f_rng, p_rng); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* Forward declarations */ -static int ecdsa_verify_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx); - -static int ecdsa_sign_rs_wrap(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx); - -/* - * Restart context for ECDSA operations with ECKEY context - * - * We need to store an actual ECDSA context, as we need to pass the same to - * the underlying ecdsa function, so we can't create it on the fly every time. - */ -typedef struct { - mbedtls_ecdsa_restart_ctx ecdsa_rs; - mbedtls_ecdsa_context ecdsa_ctx; -} eckey_restart_ctx; - -static void *eckey_rs_alloc(void) -{ - eckey_restart_ctx *rs_ctx; - - void *ctx = mbedtls_calloc(1, sizeof(eckey_restart_ctx)); - - if (ctx != NULL) { - rs_ctx = ctx; - mbedtls_ecdsa_restart_init(&rs_ctx->ecdsa_rs); - mbedtls_ecdsa_init(&rs_ctx->ecdsa_ctx); - } - - return ctx; -} - -static void eckey_rs_free(void *ctx) -{ - eckey_restart_ctx *rs_ctx; - - if (ctx == NULL) { - return; - } - - rs_ctx = ctx; - mbedtls_ecdsa_restart_free(&rs_ctx->ecdsa_rs); - mbedtls_ecdsa_free(&rs_ctx->ecdsa_ctx); - - mbedtls_free(ctx); -} - -static int eckey_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if (rs == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - /* set up our own sub-context if needed (that is, on first run) */ - if (rs->ecdsa_ctx.grp.pbits == 0) { - MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx)); - } - - MBEDTLS_MPI_CHK(ecdsa_verify_rs_wrap(pk, - md_alg, hash, hash_len, - sig, sig_len, &rs->ecdsa_rs)); - -cleanup: - return ret; -} - -static int eckey_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - eckey_restart_ctx *rs = rs_ctx; - - /* Should never happen */ - if (rs == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - /* set up our own sub-context if needed (that is, on first run) */ - if (rs->ecdsa_ctx.grp.pbits == 0) { - MBEDTLS_MPI_CHK(mbedtls_ecdsa_from_keypair(&rs->ecdsa_ctx, pk->pk_ctx)); - } - - MBEDTLS_MPI_CHK(ecdsa_sign_rs_wrap(pk, md_alg, - hash, hash_len, sig, sig_size, sig_len, - f_rng, p_rng, &rs->ecdsa_rs)); - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv) -{ - psa_status_t status; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t prv_key_len; - mbedtls_svc_key_id_t key_id = prv->priv_id; - - status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf), - &prv_key_len); - ret = PSA_PK_TO_MBEDTLS_ERR(status); - if (ret != 0) { - return ret; - } - - if (memcmp(prv_key_buf, pub->pub_raw, pub->pub_raw_len) != 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - return 0; -} -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ -static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv) -{ - psa_status_t status; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t prv_key_len; - psa_status_t destruction_status; - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t pub_key_len; - size_t curve_bits; - const psa_ecc_family_t curve = - mbedtls_ecc_group_to_psa(mbedtls_pk_ec_ro(*prv)->grp.id, &curve_bits); - const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits); - - if (curve == 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); - psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT); - - ret = mbedtls_mpi_write_binary(&mbedtls_pk_ec_ro(*prv)->d, - prv_key_buf, curve_bytes); - if (ret != 0) { - mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf)); - return ret; - } - - status = psa_import_key(&key_attr, prv_key_buf, curve_bytes, &key_id); - mbedtls_platform_zeroize(prv_key_buf, sizeof(prv_key_buf)); - ret = PSA_PK_TO_MBEDTLS_ERR(status); - if (ret != 0) { - return ret; - } - - // From now on prv_key_buf is used to store the public key of prv. - status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf), - &prv_key_len); - ret = PSA_PK_TO_MBEDTLS_ERR(status); - destruction_status = psa_destroy_key(key_id); - if (ret != 0) { - return ret; - } else if (destruction_status != PSA_SUCCESS) { - return PSA_PK_TO_MBEDTLS_ERR(destruction_status); - } - - ret = mbedtls_ecp_point_write_binary(&mbedtls_pk_ec_rw(*pub)->grp, - &mbedtls_pk_ec_rw(*pub)->Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &pub_key_len, pub_key_buf, - sizeof(pub_key_buf)); - if (ret != 0) { - return ret; - } - - if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - return 0; -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - -static int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - (void) f_rng; - (void) p_rng; - return eckey_check_pair_psa(pub, prv); -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -static int eckey_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - return mbedtls_ecp_check_pub_priv((const mbedtls_ecp_keypair *) pub->pk_ctx, - (const mbedtls_ecp_keypair *) prv->pk_ctx, - f_rng, p_rng); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -/* When PK_USE_PSA_EC_DATA is defined opaque and non-opaque keys end up - * using the same function. */ -#define ecdsa_opaque_check_pair_wrap eckey_check_pair_wrap -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ -static int ecdsa_opaque_check_pair_wrap(mbedtls_pk_context *pub, - mbedtls_pk_context *prv, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - psa_status_t status; - uint8_t exp_pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN]; - size_t exp_pub_key_len = 0; - uint8_t pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN]; - size_t pub_key_len = 0; - int ret; - (void) f_rng; - (void) p_rng; - - status = psa_export_public_key(prv->priv_id, exp_pub_key, sizeof(exp_pub_key), - &exp_pub_key_len); - if (status != PSA_SUCCESS) { - ret = psa_pk_status_to_mbedtls(status); - return ret; - } - ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec_ro(*pub)->grp), - &(mbedtls_pk_ec_ro(*pub)->Q), - MBEDTLS_ECP_PF_UNCOMPRESSED, - &pub_key_len, pub_key, sizeof(pub_key)); - if (ret != 0) { - return ret; - } - if ((exp_pub_key_len != pub_key_len) || - memcmp(exp_pub_key, pub_key, exp_pub_key_len)) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - return 0; -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) -static void *eckey_alloc_wrap(void) -{ - void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair)); - - if (ctx != NULL) { - mbedtls_ecp_keypair_init(ctx); - } - - return ctx; -} - -static void eckey_free_wrap(void *ctx) -{ - mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx); - mbedtls_free(ctx); -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - -static void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - items->type = MBEDTLS_PK_DEBUG_PSA_EC; - items->name = "eckey.Q"; - items->value = pk; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx; - items->type = MBEDTLS_PK_DEBUG_ECP; - items->name = "eckey.Q"; - items->value = &(ecp->Q); -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -const mbedtls_pk_info_t mbedtls_eckey_info = { - .type = MBEDTLS_PK_ECKEY, - .name = "EC", - .get_bitlen = eckey_get_bitlen, - .can_do = eckey_can_do, -#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) - .verify_func = ecdsa_verify_wrap, /* Compatible key structures */ -#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ - .verify_func = NULL, -#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ -#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) - .sign_func = ecdsa_sign_wrap, /* Compatible key structures */ -#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ - .sign_func = NULL, -#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - .verify_rs_func = eckey_verify_rs_wrap, - .sign_rs_func = eckey_sign_rs_wrap, - .rs_alloc_func = eckey_rs_alloc, - .rs_free_func = eckey_rs_free, -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - .decrypt_func = NULL, - .encrypt_func = NULL, - .check_pair_func = eckey_check_pair_wrap, -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - .ctx_alloc_func = NULL, - .ctx_free_func = NULL, -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - .ctx_alloc_func = eckey_alloc_wrap, - .ctx_free_func = eckey_free_wrap, -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - .debug_func = eckey_debug, -}; - -/* - * EC key restricted to ECDH - */ -static int eckeydh_can_do(mbedtls_pk_type_t type) -{ - return type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECKEY_DH; -} - -const mbedtls_pk_info_t mbedtls_eckeydh_info = { - .type = MBEDTLS_PK_ECKEY_DH, - .name = "EC_DH", - .get_bitlen = eckey_get_bitlen, /* Same underlying key structure */ - .can_do = eckeydh_can_do, - .verify_func = NULL, - .sign_func = NULL, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - .verify_rs_func = NULL, - .sign_rs_func = NULL, -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - .decrypt_func = NULL, - .encrypt_func = NULL, - .check_pair_func = eckey_check_pair_wrap, -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - .ctx_alloc_func = NULL, - .ctx_free_func = NULL, -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - .ctx_alloc_func = eckey_alloc_wrap, /* Same underlying key structure */ - .ctx_free_func = eckey_free_wrap, /* Same underlying key structure */ -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - .debug_func = eckey_debug, /* Same underlying key structure */ -}; - -#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) -static int ecdsa_can_do(mbedtls_pk_type_t type) -{ - return type == MBEDTLS_PK_ECDSA; -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -static int ecdsa_verify_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ((void) md_alg); - - ret = mbedtls_ecdsa_read_signature_restartable( - (mbedtls_ecdsa_context *) pk->pk_ctx, - hash, hash_len, sig, sig_len, - (mbedtls_ecdsa_restart_ctx *) rs_ctx); - - if (ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) { - return MBEDTLS_ERR_PK_SIG_LEN_MISMATCH; - } - - return ret; -} - -static int ecdsa_sign_rs_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - void *rs_ctx) -{ - return mbedtls_ecdsa_write_signature_restartable( - (mbedtls_ecdsa_context *) pk->pk_ctx, - md_alg, hash, hash_len, sig, sig_size, sig_len, f_rng, p_rng, - (mbedtls_ecdsa_restart_ctx *) rs_ctx); - -} - -static void *ecdsa_rs_alloc(void) -{ - void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecdsa_restart_ctx)); - - if (ctx != NULL) { - mbedtls_ecdsa_restart_init(ctx); - } - - return ctx; -} - -static void ecdsa_rs_free(void *ctx) -{ - mbedtls_ecdsa_restart_free(ctx); - mbedtls_free(ctx); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -const mbedtls_pk_info_t mbedtls_ecdsa_info = { - .type = MBEDTLS_PK_ECDSA, - .name = "ECDSA", - .get_bitlen = eckey_get_bitlen, /* Compatible key structures */ - .can_do = ecdsa_can_do, -#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) - .verify_func = ecdsa_verify_wrap, /* Compatible key structures */ -#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ - .verify_func = NULL, -#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ -#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) - .sign_func = ecdsa_sign_wrap, /* Compatible key structures */ -#else /* MBEDTLS_PK_CAN_ECDSA_SIGN */ - .sign_func = NULL, -#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - .verify_rs_func = ecdsa_verify_rs_wrap, - .sign_rs_func = ecdsa_sign_rs_wrap, - .rs_alloc_func = ecdsa_rs_alloc, - .rs_free_func = ecdsa_rs_free, -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - .decrypt_func = NULL, - .encrypt_func = NULL, - .check_pair_func = eckey_check_pair_wrap, /* Compatible key structures */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - .ctx_alloc_func = NULL, - .ctx_free_func = NULL, -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - .ctx_alloc_func = eckey_alloc_wrap, /* Compatible key structures */ - .ctx_free_func = eckey_free_wrap, /* Compatible key structures */ -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - .debug_func = eckey_debug, /* Compatible key structures */ -}; -#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* - * Support for alternative RSA-private implementations - */ - -static int rsa_alt_can_do(mbedtls_pk_type_t type) -{ - return type == MBEDTLS_PK_RSA; -} - -static size_t rsa_alt_get_bitlen(mbedtls_pk_context *pk) -{ - const mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx; - - return 8 * rsa_alt->key_len_func(rsa_alt->key); -} - -static int rsa_alt_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx; - -#if SIZE_MAX > UINT_MAX - if (UINT_MAX < hash_len) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } -#endif - - *sig_len = rsa_alt->key_len_func(rsa_alt->key); - if (*sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - if (*sig_len > sig_size) { - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - } - - return rsa_alt->sign_func(rsa_alt->key, f_rng, p_rng, - md_alg, (unsigned int) hash_len, hash, sig); -} - -static int rsa_alt_decrypt_wrap(mbedtls_pk_context *pk, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - mbedtls_rsa_alt_context *rsa_alt = pk->pk_ctx; - - ((void) f_rng); - ((void) p_rng); - - if (ilen != rsa_alt->key_len_func(rsa_alt->key)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - return rsa_alt->decrypt_func(rsa_alt->key, - olen, input, output, osize); -} - -#if defined(MBEDTLS_RSA_C) -static int rsa_alt_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - unsigned char hash[32]; - size_t sig_len = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (rsa_alt_get_bitlen(prv) != rsa_get_bitlen(pub)) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - size_t sig_size = (rsa_get_bitlen(pub) + 7) / 8; - unsigned char *sig = mbedtls_calloc(1, sig_size); - if (sig == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - - memset(hash, 0x2a, sizeof(hash)); - - if ((ret = rsa_alt_sign_wrap(prv, MBEDTLS_MD_NONE, - hash, sizeof(hash), - sig, sig_size, &sig_len, - f_rng, p_rng)) != 0) { - goto cleanup; - } - - if (rsa_verify_wrap(pub, MBEDTLS_MD_NONE, - hash, sizeof(hash), sig, sig_len) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - -cleanup: - mbedtls_zeroize_and_free(sig, sig_size); - return ret; -} -#endif /* MBEDTLS_RSA_C */ - -static void *rsa_alt_alloc_wrap(void) -{ - void *ctx = mbedtls_calloc(1, sizeof(mbedtls_rsa_alt_context)); - - if (ctx != NULL) { - memset(ctx, 0, sizeof(mbedtls_rsa_alt_context)); - } - - return ctx; -} - -static void rsa_alt_free_wrap(void *ctx) -{ - mbedtls_zeroize_and_free(ctx, sizeof(mbedtls_rsa_alt_context)); -} - -const mbedtls_pk_info_t mbedtls_rsa_alt_info = { - .type = MBEDTLS_PK_RSA_ALT, - .name = "RSA-alt", - .get_bitlen = rsa_alt_get_bitlen, - .can_do = rsa_alt_can_do, - .verify_func = NULL, - .sign_func = rsa_alt_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - .verify_rs_func = NULL, - .sign_rs_func = NULL, - .rs_alloc_func = NULL, - .rs_free_func = NULL, -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - .decrypt_func = rsa_alt_decrypt_wrap, - .encrypt_func = NULL, -#if defined(MBEDTLS_RSA_C) - .check_pair_func = rsa_alt_check_pair, -#else - .check_pair_func = NULL, -#endif - .ctx_alloc_func = rsa_alt_alloc_wrap, - .ctx_free_func = rsa_alt_free_wrap, - .debug_func = NULL, -}; -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static size_t opaque_get_bitlen(mbedtls_pk_context *pk) -{ - size_t bits; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - - if (PSA_SUCCESS != psa_get_key_attributes(pk->priv_id, &attributes)) { - return 0; - } - - bits = psa_get_key_bits(&attributes); - psa_reset_key_attributes(&attributes); - return bits; -} - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -static int ecdsa_opaque_can_do(mbedtls_pk_type_t type) -{ - return type == MBEDTLS_PK_ECKEY || - type == MBEDTLS_PK_ECDSA; -} - -const mbedtls_pk_info_t mbedtls_ecdsa_opaque_info = { - .type = MBEDTLS_PK_OPAQUE, - .name = "Opaque", - .get_bitlen = opaque_get_bitlen, - .can_do = ecdsa_opaque_can_do, -#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) - .verify_func = ecdsa_opaque_verify_wrap, -#else /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ - .verify_func = NULL, -#endif /* MBEDTLS_PK_CAN_ECDSA_VERIFY */ -#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) - .sign_func = ecdsa_opaque_sign_wrap, -#else /* MBEDTLS_PK_CAN_ECDSA_SIGN */ - .sign_func = NULL, -#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - .verify_rs_func = NULL, - .sign_rs_func = NULL, - .rs_alloc_func = NULL, - .rs_free_func = NULL, -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - .decrypt_func = NULL, - .encrypt_func = NULL, - .check_pair_func = ecdsa_opaque_check_pair_wrap, - .ctx_alloc_func = NULL, - .ctx_free_func = NULL, - .debug_func = NULL, -}; -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -static int rsa_opaque_can_do(mbedtls_pk_type_t type) -{ - return type == MBEDTLS_PK_RSA || - type == MBEDTLS_PK_RSASSA_PSS; -} - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -static int rsa_opaque_decrypt(mbedtls_pk_context *pk, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_algorithm_t alg; - psa_key_type_t type; - psa_status_t status; - - /* PSA has its own RNG */ - (void) f_rng; - (void) p_rng; - - status = psa_get_key_attributes(pk->priv_id, &attributes); - if (status != PSA_SUCCESS) { - return PSA_PK_TO_MBEDTLS_ERR(status); - } - - type = psa_get_key_type(&attributes); - alg = psa_get_key_algorithm(&attributes); - psa_reset_key_attributes(&attributes); - - if (!PSA_KEY_TYPE_IS_RSA(type)) { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } - - status = psa_asymmetric_decrypt(pk->priv_id, alg, input, ilen, NULL, 0, output, osize, olen); - if (status != PSA_SUCCESS) { - return PSA_PK_RSA_TO_MBEDTLS_ERR(status); - } - - return 0; -} -#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ - -static int rsa_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ -#if defined(MBEDTLS_RSA_C) - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_algorithm_t alg; - psa_key_type_t type; - psa_status_t status; - - /* PSA has its own RNG */ - (void) f_rng; - (void) p_rng; - - status = psa_get_key_attributes(pk->priv_id, &attributes); - if (status != PSA_SUCCESS) { - return PSA_PK_TO_MBEDTLS_ERR(status); - } - - type = psa_get_key_type(&attributes); - alg = psa_get_key_algorithm(&attributes); - psa_reset_key_attributes(&attributes); - - if (PSA_KEY_TYPE_IS_RSA(type)) { - alg = (alg & ~PSA_ALG_HASH_MASK) | mbedtls_md_psa_alg_from_type(md_alg); - } else { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } - - status = psa_sign_hash(pk->priv_id, alg, hash, hash_len, sig, sig_size, sig_len); - if (status != PSA_SUCCESS) { - if (PSA_KEY_TYPE_IS_RSA(type)) { - return PSA_PK_RSA_TO_MBEDTLS_ERR(status); - } else { - return PSA_PK_TO_MBEDTLS_ERR(status); - } - } - - return 0; -#else /* !MBEDTLS_RSA_C */ - ((void) pk); - ((void) md_alg); - ((void) hash); - ((void) hash_len); - ((void) sig); - ((void) sig_size); - ((void) sig_len); - ((void) f_rng); - ((void) p_rng); - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; -#endif /* !MBEDTLS_RSA_C */ -} - -const mbedtls_pk_info_t mbedtls_rsa_opaque_info = { - .type = MBEDTLS_PK_OPAQUE, - .name = "Opaque", - .get_bitlen = opaque_get_bitlen, - .can_do = rsa_opaque_can_do, - .verify_func = NULL, - .sign_func = rsa_opaque_sign_wrap, -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - .verify_rs_func = NULL, - .sign_rs_func = NULL, - .rs_alloc_func = NULL, - .rs_free_func = NULL, -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) - .decrypt_func = rsa_opaque_decrypt, -#else /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ - .decrypt_func = NULL, -#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ - .encrypt_func = NULL, - .check_pair_func = NULL, - .ctx_alloc_func = NULL, - .ctx_free_func = NULL, - .debug_func = NULL, -}; - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#endif /* MBEDTLS_PK_C */ diff --git a/vendor/mbedtls/library/pk_wrap.h b/vendor/mbedtls/library/pk_wrap.h deleted file mode 100644 index be096da53..000000000 --- a/vendor/mbedtls/library/pk_wrap.h +++ /dev/null @@ -1,138 +0,0 @@ -/** - * \file pk_wrap.h - * - * \brief Public Key abstraction layer: wrapper functions - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_PK_WRAP_H -#define MBEDTLS_PK_WRAP_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/pk.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif - -struct mbedtls_pk_info_t { - /** Public key type */ - mbedtls_pk_type_t type; - - /** Type name */ - const char *name; - - /** Get key size in bits */ - size_t (*get_bitlen)(mbedtls_pk_context *pk); - - /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */ - int (*can_do)(mbedtls_pk_type_t type); - - /** Verify signature */ - int (*verify_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len); - - /** Make signature */ - int (*sign_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /** Verify signature (restartable) */ - int (*verify_rs_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - const unsigned char *sig, size_t sig_len, - void *rs_ctx); - - /** Make signature (restartable) */ - int (*sign_rs_func)(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, size_t *sig_len, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, void *rs_ctx); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - /** Decrypt message */ - int (*decrypt_func)(mbedtls_pk_context *pk, const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - - /** Encrypt message */ - int (*encrypt_func)(mbedtls_pk_context *pk, const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, size_t osize, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - - /** Check public-private key pair */ - int (*check_pair_func)(mbedtls_pk_context *pub, mbedtls_pk_context *prv, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - - /** Allocate a new context */ - void * (*ctx_alloc_func)(void); - - /** Free the given context */ - void (*ctx_free_func)(void *ctx); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /** Allocate the restart context */ - void *(*rs_alloc_func)(void); - - /** Free the restart context */ - void (*rs_free_func)(void *rs_ctx); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - /** Interface with the debug module */ - void (*debug_func)(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items); - -}; -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -/* Container for RSA-alt */ -typedef struct { - void *key; - mbedtls_pk_rsa_alt_decrypt_func decrypt_func; - mbedtls_pk_rsa_alt_sign_func sign_func; - mbedtls_pk_rsa_alt_key_len_func key_len_func; -} mbedtls_rsa_alt_context; -#endif - -#if defined(MBEDTLS_RSA_C) -extern const mbedtls_pk_info_t mbedtls_rsa_info; -#endif - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -extern const mbedtls_pk_info_t mbedtls_eckey_info; -extern const mbedtls_pk_info_t mbedtls_eckeydh_info; -#endif - -#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) -extern const mbedtls_pk_info_t mbedtls_ecdsa_info; -#endif - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -extern const mbedtls_pk_info_t mbedtls_rsa_alt_info; -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -extern const mbedtls_pk_info_t mbedtls_ecdsa_opaque_info; -extern const mbedtls_pk_info_t mbedtls_rsa_opaque_info; - -#if defined(MBEDTLS_RSA_C) -int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t psa_alg_md, - mbedtls_rsa_context *rsa_ctx, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, - size_t *sig_len); -#endif /* MBEDTLS_RSA_C */ - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#endif /* MBEDTLS_PK_WRAP_H */ diff --git a/vendor/mbedtls/library/pkcs12.c b/vendor/mbedtls/library/pkcs12.c deleted file mode 100644 index a3467b982..000000000 --- a/vendor/mbedtls/library/pkcs12.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * PKCS#12 Personal Information Exchange Syntax - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 - * - * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn - */ - -#include "common.h" - -#if defined(MBEDTLS_PKCS12_C) - -#include "mbedtls/pkcs12.h" -#include "mbedtls/asn1.h" -#if defined(MBEDTLS_CIPHER_C) -#include "mbedtls/cipher.h" -#endif /* MBEDTLS_CIPHER_C */ -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#include "psa_util_internal.h" - -#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C) - -static int pkcs12_parse_pbe_params(mbedtls_asn1_buf *params, - mbedtls_asn1_buf *salt, int *iterations) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char **p = ¶ms->p; - const unsigned char *end = params->p + params->len; - - /* - * pkcs-12PbeParams ::= SEQUENCE { - * salt OCTET STRING, - * iterations INTEGER - * } - * - */ - if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - if ((ret = mbedtls_asn1_get_tag(p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret); - } - - salt->p = *p; - *p += salt->len; - - if ((ret = mbedtls_asn1_get_int(p, end, iterations)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret); - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -#define PKCS12_MAX_PWDLEN 128 - -static int pkcs12_pbe_derive_key_iv(mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - unsigned char *key, size_t keylen, - unsigned char *iv, size_t ivlen) -{ - int ret, iterations = 0; - mbedtls_asn1_buf salt; - size_t i; - unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; - - if (pwdlen > PKCS12_MAX_PWDLEN) { - return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; - } - - memset(&salt, 0, sizeof(mbedtls_asn1_buf)); - memset(&unipwd, 0, sizeof(unipwd)); - - if ((ret = pkcs12_parse_pbe_params(pbe_params, &salt, - &iterations)) != 0) { - return ret; - } - - for (i = 0; i < pwdlen; i++) { - unipwd[i * 2 + 1] = pwd[i]; - } - - if ((ret = mbedtls_pkcs12_derivation(key, keylen, unipwd, pwdlen * 2 + 2, - salt.p, salt.len, md_type, - MBEDTLS_PKCS12_DERIVE_KEY, iterations)) != 0) { - return ret; - } - - if (iv == NULL || ivlen == 0) { - return 0; - } - - if ((ret = mbedtls_pkcs12_derivation(iv, ivlen, unipwd, pwdlen * 2 + 2, - salt.p, salt.len, md_type, - MBEDTLS_PKCS12_DERIVE_IV, iterations)) != 0) { - return ret; - } - return 0; -} - -#undef PKCS12_MAX_PWDLEN - -#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7) -int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output, size_t output_size, - size_t *output_len); -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output) -{ - size_t output_len = 0; - - /* We assume caller of the function is providing a big enough output buffer - * so we pass output_size as SIZE_MAX to pass checks, However, no guarantees - * for the output size actually being correct. - */ - return mbedtls_pkcs12_pbe_ext(pbe_params, mode, cipher_type, md_type, - pwd, pwdlen, data, len, output, SIZE_MAX, - &output_len); -} -#endif - -int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode, - mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t len, - unsigned char *output, size_t output_size, - size_t *output_len) -{ - int ret, keylen = 0; - unsigned char key[32]; - unsigned char iv[16]; - const mbedtls_cipher_info_t *cipher_info; - mbedtls_cipher_context_t cipher_ctx; - size_t iv_len = 0; - size_t finish_olen = 0; - unsigned int padlen = 0; - - if (pwd == NULL && pwdlen != 0) { - return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; - } - - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) { - return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE; - } - - keylen = (int) mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; - - if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) { - if (output_size < len) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - } - - if (mode == MBEDTLS_PKCS12_PBE_ENCRYPT) { - padlen = cipher_info->block_size - (len % cipher_info->block_size); - if (output_size < (len + padlen)) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - } - - iv_len = mbedtls_cipher_info_get_iv_size(cipher_info); - if ((ret = pkcs12_pbe_derive_key_iv(pbe_params, md_type, pwd, pwdlen, - key, keylen, - iv, iv_len)) != 0) { - return ret; - } - - mbedtls_cipher_init(&cipher_ctx); - - if ((ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info)) != 0) { - goto exit; - } - - if ((ret = mbedtls_cipher_setkey(&cipher_ctx, key, 8 * keylen, - (mbedtls_operation_t) mode)) != 0) { - goto exit; - } - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - { - /* PKCS12 uses CBC with PKCS7 padding */ - mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7; -#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7) - /* For historical reasons, when decrypting, this function works when - * decrypting even when support for PKCS7 padding is disabled. In this - * case, it ignores the padding, and so will never report a - * password mismatch. - */ - if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) { - padding = MBEDTLS_PADDING_NONE; - } -#endif - if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) { - goto exit; - } - } -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - - ret = mbedtls_cipher_crypt(&cipher_ctx, iv, iv_len, data, len, output, &finish_olen); - if (ret == MBEDTLS_ERR_CIPHER_INVALID_PADDING) { - ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; - } - - *output_len += finish_olen; - -exit: - mbedtls_platform_zeroize(key, sizeof(key)); - mbedtls_platform_zeroize(iv, sizeof(iv)); - mbedtls_cipher_free(&cipher_ctx); - - return ret; -} - -#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C */ - -static void pkcs12_fill_buffer(unsigned char *data, size_t data_len, - const unsigned char *filler, size_t fill_len) -{ - unsigned char *p = data; - size_t use_len; - - if (filler != NULL && fill_len != 0) { - while (data_len > 0) { - use_len = (data_len > fill_len) ? fill_len : data_len; - memcpy(p, filler, use_len); - p += use_len; - data_len -= use_len; - } - } else { - /* If either of the above are not true then clearly there is nothing - * that this function can do. The function should *not* be called - * under either of those circumstances, as you could end up with an - * incorrect output but for safety's sake, leaving the check in as - * otherwise we could end up with memory corruption.*/ - } -} - - -static int calculate_hashes(mbedtls_md_type_t md_type, int iterations, - unsigned char *diversifier, unsigned char *salt_block, - unsigned char *pwd_block, unsigned char *hash_output, int use_salt, - int use_password, size_t hlen, size_t v) -{ - int ret = -1; - size_t i; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - md_info = mbedtls_md_info_from_type(md_type); - if (md_info == NULL) { - return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE; - } - - mbedtls_md_init(&md_ctx); - - if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { - return ret; - } - // Calculate hash( diversifier || salt_block || pwd_block ) - if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { - goto exit; - } - - if ((ret = mbedtls_md_update(&md_ctx, diversifier, v)) != 0) { - goto exit; - } - - if (use_salt != 0) { - if ((ret = mbedtls_md_update(&md_ctx, salt_block, v)) != 0) { - goto exit; - } - } - - if (use_password != 0) { - if ((ret = mbedtls_md_update(&md_ctx, pwd_block, v)) != 0) { - goto exit; - } - } - - if ((ret = mbedtls_md_finish(&md_ctx, hash_output)) != 0) { - goto exit; - } - - // Perform remaining ( iterations - 1 ) recursive hash calculations - for (i = 1; i < (size_t) iterations; i++) { - if ((ret = mbedtls_md(md_info, hash_output, hlen, hash_output)) - != 0) { - goto exit; - } - } - -exit: - mbedtls_md_free(&md_ctx); - return ret; -} - - -int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *salt, size_t saltlen, - mbedtls_md_type_t md_type, int id, int iterations) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned int j; - - unsigned char diversifier[128]; - unsigned char salt_block[128], pwd_block[128], hash_block[128] = { 0 }; - unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; - unsigned char *p; - unsigned char c; - int use_password = 0; - int use_salt = 0; - - size_t hlen, use_len, v, i; - - // This version only allows max of 64 bytes of password or salt - if (datalen > 128 || pwdlen > 64 || saltlen > 64) { - return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; - } - - if (pwd == NULL && pwdlen != 0) { - return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; - } - - if (salt == NULL && saltlen != 0) { - return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA; - } - - use_password = (pwd && pwdlen != 0); - use_salt = (salt && saltlen != 0); - - hlen = mbedtls_md_get_size_from_type(md_type); - - if (hlen <= 32) { - v = 64; - } else { - v = 128; - } - - memset(diversifier, (unsigned char) id, v); - - if (use_salt != 0) { - pkcs12_fill_buffer(salt_block, v, salt, saltlen); - } - - if (use_password != 0) { - pkcs12_fill_buffer(pwd_block, v, pwd, pwdlen); - } - - p = data; - while (datalen > 0) { - if (calculate_hashes(md_type, iterations, diversifier, salt_block, - pwd_block, hash_output, use_salt, use_password, hlen, - v) != 0) { - goto exit; - } - - use_len = (datalen > hlen) ? hlen : datalen; - memcpy(p, hash_output, use_len); - datalen -= use_len; - p += use_len; - - if (datalen == 0) { - break; - } - - // Concatenating copies of hash_output into hash_block (B) - pkcs12_fill_buffer(hash_block, v, hash_output, hlen); - - // B += 1 - for (i = v; i > 0; i--) { - if (++hash_block[i - 1] != 0) { - break; - } - } - - if (use_salt != 0) { - // salt_block += B - c = 0; - for (i = v; i > 0; i--) { - j = salt_block[i - 1] + hash_block[i - 1] + c; - c = MBEDTLS_BYTE_1(j); - salt_block[i - 1] = MBEDTLS_BYTE_0(j); - } - } - - if (use_password != 0) { - // pwd_block += B - c = 0; - for (i = v; i > 0; i--) { - j = pwd_block[i - 1] + hash_block[i - 1] + c; - c = MBEDTLS_BYTE_1(j); - pwd_block[i - 1] = MBEDTLS_BYTE_0(j); - } - } - } - - ret = 0; - -exit: - mbedtls_platform_zeroize(salt_block, sizeof(salt_block)); - mbedtls_platform_zeroize(pwd_block, sizeof(pwd_block)); - mbedtls_platform_zeroize(hash_block, sizeof(hash_block)); - mbedtls_platform_zeroize(hash_output, sizeof(hash_output)); - - return ret; -} - -#endif /* MBEDTLS_PKCS12_C */ diff --git a/vendor/mbedtls/library/pkcs5.c b/vendor/mbedtls/library/pkcs5.c deleted file mode 100644 index c6c53054b..000000000 --- a/vendor/mbedtls/library/pkcs5.c +++ /dev/null @@ -1,500 +0,0 @@ -/** - * \file pkcs5.c - * - * \brief PKCS#5 functions - * - * \author Mathias Olsson - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * PKCS#5 includes PBKDF2 and more - * - * http://tools.ietf.org/html/rfc2898 (Specification) - * http://tools.ietf.org/html/rfc6070 (Test vectors) - */ - -#include "common.h" - -#if defined(MBEDTLS_PKCS5_C) - -#include "mbedtls/pkcs5.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" -#if defined(MBEDTLS_CIPHER_C) -#include "mbedtls/cipher.h" -#endif /* MBEDTLS_CIPHER_C */ -#include "mbedtls/oid.h" -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#include - -#include "mbedtls/platform.h" - -#include "psa_util_internal.h" - -#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C) -static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params, - mbedtls_asn1_buf *salt, int *iterations, - int *keylen, mbedtls_md_type_t *md_type) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_asn1_buf prf_alg_oid; - unsigned char *p = params->p; - const unsigned char *end = params->p + params->len; - - if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - /* - * PBKDF2-params ::= SEQUENCE { - * salt OCTET STRING, - * iterationCount INTEGER, - * keyLength INTEGER OPTIONAL - * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1 - * } - * - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &salt->len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); - } - - salt->p = p; - p += salt->len; - - if ((ret = mbedtls_asn1_get_int(&p, end, iterations)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); - } - - if (p == end) { - return 0; - } - - if ((ret = mbedtls_asn1_get_int(&p, end, keylen)) != 0) { - if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); - } - } - - if (p == end) { - return 0; - } - - if ((ret = mbedtls_asn1_get_alg_null(&p, end, &prf_alg_oid)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); - } - - if (mbedtls_oid_get_md_hmac(&prf_alg_oid, md_type) != 0) { - return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE; - } - - if (p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7) -int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output, size_t output_size, - size_t *output_len); -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output) -{ - size_t output_len = 0; - - /* We assume caller of the function is providing a big enough output buffer - * so we pass output_size as SIZE_MAX to pass checks, However, no guarantees - * for the output size actually being correct. - */ - return mbedtls_pkcs5_pbes2_ext(pbe_params, mode, pwd, pwdlen, data, - datalen, output, SIZE_MAX, &output_len); -} -#endif - -int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode, - const unsigned char *pwd, size_t pwdlen, - const unsigned char *data, size_t datalen, - unsigned char *output, size_t output_size, - size_t *output_len) -{ - int ret, iterations = 0, keylen = 0; - unsigned char *p, *end; - mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params; - mbedtls_asn1_buf salt; - mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; - unsigned char key[32], iv[32]; - const mbedtls_cipher_info_t *cipher_info; - mbedtls_cipher_type_t cipher_alg; - mbedtls_cipher_context_t cipher_ctx; - unsigned int padlen = 0; - - p = pbe_params->p; - end = p + pbe_params->len; - - /* - * PBES2-params ::= SEQUENCE { - * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, - * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} - * } - */ - if (pbe_params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - if ((ret = mbedtls_asn1_get_alg(&p, end, &kdf_alg_oid, - &kdf_alg_params)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); - } - - // Only PBKDF2 supported at the moment - // - if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid) != 0) { - return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE; - } - - if ((ret = pkcs5_parse_pbkdf2_params(&kdf_alg_params, - &salt, &iterations, &keylen, - &md_type)) != 0) { - return ret; - } - - if ((ret = mbedtls_asn1_get_alg(&p, end, &enc_scheme_oid, - &enc_scheme_params)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); - } - - if (mbedtls_oid_get_cipher_alg(&enc_scheme_oid, &cipher_alg) != 0) { - return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE; - } - - cipher_info = mbedtls_cipher_info_from_type(cipher_alg); - if (cipher_info == NULL) { - return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE; - } - - /* - * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored - * since it is optional and we don't know if it was set or not - */ - keylen = (int) mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; - - if (enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING || - enc_scheme_params.len != mbedtls_cipher_info_get_iv_size(cipher_info)) { - return MBEDTLS_ERR_PKCS5_INVALID_FORMAT; - } - - if (mode == MBEDTLS_PKCS5_DECRYPT) { - if (output_size < datalen) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - } - - if (mode == MBEDTLS_PKCS5_ENCRYPT) { - padlen = cipher_info->block_size - (datalen % cipher_info->block_size); - if (output_size < (datalen + padlen)) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - } - - mbedtls_cipher_init(&cipher_ctx); - - memcpy(iv, enc_scheme_params.p, enc_scheme_params.len); - - if ((ret = mbedtls_pkcs5_pbkdf2_hmac_ext(md_type, pwd, pwdlen, salt.p, - salt.len, iterations, keylen, - key)) != 0) { - goto exit; - } - - if ((ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info)) != 0) { - goto exit; - } - - if ((ret = mbedtls_cipher_setkey(&cipher_ctx, key, 8 * keylen, - (mbedtls_operation_t) mode)) != 0) { - goto exit; - } - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - { - /* PKCS5 uses CBC with PKCS7 padding (which is the same as - * "PKCS5 padding" except that it's typically only called PKCS5 - * with 64-bit-block ciphers). - */ - mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7; -#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7) - /* For historical reasons, when decrypting, this function works when - * decrypting even when support for PKCS7 padding is disabled. In this - * case, it ignores the padding, and so will never report a - * password mismatch. - */ - if (mode == MBEDTLS_DECRYPT) { - padding = MBEDTLS_PADDING_NONE; - } -#endif - if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) { - goto exit; - } - } -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - if ((ret = mbedtls_cipher_crypt(&cipher_ctx, iv, enc_scheme_params.len, - data, datalen, output, output_len)) != 0) { - ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH; - } - -exit: - mbedtls_cipher_free(&cipher_ctx); - - return ret; -} -#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C */ - -static int pkcs5_pbkdf2_hmac(mbedtls_md_context_t *ctx, - const unsigned char *password, - size_t plen, const unsigned char *salt, size_t slen, - unsigned int iteration_count, - uint32_t key_length, unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned int i; - unsigned char md1[MBEDTLS_MD_MAX_SIZE]; - unsigned char work[MBEDTLS_MD_MAX_SIZE]; - unsigned char md_size = mbedtls_md_get_size(ctx->md_info); - size_t use_len; - unsigned char *out_p = output; - unsigned char counter[4]; - - memset(counter, 0, 4); - counter[3] = 1; - -#if UINT_MAX > 0xFFFFFFFF - if (iteration_count > 0xFFFFFFFF) { - return MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA; - } -#endif - - if ((ret = mbedtls_md_hmac_starts(ctx, password, plen)) != 0) { - return ret; - } - while (key_length) { - // U1 ends up in work - // - if ((ret = mbedtls_md_hmac_update(ctx, salt, slen)) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_md_hmac_update(ctx, counter, 4)) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_md_hmac_finish(ctx, work)) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_md_hmac_reset(ctx)) != 0) { - goto cleanup; - } - - memcpy(md1, work, md_size); - - for (i = 1; i < iteration_count; i++) { - // U2 ends up in md1 - // - if ((ret = mbedtls_md_hmac_update(ctx, md1, md_size)) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_md_hmac_finish(ctx, md1)) != 0) { - goto cleanup; - } - - if ((ret = mbedtls_md_hmac_reset(ctx)) != 0) { - goto cleanup; - } - - // U1 xor U2 - // - mbedtls_xor(work, work, md1, md_size); - } - - use_len = (key_length < md_size) ? key_length : md_size; - memcpy(out_p, work, use_len); - - key_length -= (uint32_t) use_len; - out_p += use_len; - - for (i = 4; i > 0; i--) { - if (++counter[i - 1] != 0) { - break; - } - } - } - -cleanup: - /* Zeroise buffers to clear sensitive data from memory. */ - mbedtls_platform_zeroize(work, MBEDTLS_MD_MAX_SIZE); - mbedtls_platform_zeroize(md1, MBEDTLS_MD_MAX_SIZE); - - return ret; -} - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_pkcs5_pbkdf2_hmac(mbedtls_md_context_t *ctx, - const unsigned char *password, - size_t plen, const unsigned char *salt, size_t slen, - unsigned int iteration_count, - uint32_t key_length, unsigned char *output) -{ - return pkcs5_pbkdf2_hmac(ctx, password, plen, salt, slen, iteration_count, - key_length, output); -} -#endif - -int mbedtls_pkcs5_pbkdf2_hmac_ext(mbedtls_md_type_t md_alg, - const unsigned char *password, - size_t plen, const unsigned char *salt, size_t slen, - unsigned int iteration_count, - uint32_t key_length, unsigned char *output) -{ - mbedtls_md_context_t md_ctx; - const mbedtls_md_info_t *md_info = NULL; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE; - } - - mbedtls_md_init(&md_ctx); - - if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) { - goto exit; - } - ret = pkcs5_pbkdf2_hmac(&md_ctx, password, plen, salt, slen, - iteration_count, key_length, output); -exit: - mbedtls_md_free(&md_ctx); - return ret; -} - -#if defined(MBEDTLS_SELF_TEST) - -#if !defined(MBEDTLS_MD_CAN_SHA1) -int mbedtls_pkcs5_self_test(int verbose) -{ - if (verbose != 0) { - mbedtls_printf(" PBKDF2 (SHA1): skipped\n\n"); - } - - return 0; -} -#else - -#define MAX_TESTS 6 - -static const size_t plen_test_data[MAX_TESTS] = -{ 8, 8, 8, 24, 9 }; - -static const unsigned char password_test_data[MAX_TESTS][32] = -{ - "password", - "password", - "password", - "passwordPASSWORDpassword", - "pass\0word", -}; - -static const size_t slen_test_data[MAX_TESTS] = -{ 4, 4, 4, 36, 5 }; - -static const unsigned char salt_test_data[MAX_TESTS][40] = -{ - "salt", - "salt", - "salt", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - "sa\0lt", -}; - -static const uint32_t it_cnt_test_data[MAX_TESTS] = -{ 1, 2, 4096, 4096, 4096 }; - -static const uint32_t key_len_test_data[MAX_TESTS] = -{ 20, 20, 20, 25, 16 }; - -static const unsigned char result_key_test_data[MAX_TESTS][32] = -{ - { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, - 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, - 0x2f, 0xe0, 0x37, 0xa6 }, - { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, - 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, - 0xd8, 0xde, 0x89, 0x57 }, - { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, - 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, - 0x65, 0xa4, 0x29, 0xc1 }, - { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, - 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, - 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, - 0x38 }, - { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, - 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 }, -}; - -int mbedtls_pkcs5_self_test(int verbose) -{ - int ret, i; - unsigned char key[64]; - - for (i = 0; i < MAX_TESTS; i++) { - if (verbose != 0) { - mbedtls_printf(" PBKDF2 (SHA1) #%d: ", i); - } - - ret = mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, password_test_data[i], - plen_test_data[i], salt_test_data[i], - slen_test_data[i], it_cnt_test_data[i], - key_len_test_data[i], key); - if (ret != 0 || - memcmp(result_key_test_data[i], key, key_len_test_data[i]) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto exit; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - -exit: - return ret; -} -#endif /* MBEDTLS_MD_CAN_SHA1 */ - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_PKCS5_C */ diff --git a/vendor/mbedtls/library/pkcs7.c b/vendor/mbedtls/library/pkcs7.c deleted file mode 100644 index 3aac662ba..000000000 --- a/vendor/mbedtls/library/pkcs7.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#include "common.h" - -#include "mbedtls/build_info.h" -#if defined(MBEDTLS_PKCS7_C) -#include "mbedtls/pkcs7.h" -#include "x509_internal.h" -#include "mbedtls/asn1.h" -#include "mbedtls/x509_crt.h" -#include "mbedtls/x509_crl.h" -#include "mbedtls/oid.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_FS_IO) -#include -#include -#endif - -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include -#endif - -/** - * Initializes the mbedtls_pkcs7 structure. - */ -void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7) -{ - memset(pkcs7, 0, sizeof(*pkcs7)); -} - -static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end, - size_t *len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_CONTEXT_SPECIFIC); - if (ret != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); - } else if ((size_t) (end - *p) != *len) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return ret; -} - -/** - * version Version - * Version ::= INTEGER - **/ -static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_asn1_get_int(p, end, ver); - if (ret != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret); - } - - /* If version != 1, return invalid version */ - if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) { - ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION; - } - - return ret; -} - -/** - * ContentInfo ::= SEQUENCE { - * contentType ContentType, - * content - * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } - **/ -static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end, - unsigned char **seq_end, - mbedtls_pkcs7_buf *pkcs7) -{ - size_t len = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *start = *p; - - ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_SEQUENCE); - if (ret != 0) { - *p = start; - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); - } - *seq_end = *p + len; - ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID); - if (ret != 0) { - *p = start; - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); - } - - pkcs7->tag = MBEDTLS_ASN1_OID; - pkcs7->len = len; - pkcs7->p = *p; - *p += len; - - return ret; -} - -/** - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * - * This is from x509.h - **/ -static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end, - mbedtls_x509_buf *alg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret); - } - - return ret; -} - -/** - * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier - **/ -static int pkcs7_get_digest_algorithm_set(unsigned char **p, - unsigned char *end, - mbedtls_x509_buf *alg) -{ - size_t len = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_SET); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret); - } - - end = *p + len; - - ret = mbedtls_asn1_get_alg_null(p, end, alg); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret); - } - - /** For now, it assumes there is only one digest algorithm specified **/ - if (*p != end) { - return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; - } - - return 0; -} - -/** - * certificates :: SET OF ExtendedCertificateOrCertificate, - * ExtendedCertificateOrCertificate ::= CHOICE { - * certificate Certificate -- x509, - * extendedCertificate[0] IMPLICIT ExtendedCertificate } - * Return number of certificates added to the signed data, - * 0 or higher is valid. - * Return negative error code for failure. - **/ -static int pkcs7_get_certificates(unsigned char **p, unsigned char *end, - mbedtls_x509_crt *certs) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len1 = 0; - size_t len2 = 0; - unsigned char *end_set, *end_cert, *start; - - ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_CONTEXT_SPECIFIC); - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return 0; - } - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); - } - start = *p; - end_set = *p + len1; - - ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_SEQUENCE); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret); - } - - end_cert = *p + len2; - - /* - * This is to verify that there is only one signer certificate. It seems it is - * not easy to differentiate between the chain vs different signer's certificate. - * So, we support only the root certificate and the single signer. - * The behaviour would be improved with addition of multiple signer support. - */ - if (end_cert != end_set) { - return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; - } - - if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) { - return MBEDTLS_ERR_PKCS7_INVALID_CERT; - } - - *p = end_cert; - - /* - * Since in this version we strictly support single certificate, and reaching - * here implies we have parsed successfully, we return 1. - */ - return 1; -} - -/** - * EncryptedDigest ::= OCTET STRING - **/ -static int pkcs7_get_signature(unsigned char **p, unsigned char *end, - mbedtls_pkcs7_buf *signature) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING); - if (ret != 0) { - return ret; - } - - signature->tag = MBEDTLS_ASN1_OCTET_STRING; - signature->len = len; - signature->p = *p; - - *p = *p + len; - - return 0; -} - -static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer) -{ - mbedtls_x509_name *name_cur; - mbedtls_x509_name *name_prv; - - if (signer == NULL) { - return; - } - - name_cur = signer->issuer.next; - while (name_cur != NULL) { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_free(name_prv); - } - signer->issuer.next = NULL; -} - -/** - * SignerInfo ::= SEQUENCE { - * version Version; - * issuerAndSerialNumber IssuerAndSerialNumber, - * digestAlgorithm DigestAlgorithmIdentifier, - * authenticatedAttributes - * [0] IMPLICIT Attributes OPTIONAL, - * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, - * encryptedDigest EncryptedDigest, - * unauthenticatedAttributes - * [1] IMPLICIT Attributes OPTIONAL, - * Returns 0 if the signerInfo is valid. - * Return negative error code for failure. - * Structure must not contain vales for authenticatedAttributes - * and unauthenticatedAttributes. - **/ -static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end, - mbedtls_pkcs7_signer_info *signer, - mbedtls_x509_buf *alg) -{ - unsigned char *end_signer, *end_issuer_and_sn; - int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_SEQUENCE); - if (asn1_ret != 0) { - goto out; - } - - end_signer = *p + len; - - ret = pkcs7_get_version(p, end_signer, &signer->version); - if (ret != 0) { - goto out; - } - - asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - if (asn1_ret != 0) { - goto out; - } - - end_issuer_and_sn = *p + len; - /* Parsing IssuerAndSerialNumber */ - signer->issuer_raw.p = *p; - - asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - if (asn1_ret != 0) { - goto out; - } - - ret = mbedtls_x509_get_name(p, *p + len, &signer->issuer); - if (ret != 0) { - goto out; - } - - signer->issuer_raw.len = (size_t) (*p - signer->issuer_raw.p); - - ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial); - if (ret != 0) { - goto out; - } - - /* ensure no extra or missing bytes */ - if (*p != end_issuer_and_sn) { - ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO; - goto out; - } - - ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier); - if (ret != 0) { - goto out; - } - - /* Check that the digest algorithm used matches the one provided earlier */ - if (signer->alg_identifier.tag != alg->tag || - signer->alg_identifier.len != alg->len || - memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) { - ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO; - goto out; - } - - /* Assume authenticatedAttributes is nonexistent */ - ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier); - if (ret != 0) { - goto out; - } - - ret = pkcs7_get_signature(p, end_signer, &signer->sig); - if (ret != 0) { - goto out; - } - - /* Do not permit any unauthenticated attributes */ - if (*p != end_signer) { - ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO; - } - -out: - if (asn1_ret != 0 || ret != 0) { - pkcs7_free_signer_info(signer); - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, - asn1_ret); - } - - return ret; -} - -/** - * SignerInfos ::= SET of SignerInfo - * Return number of signers added to the signed data, - * 0 or higher is valid. - * Return negative error code for failure. - **/ -static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end, - mbedtls_pkcs7_signer_info *signers_set, - mbedtls_x509_buf *digest_alg) -{ - unsigned char *end_set; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int count = 0; - size_t len = 0; - - ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_SET); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret); - } - - /* Detect zero signers */ - if (len == 0) { - return 0; - } - - end_set = *p + len; - - ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg); - if (ret != 0) { - return ret; - } - count++; - - mbedtls_pkcs7_signer_info *prev = signers_set; - while (*p != end_set) { - mbedtls_pkcs7_signer_info *signer = - mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info)); - if (!signer) { - ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED; - goto cleanup; - } - - ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg); - if (ret != 0) { - mbedtls_free(signer); - goto cleanup; - } - prev->next = signer; - prev = signer; - count++; - } - - return count; - -cleanup: - pkcs7_free_signer_info(signers_set); - mbedtls_pkcs7_signer_info *signer = signers_set->next; - while (signer != NULL) { - prev = signer; - signer = signer->next; - pkcs7_free_signer_info(prev); - mbedtls_free(prev); - } - signers_set->next = NULL; - return ret; -} - -/** - * SignedData ::= SEQUENCE { - * version Version, - * digestAlgorithms DigestAlgorithmIdentifiers, - * contentInfo ContentInfo, - * certificates - * [0] IMPLICIT ExtendedCertificatesAndCertificates - * OPTIONAL, - * crls - * [0] IMPLICIT CertificateRevocationLists OPTIONAL, - * signerInfos SignerInfos } - */ -static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, - mbedtls_pkcs7_signed_data *signed_data) -{ - unsigned char *p = buf; - unsigned char *end = buf + buflen; - unsigned char *end_content_info = NULL; - size_t len = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_type_t md_alg; - - ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_SEQUENCE); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); - } - - if (p + len != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* Get version of signed data */ - ret = pkcs7_get_version(&p, end, &signed_data->version); - if (ret != 0) { - return ret; - } - - /* Get digest algorithm */ - ret = pkcs7_get_digest_algorithm_set(&p, end, - &signed_data->digest_alg_identifiers); - if (ret != 0) { - return ret; - } - - ret = mbedtls_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg); - if (ret != 0) { - return MBEDTLS_ERR_PKCS7_INVALID_ALG; - } - - mbedtls_pkcs7_buf content_type; - memset(&content_type, 0, sizeof(content_type)); - ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type); - if (ret != 0) { - return ret; - } - if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) { - return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO; - } - - if (p != end_content_info) { - /* Determine if valid content is present */ - ret = mbedtls_asn1_get_tag(&p, - end_content_info, - &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); - } - p += len; - if (p != end_content_info) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); - } - /* Valid content is present - this is not supported */ - return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; - } - - /* Look for certificates, there may or may not be any */ - mbedtls_x509_crt_init(&signed_data->certs); - ret = pkcs7_get_certificates(&p, end, &signed_data->certs); - if (ret < 0) { - return ret; - } - - signed_data->no_of_certs = ret; - - /* - * Currently CRLs are not supported. If CRL exist, the parsing will fail - * at next step of getting signers info and return error as invalid - * signer info. - */ - - signed_data->no_of_crls = 0; - - /* Get signers info */ - ret = pkcs7_get_signers_info_set(&p, - end, - &signed_data->signers, - &signed_data->digest_alg_identifiers); - if (ret < 0) { - return ret; - } - - signed_data->no_of_signers = ret; - - /* Don't permit trailing data */ - if (p != end) { - return MBEDTLS_ERR_PKCS7_INVALID_FORMAT; - } - - return 0; -} - -int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf, - const size_t buflen) -{ - unsigned char *p; - unsigned char *end; - size_t len = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (pkcs7 == NULL) { - return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; - } - - /* make an internal copy of the buffer for parsing */ - pkcs7->raw.p = p = mbedtls_calloc(1, buflen); - if (pkcs7->raw.p == NULL) { - ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED; - goto out; - } - memcpy(p, buf, buflen); - pkcs7->raw.len = buflen; - end = p + buflen; - - ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_SEQUENCE); - if (ret != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); - goto out; - } - - if ((size_t) (end - p) != len) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - goto out; - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) { - if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - goto out; - } - p = pkcs7->raw.p; - len = buflen; - goto try_data; - } - - if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) { - /* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */ - if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len) - || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len) - || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len) - || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len) - || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) { - /* OID is valid according to the spec, but unsupported */ - ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; - } else { - /* OID is invalid according to the spec */ - ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; - } - goto out; - } - - p += len; - - ret = pkcs7_get_next_content_len(&p, end, &len); - if (ret != 0) { - goto out; - } - - /* ensure no extra/missing data */ - if (p + len != end) { - ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; - goto out; - } - -try_data: - ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data); - if (ret != 0) { - goto out; - } - - ret = MBEDTLS_PKCS7_SIGNED_DATA; - -out: - if (ret < 0) { - mbedtls_pkcs7_free(pkcs7); - } - - return ret; -} - -static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7, - const mbedtls_x509_crt *cert, - const unsigned char *data, - size_t datalen, - const int is_data_hash) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *hash; - mbedtls_pk_context pk_cxt = cert->pk; - const mbedtls_md_info_t *md_info; - mbedtls_md_type_t md_alg; - mbedtls_pkcs7_signer_info *signer; - - if (pkcs7->signed_data.no_of_signers == 0) { - return MBEDTLS_ERR_PKCS7_INVALID_CERT; - } - - if (mbedtls_x509_time_is_past(&cert->valid_to) || - mbedtls_x509_time_is_future(&cert->valid_from)) { - return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID; - } - - ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg); - if (ret != 0) { - return ret; - } - - md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - } - - hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1); - if (hash == NULL) { - return MBEDTLS_ERR_PKCS7_ALLOC_FAILED; - } - - /* BEGIN must free hash before jumping out */ - if (is_data_hash) { - if (datalen != mbedtls_md_get_size(md_info)) { - ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - } else { - memcpy(hash, data, datalen); - } - } else { - ret = mbedtls_md(md_info, data, datalen, hash); - } - if (ret != 0) { - mbedtls_free(hash); - return MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - } - - /* assume failure */ - ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - - /* - * Potential TODOs - * Currently we iterate over all signers and return success if any of them - * verify. - * - * However, we could make this better by checking against the certificate's - * identification and SignerIdentifier fields first. That would also allow - * us to distinguish between 'no signature for key' and 'signature for key - * failed to validate'. - */ - for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) { - ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash, - mbedtls_md_get_size(md_info), - signer->sig.p, signer->sig.len); - - if (ret == 0) { - break; - } - } - - mbedtls_free(hash); - /* END must free hash before jumping out */ - return ret; -} - -int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7, - const mbedtls_x509_crt *cert, - const unsigned char *data, - size_t datalen) -{ - if (data == NULL) { - return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; - } - return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0); -} - -int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7, - const mbedtls_x509_crt *cert, - const unsigned char *hash, - size_t hashlen) -{ - if (hash == NULL) { - return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; - } - return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1); -} - -/* - * Unallocate all pkcs7 data - */ -void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7) -{ - mbedtls_pkcs7_signer_info *signer_cur; - mbedtls_pkcs7_signer_info *signer_prev; - - if (pkcs7 == NULL || pkcs7->raw.p == NULL) { - return; - } - - mbedtls_free(pkcs7->raw.p); - - mbedtls_x509_crt_free(&pkcs7->signed_data.certs); - mbedtls_x509_crl_free(&pkcs7->signed_data.crl); - - signer_cur = pkcs7->signed_data.signers.next; - pkcs7_free_signer_info(&pkcs7->signed_data.signers); - while (signer_cur != NULL) { - signer_prev = signer_cur; - signer_cur = signer_prev->next; - pkcs7_free_signer_info(signer_prev); - mbedtls_free(signer_prev); - } - - pkcs7->raw.p = NULL; -} - -#endif diff --git a/vendor/mbedtls/library/pkparse.c b/vendor/mbedtls/library/pkparse.c deleted file mode 100644 index 4f6ee1398..000000000 --- a/vendor/mbedtls/library/pkparse.c +++ /dev/null @@ -1,1392 +0,0 @@ -/* - * Public Key layer for parsing key files and structures - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PK_PARSE_C) - -#include "mbedtls/pk.h" -#include "mbedtls/asn1.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/platform.h" -#include "mbedtls/error.h" -#include "mbedtls/ecp.h" -#include "pk_internal.h" - -#include - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -#include "psa/crypto.h" -#endif - -/* Key types */ -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#include "rsa_internal.h" -#endif - -/* Extended formats */ -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif -#if defined(MBEDTLS_PKCS5_C) -#include "mbedtls/pkcs5.h" -#endif -#if defined(MBEDTLS_PKCS12_C) -#include "mbedtls/pkcs12.h" -#endif - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - -/*********************************************************************** - * - * Low-level ECC parsing: optional support for SpecifiedECDomain - * - * There are two functions here that are used by the rest of the code: - * - pk_ecc_tag_is_speficied_ec_domain() - * - pk_ecc_group_id_from_specified() - * - * All the other functions are internal to this section. - * - * The two "public" functions have a dummy variant provided - * in configs without MBEDTLS_PK_PARSE_EC_EXTENDED. This acts as an - * abstraction layer for this macro, which should not appear outside - * this section. - * - **********************************************************************/ - -#if !defined(MBEDTLS_PK_PARSE_EC_EXTENDED) -/* See the "real" version for documentation */ -static int pk_ecc_tag_is_specified_ec_domain(int tag) -{ - (void) tag; - return 0; -} - -/* See the "real" version for documentation */ -static int pk_ecc_group_id_from_specified(const mbedtls_asn1_buf *params, - mbedtls_ecp_group_id *grp_id) -{ - (void) params; - (void) grp_id; - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -} -#else /* MBEDTLS_PK_PARSE_EC_EXTENDED */ -/* - * Tell if the passed tag might be the start of SpecifiedECDomain - * (that is, a sequence). - */ -static int pk_ecc_tag_is_specified_ec_domain(int tag) -{ - return tag == (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -} - -/* - * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. - * WARNING: the resulting group should only be used with - * pk_ecc_group_id_from_specified(), since its base point may not be set correctly - * if it was encoded compressed. - * - * SpecifiedECDomain ::= SEQUENCE { - * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), - * fieldID FieldID {{FieldTypes}}, - * curve Curve, - * base ECPoint, - * order INTEGER, - * cofactor INTEGER OPTIONAL, - * hash HashAlgorithm OPTIONAL, - * ... - * } - * - * We only support prime-field as field type, and ignore hash and cofactor. - */ -static int pk_group_from_specified(const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = params->p; - const unsigned char *const end = params->p + params->len; - const unsigned char *end_field, *end_curve; - size_t len; - int ver; - - /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ - if ((ret = mbedtls_asn1_get_int(&p, end, &ver)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if (ver < 1 || ver > 3) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - - /* - * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field - * fieldType FIELD-ID.&id({IOSet}), - * parameters FIELD-ID.&Type({IOSet}{@fieldType}) - * } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return ret; - } - - end_field = p + len; - - /* - * FIELD-ID ::= TYPE-IDENTIFIER - * FieldTypes FIELD-ID ::= { - * { Prime-p IDENTIFIED BY prime-field } | - * { Characteristic-two IDENTIFIED BY characteristic-two-field } - * } - * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end_field, &len, MBEDTLS_ASN1_OID)) != 0) { - return ret; - } - - if (len != MBEDTLS_OID_SIZE(MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD) || - memcmp(p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len) != 0) { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } - - p += len; - - /* Prime-p ::= INTEGER -- Field of size p. */ - if ((ret = mbedtls_asn1_get_mpi(&p, end_field, &grp->P)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - grp->pbits = mbedtls_mpi_bitlen(&grp->P); - - if (p != end_field) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* - * Curve ::= SEQUENCE { - * a FieldElement, - * b FieldElement, - * seed BIT STRING OPTIONAL - * -- Shall be present if used in SpecifiedECDomain - * -- with version equal to ecdpVer2 or ecdpVer3 - * } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return ret; - } - - end_curve = p + len; - - /* - * FieldElement ::= OCTET STRING - * containing an integer in the case of a prime field - */ - if ((ret = mbedtls_asn1_get_tag(&p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0 || - (ret = mbedtls_mpi_read_binary(&grp->A, p, len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - p += len; - - if ((ret = mbedtls_asn1_get_tag(&p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0 || - (ret = mbedtls_mpi_read_binary(&grp->B, p, len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - p += len; - - /* Ignore seed BIT STRING OPTIONAL */ - if ((ret = mbedtls_asn1_get_tag(&p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING)) == 0) { - p += len; - } - - if (p != end_curve) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* - * ECPoint ::= OCTET STRING - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if ((ret = mbedtls_ecp_point_read_binary(grp, &grp->G, - (const unsigned char *) p, len)) != 0) { - /* - * If we can't read the point because it's compressed, cheat by - * reading only the X coordinate and the parity bit of Y. - */ - if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || - (p[0] != 0x02 && p[0] != 0x03) || - len != mbedtls_mpi_size(&grp->P) + 1 || - mbedtls_mpi_read_binary(&grp->G.X, p + 1, len - 1) != 0 || - mbedtls_mpi_lset(&grp->G.Y, p[0] - 2) != 0 || - mbedtls_mpi_lset(&grp->G.Z, 1) != 0) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - } - - p += len; - - /* - * order INTEGER - */ - if ((ret = mbedtls_asn1_get_mpi(&p, end, &grp->N)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - grp->nbits = mbedtls_mpi_bitlen(&grp->N); - - /* - * Allow optional elements by purposefully not enforcing p == end here. - */ - - return 0; -} - -/* - * Find the group id associated with an (almost filled) group as generated by - * pk_group_from_specified(), or return an error if unknown. - */ -static int pk_group_id_from_group(const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id) -{ - int ret = 0; - mbedtls_ecp_group ref; - const mbedtls_ecp_group_id *id; - - mbedtls_ecp_group_init(&ref); - - for (id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++) { - /* Load the group associated to that id */ - mbedtls_ecp_group_free(&ref); - MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ref, *id)); - - /* Compare to the group we were given, starting with easy tests */ - if (grp->pbits == ref.pbits && grp->nbits == ref.nbits && - mbedtls_mpi_cmp_mpi(&grp->P, &ref.P) == 0 && - mbedtls_mpi_cmp_mpi(&grp->A, &ref.A) == 0 && - mbedtls_mpi_cmp_mpi(&grp->B, &ref.B) == 0 && - mbedtls_mpi_cmp_mpi(&grp->N, &ref.N) == 0 && - mbedtls_mpi_cmp_mpi(&grp->G.X, &ref.G.X) == 0 && - mbedtls_mpi_cmp_mpi(&grp->G.Z, &ref.G.Z) == 0 && - /* For Y we may only know the parity bit, so compare only that */ - mbedtls_mpi_get_bit(&grp->G.Y, 0) == mbedtls_mpi_get_bit(&ref.G.Y, 0)) { - break; - } - } - -cleanup: - mbedtls_ecp_group_free(&ref); - - *grp_id = *id; - - if (ret == 0 && *id == MBEDTLS_ECP_DP_NONE) { - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - } - - return ret; -} - -/* - * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID - */ -static int pk_ecc_group_id_from_specified(const mbedtls_asn1_buf *params, - mbedtls_ecp_group_id *grp_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_group grp; - - mbedtls_ecp_group_init(&grp); - - if ((ret = pk_group_from_specified(params, &grp)) != 0) { - goto cleanup; - } - - ret = pk_group_id_from_group(&grp, grp_id); - -cleanup: - /* The API respecting lifecycle for mbedtls_ecp_group struct is - * _init(), _load() and _free(). In pk_ecc_group_id_from_specified() the - * temporary grp breaks that flow and it's members are populated - * by pk_group_id_from_group(). As such mbedtls_ecp_group_free() - * which is assuming a group populated by _setup() may not clean-up - * properly -> Manually free it's members. - */ - mbedtls_mpi_free(&grp.N); - mbedtls_mpi_free(&grp.P); - mbedtls_mpi_free(&grp.A); - mbedtls_mpi_free(&grp.B); - mbedtls_ecp_point_free(&grp.G); - - return ret; -} -#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ - -/*********************************************************************** - * - * Unsorted (yet!) from this point on until the next section header - * - **********************************************************************/ - -/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } - * -- implicitCurve NULL - * } - */ -static int pk_get_ecparams(unsigned char **p, const unsigned char *end, - mbedtls_asn1_buf *params) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (end - *p < 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - /* Acceptable tags: OID for namedCurve, or specifiedECDomain */ - params->tag = **p; - if (params->tag != MBEDTLS_ASN1_OID && - !pk_ecc_tag_is_specified_ec_domain(params->tag)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - if ((ret = mbedtls_asn1_get_tag(p, end, ¶ms->len, params->tag)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - params->p = *p; - *p += params->len; - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Use EC parameters to initialise an EC group - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } - * -- implicitCurve NULL - */ -static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *pk) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_group_id grp_id; - - if (params->tag == MBEDTLS_ASN1_OID) { - if (mbedtls_oid_get_ec_grp(params, &grp_id) != 0) { - return MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE; - } - } else { - ret = pk_ecc_group_id_from_specified(params, &grp_id); - if (ret != 0) { - return ret; - } - } - - return mbedtls_pk_ecc_set_group(pk, grp_id); -} - -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - -/* - * Load an RFC8410 EC key, which doesn't have any parameters - */ -static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params, - mbedtls_ecp_group_id grp_id, - mbedtls_pk_context *pk) -{ - if (params->tag != 0 || params->len != 0) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - - return mbedtls_pk_ecc_set_group(pk, grp_id); -} - -/* - * Parse an RFC 8410 encoded private EC key - * - * CurvePrivateKey ::= OCTET STRING - */ -static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk, - unsigned char *key, size_t keylen, const unsigned char *end, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if ((ret = mbedtls_asn1_get_tag(&key, (key + keylen), &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if (key + len != end) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - - /* - * Load the private key - */ - ret = mbedtls_pk_ecc_set_key(pk, key, len); - if (ret != 0) { - return ret; - } - - /* pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys, - * which never contain a public key. As such, derive the public key - * unconditionally. */ - if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) { - return ret; - } - - return 0; -} -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ - -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -/* Get a PK algorithm identifier - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ -static int pk_get_pk_alg(unsigned char **p, - const unsigned char *end, - mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params, - mbedtls_ecp_group_id *ec_grp_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_asn1_buf alg_oid; - - memset(params, 0, sizeof(mbedtls_asn1_buf)); - - if ((ret = mbedtls_asn1_get_alg(p, end, &alg_oid, params)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_ALG, ret); - } - - ret = mbedtls_oid_get_pk_alg(&alg_oid, pk_alg); -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (ret == MBEDTLS_ERR_OID_NOT_FOUND) { - ret = mbedtls_oid_get_ec_grp_algid(&alg_oid, ec_grp_id); - if (ret == 0) { - *pk_alg = MBEDTLS_PK_ECKEY; - } - } -#else - (void) ec_grp_id; -#endif - if (ret != 0) { - return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - } - - /* - * No parameters with RSA (only for EC) - */ - if (*pk_alg == MBEDTLS_PK_RSA && - ((params->tag != MBEDTLS_ASN1_NULL && params->tag != 0) || - params->len != 0)) { - return MBEDTLS_ERR_PK_INVALID_ALG; - } - - return 0; -} - -/* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ -int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end, - mbedtls_pk_context *pk) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - mbedtls_asn1_buf alg_params; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE; - const mbedtls_pk_info_t *pk_info; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - end = *p + len; - - if ((ret = pk_get_pk_alg(p, end, &pk_alg, &alg_params, &ec_grp_id)) != 0) { - return ret; - } - - if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret); - } - - if (*p + len != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) { - return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - } - - if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0) { - return ret; - } - -#if defined(MBEDTLS_RSA_C) - if (pk_alg == MBEDTLS_PK_RSA) { - ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), *p, (size_t) (end - *p)); - if (ret == 0) { - /* On success all the input has been consumed by the parsing function. */ - *p += end - *p; - } else if ((ret <= MBEDTLS_ERR_ASN1_OUT_OF_DATA) && - (ret >= MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)) { - /* In case of ASN1 error codes add MBEDTLS_ERR_PK_INVALID_PUBKEY. */ - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret); - } else { - ret = MBEDTLS_ERR_PK_INVALID_PUBKEY; - } - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) { -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) { - ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, pk); - } else -#endif - { - ret = pk_use_ecparams(&alg_params, pk); - } - if (ret == 0) { - ret = mbedtls_pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p)); - *p += end - *p; - } - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - - if (ret == 0 && *p != end) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - if (ret != 0) { - mbedtls_pk_free(pk); - } - - return ret; -} - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -/* - * Parse a SEC1 encoded private EC key - */ -static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, - const unsigned char *key, size_t keylen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int version, pubkey_done; - size_t len, d_len; - mbedtls_asn1_buf params = { 0, 0, NULL }; - unsigned char *p = (unsigned char *) key; - unsigned char *d; - unsigned char *end = p + keylen; - unsigned char *end2; - - /* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - end = p + len; - - if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if (version != 1) { - return MBEDTLS_ERR_PK_KEY_INVALID_VERSION; - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - /* Keep a reference to the position fo the private key. It will be used - * later in this function. */ - d = p; - d_len = len; - - p += len; - - pubkey_done = 0; - if (p != end) { - /* - * Is 'parameters' present? - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 0)) == 0) { - if ((ret = pk_get_ecparams(&p, p + len, ¶ms)) != 0 || - (ret = pk_use_ecparams(¶ms, pk)) != 0) { - return ret; - } - } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - } - - /* - * Load the private key - */ - ret = mbedtls_pk_ecc_set_key(pk, d, d_len); - if (ret != 0) { - return ret; - } - - if (p != end) { - /* - * Is 'publickey' present? If not, or if we can't read it (eg because it - * is compressed), create it from the private key. - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 1)) == 0) { - end2 = p + len; - - if ((ret = mbedtls_asn1_get_bitstring_null(&p, end2, &len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if (p + len != end2) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - if ((ret = mbedtls_pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) { - pubkey_done = 1; - } else { - /* - * The only acceptable failure mode of mbedtls_pk_ecc_set_pubkey() above - * is if the point format is not recognized. - */ - if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - } - } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - } - - if (!pubkey_done) { - if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) { - return ret; - } - } - - return 0; -} -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -/*********************************************************************** - * - * PKCS#8 parsing functions - * - **********************************************************************/ - -/* - * Parse an unencrypted PKCS#8 encoded private key - * - * Notes: - * - * - This function does not own the key buffer. It is the - * responsibility of the caller to take care of zeroizing - * and freeing it after use. - * - * - The function is responsible for freeing the provided - * PK context on failure. - * - */ -static int pk_parse_key_pkcs8_unencrypted_der( - mbedtls_pk_context *pk, - const unsigned char *key, size_t keylen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret, version; - size_t len; - mbedtls_asn1_buf params; - unsigned char *p = (unsigned char *) key; - unsigned char *end = p + keylen; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE; - const mbedtls_pk_info_t *pk_info; - -#if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) - (void) f_rng; - (void) p_rng; -#endif - - /* - * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208) - * - * PrivateKeyInfo ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL } - * - * Version ::= INTEGER - * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - * PrivateKey ::= OCTET STRING - * - * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey - */ - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - end = p + len; - - if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if (version != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_VERSION, ret); - } - - if ((ret = pk_get_pk_alg(&p, end, &pk_alg, ¶ms, &ec_grp_id)) != 0) { - return ret; - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if (len < 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) { - return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - } - - if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0) { - return ret; - } - -#if defined(MBEDTLS_RSA_C) - if (pk_alg == MBEDTLS_PK_RSA) { - if ((ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), p, len)) != 0) { - mbedtls_pk_free(pk); - return ret; - } - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) { -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) { - if ((ret = - pk_use_ecparams_rfc8410(¶ms, ec_grp_id, pk)) != 0 || - (ret = - pk_parse_key_rfc8410_der(pk, p, len, end, f_rng, - p_rng)) != 0) { - mbedtls_pk_free(pk); - return ret; - } - } else -#endif - { - if ((ret = pk_use_ecparams(¶ms, pk)) != 0 || - (ret = pk_parse_key_sec1_der(pk, p, len, f_rng, p_rng)) != 0) { - mbedtls_pk_free(pk); - return ret; - } - } - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - - end = p + len; - if (end != (key + keylen)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Parse an encrypted PKCS#8 encoded private key - * - * To save space, the decryption happens in-place on the given key buffer. - * Also, while this function may modify the keybuffer, it doesn't own it, - * and instead it is the responsibility of the caller to zeroize and properly - * free it after use. - * - */ -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) -MBEDTLS_STATIC_TESTABLE int mbedtls_pk_parse_key_pkcs8_encrypted_der( - mbedtls_pk_context *pk, - unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret, decrypted = 0; - size_t len; - unsigned char *buf; - unsigned char *p, *end; - mbedtls_asn1_buf pbe_alg_oid, pbe_params; -#if defined(MBEDTLS_PKCS12_C) && defined(MBEDTLS_CIPHER_PADDING_PKCS7) && defined(MBEDTLS_CIPHER_C) - mbedtls_cipher_type_t cipher_alg; - mbedtls_md_type_t md_alg; -#endif - size_t outlen = 0; - - p = key; - end = p + keylen; - - if (pwdlen == 0) { - return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; - } - - /* - * This function parses the EncryptedPrivateKeyInfo object (PKCS#8) - * - * EncryptedPrivateKeyInfo ::= SEQUENCE { - * encryptionAlgorithm EncryptionAlgorithmIdentifier, - * encryptedData EncryptedData - * } - * - * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - * - * EncryptedData ::= OCTET STRING - * - * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo - * - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - end = p + len; - - if ((ret = mbedtls_asn1_get_alg(&p, end, &pbe_alg_oid, &pbe_params)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - - buf = p; - - /* - * Decrypt EncryptedData with appropriate PBE - */ -#if defined(MBEDTLS_PKCS12_C) && defined(MBEDTLS_CIPHER_PADDING_PKCS7) && defined(MBEDTLS_CIPHER_C) - if (mbedtls_oid_get_pkcs12_pbe_alg(&pbe_alg_oid, &md_alg, &cipher_alg) == 0) { - if ((ret = mbedtls_pkcs12_pbe_ext(&pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT, - cipher_alg, md_alg, - pwd, pwdlen, p, len, buf, len, &outlen)) != 0) { - if (ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) { - return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; - } - - return ret; - } - - decrypted = 1; - } else -#endif /* MBEDTLS_PKCS12_C && MBEDTLS_CIPHER_PADDING_PKCS7 && MBEDTLS_CIPHER_C */ -#if defined(MBEDTLS_PKCS5_C) && defined(MBEDTLS_CIPHER_PADDING_PKCS7) && defined(MBEDTLS_CIPHER_C) - if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid) == 0) { - if ((ret = mbedtls_pkcs5_pbes2_ext(&pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen, - p, len, buf, len, &outlen)) != 0) { - if (ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) { - return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; - } - - return ret; - } - - decrypted = 1; - } else -#endif /* MBEDTLS_PKCS5_C && MBEDTLS_CIPHER_PADDING_PKCS7 && MBEDTLS_CIPHER_C */ - { - ((void) pwd); - } - - if (decrypted == 0) { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } - return pk_parse_key_pkcs8_unencrypted_der(pk, buf, outlen, f_rng, p_rng); -} -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ - -/*********************************************************************** - * - * Top-level functions, with format auto-discovery - * - **********************************************************************/ - -/* - * Parse a private key - */ -int mbedtls_pk_parse_key(mbedtls_pk_context *pk, - const unsigned char *key, size_t keylen, - const unsigned char *pwd, size_t pwdlen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_pk_info_t *pk_info; -#if defined(MBEDTLS_PEM_PARSE_C) - size_t len; - mbedtls_pem_context pem; -#endif - - if (keylen == 0) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init(&pem); - -#if defined(MBEDTLS_RSA_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (key[keylen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - PEM_BEGIN_PRIVATE_KEY_RSA, PEM_END_PRIVATE_KEY_RSA, - key, pwd, pwdlen, &len); - } - - if (ret == 0) { - pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); - if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 || - (ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), - pem.buf, pem.buflen)) != 0) { - mbedtls_pk_free(pk); - } - - mbedtls_pem_free(&pem); - return ret; - } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { - return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; - } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { - return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - return ret; - } -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (key[keylen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - PEM_BEGIN_PRIVATE_KEY_EC, - PEM_END_PRIVATE_KEY_EC, - key, pwd, pwdlen, &len); - } - if (ret == 0) { - pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); - - if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 || - (ret = pk_parse_key_sec1_der(pk, - pem.buf, pem.buflen, - f_rng, p_rng)) != 0) { - mbedtls_pk_free(pk); - } - - mbedtls_pem_free(&pem); - return ret; - } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { - return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; - } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { - return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - return ret; - } -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (key[keylen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - PEM_BEGIN_PRIVATE_KEY_PKCS8, PEM_END_PRIVATE_KEY_PKCS8, - key, NULL, 0, &len); - } - if (ret == 0) { - if ((ret = pk_parse_key_pkcs8_unencrypted_der(pk, - pem.buf, pem.buflen, f_rng, p_rng)) != 0) { - mbedtls_pk_free(pk); - } - - mbedtls_pem_free(&pem); - return ret; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - return ret; - } - -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (key[keylen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8, - PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8, - key, NULL, 0, &len); - } - if (ret == 0) { - if ((ret = mbedtls_pk_parse_key_pkcs8_encrypted_der(pk, pem.buf, pem.buflen, - pwd, pwdlen, f_rng, p_rng)) != 0) { - mbedtls_pk_free(pk); - } - - mbedtls_pem_free(&pem); - return ret; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - return ret; - } -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ -#else - ((void) pwd); - ((void) pwdlen); -#endif /* MBEDTLS_PEM_PARSE_C */ - - /* - * At this point we only know it's not a PEM formatted key. Could be any - * of the known DER encoded private key formats - * - * We try the different DER format parsers to see if one passes without - * error - */ -#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) - if (pwdlen != 0) { - unsigned char *key_copy; - - if ((key_copy = mbedtls_calloc(1, keylen)) == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - - memcpy(key_copy, key, keylen); - - ret = mbedtls_pk_parse_key_pkcs8_encrypted_der(pk, key_copy, keylen, - pwd, pwdlen, f_rng, p_rng); - - mbedtls_zeroize_and_free(key_copy, keylen); - } - - if (ret == 0) { - return 0; - } - - mbedtls_pk_free(pk); - mbedtls_pk_init(pk); - - if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH) { - return ret; - } -#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ - - ret = pk_parse_key_pkcs8_unencrypted_der(pk, key, keylen, f_rng, p_rng); - if (ret == 0) { - return 0; - } - - mbedtls_pk_free(pk); - mbedtls_pk_init(pk); - -#if defined(MBEDTLS_RSA_C) - - pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); - if (mbedtls_pk_setup(pk, pk_info) == 0 && - mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), key, keylen) == 0) { - return 0; - } - - mbedtls_pk_free(pk); - mbedtls_pk_init(pk); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); - if (mbedtls_pk_setup(pk, pk_info) == 0 && - pk_parse_key_sec1_der(pk, - key, keylen, f_rng, p_rng) == 0) { - return 0; - } - mbedtls_pk_free(pk); -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - - /* If MBEDTLS_RSA_C is defined but MBEDTLS_PK_HAVE_ECC_KEYS isn't, - * it is ok to leave the PK context initialized but not - * freed: It is the caller's responsibility to call pk_init() - * before calling this function, and to call pk_free() - * when it fails. If MBEDTLS_PK_HAVE_ECC_KEYS is defined but MBEDTLS_RSA_C - * isn't, this leads to mbedtls_pk_free() being called - * twice, once here and once by the caller, but this is - * also ok and in line with the mbedtls_pk_free() calls - * on failed PEM parsing attempts. */ - - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; -} - -/* - * Parse a public key - */ -int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx, - const unsigned char *key, size_t keylen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p; -#if defined(MBEDTLS_RSA_C) - const mbedtls_pk_info_t *pk_info; -#endif -#if defined(MBEDTLS_PEM_PARSE_C) - size_t len; - mbedtls_pem_context pem; -#endif - - if (keylen == 0) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init(&pem); -#if defined(MBEDTLS_RSA_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (key[keylen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - PEM_BEGIN_PUBLIC_KEY_RSA, PEM_END_PUBLIC_KEY_RSA, - key, NULL, 0, &len); - } - - if (ret == 0) { - p = pem.buf; - if ((pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == NULL) { - mbedtls_pem_free(&pem); - return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - } - - if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0) { - mbedtls_pem_free(&pem); - return ret; - } - - if ((ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, pem.buflen)) != 0) { - mbedtls_pk_free(ctx); - } - - mbedtls_pem_free(&pem); - return ret; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - mbedtls_pem_free(&pem); - return ret; - } -#endif /* MBEDTLS_RSA_C */ - - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (key[keylen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, - key, NULL, 0, &len); - } - - if (ret == 0) { - /* - * Was PEM encoded - */ - p = pem.buf; - - ret = mbedtls_pk_parse_subpubkey(&p, p + pem.buflen, ctx); - mbedtls_pem_free(&pem); - return ret; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - mbedtls_pem_free(&pem); - return ret; - } - mbedtls_pem_free(&pem); -#endif /* MBEDTLS_PEM_PARSE_C */ - -#if defined(MBEDTLS_RSA_C) - if ((pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == NULL) { - return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; - } - - if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0) { - return ret; - } - - p = (unsigned char *) key; - ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, keylen); - if (ret == 0) { - return ret; - } - mbedtls_pk_free(ctx); - if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return ret; - } -#endif /* MBEDTLS_RSA_C */ - p = (unsigned char *) key; - - ret = mbedtls_pk_parse_subpubkey(&p, p + keylen, ctx); - - return ret; -} - -/*********************************************************************** - * - * Top-level functions, with filesystem support - * - **********************************************************************/ - -#if defined(MBEDTLS_FS_IO) -/* - * Load all data from a file into a given buffer. - * - * The file is expected to contain either PEM or DER encoded data. - * A terminating null byte is always appended. It is included in the announced - * length only if the data looks like it is PEM encoded. - */ -int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n) -{ - FILE *f; - long size; - - if ((f = fopen(path, "rb")) == NULL) { - return MBEDTLS_ERR_PK_FILE_IO_ERROR; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(f, NULL); - - fseek(f, 0, SEEK_END); - if ((size = ftell(f)) == -1) { - fclose(f); - return MBEDTLS_ERR_PK_FILE_IO_ERROR; - } - fseek(f, 0, SEEK_SET); - - *n = (size_t) size; - - if (*n + 1 == 0 || - (*buf = mbedtls_calloc(1, *n + 1)) == NULL) { - fclose(f); - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - - if (fread(*buf, 1, *n, f) != *n) { - fclose(f); - - mbedtls_zeroize_and_free(*buf, *n); - - return MBEDTLS_ERR_PK_FILE_IO_ERROR; - } - - fclose(f); - - (*buf)[*n] = '\0'; - - if (strstr((const char *) *buf, "-----BEGIN ") != NULL) { - ++*n; - } - - return 0; -} - -/* - * Load and parse a private key - */ -int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx, - const char *path, const char *pwd, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - unsigned char *buf; - - if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) { - return ret; - } - - if (pwd == NULL) { - ret = mbedtls_pk_parse_key(ctx, buf, n, NULL, 0, f_rng, p_rng); - } else { - ret = mbedtls_pk_parse_key(ctx, buf, n, - (const unsigned char *) pwd, strlen(pwd), f_rng, p_rng); - } - - mbedtls_zeroize_and_free(buf, n); - - return ret; -} - -/* - * Load and parse a public key - */ -int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - unsigned char *buf; - - if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) { - return ret; - } - - ret = mbedtls_pk_parse_public_key(ctx, buf, n); - - mbedtls_zeroize_and_free(buf, n); - - return ret; -} -#endif /* MBEDTLS_FS_IO */ - -#endif /* MBEDTLS_PK_PARSE_C */ diff --git a/vendor/mbedtls/library/pkwrite.c b/vendor/mbedtls/library/pkwrite.c deleted file mode 100644 index d264abfbd..000000000 --- a/vendor/mbedtls/library/pkwrite.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Public Key layer for writing key files and structures - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PK_WRITE_C) - -#include "mbedtls/pk.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "pk_internal.h" - -#include - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/bignum.h" -#include "mbedtls/ecp.h" -#include "mbedtls/platform_util.h" -#endif -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#include "pk_internal.h" -#endif -#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#include "pkwrite.h" -#endif -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif -#if defined(MBEDTLS_RSA_C) -#include "rsa_internal.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "psa_util_internal.h" -#endif -#include "mbedtls/platform.h" - -/* Helpers for properly sizing buffers aimed at holding public keys or - * key-pairs based on build symbols. */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH -#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH -#elif defined(MBEDTLS_USE_PSA_CRYPTO) -#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH -#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH -#else -#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_ECP_MAX_PT_LEN -#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_ECP_MAX_BYTES -#endif - -/****************************************************************************** - * Internal functions for RSA keys. - ******************************************************************************/ -#if defined(MBEDTLS_RSA_C) -static int pk_write_rsa_der(unsigned char **p, unsigned char *buf, - const mbedtls_pk_context *pk) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - psa_status_t status; - size_t buf_size = (size_t) (*p - buf); - size_t key_len = 0; - - status = psa_export_key(pk->priv_id, buf, buf_size, &key_len); - if (status == PSA_ERROR_BUFFER_TOO_SMALL) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } else if (status != PSA_SUCCESS) { - return PSA_PK_RSA_TO_MBEDTLS_ERR(status); - } - - /* We wrote to the beginning of the buffer while - * we were supposed to write to its end. */ - *p -= key_len; - memmove(*p, buf, key_len); - mbedtls_platform_zeroize(buf, *p - buf); - - return (int) key_len; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p); -} -#endif /* MBEDTLS_RSA_C */ - -/****************************************************************************** - * Internal functions for EC keys. - ******************************************************************************/ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *pk) -{ - size_t len = 0; - uint8_t buf[PK_MAX_EC_PUBLIC_KEY_SIZE]; - - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - } else { - len = pk->pub_raw_len; - memcpy(buf, pk->pub_raw, len); - } - - if (*p < start || (size_t) (*p - start) < len) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - *p -= len; - memcpy(*p, buf, len); - - return (int) len; -} -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ -static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *pk) -{ - size_t len = 0; - unsigned char buf[PK_MAX_EC_PUBLIC_KEY_SIZE]; - mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk); - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - /* Ensure there's enough space in the provided buffer before copying data into it. */ - if (len > (size_t) (*p - start)) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - *p -= len; - memcpy(*p, buf, len); - return (int) len; - } else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - { - if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &len, buf, sizeof(buf))) != 0) { - return ret; - } - } - - if (*p < start || (size_t) (*p - start) < len) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - *p -= len; - memcpy(*p, buf, len); - - return (int) len; -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - -/* - * privateKey OCTET STRING -- always of length ceil(log2(n)/8) - */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -static int pk_write_ec_private(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *pk) -{ - size_t byte_length; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE]; - psa_status_t status; - - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length); - if (status != PSA_SUCCESS) { - ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - return ret; - } - } else { - status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length); - if (status != PSA_SUCCESS) { - ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - goto exit; - } - } - - ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length); -exit: - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - return ret; -} -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ -static int pk_write_ec_private(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *pk) -{ - size_t byte_length; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE]; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length); - if (status != PSA_SUCCESS) { - ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status); - return ret; - } - } else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - { - mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk); - byte_length = (ec->grp.pbits + 7) / 8; - - ret = mbedtls_ecp_write_key_ext(ec, &byte_length, tmp, sizeof(tmp)); - if (ret != 0) { - goto exit; - } - } - ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length); -exit: - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - return ret; -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - -/* - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * } - */ -static int pk_write_ec_param(unsigned char **p, unsigned char *start, - mbedtls_ecp_group_id grp_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - const char *oid; - size_t oid_len; - - if ((ret = mbedtls_oid_get_oid_by_ec_grp(grp_id, &oid, &oid_len)) != 0) { - return ret; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); - - return (int) len; -} - -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) -/* - * RFC8410 section 7 - * - * OneAsymmetricKey ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL, - * ..., - * [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]], - * ... - * } - * ... - * CurvePrivateKey ::= OCTET STRING - */ -static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf, - const mbedtls_pk_context *pk) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - size_t oid_len = 0; - const char *oid; - mbedtls_ecp_group_id grp_id; - - /* privateKey */ - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING)); - - grp_id = mbedtls_pk_get_ec_group_id(pk); - /* privateKeyAlgorithm */ - if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) { - return ret; - } - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_algorithm_identifier_ext(p, buf, oid, oid_len, 0, 0)); - - /* version */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ - -/* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ -static int pk_write_ec_der(unsigned char **p, unsigned char *buf, - const mbedtls_pk_context *pk) -{ - size_t len = 0; - int ret; - size_t pub_len = 0, par_len = 0; - mbedtls_ecp_group_id grp_id; - - /* publicKey */ - MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk)); - - if (*p - buf < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - (*p)--; - **p = 0; - pub_len += 1; - - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len)); - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING)); - - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len)); - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 1)); - len += pub_len; - - /* parameters */ - grp_id = mbedtls_pk_get_ec_group_id(pk); - MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id)); - MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len)); - MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 0)); - len += par_len; - - /* privateKey */ - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk)); - - /* version */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -/****************************************************************************** - * Internal functions for Opaque keys. - ******************************************************************************/ -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *pk) -{ - size_t buffer_size; - size_t len = 0; - - if (*p < start) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - buffer_size = (size_t) (*p - start); - if (psa_export_public_key(pk->priv_id, start, buffer_size, - &len) != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - *p -= len; - memmove(*p, start, len); - - return (int) len; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/****************************************************************************** - * Generic helpers - ******************************************************************************/ - -/* Extend the public mbedtls_pk_get_type() by getting key type also in case of - * opaque keys. */ -static mbedtls_pk_type_t pk_get_type_ext(const mbedtls_pk_context *pk) -{ - mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (pk_type == MBEDTLS_PK_OPAQUE) { - psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t opaque_key_type; - - if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) { - return MBEDTLS_PK_NONE; - } - opaque_key_type = psa_get_key_type(&opaque_attrs); - psa_reset_key_attributes(&opaque_attrs); - - if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) { - return MBEDTLS_PK_ECKEY; - } else if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) { - return MBEDTLS_PK_RSA; - } else { - return MBEDTLS_PK_NONE; - } - } else -#endif - return pk_type; -} - -/****************************************************************************** - * Public functions for writing private/public DER keys. - ******************************************************************************/ -int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *key) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - -#if defined(MBEDTLS_RSA_C) - if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*key), start, p)); - } else -#endif -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) { - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, key)); - } else -#endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) { - MBEDTLS_ASN1_CHK_ADD(len, pk_write_opaque_pubkey(p, start, key)); - } else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - - return (int) len; -} - -int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *c; - int has_par = 1; - size_t len = 0, par_len = 0, oid_len = 0; - mbedtls_pk_type_t pk_type; - const char *oid = NULL; - - if (size == 0) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - c = buf + size; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_pk_write_pubkey(&c, buf, key)); - - if (c - buf < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - /* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ - *--c = 0; - len += 1; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_BIT_STRING)); - - pk_type = pk_get_type_ext(key); - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_group_id ec_grp_id = mbedtls_pk_get_ec_group_id(key); - if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) { - ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len); - if (ret != 0) { - return ret; - } - has_par = 0; - } else { - MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id)); - } - } -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - - /* At this point oid_len is not null only for EC Montgomery keys. */ - if (oid_len == 0) { - ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid, &oid_len); - if (ret != 0) { - return ret; - } - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier_ext(&c, buf, oid, oid_len, - par_len, has_par)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} - -int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size) -{ - unsigned char *c; - - if (size == 0) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - c = buf + size; - -#if defined(MBEDTLS_RSA_C) - if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) { - return pk_write_rsa_der(&c, buf, key); - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) { -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (mbedtls_pk_is_rfc8410(key)) { - return pk_write_ec_rfc8410_der(&c, buf, key); - } -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ - return pk_write_ec_der(&c, buf, key); - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; -} - -/****************************************************************************** - * Public functions for wrinting private/public PEM keys. - ******************************************************************************/ -#if defined(MBEDTLS_PEM_WRITE_C) - -#define PUB_DER_MAX_BYTES \ - (MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES > MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ? \ - MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES : MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES) -#define PRV_DER_MAX_BYTES \ - (MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES > MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ? \ - MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES : MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES) - -int mbedtls_pk_write_pubkey_pem(const mbedtls_pk_context *key, unsigned char *buf, size_t size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *output_buf = NULL; - output_buf = mbedtls_calloc(1, PUB_DER_MAX_BYTES); - if (output_buf == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - size_t olen = 0; - - if ((ret = mbedtls_pk_write_pubkey_der(key, output_buf, - PUB_DER_MAX_BYTES)) < 0) { - goto cleanup; - } - - if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_PUBLIC_KEY "\n", PEM_END_PUBLIC_KEY "\n", - output_buf + PUB_DER_MAX_BYTES - ret, - ret, buf, size, &olen)) != 0) { - goto cleanup; - } - - ret = 0; -cleanup: - mbedtls_free(output_buf); - return ret; -} - -int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf, size_t size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *output_buf = NULL; - output_buf = mbedtls_calloc(1, PRV_DER_MAX_BYTES); - if (output_buf == NULL) { - return MBEDTLS_ERR_PK_ALLOC_FAILED; - } - const char *begin, *end; - size_t olen = 0; - - if ((ret = mbedtls_pk_write_key_der(key, output_buf, PRV_DER_MAX_BYTES)) < 0) { - goto cleanup; - } - -#if defined(MBEDTLS_RSA_C) - if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) { - begin = PEM_BEGIN_PRIVATE_KEY_RSA "\n"; - end = PEM_END_PRIVATE_KEY_RSA "\n"; - } else -#endif -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) { - if (mbedtls_pk_is_rfc8410(key)) { - begin = PEM_BEGIN_PRIVATE_KEY_PKCS8 "\n"; - end = PEM_END_PRIVATE_KEY_PKCS8 "\n"; - } else { - begin = PEM_BEGIN_PRIVATE_KEY_EC "\n"; - end = PEM_END_PRIVATE_KEY_EC "\n"; - } - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - { - ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - goto cleanup; - } - - if ((ret = mbedtls_pem_write_buffer(begin, end, - output_buf + PRV_DER_MAX_BYTES - ret, - ret, buf, size, &olen)) != 0) { - goto cleanup; - } - - ret = 0; -cleanup: - mbedtls_zeroize_and_free(output_buf, PRV_DER_MAX_BYTES); - return ret; -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_PK_WRITE_C */ diff --git a/vendor/mbedtls/library/pkwrite.h b/vendor/mbedtls/library/pkwrite.h deleted file mode 100644 index 01dc3d2f0..000000000 --- a/vendor/mbedtls/library/pkwrite.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * \file pkwrite.h - * - * \brief Internal defines shared by the PK write module - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_PK_WRITE_H -#define MBEDTLS_PK_WRITE_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/pk.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/* - * Max sizes of key per types. Shown as tag + len (+ content). - */ - -#if defined(MBEDTLS_RSA_C) -/* - * RSA public keys: - * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 - * algorithm AlgorithmIdentifier, 1 + 1 (sequence) - * + 1 + 1 + 9 (rsa oid) - * + 1 + 1 (params null) - * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) - * RSAPublicKey ::= SEQUENCE { 1 + 3 - * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 - * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 - * } - */ -#define MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE) - -/* - * RSA private keys: - * RSAPrivateKey ::= SEQUENCE { 1 + 3 - * version Version, 1 + 1 + 1 - * modulus INTEGER, 1 + 3 + MPI_MAX + 1 - * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 - * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 - * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 - * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) - * } - */ -#define MBEDTLS_MPI_MAX_SIZE_2 (MBEDTLS_MPI_MAX_SIZE / 2 + \ - MBEDTLS_MPI_MAX_SIZE % 2) -#define MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES (47 + 3 * MBEDTLS_MPI_MAX_SIZE \ - + 5 * MBEDTLS_MPI_MAX_SIZE_2) - -#else /* MBEDTLS_RSA_C */ - -#define MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES 0 -#define MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES 0 - -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - -/* Find the maximum number of bytes necessary to store an EC point. When USE_PSA - * is defined this means looking for the maximum between PSA and built-in - * supported curves. */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#define MBEDTLS_PK_MAX_ECC_BYTES (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \ - MBEDTLS_ECP_MAX_BYTES ? \ - PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) : \ - MBEDTLS_ECP_MAX_BYTES) -#else /* MBEDTLS_USE_PSA_CRYPTO */ -#define MBEDTLS_PK_MAX_ECC_BYTES MBEDTLS_ECP_MAX_BYTES -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/* - * EC public keys: - * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 - * algorithm AlgorithmIdentifier, 1 + 1 (sequence) - * + 1 + 1 + 7 (ec oid) - * + 1 + 1 + 9 (namedCurve oid) - * subjectPublicKey BIT STRING 1 + 2 + 1 [1] - * + 1 (point format) [1] - * + 2 * ECP_MAX (coords) [1] - * } - */ -#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_PK_MAX_ECC_BYTES) - -/* - * EC private keys: - * ECPrivateKey ::= SEQUENCE { 1 + 2 - * version INTEGER , 1 + 1 + 1 - * privateKey OCTET STRING, 1 + 1 + ECP_MAX - * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) - * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above - * } - */ -#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_PK_MAX_ECC_BYTES) - -#else /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES 0 -#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES 0 - -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -/* Define the maximum available public key DER length based on the supported - * key types (EC and/or RSA). */ -#if (MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES > MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES) -#define MBEDTLS_PK_WRITE_PUBKEY_MAX_SIZE MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES -#else -#define MBEDTLS_PK_WRITE_PUBKEY_MAX_SIZE MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES -#endif - -#endif /* MBEDTLS_PK_WRITE_H */ diff --git a/vendor/mbedtls/library/platform.c b/vendor/mbedtls/library/platform.c deleted file mode 100644 index 890c4cbab..000000000 --- a/vendor/mbedtls/library/platform.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Platform abstraction layer - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PLATFORM_C) - -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -/* The compile time configuration of memory allocation via the macros - * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime - * configuration via mbedtls_platform_set_calloc_free(). So, omit everything - * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ -#if defined(MBEDTLS_PLATFORM_MEMORY) && \ - !(defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ - defined(MBEDTLS_PLATFORM_FREE_MACRO)) - -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -static void *platform_calloc_uninit(size_t n, size_t size) -{ - ((void) n); - ((void) size); - return NULL; -} - -#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit -#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ - -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -static void platform_free_uninit(void *ptr) -{ - ((void) ptr); -} - -#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FREE */ - -static void * (*mbedtls_calloc_func)(size_t, size_t) = MBEDTLS_PLATFORM_STD_CALLOC; -static void (*mbedtls_free_func)(void *) = MBEDTLS_PLATFORM_STD_FREE; - -void *mbedtls_calloc(size_t nmemb, size_t size) -{ - return (*mbedtls_calloc_func)(nmemb, size); -} - -void mbedtls_free(void *ptr) -{ - (*mbedtls_free_func)(ptr); -} - -int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t), - void (*free_func)(void *)) -{ - mbedtls_calloc_func = calloc_func; - mbedtls_free_func = free_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_MEMORY && - !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && - defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ - -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) -#include -int mbedtls_platform_win32_snprintf(char *s, size_t n, const char *fmt, ...) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - va_list argp; - - va_start(argp, fmt); - ret = mbedtls_vsnprintf(s, n, fmt, argp); - va_end(argp); - - return ret; -} -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_snprintf_uninit(char *s, size_t n, - const char *format, ...) -{ - ((void) s); - ((void) n); - ((void) format); - return 0; -} - -#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ - -int (*mbedtls_snprintf)(char *s, size_t n, - const char *format, - ...) = MBEDTLS_PLATFORM_STD_SNPRINTF; - -int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n, - const char *format, - ...)) -{ - mbedtls_snprintf = snprintf_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) -#include -int mbedtls_platform_win32_vsnprintf(char *s, size_t n, const char *fmt, va_list arg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Avoid calling the invalid parameter handler by checking ourselves */ - if (s == NULL || n == 0 || fmt == NULL) { - return -1; - } - -#if defined(_TRUNCATE) - ret = vsnprintf_s(s, n, _TRUNCATE, fmt, arg); -#else - ret = vsnprintf(s, n, fmt, arg); - if (ret < 0 || (size_t) ret == n) { - s[n-1] = '\0'; - ret = -1; - } -#endif - - return ret; -} -#endif - -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_vsnprintf_uninit(char *s, size_t n, - const char *format, va_list arg) -{ - ((void) s); - ((void) n); - ((void) format); - ((void) arg); - return -1; -} - -#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */ - -int (*mbedtls_vsnprintf)(char *s, size_t n, - const char *format, - va_list arg) = MBEDTLS_PLATFORM_STD_VSNPRINTF; - -int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n, - const char *format, - va_list arg)) -{ - mbedtls_vsnprintf = vsnprintf_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_printf_uninit(const char *format, ...) -{ - ((void) format); - return 0; -} - -#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ - -int (*mbedtls_printf)(const char *, ...) = MBEDTLS_PLATFORM_STD_PRINTF; - -int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...)) -{ - mbedtls_printf = printf_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_fprintf_uninit(FILE *stream, const char *format, ...) -{ - ((void) stream); - ((void) format); - return 0; -} - -#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ - -int (*mbedtls_fprintf)(FILE *, const char *, ...) = - MBEDTLS_PLATFORM_STD_FPRINTF; - -int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *, const char *, ...)) -{ - mbedtls_fprintf = fprintf_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -#if defined(MBEDTLS_PLATFORM_SETBUF_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_SETBUF) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static void platform_setbuf_uninit(FILE *stream, char *buf) -{ - ((void) stream); - ((void) buf); -} - -#define MBEDTLS_PLATFORM_STD_SETBUF platform_setbuf_uninit -#endif /* !MBEDTLS_PLATFORM_STD_SETBUF */ -void (*mbedtls_setbuf)(FILE *stream, char *buf) = MBEDTLS_PLATFORM_STD_SETBUF; - -int mbedtls_platform_set_setbuf(void (*setbuf_func)(FILE *stream, char *buf)) -{ - mbedtls_setbuf = setbuf_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */ - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static void platform_exit_uninit(int status) -{ - ((void) status); -} - -#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit -#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ - -void (*mbedtls_exit)(int status) = MBEDTLS_PLATFORM_STD_EXIT; - -int mbedtls_platform_set_exit(void (*exit_func)(int status)) -{ - mbedtls_exit = exit_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -#if defined(MBEDTLS_HAVE_TIME) - -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static mbedtls_time_t platform_time_uninit(mbedtls_time_t *timer) -{ - ((void) timer); - return 0; -} - -#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit -#endif /* !MBEDTLS_PLATFORM_STD_TIME */ - -mbedtls_time_t (*mbedtls_time)(mbedtls_time_t *timer) = MBEDTLS_PLATFORM_STD_TIME; - -int mbedtls_platform_set_time(mbedtls_time_t (*time_func)(mbedtls_time_t *timer)) -{ - mbedtls_time = time_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Default implementations for the platform independent seed functions use - * standard libc file functions to read from and write to a pre-defined filename - */ -int mbedtls_platform_std_nv_seed_read(unsigned char *buf, size_t buf_len) -{ - FILE *file; - size_t n; - - if ((file = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb")) == NULL) { - return -1; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(file, NULL); - - if ((n = fread(buf, 1, buf_len, file)) != buf_len) { - fclose(file); - mbedtls_platform_zeroize(buf, buf_len); - return -1; - } - - fclose(file); - return (int) n; -} - -int mbedtls_platform_std_nv_seed_write(unsigned char *buf, size_t buf_len) -{ - FILE *file; - size_t n; - - if ((file = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w")) == NULL) { - return -1; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(file, NULL); - - if ((n = fwrite(buf, 1, buf_len, file)) != buf_len) { - fclose(file); - return -1; - } - - fclose(file); - return (int) n; -} -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_read_uninit(unsigned char *buf, size_t buf_len) -{ - ((void) buf); - ((void) buf_len); - return -1; -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ - -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -/* - * Make dummy function to prevent NULL pointer dereferences - */ -static int platform_nv_seed_write_uninit(unsigned char *buf, size_t buf_len) -{ - ((void) buf); - ((void) buf_len); - return -1; -} - -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit -#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ - -int (*mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len) = - MBEDTLS_PLATFORM_STD_NV_SEED_READ; -int (*mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len) = - MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; - -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)(unsigned char *buf, size_t buf_len), - int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len)) -{ - mbedtls_nv_seed_read = nv_seed_read_func; - mbedtls_nv_seed_write = nv_seed_write_func; - return 0; -} -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) -/* - * Placeholder platform setup that does nothing by default - */ -int mbedtls_platform_setup(mbedtls_platform_context *ctx) -{ - (void) ctx; - - return 0; -} - -/* - * Placeholder platform teardown that does nothing by default - */ -void mbedtls_platform_teardown(mbedtls_platform_context *ctx) -{ - (void) ctx; -} -#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ - -#endif /* MBEDTLS_PLATFORM_C */ diff --git a/vendor/mbedtls/library/platform_util.c b/vendor/mbedtls/library/platform_util.c deleted file mode 100644 index 1cab42ffc..000000000 --- a/vendor/mbedtls/library/platform_util.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Common and shared functions used by multiple modules in the Mbed TLS - * library. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms - * except OpenBSD, where it stops us accessing explicit_bzero. - */ -#if !defined(_POSIX_C_SOURCE) && !defined(__OpenBSD__) -#define _POSIX_C_SOURCE 200112L -#endif - -#if !defined(_GNU_SOURCE) -/* Clang requires this to get support for explicit_bzero */ -#define _GNU_SOURCE -#endif - -#include "common.h" - -#include "mbedtls/platform_util.h" -#include "mbedtls/platform.h" -#include "mbedtls/threading.h" - -#include - -#ifndef __STDC_WANT_LIB_EXT1__ -#define __STDC_WANT_LIB_EXT1__ 1 /* Ask for the C11 gmtime_s() and memset_s() if available */ -#endif -#include - -#if defined(_WIN32) -#include -#endif - -// Detect platforms known to support explicit_bzero() -#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25) -#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1 -#elif (defined(__FreeBSD__) && (__FreeBSD_version >= 1100037)) || defined(__OpenBSD__) -#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1 -#endif - -#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) - -#undef HAVE_MEMORY_SANITIZER -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) -#include -#define HAVE_MEMORY_SANITIZER -#endif -#endif - -/* - * Where possible, we try to detect the presence of a platform-provided - * secure memset, such as explicit_bzero(), that is safe against being optimized - * out, and use that. - * - * For other platforms, we provide an implementation that aims not to be - * optimized out by the compiler. - * - * This implementation for mbedtls_platform_zeroize() was inspired from Colin - * Percival's blog article at: - * - * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html - * - * It uses a volatile function pointer to the standard memset(). Because the - * pointer is volatile the compiler expects it to change at - * any time and will not optimize out the call that could potentially perform - * other operations on the input buffer instead of just setting it to 0. - * Nevertheless, as pointed out by davidtgoldblatt on Hacker News - * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for - * details), optimizations of the following form are still possible: - * - * if (memset_func != memset) - * memset_func(buf, 0, len); - * - * Note that it is extremely difficult to guarantee that - * the memset() call will not be optimized out by aggressive compilers - * in a portable way. For this reason, Mbed TLS also provides the configuration - * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure - * mbedtls_platform_zeroize() to use a suitable implementation for their - * platform and needs. - */ -#if !defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO) && !(defined(__STDC_LIB_EXT1__) && \ - !defined(__IAR_SYSTEMS_ICC__)) \ - && !defined(_WIN32) -static void *(*const volatile memset_func)(void *, int, size_t) = memset; -#endif - -void mbedtls_platform_zeroize(void *buf, size_t len) -{ - if (len > 0) { -#if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO) - explicit_bzero(buf, len); -#if defined(HAVE_MEMORY_SANITIZER) - /* You'd think that Msan would recognize explicit_bzero() as - * equivalent to bzero(), but it actually doesn't on several - * platforms, including Linux (Ubuntu 20.04). - * https://github.com/google/sanitizers/issues/1507 - * https://github.com/openssh/openssh-portable/commit/74433a19bb6f4cef607680fa4d1d7d81ca3826aa - */ - __msan_unpoison(buf, len); -#endif -#elif defined(__STDC_LIB_EXT1__) && !defined(__IAR_SYSTEMS_ICC__) - memset_s(buf, len, 0, len); -#elif defined(_WIN32) - SecureZeroMemory(buf, len); -#else - memset_func(buf, 0, len); -#endif - -#if defined(__GNUC__) - /* For clang and recent gcc, pretend that we have some assembly that reads the - * zero'd memory as an additional protection against being optimised away. */ -#if defined(__clang__) || (__GNUC__ >= 10) -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wvla" -#elif defined(MBEDTLS_COMPILER_IS_GCC) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wvla" -#endif - asm volatile ("" : : "m" (*(char (*)[len]) buf) :); -#if defined(__clang__) -#pragma clang diagnostic pop -#elif defined(MBEDTLS_COMPILER_IS_GCC) -#pragma GCC diagnostic pop -#endif -#endif -#endif - } -} -#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ - -void mbedtls_zeroize_and_free(void *buf, size_t len) -{ - if (buf != NULL) { - mbedtls_platform_zeroize(buf, len); - } - - mbedtls_free(buf); -} - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -#include -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) -#include -#endif - -#if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \ - (defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L)) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ -#if !(defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)) || \ - (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) -#define PLATFORM_UTIL_USE_GMTIME -#endif - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */ - -struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt, - struct tm *tm_buf) -{ -#if defined(_WIN32) && !defined(PLATFORM_UTIL_USE_GMTIME) -#if defined(__STDC_LIB_EXT1__) - return (gmtime_s(tt, tm_buf) == 0) ? NULL : tm_buf; -#else - /* MSVC and mingw64 argument order and return value are inconsistent with the C11 standard */ - return (gmtime_s(tm_buf, tt) == 0) ? tm_buf : NULL; -#endif -#elif !defined(PLATFORM_UTIL_USE_GMTIME) - return gmtime_r(tt, tm_buf); -#else - struct tm *lt; - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_lock(&mbedtls_threading_gmtime_mutex) != 0) { - return NULL; - } -#endif /* MBEDTLS_THREADING_C */ - - lt = gmtime(tt); - - if (lt != NULL) { - memcpy(tm_buf, lt, sizeof(struct tm)); - } - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&mbedtls_threading_gmtime_mutex) != 0) { - return NULL; - } -#endif /* MBEDTLS_THREADING_C */ - - return (lt == NULL) ? NULL : tm_buf; -#endif /* _WIN32 && !EFIX64 && !EFI32 */ -} -#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#if defined(MBEDTLS_TEST_HOOKS) -void (*mbedtls_test_hook_test_fail)(const char *, int, const char *); -#endif /* MBEDTLS_TEST_HOOKS */ - -#if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT) - -#include -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) -#include -#endif - -#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) || defined(__HAIKU__) -mbedtls_ms_time_t mbedtls_ms_time(void) -{ - int ret; - struct timespec tv; - mbedtls_ms_time_t current_ms; - -#if defined(__linux__) && defined(CLOCK_BOOTTIME) || defined(__midipix__) - ret = clock_gettime(CLOCK_BOOTTIME, &tv); -#else - ret = clock_gettime(CLOCK_MONOTONIC, &tv); -#endif - if (ret) { - return time(NULL) * 1000; - } - - current_ms = tv.tv_sec; - - return current_ms*1000 + tv.tv_nsec / 1000000; -} -#elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ - defined(__MINGW32__) || defined(_WIN64) -#include -mbedtls_ms_time_t mbedtls_ms_time(void) -{ - FILETIME ct; - mbedtls_ms_time_t current_ms; - - GetSystemTimeAsFileTime(&ct); - current_ms = ((mbedtls_ms_time_t) ct.dwLowDateTime + - ((mbedtls_ms_time_t) (ct.dwHighDateTime) << 32LL))/10000; - return current_ms; -} -#else -#error "No mbedtls_ms_time available" -#endif -#endif /* MBEDTLS_HAVE_TIME && !MBEDTLS_PLATFORM_MS_TIME_ALT */ diff --git a/vendor/mbedtls/library/poly1305.c b/vendor/mbedtls/library/poly1305.c deleted file mode 100644 index c9ebe9e1d..000000000 --- a/vendor/mbedtls/library/poly1305.c +++ /dev/null @@ -1,492 +0,0 @@ -/** - * \file poly1305.c - * - * \brief Poly1305 authentication algorithm. - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#include "common.h" - -#if defined(MBEDTLS_POLY1305_C) - -#include "mbedtls/poly1305.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_POLY1305_ALT) - -#define POLY1305_BLOCK_SIZE_BYTES (16U) - -/* - * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier. - * However we provided an alternative for platforms without such a multiplier. - */ -#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) -static uint64_t mul64(uint32_t a, uint32_t b) -{ - /* a = al + 2**16 ah, b = bl + 2**16 bh */ - const uint16_t al = (uint16_t) a; - const uint16_t bl = (uint16_t) b; - const uint16_t ah = a >> 16; - const uint16_t bh = b >> 16; - - /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */ - const uint32_t lo = (uint32_t) al * bl; - const uint64_t me = (uint64_t) ((uint32_t) ah * bl) + (uint32_t) al * bh; - const uint32_t hi = (uint32_t) ah * bh; - - return lo + (me << 16) + ((uint64_t) hi << 32); -} -#else -static inline uint64_t mul64(uint32_t a, uint32_t b) -{ - return (uint64_t) a * b; -} -#endif - - -/** - * \brief Process blocks with Poly1305. - * - * \param ctx The Poly1305 context. - * \param nblocks Number of blocks to process. Note that this - * function only processes full blocks. - * \param input Buffer containing the input block(s). - * \param needs_padding Set to 0 if the padding bit has already been - * applied to the input data before calling this - * function. Otherwise, set this parameter to 1. - */ -static void poly1305_process(mbedtls_poly1305_context *ctx, - size_t nblocks, - const unsigned char *input, - uint32_t needs_padding) -{ - uint64_t d0, d1, d2, d3; - uint32_t acc0, acc1, acc2, acc3, acc4; - uint32_t r0, r1, r2, r3; - uint32_t rs1, rs2, rs3; - size_t offset = 0U; - size_t i; - - r0 = ctx->r[0]; - r1 = ctx->r[1]; - r2 = ctx->r[2]; - r3 = ctx->r[3]; - - rs1 = r1 + (r1 >> 2U); - rs2 = r2 + (r2 >> 2U); - rs3 = r3 + (r3 >> 2U); - - acc0 = ctx->acc[0]; - acc1 = ctx->acc[1]; - acc2 = ctx->acc[2]; - acc3 = ctx->acc[3]; - acc4 = ctx->acc[4]; - - /* Process full blocks */ - for (i = 0U; i < nblocks; i++) { - /* The input block is treated as a 128-bit little-endian integer */ - d0 = MBEDTLS_GET_UINT32_LE(input, offset + 0); - d1 = MBEDTLS_GET_UINT32_LE(input, offset + 4); - d2 = MBEDTLS_GET_UINT32_LE(input, offset + 8); - d3 = MBEDTLS_GET_UINT32_LE(input, offset + 12); - - /* Compute: acc += (padded) block as a 130-bit integer */ - d0 += (uint64_t) acc0; - d1 += (uint64_t) acc1 + (d0 >> 32U); - d2 += (uint64_t) acc2 + (d1 >> 32U); - d3 += (uint64_t) acc3 + (d2 >> 32U); - acc0 = (uint32_t) d0; - acc1 = (uint32_t) d1; - acc2 = (uint32_t) d2; - acc3 = (uint32_t) d3; - acc4 += (uint32_t) (d3 >> 32U) + needs_padding; - - /* Compute: acc *= r */ - d0 = mul64(acc0, r0) + - mul64(acc1, rs3) + - mul64(acc2, rs2) + - mul64(acc3, rs1); - d1 = mul64(acc0, r1) + - mul64(acc1, r0) + - mul64(acc2, rs3) + - mul64(acc3, rs2) + - mul64(acc4, rs1); - d2 = mul64(acc0, r2) + - mul64(acc1, r1) + - mul64(acc2, r0) + - mul64(acc3, rs3) + - mul64(acc4, rs2); - d3 = mul64(acc0, r3) + - mul64(acc1, r2) + - mul64(acc2, r1) + - mul64(acc3, r0) + - mul64(acc4, rs3); - acc4 *= r0; - - /* Compute: acc %= (2^130 - 5) (partial remainder) */ - d1 += (d0 >> 32); - d2 += (d1 >> 32); - d3 += (d2 >> 32); - acc0 = (uint32_t) d0; - acc1 = (uint32_t) d1; - acc2 = (uint32_t) d2; - acc3 = (uint32_t) d3; - acc4 = (uint32_t) (d3 >> 32) + acc4; - - d0 = (uint64_t) acc0 + (acc4 >> 2) + (acc4 & 0xFFFFFFFCU); - acc4 &= 3U; - acc0 = (uint32_t) d0; - d0 = (uint64_t) acc1 + (d0 >> 32U); - acc1 = (uint32_t) d0; - d0 = (uint64_t) acc2 + (d0 >> 32U); - acc2 = (uint32_t) d0; - d0 = (uint64_t) acc3 + (d0 >> 32U); - acc3 = (uint32_t) d0; - d0 = (uint64_t) acc4 + (d0 >> 32U); - acc4 = (uint32_t) d0; - - offset += POLY1305_BLOCK_SIZE_BYTES; - } - - ctx->acc[0] = acc0; - ctx->acc[1] = acc1; - ctx->acc[2] = acc2; - ctx->acc[3] = acc3; - ctx->acc[4] = acc4; -} - -/** - * \brief Compute the Poly1305 MAC - * - * \param ctx The Poly1305 context. - * \param mac The buffer to where the MAC is written. Must be - * big enough to contain the 16-byte MAC. - */ -static void poly1305_compute_mac(const mbedtls_poly1305_context *ctx, - unsigned char mac[16]) -{ - uint64_t d; - uint32_t g0, g1, g2, g3, g4; - uint32_t acc0, acc1, acc2, acc3, acc4; - uint32_t mask; - uint32_t mask_inv; - - acc0 = ctx->acc[0]; - acc1 = ctx->acc[1]; - acc2 = ctx->acc[2]; - acc3 = ctx->acc[3]; - acc4 = ctx->acc[4]; - - /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5. - * We do this by calculating acc - (2^130 - 5), then checking if - * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5) - */ - - /* Calculate acc + -(2^130 - 5) */ - d = ((uint64_t) acc0 + 5U); - g0 = (uint32_t) d; - d = ((uint64_t) acc1 + (d >> 32)); - g1 = (uint32_t) d; - d = ((uint64_t) acc2 + (d >> 32)); - g2 = (uint32_t) d; - d = ((uint64_t) acc3 + (d >> 32)); - g3 = (uint32_t) d; - g4 = acc4 + (uint32_t) (d >> 32U); - - /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */ - mask = (uint32_t) 0U - (g4 >> 2U); - mask_inv = ~mask; - - /* If 131st bit is set then acc=g, otherwise, acc is unmodified */ - acc0 = (acc0 & mask_inv) | (g0 & mask); - acc1 = (acc1 & mask_inv) | (g1 & mask); - acc2 = (acc2 & mask_inv) | (g2 & mask); - acc3 = (acc3 & mask_inv) | (g3 & mask); - - /* Add 's' */ - d = (uint64_t) acc0 + ctx->s[0]; - acc0 = (uint32_t) d; - d = (uint64_t) acc1 + ctx->s[1] + (d >> 32U); - acc1 = (uint32_t) d; - d = (uint64_t) acc2 + ctx->s[2] + (d >> 32U); - acc2 = (uint32_t) d; - acc3 += ctx->s[3] + (uint32_t) (d >> 32U); - - /* Compute MAC (128 least significant bits of the accumulator) */ - MBEDTLS_PUT_UINT32_LE(acc0, mac, 0); - MBEDTLS_PUT_UINT32_LE(acc1, mac, 4); - MBEDTLS_PUT_UINT32_LE(acc2, mac, 8); - MBEDTLS_PUT_UINT32_LE(acc3, mac, 12); -} - -void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx) -{ - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context)); -} - -void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_poly1305_context)); -} - -int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx, - const unsigned char key[32]) -{ - /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */ - ctx->r[0] = MBEDTLS_GET_UINT32_LE(key, 0) & 0x0FFFFFFFU; - ctx->r[1] = MBEDTLS_GET_UINT32_LE(key, 4) & 0x0FFFFFFCU; - ctx->r[2] = MBEDTLS_GET_UINT32_LE(key, 8) & 0x0FFFFFFCU; - ctx->r[3] = MBEDTLS_GET_UINT32_LE(key, 12) & 0x0FFFFFFCU; - - ctx->s[0] = MBEDTLS_GET_UINT32_LE(key, 16); - ctx->s[1] = MBEDTLS_GET_UINT32_LE(key, 20); - ctx->s[2] = MBEDTLS_GET_UINT32_LE(key, 24); - ctx->s[3] = MBEDTLS_GET_UINT32_LE(key, 28); - - /* Initial accumulator state */ - ctx->acc[0] = 0U; - ctx->acc[1] = 0U; - ctx->acc[2] = 0U; - ctx->acc[3] = 0U; - ctx->acc[4] = 0U; - - /* Queue initially empty */ - mbedtls_platform_zeroize(ctx->queue, sizeof(ctx->queue)); - ctx->queue_len = 0U; - - return 0; -} - -int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx, - const unsigned char *input, - size_t ilen) -{ - size_t offset = 0U; - size_t remaining = ilen; - size_t queue_free_len; - size_t nblocks; - - if ((remaining > 0U) && (ctx->queue_len > 0U)) { - queue_free_len = (POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len); - - if (ilen < queue_free_len) { - /* Not enough data to complete the block. - * Store this data with the other leftovers. - */ - memcpy(&ctx->queue[ctx->queue_len], - input, - ilen); - - ctx->queue_len += ilen; - - remaining = 0U; - } else { - /* Enough data to produce a complete block */ - memcpy(&ctx->queue[ctx->queue_len], - input, - queue_free_len); - - ctx->queue_len = 0U; - - poly1305_process(ctx, 1U, ctx->queue, 1U); /* add padding bit */ - - offset += queue_free_len; - remaining -= queue_free_len; - } - } - - if (remaining >= POLY1305_BLOCK_SIZE_BYTES) { - nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES; - - poly1305_process(ctx, nblocks, &input[offset], 1U); - - offset += nblocks * POLY1305_BLOCK_SIZE_BYTES; - remaining %= POLY1305_BLOCK_SIZE_BYTES; - } - - if (remaining > 0U) { - /* Store partial block */ - ctx->queue_len = remaining; - memcpy(ctx->queue, &input[offset], remaining); - } - - return 0; -} - -int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx, - unsigned char mac[16]) -{ - /* Process any leftover data */ - if (ctx->queue_len > 0U) { - /* Add padding bit */ - ctx->queue[ctx->queue_len] = 1U; - ctx->queue_len++; - - /* Pad with zeroes */ - memset(&ctx->queue[ctx->queue_len], - 0, - POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len); - - poly1305_process(ctx, 1U, /* Process 1 block */ - ctx->queue, 0U); /* Already padded above */ - } - - poly1305_compute_mac(ctx, mac); - - return 0; -} - -int mbedtls_poly1305_mac(const unsigned char key[32], - const unsigned char *input, - size_t ilen, - unsigned char mac[16]) -{ - mbedtls_poly1305_context ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_poly1305_init(&ctx); - - ret = mbedtls_poly1305_starts(&ctx, key); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_poly1305_update(&ctx, input, ilen); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_poly1305_finish(&ctx, mac); - -cleanup: - mbedtls_poly1305_free(&ctx); - return ret; -} - -#endif /* MBEDTLS_POLY1305_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_keys[2][32] = -{ - { - 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, - 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8, - 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, - 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b - }, - { - 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, - 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0, - 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, - 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0 - } -}; - -static const unsigned char test_data[2][127] = -{ - { - 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f, - 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f, - 0x75, 0x70 - }, - { - 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, - 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, - 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20, - 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, - 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, - 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c, - 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, - 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, - 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20, - 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75, - 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e - } -}; - -static const size_t test_data_len[2] = -{ - 34U, - 127U -}; - -static const unsigned char test_mac[2][16] = -{ - { - 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, - 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9 - }, - { - 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, - 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62 - } -}; - -/* Make sure no other definition is already present. */ -#undef ASSERT - -#define ASSERT(cond, args) \ - do \ - { \ - if (!(cond)) \ - { \ - if (verbose != 0) \ - mbedtls_printf args; \ - \ - return -1; \ - } \ - } \ - while (0) - -int mbedtls_poly1305_self_test(int verbose) -{ - unsigned char mac[16]; - unsigned i; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - for (i = 0U; i < 2U; i++) { - if (verbose != 0) { - mbedtls_printf(" Poly1305 test %u ", i); - } - - ret = mbedtls_poly1305_mac(test_keys[i], - test_data[i], - test_data_len[i], - mac); - ASSERT(0 == ret, ("error code: %i\n", ret)); - - ASSERT(0 == memcmp(mac, test_mac[i], 16U), ("failed (mac)\n")); - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_POLY1305_C */ diff --git a/vendor/mbedtls/library/psa_crypto.c b/vendor/mbedtls/library/psa_crypto.c deleted file mode 100644 index 63b16f928..000000000 --- a/vendor/mbedtls/library/psa_crypto.c +++ /dev/null @@ -1,9517 +0,0 @@ -/* - * PSA crypto layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" -#include "psa_crypto_core_common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) -#include "check_crypto_config.h" -#endif - -#include "psa/crypto.h" -#include "psa/crypto_values.h" - -#include "psa_crypto_cipher.h" -#include "psa_crypto_core.h" -#include "psa_crypto_invasive.h" -#include "psa_crypto_driver_wrappers.h" -#include "psa_crypto_driver_wrappers_no_static.h" -#include "psa_crypto_ecp.h" -#include "psa_crypto_ffdh.h" -#include "psa_crypto_hash.h" -#include "psa_crypto_mac.h" -#include "psa_crypto_rsa.h" -#include "psa_crypto_ecp.h" -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -#include "psa_crypto_se.h" -#endif -#include "psa_crypto_slot_management.h" -/* Include internal declarations that are useful for implementing persistently - * stored keys. */ -#include "psa_crypto_storage.h" - -#include "psa_crypto_random.h" -#include "psa_crypto_random_impl.h" - -#include -#include -#include "mbedtls/platform.h" - -#include "mbedtls/aes.h" -#include "mbedtls/asn1.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/bignum.h" -#include "mbedtls/camellia.h" -#include "mbedtls/chacha20.h" -#include "mbedtls/chachapoly.h" -#include "mbedtls/cipher.h" -#include "mbedtls/ccm.h" -#include "mbedtls/cmac.h" -#include "mbedtls/constant_time.h" -#include "mbedtls/des.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecp.h" -#include "mbedtls/entropy.h" -#include "mbedtls/error.h" -#include "mbedtls/gcm.h" -#include "mbedtls/md5.h" -#include "mbedtls/pk.h" -#include "pk_wrap.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "mbedtls/ripemd160.h" -#include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" -#include "mbedtls/sha512.h" -#include "mbedtls/psa_util.h" -#include "mbedtls/threading.h" - -#include "constant_time_internal.h" - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) -#define BUILTIN_ALG_ANY_HKDF 1 -#endif - -/****************************************************************/ -/* Global data, support functions and library management */ -/****************************************************************/ - -static int key_type_is_raw_bytes(psa_key_type_t type) -{ - return PSA_KEY_TYPE_IS_UNSTRUCTURED(type); -} - -/* Values for psa_global_data_t::rng_state */ -#define RNG_NOT_INITIALIZED 0 -#define RNG_INITIALIZED 1 -#define RNG_SEEDED 2 - -/* IDs for PSA crypto subsystems. Starts at 1 to catch potential uninitialized - * variables as arguments. */ -typedef enum { - PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS = 1, - PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS, - PSA_CRYPTO_SUBSYSTEM_RNG, - PSA_CRYPTO_SUBSYSTEM_TRANSACTION, -} mbedtls_psa_crypto_subsystem; - -/* Initialization flags for global_data::initialized */ -#define PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED 0x01 -#define PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED 0x02 -#define PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED 0x04 - -#define PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED ( \ - PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED | \ - PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED | \ - PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) - -typedef struct { - uint8_t initialized; - uint8_t rng_state; - mbedtls_psa_random_context_t rng; -} psa_global_data_t; - -static psa_global_data_t global_data; - -static uint8_t psa_get_initialized(void) -{ - uint8_t initialized; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - initialized = global_data.rng_state == RNG_SEEDED; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - initialized = - (initialized && (global_data.initialized == PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED)); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - return initialized; -} - -static uint8_t psa_get_drivers_initialized(void) -{ - uint8_t initialized; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - initialized = (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) != 0; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - return initialized; -} - -#define GUARD_MODULE_INITIALIZED \ - if (psa_get_initialized() == 0) \ - return PSA_ERROR_BAD_STATE; - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) - -/* Declare a local copy of an input buffer and a variable that will be used - * to store a pointer to the start of the buffer. - * - * Note: This macro must be called before any operations which may jump to - * the exit label, so that the local input copy object is safe to be freed. - * - * Assumptions: - * - input is the name of a pointer to the buffer to be copied - * - The name LOCAL_INPUT_COPY_OF_input is unused in the current scope - * - input_copy_name is a name that is unused in the current scope - */ -#define LOCAL_INPUT_DECLARE(input, input_copy_name) \ - psa_crypto_local_input_t LOCAL_INPUT_COPY_OF_##input = PSA_CRYPTO_LOCAL_INPUT_INIT; \ - const uint8_t *input_copy_name = NULL; - -/* Allocate a copy of the buffer input and set the pointer input_copy to - * point to the start of the copy. - * - * Assumptions: - * - psa_status_t status exists - * - An exit label is declared - * - input is the name of a pointer to the buffer to be copied - * - LOCAL_INPUT_DECLARE(input, input_copy) has previously been called - */ -#define LOCAL_INPUT_ALLOC(input, length, input_copy) \ - status = psa_crypto_local_input_alloc(input, length, \ - &LOCAL_INPUT_COPY_OF_##input); \ - if (status != PSA_SUCCESS) { \ - goto exit; \ - } \ - input_copy = LOCAL_INPUT_COPY_OF_##input.buffer; - -/* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC() - * - * Assumptions: - * - input_copy is the name of the input copy pointer set by LOCAL_INPUT_ALLOC() - * - input is the name of the original buffer that was copied - */ -#define LOCAL_INPUT_FREE(input, input_copy) \ - input_copy = NULL; \ - psa_crypto_local_input_free(&LOCAL_INPUT_COPY_OF_##input); - -/* Declare a local copy of an output buffer and a variable that will be used - * to store a pointer to the start of the buffer. - * - * Note: This macro must be called before any operations which may jump to - * the exit label, so that the local output copy object is safe to be freed. - * - * Assumptions: - * - output is the name of a pointer to the buffer to be copied - * - The name LOCAL_OUTPUT_COPY_OF_output is unused in the current scope - * - output_copy_name is a name that is unused in the current scope - */ -#define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \ - psa_crypto_local_output_t LOCAL_OUTPUT_COPY_OF_##output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ - uint8_t *output_copy_name = NULL; - -/* Allocate a copy of the buffer output and set the pointer output_copy to - * point to the start of the copy. - * - * Assumptions: - * - psa_status_t status exists - * - An exit label is declared - * - output is the name of a pointer to the buffer to be copied - * - LOCAL_OUTPUT_DECLARE(output, output_copy) has previously been called - */ -#define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ - status = psa_crypto_local_output_alloc(output, length, \ - &LOCAL_OUTPUT_COPY_OF_##output); \ - if (status != PSA_SUCCESS) { \ - goto exit; \ - } \ - output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer; - -/* Free the local output copy allocated previously by LOCAL_OUTPUT_ALLOC() - * after first copying back its contents to the original buffer. - * - * Assumptions: - * - psa_status_t status exists - * - output_copy is the name of the output copy pointer set by LOCAL_OUTPUT_ALLOC() - * - output is the name of the original buffer that was copied - */ -#define LOCAL_OUTPUT_FREE(output, output_copy) \ - output_copy = NULL; \ - do { \ - psa_status_t local_output_status; \ - local_output_status = psa_crypto_local_output_free(&LOCAL_OUTPUT_COPY_OF_##output); \ - if (local_output_status != PSA_SUCCESS) { \ - /* Since this error case is an internal error, it's more serious than \ - * any existing error code and so it's fine to overwrite the existing \ - * status. */ \ - status = local_output_status; \ - } \ - } while (0) -#else /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ -#define LOCAL_INPUT_DECLARE(input, input_copy_name) \ - const uint8_t *input_copy_name = NULL; -#define LOCAL_INPUT_ALLOC(input, length, input_copy) \ - input_copy = input; -#define LOCAL_INPUT_FREE(input, input_copy) \ - input_copy = NULL; -#define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \ - uint8_t *output_copy_name = NULL; -#define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ - output_copy = output; -#define LOCAL_OUTPUT_FREE(output, output_copy) \ - output_copy = NULL; -#endif /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ - - -int psa_can_do_hash(psa_algorithm_t hash_alg) -{ - (void) hash_alg; - return psa_get_drivers_initialized(); -} - -int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg) -{ - (void) key_type; - (void) cipher_alg; - return psa_get_drivers_initialized(); -} - - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \ - defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) -static int psa_is_dh_key_size_valid(size_t bits) -{ - switch (bits) { -#if defined(PSA_WANT_DH_RFC7919_2048) - case 2048: - return 1; -#endif /* PSA_WANT_DH_RFC7919_2048 */ -#if defined(PSA_WANT_DH_RFC7919_3072) - case 3072: - return 1; -#endif /* PSA_WANT_DH_RFC7919_3072 */ -#if defined(PSA_WANT_DH_RFC7919_4096) - case 4096: - return 1; -#endif /* PSA_WANT_DH_RFC7919_4096 */ -#if defined(PSA_WANT_DH_RFC7919_6144) - case 6144: - return 1; -#endif /* PSA_WANT_DH_RFC7919_6144 */ -#if defined(PSA_WANT_DH_RFC7919_8192) - case 8192: - return 1; -#endif /* PSA_WANT_DH_RFC7919_8192 */ - default: - return 0; - } -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT || - MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY || - PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */ - -psa_status_t mbedtls_to_psa_error(int ret) -{ - /* Mbed TLS error codes can combine a high-level error code and a - * low-level error code. The low-level error usually reflects the - * root cause better, so dispatch on that preferably. */ - int low_level_ret = -(-ret & 0x007f); - switch (low_level_ret != 0 ? low_level_ret : ret) { - case 0: - return PSA_SUCCESS; - -#if defined(MBEDTLS_AES_C) - case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH: - case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_AES_BAD_INPUT_DATA: - return PSA_ERROR_INVALID_ARGUMENT; -#endif - -#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_ASN1_WRITE_C) - case MBEDTLS_ERR_ASN1_OUT_OF_DATA: - case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG: - case MBEDTLS_ERR_ASN1_INVALID_LENGTH: - case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH: - case MBEDTLS_ERR_ASN1_INVALID_DATA: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_ASN1_ALLOC_FAILED: - return PSA_ERROR_INSUFFICIENT_MEMORY; - case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL: - return PSA_ERROR_BUFFER_TOO_SMALL; -#endif - -#if defined(MBEDTLS_CAMELLIA_C) - case MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA: - case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH: - return PSA_ERROR_NOT_SUPPORTED; -#endif - -#if defined(MBEDTLS_CCM_C) - case MBEDTLS_ERR_CCM_BAD_INPUT: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_CCM_AUTH_FAILED: - return PSA_ERROR_INVALID_SIGNATURE; -#endif - -#if defined(MBEDTLS_CHACHA20_C) - case MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA: - return PSA_ERROR_INVALID_ARGUMENT; -#endif - -#if defined(MBEDTLS_CHACHAPOLY_C) - case MBEDTLS_ERR_CHACHAPOLY_BAD_STATE: - return PSA_ERROR_BAD_STATE; - case MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED: - return PSA_ERROR_INVALID_SIGNATURE; -#endif - -#if defined(MBEDTLS_CIPHER_C) - case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_CIPHER_ALLOC_FAILED: - return PSA_ERROR_INSUFFICIENT_MEMORY; - case MBEDTLS_ERR_CIPHER_INVALID_PADDING: - return PSA_ERROR_INVALID_PADDING; - case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_CIPHER_AUTH_FAILED: - return PSA_ERROR_INVALID_SIGNATURE; - case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT: - return PSA_ERROR_CORRUPTION_DETECTED; -#endif - -#if !(defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || \ - defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)) - /* Only check CTR_DRBG error codes if underlying mbedtls_xxx - * functions are passed a CTR_DRBG instance. */ - case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED: - return PSA_ERROR_INSUFFICIENT_ENTROPY; - case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG: - case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR: - return PSA_ERROR_INSUFFICIENT_ENTROPY; -#endif - -#if defined(MBEDTLS_DES_C) - case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH: - return PSA_ERROR_NOT_SUPPORTED; -#endif - - case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED: - case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE: - case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED: - return PSA_ERROR_INSUFFICIENT_ENTROPY; - -#if defined(MBEDTLS_GCM_C) - case MBEDTLS_ERR_GCM_AUTH_FAILED: - return PSA_ERROR_INVALID_SIGNATURE; - case MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL: - return PSA_ERROR_BUFFER_TOO_SMALL; - case MBEDTLS_ERR_GCM_BAD_INPUT: - return PSA_ERROR_INVALID_ARGUMENT; -#endif - -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \ - defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE) - /* Only check HMAC_DRBG error codes if underlying mbedtls_xxx - * functions are passed a HMAC_DRBG instance. */ - case MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED: - return PSA_ERROR_INSUFFICIENT_ENTROPY; - case MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG: - case MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR: - return PSA_ERROR_INSUFFICIENT_ENTROPY; -#endif - -#if defined(MBEDTLS_MD_LIGHT) - case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_MD_BAD_INPUT_DATA: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_MD_ALLOC_FAILED: - return PSA_ERROR_INSUFFICIENT_MEMORY; -#if defined(MBEDTLS_FS_IO) - case MBEDTLS_ERR_MD_FILE_IO_ERROR: - return PSA_ERROR_STORAGE_FAILURE; -#endif -#endif - -#if defined(MBEDTLS_BIGNUM_C) -#if defined(MBEDTLS_FS_IO) - case MBEDTLS_ERR_MPI_FILE_IO_ERROR: - return PSA_ERROR_STORAGE_FAILURE; -#endif - case MBEDTLS_ERR_MPI_BAD_INPUT_DATA: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_MPI_INVALID_CHARACTER: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL: - return PSA_ERROR_BUFFER_TOO_SMALL; - case MBEDTLS_ERR_MPI_NEGATIVE_VALUE: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_MPI_ALLOC_FAILED: - return PSA_ERROR_INSUFFICIENT_MEMORY; -#endif - -#if defined(MBEDTLS_PK_C) - case MBEDTLS_ERR_PK_ALLOC_FAILED: - return PSA_ERROR_INSUFFICIENT_MEMORY; - case MBEDTLS_ERR_PK_TYPE_MISMATCH: - case MBEDTLS_ERR_PK_BAD_INPUT_DATA: - return PSA_ERROR_INVALID_ARGUMENT; -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || defined(MBEDTLS_FS_IO) || \ - defined(MBEDTLS_PSA_ITS_FILE_C) - case MBEDTLS_ERR_PK_FILE_IO_ERROR: - return PSA_ERROR_STORAGE_FAILURE; -#endif - case MBEDTLS_ERR_PK_KEY_INVALID_VERSION: - case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_PK_PASSWORD_REQUIRED: - case MBEDTLS_ERR_PK_PASSWORD_MISMATCH: - return PSA_ERROR_NOT_PERMITTED; - case MBEDTLS_ERR_PK_INVALID_PUBKEY: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_PK_INVALID_ALG: - case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE: - case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH: - return PSA_ERROR_INVALID_SIGNATURE; - case MBEDTLS_ERR_PK_BUFFER_TOO_SMALL: - return PSA_ERROR_BUFFER_TOO_SMALL; -#endif - - case MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED: - return PSA_ERROR_HARDWARE_FAILURE; - case MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED: - return PSA_ERROR_NOT_SUPPORTED; - -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_ERR_RSA_BAD_INPUT_DATA: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_RSA_INVALID_PADDING: - return PSA_ERROR_INVALID_PADDING; - case MBEDTLS_ERR_RSA_KEY_GEN_FAILED: - return PSA_ERROR_HARDWARE_FAILURE; - case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_RSA_PUBLIC_FAILED: - case MBEDTLS_ERR_RSA_PRIVATE_FAILED: - return PSA_ERROR_CORRUPTION_DETECTED; - case MBEDTLS_ERR_RSA_VERIFY_FAILED: - return PSA_ERROR_INVALID_SIGNATURE; - case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE: - return PSA_ERROR_BUFFER_TOO_SMALL; - case MBEDTLS_ERR_RSA_RNG_FAILED: - return PSA_ERROR_INSUFFICIENT_ENTROPY; -#endif - -#if defined(MBEDTLS_ECP_LIGHT) - case MBEDTLS_ERR_ECP_BAD_INPUT_DATA: - case MBEDTLS_ERR_ECP_INVALID_KEY: - return PSA_ERROR_INVALID_ARGUMENT; - case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL: - return PSA_ERROR_BUFFER_TOO_SMALL; - case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH: - case MBEDTLS_ERR_ECP_VERIFY_FAILED: - return PSA_ERROR_INVALID_SIGNATURE; - case MBEDTLS_ERR_ECP_ALLOC_FAILED: - return PSA_ERROR_INSUFFICIENT_MEMORY; - case MBEDTLS_ERR_ECP_RANDOM_FAILED: - return PSA_ERROR_INSUFFICIENT_ENTROPY; - -#if defined(MBEDTLS_ECP_RESTARTABLE) - case MBEDTLS_ERR_ECP_IN_PROGRESS: - return PSA_OPERATION_INCOMPLETE; -#endif -#endif - - case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED: - return PSA_ERROR_CORRUPTION_DETECTED; - - default: - return PSA_ERROR_GENERIC_ERROR; - } -} - -/** - * \brief For output buffers which contain "tags" - * (outputs that may be checked for validity like - * hashes, MACs and signatures), fill the unused - * part of the output buffer (the whole buffer on - * error, the trailing part on success) with - * something that isn't a valid tag (barring an - * attack on the tag and deliberately-crafted - * input), in case the caller doesn't check the - * return status properly. - * - * \param output_buffer Pointer to buffer to wipe. May not be NULL - * unless \p output_buffer_size is zero. - * \param status Status of function called to generate - * output_buffer originally - * \param output_buffer_size Size of output buffer. If zero, \p output_buffer - * could be NULL. - * \param output_buffer_length Length of data written to output_buffer, must be - * less than \p output_buffer_size - */ -static void psa_wipe_tag_output_buffer(uint8_t *output_buffer, psa_status_t status, - size_t output_buffer_size, size_t output_buffer_length) -{ - size_t offset = 0; - - if (output_buffer_size == 0) { - /* If output_buffer_size is 0 then we have nothing to do. We must not - call memset because output_buffer may be NULL in this case */ - return; - } - - if (status == PSA_SUCCESS) { - offset = output_buffer_length; - } - - memset(output_buffer + offset, '!', output_buffer_size - offset); -} - - -psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type, - size_t bits) -{ - /* Check that the bit size is acceptable for the key type */ - switch (type) { - case PSA_KEY_TYPE_RAW_DATA: - case PSA_KEY_TYPE_HMAC: - case PSA_KEY_TYPE_DERIVE: - case PSA_KEY_TYPE_PASSWORD: - case PSA_KEY_TYPE_PASSWORD_HASH: - break; -#if defined(PSA_WANT_KEY_TYPE_AES) - case PSA_KEY_TYPE_AES: - if (bits != 128 && bits != 192 && bits != 256) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif -#if defined(PSA_WANT_KEY_TYPE_ARIA) - case PSA_KEY_TYPE_ARIA: - if (bits != 128 && bits != 192 && bits != 256) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif -#if defined(PSA_WANT_KEY_TYPE_CAMELLIA) - case PSA_KEY_TYPE_CAMELLIA: - if (bits != 128 && bits != 192 && bits != 256) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif -#if defined(PSA_WANT_KEY_TYPE_DES) - case PSA_KEY_TYPE_DES: - if (bits != 64 && bits != 128 && bits != 192) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif -#if defined(PSA_WANT_KEY_TYPE_CHACHA20) - case PSA_KEY_TYPE_CHACHA20: - if (bits != 256) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif - default: - return PSA_ERROR_NOT_SUPPORTED; - } - if (bits % 8 != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - return PSA_SUCCESS; -} - -/** Check whether a given key type is valid for use with a given MAC algorithm - * - * Upon successful return of this function, the behavior of #PSA_MAC_LENGTH - * when called with the validated \p algorithm and \p key_type is well-defined. - * - * \param[in] algorithm The specific MAC algorithm (can be wildcard). - * \param[in] key_type The key type of the key to be used with the - * \p algorithm. - * - * \retval #PSA_SUCCESS - * The \p key_type is valid for use with the \p algorithm - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The \p key_type is not valid for use with the \p algorithm - */ -MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do( - psa_algorithm_t algorithm, - psa_key_type_t key_type) -{ - if (PSA_ALG_IS_HMAC(algorithm)) { - if (key_type == PSA_KEY_TYPE_HMAC) { - return PSA_SUCCESS; - } - } - - if (PSA_ALG_IS_BLOCK_CIPHER_MAC(algorithm)) { - /* Check that we're calling PSA_BLOCK_CIPHER_BLOCK_LENGTH with a cipher - * key. */ - if ((key_type & PSA_KEY_TYPE_CATEGORY_MASK) == - PSA_KEY_TYPE_CATEGORY_SYMMETRIC) { - /* PSA_BLOCK_CIPHER_BLOCK_LENGTH returns 1 for stream ciphers and - * the block length (larger than 1) for block ciphers. */ - if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1) { - return PSA_SUCCESS; - } - } - } - - return PSA_ERROR_INVALID_ARGUMENT; -} - -psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot, - size_t buffer_length) -{ -#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) - if (buffer_length > ((size_t) MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)) { - return PSA_ERROR_NOT_SUPPORTED; - } -#else - if (slot->key.data != NULL) { - return PSA_ERROR_ALREADY_EXISTS; - } - - slot->key.data = mbedtls_calloc(1, buffer_length); - if (slot->key.data == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } -#endif - - slot->key.bytes = buffer_length; - return PSA_SUCCESS; -} - -psa_status_t psa_copy_key_material_into_slot(psa_key_slot_t *slot, - const uint8_t *data, - size_t data_length) -{ - psa_status_t status = psa_allocate_buffer_to_slot(slot, - data_length); - if (status != PSA_SUCCESS) { - return status; - } - - memcpy(slot->key.data, data, data_length); - return PSA_SUCCESS; -} - -psa_status_t psa_import_key_into_slot( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t type = attributes->type; - - /* zero-length keys are never supported. */ - if (data_length == 0) { - return PSA_ERROR_NOT_SUPPORTED; - } - - if (key_type_is_raw_bytes(type)) { - *bits = PSA_BYTES_TO_BITS(data_length); - - status = psa_validate_unstructured_key_bit_size(attributes->type, - *bits); - if (status != PSA_SUCCESS) { - return status; - } - - /* Copy the key material. */ - memcpy(key_buffer, data, data_length); - *key_buffer_length = data_length; - (void) key_buffer_size; - - return PSA_SUCCESS; - } else if (PSA_KEY_TYPE_IS_ASYMMETRIC(type)) { -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) - if (PSA_KEY_TYPE_IS_DH(type)) { - if (psa_is_dh_key_size_valid(PSA_BYTES_TO_BITS(data_length)) == 0) { - return PSA_ERROR_NOT_SUPPORTED; - } - return mbedtls_psa_ffdh_import_key(attributes, - data, data_length, - key_buffer, key_buffer_size, - key_buffer_length, - bits); - } -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */ -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) - if (PSA_KEY_TYPE_IS_ECC(type)) { - return mbedtls_psa_ecp_import_key(attributes, - data, data_length, - key_buffer, key_buffer_size, - key_buffer_length, - bits); - } -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ -#if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) - if (PSA_KEY_TYPE_IS_RSA(type)) { - return mbedtls_psa_rsa_import_key(attributes, - data, data_length, - key_buffer, key_buffer_size, - key_buffer_length, - bits); - } -#endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ - } - - return PSA_ERROR_NOT_SUPPORTED; -} - -/** Calculate the intersection of two algorithm usage policies. - * - * Return 0 (which allows no operation) on incompatibility. - */ -static psa_algorithm_t psa_key_policy_algorithm_intersection( - psa_key_type_t key_type, - psa_algorithm_t alg1, - psa_algorithm_t alg2) -{ - /* Common case: both sides actually specify the same policy. */ - if (alg1 == alg2) { - return alg1; - } - /* If the policies are from the same hash-and-sign family, check - * if one is a wildcard. If so the other has the specific algorithm. */ - if (PSA_ALG_IS_SIGN_HASH(alg1) && - PSA_ALG_IS_SIGN_HASH(alg2) && - (alg1 & ~PSA_ALG_HASH_MASK) == (alg2 & ~PSA_ALG_HASH_MASK)) { - if (PSA_ALG_SIGN_GET_HASH(alg1) == PSA_ALG_ANY_HASH) { - return alg2; - } - if (PSA_ALG_SIGN_GET_HASH(alg2) == PSA_ALG_ANY_HASH) { - return alg1; - } - } - /* If the policies are from the same AEAD family, check whether - * one of them is a minimum-tag-length wildcard. Calculate the most - * restrictive tag length. */ - if (PSA_ALG_IS_AEAD(alg1) && PSA_ALG_IS_AEAD(alg2) && - (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg1, 0) == - PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg2, 0))) { - size_t alg1_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg1); - size_t alg2_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg2); - size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len; - - /* If both are wildcards, return most restrictive wildcard */ - if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) && - ((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) { - return PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( - alg1, restricted_len); - } - /* If only one is a wildcard, return specific algorithm if compatible. */ - if (((alg1 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) && - (alg1_len <= alg2_len)) { - return alg2; - } - if (((alg2 & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0) && - (alg2_len <= alg1_len)) { - return alg1; - } - } - /* If the policies are from the same MAC family, check whether one - * of them is a minimum-MAC-length policy. Calculate the most - * restrictive tag length. */ - if (PSA_ALG_IS_MAC(alg1) && PSA_ALG_IS_MAC(alg2) && - (PSA_ALG_FULL_LENGTH_MAC(alg1) == - PSA_ALG_FULL_LENGTH_MAC(alg2))) { - /* Validate the combination of key type and algorithm. Since the base - * algorithm of alg1 and alg2 are the same, we only need this once. */ - if (PSA_SUCCESS != psa_mac_key_can_do(alg1, key_type)) { - return 0; - } - - /* Get the (exact or at-least) output lengths for both sides of the - * requested intersection. None of the currently supported algorithms - * have an output length dependent on the actual key size, so setting it - * to a bogus value of 0 is currently OK. - * - * Note that for at-least-this-length wildcard algorithms, the output - * length is set to the shortest allowed length, which allows us to - * calculate the most restrictive tag length for the intersection. */ - size_t alg1_len = PSA_MAC_LENGTH(key_type, 0, alg1); - size_t alg2_len = PSA_MAC_LENGTH(key_type, 0, alg2); - size_t restricted_len = alg1_len > alg2_len ? alg1_len : alg2_len; - - /* If both are wildcards, return most restrictive wildcard */ - if (((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) && - ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0)) { - return PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(alg1, restricted_len); - } - - /* If only one is an at-least-this-length policy, the intersection would - * be the other (fixed-length) policy as long as said fixed length is - * equal to or larger than the shortest allowed length. */ - if ((alg1 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) { - return (alg1_len <= alg2_len) ? alg2 : 0; - } - if ((alg2 & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) { - return (alg2_len <= alg1_len) ? alg1 : 0; - } - - /* If none of them are wildcards, check whether they define the same tag - * length. This is still possible here when one is default-length and - * the other specific-length. Ensure to always return the - * specific-length version for the intersection. */ - if (alg1_len == alg2_len) { - return PSA_ALG_TRUNCATED_MAC(alg1, alg1_len); - } - } - /* If the policies are incompatible, allow nothing. */ - return 0; -} - -static int psa_key_algorithm_permits(psa_key_type_t key_type, - psa_algorithm_t policy_alg, - psa_algorithm_t requested_alg) -{ - /* Common case: the policy only allows requested_alg. */ - if (requested_alg == policy_alg) { - return 1; - } - /* If policy_alg is a hash-and-sign with a wildcard for the hash, - * and requested_alg is the same hash-and-sign family with any hash, - * then requested_alg is compliant with policy_alg. */ - if (PSA_ALG_IS_SIGN_HASH(requested_alg) && - PSA_ALG_SIGN_GET_HASH(policy_alg) == PSA_ALG_ANY_HASH) { - return (policy_alg & ~PSA_ALG_HASH_MASK) == - (requested_alg & ~PSA_ALG_HASH_MASK); - } - /* If policy_alg is a wildcard AEAD algorithm of the same base as - * the requested algorithm, check the requested tag length to be - * equal-length or longer than the wildcard-specified length. */ - if (PSA_ALG_IS_AEAD(policy_alg) && - PSA_ALG_IS_AEAD(requested_alg) && - (PSA_ALG_AEAD_WITH_SHORTENED_TAG(policy_alg, 0) == - PSA_ALG_AEAD_WITH_SHORTENED_TAG(requested_alg, 0)) && - ((policy_alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0)) { - return PSA_ALG_AEAD_GET_TAG_LENGTH(policy_alg) <= - PSA_ALG_AEAD_GET_TAG_LENGTH(requested_alg); - } - /* If policy_alg is a MAC algorithm of the same base as the requested - * algorithm, check whether their MAC lengths are compatible. */ - if (PSA_ALG_IS_MAC(policy_alg) && - PSA_ALG_IS_MAC(requested_alg) && - (PSA_ALG_FULL_LENGTH_MAC(policy_alg) == - PSA_ALG_FULL_LENGTH_MAC(requested_alg))) { - /* Validate the combination of key type and algorithm. Since the policy - * and requested algorithms are the same, we only need this once. */ - if (PSA_SUCCESS != psa_mac_key_can_do(policy_alg, key_type)) { - return 0; - } - - /* Get both the requested output length for the algorithm which is to be - * verified, and the default output length for the base algorithm. - * Note that none of the currently supported algorithms have an output - * length dependent on actual key size, so setting it to a bogus value - * of 0 is currently OK. */ - size_t requested_output_length = PSA_MAC_LENGTH( - key_type, 0, requested_alg); - size_t default_output_length = PSA_MAC_LENGTH( - key_type, 0, - PSA_ALG_FULL_LENGTH_MAC(requested_alg)); - - /* If the policy is default-length, only allow an algorithm with - * a declared exact-length matching the default. */ - if (PSA_MAC_TRUNCATED_LENGTH(policy_alg) == 0) { - return requested_output_length == default_output_length; - } - - /* If the requested algorithm is default-length, allow it if the policy - * length exactly matches the default length. */ - if (PSA_MAC_TRUNCATED_LENGTH(requested_alg) == 0 && - PSA_MAC_TRUNCATED_LENGTH(policy_alg) == default_output_length) { - return 1; - } - - /* If policy_alg is an at-least-this-length wildcard MAC algorithm, - * check for the requested MAC length to be equal to or longer than the - * minimum allowed length. */ - if ((policy_alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0) { - return PSA_MAC_TRUNCATED_LENGTH(policy_alg) <= - requested_output_length; - } - } - /* If policy_alg is a generic key agreement operation, then using it for - * a key derivation with that key agreement should also be allowed. This - * behaviour is expected to be defined in a future specification version. */ - if (PSA_ALG_IS_RAW_KEY_AGREEMENT(policy_alg) && - PSA_ALG_IS_KEY_AGREEMENT(requested_alg)) { - return PSA_ALG_KEY_AGREEMENT_GET_BASE(requested_alg) == - policy_alg; - } - /* If it isn't explicitly permitted, it's forbidden. */ - return 0; -} - -/** Test whether a policy permits an algorithm. - * - * The caller must test usage flags separately. - * - * \note This function requires providing the key type for which the policy is - * being validated, since some algorithm policy definitions (e.g. MAC) - * have different properties depending on what kind of cipher it is - * combined with. - * - * \retval PSA_SUCCESS When \p alg is a specific algorithm - * allowed by the \p policy. - * \retval PSA_ERROR_INVALID_ARGUMENT When \p alg is not a specific algorithm - * \retval PSA_ERROR_NOT_PERMITTED When \p alg is a specific algorithm, but - * the \p policy does not allow it. - */ -static psa_status_t psa_key_policy_permits(const psa_key_policy_t *policy, - psa_key_type_t key_type, - psa_algorithm_t alg) -{ - /* '0' is not a valid algorithm */ - if (alg == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* A requested algorithm cannot be a wildcard. */ - if (PSA_ALG_IS_WILDCARD(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (psa_key_algorithm_permits(key_type, policy->alg, alg) || - psa_key_algorithm_permits(key_type, policy->alg2, alg)) { - return PSA_SUCCESS; - } else { - return PSA_ERROR_NOT_PERMITTED; - } -} - -/** Restrict a key policy based on a constraint. - * - * \note This function requires providing the key type for which the policy is - * being restricted, since some algorithm policy definitions (e.g. MAC) - * have different properties depending on what kind of cipher it is - * combined with. - * - * \param[in] key_type The key type for which to restrict the policy - * \param[in,out] policy The policy to restrict. - * \param[in] constraint The policy constraint to apply. - * - * \retval #PSA_SUCCESS - * \c *policy contains the intersection of the original value of - * \c *policy and \c *constraint. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c key_type, \c *policy and \c *constraint are incompatible. - * \c *policy is unchanged. - */ -static psa_status_t psa_restrict_key_policy( - psa_key_type_t key_type, - psa_key_policy_t *policy, - const psa_key_policy_t *constraint) -{ - psa_algorithm_t intersection_alg = - psa_key_policy_algorithm_intersection(key_type, policy->alg, - constraint->alg); - psa_algorithm_t intersection_alg2 = - psa_key_policy_algorithm_intersection(key_type, policy->alg2, - constraint->alg2); - if (intersection_alg == 0 && policy->alg != 0 && constraint->alg != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - if (intersection_alg2 == 0 && policy->alg2 != 0 && constraint->alg2 != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - policy->usage &= constraint->usage; - policy->alg = intersection_alg; - policy->alg2 = intersection_alg2; - return PSA_SUCCESS; -} - -/** Get the description of a key given its identifier and policy constraints - * and lock it. - * - * The key must have allow all the usage flags set in \p usage. If \p alg is - * nonzero, the key must allow operations with this algorithm. If \p alg is - * zero, the algorithm is not checked. - * - * In case of a persistent key, the function loads the description of the key - * into a key slot if not already done. - * - * On success, the returned key slot has been registered for reading. - * It is the responsibility of the caller to then unregister - * once they have finished reading the contents of the slot. - * The caller unregisters by calling psa_unregister_read() or - * psa_unregister_read_under_mutex(). psa_unregister_read() must be called - * if and only if the caller already holds the global key slot mutex - * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates - * the unregister with mutex lock and unlock operations. - */ -static psa_status_t psa_get_and_lock_key_slot_with_policy( - mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot, - psa_key_usage_t usage, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - - status = psa_get_and_lock_key_slot(key, p_slot); - if (status != PSA_SUCCESS) { - return status; - } - slot = *p_slot; - - /* Enforce that usage policy for the key slot contains all the flags - * required by the usage parameter. There is one exception: public - * keys can always be exported, so we treat public key objects as - * if they had the export flag. */ - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) { - usage &= ~PSA_KEY_USAGE_EXPORT; - } - - if ((slot->attr.policy.usage & usage) != usage) { - status = PSA_ERROR_NOT_PERMITTED; - goto error; - } - - /* Enforce that the usage policy permits the requested algorithm. */ - if (alg != 0) { - status = psa_key_policy_permits(&slot->attr.policy, - slot->attr.type, - alg); - if (status != PSA_SUCCESS) { - goto error; - } - } - - return PSA_SUCCESS; - -error: - *p_slot = NULL; - psa_unregister_read_under_mutex(slot); - - return status; -} - -/** Get a key slot containing a transparent key and lock it. - * - * A transparent key is a key for which the key material is directly - * available, as opposed to a key in a secure element and/or to be used - * by a secure element. - * - * This is a temporary function that may be used instead of - * psa_get_and_lock_key_slot_with_policy() when there is no opaque key support - * for a cryptographic operation. - * - * On success, the returned key slot has been registered for reading. - * It is the responsibility of the caller to then unregister - * once they have finished reading the contents of the slot. - * The caller unregisters by calling psa_unregister_read() or - * psa_unregister_read_under_mutex(). psa_unregister_read() must be called - * if and only if the caller already holds the global key slot mutex - * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates - * psa_unregister_read() with mutex lock and unlock operations. - */ -static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy( - mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot, - psa_key_usage_t usage, - psa_algorithm_t alg) -{ - psa_status_t status = psa_get_and_lock_key_slot_with_policy(key, p_slot, - usage, alg); - if (status != PSA_SUCCESS) { - return status; - } - - if (psa_key_lifetime_is_external((*p_slot)->attr.lifetime)) { - psa_unregister_read_under_mutex(*p_slot); - *p_slot = NULL; - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_SUCCESS; -} - -psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot) -{ -#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) - if (slot->key.bytes > 0) { - mbedtls_platform_zeroize(slot->key.data, MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE); - } -#else - if (slot->key.data != NULL) { - mbedtls_zeroize_and_free(slot->key.data, slot->key.bytes); - } - - slot->key.data = NULL; -#endif /* MBEDTLS_PSA_STATIC_KEY_SLOTS */ - - slot->key.bytes = 0; - - return PSA_SUCCESS; -} - -/** Completely wipe a slot in memory, including its policy. - * Persistent storage is not affected. */ -psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) -{ - psa_status_t status = psa_remove_key_data_from_memory(slot); - - /* - * As the return error code may not be handled in case of multiple errors, - * do our best to report an unexpected amount of registered readers or - * an unexpected state. - * Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that the slot is valid for - * wiping. - * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the - * function is called as part of the execution of a test suite, the - * execution of the test suite is stopped in error if the assertion fails. - */ - switch (slot->state) { - case PSA_SLOT_FULL: - /* In this state psa_wipe_key_slot() must only be called if the - * caller is the last reader. */ - case PSA_SLOT_PENDING_DELETION: - /* In this state psa_wipe_key_slot() must only be called if the - * caller is the last reader. */ - if (slot->var.occupied.registered_readers != 1) { - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 1); - status = PSA_ERROR_CORRUPTION_DETECTED; - } - break; - case PSA_SLOT_FILLING: - /* In this state registered_readers must be 0. */ - if (slot->var.occupied.registered_readers != 0) { - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->var.occupied.registered_readers == 0); - status = PSA_ERROR_CORRUPTION_DETECTED; - } - break; - case PSA_SLOT_EMPTY: - /* The slot is already empty, it cannot be wiped. */ - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->state != PSA_SLOT_EMPTY); - status = PSA_ERROR_CORRUPTION_DETECTED; - break; - default: - /* The slot's state is invalid. */ - status = PSA_ERROR_CORRUPTION_DETECTED; - } - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - size_t slice_index = slot->slice_index; -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - - /* Multipart operations may still be using the key. This is safe - * because all multipart operation objects are independent from - * the key slot: if they need to access the key after the setup - * phase, they have a copy of the key. Note that this means that - * key material can linger until all operations are completed. */ - /* At this point, key material and other type-specific content has - * been wiped. Clear remaining metadata. We can call memset and not - * zeroize because the metadata is not particularly sensitive. - * This memset also sets the slot's state to PSA_SLOT_EMPTY. */ - memset(slot, 0, sizeof(*slot)); - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - /* If the slot is already corrupted, something went deeply wrong, - * like a thread still using the slot or a stray pointer leading - * to the slot's memory being used for another object. Let the slot - * leak rather than make the corruption worse. */ - if (status == PSA_SUCCESS) { - status = psa_free_key_slot(slice_index, slot); - } -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - return status; -} - -psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) -{ - psa_key_slot_t *slot; - psa_status_t status; /* status of the last operation */ - psa_status_t overall_status = PSA_SUCCESS; -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - psa_se_drv_table_entry_t *driver; -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - if (mbedtls_svc_key_id_is_null(key)) { - return PSA_SUCCESS; - } - - /* - * Get the description of the key in a key slot, and register to read it. - * In the case of a persistent key, this will load the key description - * from persistent memory if not done yet. - * We cannot avoid this loading as without it we don't know if - * the key is operated by an SE or not and this information is needed by - * the current implementation. */ - status = psa_get_and_lock_key_slot(key, &slot); - if (status != PSA_SUCCESS) { - return status; - } - -#if defined(MBEDTLS_THREADING_C) - /* We cannot unlock between setting the state to PENDING_DELETION - * and destroying the key in storage, as otherwise another thread - * could load the key into a new slot and the key will not be - * fully destroyed. */ - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock( - &mbedtls_threading_key_slot_mutex)); - - if (slot->state == PSA_SLOT_PENDING_DELETION) { - /* Another thread has destroyed the key between us locking the slot - * and us gaining the mutex. Unregister from the slot, - * and report that the key does not exist. */ - status = psa_unregister_read(slot); - - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); - return (status == PSA_SUCCESS) ? PSA_ERROR_INVALID_HANDLE : status; - } -#endif - /* Set the key slot containing the key description's state to - * PENDING_DELETION. This stops new operations from registering - * to read the slot. Current readers can safely continue to access - * the key within the slot; the last registered reader will - * automatically wipe the slot when they call psa_unregister_read(). - * If the key is persistent, we can now delete the copy of the key - * from memory. If the key is opaque, we require the driver to - * deal with the deletion. */ - overall_status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL, - PSA_SLOT_PENDING_DELETION); - - if (overall_status != PSA_SUCCESS) { - goto exit; - } - - if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) { - /* Refuse the destruction of a read-only key (which may or may not work - * if we attempt it, depending on whether the key is merely read-only - * by policy or actually physically read-only). - * Just do the best we can, which is to wipe the copy in memory - * (done in this function's cleanup code). */ - overall_status = PSA_ERROR_NOT_PERMITTED; - goto exit; - } - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - driver = psa_get_se_driver_entry(slot->attr.lifetime); - if (driver != NULL) { - /* For a key in a secure element, we need to do three things: - * remove the key file in internal storage, destroy the - * key inside the secure element, and update the driver's - * persistent data. Start a transaction that will encompass these - * three actions. */ - psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_DESTROY_KEY); - psa_crypto_transaction.key.lifetime = slot->attr.lifetime; - psa_crypto_transaction.key.slot = psa_key_slot_get_slot_number(slot); - psa_crypto_transaction.key.id = slot->attr.id; - status = psa_crypto_save_transaction(); - if (status != PSA_SUCCESS) { - (void) psa_crypto_stop_transaction(); - /* We should still try to destroy the key in the secure - * element and the key metadata in storage. This is especially - * important if the error is that the storage is full. - * But how to do it exactly without risking an inconsistent - * state after a reset? - * https://github.com/ARMmbed/mbed-crypto/issues/215 - */ - overall_status = status; - goto exit; - } - - status = psa_destroy_se_key(driver, - psa_key_slot_get_slot_number(slot)); - if (overall_status == PSA_SUCCESS) { - overall_status = status; - } - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { - /* Destroy the copy of the persistent key from storage. - * The slot will still hold a copy of the key until the last reader - * unregisters. */ - status = psa_destroy_persistent_key(slot->attr.id); - if (overall_status == PSA_SUCCESS) { - overall_status = status; - } - } -#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if (driver != NULL) { - status = psa_save_se_persistent_data(driver); - if (overall_status == PSA_SUCCESS) { - overall_status = status; - } - status = psa_crypto_stop_transaction(); - if (overall_status == PSA_SUCCESS) { - overall_status = status; - } - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - -exit: - /* Unregister from reading the slot. If we are the last active reader - * then this will wipe the slot. */ - status = psa_unregister_read(slot); - /* Prioritize CORRUPTION_DETECTED from unregistering over - * a storage error. */ - if (status != PSA_SUCCESS) { - overall_status = status; - } - -#if defined(MBEDTLS_THREADING_C) - /* Don't overwrite existing errors if the unlock fails. */ - status = overall_status; - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - - return overall_status; -} - -/** Retrieve all the publicly-accessible attributes of a key. - */ -psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, - psa_key_attributes_t *attributes) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - psa_reset_key_attributes(attributes); - - status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0); - if (status != PSA_SUCCESS) { - return status; - } - - *attributes = slot->attr; - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if (psa_get_se_driver_entry(slot->attr.lifetime) != NULL) { - psa_set_key_slot_number(attributes, - psa_key_slot_get_slot_number(slot)); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - return psa_unregister_read_under_mutex(slot); -} - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -psa_status_t psa_get_key_slot_number( - const psa_key_attributes_t *attributes, - psa_key_slot_number_t *slot_number) -{ - if (attributes->has_slot_number) { - *slot_number = attributes->slot_number; - return PSA_SUCCESS; - } else { - return PSA_ERROR_INVALID_ARGUMENT; - } -} -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - -static psa_status_t psa_export_key_buffer_internal(const uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *data, - size_t data_size, - size_t *data_length) -{ - if (key_buffer_size > data_size) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - memcpy(data, key_buffer, key_buffer_size); - memset(data + key_buffer_size, 0, - data_size - key_buffer_size); - *data_length = key_buffer_size; - return PSA_SUCCESS; -} - -psa_status_t psa_export_key_internal( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length) -{ - psa_key_type_t type = attributes->type; - - if (key_type_is_raw_bytes(type) || - PSA_KEY_TYPE_IS_RSA(type) || - PSA_KEY_TYPE_IS_ECC(type) || - PSA_KEY_TYPE_IS_DH(type)) { - return psa_export_key_buffer_internal( - key_buffer, key_buffer_size, - data, data_size, data_length); - } else { - /* This shouldn't happen in the built-in implementation, but - it is valid for a special-purpose drivers to omit - support for exporting certain key types. */ - return PSA_ERROR_NOT_SUPPORTED; - } -} - -psa_status_t psa_export_key(mbedtls_svc_key_id_t key, - uint8_t *data_external, - size_t data_size, - size_t *data_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - LOCAL_OUTPUT_DECLARE(data_external, data); - - /* Reject a zero-length output buffer now, since this can never be a - * valid key representation. This way we know that data must be a valid - * pointer and we can do things like memset(data, ..., data_size). */ - if (data_size == 0) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - /* Set the key to empty now, so that even when there are errors, we always - * set data_length to a value between 0 and data_size. On error, setting - * the key to empty is a good choice because an empty key representation is - * unlikely to be accepted anywhere. */ - *data_length = 0; - - /* Export requires the EXPORT flag. There is an exception for public keys, - * which don't require any flag, but - * psa_get_and_lock_key_slot_with_policy() takes care of this. - */ - status = psa_get_and_lock_key_slot_with_policy(key, &slot, - PSA_KEY_USAGE_EXPORT, 0); - if (status != PSA_SUCCESS) { - return status; - } - - LOCAL_OUTPUT_ALLOC(data_external, data_size, data); - - status = psa_driver_wrapper_export_key(&slot->attr, - slot->key.data, slot->key.bytes, - data, data_size, data_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - unlock_status = psa_unregister_read_under_mutex(slot); - - LOCAL_OUTPUT_FREE(data_external, data); - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_export_public_key_internal( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *data, - size_t data_size, - size_t *data_length) -{ - psa_key_type_t type = attributes->type; - - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) && - (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) || - PSA_KEY_TYPE_IS_DH(type))) { - /* Exporting public -> public */ - return psa_export_key_buffer_internal( - key_buffer, key_buffer_size, - data, data_size, data_length); - } else if (PSA_KEY_TYPE_IS_RSA(type)) { -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) - return mbedtls_psa_rsa_export_public_key(attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length); -#else - /* We don't know how to convert a private RSA key to public. */ - return PSA_ERROR_NOT_SUPPORTED; -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ - } else if (PSA_KEY_TYPE_IS_ECC(type)) { -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) - return mbedtls_psa_ecp_export_public_key(attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length); -#else - /* We don't know how to convert a private ECC key to public */ - return PSA_ERROR_NOT_SUPPORTED; -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ - } else if (PSA_KEY_TYPE_IS_DH(type)) { -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) - return mbedtls_psa_ffdh_export_public_key(attributes, - key_buffer, - key_buffer_size, - data, data_size, - data_length); -#else - return PSA_ERROR_NOT_SUPPORTED; -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */ - } else { - (void) key_buffer; - (void) key_buffer_size; - (void) data; - (void) data_size; - (void) data_length; - return PSA_ERROR_NOT_SUPPORTED; - } -} - -psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, - uint8_t *data_external, - size_t data_size, - size_t *data_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - LOCAL_OUTPUT_DECLARE(data_external, data); - - /* Reject a zero-length output buffer now, since this can never be a - * valid key representation. This way we know that data must be a valid - * pointer and we can do things like memset(data, ..., data_size). */ - if (data_size == 0) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - /* Set the key to empty now, so that even when there are errors, we always - * set data_length to a value between 0 and data_size. On error, setting - * the key to empty is a good choice because an empty key representation is - * unlikely to be accepted anywhere. */ - *data_length = 0; - - /* Exporting a public key doesn't require a usage flag. */ - status = psa_get_and_lock_key_slot_with_policy(key, &slot, 0, 0); - if (status != PSA_SUCCESS) { - return status; - } - - LOCAL_OUTPUT_ALLOC(data_external, data_size, data); - - if (!PSA_KEY_TYPE_IS_ASYMMETRIC(slot->attr.type)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - status = psa_driver_wrapper_export_public_key( - &slot->attr, slot->key.data, slot->key.bytes, - data, data_size, data_length); - -exit: - unlock_status = psa_unregister_read_under_mutex(slot); - - LOCAL_OUTPUT_FREE(data_external, data); - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -/** Validate that a key policy is internally well-formed. - * - * This function only rejects invalid policies. It does not validate the - * consistency of the policy with respect to other attributes of the key - * such as the key type. - */ -static psa_status_t psa_validate_key_policy(const psa_key_policy_t *policy) -{ - if ((policy->usage & ~(PSA_KEY_USAGE_EXPORT | - PSA_KEY_USAGE_COPY | - PSA_KEY_USAGE_ENCRYPT | - PSA_KEY_USAGE_DECRYPT | - PSA_KEY_USAGE_SIGN_MESSAGE | - PSA_KEY_USAGE_VERIFY_MESSAGE | - PSA_KEY_USAGE_SIGN_HASH | - PSA_KEY_USAGE_VERIFY_HASH | - PSA_KEY_USAGE_VERIFY_DERIVATION | - PSA_KEY_USAGE_DERIVE)) != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - return PSA_SUCCESS; -} - -/** Validate the internal consistency of key attributes. - * - * This function only rejects invalid attribute values. If does not - * validate the consistency of the attributes with any key data that may - * be involved in the creation of the key. - * - * Call this function early in the key creation process. - * - * \param[in] attributes Key attributes for the new key. - * \param[out] p_drv On any return, the driver for the key, if any. - * NULL for a transparent key. - * - */ -static psa_status_t psa_validate_key_attributes( - const psa_key_attributes_t *attributes, - psa_se_drv_table_entry_t **p_drv) -{ - psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - psa_key_lifetime_t lifetime = psa_get_key_lifetime(attributes); - mbedtls_svc_key_id_t key = psa_get_key_id(attributes); - - status = psa_validate_key_location(lifetime, p_drv); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_validate_key_persistence(lifetime); - if (status != PSA_SUCCESS) { - return status; - } - - if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { - if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key) != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } else { - if (!psa_is_valid_key_id(psa_get_key_id(attributes), 0)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - status = psa_validate_key_policy(&attributes->policy); - if (status != PSA_SUCCESS) { - return status; - } - - /* Refuse to create overly large keys. - * Note that this doesn't trigger on import if the attributes don't - * explicitly specify a size (so psa_get_key_bits returns 0), so - * psa_import_key() needs its own checks. */ - if (psa_get_key_bits(attributes) > PSA_MAX_KEY_BITS) { - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_SUCCESS; -} - -/** Prepare a key slot to receive key material. - * - * This function allocates a key slot and sets its metadata. - * - * If this function fails, call psa_fail_key_creation(). - * - * This function is intended to be used as follows: - * -# Call psa_start_key_creation() to allocate a key slot, prepare - * it with the specified attributes, and in case of a volatile key assign it - * a volatile key identifier. - * -# Populate the slot with the key material. - * -# Call psa_finish_key_creation() to finalize the creation of the slot. - * In case of failure at any step, stop the sequence and call - * psa_fail_key_creation(). - * - * On success, the key slot's state is PSA_SLOT_FILLING. - * It is the responsibility of the caller to change the slot's state to - * PSA_SLOT_EMPTY/FULL once key creation has finished. - * - * \param method An identification of the calling function. - * \param[in] attributes Key attributes for the new key. - * \param[out] p_slot On success, a pointer to the prepared slot. - * \param[out] p_drv On any return, the driver for the key, if any. - * NULL for a transparent key. - * - * \retval #PSA_SUCCESS - * The key slot is ready to receive key material. - * \return If this function fails, the key slot is an invalid state. - * You must call psa_fail_key_creation() to wipe and free the slot. - */ -static psa_status_t psa_start_key_creation( - psa_key_creation_method_t method, - const psa_key_attributes_t *attributes, - psa_key_slot_t **p_slot, - psa_se_drv_table_entry_t **p_drv) -{ - psa_status_t status; - - (void) method; - *p_drv = NULL; - - status = psa_validate_key_attributes(attributes, p_drv); - if (status != PSA_SUCCESS) { - return status; - } - - int key_is_volatile = PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime); - psa_key_id_t volatile_key_id; - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_lock( - &mbedtls_threading_key_slot_mutex)); -#endif - status = psa_reserve_free_key_slot( - key_is_volatile ? &volatile_key_id : NULL, - p_slot); -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - if (status != PSA_SUCCESS) { - return status; - } - psa_key_slot_t *slot = *p_slot; - - /* We're storing the declared bit-size of the key. It's up to each - * creation mechanism to verify that this information is correct. - * It's automatically correct for mechanisms that use the bit-size as - * an input (generate, device) but not for those where the bit-size - * is optional (import, copy). In case of a volatile key, assign it the - * volatile key identifier associated to the slot returned to contain its - * definition. */ - - slot->attr = *attributes; - if (key_is_volatile) { -#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) - slot->attr.id = volatile_key_id; -#else - slot->attr.id.key_id = volatile_key_id; -#endif - } - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* For a key in a secure element, we need to do three things - * when creating or registering a persistent key: - * create the key file in internal storage, create the - * key inside the secure element, and update the driver's - * persistent data. This is done by starting a transaction that will - * encompass these three actions. - * For registering a volatile key, we just need to find an appropriate - * slot number inside the SE. Since the key is designated volatile, creating - * a transaction is not required. */ - /* The first thing to do is to find a slot number for the new key. - * We save the slot number in persistent storage as part of the - * transaction data. It will be needed to recover if the power - * fails during the key creation process, to clean up on the secure - * element side after restarting. Obtaining a slot number from the - * secure element driver updates its persistent state, but we do not yet - * save the driver's persistent state, so that if the power fails, - * we can roll back to a state where the key doesn't exist. */ - if (*p_drv != NULL) { - psa_key_slot_number_t slot_number; - status = psa_find_se_slot_for_key(attributes, method, *p_drv, - &slot_number); - if (status != PSA_SUCCESS) { - return status; - } - - if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime)) { - psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_CREATE_KEY); - psa_crypto_transaction.key.lifetime = slot->attr.lifetime; - psa_crypto_transaction.key.slot = slot_number; - psa_crypto_transaction.key.id = slot->attr.id; - status = psa_crypto_save_transaction(); - if (status != PSA_SUCCESS) { - (void) psa_crypto_stop_transaction(); - return status; - } - } - - status = psa_copy_key_material_into_slot( - slot, (uint8_t *) (&slot_number), sizeof(slot_number)); - if (status != PSA_SUCCESS) { - return status; - } - } - - if (*p_drv == NULL && method == PSA_KEY_CREATION_REGISTER) { - /* Key registration only makes sense with a secure element. */ - return PSA_ERROR_INVALID_ARGUMENT; - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - return PSA_SUCCESS; -} - -/** Finalize the creation of a key once its key material has been set. - * - * This entails writing the key to persistent storage. - * - * If this function fails, call psa_fail_key_creation(). - * See the documentation of psa_start_key_creation() for the intended use - * of this function. - * - * If the finalization succeeds, the function sets the key slot's state to - * PSA_SLOT_FULL, and the key slot can no longer be accessed as part of the - * key creation process. - * - * \param[in,out] slot Pointer to the slot with key material. - * \param[in] driver The secure element driver for the key, - * or NULL for a transparent key. - * \param[out] key On success, identifier of the key. Note that the - * key identifier is also stored in the key slot. - * - * \retval #PSA_SUCCESS - * The key was successfully created. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * - * \return If this function fails, the key slot is an invalid state. - * You must call psa_fail_key_creation() to wipe and free the slot. - */ -static psa_status_t psa_finish_key_creation( - psa_key_slot_t *slot, - psa_se_drv_table_entry_t *driver, - mbedtls_svc_key_id_t *key) -{ - psa_status_t status = PSA_SUCCESS; - (void) slot; - (void) driver; - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_lock( - &mbedtls_threading_key_slot_mutex)); -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if (driver != NULL) { - psa_se_key_data_storage_t data; - psa_key_slot_number_t slot_number = - psa_key_slot_get_slot_number(slot); - - MBEDTLS_STATIC_ASSERT(sizeof(slot_number) == - sizeof(data.slot_number), - "Slot number size does not match psa_se_key_data_storage_t"); - - memcpy(&data.slot_number, &slot_number, sizeof(slot_number)); - status = psa_save_persistent_key(&slot->attr, - (uint8_t *) &data, - sizeof(data)); - } else -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - { - /* Key material is saved in export representation in the slot, so - * just pass the slot buffer for storage. */ - status = psa_save_persistent_key(&slot->attr, - slot->key.data, - slot->key.bytes); - } - } -#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* Finish the transaction for a key creation. This does not - * happen when registering an existing key. Detect this case - * by checking whether a transaction is in progress (actual - * creation of a persistent key in a secure element requires a transaction, - * but registration or volatile key creation doesn't use one). */ - if (driver != NULL && - psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY) { - status = psa_save_se_persistent_data(driver); - if (status != PSA_SUCCESS) { - psa_destroy_persistent_key(slot->attr.id); - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; - } - status = psa_crypto_stop_transaction(); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - if (status == PSA_SUCCESS) { - *key = slot->attr.id; - status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, - PSA_SLOT_FULL); - if (status != PSA_SUCCESS) { - *key = MBEDTLS_SVC_KEY_ID_INIT; - } - } - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; -} - -/** Abort the creation of a key. - * - * You may call this function after calling psa_start_key_creation(), - * or after psa_finish_key_creation() fails. In other circumstances, this - * function may not clean up persistent storage. - * See the documentation of psa_start_key_creation() for the intended use - * of this function. Sets the slot's state to PSA_SLOT_EMPTY. - * - * \param[in,out] slot Pointer to the slot with key material. - * \param[in] driver The secure element driver for the key, - * or NULL for a transparent key. - */ -static void psa_fail_key_creation(psa_key_slot_t *slot, - psa_se_drv_table_entry_t *driver) -{ - (void) driver; - - if (slot == NULL) { - return; - } - -#if defined(MBEDTLS_THREADING_C) - /* If the lock operation fails we still wipe the slot. - * Operations will no longer work after a failed lock, - * but we still need to wipe the slot of confidential data. */ - mbedtls_mutex_lock(&mbedtls_threading_key_slot_mutex); -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* TODO: If the key has already been created in the secure - * element, and the failure happened later (when saving metadata - * to internal storage), we need to destroy the key in the secure - * element. - * https://github.com/ARMmbed/mbed-crypto/issues/217 - */ - - /* Abort the ongoing transaction if any (there may not be one if - * the creation process failed before starting one, or if the - * key creation is a registration of a key in a secure element). - * Earlier functions must already have done what it takes to undo any - * partial creation. All that's left is to update the transaction data - * itself. */ - (void) psa_crypto_stop_transaction(); -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - psa_wipe_key_slot(slot); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_key_slot_mutex); -#endif -} - -/** Validate optional attributes during key creation. - * - * Some key attributes are optional during key creation. If they are - * specified in the attributes structure, check that they are consistent - * with the data in the slot. - * - * This function should be called near the end of key creation, after - * the slot in memory is fully populated but before saving persistent data. - */ -static psa_status_t psa_validate_optional_attributes( - const psa_key_slot_t *slot, - const psa_key_attributes_t *attributes) -{ - if (attributes->type != 0) { - if (attributes->type != slot->attr.type) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - if (attributes->bits != 0) { - if (attributes->bits != slot->attr.bits) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - return PSA_SUCCESS; -} - -psa_status_t psa_import_key(const psa_key_attributes_t *attributes, - const uint8_t *data_external, - size_t data_length, - mbedtls_svc_key_id_t *key) -{ - psa_status_t status; - LOCAL_INPUT_DECLARE(data_external, data); - psa_key_slot_t *slot = NULL; - psa_se_drv_table_entry_t *driver = NULL; - size_t bits; - size_t storage_size = data_length; - - *key = MBEDTLS_SVC_KEY_ID_INIT; - - /* Reject zero-length symmetric keys (including raw data key objects). - * This also rejects any key which might be encoded as an empty string, - * which is never valid. */ - if (data_length == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* Ensure that the bytes-to-bits conversion cannot overflow. */ - if (data_length > SIZE_MAX / 8) { - return PSA_ERROR_NOT_SUPPORTED; - } - - LOCAL_INPUT_ALLOC(data_external, data_length, data); - - status = psa_start_key_creation(PSA_KEY_CREATION_IMPORT, attributes, - &slot, &driver); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* In the case of a transparent key or an opaque key stored in local - * storage ( thus not in the case of importing a key in a secure element - * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a - * buffer to hold the imported key material. */ - if (slot->key.bytes == 0) { - if (psa_key_lifetime_is_external(attributes->lifetime)) { - status = psa_driver_wrapper_get_key_buffer_size_from_key_data( - attributes, data, data_length, &storage_size); - if (status != PSA_SUCCESS) { - goto exit; - } - } - status = psa_allocate_buffer_to_slot(slot, storage_size); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - bits = slot->attr.bits; - status = psa_driver_wrapper_import_key(attributes, - data, data_length, - slot->key.data, - slot->key.bytes, - &slot->key.bytes, &bits); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (slot->attr.bits == 0) { - slot->attr.bits = (psa_key_bits_t) bits; - } else if (bits != slot->attr.bits) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - /* Enforce a size limit, and in particular ensure that the bit - * size fits in its representation type.*/ - if (bits > PSA_MAX_KEY_BITS) { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = psa_validate_optional_attributes(slot, attributes); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_finish_key_creation(slot, driver, key); -exit: - LOCAL_INPUT_FREE(data_external, data); - if (status != PSA_SUCCESS) { - psa_fail_key_creation(slot, driver); - } - - return status; -} - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -psa_status_t mbedtls_psa_register_se_key( - const psa_key_attributes_t *attributes) -{ - psa_status_t status; - psa_key_slot_t *slot = NULL; - psa_se_drv_table_entry_t *driver = NULL; - mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; - - /* Leaving attributes unspecified is not currently supported. - * It could make sense to query the key type and size from the - * secure element, but not all secure elements support this - * and the driver HAL doesn't currently support it. */ - if (psa_get_key_type(attributes) == PSA_KEY_TYPE_NONE) { - return PSA_ERROR_NOT_SUPPORTED; - } - if (psa_get_key_bits(attributes) == 0) { - return PSA_ERROR_NOT_SUPPORTED; - } - - /* Not usable with volatile keys, even with an appropriate location, - * due to the API design. - * https://github.com/Mbed-TLS/mbedtls/issues/9253 - */ - if (PSA_KEY_LIFETIME_IS_VOLATILE(psa_get_key_lifetime(attributes))) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - status = psa_start_key_creation(PSA_KEY_CREATION_REGISTER, attributes, - &slot, &driver); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_finish_key_creation(slot, driver, &key); - -exit: - if (status != PSA_SUCCESS) { - psa_fail_key_creation(slot, driver); - } - - /* Registration doesn't keep the key in RAM. */ - psa_close_key(key); - return status; -} -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - -psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, - const psa_key_attributes_t *specified_attributes, - mbedtls_svc_key_id_t *target_key) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *source_slot = NULL; - psa_key_slot_t *target_slot = NULL; - psa_key_attributes_t actual_attributes = *specified_attributes; - psa_se_drv_table_entry_t *driver = NULL; - size_t storage_size = 0; - - *target_key = MBEDTLS_SVC_KEY_ID_INIT; - - status = psa_get_and_lock_key_slot_with_policy( - source_key, &source_slot, PSA_KEY_USAGE_COPY, 0); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_validate_optional_attributes(source_slot, - specified_attributes); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* The target key type and number of bits have been validated by - * psa_validate_optional_attributes() to be either equal to zero or - * equal to the ones of the source key. So it is safe to inherit - * them from the source key now." - * */ - actual_attributes.bits = source_slot->attr.bits; - actual_attributes.type = source_slot->attr.type; - - - status = psa_restrict_key_policy(source_slot->attr.type, - &actual_attributes.policy, - &source_slot->attr.policy); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_start_key_creation(PSA_KEY_CREATION_COPY, &actual_attributes, - &target_slot, &driver); - if (status != PSA_SUCCESS) { - goto exit; - } - if (PSA_KEY_LIFETIME_GET_LOCATION(target_slot->attr.lifetime) != - PSA_KEY_LIFETIME_GET_LOCATION(source_slot->attr.lifetime)) { - /* - * If the source and target keys are stored in different locations, - * the source key would need to be exported as plaintext and re-imported - * in the other location. This has security implications which have not - * been fully mapped. For now, this can be achieved through - * appropriate API invocations from the application, if needed. - * */ - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - /* - * When the source and target keys are within the same location, - * - For transparent keys it is a blind copy without any driver invocation, - * - For opaque keys this translates to an invocation of the drivers' - * copy_key entry point through the dispatch layer. - * */ - if (psa_key_lifetime_is_external(actual_attributes.lifetime)) { - status = psa_driver_wrapper_get_key_buffer_size(&actual_attributes, - &storage_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_allocate_buffer_to_slot(target_slot, storage_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_driver_wrapper_copy_key(&actual_attributes, - source_slot->key.data, - source_slot->key.bytes, - target_slot->key.data, - target_slot->key.bytes, - &target_slot->key.bytes); - if (status != PSA_SUCCESS) { - goto exit; - } - } else { - status = psa_copy_key_material_into_slot(target_slot, - source_slot->key.data, - source_slot->key.bytes); - if (status != PSA_SUCCESS) { - goto exit; - } - } - status = psa_finish_key_creation(target_slot, driver, target_key); -exit: - if (status != PSA_SUCCESS) { - psa_fail_key_creation(target_slot, driver); - } - - unlock_status = psa_unregister_read_under_mutex(source_slot); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - - - -/****************************************************************/ -/* Message digests */ -/****************************************************************/ - -static int is_hash_supported(psa_algorithm_t alg) -{ - switch (alg) { -#if defined(PSA_WANT_ALG_MD5) - case PSA_ALG_MD5: - return 1; -#endif -#if defined(PSA_WANT_ALG_RIPEMD160) - case PSA_ALG_RIPEMD160: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA_1) - case PSA_ALG_SHA_1: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA_224) - case PSA_ALG_SHA_224: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA_256) - case PSA_ALG_SHA_256: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA_384) - case PSA_ALG_SHA_384: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA_512) - case PSA_ALG_SHA_512: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA3_224) - case PSA_ALG_SHA3_224: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA3_256) - case PSA_ALG_SHA3_256: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA3_384) - case PSA_ALG_SHA3_384: - return 1; -#endif -#if defined(PSA_WANT_ALG_SHA3_512) - case PSA_ALG_SHA3_512: - return 1; -#endif - default: - return 0; - } -} - -psa_status_t psa_hash_abort(psa_hash_operation_t *operation) -{ - /* Aborting a non-active operation is allowed */ - if (operation->id == 0) { - return PSA_SUCCESS; - } - - psa_status_t status = psa_driver_wrapper_hash_abort(operation); - operation->id = 0; - - return status; -} - -psa_status_t psa_hash_setup(psa_hash_operation_t *operation, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - /* A context must be freshly initialized before it can be set up. */ - if (operation->id != 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (!PSA_ALG_IS_HASH(alg)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - /* Make sure the driver-dependent part of the operation is zeroed. - * This is a guarantee we make to drivers. Initializing the operation - * does not necessarily take care of it, since the context is a - * union and initializing a union does not necessarily initialize - * all of its members. */ - memset(&operation->ctx, 0, sizeof(operation->ctx)); - - status = psa_driver_wrapper_hash_setup(operation, alg); - -exit: - if (status != PSA_SUCCESS) { - psa_hash_abort(operation); - } - - return status; -} - -psa_status_t psa_hash_update(psa_hash_operation_t *operation, - const uint8_t *input_external, - size_t input_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(input_external, input); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - /* Don't require hash implementations to behave correctly on a - * zero-length input, which may have an invalid pointer. */ - if (input_length == 0) { - return PSA_SUCCESS; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - status = psa_driver_wrapper_hash_update(operation, input, input_length); - -exit: - if (status != PSA_SUCCESS) { - psa_hash_abort(operation); - } - - LOCAL_INPUT_FREE(input_external, input); - return status; -} - -static psa_status_t psa_hash_finish_internal(psa_hash_operation_t *operation, - uint8_t *hash, - size_t hash_size, - size_t *hash_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - *hash_length = 0; - if (operation->id == 0) { - return PSA_ERROR_BAD_STATE; - } - - status = psa_driver_wrapper_hash_finish( - operation, hash, hash_size, hash_length); - psa_hash_abort(operation); - - return status; -} - -psa_status_t psa_hash_finish(psa_hash_operation_t *operation, - uint8_t *hash_external, - size_t hash_size, - size_t *hash_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_OUTPUT_DECLARE(hash_external, hash); - - LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); - status = psa_hash_finish_internal(operation, hash, hash_size, hash_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_OUTPUT_FREE(hash_external, hash); - return status; -} - -psa_status_t psa_hash_verify(psa_hash_operation_t *operation, - const uint8_t *hash_external, - size_t hash_length) -{ - uint8_t actual_hash[PSA_HASH_MAX_SIZE]; - size_t actual_hash_length; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(hash_external, hash); - - status = psa_hash_finish_internal( - operation, - actual_hash, sizeof(actual_hash), - &actual_hash_length); - - if (status != PSA_SUCCESS) { - goto exit; - } - - if (actual_hash_length != hash_length) { - status = PSA_ERROR_INVALID_SIGNATURE; - goto exit; - } - - LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); - if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) { - status = PSA_ERROR_INVALID_SIGNATURE; - } - -exit: - mbedtls_platform_zeroize(actual_hash, sizeof(actual_hash)); - if (status != PSA_SUCCESS) { - psa_hash_abort(operation); - } - LOCAL_INPUT_FREE(hash_external, hash); - return status; -} - -psa_status_t psa_hash_compute(psa_algorithm_t alg, - const uint8_t *input_external, size_t input_length, - uint8_t *hash_external, size_t hash_size, - size_t *hash_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_OUTPUT_DECLARE(hash_external, hash); - - *hash_length = 0; - if (!PSA_ALG_IS_HASH(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); - status = psa_driver_wrapper_hash_compute(alg, input, input_length, - hash, hash_size, hash_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(input_external, input); - LOCAL_OUTPUT_FREE(hash_external, hash); - return status; -} - -psa_status_t psa_hash_compare(psa_algorithm_t alg, - const uint8_t *input_external, size_t input_length, - const uint8_t *hash_external, size_t hash_length) -{ - uint8_t actual_hash[PSA_HASH_MAX_SIZE]; - size_t actual_hash_length; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_INPUT_DECLARE(hash_external, hash); - - if (!PSA_ALG_IS_HASH(alg)) { - status = PSA_ERROR_INVALID_ARGUMENT; - return status; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - status = psa_driver_wrapper_hash_compute( - alg, input, input_length, - actual_hash, sizeof(actual_hash), - &actual_hash_length); - if (status != PSA_SUCCESS) { - goto exit; - } - if (actual_hash_length != hash_length) { - status = PSA_ERROR_INVALID_SIGNATURE; - goto exit; - } - - LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); - if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) { - status = PSA_ERROR_INVALID_SIGNATURE; - } - -exit: - mbedtls_platform_zeroize(actual_hash, sizeof(actual_hash)); - - LOCAL_INPUT_FREE(input_external, input); - LOCAL_INPUT_FREE(hash_external, hash); - - return status; -} - -psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, - psa_hash_operation_t *target_operation) -{ - if (source_operation->id == 0 || - target_operation->id != 0) { - return PSA_ERROR_BAD_STATE; - } - - /* Make sure the driver-dependent part of the operation is zeroed. - * This is a guarantee we make to drivers. Initializing the operation - * does not necessarily take care of it, since the context is a - * union and initializing a union does not necessarily initialize - * all of its members. */ - memset(&target_operation->ctx, 0, sizeof(target_operation->ctx)); - - psa_status_t status = psa_driver_wrapper_hash_clone(source_operation, - target_operation); - if (status != PSA_SUCCESS) { - psa_hash_abort(target_operation); - } - - return status; -} - - -/****************************************************************/ -/* MAC */ -/****************************************************************/ - -psa_status_t psa_mac_abort(psa_mac_operation_t *operation) -{ - /* Aborting a non-active operation is allowed */ - if (operation->id == 0) { - return PSA_SUCCESS; - } - - psa_status_t status = psa_driver_wrapper_mac_abort(operation); - operation->mac_size = 0; - operation->is_sign = 0; - operation->id = 0; - - return status; -} - -static psa_status_t psa_mac_finalize_alg_and_key_validation( - psa_algorithm_t alg, - const psa_key_attributes_t *attributes, - uint8_t *mac_size) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t key_type = psa_get_key_type(attributes); - size_t key_bits = psa_get_key_bits(attributes); - - if (!PSA_ALG_IS_MAC(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* Validate the combination of key type and algorithm */ - status = psa_mac_key_can_do(alg, key_type); - if (status != PSA_SUCCESS) { - return status; - } - - /* Get the output length for the algorithm and key combination */ - *mac_size = PSA_MAC_LENGTH(key_type, key_bits, alg); - - if (*mac_size < 4) { - /* A very short MAC is too short for security since it can be - * brute-forced. Ancient protocols with 32-bit MACs do exist, - * so we make this our minimum, even though 32 bits is still - * too small for security. */ - return PSA_ERROR_NOT_SUPPORTED; - } - - if (*mac_size > PSA_MAC_LENGTH(key_type, key_bits, - PSA_ALG_FULL_LENGTH_MAC(alg))) { - /* It's impossible to "truncate" to a larger length than the full length - * of the algorithm. */ - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (*mac_size > PSA_MAC_MAX_SIZE) { - /* PSA_MAC_LENGTH returns the correct length even for a MAC algorithm - * that is disabled in the compile-time configuration. The result can - * therefore be larger than PSA_MAC_MAX_SIZE, which does take the - * configuration into account. In this case, force a return of - * PSA_ERROR_NOT_SUPPORTED here. Otherwise psa_mac_verify(), or - * psa_mac_compute(mac_size=PSA_MAC_MAX_SIZE), would return - * PSA_ERROR_BUFFER_TOO_SMALL for an unsupported algorithm whose MAC size - * is larger than PSA_MAC_MAX_SIZE, which is misleading and which breaks - * systematically generated tests. */ - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_SUCCESS; -} - -static psa_status_t psa_mac_setup(psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - int is_sign) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - - /* A context must be freshly initialized before it can be set up. */ - if (operation->id != 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - /* Make sure the driver-dependent part of the operation is zeroed. - * This is a guarantee we make to drivers. Initializing the operation - * does not necessarily take care of it, since the context is a - * union and initializing a union does not necessarily initialize - * all of its members. */ - memset(&operation->ctx, 0, sizeof(operation->ctx)); - - status = psa_get_and_lock_key_slot_with_policy( - key, - &slot, - is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr, - &operation->mac_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - operation->is_sign = is_sign; - /* Dispatch the MAC setup call with validated input */ - if (is_sign) { - status = psa_driver_wrapper_mac_sign_setup(operation, - &slot->attr, - slot->key.data, - slot->key.bytes, - alg); - } else { - status = psa_driver_wrapper_mac_verify_setup(operation, - &slot->attr, - slot->key.data, - slot->key.bytes, - alg); - } - -exit: - if (status != PSA_SUCCESS) { - psa_mac_abort(operation); - } - - unlock_status = psa_unregister_read_under_mutex(slot); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg) -{ - return psa_mac_setup(operation, key, alg, 1); -} - -psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg) -{ - return psa_mac_setup(operation, key, alg, 0); -} - -psa_status_t psa_mac_update(psa_mac_operation_t *operation, - const uint8_t *input_external, - size_t input_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(input_external, input); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - return status; - } - - /* Don't require hash implementations to behave correctly on a - * zero-length input, which may have an invalid pointer. */ - if (input_length == 0) { - status = PSA_SUCCESS; - return status; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - status = psa_driver_wrapper_mac_update(operation, input, input_length); - - if (status != PSA_SUCCESS) { - psa_mac_abort(operation); - } - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(input_external, input); - - return status; -} - -psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, - uint8_t *mac_external, - size_t mac_size, - size_t *mac_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_OUTPUT_DECLARE(mac_external, mac); - LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (!operation->is_sign) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL) - * once all the error checks are done. */ - if (operation->mac_size == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (mac_size < operation->mac_size) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - - status = psa_driver_wrapper_mac_sign_finish(operation, - mac, operation->mac_size, - mac_length); - -exit: - /* In case of success, set the potential excess room in the output buffer - * to an invalid value, to avoid potentially leaking a longer MAC. - * In case of error, set the output length and content to a safe default, - * such that in case the caller misses an error check, the output would be - * an unachievable MAC. - */ - if (status != PSA_SUCCESS) { - *mac_length = mac_size; - operation->mac_size = 0; - } - - if (mac != NULL) { - psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length); - } - - abort_status = psa_mac_abort(operation); - LOCAL_OUTPUT_FREE(mac_external, mac); - - return status == PSA_SUCCESS ? abort_status : status; -} - -psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, - const uint8_t *mac_external, - size_t mac_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(mac_external, mac); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->is_sign) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->mac_size != mac_length) { - status = PSA_ERROR_INVALID_SIGNATURE; - goto exit; - } - - LOCAL_INPUT_ALLOC(mac_external, mac_length, mac); - status = psa_driver_wrapper_mac_verify_finish(operation, - mac, mac_length); - -exit: - abort_status = psa_mac_abort(operation); - LOCAL_INPUT_FREE(mac_external, mac); - - return status == PSA_SUCCESS ? abort_status : status; -} - -static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length, - int is_sign) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - uint8_t operation_mac_size = 0; - - status = psa_get_and_lock_key_slot_with_policy( - key, - &slot, - is_sign ? PSA_KEY_USAGE_SIGN_MESSAGE : PSA_KEY_USAGE_VERIFY_MESSAGE, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr, - &operation_mac_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (mac_size < operation_mac_size) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - status = psa_driver_wrapper_mac_compute( - &slot->attr, - slot->key.data, slot->key.bytes, - alg, - input, input_length, - mac, operation_mac_size, mac_length); - -exit: - /* In case of success, set the potential excess room in the output buffer - * to an invalid value, to avoid potentially leaking a longer MAC. - * In case of error, set the output length and content to a safe default, - * such that in case the caller misses an error check, the output would be - * an unachievable MAC. - */ - if (status != PSA_SUCCESS) { - *mac_length = mac_size; - operation_mac_size = 0; - } - - psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length); - - unlock_status = psa_unregister_read_under_mutex(slot); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - uint8_t *mac_external, - size_t mac_size, - size_t *mac_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_OUTPUT_DECLARE(mac_external, mac); - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); - status = psa_mac_compute_internal(key, alg, - input, input_length, - mac, mac_size, mac_length, 1); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(input_external, input); - LOCAL_OUTPUT_FREE(mac_external, mac); - - return status; -} - -psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - const uint8_t *mac_external, - size_t mac_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t actual_mac[PSA_MAC_MAX_SIZE]; - size_t actual_mac_length; - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_INPUT_DECLARE(mac_external, mac); - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - status = psa_mac_compute_internal(key, alg, - input, input_length, - actual_mac, sizeof(actual_mac), - &actual_mac_length, 0); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (mac_length != actual_mac_length) { - status = PSA_ERROR_INVALID_SIGNATURE; - goto exit; - } - - LOCAL_INPUT_ALLOC(mac_external, mac_length, mac); - if (mbedtls_ct_memcmp(mac, actual_mac, actual_mac_length) != 0) { - status = PSA_ERROR_INVALID_SIGNATURE; - goto exit; - } - -exit: - mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac)); - LOCAL_INPUT_FREE(input_external, input); - LOCAL_INPUT_FREE(mac_external, mac); - - return status; -} - -/****************************************************************/ -/* Asymmetric cryptography */ -/****************************************************************/ - -static psa_status_t psa_sign_verify_check_alg(int input_is_message, - psa_algorithm_t alg) -{ - if (input_is_message) { - if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - psa_algorithm_t hash_alg = 0; - if (PSA_ALG_IS_SIGN_HASH(alg)) { - hash_alg = PSA_ALG_SIGN_GET_HASH(alg); - } - - /* Now hash_alg==0 if alg by itself doesn't need a hash. - * This is good enough for sign-hash, but a guaranteed failure for - * sign-message which needs to hash first for all algorithms - * supported at the moment. */ - - if (hash_alg == 0 && input_is_message) { - return PSA_ERROR_INVALID_ARGUMENT; - } - if (hash_alg == PSA_ALG_ANY_HASH) { - return PSA_ERROR_INVALID_ARGUMENT; - } - /* Give up immediately if the hash is not supported. This has - * several advantages: - * - For mechanisms that don't use the hash at all (e.g. - * ECDSA verification, randomized ECDSA signature), without - * this check, the operation would succeed even though it has - * been given an invalid argument. This would not be insecure - * since the hash was not necessary, but it would be weird. - * - For mechanisms that do use the hash, we avoid an error - * deep inside the execution. In principle this doesn't matter, - * but there is a little more risk of a bug in error handling - * deep inside than in this preliminary check. - * - When calling a driver, the driver might be capable of using - * a hash that the core doesn't support. This could potentially - * result in a buffer overflow if the hash is larger than the - * maximum hash size assumed by the core. - * - Returning a consistent error makes it possible to test - * not-supported hashes in a consistent way. - */ - if (hash_alg != 0 && !is_hash_supported(hash_alg)) { - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_SUCCESS; -} - -static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key, - int input_is_message, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - *signature_length = 0; - - status = psa_sign_verify_check_alg(input_is_message, alg); - if (status != PSA_SUCCESS) { - return status; - } - - /* Immediately reject a zero-length signature buffer. This guarantees - * that signature must be a valid pointer. (On the other hand, the input - * buffer can in principle be empty since it doesn't actually have - * to be a hash.) */ - if (signature_size == 0) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - status = psa_get_and_lock_key_slot_with_policy( - key, &slot, - input_is_message ? PSA_KEY_USAGE_SIGN_MESSAGE : - PSA_KEY_USAGE_SIGN_HASH, - alg); - - if (status != PSA_SUCCESS) { - goto exit; - } - - if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - if (input_is_message) { - status = psa_driver_wrapper_sign_message( - &slot->attr, slot->key.data, slot->key.bytes, - alg, input, input_length, - signature, signature_size, signature_length); - } else { - - status = psa_driver_wrapper_sign_hash( - &slot->attr, slot->key.data, slot->key.bytes, - alg, input, input_length, - signature, signature_size, signature_length); - } - - -exit: - psa_wipe_tag_output_buffer(signature, status, signature_size, - *signature_length); - - unlock_status = psa_unregister_read_under_mutex(slot); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key, - int input_is_message, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *signature, - size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - status = psa_sign_verify_check_alg(input_is_message, alg); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_get_and_lock_key_slot_with_policy( - key, &slot, - input_is_message ? PSA_KEY_USAGE_VERIFY_MESSAGE : - PSA_KEY_USAGE_VERIFY_HASH, - alg); - - if (status != PSA_SUCCESS) { - return status; - } - - if (input_is_message) { - status = psa_driver_wrapper_verify_message( - &slot->attr, slot->key.data, slot->key.bytes, - alg, input, input_length, - signature, signature_length); - } else { - status = psa_driver_wrapper_verify_hash( - &slot->attr, slot->key.data, slot->key.bytes, - alg, input, input_length, - signature, signature_length); - } - - unlock_status = psa_unregister_read_under_mutex(slot); - - return (status == PSA_SUCCESS) ? unlock_status : status; - -} - -psa_status_t psa_sign_message_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (PSA_ALG_IS_SIGN_HASH(alg)) { - size_t hash_length; - uint8_t hash[PSA_HASH_MAX_SIZE]; - - status = psa_driver_wrapper_hash_compute( - PSA_ALG_SIGN_GET_HASH(alg), - input, input_length, - hash, sizeof(hash), &hash_length); - - if (status != PSA_SUCCESS) { - return status; - } - - return psa_driver_wrapper_sign_hash( - attributes, key_buffer, key_buffer_size, - alg, hash, hash_length, - signature, signature_size, signature_length); - } - - return PSA_ERROR_NOT_SUPPORTED; -} - -psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - uint8_t *signature_external, - size_t signature_size, - size_t *signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_OUTPUT_DECLARE(signature_external, signature); - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); - status = psa_sign_internal(key, 1, alg, input, input_length, signature, - signature_size, signature_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(input_external, input); - LOCAL_OUTPUT_FREE(signature_external, signature); - return status; -} - -psa_status_t psa_verify_message_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *signature, - size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (PSA_ALG_IS_SIGN_HASH(alg)) { - size_t hash_length; - uint8_t hash[PSA_HASH_MAX_SIZE]; - - status = psa_driver_wrapper_hash_compute( - PSA_ALG_SIGN_GET_HASH(alg), - input, input_length, - hash, sizeof(hash), &hash_length); - - if (status != PSA_SUCCESS) { - return status; - } - - return psa_driver_wrapper_verify_hash( - attributes, key_buffer, key_buffer_size, - alg, hash, hash_length, - signature, signature_length); - } - - return PSA_ERROR_NOT_SUPPORTED; -} - -psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - const uint8_t *signature_external, - size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_INPUT_DECLARE(signature_external, signature); - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); - status = psa_verify_internal(key, 1, alg, input, input_length, signature, - signature_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(input_external, input); - LOCAL_INPUT_FREE(signature_external, signature); - - return status; -} - -psa_status_t psa_sign_hash_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - uint8_t *signature, size_t signature_size, size_t *signature_length) -{ - if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || - PSA_ALG_IS_RSA_PSS(alg)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) - return mbedtls_psa_rsa_sign_hash( - attributes, - key_buffer, key_buffer_size, - alg, hash, hash_length, - signature, signature_size, signature_length); -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ - } else { - return PSA_ERROR_INVALID_ARGUMENT; - } - } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { - if (PSA_ALG_IS_ECDSA(alg)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) - return mbedtls_psa_ecdsa_sign_hash( - attributes, - key_buffer, key_buffer_size, - alg, hash, hash_length, - signature, signature_size, signature_length); -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ - } else { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - (void) key_buffer; - (void) key_buffer_size; - (void) hash; - (void) hash_length; - (void) signature; - (void) signature_size; - (void) signature_length; - - return PSA_ERROR_NOT_SUPPORTED; -} - -psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash_external, - size_t hash_length, - uint8_t *signature_external, - size_t signature_size, - size_t *signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(hash_external, hash); - LOCAL_OUTPUT_DECLARE(signature_external, signature); - - LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); - LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); - status = psa_sign_internal(key, 0, alg, hash, hash_length, signature, - signature_size, signature_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(hash_external, hash); - LOCAL_OUTPUT_FREE(signature_external, signature); - - return status; -} - -psa_status_t psa_verify_hash_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length) -{ - if (PSA_KEY_TYPE_IS_RSA(attributes->type)) { - if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || - PSA_ALG_IS_RSA_PSS(alg)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) - return mbedtls_psa_rsa_verify_hash( - attributes, - key_buffer, key_buffer_size, - alg, hash, hash_length, - signature, signature_length); -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ - } else { - return PSA_ERROR_INVALID_ARGUMENT; - } - } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { - if (PSA_ALG_IS_ECDSA(alg)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) - return mbedtls_psa_ecdsa_verify_hash( - attributes, - key_buffer, key_buffer_size, - alg, hash, hash_length, - signature, signature_length); -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ - } else { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - (void) key_buffer; - (void) key_buffer_size; - (void) hash; - (void) hash_length; - (void) signature; - (void) signature_length; - - return PSA_ERROR_NOT_SUPPORTED; -} - -psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash_external, - size_t hash_length, - const uint8_t *signature_external, - size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(hash_external, hash); - LOCAL_INPUT_DECLARE(signature_external, signature); - - LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); - LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); - status = psa_verify_internal(key, 0, alg, hash, hash_length, signature, - signature_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(hash_external, hash); - LOCAL_INPUT_FREE(signature_external, signature); - - return status; -} - -psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - const uint8_t *salt_external, - size_t salt_length, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_INPUT_DECLARE(salt_external, salt); - LOCAL_OUTPUT_DECLARE(output_external, output); - - (void) input; - (void) input_length; - (void) salt; - (void) output; - (void) output_size; - - *output_length = 0; - - if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - status = psa_get_and_lock_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_ENCRYPT, alg); - if (status != PSA_SUCCESS) { - return status; - } - if (!(PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type) || - PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type))) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_INPUT_ALLOC(salt_external, salt_length, salt); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_driver_wrapper_asymmetric_encrypt( - &slot->attr, slot->key.data, slot->key.bytes, - alg, input, input_length, salt, salt_length, - output, output_size, output_length); -exit: - unlock_status = psa_unregister_read_under_mutex(slot); - - LOCAL_INPUT_FREE(input_external, input); - LOCAL_INPUT_FREE(salt_external, salt); - LOCAL_OUTPUT_FREE(output_external, output); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - const uint8_t *salt_external, - size_t salt_length, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_INPUT_DECLARE(salt_external, salt); - LOCAL_OUTPUT_DECLARE(output_external, output); - - (void) input; - (void) input_length; - (void) salt; - (void) output; - (void) output_size; - - *output_length = 0; - - if (!PSA_ALG_IS_RSA_OAEP(alg) && salt_length != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - status = psa_get_and_lock_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_DECRYPT, alg); - if (status != PSA_SUCCESS) { - return status; - } - if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_INPUT_ALLOC(salt_external, salt_length, salt); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_driver_wrapper_asymmetric_decrypt( - &slot->attr, slot->key.data, slot->key.bytes, - alg, input, input_length, salt, salt_length, - output, output_size, output_length); - -exit: - unlock_status = psa_unregister_read_under_mutex(slot); - - LOCAL_INPUT_FREE(input_external, input); - LOCAL_INPUT_FREE(salt_external, salt); - LOCAL_OUTPUT_FREE(output_external, output); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -/****************************************************************/ -/* Asymmetric interruptible cryptography */ -/****************************************************************/ - -static uint32_t psa_interruptible_max_ops = PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED; - -void psa_interruptible_set_max_ops(uint32_t max_ops) -{ - psa_interruptible_max_ops = max_ops; -} - -uint32_t psa_interruptible_get_max_ops(void) -{ - return psa_interruptible_max_ops; -} - -uint32_t psa_sign_hash_get_num_ops( - const psa_sign_hash_interruptible_operation_t *operation) -{ - return operation->num_ops; -} - -uint32_t psa_verify_hash_get_num_ops( - const psa_verify_hash_interruptible_operation_t *operation) -{ - return operation->num_ops; -} - -static psa_status_t psa_sign_hash_abort_internal( - psa_sign_hash_interruptible_operation_t *operation) -{ - if (operation->id == 0) { - /* The object has (apparently) been initialized but it is not (yet) - * in use. It's ok to call abort on such an object, and there's - * nothing to do. */ - return PSA_SUCCESS; - } - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_driver_wrapper_sign_hash_abort(operation); - - operation->id = 0; - - /* Do not clear either the error_occurred or num_ops elements here as they - * only want to be cleared by the application calling abort, not by abort - * being called at completion of an operation. */ - - return status; -} - -psa_status_t psa_sign_hash_start( - psa_sign_hash_interruptible_operation_t *operation, - mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash_external, size_t hash_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - LOCAL_INPUT_DECLARE(hash_external, hash); - - /* Check that start has not been previously called, or operation has not - * previously errored. */ - if (operation->id != 0 || operation->error_occurred) { - return PSA_ERROR_BAD_STATE; - } - - /* Make sure the driver-dependent part of the operation is zeroed. - * This is a guarantee we make to drivers. Initializing the operation - * does not necessarily take care of it, since the context is a - * union and initializing a union does not necessarily initialize - * all of its members. */ - memset(&operation->ctx, 0, sizeof(operation->ctx)); - - status = psa_sign_verify_check_alg(0, alg); - if (status != PSA_SUCCESS) { - operation->error_occurred = 1; - return status; - } - - status = psa_get_and_lock_key_slot_with_policy(key, &slot, - PSA_KEY_USAGE_SIGN_HASH, - alg); - - if (status != PSA_SUCCESS) { - goto exit; - } - - if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); - - /* Ensure ops count gets reset, in case of operation re-use. */ - operation->num_ops = 0; - - status = psa_driver_wrapper_sign_hash_start(operation, &slot->attr, - slot->key.data, - slot->key.bytes, alg, - hash, hash_length); -exit: - - if (status != PSA_SUCCESS) { - operation->error_occurred = 1; - psa_sign_hash_abort_internal(operation); - } - - unlock_status = psa_unregister_read_under_mutex(slot); - - if (unlock_status != PSA_SUCCESS) { - operation->error_occurred = 1; - } - - LOCAL_INPUT_FREE(hash_external, hash); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - - -psa_status_t psa_sign_hash_complete( - psa_sign_hash_interruptible_operation_t *operation, - uint8_t *signature_external, size_t signature_size, - size_t *signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - LOCAL_OUTPUT_DECLARE(signature_external, signature); - - *signature_length = 0; - - /* Check that start has been called first, and that operation has not - * previously errored. */ - if (operation->id == 0 || operation->error_occurred) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - /* Immediately reject a zero-length signature buffer. This guarantees that - * signature must be a valid pointer. */ - if (signature_size == 0) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); - - status = psa_driver_wrapper_sign_hash_complete(operation, signature, - signature_size, - signature_length); - - /* Update ops count with work done. */ - operation->num_ops = psa_driver_wrapper_sign_hash_get_num_ops(operation); - -exit: - - if (signature != NULL) { - psa_wipe_tag_output_buffer(signature, status, signature_size, - *signature_length); - } - - if (status != PSA_OPERATION_INCOMPLETE) { - if (status != PSA_SUCCESS) { - operation->error_occurred = 1; - } - - psa_sign_hash_abort_internal(operation); - } - - LOCAL_OUTPUT_FREE(signature_external, signature); - - return status; -} - -psa_status_t psa_sign_hash_abort( - psa_sign_hash_interruptible_operation_t *operation) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_sign_hash_abort_internal(operation); - - /* We clear the number of ops done here, so that it is not cleared when - * the operation fails or succeeds, only on manual abort. */ - operation->num_ops = 0; - - /* Likewise, failure state. */ - operation->error_occurred = 0; - - return status; -} - -static psa_status_t psa_verify_hash_abort_internal( - psa_verify_hash_interruptible_operation_t *operation) -{ - if (operation->id == 0) { - /* The object has (apparently) been initialized but it is not (yet) - * in use. It's ok to call abort on such an object, and there's - * nothing to do. */ - return PSA_SUCCESS; - } - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_driver_wrapper_verify_hash_abort(operation); - - operation->id = 0; - - /* Do not clear either the error_occurred or num_ops elements here as they - * only want to be cleared by the application calling abort, not by abort - * being called at completion of an operation. */ - - return status; -} - -psa_status_t psa_verify_hash_start( - psa_verify_hash_interruptible_operation_t *operation, - mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash_external, size_t hash_length, - const uint8_t *signature_external, size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - LOCAL_INPUT_DECLARE(hash_external, hash); - LOCAL_INPUT_DECLARE(signature_external, signature); - - /* Check that start has not been previously called, or operation has not - * previously errored. */ - if (operation->id != 0 || operation->error_occurred) { - return PSA_ERROR_BAD_STATE; - } - - /* Make sure the driver-dependent part of the operation is zeroed. - * This is a guarantee we make to drivers. Initializing the operation - * does not necessarily take care of it, since the context is a - * union and initializing a union does not necessarily initialize - * all of its members. */ - memset(&operation->ctx, 0, sizeof(operation->ctx)); - - status = psa_sign_verify_check_alg(0, alg); - if (status != PSA_SUCCESS) { - operation->error_occurred = 1; - return status; - } - - status = psa_get_and_lock_key_slot_with_policy(key, &slot, - PSA_KEY_USAGE_VERIFY_HASH, - alg); - - if (status != PSA_SUCCESS) { - operation->error_occurred = 1; - return status; - } - - LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); - LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); - - /* Ensure ops count gets reset, in case of operation re-use. */ - operation->num_ops = 0; - - status = psa_driver_wrapper_verify_hash_start(operation, &slot->attr, - slot->key.data, - slot->key.bytes, - alg, hash, hash_length, - signature, signature_length); -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - - if (status != PSA_SUCCESS) { - operation->error_occurred = 1; - psa_verify_hash_abort_internal(operation); - } - - unlock_status = psa_unregister_read_under_mutex(slot); - - if (unlock_status != PSA_SUCCESS) { - operation->error_occurred = 1; - } - - LOCAL_INPUT_FREE(hash_external, hash); - LOCAL_INPUT_FREE(signature_external, signature); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_verify_hash_complete( - psa_verify_hash_interruptible_operation_t *operation) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - /* Check that start has been called first, and that operation has not - * previously errored. */ - if (operation->id == 0 || operation->error_occurred) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - status = psa_driver_wrapper_verify_hash_complete(operation); - - /* Update ops count with work done. */ - operation->num_ops = psa_driver_wrapper_verify_hash_get_num_ops( - operation); - -exit: - - if (status != PSA_OPERATION_INCOMPLETE) { - if (status != PSA_SUCCESS) { - operation->error_occurred = 1; - } - - psa_verify_hash_abort_internal(operation); - } - - return status; -} - -psa_status_t psa_verify_hash_abort( - psa_verify_hash_interruptible_operation_t *operation) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_verify_hash_abort_internal(operation); - - /* We clear the number of ops done here, so that it is not cleared when - * the operation fails or succeeds, only on manual abort. */ - operation->num_ops = 0; - - /* Likewise, failure state. */ - operation->error_occurred = 0; - - return status; -} - -/****************************************************************/ -/* Asymmetric interruptible cryptography internal */ -/* implementations */ -/****************************************************************/ - -void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops) -{ - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - /* Internal implementation uses zero to indicate infinite number max ops, - * therefore avoid this value, and set to minimum possible. */ - if (max_ops == 0) { - max_ops = 1; - } - - mbedtls_ecp_set_max_ops(max_ops); -#else - (void) max_ops; -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -uint32_t mbedtls_psa_sign_hash_get_num_ops( - const mbedtls_psa_sign_hash_interruptible_operation_t *operation) -{ -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - return operation->num_ops; -#else - (void) operation; - return 0; -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -uint32_t mbedtls_psa_verify_hash_get_num_ops( - const mbedtls_psa_verify_hash_interruptible_operation_t *operation) -{ - #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - return operation->num_ops; -#else - (void) operation; - return 0; -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -/* Detect supported interruptible sign/verify mechanisms precisely. - * This is not strictly needed: we could accept everything, and let the - * code fail later during complete() if the mechanism is unsupported - * (e.g. attempting deterministic ECDSA when only the randomized variant - * is available). But it's easier for applications and especially for our - * test code to detect all not-supported errors during start(). - * - * Note that this function ignores the hash component. The core code - * is supposed to check the hash part by calling is_hash_supported(). - */ -static inline int can_do_interruptible_sign_verify(psa_algorithm_t alg) -{ -#if defined(MBEDTLS_ECP_RESTARTABLE) -#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) - if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) - if (PSA_ALG_IS_RANDOMIZED_ECDSA(alg)) { - return 1; - } -#endif -#endif /* defined(MBEDTLS_ECP_RESTARTABLE) */ - (void) alg; - return 0; -} - -psa_status_t mbedtls_psa_sign_hash_start( - mbedtls_psa_sign_hash_interruptible_operation_t *operation, - const psa_key_attributes_t *attributes, const uint8_t *key_buffer, - size_t key_buffer_size, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t required_hash_length; - - if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) { - return PSA_ERROR_NOT_SUPPORTED; - } - psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type); - if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(curve)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (!can_do_interruptible_sign_verify(alg)) { - return PSA_ERROR_NOT_SUPPORTED; - } - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - mbedtls_ecdsa_restart_init(&operation->restart_ctx); - - /* Ensure num_ops is zero'ed in case of context re-use. */ - operation->num_ops = 0; - - status = mbedtls_psa_ecp_load_representation(attributes->type, - attributes->bits, - key_buffer, - key_buffer_size, - &operation->ctx); - - if (status != PSA_SUCCESS) { - return status; - } - - operation->coordinate_bytes = PSA_BITS_TO_BYTES( - operation->ctx->grp.nbits); - - psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); - operation->md_alg = mbedtls_md_type_from_psa_alg(hash_alg); - operation->alg = alg; - - /* We only need to store the same length of hash as the private key size - * here, it would be truncated by the internal implementation anyway. */ - required_hash_length = (hash_length < operation->coordinate_bytes ? - hash_length : operation->coordinate_bytes); - - if (required_hash_length > sizeof(operation->hash)) { - /* Shouldn't happen, but better safe than sorry. */ - return PSA_ERROR_CORRUPTION_DETECTED; - } - - memcpy(operation->hash, hash, required_hash_length); - operation->hash_length = required_hash_length; - - return PSA_SUCCESS; - -#else - (void) operation; - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - (void) hash; - (void) hash_length; - (void) status; - (void) required_hash_length; - - return PSA_ERROR_NOT_SUPPORTED; -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -psa_status_t mbedtls_psa_sign_hash_complete( - mbedtls_psa_sign_hash_interruptible_operation_t *operation, - uint8_t *signature, size_t signature_size, - size_t *signature_length) -{ -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi r; - mbedtls_mpi s; - - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - - /* Ensure max_ops is set to the current value (or default). */ - mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops()); - - if (signature_size < 2 * operation->coordinate_bytes) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - if (PSA_ALG_ECDSA_IS_DETERMINISTIC(operation->alg)) { - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) - status = mbedtls_to_psa_error( - mbedtls_ecdsa_sign_det_restartable(&operation->ctx->grp, - &r, - &s, - &operation->ctx->d, - operation->hash, - operation->hash_length, - operation->md_alg, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - &operation->restart_ctx)); -#else /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ - } else { - status = mbedtls_to_psa_error( - mbedtls_ecdsa_sign_restartable(&operation->ctx->grp, - &r, - &s, - &operation->ctx->d, - operation->hash, - operation->hash_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - &operation->restart_ctx)); - } - - /* Hide the fact that the restart context only holds a delta of number of - * ops done during the last operation, not an absolute value. */ - operation->num_ops += operation->restart_ctx.ecp.ops_done; - - if (status == PSA_SUCCESS) { - status = mbedtls_to_psa_error( - mbedtls_mpi_write_binary(&r, - signature, - operation->coordinate_bytes) - ); - - if (status != PSA_SUCCESS) { - goto exit; - } - - status = mbedtls_to_psa_error( - mbedtls_mpi_write_binary(&s, - signature + - operation->coordinate_bytes, - operation->coordinate_bytes) - ); - - if (status != PSA_SUCCESS) { - goto exit; - } - - *signature_length = operation->coordinate_bytes * 2; - - status = PSA_SUCCESS; - } - -exit: - - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - return status; - - #else - - (void) operation; - (void) signature; - (void) signature_size; - (void) signature_length; - - return PSA_ERROR_NOT_SUPPORTED; - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -psa_status_t mbedtls_psa_sign_hash_abort( - mbedtls_psa_sign_hash_interruptible_operation_t *operation) -{ - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - if (operation->ctx) { - mbedtls_ecdsa_free(operation->ctx); - mbedtls_free(operation->ctx); - operation->ctx = NULL; - } - - mbedtls_ecdsa_restart_free(&operation->restart_ctx); - - operation->num_ops = 0; - - return PSA_SUCCESS; - -#else - - (void) operation; - - return PSA_ERROR_NOT_SUPPORTED; - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -psa_status_t mbedtls_psa_verify_hash_start( - mbedtls_psa_verify_hash_interruptible_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t coordinate_bytes = 0; - size_t required_hash_length = 0; - - if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) { - return PSA_ERROR_NOT_SUPPORTED; - } - psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type); - if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(curve)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (!can_do_interruptible_sign_verify(alg)) { - return PSA_ERROR_NOT_SUPPORTED; - } - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - mbedtls_ecdsa_restart_init(&operation->restart_ctx); - mbedtls_mpi_init(&operation->r); - mbedtls_mpi_init(&operation->s); - - /* Ensure num_ops is zero'ed in case of context re-use. */ - operation->num_ops = 0; - - status = mbedtls_psa_ecp_load_representation(attributes->type, - attributes->bits, - key_buffer, - key_buffer_size, - &operation->ctx); - - if (status != PSA_SUCCESS) { - return status; - } - - coordinate_bytes = PSA_BITS_TO_BYTES(operation->ctx->grp.nbits); - - if (signature_length != 2 * coordinate_bytes) { - return PSA_ERROR_INVALID_SIGNATURE; - } - - status = mbedtls_to_psa_error( - mbedtls_mpi_read_binary(&operation->r, - signature, - coordinate_bytes)); - - if (status != PSA_SUCCESS) { - return status; - } - - status = mbedtls_to_psa_error( - mbedtls_mpi_read_binary(&operation->s, - signature + - coordinate_bytes, - coordinate_bytes)); - - if (status != PSA_SUCCESS) { - return status; - } - - status = mbedtls_psa_ecp_load_public_part(operation->ctx); - - if (status != PSA_SUCCESS) { - return status; - } - - /* We only need to store the same length of hash as the private key size - * here, it would be truncated by the internal implementation anyway. */ - required_hash_length = (hash_length < coordinate_bytes ? hash_length : - coordinate_bytes); - - if (required_hash_length > sizeof(operation->hash)) { - /* Shouldn't happen, but better safe than sorry. */ - return PSA_ERROR_CORRUPTION_DETECTED; - } - - memcpy(operation->hash, hash, required_hash_length); - operation->hash_length = required_hash_length; - - return PSA_SUCCESS; -#else - (void) operation; - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - (void) hash; - (void) hash_length; - (void) signature; - (void) signature_length; - (void) status; - (void) coordinate_bytes; - (void) required_hash_length; - - return PSA_ERROR_NOT_SUPPORTED; -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -psa_status_t mbedtls_psa_verify_hash_complete( - mbedtls_psa_verify_hash_interruptible_operation_t *operation) -{ - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - /* Ensure max_ops is set to the current value (or default). */ - mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops()); - - status = mbedtls_to_psa_error( - mbedtls_ecdsa_verify_restartable(&operation->ctx->grp, - operation->hash, - operation->hash_length, - &operation->ctx->Q, - &operation->r, - &operation->s, - &operation->restart_ctx)); - - /* Hide the fact that the restart context only holds a delta of number of - * ops done during the last operation, not an absolute value. */ - operation->num_ops += operation->restart_ctx.ecp.ops_done; - - return status; -#else - (void) operation; - - return PSA_ERROR_NOT_SUPPORTED; - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -psa_status_t mbedtls_psa_verify_hash_abort( - mbedtls_psa_verify_hash_interruptible_operation_t *operation) -{ - -#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ - defined(MBEDTLS_ECP_RESTARTABLE) - - if (operation->ctx) { - mbedtls_ecdsa_free(operation->ctx); - mbedtls_free(operation->ctx); - operation->ctx = NULL; - } - - mbedtls_ecdsa_restart_free(&operation->restart_ctx); - - operation->num_ops = 0; - - mbedtls_mpi_free(&operation->r); - mbedtls_mpi_free(&operation->s); - - return PSA_SUCCESS; - -#else - (void) operation; - - return PSA_ERROR_NOT_SUPPORTED; - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && - * defined( MBEDTLS_ECP_RESTARTABLE ) */ -} - -static psa_status_t psa_generate_random_internal(uint8_t *output, - size_t output_size) -{ - GUARD_MODULE_INITIALIZED; - -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - - psa_status_t status; - size_t output_length = 0; - status = mbedtls_psa_external_get_random(&global_data.rng, - output, output_size, - &output_length); - if (status != PSA_SUCCESS) { - return status; - } - /* Breaking up a request into smaller chunks is currently not supported - * for the external RNG interface. */ - if (output_length != output_size) { - return PSA_ERROR_INSUFFICIENT_ENTROPY; - } - return PSA_SUCCESS; - -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - return psa_random_internal_generate(&global_data.rng, - output, output_size); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -} - - -/****************************************************************/ -/* Symmetric cryptography */ -/****************************************************************/ - -static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - mbedtls_operation_t cipher_operation) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - psa_key_usage_t usage = (cipher_operation == MBEDTLS_ENCRYPT ? - PSA_KEY_USAGE_ENCRYPT : - PSA_KEY_USAGE_DECRYPT); - - /* A context must be freshly initialized before it can be set up. */ - if (operation->id != 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (!PSA_ALG_IS_CIPHER(alg)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - status = psa_get_and_lock_key_slot_with_policy(key, &slot, usage, alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* Initialize the operation struct members, except for id. The id member - * is used to indicate to psa_cipher_abort that there are resources to free, - * so we only set it (in the driver wrapper) after resources have been - * allocated/initialized. */ - operation->iv_set = 0; - if (alg == PSA_ALG_ECB_NO_PADDING) { - operation->iv_required = 0; - } else { - operation->iv_required = 1; - } - operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); - - - /* Make sure the driver-dependent part of the operation is zeroed. - * This is a guarantee we make to drivers. Initializing the operation - * does not necessarily take care of it, since the context is a - * union and initializing a union does not necessarily initialize - * all of its members. */ - memset(&operation->ctx, 0, sizeof(operation->ctx)); - - /* Try doing the operation through a driver before using software fallback. */ - if (cipher_operation == MBEDTLS_ENCRYPT) { - status = psa_driver_wrapper_cipher_encrypt_setup(operation, - &slot->attr, - slot->key.data, - slot->key.bytes, - alg); - } else { - status = psa_driver_wrapper_cipher_decrypt_setup(operation, - &slot->attr, - slot->key.data, - slot->key.bytes, - alg); - } - -exit: - if (status != PSA_SUCCESS) { - psa_cipher_abort(operation); - } - - unlock_status = psa_unregister_read_under_mutex(slot); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg) -{ - return psa_cipher_setup(operation, key, alg, MBEDTLS_ENCRYPT); -} - -psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg) -{ - return psa_cipher_setup(operation, key, alg, MBEDTLS_DECRYPT); -} - -psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, - uint8_t *iv_external, - size_t iv_size, - size_t *iv_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t default_iv_length = 0; - - LOCAL_OUTPUT_DECLARE(iv_external, iv); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->iv_set || !operation->iv_required) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - default_iv_length = operation->default_iv_length; - if (iv_size < default_iv_length) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) { - status = PSA_ERROR_GENERIC_ERROR; - goto exit; - } - - LOCAL_OUTPUT_ALLOC(iv_external, default_iv_length, iv); - - status = psa_generate_random_internal(iv, default_iv_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_driver_wrapper_cipher_set_iv(operation, - iv, default_iv_length); - -exit: - if (status == PSA_SUCCESS) { - *iv_length = default_iv_length; - operation->iv_set = 1; - } else { - *iv_length = 0; - psa_cipher_abort(operation); - if (iv != NULL) { - mbedtls_platform_zeroize(iv, default_iv_length); - } - } - - LOCAL_OUTPUT_FREE(iv_external, iv); - return status; -} - -psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, - const uint8_t *iv_external, - size_t iv_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - LOCAL_INPUT_DECLARE(iv_external, iv); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->iv_set || !operation->iv_required) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (iv_length > PSA_CIPHER_IV_MAX_SIZE) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - LOCAL_INPUT_ALLOC(iv_external, iv_length, iv); - - status = psa_driver_wrapper_cipher_set_iv(operation, - iv, - iv_length); - -exit: - if (status == PSA_SUCCESS) { - operation->iv_set = 1; - } else { - psa_cipher_abort(operation); - } - - LOCAL_INPUT_FREE(iv_external, iv); - - return status; -} - -psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, - const uint8_t *input_external, - size_t input_length, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_OUTPUT_DECLARE(output_external, output); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->iv_required && !operation->iv_set) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_driver_wrapper_cipher_update(operation, - input, - input_length, - output, - output_size, - output_length); - -exit: - if (status != PSA_SUCCESS) { - psa_cipher_abort(operation); - } - - LOCAL_INPUT_FREE(input_external, input); - LOCAL_OUTPUT_FREE(output_external, output); - - return status; -} - -psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; - - LOCAL_OUTPUT_DECLARE(output_external, output); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->iv_required && !operation->iv_set) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_driver_wrapper_cipher_finish(operation, - output, - output_size, - output_length); - -exit: - /* C99 doesn't allow a declaration to follow a label */; - psa_status_t abort_status = psa_cipher_abort(operation); - /* Normally abort shouldn't fail unless the operation is in a bad - * state, in which case we'd expect finish to fail with the same error. - * So it doesn't matter much which call's error code we pick when both - * fail. However, in unauthenticated decryption specifically, the - * distinction between PSA_SUCCESS and PSA_ERROR_INVALID_PADDING is - * security-sensitive (risk of a padding oracle attack), so here we - * must not have a code path that depends on the value of status. */ - if (abort_status != PSA_SUCCESS) { - status = abort_status; - } - - /* Set *output_length to 0 if status != PSA_SUCCESS, without - * leaking the value of status through a timing side channel - * (status == PSA_ERROR_INVALID_PADDING is sensitive when doing - * unpadded decryption, due to the risk of padding oracle attack). */ - mbedtls_ct_condition_t success = - mbedtls_ct_bool_not(mbedtls_ct_bool(status)); - *output_length = mbedtls_ct_size_if_else_0(success, *output_length); - - LOCAL_OUTPUT_FREE(output_external, output); - - return status; -} - -psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation) -{ - if (operation->id == 0) { - /* The object has (apparently) been initialized but it is not (yet) - * in use. It's ok to call abort on such an object, and there's - * nothing to do. */ - return PSA_SUCCESS; - } - - psa_driver_wrapper_cipher_abort(operation); - - operation->id = 0; - operation->iv_set = 0; - operation->iv_required = 0; - - return PSA_SUCCESS; -} - -psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; - size_t default_iv_length = 0; - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_OUTPUT_DECLARE(output_external, output); - - if (!PSA_ALG_IS_CIPHER(alg)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - status = psa_get_and_lock_key_slot_with_policy(key, &slot, - PSA_KEY_USAGE_ENCRYPT, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); - if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) { - status = PSA_ERROR_GENERIC_ERROR; - goto exit; - } - - if (default_iv_length > 0) { - if (output_size < default_iv_length) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - status = psa_generate_random_internal(local_iv, default_iv_length); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_driver_wrapper_cipher_encrypt( - &slot->attr, slot->key.data, slot->key.bytes, - alg, local_iv, default_iv_length, input, input_length, - psa_crypto_buffer_offset(output, default_iv_length), - output_size - default_iv_length, output_length); - -exit: - unlock_status = psa_unregister_read_under_mutex(slot); - if (status == PSA_SUCCESS) { - status = unlock_status; - } - - if (status == PSA_SUCCESS) { - if (default_iv_length > 0) { - memcpy(output, local_iv, default_iv_length); - } - *output_length += default_iv_length; - } else { - *output_length = 0; - } - - LOCAL_INPUT_FREE(input_external, input); - LOCAL_OUTPUT_FREE(output_external, output); - - return status; -} - -psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input_external, - size_t input_length, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_OUTPUT_DECLARE(output_external, output); - - if (!PSA_ALG_IS_CIPHER(alg)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - status = psa_get_and_lock_key_slot_with_policy(key, &slot, - PSA_KEY_USAGE_DECRYPT, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (input_length < PSA_CIPHER_IV_LENGTH(slot->attr.type, alg)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_driver_wrapper_cipher_decrypt( - &slot->attr, slot->key.data, slot->key.bytes, - alg, input, input_length, - output, output_size, output_length); - -exit: - unlock_status = psa_unregister_read_under_mutex(slot); - if (unlock_status != PSA_SUCCESS) { - status = unlock_status; - } - - /* Set *output_length to 0 if status != PSA_SUCCESS, without - * leaking the value of status through a timing side channel - * (status == PSA_ERROR_INVALID_PADDING is sensitive when doing - * unpadded decryption, due to the risk of padding oracle attack). */ - mbedtls_ct_condition_t success = - mbedtls_ct_bool_not(mbedtls_ct_bool(status)); - *output_length = mbedtls_ct_size_if_else_0(success, *output_length); - - LOCAL_INPUT_FREE(input_external, input); - LOCAL_OUTPUT_FREE(output_external, output); - - return status; -} - - -/****************************************************************/ -/* AEAD */ -/****************************************************************/ - -/* Helper function to get the base algorithm from its variants. */ -static psa_algorithm_t psa_aead_get_base_algorithm(psa_algorithm_t alg) -{ - return PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg); -} - -/* Helper function to perform common nonce length checks. */ -static psa_status_t psa_aead_check_nonce_length(psa_algorithm_t alg, - size_t nonce_length) -{ - psa_algorithm_t base_alg = psa_aead_get_base_algorithm(alg); - - switch (base_alg) { -#if defined(PSA_WANT_ALG_GCM) - case PSA_ALG_GCM: - /* Not checking max nonce size here as GCM spec allows almost - * arbitrarily large nonces. Please note that we do not generally - * recommend the usage of nonces of greater length than - * PSA_AEAD_NONCE_MAX_SIZE, as large nonces are hashed to a shorter - * size, which can then lead to collisions if you encrypt a very - * large number of messages.*/ - if (nonce_length != 0) { - return PSA_SUCCESS; - } - break; -#endif /* PSA_WANT_ALG_GCM */ -#if defined(PSA_WANT_ALG_CCM) - case PSA_ALG_CCM: - if (nonce_length >= 7 && nonce_length <= 13) { - return PSA_SUCCESS; - } - break; -#endif /* PSA_WANT_ALG_CCM */ -#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) - case PSA_ALG_CHACHA20_POLY1305: - if (nonce_length == 12) { - return PSA_SUCCESS; - } else if (nonce_length == 8) { - return PSA_ERROR_NOT_SUPPORTED; - } - break; -#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ - default: - (void) nonce_length; - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_ERROR_INVALID_ARGUMENT; -} - -static psa_status_t psa_aead_check_algorithm(psa_algorithm_t alg) -{ - if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_IS_WILDCARD(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - return PSA_SUCCESS; -} - -psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce_external, - size_t nonce_length, - const uint8_t *additional_data_external, - size_t additional_data_length, - const uint8_t *plaintext_external, - size_t plaintext_length, - uint8_t *ciphertext_external, - size_t ciphertext_size, - size_t *ciphertext_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - LOCAL_INPUT_DECLARE(nonce_external, nonce); - LOCAL_INPUT_DECLARE(additional_data_external, additional_data); - LOCAL_INPUT_DECLARE(plaintext_external, plaintext); - LOCAL_OUTPUT_DECLARE(ciphertext_external, ciphertext); - - *ciphertext_length = 0; - - status = psa_aead_check_algorithm(alg); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_get_and_lock_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_ENCRYPT, alg); - if (status != PSA_SUCCESS) { - return status; - } - - LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); - LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length, additional_data); - LOCAL_INPUT_ALLOC(plaintext_external, plaintext_length, plaintext); - LOCAL_OUTPUT_ALLOC(ciphertext_external, ciphertext_size, ciphertext); - - status = psa_aead_check_nonce_length(alg, nonce_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_driver_wrapper_aead_encrypt( - &slot->attr, slot->key.data, slot->key.bytes, - alg, - nonce, nonce_length, - additional_data, additional_data_length, - plaintext, plaintext_length, - ciphertext, ciphertext_size, ciphertext_length); - - if (status != PSA_SUCCESS && ciphertext_size != 0) { - memset(ciphertext, 0, ciphertext_size); - } - -exit: - LOCAL_INPUT_FREE(nonce_external, nonce); - LOCAL_INPUT_FREE(additional_data_external, additional_data); - LOCAL_INPUT_FREE(plaintext_external, plaintext); - LOCAL_OUTPUT_FREE(ciphertext_external, ciphertext); - - psa_unregister_read_under_mutex(slot); - - return status; -} - -psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce_external, - size_t nonce_length, - const uint8_t *additional_data_external, - size_t additional_data_length, - const uint8_t *ciphertext_external, - size_t ciphertext_length, - uint8_t *plaintext_external, - size_t plaintext_size, - size_t *plaintext_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - LOCAL_INPUT_DECLARE(nonce_external, nonce); - LOCAL_INPUT_DECLARE(additional_data_external, additional_data); - LOCAL_INPUT_DECLARE(ciphertext_external, ciphertext); - LOCAL_OUTPUT_DECLARE(plaintext_external, plaintext); - - *plaintext_length = 0; - - status = psa_aead_check_algorithm(alg); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_get_and_lock_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_DECRYPT, alg); - if (status != PSA_SUCCESS) { - return status; - } - - LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); - LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length, - additional_data); - LOCAL_INPUT_ALLOC(ciphertext_external, ciphertext_length, ciphertext); - LOCAL_OUTPUT_ALLOC(plaintext_external, plaintext_size, plaintext); - - status = psa_aead_check_nonce_length(alg, nonce_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_driver_wrapper_aead_decrypt( - &slot->attr, slot->key.data, slot->key.bytes, - alg, - nonce, nonce_length, - additional_data, additional_data_length, - ciphertext, ciphertext_length, - plaintext, plaintext_size, plaintext_length); - - if (status != PSA_SUCCESS && plaintext_size != 0) { - memset(plaintext, 0, plaintext_size); - } - -exit: - LOCAL_INPUT_FREE(nonce_external, nonce); - LOCAL_INPUT_FREE(additional_data_external, additional_data); - LOCAL_INPUT_FREE(ciphertext_external, ciphertext); - LOCAL_OUTPUT_FREE(plaintext_external, plaintext); - - psa_unregister_read_under_mutex(slot); - - return status; -} - -static psa_status_t psa_validate_tag_length(psa_algorithm_t alg) -{ - const uint8_t tag_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg); - - switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) { -#if defined(PSA_WANT_ALG_CCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0): - /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.*/ - if (tag_len < 4 || tag_len > 16 || tag_len % 2) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif /* PSA_WANT_ALG_CCM */ - -#if defined(PSA_WANT_ALG_GCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0): - /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. */ - if (tag_len != 4 && tag_len != 8 && (tag_len < 12 || tag_len > 16)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif /* PSA_WANT_ALG_GCM */ - -#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0): - /* We only support the default tag length. */ - if (tag_len != 16) { - return PSA_ERROR_INVALID_ARGUMENT; - } - break; -#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ - - default: - (void) tag_len; - return PSA_ERROR_NOT_SUPPORTED; - } - return PSA_SUCCESS; -} - -/* Set the key for a multipart authenticated operation. */ -static psa_status_t psa_aead_setup(psa_aead_operation_t *operation, - int is_encrypt, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - psa_key_usage_t key_usage = 0; - - status = psa_aead_check_algorithm(alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (operation->id != 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->nonce_set || operation->lengths_set || - operation->ad_started || operation->body_started) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - /* Make sure the driver-dependent part of the operation is zeroed. - * This is a guarantee we make to drivers. Initializing the operation - * does not necessarily take care of it, since the context is a - * union and initializing a union does not necessarily initialize - * all of its members. */ - memset(&operation->ctx, 0, sizeof(operation->ctx)); - - if (is_encrypt) { - key_usage = PSA_KEY_USAGE_ENCRYPT; - } else { - key_usage = PSA_KEY_USAGE_DECRYPT; - } - - status = psa_get_and_lock_key_slot_with_policy(key, &slot, key_usage, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if ((status = psa_validate_tag_length(alg)) != PSA_SUCCESS) { - goto exit; - } - - if (is_encrypt) { - status = psa_driver_wrapper_aead_encrypt_setup(operation, - &slot->attr, - slot->key.data, - slot->key.bytes, - alg); - } else { - status = psa_driver_wrapper_aead_decrypt_setup(operation, - &slot->attr, - slot->key.data, - slot->key.bytes, - alg); - } - if (status != PSA_SUCCESS) { - goto exit; - } - - operation->key_type = psa_get_key_type(&slot->attr); - -exit: - unlock_status = psa_unregister_read_under_mutex(slot); - - if (status == PSA_SUCCESS) { - status = unlock_status; - operation->alg = psa_aead_get_base_algorithm(alg); - operation->is_encrypt = is_encrypt; - } else { - psa_aead_abort(operation); - } - - return status; -} - -/* Set the key for a multipart authenticated encryption operation. */ -psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg) -{ - return psa_aead_setup(operation, 1, key, alg); -} - -/* Set the key for a multipart authenticated decryption operation. */ -psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg) -{ - return psa_aead_setup(operation, 0, key, alg); -} - -static psa_status_t psa_aead_set_nonce_internal(psa_aead_operation_t *operation, - const uint8_t *nonce, - size_t nonce_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->nonce_set) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - status = psa_aead_check_nonce_length(operation->alg, nonce_length); - if (status != PSA_SUCCESS) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - status = psa_driver_wrapper_aead_set_nonce(operation, nonce, - nonce_length); - -exit: - if (status == PSA_SUCCESS) { - operation->nonce_set = 1; - } else { - psa_aead_abort(operation); - } - - return status; -} - -/* Generate a random nonce / IV for multipart AEAD operation */ -psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, - uint8_t *nonce_external, - size_t nonce_size, - size_t *nonce_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t local_nonce[PSA_AEAD_NONCE_MAX_SIZE]; - size_t required_nonce_size = 0; - - LOCAL_OUTPUT_DECLARE(nonce_external, nonce); - LOCAL_OUTPUT_ALLOC(nonce_external, nonce_size, nonce); - - *nonce_length = 0; - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->nonce_set || !operation->is_encrypt) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - /* For CCM, this size may not be correct according to the PSA - * specification. The PSA Crypto 1.0.1 specification states: - * - * CCM encodes the plaintext length pLen in L octets, with L the smallest - * integer >= 2 where pLen < 2^(8L). The nonce length is then 15 - L bytes. - * - * However this restriction that L has to be the smallest integer is not - * applied in practice, and it is not implementable here since the - * plaintext length may or may not be known at this time. */ - required_nonce_size = PSA_AEAD_NONCE_LENGTH(operation->key_type, - operation->alg); - if (nonce_size < required_nonce_size) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - status = psa_generate_random_internal(local_nonce, required_nonce_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_aead_set_nonce_internal(operation, local_nonce, - required_nonce_size); - -exit: - if (status == PSA_SUCCESS) { - memcpy(nonce, local_nonce, required_nonce_size); - *nonce_length = required_nonce_size; - } else { - psa_aead_abort(operation); - } - - LOCAL_OUTPUT_FREE(nonce_external, nonce); - - return status; -} - -/* Set the nonce for a multipart authenticated encryption or decryption - operation.*/ -psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, - const uint8_t *nonce_external, - size_t nonce_length) -{ - psa_status_t status; - - LOCAL_INPUT_DECLARE(nonce_external, nonce); - LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); - - status = psa_aead_set_nonce_internal(operation, nonce, nonce_length); - -/* Exit label is only needed for buffer copying, prevent unused warnings. */ -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - - LOCAL_INPUT_FREE(nonce_external, nonce); - - return status; -} - -/* Declare the lengths of the message and additional data for multipart AEAD. */ -psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, - size_t ad_length, - size_t plaintext_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->lengths_set || operation->ad_started || - operation->body_started) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - switch (operation->alg) { -#if defined(PSA_WANT_ALG_GCM) - case PSA_ALG_GCM: - /* Lengths can only be too large for GCM if size_t is bigger than 32 - * bits. Without the guard this code will generate warnings on 32bit - * builds. */ -#if SIZE_MAX > UINT32_MAX - if (((uint64_t) ad_length) >> 61 != 0 || - ((uint64_t) plaintext_length) > 0xFFFFFFFE0ull) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } -#endif - break; -#endif /* PSA_WANT_ALG_GCM */ -#if defined(PSA_WANT_ALG_CCM) - case PSA_ALG_CCM: - if (ad_length > 0xFF00) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - break; -#endif /* PSA_WANT_ALG_CCM */ -#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) - case PSA_ALG_CHACHA20_POLY1305: - /* No length restrictions for ChaChaPoly. */ - break; -#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ - default: - break; - } - - status = psa_driver_wrapper_aead_set_lengths(operation, ad_length, - plaintext_length); - -exit: - if (status == PSA_SUCCESS) { - operation->ad_remaining = ad_length; - operation->body_remaining = plaintext_length; - operation->lengths_set = 1; - } else { - psa_aead_abort(operation); - } - - return status; -} - -/* Pass additional data to an active multipart AEAD operation. */ -psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, - const uint8_t *input_external, - size_t input_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_INPUT_ALLOC(input_external, input_length, input); - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (!operation->nonce_set || operation->body_started) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - /* No input to add (zero length), nothing to do. */ - if (input_length == 0) { - status = PSA_SUCCESS; - goto exit; - } - - if (operation->lengths_set) { - if (operation->ad_remaining < input_length) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - operation->ad_remaining -= input_length; - } -#if defined(PSA_WANT_ALG_CCM) - else if (operation->alg == PSA_ALG_CCM) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } -#endif /* PSA_WANT_ALG_CCM */ - - status = psa_driver_wrapper_aead_update_ad(operation, input, - input_length); - -exit: - if (status == PSA_SUCCESS) { - operation->ad_started = 1; - } else { - psa_aead_abort(operation); - } - - LOCAL_INPUT_FREE(input_external, input); - - return status; -} - -/* Encrypt or decrypt a message fragment in an active multipart AEAD - operation.*/ -psa_status_t psa_aead_update(psa_aead_operation_t *operation, - const uint8_t *input_external, - size_t input_length, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - - LOCAL_INPUT_DECLARE(input_external, input); - LOCAL_OUTPUT_DECLARE(output_external, output); - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - *output_length = 0; - - if (operation->id == 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (!operation->nonce_set) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (operation->lengths_set) { - /* Additional data length was supplied, but not all the additional - data was supplied.*/ - if (operation->ad_remaining != 0) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - /* Too much data provided. */ - if (operation->body_remaining < input_length) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - operation->body_remaining -= input_length; - } -#if defined(PSA_WANT_ALG_CCM) - else if (operation->alg == PSA_ALG_CCM) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } -#endif /* PSA_WANT_ALG_CCM */ - - status = psa_driver_wrapper_aead_update(operation, input, input_length, - output, output_size, - output_length); - -exit: - if (status == PSA_SUCCESS) { - operation->body_started = 1; - } else { - psa_aead_abort(operation); - } - - LOCAL_INPUT_FREE(input_external, input); - LOCAL_OUTPUT_FREE(output_external, output); - - return status; -} - -static psa_status_t psa_aead_final_checks(const psa_aead_operation_t *operation) -{ - if (operation->alg == PSA_ALG_CCM && !operation->lengths_set) { - return PSA_ERROR_BAD_STATE; - } - - if (operation->id == 0 || !operation->nonce_set) { - return PSA_ERROR_BAD_STATE; - } - - if (operation->lengths_set && (operation->ad_remaining != 0 || - operation->body_remaining != 0)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - return PSA_SUCCESS; -} - -/* Finish encrypting a message in a multipart AEAD operation. */ -psa_status_t psa_aead_finish(psa_aead_operation_t *operation, - uint8_t *ciphertext_external, - size_t ciphertext_size, - size_t *ciphertext_length, - uint8_t *tag_external, - size_t tag_size, - size_t *tag_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - LOCAL_OUTPUT_DECLARE(ciphertext_external, ciphertext); - LOCAL_OUTPUT_DECLARE(tag_external, tag); - - LOCAL_OUTPUT_ALLOC(ciphertext_external, ciphertext_size, ciphertext); - LOCAL_OUTPUT_ALLOC(tag_external, tag_size, tag); - - *ciphertext_length = 0; - *tag_length = tag_size; - - status = psa_aead_final_checks(operation); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (!operation->is_encrypt) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - status = psa_driver_wrapper_aead_finish(operation, ciphertext, - ciphertext_size, - ciphertext_length, - tag, tag_size, tag_length); - -exit: - - - /* In case the operation fails and the user fails to check for failure or - * the zero tag size, make sure the tag is set to something implausible. - * Even if the operation succeeds, make sure we clear the rest of the - * buffer to prevent potential leakage of anything previously placed in - * the same buffer.*/ - psa_wipe_tag_output_buffer(tag, status, tag_size, *tag_length); - - psa_aead_abort(operation); - - LOCAL_OUTPUT_FREE(ciphertext_external, ciphertext); - LOCAL_OUTPUT_FREE(tag_external, tag); - - return status; -} - -/* Finish authenticating and decrypting a message in a multipart AEAD - operation.*/ -psa_status_t psa_aead_verify(psa_aead_operation_t *operation, - uint8_t *plaintext_external, - size_t plaintext_size, - size_t *plaintext_length, - const uint8_t *tag_external, - size_t tag_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - LOCAL_OUTPUT_DECLARE(plaintext_external, plaintext); - LOCAL_INPUT_DECLARE(tag_external, tag); - - LOCAL_OUTPUT_ALLOC(plaintext_external, plaintext_size, plaintext); - LOCAL_INPUT_ALLOC(tag_external, tag_length, tag); - - *plaintext_length = 0; - - status = psa_aead_final_checks(operation); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (operation->is_encrypt) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - status = psa_driver_wrapper_aead_verify(operation, plaintext, - plaintext_size, - plaintext_length, - tag, tag_length); - -exit: - psa_aead_abort(operation); - - LOCAL_OUTPUT_FREE(plaintext_external, plaintext); - LOCAL_INPUT_FREE(tag_external, tag); - - return status; -} - -/* Abort an AEAD operation. */ -psa_status_t psa_aead_abort(psa_aead_operation_t *operation) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (operation->id == 0) { - /* The object has (apparently) been initialized but it is not (yet) - * in use. It's ok to call abort on such an object, and there's - * nothing to do. */ - return PSA_SUCCESS; - } - - status = psa_driver_wrapper_aead_abort(operation); - - memset(operation, 0, sizeof(*operation)); - - return status; -} - -/****************************************************************/ -/* Key derivation: output generation */ -/****************************************************************/ - -#if defined(BUILTIN_ALG_ANY_HKDF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) || \ - defined(PSA_HAVE_SOFT_PBKDF2) -#define AT_LEAST_ONE_BUILTIN_KDF -#endif /* At least one builtin KDF */ - -#if defined(BUILTIN_ALG_ANY_HKDF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - -/** Internal helper to set up an HMAC operation with a key passed directly. - * - * \param[in,out] operation A MAC operation object. It does not need to - * be initialized. - * \param hash_alg The hash algorithm used for HMAC. - * \param hmac_key The HMAC key. - * \param hmac_key_length Length of \p hmac_key in bytes. - * - * \return A PSA status code. - */ -static psa_status_t psa_key_derivation_start_hmac( - psa_mac_operation_t *operation, - psa_algorithm_t hash_alg, - const uint8_t *hmac_key, - size_t hmac_key_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); - psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(hmac_key_length)); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); - - /* Make sure the whole the operation is zeroed. - * It isn't enough to require the caller to initialize operation to - * PSA_MAC_OPERATION_INIT, since one field is a union and initializing - * a union does not necessarily initialize all of its members. - * psa_mac_setup() would handle PSA_MAC_OPERATION_INIT, but here we - * bypass it and call lower-level functions directly. */ - memset(operation, 0, sizeof(*operation)); - - operation->is_sign = 1; - operation->mac_size = PSA_HASH_LENGTH(hash_alg); - - status = psa_driver_wrapper_mac_sign_setup(operation, - &attributes, - hmac_key, hmac_key_length, - PSA_ALG_HMAC(hash_alg)); - - psa_reset_key_attributes(&attributes); - return status; -} -#endif /* KDF algorithms reliant on HMAC */ - -#define HKDF_STATE_INIT 0 /* no input yet */ -#define HKDF_STATE_STARTED 1 /* got salt */ -#define HKDF_STATE_KEYED 2 /* got key */ -#define HKDF_STATE_OUTPUT 3 /* output started */ - -static psa_algorithm_t psa_key_derivation_get_kdf_alg( - const psa_key_derivation_operation_t *operation) -{ - if (PSA_ALG_IS_KEY_AGREEMENT(operation->alg)) { - return PSA_ALG_KEY_AGREEMENT_GET_KDF(operation->alg); - } else { - return operation->alg; - } -} - -psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation) -{ - psa_status_t status = PSA_SUCCESS; - psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); - if (kdf_alg == 0) { - /* The object has (apparently) been initialized but it is not - * in use. It's ok to call abort on such an object, and there's - * nothing to do. */ - } else -#if defined(BUILTIN_ALG_ANY_HKDF) - if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) { - mbedtls_free(operation->ctx.hkdf.info); - status = psa_mac_abort(&operation->ctx.hkdf.hmac); - } else -#endif /* BUILTIN_ALG_ANY_HKDF */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - if (PSA_ALG_IS_TLS12_PRF(kdf_alg) || - /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */ - PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { - if (operation->ctx.tls12_prf.secret != NULL) { - mbedtls_zeroize_and_free(operation->ctx.tls12_prf.secret, - operation->ctx.tls12_prf.secret_length); - } - - if (operation->ctx.tls12_prf.seed != NULL) { - mbedtls_zeroize_and_free(operation->ctx.tls12_prf.seed, - operation->ctx.tls12_prf.seed_length); - } - - if (operation->ctx.tls12_prf.label != NULL) { - mbedtls_zeroize_and_free(operation->ctx.tls12_prf.label, - operation->ctx.tls12_prf.label_length); - } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - if (operation->ctx.tls12_prf.other_secret != NULL) { - mbedtls_zeroize_and_free(operation->ctx.tls12_prf.other_secret, - operation->ctx.tls12_prf.other_secret_length); - } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ - status = PSA_SUCCESS; - - /* We leave the fields Ai and output_block to be erased safely by the - * mbedtls_platform_zeroize() in the end of this function. */ - } else -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) - if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { - mbedtls_platform_zeroize(operation->ctx.tls12_ecjpake_to_pms.data, - sizeof(operation->ctx.tls12_ecjpake_to_pms.data)); - } else -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) */ -#if defined(PSA_HAVE_SOFT_PBKDF2) - if (PSA_ALG_IS_PBKDF2(kdf_alg)) { - if (operation->ctx.pbkdf2.salt != NULL) { - mbedtls_zeroize_and_free(operation->ctx.pbkdf2.salt, - operation->ctx.pbkdf2.salt_length); - } - - status = PSA_SUCCESS; - } else -#endif /* defined(PSA_HAVE_SOFT_PBKDF2) */ - { - status = PSA_ERROR_BAD_STATE; - } - mbedtls_platform_zeroize(operation, sizeof(*operation)); - return status; -} - -psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation, - size_t *capacity) -{ - if (operation->alg == 0) { - /* This is a blank key derivation operation. */ - return PSA_ERROR_BAD_STATE; - } - - *capacity = operation->capacity; - return PSA_SUCCESS; -} - -psa_status_t psa_key_derivation_set_capacity(psa_key_derivation_operation_t *operation, - size_t capacity) -{ - if (operation->alg == 0) { - return PSA_ERROR_BAD_STATE; - } - if (capacity > operation->capacity) { - return PSA_ERROR_INVALID_ARGUMENT; - } - operation->capacity = capacity; - return PSA_SUCCESS; -} - -#if defined(BUILTIN_ALG_ANY_HKDF) -/* Read some bytes from an HKDF-based operation. */ -static psa_status_t psa_key_derivation_hkdf_read(psa_hkdf_key_derivation_t *hkdf, - psa_algorithm_t kdf_alg, - uint8_t *output, - size_t output_length) -{ - psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg); - uint8_t hash_length = PSA_HASH_LENGTH(hash_alg); - size_t hmac_output_length; - psa_status_t status; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) - const uint8_t last_block = PSA_ALG_IS_HKDF_EXTRACT(kdf_alg) ? 0 : 0xff; -#else - const uint8_t last_block = 0xff; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ - - if (hkdf->state < HKDF_STATE_KEYED || - (!hkdf->info_set -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) - && !PSA_ALG_IS_HKDF_EXTRACT(kdf_alg) -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ - )) { - return PSA_ERROR_BAD_STATE; - } - hkdf->state = HKDF_STATE_OUTPUT; - - while (output_length != 0) { - /* Copy what remains of the current block */ - uint8_t n = hash_length - hkdf->offset_in_block; - if (n > output_length) { - n = (uint8_t) output_length; - } - memcpy(output, hkdf->output_block + hkdf->offset_in_block, n); - output += n; - output_length -= n; - hkdf->offset_in_block += n; - if (output_length == 0) { - break; - } - /* We can't be wanting more output after the last block, otherwise - * the capacity check in psa_key_derivation_output_bytes() would have - * prevented this call. It could happen only if the operation - * object was corrupted or if this function is called directly - * inside the library. */ - if (hkdf->block_number == last_block) { - return PSA_ERROR_BAD_STATE; - } - - /* We need a new block */ - ++hkdf->block_number; - hkdf->offset_in_block = 0; - - status = psa_key_derivation_start_hmac(&hkdf->hmac, - hash_alg, - hkdf->prk, - hash_length); - if (status != PSA_SUCCESS) { - return status; - } - - if (hkdf->block_number != 1) { - status = psa_mac_update(&hkdf->hmac, - hkdf->output_block, - hash_length); - if (status != PSA_SUCCESS) { - return status; - } - } - status = psa_mac_update(&hkdf->hmac, - hkdf->info, - hkdf->info_length); - if (status != PSA_SUCCESS) { - return status; - } - status = psa_mac_update(&hkdf->hmac, - &hkdf->block_number, 1); - if (status != PSA_SUCCESS) { - return status; - } - status = psa_mac_sign_finish(&hkdf->hmac, - hkdf->output_block, - sizeof(hkdf->output_block), - &hmac_output_length); - if (status != PSA_SUCCESS) { - return status; - } - } - - return PSA_SUCCESS; -} -#endif /* BUILTIN_ALG_ANY_HKDF */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) -static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( - psa_tls12_prf_key_derivation_t *tls12_prf, - psa_algorithm_t alg) -{ - psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(alg); - uint8_t hash_length = PSA_HASH_LENGTH(hash_alg); - psa_mac_operation_t hmac; - size_t hmac_output_length; - psa_status_t status, cleanup_status; - - /* We can't be wanting more output after block 0xff, otherwise - * the capacity check in psa_key_derivation_output_bytes() would have - * prevented this call. It could happen only if the operation - * object was corrupted or if this function is called directly - * inside the library. */ - if (tls12_prf->block_number == 0xff) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - - /* We need a new block */ - ++tls12_prf->block_number; - tls12_prf->left_in_block = hash_length; - - /* Recall the definition of the TLS-1.2-PRF from RFC 5246: - * - * PRF(secret, label, seed) = P_(secret, label + seed) - * - * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + - * HMAC_hash(secret, A(2) + seed) + - * HMAC_hash(secret, A(3) + seed) + ... - * - * A(0) = seed - * A(i) = HMAC_hash(secret, A(i-1)) - * - * The `psa_tls12_prf_key_derivation` structure saves the block - * `HMAC_hash(secret, A(i) + seed)` from which the output - * is currently extracted as `output_block` and where i is - * `block_number`. - */ - - status = psa_key_derivation_start_hmac(&hmac, - hash_alg, - tls12_prf->secret, - tls12_prf->secret_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - /* Calculate A(i) where i = tls12_prf->block_number. */ - if (tls12_prf->block_number == 1) { - /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads - * the variable seed and in this instance means it in the context of the - * P_hash function, where seed = label + seed.) */ - status = psa_mac_update(&hmac, - tls12_prf->label, - tls12_prf->label_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_update(&hmac, - tls12_prf->seed, - tls12_prf->seed_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - } else { - /* A(i) = HMAC_hash(secret, A(i-1)) */ - status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - } - - status = psa_mac_sign_finish(&hmac, - tls12_prf->Ai, hash_length, - &hmac_output_length); - if (hmac_output_length != hash_length) { - status = PSA_ERROR_CORRUPTION_DETECTED; - } - if (status != PSA_SUCCESS) { - goto cleanup; - } - - /* Calculate HMAC_hash(secret, A(i) + label + seed). */ - status = psa_key_derivation_start_hmac(&hmac, - hash_alg, - tls12_prf->secret, - tls12_prf->secret_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_update(&hmac, tls12_prf->Ai, hash_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_update(&hmac, tls12_prf->label, tls12_prf->label_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_update(&hmac, tls12_prf->seed, tls12_prf->seed_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_sign_finish(&hmac, - tls12_prf->output_block, hash_length, - &hmac_output_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - -cleanup: - cleanup_status = psa_mac_abort(&hmac); - if (status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS) { - status = cleanup_status; - } - - return status; -} - -static psa_status_t psa_key_derivation_tls12_prf_read( - psa_tls12_prf_key_derivation_t *tls12_prf, - psa_algorithm_t alg, - uint8_t *output, - size_t output_length) -{ - psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH(alg); - uint8_t hash_length = PSA_HASH_LENGTH(hash_alg); - psa_status_t status; - uint8_t offset, length; - - switch (tls12_prf->state) { - case PSA_TLS12_PRF_STATE_LABEL_SET: - tls12_prf->state = PSA_TLS12_PRF_STATE_OUTPUT; - break; - case PSA_TLS12_PRF_STATE_OUTPUT: - break; - default: - return PSA_ERROR_BAD_STATE; - } - - while (output_length != 0) { - /* Check if we have fully processed the current block. */ - if (tls12_prf->left_in_block == 0) { - status = psa_key_derivation_tls12_prf_generate_next_block(tls12_prf, - alg); - if (status != PSA_SUCCESS) { - return status; - } - - continue; - } - - if (tls12_prf->left_in_block > output_length) { - length = (uint8_t) output_length; - } else { - length = tls12_prf->left_in_block; - } - - offset = hash_length - tls12_prf->left_in_block; - memcpy(output, tls12_prf->output_block + offset, length); - output += length; - output_length -= length; - tls12_prf->left_in_block -= length; - } - - return PSA_SUCCESS; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || - * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) -static psa_status_t psa_key_derivation_tls12_ecjpake_to_pms_read( - psa_tls12_ecjpake_to_pms_t *ecjpake, - uint8_t *output, - size_t output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t output_size = 0; - - if (output_length != 32) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - status = psa_hash_compute(PSA_ALG_SHA_256, ecjpake->data, - PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE, output, output_length, - &output_size); - if (status != PSA_SUCCESS) { - return status; - } - - if (output_size != output_length) { - return PSA_ERROR_GENERIC_ERROR; - } - - return PSA_SUCCESS; -} -#endif - -#if defined(PSA_HAVE_SOFT_PBKDF2) -static psa_status_t psa_key_derivation_pbkdf2_generate_block( - psa_pbkdf2_key_derivation_t *pbkdf2, - psa_algorithm_t prf_alg, - uint8_t prf_output_length, - psa_key_attributes_t *attributes) -{ - psa_status_t status; - psa_mac_operation_t mac_operation; - /* Make sure the whole the operation is zeroed. - * PSA_MAC_OPERATION_INIT does not necessarily do it fully, - * since one field is a union and initializing a union does not - * necessarily initialize all of its members. - * psa_mac_setup() would do it, but here we bypass it and call - * lower-level functions directly. */ - memset(&mac_operation, 0, sizeof(mac_operation)); - size_t mac_output_length; - uint8_t U_i[PSA_MAC_MAX_SIZE]; - uint8_t *U_accumulator = pbkdf2->output_block; - uint64_t i; - uint8_t block_counter[4]; - - mac_operation.is_sign = 1; - mac_operation.mac_size = prf_output_length; - MBEDTLS_PUT_UINT32_BE(pbkdf2->block_number, block_counter, 0); - - status = psa_driver_wrapper_mac_sign_setup(&mac_operation, - attributes, - pbkdf2->password, - pbkdf2->password_length, - prf_alg); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_update(&mac_operation, pbkdf2->salt, pbkdf2->salt_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_update(&mac_operation, block_counter, sizeof(block_counter)); - if (status != PSA_SUCCESS) { - goto cleanup; - } - status = psa_mac_sign_finish(&mac_operation, U_i, sizeof(U_i), - &mac_output_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - if (mac_output_length != prf_output_length) { - status = PSA_ERROR_CORRUPTION_DETECTED; - goto cleanup; - } - - memcpy(U_accumulator, U_i, prf_output_length); - - for (i = 1; i < pbkdf2->input_cost; i++) { - /* We are passing prf_output_length as mac_size because the driver - * function directly sets mac_output_length as mac_size upon success. - * See https://github.com/Mbed-TLS/mbedtls/issues/7801 */ - status = psa_driver_wrapper_mac_compute(attributes, - pbkdf2->password, - pbkdf2->password_length, - prf_alg, U_i, prf_output_length, - U_i, prf_output_length, - &mac_output_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - mbedtls_xor(U_accumulator, U_accumulator, U_i, prf_output_length); - } - -cleanup: - /* Zeroise buffers to clear sensitive data from memory. */ - mbedtls_platform_zeroize(U_i, PSA_MAC_MAX_SIZE); - return status; -} - -static psa_status_t psa_key_derivation_pbkdf2_read( - psa_pbkdf2_key_derivation_t *pbkdf2, - psa_algorithm_t kdf_alg, - uint8_t *output, - size_t output_length) -{ - psa_status_t status; - psa_algorithm_t prf_alg; - uint8_t prf_output_length; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(pbkdf2->password_length)); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); - - if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { - prf_alg = PSA_ALG_HMAC(PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg)); - prf_output_length = PSA_HASH_LENGTH(prf_alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); - } else if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { - prf_alg = PSA_ALG_CMAC; - prf_output_length = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - } else { - return PSA_ERROR_INVALID_ARGUMENT; - } - - switch (pbkdf2->state) { - case PSA_PBKDF2_STATE_PASSWORD_SET: - /* Initially we need a new block so bytes_used is equal to block size*/ - pbkdf2->bytes_used = prf_output_length; - pbkdf2->state = PSA_PBKDF2_STATE_OUTPUT; - break; - case PSA_PBKDF2_STATE_OUTPUT: - break; - default: - return PSA_ERROR_BAD_STATE; - } - - while (output_length != 0) { - uint8_t n = prf_output_length - pbkdf2->bytes_used; - if (n > output_length) { - n = (uint8_t) output_length; - } - memcpy(output, pbkdf2->output_block + pbkdf2->bytes_used, n); - output += n; - output_length -= n; - pbkdf2->bytes_used += n; - - if (output_length == 0) { - break; - } - - /* We need a new block */ - pbkdf2->bytes_used = 0; - pbkdf2->block_number++; - - status = psa_key_derivation_pbkdf2_generate_block(pbkdf2, prf_alg, - prf_output_length, - &attributes); - if (status != PSA_SUCCESS) { - return status; - } - } - - return PSA_SUCCESS; -} -#endif /* PSA_HAVE_SOFT_PBKDF2 */ - -psa_status_t psa_key_derivation_output_bytes( - psa_key_derivation_operation_t *operation, - uint8_t *output_external, - size_t output_length) -{ - psa_status_t status; - LOCAL_OUTPUT_DECLARE(output_external, output); - - psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); - - if (operation->alg == 0) { - /* This is a blank operation. */ - return PSA_ERROR_BAD_STATE; - } - - if (output_length == 0 && operation->capacity == 0) { - /* Edge case: this is a finished operation, and 0 bytes - * were requested. The right error in this case could - * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return - * INSUFFICIENT_CAPACITY, which is right for a finished - * operation, for consistency with the case when - * output_length > 0. */ - return PSA_ERROR_INSUFFICIENT_DATA; - } - - LOCAL_OUTPUT_ALLOC(output_external, output_length, output); - if (output_length > operation->capacity) { - operation->capacity = 0; - /* Go through the error path to wipe all confidential data now - * that the operation object is useless. */ - status = PSA_ERROR_INSUFFICIENT_DATA; - goto exit; - } - - operation->capacity -= output_length; - -#if defined(BUILTIN_ALG_ANY_HKDF) - if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) { - status = psa_key_derivation_hkdf_read(&operation->ctx.hkdf, kdf_alg, - output, output_length); - } else -#endif /* BUILTIN_ALG_ANY_HKDF */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - if (PSA_ALG_IS_TLS12_PRF(kdf_alg) || - PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { - status = psa_key_derivation_tls12_prf_read(&operation->ctx.tls12_prf, - kdf_alg, output, - output_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || - * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) - if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { - status = psa_key_derivation_tls12_ecjpake_to_pms_read( - &operation->ctx.tls12_ecjpake_to_pms, output, output_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */ -#if defined(PSA_HAVE_SOFT_PBKDF2) - if (PSA_ALG_IS_PBKDF2(kdf_alg)) { - status = psa_key_derivation_pbkdf2_read(&operation->ctx.pbkdf2, kdf_alg, - output, output_length); - } else -#endif /* PSA_HAVE_SOFT_PBKDF2 */ - - { - (void) kdf_alg; - status = PSA_ERROR_BAD_STATE; - LOCAL_OUTPUT_FREE(output_external, output); - - return status; - } - -exit: - if (status != PSA_SUCCESS) { - /* Preserve the algorithm upon errors, but clear all sensitive state. - * This allows us to differentiate between exhausted operations and - * blank operations, so we can return PSA_ERROR_BAD_STATE on blank - * operations. */ - psa_algorithm_t alg = operation->alg; - psa_key_derivation_abort(operation); - operation->alg = alg; - if (output != NULL) { - memset(output, '!', output_length); - } - } - - LOCAL_OUTPUT_FREE(output_external, output); - return status; -} - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) -static void psa_des_set_key_parity(uint8_t *data, size_t data_size) -{ - if (data_size >= 8) { - mbedtls_des_key_set_parity(data); - } - if (data_size >= 16) { - mbedtls_des_key_set_parity(data + 8); - } - if (data_size >= 24) { - mbedtls_des_key_set_parity(data + 16); - } -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */ - -/* - * ECC keys on a Weierstrass elliptic curve require the generation - * of a private key which is an integer - * in the range [1, N - 1], where N is the boundary of the private key domain: - * N is the prime p for Diffie-Hellman, or the order of the - * curve’s base point for ECC. - * - * Let m be the bit size of N, such that 2^m > N >= 2^(m-1). - * This function generates the private key using the following process: - * - * 1. Draw a byte string of length ceiling(m/8) bytes. - * 2. If m is not a multiple of 8, set the most significant - * (8 * ceiling(m/8) - m) bits of the first byte in the string to zero. - * 3. Convert the string to integer k by decoding it as a big-endian byte string. - * 4. If k > N - 2, discard the result and return to step 1. - * 5. Output k + 1 as the private key. - * - * This method allows compliance to NIST standards, specifically the methods titled - * Key-Pair Generation by Testing Candidates in the following publications: - * - NIST Special Publication 800-56A: Recommendation for Pair-Wise Key-Establishment - * Schemes Using Discrete Logarithm Cryptography [SP800-56A] §5.6.1.1.4 for - * Diffie-Hellman keys. - * - * - [SP800-56A] §5.6.1.2.2 or FIPS Publication 186-4: Digital Signature - * Standard (DSS) [FIPS186-4] §B.4.2 for elliptic curve keys. - * - * Note: Function allocates memory for *data buffer, so given *data should be - * always NULL. - */ -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) -static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper( - psa_key_slot_t *slot, - size_t bits, - psa_key_derivation_operation_t *operation, - uint8_t **data - ) -{ - unsigned key_out_of_range = 1; - mbedtls_mpi k; - mbedtls_mpi diff_N_2; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t m; - size_t m_bytes = 0; - - mbedtls_mpi_init(&k); - mbedtls_mpi_init(&diff_N_2); - - psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( - slot->attr.type); - mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_from_psa(curve, bits); - - if (grp_id == MBEDTLS_ECP_DP_NONE) { - ret = MBEDTLS_ERR_ASN1_INVALID_DATA; - goto cleanup; - } - - mbedtls_ecp_group ecp_group; - mbedtls_ecp_group_init(&ecp_group); - - MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ecp_group, grp_id)); - - /* N is the boundary of the private key domain (ecp_group.N). */ - /* Let m be the bit size of N. */ - m = ecp_group.nbits; - - m_bytes = PSA_BITS_TO_BYTES(m); - - /* Calculate N - 2 - it will be needed later. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&diff_N_2, &ecp_group.N, 2)); - - /* Note: This function is always called with *data == NULL and it - * allocates memory for the data buffer. */ - *data = mbedtls_calloc(1, m_bytes); - if (*data == NULL) { - ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED; - goto cleanup; - } - - while (key_out_of_range) { - /* 1. Draw a byte string of length ceiling(m/8) bytes. */ - if ((status = psa_key_derivation_output_bytes(operation, *data, m_bytes)) != 0) { - goto cleanup; - } - - /* 2. If m is not a multiple of 8 */ - if (m % 8 != 0) { - /* Set the most significant - * (8 * ceiling(m/8) - m) bits of the first byte in - * the string to zero. - */ - uint8_t clear_bit_mask = (1 << (m % 8)) - 1; - (*data)[0] &= clear_bit_mask; - } - - /* 3. Convert the string to integer k by decoding it as a - * big-endian byte string. - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&k, *data, m_bytes)); - - /* 4. If k > N - 2, discard the result and return to step 1. - * Result of comparison is returned. When it indicates error - * then this function is called again. - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lt_mpi_ct(&diff_N_2, &k, &key_out_of_range)); - } - - /* 5. Output k + 1 as the private key. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&k, &k, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&k, *data, m_bytes)); -cleanup: - if (ret != 0) { - status = mbedtls_to_psa_error(ret); - } - if (status != PSA_SUCCESS) { - mbedtls_zeroize_and_free(*data, m_bytes); - *data = NULL; - } - mbedtls_mpi_free(&k); - mbedtls_mpi_free(&diff_N_2); - return status; -} - -/* ECC keys on a Montgomery elliptic curve draws a byte string whose length - * is determined by the curve, and sets the mandatory bits accordingly. That is: - * - * - Curve25519 (PSA_ECC_FAMILY_MONTGOMERY, 255 bits): - * draw a 32-byte string and process it as specified in - * Elliptic Curves for Security [RFC7748] §5. - * - * - Curve448 (PSA_ECC_FAMILY_MONTGOMERY, 448 bits): - * draw a 56-byte string and process it as specified in [RFC7748] §5. - * - * Note: Function allocates memory for *data buffer, so given *data should be - * always NULL. - */ - -static psa_status_t psa_generate_derived_ecc_key_montgomery_helper( - size_t bits, - psa_key_derivation_operation_t *operation, - uint8_t **data - ) -{ - size_t output_length; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - switch (bits) { - case 255: - output_length = 32; - break; - case 448: - output_length = 56; - break; - default: - return PSA_ERROR_INVALID_ARGUMENT; - break; - } - - *data = mbedtls_calloc(1, output_length); - - if (*data == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - status = psa_key_derivation_output_bytes(operation, *data, output_length); - - if (status != PSA_SUCCESS) { - return status; - } - - switch (bits) { - case 255: - (*data)[0] &= 248; - (*data)[31] &= 127; - (*data)[31] |= 64; - break; - case 448: - (*data)[0] &= 252; - (*data)[55] |= 128; - break; - default: - return PSA_ERROR_CORRUPTION_DETECTED; - break; - } - - return status; -} -#else /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ -static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper( - psa_key_slot_t *slot, size_t bits, - psa_key_derivation_operation_t *operation, uint8_t **data) -{ - (void) slot; - (void) bits; - (void) operation; - (void) data; - return PSA_ERROR_NOT_SUPPORTED; -} - -static psa_status_t psa_generate_derived_ecc_key_montgomery_helper( - size_t bits, psa_key_derivation_operation_t *operation, uint8_t **data) -{ - (void) bits; - (void) operation; - (void) data; - return PSA_ERROR_NOT_SUPPORTED; -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ -#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ - -static psa_status_t psa_generate_derived_key_internal( - psa_key_slot_t *slot, - size_t bits, - psa_key_derivation_operation_t *operation) -{ - uint8_t *data = NULL; - size_t bytes = PSA_BITS_TO_BYTES(bits); - size_t storage_size = bytes; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) - if (PSA_KEY_TYPE_IS_ECC(slot->attr.type)) { - psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type); - if (PSA_ECC_FAMILY_IS_WEIERSTRASS(curve)) { - /* Weierstrass elliptic curve */ - status = psa_generate_derived_ecc_key_weierstrass_helper(slot, bits, operation, &data); - if (status != PSA_SUCCESS) { - goto exit; - } - } else { - /* Montgomery elliptic curve */ - status = psa_generate_derived_ecc_key_montgomery_helper(bits, operation, &data); - if (status != PSA_SUCCESS) { - goto exit; - } - } - } else -#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) */ - if (key_type_is_raw_bytes(slot->attr.type)) { - if (bits % 8 != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - data = mbedtls_calloc(1, bytes); - if (data == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - status = psa_key_derivation_output_bytes(operation, data, bytes); - if (status != PSA_SUCCESS) { - goto exit; - } -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) - if (slot->attr.type == PSA_KEY_TYPE_DES) { - psa_des_set_key_parity(data, bytes); - } -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) */ - } else { - return PSA_ERROR_NOT_SUPPORTED; - } - - slot->attr.bits = (psa_key_bits_t) bits; - - if (psa_key_lifetime_is_external(slot->attr.lifetime)) { - status = psa_driver_wrapper_get_key_buffer_size(&slot->attr, - &storage_size); - if (status != PSA_SUCCESS) { - goto exit; - } - } - status = psa_allocate_buffer_to_slot(slot, storage_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_driver_wrapper_import_key(&slot->attr, - data, bytes, - slot->key.data, - slot->key.bytes, - &slot->key.bytes, &bits); - if (bits != slot->attr.bits) { - status = PSA_ERROR_INVALID_ARGUMENT; - } - -exit: - mbedtls_zeroize_and_free(data, bytes); - return status; -} - -static const psa_custom_key_parameters_t default_custom_production = - PSA_CUSTOM_KEY_PARAMETERS_INIT; - -int psa_custom_key_parameters_are_default( - const psa_custom_key_parameters_t *custom, - size_t custom_data_length) -{ - if (custom->flags != 0) { - return 0; - } - if (custom_data_length != 0) { - return 0; - } - return 1; -} - -psa_status_t psa_key_derivation_output_key_custom( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - const psa_custom_key_parameters_t *custom, - const uint8_t *custom_data, - size_t custom_data_length, - mbedtls_svc_key_id_t *key) -{ - psa_status_t status; - psa_key_slot_t *slot = NULL; - psa_se_drv_table_entry_t *driver = NULL; - - *key = MBEDTLS_SVC_KEY_ID_INIT; - - /* Reject any attempt to create a zero-length key so that we don't - * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ - if (psa_get_key_bits(attributes) == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - (void) custom_data; /* We only accept 0-length data */ - if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (operation->alg == PSA_ALG_NONE) { - return PSA_ERROR_BAD_STATE; - } - - if (!operation->can_output_key) { - return PSA_ERROR_NOT_PERMITTED; - } - - status = psa_start_key_creation(PSA_KEY_CREATION_DERIVE, attributes, - &slot, &driver); -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if (driver != NULL) { - /* Deriving a key in a secure element is not implemented yet. */ - status = PSA_ERROR_NOT_SUPPORTED; - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - if (status == PSA_SUCCESS) { - status = psa_generate_derived_key_internal(slot, - attributes->bits, - operation); - } - if (status == PSA_SUCCESS) { - status = psa_finish_key_creation(slot, driver, key); - } - if (status != PSA_SUCCESS) { - psa_fail_key_creation(slot, driver); - } - - return status; -} - -psa_status_t psa_key_derivation_output_key_ext( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - const psa_key_production_parameters_t *params, - size_t params_data_length, - mbedtls_svc_key_id_t *key) -{ - return psa_key_derivation_output_key_custom( - attributes, operation, - (const psa_custom_key_parameters_t *) params, - params->data, params_data_length, - key); -} - -psa_status_t psa_key_derivation_output_key( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t *key) -{ - return psa_key_derivation_output_key_custom(attributes, operation, - &default_custom_production, - NULL, 0, - key); -} - - -/****************************************************************/ -/* Key derivation: operation management */ -/****************************************************************/ - -#if defined(AT_LEAST_ONE_BUILTIN_KDF) -static int is_kdf_alg_supported(psa_algorithm_t kdf_alg) -{ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) - if (PSA_ALG_IS_HKDF(kdf_alg)) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) - if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) - if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) - if (PSA_ALG_IS_TLS12_PRF(kdf_alg)) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) - if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) - if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { - return 1; - } -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128) - if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { - return 1; - } -#endif - return 0; -} - -static psa_status_t psa_hash_try_support(psa_algorithm_t alg) -{ - psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; - psa_status_t status = psa_hash_setup(&operation, alg); - psa_hash_abort(&operation); - return status; -} - -static psa_status_t psa_key_derivation_set_maximum_capacity( - psa_key_derivation_operation_t *operation, - psa_algorithm_t kdf_alg) -{ -#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) - if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { - operation->capacity = PSA_HASH_LENGTH(PSA_ALG_SHA_256); - return PSA_SUCCESS; - } -#endif -#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) - if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { -#if (SIZE_MAX > UINT32_MAX) - operation->capacity = UINT32_MAX * (size_t) PSA_MAC_LENGTH( - PSA_KEY_TYPE_AES, - 128U, - PSA_ALG_CMAC); -#else - operation->capacity = SIZE_MAX; -#endif - return PSA_SUCCESS; - } -#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */ - - /* After this point, if kdf_alg is not valid then value of hash_alg may be - * invalid or meaningless but it does not affect this function */ - psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(kdf_alg); - size_t hash_size = PSA_HASH_LENGTH(hash_alg); - if (hash_size == 0) { - return PSA_ERROR_NOT_SUPPORTED; - } - - /* Make sure that hash_alg is a supported hash algorithm. Otherwise - * we might fail later, which is somewhat unfriendly and potentially - * risk-prone. */ - psa_status_t status = psa_hash_try_support(hash_alg); - if (status != PSA_SUCCESS) { - return status; - } - -#if defined(PSA_WANT_ALG_HKDF) - if (PSA_ALG_IS_HKDF(kdf_alg)) { - operation->capacity = 255 * hash_size; - } else -#endif -#if defined(PSA_WANT_ALG_HKDF_EXTRACT) - if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { - operation->capacity = hash_size; - } else -#endif -#if defined(PSA_WANT_ALG_HKDF_EXPAND) - if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { - operation->capacity = 255 * hash_size; - } else -#endif -#if defined(PSA_WANT_ALG_TLS12_PRF) - if (PSA_ALG_IS_TLS12_PRF(kdf_alg) && - (hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) { - operation->capacity = SIZE_MAX; - } else -#endif -#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) - if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg) && - (hash_alg == PSA_ALG_SHA_256 || hash_alg == PSA_ALG_SHA_384)) { - /* Master Secret is always 48 bytes - * https://datatracker.ietf.org/doc/html/rfc5246.html#section-8.1 */ - operation->capacity = 48U; - } else -#endif -#if defined(PSA_WANT_ALG_PBKDF2_HMAC) - if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { -#if (SIZE_MAX > UINT32_MAX) - operation->capacity = UINT32_MAX * hash_size; -#else - operation->capacity = SIZE_MAX; -#endif - } else -#endif /* PSA_WANT_ALG_PBKDF2_HMAC */ - { - (void) hash_size; - status = PSA_ERROR_NOT_SUPPORTED; - } - return status; -} - -static psa_status_t psa_key_derivation_setup_kdf( - psa_key_derivation_operation_t *operation, - psa_algorithm_t kdf_alg) -{ - /* Make sure that operation->ctx is properly zero-initialised. (Macro - * initialisers for this union leave some bytes unspecified.) */ - memset(&operation->ctx, 0, sizeof(operation->ctx)); - - /* Make sure that kdf_alg is a supported key derivation algorithm. */ - if (!is_kdf_alg_supported(kdf_alg)) { - return PSA_ERROR_NOT_SUPPORTED; - } - - psa_status_t status = psa_key_derivation_set_maximum_capacity(operation, - kdf_alg); - return status; -} - -static psa_status_t psa_key_agreement_try_support(psa_algorithm_t alg) -{ -#if defined(PSA_WANT_ALG_ECDH) - if (alg == PSA_ALG_ECDH) { - return PSA_SUCCESS; - } -#endif -#if defined(PSA_WANT_ALG_FFDH) - if (alg == PSA_ALG_FFDH) { - return PSA_SUCCESS; - } -#endif - (void) alg; - return PSA_ERROR_NOT_SUPPORTED; -} - -static int psa_key_derivation_allows_free_form_secret_input( - psa_algorithm_t kdf_alg) -{ -#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) - if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { - return 0; - } -#endif - (void) kdf_alg; - return 1; -} -#endif /* AT_LEAST_ONE_BUILTIN_KDF */ - -psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation, - psa_algorithm_t alg) -{ - psa_status_t status; - - if (operation->alg != 0) { - return PSA_ERROR_BAD_STATE; - } - - if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) { -#if defined(AT_LEAST_ONE_BUILTIN_KDF) - psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg); - psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(alg); - status = psa_key_agreement_try_support(ka_alg); - if (status != PSA_SUCCESS) { - return status; - } - if (!psa_key_derivation_allows_free_form_secret_input(kdf_alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - status = psa_key_derivation_setup_kdf(operation, kdf_alg); -#else - return PSA_ERROR_NOT_SUPPORTED; -#endif /* AT_LEAST_ONE_BUILTIN_KDF */ - } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) { -#if defined(AT_LEAST_ONE_BUILTIN_KDF) - status = psa_key_derivation_setup_kdf(operation, alg); -#else - return PSA_ERROR_NOT_SUPPORTED; -#endif /* AT_LEAST_ONE_BUILTIN_KDF */ - } else { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (status == PSA_SUCCESS) { - operation->alg = alg; - } - return status; -} - -#if defined(BUILTIN_ALG_ANY_HKDF) -static psa_status_t psa_hkdf_input(psa_hkdf_key_derivation_t *hkdf, - psa_algorithm_t kdf_alg, - psa_key_derivation_step_t step, - const uint8_t *data, - size_t data_length) -{ - psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg); - psa_status_t status; - switch (step) { - case PSA_KEY_DERIVATION_INPUT_SALT: -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) - if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND */ - if (hkdf->state != HKDF_STATE_INIT) { - return PSA_ERROR_BAD_STATE; - } else { - status = psa_key_derivation_start_hmac(&hkdf->hmac, - hash_alg, - data, data_length); - if (status != PSA_SUCCESS) { - return status; - } - hkdf->state = HKDF_STATE_STARTED; - return PSA_SUCCESS; - } - case PSA_KEY_DERIVATION_INPUT_SECRET: -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) - if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { - /* We shouldn't be in different state as HKDF_EXPAND only allows - * two inputs: SECRET (this case) and INFO which does not modify - * the state. It could happen only if the hkdf - * object was corrupted. */ - if (hkdf->state != HKDF_STATE_INIT) { - return PSA_ERROR_BAD_STATE; - } - - /* Allow only input that fits expected prk size */ - if (data_length != PSA_HASH_LENGTH(hash_alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - memcpy(hkdf->prk, data, data_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND */ - { - /* HKDF: If no salt was provided, use an empty salt. - * HKDF-EXTRACT: salt is mandatory. */ - if (hkdf->state == HKDF_STATE_INIT) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) - if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { - return PSA_ERROR_BAD_STATE; - } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ - status = psa_key_derivation_start_hmac(&hkdf->hmac, - hash_alg, - NULL, 0); - if (status != PSA_SUCCESS) { - return status; - } - hkdf->state = HKDF_STATE_STARTED; - } - if (hkdf->state != HKDF_STATE_STARTED) { - return PSA_ERROR_BAD_STATE; - } - status = psa_mac_update(&hkdf->hmac, - data, data_length); - if (status != PSA_SUCCESS) { - return status; - } - status = psa_mac_sign_finish(&hkdf->hmac, - hkdf->prk, - sizeof(hkdf->prk), - &data_length); - if (status != PSA_SUCCESS) { - return status; - } - } - - hkdf->state = HKDF_STATE_KEYED; - hkdf->block_number = 0; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) - if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { - /* The only block of output is the PRK. */ - memcpy(hkdf->output_block, hkdf->prk, PSA_HASH_LENGTH(hash_alg)); - hkdf->offset_in_block = 0; - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ - { - /* Block 0 is empty, and the next block will be - * generated by psa_key_derivation_hkdf_read(). */ - hkdf->offset_in_block = PSA_HASH_LENGTH(hash_alg); - } - - return PSA_SUCCESS; - case PSA_KEY_DERIVATION_INPUT_INFO: -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) - if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND) - if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg) && - hkdf->state == HKDF_STATE_INIT) { - return PSA_ERROR_BAD_STATE; - } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT */ - if (hkdf->state == HKDF_STATE_OUTPUT) { - return PSA_ERROR_BAD_STATE; - } - if (hkdf->info_set) { - return PSA_ERROR_BAD_STATE; - } - hkdf->info_length = data_length; - if (data_length != 0) { - hkdf->info = mbedtls_calloc(1, data_length); - if (hkdf->info == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - memcpy(hkdf->info, data, data_length); - } - hkdf->info_set = 1; - return PSA_SUCCESS; - default: - return PSA_ERROR_INVALID_ARGUMENT; - } -} -#endif /* BUILTIN_ALG_ANY_HKDF */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) -static psa_status_t psa_tls12_prf_set_seed(psa_tls12_prf_key_derivation_t *prf, - const uint8_t *data, - size_t data_length) -{ - if (prf->state != PSA_TLS12_PRF_STATE_INIT) { - return PSA_ERROR_BAD_STATE; - } - - if (data_length != 0) { - prf->seed = mbedtls_calloc(1, data_length); - if (prf->seed == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - memcpy(prf->seed, data, data_length); - prf->seed_length = data_length; - } - - prf->state = PSA_TLS12_PRF_STATE_SEED_SET; - - return PSA_SUCCESS; -} - -static psa_status_t psa_tls12_prf_set_key(psa_tls12_prf_key_derivation_t *prf, - const uint8_t *data, - size_t data_length) -{ - if (prf->state != PSA_TLS12_PRF_STATE_SEED_SET && - prf->state != PSA_TLS12_PRF_STATE_OTHER_KEY_SET) { - return PSA_ERROR_BAD_STATE; - } - - if (data_length != 0) { - prf->secret = mbedtls_calloc(1, data_length); - if (prf->secret == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - memcpy(prf->secret, data, data_length); - prf->secret_length = data_length; - } - - prf->state = PSA_TLS12_PRF_STATE_KEY_SET; - - return PSA_SUCCESS; -} - -static psa_status_t psa_tls12_prf_set_label(psa_tls12_prf_key_derivation_t *prf, - const uint8_t *data, - size_t data_length) -{ - if (prf->state != PSA_TLS12_PRF_STATE_KEY_SET) { - return PSA_ERROR_BAD_STATE; - } - - if (data_length != 0) { - prf->label = mbedtls_calloc(1, data_length); - if (prf->label == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - memcpy(prf->label, data, data_length); - prf->label_length = data_length; - } - - prf->state = PSA_TLS12_PRF_STATE_LABEL_SET; - - return PSA_SUCCESS; -} - -static psa_status_t psa_tls12_prf_input(psa_tls12_prf_key_derivation_t *prf, - psa_key_derivation_step_t step, - const uint8_t *data, - size_t data_length) -{ - switch (step) { - case PSA_KEY_DERIVATION_INPUT_SEED: - return psa_tls12_prf_set_seed(prf, data, data_length); - case PSA_KEY_DERIVATION_INPUT_SECRET: - return psa_tls12_prf_set_key(prf, data, data_length); - case PSA_KEY_DERIVATION_INPUT_LABEL: - return psa_tls12_prf_set_label(prf, data, data_length); - default: - return PSA_ERROR_INVALID_ARGUMENT; - } -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || - * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) -static psa_status_t psa_tls12_prf_psk_to_ms_set_key( - psa_tls12_prf_key_derivation_t *prf, - const uint8_t *data, - size_t data_length) -{ - psa_status_t status; - const size_t pms_len = (prf->state == PSA_TLS12_PRF_STATE_OTHER_KEY_SET ? - 4 + data_length + prf->other_secret_length : - 4 + 2 * data_length); - - if (data_length > PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - uint8_t *pms = mbedtls_calloc(1, pms_len); - if (pms == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - uint8_t *cur = pms; - - /* pure-PSK: - * Quoting RFC 4279, Section 2: - * - * The premaster secret is formed as follows: if the PSK is N octets - * long, concatenate a uint16 with the value N, N zero octets, a second - * uint16 with the value N, and the PSK itself. - * - * mixed-PSK: - * In a DHE-PSK, RSA-PSK, ECDHE-PSK the premaster secret is formed as - * follows: concatenate a uint16 with the length of the other secret, - * the other secret itself, uint16 with the length of PSK, and the - * PSK itself. - * For details please check: - * - RFC 4279, Section 4 for the definition of RSA-PSK, - * - RFC 4279, Section 3 for the definition of DHE-PSK, - * - RFC 5489 for the definition of ECDHE-PSK. - */ - - if (prf->state == PSA_TLS12_PRF_STATE_OTHER_KEY_SET) { - *cur++ = MBEDTLS_BYTE_1(prf->other_secret_length); - *cur++ = MBEDTLS_BYTE_0(prf->other_secret_length); - if (prf->other_secret_length != 0) { - memcpy(cur, prf->other_secret, prf->other_secret_length); - mbedtls_platform_zeroize(prf->other_secret, prf->other_secret_length); - cur += prf->other_secret_length; - } - } else { - *cur++ = MBEDTLS_BYTE_1(data_length); - *cur++ = MBEDTLS_BYTE_0(data_length); - memset(cur, 0, data_length); - cur += data_length; - } - - *cur++ = MBEDTLS_BYTE_1(data_length); - *cur++ = MBEDTLS_BYTE_0(data_length); - memcpy(cur, data, data_length); - cur += data_length; - - status = psa_tls12_prf_set_key(prf, pms, (size_t) (cur - pms)); - - mbedtls_zeroize_and_free(pms, pms_len); - return status; -} - -static psa_status_t psa_tls12_prf_psk_to_ms_set_other_key( - psa_tls12_prf_key_derivation_t *prf, - const uint8_t *data, - size_t data_length) -{ - if (prf->state != PSA_TLS12_PRF_STATE_SEED_SET) { - return PSA_ERROR_BAD_STATE; - } - - if (data_length != 0) { - prf->other_secret = mbedtls_calloc(1, data_length); - if (prf->other_secret == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - memcpy(prf->other_secret, data, data_length); - prf->other_secret_length = data_length; - } else { - prf->other_secret_length = 0; - } - - prf->state = PSA_TLS12_PRF_STATE_OTHER_KEY_SET; - - return PSA_SUCCESS; -} - -static psa_status_t psa_tls12_prf_psk_to_ms_input( - psa_tls12_prf_key_derivation_t *prf, - psa_key_derivation_step_t step, - const uint8_t *data, - size_t data_length) -{ - switch (step) { - case PSA_KEY_DERIVATION_INPUT_SECRET: - return psa_tls12_prf_psk_to_ms_set_key(prf, - data, data_length); - break; - case PSA_KEY_DERIVATION_INPUT_OTHER_SECRET: - return psa_tls12_prf_psk_to_ms_set_other_key(prf, - data, - data_length); - break; - default: - return psa_tls12_prf_input(prf, step, data, data_length); - break; - - } -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) -static psa_status_t psa_tls12_ecjpake_to_pms_input( - psa_tls12_ecjpake_to_pms_t *ecjpake, - psa_key_derivation_step_t step, - const uint8_t *data, - size_t data_length) -{ - if (data_length != PSA_TLS12_ECJPAKE_TO_PMS_INPUT_SIZE || - step != PSA_KEY_DERIVATION_INPUT_SECRET) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* Check if the passed point is in an uncompressed form */ - if (data[0] != 0x04) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* Only K.X has to be extracted - bytes 1 to 32 inclusive. */ - memcpy(ecjpake->data, data + 1, PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE); - - return PSA_SUCCESS; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */ - -#if defined(PSA_HAVE_SOFT_PBKDF2) -static psa_status_t psa_pbkdf2_set_input_cost( - psa_pbkdf2_key_derivation_t *pbkdf2, - psa_key_derivation_step_t step, - uint64_t data) -{ - if (step != PSA_KEY_DERIVATION_INPUT_COST) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (pbkdf2->state != PSA_PBKDF2_STATE_INIT) { - return PSA_ERROR_BAD_STATE; - } - - if (data > PSA_VENDOR_PBKDF2_MAX_ITERATIONS) { - return PSA_ERROR_NOT_SUPPORTED; - } - - if (data == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - pbkdf2->input_cost = data; - pbkdf2->state = PSA_PBKDF2_STATE_INPUT_COST_SET; - - return PSA_SUCCESS; -} - -static psa_status_t psa_pbkdf2_set_salt(psa_pbkdf2_key_derivation_t *pbkdf2, - const uint8_t *data, - size_t data_length) -{ - if (pbkdf2->state == PSA_PBKDF2_STATE_INPUT_COST_SET) { - pbkdf2->state = PSA_PBKDF2_STATE_SALT_SET; - } else if (pbkdf2->state == PSA_PBKDF2_STATE_SALT_SET) { - /* Appending to existing salt. No state change. */ - } else { - return PSA_ERROR_BAD_STATE; - } - - if (data_length == 0) { - /* Appending an empty string, nothing to do. */ - } else { - uint8_t *next_salt; - - next_salt = mbedtls_calloc(1, data_length + pbkdf2->salt_length); - if (next_salt == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - if (pbkdf2->salt_length != 0) { - memcpy(next_salt, pbkdf2->salt, pbkdf2->salt_length); - } - memcpy(next_salt + pbkdf2->salt_length, data, data_length); - pbkdf2->salt_length += data_length; - mbedtls_free(pbkdf2->salt); - pbkdf2->salt = next_salt; - } - return PSA_SUCCESS; -} - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) -static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg, - const uint8_t *input, - size_t input_len, - uint8_t *output, - size_t *output_len) -{ - psa_status_t status = PSA_SUCCESS; - if (input_len > PSA_HASH_BLOCK_LENGTH(hash_alg)) { - return psa_hash_compute(hash_alg, input, input_len, output, - PSA_HMAC_MAX_HASH_BLOCK_SIZE, output_len); - } else if (input_len > 0) { - memcpy(output, input, input_len); - } - *output_len = PSA_HASH_BLOCK_LENGTH(hash_alg); - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128) -static psa_status_t psa_pbkdf2_cmac_set_password(const uint8_t *input, - size_t input_len, - uint8_t *output, - size_t *output_len) -{ - psa_status_t status = PSA_SUCCESS; - if (input_len != PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC)) { - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - uint8_t zeros[16] = { 0 }; - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(sizeof(zeros))); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); - /* Passing PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC) as - * mac_size as the driver function sets mac_output_length = mac_size - * on success. See https://github.com/Mbed-TLS/mbedtls/issues/7801 */ - status = psa_driver_wrapper_mac_compute(&attributes, - zeros, sizeof(zeros), - PSA_ALG_CMAC, input, input_len, - output, - PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, - 128U, - PSA_ALG_CMAC), - output_len); - } else { - memcpy(output, input, input_len); - *output_len = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC); - } - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */ - -static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2, - psa_algorithm_t kdf_alg, - const uint8_t *data, - size_t data_length) -{ - psa_status_t status = PSA_SUCCESS; - if (pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) { - return PSA_ERROR_BAD_STATE; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) - if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { - psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg); - status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length, - pbkdf2->password, - &pbkdf2->password_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128) - if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { - status = psa_pbkdf2_cmac_set_password(data, data_length, - pbkdf2->password, - &pbkdf2->password_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */ - { - return PSA_ERROR_INVALID_ARGUMENT; - } - - pbkdf2->state = PSA_PBKDF2_STATE_PASSWORD_SET; - - return status; -} - -static psa_status_t psa_pbkdf2_input(psa_pbkdf2_key_derivation_t *pbkdf2, - psa_algorithm_t kdf_alg, - psa_key_derivation_step_t step, - const uint8_t *data, - size_t data_length) -{ - switch (step) { - case PSA_KEY_DERIVATION_INPUT_SALT: - return psa_pbkdf2_set_salt(pbkdf2, data, data_length); - case PSA_KEY_DERIVATION_INPUT_PASSWORD: - return psa_pbkdf2_set_password(pbkdf2, kdf_alg, data, data_length); - default: - return PSA_ERROR_INVALID_ARGUMENT; - } -} -#endif /* PSA_HAVE_SOFT_PBKDF2 */ - -/** Check whether the given key type is acceptable for the given - * input step of a key derivation. - * - * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE. - * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA. - * Both secret and non-secret inputs can alternatively have the type - * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning - * that the input was passed as a buffer rather than via a key object. - */ -static int psa_key_derivation_check_input_type( - psa_key_derivation_step_t step, - psa_key_type_t key_type) -{ - switch (step) { - case PSA_KEY_DERIVATION_INPUT_SECRET: - if (key_type == PSA_KEY_TYPE_DERIVE) { - return PSA_SUCCESS; - } - if (key_type == PSA_KEY_TYPE_NONE) { - return PSA_SUCCESS; - } - break; - case PSA_KEY_DERIVATION_INPUT_OTHER_SECRET: - if (key_type == PSA_KEY_TYPE_DERIVE) { - return PSA_SUCCESS; - } - if (key_type == PSA_KEY_TYPE_NONE) { - return PSA_SUCCESS; - } - break; - case PSA_KEY_DERIVATION_INPUT_LABEL: - case PSA_KEY_DERIVATION_INPUT_SALT: - case PSA_KEY_DERIVATION_INPUT_INFO: - case PSA_KEY_DERIVATION_INPUT_SEED: - if (key_type == PSA_KEY_TYPE_RAW_DATA) { - return PSA_SUCCESS; - } - if (key_type == PSA_KEY_TYPE_NONE) { - return PSA_SUCCESS; - } - break; - case PSA_KEY_DERIVATION_INPUT_PASSWORD: - if (key_type == PSA_KEY_TYPE_PASSWORD) { - return PSA_SUCCESS; - } - if (key_type == PSA_KEY_TYPE_DERIVE) { - return PSA_SUCCESS; - } - if (key_type == PSA_KEY_TYPE_NONE) { - return PSA_SUCCESS; - } - break; - } - return PSA_ERROR_INVALID_ARGUMENT; -} - -static psa_status_t psa_key_derivation_input_internal( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - psa_key_type_t key_type, - const uint8_t *data, - size_t data_length) -{ - psa_status_t status; - psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); - - if (kdf_alg == PSA_ALG_NONE) { - /* This is a blank or aborted operation. */ - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - status = psa_key_derivation_check_input_type(step, key_type); - if (status != PSA_SUCCESS) { - goto exit; - } - -#if defined(BUILTIN_ALG_ANY_HKDF) - if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) { - status = psa_hkdf_input(&operation->ctx.hkdf, kdf_alg, - step, data, data_length); - } else -#endif /* BUILTIN_ALG_ANY_HKDF */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) - if (PSA_ALG_IS_TLS12_PRF(kdf_alg)) { - status = psa_tls12_prf_input(&operation->ctx.tls12_prf, - step, data, data_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) - if (PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { - status = psa_tls12_prf_psk_to_ms_input(&operation->ctx.tls12_prf, - step, data, data_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) - if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { - status = psa_tls12_ecjpake_to_pms_input( - &operation->ctx.tls12_ecjpake_to_pms, step, data, data_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */ -#if defined(PSA_HAVE_SOFT_PBKDF2) - if (PSA_ALG_IS_PBKDF2(kdf_alg)) { - status = psa_pbkdf2_input(&operation->ctx.pbkdf2, kdf_alg, - step, data, data_length); - } else -#endif /* PSA_HAVE_SOFT_PBKDF2 */ - { - /* This can't happen unless the operation object was not initialized */ - (void) data; - (void) data_length; - (void) kdf_alg; - return PSA_ERROR_BAD_STATE; - } - -exit: - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(operation); - } - return status; -} - -static psa_status_t psa_key_derivation_input_integer_internal( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - uint64_t value) -{ - psa_status_t status; - psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); - - if (kdf_alg == PSA_ALG_NONE) { - /* This is a blank or aborted operation. */ - status = PSA_ERROR_BAD_STATE; - goto exit; - } - -#if defined(PSA_HAVE_SOFT_PBKDF2) - if (PSA_ALG_IS_PBKDF2(kdf_alg)) { - status = psa_pbkdf2_set_input_cost( - &operation->ctx.pbkdf2, step, value); - } else -#endif /* PSA_HAVE_SOFT_PBKDF2 */ - { - (void) step; - (void) value; - (void) kdf_alg; - status = PSA_ERROR_INVALID_ARGUMENT; - } - -exit: - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(operation); - } - return status; -} - -psa_status_t psa_key_derivation_input_bytes( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - const uint8_t *data_external, - size_t data_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(data_external, data); - - LOCAL_INPUT_ALLOC(data_external, data_length, data); - - status = psa_key_derivation_input_internal(operation, step, - PSA_KEY_TYPE_NONE, - data, data_length); -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_INPUT_FREE(data_external, data); - return status; -} - -psa_status_t psa_key_derivation_input_integer( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - uint64_t value) -{ - return psa_key_derivation_input_integer_internal(operation, step, value); -} - -psa_status_t psa_key_derivation_input_key( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - mbedtls_svc_key_id_t key) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - status = psa_get_and_lock_transparent_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(operation); - return status; - } - - /* Passing a key object as a SECRET or PASSWORD input unlocks the - * permission to output to a key object. */ - if (step == PSA_KEY_DERIVATION_INPUT_SECRET || - step == PSA_KEY_DERIVATION_INPUT_PASSWORD) { - operation->can_output_key = 1; - } - - status = psa_key_derivation_input_internal(operation, - step, slot->attr.type, - slot->key.data, - slot->key.bytes); - - unlock_status = psa_unregister_read_under_mutex(slot); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - - - -/****************************************************************/ -/* Key agreement */ -/****************************************************************/ - -psa_status_t psa_key_agreement_raw_builtin(const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *peer_key, - size_t peer_key_length, - uint8_t *shared_secret, - size_t shared_secret_size, - size_t *shared_secret_length) -{ - switch (alg) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) - case PSA_ALG_ECDH: - return mbedtls_psa_key_agreement_ecdh(attributes, key_buffer, - key_buffer_size, alg, - peer_key, peer_key_length, - shared_secret, - shared_secret_size, - shared_secret_length); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH) - case PSA_ALG_FFDH: - return mbedtls_psa_ffdh_key_agreement(attributes, - peer_key, - peer_key_length, - key_buffer, - key_buffer_size, - shared_secret, - shared_secret_size, - shared_secret_length); -#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */ - - default: - (void) attributes; - (void) key_buffer; - (void) key_buffer_size; - (void) peer_key; - (void) peer_key_length; - (void) shared_secret; - (void) shared_secret_size; - (void) shared_secret_length; - return PSA_ERROR_NOT_SUPPORTED; - } -} - -/** Internal function for raw key agreement - * Calls the driver wrapper which will hand off key agreement task - * to the driver's implementation if a driver is present. - * Fallback specified in the driver wrapper is built-in raw key agreement - * (psa_key_agreement_raw_builtin). - */ -static psa_status_t psa_key_agreement_raw_internal(psa_algorithm_t alg, - psa_key_slot_t *private_key, - const uint8_t *peer_key, - size_t peer_key_length, - uint8_t *shared_secret, - size_t shared_secret_size, - size_t *shared_secret_length) -{ - if (!PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) { - return PSA_ERROR_NOT_SUPPORTED; - } - - return psa_driver_wrapper_key_agreement(&private_key->attr, - private_key->key.data, - private_key->key.bytes, alg, - peer_key, peer_key_length, - shared_secret, - shared_secret_size, - shared_secret_length); -} - -/* Note that if this function fails, you must call psa_key_derivation_abort() - * to potentially free embedded data structures and wipe confidential data. - */ -static psa_status_t psa_key_agreement_internal(psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - psa_key_slot_t *private_key, - const uint8_t *peer_key, - size_t peer_key_length) -{ - psa_status_t status; - uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE] = { 0 }; - size_t shared_secret_length = 0; - psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(operation->alg); - - /* Step 1: run the secret agreement algorithm to generate the shared - * secret. */ - status = psa_key_agreement_raw_internal(ka_alg, - private_key, - peer_key, peer_key_length, - shared_secret, - sizeof(shared_secret), - &shared_secret_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* Step 2: set up the key derivation to generate key material from - * the shared secret. A shared secret is permitted wherever a key - * of type DERIVE is permitted. */ - status = psa_key_derivation_input_internal(operation, step, - PSA_KEY_TYPE_DERIVE, - shared_secret, - shared_secret_length); -exit: - mbedtls_platform_zeroize(shared_secret, shared_secret_length); - return status; -} - -psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key_external, - size_t peer_key_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - LOCAL_INPUT_DECLARE(peer_key_external, peer_key); - - if (!PSA_ALG_IS_KEY_AGREEMENT(operation->alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - status = psa_get_and_lock_transparent_key_slot_with_policy( - private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg); - if (status != PSA_SUCCESS) { - return status; - } - - LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key); - status = psa_key_agreement_internal(operation, step, - slot, - peer_key, peer_key_length); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(operation); - } else { - /* If a private key has been added as SECRET, we allow the derived - * key material to be used as a key in PSA Crypto. */ - if (step == PSA_KEY_DERIVATION_INPUT_SECRET) { - operation->can_output_key = 1; - } - } - - unlock_status = psa_unregister_read_under_mutex(slot); - LOCAL_INPUT_FREE(peer_key_external, peer_key); - - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, - mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key_external, - size_t peer_key_length, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - size_t expected_length; - LOCAL_INPUT_DECLARE(peer_key_external, peer_key); - LOCAL_OUTPUT_DECLARE(output_external, output); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - if (!PSA_ALG_IS_KEY_AGREEMENT(alg)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - status = psa_get_and_lock_transparent_key_slot_with_policy( - private_key, &slot, PSA_KEY_USAGE_DERIVE, alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is in general an upper bound - * for the output size. The PSA specification only guarantees that this - * function works if output_size >= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(...), - * but it might be nice to allow smaller buffers if the output fits. - * At the time of writing this comment, for both FFDH and ECDH, - * PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is exact so the point is moot. */ - expected_length = - PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(slot->attr.type, slot->attr.bits); - if (output_size < expected_length) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key); - status = psa_key_agreement_raw_internal(alg, slot, - peer_key, peer_key_length, - output, output_size, - output_length); - -exit: - /* Check for successful allocation of output, - * with an unsuccessful status. */ - if (output != NULL && status != PSA_SUCCESS) { - /* If an error happens and is not handled properly, the output - * may be used as a key to protect sensitive data. Arrange for such - * a key to be random, which is likely to result in decryption or - * verification errors. This is better than filling the buffer with - * some constant data such as zeros, which would result in the data - * being protected with a reproducible, easily knowable key. - */ - psa_generate_random_internal(output, output_size); - *output_length = output_size; - } - - if (output == NULL) { - /* output allocation failed. */ - *output_length = 0; - } - - unlock_status = psa_unregister_read_under_mutex(slot); - - LOCAL_INPUT_FREE(peer_key_external, peer_key); - LOCAL_OUTPUT_FREE(output_external, output); - return (status == PSA_SUCCESS) ? unlock_status : status; -} - - -/****************************************************************/ -/* Random generation */ -/****************************************************************/ - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) -#include "entropy_poll.h" -#endif - -/** Initialize the PSA random generator. - * - * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling - * this function if mutexes are enabled. - */ -static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng) -{ -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - memset(rng, 0, sizeof(*rng)); -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - psa_random_internal_init(rng); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -} - -/** Deinitialize the PSA random generator. - * - * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling - * this function if mutexes are enabled. - */ -static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng) -{ -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - memset(rng, 0, sizeof(*rng)); -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - psa_random_internal_free(rng); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -} - -/** Seed the PSA random generator. - */ -static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng) -{ -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - /* Do nothing: the external RNG seeds itself. */ - (void) rng; - return PSA_SUCCESS; -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - return psa_random_internal_seed(rng); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -} - -psa_status_t psa_random_reseed(const uint8_t *perso, size_t perso_size) -{ - GUARD_MODULE_INITIALIZED; -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - (void) perso; - (void) perso_size; - return PSA_ERROR_NOT_SUPPORTED; -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex) != 0) { - return PSA_ERROR_SERVICE_FAILURE; - } -#endif /* defined(MBEDTLS_THREADING_C) */ - int ret = mbedtls_psa_drbg_reseed(&global_data.rng.drbg, - perso, perso_size); -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - return mbedtls_to_psa_error(ret); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -} - -psa_status_t psa_random_deplete(void) -{ - GUARD_MODULE_INITIALIZED; -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - return PSA_ERROR_NOT_SUPPORTED; -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex) != 0) { - return PSA_ERROR_SERVICE_FAILURE; - } -#endif /* defined(MBEDTLS_THREADING_C) */ - mbedtls_psa_drbg_deplete(&global_data.rng.drbg); -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - return PSA_SUCCESS; -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -} - -psa_status_t psa_random_set_prediction_resistance(unsigned enabled) -{ - GUARD_MODULE_INITIALIZED; - -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - (void) enabled; - return PSA_ERROR_NOT_SUPPORTED; -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - - if (enabled != 0 && enabled != 1) { - return PSA_ERROR_INVALID_ARGUMENT; - } - -#if MBEDTLS_ENTROPY_TRUE_SOURCES > 0 -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex) != 0) { - return PSA_ERROR_SERVICE_FAILURE; - } -#endif /* defined(MBEDTLS_THREADING_C) */ - mbedtls_psa_drbg_set_prediction_resistance(&global_data.rng.drbg, enabled); -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - return PSA_SUCCESS; - -#else /* MBEDTLS_ENTROPY_TRUE_SOURCES > 0 */ - if (enabled) { - return PSA_ERROR_NOT_SUPPORTED; - } else { - return PSA_SUCCESS; - } - -#endif /* MBEDTLS_ENTROPY_TRUE_SOURCES > 0 */ -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -} - -psa_status_t psa_generate_random(uint8_t *output_external, - size_t output_size) -{ - psa_status_t status; - - LOCAL_OUTPUT_DECLARE(output_external, output); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_generate_random_internal(output, output_size); - -#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) -exit: -#endif - LOCAL_OUTPUT_FREE(output_external, output); - return status; -} - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) -psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, - size_t seed_size) -{ - if (psa_get_initialized()) { - return PSA_ERROR_NOT_PERMITTED; - } - - if (((seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM) || - (seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE)) || - (seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - return mbedtls_psa_storage_inject_entropy(seed, seed_size); -} -#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ - -/** Validate the key type and size for key generation - * - * \param type The key type - * \param bits The number of bits of the key - * - * \retval #PSA_SUCCESS - * The key type and size are valid. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size in bits of the key is not valid. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The type and/or the size in bits of the key or the combination of - * the two is not supported. - */ -static psa_status_t psa_validate_key_type_and_size_for_key_generation( - psa_key_type_t type, size_t bits) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (key_type_is_raw_bytes(type)) { - status = psa_validate_unstructured_key_bit_size(type, bits); - if (status != PSA_SUCCESS) { - return status; - } - } else -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) - if (PSA_KEY_TYPE_IS_RSA(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { - if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) { - return PSA_ERROR_NOT_SUPPORTED; - } - if (bits < PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS) { - return PSA_ERROR_NOT_SUPPORTED; - } - - /* Accept only byte-aligned keys, for the same reasons as - * in psa_import_rsa_key(). */ - if (bits % 8 != 0) { - return PSA_ERROR_NOT_SUPPORTED; - } - } else -#endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */ - -#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) - if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { - /* To avoid empty block, return successfully here. */ - return PSA_SUCCESS; - } else -#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */ - -#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) - if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { - if (psa_is_dh_key_size_valid(bits) == 0) { - return PSA_ERROR_NOT_SUPPORTED; - } - } else -#endif /* defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) */ - { - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_SUCCESS; -} - -psa_status_t psa_generate_key_internal( - const psa_key_attributes_t *attributes, - const psa_custom_key_parameters_t *custom, - const uint8_t *custom_data, - size_t custom_data_length, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t type = attributes->type; - - /* Only used for RSA */ - (void) custom; - (void) custom_data; - (void) custom_data_length; - - if (key_type_is_raw_bytes(type)) { - status = psa_generate_random_internal(key_buffer, key_buffer_size); - if (status != PSA_SUCCESS) { - return status; - } - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) - if (type == PSA_KEY_TYPE_DES) { - psa_des_set_key_parity(key_buffer, key_buffer_size); - } -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */ - } else - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) - if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - return mbedtls_psa_rsa_generate_key(attributes, - custom_data, custom_data_length, - key_buffer, - key_buffer_size, - key_buffer_length); - } else -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) - if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { - return mbedtls_psa_ecp_generate_key(attributes, - key_buffer, - key_buffer_size, - key_buffer_length); - } else -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) - if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) { - return mbedtls_psa_ffdh_generate_key(attributes, - key_buffer, - key_buffer_size, - key_buffer_length); - } else -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) */ - { - (void) key_buffer_length; - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_SUCCESS; -} - -psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes, - const psa_custom_key_parameters_t *custom, - const uint8_t *custom_data, - size_t custom_data_length, - mbedtls_svc_key_id_t *key) -{ - psa_status_t status; - psa_key_slot_t *slot = NULL; - psa_se_drv_table_entry_t *driver = NULL; - size_t key_buffer_size; - - *key = MBEDTLS_SVC_KEY_ID_INIT; - - /* Reject any attempt to create a zero-length key so that we don't - * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ - if (psa_get_key_bits(attributes) == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* Reject any attempt to create a public key. */ - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->type)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) - if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - if (custom->flags != 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } else -#endif - if (!psa_custom_key_parameters_are_default(custom, custom_data_length)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - status = psa_start_key_creation(PSA_KEY_CREATION_GENERATE, attributes, - &slot, &driver); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* In the case of a transparent key or an opaque key stored in local - * storage ( thus not in the case of generating a key in a secure element - * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a - * buffer to hold the generated key material. */ - if (slot->key.bytes == 0) { - if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) == - PSA_KEY_LOCATION_LOCAL_STORAGE) { - status = psa_validate_key_type_and_size_for_key_generation( - attributes->type, attributes->bits); - if (status != PSA_SUCCESS) { - goto exit; - } - - key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( - attributes->type, - attributes->bits); - } else { - status = psa_driver_wrapper_get_key_buffer_size( - attributes, &key_buffer_size); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - status = psa_allocate_buffer_to_slot(slot, key_buffer_size); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - status = psa_driver_wrapper_generate_key(attributes, - custom, - custom_data, custom_data_length, - slot->key.data, slot->key.bytes, - &slot->key.bytes); - if (status != PSA_SUCCESS) { - psa_remove_key_data_from_memory(slot); - } - -exit: - if (status == PSA_SUCCESS) { - status = psa_finish_key_creation(slot, driver, key); - } - if (status != PSA_SUCCESS) { - psa_fail_key_creation(slot, driver); - } - - return status; -} - -psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, - const psa_key_production_parameters_t *params, - size_t params_data_length, - mbedtls_svc_key_id_t *key) -{ - return psa_generate_key_custom( - attributes, - (const psa_custom_key_parameters_t *) params, - params->data, params_data_length, - key); -} - -psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key) -{ - return psa_generate_key_custom(attributes, - &default_custom_production, - NULL, 0, - key); -} - - - -/****************************************************************/ -/* Module setup */ -/****************************************************************/ - -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -psa_status_t mbedtls_psa_crypto_configure_entropy_sources( - void (* entropy_init)(mbedtls_entropy_context *ctx), - void (* entropy_free)(mbedtls_entropy_context *ctx)) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - if (global_data.rng_state != RNG_NOT_INITIALIZED) { - status = PSA_ERROR_BAD_STATE; - } else { - global_data.rng.entropy_init = entropy_init; - global_data.rng.entropy_free = entropy_free; - status = PSA_SUCCESS; - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - return status; -} -#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ - -void mbedtls_psa_crypto_free(void) -{ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - /* Nothing to do to free transaction. */ - if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) { - global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; - } - - if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED) { - psa_wipe_all_key_slots(); - global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED; - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - if (global_data.rng_state != RNG_NOT_INITIALIZED) { - mbedtls_psa_random_free(&global_data.rng); - } - global_data.rng_state = RNG_NOT_INITIALIZED; - mbedtls_platform_zeroize(&global_data.rng, sizeof(global_data.rng)); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - /* Terminate drivers */ - if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) { - psa_driver_wrapper_free(); - global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED; - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - -} - -#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) -/** Recover a transaction that was interrupted by a power failure. - * - * This function is called during initialization, before psa_crypto_init() - * returns. If this function returns a failure status, the initialization - * fails. - */ -static psa_status_t psa_crypto_recover_transaction( - const psa_crypto_transaction_t *transaction) -{ - switch (transaction->unknown.type) { - case PSA_CRYPTO_TRANSACTION_CREATE_KEY: - case PSA_CRYPTO_TRANSACTION_DESTROY_KEY: - /* TODO - fall through to the failure case until this - * is implemented. - * https://github.com/ARMmbed/mbed-crypto/issues/218 - */ - default: - /* We found an unsupported transaction in the storage. - * We don't know what state the storage is in. Give up. */ - return PSA_ERROR_DATA_INVALID; - } -} -#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ - -static psa_status_t mbedtls_psa_crypto_init_subsystem(mbedtls_psa_crypto_subsystem subsystem) -{ - psa_status_t status = PSA_SUCCESS; - uint8_t driver_wrappers_initialized = 0; - - switch (subsystem) { - case PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS: - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED)) { - /* Init drivers */ - status = psa_driver_wrapper_init(); - - /* Drivers need shutdown regardless of startup errors. */ - global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED; - - - } -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( - &mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - break; - - case PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS: - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED)) { - status = psa_initialize_key_slots(); - - /* Need to wipe keys even if initialization fails. */ - global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED; - - } -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( - &mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - break; - - case PSA_CRYPTO_SUBSYSTEM_RNG: - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - driver_wrappers_initialized = - (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED); - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( - &mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - /* Need to use separate mutex here, as initialisation can require - * testing of init flags, which requires locking the global data - * mutex. */ -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - /* Initialize and seed the random generator. */ - if (global_data.rng_state == RNG_NOT_INITIALIZED && driver_wrappers_initialized) { - mbedtls_psa_random_init(&global_data.rng); - global_data.rng_state = RNG_INITIALIZED; - - status = mbedtls_psa_random_seed(&global_data.rng); - if (status == PSA_SUCCESS) { - global_data.rng_state = RNG_SEEDED; - } - } - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( - &mbedtls_threading_psa_rngdata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - break; - - case PSA_CRYPTO_SUBSYSTEM_TRANSACTION: - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED)) { -#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) - status = psa_crypto_load_transaction(); - if (status == PSA_SUCCESS) { - status = psa_crypto_recover_transaction(&psa_crypto_transaction); - if (status == PSA_SUCCESS) { - global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; - } - status = psa_crypto_stop_transaction(); - } else if (status == PSA_ERROR_DOES_NOT_EXIST) { - /* There's no transaction to complete. It's all good. */ - global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; - status = PSA_SUCCESS; - } -#else /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */ - global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; - status = PSA_SUCCESS; -#endif /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */ - } - -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( - &mbedtls_threading_psa_globaldata_mutex)); -#endif /* defined(MBEDTLS_THREADING_C) */ - - break; - - default: - status = PSA_ERROR_CORRUPTION_DETECTED; - } - - /* Exit label only required when using threading macros. */ -#if defined(MBEDTLS_THREADING_C) -exit: -#endif /* defined(MBEDTLS_THREADING_C) */ - - return status; -} - -psa_status_t psa_crypto_init(void) -{ - psa_status_t status; - - /* Double initialization is explicitly allowed. Early out if everything is - * done. */ - if (psa_get_initialized()) { - return PSA_SUCCESS; - } - - status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_RNG); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_TRANSACTION); - -exit: - - if (status != PSA_SUCCESS) { - mbedtls_psa_crypto_free(); - } - - return status; -} - - - -/****************************************************************/ -/* PAKE */ -/****************************************************************/ - -#if defined(PSA_WANT_ALG_SOME_PAKE) -psa_status_t psa_crypto_driver_pake_get_password_len( - const psa_crypto_driver_pake_inputs_t *inputs, - size_t *password_len) -{ - if (inputs->password_len == 0) { - return PSA_ERROR_BAD_STATE; - } - - *password_len = inputs->password_len; - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_driver_pake_get_password( - const psa_crypto_driver_pake_inputs_t *inputs, - uint8_t *buffer, size_t buffer_size, size_t *buffer_length) -{ - if (inputs->password_len == 0) { - return PSA_ERROR_BAD_STATE; - } - - if (buffer_size < inputs->password_len) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(buffer, inputs->password, inputs->password_len); - *buffer_length = inputs->password_len; - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_driver_pake_get_user_len( - const psa_crypto_driver_pake_inputs_t *inputs, - size_t *user_len) -{ - if (inputs->user_len == 0) { - return PSA_ERROR_BAD_STATE; - } - - *user_len = inputs->user_len; - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_driver_pake_get_user( - const psa_crypto_driver_pake_inputs_t *inputs, - uint8_t *user_id, size_t user_id_size, size_t *user_id_len) -{ - if (inputs->user_len == 0) { - return PSA_ERROR_BAD_STATE; - } - - if (user_id_size < inputs->user_len) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(user_id, inputs->user, inputs->user_len); - *user_id_len = inputs->user_len; - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_driver_pake_get_peer_len( - const psa_crypto_driver_pake_inputs_t *inputs, - size_t *peer_len) -{ - if (inputs->peer_len == 0) { - return PSA_ERROR_BAD_STATE; - } - - *peer_len = inputs->peer_len; - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_driver_pake_get_peer( - const psa_crypto_driver_pake_inputs_t *inputs, - uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length) -{ - if (inputs->peer_len == 0) { - return PSA_ERROR_BAD_STATE; - } - - if (peer_id_size < inputs->peer_len) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(peer_id, inputs->peer, inputs->peer_len); - *peer_id_length = inputs->peer_len; - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_driver_pake_get_cipher_suite( - const psa_crypto_driver_pake_inputs_t *inputs, - psa_pake_cipher_suite_t *cipher_suite) -{ - if (inputs->cipher_suite.algorithm == PSA_ALG_NONE) { - return PSA_ERROR_BAD_STATE; - } - - *cipher_suite = inputs->cipher_suite; - - return PSA_SUCCESS; -} - -psa_status_t psa_pake_setup( - psa_pake_operation_t *operation, - const psa_pake_cipher_suite_t *cipher_suite) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_SETUP) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (PSA_ALG_IS_PAKE(cipher_suite->algorithm) == 0 || - PSA_ALG_IS_HASH(cipher_suite->hash) == 0) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - /* Make sure the variable-purpose part of the operation is zeroed. - * Initializing the operation does not necessarily take care of it, - * since the context is a union and initializing a union does not - * necessarily initialize all of its members. */ - memset(&operation->data, 0, sizeof(operation->data)); - - operation->alg = cipher_suite->algorithm; - operation->primitive = PSA_PAKE_PRIMITIVE(cipher_suite->type, - cipher_suite->family, cipher_suite->bits); - operation->data.inputs.cipher_suite = *cipher_suite; - -#if defined(PSA_WANT_ALG_JPAKE) - if (operation->alg == PSA_ALG_JPAKE) { - psa_jpake_computation_stage_t *computation_stage = - &operation->computation_stage.jpake; - - memset(computation_stage, 0, sizeof(*computation_stage)); - computation_stage->step = PSA_PAKE_STEP_KEY_SHARE; - } else -#endif /* PSA_WANT_ALG_JPAKE */ - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - operation->stage = PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS; - - return PSA_SUCCESS; -exit: - psa_pake_abort(operation); - return status; -} - -psa_status_t psa_pake_set_password_key( - psa_pake_operation_t *operation, - mbedtls_svc_key_id_t password) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot = NULL; - psa_key_type_t type; - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - status = psa_get_and_lock_key_slot_with_policy(password, &slot, - PSA_KEY_USAGE_DERIVE, - operation->alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - type = psa_get_key_type(&slot->attr); - - if (type != PSA_KEY_TYPE_PASSWORD && - type != PSA_KEY_TYPE_PASSWORD_HASH) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - operation->data.inputs.password = mbedtls_calloc(1, slot->key.bytes); - if (operation->data.inputs.password == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; - goto exit; - } - - memcpy(operation->data.inputs.password, slot->key.data, slot->key.bytes); - operation->data.inputs.password_len = slot->key.bytes; - operation->data.inputs.attributes = slot->attr; - -exit: - if (status != PSA_SUCCESS) { - psa_pake_abort(operation); - } - unlock_status = psa_unregister_read_under_mutex(slot); - return (status == PSA_SUCCESS) ? unlock_status : status; -} - -psa_status_t psa_pake_set_user( - psa_pake_operation_t *operation, - const uint8_t *user_id_external, - size_t user_id_len) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(user_id_external, user_id); - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (user_id_len == 0) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - if (operation->data.inputs.user_len != 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - operation->data.inputs.user = mbedtls_calloc(1, user_id_len); - if (operation->data.inputs.user == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; - goto exit; - } - - LOCAL_INPUT_ALLOC(user_id_external, user_id_len, user_id); - - memcpy(operation->data.inputs.user, user_id, user_id_len); - operation->data.inputs.user_len = user_id_len; - - status = PSA_SUCCESS; - -exit: - LOCAL_INPUT_FREE(user_id_external, user_id); - if (status != PSA_SUCCESS) { - psa_pake_abort(operation); - } - return status; -} - -psa_status_t psa_pake_set_peer( - psa_pake_operation_t *operation, - const uint8_t *peer_id_external, - size_t peer_id_len) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - LOCAL_INPUT_DECLARE(peer_id_external, peer_id); - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (peer_id_len == 0) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - if (operation->data.inputs.peer_len != 0) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - operation->data.inputs.peer = mbedtls_calloc(1, peer_id_len); - if (operation->data.inputs.peer == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; - goto exit; - } - - LOCAL_INPUT_ALLOC(peer_id_external, peer_id_len, peer_id); - - memcpy(operation->data.inputs.peer, peer_id, peer_id_len); - operation->data.inputs.peer_len = peer_id_len; - - status = PSA_SUCCESS; - -exit: - LOCAL_INPUT_FREE(peer_id_external, peer_id); - if (status != PSA_SUCCESS) { - psa_pake_abort(operation); - } - return status; -} - -psa_status_t psa_pake_set_role( - psa_pake_operation_t *operation, - psa_pake_role_t role) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - switch (operation->alg) { -#if defined(PSA_WANT_ALG_JPAKE) - case PSA_ALG_JPAKE: - if (role == PSA_PAKE_ROLE_NONE) { - return PSA_SUCCESS; - } - status = PSA_ERROR_INVALID_ARGUMENT; - break; -#endif - default: - (void) role; - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } -exit: - psa_pake_abort(operation); - return status; -} - -/* Auxiliary function to convert core computation stage to single driver step. */ -#if defined(PSA_WANT_ALG_JPAKE) -static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step( - psa_jpake_computation_stage_t *stage) -{ - psa_crypto_driver_pake_step_t key_share_step; - if (stage->round == PSA_JPAKE_FIRST) { - int is_x1; - - if (stage->io_mode == PSA_JPAKE_OUTPUT) { - is_x1 = (stage->outputs < 1); - } else { - is_x1 = (stage->inputs < 1); - } - - key_share_step = is_x1 ? - PSA_JPAKE_X1_STEP_KEY_SHARE : - PSA_JPAKE_X2_STEP_KEY_SHARE; - } else if (stage->round == PSA_JPAKE_SECOND) { - key_share_step = (stage->io_mode == PSA_JPAKE_OUTPUT) ? - PSA_JPAKE_X2S_STEP_KEY_SHARE : - PSA_JPAKE_X4S_STEP_KEY_SHARE; - } else { - return PSA_JPAKE_STEP_INVALID; - } - return (psa_crypto_driver_pake_step_t) (key_share_step + stage->step - PSA_PAKE_STEP_KEY_SHARE); -} -#endif /* PSA_WANT_ALG_JPAKE */ - -static psa_status_t psa_pake_complete_inputs( - psa_pake_operation_t *operation) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - /* Create copy of the inputs on stack as inputs share memory - with the driver context which will be setup by the driver. */ - psa_crypto_driver_pake_inputs_t inputs = operation->data.inputs; - - if (inputs.password_len == 0) { - return PSA_ERROR_BAD_STATE; - } - - if (operation->alg == PSA_ALG_JPAKE) { - if (inputs.user_len == 0 || inputs.peer_len == 0) { - return PSA_ERROR_BAD_STATE; - } - } - - /* Clear driver context */ - mbedtls_platform_zeroize(&operation->data, sizeof(operation->data)); - - status = psa_driver_wrapper_pake_setup(operation, &inputs); - - /* Driver is responsible for creating its own copy of the password. */ - mbedtls_zeroize_and_free(inputs.password, inputs.password_len); - - /* User and peer are translated to role. */ - mbedtls_free(inputs.user); - mbedtls_free(inputs.peer); - - if (status == PSA_SUCCESS) { -#if defined(PSA_WANT_ALG_JPAKE) - if (operation->alg == PSA_ALG_JPAKE) { - operation->stage = PSA_PAKE_OPERATION_STAGE_COMPUTATION; - } else -#endif /* PSA_WANT_ALG_JPAKE */ - { - status = PSA_ERROR_NOT_SUPPORTED; - } - } - return status; -} - -#if defined(PSA_WANT_ALG_JPAKE) -static psa_status_t psa_jpake_prologue( - psa_pake_operation_t *operation, - psa_pake_step_t step, - psa_jpake_io_mode_t io_mode) -{ - if (step != PSA_PAKE_STEP_KEY_SHARE && - step != PSA_PAKE_STEP_ZK_PUBLIC && - step != PSA_PAKE_STEP_ZK_PROOF) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - psa_jpake_computation_stage_t *computation_stage = - &operation->computation_stage.jpake; - - if (computation_stage->round != PSA_JPAKE_FIRST && - computation_stage->round != PSA_JPAKE_SECOND) { - return PSA_ERROR_BAD_STATE; - } - - /* Check that the step we are given is the one we were expecting */ - if (step != computation_stage->step) { - return PSA_ERROR_BAD_STATE; - } - - if (step == PSA_PAKE_STEP_KEY_SHARE && - computation_stage->inputs == 0 && - computation_stage->outputs == 0) { - /* Start of the round, so function decides whether we are inputting - * or outputting */ - computation_stage->io_mode = io_mode; - } else if (computation_stage->io_mode != io_mode) { - /* Middle of the round so the mode we are in must match the function - * called by the user */ - return PSA_ERROR_BAD_STATE; - } - - return PSA_SUCCESS; -} - -static psa_status_t psa_jpake_epilogue( - psa_pake_operation_t *operation, - psa_jpake_io_mode_t io_mode) -{ - psa_jpake_computation_stage_t *stage = - &operation->computation_stage.jpake; - - if (stage->step == PSA_PAKE_STEP_ZK_PROOF) { - /* End of an input/output */ - if (io_mode == PSA_JPAKE_INPUT) { - stage->inputs++; - if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round)) { - stage->io_mode = PSA_JPAKE_OUTPUT; - } - } - if (io_mode == PSA_JPAKE_OUTPUT) { - stage->outputs++; - if (stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { - stage->io_mode = PSA_JPAKE_INPUT; - } - } - if (stage->inputs == PSA_JPAKE_EXPECTED_INPUTS(stage->round) && - stage->outputs == PSA_JPAKE_EXPECTED_OUTPUTS(stage->round)) { - /* End of a round, move to the next round */ - stage->inputs = 0; - stage->outputs = 0; - stage->round++; - } - stage->step = PSA_PAKE_STEP_KEY_SHARE; - } else { - stage->step++; - } - return PSA_SUCCESS; -} - -#endif /* PSA_WANT_ALG_JPAKE */ - -psa_status_t psa_pake_output( - psa_pake_operation_t *operation, - psa_pake_step_t step, - uint8_t *output_external, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID; - LOCAL_OUTPUT_DECLARE(output_external, output); - *output_length = 0; - - if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { - status = psa_pake_complete_inputs(operation); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (output_size == 0) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - switch (operation->alg) { -#if defined(PSA_WANT_ALG_JPAKE) - case PSA_ALG_JPAKE: - status = psa_jpake_prologue(operation, step, PSA_JPAKE_OUTPUT); - if (status != PSA_SUCCESS) { - goto exit; - } - driver_step = convert_jpake_computation_stage_to_driver_step( - &operation->computation_stage.jpake); - break; -#endif /* PSA_WANT_ALG_JPAKE */ - default: - (void) step; - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - - status = psa_driver_wrapper_pake_output(operation, driver_step, - output, output_size, output_length); - - if (status != PSA_SUCCESS) { - goto exit; - } - - switch (operation->alg) { -#if defined(PSA_WANT_ALG_JPAKE) - case PSA_ALG_JPAKE: - status = psa_jpake_epilogue(operation, PSA_JPAKE_OUTPUT); - if (status != PSA_SUCCESS) { - goto exit; - } - break; -#endif /* PSA_WANT_ALG_JPAKE */ - default: - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - -exit: - LOCAL_OUTPUT_FREE(output_external, output); - if (status != PSA_SUCCESS) { - psa_pake_abort(operation); - } - return status; -} - -psa_status_t psa_pake_input( - psa_pake_operation_t *operation, - psa_pake_step_t step, - const uint8_t *input_external, - size_t input_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_crypto_driver_pake_step_t driver_step = PSA_JPAKE_STEP_INVALID; - const size_t max_input_length = (size_t) PSA_PAKE_INPUT_SIZE(operation->alg, - operation->primitive, - step); - LOCAL_INPUT_DECLARE(input_external, input); - - if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { - status = psa_pake_complete_inputs(operation); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - - if (input_length == 0 || input_length > max_input_length) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - switch (operation->alg) { -#if defined(PSA_WANT_ALG_JPAKE) - case PSA_ALG_JPAKE: - status = psa_jpake_prologue(operation, step, PSA_JPAKE_INPUT); - if (status != PSA_SUCCESS) { - goto exit; - } - driver_step = convert_jpake_computation_stage_to_driver_step( - &operation->computation_stage.jpake); - break; -#endif /* PSA_WANT_ALG_JPAKE */ - default: - (void) step; - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - LOCAL_INPUT_ALLOC(input_external, input_length, input); - status = psa_driver_wrapper_pake_input(operation, driver_step, - input, input_length); - - if (status != PSA_SUCCESS) { - goto exit; - } - - switch (operation->alg) { -#if defined(PSA_WANT_ALG_JPAKE) - case PSA_ALG_JPAKE: - status = psa_jpake_epilogue(operation, PSA_JPAKE_INPUT); - if (status != PSA_SUCCESS) { - goto exit; - } - break; -#endif /* PSA_WANT_ALG_JPAKE */ - default: - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - -exit: - LOCAL_INPUT_FREE(input_external, input); - if (status != PSA_SUCCESS) { - psa_pake_abort(operation); - } - return status; -} - -psa_status_t psa_pake_get_implicit_key( - psa_pake_operation_t *operation, - psa_key_derivation_operation_t *output) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t shared_key[MBEDTLS_PSA_JPAKE_BUFFER_SIZE]; - size_t shared_key_len = 0; - - if (operation->stage != PSA_PAKE_OPERATION_STAGE_COMPUTATION) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - -#if defined(PSA_WANT_ALG_JPAKE) - if (operation->alg == PSA_ALG_JPAKE) { - psa_jpake_computation_stage_t *computation_stage = - &operation->computation_stage.jpake; - if (computation_stage->round != PSA_JPAKE_FINISHED) { - status = PSA_ERROR_BAD_STATE; - goto exit; - } - } else -#endif /* PSA_WANT_ALG_JPAKE */ - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - status = psa_driver_wrapper_pake_get_implicit_key(operation, - shared_key, - sizeof(shared_key), - &shared_key_len); - - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_key_derivation_input_bytes(output, - PSA_KEY_DERIVATION_INPUT_SECRET, - shared_key, - shared_key_len); - - mbedtls_platform_zeroize(shared_key, sizeof(shared_key)); -exit: - abort_status = psa_pake_abort(operation); - return status == PSA_SUCCESS ? abort_status : status; -} - -psa_status_t psa_pake_abort( - psa_pake_operation_t *operation) -{ - psa_status_t status = PSA_SUCCESS; - - if (operation->stage == PSA_PAKE_OPERATION_STAGE_COMPUTATION) { - status = psa_driver_wrapper_pake_abort(operation); - } - - if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { - if (operation->data.inputs.password != NULL) { - mbedtls_zeroize_and_free(operation->data.inputs.password, - operation->data.inputs.password_len); - } - if (operation->data.inputs.user != NULL) { - mbedtls_free(operation->data.inputs.user); - } - if (operation->data.inputs.peer != NULL) { - mbedtls_free(operation->data.inputs.peer); - } - } - memset(operation, 0, sizeof(psa_pake_operation_t)); - - return status; -} -#endif /* PSA_WANT_ALG_SOME_PAKE */ - -/* Memory copying test hooks. These are called before input copy, after input - * copy, before output copy and after output copy, respectively. - * They are used by memory-poisoning tests to temporarily unpoison buffers - * while they are copied. */ -#if defined(MBEDTLS_TEST_HOOKS) -void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len) = NULL; -void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len) = NULL; -void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len) = NULL; -void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len) = NULL; -#endif - -/** Copy from an input buffer to a local copy. - * - * \param[in] input Pointer to input buffer. - * \param[in] input_len Length of the input buffer. - * \param[out] input_copy Pointer to a local copy in which to store the input data. - * \param[out] input_copy_len Length of the local copy buffer. - * \return #PSA_SUCCESS, if the buffer was successfully - * copied. - * \return #PSA_ERROR_CORRUPTION_DETECTED, if the local - * copy is too small to hold contents of the - * input buffer. - */ -MBEDTLS_STATIC_TESTABLE -psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, - uint8_t *input_copy, size_t input_copy_len) -{ - if (input_len > input_copy_len) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - -#if defined(MBEDTLS_TEST_HOOKS) - if (psa_input_pre_copy_hook != NULL) { - psa_input_pre_copy_hook(input, input_len); - } -#endif - - if (input_len > 0) { - memcpy(input_copy, input, input_len); - } - -#if defined(MBEDTLS_TEST_HOOKS) - if (psa_input_post_copy_hook != NULL) { - psa_input_post_copy_hook(input, input_len); - } -#endif - - return PSA_SUCCESS; -} - -/** Copy from a local output buffer into a user-supplied one. - * - * \param[in] output_copy Pointer to a local buffer containing the output. - * \param[in] output_copy_len Length of the local buffer. - * \param[out] output Pointer to user-supplied output buffer. - * \param[out] output_len Length of the user-supplied output buffer. - * \return #PSA_SUCCESS, if the buffer was successfully - * copied. - * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the - * user-supplied output buffer is too small to - * hold the contents of the local buffer. - */ -MBEDTLS_STATIC_TESTABLE -psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, - uint8_t *output, size_t output_len) -{ - if (output_len < output_copy_len) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - -#if defined(MBEDTLS_TEST_HOOKS) - if (psa_output_pre_copy_hook != NULL) { - psa_output_pre_copy_hook(output, output_len); - } -#endif - - if (output_copy_len > 0) { - memcpy(output, output_copy, output_copy_len); - } - -#if defined(MBEDTLS_TEST_HOOKS) - if (psa_output_post_copy_hook != NULL) { - psa_output_post_copy_hook(output, output_len); - } -#endif - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len, - psa_crypto_local_input_t *local_input) -{ - psa_status_t status; - - *local_input = PSA_CRYPTO_LOCAL_INPUT_INIT; - - if (input_len == 0) { - return PSA_SUCCESS; - } - - local_input->buffer = mbedtls_calloc(input_len, 1); - if (local_input->buffer == NULL) { - /* Since we dealt with the zero-length case above, we know that - * a NULL return value means a failure of allocation. */ - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - /* From now on, we must free local_input->buffer on error. */ - - local_input->length = input_len; - - status = psa_crypto_copy_input(input, input_len, - local_input->buffer, local_input->length); - if (status != PSA_SUCCESS) { - goto error; - } - - return PSA_SUCCESS; - -error: - mbedtls_zeroize_and_free(local_input->buffer, local_input->length); - local_input->buffer = NULL; - local_input->length = 0; - return status; -} - -void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input) -{ - mbedtls_zeroize_and_free(local_input->buffer, local_input->length); - local_input->buffer = NULL; - local_input->length = 0; -} - -psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, - psa_crypto_local_output_t *local_output) -{ - *local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; - - if (output_len == 0) { - return PSA_SUCCESS; - } - local_output->buffer = mbedtls_calloc(output_len, 1); - if (local_output->buffer == NULL) { - /* Since we dealt with the zero-length case above, we know that - * a NULL return value means a failure of allocation. */ - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - local_output->length = output_len; - local_output->original = output; - - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output) -{ - psa_status_t status; - - if (local_output->buffer == NULL) { - local_output->length = 0; - return PSA_SUCCESS; - } - if (local_output->original == NULL) { - /* We have an internal copy but nothing to copy back to. */ - return PSA_ERROR_CORRUPTION_DETECTED; - } - - status = psa_crypto_copy_output(local_output->buffer, local_output->length, - local_output->original, local_output->length); - if (status != PSA_SUCCESS) { - return status; - } - - mbedtls_zeroize_and_free(local_output->buffer, local_output->length); - local_output->buffer = NULL; - local_output->length = 0; - - return PSA_SUCCESS; -} - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_aead.c b/vendor/mbedtls/library/psa_crypto_aead.c deleted file mode 100644 index 307bfe784..000000000 --- a/vendor/mbedtls/library/psa_crypto_aead.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * PSA AEAD entry points - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include "psa_crypto_aead.h" -#include "psa_crypto_core.h" -#include "psa_crypto_cipher.h" - -#include -#include "mbedtls/platform.h" - -#include "mbedtls/ccm.h" -#include "mbedtls/chachapoly.h" -#include "mbedtls/cipher.h" -#include "mbedtls/gcm.h" -#include "mbedtls/error.h" - -static psa_status_t psa_aead_setup( - mbedtls_psa_aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_cipher_id_t cipher_id; - mbedtls_cipher_mode_t mode; - size_t key_bits = attributes->bits; - (void) key_buffer_size; - - status = mbedtls_cipher_values_from_psa(alg, attributes->type, - &key_bits, &mode, &cipher_id); - if (status != PSA_SUCCESS) { - return status; - } - - switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0): - operation->alg = PSA_ALG_CCM; - /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16. - * The call to mbedtls_ccm_encrypt_and_tag or - * mbedtls_ccm_auth_decrypt will validate the tag length. */ - if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - mbedtls_ccm_init(&operation->ctx.ccm); - status = mbedtls_to_psa_error( - mbedtls_ccm_setkey(&operation->ctx.ccm, cipher_id, - key_buffer, (unsigned int) key_bits)); - if (status != PSA_SUCCESS) { - return status; - } - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0): - operation->alg = PSA_ALG_GCM; - /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. - * The call to mbedtls_gcm_crypt_and_tag or - * mbedtls_gcm_auth_decrypt will validate the tag length. */ - if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - mbedtls_gcm_init(&operation->ctx.gcm); - status = mbedtls_to_psa_error( - mbedtls_gcm_setkey(&operation->ctx.gcm, cipher_id, - key_buffer, (unsigned int) key_bits)); - if (status != PSA_SUCCESS) { - return status; - } - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0): - operation->alg = PSA_ALG_CHACHA20_POLY1305; - /* We only support the default tag length. */ - if (alg != PSA_ALG_CHACHA20_POLY1305) { - return PSA_ERROR_NOT_SUPPORTED; - } - - mbedtls_chachapoly_init(&operation->ctx.chachapoly); - status = mbedtls_to_psa_error( - mbedtls_chachapoly_setkey(&operation->ctx.chachapoly, - key_buffer)); - if (status != PSA_SUCCESS) { - return status; - } - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - - default: - (void) status; - (void) key_buffer; - return PSA_ERROR_NOT_SUPPORTED; - } - - operation->key_type = psa_get_key_type(attributes); - - operation->tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg); - - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_aead_encrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *plaintext, size_t plaintext_length, - uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT; - uint8_t *tag; - - status = psa_aead_setup(&operation, attributes, key_buffer, - key_buffer_size, alg); - - if (status != PSA_SUCCESS) { - goto exit; - } - - /* For all currently supported modes, the tag is at the end of the - * ciphertext. */ - if (ciphertext_size < (plaintext_length + operation.tag_length)) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - tag = ciphertext + plaintext_length; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if (operation.alg == PSA_ALG_CCM) { - status = mbedtls_to_psa_error( - mbedtls_ccm_encrypt_and_tag(&operation.ctx.ccm, - plaintext_length, - nonce, nonce_length, - additional_data, - additional_data_length, - plaintext, ciphertext, - tag, operation.tag_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if (operation.alg == PSA_ALG_GCM) { - status = mbedtls_to_psa_error( - mbedtls_gcm_crypt_and_tag(&operation.ctx.gcm, - MBEDTLS_GCM_ENCRYPT, - plaintext_length, - nonce, nonce_length, - additional_data, additional_data_length, - plaintext, ciphertext, - operation.tag_length, tag)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if (operation.alg == PSA_ALG_CHACHA20_POLY1305) { - if (operation.tag_length != 16) { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = mbedtls_to_psa_error( - mbedtls_chachapoly_encrypt_and_tag(&operation.ctx.chachapoly, - plaintext_length, - nonce, - additional_data, - additional_data_length, - plaintext, - ciphertext, - tag)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - (void) tag; - (void) nonce; - (void) nonce_length; - (void) additional_data; - (void) additional_data_length; - (void) plaintext; - return PSA_ERROR_NOT_SUPPORTED; - } - - if (status == PSA_SUCCESS) { - *ciphertext_length = plaintext_length + operation.tag_length; - } - -exit: - mbedtls_psa_aead_abort(&operation); - - return status; -} - -/* Locate the tag in a ciphertext buffer containing the encrypted data - * followed by the tag. Return the length of the part preceding the tag in - * *plaintext_length. This is the size of the plaintext in modes where - * the encrypted data has the same size as the plaintext, such as - * CCM and GCM. */ -static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length, - const uint8_t *ciphertext, - size_t ciphertext_length, - size_t plaintext_size, - const uint8_t **p_tag) -{ - size_t payload_length; - if (tag_length > ciphertext_length) { - return PSA_ERROR_INVALID_ARGUMENT; - } - payload_length = ciphertext_length - tag_length; - if (payload_length > plaintext_size) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - *p_tag = ciphertext + payload_length; - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_aead_decrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *ciphertext, size_t ciphertext_length, - uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT; - const uint8_t *tag = NULL; - - status = psa_aead_setup(&operation, attributes, key_buffer, - key_buffer_size, alg); - - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_aead_unpadded_locate_tag(operation.tag_length, - ciphertext, ciphertext_length, - plaintext_size, &tag); - if (status != PSA_SUCCESS) { - goto exit; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if (operation.alg == PSA_ALG_CCM) { - status = mbedtls_to_psa_error( - mbedtls_ccm_auth_decrypt(&operation.ctx.ccm, - ciphertext_length - operation.tag_length, - nonce, nonce_length, - additional_data, - additional_data_length, - ciphertext, plaintext, - tag, operation.tag_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if (operation.alg == PSA_ALG_GCM) { - status = mbedtls_to_psa_error( - mbedtls_gcm_auth_decrypt(&operation.ctx.gcm, - ciphertext_length - operation.tag_length, - nonce, nonce_length, - additional_data, - additional_data_length, - tag, operation.tag_length, - ciphertext, plaintext)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if (operation.alg == PSA_ALG_CHACHA20_POLY1305) { - if (operation.tag_length != 16) { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = mbedtls_to_psa_error( - mbedtls_chachapoly_auth_decrypt(&operation.ctx.chachapoly, - ciphertext_length - operation.tag_length, - nonce, - additional_data, - additional_data_length, - tag, - ciphertext, - plaintext)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - (void) nonce; - (void) nonce_length; - (void) additional_data; - (void) additional_data_length; - (void) plaintext; - return PSA_ERROR_NOT_SUPPORTED; - } - - if (status == PSA_SUCCESS) { - *plaintext_length = ciphertext_length - operation.tag_length; - } - -exit: - mbedtls_psa_aead_abort(&operation); - - return status; -} - -/* Set the key and algorithm for a multipart authenticated encryption - * operation. */ -psa_status_t mbedtls_psa_aead_encrypt_setup( - mbedtls_psa_aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_aead_setup(operation, attributes, key_buffer, - key_buffer_size, alg); - - if (status == PSA_SUCCESS) { - operation->is_encrypt = 1; - } - - return status; -} - -/* Set the key and algorithm for a multipart authenticated decryption - * operation. */ -psa_status_t mbedtls_psa_aead_decrypt_setup( - mbedtls_psa_aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_aead_setup(operation, attributes, key_buffer, - key_buffer_size, alg); - - if (status == PSA_SUCCESS) { - operation->is_encrypt = 0; - } - - return status; -} - -/* Set a nonce for the multipart AEAD operation*/ -psa_status_t mbedtls_psa_aead_set_nonce( - mbedtls_psa_aead_operation_t *operation, - const uint8_t *nonce, - size_t nonce_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if (operation->alg == PSA_ALG_GCM) { - status = mbedtls_to_psa_error( - mbedtls_gcm_starts(&operation->ctx.gcm, - operation->is_encrypt ? - MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT, - nonce, - nonce_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if (operation->alg == PSA_ALG_CCM) { - status = mbedtls_to_psa_error( - mbedtls_ccm_starts(&operation->ctx.ccm, - operation->is_encrypt ? - MBEDTLS_CCM_ENCRYPT : MBEDTLS_CCM_DECRYPT, - nonce, - nonce_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if (operation->alg == PSA_ALG_CHACHA20_POLY1305) { - /* Note - ChaChaPoly allows an 8 byte nonce, but we would have to - * allocate a buffer in the operation, copy the nonce to it and pad - * it, so for now check the nonce is 12 bytes, as - * mbedtls_chachapoly_starts() assumes it can read 12 bytes from the - * passed in buffer. */ - if (nonce_length != 12) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - status = mbedtls_to_psa_error( - mbedtls_chachapoly_starts(&operation->ctx.chachapoly, - nonce, - operation->is_encrypt ? - MBEDTLS_CHACHAPOLY_ENCRYPT : - MBEDTLS_CHACHAPOLY_DECRYPT)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - (void) operation; - (void) nonce; - (void) nonce_length; - - return PSA_ERROR_NOT_SUPPORTED; - } - - return status; -} - -/* Declare the lengths of the message and additional data for AEAD. */ -psa_status_t mbedtls_psa_aead_set_lengths( - mbedtls_psa_aead_operation_t *operation, - size_t ad_length, - size_t plaintext_length) -{ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if (operation->alg == PSA_ALG_CCM) { - return mbedtls_to_psa_error( - mbedtls_ccm_set_lengths(&operation->ctx.ccm, - ad_length, - plaintext_length, - operation->tag_length)); - - } -#else /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ - (void) operation; - (void) ad_length; - (void) plaintext_length; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ - - return PSA_SUCCESS; -} - -/* Pass additional data to an active multipart AEAD operation. */ -psa_status_t mbedtls_psa_aead_update_ad( - mbedtls_psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if (operation->alg == PSA_ALG_GCM) { - status = mbedtls_to_psa_error( - mbedtls_gcm_update_ad(&operation->ctx.gcm, input, input_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if (operation->alg == PSA_ALG_CCM) { - status = mbedtls_to_psa_error( - mbedtls_ccm_update_ad(&operation->ctx.ccm, input, input_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if (operation->alg == PSA_ALG_CHACHA20_POLY1305) { - status = mbedtls_to_psa_error( - mbedtls_chachapoly_update_aad(&operation->ctx.chachapoly, - input, - input_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - (void) operation; - (void) input; - (void) input_length; - - return PSA_ERROR_NOT_SUPPORTED; - } - - return status; -} - -/* Encrypt or decrypt a message fragment in an active multipart AEAD - * operation.*/ -psa_status_t mbedtls_psa_aead_update( - mbedtls_psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - size_t update_output_length; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - update_output_length = input_length; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if (operation->alg == PSA_ALG_GCM) { - status = mbedtls_to_psa_error( - mbedtls_gcm_update(&operation->ctx.gcm, - input, input_length, - output, output_size, - &update_output_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if (operation->alg == PSA_ALG_CCM) { - if (output_size < input_length) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - status = mbedtls_to_psa_error( - mbedtls_ccm_update(&operation->ctx.ccm, - input, input_length, - output, output_size, - &update_output_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if (operation->alg == PSA_ALG_CHACHA20_POLY1305) { - if (output_size < input_length) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - status = mbedtls_to_psa_error( - mbedtls_chachapoly_update(&operation->ctx.chachapoly, - input_length, - input, - output)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - (void) operation; - (void) input; - (void) output; - (void) output_size; - - return PSA_ERROR_NOT_SUPPORTED; - } - - if (status == PSA_SUCCESS) { - *output_length = update_output_length; - } - - return status; -} - -/* Finish encrypting a message in a multipart AEAD operation. */ -psa_status_t mbedtls_psa_aead_finish( - mbedtls_psa_aead_operation_t *operation, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length, - uint8_t *tag, - size_t tag_size, - size_t *tag_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t finish_output_size = 0; - - if (tag_size < operation->tag_length) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if (operation->alg == PSA_ALG_GCM) { - status = mbedtls_to_psa_error( - mbedtls_gcm_finish(&operation->ctx.gcm, - ciphertext, ciphertext_size, ciphertext_length, - tag, operation->tag_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if (operation->alg == PSA_ALG_CCM) { - /* tag must be big enough to store a tag of size passed into set - * lengths. */ - if (tag_size < operation->tag_length) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - status = mbedtls_to_psa_error( - mbedtls_ccm_finish(&operation->ctx.ccm, - tag, operation->tag_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if (operation->alg == PSA_ALG_CHACHA20_POLY1305) { - /* Belt and braces. Although the above tag_size check should have - * already done this, if we later start supporting smaller tag sizes - * for chachapoly, then passing a tag buffer smaller than 16 into here - * could cause a buffer overflow, so better safe than sorry. */ - if (tag_size < 16) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - status = mbedtls_to_psa_error( - mbedtls_chachapoly_finish(&operation->ctx.chachapoly, - tag)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - (void) ciphertext; - (void) ciphertext_size; - (void) ciphertext_length; - (void) tag; - (void) tag_size; - (void) tag_length; - - return PSA_ERROR_NOT_SUPPORTED; - } - - if (status == PSA_SUCCESS) { - /* This will be zero for all supported algorithms currently, but left - * here for future support. */ - *ciphertext_length = finish_output_size; - *tag_length = operation->tag_length; - } - - return status; -} - -/* Abort an AEAD operation */ -psa_status_t mbedtls_psa_aead_abort( - mbedtls_psa_aead_operation_t *operation) -{ - switch (operation->alg) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - case PSA_ALG_CCM: - mbedtls_ccm_free(&operation->ctx.ccm); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - case PSA_ALG_GCM: - mbedtls_gcm_free(&operation->ctx.gcm); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - case PSA_ALG_CHACHA20_POLY1305: - mbedtls_chachapoly_free(&operation->ctx.chachapoly); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - } - - operation->is_encrypt = 0; - - return PSA_SUCCESS; -} - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_aead.h b/vendor/mbedtls/library/psa_crypto_aead.h deleted file mode 100644 index a3392199f..000000000 --- a/vendor/mbedtls/library/psa_crypto_aead.h +++ /dev/null @@ -1,499 +0,0 @@ -/* - * PSA AEAD driver entry points - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_AEAD_H -#define PSA_CRYPTO_AEAD_H - -#include - -/** - * \brief Process an authenticated encryption operation. - * - * \note The signature of this function is that of a PSA driver - * aead_encrypt entry point. This function behaves as an aead_encrypt - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param alg The AEAD algorithm to compute. - * \param[in] nonce Nonce or IV to use. - * \param nonce_length Size of the nonce buffer in bytes. This must - * be appropriate for the selected algorithm. - * The default nonce size is - * PSA_AEAD_NONCE_LENGTH(key_type, alg) where - * key_type is the type of key. - * \param[in] additional_data Additional data that will be authenticated - * but not encrypted. - * \param additional_data_length Size of additional_data in bytes. - * \param[in] plaintext Data that will be authenticated and encrypted. - * \param plaintext_length Size of plaintext in bytes. - * \param[out] ciphertext Output buffer for the authenticated and - * encrypted data. The additional data is not - * part of this output. For algorithms where the - * encrypted data and the authentication tag are - * defined as separate outputs, the - * authentication tag is appended to the - * encrypted data. - * \param ciphertext_size Size of the ciphertext buffer in bytes. This - * must be appropriate for the selected algorithm - * and key: - * - A sufficient output size is - * PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, - * plaintext_length) where key_type is the type - * of key. - * - PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( - * plaintext_length) evaluates to the maximum - * ciphertext size of any supported AEAD - * encryption. - * \param[out] ciphertext_length On success, the size of the output in the - * ciphertext buffer. - * - * \retval #PSA_SUCCESS Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * ciphertext_size is too small. - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_aead_encrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *plaintext, size_t plaintext_length, - uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length); - -/** - * \brief Process an authenticated decryption operation. - * - * \note The signature of this function is that of a PSA driver - * aead_decrypt entry point. This function behaves as an aead_decrypt - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param alg The AEAD algorithm to compute. - * \param[in] nonce Nonce or IV to use. - * \param nonce_length Size of the nonce buffer in bytes. This must - * be appropriate for the selected algorithm. - * The default nonce size is - * PSA_AEAD_NONCE_LENGTH(key_type, alg) where - * key_type is the type of key. - * \param[in] additional_data Additional data that has been authenticated - * but not encrypted. - * \param additional_data_length Size of additional_data in bytes. - * \param[in] ciphertext Data that has been authenticated and - * encrypted. For algorithms where the encrypted - * data and the authentication tag are defined - * as separate inputs, the buffer contains - * encrypted data followed by the authentication - * tag. - * \param ciphertext_length Size of ciphertext in bytes. - * \param[out] plaintext Output buffer for the decrypted data. - * \param plaintext_size Size of the plaintext buffer in bytes. This - * must be appropriate for the selected algorithm - * and key: - * - A sufficient output size is - * PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, - * ciphertext_length) where key_type is the - * type of key. - * - PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( - * ciphertext_length) evaluates to the maximum - * plaintext size of any supported AEAD - * decryption. - * \param[out] plaintext_length On success, the size of the output in the - * plaintext buffer. - * - * \retval #PSA_SUCCESS Success. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The cipher is not authentic. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * plaintext_size is too small. - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_aead_decrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *ciphertext, size_t ciphertext_length, - uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length); - -/** Set the key for a multipart authenticated encryption operation. - * - * \note The signature of this function is that of a PSA driver - * aead_encrypt_setup entry point. This function behaves as an - * aead_encrypt_setup entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * If an error occurs at any step after a call to - * mbedtls_psa_aead_encrypt_setup(), the operation is reset by the PSA core by a - * call to mbedtls_psa_aead_abort(). The PSA core may call - * mbedtls_psa_aead_abort() at any time after the operation has been - * initialized, and is required to when the operation is no longer needed. - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #mbedtls_psa_aead_operation_t and not yet in - * use. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - It must be consistent with the size in bits - recorded in \p attributes. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * An invalid block length was supplied. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * Failed to allocate memory for key material - */ -psa_status_t mbedtls_psa_aead_encrypt_setup( - mbedtls_psa_aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg); - -/** Set the key for a multipart authenticated decryption operation. - * - * \note The signature of this function is that of a PSA driver - * aead_decrypt_setup entry point. This function behaves as an - * aead_decrypt_setup entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * If an error occurs at any step after a call to - * mbedtls_psa_aead_decrypt_setup(), the PSA core resets the operation by a - * call to mbedtls_psa_aead_abort(). The PSA core may call - * mbedtls_psa_aead_abort() at any time after the operation has been - * initialized, and is required to when the operation is no longer needed. - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #mbedtls_psa_aead_operation_t and not yet in - * use. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - It must be consistent with the size in bits - recorded in \p attributes. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * An invalid block length was supplied. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * Failed to allocate memory for key material - */ -psa_status_t mbedtls_psa_aead_decrypt_setup( - mbedtls_psa_aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg); - -/** Set the nonce for an authenticated encryption or decryption operation. - * - * \note The signature of this function is that of a PSA driver aead_set_nonce - * entry point. This function behaves as an aead_set_nonce entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * This function sets the nonce for the authenticated - * encryption or decryption operation. - * - * The PSA core calls mbedtls_psa_aead_encrypt_setup() or - * mbedtls_psa_aead_decrypt_setup() before calling this function. - * - * If this function returns an error status, the PSA core will call - * mbedtls_psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param[in] nonce Buffer containing the nonce to use. - * \param nonce_length Size of the nonce in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size of \p nonce is not acceptable for the chosen algorithm. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Algorithm previously set is not supported in this configuration of - * the library. - */ -psa_status_t mbedtls_psa_aead_set_nonce( - mbedtls_psa_aead_operation_t *operation, - const uint8_t *nonce, - size_t nonce_length); - -/** Declare the lengths of the message and additional data for AEAD. - * - * \note The signature of this function is that of a PSA driver aead_set_lengths - * entry point. This function behaves as an aead_set_lengths entry point - * as defined in the PSA driver interface specification for transparent - * drivers. - * - * The PSA core calls this function before calling mbedtls_psa_aead_update_ad() - * or mbedtls_psa_aead_update() if the algorithm for the operation requires it. - * If the algorithm does not require it, calling this function is optional, but - * if this function is called then the implementation must enforce the lengths. - * - * The PSA core may call this function before or after setting the nonce with - * mbedtls_psa_aead_set_nonce(). - * - * - For #PSA_ALG_CCM, calling this function is required. - * - For the other AEAD algorithms defined in this specification, calling - * this function is not required. - * - * If this function returns an error status, the PSA core calls - * mbedtls_psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param ad_length Size of the non-encrypted additional - * authenticated data in bytes. - * \param plaintext_length Size of the plaintext to encrypt in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * At least one of the lengths is not acceptable for the chosen - * algorithm. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Algorithm previously set is not supported in this configuration of - * the library. - */ -psa_status_t mbedtls_psa_aead_set_lengths( - mbedtls_psa_aead_operation_t *operation, - size_t ad_length, - size_t plaintext_length); - -/** Pass additional data to an active AEAD operation. - * - * \note The signature of this function is that of a PSA driver - * aead_update_ad entry point. This function behaves as an aead_update_ad - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * Additional data is authenticated, but not encrypted. - * - * The PSA core can call this function multiple times to pass successive - * fragments of the additional data. It will not call this function after - * passing data to encrypt or decrypt with mbedtls_psa_aead_update(). - * - * Before calling this function, the PSA core will: - * 1. Call either mbedtls_psa_aead_encrypt_setup() or - * mbedtls_psa_aead_decrypt_setup(). - * 2. Set the nonce with mbedtls_psa_aead_set_nonce(). - * - * If this function returns an error status, the PSA core will call - * mbedtls_psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param[in] input Buffer containing the fragment of - * additional data. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Algorithm previously set is not supported in this configuration of - * the library. - */ -psa_status_t mbedtls_psa_aead_update_ad( - mbedtls_psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Encrypt or decrypt a message fragment in an active AEAD operation. - * - * \note The signature of this function is that of a PSA driver - * aead_update entry point. This function behaves as an aead_update entry - * point as defined in the PSA driver interface specification for - * transparent drivers. - * - * Before calling this function, the PSA core will: - * 1. Call either mbedtls_psa_aead_encrypt_setup() or - * mbedtls_psa_aead_decrypt_setup(). The choice of setup function - * determines whether this function encrypts or decrypts its input. - * 2. Set the nonce with mbedtls_psa_aead_set_nonce(). - * 3. Call mbedtls_psa_aead_update_ad() to pass all the additional data. - * - * If this function returns an error status, the PSA core will call - * mbedtls_psa_aead_abort(). - * - * This function does not require the input to be aligned to any - * particular block boundary. If the implementation can only process - * a whole block at a time, it must consume all the input provided, but - * it may delay the end of the corresponding output until a subsequent - * call to mbedtls_psa_aead_update(), mbedtls_psa_aead_finish() provides - * sufficient input. The amount of data that can be delayed in this way is - * bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE. - * - * \param[in,out] operation Active AEAD operation. - * \param[in] input Buffer containing the message fragment to - * encrypt or decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * \param output_size Size of the \p output buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, - * \c alg, \p input_length) where - * \c key_type is the type of key and \c alg is - * the algorithm that were used to set up the - * operation. - * - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p - * input_length) evaluates to the maximum - * output size of any supported AEAD - * algorithm. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or - * #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to - * determine the required buffer size. - */ -psa_status_t mbedtls_psa_aead_update( - mbedtls_psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Finish encrypting a message in an AEAD operation. - * - * \note The signature of this function is that of a PSA driver - * aead_finish entry point. This function behaves as an aead_finish entry - * point as defined in the PSA driver interface specification for - * transparent drivers. - * - * The operation must have been set up by the PSA core with - * mbedtls_psa_aead_encrypt_setup(). - * - * This function finishes the authentication of the additional data - * formed by concatenating the inputs passed to preceding calls to - * mbedtls_psa_aead_update_ad() with the plaintext formed by concatenating the - * inputs passed to preceding calls to mbedtls_psa_aead_update(). - * - * This function has two output buffers: - * - \p ciphertext contains trailing ciphertext that was buffered from - * preceding calls to mbedtls_psa_aead_update(). - * - \p tag contains the authentication tag. - * - * Whether or not this function returns successfully, the PSA core subsequently - * calls mbedtls_psa_aead_abort() to deactivate the operation. - * - * \param[in,out] operation Active AEAD operation. - * \param[out] ciphertext Buffer where the last part of the ciphertext - * is to be written. - * \param ciphertext_size Size of the \p ciphertext buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, - * \c alg) where \c key_type is the type of key - * and \c alg is the algorithm that were used to - * set up the operation. - * - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to - * the maximum output size of any supported AEAD - * algorithm. - * \param[out] ciphertext_length On success, the number of bytes of - * returned ciphertext. - * \param[out] tag Buffer where the authentication tag is - * to be written. - * \param tag_size Size of the \p tag buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c - * key_type, \c key_bits, \c alg) where - * \c key_type and \c key_bits are the type and - * bit-size of the key, and \c alg are the - * algorithm that were used in the call to - * mbedtls_psa_aead_encrypt_setup(). - * - #PSA_AEAD_TAG_MAX_SIZE evaluates to the - * maximum tag size of any supported AEAD - * algorithm. - * \param[out] tag_length On success, the number of bytes - * that make up the returned tag. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p tag buffer is too small. - * #PSA_AEAD_TAG_LENGTH(\c key_type, key_bits, \c alg) or - * #PSA_AEAD_TAG_MAX_SIZE can be used to determine the required \p tag - * buffer size. - */ -psa_status_t mbedtls_psa_aead_finish( - mbedtls_psa_aead_operation_t *operation, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length, - uint8_t *tag, - size_t tag_size, - size_t *tag_length); - -/** Abort an AEAD operation. - * - * \note The signature of this function is that of a PSA driver - * aead_abort entry point. This function behaves as an aead_abort entry - * point as defined in the PSA driver interface specification for - * transparent drivers. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by the PSA core by it calling - * mbedtls_psa_aead_encrypt_setup() or mbedtls_psa_aead_decrypt_setup() again. - * - * The PSA core may call this function any time after the operation object has - * been initialized as described in #mbedtls_psa_aead_operation_t. - * - * In particular, calling mbedtls_psa_aead_abort() after the operation has been - * terminated by a call to mbedtls_psa_aead_abort() or - * mbedtls_psa_aead_finish() is safe and has no effect. - * - * \param[in,out] operation Initialized AEAD operation. - * - * \retval #PSA_SUCCESS - * Success. - */ -psa_status_t mbedtls_psa_aead_abort( - mbedtls_psa_aead_operation_t *operation); - -#endif /* PSA_CRYPTO_AEAD_H */ diff --git a/vendor/mbedtls/library/psa_crypto_cipher.c b/vendor/mbedtls/library/psa_crypto_cipher.c deleted file mode 100644 index 7f691c1d9..000000000 --- a/vendor/mbedtls/library/psa_crypto_cipher.c +++ /dev/null @@ -1,747 +0,0 @@ -/* - * PSA cipher driver entry points - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include "psa_crypto_cipher.h" -#include "psa_crypto_core.h" -#include "psa_crypto_random_impl.h" -#include "constant_time_internal.h" - -#include "mbedtls/cipher.h" -#include "mbedtls/error.h" - -#include - -/* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols - * are enabled, but it does not provide any compatibility check between them - * (i.e. if the specified key works with the specified algorithm). This helper - * function is meant to provide this support. - * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it - * requires CIPHER_C to be enabled. - */ -static psa_status_t mbedtls_cipher_validate_values( - psa_algorithm_t alg, - psa_key_type_t key_type) -{ - /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to - eliminate bits of the logic below. */ -#if !defined(PSA_WANT_KEY_TYPE_AES) - MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES); -#endif -#if !defined(PSA_WANT_KEY_TYPE_ARIA) - MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA); -#endif -#if !defined(PSA_WANT_KEY_TYPE_CAMELLIA) - MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA); -#endif -#if !defined(PSA_WANT_KEY_TYPE_CHACHA20) - MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20); -#endif -#if !defined(PSA_WANT_KEY_TYPE_DES) - MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES); -#endif -#if !defined(PSA_WANT_ALG_CCM) - MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0)); -#endif -#if !defined(PSA_WANT_ALG_GCM) - MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0)); -#endif -#if !defined(PSA_WANT_ALG_STREAM_CIPHER) - MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER); -#endif -#if !defined(PSA_WANT_ALG_CHACHA20_POLY1305) - MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)); -#endif -#if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) - MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG); -#endif -#if !defined(PSA_WANT_ALG_CTR) - MBEDTLS_ASSUME(alg != PSA_ALG_CTR); -#endif -#if !defined(PSA_WANT_ALG_CFB) - MBEDTLS_ASSUME(alg != PSA_ALG_CFB); -#endif -#if !defined(PSA_WANT_ALG_OFB) - MBEDTLS_ASSUME(alg != PSA_ALG_OFB); -#endif -#if !defined(PSA_WANT_ALG_ECB_NO_PADDING) - MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING); -#endif -#if !defined(PSA_WANT_ALG_CBC_NO_PADDING) - MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING); -#endif -#if !defined(PSA_WANT_ALG_CBC_PKCS7) - MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7); -#endif -#if !defined(PSA_WANT_ALG_CMAC) - MBEDTLS_ASSUME(alg != PSA_ALG_CMAC); -#endif - - if (alg == PSA_ALG_STREAM_CIPHER || - alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) { - if (key_type == PSA_KEY_TYPE_CHACHA20) { - return PSA_SUCCESS; - } - } - - if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) || - alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) || - alg == PSA_ALG_CCM_STAR_NO_TAG) { - if (key_type == PSA_KEY_TYPE_AES || - key_type == PSA_KEY_TYPE_ARIA || - key_type == PSA_KEY_TYPE_CAMELLIA) { - return PSA_SUCCESS; - } - } - - if (alg == PSA_ALG_CTR || - alg == PSA_ALG_CFB || - alg == PSA_ALG_OFB || - alg == PSA_ALG_XTS || - alg == PSA_ALG_ECB_NO_PADDING || - alg == PSA_ALG_CBC_NO_PADDING || - alg == PSA_ALG_CBC_PKCS7 || - alg == PSA_ALG_CMAC) { - if (key_type == PSA_KEY_TYPE_AES || - key_type == PSA_KEY_TYPE_ARIA || - key_type == PSA_KEY_TYPE_DES || - key_type == PSA_KEY_TYPE_CAMELLIA) { - return PSA_SUCCESS; - } - } - - return PSA_ERROR_NOT_SUPPORTED; -} - -psa_status_t mbedtls_cipher_values_from_psa( - psa_algorithm_t alg, - psa_key_type_t key_type, - size_t *key_bits, - mbedtls_cipher_mode_t *mode, - mbedtls_cipher_id_t *cipher_id) -{ - mbedtls_cipher_id_t cipher_id_tmp; - /* Only DES modifies key_bits */ -#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) - (void) key_bits; -#endif - - if (PSA_ALG_IS_AEAD(alg)) { - alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0); - } - - if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) { - switch (alg) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) - case PSA_ALG_STREAM_CIPHER: - *mode = MBEDTLS_MODE_STREAM; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) - case PSA_ALG_CTR: - *mode = MBEDTLS_MODE_CTR; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) - case PSA_ALG_CFB: - *mode = MBEDTLS_MODE_CFB; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) - case PSA_ALG_OFB: - *mode = MBEDTLS_MODE_OFB; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) - case PSA_ALG_ECB_NO_PADDING: - *mode = MBEDTLS_MODE_ECB; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) - case PSA_ALG_CBC_NO_PADDING: - *mode = MBEDTLS_MODE_CBC; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) - case PSA_ALG_CBC_PKCS7: - *mode = MBEDTLS_MODE_CBC; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG) - case PSA_ALG_CCM_STAR_NO_TAG: - *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0): - *mode = MBEDTLS_MODE_CCM; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0): - *mode = MBEDTLS_MODE_GCM; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0): - *mode = MBEDTLS_MODE_CHACHAPOLY; - break; -#endif - default: - return PSA_ERROR_NOT_SUPPORTED; - } - } else if (alg == PSA_ALG_CMAC) { - *mode = MBEDTLS_MODE_ECB; - } else { - return PSA_ERROR_NOT_SUPPORTED; - } - - switch (key_type) { -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES) - case PSA_KEY_TYPE_AES: - cipher_id_tmp = MBEDTLS_CIPHER_ID_AES; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA) - case PSA_KEY_TYPE_ARIA: - cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) - case PSA_KEY_TYPE_DES: - /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES, - * and 192 for three-key Triple-DES. */ - if (*key_bits == 64) { - cipher_id_tmp = MBEDTLS_CIPHER_ID_DES; - } else { - cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES; - } - /* mbedtls doesn't recognize two-key Triple-DES as an algorithm, - * but two-key Triple-DES is functionally three-key Triple-DES - * with K1=K3, so that's how we present it to mbedtls. */ - if (*key_bits == 128) { - *key_bits = 192; - } - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA) - case PSA_KEY_TYPE_CAMELLIA: - cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA; - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20) - case PSA_KEY_TYPE_CHACHA20: - cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20; - break; -#endif - default: - return PSA_ERROR_NOT_SUPPORTED; - } - if (cipher_id != NULL) { - *cipher_id = cipher_id_tmp; - } - - return mbedtls_cipher_validate_values(alg, key_type); -} - -#if defined(MBEDTLS_CIPHER_C) -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( - psa_algorithm_t alg, - psa_key_type_t key_type, - size_t key_bits, - mbedtls_cipher_id_t *cipher_id) -{ - mbedtls_cipher_mode_t mode; - psa_status_t status; - mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE; - - status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp); - if (status != PSA_SUCCESS) { - return NULL; - } - if (cipher_id != NULL) { - *cipher_id = cipher_id_tmp; - } - - return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode); -} -#endif /* MBEDTLS_CIPHER_C */ - -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - -static psa_status_t psa_cipher_setup( - mbedtls_psa_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - mbedtls_operation_t cipher_operation) -{ - int ret = 0; - size_t key_bits; - const mbedtls_cipher_info_t *cipher_info = NULL; - psa_key_type_t key_type = attributes->type; - - (void) key_buffer_size; - - mbedtls_cipher_init(&operation->ctx.cipher); - - operation->alg = alg; - key_bits = attributes->bits; - cipher_info = mbedtls_cipher_info_from_psa(alg, key_type, - key_bits, NULL); - if (cipher_info == NULL) { - return PSA_ERROR_NOT_SUPPORTED; - } - - ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info); - if (ret != 0) { - goto exit; - } - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) - if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) { - /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */ - uint8_t keys[24]; - memcpy(keys, key_buffer, 16); - memcpy(keys + 16, key_buffer, 8); - ret = mbedtls_cipher_setkey(&operation->ctx.cipher, - keys, - 192, cipher_operation); - } else -#endif - { - ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer, - (int) key_bits, cipher_operation); - } - if (ret != 0) { - goto exit; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) - switch (alg) { - case PSA_ALG_CBC_NO_PADDING: - ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher, - MBEDTLS_PADDING_NONE); - break; - case PSA_ALG_CBC_PKCS7: - ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher, - MBEDTLS_PADDING_PKCS7); - break; - default: - /* The algorithm doesn't involve padding. */ - ret = 0; - break; - } - if (ret != 0) { - goto exit; - } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING || - MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */ - - operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 : - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type)); - operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg); - -exit: - return mbedtls_to_psa_error(ret); -} - -psa_status_t mbedtls_psa_cipher_encrypt_setup( - mbedtls_psa_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg) -{ - return psa_cipher_setup(operation, attributes, - key_buffer, key_buffer_size, - alg, MBEDTLS_ENCRYPT); -} - -psa_status_t mbedtls_psa_cipher_decrypt_setup( - mbedtls_psa_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg) -{ - return psa_cipher_setup(operation, attributes, - key_buffer, key_buffer_size, - alg, MBEDTLS_DECRYPT); -} - -psa_status_t mbedtls_psa_cipher_set_iv( - mbedtls_psa_cipher_operation_t *operation, - const uint8_t *iv, size_t iv_length) -{ - if (iv_length != operation->iv_length) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - return mbedtls_to_psa_error( - mbedtls_cipher_set_iv(&operation->ctx.cipher, - iv, iv_length)); -} - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) -/** Process input for which the algorithm is set to ECB mode. - * - * This requires manual processing, since the PSA API is defined as being - * able to process arbitrary-length calls to psa_cipher_update() with ECB mode, - * but the underlying mbedtls_cipher_update only takes full blocks. - * - * \param ctx The mbedtls cipher context to use. It must have been - * set up for ECB. - * \param[in] input The input plaintext or ciphertext to process. - * \param input_length The number of bytes to process from \p input. - * This does not need to be aligned to a block boundary. - * If there is a partial block at the end of the input, - * it is stored in \p ctx for future processing. - * \param output The buffer where the output is written. It must be - * at least `BS * floor((p + input_length) / BS)` bytes - * long, where `p` is the number of bytes in the - * unprocessed partial block in \p ctx (with - * `0 <= p <= BS - 1`) and `BS` is the block size. - * \param output_length On success, the number of bytes written to \p output. - * \c 0 on error. - * - * \return #PSA_SUCCESS or an error from a hardware accelerator - */ -static psa_status_t psa_cipher_update_ecb( - mbedtls_cipher_context_t *ctx, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); - size_t internal_output_length = 0; - *output_length = 0; - - if (input_length == 0) { - status = PSA_SUCCESS; - goto exit; - } - - if (ctx->unprocessed_len > 0) { - /* Fill up to block size, and run the block if there's a full one. */ - size_t bytes_to_copy = block_size - ctx->unprocessed_len; - - if (input_length < bytes_to_copy) { - bytes_to_copy = input_length; - } - - memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), - input, bytes_to_copy); - input_length -= bytes_to_copy; - input += bytes_to_copy; - ctx->unprocessed_len += bytes_to_copy; - - if (ctx->unprocessed_len == block_size) { - status = mbedtls_to_psa_error( - mbedtls_cipher_update(ctx, - ctx->unprocessed_data, - block_size, - output, &internal_output_length)); - - if (status != PSA_SUCCESS) { - goto exit; - } - - output += internal_output_length; - *output_length += internal_output_length; - ctx->unprocessed_len = 0; - } - } - - while (input_length >= block_size) { - /* Run all full blocks we have, one by one */ - status = mbedtls_to_psa_error( - mbedtls_cipher_update(ctx, input, - block_size, - output, &internal_output_length)); - - if (status != PSA_SUCCESS) { - goto exit; - } - - input_length -= block_size; - input += block_size; - - output += internal_output_length; - *output_length += internal_output_length; - } - - if (input_length > 0) { - /* Save unprocessed bytes for later processing */ - memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), - input, input_length); - ctx->unprocessed_len += input_length; - } - - status = PSA_SUCCESS; - -exit: - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */ - -psa_status_t mbedtls_psa_cipher_update( - mbedtls_psa_cipher_operation_t *operation, - const uint8_t *input, size_t input_length, - uint8_t *output, size_t output_size, size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t expected_output_size; - - if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) { - /* Take the unprocessed partial block left over from previous - * update calls, if any, plus the input to this call. Remove - * the last partial block, if any. You get the data that will be - * output in this call. */ - expected_output_size = - (operation->ctx.cipher.unprocessed_len + input_length) - / operation->block_length * operation->block_length; - } else { - expected_output_size = input_length; - } - - if (output_size < expected_output_size) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) - if (operation->alg == PSA_ALG_ECB_NO_PADDING) { - /* mbedtls_cipher_update has an API inconsistency: it will only - * process a single block at a time in ECB mode. Abstract away that - * inconsistency here to match the PSA API behaviour. */ - status = psa_cipher_update_ecb(&operation->ctx.cipher, - input, - input_length, - output, - output_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */ - if (input_length == 0) { - /* There is no input, nothing to be done */ - *output_length = 0; - status = PSA_SUCCESS; - } else { - status = mbedtls_to_psa_error( - mbedtls_cipher_update(&operation->ctx.cipher, input, - input_length, output, output_length)); - - if (*output_length > output_size) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - } - - return status; -} - -psa_status_t mbedtls_psa_cipher_finish( - mbedtls_psa_cipher_operation_t *operation, - uint8_t *output, size_t output_size, size_t *output_length) -{ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; - size_t invalid_padding = 0; - - /* We will copy output_size bytes from temp_output_buffer to the - * output buffer. We can't use *output_length to determine how - * much to copy because we must not leak that value through timing - * when doing decryption with unpadding. But the underlying function - * is not guaranteed to write beyond *output_length. To ensure we don't - * leak the former content of the stack to the caller, wipe that - * former content. */ - uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH] = { 0 }; - if (output_size > sizeof(temp_output_buffer)) { - output_size = sizeof(temp_output_buffer); - } - - if (operation->ctx.cipher.unprocessed_len != 0) { - if (operation->alg == PSA_ALG_ECB_NO_PADDING || - operation->alg == PSA_ALG_CBC_NO_PADDING) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - } - - status = mbedtls_to_psa_error( - mbedtls_cipher_finish_padded(&operation->ctx.cipher, - temp_output_buffer, - output_length, - &invalid_padding)); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (output_size == 0) { - ; /* Nothing to copy. Note that output may be NULL in this case. */ - } else { - /* Do not use the value of *output_length to determine how much - * to copy. When decrypting a padded cipher, the output length is - * sensitive, and leaking it could allow a padding oracle attack. */ - memcpy(output, temp_output_buffer, output_size); - } - - status = mbedtls_ct_error_if_else_0(invalid_padding, - PSA_ERROR_INVALID_PADDING); - mbedtls_ct_condition_t buffer_too_small = - mbedtls_ct_uint_lt(output_size, *output_length); - status = mbedtls_ct_error_if(buffer_too_small, - PSA_ERROR_BUFFER_TOO_SMALL, - status); - -exit: - mbedtls_platform_zeroize(temp_output_buffer, - sizeof(temp_output_buffer)); - return status; -} - -psa_status_t mbedtls_psa_cipher_abort( - mbedtls_psa_cipher_operation_t *operation) -{ - /* Sanity check (shouldn't happen: operation->alg should - * always have been initialized to a valid value). */ - if (!PSA_ALG_IS_CIPHER(operation->alg)) { - return PSA_ERROR_BAD_STATE; - } - - mbedtls_cipher_free(&operation->ctx.cipher); - - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_cipher_encrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *iv, - size_t iv_length, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT; - size_t update_output_length, finish_output_length; - - status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes, - key_buffer, key_buffer_size, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (iv_length > 0) { - status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - status = mbedtls_psa_cipher_update(&operation, input, input_length, - output, output_size, - &update_output_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = mbedtls_psa_cipher_finish( - &operation, - mbedtls_buffer_offset(output, update_output_length), - output_size - update_output_length, &finish_output_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - *output_length = update_output_length + finish_output_length; - -exit: - if (status == PSA_SUCCESS) { - status = mbedtls_psa_cipher_abort(&operation); - } else { - mbedtls_psa_cipher_abort(&operation); - } - - return status; -} - -psa_status_t mbedtls_psa_cipher_decrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT; - size_t olength, accumulated_length; - - status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes, - key_buffer, key_buffer_size, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (operation.iv_length > 0) { - status = mbedtls_psa_cipher_set_iv(&operation, - input, operation.iv_length); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - status = mbedtls_psa_cipher_update( - &operation, - mbedtls_buffer_offset_const(input, operation.iv_length), - input_length - operation.iv_length, - output, output_size, &olength); - if (status != PSA_SUCCESS) { - goto exit; - } - - accumulated_length = olength; - - status = mbedtls_psa_cipher_finish( - &operation, - mbedtls_buffer_offset(output, accumulated_length), - output_size - accumulated_length, &olength); - - *output_length = accumulated_length + olength; - -exit: - /* C99 doesn't allow a declaration to follow a label */; - psa_status_t abort_status = mbedtls_psa_cipher_abort(&operation); - /* Normally abort shouldn't fail unless the operation is in a bad - * state, in which case we'd expect finish to fail with the same error. - * So it doesn't matter much which call's error code we pick when both - * fail. However, in unauthenticated decryption specifically, the - * distinction between PSA_SUCCESS and PSA_ERROR_INVALID_PADDING is - * security-sensitive (risk of a padding oracle attack), so here we - * must not have a code path that depends on the value of status. */ - if (abort_status != PSA_SUCCESS) { - status = abort_status; - } - - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_cipher.h b/vendor/mbedtls/library/psa_crypto_cipher.h deleted file mode 100644 index cc565851c..000000000 --- a/vendor/mbedtls/library/psa_crypto_cipher.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * PSA cipher driver entry points and associated auxiliary functions - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_CIPHER_H -#define PSA_CRYPTO_CIPHER_H - -#include -#include - -/** Get Mbed TLS cipher information given the cipher algorithm PSA identifier - * as well as the PSA type and size of the key to be used with the cipher - * algorithm. - * - * \param[in] alg PSA cipher algorithm identifier - * \param[in] key_type PSA key type - * \param[in,out] key_bits Size of the key in bits. The value provided in input - * might be updated if necessary. - * \param[out] mode Mbed TLS cipher mode - * \param[out] cipher_id Mbed TLS cipher algorithm identifier - * - * \return On success \c PSA_SUCCESS is returned and key_bits, mode and cipher_id - * are properly updated. - * \c PSA_ERROR_NOT_SUPPORTED is returned if the cipher algorithm is not - * supported. - */ - -psa_status_t mbedtls_cipher_values_from_psa(psa_algorithm_t alg, psa_key_type_t key_type, - size_t *key_bits, mbedtls_cipher_mode_t *mode, - mbedtls_cipher_id_t *cipher_id); - -#if defined(MBEDTLS_CIPHER_C) -/** Get Mbed TLS cipher information given the cipher algorithm PSA identifier - * as well as the PSA type and size of the key to be used with the cipher - * algorithm. - * - * \param alg PSA cipher algorithm identifier - * \param key_type PSA key type - * \param key_bits Size of the key in bits - * \param[out] cipher_id Mbed TLS cipher algorithm identifier - * - * \return The Mbed TLS cipher information of the cipher algorithm. - * \c NULL if the PSA cipher algorithm is not supported. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( - psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits, - mbedtls_cipher_id_t *cipher_id); -#endif /* MBEDTLS_CIPHER_C */ - -/** - * \brief Set the key for a multipart symmetric encryption operation. - * - * \note The signature of this function is that of a PSA driver - * cipher_encrypt_setup entry point. This function behaves as a - * cipher_encrypt_setup entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in,out] operation The operation object to set up. It has been - * initialized as per the documentation for - * #psa_cipher_operation_t and not yet in use. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_cipher_encrypt_setup( - mbedtls_psa_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg); - -/** - * \brief Set the key for a multipart symmetric decryption operation. - * - * \note The signature of this function is that of a PSA driver - * cipher_decrypt_setup entry point. This function behaves as a - * cipher_decrypt_setup entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in,out] operation The operation object to set up. It has been - * initialized as per the documentation for - * #psa_cipher_operation_t and not yet in use. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_cipher_decrypt_setup( - mbedtls_psa_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg); - -/** Set the IV for a symmetric encryption or decryption operation. - * - * This function sets the IV (initialization vector), nonce - * or initial counter value for the encryption or decryption operation. - * - * \note The signature of this function is that of a PSA driver - * cipher_set_iv entry point. This function behaves as a - * cipher_set_iv entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in,out] operation Active cipher operation. - * \param[in] iv Buffer containing the IV to use. - * \param[in] iv_length Size of the IV in bytes. It is guaranteed by - * the core to be less or equal to - * PSA_CIPHER_IV_MAX_SIZE. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size of \p iv is not acceptable for the chosen algorithm, - * or the chosen algorithm does not use an IV. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_cipher_set_iv( - mbedtls_psa_cipher_operation_t *operation, - const uint8_t *iv, size_t iv_length); - -/** Encrypt or decrypt a message fragment in an active cipher operation. - * - * \note The signature of this function is that of a PSA driver - * cipher_update entry point. This function behaves as a - * cipher_update entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in,out] operation Active cipher operation. - * \param[in] input Buffer containing the message fragment to - * encrypt or decrypt. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * \param[in] output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_cipher_update( - mbedtls_psa_cipher_operation_t *operation, - const uint8_t *input, size_t input_length, - uint8_t *output, size_t output_size, size_t *output_length); - -/** Finish encrypting or decrypting a message in a cipher operation. - * - * \note The signature of this function is that of a PSA driver - * cipher_finish entry point. This function behaves as a - * cipher_finish entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in,out] operation Active cipher operation. - * \param[out] output Buffer where the output is to be written. - * \param[in] output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total input size passed to this operation is not valid for - * this particular algorithm. For example, the algorithm is a based - * on block cipher and requires a whole number of blocks, but the - * total input size is not a multiple of the block size. - * \retval #PSA_ERROR_INVALID_PADDING - * This is a decryption operation for an algorithm that includes - * padding, and the ciphertext does not contain valid padding. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_cipher_finish( - mbedtls_psa_cipher_operation_t *operation, - uint8_t *output, size_t output_size, size_t *output_length); - -/** Abort a cipher operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation. - * - * \note The signature of this function is that of a PSA driver - * cipher_abort entry point. This function behaves as a - * cipher_abort entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in,out] operation Initialized cipher operation. - * - * \retval #PSA_SUCCESS \emptydescription - */ -psa_status_t mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t *operation); - -/** Encrypt a message using a symmetric cipher. - * - * \note The signature of this function is that of a PSA driver - * cipher_encrypt entry point. This function behaves as a - * cipher_encrypt entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param[in] iv Buffer containing the IV for encryption. The - * IV has been generated by the core. - * \param[in] iv_length Size of the \p iv in bytes. - * \param[in] input Buffer containing the message to encrypt. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[in,out] output Buffer where the output is to be written. - * \param[in] output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes that make up - * the returned output. Initialized to zero - * by the core. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size \p iv_length is not acceptable for the chosen algorithm, - * or the chosen algorithm does not use an IV. - * The total input size passed to this operation is not valid for - * this particular algorithm. For example, the algorithm is a based - * on block cipher and requires a whole number of blocks, but the - * total input size is not a multiple of the block size. - * \retval #PSA_ERROR_INVALID_PADDING - * This is a decryption operation for an algorithm that includes - * padding, and the ciphertext does not contain valid padding. - */ -psa_status_t mbedtls_psa_cipher_encrypt(const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *iv, - size_t iv_length, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Decrypt a message using a symmetric cipher. - * - * \note The signature of this function is that of a PSA driver - * cipher_decrypt entry point. This function behaves as a - * cipher_decrypt entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param[in] input Buffer containing the iv and the ciphertext. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * \param[in] output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes that make up - * the returned output. Initialized to zero - * by the core. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size of \p iv is not acceptable for the chosen algorithm, - * or the chosen algorithm does not use an IV. - * The total input size passed to this operation is not valid for - * this particular algorithm. For example, the algorithm is a based - * on block cipher and requires a whole number of blocks, but the - * total input size is not a multiple of the block size. - * \retval #PSA_ERROR_INVALID_PADDING - * This is a decryption operation for an algorithm that includes - * padding, and the ciphertext does not contain valid padding. - */ -psa_status_t mbedtls_psa_cipher_decrypt(const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -#endif /* PSA_CRYPTO_CIPHER_H */ diff --git a/vendor/mbedtls/library/psa_crypto_client.c b/vendor/mbedtls/library/psa_crypto_client.c deleted file mode 100644 index 72f671d63..000000000 --- a/vendor/mbedtls/library/psa_crypto_client.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * PSA crypto client code - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" -#include "psa/crypto.h" - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) - -#include -#include "mbedtls/platform.h" - -void psa_reset_key_attributes(psa_key_attributes_t *attributes) -{ - memset(attributes, 0, sizeof(*attributes)); -} - -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ diff --git a/vendor/mbedtls/library/psa_crypto_core.h b/vendor/mbedtls/library/psa_crypto_core.h deleted file mode 100644 index ac92ea2b3..000000000 --- a/vendor/mbedtls/library/psa_crypto_core.h +++ /dev/null @@ -1,983 +0,0 @@ -/* - * PSA crypto core internal interfaces - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_CORE_H -#define PSA_CRYPTO_CORE_H - -/* - * Include the build-time configuration information header. Here, we do not - * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which - * is basically just an alias to it. This is to ease the maintenance of the - * TF-PSA-Crypto repository which has a different build system and - * configuration. - */ -#include "psa/build_info.h" - -#include "psa/crypto.h" -#include "psa/crypto_se_driver.h" -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -typedef enum { - PSA_SLOT_EMPTY = 0, - PSA_SLOT_FILLING, - PSA_SLOT_FULL, - PSA_SLOT_PENDING_DELETION, -} psa_key_slot_state_t; - -/** The data structure representing a key slot, containing key material - * and metadata for one key. - */ -typedef struct { - /* This field is accessed in a lot of places. Putting it first - * reduces the code size. */ - psa_key_attributes_t attr; - - /* - * The current state of the key slot, as described in - * docs/architecture/psa-thread-safety/psa-thread-safety.md. - * - * Library functions can modify the state of a key slot by calling - * psa_key_slot_state_transition. - * - * The state variable is used to help determine whether library functions - * which operate on the slot succeed. For example, psa_finish_key_creation, - * which transfers the state of a slot from PSA_SLOT_FILLING to - * PSA_SLOT_FULL, must fail with error code PSA_ERROR_CORRUPTION_DETECTED - * if the state of the slot is not PSA_SLOT_FILLING. - * - * Library functions which traverse the array of key slots only consider - * slots that are in a suitable state for the function. - * For example, psa_get_and_lock_key_slot_in_memory, which finds a slot - * containing a given key ID, will only check slots whose state variable is - * PSA_SLOT_FULL. - */ - psa_key_slot_state_t state; - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - /* The index of the slice containing this slot. - * This field must be filled if the slot contains a key - * (including keys being created or destroyed), and can be either - * filled or 0 when the slot is free. - * - * In most cases, the slice index can be deduced from the key identifer. - * We keep it in a separate field for robustness (it reduces the chance - * that a coding mistake in the key store will result in accessing the - * wrong slice), and also so that it's available even on code paths - * during creation or destruction where the key identifier might not be - * filled in. - * */ - uint8_t slice_index; -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - union { - struct { - /* The index of the next slot in the free list for this - * slice, relative * to the next array element. - * - * That is, 0 means the next slot, 1 means the next slot - * but one, etc. -1 would mean the slot itself. -2 means - * the previous slot, etc. - * - * If this is beyond the array length, the free list ends with the - * current element. - * - * The reason for this strange encoding is that 0 means the next - * element. This way, when we allocate a slice and initialize it - * to all-zero, the slice is ready for use, with a free list that - * consists of all the slots in order. - */ - int32_t next_free_relative_to_next; - } free; - - struct { - /* - * Number of functions registered as reading the material in the key slot. - * - * Library functions must not write directly to registered_readers - * - * A function must call psa_register_read(slot) before reading - * the current contents of the slot for an operation. - * They then must call psa_unregister_read(slot) once they have - * finished reading the current contents of the slot. If the key - * slot mutex is not held (when mutexes are enabled), this call - * must be done via a call to - * psa_unregister_read_under_mutex(slot). - * A function must call psa_key_slot_has_readers(slot) to check if - * the slot is in use for reading. - * - * This counter is used to prevent resetting the key slot while - * the library may access it. For example, such control is needed - * in the following scenarios: - * . In case of key slot starvation, all key slots contain the - * description of a key, and the library asks for the - * description of a persistent key not present in the - * key slots, the key slots currently accessed by the - * library cannot be reclaimed to free a key slot to load - * the persistent key. - * . In case of a multi-threaded application where one thread - * asks to close or purge or destroy a key while it is in use - * by the library through another thread. */ - size_t registered_readers; - } occupied; - } var; - - /* Dynamically allocated key data buffer. - * Format as specified in psa_export_key(). */ - struct key_data { -#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) - uint8_t data[MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE]; -#else - uint8_t *data; -#endif - size_t bytes; - } key; -} psa_key_slot_t; - -#if defined(MBEDTLS_THREADING_C) - -/** Perform a mutex operation and return immediately upon failure. - * - * Returns PSA_ERROR_SERVICE_FAILURE if the operation fails - * and status was PSA_SUCCESS. - * - * Assumptions: - * psa_status_t status exists. - * f is a mutex operation which returns 0 upon success. - */ -#define PSA_THREADING_CHK_RET(f) \ - do \ - { \ - if ((f) != 0) { \ - if (status == PSA_SUCCESS) { \ - return PSA_ERROR_SERVICE_FAILURE; \ - } \ - return status; \ - } \ - } while (0); - -/** Perform a mutex operation and goto exit on failure. - * - * Sets status to PSA_ERROR_SERVICE_FAILURE if status was PSA_SUCCESS. - * - * Assumptions: - * psa_status_t status exists. - * Label exit: exists. - * f is a mutex operation which returns 0 upon success. - */ -#define PSA_THREADING_CHK_GOTO_EXIT(f) \ - do \ - { \ - if ((f) != 0) { \ - if (status == PSA_SUCCESS) { \ - status = PSA_ERROR_SERVICE_FAILURE; \ - } \ - goto exit; \ - } \ - } while (0); -#endif - -/** Test whether a key slot has any registered readers. - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \param[in] slot The key slot to test. - * - * \return 1 if the slot has any registered readers, 0 otherwise. - */ -static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot) -{ - return slot->var.occupied.registered_readers > 0; -} - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -/** Get the SE slot number of a key from the key slot storing its description. - * - * \param[in] slot The key slot to query. This must be a key slot storing - * the description of a key of a dynamically registered - * secure element, otherwise the behaviour is undefined. - */ -static inline psa_key_slot_number_t psa_key_slot_get_slot_number( - const psa_key_slot_t *slot) -{ - return *((psa_key_slot_number_t *) (slot->key.data)); -} -#endif - -/** Completely wipe a slot in memory, including its policy. - * - * Persistent storage is not affected. - * Sets the slot's state to PSA_SLOT_EMPTY. - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \param[in,out] slot The key slot to wipe. - * - * \retval #PSA_SUCCESS - * The slot has been successfully wiped. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The slot's state was PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION, and - * the amount of registered readers was not equal to 1. Or, - * the slot's state was PSA_SLOT_EMPTY. Or, - * the slot's state was PSA_SLOT_FILLING, and the amount - * of registered readers was not equal to 0. - */ -psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot); - -/** Try to allocate a buffer to an empty key slot. - * - * \param[in,out] slot Key slot to attach buffer to. - * \param[in] buffer_length Requested size of the buffer. - * - * \retval #PSA_SUCCESS - * The buffer has been successfully allocated. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * Not enough memory was available for allocation. - * \retval #PSA_ERROR_ALREADY_EXISTS - * Trying to allocate a buffer to a non-empty key slot. - */ -psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot, - size_t buffer_length); - -/** Wipe key data from a slot. Preserves metadata such as the policy. */ -psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot); - -/** Copy key data (in export format) into an empty key slot. - * - * This function assumes that the slot does not contain - * any key material yet. On failure, the slot content is unchanged. - * - * \param[in,out] slot Key slot to copy the key into. - * \param[in] data Buffer containing the key material. - * \param data_length Size of the key buffer. - * - * \retval #PSA_SUCCESS - * The key has been copied successfully. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * Not enough memory was available for allocation of the - * copy buffer. - * \retval #PSA_ERROR_ALREADY_EXISTS - * There was other key material already present in the slot. - */ -psa_status_t psa_copy_key_material_into_slot(psa_key_slot_t *slot, - const uint8_t *data, - size_t data_length); - -/** Convert an Mbed TLS error code to a PSA error code - * - * \note This function is provided solely for the convenience of - * Mbed TLS and may be removed at any time without notice. - * - * \param ret An Mbed TLS-thrown error code - * - * \return The corresponding PSA error code - */ -psa_status_t mbedtls_to_psa_error(int ret); - -/** Import a key in binary format. - * - * \note The signature of this function is that of a PSA driver - * import_key entry point. This function behaves as an import_key - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes for the key to import. - * \param[in] data The buffer containing the key data in import - * format. - * \param[in] data_length Size of the \p data buffer in bytes. - * \param[out] key_buffer The buffer to contain the key data in output - * format upon successful return. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This - * size is greater or equal to \p data_length. - * \param[out] key_buffer_length The length of the data written in \p - * key_buffer in bytes. - * \param[out] bits The key size in number of bits. - * - * \retval #PSA_SUCCESS The key was imported successfully. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key data is not correctly formatted. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t psa_import_key_into_slot( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits); - -/** Export a key in binary format - * - * \note The signature of this function is that of a PSA driver export_key - * entry point. This function behaves as an export_key entry point as - * defined in the PSA driver interface specification. - * - * \param[in] attributes The attributes for the key to export. - * \param[in] key_buffer Material or context of the key to export. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[out] data Buffer where the key data is to be written. - * \param[in] data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes written in - * \p data - * - * \retval #PSA_SUCCESS The key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t psa_export_key_internal( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length); - -/** Export a public key or the public part of a key pair in binary format. - * - * \note The signature of this function is that of a PSA driver - * export_public_key entry point. This function behaves as an - * export_public_key entry point as defined in the PSA driver interface - * specification. - * - * \param[in] attributes The attributes for the key to export. - * \param[in] key_buffer Material or context of the key to export. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[out] data Buffer where the key data is to be written. - * \param[in] data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes written in - * \p data - * - * \retval #PSA_SUCCESS The public key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t psa_export_public_key_internal( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length); - -/** Whether a key custom production parameters structure is the default. - * - * Calls to a key generation driver with non-default custom production parameters - * require a driver supporting custom production parameters. - * - * \param[in] custom The key custom production parameters to check. - * \param custom_data_length Size of the associated variable-length data - * in bytes. - */ -int psa_custom_key_parameters_are_default( - const psa_custom_key_parameters_t *custom, - size_t custom_data_length); - -/** - * \brief Generate a key. - * - * \note The signature of the function is that of a PSA driver generate_key - * entry point. - * - * \param[in] attributes The attributes for the key to generate. - * \param[in] custom Custom parameters for the key generation. - * \param[in] custom_data Variable-length data associated with \c custom. - * \param custom_data_length Length of `custom_data` in bytes. - * \param[out] key_buffer Buffer where the key data is to be written. - * \param[in] key_buffer_size Size of \p key_buffer in bytes. - * \param[out] key_buffer_length On success, the number of bytes written in - * \p key_buffer. - * - * \retval #PSA_SUCCESS - * The key was generated successfully. - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED - * Key size in bits or type not supported. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of \p key_buffer is too small. - */ -psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes, - const psa_custom_key_parameters_t *custom, - const uint8_t *custom_data, - size_t custom_data_length, - uint8_t *key_buffer, - size_t key_buffer_size, - size_t *key_buffer_length); - -/** Sign a message with a private key. For hash-and-sign algorithms, - * this includes the hashing step. - * - * \note The signature of this function is that of a PSA driver - * sign_message entry point. This function behaves as a sign_message - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \note This function will call the driver for psa_sign_hash - * and go through driver dispatch again. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * the type of the key. - * \param[in] input The input message to sign. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param[in] signature_size Size of the \p signature buffer in bytes. - * \param[out] signature_length On success, the number of bytes - * that make up the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of the key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - */ -psa_status_t psa_sign_message_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *input, size_t input_length, - uint8_t *signature, size_t signature_size, size_t *signature_length); - -/** Verify the signature of a message with a public key, using - * a hash-and-sign verification algorithm. - * - * \note The signature of this function is that of a PSA driver - * verify_message entry point. This function behaves as a verify_message - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \note This function will call the driver for psa_verify_hash - * and go through driver dispatch again. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * the type of the key. - * \param[in] input The message whose signature is to be verified. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param[in] signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The signature is valid. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t psa_verify_message_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *input, size_t input_length, - const uint8_t *signature, size_t signature_length); - -/** Sign an already-calculated hash with a private key. - * - * \note The signature of this function is that of a PSA driver - * sign_hash entry point. This function behaves as a sign_hash - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * the type of the key. - * \param[in] hash The hash or message to sign. - * \param[in] hash_length Size of the \p hash buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param[in] signature_size Size of the \p signature buffer in bytes. - * \param[out] signature_length On success, the number of bytes - * that make up the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of the key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - */ -psa_status_t psa_sign_hash_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - uint8_t *signature, size_t signature_size, size_t *signature_length); - -/** - * \brief Verify the signature a hash or short message using a public key. - * - * \note The signature of this function is that of a PSA driver - * verify_hash entry point. This function behaves as a verify_hash - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * the type of the key. - * \param[in] hash The hash or message whose signature is to be - * verified. - * \param[in] hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param[in] signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The signature is valid. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t psa_verify_hash_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length); - -/** - * \brief Validate the key bit size for unstructured keys. - * - * \note Check that the bit size is acceptable for a given key type for - * unstructured keys. - * - * \param[in] type The key type - * \param[in] bits The number of bits of the key - * - * \retval #PSA_SUCCESS - * The key type and size are valid. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size in bits of the key is not valid. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The type and/or the size in bits of the key or the combination of - * the two is not supported. - */ -psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type, - size_t bits); - -/** Perform a key agreement and return the raw shared secret, using - built-in raw key agreement functions. - * - * \note The signature of this function is that of a PSA driver - * key_agreement entry point. This function behaves as a key_agreement - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the private key - * context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in - * bytes. - * \param[in] alg A key agreement algorithm that is - * compatible with the type of the key. - * \param[in] peer_key The buffer containing the key context - * of the peer's public key. - * \param[in] peer_key_length Size of the \p peer_key buffer in - * bytes. - * \param[out] shared_secret The buffer to which the shared secret - * is to be written. - * \param[in] shared_secret_size Size of the \p shared_secret buffer in - * bytes. - * \param[out] shared_secret_length On success, the number of bytes that make - * up the returned shared secret. - * \retval #PSA_SUCCESS - * Success. Shared secret successfully calculated. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p alg is not a key agreement algorithm, or - * \p private_key is not compatible with \p alg, - * or \p peer_key is not valid for \p alg or not compatible with - * \p private_key. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p shared_secret_size is too small - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not a supported key agreement algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE \emptydescription - */ -psa_status_t psa_key_agreement_raw_builtin( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *peer_key, - size_t peer_key_length, - uint8_t *shared_secret, - size_t shared_secret_size, - size_t *shared_secret_length); - -/** - * \brief Set the maximum number of ops allowed to be executed by an - * interruptible function in a single call. - * - * \note The signature of this function is that of a PSA driver - * interruptible_set_max_ops entry point. This function behaves as an - * interruptible_set_max_ops entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in] max_ops The maximum number of ops to be executed in a - * single call, this can be a number from 0 to - * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0 - * is obviously the least amount of work done per - * call. - */ -void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops); - -/** - * \brief Get the maximum number of ops allowed to be executed by an - * interruptible function in a single call. - * - * \note The signature of this function is that of a PSA driver - * interruptible_get_max_ops entry point. This function behaves as an - * interruptible_get_max_ops entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \return Maximum number of ops allowed to be executed - * by an interruptible function in a single call. - */ -uint32_t mbedtls_psa_interruptible_get_max_ops(void); - -/** - * \brief Get the number of ops that a hash signing operation has taken for the - * previous call. If no call or work has taken place, this will return - * zero. - * - * \note The signature of this function is that of a PSA driver - * sign_hash_get_num_ops entry point. This function behaves as an - * sign_hash_get_num_ops entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param operation The \c - * mbedtls_psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \return Number of ops that were completed - * in the last call to \c - * mbedtls_psa_sign_hash_complete(). - */ -uint32_t mbedtls_psa_sign_hash_get_num_ops( - const mbedtls_psa_sign_hash_interruptible_operation_t *operation); - -/** - * \brief Get the number of ops that a hash verification operation has taken for - * the previous call. If no call or work has taken place, this will - * return zero. - * - * \note The signature of this function is that of a PSA driver - * verify_hash_get_num_ops entry point. This function behaves as an - * verify_hash_get_num_ops entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param operation The \c - * mbedtls_psa_verify_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \return Number of ops that were completed - * in the last call to \c - * mbedtls_psa_verify_hash_complete(). - */ -uint32_t mbedtls_psa_verify_hash_get_num_ops( - const mbedtls_psa_verify_hash_interruptible_operation_t *operation); - -/** - * \brief Start signing a hash or short message with a private key, in an - * interruptible manner. - * - * \note The signature of this function is that of a PSA driver - * sign_hash_start entry point. This function behaves as a - * sign_hash_start entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * \param[in] operation The \c - * mbedtls_psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * the type of the key. - * \param[in] hash The hash or message to sign. - * \param hash_length Size of the \p hash buffer in bytes. - * - * \retval #PSA_SUCCESS - * The operation started successfully - call \c psa_sign_hash_complete() - * with the same context to complete the operation - * \retval #PSA_ERROR_INVALID_ARGUMENT - * An unsupported, incorrectly formatted or incorrect type of key was - * used. - * \retval #PSA_ERROR_NOT_SUPPORTED Either no internal interruptible operations - * are currently supported, or the key type is currently unsupported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * There was insufficient memory to load the key representation. - */ -psa_status_t mbedtls_psa_sign_hash_start( - mbedtls_psa_sign_hash_interruptible_operation_t *operation, - const psa_key_attributes_t *attributes, const uint8_t *key_buffer, - size_t key_buffer_size, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length); - -/** - * \brief Continue and eventually complete the action of signing a hash or - * short message with a private key, in an interruptible manner. - * - * \note The signature of this function is that of a PSA driver - * sign_hash_complete entry point. This function behaves as a - * sign_hash_complete entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * \param[in] operation The \c - * mbedtls_psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \param[out] signature Buffer where the signature is to be written. - * \param signature_size Size of the \p signature buffer in bytes. This - * must be appropriate for the selected - * algorithm and key. - * \param[out] signature_length On success, the number of bytes that make up - * the returned signature value. - * - * \retval #PSA_SUCCESS - * Operation completed successfully - * - * \retval #PSA_OPERATION_INCOMPLETE - * Operation was interrupted due to the setting of \c - * psa_interruptible_set_max_ops(), there is still work to be done, - * please call this function again with the same operation object. - * - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - */ -psa_status_t mbedtls_psa_sign_hash_complete( - mbedtls_psa_sign_hash_interruptible_operation_t *operation, - uint8_t *signature, size_t signature_size, - size_t *signature_length); - -/** - * \brief Abort a sign hash operation. - * - * \note The signature of this function is that of a PSA driver sign_hash_abort - * entry point. This function behaves as a sign_hash_abort entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * \param[in] operation The \c - * mbedtls_psa_sign_hash_interruptible_operation_t - * to abort. - * - * \retval #PSA_SUCCESS - * The operation was aborted successfully. - */ -psa_status_t mbedtls_psa_sign_hash_abort( - mbedtls_psa_sign_hash_interruptible_operation_t *operation); - -/** - * \brief Start reading and verifying a hash or short message, in an - * interruptible manner. - * - * \note The signature of this function is that of a PSA driver - * verify_hash_start entry point. This function behaves as a - * verify_hash_start entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * \param[in] operation The \c - * mbedtls_psa_verify_hash_interruptible_operation_t - * to use. This must be initialized first. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * the type of the key. - * \param[in] hash The hash whose signature is to be verified. - * \param hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The operation started successfully - call \c psa_sign_hash_complete() - * with the same context to complete the operation - * \retval #PSA_ERROR_INVALID_ARGUMENT - * An unsupported or incorrect type of key was used. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Either no internal interruptible operations are currently supported, - * or the key type is currently unsupported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * There was insufficient memory either to load the key representation, - * or to prepare the operation. - */ -psa_status_t mbedtls_psa_verify_hash_start( - mbedtls_psa_verify_hash_interruptible_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length); - -/** - * \brief Continue and eventually complete the action of signing a hash or - * short message with a private key, in an interruptible manner. - * - * \note The signature of this function is that of a PSA driver - * sign_hash_complete entry point. This function behaves as a - * sign_hash_complete entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * \param[in] operation The \c - * mbedtls_psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \retval #PSA_SUCCESS - * Operation completed successfully, and the passed signature is valid. - * - * \retval #PSA_OPERATION_INCOMPLETE - * Operation was interrupted due to the setting of \c - * psa_interruptible_set_max_ops(), there is still work to be done, - * please call this function again with the same operation object. - * - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_verify_hash_complete( - mbedtls_psa_verify_hash_interruptible_operation_t *operation); - -/** - * \brief Abort a verify signed hash operation. - * - * \note The signature of this function is that of a PSA driver - * verify_hash_abort entry point. This function behaves as a - * verify_hash_abort entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * \param[in] operation The \c - * mbedtls_psa_verify_hash_interruptible_operation_t - * to abort. - * - * \retval #PSA_SUCCESS - * The operation was aborted successfully. - */ -psa_status_t mbedtls_psa_verify_hash_abort( - mbedtls_psa_verify_hash_interruptible_operation_t *operation); - -typedef struct psa_crypto_local_input_s { - uint8_t *buffer; - size_t length; -} psa_crypto_local_input_t; - -#define PSA_CRYPTO_LOCAL_INPUT_INIT ((psa_crypto_local_input_t) { NULL, 0 }) - -/** Allocate a local copy of an input buffer and copy the contents into it. - * - * \param[in] input Pointer to input buffer. - * \param[in] input_len Length of the input buffer. - * \param[out] local_input Pointer to a psa_crypto_local_input_t struct - * containing a local input copy. - * \return #PSA_SUCCESS, if the buffer was successfully - * copied. - * \return #PSA_ERROR_INSUFFICIENT_MEMORY, if a copy of - * the buffer cannot be allocated. - */ -psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len, - psa_crypto_local_input_t *local_input); - -/** Free a local copy of an input buffer. - * - * \param[in] local_input Pointer to a psa_crypto_local_input_t struct - * populated by a previous call to - * psa_crypto_local_input_alloc(). - */ -void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input); - -typedef struct psa_crypto_local_output_s { - uint8_t *original; - uint8_t *buffer; - size_t length; -} psa_crypto_local_output_t; - -#define PSA_CRYPTO_LOCAL_OUTPUT_INIT ((psa_crypto_local_output_t) { NULL, NULL, 0 }) - -/** Allocate a local copy of an output buffer. - * - * \note This does not copy any data from the original - * output buffer but only allocates a buffer - * whose contents will be copied back to the - * original in a future call to - * psa_crypto_local_output_free(). - * - * \param[in] output Pointer to output buffer. - * \param[in] output_len Length of the output buffer. - * \param[out] local_output Pointer to a psa_crypto_local_output_t struct to - * populate with the local output copy. - * \return #PSA_SUCCESS, if the buffer was successfully - * copied. - * \return #PSA_ERROR_INSUFFICIENT_MEMORY, if a copy of - * the buffer cannot be allocated. - */ -psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, - psa_crypto_local_output_t *local_output); - -/** Copy from a local copy of an output buffer back to the original, then - * free the local copy. - * - * \param[in] local_output Pointer to a psa_crypto_local_output_t struct - * populated by a previous call to - * psa_crypto_local_output_alloc(). - * \return #PSA_SUCCESS, if the local output was - * successfully copied back to the original. - * \return #PSA_ERROR_CORRUPTION_DETECTED, if the output - * could not be copied back to the original. - */ -psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output); - -#endif /* PSA_CRYPTO_CORE_H */ diff --git a/vendor/mbedtls/library/psa_crypto_core_common.h b/vendor/mbedtls/library/psa_crypto_core_common.h deleted file mode 100644 index 98fce2cca..000000000 --- a/vendor/mbedtls/library/psa_crypto_core_common.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * \file psa_crypto_core_common.h - * - * \brief Utility macros for internal use in the PSA cryptography core. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_CORE_COMMON_H -#define PSA_CRYPTO_CORE_COMMON_H - -/** Return an offset into a buffer. - * - * This is just the addition of an offset to a pointer, except that this - * function also accepts an offset of 0 into a buffer whose pointer is null. - * (`p + n` has undefined behavior when `p` is null, even when `n == 0`. - * A null pointer is a valid buffer pointer when the size is 0, for example - * as the result of `malloc(0)` on some platforms.) - * - * \param p Pointer to a buffer of at least n bytes. - * This may be \p NULL if \p n is zero. - * \param n An offset in bytes. - * \return Pointer to offset \p n in the buffer \p p. - * Note that this is only a valid pointer if the size of the - * buffer is at least \p n + 1. - */ -static inline unsigned char *psa_crypto_buffer_offset( - unsigned char *p, size_t n) -{ - return p == NULL ? NULL : p + n; -} - -/** Return an offset into a read-only buffer. - * - * Similar to mbedtls_buffer_offset(), but for const pointers. - * - * \param p Pointer to a buffer of at least n bytes. - * This may be \p NULL if \p n is zero. - * \param n An offset in bytes. - * \return Pointer to offset \p n in the buffer \p p. - * Note that this is only a valid pointer if the size of the - * buffer is at least \p n + 1. - */ -static inline const unsigned char *psa_crypto_buffer_offset_const( - const unsigned char *p, size_t n) -{ - return p == NULL ? NULL : p + n; -} - -#endif /* PSA_CRYPTO_CORE_COMMON_H */ diff --git a/vendor/mbedtls/library/psa_crypto_driver_wrappers.h b/vendor/mbedtls/library/psa_crypto_driver_wrappers.h deleted file mode 100644 index 0ed221b50..000000000 --- a/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +++ /dev/null @@ -1,2896 +0,0 @@ -/* - * Functions to delegate cryptographic operations to an available - * and appropriate accelerator. - * Warning: This file is now auto-generated. - */ -/* Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - - -/* BEGIN-common headers */ -#include "common.h" -#include "psa_crypto_aead.h" -#include "psa_crypto_cipher.h" -#include "psa_crypto_core.h" -#include "psa_crypto_driver_wrappers_no_static.h" -#include "psa_crypto_hash.h" -#include "psa_crypto_mac.h" -#include "psa_crypto_pake.h" -#include "psa_crypto_rsa.h" - -#include "mbedtls/platform.h" -#include "mbedtls/constant_time.h" -/* END-common headers */ - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -/* BEGIN-driver headers */ -/* Headers for mbedtls_test opaque driver */ -#if defined(PSA_CRYPTO_DRIVER_TEST) -#include "test/drivers/test_driver.h" - -#endif -/* Headers for mbedtls_test transparent driver */ -#if defined(PSA_CRYPTO_DRIVER_TEST) -#include "test/drivers/test_driver.h" - -#endif -/* Headers for p256 transparent driver */ -#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) -#include "../3rdparty/p256-m/p256-m_driver_entrypoints.h" - -#endif - -/* END-driver headers */ - -/* Auto-generated values depending on which drivers are registered. - * ID 0 is reserved for unallocated operations. - * ID 1 is reserved for the Mbed TLS software driver. */ -/* BEGIN-driver id definition */ -#define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1) -#define MBEDTLS_TEST_OPAQUE_DRIVER_ID (2) -#define MBEDTLS_TEST_TRANSPARENT_DRIVER_ID (3) -#define P256_TRANSPARENT_DRIVER_ID (4) - -/* END-driver id */ - -/* BEGIN-Common Macro definitions */ - -/* END-Common Macro definitions */ - -/* Support the 'old' SE interface when asked to */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style - * SE driver is present, to avoid unused argument errors at compile time. */ -#ifndef PSA_CRYPTO_DRIVER_PRESENT -#define PSA_CRYPTO_DRIVER_PRESENT -#endif -#include "psa_crypto_se.h" -#endif - -static inline psa_status_t psa_driver_wrapper_init( void ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - status = psa_init_all_se_drivers( ); - if( status != PSA_SUCCESS ) - return( status ); -#endif - -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_init( ); - if( status != PSA_SUCCESS ) - return( status ); - - status = mbedtls_test_opaque_init( ); - if( status != PSA_SUCCESS ) - return( status ); -#endif - - (void) status; - return( PSA_SUCCESS ); -} - -static inline void psa_driver_wrapper_free( void ) -{ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* Unregister all secure element drivers, so that we restart from - * a pristine state. */ - psa_unregister_all_se_drivers( ); -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - -#if defined(PSA_CRYPTO_DRIVER_TEST) - mbedtls_test_transparent_free( ); - mbedtls_test_opaque_free( ); -#endif -} - -/* Start delegation functions */ -static inline psa_status_t psa_driver_wrapper_sign_message( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_signature_sign_message( - attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - signature, - signature_size, - signature_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - break; - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_test_opaque_signature_sign_message( - attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - signature, - signature_size, - signature_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); - break; -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - break; - } - - return( psa_sign_message_builtin( attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - signature, - signature_size, - signature_length ) ); -} - -static inline psa_status_t psa_driver_wrapper_verify_message( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *signature, - size_t signature_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_signature_verify_message( - attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - signature, - signature_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - break; - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_signature_verify_message( - attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - signature, - signature_length ) ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); - break; -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - break; - } - - return( psa_verify_message_builtin( attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - signature, - signature_length ) ); -} - -static inline psa_status_t psa_driver_wrapper_sign_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - uint8_t *signature, size_t signature_size, size_t *signature_length ) -{ - /* Try dynamically-registered SE interface first */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - - if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) - { - if( drv->asymmetric == NULL || - drv->asymmetric->p_sign == NULL ) - { - /* Key is defined in SE, but we have no way to exercise it */ - return( PSA_ERROR_NOT_SUPPORTED ); - } - return( drv->asymmetric->p_sign( - drv_context, *( (psa_key_slot_number_t *)key_buffer ), - alg, hash, hash_length, - signature, signature_size, signature_length ) ); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_signature_sign_hash( attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_size, - signature_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && - PSA_ALG_IS_RANDOMIZED_ECDSA(alg) && - PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && - psa_get_key_bits(attributes) == 256 ) - { - status = p256_transparent_sign_hash( attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_size, - signature_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); - } -#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - /* Fell through, meaning no accelerator supports this operation */ - return( psa_sign_hash_builtin( attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_size, - signature_length ) ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_signature_sign_hash( attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_size, - signature_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_verify_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length ) -{ - /* Try dynamically-registered SE interface first */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - - if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) - { - if( drv->asymmetric == NULL || - drv->asymmetric->p_verify == NULL ) - { - /* Key is defined in SE, but we have no way to exercise it */ - return( PSA_ERROR_NOT_SUPPORTED ); - } - return( drv->asymmetric->p_verify( - drv_context, *( (psa_key_slot_number_t *)key_buffer ), - alg, hash, hash_length, - signature, signature_length ) ); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_signature_verify_hash( - attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && - PSA_ALG_IS_ECDSA(alg) && - PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && - psa_get_key_bits(attributes) == 256 ) - { - status = p256_transparent_verify_hash( attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); - } -#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - return( psa_verify_hash_builtin( attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_length ) ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_signature_verify_hash( attributes, - key_buffer, - key_buffer_size, - alg, - hash, - hash_length, - signature, - signature_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline uint32_t psa_driver_wrapper_sign_hash_get_num_ops( - psa_sign_hash_interruptible_operation_t *operation ) -{ - switch( operation->id ) - { - /* If uninitialised, return 0, as no work can have been done. */ - case 0: - return 0; - - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return(mbedtls_psa_sign_hash_get_num_ops(&operation->ctx.mbedtls_ctx)); - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - /* Add test driver tests here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - /* Can't happen (see discussion in #8271) */ - return 0; -} - -static inline uint32_t psa_driver_wrapper_verify_hash_get_num_ops( - psa_verify_hash_interruptible_operation_t *operation ) -{ - switch( operation->id ) - { - /* If uninitialised, return 0, as no work can have been done. */ - case 0: - return 0; - - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return (mbedtls_psa_verify_hash_get_num_ops(&operation->ctx.mbedtls_ctx)); - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - /* Add test driver tests here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - } - - /* Can't happen (see discussion in #8271) */ - return 0; -} - -static inline psa_status_t psa_driver_wrapper_sign_hash_start( - psa_sign_hash_interruptible_operation_t *operation, - const psa_key_attributes_t *attributes, const uint8_t *key_buffer, - size_t key_buffer_size, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( - psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - - /* Add test driver tests here */ - - /* Declared with fallback == true */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Fell through, meaning no accelerator supports this operation */ - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - status = mbedtls_psa_sign_hash_start( &operation->ctx.mbedtls_ctx, - attributes, - key_buffer, key_buffer_size, - alg, hash, hash_length ); - break; - - /* Add cases for opaque driver here */ - - default: - /* Key is declared with a lifetime not known to us */ - status = PSA_ERROR_INVALID_ARGUMENT; - break; - } - - return( status ); -} - -static inline psa_status_t psa_driver_wrapper_sign_hash_complete( - psa_sign_hash_interruptible_operation_t *operation, - uint8_t *signature, size_t signature_size, - size_t *signature_length ) -{ - switch( operation->id ) - { - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_sign_hash_complete( &operation->ctx.mbedtls_ctx, - signature, signature_size, - signature_length ) ); - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - /* Add test driver tests here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - ( void ) signature; - ( void ) signature_size; - ( void ) signature_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_sign_hash_abort( - psa_sign_hash_interruptible_operation_t *operation ) -{ - switch( operation->id ) - { - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_sign_hash_abort( &operation->ctx.mbedtls_ctx ) ); - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - /* Add test driver tests here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_verify_hash_start( - psa_verify_hash_interruptible_operation_t *operation, - const psa_key_attributes_t *attributes, const uint8_t *key_buffer, - size_t key_buffer_size, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( - psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - - /* Add test driver tests here */ - - /* Declared with fallback == true */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Fell through, meaning no accelerator supports this operation */ - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - status = mbedtls_psa_verify_hash_start( &operation->ctx.mbedtls_ctx, - attributes, - key_buffer, key_buffer_size, - alg, hash, hash_length, - signature, signature_length ); - break; - - /* Add cases for opaque driver here */ - - default: - /* Key is declared with a lifetime not known to us */ - status = PSA_ERROR_INVALID_ARGUMENT; - break; - } - - return( status ); -} - -static inline psa_status_t psa_driver_wrapper_verify_hash_complete( - psa_verify_hash_interruptible_operation_t *operation ) -{ - switch( operation->id ) - { - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_verify_hash_complete( - &operation->ctx.mbedtls_ctx - ) ); - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - /* Add test driver tests here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_verify_hash_abort( - psa_verify_hash_interruptible_operation_t *operation ) -{ - switch( operation->id ) - { - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_verify_hash_abort( &operation->ctx.mbedtls_ctx - ) ); - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - /* Add test driver tests here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -/** Calculate the key buffer size required to store the key material of a key - * associated with an opaque driver from input key data. - * - * \param[in] attributes The key attributes - * \param[in] data The input key data. - * \param[in] data_length The input data length. - * \param[out] key_buffer_size Minimum buffer size to contain the key material. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - */ -static inline psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( - const psa_key_attributes_t *attributes, - const uint8_t *data, - size_t data_length, - size_t *key_buffer_size ) -{ - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - psa_key_type_t key_type = psa_get_key_type(attributes); - - *key_buffer_size = 0; - switch( location ) - { -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - *key_buffer_size = mbedtls_test_opaque_size_function( key_type, - PSA_BYTES_TO_BITS( data_length ) ); - return( ( *key_buffer_size != 0 ) ? - PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ - - default: - (void)key_type; - (void)data; - (void)data_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_generate_key( - const psa_key_attributes_t *attributes, - const psa_custom_key_parameters_t *custom, - const uint8_t *custom_data, size_t custom_data_length, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)); - -#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) - int is_default_production = - psa_custom_key_parameters_are_default(custom, custom_data_length); - if( location != PSA_KEY_LOCATION_LOCAL_STORAGE && !is_default_production ) - { - /* We don't support passing custom production parameters - * to drivers yet. */ - return PSA_ERROR_NOT_SUPPORTED; - } -#else - int is_default_production = 1; - (void) is_default_production; -#endif - - /* Try dynamically-registered SE interface first */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - - if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) - { - size_t pubkey_length = 0; /* We don't support this feature yet */ - if( drv->key_management == NULL || - drv->key_management->p_generate == NULL ) - { - /* Key is defined as being in SE, but we have no way to generate it */ - return( PSA_ERROR_NOT_SUPPORTED ); - } - return( drv->key_management->p_generate( - drv_context, - *( (psa_key_slot_number_t *)key_buffer ), - attributes, NULL, 0, &pubkey_length ) ); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - /* Transparent drivers are limited to generating asymmetric keys. */ - /* We don't support passing custom production parameters - * to drivers yet. */ - if( PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type(attributes) ) && - is_default_production ) - { - /* Cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_generate_key( - attributes, key_buffer, key_buffer_size, - key_buffer_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - break; -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && - psa_get_key_type(attributes) == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) && - psa_get_key_bits(attributes) == 256 ) - { - status = p256_transparent_generate_key( attributes, - key_buffer, - key_buffer_size, - key_buffer_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - break; - } - -#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */ - } -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Software fallback */ - status = psa_generate_key_internal( - attributes, custom, custom_data, custom_data_length, - key_buffer, key_buffer_size, key_buffer_length ); - break; - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_test_opaque_generate_key( - attributes, key_buffer, key_buffer_size, key_buffer_length ); - break; -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - default: - /* Key is declared with a lifetime not known to us */ - status = PSA_ERROR_INVALID_ARGUMENT; - break; - } - - return( status ); -} - -static inline psa_status_t psa_driver_wrapper_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, - size_t data_length, - uint8_t *key_buffer, - size_t key_buffer_size, - size_t *key_buffer_length, - size_t *bits ) -{ - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( - psa_get_key_lifetime( attributes ) ); - - /* Try dynamically-registered SE interface first */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - - if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) - { - if( drv->key_management == NULL || - drv->key_management->p_import == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); - - /* The driver should set the number of key bits, however in - * case it doesn't, we initialize bits to an invalid value. */ - *bits = PSA_MAX_KEY_BITS + 1; - status = drv->key_management->p_import( - drv_context, - *( (psa_key_slot_number_t *)key_buffer ), - attributes, data, data_length, bits ); - - if( status != PSA_SUCCESS ) - return( status ); - - if( (*bits) > PSA_MAX_KEY_BITS ) - return( PSA_ERROR_NOT_SUPPORTED ); - - return( PSA_SUCCESS ); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - -#if (defined(PSA_CRYPTO_DRIVER_TEST) ) - status = mbedtls_test_transparent_import_key - (attributes, - data, - data_length, - key_buffer, - key_buffer_size, - key_buffer_length, - bits - ); - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - -#if (defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) ) - status = p256_transparent_import_key - (attributes, - data, - data_length, - key_buffer, - key_buffer_size, - key_buffer_length, - bits - ); - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - - -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Fell through, meaning no accelerator supports this operation */ - return( psa_import_key_into_slot( attributes, - data, data_length, - key_buffer, key_buffer_size, - key_buffer_length, bits ) ); - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - -#if (defined(PSA_CRYPTO_DRIVER_TEST) ) - case 0x7fffff: - return( mbedtls_test_opaque_import_key - (attributes, - data, - data_length, - key_buffer, - key_buffer_size, - key_buffer_length, - bits - )); -#endif - - -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } - -} - -static inline psa_status_t psa_driver_wrapper_export_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length ) - -{ - - psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( - psa_get_key_lifetime( attributes ) ); - - /* Try dynamically-registered SE interface first */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - - if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) - { - if( ( drv->key_management == NULL ) || - ( drv->key_management->p_export == NULL ) ) - { - return( PSA_ERROR_NOT_SUPPORTED ); - } - - return( drv->key_management->p_export( - drv_context, - *( (psa_key_slot_number_t *)key_buffer ), - data, data_size, data_length ) ); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - return( psa_export_key_internal( attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length ) ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - -#if (defined(PSA_CRYPTO_DRIVER_TEST) ) - case 0x7fffff: - return( mbedtls_test_opaque_export_key - (attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length - )); -#endif - - -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - return( status ); - } - -} - -static inline psa_status_t psa_driver_wrapper_copy_key( - psa_key_attributes_t *attributes, - const uint8_t *source_key, size_t source_key_length, - uint8_t *target_key_buffer, size_t target_key_buffer_size, - size_t *target_key_buffer_length ) -{ - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - - if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) - { - /* Copying to a secure element is not implemented yet. */ - return( PSA_ERROR_NOT_SUPPORTED ); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - switch( location ) - { -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - -#if (defined(PSA_CRYPTO_DRIVER_TEST) ) - case 0x7fffff: - return( mbedtls_test_opaque_copy_key - (attributes, - source_key, - source_key_length, - target_key_buffer, - target_key_buffer_size, - target_key_buffer_length - )); -#endif - - -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void)source_key; - (void)source_key_length; - (void)target_key_buffer; - (void)target_key_buffer_size; - (void)target_key_buffer_length; - status = PSA_ERROR_INVALID_ARGUMENT; - } - return( status ); - -} - -/* - * Cipher functions - */ -static inline psa_status_t psa_driver_wrapper_cipher_encrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *iv, - size_t iv_length, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_cipher_encrypt( attributes, - key_buffer, - key_buffer_size, - alg, - iv, - iv_length, - input, - input_length, - output, - output_size, - output_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - return( mbedtls_psa_cipher_encrypt( attributes, - key_buffer, - key_buffer_size, - alg, - iv, - iv_length, - input, - input_length, - output, - output_size, - output_length ) ); -#else - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_cipher_encrypt( attributes, - key_buffer, - key_buffer_size, - alg, - iv, - iv_length, - input, - input_length, - output, - output_size, - output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - (void)key_buffer; - (void)key_buffer_size; - (void)alg; - (void)iv; - (void)iv_length; - (void)input; - (void)input_length; - (void)output; - (void)output_size; - (void)output_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_cipher_decrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_cipher_decrypt( attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - output, - output_size, - output_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - return( mbedtls_psa_cipher_decrypt( attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - output, - output_size, - output_length ) ); -#else - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_cipher_decrypt( attributes, - key_buffer, - key_buffer_size, - alg, - input, - input_length, - output, - output_size, - output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - (void)key_buffer; - (void)key_buffer_size; - (void)alg; - (void)input; - (void)input_length; - (void)output; - (void)output_size; - (void)output_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_cipher_encrypt_setup( - psa_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_cipher_encrypt_setup( - &operation->ctx.transparent_test_driver_ctx, - attributes, - key_buffer, - key_buffer_size, - alg ); - /* Declared with fallback == true */ - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - /* Fell through, meaning no accelerator supports this operation */ - status = mbedtls_psa_cipher_encrypt_setup( &operation->ctx.mbedtls_ctx, - attributes, - key_buffer, - key_buffer_size, - alg ); - if( status == PSA_SUCCESS ) - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - return( PSA_ERROR_NOT_SUPPORTED ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_test_opaque_cipher_encrypt_setup( - &operation->ctx.opaque_test_driver_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID; - - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - (void)operation; - (void)key_buffer; - (void)key_buffer_size; - (void)alg; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_cipher_decrypt_setup( - psa_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_cipher_decrypt_setup( - &operation->ctx.transparent_test_driver_ctx, - attributes, - key_buffer, - key_buffer_size, - alg ); - /* Declared with fallback == true */ - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - /* Fell through, meaning no accelerator supports this operation */ - status = mbedtls_psa_cipher_decrypt_setup( &operation->ctx.mbedtls_ctx, - attributes, - key_buffer, - key_buffer_size, - alg ); - if( status == PSA_SUCCESS ) - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - - return( status ); -#else /* MBEDTLS_PSA_BUILTIN_CIPHER */ - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_test_opaque_cipher_decrypt_setup( - &operation->ctx.opaque_test_driver_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID; - - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - (void)operation; - (void)key_buffer; - (void)key_buffer_size; - (void)alg; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_cipher_set_iv( - psa_cipher_operation_t *operation, - const uint8_t *iv, - size_t iv_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_cipher_set_iv( &operation->ctx.mbedtls_ctx, - iv, - iv_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_cipher_set_iv( - &operation->ctx.transparent_test_driver_ctx, - iv, iv_length ) ); - - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - return( mbedtls_test_opaque_cipher_set_iv( - &operation->ctx.opaque_test_driver_ctx, - iv, iv_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)iv; - (void)iv_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_cipher_update( - psa_cipher_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_cipher_update( &operation->ctx.mbedtls_ctx, - input, - input_length, - output, - output_size, - output_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_cipher_update( - &operation->ctx.transparent_test_driver_ctx, - input, input_length, - output, output_size, output_length ) ); - - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - return( mbedtls_test_opaque_cipher_update( - &operation->ctx.opaque_test_driver_ctx, - input, input_length, - output, output_size, output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)input; - (void)input_length; - (void)output; - (void)output_size; - (void)output_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_cipher_finish( - psa_cipher_operation_t *operation, - uint8_t *output, - size_t output_size, - size_t *output_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_cipher_finish( &operation->ctx.mbedtls_ctx, - output, - output_size, - output_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_cipher_finish( - &operation->ctx.transparent_test_driver_ctx, - output, output_size, output_length ) ); - - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - return( mbedtls_test_opaque_cipher_finish( - &operation->ctx.opaque_test_driver_ctx, - output, output_size, output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)output; - (void)output_size; - (void)output_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_cipher_abort( - psa_cipher_operation_t *operation ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_cipher_abort( &operation->ctx.mbedtls_ctx ) ); -#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - status = mbedtls_test_transparent_cipher_abort( - &operation->ctx.transparent_test_driver_ctx ); - mbedtls_platform_zeroize( - &operation->ctx.transparent_test_driver_ctx, - sizeof( operation->ctx.transparent_test_driver_ctx ) ); - return( status ); - - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - status = mbedtls_test_opaque_cipher_abort( - &operation->ctx.opaque_test_driver_ctx ); - mbedtls_platform_zeroize( - &operation->ctx.opaque_test_driver_ctx, - sizeof( operation->ctx.opaque_test_driver_ctx ) ); - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -/* - * Hashing functions - */ -static inline psa_status_t psa_driver_wrapper_hash_compute( - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *hash, - size_t hash_size, - size_t *hash_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - /* Try accelerators first */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_hash_compute( - alg, input, input_length, hash, hash_size, hash_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - - /* If software fallback is compiled in, try fallback */ -#if defined(MBEDTLS_PSA_BUILTIN_HASH) - status = mbedtls_psa_hash_compute( alg, input, input_length, - hash, hash_size, hash_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - (void) status; - (void) alg; - (void) input; - (void) input_length; - (void) hash; - (void) hash_size; - (void) hash_length; - - return( PSA_ERROR_NOT_SUPPORTED ); -} - -static inline psa_status_t psa_driver_wrapper_hash_setup( - psa_hash_operation_t *operation, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - /* Try setup on accelerators first */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_hash_setup( - &operation->ctx.test_driver_ctx, alg ); - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - - /* If software fallback is compiled in, try fallback */ -#if defined(MBEDTLS_PSA_BUILTIN_HASH) - status = mbedtls_psa_hash_setup( &operation->ctx.mbedtls_ctx, alg ); - if( status == PSA_SUCCESS ) - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - /* Nothing left to try if we fall through here */ - (void) status; - (void) operation; - (void) alg; - return( PSA_ERROR_NOT_SUPPORTED ); -} - -static inline psa_status_t psa_driver_wrapper_hash_clone( - const psa_hash_operation_t *source_operation, - psa_hash_operation_t *target_operation ) -{ - switch( source_operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_HASH) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - target_operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - return( mbedtls_psa_hash_clone( &source_operation->ctx.mbedtls_ctx, - &target_operation->ctx.mbedtls_ctx ) ); -#endif -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - target_operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - return( mbedtls_test_transparent_hash_clone( - &source_operation->ctx.test_driver_ctx, - &target_operation->ctx.test_driver_ctx ) ); -#endif - default: - (void) target_operation; - return( PSA_ERROR_BAD_STATE ); - } -} - -static inline psa_status_t psa_driver_wrapper_hash_update( - psa_hash_operation_t *operation, - const uint8_t *input, - size_t input_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_HASH) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_hash_update( &operation->ctx.mbedtls_ctx, - input, input_length ) ); -#endif -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_hash_update( - &operation->ctx.test_driver_ctx, - input, input_length ) ); -#endif - default: - (void) input; - (void) input_length; - return( PSA_ERROR_BAD_STATE ); - } -} - -static inline psa_status_t psa_driver_wrapper_hash_finish( - psa_hash_operation_t *operation, - uint8_t *hash, - size_t hash_size, - size_t *hash_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_HASH) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_hash_finish( &operation->ctx.mbedtls_ctx, - hash, hash_size, hash_length ) ); -#endif -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_hash_finish( - &operation->ctx.test_driver_ctx, - hash, hash_size, hash_length ) ); -#endif - default: - (void) hash; - (void) hash_size; - (void) hash_length; - return( PSA_ERROR_BAD_STATE ); - } -} - -static inline psa_status_t psa_driver_wrapper_hash_abort( - psa_hash_operation_t *operation ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_HASH) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_hash_abort( &operation->ctx.mbedtls_ctx ) ); -#endif -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_hash_abort( - &operation->ctx.test_driver_ctx ) ); -#endif - default: - return( PSA_ERROR_BAD_STATE ); - } -} - -static inline psa_status_t psa_driver_wrapper_aead_encrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *plaintext, size_t plaintext_length, - uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_aead_encrypt( - attributes, key_buffer, key_buffer_size, - alg, - nonce, nonce_length, - additional_data, additional_data_length, - plaintext, plaintext_length, - ciphertext, ciphertext_size, ciphertext_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Fell through, meaning no accelerator supports this operation */ - return( mbedtls_psa_aead_encrypt( - attributes, key_buffer, key_buffer_size, - alg, - nonce, nonce_length, - additional_data, additional_data_length, - plaintext, plaintext_length, - ciphertext, ciphertext_size, ciphertext_length ) ); - - /* Add cases for opaque driver here */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_aead_decrypt( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *ciphertext, size_t ciphertext_length, - uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_aead_decrypt( - attributes, key_buffer, key_buffer_size, - alg, - nonce, nonce_length, - additional_data, additional_data_length, - ciphertext, ciphertext_length, - plaintext, plaintext_size, plaintext_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Fell through, meaning no accelerator supports this operation */ - return( mbedtls_psa_aead_decrypt( - attributes, key_buffer, key_buffer_size, - alg, - nonce, nonce_length, - additional_data, additional_data_length, - ciphertext, ciphertext_length, - plaintext, plaintext_size, plaintext_length ) ); - - /* Add cases for opaque driver here */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_aead_encrypt_setup( - psa_aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - status = mbedtls_test_transparent_aead_encrypt_setup( - &operation->ctx.transparent_test_driver_ctx, - attributes, key_buffer, key_buffer_size, - alg ); - - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Fell through, meaning no accelerator supports this operation */ - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - status = mbedtls_psa_aead_encrypt_setup( - &operation->ctx.mbedtls_ctx, attributes, - key_buffer, key_buffer_size, - alg ); - - return( status ); - - /* Add cases for opaque driver here */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_aead_decrypt_setup( - psa_aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - status = mbedtls_test_transparent_aead_decrypt_setup( - &operation->ctx.transparent_test_driver_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Fell through, meaning no accelerator supports this operation */ - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - status = mbedtls_psa_aead_decrypt_setup( - &operation->ctx.mbedtls_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - - return( status ); - - /* Add cases for opaque driver here */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_aead_set_nonce( - psa_aead_operation_t *operation, - const uint8_t *nonce, - size_t nonce_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_AEAD) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_aead_set_nonce( &operation->ctx.mbedtls_ctx, - nonce, - nonce_length ) ); - -#endif /* MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_aead_set_nonce( - &operation->ctx.transparent_test_driver_ctx, - nonce, nonce_length ) ); - - /* Add cases for opaque driver here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)nonce; - (void)nonce_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_aead_set_lengths( - psa_aead_operation_t *operation, - size_t ad_length, - size_t plaintext_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_AEAD) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_aead_set_lengths( &operation->ctx.mbedtls_ctx, - ad_length, - plaintext_length ) ); - -#endif /* MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_aead_set_lengths( - &operation->ctx.transparent_test_driver_ctx, - ad_length, plaintext_length ) ); - - /* Add cases for opaque driver here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)ad_length; - (void)plaintext_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_aead_update_ad( - psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_AEAD) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_aead_update_ad( &operation->ctx.mbedtls_ctx, - input, - input_length ) ); - -#endif /* MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_aead_update_ad( - &operation->ctx.transparent_test_driver_ctx, - input, input_length ) ); - - /* Add cases for opaque driver here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)input; - (void)input_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_aead_update( - psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_AEAD) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_aead_update( &operation->ctx.mbedtls_ctx, - input, input_length, - output, output_size, - output_length ) ); - -#endif /* MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_aead_update( - &operation->ctx.transparent_test_driver_ctx, - input, input_length, output, output_size, - output_length ) ); - - /* Add cases for opaque driver here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)input; - (void)input_length; - (void)output; - (void)output_size; - (void)output_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_aead_finish( - psa_aead_operation_t *operation, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length, - uint8_t *tag, - size_t tag_size, - size_t *tag_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_AEAD) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_aead_finish( &operation->ctx.mbedtls_ctx, - ciphertext, - ciphertext_size, - ciphertext_length, tag, - tag_size, tag_length ) ); - -#endif /* MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_aead_finish( - &operation->ctx.transparent_test_driver_ctx, - ciphertext, ciphertext_size, - ciphertext_length, tag, tag_size, tag_length ) ); - - /* Add cases for opaque driver here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)ciphertext; - (void)ciphertext_size; - (void)ciphertext_length; - (void)tag; - (void)tag_size; - (void)tag_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_aead_verify( - psa_aead_operation_t *operation, - uint8_t *plaintext, - size_t plaintext_size, - size_t *plaintext_length, - const uint8_t *tag, - size_t tag_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_AEAD) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - { - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t check_tag[PSA_AEAD_TAG_MAX_SIZE]; - size_t check_tag_length; - - status = mbedtls_psa_aead_finish( &operation->ctx.mbedtls_ctx, - plaintext, - plaintext_size, - plaintext_length, - check_tag, - sizeof( check_tag ), - &check_tag_length ); - - if( status == PSA_SUCCESS ) - { - if( tag_length != check_tag_length || - mbedtls_ct_memcmp( tag, check_tag, tag_length ) - != 0 ) - status = PSA_ERROR_INVALID_SIGNATURE; - } - - mbedtls_platform_zeroize( check_tag, sizeof( check_tag ) ); - - return( status ); - } - -#endif /* MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_aead_verify( - &operation->ctx.transparent_test_driver_ctx, - plaintext, plaintext_size, - plaintext_length, tag, tag_length ) ); - - /* Add cases for opaque driver here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - (void)plaintext; - (void)plaintext_size; - (void)plaintext_length; - (void)tag; - (void)tag_length; - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -static inline psa_status_t psa_driver_wrapper_aead_abort( - psa_aead_operation_t *operation ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_AEAD) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_aead_abort( &operation->ctx.mbedtls_ctx ) ); - -#endif /* MBEDTLS_PSA_BUILTIN_AEAD */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_aead_abort( - &operation->ctx.transparent_test_driver_ctx ) ); - - /* Add cases for opaque driver here */ - -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - } - - return( PSA_ERROR_INVALID_ARGUMENT ); -} - -/* - * MAC functions - */ -static inline psa_status_t psa_driver_wrapper_mac_compute( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_mac_compute( - attributes, key_buffer, key_buffer_size, alg, - input, input_length, - mac, mac_size, mac_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#if defined(MBEDTLS_PSA_BUILTIN_MAC) - /* Fell through, meaning no accelerator supports this operation */ - status = mbedtls_psa_mac_compute( - attributes, key_buffer, key_buffer_size, alg, - input, input_length, - mac, mac_size, mac_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* MBEDTLS_PSA_BUILTIN_MAC */ - return( PSA_ERROR_NOT_SUPPORTED ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_test_opaque_mac_compute( - attributes, key_buffer, key_buffer_size, alg, - input, input_length, - mac, mac_size, mac_length ); - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - (void) input; - (void) input_length; - (void) mac; - (void) mac_size; - (void) mac_length; - (void) status; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_mac_sign_setup( - psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_mac_sign_setup( - &operation->ctx.transparent_test_driver_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - /* Declared with fallback == true */ - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#if defined(MBEDTLS_PSA_BUILTIN_MAC) - /* Fell through, meaning no accelerator supports this operation */ - status = mbedtls_psa_mac_sign_setup( &operation->ctx.mbedtls_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - if( status == PSA_SUCCESS ) - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* MBEDTLS_PSA_BUILTIN_MAC */ - return( PSA_ERROR_NOT_SUPPORTED ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_test_opaque_mac_sign_setup( - &operation->ctx.opaque_test_driver_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID; - - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void) status; - (void) operation; - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_mac_verify_setup( - psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_mac_verify_setup( - &operation->ctx.transparent_test_driver_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - /* Declared with fallback == true */ - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#if defined(MBEDTLS_PSA_BUILTIN_MAC) - /* Fell through, meaning no accelerator supports this operation */ - status = mbedtls_psa_mac_verify_setup( &operation->ctx.mbedtls_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - if( status == PSA_SUCCESS ) - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* MBEDTLS_PSA_BUILTIN_MAC */ - return( PSA_ERROR_NOT_SUPPORTED ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_test_opaque_mac_verify_setup( - &operation->ctx.opaque_test_driver_ctx, - attributes, - key_buffer, key_buffer_size, - alg ); - - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_OPAQUE_DRIVER_ID; - - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - (void) status; - (void) operation; - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_mac_update( - psa_mac_operation_t *operation, - const uint8_t *input, - size_t input_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_MAC) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_mac_update( &operation->ctx.mbedtls_ctx, - input, input_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_MAC */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_mac_update( - &operation->ctx.transparent_test_driver_ctx, - input, input_length ) ); - - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - return( mbedtls_test_opaque_mac_update( - &operation->ctx.opaque_test_driver_ctx, - input, input_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void) input; - (void) input_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_mac_sign_finish( - psa_mac_operation_t *operation, - uint8_t *mac, - size_t mac_size, - size_t *mac_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_MAC) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_mac_sign_finish( &operation->ctx.mbedtls_ctx, - mac, mac_size, mac_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_MAC */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_mac_sign_finish( - &operation->ctx.transparent_test_driver_ctx, - mac, mac_size, mac_length ) ); - - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - return( mbedtls_test_opaque_mac_sign_finish( - &operation->ctx.opaque_test_driver_ctx, - mac, mac_size, mac_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void) mac; - (void) mac_size; - (void) mac_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_mac_verify_finish( - psa_mac_operation_t *operation, - const uint8_t *mac, - size_t mac_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_MAC) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_mac_verify_finish( &operation->ctx.mbedtls_ctx, - mac, mac_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_MAC */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_mac_verify_finish( - &operation->ctx.transparent_test_driver_ctx, - mac, mac_length ) ); - - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - return( mbedtls_test_opaque_mac_verify_finish( - &operation->ctx.opaque_test_driver_ctx, - mac, mac_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void) mac; - (void) mac_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_mac_abort( - psa_mac_operation_t *operation ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_MAC) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_mac_abort( &operation->ctx.mbedtls_ctx ) ); -#endif /* MBEDTLS_PSA_BUILTIN_MAC */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_mac_abort( - &operation->ctx.transparent_test_driver_ctx ) ); - case MBEDTLS_TEST_OPAQUE_DRIVER_ID: - return( mbedtls_test_opaque_mac_abort( - &operation->ctx.opaque_test_driver_ctx ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -/* - * Asymmetric cryptography - */ -static inline psa_status_t psa_driver_wrapper_asymmetric_encrypt( - const psa_key_attributes_t *attributes, const uint8_t *key_buffer, - size_t key_buffer_size, psa_algorithm_t alg, const uint8_t *input, - size_t input_length, const uint8_t *salt, size_t salt_length, - uint8_t *output, size_t output_size, size_t *output_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_asymmetric_encrypt( attributes, - key_buffer, key_buffer_size, alg, input, input_length, - salt, salt_length, output, output_size, - output_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - return( mbedtls_psa_asymmetric_encrypt( attributes, - key_buffer, key_buffer_size, alg, input, input_length, - salt, salt_length, output, output_size, output_length ) - ); - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_asymmetric_encrypt( attributes, - key_buffer, key_buffer_size, alg, input, input_length, - salt, salt_length, output, output_size, output_length ) - ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - (void)key_buffer; - (void)key_buffer_size; - (void)alg; - (void)input; - (void)input_length; - (void)salt; - (void)salt_length; - (void)output; - (void)output_size; - (void)output_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_asymmetric_decrypt( - const psa_key_attributes_t *attributes, const uint8_t *key_buffer, - size_t key_buffer_size, psa_algorithm_t alg, const uint8_t *input, - size_t input_length, const uint8_t *salt, size_t salt_length, - uint8_t *output, size_t output_size, size_t *output_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_asymmetric_decrypt( attributes, - key_buffer, key_buffer_size, alg, input, input_length, - salt, salt_length, output, output_size, - output_length ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - return( mbedtls_psa_asymmetric_decrypt( attributes, - key_buffer, key_buffer_size, alg,input, input_length, - salt, salt_length, output, output_size, - output_length ) ); - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_asymmetric_decrypt( attributes, - key_buffer, key_buffer_size, alg, input, input_length, - salt, salt_length, output, output_size, - output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - default: - /* Key is declared with a lifetime not known to us */ - (void)status; - (void)key_buffer; - (void)key_buffer_size; - (void)alg; - (void)input; - (void)input_length; - (void)salt; - (void)salt_length; - (void)output; - (void)output_size; - (void)output_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_key_agreement( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *peer_key, - size_t peer_key_length, - uint8_t *shared_secret, - size_t shared_secret_size, - size_t *shared_secret_length - ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = - mbedtls_test_transparent_key_agreement( attributes, - key_buffer, key_buffer_size, alg, peer_key, - peer_key_length, shared_secret, shared_secret_size, - shared_secret_length ); - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && - PSA_ALG_IS_ECDH(alg) && - PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && - psa_get_key_bits(attributes) == 256 ) - { - status = p256_transparent_key_agreement( attributes, - key_buffer, - key_buffer_size, - alg, - peer_key, - peer_key_length, - shared_secret, - shared_secret_size, - shared_secret_length ); - if( status != PSA_ERROR_NOT_SUPPORTED) - return( status ); - } -#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - /* Software Fallback */ - status = psa_key_agreement_raw_builtin( attributes, - key_buffer, - key_buffer_size, - alg, - peer_key, - peer_key_length, - shared_secret, - shared_secret_size, - shared_secret_length ); - return( status ); -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: - return( mbedtls_test_opaque_key_agreement( attributes, - key_buffer, key_buffer_size, alg, peer_key, - peer_key_length, shared_secret, shared_secret_size, - shared_secret_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - - default: - (void) attributes; - (void) key_buffer; - (void) key_buffer_size; - (void) peer_key; - (void) peer_key_length; - (void) shared_secret; - (void) shared_secret_size; - (void) shared_secret_length; - return( PSA_ERROR_NOT_SUPPORTED ); - - } -} - -static inline psa_status_t psa_driver_wrapper_pake_setup( - psa_pake_operation_t *operation, - const psa_crypto_driver_pake_inputs_t *inputs ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime( &inputs->attributes ) ); - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ - status = PSA_ERROR_NOT_SUPPORTED; -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_test_transparent_pake_setup( - &operation->data.ctx.transparent_test_driver_ctx, - inputs ); - if( status == PSA_SUCCESS ) - operation->id = MBEDTLS_TEST_TRANSPARENT_DRIVER_ID; - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#if defined(MBEDTLS_PSA_BUILTIN_PAKE) - status = mbedtls_psa_pake_setup( &operation->data.ctx.mbedtls_ctx, - inputs ); - if( status == PSA_SUCCESS ) - operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; -#endif - return status; - /* Add cases for opaque driver here */ - default: - /* Key is declared with a lifetime not known to us */ - (void)operation; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_pake_output( - psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - uint8_t *output, - size_t output_size, - size_t *output_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_PAKE) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_pake_output( &operation->data.ctx.mbedtls_ctx, step, - output, output_size, output_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_PAKE */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_pake_output( - &operation->data.ctx.transparent_test_driver_ctx, - step, output, output_size, output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void) step; - (void) output; - (void) output_size; - (void) output_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_pake_input( - psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - const uint8_t *input, - size_t input_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_PAKE) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_pake_input( &operation->data.ctx.mbedtls_ctx, - step, input, - input_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_PAKE */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_pake_input( - &operation->data.ctx.transparent_test_driver_ctx, - step, - input, input_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void) step; - (void) input; - (void) input_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_pake_get_implicit_key( - psa_pake_operation_t *operation, - uint8_t *output, size_t output_size, - size_t *output_length ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_PAKE) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_pake_get_implicit_key( &operation->data.ctx.mbedtls_ctx, - output, output_size, output_length ) ); -#endif /* MBEDTLS_PSA_BUILTIN_PAKE */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_pake_get_implicit_key( - &operation->data.ctx.transparent_test_driver_ctx, - output, output_size, output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void) output; - (void) output_size; - (void) output_length; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -static inline psa_status_t psa_driver_wrapper_pake_abort( - psa_pake_operation_t * operation ) -{ - switch( operation->id ) - { -#if defined(MBEDTLS_PSA_BUILTIN_PAKE) - case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_pake_abort( &operation->data.ctx.mbedtls_ctx ) ); -#endif /* MBEDTLS_PSA_BUILTIN_PAKE */ - -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -#if defined(PSA_CRYPTO_DRIVER_TEST) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - return( mbedtls_test_transparent_pake_abort( - &operation->data.ctx.transparent_test_driver_ctx ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c b/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c deleted file mode 100644 index de8a5269b..000000000 --- a/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Functions to delegate cryptographic operations to an available - * and appropriate accelerator. - * Warning: This file is now auto-generated. - */ -/* Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - - -/* BEGIN-common headers */ -#include "common.h" -#include "psa_crypto_aead.h" -#include "psa_crypto_cipher.h" -#include "psa_crypto_core.h" -#include "psa_crypto_driver_wrappers_no_static.h" -#include "psa_crypto_hash.h" -#include "psa_crypto_mac.h" -#include "psa_crypto_pake.h" -#include "psa_crypto_rsa.h" - -#include "mbedtls/platform.h" -/* END-common headers */ - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -/* BEGIN-driver headers */ -/* Headers for mbedtls_test opaque driver */ -#if defined(PSA_CRYPTO_DRIVER_TEST) -#include "test/drivers/test_driver.h" - -#endif -/* Headers for mbedtls_test transparent driver */ -#if defined(PSA_CRYPTO_DRIVER_TEST) -#include "test/drivers/test_driver.h" - -#endif -/* Headers for p256 transparent driver */ -#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) -#include "../3rdparty/p256-m/p256-m_driver_entrypoints.h" - -#endif - -/* END-driver headers */ - -/* Auto-generated values depending on which drivers are registered. - * ID 0 is reserved for unallocated operations. - * ID 1 is reserved for the Mbed TLS software driver. */ -/* BEGIN-driver id definition */ -#define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1) -#define MBEDTLS_TEST_OPAQUE_DRIVER_ID (2) -#define MBEDTLS_TEST_TRANSPARENT_DRIVER_ID (3) -#define P256_TRANSPARENT_DRIVER_ID (4) - -/* END-driver id */ - -/* BEGIN-Common Macro definitions */ - -/* END-Common Macro definitions */ - -/* Support the 'old' SE interface when asked to */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style - * SE driver is present, to avoid unused argument errors at compile time. */ -#ifndef PSA_CRYPTO_DRIVER_PRESENT -#define PSA_CRYPTO_DRIVER_PRESENT -#endif -#include "psa_crypto_se.h" -#endif - -/** Get the key buffer size required to store the key material of a key - * associated with an opaque driver. - * - * \param[in] attributes The key attributes. - * \param[out] key_buffer_size Minimum buffer size to contain the key material - * - * \retval #PSA_SUCCESS - * The minimum size for a buffer to contain the key material has been - * returned successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The type and/or the size in bits of the key or the combination of - * the two is not supported. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key is declared with a lifetime not known to us. - */ -psa_status_t psa_driver_wrapper_get_key_buffer_size( - const psa_key_attributes_t *attributes, - size_t *key_buffer_size ) -{ - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - psa_key_type_t key_type = psa_get_key_type(attributes); - size_t key_bits = psa_get_key_bits(attributes); - - *key_buffer_size = 0; - switch( location ) - { -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LOCATION: -#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) - /* Emulate property 'builtin_key_size' */ - if( psa_key_id_is_builtin( - MBEDTLS_SVC_KEY_ID_GET_KEY_ID( - psa_get_key_id( attributes ) ) ) ) - { - *key_buffer_size = sizeof( psa_drv_slot_number_t ); - return( PSA_SUCCESS ); - } -#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ - *key_buffer_size = mbedtls_test_opaque_size_function( key_type, - key_bits ); - return( ( *key_buffer_size != 0 ) ? - PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ - - default: - (void)key_type; - (void)key_bits; - return( PSA_ERROR_INVALID_ARGUMENT ); - } -} - -psa_status_t psa_driver_wrapper_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length ) - -{ - - psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( - psa_get_key_lifetime( attributes ) ); - - /* Try dynamically-registered SE interface first */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - - if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) - { - if( ( drv->key_management == NULL ) || - ( drv->key_management->p_export_public == NULL ) ) - { - return( PSA_ERROR_NOT_SUPPORTED ); - } - - return( drv->key_management->p_export_public( - drv_context, - *( (psa_key_slot_number_t *)key_buffer ), - data, data_size, data_length ) ); - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - switch( location ) - { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - /* Key is stored in the slot in export representation, so - * cycle through all known transparent accelerators */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - -#if (defined(PSA_CRYPTO_DRIVER_TEST) ) - status = mbedtls_test_transparent_export_public_key - (attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length - ); - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - -#if (defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) ) - status = p256_transparent_export_public_key - (attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length - ); - - if( status != PSA_ERROR_NOT_SUPPORTED ) - return( status ); -#endif - - -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - /* Fell through, meaning no accelerator supports this operation */ - return( psa_export_public_key_internal( attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length ) ); - - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - -#if (defined(PSA_CRYPTO_DRIVER_TEST) ) - case 0x7fffff: - return( mbedtls_test_opaque_export_public_key - (attributes, - key_buffer, - key_buffer_size, - data, - data_size, - data_length - )); -#endif - - -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - /* Key is declared with a lifetime not known to us */ - return( status ); - } - -} - -psa_status_t psa_driver_wrapper_get_builtin_key( - psa_drv_slot_number_t slot_number, - psa_key_attributes_t *attributes, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) -{ - - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); - switch( location ) - { -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - -#if (defined(PSA_CRYPTO_DRIVER_TEST) ) - case 0x7fffff: - return( mbedtls_test_opaque_get_builtin_key - (slot_number, - attributes, - key_buffer, - key_buffer_size, - key_buffer_length - )); -#endif - - -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - default: - (void) slot_number; - (void) key_buffer; - (void) key_buffer_size; - (void) key_buffer_length; - return( PSA_ERROR_DOES_NOT_EXIST ); - } - -} - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h b/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h deleted file mode 100644 index cd617f60e..000000000 --- a/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Function signatures for functionality that can be provided by - * cryptographic accelerators. - */ -/* Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H -#define PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H - -#include "psa/crypto.h" -#include "psa/crypto_driver_common.h" - -psa_status_t psa_driver_wrapper_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length); - -psa_status_t psa_driver_wrapper_get_key_buffer_size( - const psa_key_attributes_t *attributes, - size_t *key_buffer_size); - -psa_status_t psa_driver_wrapper_get_builtin_key( - psa_drv_slot_number_t slot_number, - psa_key_attributes_t *attributes, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); - -#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H */ - -/* End of automatically generated file. */ diff --git a/vendor/mbedtls/library/psa_crypto_ecp.c b/vendor/mbedtls/library/psa_crypto_ecp.c deleted file mode 100644 index 48b90ef57..000000000 --- a/vendor/mbedtls/library/psa_crypto_ecp.c +++ /dev/null @@ -1,594 +0,0 @@ -/* - * PSA ECP layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include -#include "psa_crypto_core.h" -#include "psa_crypto_ecp.h" -#include "psa_crypto_random_impl.h" -#include "mbedtls/psa_util.h" - -#include -#include -#include "mbedtls/platform.h" - -#include -#include -#include -#include - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) -/* Helper function to verify if the provided EC's family and key bit size are valid. - * - * Note: "bits" parameter is used both as input and output and it might be updated - * in case provided input value is not multiple of 8 ("sloppy" bits). - */ -static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits) -{ - switch (family) { - case PSA_ECC_FAMILY_SECP_R1: - switch (*bits) { - case 192: - case 224: - case 256: - case 384: - case 521: - return PSA_SUCCESS; - case 528: - *bits = 521; - return PSA_SUCCESS; - } - break; - - case PSA_ECC_FAMILY_BRAINPOOL_P_R1: - switch (*bits) { - case 256: - case 384: - case 512: - return PSA_SUCCESS; - } - break; - - case PSA_ECC_FAMILY_MONTGOMERY: - switch (*bits) { - case 448: - case 255: - return PSA_SUCCESS; - case 256: - *bits = 255; - return PSA_SUCCESS; - } - break; - - case PSA_ECC_FAMILY_SECP_K1: - switch (*bits) { - case 192: - /* secp224k1 is not and will not be supported in PSA (#3541). */ - case 256: - return PSA_SUCCESS; - } - break; - } - - return PSA_ERROR_INVALID_ARGUMENT; -} - -psa_status_t mbedtls_psa_ecp_load_representation( - psa_key_type_t type, size_t curve_bits, - const uint8_t *data, size_t data_length, - mbedtls_ecp_keypair **p_ecp) -{ - mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; - psa_status_t status; - mbedtls_ecp_keypair *ecp = NULL; - size_t curve_bytes = data_length; - int explicit_bits = (curve_bits != 0); - - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) && - PSA_KEY_TYPE_ECC_GET_FAMILY(type) != PSA_ECC_FAMILY_MONTGOMERY) { - /* A Weierstrass public key is represented as: - * - The byte 0x04; - * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; - * - `y_P` as a `ceiling(m/8)`-byte string, big-endian. - * So its data length is 2m+1 where m is the curve size in bits. - */ - if ((data_length & 1) == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - curve_bytes = data_length / 2; - - /* Montgomery public keys are represented in compressed format, meaning - * their curve_bytes is equal to the amount of input. */ - - /* Private keys are represented in uncompressed private random integer - * format, meaning their curve_bytes is equal to the amount of input. */ - } - - if (explicit_bits) { - /* With an explicit bit-size, the data must have the matching length. */ - if (curve_bytes != PSA_BITS_TO_BYTES(curve_bits)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } else { - /* We need to infer the bit-size from the data. Since the only - * information we have is the length in bytes, the value of curve_bits - * at this stage is rounded up to the nearest multiple of 8. */ - curve_bits = PSA_BYTES_TO_BITS(curve_bytes); - } - - /* Allocate and initialize a key representation. */ - ecp = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair)); - if (ecp == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - mbedtls_ecp_keypair_init(ecp); - - status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), &curve_bits); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* Load the group. */ - grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type), - curve_bits); - if (grp_id == MBEDTLS_ECP_DP_NONE) { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - status = mbedtls_to_psa_error( - mbedtls_ecp_group_load(&ecp->grp, grp_id)); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* Load the key material. */ - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) { - /* Load the public value. */ - status = mbedtls_to_psa_error( - mbedtls_ecp_point_read_binary(&ecp->grp, &ecp->Q, - data, - data_length)); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* Check that the point is on the curve. */ - status = mbedtls_to_psa_error( - mbedtls_ecp_check_pubkey(&ecp->grp, &ecp->Q)); - if (status != PSA_SUCCESS) { - goto exit; - } - } else { - /* Load and validate the secret value. */ - status = mbedtls_to_psa_error( - mbedtls_ecp_read_key(ecp->grp.id, - ecp, - data, - data_length)); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - *p_ecp = ecp; -exit: - if (status != PSA_SUCCESS) { - mbedtls_ecp_keypair_free(ecp); - mbedtls_free(ecp); - } - - return status; -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) - -psa_status_t mbedtls_psa_ecp_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits) -{ - psa_status_t status; - mbedtls_ecp_keypair *ecp = NULL; - - /* Parse input */ - status = mbedtls_psa_ecp_load_representation(attributes->type, - attributes->bits, - data, - data_length, - &ecp); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) == - PSA_ECC_FAMILY_MONTGOMERY) { - *bits = ecp->grp.nbits + 1; - } else { - *bits = ecp->grp.nbits; - } - - /* Re-export the data to PSA export format. There is currently no support - * for other input formats then the export format, so this is a 1-1 - * copy operation. */ - status = mbedtls_psa_ecp_export_key(attributes->type, - ecp, - key_buffer, - key_buffer_size, - key_buffer_length); -exit: - /* Always free the PK object (will also free contained ECP context) */ - mbedtls_ecp_keypair_free(ecp); - mbedtls_free(ecp); - - return status; -} - -psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type, - mbedtls_ecp_keypair *ecp, - uint8_t *data, - size_t data_size, - size_t *data_length) -{ - psa_status_t status; - - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) { - /* Check whether the public part is loaded */ - if (mbedtls_ecp_is_zero(&ecp->Q)) { - /* Calculate the public key */ - status = mbedtls_to_psa_error( - mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE)); - if (status != PSA_SUCCESS) { - return status; - } - } - - status = mbedtls_to_psa_error( - mbedtls_ecp_point_write_binary(&ecp->grp, &ecp->Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - data_length, - data, - data_size)); - if (status != PSA_SUCCESS) { - memset(data, 0, data_size); - } - - return status; - } else { - status = mbedtls_to_psa_error( - mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size)); - return status; - } -} - -psa_status_t mbedtls_psa_ecp_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_keypair *ecp = NULL; - - status = mbedtls_psa_ecp_load_representation( - attributes->type, attributes->bits, - key_buffer, key_buffer_size, &ecp); - if (status != PSA_SUCCESS) { - return status; - } - - status = mbedtls_psa_ecp_export_key( - PSA_KEY_TYPE_ECC_PUBLIC_KEY( - PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)), - ecp, data, data_size, data_length); - - mbedtls_ecp_keypair_free(ecp); - mbedtls_free(ecp); - - return status; -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) -psa_status_t mbedtls_psa_ecp_generate_key( - const psa_key_attributes_t *attributes, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) -{ - psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( - attributes->type); - mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_from_psa(curve, attributes->bits); - if (grp_id == MBEDTLS_ECP_DP_NONE) { - return PSA_ERROR_NOT_SUPPORTED; - } - - mbedtls_ecp_keypair ecp; - mbedtls_ecp_keypair_init(&ecp); - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_ecp_group_load(&ecp.grp, grp_id); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_ecp_gen_privkey(&ecp.grp, &ecp.d, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_ecp_write_key_ext(&ecp, key_buffer_length, - key_buffer, key_buffer_size); - -exit: - mbedtls_ecp_keypair_free(&ecp); - return mbedtls_to_psa_error(ret); -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ - -/****************************************************************/ -/* ECDSA sign/verify */ -/****************************************************************/ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) -psa_status_t mbedtls_psa_ecdsa_sign_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - uint8_t *signature, size_t signature_size, size_t *signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_keypair *ecp = NULL; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t curve_bytes; - mbedtls_mpi r, s; - - status = mbedtls_psa_ecp_load_representation(attributes->type, - attributes->bits, - key_buffer, - key_buffer_size, - &ecp); - if (status != PSA_SUCCESS) { - return status; - } - - curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits); - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - - if (signature_size < 2 * curve_bytes) { - ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - goto cleanup; - } - - if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) - psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); - mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg); - MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext( - &ecp->grp, &r, &s, - &ecp->d, hash, - hash_length, md_alg, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE)); -#else - ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - goto cleanup; -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ - } else { - (void) alg; - MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ecp->grp, &r, &s, &ecp->d, - hash, hash_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE)); - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&r, - signature, - curve_bytes)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&s, - signature + curve_bytes, - curve_bytes)); -cleanup: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - if (ret == 0) { - *signature_length = 2 * curve_bytes; - } - - mbedtls_ecp_keypair_free(ecp); - mbedtls_free(ecp); - - return mbedtls_to_psa_error(ret); -} - -psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp) -{ - int ret = 0; - - /* Check whether the public part is loaded. If not, load it. */ - if (mbedtls_ecp_is_zero(&ecp->Q)) { - ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q, - &ecp->d, &ecp->grp.G, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE); - } - - return mbedtls_to_psa_error(ret); -} - -psa_status_t mbedtls_psa_ecdsa_verify_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_ecp_keypair *ecp = NULL; - size_t curve_bytes; - mbedtls_mpi r, s; - - (void) alg; - - status = mbedtls_psa_ecp_load_representation(attributes->type, - attributes->bits, - key_buffer, - key_buffer_size, - &ecp); - if (status != PSA_SUCCESS) { - return status; - } - - curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits); - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - - if (signature_length != 2 * curve_bytes) { - status = PSA_ERROR_INVALID_SIGNATURE; - goto cleanup; - } - - status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r, - signature, - curve_bytes)); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s, - signature + curve_bytes, - curve_bytes)); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = mbedtls_psa_ecp_load_public_part(ecp); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash, - hash_length, &ecp->Q, - &r, &s)); -cleanup: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - mbedtls_ecp_keypair_free(ecp); - mbedtls_free(ecp); - - return status; -} - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ - * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ - -/****************************************************************/ -/* ECDH Key Agreement */ -/****************************************************************/ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) -psa_status_t mbedtls_psa_key_agreement_ecdh( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length, - uint8_t *shared_secret, size_t shared_secret_size, - size_t *shared_secret_length) -{ - psa_status_t status; - if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) || - !PSA_ALG_IS_ECDH(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - mbedtls_ecp_keypair *ecp = NULL; - status = mbedtls_psa_ecp_load_representation( - attributes->type, - attributes->bits, - key_buffer, - key_buffer_size, - &ecp); - if (status != PSA_SUCCESS) { - return status; - } - mbedtls_ecp_keypair *their_key = NULL; - mbedtls_ecdh_context ecdh; - size_t bits = 0; - psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ecp->grp.id, &bits); - mbedtls_ecdh_init(&ecdh); - - status = mbedtls_psa_ecp_load_representation( - PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve), - bits, - peer_key, - peer_key_length, - &their_key); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = mbedtls_to_psa_error( - mbedtls_ecdh_get_params(&ecdh, their_key, MBEDTLS_ECDH_THEIRS)); - if (status != PSA_SUCCESS) { - goto exit; - } - status = mbedtls_to_psa_error( - mbedtls_ecdh_get_params(&ecdh, ecp, MBEDTLS_ECDH_OURS)); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = mbedtls_to_psa_error( - mbedtls_ecdh_calc_secret(&ecdh, - shared_secret_length, - shared_secret, shared_secret_size, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE)); - if (status != PSA_SUCCESS) { - goto exit; - } - if (PSA_BITS_TO_BYTES(bits) != *shared_secret_length) { - status = PSA_ERROR_CORRUPTION_DETECTED; - } -exit: - if (status != PSA_SUCCESS) { - mbedtls_platform_zeroize(shared_secret, shared_secret_size); - } - mbedtls_ecdh_free(&ecdh); - mbedtls_ecp_keypair_free(their_key); - mbedtls_free(their_key); - mbedtls_ecp_keypair_free(ecp); - mbedtls_free(ecp); - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */ - - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_ecp.h b/vendor/mbedtls/library/psa_crypto_ecp.h deleted file mode 100644 index a9f5d59de..000000000 --- a/vendor/mbedtls/library/psa_crypto_ecp.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * PSA ECP layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_ECP_H -#define PSA_CRYPTO_ECP_H - -#include -#include - -/** Load the contents of a key buffer into an internal ECP representation - * - * \param[in] type The type of key contained in \p data. - * \param[in] curve_bits The nominal bit-size of the curve. - * It must be consistent with the representation - * passed in \p data. - * This can be 0, in which case the bit-size - * is inferred from \p data_length (which is possible - * for all key types and representation formats - * formats that are currently supported or will - * be in the foreseeable future). - * \param[in] data The buffer from which to load the representation. - * \param[in] data_length The size in bytes of \p data. - * \param[out] p_ecp Returns a pointer to an ECP context on success. - * The caller is responsible for freeing both the - * contents of the context and the context itself - * when done. - */ -psa_status_t mbedtls_psa_ecp_load_representation(psa_key_type_t type, - size_t curve_bits, - const uint8_t *data, - size_t data_length, - mbedtls_ecp_keypair **p_ecp); - -/** Load the public part of an internal ECP, if required. - * - * \param ecp The ECP context to load the public part for. - * - * \return PSA_SUCCESS on success, otherwise an MPI error. - */ - -psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp); - -/** Import an ECP key in binary format. - * - * \note The signature of this function is that of a PSA driver - * import_key entry point. This function behaves as an import_key - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes for the key to import. - * \param[in] data The buffer containing the key data in import - * format. - * \param[in] data_length Size of the \p data buffer in bytes. - * \param[out] key_buffer The buffer containing the key data in output - * format. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This - * size is greater or equal to \p data_length. - * \param[out] key_buffer_length The length of the data written in \p - * key_buffer in bytes. - * \param[out] bits The key size in number of bits. - * - * \retval #PSA_SUCCESS The ECP key was imported successfully. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key data is not correctly formatted. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_ecp_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits); - -/** Export an ECP key to export representation - * - * \param[in] type The type of key (public/private) to export - * \param[in] ecp The internal ECP representation from which to export - * \param[out] data The buffer to export to - * \param[in] data_size The length of the buffer to export to - * \param[out] data_length The amount of bytes written to \p data - */ -psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type, - mbedtls_ecp_keypair *ecp, - uint8_t *data, - size_t data_size, - size_t *data_length); - -/** Export an ECP public key or the public part of an ECP key pair in binary - * format. - * - * \note The signature of this function is that of a PSA driver - * export_public_key entry point. This function behaves as an - * export_public_key entry point as defined in the PSA driver interface - * specification. - * - * \param[in] attributes The attributes for the key to export. - * \param[in] key_buffer Material or context of the key to export. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[out] data Buffer where the key data is to be written. - * \param[in] data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes written in - * \p data - * - * \retval #PSA_SUCCESS The ECP public key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_ecp_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length); - -/** - * \brief Generate an ECP key. - * - * \note The signature of the function is that of a PSA driver generate_key - * entry point. - * - * \param[in] attributes The attributes for the ECP key to generate. - * \param[out] key_buffer Buffer where the key data is to be written. - * \param[in] key_buffer_size Size of \p key_buffer in bytes. - * \param[out] key_buffer_length On success, the number of bytes written in - * \p key_buffer. - * - * \retval #PSA_SUCCESS - * The key was successfully generated. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Key length or type not supported. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of \p key_buffer is too small. - */ -psa_status_t mbedtls_psa_ecp_generate_key( - const psa_key_attributes_t *attributes, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); - -/** Sign an already-calculated hash with ECDSA. - * - * \note The signature of this function is that of a PSA driver - * sign_hash entry point. This function behaves as a sign_hash - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the ECC key to use for the - * operation. - * \param[in] key_buffer The buffer containing the ECC key context. - * format. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg Randomized or deterministic ECDSA algorithm. - * \param[in] hash The hash or message to sign. - * \param[in] hash_length Size of the \p hash buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param[in] signature_size Size of the \p signature buffer in bytes. - * \param[out] signature_length On success, the number of bytes - * that make up the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_ECC_KEY_PAIR, \c key_bits, - * \p alg) where \c key_bits is the bit-size of the ECC key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - */ -psa_status_t mbedtls_psa_ecdsa_sign_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - uint8_t *signature, size_t signature_size, size_t *signature_length); - -/** - * \brief Verify an ECDSA hash or short message signature. - * - * \note The signature of this function is that of a PSA driver - * verify_hash entry point. This function behaves as a verify_hash - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the ECC key to use for the - * operation. - * \param[in] key_buffer The buffer containing the ECC key context. - * format. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg Randomized or deterministic ECDSA algorithm. - * \param[in] hash The hash or message whose signature is to be - * verified. - * \param[in] hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param[in] signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The signature is valid. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_ecdsa_verify_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length); - - -/** Perform a key agreement and return the raw ECDH shared secret. - * - * \note The signature of this function is that of a PSA driver - * key_agreement entry point. This function behaves as a key_agreement - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the private key - * context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in - * bytes. - * \param[in] alg A key agreement algorithm that is - * compatible with the type of the key. - * \param[in] peer_key The buffer containing the key context - * of the peer's public key. - * \param[in] peer_key_length Size of the \p peer_key buffer in - * bytes. - * \param[out] shared_secret The buffer to which the shared secret - * is to be written. - * \param[in] shared_secret_size Size of the \p shared_secret buffer in - * bytes. - * \param[out] shared_secret_length On success, the number of bytes that make - * up the returned shared secret. - * \retval #PSA_SUCCESS - * Success. Shared secret successfully calculated. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p alg is not a key agreement algorithm, or - * \p private_key is not compatible with \p alg, - * or \p peer_key is not valid for \p alg or not compatible with - * \p private_key. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p shared_secret_size is too small - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not a supported key agreement algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_key_agreement_ecdh( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length, - uint8_t *shared_secret, size_t shared_secret_size, - size_t *shared_secret_length); -#endif /* PSA_CRYPTO_ECP_H */ diff --git a/vendor/mbedtls/library/psa_crypto_ffdh.c b/vendor/mbedtls/library/psa_crypto_ffdh.c deleted file mode 100644 index c759affb4..000000000 --- a/vendor/mbedtls/library/psa_crypto_ffdh.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * PSA FFDH layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -/* This header is only needed because it defines - * MBEDTLS_DHM_RFC7919_FFDHEXXXX_[P|G]_BIN symbols that are used in - * mbedtls_psa_ffdh_set_prime_generator(). Apart from that, this module - * only uses bignum functions for arithmetic. */ -#include - -#include -#include "psa_crypto_core.h" -#include "psa_crypto_ffdh.h" -#include "psa_crypto_random_impl.h" -#include "mbedtls/platform.h" -#include "mbedtls/error.h" - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH) -static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size, - mbedtls_mpi *P, - mbedtls_mpi *G) -{ - const unsigned char *dhm_P = NULL; - const unsigned char *dhm_G = NULL; - size_t dhm_size_P = 0; - size_t dhm_size_G = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (P == NULL && G == NULL) { - return PSA_ERROR_INVALID_ARGUMENT; - } - -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048) - static const unsigned char dhm_P_2048[] = - MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN; - static const unsigned char dhm_G_2048[] = - MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072) - static const unsigned char dhm_P_3072[] = - MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN; - static const unsigned char dhm_G_3072[] = - MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096) - static const unsigned char dhm_P_4096[] = - MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN; - static const unsigned char dhm_G_4096[] = - MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144) - static const unsigned char dhm_P_6144[] = - MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN; - static const unsigned char dhm_G_6144[] = - MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192) - static const unsigned char dhm_P_8192[] = - MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN; - static const unsigned char dhm_G_8192[] = - MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */ - - switch (key_size) { -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048) - case sizeof(dhm_P_2048): - dhm_P = dhm_P_2048; - dhm_G = dhm_G_2048; - dhm_size_P = sizeof(dhm_P_2048); - dhm_size_G = sizeof(dhm_G_2048); - break; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072) - case sizeof(dhm_P_3072): - dhm_P = dhm_P_3072; - dhm_G = dhm_G_3072; - dhm_size_P = sizeof(dhm_P_3072); - dhm_size_G = sizeof(dhm_G_3072); - break; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096) - case sizeof(dhm_P_4096): - dhm_P = dhm_P_4096; - dhm_G = dhm_G_4096; - dhm_size_P = sizeof(dhm_P_4096); - dhm_size_G = sizeof(dhm_G_4096); - break; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144) - case sizeof(dhm_P_6144): - dhm_P = dhm_P_6144; - dhm_G = dhm_G_6144; - dhm_size_P = sizeof(dhm_P_6144); - dhm_size_G = sizeof(dhm_G_6144); - break; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */ -#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192) - case sizeof(dhm_P_8192): - dhm_P = dhm_P_8192; - dhm_G = dhm_G_8192; - dhm_size_P = sizeof(dhm_P_8192); - dhm_size_G = sizeof(dhm_G_8192); - break; -#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */ - default: - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (P != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(P, dhm_P, - dhm_size_P)); - } - if (G != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(G, dhm_G, - dhm_size_G)); - } - -cleanup: - if (ret != 0) { - return mbedtls_to_psa_error(ret); - } - - return PSA_SUCCESS; -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT || - MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE || - MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY || - MBEDTLS_PSA_BUILTIN_ALG_FFDH */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) -psa_status_t mbedtls_psa_ffdh_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *data, - size_t data_size, - size_t *data_length) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi GX, G, X, P; - psa_key_type_t type = attributes->type; - - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) { - if (key_buffer_size > data_size) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - memcpy(data, key_buffer, key_buffer_size); - memset(data + key_buffer_size, 0, - data_size - key_buffer_size); - *data_length = key_buffer_size; - return PSA_SUCCESS; - } - - mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G); - mbedtls_mpi_init(&X); mbedtls_mpi_init(&P); - - size_t key_len = PSA_BITS_TO_BYTES(attributes->bits); - if (key_len > data_size) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto cleanup; - } - - status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer, - key_buffer_size)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&GX, &G, &X, &P, NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&GX, data, key_len)); - - *data_length = key_len; - - ret = 0; -cleanup: - mbedtls_mpi_free(&P); mbedtls_mpi_free(&G); - mbedtls_mpi_free(&X); mbedtls_mpi_free(&GX); - - if (status == PSA_SUCCESS && ret != 0) { - status = mbedtls_to_psa_error(ret); - } - - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT || - MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) -psa_status_t mbedtls_psa_ffdh_generate_key( - const psa_key_attributes_t *attributes, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) -{ - mbedtls_mpi X, P; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi_init(&P); mbedtls_mpi_init(&X); - (void) attributes; - - status = mbedtls_psa_ffdh_set_prime_generator(key_buffer_size, &P, NULL); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - /* RFC7919: Traditional finite field Diffie-Hellman has each peer choose their - secret exponent from the range [2, P-2]. - Select random value in range [3, P-1] and decrease it by 1. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_random(&X, 3, &P, mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &X, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&X, key_buffer, key_buffer_size)); - *key_buffer_length = key_buffer_size; - -cleanup: - mbedtls_mpi_free(&P); mbedtls_mpi_free(&X); - if (status == PSA_SUCCESS && ret != 0) { - return mbedtls_to_psa_error(ret); - } - - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) -psa_status_t mbedtls_psa_ffdh_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits) -{ - (void) attributes; - - if (key_buffer_size < data_length) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - memcpy(key_buffer, data, data_length); - *key_buffer_length = data_length; - *bits = PSA_BYTES_TO_BITS(data_length); - - return PSA_SUCCESS; -} -#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH) -psa_status_t mbedtls_psa_ffdh_key_agreement( - const psa_key_attributes_t *attributes, - const uint8_t *peer_key, - size_t peer_key_length, - const uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *shared_secret, - size_t shared_secret_size, - size_t *shared_secret_length) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi P, X, GY, K; - const size_t calculated_shared_secret_size = key_buffer_size; - - if (!PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_get_key_type(attributes))) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (peer_key_length != key_buffer_size) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - /* This has been checked by the core, but keep a local check too. */ - if (calculated_shared_secret_size > shared_secret_size) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - mbedtls_mpi_init(&P); - mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY); - mbedtls_mpi_init(&K); - - status = mbedtls_psa_ffdh_set_prime_generator( - PSA_BITS_TO_BYTES(attributes->bits), &P, NULL); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key, - peer_key_length)); - - /* RFC 7919 5.1: validate the peer's public key: 1 < GY < P-1 - * - * This check is sufficient to ensure GY is not of low order, because we're - * using a safe prime (that is, q = (p-1) / 2 is also prime), so the only - * group elements of low order are 1 and p-1. (Obviously we also want to - * exclude 0 that is not a group element, and values >= p as they are not - * residues mod p.) - * - * Note: we know we're using a safe prime because the only FFDH groups - * defined by the PSA spec are from RFC 7919 (since version 1.0) and RFC - * 3525 (since v1.4, not yet supported in tf-psa-crypto as of writing this - * comment), which both use safe primes. - * - * Note: NIST SP 800-56Ar3 5.7.1.1 (2) has the check on the shared secret, - * but checking before is equivalent (unless our secret key is exactly - * (p-1)/2, which has negligible probability and can't be influenced by the - * adversary). Checking before is cleaner in terms of side channel analysis, - * as we haven't loaded our secret yet, so no worries about branches. - * - * Use X as a temporary, since we haven't loaded it yet. - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &P, 1)); // x = p - 1 - if (mbedtls_mpi_cmp_mpi(&GY, &X) >= 0) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto cleanup; - } - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, 1)); // x = 1 - if (mbedtls_mpi_cmp_mpi(&GY, &X) <= 0) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer, - key_buffer_size)); - - /* Calculate shared secret public key: K = G^(XY) mod P = GY^X mod P */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K, shared_secret, - calculated_shared_secret_size)); - - *shared_secret_length = calculated_shared_secret_size; - - ret = 0; - -cleanup: - mbedtls_mpi_free(&P); - mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY); - mbedtls_mpi_free(&K); - - if (status == PSA_SUCCESS && ret != 0) { - status = mbedtls_to_psa_error(ret); - } - - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */ - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_ffdh.h b/vendor/mbedtls/library/psa_crypto_ffdh.h deleted file mode 100644 index 79accd15a..000000000 --- a/vendor/mbedtls/library/psa_crypto_ffdh.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * PSA FFDH layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_FFDH_H -#define PSA_CRYPTO_FFDH_H - -#include - -/** Perform a key agreement and return the FFDH shared secret. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] peer_key The buffer containing the key context - * of the peer's public key. - * \param[in] peer_key_length Size of the \p peer_key buffer in - * bytes. - * \param[in] key_buffer The buffer containing the private key - * context. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in - * bytes. - * \param[out] shared_secret The buffer to which the shared secret - * is to be written. - * \param[in] shared_secret_size Size of the \p shared_secret buffer in - * bytes. - * \param[out] shared_secret_length On success, the number of bytes that make - * up the returned shared secret. - * \retval #PSA_SUCCESS - * Success. Shared secret successfully calculated. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key_buffer_size, \p peer_key_length, \p shared_secret_size - * do not match - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_ffdh_key_agreement( - const psa_key_attributes_t *attributes, - const uint8_t *peer_key, - size_t peer_key_length, - const uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *shared_secret, - size_t shared_secret_size, - size_t *shared_secret_length); - -/** Export a public key or the public part of a DH key pair in binary format. - * - * \param[in] attributes The attributes for the key to export. - * \param[in] key_buffer Material or context of the key to export. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[out] data Buffer where the key data is to be written. - * \param[in] data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes written in - * \p data - * - * \retval #PSA_SUCCESS The public key was exported successfully. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of \p key_buffer is too small. - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_ffdh_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *data, - size_t data_size, - size_t *data_length); - -/** - * \brief Generate DH key. - * - * \note The signature of the function is that of a PSA driver generate_key - * entry point. - * - * \param[in] attributes The attributes for the key to generate. - * \param[out] key_buffer Buffer where the key data is to be written. - * \param[in] key_buffer_size Size of \p key_buffer in bytes. - * \param[out] key_buffer_length On success, the number of bytes written in - * \p key_buffer. - * - * \retval #PSA_SUCCESS - * The key was generated successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Key size in bits is invalid. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of \p key_buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_ffdh_generate_key( - const psa_key_attributes_t *attributes, - uint8_t *key_buffer, - size_t key_buffer_size, - size_t *key_buffer_length); - -/** - * \brief Import DH key. - * - * \note The signature of the function is that of a PSA driver import_key - * entry point. - * - * \param[in] attributes The attributes for the key to import. - * \param[in] data The buffer containing the key data in import - * format. - * \param[in] data_length Size of the \p data buffer in bytes. - * \param[out] key_buffer The buffer containing the key data in output - * format. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This - * size is greater or equal to \p data_length. - * \param[out] key_buffer_length The length of the data written in \p - * key_buffer in bytes. - * \param[out] bits The key size in number of bits. - * - * \retval #PSA_SUCCESS - * The key was generated successfully. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of \p key_buffer is too small. - */ -psa_status_t mbedtls_psa_ffdh_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits); - -#endif /* PSA_CRYPTO_FFDH_H */ diff --git a/vendor/mbedtls/library/psa_crypto_hash.c b/vendor/mbedtls/library/psa_crypto_hash.c deleted file mode 100644 index eeb7666c1..000000000 --- a/vendor/mbedtls/library/psa_crypto_hash.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * PSA hashing layer on top of Mbed TLS software crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include -#include "psa_crypto_core.h" -#include "psa_crypto_hash.h" - -#include -#include - -#if defined(MBEDTLS_PSA_BUILTIN_HASH) -psa_status_t mbedtls_psa_hash_abort( - mbedtls_psa_hash_operation_t *operation) -{ - switch (operation->alg) { - case 0: - /* The object has (apparently) been initialized but it is not - * in use. It's ok to call abort on such an object, and there's - * nothing to do. */ - break; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) - case PSA_ALG_MD5: - mbedtls_md5_free(&operation->ctx.md5); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) - case PSA_ALG_RIPEMD160: - mbedtls_ripemd160_free(&operation->ctx.ripemd160); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) - case PSA_ALG_SHA_1: - mbedtls_sha1_free(&operation->ctx.sha1); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) - case PSA_ALG_SHA_224: - mbedtls_sha256_free(&operation->ctx.sha256); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) - case PSA_ALG_SHA_256: - mbedtls_sha256_free(&operation->ctx.sha256); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) - case PSA_ALG_SHA_384: - mbedtls_sha512_free(&operation->ctx.sha512); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) - case PSA_ALG_SHA_512: - mbedtls_sha512_free(&operation->ctx.sha512); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) - case PSA_ALG_SHA3_224: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) - case PSA_ALG_SHA3_256: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) - case PSA_ALG_SHA3_384: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - case PSA_ALG_SHA3_512: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - mbedtls_sha3_free(&operation->ctx.sha3); - break; -#endif - default: - return PSA_ERROR_BAD_STATE; - } - operation->alg = 0; - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_hash_setup( - mbedtls_psa_hash_operation_t *operation, - psa_algorithm_t alg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* A context must be freshly initialized before it can be set up. */ - if (operation->alg != 0) { - return PSA_ERROR_BAD_STATE; - } - - switch (alg) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) - case PSA_ALG_MD5: - mbedtls_md5_init(&operation->ctx.md5); - ret = mbedtls_md5_starts(&operation->ctx.md5); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) - case PSA_ALG_RIPEMD160: - mbedtls_ripemd160_init(&operation->ctx.ripemd160); - ret = mbedtls_ripemd160_starts(&operation->ctx.ripemd160); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) - case PSA_ALG_SHA_1: - mbedtls_sha1_init(&operation->ctx.sha1); - ret = mbedtls_sha1_starts(&operation->ctx.sha1); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) - case PSA_ALG_SHA_224: - mbedtls_sha256_init(&operation->ctx.sha256); - ret = mbedtls_sha256_starts(&operation->ctx.sha256, 1); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) - case PSA_ALG_SHA_256: - mbedtls_sha256_init(&operation->ctx.sha256); - ret = mbedtls_sha256_starts(&operation->ctx.sha256, 0); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) - case PSA_ALG_SHA_384: - mbedtls_sha512_init(&operation->ctx.sha512); - ret = mbedtls_sha512_starts(&operation->ctx.sha512, 1); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) - case PSA_ALG_SHA_512: - mbedtls_sha512_init(&operation->ctx.sha512); - ret = mbedtls_sha512_starts(&operation->ctx.sha512, 0); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) - case PSA_ALG_SHA3_224: - mbedtls_sha3_init(&operation->ctx.sha3); - ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_224); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) - case PSA_ALG_SHA3_256: - mbedtls_sha3_init(&operation->ctx.sha3); - ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_256); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) - case PSA_ALG_SHA3_384: - mbedtls_sha3_init(&operation->ctx.sha3); - ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_384); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - case PSA_ALG_SHA3_512: - mbedtls_sha3_init(&operation->ctx.sha3); - ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_512); - break; -#endif - default: - return PSA_ALG_IS_HASH(alg) ? - PSA_ERROR_NOT_SUPPORTED : - PSA_ERROR_INVALID_ARGUMENT; - } - if (ret == 0) { - operation->alg = alg; - } else { - mbedtls_psa_hash_abort(operation); - } - return mbedtls_to_psa_error(ret); -} - -psa_status_t mbedtls_psa_hash_clone( - const mbedtls_psa_hash_operation_t *source_operation, - mbedtls_psa_hash_operation_t *target_operation) -{ - switch (source_operation->alg) { - case 0: - return PSA_ERROR_BAD_STATE; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) - case PSA_ALG_MD5: - mbedtls_md5_clone(&target_operation->ctx.md5, - &source_operation->ctx.md5); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) - case PSA_ALG_RIPEMD160: - mbedtls_ripemd160_clone(&target_operation->ctx.ripemd160, - &source_operation->ctx.ripemd160); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) - case PSA_ALG_SHA_1: - mbedtls_sha1_clone(&target_operation->ctx.sha1, - &source_operation->ctx.sha1); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) - case PSA_ALG_SHA_224: - mbedtls_sha256_clone(&target_operation->ctx.sha256, - &source_operation->ctx.sha256); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) - case PSA_ALG_SHA_256: - mbedtls_sha256_clone(&target_operation->ctx.sha256, - &source_operation->ctx.sha256); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) - case PSA_ALG_SHA_384: - mbedtls_sha512_clone(&target_operation->ctx.sha512, - &source_operation->ctx.sha512); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) - case PSA_ALG_SHA_512: - mbedtls_sha512_clone(&target_operation->ctx.sha512, - &source_operation->ctx.sha512); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) - case PSA_ALG_SHA3_224: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) - case PSA_ALG_SHA3_256: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) - case PSA_ALG_SHA3_384: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - case PSA_ALG_SHA3_512: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - mbedtls_sha3_clone(&target_operation->ctx.sha3, - &source_operation->ctx.sha3); - break; -#endif - default: - (void) source_operation; - (void) target_operation; - return PSA_ERROR_NOT_SUPPORTED; - } - - target_operation->alg = source_operation->alg; - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_hash_update( - mbedtls_psa_hash_operation_t *operation, - const uint8_t *input, - size_t input_length) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - switch (operation->alg) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) - case PSA_ALG_MD5: - ret = mbedtls_md5_update(&operation->ctx.md5, - input, input_length); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) - case PSA_ALG_RIPEMD160: - ret = mbedtls_ripemd160_update(&operation->ctx.ripemd160, - input, input_length); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) - case PSA_ALG_SHA_1: - ret = mbedtls_sha1_update(&operation->ctx.sha1, - input, input_length); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) - case PSA_ALG_SHA_224: - ret = mbedtls_sha256_update(&operation->ctx.sha256, - input, input_length); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) - case PSA_ALG_SHA_256: - ret = mbedtls_sha256_update(&operation->ctx.sha256, - input, input_length); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) - case PSA_ALG_SHA_384: - ret = mbedtls_sha512_update(&operation->ctx.sha512, - input, input_length); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) - case PSA_ALG_SHA_512: - ret = mbedtls_sha512_update(&operation->ctx.sha512, - input, input_length); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) - case PSA_ALG_SHA3_224: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) - case PSA_ALG_SHA3_256: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) - case PSA_ALG_SHA3_384: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - case PSA_ALG_SHA3_512: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - ret = mbedtls_sha3_update(&operation->ctx.sha3, - input, input_length); - break; -#endif - default: - (void) input; - (void) input_length; - return PSA_ERROR_BAD_STATE; - } - - return mbedtls_to_psa_error(ret); -} - -psa_status_t mbedtls_psa_hash_finish( - mbedtls_psa_hash_operation_t *operation, - uint8_t *hash, - size_t hash_size, - size_t *hash_length) -{ - psa_status_t status; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t actual_hash_length = PSA_HASH_LENGTH(operation->alg); - - /* Fill the output buffer with something that isn't a valid hash - * (barring an attack on the hash and deliberately-crafted input), - * in case the caller doesn't check the return status properly. */ - *hash_length = hash_size; - /* If hash_size is 0 then hash may be NULL and then the - * call to memset would have undefined behavior. */ - if (hash_size != 0) { - memset(hash, '!', hash_size); - } - - if (hash_size < actual_hash_length) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - switch (operation->alg) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) - case PSA_ALG_MD5: - ret = mbedtls_md5_finish(&operation->ctx.md5, hash); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) - case PSA_ALG_RIPEMD160: - ret = mbedtls_ripemd160_finish(&operation->ctx.ripemd160, hash); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) - case PSA_ALG_SHA_1: - ret = mbedtls_sha1_finish(&operation->ctx.sha1, hash); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) - case PSA_ALG_SHA_224: - ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) - case PSA_ALG_SHA_256: - ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) - case PSA_ALG_SHA_384: - ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) - case PSA_ALG_SHA_512: - ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash); - break; -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) - case PSA_ALG_SHA3_224: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) - case PSA_ALG_SHA3_256: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) - case PSA_ALG_SHA3_384: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - case PSA_ALG_SHA3_512: -#endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512) - ret = mbedtls_sha3_finish(&operation->ctx.sha3, hash, hash_size); - break; -#endif - default: - (void) hash; - return PSA_ERROR_BAD_STATE; - } - status = mbedtls_to_psa_error(ret); - -exit: - if (status == PSA_SUCCESS) { - *hash_length = actual_hash_length; - } - return status; -} - -psa_status_t mbedtls_psa_hash_compute( - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *hash, - size_t hash_size, - size_t *hash_length) -{ - mbedtls_psa_hash_operation_t operation = MBEDTLS_PSA_HASH_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - - *hash_length = hash_size; - status = mbedtls_psa_hash_setup(&operation, alg); - if (status != PSA_SUCCESS) { - goto exit; - } - status = mbedtls_psa_hash_update(&operation, input, input_length); - if (status != PSA_SUCCESS) { - goto exit; - } - status = mbedtls_psa_hash_finish(&operation, hash, hash_size, hash_length); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - abort_status = mbedtls_psa_hash_abort(&operation); - if (status == PSA_SUCCESS) { - return abort_status; - } else { - return status; - } - -} -#endif /* MBEDTLS_PSA_BUILTIN_HASH */ - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_hash.h b/vendor/mbedtls/library/psa_crypto_hash.h deleted file mode 100644 index 0a7be8055..000000000 --- a/vendor/mbedtls/library/psa_crypto_hash.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * PSA hashing layer on top of Mbed TLS software crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_HASH_H -#define PSA_CRYPTO_HASH_H - -#include - -/** Calculate the hash (digest) of a message using Mbed TLS routines. - * - * \note The signature of this function is that of a PSA driver hash_compute - * entry point. This function behaves as a hash_compute entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * \param[in] input Buffer containing the message to hash. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] hash Buffer where the hash is to be written. - * \param hash_size Size of the \p hash buffer in bytes. - * \param[out] hash_length On success, the number of bytes - * that make up the hash value. This is always - * #PSA_HASH_LENGTH(\p alg). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p hash_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_hash_compute( - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *hash, - size_t hash_size, - size_t *hash_length); - -/** Set up a multipart hash operation using Mbed TLS routines. - * - * \note The signature of this function is that of a PSA driver hash_setup - * entry point. This function behaves as a hash_setup entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * If an error occurs at any step after a call to mbedtls_psa_hash_setup(), the - * operation will need to be reset by a call to mbedtls_psa_hash_abort(). The - * core may call mbedtls_psa_hash_abort() at any time after the operation - * has been initialized. - * - * After a successful call to mbedtls_psa_hash_setup(), the core must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to mbedtls_psa_hash_finish() or mbedtls_psa_hash_verify(). - * - A call to mbedtls_psa_hash_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized to all-zero and not yet be in use. - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_hash_setup( - mbedtls_psa_hash_operation_t *operation, - psa_algorithm_t alg); - -/** Clone an Mbed TLS hash operation. - * - * \note The signature of this function is that of a PSA driver hash_clone - * entry point. This function behaves as a hash_clone entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * This function copies the state of an ongoing hash operation to - * a new operation object. In other words, this function is equivalent - * to calling mbedtls_psa_hash_setup() on \p target_operation with the same - * algorithm that \p source_operation was set up for, then - * mbedtls_psa_hash_update() on \p target_operation with the same input that - * that was passed to \p source_operation. After this function returns, the - * two objects are independent, i.e. subsequent calls involving one of - * the objects do not affect the other object. - * - * \param[in] source_operation The active hash operation to clone. - * \param[in,out] target_operation The operation object to set up. - * It must be initialized but not active. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The \p source_operation state is not valid (it must be active). - * \retval #PSA_ERROR_BAD_STATE - * The \p target_operation state is not valid (it must be inactive). - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_hash_clone( - const mbedtls_psa_hash_operation_t *source_operation, - mbedtls_psa_hash_operation_t *target_operation); - -/** Add a message fragment to a multipart Mbed TLS hash operation. - * - * \note The signature of this function is that of a PSA driver hash_update - * entry point. This function behaves as a hash_update entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * The application must call mbedtls_psa_hash_setup() before calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling mbedtls_psa_hash_abort(). - * - * \param[in,out] operation Active hash operation. - * \param[in] input Buffer containing the message fragment to hash. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_hash_update( - mbedtls_psa_hash_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Finish the calculation of the Mbed TLS-calculated hash of a message. - * - * \note The signature of this function is that of a PSA driver hash_finish - * entry point. This function behaves as a hash_finish entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * The application must call mbedtls_psa_hash_setup() before calling this function. - * This function calculates the hash of the message formed by concatenating - * the inputs passed to preceding calls to mbedtls_psa_hash_update(). - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling mbedtls_psa_hash_abort(). - * - * \param[in,out] operation Active hash operation. - * \param[out] hash Buffer where the hash is to be written. - * \param hash_size Size of the \p hash buffer in bytes. - * \param[out] hash_length On success, the number of bytes - * that make up the hash value. This is always - * #PSA_HASH_LENGTH(\c alg) where \c alg is the - * hash algorithm that is calculated. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active). - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p hash buffer is too small. You can determine a - * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) - * where \c alg is the hash algorithm that is calculated. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_hash_finish( - mbedtls_psa_hash_operation_t *operation, - uint8_t *hash, - size_t hash_size, - size_t *hash_length); - -/** Abort an Mbed TLS hash operation. - * - * \note The signature of this function is that of a PSA driver hash_abort - * entry point. This function behaves as a hash_abort entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * mbedtls_psa_hash_setup() again. - * - * You may call this function any time after the operation object has - * been initialized by one of the methods described in #psa_hash_operation_t. - * - * In particular, calling mbedtls_psa_hash_abort() after the operation has been - * terminated by a call to mbedtls_psa_hash_abort(), mbedtls_psa_hash_finish() or - * mbedtls_psa_hash_verify() is safe and has no effect. - * - * \param[in,out] operation Initialized hash operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_hash_abort( - mbedtls_psa_hash_operation_t *operation); - -#endif /* PSA_CRYPTO_HASH_H */ diff --git a/vendor/mbedtls/library/psa_crypto_invasive.h b/vendor/mbedtls/library/psa_crypto_invasive.h deleted file mode 100644 index 51c90c64a..000000000 --- a/vendor/mbedtls/library/psa_crypto_invasive.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * \file psa_crypto_invasive.h - * - * \brief PSA cryptography module: invasive interfaces for test only. - * - * The interfaces in this file are intended for testing purposes only. - * They MUST NOT be made available to clients over IPC in integrations - * with isolation, and they SHOULD NOT be made available in library - * integrations except when building the library for testing. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_INVASIVE_H -#define PSA_CRYPTO_INVASIVE_H - -/* - * Include the build-time configuration information header. Here, we do not - * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which - * is basically just an alias to it. This is to ease the maintenance of the - * TF-PSA-Crypto repository which has a different build system and - * configuration. - */ -#include "psa/build_info.h" - -#include "psa/crypto.h" -#include "common.h" - -#include "mbedtls/entropy.h" - -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -/** \brief Configure entropy sources. - * - * This function may only be called before a call to psa_crypto_init(), - * or after a call to mbedtls_psa_crypto_free() and before any - * subsequent call to psa_crypto_init(). - * - * This function is only intended for test purposes. The functionality - * it provides is also useful for system integrators, but - * system integrators should configure entropy drivers instead of - * breaking through to the Mbed TLS API. - * - * \param entropy_init Function to initialize the entropy context - * and set up the desired entropy sources. - * It is called by psa_crypto_init(). - * By default this is mbedtls_entropy_init(). - * This function cannot report failures directly. - * To indicate a failure, set the entropy context - * to a state where mbedtls_entropy_func() will - * return an error. - * \param entropy_free Function to free the entropy context - * and associated resources. - * It is called by mbedtls_psa_crypto_free(). - * By default this is mbedtls_entropy_free(). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_PERMITTED - * The caller does not have the permission to configure - * entropy sources. - * \retval #PSA_ERROR_BAD_STATE - * The library has already been initialized. - */ -psa_status_t mbedtls_psa_crypto_configure_entropy_sources( - void (* entropy_init)(mbedtls_entropy_context *ctx), - void (* entropy_free)(mbedtls_entropy_context *ctx)); -#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ - -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) -psa_status_t psa_mac_key_can_do( - psa_algorithm_t algorithm, - psa_key_type_t key_type); - -psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, - uint8_t *input_copy, size_t input_copy_len); - -psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, - uint8_t *output, size_t output_len); - -/* - * Test hooks to use for memory unpoisoning/poisoning in copy functions. - */ -extern void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len); -extern void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len); -extern void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len); -extern void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len); - -#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C */ - -#endif /* PSA_CRYPTO_INVASIVE_H */ diff --git a/vendor/mbedtls/library/psa_crypto_its.h b/vendor/mbedtls/library/psa_crypto_its.h deleted file mode 100644 index 877063b87..000000000 --- a/vendor/mbedtls/library/psa_crypto_its.h +++ /dev/null @@ -1,131 +0,0 @@ -/** \file psa_crypto_its.h - * \brief Interface of trusted storage that crypto is built on. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_ITS_H -#define PSA_CRYPTO_ITS_H - -#include -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \brief Flags used when creating a data entry - */ -typedef uint32_t psa_storage_create_flags_t; - -/** \brief A type for UIDs used for identifying data - */ -typedef uint64_t psa_storage_uid_t; - -#define PSA_STORAGE_FLAG_NONE 0 /**< No flags to pass */ -#define PSA_STORAGE_FLAG_WRITE_ONCE (1 << 0) /**< The data associated with the uid will not be able to be modified or deleted. Intended to be used to set bits in `psa_storage_create_flags_t`*/ - -/** - * \brief A container for metadata associated with a specific uid - */ -struct psa_storage_info_t { - uint32_t size; /**< The size of the data associated with a uid **/ - psa_storage_create_flags_t flags; /**< The flags set when the uid was created **/ -}; - -/** Flag indicating that \ref psa_storage_create and \ref psa_storage_set_extended are supported */ -#define PSA_STORAGE_SUPPORT_SET_EXTENDED (1 << 0) - -#define PSA_ITS_API_VERSION_MAJOR 1 /**< The major version number of the PSA ITS API. It will be incremented on significant updates that may include breaking changes */ -#define PSA_ITS_API_VERSION_MINOR 1 /**< The minor version number of the PSA ITS API. It will be incremented in small updates that are unlikely to include breaking changes */ - -/** - * \brief create a new or modify an existing uid/value pair - * - * \param[in] uid the identifier for the data - * \param[in] data_length The size in bytes of the data in `p_data` - * \param[in] p_data A buffer containing the data - * \param[in] create_flags The flags that the data will be stored with - * - * \return A status indicating the success/failure of the operation - * - * \retval #PSA_SUCCESS The operation completed successfully - * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_FLAG_WRITE_ONCE - * \retval #PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium - * \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) - * \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`) - * is invalid, for example is `NULL` or references memory the caller cannot access - */ -psa_status_t psa_its_set(psa_storage_uid_t uid, - uint32_t data_length, - const void *p_data, - psa_storage_create_flags_t create_flags); - -/** - * \brief Retrieve the value associated with a provided uid - * - * \param[in] uid The uid value - * \param[in] data_offset The starting offset of the data requested - * \param[in] data_length the amount of data requested (and the minimum allocated size of the `p_data` buffer) - * \param[out] p_data The buffer where the data will be placed upon successful completion - * \param[out] p_data_length The amount of data returned in the p_data buffer - * - * - * \return A status indicating the success/failure of the operation - * - * \retval #PSA_SUCCESS The operation completed successfully - * \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided `uid` value was not found in the storage - * \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) - * \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted - * \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`, `p_data_length`) - * is invalid. For example is `NULL` or references memory the caller cannot access. - * In addition, this can also happen if an invalid offset was provided. - */ -psa_status_t psa_its_get(psa_storage_uid_t uid, - uint32_t data_offset, - uint32_t data_length, - void *p_data, - size_t *p_data_length); - -/** - * \brief Retrieve the metadata about the provided uid - * - * \param[in] uid The uid value - * \param[out] p_info A pointer to the `psa_storage_info_t` struct that will be populated with the metadata - * - * \return A status indicating the success/failure of the operation - * - * \retval #PSA_SUCCESS The operation completed successfully - * \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage - * \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted - * \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_info`) - * is invalid, for example is `NULL` or references memory the caller cannot access - */ -psa_status_t psa_its_get_info(psa_storage_uid_t uid, - struct psa_storage_info_t *p_info); - -/** - * \brief Remove the provided key and its associated data from the storage - * - * \param[in] uid The uid value - * - * \return A status indicating the success/failure of the operation - * - * \retval #PSA_SUCCESS The operation completed successfully - * \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage - * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_FLAG_WRITE_ONCE - * \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) - */ -psa_status_t psa_its_remove(psa_storage_uid_t uid); - -#ifdef __cplusplus -} -#endif - -#endif /* PSA_CRYPTO_ITS_H */ diff --git a/vendor/mbedtls/library/psa_crypto_mac.c b/vendor/mbedtls/library/psa_crypto_mac.c deleted file mode 100644 index 4464158f9..000000000 --- a/vendor/mbedtls/library/psa_crypto_mac.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * PSA MAC layer on top of Mbed TLS software crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include -#include "psa_crypto_core.h" -#include "psa_crypto_cipher.h" -#include "psa_crypto_mac.h" -#include - -#include -#include "mbedtls/constant_time.h" -#include - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) -static psa_status_t psa_hmac_abort_internal( - mbedtls_psa_hmac_operation_t *hmac) -{ - mbedtls_platform_zeroize(hmac->opad, sizeof(hmac->opad)); - return psa_hash_abort(&hmac->hash_ctx); -} - -static psa_status_t psa_hmac_setup_internal( - mbedtls_psa_hmac_operation_t *hmac, - const uint8_t *key, - size_t key_length, - psa_algorithm_t hash_alg) -{ - uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; - size_t i; - size_t hash_size = PSA_HASH_LENGTH(hash_alg); - size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg); - psa_status_t status; - - hmac->alg = hash_alg; - - /* Sanity checks on block_size, to guarantee that there won't be a buffer - * overflow below. This should never trigger if the hash algorithm - * is implemented correctly. */ - /* The size checks against the ipad and opad buffers cannot be written - * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )` - * because that triggers -Wlogical-op on GCC 7.3. */ - if (block_size > sizeof(ipad)) { - return PSA_ERROR_NOT_SUPPORTED; - } - if (block_size > sizeof(hmac->opad)) { - return PSA_ERROR_NOT_SUPPORTED; - } - if (block_size < hash_size) { - return PSA_ERROR_NOT_SUPPORTED; - } - - if (key_length > block_size) { - status = psa_hash_compute(hash_alg, key, key_length, - ipad, sizeof(ipad), &key_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - } - /* A 0-length key is not commonly used in HMAC when used as a MAC, - * but it is permitted. It is common when HMAC is used in HKDF, for - * example. Don't call `memcpy` in the 0-length because `key` could be - * an invalid pointer which would make the behavior undefined. */ - else if (key_length != 0) { - memcpy(ipad, key, key_length); - } - - /* ipad contains the key followed by garbage. Xor and fill with 0x36 - * to create the ipad value. */ - for (i = 0; i < key_length; i++) { - ipad[i] ^= 0x36; - } - memset(ipad + key_length, 0x36, block_size - key_length); - - /* Copy the key material from ipad to opad, flipping the requisite bits, - * and filling the rest of opad with the requisite constant. */ - for (i = 0; i < key_length; i++) { - hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C; - } - memset(hmac->opad + key_length, 0x5C, block_size - key_length); - - status = psa_hash_setup(&hmac->hash_ctx, hash_alg); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = psa_hash_update(&hmac->hash_ctx, ipad, block_size); - -cleanup: - mbedtls_platform_zeroize(ipad, sizeof(ipad)); - - return status; -} - -static psa_status_t psa_hmac_update_internal( - mbedtls_psa_hmac_operation_t *hmac, - const uint8_t *data, - size_t data_length) -{ - return psa_hash_update(&hmac->hash_ctx, data, data_length); -} - -static psa_status_t psa_hmac_finish_internal( - mbedtls_psa_hmac_operation_t *hmac, - uint8_t *mac, - size_t mac_size) -{ - uint8_t tmp[PSA_HASH_MAX_SIZE]; - psa_algorithm_t hash_alg = hmac->alg; - size_t hash_size = 0; - size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg); - psa_status_t status; - - status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size); - if (status != PSA_SUCCESS) { - return status; - } - /* From here on, tmp needs to be wiped. */ - - status = psa_hash_setup(&hmac->hash_ctx, hash_alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&hmac->hash_ctx, hmac->opad, block_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_update(&hmac->hash_ctx, tmp, hash_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size); - if (status != PSA_SUCCESS) { - goto exit; - } - - memcpy(mac, tmp, mac_size); - -exit: - mbedtls_platform_zeroize(tmp, hash_size); - return status; -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) -static psa_status_t cmac_setup(mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(PSA_WANT_KEY_TYPE_DES) - /* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept - * to do CMAC with pure DES, so return NOT_SUPPORTED here. */ - if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES && - (psa_get_key_bits(attributes) == 64 || - psa_get_key_bits(attributes) == 128)) { - return PSA_ERROR_NOT_SUPPORTED; - } -#endif - - const mbedtls_cipher_info_t *cipher_info = - mbedtls_cipher_info_from_psa( - PSA_ALG_CMAC, - psa_get_key_type(attributes), - psa_get_key_bits(attributes), - NULL); - - if (cipher_info == NULL) { - return PSA_ERROR_NOT_SUPPORTED; - } - - ret = mbedtls_cipher_setup(&operation->ctx.cmac, cipher_info); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_cipher_cmac_starts(&operation->ctx.cmac, - key_buffer, - psa_get_key_bits(attributes)); -exit: - return mbedtls_to_psa_error(ret); -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - -/* Initialize this driver's MAC operation structure. Once this function has been - * called, mbedtls_psa_mac_abort can run and will do the right thing. */ -static psa_status_t mac_init( - mbedtls_psa_mac_operation_t *operation, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - operation->alg = alg; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) { - mbedtls_cipher_init(&operation->ctx.cmac); - status = PSA_SUCCESS; - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if (PSA_ALG_IS_HMAC(operation->alg)) { - /* We'll set up the hash operation later in psa_hmac_setup_internal. */ - operation->ctx.hmac.alg = 0; - status = PSA_SUCCESS; - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - (void) operation; - status = PSA_ERROR_NOT_SUPPORTED; - } - - if (status != PSA_SUCCESS) { - memset(operation, 0, sizeof(*operation)); - } - return status; -} - -psa_status_t mbedtls_psa_mac_abort(mbedtls_psa_mac_operation_t *operation) -{ - if (operation->alg == 0) { - /* The object has (apparently) been initialized but it is not - * in use. It's ok to call abort on such an object, and there's - * nothing to do. */ - return PSA_SUCCESS; - } else -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) { - mbedtls_cipher_free(&operation->ctx.cmac); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if (PSA_ALG_IS_HMAC(operation->alg)) { - psa_hmac_abort_internal(&operation->ctx.hmac); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - /* Sanity check (shouldn't happen: operation->alg should - * always have been initialized to a valid value). */ - goto bad_state; - } - - operation->alg = 0; - - return PSA_SUCCESS; - -bad_state: - /* If abort is called on an uninitialized object, we can't trust - * anything. Wipe the object in case it contains confidential data. - * This may result in a memory leak if a pointer gets overwritten, - * but it's too late to do anything about this. */ - memset(operation, 0, sizeof(*operation)); - return PSA_ERROR_BAD_STATE; -} - -static psa_status_t psa_mac_setup(mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - /* A context must be freshly initialized before it can be set up. */ - if (operation->alg != 0) { - return PSA_ERROR_BAD_STATE; - } - - status = mac_init(operation, alg); - if (status != PSA_SUCCESS) { - return status; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) { - /* Key buffer size for CMAC is dictated by the key bits set on the - * attributes, and previously validated by the core on key import. */ - (void) key_buffer_size; - status = cmac_setup(operation, attributes, key_buffer); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if (PSA_ALG_IS_HMAC(alg)) { - status = psa_hmac_setup_internal(&operation->ctx.hmac, - key_buffer, - key_buffer_size, - PSA_ALG_HMAC_GET_HASH(alg)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - (void) attributes; - (void) key_buffer; - (void) key_buffer_size; - status = PSA_ERROR_NOT_SUPPORTED; - } - - if (status != PSA_SUCCESS) { - mbedtls_psa_mac_abort(operation); - } - - return status; -} - -psa_status_t mbedtls_psa_mac_sign_setup( - mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg) -{ - return psa_mac_setup(operation, attributes, - key_buffer, key_buffer_size, alg); -} - -psa_status_t mbedtls_psa_mac_verify_setup( - mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg) -{ - return psa_mac_setup(operation, attributes, - key_buffer, key_buffer_size, alg); -} - -psa_status_t mbedtls_psa_mac_update( - mbedtls_psa_mac_operation_t *operation, - const uint8_t *input, - size_t input_length) -{ - if (operation->alg == 0) { - return PSA_ERROR_BAD_STATE; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) { - return mbedtls_to_psa_error( - mbedtls_cipher_cmac_update(&operation->ctx.cmac, - input, input_length)); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if (PSA_ALG_IS_HMAC(operation->alg)) { - return psa_hmac_update_internal(&operation->ctx.hmac, - input, input_length); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - /* This shouldn't happen if `operation` was initialized by - * a setup function. */ - (void) input; - (void) input_length; - return PSA_ERROR_BAD_STATE; - } -} - -static psa_status_t psa_mac_finish_internal( - mbedtls_psa_mac_operation_t *operation, - uint8_t *mac, size_t mac_size) -{ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) { - uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE]; - int ret = mbedtls_cipher_cmac_finish(&operation->ctx.cmac, tmp); - if (ret == 0) { - memcpy(mac, tmp, mac_size); - } - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - return mbedtls_to_psa_error(ret); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if (PSA_ALG_IS_HMAC(operation->alg)) { - return psa_hmac_finish_internal(&operation->ctx.hmac, - mac, mac_size); - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - /* This shouldn't happen if `operation` was initialized by - * a setup function. */ - (void) operation; - (void) mac; - (void) mac_size; - return PSA_ERROR_BAD_STATE; - } -} - -psa_status_t mbedtls_psa_mac_sign_finish( - mbedtls_psa_mac_operation_t *operation, - uint8_t *mac, - size_t mac_size, - size_t *mac_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (operation->alg == 0) { - return PSA_ERROR_BAD_STATE; - } - - status = psa_mac_finish_internal(operation, mac, mac_size); - if (status == PSA_SUCCESS) { - *mac_length = mac_size; - } - - return status; -} - -psa_status_t mbedtls_psa_mac_verify_finish( - mbedtls_psa_mac_operation_t *operation, - const uint8_t *mac, - size_t mac_length) -{ - uint8_t actual_mac[PSA_MAC_MAX_SIZE]; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (operation->alg == 0) { - return PSA_ERROR_BAD_STATE; - } - - /* Consistency check: requested MAC length fits our local buffer */ - if (mac_length > sizeof(actual_mac)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - status = psa_mac_finish_internal(operation, actual_mac, mac_length); - if (status != PSA_SUCCESS) { - goto cleanup; - } - - if (mbedtls_ct_memcmp(mac, actual_mac, mac_length) != 0) { - status = PSA_ERROR_INVALID_SIGNATURE; - } - -cleanup: - mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac)); - - return status; -} - -psa_status_t mbedtls_psa_mac_compute( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT; - /* Make sure the whole operation is zeroed. - * PSA_MAC_OPERATION_INIT does not necessarily do it fully, - * since one field is a union and initializing a union does not - * necessarily initialize all of its members. - * In multipart operations, this is done in the API functions, - * before driver dispatch, since it needs to be done before calling - * the driver entry point. Here, we bypass the multipart API, - * so it's our job. */ - memset(&operation, 0, sizeof(operation)); - - status = psa_mac_setup(&operation, - attributes, key_buffer, key_buffer_size, - alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (input_length > 0) { - status = mbedtls_psa_mac_update(&operation, input, input_length); - if (status != PSA_SUCCESS) { - goto exit; - } - } - - status = psa_mac_finish_internal(&operation, mac, mac_size); - if (status == PSA_SUCCESS) { - *mac_length = mac_size; - } - -exit: - mbedtls_psa_mac_abort(&operation); - - return status; -} - -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || MBEDTLS_PSA_BUILTIN_ALG_CMAC */ - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_mac.h b/vendor/mbedtls/library/psa_crypto_mac.h deleted file mode 100644 index 2f614bcc6..000000000 --- a/vendor/mbedtls/library/psa_crypto_mac.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * PSA MAC layer on top of Mbed TLS software crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_MAC_H -#define PSA_CRYPTO_MAC_H - -#include - -/** Calculate the MAC (message authentication code) of a message using Mbed TLS. - * - * \note The signature of this function is that of a PSA driver mac_compute - * entry point. This function behaves as a mac_compute entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key to use for - * computing the MAC. This buffer contains the key - * in export representation as defined by - * psa_export_key() (i.e. the raw key bytes). - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param alg The MAC algorithm to use (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * \param[in] input Buffer containing the input message. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] mac Buffer where the MAC value is to be written. - * \param mac_size Size of the \p mac buffer in bytes. - * \param[out] mac_length On success, the number of bytes - * that make up the MAC value. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p mac_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_mac_compute( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length); - -/** Set up a multipart MAC calculation operation using Mbed TLS. - * - * \note The signature of this function is that of a PSA driver mac_sign_setup - * entry point. This function behaves as a mac_sign_setup entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized and not yet in use. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key to use for - * computing the MAC. This buffer contains the key - * in export representation as defined by - * psa_export_key() (i.e. the raw key bytes). - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param alg The MAC algorithm to use (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive). - */ -psa_status_t mbedtls_psa_mac_sign_setup( - mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg); - -/** Set up a multipart MAC verification operation using Mbed TLS. - * - * \note The signature of this function is that of a PSA driver mac_verify_setup - * entry point. This function behaves as a mac_verify_setup entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized and not yet in use. - * \param[in] attributes The attributes of the key to use for the - * operation. - * \param[in] key_buffer The buffer containing the key to use for - * computing the MAC. This buffer contains the key - * in export representation as defined by - * psa_export_key() (i.e. the raw key bytes). - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param alg The MAC algorithm to use (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive). - */ -psa_status_t mbedtls_psa_mac_verify_setup( - mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg); - -/** Add a message fragment to a multipart MAC operation using Mbed TLS. - * - * \note The signature of this function is that of a PSA driver mac_update - * entry point. This function behaves as a mac_update entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * The PSA core calls mbedtls_psa_mac_sign_setup() or - * mbedtls_psa_mac_verify_setup() before calling this function. - * - * If this function returns an error status, the PSA core aborts the - * operation by calling mbedtls_psa_mac_abort(). - * - * \param[in,out] operation Active MAC operation. - * \param[in] input Buffer containing the message fragment to add to - * the MAC calculation. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_mac_update( - mbedtls_psa_mac_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Finish the calculation of the MAC of a message using Mbed TLS. - * - * \note The signature of this function is that of a PSA driver mac_sign_finish - * entry point. This function behaves as a mac_sign_finish entry point as - * defined in the PSA driver interface specification for transparent - * drivers. - * - * The PSA core calls mbedtls_psa_mac_sign_setup() before calling this function. - * This function calculates the MAC of the message formed by concatenating - * the inputs passed to preceding calls to mbedtls_psa_mac_update(). - * - * Whether this function returns successfully or not, the PSA core subsequently - * aborts the operation by calling mbedtls_psa_mac_abort(). - * - * \param[in,out] operation Active MAC operation. - * \param[out] mac Buffer where the MAC value is to be written. - * \param mac_size Output size requested for the MAC algorithm. The PSA - * core guarantees this is a valid MAC length for the - * algorithm and key combination passed to - * mbedtls_psa_mac_sign_setup(). It also guarantees the - * \p mac buffer is large enough to contain the - * requested output size. - * \param[out] mac_length On success, the number of bytes output to buffer - * \p mac, which will be equal to the requested length - * \p mac_size. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active mac sign - * operation). - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p mac buffer is too small. A sufficient buffer size - * can be determined by calling PSA_MAC_LENGTH(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_mac_sign_finish( - mbedtls_psa_mac_operation_t *operation, - uint8_t *mac, - size_t mac_size, - size_t *mac_length); - -/** Finish the calculation of the MAC of a message and compare it with - * an expected value using Mbed TLS. - * - * \note The signature of this function is that of a PSA driver - * mac_verify_finish entry point. This function behaves as a - * mac_verify_finish entry point as defined in the PSA driver interface - * specification for transparent drivers. - * - * The PSA core calls mbedtls_psa_mac_verify_setup() before calling this - * function. This function calculates the MAC of the message formed by - * concatenating the inputs passed to preceding calls to - * mbedtls_psa_mac_update(). It then compares the calculated MAC with the - * expected MAC passed as a parameter to this function. - * - * Whether this function returns successfully or not, the PSA core subsequently - * aborts the operation by calling mbedtls_psa_mac_abort(). - * - * \param[in,out] operation Active MAC operation. - * \param[in] mac Buffer containing the expected MAC value. - * \param mac_length Length in bytes of the expected MAC value. The PSA - * core guarantees that this length is a valid MAC - * length for the algorithm and key combination passed - * to mbedtls_psa_mac_verify_setup(). - * - * \retval #PSA_SUCCESS - * The expected MAC is identical to the actual MAC of the message. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The MAC of the message was calculated successfully, but it - * differs from the expected MAC. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active mac verify - * operation). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_mac_verify_finish( - mbedtls_psa_mac_operation_t *operation, - const uint8_t *mac, - size_t mac_length); - -/** Abort a MAC operation using Mbed TLS. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * mbedtls_psa_mac_sign_setup() or mbedtls_psa_mac_verify_setup() again. - * - * The PSA core may call this function any time after the operation object has - * been initialized by one of the methods described in - * #mbedtls_psa_mac_operation_t. - * - * In particular, calling mbedtls_psa_mac_abort() after the operation has been - * terminated by a call to mbedtls_psa_mac_abort(), - * mbedtls_psa_mac_sign_finish() or mbedtls_psa_mac_verify_finish() is safe and - * has no effect. - * - * \param[in,out] operation Initialized MAC operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_mac_abort( - mbedtls_psa_mac_operation_t *operation); - -#endif /* PSA_CRYPTO_MAC_H */ diff --git a/vendor/mbedtls/library/psa_crypto_pake.c b/vendor/mbedtls/library/psa_crypto_pake.c deleted file mode 100644 index 9ac2e8c48..000000000 --- a/vendor/mbedtls/library/psa_crypto_pake.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * PSA PAKE layer on top of Mbed TLS software crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include -#include "psa_crypto_core.h" -#include "psa_crypto_pake.h" -#include "psa_crypto_slot_management.h" - -#include -#include "psa_util_internal.h" - -#include -#include -#include - -/* - * State sequence: - * - * psa_pake_setup() - * | - * |-- In any order: - * | | psa_pake_set_password_key() - * | | psa_pake_set_user() - * | | psa_pake_set_peer() - * | | psa_pake_set_role() - * | - * |--- In any order: (First round input before or after first round output) - * | | - * | |------ In Order - * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE) - * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC) - * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF) - * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE) - * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC) - * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF) - * | | - * | |------ In Order: - * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE) - * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC) - * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF) - * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE) - * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC) - * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF) - * | - * |--- In any order: (Second round input before or after second round output) - * | | - * | |------ In Order - * | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE) - * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC) - * | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF) - * | | - * | |------ In Order: - * | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE) - * | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC) - * | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF) - * | - * psa_pake_get_implicit_key() - * psa_pake_abort() - */ - -/* - * Possible sequence of calls to implementation: - * - * |--- In any order: - * | | - * | |------ In Order - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_KEY_SHARE) - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PUBLIC) - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PROOF) - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_KEY_SHARE) - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PUBLIC) - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PROOF) - * | | - * | |------ In Order: - * | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_KEY_SHARE) - * | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PUBLIC) - * | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PROOF) - * | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_KEY_SHARE) - * | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PUBLIC) - * | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PROOF) - * | - * |--- In any order: - * | | - * | |------ In Order - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_KEY_SHARE) - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PUBLIC) - * | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PROOF) - * | | - * | |------ In Order: - * | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_KEY_SHARE) - * | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PUBLIC) - * | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PROOF) - */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) -static psa_status_t mbedtls_ecjpake_to_psa_error(int ret) -{ - switch (ret) { - case MBEDTLS_ERR_MPI_BAD_INPUT_DATA: - case MBEDTLS_ERR_ECP_BAD_INPUT_DATA: - case MBEDTLS_ERR_ECP_INVALID_KEY: - case MBEDTLS_ERR_ECP_VERIFY_FAILED: - return PSA_ERROR_DATA_INVALID; - case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL: - case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL: - return PSA_ERROR_BUFFER_TOO_SMALL; - case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE: - return PSA_ERROR_NOT_SUPPORTED; - case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED: - return PSA_ERROR_CORRUPTION_DETECTED; - default: - return PSA_ERROR_GENERIC_ERROR; - } -} -#endif - -#if defined(MBEDTLS_PSA_BUILTIN_PAKE) -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) -static psa_status_t psa_pake_ecjpake_setup(mbedtls_psa_pake_operation_t *operation) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_ecjpake_init(&operation->ctx.jpake); - - ret = mbedtls_ecjpake_setup(&operation->ctx.jpake, - operation->role, - MBEDTLS_MD_SHA256, - MBEDTLS_ECP_DP_SECP256R1, - operation->password, - operation->password_len); - - mbedtls_platform_zeroize(operation->password, operation->password_len); - - if (ret != 0) { - return mbedtls_ecjpake_to_psa_error(ret); - } - - return PSA_SUCCESS; -} -#endif - -/* The only two JPAKE user/peer identifiers supported in built-in implementation. */ -static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' }; -static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' }; - -psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation, - const psa_crypto_driver_pake_inputs_t *inputs) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t user_len = 0, peer_len = 0, password_len = 0; - uint8_t *peer = NULL, *user = NULL; - size_t actual_user_len = 0, actual_peer_len = 0, actual_password_len = 0; - psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - - status = psa_crypto_driver_pake_get_password_len(inputs, &password_len); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_crypto_driver_pake_get_user_len(inputs, &user_len); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_crypto_driver_pake_get_peer_len(inputs, &peer_len); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_crypto_driver_pake_get_cipher_suite(inputs, &cipher_suite); - if (status != PSA_SUCCESS) { - return status; - } - - operation->password = mbedtls_calloc(1, password_len); - if (operation->password == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; - goto error; - } - - user = mbedtls_calloc(1, user_len); - if (user == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; - goto error; - } - - peer = mbedtls_calloc(1, peer_len); - if (peer == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; - goto error; - } - - status = psa_crypto_driver_pake_get_password(inputs, operation->password, - password_len, &actual_password_len); - if (status != PSA_SUCCESS) { - goto error; - } - - status = psa_crypto_driver_pake_get_user(inputs, user, - user_len, &actual_user_len); - if (status != PSA_SUCCESS) { - goto error; - } - - status = psa_crypto_driver_pake_get_peer(inputs, peer, - peer_len, &actual_peer_len); - if (status != PSA_SUCCESS) { - goto error; - } - - operation->password_len = actual_password_len; - operation->alg = cipher_suite.algorithm; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) - if (cipher_suite.algorithm == PSA_ALG_JPAKE) { - if (cipher_suite.type != PSA_PAKE_PRIMITIVE_TYPE_ECC || - cipher_suite.family != PSA_ECC_FAMILY_SECP_R1 || - cipher_suite.bits != 256 || - cipher_suite.hash != PSA_ALG_SHA_256) { - status = PSA_ERROR_NOT_SUPPORTED; - goto error; - } - - const size_t user_peer_len = sizeof(jpake_client_id); // client and server have the same length - if (actual_user_len != user_peer_len || - actual_peer_len != user_peer_len) { - status = PSA_ERROR_NOT_SUPPORTED; - goto error; - } - - if (memcmp(user, jpake_client_id, actual_user_len) == 0 && - memcmp(peer, jpake_server_id, actual_peer_len) == 0) { - operation->role = MBEDTLS_ECJPAKE_CLIENT; - } else - if (memcmp(user, jpake_server_id, actual_user_len) == 0 && - memcmp(peer, jpake_client_id, actual_peer_len) == 0) { - operation->role = MBEDTLS_ECJPAKE_SERVER; - } else { - status = PSA_ERROR_NOT_SUPPORTED; - goto error; - } - - operation->buffer_length = 0; - operation->buffer_offset = 0; - - status = psa_pake_ecjpake_setup(operation); - if (status != PSA_SUCCESS) { - goto error; - } - - /* Role has been set, release user/peer buffers. */ - mbedtls_free(user); mbedtls_free(peer); - - return PSA_SUCCESS; - } else -#else - (void) operation; - (void) inputs; -#endif - { status = PSA_ERROR_NOT_SUPPORTED; } - -error: - mbedtls_free(user); mbedtls_free(peer); - /* In case of failure of the setup of a multipart operation, the PSA driver interface - * specifies that the core does not call any other driver entry point thus does not - * call mbedtls_psa_pake_abort(). Therefore call it here to do the needed clean - * up like freeing the memory that may have been allocated to store the password. - */ - mbedtls_psa_pake_abort(operation); - return status; -} - -static psa_status_t mbedtls_psa_pake_output_internal( - mbedtls_psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t length; - (void) step; // Unused parameter - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) - /* - * The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different - * handling of output sequencing. - * - * The Mbed TLS JPAKE API outputs the whole X1+X2 and X2S steps data - * at once, on the other side the PSA CRYPTO PAKE api requires - * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be - * retrieved in sequence. - * - * In order to achieve API compatibility, the whole X1+X2 or X2S steps - * data is stored in an intermediate buffer at first step output call, - * and data is sliced down by parsing the ECPoint records in order - * to return the right parts on each step. - */ - if (operation->alg == PSA_ALG_JPAKE) { - /* Initialize & write round on KEY_SHARE sequences */ - if (step == PSA_JPAKE_X1_STEP_KEY_SHARE) { - ret = mbedtls_ecjpake_write_round_one(&operation->ctx.jpake, - operation->buffer, - sizeof(operation->buffer), - &operation->buffer_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE); - if (ret != 0) { - return mbedtls_ecjpake_to_psa_error(ret); - } - - operation->buffer_offset = 0; - } else if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE) { - ret = mbedtls_ecjpake_write_round_two(&operation->ctx.jpake, - operation->buffer, - sizeof(operation->buffer), - &operation->buffer_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE); - if (ret != 0) { - return mbedtls_ecjpake_to_psa_error(ret); - } - - operation->buffer_offset = 0; - } - - /* - * mbedtls_ecjpake_write_round_xxx() outputs thing in the format - * defined by draft-cragie-tls-ecjpake-01 section 7. The summary is - * that the data for each step is prepended with a length byte, and - * then they're concatenated. Additionally, the server's second round - * output is prepended with a 3-bytes ECParameters structure. - * - * In PSA, we output each step separately, and don't prepend the - * output with a length byte, even less a curve identifier, as that - * information is already available. - */ - if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE && - operation->role == MBEDTLS_ECJPAKE_SERVER) { - /* Skip ECParameters, with is 3 bytes (RFC 8422) */ - operation->buffer_offset += 3; - } - - /* Read the length byte then move past it to the data */ - length = operation->buffer[operation->buffer_offset]; - operation->buffer_offset += 1; - - if (operation->buffer_offset + length > operation->buffer_length) { - return PSA_ERROR_DATA_CORRUPT; - } - - if (output_size < length) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(output, - operation->buffer + operation->buffer_offset, - length); - *output_length = length; - - operation->buffer_offset += length; - - /* Reset buffer after ZK_PROOF sequence */ - if ((step == PSA_JPAKE_X2_STEP_ZK_PROOF) || - (step == PSA_JPAKE_X2S_STEP_ZK_PROOF)) { - mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer)); - operation->buffer_length = 0; - operation->buffer_offset = 0; - } - - return PSA_SUCCESS; - } else -#else - (void) step; - (void) output; - (void) output_size; - (void) output_length; -#endif - { return PSA_ERROR_NOT_SUPPORTED; } -} - -psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = mbedtls_psa_pake_output_internal( - operation, step, output, output_size, output_length); - - return status; -} - -static psa_status_t mbedtls_psa_pake_input_internal( - mbedtls_psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - const uint8_t *input, - size_t input_length) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - (void) step; // Unused parameter - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) - /* - * The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different - * handling of input sequencing. - * - * The Mbed TLS JPAKE API takes the whole X1+X2 or X4S steps data - * at once as input, on the other side the PSA CRYPTO PAKE api requires - * the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be - * given in sequence. - * - * In order to achieve API compatibility, each X1+X2 or X4S step data - * is stored sequentially in an intermediate buffer and given to the - * Mbed TLS JPAKE API on the last step. - * - * This causes any input error to be only detected on the last step. - */ - if (operation->alg == PSA_ALG_JPAKE) { - /* - * Copy input to local buffer and format it as the Mbed TLS API - * expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7. - * The summary is that the data for each step is prepended with a - * length byte, and then they're concatenated. Additionally, the - * server's second round output is prepended with a 3-bytes - * ECParameters structure - which means we have to prepend that when - * we're a client. - */ - if (step == PSA_JPAKE_X4S_STEP_KEY_SHARE && - operation->role == MBEDTLS_ECJPAKE_CLIENT) { - /* We only support secp256r1. */ - /* This is the ECParameters structure defined by RFC 8422. */ - unsigned char ecparameters[3] = { - 3, /* named_curve */ - 0, 23 /* secp256r1 */ - }; - - if (operation->buffer_length + sizeof(ecparameters) > - sizeof(operation->buffer)) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(operation->buffer + operation->buffer_length, - ecparameters, sizeof(ecparameters)); - operation->buffer_length += sizeof(ecparameters); - } - - /* - * The core checks that input_length is smaller than - * PSA_PAKE_INPUT_MAX_SIZE. - * Thus no risk of integer overflow here. - */ - if (operation->buffer_length + input_length + 1 > sizeof(operation->buffer)) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - - /* Write the length byte */ - operation->buffer[operation->buffer_length] = (uint8_t) input_length; - operation->buffer_length += 1; - - /* Finally copy the data */ - memcpy(operation->buffer + operation->buffer_length, - input, input_length); - operation->buffer_length += input_length; - - /* Load buffer at each last round ZK_PROOF */ - if (step == PSA_JPAKE_X2_STEP_ZK_PROOF) { - ret = mbedtls_ecjpake_read_round_one(&operation->ctx.jpake, - operation->buffer, - operation->buffer_length); - - mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer)); - operation->buffer_length = 0; - - if (ret != 0) { - return mbedtls_ecjpake_to_psa_error(ret); - } - } else if (step == PSA_JPAKE_X4S_STEP_ZK_PROOF) { - ret = mbedtls_ecjpake_read_round_two(&operation->ctx.jpake, - operation->buffer, - operation->buffer_length); - - mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer)); - operation->buffer_length = 0; - - if (ret != 0) { - return mbedtls_ecjpake_to_psa_error(ret); - } - } - - return PSA_SUCCESS; - } else -#else - (void) step; - (void) input; - (void) input_length; -#endif - { return PSA_ERROR_NOT_SUPPORTED; } -} - -psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - const uint8_t *input, - size_t input_length) -{ - psa_status_t status = mbedtls_psa_pake_input_internal( - operation, step, input, input_length); - - return status; -} - -psa_status_t mbedtls_psa_pake_get_implicit_key( - mbedtls_psa_pake_operation_t *operation, - uint8_t *output, size_t output_size, - size_t *output_length) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) - if (operation->alg == PSA_ALG_JPAKE) { - ret = mbedtls_ecjpake_write_shared_key(&operation->ctx.jpake, - output, - output_size, - output_length, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE); - if (ret != 0) { - return mbedtls_ecjpake_to_psa_error(ret); - } - - return PSA_SUCCESS; - } else -#else - (void) output; -#endif - { return PSA_ERROR_NOT_SUPPORTED; } -} - -psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation) -{ - mbedtls_zeroize_and_free(operation->password, operation->password_len); - operation->password = NULL; - operation->password_len = 0; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE) - if (operation->alg == PSA_ALG_JPAKE) { - operation->role = MBEDTLS_ECJPAKE_NONE; - mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer)); - operation->buffer_length = 0; - operation->buffer_offset = 0; - mbedtls_ecjpake_free(&operation->ctx.jpake); - } -#endif - - operation->alg = PSA_ALG_NONE; - - return PSA_SUCCESS; -} - -#endif /* MBEDTLS_PSA_BUILTIN_PAKE */ - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_pake.h b/vendor/mbedtls/library/psa_crypto_pake.h deleted file mode 100644 index 3d3ee0cc9..000000000 --- a/vendor/mbedtls/library/psa_crypto_pake.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * PSA PAKE layer on top of Mbed TLS software crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_PAKE_H -#define PSA_CRYPTO_PAKE_H - -#include - -/** Set the session information for a password-authenticated key exchange. - * - * \note The signature of this function is that of a PSA driver - * pake_setup entry point. This function behaves as a pake_setup - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized but not set up yet. - * \param[in] inputs Inputs required for PAKE operation (role, password, - * key lifetime, cipher suite) - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The algorithm in \p cipher_suite is not a supported PAKE algorithm, - * or the PAKE primitive in \p cipher_suite is not supported or not - * compatible with the PAKE algorithm, or the hash algorithm in - * \p cipher_suite is not supported or not compatible with the PAKE - * algorithm and primitive. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation, - const psa_crypto_driver_pake_inputs_t *inputs); - - -/** Get output for a step of a password-authenticated key exchange. - * - * \note The signature of this function is that of a PSA driver - * pake_output entry point. This function behaves as a pake_output - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in,out] operation Active PAKE operation. - * \param step The step of the algorithm for which the output is - * requested. - * \param[out] output Buffer where the output is to be written in the - * format appropriate for this driver \p step. Refer to - * the documentation of psa_crypto_driver_pake_step_t for - * more information. - * \param output_size Size of the \p output buffer in bytes. This must - * be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \p - * primitive, \p step) where \p alg and - * \p primitive are the PAKE algorithm and primitive - * in the operation's cipher suite, and \p step is - * the output step. - * - * \param[out] output_length On success, the number of bytes of the returned - * output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - */ -psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Provide input for a step of a password-authenticated key exchange. - * - * \note The signature of this function is that of a PSA driver - * pake_input entry point. This function behaves as a pake_input - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \note The core checks that input_length is smaller than PSA_PAKE_INPUT_MAX_SIZE. - * - * \param[in,out] operation Active PAKE operation. - * \param step The driver step for which the input is provided. - * \param[in] input Buffer containing the input in the format - * appropriate for this \p step. Refer to the - * documentation of psa_crypto_driver_pake_step_t - * for more information. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The verification fails for a zero-knowledge input step. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * the \p input is not valid for the \p operation's algorithm, cipher suite - * or \p step. - * \retval #PSA_ERROR_NOT_SUPPORTED - * the \p input is not supported for the \p operation's algorithm, cipher - * suite or \p step. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - */ -psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation, - psa_crypto_driver_pake_step_t step, - const uint8_t *input, - size_t input_length); - -/** Get implicitly confirmed shared secret from a PAKE. - * - * \note The signature of this function is that of a PSA driver - * pake_get_implicit_key entry point. This function behaves as a - * pake_get_implicit_key entry point as defined in the PSA driver - * interface specification for transparent drivers. - * - * \param[in,out] operation Active PAKE operation. - * \param[out] output Output buffer for implicit key. - * \param output_size Size of the output buffer in bytes. - * \param[out] output_length On success, the number of bytes of the implicit key. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Input from a PAKE is not supported by the algorithm in the \p output - * key derivation operation. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - */ -psa_status_t mbedtls_psa_pake_get_implicit_key( - mbedtls_psa_pake_operation_t *operation, - uint8_t *output, size_t output_size, - size_t *output_length); - -/** Abort a PAKE operation. - * - * \note The signature of this function is that of a PSA driver - * pake_abort entry point. This function behaves as a pake_abort - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in,out] operation The operation to abort. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation); - -#endif /* PSA_CRYPTO_PAKE_H */ diff --git a/vendor/mbedtls/library/psa_crypto_random.c b/vendor/mbedtls/library/psa_crypto_random.c deleted file mode 100644 index af6e5de4b..000000000 --- a/vendor/mbedtls/library/psa_crypto_random.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * PSA crypto random generator. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) && !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - -#include "psa_crypto_core.h" -#include "psa_crypto_random.h" -#include "psa_crypto_random_impl.h" -#include "threading_internal.h" - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) -#include "entropy_poll.h" -#endif - -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) -/* For getpid(), for fork protection */ -#include -#if defined(MBEDTLS_HAVE_TIME) -#include -#else -/* For gettimeofday(), for fork protection without actual entropy */ -#include -#endif -#endif - -void psa_random_internal_init(mbedtls_psa_random_context_t *rng) -{ - /* Set default configuration if - * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */ - if (rng->entropy_init == NULL) { - rng->entropy_init = mbedtls_entropy_init; - } - if (rng->entropy_free == NULL) { - rng->entropy_free = mbedtls_entropy_free; - } - - rng->entropy_init(&rng->entropy); -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ - defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) - /* The PSA entropy injection feature depends on using NV seed as an entropy - * source. Add NV seed as an entropy source for PSA entropy injection. */ - mbedtls_entropy_add_source(&rng->entropy, - mbedtls_nv_seed_poll, NULL, - MBEDTLS_ENTROPY_BLOCK_SIZE, - MBEDTLS_ENTROPY_SOURCE_STRONG); -#endif - - mbedtls_psa_drbg_init(&rng->drbg); -} - -void psa_random_internal_free(mbedtls_psa_random_context_t *rng) -{ - mbedtls_psa_drbg_free(&rng->drbg); - rng->entropy_free(&rng->entropy); -} -psa_status_t psa_random_internal_seed(mbedtls_psa_random_context_t *rng) -{ - const unsigned char drbg_seed[] = "PSA"; - int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy, - drbg_seed, sizeof(drbg_seed) - 1); -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) - rng->pid = getpid(); -#endif - return mbedtls_to_psa_error(ret); -} - -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) -static psa_status_t psa_random_internal_reseed_child( - mbedtls_psa_random_context_t *rng, - intmax_t pid) -{ - /* Reseeding from actual entropy gives the child a unique RNG state - * which the parent process cannot predict, and wipes the - * parent's RNG state from the child. - * - * However, in some library configurations, there is no actual - * entropy source, only a nonvolatile seed (MBEDTLS_ENTROPY_NV_SEED - * enabled and no actual entropy source enabled). In such a - * configuration, the reseed operation is deterministic and - * always injects the same content, so with the DRBG reseed - * process alone, for example, two child processes forked in - * close sequence would end up with the same RNG state. - - * To avoid this, we use a personalization string that has a high - * likelihood of being unique. This way, the child has a unique state. - * The parent can predict the child's RNG state until the next time - * it reseeds or generates some random output, but that's - * unavoidable in the absence of actual entropy. - */ - struct { - /* Using the PID mostly guarantees that each child gets a - * unique state. */ - /* Use intmax_t, not pid_t, because some Unix-like platforms - * don't define pid_t, or more likely nowadays they define - * pid_t but only with certain platform macros which might not - * be the exact ones we use. In practice, this only costs - * a couple of instructions to pass and compare two words - * rather than one. - */ - intmax_t pid; - /* In case an old child had died and its PID is reused for - * a new child of the same process, also include the time. */ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_ms_time_t now; -#else - struct timeval now; -#endif - } perso; - memset(&perso, 0, sizeof(perso)); - perso.pid = pid; -#if defined(MBEDTLS_HAVE_TIME) - perso.now = mbedtls_ms_time(); -#else - /* We don't have mbedtls_ms_time(), but the platform has getpid(). - * Use gettimeofday(), which is a classic Unix function. Modern POSIX - * has stopped requiring gettimeofday() (in favor of clock_gettime()), - * but this is fallback code for restricted configurations, so it's - * more likely to be used on embedded platforms that only have a subset - * of Unix APIs and are more likely to have the classic gettimeofday(). */ - if (gettimeofday(&perso.now, NULL) == -1) { - return PSA_ERROR_INSUFFICIENT_ENTROPY; - } -#endif - int ret = mbedtls_psa_drbg_reseed(&rng->drbg, - (unsigned char *) &perso, sizeof(perso)); - return mbedtls_to_psa_error(ret); -} -#endif /* MBEDTLS_PLATFORM_IS_UNIXLIKE */ - -psa_status_t psa_random_internal_generate( - mbedtls_psa_random_context_t *rng, - uint8_t *output, size_t output_size) -{ -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) - intmax_t pid = getpid(); - if (pid != rng->pid) { - /* This is a (grand...)child of the original process, but - * we inherited the RNG state from our parent. We must reseed! */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - psa_status_t status = psa_random_internal_reseed_child(rng, pid); - if (status == PSA_SUCCESS) { - rng->pid = pid; - } -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - if (status != PSA_SUCCESS) { - return status; - } - } -#endif /* MBEDTLS_PLATFORM_IS_UNIXLIKE */ - - while (output_size > 0) { - size_t request_size = - (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? - MBEDTLS_PSA_RANDOM_MAX_REQUEST : - output_size); -#if defined(MBEDTLS_CTR_DRBG_C) - int ret = mbedtls_ctr_drbg_random(&rng->drbg, output, request_size); -#elif defined(MBEDTLS_HMAC_DRBG_C) - int ret = mbedtls_hmac_drbg_random(&rng->drbg, output, request_size); -#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ - if (ret != 0) { - return mbedtls_to_psa_error(ret); - } - output_size -= request_size; - output += request_size; - } - return PSA_SUCCESS; -} - -#endif /* MBEDTLS_PSA_CRYPTO_C && !MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ diff --git a/vendor/mbedtls/library/psa_crypto_random.h b/vendor/mbedtls/library/psa_crypto_random.h deleted file mode 100644 index 167bb235b..000000000 --- a/vendor/mbedtls/library/psa_crypto_random.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * PSA crypto random generator internal functions. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_RANDOM_H -#define PSA_CRYPTO_RANDOM_H - -#include "common.h" - -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - -#include -#include "psa_crypto_random_impl.h" - -/** Initialize the PSA random generator. - * - * \param[out] rng The random generator context to initialize. - */ -void psa_random_internal_init(mbedtls_psa_random_context_t *rng); - -/** Deinitialize the PSA random generator. - * - * \param[in,out] rng The random generator context to deinitialize. - */ -void psa_random_internal_free(mbedtls_psa_random_context_t *rng); - -/** Seed the PSA random generator. - * - * \note This function is not thread-safe. - * - * \param[in,out] rng The random generator context to seed. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * The entropy source failed. - */ -psa_status_t psa_random_internal_seed(mbedtls_psa_random_context_t *rng); - -/** - * \brief Generate random bytes. Like psa_generate_random(), but for use - * inside the library. - * - * This function is thread-safe. - * - * \warning This function **can** fail! Callers MUST check the return status - * and MUST NOT use the content of the output buffer if the return - * status is not #PSA_SUCCESS. - * - * \param[in,out] rng The random generator context to seed. - * \param[out] output Output buffer for the generated data. - * \param output_size Number of bytes to generate and output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * The random generator needed to reseed, and the entropy - * source failed. - * \retval #PSA_ERROR_HARDWARE_FAILURE - * A hardware accelerator failed. - */ -psa_status_t psa_random_internal_generate( - mbedtls_psa_random_context_t *rng, - uint8_t *output, size_t output_size); - -#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ - -#endif /* PSA_CRYPTO_RANDOM_H */ diff --git a/vendor/mbedtls/library/psa_crypto_random_impl.h b/vendor/mbedtls/library/psa_crypto_random_impl.h deleted file mode 100644 index 68bb3a39f..000000000 --- a/vendor/mbedtls/library/psa_crypto_random_impl.h +++ /dev/null @@ -1,200 +0,0 @@ -/** \file psa_crypto_random_impl.h - * - * \brief PSA crypto random generator implementation abstraction. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_RANDOM_IMPL_H -#define PSA_CRYPTO_RANDOM_IMPL_H - -#include "psa_util_internal.h" - -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - -typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t; - -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - -#include "mbedtls/entropy.h" - -/* Choose a DRBG based on configuration and availability */ -#if defined(MBEDTLS_CTR_DRBG_C) - -#include "mbedtls/ctr_drbg.h" -#undef MBEDTLS_PSA_HMAC_DRBG_MD_TYPE - -#elif defined(MBEDTLS_HMAC_DRBG_C) - -#include "mbedtls/hmac_drbg.h" -#if defined(MBEDTLS_MD_CAN_SHA512) && defined(MBEDTLS_MD_CAN_SHA256) -#include -#if SIZE_MAX > 0xffffffff -/* Looks like a 64-bit system, so prefer SHA-512. */ -#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512 -#else -/* Looks like a 32-bit system, so prefer SHA-256. */ -#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 -#endif -#elif defined(MBEDTLS_MD_CAN_SHA512) -#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512 -#elif defined(MBEDTLS_MD_CAN_SHA256) -#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 -#else -#error "No hash algorithm available for HMAC_DBRG." -#endif - -#else /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/ - -#error "No DRBG module available for the psa_crypto module." - -#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/ - -/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */ -#if defined(MBEDTLS_CTR_DRBG_C) -#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST -#elif defined(MBEDTLS_HMAC_DRBG_C) -#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) -typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t; -#elif defined(MBEDTLS_HMAC_DRBG_C) -typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t; -#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ - -typedef struct { - void (* entropy_init)(mbedtls_entropy_context *ctx); - void (* entropy_free)(mbedtls_entropy_context *ctx); - mbedtls_entropy_context entropy; - mbedtls_psa_drbg_context_t drbg; -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) - /* Fork protection: normally pid = getpid(). If the value changes, - * we are in a (grand)*child of the original process, so reseed - * the RNG to ensure that the child and the original process have - * distinct RNG states. See psa_random_internal_generate(). - * - * The type is intmax_t, not pid_t, for portability reasons: - * pid_t is defined in `unistd.h`, but on some platforms, it may - * only be defined if a certain compatibility level is requested - * by defining a macro such as _POSIX_C_SOURCE or _XOPEN_SOURCE. - * The macro needs to be defined before any system header, which - * may be hard to do in some C files that include this header - * (e.g. test suites). So we sidestep this complication, at the - * cost of possibly a few more instructions to compare pid values. - */ - intmax_t pid; -#endif -} mbedtls_psa_random_context_t; - -/** Initialize the PSA DRBG. - * - * \param p_rng Pointer to the Mbed TLS DRBG state. - */ -static inline void mbedtls_psa_drbg_init(mbedtls_psa_drbg_context_t *p_rng) -{ -#if defined(MBEDTLS_CTR_DRBG_C) - mbedtls_ctr_drbg_init(p_rng); -#elif defined(MBEDTLS_HMAC_DRBG_C) - mbedtls_hmac_drbg_init(p_rng); -#endif -} - -/** Deinitialize the PSA DRBG. - * - * \param p_rng Pointer to the Mbed TLS DRBG state. - */ -static inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t *p_rng) -{ -#if defined(MBEDTLS_CTR_DRBG_C) - mbedtls_ctr_drbg_free(p_rng); -#elif defined(MBEDTLS_HMAC_DRBG_C) - mbedtls_hmac_drbg_free(p_rng); -#endif -} - -/** Seed the PSA DRBG. - * - * \param drbg_ctx The DRBG context to seed. - * It must be initialized but not active. - * \param entropy An entropy context to read the seed from. - * \param custom The personalization string. - * This can be \c NULL, in which case the personalization - * string is empty regardless of the value of \p len. - * \param len The length of the personalization string. - * - * \return \c 0 on success. - * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure. - */ -static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx, - mbedtls_entropy_context *entropy, - const unsigned char *custom, size_t len) -{ -#if defined(MBEDTLS_CTR_DRBG_C) - return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len); -#elif defined(MBEDTLS_HMAC_DRBG_C) - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE); - return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len); -#endif -} - -/** Reseed the PSA DRBG. - * - * \param drbg_ctx The DRBG context to reseed. - * It must be active. - * \param additional Additional data to inject. - * \param len The length of \p additional in bytes. - * This can be 0 to simply reseed from the entropy source. - * - * \return \c 0 on success. - * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure. - */ -static inline int mbedtls_psa_drbg_reseed(mbedtls_psa_drbg_context_t *drbg_ctx, - const unsigned char *additional, - size_t len) -{ -#if defined(MBEDTLS_CTR_DRBG_C) - return mbedtls_ctr_drbg_reseed(drbg_ctx, additional, len); -#elif defined(MBEDTLS_HMAC_DRBG_C) - return mbedtls_hmac_drbg_reseed(drbg_ctx, additional, len); -#endif -} - -/** Deplete the PSA DRBG, i.e. cause it to reseed the next time it is used. - * - * \note This function is not thread-safe. - * - * \param drbg_ctx The DRBG context to deplete. - * It must be active. - */ -static inline void mbedtls_psa_drbg_deplete(mbedtls_psa_drbg_context_t *drbg_ctx) -{ - drbg_ctx->reseed_counter = drbg_ctx->reseed_interval; -} - -#if MBEDTLS_ENTROPY_TRUE_SOURCES > 0 -/** Set prediction resistance in the PSA DRBG. - * - * \note This function is not thread-safe. - * - * \param drbg_ctx The DRBG context to reconfigure. - * It must be active. - * \param enabled \c 1 to enable, or \c 0 to disable. - */ -static inline void mbedtls_psa_drbg_set_prediction_resistance( - mbedtls_psa_drbg_context_t *drbg_ctx, - unsigned enabled) -{ -#if defined(MBEDTLS_CTR_DRBG_C) - mbedtls_ctr_drbg_set_prediction_resistance(drbg_ctx, enabled); -#elif defined(MBEDTLS_HMAC_DRBG_C) - mbedtls_hmac_drbg_set_prediction_resistance(drbg_ctx, enabled); -#endif -} -#endif /* MBEDTLS_ENTROPY_TRUE_SOURCES > 0 */ - -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - -#endif /* PSA_CRYPTO_RANDOM_IMPL_H */ diff --git a/vendor/mbedtls/library/psa_crypto_rsa.c b/vendor/mbedtls/library/psa_crypto_rsa.c deleted file mode 100644 index 38dc3b8ed..000000000 --- a/vendor/mbedtls/library/psa_crypto_rsa.c +++ /dev/null @@ -1,705 +0,0 @@ -/* - * PSA RSA layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include -#include "psa/crypto_values.h" -#include "psa_crypto_core.h" -#include "psa_crypto_random_impl.h" -#include "psa_crypto_rsa.h" -#include "psa_crypto_hash.h" -#include "mbedtls/psa_util.h" - -#include -#include -#include "mbedtls/platform.h" - -#include -#include -#include "rsa_internal.h" - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) - -/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes - * that are not a multiple of 8) well. For example, there is only - * mbedtls_rsa_get_len(), which returns a number of bytes, and no - * way to return the exact bit size of a key. - * To keep things simple, reject non-byte-aligned key sizes. */ -static psa_status_t psa_check_rsa_key_byte_aligned( - const mbedtls_rsa_context *rsa) -{ - mbedtls_mpi n; - psa_status_t status; - mbedtls_mpi_init(&n); - status = mbedtls_to_psa_error( - mbedtls_rsa_export(rsa, &n, NULL, NULL, NULL, NULL)); - if (status == PSA_SUCCESS) { - if (mbedtls_mpi_bitlen(&n) % 8 != 0) { - status = PSA_ERROR_NOT_SUPPORTED; - } - } - mbedtls_mpi_free(&n); - return status; -} - -psa_status_t mbedtls_psa_rsa_load_representation( - psa_key_type_t type, const uint8_t *data, size_t data_length, - mbedtls_rsa_context **p_rsa) -{ - psa_status_t status; - size_t bits; - - *p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context)); - if (*p_rsa == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - mbedtls_rsa_init(*p_rsa); - - /* Parse the data. */ - if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) { - status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length)); - } else { - status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length)); - } - if (status != PSA_SUCCESS) { - goto exit; - } - - /* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS - * supports non-byte-aligned key sizes, but not well. For example, - * mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */ - bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa)); - if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = psa_check_rsa_key_byte_aligned(*p_rsa); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - return status; -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ - -#if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) -psa_status_t mbedtls_psa_rsa_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits) -{ - psa_status_t status; - mbedtls_rsa_context *rsa = NULL; - - /* Parse input */ - status = mbedtls_psa_rsa_load_representation(attributes->type, - data, - data_length, - &rsa); - if (status != PSA_SUCCESS) { - goto exit; - } - - *bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(rsa)); - - /* Re-export the data to PSA export format, such that we can store export - * representation in the key slot. Export representation in case of RSA is - * the smallest representation that's allowed as input, so a straight-up - * allocation of the same size as the input buffer will be large enough. */ - status = mbedtls_psa_rsa_export_key(attributes->type, - rsa, - key_buffer, - key_buffer_size, - key_buffer_length); -exit: - /* Always free the RSA object */ - mbedtls_rsa_free(rsa); - mbedtls_free(rsa); - - return status; -} -#endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ - defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) -psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type, - mbedtls_rsa_context *rsa, - uint8_t *data, - size_t data_size, - size_t *data_length) -{ - int ret; - uint8_t *end = data + data_size; - - /* PSA Crypto API defines the format of an RSA key as a DER-encoded - * representation of the non-encrypted PKCS#1 RSAPrivateKey for a - * private key and of the RFC3279 RSAPublicKey for a public key. */ - if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) { - ret = mbedtls_rsa_write_key(rsa, data, &end); - } else { - ret = mbedtls_rsa_write_pubkey(rsa, data, &end); - } - - if (ret < 0) { - /* Clean up in case pk_write failed halfway through. */ - memset(data, 0, data_size); - return mbedtls_to_psa_error(ret); - } - - /* The mbedtls_pk_xxx functions write to the end of the buffer. - * Move the data to the beginning and erase remaining data - * at the original location. */ - if (2 * (size_t) ret <= data_size) { - memcpy(data, data + data_size - ret, ret); - memset(data + data_size - ret, 0, ret); - } else if ((size_t) ret < data_size) { - memmove(data, data + data_size - ret, ret); - memset(data + ret, 0, data_size - ret); - } - - *data_length = ret; - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_rsa_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_rsa_context *rsa = NULL; - - status = mbedtls_psa_rsa_load_representation( - attributes->type, key_buffer, key_buffer_size, &rsa); - if (status == PSA_SUCCESS) { - status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY, - rsa, - data, - data_size, - data_length); - } - - mbedtls_rsa_free(rsa); - mbedtls_free(rsa); - - return status; -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || - * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) -static psa_status_t psa_rsa_read_exponent(const uint8_t *e_bytes, - size_t e_length, - int *exponent) -{ - size_t i; - uint32_t acc = 0; - - /* Mbed TLS encodes the public exponent as an int. For simplicity, only - * support values that fit in a 32-bit integer, which is larger than - * int on just about every platform anyway. */ - if (e_length > sizeof(acc)) { - return PSA_ERROR_NOT_SUPPORTED; - } - for (i = 0; i < e_length; i++) { - acc = (acc << 8) | e_bytes[i]; - } - if (acc > INT_MAX) { - return PSA_ERROR_NOT_SUPPORTED; - } - *exponent = acc; - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_rsa_generate_key( - const psa_key_attributes_t *attributes, - const uint8_t *custom_data, size_t custom_data_length, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) -{ - psa_status_t status; - mbedtls_rsa_context rsa; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int exponent = 65537; - - if (custom_data_length != 0) { - status = psa_rsa_read_exponent(custom_data, custom_data_length, - &exponent); - if (status != PSA_SUCCESS) { - return status; - } - } - - mbedtls_rsa_init(&rsa); - ret = mbedtls_rsa_gen_key(&rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - (unsigned int) attributes->bits, - exponent); - if (ret != 0) { - mbedtls_rsa_free(&rsa); - return mbedtls_to_psa_error(ret); - } - - status = mbedtls_psa_rsa_export_key(attributes->type, - &rsa, key_buffer, key_buffer_size, - key_buffer_length); - mbedtls_rsa_free(&rsa); - - return status; -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */ - -/****************************************************************/ -/* Sign/verify hashes */ -/****************************************************************/ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) - -/* Decode the hash algorithm from alg and store the mbedtls encoding in - * md_alg. Verify that the hash length is acceptable. */ -static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg, - size_t hash_length, - mbedtls_md_type_t *md_alg) -{ - psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); - *md_alg = mbedtls_md_type_from_psa_alg(hash_alg); - - /* The Mbed TLS RSA module uses an unsigned int for hash length - * parameters. Validate that it fits so that we don't risk an - * overflow later. */ -#if SIZE_MAX > UINT_MAX - if (hash_length > UINT_MAX) { - return PSA_ERROR_INVALID_ARGUMENT; - } -#endif - - /* For signatures using a hash, the hash length must be correct. */ - if (alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW) { - if (*md_alg == MBEDTLS_MD_NONE) { - return PSA_ERROR_NOT_SUPPORTED; - } - if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) { - return PSA_ERROR_INVALID_ARGUMENT; - } - } - - return PSA_SUCCESS; -} - -psa_status_t mbedtls_psa_rsa_sign_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - uint8_t *signature, size_t signature_size, size_t *signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_rsa_context *rsa = NULL; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_type_t md_alg; - - status = mbedtls_psa_rsa_load_representation(attributes->type, - key_buffer, - key_buffer_size, - &rsa); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_rsa_decode_md_type(alg, hash_length, &md_alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (signature_size < mbedtls_rsa_get_len(rsa)) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) - if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) { - ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15, - MBEDTLS_MD_NONE); - if (ret == 0) { - ret = mbedtls_rsa_pkcs1_sign(rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - md_alg, - (unsigned int) hash_length, - hash, - signature); - } - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) - if (PSA_ALG_IS_RSA_PSS(alg)) { - ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg); - - if (ret == 0) { - ret = mbedtls_rsa_rsassa_pss_sign(rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - MBEDTLS_MD_NONE, - (unsigned int) hash_length, - hash, - signature); - } - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - if (ret == 0) { - *signature_length = mbedtls_rsa_get_len(rsa); - } - status = mbedtls_to_psa_error(ret); - -exit: - mbedtls_rsa_free(rsa); - mbedtls_free(rsa); - - return status; -} - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) -static int rsa_pss_expected_salt_len(psa_algorithm_t alg, - const mbedtls_rsa_context *rsa, - size_t hash_length) -{ - if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) { - return MBEDTLS_RSA_SALT_LEN_ANY; - } - /* Otherwise: standard salt length, i.e. largest possible salt length - * up to the hash length. */ - int klen = (int) mbedtls_rsa_get_len(rsa); // known to fit - int hlen = (int) hash_length; // known to fit - int room = klen - 2 - hlen; - if (room < 0) { - return 0; // there is no valid signature in this case anyway - } else if (room > hlen) { - return hlen; - } else { - return room; - } -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ - -psa_status_t mbedtls_psa_rsa_verify_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_rsa_context *rsa = NULL; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_type_t md_alg; - - status = mbedtls_psa_rsa_load_representation(attributes->type, - key_buffer, - key_buffer_size, - &rsa); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_rsa_decode_md_type(alg, hash_length, &md_alg); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (signature_length != mbedtls_rsa_get_len(rsa)) { - status = PSA_ERROR_INVALID_SIGNATURE; - goto exit; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) - if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) { - ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15, - MBEDTLS_MD_NONE); - if (ret == 0) { - ret = mbedtls_rsa_pkcs1_verify(rsa, - md_alg, - (unsigned int) hash_length, - hash, - signature); - } - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) - if (PSA_ALG_IS_RSA_PSS(alg)) { - ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg); - if (ret == 0) { - int slen = rsa_pss_expected_salt_len(alg, rsa, hash_length); - ret = mbedtls_rsa_rsassa_pss_verify_ext(rsa, - md_alg, - (unsigned) hash_length, - hash, - md_alg, - slen, - signature); - } - } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - /* Mbed TLS distinguishes "invalid padding" from "valid padding but - * the rest of the signature is invalid". This has little use in - * practice and PSA doesn't report this distinction. */ - status = (ret == MBEDTLS_ERR_RSA_INVALID_PADDING) ? - PSA_ERROR_INVALID_SIGNATURE : - mbedtls_to_psa_error(ret); - -exit: - mbedtls_rsa_free(rsa); - mbedtls_free(rsa); - - return status; -} - -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ - -/****************************************************************/ -/* Asymmetric cryptography */ -/****************************************************************/ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) -static int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg, - mbedtls_rsa_context *rsa) -{ - psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg); - mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg); - - /* Just to get the error status right, as rsa_set_padding() doesn't - * distinguish between "bad RSA algorithm" and "unknown hash". */ - if (mbedtls_md_info_from_type(md_alg) == NULL) { - return PSA_ERROR_NOT_SUPPORTED; - } - - return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg); -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ - -psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - (void) key_buffer; - (void) key_buffer_size; - (void) input; - (void) input_length; - (void) salt; - (void) salt_length; - (void) output; - (void) output_size; - (void) output_length; - - if (PSA_KEY_TYPE_IS_RSA(attributes->type)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) - mbedtls_rsa_context *rsa = NULL; - status = mbedtls_psa_rsa_load_representation(attributes->type, - key_buffer, - key_buffer_size, - &rsa); - if (status != PSA_SUCCESS) { - goto rsa_exit; - } - - if (output_size < mbedtls_rsa_get_len(rsa)) { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto rsa_exit; - } -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ - if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) - status = mbedtls_to_psa_error( - mbedtls_rsa_pkcs1_encrypt(rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - input_length, - input, - output)); -#else - status = PSA_ERROR_NOT_SUPPORTED; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */ - } else - if (PSA_ALG_IS_RSA_OAEP(alg)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) - status = mbedtls_to_psa_error( - psa_rsa_oaep_set_padding_mode(alg, rsa)); - if (status != PSA_SUCCESS) { - goto rsa_exit; - } - - status = mbedtls_to_psa_error( - mbedtls_rsa_rsaes_oaep_encrypt(rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - salt, salt_length, - input_length, - input, - output)); -#else - status = PSA_ERROR_NOT_SUPPORTED; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */ - } else { - status = PSA_ERROR_INVALID_ARGUMENT; - } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) -rsa_exit: - if (status == PSA_SUCCESS) { - *output_length = mbedtls_rsa_get_len(rsa); - } - - mbedtls_rsa_free(rsa); - mbedtls_free(rsa); -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ - } else { - status = PSA_ERROR_NOT_SUPPORTED; - } - - return status; -} - -psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - (void) key_buffer; - (void) key_buffer_size; - (void) input; - (void) input_length; - (void) salt; - (void) salt_length; - (void) output; - (void) output_size; - (void) output_length; - - *output_length = 0; - - if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) - mbedtls_rsa_context *rsa = NULL; - status = mbedtls_psa_rsa_load_representation(attributes->type, - key_buffer, - key_buffer_size, - &rsa); - if (status != PSA_SUCCESS) { - goto rsa_exit; - } - - if (input_length != mbedtls_rsa_get_len(rsa)) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto rsa_exit; - } -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ - - if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) - status = mbedtls_to_psa_error( - mbedtls_rsa_pkcs1_decrypt(rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - output_length, - input, - output, - output_size)); -#else - status = PSA_ERROR_NOT_SUPPORTED; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */ - } else - if (PSA_ALG_IS_RSA_OAEP(alg)) { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) - status = mbedtls_to_psa_error( - psa_rsa_oaep_set_padding_mode(alg, rsa)); - if (status != PSA_SUCCESS) { - goto rsa_exit; - } - - status = mbedtls_to_psa_error( - mbedtls_rsa_rsaes_oaep_decrypt(rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - salt, salt_length, - output_length, - input, - output, - output_size)); -#else - status = PSA_ERROR_NOT_SUPPORTED; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */ - } else { - status = PSA_ERROR_INVALID_ARGUMENT; - } - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) -rsa_exit: - mbedtls_rsa_free(rsa); - mbedtls_free(rsa); -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || - * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ - } else { - status = PSA_ERROR_NOT_SUPPORTED; - } - - return status; -} - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_rsa.h b/vendor/mbedtls/library/psa_crypto_rsa.h deleted file mode 100644 index 1a780006a..000000000 --- a/vendor/mbedtls/library/psa_crypto_rsa.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - * PSA RSA layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_RSA_H -#define PSA_CRYPTO_RSA_H - -#include -#include - -/** Load the contents of a key buffer into an internal RSA representation - * - * \param[in] type The type of key contained in \p data. - * \param[in] data The buffer from which to load the representation. - * \param[in] data_length The size in bytes of \p data. - * \param[out] p_rsa Returns a pointer to an RSA context on success. - * The caller is responsible for freeing both the - * contents of the context and the context itself - * when done. - */ -psa_status_t mbedtls_psa_rsa_load_representation(psa_key_type_t type, - const uint8_t *data, - size_t data_length, - mbedtls_rsa_context **p_rsa); - -/** Import an RSA key in binary format. - * - * \note The signature of this function is that of a PSA driver - * import_key entry point. This function behaves as an import_key - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes for the key to import. - * \param[in] data The buffer containing the key data in import - * format. - * \param[in] data_length Size of the \p data buffer in bytes. - * \param[out] key_buffer The buffer containing the key data in output - * format. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This - * size is greater or equal to \p data_length. - * \param[out] key_buffer_length The length of the data written in \p - * key_buffer in bytes. - * \param[out] bits The key size in number of bits. - * - * \retval #PSA_SUCCESS The RSA key was imported successfully. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key data is not correctly formatted. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - */ -psa_status_t mbedtls_psa_rsa_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - uint8_t *key_buffer, size_t key_buffer_size, - size_t *key_buffer_length, size_t *bits); - -/** Export an RSA key to export representation - * - * \param[in] type The type of key (public/private) to export - * \param[in] rsa The internal RSA representation from which to export - * \param[out] data The buffer to export to - * \param[in] data_size The length of the buffer to export to - * \param[out] data_length The amount of bytes written to \p data - */ -psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type, - mbedtls_rsa_context *rsa, - uint8_t *data, - size_t data_size, - size_t *data_length); - -/** Export a public RSA key or the public part of an RSA key pair in binary - * format. - * - * \note The signature of this function is that of a PSA driver - * export_public_key entry point. This function behaves as an - * export_public_key entry point as defined in the PSA driver interface - * specification. - * - * \param[in] attributes The attributes for the key to export. - * \param[in] key_buffer Material or context of the key to export. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[out] data Buffer where the key data is to be written. - * \param[in] data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes written in - * \p data. - * - * \retval #PSA_SUCCESS The RSA public key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_rsa_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length); - -/** - * \brief Generate an RSA key. - * - * \param[in] attributes The attributes for the RSA key to generate. - * \param[in] custom_data The public exponent to use. - * This can be a null pointer if - * \c params_data_length is 0. - * \param custom_data_length Length of \p custom_data in bytes. - * This can be 0, in which case the - * public exponent will be 65537. - * \param[out] key_buffer Buffer where the key data is to be written. - * \param[in] key_buffer_size Size of \p key_buffer in bytes. - * \param[out] key_buffer_length On success, the number of bytes written in - * \p key_buffer. - * - * \retval #PSA_SUCCESS - * The key was successfully generated. - * \retval #PSA_ERROR_NOT_SUPPORTED - * Key length or type not supported. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of \p key_buffer is too small. - */ -psa_status_t mbedtls_psa_rsa_generate_key( - const psa_key_attributes_t *attributes, - const uint8_t *custom_data, size_t custom_data_length, - uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); - -/** Sign an already-calculated hash with an RSA private key. - * - * \note The signature of this function is that of a PSA driver - * sign_hash entry point. This function behaves as a sign_hash - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the RSA key to use for the - * operation. - * \param[in] key_buffer The buffer containing the RSA key context. - * format. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * an RSA key. - * \param[in] hash The hash or message to sign. - * \param[in] hash_length Size of the \p hash buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param[in] signature_size Size of the \p signature buffer in bytes. - * \param[out] signature_length On success, the number of bytes - * that make up the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_RSA_KEY_PAIR, \c key_bits, - * \p alg) where \c key_bits is the bit-size of the RSA key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - */ -psa_status_t mbedtls_psa_rsa_sign_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - uint8_t *signature, size_t signature_size, size_t *signature_length); - -/** - * \brief Verify the signature a hash or short message using a public RSA key. - * - * \note The signature of this function is that of a PSA driver - * verify_hash entry point. This function behaves as a verify_hash - * entry point as defined in the PSA driver interface specification for - * transparent drivers. - * - * \param[in] attributes The attributes of the RSA key to use for the - * operation. - * \param[in] key_buffer The buffer containing the RSA key context. - * format. - * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] alg A signature algorithm that is compatible with - * an RSA key. - * \param[in] hash The hash or message whose signature is to be - * verified. - * \param[in] hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param[in] signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The signature is valid. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - */ -psa_status_t mbedtls_psa_rsa_verify_hash( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length); - -/** - * \brief Encrypt a short message with a public key. - * - * \param attributes The attributes for the key to import. - * \param key_buffer Buffer where the key data is to be written. - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] salt A salt or label, if supported by the - * encryption algorithm. - * If the algorithm does not support a - * salt, pass \c NULL. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass \c NULL. - * - * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param salt_length Size of the \p salt buffer in bytes. - * If \p salt is \c NULL, pass 0. - * \param[out] output Buffer where the encrypted message is to - * be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** - * \brief Decrypt a short message with a private key. - * - * \param attributes The attributes for the key to import. - * \param key_buffer Buffer where the key data is to be written. - * \param key_buffer_size Size of the \p key_buffer buffer in bytes. - * \param[in] input The message to decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] salt A salt or label, if supported by the - * encryption algorithm. - * If the algorithm does not support a - * salt, pass \c NULL. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass \c NULL. - * - * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param salt_length Size of the \p salt buffer in bytes. - * If \p salt is \c NULL, pass 0. - * \param[out] output Buffer where the decrypted message is to - * be written. - * \param output_size Size of the \c output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_INVALID_PADDING \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -#endif /* PSA_CRYPTO_RSA_H */ diff --git a/vendor/mbedtls/library/psa_crypto_se.c b/vendor/mbedtls/library/psa_crypto_se.c deleted file mode 100644 index 7a36a4f3a..000000000 --- a/vendor/mbedtls/library/psa_crypto_se.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * PSA crypto support for secure element drivers - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - -#include -#include - -#include "psa/crypto_se_driver.h" - -#include "psa_crypto_se.h" - -#if defined(MBEDTLS_PSA_ITS_FILE_C) -#include "psa_crypto_its.h" -#else /* Native ITS implementation */ -#include "psa/error.h" -#include "psa/internal_trusted_storage.h" -#endif - -#include "mbedtls/platform.h" - - - -/****************************************************************/ -/* Driver lookup */ -/****************************************************************/ - -/* This structure is identical to psa_drv_se_context_t declared in - * `crypto_se_driver.h`, except that some parts are writable here - * (non-const, or pointer to non-const). */ -typedef struct { - void *persistent_data; - size_t persistent_data_size; - uintptr_t transient_data; -} psa_drv_se_internal_context_t; - -struct psa_se_drv_table_entry_s { - psa_key_location_t location; - const psa_drv_se_t *methods; - union { - psa_drv_se_internal_context_t internal; - psa_drv_se_context_t context; - } u; -}; - -static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS]; - -psa_se_drv_table_entry_t *psa_get_se_driver_entry( - psa_key_lifetime_t lifetime) -{ - size_t i; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime); - /* In the driver table, location=0 means an entry that isn't used. - * No driver has a location of 0 because it's a reserved value - * (which designates transparent keys). Make sure we never return - * a driver entry for location 0. */ - if (location == 0) { - return NULL; - } - for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) { - if (driver_table[i].location == location) { - return &driver_table[i]; - } - } - return NULL; -} - -const psa_drv_se_t *psa_get_se_driver_methods( - const psa_se_drv_table_entry_t *driver) -{ - return driver->methods; -} - -psa_drv_se_context_t *psa_get_se_driver_context( - psa_se_drv_table_entry_t *driver) -{ - return &driver->u.context; -} - -int psa_get_se_driver(psa_key_lifetime_t lifetime, - const psa_drv_se_t **p_methods, - psa_drv_se_context_t **p_drv_context) -{ - psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry(lifetime); - if (p_methods != NULL) { - *p_methods = (driver ? driver->methods : NULL); - } - if (p_drv_context != NULL) { - *p_drv_context = (driver ? &driver->u.context : NULL); - } - return driver != NULL; -} - - - -/****************************************************************/ -/* Persistent data management */ -/****************************************************************/ - -static psa_status_t psa_get_se_driver_its_file_uid( - const psa_se_drv_table_entry_t *driver, - psa_storage_uid_t *uid) -{ - if (driver->location > PSA_MAX_SE_LOCATION) { - return PSA_ERROR_NOT_SUPPORTED; - } - - /* ITS file sizes are limited to 32 bits. */ - if (driver->u.internal.persistent_data_size > UINT32_MAX) { - return PSA_ERROR_NOT_SUPPORTED; - } - - /* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */ - *uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location; - return PSA_SUCCESS; -} - -psa_status_t psa_load_se_persistent_data( - const psa_se_drv_table_entry_t *driver) -{ - psa_status_t status; - psa_storage_uid_t uid; - size_t length; - - status = psa_get_se_driver_its_file_uid(driver, &uid); - if (status != PSA_SUCCESS) { - return status; - } - - /* Read the amount of persistent data that the driver requests. - * If the data in storage is larger, it is truncated. If the data - * in storage is smaller, silently keep what is already at the end - * of the output buffer. */ - /* psa_get_se_driver_its_file_uid ensures that the size_t - * persistent_data_size is in range, but compilers don't know that, - * so cast to reassure them. */ - return psa_its_get(uid, 0, - (uint32_t) driver->u.internal.persistent_data_size, - driver->u.internal.persistent_data, - &length); -} - -psa_status_t psa_save_se_persistent_data( - const psa_se_drv_table_entry_t *driver) -{ - psa_status_t status; - psa_storage_uid_t uid; - - status = psa_get_se_driver_its_file_uid(driver, &uid); - if (status != PSA_SUCCESS) { - return status; - } - - /* psa_get_se_driver_its_file_uid ensures that the size_t - * persistent_data_size is in range, but compilers don't know that, - * so cast to reassure them. */ - return psa_its_set(uid, - (uint32_t) driver->u.internal.persistent_data_size, - driver->u.internal.persistent_data, - 0); -} - -psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location) -{ - psa_storage_uid_t uid; - if (location > PSA_MAX_SE_LOCATION) { - return PSA_ERROR_NOT_SUPPORTED; - } - uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location; - return psa_its_remove(uid); -} - -psa_status_t psa_find_se_slot_for_key( - const psa_key_attributes_t *attributes, - psa_key_creation_method_t method, - psa_se_drv_table_entry_t *driver, - psa_key_slot_number_t *slot_number) -{ - psa_status_t status; - psa_key_location_t key_location = - PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)); - - /* If the location is wrong, it's a bug in the library. */ - if (driver->location != key_location) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - - /* If the driver doesn't support key creation in any way, give up now. */ - if (driver->methods->key_management == NULL) { - return PSA_ERROR_NOT_SUPPORTED; - } - - if (psa_get_key_slot_number(attributes, slot_number) == PSA_SUCCESS) { - /* The application wants to use a specific slot. Allow it if - * the driver supports it. On a system with isolation, - * the crypto service must check that the application is - * permitted to request this slot. */ - psa_drv_se_validate_slot_number_t p_validate_slot_number = - driver->methods->key_management->p_validate_slot_number; - if (p_validate_slot_number == NULL) { - return PSA_ERROR_NOT_SUPPORTED; - } - status = p_validate_slot_number(&driver->u.context, - driver->u.internal.persistent_data, - attributes, method, - *slot_number); - } else if (method == PSA_KEY_CREATION_REGISTER) { - /* The application didn't specify a slot number. This doesn't - * make sense when registering a slot. */ - return PSA_ERROR_INVALID_ARGUMENT; - } else { - /* The application didn't tell us which slot to use. Let the driver - * choose. This is the normal case. */ - psa_drv_se_allocate_key_t p_allocate = - driver->methods->key_management->p_allocate; - if (p_allocate == NULL) { - return PSA_ERROR_NOT_SUPPORTED; - } - status = p_allocate(&driver->u.context, - driver->u.internal.persistent_data, - attributes, method, - slot_number); - } - return status; -} - -psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver, - psa_key_slot_number_t slot_number) -{ - psa_status_t status; - psa_status_t storage_status; - /* Normally a missing method would mean that the action is not - * supported. But psa_destroy_key() is not supposed to return - * PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should - * be able to destroy it. The only use case for a driver that - * does not have a way to destroy keys at all is if the keys are - * locked in a read-only state: we can use the keys but not - * destroy them. Hence, if the driver doesn't support destroying - * keys, it's really a lack of permission. */ - if (driver->methods->key_management == NULL || - driver->methods->key_management->p_destroy == NULL) { - return PSA_ERROR_NOT_PERMITTED; - } - status = driver->methods->key_management->p_destroy( - &driver->u.context, - driver->u.internal.persistent_data, - slot_number); - storage_status = psa_save_se_persistent_data(driver); - return status == PSA_SUCCESS ? storage_status : status; -} - -psa_status_t psa_init_all_se_drivers(void) -{ - size_t i; - for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) { - psa_se_drv_table_entry_t *driver = &driver_table[i]; - if (driver->location == 0) { - continue; /* skipping unused entry */ - } - const psa_drv_se_t *methods = psa_get_se_driver_methods(driver); - if (methods->p_init != NULL) { - psa_status_t status = methods->p_init( - &driver->u.context, - driver->u.internal.persistent_data, - driver->location); - if (status != PSA_SUCCESS) { - return status; - } - status = psa_save_se_persistent_data(driver); - if (status != PSA_SUCCESS) { - return status; - } - } - } - return PSA_SUCCESS; -} - - - -/****************************************************************/ -/* Driver registration */ -/****************************************************************/ - -psa_status_t psa_register_se_driver( - psa_key_location_t location, - const psa_drv_se_t *methods) -{ - size_t i; - psa_status_t status; - - if (methods->hal_version != PSA_DRV_SE_HAL_VERSION) { - return PSA_ERROR_NOT_SUPPORTED; - } - /* Driver table entries are 0-initialized. 0 is not a valid driver - * location because it means a transparent key. */ - MBEDTLS_STATIC_ASSERT(PSA_KEY_LOCATION_LOCAL_STORAGE == 0, - "Secure element support requires 0 to mean a local key"); - - if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) { - return PSA_ERROR_INVALID_ARGUMENT; - } - if (location > PSA_MAX_SE_LOCATION) { - return PSA_ERROR_NOT_SUPPORTED; - } - - for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) { - if (driver_table[i].location == 0) { - break; - } - /* Check that location isn't already in use up to the first free - * entry. Since entries are created in order and never deleted, - * there can't be a used entry after the first free entry. */ - if (driver_table[i].location == location) { - return PSA_ERROR_ALREADY_EXISTS; - } - } - if (i == PSA_MAX_SE_DRIVERS) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - driver_table[i].location = location; - driver_table[i].methods = methods; - driver_table[i].u.internal.persistent_data_size = - methods->persistent_data_size; - - if (methods->persistent_data_size != 0) { - driver_table[i].u.internal.persistent_data = - mbedtls_calloc(1, methods->persistent_data_size); - if (driver_table[i].u.internal.persistent_data == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; - goto error; - } - /* Load the driver's persistent data. On first use, the persistent - * data does not exist in storage, and is initialized to - * all-bits-zero by the calloc call just above. */ - status = psa_load_se_persistent_data(&driver_table[i]); - if (status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST) { - goto error; - } - } - - return PSA_SUCCESS; - -error: - memset(&driver_table[i], 0, sizeof(driver_table[i])); - return status; -} - -void psa_unregister_all_se_drivers(void) -{ - size_t i; - for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) { - if (driver_table[i].u.internal.persistent_data != NULL) { - mbedtls_free(driver_table[i].u.internal.persistent_data); - } - } - memset(driver_table, 0, sizeof(driver_table)); -} - - - -/****************************************************************/ -/* The end */ -/****************************************************************/ - -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ diff --git a/vendor/mbedtls/library/psa_crypto_se.h b/vendor/mbedtls/library/psa_crypto_se.h deleted file mode 100644 index e0bd5acfb..000000000 --- a/vendor/mbedtls/library/psa_crypto_se.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * PSA crypto support for secure element drivers - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_SE_H -#define PSA_CRYPTO_SE_H - -/* - * Include the build-time configuration information header. Here, we do not - * include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which - * is basically just an alias to it. This is to ease the maintenance of the - * TF-PSA-Crypto repository which has a different build system and - * configuration. - */ -#include "psa/build_info.h" - -#include "psa/crypto.h" -#include "psa/crypto_se_driver.h" - -/** The maximum location value that this implementation supports - * for a secure element. - * - * This is not a characteristic that each PSA implementation has, but a - * limitation of the current implementation due to the constraints imposed - * by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. - * - * The minimum location value for a secure element is 1, like on any - * PSA implementation (0 means a transparent key). - */ -#define PSA_MAX_SE_LOCATION 255 - -/** The base of the range of ITS file identifiers for secure element - * driver persistent data. - * - * We use a slice of the implementation reserved range 0xffff0000..0xffffffff, - * specifically the range 0xfffffe00..0xfffffeff. The length of this range - * drives the value of #PSA_MAX_SE_LOCATION. The identifier 0xfffffe00 is - * actually not used since it corresponds to #PSA_KEY_LOCATION_LOCAL_STORAGE - * which doesn't have a driver. - */ -#define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ((psa_key_id_t) 0xfffffe00) - -/** The maximum number of registered secure element driver locations. */ -#define PSA_MAX_SE_DRIVERS 4 - -/** Unregister all secure element drivers. - * - * \warning Do not call this function while the library is in the initialized - * state. This function is only intended to be called at the end - * of mbedtls_psa_crypto_free(). - */ -void psa_unregister_all_se_drivers(void); - -/** Initialize all secure element drivers. - * - * Called from psa_crypto_init(). - */ -psa_status_t psa_init_all_se_drivers(void); - -/** A structure that describes a registered secure element driver. - * - * A secure element driver table entry contains a pointer to the - * driver's method table as well as the driver context structure. - */ -typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t; - -/** Return the secure element driver information for a lifetime value. - * - * \param lifetime The lifetime value to query. - * \param[out] p_methods On output, if there is a driver, - * \c *methods points to its method table. - * Otherwise \c *methods is \c NULL. - * \param[out] p_drv_context On output, if there is a driver, - * \c *drv_context points to its context - * structure. - * Otherwise \c *drv_context is \c NULL. - * - * \retval 1 - * \p lifetime corresponds to a registered driver. - * \retval 0 - * \p lifetime does not correspond to a registered driver. - */ -int psa_get_se_driver(psa_key_lifetime_t lifetime, - const psa_drv_se_t **p_methods, - psa_drv_se_context_t **p_drv_context); - -/** Return the secure element driver table entry for a lifetime value. - * - * \param lifetime The lifetime value to query. - * - * \return The driver table entry for \p lifetime, or - * \p NULL if \p lifetime does not correspond to a registered driver. - */ -psa_se_drv_table_entry_t *psa_get_se_driver_entry( - psa_key_lifetime_t lifetime); - -/** Return the method table for a secure element driver. - * - * \param[in] driver The driver table entry to access, or \c NULL. - * - * \return The driver's method table. - * \c NULL if \p driver is \c NULL. - */ -const psa_drv_se_t *psa_get_se_driver_methods( - const psa_se_drv_table_entry_t *driver); - -/** Return the context of a secure element driver. - * - * \param[in] driver The driver table entry to access, or \c NULL. - * - * \return A pointer to the driver context. - * \c NULL if \p driver is \c NULL. - */ -psa_drv_se_context_t *psa_get_se_driver_context( - psa_se_drv_table_entry_t *driver); - -/** Find a free slot for a key that is to be created. - * - * This function calls the relevant method in the driver to find a suitable - * slot for a key with the given attributes. - * - * \param[in] attributes Metadata about the key that is about to be created. - * \param[in] driver The driver table entry to query. - * \param[out] slot_number On success, a slot number that is free in this - * secure element. - */ -psa_status_t psa_find_se_slot_for_key( - const psa_key_attributes_t *attributes, - psa_key_creation_method_t method, - psa_se_drv_table_entry_t *driver, - psa_key_slot_number_t *slot_number); - -/** Destroy a key in a secure element. - * - * This function calls the relevant driver method to destroy a key - * and updates the driver's persistent data. - */ -psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver, - psa_key_slot_number_t slot_number); - -/** Load the persistent data of a secure element driver. - * - * \param driver The driver table entry containing the persistent - * data to load from storage. - * - * \return #PSA_SUCCESS - * \return #PSA_ERROR_NOT_SUPPORTED - * \return #PSA_ERROR_DOES_NOT_EXIST - * \return #PSA_ERROR_STORAGE_FAILURE - * \return #PSA_ERROR_DATA_CORRUPT - * \return #PSA_ERROR_INVALID_ARGUMENT - */ -psa_status_t psa_load_se_persistent_data( - const psa_se_drv_table_entry_t *driver); - -/** Save the persistent data of a secure element driver. - * - * \param[in] driver The driver table entry containing the persistent - * data to save to storage. - * - * \return #PSA_SUCCESS - * \return #PSA_ERROR_NOT_SUPPORTED - * \return #PSA_ERROR_NOT_PERMITTED - * \return #PSA_ERROR_NOT_SUPPORTED - * \return #PSA_ERROR_INSUFFICIENT_STORAGE - * \return #PSA_ERROR_STORAGE_FAILURE - * \return #PSA_ERROR_INVALID_ARGUMENT - */ -psa_status_t psa_save_se_persistent_data( - const psa_se_drv_table_entry_t *driver); - -/** Destroy the persistent data of a secure element driver. - * - * This is currently only used for testing. - * - * \param[in] location The location identifier for the driver whose - * persistent data is to be erased. - */ -psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location); - - -/** The storage representation of a key whose data is in a secure element. - */ -typedef struct { - uint8_t slot_number[sizeof(psa_key_slot_number_t)]; -} psa_se_key_data_storage_t; - -#endif /* PSA_CRYPTO_SE_H */ diff --git a/vendor/mbedtls/library/psa_crypto_slot_management.c b/vendor/mbedtls/library/psa_crypto_slot_management.c deleted file mode 100644 index d514d1af0..000000000 --- a/vendor/mbedtls/library/psa_crypto_slot_management.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * PSA crypto layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_C) - -#include "psa/crypto.h" - -#include "psa_crypto_core.h" -#include "psa_crypto_driver_wrappers_no_static.h" -#include "psa_crypto_slot_management.h" -#include "psa_crypto_storage.h" -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -#include "psa_crypto_se.h" -#endif - -#include -#include -#include "mbedtls/platform.h" -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - - - -/* Make sure we have distinct ranges of key identifiers for distinct - * purposes. */ -MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_USER_MIN < PSA_KEY_ID_USER_MAX, - "Empty user key ID range"); -MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN < PSA_KEY_ID_VENDOR_MAX, - "Empty vendor key ID range"); -MBEDTLS_STATIC_ASSERT(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN <= MBEDTLS_PSA_KEY_ID_BUILTIN_MAX, - "Empty builtin key ID range"); -MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MIN <= PSA_KEY_ID_VOLATILE_MAX, - "Empty volatile key ID range"); - -MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_USER_MAX < PSA_KEY_ID_VENDOR_MIN || - PSA_KEY_ID_VENDOR_MAX < PSA_KEY_ID_USER_MIN, - "Overlap between user key IDs and vendor key IDs"); - -MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN <= MBEDTLS_PSA_KEY_ID_BUILTIN_MIN && - MBEDTLS_PSA_KEY_ID_BUILTIN_MAX <= PSA_KEY_ID_VENDOR_MAX, - "Builtin key identifiers are not in the vendor range"); - -MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VENDOR_MIN <= PSA_KEY_ID_VOLATILE_MIN && - PSA_KEY_ID_VOLATILE_MAX <= PSA_KEY_ID_VENDOR_MAX, - "Volatile key identifiers are not in the vendor range"); - -MBEDTLS_STATIC_ASSERT(PSA_KEY_ID_VOLATILE_MAX < MBEDTLS_PSA_KEY_ID_BUILTIN_MIN || - MBEDTLS_PSA_KEY_ID_BUILTIN_MAX < PSA_KEY_ID_VOLATILE_MIN, - "Overlap between builtin key IDs and volatile key IDs"); - - - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - -/* Dynamic key store. - * - * The key store consists of multiple slices. - * - * The volatile keys are stored in variable-sized tables called slices. - * Slices are allocated on demand and deallocated when possible. - * The size of slices increases exponentially, so the average overhead - * (number of slots that are allocated but not used) is roughly - * proportional to the number of keys (with a factor that grows - * when the key store is fragmented). - * - * One slice is dedicated to the cache of persistent and built-in keys. - * For simplicity, they are separated from volatile keys. This cache - * slice has a fixed size and has the slice index KEY_SLOT_CACHE_SLICE_INDEX, - * located after the slices for volatile keys. - */ - -/* Size of the last slice containing the cache of persistent and built-in keys. */ -#define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT - -/* Volatile keys are stored in slices 0 through - * (KEY_SLOT_VOLATILE_SLICE_COUNT - 1) inclusive. - * Each slice is twice the size of the previous slice. - * Volatile key identifiers encode the slice number as follows: - * bits 30..31: 0b10 (mandated by the PSA Crypto specification). - * bits 25..29: slice index (0...KEY_SLOT_VOLATILE_SLICE_COUNT-1) - * bits 0..24: slot index in slice - */ -#define KEY_ID_SLOT_INDEX_WIDTH 25u -#define KEY_ID_SLICE_INDEX_WIDTH 5u - -#define KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH 16u -#define KEY_SLOT_VOLATILE_SLICE_COUNT 22u -#define KEY_SLICE_COUNT (KEY_SLOT_VOLATILE_SLICE_COUNT + 1u) -#define KEY_SLOT_CACHE_SLICE_INDEX KEY_SLOT_VOLATILE_SLICE_COUNT - - -/* Check that the length of the largest slice (calculated as - * KEY_SLICE_LENGTH_MAX below) does not overflow size_t. We use - * an indirect method in case the calculation of KEY_SLICE_LENGTH_MAX - * itself overflows uintmax_t: if (BASE_LENGTH << c) - * overflows size_t then BASE_LENGTH > SIZE_MAX >> c. - */ -#if (KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH > \ - SIZE_MAX >> (KEY_SLOT_VOLATILE_SLICE_COUNT - 1)) -#error "Maximum slice length overflows size_t" -#endif - -#if KEY_ID_SLICE_INDEX_WIDTH + KEY_ID_SLOT_INDEX_WIDTH > 30 -#error "Not enough room in volatile key IDs for slice index and slot index" -#endif -#if KEY_SLOT_VOLATILE_SLICE_COUNT > (1 << KEY_ID_SLICE_INDEX_WIDTH) -#error "Too many slices to fit the slice index in a volatile key ID" -#endif -#define KEY_SLICE_LENGTH_MAX \ - (KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH << (KEY_SLOT_VOLATILE_SLICE_COUNT - 1)) -#if KEY_SLICE_LENGTH_MAX > 1 << KEY_ID_SLOT_INDEX_WIDTH -#error "Not enough room in volatile key IDs for a slot index in the largest slice" -#endif -#if KEY_ID_SLICE_INDEX_WIDTH > 8 -#error "Slice index does not fit in uint8_t for psa_key_slot_t::slice_index" -#endif - - -/* Calculate the volatile key id to use for a given slot. - * This function assumes valid parameter values. */ -static psa_key_id_t volatile_key_id_of_index(size_t slice_idx, - size_t slot_idx) -{ - /* We assert above that the slice and slot indexes fit in separate - * bit-fields inside psa_key_id_t, which is a 32-bit type per the - * PSA Cryptography specification. */ - return (psa_key_id_t) (0x40000000u | - (slice_idx << KEY_ID_SLOT_INDEX_WIDTH) | - slot_idx); -} - -/* Calculate the slice containing the given volatile key. - * This function assumes valid parameter values. */ -static size_t slice_index_of_volatile_key_id(psa_key_id_t key_id) -{ - size_t mask = (1LU << KEY_ID_SLICE_INDEX_WIDTH) - 1; - return (key_id >> KEY_ID_SLOT_INDEX_WIDTH) & mask; -} - -/* Calculate the index of the slot containing the given volatile key. - * This function assumes valid parameter values. */ -static size_t slot_index_of_volatile_key_id(psa_key_id_t key_id) -{ - return key_id & ((1LU << KEY_ID_SLOT_INDEX_WIDTH) - 1); -} - -/* In global_data.first_free_slot_index, use this special value to - * indicate that the slice is full. */ -#define FREE_SLOT_INDEX_NONE ((size_t) -1) - -#if defined(MBEDTLS_TEST_HOOKS) -size_t psa_key_slot_volatile_slice_count(void) -{ - return KEY_SLOT_VOLATILE_SLICE_COUNT; -} -#endif - -#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - -/* Static key store. - * - * All the keys (volatile or persistent) are in a single slice. - * We only use slices as a concept to allow some differences between - * static and dynamic key store management to be buried in auxiliary - * functions. - */ - -#define PERSISTENT_KEY_CACHE_COUNT MBEDTLS_PSA_KEY_SLOT_COUNT -#define KEY_SLICE_COUNT 1u -#define KEY_SLOT_CACHE_SLICE_INDEX 0 - -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - -typedef struct { -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - psa_key_slot_t *key_slices[KEY_SLICE_COUNT]; - size_t first_free_slot_index[KEY_SLOT_VOLATILE_SLICE_COUNT]; -#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT]; -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - uint8_t key_slots_initialized; -} psa_global_data_t; - -static psa_global_data_t global_data; - -static uint8_t psa_get_key_slots_initialized(void) -{ - uint8_t initialized; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - initialized = global_data.key_slots_initialized; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - return initialized; -} - - - -/** The length of the given slice in the key slot table. - * - * \param slice_idx The slice number. It must satisfy - * 0 <= slice_idx < KEY_SLICE_COUNT. - * - * \return The number of elements in the given slice. - */ -static inline size_t key_slice_length(size_t slice_idx); - -/** Get a pointer to the slot where the given volatile key is located. - * - * \param key_id The key identifier. It must be a valid volatile key - * identifier. - * \return A pointer to the only slot that the given key - * can be in. Note that the slot may be empty or - * contain a different key. - */ -static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id); - -/** Get a pointer to an entry in the persistent key cache. - * - * \param slot_idx The index in the table. It must satisfy - * 0 <= slot_idx < PERSISTENT_KEY_CACHE_COUNT. - * \return A pointer to the slot containing the given - * persistent key cache entry. - */ -static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx); - -/** Get a pointer to a slot given by slice and index. - * - * \param slice_idx The slice number. It must satisfy - * 0 <= slice_idx < KEY_SLICE_COUNT. - * \param slot_idx An index in the given slice. It must satisfy - * 0 <= slot_idx < key_slice_length(slice_idx). - * - * \return A pointer to the given slot. - */ -static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx); - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - -#if defined(MBEDTLS_TEST_HOOKS) -size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(size_t slice_idx) = NULL; -#endif - -static inline size_t key_slice_length(size_t slice_idx) -{ - if (slice_idx == KEY_SLOT_CACHE_SLICE_INDEX) { - return PERSISTENT_KEY_CACHE_COUNT; - } else { -#if defined(MBEDTLS_TEST_HOOKS) - if (mbedtls_test_hook_psa_volatile_key_slice_length != NULL) { - return mbedtls_test_hook_psa_volatile_key_slice_length(slice_idx); - } -#endif - return KEY_SLOT_VOLATILE_SLICE_BASE_LENGTH << slice_idx; - } -} - -static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id) -{ - size_t slice_idx = slice_index_of_volatile_key_id(key_id); - if (slice_idx >= KEY_SLOT_VOLATILE_SLICE_COUNT) { - return NULL; - } - size_t slot_idx = slot_index_of_volatile_key_id(key_id); - if (slot_idx >= key_slice_length(slice_idx)) { - return NULL; - } - psa_key_slot_t *slice = global_data.key_slices[slice_idx]; - if (slice == NULL) { - return NULL; - } - return &slice[slot_idx]; -} - -static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx) -{ - return &global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX][slot_idx]; -} - -static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx) -{ - return &global_data.key_slices[slice_idx][slot_idx]; -} - -#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - -static inline size_t key_slice_length(size_t slice_idx) -{ - (void) slice_idx; - return ARRAY_LENGTH(global_data.key_slots); -} - -static inline psa_key_slot_t *get_volatile_key_slot(psa_key_id_t key_id) -{ - MBEDTLS_STATIC_ASSERT(ARRAY_LENGTH(global_data.key_slots) <= - PSA_KEY_ID_VOLATILE_MAX - PSA_KEY_ID_VOLATILE_MIN + 1, - "The key slot array is larger than the volatile key ID range"); - return &global_data.key_slots[key_id - PSA_KEY_ID_VOLATILE_MIN]; -} - -static inline psa_key_slot_t *get_persistent_key_slot(size_t slot_idx) -{ - return &global_data.key_slots[slot_idx]; -} - -static inline psa_key_slot_t *get_key_slot(size_t slice_idx, size_t slot_idx) -{ - (void) slice_idx; - return &global_data.key_slots[slot_idx]; -} - -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - - -int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok) -{ - psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key); - - if ((PSA_KEY_ID_USER_MIN <= key_id) && - (key_id <= PSA_KEY_ID_USER_MAX)) { - return 1; - } - - if (vendor_ok && - (PSA_KEY_ID_VENDOR_MIN <= key_id) && - (key_id <= PSA_KEY_ID_VENDOR_MAX)) { - return 1; - } - - return 0; -} - -/** Get the description in memory of a key given its identifier and lock it. - * - * The descriptions of volatile keys and loaded persistent keys are - * stored in key slots. This function returns a pointer to the key slot - * containing the description of a key given its identifier. - * - * The function searches the key slots containing the description of the key - * with \p key identifier. The function does only read accesses to the key - * slots. The function does not load any persistent key thus does not access - * any storage. - * - * For volatile key identifiers, only one key slot is queried as a volatile - * key with identifier key_id can only be stored in slot of index - * ( key_id - #PSA_KEY_ID_VOLATILE_MIN ). - * - * On success, the function locks the key slot. It is the responsibility of - * the caller to unlock the key slot when it does not access it anymore. - * - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \param key Key identifier to query. - * \param[out] p_slot On success, `*p_slot` contains a pointer to the - * key slot containing the description of the key - * identified by \p key. - * - * \retval #PSA_SUCCESS - * The pointer to the key slot containing the description of the key - * identified by \p key was returned. - * \retval #PSA_ERROR_INVALID_HANDLE - * \p key is not a valid key identifier. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * There is no key with key identifier \p key in the key slots. - */ -static psa_status_t psa_get_and_lock_key_slot_in_memory( - mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key); - size_t slot_idx; - psa_key_slot_t *slot = NULL; - - if (psa_key_id_is_volatile(key_id)) { - slot = get_volatile_key_slot(key_id); - - /* Check if both the PSA key identifier key_id and the owner - * identifier of key match those of the key slot. */ - if (slot != NULL && - slot->state == PSA_SLOT_FULL && - mbedtls_svc_key_id_equal(key, slot->attr.id)) { - status = PSA_SUCCESS; - } else { - status = PSA_ERROR_DOES_NOT_EXIST; - } - } else { - if (!psa_is_valid_key_id(key, 1)) { - return PSA_ERROR_INVALID_HANDLE; - } - - for (slot_idx = 0; slot_idx < PERSISTENT_KEY_CACHE_COUNT; slot_idx++) { - slot = get_persistent_key_slot(slot_idx); - /* Only consider slots which are in a full state. */ - if ((slot->state == PSA_SLOT_FULL) && - (mbedtls_svc_key_id_equal(key, slot->attr.id))) { - break; - } - } - status = (slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT) ? - PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST; - } - - if (status == PSA_SUCCESS) { - status = psa_register_read(slot); - if (status == PSA_SUCCESS) { - *p_slot = slot; - } - } - - return status; -} - -psa_status_t psa_initialize_key_slots(void) -{ -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX] = - mbedtls_calloc(PERSISTENT_KEY_CACHE_COUNT, - sizeof(*global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX])); - if (global_data.key_slices[KEY_SLOT_CACHE_SLICE_INDEX] == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } -#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - /* Nothing to do: program startup and psa_wipe_all_key_slots() both - * guarantee that the key slots are initialized to all-zero, which - * means that all the key slots are in a valid, empty state. The global - * data mutex is already held when calling this function, so no need to - * lock it here, to set the flag. */ -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - global_data.key_slots_initialized = 1; - return PSA_SUCCESS; -} - -void psa_wipe_all_key_slots(void) -{ - for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) { -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - if (global_data.key_slices[slice_idx] == NULL) { - continue; - } -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { - psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - /* When MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled, calling - * psa_wipe_key_slot() on an unused slot is useless, but it - * happens to work (because we flip the state to PENDING_DELETION). - * - * When MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, - * psa_wipe_key_slot() needs to have a valid slice_index - * field, but that value might not be correct in a - * free slot, so we must not call it. - * - * Bypass the call to psa_wipe_key_slot() if the slot is empty, - * but only if MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, to save - * a few bytes of code size otherwise. - */ - if (slot->state == PSA_SLOT_EMPTY) { - continue; - } -#endif - slot->var.occupied.registered_readers = 1; - slot->state = PSA_SLOT_PENDING_DELETION; - (void) psa_wipe_key_slot(slot); - } -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - mbedtls_free(global_data.key_slices[slice_idx]); - global_data.key_slices[slice_idx] = NULL; -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - } - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - for (size_t slice_idx = 0; slice_idx < KEY_SLOT_VOLATILE_SLICE_COUNT; slice_idx++) { - global_data.first_free_slot_index[slice_idx] = 0; - } -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - /* The global data mutex is already held when calling this function. */ - global_data.key_slots_initialized = 0; -} - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - -static psa_status_t psa_allocate_volatile_key_slot(psa_key_id_t *key_id, - psa_key_slot_t **p_slot) -{ - size_t slice_idx; - for (slice_idx = 0; slice_idx < KEY_SLOT_VOLATILE_SLICE_COUNT; slice_idx++) { - if (global_data.first_free_slot_index[slice_idx] != FREE_SLOT_INDEX_NONE) { - break; - } - } - if (slice_idx == KEY_SLOT_VOLATILE_SLICE_COUNT) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - if (global_data.key_slices[slice_idx] == NULL) { - global_data.key_slices[slice_idx] = - mbedtls_calloc(key_slice_length(slice_idx), - sizeof(psa_key_slot_t)); - if (global_data.key_slices[slice_idx] == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - } - psa_key_slot_t *slice = global_data.key_slices[slice_idx]; - - size_t slot_idx = global_data.first_free_slot_index[slice_idx]; - *key_id = volatile_key_id_of_index(slice_idx, slot_idx); - - psa_key_slot_t *slot = &slice[slot_idx]; - size_t next_free = slot_idx + 1 + slot->var.free.next_free_relative_to_next; - if (next_free >= key_slice_length(slice_idx)) { - next_free = FREE_SLOT_INDEX_NONE; - } - global_data.first_free_slot_index[slice_idx] = next_free; - /* The .next_free field is not meaningful when the slot is not free, - * so give it the same content as freshly initialized memory. */ - slot->var.free.next_free_relative_to_next = 0; - - psa_status_t status = psa_key_slot_state_transition(slot, - PSA_SLOT_EMPTY, - PSA_SLOT_FILLING); - if (status != PSA_SUCCESS) { - /* The only reason for failure is if the slot state was not empty. - * This indicates that something has gone horribly wrong. - * In this case, we leave the slot out of the free list, and stop - * modifying it. This minimizes any further corruption. The slot - * is a memory leak, but that's a lesser evil. */ - return status; - } - - *p_slot = slot; - /* We assert at compile time that the slice index fits in uint8_t. */ - slot->slice_index = (uint8_t) slice_idx; - return PSA_SUCCESS; -} - -psa_status_t psa_free_key_slot(size_t slice_idx, - psa_key_slot_t *slot) -{ - - if (slice_idx == KEY_SLOT_CACHE_SLICE_INDEX) { - /* This is a cache entry. We don't maintain a free list, so - * there's nothing to do. */ - return PSA_SUCCESS; - } - if (slice_idx >= KEY_SLOT_VOLATILE_SLICE_COUNT) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - - psa_key_slot_t *slice = global_data.key_slices[slice_idx]; - psa_key_slot_t *slice_end = slice + key_slice_length(slice_idx); - if (slot < slice || slot >= slice_end) { - /* The slot isn't actually in the slice! We can't detect that - * condition for sure, because the pointer comparison itself is - * undefined behavior in that case. That same condition makes the - * subtraction to calculate the slot index also UB. - * Give up now to avoid causing further corruption. - */ - return PSA_ERROR_CORRUPTION_DETECTED; - } - size_t slot_idx = slot - slice; - - size_t next_free = global_data.first_free_slot_index[slice_idx]; - if (next_free >= key_slice_length(slice_idx)) { - /* The slot was full. The newly freed slot thus becomes the - * end of the free list. */ - next_free = key_slice_length(slice_idx); - } - global_data.first_free_slot_index[slice_idx] = slot_idx; - slot->var.free.next_free_relative_to_next = - (int32_t) next_free - (int32_t) slot_idx - 1; - - return PSA_SUCCESS; -} -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - -psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, - psa_key_slot_t **p_slot) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t slot_idx; - psa_key_slot_t *selected_slot, *unused_persistent_key_slot; - - if (!psa_get_key_slots_initialized()) { - status = PSA_ERROR_BAD_STATE; - goto error; - } - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - if (volatile_key_id != NULL) { - return psa_allocate_volatile_key_slot(volatile_key_id, p_slot); - } -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - - /* With a dynamic key store, allocate an entry in the cache slice, - * applicable only to non-volatile keys that get cached in RAM. - * With a static key store, allocate an entry in the sole slice, - * applicable to all keys. */ - selected_slot = unused_persistent_key_slot = NULL; - for (slot_idx = 0; slot_idx < PERSISTENT_KEY_CACHE_COUNT; slot_idx++) { - psa_key_slot_t *slot = get_key_slot(KEY_SLOT_CACHE_SLICE_INDEX, slot_idx); - if (slot->state == PSA_SLOT_EMPTY) { - selected_slot = slot; - break; - } - - if ((unused_persistent_key_slot == NULL) && - (slot->state == PSA_SLOT_FULL) && - (!psa_key_slot_has_readers(slot)) && - (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime))) { - unused_persistent_key_slot = slot; - } - } - - /* - * If there is no unused key slot and there is at least one unlocked key - * slot containing the description of a persistent key, recycle the first - * such key slot we encountered. If we later need to operate on the - * persistent key we are evicting now, we will reload its description from - * storage. - */ - if ((selected_slot == NULL) && - (unused_persistent_key_slot != NULL)) { - selected_slot = unused_persistent_key_slot; - psa_register_read(selected_slot); - status = psa_wipe_key_slot(selected_slot); - if (status != PSA_SUCCESS) { - goto error; - } - } - - if (selected_slot != NULL) { - status = psa_key_slot_state_transition(selected_slot, PSA_SLOT_EMPTY, - PSA_SLOT_FILLING); - if (status != PSA_SUCCESS) { - goto error; - } - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - selected_slot->slice_index = KEY_SLOT_CACHE_SLICE_INDEX; -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - -#if !defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - if (volatile_key_id != NULL) { - /* Refresh slot_idx, for when the slot is not the original - * selected_slot but rather unused_persistent_key_slot. */ - slot_idx = selected_slot - global_data.key_slots; - *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + (psa_key_id_t) slot_idx; - } -#endif - *p_slot = selected_slot; - - return PSA_SUCCESS; - } - status = PSA_ERROR_INSUFFICIENT_MEMORY; - -error: - *p_slot = NULL; - - return status; -} - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) -static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot) -{ - psa_status_t status = PSA_SUCCESS; - uint8_t *key_data = NULL; - size_t key_data_length = 0; - psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); - - /* Do not try to load a persistent key whose ID is in the volatile range. */ - if ((key_id >= PSA_KEY_ID_VOLATILE_MIN) && (key_id <= PSA_KEY_ID_VOLATILE_MAX)) { - return PSA_ERROR_DOES_NOT_EXIST; - } - - status = psa_load_persistent_key(&slot->attr, - &key_data, &key_data_length); - if (status != PSA_SUCCESS) { - goto exit; - } - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* Special handling is required for loading keys associated with a - * dynamically registered SE interface. */ - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; - if (psa_get_se_driver(slot->attr.lifetime, &drv, &drv_context)) { - psa_se_key_data_storage_t *data; - - if (key_data_length != sizeof(*data)) { - status = PSA_ERROR_DATA_INVALID; - goto exit; - } - data = (psa_se_key_data_storage_t *) key_data; - status = psa_copy_key_material_into_slot( - slot, data->slot_number, sizeof(data->slot_number)); - goto exit; - } -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - status = psa_copy_key_material_into_slot(slot, key_data, key_data_length); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: - psa_free_persistent_key_data(key_data, key_data_length); - return status; -} -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ - -#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) - -static psa_status_t psa_load_builtin_key_into_slot(psa_key_slot_t *slot) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_VOLATILE; - psa_drv_slot_number_t slot_number = 0; - size_t key_buffer_size = 0; - size_t key_buffer_length = 0; - - if (!psa_key_id_is_builtin( - MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id))) { - return PSA_ERROR_DOES_NOT_EXIST; - } - - /* Check the platform function to see whether this key actually exists */ - status = mbedtls_psa_platform_get_builtin_key( - slot->attr.id, &lifetime, &slot_number); - if (status != PSA_SUCCESS) { - return status; - } - - /* Set required key attributes to ensure get_builtin_key can retrieve the - * full attributes. */ - psa_set_key_id(&attributes, slot->attr.id); - psa_set_key_lifetime(&attributes, lifetime); - - /* Get the full key attributes from the driver in order to be able to - * calculate the required buffer size. */ - status = psa_driver_wrapper_get_builtin_key( - slot_number, &attributes, - NULL, 0, NULL); - if (status != PSA_ERROR_BUFFER_TOO_SMALL) { - /* Builtin keys cannot be defined by the attributes alone */ - if (status == PSA_SUCCESS) { - status = PSA_ERROR_CORRUPTION_DETECTED; - } - return status; - } - - /* If the key should exist according to the platform, then ask the driver - * what its expected size is. */ - status = psa_driver_wrapper_get_key_buffer_size(&attributes, - &key_buffer_size); - if (status != PSA_SUCCESS) { - return status; - } - - /* Allocate a buffer of the required size and load the builtin key directly - * into the (now properly sized) slot buffer. */ - status = psa_allocate_buffer_to_slot(slot, key_buffer_size); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_driver_wrapper_get_builtin_key( - slot_number, &attributes, - slot->key.data, slot->key.bytes, &key_buffer_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - /* Copy actual key length and core attributes into the slot on success */ - slot->key.bytes = key_buffer_length; - slot->attr = attributes; -exit: - if (status != PSA_SUCCESS) { - psa_remove_key_data_from_memory(slot); - } - return status; -} -#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ - -psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - *p_slot = NULL; - if (!psa_get_key_slots_initialized()) { - return PSA_ERROR_BAD_STATE; - } - -#if defined(MBEDTLS_THREADING_C) - /* We need to set status as success, otherwise CORRUPTION_DETECTED - * would be returned if the lock fails. */ - status = PSA_SUCCESS; - /* If the key is persistent and not loaded, we cannot unlock the mutex - * between checking if the key is loaded and setting the slot as FULL, - * as otherwise another thread may load and then destroy the key - * in the meantime. */ - PSA_THREADING_CHK_RET(mbedtls_mutex_lock( - &mbedtls_threading_key_slot_mutex)); -#endif - /* - * On success, the pointer to the slot is passed directly to the caller - * thus no need to unlock the key slot here. - */ - status = psa_get_and_lock_key_slot_in_memory(key, p_slot); - if (status != PSA_ERROR_DOES_NOT_EXIST) { -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; - } - - /* Loading keys from storage requires support for such a mechanism */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \ - defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) - - status = psa_reserve_free_key_slot(NULL, p_slot); - if (status != PSA_SUCCESS) { -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; - } - - (*p_slot)->attr.id = key; - (*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT; - - status = PSA_ERROR_DOES_NOT_EXIST; -#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) - /* Load keys in the 'builtin' range through their own interface */ - status = psa_load_builtin_key_into_slot(*p_slot); -#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if (status == PSA_ERROR_DOES_NOT_EXIST) { - status = psa_load_persistent_key_into_slot(*p_slot); - } -#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - - if (status != PSA_SUCCESS) { - psa_wipe_key_slot(*p_slot); - - /* If the key does not exist, we need to return - * PSA_ERROR_INVALID_HANDLE. */ - if (status == PSA_ERROR_DOES_NOT_EXIST) { - status = PSA_ERROR_INVALID_HANDLE; - } - } else { - /* Add implicit usage flags. */ - psa_extend_key_usage_flags(&(*p_slot)->attr.policy.usage); - - psa_key_slot_state_transition((*p_slot), PSA_SLOT_FILLING, - PSA_SLOT_FULL); - status = psa_register_read(*p_slot); - } - -#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ - status = PSA_ERROR_INVALID_HANDLE; -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ - - if (status != PSA_SUCCESS) { - *p_slot = NULL; - } -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; -} - -psa_status_t psa_unregister_read(psa_key_slot_t *slot) -{ - if (slot == NULL) { - return PSA_SUCCESS; - } - if ((slot->state != PSA_SLOT_FULL) && - (slot->state != PSA_SLOT_PENDING_DELETION)) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - - /* If we are the last reader and the slot is marked for deletion, - * we must wipe the slot here. */ - if ((slot->state == PSA_SLOT_PENDING_DELETION) && - (slot->var.occupied.registered_readers == 1)) { - return psa_wipe_key_slot(slot); - } - - if (psa_key_slot_has_readers(slot)) { - slot->var.occupied.registered_readers--; - return PSA_SUCCESS; - } - - /* - * As the return error code may not be handled in case of multiple errors, - * do our best to report if there are no registered readers. Assert with - * MBEDTLS_TEST_HOOK_TEST_ASSERT that there are registered readers: - * if the MBEDTLS_TEST_HOOKS configuration option is enabled and - * the function is called as part of the execution of a test suite, the - * execution of the test suite is stopped in error if the assertion fails. - */ - MBEDTLS_TEST_HOOK_TEST_ASSERT(psa_key_slot_has_readers(slot)); - return PSA_ERROR_CORRUPTION_DETECTED; -} - -psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_THREADING_C) - /* We need to set status as success, otherwise CORRUPTION_DETECTED - * would be returned if the lock fails. */ - status = PSA_SUCCESS; - PSA_THREADING_CHK_RET(mbedtls_mutex_lock( - &mbedtls_threading_key_slot_mutex)); -#endif - status = psa_unregister_read(slot); -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; -} - -psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime, - psa_se_drv_table_entry_t **p_drv) -{ - if (psa_key_lifetime_is_external(lifetime)) { -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* Check whether a driver is registered against this lifetime */ - psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry(lifetime); - if (driver != NULL) { - if (p_drv != NULL) { - *p_drv = driver; - } - return PSA_SUCCESS; - } -#else /* MBEDTLS_PSA_CRYPTO_SE_C */ - (void) p_drv; -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - /* Key location for external keys gets checked by the wrapper */ - return PSA_SUCCESS; - } else { - /* Local/internal keys are always valid */ - return PSA_SUCCESS; - } -} - -psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime) -{ - if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { - /* Volatile keys are always supported */ - return PSA_SUCCESS; - } else { - /* Persistent keys require storage support */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if (PSA_KEY_LIFETIME_IS_READ_ONLY(lifetime)) { - return PSA_ERROR_INVALID_ARGUMENT; - } else { - return PSA_SUCCESS; - } -#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ - return PSA_ERROR_NOT_SUPPORTED; -#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */ - } -} - -psa_status_t psa_open_key(mbedtls_svc_key_id_t key, psa_key_handle_t *handle) -{ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \ - defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) - psa_status_t status; - psa_key_slot_t *slot; - - status = psa_get_and_lock_key_slot(key, &slot); - if (status != PSA_SUCCESS) { - *handle = PSA_KEY_HANDLE_INIT; - if (status == PSA_ERROR_INVALID_HANDLE) { - status = PSA_ERROR_DOES_NOT_EXIST; - } - - return status; - } - - *handle = key; - - return psa_unregister_read_under_mutex(slot); - -#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ - (void) key; - *handle = PSA_KEY_HANDLE_INIT; - return PSA_ERROR_NOT_SUPPORTED; -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ -} - -psa_status_t psa_close_key(psa_key_handle_t handle) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - - if (psa_key_handle_is_null(handle)) { - return PSA_SUCCESS; - } - -#if defined(MBEDTLS_THREADING_C) - /* We need to set status as success, otherwise CORRUPTION_DETECTED - * would be returned if the lock fails. */ - status = PSA_SUCCESS; - PSA_THREADING_CHK_RET(mbedtls_mutex_lock( - &mbedtls_threading_key_slot_mutex)); -#endif - status = psa_get_and_lock_key_slot_in_memory(handle, &slot); - if (status != PSA_SUCCESS) { - if (status == PSA_ERROR_DOES_NOT_EXIST) { - status = PSA_ERROR_INVALID_HANDLE; - } -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; - } - - if (slot->var.occupied.registered_readers == 1) { - status = psa_wipe_key_slot(slot); - } else { - status = psa_unregister_read(slot); - } -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - - return status; -} - -psa_status_t psa_purge_key(mbedtls_svc_key_id_t key) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; - -#if defined(MBEDTLS_THREADING_C) - /* We need to set status as success, otherwise CORRUPTION_DETECTED - * would be returned if the lock fails. */ - status = PSA_SUCCESS; - PSA_THREADING_CHK_RET(mbedtls_mutex_lock( - &mbedtls_threading_key_slot_mutex)); -#endif - status = psa_get_and_lock_key_slot_in_memory(key, &slot); - if (status != PSA_SUCCESS) { -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - return status; - } - - if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) && - (slot->var.occupied.registered_readers == 1)) { - status = psa_wipe_key_slot(slot); - } else { - status = psa_unregister_read(slot); - } -#if defined(MBEDTLS_THREADING_C) - PSA_THREADING_CHK_RET(mbedtls_mutex_unlock( - &mbedtls_threading_key_slot_mutex)); -#endif - - return status; -} - -void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats) -{ - memset(stats, 0, sizeof(*stats)); - - for (size_t slice_idx = 0; slice_idx < KEY_SLICE_COUNT; slice_idx++) { -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - if (global_data.key_slices[slice_idx] == NULL) { - continue; - } -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - for (size_t slot_idx = 0; slot_idx < key_slice_length(slice_idx); slot_idx++) { - const psa_key_slot_t *slot = get_key_slot(slice_idx, slot_idx); - if (slot->state == PSA_SLOT_EMPTY) { - ++stats->empty_slots; - continue; - } - if (psa_key_slot_has_readers(slot)) { - ++stats->locked_slots; - } - if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { - ++stats->volatile_slots; - } else { - psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); - ++stats->persistent_slots; - if (id > stats->max_open_internal_key_id) { - stats->max_open_internal_key_id = id; - } - } - if (PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) != - PSA_KEY_LOCATION_LOCAL_STORAGE) { - psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); - ++stats->external_slots; - if (id > stats->max_open_external_key_id) { - stats->max_open_external_key_id = id; - } - } - } - } -} - -#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/vendor/mbedtls/library/psa_crypto_slot_management.h b/vendor/mbedtls/library/psa_crypto_slot_management.h deleted file mode 100644 index af1208e3a..000000000 --- a/vendor/mbedtls/library/psa_crypto_slot_management.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * PSA crypto layer on top of Mbed TLS crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H -#define PSA_CRYPTO_SLOT_MANAGEMENT_H - -#include "psa/crypto.h" -#include "psa_crypto_core.h" -#include "psa_crypto_se.h" - -/** Range of volatile key identifiers. - * - * The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation - * range of key identifiers are reserved for volatile key identifiers. - * - * If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id - * indicates the key slot containing the volatile key definition. See - * psa_crypto_slot_management.c for details. - */ - -/** The minimum value for a volatile key identifier. - */ -#define PSA_KEY_ID_VOLATILE_MIN PSA_KEY_ID_VENDOR_MIN - -/** The maximum value for a volatile key identifier. - */ -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) -#define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1) -#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ -#define PSA_KEY_ID_VOLATILE_MAX \ - (PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1) -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - -/** Test whether a key identifier is a volatile key identifier. - * - * \param key_id Key identifier to test. - * - * \retval 1 - * The key identifier is a volatile key identifier. - * \retval 0 - * The key identifier is not a volatile key identifier. - */ -static inline int psa_key_id_is_volatile(psa_key_id_t key_id) -{ - return (key_id >= PSA_KEY_ID_VOLATILE_MIN) && - (key_id <= PSA_KEY_ID_VOLATILE_MAX); -} - -/** Get the description of a key given its identifier and lock it. - * - * The descriptions of volatile keys and loaded persistent keys are stored in - * key slots. This function returns a pointer to the key slot containing the - * description of a key given its identifier. - * - * In case of a persistent key, the function loads the description of the key - * into a key slot if not already done. - * - * On success, the returned key slot has been registered for reading. - * It is the responsibility of the caller to call psa_unregister_read(slot) - * when they have finished reading the contents of the slot. - * - * On failure, `*p_slot` is set to NULL. This ensures that it is always valid - * to call psa_unregister_read on the returned slot. - * - * \param key Key identifier to query. - * \param[out] p_slot On success, `*p_slot` contains a pointer to the - * key slot containing the description of the key - * identified by \p key. - * - * \retval #PSA_SUCCESS - * \p *p_slot contains a pointer to the key slot containing the - * description of the key identified by \p key. - * The key slot counter has been incremented. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been initialized. - * \retval #PSA_ERROR_INVALID_HANDLE - * \p key is not a valid key identifier. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \p key is a persistent key identifier. The implementation does not - * have sufficient resources to load the persistent key. This can be - * due to a lack of empty key slot, or available memory. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * There is no key with key identifier \p key. - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - */ -psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot); - -/** Initialize the key slot structures. - * - * \retval #PSA_SUCCESS - * Currently this function always succeeds. - */ -psa_status_t psa_initialize_key_slots(void); - -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) -/* Allow test code to customize the key slice length. We use this in tests - * that exhaust the key store to reach a full key store in reasonable time - * and memory. - * - * The length of each slice must be between 1 and - * (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive. - * - * The length for a given slice index must not change while - * the key store is initialized. - */ -extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)( - size_t slice_idx); - -/* The number of volatile key slices. */ -size_t psa_key_slot_volatile_slice_count(void); -#endif - -/** Delete all data from key slots in memory. - * This function is not thread safe, it wipes every key slot regardless of - * state and reader count. It should only be called when no slot is in use. - * - * This does not affect persistent storage. */ -void psa_wipe_all_key_slots(void); - -/** Find a free key slot and reserve it to be filled with a key. - * - * This function finds a key slot that is free, - * sets its state to PSA_SLOT_FILLING and then returns the slot. - * - * On success, the key slot's state is PSA_SLOT_FILLING. - * It is the responsibility of the caller to change the slot's state to - * PSA_SLOT_EMPTY/FULL once key creation has finished. - * - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \param[out] volatile_key_id - If null, reserve a cache slot for - * a persistent or built-in key. - * - If non-null, allocate a slot for - * a volatile key. On success, - * \p *volatile_key_id is the - * identifier corresponding to the - * returned slot. It is the caller's - * responsibility to set this key identifier - * in the attributes. - * \param[out] p_slot On success, a pointer to the slot. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * There were no free key slots. - * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not - * enough memory to allocate more slots. - * \retval #PSA_ERROR_BAD_STATE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * This function attempted to operate on a key slot which was in an - * unexpected state. - */ -psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, - psa_key_slot_t **p_slot); - -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) -/** Return a key slot to the free list. - * - * Call this function when a slot obtained from psa_reserve_free_key_slot() - * is no longer in use. - * - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \param slice_idx The slice containing the slot. - * This is `slot->slice_index` when the slot - * is obtained from psa_reserve_free_key_slot(). - * \param slot The key slot. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * This function attempted to operate on a key slot which was in an - * unexpected state. - */ -psa_status_t psa_free_key_slot(size_t slice_idx, - psa_key_slot_t *slot); -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ - -/** Change the state of a key slot. - * - * This function changes the state of the key slot from expected_state to - * new state. If the state of the slot was not expected_state, the state is - * unchanged. - * - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \param[in] slot The key slot. - * \param[in] expected_state The current state of the slot. - * \param[in] new_state The new state of the slot. - * - * \retval #PSA_SUCCESS - The key slot's state variable is new_state. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The slot's state was not expected_state. - */ -static inline psa_status_t psa_key_slot_state_transition( - psa_key_slot_t *slot, psa_key_slot_state_t expected_state, - psa_key_slot_state_t new_state) -{ - if (slot->state != expected_state) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - slot->state = new_state; - return PSA_SUCCESS; -} - -/** Register as a reader of a key slot. - * - * This function increments the key slot registered reader counter by one. - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \param[in] slot The key slot. - * - * \retval #PSA_SUCCESS - The key slot registered reader counter was incremented. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The reader counter already reached its maximum value and was not - * increased, or the slot's state was not PSA_SLOT_FULL. - */ -static inline psa_status_t psa_register_read(psa_key_slot_t *slot) -{ - if ((slot->state != PSA_SLOT_FULL) || - (slot->var.occupied.registered_readers >= SIZE_MAX)) { - return PSA_ERROR_CORRUPTION_DETECTED; - } - slot->var.occupied.registered_readers++; - - return PSA_SUCCESS; -} - -/** Unregister from reading a key slot. - * - * This function decrements the key slot registered reader counter by one. - * If the state of the slot is PSA_SLOT_PENDING_DELETION, - * and there is only one registered reader (the caller), - * this function will call psa_wipe_key_slot(). - * If multi-threading is enabled, the caller must hold the - * global key slot mutex. - * - * \note To ease the handling of errors in retrieving a key slot - * a NULL input pointer is valid, and the function returns - * successfully without doing anything in that case. - * - * \param[in] slot The key slot. - * \retval #PSA_SUCCESS - * \p slot is NULL or the key slot reader counter has been - * decremented (and potentially wiped) successfully. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The slot's state was neither PSA_SLOT_FULL nor - * PSA_SLOT_PENDING_DELETION. - * Or a wipe was attempted and the slot's state was not - * PSA_SLOT_PENDING_DELETION. - * Or registered_readers was equal to 0. - */ -psa_status_t psa_unregister_read(psa_key_slot_t *slot); - -/** Wrap a call to psa_unregister_read in the global key slot mutex. - * - * If threading is disabled, this simply calls psa_unregister_read. - * - * \note To ease the handling of errors in retrieving a key slot - * a NULL input pointer is valid, and the function returns - * successfully without doing anything in that case. - * - * \param[in] slot The key slot. - * \retval #PSA_SUCCESS - * \p slot is NULL or the key slot reader counter has been - * decremented (and potentially wiped) successfully. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The slot's state was neither PSA_SLOT_FULL nor - * PSA_SLOT_PENDING_DELETION. - * Or a wipe was attempted and the slot's state was not - * PSA_SLOT_PENDING_DELETION. - * Or registered_readers was equal to 0. - */ -psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot); - -/** Test whether a lifetime designates a key in an external cryptoprocessor. - * - * \param lifetime The lifetime to test. - * - * \retval 1 - * The lifetime designates an external key. There should be a - * registered driver for this lifetime, otherwise the key cannot - * be created or manipulated. - * \retval 0 - * The lifetime designates a key that is volatile or in internal - * storage. - */ -static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime) -{ - return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) - != PSA_KEY_LOCATION_LOCAL_STORAGE; -} - -/** Validate a key's location. - * - * This function checks whether the key's attributes point to a location that - * is known to the PSA Core, and returns the driver function table if the key - * is to be found in an external location. - * - * \param[in] lifetime The key lifetime attribute. - * \param[out] p_drv On success, when a key is located in external - * storage, returns a pointer to the driver table - * associated with the key's storage location. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - */ -psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime, - psa_se_drv_table_entry_t **p_drv); - -/** Validate the persistence of a key. - * - * \param[in] lifetime The key lifetime attribute. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED The key is persistent but persistent keys - * are not supported. - */ -psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime); - -/** Validate a key identifier. - * - * \param[in] key The key identifier. - * \param[in] vendor_ok Non-zero to indicate that key identifiers in the - * vendor range are allowed, volatile key identifiers - * excepted \c 0 otherwise. - * - * \retval <> 0 if the key identifier is valid, 0 otherwise. - */ -int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok); - -#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */ diff --git a/vendor/mbedtls/library/psa_crypto_storage.c b/vendor/mbedtls/library/psa_crypto_storage.c deleted file mode 100644 index 7d1317b45..000000000 --- a/vendor/mbedtls/library/psa_crypto_storage.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * PSA persistent key storage - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - -#include -#include - -#include "psa/crypto.h" -#include "psa_crypto_storage.h" -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_PSA_ITS_FILE_C) -#include "psa_crypto_its.h" -#else /* Native ITS implementation */ -#include "psa/error.h" -#include "psa/internal_trusted_storage.h" -#endif - -#include "mbedtls/platform.h" - - - -/****************************************************************/ -/* Key storage */ -/****************************************************************/ - -/* Determine a file name (ITS file identifier) for the given key identifier. - * The file name must be distinct from any file that is used for a purpose - * other than storing a key. Currently, the only such file is the random seed - * file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID and whose value is - * 0xFFFFFF52. */ -static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key) -{ -#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) - /* Encode the owner in the upper 32 bits. This means that if - * owner values are nonzero (as they are on a PSA platform), - * no key file will ever have a value less than 0x100000000, so - * the whole range 0..0xffffffff is available for non-key files. */ - uint32_t unsigned_owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key); - return ((uint64_t) unsigned_owner_id << 32) | - MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key); -#else - /* Use the key id directly as a file name. - * psa_is_key_id_valid() in psa_crypto_slot_management.c - * is responsible for ensuring that key identifiers do not have a - * value that is reserved for non-key files. */ - return key; -#endif -} - -/** - * \brief Load persistent data for the given key slot number. - * - * This function reads data from a storage backend and returns the data in a - * buffer. - * - * \param key Persistent identifier of the key to be loaded. This - * should be an occupied storage location. - * \param[out] data Buffer where the data is to be written. - * \param data_size Size of the \c data buffer in bytes. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription - */ -static psa_status_t psa_crypto_storage_load( - const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size) -{ - psa_status_t status; - psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key); - struct psa_storage_info_t data_identifier_info; - size_t data_length = 0; - - status = psa_its_get_info(data_identifier, &data_identifier_info); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_its_get(data_identifier, 0, (uint32_t) data_size, data, &data_length); - if (data_size != data_length) { - return PSA_ERROR_DATA_INVALID; - } - - return status; -} - -int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key) -{ - psa_status_t ret; - psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key); - struct psa_storage_info_t data_identifier_info; - - ret = psa_its_get_info(data_identifier, &data_identifier_info); - - if (ret == PSA_ERROR_DOES_NOT_EXIST) { - return 0; - } - return 1; -} - -/** - * \brief Store persistent data for the given key slot number. - * - * This function stores the given data buffer to a persistent storage. - * - * \param key Persistent identifier of the key to be stored. This - * should be an unoccupied storage location. - * \param[in] data Buffer containing the data to be stored. - * \param data_length The number of bytes - * that make up the data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - */ -static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key, - const uint8_t *data, - size_t data_length) -{ - psa_status_t status; - psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key); - struct psa_storage_info_t data_identifier_info; - - if (psa_is_key_present_in_storage(key) == 1) { - return PSA_ERROR_ALREADY_EXISTS; - } - - status = psa_its_set(data_identifier, (uint32_t) data_length, data, 0); - if (status != PSA_SUCCESS) { - return PSA_ERROR_DATA_INVALID; - } - - status = psa_its_get_info(data_identifier, &data_identifier_info); - if (status != PSA_SUCCESS) { - goto exit; - } - - if (data_identifier_info.size != data_length) { - status = PSA_ERROR_DATA_INVALID; - goto exit; - } - -exit: - if (status != PSA_SUCCESS) { - /* Remove the file in case we managed to create it but something - * went wrong. It's ok if the file doesn't exist. If the file exists - * but the removal fails, we're already reporting an error so there's - * nothing else we can do. */ - (void) psa_its_remove(data_identifier); - } - return status; -} - -psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key) -{ - psa_status_t ret; - psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key); - struct psa_storage_info_t data_identifier_info; - - ret = psa_its_get_info(data_identifier, &data_identifier_info); - if (ret == PSA_ERROR_DOES_NOT_EXIST) { - return PSA_SUCCESS; - } - - if (psa_its_remove(data_identifier) != PSA_SUCCESS) { - return PSA_ERROR_DATA_INVALID; - } - - ret = psa_its_get_info(data_identifier, &data_identifier_info); - if (ret != PSA_ERROR_DOES_NOT_EXIST) { - return PSA_ERROR_DATA_INVALID; - } - - return PSA_SUCCESS; -} - -/** - * \brief Get data length for given key slot number. - * - * \param key Persistent identifier whose stored data length - * is to be obtained. - * \param[out] data_length The number of bytes that make up the data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - */ -static psa_status_t psa_crypto_storage_get_data_length( - const mbedtls_svc_key_id_t key, - size_t *data_length) -{ - psa_status_t status; - psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key); - struct psa_storage_info_t data_identifier_info; - - status = psa_its_get_info(data_identifier, &data_identifier_info); - if (status != PSA_SUCCESS) { - return status; - } - - *data_length = (size_t) data_identifier_info.size; - - return PSA_SUCCESS; -} - -/** - * Persistent key storage magic header. - */ -#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY" -#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER)) - -typedef struct { - uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH]; - uint8_t version[4]; - uint8_t lifetime[sizeof(psa_key_lifetime_t)]; - uint8_t type[2]; - uint8_t bits[2]; - uint8_t policy[sizeof(psa_key_policy_t)]; - uint8_t data_len[4]; - uint8_t key_data[]; -} psa_persistent_key_storage_format; - -void psa_format_key_data_for_storage(const uint8_t *data, - const size_t data_length, - const psa_key_attributes_t *attr, - uint8_t *storage_data) -{ - psa_persistent_key_storage_format *storage_format = - (psa_persistent_key_storage_format *) storage_data; - - memcpy(storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, - PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH); - MBEDTLS_PUT_UINT32_LE(0, storage_format->version, 0); - MBEDTLS_PUT_UINT32_LE(attr->lifetime, storage_format->lifetime, 0); - MBEDTLS_PUT_UINT16_LE((uint16_t) attr->type, storage_format->type, 0); - MBEDTLS_PUT_UINT16_LE((uint16_t) attr->bits, storage_format->bits, 0); - MBEDTLS_PUT_UINT32_LE(attr->policy.usage, storage_format->policy, 0); - MBEDTLS_PUT_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t)); - MBEDTLS_PUT_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t)); - MBEDTLS_PUT_UINT32_LE(data_length, storage_format->data_len, 0); - memcpy(storage_format->key_data, data, data_length); -} - -static psa_status_t check_magic_header(const uint8_t *data) -{ - if (memcmp(data, PSA_KEY_STORAGE_MAGIC_HEADER, - PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH) != 0) { - return PSA_ERROR_DATA_INVALID; - } - return PSA_SUCCESS; -} - -psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data, - size_t storage_data_length, - uint8_t **key_data, - size_t *key_data_length, - psa_key_attributes_t *attr) -{ - psa_status_t status; - const psa_persistent_key_storage_format *storage_format = - (const psa_persistent_key_storage_format *) storage_data; - uint32_t version; - - if (storage_data_length < sizeof(*storage_format)) { - return PSA_ERROR_DATA_INVALID; - } - - status = check_magic_header(storage_data); - if (status != PSA_SUCCESS) { - return status; - } - - version = MBEDTLS_GET_UINT32_LE(storage_format->version, 0); - if (version != 0) { - return PSA_ERROR_DATA_INVALID; - } - - *key_data_length = MBEDTLS_GET_UINT32_LE(storage_format->data_len, 0); - if (*key_data_length > (storage_data_length - sizeof(*storage_format)) || - *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) { - return PSA_ERROR_DATA_INVALID; - } - - if (*key_data_length == 0) { - *key_data = NULL; - } else { - *key_data = mbedtls_calloc(1, *key_data_length); - if (*key_data == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - memcpy(*key_data, storage_format->key_data, *key_data_length); - } - - attr->lifetime = MBEDTLS_GET_UINT32_LE(storage_format->lifetime, 0); - attr->type = MBEDTLS_GET_UINT16_LE(storage_format->type, 0); - attr->bits = MBEDTLS_GET_UINT16_LE(storage_format->bits, 0); - attr->policy.usage = MBEDTLS_GET_UINT32_LE(storage_format->policy, 0); - attr->policy.alg = MBEDTLS_GET_UINT32_LE(storage_format->policy, sizeof(uint32_t)); - attr->policy.alg2 = MBEDTLS_GET_UINT32_LE(storage_format->policy, 2 * sizeof(uint32_t)); - - return PSA_SUCCESS; -} - -psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr, - const uint8_t *data, - const size_t data_length) -{ - size_t storage_data_length; - uint8_t *storage_data; - psa_status_t status; - - /* All keys saved to persistent storage always have a key context */ - if (data == NULL || data_length == 0) { - return PSA_ERROR_INVALID_ARGUMENT; - } - - if (data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) { - return PSA_ERROR_INSUFFICIENT_STORAGE; - } - storage_data_length = data_length + sizeof(psa_persistent_key_storage_format); - - storage_data = mbedtls_calloc(1, storage_data_length); - if (storage_data == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - psa_format_key_data_for_storage(data, data_length, attr, storage_data); - - status = psa_crypto_storage_store(attr->id, - storage_data, storage_data_length); - - mbedtls_zeroize_and_free(storage_data, storage_data_length); - - return status; -} - -void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length) -{ - mbedtls_zeroize_and_free(key_data, key_data_length); -} - -psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr, - uint8_t **data, - size_t *data_length) -{ - psa_status_t status = PSA_SUCCESS; - uint8_t *loaded_data; - size_t storage_data_length = 0; - mbedtls_svc_key_id_t key = attr->id; - - status = psa_crypto_storage_get_data_length(key, &storage_data_length); - if (status != PSA_SUCCESS) { - return status; - } - - loaded_data = mbedtls_calloc(1, storage_data_length); - - if (loaded_data == NULL) { - return PSA_ERROR_INSUFFICIENT_MEMORY; - } - - status = psa_crypto_storage_load(key, loaded_data, storage_data_length); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_parse_key_data_from_storage(loaded_data, storage_data_length, - data, data_length, attr); - - /* All keys saved to persistent storage always have a key context */ - if (status == PSA_SUCCESS && - (*data == NULL || *data_length == 0)) { - status = PSA_ERROR_STORAGE_FAILURE; - } - -exit: - mbedtls_zeroize_and_free(loaded_data, storage_data_length); - return status; -} - - - -/****************************************************************/ -/* Transactions */ -/****************************************************************/ - -#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) - -psa_crypto_transaction_t psa_crypto_transaction; - -psa_status_t psa_crypto_save_transaction(void) -{ - struct psa_storage_info_t p_info; - psa_status_t status; - status = psa_its_get_info(PSA_CRYPTO_ITS_TRANSACTION_UID, &p_info); - if (status == PSA_SUCCESS) { - /* This shouldn't happen: we're trying to start a transaction while - * there is still a transaction that hasn't been replayed. */ - return PSA_ERROR_CORRUPTION_DETECTED; - } else if (status != PSA_ERROR_DOES_NOT_EXIST) { - return status; - } - return psa_its_set(PSA_CRYPTO_ITS_TRANSACTION_UID, - sizeof(psa_crypto_transaction), - &psa_crypto_transaction, - 0); -} - -psa_status_t psa_crypto_load_transaction(void) -{ - psa_status_t status; - size_t length; - status = psa_its_get(PSA_CRYPTO_ITS_TRANSACTION_UID, 0, - sizeof(psa_crypto_transaction), - &psa_crypto_transaction, &length); - if (status != PSA_SUCCESS) { - return status; - } - if (length != sizeof(psa_crypto_transaction)) { - return PSA_ERROR_DATA_INVALID; - } - return PSA_SUCCESS; -} - -psa_status_t psa_crypto_stop_transaction(void) -{ - psa_status_t status = psa_its_remove(PSA_CRYPTO_ITS_TRANSACTION_UID); - /* Whether or not updating the storage succeeded, the transaction is - * finished now. It's too late to go back, so zero out the in-memory - * data. */ - memset(&psa_crypto_transaction, 0, sizeof(psa_crypto_transaction)); - return status; -} - -#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ - - - -/****************************************************************/ -/* Random generator state */ -/****************************************************************/ - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) -psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed, - size_t seed_size) -{ - psa_status_t status; - struct psa_storage_info_t p_info; - - status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info); - - if (PSA_ERROR_DOES_NOT_EXIST == status) { /* No seed exists */ - status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0); - } else if (PSA_SUCCESS == status) { - /* You should not be here. Seed needs to be injected only once */ - status = PSA_ERROR_NOT_PERMITTED; - } - return status; -} -#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ - - - -/****************************************************************/ -/* The end */ -/****************************************************************/ - -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ diff --git a/vendor/mbedtls/library/psa_crypto_storage.h b/vendor/mbedtls/library/psa_crypto_storage.h deleted file mode 100644 index 433ecdca5..000000000 --- a/vendor/mbedtls/library/psa_crypto_storage.h +++ /dev/null @@ -1,392 +0,0 @@ -/** - * \file psa_crypto_storage.h - * - * \brief PSA cryptography module: Mbed TLS key storage - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_CRYPTO_STORAGE_H -#define PSA_CRYPTO_STORAGE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "psa/crypto.h" -#include "psa/crypto_se_driver.h" - -#include -#include - -/* Limit the maximum key size in storage. */ -#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) -/* Reflect the maximum size for the key buffer. */ -#define PSA_CRYPTO_MAX_STORAGE_SIZE (MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE) -#else -/* Just set an upper boundary but it should have no effect since the key size - * is limited in memory. */ -#define PSA_CRYPTO_MAX_STORAGE_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS)) -#endif - -/* Sanity check: a file size must fit in 32 bits. Allow a generous - * 64kB of metadata. */ -#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000 -#error "PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000" -#endif - -/** The maximum permitted persistent slot number. - * - * In Mbed Crypto 0.1.0b: - * - Using the file backend, all key ids are ok except 0. - * - Using the ITS backend, all key ids are ok except 0xFFFFFF52 - * (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the - * device's random seed (if this feature is enabled). - * - Only key ids from 1 to #MBEDTLS_PSA_KEY_SLOT_COUNT are actually used. - * - * Since we need to preserve the random seed, avoid using that key slot. - * Reserve a whole range of key slots just in case something else comes up. - * - * This limitation will probably become moot when we implement client - * separation for key storage. - */ -#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX - -/** - * \brief Checks if persistent data is stored for the given key slot number - * - * This function checks if any key data or metadata exists for the key slot in - * the persistent storage. - * - * \param key Persistent identifier to check. - * - * \retval 0 - * No persistent data present for slot number - * \retval 1 - * Persistent data present for slot number - */ -int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key); - -/** - * \brief Format key data and metadata and save to a location for given key - * slot. - * - * This function formats the key data and metadata and saves it to a - * persistent storage backend. The storage location corresponding to the - * key slot must be empty, otherwise this function will fail. This function - * should be called after loading the key into an internal slot to ensure the - * persistent key is not saved into a storage location corresponding to an - * already occupied non-persistent key, as well as ensuring the key data is - * validated. - * - * Note: This function will only succeed for key buffers which are not - * empty. If passed a NULL pointer or zero-length, the function will fail - * with #PSA_ERROR_INVALID_ARGUMENT. - * - * \param[in] attr The attributes of the key to save. - * The key identifier field in the attributes - * determines the key's location. - * \param[in] data Buffer containing the key data. - * \param data_length The number of bytes that make up the key data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - */ -psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr, - const uint8_t *data, - const size_t data_length); - -/** - * \brief Parses key data and metadata and load persistent key for given - * key slot number. - * - * This function reads from a storage backend, parses the key data and - * metadata and writes them to the appropriate output parameters. - * - * Note: This function allocates a buffer and returns a pointer to it through - * the data parameter. On successful return, the pointer is guaranteed to be - * valid and the buffer contains at least one byte of data. - * psa_free_persistent_key_data() must be called on the data buffer - * afterwards to zeroize and free this buffer. - * - * \param[in,out] attr On input, the key identifier field identifies - * the key to load. Other fields are ignored. - * On success, the attribute structure contains - * the key metadata that was loaded from storage. - * \param[out] data Pointer to an allocated key data buffer on return. - * \param[out] data_length The number of bytes that make up the key data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription - */ -psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr, - uint8_t **data, - size_t *data_length); - -/** - * \brief Remove persistent data for the given key slot number. - * - * \param key Persistent identifier of the key to remove - * from persistent storage. - * - * \retval #PSA_SUCCESS - * The key was successfully removed, - * or the key did not exist. - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - */ -psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key); - -/** - * \brief Free the temporary buffer allocated by psa_load_persistent_key(). - * - * This function must be called at some point after psa_load_persistent_key() - * to zeroize and free the memory allocated to the buffer in that function. - * - * \param key_data Buffer for the key data. - * \param key_data_length Size of the key data buffer. - * - */ -void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length); - -/** - * \brief Formats key data and metadata for persistent storage - * - * \param[in] data Buffer containing the key data. - * \param data_length Length of the key data buffer. - * \param[in] attr The core attributes of the key. - * \param[out] storage_data Output buffer for the formatted data. - * - */ -void psa_format_key_data_for_storage(const uint8_t *data, - const size_t data_length, - const psa_key_attributes_t *attr, - uint8_t *storage_data); - -/** - * \brief Parses persistent storage data into key data and metadata - * - * \param[in] storage_data Buffer for the storage data. - * \param storage_data_length Length of the storage data buffer - * \param[out] key_data On output, pointer to a newly allocated buffer - * containing the key data. This must be freed - * using psa_free_persistent_key_data() - * \param[out] key_data_length Length of the key data buffer - * \param[out] attr On success, the attribute structure is filled - * with the loaded key metadata. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - */ -psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data, - size_t storage_data_length, - uint8_t **key_data, - size_t *key_data_length, - psa_key_attributes_t *attr); - -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -/** This symbol is defined if transaction support is required. */ -#define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS 1 -#endif - -#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) - -/** The type of transaction that is in progress. - */ -/* This is an integer type rather than an enum for two reasons: to support - * unknown values when loading a transaction file, and to ensure that the - * type has a known size. - */ -typedef uint16_t psa_crypto_transaction_type_t; - -/** No transaction is in progress. - * - * This has the value 0, so zero-initialization sets a transaction's type to - * this value. - */ -#define PSA_CRYPTO_TRANSACTION_NONE ((psa_crypto_transaction_type_t) 0x0000) - -/** A key creation transaction. - * - * This is only used for keys in an external cryptoprocessor (secure element). - * Keys in RAM or in internal storage are created atomically in storage - * (simple file creation), so they do not need a transaction mechanism. - */ -#define PSA_CRYPTO_TRANSACTION_CREATE_KEY ((psa_crypto_transaction_type_t) 0x0001) - -/** A key destruction transaction. - * - * This is only used for keys in an external cryptoprocessor (secure element). - * Keys in RAM or in internal storage are destroyed atomically in storage - * (simple file deletion), so they do not need a transaction mechanism. - */ -#define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ((psa_crypto_transaction_type_t) 0x0002) - -/** Transaction data. - * - * This type is designed to be serialized by writing the memory representation - * and reading it back on the same device. - * - * \note The transaction mechanism is not thread-safe. There can only be one - * single active transaction at a time. - * The transaction object is #psa_crypto_transaction. - * - * \note If an API call starts a transaction, it must complete this transaction - * before returning to the application. - * - * The lifetime of a transaction is the following (note that only one - * transaction may be active at a time): - * - * -# Call psa_crypto_prepare_transaction() to initialize the transaction - * object in memory and declare the type of transaction that is starting. - * -# Fill in the type-specific fields of #psa_crypto_transaction. - * -# Call psa_crypto_save_transaction() to start the transaction. This - * saves the transaction data to internal storage. - * -# Perform the work of the transaction by modifying files, contacting - * external entities, or whatever needs doing. Note that the transaction - * may be interrupted by a power failure, so you need to have a way - * recover from interruptions either by undoing what has been done - * so far or by resuming where you left off. - * -# If there are intermediate stages in the transaction, update - * the fields of #psa_crypto_transaction and call - * psa_crypto_save_transaction() again when each stage is reached. - * -# When the transaction is over, call psa_crypto_stop_transaction() to - * remove the transaction data in storage and in memory. - * - * If the system crashes while a transaction is in progress, psa_crypto_init() - * calls psa_crypto_load_transaction() and takes care of completing or - * rewinding the transaction. This is done in psa_crypto_recover_transaction() - * in psa_crypto.c. If you add a new type of transaction, be - * sure to add code for it in psa_crypto_recover_transaction(). - */ -typedef union { - /* Each element of this union must have the following properties - * to facilitate serialization and deserialization: - * - * - The element is a struct. - * - The first field of the struct is `psa_crypto_transaction_type_t type`. - * - Elements of the struct are arranged such a way that there is - * no padding. - */ - struct psa_crypto_transaction_unknown_s { - psa_crypto_transaction_type_t type; - uint16_t unused1; - uint32_t unused2; - uint64_t unused3; - uint64_t unused4; - } unknown; - /* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or - * #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */ - struct psa_crypto_transaction_key_s { - psa_crypto_transaction_type_t type; - uint16_t unused1; - psa_key_lifetime_t lifetime; - psa_key_slot_number_t slot; - mbedtls_svc_key_id_t id; - } key; -} psa_crypto_transaction_t; - -/** The single active transaction. - */ -extern psa_crypto_transaction_t psa_crypto_transaction; - -/** Prepare for a transaction. - * - * There must not be an ongoing transaction. - * - * \param type The type of transaction to start. - */ -static inline void psa_crypto_prepare_transaction( - psa_crypto_transaction_type_t type) -{ - psa_crypto_transaction.unknown.type = type; -} - -/** Save the transaction data to storage. - * - * You may call this function multiple times during a transaction to - * atomically update the transaction state. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - */ -psa_status_t psa_crypto_save_transaction(void); - -/** Load the transaction data from storage, if any. - * - * This function is meant to be called from psa_crypto_init() to recover - * in case a transaction was interrupted by a system crash. - * - * \retval #PSA_SUCCESS - * The data about the ongoing transaction has been loaded to - * #psa_crypto_transaction. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * There is no ongoing transaction. - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - */ -psa_status_t psa_crypto_load_transaction(void); - -/** Indicate that the current transaction is finished. - * - * Call this function at the very end of transaction processing. - * This function does not "commit" or "abort" the transaction: the storage - * subsystem has no concept of "commit" and "abort", just saving and - * removing the transaction information in storage. - * - * This function erases the transaction data in storage (if any) and - * resets the transaction data in memory. - * - * \retval #PSA_SUCCESS - * There was transaction data in storage. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * There was no transaction data in storage. - * \retval #PSA_ERROR_STORAGE_FAILURE - * It was impossible to determine whether there was transaction data - * in storage, or the transaction data could not be erased. - */ -psa_status_t psa_crypto_stop_transaction(void); - -/** The ITS file identifier for the transaction data. - * - * 0xffffffNN = special file; 0x74 = 't' for transaction. - */ -#define PSA_CRYPTO_ITS_TRANSACTION_UID ((psa_key_id_t) 0xffffff74) - -#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ - -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) -/** Backend side of mbedtls_psa_inject_entropy(). - * - * This function stores the supplied data into the entropy seed file. - * - * \retval #PSA_SUCCESS - * Success - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The entropy seed file already exists. - */ -psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed, - size_t seed_size); -#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ - -#ifdef __cplusplus -} -#endif - -#endif /* PSA_CRYPTO_STORAGE_H */ diff --git a/vendor/mbedtls/library/psa_its_file.c b/vendor/mbedtls/library/psa_its_file.c deleted file mode 100644 index 956713748..000000000 --- a/vendor/mbedtls/library/psa_its_file.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * PSA ITS simulator over stdio files. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_PSA_ITS_FILE_C) - -#include "mbedtls/platform.h" - -#if defined(_WIN32) -#include -#endif - -#include "psa_crypto_its.h" - -#include -#include -#include -#include - -#if !defined(PSA_ITS_STORAGE_PREFIX) -#define PSA_ITS_STORAGE_PREFIX "" -#endif - -#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08x%08x" -#define PSA_ITS_STORAGE_SUFFIX ".psa_its" -#define PSA_ITS_STORAGE_FILENAME_LENGTH \ - (sizeof(PSA_ITS_STORAGE_PREFIX) - 1 + /*prefix without terminating 0*/ \ - 16 + /*UID (64-bit number in hex)*/ \ - sizeof(PSA_ITS_STORAGE_SUFFIX) - 1 + /*suffix without terminating 0*/ \ - 1 /*terminating null byte*/) -#define PSA_ITS_STORAGE_TEMP \ - PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX - -/* The maximum value of psa_storage_info_t.size */ -#define PSA_ITS_MAX_SIZE 0xffffffff - -#define PSA_ITS_MAGIC_STRING "PSA\0ITS\0" -#define PSA_ITS_MAGIC_LENGTH 8 - -/* As rename fails on Windows if the new filepath already exists, - * use MoveFileExA with the MOVEFILE_REPLACE_EXISTING flag instead. - * Returns 0 on success, nonzero on failure. */ -#if defined(_WIN32) -#define rename_replace_existing(oldpath, newpath) \ - (!MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING)) -#else -#define rename_replace_existing(oldpath, newpath) rename(oldpath, newpath) -#endif - -typedef struct { - uint8_t magic[PSA_ITS_MAGIC_LENGTH]; - uint8_t size[sizeof(uint32_t)]; - uint8_t flags[sizeof(psa_storage_create_flags_t)]; -} psa_its_file_header_t; - -static void psa_its_fill_filename(psa_storage_uid_t uid, char *filename) -{ - /* Break up the UID into two 32-bit pieces so as not to rely on - * long long support in snprintf. */ - mbedtls_snprintf(filename, PSA_ITS_STORAGE_FILENAME_LENGTH, - "%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s", - PSA_ITS_STORAGE_PREFIX, - (unsigned) (uid >> 32), - (unsigned) (uid & 0xffffffff), - PSA_ITS_STORAGE_SUFFIX); -} - -static psa_status_t psa_its_read_file(psa_storage_uid_t uid, - struct psa_storage_info_t *p_info, - FILE **p_stream) -{ - char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; - psa_its_file_header_t header; - size_t n; - - *p_stream = NULL; - psa_its_fill_filename(uid, filename); - *p_stream = fopen(filename, "rb"); - if (*p_stream == NULL) { - return PSA_ERROR_DOES_NOT_EXIST; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(*p_stream, NULL); - - n = fread(&header, 1, sizeof(header), *p_stream); - if (n != sizeof(header)) { - return PSA_ERROR_DATA_CORRUPT; - } - if (memcmp(header.magic, PSA_ITS_MAGIC_STRING, - PSA_ITS_MAGIC_LENGTH) != 0) { - return PSA_ERROR_DATA_CORRUPT; - } - - p_info->size = MBEDTLS_GET_UINT32_LE(header.size, 0); - p_info->flags = MBEDTLS_GET_UINT32_LE(header.flags, 0); - - return PSA_SUCCESS; -} - -psa_status_t psa_its_get_info(psa_storage_uid_t uid, - struct psa_storage_info_t *p_info) -{ - psa_status_t status; - FILE *stream = NULL; - status = psa_its_read_file(uid, p_info, &stream); - if (stream != NULL) { - fclose(stream); - } - return status; -} - -psa_status_t psa_its_get(psa_storage_uid_t uid, - uint32_t data_offset, - uint32_t data_length, - void *p_data, - size_t *p_data_length) -{ - psa_status_t status; - FILE *stream = NULL; - size_t n; - struct psa_storage_info_t info; - - status = psa_its_read_file(uid, &info, &stream); - if (status != PSA_SUCCESS) { - goto exit; - } - status = PSA_ERROR_INVALID_ARGUMENT; - if (data_offset + data_length < data_offset) { - goto exit; - } -#if SIZE_MAX < 0xffffffff - if (data_offset + data_length > SIZE_MAX) { - goto exit; - } -#endif - if (data_offset + data_length > info.size) { - goto exit; - } - - status = PSA_ERROR_STORAGE_FAILURE; -#if LONG_MAX < 0xffffffff - while (data_offset > LONG_MAX) { - if (fseek(stream, LONG_MAX, SEEK_CUR) != 0) { - goto exit; - } - data_offset -= LONG_MAX; - } -#endif - if (fseek(stream, data_offset, SEEK_CUR) != 0) { - goto exit; - } - n = fread(p_data, 1, data_length, stream); - if (n != data_length) { - goto exit; - } - status = PSA_SUCCESS; - if (p_data_length != NULL) { - *p_data_length = n; - } - -exit: - if (stream != NULL) { - fclose(stream); - } - return status; -} - -psa_status_t psa_its_set(psa_storage_uid_t uid, - uint32_t data_length, - const void *p_data, - psa_storage_create_flags_t create_flags) -{ - if (uid == 0) { - return PSA_ERROR_INVALID_HANDLE; - } - - psa_status_t status = PSA_ERROR_STORAGE_FAILURE; - char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; - FILE *stream = NULL; - psa_its_file_header_t header; - size_t n; - - memcpy(header.magic, PSA_ITS_MAGIC_STRING, PSA_ITS_MAGIC_LENGTH); - MBEDTLS_PUT_UINT32_LE(data_length, header.size, 0); - MBEDTLS_PUT_UINT32_LE(create_flags, header.flags, 0); - - psa_its_fill_filename(uid, filename); - stream = fopen(PSA_ITS_STORAGE_TEMP, "wb"); - - if (stream == NULL) { - goto exit; - } - - /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ - mbedtls_setbuf(stream, NULL); - - status = PSA_ERROR_INSUFFICIENT_STORAGE; - n = fwrite(&header, 1, sizeof(header), stream); - if (n != sizeof(header)) { - goto exit; - } - if (data_length != 0) { - n = fwrite(p_data, 1, data_length, stream); - if (n != data_length) { - goto exit; - } - } - status = PSA_SUCCESS; - -exit: - if (stream != NULL) { - int ret = fclose(stream); - if (status == PSA_SUCCESS && ret != 0) { - status = PSA_ERROR_INSUFFICIENT_STORAGE; - } - } - if (status == PSA_SUCCESS) { - if (rename_replace_existing(PSA_ITS_STORAGE_TEMP, filename) != 0) { - status = PSA_ERROR_STORAGE_FAILURE; - } - } - /* The temporary file may still exist, but only in failure cases where - * we're already reporting an error. So there's nothing we can do on - * failure. If the function succeeded, and in some error cases, the - * temporary file doesn't exist and so remove() is expected to fail. - * Thus we just ignore the return status of remove(). */ - (void) remove(PSA_ITS_STORAGE_TEMP); - return status; -} - -psa_status_t psa_its_remove(psa_storage_uid_t uid) -{ - char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; - FILE *stream; - psa_its_fill_filename(uid, filename); - stream = fopen(filename, "rb"); - if (stream == NULL) { - return PSA_ERROR_DOES_NOT_EXIST; - } - fclose(stream); - if (remove(filename) != 0) { - return PSA_ERROR_STORAGE_FAILURE; - } - return PSA_SUCCESS; -} - -#endif /* MBEDTLS_PSA_ITS_FILE_C */ diff --git a/vendor/mbedtls/library/psa_util.c b/vendor/mbedtls/library/psa_util.c deleted file mode 100644 index 014e648ad..000000000 --- a/vendor/mbedtls/library/psa_util.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * PSA hashing layer on top of Mbed TLS software crypto - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -/* This is needed for MBEDTLS_ERR_XXX macros */ -#include - -#if defined(MBEDTLS_ASN1_WRITE_C) -#include -#include -#endif - -#include "psa_util_internal.h" - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) - -#include - -#if defined(MBEDTLS_MD_LIGHT) -#include -#endif -#if defined(MBEDTLS_LMS_C) -#include -#endif -#if defined(MBEDTLS_SSL_TLS_C) && \ - (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)) -#include -#endif -#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -#include -#endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -#include -#endif -#if defined(MBEDTLS_PK_C) -#include -#endif -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -#include -#endif -#include - -/* PSA_SUCCESS is kept at the top of each error table since - * it's the most common status when everything functions properly. */ -#if defined(MBEDTLS_MD_LIGHT) -const mbedtls_error_pair_t psa_to_md_errors[] = -{ - { PSA_SUCCESS, 0 }, - { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE }, - { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_MD_BAD_INPUT_DATA }, - { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_MD_ALLOC_FAILED } -}; -#endif - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -const mbedtls_error_pair_t psa_to_cipher_errors[] = -{ - { PSA_SUCCESS, 0 }, - { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE }, - { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA }, - { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_CIPHER_ALLOC_FAILED } -}; -#endif - -#if defined(MBEDTLS_LMS_C) -const mbedtls_error_pair_t psa_to_lms_errors[] = -{ - { PSA_SUCCESS, 0 }, - { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL }, - { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_LMS_BAD_INPUT_DATA } -}; -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && \ - (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)) -const mbedtls_error_pair_t psa_to_ssl_errors[] = -{ - { PSA_SUCCESS, 0 }, - { PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_SSL_ALLOC_FAILED }, - { PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE }, - { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_SSL_INVALID_MAC }, - { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_SSL_BAD_INPUT_DATA }, - { PSA_ERROR_BAD_STATE, MBEDTLS_ERR_SSL_INTERNAL_ERROR }, - { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL } -}; -#endif - -#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -const mbedtls_error_pair_t psa_to_pk_rsa_errors[] = -{ - { PSA_SUCCESS, 0 }, - { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_RSA_BAD_INPUT_DATA }, - { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_RSA_BAD_INPUT_DATA }, - { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_RSA_BAD_INPUT_DATA }, - { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE }, - { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_RSA_RNG_FAILED }, - { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_RSA_VERIFY_FAILED }, - { PSA_ERROR_INVALID_PADDING, MBEDTLS_ERR_RSA_INVALID_PADDING } -}; -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[] = -{ - { PSA_SUCCESS, 0 }, - { PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_ECP_BAD_INPUT_DATA }, - { PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_ECP_BAD_INPUT_DATA }, - { PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE }, - { PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL }, - { PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_ECP_RANDOM_FAILED }, - { PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_ECP_VERIFY_FAILED } -}; -#endif - -int psa_generic_status_to_mbedtls(psa_status_t status) -{ - switch (status) { - case PSA_SUCCESS: - return 0; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; - case PSA_ERROR_CORRUPTION_DETECTED: - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - case PSA_ERROR_COMMUNICATION_FAILURE: - case PSA_ERROR_HARDWARE_FAILURE: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - case PSA_ERROR_NOT_PERMITTED: - default: - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } -} - -int psa_status_to_mbedtls(psa_status_t status, - const mbedtls_error_pair_t *local_translations, - size_t local_errors_num, - int (*fallback_f)(psa_status_t)) -{ - for (size_t i = 0; i < local_errors_num; i++) { - if (status == local_translations[i].psa_status) { - return local_translations[i].mbedtls_error; - } - } - return fallback_f(status); -} - -#if defined(MBEDTLS_PK_C) -int psa_pk_status_to_mbedtls(psa_status_t status) -{ - switch (status) { - case PSA_ERROR_INVALID_HANDLE: - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - case PSA_ERROR_INVALID_ARGUMENT: - return MBEDTLS_ERR_PK_INVALID_ALG; - case PSA_ERROR_NOT_PERMITTED: - return MBEDTLS_ERR_PK_TYPE_MISMATCH; - case PSA_ERROR_INSUFFICIENT_MEMORY: - return MBEDTLS_ERR_PK_ALLOC_FAILED; - case PSA_ERROR_BAD_STATE: - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - case PSA_ERROR_DATA_CORRUPT: - case PSA_ERROR_DATA_INVALID: - case PSA_ERROR_STORAGE_FAILURE: - return MBEDTLS_ERR_PK_FILE_IO_ERROR; - default: - return psa_generic_status_to_mbedtls(status); - } -} -#endif /* MBEDTLS_PK_C */ - -/****************************************************************/ -/* Key management */ -/****************************************************************/ - -#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, - size_t *bits) -{ - switch (grpid) { -#if defined(MBEDTLS_ECP_HAVE_SECP192R1) - case MBEDTLS_ECP_DP_SECP192R1: - *bits = 192; - return PSA_ECC_FAMILY_SECP_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP224R1) - case MBEDTLS_ECP_DP_SECP224R1: - *bits = 224; - return PSA_ECC_FAMILY_SECP_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP256R1) - case MBEDTLS_ECP_DP_SECP256R1: - *bits = 256; - return PSA_ECC_FAMILY_SECP_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP384R1) - case MBEDTLS_ECP_DP_SECP384R1: - *bits = 384; - return PSA_ECC_FAMILY_SECP_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP521R1) - case MBEDTLS_ECP_DP_SECP521R1: - *bits = 521; - return PSA_ECC_FAMILY_SECP_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_BP256R1) - case MBEDTLS_ECP_DP_BP256R1: - *bits = 256; - return PSA_ECC_FAMILY_BRAINPOOL_P_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_BP384R1) - case MBEDTLS_ECP_DP_BP384R1: - *bits = 384; - return PSA_ECC_FAMILY_BRAINPOOL_P_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_BP512R1) - case MBEDTLS_ECP_DP_BP512R1: - *bits = 512; - return PSA_ECC_FAMILY_BRAINPOOL_P_R1; -#endif -#if defined(MBEDTLS_ECP_HAVE_CURVE25519) - case MBEDTLS_ECP_DP_CURVE25519: - *bits = 255; - return PSA_ECC_FAMILY_MONTGOMERY; -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP192K1) - case MBEDTLS_ECP_DP_SECP192K1: - *bits = 192; - return PSA_ECC_FAMILY_SECP_K1; -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP224K1) - /* secp224k1 is not and will not be supported in PSA (#3541). */ -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP256K1) - case MBEDTLS_ECP_DP_SECP256K1: - *bits = 256; - return PSA_ECC_FAMILY_SECP_K1; -#endif -#if defined(MBEDTLS_ECP_HAVE_CURVE448) - case MBEDTLS_ECP_DP_CURVE448: - *bits = 448; - return PSA_ECC_FAMILY_MONTGOMERY; -#endif - default: - *bits = 0; - return 0; - } -} - -mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family, - size_t bits) -{ - switch (family) { - case PSA_ECC_FAMILY_SECP_R1: - switch (bits) { -#if defined(PSA_WANT_ECC_SECP_R1_192) - case 192: - return MBEDTLS_ECP_DP_SECP192R1; -#endif -#if defined(PSA_WANT_ECC_SECP_R1_224) - case 224: - return MBEDTLS_ECP_DP_SECP224R1; -#endif -#if defined(PSA_WANT_ECC_SECP_R1_256) - case 256: - return MBEDTLS_ECP_DP_SECP256R1; -#endif -#if defined(PSA_WANT_ECC_SECP_R1_384) - case 384: - return MBEDTLS_ECP_DP_SECP384R1; -#endif -#if defined(PSA_WANT_ECC_SECP_R1_521) - case 521: - return MBEDTLS_ECP_DP_SECP521R1; -#endif - } - break; - - case PSA_ECC_FAMILY_BRAINPOOL_P_R1: - switch (bits) { -#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) - case 256: - return MBEDTLS_ECP_DP_BP256R1; -#endif -#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) - case 384: - return MBEDTLS_ECP_DP_BP384R1; -#endif -#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) - case 512: - return MBEDTLS_ECP_DP_BP512R1; -#endif - } - break; - - case PSA_ECC_FAMILY_MONTGOMERY: - switch (bits) { -#if defined(PSA_WANT_ECC_MONTGOMERY_255) - case 255: - return MBEDTLS_ECP_DP_CURVE25519; -#endif -#if defined(PSA_WANT_ECC_MONTGOMERY_448) - case 448: - return MBEDTLS_ECP_DP_CURVE448; -#endif - } - break; - - case PSA_ECC_FAMILY_SECP_K1: - switch (bits) { -#if defined(PSA_WANT_ECC_SECP_K1_192) - case 192: - return MBEDTLS_ECP_DP_SECP192K1; -#endif -#if defined(PSA_WANT_ECC_SECP_K1_224) - /* secp224k1 is not and will not be supported in PSA (#3541). */ -#endif -#if defined(PSA_WANT_ECC_SECP_K1_256) - case 256: - return MBEDTLS_ECP_DP_SECP256K1; -#endif - } - break; - } - - return MBEDTLS_ECP_DP_NONE; -} -#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ - -/* Wrapper function allowing the classic API to use the PSA RNG. - * - * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls - * `psa_generate_random(...)`. The state parameter is ignored since the - * PSA API doesn't support passing an explicit state. - */ -int mbedtls_psa_get_random(void *p_rng, - unsigned char *output, - size_t output_size) -{ - /* This function takes a pointer to the RNG state because that's what - * classic mbedtls functions using an RNG expect. The PSA RNG manages - * its own state internally and doesn't let the caller access that state. - * So we just ignore the state parameter, and in practice we'll pass - * NULL. */ - (void) p_rng; - psa_status_t status = psa_generate_random(output, output_size); - if (status == PSA_SUCCESS) { - return 0; - } else { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } -} - -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ - -#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) - -/** - * \brief Convert a single raw coordinate to DER ASN.1 format. The output der - * buffer is filled backward (i.e. starting from its end). - * - * \param raw_buf Buffer containing the raw coordinate to be - * converted. - * \param raw_len Length of raw_buf in bytes. This must be > 0. - * \param der_buf_start Pointer to the beginning of the buffer which - * will be filled with the DER converted data. - * \param der_buf_end End of the buffer used to store the DER output. - * - * \return On success, the amount of data (in bytes) written to - * the DER buffer. - * \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der - * buffer is too small to contain all the converted data. - * \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw - * coordinate is null (i.e. all zeros). - * - * \warning Raw and der buffer must not be overlapping. - */ -static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len, - unsigned char *der_buf_start, - unsigned char *der_buf_end) -{ - unsigned char *p = der_buf_end; - int len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* ASN.1 DER encoding requires minimal length, so skip leading 0s. - * Provided input MPIs should not be 0, but as a failsafe measure, still - * detect that and return error in case. */ - while (*raw_buf == 0x00) { - ++raw_buf; - --raw_len; - if (raw_len == 0) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - } - len = (int) raw_len; - - /* Copy the raw coordinate to the end of der_buf. */ - if ((p - der_buf_start) < len) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - p -= len; - memcpy(p, raw_buf, len); - - /* If MSb is 1, ASN.1 requires that we prepend a 0. */ - if (*p & 0x80) { - if ((p - der_buf_start) < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - --p; - *p = 0x00; - ++len; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER)); - - return len; -} - -int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len, - unsigned char *der, size_t der_size, size_t *der_len) -{ - unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - const size_t coordinate_len = PSA_BITS_TO_BYTES(bits); - size_t len = 0; - unsigned char *p = der + der_size; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (bits == 0) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - if (raw_len != (2 * coordinate_len)) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - if (coordinate_len > sizeof(r)) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - /* Since raw and der buffers might overlap, dump r and s before starting - * the conversion. */ - memcpy(r, raw, coordinate_len); - memcpy(s, raw + coordinate_len, coordinate_len); - - /* der buffer will initially be written starting from its end so we pick s - * first and then r. */ - ret = convert_raw_to_der_single_int(s, coordinate_len, der, p); - if (ret < 0) { - return ret; - } - p -= ret; - len += ret; - - ret = convert_raw_to_der_single_int(r, coordinate_len, der, p); - if (ret < 0) { - return ret; - } - p -= ret; - len += ret; - - /* Add ASN.1 header (len + tag). */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - /* memmove the content of der buffer to its beginnig. */ - memmove(der, p, len); - *der_len = len; - - return 0; -} - -/** - * \brief Convert a single integer from ASN.1 DER format to raw. - * - * \param der Buffer containing the DER integer value to be - * converted. - * \param der_len Length of the der buffer in bytes. - * \param raw Output buffer that will be filled with the - * converted data. This should be at least - * coordinate_size bytes and it must be zeroed before - * calling this function. - * \param coordinate_size Size (in bytes) of a single coordinate in raw - * format. - * - * \return On success, the amount of DER data parsed from the - * provided der buffer. - * \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag - * is missing in the der buffer. - * \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer - * is null (i.e. all zeros) or if the output raw buffer - * is too small to contain the converted raw value. - * - * \warning Der and raw buffers must not be overlapping. - */ -static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len, - unsigned char *raw, size_t coordinate_size) -{ - unsigned char *p = der; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t unpadded_len, padding_len = 0; - - /* Get the length of ASN.1 element (i.e. the integer we need to parse). */ - ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len, - MBEDTLS_ASN1_INTEGER); - if (ret != 0) { - return ret; - } - - /* It's invalid to have: - * - unpadded_len == 0. - * - MSb set without a leading 0x00 (leading 0x00 is checked below). */ - if (((unpadded_len == 0) || (*p & 0x80) != 0)) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - - /* Skip possible leading zero */ - if (*p == 0x00) { - p++; - unpadded_len--; - /* It is not allowed to have more than 1 leading zero. - * Ignore the case in which unpadded_len = 0 because that's a 0 encoded - * in ASN.1 format (i.e. 020100). */ - if ((unpadded_len > 0) && (*p == 0x00)) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - } - - if (unpadded_len > coordinate_size) { - /* Parsed number is longer than the maximum expected value. */ - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - padding_len = coordinate_size - unpadded_len; - /* raw buffer was already zeroed by the calling function so zero-padding - * operation is skipped here. */ - memcpy(raw + padding_len, p, unpadded_len); - p += unpadded_len; - - return (int) (p - der); -} - -int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len, - unsigned char *raw, size_t raw_size, size_t *raw_len) -{ - unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE]; - unsigned char *p = (unsigned char *) der; - size_t data_len; - size_t coordinate_size = PSA_BITS_TO_BYTES(bits); - int ret; - - if (bits == 0) { - return MBEDTLS_ERR_ASN1_INVALID_DATA; - } - /* The output raw buffer should be at least twice the size of a raw - * coordinate in order to store r and s. */ - if (raw_size < coordinate_size * 2) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - if (2 * coordinate_size > sizeof(raw_tmp)) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - /* Check that the provided input DER buffer has the right header. */ - ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - if (ret != 0) { - return ret; - } - - memset(raw_tmp, 0, 2 * coordinate_size); - - /* Extract r */ - ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size); - if (ret < 0) { - return ret; - } - p += ret; - data_len -= ret; - - /* Extract s */ - ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size, - coordinate_size); - if (ret < 0) { - return ret; - } - p += ret; - data_len -= ret; - - /* Check that we consumed all the input der data. */ - if ((size_t) (p - der) != der_len) { - return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } - - memcpy(raw, raw_tmp, 2 * coordinate_size); - *raw_len = 2 * coordinate_size; - - return 0; -} - -#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ diff --git a/vendor/mbedtls/library/psa_util_internal.h b/vendor/mbedtls/library/psa_util_internal.h deleted file mode 100644 index 70a08a02c..000000000 --- a/vendor/mbedtls/library/psa_util_internal.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * \file psa_util_internal.h - * - * \brief Internal utility functions for use of PSA Crypto. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_PSA_UTIL_INTERNAL_H -#define MBEDTLS_PSA_UTIL_INTERNAL_H - -/* Include the public header so that users only need one include. */ -#include "mbedtls/psa_util.h" - -#include "psa/crypto.h" - -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) - -/************************************************************************* - * FFDH - ************************************************************************/ - -#define MBEDTLS_PSA_MAX_FFDH_PUBKEY_LENGTH \ - PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) - -/************************************************************************* - * ECC - ************************************************************************/ - -#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) - -#define MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH \ - PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) - -/************************************************************************* - * Error translation - ************************************************************************/ - -typedef struct { - /* Error codes used by PSA crypto are in -255..-128, fitting in 16 bits. */ - int16_t psa_status; - /* Error codes used by Mbed TLS are in one of the ranges - * -127..-1 (low-level) or -32767..-4096 (high-level with a low-level - * code optionally added), fitting in 16 bits. */ - int16_t mbedtls_error; -} mbedtls_error_pair_t; - -#if defined(MBEDTLS_MD_LIGHT) -extern const mbedtls_error_pair_t psa_to_md_errors[4]; -#endif - -#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA) -extern const mbedtls_error_pair_t psa_to_cipher_errors[4]; -#endif - -#if defined(MBEDTLS_LMS_C) -extern const mbedtls_error_pair_t psa_to_lms_errors[3]; -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) -extern const mbedtls_error_pair_t psa_to_ssl_errors[7]; -#endif - -#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -extern const mbedtls_error_pair_t psa_to_pk_rsa_errors[8]; -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -extern const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[7]; -#endif - -/* Generic fallback function for error translation, - * when the received state was not module-specific. */ -int psa_generic_status_to_mbedtls(psa_status_t status); - -/* This function iterates over provided local error translations, - * and if no match was found - calls the fallback error translation function. */ -int psa_status_to_mbedtls(psa_status_t status, - const mbedtls_error_pair_t *local_translations, - size_t local_errors_num, - int (*fallback_f)(psa_status_t)); - -/* The second out of three-stage error handling functions of the pk module, - * acts as a fallback after RSA / ECDSA error translation, and if no match - * is found, it itself calls psa_generic_status_to_mbedtls. */ -int psa_pk_status_to_mbedtls(psa_status_t status); - -/* Utility macro to shorten the defines of error translator in modules. */ -#define PSA_TO_MBEDTLS_ERR_LIST(status, error_list, fallback_f) \ - psa_status_to_mbedtls(status, error_list, \ - sizeof(error_list)/sizeof(error_list[0]), \ - fallback_f) - -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ -#endif /* MBEDTLS_PSA_UTIL_INTERNAL_H */ diff --git a/vendor/mbedtls/library/ripemd160.c b/vendor/mbedtls/library/ripemd160.c deleted file mode 100644 index b4fc3cdba..000000000 --- a/vendor/mbedtls/library/ripemd160.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * RIPE MD-160 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The RIPEMD-160 algorithm was designed by RIPE in 1996 - * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html - * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 - */ - -#include "common.h" - -#if defined(MBEDTLS_RIPEMD160_C) - -#include "mbedtls/ripemd160.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_RIPEMD160_ALT) - -void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_ripemd160_context)); -} - -void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ripemd160_context)); -} - -void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst, - const mbedtls_ripemd160_context *src) -{ - *dst = *src; -} - -/* - * RIPEMD-160 context setup - */ -int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - - return 0; -} - -#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) -/* - * Process one block - */ -int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx, - const unsigned char data[64]) -{ - struct { - uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; - } local; - - local.X[0] = MBEDTLS_GET_UINT32_LE(data, 0); - local.X[1] = MBEDTLS_GET_UINT32_LE(data, 4); - local.X[2] = MBEDTLS_GET_UINT32_LE(data, 8); - local.X[3] = MBEDTLS_GET_UINT32_LE(data, 12); - local.X[4] = MBEDTLS_GET_UINT32_LE(data, 16); - local.X[5] = MBEDTLS_GET_UINT32_LE(data, 20); - local.X[6] = MBEDTLS_GET_UINT32_LE(data, 24); - local.X[7] = MBEDTLS_GET_UINT32_LE(data, 28); - local.X[8] = MBEDTLS_GET_UINT32_LE(data, 32); - local.X[9] = MBEDTLS_GET_UINT32_LE(data, 36); - local.X[10] = MBEDTLS_GET_UINT32_LE(data, 40); - local.X[11] = MBEDTLS_GET_UINT32_LE(data, 44); - local.X[12] = MBEDTLS_GET_UINT32_LE(data, 48); - local.X[13] = MBEDTLS_GET_UINT32_LE(data, 52); - local.X[14] = MBEDTLS_GET_UINT32_LE(data, 56); - local.X[15] = MBEDTLS_GET_UINT32_LE(data, 60); - - local.A = local.Ap = ctx->state[0]; - local.B = local.Bp = ctx->state[1]; - local.C = local.Cp = ctx->state[2]; - local.D = local.Dp = ctx->state[3]; - local.E = local.Ep = ctx->state[4]; - -#define F1(x, y, z) ((x) ^ (y) ^ (z)) -#define F2(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define F3(x, y, z) (((x) | ~(y)) ^ (z)) -#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define F5(x, y, z) ((x) ^ ((y) | ~(z))) - -#define S(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - -#define P(a, b, c, d, e, r, s, f, k) \ - do \ - { \ - (a) += f((b), (c), (d)) + local.X[r] + (k); \ - (a) = S((a), (s)) + (e); \ - (c) = S((c), 10); \ - } while (0) - -#define P2(a, b, c, d, e, r, s, rp, sp) \ - do \ - { \ - P((a), (b), (c), (d), (e), (r), (s), F, K); \ - P(a ## p, b ## p, c ## p, d ## p, e ## p, \ - (rp), (sp), Fp, Kp); \ - } while (0) - -#define F F1 -#define K 0x00000000 -#define Fp F5 -#define Kp 0x50A28BE6 - P2(local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8); - P2(local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9); - P2(local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9); - P2(local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11); - P2(local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13); - P2(local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15); - P2(local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15); - P2(local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5); - P2(local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7); - P2(local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7); - P2(local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8); - P2(local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11); - P2(local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14); - P2(local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14); - P2(local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12); - P2(local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F2 -#define K 0x5A827999 -#define Fp F4 -#define Kp 0x5C4DD124 - P2(local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9); - P2(local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13); - P2(local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15); - P2(local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7); - P2(local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12); - P2(local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8); - P2(local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9); - P2(local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11); - P2(local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7); - P2(local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7); - P2(local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12); - P2(local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7); - P2(local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6); - P2(local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15); - P2(local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13); - P2(local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F3 -#define K 0x6ED9EBA1 -#define Fp F3 -#define Kp 0x6D703EF3 - P2(local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9); - P2(local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7); - P2(local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15); - P2(local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11); - P2(local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8); - P2(local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6); - P2(local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6); - P2(local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14); - P2(local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12); - P2(local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13); - P2(local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5); - P2(local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14); - P2(local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13); - P2(local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13); - P2(local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7); - P2(local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F4 -#define K 0x8F1BBCDC -#define Fp F2 -#define Kp 0x7A6D76E9 - P2(local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15); - P2(local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5); - P2(local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8); - P2(local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11); - P2(local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14); - P2(local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14); - P2(local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6); - P2(local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14); - P2(local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6); - P2(local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9); - P2(local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12); - P2(local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9); - P2(local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12); - P2(local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5); - P2(local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15); - P2(local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F5 -#define K 0xA953FD4E -#define Fp F1 -#define Kp 0x00000000 - P2(local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8); - P2(local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5); - P2(local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12); - P2(local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9); - P2(local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12); - P2(local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5); - P2(local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14); - P2(local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6); - P2(local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8); - P2(local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13); - P2(local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6); - P2(local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5); - P2(local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15); - P2(local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13); - P2(local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11); - P2(local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11); -#undef F -#undef K -#undef Fp -#undef Kp - - local.C = ctx->state[1] + local.C + local.Dp; - ctx->state[1] = ctx->state[2] + local.D + local.Ep; - ctx->state[2] = ctx->state[3] + local.E + local.Ap; - ctx->state[3] = ctx->state[4] + local.A + local.Bp; - ctx->state[4] = ctx->state[0] + local.B + local.Cp; - ctx->state[0] = local.C; - - /* Zeroise variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize(&local, sizeof(local)); - - return 0; -} - -#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ - -/* - * RIPEMD-160 process buffer - */ -int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx, - const unsigned char *input, - size_t ilen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t fill; - uint32_t left; - - if (ilen == 0) { - return 0; - } - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if (ctx->total[0] < (uint32_t) ilen) { - ctx->total[1]++; - } - - if (left && ilen >= fill) { - memcpy((void *) (ctx->buffer + left), input, fill); - - if ((ret = mbedtls_internal_ripemd160_process(ctx, ctx->buffer)) != 0) { - return ret; - } - - input += fill; - ilen -= fill; - left = 0; - } - - while (ilen >= 64) { - if ((ret = mbedtls_internal_ripemd160_process(ctx, input)) != 0) { - return ret; - } - - input += 64; - ilen -= 64; - } - - if (ilen > 0) { - memcpy((void *) (ctx->buffer + left), input, ilen); - } - - return 0; -} - -static const unsigned char ripemd160_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * RIPEMD-160 final digest - */ -int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx, - unsigned char output[20]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint32_t last, padn; - uint32_t high, low; - unsigned char msglen[8]; - - high = (ctx->total[0] >> 29) - | (ctx->total[1] << 3); - low = (ctx->total[0] << 3); - - MBEDTLS_PUT_UINT32_LE(low, msglen, 0); - MBEDTLS_PUT_UINT32_LE(high, msglen, 4); - - last = ctx->total[0] & 0x3F; - padn = (last < 56) ? (56 - last) : (120 - last); - - ret = mbedtls_ripemd160_update(ctx, ripemd160_padding, padn); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_ripemd160_update(ctx, msglen, 8); - if (ret != 0) { - goto exit; - } - - MBEDTLS_PUT_UINT32_LE(ctx->state[0], output, 0); - MBEDTLS_PUT_UINT32_LE(ctx->state[1], output, 4); - MBEDTLS_PUT_UINT32_LE(ctx->state[2], output, 8); - MBEDTLS_PUT_UINT32_LE(ctx->state[3], output, 12); - MBEDTLS_PUT_UINT32_LE(ctx->state[4], output, 16); - - ret = 0; - -exit: - mbedtls_ripemd160_free(ctx); - return ret; -} - -#endif /* ! MBEDTLS_RIPEMD160_ALT */ - -/* - * output = RIPEMD-160( input buffer ) - */ -int mbedtls_ripemd160(const unsigned char *input, - size_t ilen, - unsigned char output[20]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ripemd160_context ctx; - - mbedtls_ripemd160_init(&ctx); - - if ((ret = mbedtls_ripemd160_starts(&ctx)) != 0) { - goto exit; - } - - if ((ret = mbedtls_ripemd160_update(&ctx, input, ilen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_ripemd160_finish(&ctx, output)) != 0) { - goto exit; - } - -exit: - mbedtls_ripemd160_free(&ctx); - - return ret; -} - -#if defined(MBEDTLS_SELF_TEST) -/* - * Test vectors from the RIPEMD-160 paper and - * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC - */ -#define TESTS 8 -static const unsigned char ripemd160_test_str[TESTS][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }, -}; - -static const size_t ripemd160_test_strlen[TESTS] = -{ - 0, 1, 3, 14, 26, 56, 62, 80 -}; - -static const unsigned char ripemd160_test_md[TESTS][20] = -{ - { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, - 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, - { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, - 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, - { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, - 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, - { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, - 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, - { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, - 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, - { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, - 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, - { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, - 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, - { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, - 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, -}; - -/* - * Checkup routine - */ -int mbedtls_ripemd160_self_test(int verbose) -{ - int i, ret = 0; - unsigned char output[20]; - - memset(output, 0, sizeof(output)); - - for (i = 0; i < TESTS; i++) { - if (verbose != 0) { - mbedtls_printf(" RIPEMD-160 test #%d: ", i + 1); - } - - ret = mbedtls_ripemd160(ripemd160_test_str[i], - ripemd160_test_strlen[i], output); - if (ret != 0) { - goto fail; - } - - if (memcmp(output, ripemd160_test_md[i], 20) != 0) { - ret = 1; - goto fail; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; - -fail: - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_RIPEMD160_C */ diff --git a/vendor/mbedtls/library/rsa.c b/vendor/mbedtls/library/rsa.c deleted file mode 100644 index 2eb042ff5..000000000 --- a/vendor/mbedtls/library/rsa.c +++ /dev/null @@ -1,3120 +0,0 @@ -/* - * The RSA public-key cryptosystem - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * The following sources were referenced in the design of this implementation - * of the RSA algorithm: - * - * [1] A method for obtaining digital signatures and public-key cryptosystems - * R Rivest, A Shamir, and L Adleman - * http://people.csail.mit.edu/rivest/pubs.html#RSA78 - * - * [2] Handbook of Applied Cryptography - 1997, Chapter 8 - * Menezes, van Oorschot and Vanstone - * - * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks - * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and - * Stefan Mangard - * https://arxiv.org/abs/1702.08719v2 - * - */ - -#include "common.h" - -#if defined(MBEDTLS_RSA_C) - -#include "mbedtls/rsa.h" -#include "bignum_core.h" -#include "bignum_internal.h" -#include "rsa_alt_helpers.h" -#include "rsa_internal.h" -#include "mbedtls/oid.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" -#include "constant_time_internal.h" -#include "mbedtls/constant_time.h" -#include "md_psa.h" - -#include - -#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__) -#include -#endif - -#include "mbedtls/platform.h" - -/* - * Wrapper around mbedtls_asn1_get_mpi() that rejects zero. - * - * The value zero is: - * - never a valid value for an RSA parameter - * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete(). - * - * Since values can't be omitted in PKCS#1, passing a zero value to - * rsa_complete() would be incorrect, so reject zero values early. - */ -static int asn1_get_nonzero_mpi(unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X) -{ - int ret; - - ret = mbedtls_asn1_get_mpi(p, end, X); - if (ret != 0) { - return ret; - } - - if (mbedtls_mpi_cmp_int(X, 0) == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - return 0; -} - -int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen) -{ - int ret, version; - size_t len; - unsigned char *p, *end; - - mbedtls_mpi T; - mbedtls_mpi_init(&T); - - p = (unsigned char *) key; - end = p + keylen; - - /* - * This function parses the RSAPrivateKey (PKCS#1) - * - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * otherPrimeInfos OtherPrimeInfos OPTIONAL - * } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return ret; - } - - if (end != p + len) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) { - return ret; - } - - if (version != 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* Import N */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_rsa_import(rsa, &T, NULL, NULL, - NULL, NULL)) != 0) { - goto cleanup; - } - - /* Import E */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL, - NULL, &T)) != 0) { - goto cleanup; - } - - /* Import D */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL, - &T, NULL)) != 0) { - goto cleanup; - } - - /* Import P */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_rsa_import(rsa, NULL, &T, NULL, - NULL, NULL)) != 0) { - goto cleanup; - } - - /* Import Q */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_rsa_import(rsa, NULL, NULL, &T, - NULL, NULL)) != 0) { - goto cleanup; - } - -#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT) - /* - * The RSA CRT parameters DP, DQ and QP are nominally redundant, in - * that they can be easily recomputed from D, P and Q. However by - * parsing them from the PKCS1 structure it is possible to avoid - * recalculating them which both reduces the overhead of loading - * RSA private keys into memory and also avoids side channels which - * can arise when computing those values, since all of D, P, and Q - * are secret. See https://eprint.iacr.org/2020/055 for a - * description of one such attack. - */ - - /* Import DP */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) { - goto cleanup; - } - - /* Import DQ */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) { - goto cleanup; - } - - /* Import QP */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) { - goto cleanup; - } - -#else - /* Verify existence of the CRT params */ - if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || - (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) { - goto cleanup; - } -#endif - - /* rsa_complete() doesn't complete anything with the default - * implementation but is still called: - * - for the benefit of alternative implementation that may want to - * pre-compute stuff beyond what's provided (eg Montgomery factors) - * - as is also sanity-checks the key - * - * Furthermore, we also check the public part for consistency with - * mbedtls_pk_parse_pubkey(), as it includes size minima for example. - */ - if ((ret = mbedtls_rsa_complete(rsa)) != 0 || - (ret = mbedtls_rsa_check_pubkey(rsa)) != 0) { - goto cleanup; - } - - if (p != end) { - ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } - -cleanup: - - mbedtls_mpi_free(&T); - - if (ret != 0) { - mbedtls_rsa_free(rsa); - } - - return ret; -} - -int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen) -{ - unsigned char *p = (unsigned char *) key; - unsigned char *end = (unsigned char *) (key + keylen); - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - /* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return ret; - } - - if (end != p + len) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* Import N */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { - return ret; - } - - if ((ret = mbedtls_rsa_import_raw(rsa, p, len, NULL, 0, NULL, 0, - NULL, 0, NULL, 0)) != 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - p += len; - - /* Import E */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { - return ret; - } - - if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, p, len)) != 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - p += len; - - if (mbedtls_rsa_complete(rsa) != 0 || - mbedtls_rsa_check_pubkey(rsa) != 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (p != end) { - return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } - - return 0; -} - -int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start, - unsigned char **p) -{ - size_t len = 0; - int ret; - - mbedtls_mpi T; /* Temporary holding the exported parameters */ - - /* - * Export the parameters one after another to avoid simultaneous copies. - */ - - mbedtls_mpi_init(&T); - - /* Export QP */ - if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export DQ */ - if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export DP */ - if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export Q */ - if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, &T, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export P */ - if ((ret = mbedtls_rsa_export(rsa, NULL, &T, NULL, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export D */ - if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, &T, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export E */ - if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export N */ - if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - -end_of_export: - - mbedtls_mpi_free(&T); - if (ret < 0) { - return ret; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, start, 0)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} - -/* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ -int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start, - unsigned char **p) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - mbedtls_mpi T; - - mbedtls_mpi_init(&T); - - /* Export E */ - if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export N */ - if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) { - goto end_of_export; - } - len += ret; - -end_of_export: - - mbedtls_mpi_free(&T); - if (ret < 0) { - return ret; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} - -#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) - -/** This function performs the unpadding part of a PKCS#1 v1.5 decryption - * operation (EME-PKCS1-v1_5 decoding). - * - * \note The return value from this function is a sensitive value - * (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen - * in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING - * is often a situation that an attacker can provoke and leaking which - * one is the result is precisely the information the attacker wants. - * - * \param input The input buffer which is the payload inside PKCS#1v1.5 - * encryption padding, called the "encoded message EM" - * by the terminology. - * \param ilen The length of the payload in the \p input buffer. - * \param output The buffer for the payload, called "message M" by the - * PKCS#1 terminology. This must be a writable buffer of - * length \p output_max_len bytes. - * \param olen The address at which to store the length of - * the payload. This must not be \c NULL. - * \param output_max_len The length in bytes of the output buffer \p output. - * - * \return \c 0 on success. - * \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE - * The output buffer is too small for the unpadded payload. - * \return #MBEDTLS_ERR_RSA_INVALID_PADDING - * The input doesn't contain properly formatted padding. - */ -static int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input, - size_t ilen, - unsigned char *output, - size_t output_max_len, - size_t *olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, plaintext_max_size; - - /* The following variables take sensitive values: their value must - * not leak into the observable behavior of the function other than - * the designated outputs (output, olen, return value). Otherwise - * this would open the execution of the function to - * side-channel-based variants of the Bleichenbacher padding oracle - * attack. Potential side channels include overall timing, memory - * access patterns (especially visible to an adversary who has access - * to a shared memory cache), and branches (especially visible to - * an adversary who has access to a shared code cache or to a shared - * branch predictor). */ - size_t pad_count = 0; - mbedtls_ct_condition_t bad; - mbedtls_ct_condition_t pad_done; - size_t plaintext_size = 0; - mbedtls_ct_condition_t output_too_large; - - plaintext_max_size = (output_max_len > ilen - 11) ? ilen - 11 - : output_max_len; - - /* Check and get padding length in constant time and constant - * memory trace. The first byte must be 0. */ - bad = mbedtls_ct_bool(input[0]); - - - /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00 - * where PS must be at least 8 nonzero bytes. */ - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(input[1], MBEDTLS_RSA_CRYPT)); - - /* Read the whole buffer. Set pad_done to nonzero if we find - * the 0x00 byte and remember the padding length in pad_count. */ - pad_done = MBEDTLS_CT_FALSE; - for (i = 2; i < ilen; i++) { - mbedtls_ct_condition_t found = mbedtls_ct_uint_eq(input[i], 0); - pad_done = mbedtls_ct_bool_or(pad_done, found); - pad_count += mbedtls_ct_uint_if_else_0(mbedtls_ct_bool_not(pad_done), 1); - } - - /* If pad_done is still zero, there's no data, only unfinished padding. */ - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_not(pad_done)); - - /* There must be at least 8 bytes of padding. */ - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_gt(8, pad_count)); - - /* If the padding is valid, set plaintext_size to the number of - * remaining bytes after stripping the padding. If the padding - * is invalid, avoid leaking this fact through the size of the - * output: use the maximum message size that fits in the output - * buffer. Do it without branches to avoid leaking the padding - * validity through timing. RSA keys are small enough that all the - * size_t values involved fit in unsigned int. */ - plaintext_size = mbedtls_ct_uint_if( - bad, (unsigned) plaintext_max_size, - (unsigned) (ilen - pad_count - 3)); - - /* Set output_too_large to 0 if the plaintext fits in the output - * buffer and to 1 otherwise. */ - output_too_large = mbedtls_ct_uint_gt(plaintext_size, - plaintext_max_size); - - /* Set ret without branches to avoid timing attacks. Return: - * - INVALID_PADDING if the padding is bad (bad != 0). - * - OUTPUT_TOO_LARGE if the padding is good but the decrypted - * plaintext does not fit in the output buffer. - * - 0 if the padding is correct. */ - ret = mbedtls_ct_error_if( - bad, - MBEDTLS_ERR_RSA_INVALID_PADDING, - mbedtls_ct_error_if_else_0(output_too_large, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) - ); - - /* If the padding is bad or the plaintext is too large, zero the - * data that we're about to copy to the output buffer. - * We need to copy the same amount of data - * from the same buffer whether the padding is good or not to - * avoid leaking the padding validity through overall timing or - * through memory or cache access patterns. */ - mbedtls_ct_zeroize_if(mbedtls_ct_bool_or(bad, output_too_large), input + 11, ilen - 11); - - /* If the plaintext is too large, truncate it to the buffer size. - * Copy anyway to avoid revealing the length through timing, because - * revealing the length is as bad as revealing the padding validity - * for a Bleichenbacher attack. */ - plaintext_size = mbedtls_ct_uint_if(output_too_large, - (unsigned) plaintext_max_size, - (unsigned) plaintext_size); - - /* Move the plaintext to the leftmost position where it can start in - * the working buffer, i.e. make it start plaintext_max_size from - * the end of the buffer. Do this with a memory access trace that - * does not depend on the plaintext size. After this move, the - * starting location of the plaintext is no longer sensitive - * information. */ - mbedtls_ct_memmove_left(input + ilen - plaintext_max_size, - plaintext_max_size, - plaintext_max_size - plaintext_size); - - /* Finally copy the decrypted plaintext plus trailing zeros into the output - * buffer. If output_max_len is 0, then output may be an invalid pointer - * and the result of memcpy() would be undefined; prevent undefined - * behavior making sure to depend only on output_max_len (the size of the - * user-provided output buffer), which is independent from plaintext - * length, validity of padding, success of the decryption, and other - * secrets. */ - if (output_max_len != 0) { - memcpy(output, input + ilen - plaintext_max_size, plaintext_max_size); - } - - /* Report the amount of data we copied to the output buffer. In case - * of errors (bad padding or output too large), the value of *olen - * when this function returns is not specified. Making it equivalent - * to the good case limits the risks of leaking the padding validity. */ - *olen = plaintext_size; - - return ret; -} - -#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */ - -#if !defined(MBEDTLS_RSA_ALT) - -int mbedtls_rsa_import(mbedtls_rsa_context *ctx, - const mbedtls_mpi *N, - const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *E) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((N != NULL && (ret = mbedtls_mpi_copy(&ctx->N, N)) != 0) || - (P != NULL && (ret = mbedtls_mpi_copy(&ctx->P, P)) != 0) || - (Q != NULL && (ret = mbedtls_mpi_copy(&ctx->Q, Q)) != 0) || - (D != NULL && (ret = mbedtls_mpi_copy(&ctx->D, D)) != 0) || - (E != NULL && (ret = mbedtls_mpi_copy(&ctx->E, E)) != 0)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } - - if (N != NULL) { - ctx->len = mbedtls_mpi_size(&ctx->N); - } - - return 0; -} - -int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx, - unsigned char const *N, size_t N_len, - unsigned char const *P, size_t P_len, - unsigned char const *Q, size_t Q_len, - unsigned char const *D, size_t D_len, - unsigned char const *E, size_t E_len) -{ - int ret = 0; - - if (N != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->N, N, N_len)); - ctx->len = mbedtls_mpi_size(&ctx->N); - } - - if (P != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->P, P, P_len)); - } - - if (Q != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->Q, Q, Q_len)); - } - - if (D != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->D, D, D_len)); - } - - if (E != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->E, E, E_len)); - } - -cleanup: - - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } - - return 0; -} - -/* - * Checks whether the context fields are set in such a way - * that the RSA primitives will be able to execute without error. - * It does *not* make guarantees for consistency of the parameters. - */ -static int rsa_check_context(mbedtls_rsa_context const *ctx, int is_priv, - int blinding_needed) -{ -#if !defined(MBEDTLS_RSA_NO_CRT) - /* blinding_needed is only used for NO_CRT to decide whether - * P,Q need to be present or not. */ - ((void) blinding_needed); -#endif - - if (ctx->len != mbedtls_mpi_size(&ctx->N) || - ctx->len > MBEDTLS_MPI_MAX_SIZE) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* - * 1. Modular exponentiation needs positive, odd moduli. - */ - - /* Modular exponentiation wrt. N is always used for - * RSA public key operations. */ - if (mbedtls_mpi_cmp_int(&ctx->N, 0) <= 0 || - mbedtls_mpi_get_bit(&ctx->N, 0) == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Modular exponentiation for P and Q is only - * used for private key operations and if CRT - * is used. */ - if (is_priv && - (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 || - mbedtls_mpi_get_bit(&ctx->P, 0) == 0 || - mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0 || - mbedtls_mpi_get_bit(&ctx->Q, 0) == 0)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } -#endif /* !MBEDTLS_RSA_NO_CRT */ - - /* - * 2. Exponents must be positive - */ - - /* Always need E for public key operations */ - if (mbedtls_mpi_cmp_int(&ctx->E, 0) <= 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_RSA_NO_CRT) - /* For private key operations, use D or DP & DQ - * as (unblinded) exponents. */ - if (is_priv && mbedtls_mpi_cmp_int(&ctx->D, 0) <= 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } -#else - if (is_priv && - (mbedtls_mpi_cmp_int(&ctx->DP, 0) <= 0 || - mbedtls_mpi_cmp_int(&ctx->DQ, 0) <= 0)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Blinding shouldn't make exponents negative either, - * so check that P, Q >= 1 if that hasn't yet been - * done as part of 1. */ -#if defined(MBEDTLS_RSA_NO_CRT) - if (is_priv && blinding_needed && - (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 || - mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } -#endif - - /* It wouldn't lead to an error if it wasn't satisfied, - * but check for QP >= 1 nonetheless. */ -#if !defined(MBEDTLS_RSA_NO_CRT) - if (is_priv && - mbedtls_mpi_cmp_int(&ctx->QP, 0) <= 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } -#endif - - return 0; -} - -int mbedtls_rsa_complete(mbedtls_rsa_context *ctx) -{ - int ret = 0; - int have_N, have_P, have_Q, have_D, have_E; -#if !defined(MBEDTLS_RSA_NO_CRT) - int have_DP, have_DQ, have_QP; -#endif - int n_missing, pq_missing, d_missing, is_pub, is_priv; - - have_N = (mbedtls_mpi_cmp_int(&ctx->N, 0) != 0); - have_P = (mbedtls_mpi_cmp_int(&ctx->P, 0) != 0); - have_Q = (mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0); - have_D = (mbedtls_mpi_cmp_int(&ctx->D, 0) != 0); - have_E = (mbedtls_mpi_cmp_int(&ctx->E, 0) != 0); - -#if !defined(MBEDTLS_RSA_NO_CRT) - have_DP = (mbedtls_mpi_cmp_int(&ctx->DP, 0) != 0); - have_DQ = (mbedtls_mpi_cmp_int(&ctx->DQ, 0) != 0); - have_QP = (mbedtls_mpi_cmp_int(&ctx->QP, 0) != 0); -#endif - - /* - * Check whether provided parameters are enough - * to deduce all others. The following incomplete - * parameter sets for private keys are supported: - * - * (1) P, Q missing. - * (2) D and potentially N missing. - * - */ - - n_missing = have_P && have_Q && have_D && have_E; - pq_missing = have_N && !have_P && !have_Q && have_D && have_E; - d_missing = have_P && have_Q && !have_D && have_E; - is_pub = have_N && !have_P && !have_Q && !have_D && have_E; - - /* These three alternatives are mutually exclusive */ - is_priv = n_missing || pq_missing || d_missing; - - if (!is_priv && !is_pub) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* - * Step 1: Deduce N if P, Q are provided. - */ - - if (!have_N && have_P && have_Q) { - if ((ret = mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, - &ctx->Q)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } - - ctx->len = mbedtls_mpi_size(&ctx->N); - } - - /* - * Step 2: Deduce and verify all remaining core parameters. - */ - - if (pq_missing) { - ret = mbedtls_rsa_deduce_primes(&ctx->N, &ctx->E, &ctx->D, - &ctx->P, &ctx->Q); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } - - } else if (d_missing) { - if ((ret = mbedtls_rsa_deduce_private_exponent(&ctx->P, - &ctx->Q, - &ctx->E, - &ctx->D)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } - } - - /* - * Step 3: Deduce all additional parameters specific - * to our current RSA implementation. - */ - -#if !defined(MBEDTLS_RSA_NO_CRT) - if (is_priv && !(have_DP && have_DQ && have_QP)) { - ret = mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } - } -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* - * Step 3: Basic sanity checks - */ - - return rsa_check_context(ctx, is_priv, 1); -} - -int mbedtls_rsa_export_raw(const mbedtls_rsa_context *ctx, - unsigned char *N, size_t N_len, - unsigned char *P, size_t P_len, - unsigned char *Q, size_t Q_len, - unsigned char *D, size_t D_len, - unsigned char *E, size_t E_len) -{ - int ret = 0; - int is_priv; - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->E, 0) != 0; - - if (!is_priv) { - /* If we're trying to export private parameters for a public key, - * something must be wrong. */ - if (P != NULL || Q != NULL || D != NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - } - - if (N != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->N, N, N_len)); - } - - if (P != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->P, P, P_len)); - } - - if (Q != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->Q, Q, Q_len)); - } - - if (D != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->D, D, D_len)); - } - - if (E != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->E, E, E_len)); - } - -cleanup: - - return ret; -} - -int mbedtls_rsa_export(const mbedtls_rsa_context *ctx, - mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, - mbedtls_mpi *D, mbedtls_mpi *E) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int is_priv; - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->E, 0) != 0; - - if (!is_priv) { - /* If we're trying to export private parameters for a public key, - * something must be wrong. */ - if (P != NULL || Q != NULL || D != NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - } - - /* Export all requested core parameters. */ - - if ((N != NULL && (ret = mbedtls_mpi_copy(N, &ctx->N)) != 0) || - (P != NULL && (ret = mbedtls_mpi_copy(P, &ctx->P)) != 0) || - (Q != NULL && (ret = mbedtls_mpi_copy(Q, &ctx->Q)) != 0) || - (D != NULL && (ret = mbedtls_mpi_copy(D, &ctx->D)) != 0) || - (E != NULL && (ret = mbedtls_mpi_copy(E, &ctx->E)) != 0)) { - return ret; - } - - return 0; -} - -/* - * Export CRT parameters - * This must also be implemented if CRT is not used, for being able to - * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt - * can be used in this case. - */ -int mbedtls_rsa_export_crt(const mbedtls_rsa_context *ctx, - mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int is_priv; - - /* Check if key is private or public */ - is_priv = - mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 && - mbedtls_mpi_cmp_int(&ctx->E, 0) != 0; - - if (!is_priv) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Export all requested blinding parameters. */ - if ((DP != NULL && (ret = mbedtls_mpi_copy(DP, &ctx->DP)) != 0) || - (DQ != NULL && (ret = mbedtls_mpi_copy(DQ, &ctx->DQ)) != 0) || - (QP != NULL && (ret = mbedtls_mpi_copy(QP, &ctx->QP)) != 0)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } -#else - if ((ret = mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D, - DP, DQ, QP)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret); - } -#endif - - return 0; -} - -/* - * Initialize an RSA context - */ -void mbedtls_rsa_init(mbedtls_rsa_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_rsa_context)); - - ctx->padding = MBEDTLS_RSA_PKCS_V15; - ctx->hash_id = MBEDTLS_MD_NONE; - -#if defined(MBEDTLS_THREADING_C) - /* Set ctx->ver to nonzero to indicate that the mutex has been - * initialized and will need to be freed. */ - ctx->ver = 1; - mbedtls_mutex_init(&ctx->mutex); -#endif -} - -/* - * Set padding for an existing RSA context - */ -int mbedtls_rsa_set_padding(mbedtls_rsa_context *ctx, int padding, - mbedtls_md_type_t hash_id) -{ - switch (padding) { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - break; -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - break; -#endif - default: - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } - -#if defined(MBEDTLS_PKCS1_V21) - if ((padding == MBEDTLS_RSA_PKCS_V21) && - (hash_id != MBEDTLS_MD_NONE)) { - /* Just make sure this hash is supported in this build. */ - if (mbedtls_md_info_from_type(hash_id) == NULL) { - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } - } -#endif /* MBEDTLS_PKCS1_V21 */ - - ctx->padding = padding; - ctx->hash_id = hash_id; - - return 0; -} - -/* - * Get padding mode of initialized RSA context - */ -int mbedtls_rsa_get_padding_mode(const mbedtls_rsa_context *ctx) -{ - return ctx->padding; -} - -/* - * Get hash identifier of mbedtls_md_type_t type - */ -int mbedtls_rsa_get_md_alg(const mbedtls_rsa_context *ctx) -{ - return ctx->hash_id; -} - -/* - * Get length in bits of RSA modulus - */ -size_t mbedtls_rsa_get_bitlen(const mbedtls_rsa_context *ctx) -{ - return mbedtls_mpi_bitlen(&ctx->N); -} - -/* - * Get length in bytes of RSA modulus - */ -size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx) -{ - return ctx->len; -} - -#if defined(MBEDTLS_GENPRIME) - -/* - * Generate an RSA keypair - * - * This generation method follows the RSA key pair generation procedure of - * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072. - */ -int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - unsigned int nbits, int exponent) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_mpi H; - int prime_quality = 0; - - /* - * If the modulus is 1024 bit long or shorter, then the security strength of - * the RSA algorithm is less than or equal to 80 bits and therefore an error - * rate of 2^-80 is sufficient. - */ - if (nbits > 1024) { - prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR; - } - - mbedtls_mpi_init(&H); - - if (exponent < 3 || nbits % 2 != 0) { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - if (nbits < MBEDTLS_RSA_GEN_KEY_MIN_BITS) { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - /* - * find primes P and Q with Q < P so that: - * 1. |P-Q| > 2^( nbits / 2 - 100 ) - * 2. GCD( E, (P-1)*(Q-1) ) == 1 - * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 ) - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->E, exponent)); - - do { - MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->P, nbits >> 1, - prime_quality, f_rng, p_rng)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->Q, nbits >> 1, - prime_quality, f_rng, p_rng)); - - /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&H, &ctx->P, &ctx->Q)); - if (mbedtls_mpi_bitlen(&H) <= ((nbits >= 200) ? ((nbits >> 1) - 99) : 0)) { - continue; - } - - /* not required by any standards, but some users rely on the fact that P > Q */ - if (H.s < 0) { - mbedtls_mpi_swap(&ctx->P, &ctx->Q); - } - - /* Compute D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) - * if it exists (FIPS 186-4 §B.3.1 criterion 2(a)) */ - ret = mbedtls_rsa_deduce_private_exponent(&ctx->P, &ctx->Q, &ctx->E, &ctx->D); - if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { - continue; - } - if (ret != 0) { - goto cleanup; - } - - /* (FIPS 186-4 §B.3.1 criterion 3(a)) */ - if (mbedtls_mpi_bitlen(&ctx->D) <= ((nbits + 1) / 2)) { - continue; - } - - break; - } while (1); - - - /* N = P * Q */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, &ctx->Q)); - ctx->len = mbedtls_mpi_size(&ctx->N); - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* - * DP = D mod (P - 1) - * DQ = D mod (Q - 1) - * QP = Q^-1 mod P - */ - MBEDTLS_MPI_CHK(mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP)); -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Double-check */ - MBEDTLS_MPI_CHK(mbedtls_rsa_check_privkey(ctx)); - -cleanup: - - mbedtls_mpi_free(&H); - - if (ret != 0) { - mbedtls_rsa_free(ctx); - - if ((-ret & ~0x7f) == 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret); - } - return ret; - } - - return 0; -} - -#endif /* MBEDTLS_GENPRIME */ - -/* - * Check a public RSA key - */ -int mbedtls_rsa_check_pubkey(const mbedtls_rsa_context *ctx) -{ - if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */) != 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - if (mbedtls_mpi_bitlen(&ctx->N) < 128) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - if (mbedtls_mpi_get_bit(&ctx->E, 0) == 0 || - mbedtls_mpi_bitlen(&ctx->E) < 2 || - mbedtls_mpi_cmp_mpi(&ctx->E, &ctx->N) >= 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - return 0; -} - -/* - * Check for the consistency of all fields in an RSA private key context - */ -int mbedtls_rsa_check_privkey(const mbedtls_rsa_context *ctx) -{ - if (mbedtls_rsa_check_pubkey(ctx) != 0 || - rsa_check_context(ctx, 1 /* private */, 1 /* blinding */) != 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - if (mbedtls_rsa_validate_params(&ctx->N, &ctx->P, &ctx->Q, - &ctx->D, &ctx->E, NULL, NULL) != 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - -#if !defined(MBEDTLS_RSA_NO_CRT) - else if (mbedtls_rsa_validate_crt(&ctx->P, &ctx->Q, &ctx->D, - &ctx->DP, &ctx->DQ, &ctx->QP) != 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } -#endif - - return 0; -} - -/* - * Check if contexts holding a public and private key match - */ -int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub, - const mbedtls_rsa_context *prv) -{ - if (mbedtls_rsa_check_pubkey(pub) != 0 || - mbedtls_rsa_check_privkey(prv) != 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - if (mbedtls_mpi_cmp_mpi(&pub->N, &prv->N) != 0 || - mbedtls_mpi_cmp_mpi(&pub->E, &prv->E) != 0) { - return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - return 0; -} - -/* - * Do an RSA public key operation - */ -int mbedtls_rsa_public(mbedtls_rsa_context *ctx, - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen; - mbedtls_mpi T; - - if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - mbedtls_mpi_init(&T); - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len)); - - if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - olen = ctx->len; - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_unsafe(&T, &T, &ctx->E, &ctx->N, &ctx->RN)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - mbedtls_mpi_free(&T); - - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret); - } - - return 0; -} - -#if !defined(MBEDTLS_RSA_NO_CRT) -/* - * Compute T such that T = TP mod P and T = TQ mod Q. - * (This is the Chinese Remainder Theorem - CRT.) - */ -static int rsa_apply_crt(mbedtls_mpi *T, - const mbedtls_mpi *TP, - const mbedtls_mpi *TQ, - const mbedtls_rsa_context *ctx) -{ - int ret; - - /* - * Set T = ((TP - TQ) * (Q^-1 mod P) mod P) * Q + TQ - * - * That way we have both: - * mod P: T = (TP - TQ) * (Q^-1 * Q) + TQ = (TP - TQ) * 1 + TQ = TP - * mod Q: T = (...) * Q + TQ = TQ - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(T, TP, TQ)); // T = TP - TQ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(T, T, &ctx->QP)); // T *= Q^-1 mod P - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(T, T, &ctx->P)); // T %= P - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(T, T, &ctx->Q)); // T *= Q - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(T, T, TQ)); // T += TQ - -cleanup: - return ret; -} -#endif - -/* Generate random A and B such that A^-1 = B mod N */ -static int rsa_gen_rand_with_inverse(const mbedtls_rsa_context *ctx, - mbedtls_mpi *A, - mbedtls_mpi *B, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ -#if defined(MBEDTLS_RSA_NO_CRT) - int ret; - mbedtls_mpi G; - - mbedtls_mpi_init(&G); - - MBEDTLS_MPI_CHK(mbedtls_mpi_random(A, 1, &ctx->N, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, B, A, &ctx->N)); - - if (mbedtls_mpi_cmp_int(&G, 1) != 0) { - /* This happens if we're unlucky enough to draw a multiple of P or Q, - * or if (at least) one of them is not a prime, and we drew a multiple - * of one of its factors. */ - ret = MBEDTLS_ERR_RSA_RNG_FAILED; - goto cleanup; - } - -cleanup: - mbedtls_mpi_free(&G); - - return ret; -#else - int ret; - mbedtls_mpi Ap, Aq, Bp, Bq, G; - - mbedtls_mpi_init(&Ap); mbedtls_mpi_init(&Aq); - mbedtls_mpi_init(&Bp); mbedtls_mpi_init(&Bq); - mbedtls_mpi_init(&G); - - /* - * Instead of generating A, B = A^-1 (mod N) directly, generate one Ap, Bp - * pair (mod P) and one pair (mod Q) and use Chinese Remainder Theorem to - * construct an A and B from those. - * - * This works because the CRT correspondence is a ring isomorphism between - * Z/NZ (integers mod N) and Z/PZ x Z/QZ (pairs of integers mod P and Q): - * - it is a bijection (one-to-one correspondence); - * - doing a ring operation (modular +, -, *, ^-1 when possible) on one side is - * the same as doing it on the other side. - * So, drawing uniformly at random an invertible A mod N is the same as - * drawing uniformly at random pairs of invertible Ap mod P, Aq mod Q. - */ - - /* Generate Ap in [1, P) and compute Bp = Ap^-1 mod P */ - MBEDTLS_MPI_CHK(mbedtls_mpi_random(&Ap, 1, &ctx->P, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &Bp, &Ap, &ctx->P)); - if (mbedtls_mpi_cmp_int(&G, 1) != 0) { - /* This can only happen if P was not a prime. */ - ret = MBEDTLS_ERR_RSA_RNG_FAILED; - goto cleanup; - } - - /* Generate Aq in [1, Q) and compute Bq = Aq^-1 mod Q */ - MBEDTLS_MPI_CHK(mbedtls_mpi_random(&Aq, 1, &ctx->Q, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &Bq, &Aq, &ctx->Q)); - if (mbedtls_mpi_cmp_int(&G, 1) != 0) { - /* This can only happen if Q was not a prime. */ - ret = MBEDTLS_ERR_RSA_RNG_FAILED; - goto cleanup; - } - - /* Reconstruct A and B */ - MBEDTLS_MPI_CHK(rsa_apply_crt(A, &Ap, &Aq, ctx)); - MBEDTLS_MPI_CHK(rsa_apply_crt(B, &Bp, &Bq, ctx)); - -cleanup: - mbedtls_mpi_free(&Ap); mbedtls_mpi_free(&Aq); - mbedtls_mpi_free(&Bp); mbedtls_mpi_free(&Bq); - mbedtls_mpi_free(&G); - - return ret; -#endif -} - -/* - * Generate or update blinding values, see section 10 of: - * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, - * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer - * Berlin Heidelberg, 1996. p. 104-113. - */ -static int rsa_prepare_blinding(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ - int ret; - - if (ctx->Vf.p != NULL) { - /* We already have blinding values, just update them by squaring */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->N)); - goto cleanup; - } - - /* Unblinding value: Vf = random number, invertible mod N */ - MBEDTLS_MPI_CHK(rsa_gen_rand_with_inverse(ctx, &ctx->Vf, &ctx->Vi, f_rng, p_rng)); - - /* Blinding value: Vi = Vf^(-e) mod N - * (Vi already contains Vf^-1 at this point) */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN)); - -cleanup: - return ret; -} - -/* - * Unblind - * T = T * Vf mod N - */ -static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); - const size_t nlimbs = N->n; - const size_t tlimbs = mbedtls_mpi_core_montmul_working_limbs(nlimbs); - mbedtls_mpi RR, M_T; - - mbedtls_mpi_init(&RR); - mbedtls_mpi_init(&M_T); - - MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&M_T, tlimbs)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs)); - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs)); - - /* T = T * Vf mod N - * Reminder: montmul(A, B, N) = A * B * R^-1 mod N - * Usually both operands are multiplied by R mod N beforehand (by calling - * `to_mont_rep()` on them), yielding a result that's also * R mod N (aka - * "in the Montgomery domain"). Here we only multiply one operand by R mod - * N, so the result is directly what we want - no need to call - * `from_mont_rep()` on it. */ - mbedtls_mpi_core_to_mont_rep(T->p, T->p, N->p, nlimbs, mm, RR.p, M_T.p); - mbedtls_mpi_core_montmul(T->p, T->p, Vf->p, nlimbs, N->p, nlimbs, mm, M_T.p); - -cleanup: - - mbedtls_mpi_free(&RR); - mbedtls_mpi_free(&M_T); - - return ret; -} - -/* - * Exponent blinding supposed to prevent side-channel attacks using multiple - * traces of measurements to recover the RSA key. The more collisions are there, - * the more bits of the key can be recovered. See [3]. - * - * Collecting n collisions with m bit long blinding value requires 2^(m-m/n) - * observations on average. - * - * For example with 28 byte blinding to achieve 2 collisions the adversary has - * to make 2^112 observations on average. - * - * (With the currently (as of 2017 April) known best algorithms breaking 2048 - * bit RSA requires approximately as much time as trying out 2^112 random keys. - * Thus in this sense with 28 byte blinding the security is not reduced by - * side-channel attacks like the one in [3]) - * - * This countermeasure does not help if the key recovery is possible with a - * single trace. - */ -#define RSA_EXPONENT_BLINDING 28 - -/* - * Do an RSA private key operation - */ -int mbedtls_rsa_private(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - const unsigned char *input, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen; - - /* Temporary holding the result */ - mbedtls_mpi T; - - /* Temporaries holding P-1, Q-1 and the - * exponent blinding factor, respectively. */ - mbedtls_mpi P1, Q1, R; - -#if !defined(MBEDTLS_RSA_NO_CRT) - /* Temporaries holding the results mod p resp. mod q. */ - mbedtls_mpi TP, TQ; - - /* Temporaries holding the blinded exponents for - * the mod p resp. mod q computation (if used). */ - mbedtls_mpi DP_blind, DQ_blind; -#else - /* Temporary holding the blinded exponent (if used). */ - mbedtls_mpi D_blind; -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Temporaries holding the initial input and the double - * checked result; should be the same in the end. */ - mbedtls_mpi input_blinded, check_result_blinded; - - if (f_rng == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (rsa_check_context(ctx, 1 /* private key checks */, - 1 /* blinding on */) != 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - /* MPI Initialization */ - mbedtls_mpi_init(&T); - - mbedtls_mpi_init(&P1); - mbedtls_mpi_init(&Q1); - mbedtls_mpi_init(&R); - -#if defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_init(&D_blind); -#else - mbedtls_mpi_init(&DP_blind); - mbedtls_mpi_init(&DQ_blind); -#endif - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_init(&TP); mbedtls_mpi_init(&TQ); -#endif - - mbedtls_mpi_init(&input_blinded); - mbedtls_mpi_init(&check_result_blinded); - - /* End of MPI initialization */ - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len)); - if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - /* - * Blinding - * T = T * Vi mod N - */ - MBEDTLS_MPI_CHK(rsa_prepare_blinding(ctx, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vi)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&input_blinded, &T)); - - /* - * Exponent blinding - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&P1, &ctx->P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&Q1, &ctx->Q, 1)); - -#if defined(MBEDTLS_RSA_NO_CRT) - /* - * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING, - f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &P1, &Q1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &D_blind, &R)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&D_blind, &D_blind, &ctx->D)); -#else - /* - * DP_blind = ( P - 1 ) * R + DP - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING, - f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DP_blind, &P1, &R)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DP_blind, &DP_blind, - &ctx->DP)); - - /* - * DQ_blind = ( Q - 1 ) * R + DQ - */ - MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING, - f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DQ_blind, &Q1, &R)); - MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DQ_blind, &DQ_blind, - &ctx->DQ)); -#endif /* MBEDTLS_RSA_NO_CRT */ - -#if defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &D_blind, &ctx->N, &ctx->RN)); -#else - /* - * Faster decryption using the CRT - * - * TP = input ^ dP mod P - * TQ = input ^ dQ mod Q - */ - - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, &DP_blind, &ctx->P, &ctx->RP)); - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, &DQ_blind, &ctx->Q, &ctx->RQ)); - MBEDTLS_MPI_CHK(rsa_apply_crt(&T, &TP, &TQ, ctx)); -#endif /* MBEDTLS_RSA_NO_CRT */ - - /* Verify the result to prevent glitching attacks. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&check_result_blinded, &T, &ctx->E, - &ctx->N, &ctx->RN)); - if (mbedtls_mpi_cmp_mpi(&check_result_blinded, &input_blinded) != 0) { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto cleanup; - } - - /* - * Unblind - * T = T * Vf mod N - */ - MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N)); - - olen = ctx->len; - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - mbedtls_mpi_free(&P1); - mbedtls_mpi_free(&Q1); - mbedtls_mpi_free(&R); - -#if defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free(&D_blind); -#else - mbedtls_mpi_free(&DP_blind); - mbedtls_mpi_free(&DQ_blind); -#endif - - mbedtls_mpi_free(&T); - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free(&TP); mbedtls_mpi_free(&TQ); -#endif - - mbedtls_mpi_free(&check_result_blinded); - mbedtls_mpi_free(&input_blinded); - - if (ret != 0 && ret >= -0x007f) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret); - } - - return ret; -} - -#if defined(MBEDTLS_PKCS1_V21) -/** - * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. - * - * \param dst buffer to mask - * \param dlen length of destination buffer - * \param src source of the mask generation - * \param slen length of the source buffer - * \param md_alg message digest to use - */ -static int mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, - size_t slen, mbedtls_md_type_t md_alg) -{ - unsigned char counter[4]; - unsigned char *p; - unsigned int hlen; - size_t i, use_len; - unsigned char mask[MBEDTLS_MD_MAX_SIZE]; - int ret = 0; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - - mbedtls_md_init(&md_ctx); - md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - mbedtls_md_init(&md_ctx); - if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { - goto exit; - } - - hlen = mbedtls_md_get_size(md_info); - - memset(mask, 0, sizeof(mask)); - memset(counter, 0, 4); - - /* Generate and apply dbMask */ - p = dst; - - while (dlen > 0) { - use_len = hlen; - if (dlen < hlen) { - use_len = dlen; - } - - if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, src, slen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, counter, 4)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_finish(&md_ctx, mask)) != 0) { - goto exit; - } - - for (i = 0; i < use_len; ++i) { - *p++ ^= mask[i]; - } - - counter[3]++; - - dlen -= use_len; - } - -exit: - mbedtls_platform_zeroize(mask, sizeof(mask)); - mbedtls_md_free(&md_ctx); - - return ret; -} - -/** - * Generate Hash(M') as in RFC 8017 page 43 points 5 and 6. - * - * \param hash the input hash - * \param hlen length of the input hash - * \param salt the input salt - * \param slen length of the input salt - * \param out the output buffer - must be large enough for \p md_alg - * \param md_alg message digest to use - */ -static int hash_mprime(const unsigned char *hash, size_t hlen, - const unsigned char *salt, size_t slen, - unsigned char *out, mbedtls_md_type_t md_alg) -{ - const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - mbedtls_md_context_t md_ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - mbedtls_md_init(&md_ctx); - if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_starts(&md_ctx)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, zeros, sizeof(zeros))) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, hash, hlen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_update(&md_ctx, salt, slen)) != 0) { - goto exit; - } - if ((ret = mbedtls_md_finish(&md_ctx, out)) != 0) { - goto exit; - } - -exit: - mbedtls_md_free(&md_ctx); - - return ret; -} - -/** - * Compute a hash. - * - * \param md_alg algorithm to use - * \param input input message to hash - * \param ilen input length - * \param output the output buffer - must be large enough for \p md_alg - */ -static int compute_hash(mbedtls_md_type_t md_alg, - const unsigned char *input, size_t ilen, - unsigned char *output) -{ - const mbedtls_md_info_t *md_info; - - md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - return mbedtls_md(md_info, input, ilen, output); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function - */ -int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - const unsigned char *label, size_t label_len, - size_t ilen, - const unsigned char *input, - unsigned char *output) -{ - size_t olen; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = output; - unsigned int hlen; - - if (f_rng == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id); - if (hlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - olen = ctx->len; - - /* first comparison checks for overflow */ - if (ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - memset(output, 0, olen); - - *p++ = 0; - - /* Generate a random octet string seed */ - if ((ret = f_rng(p_rng, p, hlen)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret); - } - - p += hlen; - - /* Construct DB */ - ret = compute_hash((mbedtls_md_type_t) ctx->hash_id, label, label_len, p); - if (ret != 0) { - return ret; - } - p += hlen; - p += olen - 2 * hlen - 2 - ilen; - *p++ = 1; - if (ilen != 0) { - memcpy(p, input, ilen); - } - - /* maskedDB: Apply dbMask to DB */ - if ((ret = mgf_mask(output + hlen + 1, olen - hlen - 1, output + 1, hlen, - (mbedtls_md_type_t) ctx->hash_id)) != 0) { - return ret; - } - - /* maskedSeed: Apply seedMask to seed */ - if ((ret = mgf_mask(output + 1, hlen, output + hlen + 1, olen - hlen - 1, - (mbedtls_md_type_t) ctx->hash_id)) != 0) { - return ret; - } - - return mbedtls_rsa_public(ctx, output, output); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function - */ -int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, size_t ilen, - const unsigned char *input, - unsigned char *output) -{ - size_t nb_pad, olen; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = output; - - olen = ctx->len; - - /* first comparison checks for overflow */ - if (ilen + 11 < ilen || olen < ilen + 11) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - nb_pad = olen - 3 - ilen; - - *p++ = 0; - - if (f_rng == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - *p++ = MBEDTLS_RSA_CRYPT; - - while (nb_pad-- > 0) { - int rng_dl = 100; - - do { - ret = f_rng(p_rng, p, 1); - } while (*p == 0 && --rng_dl && ret == 0); - - /* Check if RNG failed to generate data */ - if (rng_dl == 0 || ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret); - } - - p++; - } - - *p++ = 0; - if (ilen != 0) { - memcpy(p, input, ilen); - } - - return mbedtls_rsa_public(ctx, output, output); -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Add the message padding, then do an RSA operation - */ -int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - size_t ilen, - const unsigned char *input, - unsigned char *output) -{ - switch (ctx->padding) { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx, f_rng, p_rng, - ilen, input, output); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsaes_oaep_encrypt(ctx, f_rng, p_rng, NULL, 0, - ilen, input, output); -#endif - - default: - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function - */ -int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - const unsigned char *label, size_t label_len, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t ilen, i, pad_len; - unsigned char *p; - mbedtls_ct_condition_t bad, in_padding; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; - unsigned int hlen; - - /* - * Parameters sanity checks - */ - if (ctx->padding != MBEDTLS_RSA_PKCS_V21) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - ilen = ctx->len; - - if (ilen < 16 || ilen > sizeof(buf)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id); - if (hlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - // checking for integer underflow - if (2 * hlen + 2 > ilen) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* - * RSA operation - */ - ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf); - - if (ret != 0) { - goto cleanup; - } - - /* - * Unmask data and generate lHash - */ - /* seed: Apply seedMask to maskedSeed */ - if ((ret = mgf_mask(buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, - (mbedtls_md_type_t) ctx->hash_id)) != 0 || - /* DB: Apply dbMask to maskedDB */ - (ret = mgf_mask(buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, - (mbedtls_md_type_t) ctx->hash_id)) != 0) { - goto cleanup; - } - - /* Generate lHash */ - ret = compute_hash((mbedtls_md_type_t) ctx->hash_id, - label, label_len, lhash); - if (ret != 0) { - goto cleanup; - } - - /* - * Check contents, in "constant-time" - */ - p = buf; - - bad = mbedtls_ct_bool(*p++); /* First byte must be 0 */ - - p += hlen; /* Skip seed */ - - /* Check lHash */ - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool(mbedtls_ct_memcmp(lhash, p, hlen))); - p += hlen; - - /* Get zero-padding len, but always read till end of buffer - * (minus one, for the 01 byte) */ - pad_len = 0; - in_padding = MBEDTLS_CT_TRUE; - for (i = 0; i < ilen - 2 * hlen - 2; i++) { - in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_uint_eq(p[i], 0)); - pad_len += mbedtls_ct_uint_if_else_0(in_padding, 1); - } - - p += pad_len; - bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(*p++, 0x01)); - - /* - * The only information "leaked" is whether the padding was correct or not - * (eg, no data is copied if it was not correct). This meets the - * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between - * the different error conditions. - */ - if (bad != MBEDTLS_CT_FALSE) { - ret = MBEDTLS_ERR_RSA_INVALID_PADDING; - goto cleanup; - } - - if (ilen - ((size_t) (p - buf)) > output_max_len) { - ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; - goto cleanup; - } - - *olen = ilen - ((size_t) (p - buf)); - if (*olen != 0) { - memcpy(output, p, *olen); - } - ret = 0; - -cleanup: - mbedtls_platform_zeroize(buf, sizeof(buf)); - mbedtls_platform_zeroize(lhash, sizeof(lhash)); - - return ret; -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function - */ -int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t ilen; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; - - ilen = ctx->len; - - if (ctx->padding != MBEDTLS_RSA_PKCS_V15) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (ilen < 16 || ilen > sizeof(buf)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf); - - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding(buf, ilen, - output, output_max_len, olen); - -cleanup: - mbedtls_platform_zeroize(buf, sizeof(buf)); - - return ret; -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation, then remove the message padding - */ -int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len) -{ - switch (ctx->padding) { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx, f_rng, p_rng, olen, - input, output, output_max_len); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsaes_oaep_decrypt(ctx, f_rng, p_rng, NULL, 0, - olen, input, output, - output_max_len); -#endif - - default: - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } -} - -#if defined(MBEDTLS_PKCS1_V21) -static int rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - int saltlen, - unsigned char *sig) -{ - size_t olen; - unsigned char *p = sig; - unsigned char *salt = NULL; - size_t slen, min_slen, hlen, offset = 0; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t msb; - mbedtls_md_type_t hash_id; - - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (f_rng == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - olen = ctx->len; - - if (md_alg != MBEDTLS_MD_NONE) { - /* Gather length of hash to sign */ - size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg); - if (exp_hashlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (hashlen != exp_hashlen) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - } - - hash_id = (mbedtls_md_type_t) ctx->hash_id; - if (hash_id == MBEDTLS_MD_NONE) { - hash_id = md_alg; - } - hlen = mbedtls_md_get_size_from_type(hash_id); - if (hlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY) { - /* Calculate the largest possible salt length, up to the hash size. - * Normally this is the hash length, which is the maximum salt length - * according to FIPS 185-4 §5.5 (e) and common practice. If there is not - * enough room, use the maximum salt length that fits. The constraint is - * that the hash length plus the salt length plus 2 bytes must be at most - * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 - * (PKCS#1 v2.2) §9.1.1 step 3. */ - min_slen = hlen - 2; - if (olen < hlen + min_slen + 2) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } else if (olen >= hlen + hlen + 2) { - slen = hlen; - } else { - slen = olen - hlen - 2; - } - } else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } else { - slen = (size_t) saltlen; - } - - memset(sig, 0, olen); - - /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ - msb = mbedtls_mpi_bitlen(&ctx->N) - 1; - p += olen - hlen - slen - 2; - *p++ = 0x01; - - /* Generate salt of length slen in place in the encoded message */ - salt = p; - if ((ret = f_rng(p_rng, salt, slen)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret); - } - - p += slen; - - /* Generate H = Hash( M' ) */ - ret = hash_mprime(hash, hashlen, salt, slen, p, hash_id); - if (ret != 0) { - return ret; - } - - /* Compensate for boundary condition when applying mask */ - if (msb % 8 == 0) { - offset = 1; - } - - /* maskedDB: Apply dbMask to DB */ - ret = mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_id); - if (ret != 0) { - return ret; - } - - msb = mbedtls_mpi_bitlen(&ctx->N) - 1; - sig[0] &= 0xFF >> (olen * 8 - msb); - - p += hlen; - *p++ = 0xBC; - - return mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig); -} - -static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - int saltlen, - unsigned char *sig) -{ - if (ctx->padding != MBEDTLS_RSA_PKCS_V21) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - if ((ctx->hash_id == MBEDTLS_MD_NONE) && (md_alg == MBEDTLS_MD_NONE)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, hashlen, hash, saltlen, - sig); -} - -int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig) -{ - return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, - hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig); -} - -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with - * the option to pass in the salt length. - */ -int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - int saltlen, - unsigned char *sig) -{ - return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg, - hashlen, hash, saltlen, sig); -} - -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function - */ -int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig) -{ - return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg, - hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig); -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function - */ - -/* Construct a PKCS v1.5 encoding of a hashed message - * - * This is used both for signature generation and verification. - * - * Parameters: - * - md_alg: Identifies the hash algorithm used to generate the given hash; - * MBEDTLS_MD_NONE if raw data is signed. - * - hashlen: Length of hash. Must match md_alg if that's not NONE. - * - hash: Buffer containing the hashed message or the raw data. - * - dst_len: Length of the encoded message. - * - dst: Buffer to hold the encoded message. - * - * Assumptions: - * - hash has size hashlen. - * - dst points to a buffer of size at least dst_len. - * - */ -static int rsa_rsassa_pkcs1_v15_encode(mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - size_t dst_len, - unsigned char *dst) -{ - size_t oid_size = 0; - size_t nb_pad = dst_len; - unsigned char *p = dst; - const char *oid = NULL; - - /* Are we signing hashed or raw data? */ - if (md_alg != MBEDTLS_MD_NONE) { - unsigned char md_size = mbedtls_md_get_size_from_type(md_alg); - if (md_size == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (mbedtls_oid_get_oid_by_md(md_alg, &oid, &oid_size) != 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (hashlen != md_size) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* Double-check that 8 + hashlen + oid_size can be used as a - * 1-byte ASN.1 length encoding and that there's no overflow. */ - if (8 + hashlen + oid_size >= 0x80 || - 10 + hashlen < hashlen || - 10 + hashlen + oid_size < 10 + hashlen) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* - * Static bounds check: - * - Need 10 bytes for five tag-length pairs. - * (Insist on 1-byte length encodings to protect against variants of - * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) - * - Need hashlen bytes for hash - * - Need oid_size bytes for hash alg OID. - */ - if (nb_pad < 10 + hashlen + oid_size) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - nb_pad -= 10 + hashlen + oid_size; - } else { - if (nb_pad < hashlen) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - nb_pad -= hashlen; - } - - /* Need space for signature header and padding delimiter (3 bytes), - * and 8 bytes for the minimal padding */ - if (nb_pad < 3 + 8) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - nb_pad -= 3; - - /* Now nb_pad is the amount of memory to be filled - * with padding, and at least 8 bytes long. */ - - /* Write signature header and padding */ - *p++ = 0; - *p++ = MBEDTLS_RSA_SIGN; - memset(p, 0xFF, nb_pad); - p += nb_pad; - *p++ = 0; - - /* Are we signing raw data? */ - if (md_alg == MBEDTLS_MD_NONE) { - memcpy(p, hash, hashlen); - return 0; - } - - /* Signing hashed data, add corresponding ASN.1 structure - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest } - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * Digest ::= OCTET STRING - * - * Schematic: - * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] - * TAG-NULL + LEN [ NULL ] ] - * TAG-OCTET + LEN [ HASH ] ] - */ - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char) (0x08 + oid_size + hashlen); - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char) (0x04 + oid_size); - *p++ = MBEDTLS_ASN1_OID; - *p++ = (unsigned char) oid_size; - memcpy(p, oid, oid_size); - p += oid_size; - *p++ = MBEDTLS_ASN1_NULL; - *p++ = 0x00; - *p++ = MBEDTLS_ASN1_OCTET_STRING; - *p++ = (unsigned char) hashlen; - memcpy(p, hash, hashlen); - p += hashlen; - - /* Just a sanity-check, should be automatic - * after the initial bounds check. */ - if (p != dst + dst_len) { - mbedtls_platform_zeroize(dst, dst_len); - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - return 0; -} - -/* - * Do an RSA operation to sign the message digest - */ -int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *sig_try = NULL, *verif = NULL; - - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (ctx->padding != MBEDTLS_RSA_PKCS_V15) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* - * Prepare PKCS1-v1.5 encoding (padding and hash identifier) - */ - - if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, - ctx->len, sig)) != 0) { - return ret; - } - - /* Private key operation - * - * In order to prevent Lenstra's attack, make the signature in a - * temporary buffer and check it before returning it. - */ - - sig_try = mbedtls_calloc(1, ctx->len); - if (sig_try == NULL) { - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - verif = mbedtls_calloc(1, ctx->len); - if (verif == NULL) { - mbedtls_free(sig_try); - return MBEDTLS_ERR_MPI_ALLOC_FAILED; - } - - MBEDTLS_MPI_CHK(mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig_try)); - MBEDTLS_MPI_CHK(mbedtls_rsa_public(ctx, sig_try, verif)); - - if (mbedtls_ct_memcmp(verif, sig, ctx->len) != 0) { - ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED; - goto cleanup; - } - - memcpy(sig, sig_try, ctx->len); - -cleanup: - mbedtls_zeroize_and_free(sig_try, ctx->len); - mbedtls_zeroize_and_free(verif, ctx->len); - - if (ret != 0) { - memset(sig, '!', ctx->len); - } - return ret; -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation to sign the message digest - */ -int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig) -{ - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - switch (ctx->padding) { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx, f_rng, p_rng, - md_alg, hashlen, hash, sig); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg, - hashlen, hash, sig); -#endif - - default: - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } -} - -#if defined(MBEDTLS_PKCS1_V21) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function - */ -int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - mbedtls_md_type_t mgf1_hash_id, - int expected_salt_len, - const unsigned char *sig) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t siglen; - unsigned char *p; - unsigned char *hash_start; - unsigned char result[MBEDTLS_MD_MAX_SIZE]; - unsigned int hlen; - size_t observed_salt_len, msb; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = { 0 }; - - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - siglen = ctx->len; - - if (siglen < 16 || siglen > sizeof(buf)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - ret = mbedtls_rsa_public(ctx, sig, buf); - - if (ret != 0) { - return ret; - } - - p = buf; - - if (buf[siglen - 1] != 0xBC) { - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } - - if (md_alg != MBEDTLS_MD_NONE) { - /* Gather length of hash to sign */ - size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg); - if (exp_hashlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - if (hashlen != exp_hashlen) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - } - - hlen = mbedtls_md_get_size_from_type(mgf1_hash_id); - if (hlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* - * Note: EMSA-PSS verification is over the length of N - 1 bits - */ - msb = mbedtls_mpi_bitlen(&ctx->N) - 1; - - if (buf[0] >> (8 - siglen * 8 + msb)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - /* Compensate for boundary condition when applying mask */ - if (msb % 8 == 0) { - p++; - siglen -= 1; - } - - if (siglen < hlen + 2) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - hash_start = p + siglen - hlen - 1; - - ret = mgf_mask(p, siglen - hlen - 1, hash_start, hlen, mgf1_hash_id); - if (ret != 0) { - return ret; - } - - buf[0] &= 0xFF >> (siglen * 8 - msb); - - while (p < hash_start - 1 && *p == 0) { - p++; - } - - if (*p++ != 0x01) { - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } - - observed_salt_len = (size_t) (hash_start - p); - - if (expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY && - observed_salt_len != (size_t) expected_salt_len) { - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } - - /* - * Generate H = Hash( M' ) - */ - ret = hash_mprime(hash, hashlen, p, observed_salt_len, - result, mgf1_hash_id); - if (ret != 0) { - return ret; - } - - if (memcmp(hash_start, result, hlen) != 0) { - return MBEDTLS_ERR_RSA_VERIFY_FAILED; - } - - return 0; -} - -/* - * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function - */ -int mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig) -{ - mbedtls_md_type_t mgf1_hash_id; - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - mgf1_hash_id = (ctx->hash_id != MBEDTLS_MD_NONE) - ? (mbedtls_md_type_t) ctx->hash_id - : md_alg; - - return mbedtls_rsa_rsassa_pss_verify_ext(ctx, - md_alg, hashlen, hash, - mgf1_hash_id, - MBEDTLS_RSA_SALT_LEN_ANY, - sig); - -} -#endif /* MBEDTLS_PKCS1_V21 */ - -#if defined(MBEDTLS_PKCS1_V15) -/* - * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function - */ -int mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig) -{ - int ret = 0; - size_t sig_len; - unsigned char *encoded = NULL, *encoded_expected = NULL; - - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - sig_len = ctx->len; - - /* - * Prepare expected PKCS1 v1.5 encoding of hash. - */ - - if ((encoded = mbedtls_calloc(1, sig_len)) == NULL || - (encoded_expected = mbedtls_calloc(1, sig_len)) == NULL) { - ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; - goto cleanup; - } - - if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, sig_len, - encoded_expected)) != 0) { - goto cleanup; - } - - /* - * Apply RSA primitive to get what should be PKCS1 encoded hash. - */ - - ret = mbedtls_rsa_public(ctx, sig, encoded); - if (ret != 0) { - goto cleanup; - } - - /* - * Compare - */ - - if ((ret = mbedtls_ct_memcmp(encoded, encoded_expected, - sig_len)) != 0) { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto cleanup; - } - -cleanup: - - if (encoded != NULL) { - mbedtls_zeroize_and_free(encoded, sig_len); - } - - if (encoded_expected != NULL) { - mbedtls_zeroize_and_free(encoded_expected, sig_len); - } - - return ret; -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Do an RSA operation and check the message digest - */ -int mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context *ctx, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - const unsigned char *sig) -{ - if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - - switch (ctx->padding) { -#if defined(MBEDTLS_PKCS1_V15) - case MBEDTLS_RSA_PKCS_V15: - return mbedtls_rsa_rsassa_pkcs1_v15_verify(ctx, md_alg, - hashlen, hash, sig); -#endif - -#if defined(MBEDTLS_PKCS1_V21) - case MBEDTLS_RSA_PKCS_V21: - return mbedtls_rsa_rsassa_pss_verify(ctx, md_alg, - hashlen, hash, sig); -#endif - - default: - return MBEDTLS_ERR_RSA_INVALID_PADDING; - } -} - -/* - * Copy the components of an RSA key - */ -int mbedtls_rsa_copy(mbedtls_rsa_context *dst, const mbedtls_rsa_context *src) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - dst->len = src->len; - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->N, &src->N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->E, &src->E)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->D, &src->D)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->P, &src->P)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Q, &src->Q)); - -#if !defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DP, &src->DP)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DQ, &src->DQ)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->QP, &src->QP)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RP, &src->RP)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RQ, &src->RQ)); -#endif - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RN, &src->RN)); - - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vi, &src->Vi)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vf, &src->Vf)); - - dst->padding = src->padding; - dst->hash_id = src->hash_id; - -cleanup: - if (ret != 0) { - mbedtls_rsa_free(dst); - } - - return ret; -} - -/* - * Free the components of an RSA key - */ -void mbedtls_rsa_free(mbedtls_rsa_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_mpi_free(&ctx->Vi); - mbedtls_mpi_free(&ctx->Vf); - mbedtls_mpi_free(&ctx->RN); - mbedtls_mpi_free(&ctx->D); - mbedtls_mpi_free(&ctx->Q); - mbedtls_mpi_free(&ctx->P); - mbedtls_mpi_free(&ctx->E); - mbedtls_mpi_free(&ctx->N); - -#if !defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi_free(&ctx->RQ); - mbedtls_mpi_free(&ctx->RP); - mbedtls_mpi_free(&ctx->QP); - mbedtls_mpi_free(&ctx->DQ); - mbedtls_mpi_free(&ctx->DP); -#endif /* MBEDTLS_RSA_NO_CRT */ - -#if defined(MBEDTLS_THREADING_C) - /* Free the mutex, but only if it hasn't been freed already. */ - if (ctx->ver != 0) { - mbedtls_mutex_free(&ctx->mutex); - ctx->ver = 0; - } -#endif -} - -#endif /* !MBEDTLS_RSA_ALT */ - -#if defined(MBEDTLS_SELF_TEST) - - -/* - * Example RSA-1024 keypair, for test purposes - */ -#define KEY_LEN 128 - -#define RSA_N "9292758453063D803DD603D5E777D788" \ - "8ED1D5BF35786190FA2F23EBC0848AEA" \ - "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ - "7130B9CED7ACDF54CFC7555AC14EEBAB" \ - "93A89813FBF3C4F8066D2D800F7C38A8" \ - "1AE31942917403FF4946B0A83D3D3E05" \ - "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ - "5E94BB77B07507233A0BC7BAC8F90F79" - -#define RSA_E "10001" - -#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ - "66CA472BC44D253102F8B4A9D3BFA750" \ - "91386C0077937FE33FA3252D28855837" \ - "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ - "DF79C5CE07EE72C7F123142198164234" \ - "CABB724CF78B8173B9F880FC86322407" \ - "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ - "071513A1E85B5DFA031F21ECAE91A34D" - -#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ - "2C01CAD19EA484A87EA4377637E75500" \ - "FCB2005C5C7DD6EC4AC023CDA285D796" \ - "C3D9E75E1EFC42488BB4F1D13AC30A57" - -#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ - "E211C2B9E5DB1ED0BF61D0D9899620F4" \ - "910E4168387E3C30AA1E00C339A79508" \ - "8452DD96A9A5EA5D9DCA68DA636032AF" - -#define PT_LEN 24 -#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ - "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" - -#if defined(MBEDTLS_PKCS1_V15) -static int myrand(void *rng_state, unsigned char *output, size_t len) -{ -#if !defined(__OpenBSD__) && !defined(__NetBSD__) - size_t i; - - if (rng_state != NULL) { - rng_state = NULL; - } - - for (i = 0; i < len; ++i) { - output[i] = rand(); - } -#else - if (rng_state != NULL) { - rng_state = NULL; - } - - arc4random_buf(output, len); -#endif /* !OpenBSD && !NetBSD */ - - return 0; -} -#endif /* MBEDTLS_PKCS1_V15 */ - -/* - * Checkup routine - */ -int mbedtls_rsa_self_test(int verbose) -{ - int ret = 0; -#if defined(MBEDTLS_PKCS1_V15) - size_t len; - mbedtls_rsa_context rsa; - unsigned char rsa_plaintext[PT_LEN]; - unsigned char rsa_decrypted[PT_LEN]; - unsigned char rsa_ciphertext[KEY_LEN]; -#if defined(MBEDTLS_MD_CAN_SHA1) - unsigned char sha1sum[20]; -#endif - - mbedtls_mpi K; - - mbedtls_mpi_init(&K); - mbedtls_rsa_init(&rsa); - - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_N)); - MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, &K, NULL, NULL, NULL, NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_P)); - MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, &K, NULL, NULL, NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_Q)); - MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, &K, NULL, NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_D)); - MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, &K, NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_E)); - MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, NULL, &K)); - - MBEDTLS_MPI_CHK(mbedtls_rsa_complete(&rsa)); - - if (verbose != 0) { - mbedtls_printf(" RSA key validation: "); - } - - if (mbedtls_rsa_check_pubkey(&rsa) != 0 || - mbedtls_rsa_check_privkey(&rsa) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n PKCS#1 encryption : "); - } - - memcpy(rsa_plaintext, RSA_PT, PT_LEN); - - if (mbedtls_rsa_pkcs1_encrypt(&rsa, myrand, NULL, - PT_LEN, rsa_plaintext, - rsa_ciphertext) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n PKCS#1 decryption : "); - } - - if (mbedtls_rsa_pkcs1_decrypt(&rsa, myrand, NULL, - &len, rsa_ciphertext, rsa_decrypted, - sizeof(rsa_decrypted)) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (memcmp(rsa_decrypted, rsa_plaintext, len) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - -#if defined(MBEDTLS_MD_CAN_SHA1) - if (verbose != 0) { - mbedtls_printf(" PKCS#1 data sign : "); - } - - if (mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), - rsa_plaintext, PT_LEN, sha1sum) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - return 1; - } - - if (mbedtls_rsa_pkcs1_sign(&rsa, myrand, NULL, - MBEDTLS_MD_SHA1, 20, - sha1sum, rsa_ciphertext) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n PKCS#1 sig. verify: "); - } - - if (mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA1, 20, - sha1sum, rsa_ciphertext) != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - - ret = 1; - goto cleanup; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } -#endif /* MBEDTLS_MD_CAN_SHA1 */ - - if (verbose != 0) { - mbedtls_printf("\n"); - } - -cleanup: - mbedtls_mpi_free(&K); - mbedtls_rsa_free(&rsa); -#else /* MBEDTLS_PKCS1_V15 */ - ((void) verbose); -#endif /* MBEDTLS_PKCS1_V15 */ - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_RSA_C */ diff --git a/vendor/mbedtls/library/rsa_alt_helpers.c b/vendor/mbedtls/library/rsa_alt_helpers.c deleted file mode 100644 index 8a09f93a3..000000000 --- a/vendor/mbedtls/library/rsa_alt_helpers.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Helper functions for the RSA module - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - */ - -#include "common.h" - -#if defined(MBEDTLS_RSA_C) - -#include "mbedtls/rsa.h" -#include "mbedtls/bignum.h" -#include "bignum_internal.h" -#include "rsa_alt_helpers.h" - -/* - * Compute RSA prime factors from public and private exponents - * - * Summary of algorithm: - * Setting F := lcm(P-1,Q-1), the idea is as follows: - * - * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2) - * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the - * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four - * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1) - * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime - * factors of N. - * - * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same - * construction still applies since (-)^K is the identity on the set of - * roots of 1 in Z/NZ. - * - * The public and private key primitives (-)^E and (-)^D are mutually inverse - * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e. - * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L. - * Splitting L = 2^t * K with K odd, we have - * - * DE - 1 = FL = (F/2) * (2^(t+1)) * K, - * - * so (F / 2) * K is among the numbers - * - * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord - * - * where ord is the order of 2 in (DE - 1). - * We can therefore iterate through these numbers apply the construction - * of (a) and (b) above to attempt to factor N. - * - */ -int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N, - mbedtls_mpi const *E, mbedtls_mpi const *D, - mbedtls_mpi *P, mbedtls_mpi *Q) -{ - int ret = 0; - - uint16_t attempt; /* Number of current attempt */ - uint16_t iter; /* Number of squares computed in the current attempt */ - - uint16_t order; /* Order of 2 in DE - 1 */ - - mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */ - mbedtls_mpi K; /* Temporary holding the current candidate */ - - const unsigned char primes[] = { 2, - 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, - 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, - 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251 }; - - const size_t num_primes = sizeof(primes) / sizeof(*primes); - - if (P == NULL || Q == NULL || P->p != NULL || Q->p != NULL) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (mbedtls_mpi_cmp_int(N, 0) <= 0 || - mbedtls_mpi_cmp_int(D, 1) <= 0 || - mbedtls_mpi_cmp_mpi(D, N) >= 0 || - mbedtls_mpi_cmp_int(E, 1) <= 0 || - mbedtls_mpi_cmp_mpi(E, N) >= 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - /* - * Initializations and temporary changes - */ - - mbedtls_mpi_init(&K); - mbedtls_mpi_init(&T); - - /* T := DE - 1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, D, E)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&T, &T, 1)); - - if ((order = (uint16_t) mbedtls_mpi_lsb(&T)) == 0) { - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - goto cleanup; - } - - /* After this operation, T holds the largest odd divisor of DE - 1. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&T, order)); - - /* - * Actual work - */ - - /* Skip trying 2 if N == 1 mod 8 */ - attempt = 0; - if (N->p[0] % 8 == 1) { - attempt = 1; - } - - for (; attempt < num_primes; ++attempt) { - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&K, primes[attempt])); - - /* Check if gcd(K,N) = 1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(P, NULL, &K, N)); - if (mbedtls_mpi_cmp_int(P, 1) != 0) { - continue; - } - - /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ... - * and check whether they have nontrivial GCD with N. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &K, &T, N, - Q /* temporarily use Q for storing Montgomery - * multiplication helper values */)); - - for (iter = 1; iter <= order; ++iter) { - /* If we reach 1 prematurely, there's no point - * in continuing to square K */ - if (mbedtls_mpi_cmp_int(&K, 1) == 0) { - break; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&K, &K, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(P, NULL, &K, N)); - - if (mbedtls_mpi_cmp_int(P, 1) == 1 && - mbedtls_mpi_cmp_mpi(P, N) == -1) { - /* - * Have found a nontrivial divisor P of N. - * Set Q := N / P. - */ - - MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(Q, NULL, N, P)); - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &K)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, N)); - } - - /* - * If we get here, then either we prematurely aborted the loop because - * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must - * be 1 if D,E,N were consistent. - * Check if that's the case and abort if not, to avoid very long, - * yet eventually failing, computations if N,D,E were not sane. - */ - if (mbedtls_mpi_cmp_int(&K, 1) != 0) { - break; - } - } - - ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - -cleanup: - - mbedtls_mpi_free(&K); - mbedtls_mpi_free(&T); - return ret; -} - -/* - * Given P, Q and the public exponent E, deduce D. - * This is essentially a modular inversion. - */ -int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P, - mbedtls_mpi const *Q, - mbedtls_mpi const *E, - mbedtls_mpi *D) -{ - int ret = 0; - mbedtls_mpi K, L; - - if (D == NULL) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (mbedtls_mpi_cmp_int(P, 1) <= 0 || - mbedtls_mpi_cmp_int(Q, 1) <= 0 || - mbedtls_mpi_cmp_int(E, 0) == 0) { - return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - } - - if (mbedtls_mpi_get_bit(E, 0) != 1) { - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - } - - mbedtls_mpi_init(&K); - mbedtls_mpi_init(&L); - - /* Temporarily put K := P-1 and L := Q-1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1)); - - /* Temporarily put D := gcd(P-1, Q-1) */ - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(D, &K, &L)); - - /* K := LCM(P-1, Q-1) */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &L)); - MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&K, NULL, &K, D)); - - /* Compute modular inverse of E mod LCM(P-1, Q-1) - * This is FIPS 186-4 §B.3.1 criterion 3(b). - * This will return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if E is not coprime to - * (P-1)(Q-1), also validating FIPS 186-4 §B.3.1 criterion 2(a). */ - MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_even_in_range(D, E, &K)); - -cleanup: - - mbedtls_mpi_free(&K); - mbedtls_mpi_free(&L); - - return ret; -} - -int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, mbedtls_mpi *DP, - mbedtls_mpi *DQ, mbedtls_mpi *QP) -{ - int ret = 0; - mbedtls_mpi K; - mbedtls_mpi_init(&K); - - /* DP = D mod P-1 */ - if (DP != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DP, D, &K)); - } - - /* DQ = D mod Q-1 */ - if (DQ != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DQ, D, &K)); - } - - /* QP = Q^{-1} mod P */ - if (QP != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_odd(QP, Q, P)); - } - -cleanup: - mbedtls_mpi_free(&K); - - return ret; -} - -/* - * Check that core RSA parameters are sane. - */ -int mbedtls_rsa_validate_params(const mbedtls_mpi *N, const mbedtls_mpi *P, - const mbedtls_mpi *Q, const mbedtls_mpi *D, - const mbedtls_mpi *E, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = 0; - mbedtls_mpi K, L; - - mbedtls_mpi_init(&K); - mbedtls_mpi_init(&L); - - /* - * Step 1: If PRNG provided, check that P and Q are prime - */ - -#if defined(MBEDTLS_GENPRIME) - /* - * When generating keys, the strongest security we support aims for an error - * rate of at most 2^-100 and we are aiming for the same certainty here as - * well. - */ - if (f_rng != NULL && P != NULL && - (ret = mbedtls_mpi_is_prime_ext(P, 50, f_rng, p_rng)) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - if (f_rng != NULL && Q != NULL && - (ret = mbedtls_mpi_is_prime_ext(Q, 50, f_rng, p_rng)) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } -#else - ((void) f_rng); - ((void) p_rng); -#endif /* MBEDTLS_GENPRIME */ - - /* - * Step 2: Check that 1 < N = P * Q - */ - - if (P != NULL && Q != NULL && N != NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, P, Q)); - if (mbedtls_mpi_cmp_int(N, 1) <= 0 || - mbedtls_mpi_cmp_mpi(&K, N) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* - * Step 3: Check and 1 < D, E < N if present. - */ - - if (N != NULL && D != NULL && E != NULL) { - if (mbedtls_mpi_cmp_int(D, 1) <= 0 || - mbedtls_mpi_cmp_int(E, 1) <= 0 || - mbedtls_mpi_cmp_mpi(D, N) >= 0 || - mbedtls_mpi_cmp_mpi(E, N) >= 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* - * Step 4: Check that D, E are inverse modulo P-1 and Q-1 - */ - - if (P != NULL && Q != NULL && D != NULL && E != NULL) { - if (mbedtls_mpi_cmp_int(P, 1) <= 0 || - mbedtls_mpi_cmp_int(Q, 1) <= 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - /* Compute DE-1 mod P-1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L)); - if (mbedtls_mpi_cmp_int(&K, 0) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - - /* Compute DE-1 mod Q-1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L)); - if (mbedtls_mpi_cmp_int(&K, 0) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - -cleanup: - - mbedtls_mpi_free(&K); - mbedtls_mpi_free(&L); - - /* Wrap MPI error codes by RSA check failure error code */ - if (ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) { - ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - return ret; -} - -/* - * Check that RSA CRT parameters are in accordance with core parameters. - */ -int mbedtls_rsa_validate_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *DP, - const mbedtls_mpi *DQ, const mbedtls_mpi *QP) -{ - int ret = 0; - - mbedtls_mpi K, L; - mbedtls_mpi_init(&K); - mbedtls_mpi_init(&L); - - /* Check that DP - D == 0 mod P - 1 */ - if (DP != NULL) { - if (P == NULL) { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DP, D)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K)); - - if (mbedtls_mpi_cmp_int(&L, 0) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* Check that DQ - D == 0 mod Q - 1 */ - if (DQ != NULL) { - if (Q == NULL) { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DQ, D)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K)); - - if (mbedtls_mpi_cmp_int(&L, 0) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - - /* Check that QP * Q - 1 == 0 mod P */ - if (QP != NULL) { - if (P == NULL || Q == NULL) { - ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - goto cleanup; - } - - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, QP, Q)); - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, P)); - if (mbedtls_mpi_cmp_int(&K, 0) != 0) { - ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - goto cleanup; - } - } - -cleanup: - - /* Wrap MPI error codes by RSA check failure error code */ - if (ret != 0 && - ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED && - ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA) { - ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; - } - - mbedtls_mpi_free(&K); - mbedtls_mpi_free(&L); - - return ret; -} - -#endif /* MBEDTLS_RSA_C */ diff --git a/vendor/mbedtls/library/rsa_alt_helpers.h b/vendor/mbedtls/library/rsa_alt_helpers.h deleted file mode 100644 index 8ff74a02b..000000000 --- a/vendor/mbedtls/library/rsa_alt_helpers.h +++ /dev/null @@ -1,209 +0,0 @@ -/** - * \file rsa_alt_helpers.h - * - * \brief Context-independent RSA helper functions - * - * This module declares some RSA-related helper functions useful when - * implementing the RSA interface. These functions are provided in a separate - * compilation unit in order to make it easy for designers of alternative RSA - * implementations to use them in their own code, as it is conceived that the - * functionality they provide will be necessary for most complete - * implementations. - * - * End-users of Mbed TLS who are not providing their own alternative RSA - * implementations should not use these functions directly, and should instead - * use only the functions declared in rsa.h. - * - * The interface provided by this module will be maintained through LTS (Long - * Term Support) branches of Mbed TLS, but may otherwise be subject to change, - * and must be considered an internal interface of the library. - * - * There are two classes of helper functions: - * - * (1) Parameter-generating helpers. These are: - * - mbedtls_rsa_deduce_primes - * - mbedtls_rsa_deduce_private_exponent - * - mbedtls_rsa_deduce_crt - * Each of these functions takes a set of core RSA parameters and - * generates some other, or CRT related parameters. - * - * (2) Parameter-checking helpers. These are: - * - mbedtls_rsa_validate_params - * - mbedtls_rsa_validate_crt - * They take a set of core or CRT related RSA parameters and check their - * validity. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_RSA_ALT_HELPERS_H -#define MBEDTLS_RSA_ALT_HELPERS_H - -#include "mbedtls/build_info.h" - -#include "mbedtls/bignum.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * \brief Compute RSA prime moduli P, Q from public modulus N=PQ - * and a pair of private and public key. - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param N RSA modulus N = PQ, with P, Q to be found - * \param E RSA public exponent - * \param D RSA private exponent - * \param P Pointer to MPI holding first prime factor of N on success - * \param Q Pointer to MPI holding second prime factor of N on success - * - * \return - * - 0 if successful. In this case, P and Q constitute a - * factorization of N. - * - A non-zero error code otherwise. - * - * \note It is neither checked that P, Q are prime nor that - * D, E are modular inverses wrt. P-1 and Q-1. For that, - * use the helper function \c mbedtls_rsa_validate_params. - * - */ -int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N, mbedtls_mpi const *E, - mbedtls_mpi const *D, - mbedtls_mpi *P, mbedtls_mpi *Q); - -/** - * \brief Compute RSA private exponent from - * prime moduli and public key. - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param P First prime factor of RSA modulus - * \param Q Second prime factor of RSA modulus - * \param E RSA public exponent - * \param D Pointer to MPI holding the private exponent on success, - * i.e. the modular inverse of E modulo LCM(P-1,Q-1). - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. - * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if E is not coprime to P-1 - * and Q-1, that is, if GCD( E, (P-1)*(Q-1) ) != 1. - * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if inputs are otherwise - * invalid. - * - * \note This function does not check whether P and Q are primes. - * - */ -int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P, - mbedtls_mpi const *Q, - mbedtls_mpi const *E, - mbedtls_mpi *D); - - -/** - * \brief Generate RSA-CRT parameters - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param P First prime factor of N - * \param Q Second prime factor of N - * \param D RSA private exponent - * \param DP Output variable for D modulo P-1 - * \param DQ Output variable for D modulo Q-1 - * \param QP Output variable for the modular inverse of Q modulo P. - * - * \return 0 on success, non-zero error code otherwise. - * - * \note This function does not check whether P, Q are - * prime and whether D is a valid private exponent. - * - */ -int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, mbedtls_mpi *DP, - mbedtls_mpi *DQ, mbedtls_mpi *QP); - - -/** - * \brief Check validity of core RSA parameters - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param N RSA modulus N = PQ - * \param P First prime factor of N - * \param Q Second prime factor of N - * \param D RSA private exponent - * \param E RSA public exponent - * \param f_rng PRNG to be used for primality check, or NULL - * \param p_rng PRNG context for f_rng, or NULL - * - * \return - * - 0 if the following conditions are satisfied - * if all relevant parameters are provided: - * - P prime if f_rng != NULL (%) - * - Q prime if f_rng != NULL (%) - * - 1 < N = P * Q - * - 1 < D, E < N - * - D and E are modular inverses modulo P-1 and Q-1 - * (%) This is only done if MBEDTLS_GENPRIME is defined. - * - A non-zero error code otherwise. - * - * \note The function can be used with a restricted set of arguments - * to perform specific checks only. E.g., calling it with - * (-,P,-,-,-) and a PRNG amounts to a primality check for P. - */ -int mbedtls_rsa_validate_params(const mbedtls_mpi *N, const mbedtls_mpi *P, - const mbedtls_mpi *Q, const mbedtls_mpi *D, - const mbedtls_mpi *E, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); - -/** - * \brief Check validity of RSA CRT parameters - * - * \note This is a 'static' helper function not operating on - * an RSA context. Alternative implementations need not - * overwrite it. - * - * \param P First prime factor of RSA modulus - * \param Q Second prime factor of RSA modulus - * \param D RSA private exponent - * \param DP MPI to check for D modulo P-1 - * \param DQ MPI to check for D modulo P-1 - * \param QP MPI to check for the modular inverse of Q modulo P. - * - * \return - * - 0 if the following conditions are satisfied: - * - D = DP mod P-1 if P, D, DP != NULL - * - Q = DQ mod P-1 if P, D, DQ != NULL - * - QP = Q^-1 mod P if P, Q, QP != NULL - * - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed, - * potentially including \c MBEDTLS_ERR_MPI_XXX if some - * MPI calculations failed. - * - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient - * data was provided to check DP, DQ or QP. - * - * \note The function can be used with a restricted set of arguments - * to perform specific checks only. E.g., calling it with the - * parameters (P, -, D, DP, -, -) will check DP = D mod P-1. - */ -int mbedtls_rsa_validate_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q, - const mbedtls_mpi *D, const mbedtls_mpi *DP, - const mbedtls_mpi *DQ, const mbedtls_mpi *QP); - -#ifdef __cplusplus -} -#endif - -#endif /* rsa_alt_helpers.h */ diff --git a/vendor/mbedtls/library/rsa_internal.h b/vendor/mbedtls/library/rsa_internal.h deleted file mode 100644 index f79c3b712..000000000 --- a/vendor/mbedtls/library/rsa_internal.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * \file rsa_internal.h - * - * \brief Internal-only RSA public-key cryptosystem API. - * - * This file declares RSA-related functions that are to be used - * only from within the Mbed TLS library itself. - * - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_RSA_INTERNAL_H -#define MBEDTLS_RSA_INTERNAL_H - -#include "mbedtls/rsa.h" -#include "mbedtls/asn1.h" - -/** - * \brief Parse a PKCS#1 (ASN.1) encoded private RSA key. - * - * \param rsa The RSA context where parsed data will be stored. - * \param key The buffer that contains the key. - * \param keylen The length of the key buffer in bytes. - * - * \return 0 on success. - * \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors. - * \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while - * parsing data. - * \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the - * provided key fail. - */ -int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen); - -/** - * \brief Parse a PKCS#1 (ASN.1) encoded public RSA key. - * - * \param rsa The RSA context where parsed data will be stored. - * \param key The buffer that contains the key. - * \param keylen The length of the key buffer in bytes. - * - * \return 0 on success. - * \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors. - * \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while - * parsing data. - * \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the - * provided key fail. - */ -int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen); - -/** - * \brief Write a PKCS#1 (ASN.1) encoded private RSA key. - * - * \param rsa The RSA context which contains the data to be written. - * \param start Beginning of the buffer that will be filled with the - * private key. - * \param p End of the buffer that will be filled with the private key. - * On successful return, the referenced pointer will be - * updated in order to point to the beginning of written data. - * - * \return On success, the number of bytes written to the output buffer - * (i.e. a value > 0). - * \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not - * contain a valid key pair. - * \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the - * output buffer. - * - * \note The output buffer is filled backward, i.e. starting from its - * end and moving toward its start. - */ -int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start, - unsigned char **p); - -/** - * \brief Parse a PKCS#1 (ASN.1) encoded public RSA key. - * - * \param rsa The RSA context which contains the data to be written. - * \param start Beginning of the buffer that will be filled with the - * private key. - * \param p End of the buffer that will be filled with the private key. - * On successful return, the referenced pointer will be - * updated in order to point to the beginning of written data. - * - * \return On success, the number of bytes written to the output buffer - * (i.e. a value > 0). - * \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not - * contain a valid public key. - * \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the - * output buffer. - * - * \note The output buffer is filled backward, i.e. starting from its - * end and moving toward its start. - */ -int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start, - unsigned char **p); - -#if defined(MBEDTLS_PKCS1_V21) -/** - * \brief This function is analogue to \c mbedtls_rsa_rsassa_pss_sign(). - * The only difference between them is that this function is more flexible - * on the parameters of \p ctx that are set with \c mbedtls_rsa_set_padding(). - * - * \note Compared to its counterpart, this function: - * - does not check the padding setting of \p ctx. - * - allows the hash_id of \p ctx to be MBEDTLS_MD_NONE, - * in which case it uses \p md_alg as the hash_id. - * - * \note Refer to \c mbedtls_rsa_rsassa_pss_sign() for a description - * of the functioning and parameters of this function. - */ -int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig); -#endif /* MBEDTLS_PKCS1_V21 */ - -#endif /* rsa_internal.h */ diff --git a/vendor/mbedtls/library/sha1.c b/vendor/mbedtls/library/sha1.c deleted file mode 100644 index dfbe481f3..000000000 --- a/vendor/mbedtls/library/sha1.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#include "common.h" - -#if defined(MBEDTLS_SHA1_C) - -#include "mbedtls/sha1.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#include "mbedtls/platform.h" - -#if !defined(MBEDTLS_SHA1_ALT) - -void mbedtls_sha1_init(mbedtls_sha1_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_sha1_context)); -} - -void mbedtls_sha1_free(mbedtls_sha1_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha1_context)); -} - -void mbedtls_sha1_clone(mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src) -{ - *dst = *src; -} - -/* - * SHA-1 context setup - */ -int mbedtls_sha1_starts(mbedtls_sha1_context *ctx) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - - return 0; -} - -#if !defined(MBEDTLS_SHA1_PROCESS_ALT) -int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, - const unsigned char data[64]) -{ - struct { - uint32_t temp, W[16], A, B, C, D, E; - } local; - - local.W[0] = MBEDTLS_GET_UINT32_BE(data, 0); - local.W[1] = MBEDTLS_GET_UINT32_BE(data, 4); - local.W[2] = MBEDTLS_GET_UINT32_BE(data, 8); - local.W[3] = MBEDTLS_GET_UINT32_BE(data, 12); - local.W[4] = MBEDTLS_GET_UINT32_BE(data, 16); - local.W[5] = MBEDTLS_GET_UINT32_BE(data, 20); - local.W[6] = MBEDTLS_GET_UINT32_BE(data, 24); - local.W[7] = MBEDTLS_GET_UINT32_BE(data, 28); - local.W[8] = MBEDTLS_GET_UINT32_BE(data, 32); - local.W[9] = MBEDTLS_GET_UINT32_BE(data, 36); - local.W[10] = MBEDTLS_GET_UINT32_BE(data, 40); - local.W[11] = MBEDTLS_GET_UINT32_BE(data, 44); - local.W[12] = MBEDTLS_GET_UINT32_BE(data, 48); - local.W[13] = MBEDTLS_GET_UINT32_BE(data, 52); - local.W[14] = MBEDTLS_GET_UINT32_BE(data, 56); - local.W[15] = MBEDTLS_GET_UINT32_BE(data, 60); - -#define S(x, n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - -#define R(t) \ - ( \ - local.temp = local.W[((t) - 3) & 0x0F] ^ \ - local.W[((t) - 8) & 0x0F] ^ \ - local.W[((t) - 14) & 0x0F] ^ \ - local.W[(t) & 0x0F], \ - (local.W[(t) & 0x0F] = S(local.temp, 1)) \ - ) - -#define P(a, b, c, d, e, x) \ - do \ - { \ - (e) += S((a), 5) + F((b), (c), (d)) + K + (x); \ - (b) = S((b), 30); \ - } while (0) - - local.A = ctx->state[0]; - local.B = ctx->state[1]; - local.C = ctx->state[2]; - local.D = ctx->state[3]; - local.E = ctx->state[4]; - -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define K 0x5A827999 - - P(local.A, local.B, local.C, local.D, local.E, local.W[0]); - P(local.E, local.A, local.B, local.C, local.D, local.W[1]); - P(local.D, local.E, local.A, local.B, local.C, local.W[2]); - P(local.C, local.D, local.E, local.A, local.B, local.W[3]); - P(local.B, local.C, local.D, local.E, local.A, local.W[4]); - P(local.A, local.B, local.C, local.D, local.E, local.W[5]); - P(local.E, local.A, local.B, local.C, local.D, local.W[6]); - P(local.D, local.E, local.A, local.B, local.C, local.W[7]); - P(local.C, local.D, local.E, local.A, local.B, local.W[8]); - P(local.B, local.C, local.D, local.E, local.A, local.W[9]); - P(local.A, local.B, local.C, local.D, local.E, local.W[10]); - P(local.E, local.A, local.B, local.C, local.D, local.W[11]); - P(local.D, local.E, local.A, local.B, local.C, local.W[12]); - P(local.C, local.D, local.E, local.A, local.B, local.W[13]); - P(local.B, local.C, local.D, local.E, local.A, local.W[14]); - P(local.A, local.B, local.C, local.D, local.E, local.W[15]); - P(local.E, local.A, local.B, local.C, local.D, R(16)); - P(local.D, local.E, local.A, local.B, local.C, R(17)); - P(local.C, local.D, local.E, local.A, local.B, R(18)); - P(local.B, local.C, local.D, local.E, local.A, R(19)); - -#undef K -#undef F - -#define F(x, y, z) ((x) ^ (y) ^ (z)) -#define K 0x6ED9EBA1 - - P(local.A, local.B, local.C, local.D, local.E, R(20)); - P(local.E, local.A, local.B, local.C, local.D, R(21)); - P(local.D, local.E, local.A, local.B, local.C, R(22)); - P(local.C, local.D, local.E, local.A, local.B, R(23)); - P(local.B, local.C, local.D, local.E, local.A, R(24)); - P(local.A, local.B, local.C, local.D, local.E, R(25)); - P(local.E, local.A, local.B, local.C, local.D, R(26)); - P(local.D, local.E, local.A, local.B, local.C, R(27)); - P(local.C, local.D, local.E, local.A, local.B, R(28)); - P(local.B, local.C, local.D, local.E, local.A, R(29)); - P(local.A, local.B, local.C, local.D, local.E, R(30)); - P(local.E, local.A, local.B, local.C, local.D, R(31)); - P(local.D, local.E, local.A, local.B, local.C, R(32)); - P(local.C, local.D, local.E, local.A, local.B, R(33)); - P(local.B, local.C, local.D, local.E, local.A, R(34)); - P(local.A, local.B, local.C, local.D, local.E, R(35)); - P(local.E, local.A, local.B, local.C, local.D, R(36)); - P(local.D, local.E, local.A, local.B, local.C, R(37)); - P(local.C, local.D, local.E, local.A, local.B, R(38)); - P(local.B, local.C, local.D, local.E, local.A, R(39)); - -#undef K -#undef F - -#define F(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define K 0x8F1BBCDC - - P(local.A, local.B, local.C, local.D, local.E, R(40)); - P(local.E, local.A, local.B, local.C, local.D, R(41)); - P(local.D, local.E, local.A, local.B, local.C, R(42)); - P(local.C, local.D, local.E, local.A, local.B, R(43)); - P(local.B, local.C, local.D, local.E, local.A, R(44)); - P(local.A, local.B, local.C, local.D, local.E, R(45)); - P(local.E, local.A, local.B, local.C, local.D, R(46)); - P(local.D, local.E, local.A, local.B, local.C, R(47)); - P(local.C, local.D, local.E, local.A, local.B, R(48)); - P(local.B, local.C, local.D, local.E, local.A, R(49)); - P(local.A, local.B, local.C, local.D, local.E, R(50)); - P(local.E, local.A, local.B, local.C, local.D, R(51)); - P(local.D, local.E, local.A, local.B, local.C, R(52)); - P(local.C, local.D, local.E, local.A, local.B, R(53)); - P(local.B, local.C, local.D, local.E, local.A, R(54)); - P(local.A, local.B, local.C, local.D, local.E, R(55)); - P(local.E, local.A, local.B, local.C, local.D, R(56)); - P(local.D, local.E, local.A, local.B, local.C, R(57)); - P(local.C, local.D, local.E, local.A, local.B, R(58)); - P(local.B, local.C, local.D, local.E, local.A, R(59)); - -#undef K -#undef F - -#define F(x, y, z) ((x) ^ (y) ^ (z)) -#define K 0xCA62C1D6 - - P(local.A, local.B, local.C, local.D, local.E, R(60)); - P(local.E, local.A, local.B, local.C, local.D, R(61)); - P(local.D, local.E, local.A, local.B, local.C, R(62)); - P(local.C, local.D, local.E, local.A, local.B, R(63)); - P(local.B, local.C, local.D, local.E, local.A, R(64)); - P(local.A, local.B, local.C, local.D, local.E, R(65)); - P(local.E, local.A, local.B, local.C, local.D, R(66)); - P(local.D, local.E, local.A, local.B, local.C, R(67)); - P(local.C, local.D, local.E, local.A, local.B, R(68)); - P(local.B, local.C, local.D, local.E, local.A, R(69)); - P(local.A, local.B, local.C, local.D, local.E, R(70)); - P(local.E, local.A, local.B, local.C, local.D, R(71)); - P(local.D, local.E, local.A, local.B, local.C, R(72)); - P(local.C, local.D, local.E, local.A, local.B, R(73)); - P(local.B, local.C, local.D, local.E, local.A, R(74)); - P(local.A, local.B, local.C, local.D, local.E, R(75)); - P(local.E, local.A, local.B, local.C, local.D, R(76)); - P(local.D, local.E, local.A, local.B, local.C, R(77)); - P(local.C, local.D, local.E, local.A, local.B, R(78)); - P(local.B, local.C, local.D, local.E, local.A, R(79)); - -#undef K -#undef F - - ctx->state[0] += local.A; - ctx->state[1] += local.B; - ctx->state[2] += local.C; - ctx->state[3] += local.D; - ctx->state[4] += local.E; - - /* Zeroise buffers and variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize(&local, sizeof(local)); - - return 0; -} - -#endif /* !MBEDTLS_SHA1_PROCESS_ALT */ - -/* - * SHA-1 process buffer - */ -int mbedtls_sha1_update(mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t fill; - uint32_t left; - - if (ilen == 0) { - return 0; - } - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if (ctx->total[0] < (uint32_t) ilen) { - ctx->total[1]++; - } - - if (left && ilen >= fill) { - memcpy((void *) (ctx->buffer + left), input, fill); - - if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0) { - return ret; - } - - input += fill; - ilen -= fill; - left = 0; - } - - while (ilen >= 64) { - if ((ret = mbedtls_internal_sha1_process(ctx, input)) != 0) { - return ret; - } - - input += 64; - ilen -= 64; - } - - if (ilen > 0) { - memcpy((void *) (ctx->buffer + left), input, ilen); - } - - return 0; -} - -/* - * SHA-1 final digest - */ -int mbedtls_sha1_finish(mbedtls_sha1_context *ctx, - unsigned char output[20]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint32_t used; - uint32_t high, low; - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if (used <= 56) { - /* Enough room for padding + length in current block */ - memset(ctx->buffer + used, 0, 56 - used); - } else { - /* We'll need an extra block */ - memset(ctx->buffer + used, 0, 64 - used); - - if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - memset(ctx->buffer, 0, 56); - } - - /* - * Add message length - */ - high = (ctx->total[0] >> 29) - | (ctx->total[1] << 3); - low = (ctx->total[0] << 3); - - MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56); - MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60); - - if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - /* - * Output final state - */ - MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0); - MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4); - MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8); - MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12); - MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16); - - ret = 0; - -exit: - mbedtls_sha1_free(ctx); - return ret; -} - -#endif /* !MBEDTLS_SHA1_ALT */ - -/* - * output = SHA-1( input buffer ) - */ -int mbedtls_sha1(const unsigned char *input, - size_t ilen, - unsigned char output[20]) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_sha1_context ctx; - - mbedtls_sha1_init(&ctx); - - if ((ret = mbedtls_sha1_starts(&ctx)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha1_update(&ctx, input, ilen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha1_finish(&ctx, output)) != 0) { - goto exit; - } - -exit: - mbedtls_sha1_free(&ctx); - return ret; -} - -#if defined(MBEDTLS_SELF_TEST) -/* - * FIPS-180-1 test vectors - */ -static const unsigned char sha1_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const size_t sha1_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha1_test_sum[3][20] = -{ - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, - { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, - 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } -}; - -/* - * Checkup routine - */ -int mbedtls_sha1_self_test(int verbose) -{ - int i, j, buflen, ret = 0; - unsigned char buf[1024]; - unsigned char sha1sum[20]; - mbedtls_sha1_context ctx; - - mbedtls_sha1_init(&ctx); - - /* - * SHA-1 - */ - for (i = 0; i < 3; i++) { - if (verbose != 0) { - mbedtls_printf(" SHA-1 test #%d: ", i + 1); - } - - if ((ret = mbedtls_sha1_starts(&ctx)) != 0) { - goto fail; - } - - if (i == 2) { - memset(buf, 'a', buflen = 1000); - - for (j = 0; j < 1000; j++) { - ret = mbedtls_sha1_update(&ctx, buf, buflen); - if (ret != 0) { - goto fail; - } - } - } else { - ret = mbedtls_sha1_update(&ctx, sha1_test_buf[i], - sha1_test_buflen[i]); - if (ret != 0) { - goto fail; - } - } - - if ((ret = mbedtls_sha1_finish(&ctx, sha1sum)) != 0) { - goto fail; - } - - if (memcmp(sha1sum, sha1_test_sum[i], 20) != 0) { - ret = 1; - goto fail; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - goto exit; - -fail: - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - -exit: - mbedtls_sha1_free(&ctx); - - return ret; -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA1_C */ diff --git a/vendor/mbedtls/library/sha256.c b/vendor/mbedtls/library/sha256.c deleted file mode 100644 index 4f1ac3e0f..000000000 --- a/vendor/mbedtls/library/sha256.c +++ /dev/null @@ -1,983 +0,0 @@ -/* - * FIPS-180-2 compliant SHA-256 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The SHA-256 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */ -#if !defined(_GNU_SOURCE) -#define _GNU_SOURCE -#endif - -#if defined(__clang__) && (__clang_major__ >= 4) - -/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if, - * but that is defined by build_info.h, and we need this block to happen first. */ -#if defined(__ARM_ARCH) && (__ARM_ARCH_PROFILE == 'A') -#if __ARM_ARCH >= 8 -#define MBEDTLS_SHA256_ARCH_IS_ARMV8_A -#endif -#endif - -#if defined(MBEDTLS_SHA256_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO) -/* - * The intrinsic declaration are guarded by predefined ACLE macros in clang: - * these are normally only enabled by the -march option on the command line. - * By defining the macros ourselves we gain access to those declarations without - * requiring -march on the command line. - * - * `arm_neon.h` is included by common.h, so we put these defines - * at the top of this file, before any includes but after the intrinsic - * declaration. This is necessary with - * Clang <=15.x. With Clang 16.0 and above, these macro definitions are - * no longer required, but they're harmless. See - * https://reviews.llvm.org/D131064 - */ -#define __ARM_FEATURE_CRYPTO 1 -/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions - * - * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it - * for older compilers. - */ -#define __ARM_FEATURE_SHA2 1 -#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG -#endif - -#endif /* defined(__clang__) && (__clang_major__ >= 4) */ - -#include "common.h" - -#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C) - -#include "mbedtls/sha256.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_ARCH_IS_ARMV8_A) - -# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \ - defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) -# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS) -# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) -# warning "Target does not support NEON instructions" -# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT -# else -# error "Target does not support NEON instructions" -# endif -# endif -# endif - -# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \ - defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) -/* *INDENT-OFF* */ - -# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG) -# if defined(__ARMCOMPILER_VERSION) -# if __ARMCOMPILER_VERSION <= 6090000 -# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*" -# endif -# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function) -# define MBEDTLS_POP_TARGET_PRAGMA -# elif defined(__clang__) -# if __clang_major__ < 4 -# error "A more recent Clang is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*" -# endif -# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function) -# define MBEDTLS_POP_TARGET_PRAGMA -# elif defined(__GNUC__) - /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some - * intrinsics are missing. Missing intrinsics could be worked around. - */ -# if __GNUC__ < 6 -# error "A more recent GCC is required for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*" -# else -# pragma GCC push_options -# pragma GCC target ("arch=armv8-a+crypto") -# define MBEDTLS_POP_TARGET_PRAGMA -# endif -# else -# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*" -# endif -# endif -/* *INDENT-ON* */ - -# endif -# if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) -# if defined(__unix__) -# if defined(__linux__) -/* Our preferred method of detection is getauxval() */ -# include -/* These are not always defined via sys/auxv.h */ -# if !defined(HWCAP_SHA2) -# define HWCAP_SHA2 (1 << 6) -# endif -# if !defined(HWCAP2_SHA2) -# define HWCAP2_SHA2 (1 << 3) -# endif -# endif -/* Use SIGILL on Unix, and fall back to it on Linux */ -# include -# endif -# endif -#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) -# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY -# undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT -#endif - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) -/* - * Capability detection code comes early, so we can disable - * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT if no detection mechanism found - */ -#if defined(MBEDTLS_ARCH_IS_ARM64) && defined(HWCAP_SHA2) -static int mbedtls_a64_crypto_sha256_determine_support(void) -{ - return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0; -} -#elif defined(MBEDTLS_ARCH_IS_ARM32) && defined(HWCAP2_SHA2) -static int mbedtls_a64_crypto_sha256_determine_support(void) -{ - return (getauxval(AT_HWCAP2) & HWCAP2_SHA2) ? 1 : 0; -} -#elif defined(__APPLE__) -static int mbedtls_a64_crypto_sha256_determine_support(void) -{ - return 1; -} -#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include - -static int mbedtls_a64_crypto_sha256_determine_support(void) -{ - return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? - 1 : 0; -} -#elif defined(__unix__) && defined(SIG_SETMASK) -/* Detection with SIGILL, setjmp() and longjmp() */ -#include -#include - -static jmp_buf return_from_sigill; - -/* - * Armv8-A SHA256 support detection via SIGILL - */ -static void sigill_handler(int signal) -{ - (void) signal; - longjmp(return_from_sigill, 1); -} - -static int mbedtls_a64_crypto_sha256_determine_support(void) -{ - struct sigaction old_action, new_action; - - sigset_t old_mask; - if (sigprocmask(0, NULL, &old_mask)) { - return 0; - } - - sigemptyset(&new_action.sa_mask); - new_action.sa_flags = 0; - new_action.sa_handler = sigill_handler; - - sigaction(SIGILL, &new_action, &old_action); - - static int ret = 0; - - if (setjmp(return_from_sigill) == 0) { /* First return only */ - /* If this traps, we will return a second time from setjmp() with 1 */ -#if defined(MBEDTLS_ARCH_IS_ARM64) - asm volatile ("sha256h q0, q0, v0.4s" : : : "v0"); -#else - asm volatile ("sha256h.32 q0, q0, q0" : : : "q0"); -#endif - ret = 1; - } - - sigaction(SIGILL, &old_action, NULL); - sigprocmask(SIG_SETMASK, &old_mask, NULL); - - return ret; -} -#else -#warning "No mechanism to detect ARMV8_CRYPTO found, using C code only" -#undef MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT -#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */ - -#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */ - -#if !defined(MBEDTLS_SHA256_ALT) - -#define SHA256_BLOCK_SIZE 64 - -void mbedtls_sha256_init(mbedtls_sha256_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_sha256_context)); -} - -void mbedtls_sha256_free(mbedtls_sha256_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context)); -} - -void mbedtls_sha256_clone(mbedtls_sha256_context *dst, - const mbedtls_sha256_context *src) -{ - *dst = *src; -} - -/* - * SHA-256 context setup - */ -int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224) -{ -#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C) - if (is224 != 0 && is224 != 1) { - return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; - } -#elif defined(MBEDTLS_SHA256_C) - if (is224 != 0) { - return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; - } -#else /* defined MBEDTLS_SHA224_C only */ - if (is224 == 0) { - return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; - } -#endif - - ctx->total[0] = 0; - ctx->total[1] = 0; - - if (is224 == 0) { -#if defined(MBEDTLS_SHA256_C) - ctx->state[0] = 0x6A09E667; - ctx->state[1] = 0xBB67AE85; - ctx->state[2] = 0x3C6EF372; - ctx->state[3] = 0xA54FF53A; - ctx->state[4] = 0x510E527F; - ctx->state[5] = 0x9B05688C; - ctx->state[6] = 0x1F83D9AB; - ctx->state[7] = 0x5BE0CD19; -#endif - } else { -#if defined(MBEDTLS_SHA224_C) - ctx->state[0] = 0xC1059ED8; - ctx->state[1] = 0x367CD507; - ctx->state[2] = 0x3070DD17; - ctx->state[3] = 0xF70E5939; - ctx->state[4] = 0xFFC00B31; - ctx->state[5] = 0x68581511; - ctx->state[6] = 0x64F98FA7; - ctx->state[7] = 0xBEFA4FA4; -#endif - } - -#if defined(MBEDTLS_SHA224_C) - ctx->is224 = is224; -#endif - - return 0; -} - -#if !defined(MBEDTLS_SHA256_PROCESS_ALT) -static const uint32_t K[] = -{ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, -}; - -#endif - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \ - defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) -# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many -# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process -#endif - -static size_t mbedtls_internal_sha256_process_many_a64_crypto( - mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len) -{ - uint32x4_t abcd = vld1q_u32(&ctx->state[0]); - uint32x4_t efgh = vld1q_u32(&ctx->state[4]); - - size_t processed = 0; - - for (; - len >= SHA256_BLOCK_SIZE; - processed += SHA256_BLOCK_SIZE, - msg += SHA256_BLOCK_SIZE, - len -= SHA256_BLOCK_SIZE) { - uint32x4_t tmp, abcd_prev; - - uint32x4_t abcd_orig = abcd; - uint32x4_t efgh_orig = efgh; - - uint32x4_t sched0 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 0)); - uint32x4_t sched1 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 1)); - uint32x4_t sched2 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 2)); - uint32x4_t sched3 = vreinterpretq_u32_u8(vld1q_u8(msg + 16 * 3)); - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */ - /* Untested on BE */ - sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0))); - sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1))); - sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2))); - sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3))); -#endif - - /* Rounds 0 to 3 */ - tmp = vaddq_u32(sched0, vld1q_u32(&K[0])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - - /* Rounds 4 to 7 */ - tmp = vaddq_u32(sched1, vld1q_u32(&K[4])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - - /* Rounds 8 to 11 */ - tmp = vaddq_u32(sched2, vld1q_u32(&K[8])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - - /* Rounds 12 to 15 */ - tmp = vaddq_u32(sched3, vld1q_u32(&K[12])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - - for (int t = 16; t < 64; t += 16) { - /* Rounds t to t + 3 */ - sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3); - tmp = vaddq_u32(sched0, vld1q_u32(&K[t])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - - /* Rounds t + 4 to t + 7 */ - sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0); - tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - - /* Rounds t + 8 to t + 11 */ - sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1); - tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - - /* Rounds t + 12 to t + 15 */ - sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2); - tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12])); - abcd_prev = abcd; - abcd = vsha256hq_u32(abcd_prev, efgh, tmp); - efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); - } - - abcd = vaddq_u32(abcd, abcd_orig); - efgh = vaddq_u32(efgh, efgh_orig); - } - - vst1q_u32(&ctx->state[0], abcd); - vst1q_u32(&ctx->state[4], efgh); - - return processed; -} - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) -/* - * This function is for internal use only if we are building both C and Armv8-A - * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process() - */ -static -#endif -int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx, - const unsigned char data[SHA256_BLOCK_SIZE]) -{ - return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data, - SHA256_BLOCK_SIZE) == - SHA256_BLOCK_SIZE) ? 0 : -1; -} - -#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */ - -#if defined(MBEDTLS_POP_TARGET_PRAGMA) -#if defined(__clang__) -#pragma clang attribute pop -#elif defined(__GNUC__) -#pragma GCC pop_options -#endif -#undef MBEDTLS_POP_TARGET_PRAGMA -#endif - -#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) -#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many -#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process -#endif - - -#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \ - !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) - -#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n)) -#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n)))) - -#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) -#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) - -#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) - -#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) - -#define R(t) \ - ( \ - local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \ - S0(local.W[(t) - 15]) + local.W[(t) - 16] \ - ) - -#define P(a, b, c, d, e, f, g, h, x, K) \ - do \ - { \ - local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \ - local.temp2 = S2(a) + F0((a), (b), (c)); \ - (d) += local.temp1; (h) = local.temp1 + local.temp2; \ - } while (0) - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) -/* - * This function is for internal use only if we are building both C and Armv8 - * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process() - */ -static -#endif -int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx, - const unsigned char data[SHA256_BLOCK_SIZE]) -{ - struct { - uint32_t temp1, temp2, W[64]; - uint32_t A[8]; - } local; - - unsigned int i; - - for (i = 0; i < 8; i++) { - local.A[i] = ctx->state[i]; - } - -#if defined(MBEDTLS_SHA256_SMALLER) - for (i = 0; i < 64; i++) { - if (i < 16) { - local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i); - } else { - R(i); - } - - P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], local.W[i], K[i]); - - local.temp1 = local.A[7]; local.A[7] = local.A[6]; - local.A[6] = local.A[5]; local.A[5] = local.A[4]; - local.A[4] = local.A[3]; local.A[3] = local.A[2]; - local.A[2] = local.A[1]; local.A[1] = local.A[0]; - local.A[0] = local.temp1; - } -#else /* MBEDTLS_SHA256_SMALLER */ - for (i = 0; i < 16; i++) { - local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i); - } - - for (i = 0; i < 16; i += 8) { - P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]); - P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], - local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]); - P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], - local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]); - P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], - local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]); - P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], - local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]); - P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], - local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]); - P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], - local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]); - P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], - local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]); - } - - for (i = 16; i < 64; i += 8) { - P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]); - P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], - local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]); - P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], - local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]); - P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], - local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]); - P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], - local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]); - P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], - local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]); - P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], - local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]); - P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], - local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]); - } -#endif /* MBEDTLS_SHA256_SMALLER */ - - for (i = 0; i < 8; i++) { - ctx->state[i] += local.A[i]; - } - - /* Zeroise buffers and variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize(&local, sizeof(local)); - - return 0; -} - -#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */ - - -#if !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) - -static size_t mbedtls_internal_sha256_process_many_c( - mbedtls_sha256_context *ctx, const uint8_t *data, size_t len) -{ - size_t processed = 0; - - while (len >= SHA256_BLOCK_SIZE) { - if (mbedtls_internal_sha256_process_c(ctx, data) != 0) { - return 0; - } - - data += SHA256_BLOCK_SIZE; - len -= SHA256_BLOCK_SIZE; - - processed += SHA256_BLOCK_SIZE; - } - - return processed; -} - -#endif /* !MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */ - - -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) - -static int mbedtls_a64_crypto_sha256_has_support(void) -{ - static int done = 0; - static int supported = 0; - - if (!done) { - supported = mbedtls_a64_crypto_sha256_determine_support(); - done = 1; - } - - return supported; -} - -static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx, - const uint8_t *msg, size_t len) -{ - if (mbedtls_a64_crypto_sha256_has_support()) { - return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len); - } else { - return mbedtls_internal_sha256_process_many_c(ctx, msg, len); - } -} - -int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, - const unsigned char data[SHA256_BLOCK_SIZE]) -{ - if (mbedtls_a64_crypto_sha256_has_support()) { - return mbedtls_internal_sha256_process_a64_crypto(ctx, data); - } else { - return mbedtls_internal_sha256_process_c(ctx, data); - } -} - -#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */ - - -/* - * SHA-256 process buffer - */ -int mbedtls_sha256_update(mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t fill; - uint32_t left; - - if (ilen == 0) { - return 0; - } - - left = ctx->total[0] & 0x3F; - fill = SHA256_BLOCK_SIZE - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if (ctx->total[0] < (uint32_t) ilen) { - ctx->total[1]++; - } - - if (left && ilen >= fill) { - memcpy((void *) (ctx->buffer + left), input, fill); - - if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) { - return ret; - } - - input += fill; - ilen -= fill; - left = 0; - } - - while (ilen >= SHA256_BLOCK_SIZE) { - size_t processed = - mbedtls_internal_sha256_process_many(ctx, input, ilen); - if (processed < SHA256_BLOCK_SIZE) { - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } - - input += processed; - ilen -= processed; - } - - if (ilen > 0) { - memcpy((void *) (ctx->buffer + left), input, ilen); - } - - return 0; -} - -/* - * SHA-256 final digest - */ -int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint32_t used; - uint32_t high, low; - int truncated = 0; - - /* - * Add padding: 0x80 then 0x00 until 8 bytes remain for the length - */ - used = ctx->total[0] & 0x3F; - - ctx->buffer[used++] = 0x80; - - if (used <= 56) { - /* Enough room for padding + length in current block */ - memset(ctx->buffer + used, 0, 56 - used); - } else { - /* We'll need an extra block */ - memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used); - - if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - memset(ctx->buffer, 0, 56); - } - - /* - * Add message length - */ - high = (ctx->total[0] >> 29) - | (ctx->total[1] << 3); - low = (ctx->total[0] << 3); - - MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56); - MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60); - - if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - /* - * Output final state - */ - MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0); - MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4); - MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8); - MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12); - MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16); - MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20); - MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24); - -#if defined(MBEDTLS_SHA224_C) - truncated = ctx->is224; -#endif - if (!truncated) { - MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28); - } - - ret = 0; - -exit: - mbedtls_sha256_free(ctx); - return ret; -} - -#endif /* !MBEDTLS_SHA256_ALT */ - -/* - * output = SHA-256( input buffer ) - */ -int mbedtls_sha256(const unsigned char *input, - size_t ilen, - unsigned char *output, - int is224) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_sha256_context ctx; - -#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C) - if (is224 != 0 && is224 != 1) { - return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; - } -#elif defined(MBEDTLS_SHA256_C) - if (is224 != 0) { - return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; - } -#else /* defined MBEDTLS_SHA224_C only */ - if (is224 == 0) { - return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; - } -#endif - - mbedtls_sha256_init(&ctx); - - if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) { - goto exit; - } - -exit: - mbedtls_sha256_free(&ctx); - - return ret; -} - -#if defined(MBEDTLS_SELF_TEST) -/* - * FIPS-180-2 test vectors - */ -static const unsigned char sha_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const size_t sha_test_buflen[3] = -{ - 3, 56, 1000 -}; - -typedef const unsigned char (sha_test_sum_t)[32]; - -/* - * SHA-224 test vectors - */ -#if defined(MBEDTLS_SHA224_C) -static sha_test_sum_t sha224_test_sum[] = -{ - { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, - 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, - 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, - 0xE3, 0x6C, 0x9D, 0xA7 }, - { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, - 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, - 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, - 0x52, 0x52, 0x25, 0x25 }, - { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, - 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, - 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, - 0x4E, 0xE7, 0xAD, 0x67 } -}; -#endif - -/* - * SHA-256 test vectors - */ -#if defined(MBEDTLS_SHA256_C) -static sha_test_sum_t sha256_test_sum[] = -{ - { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, - 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, - 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, - 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, - { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, - 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, - 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, - 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, - { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, - 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, - 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, - 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } -}; -#endif - -/* - * Checkup routine - */ -static int mbedtls_sha256_common_self_test(int verbose, int is224) -{ - int i, buflen, ret = 0; - unsigned char *buf; - unsigned char sha256sum[32]; - mbedtls_sha256_context ctx; - -#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C) - sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum; -#elif defined(MBEDTLS_SHA256_C) - sha_test_sum_t *sha_test_sum = sha256_test_sum; -#else - sha_test_sum_t *sha_test_sum = sha224_test_sum; -#endif - - buf = mbedtls_calloc(1024, sizeof(unsigned char)); - if (NULL == buf) { - if (verbose != 0) { - mbedtls_printf("Buffer allocation failed\n"); - } - - return 1; - } - - mbedtls_sha256_init(&ctx); - - for (i = 0; i < 3; i++) { - if (verbose != 0) { - mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1); - } - - if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) { - goto fail; - } - - if (i == 2) { - memset(buf, 'a', buflen = 1000); - - for (int j = 0; j < 1000; j++) { - ret = mbedtls_sha256_update(&ctx, buf, buflen); - if (ret != 0) { - goto fail; - } - } - - } else { - ret = mbedtls_sha256_update(&ctx, sha_test_buf[i], - sha_test_buflen[i]); - if (ret != 0) { - goto fail; - } - } - - if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) { - goto fail; - } - - - if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) { - ret = 1; - goto fail; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - goto exit; - -fail: - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - -exit: - mbedtls_sha256_free(&ctx); - mbedtls_free(buf); - - return ret; -} - -#if defined(MBEDTLS_SHA256_C) -int mbedtls_sha256_self_test(int verbose) -{ - return mbedtls_sha256_common_self_test(verbose, 0); -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA224_C) -int mbedtls_sha224_self_test(int verbose) -{ - return mbedtls_sha256_common_self_test(verbose, 1); -} -#endif /* MBEDTLS_SHA224_C */ - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */ diff --git a/vendor/mbedtls/library/sha3.c b/vendor/mbedtls/library/sha3.c deleted file mode 100644 index 57385595f..000000000 --- a/vendor/mbedtls/library/sha3.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * FIPS-202 compliant SHA3 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The SHA-3 Secure Hash Standard was published by NIST in 2015. - * - * https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_SHA3_C) - -/* - * These macros select manually unrolled implementations of parts of the main permutation function. - * - * Unrolling has a major impact on both performance and code size. gcc performance benefits a lot - * from manually unrolling at higher optimisation levels. - * - * Depending on your size/perf priorities, compiler and target, it may be beneficial to adjust - * these; the defaults here should give sensible trade-offs for gcc and clang on aarch64 and - * x86-64. - */ -#if !defined(MBEDTLS_SHA3_THETA_UNROLL) - #define MBEDTLS_SHA3_THETA_UNROLL 0 //no-check-names -#endif -#if !defined(MBEDTLS_SHA3_CHI_UNROLL) - #if defined(__OPTIMIZE_SIZE__) - #define MBEDTLS_SHA3_CHI_UNROLL 0 //no-check-names - #else - #define MBEDTLS_SHA3_CHI_UNROLL 1 //no-check-names - #endif -#endif -#if !defined(MBEDTLS_SHA3_PI_UNROLL) - #define MBEDTLS_SHA3_PI_UNROLL 1 //no-check-names -#endif -#if !defined(MBEDTLS_SHA3_RHO_UNROLL) - #define MBEDTLS_SHA3_RHO_UNROLL 1 //no-check-names -#endif - -#include "mbedtls/sha3.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) -#include "mbedtls/platform.h" -#endif /* MBEDTLS_SELF_TEST */ - -#define XOR_BYTE 0x6 - -/* Precomputed masks for the iota transform. - * - * Each round uses a 64-bit mask value. In each mask values, only - * bits whose position is of the form 2^k-1 can be set, thus only - * 7 of 64 bits of the mask need to be known for each mask value. - * - * We use a compressed encoding of the mask where bits 63, 31 and 15 - * are moved to bits 4-6. This allows us to make each mask value - * 1 byte rather than 8 bytes, saving 7*24 = 168 bytes of data (with - * perhaps a little variation due to alignment). Decompressing this - * requires a little code, but much less than the savings on the table. - * - * The impact on performance depends on the platform and compiler. - * There's a bit more computation, but less memory bandwidth. A quick - * benchmark on x86_64 shows a 7% speed improvement with GCC and a - * 5% speed penalty with Clang, compared to the naive uint64_t[24] table. - * YMMV. - */ -/* Helper macro to set the values of the higher bits in unused low positions */ -#define H(b63, b31, b15) (b63 << 6 | b31 << 5 | b15 << 4) -static const uint8_t iota_r_packed[24] = { - H(0, 0, 0) | 0x01, H(0, 0, 1) | 0x82, H(1, 0, 1) | 0x8a, H(1, 1, 1) | 0x00, - H(0, 0, 1) | 0x8b, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x09, - H(0, 0, 0) | 0x8a, H(0, 0, 0) | 0x88, H(0, 1, 1) | 0x09, H(0, 1, 0) | 0x0a, - H(0, 1, 1) | 0x8b, H(1, 0, 0) | 0x8b, H(1, 0, 1) | 0x89, H(1, 0, 1) | 0x03, - H(1, 0, 1) | 0x02, H(1, 0, 0) | 0x80, H(0, 0, 1) | 0x0a, H(1, 1, 0) | 0x0a, - H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x80, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x08, -}; -#undef H - -static const uint32_t rho[6] = { - 0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832 -}; - -static const uint32_t pi[6] = { - 0x110b070a, 0x10050312, 0x04181508, 0x0d13170f, 0x0e14020c, 0x01060916 -}; - -#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right -#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \ -} while (0) -#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3))) -#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0) - -/* The permutation function. */ -static void keccak_f1600(mbedtls_sha3_context *ctx) -{ - uint64_t lane[5]; - uint64_t *s = ctx->state; - int i; - - for (int round = 0; round < 24; round++) { - uint64_t t; - - /* Theta */ -#if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names - for (i = 0; i < 5; i++) { - lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]; - } - for (i = 0; i < 5; i++) { - t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63); - s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t; - } -#else - lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20]; - lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21]; - lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22]; - lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23]; - lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24]; - - t = lane[4] ^ ROTR64(lane[1], 63); - s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t; - - t = lane[0] ^ ROTR64(lane[2], 63); - s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t; - - t = lane[1] ^ ROTR64(lane[3], 63); - s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t; - - t = lane[2] ^ ROTR64(lane[4], 63); - s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t; - - t = lane[3] ^ ROTR64(lane[0], 63); - s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t; -#endif - - /* Rho */ - for (i = 1; i < 25; i += 4) { - uint32_t r = rho[(i - 1) >> 2]; -#if MBEDTLS_SHA3_RHO_UNROLL == 0 - for (int j = i; j < i + 4; j++) { - uint8_t r8 = (uint8_t) (r >> 24); - r <<= 8; - s[j] = ROTR64(s[j], r8); - } -#else - s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r)); - s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r)); - s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r)); - s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r)); -#endif - } - - /* Pi */ - t = s[1]; -#if MBEDTLS_SHA3_PI_UNROLL == 0 - for (i = 0; i < 24; i += 4) { - uint32_t p = pi[i >> 2]; - for (unsigned j = 0; j < 4; j++) { - SWAP(s[p & 0xff], t); - p >>= 8; - } - } -#else - uint32_t p = pi[0]; - SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t); - SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t); - p = pi[1]; - SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t); - SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t); - p = pi[2]; - SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t); - SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t); - p = pi[3]; - SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t); - SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t); - p = pi[4]; - SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t); - SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t); - p = pi[5]; - SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t); - SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t); -#endif - - /* Chi */ -#if MBEDTLS_SHA3_CHI_UNROLL == 0 //no-check-names - for (i = 0; i <= 20; i += 5) { - lane[0] = s[i]; lane[1] = s[i + 1]; lane[2] = s[i + 2]; - lane[3] = s[i + 3]; lane[4] = s[i + 4]; - s[i + 0] ^= (~lane[1]) & lane[2]; - s[i + 1] ^= (~lane[2]) & lane[3]; - s[i + 2] ^= (~lane[3]) & lane[4]; - s[i + 3] ^= (~lane[4]) & lane[0]; - s[i + 4] ^= (~lane[0]) & lane[1]; - } -#else - lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4]; - s[0] ^= (~lane[1]) & lane[2]; - s[1] ^= (~lane[2]) & lane[3]; - s[2] ^= (~lane[3]) & lane[4]; - s[3] ^= (~lane[4]) & lane[0]; - s[4] ^= (~lane[0]) & lane[1]; - - lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9]; - s[5] ^= (~lane[1]) & lane[2]; - s[6] ^= (~lane[2]) & lane[3]; - s[7] ^= (~lane[3]) & lane[4]; - s[8] ^= (~lane[4]) & lane[0]; - s[9] ^= (~lane[0]) & lane[1]; - - lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14]; - s[10] ^= (~lane[1]) & lane[2]; - s[11] ^= (~lane[2]) & lane[3]; - s[12] ^= (~lane[3]) & lane[4]; - s[13] ^= (~lane[4]) & lane[0]; - s[14] ^= (~lane[0]) & lane[1]; - - lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19]; - s[15] ^= (~lane[1]) & lane[2]; - s[16] ^= (~lane[2]) & lane[3]; - s[17] ^= (~lane[3]) & lane[4]; - s[18] ^= (~lane[4]) & lane[0]; - s[19] ^= (~lane[0]) & lane[1]; - - lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24]; - s[20] ^= (~lane[1]) & lane[2]; - s[21] ^= (~lane[2]) & lane[3]; - s[22] ^= (~lane[3]) & lane[4]; - s[23] ^= (~lane[4]) & lane[0]; - s[24] ^= (~lane[0]) & lane[1]; -#endif - - /* Iota */ - /* Decompress the round masks (see definition of rc) */ - s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 | - (iota_r_packed[round] & 0x20ull) << 26 | - (iota_r_packed[round] & 0x10ull) << 11 | - (iota_r_packed[round] & 0x8f)); - } -} - -void mbedtls_sha3_init(mbedtls_sha3_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_sha3_context)); -} - -void mbedtls_sha3_free(mbedtls_sha3_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context)); -} - -void mbedtls_sha3_clone(mbedtls_sha3_context *dst, - const mbedtls_sha3_context *src) -{ - *dst = *src; -} - -/* - * SHA-3 context setup - */ -int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id) -{ - switch (id) { - case MBEDTLS_SHA3_224: - ctx->olen = 224 / 8; - ctx->max_block_size = 1152 / 8; - break; - case MBEDTLS_SHA3_256: - ctx->olen = 256 / 8; - ctx->max_block_size = 1088 / 8; - break; - case MBEDTLS_SHA3_384: - ctx->olen = 384 / 8; - ctx->max_block_size = 832 / 8; - break; - case MBEDTLS_SHA3_512: - ctx->olen = 512 / 8; - ctx->max_block_size = 576 / 8; - break; - default: - return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA; - } - - memset(ctx->state, 0, sizeof(ctx->state)); - ctx->index = 0; - - return 0; -} - -/* - * SHA-3 process buffer - */ -int mbedtls_sha3_update(mbedtls_sha3_context *ctx, - const uint8_t *input, - size_t ilen) -{ - if (ilen >= 8) { - // 8-byte align index - int align_bytes = 8 - (ctx->index % 8); - if (align_bytes) { - for (; align_bytes > 0; align_bytes--) { - ABSORB(ctx, ctx->index, *input++); - ilen--; - ctx->index++; - } - if ((ctx->index = ctx->index % ctx->max_block_size) == 0) { - keccak_f1600(ctx); - } - } - - // process input in 8-byte chunks - while (ilen >= 8) { - ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0)); - input += 8; - ilen -= 8; - if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) { - keccak_f1600(ctx); - } - } - } - - // handle remaining bytes - while (ilen-- > 0) { - ABSORB(ctx, ctx->index, *input++); - if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) { - keccak_f1600(ctx); - } - } - - return 0; -} - -int mbedtls_sha3_finish(mbedtls_sha3_context *ctx, - uint8_t *output, size_t olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Catch SHA-3 families, with fixed output length */ - if (ctx->olen > 0) { - if (ctx->olen > olen) { - ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA; - goto exit; - } - olen = ctx->olen; - } - - ABSORB(ctx, ctx->index, XOR_BYTE); - ABSORB(ctx, ctx->max_block_size - 1, 0x80); - keccak_f1600(ctx); - ctx->index = 0; - - while (olen-- > 0) { - *output++ = SQUEEZE(ctx, ctx->index); - - if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) { - keccak_f1600(ctx); - } - } - - ret = 0; - -exit: - mbedtls_sha3_free(ctx); - return ret; -} - -/* - * output = SHA-3( input buffer ) - */ -int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input, - size_t ilen, uint8_t *output, size_t olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_sha3_context ctx; - - mbedtls_sha3_init(&ctx); - - /* Sanity checks are performed in every mbedtls_sha3_xxx() */ - if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) { - goto exit; - } - -exit: - mbedtls_sha3_free(&ctx); - - return ret; -} - -/**************** Self-tests ****************/ - -#if defined(MBEDTLS_SELF_TEST) - -static const unsigned char test_data[2][4] = -{ - "", - "abc", -}; - -static const size_t test_data_len[2] = -{ - 0, /* "" */ - 3 /* "abc" */ -}; - -static const unsigned char test_hash_sha3_224[2][28] = -{ - { /* "" */ - 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7, - 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB, - 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F, - 0x5B, 0x5A, 0x6B, 0xC7 - }, - { /* "abc" */ - 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A, - 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F, - 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD, - 0x73, 0xB4, 0x6F, 0xDF - } -}; - -static const unsigned char test_hash_sha3_256[2][32] = -{ - { /* "" */ - 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66, - 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62, - 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA, - 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A - }, - { /* "abc" */ - 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2, - 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD, - 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B, - 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32 - } -}; - -static const unsigned char test_hash_sha3_384[2][48] = -{ - { /* "" */ - 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D, - 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85, - 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61, - 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A, - 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47, - 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04 - }, - { /* "abc" */ - 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9, - 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D, - 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25, - 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2, - 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5, - 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25 - } -}; - -static const unsigned char test_hash_sha3_512[2][64] = -{ - { /* "" */ - 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5, - 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E, - 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59, - 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6, - 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C, - 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58, - 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3, - 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26 - }, - { /* "abc" */ - 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A, - 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E, - 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D, - 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E, - 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9, - 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40, - 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5, - 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0 - } -}; - -static const unsigned char long_kat_hash_sha3_224[28] = -{ - 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E, - 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C, - 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7, - 0xA7, 0xFD, 0x65, 0x3C -}; - -static const unsigned char long_kat_hash_sha3_256[32] = -{ - 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34, - 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6, - 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99, - 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1 -}; - -static const unsigned char long_kat_hash_sha3_384[48] = -{ - 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53, - 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD, - 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E, - 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84, - 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42, - 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40 -}; - -static const unsigned char long_kat_hash_sha3_512[64] = -{ - 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB, - 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E, - 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF, - 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59, - 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE, - 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66, - 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E, - 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87 -}; - -static int mbedtls_sha3_kat_test(int verbose, - const char *type_name, - mbedtls_sha3_id id, - int test_num) -{ - uint8_t hash[64]; - int result; - - result = mbedtls_sha3(id, - test_data[test_num], test_data_len[test_num], - hash, sizeof(hash)); - if (result != 0) { - if (verbose != 0) { - mbedtls_printf(" %s test %d error code: %d\n", - type_name, test_num, result); - } - - return result; - } - - switch (id) { - case MBEDTLS_SHA3_224: - result = memcmp(hash, test_hash_sha3_224[test_num], 28); - break; - case MBEDTLS_SHA3_256: - result = memcmp(hash, test_hash_sha3_256[test_num], 32); - break; - case MBEDTLS_SHA3_384: - result = memcmp(hash, test_hash_sha3_384[test_num], 48); - break; - case MBEDTLS_SHA3_512: - result = memcmp(hash, test_hash_sha3_512[test_num], 64); - break; - default: - break; - } - - if (0 != result) { - if (verbose != 0) { - mbedtls_printf(" %s test %d failed\n", type_name, test_num); - } - - return -1; - } - - if (verbose != 0) { - mbedtls_printf(" %s test %d passed\n", type_name, test_num); - } - - return 0; -} - -static int mbedtls_sha3_long_kat_test(int verbose, - const char *type_name, - mbedtls_sha3_id id) -{ - mbedtls_sha3_context ctx; - unsigned char buffer[1000]; - unsigned char hash[64]; - int result = 0; - - memset(buffer, 'a', 1000); - - if (verbose != 0) { - mbedtls_printf(" %s long KAT test ", type_name); - } - - mbedtls_sha3_init(&ctx); - - result = mbedtls_sha3_starts(&ctx, id); - if (result != 0) { - if (verbose != 0) { - mbedtls_printf("setup failed\n "); - } - } - - /* Process 1,000,000 (one million) 'a' characters */ - for (int i = 0; i < 1000; i++) { - result = mbedtls_sha3_update(&ctx, buffer, 1000); - if (result != 0) { - if (verbose != 0) { - mbedtls_printf("update error code: %i\n", result); - } - - goto cleanup; - } - } - - result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash)); - if (result != 0) { - if (verbose != 0) { - mbedtls_printf("finish error code: %d\n", result); - } - - goto cleanup; - } - - switch (id) { - case MBEDTLS_SHA3_224: - result = memcmp(hash, long_kat_hash_sha3_224, 28); - break; - case MBEDTLS_SHA3_256: - result = memcmp(hash, long_kat_hash_sha3_256, 32); - break; - case MBEDTLS_SHA3_384: - result = memcmp(hash, long_kat_hash_sha3_384, 48); - break; - case MBEDTLS_SHA3_512: - result = memcmp(hash, long_kat_hash_sha3_512, 64); - break; - default: - break; - } - - if (result != 0) { - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - -cleanup: - mbedtls_sha3_free(&ctx); - return result; -} - -int mbedtls_sha3_self_test(int verbose) -{ - int i; - - /* SHA-3 Known Answer Tests (KAT) */ - for (i = 0; i < 2; i++) { - if (0 != mbedtls_sha3_kat_test(verbose, - "SHA3-224", MBEDTLS_SHA3_224, i)) { - return 1; - } - - if (0 != mbedtls_sha3_kat_test(verbose, - "SHA3-256", MBEDTLS_SHA3_256, i)) { - return 1; - } - - if (0 != mbedtls_sha3_kat_test(verbose, - "SHA3-384", MBEDTLS_SHA3_384, i)) { - return 1; - } - - if (0 != mbedtls_sha3_kat_test(verbose, - "SHA3-512", MBEDTLS_SHA3_512, i)) { - return 1; - } - } - - /* SHA-3 long KAT tests */ - if (0 != mbedtls_sha3_long_kat_test(verbose, - "SHA3-224", MBEDTLS_SHA3_224)) { - return 1; - } - - if (0 != mbedtls_sha3_long_kat_test(verbose, - "SHA3-256", MBEDTLS_SHA3_256)) { - return 1; - } - - if (0 != mbedtls_sha3_long_kat_test(verbose, - "SHA3-384", MBEDTLS_SHA3_384)) { - return 1; - } - - if (0 != mbedtls_sha3_long_kat_test(verbose, - "SHA3-512", MBEDTLS_SHA3_512)) { - return 1; - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - return 0; -} -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA3_C */ diff --git a/vendor/mbedtls/library/sha512.c b/vendor/mbedtls/library/sha512.c deleted file mode 100644 index 286cbdf9f..000000000 --- a/vendor/mbedtls/library/sha512.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * FIPS-180-2 compliant SHA-384/512 implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The SHA-512 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \ - defined(__clang__) && __clang_major__ >= 7 -/* - * The intrinsic declaration are guarded by predefined ACLE macros in clang: - * these are normally only enabled by the -march option on the command line. - * By defining the macros ourselves we gain access to those declarations without - * requiring -march on the command line. - * - * `arm_neon.h` is included by common.h, so we put these defines - * at the top of this file, before any includes but after the intrinsic - * declaration. This is necessary with - * Clang <=15.x. With Clang 16.0 and above, these macro definitions are - * no longer required, but they're harmless. See - * https://reviews.llvm.org/D131064 - */ -#define __ARM_FEATURE_SHA512 1 -#define MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG -#endif - -#include "common.h" - -#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C) - -#include "mbedtls/sha512.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/error.h" - -#if defined(_MSC_VER) || defined(__WATCOMC__) - #define UL64(x) x##ui64 -#else - #define UL64(x) x##ULL -#endif - -#include - -#include "mbedtls/platform.h" - -#if defined(__aarch64__) -# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \ - defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) -/* *INDENT-OFF* */ -# if !defined(MBEDTLS_HAVE_NEON_INTRINSICS) -# error "Target does not support NEON instructions" -# endif -/* - * Best performance comes from most recent compilers, with intrinsics and -O3. - * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and - * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12). - * - * GCC < 8 won't work at all (lacks the sha512 instructions) - * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512 - * - * Clang < 7 won't work at all (lacks the sha512 instructions) - * Clang 7-12 don't have intrinsics (but we work around that with inline - * assembler) or __ARM_FEATURE_SHA512 - * Clang == 13.0.0 same as clang 12 (only seen on macOS) - * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics - */ -# if !defined(__ARM_FEATURE_SHA512) || defined(MBEDTLS_ENABLE_ARM_SHA3_EXTENSIONS_COMPILER_FLAG) - /* Test Clang first, as it defines __GNUC__ */ -# if defined(__ARMCOMPILER_VERSION) -# if __ARMCOMPILER_VERSION < 6090000 -# error "A more recent armclang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# elif __ARMCOMPILER_VERSION == 6090000 -# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# else -# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function) -# define MBEDTLS_POP_TARGET_PRAGMA -# endif -# elif defined(__clang__) -# if __clang_major__ < 7 -# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# else -# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function) -# define MBEDTLS_POP_TARGET_PRAGMA -# endif -# elif defined(__GNUC__) -# if __GNUC__ < 8 -# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# else -# pragma GCC push_options -# pragma GCC target ("arch=armv8.2-a+sha3") -# define MBEDTLS_POP_TARGET_PRAGMA -# endif -# else -# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# endif -# endif -/* *INDENT-ON* */ -# endif -# if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) -# if defined(__unix__) -# if defined(__linux__) -/* Our preferred method of detection is getauxval() */ -# include -# if !defined(HWCAP_SHA512) -/* The same header that declares getauxval() should provide the HWCAP_xxx - * constants to analyze its return value. However, the libc may be too - * old to have the constant that we need. So if it's missing, assume that - * the value is the same one used by the Linux kernel ABI. - */ -# define HWCAP_SHA512 (1 << 21) -# endif -# endif -/* Use SIGILL on Unix, and fall back to it on Linux */ -# include -# endif -# endif -#elif !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) -# undef MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY -# undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT -#endif - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) -/* - * Capability detection code comes early, so we can disable - * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found - */ -#if defined(HWCAP_SHA512) -static int mbedtls_a64_crypto_sha512_determine_support(void) -{ - return (getauxval(AT_HWCAP) & HWCAP_SHA512) ? 1 : 0; -} -#elif defined(__APPLE__) -#include -#include - -static int mbedtls_a64_crypto_sha512_determine_support(void) -{ - int value = 0; - size_t value_len = sizeof(value); - - int ret = sysctlbyname("hw.optional.armv8_2_sha512", &value, &value_len, - NULL, 0); - return ret == 0 && value != 0; -} -#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) -/* - * As of March 2022, there don't appear to be any PF_ARM_V8_* flags - * available to pass to IsProcessorFeaturePresent() to check for - * SHA-512 support. So we fall back to the C code only. - */ -#if defined(_MSC_VER) -#pragma message "No mechanism to detect A64_CRYPTO found, using C code only" -#else -#warning "No mechanism to detect A64_CRYPTO found, using C code only" -#endif -#elif defined(__unix__) && defined(SIG_SETMASK) -/* Detection with SIGILL, setjmp() and longjmp() */ -#include -#include - -static jmp_buf return_from_sigill; - -/* - * A64 SHA512 support detection via SIGILL - */ -static void sigill_handler(int signal) -{ - (void) signal; - longjmp(return_from_sigill, 1); -} - -static int mbedtls_a64_crypto_sha512_determine_support(void) -{ - struct sigaction old_action, new_action; - - sigset_t old_mask; - if (sigprocmask(0, NULL, &old_mask)) { - return 0; - } - - sigemptyset(&new_action.sa_mask); - new_action.sa_flags = 0; - new_action.sa_handler = sigill_handler; - - sigaction(SIGILL, &new_action, &old_action); - - static int ret = 0; - - if (setjmp(return_from_sigill) == 0) { /* First return only */ - /* If this traps, we will return a second time from setjmp() with 1 */ - asm ("sha512h q0, q0, v0.2d" : : : "v0"); - ret = 1; - } - - sigaction(SIGILL, &old_action, NULL); - sigprocmask(SIG_SETMASK, &old_mask, NULL); - - return ret; -} -#else -#warning "No mechanism to detect A64_CRYPTO found, using C code only" -#undef MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT -#endif /* HWCAP_SHA512, __APPLE__, __unix__ && SIG_SETMASK */ - -#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */ - -#if !defined(MBEDTLS_SHA512_ALT) - -#define SHA512_BLOCK_SIZE 128 - -#if defined(MBEDTLS_SHA512_SMALLER) -static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i) -{ - MBEDTLS_PUT_UINT64_BE(n, b, i); -} -#else -#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE -#endif /* MBEDTLS_SHA512_SMALLER */ - -void mbedtls_sha512_init(mbedtls_sha512_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_sha512_context)); -} - -void mbedtls_sha512_free(mbedtls_sha512_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context)); -} - -void mbedtls_sha512_clone(mbedtls_sha512_context *dst, - const mbedtls_sha512_context *src) -{ - *dst = *src; -} - -/* - * SHA-512 context setup - */ -int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384) -{ -#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C) - if (is384 != 0 && is384 != 1) { - return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA; - } -#elif defined(MBEDTLS_SHA512_C) - if (is384 != 0) { - return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA; - } -#else /* defined MBEDTLS_SHA384_C only */ - if (is384 == 0) { - return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA; - } -#endif - - ctx->total[0] = 0; - ctx->total[1] = 0; - - if (is384 == 0) { -#if defined(MBEDTLS_SHA512_C) - ctx->state[0] = UL64(0x6A09E667F3BCC908); - ctx->state[1] = UL64(0xBB67AE8584CAA73B); - ctx->state[2] = UL64(0x3C6EF372FE94F82B); - ctx->state[3] = UL64(0xA54FF53A5F1D36F1); - ctx->state[4] = UL64(0x510E527FADE682D1); - ctx->state[5] = UL64(0x9B05688C2B3E6C1F); - ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); - ctx->state[7] = UL64(0x5BE0CD19137E2179); -#endif /* MBEDTLS_SHA512_C */ - } else { -#if defined(MBEDTLS_SHA384_C) - ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); - ctx->state[1] = UL64(0x629A292A367CD507); - ctx->state[2] = UL64(0x9159015A3070DD17); - ctx->state[3] = UL64(0x152FECD8F70E5939); - ctx->state[4] = UL64(0x67332667FFC00B31); - ctx->state[5] = UL64(0x8EB44A8768581511); - ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); - ctx->state[7] = UL64(0x47B5481DBEFA4FA4); -#endif /* MBEDTLS_SHA384_C */ - } - -#if defined(MBEDTLS_SHA384_C) - ctx->is384 = is384; -#endif - - return 0; -} - -#if !defined(MBEDTLS_SHA512_PROCESS_ALT) - -/* - * Round constants - */ -static const uint64_t K[80] = -{ - UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), - UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), - UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), - UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), - UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), - UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), - UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), - UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), - UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), - UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), - UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), - UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), - UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), - UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), - UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), - UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), - UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), - UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), - UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), - UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), - UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), - UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), - UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), - UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), - UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), - UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), - UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), - UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), - UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), - UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), - UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), - UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), - UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), - UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), - UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), - UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), - UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), - UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), - UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), - UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) -}; -#endif - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \ - defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) -# define mbedtls_internal_sha512_process_many_a64_crypto mbedtls_internal_sha512_process_many -# define mbedtls_internal_sha512_process_a64_crypto mbedtls_internal_sha512_process -#endif - -/* Accelerated SHA-512 implementation originally written by Simon Tatham for PuTTY, - * under the MIT licence; dual-licensed as Apache 2 with his kind permission. - */ - -#if defined(__clang__) && \ - (__clang_major__ < 13 || \ - (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0)) -static inline uint64x2_t vsha512su0q_u64(uint64x2_t x, uint64x2_t y) -{ - asm ("sha512su0 %0.2D,%1.2D" : "+w" (x) : "w" (y)); - return x; -} -static inline uint64x2_t vsha512su1q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z) -{ - asm ("sha512su1 %0.2D,%1.2D,%2.2D" : "+w" (x) : "w" (y), "w" (z)); - return x; -} -static inline uint64x2_t vsha512hq_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z) -{ - asm ("sha512h %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z)); - return x; -} -static inline uint64x2_t vsha512h2q_u64(uint64x2_t x, uint64x2_t y, uint64x2_t z) -{ - asm ("sha512h2 %0,%1,%2.2D" : "+w" (x) : "w" (y), "w" (z)); - return x; -} -#endif /* __clang__ etc */ - -static size_t mbedtls_internal_sha512_process_many_a64_crypto( - mbedtls_sha512_context *ctx, const uint8_t *msg, size_t len) -{ - uint64x2_t ab = vld1q_u64(&ctx->state[0]); - uint64x2_t cd = vld1q_u64(&ctx->state[2]); - uint64x2_t ef = vld1q_u64(&ctx->state[4]); - uint64x2_t gh = vld1q_u64(&ctx->state[6]); - - size_t processed = 0; - - for (; - len >= SHA512_BLOCK_SIZE; - processed += SHA512_BLOCK_SIZE, - msg += SHA512_BLOCK_SIZE, - len -= SHA512_BLOCK_SIZE) { - uint64x2_t initial_sum, sum, intermed; - - uint64x2_t ab_orig = ab; - uint64x2_t cd_orig = cd; - uint64x2_t ef_orig = ef; - uint64x2_t gh_orig = gh; - - uint64x2_t s0 = (uint64x2_t) vld1q_u8(msg + 16 * 0); - uint64x2_t s1 = (uint64x2_t) vld1q_u8(msg + 16 * 1); - uint64x2_t s2 = (uint64x2_t) vld1q_u8(msg + 16 * 2); - uint64x2_t s3 = (uint64x2_t) vld1q_u8(msg + 16 * 3); - uint64x2_t s4 = (uint64x2_t) vld1q_u8(msg + 16 * 4); - uint64x2_t s5 = (uint64x2_t) vld1q_u8(msg + 16 * 5); - uint64x2_t s6 = (uint64x2_t) vld1q_u8(msg + 16 * 6); - uint64x2_t s7 = (uint64x2_t) vld1q_u8(msg + 16 * 7); - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* assume LE if these not defined; untested on BE */ - s0 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s0))); - s1 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s1))); - s2 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s2))); - s3 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s3))); - s4 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s4))); - s5 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s5))); - s6 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s6))); - s7 = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(s7))); -#endif - - /* Rounds 0 and 1 */ - initial_sum = vaddq_u64(s0, vld1q_u64(&K[0])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh); - intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1)); - gh = vsha512h2q_u64(intermed, cd, ab); - cd = vaddq_u64(cd, intermed); - - /* Rounds 2 and 3 */ - initial_sum = vaddq_u64(s1, vld1q_u64(&K[2])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef); - intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1)); - ef = vsha512h2q_u64(intermed, ab, gh); - ab = vaddq_u64(ab, intermed); - - /* Rounds 4 and 5 */ - initial_sum = vaddq_u64(s2, vld1q_u64(&K[4])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd); - intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1)); - cd = vsha512h2q_u64(intermed, gh, ef); - gh = vaddq_u64(gh, intermed); - - /* Rounds 6 and 7 */ - initial_sum = vaddq_u64(s3, vld1q_u64(&K[6])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab); - intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1)); - ab = vsha512h2q_u64(intermed, ef, cd); - ef = vaddq_u64(ef, intermed); - - /* Rounds 8 and 9 */ - initial_sum = vaddq_u64(s4, vld1q_u64(&K[8])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh); - intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1)); - gh = vsha512h2q_u64(intermed, cd, ab); - cd = vaddq_u64(cd, intermed); - - /* Rounds 10 and 11 */ - initial_sum = vaddq_u64(s5, vld1q_u64(&K[10])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef); - intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1)); - ef = vsha512h2q_u64(intermed, ab, gh); - ab = vaddq_u64(ab, intermed); - - /* Rounds 12 and 13 */ - initial_sum = vaddq_u64(s6, vld1q_u64(&K[12])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd); - intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1)); - cd = vsha512h2q_u64(intermed, gh, ef); - gh = vaddq_u64(gh, intermed); - - /* Rounds 14 and 15 */ - initial_sum = vaddq_u64(s7, vld1q_u64(&K[14])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab); - intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1)); - ab = vsha512h2q_u64(intermed, ef, cd); - ef = vaddq_u64(ef, intermed); - - for (unsigned int t = 16; t < 80; t += 16) { - /* Rounds t and t + 1 */ - s0 = vsha512su1q_u64(vsha512su0q_u64(s0, s1), s7, vextq_u64(s4, s5, 1)); - initial_sum = vaddq_u64(s0, vld1q_u64(&K[t])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh); - intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1)); - gh = vsha512h2q_u64(intermed, cd, ab); - cd = vaddq_u64(cd, intermed); - - /* Rounds t + 2 and t + 3 */ - s1 = vsha512su1q_u64(vsha512su0q_u64(s1, s2), s0, vextq_u64(s5, s6, 1)); - initial_sum = vaddq_u64(s1, vld1q_u64(&K[t + 2])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef); - intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1)); - ef = vsha512h2q_u64(intermed, ab, gh); - ab = vaddq_u64(ab, intermed); - - /* Rounds t + 4 and t + 5 */ - s2 = vsha512su1q_u64(vsha512su0q_u64(s2, s3), s1, vextq_u64(s6, s7, 1)); - initial_sum = vaddq_u64(s2, vld1q_u64(&K[t + 4])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd); - intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1)); - cd = vsha512h2q_u64(intermed, gh, ef); - gh = vaddq_u64(gh, intermed); - - /* Rounds t + 6 and t + 7 */ - s3 = vsha512su1q_u64(vsha512su0q_u64(s3, s4), s2, vextq_u64(s7, s0, 1)); - initial_sum = vaddq_u64(s3, vld1q_u64(&K[t + 6])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab); - intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1)); - ab = vsha512h2q_u64(intermed, ef, cd); - ef = vaddq_u64(ef, intermed); - - /* Rounds t + 8 and t + 9 */ - s4 = vsha512su1q_u64(vsha512su0q_u64(s4, s5), s3, vextq_u64(s0, s1, 1)); - initial_sum = vaddq_u64(s4, vld1q_u64(&K[t + 8])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), gh); - intermed = vsha512hq_u64(sum, vextq_u64(ef, gh, 1), vextq_u64(cd, ef, 1)); - gh = vsha512h2q_u64(intermed, cd, ab); - cd = vaddq_u64(cd, intermed); - - /* Rounds t + 10 and t + 11 */ - s5 = vsha512su1q_u64(vsha512su0q_u64(s5, s6), s4, vextq_u64(s1, s2, 1)); - initial_sum = vaddq_u64(s5, vld1q_u64(&K[t + 10])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ef); - intermed = vsha512hq_u64(sum, vextq_u64(cd, ef, 1), vextq_u64(ab, cd, 1)); - ef = vsha512h2q_u64(intermed, ab, gh); - ab = vaddq_u64(ab, intermed); - - /* Rounds t + 12 and t + 13 */ - s6 = vsha512su1q_u64(vsha512su0q_u64(s6, s7), s5, vextq_u64(s2, s3, 1)); - initial_sum = vaddq_u64(s6, vld1q_u64(&K[t + 12])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), cd); - intermed = vsha512hq_u64(sum, vextq_u64(ab, cd, 1), vextq_u64(gh, ab, 1)); - cd = vsha512h2q_u64(intermed, gh, ef); - gh = vaddq_u64(gh, intermed); - - /* Rounds t + 14 and t + 15 */ - s7 = vsha512su1q_u64(vsha512su0q_u64(s7, s0), s6, vextq_u64(s3, s4, 1)); - initial_sum = vaddq_u64(s7, vld1q_u64(&K[t + 14])); - sum = vaddq_u64(vextq_u64(initial_sum, initial_sum, 1), ab); - intermed = vsha512hq_u64(sum, vextq_u64(gh, ab, 1), vextq_u64(ef, gh, 1)); - ab = vsha512h2q_u64(intermed, ef, cd); - ef = vaddq_u64(ef, intermed); - } - - ab = vaddq_u64(ab, ab_orig); - cd = vaddq_u64(cd, cd_orig); - ef = vaddq_u64(ef, ef_orig); - gh = vaddq_u64(gh, gh_orig); - } - - vst1q_u64(&ctx->state[0], ab); - vst1q_u64(&ctx->state[2], cd); - vst1q_u64(&ctx->state[4], ef); - vst1q_u64(&ctx->state[6], gh); - - return processed; -} - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) -/* - * This function is for internal use only if we are building both C and A64 - * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process() - */ -static -#endif -int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx, - const unsigned char data[SHA512_BLOCK_SIZE]) -{ - return (mbedtls_internal_sha512_process_many_a64_crypto(ctx, data, - SHA512_BLOCK_SIZE) == - SHA512_BLOCK_SIZE) ? 0 : -1; -} - -#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ - -#if defined(MBEDTLS_POP_TARGET_PRAGMA) -#if defined(__clang__) -#pragma clang attribute pop -#elif defined(__GNUC__) -#pragma GCC pop_options -#endif -#undef MBEDTLS_POP_TARGET_PRAGMA -#endif - - -#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) -#define mbedtls_internal_sha512_process_many_c mbedtls_internal_sha512_process_many -#define mbedtls_internal_sha512_process_c mbedtls_internal_sha512_process -#endif - - -#if !defined(MBEDTLS_SHA512_PROCESS_ALT) && !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) -/* - * This function is for internal use only if we are building both C and A64 - * versions, otherwise it is renamed to be the public mbedtls_internal_sha512_process() - */ -static -#endif -int mbedtls_internal_sha512_process_c(mbedtls_sha512_context *ctx, - const unsigned char data[SHA512_BLOCK_SIZE]) -{ - int i; - struct { - uint64_t temp1, temp2, W[80]; - uint64_t A[8]; - } local; - -#define SHR(x, n) ((x) >> (n)) -#define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n)))) - -#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) -#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6)) - -#define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) -#define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) - -#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) - -#define P(a, b, c, d, e, f, g, h, x, K) \ - do \ - { \ - local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \ - local.temp2 = S2(a) + F0((a), (b), (c)); \ - (d) += local.temp1; (h) = local.temp1 + local.temp2; \ - } while (0) - - for (i = 0; i < 8; i++) { - local.A[i] = ctx->state[i]; - } - -#if defined(MBEDTLS_SHA512_SMALLER) - for (i = 0; i < 80; i++) { - if (i < 16) { - local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3); - } else { - local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] + - S0(local.W[i - 15]) + local.W[i - 16]; - } - - P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], local.W[i], K[i]); - - local.temp1 = local.A[7]; local.A[7] = local.A[6]; - local.A[6] = local.A[5]; local.A[5] = local.A[4]; - local.A[4] = local.A[3]; local.A[3] = local.A[2]; - local.A[2] = local.A[1]; local.A[1] = local.A[0]; - local.A[0] = local.temp1; - } -#else /* MBEDTLS_SHA512_SMALLER */ - for (i = 0; i < 16; i++) { - local.W[i] = MBEDTLS_GET_UINT64_BE(data, i << 3); - } - - for (; i < 80; i++) { - local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] + - S0(local.W[i - 15]) + local.W[i - 16]; - } - - i = 0; - do { - P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], - local.A[5], local.A[6], local.A[7], local.W[i], K[i]); i++; - P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], - local.A[4], local.A[5], local.A[6], local.W[i], K[i]); i++; - P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], - local.A[3], local.A[4], local.A[5], local.W[i], K[i]); i++; - P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], - local.A[2], local.A[3], local.A[4], local.W[i], K[i]); i++; - P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], - local.A[1], local.A[2], local.A[3], local.W[i], K[i]); i++; - P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], - local.A[0], local.A[1], local.A[2], local.W[i], K[i]); i++; - P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], - local.A[7], local.A[0], local.A[1], local.W[i], K[i]); i++; - P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], - local.A[6], local.A[7], local.A[0], local.W[i], K[i]); i++; - } while (i < 80); -#endif /* MBEDTLS_SHA512_SMALLER */ - - for (i = 0; i < 8; i++) { - ctx->state[i] += local.A[i]; - } - - /* Zeroise buffers and variables to clear sensitive data from memory. */ - mbedtls_platform_zeroize(&local, sizeof(local)); - - return 0; -} - -#endif /* !MBEDTLS_SHA512_PROCESS_ALT && !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ - - -#if !defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) - -static size_t mbedtls_internal_sha512_process_many_c( - mbedtls_sha512_context *ctx, const uint8_t *data, size_t len) -{ - size_t processed = 0; - - while (len >= SHA512_BLOCK_SIZE) { - if (mbedtls_internal_sha512_process_c(ctx, data) != 0) { - return 0; - } - - data += SHA512_BLOCK_SIZE; - len -= SHA512_BLOCK_SIZE; - - processed += SHA512_BLOCK_SIZE; - } - - return processed; -} - -#endif /* !MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ - - -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) - -static int mbedtls_a64_crypto_sha512_has_support(void) -{ - static int done = 0; - static int supported = 0; - - if (!done) { - supported = mbedtls_a64_crypto_sha512_determine_support(); - done = 1; - } - - return supported; -} - -static size_t mbedtls_internal_sha512_process_many(mbedtls_sha512_context *ctx, - const uint8_t *msg, size_t len) -{ - if (mbedtls_a64_crypto_sha512_has_support()) { - return mbedtls_internal_sha512_process_many_a64_crypto(ctx, msg, len); - } else { - return mbedtls_internal_sha512_process_many_c(ctx, msg, len); - } -} - -int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx, - const unsigned char data[SHA512_BLOCK_SIZE]) -{ - if (mbedtls_a64_crypto_sha512_has_support()) { - return mbedtls_internal_sha512_process_a64_crypto(ctx, data); - } else { - return mbedtls_internal_sha512_process_c(ctx, data); - } -} - -#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */ - -/* - * SHA-512 process buffer - */ -int mbedtls_sha512_update(mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t fill; - unsigned int left; - - if (ilen == 0) { - return 0; - } - - left = (unsigned int) (ctx->total[0] & 0x7F); - fill = SHA512_BLOCK_SIZE - left; - - ctx->total[0] += (uint64_t) ilen; - - if (ctx->total[0] < (uint64_t) ilen) { - ctx->total[1]++; - } - - if (left && ilen >= fill) { - memcpy((void *) (ctx->buffer + left), input, fill); - - if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) { - return ret; - } - - input += fill; - ilen -= fill; - left = 0; - } - - while (ilen >= SHA512_BLOCK_SIZE) { - size_t processed = - mbedtls_internal_sha512_process_many(ctx, input, ilen); - if (processed < SHA512_BLOCK_SIZE) { - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } - - input += processed; - ilen -= processed; - } - - if (ilen > 0) { - memcpy((void *) (ctx->buffer + left), input, ilen); - } - - return 0; -} - -/* - * SHA-512 final digest - */ -int mbedtls_sha512_finish(mbedtls_sha512_context *ctx, - unsigned char *output) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned used; - uint64_t high, low; - int truncated = 0; - - /* - * Add padding: 0x80 then 0x00 until 16 bytes remain for the length - */ - used = ctx->total[0] & 0x7F; - - ctx->buffer[used++] = 0x80; - - if (used <= 112) { - /* Enough room for padding + length in current block */ - memset(ctx->buffer + used, 0, 112 - used); - } else { - /* We'll need an extra block */ - memset(ctx->buffer + used, 0, SHA512_BLOCK_SIZE - used); - - if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - memset(ctx->buffer, 0, 112); - } - - /* - * Add message length - */ - high = (ctx->total[0] >> 61) - | (ctx->total[1] << 3); - low = (ctx->total[0] << 3); - - sha512_put_uint64_be(high, ctx->buffer, 112); - sha512_put_uint64_be(low, ctx->buffer, 120); - - if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0) { - goto exit; - } - - /* - * Output final state - */ - sha512_put_uint64_be(ctx->state[0], output, 0); - sha512_put_uint64_be(ctx->state[1], output, 8); - sha512_put_uint64_be(ctx->state[2], output, 16); - sha512_put_uint64_be(ctx->state[3], output, 24); - sha512_put_uint64_be(ctx->state[4], output, 32); - sha512_put_uint64_be(ctx->state[5], output, 40); - -#if defined(MBEDTLS_SHA384_C) - truncated = ctx->is384; -#endif - if (!truncated) { - sha512_put_uint64_be(ctx->state[6], output, 48); - sha512_put_uint64_be(ctx->state[7], output, 56); - } - - ret = 0; - -exit: - mbedtls_sha512_free(ctx); - return ret; -} - -#endif /* !MBEDTLS_SHA512_ALT */ - -/* - * output = SHA-512( input buffer ) - */ -int mbedtls_sha512(const unsigned char *input, - size_t ilen, - unsigned char *output, - int is384) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_sha512_context ctx; - -#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C) - if (is384 != 0 && is384 != 1) { - return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA; - } -#elif defined(MBEDTLS_SHA512_C) - if (is384 != 0) { - return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA; - } -#else /* defined MBEDTLS_SHA384_C only */ - if (is384 == 0) { - return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA; - } -#endif - - mbedtls_sha512_init(&ctx); - - if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0) { - goto exit; - } - - if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0) { - goto exit; - } - -exit: - mbedtls_sha512_free(&ctx); - - return ret; -} - -#if defined(MBEDTLS_SELF_TEST) - -/* - * FIPS-180-2 test vectors - */ -static const unsigned char sha_test_buf[3][113] = -{ - { "abc" }, - { - "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" - }, - { "" } -}; - -static const size_t sha_test_buflen[3] = -{ - 3, 112, 1000 -}; - -typedef const unsigned char (sha_test_sum_t)[64]; - -/* - * SHA-384 test vectors - */ -#if defined(MBEDTLS_SHA384_C) -static sha_test_sum_t sha384_test_sum[] = -{ - { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, - 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, - 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, - 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, - 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, - 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, - { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, - 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, - 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, - 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, - 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, - 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, - { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, - 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, - 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, - 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, - 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, - 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 } -}; -#endif /* MBEDTLS_SHA384_C */ - -/* - * SHA-512 test vectors - */ -#if defined(MBEDTLS_SHA512_C) -static sha_test_sum_t sha512_test_sum[] = -{ - { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, - 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, - 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, - 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, - 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, - 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, - 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, - 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, - { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, - 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, - 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, - 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, - 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, - 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, - 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, - 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, - { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, - 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, - 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, - 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, - 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, - 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, - 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, - 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } -}; -#endif /* MBEDTLS_SHA512_C */ - -static int mbedtls_sha512_common_self_test(int verbose, int is384) -{ - int i, buflen, ret = 0; - unsigned char *buf; - unsigned char sha512sum[64]; - mbedtls_sha512_context ctx; - -#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_SHA512_C) - sha_test_sum_t *sha_test_sum = (is384) ? sha384_test_sum : sha512_test_sum; -#elif defined(MBEDTLS_SHA512_C) - sha_test_sum_t *sha_test_sum = sha512_test_sum; -#else - sha_test_sum_t *sha_test_sum = sha384_test_sum; -#endif - - buf = mbedtls_calloc(1024, sizeof(unsigned char)); - if (NULL == buf) { - if (verbose != 0) { - mbedtls_printf("Buffer allocation failed\n"); - } - - return 1; - } - - mbedtls_sha512_init(&ctx); - - for (i = 0; i < 3; i++) { - if (verbose != 0) { - mbedtls_printf(" SHA-%d test #%d: ", 512 - is384 * 128, i + 1); - } - - if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0) { - goto fail; - } - - if (i == 2) { - memset(buf, 'a', buflen = 1000); - - for (int j = 0; j < 1000; j++) { - ret = mbedtls_sha512_update(&ctx, buf, buflen); - if (ret != 0) { - goto fail; - } - } - } else { - ret = mbedtls_sha512_update(&ctx, sha_test_buf[i], - sha_test_buflen[i]); - if (ret != 0) { - goto fail; - } - } - - if ((ret = mbedtls_sha512_finish(&ctx, sha512sum)) != 0) { - goto fail; - } - - if (memcmp(sha512sum, sha_test_sum[i], 64 - is384 * 16) != 0) { - ret = 1; - goto fail; - } - - if (verbose != 0) { - mbedtls_printf("passed\n"); - } - } - - if (verbose != 0) { - mbedtls_printf("\n"); - } - - goto exit; - -fail: - if (verbose != 0) { - mbedtls_printf("failed\n"); - } - -exit: - mbedtls_sha512_free(&ctx); - mbedtls_free(buf); - - return ret; -} - -#if defined(MBEDTLS_SHA512_C) -int mbedtls_sha512_self_test(int verbose) -{ - return mbedtls_sha512_common_self_test(verbose, 0); -} -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA384_C) -int mbedtls_sha384_self_test(int verbose) -{ - return mbedtls_sha512_common_self_test(verbose, 1); -} -#endif /* MBEDTLS_SHA384_C */ - -#undef ARRAY_LENGTH - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_SHA512_C || MBEDTLS_SHA384_C */ diff --git a/vendor/mbedtls/library/ssl_cache.c b/vendor/mbedtls/library/ssl_cache.c deleted file mode 100644 index 772cb8fdf..000000000 --- a/vendor/mbedtls/library/ssl_cache.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * SSL session cache implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * These session callbacks use a simple chained list - * to store and retrieve the session information. - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_CACHE_C) - -#include "mbedtls/platform.h" - -#include "mbedtls/ssl_cache.h" -#include "ssl_misc.h" -#include "mbedtls/error.h" - -#include - -void mbedtls_ssl_cache_init(mbedtls_ssl_cache_context *cache) -{ - memset(cache, 0, sizeof(mbedtls_ssl_cache_context)); - - cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT; - cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&cache->mutex); -#endif -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_cache_find_entry(mbedtls_ssl_cache_context *cache, - unsigned char const *session_id, - size_t session_id_len, - mbedtls_ssl_cache_entry **dst) -{ - int ret = MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t = mbedtls_time(NULL); -#endif - mbedtls_ssl_cache_entry *cur; - - for (cur = cache->chain; cur != NULL; cur = cur->next) { -#if defined(MBEDTLS_HAVE_TIME) - if (cache->timeout != 0 && - (int) (t - cur->timestamp) > cache->timeout) { - continue; - } -#endif - - if (session_id_len != cur->session_id_len || - memcmp(session_id, cur->session_id, - cur->session_id_len) != 0) { - continue; - } - - break; - } - - if (cur != NULL) { - *dst = cur; - ret = 0; - } - - return ret; -} - - -int mbedtls_ssl_cache_get(void *data, - unsigned char const *session_id, - size_t session_id_len, - mbedtls_ssl_session *session) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *entry; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) { - return ret; - } -#endif - - ret = ssl_cache_find_entry(cache, session_id, session_id_len, &entry); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_ssl_session_load(session, - entry->session, - entry->session_len); - if (ret != 0) { - goto exit; - } - - ret = 0; - -exit: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&cache->mutex) != 0) { - ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -/* zeroize a cache entry */ -static void ssl_cache_entry_zeroize(mbedtls_ssl_cache_entry *entry) -{ - if (entry == NULL) { - return; - } - - /* zeroize and free session structure */ - if (entry->session != NULL) { - mbedtls_zeroize_and_free(entry->session, entry->session_len); - } - - /* zeroize the whole entry structure */ - mbedtls_platform_zeroize(entry, sizeof(mbedtls_ssl_cache_entry)); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_cache_pick_writing_slot(mbedtls_ssl_cache_context *cache, - unsigned char const *session_id, - size_t session_id_len, - mbedtls_ssl_cache_entry **dst) -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t = mbedtls_time(NULL), oldest = 0; -#endif /* MBEDTLS_HAVE_TIME */ - - mbedtls_ssl_cache_entry *old = NULL; - int count = 0; - mbedtls_ssl_cache_entry *cur, *last; - - /* Check 1: Is there already an entry with the given session ID? - * - * If yes, overwrite it. - * - * If not, `count` will hold the size of the session cache - * at the end of this loop, and `last` will point to the last - * entry, both of which will be used later. */ - - last = NULL; - for (cur = cache->chain; cur != NULL; cur = cur->next) { - count++; - if (session_id_len == cur->session_id_len && - memcmp(session_id, cur->session_id, cur->session_id_len) == 0) { - goto found; - } - last = cur; - } - - /* Check 2: Is there an outdated entry in the cache? - * - * If so, overwrite it. - * - * If not, remember the oldest entry in `old` for later. - */ - -#if defined(MBEDTLS_HAVE_TIME) - for (cur = cache->chain; cur != NULL; cur = cur->next) { - if (cache->timeout != 0 && - (int) (t - cur->timestamp) > cache->timeout) { - goto found; - } - - if (oldest == 0 || cur->timestamp < oldest) { - oldest = cur->timestamp; - old = cur; - } - } -#endif /* MBEDTLS_HAVE_TIME */ - - /* Check 3: Is there free space in the cache? */ - - if (count < cache->max_entries) { - /* Create new entry */ - cur = mbedtls_calloc(1, sizeof(mbedtls_ssl_cache_entry)); - if (cur == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - /* Append to the end of the linked list. */ - if (last == NULL) { - cache->chain = cur; - } else { - last->next = cur; - } - - goto found; - } - - /* Last resort: The cache is full and doesn't contain any outdated - * elements. In this case, we evict the oldest one, judged by timestamp - * (if present) or cache-order. */ - -#if defined(MBEDTLS_HAVE_TIME) - if (old == NULL) { - /* This should only happen on an ill-configured cache - * with max_entries == 0. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } -#else /* MBEDTLS_HAVE_TIME */ - /* Reuse first entry in chain, but move to last place. */ - if (cache->chain == NULL) { - /* This should never happen */ - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - - old = cache->chain; - cache->chain = old->next; - old->next = NULL; - last->next = old; -#endif /* MBEDTLS_HAVE_TIME */ - - /* Now `old` points to the oldest entry to be overwritten. */ - cur = old; - -found: - - /* If we're reusing an entry, free it first. */ - if (cur->session != NULL) { - /* `ssl_cache_entry_zeroize` would break the chain, - * so we reuse `old` to record `next` temporarily. */ - old = cur->next; - ssl_cache_entry_zeroize(cur); - cur->next = old; - } - -#if defined(MBEDTLS_HAVE_TIME) - cur->timestamp = t; -#endif - - *dst = cur; - return 0; -} - -int mbedtls_ssl_cache_set(void *data, - unsigned char const *session_id, - size_t session_id_len, - const mbedtls_ssl_session *session) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *cur; - - size_t session_serialized_len = 0; - unsigned char *session_serialized = NULL; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) { - return ret; - } -#endif - - ret = ssl_cache_pick_writing_slot(cache, - session_id, session_id_len, - &cur); - if (ret != 0) { - goto exit; - } - - /* Check how much space we need to serialize the session - * and allocate a sufficiently large buffer. */ - ret = mbedtls_ssl_session_save(session, NULL, 0, &session_serialized_len); - if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) { - goto exit; - } - - session_serialized = mbedtls_calloc(1, session_serialized_len); - if (session_serialized == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - - /* Now serialize the session into the allocated buffer. */ - ret = mbedtls_ssl_session_save(session, - session_serialized, - session_serialized_len, - &session_serialized_len); - if (ret != 0) { - goto exit; - } - - if (session_id_len > sizeof(cur->session_id)) { - ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - goto exit; - } - cur->session_id_len = session_id_len; - memcpy(cur->session_id, session_id, session_id_len); - - cur->session = session_serialized; - cur->session_len = session_serialized_len; - session_serialized = NULL; - - ret = 0; - -exit: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&cache->mutex) != 0) { - ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - if (session_serialized != NULL) { - mbedtls_zeroize_and_free(session_serialized, session_serialized_len); - session_serialized = NULL; - } - - return ret; -} - -int mbedtls_ssl_cache_remove(void *data, - unsigned char const *session_id, - size_t session_id_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *entry; - mbedtls_ssl_cache_entry *prev; - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&cache->mutex)) != 0) { - return ret; - } -#endif - - ret = ssl_cache_find_entry(cache, session_id, session_id_len, &entry); - /* No valid entry found, exit with success */ - if (ret != 0) { - ret = 0; - goto exit; - } - - /* Now we remove the entry from the chain */ - if (entry == cache->chain) { - cache->chain = entry->next; - goto free; - } - for (prev = cache->chain; prev->next != NULL; prev = prev->next) { - if (prev->next == entry) { - prev->next = entry->next; - break; - } - } - -free: - ssl_cache_entry_zeroize(entry); - mbedtls_free(entry); - ret = 0; - -exit: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&cache->mutex) != 0) { - ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -#if defined(MBEDTLS_HAVE_TIME) -void mbedtls_ssl_cache_set_timeout(mbedtls_ssl_cache_context *cache, int timeout) -{ - if (timeout < 0) { - timeout = 0; - } - - cache->timeout = timeout; -} -#endif /* MBEDTLS_HAVE_TIME */ - -void mbedtls_ssl_cache_set_max_entries(mbedtls_ssl_cache_context *cache, int max) -{ - if (max < 0) { - max = 0; - } - - cache->max_entries = max; -} - -void mbedtls_ssl_cache_free(mbedtls_ssl_cache_context *cache) -{ - mbedtls_ssl_cache_entry *cur, *prv; - - cur = cache->chain; - - while (cur != NULL) { - prv = cur; - cur = cur->next; - - ssl_cache_entry_zeroize(prv); - mbedtls_free(prv); - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free(&cache->mutex); -#endif - cache->chain = NULL; -} - -#endif /* MBEDTLS_SSL_CACHE_C */ diff --git a/vendor/mbedtls/library/ssl_ciphersuites.c b/vendor/mbedtls/library/ssl_ciphersuites.c deleted file mode 100644 index 23619a26c..000000000 --- a/vendor/mbedtls/library/ssl_ciphersuites.c +++ /dev/null @@ -1,2050 +0,0 @@ -/** - * \file ssl_ciphersuites.c - * - * \brief SSL ciphersuites for Mbed TLS - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_TLS_C) - -#include "mbedtls/platform.h" - -#include "mbedtls/ssl_ciphersuites.h" -#include "mbedtls/ssl.h" -#include "ssl_misc.h" -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -#endif - -#include - -/* - * Ordered from most preferred to least preferred in terms of security. - * - * Current rule (except weak and null which come last): - * 1. By key exchange: - * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK - * 2. By key length and cipher: - * ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 - * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 - * 4. By hash function used when relevant - * 5. By key exchange/auth again: EC > non-EC - */ -static const int ciphersuite_preference[] = -{ -#if defined(MBEDTLS_SSL_CIPHERSUITES) - MBEDTLS_SSL_CIPHERSUITES, -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - /* TLS 1.3 ciphersuites */ - MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS1_3_AES_256_GCM_SHA384, - MBEDTLS_TLS1_3_AES_128_GCM_SHA256, - MBEDTLS_TLS1_3_AES_128_CCM_SHA256, - MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - /* Chacha-Poly ephemeral suites */ - MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - - /* All AES-256 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, - - /* All CAMELLIA-256 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - - /* All ARIA-256 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, - - /* All AES-128 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, - - /* All CAMELLIA-128 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - - /* All ARIA-128 ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - - /* The PSK ephemeral suites */ - MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - - /* The ECJPAKE suite */ - MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, - - /* All AES-256 suites */ - MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, - - /* All CAMELLIA-256 suites */ - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - - /* All ARIA-256 suites */ - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, - - /* All AES-128 suites */ - MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, - - /* All CAMELLIA-128 suites */ - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - - /* All ARIA-128 suites */ - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - - /* The RSA PSK suites */ - MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - - /* The PSK suites */ - MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_PSK_WITH_AES_256_CCM, - MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, - MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_128_CCM, - MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, - MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256, - - /* NULL suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, - - MBEDTLS_TLS_RSA_WITH_NULL_SHA256, - MBEDTLS_TLS_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_RSA_WITH_NULL_MD5, - MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, - MBEDTLS_TLS_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_PSK_WITH_NULL_SHA, - -#endif /* MBEDTLS_SSL_CIPHERSUITES */ - 0 -}; - -static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = -{ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS1_3_AES_256_GCM_SHA384, "TLS1-3-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, - MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ - 0, - MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS1_3_AES_128_GCM_SHA256, "TLS1-3-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ - 0, - MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#if defined(MBEDTLS_SSL_HAVE_CCM) && defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS1_3_AES_128_CCM_SHA256, "TLS1-3-AES-128-CCM-SHA256", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ - 0, - MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 }, - { MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, "TLS1-3-AES-128-CCM-8-SHA256", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 }, -#endif /* MBEDTLS_MD_CAN_SHA256 && MBEDTLS_SSL_HAVE_CCM */ -#endif /* MBEDTLS_SSL_HAVE_AES */ -#if defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) && defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256, - "TLS1-3-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ - 0, - MBEDTLS_SSL_VERSION_TLS1_3, MBEDTLS_SSL_VERSION_TLS1_3 }, -#endif /* MBEDTLS_SSL_HAVE_CHACHAPOLY && MBEDTLS_MD_CAN_SHA256 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) && \ - defined(MBEDTLS_MD_CAN_SHA256) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - { MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - { MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - { MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - { MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - { MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#endif /* MBEDTLS_SSL_HAVE_CHACHAPOLY && - MBEDTLS_MD_CAN_SHA256 && - MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_MD_CAN_SHA1) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_SSL_HAVE_CCM) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CCM */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_MD_CAN_SHA1) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, - "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, - "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, - "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_MD_CAN_SHA384) && \ - defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 && MBEDTLS_SSL_HAVE_GCM */ - -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ - -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_CCM) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CCM */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_MD_CAN_SHA384) && \ - defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 && MBEDTLS_SSL_HAVE_GCM */ - -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ - -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA1) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_SSL_HAVE_CCM) - { MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CCM */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_MD_CAN_SHA1) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, - "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, - "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, - "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, - "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_MD_CAN_SHA1) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_SSL_HAVE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_GCM) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ - -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ - -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_CCM) - { MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CCM */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ - -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ - -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#if defined(MBEDTLS_SSL_HAVE_CCM) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CCM */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) - -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ - -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ - -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ - -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, - - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ -#endif /* MBEDTLS_SSL_HAVE_AES */ - -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) -#if defined(MBEDTLS_SSL_HAVE_CBC) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_CBC */ - -#if defined(MBEDTLS_SSL_HAVE_GCM) -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_SSL_HAVE_GCM */ -#endif /* MBEDTLS_SSL_HAVE_CAMELLIA */ - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#if defined(MBEDTLS_SSL_HAVE_AES) -#if defined(MBEDTLS_SSL_HAVE_CCM) - { MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE, - MBEDTLS_CIPHERSUITE_SHORT_TAG, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_SSL_HAVE_CCM */ -#endif /* MBEDTLS_SSL_HAVE_AES */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_MD_CAN_MD5) - { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ - -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ - -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ - -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -#if defined(MBEDTLS_MD_CAN_SHA1) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA1 */ - -#if defined(MBEDTLS_MD_CAN_SHA256) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_CIPHERSUITE_WEAK, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - -#if defined(MBEDTLS_SSL_HAVE_ARIA) - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA384)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_GCM) && defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif -#if (defined(MBEDTLS_SSL_HAVE_CBC) && \ - defined(MBEDTLS_MD_CAN_SHA256)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - 0, - MBEDTLS_SSL_VERSION_TLS1_2, MBEDTLS_SSL_VERSION_TLS1_2 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#endif /* MBEDTLS_SSL_HAVE_ARIA */ - - - { 0, "", - MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE, - 0, 0, 0 } -}; - -#if defined(MBEDTLS_SSL_CIPHERSUITES) -const int *mbedtls_ssl_list_ciphersuites(void) -{ - return ciphersuite_preference; -} -#else -#define MAX_CIPHERSUITES sizeof(ciphersuite_definitions) / \ - sizeof(ciphersuite_definitions[0]) -static int supported_ciphersuites[MAX_CIPHERSUITES]; -static int supported_init = 0; - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ciphersuite_is_removed(const mbedtls_ssl_ciphersuite_t *cs_info) -{ - (void) cs_info; - - return 0; -} - -const int *mbedtls_ssl_list_ciphersuites(void) -{ - /* - * On initial call filter out all ciphersuites not supported by current - * build based on presence in the ciphersuite_definitions. - */ - if (supported_init == 0) { - const int *p; - int *q; - - for (p = ciphersuite_preference, q = supported_ciphersuites; - *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; - p++) { - const mbedtls_ssl_ciphersuite_t *cs_info; - if ((cs_info = mbedtls_ssl_ciphersuite_from_id(*p)) != NULL && - !ciphersuite_is_removed(cs_info)) { - *(q++) = *p; - } - } - *q = 0; - - supported_init = 1; - } - - return supported_ciphersuites; -} -#endif /* MBEDTLS_SSL_CIPHERSUITES */ - -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( - const char *ciphersuite_name) -{ - const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; - - if (NULL == ciphersuite_name) { - return NULL; - } - - while (cur->id != 0) { - if (0 == strcmp(cur->name, ciphersuite_name)) { - return cur; - } - - cur++; - } - - return NULL; -} - -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id(int ciphersuite) -{ - const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; - - while (cur->id != 0) { - if (cur->id == ciphersuite) { - return cur; - } - - cur++; - } - - return NULL; -} - -const char *mbedtls_ssl_get_ciphersuite_name(const int ciphersuite_id) -{ - const mbedtls_ssl_ciphersuite_t *cur; - - cur = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id); - - if (cur == NULL) { - return "unknown"; - } - - return cur->name; -} - -int mbedtls_ssl_get_ciphersuite_id(const char *ciphersuite_name) -{ - const mbedtls_ssl_ciphersuite_t *cur; - - cur = mbedtls_ssl_ciphersuite_from_string(ciphersuite_name); - - if (cur == NULL) { - return 0; - } - - return cur->id; -} - -size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t key_type; - psa_algorithm_t alg; - size_t key_bits; - - status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) info->cipher, - info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16, - &alg, &key_type, &key_bits); - - if (status != PSA_SUCCESS) { - return 0; - } - - return key_bits; -#else - const mbedtls_cipher_info_t * const cipher_info = - mbedtls_cipher_info_from_type((mbedtls_cipher_type_t) info->cipher); - - return mbedtls_cipher_info_get_key_bitlen(cipher_info); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} - -#if defined(MBEDTLS_PK_C) -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->key_exchange) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return MBEDTLS_PK_RSA; - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return MBEDTLS_PK_ECDSA; - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return MBEDTLS_PK_ECKEY; - - default: - return MBEDTLS_PK_NONE; - } -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->key_exchange) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return PSA_ALG_RSA_PKCS1V15_CRYPT; - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - return PSA_ALG_RSA_PKCS1V15_SIGN( - mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac)); - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac)); - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return PSA_ALG_ECDH; - - default: - return PSA_ALG_NONE; - } -} - -psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->key_exchange) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return PSA_KEY_USAGE_DECRYPT; - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return PSA_KEY_USAGE_SIGN_HASH; - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return PSA_KEY_USAGE_DERIVE; - - default: - return 0; - } -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->key_exchange) { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - return MBEDTLS_PK_RSA; - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return MBEDTLS_PK_ECDSA; - - default: - return MBEDTLS_PK_NONE; - } -} - -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->key_exchange) { - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || - * MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || - * MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->key_exchange) { - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ - -#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/vendor/mbedtls/library/ssl_ciphersuites_internal.h b/vendor/mbedtls/library/ssl_ciphersuites_internal.h deleted file mode 100644 index 27ff72106..000000000 --- a/vendor/mbedtls/library/ssl_ciphersuites_internal.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * \file ssl_ciphersuites_internal.h - * - * \brief Internal part of the public "ssl_ciphersuites.h". - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H -#define MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H - -#include "mbedtls/pk.h" - -#if defined(MBEDTLS_PK_C) -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info); -#if defined(MBEDTLS_USE_PSA_CRYPTO) -psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info); -psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info); -#endif /* MBEDTLS_PK_C */ - -int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info); -int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info); - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED) -static inline int mbedtls_ssl_ciphersuite_has_pfs(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) -static inline int mbedtls_ssl_ciphersuite_no_pfs(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdh(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */ - -static inline int mbedtls_ssl_ciphersuite_cert_req_allowed(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return 1; - - default: - return 0; - } -} - -static inline int mbedtls_ssl_ciphersuite_uses_srv_cert(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return 1; - - default: - return 0; - } -} - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_dhe(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdhe(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_server_signature( - const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ - -#endif /* MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H */ diff --git a/vendor/mbedtls/library/ssl_client.c b/vendor/mbedtls/library/ssl_client.c deleted file mode 100644 index 0bd00cd91..000000000 --- a/vendor/mbedtls/library/ssl_client.c +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * TLS 1.2 and 1.3 client-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_CLI_C) -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - -#include - -#include "debug_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/platform.h" - -#include "ssl_client.h" -#include "ssl_misc.h" -#include "ssl_tls13_keys.h" -#include "ssl_debug_helpers.h" - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - const char *hostname = mbedtls_ssl_get_hostname_pointer(ssl); - size_t hostname_len; - - *olen = 0; - - if (hostname == NULL) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding server name extension: %s", - hostname)); - - hostname_len = strlen(hostname); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, hostname_len + 9); - - /* - * Sect. 3, RFC 6066 (TLS Extensions Definitions) - * - * In order to provide any of the server names, clients MAY include an - * extension of type "server_name" in the (extended) client hello. The - * "extension_data" field of this extension SHALL contain - * "ServerNameList" where: - * - * struct { - * NameType name_type; - * select (name_type) { - * case host_name: HostName; - * } name; - * } ServerName; - * - * enum { - * host_name(0), (255) - * } NameType; - * - * opaque HostName<1..2^16-1>; - * - * struct { - * ServerName server_name_list<1..2^16-1> - * } ServerNameList; - * - */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SERVERNAME, p, 0); - p += 2; - - MBEDTLS_PUT_UINT16_BE(hostname_len + 5, p, 0); - p += 2; - - MBEDTLS_PUT_UINT16_BE(hostname_len + 3, p, 0); - p += 2; - - *p++ = MBEDTLS_BYTE_0(MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME); - - MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0); - p += 2; - - memcpy(p, hostname, hostname_len); - - *olen = hostname_len + 9; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_SERVERNAME); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - return 0; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_ALPN) -/* - * ssl_write_alpn_ext() - * - * Structure of the application_layer_protocol_negotiation extension in - * ClientHello: - * - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - * - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_alpn_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - - *out_len = 0; - - if (ssl->conf->alpn_list == NULL) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding alpn extension")); - - - /* Check we have enough space for the extension type (2 bytes), the - * extension length (2 bytes) and the protocol_name_list length (2 bytes). - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ALPN, p, 0); - /* Skip writing extension and list length for now */ - p += 6; - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - */ - for (const char **cur = ssl->conf->alpn_list; *cur != NULL; cur++) { - /* - * mbedtls_ssl_conf_set_alpn_protocols() checked that the length of - * protocol names is less than 255. - */ - size_t protocol_name_len = strlen(*cur); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 1 + protocol_name_len); - *p++ = (unsigned char) protocol_name_len; - memcpy(p, *cur, protocol_name_len); - p += protocol_name_len; - } - - *out_len = (size_t) (p - buf); - - /* List length = *out_len - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ - MBEDTLS_PUT_UINT16_BE(*out_len - 6, buf, 4); - - /* Extension length = *out_len - 2 (ext_type) - 2 (ext_len) */ - MBEDTLS_PUT_UINT16_BE(*out_len - 4, buf, 2); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_ALPN); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - return 0; -} -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) -/* - * Function for writing a supported groups (TLS 1.3) or supported elliptic - * curves (TLS 1.2) extension. - * - * The "extension_data" field of a supported groups extension contains a - * "NamedGroupList" value (TLS 1.3 RFC8446): - * enum { - * secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019), - * x25519(0x001D), x448(0x001E), - * ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102), - * ffdhe6144(0x0103), ffdhe8192(0x0104), - * ffdhe_private_use(0x01FC..0x01FF), - * ecdhe_private_use(0xFE00..0xFEFF), - * (0xFFFF) - * } NamedGroup; - * struct { - * NamedGroup named_group_list<2..2^16-1>; - * } NamedGroupList; - * - * The "extension_data" field of a supported elliptic curves extension contains - * a "NamedCurveList" value (TLS 1.2 RFC 8422): - * enum { - * deprecated(1..22), - * secp256r1 (23), secp384r1 (24), secp521r1 (25), - * x25519(29), x448(30), - * reserved (0xFE00..0xFEFF), - * deprecated(0xFF01..0xFF02), - * (0xFFFF) - * } NamedCurve; - * struct { - * NamedCurve named_curve_list<2..2^16-1> - * } NamedCurveList; - * - * The TLS 1.3 supported groups extension was defined to be a compatible - * generalization of the TLS 1.2 supported elliptic curves extension. They both - * share the same extension identifier. - * - */ -#define SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_2_FLAG 1 -#define SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG 2 - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_supported_groups_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - int flags, - size_t *out_len) -{ - unsigned char *p = buf; - unsigned char *named_group_list; /* Start of named_group_list */ - size_t named_group_list_len; /* Length of named_group_list */ - const uint16_t *group_list = mbedtls_ssl_get_groups(ssl); - - *out_len = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding supported_groups extension")); - - /* Check if we have space for header and length fields: - * - extension_type (2 bytes) - * - extension_data_length (2 bytes) - * - named_group_list_length (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - p += 6; - - named_group_list = p; - - if (group_list == NULL) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - - for (; *group_list != 0; group_list++) { - int propose_group = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, ("got supported group(%04x)", *group_list)); - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - if (flags & SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG) { -#if defined(PSA_WANT_ALG_ECDH) - if (mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list) && - (mbedtls_ssl_get_ecp_group_id_from_tls_id(*group_list) != - MBEDTLS_ECP_DP_NONE)) { - propose_group = 1; - } -#endif -#if defined(PSA_WANT_ALG_FFDH) - if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) { - propose_group = 1; - } -#endif - } -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC) - if ((flags & SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_2_FLAG) && - mbedtls_ssl_tls12_named_group_is_ecdhe(*group_list) && - (mbedtls_ssl_get_ecp_group_id_from_tls_id(*group_list) != - MBEDTLS_ECP_DP_NONE)) { - propose_group = 1; - } -#endif /* MBEDTLS_SSL_TLS1_2_SOME_ECC */ - - if (propose_group) { - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - MBEDTLS_PUT_UINT16_BE(*group_list, p, 0); - p += 2; - MBEDTLS_SSL_DEBUG_MSG(3, ("NamedGroup: %s ( %x )", - mbedtls_ssl_named_group_to_str(*group_list), - *group_list)); - } - } - - /* Length of named_group_list */ - named_group_list_len = (size_t) (p - named_group_list); - if (named_group_list_len == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("No group available.")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Write extension_type */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_GROUPS, buf, 0); - /* Write extension_data_length */ - MBEDTLS_PUT_UINT16_BE(named_group_list_len + 2, buf, 2); - /* Write length of named_group_list */ - MBEDTLS_PUT_UINT16_BE(named_group_list_len, buf, 4); - - MBEDTLS_SSL_DEBUG_BUF(3, "Supported groups extension", - buf + 4, named_group_list_len + 2); - - *out_len = (size_t) (p - buf); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_tls13_set_hs_sent_ext_mask( - ssl, MBEDTLS_TLS_EXT_SUPPORTED_GROUPS); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - return 0; -} -#endif /* MBEDTLS_SSL_TLS1_2_SOME_ECC || - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_client_hello_cipher_suites( - mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - int *tls12_uses_ec, - size_t *out_len) -{ - unsigned char *p = buf; - const int *ciphersuite_list; - unsigned char *cipher_suites; /* Start of the cipher_suites list */ - size_t cipher_suites_len; - - *tls12_uses_ec = 0; - *out_len = 0; - - /* - * Ciphersuite list - * - * This is a list of the symmetric cipher options supported by - * the client, specifically the record protection algorithm - * ( including secret key length ) and a hash to be used with - * HKDF, in descending order of client preference. - */ - ciphersuite_list = ssl->conf->ciphersuite_list; - - /* Check there is space for the cipher suite list length (2 bytes). */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - p += 2; - - /* Write cipher_suites - * CipherSuite cipher_suites<2..2^16-2>; - */ - cipher_suites = p; - for (size_t i = 0; ciphersuite_list[i] != 0; i++) { - int cipher_suite = ciphersuite_list[i]; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(cipher_suite); - - if (mbedtls_ssl_validate_ciphersuite(ssl, ciphersuite_info, - ssl->handshake->min_tls_version, - ssl->tls_version) != 0) { - continue; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - (defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)) - *tls12_uses_ec |= mbedtls_ssl_ciphersuite_uses_ec(ciphersuite_info); -#endif - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, add ciphersuite: %04x, %s", - (unsigned int) cipher_suite, - ciphersuite_info->name)); - - /* Check there is space for the cipher suite identifier (2 bytes). */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - MBEDTLS_PUT_UINT16_BE(cipher_suite, p, 0); - p += 2; - } - - /* - * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ - int renegotiating = 0; -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE); -#endif - if (!renegotiating) { - MBEDTLS_SSL_DEBUG_MSG(3, ("adding EMPTY_RENEGOTIATION_INFO_SCSV")); - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - MBEDTLS_PUT_UINT16_BE(MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO, p, 0); - p += 2; - } - - /* Write the cipher_suites length in number of bytes */ - cipher_suites_len = (size_t) (p - cipher_suites); - MBEDTLS_PUT_UINT16_BE(cipher_suites_len, buf, 0); - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, got %" MBEDTLS_PRINTF_SIZET " cipher suites", - cipher_suites_len/2)); - - /* Output the total length of cipher_suites field. */ - *out_len = (size_t) (p - buf); - - return 0; -} - -/* - * Structure of the TLS 1.3 ClientHello message: - * - * struct { - * ProtocolVersion legacy_version = 0x0303; // TLS v1.2 - * Random random; - * opaque legacy_session_id<0..32>; - * CipherSuite cipher_suites<2..2^16-2>; - * opaque legacy_compression_methods<1..2^8-1>; - * Extension extensions<8..2^16-1>; - * } ClientHello; - * - * Structure of the (D)TLS 1.2 ClientHello message: - * - * struct { - * ProtocolVersion client_version; - * Random random; - * SessionID session_id; - * opaque cookie<0..2^8-1>; // DTLS 1.2 ONLY - * CipherSuite cipher_suites<2..2^16-2>; - * CompressionMethod compression_methods<1..2^8-1>; - * select (extensions_present) { - * case false: - * struct {}; - * case true: - * Extension extensions<0..2^16-1>; - * }; - * } ClientHello; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_client_hello_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len, - size_t *binders_len) -{ - int ret; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - unsigned char *p = buf; - unsigned char *p_extensions_len; /* Pointer to extensions length */ - size_t output_len; /* Length of buffer used by function */ - size_t extensions_len; /* Length of the list of extensions*/ - int tls12_uses_ec = 0; - - *out_len = 0; - *binders_len = 0; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - unsigned char propose_tls12 = - (handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) - && - (MBEDTLS_SSL_VERSION_TLS1_2 <= ssl->tls_version); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - unsigned char propose_tls13 = - (handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_3) - && - (MBEDTLS_SSL_VERSION_TLS1_3 <= ssl->tls_version); -#endif - - /* - * Write client_version (TLS 1.2) or legacy_version (TLS 1.3) - * - * In all cases this is the TLS 1.2 version. - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - mbedtls_ssl_write_version(p, ssl->conf->transport, - MBEDTLS_SSL_VERSION_TLS1_2); - p += 2; - - /* ... - * Random random; - * ... - * - * The random bytes have been prepared by ssl_prepare_client_hello() into - * the handshake->randbytes buffer and are copied here into the output - * buffer. - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); - memcpy(p, handshake->randbytes, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", - p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); - p += MBEDTLS_CLIENT_HELLO_RANDOM_LEN; - - /* TLS 1.2: - * ... - * SessionID session_id; - * ... - * with - * opaque SessionID<0..32>; - * - * TLS 1.3: - * ... - * opaque legacy_session_id<0..32>; - * ... - * - * The (legacy) session identifier bytes have been prepared by - * ssl_prepare_client_hello() into the ssl->session_negotiate->id buffer - * and are copied here into the output buffer. - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, ssl->session_negotiate->id_len + 1); - *p++ = (unsigned char) ssl->session_negotiate->id_len; - memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len); - p += ssl->session_negotiate->id_len; - - MBEDTLS_SSL_DEBUG_BUF(3, "session id", ssl->session_negotiate->id, - ssl->session_negotiate->id_len); - - /* DTLS 1.2 ONLY - * ... - * opaque cookie<0..2^8-1>; - * ... - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { -#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) - uint8_t cookie_len = 0; -#else - uint16_t cookie_len = 0; -#endif /* !MBEDTLS_SSL_PROTO_TLS1_3 */ - - if (handshake->cookie != NULL) { - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie", - handshake->cookie, - handshake->cookie_len); - cookie_len = handshake->cookie_len; - } - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, cookie_len + 1); - *p++ = (unsigned char) cookie_len; - if (cookie_len > 0) { - memcpy(p, handshake->cookie, cookie_len); - p += cookie_len; - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_DTLS */ - - /* Write cipher_suites */ - ret = ssl_write_client_hello_cipher_suites(ssl, p, end, - &tls12_uses_ec, - &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - - /* Write legacy_compression_methods (TLS 1.3) or - * compression_methods (TLS 1.2) - * - * For every TLS 1.3 ClientHello, this vector MUST contain exactly - * one byte set to zero, which corresponds to the 'null' compression - * method in prior versions of TLS. - * - * For TLS 1.2 ClientHello, for security reasons we do not support - * compression anymore, thus also just the 'null' compression method. - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - *p++ = 1; - *p++ = MBEDTLS_SSL_COMPRESS_NULL; - - /* Write extensions */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - /* Keeping track of the included extensions */ - handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE; -#endif - - /* First write extensions, then the total length */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - p_extensions_len = p; - p += 2; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - /* Write server name extension */ - ret = ssl_write_hostname_ext(ssl, p, end, &output_len); - if (ret != 0) { - return ret; - } - p += output_len; -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_ALPN) - ret = ssl_write_alpn_ext(ssl, p, end, &output_len); - if (ret != 0) { - return ret; - } - p += output_len; -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (propose_tls13) { - ret = mbedtls_ssl_tls13_write_client_hello_exts(ssl, p, end, - &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } -#endif - -#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC) || \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - { - int ssl_write_supported_groups_ext_flags = 0; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - if (propose_tls13 && mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) { - ssl_write_supported_groups_ext_flags |= - SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG; - } -#endif -#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC) - if (propose_tls12 && tls12_uses_ec) { - ssl_write_supported_groups_ext_flags |= - SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_2_FLAG; - } -#endif - if (ssl_write_supported_groups_ext_flags != 0) { - ret = ssl_write_supported_groups_ext(ssl, p, end, - ssl_write_supported_groups_ext_flags, - &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } - } -#endif /* MBEDTLS_SSL_TLS1_2_SOME_ECC || - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - int write_sig_alg_ext = 0; -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - write_sig_alg_ext = write_sig_alg_ext || - (propose_tls13 && mbedtls_ssl_conf_tls13_is_ephemeral_enabled(ssl)); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - write_sig_alg_ext = write_sig_alg_ext || propose_tls12; -#endif - - if (write_sig_alg_ext) { - ret = mbedtls_ssl_write_sig_alg_ext(ssl, p, end, &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (propose_tls12) { - ret = mbedtls_ssl_tls12_write_client_hello_exts(ssl, p, end, - tls12_uses_ec, - &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - /* The "pre_shared_key" extension (RFC 8446 Section 4.2.11) - * MUST be the last extension in the ClientHello. - */ - if (propose_tls13 && mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl)) { - ret = mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext( - ssl, p, end, &output_len, binders_len); - if (ret != 0) { - return ret; - } - p += output_len; - } -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - - /* Write the length of the list of extensions. */ - extensions_len = (size_t) (p - p_extensions_len) - 2; - - if (extensions_len == 0) { - p = p_extensions_len; - } else { - MBEDTLS_PUT_UINT16_BE(extensions_len, p_extensions_len, 0); - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, total extension length: %" \ - MBEDTLS_PRINTF_SIZET, extensions_len)); - MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", - p_extensions_len, extensions_len); - } - - *out_len = (size_t) (p - buf); - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_generate_random(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *randbytes = ssl->handshake->randbytes; - size_t gmt_unix_time_len = 0; - - /* - * Generate the random bytes - * - * TLS 1.2 case: - * struct { - * uint32 gmt_unix_time; - * opaque random_bytes[28]; - * } Random; - * - * TLS 1.3 case: - * opaque Random[32]; - */ - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t gmt_unix_time = mbedtls_time(NULL); - MBEDTLS_PUT_UINT32_BE(gmt_unix_time, randbytes, 0); - gmt_unix_time_len = 4; - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, current time: %" MBEDTLS_PRINTF_LONGLONG, - (long long) gmt_unix_time)); -#endif /* MBEDTLS_HAVE_TIME */ - } - - ret = ssl->conf->f_rng(ssl->conf->p_rng, - randbytes + gmt_unix_time_len, - MBEDTLS_CLIENT_HELLO_RANDOM_LEN - gmt_unix_time_len); - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl) -{ - int ret; - size_t session_id_len; - mbedtls_ssl_session *session_negotiate = ssl->session_negotiate; - - if (session_negotiate == NULL) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_HAVE_TIME) - - /* Check if a tls13 ticket has been configured. */ - if (ssl->handshake->resume != 0 && - session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 && - session_negotiate->ticket != NULL) { - mbedtls_ms_time_t now = mbedtls_ms_time(); - mbedtls_ms_time_t age = now - session_negotiate->ticket_reception_time; - if (age < 0 || - age > (mbedtls_ms_time_t) session_negotiate->ticket_lifetime * 1000) { - /* Without valid ticket, disable session resumption.*/ - MBEDTLS_SSL_DEBUG_MSG( - 3, ("Ticket expired, disable session resumption")); - ssl->handshake->resume = 0; - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && - MBEDTLS_SSL_SESSION_TICKETS && - MBEDTLS_HAVE_TIME */ - - /* Bet on the highest configured version if we are not in a TLS 1.2 - * renegotiation or session resumption. - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - ssl->handshake->min_tls_version = ssl->tls_version; - } else -#endif - { - if (ssl->handshake->resume) { - ssl->tls_version = session_negotiate->tls_version; - ssl->handshake->min_tls_version = ssl->tls_version; - } else { - ssl->handshake->min_tls_version = ssl->conf->min_tls_version; - } - } - - /* - * Generate the random bytes, except when responding to a verify request - * where we MUST reuse the previously generated random bytes - * (RFC 6347 4.2.1). - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (ssl->handshake->cookie == NULL)) -#endif - { -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (!ssl->handshake->hello_retry_request_flag) -#endif - { - ret = ssl_generate_random(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "Random bytes generation failed", ret); - return ret; - } - } - } - - /* - * Prepare session identifier. At that point, the length of the session - * identifier in the SSL context `ssl->session_negotiate->id_len` is equal - * to zero, except in the case of a TLS 1.2 session renegotiation or - * session resumption. - */ - session_id_len = session_negotiate->id_len; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { - if (session_id_len < 16 || session_id_len > 32 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif - ssl->handshake->resume == 0) { - session_id_len = 0; - } - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - /* - * RFC 5077 section 3.4: "When presenting a ticket, the client MAY - * generate and include a Session ID in the TLS ClientHello." - */ - int renegotiating = 0; -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - renegotiating = 1; - } -#endif - if (!renegotiating) { - if ((session_negotiate->ticket != NULL) && - (session_negotiate->ticket_len != 0)) { - session_id_len = 32; - } - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - /* - * Create a legacy session identifier for the purpose of middlebox - * compatibility only if one has not been created already, which is - * the case if we are here for the TLS 1.3 second ClientHello. - * - * Versions of TLS before TLS 1.3 supported a "session resumption" - * feature which has been merged with pre-shared keys in TLS 1.3 - * version. A client which has a cached session ID set by a pre-TLS 1.3 - * server SHOULD set this field to that value. In compatibility mode, - * this field MUST be non-empty, so a client not offering a pre-TLS 1.3 - * session MUST generate a new 32-byte value. This value need not be - * random but SHOULD be unpredictable to avoid implementations fixating - * on a specific value (also known as ossification). Otherwise, it MUST - * be set as a zero-length vector ( i.e., a zero-valued single byte - * length field ). - */ - session_id_len = 32; - } -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - - if (session_id_len != session_negotiate->id_len) { - session_negotiate->id_len = session_id_len; - if (session_id_len > 0) { - ret = ssl->conf->f_rng(ssl->conf->p_rng, - session_negotiate->id, - session_id_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "creating session id failed", ret); - return ret; - } - } - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - const char *context_hostname = mbedtls_ssl_get_hostname_pointer(ssl); - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 && - ssl->handshake->resume) { - int hostname_mismatch = context_hostname != NULL || - session_negotiate->hostname != NULL; - if (context_hostname != NULL && session_negotiate->hostname != NULL) { - hostname_mismatch = strcmp( - context_hostname, session_negotiate->hostname) != 0; - } - - if (hostname_mismatch) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Hostname mismatch the session ticket, " - "disable session resumption.")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - } else { - return mbedtls_ssl_session_set_hostname(session_negotiate, - context_hostname); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && - MBEDTLS_SSL_SESSION_TICKETS && - MBEDTLS_SSL_SERVER_NAME_INDICATION */ - - return 0; -} -/* - * Write ClientHello handshake message. - * Handler for MBEDTLS_SSL_CLIENT_HELLO - */ -int mbedtls_ssl_write_client_hello(mbedtls_ssl_context *ssl) -{ - int ret = 0; - unsigned char *buf; - size_t buf_len, msg_len, binders_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write client hello")); - - MBEDTLS_SSL_PROC_CHK(ssl_prepare_client_hello(ssl)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_write_client_hello_body(ssl, buf, - buf + buf_len, - &msg_len, - &binders_len)); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ssl->out_msglen = msg_len + 4; - mbedtls_ssl_send_flight_completed(ssl); - - /* - * The two functions below may try to send data on the network and - * can return with the MBEDTLS_ERR_SSL_WANT_READ error code when they - * fail to do so and the transmission has to be retried later. In that - * case as in fatal error cases, we return immediately. But we must have - * set the handshake state to the next state at that point to ensure - * that we will not write and send again a ClientHello when we - * eventually succeed in sending the pending data. - */ - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO); - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret); - return ret; - } - } else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_DTLS */ - { - - ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl, - MBEDTLS_SSL_HS_CLIENT_HELLO, - msg_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_add_hs_hdr_to_checksum", ret); - return ret; - } - ret = ssl->handshake->update_checksum(ssl, buf, msg_len - binders_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); - return ret; - } -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - if (binders_len > 0) { - MBEDTLS_SSL_PROC_CHK( - mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext( - ssl, buf + msg_len - binders_len, buf + msg_len)); - ret = ssl->handshake->update_checksum(ssl, buf + msg_len - binders_len, - binders_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); - return ret; - } - } -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl, - buf_len, - msg_len)); - - /* - * Set next state. Note that if TLS 1.3 is proposed, this may be - * overwritten by mbedtls_ssl_tls13_finalize_client_hello(). - */ - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_3 && - MBEDTLS_SSL_VERSION_TLS1_3 <= ssl->tls_version) { - ret = mbedtls_ssl_tls13_finalize_client_hello(ssl); - } -#endif - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - MBEDTLS_SSL_PRINT_EXTS( - 3, MBEDTLS_SSL_HS_CLIENT_HELLO, ssl->handshake->sent_extensions); -#endif - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client hello")); - return ret; -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 || MBEDTLS_SSL_PROTO_TLS1_2 */ -#endif /* MBEDTLS_SSL_CLI_C */ diff --git a/vendor/mbedtls/library/ssl_client.h b/vendor/mbedtls/library/ssl_client.h deleted file mode 100644 index 05ee7e4cc..000000000 --- a/vendor/mbedtls/library/ssl_client.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * TLS 1.2 and 1.3 client-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_SSL_CLIENT_H -#define MBEDTLS_SSL_CLIENT_H - -#include "common.h" - -#if defined(MBEDTLS_SSL_TLS_C) -#include "ssl_misc.h" -#endif - -#include - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_client_hello(mbedtls_ssl_context *ssl); - -#endif /* MBEDTLS_SSL_CLIENT_H */ diff --git a/vendor/mbedtls/library/ssl_cookie.c b/vendor/mbedtls/library/ssl_cookie.c deleted file mode 100644 index acc9e8c08..000000000 --- a/vendor/mbedtls/library/ssl_cookie.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * DTLS cookie callbacks implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * These session callbacks use a simple chained list - * to store and retrieve the session information. - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_COOKIE_C) - -#include "mbedtls/platform.h" - -#include "mbedtls/ssl_cookie.h" -#include "ssl_misc.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/constant_time.h" - -#include - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) -#endif - -/* - * If DTLS is in use, then at least one of SHA-256 or SHA-384 is - * available. Try SHA-256 first as 384 wastes resources - */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#define COOKIE_MD MBEDTLS_MD_SHA256 -#define COOKIE_MD_OUTLEN 32 -#define COOKIE_HMAC_LEN 28 -#elif defined(MBEDTLS_MD_CAN_SHA384) -#define COOKIE_MD MBEDTLS_MD_SHA384 -#define COOKIE_MD_OUTLEN 48 -#define COOKIE_HMAC_LEN 28 -#else -#error "DTLS hello verify needs SHA-256 or SHA-384" -#endif - -/* - * Cookies are formed of a 4-bytes timestamp (or serial number) and - * an HMAC of timestamp and client ID. - */ -#define COOKIE_LEN (4 + COOKIE_HMAC_LEN) - -void mbedtls_ssl_cookie_init(mbedtls_ssl_cookie_ctx *ctx) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ctx->psa_hmac_key = MBEDTLS_SVC_KEY_ID_INIT; -#else - mbedtls_md_init(&ctx->hmac_ctx); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if !defined(MBEDTLS_HAVE_TIME) - ctx->serial = 0; -#endif - ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT; - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&ctx->mutex); -#endif -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ -} - -void mbedtls_ssl_cookie_set_timeout(mbedtls_ssl_cookie_ctx *ctx, unsigned long delay) -{ - ctx->timeout = delay; -} - -void mbedtls_ssl_cookie_free(mbedtls_ssl_cookie_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_destroy_key(ctx->psa_hmac_key); -#else - mbedtls_md_free(&ctx->hmac_ctx); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free(&ctx->mutex); -#endif -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_cookie_ctx)); -} - -int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_algorithm_t alg; - - (void) f_rng; - (void) p_rng; - - alg = mbedtls_md_psa_alg_from_type(COOKIE_MD); - if (alg == 0) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ctx->psa_hmac_alg = PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(alg), - COOKIE_HMAC_LEN); - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE | - PSA_KEY_USAGE_SIGN_MESSAGE); - psa_set_key_algorithm(&attributes, ctx->psa_hmac_alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); - psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(COOKIE_MD_OUTLEN)); - - if ((status = psa_generate_key(&attributes, - &ctx->psa_hmac_key)) != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char key[COOKIE_MD_OUTLEN]; - - if ((ret = f_rng(p_rng, key, sizeof(key))) != 0) { - return ret; - } - - ret = mbedtls_md_setup(&ctx->hmac_ctx, mbedtls_md_info_from_type(COOKIE_MD), 1); - if (ret != 0) { - return ret; - } - - ret = mbedtls_md_hmac_starts(&ctx->hmac_ctx, key, sizeof(key)); - if (ret != 0) { - return ret; - } - - mbedtls_platform_zeroize(key, sizeof(key)); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - return 0; -} - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) -/* - * Generate the HMAC part of a cookie - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_cookie_hmac(mbedtls_md_context_t *hmac_ctx, - const unsigned char time[4], - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len) -{ - unsigned char hmac_out[COOKIE_MD_OUTLEN]; - - MBEDTLS_SSL_CHK_BUF_PTR(*p, end, COOKIE_HMAC_LEN); - - if (mbedtls_md_hmac_reset(hmac_ctx) != 0 || - mbedtls_md_hmac_update(hmac_ctx, time, 4) != 0 || - mbedtls_md_hmac_update(hmac_ctx, cli_id, cli_id_len) != 0 || - mbedtls_md_hmac_finish(hmac_ctx, hmac_out) != 0) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - memcpy(*p, hmac_out, COOKIE_HMAC_LEN); - *p += COOKIE_HMAC_LEN; - - return 0; -} -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ - -/* - * Generate cookie for DTLS ClientHello verification - */ -int mbedtls_ssl_cookie_write(void *p_ctx, - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t sign_mac_length = 0; -#endif - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; - unsigned long t; - - if (ctx == NULL || cli_id == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_SSL_CHK_BUF_PTR(*p, end, COOKIE_LEN); - -#if defined(MBEDTLS_HAVE_TIME) - t = (unsigned long) mbedtls_time(NULL); -#else - t = ctx->serial++; -#endif - - MBEDTLS_PUT_UINT32_BE(t, *p, 0); - *p += 4; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_mac_sign_setup(&operation, ctx->psa_hmac_key, - ctx->psa_hmac_alg); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - status = psa_mac_update(&operation, *p - 4, 4); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - status = psa_mac_update(&operation, cli_id, cli_id_len); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - status = psa_mac_sign_finish(&operation, *p, COOKIE_MD_OUTLEN, - &sign_mac_length); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - *p += COOKIE_HMAC_LEN; - - ret = 0; -#else -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret); - } -#endif - - ret = ssl_cookie_hmac(&ctx->hmac_ctx, *p - 4, - p, end, cli_id, cli_id_len); - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, - MBEDTLS_ERR_THREADING_MUTEX_ERROR); - } -#endif -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -exit: - status = psa_mac_abort(&operation); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - return ret; -} - -/* - * Check a cookie - */ -int mbedtls_ssl_cookie_check(void *p_ctx, - const unsigned char *cookie, size_t cookie_len, - const unsigned char *cli_id, size_t cli_id_len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#else - unsigned char ref_hmac[COOKIE_HMAC_LEN]; - unsigned char *p = ref_hmac; -#endif - int ret = 0; - mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; - unsigned long cur_time, cookie_time; - - if (ctx == NULL || cli_id == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (cookie_len != COOKIE_LEN) { - return -1; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_mac_verify_setup(&operation, ctx->psa_hmac_key, - ctx->psa_hmac_alg); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - status = psa_mac_update(&operation, cookie, 4); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - status = psa_mac_update(&operation, cli_id, - cli_id_len); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - status = psa_mac_verify_finish(&operation, cookie + 4, - COOKIE_HMAC_LEN); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - ret = 0; -#else -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret); - } -#endif - - if (ssl_cookie_hmac(&ctx->hmac_ctx, cookie, - &p, p + sizeof(ref_hmac), - cli_id, cli_id_len) != 0) { - ret = -1; - } - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, - MBEDTLS_ERR_THREADING_MUTEX_ERROR); - } -#endif - - if (ret != 0) { - goto exit; - } - - if (mbedtls_ct_memcmp(cookie + 4, ref_hmac, sizeof(ref_hmac)) != 0) { - ret = -1; - goto exit; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_HAVE_TIME) - cur_time = (unsigned long) mbedtls_time(NULL); -#else - cur_time = ctx->serial; -#endif - - cookie_time = (unsigned long) MBEDTLS_GET_UINT32_BE(cookie, 0); - - if (ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout) { - ret = -1; - goto exit; - } - -exit: -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_mac_abort(&operation); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - } -#else - mbedtls_platform_zeroize(ref_hmac, sizeof(ref_hmac)); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - return ret; -} -#endif /* MBEDTLS_SSL_COOKIE_C */ diff --git a/vendor/mbedtls/library/ssl_debug_helpers.h b/vendor/mbedtls/library/ssl_debug_helpers.h deleted file mode 100644 index 38ef76376..000000000 --- a/vendor/mbedtls/library/ssl_debug_helpers.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * \file ssl_debug_helpers.h - * - * \brief Automatically generated helper functions for debugging - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_SSL_DEBUG_HELPERS_H -#define MBEDTLS_SSL_DEBUG_HELPERS_H - -#include "common.h" - -#if defined(MBEDTLS_DEBUG_C) - -#include "mbedtls/ssl.h" -#include "ssl_misc.h" - - -const char *mbedtls_ssl_states_str(mbedtls_ssl_states in); - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) -const char *mbedtls_ssl_early_data_status_str(mbedtls_ssl_early_data_status in); -const char *mbedtls_ssl_early_data_state_str(mbedtls_ssl_early_data_state in); -#endif - -const char *mbedtls_ssl_protocol_version_str(mbedtls_ssl_protocol_version in); - -const char *mbedtls_tls_prf_types_str(mbedtls_tls_prf_types in); - -const char *mbedtls_ssl_key_export_type_str(mbedtls_ssl_key_export_type in); - -const char *mbedtls_ssl_sig_alg_to_str(uint16_t in); - -const char *mbedtls_ssl_named_group_to_str(uint16_t in); - -const char *mbedtls_ssl_get_extension_name(unsigned int extension_type); - -const char *mbedtls_ssl_get_hs_msg_name(int hs_msg_type); - -void mbedtls_ssl_print_extensions(const mbedtls_ssl_context *ssl, - int level, const char *file, int line, - int hs_msg_type, uint32_t extensions_mask, - const char *extra); - -void mbedtls_ssl_print_extension(const mbedtls_ssl_context *ssl, - int level, const char *file, int line, - int hs_msg_type, unsigned int extension_type, - const char *extra_msg0, const char *extra_msg1); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl, - int level, const char *file, int line, - unsigned int flags); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ - -#define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask) \ - mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__, \ - hs_msg_type, extensions_mask, NULL) - -#define MBEDTLS_SSL_PRINT_EXT(level, hs_msg_type, extension_type, extra) \ - mbedtls_ssl_print_extension(ssl, level, __FILE__, __LINE__, \ - hs_msg_type, extension_type, \ - extra, NULL) - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags) \ - mbedtls_ssl_print_ticket_flags(ssl, level, __FILE__, __LINE__, flags) -#endif - -#else - -#define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extension_mask) - -#define MBEDTLS_SSL_PRINT_EXT(level, hs_msg_type, extension_type, extra) - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags) -#endif - -#endif /* MBEDTLS_DEBUG_C */ - -#endif /* MBEDTLS_SSL_DEBUG_HELPERS_H */ diff --git a/vendor/mbedtls/library/ssl_debug_helpers_generated.c b/vendor/mbedtls/library/ssl_debug_helpers_generated.c deleted file mode 100644 index 808fce737..000000000 --- a/vendor/mbedtls/library/ssl_debug_helpers_generated.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Automatically generated by generate_ssl_debug_helpers.py. DO NOT EDIT. */ - -/** - * \file ssl_debug_helpers_generated.c - * - * \brief Automatically generated helper functions for debugging - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - */ - -#include "ssl_misc.h" - -#if defined(MBEDTLS_DEBUG_C) - -#include "ssl_debug_helpers.h" - - -const char *mbedtls_ssl_named_group_to_str( uint16_t in ) -{ - switch( in ) - { - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP192K1: - return "secp192k1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP192R1: - return "secp192r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP224K1: - return "secp224k1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP224R1: - return "secp224r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP256K1: - return "secp256k1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1: - return "secp256r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1: - return "secp384r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1: - return "secp521r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1: - return "bp256r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1: - return "bp384r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1: - return "bp512r1"; - case MBEDTLS_SSL_IANA_TLS_GROUP_X25519: - return "x25519"; - case MBEDTLS_SSL_IANA_TLS_GROUP_X448: - return "x448"; - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048: - return "ffdhe2048"; - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE3072: - return "ffdhe3072"; - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE4096: - return "ffdhe4096"; - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE6144: - return "ffdhe6144"; - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192: - return "ffdhe8192"; - }; - - return "UNKNOWN"; -} -const char *mbedtls_ssl_sig_alg_to_str( uint16_t in ) -{ - switch( in ) - { - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256: - return "rsa_pkcs1_sha256"; - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384: - return "rsa_pkcs1_sha384"; - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512: - return "rsa_pkcs1_sha512"; - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256: - return "ecdsa_secp256r1_sha256"; - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384: - return "ecdsa_secp384r1_sha384"; - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512: - return "ecdsa_secp521r1_sha512"; - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: - return "rsa_pss_rsae_sha256"; - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: - return "rsa_pss_rsae_sha384"; - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: - return "rsa_pss_rsae_sha512"; - case MBEDTLS_TLS1_3_SIG_ED25519: - return "ed25519"; - case MBEDTLS_TLS1_3_SIG_ED448: - return "ed448"; - case MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA256: - return "rsa_pss_pss_sha256"; - case MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA384: - return "rsa_pss_pss_sha384"; - case MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA512: - return "rsa_pss_pss_sha512"; - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA1: - return "rsa_pkcs1_sha1"; - case MBEDTLS_TLS1_3_SIG_ECDSA_SHA1: - return "ecdsa_sha1"; - case MBEDTLS_TLS1_3_SIG_NONE: - return "none"; - }; - - return "UNKNOWN"; -} -const char *mbedtls_ssl_states_str( mbedtls_ssl_states in ) -{ - switch (in) { - case MBEDTLS_SSL_HELLO_REQUEST: - return "MBEDTLS_SSL_HELLO_REQUEST"; - case MBEDTLS_SSL_CLIENT_HELLO: - return "MBEDTLS_SSL_CLIENT_HELLO"; - case MBEDTLS_SSL_SERVER_HELLO: - return "MBEDTLS_SSL_SERVER_HELLO"; - case MBEDTLS_SSL_SERVER_CERTIFICATE: - return "MBEDTLS_SSL_SERVER_CERTIFICATE"; - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - return "MBEDTLS_SSL_SERVER_KEY_EXCHANGE"; - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - return "MBEDTLS_SSL_CERTIFICATE_REQUEST"; - case MBEDTLS_SSL_SERVER_HELLO_DONE: - return "MBEDTLS_SSL_SERVER_HELLO_DONE"; - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - return "MBEDTLS_SSL_CLIENT_CERTIFICATE"; - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - return "MBEDTLS_SSL_CLIENT_KEY_EXCHANGE"; - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - return "MBEDTLS_SSL_CERTIFICATE_VERIFY"; - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - return "MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC"; - case MBEDTLS_SSL_CLIENT_FINISHED: - return "MBEDTLS_SSL_CLIENT_FINISHED"; - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: - return "MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC"; - case MBEDTLS_SSL_SERVER_FINISHED: - return "MBEDTLS_SSL_SERVER_FINISHED"; - case MBEDTLS_SSL_FLUSH_BUFFERS: - return "MBEDTLS_SSL_FLUSH_BUFFERS"; - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - return "MBEDTLS_SSL_HANDSHAKE_WRAPUP"; - case MBEDTLS_SSL_NEW_SESSION_TICKET: - return "MBEDTLS_SSL_NEW_SESSION_TICKET"; - case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: - return "MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT"; - case MBEDTLS_SSL_HELLO_RETRY_REQUEST: - return "MBEDTLS_SSL_HELLO_RETRY_REQUEST"; - case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS: - return "MBEDTLS_SSL_ENCRYPTED_EXTENSIONS"; - case MBEDTLS_SSL_END_OF_EARLY_DATA: - return "MBEDTLS_SSL_END_OF_EARLY_DATA"; - case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY: - return "MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY"; - case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED: - return "MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED"; - case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO: - return "MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO"; - case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO: - return "MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO"; - case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO: - return "MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO"; - case MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST: - return "MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST"; - case MBEDTLS_SSL_HANDSHAKE_OVER: - return "MBEDTLS_SSL_HANDSHAKE_OVER"; - case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET: - return "MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET"; - case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH: - return "MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH"; - default: - return "UNKNOWN_VALUE"; - } -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) -const char *mbedtls_ssl_early_data_status_str( mbedtls_ssl_early_data_status in ) -{ - switch (in) { - case MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED: - return "MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED"; - case MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED: - return "MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED"; - case MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED: - return "MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED"; - default: - return "UNKNOWN_VALUE"; - } -} - -#endif /* defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) */ -const char *mbedtls_ssl_protocol_version_str( mbedtls_ssl_protocol_version in ) -{ - switch (in) { - case MBEDTLS_SSL_VERSION_UNKNOWN: - return "MBEDTLS_SSL_VERSION_UNKNOWN"; - case MBEDTLS_SSL_VERSION_TLS1_2: - return "MBEDTLS_SSL_VERSION_TLS1_2"; - case MBEDTLS_SSL_VERSION_TLS1_3: - return "MBEDTLS_SSL_VERSION_TLS1_3"; - default: - return "UNKNOWN_VALUE"; - } -} - -const char *mbedtls_tls_prf_types_str( mbedtls_tls_prf_types in ) -{ - switch (in) { - case MBEDTLS_SSL_TLS_PRF_NONE: - return "MBEDTLS_SSL_TLS_PRF_NONE"; - case MBEDTLS_SSL_TLS_PRF_SHA384: - return "MBEDTLS_SSL_TLS_PRF_SHA384"; - case MBEDTLS_SSL_TLS_PRF_SHA256: - return "MBEDTLS_SSL_TLS_PRF_SHA256"; - case MBEDTLS_SSL_HKDF_EXPAND_SHA384: - return "MBEDTLS_SSL_HKDF_EXPAND_SHA384"; - case MBEDTLS_SSL_HKDF_EXPAND_SHA256: - return "MBEDTLS_SSL_HKDF_EXPAND_SHA256"; - default: - return "UNKNOWN_VALUE"; - } -} - -const char *mbedtls_ssl_key_export_type_str( mbedtls_ssl_key_export_type in ) -{ - switch (in) { - case MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET: - return "MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET"; -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET: - return "MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET"; - case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_EARLY_EXPORTER_SECRET: - return "MBEDTLS_SSL_KEY_EXPORT_TLS1_3_EARLY_EXPORTER_SECRET"; - case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET: - return "MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET"; - case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET: - return "MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET"; - case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET: - return "MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET"; - case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET: - return "MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET"; -#endif - default: - return "UNKNOWN_VALUE"; - } -} - - - -#endif /* MBEDTLS_DEBUG_C */ -/* End of automatically generated file. */ - diff --git a/vendor/mbedtls/library/ssl_misc.h b/vendor/mbedtls/library/ssl_misc.h deleted file mode 100644 index 218a30d40..000000000 --- a/vendor/mbedtls/library/ssl_misc.h +++ /dev/null @@ -1,3105 +0,0 @@ -/** - * \file ssl_misc.h - * - * \brief Internal functions shared by the SSL modules - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_SSL_MISC_H -#define MBEDTLS_SSL_MISC_H - -#include "mbedtls/build_info.h" -#include "common.h" - -#include "mbedtls/error.h" - -#include "mbedtls/ssl.h" -#include "mbedtls/debug.h" -#include "debug_internal.h" - -#include "mbedtls/cipher.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) -#include "psa/crypto.h" -#include "psa_util_internal.h" -#endif - -#if defined(MBEDTLS_MD_CAN_MD5) -#include "mbedtls/md5.h" -#endif - -#if defined(MBEDTLS_MD_CAN_SHA1) -#include "mbedtls/sha1.h" -#endif - -#if defined(MBEDTLS_MD_CAN_SHA256) -#include "mbedtls/sha256.h" -#endif - -#if defined(MBEDTLS_MD_CAN_SHA512) -#include "mbedtls/sha512.h" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - !defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/ecjpake.h" -#endif - -#include "mbedtls/pk.h" -#include "ssl_ciphersuites_internal.h" -#include "x509_internal.h" -#include "pk_internal.h" - - -/* Shorthand for restartable ECC */ -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - defined(MBEDTLS_SSL_CLI_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED -#endif - -#define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 -#define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ -#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ -#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */ - -/* Faked handshake message identity for HelloRetryRequest. */ -#define MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST (-MBEDTLS_SSL_HS_SERVER_HELLO) - -/* - * Internal identity of handshake extensions - */ -#define MBEDTLS_SSL_EXT_ID_UNRECOGNIZED 0 -#define MBEDTLS_SSL_EXT_ID_SERVERNAME 1 -#define MBEDTLS_SSL_EXT_ID_SERVERNAME_HOSTNAME 1 -#define MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH 2 -#define MBEDTLS_SSL_EXT_ID_STATUS_REQUEST 3 -#define MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS 4 -#define MBEDTLS_SSL_EXT_ID_SUPPORTED_ELLIPTIC_CURVES 4 -#define MBEDTLS_SSL_EXT_ID_SIG_ALG 5 -#define MBEDTLS_SSL_EXT_ID_USE_SRTP 6 -#define MBEDTLS_SSL_EXT_ID_HEARTBEAT 7 -#define MBEDTLS_SSL_EXT_ID_ALPN 8 -#define MBEDTLS_SSL_EXT_ID_SCT 9 -#define MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE 10 -#define MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE 11 -#define MBEDTLS_SSL_EXT_ID_PADDING 12 -#define MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY 13 -#define MBEDTLS_SSL_EXT_ID_EARLY_DATA 14 -#define MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS 15 -#define MBEDTLS_SSL_EXT_ID_COOKIE 16 -#define MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES 17 -#define MBEDTLS_SSL_EXT_ID_CERT_AUTH 18 -#define MBEDTLS_SSL_EXT_ID_OID_FILTERS 19 -#define MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH 20 -#define MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT 21 -#define MBEDTLS_SSL_EXT_ID_KEY_SHARE 22 -#define MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC 23 -#define MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS 24 -#define MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC 25 -#define MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET 26 -#define MBEDTLS_SSL_EXT_ID_SESSION_TICKET 27 -#define MBEDTLS_SSL_EXT_ID_RECORD_SIZE_LIMIT 28 - -/* Utility for translating IANA extension type. */ -uint32_t mbedtls_ssl_get_extension_id(unsigned int extension_type); -uint32_t mbedtls_ssl_get_extension_mask(unsigned int extension_type); -/* Macros used to define mask constants */ -#define MBEDTLS_SSL_EXT_MASK(id) (1ULL << (MBEDTLS_SSL_EXT_ID_##id)) -/* Reset value of extension mask */ -#define MBEDTLS_SSL_EXT_MASK_NONE 0 - -/* In messages containing extension requests, we should ignore unrecognized - * extensions. In messages containing extension responses, unrecognized - * extensions should result in handshake abortion. Messages containing - * extension requests include ClientHello, CertificateRequest and - * NewSessionTicket. Messages containing extension responses include - * ServerHello, HelloRetryRequest, EncryptedExtensions and Certificate. - * - * RFC 8446 section 4.1.3 - * - * The ServerHello MUST only include extensions which are required to establish - * the cryptographic context and negotiate the protocol version. - * - * RFC 8446 section 4.2 - * - * If an implementation receives an extension which it recognizes and which is - * not specified for the message in which it appears, it MUST abort the handshake - * with an "illegal_parameter" alert. - */ - -/* Extensions that are not recognized by TLS 1.3 */ -#define MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED \ - (MBEDTLS_SSL_EXT_MASK(SUPPORTED_POINT_FORMATS) | \ - MBEDTLS_SSL_EXT_MASK(ENCRYPT_THEN_MAC) | \ - MBEDTLS_SSL_EXT_MASK(EXTENDED_MASTER_SECRET) | \ - MBEDTLS_SSL_EXT_MASK(SESSION_TICKET) | \ - MBEDTLS_SSL_EXT_MASK(TRUNCATED_HMAC) | \ - MBEDTLS_SSL_EXT_MASK(UNRECOGNIZED)) - -/* RFC 8446 section 4.2. Allowed extensions for ClientHello */ -#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH \ - (MBEDTLS_SSL_EXT_MASK(SERVERNAME) | \ - MBEDTLS_SSL_EXT_MASK(MAX_FRAGMENT_LENGTH) | \ - MBEDTLS_SSL_EXT_MASK(STATUS_REQUEST) | \ - MBEDTLS_SSL_EXT_MASK(SUPPORTED_GROUPS) | \ - MBEDTLS_SSL_EXT_MASK(SIG_ALG) | \ - MBEDTLS_SSL_EXT_MASK(USE_SRTP) | \ - MBEDTLS_SSL_EXT_MASK(HEARTBEAT) | \ - MBEDTLS_SSL_EXT_MASK(ALPN) | \ - MBEDTLS_SSL_EXT_MASK(SCT) | \ - MBEDTLS_SSL_EXT_MASK(CLI_CERT_TYPE) | \ - MBEDTLS_SSL_EXT_MASK(SERV_CERT_TYPE) | \ - MBEDTLS_SSL_EXT_MASK(PADDING) | \ - MBEDTLS_SSL_EXT_MASK(KEY_SHARE) | \ - MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | \ - MBEDTLS_SSL_EXT_MASK(PSK_KEY_EXCHANGE_MODES) | \ - MBEDTLS_SSL_EXT_MASK(EARLY_DATA) | \ - MBEDTLS_SSL_EXT_MASK(COOKIE) | \ - MBEDTLS_SSL_EXT_MASK(SUPPORTED_VERSIONS) | \ - MBEDTLS_SSL_EXT_MASK(CERT_AUTH) | \ - MBEDTLS_SSL_EXT_MASK(POST_HANDSHAKE_AUTH) | \ - MBEDTLS_SSL_EXT_MASK(SIG_ALG_CERT) | \ - MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT) | \ - MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED) - -/* RFC 8446 section 4.2. Allowed extensions for EncryptedExtensions */ -#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE \ - (MBEDTLS_SSL_EXT_MASK(SERVERNAME) | \ - MBEDTLS_SSL_EXT_MASK(MAX_FRAGMENT_LENGTH) | \ - MBEDTLS_SSL_EXT_MASK(SUPPORTED_GROUPS) | \ - MBEDTLS_SSL_EXT_MASK(USE_SRTP) | \ - MBEDTLS_SSL_EXT_MASK(HEARTBEAT) | \ - MBEDTLS_SSL_EXT_MASK(ALPN) | \ - MBEDTLS_SSL_EXT_MASK(CLI_CERT_TYPE) | \ - MBEDTLS_SSL_EXT_MASK(SERV_CERT_TYPE) | \ - MBEDTLS_SSL_EXT_MASK(EARLY_DATA) | \ - MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT)) - -/* RFC 8446 section 4.2. Allowed extensions for CertificateRequest */ -#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR \ - (MBEDTLS_SSL_EXT_MASK(STATUS_REQUEST) | \ - MBEDTLS_SSL_EXT_MASK(SIG_ALG) | \ - MBEDTLS_SSL_EXT_MASK(SCT) | \ - MBEDTLS_SSL_EXT_MASK(CERT_AUTH) | \ - MBEDTLS_SSL_EXT_MASK(OID_FILTERS) | \ - MBEDTLS_SSL_EXT_MASK(SIG_ALG_CERT) | \ - MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED) - -/* RFC 8446 section 4.2. Allowed extensions for Certificate */ -#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CT \ - (MBEDTLS_SSL_EXT_MASK(STATUS_REQUEST) | \ - MBEDTLS_SSL_EXT_MASK(SCT)) - -/* RFC 8446 section 4.2. Allowed extensions for ServerHello */ -#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH \ - (MBEDTLS_SSL_EXT_MASK(KEY_SHARE) | \ - MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | \ - MBEDTLS_SSL_EXT_MASK(SUPPORTED_VERSIONS)) - -/* RFC 8446 section 4.2. Allowed extensions for HelloRetryRequest */ -#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR \ - (MBEDTLS_SSL_EXT_MASK(KEY_SHARE) | \ - MBEDTLS_SSL_EXT_MASK(COOKIE) | \ - MBEDTLS_SSL_EXT_MASK(SUPPORTED_VERSIONS)) - -/* RFC 8446 section 4.2. Allowed extensions for NewSessionTicket */ -#define MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST \ - (MBEDTLS_SSL_EXT_MASK(EARLY_DATA) | \ - MBEDTLS_SSL_TLS1_3_EXT_MASK_UNRECOGNIZED) - -/* - * Helper macros for function call with return check. - */ -/* - * Exit when return non-zero value - */ -#define MBEDTLS_SSL_PROC_CHK(f) \ - do { \ - ret = (f); \ - if (ret != 0) \ - { \ - goto cleanup; \ - } \ - } while (0) -/* - * Exit when return negative value - */ -#define MBEDTLS_SSL_PROC_CHK_NEG(f) \ - do { \ - ret = (f); \ - if (ret < 0) \ - { \ - goto cleanup; \ - } \ - } while (0) - -/* - * DTLS retransmission states, see RFC 6347 4.2.4 - * - * The SENDING state is merged in PREPARING for initial sends, - * but is distinct for resends. - * - * Note: initial state is wrong for server, but is not used anyway. - */ -#define MBEDTLS_SSL_RETRANS_PREPARING 0 -#define MBEDTLS_SSL_RETRANS_SENDING 1 -#define MBEDTLS_SSL_RETRANS_WAITING 2 -#define MBEDTLS_SSL_RETRANS_FINISHED 3 - -/* - * Allow extra bytes for record, authentication and encryption overhead: - * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256). - */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - -/* This macro determines whether CBC is supported. */ -#if defined(MBEDTLS_SSL_HAVE_CBC) && \ - (defined(MBEDTLS_SSL_HAVE_AES) || \ - defined(MBEDTLS_SSL_HAVE_CAMELLIA) || \ - defined(MBEDTLS_SSL_HAVE_ARIA)) -#define MBEDTLS_SSL_SOME_SUITES_USE_CBC -#endif - -/* This macro determines whether a ciphersuite using a - * stream cipher can be used. */ -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#define MBEDTLS_SSL_SOME_SUITES_USE_STREAM -#endif - -/* This macro determines whether the CBC construct used in TLS 1.2 is supported. */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) -#define MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC -#endif - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM) || \ - defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) -#define MBEDTLS_SSL_SOME_SUITES_USE_MAC -#endif - -/* This macro determines whether a ciphersuite uses Encrypt-then-MAC with CBC */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ - defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -#define MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM -#endif - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -/* Ciphersuites using HMAC */ -#if defined(MBEDTLS_MD_CAN_SHA384) -#define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ -#elif defined(MBEDTLS_MD_CAN_SHA256) -#define MBEDTLS_SSL_MAC_ADD 32 /* SHA-256 used for HMAC */ -#else -#define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ -#endif -#else /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ -/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ -#define MBEDTLS_SSL_MAC_ADD 16 -#endif - -#if defined(MBEDTLS_SSL_HAVE_CBC) -#define MBEDTLS_SSL_PADDING_ADD 256 -#else -#define MBEDTLS_SSL_PADDING_ADD 0 -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define MBEDTLS_SSL_MAX_CID_EXPANSION MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY -#else -#define MBEDTLS_SSL_MAX_CID_EXPANSION 0 -#endif - -#define MBEDTLS_SSL_PAYLOAD_OVERHEAD (MBEDTLS_MAX_IV_LENGTH + \ - MBEDTLS_SSL_MAC_ADD + \ - MBEDTLS_SSL_PADDING_ADD + \ - MBEDTLS_SSL_MAX_CID_EXPANSION \ - ) - -#define MBEDTLS_SSL_IN_PAYLOAD_LEN (MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - (MBEDTLS_SSL_IN_CONTENT_LEN)) - -#define MBEDTLS_SSL_OUT_PAYLOAD_LEN (MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - (MBEDTLS_SSL_OUT_CONTENT_LEN)) - -/* The maximum number of buffered handshake messages. */ -#define MBEDTLS_SSL_MAX_BUFFERED_HS 4 - -/* Maximum length we can advertise as our max content length for - RFC 6066 max_fragment_length extension negotiation purposes - (the lesser of both sizes, if they are unequal.) - */ -#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ( \ - (MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN) \ - ? (MBEDTLS_SSL_OUT_CONTENT_LEN) \ - : (MBEDTLS_SSL_IN_CONTENT_LEN) \ - ) - -/* Maximum size in bytes of list in signature algorithms ext., RFC 5246/8446 */ -#define MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN 65534 - -/* Minimum size in bytes of list in signature algorithms ext., RFC 5246/8446 */ -#define MBEDTLS_SSL_MIN_SIG_ALG_LIST_LEN 2 - -/* Maximum size in bytes of list in supported elliptic curve ext., RFC 4492 */ -#define MBEDTLS_SSL_MAX_CURVE_LIST_LEN 65535 - -#define MBEDTLS_RECEIVED_SIG_ALGS_SIZE 20 - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - -#define MBEDTLS_TLS_SIG_NONE MBEDTLS_TLS1_3_SIG_NONE - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#define MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(sig, hash) ((hash << 8) | sig) -#define MBEDTLS_SSL_TLS12_SIG_ALG_FROM_SIG_AND_HASH_ALG(alg) (alg & 0xFF) -#define MBEDTLS_SSL_TLS12_HASH_ALG_FROM_SIG_AND_HASH_ALG(alg) (alg >> 8) -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -/* - * Check that we obey the standard's message size bounds - */ - -#if MBEDTLS_SSL_IN_CONTENT_LEN > 16384 -#error "Bad configuration - incoming record content too large." -#endif - -#if MBEDTLS_SSL_OUT_CONTENT_LEN > 16384 -#error "Bad configuration - outgoing record content too large." -#endif - -#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_IN_CONTENT_LEN + 2048 -#error "Bad configuration - incoming protected record payload too large." -#endif - -#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN + 2048 -#error "Bad configuration - outgoing protected record payload too large." -#endif - -/* Calculate buffer sizes */ - -/* Note: Even though the TLS record header is only 5 bytes - long, we're internally using 8 bytes to store the - implicit sequence number. */ -#define MBEDTLS_SSL_HEADER_LEN 13 - -#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define MBEDTLS_SSL_IN_BUFFER_LEN \ - ((MBEDTLS_SSL_HEADER_LEN) + (MBEDTLS_SSL_IN_PAYLOAD_LEN)) -#else -#define MBEDTLS_SSL_IN_BUFFER_LEN \ - ((MBEDTLS_SSL_HEADER_LEN) + (MBEDTLS_SSL_IN_PAYLOAD_LEN) \ - + (MBEDTLS_SSL_CID_IN_LEN_MAX)) -#endif - -#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define MBEDTLS_SSL_OUT_BUFFER_LEN \ - ((MBEDTLS_SSL_HEADER_LEN) + (MBEDTLS_SSL_OUT_PAYLOAD_LEN)) -#else -#define MBEDTLS_SSL_OUT_BUFFER_LEN \ - ((MBEDTLS_SSL_HEADER_LEN) + (MBEDTLS_SSL_OUT_PAYLOAD_LEN) \ - + (MBEDTLS_SSL_CID_OUT_LEN_MAX)) -#endif - -#define MBEDTLS_CLIENT_HELLO_RANDOM_LEN 32 -#define MBEDTLS_SERVER_HELLO_RANDOM_LEN 32 - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/** - * \brief Return the maximum fragment length (payload, in bytes) for - * the output buffer. For the client, this is the configured - * value. For the server, it is the minimum of two - the - * configured value and the negotiated one. - * - * \sa mbedtls_ssl_conf_max_frag_len() - * \sa mbedtls_ssl_get_max_out_record_payload() - * - * \param ssl SSL context - * - * \return Current maximum fragment length for the output buffer. - */ -size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl); - -/** - * \brief Return the maximum fragment length (payload, in bytes) for - * the input buffer. This is the negotiated maximum fragment - * length, or, if there is none, MBEDTLS_SSL_IN_CONTENT_LEN. - * If it is not defined either, the value is 2^14. This function - * works as its predecessor, \c mbedtls_ssl_get_max_frag_len(). - * - * \sa mbedtls_ssl_conf_max_frag_len() - * \sa mbedtls_ssl_get_max_in_record_payload() - * - * \param ssl SSL context - * - * \return Current maximum fragment length for the output buffer. - */ -size_t mbedtls_ssl_get_input_max_frag_len(const mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) -/** - * \brief Get the size limit in bytes for the protected outgoing records - * as defined in RFC 8449 - * - * \param ssl SSL context - * - * \return The size limit in bytes for the protected outgoing - * records as defined in RFC 8449. - */ -size_t mbedtls_ssl_get_output_record_size_limit(const mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) -static inline size_t mbedtls_ssl_get_output_buflen(const mbedtls_ssl_context *ctx) -{ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - return mbedtls_ssl_get_output_max_frag_len(ctx) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD - + MBEDTLS_SSL_CID_OUT_LEN_MAX; -#else - return mbedtls_ssl_get_output_max_frag_len(ctx) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD; -#endif -} - -static inline size_t mbedtls_ssl_get_input_buflen(const mbedtls_ssl_context *ctx) -{ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - return mbedtls_ssl_get_input_max_frag_len(ctx) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD - + MBEDTLS_SSL_CID_IN_LEN_MAX; -#else - return mbedtls_ssl_get_input_max_frag_len(ctx) - + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD; -#endif -} -#endif - -/* - * TLS extension flags (for extensions with outgoing ServerHello content - * that need it (e.g. for RENEGOTIATION_INFO the server already knows because - * of state of the renegotiation flag, so no indicator is required) - */ -#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) -#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) - -/** - * \brief This function checks if the remaining size in a buffer is - * greater or equal than a needed space. - * - * \param cur Pointer to the current position in the buffer. - * \param end Pointer to one past the end of the buffer. - * \param need Needed space in bytes. - * - * \return Zero if the needed space is available in the buffer, non-zero - * otherwise. - */ -#if !defined(MBEDTLS_TEST_HOOKS) -static inline int mbedtls_ssl_chk_buf_ptr(const uint8_t *cur, - const uint8_t *end, size_t need) -{ - return (cur > end) || (need > (size_t) (end - cur)); -} -#else -typedef struct { - const uint8_t *cur; - const uint8_t *end; - size_t need; -} mbedtls_ssl_chk_buf_ptr_args; - -void mbedtls_ssl_set_chk_buf_ptr_fail_args( - const uint8_t *cur, const uint8_t *end, size_t need); -void mbedtls_ssl_reset_chk_buf_ptr_fail_args(void); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_cmp_chk_buf_ptr_fail_args(mbedtls_ssl_chk_buf_ptr_args *args); - -static inline int mbedtls_ssl_chk_buf_ptr(const uint8_t *cur, - const uint8_t *end, size_t need) -{ - if ((cur > end) || (need > (size_t) (end - cur))) { - mbedtls_ssl_set_chk_buf_ptr_fail_args(cur, end, need); - return 1; - } - return 0; -} -#endif /* MBEDTLS_TEST_HOOKS */ - -/** - * \brief This macro checks if the remaining size in a buffer is - * greater or equal than a needed space. If it is not the case, - * it returns an SSL_BUFFER_TOO_SMALL error. - * - * \param cur Pointer to the current position in the buffer. - * \param end Pointer to one past the end of the buffer. - * \param need Needed space in bytes. - * - */ -#define MBEDTLS_SSL_CHK_BUF_PTR(cur, end, need) \ - do { \ - if (mbedtls_ssl_chk_buf_ptr((cur), (end), (need)) != 0) \ - { \ - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; \ - } \ - } while (0) - -/** - * \brief This macro checks if the remaining length in an input buffer is - * greater or equal than a needed length. If it is not the case, it - * returns #MBEDTLS_ERR_SSL_DECODE_ERROR error and pends a - * #MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR alert message. - * - * This is a function-like macro. It is guaranteed to evaluate each - * argument exactly once. - * - * \param cur Pointer to the current position in the buffer. - * \param end Pointer to one past the end of the buffer. - * \param need Needed length in bytes. - * - */ -#define MBEDTLS_SSL_CHK_BUF_READ_PTR(cur, end, need) \ - do { \ - if (mbedtls_ssl_chk_buf_ptr((cur), (end), (need)) != 0) \ - { \ - MBEDTLS_SSL_DEBUG_MSG(1, \ - ("missing input data in %s", __func__)); \ - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, \ - MBEDTLS_ERR_SSL_DECODE_ERROR); \ - return MBEDTLS_ERR_SSL_DECODE_ERROR; \ - } \ - } while (0) - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int mbedtls_ssl_tls_prf_cb(const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen); - -/* cipher.h exports the maximum IV, key and block length from - * all ciphers enabled in the config, regardless of whether those - * ciphers are actually usable in SSL/TLS. Notably, XTS is enabled - * in the default configuration and uses 64 Byte keys, but it is - * not used for record protection in SSL/TLS. - * - * In order to prevent unnecessary inflation of key structures, - * we introduce SSL-specific variants of the max-{key,block,IV} - * macros here which are meant to only take those ciphers into - * account which can be negotiated in SSL/TLS. - * - * Since the current definitions of MBEDTLS_MAX_{KEY|BLOCK|IV}_LENGTH - * in cipher.h are rough overapproximations of the real maxima, here - * we content ourselves with replicating those overapproximations - * for the maximum block and IV length, and excluding XTS from the - * computation of the maximum key length. */ -#define MBEDTLS_SSL_MAX_BLOCK_LENGTH 16 -#define MBEDTLS_SSL_MAX_IV_LENGTH 16 -#define MBEDTLS_SSL_MAX_KEY_LENGTH 32 - -/** - * \brief The data structure holding the cryptographic material (key and IV) - * used for record protection in TLS 1.3. - */ -struct mbedtls_ssl_key_set { - /*! The key for client->server records. */ - unsigned char client_write_key[MBEDTLS_SSL_MAX_KEY_LENGTH]; - /*! The key for server->client records. */ - unsigned char server_write_key[MBEDTLS_SSL_MAX_KEY_LENGTH]; - /*! The IV for client->server records. */ - unsigned char client_write_iv[MBEDTLS_SSL_MAX_IV_LENGTH]; - /*! The IV for server->client records. */ - unsigned char server_write_iv[MBEDTLS_SSL_MAX_IV_LENGTH]; - - size_t key_len; /*!< The length of client_write_key and - * server_write_key, in Bytes. */ - size_t iv_len; /*!< The length of client_write_iv and - * server_write_iv, in Bytes. */ -}; -typedef struct mbedtls_ssl_key_set mbedtls_ssl_key_set; - -typedef struct { - unsigned char binder_key[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char client_early_traffic_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char early_exporter_master_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; -} mbedtls_ssl_tls13_early_secrets; - -typedef struct { - unsigned char client_handshake_traffic_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char server_handshake_traffic_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; -} mbedtls_ssl_tls13_handshake_secrets; - -/* - * This structure contains the parameters only needed during handshake. - */ -struct mbedtls_ssl_handshake_params { - /* Frequently-used boolean or byte fields (placed early to take - * advantage of smaller code size for indirect access on Arm Thumb) */ - uint8_t resume; /*!< session resume indicator*/ - uint8_t cli_exts; /*!< client extension presence*/ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - uint8_t sni_authmode; /*!< authmode from SNI callback */ -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - /* Flag indicating if a CertificateRequest message has been sent - * to the client or not. */ - uint8_t certificate_request_sent; -#if defined(MBEDTLS_SSL_EARLY_DATA) - /* Flag indicating if the server has accepted early data or not. */ - uint8_t early_data_accepted; -#endif -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - uint8_t new_session_ticket; /*!< use NewSessionTicket? */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_CLI_C) - /** Minimum TLS version to be negotiated. - * - * It is set up in the ClientHello writing preparation stage and used - * throughout the ClientHello writing. Not relevant anymore as soon as - * the protocol version has been negotiated thus as soon as the - * ServerHello is received. - * For a fresh handshake not linked to any previous handshake, it is - * equal to the configured minimum minor version to be negotiated. When - * renegotiating or resuming a session, it is equal to the previously - * negotiated minor version. - * - * There is no maximum TLS version field in this handshake context. - * From the start of the handshake, we need to define a current protocol - * version for the record layer which we define as the maximum TLS - * version to be negotiated. The `tls_version` field of the SSL context is - * used to store this maximum value until it contains the actual - * negotiated value. - */ - mbedtls_ssl_protocol_version min_tls_version; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - uint8_t extended_ms; /*!< use Extended Master Secret? */ -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - uint8_t async_in_progress; /*!< an asynchronous operation is in progress */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - unsigned char retransmit_state; /*!< Retransmission state */ -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - unsigned char group_list_heap_allocated; - unsigned char sig_algs_heap_allocated; -#endif - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - uint8_t ecrs_enabled; /*!< Handshake supports EC restart? */ - enum { /* this complements ssl->state with info on intra-state operations */ - ssl_ecrs_none = 0, /*!< nothing going on (yet) */ - ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */ - ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */ - ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */ - ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */ - } ecrs_state; /*!< current (or last) operation */ - mbedtls_x509_crt *ecrs_peer_cert; /*!< The peer's CRT chain. */ - size_t ecrs_n; /*!< place for saving a length */ -#endif - - mbedtls_ssl_ciphersuite_t const *ciphersuite_info; - - MBEDTLS_CHECK_RETURN_CRITICAL - int (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); - MBEDTLS_CHECK_RETURN_CRITICAL - int (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *); - MBEDTLS_CHECK_RETURN_CRITICAL - int (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); - mbedtls_ssl_tls_prf_cb *tls_prf; - - /* - * Handshake specific crypto variables - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - uint8_t key_exchange_mode; /*!< Selected key exchange mode */ - - /** - * Flag indicating if, in the course of the current handshake, an - * HelloRetryRequest message has been sent by the server or received by - * the client (<> 0) or not (0). - */ - uint8_t hello_retry_request_flag; - -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - /** - * Flag indicating if, in the course of the current handshake, a dummy - * change_cipher_spec (CCS) record has already been sent. Used to send only - * one CCS per handshake while not complicating the handshake state - * transitions for that purpose. - */ - uint8_t ccs_sent; -#endif - -#if defined(MBEDTLS_SSL_SRV_C) -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - uint8_t tls13_kex_modes; /*!< Key exchange modes supported by the client */ -#endif - /** selected_group of key_share extension in HelloRetryRequest message. */ - uint16_t hrr_selected_group; -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - uint16_t new_session_tickets_count; /*!< number of session tickets */ -#endif -#endif /* MBEDTLS_SSL_SRV_C */ - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - uint16_t received_sig_algs[MBEDTLS_RECEIVED_SIG_ALGS_SIZE]; -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - const uint16_t *group_list; - const uint16_t *sig_algs; -#endif - -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ -#endif - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) - mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ -#endif /* !MBEDTLS_USE_PSA_CRYPTO && - MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED) - psa_key_type_t xxdh_psa_type; - size_t xxdh_psa_bits; - mbedtls_svc_key_id_t xxdh_psa_privkey; - uint8_t xxdh_psa_privkey_is_external; - unsigned char xxdh_psa_peerkey[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; - size_t xxdh_psa_peerkey_len; -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_pake_operation_t psa_pake_ctx; /*!< EC J-PAKE key exchange */ - mbedtls_svc_key_id_t psa_pake_password; - uint8_t psa_pake_ctx_is_ok; -#else - mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_SSL_CLI_C) - unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ - size_t ecjpake_cache_len; /*!< Length of cached data */ -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - uint16_t *curves_tls_id; /*!< List of TLS IDs of supported elliptic curves */ -#endif - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_svc_key_id_t psk_opaque; /*!< Opaque PSK from the callback */ - uint8_t psk_opaque_is_internal; -#else - unsigned char *psk; /*!< PSK from the callback */ - size_t psk_len; /*!< Length of PSK from callback */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - uint16_t selected_identity; -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */ -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */ -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ - mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */ - mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */ -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - struct { - size_t total_bytes_buffered; /*!< Cumulative size of heap allocated - * buffers used for message buffering. */ - - uint8_t seen_ccs; /*!< Indicates if a CCS message has - * been seen in the current flight. */ - - struct mbedtls_ssl_hs_buffer { - unsigned is_valid : 1; - unsigned is_fragmented : 1; - unsigned is_complete : 1; - unsigned char *data; - size_t data_len; - } hs[MBEDTLS_SSL_MAX_BUFFERED_HS]; - - struct { - unsigned char *data; - size_t len; - unsigned epoch; - } future_record; - - } buffering; - -#if defined(MBEDTLS_SSL_CLI_C) && \ - (defined(MBEDTLS_SSL_PROTO_DTLS) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_3)) - unsigned char *cookie; /*!< HelloVerifyRequest cookie for DTLS - * HelloRetryRequest cookie for TLS 1.3 */ -#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) - /* RFC 6347 page 15 - ... - opaque cookie<0..2^8-1>; - ... - */ - uint8_t cookie_len; -#else - /* RFC 8446 page 39 - ... - opaque cookie<0..2^16-1>; - ... - If TLS1_3 is enabled, the max length is 2^16 - 1 - */ - uint16_t cookie_len; /*!< DTLS: HelloVerifyRequest cookie length - * TLS1_3: HelloRetryRequest cookie length */ -#endif -#endif /* MBEDTLS_SSL_CLI_C && - ( MBEDTLS_SSL_PROTO_DTLS || - MBEDTLS_SSL_PROTO_TLS1_3 ) */ -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_DTLS) - unsigned char cookie_verify_result; /*!< Srv: flag for sending a cookie */ -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ - unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ - - uint32_t retransmit_timeout; /*!< Current value of timeout */ - mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ - mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ - unsigned char *cur_msg_p; /*!< Position in current message */ - unsigned int in_flight_start_seq; /*!< Minimum message sequence in the - flight being received */ - mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for - resending messages */ - unsigned char alt_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /*!< Alternative record epoch/counter - for resending messages */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* The state of CID configuration in this handshake. */ - - uint8_t cid_in_use; /*!< This indicates whether the use of the CID extension - * has been negotiated. Possible values are - * #MBEDTLS_SSL_CID_ENABLED and - * #MBEDTLS_SSL_CID_DISABLED. */ - unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX]; /*! The peer's CID */ - uint8_t peer_cid_len; /*!< The length of - * \c peer_cid. */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Checksum contexts - */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_operation_t fin_sha256_psa; -#else - mbedtls_md_context_t fin_sha256; -#endif -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_operation_t fin_sha384_psa; -#else - mbedtls_md_context_t fin_sha384; -#endif -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - uint16_t offered_group_id; /* The NamedGroup value for the group - * that is being used for ephemeral - * key exchange. - * - * On the client: Defaults to the first - * entry in the client's group list, - * but can be overwritten by the HRR. */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_CLI_C) - uint8_t client_auth; /*!< used to check if CertificateRequest has been - received from server side. If CertificateRequest - has been received, Certificate and CertificateVerify - should be sent to server */ -#endif /* MBEDTLS_SSL_CLI_C */ - /* - * State-local variables used during the processing - * of a specific handshake state. - */ - union { - /* Outgoing Finished message */ - struct { - uint8_t preparation_done; - - /* Buffer holding digest of the handshake up to - * but excluding the outgoing finished message. */ - unsigned char digest[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t digest_len; - } finished_out; - - /* Incoming Finished message */ - struct { - uint8_t preparation_done; - - /* Buffer holding digest of the handshake up to but - * excluding the peer's incoming finished message. */ - unsigned char digest[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t digest_len; - } finished_in; - - } state_local; - - /* End of state-local variables. */ - - unsigned char randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN + - MBEDTLS_SERVER_HELLO_RANDOM_LEN]; - /*!< random bytes */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; - /*!< premaster secret */ - size_t pmslen; /*!< premaster length */ -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - uint32_t sent_extensions; /*!< extensions sent by endpoint */ - uint32_t received_extensions; /*!< extensions received by endpoint */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - unsigned char certificate_request_context_len; - unsigned char *certificate_request_context; -#endif - - /** TLS 1.3 transform for encrypted handshake messages. */ - mbedtls_ssl_transform *transform_handshake; - union { - unsigned char early[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char handshake[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char app[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - } tls13_master_secrets; - - mbedtls_ssl_tls13_handshake_secrets tls13_hs_secrets; -#if defined(MBEDTLS_SSL_EARLY_DATA) - /** TLS 1.3 transform for early data and handshake messages. */ - mbedtls_ssl_transform *transform_earlydata; -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /** Asynchronous operation context. This field is meant for use by the - * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start, - * mbedtls_ssl_config::f_async_decrypt_start, - * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel). - * The library does not use it internally. */ - void *user_async_ctx; -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - const unsigned char *sni_name; /*!< raw SNI */ - size_t sni_name_len; /*!< raw SNI len */ -#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) - const mbedtls_x509_crt *dn_hints; /*!< acceptable client cert issuers */ -#endif -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ -}; - -typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer; - -/* - * Representation of decryption/encryption transformations on records - * - * There are the following general types of record transformations: - * - Stream transformations (TLS versions == 1.2 only) - * Transformation adding a MAC and applying a stream-cipher - * to the authenticated message. - * - CBC block cipher transformations ([D]TLS versions == 1.2 only) - * For TLS 1.2, no IV is generated at key extraction time, but every - * encrypted record is explicitly prefixed by the IV with which it was - * encrypted. - * - AEAD transformations ([D]TLS versions == 1.2 only) - * These come in two fundamentally different versions, the first one - * used in TLS 1.2, excluding ChaChaPoly ciphersuites, and the second - * one used for ChaChaPoly ciphersuites in TLS 1.2 as well as for TLS 1.3. - * In the first transformation, the IV to be used for a record is obtained - * as the concatenation of an explicit, static 4-byte IV and the 8-byte - * record sequence number, and explicitly prepending this sequence number - * to the encrypted record. In contrast, in the second transformation - * the IV is obtained by XOR'ing a static IV obtained at key extraction - * time with the 8-byte record sequence number, without prepending the - * latter to the encrypted record. - * - * Additionally, DTLS 1.2 + CID as well as TLS 1.3 use an inner plaintext - * which allows to add flexible length padding and to hide a record's true - * content type. - * - * In addition to type and version, the following parameters are relevant: - * - The symmetric cipher algorithm to be used. - * - The (static) encryption/decryption keys for the cipher. - * - For stream/CBC, the type of message digest to be used. - * - For stream/CBC, (static) encryption/decryption keys for the digest. - * - For AEAD transformations, the size (potentially 0) of an explicit, - * random initialization vector placed in encrypted records. - * - For some transformations (currently AEAD) an implicit IV. It is static - * and (if present) is combined with the explicit IV in a transformation- - * -dependent way (e.g. appending in TLS 1.2 and XOR'ing in TLS 1.3). - * - For stream/CBC, a flag determining the order of encryption and MAC. - * - The details of the transformation depend on the SSL/TLS version. - * - The length of the authentication tag. - * - * The struct below refines this abstract view as follows: - * - The cipher underlying the transformation is managed in - * cipher contexts cipher_ctx_{enc/dec}, which must have the - * same cipher type. The mode of these cipher contexts determines - * the type of the transformation in the sense above: e.g., if - * the type is MBEDTLS_CIPHER_AES_256_CBC resp. MBEDTLS_CIPHER_AES_192_GCM - * then the transformation has type CBC resp. AEAD. - * - The cipher keys are never stored explicitly but - * are maintained within cipher_ctx_{enc/dec}. - * - For stream/CBC transformations, the message digest contexts - * used for the MAC's are stored in md_ctx_{enc/dec}. These contexts - * are unused for AEAD transformations. - * - For stream/CBC transformations, the MAC keys are not stored explicitly - * but maintained within md_ctx_{enc/dec}. - * - The mac_enc and mac_dec fields are unused for EAD transformations. - * - For transformations using an implicit IV maintained within - * the transformation context, its contents are stored within - * iv_{enc/dec}. - * - The value of ivlen indicates the length of the IV. - * This is redundant in case of stream/CBC transformations - * which always use 0 resp. the cipher's block length as the - * IV length, but is needed for AEAD ciphers and may be - * different from the underlying cipher's block length - * in this case. - * - The field fixed_ivlen is nonzero for AEAD transformations only - * and indicates the length of the static part of the IV which is - * constant throughout the communication, and which is stored in - * the first fixed_ivlen bytes of the iv_{enc/dec} arrays. - * - tls_version denotes the 2-byte TLS version - * - For stream/CBC transformations, maclen denotes the length of the - * authentication tag, while taglen is unused and 0. - * - For AEAD transformations, taglen denotes the length of the - * authentication tag, while maclen is unused and 0. - * - For CBC transformations, encrypt_then_mac determines the - * order of encryption and authentication. This field is unused - * in other transformations. - * - */ -struct mbedtls_ssl_transform { - /* - * Session specific crypto layer - */ - size_t minlen; /*!< min. ciphertext length */ - size_t ivlen; /*!< IV length */ - size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */ - size_t maclen; /*!< MAC(CBC) len */ - size_t taglen; /*!< TAG(AEAD) len */ - - unsigned char iv_enc[16]; /*!< IV (encryption) */ - unsigned char iv_dec[16]; /*!< IV (decryption) */ - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_svc_key_id_t psa_mac_enc; /*!< MAC (encryption) */ - mbedtls_svc_key_id_t psa_mac_dec; /*!< MAC (decryption) */ - psa_algorithm_t psa_mac_alg; /*!< psa MAC algorithm */ -#else - mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */ - mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - int encrypt_then_mac; /*!< flag for EtM activation */ -#endif - -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - - mbedtls_ssl_protocol_version tls_version; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_svc_key_id_t psa_key_enc; /*!< psa encryption key */ - mbedtls_svc_key_id_t psa_key_dec; /*!< psa decryption key */ - psa_algorithm_t psa_alg; /*!< psa algorithm */ -#else - mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */ - mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - uint8_t in_cid_len; - uint8_t out_cid_len; - unsigned char in_cid[MBEDTLS_SSL_CID_IN_LEN_MAX]; - unsigned char out_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX]; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_KEEP_RANDBYTES) - /* We need the Hello random bytes in order to re-derive keys from the - * Master Secret and other session info and for the keying material - * exporter in TLS 1.2. - * See ssl_tls12_populate_transform() */ - unsigned char randbytes[MBEDTLS_SERVER_HELLO_RANDOM_LEN + - MBEDTLS_CLIENT_HELLO_RANDOM_LEN]; - /*!< ServerHello.random+ClientHello.random */ -#endif /* defined(MBEDTLS_SSL_KEEP_RANDBYTES) */ -}; - -/* - * Return 1 if the transform uses an AEAD cipher, 0 otherwise. - * Equivalently, return 0 if a separate MAC is used, 1 otherwise. - */ -static inline int mbedtls_ssl_transform_uses_aead( - const mbedtls_ssl_transform *transform) -{ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - return transform->maclen == 0 && transform->taglen != 0; -#else - (void) transform; - return 1; -#endif -} - -/* - * Internal representation of record frames - * - * Instances come in two flavors: - * (1) Encrypted - * These always have data_offset = 0 - * (2) Unencrypted - * These have data_offset set to the amount of - * pre-expansion during record protection. Concretely, - * this is the length of the fixed part of the explicit IV - * used for encryption, or 0 if no explicit IV is used - * (e.g. for stream ciphers). - * - * The reason for the data_offset in the unencrypted case - * is to allow for in-place conversion of an unencrypted to - * an encrypted record. If the offset wasn't included, the - * encrypted content would need to be shifted afterwards to - * make space for the fixed IV. - * - */ -#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX -#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_OUT_LEN_MAX -#else -#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_IN_LEN_MAX -#endif - -typedef struct { - uint8_t ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; /* In TLS: The implicit record sequence number. - * In DTLS: The 2-byte epoch followed by - * the 6-byte sequence number. - * This is stored as a raw big endian byte array - * as opposed to a uint64_t because we rarely - * need to perform arithmetic on this, but do - * need it as a Byte array for the purpose of - * MAC computations. */ - uint8_t type; /* The record content type. */ - uint8_t ver[2]; /* SSL/TLS version as present on the wire. - * Convert to internal presentation of versions - * using mbedtls_ssl_read_version() and - * mbedtls_ssl_write_version(). - * Keep wire-format for MAC computations. */ - - unsigned char *buf; /* Memory buffer enclosing the record content */ - size_t buf_len; /* Buffer length */ - size_t data_offset; /* Offset of record content */ - size_t data_len; /* Length of record content */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - uint8_t cid_len; /* Length of the CID (0 if not present) */ - unsigned char cid[MBEDTLS_SSL_CID_LEN_MAX]; /* The CID */ -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -} mbedtls_record; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/* - * List of certificate + private key pairs - */ -struct mbedtls_ssl_key_cert { - mbedtls_x509_crt *cert; /*!< cert */ - mbedtls_pk_context *key; /*!< private key */ - mbedtls_ssl_key_cert *next; /*!< next key/cert pair */ -}; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/* - * List of handshake messages kept around for resending - */ -struct mbedtls_ssl_flight_item { - unsigned char *p; /*!< message, including handshake headers */ - size_t len; /*!< length of p */ - unsigned char type; /*!< type of the message: handshake or CCS */ - mbedtls_ssl_flight_item *next; /*!< next handshake message(s) */ -}; -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -/** - * \brief Given an SSL context and its associated configuration, write the TLS - * 1.2 specific extensions of the ClientHello message. - * - * \param[in] ssl SSL context - * \param[in] buf Base address of the buffer where to write the extensions - * \param[in] end End address of the buffer where to write the extensions - * \param uses_ec Whether one proposed ciphersuite uses an elliptic curve - * (<> 0) or not ( 0 ). - * \param[out] out_len Length of the data written into the buffer \p buf - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - int uses_ec, - size_t *out_len); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - -/** - * \brief Find the preferred hash for a given signature algorithm. - * - * \param[in] ssl SSL context - * \param[in] sig_alg A signature algorithm identifier as defined in the - * TLS 1.2 SignatureAlgorithm enumeration. - * - * \return The preferred hash algorithm for \p sig_alg. It is a hash algorithm - * identifier as defined in the TLS 1.2 HashAlgorithm enumeration. - */ -unsigned int mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( - mbedtls_ssl_context *ssl, - unsigned int sig_alg); - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ - -/** - * \brief Free referenced items in an SSL transform context and clear - * memory - * - * \param transform SSL transform context - */ -void mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform); - -/** - * \brief Free referenced items in an SSL handshake context and clear - * memory - * - * \param ssl SSL context - */ -void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl); - -/* set inbound transform of ssl context */ -void mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform); - -/* set outbound transform of ssl context */ -void mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl); -void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_DEBUG_C) -/* Declared in "ssl_debug_helpers.h". We can't include this file from - * "ssl_misc.h" because it includes "ssl_misc.h" because it needs some - * type definitions. TODO: split the type definitions and the helper - * functions into different headers. - */ -const char *mbedtls_ssl_states_str(mbedtls_ssl_states state); -#endif - -static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl, - mbedtls_ssl_states state) -{ - MBEDTLS_SSL_DEBUG_MSG(3, ("handshake state: %d (%s) -> %d (%s)", - ssl->state, mbedtls_ssl_states_str((mbedtls_ssl_states) ssl->state), - (int) state, mbedtls_ssl_states_str(state))); - ssl->state = (int) state; -} - -static inline void mbedtls_ssl_handshake_increment_state(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_handshake_set_state(ssl, (mbedtls_ssl_states) (ssl->state + 1)); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_derive_keys(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl); - -/** - * \brief Update record layer - * - * This function roughly separates the implementation - * of the logic of (D)TLS from the implementation - * of the secure transport. - * - * \param ssl The SSL context to use. - * \param update_hs_digest This indicates if the handshake digest - * should be automatically updated in case - * a handshake message is found. - * - * \return 0 or non-zero error code. - * - * \note A clarification on what is called 'record layer' here - * is in order, as many sensible definitions are possible: - * - * The record layer takes as input an untrusted underlying - * transport (stream or datagram) and transforms it into - * a serially multiplexed, secure transport, which - * conceptually provides the following: - * - * (1) Three datagram based, content-agnostic transports - * for handshake, alert and CCS messages. - * (2) One stream- or datagram-based transport - * for application data. - * (3) Functionality for changing the underlying transform - * securing the contents. - * - * The interface to this functionality is given as follows: - * - * a Updating - * [Currently implemented by mbedtls_ssl_read_record] - * - * Check if and on which of the four 'ports' data is pending: - * Nothing, a controlling datagram of type (1), or application - * data (2). In any case data is present, internal buffers - * provide access to the data for the user to process it. - * Consumption of type (1) datagrams is done automatically - * on the next update, invalidating that the internal buffers - * for previous datagrams, while consumption of application - * data (2) is user-controlled. - * - * b Reading of application data - * [Currently manual adaption of ssl->in_offt pointer] - * - * As mentioned in the last paragraph, consumption of data - * is different from the automatic consumption of control - * datagrams (1) because application data is treated as a stream. - * - * c Tracking availability of application data - * [Currently manually through decreasing ssl->in_msglen] - * - * For efficiency and to retain datagram semantics for - * application data in case of DTLS, the record layer - * provides functionality for checking how much application - * data is still available in the internal buffer. - * - * d Changing the transformation securing the communication. - * - * Given an opaque implementation of the record layer in the - * above sense, it should be possible to implement the logic - * of (D)TLS on top of it without the need to know anything - * about the record layer's internals. This is done e.g. - * in all the handshake handling functions, and in the - * application data reading function mbedtls_ssl_read. - * - * \note The above tries to give a conceptual picture of the - * record layer, but the current implementation deviates - * from it in some places. For example, our implementation of - * the update functionality through mbedtls_ssl_read_record - * discards datagrams depending on the current state, which - * wouldn't fall under the record layer's responsibility - * following the above definition. - * - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl, - unsigned update_hs_digest); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want); - -/* - * Write handshake message header - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type, - unsigned char **buf, size_t *buf_len); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl, - int update_checksum, - int force_flush); -static inline int mbedtls_ssl_write_handshake_msg(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_write_handshake_msg_ext(ssl, 1 /* update checksum */, 1 /* force flush */); -} - -/* - * Write handshake message tail - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context *ssl, - size_t buf_len, size_t msg_len); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, int force_flush); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl); - -void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info); - -/* - * Update checksum of handshake messages. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - unsigned char const *msg, - size_t msg_len); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - size_t total_hs_len); - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -#if !defined(MBEDTLS_USE_PSA_CRYPTO) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_psk_derive_premaster(mbedtls_ssl_context *ssl, - mbedtls_key_exchange_type_t key_ex); -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -#if defined(MBEDTLS_SSL_CLI_C) || defined(MBEDTLS_SSL_SRV_C) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_conf_has_static_psk(mbedtls_ssl_config const *conf); -#endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * Get the first defined opaque PSK by order of precedence: - * 1. handshake PSK set by \c mbedtls_ssl_set_hs_psk_opaque() in the PSK - * callback - * 2. static PSK configured by \c mbedtls_ssl_conf_psk_opaque() - * Return an opaque PSK - */ -static inline mbedtls_svc_key_id_t mbedtls_ssl_get_opaque_psk( - const mbedtls_ssl_context *ssl) -{ - if (!mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) { - return ssl->handshake->psk_opaque; - } - - if (!mbedtls_svc_key_id_is_null(ssl->conf->psk_opaque)) { - return ssl->conf->psk_opaque; - } - - return MBEDTLS_SVC_KEY_ID_INIT; -} -#else -/** - * Get the first defined PSK by order of precedence: - * 1. handshake PSK set by \c mbedtls_ssl_set_hs_psk() in the PSK callback - * 2. static PSK configured by \c mbedtls_ssl_conf_psk() - * Return a code and update the pair (PSK, PSK length) passed to this function - */ -static inline int mbedtls_ssl_get_psk(const mbedtls_ssl_context *ssl, - const unsigned char **psk, size_t *psk_len) -{ - if (ssl->handshake->psk != NULL && ssl->handshake->psk_len > 0) { - *psk = ssl->handshake->psk; - *psk_len = ssl->handshake->psk_len; - } else if (ssl->conf->psk != NULL && ssl->conf->psk_len > 0) { - *psk = ssl->conf->psk; - *psk_len = ssl->conf->psk_len; - } else { - *psk = NULL; - *psk_len = 0; - return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; - } - - return 0; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */ - -#if defined(MBEDTLS_PK_C) -unsigned char mbedtls_ssl_sig_from_pk(mbedtls_pk_context *pk); -unsigned char mbedtls_ssl_sig_from_pk_alg(mbedtls_pk_type_t type); -mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig(unsigned char sig); -#endif - -mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash(unsigned char hash); -unsigned char mbedtls_ssl_hash_from_md_alg(int md); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md); -#endif - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_check_curve_tls_id(const mbedtls_ssl_context *ssl, uint16_t tls_id); -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_check_curve(const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id); -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -/** - * \brief Return PSA EC info for the specified TLS ID. - * - * \param tls_id The TLS ID to look for - * \param type If the TLD ID is supported, then proper \c psa_key_type_t - * value is returned here. Can be NULL. - * \param bits If the TLD ID is supported, then proper bit size is returned - * here. Can be NULL. - * \return PSA_SUCCESS if the TLS ID is supported, - * PSA_ERROR_NOT_SUPPORTED otherwise - * - * \note If either \c family or \c bits parameters are NULL, then - * the corresponding value is not returned. - * The function can be called with both parameters as NULL - * simply to check if a specific TLS ID is supported. - */ -int mbedtls_ssl_get_psa_curve_info_from_tls_id(uint16_t tls_id, - psa_key_type_t *type, - size_t *bits); - -/** - * \brief Return \c mbedtls_ecp_group_id for the specified TLS ID. - * - * \param tls_id The TLS ID to look for - * \return Proper \c mbedtls_ecp_group_id if the TLS ID is supported, - * or MBEDTLS_ECP_DP_NONE otherwise - */ -mbedtls_ecp_group_id mbedtls_ssl_get_ecp_group_id_from_tls_id(uint16_t tls_id); - -/** - * \brief Return TLS ID for the specified \c mbedtls_ecp_group_id. - * - * \param grp_id The \c mbedtls_ecp_group_id ID to look for - * \return Proper TLS ID if the \c mbedtls_ecp_group_id is supported, - * or 0 otherwise - */ -uint16_t mbedtls_ssl_get_tls_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id); - -#if defined(MBEDTLS_DEBUG_C) -/** - * \brief Return EC's name for the specified TLS ID. - * - * \param tls_id The TLS ID to look for - * \return A pointer to a const string with the proper name. If TLS - * ID is not supported, a NULL pointer is returned instead. - */ -const char *mbedtls_ssl_get_curve_name_from_tls_id(uint16_t tls_id); -#endif - -#if defined(MBEDTLS_SSL_DTLS_SRTP) -static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value - (const uint16_t srtp_profile_value) -{ - switch (srtp_profile_value) { - case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: - case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: - case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: - case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: - return srtp_profile_value; - default: break; - } - return MBEDTLS_TLS_SRTP_UNSET; -} -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static inline mbedtls_pk_context *mbedtls_ssl_own_key(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_key_cert *key_cert; - - if (ssl->handshake != NULL && ssl->handshake->key_cert != NULL) { - key_cert = ssl->handshake->key_cert; - } else { - key_cert = ssl->conf->key_cert; - } - - return key_cert == NULL ? NULL : key_cert->key; -} - -static inline mbedtls_x509_crt *mbedtls_ssl_own_cert(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_key_cert *key_cert; - - if (ssl->handshake != NULL && ssl->handshake->key_cert != NULL) { - key_cert = ssl->handshake->key_cert; - } else { - key_cert = ssl->conf->key_cert; - } - - return key_cert == NULL ? NULL : key_cert->cert; -} - -/* - * Verify a certificate. - * - * [in/out] ssl: misc. things read - * ssl->session_negotiate->verify_result updated - * [in] authmode: one of MBEDTLS_SSL_VERIFY_{NONE,OPTIONAL,REQUIRED} - * [in] chain: the certificate chain to verify (ie the peer's chain) - * [in] ciphersuite_info: For TLS 1.2, this session's ciphersuite; - * for TLS 1.3, may be left NULL. - * [in] rs_ctx: restart context if restartable ECC is in use; - * leave NULL for no restartable behaviour. - * - * Return: - * - 0 if the handshake should continue. Depending on the - * authmode it means: - * - REQUIRED: the certificate was found to be valid, trusted & acceptable. - * ssl->session_negotiate->verify_result is 0. - * - OPTIONAL: the certificate may or may not be acceptable, but - * ssl->session_negotiate->verify_result was updated with the result. - * - NONE: the certificate wasn't even checked. - * - MBEDTLS_ERR_X509_CERT_VERIFY_FAILED or MBEDTLS_ERR_SSL_BAD_CERTIFICATE if - * the certificate was found to be invalid/untrusted/unacceptable and the - * handshake should be aborted (can only happen with REQUIRED). - * - another error code if another error happened (out-of-memory, etc.) - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, - int authmode, - mbedtls_x509_crt *chain, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info, - void *rs_ctx); - -/* - * Check usage of a certificate wrt usage extensions: - * keyUsage and extendedKeyUsage. - * (Note: nSCertType is deprecated and not standard, we don't check it.) - * - * Note: if tls_version is 1.3, ciphersuite is ignored and can be NULL. - * - * Note: recv_endpoint is the receiver's endpoint. - * - * Return 0 if everything is OK, -1 if not. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, - const mbedtls_ssl_ciphersuite_t *ciphersuite, - int recv_endpoint, - mbedtls_ssl_protocol_version tls_version, - uint32_t *flags); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -void mbedtls_ssl_write_version(unsigned char version[2], int transport, - mbedtls_ssl_protocol_version tls_version); -uint16_t mbedtls_ssl_read_version(const unsigned char version[2], - int transport); - -static inline size_t mbedtls_ssl_in_hdr_len(const mbedtls_ssl_context *ssl) -{ -#if !defined(MBEDTLS_SSL_PROTO_DTLS) - ((void) ssl); -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return 13; - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - return 5; - } -} - -static inline size_t mbedtls_ssl_out_hdr_len(const mbedtls_ssl_context *ssl) -{ - return (size_t) (ssl->out_iv - ssl->out_hdr); -} - -static inline size_t mbedtls_ssl_hs_hdr_len(const mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return 12; - } -#else - ((void) ssl); -#endif - return 4; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl); -void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_resend(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl); -#endif - -/* Visible for testing purposes only */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl); -void mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl); -#endif - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_session_copy(mbedtls_ssl_session *dst, - const mbedtls_ssl_session *src); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -/* The hash buffer must have at least MBEDTLS_MD_MAX_SIZE bytes of length. */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg); -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#ifdef __cplusplus -} -#endif - -void mbedtls_ssl_transform_init(mbedtls_ssl_transform *transform); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec); - -/* Length of the "epoch" field in the record header */ -static inline size_t mbedtls_ssl_ep_len(const mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return 2; - } -#else - ((void) ssl); -#endif - return 0; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_resend_hello_request(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl); - -void mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context *ssl); -void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl); -void mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context *ssl); -void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial); -void mbedtls_ssl_session_reset_msg_layer(mbedtls_ssl_context *ssl, - int partial); - -/* - * Send pending alert - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context *ssl); - -/* - * Set pending fatal alert flag. - */ -void mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context *ssl, - unsigned char alert_type, - int alert_reason); - -/* Alias of mbedtls_ssl_pend_fatal_alert */ -#define MBEDTLS_SSL_PEND_FATAL_ALERT(type, user_return_value) \ - mbedtls_ssl_pend_fatal_alert(ssl, type, user_return_value) - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -void mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl); -#endif - -void mbedtls_ssl_handshake_wrapup_free_hs_transform(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_start_renegotiation(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -size_t mbedtls_ssl_get_current_mtu(const mbedtls_ssl_context *ssl); -void mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl); -void mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -/** - * ssl utils functions for checking configuration. - */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -static inline int mbedtls_ssl_conf_is_tls13_only(const mbedtls_ssl_config *conf) -{ - return conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 && - conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3; -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static inline int mbedtls_ssl_conf_is_tls12_only(const mbedtls_ssl_config *conf) -{ - return conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && - conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_2; -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -static inline int mbedtls_ssl_conf_is_tls13_enabled(const mbedtls_ssl_config *conf) -{ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - return conf->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_3 && - conf->max_tls_version >= MBEDTLS_SSL_VERSION_TLS1_3; -#else - ((void) conf); - return 0; -#endif -} - -static inline int mbedtls_ssl_conf_is_tls12_enabled(const mbedtls_ssl_config *conf) -{ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - return conf->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_2 && - conf->max_tls_version >= MBEDTLS_SSL_VERSION_TLS1_2; -#else - ((void) conf); - return 0; -#endif -} - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3) -static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13(const mbedtls_ssl_config *conf) -{ - return conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && - conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -/** \brief Initialize the PSA crypto subsystem if necessary. - * - * Call this function before doing any cryptography in a TLS 1.3 handshake. - * - * This is necessary in Mbed TLS 3.x for backward compatibility. - * Up to Mbed TLS 3.5, in the default configuration, you could perform - * a TLS connection with default parameters without having called - * psa_crypto_init(), since the TLS layer only supported TLS 1.2 and - * did not use PSA crypto. (TLS 1.2 only uses PSA crypto if - * MBEDTLS_USE_PSA_CRYPTO is enabled, which is not the case in the default - * configuration.) Starting with Mbed TLS 3.6.0, TLS 1.3 is enabled - * by default, and the TLS 1.3 layer uses PSA crypto. This means that - * applications that are not otherwise using PSA crypto and that worked - * with Mbed TLS 3.5 started failing in TLS 3.6.0 if they connected to - * a peer that supports TLS 1.3. See - * https://github.com/Mbed-TLS/mbedtls/issues/9072 - */ -int mbedtls_ssl_tls13_crypto_init(mbedtls_ssl_context *ssl); - -extern const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[ - MBEDTLS_SERVER_HELLO_RANDOM_LEN]; -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_process_finished_message(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_finished_message(mbedtls_ssl_context *ssl); -void mbedtls_ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl); - -/** - * \brief Given an SSL context and its associated configuration, write the TLS - * 1.3 specific extensions of the ClientHello message. - * - * \param[in] ssl SSL context - * \param[in] buf Base address of the buffer where to write the extensions - * \param[in] end End address of the buffer where to write the extensions - * \param[out] out_len Length of the data written into the buffer \p buf - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len); - -/** - * \brief TLS 1.3 client side state machine entry - * - * \param ssl SSL context - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl); - -/** - * \brief TLS 1.3 server side state machine entry - * - * \param ssl SSL context - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl); - - -/* - * Helper functions around key exchange modes. - */ -static inline int mbedtls_ssl_conf_tls13_is_kex_mode_enabled(mbedtls_ssl_context *ssl, - int kex_mode_mask) -{ - return (ssl->conf->tls13_kex_modes & kex_mode_mask) != 0; -} - -static inline int mbedtls_ssl_conf_tls13_is_psk_enabled(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK); -} - -static inline int mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL); -} - -static inline int mbedtls_ssl_conf_tls13_is_ephemeral_enabled(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL); -} - -static inline int mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL); -} - -static inline int mbedtls_ssl_conf_tls13_is_some_psk_enabled(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_conf_tls13_is_kex_mode_enabled(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL); -} - -#if defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -/** - * Given a list of key exchange modes, check if at least one of them is - * supported by peer. - * - * \param[in] ssl SSL context - * \param kex_modes_mask Mask of the key exchange modes to check - * - * \return Non-zero if at least one of the key exchange modes is supported by - * the peer, otherwise \c 0. - */ -static inline int mbedtls_ssl_tls13_is_kex_mode_supported(mbedtls_ssl_context *ssl, - int kex_modes_mask) -{ - return (ssl->handshake->tls13_kex_modes & kex_modes_mask) != 0; -} - -static inline int mbedtls_ssl_tls13_is_psk_supported(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_tls13_is_kex_mode_supported(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK); -} - -static inline int mbedtls_ssl_tls13_is_psk_ephemeral_supported( - mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_tls13_is_kex_mode_supported(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL); -} - -static inline int mbedtls_ssl_tls13_is_ephemeral_supported(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_tls13_is_kex_mode_supported(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL); -} - -static inline int mbedtls_ssl_tls13_is_some_ephemeral_supported(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_tls13_is_kex_mode_supported(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL); -} - -static inline int mbedtls_ssl_tls13_is_some_psk_supported(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_tls13_is_kex_mode_supported(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL); -} -#endif /* MBEDTLS_SSL_SRV_C && - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - -/* - * Helper functions for extensions checking. - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_check_received_extension( - mbedtls_ssl_context *ssl, - int hs_msg_type, - unsigned int received_extension_type, - uint32_t hs_msg_allowed_extensions_mask); - -static inline void mbedtls_ssl_tls13_set_hs_sent_ext_mask( - mbedtls_ssl_context *ssl, unsigned int extension_type) -{ - ssl->handshake->sent_extensions |= - mbedtls_ssl_get_extension_mask(extension_type); -} - -/* - * Helper functions to check the selected key exchange mode. - */ -static inline int mbedtls_ssl_tls13_key_exchange_mode_check( - mbedtls_ssl_context *ssl, int kex_mask) -{ - return (ssl->handshake->key_exchange_mode & kex_mask) != 0; -} - -static inline int mbedtls_ssl_tls13_key_exchange_mode_with_psk( - mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_tls13_key_exchange_mode_check(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL); -} - -static inline int mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral( - mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_tls13_key_exchange_mode_check(ssl, - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL); -} - -/* - * Fetch TLS 1.3 handshake message header - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_fetch_handshake_msg(mbedtls_ssl_context *ssl, - unsigned hs_type, - unsigned char **buf, - size_t *buf_len); - -/** - * \brief Detect if a list of extensions contains a supported_versions - * extension or not. - * - * \param[in] ssl SSL context - * \param[in] buf Address of the first byte of the extensions vector. - * \param[in] end End of the buffer containing the list of extensions. - * \param[out] supported_versions_data If the extension is present, address of - * its first byte of data, NULL otherwise. - * \param[out] supported_versions_data_end If the extension is present, address - * of the first byte immediately - * following the extension data, NULL - * otherwise. - * \return 0 if the list of extensions does not contain a supported_versions - * extension. - * \return 1 if the list of extensions contains a supported_versions - * extension. - * \return A negative value if an error occurred while parsing the - * extensions. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( - mbedtls_ssl_context *ssl, - const unsigned char *buf, const unsigned char *end, - const unsigned char **supported_versions_data, - const unsigned char **supported_versions_data_end); - -/* - * Handler of TLS 1.3 server certificate message - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_process_certificate(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -/* - * Handler of TLS 1.3 write Certificate message - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_certificate(mbedtls_ssl_context *ssl); - -/* - * Handler of TLS 1.3 write Certificate Verify message - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl); - -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -/* - * Generic handler of Certificate Verify - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl); - -/* - * Write of dummy-CCS's for middlebox compatibility - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl); - -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange( - mbedtls_ssl_context *ssl, - uint16_t named_group, - unsigned char *buf, - unsigned char *end, - size_t *out_len); -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) -int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, - int in_new_session_ticket, - unsigned char *buf, - const unsigned char *end, - size_t *out_len); - -int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, - size_t early_data_len); - -typedef enum { -/* - * The client has not sent the first ClientHello yet, the negotiation of early - * data has not started yet. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_IDLE, - -/* - * In its ClientHello, the client has not included an early data indication - * extension. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT, - -/* - * The client has sent an early data indication extension in its first - * ClientHello, it has not received the response (ServerHello or - * HelloRetryRequest) from the server yet. The transform to protect early data - * is not set either as for middlebox compatibility a dummy CCS may have to be - * sent in clear. Early data cannot be sent to the server yet. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT, - -/* - * The client has sent an early data indication extension in its first - * ClientHello, it has not received the response (ServerHello or - * HelloRetryRequest) from the server yet. The transform to protect early data - * has been set and early data can be written now. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, - -/* - * The client has indicated the use of early data and the server has accepted - * it. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED, - -/* - * The client has indicated the use of early data but the server has rejected - * it. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED, - -/* - * The client has sent an early data indication extension in its first - * ClientHello, the server has accepted them and the client has received the - * server Finished message. It cannot send early data to the server anymore. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED, - -} mbedtls_ssl_early_data_state; -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -/* - * Write Signature Algorithm extension - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_sig_alg_ext(mbedtls_ssl_context *ssl, unsigned char *buf, - const unsigned char *end, size_t *out_len); -/* - * Parse TLS Signature Algorithm extension - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_sig_alg_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end); -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -/* Get handshake transcript */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_get_handshake_transcript(mbedtls_ssl_context *ssl, - const mbedtls_md_type_t md, - unsigned char *dst, - size_t dst_len, - size_t *olen); - -/* - * Return supported groups. - * - * In future, invocations can be changed to ssl->conf->group_list - * when mbedtls_ssl_conf_curves() is deleted. - * - * ssl->handshake->group_list is either a translation of curve_list to IANA TLS group - * identifiers when mbedtls_ssl_conf_curves() has been used, or a pointer to - * ssl->conf->group_list when mbedtls_ssl_conf_groups() has been more recently invoked. - * - */ -static inline const void *mbedtls_ssl_get_groups(const mbedtls_ssl_context *ssl) -{ - #if defined(MBEDTLS_DEPRECATED_REMOVED) || !defined(MBEDTLS_ECP_C) - return ssl->conf->group_list; - #else - if ((ssl->handshake != NULL) && (ssl->handshake->group_list != NULL)) { - return ssl->handshake->group_list; - } else { - return ssl->conf->group_list; - } - #endif -} - -/* - * Helper functions for NamedGroup. - */ -static inline int mbedtls_ssl_tls12_named_group_is_ecdhe(uint16_t named_group) -{ - /* - * RFC 8422 section 5.1.1 - */ - return named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X25519 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X448 || - /* Below deprecated curves should be removed with notice to users */ - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP192K1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP192R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP224K1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP224R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256K1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1; -} - -static inline int mbedtls_ssl_tls13_named_group_is_ecdhe(uint16_t named_group) -{ - return named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X25519 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1 || - named_group == MBEDTLS_SSL_IANA_TLS_GROUP_X448; -} - -static inline int mbedtls_ssl_tls13_named_group_is_ffdh(uint16_t named_group) -{ - return named_group >= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048 && - named_group <= MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192; -} - -static inline int mbedtls_ssl_named_group_is_offered( - const mbedtls_ssl_context *ssl, uint16_t named_group) -{ - const uint16_t *group_list = mbedtls_ssl_get_groups(ssl); - - if (group_list == NULL) { - return 0; - } - - for (; *group_list != 0; group_list++) { - if (*group_list == named_group) { - return 1; - } - } - - return 0; -} - -static inline int mbedtls_ssl_named_group_is_supported(uint16_t named_group) -{ -#if defined(PSA_WANT_ALG_ECDH) - if (mbedtls_ssl_tls13_named_group_is_ecdhe(named_group)) { - if (mbedtls_ssl_get_ecp_group_id_from_tls_id(named_group) != - MBEDTLS_ECP_DP_NONE) { - return 1; - } - } -#endif -#if defined(PSA_WANT_ALG_FFDH) - if (mbedtls_ssl_tls13_named_group_is_ffdh(named_group)) { - return 1; - } -#endif -#if !defined(PSA_WANT_ALG_ECDH) && !defined(PSA_WANT_ALG_FFDH) - (void) named_group; -#endif - return 0; -} - -/* - * Return supported signature algorithms. - * - * In future, invocations can be changed to ssl->conf->sig_algs when - * mbedtls_ssl_conf_sig_hashes() is deleted. - * - * ssl->handshake->sig_algs is either a translation of sig_hashes to IANA TLS - * signature algorithm identifiers when mbedtls_ssl_conf_sig_hashes() has been - * used, or a pointer to ssl->conf->sig_algs when mbedtls_ssl_conf_sig_algs() has - * been more recently invoked. - * - */ -static inline const void *mbedtls_ssl_get_sig_algs( - const mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ssl->handshake != NULL && - ssl->handshake->sig_algs_heap_allocated == 1 && - ssl->handshake->sig_algs != NULL) { - return ssl->handshake->sig_algs; - } -#endif - return ssl->conf->sig_algs; - -#else /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - - ((void) ssl); - return NULL; -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -static inline int mbedtls_ssl_sig_alg_is_received(const mbedtls_ssl_context *ssl, - uint16_t own_sig_alg) -{ - const uint16_t *sig_alg = ssl->handshake->received_sig_algs; - if (sig_alg == NULL) { - return 0; - } - - for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) { - if (*sig_alg == own_sig_alg) { - return 1; - } - } - return 0; -} - -static inline int mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported( - const uint16_t sig_alg) -{ - switch (sig_alg) { -#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) -#if defined(PSA_WANT_ALG_SHA_256) && defined(PSA_WANT_ECC_SECP_R1_256) - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256: - break; -#endif /* PSA_WANT_ALG_SHA_256 && MBEDTLS_ECP_DP_SECP256R1_ENABLED */ -#if defined(PSA_WANT_ALG_SHA_384) && defined(PSA_WANT_ECC_SECP_R1_384) - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384: - break; -#endif /* PSA_WANT_ALG_SHA_384 && MBEDTLS_ECP_DP_SECP384R1_ENABLED */ -#if defined(PSA_WANT_ALG_SHA_512) && defined(PSA_WANT_ECC_SECP_R1_521) - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512: - break; -#endif /* PSA_WANT_ALG_SHA_512 && MBEDTLS_ECP_DP_SECP521R1_ENABLED */ -#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */ - -#if defined(MBEDTLS_PKCS1_V21) -#if defined(PSA_WANT_ALG_SHA_256) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: - break; -#endif /* PSA_WANT_ALG_SHA_256 */ -#if defined(PSA_WANT_ALG_SHA_384) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: - break; -#endif /* PSA_WANT_ALG_SHA_384 */ -#if defined(PSA_WANT_ALG_SHA_512) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: - break; -#endif /* PSA_WANT_ALG_SHA_512 */ -#endif /* MBEDTLS_PKCS1_V21 */ - default: - return 0; - } - return 1; - -} - -static inline int mbedtls_ssl_tls13_sig_alg_is_supported( - const uint16_t sig_alg) -{ - switch (sig_alg) { -#if defined(MBEDTLS_PKCS1_V15) -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256: - break; -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384: - break; -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_MD_CAN_SHA512) - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512: - break; -#endif /* MBEDTLS_MD_CAN_SHA512 */ -#endif /* MBEDTLS_PKCS1_V15 */ - default: - return mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported( - sig_alg); - } - return 1; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_check_sig_alg_cert_key_match(uint16_t sig_alg, - mbedtls_pk_context *key); -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -static inline int mbedtls_ssl_sig_alg_is_offered(const mbedtls_ssl_context *ssl, - uint16_t proposed_sig_alg) -{ - const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl); - if (sig_alg == NULL) { - return 0; - } - - for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) { - if (*sig_alg == proposed_sig_alg) { - return 1; - } - } - return 0; -} - -static inline int mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg( - uint16_t sig_alg, mbedtls_pk_type_t *pk_type, mbedtls_md_type_t *md_alg) -{ - *pk_type = mbedtls_ssl_pk_alg_from_sig(sig_alg & 0xff); - *md_alg = mbedtls_ssl_md_alg_from_hash((sig_alg >> 8) & 0xff); - - if (*pk_type != MBEDTLS_PK_NONE && *md_alg != MBEDTLS_MD_NONE) { - return 0; - } - - switch (sig_alg) { -#if defined(MBEDTLS_PKCS1_V21) -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: - *md_alg = MBEDTLS_MD_SHA256; - *pk_type = MBEDTLS_PK_RSASSA_PSS; - break; -#endif /* MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: - *md_alg = MBEDTLS_MD_SHA384; - *pk_type = MBEDTLS_PK_RSASSA_PSS; - break; -#endif /* MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_MD_CAN_SHA512) - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: - *md_alg = MBEDTLS_MD_SHA512; - *pk_type = MBEDTLS_PK_RSASSA_PSS; - break; -#endif /* MBEDTLS_MD_CAN_SHA512 */ -#endif /* MBEDTLS_PKCS1_V21 */ - default: - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - return 0; -} - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static inline int mbedtls_ssl_tls12_sig_alg_is_supported( - const uint16_t sig_alg) -{ - /* High byte is hash */ - unsigned char hash = MBEDTLS_BYTE_1(sig_alg); - unsigned char sig = MBEDTLS_BYTE_0(sig_alg); - - switch (hash) { -#if defined(MBEDTLS_MD_CAN_MD5) - case MBEDTLS_SSL_HASH_MD5: - break; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA1) - case MBEDTLS_SSL_HASH_SHA1: - break; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA224) - case MBEDTLS_SSL_HASH_SHA224: - break; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_SSL_HASH_SHA256: - break; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_SSL_HASH_SHA384: - break; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA512) - case MBEDTLS_SSL_HASH_SHA512: - break; -#endif - - default: - return 0; - } - - switch (sig) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_SSL_SIG_RSA: - break; -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - case MBEDTLS_SSL_SIG_ECDSA: - break; -#endif - - default: - return 0; - } - - return 1; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -static inline int mbedtls_ssl_sig_alg_is_supported( - const mbedtls_ssl_context *ssl, - const uint16_t sig_alg) -{ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { - return mbedtls_ssl_tls12_sig_alg_is_supported(sig_alg); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - return mbedtls_ssl_tls13_sig_alg_is_supported(sig_alg); - } -#endif - ((void) ssl); - ((void) sig_alg); - return 0; -} -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) -/* Corresponding PSA algorithm for MBEDTLS_CIPHER_NULL. - * Same value is used for PSA_ALG_CATEGORY_CIPHER, hence it is - * guaranteed to not be a valid PSA algorithm identifier. - */ -#define MBEDTLS_SSL_NULL_CIPHER 0x04000000 - -/** - * \brief Translate mbedtls cipher type/taglen pair to psa: - * algorithm, key type and key size. - * - * \param mbedtls_cipher_type [in] given mbedtls cipher type - * \param taglen [in] given tag length - * 0 - default tag length - * \param alg [out] corresponding PSA alg - * There is no corresponding PSA - * alg for MBEDTLS_CIPHER_NULL, so - * in this case MBEDTLS_SSL_NULL_CIPHER - * is returned via this parameter - * \param key_type [out] corresponding PSA key type - * \param key_size [out] corresponding PSA key size - * - * \return PSA_SUCCESS on success or PSA_ERROR_NOT_SUPPORTED if - * conversion is not supported. - */ -psa_status_t mbedtls_ssl_cipher_to_psa(mbedtls_cipher_type_t mbedtls_cipher_type, - size_t taglen, - psa_algorithm_t *alg, - psa_key_type_t *key_type, - size_t *key_size); - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief Convert given PSA status to mbedtls error code. - * - * \param status [in] given PSA status - * - * \return corresponding mbedtls error code - */ -static inline MBEDTLS_DEPRECATED int psa_ssl_status_to_mbedtls(psa_status_t status) -{ - switch (status) { - case PSA_SUCCESS: - return 0; - case PSA_ERROR_INSUFFICIENT_MEMORY: - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - case PSA_ERROR_INVALID_SIGNATURE: - return MBEDTLS_ERR_SSL_INVALID_MAC; - case PSA_ERROR_INVALID_ARGUMENT: - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - case PSA_ERROR_BAD_STATE: - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - default: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - defined(MBEDTLS_USE_PSA_CRYPTO) - -typedef enum { - MBEDTLS_ECJPAKE_ROUND_ONE, - MBEDTLS_ECJPAKE_ROUND_TWO -} mbedtls_ecjpake_rounds_t; - -/** - * \brief Parse the provided input buffer for getting the first round - * of key exchange. This code is common between server and client - * - * \param pake_ctx [in] the PAKE's operation/context structure - * \param buf [in] input buffer to parse - * \param len [in] length of the input buffer - * \param round [in] either MBEDTLS_ECJPAKE_ROUND_ONE or - * MBEDTLS_ECJPAKE_ROUND_TWO - * - * \return 0 on success or a negative error code in case of failure - */ -int mbedtls_psa_ecjpake_read_round( - psa_pake_operation_t *pake_ctx, - const unsigned char *buf, - size_t len, mbedtls_ecjpake_rounds_t round); - -/** - * \brief Write the first round of key exchange into the provided output - * buffer. This code is common between server and client - * - * \param pake_ctx [in] the PAKE's operation/context structure - * \param buf [out] the output buffer in which data will be written to - * \param len [in] length of the output buffer - * \param olen [out] the length of the data really written on the buffer - * \param round [in] either MBEDTLS_ECJPAKE_ROUND_ONE or - * MBEDTLS_ECJPAKE_ROUND_TWO - * - * \return 0 on success or a negative error code in case of failure - */ -int mbedtls_psa_ecjpake_write_round( - psa_pake_operation_t *pake_ctx, - unsigned char *buf, - size_t len, size_t *olen, - mbedtls_ecjpake_rounds_t round); - -#endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO - -/** - * \brief TLS record protection modes - */ -typedef enum { - MBEDTLS_SSL_MODE_STREAM = 0, - MBEDTLS_SSL_MODE_CBC, - MBEDTLS_SSL_MODE_CBC_ETM, - MBEDTLS_SSL_MODE_AEAD -} mbedtls_ssl_mode_t; - -mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_transform( - const mbedtls_ssl_transform *transform); - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) -mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite( - int encrypt_then_mac, - const mbedtls_ssl_ciphersuite_t *suite); -#else -mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite( - const mbedtls_ssl_ciphersuite_t *suite); -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_read_public_xxdhe_share(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t buf_len); - -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ - -static inline int mbedtls_ssl_tls13_cipher_suite_is_offered( - mbedtls_ssl_context *ssl, int cipher_suite) -{ - const int *ciphersuite_list = ssl->conf->ciphersuite_list; - - /* Check whether we have offered this ciphersuite */ - for (size_t i = 0; ciphersuite_list[i] != 0; i++) { - if (ciphersuite_list[i] == cipher_suite) { - return 1; - } - } - return 0; -} - -/** - * \brief Validate cipher suite against config in SSL context. - * - * \param ssl SSL context - * \param suite_info Cipher suite to validate - * \param min_tls_version Minimal TLS version to accept a cipher suite - * \param max_tls_version Maximal TLS version to accept a cipher suite - * - * \return 0 if valid, negative value otherwise. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_validate_ciphersuite( - const mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *suite_info, - mbedtls_ssl_protocol_version min_tls_version, - mbedtls_ssl_protocol_version max_tls_version); - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_server_name_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end); -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) -#define MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH (2) -#define MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN (64) /* As defined in RFC 8449 */ - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end); - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_record_size_limit_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *out_len); -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_SSL_ALPN) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_alpn_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end); - - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_write_alpn_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len); -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_TEST_HOOKS) -int mbedtls_ssl_check_dtls_clihlo_cookie( - mbedtls_ssl_context *ssl, - const unsigned char *cli_id, size_t cli_id_len, - const unsigned char *in, size_t in_len, - unsigned char *obuf, size_t buf_len, size_t *olen); -#endif - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -/** - * \brief Given an SSL context and its associated configuration, write the TLS - * 1.3 specific Pre-Shared key extension. - * - * \param[in] ssl SSL context - * \param[in] buf Base address of the buffer where to write the extension - * \param[in] end End address of the buffer where to write the extension - * \param[out] out_len Length in bytes of the Pre-Shared key extension: data - * written into the buffer \p buf by this function plus - * the length of the binders to be written. - * \param[out] binders_len Length of the binders to be written at the end of - * the extension. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext( - mbedtls_ssl_context *ssl, - unsigned char *buf, unsigned char *end, - size_t *out_len, size_t *binders_len); - -/** - * \brief Given an SSL context and its associated configuration, write the TLS - * 1.3 specific Pre-Shared key extension binders at the end of the - * ClientHello. - * - * \param[in] ssl SSL context - * \param[in] buf Base address of the buffer where to write the binders - * \param[in] end End address of the buffer where to write the binders - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext( - mbedtls_ssl_context *ssl, - unsigned char *buf, unsigned char *end); -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -/** Get the host name from the SSL context. - * - * \param[in] ssl SSL context - * - * \return The \p hostname pointer from the SSL context. - * \c NULL if mbedtls_ssl_set_hostname() has never been called on - * \p ssl or if it was last called with \p NULL. - */ -const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ - defined(MBEDTLS_SSL_CLI_C) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session, - const char *hostname); -#endif - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \ - defined(MBEDTLS_SSL_ALPN) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session, - const char *alpn); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) - -#define MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME (604800) - -static inline unsigned int mbedtls_ssl_tls13_session_get_ticket_flags( - mbedtls_ssl_session *session, unsigned int flags) -{ - return session->ticket_flags & - (flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK); -} - -/** - * Check if at least one of the given flags is set in - * the session ticket. See the definition of - * `MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK` to get all - * permitted flags. - */ -static inline int mbedtls_ssl_tls13_session_ticket_has_flags( - mbedtls_ssl_session *session, unsigned int flags) -{ - return mbedtls_ssl_tls13_session_get_ticket_flags(session, flags) != 0; -} - -static inline int mbedtls_ssl_tls13_session_ticket_allow_psk( - mbedtls_ssl_session *session) -{ - return mbedtls_ssl_tls13_session_ticket_has_flags( - session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION); -} - -static inline int mbedtls_ssl_tls13_session_ticket_allow_psk_ephemeral( - mbedtls_ssl_session *session) -{ - return mbedtls_ssl_tls13_session_ticket_has_flags( - session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION); -} - -static inline unsigned int mbedtls_ssl_tls13_session_ticket_allow_early_data( - mbedtls_ssl_session *session) -{ - return mbedtls_ssl_tls13_session_ticket_has_flags( - session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA); -} - -static inline void mbedtls_ssl_tls13_session_set_ticket_flags( - mbedtls_ssl_session *session, unsigned int flags) -{ - session->ticket_flags |= (flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK); -} - -static inline void mbedtls_ssl_tls13_session_clear_ticket_flags( - mbedtls_ssl_session *session, unsigned int flags) -{ - session->ticket_flags &= ~(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK); -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) -#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT 0 -#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT 1 - -#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK \ - (1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT) -#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK \ - (1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT) - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static inline int mbedtls_ssl_conf_get_session_tickets( - const mbedtls_ssl_config *conf) -{ - return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK ? - MBEDTLS_SSL_SESSION_TICKETS_ENABLED : - MBEDTLS_SSL_SESSION_TICKETS_DISABLED; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -static inline int mbedtls_ssl_conf_is_signal_new_session_tickets_enabled( - const mbedtls_ssl_config *conf) -{ - return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK ? - MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED : - MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) -int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl); -#endif - -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - -/** Compute the HMAC of variable-length data with constant flow. - * - * This function computes the HMAC of the concatenation of \p add_data and \p - * data, and does with a code flow and memory access pattern that does not - * depend on \p data_len_secret, but only on \p min_data_len and \p - * max_data_len. In particular, this function always reads exactly \p - * max_data_len bytes from \p data. - * - * \param ctx The HMAC context. It must have keys configured - * with mbedtls_md_hmac_starts() and use one of the - * following hashes: SHA-384, SHA-256, SHA-1 or MD-5. - * It is reset using mbedtls_md_hmac_reset() after - * the computation is complete to prepare for the - * next computation. - * \param add_data The first part of the message whose HMAC is being - * calculated. This must point to a readable buffer - * of \p add_data_len bytes. - * \param add_data_len The length of \p add_data in bytes. - * \param data The buffer containing the second part of the - * message. This must point to a readable buffer - * of \p max_data_len bytes. - * \param data_len_secret The length of the data to process in \p data. - * This must be no less than \p min_data_len and no - * greater than \p max_data_len. - * \param min_data_len The minimal length of the second part of the - * message, read from \p data. - * \param max_data_len The maximal length of the second part of the - * message, read from \p data. - * \param output The HMAC will be written here. This must point to - * a writable buffer of sufficient size to hold the - * HMAC value. - * - * \retval 0 on success. - * \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED - * The hardware accelerator failed. - */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_ct_hmac(mbedtls_svc_key_id_t key, - psa_algorithm_t mac_alg, - const unsigned char *add_data, - size_t add_data_len, - const unsigned char *data, - size_t data_len_secret, - size_t min_data_len, - size_t max_data_len, - unsigned char *output); -#else -int mbedtls_ct_hmac(mbedtls_md_context_t *ctx, - const unsigned char *add_data, - size_t add_data_len, - const unsigned char *data, - size_t data_len_secret, - size_t min_data_len, - size_t max_data_len, - unsigned char *output); -#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */ -#endif /* MBEDTLS_TEST_HOOKS && defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) */ - -#endif /* ssl_misc.h */ diff --git a/vendor/mbedtls/library/ssl_msg.c b/vendor/mbedtls/library/ssl_msg.c deleted file mode 100644 index b0ab60835..000000000 --- a/vendor/mbedtls/library/ssl_msg.c +++ /dev/null @@ -1,6611 +0,0 @@ -/* - * Generic SSL/TLS messaging layer functions - * (record layer + retransmission state machine) - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * http://www.ietf.org/rfc/rfc2246.txt - * http://www.ietf.org/rfc/rfc4346.txt - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_TLS_C) - -#include "mbedtls/platform.h" - -#include "mbedtls/ssl.h" -#include "ssl_misc.h" -#include "debug_internal.h" -#include "ssl_debug_helpers.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/version.h" -#include "constant_time_internal.h" -#include "mbedtls/constant_time.h" - -#include -#include - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa_util_internal.h" -#include "psa/crypto.h" -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#include "mbedtls/oid.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) -#endif - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - -#if defined(PSA_WANT_ALG_SHA_384) -#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_384) -#elif defined(PSA_WANT_ALG_SHA_256) -#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_256) -#else /* See check_config.h */ -#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_1) -#endif - -MBEDTLS_STATIC_TESTABLE -int mbedtls_ct_hmac(mbedtls_svc_key_id_t key, - psa_algorithm_t mac_alg, - const unsigned char *add_data, - size_t add_data_len, - const unsigned char *data, - size_t data_len_secret, - size_t min_data_len, - size_t max_data_len, - unsigned char *output) -{ - /* - * This function breaks the HMAC abstraction and uses psa_hash_clone() - * extension in order to get constant-flow behaviour. - * - * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means - * concatenation, and okey/ikey are the XOR of the key with some fixed bit - * patterns (see RFC 2104, sec. 2). - * - * We'll first compute ikey/okey, then inner_hash = HASH(ikey + msg) by - * hashing up to minlen, then cloning the context, and for each byte up - * to maxlen finishing up the hash computation, keeping only the - * correct result. - * - * Then we only need to compute HASH(okey + inner_hash) and we're done. - */ - psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(mac_alg); - const size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg); - unsigned char key_buf[MAX_HASH_BLOCK_LENGTH]; - const size_t hash_size = PSA_HASH_LENGTH(hash_alg); - psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; - size_t hash_length; - - unsigned char aux_out[PSA_HASH_MAX_SIZE]; - psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT; - size_t offset; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - size_t mac_key_length; - size_t i; - -#define PSA_CHK(func_call) \ - do { \ - status = (func_call); \ - if (status != PSA_SUCCESS) \ - goto cleanup; \ - } while (0) - - /* Export MAC key - * We assume key length is always exactly the output size - * which is never more than the block size, thus we use block_size - * as the key buffer size. - */ - PSA_CHK(psa_export_key(key, key_buf, block_size, &mac_key_length)); - - /* Calculate ikey */ - for (i = 0; i < mac_key_length; i++) { - key_buf[i] = (unsigned char) (key_buf[i] ^ 0x36); - } - for (; i < block_size; ++i) { - key_buf[i] = 0x36; - } - - PSA_CHK(psa_hash_setup(&operation, hash_alg)); - - /* Now compute inner_hash = HASH(ikey + msg) */ - PSA_CHK(psa_hash_update(&operation, key_buf, block_size)); - PSA_CHK(psa_hash_update(&operation, add_data, add_data_len)); - PSA_CHK(psa_hash_update(&operation, data, min_data_len)); - - /* Fill the hash buffer in advance with something that is - * not a valid hash (barring an attack on the hash and - * deliberately-crafted input), in case the caller doesn't - * check the return status properly. */ - memset(output, '!', hash_size); - - /* For each possible length, compute the hash up to that point */ - for (offset = min_data_len; offset <= max_data_len; offset++) { - PSA_CHK(psa_hash_clone(&operation, &aux_operation)); - PSA_CHK(psa_hash_finish(&aux_operation, aux_out, - PSA_HASH_MAX_SIZE, &hash_length)); - /* Keep only the correct inner_hash in the output buffer */ - mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret), - output, aux_out, NULL, hash_size); - - if (offset < max_data_len) { - PSA_CHK(psa_hash_update(&operation, data + offset, 1)); - } - } - - /* Abort current operation to prepare for final operation */ - PSA_CHK(psa_hash_abort(&operation)); - - /* Calculate okey */ - for (i = 0; i < mac_key_length; i++) { - key_buf[i] = (unsigned char) ((key_buf[i] ^ 0x36) ^ 0x5C); - } - for (; i < block_size; ++i) { - key_buf[i] = 0x5C; - } - - /* Now compute HASH(okey + inner_hash) */ - PSA_CHK(psa_hash_setup(&operation, hash_alg)); - PSA_CHK(psa_hash_update(&operation, key_buf, block_size)); - PSA_CHK(psa_hash_update(&operation, output, hash_size)); - PSA_CHK(psa_hash_finish(&operation, output, hash_size, &hash_length)); - -#undef PSA_CHK - -cleanup: - mbedtls_platform_zeroize(key_buf, MAX_HASH_BLOCK_LENGTH); - mbedtls_platform_zeroize(aux_out, PSA_HASH_MAX_SIZE); - - psa_hash_abort(&operation); - psa_hash_abort(&aux_operation); - return PSA_TO_MBEDTLS_ERR(status); -} - -#undef MAX_HASH_BLOCK_LENGTH - -#else -MBEDTLS_STATIC_TESTABLE -int mbedtls_ct_hmac(mbedtls_md_context_t *ctx, - const unsigned char *add_data, - size_t add_data_len, - const unsigned char *data, - size_t data_len_secret, - size_t min_data_len, - size_t max_data_len, - unsigned char *output) -{ - /* - * This function breaks the HMAC abstraction and uses the md_clone() - * extension to the MD API in order to get constant-flow behaviour. - * - * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means - * concatenation, and okey/ikey are the XOR of the key with some fixed bit - * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx. - * - * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to - * minlen, then cloning the context, and for each byte up to maxlen - * finishing up the hash computation, keeping only the correct result. - * - * Then we only need to compute HASH(okey + inner_hash) and we're done. - */ - const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info); - /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5, - * all of which have the same block size except SHA-384. */ - const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64; - const unsigned char * const ikey = ctx->hmac_ctx; - const unsigned char * const okey = ikey + block_size; - const size_t hash_size = mbedtls_md_get_size(ctx->md_info); - - unsigned char aux_out[MBEDTLS_MD_MAX_SIZE]; - mbedtls_md_context_t aux; - size_t offset; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_md_init(&aux); - -#define MD_CHK(func_call) \ - do { \ - ret = (func_call); \ - if (ret != 0) \ - goto cleanup; \ - } while (0) - - MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0)); - - /* After hmac_start() of hmac_reset(), ikey has already been hashed, - * so we can start directly with the message */ - MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len)); - MD_CHK(mbedtls_md_update(ctx, data, min_data_len)); - - /* Fill the hash buffer in advance with something that is - * not a valid hash (barring an attack on the hash and - * deliberately-crafted input), in case the caller doesn't - * check the return status properly. */ - memset(output, '!', hash_size); - - /* For each possible length, compute the hash up to that point */ - for (offset = min_data_len; offset <= max_data_len; offset++) { - MD_CHK(mbedtls_md_clone(&aux, ctx)); - MD_CHK(mbedtls_md_finish(&aux, aux_out)); - /* Keep only the correct inner_hash in the output buffer */ - mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret), - output, aux_out, NULL, hash_size); - - if (offset < max_data_len) { - MD_CHK(mbedtls_md_update(ctx, data + offset, 1)); - } - } - - /* The context needs to finish() before it starts() again */ - MD_CHK(mbedtls_md_finish(ctx, aux_out)); - - /* Now compute HASH(okey + inner_hash) */ - MD_CHK(mbedtls_md_starts(ctx)); - MD_CHK(mbedtls_md_update(ctx, okey, block_size)); - MD_CHK(mbedtls_md_update(ctx, output, hash_size)); - MD_CHK(mbedtls_md_finish(ctx, output)); - - /* Done, get ready for next time */ - MD_CHK(mbedtls_md_hmac_reset(ctx)); - -#undef MD_CHK - -cleanup: - mbedtls_md_free(&aux); - return ret; -} - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - -static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl); - -/* - * Start a timer. - * Passing millisecs = 0 cancels a running timer. - */ -void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs) -{ - if (ssl->f_set_timer == NULL) { - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("set_timer to %d ms", (int) millisecs)); - ssl->f_set_timer(ssl->p_timer, millisecs / 4, millisecs); -} - -/* - * Return -1 is timer is expired, 0 if it isn't. - */ -int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl) -{ - if (ssl->f_get_timer == NULL) { - return 0; - } - - if (ssl->f_get_timer(ssl->p_timer) == 2) { - MBEDTLS_SSL_DEBUG_MSG(3, ("timer expired")); - return -1; - } - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_record_header(mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t len, - mbedtls_record *rec); - -int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t buflen) -{ - int ret = 0; - MBEDTLS_SSL_DEBUG_MSG(3, ("=> mbedtls_ssl_check_record")); - MBEDTLS_SSL_DEBUG_BUF(3, "record buffer", buf, buflen); - - /* We don't support record checking in TLS because - * there doesn't seem to be a usecase for it. - */ - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM) { - ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - goto exit; - } -#if defined(MBEDTLS_SSL_PROTO_DTLS) - else { - mbedtls_record rec; - - ret = ssl_parse_record_header(ssl, buf, buflen, &rec); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(3, "ssl_parse_record_header", ret); - goto exit; - } - - if (ssl->transform_in != NULL) { - ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, &rec); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(3, "mbedtls_ssl_decrypt_buf", ret); - goto exit; - } - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -exit: - /* On success, we have decrypted the buffer in-place, so make - * sure we don't leak any plaintext data. */ - mbedtls_platform_zeroize(buf, buflen); - - /* For the purpose of this API, treat messages with unexpected CID - * as well as such from future epochs as unexpected. */ - if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID || - ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) { - ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("<= mbedtls_ssl_check_record")); - return ret; -} - -#define SSL_DONT_FORCE_FLUSH 0 -#define SSL_FORCE_FLUSH 1 - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -/* Forward declarations for functions related to message buffering. */ -static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, - uint8_t slot); -static void ssl_buffering_shift_slots(mbedtls_ssl_context *ssl, unsigned shift); -static void ssl_free_buffered_record(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_load_buffered_message(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_load_buffered_record(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_buffer_message(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_buffer_future_record(mbedtls_ssl_context *ssl, - mbedtls_record const *rec); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl); - -static size_t ssl_get_maximum_datagram_size(mbedtls_ssl_context const *ssl) -{ - size_t mtu = mbedtls_ssl_get_current_mtu(ssl); -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len; -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif - - if (mtu != 0 && mtu < out_buf_len) { - return mtu; - } - - return out_buf_len; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const *ssl) -{ - size_t const bytes_written = ssl->out_left; - size_t const mtu = ssl_get_maximum_datagram_size(ssl); - - /* Double-check that the write-index hasn't gone - * past what we can transmit in a single datagram. */ - if (bytes_written > mtu) { - /* Should never happen... */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - return (int) (mtu - bytes_written); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t remaining, expansion; - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl); - - if (max_len > mfl) { - max_len = mfl; - } - - /* By the standard (RFC 6066 Sect. 4), the MFL extension - * only limits the maximum record payload size, so in theory - * we would be allowed to pack multiple records of payload size - * MFL into a single datagram. However, this would mean that there's - * no way to explicitly communicate MTU restrictions to the peer. - * - * The following reduction of max_len makes sure that we never - * write datagrams larger than MFL + Record Expansion Overhead. - */ - if (max_len <= ssl->out_left) { - return 0; - } - - max_len -= ssl->out_left; -#endif - - ret = ssl_get_remaining_space_in_datagram(ssl); - if (ret < 0) { - return ret; - } - remaining = (size_t) ret; - - ret = mbedtls_ssl_get_record_expansion(ssl); - if (ret < 0) { - return ret; - } - expansion = (size_t) ret; - - if (remaining <= expansion) { - return 0; - } - - remaining -= expansion; - if (remaining >= max_len) { - remaining = max_len; - } - - return (int) remaining; -} - -/* - * Double the retransmit timeout value, within the allowed range, - * returning -1 if the maximum value has already been reached. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_double_retransmit_timeout(mbedtls_ssl_context *ssl) -{ - uint32_t new_timeout; - - if (ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max) { - return -1; - } - - /* Implement the final paragraph of RFC 6347 section 4.1.1.1 - * in the following way: after the initial transmission and a first - * retransmission, back off to a temporary estimated MTU of 508 bytes. - * This value is guaranteed to be deliverable (if not guaranteed to be - * delivered) of any compliant IPv4 (and IPv6) network, and should work - * on most non-IP stacks too. */ - if (ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min) { - ssl->handshake->mtu = 508; - MBEDTLS_SSL_DEBUG_MSG(2, ("mtu autoreduction to %d bytes", ssl->handshake->mtu)); - } - - new_timeout = 2 * ssl->handshake->retransmit_timeout; - - /* Avoid arithmetic overflow and range overflow */ - if (new_timeout < ssl->handshake->retransmit_timeout || - new_timeout > ssl->conf->hs_timeout_max) { - new_timeout = ssl->conf->hs_timeout_max; - } - - ssl->handshake->retransmit_timeout = new_timeout; - MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs", - (unsigned long) ssl->handshake->retransmit_timeout)); - - return 0; -} - -static void ssl_reset_retransmit_timeout(mbedtls_ssl_context *ssl) -{ - ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; - MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs", - (unsigned long) ssl->handshake->retransmit_timeout)); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -/* - * Encryption/decryption functions - */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || defined(MBEDTLS_SSL_PROTO_TLS1_3) - -static size_t ssl_compute_padding_length(size_t len, - size_t granularity) -{ - return (granularity - (len + 1) % granularity) % granularity; -} - -/* This functions transforms a (D)TLS plaintext fragment and a record content - * type into an instance of the (D)TLSInnerPlaintext structure. This is used - * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect - * a record's content type. - * - * struct { - * opaque content[DTLSPlaintext.length]; - * ContentType real_type; - * uint8 zeros[length_of_padding]; - * } (D)TLSInnerPlaintext; - * - * Input: - * - `content`: The beginning of the buffer holding the - * plaintext to be wrapped. - * - `*content_size`: The length of the plaintext in Bytes. - * - `max_len`: The number of Bytes available starting from - * `content`. This must be `>= *content_size`. - * - `rec_type`: The desired record content type. - * - * Output: - * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure. - * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure. - * - * Returns: - * - `0` on success. - * - A negative error code if `max_len` didn't offer enough space - * for the expansion. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_build_inner_plaintext(unsigned char *content, - size_t *content_size, - size_t remaining, - uint8_t rec_type, - size_t pad) -{ - size_t len = *content_size; - - /* Write real content type */ - if (remaining == 0) { - return -1; - } - content[len] = rec_type; - len++; - remaining--; - - if (remaining < pad) { - return -1; - } - memset(content + len, 0, pad); - len += pad; - remaining -= pad; - - *content_size = len; - return 0; -} - -/* This function parses a (D)TLSInnerPlaintext structure. - * See ssl_build_inner_plaintext() for details. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_inner_plaintext(unsigned char const *content, - size_t *content_size, - uint8_t *rec_type) -{ - size_t remaining = *content_size; - - /* Determine length of padding by skipping zeroes from the back. */ - do { - if (remaining == 0) { - return -1; - } - remaining--; - } while (content[remaining] == 0); - - *content_size = remaining; - *rec_type = content[remaining]; - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || MBEDTLS_SSL_PROTO_TLS1_3 */ - -/* The size of the `add_data` structure depends on various - * factors, namely - * - * 1) CID functionality disabled - * - * additional_data = - * 8: seq_num + - * 1: type + - * 2: version + - * 2: length of inner plaintext + - * - * size = 13 bytes - * - * 2) CID functionality based on RFC 9146 enabled - * - * size = 8 + 1 + 1 + 1 + 2 + 2 + 6 + 2 + CID-length - * = 23 + CID-length - * - * 3) CID functionality based on legacy CID version - according to draft-ietf-tls-dtls-connection-id-05 - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 - * - * size = 13 + 1 + CID-length - * - * More information about the CID usage: - * - * Per Section 5.3 of draft-ietf-tls-dtls-connection-id-05 the - * size of the additional data structure is calculated as: - * - * additional_data = - * 8: seq_num + - * 1: tls12_cid + - * 2: DTLSCipherText.version + - * n: cid + - * 1: cid_length + - * 2: length_of_DTLSInnerPlaintext - * - * Per RFC 9146 the size of the add_data structure is calculated as: - * - * additional_data = - * 8: seq_num_placeholder + - * 1: tls12_cid + - * 1: cid_length + - * 1: tls12_cid + - * 2: DTLSCiphertext.version + - * 2: epoch + - * 6: sequence_number + - * n: cid + - * 2: length_of_DTLSInnerPlaintext - * - */ -static void ssl_extract_add_data_from_record(unsigned char *add_data, - size_t *add_data_len, - mbedtls_record *rec, - mbedtls_ssl_protocol_version - tls_version, - size_t taglen) -{ - /* Several types of ciphers have been defined for use with TLS and DTLS, - * and the MAC calculations for those ciphers differ slightly. Further - * variants were added when the CID functionality was added with RFC 9146. - * This implementations also considers the use of a legacy version of the - * CID specification published in draft-ietf-tls-dtls-connection-id-05, - * which is used in deployments. - * - * We will distinguish between the non-CID and the CID cases below. - * - * --- Non-CID cases --- - * - * Quoting RFC 5246 (TLS 1.2): - * - * additional_data = seq_num + TLSCompressed.type + - * TLSCompressed.version + TLSCompressed.length; - * - * For TLS 1.3, the record sequence number is dropped from the AAD - * and encoded within the nonce of the AEAD operation instead. - * Moreover, the additional data involves the length of the TLS - * ciphertext, not the TLS plaintext as in earlier versions. - * Quoting RFC 8446 (TLS 1.3): - * - * additional_data = TLSCiphertext.opaque_type || - * TLSCiphertext.legacy_record_version || - * TLSCiphertext.length - * - * We pass the tag length to this function in order to compute the - * ciphertext length from the inner plaintext length rec->data_len via - * - * TLSCiphertext.length = TLSInnerPlaintext.length + taglen. - * - * --- CID cases --- - * - * RFC 9146 uses a common pattern when constructing the data - * passed into a MAC / AEAD cipher. - * - * Data concatenation for MACs used with block ciphers with - * Encrypt-then-MAC Processing (with CID): - * - * data = seq_num_placeholder + - * tls12_cid + - * cid_length + - * tls12_cid + - * DTLSCiphertext.version + - * epoch + - * sequence_number + - * cid + - * DTLSCiphertext.length + - * IV + - * ENC(content + padding + padding_length) - * - * Data concatenation for MACs used with block ciphers (with CID): - * - * data = seq_num_placeholder + - * tls12_cid + - * cid_length + - * tls12_cid + - * DTLSCiphertext.version + - * epoch + - * sequence_number + - * cid + - * length_of_DTLSInnerPlaintext + - * DTLSInnerPlaintext.content + - * DTLSInnerPlaintext.real_type + - * DTLSInnerPlaintext.zeros - * - * AEAD ciphers use the following additional data calculation (with CIDs): - * - * additional_data = seq_num_placeholder + - * tls12_cid + - * cid_length + - * tls12_cid + - * DTLSCiphertext.version + - * epoch + - * sequence_number + - * cid + - * length_of_DTLSInnerPlaintext - * - * Section 5.3 of draft-ietf-tls-dtls-connection-id-05 (for legacy CID use) - * defines the additional data calculation as follows: - * - * additional_data = seq_num + - * tls12_cid + - * DTLSCipherText.version + - * cid + - * cid_length + - * length_of_DTLSInnerPlaintext - */ - - unsigned char *cur = add_data; - size_t ad_len_field = rec->data_len; - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0 - const unsigned char seq_num_placeholder[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - /* In TLS 1.3, the AAD contains the length of the TLSCiphertext, - * which differs from the length of the TLSInnerPlaintext - * by the length of the authentication tag. */ - ad_len_field += taglen; - } else -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - { - ((void) tls_version); - ((void) taglen); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0 - if (rec->cid_len != 0) { - // seq_num_placeholder - memcpy(cur, seq_num_placeholder, sizeof(seq_num_placeholder)); - cur += sizeof(seq_num_placeholder); - - // tls12_cid type - *cur = rec->type; - cur++; - - // cid_length - *cur = rec->cid_len; - cur++; - } else -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - { - // epoch + sequence number - memcpy(cur, rec->ctr, sizeof(rec->ctr)); - cur += sizeof(rec->ctr); - } - } - - // type - *cur = rec->type; - cur++; - - // version - memcpy(cur, rec->ver, sizeof(rec->ver)); - cur += sizeof(rec->ver); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 1 - - if (rec->cid_len != 0) { - // CID - memcpy(cur, rec->cid, rec->cid_len); - cur += rec->cid_len; - - // cid_length - *cur = rec->cid_len; - cur++; - - // length of inner plaintext - MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0); - cur += 2; - } else -#elif defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ - MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0 - - if (rec->cid_len != 0) { - // epoch + sequence number - memcpy(cur, rec->ctr, sizeof(rec->ctr)); - cur += sizeof(rec->ctr); - - // CID - memcpy(cur, rec->cid, rec->cid_len); - cur += rec->cid_len; - - // length of inner plaintext - MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0); - cur += 2; - } else -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - { - MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0); - cur += 2; - } - - *add_data_len = (size_t) (cur - add_data); -} - -#if defined(MBEDTLS_SSL_HAVE_AEAD) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_transform_aead_dynamic_iv_is_explicit( - mbedtls_ssl_transform const *transform) -{ - return transform->ivlen != transform->fixed_ivlen; -} - -/* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV ) - * - * Concretely, this occurs in two variants: - * - * a) Fixed and dynamic IV lengths add up to total IV length, giving - * IV = fixed_iv || dynamic_iv - * - * This variant is used in TLS 1.2 when used with GCM or CCM. - * - * b) Fixed IV lengths matches total IV length, giving - * IV = fixed_iv XOR ( 0 || dynamic_iv ) - * - * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly. - * - * See also the documentation of mbedtls_ssl_transform. - * - * This function has the precondition that - * - * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len ) - * - * which has to be ensured by the caller. If this precondition - * violated, the behavior of this function is undefined. - */ -static void ssl_build_record_nonce(unsigned char *dst_iv, - size_t dst_iv_len, - unsigned char const *fixed_iv, - size_t fixed_iv_len, - unsigned char const *dynamic_iv, - size_t dynamic_iv_len) -{ - /* Start with Fixed IV || 0 */ - memset(dst_iv, 0, dst_iv_len); - memcpy(dst_iv, fixed_iv, fixed_iv_len); - - dst_iv += dst_iv_len - dynamic_iv_len; - mbedtls_xor(dst_iv, dst_iv, dynamic_iv, dynamic_iv_len); -} -#endif /* MBEDTLS_SSL_HAVE_AEAD */ - -int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - mbedtls_ssl_mode_t ssl_mode; - int auth_done = 0; - unsigned char *data; - /* For an explanation of the additional data length see - * the description of ssl_extract_add_data_from_record(). - */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char add_data[23 + MBEDTLS_SSL_CID_OUT_LEN_MAX]; -#else - unsigned char add_data[13]; -#endif - size_t add_data_len; - size_t post_avail; - - /* The SSL context is only used for debugging purposes! */ -#if !defined(MBEDTLS_DEBUG_C) - ssl = NULL; /* make sure we don't use it except for debug */ - ((void) ssl); -#endif - - /* The PRNG is used for dynamic IV generation that's used - * for CBC transformations in TLS 1.2. */ -#if !(defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2)) - ((void) f_rng); - ((void) p_rng); -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> encrypt buf")); - - if (transform == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no transform provided to encrypt_buf")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - if (rec == NULL - || rec->buf == NULL - || rec->buf_len < rec->data_offset - || rec->buf_len - rec->data_offset < rec->data_len -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - || rec->cid_len != 0 -#endif - ) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to encrypt_buf")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ssl_mode = mbedtls_ssl_get_mode_from_transform(transform); - - data = rec->buf + rec->data_offset; - post_avail = rec->buf_len - (rec->data_len + rec->data_offset); - MBEDTLS_SSL_DEBUG_BUF(4, "before encrypt: output payload", - data, rec->data_len); - - if (rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Record content %" MBEDTLS_PRINTF_SIZET - " too large, maximum %" MBEDTLS_PRINTF_SIZET, - rec->data_len, - (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* The following two code paths implement the (D)TLSInnerPlaintext - * structure present in TLS 1.3 and DTLS 1.2 + CID. - * - * See ssl_build_inner_plaintext() for more information. - * - * Note that this changes `rec->data_len`, and hence - * `post_avail` needs to be recalculated afterwards. - * - * Note also that the two code paths cannot occur simultaneously - * since they apply to different versions of the protocol. There - * is hence no risk of double-addition of the inner plaintext. - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - size_t padding = - ssl_compute_padding_length(rec->data_len, - MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY); - if (ssl_build_inner_plaintext(data, - &rec->data_len, - post_avail, - rec->type, - padding) != 0) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* - * Add CID information - */ - rec->cid_len = transform->out_cid_len; - memcpy(rec->cid, transform->out_cid, transform->out_cid_len); - MBEDTLS_SSL_DEBUG_BUF(3, "CID", rec->cid, rec->cid_len); - - if (rec->cid_len != 0) { - size_t padding = - ssl_compute_padding_length(rec->data_len, - MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY); - /* - * Wrap plaintext into DTLSInnerPlaintext structure. - * See ssl_build_inner_plaintext() for more information. - * - * Note that this changes `rec->data_len`, and hence - * `post_avail` needs to be recalculated afterwards. - */ - if (ssl_build_inner_plaintext(data, - &rec->data_len, - post_avail, - rec->type, - padding) != 0) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - rec->type = MBEDTLS_SSL_MSG_CID; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - post_avail = rec->buf_len - (rec->data_len + rec->data_offset); - - /* - * Add MAC before if needed - */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - if (ssl_mode == MBEDTLS_SSL_MODE_STREAM || - ssl_mode == MBEDTLS_SSL_MODE_CBC) { - if (post_avail < transform->maclen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t sign_mac_length = 0; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - ssl_extract_add_data_from_record(add_data, &add_data_len, rec, - transform->tls_version, - transform->taglen); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_mac_sign_setup(&operation, transform->psa_mac_enc, - transform->psa_mac_alg); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_disabled; - } - - status = psa_mac_update(&operation, add_data, add_data_len); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_disabled; - } - - status = psa_mac_update(&operation, data, rec->data_len); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_disabled; - } - - status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD, - &sign_mac_length); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_disabled; - } -#else - ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data, - add_data_len); - if (ret != 0) { - goto hmac_failed_etm_disabled; - } - ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, data, rec->data_len); - if (ret != 0) { - goto hmac_failed_etm_disabled; - } - ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac); - if (ret != 0) { - goto hmac_failed_etm_disabled; - } - ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc); - if (ret != 0) { - goto hmac_failed_etm_disabled; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - memcpy(data + rec->data_len, mac, transform->maclen); -#endif - - MBEDTLS_SSL_DEBUG_BUF(4, "computed mac", data + rec->data_len, - transform->maclen); - - rec->data_len += transform->maclen; - post_avail -= transform->maclen; - auth_done++; - -hmac_failed_etm_disabled: - mbedtls_platform_zeroize(mac, transform->maclen); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = PSA_TO_MBEDTLS_ERR(status); - status = psa_mac_abort(&operation); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_hmac_xxx", ret); - return ret; - } - } -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - - /* - * Encrypt - */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM) - if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) { - MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " - "including %d bytes of padding", - rec->data_len, 0)); - - /* The only supported stream cipher is "NULL", - * so there's nothing to do here.*/ - } else -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */ - -#if defined(MBEDTLS_SSL_HAVE_AEAD) - if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) { - unsigned char iv[12]; - unsigned char *dynamic_iv; - size_t dynamic_iv_len; - int dynamic_iv_is_explicit = - ssl_transform_aead_dynamic_iv_is_explicit(transform); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Check that there's space for the authentication tag. */ - if (post_avail < transform->taglen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - /* - * Build nonce for AEAD encryption. - * - * Note: In the case of CCM and GCM in TLS 1.2, the dynamic - * part of the IV is prepended to the ciphertext and - * can be chosen freely - in particular, it need not - * agree with the record sequence number. - * However, since ChaChaPoly as well as all AEAD modes - * in TLS 1.3 use the record sequence number as the - * dynamic part of the nonce, we uniformly use the - * record sequence number here in all cases. - */ - dynamic_iv = rec->ctr; - dynamic_iv_len = sizeof(rec->ctr); - - ssl_build_record_nonce(iv, sizeof(iv), - transform->iv_enc, - transform->fixed_ivlen, - dynamic_iv, - dynamic_iv_len); - - /* - * Build additional data for AEAD encryption. - * This depends on the TLS version. - */ - ssl_extract_add_data_from_record(add_data, &add_data_len, rec, - transform->tls_version, - transform->taglen); - - MBEDTLS_SSL_DEBUG_BUF(4, "IV used (internal)", - iv, transform->ivlen); - MBEDTLS_SSL_DEBUG_BUF(4, "IV used (transmitted)", - dynamic_iv, - dynamic_iv_is_explicit ? dynamic_iv_len : 0); - MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD", - add_data, add_data_len); - MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " - "including 0 bytes of padding", - rec->data_len)); - - /* - * Encrypt and authenticate - */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_aead_encrypt(transform->psa_key_enc, - transform->psa_alg, - iv, transform->ivlen, - add_data, add_data_len, - data, rec->data_len, - data, rec->buf_len - (data - rec->buf), - &rec->data_len); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_encrypt_buf", ret); - return ret; - } -#else - if ((ret = mbedtls_cipher_auth_encrypt_ext(&transform->cipher_ctx_enc, - iv, transform->ivlen, - add_data, add_data_len, - data, rec->data_len, /* src */ - data, rec->buf_len - (size_t) (data - rec->buf), /* dst */ - &rec->data_len, - transform->taglen)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_encrypt_ext", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - MBEDTLS_SSL_DEBUG_BUF(4, "after encrypt: tag", - data + rec->data_len - transform->taglen, - transform->taglen); - /* Account for authentication tag. */ - post_avail -= transform->taglen; - - /* - * Prefix record content with dynamic IV in case it is explicit. - */ - if (dynamic_iv_is_explicit != 0) { - if (rec->data_offset < dynamic_iv_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - memcpy(data - dynamic_iv_len, dynamic_iv, dynamic_iv_len); - rec->data_offset -= dynamic_iv_len; - rec->data_len += dynamic_iv_len; - } - - auth_done++; - } else -#endif /* MBEDTLS_SSL_HAVE_AEAD */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) - if (ssl_mode == MBEDTLS_SSL_MODE_CBC || - ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t padlen, i; - size_t olen; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t part_len; - psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* Currently we're always using minimal padding - * (up to 255 bytes would be allowed). */ - padlen = transform->ivlen - (rec->data_len + 1) % transform->ivlen; - if (padlen == transform->ivlen) { - padlen = 0; - } - - /* Check there's enough space in the buffer for the padding. */ - if (post_avail < padlen + 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - for (i = 0; i <= padlen; i++) { - data[rec->data_len + i] = (unsigned char) padlen; - } - - rec->data_len += padlen + 1; - post_avail -= padlen + 1; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Prepend per-record IV for block cipher in TLS v1.2 as per - * Method 1 (6.2.3.2. in RFC4346 and RFC5246) - */ - if (f_rng == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("No PRNG provided to encrypt_record routine")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if (rec->data_offset < transform->ivlen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - /* - * Generate IV - */ - ret = f_rng(p_rng, transform->iv_enc, transform->ivlen); - if (ret != 0) { - return ret; - } - - memcpy(data - transform->ivlen, transform->iv_enc, transform->ivlen); -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " - "including %" - MBEDTLS_PRINTF_SIZET - " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding", - rec->data_len, transform->ivlen, - padlen + 1)); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_cipher_encrypt_setup(&cipher_op, - transform->psa_key_enc, transform->psa_alg); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_encrypt_setup", ret); - return ret; - } - - status = psa_cipher_set_iv(&cipher_op, transform->iv_enc, transform->ivlen); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret); - return ret; - - } - - status = psa_cipher_update(&cipher_op, - data, rec->data_len, - data, rec->data_len, &olen); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret); - return ret; - - } - - status = psa_cipher_finish(&cipher_op, - data + olen, rec->data_len - olen, - &part_len); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret); - return ret; - - } - - olen += part_len; -#else - if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_enc, - transform->iv_enc, - transform->ivlen, - data, rec->data_len, - data, &olen)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (rec->data_len != olen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - data -= transform->ivlen; - rec->data_offset -= transform->ivlen; - rec->data_len += transform->ivlen; - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if (auth_done == 0) { - unsigned char mac[MBEDTLS_SSL_MAC_ADD]; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - size_t sign_mac_length = 0; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* MAC(MAC_write_key, add_data, IV, ENC(content + padding + padding_length)) - */ - - if (post_avail < transform->maclen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - ssl_extract_add_data_from_record(add_data, &add_data_len, - rec, transform->tls_version, - transform->taglen); - - MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac")); - MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data, - add_data_len); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_mac_sign_setup(&operation, transform->psa_mac_enc, - transform->psa_mac_alg); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } - - status = psa_mac_update(&operation, add_data, add_data_len); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } - - status = psa_mac_update(&operation, data, rec->data_len); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } - - status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD, - &sign_mac_length); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } -#else - - ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data, - add_data_len); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } - ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, - data, rec->data_len); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } - ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } - ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - memcpy(data + rec->data_len, mac, transform->maclen); - - rec->data_len += transform->maclen; - post_avail -= transform->maclen; - auth_done++; - -hmac_failed_etm_enabled: - mbedtls_platform_zeroize(mac, transform->maclen); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = PSA_TO_MBEDTLS_ERR(status); - status = psa_mac_abort(&operation); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "HMAC calculation failed", ret); - return ret; - } - } -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - } else -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Make extra sure authentication was performed, exactly once */ - if (auth_done != 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= encrypt buf")); - - return 0; -} - -int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl, - mbedtls_ssl_transform *transform, - mbedtls_record *rec) -{ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) || defined(MBEDTLS_SSL_HAVE_AEAD) - size_t olen; -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC || MBEDTLS_SSL_HAVE_AEAD */ - mbedtls_ssl_mode_t ssl_mode; - int ret; - - int auth_done = 0; -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - size_t padlen = 0; - mbedtls_ct_condition_t correct = MBEDTLS_CT_TRUE; -#endif - unsigned char *data; - /* For an explanation of the additional data length see - * the description of ssl_extract_add_data_from_record(). - */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char add_data[23 + MBEDTLS_SSL_CID_IN_LEN_MAX]; -#else - unsigned char add_data[13]; -#endif - size_t add_data_len; - -#if !defined(MBEDTLS_DEBUG_C) - ssl = NULL; /* make sure we don't use it except for debug */ - ((void) ssl); -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> decrypt buf")); - if (rec == NULL || - rec->buf == NULL || - rec->buf_len < rec->data_offset || - rec->buf_len - rec->data_offset < rec->data_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to decrypt_buf")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - data = rec->buf + rec->data_offset; - ssl_mode = mbedtls_ssl_get_mode_from_transform(transform); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* - * Match record's CID with incoming CID. - */ - if (rec->cid_len != transform->in_cid_len || - memcmp(rec->cid, transform->in_cid, rec->cid_len) != 0) { - return MBEDTLS_ERR_SSL_UNEXPECTED_CID; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM) - if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) { - if (rec->data_len < transform->maclen) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Record too short for MAC:" - " %" MBEDTLS_PRINTF_SIZET " < %" MBEDTLS_PRINTF_SIZET, - rec->data_len, transform->maclen)); - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - - /* The only supported stream cipher is "NULL", - * so there's no encryption to do here.*/ - } else -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */ -#if defined(MBEDTLS_SSL_HAVE_AEAD) - if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) { - unsigned char iv[12]; - unsigned char *dynamic_iv; - size_t dynamic_iv_len; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* - * Extract dynamic part of nonce for AEAD decryption. - * - * Note: In the case of CCM and GCM in TLS 1.2, the dynamic - * part of the IV is prepended to the ciphertext and - * can be chosen freely - in particular, it need not - * agree with the record sequence number. - */ - dynamic_iv_len = sizeof(rec->ctr); - if (ssl_transform_aead_dynamic_iv_is_explicit(transform) == 1) { - if (rec->data_len < dynamic_iv_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET - " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ", - rec->data_len, - dynamic_iv_len)); - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - dynamic_iv = data; - - data += dynamic_iv_len; - rec->data_offset += dynamic_iv_len; - rec->data_len -= dynamic_iv_len; - } else { - dynamic_iv = rec->ctr; - } - - /* Check that there's space for the authentication tag. */ - if (rec->data_len < transform->taglen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET - ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ", - rec->data_len, - transform->taglen)); - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - rec->data_len -= transform->taglen; - - /* - * Prepare nonce from dynamic and static parts. - */ - ssl_build_record_nonce(iv, sizeof(iv), - transform->iv_dec, - transform->fixed_ivlen, - dynamic_iv, - dynamic_iv_len); - - /* - * Build additional data for AEAD encryption. - * This depends on the TLS version. - */ - ssl_extract_add_data_from_record(add_data, &add_data_len, rec, - transform->tls_version, - transform->taglen); - MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD", - add_data, add_data_len); - - /* Because of the check above, we know that there are - * explicit_iv_len Bytes preceding data, and taglen - * bytes following data + data_len. This justifies - * the debug message and the invocation of - * mbedtls_cipher_auth_decrypt_ext() below. */ - - MBEDTLS_SSL_DEBUG_BUF(4, "IV used", iv, transform->ivlen); - MBEDTLS_SSL_DEBUG_BUF(4, "TAG used", data + rec->data_len, - transform->taglen); - - /* - * Decrypt and authenticate - */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_aead_decrypt(transform->psa_key_dec, - transform->psa_alg, - iv, transform->ivlen, - add_data, add_data_len, - data, rec->data_len + transform->taglen, - data, rec->buf_len - (data - rec->buf), - &olen); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_aead_decrypt", ret); - return ret; - } -#else - if ((ret = mbedtls_cipher_auth_decrypt_ext - (&transform->cipher_ctx_dec, - iv, transform->ivlen, - add_data, add_data_len, - data, rec->data_len + transform->taglen, /* src */ - data, rec->buf_len - (size_t) (data - rec->buf), &olen, /* dst */ - transform->taglen)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_decrypt_ext", ret); - - if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) { - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - auth_done++; - - /* Double-check that AEAD decryption doesn't change content length. */ - if (olen != rec->data_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - } else -#endif /* MBEDTLS_SSL_HAVE_AEAD */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) - if (ssl_mode == MBEDTLS_SSL_MODE_CBC || - ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { - size_t minlen = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t part_len; - psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* - * Check immediate ciphertext sanity - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* The ciphertext is prefixed with the CBC IV. */ - minlen += transform->ivlen; -#endif - - /* Size considerations: - * - * - The CBC cipher text must not be empty and hence - * at least of size transform->ivlen. - * - * Together with the potential IV-prefix, this explains - * the first of the two checks below. - * - * - The record must contain a MAC, either in plain or - * encrypted, depending on whether Encrypt-then-MAC - * is used or not. - * - If it is, the message contains the IV-prefix, - * the CBC ciphertext, and the MAC. - * - If it is not, the padded plaintext, and hence - * the CBC ciphertext, has at least length maclen + 1 - * because there is at least the padding length byte. - * - * As the CBC ciphertext is not empty, both cases give the - * lower bound minlen + maclen + 1 on the record size, which - * we test for in the second check below. - */ - if (rec->data_len < minlen + transform->ivlen || - rec->data_len < minlen + transform->maclen + 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET - ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET - "), maclen (%" MBEDTLS_PRINTF_SIZET ") " - "+ 1 ) ( + expl IV )", - rec->data_len, - transform->ivlen, - transform->maclen)); - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - - /* - * Authenticate before decrypt if enabled - */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if (ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; -#else - unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac")); - - /* Update data_len in tandem with add_data. - * - * The subtraction is safe because of the previous check - * data_len >= minlen + maclen + 1. - * - * Afterwards, we know that data + data_len is followed by at - * least maclen Bytes, which justifies the call to - * mbedtls_ct_memcmp() below. - * - * Further, we still know that data_len > minlen */ - rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record(add_data, &add_data_len, rec, - transform->tls_version, - transform->taglen); - - /* Calculate expected MAC. */ - MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data, - add_data_len); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_mac_verify_setup(&operation, transform->psa_mac_dec, - transform->psa_mac_alg); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } - - status = psa_mac_update(&operation, add_data, add_data_len); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } - - status = psa_mac_update(&operation, data, rec->data_len); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } - - /* Compare expected MAC with MAC at the end of the record. */ - status = psa_mac_verify_finish(&operation, data + rec->data_len, - transform->maclen); - if (status != PSA_SUCCESS) { - goto hmac_failed_etm_enabled; - } -#else - ret = mbedtls_md_hmac_update(&transform->md_ctx_dec, add_data, - add_data_len); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } - ret = mbedtls_md_hmac_update(&transform->md_ctx_dec, - data, rec->data_len); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } - ret = mbedtls_md_hmac_finish(&transform->md_ctx_dec, mac_expect); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } - ret = mbedtls_md_hmac_reset(&transform->md_ctx_dec); - if (ret != 0) { - goto hmac_failed_etm_enabled; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "message mac", data + rec->data_len, - transform->maclen); - MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, - transform->maclen); - - /* Compare expected MAC with MAC at the end of the record. */ - if (mbedtls_ct_memcmp(data + rec->data_len, mac_expect, - transform->maclen) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match")); - ret = MBEDTLS_ERR_SSL_INVALID_MAC; - goto hmac_failed_etm_enabled; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - auth_done++; - -hmac_failed_etm_enabled: -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = PSA_TO_MBEDTLS_ERR(status); - status = psa_mac_abort(&operation); - if (ret == 0 && status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - } -#else - mbedtls_platform_zeroize(mac_expect, transform->maclen); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (ret != 0) { - if (ret != MBEDTLS_ERR_SSL_INVALID_MAC) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_hmac_xxx", ret); - } - return ret; - } - } -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - - /* - * Check length sanity - */ - - /* We know from above that data_len > minlen >= 0, - * so the following check in particular implies that - * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */ - if (rec->data_len % transform->ivlen != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET - ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0", - rec->data_len, transform->ivlen)); - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Initialize for prepended IV for block cipher in TLS v1.2 - */ - /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */ - memcpy(transform->iv_dec, data, transform->ivlen); - - data += transform->ivlen; - rec->data_offset += transform->ivlen; - rec->data_len -= transform->ivlen; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_cipher_decrypt_setup(&cipher_op, - transform->psa_key_dec, transform->psa_alg); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_decrypt_setup", ret); - return ret; - } - - status = psa_cipher_set_iv(&cipher_op, transform->iv_dec, transform->ivlen); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret); - return ret; - } - - status = psa_cipher_update(&cipher_op, - data, rec->data_len, - data, rec->data_len, &olen); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret); - return ret; - } - - status = psa_cipher_finish(&cipher_op, - data + olen, rec->data_len - olen, - &part_len); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret); - return ret; - } - - olen += part_len; -#else - - if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_dec, - transform->iv_dec, transform->ivlen, - data, rec->data_len, data, &olen)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* Double-check that length hasn't changed during decryption. */ - if (rec->data_len != olen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Safe since data_len >= minlen + maclen + 1, so after having - * subtracted at most minlen and maclen up to this point, - * data_len > 0 (because of data_len % ivlen == 0, it's actually - * >= ivlen ). */ - padlen = data[rec->data_len - 1]; - - if (auth_done == 1) { - const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge( - rec->data_len, - padlen + 1); - correct = mbedtls_ct_bool_and(ge, correct); - padlen = mbedtls_ct_size_if_else_0(ge, padlen); - } else { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - if (rec->data_len < transform->maclen + padlen + 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET - ") < maclen (%" MBEDTLS_PRINTF_SIZET - ") + padlen (%" MBEDTLS_PRINTF_SIZET ")", - rec->data_len, - transform->maclen, - padlen + 1)); - } -#endif - const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge( - rec->data_len, - transform->maclen + padlen + 1); - correct = mbedtls_ct_bool_and(ge, correct); - padlen = mbedtls_ct_size_if_else_0(ge, padlen); - } - - padlen++; - - /* Regardless of the validity of the padding, - * we have data_len >= padlen here. */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* The padding check involves a series of up to 256 - * consecutive memory reads at the end of the record - * plaintext buffer. In order to hide the length and - * validity of the padding, always perform exactly - * `min(256,plaintext_len)` reads (but take into account - * only the last `padlen` bytes for the padding check). */ - size_t pad_count = 0; - volatile unsigned char * const check = data; - - /* Index of first padding byte; it has been ensured above - * that the subtraction is safe. */ - size_t const padding_idx = rec->data_len - padlen; - size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256; - size_t const start_idx = rec->data_len - num_checks; - size_t idx; - - for (idx = start_idx; idx < rec->data_len; idx++) { - /* pad_count += (idx >= padding_idx) && - * (check[idx] == padlen - 1); - */ - const mbedtls_ct_condition_t a = mbedtls_ct_uint_ge(idx, padding_idx); - size_t increment = mbedtls_ct_size_if_else_0(a, 1); - const mbedtls_ct_condition_t b = mbedtls_ct_uint_eq(check[idx], padlen - 1); - increment = mbedtls_ct_size_if_else_0(b, increment); - pad_count += increment; - } - correct = mbedtls_ct_bool_and(mbedtls_ct_uint_eq(pad_count, padlen), correct); - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - if (padlen > 0 && correct == MBEDTLS_CT_FALSE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected")); - } -#endif - padlen = mbedtls_ct_size_if_else_0(correct, padlen); - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - /* If the padding was found to be invalid, padlen == 0 - * and the subtraction is safe. If the padding was found valid, - * padlen hasn't been changed and the previous assertion - * data_len >= padlen still holds. */ - rec->data_len -= padlen; - } else -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_BUF(4, "raw buffer after decryption", - data, rec->data_len); -#endif - - /* - * Authenticate if not done yet. - * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). - */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - if (auth_done == 0) { - unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 }; - unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 }; - - /* For CBC+MAC, If the initial value of padlen was such that - * data_len < maclen + padlen + 1, then padlen - * got reset to 1, and the initial check - * data_len >= minlen + maclen + 1 - * guarantees that at this point we still - * have at least data_len >= maclen. - * - * If the initial value of padlen was such that - * data_len >= maclen + padlen + 1, then we have - * subtracted either padlen + 1 (if the padding was correct) - * or 0 (if the padding was incorrect) since then, - * hence data_len >= maclen in any case. - * - * For stream ciphers, we checked above that - * data_len >= maclen. - */ - rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record(add_data, &add_data_len, rec, - transform->tls_version, - transform->taglen); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * The next two sizes are the minimum and maximum values of - * data_len over all padlen values. - * - * They're independent of padlen, since we previously did - * data_len -= padlen. - * - * Note that max_len + maclen is never more than the buffer - * length, as we previously did in_msglen -= maclen too. - */ - const size_t max_len = rec->data_len + padlen; - const size_t min_len = (max_len > 256) ? max_len - 256 : 0; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = mbedtls_ct_hmac(transform->psa_mac_dec, - transform->psa_mac_alg, - add_data, add_data_len, - data, rec->data_len, min_len, max_len, - mac_expect); -#else - ret = mbedtls_ct_hmac(&transform->md_ctx_dec, - add_data, add_data_len, - data, rec->data_len, min_len, max_len, - mac_expect); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ct_hmac", ret); - goto hmac_failed_etm_disabled; - } - - mbedtls_ct_memcpy_offset(mac_peer, data, - rec->data_len, - min_len, max_len, - transform->maclen); -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, transform->maclen); - MBEDTLS_SSL_DEBUG_BUF(4, "message mac", mac_peer, transform->maclen); -#endif - - if (mbedtls_ct_memcmp(mac_peer, mac_expect, - transform->maclen) != 0) { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match")); -#endif - correct = MBEDTLS_CT_FALSE; - } - auth_done++; - -hmac_failed_etm_disabled: - mbedtls_platform_zeroize(mac_peer, transform->maclen); - mbedtls_platform_zeroize(mac_expect, transform->maclen); - if (ret != 0) { - return ret; - } - } - - /* - * Finally check the correct flag - */ - if (correct == MBEDTLS_CT_FALSE) { - return MBEDTLS_ERR_SSL_INVALID_MAC; - } -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - - /* Make extra sure authentication was performed, exactly once */ - if (auth_done != 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - /* Remove inner padding and infer true content type. */ - ret = ssl_parse_inner_plaintext(data, &rec->data_len, - &rec->type); - - if (ret != 0) { - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if (rec->cid_len != 0) { - ret = ssl_parse_inner_plaintext(data, &rec->data_len, - &rec->type); - if (ret != 0) { - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= decrypt buf")); - - return 0; -} - -#undef MAC_NONE -#undef MAC_PLAINTEXT -#undef MAC_CIPHERTEXT - -/* - * Fill the input message buffer by appending data to it. - * The amount of data already fetched is in ssl->in_left. - * - * If we return 0, is it guaranteed that (at least) nb_want bytes are - * available (from this read and/or a previous one). Otherwise, an error code - * is returned (possibly EOF or WANT_READ). - * - * With stream transport (TLS) on success ssl->in_left == nb_want, but - * with datagram transport (DTLS) on success ssl->in_left >= nb_want, - * since we always read a whole datagram at once. - * - * For DTLS, it is up to the caller to set ssl->next_record_offset when - * they're done reading a record. - */ -int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> fetch input")); - - if (ssl->f_recv == NULL && ssl->f_recv_timeout == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() ")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (nb_want > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("requesting more data than fits")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - uint32_t timeout; - - /* - * The point is, we need to always read a full datagram at once, so we - * sometimes read more then requested, and handle the additional data. - * It could be the rest of the current record (while fetching the - * header) and/or some other records in the same datagram. - */ - - /* - * Move to the next record in the already read datagram if applicable - */ - if (ssl->next_record_offset != 0) { - if (ssl->in_left < ssl->next_record_offset) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ssl->in_left -= ssl->next_record_offset; - - if (ssl->in_left != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("next record in same datagram, offset: %" - MBEDTLS_PRINTF_SIZET, - ssl->next_record_offset)); - memmove(ssl->in_hdr, - ssl->in_hdr + ssl->next_record_offset, - ssl->in_left); - } - - ssl->next_record_offset = 0; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET - ", nb_want: %" MBEDTLS_PRINTF_SIZET, - ssl->in_left, nb_want)); - - /* - * Done if we already have enough data. - */ - if (nb_want <= ssl->in_left) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input")); - return 0; - } - - /* - * A record can't be split across datagrams. If we need to read but - * are not at the beginning of a new record, the caller did something - * wrong. - */ - if (ssl->in_left != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* - * Don't even try to read if time's out already. - * This avoids by-passing the timer when repeatedly receiving messages - * that will end up being dropped. - */ - if (mbedtls_ssl_check_timer(ssl) != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("timer has expired")); - ret = MBEDTLS_ERR_SSL_TIMEOUT; - } else { - len = in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf); - - if (mbedtls_ssl_is_handshake_over(ssl) == 0) { - timeout = ssl->handshake->retransmit_timeout; - } else { - timeout = ssl->conf->read_timeout; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("f_recv_timeout: %lu ms", (unsigned long) timeout)); - - if (ssl->f_recv_timeout != NULL) { - ret = ssl->f_recv_timeout(ssl->p_bio, ssl->in_hdr, len, - timeout); - } else { - ret = ssl->f_recv(ssl->p_bio, ssl->in_hdr, len); - } - - MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret); - - if (ret == 0) { - return MBEDTLS_ERR_SSL_CONN_EOF; - } - } - - if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { - MBEDTLS_SSL_DEBUG_MSG(2, ("timeout")); - mbedtls_ssl_set_timer(ssl, 0); - - if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { - if (ssl_double_retransmit_timeout(ssl) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("handshake timeout")); - return MBEDTLS_ERR_SSL_TIMEOUT; - } - - if ((ret = mbedtls_ssl_resend(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret); - return ret; - } - - return MBEDTLS_ERR_SSL_WANT_READ; - } -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - else if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) { - if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request", - ret); - return ret; - } - - return MBEDTLS_ERR_SSL_WANT_READ; - } -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ - } - - if (ret < 0) { - return ret; - } - - ssl->in_left = ret; - } else -#endif - { - MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET - ", nb_want: %" MBEDTLS_PRINTF_SIZET, - ssl->in_left, nb_want)); - - while (ssl->in_left < nb_want) { - len = nb_want - ssl->in_left; - - if (mbedtls_ssl_check_timer(ssl) != 0) { - ret = MBEDTLS_ERR_SSL_TIMEOUT; - } else { - if (ssl->f_recv_timeout != NULL) { - ret = ssl->f_recv_timeout(ssl->p_bio, - ssl->in_hdr + ssl->in_left, len, - ssl->conf->read_timeout); - } else { - ret = ssl->f_recv(ssl->p_bio, - ssl->in_hdr + ssl->in_left, len); - } - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET - ", nb_want: %" MBEDTLS_PRINTF_SIZET, - ssl->in_left, nb_want)); - MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret); - - if (ret == 0) { - return MBEDTLS_ERR_SSL_CONN_EOF; - } - - if (ret < 0) { - return ret; - } - - if ((size_t) ret > len) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET - " were requested", - ret, len)); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ssl->in_left += ret; - } - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input")); - - return 0; -} - -/* - * Flush any data not yet written - */ -int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> flush output")); - - if (ssl->f_send == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() ")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* Avoid incrementing counter if data is flushed */ - if (ssl->out_left == 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output")); - return 0; - } - - while (ssl->out_left > 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("message length: %" MBEDTLS_PRINTF_SIZET - ", out_left: %" MBEDTLS_PRINTF_SIZET, - mbedtls_ssl_out_hdr_len(ssl) + ssl->out_msglen, ssl->out_left)); - - buf = ssl->out_hdr - ssl->out_left; - ret = ssl->f_send(ssl->p_bio, buf, ssl->out_left); - - MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", ret); - - if (ret <= 0) { - return ret; - } - - if ((size_t) ret > ssl->out_left) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET - " bytes were sent", - ret, ssl->out_left)); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ssl->out_left -= ret; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ssl->out_hdr = ssl->out_buf; - } else -#endif - { - ssl->out_hdr = ssl->out_buf + 8; - } - mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output")); - - return 0; -} - -/* - * Functions to handle the DTLS retransmission state machine - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/* - * Append current handshake message to current outgoing flight - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_flight_append(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_flight_item *msg; - MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_flight_append")); - MBEDTLS_SSL_DEBUG_BUF(4, "message appended to flight", - ssl->out_msg, ssl->out_msglen); - - /* Allocate space for current message */ - if ((msg = mbedtls_calloc(1, sizeof(mbedtls_ssl_flight_item))) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", - sizeof(mbedtls_ssl_flight_item))); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - if ((msg->p = mbedtls_calloc(1, ssl->out_msglen)) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", - ssl->out_msglen)); - mbedtls_free(msg); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - /* Copy current handshake message with headers */ - memcpy(msg->p, ssl->out_msg, ssl->out_msglen); - msg->len = ssl->out_msglen; - msg->type = ssl->out_msgtype; - msg->next = NULL; - - /* Append to the current flight */ - if (ssl->handshake->flight == NULL) { - ssl->handshake->flight = msg; - } else { - mbedtls_ssl_flight_item *cur = ssl->handshake->flight; - while (cur->next != NULL) { - cur = cur->next; - } - cur->next = msg; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_flight_append")); - return 0; -} - -/* - * Free the current flight of handshake messages - */ -void mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight) -{ - mbedtls_ssl_flight_item *cur = flight; - mbedtls_ssl_flight_item *next; - - while (cur != NULL) { - next = cur->next; - - mbedtls_free(cur->p); - mbedtls_free(cur); - - cur = next; - } -} - -/* - * Swap transform_out and out_ctr with the alternative ones - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_swap_epochs(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_transform *tmp_transform; - unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; - - if (ssl->transform_out == ssl->handshake->alt_transform_out) { - MBEDTLS_SSL_DEBUG_MSG(3, ("skip swap epochs")); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("swap epochs")); - - /* Swap transforms */ - tmp_transform = ssl->transform_out; - ssl->transform_out = ssl->handshake->alt_transform_out; - ssl->handshake->alt_transform_out = tmp_transform; - - /* Swap epoch + sequence_number */ - memcpy(tmp_out_ctr, ssl->cur_out_ctr, sizeof(tmp_out_ctr)); - memcpy(ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, - sizeof(ssl->cur_out_ctr)); - memcpy(ssl->handshake->alt_out_ctr, tmp_out_ctr, - sizeof(ssl->handshake->alt_out_ctr)); - - /* Adjust to the newly activated transform */ - mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out); - - return 0; -} - -/* - * Retransmit the current flight of messages. - */ -int mbedtls_ssl_resend(mbedtls_ssl_context *ssl) -{ - int ret = 0; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_resend")); - - ret = mbedtls_ssl_flight_transmit(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_resend")); - - return ret; -} - -/* - * Transmit or retransmit the current flight of messages. - * - * Need to remember the current message in case flush_output returns - * WANT_WRITE, causing us to exit this function and come back later. - * This function must be called until state is no longer SENDING. - */ -int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_flight_transmit")); - - if (ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING) { - MBEDTLS_SSL_DEBUG_MSG(2, ("initialise flight transmission")); - - ssl->handshake->cur_msg = ssl->handshake->flight; - ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; - ret = ssl_swap_epochs(ssl); - if (ret != 0) { - return ret; - } - - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; - } - - while (ssl->handshake->cur_msg != NULL) { - size_t max_frag_len; - const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; - - int const is_finished = - (cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && - cur->p[0] == MBEDTLS_SSL_HS_FINISHED); - - int const force_flush = ssl->disable_datagram_packing == 1 ? - SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; - - /* Swap epochs before sending Finished: we can't do it after - * sending ChangeCipherSpec, in case write returns WANT_READ. - * Must be done before copying, may change out_msg pointer */ - if (is_finished && ssl->handshake->cur_msg_p == (cur->p + 12)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("swap epochs to send finished message")); - ret = ssl_swap_epochs(ssl); - if (ret != 0) { - return ret; - } - } - - ret = ssl_get_remaining_payload_in_datagram(ssl); - if (ret < 0) { - return ret; - } - max_frag_len = (size_t) ret; - - /* CCS is copied as is, while HS messages may need fragmentation */ - if (cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { - if (max_frag_len == 0) { - if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { - return ret; - } - - continue; - } - - memcpy(ssl->out_msg, cur->p, cur->len); - ssl->out_msglen = cur->len; - ssl->out_msgtype = cur->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += cur->len; - } else { - const unsigned char * const p = ssl->handshake->cur_msg_p; - const size_t hs_len = cur->len - 12; - const size_t frag_off = (size_t) (p - (cur->p + 12)); - const size_t rem_len = hs_len - frag_off; - size_t cur_hs_frag_len, max_hs_frag_len; - - if ((max_frag_len < 12) || (max_frag_len == 12 && hs_len != 0)) { - if (is_finished) { - ret = ssl_swap_epochs(ssl); - if (ret != 0) { - return ret; - } - } - - if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { - return ret; - } - - continue; - } - max_hs_frag_len = max_frag_len - 12; - - cur_hs_frag_len = rem_len > max_hs_frag_len ? - max_hs_frag_len : rem_len; - - if (frag_off == 0 && cur_hs_frag_len != hs_len) { - MBEDTLS_SSL_DEBUG_MSG(2, ("fragmenting %s handshake message (%u > %u)", - mbedtls_ssl_get_hs_msg_name(cur->p[0]), - (unsigned) cur_hs_frag_len, - (unsigned) max_hs_frag_len)); - } - - /* Messages are stored with handshake headers as if not fragmented, - * copy beginning of headers then fill fragmentation fields. - * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ - memcpy(ssl->out_msg, cur->p, 6); - - ssl->out_msg[6] = MBEDTLS_BYTE_2(frag_off); - ssl->out_msg[7] = MBEDTLS_BYTE_1(frag_off); - ssl->out_msg[8] = MBEDTLS_BYTE_0(frag_off); - - ssl->out_msg[9] = MBEDTLS_BYTE_2(cur_hs_frag_len); - ssl->out_msg[10] = MBEDTLS_BYTE_1(cur_hs_frag_len); - ssl->out_msg[11] = MBEDTLS_BYTE_0(cur_hs_frag_len); - - MBEDTLS_SSL_DEBUG_BUF(3, "handshake header", ssl->out_msg, 12); - - /* Copy the handshake message content and set records fields */ - memcpy(ssl->out_msg + 12, p, cur_hs_frag_len); - ssl->out_msglen = cur_hs_frag_len + 12; - ssl->out_msgtype = cur->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += cur_hs_frag_len; - } - - /* If done with the current message move to the next one if any */ - if (ssl->handshake->cur_msg_p >= cur->p + cur->len) { - if (cur->next != NULL) { - ssl->handshake->cur_msg = cur->next; - ssl->handshake->cur_msg_p = cur->next->p + 12; - } else { - ssl->handshake->cur_msg = NULL; - ssl->handshake->cur_msg_p = NULL; - } - } - - /* Actually send the message out */ - if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret); - return ret; - } - } - - if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { - return ret; - } - - /* Update state and set timer */ - if (mbedtls_ssl_is_handshake_over(ssl) == 1) { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - } else { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout); - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_flight_transmit")); - - return 0; -} - -/* - * To be called when the last message of an incoming flight is received. - */ -void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl) -{ - /* We won't need to resend that one any more */ - mbedtls_ssl_flight_free(ssl->handshake->flight); - ssl->handshake->flight = NULL; - ssl->handshake->cur_msg = NULL; - - /* The next incoming flight will start with this msg_seq */ - ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; - - /* We don't want to remember CCS's across flight boundaries. */ - ssl->handshake->buffering.seen_ccs = 0; - - /* Clear future message buffering structure. */ - mbedtls_ssl_buffering_free(ssl); - - /* Cancel timer */ - mbedtls_ssl_set_timer(ssl, 0); - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - } else { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; - } -} - -/* - * To be called when the last message of an outgoing flight is send. - */ -void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl) -{ - ssl_reset_retransmit_timeout(ssl); - mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout); - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - } else { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - } -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -/* - * Handshake layer functions - */ -int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type, - unsigned char **buf, size_t *buf_len) -{ - /* - * Reserve 4 bytes for handshake header. ( Section 4,RFC 8446 ) - * ... - * HandshakeType msg_type; - * uint24 length; - * ... - */ - *buf = ssl->out_msg + 4; - *buf_len = MBEDTLS_SSL_OUT_CONTENT_LEN - 4; - - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = hs_type; - - return 0; -} - -/* - * Write (DTLS: or queue) current handshake (including CCS) message. - * - * - fill in handshake headers - * - update handshake checksum - * - DTLS: save message for resending - * - then pass to the record layer - * - * DTLS: except for HelloRequest, messages are only queued, and will only be - * actually sent when calling flight_transmit() or resend(). - * - * Inputs: - * - ssl->out_msglen: 4 + actual handshake message len - * (4 is the size of handshake headers for TLS) - * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) - * - ssl->out_msg + 4: the handshake message body - * - * Outputs, ie state before passing to flight_append() or write_record(): - * - ssl->out_msglen: the length of the record contents - * (including handshake headers but excluding record headers) - * - ssl->out_msg: the record contents (handshake headers + content) - */ -int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl, - int update_checksum, - int force_flush) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const size_t hs_len = ssl->out_msglen - 4; - const unsigned char hs_type = ssl->out_msg[0]; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write handshake message")); - - /* - * Sanity checks - */ - if (ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Whenever we send anything different from a - * HelloRequest we should be in a handshake - double check. */ - if (!(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST) && - ssl->handshake == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } -#endif - - /* Double-check that we did not exceed the bounds - * of the outgoing record buffer. - * This should never fail as the various message - * writing functions must obey the bounds of the - * outgoing record buffer, but better be safe. - * - * Note: We deliberately do not check for the MTU or MFL here. - */ - if (ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Record too large: " - "size %" MBEDTLS_PRINTF_SIZET - ", maximum %" MBEDTLS_PRINTF_SIZET, - ssl->out_msglen, - (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN)); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* - * Fill handshake headers - */ - if (ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) { - ssl->out_msg[1] = MBEDTLS_BYTE_2(hs_len); - ssl->out_msg[2] = MBEDTLS_BYTE_1(hs_len); - ssl->out_msg[3] = MBEDTLS_BYTE_0(hs_len); - - /* - * DTLS has additional fields in the Handshake layer, - * between the length field and the actual payload: - * uint16 message_seq; - * uint24 fragment_offset; - * uint24 fragment_length; - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* Make room for the additional DTLS fields */ - if (MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8) { - MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS handshake message too large: " - "size %" MBEDTLS_PRINTF_SIZET ", maximum %" - MBEDTLS_PRINTF_SIZET, - hs_len, - (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN - 12))); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - memmove(ssl->out_msg + 12, ssl->out_msg + 4, hs_len); - ssl->out_msglen += 8; - - /* Write message_seq and update it, except for HelloRequest */ - if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST) { - MBEDTLS_PUT_UINT16_BE(ssl->handshake->out_msg_seq, ssl->out_msg, 4); - ++(ssl->handshake->out_msg_seq); - } else { - ssl->out_msg[4] = 0; - ssl->out_msg[5] = 0; - } - - /* Handshake hashes are computed without fragmentation, - * so set frag_offset = 0 and frag_len = hs_len for now */ - memset(ssl->out_msg + 6, 0x00, 3); - memcpy(ssl->out_msg + 9, ssl->out_msg + 1, 3); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Update running hashes of handshake messages seen */ - if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0) { - ret = ssl->handshake->update_checksum(ssl, ssl->out_msg, - ssl->out_msglen); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); - return ret; - } - } - } - - /* Either send now, or just save to be sent (and resent) later */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - !(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST)) { - if ((ret = ssl_flight_append(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_flight_append", ret); - return ret; - } - } else -#endif - { - if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_record", ret); - return ret; - } - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write handshake message")); - - return 0; -} - -int mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context *ssl, - size_t buf_len, size_t msg_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t msg_with_header_len; - ((void) buf_len); - - /* Add reserved 4 bytes for handshake header */ - msg_with_header_len = msg_len + 4; - ssl->out_msglen = msg_with_header_len; - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_handshake_msg_ext(ssl, 0, 0)); - -cleanup: - return ret; -} - -/* - * Record layer functions - */ - -/* - * Write current record. - * - * Uses: - * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) - * - ssl->out_msglen: length of the record content (excl headers) - * - ssl->out_msg: record content - */ -int mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, int force_flush) -{ - int ret, done = 0; - size_t len = ssl->out_msglen; - int flush = force_flush; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write record")); - - if (!done) { - unsigned i; - size_t protected_record_size; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len; -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif - /* Skip writing the record content type to after the encryption, - * as it may change when using the CID extension. */ - mbedtls_ssl_protocol_version tls_ver = ssl->tls_version; -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - /* TLS 1.3 still uses the TLS 1.2 version identifier - * for backwards compatibility. */ - if (tls_ver == MBEDTLS_SSL_VERSION_TLS1_3) { - tls_ver = MBEDTLS_SSL_VERSION_TLS1_2; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - mbedtls_ssl_write_version(ssl->out_hdr + 1, ssl->conf->transport, - tls_ver); - - memcpy(ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN); - MBEDTLS_PUT_UINT16_BE(len, ssl->out_len, 0); - - if (ssl->transform_out != NULL) { - mbedtls_record rec; - - rec.buf = ssl->out_iv; - rec.buf_len = out_buf_len - (size_t) (ssl->out_iv - ssl->out_buf); - rec.data_len = ssl->out_msglen; - rec.data_offset = (size_t) (ssl->out_msg - rec.buf); - - memcpy(&rec.ctr[0], ssl->out_ctr, sizeof(rec.ctr)); - mbedtls_ssl_write_version(rec.ver, ssl->conf->transport, tls_ver); - rec.type = ssl->out_msgtype; - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* The CID is set by mbedtls_ssl_encrypt_buf(). */ - rec.cid_len = 0; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - if ((ret = mbedtls_ssl_encrypt_buf(ssl, ssl->transform_out, &rec, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_encrypt_buf", ret); - return ret; - } - - if (rec.data_offset != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Update the record content type and CID. */ - ssl->out_msgtype = rec.type; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - memcpy(ssl->out_cid, rec.cid, rec.cid_len); -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->out_msglen = len = rec.data_len; - MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->out_len, 0); - } - - protected_record_size = len + mbedtls_ssl_out_hdr_len(ssl); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* In case of DTLS, double-check that we don't exceed - * the remaining space in the datagram. */ - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ret = ssl_get_remaining_space_in_datagram(ssl); - if (ret < 0) { - return ret; - } - - if (protected_record_size > (size_t) ret) { - /* Should never happen */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Now write the potentially updated record content type. */ - ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; - - MBEDTLS_SSL_DEBUG_MSG(3, ("output record: msgtype = %u, " - "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET, - ssl->out_hdr[0], ssl->out_hdr[1], - ssl->out_hdr[2], len)); - - MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network", - ssl->out_hdr, protected_record_size); - - ssl->out_left += protected_record_size; - ssl->out_hdr += protected_record_size; - mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out); - - for (i = 8; i > mbedtls_ssl_ep_len(ssl); i--) { - if (++ssl->cur_out_ctr[i - 1] != 0) { - break; - } - } - - /* The loop goes to its end if the counter is wrapping */ - if (i == mbedtls_ssl_ep_len(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("outgoing message counter would wrap")); - return MBEDTLS_ERR_SSL_COUNTER_WRAPPING; - } - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - flush == SSL_DONT_FORCE_FLUSH) { - size_t remaining; - ret = ssl_get_remaining_payload_in_datagram(ssl); - if (ret < 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_remaining_payload_in_datagram", - ret); - return ret; - } - - remaining = (size_t) ret; - if (remaining == 0) { - flush = SSL_FORCE_FLUSH; - } else { - MBEDTLS_SSL_DEBUG_MSG(2, - ("Still %u bytes available in current datagram", - (unsigned) remaining)); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if ((flush == SSL_FORCE_FLUSH) && - (ret = mbedtls_ssl_flush_output(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write record")); - - return 0; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_hs_is_proper_fragment(mbedtls_ssl_context *ssl) -{ - if (ssl->in_msglen < ssl->in_hslen || - memcmp(ssl->in_msg + 6, "\0\0\0", 3) != 0 || - memcmp(ssl->in_msg + 9, ssl->in_msg + 1, 3) != 0) { - return 1; - } - return 0; -} - -static uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl) -{ - return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9); -} - -static uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl) -{ - return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_hs_header(mbedtls_ssl_context const *ssl) -{ - uint32_t msg_len, frag_off, frag_len; - - msg_len = ssl_get_hs_total_len(ssl); - frag_off = ssl_get_hs_frag_off(ssl); - frag_len = ssl_get_hs_frag_len(ssl); - - if (frag_off > msg_len) { - return -1; - } - - if (frag_len > msg_len - frag_off) { - return -1; - } - - if (frag_len + 12 > ssl->in_msglen) { - return -1; - } - - return 0; -} - -/* - * Mark bits in bitmask (used for DTLS HS reassembly) - */ -static void ssl_bitmask_set(unsigned char *mask, size_t offset, size_t len) -{ - unsigned int start_bits, end_bits; - - start_bits = 8 - (offset % 8); - if (start_bits != 8) { - size_t first_byte_idx = offset / 8; - - /* Special case */ - if (len <= start_bits) { - for (; len != 0; len--) { - mask[first_byte_idx] |= 1 << (start_bits - len); - } - - /* Avoid potential issues with offset or len becoming invalid */ - return; - } - - offset += start_bits; /* Now offset % 8 == 0 */ - len -= start_bits; - - for (; start_bits != 0; start_bits--) { - mask[first_byte_idx] |= 1 << (start_bits - 1); - } - } - - end_bits = len % 8; - if (end_bits != 0) { - size_t last_byte_idx = (offset + len) / 8; - - len -= end_bits; /* Now len % 8 == 0 */ - - for (; end_bits != 0; end_bits--) { - mask[last_byte_idx] |= 1 << (8 - end_bits); - } - } - - memset(mask + offset / 8, 0xFF, len / 8); -} - -/* - * Check that bitmask is full - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_bitmask_check(unsigned char *mask, size_t len) -{ - size_t i; - - for (i = 0; i < len / 8; i++) { - if (mask[i] != 0xFF) { - return -1; - } - } - - for (i = 0; i < len % 8; i++) { - if ((mask[len / 8] & (1 << (7 - i))) == 0) { - return -1; - } - } - - return 0; -} - -/* msg_len does not include the handshake header */ -static size_t ssl_get_reassembly_buffer_size(size_t msg_len, - unsigned add_bitmap) -{ - size_t alloc_len; - - alloc_len = 12; /* Handshake header */ - alloc_len += msg_len; /* Content buffer */ - - if (add_bitmap) { - alloc_len += msg_len / 8 + (msg_len % 8 != 0); /* Bitmap */ - - } - return alloc_len; -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl) -{ - return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1); -} - -int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl) -{ - if (ssl->badmac_seen_or_in_hsfraglen == 0) { - /* The handshake message must at least include the header. - * We may not have the full message yet in case of fragmentation. - * To simplify the code, we insist on having the header (and in - * particular the handshake message length) in the first - * fragment. */ - if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET, - ssl->in_msglen)); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl); - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen =" - " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %" - MBEDTLS_PRINTF_SIZET, - ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen)); - - if (ssl->transform_in != NULL) { - MBEDTLS_SSL_DEBUG_MSG(4, ("decrypted handshake message:" - " iv-buf=%d hdr-buf=%d hdr-buf=%d", - (int) (ssl->in_iv - ssl->in_buf), - (int) (ssl->in_hdr - ssl->in_buf), - (int) (ssl->in_msg - ssl->in_buf))); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned int recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4); - - if (ssl_check_hs_header(ssl) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid handshake header")); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - if (ssl->in_msg[0] == MBEDTLS_SSL_HS_CLIENT_HELLO && - ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - if (ssl->state == MBEDTLS_SSL_CLIENT_HELLO -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) { - /* - * When establishing the connection, the client may go through - * a series of ClientHello and HelloVerifyRequest requests and - * responses. The server intentionally does not keep trace of - * these initial round trips: minimum allocated ressources as - * long as the reachability of the client has not been - * confirmed. When receiving the "first ClientHello" from - * server perspective, we may thus need to adapt the next - * expected `message_seq` for the incoming and outgoing - * handshake messages. - */ - if ((ssl->handshake->in_msg_seq == 0) && (recv_msg_seq > 0)) { - MBEDTLS_SSL_DEBUG_MSG(3, ("shift slots by %u", recv_msg_seq)); - ssl_buffering_shift_slots(ssl, recv_msg_seq); - ssl->handshake->in_msg_seq = recv_msg_seq; - ssl->handshake->out_msg_seq = recv_msg_seq; - } - - /* Epoch should be 0 for initial handshakes */ - if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2, - sizeof(ssl->cur_out_ctr) - 2); - - } else if (mbedtls_ssl_is_handshake_over(ssl) == 1) { - /* In case of a post-handshake ClientHello that initiates a - * renegotiation check that the handshake message sequence - * number is zero. - */ - if (recv_msg_seq != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: " - "%u (expected 0)", - recv_msg_seq)); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - } - } - - if (ssl->handshake != NULL && - ((mbedtls_ssl_is_handshake_over(ssl) == 0 && - recv_msg_seq != ssl->handshake->in_msg_seq) || - (mbedtls_ssl_is_handshake_over(ssl) == 1 && - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO))) { - if (recv_msg_seq > ssl->handshake->in_msg_seq) { - MBEDTLS_SSL_DEBUG_MSG(2, - ( - "received future handshake message of sequence number %u (next %u)", - recv_msg_seq, - ssl->handshake->in_msg_seq)); - return MBEDTLS_ERR_SSL_EARLY_MESSAGE; - } - - /* Retransmit only on last message from previous flight, to avoid - * too many retransmissions. - * Besides, No sane server ever retransmits HelloVerifyRequest */ - if (recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && - ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) { - MBEDTLS_SSL_DEBUG_MSG(2, ("received message from last flight, " - "message_seq = %u, start_of_flight = %u", - recv_msg_seq, - ssl->handshake->in_flight_start_seq)); - - if ((ret = mbedtls_ssl_resend(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret); - return ret; - } - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("dropping out-of-sequence message: " - "message_seq = %u, expected = %u", - recv_msg_seq, - ssl->handshake->in_msg_seq)); - } - - return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } - /* Wait until message completion to increment in_msg_seq */ - - /* Message reassembly is handled alongside buffering of future - * messages; the commonality is that both handshake fragments and - * future messages cannot be forwarded immediately to the - * handshake logic layer. */ - if (ssl_hs_is_proper_fragment(ssl) == 1) { - MBEDTLS_SSL_DEBUG_MSG(2, ("found fragmented DTLS handshake message")); - return MBEDTLS_ERR_SSL_EARLY_MESSAGE; - } - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - unsigned char *const reassembled_record_start = - ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - unsigned char *const payload_start = - reassembled_record_start + mbedtls_ssl_in_hdr_len(ssl); - unsigned char *payload_end = payload_start + ssl->badmac_seen_or_in_hsfraglen; - /* How many more bytes we want to have a complete handshake message. */ - const size_t hs_remain = ssl->in_hslen - ssl->badmac_seen_or_in_hsfraglen; - /* How many bytes of the current record are part of the first - * handshake message. There may be more handshake messages (possibly - * incomplete) in the same record; if so, we leave them after the - * current record, and ssl_consume_current_message() will take - * care of consuming the next handshake message. */ - const size_t hs_this_fragment_len = - ssl->in_msglen > hs_remain ? hs_remain : ssl->in_msglen; - (void) hs_this_fragment_len; - - MBEDTLS_SSL_DEBUG_MSG(3, - ("%s handshake fragment: %" MBEDTLS_PRINTF_SIZET - ", %u..%u of %" MBEDTLS_PRINTF_SIZET, - (ssl->badmac_seen_or_in_hsfraglen != 0 ? - "subsequent" : - hs_this_fragment_len == ssl->in_hslen ? - "sole" : - "initial"), - ssl->in_msglen, - ssl->badmac_seen_or_in_hsfraglen, - ssl->badmac_seen_or_in_hsfraglen + - (unsigned) hs_this_fragment_len, - ssl->in_hslen)); - - /* Move the received handshake fragment to have the whole message - * (at least the part received so far) in a single segment at a - * known offset in the input buffer. - * - When receiving a non-initial handshake fragment, append it to - * the initial segment. - * - Even the initial handshake fragment is moved, if it was - * encrypted with an explicit IV: decryption leaves the payload - * after the explicit IV, but here we move it to start where the - * IV was. - */ -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t const in_buf_len = ssl->in_buf_len; -#else - size_t const in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; -#endif - if (payload_end + ssl->in_msglen > ssl->in_buf + in_buf_len) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Shouldn't happen: no room to move handshake fragment %" - MBEDTLS_PRINTF_SIZET " from %p to %p (buf=%p len=%" - MBEDTLS_PRINTF_SIZET ")", - ssl->in_msglen, - (void *) ssl->in_msg, (void *) payload_end, - (void *) ssl->in_buf, in_buf_len)); - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - memmove(payload_end, ssl->in_msg, ssl->in_msglen); - - ssl->badmac_seen_or_in_hsfraglen += (unsigned) ssl->in_msglen; - payload_end += ssl->in_msglen; - - if (ssl->badmac_seen_or_in_hsfraglen < ssl->in_hslen) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Prepare: waiting for more handshake fragments " - "%u/%" MBEDTLS_PRINTF_SIZET, - ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen)); - ssl->in_hdr = payload_end; - ssl->in_msglen = 0; - mbedtls_ssl_update_in_pointers(ssl); - return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } else { - ssl->in_msglen = ssl->badmac_seen_or_in_hsfraglen; - ssl->badmac_seen_or_in_hsfraglen = 0; - ssl->in_hdr = reassembled_record_start; - mbedtls_ssl_update_in_pointers(ssl); - - /* Update the record length in the fully reassembled record */ - if (ssl->in_msglen > 0xffff) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Shouldn't happen: in_msglen=%" - MBEDTLS_PRINTF_SIZET " > 0xffff", - ssl->in_msglen)); - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0); - - size_t record_len = mbedtls_ssl_in_hdr_len(ssl) + ssl->in_msglen; - (void) record_len; - MBEDTLS_SSL_DEBUG_BUF(4, "reassembled record", - ssl->in_hdr, record_len); - if (ssl->in_hslen < ssl->in_msglen) { - MBEDTLS_SSL_DEBUG_MSG(3, - ("More handshake messages in the record: " - "%" MBEDTLS_PRINTF_SIZET " + %" MBEDTLS_PRINTF_SIZET, - ssl->in_hslen, - ssl->in_msglen - ssl->in_hslen)); - } - } - } - - return 0; -} - -int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if (mbedtls_ssl_is_handshake_over(ssl) == 0 && hs != NULL) { - ret = ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); - return ret; - } - } - - /* Handshake message is complete, increment counter */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL) { - - /* Increment handshake sequence number */ - hs->in_msg_seq++; - ssl_buffering_shift_slots(ssl, 1); - } -#endif - return 0; -} - -/* - * DTLS anti-replay: RFC 6347 4.1.2.6 - * - * in_window is a field of bits numbered from 0 (lsb) to 63 (msb). - * Bit n is set iff record number in_window_top - n has been seen. - * - * Usually, in_window_top is the last record number seen and the lsb of - * in_window is set. The only exception is the initial state (record number 0 - * not seen yet). - */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -void mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl) -{ - ssl->in_window_top = 0; - ssl->in_window = 0; -} - -static inline uint64_t ssl_load_six_bytes(unsigned char *buf) -{ - return ((uint64_t) buf[0] << 40) | - ((uint64_t) buf[1] << 32) | - ((uint64_t) buf[2] << 24) | - ((uint64_t) buf[3] << 16) | - ((uint64_t) buf[4] << 8) | - ((uint64_t) buf[5]); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context *ssl, uint8_t *record_in_ctr) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *original_in_ctr; - - // save original in_ctr - original_in_ctr = ssl->in_ctr; - - // use counter from record - ssl->in_ctr = record_in_ctr; - - ret = mbedtls_ssl_dtls_replay_check((mbedtls_ssl_context const *) ssl); - - // restore the counter - ssl->in_ctr = original_in_ctr; - - return ret; -} - -/* - * Return 0 if sequence number is acceptable, -1 otherwise - */ -int mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl) -{ - uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2); - uint64_t bit; - - if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) { - return 0; - } - - if (rec_seqnum > ssl->in_window_top) { - return 0; - } - - bit = ssl->in_window_top - rec_seqnum; - - if (bit >= 64) { - return -1; - } - - if ((ssl->in_window & ((uint64_t) 1 << bit)) != 0) { - return -1; - } - - return 0; -} - -/* - * Update replay window on new validated record - */ -void mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl) -{ - uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2); - - if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) { - return; - } - - if (rec_seqnum > ssl->in_window_top) { - /* Update window_top and the contents of the window */ - uint64_t shift = rec_seqnum - ssl->in_window_top; - - if (shift >= 64) { - ssl->in_window = 1; - } else { - ssl->in_window <<= shift; - ssl->in_window |= 1; - } - - ssl->in_window_top = rec_seqnum; - } else { - /* Mark that number as seen in the current window */ - uint64_t bit = ssl->in_window_top - rec_seqnum; - - if (bit < 64) { /* Always true, but be extra sure */ - ssl->in_window |= (uint64_t) 1 << bit; - } - } -} -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) -/* - * Check if a datagram looks like a ClientHello with a valid cookie, - * and if it doesn't, generate a HelloVerifyRequest message. - * Both input and output include full DTLS headers. - * - * - if cookie is valid, return 0 - * - if ClientHello looks superficially valid but cookie is not, - * fill obuf and set olen, then - * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED - * - otherwise return a specific error code - */ -MBEDTLS_CHECK_RETURN_CRITICAL -MBEDTLS_STATIC_TESTABLE -int mbedtls_ssl_check_dtls_clihlo_cookie( - mbedtls_ssl_context *ssl, - const unsigned char *cli_id, size_t cli_id_len, - const unsigned char *in, size_t in_len, - unsigned char *obuf, size_t buf_len, size_t *olen) -{ - size_t sid_len, cookie_len, epoch, fragment_offset; - unsigned char *p; - - /* - * Structure of ClientHello with record and handshake headers, - * and expected values. We don't need to check a lot, more checks will be - * done when actually parsing the ClientHello - skipping those checks - * avoids code duplication and does not make cookie forging any easier. - * - * 0-0 ContentType type; copied, must be handshake - * 1-2 ProtocolVersion version; copied - * 3-4 uint16 epoch; copied, must be 0 - * 5-10 uint48 sequence_number; copied - * 11-12 uint16 length; (ignored) - * - * 13-13 HandshakeType msg_type; (ignored) - * 14-16 uint24 length; (ignored) - * 17-18 uint16 message_seq; copied - * 19-21 uint24 fragment_offset; copied, must be 0 - * 22-24 uint24 fragment_length; (ignored) - * - * 25-26 ProtocolVersion client_version; (ignored) - * 27-58 Random random; (ignored) - * 59-xx SessionID session_id; 1 byte len + sid_len content - * 60+ opaque cookie<0..2^8-1>; 1 byte len + content - * ... - * - * Minimum length is 61 bytes. - */ - MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: in_len=%u", - (unsigned) in_len)); - MBEDTLS_SSL_DEBUG_BUF(4, "cli_id", cli_id, cli_id_len); - if (in_len < 61) { - MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: record too short")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - epoch = MBEDTLS_GET_UINT16_BE(in, 3); - fragment_offset = MBEDTLS_GET_UINT24_BE(in, 19); - - if (in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || epoch != 0 || - fragment_offset != 0) { - MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: not a good ClientHello")); - MBEDTLS_SSL_DEBUG_MSG(4, (" type=%u epoch=%u fragment_offset=%u", - in[0], (unsigned) epoch, - (unsigned) fragment_offset)); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - sid_len = in[59]; - if (59 + 1 + sid_len + 1 > in_len) { - MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: sid_len=%u > %u", - (unsigned) sid_len, - (unsigned) in_len - 61)); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - MBEDTLS_SSL_DEBUG_BUF(4, "sid received from network", - in + 60, sid_len); - - cookie_len = in[60 + sid_len]; - if (59 + 1 + sid_len + 1 + cookie_len > in_len) { - MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: cookie_len=%u > %u", - (unsigned) cookie_len, - (unsigned) (in_len - sid_len - 61))); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "cookie received from network", - in + sid_len + 61, cookie_len); - if (ssl->conf->f_cookie_check(ssl->conf->p_cookie, - in + sid_len + 61, cookie_len, - cli_id, cli_id_len) == 0) { - MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: valid")); - return 0; - } - - /* - * If we get here, we've got an invalid cookie, let's prepare HVR. - * - * 0-0 ContentType type; copied - * 1-2 ProtocolVersion version; copied - * 3-4 uint16 epoch; copied - * 5-10 uint48 sequence_number; copied - * 11-12 uint16 length; olen - 13 - * - * 13-13 HandshakeType msg_type; hello_verify_request - * 14-16 uint24 length; olen - 25 - * 17-18 uint16 message_seq; copied - * 19-21 uint24 fragment_offset; copied - * 22-24 uint24 fragment_length; olen - 25 - * - * 25-26 ProtocolVersion server_version; 0xfe 0xff - * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie - * - * Minimum length is 28. - */ - if (buf_len < 28) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - /* Copy most fields and adapt others */ - memcpy(obuf, in, 25); - obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; - obuf[25] = 0xfe; - obuf[26] = 0xff; - - /* Generate and write actual cookie */ - p = obuf + 28; - if (ssl->conf->f_cookie_write(ssl->conf->p_cookie, - &p, obuf + buf_len, - cli_id, cli_id_len) != 0) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - *olen = (size_t) (p - obuf); - - /* Go back and fill length fields */ - obuf[27] = (unsigned char) (*olen - 28); - - obuf[14] = obuf[22] = MBEDTLS_BYTE_2(*olen - 25); - obuf[15] = obuf[23] = MBEDTLS_BYTE_1(*olen - 25); - obuf[16] = obuf[24] = MBEDTLS_BYTE_0(*olen - 25); - - MBEDTLS_PUT_UINT16_BE(*olen - 13, obuf, 11); - - return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED; -} - -/* - * Handle possible client reconnect with the same UDP quadruplet - * (RFC 6347 Section 4.2.8). - * - * Called by ssl_parse_record_header() in case we receive an epoch 0 record - * that looks like a ClientHello. - * - * - if the input looks like a ClientHello without cookies, - * send back HelloVerifyRequest, then return 0 - * - if the input looks like a ClientHello with a valid cookie, - * reset the session of the current context, and - * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT - * - if anything goes wrong, return a specific error code - * - * This function is called (through ssl_check_client_reconnect()) when an - * unexpected record is found in ssl_get_next_record(), which will discard the - * record if we return 0, and bubble up the return value otherwise (this - * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected - * errors, and is the right thing to do in both cases). - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_handle_possible_reconnect(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - if (ssl->conf->f_cookie_write == NULL || - ssl->conf->f_cookie_check == NULL) { - /* If we can't use cookies to verify reachability of the peer, - * drop the record. */ - MBEDTLS_SSL_DEBUG_MSG(1, ("no cookie callbacks, " - "can't check reconnect validity")); - return 0; - } - - ret = mbedtls_ssl_check_dtls_clihlo_cookie( - ssl, - ssl->cli_id, ssl->cli_id_len, - ssl->in_buf, ssl->in_left, - ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len); - - MBEDTLS_SSL_DEBUG_RET(2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret); - - if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) { - int send_ret; - MBEDTLS_SSL_DEBUG_MSG(1, ("sending HelloVerifyRequest")); - MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network", - ssl->out_buf, len); - /* Don't check write errors as we can't do anything here. - * If the error is permanent we'll catch it later, - * if it's not, then hopefully it'll work next time. */ - send_ret = ssl->f_send(ssl->p_bio, ssl->out_buf, len); - MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", send_ret); - (void) send_ret; - - return 0; - } - - if (ret == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("cookie is valid, resetting context")); - if ((ret = mbedtls_ssl_session_reset_int(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "reset", ret); - return ret; - } - - return MBEDTLS_ERR_SSL_CLIENT_RECONNECT; - } - - return ret; -} -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_record_type(uint8_t record_type) -{ - if (record_type != MBEDTLS_SSL_MSG_HANDSHAKE && - record_type != MBEDTLS_SSL_MSG_ALERT && - record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && - record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA) { - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - return 0; -} - -/* - * ContentType type; - * ProtocolVersion version; - * uint16 epoch; // DTLS only - * uint48 sequence_number; // DTLS only - * uint16 length; - * - * Return 0 if header looks sane (and, for DTLS, the record is expected) - * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, - * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. - * - * With DTLS, mbedtls_ssl_read_record() will: - * 1. proceed with the record if this function returns 0 - * 2. drop only the current record if this function returns UNEXPECTED_RECORD - * 3. return CLIENT_RECONNECT if this function return that value - * 4. drop the whole datagram if this function returns anything else. - * Point 2 is needed when the peer is resending, and we have already received - * the first record from a datagram but are still waiting for the others. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_record_header(mbedtls_ssl_context const *ssl, - unsigned char *buf, - size_t len, - mbedtls_record *rec) -{ - mbedtls_ssl_protocol_version tls_version; - - size_t const rec_hdr_type_offset = 0; - size_t const rec_hdr_type_len = 1; - - size_t const rec_hdr_version_offset = rec_hdr_type_offset + - rec_hdr_type_len; - size_t const rec_hdr_version_len = 2; - - size_t const rec_hdr_ctr_len = 8; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint32_t rec_epoch; - size_t const rec_hdr_ctr_offset = rec_hdr_version_offset + - rec_hdr_version_len; - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset + - rec_hdr_ctr_len; - size_t rec_hdr_cid_len = 0; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - size_t rec_hdr_len_offset; /* To be determined */ - size_t const rec_hdr_len_len = 2; - - /* - * Check minimum lengths for record header. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len; - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len; - } - - if (len < rec_hdr_len_offset + rec_hdr_len_len) { - MBEDTLS_SSL_DEBUG_MSG(1, - ( - "datagram of length %u too small to hold DTLS record header of length %u", - (unsigned) len, - (unsigned) (rec_hdr_len_offset + rec_hdr_len_len))); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - /* - * Parse and validate record content type - */ - - rec->type = buf[rec_hdr_type_offset]; - - /* Check record content type */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - rec->cid_len = 0; - - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->conf->cid_len != 0 && - rec->type == MBEDTLS_SSL_MSG_CID) { - /* Shift pointers to account for record header including CID - * struct { - * ContentType outer_type = tls12_cid; - * ProtocolVersion version; - * uint16 epoch; - * uint48 sequence_number; - * opaque cid[cid_length]; // Additional field compared to - * // default DTLS record format - * uint16 length; - * opaque enc_content[DTLSCiphertext.length]; - * } DTLSCiphertext; - */ - - /* So far, we only support static CID lengths - * fixed in the configuration. */ - rec_hdr_cid_len = ssl->conf->cid_len; - rec_hdr_len_offset += rec_hdr_cid_len; - - if (len < rec_hdr_len_offset + rec_hdr_len_len) { - MBEDTLS_SSL_DEBUG_MSG(1, - ( - "datagram of length %u too small to hold DTLS record header including CID, length %u", - (unsigned) len, - (unsigned) (rec_hdr_len_offset + rec_hdr_len_len))); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - /* configured CID len is guaranteed at most 255, see - * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */ - rec->cid_len = (uint8_t) rec_hdr_cid_len; - memcpy(rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len); - } else -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - { - if (ssl_check_record_type(rec->type)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type %u", - (unsigned) rec->type)); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - } - - /* - * Parse and validate record version - */ - rec->ver[0] = buf[rec_hdr_version_offset + 0]; - rec->ver[1] = buf[rec_hdr_version_offset + 1]; - tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version( - buf + rec_hdr_version_offset, - ssl->conf->transport); - - if (tls_version > ssl->conf->max_tls_version) { - MBEDTLS_SSL_DEBUG_MSG(1, ("TLS version mismatch: got %u, expected max %u", - (unsigned) tls_version, - (unsigned) ssl->conf->max_tls_version)); - - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - /* - * Parse/Copy record sequence number. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* Copy explicit record sequence number from input buffer. */ - memcpy(&rec->ctr[0], buf + rec_hdr_ctr_offset, - rec_hdr_ctr_len); - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - /* Copy implicit record sequence number from SSL context structure. */ - memcpy(&rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len); - } - - /* - * Parse record length. - */ - - rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len; - rec->data_len = MBEDTLS_GET_UINT16_BE(buf, rec_hdr_len_offset); - MBEDTLS_SSL_DEBUG_BUF(4, "input record header", buf, rec->data_offset); - - MBEDTLS_SSL_DEBUG_MSG(3, ("input record: msgtype = %u, " - "version = [0x%x], msglen = %" MBEDTLS_PRINTF_SIZET, - rec->type, (unsigned) tls_version, rec->data_len)); - - rec->buf = buf; - rec->buf_len = rec->data_offset + rec->data_len; - - if (rec->data_len == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("rejecting empty record")); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - /* - * DTLS-related tests. - * Check epoch before checking length constraint because - * the latter varies with the epoch. E.g., if a ChangeCipherSpec - * message gets duplicated before the corresponding Finished message, - * the second ChangeCipherSpec should be discarded because it belongs - * to an old epoch, but not because its length is shorter than - * the minimum record length for packets using the new record transform. - * Note that these two kinds of failures are handled differently, - * as an unexpected record is silently skipped but an invalid - * record leads to the entire datagram being dropped. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - rec_epoch = MBEDTLS_GET_UINT16_BE(rec->ctr, 0); - - /* Check that the datagram is large enough to contain a record - * of the advertised length. */ - if (len < rec->data_offset + rec->data_len) { - MBEDTLS_SSL_DEBUG_MSG(1, - ( - "Datagram of length %u too small to contain record of advertised length %u.", - (unsigned) len, - (unsigned) (rec->data_offset + rec->data_len))); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - /* Records from other, non-matching epochs are silently discarded. - * (The case of same-port Client reconnects must be considered in - * the caller). */ - if (rec_epoch != ssl->in_epoch) { - MBEDTLS_SSL_DEBUG_MSG(1, ("record from another epoch: " - "expected %u, received %lu", - ssl->in_epoch, (unsigned long) rec_epoch)); - - /* Records from the next epoch are considered for buffering - * (concretely: early Finished messages). */ - if (rec_epoch == (unsigned) ssl->in_epoch + 1) { - MBEDTLS_SSL_DEBUG_MSG(2, ("Consider record for buffering")); - return MBEDTLS_ERR_SSL_EARLY_MESSAGE; - } - - return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - /* For records from the correct epoch, check whether their - * sequence number has been seen before. */ - else if (mbedtls_ssl_dtls_record_replay_check((mbedtls_ssl_context *) ssl, - &rec->ctr[0]) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record")); - return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } -#endif - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - return 0; -} - - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_client_reconnect(mbedtls_ssl_context *ssl) -{ - unsigned int rec_epoch = MBEDTLS_GET_UINT16_BE(ssl->in_ctr, 0); - - /* - * Check for an epoch 0 ClientHello. We can't use in_msg here to - * access the first byte of record content (handshake type), as we - * have an active transform (possibly iv_len != 0), so use the - * fact that the record header len is 13 instead. - */ - if (rec_epoch == 0 && - ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - mbedtls_ssl_is_handshake_over(ssl) == 1 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_left > 13 && - ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO) { - MBEDTLS_SSL_DEBUG_MSG(1, ("possible client reconnect " - "from the same port")); - return ssl_handle_possible_reconnect(ssl); - } - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - -/* - * If applicable, decrypt record content - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_prepare_record_content(mbedtls_ssl_context *ssl, - mbedtls_record *rec) -{ - int ret, done = 0; - - MBEDTLS_SSL_DEBUG_BUF(4, "input record from network", - rec->buf, rec->buf_len); - - /* - * In TLS 1.3, always treat ChangeCipherSpec records - * as unencrypted. The only thing we do with them is - * check the length and content and ignore them. - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->transform_in != NULL && - ssl->transform_in->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - if (rec->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { - done = 1; - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - if (!done && ssl->transform_in != NULL) { - unsigned char const old_msg_type = rec->type; - - if ((ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, - rec)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_decrypt_buf", ret); - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) - /* - * Although the server rejected early data, it might receive early - * data as long as it has not received the client Finished message. - * It is encrypted with early keys and should be ignored as stated - * in section 4.2.10 of RFC 8446: - * - * "Ignore the extension and return a regular 1-RTT response. The - * server then skips past early data by attempting to deprotect - * received records using the handshake traffic key, discarding - * records which fail deprotection (up to the configured - * max_early_data_size). Once a record is deprotected successfully, - * it is treated as the start of the client's second flight and the - * server proceeds as with an ordinary 1-RTT handshake." - */ - if ((old_msg_type == MBEDTLS_SSL_MSG_APPLICATION_DATA) && - (ssl->discard_early_data_record == - MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) { - MBEDTLS_SSL_DEBUG_MSG( - 3, ("EarlyData: deprotect and discard app data records.")); - - ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len); - if (ret != 0) { - return ret; - } - ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID && - ssl->conf->ignore_unexpected_cid - == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ignoring unexpected CID")); - ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /* - * The decryption of the record failed, no reason to ignore it, - * return in error with the decryption error code. - */ - return ret; - } - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) - /* - * If the server were discarding protected records that it fails to - * deprotect because it has rejected early data, as we have just - * deprotected successfully a record, the server has to resume normal - * operation and fail the connection if the deprotection of a record - * fails. - */ - if (ssl->discard_early_data_record == - MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD) { - ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; - } -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */ - - if (old_msg_type != rec->type) { - MBEDTLS_SSL_DEBUG_MSG(4, ("record type after decrypt (before %d): %d", - old_msg_type, rec->type)); - } - - MBEDTLS_SSL_DEBUG_BUF(4, "input payload after decrypt", - rec->buf + rec->data_offset, rec->data_len); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* We have already checked the record content type - * in ssl_parse_record_header(), failing or silently - * dropping the record in the case of an unknown type. - * - * Since with the use of CIDs, the record content type - * might change during decryption, re-check the record - * content type, but treat a failure as fatal this time. */ - if (ssl_check_record_type(rec->type)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type")); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - if (rec->data_len == 0) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 - && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA) { - /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid zero-length message type: %d", ssl->in_msgtype)); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - ssl->nb_zero++; - - /* - * Three or more empty messages may be a DoS attack - * (excessive CPU consumption). - */ - if (ssl->nb_zero > 3) { - MBEDTLS_SSL_DEBUG_MSG(1, ("received four consecutive empty " - "messages, possible DoS attack")); - /* Treat the records as if they were not properly authenticated, - * thereby failing the connection if we see more than allowed - * by the configured bad MAC threshold. */ - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - } else { - ssl->nb_zero = 0; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ; /* in_ctr read from peer, not maintained internally */ - } else -#endif - { - unsigned i; - for (i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - i > mbedtls_ssl_ep_len(ssl); i--) { - if (++ssl->in_ctr[i - 1] != 0) { - break; - } - } - - /* The loop goes to its end iff the counter is wrapping */ - if (i == mbedtls_ssl_ep_len(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("incoming message counter would wrap")); - return MBEDTLS_ERR_SSL_COUNTER_WRAPPING; - } - } - - } - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) - /* - * Although the server rejected early data because it needed to send an - * HelloRetryRequest message, it might receive early data as long as it has - * not received the client Finished message. - * The early data is encrypted with early keys and should be ignored as - * stated in section 4.2.10 of RFC 8446 (second case): - * - * "The server then ignores early data by skipping all records with an - * external content type of "application_data" (indicating that they are - * encrypted), up to the configured max_early_data_size. Ignore application - * data message before 2nd ClientHello when early_data was received in 1st - * ClientHello." - */ - if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) { - if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) { - - ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len); - if (ret != 0) { - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG( - 3, ("EarlyData: Ignore application message before 2nd ClientHello")); - - return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) { - ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; - } - } -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - mbedtls_ssl_dtls_replay_update(ssl); - } -#endif - - /* Check actual (decrypted) record content length against - * configured maximum. */ - if (rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad message length")); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - return 0; -} - -/* - * Read a record. - * - * Silently ignore non-fatal alert (and for DTLS, invalid records as well, - * RFC 6347 4.1.2.7) and continue reading until a valid record is found. - * - */ - -/* Helper functions for mbedtls_ssl_read_record(). */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_consume_current_message(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_next_record(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl); - -int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl, - unsigned update_hs_digest) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> read record")); - - if (ssl->keep_current_message == 0) { - do { - - ret = ssl_consume_current_message(ssl); - if (ret != 0) { - return ret; - } - - if (ssl_record_is_in_progress(ssl) == 0) { - int dtls_have_buffered = 0; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - - /* We only check for buffered messages if the - * current datagram is fully consumed. */ - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl_next_record_is_in_datagram(ssl) == 0) { - if (ssl_load_buffered_message(ssl) == 0) { - dtls_have_buffered = 1; - } - } - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - if (dtls_have_buffered == 0) { - ret = ssl_get_next_record(ssl); - if (ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) { - continue; - } - - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_get_next_record"), ret); - return ret; - } - } - } - - ret = mbedtls_ssl_handle_message_type(ssl); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) { - /* Buffer future message */ - ret = ssl_buffer_message(ssl); - if (ret != 0) { - return ret; - } - - ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - } while (MBEDTLS_ERR_SSL_NON_FATAL == ret || - MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret); - - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_handle_message_type"), ret); - return ret; - } - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - update_hs_digest == 1) { - ret = mbedtls_ssl_update_handshake_status(ssl); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); - return ret; - } - } - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message")); - ssl->keep_current_message = 0; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= read record")); - - return 0; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl) -{ - if (ssl->in_left > ssl->next_record_offset) { - return 1; - } - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_load_buffered_message(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer *hs_buf; - int ret = 0; - - if (hs == NULL) { - return -1; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_message")); - - if (ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || - ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) { - /* Check if we have seen a ChangeCipherSpec before. - * If yes, synthesize a CCS record. */ - if (!hs->buffering.seen_ccs) { - MBEDTLS_SSL_DEBUG_MSG(2, ("CCS not seen in the current flight")); - ret = -1; - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("Injecting buffered CCS message")); - ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - ssl->in_msglen = 1; - ssl->in_msg[0] = 1; - - /* As long as they are equal, the exact value doesn't matter. */ - ssl->in_left = 0; - ssl->next_record_offset = 0; - - hs->buffering.seen_ccs = 0; - goto exit; - } - -#if defined(MBEDTLS_DEBUG_C) - /* Debug only */ - { - unsigned offset; - for (offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { - hs_buf = &hs->buffering.hs[offset]; - if (hs_buf->is_valid == 1) { - MBEDTLS_SSL_DEBUG_MSG(2, ("Future message with sequence number %u %s buffered.", - hs->in_msg_seq + offset, - hs_buf->is_complete ? "fully" : "partially")); - } - } - } -#endif /* MBEDTLS_DEBUG_C */ - - /* Check if we have buffered and/or fully reassembled the - * next handshake message. */ - hs_buf = &hs->buffering.hs[0]; - if ((hs_buf->is_valid == 1) && (hs_buf->is_complete == 1)) { - /* Synthesize a record containing the buffered HS message. */ - size_t msg_len = MBEDTLS_GET_UINT24_BE(hs_buf->data, 1); - - /* Double-check that we haven't accidentally buffered - * a message that doesn't fit into the input buffer. */ - if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("%s handshake message has been buffered%s", - mbedtls_ssl_get_hs_msg_name(hs_buf->data[0]), - hs_buf->is_fragmented ? " and reassembled" : "")); - MBEDTLS_SSL_DEBUG_BUF(3, "Buffered handshake message (incl. header)", - hs_buf->data, msg_len + 12); - - ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->in_hslen = msg_len + 12; - ssl->in_msglen = msg_len + 12; - memcpy(ssl->in_msg, hs_buf->data, ssl->in_hslen); - - ret = 0; - goto exit; - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message %u not or only partially buffered", - hs->in_msg_seq)); - } - - ret = -1; - -exit: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_message")); - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_buffer_make_space(mbedtls_ssl_context *ssl, - size_t desired) -{ - int offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - MBEDTLS_SSL_DEBUG_MSG(2, ("Attempt to free buffered messages to have %u bytes available", - (unsigned) desired)); - - /* Get rid of future records epoch first, if such exist. */ - ssl_free_buffered_record(ssl); - - /* Check if we have enough space available now. */ - if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing future epoch record")); - return 0; - } - - /* We don't have enough space to buffer the next expected handshake - * message. Remove buffers used for future messages to gain space, - * starting with the most distant one. */ - for (offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; - offset >= 0; offset--) { - MBEDTLS_SSL_DEBUG_MSG(2, - ( - "Free buffering slot %d to make space for reassembly of next handshake message", - offset)); - - ssl_buffering_free_slot(ssl, (uint8_t) offset); - - /* Check if we have enough space available now. */ - if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing buffered HS messages")); - return 0; - } - } - - return -1; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_buffer_message(mbedtls_ssl_context *ssl) -{ - int ret = 0; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if (hs == NULL) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_buffer_message")); - - switch (ssl->in_msgtype) { - case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: - MBEDTLS_SSL_DEBUG_MSG(2, ("Remember CCS message")); - - hs->buffering.seen_ccs = 1; - break; - - case MBEDTLS_SSL_MSG_HANDSHAKE: - { - unsigned recv_msg_seq_offset; - unsigned recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4); - mbedtls_ssl_hs_buffer *hs_buf; - size_t msg_len = ssl->in_hslen - 12; - - /* We should never receive an old handshake - * message - double-check nonetheless. */ - if (recv_msg_seq < ssl->handshake->in_msg_seq) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; - if (recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS) { - /* Silently ignore -- message too far in the future */ - MBEDTLS_SSL_DEBUG_MSG(2, - ("Ignore future HS message with sequence number %u, " - "buffering window %u - %u", - recv_msg_seq, ssl->handshake->in_msg_seq, - ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - - 1)); - - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering HS message with sequence number %u, offset %u ", - recv_msg_seq, recv_msg_seq_offset)); - - hs_buf = &hs->buffering.hs[recv_msg_seq_offset]; - - /* Check if the buffering for this seq nr has already commenced. */ - if (!hs_buf->is_valid) { - size_t reassembly_buf_sz; - - hs_buf->is_fragmented = - (ssl_hs_is_proper_fragment(ssl) == 1); - - /* We copy the message back into the input buffer - * after reassembly, so check that it's not too large. - * This is an implementation-specific limitation - * and not one from the standard, hence it is not - * checked in ssl_check_hs_header(). */ - if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) { - /* Ignore message */ - goto exit; - } - - /* Check if we have enough space to buffer the message. */ - if (hs->buffering.total_bytes_buffered > - MBEDTLS_SSL_DTLS_MAX_BUFFERING) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - reassembly_buf_sz = ssl_get_reassembly_buffer_size(msg_len, - hs_buf->is_fragmented); - - if (reassembly_buf_sz > (MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered)) { - if (recv_msg_seq_offset > 0) { - /* If we can't buffer a future message because - * of space limitations -- ignore. */ - MBEDTLS_SSL_DEBUG_MSG(2, - ("Buffering of future message of size %" - MBEDTLS_PRINTF_SIZET - " would exceed the compile-time limit %" - MBEDTLS_PRINTF_SIZET - " (already %" MBEDTLS_PRINTF_SIZET - " bytes buffered) -- ignore\n", - msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, - hs->buffering.total_bytes_buffered)); - goto exit; - } else { - MBEDTLS_SSL_DEBUG_MSG(2, - ("Buffering of future message of size %" - MBEDTLS_PRINTF_SIZET - " would exceed the compile-time limit %" - MBEDTLS_PRINTF_SIZET - " (already %" MBEDTLS_PRINTF_SIZET - " bytes buffered) -- attempt to make space by freeing buffered future messages\n", - msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, - hs->buffering.total_bytes_buffered)); - } - - if (ssl_buffer_make_space(ssl, reassembly_buf_sz) != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, - ("Reassembly of next message of size %" - MBEDTLS_PRINTF_SIZET - " (%" MBEDTLS_PRINTF_SIZET - " with bitmap) would exceed" - " the compile-time limit %" - MBEDTLS_PRINTF_SIZET - " (already %" MBEDTLS_PRINTF_SIZET - " bytes buffered) -- fail\n", - msg_len, - reassembly_buf_sz, - (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, - hs->buffering.total_bytes_buffered)); - ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - goto exit; - } - } - - MBEDTLS_SSL_DEBUG_MSG(2, - ("initialize reassembly, total length = %" - MBEDTLS_PRINTF_SIZET, - msg_len)); - - hs_buf->data = mbedtls_calloc(1, reassembly_buf_sz); - if (hs_buf->data == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - hs_buf->data_len = reassembly_buf_sz; - - /* Prepare final header: copy msg_type, length and message_seq, - * then add standardised fragment_offset and fragment_length */ - memcpy(hs_buf->data, ssl->in_msg, 6); - memset(hs_buf->data + 6, 0, 3); - memcpy(hs_buf->data + 9, hs_buf->data + 1, 3); - - hs_buf->is_valid = 1; - - hs->buffering.total_bytes_buffered += reassembly_buf_sz; - } else { - /* Make sure msg_type and length are consistent */ - if (memcmp(hs_buf->data, ssl->in_msg, 4) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Fragment header mismatch - ignore")); - /* Ignore */ - goto exit; - } - } - - if (!hs_buf->is_complete) { - size_t frag_len, frag_off; - unsigned char * const msg = hs_buf->data + 12; - - /* - * Check and copy current fragment - */ - - /* Validation of header fields already done in - * mbedtls_ssl_prepare_handshake_record(). */ - frag_off = ssl_get_hs_frag_off(ssl); - frag_len = ssl_get_hs_frag_len(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("adding fragment, offset = %" MBEDTLS_PRINTF_SIZET - ", length = %" MBEDTLS_PRINTF_SIZET, - frag_off, frag_len)); - memcpy(msg + frag_off, ssl->in_msg + 12, frag_len); - - if (hs_buf->is_fragmented) { - unsigned char * const bitmask = msg + msg_len; - ssl_bitmask_set(bitmask, frag_off, frag_len); - hs_buf->is_complete = (ssl_bitmask_check(bitmask, - msg_len) == 0); - } else { - hs_buf->is_complete = 1; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("message %scomplete", - hs_buf->is_complete ? "" : "not yet ")); - } - - break; - } - - default: - /* We don't buffer other types of messages. */ - break; - } - -exit: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_buffer_message")); - return ret; -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_consume_current_message(mbedtls_ssl_context *ssl) -{ - /* - * Consume last content-layer message and potentially - * update in_msglen which keeps track of the contents' - * consumption state. - * - * (1) Handshake messages: - * Remove last handshake message, move content - * and adapt in_msglen. - * - * (2) Alert messages: - * Consume whole record content, in_msglen = 0. - * - * (3) Change cipher spec: - * Consume whole record content, in_msglen = 0. - * - * (4) Application data: - * Don't do anything - the record layer provides - * the application data as a stream transport - * and consumes through mbedtls_ssl_read only. - * - */ - - /* Case (1): Handshake messages */ - if (ssl->in_hslen != 0) { - /* Hard assertion to be sure that no application data - * is in flight, as corrupting ssl->in_msglen during - * ssl->in_offt != NULL is fatal. */ - if (ssl->in_offt != NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if (ssl->badmac_seen_or_in_hsfraglen != 0) { - /* Not all handshake fragments have arrived, do not consume. */ - MBEDTLS_SSL_DEBUG_MSG(3, ("Consume: waiting for more handshake fragments " - "%u/%" MBEDTLS_PRINTF_SIZET, - ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen)); - return 0; - } - - /* - * Get next Handshake message in the current record - */ - - /* Notes: - * (1) in_hslen is not necessarily the size of the - * current handshake content: If DTLS handshake - * fragmentation is used, that's the fragment - * size instead. Using the total handshake message - * size here is faulty and should be changed at - * some point. - * (2) While it doesn't seem to cause problems, one - * has to be very careful not to assume that in_hslen - * is always <= in_msglen in a sensible communication. - * Again, it's wrong for DTLS handshake fragmentation. - * The following check is therefore mandatory, and - * should not be treated as a silently corrected assertion. - * Additionally, ssl->in_hslen might be arbitrarily out of - * bounds after handling a DTLS message with an unexpected - * sequence number, see mbedtls_ssl_prepare_handshake_record. - */ - if (ssl->in_hslen < ssl->in_msglen) { - ssl->in_msglen -= ssl->in_hslen; - memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen, - ssl->in_msglen); - MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0); - - MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record", - ssl->in_msg, ssl->in_msglen); - } else { - ssl->in_msglen = 0; - } - - ssl->in_hslen = 0; - } - /* Case (4): Application data */ - else if (ssl->in_offt != NULL) { - return 0; - } - /* Everything else (CCS & Alerts) */ - else { - ssl->in_msglen = 0; - } - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl) -{ - if (ssl->in_msglen > 0) { - return 1; - } - - return 0; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static void ssl_free_buffered_record(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if (hs == NULL) { - return; - } - - if (hs->buffering.future_record.data != NULL) { - hs->buffering.total_bytes_buffered -= - hs->buffering.future_record.len; - - mbedtls_free(hs->buffering.future_record.data); - hs->buffering.future_record.data = NULL; - } -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_load_buffered_record(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - unsigned char *rec; - size_t rec_len; - unsigned rec_epoch; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; -#endif - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return 0; - } - - if (hs == NULL) { - return 0; - } - - rec = hs->buffering.future_record.data; - rec_len = hs->buffering.future_record.len; - rec_epoch = hs->buffering.future_record.epoch; - - if (rec == NULL) { - return 0; - } - - /* Only consider loading future records if the - * input buffer is empty. */ - if (ssl_next_record_is_in_datagram(ssl) == 1) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_record")); - - if (rec_epoch != ssl->in_epoch) { - MBEDTLS_SSL_DEBUG_MSG(2, ("Buffered record not from current epoch.")); - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("Found buffered record from current epoch - load")); - - /* Double-check that the record is not too large */ - if (rec_len > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - memcpy(ssl->in_hdr, rec, rec_len); - ssl->in_left = rec_len; - ssl->next_record_offset = 0; - - ssl_free_buffered_record(ssl); - -exit: - MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_record")); - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_buffer_future_record(mbedtls_ssl_context *ssl, - mbedtls_record const *rec) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - /* Don't buffer future records outside handshakes. */ - if (hs == NULL) { - return 0; - } - - /* Only buffer handshake records (we are only interested - * in Finished messages). */ - if (rec->type != MBEDTLS_SSL_MSG_HANDSHAKE) { - return 0; - } - - /* Don't buffer more than one future epoch record. */ - if (hs->buffering.future_record.data != NULL) { - return 0; - } - - /* Don't buffer record if there's not enough buffering space remaining. */ - if (rec->buf_len > (MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET - " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET - " (already %" MBEDTLS_PRINTF_SIZET - " bytes buffered) -- ignore\n", - rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, - hs->buffering.total_bytes_buffered)); - return 0; - } - - /* Buffer record */ - MBEDTLS_SSL_DEBUG_MSG(2, ("Buffer record from epoch %u", - ssl->in_epoch + 1U)); - MBEDTLS_SSL_DEBUG_BUF(3, "Buffered record", rec->buf, rec->buf_len); - - /* ssl_parse_record_header() only considers records - * of the next epoch as candidates for buffering. */ - hs->buffering.future_record.epoch = ssl->in_epoch + 1; - hs->buffering.future_record.len = rec->buf_len; - - hs->buffering.future_record.data = - mbedtls_calloc(1, hs->buffering.future_record.len); - if (hs->buffering.future_record.data == NULL) { - /* If we run out of RAM trying to buffer a - * record from the next epoch, just ignore. */ - return 0; - } - - memcpy(hs->buffering.future_record.data, rec->buf, rec->buf_len); - - hs->buffering.total_bytes_buffered += rec->buf_len; - return 0; -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_next_record(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_record rec; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* We might have buffered a future record; if so, - * and if the epoch matches now, load it. - * On success, this call will set ssl->in_left to - * the length of the buffered record, so that - * the calls to ssl_fetch_input() below will - * essentially be no-ops. */ - ret = ssl_load_buffered_record(ssl); - if (ret != 0) { - return ret; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Ensure that we have enough space available for the default form - * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS, - * with no space for CIDs counted in). */ - ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl)); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); - return ret; - } - - ret = ssl_parse_record_header(ssl, ssl->in_hdr, ssl->in_left, &rec); - if (ret != 0) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) { - ret = ssl_buffer_future_record(ssl, &rec); - if (ret != 0) { - return ret; - } - - /* Fall through to handling of unexpected records */ - ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } - -#if defined(MBEDTLS_SSL_SRV_C) - /* - * In DTLS, invalid records are usually ignored because it is easy - * for an attacker to inject UDP datagrams, and we do not want such - * packets to disrupt the entire connection. - * - * However, when expecting the ClientHello, we reject invalid or - * unexpected records. This avoids waiting for further records - * before receiving at least one valid message. Such records could - * be leftover messages from a previous connection, accidental - * input, or part of a DoS attempt. - * - * Since no valid message has been received yet, immediately - * closing the connection does not result in any loss. - */ - if ((ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) && - (ssl->state == MBEDTLS_SSL_CLIENT_HELLO) -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && (ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE) -#endif - ) { - return ret; - } -#endif /* MBEDTLS_SSL_SRV_C */ - - if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) { -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) - /* Reset in pointers to default state for TLS/DTLS records, - * assuming no CID and no offset between record content and - * record plaintext. */ - mbedtls_ssl_update_in_pointers(ssl); - - /* Setup internal message pointers from record structure. */ - ssl->in_msgtype = rec.type; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_len = ssl->in_cid + rec.cid_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_iv = ssl->in_msg = ssl->in_len + 2; - ssl->in_msglen = rec.data_len; - - ret = ssl_check_client_reconnect(ssl); - MBEDTLS_SSL_DEBUG_RET(2, "ssl_check_client_reconnect", ret); - if (ret != 0) { - return ret; - } -#endif - - /* Skip unexpected record (but not whole datagram) */ - ssl->next_record_offset = rec.buf_len; - - MBEDTLS_SSL_DEBUG_MSG(1, ("discarding unexpected record " - "(header)")); - } else { - /* Skip invalid record and the rest of the datagram */ - ssl->next_record_offset = 0; - ssl->in_left = 0; - - MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record " - "(header)")); - } - - /* Get next record */ - return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } else -#endif - { - return ret; - } - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* Remember offset of next record within datagram. */ - ssl->next_record_offset = rec.buf_len; - if (ssl->next_record_offset < ssl->in_left) { - MBEDTLS_SSL_DEBUG_MSG(3, ("more than one record within datagram")); - } - } else -#endif - { - /* - * Fetch record contents from underlying transport. - */ - ret = mbedtls_ssl_fetch_input(ssl, rec.buf_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); - return ret; - } - - ssl->in_left = 0; - } - - /* - * Decrypt record contents. - */ - - if ((ret = ssl_prepare_record_content(ssl, &rec)) != 0) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* Silently discard invalid records */ - if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { - /* Except when waiting for Finished as a bad mac here - * probably means something went wrong in the handshake - * (eg wrong psk used, mitm downgrade attempt, etc.) */ - if (ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || - ssl->state == MBEDTLS_SSL_SERVER_FINISHED) { -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC); - } -#endif - return ret; - } - - if (ssl->conf->badmac_limit != 0) { - ++ssl->badmac_seen_or_in_hsfraglen; - if (ssl->badmac_seen_or_in_hsfraglen >= ssl->conf->badmac_limit) { - MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC")); - return MBEDTLS_ERR_SSL_INVALID_MAC; - } - } - - /* As above, invalid records cause - * dismissal of the whole datagram. */ - - ssl->next_record_offset = 0; - ssl->in_left = 0; - - MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record (mac)")); - return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } - - return ret; - } else -#endif - { - /* Error out (and send alert) on invalid records */ -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC); - } -#endif - return ret; - } - } - - - /* Reset in pointers to default state for TLS/DTLS records, - * assuming no CID and no offset between record content and - * record plaintext. */ - mbedtls_ssl_update_in_pointers(ssl); -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_len = ssl->in_cid + rec.cid_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_iv = ssl->in_len + 2; - - /* The record content type may change during decryption, - * so re-read it. */ - ssl->in_msgtype = rec.type; - - ssl->in_msg = rec.buf + rec.data_offset; - ssl->in_msglen = rec.data_len; - - return 0; -} - -int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* If we're in the middle of a fragmented TLS handshake message, - * we don't accept any other message type. For TLS 1.3, the spec forbids - * interleaving other message types between handshake fragments. For TLS - * 1.2, the spec does not forbid it but we do. */ - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM && - ssl->badmac_seen_or_in_hsfraglen != 0 && - ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("non-handshake message in the middle" - " of a fragmented handshake message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - /* - * Handle particular types of records - */ - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) { - if ((ret = mbedtls_ssl_prepare_handshake_record(ssl)) != 0) { - return ret; - } - } - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { - if (ssl->in_msglen != 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET, - ssl->in_msglen)); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - if (ssl->in_msg[0] != 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, content: %02x", - ssl->in_msg[0])); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && - ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) { - if (ssl->handshake == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("dropping ChangeCipherSpec outside handshake")); - return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("received out-of-order ChangeCipherSpec - remember")); - return MBEDTLS_ERR_SSL_EARLY_MESSAGE; - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - MBEDTLS_SSL_DEBUG_MSG(2, - ("Ignore ChangeCipherSpec in TLS 1.3 compatibility mode")); - return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - } - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) { - if (ssl->in_msglen != 2) { - /* Note: Standard allows for more than one 2 byte alert - to be packed in a single message, but Mbed TLS doesn't - currently support this. */ - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid alert message, len: %" MBEDTLS_PRINTF_SIZET, - ssl->in_msglen)); - return MBEDTLS_ERR_SSL_INVALID_RECORD; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("got an alert message, type: [%u:%u]", - ssl->in_msg[0], ssl->in_msg[1])); - - /* - * Ignore non-fatal alerts, except close_notify and no_renegotiation - */ - if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("is a fatal alert message (msg %d)", - ssl->in_msg[1])); - return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE; - } - - if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY) { - MBEDTLS_SSL_DEBUG_MSG(2, ("is a close notify message")); - return MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY; - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) - if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION) { - MBEDTLS_SSL_DEBUG_MSG(2, ("is a no renegotiation alert")); - /* Will be handled when trying to parse ServerHello */ - return 0; - } -#endif - /* Silently ignore: fetch new message */ - return MBEDTLS_ERR_SSL_NON_FATAL; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* Drop unexpected ApplicationData records, - * except at the beginning of renegotiations */ - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && - mbedtls_ssl_is_handshake_over(ssl) == 0 -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && !(ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->state == MBEDTLS_SSL_SERVER_HELLO) -#endif - ) { - MBEDTLS_SSL_DEBUG_MSG(1, ("dropping unexpected ApplicationData")); - return MBEDTLS_ERR_SSL_NON_FATAL; - } - - if (ssl->handshake != NULL && - mbedtls_ssl_is_handshake_over(ssl) == 1) { - mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - return 0; -} - -int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); -} - -int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, - unsigned char level, - unsigned char message) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ssl == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (ssl->out_left != 0) { - return mbedtls_ssl_flush_output(ssl); - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> send alert message")); - MBEDTLS_SSL_DEBUG_MSG(3, ("send alert level=%u message=%u", level, message)); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; - ssl->out_msglen = 2; - ssl->out_msg[0] = level; - ssl->out_msg[1] = message; - - if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret); - return ret; - } - MBEDTLS_SSL_DEBUG_MSG(2, ("<= send alert message")); - - return 0; -} - -int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec")); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - ssl->out_msglen = 1; - ssl->out_msg[0] = 1; - - mbedtls_ssl_handshake_increment_state(ssl); - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec")); - - return 0; -} - -int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse change cipher spec")); - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad change cipher spec message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - /* CCS records are only accepted if they have length 1 and content '1', - * so we don't need to check this here. */ - - /* - * Switch to our negotiated transform and session parameters for inbound - * data. - */ - MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for inbound data")); -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - ssl->transform_in = ssl->transform_negotiate; -#endif - ssl->session_in = ssl->session_negotiate; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - mbedtls_ssl_dtls_replay_reset(ssl); -#endif - - /* Increment epoch */ - if (++ssl->in_epoch == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap")); - /* This is highly unlikely to happen for legitimate reasons, so - treat it as an attack and don't send an alert. */ - return MBEDTLS_ERR_SSL_COUNTER_WRAPPING; - } - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN); - - mbedtls_ssl_update_in_pointers(ssl); - - mbedtls_ssl_handshake_increment_state(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec")); - - return 0; -} - -/* Once ssl->out_hdr as the address of the beginning of the - * next outgoing record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->out_hdr, - * and the caller has to make sure there's space for this. - */ - -static size_t ssl_transform_get_explicit_iv_len( - mbedtls_ssl_transform const *transform) -{ - return transform->ivlen - transform->fixed_ivlen; -} - -void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ssl->out_ctr = ssl->out_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - ssl->out_len = ssl->out_cid; - if (transform != NULL) { - ssl->out_len += transform->out_cid_len; - } -#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->out_iv = ssl->out_len + 2; - } else -#endif - { - ssl->out_len = ssl->out_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->out_cid = ssl->out_len; -#endif - ssl->out_iv = ssl->out_hdr + 5; - } - - ssl->out_msg = ssl->out_iv; - /* Adjust out_msg to make space for explicit IV, if used. */ - if (transform != NULL) { - ssl->out_msg += ssl_transform_get_explicit_iv_len(transform); - } -} - -/* Once ssl->in_hdr as the address of the beginning of the - * next incoming record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->in_hdr, - * and the caller has to make sure there's space for this. - */ - -void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl) -{ - /* This function sets the pointers to match the case - * of unprotected TLS/DTLS records, with both ssl->in_iv - * and ssl->in_msg pointing to the beginning of the record - * content. - * - * When decrypting a protected record, ssl->in_msg - * will be shifted to point to the beginning of the - * record plaintext. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* This sets the header pointers to match records - * without CID. When we receive a record containing - * a CID, the fields are shifted accordingly in - * ssl_parse_record_header(). */ - ssl->in_ctr = ssl->in_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - ssl->in_len = ssl->in_cid; /* Default: no CID */ -#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - ssl->in_iv = ssl->in_len + 2; - } else -#endif - { - ssl->in_ctr = ssl->in_buf; - ssl->in_len = ssl->in_hdr + 3; -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl->in_cid = ssl->in_len; -#endif - ssl->in_iv = ssl->in_hdr + 5; - } - - /* This will be adjusted at record decryption time. */ - ssl->in_msg = ssl->in_iv; -} - -/* - * Setup an SSL context - */ - -void mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ssl->in_hdr = ssl->in_buf; - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - ssl->in_hdr = ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - } - - /* Derive other internal pointers. */ - mbedtls_ssl_update_in_pointers(ssl); -} - -void mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context *ssl) -{ - /* Set the incoming and outgoing record pointers. */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ssl->out_hdr = ssl->out_buf; - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - ssl->out_ctr = ssl->out_buf; - ssl->out_hdr = ssl->out_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - } - /* Derive other internal pointers. */ - mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */); -} - -/* - * SSL get accessors - */ -size_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl) -{ - return ssl->in_offt == NULL ? 0 : ssl->in_msglen; -} - -int mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl) -{ - /* - * Case A: We're currently holding back - * a message for further processing. - */ - - if (ssl->keep_current_message == 1) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: record held back for processing")); - return 1; - } - - /* - * Case B: Further records are pending in the current datagram. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->in_left > ssl->next_record_offset) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: more records within current datagram")); - return 1; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Case C: A handshake message is being processed. - */ - - if (ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen) { - MBEDTLS_SSL_DEBUG_MSG(3, - ("ssl_check_pending: more handshake messages within current record")); - return 1; - } - - /* - * Case D: An application data message is being processed - */ - if (ssl->in_offt != NULL) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: application data record is being processed")); - return 1; - } - - /* - * In all other cases, the rest of the message can be dropped. - * As in ssl_get_next_record, this needs to be adapted if - * we implement support for multiple alerts in single records. - */ - - MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: nothing pending")); - return 0; -} - - -int mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl) -{ - size_t transform_expansion = 0; - const mbedtls_ssl_transform *transform = ssl->transform_out; - unsigned block_size; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t key_type; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - size_t out_hdr_len = mbedtls_ssl_out_hdr_len(ssl); - - if (transform == NULL) { - return (int) out_hdr_len; - } - - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (transform->psa_alg == PSA_ALG_GCM || - transform->psa_alg == PSA_ALG_CCM || - transform->psa_alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 8) || - transform->psa_alg == PSA_ALG_CHACHA20_POLY1305 || - transform->psa_alg == MBEDTLS_SSL_NULL_CIPHER) { - transform_expansion = transform->minlen; - } else if (transform->psa_alg == PSA_ALG_CBC_NO_PADDING) { - (void) psa_get_key_attributes(transform->psa_key_enc, &attr); - key_type = psa_get_key_type(&attr); - - block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type); - - /* Expansion due to the addition of the MAC. */ - transform_expansion += transform->maclen; - - /* Expansion due to the addition of CBC padding; - * Theoretically up to 256 bytes, but we never use - * more than the block size of the underlying cipher. */ - transform_expansion += block_size; - - /* For TLS 1.2 or higher, an explicit IV is added - * after the record header. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - transform_expansion += block_size; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - } else { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Unsupported psa_alg spotted in mbedtls_ssl_get_record_expansion()")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } -#else - switch (mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc)) { - case MBEDTLS_MODE_GCM: - case MBEDTLS_MODE_CCM: - case MBEDTLS_MODE_CHACHAPOLY: - case MBEDTLS_MODE_STREAM: - transform_expansion = transform->minlen; - break; - - case MBEDTLS_MODE_CBC: - - block_size = mbedtls_cipher_get_block_size( - &transform->cipher_ctx_enc); - - /* Expansion due to the addition of the MAC. */ - transform_expansion += transform->maclen; - - /* Expansion due to the addition of CBC padding; - * Theoretically up to 256 bytes, but we never use - * more than the block size of the underlying cipher. */ - transform_expansion += block_size; - - /* For TLS 1.2 or higher, an explicit IV is added - * after the record header. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - transform_expansion += block_size; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - break; - - default: - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if (transform->out_cid_len != 0) { - transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - return (int) (out_hdr_len + transform_expansion); -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/* - * Check record counters and renegotiate if they're above the limit. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl) -{ - size_t ep_len = mbedtls_ssl_ep_len(ssl); - int in_ctr_cmp; - int out_ctr_cmp; - - if (mbedtls_ssl_is_handshake_over(ssl) == 0 || - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || - ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED) { - return 0; - } - - in_ctr_cmp = memcmp(ssl->in_ctr + ep_len, - &ssl->conf->renego_period[ep_len], - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len); - out_ctr_cmp = memcmp(&ssl->cur_out_ctr[ep_len], - &ssl->conf->renego_period[ep_len], - sizeof(ssl->cur_out_ctr) - ep_len); - - if (in_ctr_cmp <= 0 && out_ctr_cmp <= 0) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("record counter limit reached: renegotiate")); - return mbedtls_ssl_renegotiate(ssl); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#if defined(MBEDTLS_SSL_CLI_C) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_is_new_session_ticket(mbedtls_ssl_context *ssl) -{ - - if ((ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl)) || - (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET)) { - return 0; - } - - return 1; -} -#endif /* MBEDTLS_SSL_CLI_C */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) -{ - - MBEDTLS_SSL_DEBUG_MSG(3, ("received post-handshake message")); - -#if defined(MBEDTLS_SSL_CLI_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - if (ssl_tls13_is_new_session_ticket(ssl)) { -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received")); - if (mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(ssl->conf) == - MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED) { - ssl->keep_current_message = 1; - - mbedtls_ssl_handshake_set_state(ssl, - MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET); - return MBEDTLS_ERR_SSL_WANT_READ; - } else { - MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, handling disabled.")); - return 0; - } -#else - MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, not supported.")); - return 0; -#endif - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - - /* Fail in all other cases. */ - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -/* This function is called from mbedtls_ssl_read() when a handshake message is - * received after the initial handshake. In this context, handshake messages - * may only be sent for the purpose of initiating renegotiations. - * - * This function is introduced as a separate helper since the handling - * of post-handshake handshake messages changes significantly in TLS 1.3, - * and having a helper function allows to distinguish between TLS <= 1.2 and - * TLS 1.3 in the future without bloating the logic of mbedtls_ssl_read(). - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* - * - For client-side, expect SERVER_HELLO_REQUEST. - * - For server-side, expect CLIENT_HELLO. - * - Fail (TLS) or silently drop record (DTLS) in other cases. - */ - -#if defined(MBEDTLS_SSL_CLI_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - (ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl))) { - MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not HelloRequest)")); - - /* With DTLS, drop the packet (probably from last handshake) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return 0; - } -#endif - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } -#endif /* MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) { - MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not ClientHello)")); - - /* With DTLS, drop the packet (probably from last handshake) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return 0; - } -#endif - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - /* Determine whether renegotiation attempt should be accepted */ - if (!(ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || - (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == - MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION))) { - /* - * Accept renegotiation request - */ - - /* DTLS clients need to know renego is server-initiated */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; - } -#endif - - /* Keep the ClientHello message for ssl_parse_client_hello() */ - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - ssl->keep_current_message = 1; - } - ret = mbedtls_ssl_start_renegotiation(ssl); - if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation", - ret); - return ret; - } - } else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - /* - * Refuse renegotiation - */ - - MBEDTLS_SSL_DEBUG_MSG(3, ("refusing renegotiation, sending alert")); - - if ((ret = mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_WARNING, - MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION)) != 0) { - return ret; - } - } - - return 0; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) -{ - /* Check protocol version and dispatch accordingly. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - return ssl_tls13_handle_hs_message_post_handshake(ssl); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) { - return ssl_tls12_handle_hs_message_post_handshake(ssl); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - /* Should never happen */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} - -/* - * brief Read at most 'len' application data bytes from the input - * buffer. - * - * param ssl SSL context: - * - First byte of application data not read yet in the input - * buffer located at address `in_offt`. - * - The number of bytes of data not read yet is `in_msglen`. - * param buf buffer that will hold the data - * param len maximum number of bytes to read - * - * note The function updates the fields `in_offt` and `in_msglen` - * according to the number of bytes read. - * - * return The number of bytes read. - */ -static int ssl_read_application_data( - mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) -{ - size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen; - - if (len != 0) { - memcpy(buf, ssl->in_offt, n); - ssl->in_msglen -= n; - } - - /* Zeroising the plaintext buffer to erase unused application data - from the memory. */ - mbedtls_platform_zeroize(ssl->in_offt, n); - - if (ssl->in_msglen == 0) { - /* all bytes consumed */ - ssl->in_offt = NULL; - ssl->keep_current_message = 0; - } else { - /* more data available */ - ssl->in_offt += n; - } - - return (int) n; -} - -/* - * Receive application data decrypted from the SSL layer - */ -int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ssl == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> read")); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { - return ret; - } - - if (ssl->handshake != NULL && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) { - if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { - return ret; - } - } - } -#endif - - /* - * Check if renegotiation is necessary and/or handshake is - * in process. If yes, perform/continue, and fall through - * if an unexpected packet is received while the client - * is waiting for the ServerHello. - * - * (There is no equivalent to the last condition on - * the server-side as it is not treated as within - * a handshake while waiting for the ClientHello - * after a renegotiation request.) - */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ret = ssl_check_ctr_renegotiate(ssl); - if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret); - return ret; - } -#endif - - if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { - ret = mbedtls_ssl_handshake(ssl); - if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); - return ret; - } - } - - /* Loop as long as no application data record is available */ - while (ssl->in_offt == NULL) { - /* Start timer if not already running */ - if (ssl->f_get_timer != NULL && - ssl->f_get_timer(ssl->p_timer) == -1) { - mbedtls_ssl_set_timer(ssl, ssl->conf->read_timeout); - } - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - if (ret == MBEDTLS_ERR_SSL_CONN_EOF) { - return 0; - } - - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - if (ssl->in_msglen == 0 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) { - /* - * OpenSSL sends empty messages to randomize the IV - */ - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - if (ret == MBEDTLS_ERR_SSL_CONN_EOF) { - return 0; - } - - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - } - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) { - ret = ssl_handle_hs_message_post_handshake(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_handle_hs_message_post_handshake", - ret); - return ret; - } - - /* At this point, we don't know whether the renegotiation triggered - * by the post-handshake message has been completed or not. The cases - * to consider are the following: - * 1) The renegotiation is complete. In this case, no new record - * has been read yet. - * 2) The renegotiation is incomplete because the client received - * an application data record while awaiting the ServerHello. - * 3) The renegotiation is incomplete because the client received - * a non-handshake, non-application data message while awaiting - * the ServerHello. - * - * In each of these cases, looping will be the proper action: - * - For 1), the next iteration will read a new record and check - * if it's application data. - * - For 2), the loop condition isn't satisfied as application data - * is present, hence continue is the same as break - * - For 3), the loop condition is satisfied and read_record - * will re-deliver the message that was held back by the client - * when expecting the ServerHello. - */ - - continue; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) { - if (ssl->conf->renego_max_records >= 0) { - if (++ssl->renego_records_seen > ssl->conf->renego_max_records) { - MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation requested, " - "but not honored by client")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - } - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) { - MBEDTLS_SSL_DEBUG_MSG(2, ("ignoring non-fatal non-closure alert")); - return MBEDTLS_ERR_SSL_WANT_READ; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad application data message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - ssl->in_offt = ssl->in_msg; - - /* We're going to return something now, cancel timer, - * except if handshake (renegotiation) is in progress */ - if (mbedtls_ssl_is_handshake_over(ssl) == 1) { - mbedtls_ssl_set_timer(ssl, 0); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* If we requested renego but received AppData, resend HelloRequest. - * Do it now, after setting in_offt, to avoid taking this branch - * again if ssl_write_hello_request() returns WANT_WRITE */ -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) { - if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request", - ret); - return ret; - } - } -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - } - - ret = ssl_read_application_data(ssl, buf, len); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= read")); - - return ret; -} - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) -int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, - unsigned char *buf, size_t len) -{ - if (ssl == NULL || (ssl->conf == NULL)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* - * The server may receive early data only while waiting for the End of - * Early Data handshake message. - */ - if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) || - (ssl->in_offt == NULL)) { - return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; - } - - return ssl_read_application_data(ssl, buf, len); -} -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */ - -/* - * Send application data to be encrypted by the SSL layer, taking care of max - * fragment length and buffer size. - * - * According to RFC 5246 Section 6.2.1: - * - * Zero-length fragments of Application data MAY be sent as they are - * potentially useful as a traffic analysis countermeasure. - * - * Therefore, it is possible that the input message length is 0 and the - * corresponding return code is 0 on success. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_real(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) -{ - int ret = mbedtls_ssl_get_max_out_record_payload(ssl); - const size_t max_len = (size_t) ret; - - if (ret < 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_max_out_record_payload", ret); - return ret; - } - - if (len > max_len) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - MBEDTLS_SSL_DEBUG_MSG(1, ("fragment larger than the (negotiated) " - "maximum fragment length: %" MBEDTLS_PRINTF_SIZET - " > %" MBEDTLS_PRINTF_SIZET, - len, max_len)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } else -#endif - len = max_len; - } - - if (ssl->out_left != 0) { - /* - * The user has previously tried to send the data and - * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially - * written. In this case, we expect the high-level write function - * (e.g. mbedtls_ssl_write()) to be called with the same parameters - */ - if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret); - return ret; - } - } else { - /* - * The user is trying to send a message the first time, so we need to - * copy the data into the internal buffers and setup the data structure - * to keep track of partial writes - */ - ssl->out_msglen = len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; - if (len > 0) { - memcpy(ssl->out_msg, buf, len); - } - - if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret); - return ret; - } - } - - return (int) len; -} - -/* - * Write application data (public-facing wrapper) - */ -int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write")); - - if (ssl == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if ((ret = ssl_check_ctr_renegotiate(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret); - return ret; - } -#endif - - if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { - if ((ret = mbedtls_ssl_handshake(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); - return ret; - } - } - - ret = ssl_write_real(ssl, buf, len); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write")); - - return ret; -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const struct mbedtls_ssl_config *conf; - uint32_t remaining; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data")); - - if (ssl == NULL || (conf = ssl->conf) == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (conf->endpoint != MBEDTLS_SSL_IS_CLIENT) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) || - (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) { - return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; - } - - if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { - return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; - } - - /* - * If we are at the beginning of the handshake, the early data state being - * equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or - * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT advance the handshake just - * enough to be able to send early data if possible. That way, we can - * guarantee that when starting the handshake with this function we will - * send at least one record of early data. Note that when the state is - * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT and not yet - * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data - * as the early data outbound transform has not been set as we may have to - * first send a dummy CCS in clear. - */ - if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) || - (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) { - while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) || - (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) { - ret = mbedtls_ssl_handshake_step(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret); - return ret; - } - - ret = mbedtls_ssl_flush_output(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret); - return ret; - } - } - remaining = ssl->session_negotiate->max_early_data_size; - } else { - /* - * If we are past the point where we can send early data or we have - * already reached the maximum early data size, return immediately. - * Otherwise, progress the handshake as much as possible to not delay - * it too much. If we reach a point where we can still send early data, - * then we will send some. - */ - if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) && - (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) { - return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; - } - - remaining = ssl->session_negotiate->max_early_data_size - - ssl->total_early_data_size; - - if (remaining == 0) { - return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; - } - - ret = mbedtls_ssl_handshake(ssl); - if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); - return ret; - } - } - - if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) && - (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) - || (remaining == 0)) { - return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; - } - - if (len > remaining) { - len = remaining; - } - - ret = ssl_write_real(ssl, buf, len); - if (ret >= 0) { - ssl->total_early_data_size += ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret)); - - return ret; -} -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ - -/* - * Notify the peer that the connection is being closed - */ -int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ssl == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write close notify")); - - if (mbedtls_ssl_is_handshake_over(ssl) == 1) { - if ((ret = mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_WARNING, - MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_send_alert_message", ret); - return ret; - } - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write close notify")); - - return 0; -} - -void mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform) -{ - if (transform == NULL) { - return; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_destroy_key(transform->psa_key_enc); - psa_destroy_key(transform->psa_key_dec); -#else - mbedtls_cipher_free(&transform->cipher_ctx_enc); - mbedtls_cipher_free(&transform->cipher_ctx_dec); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_destroy_key(transform->psa_mac_enc); - psa_destroy_key(transform->psa_mac_dec); -#else - mbedtls_md_free(&transform->md_ctx_enc); - mbedtls_md_free(&transform->md_ctx_dec); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif - - mbedtls_platform_zeroize(transform, sizeof(mbedtls_ssl_transform)); -} - -void mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform) -{ - ssl->transform_in = transform; - memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN); -} - -void mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform) -{ - ssl->transform_out = transform; - memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr)); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -void mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl) -{ - unsigned offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if (hs == NULL) { - return; - } - - ssl_free_buffered_record(ssl); - - for (offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { - ssl_buffering_free_slot(ssl, offset); - } -} - -static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, - uint8_t slot) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; - - if (slot >= MBEDTLS_SSL_MAX_BUFFERED_HS) { - return; - } - - if (hs_buf->is_valid == 1) { - hs->buffering.total_bytes_buffered -= hs_buf->data_len; - mbedtls_zeroize_and_free(hs_buf->data, hs_buf->data_len); - memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer)); - } -} - -/* - * Shift the buffering slots to the left by `shift` positions. - * After the operation, slot i contains the previous slot i + shift. - */ -static void ssl_buffering_shift_slots(mbedtls_ssl_context *ssl, - unsigned shift) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - unsigned offset; - - if (shift == 0) { - return; - } - - if (shift >= MBEDTLS_SSL_MAX_BUFFERED_HS) { - shift = MBEDTLS_SSL_MAX_BUFFERED_HS; - } - - /* Free discarded entries */ - for (offset = 0; offset < shift; offset++) { - ssl_buffering_free_slot(ssl, offset); - } - - /* Shift remaining entries left */ - for (offset = 0; offset + shift < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { - hs->buffering.hs[offset] = hs->buffering.hs[offset + shift]; - } - - /* Reset the remaining entries at the end. Some may already have been - * cleared by the loop freeing the discarded entries, but resetting all - * of them is simpler and avoids tracking which ones were already handled. - */ - for (; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { - memset(&hs->buffering.hs[offset], 0, sizeof(hs->buffering.hs[offset])); - } -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -/* - * Convert version numbers to/from wire format - * and, for DTLS, to/from TLS equivalent. - * - * For TLS this is the identity. - * For DTLS, map as follows, then use 1's complement (v -> ~v): - * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) - * DTLS 1.0 is stored as TLS 1.1 internally - */ -void mbedtls_ssl_write_version(unsigned char version[2], int transport, - mbedtls_ssl_protocol_version tls_version) -{ - uint16_t tls_version_formatted; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - tls_version_formatted = - ~(tls_version - (tls_version == 0x0302 ? 0x0202 : 0x0201)); - } else -#else - ((void) transport); -#endif - { - tls_version_formatted = (uint16_t) tls_version; - } - MBEDTLS_PUT_UINT16_BE(tls_version_formatted, version, 0); -} - -uint16_t mbedtls_ssl_read_version(const unsigned char version[2], - int transport) -{ - uint16_t tls_version = MBEDTLS_GET_UINT16_BE(version, 0); -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - tls_version = - ~(tls_version - (tls_version == 0xfeff ? 0x0202 : 0x0201)); - } -#else - ((void) transport); -#endif - return tls_version; -} - -/* - * Send pending fatal alert. - * 0, No alert message. - * !0, if mbedtls_ssl_send_alert_message() returned in error, the error code it - * returned, ssl->alert_reason otherwise. - */ -int mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context *ssl) -{ - int ret; - - /* No pending alert, return success*/ - if (ssl->send_alert == 0) { - return 0; - } - - ret = mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - ssl->alert_type); - - /* If mbedtls_ssl_send_alert_message() returned with MBEDTLS_ERR_SSL_WANT_WRITE, - * do not clear the alert to be able to send it later. - */ - if (ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - ssl->send_alert = 0; - } - - if (ret != 0) { - return ret; - } - - return ssl->alert_reason; -} - -/* - * Set pending fatal alert flag. - */ -void mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context *ssl, - unsigned char alert_type, - int alert_reason) -{ - ssl->send_alert = 1; - ssl->alert_type = alert_type; - ssl->alert_reason = alert_reason; -} - -#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/vendor/mbedtls/library/ssl_ticket.c b/vendor/mbedtls/library/ssl_ticket.c deleted file mode 100644 index bfb656cf6..000000000 --- a/vendor/mbedtls/library/ssl_ticket.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * TLS server tickets callbacks implementation - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_TICKET_C) - -#include "mbedtls/platform.h" - -#include "ssl_misc.h" -#include "mbedtls/ssl_ticket.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) -#endif - -/* - * Initialize context - */ -void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_ssl_ticket_context)); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init(&ctx->mutex); -#endif -} - -#define MAX_KEY_BYTES MBEDTLS_SSL_TICKET_MAX_KEY_BYTES - -#define TICKET_KEY_NAME_BYTES MBEDTLS_SSL_TICKET_KEY_NAME_BYTES -#define TICKET_IV_BYTES 12 -#define TICKET_CRYPT_LEN_BYTES 2 -#define TICKET_AUTH_TAG_BYTES 16 - -#define TICKET_MIN_LEN (TICKET_KEY_NAME_BYTES + \ - TICKET_IV_BYTES + \ - TICKET_CRYPT_LEN_BYTES + \ - TICKET_AUTH_TAG_BYTES) -#define TICKET_ADD_DATA_LEN (TICKET_KEY_NAME_BYTES + \ - TICKET_IV_BYTES + \ - TICKET_CRYPT_LEN_BYTES) - -/* - * Generate/update a key - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_ticket_gen_key(mbedtls_ssl_ticket_context *ctx, - unsigned char index) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char buf[MAX_KEY_BYTES] = { 0 }; - mbedtls_ssl_ticket_key *key = ctx->keys + index; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; -#endif - -#if defined(MBEDTLS_HAVE_TIME) - key->generation_time = mbedtls_time(NULL); -#endif - /* The lifetime of a key is the configured lifetime of the tickets when - * the key is created. - */ - key->lifetime = ctx->ticket_lifetime; - - if ((ret = ctx->f_rng(ctx->p_rng, key->name, sizeof(key->name))) != 0) { - return ret; - } - - if ((ret = ctx->f_rng(ctx->p_rng, buf, sizeof(buf))) != 0) { - return ret; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_set_key_usage_flags(&attributes, - PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, key->alg); - psa_set_key_type(&attributes, key->key_type); - psa_set_key_bits(&attributes, key->key_bits); - - ret = PSA_TO_MBEDTLS_ERR( - psa_import_key(&attributes, buf, - PSA_BITS_TO_BYTES(key->key_bits), - &key->key)); -#else - /* With GCM and CCM, same context can encrypt & decrypt */ - ret = mbedtls_cipher_setkey(&key->ctx, buf, - mbedtls_cipher_get_key_bitlen(&key->ctx), - MBEDTLS_ENCRYPT); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - mbedtls_platform_zeroize(buf, sizeof(buf)); - - return ret; -} - -/* - * Rotate/generate keys if necessary - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_ticket_update_keys(mbedtls_ssl_ticket_context *ctx) -{ -#if !defined(MBEDTLS_HAVE_TIME) - ((void) ctx); -#else - mbedtls_ssl_ticket_key * const key = ctx->keys + ctx->active; - if (key->lifetime != 0) { - mbedtls_time_t current_time = mbedtls_time(NULL); - mbedtls_time_t key_time = key->generation_time; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#endif - - if (current_time >= key_time && - (uint64_t) (current_time - key_time) < key->lifetime) { - return 0; - } - - ctx->active = 1 - ctx->active; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((status = psa_destroy_key(ctx->keys[ctx->active].key)) != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - return ssl_ticket_gen_key(ctx, ctx->active); - } else -#endif /* MBEDTLS_HAVE_TIME */ - return 0; -} - -/* - * Rotate active session ticket encryption key - */ -int mbedtls_ssl_ticket_rotate(mbedtls_ssl_ticket_context *ctx, - const unsigned char *name, size_t nlength, - const unsigned char *k, size_t klength, - uint32_t lifetime) -{ - const unsigned char idx = 1 - ctx->active; - mbedtls_ssl_ticket_key * const key = ctx->keys + idx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - const size_t bitlen = key->key_bits; -#else - const int bitlen = mbedtls_cipher_get_key_bitlen(&key->ctx); -#endif - - if (nlength < TICKET_KEY_NAME_BYTES || klength * 8 < (size_t) bitlen) { - return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((status = psa_destroy_key(key->key)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - return ret; - } - - psa_set_key_usage_flags(&attributes, - PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, key->alg); - psa_set_key_type(&attributes, key->key_type); - psa_set_key_bits(&attributes, key->key_bits); - - if ((status = psa_import_key(&attributes, k, - PSA_BITS_TO_BYTES(key->key_bits), - &key->key)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - return ret; - } -#else - ret = mbedtls_cipher_setkey(&key->ctx, k, bitlen, MBEDTLS_ENCRYPT); - if (ret != 0) { - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - ctx->active = idx; - ctx->ticket_lifetime = lifetime; - memcpy(key->name, name, TICKET_KEY_NAME_BYTES); -#if defined(MBEDTLS_HAVE_TIME) - key->generation_time = mbedtls_time(NULL); -#endif - key->lifetime = lifetime; - - return 0; -} - -/* - * Setup context for actual use - */ -int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_cipher_type_t cipher, - uint32_t lifetime) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t key_bits; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_algorithm_t alg; - psa_key_type_t key_type; -#else - const mbedtls_cipher_info_t *cipher_info; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_ssl_cipher_to_psa(cipher, TICKET_AUTH_TAG_BYTES, - &alg, &key_type, &key_bits) != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (PSA_ALG_IS_AEAD(alg) == 0) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -#else - cipher_info = mbedtls_cipher_info_from_type(cipher); - - if (mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_GCM && - mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CCM && - mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CHACHAPOLY) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - key_bits = mbedtls_cipher_info_get_key_bitlen(cipher_info); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (key_bits > 8 * MAX_KEY_BYTES) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ctx->f_rng = f_rng; - ctx->p_rng = p_rng; - - ctx->ticket_lifetime = lifetime; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ctx->keys[0].alg = alg; - ctx->keys[0].key_type = key_type; - ctx->keys[0].key_bits = key_bits; - - ctx->keys[1].alg = alg; - ctx->keys[1].key_type = key_type; - ctx->keys[1].key_bits = key_bits; -#else - if ((ret = mbedtls_cipher_setup(&ctx->keys[0].ctx, cipher_info)) != 0) { - return ret; - } - - if ((ret = mbedtls_cipher_setup(&ctx->keys[1].ctx, cipher_info)) != 0) { - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if ((ret = ssl_ticket_gen_key(ctx, 0)) != 0 || - (ret = ssl_ticket_gen_key(ctx, 1)) != 0) { - return ret; - } - - return 0; -} - -/* - * Create session ticket, with the following structure: - * - * struct { - * opaque key_name[4]; - * opaque iv[12]; - * opaque encrypted_state<0..2^16-1>; - * opaque tag[16]; - * } ticket; - * - * The key_name, iv, and length of encrypted_state are the additional - * authenticated data. - */ - -int mbedtls_ssl_ticket_write(void *p_ticket, - const mbedtls_ssl_session *session, - unsigned char *start, - const unsigned char *end, - size_t *tlen, - uint32_t *ticket_lifetime) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_ticket_context *ctx = p_ticket; - mbedtls_ssl_ticket_key *key; - unsigned char *key_name = start; - unsigned char *iv = start + TICKET_KEY_NAME_BYTES; - unsigned char *state_len_bytes = iv + TICKET_IV_BYTES; - unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES; - size_t clear_len, ciph_len; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#endif - - *tlen = 0; - - if (ctx == NULL || ctx->f_rng == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag, - * in addition to session itself, that will be checked when writing it. */ - MBEDTLS_SSL_CHK_BUF_PTR(start, end, TICKET_MIN_LEN); - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - if ((ret = ssl_ticket_update_keys(ctx)) != 0) { - goto cleanup; - } - - key = &ctx->keys[ctx->active]; - - *ticket_lifetime = key->lifetime; - - memcpy(key_name, key->name, TICKET_KEY_NAME_BYTES); - - if ((ret = ctx->f_rng(ctx->p_rng, iv, TICKET_IV_BYTES)) != 0) { - goto cleanup; - } - - /* Dump session state */ - if ((ret = mbedtls_ssl_session_save(session, - state, (size_t) (end - state), - &clear_len)) != 0 || - (unsigned long) clear_len > 65535) { - goto cleanup; - } - MBEDTLS_PUT_UINT16_BE(clear_len, state_len_bytes, 0); - - /* Encrypt and authenticate */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((status = psa_aead_encrypt(key->key, key->alg, iv, TICKET_IV_BYTES, - key_name, TICKET_ADD_DATA_LEN, - state, clear_len, - state, end - state, - &ciph_len)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto cleanup; - } -#else - if ((ret = mbedtls_cipher_auth_encrypt_ext(&key->ctx, - iv, TICKET_IV_BYTES, - /* Additional data: key name, IV and length */ - key_name, TICKET_ADD_DATA_LEN, - state, clear_len, - state, (size_t) (end - state), &ciph_len, - TICKET_AUTH_TAG_BYTES)) != 0) { - goto cleanup; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (ciph_len != clear_len + TICKET_AUTH_TAG_BYTES) { - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES; - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -/* - * Select key based on name - */ -static mbedtls_ssl_ticket_key *ssl_ticket_select_key( - mbedtls_ssl_ticket_context *ctx, - const unsigned char name[4]) -{ - unsigned char i; - - for (i = 0; i < sizeof(ctx->keys) / sizeof(*ctx->keys); i++) { - if (memcmp(name, ctx->keys[i].name, 4) == 0) { - return &ctx->keys[i]; - } - } - - return NULL; -} - -/* - * Load session ticket (see mbedtls_ssl_ticket_write for structure) - */ -int mbedtls_ssl_ticket_parse(void *p_ticket, - mbedtls_ssl_session *session, - unsigned char *buf, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_ticket_context *ctx = p_ticket; - mbedtls_ssl_ticket_key *key; - unsigned char *key_name = buf; - unsigned char *iv = buf + TICKET_KEY_NAME_BYTES; - unsigned char *enc_len_p = iv + TICKET_IV_BYTES; - unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES; - size_t enc_len, clear_len; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#endif - - if (ctx == NULL || ctx->f_rng == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (len < TICKET_MIN_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) { - return ret; - } -#endif - - if ((ret = ssl_ticket_update_keys(ctx)) != 0) { - goto cleanup; - } - - enc_len = MBEDTLS_GET_UINT16_BE(enc_len_p, 0); - - if (len != TICKET_MIN_LEN + enc_len) { - ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - goto cleanup; - } - - /* Select key */ - if ((key = ssl_ticket_select_key(ctx, key_name)) == NULL) { - /* We can't know for sure but this is a likely option unless we're - * under attack - this is only informative anyway */ - ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; - goto cleanup; - } - - /* Decrypt and authenticate */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((status = psa_aead_decrypt(key->key, key->alg, iv, TICKET_IV_BYTES, - key_name, TICKET_ADD_DATA_LEN, - ticket, enc_len + TICKET_AUTH_TAG_BYTES, - ticket, enc_len, &clear_len)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto cleanup; - } -#else - if ((ret = mbedtls_cipher_auth_decrypt_ext(&key->ctx, - iv, TICKET_IV_BYTES, - /* Additional data: key name, IV and length */ - key_name, TICKET_ADD_DATA_LEN, - ticket, enc_len + TICKET_AUTH_TAG_BYTES, - ticket, enc_len, &clear_len, - TICKET_AUTH_TAG_BYTES)) != 0) { - if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) { - ret = MBEDTLS_ERR_SSL_INVALID_MAC; - } - - goto cleanup; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (clear_len != enc_len) { - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - /* Actually load session */ - if ((ret = mbedtls_ssl_session_load(session, ticket, clear_len)) != 0) { - goto cleanup; - } - -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_ms_time_t ticket_creation_time, ticket_age; - mbedtls_ms_time_t ticket_lifetime = - (mbedtls_ms_time_t) key->lifetime * 1000; - - ret = mbedtls_ssl_session_get_ticket_creation_time(session, - &ticket_creation_time); - if (ret != 0) { - goto cleanup; - } - - ticket_age = mbedtls_ms_time() - ticket_creation_time; - if (ticket_age < 0 || ticket_age > ticket_lifetime) { - ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; - goto cleanup; - } -#endif - -cleanup: -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&ctx->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif - - return ret; -} - -/* - * Free context - */ -void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx) -{ - if (ctx == NULL) { - return; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_destroy_key(ctx->keys[0].key); - psa_destroy_key(ctx->keys[1].key); -#else - mbedtls_cipher_free(&ctx->keys[0].ctx); - mbedtls_cipher_free(&ctx->keys[1].ctx); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free(&ctx->mutex); -#endif - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_ticket_context)); -} - -#endif /* MBEDTLS_SSL_TICKET_C */ diff --git a/vendor/mbedtls/library/ssl_tls.c b/vendor/mbedtls/library/ssl_tls.c deleted file mode 100644 index 1185b0b28..000000000 --- a/vendor/mbedtls/library/ssl_tls.c +++ /dev/null @@ -1,10195 +0,0 @@ -/* - * TLS shared functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * http://www.ietf.org/rfc/rfc2246.txt - * http://www.ietf.org/rfc/rfc4346.txt - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_TLS_C) - -#include "mbedtls/platform.h" - -#include "mbedtls/ssl.h" -#include "ssl_client.h" -#include "ssl_debug_helpers.h" -#include "ssl_misc.h" -#include "ssl_tls13_keys.h" - -#include "debug_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/version.h" -#include "mbedtls/constant_time.h" - -#include - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -#include "md_psa.h" -#include "psa_util_internal.h" -#include "psa/crypto.h" -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#include "mbedtls/oid.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* Define local translating functions to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) -#endif - -#if defined(MBEDTLS_TEST_HOOKS) -static mbedtls_ssl_chk_buf_ptr_args chk_buf_ptr_fail_args; - -void mbedtls_ssl_set_chk_buf_ptr_fail_args( - const uint8_t *cur, const uint8_t *end, size_t need) -{ - chk_buf_ptr_fail_args.cur = cur; - chk_buf_ptr_fail_args.end = end; - chk_buf_ptr_fail_args.need = need; -} - -void mbedtls_ssl_reset_chk_buf_ptr_fail_args(void) -{ - memset(&chk_buf_ptr_fail_args, 0, sizeof(chk_buf_ptr_fail_args)); -} - -int mbedtls_ssl_cmp_chk_buf_ptr_fail_args(mbedtls_ssl_chk_buf_ptr_args *args) -{ - return (chk_buf_ptr_fail_args.cur != args->cur) || - (chk_buf_ptr_fail_args.end != args->end) || - (chk_buf_ptr_fail_args.need != args->need); -} -#endif /* MBEDTLS_TEST_HOOKS */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -/* Top-level Connection ID API */ - -int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf, - size_t len, - int ignore_other_cid) -{ - if (len > MBEDTLS_SSL_CID_IN_LEN_MAX) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL && - ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - conf->ignore_unexpected_cid = ignore_other_cid; - conf->cid_len = len; - return 0; -} - -int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl, - int enable, - unsigned char const *own_cid, - size_t own_cid_len) -{ - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl->negotiate_cid = enable; - if (enable == MBEDTLS_SSL_CID_DISABLED) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Disable use of CID extension.")); - return 0; - } - MBEDTLS_SSL_DEBUG_MSG(3, ("Enable use of CID extension.")); - MBEDTLS_SSL_DEBUG_BUF(3, "Own CID", own_cid, own_cid_len); - - if (own_cid_len != ssl->conf->cid_len) { - MBEDTLS_SSL_DEBUG_MSG(3, ("CID length %u does not match CID length %u in config", - (unsigned) own_cid_len, - (unsigned) ssl->conf->cid_len)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - memcpy(ssl->own_cid, own_cid, own_cid_len); - /* Truncation is not an issue here because - * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */ - ssl->own_cid_len = (uint8_t) own_cid_len; - - return 0; -} - -int mbedtls_ssl_get_own_cid(mbedtls_ssl_context *ssl, - int *enabled, - unsigned char own_cid[MBEDTLS_SSL_CID_IN_LEN_MAX], - size_t *own_cid_len) -{ - *enabled = MBEDTLS_SSL_CID_DISABLED; - - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* We report MBEDTLS_SSL_CID_DISABLED in case the CID length is - * zero as this is indistinguishable from not requesting to use - * the CID extension. */ - if (ssl->own_cid_len == 0 || ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { - return 0; - } - - if (own_cid_len != NULL) { - *own_cid_len = ssl->own_cid_len; - if (own_cid != NULL) { - memcpy(own_cid, ssl->own_cid, ssl->own_cid_len); - } - } - - *enabled = MBEDTLS_SSL_CID_ENABLED; - - return 0; -} - -int mbedtls_ssl_get_peer_cid(mbedtls_ssl_context *ssl, - int *enabled, - unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX], - size_t *peer_cid_len) -{ - *enabled = MBEDTLS_SSL_CID_DISABLED; - - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || - mbedtls_ssl_is_handshake_over(ssl) == 0) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions - * were used, but client and server requested the empty CID. - * This is indistinguishable from not using the CID extension - * in the first place. */ - if (ssl->transform_in->in_cid_len == 0 && - ssl->transform_in->out_cid_len == 0) { - return 0; - } - - if (peer_cid_len != NULL) { - *peer_cid_len = ssl->transform_in->out_cid_len; - if (peer_cid != NULL) { - memcpy(peer_cid, ssl->transform_in->out_cid, - ssl->transform_in->out_cid_len); - } - } - - *enabled = MBEDTLS_SSL_CID_ENABLED; - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/* - * Convert max_fragment_length codes to length. - * RFC 6066 says: - * enum{ - * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255) - * } MaxFragmentLength; - * and we add 0 -> extension unused - */ -static unsigned int ssl_mfl_code_to_length(int mfl) -{ - switch (mfl) { - case MBEDTLS_SSL_MAX_FRAG_LEN_NONE: - return MBEDTLS_TLS_EXT_ADV_CONTENT_LEN; - case MBEDTLS_SSL_MAX_FRAG_LEN_512: - return 512; - case MBEDTLS_SSL_MAX_FRAG_LEN_1024: - return 1024; - case MBEDTLS_SSL_MAX_FRAG_LEN_2048: - return 2048; - case MBEDTLS_SSL_MAX_FRAG_LEN_4096: - return 4096; - default: - return MBEDTLS_TLS_EXT_ADV_CONTENT_LEN; - } -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -int mbedtls_ssl_session_copy(mbedtls_ssl_session *dst, - const mbedtls_ssl_session *src) -{ - mbedtls_ssl_session_free(dst); - memcpy(dst, src, sizeof(mbedtls_ssl_session)); -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - dst->ticket = NULL; -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - dst->hostname = NULL; -#endif -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_ALPN) && \ - defined(MBEDTLS_SSL_EARLY_DATA) - dst->ticket_alpn = NULL; -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if (src->peer_cert != NULL) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - dst->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt)); - if (dst->peer_cert == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - mbedtls_x509_crt_init(dst->peer_cert); - - if ((ret = mbedtls_x509_crt_parse_der(dst->peer_cert, src->peer_cert->raw.p, - src->peer_cert->raw.len)) != 0) { - mbedtls_free(dst->peer_cert); - dst->peer_cert = NULL; - return ret; - } - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (src->peer_cert_digest != NULL) { - dst->peer_cert_digest = - mbedtls_calloc(1, src->peer_cert_digest_len); - if (dst->peer_cert_digest == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(dst->peer_cert_digest, src->peer_cert_digest, - src->peer_cert_digest_len); - dst->peer_cert_digest_type = src->peer_cert_digest_type; - dst->peer_cert_digest_len = src->peer_cert_digest_len; - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_ALPN) && \ - defined(MBEDTLS_SSL_EARLY_DATA) - { - int ret = mbedtls_ssl_session_set_ticket_alpn(dst, src->ticket_alpn); - if (ret != 0) { - return ret; - } - } -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_ALPN && MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - if (src->ticket != NULL) { - dst->ticket = mbedtls_calloc(1, src->ticket_len); - if (dst->ticket == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(dst->ticket, src->ticket, src->ticket_len); - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (src->endpoint == MBEDTLS_SSL_IS_CLIENT) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ret = mbedtls_ssl_session_set_hostname(dst, src->hostname); - if (ret != 0) { - return ret; - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && - MBEDTLS_SSL_SERVER_NAME_INDICATION */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - - return 0; -} - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) -MBEDTLS_CHECK_RETURN_CRITICAL -static int resize_buffer(unsigned char **buffer, size_t len_new, size_t *len_old) -{ - unsigned char *resized_buffer = mbedtls_calloc(1, len_new); - if (resized_buffer == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - /* We want to copy len_new bytes when downsizing the buffer, and - * len_old bytes when upsizing, so we choose the smaller of two sizes, - * to fit one buffer into another. Size checks, ensuring that no data is - * lost, are done outside of this function. */ - memcpy(resized_buffer, *buffer, - (len_new < *len_old) ? len_new : *len_old); - mbedtls_zeroize_and_free(*buffer, *len_old); - - *buffer = resized_buffer; - *len_old = len_new; - - return 0; -} - -static void handle_buffer_resizing(mbedtls_ssl_context *ssl, int downsizing, - size_t in_buf_new_len, - size_t out_buf_new_len) -{ - int modified = 0; - size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0, hdr_in = 0; - size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0; - if (ssl->in_buf != NULL) { - written_in = ssl->in_msg - ssl->in_buf; - iv_offset_in = ssl->in_iv - ssl->in_buf; - len_offset_in = ssl->in_len - ssl->in_buf; - hdr_in = ssl->in_hdr - ssl->in_buf; - if (downsizing ? - ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len : - ssl->in_buf_len < in_buf_new_len) { - if (resize_buffer(&ssl->in_buf, in_buf_new_len, &ssl->in_buf_len) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("input buffer resizing failed - out of memory")); - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating in_buf to %" MBEDTLS_PRINTF_SIZET, - in_buf_new_len)); - modified = 1; - } - } - } - - if (ssl->out_buf != NULL) { - written_out = ssl->out_msg - ssl->out_buf; - iv_offset_out = ssl->out_iv - ssl->out_buf; - len_offset_out = ssl->out_len - ssl->out_buf; - if (downsizing ? - ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len : - ssl->out_buf_len < out_buf_new_len) { - if (resize_buffer(&ssl->out_buf, out_buf_new_len, &ssl->out_buf_len) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("output buffer resizing failed - out of memory")); - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("Reallocating out_buf to %" MBEDTLS_PRINTF_SIZET, - out_buf_new_len)); - modified = 1; - } - } - } - if (modified) { - /* Update pointers here to avoid doing it twice. */ - ssl->in_hdr = ssl->in_buf + hdr_in; - mbedtls_ssl_update_in_pointers(ssl); - mbedtls_ssl_reset_out_pointers(ssl); - - /* Fields below might not be properly updated with record - * splitting or with CID, so they are manually updated here. */ - ssl->out_msg = ssl->out_buf + written_out; - ssl->out_len = ssl->out_buf + len_offset_out; - ssl->out_iv = ssl->out_buf + iv_offset_out; - - ssl->in_msg = ssl->in_buf + written_in; - ssl->in_len = ssl->in_buf + len_offset_in; - ssl->in_iv = ssl->in_buf + iv_offset_in; - } -} -#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) -typedef int (*tls_prf_fn)(const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen); - -static tls_prf_fn ssl_tls12prf_from_cs(int ciphersuite_id); - -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ - -/* Type for the TLS PRF */ -typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *, - const unsigned char *, size_t, - unsigned char *, size_t); - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform, - int ciphersuite, - const unsigned char master[48], -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - int encrypt_then_mac, -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - ssl_tls_prf_t tls_prf, - const unsigned char randbytes[64], - mbedtls_ssl_protocol_version tls_version, - unsigned endpoint, - const mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_MD_CAN_SHA256) -MBEDTLS_CHECK_RETURN_CRITICAL -static int tls_prf_sha256(const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen); -static int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *); -static int ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int); - -#endif /* MBEDTLS_MD_CAN_SHA256*/ - -#if defined(MBEDTLS_MD_CAN_SHA384) -MBEDTLS_CHECK_RETURN_CRITICAL -static int tls_prf_sha384(const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen); - -static int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *); -static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int); -#endif /* MBEDTLS_MD_CAN_SHA384*/ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls12_session_load(mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len); -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -static int ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t); - -#if defined(MBEDTLS_MD_CAN_SHA256) -static int ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t); -#endif /* MBEDTLS_MD_CAN_SHA256*/ - -#if defined(MBEDTLS_MD_CAN_SHA384) -static int ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t); -#endif /* MBEDTLS_MD_CAN_SHA384*/ - -int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, - const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen) -{ - mbedtls_ssl_tls_prf_cb *tls_prf = NULL; - - switch (prf) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_SSL_TLS_PRF_SHA384: - tls_prf = tls_prf_sha384; - break; -#endif /* MBEDTLS_MD_CAN_SHA384*/ -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_SSL_TLS_PRF_SHA256: - tls_prf = tls_prf_sha256; - break; -#endif /* MBEDTLS_MD_CAN_SHA256*/ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - default: - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - return tls_prf(secret, slen, label, random, rlen, dstbuf, dlen); -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static void ssl_clear_peer_cert(mbedtls_ssl_session *session) -{ -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if (session->peer_cert != NULL) { - mbedtls_x509_crt_free(session->peer_cert); - mbedtls_free(session->peer_cert); - session->peer_cert = NULL; - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (session->peer_cert_digest != NULL) { - /* Zeroization is not necessary. */ - mbedtls_free(session->peer_cert_digest); - session->peer_cert_digest = NULL; - session->peer_cert_digest_type = MBEDTLS_MD_NONE; - session->peer_cert_digest_len = 0; - } -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -uint32_t mbedtls_ssl_get_extension_id(unsigned int extension_type) -{ - switch (extension_type) { - case MBEDTLS_TLS_EXT_SERVERNAME: - return MBEDTLS_SSL_EXT_ID_SERVERNAME; - - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - return MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH; - - case MBEDTLS_TLS_EXT_STATUS_REQUEST: - return MBEDTLS_SSL_EXT_ID_STATUS_REQUEST; - - case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS: - return MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS; - - case MBEDTLS_TLS_EXT_SIG_ALG: - return MBEDTLS_SSL_EXT_ID_SIG_ALG; - - case MBEDTLS_TLS_EXT_USE_SRTP: - return MBEDTLS_SSL_EXT_ID_USE_SRTP; - - case MBEDTLS_TLS_EXT_HEARTBEAT: - return MBEDTLS_SSL_EXT_ID_HEARTBEAT; - - case MBEDTLS_TLS_EXT_ALPN: - return MBEDTLS_SSL_EXT_ID_ALPN; - - case MBEDTLS_TLS_EXT_SCT: - return MBEDTLS_SSL_EXT_ID_SCT; - - case MBEDTLS_TLS_EXT_CLI_CERT_TYPE: - return MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE; - - case MBEDTLS_TLS_EXT_SERV_CERT_TYPE: - return MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE; - - case MBEDTLS_TLS_EXT_PADDING: - return MBEDTLS_SSL_EXT_ID_PADDING; - - case MBEDTLS_TLS_EXT_PRE_SHARED_KEY: - return MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY; - - case MBEDTLS_TLS_EXT_EARLY_DATA: - return MBEDTLS_SSL_EXT_ID_EARLY_DATA; - - case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS: - return MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS; - - case MBEDTLS_TLS_EXT_COOKIE: - return MBEDTLS_SSL_EXT_ID_COOKIE; - - case MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES: - return MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES; - - case MBEDTLS_TLS_EXT_CERT_AUTH: - return MBEDTLS_SSL_EXT_ID_CERT_AUTH; - - case MBEDTLS_TLS_EXT_OID_FILTERS: - return MBEDTLS_SSL_EXT_ID_OID_FILTERS; - - case MBEDTLS_TLS_EXT_POST_HANDSHAKE_AUTH: - return MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH; - - case MBEDTLS_TLS_EXT_SIG_ALG_CERT: - return MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT; - - case MBEDTLS_TLS_EXT_KEY_SHARE: - return MBEDTLS_SSL_EXT_ID_KEY_SHARE; - - case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: - return MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC; - - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - return MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS; - - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - return MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC; - - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - return MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET; - - case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT: - return MBEDTLS_SSL_EXT_ID_RECORD_SIZE_LIMIT; - - case MBEDTLS_TLS_EXT_SESSION_TICKET: - return MBEDTLS_SSL_EXT_ID_SESSION_TICKET; - - } - - return MBEDTLS_SSL_EXT_ID_UNRECOGNIZED; -} - -uint32_t mbedtls_ssl_get_extension_mask(unsigned int extension_type) -{ - return 1 << mbedtls_ssl_get_extension_id(extension_type); -} - -#if defined(MBEDTLS_DEBUG_C) -static const char *extension_name_table[] = { - [MBEDTLS_SSL_EXT_ID_UNRECOGNIZED] = "unrecognized", - [MBEDTLS_SSL_EXT_ID_SERVERNAME] = "server_name", - [MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH] = "max_fragment_length", - [MBEDTLS_SSL_EXT_ID_STATUS_REQUEST] = "status_request", - [MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS] = "supported_groups", - [MBEDTLS_SSL_EXT_ID_SIG_ALG] = "signature_algorithms", - [MBEDTLS_SSL_EXT_ID_USE_SRTP] = "use_srtp", - [MBEDTLS_SSL_EXT_ID_HEARTBEAT] = "heartbeat", - [MBEDTLS_SSL_EXT_ID_ALPN] = "application_layer_protocol_negotiation", - [MBEDTLS_SSL_EXT_ID_SCT] = "signed_certificate_timestamp", - [MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE] = "client_certificate_type", - [MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE] = "server_certificate_type", - [MBEDTLS_SSL_EXT_ID_PADDING] = "padding", - [MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY] = "pre_shared_key", - [MBEDTLS_SSL_EXT_ID_EARLY_DATA] = "early_data", - [MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS] = "supported_versions", - [MBEDTLS_SSL_EXT_ID_COOKIE] = "cookie", - [MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES] = "psk_key_exchange_modes", - [MBEDTLS_SSL_EXT_ID_CERT_AUTH] = "certificate_authorities", - [MBEDTLS_SSL_EXT_ID_OID_FILTERS] = "oid_filters", - [MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH] = "post_handshake_auth", - [MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT] = "signature_algorithms_cert", - [MBEDTLS_SSL_EXT_ID_KEY_SHARE] = "key_share", - [MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC] = "truncated_hmac", - [MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS] = "supported_point_formats", - [MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC] = "encrypt_then_mac", - [MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET] = "extended_master_secret", - [MBEDTLS_SSL_EXT_ID_SESSION_TICKET] = "session_ticket", - [MBEDTLS_SSL_EXT_ID_RECORD_SIZE_LIMIT] = "record_size_limit" -}; - -static const unsigned int extension_type_table[] = { - [MBEDTLS_SSL_EXT_ID_UNRECOGNIZED] = 0xff, - [MBEDTLS_SSL_EXT_ID_SERVERNAME] = MBEDTLS_TLS_EXT_SERVERNAME, - [MBEDTLS_SSL_EXT_ID_MAX_FRAGMENT_LENGTH] = MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, - [MBEDTLS_SSL_EXT_ID_STATUS_REQUEST] = MBEDTLS_TLS_EXT_STATUS_REQUEST, - [MBEDTLS_SSL_EXT_ID_SUPPORTED_GROUPS] = MBEDTLS_TLS_EXT_SUPPORTED_GROUPS, - [MBEDTLS_SSL_EXT_ID_SIG_ALG] = MBEDTLS_TLS_EXT_SIG_ALG, - [MBEDTLS_SSL_EXT_ID_USE_SRTP] = MBEDTLS_TLS_EXT_USE_SRTP, - [MBEDTLS_SSL_EXT_ID_HEARTBEAT] = MBEDTLS_TLS_EXT_HEARTBEAT, - [MBEDTLS_SSL_EXT_ID_ALPN] = MBEDTLS_TLS_EXT_ALPN, - [MBEDTLS_SSL_EXT_ID_SCT] = MBEDTLS_TLS_EXT_SCT, - [MBEDTLS_SSL_EXT_ID_CLI_CERT_TYPE] = MBEDTLS_TLS_EXT_CLI_CERT_TYPE, - [MBEDTLS_SSL_EXT_ID_SERV_CERT_TYPE] = MBEDTLS_TLS_EXT_SERV_CERT_TYPE, - [MBEDTLS_SSL_EXT_ID_PADDING] = MBEDTLS_TLS_EXT_PADDING, - [MBEDTLS_SSL_EXT_ID_PRE_SHARED_KEY] = MBEDTLS_TLS_EXT_PRE_SHARED_KEY, - [MBEDTLS_SSL_EXT_ID_EARLY_DATA] = MBEDTLS_TLS_EXT_EARLY_DATA, - [MBEDTLS_SSL_EXT_ID_SUPPORTED_VERSIONS] = MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, - [MBEDTLS_SSL_EXT_ID_COOKIE] = MBEDTLS_TLS_EXT_COOKIE, - [MBEDTLS_SSL_EXT_ID_PSK_KEY_EXCHANGE_MODES] = MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES, - [MBEDTLS_SSL_EXT_ID_CERT_AUTH] = MBEDTLS_TLS_EXT_CERT_AUTH, - [MBEDTLS_SSL_EXT_ID_OID_FILTERS] = MBEDTLS_TLS_EXT_OID_FILTERS, - [MBEDTLS_SSL_EXT_ID_POST_HANDSHAKE_AUTH] = MBEDTLS_TLS_EXT_POST_HANDSHAKE_AUTH, - [MBEDTLS_SSL_EXT_ID_SIG_ALG_CERT] = MBEDTLS_TLS_EXT_SIG_ALG_CERT, - [MBEDTLS_SSL_EXT_ID_KEY_SHARE] = MBEDTLS_TLS_EXT_KEY_SHARE, - [MBEDTLS_SSL_EXT_ID_TRUNCATED_HMAC] = MBEDTLS_TLS_EXT_TRUNCATED_HMAC, - [MBEDTLS_SSL_EXT_ID_SUPPORTED_POINT_FORMATS] = MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, - [MBEDTLS_SSL_EXT_ID_ENCRYPT_THEN_MAC] = MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, - [MBEDTLS_SSL_EXT_ID_EXTENDED_MASTER_SECRET] = MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, - [MBEDTLS_SSL_EXT_ID_SESSION_TICKET] = MBEDTLS_TLS_EXT_SESSION_TICKET, - [MBEDTLS_SSL_EXT_ID_RECORD_SIZE_LIMIT] = MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT -}; - -const char *mbedtls_ssl_get_extension_name(unsigned int extension_type) -{ - return extension_name_table[ - mbedtls_ssl_get_extension_id(extension_type)]; -} - -const char *mbedtls_ssl_get_hs_msg_name(int hs_msg_type) -{ - switch (hs_msg_type) { - case MBEDTLS_SSL_HS_CLIENT_HELLO: - return "ClientHello"; - case MBEDTLS_SSL_HS_SERVER_HELLO: - return "ServerHello"; - case MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST: - return "HelloRetryRequest"; - case MBEDTLS_SSL_HS_NEW_SESSION_TICKET: - return "NewSessionTicket"; - case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS: - return "EncryptedExtensions"; - case MBEDTLS_SSL_HS_CERTIFICATE: - return "Certificate"; - case MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE: - return "ServerKeyExchange"; - case MBEDTLS_SSL_HS_CERTIFICATE_REQUEST: - return "CertificateRequest"; - case MBEDTLS_SSL_HS_CERTIFICATE_VERIFY: - return "CertificateVerify"; - case MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE: - return "ClientKeyExchange"; - case MBEDTLS_SSL_HS_FINISHED: - return "Finished"; - } - return "Unknown"; -} - -void mbedtls_ssl_print_extension(const mbedtls_ssl_context *ssl, - int level, const char *file, int line, - int hs_msg_type, unsigned int extension_type, - const char *extra_msg0, const char *extra_msg1) -{ - const char *extra_msg; - if (extra_msg0 && extra_msg1) { - mbedtls_debug_print_msg( - ssl, level, file, line, - "%s: %s(%u) extension %s %s.", - mbedtls_ssl_get_hs_msg_name(hs_msg_type), - mbedtls_ssl_get_extension_name(extension_type), - extension_type, - extra_msg0, extra_msg1); - return; - } - - extra_msg = extra_msg0 ? extra_msg0 : extra_msg1; - if (extra_msg) { - mbedtls_debug_print_msg( - ssl, level, file, line, - "%s: %s(%u) extension %s.", mbedtls_ssl_get_hs_msg_name(hs_msg_type), - mbedtls_ssl_get_extension_name(extension_type), extension_type, - extra_msg); - return; - } - - mbedtls_debug_print_msg( - ssl, level, file, line, - "%s: %s(%u) extension.", mbedtls_ssl_get_hs_msg_name(hs_msg_type), - mbedtls_ssl_get_extension_name(extension_type), extension_type); -} - -void mbedtls_ssl_print_extensions(const mbedtls_ssl_context *ssl, - int level, const char *file, int line, - int hs_msg_type, uint32_t extensions_mask, - const char *extra) -{ - - for (unsigned i = 0; - i < sizeof(extension_name_table) / sizeof(extension_name_table[0]); - i++) { - mbedtls_ssl_print_extension( - ssl, level, file, line, hs_msg_type, extension_type_table[i], - extensions_mask & (1 << i) ? "exists" : "does not exist", extra); - } -} - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -static const char *ticket_flag_name_table[] = -{ - [0] = "ALLOW_PSK_RESUMPTION", - [2] = "ALLOW_PSK_EPHEMERAL_RESUMPTION", - [3] = "ALLOW_EARLY_DATA", -}; - -void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl, - int level, const char *file, int line, - unsigned int flags) -{ - size_t i; - - mbedtls_debug_print_msg(ssl, level, file, line, - "print ticket_flags (0x%02x)", flags); - - flags = flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK; - - for (i = 0; i < ARRAY_LENGTH(ticket_flag_name_table); i++) { - if ((flags & (1 << i))) { - mbedtls_debug_print_msg(ssl, level, file, line, "- %s is set.", - ticket_flag_name_table[i]); - } - } -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ - -#endif /* MBEDTLS_DEBUG_C */ - -void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info) -{ - ((void) ciphersuite_info); - -#if defined(MBEDTLS_MD_CAN_SHA384) - if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) { - ssl->handshake->update_checksum = ssl_update_checksum_sha384; - } else -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - if (ciphersuite_info->mac != MBEDTLS_MD_SHA384) { - ssl->handshake->update_checksum = ssl_update_checksum_sha256; - } else -#endif - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return; - } -} - -int mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - size_t total_hs_len) -{ - unsigned char hs_hdr[4]; - - /* Build HS header for checksum update. */ - hs_hdr[0] = MBEDTLS_BYTE_0(hs_type); - hs_hdr[1] = MBEDTLS_BYTE_2(total_hs_len); - hs_hdr[2] = MBEDTLS_BYTE_1(total_hs_len); - hs_hdr[3] = MBEDTLS_BYTE_0(total_hs_len); - - return ssl->handshake->update_checksum(ssl, hs_hdr, sizeof(hs_hdr)); -} - -int mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - unsigned char const *msg, - size_t msg_len) -{ - int ret; - ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl, hs_type, msg_len); - if (ret != 0) { - return ret; - } - return ssl->handshake->update_checksum(ssl, msg, msg_len); -} - -int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_MD_CAN_SHA256) || \ - defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#endif -#else /* SHA-256 or SHA-384 */ - ((void) ssl); -#endif /* SHA-256 or SHA-384 */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_hash_abort(&ssl->handshake->fin_sha256_psa); - if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); - } - status = psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256); - if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); - } -#else - mbedtls_md_free(&ssl->handshake->fin_sha256); - mbedtls_md_init(&ssl->handshake->fin_sha256); - ret = mbedtls_md_setup(&ssl->handshake->fin_sha256, - mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), - 0); - if (ret != 0) { - return ret; - } - ret = mbedtls_md_starts(&ssl->handshake->fin_sha256); - if (ret != 0) { - return ret; - } -#endif -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_hash_abort(&ssl->handshake->fin_sha384_psa); - if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); - } - status = psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384); - if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); - } -#else - mbedtls_md_free(&ssl->handshake->fin_sha384); - mbedtls_md_init(&ssl->handshake->fin_sha384); - ret = mbedtls_md_setup(&ssl->handshake->fin_sha384, - mbedtls_md_info_from_type(MBEDTLS_MD_SHA384), 0); - if (ret != 0) { - return ret; - } - ret = mbedtls_md_starts(&ssl->handshake->fin_sha384); - if (ret != 0) { - return ret; - } -#endif -#endif - return 0; -} - -static int ssl_update_checksum_start(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) -{ -#if defined(MBEDTLS_MD_CAN_SHA256) || \ - defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#endif -#else /* SHA-256 or SHA-384 */ - ((void) ssl); - (void) buf; - (void) len; -#endif /* SHA-256 or SHA-384 */ -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len); - if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); - } -#else - ret = mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len); - if (ret != 0) { - return ret; - } -#endif -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len); - if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); - } -#else - ret = mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len); - if (ret != 0) { - return ret; - } -#endif -#endif - return 0; -} - -#if defined(MBEDTLS_MD_CAN_SHA256) -static int ssl_update_checksum_sha256(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - return mbedtls_md_error_from_psa(psa_hash_update( - &ssl->handshake->fin_sha256_psa, buf, len)); -#else - return mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len); -#endif -} -#endif - -#if defined(MBEDTLS_MD_CAN_SHA384) -static int ssl_update_checksum_sha384(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - return mbedtls_md_error_from_psa(psa_hash_update( - &ssl->handshake->fin_sha384_psa, buf, len)); -#else - return mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len); -#endif -} -#endif - -static void ssl_handshake_params_init(mbedtls_ssl_handshake_params *handshake) -{ - memset(handshake, 0, sizeof(mbedtls_ssl_handshake_params)); - -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - handshake->fin_sha256_psa = psa_hash_operation_init(); -#else - mbedtls_md_init(&handshake->fin_sha256); -#endif -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - handshake->fin_sha384_psa = psa_hash_operation_init(); -#else - mbedtls_md_init(&handshake->fin_sha384); -#endif -#endif - - handshake->update_checksum = ssl_update_checksum_start; - -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_init(&handshake->dhm_ctx); -#endif -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) - mbedtls_ecdh_init(&handshake->ecdh_ctx); -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - handshake->psa_pake_ctx = psa_pake_operation_init(); - handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT; -#else - mbedtls_ecjpake_init(&handshake->ecjpake_ctx); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_SSL_CLI_C) - handshake->ecjpake_cache = NULL; - handshake->ecjpake_cache_len = 0; -#endif -#endif - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - mbedtls_x509_crt_restart_init(&handshake->ecrs_ctx); -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_init(&handshake->peer_pubkey); -#endif -} - -void mbedtls_ssl_transform_init(mbedtls_ssl_transform *transform) -{ - memset(transform, 0, sizeof(mbedtls_ssl_transform)); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - transform->psa_key_enc = MBEDTLS_SVC_KEY_ID_INIT; - transform->psa_key_dec = MBEDTLS_SVC_KEY_ID_INIT; -#else - mbedtls_cipher_init(&transform->cipher_ctx_enc); - mbedtls_cipher_init(&transform->cipher_ctx_dec); -#endif - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - transform->psa_mac_enc = MBEDTLS_SVC_KEY_ID_INIT; - transform->psa_mac_dec = MBEDTLS_SVC_KEY_ID_INIT; -#else - mbedtls_md_init(&transform->md_ctx_enc); - mbedtls_md_init(&transform->md_ctx_dec); -#endif -#endif -} - -void mbedtls_ssl_session_init(mbedtls_ssl_session *session) -{ - memset(session, 0, sizeof(mbedtls_ssl_session)); - /* Set verify_result to -1u to indicate 'result not available'. */ - session->verify_result = 0xFFFFFFFF; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_handshake_init(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Clear old handshake information if present */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->transform_negotiate) { - mbedtls_ssl_transform_free(ssl->transform_negotiate); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - if (ssl->session_negotiate) { - mbedtls_ssl_session_free(ssl->session_negotiate); - } - if (ssl->handshake) { - mbedtls_ssl_handshake_free(ssl); - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Either the pointers are now NULL or cleared properly and can be freed. - * Now allocate missing structures. - */ - if (ssl->transform_negotiate == NULL) { - ssl->transform_negotiate = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform)); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - if (ssl->session_negotiate == NULL) { - ssl->session_negotiate = mbedtls_calloc(1, sizeof(mbedtls_ssl_session)); - } - - if (ssl->handshake == NULL) { - ssl->handshake = mbedtls_calloc(1, sizeof(mbedtls_ssl_handshake_params)); - } -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - /* If the buffers are too small - reallocate */ - - handle_buffer_resizing(ssl, 0, MBEDTLS_SSL_IN_BUFFER_LEN, - MBEDTLS_SSL_OUT_BUFFER_LEN); -#endif - - /* All pointers should exist and can be directly freed without issue */ - if (ssl->handshake == NULL || -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - ssl->transform_negotiate == NULL || -#endif - ssl->session_negotiate == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc() of ssl sub-contexts failed")); - - mbedtls_free(ssl->handshake); - ssl->handshake = NULL; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_free(ssl->transform_negotiate); - ssl->transform_negotiate = NULL; -#endif - - mbedtls_free(ssl->session_negotiate); - ssl->session_negotiate = NULL; - - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - -#if defined(MBEDTLS_SSL_EARLY_DATA) -#if defined(MBEDTLS_SSL_CLI_C) - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IDLE; -#endif -#if defined(MBEDTLS_SSL_SRV_C) - ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; -#endif - ssl->total_early_data_size = 0; -#endif /* MBEDTLS_SSL_EARLY_DATA */ - - /* Initialize structures */ - mbedtls_ssl_session_init(ssl->session_negotiate); - ssl_handshake_params_init(ssl->handshake); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_ssl_transform_init(ssl->transform_negotiate); -#endif - - /* Setup handshake checksums */ - ret = mbedtls_ssl_reset_checksum(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_reset_checksum", ret); - return ret; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_SSL_SESSION_TICKETS) - ssl->handshake->new_session_tickets_count = - ssl->conf->new_session_tickets_count; -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - ssl->handshake->alt_transform_out = ssl->transform_out; - - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; - } else { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - } - - mbedtls_ssl_set_timer(ssl, 0); - } -#endif - -/* - * curve_list is translated to IANA TLS group identifiers here because - * mbedtls_ssl_conf_curves returns void and so can't return - * any error codes. - */ -#if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - /* Heap allocate and translate curve_list from internal to IANA group ids */ - if (ssl->conf->curve_list != NULL) { - size_t length; - const mbedtls_ecp_group_id *curve_list = ssl->conf->curve_list; - - for (length = 0; (curve_list[length] != MBEDTLS_ECP_DP_NONE); length++) { - } - - /* Leave room for zero termination */ - uint16_t *group_list = mbedtls_calloc(length + 1, sizeof(uint16_t)); - if (group_list == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - for (size_t i = 0; i < length; i++) { - uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( - curve_list[i]); - if (tls_id == 0) { - mbedtls_free(group_list); - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - group_list[i] = tls_id; - } - - group_list[length] = 0; - - ssl->handshake->group_list = group_list; - ssl->handshake->group_list_heap_allocated = 1; - } else { - ssl->handshake->group_list = ssl->conf->group_list; - ssl->handshake->group_list_heap_allocated = 0; - } -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* Heap allocate and translate sig_hashes from internal hash identifiers to - signature algorithms IANA identifiers. */ - if (mbedtls_ssl_conf_is_tls12_only(ssl->conf) && - ssl->conf->sig_hashes != NULL) { - const int *md; - const int *sig_hashes = ssl->conf->sig_hashes; - size_t sig_algs_len = 0; - uint16_t *p; - - MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN - <= (SIZE_MAX - (2 * sizeof(uint16_t))), - "MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN too big"); - - for (md = sig_hashes; *md != MBEDTLS_MD_NONE; md++) { - if (mbedtls_ssl_hash_from_md_alg(*md) == MBEDTLS_SSL_HASH_NONE) { - continue; - } -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - sig_algs_len += sizeof(uint16_t); -#endif - -#if defined(MBEDTLS_RSA_C) - sig_algs_len += sizeof(uint16_t); -#endif - if (sig_algs_len > MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - } - - if (sig_algs_len < MBEDTLS_SSL_MIN_SIG_ALG_LIST_LEN) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - - ssl->handshake->sig_algs = mbedtls_calloc(1, sig_algs_len + - sizeof(uint16_t)); - if (ssl->handshake->sig_algs == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - p = (uint16_t *) ssl->handshake->sig_algs; - for (md = sig_hashes; *md != MBEDTLS_MD_NONE; md++) { - unsigned char hash = mbedtls_ssl_hash_from_md_alg(*md); - if (hash == MBEDTLS_SSL_HASH_NONE) { - continue; - } -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - *p = ((hash << 8) | MBEDTLS_SSL_SIG_ECDSA); - p++; -#endif -#if defined(MBEDTLS_RSA_C) - *p = ((hash << 8) | MBEDTLS_SSL_SIG_RSA); - p++; -#endif - } - *p = MBEDTLS_TLS_SIG_NONE; - ssl->handshake->sig_algs_heap_allocated = 1; - } else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - ssl->handshake->sig_algs_heap_allocated = 0; - } -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - return 0; -} - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -/* Dummy cookie callbacks for defaults */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_cookie_write_dummy(void *ctx, - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len) -{ - ((void) ctx); - ((void) p); - ((void) end); - ((void) cli_id); - ((void) cli_id_len); - - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_cookie_check_dummy(void *ctx, - const unsigned char *cookie, size_t cookie_len, - const unsigned char *cli_id, size_t cli_id_len) -{ - ((void) ctx); - ((void) cookie); - ((void) cookie_len); - ((void) cli_id); - ((void) cli_id_len); - - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - -/* - * Initialize an SSL context - */ -void mbedtls_ssl_init(mbedtls_ssl_context *ssl) -{ - memset(ssl, 0, sizeof(mbedtls_ssl_context)); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_conf_version_check(const mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_config *conf = ssl->conf; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (mbedtls_ssl_conf_is_tls13_only(conf)) { - if (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS 1.3 is not yet supported.")); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - MBEDTLS_SSL_DEBUG_MSG(4, ("The SSL configuration is tls13 only.")); - return 0; - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (mbedtls_ssl_conf_is_tls12_only(conf)) { - MBEDTLS_SSL_DEBUG_MSG(4, ("The SSL configuration is tls12 only.")); - return 0; - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (mbedtls_ssl_conf_is_hybrid_tls12_tls13(conf)) { - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS not yet supported in Hybrid TLS 1.3 + TLS 1.2")); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - MBEDTLS_SSL_DEBUG_MSG(4, ("The SSL configuration is TLS 1.3 or TLS 1.2.")); - return 0; - } -#endif - - MBEDTLS_SSL_DEBUG_MSG(1, ("The SSL configuration is invalid.")); - return MBEDTLS_ERR_SSL_BAD_CONFIG; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_conf_check(const mbedtls_ssl_context *ssl) -{ - int ret; - ret = ssl_conf_version_check(ssl); - if (ret != 0) { - return ret; - } - - if (ssl->conf->f_rng == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided")); - return MBEDTLS_ERR_SSL_NO_RNG; - } - - /* Space for further checks */ - - return 0; -} - -/* - * Setup an SSL context - */ - -int mbedtls_ssl_setup(mbedtls_ssl_context *ssl, - const mbedtls_ssl_config *conf) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; - - ssl->conf = conf; - - if ((ret = ssl_conf_check(ssl)) != 0) { - return ret; - } - ssl->tls_version = ssl->conf->max_tls_version; - - /* - * Prepare base structures - */ - - /* Set to NULL in case of an error condition */ - ssl->out_buf = NULL; - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - ssl->in_buf_len = in_buf_len; -#endif - ssl->in_buf = mbedtls_calloc(1, in_buf_len); - if (ssl->in_buf == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", in_buf_len)); - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto error; - } - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - ssl->out_buf_len = out_buf_len; -#endif - ssl->out_buf = mbedtls_calloc(1, out_buf_len); - if (ssl->out_buf == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", out_buf_len)); - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto error; - } - - mbedtls_ssl_reset_in_pointers(ssl); - mbedtls_ssl_reset_out_pointers(ssl); - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - memset(&ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info)); -#endif - - if ((ret = ssl_handshake_init(ssl)) != 0) { - goto error; - } - - return 0; - -error: - mbedtls_free(ssl->in_buf); - mbedtls_free(ssl->out_buf); - - ssl->conf = NULL; - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - ssl->in_buf_len = 0; - ssl->out_buf_len = 0; -#endif - ssl->in_buf = NULL; - ssl->out_buf = NULL; - - ssl->in_hdr = NULL; - ssl->in_ctr = NULL; - ssl->in_len = NULL; - ssl->in_iv = NULL; - ssl->in_msg = NULL; - - ssl->out_hdr = NULL; - ssl->out_ctr = NULL; - ssl->out_len = NULL; - ssl->out_iv = NULL; - ssl->out_msg = NULL; - - return ret; -} - -/* - * Reset an initialized and used SSL context for re-use while retaining - * all application-set variables, function pointers and data. - * - * If partial is non-zero, keep data in the input buffer and client ID. - * (Use when a DTLS client reconnects from the same port.) - */ -void mbedtls_ssl_session_reset_msg_layer(mbedtls_ssl_context *ssl, - int partial) -{ -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; - size_t out_buf_len = ssl->out_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif - -#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || !defined(MBEDTLS_SSL_SRV_C) - partial = 0; -#endif - - /* Cancel any possibly running timer */ - mbedtls_ssl_set_timer(ssl, 0); - - mbedtls_ssl_reset_in_pointers(ssl); - mbedtls_ssl_reset_out_pointers(ssl); - - /* Reset incoming message parsing */ - ssl->in_offt = NULL; - ssl->nb_zero = 0; - ssl->in_msgtype = 0; - ssl->in_msglen = 0; - ssl->in_hslen = 0; - ssl->keep_current_message = 0; - ssl->transform_in = NULL; - - /* TLS: reset in_hsfraglen, which is part of message parsing. - * DTLS: on a client reconnect, don't reset badmac_seen. */ - if (!partial) { - ssl->badmac_seen_or_in_hsfraglen = 0; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - ssl->next_record_offset = 0; - ssl->in_epoch = 0; -#endif - - /* Keep current datagram if partial == 1 */ - if (partial == 0) { - ssl->in_left = 0; - memset(ssl->in_buf, 0, in_buf_len); - } - - ssl->send_alert = 0; - - /* Reset outgoing message writing */ - ssl->out_msgtype = 0; - ssl->out_msglen = 0; - ssl->out_left = 0; - memset(ssl->out_buf, 0, out_buf_len); - memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr)); - ssl->transform_out = NULL; - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - mbedtls_ssl_dtls_replay_reset(ssl); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->transform) { - mbedtls_ssl_transform_free(ssl->transform); - mbedtls_free(ssl->transform); - ssl->transform = NULL; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_transform_free(ssl->transform_application); - mbedtls_free(ssl->transform_application); - ssl->transform_application = NULL; - - if (ssl->handshake != NULL) { -#if defined(MBEDTLS_SSL_EARLY_DATA) - mbedtls_ssl_transform_free(ssl->handshake->transform_earlydata); - mbedtls_free(ssl->handshake->transform_earlydata); - ssl->handshake->transform_earlydata = NULL; -#endif - - mbedtls_ssl_transform_free(ssl->handshake->transform_handshake); - mbedtls_free(ssl->handshake->transform_handshake); - ssl->handshake->transform_handshake = NULL; - } - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -} - -int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_REQUEST); - ssl->tls_version = ssl->conf->max_tls_version; - - mbedtls_ssl_session_reset_msg_layer(ssl, partial); - - /* Reset renegotiation state */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE; - ssl->renego_records_seen = 0; - - ssl->verify_data_len = 0; - memset(ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN); - memset(ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN); -#endif - ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION; - - ssl->session_in = NULL; - ssl->session_out = NULL; - if (ssl->session) { - mbedtls_ssl_session_free(ssl->session); - mbedtls_free(ssl->session); - ssl->session = NULL; - } - -#if defined(MBEDTLS_SSL_ALPN) - ssl->alpn_chosen = NULL; -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - int free_cli_id = 1; -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) - free_cli_id = (partial == 0); -#endif - if (free_cli_id) { - mbedtls_free(ssl->cli_id); - ssl->cli_id = NULL; - ssl->cli_id_len = 0; - } -#endif - - if ((ret = ssl_handshake_init(ssl)) != 0) { - return ret; - } - - return 0; -} - -/* - * Reset an initialized and used SSL context for re-use while retaining - * all application-set variables, function pointers and data. - */ -int mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl) -{ - return mbedtls_ssl_session_reset_int(ssl, 0); -} - -/* - * SSL set accessors - */ -void mbedtls_ssl_conf_endpoint(mbedtls_ssl_config *conf, int endpoint) -{ - conf->endpoint = endpoint; -} - -void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport) -{ - conf->transport = transport; -} - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -void mbedtls_ssl_conf_dtls_anti_replay(mbedtls_ssl_config *conf, char mode) -{ - conf->anti_replay = mode; -} -#endif - -void mbedtls_ssl_conf_dtls_badmac_limit(mbedtls_ssl_config *conf, unsigned limit) -{ - conf->badmac_limit = limit; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -void mbedtls_ssl_set_datagram_packing(mbedtls_ssl_context *ssl, - unsigned allow_packing) -{ - ssl->disable_datagram_packing = !allow_packing; -} - -void mbedtls_ssl_conf_handshake_timeout(mbedtls_ssl_config *conf, - uint32_t min, uint32_t max) -{ - conf->hs_timeout_min = min; - conf->hs_timeout_max = max; -} -#endif - -void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode) -{ - conf->authmode = authmode; -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_conf_verify(mbedtls_ssl_config *conf, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy) -{ - conf->f_vrfy = f_vrfy; - conf->p_vrfy = p_vrfy; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - conf->f_rng = f_rng; - conf->p_rng = p_rng; -} - -void mbedtls_ssl_conf_dbg(mbedtls_ssl_config *conf, - void (*f_dbg)(void *, int, const char *, int, const char *), - void *p_dbg) -{ - conf->f_dbg = f_dbg; - conf->p_dbg = p_dbg; -} - -void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl, - void *p_bio, - mbedtls_ssl_send_t *f_send, - mbedtls_ssl_recv_t *f_recv, - mbedtls_ssl_recv_timeout_t *f_recv_timeout) -{ - ssl->p_bio = p_bio; - ssl->f_send = f_send; - ssl->f_recv = f_recv; - ssl->f_recv_timeout = f_recv_timeout; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -void mbedtls_ssl_set_mtu(mbedtls_ssl_context *ssl, uint16_t mtu) -{ - ssl->mtu = mtu; -} -#endif - -void mbedtls_ssl_conf_read_timeout(mbedtls_ssl_config *conf, uint32_t timeout) -{ - conf->read_timeout = timeout; -} - -void mbedtls_ssl_set_timer_cb(mbedtls_ssl_context *ssl, - void *p_timer, - mbedtls_ssl_set_timer_t *f_set_timer, - mbedtls_ssl_get_timer_t *f_get_timer) -{ - ssl->p_timer = p_timer; - ssl->f_set_timer = f_set_timer; - ssl->f_get_timer = f_get_timer; - - /* Make sure we start with no timer running */ - mbedtls_ssl_set_timer(ssl, 0); -} - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf, - void *p_cache, - mbedtls_ssl_cache_get_t *f_get_cache, - mbedtls_ssl_cache_set_t *f_set_cache) -{ - conf->p_cache = p_cache; - conf->f_get_cache = f_get_cache; - conf->f_set_cache = f_set_cache; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ssl == NULL || - session == NULL || - ssl->session_negotiate == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (ssl->handshake->resume == 1) { - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - mbedtls_ssl_ciphersuite_from_id(session->ciphersuite); - - if (mbedtls_ssl_validate_ciphersuite( - ssl, ciphersuite_info, MBEDTLS_SSL_VERSION_TLS1_3, - MBEDTLS_SSL_VERSION_TLS1_3) != 0) { - MBEDTLS_SSL_DEBUG_MSG(4, ("%d is not a valid TLS 1.3 ciphersuite.", - session->ciphersuite)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -#else - /* - * If session tickets are not enabled, it is not possible to resume a - * TLS 1.3 session, thus do not make any change to the SSL context in - * the first place. - */ - return 0; -#endif - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - if ((ret = mbedtls_ssl_session_copy(ssl->session_negotiate, - session)) != 0) { - return ret; - } - - ssl->handshake->resume = 1; - - return 0; -} -#endif /* MBEDTLS_SSL_CLI_C */ - -void mbedtls_ssl_conf_ciphersuites(mbedtls_ssl_config *conf, - const int *ciphersuites) -{ - conf->ciphersuite_list = ciphersuites; -} - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -void mbedtls_ssl_conf_tls13_key_exchange_modes(mbedtls_ssl_config *conf, - const int kex_modes) -{ - conf->tls13_kex_modes = kex_modes & MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL; -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) -void mbedtls_ssl_conf_early_data(mbedtls_ssl_config *conf, - int early_data_enabled) -{ - conf->early_data_enabled = early_data_enabled; -} - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_max_early_data_size( - mbedtls_ssl_config *conf, uint32_t max_early_data_size) -{ - conf->max_early_data_size = max_early_data_size; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -#endif /* MBEDTLS_SSL_EARLY_DATA */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_conf_cert_profile(mbedtls_ssl_config *conf, - const mbedtls_x509_crt_profile *profile) -{ - conf->cert_profile = profile; -} - -static void ssl_key_cert_free(mbedtls_ssl_key_cert *key_cert) -{ - mbedtls_ssl_key_cert *cur = key_cert, *next; - - while (cur != NULL) { - next = cur->next; - mbedtls_free(cur); - cur = next; - } -} - -/* Append a new keycert entry to a (possibly empty) list */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_append_key_cert(mbedtls_ssl_key_cert **head, - mbedtls_x509_crt *cert, - mbedtls_pk_context *key) -{ - mbedtls_ssl_key_cert *new_cert; - - if (cert == NULL) { - /* Free list if cert is null */ - ssl_key_cert_free(*head); - *head = NULL; - return 0; - } - - new_cert = mbedtls_calloc(1, sizeof(mbedtls_ssl_key_cert)); - if (new_cert == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - new_cert->cert = cert; - new_cert->key = key; - new_cert->next = NULL; - - /* Update head if the list was null, else add to the end */ - if (*head == NULL) { - *head = new_cert; - } else { - mbedtls_ssl_key_cert *cur = *head; - while (cur->next != NULL) { - cur = cur->next; - } - cur->next = new_cert; - } - - return 0; -} - -int mbedtls_ssl_conf_own_cert(mbedtls_ssl_config *conf, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key) -{ - return ssl_append_key_cert(&conf->key_cert, own_cert, pk_key); -} - -void mbedtls_ssl_conf_ca_chain(mbedtls_ssl_config *conf, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl) -{ - conf->ca_chain = ca_chain; - conf->ca_crl = ca_crl; - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb() - * cannot be used together. */ - conf->f_ca_cb = NULL; - conf->p_ca_cb = NULL; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -} - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -void mbedtls_ssl_conf_ca_cb(mbedtls_ssl_config *conf, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb) -{ - conf->f_ca_cb = f_ca_cb; - conf->p_ca_cb = p_ca_cb; - - /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb() - * cannot be used together. */ - conf->ca_chain = NULL; - conf->ca_crl = NULL; -} -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -const unsigned char *mbedtls_ssl_get_hs_sni(mbedtls_ssl_context *ssl, - size_t *name_len) -{ - *name_len = ssl->handshake->sni_name_len; - return ssl->handshake->sni_name; -} - -int mbedtls_ssl_set_hs_own_cert(mbedtls_ssl_context *ssl, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key) -{ - return ssl_append_key_cert(&ssl->handshake->sni_key_cert, - own_cert, pk_key); -} - -void mbedtls_ssl_set_hs_ca_chain(mbedtls_ssl_context *ssl, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl) -{ - ssl->handshake->sni_ca_chain = ca_chain; - ssl->handshake->sni_ca_crl = ca_crl; -} - -#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -void mbedtls_ssl_set_hs_dn_hints(mbedtls_ssl_context *ssl, - const mbedtls_x509_crt *crt) -{ - ssl->handshake->dn_hints = crt; -} -#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ - -void mbedtls_ssl_set_hs_authmode(mbedtls_ssl_context *ssl, - int authmode) -{ - ssl->handshake->sni_authmode = authmode; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_set_verify(mbedtls_ssl_context *ssl, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy) -{ - ssl->f_vrfy = f_vrfy; - ssl->p_vrfy = p_vrfy; -} -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' }; -static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' }; - -static psa_status_t mbedtls_ssl_set_hs_ecjpake_password_common( - mbedtls_ssl_context *ssl, - mbedtls_svc_key_id_t pwd) -{ - psa_status_t status; - psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - const uint8_t *user = NULL; - size_t user_len = 0; - const uint8_t *peer = NULL; - size_t peer_len = 0; - psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE); - psa_pake_cs_set_primitive(&cipher_suite, - PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, - PSA_ECC_FAMILY_SECP_R1, - 256)); - psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256); - - status = psa_pake_setup(&ssl->handshake->psa_pake_ctx, &cipher_suite); - if (status != PSA_SUCCESS) { - return status; - } - - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - user = jpake_server_id; - user_len = sizeof(jpake_server_id); - peer = jpake_client_id; - peer_len = sizeof(jpake_client_id); - } else { - user = jpake_client_id; - user_len = sizeof(jpake_client_id); - peer = jpake_server_id; - peer_len = sizeof(jpake_server_id); - } - - status = psa_pake_set_user(&ssl->handshake->psa_pake_ctx, user, user_len); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_pake_set_peer(&ssl->handshake->psa_pake_ctx, peer, peer_len); - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_pake_set_password_key(&ssl->handshake->psa_pake_ctx, pwd); - if (status != PSA_SUCCESS) { - return status; - } - - ssl->handshake->psa_pake_ctx_is_ok = 1; - - return PSA_SUCCESS; -} - -int mbedtls_ssl_set_hs_ecjpake_password(mbedtls_ssl_context *ssl, - const unsigned char *pw, - size_t pw_len) -{ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; - - if (ssl->handshake == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* Empty password is not valid */ - if ((pw == NULL) || (pw_len == 0)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&attributes, PSA_ALG_JPAKE); - psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD); - - status = psa_import_key(&attributes, pw, pw_len, - &ssl->handshake->psa_pake_password); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = mbedtls_ssl_set_hs_ecjpake_password_common(ssl, - ssl->handshake->psa_pake_password); - if (status != PSA_SUCCESS) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - return 0; -} - -int mbedtls_ssl_set_hs_ecjpake_password_opaque(mbedtls_ssl_context *ssl, - mbedtls_svc_key_id_t pwd) -{ - psa_status_t status; - - if (ssl->handshake == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (mbedtls_svc_key_id_is_null(pwd)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - status = mbedtls_ssl_set_hs_ecjpake_password_common(ssl, pwd); - if (status != PSA_SUCCESS) { - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - return 0; -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -int mbedtls_ssl_set_hs_ecjpake_password(mbedtls_ssl_context *ssl, - const unsigned char *pw, - size_t pw_len) -{ - mbedtls_ecjpake_role role; - - if (ssl->handshake == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* Empty password is not valid */ - if ((pw == NULL) || (pw_len == 0)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - role = MBEDTLS_ECJPAKE_SERVER; - } else { - role = MBEDTLS_ECJPAKE_CLIENT; - } - - return mbedtls_ecjpake_setup(&ssl->handshake->ecjpake_ctx, - role, - MBEDTLS_MD_SHA256, - MBEDTLS_ECP_DP_SECP256R1, - pw, pw_len); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -int mbedtls_ssl_conf_has_static_psk(mbedtls_ssl_config const *conf) -{ - if (conf->psk_identity == NULL || - conf->psk_identity_len == 0) { - return 0; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) { - return 1; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (conf->psk != NULL && conf->psk_len != 0) { - return 1; - } - - return 0; -} - -static void ssl_conf_remove_psk(mbedtls_ssl_config *conf) -{ - /* Remove reference to existing PSK, if any. */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) { - /* The maintenance of the PSK key slot is the - * user's responsibility. */ - conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (conf->psk != NULL) { - mbedtls_zeroize_and_free(conf->psk, conf->psk_len); - conf->psk = NULL; - conf->psk_len = 0; - } - - /* Remove reference to PSK identity, if any. */ - if (conf->psk_identity != NULL) { - mbedtls_free(conf->psk_identity); - conf->psk_identity = NULL; - conf->psk_identity_len = 0; - } -} - -/* This function assumes that PSK identity in the SSL config is unset. - * It checks that the provided identity is well-formed and attempts - * to make a copy of it in the SSL config. - * On failure, the PSK identity in the config remains unset. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_conf_set_psk_identity(mbedtls_ssl_config *conf, - unsigned char const *psk_identity, - size_t psk_identity_len) -{ - /* Identity len will be encoded on two bytes */ - if (psk_identity == NULL || - psk_identity_len == 0 || - (psk_identity_len >> 16) != 0 || - psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - conf->psk_identity = mbedtls_calloc(1, psk_identity_len); - if (conf->psk_identity == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - conf->psk_identity_len = psk_identity_len; - memcpy(conf->psk_identity, psk_identity, conf->psk_identity_len); - - return 0; -} - -int mbedtls_ssl_conf_psk(mbedtls_ssl_config *conf, - const unsigned char *psk, size_t psk_len, - const unsigned char *psk_identity, size_t psk_identity_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* We currently only support one PSK, raw or opaque. */ - if (mbedtls_ssl_conf_has_static_psk(conf)) { - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - /* Check and set raw PSK */ - if (psk == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (psk_len == 0) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (psk_len > MBEDTLS_PSK_MAX_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if ((conf->psk = mbedtls_calloc(1, psk_len)) == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - conf->psk_len = psk_len; - memcpy(conf->psk, psk, conf->psk_len); - - /* Check and set PSK Identity */ - ret = ssl_conf_set_psk_identity(conf, psk_identity, psk_identity_len); - if (ret != 0) { - ssl_conf_remove_psk(conf); - } - - return ret; -} - -static void ssl_remove_psk(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (!mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) { - /* The maintenance of the external PSK key slot is the - * user's responsibility. */ - if (ssl->handshake->psk_opaque_is_internal) { - psa_destroy_key(ssl->handshake->psk_opaque); - ssl->handshake->psk_opaque_is_internal = 0; - } - ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT; - } -#else - if (ssl->handshake->psk != NULL) { - mbedtls_zeroize_and_free(ssl->handshake->psk, - ssl->handshake->psk_len); - ssl->handshake->psk_len = 0; - ssl->handshake->psk = NULL; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} - -int mbedtls_ssl_set_hs_psk(mbedtls_ssl_context *ssl, - const unsigned char *psk, size_t psk_len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_attributes_t key_attributes = psa_key_attributes_init(); - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_algorithm_t alg = PSA_ALG_NONE; - mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (psk == NULL || ssl->handshake == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (psk_len > MBEDTLS_PSK_MAX_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl_remove_psk(ssl); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { - if (ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384) { - alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384); - } else { - alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256); - } - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - alg = PSA_ALG_HKDF_EXTRACT(PSA_ALG_ANY_HASH); - psa_set_key_usage_flags(&key_attributes, - PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - psa_set_key_algorithm(&key_attributes, alg); - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_DERIVE); - - status = psa_import_key(&key_attributes, psk, psk_len, &key); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - /* Allow calling psa_destroy_key() on psk remove */ - ssl->handshake->psk_opaque_is_internal = 1; - return mbedtls_ssl_set_hs_psk_opaque(ssl, key); -#else - if ((ssl->handshake->psk = mbedtls_calloc(1, psk_len)) == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - ssl->handshake->psk_len = psk_len; - memcpy(ssl->handshake->psk, psk, ssl->handshake->psk_len); - - return 0; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_ssl_conf_psk_opaque(mbedtls_ssl_config *conf, - mbedtls_svc_key_id_t psk, - const unsigned char *psk_identity, - size_t psk_identity_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* We currently only support one PSK, raw or opaque. */ - if (mbedtls_ssl_conf_has_static_psk(conf)) { - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - /* Check and set opaque PSK */ - if (mbedtls_svc_key_id_is_null(psk)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - conf->psk_opaque = psk; - - /* Check and set PSK Identity */ - ret = ssl_conf_set_psk_identity(conf, psk_identity, - psk_identity_len); - if (ret != 0) { - ssl_conf_remove_psk(conf); - } - - return ret; -} - -int mbedtls_ssl_set_hs_psk_opaque(mbedtls_ssl_context *ssl, - mbedtls_svc_key_id_t psk) -{ - if ((mbedtls_svc_key_id_is_null(psk)) || - (ssl->handshake == NULL)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl_remove_psk(ssl); - ssl->handshake->psk_opaque = psk; - return 0; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_psk_cb(mbedtls_ssl_config *conf, - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_psk) -{ - conf->f_psk = f_psk; - conf->p_psk = p_psk; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static mbedtls_ssl_mode_t mbedtls_ssl_get_base_mode( - psa_algorithm_t alg) -{ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - if (alg == PSA_ALG_CBC_NO_PADDING) { - return MBEDTLS_SSL_MODE_CBC; - } -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - if (PSA_ALG_IS_AEAD(alg)) { - return MBEDTLS_SSL_MODE_AEAD; - } - return MBEDTLS_SSL_MODE_STREAM; -} - -#else /* MBEDTLS_USE_PSA_CRYPTO */ - -static mbedtls_ssl_mode_t mbedtls_ssl_get_base_mode( - mbedtls_cipher_mode_t mode) -{ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - if (mode == MBEDTLS_MODE_CBC) { - return MBEDTLS_SSL_MODE_CBC; - } -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) - if (mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM || - mode == MBEDTLS_MODE_CHACHAPOLY) { - return MBEDTLS_SSL_MODE_AEAD; - } -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ - - return MBEDTLS_SSL_MODE_STREAM; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -static mbedtls_ssl_mode_t mbedtls_ssl_get_actual_mode( - mbedtls_ssl_mode_t base_mode, - int encrypt_then_mac) -{ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - if (encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED && - base_mode == MBEDTLS_SSL_MODE_CBC) { - return MBEDTLS_SSL_MODE_CBC_ETM; - } -#else - (void) encrypt_then_mac; -#endif - return base_mode; -} - -mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_transform( - const mbedtls_ssl_transform *transform) -{ - mbedtls_ssl_mode_t base_mode = mbedtls_ssl_get_base_mode( -#if defined(MBEDTLS_USE_PSA_CRYPTO) - transform->psa_alg -#else - mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc) -#endif - ); - - int encrypt_then_mac = 0; -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - encrypt_then_mac = transform->encrypt_then_mac; -#endif - return mbedtls_ssl_get_actual_mode(base_mode, encrypt_then_mac); -} - -mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite( -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - int encrypt_then_mac, -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - const mbedtls_ssl_ciphersuite_t *suite) -{ - mbedtls_ssl_mode_t base_mode = MBEDTLS_SSL_MODE_STREAM; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; - psa_algorithm_t alg; - psa_key_type_t type; - size_t size; - status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) suite->cipher, - 0, &alg, &type, &size); - if (status == PSA_SUCCESS) { - base_mode = mbedtls_ssl_get_base_mode(alg); - } -#else - const mbedtls_cipher_info_t *cipher = - mbedtls_cipher_info_from_type((mbedtls_cipher_type_t) suite->cipher); - if (cipher != NULL) { - base_mode = - mbedtls_ssl_get_base_mode( - mbedtls_cipher_info_get_mode(cipher)); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if !defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - int encrypt_then_mac = 0; -#endif - return mbedtls_ssl_get_actual_mode(base_mode, encrypt_then_mac); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) - -psa_status_t mbedtls_ssl_cipher_to_psa(mbedtls_cipher_type_t mbedtls_cipher_type, - size_t taglen, - psa_algorithm_t *alg, - psa_key_type_t *key_type, - size_t *key_size) -{ -#if !defined(MBEDTLS_SSL_HAVE_CCM) - (void) taglen; -#endif - switch (mbedtls_cipher_type) { -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CBC) - case MBEDTLS_CIPHER_AES_128_CBC: - *alg = PSA_ALG_CBC_NO_PADDING; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_AES_128_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_AES_128_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_AES_192_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 192; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_AES_192_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 192; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CBC) - case MBEDTLS_CIPHER_AES_256_CBC: - *alg = PSA_ALG_CBC_NO_PADDING; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_AES_256_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_AES_256_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_AES; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CBC) - case MBEDTLS_CIPHER_ARIA_128_CBC: - *alg = PSA_ALG_CBC_NO_PADDING; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_ARIA_128_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_ARIA_128_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_ARIA_192_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 192; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_ARIA_192_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 192; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CBC) - case MBEDTLS_CIPHER_ARIA_256_CBC: - *alg = PSA_ALG_CBC_NO_PADDING; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_ARIA_256_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_ARIA) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_ARIA_256_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_ARIA; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CBC) - case MBEDTLS_CIPHER_CAMELLIA_128_CBC: - *alg = PSA_ALG_CBC_NO_PADDING; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_CAMELLIA_128_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_CAMELLIA_128_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 128; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_CAMELLIA_192_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 192; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_CAMELLIA_192_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 192; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CBC) - case MBEDTLS_CIPHER_CAMELLIA_256_CBC: - *alg = PSA_ALG_CBC_NO_PADDING; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_CCM) - case MBEDTLS_CIPHER_CAMELLIA_256_CCM: - *alg = taglen ? PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen) : PSA_ALG_CCM; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CAMELLIA) && defined(MBEDTLS_SSL_HAVE_GCM) - case MBEDTLS_CIPHER_CAMELLIA_256_GCM: - *alg = PSA_ALG_GCM; - *key_type = PSA_KEY_TYPE_CAMELLIA; - *key_size = 256; - break; -#endif -#if defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) - case MBEDTLS_CIPHER_CHACHA20_POLY1305: - *alg = PSA_ALG_CHACHA20_POLY1305; - *key_type = PSA_KEY_TYPE_CHACHA20; - *key_size = 256; - break; -#endif - case MBEDTLS_CIPHER_NULL: - *alg = MBEDTLS_SSL_NULL_CIPHER; - *key_type = 0; - *key_size = 0; - break; - default: - return PSA_ERROR_NOT_SUPPORTED; - } - - return PSA_SUCCESS; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) -int mbedtls_ssl_conf_dh_param_bin(mbedtls_ssl_config *conf, - const unsigned char *dhm_P, size_t P_len, - const unsigned char *dhm_G, size_t G_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_mpi_free(&conf->dhm_P); - mbedtls_mpi_free(&conf->dhm_G); - - if ((ret = mbedtls_mpi_read_binary(&conf->dhm_P, dhm_P, P_len)) != 0 || - (ret = mbedtls_mpi_read_binary(&conf->dhm_G, dhm_G, G_len)) != 0) { - mbedtls_mpi_free(&conf->dhm_P); - mbedtls_mpi_free(&conf->dhm_G); - return ret; - } - - return 0; -} - -int mbedtls_ssl_conf_dh_param_ctx(mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_mpi_free(&conf->dhm_P); - mbedtls_mpi_free(&conf->dhm_G); - - if ((ret = mbedtls_dhm_get_value(dhm_ctx, MBEDTLS_DHM_PARAM_P, - &conf->dhm_P)) != 0 || - (ret = mbedtls_dhm_get_value(dhm_ctx, MBEDTLS_DHM_PARAM_G, - &conf->dhm_G)) != 0) { - mbedtls_mpi_free(&conf->dhm_P); - mbedtls_mpi_free(&conf->dhm_G); - return ret; - } - - return 0; -} -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) -/* - * Set the minimum length for Diffie-Hellman parameters - */ -void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf, - unsigned int bitlen) -{ - conf->dhm_min_bitlen = bitlen; -} -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SSL_PROTO_TLS1_2) -/* - * Set allowed/preferred hashes for handshake signatures - */ -void mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf, - const int *hashes) -{ - conf->sig_hashes = hashes; -} -#endif /* !MBEDTLS_DEPRECATED_REMOVED && MBEDTLS_SSL_PROTO_TLS1_2 */ - -/* Configure allowed signature algorithms for handshake */ -void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf, - const uint16_t *sig_algs) -{ -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - conf->sig_hashes = NULL; -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - conf->sig_algs = sig_algs; -} -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_ECP_C) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -/* - * Set the allowed elliptic curves - * - * mbedtls_ssl_setup() takes the provided list - * and translates it to a list of IANA TLS group identifiers, - * stored in ssl->handshake->group_list. - * - */ -void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf, - const mbedtls_ecp_group_id *curve_list) -{ - conf->curve_list = curve_list; - conf->group_list = NULL; -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_ECP_C */ - -/* - * Set the allowed groups - */ -void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf, - const uint16_t *group_list) -{ -#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) - conf->curve_list = NULL; -#endif - conf->group_list = group_list; -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - -/* A magic value for `ssl->hostname` indicating that - * mbedtls_ssl_set_hostname() has been called with `NULL`. - * If mbedtls_ssl_set_hostname() has never been called on `ssl`, then - * `ssl->hostname == NULL`. */ -static const char *const ssl_hostname_skip_cn_verification = ""; - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -/** Whether mbedtls_ssl_set_hostname() has been called. - * - * \param[in] ssl SSL context - * - * \return \c 1 if mbedtls_ssl_set_hostname() has been called on \p ssl - * (including `mbedtls_ssl_set_hostname(ssl, NULL)`), - * otherwise \c 0. - */ -static int mbedtls_ssl_has_set_hostname_been_called( - const mbedtls_ssl_context *ssl) -{ - return ssl->hostname != NULL; -} -#endif - -/* Micro-optimization: don't export this function if it isn't needed outside - * of this source file. */ -#if !defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -static -#endif -const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl) -{ - if (ssl->hostname == ssl_hostname_skip_cn_verification) { - return NULL; - } - return ssl->hostname; -} - -static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl) -{ - if (ssl->hostname != NULL && - ssl->hostname != ssl_hostname_skip_cn_verification) { - mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname)); - } - ssl->hostname = NULL; -} - -int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname) -{ - /* Initialize to suppress unnecessary compiler warning */ - size_t hostname_len = 0; - - /* Check if new hostname is valid before - * making any change to current one */ - if (hostname != NULL) { - hostname_len = strlen(hostname); - - if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - } - - /* Now it's clear that we will overwrite the old hostname, - * so we can free it safely */ - mbedtls_ssl_free_hostname(ssl); - - if (hostname == NULL) { - /* Passing NULL as hostname clears the old one, but leaves a - * special marker to indicate that mbedtls_ssl_set_hostname() - * has been called. */ - /* ssl->hostname should be const, but isn't. We won't actually - * write to the buffer, so it's ok to cast away the const. */ - ssl->hostname = (char *) ssl_hostname_skip_cn_verification; - } else { - ssl->hostname = mbedtls_calloc(1, hostname_len + 1); - if (ssl->hostname == NULL) { - /* mbedtls_ssl_set_hostname() has been called, but unsuccessfully. - * Leave ssl->hostname in the same state as if the function had - * not been called, i.e. a null pointer. */ - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(ssl->hostname, hostname, hostname_len); - - ssl->hostname[hostname_len] = '\0'; - } - - return 0; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -void mbedtls_ssl_conf_sni(mbedtls_ssl_config *conf, - int (*f_sni)(void *, mbedtls_ssl_context *, - const unsigned char *, size_t), - void *p_sni) -{ - conf->f_sni = f_sni; - conf->p_sni = p_sni; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_ALPN) -int mbedtls_ssl_conf_alpn_protocols(mbedtls_ssl_config *conf, const char **protos) -{ - size_t cur_len, tot_len; - const char **p; - - /* - * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings - * MUST NOT be truncated." - * We check lengths now rather than later. - */ - tot_len = 0; - for (p = protos; *p != NULL; p++) { - cur_len = strlen(*p); - tot_len += cur_len; - - if ((cur_len == 0) || - (cur_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) || - (tot_len > MBEDTLS_SSL_MAX_ALPN_LIST_LEN)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - } - - conf->alpn_list = protos; - - return 0; -} - -const char *mbedtls_ssl_get_alpn_protocol(const mbedtls_ssl_context *ssl) -{ - return ssl->alpn_chosen; -} -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) -void mbedtls_ssl_conf_srtp_mki_value_supported(mbedtls_ssl_config *conf, - int support_mki_value) -{ - conf->dtls_srtp_mki_support = support_mki_value; -} - -int mbedtls_ssl_dtls_srtp_set_mki_value(mbedtls_ssl_context *ssl, - unsigned char *mki_value, - uint16_t mki_len) -{ - if (mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED) { - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - memcpy(ssl->dtls_srtp_info.mki_value, mki_value, mki_len); - ssl->dtls_srtp_info.mki_len = mki_len; - return 0; -} - -int mbedtls_ssl_conf_dtls_srtp_protection_profiles(mbedtls_ssl_config *conf, - const mbedtls_ssl_srtp_profile *profiles) -{ - const mbedtls_ssl_srtp_profile *p; - size_t list_size = 0; - - /* check the profiles list: all entry must be valid, - * its size cannot be more than the total number of supported profiles, currently 4 */ - for (p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET && - list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH; - p++) { - if (mbedtls_ssl_check_srtp_profile_value(*p) != MBEDTLS_TLS_SRTP_UNSET) { - list_size++; - } else { - /* unsupported value, stop parsing and set the size to an error value */ - list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1; - } - } - - if (list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH) { - conf->dtls_srtp_profile_list = NULL; - conf->dtls_srtp_profile_list_len = 0; - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - conf->dtls_srtp_profile_list = profiles; - conf->dtls_srtp_profile_list_len = list_size; - - return 0; -} - -void mbedtls_ssl_get_dtls_srtp_negotiation_result(const mbedtls_ssl_context *ssl, - mbedtls_dtls_srtp_info *dtls_srtp_info) -{ - dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile; - /* do not copy the mki value if there is no chosen profile */ - if (dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) { - dtls_srtp_info->mki_len = 0; - } else { - dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len; - memcpy(dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value, - ssl->dtls_srtp_info.mki_len); - } -} -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -void mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, int major, int minor) -{ - conf->max_tls_version = (mbedtls_ssl_protocol_version) ((major << 8) | minor); -} - -void mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, int major, int minor) -{ - conf->min_tls_version = (mbedtls_ssl_protocol_version) ((major << 8) | minor); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_cert_req_ca_list(mbedtls_ssl_config *conf, - char cert_req_ca_list) -{ - conf->cert_req_ca_list = cert_req_ca_list; -} -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -void mbedtls_ssl_conf_encrypt_then_mac(mbedtls_ssl_config *conf, char etm) -{ - conf->encrypt_then_mac = etm; -} -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -void mbedtls_ssl_conf_extended_master_secret(mbedtls_ssl_config *conf, char ems) -{ - conf->extended_ms = ems; -} -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -int mbedtls_ssl_conf_max_frag_len(mbedtls_ssl_config *conf, unsigned char mfl_code) -{ - if (mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID || - ssl_mfl_code_to_length(mfl_code) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - conf->mfl_code = mfl_code; - - return 0; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -void mbedtls_ssl_conf_legacy_renegotiation(mbedtls_ssl_config *conf, int allow_legacy) -{ - conf->allow_legacy_renegotiation = allow_legacy; -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -void mbedtls_ssl_conf_renegotiation(mbedtls_ssl_config *conf, int renegotiation) -{ - conf->disable_renegotiation = renegotiation; -} - -void mbedtls_ssl_conf_renegotiation_enforced(mbedtls_ssl_config *conf, int max_records) -{ - conf->renego_max_records = max_records; -} - -void mbedtls_ssl_conf_renegotiation_period(mbedtls_ssl_config *conf, - const unsigned char period[8]) -{ - memcpy(conf->renego_period, period, 8); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(MBEDTLS_SSL_CLI_C) - -void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets) -{ - conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK; - conf->session_tickets |= (use_tickets != 0) << - MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT; -} - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets( - mbedtls_ssl_config *conf, int signal_new_session_tickets) -{ - conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK; - conf->session_tickets |= (signal_new_session_tickets != 0) << - MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -#endif /* MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SRV_C) - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) -void mbedtls_ssl_conf_new_session_tickets(mbedtls_ssl_config *conf, - uint16_t num_tickets) -{ - conf->new_session_tickets_count = num_tickets; -} -#endif - -void mbedtls_ssl_conf_session_tickets_cb(mbedtls_ssl_config *conf, - mbedtls_ssl_ticket_write_t *f_ticket_write, - mbedtls_ssl_ticket_parse_t *f_ticket_parse, - void *p_ticket) -{ - conf->f_ticket_write = f_ticket_write; - conf->f_ticket_parse = f_ticket_parse; - conf->p_ticket = p_ticket; -} -#endif -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -void mbedtls_ssl_set_export_keys_cb(mbedtls_ssl_context *ssl, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys) -{ - ssl->f_export_keys = f_export_keys; - ssl->p_export_keys = p_export_keys; -} - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -void mbedtls_ssl_conf_async_private_cb( - mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *async_config_data) -{ - conf->f_async_sign_start = f_async_sign; - conf->f_async_decrypt_start = f_async_decrypt; - conf->f_async_resume = f_async_resume; - conf->f_async_cancel = f_async_cancel; - conf->p_async_config_data = async_config_data; -} - -void *mbedtls_ssl_conf_get_async_config_data(const mbedtls_ssl_config *conf) -{ - return conf->p_async_config_data; -} - -void *mbedtls_ssl_get_async_operation_data(const mbedtls_ssl_context *ssl) -{ - if (ssl->handshake == NULL) { - return NULL; - } else { - return ssl->handshake->user_async_ctx; - } -} - -void mbedtls_ssl_set_async_operation_data(mbedtls_ssl_context *ssl, - void *ctx) -{ - if (ssl->handshake != NULL) { - ssl->handshake->user_async_ctx = ctx; - } -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -/* - * SSL get accessors - */ -uint32_t mbedtls_ssl_get_verify_result(const mbedtls_ssl_context *ssl) -{ - if (ssl->session != NULL) { - return ssl->session->verify_result; - } - - if (ssl->session_negotiate != NULL) { - return ssl->session_negotiate->verify_result; - } - - return 0xFFFFFFFF; -} - -int mbedtls_ssl_get_ciphersuite_id_from_ssl(const mbedtls_ssl_context *ssl) -{ - if (ssl == NULL || ssl->session == NULL) { - return 0; - } - - return ssl->session->ciphersuite; -} - -const char *mbedtls_ssl_get_ciphersuite(const mbedtls_ssl_context *ssl) -{ - if (ssl == NULL || ssl->session == NULL) { - return NULL; - } - - return mbedtls_ssl_get_ciphersuite_name(ssl->session->ciphersuite); -} - -const char *mbedtls_ssl_get_version(const mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - switch (ssl->tls_version) { - case MBEDTLS_SSL_VERSION_TLS1_2: - return "DTLSv1.2"; - default: - return "unknown (DTLS)"; - } - } -#endif - - switch (ssl->tls_version) { - case MBEDTLS_SSL_VERSION_TLS1_2: - return "TLSv1.2"; - case MBEDTLS_SSL_VERSION_TLS1_3: - return "TLSv1.3"; - default: - return "unknown"; - } -} - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - -size_t mbedtls_ssl_get_output_record_size_limit(const mbedtls_ssl_context *ssl) -{ - const size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t record_size_limit = max_len; - - if (ssl->session != NULL && - ssl->session->record_size_limit >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN && - ssl->session->record_size_limit < max_len) { - record_size_limit = ssl->session->record_size_limit; - } - - // TODO: this is currently untested - /* During a handshake, use the value being negotiated */ - if (ssl->session_negotiate != NULL && - ssl->session_negotiate->record_size_limit >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN && - ssl->session_negotiate->record_size_limit < max_len) { - record_size_limit = ssl->session_negotiate->record_size_limit; - } - - return record_size_limit; -} -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -size_t mbedtls_ssl_get_input_max_frag_len(const mbedtls_ssl_context *ssl) -{ - size_t max_len = MBEDTLS_SSL_IN_CONTENT_LEN; - size_t read_mfl; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */ - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE) { - return ssl_mfl_code_to_length(ssl->conf->mfl_code); - } -#endif - - /* Check if a smaller max length was negotiated */ - if (ssl->session_out != NULL) { - read_mfl = ssl_mfl_code_to_length(ssl->session_out->mfl_code); - if (read_mfl < max_len) { - max_len = read_mfl; - } - } - - /* During a handshake, use the value being negotiated */ - if (ssl->session_negotiate != NULL) { - read_mfl = ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code); - if (read_mfl < max_len) { - max_len = read_mfl; - } - } - - return max_len; -} - -size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl) -{ - size_t max_len; - - /* - * Assume mfl_code is correct since it was checked when set - */ - max_len = ssl_mfl_code_to_length(ssl->conf->mfl_code); - - /* Check if a smaller max length was negotiated */ - if (ssl->session_out != NULL && - ssl_mfl_code_to_length(ssl->session_out->mfl_code) < max_len) { - max_len = ssl_mfl_code_to_length(ssl->session_out->mfl_code); - } - - /* During a handshake, use the value being negotiated */ - if (ssl->session_negotiate != NULL && - ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code) < max_len) { - max_len = ssl_mfl_code_to_length(ssl->session_negotiate->mfl_code); - } - - return max_len; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -size_t mbedtls_ssl_get_current_mtu(const mbedtls_ssl_context *ssl) -{ - if (ssl->handshake == NULL || ssl->handshake->mtu == 0) { - return ssl->mtu; - } - - if (ssl->mtu == 0) { - return ssl->handshake->mtu; - } - - return ssl->mtu < ssl->handshake->mtu ? - ssl->mtu : ssl->handshake->mtu; -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -int mbedtls_ssl_get_max_out_record_payload(const mbedtls_ssl_context *ssl) -{ - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) - (void) ssl; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl); - - if (max_len > mfl) { - max_len = mfl; - } -#endif - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - const size_t record_size_limit = mbedtls_ssl_get_output_record_size_limit(ssl); - - if (max_len > record_size_limit) { - max_len = record_size_limit; - } -#endif - - if (ssl->transform_out != NULL && - ssl->transform_out->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - /* - * In TLS 1.3 case, when records are protected, `max_len` as computed - * above is the maximum length of the TLSInnerPlaintext structure that - * along the plaintext payload contains the inner content type (one byte) - * and some zero padding. Given the algorithm used for padding - * in mbedtls_ssl_encrypt_buf(), compute the maximum length for - * the plaintext payload. Round down to a multiple of - * MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY and - * subtract 1. - */ - max_len = ((max_len / MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY) * - MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY) - 1; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (mbedtls_ssl_get_current_mtu(ssl) != 0) { - const size_t mtu = mbedtls_ssl_get_current_mtu(ssl); - const int ret = mbedtls_ssl_get_record_expansion(ssl); - const size_t overhead = (size_t) ret; - - if (ret < 0) { - return ret; - } - - if (mtu <= overhead) { - MBEDTLS_SSL_DEBUG_MSG(1, ("MTU too low for record expansion")); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - if (max_len > mtu - overhead) { - max_len = mtu - overhead; - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) && \ - !defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - ((void) ssl); -#endif - - return (int) max_len; -} - -int mbedtls_ssl_get_max_in_record_payload(const mbedtls_ssl_context *ssl) -{ - size_t max_len = MBEDTLS_SSL_IN_CONTENT_LEN; - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - (void) ssl; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_input_max_frag_len(ssl); - - if (max_len > mfl) { - max_len = mfl; - } -#endif - - return (int) max_len; -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl) -{ - if (ssl == NULL || ssl->session == NULL) { - return NULL; - } - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - return ssl->session->peer_cert; -#else - return NULL; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, - mbedtls_ssl_session *dst) -{ - int ret; - - if (ssl == NULL || - dst == NULL || - ssl->session == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* Since Mbed TLS 3.0, mbedtls_ssl_get_session() is no longer - * idempotent: Each session can only be exported once. - * - * (This is in preparation for TLS 1.3 support where we will - * need the ability to export multiple sessions (aka tickets), - * which will be achieved by calling mbedtls_ssl_get_session() - * multiple times until it fails.) - * - * Check whether we have already exported the current session, - * and fail if so. - */ - if (ssl->session->exported == 1) { - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - ret = mbedtls_ssl_session_copy(dst, ssl->session); - if (ret != 0) { - return ret; - } - - /* Remember that we've exported the session. */ - ssl->session->exported = 1; - return 0; -} -#endif /* MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - -/* Serialization of TLS 1.2 sessions - * - * For more detail, see the description of ssl_session_save(). - */ -static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len) -{ - unsigned char *p = buf; - size_t used = 0; - -#if defined(MBEDTLS_HAVE_TIME) - uint64_t start; -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Time - */ -#if defined(MBEDTLS_HAVE_TIME) - used += 8; - - if (used <= buf_len) { - start = (uint64_t) session->start; - - MBEDTLS_PUT_UINT64_BE(start, p, 0); - p += 8; - } -#endif /* MBEDTLS_HAVE_TIME */ - - /* - * Basic mandatory fields - */ - used += 1 /* id_len */ - + sizeof(session->id) - + sizeof(session->master) - + 4; /* verify_result */ - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_0(session->id_len); - memcpy(p, session->id, 32); - p += 32; - - memcpy(p, session->master, 48); - p += 48; - - MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0); - p += 4; - } - - /* - * Peer's end-entity certificate - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if (session->peer_cert == NULL) { - cert_len = 0; - } else { - cert_len = session->peer_cert->raw.len; - } - - used += 3 + cert_len; - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_2(cert_len); - *p++ = MBEDTLS_BYTE_1(cert_len); - *p++ = MBEDTLS_BYTE_0(cert_len); - - if (session->peer_cert != NULL) { - memcpy(p, session->peer_cert->raw.p, cert_len); - p += cert_len; - } - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (session->peer_cert_digest != NULL) { - used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len; - if (used <= buf_len) { - *p++ = (unsigned char) session->peer_cert_digest_type; - *p++ = (unsigned char) session->peer_cert_digest_len; - memcpy(p, session->peer_cert_digest, - session->peer_cert_digest_len); - p += session->peer_cert_digest_len; - } - } else { - used += 2; - if (used <= buf_len) { - *p++ = (unsigned char) MBEDTLS_MD_NONE; - *p++ = 0; - } - } -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Session ticket if any, plus associated data - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { - used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */ - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_2(session->ticket_len); - *p++ = MBEDTLS_BYTE_1(session->ticket_len); - *p++ = MBEDTLS_BYTE_0(session->ticket_len); - - if (session->ticket != NULL) { - memcpy(p, session->ticket, session->ticket_len); - p += session->ticket_len; - } - - MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0); - p += 4; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { - used += 8; - - if (used <= buf_len) { - MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0); - p += 8; - } - } -#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - /* - * Misc extension-related info - */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - used += 1; - - if (used <= buf_len) { - *p++ = session->mfl_code; - } -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - used += 1; - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac); - } -#endif - - return used; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls12_session_load(mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len) -{ -#if defined(MBEDTLS_HAVE_TIME) - uint64_t start; -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - const unsigned char *p = buf; - const unsigned char * const end = buf + len; - - /* - * Time - */ -#if defined(MBEDTLS_HAVE_TIME) - if (8 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - start = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; - - session->start = (mbedtls_time_t) start; -#endif /* MBEDTLS_HAVE_TIME */ - - /* - * Basic mandatory fields - */ - if (1 + 32 + 48 + 4 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->id_len = *p++; - memcpy(session->id, p, 32); - p += 32; - - memcpy(session->master, p, 48); - p += 48; - - session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - - /* Immediately clear invalid pointer values that have been read, in case - * we exit early before we replaced them with valid ones. */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - session->peer_cert = NULL; -#else - session->peer_cert_digest = NULL; -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - session->ticket = NULL; -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - - /* - * Peer certificate - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* Deserialize CRT from the end of the ticket. */ - if (3 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - cert_len = MBEDTLS_GET_UINT24_BE(p, 0); - p += 3; - - if (cert_len != 0) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (cert_len > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt)); - - if (session->peer_cert == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - mbedtls_x509_crt_init(session->peer_cert); - - if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert, - p, cert_len)) != 0) { - mbedtls_x509_crt_free(session->peer_cert); - mbedtls_free(session->peer_cert); - session->peer_cert = NULL; - return ret; - } - - p += cert_len; - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* Deserialize CRT digest from the end of the ticket. */ - if (2 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->peer_cert_digest_type = (mbedtls_md_type_t) *p++; - session->peer_cert_digest_len = (size_t) *p++; - - if (session->peer_cert_digest_len != 0) { - const mbedtls_md_info_t *md_info = - mbedtls_md_info_from_type(session->peer_cert_digest_type); - if (md_info == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (session->peer_cert_digest_len > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->peer_cert_digest = - mbedtls_calloc(1, session->peer_cert_digest_len); - if (session->peer_cert_digest == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(session->peer_cert_digest, p, - session->peer_cert_digest_len); - p += session->peer_cert_digest_len; - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Session ticket and associated data - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { - if (3 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0); - p += 3; - - if (session->ticket_len != 0) { - if (session->ticket_len > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->ticket = mbedtls_calloc(1, session->ticket_len); - if (session->ticket == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(session->ticket, p, session->ticket_len); - p += session->ticket_len; - } - - if (4 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - } -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { - if (8 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; - } -#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - /* - * Misc extension-related info - */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - if (1 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->mfl_code = *p++; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if (1 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->encrypt_then_mac = *p++; -#endif - - /* Done, should have consumed entire buffer */ - if (p != end) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - return 0; -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -/* Serialization of TLS 1.3 sessions: - * - * For more detail, see the description of ssl_session_save(). - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen) -{ - unsigned char *p = buf; -#if defined(MBEDTLS_SSL_CLI_C) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - size_t hostname_len = (session->hostname == NULL) ? - 0 : strlen(session->hostname) + 1; -#endif - -#if defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - const size_t alpn_len = (session->ticket_alpn == NULL) ? - 0 : strlen(session->ticket_alpn) + 1; -#endif - size_t needed = 4 /* ticket_age_add */ - + 1 /* ticket_flags */ - + 1; /* resumption_key length */ - - *olen = 0; - - if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - needed += session->resumption_key_len; /* resumption_key */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) - needed += 4; /* max_early_data_size */ -#endif -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - needed += 2; /* record_size_limit */ -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_HAVE_TIME) - needed += 8; /* ticket_creation_time or ticket_reception_time */ -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - needed += 2 /* alpn_len */ - + alpn_len; /* alpn */ -#endif - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - needed += 2 /* hostname_len */ - + hostname_len; /* hostname */ -#endif - - needed += 4 /* ticket_lifetime */ - + 2; /* ticket_len */ - - /* Check size_t overflow */ - if (session->ticket_len > SIZE_MAX - needed) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - needed += session->ticket_len; /* ticket */ - } -#endif /* MBEDTLS_SSL_CLI_C */ - - *olen = needed; - if (needed > buf_len) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 0); - p[4] = session->ticket_flags; - - /* save resumption_key */ - p[5] = session->resumption_key_len; - p += 6; - memcpy(p, session->resumption_key, session->resumption_key_len); - p += session->resumption_key_len; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0); - p += 4; -#endif -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - MBEDTLS_PUT_UINT16_BE(session->record_size_limit, p, 0); - p += 2; -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { -#if defined(MBEDTLS_HAVE_TIME) - MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0); - p += 8; -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - MBEDTLS_PUT_UINT16_BE(alpn_len, p, 0); - p += 2; - - if (alpn_len > 0) { - /* save chosen alpn */ - memcpy(p, session->ticket_alpn, alpn_len); - p += alpn_len; - } -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0); - p += 2; - if (hostname_len > 0) { - /* save host name */ - memcpy(p, session->hostname, hostname_len); - p += hostname_len; - } -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_HAVE_TIME) - MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0); - p += 8; -#endif - MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0); - p += 4; - - MBEDTLS_PUT_UINT16_BE(session->ticket_len, p, 0); - p += 2; - - if (session->ticket != NULL && session->ticket_len > 0) { - memcpy(p, session->ticket, session->ticket_len); - p += session->ticket_len; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_session_load(mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len) -{ - const unsigned char *p = buf; - const unsigned char *end = buf + len; - - if (end - p < 6) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 0); - session->ticket_flags = p[4]; - - /* load resumption_key */ - session->resumption_key_len = p[5]; - p += 6; - - if (end - p < session->resumption_key_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (sizeof(session->resumption_key) < session->resumption_key_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - memcpy(session->resumption_key, p, session->resumption_key_len); - p += session->resumption_key_len; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (end - p < 4) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; -#endif -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->record_size_limit = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { -#if defined(MBEDTLS_HAVE_TIME) - if (end - p < 8) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - size_t alpn_len; - - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - alpn_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - if (end - p < (long int) alpn_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (alpn_len > 0) { - int ret = mbedtls_ssl_session_set_ticket_alpn(session, (char *) p); - if (ret != 0) { - return ret; - } - p += alpn_len; - } -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - size_t hostname_len; - /* load host name */ - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - hostname_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - if (end - p < (long int) hostname_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (hostname_len > 0) { - session->hostname = mbedtls_calloc(1, hostname_len); - if (session->hostname == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(session->hostname, p, hostname_len); - p += hostname_len; - } -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_HAVE_TIME) - if (end - p < 8) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; -#endif - if (end - p < 4) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - if (end - p < (long int) session->ticket_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (session->ticket_len > 0) { - session->ticket = mbedtls_calloc(1, session->ticket_len); - if (session->ticket == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(session->ticket, p, session->ticket_len); - p += session->ticket_len; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - - return 0; - -} -#else /* MBEDTLS_SSL_SESSION_TICKETS */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen) -{ - ((void) session); - ((void) buf); - ((void) buf_len); - *olen = 0; - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} - -static int ssl_tls13_session_load(const mbedtls_ssl_session *session, - const unsigned char *buf, - size_t buf_len) -{ - ((void) session); - ((void) buf); - ((void) buf_len); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} -#endif /* !MBEDTLS_SSL_SESSION_TICKETS */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -/* - * Define ticket header determining Mbed TLS version - * and structure of the ticket. - */ - -/* - * Define bitflag determining compile-time settings influencing - * structure of serialized SSL sessions. - */ - -#if defined(MBEDTLS_HAVE_TIME) -#define SSL_SERIALIZED_SESSION_CONFIG_TIME 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_TIME 0 -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#define SSL_SERIALIZED_SESSION_CONFIG_CRT 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0 -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 0 -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS) -#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 0 -#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -#define SSL_SERIALIZED_SESSION_CONFIG_MFL 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_MFL 0 -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -#define SSL_SERIALIZED_SESSION_CONFIG_ETM 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_ETM 0 -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0 -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -#define SSL_SERIALIZED_SESSION_CONFIG_SNI 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_SNI 0 -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) -#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 0 -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) -#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 0 -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) && \ - defined(MBEDTLS_SSL_EARLY_DATA) -#define SSL_SERIALIZED_SESSION_CONFIG_ALPN 1 -#else -#define SSL_SERIALIZED_SESSION_CONFIG_ALPN 0 -#endif /* MBEDTLS_SSL_ALPN */ - -#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0 -#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1 -#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2 -#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3 -#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 4 -#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 5 -#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT 6 -#define SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT 7 -#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT 8 -#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT 9 -#define SSL_SERIALIZED_SESSION_CONFIG_ALPN_BIT 10 - -#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \ - ((uint16_t) ( \ - (SSL_SERIALIZED_SESSION_CONFIG_TIME << SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_CRT << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << \ - SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT << \ - SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_SNI << SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA << \ - SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE << \ - SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_ALPN << \ - SSL_SERIALIZED_SESSION_CONFIG_ALPN_BIT))) - -static const unsigned char ssl_serialized_session_header[] = { - MBEDTLS_VERSION_MAJOR, - MBEDTLS_VERSION_MINOR, - MBEDTLS_VERSION_PATCH, - MBEDTLS_BYTE_1(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG), - MBEDTLS_BYTE_0(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG), -}; - -/* - * Serialize a session in the following format: - * (in the presentation language of TLS, RFC 8446 section 3) - * - * TLS 1.2 session: - * - * struct { - * #if defined(MBEDTLS_SSL_SESSION_TICKETS) - * opaque ticket<0..2^24-1>; // length 0 means no ticket - * uint32 ticket_lifetime; - * #endif - * } ClientOnlyData; - * - * struct { - * #if defined(MBEDTLS_HAVE_TIME) - * uint64 start_time; - * #endif - * uint8 session_id_len; // at most 32 - * opaque session_id[32]; - * opaque master[48]; // fixed length in the standard - * uint32 verify_result; - * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert - * #else - * uint8 peer_cert_digest_type; - * opaque peer_cert_digest<0..2^8-1> - * #endif - * select (endpoint) { - * case client: ClientOnlyData; - * case server: uint64 ticket_creation_time; - * }; - * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - * uint8 mfl_code; // up to 255 according to standard - * #endif - * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - * uint8 encrypt_then_mac; // 0 or 1 - * #endif - * } serialized_session_tls12; - * - * - * TLS 1.3 Session: - * - * struct { - * #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - * opaque hostname<0..2^16-1>; - * #endif - * #if defined(MBEDTLS_HAVE_TIME) - * uint64 ticket_reception_time; - * #endif - * uint32 ticket_lifetime; - * opaque ticket<1..2^16-1>; - * } ClientOnlyData; - * - * struct { - * uint32 ticket_age_add; - * uint8 ticket_flags; - * opaque resumption_key<0..255>; - * #if defined(MBEDTLS_SSL_EARLY_DATA) - * uint32 max_early_data_size; - * #endif - * #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - * uint16 record_size_limit; - * #endif - * select ( endpoint ) { - * case client: ClientOnlyData; - * case server: - * #if defined(MBEDTLS_HAVE_TIME) - * uint64 ticket_creation_time; - * #endif - * #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - * opaque ticket_alpn<0..256>; - * #endif - * }; - * } serialized_session_tls13; - * - * - * SSL session: - * - * struct { - * - * opaque mbedtls_version[3]; // library version: major, minor, patch - * opaque session_format[2]; // library-version specific 16-bit field - * // determining the format of the remaining - * // serialized data. - * - * Note: When updating the format, remember to keep - * these version+format bytes. - * - * // In this version, `session_format` determines - * // the setting of those compile-time - * // configuration options which influence - * // the structure of mbedtls_ssl_session. - * - * uint8_t minor_ver; // Protocol minor version. Possible values: - * // - TLS 1.2 (0x0303) - * // - TLS 1.3 (0x0304) - * uint8_t endpoint; - * uint16_t ciphersuite; - * - * select (serialized_session.tls_version) { - * - * case MBEDTLS_SSL_VERSION_TLS1_2: - * serialized_session_tls12 data; - * case MBEDTLS_SSL_VERSION_TLS1_3: - * serialized_session_tls13 data; - * - * }; - * - * } serialized_session; - * - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_session_save(const mbedtls_ssl_session *session, - unsigned char omit_header, - unsigned char *buf, - size_t buf_len, - size_t *olen) -{ - unsigned char *p = buf; - size_t used = 0; - size_t remaining_len; -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - size_t out_len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#endif - if (session == NULL) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if (!omit_header) { - /* - * Add Mbed TLS version identifier - */ - used += sizeof(ssl_serialized_session_header); - - if (used <= buf_len) { - memcpy(p, ssl_serialized_session_header, - sizeof(ssl_serialized_session_header)); - p += sizeof(ssl_serialized_session_header); - } - } - - /* - * TLS version identifier, endpoint, ciphersuite - */ - used += 1 /* TLS version */ - + 1 /* endpoint */ - + 2; /* ciphersuite */ - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_0(session->tls_version); - *p++ = session->endpoint; - MBEDTLS_PUT_UINT16_BE(session->ciphersuite, p, 0); - p += 2; - } - - /* Forward to version-specific serialization routine. */ - remaining_len = (buf_len >= used) ? buf_len - used : 0; - switch (session->tls_version) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - case MBEDTLS_SSL_VERSION_TLS1_2: - used += ssl_tls12_session_save(session, p, remaining_len); - break; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - case MBEDTLS_SSL_VERSION_TLS1_3: - ret = ssl_tls13_session_save(session, p, remaining_len, &out_len); - if (ret != 0 && ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) { - return ret; - } - used += out_len; - break; -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - default: - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - *olen = used; - if (used > buf_len) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - return 0; -} - -/* - * Public wrapper for ssl_session_save() - */ -int mbedtls_ssl_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen) -{ - return ssl_session_save(session, 0, buf, buf_len, olen); -} - -/* - * Deserialize session, see mbedtls_ssl_session_save() for format. - * - * This internal version is wrapped by a public function that cleans up in - * case of error, and has an extra option omit_header. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_session_load(mbedtls_ssl_session *session, - unsigned char omit_header, - const unsigned char *buf, - size_t len) -{ - const unsigned char *p = buf; - const unsigned char * const end = buf + len; - size_t remaining_len; - - - if (session == NULL) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if (!omit_header) { - /* - * Check Mbed TLS version identifier - */ - - if ((size_t) (end - p) < sizeof(ssl_serialized_session_header)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (memcmp(p, ssl_serialized_session_header, - sizeof(ssl_serialized_session_header)) != 0) { - return MBEDTLS_ERR_SSL_VERSION_MISMATCH; - } - p += sizeof(ssl_serialized_session_header); - } - - /* - * TLS version identifier, endpoint, ciphersuite - */ - if (4 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->tls_version = (mbedtls_ssl_protocol_version) (0x0300 | *p++); - session->endpoint = *p++; - session->ciphersuite = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* Dispatch according to TLS version. */ - remaining_len = (size_t) (end - p); - switch (session->tls_version) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - case MBEDTLS_SSL_VERSION_TLS1_2: - return ssl_tls12_session_load(session, p, remaining_len); -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - case MBEDTLS_SSL_VERSION_TLS1_3: - return ssl_tls13_session_load(session, p, remaining_len); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - default: - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -} - -/* - * Deserialize session: public wrapper for error cleaning - */ -int mbedtls_ssl_session_load(mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len) -{ - int ret = ssl_session_load(session, 0, buf, len); - - if (ret != 0) { - mbedtls_ssl_session_free(session); - } - - return ret; -} - -/* - * Perform a single step of the SSL handshake - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_prepare_handshake_step(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* - * We may have not been able to send to the peer all the handshake data - * that were written into the output buffer by the previous handshake step, - * if the write to the network callback returned with the - * #MBEDTLS_ERR_SSL_WANT_WRITE error code. - * We proceed to the next handshake step only when all data from the - * previous one have been sent to the peer, thus we make sure that this is - * the case here by calling `mbedtls_ssl_flush_output()`. The function may - * return with the #MBEDTLS_ERR_SSL_WANT_WRITE error code in which case - * we have to wait before to go ahead. - * In the case of TLS 1.3, handshake step handlers do not send data to the - * peer. Data are only sent here and through - * `mbedtls_ssl_handle_pending_alert` in case an error that triggered an - * alert occurred. - */ - if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { - return ret; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) { - if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { - return ret; - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - return ret; -} - -int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ssl == NULL || - ssl->conf == NULL || - ssl->handshake == NULL || - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ret = ssl_prepare_handshake_step(ssl); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_handle_pending_alert(ssl); - if (ret != 0) { - goto cleanup; - } - - /* If ssl->conf->endpoint is not one of MBEDTLS_SSL_IS_CLIENT or - * MBEDTLS_SSL_IS_SERVER, this is the return code we give */ - ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - -#if defined(MBEDTLS_SSL_CLI_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - MBEDTLS_SSL_DEBUG_MSG(2, ("client state: %s", - mbedtls_ssl_states_str((mbedtls_ssl_states) ssl->state))); - - switch (ssl->state) { - case MBEDTLS_SSL_HELLO_REQUEST: - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - ret = 0; - break; - - case MBEDTLS_SSL_CLIENT_HELLO: - ret = mbedtls_ssl_write_client_hello(ssl); - break; - - default: -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - ret = mbedtls_ssl_tls13_handshake_client_step(ssl); - } else { - ret = mbedtls_ssl_handshake_client_step(ssl); - } -#elif defined(MBEDTLS_SSL_PROTO_TLS1_2) - ret = mbedtls_ssl_handshake_client_step(ssl); -#else - ret = mbedtls_ssl_tls13_handshake_client_step(ssl); -#endif - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - ret = mbedtls_ssl_tls13_handshake_server_step(ssl); - } else { - ret = mbedtls_ssl_handshake_server_step(ssl); - } -#elif defined(MBEDTLS_SSL_PROTO_TLS1_2) - ret = mbedtls_ssl_handshake_server_step(ssl); -#else - ret = mbedtls_ssl_tls13_handshake_server_step(ssl); -#endif - } -#endif /* MBEDTLS_SSL_SRV_C */ - - if (ret != 0) { - /* handshake_step return error. And it is same - * with alert_reason. - */ - if (ssl->send_alert) { - ret = mbedtls_ssl_handle_pending_alert(ssl); - goto cleanup; - } - } - -cleanup: - return ret; -} - -/* - * Perform the SSL handshake - */ -int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl) -{ - int ret = 0; - - /* Sanity checks */ - - if (ssl == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - (ssl->f_set_timer == NULL || ssl->f_get_timer == NULL)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("You must use " - "mbedtls_ssl_set_timer_cb() for DTLS")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> handshake")); - - /* Main handshake loop */ - while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { - ret = mbedtls_ssl_handshake_step(ssl); - - if (ret != 0) { - break; - } - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= handshake")); - - return ret; -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -#if defined(MBEDTLS_SSL_SRV_C) -/* - * Write HelloRequest to request renegotiation on server - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_hello_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello request")); - - ssl->out_msglen = 4; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST; - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello request")); - - return 0; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -/* - * Actually renegotiate current connection, triggered by either: - * - any side: calling mbedtls_ssl_renegotiate(), - * - client: receiving a HelloRequest during mbedtls_ssl_read(), - * - server: receiving any handshake message on server during mbedtls_ssl_read() after - * the initial handshake is completed. - * If the handshake doesn't complete due to waiting for I/O, it will continue - * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively. - */ -int mbedtls_ssl_start_renegotiation(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> renegotiate")); - - if ((ret = ssl_handshake_init(ssl)) != 0) { - return ret; - } - - /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and - * the ServerHello will have message_seq = 1" */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) { - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - ssl->handshake->out_msg_seq = 1; - } else { - ssl->handshake->in_msg_seq = 1; - } - } -#endif - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_REQUEST); - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS; - - if ((ret = mbedtls_ssl_handshake(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= renegotiate")); - - return 0; -} - -/* - * Renegotiate current connection on client, - * or request renegotiation on server - */ -int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - if (ssl == NULL || ssl->conf == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_SSL_SRV_C) - /* On server, just send the request */ - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - if (mbedtls_ssl_is_handshake_over(ssl) == 0) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; - - /* Did we already try/start sending HelloRequest? */ - if (ssl->out_left != 0) { - return mbedtls_ssl_flush_output(ssl); - } - - return ssl_write_hello_request(ssl); - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) - /* - * On client, either start the renegotiation process or, - * if already in progress, continue the handshake - */ - if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { - if (mbedtls_ssl_is_handshake_over(ssl) == 0) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_ssl_start_renegotiation(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation", ret); - return ret; - } - } else { - if ((ret = mbedtls_ssl_handshake(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); - return ret; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - - return ret; -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - if (handshake == NULL) { - return; - } - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ssl->handshake->group_list_heap_allocated) { - mbedtls_free((void *) handshake->group_list); - } - handshake->group_list = NULL; -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - if (ssl->handshake->sig_algs_heap_allocated) { - mbedtls_free((void *) handshake->sig_algs); - } - handshake->sig_algs = NULL; -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->handshake->certificate_request_context) { - mbedtls_free((void *) handshake->certificate_request_context); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if (ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0) { - ssl->conf->f_async_cancel(ssl); - handshake->async_in_progress = 0; - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort(&handshake->fin_sha256_psa); -#else - mbedtls_md_free(&handshake->fin_sha256); -#endif -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort(&handshake->fin_sha384_psa); -#else - mbedtls_md_free(&handshake->fin_sha384); -#endif -#endif - -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_free(&handshake->dhm_ctx); -#endif -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) - mbedtls_ecdh_free(&handshake->ecdh_ctx); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_pake_abort(&handshake->psa_pake_ctx); - /* - * Opaque keys are not stored in the handshake's data and it's the user - * responsibility to destroy them. Clear ones, instead, are created by - * the TLS library and should be destroyed at the same level - */ - if (!mbedtls_svc_key_id_is_null(handshake->psa_pake_password)) { - psa_destroy_key(handshake->psa_pake_password); - } - handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT; -#else - mbedtls_ecjpake_free(&handshake->ecjpake_ctx); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_SSL_CLI_C) - mbedtls_free(handshake->ecjpake_cache); - handshake->ecjpake_cache = NULL; - handshake->ecjpake_cache_len = 0; -#endif -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_WITH_ECDSA_ANY_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - /* explicit void pointer cast for buggy MS compiler */ - mbedtls_free((void *) handshake->curves_tls_id); -#endif - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (!mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) { - /* The maintenance of the external PSK key slot is the - * user's responsibility. */ - if (ssl->handshake->psk_opaque_is_internal) { - psa_destroy_key(ssl->handshake->psk_opaque); - ssl->handshake->psk_opaque_is_internal = 0; - } - ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT; - } -#else - if (handshake->psk != NULL) { - mbedtls_zeroize_and_free(handshake->psk, handshake->psk_len); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - /* - * Free only the linked list wrapper, not the keys themselves - * since the belong to the SNI callback - */ - ssl_key_cert_free(handshake->sni_key_cert); -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - mbedtls_x509_crt_restart_free(&handshake->ecrs_ctx); - if (handshake->ecrs_peer_cert != NULL) { - mbedtls_x509_crt_free(handshake->ecrs_peer_cert); - mbedtls_free(handshake->ecrs_peer_cert); - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_free(&handshake->peer_pubkey); -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -#if defined(MBEDTLS_SSL_CLI_C) && \ - (defined(MBEDTLS_SSL_PROTO_DTLS) || defined(MBEDTLS_SSL_PROTO_TLS1_3)) - mbedtls_free(handshake->cookie); -#endif /* MBEDTLS_SSL_CLI_C && - ( MBEDTLS_SSL_PROTO_DTLS || MBEDTLS_SSL_PROTO_TLS1_3 ) */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - mbedtls_ssl_flight_free(handshake->flight); - mbedtls_ssl_buffering_free(ssl); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED) - if (handshake->xxdh_psa_privkey_is_external == 0) { - psa_destroy_key(handshake->xxdh_psa_privkey); - } -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_transform_free(handshake->transform_handshake); - mbedtls_free(handshake->transform_handshake); -#if defined(MBEDTLS_SSL_EARLY_DATA) - mbedtls_ssl_transform_free(handshake->transform_earlydata); - mbedtls_free(handshake->transform_earlydata); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - /* If the buffers are too big - reallocate. Because of the way Mbed TLS - * processes datagrams and the fact that a datagram is allowed to have - * several records in it, it is possible that the I/O buffers are not - * empty at this stage */ - handle_buffer_resizing(ssl, 1, mbedtls_ssl_get_input_buflen(ssl), - mbedtls_ssl_get_output_buflen(ssl)); -#endif - - /* mbedtls_platform_zeroize MUST be last one in this function */ - mbedtls_platform_zeroize(handshake, - sizeof(mbedtls_ssl_handshake_params)); -} - -void mbedtls_ssl_session_free(mbedtls_ssl_session *session) -{ - if (session == NULL) { - return; - } - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - ssl_clear_peer_cert(session); -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - mbedtls_free(session->hostname); -#endif - mbedtls_free(session->ticket); -#endif - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && \ - defined(MBEDTLS_SSL_SRV_C) - mbedtls_free(session->ticket_alpn); -#endif - - mbedtls_platform_zeroize(session, sizeof(mbedtls_ssl_session)); - - /* Set verify_result to -1u to indicate 'result not available'. */ - session->verify_result = 0xFFFFFFFF; -} - -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 1u -#else -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 0u -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 1u - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 1u -#else -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 0u -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_ALPN) -#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 1u -#else -#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 0u -#endif /* MBEDTLS_SSL_ALPN */ - -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT 0 -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT 1 -#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT 2 -#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT 3 - -#define SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG \ - ((uint32_t) ( \ - (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID << \ - SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT) | \ - (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT << \ - SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT) | \ - (SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY << \ - SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT) | \ - (SSL_SERIALIZED_CONTEXT_CONFIG_ALPN << SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT) | \ - 0u)) - -static const unsigned char ssl_serialized_context_header[] = { - MBEDTLS_VERSION_MAJOR, - MBEDTLS_VERSION_MINOR, - MBEDTLS_VERSION_PATCH, - MBEDTLS_BYTE_1(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG), - MBEDTLS_BYTE_0(SSL_SERIALIZED_SESSION_CONFIG_BITFLAG), - MBEDTLS_BYTE_2(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG), - MBEDTLS_BYTE_1(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG), - MBEDTLS_BYTE_0(SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG), -}; - -/* - * Serialize a full SSL context - * - * The format of the serialized data is: - * (in the presentation language of TLS, RFC 8446 section 3) - * - * // header - * opaque mbedtls_version[3]; // major, minor, patch - * opaque context_format[5]; // version-specific field determining - * // the format of the remaining - * // serialized data. - * Note: When updating the format, remember to keep these - * version+format bytes. (We may make their size part of the API.) - * - * // session sub-structure - * opaque session<1..2^32-1>; // see mbedtls_ssl_session_save() - * // transform sub-structure - * uint8 random[64]; // ServerHello.random+ClientHello.random - * uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value - * uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use - * // fields from ssl_context - * uint32 badmac_seen_or_in_hsfraglen; // DTLS: number of records with failing MAC - * uint64 in_window_top; // DTLS: last validated record seq_num - * uint64 in_window; // DTLS: bitmask for replay protection - * uint8 disable_datagram_packing; // DTLS: only one record per datagram - * uint64 cur_out_ctr; // Record layer: outgoing sequence number - * uint16 mtu; // DTLS: path mtu (max outgoing fragment size) - * uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol - * - * Note that many fields of the ssl_context or sub-structures are not - * serialized, as they fall in one of the following categories: - * - * 1. forced value (eg in_left must be 0) - * 2. pointer to dynamically-allocated memory (eg session, transform) - * 3. value can be re-derived from other data (eg session keys from MS) - * 4. value was temporary (eg content of input buffer) - * 5. value will be provided by the user again (eg I/O callbacks and context) - */ -int mbedtls_ssl_context_save(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t buf_len, - size_t *olen) -{ - unsigned char *p = buf; - size_t used = 0; - size_t session_len; - int ret = 0; - - /* - * Enforce usage restrictions, see "return BAD_INPUT_DATA" in - * this function's documentation. - * - * These are due to assumptions/limitations in the implementation. Some of - * them are likely to stay (no handshake in progress) some might go away - * (only DTLS) but are currently used to simplify the implementation. - */ - /* The initial handshake must be over */ - if (mbedtls_ssl_is_handshake_over(ssl) == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Initial handshake isn't over")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (ssl->handshake != NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Handshake isn't completed")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - /* Double-check that sub-structures are indeed ready */ - if (ssl->transform == NULL || ssl->session == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Serialised structures aren't ready")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - /* There must be no pending incoming or outgoing data */ - if (mbedtls_ssl_check_pending(ssl) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("There is pending incoming data")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (ssl->out_left != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("There is pending outgoing data")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - /* Protocol must be DTLS, not TLS */ - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Only DTLS is supported")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - /* Version must be 1.2 */ - if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Only version 1.2 supported")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - /* We must be using an AEAD ciphersuite */ - if (mbedtls_ssl_transform_uses_aead(ssl->transform) != 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Only AEAD ciphersuites supported")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - /* Renegotiation must not be enabled */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Renegotiation must not be enabled")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -#endif - - /* - * Version and format identifier - */ - used += sizeof(ssl_serialized_context_header); - - if (used <= buf_len) { - memcpy(p, ssl_serialized_context_header, - sizeof(ssl_serialized_context_header)); - p += sizeof(ssl_serialized_context_header); - } - - /* - * Session (length + data) - */ - ret = ssl_session_save(ssl->session, 1, NULL, 0, &session_len); - if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) { - return ret; - } - - used += 4 + session_len; - if (used <= buf_len) { - MBEDTLS_PUT_UINT32_BE(session_len, p, 0); - p += 4; - - ret = ssl_session_save(ssl->session, 1, - p, session_len, &session_len); - if (ret != 0) { - return ret; - } - - p += session_len; - } - - /* - * Transform - */ - used += sizeof(ssl->transform->randbytes); - if (used <= buf_len) { - memcpy(p, ssl->transform->randbytes, - sizeof(ssl->transform->randbytes)); - p += sizeof(ssl->transform->randbytes); - } - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - used += 2U + ssl->transform->in_cid_len + ssl->transform->out_cid_len; - if (used <= buf_len) { - *p++ = ssl->transform->in_cid_len; - memcpy(p, ssl->transform->in_cid, ssl->transform->in_cid_len); - p += ssl->transform->in_cid_len; - - *p++ = ssl->transform->out_cid_len; - memcpy(p, ssl->transform->out_cid, ssl->transform->out_cid_len); - p += ssl->transform->out_cid_len; - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /* - * Saved fields from top-level ssl_context structure - */ - used += 4; - if (used <= buf_len) { - MBEDTLS_PUT_UINT32_BE(ssl->badmac_seen_or_in_hsfraglen, p, 0); - p += 4; - } - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - used += 16; - if (used <= buf_len) { - MBEDTLS_PUT_UINT64_BE(ssl->in_window_top, p, 0); - p += 8; - - MBEDTLS_PUT_UINT64_BE(ssl->in_window, p, 0); - p += 8; - } -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - used += 1; - if (used <= buf_len) { - *p++ = ssl->disable_datagram_packing; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - used += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - if (used <= buf_len) { - memcpy(p, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN); - p += MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - used += 2; - if (used <= buf_len) { - MBEDTLS_PUT_UINT16_BE(ssl->mtu, p, 0); - p += 2; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_ALPN) - { - const uint8_t alpn_len = ssl->alpn_chosen - ? (uint8_t) strlen(ssl->alpn_chosen) - : 0; - - used += 1 + alpn_len; - if (used <= buf_len) { - *p++ = alpn_len; - - if (ssl->alpn_chosen != NULL) { - memcpy(p, ssl->alpn_chosen, alpn_len); - p += alpn_len; - } - } - } -#endif /* MBEDTLS_SSL_ALPN */ - - /* - * Done - */ - *olen = used; - - if (used > buf_len) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "saved context", buf, used); - - return mbedtls_ssl_session_reset_int(ssl, 0); -} - -/* - * Deserialize context, see mbedtls_ssl_context_save() for format. - * - * This internal version is wrapped by a public function that cleans up in - * case of error. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_context_load(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - const unsigned char *p = buf; - const unsigned char * const end = buf + len; - size_t session_len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - tls_prf_fn prf_func = NULL; -#endif - - /* - * The context should have been freshly setup or reset. - * Give the user an error in case of obvious misuse. - * (Checking session is useful because it won't be NULL if we're - * renegotiating, or if the user mistakenly loaded a session first.) - */ - if (ssl->state != MBEDTLS_SSL_HELLO_REQUEST || - ssl->session != NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* - * We can't check that the config matches the initial one, but we can at - * least check it matches the requirements for serializing. - */ - if ( -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED || -#endif - ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || - ssl->conf->max_tls_version < MBEDTLS_SSL_VERSION_TLS1_2 || - ssl->conf->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 - ) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "context to load", buf, len); - - /* - * Check version identifier - */ - if ((size_t) (end - p) < sizeof(ssl_serialized_context_header)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (memcmp(p, ssl_serialized_context_header, - sizeof(ssl_serialized_context_header)) != 0) { - return MBEDTLS_ERR_SSL_VERSION_MISMATCH; - } - p += sizeof(ssl_serialized_context_header); - - /* - * Session - */ - if ((size_t) (end - p) < 4) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session_len = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - - /* This has been allocated by ssl_handshake_init(), called by - * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */ - ssl->session = ssl->session_negotiate; - ssl->session_in = ssl->session; - ssl->session_out = ssl->session; - ssl->session_negotiate = NULL; - - if ((size_t) (end - p) < session_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ret = ssl_session_load(ssl->session, 1, p, session_len); - if (ret != 0) { - mbedtls_ssl_session_free(ssl->session); - return ret; - } - - p += session_len; - - /* - * Transform - */ - - /* This has been allocated by ssl_handshake_init(), called by - * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - ssl->transform = ssl->transform_negotiate; - ssl->transform_in = ssl->transform; - ssl->transform_out = ssl->transform; - ssl->transform_negotiate = NULL; -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - prf_func = ssl_tls12prf_from_cs(ssl->session->ciphersuite); - if (prf_func == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* Read random bytes and populate structure */ - if ((size_t) (end - p) < sizeof(ssl->transform->randbytes)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ret = ssl_tls12_populate_transform(ssl->transform, - ssl->session->ciphersuite, - ssl->session->master, -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - ssl->session->encrypt_then_mac, -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - prf_func, - p, /* currently pointing to randbytes */ - MBEDTLS_SSL_VERSION_TLS1_2, /* (D)TLS 1.2 is forced */ - ssl->conf->endpoint, - ssl); - if (ret != 0) { - return ret; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - p += sizeof(ssl->transform->randbytes); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* Read connection IDs and store them */ - if ((size_t) (end - p) < 1) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl->transform->in_cid_len = *p++; - - if ((size_t) (end - p) < ssl->transform->in_cid_len + 1u) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - memcpy(ssl->transform->in_cid, p, ssl->transform->in_cid_len); - p += ssl->transform->in_cid_len; - - ssl->transform->out_cid_len = *p++; - - if ((size_t) (end - p) < ssl->transform->out_cid_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - memcpy(ssl->transform->out_cid, p, ssl->transform->out_cid_len); - p += ssl->transform->out_cid_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /* - * Saved fields from top-level ssl_context structure - */ - if ((size_t) (end - p) < 4) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl->badmac_seen_or_in_hsfraglen = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if ((size_t) (end - p) < 16) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl->in_window_top = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; - - ssl->in_window = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if ((size_t) (end - p) < 1) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl->disable_datagram_packing = *p++; -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if ((size_t) (end - p) < sizeof(ssl->cur_out_ctr)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - memcpy(ssl->cur_out_ctr, p, sizeof(ssl->cur_out_ctr)); - p += sizeof(ssl->cur_out_ctr); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if ((size_t) (end - p) < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl->mtu = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_ALPN) - { - uint8_t alpn_len; - const char **cur; - - if ((size_t) (end - p) < 1) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - alpn_len = *p++; - - if (alpn_len != 0 && ssl->conf->alpn_list != NULL) { - /* alpn_chosen should point to an item in the configured list */ - for (cur = ssl->conf->alpn_list; *cur != NULL; cur++) { - if (strlen(*cur) == alpn_len && - memcmp(p, *cur, alpn_len) == 0) { - ssl->alpn_chosen = *cur; - break; - } - } - } - - /* can only happen on conf mismatch */ - if (alpn_len != 0 && ssl->alpn_chosen == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - p += alpn_len; - } -#endif /* MBEDTLS_SSL_ALPN */ - - /* - * Forced fields from top-level ssl_context structure - * - * Most of them already set to the correct value by mbedtls_ssl_init() and - * mbedtls_ssl_reset(), so we only need to set the remaining ones. - */ - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); - ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2; - - /* Adjust pointers for header fields of outgoing records to - * the given transform, accounting for explicit IV and CID. */ - mbedtls_ssl_update_out_pointers(ssl, ssl->transform); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - ssl->in_epoch = 1; -#endif - - /* mbedtls_ssl_reset() leaves the handshake sub-structure allocated, - * which we don't want - otherwise we'd end up freeing the wrong transform - * by calling mbedtls_ssl_handshake_wrapup_free_hs_transform() - * inappropriately. */ - if (ssl->handshake != NULL) { - mbedtls_ssl_handshake_free(ssl); - mbedtls_free(ssl->handshake); - ssl->handshake = NULL; - } - - /* - * Done - should have consumed entire buffer - */ - if (p != end) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - return 0; -} - -/* - * Deserialize context: public wrapper for error cleaning - */ -int mbedtls_ssl_context_load(mbedtls_ssl_context *context, - const unsigned char *buf, - size_t len) -{ - int ret = ssl_context_load(context, buf, len); - - if (ret != 0) { - mbedtls_ssl_free(context); - } - - return ret; -} -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ - -/* - * Free an SSL context - */ -void mbedtls_ssl_free(mbedtls_ssl_context *ssl) -{ - if (ssl == NULL) { - return; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> free")); - - if (ssl->out_buf != NULL) { -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len; -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; -#endif - - mbedtls_zeroize_and_free(ssl->out_buf, out_buf_len); - ssl->out_buf = NULL; - } - - if (ssl->in_buf != NULL) { -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t in_buf_len = ssl->in_buf_len; -#else - size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; -#endif - - mbedtls_zeroize_and_free(ssl->in_buf, in_buf_len); - ssl->in_buf = NULL; - } - - if (ssl->transform) { - mbedtls_ssl_transform_free(ssl->transform); - mbedtls_free(ssl->transform); - } - - if (ssl->handshake) { - mbedtls_ssl_handshake_free(ssl); - mbedtls_free(ssl->handshake); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_ssl_transform_free(ssl->transform_negotiate); - mbedtls_free(ssl->transform_negotiate); -#endif - - mbedtls_ssl_session_free(ssl->session_negotiate); - mbedtls_free(ssl->session_negotiate); - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_transform_free(ssl->transform_application); - mbedtls_free(ssl->transform_application); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - if (ssl->session) { - mbedtls_ssl_session_free(ssl->session); - mbedtls_free(ssl->session); - } - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_free_hostname(ssl); -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - mbedtls_free(ssl->cli_id); -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= free")); - - /* Actually clear after last debug message */ - mbedtls_platform_zeroize(ssl, sizeof(mbedtls_ssl_context)); -} - -/* - * Initialize mbedtls_ssl_config - */ -void mbedtls_ssl_config_init(mbedtls_ssl_config *conf) -{ - memset(conf, 0, sizeof(mbedtls_ssl_config)); -} - -/* The selection should be the same as mbedtls_x509_crt_profile_default in - * x509_crt.c, plus Montgomery curves for ECDHE. Here, the order matters: - * curves with a lower resource usage come first. - * See the documentation of mbedtls_ssl_conf_curves() for what we promise - * about this list. - */ -static const uint16_t ssl_preset_default_groups[] = { -#if defined(MBEDTLS_ECP_HAVE_CURVE25519) - MBEDTLS_SSL_IANA_TLS_GROUP_X25519, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP256R1) - MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP384R1) - MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, -#endif -#if defined(MBEDTLS_ECP_HAVE_CURVE448) - MBEDTLS_SSL_IANA_TLS_GROUP_X448, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP521R1) - MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1, -#endif -#if defined(MBEDTLS_ECP_HAVE_BP256R1) - MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1, -#endif -#if defined(MBEDTLS_ECP_HAVE_BP384R1) - MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1, -#endif -#if defined(MBEDTLS_ECP_HAVE_BP512R1) - MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1, -#endif -#if defined(PSA_WANT_ALG_FFDH) - MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048, - MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE3072, - MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE4096, - MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE6144, - MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192, -#endif - MBEDTLS_SSL_IANA_TLS_GROUP_NONE -}; - -static const int ssl_preset_suiteb_ciphersuites[] = { - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - 0 -}; - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - -/* NOTICE: - * For ssl_preset_*_sig_algs and ssl_tls12_preset_*_sig_algs, the following - * rules SHOULD be upheld. - * - No duplicate entries. - * - But if there is a good reason, do not change the order of the algorithms. - * - ssl_tls12_preset* is for TLS 1.2 use only. - * - ssl_preset_* is for TLS 1.3 only or hybrid TLS 1.3/1.2 handshakes. - */ -static const uint16_t ssl_preset_default_sig_algs[] = { - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) && \ - defined(MBEDTLS_MD_CAN_SHA256) && \ - defined(PSA_WANT_ECC_SECP_R1_256) - MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256, - // == MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256) -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) && \ - defined(MBEDTLS_MD_CAN_SHA384) && \ - defined(PSA_WANT_ECC_SECP_R1_384) - MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384, - // == MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384) -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) && \ - defined(MBEDTLS_MD_CAN_SHA512) && \ - defined(PSA_WANT_ECC_SECP_R1_521) - MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512, - // == MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512) -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_MD_CAN_SHA512) - MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512, -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_MD_CAN_SHA384) - MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384, -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && defined(MBEDTLS_MD_CAN_SHA256) - MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256, -#endif - -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA512) - MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA512 */ - -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA384) - MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA384 */ - -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) - MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA256 */ - - MBEDTLS_TLS_SIG_NONE -}; - -/* NOTICE: see above */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static const uint16_t ssl_tls12_preset_default_sig_algs[] = { - -#if defined(MBEDTLS_MD_CAN_SHA512) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512), -#endif -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512, -#endif -#if defined(MBEDTLS_RSA_C) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA512), -#endif -#endif /* MBEDTLS_MD_CAN_SHA512 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384), -#endif -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384, -#endif -#if defined(MBEDTLS_RSA_C) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA384), -#endif -#endif /* MBEDTLS_MD_CAN_SHA384 */ - -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256), -#endif -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256, -#endif -#if defined(MBEDTLS_RSA_C) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA256), -#endif -#endif /* MBEDTLS_MD_CAN_SHA256 */ - - MBEDTLS_TLS_SIG_NONE -}; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -/* NOTICE: see above */ -static const uint16_t ssl_preset_suiteb_sig_algs[] = { - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) && \ - defined(MBEDTLS_MD_CAN_SHA256) && \ - defined(MBEDTLS_ECP_HAVE_SECP256R1) - MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256, - // == MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256) -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) && \ - defined(MBEDTLS_MD_CAN_SHA384) && \ - defined(MBEDTLS_ECP_HAVE_SECP384R1) - MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384, - // == MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384) -#endif - - MBEDTLS_TLS_SIG_NONE -}; - -/* NOTICE: see above */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static const uint16_t ssl_tls12_preset_suiteb_sig_algs[] = { - -#if defined(MBEDTLS_MD_CAN_SHA256) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256), -#endif -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384), -#endif -#endif /* MBEDTLS_MD_CAN_SHA384 */ - - MBEDTLS_TLS_SIG_NONE -}; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -static const uint16_t ssl_preset_suiteb_groups[] = { -#if defined(MBEDTLS_ECP_HAVE_SECP256R1) - MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP384R1) - MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, -#endif - MBEDTLS_SSL_IANA_TLS_GROUP_NONE -}; - -#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -/* Function for checking `ssl_preset_*_sig_algs` and `ssl_tls12_preset_*_sig_algs` - * to make sure there are no duplicated signature algorithm entries. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_no_sig_alg_duplication(const uint16_t *sig_algs) -{ - size_t i, j; - int ret = 0; - - for (i = 0; sig_algs[i] != MBEDTLS_TLS_SIG_NONE; i++) { - for (j = 0; j < i; j++) { - if (sig_algs[i] != sig_algs[j]) { - continue; - } - mbedtls_printf(" entry(%04x,%" MBEDTLS_PRINTF_SIZET - ") is duplicated at %" MBEDTLS_PRINTF_SIZET "\n", - sig_algs[i], j, i); - ret = -1; - } - } - return ret; -} - -#endif /* MBEDTLS_DEBUG_C && MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -/* - * Load default in mbedtls_ssl_config - */ -int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf, - int endpoint, int transport, int preset) -{ -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#endif - -#if defined(MBEDTLS_DEBUG_C) && defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - if (ssl_check_no_sig_alg_duplication(ssl_preset_suiteb_sig_algs)) { - mbedtls_printf("ssl_preset_suiteb_sig_algs has duplicated entries\n"); - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - - if (ssl_check_no_sig_alg_duplication(ssl_preset_default_sig_algs)) { - mbedtls_printf("ssl_preset_default_sig_algs has duplicated entries\n"); - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl_check_no_sig_alg_duplication(ssl_tls12_preset_suiteb_sig_algs)) { - mbedtls_printf("ssl_tls12_preset_suiteb_sig_algs has duplicated entries\n"); - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - - if (ssl_check_no_sig_alg_duplication(ssl_tls12_preset_default_sig_algs)) { - mbedtls_printf("ssl_tls12_preset_default_sig_algs has duplicated entries\n"); - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#endif /* MBEDTLS_DEBUG_C && MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - - /* Use the functions here so that they are covered in tests, - * but otherwise access member directly for efficiency */ - mbedtls_ssl_conf_endpoint(conf, endpoint); - mbedtls_ssl_conf_transport(conf, transport); - - /* - * Things that are common to all presets - */ -#if defined(MBEDTLS_SSL_CLI_C) - if (endpoint == MBEDTLS_SSL_IS_CLIENT) { - conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED; -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - mbedtls_ssl_conf_session_tickets(conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED); -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - /* Contrary to TLS 1.2 tickets, TLS 1.3 NewSessionTicket message - * handling is disabled by default in Mbed TLS 3.6.x for backward - * compatibility with client applications developed using Mbed TLS 3.5 - * or earlier with the default configuration. - * - * Up to Mbed TLS 3.5, in the default configuration TLS 1.3 was - * disabled, and a Mbed TLS client with the default configuration would - * establish a TLS 1.2 connection with a TLS 1.2 and TLS 1.3 capable - * server. - * - * Starting with Mbed TLS 3.6.0, TLS 1.3 is enabled by default, and thus - * an Mbed TLS client with the default configuration establishes a - * TLS 1.3 connection with a TLS 1.2 and TLS 1.3 capable server. If - * following the handshake the TLS 1.3 server sends NewSessionTicket - * messages and the Mbed TLS client processes them, this results in - * Mbed TLS high level APIs (mbedtls_ssl_read(), - * mbedtls_ssl_handshake(), ...) to eventually return an - * #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET non fatal error code - * (see the documentation of mbedtls_ssl_read() for more information on - * that error code). Applications unaware of that TLS 1.3 specific non - * fatal error code are then failing. - */ - mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets( - conf, MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED); -#endif -#endif - } -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - conf->f_cookie_write = ssl_cookie_write_dummy; - conf->f_cookie_check = ssl_cookie_check_dummy; -#endif - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; - conf->respect_cli_pref = MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER; -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; - conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; - memset(conf->renego_period, 0x00, 2); - memset(conf->renego_period + 2, 0xFF, 6); -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - if (endpoint == MBEDTLS_SSL_IS_SERVER) { - const unsigned char dhm_p[] = - MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN; - const unsigned char dhm_g[] = - MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN; - - if ((ret = mbedtls_ssl_conf_dh_param_bin(conf, - dhm_p, sizeof(dhm_p), - dhm_g, sizeof(dhm_g))) != 0) { - return ret; - } - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#if defined(MBEDTLS_SSL_EARLY_DATA) - mbedtls_ssl_conf_early_data(conf, MBEDTLS_SSL_EARLY_DATA_DISABLED); -#if defined(MBEDTLS_SSL_SRV_C) - mbedtls_ssl_conf_max_early_data_size(conf, MBEDTLS_SSL_MAX_EARLY_DATA_SIZE); -#endif -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS) - mbedtls_ssl_conf_new_session_tickets( - conf, MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS); -#endif - /* - * Allow all TLS 1.3 key exchange modes by default. - */ - conf->tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL; -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; - conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; -#else - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -#endif - } else { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3) - conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; - conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_3; -#elif defined(MBEDTLS_SSL_PROTO_TLS1_3) - conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_3; - conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_3; -#elif defined(MBEDTLS_SSL_PROTO_TLS1_2) - conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; - conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; -#else - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -#endif - } - - /* - * Preset-specific defaults - */ - switch (preset) { - /* - * NSA Suite B - */ - case MBEDTLS_SSL_PRESET_SUITEB: - - conf->ciphersuite_list = ssl_preset_suiteb_ciphersuites; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; -#endif - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (mbedtls_ssl_conf_is_tls12_only(conf)) { - conf->sig_algs = ssl_tls12_preset_suiteb_sig_algs; - } else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - conf->sig_algs = ssl_preset_suiteb_sig_algs; -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) - conf->curve_list = NULL; -#endif - conf->group_list = ssl_preset_suiteb_groups; - break; - - /* - * Default - */ - default: - - conf->ciphersuite_list = mbedtls_ssl_list_ciphersuites(); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - conf->cert_profile = &mbedtls_x509_crt_profile_default; -#endif - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (mbedtls_ssl_conf_is_tls12_only(conf)) { - conf->sig_algs = ssl_tls12_preset_default_sig_algs; - } else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - conf->sig_algs = ssl_preset_default_sig_algs; -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_ECP_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) - conf->curve_list = NULL; -#endif - conf->group_list = ssl_preset_default_groups; - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - conf->dhm_min_bitlen = 1024; -#endif - } - - return 0; -} - -/* - * Free mbedtls_ssl_config - */ -void mbedtls_ssl_config_free(mbedtls_ssl_config *conf) -{ - if (conf == NULL) { - return; - } - -#if defined(MBEDTLS_DHM_C) - mbedtls_mpi_free(&conf->dhm_P); - mbedtls_mpi_free(&conf->dhm_G); -#endif - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) { - conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (conf->psk != NULL) { - mbedtls_zeroize_and_free(conf->psk, conf->psk_len); - conf->psk = NULL; - conf->psk_len = 0; - } - - if (conf->psk_identity != NULL) { - mbedtls_zeroize_and_free(conf->psk_identity, conf->psk_identity_len); - conf->psk_identity = NULL; - conf->psk_identity_len = 0; - } -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - ssl_key_cert_free(conf->key_cert); -#endif - - mbedtls_platform_zeroize(conf, sizeof(mbedtls_ssl_config)); -} - -#if defined(MBEDTLS_PK_C) && \ - (defined(MBEDTLS_RSA_C) || defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED)) -/* - * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX - */ -unsigned char mbedtls_ssl_sig_from_pk(mbedtls_pk_context *pk) -{ -#if defined(MBEDTLS_RSA_C) - if (mbedtls_pk_can_do(pk, MBEDTLS_PK_RSA)) { - return MBEDTLS_SSL_SIG_RSA; - } -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) - if (mbedtls_pk_can_do(pk, MBEDTLS_PK_ECDSA)) { - return MBEDTLS_SSL_SIG_ECDSA; - } -#endif - return MBEDTLS_SSL_SIG_ANON; -} - -unsigned char mbedtls_ssl_sig_from_pk_alg(mbedtls_pk_type_t type) -{ - switch (type) { - case MBEDTLS_PK_RSA: - return MBEDTLS_SSL_SIG_RSA; - case MBEDTLS_PK_ECDSA: - case MBEDTLS_PK_ECKEY: - return MBEDTLS_SSL_SIG_ECDSA; - default: - return MBEDTLS_SSL_SIG_ANON; - } -} - -mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig(unsigned char sig) -{ - switch (sig) { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_SSL_SIG_RSA: - return MBEDTLS_PK_RSA; -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED) - case MBEDTLS_SSL_SIG_ECDSA: - return MBEDTLS_PK_ECDSA; -#endif - default: - return MBEDTLS_PK_NONE; - } -} -#endif /* MBEDTLS_PK_C && - ( MBEDTLS_RSA_C || MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ANY_ALLOWED_ENABLED ) */ - -/* - * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX - */ -mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash(unsigned char hash) -{ - switch (hash) { -#if defined(MBEDTLS_MD_CAN_MD5) - case MBEDTLS_SSL_HASH_MD5: - return MBEDTLS_MD_MD5; -#endif -#if defined(MBEDTLS_MD_CAN_SHA1) - case MBEDTLS_SSL_HASH_SHA1: - return MBEDTLS_MD_SHA1; -#endif -#if defined(MBEDTLS_MD_CAN_SHA224) - case MBEDTLS_SSL_HASH_SHA224: - return MBEDTLS_MD_SHA224; -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_SSL_HASH_SHA256: - return MBEDTLS_MD_SHA256; -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_SSL_HASH_SHA384: - return MBEDTLS_MD_SHA384; -#endif -#if defined(MBEDTLS_MD_CAN_SHA512) - case MBEDTLS_SSL_HASH_SHA512: - return MBEDTLS_MD_SHA512; -#endif - default: - return MBEDTLS_MD_NONE; - } -} - -/* - * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX - */ -unsigned char mbedtls_ssl_hash_from_md_alg(int md) -{ - switch (md) { -#if defined(MBEDTLS_MD_CAN_MD5) - case MBEDTLS_MD_MD5: - return MBEDTLS_SSL_HASH_MD5; -#endif -#if defined(MBEDTLS_MD_CAN_SHA1) - case MBEDTLS_MD_SHA1: - return MBEDTLS_SSL_HASH_SHA1; -#endif -#if defined(MBEDTLS_MD_CAN_SHA224) - case MBEDTLS_MD_SHA224: - return MBEDTLS_SSL_HASH_SHA224; -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_MD_SHA256: - return MBEDTLS_SSL_HASH_SHA256; -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_MD_SHA384: - return MBEDTLS_SSL_HASH_SHA384; -#endif -#if defined(MBEDTLS_MD_CAN_SHA512) - case MBEDTLS_MD_SHA512: - return MBEDTLS_SSL_HASH_SHA512; -#endif - default: - return MBEDTLS_SSL_HASH_NONE; - } -} - -/* - * Check if a curve proposed by the peer is in our list. - * Return 0 if we're willing to use it, -1 otherwise. - */ -int mbedtls_ssl_check_curve_tls_id(const mbedtls_ssl_context *ssl, uint16_t tls_id) -{ - const uint16_t *group_list = mbedtls_ssl_get_groups(ssl); - - if (group_list == NULL) { - return -1; - } - - for (; *group_list != 0; group_list++) { - if (*group_list == tls_id) { - return 0; - } - } - - return -1; -} - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -/* - * Same as mbedtls_ssl_check_curve_tls_id() but with a mbedtls_ecp_group_id. - */ -int mbedtls_ssl_check_curve(const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id) -{ - uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); - - if (tls_id == 0) { - return -1; - } - - return mbedtls_ssl_check_curve_tls_id(ssl, tls_id); -} -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -static const struct { - uint16_t tls_id; - mbedtls_ecp_group_id ecp_group_id; - psa_ecc_family_t psa_family; - uint16_t bits; -} tls_id_match_table[] = -{ -#if defined(MBEDTLS_ECP_HAVE_SECP521R1) - { 25, MBEDTLS_ECP_DP_SECP521R1, PSA_ECC_FAMILY_SECP_R1, 521 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_BP512R1) - { 28, MBEDTLS_ECP_DP_BP512R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 512 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP384R1) - { 24, MBEDTLS_ECP_DP_SECP384R1, PSA_ECC_FAMILY_SECP_R1, 384 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_BP384R1) - { 27, MBEDTLS_ECP_DP_BP384R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 384 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP256R1) - { 23, MBEDTLS_ECP_DP_SECP256R1, PSA_ECC_FAMILY_SECP_R1, 256 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP256K1) - { 22, MBEDTLS_ECP_DP_SECP256K1, PSA_ECC_FAMILY_SECP_K1, 256 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_BP256R1) - { 26, MBEDTLS_ECP_DP_BP256R1, PSA_ECC_FAMILY_BRAINPOOL_P_R1, 256 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP224R1) - { 21, MBEDTLS_ECP_DP_SECP224R1, PSA_ECC_FAMILY_SECP_R1, 224 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP224K1) - { 20, MBEDTLS_ECP_DP_SECP224K1, PSA_ECC_FAMILY_SECP_K1, 224 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP192R1) - { 19, MBEDTLS_ECP_DP_SECP192R1, PSA_ECC_FAMILY_SECP_R1, 192 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_SECP192K1) - { 18, MBEDTLS_ECP_DP_SECP192K1, PSA_ECC_FAMILY_SECP_K1, 192 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_CURVE25519) - { 29, MBEDTLS_ECP_DP_CURVE25519, PSA_ECC_FAMILY_MONTGOMERY, 255 }, -#endif -#if defined(MBEDTLS_ECP_HAVE_CURVE448) - { 30, MBEDTLS_ECP_DP_CURVE448, PSA_ECC_FAMILY_MONTGOMERY, 448 }, -#endif - { 0, MBEDTLS_ECP_DP_NONE, 0, 0 }, -}; - -int mbedtls_ssl_get_psa_curve_info_from_tls_id(uint16_t tls_id, - psa_key_type_t *type, - size_t *bits) -{ - for (int i = 0; tls_id_match_table[i].tls_id != 0; i++) { - if (tls_id_match_table[i].tls_id == tls_id) { - if (type != NULL) { - *type = PSA_KEY_TYPE_ECC_KEY_PAIR(tls_id_match_table[i].psa_family); - } - if (bits != NULL) { - *bits = tls_id_match_table[i].bits; - } - return PSA_SUCCESS; - } - } - - return PSA_ERROR_NOT_SUPPORTED; -} - -mbedtls_ecp_group_id mbedtls_ssl_get_ecp_group_id_from_tls_id(uint16_t tls_id) -{ - for (int i = 0; tls_id_match_table[i].tls_id != 0; i++) { - if (tls_id_match_table[i].tls_id == tls_id) { - return tls_id_match_table[i].ecp_group_id; - } - } - - return MBEDTLS_ECP_DP_NONE; -} - -uint16_t mbedtls_ssl_get_tls_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id) -{ - for (int i = 0; tls_id_match_table[i].ecp_group_id != MBEDTLS_ECP_DP_NONE; - i++) { - if (tls_id_match_table[i].ecp_group_id == grp_id) { - return tls_id_match_table[i].tls_id; - } - } - - return 0; -} - -#if defined(MBEDTLS_DEBUG_C) -static const struct { - uint16_t tls_id; - const char *name; -} tls_id_curve_name_table[] = -{ - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP521R1, "secp521r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_BP512R1, "brainpoolP512r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, "secp384r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_BP384R1, "brainpoolP384r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1, "secp256r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP256K1, "secp256k1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_BP256R1, "brainpoolP256r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP224R1, "secp224r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP224K1, "secp224k1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP192R1, "secp192r1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_SECP192K1, "secp192k1" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_X25519, "x25519" }, - { MBEDTLS_SSL_IANA_TLS_GROUP_X448, "x448" }, - { 0, NULL }, -}; - -const char *mbedtls_ssl_get_curve_name_from_tls_id(uint16_t tls_id) -{ - for (int i = 0; tls_id_curve_name_table[i].tls_id != 0; i++) { - if (tls_id_curve_name_table[i].tls_id == tls_id) { - return tls_id_curve_name_table[i].name; - } - } - - return NULL; -} -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_ssl_get_handshake_transcript(mbedtls_ssl_context *ssl, - const mbedtls_md_type_t md, - unsigned char *dst, - size_t dst_len, - size_t *olen) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_hash_operation_t *hash_operation_to_clone; - psa_hash_operation_t hash_operation = psa_hash_operation_init(); - - *olen = 0; - - switch (md) { -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_MD_SHA384: - hash_operation_to_clone = &ssl->handshake->fin_sha384_psa; - break; -#endif - -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_MD_SHA256: - hash_operation_to_clone = &ssl->handshake->fin_sha256_psa; - break; -#endif - - default: - goto exit; - } - - status = psa_hash_clone(hash_operation_to_clone, &hash_operation); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&hash_operation, dst, dst_len, olen); - if (status != PSA_SUCCESS) { - goto exit; - } - -exit: -#if !defined(MBEDTLS_MD_CAN_SHA384) && \ - !defined(MBEDTLS_MD_CAN_SHA256) - (void) ssl; -#endif - return PSA_TO_MBEDTLS_ERR(status); -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_MD_CAN_SHA384) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_handshake_transcript_sha384(mbedtls_ssl_context *ssl, - unsigned char *dst, - size_t dst_len, - size_t *olen) -{ - int ret; - mbedtls_md_context_t sha384; - - if (dst_len < 48) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - mbedtls_md_init(&sha384); - ret = mbedtls_md_setup(&sha384, mbedtls_md_info_from_type(MBEDTLS_MD_SHA384), 0); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_clone(&sha384, &ssl->handshake->fin_sha384); - if (ret != 0) { - goto exit; - } - - if ((ret = mbedtls_md_finish(&sha384, dst)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_finish", ret); - goto exit; - } - - *olen = 48; - -exit: - - mbedtls_md_free(&sha384); - return ret; -} -#endif /* MBEDTLS_MD_CAN_SHA384 */ - -#if defined(MBEDTLS_MD_CAN_SHA256) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_handshake_transcript_sha256(mbedtls_ssl_context *ssl, - unsigned char *dst, - size_t dst_len, - size_t *olen) -{ - int ret; - mbedtls_md_context_t sha256; - - if (dst_len < 32) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - mbedtls_md_init(&sha256); - ret = mbedtls_md_setup(&sha256, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 0); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_clone(&sha256, &ssl->handshake->fin_sha256); - if (ret != 0) { - goto exit; - } - - if ((ret = mbedtls_md_finish(&sha256, dst)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_finish", ret); - goto exit; - } - - *olen = 32; - -exit: - - mbedtls_md_free(&sha256); - return ret; -} -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -int mbedtls_ssl_get_handshake_transcript(mbedtls_ssl_context *ssl, - const mbedtls_md_type_t md, - unsigned char *dst, - size_t dst_len, - size_t *olen) -{ - switch (md) { - -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_MD_SHA384: - return ssl_get_handshake_transcript_sha384(ssl, dst, dst_len, olen); -#endif /* MBEDTLS_MD_CAN_SHA384*/ - -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_MD_SHA256: - return ssl_get_handshake_transcript_sha256(ssl, dst, dst_len, olen); -#endif /* MBEDTLS_MD_CAN_SHA256*/ - - default: -#if !defined(MBEDTLS_MD_CAN_SHA384) && \ - !defined(MBEDTLS_MD_CAN_SHA256) - (void) ssl; - (void) dst; - (void) dst_len; - (void) olen; -#endif - break; - } - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} - -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -/* mbedtls_ssl_parse_sig_alg_ext() - * - * The `extension_data` field of signature algorithm contains a `SignatureSchemeList` - * value (TLS 1.3 RFC8446): - * enum { - * .... - * ecdsa_secp256r1_sha256( 0x0403 ), - * ecdsa_secp384r1_sha384( 0x0503 ), - * ecdsa_secp521r1_sha512( 0x0603 ), - * .... - * } SignatureScheme; - * - * struct { - * SignatureScheme supported_signature_algorithms<2..2^16-2>; - * } SignatureSchemeList; - * - * The `extension_data` field of signature algorithm contains a `SignatureAndHashAlgorithm` - * value (TLS 1.2 RFC5246): - * enum { - * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), - * sha512(6), (255) - * } HashAlgorithm; - * - * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } - * SignatureAlgorithm; - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * SignatureAndHashAlgorithm - * supported_signature_algorithms<2..2^16-2>; - * - * The TLS 1.3 signature algorithm extension was defined to be a compatible - * generalization of the TLS 1.2 signature algorithm extension. - * `SignatureAndHashAlgorithm` field of TLS 1.2 can be represented by - * `SignatureScheme` field of TLS 1.3 - * - */ -int mbedtls_ssl_parse_sig_alg_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - const unsigned char *p = buf; - size_t supported_sig_algs_len = 0; - const unsigned char *supported_sig_algs_end; - uint16_t sig_alg; - uint32_t common_idx = 0; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - supported_sig_algs_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - memset(ssl->handshake->received_sig_algs, 0, - sizeof(ssl->handshake->received_sig_algs)); - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, supported_sig_algs_len); - supported_sig_algs_end = p + supported_sig_algs_len; - while (p < supported_sig_algs_end) { - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, supported_sig_algs_end, 2); - sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_DEBUG_MSG(4, ("received signature algorithm: 0x%x %s", - sig_alg, - mbedtls_ssl_sig_alg_to_str(sig_alg))); -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && - (!(mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg) && - mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg)))) { - continue; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - MBEDTLS_SSL_DEBUG_MSG(4, ("valid signature algorithm: %s", - mbedtls_ssl_sig_alg_to_str(sig_alg))); - - if (common_idx + 1 < MBEDTLS_RECEIVED_SIG_ALGS_SIZE) { - ssl->handshake->received_sig_algs[common_idx] = sig_alg; - common_idx += 1; - } - } - /* Check that we consumed all the message. */ - if (p != end) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Signature algorithms extension length misaligned")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - if (common_idx == 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("no signature algorithm in common")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - ssl->handshake->received_sig_algs[common_idx] = MBEDTLS_TLS_SIG_NONE; - return 0; -} - -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - -static psa_status_t setup_psa_key_derivation(psa_key_derivation_operation_t *derivation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const unsigned char *raw_psk, size_t raw_psk_length, - const unsigned char *seed, size_t seed_length, - const unsigned char *label, size_t label_length, - const unsigned char *other_secret, - size_t other_secret_length, - size_t capacity) -{ - psa_status_t status; - - status = psa_key_derivation_setup(derivation, alg); - if (status != PSA_SUCCESS) { - return status; - } - - if (PSA_ALG_IS_TLS12_PRF(alg) || PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) { - status = psa_key_derivation_input_bytes(derivation, - PSA_KEY_DERIVATION_INPUT_SEED, - seed, seed_length); - if (status != PSA_SUCCESS) { - return status; - } - - if (other_secret != NULL) { - status = psa_key_derivation_input_bytes(derivation, - PSA_KEY_DERIVATION_INPUT_OTHER_SECRET, - other_secret, other_secret_length); - if (status != PSA_SUCCESS) { - return status; - } - } - - if (mbedtls_svc_key_id_is_null(key)) { - status = psa_key_derivation_input_bytes( - derivation, PSA_KEY_DERIVATION_INPUT_SECRET, - raw_psk, raw_psk_length); - } else { - status = psa_key_derivation_input_key( - derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key); - } - if (status != PSA_SUCCESS) { - return status; - } - - status = psa_key_derivation_input_bytes(derivation, - PSA_KEY_DERIVATION_INPUT_LABEL, - label, label_length); - if (status != PSA_SUCCESS) { - return status; - } - } else { - return PSA_ERROR_NOT_SUPPORTED; - } - - status = psa_key_derivation_set_capacity(derivation, capacity); - if (status != PSA_SUCCESS) { - return status; - } - - return PSA_SUCCESS; -} - -#if defined(PSA_WANT_ALG_SHA_384) || \ - defined(PSA_WANT_ALG_SHA_256) -MBEDTLS_CHECK_RETURN_CRITICAL -static int tls_prf_generic(mbedtls_md_type_t md_type, - const unsigned char *secret, size_t slen, - const char *label, size_t label_len, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen) -{ - psa_status_t status; - psa_algorithm_t alg; - mbedtls_svc_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_derivation_operation_t derivation = - PSA_KEY_DERIVATION_OPERATION_INIT; - - if (md_type == MBEDTLS_MD_SHA384) { - alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384); - } else { - alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256); - } - - /* Normally a "secret" should be long enough to be impossible to - * find by brute force, and in particular should not be empty. But - * this PRF is also used to derive an IV, in particular in EAP-TLS, - * and for this use case it makes sense to have a 0-length "secret". - * Since the key API doesn't allow importing a key of length 0, - * keep master_key=0, which setup_psa_key_derivation() understands - * to mean a 0-length "secret" input. */ - if (slen != 0) { - psa_key_attributes_t key_attributes = psa_key_attributes_init(); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&key_attributes, alg); - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_DERIVE); - - status = psa_import_key(&key_attributes, secret, slen, &master_key); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - } - - status = setup_psa_key_derivation(&derivation, - master_key, alg, - NULL, 0, - random, rlen, - (unsigned char const *) label, - label_len, - NULL, 0, - dlen); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(&derivation); - psa_destroy_key(master_key); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_key_derivation_output_bytes(&derivation, dstbuf, dlen); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(&derivation); - psa_destroy_key(master_key); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_key_derivation_abort(&derivation); - if (status != PSA_SUCCESS) { - psa_destroy_key(master_key); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - if (!mbedtls_svc_key_id_is_null(master_key)) { - status = psa_destroy_key(master_key); - } - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - return 0; -} -#endif /* PSA_WANT_ALG_SHA_256 || PSA_WANT_ALG_SHA_384 */ -#else /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_MD_C) && \ - (defined(MBEDTLS_MD_CAN_SHA256) || \ - defined(MBEDTLS_MD_CAN_SHA384)) -MBEDTLS_CHECK_RETURN_CRITICAL -static int tls_prf_generic(mbedtls_md_type_t md_type, - const unsigned char *secret, size_t slen, - const char *label, size_t label_len, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen) -{ - size_t nb; - size_t i, j, k, md_len; - unsigned char *tmp; - size_t tmp_len = 0; - unsigned char h_i[MBEDTLS_MD_MAX_SIZE]; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_md_init(&md_ctx); - - if ((md_info = mbedtls_md_info_from_type(md_type)) == NULL) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - md_len = mbedtls_md_get_size(md_info); - - tmp_len = md_len + label_len + rlen; - tmp = mbedtls_calloc(1, tmp_len); - if (tmp == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - - nb = label_len; - memcpy(tmp + md_len, label, nb); - memcpy(tmp + md_len + nb, random, rlen); - nb += rlen; - - /* - * Compute P_(secret, label + random)[0..dlen] - */ - if ((ret = mbedtls_md_setup(&md_ctx, md_info, 1)) != 0) { - goto exit; - } - - ret = mbedtls_md_hmac_starts(&md_ctx, secret, slen); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_hmac_update(&md_ctx, tmp + md_len, nb); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_hmac_finish(&md_ctx, tmp); - if (ret != 0) { - goto exit; - } - - for (i = 0; i < dlen; i += md_len) { - ret = mbedtls_md_hmac_reset(&md_ctx); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_hmac_update(&md_ctx, tmp, md_len + nb); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_hmac_finish(&md_ctx, h_i); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_md_hmac_reset(&md_ctx); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_hmac_update(&md_ctx, tmp, md_len); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_hmac_finish(&md_ctx, tmp); - if (ret != 0) { - goto exit; - } - - k = (i + md_len > dlen) ? dlen % md_len : md_len; - - for (j = 0; j < k; j++) { - dstbuf[i + j] = h_i[j]; - } - } - -exit: - mbedtls_md_free(&md_ctx); - - if (tmp != NULL) { - mbedtls_platform_zeroize(tmp, tmp_len); - } - - mbedtls_platform_zeroize(h_i, sizeof(h_i)); - - mbedtls_free(tmp); - - return ret; -} -#endif /* MBEDTLS_MD_C && ( MBEDTLS_MD_CAN_SHA256 || MBEDTLS_MD_CAN_SHA384 ) */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_MD_CAN_SHA256) -MBEDTLS_CHECK_RETURN_CRITICAL -static int tls_prf_sha256(const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen) -{ - return tls_prf_generic(MBEDTLS_MD_SHA256, secret, slen, - label, strlen(label), random, rlen, dstbuf, dlen); -} -#endif /* MBEDTLS_MD_CAN_SHA256*/ - -#if defined(MBEDTLS_MD_CAN_SHA384) -MBEDTLS_CHECK_RETURN_CRITICAL -static int tls_prf_sha384(const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen) -{ - return tls_prf_generic(MBEDTLS_MD_SHA384, secret, slen, - label, strlen(label), random, rlen, dstbuf, dlen); -} -#endif /* MBEDTLS_MD_CAN_SHA384*/ - -/* - * Set appropriate PRF function and other SSL / TLS1.2 functions - * - * Inputs: - * - hash associated with the ciphersuite (only used by TLS 1.2) - * - * Outputs: - * - the tls_prf, calc_verify and calc_finished members of handshake structure - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_set_handshake_prfs(mbedtls_ssl_handshake_params *handshake, - mbedtls_md_type_t hash) -{ -#if defined(MBEDTLS_MD_CAN_SHA384) - if (hash == MBEDTLS_MD_SHA384) { - handshake->tls_prf = tls_prf_sha384; - handshake->calc_verify = ssl_calc_verify_tls_sha384; - handshake->calc_finished = ssl_calc_finished_tls_sha384; - } else -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - { - (void) hash; - handshake->tls_prf = tls_prf_sha256; - handshake->calc_verify = ssl_calc_verify_tls_sha256; - handshake->calc_finished = ssl_calc_finished_tls_sha256; - } -#else - { - (void) handshake; - (void) hash; - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } -#endif - - return 0; -} - -/* - * Compute master secret if needed - * - * Parameters: - * [in/out] handshake - * [in] resume, premaster, extended_ms, calc_verify, tls_prf - * (PSA-PSK) ciphersuite_info, psk_opaque - * [out] premaster (cleared) - * [out] master - * [in] ssl: optionally used for debugging, EMS and PSA-PSK - * debug: conf->f_dbg, conf->p_dbg - * EMS: passed to calc_verify (debug + session_negotiate) - * PSA-PSA: conf - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake, - unsigned char *master, - const mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* cf. RFC 5246, Section 8.1: - * "The master secret is always exactly 48 bytes in length." */ - size_t const master_secret_len = 48; - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - unsigned char session_hash[48]; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - - /* The label for the KDF used for key expansion. - * This is either "master secret" or "extended master secret" - * depending on whether the Extended Master Secret extension - * is used. */ - char const *lbl = "master secret"; - - /* The seed for the KDF used for key expansion. - * - If the Extended Master Secret extension is not used, - * this is ClientHello.Random + ServerHello.Random - * (see Sect. 8.1 in RFC 5246). - * - If the Extended Master Secret extension is used, - * this is the transcript of the handshake so far. - * (see Sect. 4 in RFC 7627). */ - unsigned char const *seed = handshake->randbytes; - size_t seed_len = 64; - -#if !defined(MBEDTLS_DEBUG_C) && \ - !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ - !(defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)) - ssl = NULL; /* make sure we don't use it except for those cases */ - (void) ssl; -#endif - - if (handshake->resume != 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("no premaster (session resumed)")); - return 0; - } - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if (handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) { - lbl = "extended master secret"; - seed = session_hash; - ret = handshake->calc_verify(ssl, session_hash, &seed_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "calc_verify", ret); - } - - MBEDTLS_SSL_DEBUG_BUF(3, "session hash for extended master secret", - session_hash, seed_len); - } -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_psk(handshake->ciphersuite_info) == 1) { - /* Perform PSK-to-MS expansion in a single step. */ - psa_status_t status; - psa_algorithm_t alg; - mbedtls_svc_key_id_t psk; - psa_key_derivation_operation_t derivation = - PSA_KEY_DERIVATION_OPERATION_INIT; - mbedtls_md_type_t hash_alg = (mbedtls_md_type_t) handshake->ciphersuite_info->mac; - - MBEDTLS_SSL_DEBUG_MSG(2, ("perform PSA-based PSK-to-MS expansion")); - - psk = mbedtls_ssl_get_opaque_psk(ssl); - - if (hash_alg == MBEDTLS_MD_SHA384) { - alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384); - } else { - alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256); - } - - size_t other_secret_len = 0; - unsigned char *other_secret = NULL; - - switch (handshake->ciphersuite_info->key_exchange) { - /* Provide other secret. - * Other secret is stored in premaster, where first 2 bytes hold the - * length of the other key. - */ - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - /* For RSA-PSK other key length is always 48 bytes. */ - other_secret_len = 48; - other_secret = handshake->premaster + 2; - break; - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - other_secret_len = MBEDTLS_GET_UINT16_BE(handshake->premaster, 0); - other_secret = handshake->premaster + 2; - break; - default: - break; - } - - status = setup_psa_key_derivation(&derivation, psk, alg, - ssl->conf->psk, ssl->conf->psk_len, - seed, seed_len, - (unsigned char const *) lbl, - (size_t) strlen(lbl), - other_secret, other_secret_len, - master_secret_len); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(&derivation); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_key_derivation_output_bytes(&derivation, - master, - master_secret_len); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(&derivation); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_key_derivation_abort(&derivation); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - } else -#endif - { -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if (handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { - psa_status_t status; - psa_algorithm_t alg = PSA_ALG_TLS12_ECJPAKE_TO_PMS; - psa_key_derivation_operation_t derivation = - PSA_KEY_DERIVATION_OPERATION_INIT; - - MBEDTLS_SSL_DEBUG_MSG(2, ("perform PSA-based PMS KDF for ECJPAKE")); - - handshake->pmslen = PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE; - - status = psa_key_derivation_setup(&derivation, alg); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_key_derivation_set_capacity(&derivation, - PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(&derivation); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_pake_get_implicit_key(&handshake->psa_pake_ctx, - &derivation); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(&derivation); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_key_derivation_output_bytes(&derivation, - handshake->premaster, - handshake->pmslen); - if (status != PSA_SUCCESS) { - psa_key_derivation_abort(&derivation); - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - status = psa_key_derivation_abort(&derivation); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - } -#endif - ret = handshake->tls_prf(handshake->premaster, handshake->pmslen, - lbl, seed, seed_len, - master, - master_secret_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "prf", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "premaster secret", - handshake->premaster, - handshake->pmslen); - - mbedtls_platform_zeroize(handshake->premaster, - sizeof(handshake->premaster)); - } - - return 0; -} - -int mbedtls_ssl_derive_keys(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_ssl_ciphersuite_t * const ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive keys")); - - /* Set PRF, calc_verify and calc_finished function pointers */ - ret = ssl_set_handshake_prfs(ssl->handshake, - (mbedtls_md_type_t) ciphersuite_info->mac); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_set_handshake_prfs", ret); - return ret; - } - - /* Compute master secret if needed */ - ret = ssl_compute_master(ssl->handshake, - ssl->session_negotiate->master, - ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_compute_master", ret); - return ret; - } - - /* Swap the client and server random values: - * - MS derivation wanted client+server (RFC 5246 8.1) - * - key derivation wants server+client (RFC 5246 6.3) */ - { - unsigned char tmp[64]; - memcpy(tmp, ssl->handshake->randbytes, 64); - memcpy(ssl->handshake->randbytes, tmp + 32, 32); - memcpy(ssl->handshake->randbytes + 32, tmp, 32); - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - } - - /* Populate transform structure */ - ret = ssl_tls12_populate_transform(ssl->transform_negotiate, - ssl->session_negotiate->ciphersuite, - ssl->session_negotiate->master, -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - ssl->session_negotiate->encrypt_then_mac, -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - ssl->handshake->tls_prf, - ssl->handshake->randbytes, - ssl->tls_version, - ssl->conf->endpoint, - ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls12_populate_transform", ret); - return ret; - } - - /* We no longer need Server/ClientHello.random values */ - mbedtls_platform_zeroize(ssl->handshake->randbytes, - sizeof(ssl->handshake->randbytes)); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= derive keys")); - - return 0; -} - -int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md) -{ - switch (md) { -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_SSL_HASH_SHA384: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; - break; -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_SSL_HASH_SHA256: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; - break; -#endif - default: - return -1; - } -#if !defined(MBEDTLS_MD_CAN_SHA384) && \ - !defined(MBEDTLS_MD_CAN_SHA256) - (void) ssl; -#endif - return 0; -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int ssl_calc_verify_tls_psa(const mbedtls_ssl_context *ssl, - const psa_hash_operation_t *hs_op, - size_t buffer_size, - unsigned char *hash, - size_t *hlen) -{ - psa_status_t status; - psa_hash_operation_t cloned_op = psa_hash_operation_init(); - -#if !defined(MBEDTLS_DEBUG_C) - (void) ssl; -#endif - MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify")); - status = psa_hash_clone(hs_op, &cloned_op); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&cloned_op, hash, buffer_size, hlen); - if (status != PSA_SUCCESS) { - goto exit; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen); - MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify")); - -exit: - psa_hash_abort(&cloned_op); - return mbedtls_md_error_from_psa(status); -} -#else -static int ssl_calc_verify_tls_legacy(const mbedtls_ssl_context *ssl, - const mbedtls_md_context_t *hs_ctx, - unsigned char *hash, - size_t *hlen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_context_t cloned_ctx; - - mbedtls_md_init(&cloned_ctx); - -#if !defined(MBEDTLS_DEBUG_C) - (void) ssl; -#endif - MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify")); - - ret = mbedtls_md_setup(&cloned_ctx, mbedtls_md_info_from_ctx(hs_ctx), 0); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_clone(&cloned_ctx, hs_ctx); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_md_finish(&cloned_ctx, hash); - if (ret != 0) { - goto exit; - } - - *hlen = mbedtls_md_get_size(mbedtls_md_info_from_ctx(hs_ctx)); - - MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen); - MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify")); - -exit: - mbedtls_md_free(&cloned_ctx); - return ret; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_MD_CAN_SHA256) -int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl, - unsigned char *hash, - size_t *hlen) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - return ssl_calc_verify_tls_psa(ssl, &ssl->handshake->fin_sha256_psa, 32, - hash, hlen); -#else - return ssl_calc_verify_tls_legacy(ssl, &ssl->handshake->fin_sha256, - hash, hlen); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} -#endif /* MBEDTLS_MD_CAN_SHA256 */ - -#if defined(MBEDTLS_MD_CAN_SHA384) -int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl, - unsigned char *hash, - size_t *hlen) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - return ssl_calc_verify_tls_psa(ssl, &ssl->handshake->fin_sha384_psa, 48, - hash, hlen); -#else - return ssl_calc_verify_tls_legacy(ssl, &ssl->handshake->fin_sha384, - hash, hlen); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} -#endif /* MBEDTLS_MD_CAN_SHA384 */ - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -int mbedtls_ssl_psk_derive_premaster(mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex) -{ - unsigned char *p = ssl->handshake->premaster; - unsigned char *end = p + sizeof(ssl->handshake->premaster); - const unsigned char *psk = NULL; - size_t psk_len = 0; - int psk_ret = mbedtls_ssl_get_psk(ssl, &psk, &psk_len); - - if (psk_ret == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) { - /* - * This should never happen because the existence of a PSK is always - * checked before calling this function. - * - * The exception is opaque DHE-PSK. For DHE-PSK fill premaster with - * the shared secret without PSK. - */ - if (key_ex != MBEDTLS_KEY_EXCHANGE_DHE_PSK) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - } - - /* - * PMS = struct { - * opaque other_secret<0..2^16-1>; - * opaque psk<0..2^16-1>; - * }; - * with "other_secret" depending on the particular key exchange - */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if (key_ex == MBEDTLS_KEY_EXCHANGE_PSK) { - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_PUT_UINT16_BE(psk_len, p, 0); - p += 2; - - if (end < p || (size_t) (end - p) < psk_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - memset(p, 0, psk_len); - p += psk_len; - } else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if (key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { - /* - * other_secret already set by the ClientKeyExchange message, - * and is 48 bytes long - */ - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - *p++ = 0; - *p++ = 48; - p += 48; - } else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if (key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - /* Write length only when we know the actual value */ - if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, - p + 2, (size_t) (end - (p + 2)), &len, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); - return ret; - } - MBEDTLS_PUT_UINT16_BE(len, p, 0); - p += 2 + len; - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); - } else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if (key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t zlen; - - if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, &zlen, - p + 2, (size_t) (end - (p + 2)), - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret); - return ret; - } - - MBEDTLS_PUT_UINT16_BE(zlen, p, 0); - p += 2 + zlen; - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z); - } else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* opaque psk<0..2^16-1>; */ - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_PUT_UINT16_BE(psk_len, p, 0); - p += 2; - - if (end < p || (size_t) (end - p) < psk_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - memcpy(p, psk, psk_len); - p += psk_len; - - ssl->handshake->pmslen = (size_t) (p - ssl->handshake->premaster); - - return 0; -} -#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_hello_request(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -int mbedtls_ssl_resend_hello_request(mbedtls_ssl_context *ssl) -{ - /* If renegotiation is not enforced, retransmit until we would reach max - * timeout if we were using the usual handshake doubling scheme */ - if (ssl->conf->renego_max_records < 0) { - uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; - unsigned char doublings = 1; - - while (ratio != 0) { - ++doublings; - ratio >>= 1; - } - - if (++ssl->renego_records_seen > doublings) { - MBEDTLS_SSL_DEBUG_MSG(2, ("no longer retransmitting hello request")); - return 0; - } - } - - return ssl_write_hello_request(ssl); -} -#endif -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ - -/* - * Handshake functions - */ -#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) -/* No certificate support -> dummy functions */ -int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate")); - - if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} - -int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate")); - - if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} - -#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ -/* Some certificate support -> implement write and parse */ - -int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t i, n; - const mbedtls_x509_crt *crt; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate")); - - if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - -#if defined(MBEDTLS_SSL_CLI_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - if (ssl->handshake->client_auth == 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - if (mbedtls_ssl_own_cert(ssl) == NULL) { - /* Should never happen because we shouldn't have picked the - * ciphersuite if we don't have a certificate. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - } -#endif - - MBEDTLS_SSL_DEBUG_CRT(3, "own certificate", mbedtls_ssl_own_cert(ssl)); - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 6 length of all certs - * 7 . 9 length of cert. 1 - * 10 . n-1 peer certificate - * n . n+2 length of cert. 2 - * n+3 . ... upper level cert, etc. - */ - i = 7; - crt = mbedtls_ssl_own_cert(ssl); - - while (crt != NULL) { - n = crt->raw.len; - if (n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i) { - MBEDTLS_SSL_DEBUG_MSG(1, ("certificate too large, %" MBEDTLS_PRINTF_SIZET - " > %" MBEDTLS_PRINTF_SIZET, - i + 3 + n, (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN)); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - ssl->out_msg[i] = MBEDTLS_BYTE_2(n); - ssl->out_msg[i + 1] = MBEDTLS_BYTE_1(n); - ssl->out_msg[i + 2] = MBEDTLS_BYTE_0(n); - - i += 3; memcpy(ssl->out_msg + i, crt->raw.p, n); - i += n; crt = crt->next; - } - - ssl->out_msg[4] = MBEDTLS_BYTE_2(i - 7); - ssl->out_msg[5] = MBEDTLS_BYTE_1(i - 7); - ssl->out_msg[6] = MBEDTLS_BYTE_0(i - 7); - - ssl->out_msglen = i; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE; - - mbedtls_ssl_handshake_increment_state(ssl); - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate")); - - return ret; -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl, - unsigned char *crt_buf, - size_t crt_buf_len) -{ - mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert; - - if (peer_crt == NULL) { - return -1; - } - - if (peer_crt->raw.len != crt_buf_len) { - return -1; - } - - return memcmp(peer_crt->raw.p, crt_buf, peer_crt->raw.len); -} -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_peer_crt_unchanged(mbedtls_ssl_context *ssl, - unsigned char *crt_buf, - size_t crt_buf_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char const * const peer_cert_digest = - ssl->session->peer_cert_digest; - mbedtls_md_type_t const peer_cert_digest_type = - ssl->session->peer_cert_digest_type; - mbedtls_md_info_t const * const digest_info = - mbedtls_md_info_from_type(peer_cert_digest_type); - unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN]; - size_t digest_len; - - if (peer_cert_digest == NULL || digest_info == NULL) { - return -1; - } - - digest_len = mbedtls_md_get_size(digest_info); - if (digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN) { - return -1; - } - - ret = mbedtls_md(digest_info, crt_buf, crt_buf_len, tmp_digest); - if (ret != 0) { - return -1; - } - - return memcmp(tmp_digest, peer_cert_digest, digest_len); -} -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - -/* - * Once the certificate message is read, parse it into a cert chain and - * perform basic checks, but leave actual verification to the caller - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_certificate_chain(mbedtls_ssl_context *ssl, - mbedtls_x509_crt *chain) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - int crt_cnt = 0; -#endif - size_t i, n; - uint8_t alert; - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - if (ssl->in_hslen < mbedtls_ssl_hs_hdr_len(ssl) + 3 + 3) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - i = mbedtls_ssl_hs_hdr_len(ssl); - - /* - * Same message structure as in mbedtls_ssl_write_certificate() - */ - n = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i + 1); - - if (ssl->in_msg[i] != 0 || - ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */ - i += 3; - - /* Iterate through and parse the CRTs in the provided chain. */ - while (i < ssl->in_hslen) { - /* Check that there's room for the next CRT's length fields. */ - if (i + 3 > ssl->in_hslen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message")); - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - /* In theory, the CRT can be up to 2**24 Bytes, but we don't support - * anything beyond 2**16 ~ 64K. */ - if (ssl->in_msg[i] != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message")); - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT); - return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; - } - - /* Read length of the next CRT in the chain. */ - n = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i + 1); - i += 3; - - if (n < 128 || i + n > ssl->in_hslen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message")); - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Check if we're handling the first CRT in the chain. */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - if (crt_cnt++ == 0 && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { - /* During client-side renegotiation, check that the server's - * end-CRTs hasn't changed compared to the initial handshake, - * mitigating the triple handshake attack. On success, reuse - * the original end-CRT instead of parsing it again. */ - MBEDTLS_SSL_DEBUG_MSG(3, ("Check that peer CRT hasn't changed during renegotiation")); - if (ssl_check_peer_crt_unchanged(ssl, - &ssl->in_msg[i], - n) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("new server cert during renegotiation")); - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED); - return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; - } - - /* Now we can safely free the original chain. */ - ssl_clear_peer_cert(ssl->session); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - - /* Parse the next certificate in the chain. */ -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - ret = mbedtls_x509_crt_parse_der(chain, ssl->in_msg + i, n); -#else - /* If we don't need to store the CRT chain permanently, parse - * it in-place from the input buffer instead of making a copy. */ - ret = mbedtls_x509_crt_parse_der_nocopy(chain, ssl->in_msg + i, n); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - switch (ret) { - case 0: /*ok*/ - case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: - /* Ignore certificate with an unknown algorithm: maybe a - prior certificate was already trusted. */ - break; - - case MBEDTLS_ERR_X509_ALLOC_FAILED: - alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; - goto crt_parse_der_failed; - - case MBEDTLS_ERR_X509_UNKNOWN_VERSION: - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - goto crt_parse_der_failed; - - default: - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; -crt_parse_der_failed: - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert); - MBEDTLS_SSL_DEBUG_RET(1, " mbedtls_x509_crt_parse_der", ret); - return ret; - } - - i += n; - } - - MBEDTLS_SSL_DEBUG_CRT(3, "peer certificate", chain); - return 0; -} - -#if defined(MBEDTLS_SSL_SRV_C) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_srv_check_client_no_crt_notification(mbedtls_ssl_context *ssl) -{ - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - return -1; - } - - if (ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len(ssl) && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE && - memcmp(ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl), "\0\0\0", 3) == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("peer has no certificate")); - return 0; - } - return -1; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -/* Check if a certificate message is expected. - * Return either - * - SSL_CERTIFICATE_EXPECTED, or - * - SSL_CERTIFICATE_SKIP - * indicating whether a Certificate message is expected or not. - */ -#define SSL_CERTIFICATE_EXPECTED 0 -#define SSL_CERTIFICATE_SKIP 1 -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl, - int authmode) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { - ssl->session_negotiate->verify_result = 0; - return SSL_CERTIFICATE_SKIP; - } - -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { - return SSL_CERTIFICATE_SKIP; - } - - if (authmode == MBEDTLS_SSL_VERIFY_NONE) { - ssl->session_negotiate->verify_result = - MBEDTLS_X509_BADCERT_SKIP_VERIFY; - return SSL_CERTIFICATE_SKIP; - } - } -#else - ((void) authmode); -#endif /* MBEDTLS_SSL_SRV_C */ - - return SSL_CERTIFICATE_EXPECTED; -} - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_remember_peer_crt_digest(mbedtls_ssl_context *ssl, - unsigned char *start, size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - /* Remember digest of the peer's end-CRT. */ - ssl->session_negotiate->peer_cert_digest = - mbedtls_calloc(1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN); - if (ssl->session_negotiate->peer_cert_digest == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%d bytes) failed", - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN)); - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - ret = mbedtls_md(mbedtls_md_info_from_type( - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE), - start, len, - ssl->session_negotiate->peer_cert_digest); - - ssl->session_negotiate->peer_cert_digest_type = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE; - ssl->session_negotiate->peer_cert_digest_len = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN; - - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_remember_peer_pubkey(mbedtls_ssl_context *ssl, - unsigned char *start, size_t len) -{ - unsigned char *end = start + len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* Make a copy of the peer's raw public key. */ - mbedtls_pk_init(&ssl->handshake->peer_pubkey); - ret = mbedtls_pk_parse_subpubkey(&start, end, - &ssl->handshake->peer_pubkey); - if (ret != 0) { - /* We should have parsed the public key before. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - return 0; -} -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl) -{ - int ret = 0; - int crt_expected; - /* Authmode: precedence order is SNI if used else configuration */ -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET - ? ssl->handshake->sni_authmode - : ssl->conf->authmode; -#else - const int authmode = ssl->conf->authmode; -#endif - void *rs_ctx = NULL; - mbedtls_x509_crt *chain = NULL; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate")); - - crt_expected = ssl_parse_certificate_coordinate(ssl, authmode); - if (crt_expected == SSL_CERTIFICATE_SKIP) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate")); - goto exit; - } - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_verify) { - chain = ssl->handshake->ecrs_peer_cert; - ssl->handshake->ecrs_peer_cert = NULL; - goto crt_verify; - } -#endif - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - /* mbedtls_ssl_read_record may have sent an alert already. We - let it decide whether to alert. */ - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - goto exit; - } - -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl_srv_check_client_no_crt_notification(ssl) == 0) { - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; - - if (authmode != MBEDTLS_SSL_VERIFY_OPTIONAL) { - ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE; - } - - goto exit; - } -#endif /* MBEDTLS_SSL_SRV_C */ - - /* Clear existing peer CRT structure in case we tried to - * reuse a session but it failed, and allocate a new one. */ - ssl_clear_peer_cert(ssl->session_negotiate); - - chain = mbedtls_calloc(1, sizeof(mbedtls_x509_crt)); - if (chain == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", - sizeof(mbedtls_x509_crt))); - mbedtls_ssl_send_alert_message(ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - mbedtls_x509_crt_init(chain); - - ret = ssl_parse_certificate_chain(ssl, chain); - if (ret != 0) { - goto exit; - } - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled) { - ssl->handshake->ecrs_state = ssl_ecrs_crt_verify; - } - -crt_verify: - if (ssl->handshake->ecrs_enabled) { - rs_ctx = &ssl->handshake->ecrs_ctx; - } -#endif - - ret = mbedtls_ssl_verify_certificate(ssl, authmode, chain, - ssl->handshake->ciphersuite_info, - rs_ctx); - if (ret != 0) { - goto exit; - } - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - { - unsigned char *crt_start, *pk_start; - size_t crt_len, pk_len; - - /* We parse the CRT chain without copying, so - * these pointers point into the input buffer, - * and are hence still valid after freeing the - * CRT chain. */ - - crt_start = chain->raw.p; - crt_len = chain->raw.len; - - pk_start = chain->pk_raw.p; - pk_len = chain->pk_raw.len; - - /* Free the CRT structures before computing - * digest and copying the peer's public key. */ - mbedtls_x509_crt_free(chain); - mbedtls_free(chain); - chain = NULL; - - ret = ssl_remember_peer_crt_digest(ssl, crt_start, crt_len); - if (ret != 0) { - goto exit; - } - - ret = ssl_remember_peer_pubkey(ssl, pk_start, pk_len); - if (ret != 0) { - goto exit; - } - } -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* Pass ownership to session structure. */ - ssl->session_negotiate->peer_cert = chain; - chain = NULL; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate")); - -exit: - - if (ret == 0) { - mbedtls_ssl_handshake_increment_state(ssl); - } - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) { - ssl->handshake->ecrs_peer_cert = chain; - chain = NULL; - } -#endif - - if (chain != NULL) { - mbedtls_x509_crt_free(chain); - mbedtls_free(chain); - } - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ - -static int ssl_calc_finished_tls_generic(mbedtls_ssl_context *ssl, void *ctx, - unsigned char *padbuf, size_t hlen, - unsigned char *buf, int from) -{ - unsigned int len = 12; - const char *sender; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; - psa_hash_operation_t *hs_op = ctx; - psa_hash_operation_t cloned_op = PSA_HASH_OPERATION_INIT; - size_t hash_size; -#else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_context_t *hs_ctx = ctx; - mbedtls_md_context_t cloned_ctx; - mbedtls_md_init(&cloned_ctx); -#endif - - mbedtls_ssl_session *session = ssl->session_negotiate; - if (!session) { - session = ssl->session; - } - - sender = (from == MBEDTLS_SSL_IS_CLIENT) - ? "client finished" - : "server finished"; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc PSA finished tls")); - - status = psa_hash_clone(hs_op, &cloned_op); - if (status != PSA_SUCCESS) { - goto exit; - } - - status = psa_hash_finish(&cloned_op, padbuf, hlen, &hash_size); - if (status != PSA_SUCCESS) { - goto exit; - } - MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, hlen); -#else - MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc finished tls")); - - ret = mbedtls_md_setup(&cloned_ctx, mbedtls_md_info_from_ctx(hs_ctx), 0); - if (ret != 0) { - goto exit; - } - ret = mbedtls_md_clone(&cloned_ctx, hs_ctx); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_md_finish(&cloned_ctx, padbuf); - if (ret != 0) { - goto exit; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - MBEDTLS_SSL_DEBUG_BUF(4, "finished output", padbuf, hlen); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - ssl->handshake->tls_prf(session->master, 48, sender, - padbuf, hlen, buf, len); - - MBEDTLS_SSL_DEBUG_BUF(3, "calc finished result", buf, len); - - mbedtls_platform_zeroize(padbuf, hlen); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished")); - -exit: -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort(&cloned_op); - return mbedtls_md_error_from_psa(status); -#else - mbedtls_md_free(&cloned_ctx); - return ret; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} - -#if defined(MBEDTLS_MD_CAN_SHA256) -static int ssl_calc_finished_tls_sha256( - mbedtls_ssl_context *ssl, unsigned char *buf, int from) -{ - unsigned char padbuf[32]; - return ssl_calc_finished_tls_generic(ssl, -#if defined(MBEDTLS_USE_PSA_CRYPTO) - &ssl->handshake->fin_sha256_psa, -#else - &ssl->handshake->fin_sha256, -#endif - padbuf, sizeof(padbuf), - buf, from); -} -#endif /* MBEDTLS_MD_CAN_SHA256*/ - - -#if defined(MBEDTLS_MD_CAN_SHA384) -static int ssl_calc_finished_tls_sha384( - mbedtls_ssl_context *ssl, unsigned char *buf, int from) -{ - unsigned char padbuf[48]; - return ssl_calc_finished_tls_generic(ssl, -#if defined(MBEDTLS_USE_PSA_CRYPTO) - &ssl->handshake->fin_sha384_psa, -#else - &ssl->handshake->fin_sha384, -#endif - padbuf, sizeof(padbuf), - buf, from); -} -#endif /* MBEDTLS_MD_CAN_SHA384*/ - -void mbedtls_ssl_handshake_wrapup_free_hs_transform(mbedtls_ssl_context *ssl) -{ - MBEDTLS_SSL_DEBUG_MSG(3, ("=> handshake wrapup: final free")); - - /* - * Free our handshake params - */ - mbedtls_ssl_handshake_free(ssl); - mbedtls_free(ssl->handshake); - ssl->handshake = NULL; - - /* - * Free the previous transform and switch in the current one - */ - if (ssl->transform) { - mbedtls_ssl_transform_free(ssl->transform); - mbedtls_free(ssl->transform); - } - ssl->transform = ssl->transform_negotiate; - ssl->transform_negotiate = NULL; - - MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup: final free")); -} - -void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl) -{ - int resume = ssl->handshake->resume; - - MBEDTLS_SSL_DEBUG_MSG(3, ("=> handshake wrapup")); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE; - ssl->renego_records_seen = 0; - } -#endif - - /* - * Free the previous session and switch in the current one - */ - if (ssl->session) { -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - /* RFC 7366 3.1: keep the EtM state */ - ssl->session_negotiate->encrypt_then_mac = - ssl->session->encrypt_then_mac; -#endif - - mbedtls_ssl_session_free(ssl->session); - mbedtls_free(ssl->session); - } - ssl->session = ssl->session_negotiate; - ssl->session_negotiate = NULL; - - /* - * Add cache entry - */ - if (ssl->conf->f_set_cache != NULL && - ssl->session->id_len != 0 && - resume == 0) { - if (ssl->conf->f_set_cache(ssl->conf->p_cache, - ssl->session->id, - ssl->session->id_len, - ssl->session) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("cache did not store session")); - } - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->flight != NULL) { - /* Cancel handshake timer */ - mbedtls_ssl_set_timer(ssl, 0); - - /* Keep last flight around in case we need to resend it: - * we need the handshake and transform structures for that */ - MBEDTLS_SSL_DEBUG_MSG(3, ("skip freeing handshake and transform")); - } else -#endif - mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl); - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); - - MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup")); -} - -int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl) -{ - int ret; - unsigned int hash_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write finished")); - - mbedtls_ssl_update_out_pointers(ssl, ssl->transform_negotiate); - - ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret); - return ret; - } - - /* - * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites - * may define some other value. Currently (early 2016), no defined - * ciphersuite does this (and this is unlikely to change as activity has - * moved to TLS 1.3 now) so we can keep the hardcoded 12 here. - */ - hash_len = 12; - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->verify_data_len = hash_len; - memcpy(ssl->own_verify_data, ssl->out_msg + 4, hash_len); -#endif - - ssl->out_msglen = 4 + hash_len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED; - - /* - * In case of session resuming, invert the client and server - * ChangeCipherSpec messages order. - */ - if (ssl->handshake->resume != 0) { -#if defined(MBEDTLS_SSL_CLI_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); - } -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC); - } -#endif - } else { - mbedtls_ssl_handshake_increment_state(ssl); - } - - /* - * Switch to our negotiated transform and session parameters for outbound - * data. - */ - MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for outbound data")); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - unsigned char i; - - /* Remember current epoch settings for resending */ - ssl->handshake->alt_transform_out = ssl->transform_out; - memcpy(ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, - sizeof(ssl->handshake->alt_out_ctr)); - - /* Set sequence_number to zero */ - memset(&ssl->cur_out_ctr[2], 0, sizeof(ssl->cur_out_ctr) - 2); - - - /* Increment epoch */ - for (i = 2; i > 0; i--) { - if (++ssl->cur_out_ctr[i - 1] != 0) { - break; - } - } - - /* The loop goes to its end iff the counter is wrapping */ - if (i == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap")); - return MBEDTLS_ERR_SSL_COUNTER_WRAPPING; - } - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr)); - - ssl->transform_out = ssl->transform_negotiate; - ssl->session_out = ssl->session_negotiate; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - mbedtls_ssl_send_flight_completed(ssl); - } -#endif - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret); - return ret; - } -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write finished")); - - return 0; -} - -#define SSL_MAX_HASH_LEN 12 - -int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned int hash_len = 12; - unsigned char buf[SSL_MAX_HASH_LEN]; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse finished")); - - ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret); - return ret; - } - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - goto exit; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - goto exit; - } - - if (ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - goto exit; - } - - if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + hash_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - ret = MBEDTLS_ERR_SSL_DECODE_ERROR; - goto exit; - } - - if (mbedtls_ct_memcmp(ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl), - buf, hash_len) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR); - ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - goto exit; - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->verify_data_len = hash_len; - memcpy(ssl->peer_verify_data, buf, hash_len); -#endif - - if (ssl->handshake->resume != 0) { -#if defined(MBEDTLS_SSL_CLI_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC); - } -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); - } -#endif - } else { - mbedtls_ssl_handshake_increment_state(ssl); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - mbedtls_ssl_recv_flight_completed(ssl); - } -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse finished")); - -exit: - mbedtls_platform_zeroize(buf, hash_len); - return ret; -} - -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) -/* - * Helper to get TLS 1.2 PRF from ciphersuite - * (Duplicates bits of logic from ssl_set_handshake_prfs().) - */ -static tls_prf_fn ssl_tls12prf_from_cs(int ciphersuite_id) -{ - const mbedtls_ssl_ciphersuite_t * const ciphersuite_info = - mbedtls_ssl_ciphersuite_from_id(ciphersuite_id); -#if defined(MBEDTLS_MD_CAN_SHA384) - if (ciphersuite_info != NULL && ciphersuite_info->mac == MBEDTLS_MD_SHA384) { - return tls_prf_sha384; - } else -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - { - if (ciphersuite_info != NULL && ciphersuite_info->mac == MBEDTLS_MD_SHA256) { - return tls_prf_sha256; - } - } -#endif -#if !defined(MBEDTLS_MD_CAN_SHA384) && \ - !defined(MBEDTLS_MD_CAN_SHA256) - (void) ciphersuite_info; -#endif - - return NULL; -} -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ - -static mbedtls_tls_prf_types tls_prf_get_type(mbedtls_ssl_tls_prf_cb *tls_prf) -{ - ((void) tls_prf); -#if defined(MBEDTLS_MD_CAN_SHA384) - if (tls_prf == tls_prf_sha384) { - return MBEDTLS_SSL_TLS_PRF_SHA384; - } else -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - if (tls_prf == tls_prf_sha256) { - return MBEDTLS_SSL_TLS_PRF_SHA256; - } else -#endif - return MBEDTLS_SSL_TLS_PRF_NONE; -} - -/* - * Populate a transform structure with session keys and all the other - * necessary information. - * - * Parameters: - * - [in/out]: transform: structure to populate - * [in] must be just initialised with mbedtls_ssl_transform_init() - * [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf() - * - [in] ciphersuite - * - [in] master - * - [in] encrypt_then_mac - * - [in] tls_prf: pointer to PRF to use for key derivation - * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random - * - [in] tls_version: TLS version - * - [in] endpoint: client or server - * - [in] ssl: used for: - * - ssl->conf->{f,p}_export_keys - * [in] optionally used for: - * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform, - int ciphersuite, - const unsigned char master[48], -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - int encrypt_then_mac, -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - ssl_tls_prf_t tls_prf, - const unsigned char randbytes[64], - mbedtls_ssl_protocol_version tls_version, - unsigned endpoint, - const mbedtls_ssl_context *ssl) -{ - int ret = 0; - unsigned char keyblk[256]; - unsigned char *key1; - unsigned char *key2; - unsigned char *mac_enc; - unsigned char *mac_dec; - size_t mac_key_len = 0; - size_t iv_copy_len; - size_t keylen; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - mbedtls_ssl_mode_t ssl_mode; -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - const mbedtls_cipher_info_t *cipher_info; - const mbedtls_md_info_t *md_info; -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_type_t key_type; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_algorithm_t alg; - psa_algorithm_t mac_alg = 0; - size_t key_bits; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; -#endif - - /* - * Some data just needs copying into the structure - */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - transform->encrypt_then_mac = encrypt_then_mac; -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - transform->tls_version = tls_version; - -#if defined(MBEDTLS_SSL_KEEP_RANDBYTES) - memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes)); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - /* At the moment, we keep TLS <= 1.2 and TLS 1.3 transform - * generation separate. This should never happen. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - /* - * Get various info structures - */ - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite); - if (ciphersuite_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("ciphersuite info for %d not found", - ciphersuite)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl_mode = mbedtls_ssl_get_mode_from_ciphersuite( -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - encrypt_then_mac, -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - ciphersuite_info); - - if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) { - transform->taglen = - ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) ciphersuite_info->cipher, - transform->taglen, - &alg, - &key_type, - &key_bits)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_cipher_to_psa", ret); - goto end; - } -#else - cipher_info = mbedtls_cipher_info_from_type((mbedtls_cipher_type_t) ciphersuite_info->cipher); - if (cipher_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found", - ciphersuite_info->cipher)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mac_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); - if (mac_alg == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_md_psa_alg_from_type for %u not found", - (unsigned) ciphersuite_info->mac)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -#else - md_info = mbedtls_md_info_from_type((mbedtls_md_type_t) ciphersuite_info->mac); - if (md_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_md info for %u not found", - (unsigned) ciphersuite_info->mac)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* Copy own and peer's CID if the use of the CID - * extension has been negotiated. */ - if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Copy CIDs into SSL transform")); - - transform->in_cid_len = ssl->own_cid_len; - memcpy(transform->in_cid, ssl->own_cid, ssl->own_cid_len); - MBEDTLS_SSL_DEBUG_BUF(3, "Incoming CID", transform->in_cid, - transform->in_cid_len); - - transform->out_cid_len = ssl->handshake->peer_cid_len; - memcpy(transform->out_cid, ssl->handshake->peer_cid, - ssl->handshake->peer_cid_len); - MBEDTLS_SSL_DEBUG_BUF(3, "Outgoing CID", transform->out_cid, - transform->out_cid_len); - } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - /* - * Compute key block using the PRF - */ - ret = tls_prf(master, 48, "key expansion", randbytes, 64, keyblk, 256); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "prf", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite = %s", - mbedtls_ssl_get_ciphersuite_name(ciphersuite))); - MBEDTLS_SSL_DEBUG_BUF(3, "master secret", master, 48); - MBEDTLS_SSL_DEBUG_BUF(4, "random bytes", randbytes, 64); - MBEDTLS_SSL_DEBUG_BUF(4, "key block", keyblk, 256); - - /* - * Determine the appropriate key, IV and MAC length. - */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - keylen = PSA_BITS_TO_BYTES(key_bits); -#else - keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; -#endif - -#if defined(MBEDTLS_SSL_HAVE_AEAD) - if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) { - size_t explicit_ivlen; - - transform->maclen = 0; - mac_key_len = 0; - - /* All modes haves 96-bit IVs, but the length of the static parts vary - * with mode and version: - * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes - * (to be concatenated with a dynamically chosen IV of 8 Bytes) - * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's - * a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record - * sequence number). - */ - transform->ivlen = 12; - - int is_chachapoly = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - is_chachapoly = (key_type == PSA_KEY_TYPE_CHACHA20); -#else - is_chachapoly = (mbedtls_cipher_info_get_mode(cipher_info) - == MBEDTLS_MODE_CHACHAPOLY); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (is_chachapoly) { - transform->fixed_ivlen = 12; - } else { - transform->fixed_ivlen = 4; - } - - /* Minimum length of encrypted record */ - explicit_ivlen = transform->ivlen - transform->fixed_ivlen; - transform->minlen = explicit_ivlen + transform->taglen; - } else -#endif /* MBEDTLS_SSL_HAVE_AEAD */ -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - if (ssl_mode == MBEDTLS_SSL_MODE_STREAM || - ssl_mode == MBEDTLS_SSL_MODE_CBC || - ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type); -#else - size_t block_size = mbedtls_cipher_info_get_block_size(cipher_info); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Get MAC length */ - mac_key_len = PSA_HASH_LENGTH(mac_alg); -#else - /* Initialize HMAC contexts */ - if ((ret = mbedtls_md_setup(&transform->md_ctx_enc, md_info, 1)) != 0 || - (ret = mbedtls_md_setup(&transform->md_ctx_dec, md_info, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_setup", ret); - goto end; - } - - /* Get MAC length */ - mac_key_len = mbedtls_md_get_size(md_info); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - transform->maclen = mac_key_len; - - /* IV length */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - transform->ivlen = PSA_CIPHER_IV_LENGTH(key_type, alg); -#else - transform->ivlen = mbedtls_cipher_info_get_iv_size(cipher_info); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* Minimum length */ - if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) { - transform->minlen = transform->maclen; - } else { - /* - * GenericBlockCipher: - * 1. if EtM is in use: one block plus MAC - * otherwise: * first multiple of blocklen greater than maclen - * 2. IV - */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if (ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { - transform->minlen = transform->maclen - + block_size; - } else -#endif - { - transform->minlen = transform->maclen - + block_size - - transform->maclen % block_size; - } - - if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { - transform->minlen += transform->ivlen; - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto end; - } - } - } else -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("keylen: %u, minlen: %u, ivlen: %u, maclen: %u", - (unsigned) keylen, - (unsigned) transform->minlen, - (unsigned) transform->ivlen, - (unsigned) transform->maclen)); - - /* - * Finally setup the cipher contexts, IVs and MAC secrets. - */ -#if defined(MBEDTLS_SSL_CLI_C) - if (endpoint == MBEDTLS_SSL_IS_CLIENT) { - key1 = keyblk + mac_key_len * 2; - key2 = keyblk + mac_key_len * 2 + keylen; - - mac_enc = keyblk; - mac_dec = keyblk + mac_key_len; - - iv_copy_len = (transform->fixed_ivlen) ? - transform->fixed_ivlen : transform->ivlen; - memcpy(transform->iv_enc, key2 + keylen, iv_copy_len); - memcpy(transform->iv_dec, key2 + keylen + iv_copy_len, - iv_copy_len); - } else -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - if (endpoint == MBEDTLS_SSL_IS_SERVER) { - key1 = keyblk + mac_key_len * 2 + keylen; - key2 = keyblk + mac_key_len * 2; - - mac_enc = keyblk + mac_key_len; - mac_dec = keyblk; - - iv_copy_len = (transform->fixed_ivlen) ? - transform->fixed_ivlen : transform->ivlen; - memcpy(transform->iv_dec, key1 + keylen, iv_copy_len); - memcpy(transform->iv_enc, key1 + keylen + iv_copy_len, - iv_copy_len); - } else -#endif /* MBEDTLS_SSL_SRV_C */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto end; - } - - if (ssl->f_export_keys != NULL) { - ssl->f_export_keys(ssl->p_export_keys, - MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET, - master, 48, - randbytes + 32, - randbytes, - tls_prf_get_type(tls_prf)); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - transform->psa_alg = alg; - - if (alg != MBEDTLS_SSL_NULL_CIPHER) { - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, key_type); - - if ((status = psa_import_key(&attributes, - key1, - PSA_BITS_TO_BYTES(key_bits), - &transform->psa_key_enc)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET(3, "psa_import_key", (int) status); - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_import_key", ret); - goto end; - } - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); - - if ((status = psa_import_key(&attributes, - key2, - PSA_BITS_TO_BYTES(key_bits), - &transform->psa_key_dec)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_import_key", ret); - goto end; - } - } -#else - if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_enc, - cipher_info)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret); - goto end; - } - - if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec, - cipher_info)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret); - goto end; - } - - if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_enc, key1, - (int) mbedtls_cipher_info_get_key_bitlen(cipher_info), - MBEDTLS_ENCRYPT)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret); - goto end; - } - - if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_dec, key2, - (int) mbedtls_cipher_info_get_key_bitlen(cipher_info), - MBEDTLS_DECRYPT)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret); - goto end; - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if (mbedtls_cipher_info_get_mode(cipher_info) == MBEDTLS_MODE_CBC) { - if ((ret = mbedtls_cipher_set_padding_mode(&transform->cipher_ctx_enc, - MBEDTLS_PADDING_NONE)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_set_padding_mode", ret); - goto end; - } - - if ((ret = mbedtls_cipher_set_padding_mode(&transform->cipher_ctx_dec, - MBEDTLS_PADDING_NONE)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_set_padding_mode", ret); - goto end; - } - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) - /* For HMAC-based ciphersuites, initialize the HMAC transforms. - For AEAD-based ciphersuites, there is nothing to do here. */ - if (mac_key_len != 0) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - transform->psa_mac_alg = PSA_ALG_HMAC(mac_alg); - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); - psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(mac_alg)); - psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); - - if ((status = psa_import_key(&attributes, - mac_enc, mac_key_len, - &transform->psa_mac_enc)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_import_mac_key", ret); - goto end; - } - - if ((transform->psa_alg == MBEDTLS_SSL_NULL_CIPHER) || - ((transform->psa_alg == PSA_ALG_CBC_NO_PADDING) -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - && (transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) -#endif - )) { - /* mbedtls_ct_hmac() requires the key to be exportable */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT | - PSA_KEY_USAGE_VERIFY_HASH); - } else { - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); - } - - if ((status = psa_import_key(&attributes, - mac_dec, mac_key_len, - &transform->psa_mac_dec)) != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_import_mac_key", ret); - goto end; - } -#else - ret = mbedtls_md_hmac_starts(&transform->md_ctx_enc, mac_enc, mac_key_len); - if (ret != 0) { - goto end; - } - ret = mbedtls_md_hmac_starts(&transform->md_ctx_dec, mac_dec, mac_key_len); - if (ret != 0) { - goto end; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - - ((void) mac_dec); - ((void) mac_enc); - -end: - mbedtls_platform_zeroize(keyblk, sizeof(keyblk)); - return ret; -} - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_psa_ecjpake_read_round( - psa_pake_operation_t *pake_ctx, - const unsigned char *buf, - size_t len, mbedtls_ecjpake_rounds_t round) -{ - psa_status_t status; - size_t input_offset = 0; - /* - * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice - * At round two perform a single cycle - */ - unsigned int remaining_steps = (round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1; - - for (; remaining_steps > 0; remaining_steps--) { - for (psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE; - step <= PSA_PAKE_STEP_ZK_PROOF; - ++step) { - /* Length is stored at the first byte */ - size_t length = buf[input_offset]; - input_offset += 1; - - if (input_offset + length > len) { - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - status = psa_pake_input(pake_ctx, step, - buf + input_offset, length); - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } - - input_offset += length; - } - } - - if (input_offset != len) { - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - return 0; -} - -int mbedtls_psa_ecjpake_write_round( - psa_pake_operation_t *pake_ctx, - unsigned char *buf, - size_t len, size_t *olen, - mbedtls_ecjpake_rounds_t round) -{ - psa_status_t status; - size_t output_offset = 0; - size_t output_len; - /* - * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice - * At round two perform a single cycle - */ - unsigned int remaining_steps = (round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1; - - for (; remaining_steps > 0; remaining_steps--) { - for (psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE; - step <= PSA_PAKE_STEP_ZK_PROOF; - ++step) { - /* - * For each step, prepend 1 byte with the length of the data as - * given by psa_pake_output(). - */ - status = psa_pake_output(pake_ctx, step, - buf + output_offset + 1, - len - output_offset - 1, - &output_len); - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } - - *(buf + output_offset) = (uint8_t) output_len; - - output_offset += output_len + 1; - } - } - - *olen = output_offset; - - return 0; -} -#endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg) -{ - psa_status_t status; - psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; - psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(md_alg); - - MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based computation of digest of ServerKeyExchange")); - - if ((status = psa_hash_setup(&hash_operation, - hash_alg)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_setup", status); - goto exit; - } - - if ((status = psa_hash_update(&hash_operation, ssl->handshake->randbytes, - 64)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status); - goto exit; - } - - if ((status = psa_hash_update(&hash_operation, - data, data_len)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_update", status); - goto exit; - } - - if ((status = psa_hash_finish(&hash_operation, hash, PSA_HASH_MAX_SIZE, - hashlen)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET(1, "psa_hash_finish", status); - goto exit; - } - -exit: - if (status != PSA_SUCCESS) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - switch (status) { - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; - case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */ - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_MD_BAD_INPUT_DATA; - case PSA_ERROR_INSUFFICIENT_MEMORY: - return MBEDTLS_ERR_MD_ALLOC_FAILED; - default: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - } - return 0; -} - -#else - -int mbedtls_ssl_get_key_exchange_md_tls1_2(mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg) -{ - int ret = 0; - mbedtls_md_context_t ctx; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg); - *hashlen = mbedtls_md_get_size(md_info); - - MBEDTLS_SSL_DEBUG_MSG(3, ("Perform mbedtls-based computation of digest of ServerKeyExchange")); - - mbedtls_md_init(&ctx); - - /* - * digitally-signed struct { - * opaque client_random[32]; - * opaque server_random[32]; - * ServerDHParams params; - * }; - */ - if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_setup", ret); - goto exit; - } - if ((ret = mbedtls_md_starts(&ctx)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_starts", ret); - goto exit; - } - if ((ret = mbedtls_md_update(&ctx, ssl->handshake->randbytes, 64)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_update", ret); - goto exit; - } - if ((ret = mbedtls_md_update(&ctx, data, data_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_update", ret); - goto exit; - } - if ((ret = mbedtls_md_finish(&ctx, hash)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_finish", ret); - goto exit; - } - -exit: - mbedtls_md_free(&ctx); - - if (ret != 0) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - } - - return ret; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - -/* Find the preferred hash for a given signature algorithm. */ -unsigned int mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( - mbedtls_ssl_context *ssl, - unsigned int sig_alg) -{ - unsigned int i; - uint16_t *received_sig_algs = ssl->handshake->received_sig_algs; - - if (sig_alg == MBEDTLS_SSL_SIG_ANON) { - return MBEDTLS_SSL_HASH_NONE; - } - - for (i = 0; received_sig_algs[i] != MBEDTLS_TLS_SIG_NONE; i++) { - unsigned int hash_alg_received = - MBEDTLS_SSL_TLS12_HASH_ALG_FROM_SIG_AND_HASH_ALG( - received_sig_algs[i]); - unsigned int sig_alg_received = - MBEDTLS_SSL_TLS12_SIG_ALG_FROM_SIG_AND_HASH_ALG( - received_sig_algs[i]); - - mbedtls_md_type_t md_alg = - mbedtls_ssl_md_alg_from_hash((unsigned char) hash_alg_received); - if (md_alg == MBEDTLS_MD_NONE) { - continue; - } - - if (sig_alg == sig_alg_received) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (ssl->handshake->key_cert && ssl->handshake->key_cert->key) { - psa_algorithm_t psa_hash_alg = - mbedtls_md_psa_alg_from_type(md_alg); - - if (sig_alg_received == MBEDTLS_SSL_SIG_ECDSA && - !mbedtls_pk_can_do_ext(ssl->handshake->key_cert->key, - PSA_ALG_ECDSA(psa_hash_alg), - PSA_KEY_USAGE_SIGN_HASH)) { - continue; - } - - if (sig_alg_received == MBEDTLS_SSL_SIG_RSA && - !mbedtls_pk_can_do_ext(ssl->handshake->key_cert->key, - PSA_ALG_RSA_PKCS1V15_SIGN( - psa_hash_alg), - PSA_KEY_USAGE_SIGN_HASH)) { - continue; - } - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - return hash_alg_received; - } - } - - return MBEDTLS_SSL_HASH_NONE; -} - -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -int mbedtls_ssl_validate_ciphersuite( - const mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *suite_info, - mbedtls_ssl_protocol_version min_tls_version, - mbedtls_ssl_protocol_version max_tls_version) -{ - (void) ssl; - - if (suite_info == NULL) { - return -1; - } - - if ((suite_info->min_tls_version > max_tls_version) || - (suite_info->max_tls_version < min_tls_version)) { - return -1; - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_CLI_C) -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && - ssl->handshake->psa_pake_ctx_is_ok != 1) -#else - if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && - mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - { - return -1; - } -#endif - - /* Don't suggest PSK-based ciphersuite if no PSK is available. */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_psk(suite_info) && - mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) { - return -1; - } -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - return 0; -} - -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -/* - * Function for writing a signature algorithm extension. - * - * The `extension_data` field of signature algorithm contains a `SignatureSchemeList` - * value (TLS 1.3 RFC8446): - * enum { - * .... - * ecdsa_secp256r1_sha256( 0x0403 ), - * ecdsa_secp384r1_sha384( 0x0503 ), - * ecdsa_secp521r1_sha512( 0x0603 ), - * .... - * } SignatureScheme; - * - * struct { - * SignatureScheme supported_signature_algorithms<2..2^16-2>; - * } SignatureSchemeList; - * - * The `extension_data` field of signature algorithm contains a `SignatureAndHashAlgorithm` - * value (TLS 1.2 RFC5246): - * enum { - * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), - * sha512(6), (255) - * } HashAlgorithm; - * - * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } - * SignatureAlgorithm; - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * SignatureAndHashAlgorithm - * supported_signature_algorithms<2..2^16-2>; - * - * The TLS 1.3 signature algorithm extension was defined to be a compatible - * generalization of the TLS 1.2 signature algorithm extension. - * `SignatureAndHashAlgorithm` field of TLS 1.2 can be represented by - * `SignatureScheme` field of TLS 1.3 - * - */ -int mbedtls_ssl_write_sig_alg_ext(mbedtls_ssl_context *ssl, unsigned char *buf, - const unsigned char *end, size_t *out_len) -{ - unsigned char *p = buf; - unsigned char *supported_sig_alg; /* Start of supported_signature_algorithms */ - size_t supported_sig_alg_len = 0; /* Length of supported_signature_algorithms */ - - *out_len = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, ("adding signature_algorithms extension")); - - /* Check if we have space for header and length field: - * - extension_type (2 bytes) - * - extension_data_length (2 bytes) - * - supported_signature_algorithms_length (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - p += 6; - - /* - * Write supported_signature_algorithms - */ - supported_sig_alg = p; - const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl); - if (sig_alg == NULL) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - - for (; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++) { - MBEDTLS_SSL_DEBUG_MSG(3, ("got signature scheme [%x] %s", - *sig_alg, - mbedtls_ssl_sig_alg_to_str(*sig_alg))); - if (!mbedtls_ssl_sig_alg_is_supported(ssl, *sig_alg)) { - continue; - } - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - MBEDTLS_PUT_UINT16_BE(*sig_alg, p, 0); - p += 2; - MBEDTLS_SSL_DEBUG_MSG(3, ("sent signature scheme [%x] %s", - *sig_alg, - mbedtls_ssl_sig_alg_to_str(*sig_alg))); - } - - /* Length of supported_signature_algorithms */ - supported_sig_alg_len = (size_t) (p - supported_sig_alg); - if (supported_sig_alg_len == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("No signature algorithms defined.")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SIG_ALG, buf, 0); - MBEDTLS_PUT_UINT16_BE(supported_sig_alg_len + 2, buf, 2); - MBEDTLS_PUT_UINT16_BE(supported_sig_alg_len, buf, 4); - - *out_len = (size_t) (p - buf); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_SIG_ALG); -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - - return 0; -} -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -/* - * mbedtls_ssl_parse_server_name_ext - * - * Structure of server_name extension: - * - * enum { - * host_name(0), (255) - * } NameType; - * opaque HostName<1..2^16-1>; - * - * struct { - * NameType name_type; - * select (name_type) { - * case host_name: HostName; - * } name; - * } ServerName; - * struct { - * ServerName server_name_list<1..2^16-1> - * } ServerNameList; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_server_name_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - size_t server_name_list_len, hostname_len; - const unsigned char *server_name_list_end; - - MBEDTLS_SSL_DEBUG_MSG(3, ("parse ServerName extension")); - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - server_name_list_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, server_name_list_len); - server_name_list_end = p + server_name_list_len; - while (p < server_name_list_end) { - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, server_name_list_end, 3); - hostname_len = MBEDTLS_GET_UINT16_BE(p, 1); - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, server_name_list_end, - hostname_len + 3); - - if (p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME) { - /* sni_name is intended to be used only during the parsing of the - * ClientHello message (it is reset to NULL before the end of - * the message parsing). Thus it is ok to just point to the - * reception buffer and not make a copy of it. - */ - ssl->handshake->sni_name = p + 3; - ssl->handshake->sni_name_len = hostname_len; - if (ssl->conf->f_sni == NULL) { - return 0; - } - ret = ssl->conf->f_sni(ssl->conf->p_sni, - ssl, p + 3, hostname_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_sni_wrapper", ret); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME, - MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME); - return MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME; - } - return 0; - } - - p += hostname_len + 3; - } - - return 0; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_ALPN) -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_parse_alpn_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - const unsigned char *p = buf; - size_t protocol_name_list_len; - const unsigned char *protocol_name_list; - const unsigned char *protocol_name_list_end; - size_t protocol_name_len; - - /* If ALPN not configured, just ignore the extension */ - if (ssl->conf->alpn_list == NULL) { - return 0; - } - - /* - * RFC7301, section 3.1 - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - */ - - /* - * protocol_name_list_len 2 bytes - * protocol_name_len 1 bytes - * protocol_name >=1 byte - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 4); - - protocol_name_list_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, protocol_name_list_len); - protocol_name_list = p; - protocol_name_list_end = p + protocol_name_list_len; - - /* Validate peer's list (lengths) */ - while (p < protocol_name_list_end) { - protocol_name_len = *p++; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, protocol_name_list_end, - protocol_name_len); - if (protocol_name_len == 0) { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - p += protocol_name_len; - } - - /* Use our order of preference */ - for (const char **alpn = ssl->conf->alpn_list; *alpn != NULL; alpn++) { - size_t const alpn_len = strlen(*alpn); - p = protocol_name_list; - while (p < protocol_name_list_end) { - protocol_name_len = *p++; - if (protocol_name_len == alpn_len && - memcmp(p, *alpn, alpn_len) == 0) { - ssl->alpn_chosen = *alpn; - return 0; - } - - p += protocol_name_len; - } - } - - /* If we get here, no match was found */ - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL, - MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL); - return MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL; -} - -int mbedtls_ssl_write_alpn_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - size_t protocol_name_len; - *out_len = 0; - - if (ssl->alpn_chosen == NULL) { - return 0; - } - - protocol_name_len = strlen(ssl->alpn_chosen); - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 7 + protocol_name_len); - - MBEDTLS_SSL_DEBUG_MSG(3, ("server side, adding alpn extension")); - /* - * 0 . 1 ext identifier - * 2 . 3 ext length - * 4 . 5 protocol list length - * 6 . 6 protocol name length - * 7 . 7+n protocol name - */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ALPN, p, 0); - - *out_len = 7 + protocol_name_len; - - MBEDTLS_PUT_UINT16_BE(protocol_name_len + 3, p, 2); - MBEDTLS_PUT_UINT16_BE(protocol_name_len + 1, p, 4); - /* Note: the length of the chosen protocol has been checked to be less - * than 255 bytes in `mbedtls_ssl_conf_alpn_protocols`. - */ - p[6] = MBEDTLS_BYTE_0(protocol_name_len); - - memcpy(p + 7, ssl->alpn_chosen, protocol_name_len); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_ALPN); -#endif - - return 0; -} -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ - defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ - defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session, - const char *hostname) -{ - /* Initialize to suppress unnecessary compiler warning */ - size_t hostname_len = 0; - - /* Check if new hostname is valid before - * making any change to current one */ - if (hostname != NULL) { - hostname_len = strlen(hostname); - - if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - } - - /* Now it's clear that we will overwrite the old hostname, - * so we can free it safely */ - if (session->hostname != NULL) { - mbedtls_zeroize_and_free(session->hostname, - strlen(session->hostname)); - } - - /* Passing NULL as hostname shall clear the old one */ - if (hostname == NULL) { - session->hostname = NULL; - } else { - session->hostname = mbedtls_calloc(1, hostname_len + 1); - if (session->hostname == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(session->hostname, hostname, hostname_len); - } - - return 0; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && - MBEDTLS_SSL_SESSION_TICKETS && - MBEDTLS_SSL_SERVER_NAME_INDICATION && - MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \ - defined(MBEDTLS_SSL_ALPN) -int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session, - const char *alpn) -{ - size_t alpn_len = 0; - - if (alpn != NULL) { - alpn_len = strlen(alpn); - - if (alpn_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - } - - if (session->ticket_alpn != NULL) { - mbedtls_zeroize_and_free(session->ticket_alpn, - strlen(session->ticket_alpn)); - session->ticket_alpn = NULL; - } - - if (alpn != NULL) { - session->ticket_alpn = mbedtls_calloc(alpn_len + 1, 1); - if (session->ticket_alpn == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(session->ticket_alpn, alpn, alpn_len); - } - - return 0; -} -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ - -/* - * The following functions are used by 1.2 and 1.3, client and server. - */ -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, - const mbedtls_ssl_ciphersuite_t *ciphersuite, - int recv_endpoint, - mbedtls_ssl_protocol_version tls_version, - uint32_t *flags) -{ - int ret = 0; - unsigned int usage = 0; - const char *ext_oid; - size_t ext_len; - - /* - * keyUsage - */ - - /* Note: don't guard this with MBEDTLS_SSL_CLI_C because the server wants - * to check what a compliant client will think while choosing which cert - * to send to the client. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && - recv_endpoint == MBEDTLS_SSL_IS_CLIENT) { - /* TLS 1.2 server part of the key exchange */ - switch (ciphersuite->key_exchange) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT; - break; - - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; - break; - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - usage = MBEDTLS_X509_KU_KEY_AGREEMENT; - break; - - /* Don't use default: we want warnings when adding new values */ - case MBEDTLS_KEY_EXCHANGE_NONE: - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - usage = 0; - } - } else -#endif - { - /* This is either TLS 1.3 authentication, which always uses signatures, - * or 1.2 client auth: rsa_sign and mbedtls_ecdsa_sign are the only - * options we implement, both using signatures. */ - (void) tls_version; - (void) ciphersuite; - usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; - } - - if (mbedtls_x509_crt_check_key_usage(cert, usage) != 0) { - *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE; - ret = -1; - } - - /* - * extKeyUsage - */ - - if (recv_endpoint == MBEDTLS_SSL_IS_CLIENT) { - ext_oid = MBEDTLS_OID_SERVER_AUTH; - ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH); - } else { - ext_oid = MBEDTLS_OID_CLIENT_AUTH; - ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH); - } - - if (mbedtls_x509_crt_check_extended_key_usage(cert, ext_oid, ext_len) != 0) { - *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE; - ret = -1; - } - - return ret; -} - -static int get_hostname_for_verification(mbedtls_ssl_context *ssl, - const char **hostname) -{ - if (!mbedtls_ssl_has_set_hostname_been_called(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Certificate verification without having set hostname")); -#if !defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME) - if (mbedtls_ssl_conf_get_endpoint(ssl->conf) == MBEDTLS_SSL_IS_CLIENT && - ssl->conf->authmode == MBEDTLS_SSL_VERIFY_REQUIRED) { - return MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME; - } -#endif - } - - *hostname = mbedtls_ssl_get_hostname_pointer(ssl); - if (*hostname == NULL) { - MBEDTLS_SSL_DEBUG_MSG(2, ("Certificate verification without CN verification")); - } - - return 0; -} - -int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, - int authmode, - mbedtls_x509_crt *chain, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info, - void *rs_ctx) -{ - if (authmode == MBEDTLS_SSL_VERIFY_NONE) { - ssl->session_negotiate->verify_result = 0; - return 0; - } - - /* - * Primary check: use the appropriate X.509 verification function - */ - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); - void *p_vrfy; - if (ssl->f_vrfy != NULL) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Use context-specific verification callback")); - f_vrfy = ssl->f_vrfy; - p_vrfy = ssl->p_vrfy; - } else { - MBEDTLS_SSL_DEBUG_MSG(3, ("Use configuration-specific verification callback")); - f_vrfy = ssl->conf->f_vrfy; - p_vrfy = ssl->conf->p_vrfy; - } - - const char *hostname = ""; - int ret = get_hostname_for_verification(ssl, &hostname); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "get_hostname_for_verification", ret); - return ret; - } - - int have_ca_chain_or_callback = 0; -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - if (ssl->conf->f_ca_cb != NULL) { - ((void) rs_ctx); - have_ca_chain_or_callback = 1; - - MBEDTLS_SSL_DEBUG_MSG(3, ("use CA callback for X.509 CRT verification")); - ret = mbedtls_x509_crt_verify_with_ca_cb( - chain, - ssl->conf->f_ca_cb, - ssl->conf->p_ca_cb, - ssl->conf->cert_profile, - hostname, - &ssl->session_negotiate->verify_result, - f_vrfy, p_vrfy); - } else -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - { - mbedtls_x509_crt *ca_chain; - mbedtls_x509_crl *ca_crl; -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (ssl->handshake->sni_ca_chain != NULL) { - ca_chain = ssl->handshake->sni_ca_chain; - ca_crl = ssl->handshake->sni_ca_crl; - } else -#endif - { - ca_chain = ssl->conf->ca_chain; - ca_crl = ssl->conf->ca_crl; - } - - if (ca_chain != NULL) { - have_ca_chain_or_callback = 1; - } - - ret = mbedtls_x509_crt_verify_restartable( - chain, - ca_chain, ca_crl, - ssl->conf->cert_profile, - hostname, - &ssl->session_negotiate->verify_result, - f_vrfy, p_vrfy, rs_ctx); - } - - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret); - } - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; - } -#endif - - /* - * Secondary checks: always done, but change 'ret' only if it was 0 - */ - - /* With TLS 1.2 and ECC certs, check that the curve used by the - * certificate is on our list of acceptable curves. - * - * With TLS 1.3 this is not needed because the curve is part of the - * signature algorithm (eg ecdsa_secp256r1_sha256) which is checked when - * we validate the signature made with the key associated to this cert. - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && - mbedtls_pk_can_do(&chain->pk, MBEDTLS_PK_ECKEY)) { - if (mbedtls_ssl_check_curve(ssl, mbedtls_pk_get_ec_group_id(&chain->pk)) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (EC key curve)")); - ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; - if (ret == 0) { - ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE; - } - } - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_PK_HAVE_ECC_KEYS */ - - /* Check X.509 usage extensions (keyUsage, extKeyUsage) */ - if (mbedtls_ssl_check_cert_usage(chain, - ciphersuite_info, - ssl->conf->endpoint, - ssl->tls_version, - &ssl->session_negotiate->verify_result) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)")); - if (ret == 0) { - ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE; - } - } - - /* With authmode optional, we want to keep going if the certificate was - * unacceptable, but still fail on other errors (out of memory etc), - * including fatal errors from the f_vrfy callback. - * - * The only acceptable errors are: - * - MBEDTLS_ERR_X509_CERT_VERIFY_FAILED: cert rejected by primary check; - * - MBEDTLS_ERR_SSL_BAD_CERTIFICATE: cert rejected by secondary checks. - * Anything else is a fatal error. */ - if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && - (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || - ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE)) { - ret = 0; - } - - /* Return a specific error as this is a user error: inconsistent - * configuration - can't verify without trust anchors. */ - if (have_ca_chain_or_callback == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain")); - ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; - } - - if (ret != 0) { - uint8_t alert; - - /* The certificate may have been rejected for several reasons. - Pick one and send the corresponding alert. Which alert to send - may be a subject of debate in some cases. */ - if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER) { - alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) { - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE) { - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE) { - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK) { - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY) { - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED) { - alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED) { - alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED; - } else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { - alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA; - } else { - alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN; - } - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - alert); - } - -#if defined(MBEDTLS_DEBUG_C) - if (ssl->session_negotiate->verify_result != 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x", - (unsigned int) ssl->session_negotiate->verify_result)); - } else { - MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear")); - } -#endif /* MBEDTLS_DEBUG_C */ - - return ret; -} -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl, - const mbedtls_md_type_t hash_alg, - uint8_t *out, - const size_t key_len, - const char *label, - const size_t label_len, - const unsigned char *context, - const size_t context_len, - const int use_context) -{ - int ret = 0; - unsigned char *prf_input = NULL; - - /* The input to the PRF is client_random, then server_random. - * If a context is provided, this is then followed by the context length - * as a 16-bit big-endian integer, and then the context itself. */ - const size_t randbytes_len = MBEDTLS_CLIENT_HELLO_RANDOM_LEN + MBEDTLS_SERVER_HELLO_RANDOM_LEN; - size_t prf_input_len = randbytes_len; - if (use_context) { - if (context_len > UINT16_MAX) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* This does not overflow a 32-bit size_t because the current value of - * prf_input_len is 64 (length of client_random + server_random) and - * context_len fits into two bytes (checked above). */ - prf_input_len += sizeof(uint16_t) + context_len; - } - - prf_input = mbedtls_calloc(prf_input_len, sizeof(unsigned char)); - if (prf_input == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(prf_input, - ssl->transform->randbytes + MBEDTLS_SERVER_HELLO_RANDOM_LEN, - MBEDTLS_CLIENT_HELLO_RANDOM_LEN); - memcpy(prf_input + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, - ssl->transform->randbytes, - MBEDTLS_SERVER_HELLO_RANDOM_LEN); - if (use_context) { - MBEDTLS_PUT_UINT16_BE(context_len, prf_input, randbytes_len); - memcpy(prf_input + randbytes_len + sizeof(uint16_t), context, context_len); - } - ret = tls_prf_generic(hash_alg, ssl->session->master, sizeof(ssl->session->master), - label, label_len, - prf_input, prf_input_len, - out, key_len); - mbedtls_free(prf_input); - return ret; -} -#endif /* defined(MBEDTLS_SSL_PROTO_TLS1_2) */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, - const mbedtls_md_type_t hash_alg, - uint8_t *out, - const size_t key_len, - const char *label, - const size_t label_len, - const unsigned char *context, - const size_t context_len) -{ - const psa_algorithm_t psa_hash_alg = mbedtls_md_psa_alg_from_type(hash_alg); - const size_t hash_len = PSA_HASH_LENGTH(psa_hash_alg); - const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; - - /* The length of the label must be at most 249 bytes to fit into the HkdfLabel - * struct as defined in RFC 8446, Section 7.1. - * - * The length of the context is unlimited even though the context field in the - * struct can only hold up to 255 bytes. This is because we place a *hash* of - * the context in the field. */ - if (label_len > 249) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - return mbedtls_ssl_tls13_exporter(psa_hash_alg, secret, hash_len, - (const unsigned char *) label, label_len, - context, context_len, out, key_len); -} -#endif /* defined(MBEDTLS_SSL_PROTO_TLS1_3) */ - -int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, - uint8_t *out, const size_t key_len, - const char *label, const size_t label_len, - const unsigned char *context, const size_t context_len, - const int use_context) -{ - if (!mbedtls_ssl_is_handshake_over(ssl)) { - /* TODO: Change this to a more appropriate error code when one is available. */ - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (key_len > MBEDTLS_SSL_EXPORT_MAX_KEY_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - int ciphersuite_id = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); - const mbedtls_ssl_ciphersuite_t *ciphersuite = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id); - const mbedtls_md_type_t hash_alg = ciphersuite->mac; - - switch (mbedtls_ssl_get_version_number(ssl)) { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - case MBEDTLS_SSL_VERSION_TLS1_2: - return mbedtls_ssl_tls12_export_keying_material(ssl, hash_alg, out, key_len, - label, label_len, - context, context_len, use_context); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - case MBEDTLS_SSL_VERSION_TLS1_3: - return mbedtls_ssl_tls13_export_keying_material(ssl, - hash_alg, - out, - key_len, - label, - label_len, - use_context ? context : NULL, - use_context ? context_len : 0); -#endif - default: - return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - } -} - -#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */ - -#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/vendor/mbedtls/library/ssl_tls12_client.c b/vendor/mbedtls/library/ssl_tls12_client.c deleted file mode 100644 index 0196c0cc5..000000000 --- a/vendor/mbedtls/library/ssl_tls12_client.c +++ /dev/null @@ -1,3639 +0,0 @@ -/* - * TLS client-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2) - -#include "mbedtls/platform.h" - -#include "mbedtls/ssl.h" -#include "ssl_client.h" -#include "ssl_misc.h" -#include "debug_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/constant_time.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa_util_internal.h" -#include "psa/crypto.h" -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#include - -#include - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#include "mbedtls/platform_util.h" -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - - *olen = 0; - - /* We're always including a TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the - * initial ClientHello, in which case also adding the renegotiation - * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ - if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding renegotiation extension")); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + ssl->verify_data_len); - - /* - * Secure renegotiation - */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len + 1); - *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len); - - memcpy(p, ssl->own_verify_data, ssl->verify_data_len); - - *olen = 5 + ssl->verify_data_len; - - return 0; -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - (void) ssl; /* ssl used for debugging only */ - - *olen = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding supported_point_formats extension")); - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 2; - - *p++ = 1; - *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; - - *olen = 6; - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - size_t kkpp_len = 0; - - *olen = 0; - - /* Skip costly extension if we can't use EC J-PAKE anyway */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (ssl->handshake->psa_pake_ctx_is_ok != 1) { - return 0; - } -#else - if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) { - return 0; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding ecjpake_kkpp extension")); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0); - p += 2; - - /* - * We may need to send ClientHello multiple times for Hello verification. - * We don't want to compute fresh values every time (both for performance - * and consistency reasons), so cache the extension content. - */ - if (ssl->handshake->ecjpake_cache == NULL || - ssl->handshake->ecjpake_cache_len == 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("generating new ecjpake parameters")); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, - p + 2, end - p - 2, &kkpp_len, - MBEDTLS_ECJPAKE_ROUND_ONE); - if (ret != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); - return ret; - } -#else - ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx, - p + 2, end - p - 2, &kkpp_len, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "mbedtls_ecjpake_write_round_one", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - ssl->handshake->ecjpake_cache = mbedtls_calloc(1, kkpp_len); - if (ssl->handshake->ecjpake_cache == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("allocation failed")); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(ssl->handshake->ecjpake_cache, p + 2, kkpp_len); - ssl->handshake->ecjpake_cache_len = kkpp_len; - } else { - MBEDTLS_SSL_DEBUG_MSG(3, ("re-using cached ecjpake parameters")); - - kkpp_len = ssl->handshake->ecjpake_cache_len; - MBEDTLS_SSL_CHK_BUF_PTR(p + 2, end, kkpp_len); - - memcpy(p + 2, ssl->handshake->ecjpake_cache, kkpp_len); - } - - MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0); - p += 2; - - *olen = kkpp_len + 4; - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_cid_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - size_t ext_len; - - /* - * struct { - * opaque cid<0..2^8-1>; - * } ConnectionId; - */ - - *olen = 0; - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || - ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { - return 0; - } - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding CID extension")); - - /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX - * which is at most 255, so the increment cannot overflow. */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, (unsigned) (ssl->own_cid_len + 5)); - - /* Add extension ID + size */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0); - p += 2; - ext_len = (size_t) ssl->own_cid_len + 1; - MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); - p += 2; - - *p++ = (uint8_t) ssl->own_cid_len; - memcpy(p, ssl->own_cid, ssl->own_cid_len); - - *olen = ssl->own_cid_len + 5; - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - - *olen = 0; - - if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding max_fragment_length extension")); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 1; - - *p++ = ssl->conf->mfl_code; - - *olen = 5; - - return 0; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - - *olen = 0; - - if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding encrypt_then_mac extension")); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; - - return 0; -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - - *olen = 0; - - if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding extended_master_secret extension")); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; - - return 0; -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - size_t tlen = ssl->session_negotiate->ticket_len; - - *olen = 0; - - if (mbedtls_ssl_conf_get_session_tickets(ssl->conf) == - MBEDTLS_SSL_SESSION_TICKETS_DISABLED) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding session ticket extension")); - - /* The addition is safe here since the ticket length is 16 bit. */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4 + tlen); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0); - p += 2; - - MBEDTLS_PUT_UINT16_BE(tlen, p, 0); - p += 2; - - *olen = 4; - - if (ssl->session_negotiate->ticket == NULL || tlen == 0) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("sending session ticket of length %" MBEDTLS_PRINTF_SIZET, tlen)); - - memcpy(p, ssl->session_negotiate->ticket, tlen); - - *olen += tlen; - - return 0; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *olen) -{ - unsigned char *p = buf; - size_t protection_profiles_index = 0, ext_len = 0; - uint16_t mki_len = 0, profile_value = 0; - - *olen = 0; - - if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (ssl->conf->dtls_srtp_profile_list == NULL) || - (ssl->conf->dtls_srtp_profile_list_len == 0)) { - return 0; - } - - /* RFC 5764 section 4.1.1 - * uint8 SRTPProtectionProfile[2]; - * - * struct { - * SRTPProtectionProfiles SRTPProtectionProfiles; - * opaque srtp_mki<0..255>; - * } UseSRTPData; - * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; - */ - if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { - mki_len = ssl->dtls_srtp_info.mki_len; - } - /* Extension length = 2 bytes for profiles length, - * ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ), - * 1 byte for srtp_mki vector length and the mki_len value - */ - ext_len = 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len; - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding use_srtp extension")); - - /* Check there is room in the buffer for the extension + 4 bytes - * - the extension tag (2 bytes) - * - the extension length (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, ext_len + 4); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, p, 0); - p += 2; - - MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); - p += 2; - - /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */ - /* micro-optimization: - * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH - * which is lower than 127, so the upper byte of the length is always 0 - * For the documentation, the more generic code is left in comments - * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len ) - * >> 8 ) & 0xFF ); - */ - *p++ = 0; - *p++ = MBEDTLS_BYTE_0(2 * ssl->conf->dtls_srtp_profile_list_len); - - for (protection_profiles_index = 0; - protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len; - protection_profiles_index++) { - profile_value = mbedtls_ssl_check_srtp_profile_value - (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]); - if (profile_value != MBEDTLS_TLS_SRTP_UNSET) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_write_use_srtp_ext, add profile: %04x", - profile_value)); - MBEDTLS_PUT_UINT16_BE(profile_value, p, 0); - p += 2; - } else { - /* - * Note: we shall never arrive here as protection profiles - * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function - */ - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, " - "illegal DTLS-SRTP protection profile %d", - ssl->conf->dtls_srtp_profile_list[protection_profiles_index] - )); - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - } - - *p++ = mki_len & 0xFF; - - if (mki_len != 0) { - memcpy(p, ssl->dtls_srtp_info.mki_value, mki_len); - /* - * Increment p to point to the current position. - */ - p += mki_len; - MBEDTLS_SSL_DEBUG_BUF(3, "sending mki", ssl->dtls_srtp_info.mki_value, - ssl->dtls_srtp_info.mki_len); - } - - /* - * total extension length: extension type (2 bytes) - * + extension length (2 bytes) - * + protection profile length (2 bytes) - * + 2 * number of protection profiles - * + srtp_mki vector length(1 byte) - * + mki value - */ - *olen = p - buf; - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -int mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - int uses_ec, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - size_t ext_len = 0; - - (void) ssl; - (void) end; - (void) uses_ec; - (void) ret; - (void) ext_len; - - *out_len = 0; - - /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added - * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if ((ret = ssl_write_renegotiation_ext(ssl, p, end, &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_renegotiation_ext", ret); - return ret; - } - p += ext_len; -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if (uses_ec) { - if ((ret = ssl_write_supported_point_formats_ext(ssl, p, end, - &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_supported_point_formats_ext", ret); - return ret; - } - p += ext_len; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if ((ret = ssl_write_ecjpake_kkpp_ext(ssl, p, end, &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret); - return ret; - } - p += ext_len; -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - if ((ret = ssl_write_cid_ext(ssl, p, end, &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_cid_ext", ret); - return ret; - } - p += ext_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - if ((ret = ssl_write_max_fragment_length_ext(ssl, p, end, - &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_max_fragment_length_ext", ret); - return ret; - } - p += ext_len; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if ((ret = ssl_write_encrypt_then_mac_ext(ssl, p, end, &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_encrypt_then_mac_ext", ret); - return ret; - } - p += ext_len; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if ((ret = ssl_write_extended_ms_ext(ssl, p, end, &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_extended_ms_ext", ret); - return ret; - } - p += ext_len; -#endif - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - if ((ret = ssl_write_use_srtp_ext(ssl, p, end, &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_use_srtp_ext", ret); - return ret; - } - p += ext_len; -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if ((ret = ssl_write_session_ticket_ext(ssl, p, end, &ext_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_session_ticket_ext", ret); - return ret; - } - p += ext_len; -#endif - - *out_len = (size_t) (p - buf); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - /* Check verify-data in constant-time. The length OTOH is no secret */ - if (len != 1 + ssl->verify_data_len * 2 || - buf[0] != ssl->verify_data_len * 2 || - mbedtls_ct_memcmp(buf + 1, - ssl->own_verify_data, ssl->verify_data_len) != 0 || - mbedtls_ct_memcmp(buf + 1 + ssl->verify_data_len, - ssl->peer_verify_data, ssl->verify_data_len) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - } else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - if (len != 1 || buf[0] != 0x00) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("non-zero length renegotiation info")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - } - - return 0; -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - /* - * server should use the extension only if we did, - * and if so the server's value should match ours (and len is always 1) - */ - if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE || - len != 1 || - buf[0] != ssl->conf->mfl_code) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("non-matching max fragment length extension")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - return 0; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - size_t peer_cid_len; - - if ( /* CID extension only makes sense in DTLS */ - ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || - /* The server must only send the CID extension if we have offered it. */ - ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { - MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension unexpected")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); - return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; - } - - if (len == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - peer_cid_len = *buf++; - len--; - - if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) { - MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - if (len != peer_cid_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; - ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; - memcpy(ssl->handshake->peer_cid, buf, peer_cid_len); - - MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated")); - MBEDTLS_SSL_DEBUG_BUF(3, "Server CID", buf, peer_cid_len); - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - len != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("non-matching encrypt-then-MAC extension")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); - return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; - } - - ((void) buf); - - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; - - return 0; -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - len != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("non-matching extended master secret extension")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); - return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; - } - - ((void) buf); - - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; - - return 0; -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - if ((mbedtls_ssl_conf_get_session_tickets(ssl->conf) == - MBEDTLS_SSL_SESSION_TICKETS_DISABLED) || - len != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("non-matching session ticket extension")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); - return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; - } - - ((void) buf); - - ssl->handshake->new_session_ticket = 1; - - return 0; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - size_t list_size; - const unsigned char *p; - - if (len == 0 || (size_t) (buf[0] + 1) != len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - list_size = buf[0]; - - p = buf + 1; - while (list_size > 0) { - if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || - p[0] == MBEDTLS_ECP_PF_COMPRESSED) { -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) - ssl->handshake->ecdh_ctx.point_format = p[0]; -#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */ -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx, - p[0]); -#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0])); - return 0; - } - - list_size--; - p++; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("no point format in common")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ssl->handshake->ciphersuite_info->key_exchange != - MBEDTLS_KEY_EXCHANGE_ECJPAKE) { - MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension")); - return 0; - } - - /* If we got here, we no longer need our cached extension */ - mbedtls_free(ssl->handshake->ecjpake_cache); - ssl->handshake->ecjpake_cache = NULL; - ssl->handshake->ecjpake_cache_len = 0; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((ret = mbedtls_psa_ecjpake_read_round( - &ssl->handshake->psa_pake_ctx, buf, len, - MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return ret; - } - - return 0; -#else - if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx, - buf, len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return ret; - } - - return 0; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_alpn_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) -{ - size_t list_len, name_len; - const char **p; - - /* If we didn't send it, the server shouldn't send it */ - if (ssl->conf->alpn_list == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching ALPN extension")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); - return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; - } - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - * - * the "ProtocolNameList" MUST contain exactly one "ProtocolName" - */ - - /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ - if (len < 4) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - list_len = MBEDTLS_GET_UINT16_BE(buf, 0); - if (list_len != len - 2) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - name_len = buf[2]; - if (name_len != list_len - 1) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Check that the server chosen protocol was in our list and save it */ - for (p = ssl->conf->alpn_list; *p != NULL; p++) { - if (name_len == strlen(*p) && - memcmp(buf + 3, *p, name_len) == 0) { - ssl->alpn_chosen = *p; - return 0; - } - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("ALPN extension: no matching protocol")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; -} -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET; - size_t i, mki_len = 0; - uint16_t server_protection_profile_value = 0; - - /* If use_srtp is not configured, just ignore the extension */ - if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (ssl->conf->dtls_srtp_profile_list == NULL) || - (ssl->conf->dtls_srtp_profile_list_len == 0)) { - return 0; - } - - /* RFC 5764 section 4.1.1 - * uint8 SRTPProtectionProfile[2]; - * - * struct { - * SRTPProtectionProfiles SRTPProtectionProfiles; - * opaque srtp_mki<0..255>; - * } UseSRTPData; - - * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; - * - */ - if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { - mki_len = ssl->dtls_srtp_info.mki_len; - } - - /* - * Length is 5 + optional mki_value : one protection profile length (2 bytes) - * + protection profile (2 bytes) - * + mki_len(1 byte) - * and optional srtp_mki - */ - if ((len < 5) || (len != (buf[4] + 5u))) { - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* - * get the server protection profile - */ - - /* - * protection profile length must be 0x0002 as we must have only - * one protection profile in server Hello - */ - if ((buf[0] != 0) || (buf[1] != 2)) { - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - server_protection_profile_value = (buf[2] << 8) | buf[3]; - server_protection = mbedtls_ssl_check_srtp_profile_value( - server_protection_profile_value); - if (server_protection != MBEDTLS_TLS_SRTP_UNSET) { - MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s", - mbedtls_ssl_get_srtp_profile_as_string( - server_protection))); - } - - ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; - - /* - * Check we have the server profile in our list - */ - for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) { - if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) { - ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; - MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s", - mbedtls_ssl_get_srtp_profile_as_string( - server_protection))); - break; - } - } - - /* If no match was found : server problem, it shall never answer with incompatible profile */ - if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* If server does not use mki in its reply, make sure the client won't keep - * one as negotiated */ - if (len == 5) { - ssl->dtls_srtp_info.mki_len = 0; - } - - /* - * RFC5764: - * If the client detects a nonzero-length MKI in the server's response - * that is different than the one the client offered, then the client - * MUST abort the handshake and SHOULD send an invalid_parameter alert. - */ - if (len > 5 && (buf[4] != mki_len || - (memcmp(ssl->dtls_srtp_info.mki_value, &buf[5], mki_len)))) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } -#if defined(MBEDTLS_DEBUG_C) - if (len > 5) { - MBEDTLS_SSL_DEBUG_BUF(3, "received mki", ssl->dtls_srtp_info.mki_value, - ssl->dtls_srtp_info.mki_len); - } -#endif - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -/* - * Parse HelloVerifyRequest. Only called after verifying the HS type. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); - uint16_t dtls_legacy_version; - -#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) - uint8_t cookie_len; -#else - uint16_t cookie_len; -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse hello verify request")); - - /* Check that there is enough room for: - * - 2 bytes of version - * - 1 byte of cookie_len - */ - if (mbedtls_ssl_hs_hdr_len(ssl) + 3 > ssl->in_msglen) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("incoming HelloVerifyRequest message is too short")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* - * struct { - * ProtocolVersion server_version; - * opaque cookie<0..2^8-1>; - * } HelloVerifyRequest; - */ - MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2); - dtls_legacy_version = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* - * Since the RFC is not clear on this point, accept DTLS 1.0 (0xfeff) - * The DTLS 1.3 (current draft) renames ProtocolVersion server_version to - * legacy_version and locks the value of legacy_version to 0xfefd (DTLS 1.2) - */ - if (dtls_legacy_version != 0xfefd && dtls_legacy_version != 0xfeff) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server version")); - - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); - - return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - } - - cookie_len = *p++; - if ((ssl->in_msg + ssl->in_msglen) - p < cookie_len) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("cookie length does not match incoming message size")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - MBEDTLS_SSL_DEBUG_BUF(3, "cookie", p, cookie_len); - - mbedtls_free(ssl->handshake->cookie); - - ssl->handshake->cookie = mbedtls_calloc(1, cookie_len); - if (ssl->handshake->cookie == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc failed (%d bytes)", cookie_len)); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(ssl->handshake->cookie, p, cookie_len); - ssl->handshake->cookie_len = cookie_len; - - /* Start over at ClientHello */ - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - ret = mbedtls_ssl_reset_checksum(ssl); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret); - return ret; - } - - mbedtls_ssl_recv_flight_completed(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse hello verify request")); - - return 0; -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_server_hello(mbedtls_ssl_context *ssl) -{ - int ret, i; - size_t n; - size_t ext_len; - unsigned char *buf, *ext; - unsigned char comp; -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renegotiation_info_seen = 0; -#endif - int handshake_failure = 0; - const mbedtls_ssl_ciphersuite_t *suite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello")); - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - buf = ssl->in_msg; - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { - ssl->renego_records_seen++; - - if (ssl->conf->renego_max_records >= 0 && - ssl->renego_records_seen > ssl->conf->renego_max_records) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("renegotiation requested, but not honored by server")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - MBEDTLS_SSL_DEBUG_MSG(1, - ("non-handshake message during renegotiation")); - - ssl->keep_current_message = 1; - return MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - if (buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) { - MBEDTLS_SSL_DEBUG_MSG(2, ("received hello verify request")); - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello")); - return ssl_parse_hello_verify_request(ssl); - } else { - /* We made it through the verification process */ - mbedtls_free(ssl->handshake->cookie); - ssl->handshake->cookie = NULL; - ssl->handshake->cookie_len = 0; - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if (ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len(ssl) || - buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* - * 0 . 1 server_version - * 2 . 33 random (maybe including 4 bytes of Unix time) - * 34 . 34 session_id length = n - * 35 . 34+n session_id - * 35+n . 36+n cipher_suite - * 37+n . 37+n compression_method - * - * 38+n . 39+n extensions length (optional) - * 40+n . .. extensions - */ - buf += mbedtls_ssl_hs_hdr_len(ssl); - - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", buf, 2); - ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf, - ssl->conf->transport); - ssl->session_negotiate->tls_version = ssl->tls_version; - ssl->session_negotiate->endpoint = ssl->conf->endpoint; - - if (ssl->tls_version < ssl->conf->min_tls_version || - ssl->tls_version > ssl->conf->max_tls_version) { - MBEDTLS_SSL_DEBUG_MSG(1, - ( - "server version out of bounds - min: [0x%x], server: [0x%x], max: [0x%x]", - (unsigned) ssl->conf->min_tls_version, - (unsigned) ssl->tls_version, - (unsigned) ssl->conf->max_tls_version)); - - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); - - return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %lu", - ((unsigned long) buf[2] << 24) | - ((unsigned long) buf[3] << 16) | - ((unsigned long) buf[4] << 8) | - ((unsigned long) buf[5]))); - - memcpy(ssl->handshake->randbytes + 32, buf + 2, 32); - - n = buf[34]; - - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 2, 32); - - if (n > 32) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - if (ssl->in_hslen > mbedtls_ssl_hs_hdr_len(ssl) + 39 + n) { - ext_len = MBEDTLS_GET_UINT16_BE(buf, 38 + n); - - if ((ext_len > 0 && ext_len < 4) || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 40 + n + ext_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - } else if (ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl) + 38 + n) { - ext_len = 0; - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* ciphersuite (used later) */ - i = (int) MBEDTLS_GET_UINT16_BE(buf, n + 35); - - /* - * Read and check compression - */ - comp = buf[37 + n]; - - if (comp != MBEDTLS_SSL_COMPRESS_NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("server hello, bad compression: %d", comp)); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - /* - * Initialize update checksum functions - */ - ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(i); - if (ssl->handshake->ciphersuite_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("ciphersuite info for %04x not found", (unsigned int) i)); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - mbedtls_ssl_optimize_checksum(ssl, ssl->handshake->ciphersuite_info); - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n)); - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, session id", buf + 35, n); - - /* - * Check if the session can be resumed - */ - if (ssl->handshake->resume == 0 || n == 0 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif - ssl->session_negotiate->ciphersuite != i || - ssl->session_negotiate->id_len != n || - memcmp(ssl->session_negotiate->id, buf + 35, n) != 0) { - mbedtls_ssl_handshake_increment_state(ssl); - ssl->handshake->resume = 0; -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time(NULL); -#endif - ssl->session_negotiate->ciphersuite = i; - ssl->session_negotiate->id_len = n; - memcpy(ssl->session_negotiate->id, buf + 35, n); - } else { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC); - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed", - ssl->handshake->resume ? "a" : "no")); - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %04x", (unsigned) i)); - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: %d", - buf[37 + n])); - - /* - * Perform cipher suite validation in same way as in ssl_write_client_hello. - */ - i = 0; - while (1) { - if (ssl->conf->ciphersuite_list[i] == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - if (ssl->conf->ciphersuite_list[i++] == - ssl->session_negotiate->ciphersuite) { - break; - } - } - - suite_info = mbedtls_ssl_ciphersuite_from_id( - ssl->session_negotiate->ciphersuite); - if (mbedtls_ssl_validate_ciphersuite(ssl, suite_info, ssl->tls_version, - ssl->tls_version) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("server hello, chosen ciphersuite: %s", suite_info->name)); - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && - ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { - ssl->handshake->ecrs_enabled = 1; - } -#endif - - if (comp != MBEDTLS_SSL_COMPRESS_NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - ext = buf + 40 + n; - - MBEDTLS_SSL_DEBUG_MSG(2, - ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, - ext_len)); - - while (ext_len) { - unsigned int ext_id = MBEDTLS_GET_UINT16_BE(ext, 0); - unsigned int ext_size = MBEDTLS_GET_UINT16_BE(ext, 2); - - if (ext_size + 4 > ext_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - mbedtls_ssl_send_alert_message( - ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - switch (ext_id) { - case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: - MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension")); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiation_info_seen = 1; -#endif - - if ((ret = ssl_parse_renegotiation_info(ssl, ext + 4, - ext_size)) != 0) { - return ret; - } - - break; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG(3, - ("found max_fragment_length extension")); - - if ((ret = ssl_parse_max_fragment_length_ext(ssl, - ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - case MBEDTLS_TLS_EXT_CID: - MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension")); - - if ((ret = ssl_parse_cid_ext(ssl, - ext + 4, - ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt_then_mac extension")); - - if ((ret = ssl_parse_encrypt_then_mac_ext(ssl, - ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG(3, - ("found extended_master_secret extension")); - - if ((ret = ssl_parse_extended_ms_ext(ssl, - ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_TLS_EXT_SESSION_TICKET: - MBEDTLS_SSL_DEBUG_MSG(3, ("found session_ticket extension")); - - if ((ret = ssl_parse_session_ticket_ext(ssl, - ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG(3, - ("found supported_point_formats extension")); - - if ((ret = ssl_parse_supported_point_formats_ext(ssl, - ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: - MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake_kkpp extension")); - - if ((ret = ssl_parse_ecjpake_kkpp(ssl, - ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension")); - - if ((ret = ssl_parse_alpn_ext(ssl, ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - case MBEDTLS_TLS_EXT_USE_SRTP: - MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension")); - - if ((ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - - default: - MBEDTLS_SSL_DEBUG_MSG(3, - ("unknown extension found: %u (ignoring)", ext_id)); - } - - ext_len -= 4 + ext_size; - ext += 4 + ext_size; - - if (ext_len > 0 && ext_len < 4) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - } - - /* - * mbedtls_ssl_derive_keys() has to be called after the parsing of the - * extensions. It sets the transform data for the resumed session which in - * case of DTLS includes the server CID extracted from the CID extension. - */ - if (ssl->handshake->resume) { - if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - return ret; - } - } - - /* - * Renegotiation security checks - */ - if (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == - MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("legacy renegotiation, breaking off handshake")); - handshake_failure = 1; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && - renegotiation_info_seen == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("renegotiation_info extension missing (secure)")); - handshake_failure = 1; - } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == - MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) { - MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed")); - handshake_failure = 1; - } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - renegotiation_info_seen == 1) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("renegotiation_info extension present (legacy)")); - handshake_failure = 1; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - if (handshake_failure == 1) { - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello")); - - return 0; -} - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_server_dh_params(mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t dhm_actual_bitlen; - - /* - * Ephemeral DH parameters: - * - * struct { - * opaque dh_p<1..2^16-1>; - * opaque dh_g<1..2^16-1>; - * opaque dh_Ys<1..2^16-1>; - * } ServerDHParams; - */ - if ((ret = mbedtls_dhm_read_params(&ssl->handshake->dhm_ctx, - p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(2, ("mbedtls_dhm_read_params"), ret); - return ret; - } - - dhm_actual_bitlen = mbedtls_dhm_get_bitlen(&ssl->handshake->dhm_ctx); - if (dhm_actual_bitlen < ssl->conf->dhm_min_bitlen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u", - dhm_actual_bitlen, - ssl->conf->dhm_min_bitlen)); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P); - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G); - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY); - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end) -{ - uint16_t tls_id; - size_t ecpoint_len; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - psa_key_type_t key_type = PSA_KEY_TYPE_NONE; - size_t ec_bits = 0; - - /* - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - * - * 1 curve_type (must be "named_curve") - * 2..3 NamedCurve - * 4 ECPoint.len - * 5+ ECPoint contents - */ - if (end - *p < 4) { - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* First byte is curve_type; only named_curve is handled */ - if (*(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) { - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* Next two bytes are the namedcurve value */ - tls_id = MBEDTLS_GET_UINT16_BE(*p, 0); - *p += 2; - - /* Check it's a curve we offered */ - if (mbedtls_ssl_check_curve_tls_id(ssl, tls_id) != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, - ("bad server key exchange message (ECDHE curve): %u", - (unsigned) tls_id)); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* Convert EC's TLS ID to PSA key type. */ - if (mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, - &ec_bits) == PSA_ERROR_NOT_SUPPORTED) { - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - handshake->xxdh_psa_type = key_type; - handshake->xxdh_psa_bits = ec_bits; - - /* Keep a copy of the peer's public key */ - ecpoint_len = *(*p)++; - if ((size_t) (end - *p) < ecpoint_len) { - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) { - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - memcpy(handshake->xxdh_psa_peerkey, *p, ecpoint_len); - handshake->xxdh_psa_peerkey_len = ecpoint_len; - *p += ecpoint_len; - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#else -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_server_ecdh_params(const mbedtls_ssl_context *ssl) -{ - uint16_t tls_id; - mbedtls_ecp_group_id grp_id; -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - grp_id = ssl->handshake->ecdh_ctx.grp.id; -#else - grp_id = ssl->handshake->ecdh_ctx.grp_id; -#endif - - tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); - if (tls_id == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("ECDH curve: %s", - mbedtls_ssl_get_curve_name_from_tls_id(tls_id))); - - if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) { - return -1; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP); - - return 0; -} - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - /* - * Ephemeral ECDH parameters: - * - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ - if ((ret = mbedtls_ecdh_read_params(&ssl->handshake->ecdh_ctx, - (const unsigned char **) p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_read_params"), ret); -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; - } -#endif - return ret; - } - - if (ssl_check_server_ecdh_params(ssl) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("bad server key exchange message (ECDHE curve)")); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || \ - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \ - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_server_psk_hint(mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - uint16_t len; - ((void) ssl); - - /* - * PSK parameters: - * - * opaque psk_identity_hint<0..2^16-1>; - */ - if (end - (*p) < 2) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("bad server key exchange message (psk_identity_hint length)")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - len = MBEDTLS_GET_UINT16_BE(*p, 0); - *p += 2; - - if (end - (*p) < len) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("bad server key exchange message (psk_identity_hint length)")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* - * Note: we currently ignore the PSK identity hint, as we only allow one - * PSK to be provisioned on the client. This could be changed later if - * someone needs that feature. - */ - *p += len; - ret = 0; - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -/* - * Generate a pre-master secret and encrypt it with the server's RSA key - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl, - size_t offset, size_t *olen, - size_t pms_offset) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len_bytes = 2; - unsigned char *p = ssl->handshake->premaster + pms_offset; - mbedtls_pk_context *peer_pk; - - if (offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small for encrypted pms")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - /* - * Generate (part of) the pre-master as - * struct { - * ProtocolVersion client_version; - * opaque random[46]; - * } PreMasterSecret; - */ - mbedtls_ssl_write_version(p, ssl->conf->transport, - MBEDTLS_SSL_VERSION_TLS1_2); - - if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p + 2, 46)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "f_rng", ret); - return ret; - } - - ssl->handshake->pmslen = 48; - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (ssl->session_negotiate->peer_cert == NULL) { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* - * Now write it out, encrypted - */ - if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_RSA)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("certificate key type mismatch")); - return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - } - - if ((ret = mbedtls_pk_encrypt(peer_pk, - p, ssl->handshake->pmslen, - ssl->out_msg + offset + len_bytes, olen, - MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_encrypt", ret); - return ret; - } - - if (len_bytes == 2) { - MBEDTLS_PUT_UINT16_BE(*olen, ssl->out_msg, offset); - *olen += 2; - } - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it. */ - mbedtls_pk_free(peer_pk); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_pk_context *peer_pk; - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (ssl->session_negotiate->peer_cert == NULL) { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* This is a public key, so it can't be opaque, so can_do() is a good - * enough check to ensure pk_ec() is safe to use below. */ - if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_ECKEY)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable")); - return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - } - -#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) - const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk); -#endif /* !defined(MBEDTLS_PK_USE_PSA_EC_DATA) */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - uint16_t tls_id = 0; - psa_key_type_t key_type = PSA_KEY_TYPE_NONE; - mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(peer_pk); - - if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)")); - return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; - } - - tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); - if (tls_id == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not supported", - grp_id)); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - /* If the above conversion to TLS ID was fine, then also this one will be, - so there is no need to check the return value here */ - mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, - &ssl->handshake->xxdh_psa_bits); - - ssl->handshake->xxdh_psa_type = key_type; - - /* Store peer's public key in psa format. */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - memcpy(ssl->handshake->xxdh_psa_peerkey, peer_pk->pub_raw, peer_pk->pub_raw_len); - ssl->handshake->xxdh_psa_peerkey_len = peer_pk->pub_raw_len; - ret = 0; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - size_t olen = 0; - ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, - ssl->handshake->xxdh_psa_peerkey, - sizeof(ssl->handshake->xxdh_psa_peerkey)); - - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret); - return ret; - } - ssl->handshake->xxdh_psa_peerkey_len = olen; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -#else /* MBEDTLS_USE_PSA_CRYPTO */ - if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key, - MBEDTLS_ECDH_THEIRS)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret); - return ret; - } - - if (ssl_check_server_ecdh_params(ssl) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)")); - return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it, - * so that more RAM is available for upcoming expensive - * operations like ECDHE. */ - mbedtls_pk_free(peer_pk); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_signature_algorithm(mbedtls_ssl_context *ssl, - uint16_t sig_alg, - mbedtls_md_type_t *md_alg, - mbedtls_pk_type_t *pk_alg) -{ - if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(sig_alg, pk_alg, md_alg) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Server used unsupported value in SigAlg extension 0x%04x", - sig_alg)); - return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; - } - - /* - * mbedtls_ssl_get_pk_sigalg_and_md_alg_from_sig_alg() understands sig_alg code points across - * TLS versions. Make sure that the received sig_alg extension is valid in TLS 1.2. - */ - if (!mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Server used unsupported value in SigAlg extension 0x%04x", - sig_alg)); - return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; - } - - /* - * Check if the signature algorithm is acceptable - */ - if (!mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Server used SigAlg value 0x%04x that was not offered", sig_alg)); - return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("Server used SignatureAlgorithm %d", sig_alg & 0x00FF)); - MBEDTLS_SSL_DEBUG_MSG(2, ("Server used HashAlgorithm %d", sig_alg >> 8)); - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - unsigned char *p = NULL, *end = NULL; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server key exchange")); - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - ((void) p); - ((void) end); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { - if ((ret = ssl_get_ecdh_params_from_cert(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - ((void) p); - ((void) end); -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing) { - goto start_processing; - } -#endif - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - /* - * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server - * doesn't use a psk_identity_hint - */ - if (ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE) { - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { - /* Current message is probably either - * CertificateRequest or ServerHelloDone */ - ssl->keep_current_message = 1; - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG(1, - ("server key exchange message must not be skipped")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled) { - ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing; - } - -start_processing: -#endif - p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); - end = ssl->in_msg + ssl->in_hslen; - MBEDTLS_SSL_DEBUG_BUF(3, "server key exchange", p, (size_t) (end - p)); - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { - if (ssl_parse_server_psk_hint(ssl, &p, end) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - } /* FALLTHROUGH */ -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { - ; /* nothing more to do */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { - if (ssl_parse_server_dh_params(ssl, &p, end) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - } else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA) { - if (ssl_parse_server_ecdh_params(ssl, &p, end) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - } else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* - * The first 3 bytes are: - * [0] MBEDTLS_ECP_TLS_NAMED_CURVE - * [1, 2] elliptic curve's TLS ID - * - * However since we only support secp256r1 for now, we check only - * that TLS ID here - */ - uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE(p, 1); - uint16_t exp_tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( - MBEDTLS_ECP_DP_SECP256R1); - - if (exp_tls_id == 0) { - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - if ((*p != MBEDTLS_ECP_TLS_NAMED_CURVE) || - (read_tls_id != exp_tls_id)) { - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - p += 3; - - if ((ret = mbedtls_psa_ecjpake_read_round( - &ssl->handshake->psa_pake_ctx, p, end - p, - MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } -#else - ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx, - p, end - p); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) { - size_t sig_len, hashlen; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); - size_t params_len = (size_t) (p - params); - void *rs_ctx = NULL; - - mbedtls_pk_context *peer_pk; - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (ssl->session_negotiate->peer_cert == NULL) { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* - * Handle the digitally-signed structure - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - uint16_t sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); - if (ssl_parse_signature_algorithm(ssl, sig_alg, &md_alg, &pk_alg) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - p += 2; - - if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - /* - * Read signature - */ - - if (p > end - 2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - sig_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - if (p != end - sig_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "signature", p, sig_len); - - /* - * Compute the hash that has been signed - */ - if (md_alg != MBEDTLS_MD_NONE) { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen, - params, params_len, - md_alg); - if (ret != 0) { - return ret; - } - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen); - - /* - * Verify signature - */ - if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - } - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled) { - rs_ctx = &ssl->handshake->ecrs_ctx.pk; - } -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if (pk_alg == MBEDTLS_PK_RSASSA_PSS) { - mbedtls_pk_rsassa_pss_options rsassa_pss_options; - rsassa_pss_options.mgf1_hash_id = md_alg; - rsassa_pss_options.expected_salt_len = - mbedtls_md_get_size_from_type(md_alg); - if (rsassa_pss_options.expected_salt_len == 0) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ret = mbedtls_pk_verify_ext(pk_alg, &rsassa_pss_options, - peer_pk, - md_alg, hash, hashlen, - p, sig_len); - } else -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - ret = mbedtls_pk_verify_restartable(peer_pk, - md_alg, hash, hashlen, p, sig_len, rs_ctx); - - if (ret != 0) { - int send_alert_msg = 1; -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - send_alert_msg = (ret != MBEDTLS_ERR_ECP_IN_PROGRESS); -#endif - if (send_alert_msg) { - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR); - } - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret); -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; - } -#endif - return ret; - } - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it, - * so that more RAM is available for upcoming expensive - * operations like ECDHE. */ - mbedtls_pk_free(peer_pk); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - } -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ - -exit: - mbedtls_ssl_handshake_increment_state(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server key exchange")); - - return 0; -} - -#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request")); - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} -#else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - size_t n = 0; - size_t cert_type_len = 0, dn_len = 0; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - size_t sig_alg_len; -#if defined(MBEDTLS_DEBUG_C) - unsigned char *sig_alg; - unsigned char *dn; -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request")); - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - mbedtls_ssl_handshake_increment_state(ssl); - ssl->handshake->client_auth = - (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST); - - MBEDTLS_SSL_DEBUG_MSG(3, ("got %s certificate request", - ssl->handshake->client_auth ? "a" : "no")); - - if (ssl->handshake->client_auth == 0) { - /* Current message is probably the ServerHelloDone */ - ssl->keep_current_message = 1; - goto exit; - } - - /* - * struct { - * ClientCertificateType certificate_types<1..2^8-1>; - * SignatureAndHashAlgorithm - * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only - * DistinguishedName certificate_authorities<0..2^16-1>; - * } CertificateRequest; - * - * Since we only support a single certificate on clients, let's just - * ignore all the information that's supposed to help us pick a - * certificate. - * - * We could check that our certificate matches the request, and bail out - * if it doesn't, but it's simpler to just send the certificate anyway, - * and give the server the opportunity to decide if it should terminate - * the connection when it doesn't like our certificate. - * - * Same goes for the hash in TLS 1.2's signature_algorithms: at this - * point we only have one hash available (see comments in - * write_certificate_verify), so let's just use what we have. - * - * However, we still minimally parse the message to check it is at least - * superficially sane. - */ - buf = ssl->in_msg; - - /* certificate_types */ - if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - cert_type_len = buf[mbedtls_ssl_hs_hdr_len(ssl)]; - n = cert_type_len; - - /* - * In the subsequent code there are two paths that read from buf: - * * the length of the signature algorithms field (if minor version of - * SSL is 3), - * * distinguished name length otherwise. - * Both reach at most the index: - * ...hdr_len + 2 + n, - * therefore the buffer length at this point must be greater than that - * regardless of the actual code path. - */ - if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 2 + n) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* supported_signature_algorithms */ - sig_alg_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n); - - /* - * The furthest access in buf is in the loop few lines below: - * sig_alg[i + 1], - * where: - * sig_alg = buf + ...hdr_len + 3 + n, - * max(i) = sig_alg_len - 1. - * Therefore the furthest access is: - * buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1], - * which reduces to: - * buf[...hdr_len + 3 + n + sig_alg_len], - * which is one less than we need the buf to be. - */ - if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 3 + n + sig_alg_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - -#if defined(MBEDTLS_DEBUG_C) - sig_alg = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n; - for (size_t i = 0; i < sig_alg_len; i += 2) { - MBEDTLS_SSL_DEBUG_MSG(3, - ("Supported Signature Algorithm found: %02x %02x", - sig_alg[i], sig_alg[i + 1])); - } -#endif - - n += 2 + sig_alg_len; - - /* certificate_authorities */ - dn_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n); - - n += dn_len; - if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 3 + n) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - -#if defined(MBEDTLS_DEBUG_C) - dn = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n - dn_len; - for (size_t i = 0, dni_len = 0; i < dn_len; i += 2 + dni_len) { - unsigned char *p = dn + i + 2; - mbedtls_x509_name name; - size_t asn1_len; - char s[MBEDTLS_X509_MAX_DN_NAME_SIZE]; - memset(&name, 0, sizeof(name)); - dni_len = MBEDTLS_GET_UINT16_BE(dn + i, 0); - if (dni_len > dn_len - i - 2 || - mbedtls_asn1_get_tag(&p, p + dni_len, &asn1_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0 || - mbedtls_x509_get_name(&p, p + asn1_len, &name) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - MBEDTLS_SSL_DEBUG_MSG(3, - ("DN hint: %.*s", - mbedtls_x509_dn_gets(s, sizeof(s), &name), s)); - mbedtls_asn1_free_named_data_list_shallow(name.next); - } -#endif - -exit: - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request")); - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello done")); - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) || - ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - mbedtls_ssl_handshake_increment_state(ssl); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - mbedtls_ssl_recv_flight_completed(ssl); - } -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello done")); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - size_t header_len; - size_t content_len; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write client key exchange")); - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) { - /* - * DHM key exchange -- send G^X mod P - */ - content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx); - - MBEDTLS_PUT_UINT16_BE(content_len, ssl->out_msg, 4); - header_len = 6; - - ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx, - (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), - &ssl->out_msg[header_len], content_len, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X); - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX); - - if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); - } else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t key_attributes; - - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - header_len = 4; - - MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based ECDH computation.")); - - /* - * Generate EC private key for ECDHE exchange. - */ - - /* The master secret is obtained from the shared ECDH secret by - * applying the TLS 1.2 PRF with a specific salt and label. While - * the PSA Crypto API encourages combining key agreement schemes - * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not - * yet support the provisioning of salt + label to the KDF. - * For the time being, we therefore need to split the computation - * of the ECDH secret and the application of the TLS 1.2 PRF. */ - key_attributes = psa_key_attributes_init(); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); - psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); - - /* Generate ECDH private key. */ - status = psa_generate_key(&key_attributes, - &handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - /* Export the public part of the ECDH private key from PSA. - * The export format is an ECPoint structure as expected by TLS, - * but we just need to add a length byte before that. */ - unsigned char *own_pubkey = ssl->out_msg + header_len + 1; - unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t own_pubkey_max_len = (size_t) (end - own_pubkey); - size_t own_pubkey_len; - - status = psa_export_public_key(handshake->xxdh_psa_privkey, - own_pubkey, own_pubkey_max_len, - &own_pubkey_len); - if (status != PSA_SUCCESS) { - psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } - - ssl->out_msg[header_len] = (unsigned char) own_pubkey_len; - content_len = own_pubkey_len + 1; - - /* The ECDH secret is the premaster secret used for key derivation. */ - - /* Compute ECDH shared secret. */ - status = psa_raw_key_agreement(PSA_ALG_ECDH, - handshake->xxdh_psa_privkey, - handshake->xxdh_psa_peerkey, - handshake->xxdh_psa_peerkey_len, - ssl->handshake->premaster, - sizeof(ssl->handshake->premaster), - &ssl->handshake->pmslen); - - destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - - if (status != PSA_SUCCESS || destruction_status != PSA_SUCCESS) { - return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; - } -#else - /* - * ECDH key exchange -- send client public value - */ - header_len = 4; - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled) { - if (ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret) { - goto ecdh_calc_secret; - } - - mbedtls_ecdh_enable_restart(&ssl->handshake->ecdh_ctx); - } -#endif - - ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx, - &content_len, - &ssl->out_msg[header_len], 1000, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret); -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; - } -#endif - return ret; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q); - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled) { - ssl->handshake->ecrs_n = content_len; - ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; - } - -ecdh_calc_secret: - if (ssl->handshake->ecrs_enabled) { - content_len = ssl->handshake->ecrs_n; - } -#endif - if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret); -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; - } -#endif - return ret; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t key_attributes; - - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* - * opaque psk_identity<0..2^16-1>; - */ - if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) { - /* We don't offer PSK suites if we don't have a PSK, - * and we check that the server's choice is among the - * ciphersuites we offered, so this should never happen. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* uint16 to store content length */ - const size_t content_len_size = 2; - - header_len = 4; - - if (header_len + content_len_size + ssl->conf->psk_identity_len - > MBEDTLS_SSL_OUT_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("psk identity too long or SSL buffer too short")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - unsigned char *p = ssl->out_msg + header_len; - - *p++ = MBEDTLS_BYTE_1(ssl->conf->psk_identity_len); - *p++ = MBEDTLS_BYTE_0(ssl->conf->psk_identity_len); - header_len += content_len_size; - - memcpy(p, ssl->conf->psk_identity, - ssl->conf->psk_identity_len); - p += ssl->conf->psk_identity_len; - - header_len += ssl->conf->psk_identity_len; - - MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based ECDH computation.")); - - /* - * Generate EC private key for ECDHE exchange. - */ - - /* The master secret is obtained from the shared ECDH secret by - * applying the TLS 1.2 PRF with a specific salt and label. While - * the PSA Crypto API encourages combining key agreement schemes - * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not - * yet support the provisioning of salt + label to the KDF. - * For the time being, we therefore need to split the computation - * of the ECDH secret and the application of the TLS 1.2 PRF. */ - key_attributes = psa_key_attributes_init(); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); - psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); - - /* Generate ECDH private key. */ - status = psa_generate_key(&key_attributes, - &handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } - - /* Export the public part of the ECDH private key from PSA. - * The export format is an ECPoint structure as expected by TLS, - * but we just need to add a length byte before that. */ - unsigned char *own_pubkey = p + 1; - unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t own_pubkey_max_len = (size_t) (end - own_pubkey); - size_t own_pubkey_len = 0; - - status = psa_export_public_key(handshake->xxdh_psa_privkey, - own_pubkey, own_pubkey_max_len, - &own_pubkey_len); - if (status != PSA_SUCCESS) { - psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return PSA_TO_MBEDTLS_ERR(status); - } - - *p = (unsigned char) own_pubkey_len; - content_len = own_pubkey_len + 1; - - /* As RFC 5489 section 2, the premaster secret is formed as follows: - * - a uint16 containing the length (in octets) of the ECDH computation - * - the octet string produced by the ECDH computation - * - a uint16 containing the length (in octets) of the PSK - * - the PSK itself - */ - unsigned char *pms = ssl->handshake->premaster; - const unsigned char * const pms_end = pms + - sizeof(ssl->handshake->premaster); - /* uint16 to store length (in octets) of the ECDH computation */ - const size_t zlen_size = 2; - size_t zlen = 0; - - /* Perform ECDH computation after the uint16 reserved for the length */ - status = psa_raw_key_agreement(PSA_ALG_ECDH, - handshake->xxdh_psa_privkey, - handshake->xxdh_psa_peerkey, - handshake->xxdh_psa_peerkey_len, - pms + zlen_size, - pms_end - (pms + zlen_size), - &zlen); - - destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } else if (destruction_status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(destruction_status); - } - - /* Write the ECDH computation length before the ECDH computation */ - MBEDTLS_PUT_UINT16_BE(zlen, pms, 0); - pms += zlen_size + zlen; - } else -#endif /* MBEDTLS_USE_PSA_CRYPTO && - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_psk(ciphersuite_info)) { - /* - * opaque psk_identity<0..2^16-1>; - */ - if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) { - /* We don't offer PSK suites if we don't have a PSK, - * and we check that the server's choice is among the - * ciphersuites we offered, so this should never happen. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - header_len = 4; - content_len = ssl->conf->psk_identity_len; - - if (header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("psk identity too long or SSL buffer too short")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len); - ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len); - - memcpy(ssl->out_msg + header_len, - ssl->conf->psk_identity, - ssl->conf->psk_identity_len); - header_len += ssl->conf->psk_identity_len; - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) { - content_len = 0; - } else -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { - if ((ret = ssl_write_encrypted_pms(ssl, header_len, - &content_len, 2)) != 0) { - return ret; - } - } else -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { - /* - * ClientDiffieHellmanPublic public (DHM send G^X mod P) - */ - content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx); - - if (header_len + 2 + content_len > - MBEDTLS_SSL_OUT_CONTENT_LEN) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("psk identity or DHM size too long or SSL buffer too short")); - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len); - ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len); - - ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx, - (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), - &ssl->out_msg[header_len], content_len, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret); - return ret; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - unsigned char *pms = ssl->handshake->premaster; - unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster); - size_t pms_len; - - /* Write length only when we know the actual value */ - if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, - pms + 2, pms_end - (pms + 2), &pms_len, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); - return ret; - } - MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0); - pms += 2 + pms_len; - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); -#endif - } else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { - /* - * ClientECDiffieHellmanPublic public; - */ - ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx, - &content_len, - &ssl->out_msg[header_len], - MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q); - } else -#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, - (mbedtls_key_exchange_type_t) ciphersuite_info-> - key_exchange)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "mbedtls_ssl_psk_derive_premaster", ret); - return ret; - } -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { - header_len = 4; - if ((ret = ssl_write_encrypted_pms(ssl, header_len, - &content_len, 0)) != 0) { - return ret; - } - } else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { - header_len = 4; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - unsigned char *out_p = ssl->out_msg + header_len; - unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - - header_len; - ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, - out_p, end_p - out_p, &content_len, - MBEDTLS_ECJPAKE_ROUND_TWO); - if (ret != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); - return ret; - } -#else - ret = mbedtls_ecjpake_write_round_two(&ssl->handshake->ecjpake_ctx, - ssl->out_msg + header_len, - MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, - &content_len, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret); - return ret; - } - - ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - { - ((void) ciphersuite_info); - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ssl->out_msglen = header_len + content_len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; - - mbedtls_ssl_handshake_increment_state(ssl); - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client key exchange")); - - return 0; -} - -#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify")); - - if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); - return ret; - } - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} -#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - size_t n = 0, offset = 0; - unsigned char hash[48]; - unsigned char *hash_start = hash; - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - size_t hashlen; - void *rs_ctx = NULL; -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf); -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf); -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify")); - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign) { - goto sign; - } -#endif - - if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); - return ret; - } - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - if (ssl->handshake->client_auth == 0 || - mbedtls_ssl_own_cert(ssl) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - if (mbedtls_ssl_own_key(ssl) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key for certificate")); - return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; - } - - /* - * Make a signature of the handshake digests - */ -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled) { - ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign; - } - -sign: -#endif - - ret = ssl->handshake->calc_verify(ssl, hash, &hashlen); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret); - return ret; - } - - /* - * digitally-signed struct { - * opaque handshake_messages[handshake_messages_length]; - * }; - * - * Taking shortcut here. We assume that the server always allows the - * PRF Hash function and has sent it in the allowed signature - * algorithms list received in the Certificate Request message. - * - * Until we encounter a server that does not, we will take this - * shortcut. - * - * Reason: Otherwise we should have running hashes for SHA512 and - * SHA224 in order to satisfy 'weird' needs from the server - * side. - */ - if (ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384) { - md_alg = MBEDTLS_MD_SHA384; - ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; - } else { - md_alg = MBEDTLS_MD_SHA256; - ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256; - } - ssl->out_msg[5] = mbedtls_ssl_sig_from_pk(mbedtls_ssl_own_key(ssl)); - - /* Info from md_alg will be used instead */ - hashlen = 0; - offset = 2; - -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ssl->handshake->ecrs_enabled) { - rs_ctx = &ssl->handshake->ecrs_ctx.pk; - } -#endif - - if ((ret = mbedtls_pk_sign_restartable(mbedtls_ssl_own_key(ssl), - md_alg, hash_start, hashlen, - ssl->out_msg + 6 + offset, - out_buf_len - 6 - offset, - &n, - ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret); -#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) - if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; - } -#endif - return ret; - } - - MBEDTLS_PUT_UINT16_BE(n, ssl->out_msg, offset + 4); - - ssl->out_msglen = 6 + n + offset; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; - - mbedtls_ssl_handshake_increment_state(ssl); - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate verify")); - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint32_t lifetime; - size_t ticket_len; - unsigned char *ticket; - const unsigned char *msg; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket")); - - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - /* - * struct { - * uint32 ticket_lifetime_hint; - * opaque ticket<0..2^16-1>; - * } NewSessionTicket; - * - * 0 . 3 ticket_lifetime_hint - * 4 . 5 ticket_len (n) - * 6 . 5+n ticket content - */ - if (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET || - ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); - - lifetime = MBEDTLS_GET_UINT32_BE(msg, 0); - - ticket_len = MBEDTLS_GET_UINT16_BE(msg, 4); - - if (ticket_len + 6 + mbedtls_ssl_hs_hdr_len(ssl) != ssl->in_hslen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len)); - - /* We're not waiting for a NewSessionTicket message any more */ - ssl->handshake->new_session_ticket = 0; - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC); - - /* - * Zero-length ticket means the server changed his mind and doesn't want - * to send a ticket after all, so just forget it - */ - if (ticket_len == 0) { - return 0; - } - - if (ssl->session != NULL && ssl->session->ticket != NULL) { - mbedtls_zeroize_and_free(ssl->session->ticket, - ssl->session->ticket_len); - ssl->session->ticket = NULL; - ssl->session->ticket_len = 0; - } - - mbedtls_zeroize_and_free(ssl->session_negotiate->ticket, - ssl->session_negotiate->ticket_len); - ssl->session_negotiate->ticket = NULL; - ssl->session_negotiate->ticket_len = 0; - - if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(ticket, msg + 6, ticket_len); - - ssl->session_negotiate->ticket = ticket; - ssl->session_negotiate->ticket_len = ticket_len; - ssl->session_negotiate->ticket_lifetime = lifetime; - - /* - * RFC 5077 section 3.4: - * "If the client receives a session ticket from the server, then it - * discards any Session ID that was sent in the ServerHello." - */ - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket in use, discarding session id")); - ssl->session_negotiate->id_len = 0; - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket")); - - return 0; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -/* - * SSL handshake -- client side -- single step - */ -int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl) -{ - int ret = 0; - - /* Change state now, so that it is right in mbedtls_ssl_read_record(), used - * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && - ssl->handshake->new_session_ticket != 0) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_NEW_SESSION_TICKET); - } -#endif - - switch (ssl->state) { - case MBEDTLS_SSL_HELLO_REQUEST: - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - break; - - /* - * ==> ClientHello - */ - case MBEDTLS_SSL_CLIENT_HELLO: - ret = mbedtls_ssl_write_client_hello(ssl); - break; - - /* - * <== ServerHello - * Certificate - * ( ServerKeyExchange ) - * ( CertificateRequest ) - * ServerHelloDone - */ - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_parse_server_hello(ssl); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = mbedtls_ssl_parse_certificate(ssl); - break; - - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - ret = ssl_parse_server_key_exchange(ssl); - break; - - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_parse_certificate_request(ssl); - break; - - case MBEDTLS_SSL_SERVER_HELLO_DONE: - ret = ssl_parse_server_hello_done(ssl); - break; - - /* - * ==> ( Certificate/Alert ) - * ClientKeyExchange - * ( CertificateVerify ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = mbedtls_ssl_write_certificate(ssl); - break; - - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_write_client_key_exchange(ssl); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_write_certificate_verify(ssl); - break; - - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_write_change_cipher_spec(ssl); - break; - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = mbedtls_ssl_write_finished(ssl); - break; - - /* - * <== ( NewSessionTicket ) - * ChangeCipherSpec - * Finished - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_NEW_SESSION_TICKET: - ret = ssl_parse_new_session_ticket(ssl); - break; -#endif - - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_parse_change_cipher_spec(ssl); - break; - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = mbedtls_ssl_parse_finished(ssl); - break; - - case MBEDTLS_SSL_FLUSH_BUFFERS: - MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup(ssl); - break; - - default: - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - return ret; -} - -#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_2 */ diff --git a/vendor/mbedtls/library/ssl_tls12_server.c b/vendor/mbedtls/library/ssl_tls12_server.c deleted file mode 100644 index d2ee9a076..000000000 --- a/vendor/mbedtls/library/ssl_tls12_server.c +++ /dev/null @@ -1,4307 +0,0 @@ -/* - * TLS server-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2) - -#include "mbedtls/platform.h" - -#include "mbedtls/ssl.h" -#include "ssl_misc.h" -#include "debug_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/platform_util.h" -#include "constant_time_internal.h" -#include "mbedtls/constant_time.h" - -#include - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) -#endif -#endif - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -int mbedtls_ssl_set_client_transport_id(mbedtls_ssl_context *ssl, - const unsigned char *info, - size_t ilen) -{ - if (ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - mbedtls_free(ssl->cli_id); - - if ((ssl->cli_id = mbedtls_calloc(1, ilen)) == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(ssl->cli_id, info, ilen); - ssl->cli_id_len = ilen; - - return 0; -} - -void mbedtls_ssl_conf_dtls_cookies(mbedtls_ssl_config *conf, - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie) -{ - conf->f_cookie_write = f_cookie_write; - conf->f_cookie_check = f_cookie_check; - conf->p_cookie = p_cookie; -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_conf_has_psk_or_cb(mbedtls_ssl_config const *conf) -{ - if (conf->f_psk != NULL) { - return 1; - } - - if (conf->psk_identity_len == 0 || conf->psk_identity == NULL) { - return 0; - } - - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) { - return 1; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (conf->psk != NULL && conf->psk_len != 0) { - return 1; - } - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - /* Check verify-data in constant-time. The length OTOH is no secret */ - if (len != 1 + ssl->verify_data_len || - buf[0] != ssl->verify_data_len || - mbedtls_ct_memcmp(buf + 1, ssl->peer_verify_data, - ssl->verify_data_len) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - } else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - if (len != 1 || buf[0] != 0x0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("non-zero length renegotiation info")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - } - - return 0; -} - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -/* - * Function for parsing a supported groups (TLS 1.3) or supported elliptic - * curves (TLS 1.2) extension. - * - * The "extension_data" field of a supported groups extension contains a - * "NamedGroupList" value (TLS 1.3 RFC8446): - * enum { - * secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019), - * x25519(0x001D), x448(0x001E), - * ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102), - * ffdhe6144(0x0103), ffdhe8192(0x0104), - * ffdhe_private_use(0x01FC..0x01FF), - * ecdhe_private_use(0xFE00..0xFEFF), - * (0xFFFF) - * } NamedGroup; - * struct { - * NamedGroup named_group_list<2..2^16-1>; - * } NamedGroupList; - * - * The "extension_data" field of a supported elliptic curves extension contains - * a "NamedCurveList" value (TLS 1.2 RFC 8422): - * enum { - * deprecated(1..22), - * secp256r1 (23), secp384r1 (24), secp521r1 (25), - * x25519(29), x448(30), - * reserved (0xFE00..0xFEFF), - * deprecated(0xFF01..0xFF02), - * (0xFFFF) - * } NamedCurve; - * struct { - * NamedCurve named_curve_list<2..2^16-1> - * } NamedCurveList; - * - * The TLS 1.3 supported groups extension was defined to be a compatible - * generalization of the TLS 1.2 supported elliptic curves extension. They both - * share the same extension identifier. - * - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_supported_groups_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - size_t list_size, our_size; - const unsigned char *p; - uint16_t *curves_tls_id; - - if (len < 2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - list_size = MBEDTLS_GET_UINT16_BE(buf, 0); - if (list_size + 2 != len || - list_size % 2 != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Should never happen unless client duplicates the extension */ - if (ssl->handshake->curves_tls_id != NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - /* Don't allow our peer to make us allocate too much memory, - * and leave room for a final 0 */ - our_size = list_size / 2 + 1; - if (our_size > MBEDTLS_ECP_DP_MAX) { - our_size = MBEDTLS_ECP_DP_MAX; - } - - if ((curves_tls_id = mbedtls_calloc(our_size, - sizeof(*curves_tls_id))) == NULL) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - ssl->handshake->curves_tls_id = curves_tls_id; - - p = buf + 2; - while (list_size > 0 && our_size > 1) { - uint16_t curr_tls_id = MBEDTLS_GET_UINT16_BE(p, 0); - - if (mbedtls_ssl_get_ecp_group_id_from_tls_id(curr_tls_id) != - MBEDTLS_ECP_DP_NONE) { - *curves_tls_id++ = curr_tls_id; - our_size--; - } - - list_size -= 2; - p += 2; - } - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_supported_point_formats(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - size_t list_size; - const unsigned char *p; - - if (len == 0 || (size_t) (buf[0] + 1) != len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - list_size = buf[0]; - - p = buf + 1; - while (list_size > 0) { - if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || - p[0] == MBEDTLS_ECP_PF_COMPRESSED) { -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) - ssl->handshake->ecdh_ctx.point_format = p[0]; -#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */ -#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx, - p[0]); -#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0])); - return 0; - } - - list_size--; - p++; - } - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (ssl->handshake->psa_pake_ctx_is_ok != 1) -#else - if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - { - MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension")); - return 0; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((ret = mbedtls_psa_ecjpake_read_round( - &ssl->handshake->psa_pake_ctx, buf, len, - MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - - return ret; - } -#else - if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx, - buf, len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* Only mark the extension as OK when we're sure it is */ - ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - if (len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - ssl->session_negotiate->mfl_code = buf[0]; - - return 0; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - size_t peer_cid_len; - - /* CID extension only makes sense in DTLS */ - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - /* - * struct { - * opaque cid<0..2^8-1>; - * } ConnectionId; - */ - - if (len < 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - peer_cid_len = *buf++; - len--; - - if (len != peer_cid_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Ignore CID if the user has disabled its use. */ - if (ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { - /* Leave ssl->handshake->cid_in_use in its default - * value of MBEDTLS_SSL_CID_DISABLED. */ - MBEDTLS_SSL_DEBUG_MSG(3, ("Client sent CID extension, but CID disabled")); - return 0; - } - - if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; - ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; - memcpy(ssl->handshake->peer_cid, buf, peer_cid_len); - - MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated")); - MBEDTLS_SSL_DEBUG_BUF(3, "Client CID", buf, peer_cid_len); - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - if (len != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - ((void) buf); - - if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED) { - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; - } - - return 0; -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - if (len != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - ((void) buf); - - if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) { - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; - } - - return 0; -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_session session; - - mbedtls_ssl_session_init(&session); - - if (ssl->conf->f_ticket_parse == NULL || - ssl->conf->f_ticket_write == NULL) { - return 0; - } - - /* Remember the client asked us to send a new ticket */ - ssl->handshake->new_session_ticket = 1; - - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, len)); - - if (len == 0) { - return 0; - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket rejected: renegotiating")); - return 0; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - /* - * Failures are ok: just ignore the ticket and proceed. - */ - if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, &session, - buf, len)) != 0) { - mbedtls_ssl_session_free(&session); - - if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic")); - } else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired")); - } else { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_parse", ret); - } - - return 0; - } - - /* - * Keep the session ID sent by the client, since we MUST send it back to - * inform them we're accepting the ticket (RFC 5077 section 3.4) - */ - session.id_len = ssl->session_negotiate->id_len; - memcpy(&session.id, ssl->session_negotiate->id, session.id_len); - - mbedtls_ssl_session_free(ssl->session_negotiate); - memcpy(ssl->session_negotiate, &session, sizeof(mbedtls_ssl_session)); - - /* Zeroize instead of free as we copied the content */ - mbedtls_platform_zeroize(&session, sizeof(mbedtls_ssl_session)); - - MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from ticket")); - - ssl->handshake->resume = 1; - - /* Don't send a new ticket after all, this one is OK */ - ssl->handshake->new_session_ticket = 0; - - return 0; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len) -{ - mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET; - size_t i, j; - size_t profile_length; - uint16_t mki_length; - /*! 2 bytes for profile length and 1 byte for mki len */ - const size_t size_of_lengths = 3; - - /* If use_srtp is not configured, just ignore the extension */ - if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (ssl->conf->dtls_srtp_profile_list == NULL) || - (ssl->conf->dtls_srtp_profile_list_len == 0)) { - return 0; - } - - /* RFC5764 section 4.1.1 - * uint8 SRTPProtectionProfile[2]; - * - * struct { - * SRTPProtectionProfiles SRTPProtectionProfiles; - * opaque srtp_mki<0..255>; - * } UseSRTPData; - - * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; - */ - - /* - * Min length is 5: at least one protection profile(2 bytes) - * and length(2 bytes) + srtp_mki length(1 byte) - * Check here that we have at least 2 bytes of protection profiles length - * and one of srtp_mki length - */ - if (len < size_of_lengths) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; - - /* first 2 bytes are protection profile length(in bytes) */ - profile_length = (buf[0] << 8) | buf[1]; - buf += 2; - - /* The profile length cannot be bigger than input buffer size - lengths fields */ - if (profile_length > len - size_of_lengths || - profile_length % 2 != 0) { /* profiles are 2 bytes long, so the length must be even */ - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - /* - * parse the extension list values are defined in - * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml - */ - for (j = 0; j < profile_length; j += 2) { - uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1]; - client_protection = mbedtls_ssl_check_srtp_profile_value(protection_profile_value); - - if (client_protection != MBEDTLS_TLS_SRTP_UNSET) { - MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s", - mbedtls_ssl_get_srtp_profile_as_string( - client_protection))); - } else { - continue; - } - /* check if suggested profile is in our list */ - for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) { - if (client_protection == ssl->conf->dtls_srtp_profile_list[i]) { - ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; - MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s", - mbedtls_ssl_get_srtp_profile_as_string( - client_protection))); - break; - } - } - if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET) { - break; - } - } - buf += profile_length; /* buf points to the mki length */ - mki_length = *buf; - buf++; - - if (mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH || - mki_length + profile_length + size_of_lengths != len) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Parse the mki only if present and mki is supported locally */ - if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED && - mki_length > 0) { - ssl->dtls_srtp_info.mki_len = mki_length; - - memcpy(ssl->dtls_srtp_info.mki_value, buf, mki_length); - - MBEDTLS_SSL_DEBUG_BUF(3, "using mki", ssl->dtls_srtp_info.mki_value, - ssl->dtls_srtp_info.mki_len); - } - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -/* - * Auxiliary functions for ServerHello parsing and related actions - */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/* - * Return 0 if the given key uses one of the acceptable curves, -1 otherwise - */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_check_key_curve(mbedtls_pk_context *pk, - uint16_t *curves_tls_id) -{ - uint16_t *curr_tls_id = curves_tls_id; - mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk); - mbedtls_ecp_group_id curr_grp_id; - - while (*curr_tls_id != 0) { - curr_grp_id = mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id); - if (curr_grp_id == grp_id) { - return 0; - } - curr_tls_id++; - } - - return -1; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED */ - -/* - * Try picking a certificate for this ciphersuite, - * return 0 on success and -1 on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_pick_cert(mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info) -{ - mbedtls_ssl_key_cert *cur, *list; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_algorithm_t pk_alg = - mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(ciphersuite_info); - psa_key_usage_t pk_usage = - mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(ciphersuite_info); -#else - mbedtls_pk_type_t pk_alg = - mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - uint32_t flags; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (ssl->handshake->sni_key_cert != NULL) { - list = ssl->handshake->sni_key_cert; - } else -#endif - list = ssl->conf->key_cert; - - int pk_alg_is_none = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - pk_alg_is_none = (pk_alg == PSA_ALG_NONE); -#else - pk_alg_is_none = (pk_alg == MBEDTLS_PK_NONE); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (pk_alg_is_none) { - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite requires certificate")); - - if (list == NULL) { - MBEDTLS_SSL_DEBUG_MSG(3, ("server has no certificate")); - return -1; - } - - for (cur = list; cur != NULL; cur = cur->next) { - flags = 0; - MBEDTLS_SSL_DEBUG_CRT(3, "candidate certificate chain, certificate", - cur->cert); - - int key_type_matches = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - key_type_matches = ((ssl->conf->f_async_sign_start != NULL || - ssl->conf->f_async_decrypt_start != NULL || - mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage)) && - mbedtls_pk_can_do_ext(&cur->cert->pk, pk_alg, pk_usage)); -#else - key_type_matches = ( - mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage)); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ -#else - key_type_matches = mbedtls_pk_can_do(&cur->cert->pk, pk_alg); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if (!key_type_matches) { - MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: key type")); - continue; - } - - /* - * This avoids sending the client a cert it'll reject based on - * keyUsage or other extensions. - * - * It also allows the user to provision different certificates for - * different uses based on keyUsage, eg if they want to avoid signing - * and decrypting with the same RSA key. - */ - if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_VERSION_TLS1_2, - &flags) != 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: " - "(extended) key usage extension")); - continue; - } - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - if (pk_alg == MBEDTLS_PK_ECDSA && - ssl_check_key_curve(&cur->cert->pk, - ssl->handshake->curves_tls_id) != 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: elliptic curve")); - continue; - } -#endif - - /* If we get there, we got a winner */ - break; - } - - /* Do not update ssl->handshake->key_cert unless there is a match */ - if (cur != NULL) { - ssl->handshake->key_cert = cur; - MBEDTLS_SSL_DEBUG_CRT(3, "selected certificate chain, certificate", - ssl->handshake->key_cert->cert); - return 0; - } - - return -1; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* - * Check if a given ciphersuite is suitable for use with our config/keys/etc - * Sets ciphersuite_info only if the suite matches. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_ciphersuite_match(mbedtls_ssl_context *ssl, int suite_id, - const mbedtls_ssl_ciphersuite_t **ciphersuite_info) -{ - const mbedtls_ssl_ciphersuite_t *suite_info; - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - mbedtls_pk_type_t sig_type; -#endif - - suite_info = mbedtls_ssl_ciphersuite_from_id(suite_id); - if (suite_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("trying ciphersuite: %#04x (%s)", - (unsigned int) suite_id, suite_info->name)); - - if (suite_info->min_tls_version > ssl->tls_version || - suite_info->max_tls_version < ssl->tls_version) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: version")); - return 0; - } - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && - (ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK) == 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: ecjpake " - "not configured or ext missing")); - return 0; - } -#endif - - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_ec(suite_info) && - (ssl->handshake->curves_tls_id == NULL || - ssl->handshake->curves_tls_id[0] == 0)) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: " - "no common elliptic curve")); - return 0; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - /* If the ciphersuite requires a pre-shared key and we don't - * have one, skip it now rather than failing later */ - if (mbedtls_ssl_ciphersuite_uses_psk(suite_info) && - ssl_conf_has_psk_or_cb(ssl->conf) == 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no pre-shared key")); - return 0; - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /* - * Final check: if ciphersuite requires us to have a - * certificate/key of a particular type: - * - select the appropriate certificate if we have one, or - * - try the next ciphersuite if we don't - * This must be done last since we modify the key_cert list. - */ - if (ssl_pick_cert(ssl, suite_info) != 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: " - "no suitable certificate")); - return 0; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - /* If the ciphersuite requires signing, check whether - * a suitable hash algorithm is present. */ - sig_type = mbedtls_ssl_get_ciphersuite_sig_alg(suite_info); - if (sig_type != MBEDTLS_PK_NONE && - mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( - ssl, mbedtls_ssl_sig_from_pk_alg(sig_type)) == MBEDTLS_SSL_HASH_NONE) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no suitable hash algorithm " - "for signature algorithm %u", (unsigned) sig_type)); - return 0; - } - -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ - - *ciphersuite_info = suite_info; - return 0; -} - -/* This function doesn't alert on errors that happen early during - ClientHello parsing because they might indicate that the client is - not talking SSL/TLS at all and would not understand our alert. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_client_hello(mbedtls_ssl_context *ssl) -{ - int ret, got_common_suite; - size_t i, j; - size_t ciph_offset, comp_offset, ext_offset; - size_t msg_len, ciph_len, sess_len, comp_len, ext_len; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - size_t cookie_offset, cookie_len; -#endif - unsigned char *buf, *p, *ext; -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renegotiation_info_seen = 0; -#endif - int handshake_failure = 0; - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - - /* If there is no signature-algorithm extension present, - * we need to fall back to the default values for allowed - * signature-hash pairs. */ -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - int sig_hash_alg_ext_present = 0; -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello")); - - /* - * Fetch the expected ClientHello handshake message. Do not ask - * mbedtls_ssl_read_record() to update the handshake digest, because the - * ClientHello may already have been read in ssl_tls13_process_client_hello() - * or as a post-handshake message (renegotiation). In those cases we need - * to update the digest ourselves, and it is simpler to do so - * unconditionally than to track whether it is needed. - */ - if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record ", ret); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* - * In the case of an alert message corresponding to the termination of - * a previous connection, `ssl_parse_record_header()` and then - * `mbedtls_ssl_read_record()` may return - * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD because of a non zero epoch. - * - * Historically, the library has returned - * MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE in this situation. - * The sample program dtls_server.c relies on this behavior - * (see - * https://github.com/Mbed-TLS/mbedtls/blob/d5e35a376bee23fad0b17f2e3e94a32ce4017c64/programs/ssl/dtls_server.c#L295), - * and user applications may rely on it as well. - * - * For compatibility, map MBEDTLS_ERR_SSL_UNEXPECTED_RECORD - * to MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE here. - * - * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD does not appear to be - * used to detect a specific error condition, so this mapping - * should not remove any meaningful distinction. - */ - if ((ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && (ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE) -#endif - ) { - if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) { - MBEDTLS_SSL_DEBUG_MSG(1, ("mapping UNEXPECTED_RECORD to UNEXPECTED_MESSAGE")); - ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - return ret; - } - - /* - * Update the handshake checksum. - * - * Note that the checksum must be updated before parsing the extensions - * because ssl_parse_session_ticket_ext() may decrypt the ticket in place - * and therefore modify the ClientHello message. This occurs when using - * the Mbed TLS ssl_ticket.c implementation. - */ - ret = mbedtls_ssl_update_handshake_status(ssl); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); - return ret; - } - - buf = ssl->in_msg; - msg_len = ssl->in_hslen; - - /* - * Handshake layer: - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 5 DTLS only: message sequence number - * 6 . 8 DTLS only: fragment offset - * 9 . 11 DTLS only: fragment length - */ - if ((ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) || - (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - buf += mbedtls_ssl_hs_hdr_len(ssl); - msg_len -= mbedtls_ssl_hs_hdr_len(ssl); - - /* - * ClientHello layout: - * 0 . 1 protocol version - * 2 . 33 random bytes (starting with 4 bytes of Unix time) - * 34 . 34 session id length (1 byte) - * 35 . 34+x session id, where x = session id length from byte 34 - * 35+x . 35+x DTLS only: cookie length (1 byte) - * 36+x . .. DTLS only: cookie - * .. . .. ciphersuite list length (2 bytes) - * .. . .. ciphersuite list - * .. . .. compression alg. list length (1 byte) - * .. . .. compression alg. list - * .. . .. extensions length (2 bytes, optional) - * .. . .. extensions (optional) - */ - - /* - * Minimal length (with everything empty and extensions omitted) is - * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can - * read at least up to session id length without worrying. - */ - if (msg_len < 38) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* - * Check and save the protocol version - */ - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, version", buf, 2); - - ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf, - ssl->conf->transport); - ssl->session_negotiate->tls_version = ssl->tls_version; - ssl->session_negotiate->endpoint = ssl->conf->endpoint; - - if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("server only supports TLS 1.2")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); - return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - } - - /* - * Save client random (inc. Unix time) - */ - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", buf + 2, 32); - - memcpy(ssl->handshake->randbytes, buf + 2, 32); - - /* - * Check the session ID length and save session ID - */ - sess_len = buf[34]; - - if (sess_len > sizeof(ssl->session_negotiate->id) || - sess_len + 34 + 2 > msg_len) { /* 2 for cipherlist length field */ - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id", buf + 35, sess_len); - - ssl->session_negotiate->id_len = sess_len; - memset(ssl->session_negotiate->id, 0, - sizeof(ssl->session_negotiate->id)); - memcpy(ssl->session_negotiate->id, buf + 35, - ssl->session_negotiate->id_len); - - /* - * Check the cookie length and content - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - cookie_offset = 35 + sess_len; - cookie_len = buf[cookie_offset]; - - if (cookie_offset + 1 + cookie_len + 2 > msg_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie", - buf + cookie_offset + 1, cookie_len); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if (ssl->conf->f_cookie_check != NULL -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) { - if (ssl->conf->f_cookie_check(ssl->conf->p_cookie, - buf + cookie_offset + 1, cookie_len, - ssl->cli_id, ssl->cli_id_len) != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification failed")); - ssl->handshake->cookie_verify_result = 1; - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification passed")); - ssl->handshake->cookie_verify_result = 0; - } - } else -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - { - /* We know we didn't send a cookie, so it should be empty */ - if (cookie_len != 0) { - /* This may be an attacker's probe, so don't send an alert */ - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification skipped")); - } - - /* - * Check the ciphersuitelist length (will be parsed later) - */ - ciph_offset = cookie_offset + 1 + cookie_len; - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - ciph_offset = 35 + sess_len; - - ciph_len = MBEDTLS_GET_UINT16_BE(buf, ciph_offset); - - if (ciph_len < 2 || - ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */ - (ciph_len % 2) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, ciphersuitelist", - buf + ciph_offset + 2, ciph_len); - - /* - * Check the compression algorithm's length. - * The list contents are ignored because implementing - * MBEDTLS_SSL_COMPRESS_NULL is mandatory and is the only - * option supported by Mbed TLS. - */ - comp_offset = ciph_offset + 2 + ciph_len; - - comp_len = buf[comp_offset]; - - if (comp_len < 1 || - comp_len > 16 || - comp_len + comp_offset + 1 > msg_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, compression", - buf + comp_offset + 1, comp_len); - - /* - * Check the extension length - */ - ext_offset = comp_offset + 1 + comp_len; - if (msg_len > ext_offset) { - if (msg_len < ext_offset + 2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - ext_len = MBEDTLS_GET_UINT16_BE(buf, ext_offset); - - if (msg_len != ext_offset + 2 + ext_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - } else { - ext_len = 0; - } - - ext = buf + ext_offset + 2; - MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", ext, ext_len); - - while (ext_len != 0) { - unsigned int ext_id; - unsigned int ext_size; - if (ext_len < 4) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - ext_id = MBEDTLS_GET_UINT16_BE(ext, 0); - ext_size = MBEDTLS_GET_UINT16_BE(ext, 2); - - if (ext_size + 4 > ext_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - switch (ext_id) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - case MBEDTLS_TLS_EXT_SERVERNAME: - MBEDTLS_SSL_DEBUG_MSG(3, ("found ServerName extension")); - ret = mbedtls_ssl_parse_server_name_ext(ssl, ext + 4, - ext + 4 + ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - - case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: - MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension")); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiation_info_seen = 1; -#endif - - ret = ssl_parse_renegotiation_info(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - case MBEDTLS_TLS_EXT_SIG_ALG: - MBEDTLS_SSL_DEBUG_MSG(3, ("found signature_algorithms extension")); - - ret = mbedtls_ssl_parse_sig_alg_ext(ssl, ext + 4, ext + 4 + ext_size); - if (ret != 0) { - return ret; - } - - sig_hash_alg_ext_present = 1; - break; -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS: - MBEDTLS_SSL_DEBUG_MSG(3, ("found supported elliptic curves extension")); - - ret = ssl_parse_supported_groups_ext(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; - - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG(3, ("found supported point formats extension")); - ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; - - ret = ssl_parse_supported_point_formats(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || \ - MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: - MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake kkpp extension")); - - ret = ssl_parse_ecjpake_kkpp(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG(3, ("found max fragment length extension")); - - ret = ssl_parse_max_fragment_length_ext(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - case MBEDTLS_TLS_EXT_CID: - MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension")); - - ret = ssl_parse_cid_ext(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt then mac extension")); - - ret = ssl_parse_encrypt_then_mac_ext(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG(3, ("found extended master secret extension")); - - ret = ssl_parse_extended_ms_ext(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_TLS_EXT_SESSION_TICKET: - MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension")); - /* - * If the Mbed TLS ssl_ticket.c implementation is used, the - * ticket is decrypted in place. This modifies the ClientHello - * message in the input buffer. - */ - ret = ssl_parse_session_ticket_ext(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension")); - - ret = mbedtls_ssl_parse_alpn_ext(ssl, ext + 4, - ext + 4 + ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - case MBEDTLS_TLS_EXT_USE_SRTP: - MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension")); - - ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size); - if (ret != 0) { - return ret; - } - break; -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - - default: - MBEDTLS_SSL_DEBUG_MSG(3, ("unknown extension found: %u (ignoring)", - ext_id)); - } - - ext_len -= 4 + ext_size; - ext += 4 + ext_size; - } - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - - /* - * Try to fall back to default hash SHA1 if the client - * hasn't provided any preferred signature-hash combinations. - */ - if (!sig_hash_alg_ext_present) { - uint16_t *received_sig_algs = ssl->handshake->received_sig_algs; - const uint16_t default_sig_algs[] = { -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, - MBEDTLS_SSL_HASH_SHA1), -#endif -#if defined(MBEDTLS_RSA_C) - MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, - MBEDTLS_SSL_HASH_SHA1), -#endif - MBEDTLS_TLS_SIG_NONE - }; - - MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0]) - <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE, - "default_sig_algs is too big"); - - memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs)); - } - -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ - - /* - * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ - for (i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2) { - if (p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO) { - MBEDTLS_SSL_DEBUG_MSG(3, ("received TLS_EMPTY_RENEGOTIATION_INFO ")); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { - MBEDTLS_SSL_DEBUG_MSG(1, ("received RENEGOTIATION SCSV " - "during renegotiation")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } -#endif - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - break; - } - } - - /* - * Renegotiation security checks - */ - if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation, breaking off handshake")); - handshake_failure = 1; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && - renegotiation_info_seen == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension missing (secure)")); - handshake_failure = 1; - } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) { - MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed")); - handshake_failure = 1; - } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - renegotiation_info_seen == 1) { - MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension present (legacy)")); - handshake_failure = 1; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - if (handshake_failure == 1) { - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* - * Server certification selection (after processing TLS extensions) - */ - if (ssl->conf->f_cert_cb && (ret = ssl->conf->f_cert_cb(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "f_cert_cb", ret); - return ret; - } -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - ssl->handshake->sni_name = NULL; - ssl->handshake->sni_name_len = 0; -#endif - - /* - * Search for a matching ciphersuite - * (At the end because we need information from the EC-based extensions - * and certificate from the SNI callback triggered by the SNI extension - * or certificate from server certificate selection callback.) - */ - got_common_suite = 0; - ciphersuites = ssl->conf->ciphersuite_list; - ciphersuite_info = NULL; - - if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) { - for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) { - for (i = 0; ciphersuites[i] != 0; i++) { - if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) { - continue; - } - - got_common_suite = 1; - - if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i], - &ciphersuite_info)) != 0) { - return ret; - } - - if (ciphersuite_info != NULL) { - goto have_ciphersuite; - } - } - } - } else { - for (i = 0; ciphersuites[i] != 0; i++) { - for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) { - if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) { - continue; - } - - got_common_suite = 1; - - if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i], - &ciphersuite_info)) != 0) { - return ret; - } - - if (ciphersuite_info != NULL) { - goto have_ciphersuite; - } - } - } - } - - if (got_common_suite) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got ciphersuites in common, " - "but none of them usable")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no ciphersuites in common")); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - -have_ciphersuite: - MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %s", ciphersuite_info->name)); - - ssl->session_negotiate->ciphersuite = ciphersuites[i]; - ssl->handshake->ciphersuite_info = ciphersuite_info; - - mbedtls_ssl_handshake_increment_state(ssl); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - mbedtls_ssl_recv_flight_completed(ssl); - } -#endif - - /* Debugging-only output for testsuite */ -#if defined(MBEDTLS_DEBUG_C) && \ - defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) - mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg(ciphersuite_info); - if (sig_alg != MBEDTLS_PK_NONE) { - unsigned int sig_hash = mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( - ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg)); - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, signature_algorithm ext: %u", - sig_hash)); - } else { - MBEDTLS_SSL_DEBUG_MSG(3, ("no hash algorithm for signature algorithm " - "%u - should not happen", (unsigned) sig_alg)); - } -#endif - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client hello")); - - return 0; -} - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) -static void ssl_write_cid_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - unsigned char *p = buf; - size_t ext_len; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - /* Skip writing the extension if we don't want to use it or if - * the client hasn't offered it. */ - if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED) { - return; - } - - /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX - * which is at most 255, so the increment cannot overflow. */ - if (end < p || (size_t) (end - p) < (unsigned) (ssl->own_cid_len + 5)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding CID extension")); - - /* - * struct { - * opaque cid<0..2^8-1>; - * } ConnectionId; - */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0); - p += 2; - ext_len = (size_t) ssl->own_cid_len + 1; - MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); - p += 2; - - *p++ = (uint8_t) ssl->own_cid_len; - memcpy(p, ssl->own_cid, ssl->own_cid_len); - - *olen = ssl->own_cid_len + 5; -} -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) -static void ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - unsigned char *p = buf; - const mbedtls_ssl_ciphersuite_t *suite = NULL; - - /* - * RFC 7366: "If a server receives an encrypt-then-MAC request extension - * from a client and then selects a stream or Authenticated Encryption - * with Associated Data (AEAD) ciphersuite, it MUST NOT send an - * encrypt-then-MAC response extension back to the client." - */ - suite = mbedtls_ssl_ciphersuite_from_id( - ssl->session_negotiate->ciphersuite); - if (suite == NULL) { - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED; - } else { - mbedtls_ssl_mode_t ssl_mode = - mbedtls_ssl_get_mode_from_ciphersuite( - ssl->session_negotiate->encrypt_then_mac, - suite); - - if (ssl_mode != MBEDTLS_SSL_MODE_CBC_ETM) { - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED; - } - } - - if (ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding encrypt then mac extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static void ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - unsigned char *p = buf; - - if (ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding extended master secret " - "extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static void ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - unsigned char *p = buf; - - if (ssl->handshake->new_session_ticket == 0) { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding session ticket extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -static void ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - unsigned char *p = buf; - - if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION) { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, secure renegotiation extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0); - p += 2; - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - *p++ = 0x00; - *p++ = (ssl->verify_data_len * 2 + 1) & 0xFF; - *p++ = ssl->verify_data_len * 2 & 0xFF; - - memcpy(p, ssl->peer_verify_data, ssl->verify_data_len); - p += ssl->verify_data_len; - memcpy(p, ssl->own_verify_data, ssl->verify_data_len); - p += ssl->verify_data_len; - } else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - *p++ = 0x00; - *p++ = 0x01; - *p++ = 0x00; - } - - *olen = (size_t) (p - buf); -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static void ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - unsigned char *p = buf; - - if (ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, max_fragment_length extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 1; - - *p++ = ssl->session_negotiate->mfl_code; - - *olen = 5; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - unsigned char *p = buf; - ((void) ssl); - - if ((ssl->handshake->cli_exts & - MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT) == 0) { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, supported_point_formats extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0); - p += 2; - - *p++ = 0x00; - *p++ = 2; - - *p++ = 1; - *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; - - *olen = 6; -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t kkpp_len; - - *olen = 0; - - /* Skip costly computation if not needed */ - if (ssl->handshake->ciphersuite_info->key_exchange != - MBEDTLS_KEY_EXCHANGE_ECJPAKE) { - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, ecjpake kkpp extension")); - - if (end - p < 4) { - MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); - return; - } - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0); - p += 2; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, - p + 2, (size_t) (end - p - 2), &kkpp_len, - MBEDTLS_ECJPAKE_ROUND_ONE); - if (ret != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); - return; - } -#else - ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx, - p + 2, (size_t) (end - p - 2), &kkpp_len, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret); - return; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0); - p += 2; - - *olen = kkpp_len + 4; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_DTLS_SRTP) && defined(MBEDTLS_SSL_PROTO_DTLS) -static void ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) -{ - size_t mki_len = 0, ext_len = 0; - uint16_t profile_value = 0; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET)) { - return; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding use_srtp extension")); - - if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { - mki_len = ssl->dtls_srtp_info.mki_len; - } - - /* The extension total size is 9 bytes : - * - 2 bytes for the extension tag - * - 2 bytes for the total size - * - 2 bytes for the protection profile length - * - 2 bytes for the protection profile - * - 1 byte for the mki length - * + the actual mki length - * Check we have enough room in the output buffer */ - if ((size_t) (end - buf) < mki_len + 9) { - MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); - return; - } - - /* extension */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0); - /* - * total length 5 and mki value: only one profile(2 bytes) - * and length(2 bytes) and srtp_mki ) - */ - ext_len = 5 + mki_len; - MBEDTLS_PUT_UINT16_BE(ext_len, buf, 2); - - /* protection profile length: 2 */ - buf[4] = 0x00; - buf[5] = 0x02; - profile_value = mbedtls_ssl_check_srtp_profile_value( - ssl->dtls_srtp_info.chosen_dtls_srtp_profile); - if (profile_value != MBEDTLS_TLS_SRTP_UNSET) { - MBEDTLS_PUT_UINT16_BE(profile_value, buf, 6); - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("use_srtp extension invalid profile")); - return; - } - - buf[8] = mki_len & 0xFF; - memcpy(&buf[9], ssl->dtls_srtp_info.mki_value, mki_len); - - *olen = 9 + mki_len; -} -#endif /* MBEDTLS_SSL_DTLS_SRTP */ - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = ssl->out_msg + 4; - unsigned char *cookie_len_byte; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello verify request")); - - /* - * struct { - * ProtocolVersion server_version; - * opaque cookie<0..2^8-1>; - * } HelloVerifyRequest; - */ - - /* The RFC is not clear on this point, but sending the actual negotiated - * version looks like the most interoperable thing to do. */ - mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version); - MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2); - p += 2; - - /* If we get here, f_cookie_check is not null */ - if (ssl->conf->f_cookie_write == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("inconsistent cookie callbacks")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Skip length byte until we know the length */ - cookie_len_byte = p++; - - if ((ret = ssl->conf->f_cookie_write(ssl->conf->p_cookie, - &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN, - ssl->cli_id, ssl->cli_id_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "f_cookie_write", ret); - return ret; - } - - *cookie_len_byte = (unsigned char) (p - (cookie_len_byte + 1)); - - MBEDTLS_SSL_DEBUG_BUF(3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte); - - ssl->out_msglen = (size_t) (p - ssl->out_msg); - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT); - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret); - return ret; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello verify request")); - - return 0; -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - -static void ssl_handle_id_based_session_resumption(mbedtls_ssl_context *ssl) -{ - int ret; - mbedtls_ssl_session session_tmp; - mbedtls_ssl_session * const session = ssl->session_negotiate; - - /* Resume is 0 by default, see ssl_handshake_init(). - * It may be already set to 1 by ssl_parse_session_ticket_ext(). */ - if (ssl->handshake->resume == 1) { - return; - } - if (session->id_len == 0) { - return; - } - if (ssl->conf->f_get_cache == NULL) { - return; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { - return; - } -#endif - - mbedtls_ssl_session_init(&session_tmp); - - ret = ssl->conf->f_get_cache(ssl->conf->p_cache, - session->id, - session->id_len, - &session_tmp); - if (ret != 0) { - goto exit; - } - - if (session->ciphersuite != session_tmp.ciphersuite) { - /* Mismatch between cached and negotiated session */ - goto exit; - } - - /* Move semantics */ - mbedtls_ssl_session_free(session); - *session = session_tmp; - memset(&session_tmp, 0, sizeof(session_tmp)); - - MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from cache")); - ssl->handshake->resume = 1; - -exit: - - mbedtls_ssl_session_free(&session_tmp); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_server_hello(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t; -#endif - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen, ext_len = 0, n; - unsigned char *buf, *p; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello")); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->cookie_verify_result != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("client hello was not authenticated")); - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello")); - - return ssl_write_hello_verify_request(ssl); - } -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 5 protocol version - * 6 . 9 UNIX time() - * 10 . 37 random bytes - */ - buf = ssl->out_msg; - p = buf + 4; - - mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version); - p += 2; - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]", - buf[4], buf[5])); - -#if defined(MBEDTLS_HAVE_TIME) - t = mbedtls_time(NULL); - MBEDTLS_PUT_UINT32_BE(t, p, 0); - p += 4; - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %" MBEDTLS_PRINTF_LONGLONG, - (long long) t)); -#else - if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 4)) != 0) { - return ret; - } - - p += 4; -#endif /* MBEDTLS_HAVE_TIME */ - - if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 20)) != 0) { - return ret; - } - p += 20; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - /* - * RFC 8446 - * TLS 1.3 has a downgrade protection mechanism embedded in the server's - * random value. TLS 1.3 servers which negotiate TLS 1.2 or below in - * response to a ClientHello MUST set the last 8 bytes of their Random - * value specially in their ServerHello. - */ - if (mbedtls_ssl_conf_is_tls13_enabled(ssl->conf)) { - static const unsigned char magic_tls12_downgrade_string[] = - { 'D', 'O', 'W', 'N', 'G', 'R', 'D', 1 }; - - MBEDTLS_STATIC_ASSERT( - sizeof(magic_tls12_downgrade_string) == 8, - "magic_tls12_downgrade_string does not have the expected size"); - - memcpy(p, magic_tls12_downgrade_string, - sizeof(magic_tls12_downgrade_string)); - } else -#endif - { - if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 8)) != 0) { - return ret; - } - } - p += 8; - - memcpy(ssl->handshake->randbytes + 32, buf + 6, 32); - - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 6, 32); - - ssl_handle_id_based_session_resumption(ssl); - - if (ssl->handshake->resume == 0) { - /* - * New session, create a new session id, - * unless we're about to issue a session ticket - */ - mbedtls_ssl_handshake_increment_state(ssl); - -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time(NULL); -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl->handshake->new_session_ticket != 0) { - ssl->session_negotiate->id_len = n = 0; - memset(ssl->session_negotiate->id, 0, 32); - } else -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - { - ssl->session_negotiate->id_len = n = 32; - if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, ssl->session_negotiate->id, - n)) != 0) { - return ret; - } - } - } else { - /* - * Resuming a session - */ - n = ssl->session_negotiate->id_len; - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC); - - if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); - return ret; - } - } - - /* - * 38 . 38 session id length - * 39 . 38+n session id - * 39+n . 40+n chosen ciphersuite - * 41+n . 41+n chosen compression alg. - * 42+n . 43+n extensions length - * 44+n . 43+n+m extensions - */ - *p++ = (unsigned char) ssl->session_negotiate->id_len; - memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len); - p += ssl->session_negotiate->id_len; - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n)); - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, session id", buf + 39, n); - MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed", - ssl->handshake->resume ? "a" : "no")); - - MBEDTLS_PUT_UINT16_BE(ssl->session_negotiate->ciphersuite, p, 0); - p += 2; - *p++ = MBEDTLS_BYTE_0(MBEDTLS_SSL_COMPRESS_NULL); - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %s", - mbedtls_ssl_get_ciphersuite_name(ssl->session_negotiate->ciphersuite))); - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: 0x%02X", - (unsigned int) MBEDTLS_SSL_COMPRESS_NULL)); - - /* - * First write extensions, then the total length - */ - ssl_write_renegotiation_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - ssl_write_max_fragment_length_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - ssl_write_cid_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) - ssl_write_encrypt_then_mac_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - ssl_write_extended_ms_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - ssl_write_session_ticket_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - const mbedtls_ssl_ciphersuite_t *suite = - mbedtls_ssl_ciphersuite_from_id(ssl->session_negotiate->ciphersuite); - if (suite != NULL && mbedtls_ssl_ciphersuite_uses_ec(suite)) { - ssl_write_supported_point_formats_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ALPN) - unsigned char *end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN - 4; - if ((ret = mbedtls_ssl_write_alpn_ext(ssl, p + 2 + ext_len, end, &olen)) - != 0) { - return ret; - } - - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_DTLS_SRTP) - ssl_write_use_srtp_ext(ssl, p + 2 + ext_len, &olen); - ext_len += olen; -#endif - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, - ext_len)); - - if (ext_len > 0) { - MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); - p += 2 + ext_len; - } - - ssl->out_msglen = (size_t) (p - buf); - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; - - ret = mbedtls_ssl_write_handshake_msg(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello")); - - return ret; -} - -#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_certificate_request(mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request")); - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} -#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_certificate_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - uint16_t dn_size, total_dn_size; /* excluding length bytes */ - size_t ct_len, sa_len; /* including length bytes */ - unsigned char *buf, *p; - const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - const mbedtls_x509_crt *crt; - int authmode; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request")); - - mbedtls_ssl_handshake_increment_state(ssl); - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) { - authmode = ssl->handshake->sni_authmode; - } else -#endif - authmode = ssl->conf->authmode; - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info) || - authmode == MBEDTLS_SSL_VERIFY_NONE) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request")); - return 0; - } - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 4 cert type count - * 5 .. m-1 cert types - * m .. m+1 sig alg length (TLS 1.2 only) - * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) - * n .. n+1 length of all DNs - * n+2 .. n+3 length of DN 1 - * n+4 .. ... Distinguished Name #1 - * ... .. ... length of DN 2, etc. - */ - buf = ssl->out_msg; - p = buf + 4; - - /* - * Supported certificate types - * - * ClientCertificateType certificate_types<1..2^8-1>; - * enum { (255) } ClientCertificateType; - */ - ct_len = 0; - -#if defined(MBEDTLS_RSA_C) - p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) - p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; -#endif - - p[0] = (unsigned char) ct_len++; - p += ct_len; - - sa_len = 0; - - /* - * Add signature_algorithms for verify (TLS 1.2) - * - * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>; - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * enum { (255) } HashAlgorithm; - * enum { (255) } SignatureAlgorithm; - */ - const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl); - if (sig_alg == NULL) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - - for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) { - unsigned char hash = MBEDTLS_BYTE_1(*sig_alg); - - if (mbedtls_ssl_set_calc_verify_md(ssl, hash)) { - continue; - } - if (!mbedtls_ssl_sig_alg_is_supported(ssl, *sig_alg)) { - continue; - } - - /* Write elements at offsets starting from 1 (offset 0 is for the - * length). Thus the offset of each element is the length of the - * partial list including that element. */ - sa_len += 2; - MBEDTLS_PUT_UINT16_BE(*sig_alg, p, sa_len); - - } - - /* Fill in list length. */ - MBEDTLS_PUT_UINT16_BE(sa_len, p, 0); - sa_len += 2; - p += sa_len; - - /* - * DistinguishedName certificate_authorities<0..2^16-1>; - * opaque DistinguishedName<1..2^16-1>; - */ - p += 2; - - total_dn_size = 0; - - if (ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED) { - /* NOTE: If trusted certificates are provisioned - * via a CA callback (configured through - * `mbedtls_ssl_conf_ca_cb()`, then the - * CertificateRequest is currently left empty. */ - -#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (ssl->handshake->dn_hints != NULL) { - crt = ssl->handshake->dn_hints; - } else -#endif - if (ssl->conf->dn_hints != NULL) { - crt = ssl->conf->dn_hints; - } else -#endif -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (ssl->handshake->sni_ca_chain != NULL) { - crt = ssl->handshake->sni_ca_chain; - } else -#endif - crt = ssl->conf->ca_chain; - - while (crt != NULL && crt->version != 0) { - /* It follows from RFC 5280 A.1 that this length - * can be represented in at most 11 bits. */ - dn_size = (uint16_t) crt->subject_raw.len; - - if (end < p || (size_t) (end - p) < 2 + (size_t) dn_size) { - MBEDTLS_SSL_DEBUG_MSG(1, ("skipping CAs: buffer too short")); - break; - } - - MBEDTLS_PUT_UINT16_BE(dn_size, p, 0); - p += 2; - memcpy(p, crt->subject_raw.p, dn_size); - p += dn_size; - - MBEDTLS_SSL_DEBUG_BUF(3, "requested DN", p - dn_size, dn_size); - - total_dn_size += (unsigned short) (2 + dn_size); - crt = crt->next; - } - } - - ssl->out_msglen = (size_t) (p - buf); - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; - MBEDTLS_PUT_UINT16_BE(total_dn_size, ssl->out_msg, 4 + ct_len + sa_len); - - ret = mbedtls_ssl_write_handshake_msg(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate request")); - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ - -#if (defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)) -#if defined(MBEDTLS_USE_PSA_CRYPTO) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_pk_context *pk; - mbedtls_pk_type_t pk_type; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - unsigned char buf[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - size_t key_len; -#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) - uint16_t tls_id = 0; - psa_key_type_t key_type = PSA_KEY_TYPE_NONE; - mbedtls_ecp_group_id grp_id; - mbedtls_ecp_keypair *key; -#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ - - pk = mbedtls_ssl_own_key(ssl); - - if (pk == NULL) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - - pk_type = mbedtls_pk_get_type(pk); - - switch (pk_type) { - case MBEDTLS_PK_OPAQUE: -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) { - return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - } - - /* Get the attributes of the key previously parsed by PK module in - * order to extract its type and length (in bits). */ - status = psa_get_key_attributes(pk->priv_id, &key_attributes); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes); - ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes); - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - if (pk_type != MBEDTLS_PK_OPAQUE) { - /* PK_ECKEY[_DH] and PK_ECDSA instead as parsed from the PK - * module and only have ECDSA capabilities. Since we need - * them for ECDH later, we export and then re-import them with - * proper flags and algorithm. Of course We also set key's type - * and bits that we just got above. */ - key_attributes = psa_key_attributes_init(); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_type(&key_attributes, - PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type)); - psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits); - - status = psa_export_key(pk->priv_id, buf, sizeof(buf), &key_len); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - status = psa_import_key(&key_attributes, buf, key_len, - &ssl->handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - /* Set this key as owned by the TLS library: it will be its duty - * to clear it exit. */ - ssl->handshake->xxdh_psa_privkey_is_external = 0; - - ret = 0; - break; - } -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - - /* Opaque key is created by the user (externally from Mbed TLS) - * so we assume it already has the right algorithm and flags - * set. Just copy its ID as reference. */ - ssl->handshake->xxdh_psa_privkey = pk->priv_id; - ssl->handshake->xxdh_psa_privkey_is_external = 1; - ret = 0; - break; - -#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) - case MBEDTLS_PK_ECKEY: - case MBEDTLS_PK_ECKEY_DH: - case MBEDTLS_PK_ECDSA: - key = mbedtls_pk_ec_rw(*pk); - grp_id = mbedtls_pk_get_ec_group_id(pk); - if (grp_id == MBEDTLS_ECP_DP_NONE) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - } - tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); - if (tls_id == 0) { - /* This elliptic curve is not supported */ - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* If the above conversion to TLS ID was fine, then also this one will - be, so there is no need to check the return value here */ - mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, - &ssl->handshake->xxdh_psa_bits); - - ssl->handshake->xxdh_psa_type = key_type; - - key_attributes = psa_key_attributes_init(); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_type(&key_attributes, - PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type)); - psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits); - - ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf)); - if (ret != 0) { - mbedtls_platform_zeroize(buf, sizeof(buf)); - break; - } - - status = psa_import_key(&key_attributes, buf, key_len, - &ssl->handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - mbedtls_platform_zeroize(buf, sizeof(buf)); - break; - } - - mbedtls_platform_zeroize(buf, sizeof(buf)); - ret = 0; - break; -#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ - default: - ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - } - -exit: - psa_reset_key_attributes(&key_attributes); - mbedtls_platform_zeroize(buf, sizeof(buf)); - - return ret; -} -#else /* MBEDTLS_USE_PSA_CRYPTO */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - const mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl); - if (private_key == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no server private key")); - return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; - } - - if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_ECKEY)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable")); - return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; - } - - if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, - mbedtls_pk_ec_ro(*mbedtls_ssl_own_key(ssl)), - MBEDTLS_ECDH_OURS)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret); - return ret; - } - - return 0; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_resume_server_key_exchange(mbedtls_ssl_context *ssl, - size_t *signature_len) -{ - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2; - size_t sig_max_len = (ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN - - sig_start); - int ret = ssl->conf->f_async_resume(ssl, - sig_start, signature_len, sig_max_len); - if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data(ssl, NULL); - } - MBEDTLS_SSL_DEBUG_RET(2, "ssl_resume_server_key_exchange", ret); - return ret; -} -#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - -/* Prepare the ServerKeyExchange message, up to and including - * calculating the signature if any, but excluding formatting the - * signature and sending the message. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_prepare_server_key_exchange(mbedtls_ssl_context *ssl, - size_t *signature_len) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED) -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) - unsigned char *dig_signed = NULL; -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */ - - (void) ciphersuite_info; /* unused in some configurations */ -#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) - (void) signature_len; -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf); -#else - size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf); -#endif -#endif - - ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ - - /* - * - * Part 1: Provide key exchange parameters for chosen ciphersuite. - * - */ - - /* - * - ECJPAKE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - unsigned char *out_p = ssl->out_msg + ssl->out_msglen; - unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - - ssl->out_msglen; - size_t output_offset = 0; - size_t output_len = 0; - - /* - * The first 3 bytes are: - * [0] MBEDTLS_ECP_TLS_NAMED_CURVE - * [1, 2] elliptic curve's TLS ID - * - * However since we only support secp256r1 for now, we hardcode its - * TLS ID here - */ - uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( - MBEDTLS_ECP_DP_SECP256R1); - if (tls_id == 0) { - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE; - MBEDTLS_PUT_UINT16_BE(tls_id, out_p, 1); - output_offset += 3; - - ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, - out_p + output_offset, - end_p - out_p - output_offset, &output_len, - MBEDTLS_ECJPAKE_ROUND_TWO); - if (ret != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); - return ret; - } - - output_offset += output_len; - ssl->out_msglen += output_offset; -#else - size_t len = 0; - - ret = mbedtls_ecjpake_write_round_two( - &ssl->handshake->ecjpake_ctx, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret); - return ret; - } - - ssl->out_msglen += len; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - - /* - * For (EC)DHE key exchanges with PSK, parameters are prefixed by support - * identity hint (RFC 4279, Sec. 3). Until someone needs this feature, - * we use empty support identity hints here. - **/ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { - ssl->out_msg[ssl->out_msglen++] = 0x00; - ssl->out_msg[ssl->out_msglen++] = 0x00; - } -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - - /* - * - DHE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_dhe(ciphersuite_info)) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - if (ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no DH parameters set")); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* - * Ephemeral DH parameters: - * - * struct { - * opaque dh_p<1..2^16-1>; - * opaque dh_g<1..2^16-1>; - * opaque dh_Ys<1..2^16-1>; - * } ServerDHParams; - */ - if ((ret = mbedtls_dhm_set_group(&ssl->handshake->dhm_ctx, - &ssl->conf->dhm_P, - &ssl->conf->dhm_G)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_set_group", ret); - return ret; - } - - if ((ret = mbedtls_dhm_make_params( - &ssl->handshake->dhm_ctx, - (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), - ssl->out_msg + ssl->out_msglen, &len, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_params", ret); - return ret; - } - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; -#endif - - ssl->out_msglen += len; - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X); - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P); - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G); - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX); - } -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */ - - /* - * - ECDHE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_ecdhe(ciphersuite_info)) { - /* - * Ephemeral ECDH parameters: - * - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ - uint16_t *curr_tls_id = ssl->handshake->curves_tls_id; - const uint16_t *group_list = mbedtls_ssl_get_groups(ssl); - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - /* Match our preference list against the offered curves */ - if ((group_list == NULL) || (curr_tls_id == NULL)) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - for (; *group_list != 0; group_list++) { - for (curr_tls_id = ssl->handshake->curves_tls_id; - *curr_tls_id != 0; curr_tls_id++) { - if (*curr_tls_id == *group_list) { - goto curve_matching_done; - } - } - } - -curve_matching_done: - if (*curr_tls_id == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no matching curve for ECDHE")); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("ECDHE curve: %s", - mbedtls_ssl_get_curve_name_from_tls_id(*curr_tls_id))); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_GENERIC_ERROR; - psa_key_attributes_t key_attributes; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - uint8_t *p = ssl->out_msg + ssl->out_msglen; - const size_t header_size = 4; // curve_type(1), namedcurve(2), - // data length(1) - const size_t data_length_size = 1; - psa_key_type_t key_type = PSA_KEY_TYPE_NONE; - size_t ec_bits = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based ECDH computation.")); - - /* Convert EC's TLS ID to PSA key type. */ - if (mbedtls_ssl_get_psa_curve_info_from_tls_id(*curr_tls_id, - &key_type, - &ec_bits) == PSA_ERROR_NOT_SUPPORTED) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid ecc group parse.")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - handshake->xxdh_psa_type = key_type; - handshake->xxdh_psa_bits = ec_bits; - - key_attributes = psa_key_attributes_init(); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); - psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); - - /* - * ECParameters curve_params - * - * First byte is curve_type, always named_curve - */ - *p++ = MBEDTLS_ECP_TLS_NAMED_CURVE; - - /* - * Next two bytes are the namedcurve value - */ - MBEDTLS_PUT_UINT16_BE(*curr_tls_id, p, 0); - p += 2; - - /* Generate ECDH private key. */ - status = psa_generate_key(&key_attributes, - &handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_generate_key", ret); - return ret; - } - - /* - * ECPoint public - * - * First byte is data length. - * It will be filled later. p holds now the data length location. - */ - - /* Export the public part of the ECDH private key from PSA. - * Make one byte space for the length. - */ - unsigned char *own_pubkey = p + data_length_size; - - size_t own_pubkey_max_len = (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN - - (own_pubkey - ssl->out_msg)); - - status = psa_export_public_key(handshake->xxdh_psa_privkey, - own_pubkey, own_pubkey_max_len, - &len); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_export_public_key", ret); - (void) psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return ret; - } - - /* Store the length of the exported public key. */ - *p = (uint8_t) len; - - /* Determine full message length. */ - len += header_size; -#else - mbedtls_ecp_group_id curr_grp_id = - mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id); - - if ((ret = mbedtls_ecdh_setup(&ssl->handshake->ecdh_ctx, - curr_grp_id)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecp_group_load", ret); - return ret; - } - - if ((ret = mbedtls_ecdh_make_params( - &ssl->handshake->ecdh_ctx, &len, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_params", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; -#endif - - ssl->out_msglen += len; - } -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */ - - /* - * - * Part 2: For key exchanges involving the server signing the - * exchange parameters, compute and add the signature here. - * - */ -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) { - if (dig_signed == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - size_t dig_signed_len = (size_t) (ssl->out_msg + ssl->out_msglen - dig_signed); - size_t hashlen = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* - * 2.1: Choose hash algorithm: - * For TLS 1.2, obey signature-hash-algorithm extension - * to choose appropriate hash. - */ - - mbedtls_pk_type_t sig_alg = - mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info); - - unsigned char sig_hash = - (unsigned char) mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( - ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg)); - - mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash(sig_hash); - - /* For TLS 1.2, obey signature-hash-algorithm extension - * (RFC 5246, Sec. 7.4.1.4.1). */ - if (sig_alg == MBEDTLS_PK_NONE || md_alg == MBEDTLS_MD_NONE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - /* (... because we choose a cipher suite - * only if there is a matching hash.) */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("pick hash algorithm %u for signing", (unsigned) md_alg)); - - /* - * 2.2: Compute the hash to be signed - */ - if (md_alg != MBEDTLS_MD_NONE) { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen, - dig_signed, - dig_signed_len, - md_alg); - if (ret != 0) { - return ret; - } - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen); - - /* - * 2.3: Compute and add the signature - */ - /* - * We need to specify signature and hash algorithm explicitly through - * a prefix to the signature. - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * struct { - * SignatureAndHashAlgorithm algorithm; - * opaque signature<0..2^16-1>; - * } DigitallySigned; - * - */ - - ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_hash_from_md_alg(md_alg); - ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_sig_from_pk_alg(sig_alg); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if (ssl->conf->f_async_sign_start != NULL) { - ret = ssl->conf->f_async_sign_start(ssl, - mbedtls_ssl_own_cert(ssl), - md_alg, hash, hashlen); - switch (ret) { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_sign was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return ssl_resume_server_key_exchange(ssl, signature_len); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS; - default: - MBEDTLS_SSL_DEBUG_RET(1, "f_async_sign_start", ret); - return ret; - } - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if (mbedtls_ssl_own_key(ssl) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key")); - return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; - } - - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - if ((ret = mbedtls_pk_sign(mbedtls_ssl_own_key(ssl), - md_alg, hash, hashlen, - ssl->out_msg + ssl->out_msglen + 2, - out_buf_len - ssl->out_msglen - 2, - signature_len, - ssl->conf->f_rng, - ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret); - return ret; - } - } -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ - - return 0; -} - -/* Prepare the ServerKeyExchange message and send it. For ciphersuites - * that do not include a ServerKeyExchange message, do nothing. Either - * way, if successful, move on to the next step in the SSL state - * machine. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t signature_len = 0; -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server key exchange")); - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) - /* Extract static ECDH parameters and abort if ServerKeyExchange - * is not needed. */ - if (mbedtls_ssl_ciphersuite_no_pfs(ciphersuite_info)) { - /* For suites involving ECDH, extract DH parameters - * from certificate at this point. */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) - if (mbedtls_ssl_ciphersuite_uses_ecdh(ciphersuite_info)) { - ret = ssl_get_ecdh_params_from_cert(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret); - return ret; - } - } -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */ - - /* Key exchanges not involving ephemeral keys don't use - * ServerKeyExchange, so end here. */ - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already prepared the message and there is an ongoing - * signature operation, resume signing. */ - if (ssl->handshake->async_in_progress != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("resuming signature operation")); - ret = ssl_resume_server_key_exchange(ssl, &signature_len); - } else -#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - { - /* ServerKeyExchange is needed. Prepare the message. */ - ret = ssl_prepare_server_key_exchange(ssl, &signature_len); - } - - if (ret != 0) { - /* If we're starting to write a new message, set ssl->out_msglen - * to 0. But if we're resuming after an asynchronous message, - * out_msglen is the amount of data written so far and mst be - * preserved. */ - if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange (pending)")); - } else { - ssl->out_msglen = 0; - } - return ret; - } - - /* If there is a signature, write its length. - * ssl_prepare_server_key_exchange already wrote the signature - * itself at its proper place in the output buffer. */ -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) - if (signature_len != 0) { - ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1(signature_len); - ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0(signature_len); - - MBEDTLS_SSL_DEBUG_BUF(3, "my signature", - ssl->out_msg + ssl->out_msglen, - signature_len); - - /* Skip over the already-written signature */ - ssl->out_msglen += signature_len; - } -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ - - /* Add header and send. */ - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; - - mbedtls_ssl_handshake_increment_state(ssl); - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange")); - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_server_hello_done(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello done")); - - ssl->out_msglen = 4; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; - - mbedtls_ssl_handshake_increment_state(ssl); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - mbedtls_ssl_send_flight_completed(ssl); - } -#endif - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret); - return ret; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello done")); - - return 0; -} - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_client_dh_public(mbedtls_ssl_context *ssl, unsigned char **p, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t n; - - /* - * Receive G^Y mod P, premaster = (G^Y)^X mod P - */ - if (*p + 2 > end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - n = MBEDTLS_GET_UINT16_BE(*p, 0); - *p += 2; - - if (*p + n > end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - if ((ret = mbedtls_dhm_read_public(&ssl->handshake->dhm_ctx, *p, n)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_read_public", ret); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - *p += n; - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY); - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_resume_decrypt_pms(mbedtls_ssl_context *ssl, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize) -{ - int ret = ssl->conf->f_async_resume(ssl, - peer_pms, peer_pmslen, peer_pmssize); - if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data(ssl, NULL); - } - MBEDTLS_SSL_DEBUG_RET(2, "ssl_decrypt_encrypted_pms", ret); - return ret; -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_decrypt_encrypted_pms(mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_x509_crt *own_cert = mbedtls_ssl_own_cert(ssl); - if (own_cert == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no local certificate")); - return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE; - } - mbedtls_pk_context *public_key = &own_cert->pk; - mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl); - size_t len = mbedtls_pk_get_len(public_key); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already started decoding the message and there is an ongoing - * decryption operation, resume signing. */ - if (ssl->handshake->async_in_progress != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("resuming decryption operation")); - return ssl_resume_decrypt_pms(ssl, - peer_pms, peer_pmslen, peer_pmssize); - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - /* - * Prepare to decrypt the premaster using own private RSA key - */ - if (p + 2 > end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - if (*p++ != MBEDTLS_BYTE_1(len) || - *p++ != MBEDTLS_BYTE_0(len)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - if (p + len != end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* - * Decrypt the premaster secret - */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if (ssl->conf->f_async_decrypt_start != NULL) { - ret = ssl->conf->f_async_decrypt_start(ssl, - mbedtls_ssl_own_cert(ssl), - p, len); - switch (ret) { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_decrypt_start was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return ssl_resume_decrypt_pms(ssl, - peer_pms, - peer_pmslen, - peer_pmssize); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS; - default: - MBEDTLS_SSL_DEBUG_RET(1, "f_async_decrypt_start", ret); - return ret; - } - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_RSA)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no RSA private key")); - return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; - } - - ret = mbedtls_pk_decrypt(private_key, p, len, - peer_pms, peer_pmslen, peer_pmssize, - ssl->conf->f_rng, ssl->conf->p_rng); - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_encrypted_pms(mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - size_t pms_offset) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *pms = ssl->handshake->premaster + pms_offset; - unsigned char ver[2]; - unsigned char fake_pms[48], peer_pms[48]; - size_t peer_pmslen; - mbedtls_ct_condition_t diff; - - /* In case of a failure in decryption, the decryption may write less than - * 2 bytes of output, but we always read the first two bytes. It doesn't - * matter in the end because diff will be nonzero in that case due to - * ret being nonzero, and we only care whether diff is 0. - * But do initialize peer_pms and peer_pmslen for robustness anyway. This - * also makes memory analyzers happy (don't access uninitialized memory, - * even if it's an unsigned char). */ - peer_pms[0] = peer_pms[1] = ~0; - peer_pmslen = 0; - - ret = ssl_decrypt_encrypted_pms(ssl, p, end, - peer_pms, - &peer_pmslen, - sizeof(peer_pms)); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { - return ret; - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - mbedtls_ssl_write_version(ver, ssl->conf->transport, - ssl->session_negotiate->tls_version); - - /* Avoid data-dependent branches while checking for invalid - * padding, to protect against timing-based Bleichenbacher-type - * attacks. */ - diff = mbedtls_ct_bool(ret); - diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pmslen, 48)); - diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[0], ver[0])); - diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[1], ver[1])); - - /* - * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding - * must not cause the connection to end immediately; instead, send a - * bad_record_mac later in the handshake. - * To protect against timing-based variants of the attack, we must - * not have any branch that depends on whether the decryption was - * successful. In particular, always generate the fake premaster secret, - * regardless of whether it will ultimately influence the output or not. - */ - ret = ssl->conf->f_rng(ssl->conf->p_rng, fake_pms, sizeof(fake_pms)); - if (ret != 0) { - /* It's ok to abort on an RNG failure, since this does not reveal - * anything about the RSA decryption. */ - return ret; - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - if (diff != MBEDTLS_CT_FALSE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - } -#endif - - if (sizeof(ssl->handshake->premaster) < pms_offset || - sizeof(ssl->handshake->premaster) - pms_offset < 48) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - ssl->handshake->pmslen = 48; - - /* Set pms to either the true or the fake PMS, without - * data-dependent branches. */ - mbedtls_ct_memcpy_if(diff, pms, fake_pms, peer_pms, ssl->handshake->pmslen); - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_client_psk_identity(mbedtls_ssl_context *ssl, unsigned char **p, - const unsigned char *end) -{ - int ret = 0; - uint16_t n; - - if (ssl_conf_has_psk_or_cb(ssl->conf) == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("got no pre-shared key")); - return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; - } - - /* - * Receive client pre-shared key identity name - */ - if (end - *p < 2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - n = MBEDTLS_GET_UINT16_BE(*p, 0); - *p += 2; - - if (n == 0 || n > end - *p) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - if (ssl->conf->f_psk != NULL) { - if (ssl->conf->f_psk(ssl->conf->p_psk, ssl, *p, n) != 0) { - ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - } else { - /* Identity is not a big secret since clients send it in the clear, - * but treat it carefully anyway, just in case */ - if (n != ssl->conf->psk_identity_len || - mbedtls_ct_memcmp(ssl->conf->psk_identity, *p, n) != 0) { - ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - } - - if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) { - MBEDTLS_SSL_DEBUG_BUF(3, "Unknown PSK identity", *p, n); - mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY); - return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - - *p += n; - - return 0; -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - unsigned char *p, *end; - - ciphersuite_info = ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client key exchange")); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \ - (defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)) - if ((ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) && - (ssl->handshake->async_in_progress != 0)) { - /* We've already read a record and there is an asynchronous - * operation in progress to decrypt it. So skip reading the - * record. */ - MBEDTLS_SSL_DEBUG_MSG(3, ("will resume decryption of previously-read record")); - } else -#endif - if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); - end = ssl->in_msg + ssl->in_hslen; - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) { - if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret); - return ret; - } - - if (p != end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); - } else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t data_len = (size_t) (*p++); - size_t buf_len = (size_t) (end - p); - psa_status_t status = PSA_ERROR_GENERIC_ERROR; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - MBEDTLS_SSL_DEBUG_MSG(3, ("Read the peer's public key.")); - - /* - * We must have at least two bytes (1 for length, at least 1 for data) - */ - if (buf_len < 2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length: %" MBEDTLS_PRINTF_SIZET, - buf_len)); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - if (data_len < 1 || data_len > buf_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length: %" MBEDTLS_PRINTF_SIZET - " > %" MBEDTLS_PRINTF_SIZET, - data_len, buf_len)); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* Store peer's ECDH public key. */ - if (data_len > sizeof(handshake->xxdh_psa_peerkey)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %" MBEDTLS_PRINTF_SIZET - " > %" MBEDTLS_PRINTF_SIZET, - data_len, - sizeof(handshake->xxdh_psa_peerkey))); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - memcpy(handshake->xxdh_psa_peerkey, p, data_len); - handshake->xxdh_psa_peerkey_len = data_len; - - /* Compute ECDH shared secret. */ - status = psa_raw_key_agreement( - PSA_ALG_ECDH, handshake->xxdh_psa_privkey, - handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len, - handshake->premaster, sizeof(handshake->premaster), - &handshake->pmslen); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret); - if (handshake->xxdh_psa_privkey_is_external == 0) { - (void) psa_destroy_key(handshake->xxdh_psa_privkey); - } - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return ret; - } - - if (handshake->xxdh_psa_privkey_is_external == 0) { - status = psa_destroy_key(handshake->xxdh_psa_privkey); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret); - return ret; - } - } - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; -#else - if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx, - p, (size_t) (end - p))) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP); - - if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) { - if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); - return ret; - } - - if (p != end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, - (mbedtls_key_exchange_type_t) ciphersuite_info-> - key_exchange)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); - return ret; - } -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if (ssl->handshake->async_in_progress != 0) { - /* There is an asynchronous operation in progress to - * decrypt the encrypted premaster secret, so skip - * directly to resuming this operation. */ - MBEDTLS_SSL_DEBUG_MSG(3, ("PSK identity already parsed")); - /* Update p to skip the PSK identity. ssl_parse_encrypted_pms - * won't actually use it, but maintain p anyway for robustness. */ - p += ssl->conf->psk_identity_len + 2; - } else -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); - return ret; - } - - if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 2)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_encrypted_pms"), ret); - return ret; - } - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, - (mbedtls_key_exchange_type_t) ciphersuite_info-> - key_exchange)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); - return ret; - } -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { - if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); - return ret; - } - if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret); - return ret; - } - - if (p != end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - unsigned char *pms = ssl->handshake->premaster; - unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster); - size_t pms_len; - - /* Write length only when we know the actual value */ - if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, - pms + 2, pms_end - (pms + 2), &pms_len, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); - return ret; - } - MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0); - pms += 2 + pms_len; - - MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); -#else - if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, - (mbedtls_key_exchange_type_t) ciphersuite_info-> - key_exchange)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; - size_t ecpoint_len; - - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); - psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return ret; - } - - /* Keep a copy of the peer's public key */ - if (p >= end) { - psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - ecpoint_len = *(p++); - if ((size_t) (end - p) < ecpoint_len) { - psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* When FFDH is enabled, the array handshake->xxdh_psa_peer_key size takes into account - the sizes of the FFDH keys which are at least 2048 bits. - The size of the array is thus greater than 256 bytes which is greater than any - possible value of ecpoint_len (type uint8_t) and the check below can be skipped.*/ -#if !defined(PSA_WANT_ALG_FFDH) - if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) { - psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } -#else - MBEDTLS_STATIC_ASSERT(sizeof(handshake->xxdh_psa_peerkey) >= UINT8_MAX, - "peer key buffer too small"); -#endif - - memcpy(handshake->xxdh_psa_peerkey, p, ecpoint_len); - handshake->xxdh_psa_peerkey_len = ecpoint_len; - p += ecpoint_len; - - /* As RFC 5489 section 2, the premaster secret is formed as follows: - * - a uint16 containing the length (in octets) of the ECDH computation - * - the octet string produced by the ECDH computation - * - a uint16 containing the length (in octets) of the PSK - * - the PSK itself - */ - unsigned char *psm = ssl->handshake->premaster; - const unsigned char * const psm_end = - psm + sizeof(ssl->handshake->premaster); - /* uint16 to store length (in octets) of the ECDH computation */ - const size_t zlen_size = 2; - size_t zlen = 0; - - /* Compute ECDH shared secret. */ - status = psa_raw_key_agreement(PSA_ALG_ECDH, - handshake->xxdh_psa_privkey, - handshake->xxdh_psa_peerkey, - handshake->xxdh_psa_peerkey_len, - psm + zlen_size, - psm_end - (psm + zlen_size), - &zlen); - - destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } else if (destruction_status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(destruction_status); - } - - /* Write the ECDH computation length before the ECDH computation */ - MBEDTLS_PUT_UINT16_BE(zlen, psm, 0); - psm += zlen_size + zlen; - -#else /* MBEDTLS_USE_PSA_CRYPTO */ - if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); - return ret; - } - - if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx, - p, (size_t) (end - p))) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP); - - if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, - (mbedtls_key_exchange_type_t) ciphersuite_info-> - key_exchange)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { - if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 0)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_parse_encrypted_pms_secret"), ret); - return ret; - } - } else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if ((ret = mbedtls_psa_ecjpake_read_round( - &ssl->handshake->psa_pake_ctx, p, (size_t) (end - p), - MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) { - psa_destroy_key(ssl->handshake->psa_pake_password); - psa_pake_abort(&ssl->handshake->psa_pake_ctx); - - MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret); - return ret; - } -#else - ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx, - p, (size_t) (end - p)); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - } else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); - return ret; - } - - mbedtls_ssl_handshake_increment_state(ssl); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange")); - - return 0; -} - -#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify")); - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} -#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t i, sig_len; - unsigned char hash[48]; - unsigned char *hash_start = hash; - size_t hashlen; - mbedtls_pk_type_t pk_alg; - mbedtls_md_type_t md_alg; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - mbedtls_pk_context *peer_pk; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify")); - - if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if (ssl->session_negotiate->peer_cert == NULL) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (ssl->session_negotiate->peer_cert_digest == NULL) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - mbedtls_ssl_handshake_increment_state(ssl); - return 0; - } -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* Read the message without adding it to the checksum */ - ret = mbedtls_ssl_read_record(ssl, 0 /* no checksum update */); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_read_record"), ret); - return ret; - } - - mbedtls_ssl_handshake_increment_state(ssl); - - /* Process the message contents */ - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || - ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - i = mbedtls_ssl_hs_hdr_len(ssl); - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (ssl->session_negotiate->peer_cert == NULL) { - /* Should never happen */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* - * struct { - * SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only - * opaque signature<0..2^16-1>; - * } DigitallySigned; - */ - if (i + 2 > ssl->in_hslen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* - * Hash - */ - md_alg = mbedtls_ssl_md_alg_from_hash(ssl->in_msg[i]); - - if (md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md(ssl, ssl->in_msg[i])) { - MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg" - " for verify message")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - -#if !defined(MBEDTLS_MD_SHA1) - if (MBEDTLS_MD_SHA1 == md_alg) { - hash_start += 16; - } -#endif - - /* Info from md_alg will be used instead */ - hashlen = 0; - - i++; - - /* - * Signature - */ - if ((pk_alg = mbedtls_ssl_pk_alg_from_sig(ssl->in_msg[i])) - == MBEDTLS_PK_NONE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg" - " for verify message")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - /* - * Check the certificate's key type matches the signature alg - */ - if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("sig_alg doesn't match cert key")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - i++; - - if (i + 2 > ssl->in_hslen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - sig_len = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i); - i += 2; - - if (i + sig_len != ssl->in_hslen) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Calculate hash and verify signature */ - { - size_t dummy_hlen; - ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret); - return ret; - } - } - - if ((ret = mbedtls_pk_verify(peer_pk, - md_alg, hash_start, hashlen, - ssl->in_msg + i, sig_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret); - return ret; - } - - ret = mbedtls_ssl_update_handshake_status(ssl); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify")); - - return ret; -} -#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_write_new_session_ticket(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t tlen; - uint32_t lifetime; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write new session ticket")); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_NEW_SESSION_TICKET; - - /* - * struct { - * uint32 ticket_lifetime_hint; - * opaque ticket<0..2^16-1>; - * } NewSessionTicket; - * - * 4 . 7 ticket_lifetime_hint (0 = unspecified) - * 8 . 9 ticket_len (n) - * 10 . 9+n ticket content - */ - -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->ticket_creation_time = mbedtls_ms_time(); -#endif - if ((ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket, - ssl->session_negotiate, - ssl->out_msg + 10, - ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, - &tlen, &lifetime)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_write", ret); - tlen = 0; - } - - MBEDTLS_PUT_UINT32_BE(lifetime, ssl->out_msg, 4); - MBEDTLS_PUT_UINT16_BE(tlen, ssl->out_msg, 8); - ssl->out_msglen = 10 + tlen; - - /* - * Morally equivalent to updating ssl->state, but NewSessionTicket and - * ChangeCipherSpec share the same state. - */ - ssl->handshake->new_session_ticket = 0; - - if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket")); - - return 0; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -/* - * SSL handshake -- server side -- single step - */ -int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl) -{ - int ret = 0; - - MBEDTLS_SSL_DEBUG_MSG(2, ("server state: %d", ssl->state)); - - switch (ssl->state) { - case MBEDTLS_SSL_HELLO_REQUEST: - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - break; - - /* - * <== ClientHello - */ - case MBEDTLS_SSL_CLIENT_HELLO: - ret = ssl_parse_client_hello(ssl); - break; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: - return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED; -#endif - - /* - * ==> ServerHello - * Certificate - * ( ServerKeyExchange ) - * ( CertificateRequest ) - * ServerHelloDone - */ - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_write_server_hello(ssl); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = mbedtls_ssl_write_certificate(ssl); - break; - - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - ret = ssl_write_server_key_exchange(ssl); - break; - - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_write_certificate_request(ssl); - break; - - case MBEDTLS_SSL_SERVER_HELLO_DONE: - ret = ssl_write_server_hello_done(ssl); - break; - - /* - * <== ( Certificate/Alert ) - * ClientKeyExchange - * ( CertificateVerify ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = mbedtls_ssl_parse_certificate(ssl); - break; - - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_parse_client_key_exchange(ssl); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_parse_certificate_verify(ssl); - break; - - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_parse_change_cipher_spec(ssl); - break; - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = mbedtls_ssl_parse_finished(ssl); - break; - - /* - * ==> ( NewSessionTicket ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl->handshake->new_session_ticket != 0) { - ret = ssl_write_new_session_ticket(ssl); - } else -#endif - ret = mbedtls_ssl_write_change_cipher_spec(ssl); - break; - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = mbedtls_ssl_write_finished(ssl); - break; - - case MBEDTLS_SSL_FLUSH_BUFFERS: - MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup(ssl); - break; - - default: - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - return ret; -} - -void mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order) -{ - conf->respect_cli_pref = order; -} - -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_2 */ diff --git a/vendor/mbedtls/library/ssl_tls13_client.c b/vendor/mbedtls/library/ssl_tls13_client.c deleted file mode 100644 index 752bc033f..000000000 --- a/vendor/mbedtls/library/ssl_tls13_client.c +++ /dev/null @@ -1,3190 +0,0 @@ -/* - * TLS 1.3 client-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#include - -#include "debug_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/platform.h" - -#include "ssl_misc.h" -#include "ssl_client.h" -#include "ssl_tls13_keys.h" -#include "ssl_debug_helpers.h" -#include "mbedtls/psa_util.h" - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) -#endif - -/* Write extensions */ - -/* - * ssl_tls13_write_supported_versions_ext(): - * - * struct { - * ProtocolVersion versions<2..254>; - * } SupportedVersions; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_supported_versions_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - unsigned char versions_len = (ssl->handshake->min_tls_version <= - MBEDTLS_SSL_VERSION_TLS1_2) ? 4 : 2; - - *out_len = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding supported versions extension")); - - /* Check if we have space to write the extension: - * - extension_type (2 bytes) - * - extension_data_length (2 bytes) - * - versions_length (1 byte ) - * - versions (2 or 4 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + versions_len); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, p, 0); - MBEDTLS_PUT_UINT16_BE(versions_len + 1, p, 2); - p += 4; - - /* Length of versions */ - *p++ = versions_len; - - /* Write values of supported versions. - * They are defined by the configuration. - * Currently, we advertise only TLS 1.3 or both TLS 1.3 and TLS 1.2. - */ - mbedtls_ssl_write_version(p, MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_VERSION_TLS1_3); - MBEDTLS_SSL_DEBUG_MSG(3, ("supported version: [3:4]")); - - - if (ssl->handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) { - mbedtls_ssl_write_version(p + 2, MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_VERSION_TLS1_2); - MBEDTLS_SSL_DEBUG_MSG(3, ("supported version: [3:3]")); - } - - *out_len = 5 + versions_len; - - mbedtls_ssl_tls13_set_hs_sent_ext_mask( - ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - ((void) ssl); - - MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 2); - if (mbedtls_ssl_read_version(buf, ssl->conf->transport) != - MBEDTLS_SSL_VERSION_TLS1_3) { - MBEDTLS_SSL_DEBUG_MSG(1, ("unexpected version")); - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - if (&buf[2] != end) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("supported_versions ext data length incorrect")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - return 0; -} - -#if defined(MBEDTLS_SSL_ALPN) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_alpn_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) -{ - const unsigned char *p = buf; - const unsigned char *end = buf + len; - size_t protocol_name_list_len, protocol_name_len; - const unsigned char *protocol_name_list_end; - - /* If we didn't send it, the server shouldn't send it */ - if (ssl->conf->alpn_list == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - * - * the "ProtocolNameList" MUST contain exactly one "ProtocolName" - */ - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - protocol_name_list_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, protocol_name_list_len); - protocol_name_list_end = p + protocol_name_list_len; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, protocol_name_list_end, 1); - protocol_name_len = *p++; - - /* Check that the server chosen protocol was in our list and save it */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, protocol_name_list_end, protocol_name_len); - for (const char **alpn = ssl->conf->alpn_list; *alpn != NULL; alpn++) { - if (protocol_name_len == strlen(*alpn) && - memcmp(p, *alpn, protocol_name_len) == 0) { - ssl->alpn_chosen = *alpn; - return 0; - } - } - - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; -} -#endif /* MBEDTLS_SSL_ALPN */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_reset_key_share(mbedtls_ssl_context *ssl) -{ - uint16_t group_id = ssl->handshake->offered_group_id; - - if (group_id == 0) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - if (mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) || - mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - /* Destroy generated private key. */ - status = psa_destroy_key(ssl->handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret); - return ret; - } - - ssl->handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; - return 0; - } else -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - if (0 /* other KEMs? */) { - /* Do something */ - } - - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} - -/* - * Functions for writing key_share extension. - */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_get_default_group_id(mbedtls_ssl_context *ssl, - uint16_t *group_id) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) - const uint16_t *group_list = mbedtls_ssl_get_groups(ssl); - /* Pick first available ECDHE group compatible with TLS 1.3 */ - if (group_list == NULL) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - - for (; *group_list != 0; group_list++) { -#if defined(PSA_WANT_ALG_ECDH) - if ((mbedtls_ssl_get_psa_curve_info_from_tls_id( - *group_list, NULL, NULL) == PSA_SUCCESS) && - mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) { - *group_id = *group_list; - return 0; - } -#endif -#if defined(PSA_WANT_ALG_FFDH) - if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) { - *group_id = *group_list; - return 0; - } -#endif - } -#else - ((void) ssl); - ((void) group_id); -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ - - return ret; -} - -/* - * ssl_tls13_write_key_share_ext - * - * Structure of key_share extension in ClientHello: - * - * struct { - * NamedGroup group; - * opaque key_exchange<1..2^16-1>; - * } KeyShareEntry; - * struct { - * KeyShareEntry client_shares<0..2^16-1>; - * } KeyShareClientHello; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - unsigned char *client_shares; /* Start of client_shares */ - size_t client_shares_len; /* Length of client_shares */ - uint16_t group_id; - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - *out_len = 0; - - /* Check if we have space for header and length fields: - * - extension_type (2 bytes) - * - extension_data_length (2 bytes) - * - client_shares_length (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - p += 6; - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello: adding key share extension")); - - /* HRR could already have requested something else. */ - group_id = ssl->handshake->offered_group_id; - if (!mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) && - !mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) { - MBEDTLS_SSL_PROC_CHK(ssl_tls13_get_default_group_id(ssl, - &group_id)); - } - - /* - * Dispatch to type-specific key generation function. - * - * So far, we're only supporting ECDHE. With the introduction - * of PQC KEMs, we'll want to have multiple branches, one per - * type of KEM, and dispatch to the corresponding crypto. And - * only one key share entry is allowed. - */ - client_shares = p; -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) - if (mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) || - mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) { - /* Pointer to group */ - unsigned char *group = p; - /* Length of key_exchange */ - size_t key_exchange_len = 0; - - /* Check there is space for header of KeyShareEntry - * - group (2 bytes) - * - key_exchange_length (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); - p += 4; - ret = mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange( - ssl, group_id, p, end, &key_exchange_len); - p += key_exchange_len; - if (ret != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("client hello: failed generating xxdh key exchange")); - return ret; - } - - /* Write group */ - MBEDTLS_PUT_UINT16_BE(group_id, group, 0); - /* Write key_exchange_length */ - MBEDTLS_PUT_UINT16_BE(key_exchange_len, group, 2); - } else -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ - if (0 /* other KEMs? */) { - /* Do something */ - } else { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Length of client_shares */ - client_shares_len = p - client_shares; - if (client_shares_len == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("No key share defined.")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - /* Write extension_type */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_KEY_SHARE, buf, 0); - /* Write extension_data_length */ - MBEDTLS_PUT_UINT16_BE(client_shares_len + 2, buf, 2); - /* Write client_shares_length */ - MBEDTLS_PUT_UINT16_BE(client_shares_len, buf, 4); - - /* Update offered_group_id field */ - ssl->handshake->offered_group_id = group_id; - - /* Output the total length of key_share extension. */ - *out_len = p - buf; - - MBEDTLS_SSL_DEBUG_BUF( - 3, "client hello, key_share extension", buf, *out_len); - - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_KEY_SHARE); - -cleanup: - - return ret; -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - -/* - * ssl_tls13_parse_hrr_key_share_ext() - * Parse key_share extension in Hello Retry Request - * - * struct { - * NamedGroup selected_group; - * } KeyShareHelloRetryRequest; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_hrr_key_share_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) - const unsigned char *p = buf; - int selected_group; - int found = 0; - - const uint16_t *group_list = mbedtls_ssl_get_groups(ssl); - if (group_list == NULL) { - return MBEDTLS_ERR_SSL_BAD_CONFIG; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "key_share extension", p, end - buf); - - /* Read selected_group */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - selected_group = MBEDTLS_GET_UINT16_BE(p, 0); - MBEDTLS_SSL_DEBUG_MSG(3, ("selected_group ( %d )", selected_group)); - - /* Upon receipt of this extension in a HelloRetryRequest, the client - * MUST first verify that the selected_group field corresponds to a - * group which was provided in the "supported_groups" extension in the - * original ClientHello. - * The supported_group was based on the info in ssl->conf->group_list. - * - * If the server provided a key share that was not sent in the ClientHello - * then the client MUST abort the handshake with an "illegal_parameter" alert. - */ - for (; *group_list != 0; group_list++) { -#if defined(PSA_WANT_ALG_ECDH) - if (mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) { - if ((mbedtls_ssl_get_psa_curve_info_from_tls_id( - *group_list, NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) || - *group_list != selected_group) { - found = 1; - break; - } - } -#endif /* PSA_WANT_ALG_ECDH */ -#if defined(PSA_WANT_ALG_FFDH) - if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) { - found = 1; - break; - } -#endif /* PSA_WANT_ALG_FFDH */ - } - - /* Client MUST verify that the selected_group field does not - * correspond to a group which was provided in the "key_share" - * extension in the original ClientHello. If the server sent an - * HRR message with a key share already provided in the - * ClientHello then the client MUST abort the handshake with - * an "illegal_parameter" alert. - */ - if (found == 0 || selected_group == ssl->handshake->offered_group_id) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid key share in HRR")); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - /* Remember server's preference for next ClientHello */ - ssl->handshake->offered_group_id = selected_group; - - return 0; -#else /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ - (void) ssl; - (void) buf; - (void) end; - return MBEDTLS_ERR_SSL_BAD_CONFIG; -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ -} - -/* - * ssl_tls13_parse_key_share_ext() - * Parse key_share extension in Server Hello - * - * struct { - * KeyShareEntry server_share; - * } KeyShareServerHello; - * struct { - * NamedGroup group; - * opaque key_exchange<1..2^16-1>; - * } KeyShareEntry; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_key_share_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - uint16_t group, offered_group; - - /* ... - * NamedGroup group; (2 bytes) - * ... - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - group = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* Check that the chosen group matches the one we offered. */ - offered_group = ssl->handshake->offered_group_id; - if (offered_group != group) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Invalid server key share, our group %u, their group %u", - (unsigned) offered_group, (unsigned) group)); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - if (mbedtls_ssl_tls13_named_group_is_ecdhe(group) || - mbedtls_ssl_tls13_named_group_is_ffdh(group)) { - MBEDTLS_SSL_DEBUG_MSG(2, - ("DHE group name: %s", mbedtls_ssl_named_group_to_str(group))); - ret = mbedtls_ssl_tls13_read_public_xxdhe_share(ssl, p, end - p); - if (ret != 0) { - return ret; - } - } else -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - if (0 /* other KEMs? */) { - /* Do something */ - } else { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - return ret; -} - -/* - * ssl_tls13_parse_cookie_ext() - * Parse cookie extension in Hello Retry Request - * - * struct { - * opaque cookie<1..2^16-1>; - * } Cookie; - * - * When sending a HelloRetryRequest, the server MAY provide a "cookie" - * extension to the client (this is an exception to the usual rule that - * the only extensions that may be sent are those that appear in the - * ClientHello). When sending the new ClientHello, the client MUST copy - * the contents of the extension received in the HelloRetryRequest into - * a "cookie" extension in the new ClientHello. Clients MUST NOT use - * cookies in their initial ClientHello in subsequent connections. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_cookie_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - uint16_t cookie_len; - const unsigned char *p = buf; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* Retrieve length field of cookie */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - cookie_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cookie_len); - MBEDTLS_SSL_DEBUG_BUF(3, "cookie extension", p, cookie_len); - - mbedtls_free(handshake->cookie); - handshake->cookie_len = 0; - handshake->cookie = mbedtls_calloc(1, cookie_len); - if (handshake->cookie == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("alloc failed ( %ud bytes )", - cookie_len)); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(handshake->cookie, p, cookie_len); - handshake->cookie_len = cookie_len; - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_cookie_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - *out_len = 0; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - if (handshake->cookie == NULL) { - MBEDTLS_SSL_DEBUG_MSG(3, ("no cookie to send; skip extension")); - return 0; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie", - handshake->cookie, - handshake->cookie_len); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, handshake->cookie_len + 6); - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding cookie extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_COOKIE, p, 0); - MBEDTLS_PUT_UINT16_BE(handshake->cookie_len + 2, p, 2); - MBEDTLS_PUT_UINT16_BE(handshake->cookie_len, p, 4); - p += 6; - - /* Cookie */ - memcpy(p, handshake->cookie, handshake->cookie_len); - - *out_len = handshake->cookie_len + 6; - - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_COOKIE); - - return 0; -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -/* - * ssl_tls13_write_psk_key_exchange_modes_ext() structure: - * - * enum { psk_ke( 0 ), psk_dhe_ke( 1 ), ( 255 ) } PskKeyExchangeMode; - * - * struct { - * PskKeyExchangeMode ke_modes<1..255>; - * } PskKeyExchangeModes; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_psk_key_exchange_modes_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - int ke_modes_len = 0; - - ((void) ke_modes_len); - *out_len = 0; - - /* Skip writing extension if no PSK key exchange mode - * is enabled in the config. - */ - if (!mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(3, ("skip psk_key_exchange_modes extension")); - return 0; - } - - /* Require 7 bytes of data, otherwise fail, - * even if extension might be shorter. - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 7); - MBEDTLS_SSL_DEBUG_MSG( - 3, ("client hello, adding psk_key_exchange_modes extension")); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES, p, 0); - - /* Skip extension length (2 bytes) and - * ke_modes length (1 byte) for now. - */ - p += 5; - - if (mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl)) { - *p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE; - ke_modes_len++; - - MBEDTLS_SSL_DEBUG_MSG(4, ("Adding PSK-ECDHE key exchange mode")); - } - - if (mbedtls_ssl_conf_tls13_is_psk_enabled(ssl)) { - *p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE; - ke_modes_len++; - - MBEDTLS_SSL_DEBUG_MSG(4, ("Adding pure PSK key exchange mode")); - } - - /* Now write the extension and ke_modes length */ - MBEDTLS_PUT_UINT16_BE(ke_modes_len + 1, buf, 2); - buf[4] = ke_modes_len; - - *out_len = p - buf; - - mbedtls_ssl_tls13_set_hs_sent_ext_mask( - ssl, MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES); - - return 0; -} - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL; - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite); - - if (ciphersuite_info != NULL) { - return mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); - } - - return PSA_ALG_NONE; -} - -static int ssl_tls13_has_configured_ticket(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_session *session = ssl->session_negotiate; - return ssl->handshake->resume && - session != NULL && session->ticket != NULL && - mbedtls_ssl_conf_tls13_is_kex_mode_enabled( - ssl, mbedtls_ssl_tls13_session_get_ticket_flags( - session, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL)); -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) -static int ssl_tls13_early_data_has_valid_ticket(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_session *session = ssl->session_negotiate; - return ssl->handshake->resume && - session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 && - mbedtls_ssl_tls13_session_ticket_allow_early_data(session) && - mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, session->ciphersuite); -} -#endif - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_ticket_get_identity(mbedtls_ssl_context *ssl, - psa_algorithm_t *hash_alg, - const unsigned char **identity, - size_t *identity_len) -{ - mbedtls_ssl_session *session = ssl->session_negotiate; - - if (!ssl_tls13_has_configured_ticket(ssl)) { - return -1; - } - - *hash_alg = ssl_tls13_get_ciphersuite_hash_alg(session->ciphersuite); - *identity = session->ticket; - *identity_len = session->ticket_len; - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_ticket_get_psk(mbedtls_ssl_context *ssl, - psa_algorithm_t *hash_alg, - const unsigned char **psk, - size_t *psk_len) -{ - - mbedtls_ssl_session *session = ssl->session_negotiate; - - if (!ssl_tls13_has_configured_ticket(ssl)) { - return -1; - } - - *hash_alg = ssl_tls13_get_ciphersuite_hash_alg(session->ciphersuite); - *psk = session->resumption_key; - *psk_len = session->resumption_key_len; - - return 0; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_psk_get_identity(mbedtls_ssl_context *ssl, - psa_algorithm_t *hash_alg, - const unsigned char **identity, - size_t *identity_len) -{ - - if (!mbedtls_ssl_conf_has_static_psk(ssl->conf)) { - return -1; - } - - *hash_alg = PSA_ALG_SHA_256; - *identity = ssl->conf->psk_identity; - *identity_len = ssl->conf->psk_identity_len; - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_psk_get_psk(mbedtls_ssl_context *ssl, - psa_algorithm_t *hash_alg, - const unsigned char **psk, - size_t *psk_len) -{ - - if (!mbedtls_ssl_conf_has_static_psk(ssl->conf)) { - return -1; - } - - *hash_alg = PSA_ALG_SHA_256; - *psk = ssl->conf->psk; - *psk_len = ssl->conf->psk_len; - return 0; -} - -static int ssl_tls13_get_configured_psk_count(mbedtls_ssl_context *ssl) -{ - int configured_psk_count = 0; -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl_tls13_has_configured_ticket(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket is configured")); - configured_psk_count++; - } -#endif - if (mbedtls_ssl_conf_has_static_psk(ssl->conf)) { - MBEDTLS_SSL_DEBUG_MSG(3, ("PSK is configured")); - configured_psk_count++; - } - return configured_psk_count; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_identity(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - const unsigned char *identity, - size_t identity_len, - uint32_t obfuscated_ticket_age, - size_t *out_len) -{ - ((void) ssl); - *out_len = 0; - - /* - * - identity_len (2 bytes) - * - identity (psk_identity_len bytes) - * - obfuscated_ticket_age (4 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 6 + identity_len); - - MBEDTLS_PUT_UINT16_BE(identity_len, buf, 0); - memcpy(buf + 2, identity, identity_len); - MBEDTLS_PUT_UINT32_BE(obfuscated_ticket_age, buf, 2 + identity_len); - - MBEDTLS_SSL_DEBUG_BUF(4, "write identity", buf, 6 + identity_len); - - *out_len = 6 + identity_len; - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_binder(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - int psk_type, - psa_algorithm_t hash_alg, - const unsigned char *psk, - size_t psk_len, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char binder_len; - unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t transcript_len = 0; - - *out_len = 0; - - binder_len = PSA_HASH_LENGTH(hash_alg); - - /* - * - binder_len (1 bytes) - * - binder (binder_len bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 1 + binder_len); - - buf[0] = binder_len; - - /* Get current state of handshake transcript. */ - ret = mbedtls_ssl_get_handshake_transcript( - ssl, mbedtls_md_type_from_psa_alg(hash_alg), - transcript, sizeof(transcript), &transcript_len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_create_psk_binder(ssl, hash_alg, - psk, psk_len, psk_type, - transcript, buf + 1); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_create_psk_binder", ret); - return ret; - } - MBEDTLS_SSL_DEBUG_BUF(4, "write binder", buf, 1 + binder_len); - - *out_len = 1 + binder_len; - - return 0; -} - -/* - * mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext() structure: - * - * struct { - * opaque identity<1..2^16-1>; - * uint32 obfuscated_ticket_age; - * } PskIdentity; - * - * opaque PskBinderEntry<32..255>; - * - * struct { - * PskIdentity identities<7..2^16-1>; - * PskBinderEntry binders<33..2^16-1>; - * } OfferedPsks; - * - * struct { - * select (Handshake.msg_type) { - * case client_hello: OfferedPsks; - * ... - * }; - * } PreSharedKeyExtension; - * - */ -int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext( - mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end, - size_t *out_len, size_t *binders_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int configured_psk_count = 0; - unsigned char *p = buf; - psa_algorithm_t hash_alg = PSA_ALG_NONE; - const unsigned char *identity; - size_t identity_len; - size_t l_binders_len = 0; - size_t output_len; - - *out_len = 0; - *binders_len = 0; - - /* Check if we have any PSKs to offer. If no, skip pre_shared_key */ - configured_psk_count = ssl_tls13_get_configured_psk_count(ssl); - if (configured_psk_count == 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("skip pre_shared_key extensions")); - return 0; - } - - MBEDTLS_SSL_DEBUG_MSG(4, ("Pre-configured PSK number = %d", - configured_psk_count)); - - /* Check if we have space to write the extension, binders included. - * - extension_type (2 bytes) - * - extension_data_len (2 bytes) - * - identities_len (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - p += 6; - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl_tls13_ticket_get_identity( - ssl, &hash_alg, &identity, &identity_len) == 0) { -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_ms_time_t now = mbedtls_ms_time(); - mbedtls_ssl_session *session = ssl->session_negotiate; - /* The ticket age has been checked to be smaller than the - * `ticket_lifetime` in ssl_prepare_client_hello() which is smaller than - * 7 days (enforced in ssl_tls13_parse_new_session_ticket()) . Thus the - * cast to `uint32_t` of the ticket age is safe. */ - uint32_t obfuscated_ticket_age = - (uint32_t) (now - session->ticket_reception_time); - obfuscated_ticket_age += session->ticket_age_add; - - ret = ssl_tls13_write_identity(ssl, p, end, - identity, identity_len, - obfuscated_ticket_age, - &output_len); -#else - ret = ssl_tls13_write_identity(ssl, p, end, identity, identity_len, - 0, &output_len); -#endif /* MBEDTLS_HAVE_TIME */ - if (ret != 0) { - return ret; - } - - p += output_len; - l_binders_len += 1 + PSA_HASH_LENGTH(hash_alg); - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - if (ssl_tls13_psk_get_identity( - ssl, &hash_alg, &identity, &identity_len) == 0) { - - ret = ssl_tls13_write_identity(ssl, p, end, identity, identity_len, 0, - &output_len); - if (ret != 0) { - return ret; - } - - p += output_len; - l_binders_len += 1 + PSA_HASH_LENGTH(hash_alg); - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("client hello, adding pre_shared_key extension, " - "omitting PSK binder list")); - - /* Take into account the two bytes for the length of the binders. */ - l_binders_len += 2; - /* Check if there is enough space for binders */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, l_binders_len); - - /* - * - extension_type (2 bytes) - * - extension_data_len (2 bytes) - * - identities_len (2 bytes) - */ - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_PRE_SHARED_KEY, buf, 0); - MBEDTLS_PUT_UINT16_BE(p - buf - 4 + l_binders_len, buf, 2); - MBEDTLS_PUT_UINT16_BE(p - buf - 6, buf, 4); - - *out_len = (p - buf) + l_binders_len; - *binders_len = l_binders_len; - - MBEDTLS_SSL_DEBUG_BUF(3, "pre_shared_key identities", buf, p - buf); - - return 0; -} - -int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext( - mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - psa_algorithm_t hash_alg = PSA_ALG_NONE; - const unsigned char *psk; - size_t psk_len; - size_t output_len; - - /* Check if we have space to write binders_len. - * - binders_len (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - p += 2; - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len) == 0) { - - ret = ssl_tls13_write_binder(ssl, p, end, - MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION, - hash_alg, psk, psk_len, - &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - if (ssl_tls13_psk_get_psk(ssl, &hash_alg, &psk, &psk_len) == 0) { - - ret = ssl_tls13_write_binder(ssl, p, end, - MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL, - hash_alg, psk, psk_len, - &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding PSK binder list.")); - - /* - * - binders_len (2 bytes) - */ - MBEDTLS_PUT_UINT16_BE(p - buf - 2, buf, 0); - - MBEDTLS_SSL_DEBUG_BUF(3, "pre_shared_key binders", buf, p - buf); - - mbedtls_ssl_tls13_set_hs_sent_ext_mask( - ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY); - - return 0; -} - -/* - * struct { - * opaque identity<1..2^16-1>; - * uint32 obfuscated_ticket_age; - * } PskIdentity; - * - * opaque PskBinderEntry<32..255>; - * - * struct { - * - * select (Handshake.msg_type) { - * ... - * case server_hello: uint16 selected_identity; - * }; - * - * } PreSharedKeyExtension; - * - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_server_pre_shared_key_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int selected_identity; - const unsigned char *psk; - size_t psk_len; - psa_algorithm_t hash_alg; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 2); - selected_identity = MBEDTLS_GET_UINT16_BE(buf, 0); - ssl->handshake->selected_identity = (uint16_t) selected_identity; - - MBEDTLS_SSL_DEBUG_MSG(3, ("selected_identity = %d", selected_identity)); - - if (selected_identity >= ssl_tls13_get_configured_psk_count(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid PSK identity.")); - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (selected_identity == 0 && ssl_tls13_has_configured_ticket(ssl)) { - ret = ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len); - } else -#endif - if (mbedtls_ssl_conf_has_static_psk(ssl->conf)) { - ret = ssl_tls13_psk_get_psk(ssl, &hash_alg, &psk, &psk_len); - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - if (ret != 0) { - return ret; - } - - if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac) - != hash_alg) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Invalid ciphersuite for external psk.")); - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret); - return ret; - } - - return 0; -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - -int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - size_t ext_len; - - *out_len = 0; - - ret = mbedtls_ssl_tls13_crypto_init(ssl); - if (ret != 0) { - return ret; - } - - /* Write supported_versions extension - * - * Supported Versions Extension is mandatory with TLS 1.3. - */ - ret = ssl_tls13_write_supported_versions_ext(ssl, p, end, &ext_len); - if (ret != 0) { - return ret; - } - p += ext_len; - - /* Echo the cookie if the server provided one in its preceding - * HelloRetryRequest message. - */ - ret = ssl_tls13_write_cookie_ext(ssl, p, end, &ext_len); - if (ret != 0) { - return ret; - } - p += ext_len; - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - ret = mbedtls_ssl_tls13_write_record_size_limit_ext( - ssl, p, end, &ext_len); - if (ret != 0) { - return ret; - } - p += ext_len; -#endif - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) { - ret = ssl_tls13_write_key_share_ext(ssl, p, end, &ext_len); - if (ret != 0) { - return ret; - } - p += ext_len; - } -#endif - -#if defined(MBEDTLS_SSL_EARLY_DATA) - /* In the first ClientHello, write the early data indication extension if - * necessary and update the early data state. - * If an HRR has been received and thus we are currently writing the - * second ClientHello, the second ClientHello must not contain an early - * data extension and the early data state must stay as it is: - * MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT or - * MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED. - */ - if (!ssl->handshake->hello_retry_request_flag) { - if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) && - ssl_tls13_early_data_has_valid_ticket(ssl) && - ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) { - ret = mbedtls_ssl_tls13_write_early_data_ext( - ssl, 0, p, end, &ext_len); - if (ret != 0) { - return ret; - } - p += ext_len; - - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT; - } else { - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT; - } - } -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - /* For PSK-based key exchange we need the pre_shared_key extension - * and the psk_key_exchange_modes extension. - * - * The pre_shared_key extension MUST be the last extension in the - * ClientHello. Servers MUST check that it is the last extension and - * otherwise fail the handshake with an "illegal_parameter" alert. - * - * Add the psk_key_exchange_modes extension. - */ - ret = ssl_tls13_write_psk_key_exchange_modes_ext(ssl, p, end, &ext_len); - if (ret != 0) { - return ret; - } - p += ext_len; -#endif - - *out_len = p - buf; - - return 0; -} - -int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) -{ - ((void) ssl); - -#if defined(MBEDTLS_SSL_EARLY_DATA) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_algorithm_t hash_alg = PSA_ALG_NONE; - const unsigned char *psk; - size_t psk_len; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - - if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Set hs psk for early data when writing the first psk")); - - ret = ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_ticket_get_psk", ret); - return ret; - } - - ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret); - return ret; - } - - /* - * Early data are going to be encrypted using the ciphersuite - * associated with the pre-shared key used for the handshake. - * Note that if the server rejects early data, the handshake - * based on the pre-shared key may complete successfully - * with a selected ciphersuite different from the ciphersuite - * associated with the pre-shared key. Only the hashes of the - * two ciphersuites have to be the same. In that case, the - * encrypted handshake data and application data are - * encrypted using a different ciphersuite than the one used for - * the rejected early data. - */ - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( - ssl->session_negotiate->ciphersuite); - ssl->handshake->ciphersuite_info = ciphersuite_info; - - /* Enable psk and psk_ephemeral to make stage early happy */ - ssl->handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL; - - /* Start the TLS 1.3 key schedule: - * Set the PSK and derive early secret. - */ - ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret); - return ret; - } - - /* Derive early data key material */ - ret = mbedtls_ssl_tls13_compute_early_transform(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_compute_early_transform", ret); - return ret; - } - -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO); -#else - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Switch to early data keys for outbound traffic")); - mbedtls_ssl_set_outbound_transform( - ssl, ssl->handshake->transform_earlydata); - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE; -#endif - } -#endif /* MBEDTLS_SSL_EARLY_DATA */ - return 0; -} -/* - * Functions for parsing and processing Server Hello - */ - -/** - * \brief Detect if the ServerHello contains a supported_versions extension - * or not. - * - * \param[in] ssl SSL context - * \param[in] buf Buffer containing the ServerHello message - * \param[in] end End of the buffer containing the ServerHello message - * - * \return 0 if the ServerHello does not contain a supported_versions extension - * \return 1 if the ServerHello contains a supported_versions extension - * \return A negative value if an error occurred while parsing the ServerHello. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_is_supported_versions_ext_present( - mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - const unsigned char *p = buf; - size_t legacy_session_id_echo_len; - const unsigned char *supported_versions_data; - const unsigned char *supported_versions_data_end; - - /* - * Check there is enough data to access the legacy_session_id_echo vector - * length: - * - legacy_version 2 bytes - * - random MBEDTLS_SERVER_HELLO_RANDOM_LEN bytes - * - legacy_session_id_echo length 1 byte - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 3); - p += MBEDTLS_SERVER_HELLO_RANDOM_LEN + 2; - legacy_session_id_echo_len = *p; - - /* - * Jump to the extensions, jumping over: - * - legacy_session_id_echo (legacy_session_id_echo_len + 1) bytes - * - cipher_suite 2 bytes - * - legacy_compression_method 1 byte - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len + 4); - p += legacy_session_id_echo_len + 4; - - return mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( - ssl, p, end, - &supported_versions_data, &supported_versions_data_end); -} - -/* Returns a negative value on failure, and otherwise - * - 1 if the last eight bytes of the ServerHello random bytes indicate that - * the server is TLS 1.3 capable but negotiating TLS 1.2 or below. - * - 0 otherwise - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_is_downgrade_negotiation(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - /* First seven bytes of the magic downgrade strings, see RFC 8446 4.1.3 */ - static const unsigned char magic_downgrade_string[] = - { 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44 }; - const unsigned char *last_eight_bytes_of_random; - unsigned char last_byte_of_random; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 2); - last_eight_bytes_of_random = buf + 2 + MBEDTLS_SERVER_HELLO_RANDOM_LEN - 8; - - if (memcmp(last_eight_bytes_of_random, - magic_downgrade_string, - sizeof(magic_downgrade_string)) == 0) { - last_byte_of_random = last_eight_bytes_of_random[7]; - return last_byte_of_random == 0 || - last_byte_of_random == 1; - } - - return 0; -} - -/* Returns a negative value on failure, and otherwise - * - SSL_SERVER_HELLO or - * - SSL_SERVER_HELLO_HRR - * to indicate which message is expected and to be parsed next. - */ -#define SSL_SERVER_HELLO 0 -#define SSL_SERVER_HELLO_HRR 1 -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_server_hello_is_hrr(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - - /* Check whether this message is a HelloRetryRequest ( HRR ) message. - * - * Server Hello and HRR are only distinguished by Random set to the - * special value of the SHA-256 of "HelloRetryRequest". - * - * struct { - * ProtocolVersion legacy_version = 0x0303; - * Random random; - * opaque legacy_session_id_echo<0..32>; - * CipherSuite cipher_suite; - * uint8 legacy_compression_method = 0; - * Extension extensions<6..2^16-1>; - * } ServerHello; - * - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR( - buf, end, 2 + sizeof(mbedtls_ssl_tls13_hello_retry_request_magic)); - - if (memcmp(buf + 2, mbedtls_ssl_tls13_hello_retry_request_magic, - sizeof(mbedtls_ssl_tls13_hello_retry_request_magic)) == 0) { - return SSL_SERVER_HELLO_HRR; - } - - return SSL_SERVER_HELLO; -} - -/* - * Returns a negative value on failure, and otherwise - * - SSL_SERVER_HELLO or - * - SSL_SERVER_HELLO_HRR or - * - SSL_SERVER_HELLO_TLS1_2 - */ -#define SSL_SERVER_HELLO_TLS1_2 2 -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_is_supported_versions_ext_present( - ssl, buf, end)); - - if (ret == 0) { - MBEDTLS_SSL_PROC_CHK_NEG( - ssl_tls13_is_downgrade_negotiation(ssl, buf, end)); - - /* If the server is negotiating TLS 1.2 or below and: - * . we did not propose TLS 1.2 or - * . the server responded it is TLS 1.3 capable but negotiating a lower - * version of the protocol and thus we are under downgrade attack - * abort the handshake with an "illegal parameter" alert. - */ - if (handshake->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 || ret) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - /* - * Version 1.2 of the protocol has been negotiated, set the - * ssl->keep_current_message flag for the ServerHello to be kept and - * parsed as a TLS 1.2 ServerHello. We also change ssl->tls_version to - * MBEDTLS_SSL_VERSION_TLS1_2 thus from now on mbedtls_ssl_handshake_step() - * will dispatch to the TLS 1.2 state machine. - */ - ssl->keep_current_message = 1; - ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2; - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, - buf, (size_t) (end - buf))); - - if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) { - ret = ssl_tls13_reset_key_share(ssl); - if (ret != 0) { - return ret; - } - } - - return SSL_SERVER_HELLO_TLS1_2; - } - - ssl->session_negotiate->tls_version = ssl->tls_version; - ssl->session_negotiate->endpoint = ssl->conf->endpoint; - - handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - ret = ssl_server_hello_is_hrr(ssl, buf, end); - switch (ret) { - case SSL_SERVER_HELLO: - MBEDTLS_SSL_DEBUG_MSG(2, ("received ServerHello message")); - break; - case SSL_SERVER_HELLO_HRR: - MBEDTLS_SSL_DEBUG_MSG(2, ("received HelloRetryRequest message")); - /* If a client receives a second HelloRetryRequest in the same - * connection (i.e., where the ClientHello was itself in response - * to a HelloRetryRequest), it MUST abort the handshake with an - * "unexpected_message" alert. - */ - if (handshake->hello_retry_request_flag) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received")); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE, - MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - /* - * Clients must abort the handshake with an "illegal_parameter" - * alert if the HelloRetryRequest would not result in any change - * in the ClientHello. - * In a PSK only key exchange that what we expect. - */ - if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Unexpected HRR in pure PSK key exchange.")); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - handshake->hello_retry_request_flag = 1; - - break; - } - -cleanup: - - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_check_server_hello_session_id_echo(mbedtls_ssl_context *ssl, - const unsigned char **buf, - const unsigned char *end) -{ - const unsigned char *p = *buf; - size_t legacy_session_id_echo_len; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1); - legacy_session_id_echo_len = *p++; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len); - - /* legacy_session_id_echo */ - if (ssl->session_negotiate->id_len != legacy_session_id_echo_len || - memcmp(ssl->session_negotiate->id, p, legacy_session_id_echo_len) != 0) { - MBEDTLS_SSL_DEBUG_BUF(3, "Expected Session ID", - ssl->session_negotiate->id, - ssl->session_negotiate->id_len); - MBEDTLS_SSL_DEBUG_BUF(3, "Received Session ID", p, - legacy_session_id_echo_len); - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - p += legacy_session_id_echo_len; - *buf = p; - - MBEDTLS_SSL_DEBUG_BUF(3, "Session ID", ssl->session_negotiate->id, - ssl->session_negotiate->id_len); - return 0; -} - -/* Parse ServerHello message and configure context - * - * struct { - * ProtocolVersion legacy_version = 0x0303; // TLS 1.2 - * Random random; - * opaque legacy_session_id_echo<0..32>; - * CipherSuite cipher_suite; - * uint8 legacy_compression_method = 0; - * Extension extensions<6..2^16-1>; - * } ServerHello; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_server_hello(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end, - int is_hrr) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - size_t extensions_len; - const unsigned char *extensions_end; - uint16_t cipher_suite; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - int fatal_alert = 0; - uint32_t allowed_extensions_mask; - int hs_msg_type = is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST : - MBEDTLS_SSL_HS_SERVER_HELLO; - - /* - * Check there is space for minimal fields - * - * - legacy_version ( 2 bytes) - * - random (MBEDTLS_SERVER_HELLO_RANDOM_LEN bytes) - * - legacy_session_id_echo ( 1 byte ), minimum size - * - cipher_suite ( 2 bytes) - * - legacy_compression_method ( 1 byte ) - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 6); - - MBEDTLS_SSL_DEBUG_BUF(4, "server hello", p, end - p); - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", p, 2); - - /* ... - * ProtocolVersion legacy_version = 0x0303; // TLS 1.2 - * ... - * with ProtocolVersion defined as: - * uint16 ProtocolVersion; - */ - if (mbedtls_ssl_read_version(p, ssl->conf->transport) != - MBEDTLS_SSL_VERSION_TLS1_2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Unsupported version of TLS.")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION, - MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION); - ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - goto cleanup; - } - p += 2; - - /* ... - * Random random; - * ... - * with Random defined as: - * opaque Random[MBEDTLS_SERVER_HELLO_RANDOM_LEN]; - */ - if (!is_hrr) { - memcpy(&handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN], p, - MBEDTLS_SERVER_HELLO_RANDOM_LEN); - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", - p, MBEDTLS_SERVER_HELLO_RANDOM_LEN); - } - p += MBEDTLS_SERVER_HELLO_RANDOM_LEN; - - /* ... - * opaque legacy_session_id_echo<0..32>; - * ... - */ - if (ssl_tls13_check_server_hello_session_id_echo(ssl, &p, end) != 0) { - fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; - goto cleanup; - } - - /* ... - * CipherSuite cipher_suite; - * ... - * with CipherSuite defined as: - * uint8 CipherSuite[2]; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(cipher_suite); - /* - * Check whether this ciphersuite is valid and offered. - */ - if ((mbedtls_ssl_validate_ciphersuite(ssl, ciphersuite_info, - ssl->tls_version, - ssl->tls_version) != 0) || - !mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, cipher_suite)) { - fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; - } - /* - * If we received an HRR before and that the proposed selected - * ciphersuite in this server hello is not the same as the one - * proposed in the HRR, we abort the handshake and send an - * "illegal_parameter" alert. - */ - else if ((!is_hrr) && handshake->hello_retry_request_flag && - (cipher_suite != ssl->session_negotiate->ciphersuite)) { - fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; - } - - if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER) { - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid ciphersuite(%04x) parameter", - cipher_suite)); - goto cleanup; - } - - /* Configure ciphersuites */ - mbedtls_ssl_optimize_checksum(ssl, ciphersuite_info); - - handshake->ciphersuite_info = ciphersuite_info; - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: ( %04x ) - %s", - cipher_suite, ciphersuite_info->name)); - -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time(NULL); -#endif /* MBEDTLS_HAVE_TIME */ - - /* ... - * uint8 legacy_compression_method = 0; - * ... - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1); - if (p[0] != MBEDTLS_SSL_COMPRESS_NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad legacy compression method")); - fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; - goto cleanup; - } - p++; - - /* ... - * Extension extensions<6..2^16-1>; - * ... - * struct { - * ExtensionType extension_type; (2 bytes) - * opaque extension_data<0..2^16-1>; - * } Extension; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* Check extensions do not go beyond the buffer of data. */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); - extensions_end = p + extensions_len; - - MBEDTLS_SSL_DEBUG_BUF(3, "server hello extensions", p, extensions_len); - - handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - allowed_extensions_mask = is_hrr ? - MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR : - MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH; - - while (p < extensions_end) { - unsigned int extension_type; - size_t extension_data_len; - const unsigned char *extension_data_end; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); - extension_data_end = p + extension_data_len; - - ret = mbedtls_ssl_tls13_check_received_extension( - ssl, hs_msg_type, extension_type, allowed_extensions_mask); - if (ret != 0) { - return ret; - } - - switch (extension_type) { - case MBEDTLS_TLS_EXT_COOKIE: - - ret = ssl_tls13_parse_cookie_ext(ssl, - p, extension_data_end); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "ssl_tls13_parse_cookie_ext", - ret); - goto cleanup; - } - break; - - case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS: - ret = ssl_tls13_parse_supported_versions_ext(ssl, - p, - extension_data_end); - if (ret != 0) { - goto cleanup; - } - break; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - case MBEDTLS_TLS_EXT_PRE_SHARED_KEY: - MBEDTLS_SSL_DEBUG_MSG(3, ("found pre_shared_key extension")); - - if ((ret = ssl_tls13_parse_server_pre_shared_key_ext( - ssl, p, extension_data_end)) != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, ("ssl_tls13_parse_server_pre_shared_key_ext"), ret); - return ret; - } - break; -#endif - - case MBEDTLS_TLS_EXT_KEY_SHARE: - MBEDTLS_SSL_DEBUG_MSG(3, ("found key_shares extension")); - if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) { - fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT; - goto cleanup; - } - - if (is_hrr) { - ret = ssl_tls13_parse_hrr_key_share_ext(ssl, - p, extension_data_end); - } else { - ret = ssl_tls13_parse_key_share_ext(ssl, - p, extension_data_end); - } - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "ssl_tls13_parse_key_share_ext", - ret); - goto cleanup; - } - break; - - default: - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - p += extension_data_len; - } - - MBEDTLS_SSL_PRINT_EXTS(3, hs_msg_type, handshake->received_extensions); - -cleanup: - - if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT, - MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION); - ret = MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; - } else if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - ret = MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - return ret; -} - -#if defined(MBEDTLS_DEBUG_C) -static const char *ssl_tls13_get_kex_mode_str(int mode) -{ - switch (mode) { - case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK: - return "psk"; - case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL: - return "ephemeral"; - case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL: - return "psk_ephemeral"; - default: - return "unknown mode"; - } -} -#endif /* MBEDTLS_DEBUG_C */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* Determine the key exchange mode: - * 1) If both the pre_shared_key and key_share extensions were received - * then the key exchange mode is PSK with EPHEMERAL. - * 2) If only the pre_shared_key extension was received then the key - * exchange mode is PSK-only. - * 3) If only the key_share extension was received then the key - * exchange mode is EPHEMERAL-only. - */ - switch (handshake->received_extensions & - (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | - MBEDTLS_SSL_EXT_MASK(KEY_SHARE))) { - /* Only the pre_shared_key extension was received */ - case MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY): - handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; - break; - - /* Only the key_share extension was received */ - case MBEDTLS_SSL_EXT_MASK(KEY_SHARE): - handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL; - break; - - /* Both the pre_shared_key and key_share extensions were received */ - case (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | - MBEDTLS_SSL_EXT_MASK(KEY_SHARE)): - handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; - break; - - /* Neither pre_shared_key nor key_share extension was received */ - default: - MBEDTLS_SSL_DEBUG_MSG(1, ("Unknown key exchange.")); - ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - goto cleanup; - } - - if (!mbedtls_ssl_conf_tls13_is_kex_mode_enabled( - ssl, handshake->key_exchange_mode)) { - ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - MBEDTLS_SSL_DEBUG_MSG( - 2, ("Key exchange mode(%s) is not supported.", - ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode))); - goto cleanup; - } - - MBEDTLS_SSL_DEBUG_MSG( - 3, ("Selected key exchange mode: %s", - ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode))); - - /* Start the TLS 1.3 key scheduling if not already done. - * - * If we proposed early data then we have already derived an - * early secret using the selected PSK and its associated hash. - * It means that if the negotiated key exchange mode is psk or - * psk_ephemeral, we have already correctly computed the - * early secret and thus we do not do it again. In all other - * cases we compute it here. - */ -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT || - handshake->key_exchange_mode == - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) -#endif - { - ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret); - goto cleanup; - } - } - - ret = mbedtls_ssl_tls13_compute_handshake_transform(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "mbedtls_ssl_tls13_compute_handshake_transform", - ret); - goto cleanup; - } - - mbedtls_ssl_set_inbound_transform(ssl, handshake->transform_handshake); - MBEDTLS_SSL_DEBUG_MSG(1, ("Switch to handshake keys for inbound traffic")); - ssl->session_in = ssl->session_negotiate; - -cleanup: - if (ret != 0) { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - } - - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - mbedtls_ssl_session_reset_msg_layer(ssl, 0); - - /* - * We are going to re-generate a shared secret corresponding to the group - * selected by the server, which is different from the group for which we - * generated a shared secret in the first client hello. - * Thus, reset the shared secret. - */ - ret = ssl_tls13_reset_key_share(ssl); - if (ret != 0) { - return ret; - } - - ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) { - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED; - } -#endif - - return 0; -} - -/* - * Wait and parse ServerHello handshake message. - * Handler for MBEDTLS_SSL_SERVER_HELLO - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf = NULL; - size_t buf_len = 0; - int is_hrr = 0; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> %s", __func__)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len)); - - ret = ssl_tls13_preprocess_server_hello(ssl, buf, buf + buf_len); - if (ret < 0) { - goto cleanup; - } else { - is_hrr = (ret == SSL_SERVER_HELLO_HRR); - } - - if (ret == SSL_SERVER_HELLO_TLS1_2) { - ret = 0; - goto cleanup; - } - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_server_hello(ssl, buf, - buf + buf_len, - is_hrr)); - if (is_hrr) { - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl)); - } - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, buf_len)); - - if (is_hrr) { - MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl)); -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - /* If not offering early data, the client sends a dummy CCS record - * immediately before its second flight. This may either be before - * its second ClientHello or before its encrypted handshake flight. - */ - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO); -#else - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - } else { - MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_server_hello(ssl)); - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS); - } - -cleanup: - MBEDTLS_SSL_DEBUG_MSG(2, ("<= %s ( %s )", __func__, - is_hrr ? "HelloRetryRequest" : "ServerHello")); - return ret; -} - -/* - * - * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS - * - * The EncryptedExtensions message contains any extensions which - * should be protected, i.e., any which are not needed to establish - * the cryptographic context. - */ - -/* Parse EncryptedExtensions message - * struct { - * Extension extensions<0..2^16-1>; - * } EncryptedExtensions; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = 0; - size_t extensions_len; - const unsigned char *p = buf; - const unsigned char *extensions_end; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); - extensions_end = p + extensions_len; - - MBEDTLS_SSL_DEBUG_BUF(3, "encrypted extensions", p, extensions_len); - - handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - while (p < extensions_end) { - unsigned int extension_type; - size_t extension_data_len; - - /* - * struct { - * ExtensionType extension_type; (2 bytes) - * opaque extension_data<0..2^16-1>; - * } Extension; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); - - ret = mbedtls_ssl_tls13_check_received_extension( - ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, extension_type, - MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE); - if (ret != 0) { - return ret; - } - - switch (extension_type) { -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension")); - - if ((ret = ssl_tls13_parse_alpn_ext( - ssl, p, (size_t) extension_data_len)) != 0) { - return ret; - } - - break; -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) - case MBEDTLS_TLS_EXT_EARLY_DATA: - - if (extension_data_len != 0) { - /* The message must be empty. */ - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - break; -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT: - MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension")); - - ret = mbedtls_ssl_tls13_parse_record_size_limit_ext( - ssl, p, p + extension_data_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, ("mbedtls_ssl_tls13_parse_record_size_limit_ext"), ret); - return ret; - } - break; -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - - default: - MBEDTLS_SSL_PRINT_EXT( - 3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, - extension_type, "( ignored )"); - break; - } - - p += extension_data_len; - } - - if ((handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT)) && - (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(MAX_FRAGMENT_LENGTH))) { - MBEDTLS_SSL_DEBUG_MSG(3, - ( - "Record size limit extension cannot be used with max fragment length extension")); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, - handshake->received_extensions); - - /* Check that we consumed all the message. */ - if (p != end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("EncryptedExtension lengths misaligned")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) -{ - int ret; - unsigned char *buf; - size_t buf_len; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse encrypted extensions")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, - &buf, &buf_len)); - - /* Process the message contents */ - MBEDTLS_SSL_PROC_CHK( - ssl_tls13_parse_encrypted_extensions(ssl, buf, buf + buf_len)); - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) { - /* RFC8446 4.2.11 - * If the server supplies an "early_data" extension, the - * client MUST verify that the server's selected_identity - * is 0. If any other value is returned, the client MUST - * abort the handshake with an "illegal_parameter" alert. - * - * RFC 8446 4.2.10 - * In order to accept early data, the server MUST have accepted a PSK - * cipher suite and selected the first key offered in the client's - * "pre_shared_key" extension. In addition, it MUST verify that the - * following values are the same as those associated with the - * selected PSK: - * - The TLS version number - * - The selected cipher suite - * - The selected ALPN [RFC7301] protocol, if any - * - * The server has sent an early data extension in its Encrypted - * Extension message thus accepted to receive early data. We - * check here that the additional constraints on the handshake - * parameters, when early data are exchanged, are met, - * namely: - * - a PSK has been selected for the handshake - * - the selected PSK for the handshake was the first one proposed - * by the client. - * - the selected ciphersuite for the handshake is the ciphersuite - * associated with the selected PSK. - */ - if ((!mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) || - handshake->selected_identity != 0 || - handshake->ciphersuite_info->id != - ssl->session_negotiate->ciphersuite) { - - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED; - } else if (ssl->early_data_state != - MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) { - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED; - } -#endif - - /* - * In case the client has proposed a PSK associated with a ticket, - * `ssl->session_negotiate->ciphersuite` still contains at this point the - * identifier of the ciphersuite associated with the ticket. This is that - * way because, if an exchange of early data is agreed upon, we need - * it to check that the ciphersuite selected for the handshake is the - * ticket ciphersuite (see above). This information is not needed - * anymore thus we can now set it to the identifier of the ciphersuite - * used in this session under negotiation. - */ - ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id; - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, - buf, buf_len)); - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); - - /* Since we're not using a certificate, set verify_result to success */ - ssl->session_negotiate->verify_result = 0; - } else { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST); - } -#else - ((void) ssl); - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); -#endif - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse encrypted extensions")); - return ret; - -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) -/* - * Handler for MBEDTLS_SSL_END_OF_EARLY_DATA - * - * RFC 8446 section 4.5 - * - * struct {} EndOfEarlyData; - * - * If the server sent an "early_data" extension in EncryptedExtensions, the - * client MUST send an EndOfEarlyData message after receiving the server - * Finished. Otherwise, the client MUST NOT send an EndOfEarlyData message. - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_end_of_early_data(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf = NULL; - size_t buf_len; - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write EndOfEarlyData")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_hdr_to_checksum( - ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0)); - - MBEDTLS_SSL_PROC_CHK( - mbedtls_ssl_finish_handshake_msg(ssl, buf_len, 0)); - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write EndOfEarlyData")); - return ret; -} - -int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl) -{ - if ((ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) || - (!mbedtls_ssl_is_handshake_over(ssl))) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - switch (ssl->early_data_state) { - case MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT: - return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED; - break; - - case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED: - return MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; - break; - - case MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED: - return MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; - break; - - default: - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } -} -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -/* - * STATE HANDLING: CertificateRequest - * - */ -#define SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST 0 -#define SSL_CERTIFICATE_REQUEST_SKIP 1 -/* Coordination: - * Deals with the ambiguity of not knowing if a CertificateRequest - * will be sent. Returns a negative code on failure, or - * - SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST - * - SSL_CERTIFICATE_REQUEST_SKIP - * indicating if a Certificate Request is expected or not. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_certificate_request_coordinate(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - ssl->keep_current_message = 1; - - if ((ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) && - (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST)) { - MBEDTLS_SSL_DEBUG_MSG(3, ("got a certificate request")); - return SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("got no certificate request")); - - return SSL_CERTIFICATE_REQUEST_SKIP; -} - -/* - * ssl_tls13_parse_certificate_request() - * Parse certificate request - * struct { - * opaque certificate_request_context<0..2^8-1>; - * Extension extensions<2..2^16-1>; - * } CertificateRequest; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_certificate_request(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - size_t certificate_request_context_len = 0; - size_t extensions_len = 0; - const unsigned char *extensions_end; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* ... - * opaque certificate_request_context<0..2^8-1> - * ... - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1); - certificate_request_context_len = (size_t) p[0]; - p += 1; - - if (certificate_request_context_len > 0) { - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, certificate_request_context_len); - MBEDTLS_SSL_DEBUG_BUF(3, "Certificate Request Context", - p, certificate_request_context_len); - - handshake->certificate_request_context = - mbedtls_calloc(1, certificate_request_context_len); - if (handshake->certificate_request_context == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(handshake->certificate_request_context, p, - certificate_request_context_len); - p += certificate_request_context_len; - } - - /* ... - * Extension extensions<2..2^16-1>; - * ... - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); - extensions_end = p + extensions_len; - - handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - while (p < extensions_end) { - unsigned int extension_type; - size_t extension_data_len; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); - - ret = mbedtls_ssl_tls13_check_received_extension( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, extension_type, - MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR); - if (ret != 0) { - return ret; - } - - switch (extension_type) { - case MBEDTLS_TLS_EXT_SIG_ALG: - MBEDTLS_SSL_DEBUG_MSG(3, - ("found signature algorithms extension")); - ret = mbedtls_ssl_parse_sig_alg_ext(ssl, p, - p + extension_data_len); - if (ret != 0) { - return ret; - } - - break; - - default: - MBEDTLS_SSL_PRINT_EXT( - 3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, - extension_type, "( ignored )"); - break; - } - - p += extension_data_len; - } - - MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, - handshake->received_extensions); - - /* Check that we consumed all the message. */ - if (p != end) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("CertificateRequest misaligned")); - goto decode_error; - } - - /* RFC 8446 section 4.3.2 - * - * The "signature_algorithms" extension MUST be specified - */ - if ((handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(SIG_ALG)) == 0) { - MBEDTLS_SSL_DEBUG_MSG(3, - ("no signature algorithms extension found")); - goto decode_error; - } - - ssl->handshake->client_auth = 1; - return 0; - -decode_error: - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; -} - -/* - * Handler for MBEDTLS_SSL_CERTIFICATE_REQUEST - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_certificate_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request")); - - MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_certificate_request_coordinate(ssl)); - - if (ret == SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST) { - unsigned char *buf; - size_t buf_len; - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request( - ssl, buf, buf + buf_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, - buf, buf_len)); - } else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) { - ret = 0; - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CERTIFICATE); - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request")); - return ret; -} - -/* - * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_server_certificate(mbedtls_ssl_context *ssl) -{ - int ret; - - ret = mbedtls_ssl_tls13_process_certificate(ssl); - if (ret != 0) { - return ret; - } - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY); - return 0; -} - -/* - * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl) -{ - int ret; - - ret = mbedtls_ssl_tls13_process_certificate_verify(ssl); - if (ret != 0) { - return ret; - } - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); - return 0; -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -/* - * Handler for MBEDTLS_SSL_SERVER_FINISHED - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl) -{ - int ret; - - ret = mbedtls_ssl_tls13_process_finished_message(ssl); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_compute_application_transform(ssl); - if (ret != 0) { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return ret; - } - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED) { - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED; - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA); - } else -#endif /* MBEDTLS_SSL_EARLY_DATA */ - { -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED); -#else - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - } - - return 0; -} - -/* - * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_client_certificate(mbedtls_ssl_context *ssl) -{ - int non_empty_certificate_msg = 0; - - MBEDTLS_SSL_DEBUG_MSG(1, - ("Switch to handshake traffic keys for outbound traffic")); - mbedtls_ssl_set_outbound_transform(ssl, ssl->handshake->transform_handshake); - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - if (ssl->handshake->client_auth) { - int ret = mbedtls_ssl_tls13_write_certificate(ssl); - if (ret != 0) { - return ret; - } - - if (mbedtls_ssl_own_cert(ssl) != NULL) { - non_empty_certificate_msg = 1; - } - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("skip write certificate")); - } -#endif - - if (non_empty_certificate_msg) { - mbedtls_ssl_handshake_set_state(ssl, - MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY); - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("skip write certificate verify")); - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED); - } - - return 0; -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -/* - * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_client_certificate_verify(mbedtls_ssl_context *ssl) -{ - int ret = mbedtls_ssl_tls13_write_certificate_verify(ssl); - - if (ret == 0) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED); - } - - return ret; -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -/* - * Handler for MBEDTLS_SSL_CLIENT_FINISHED - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_client_finished(mbedtls_ssl_context *ssl) -{ - int ret; - - ret = mbedtls_ssl_tls13_write_finished_message(ssl); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_compute_resumption_master_secret ", ret); - return ret; - } - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_FLUSH_BUFFERS); - return 0; -} - -/* - * Handler for MBEDTLS_SSL_FLUSH_BUFFERS - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_flush_buffers(mbedtls_ssl_context *ssl) -{ - MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); - return 0; -} - -/* - * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl) -{ - - mbedtls_ssl_tls13_handshake_wrapup(ssl); - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); - return 0; -} - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - -#if defined(MBEDTLS_SSL_EARLY_DATA) -/* From RFC 8446 section 4.2.10 - * - * struct { - * select (Handshake.msg_type) { - * case new_session_ticket: uint32 max_early_data_size; - * ... - * }; - * } EarlyDataIndication; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_new_session_ticket_early_data_ext( - mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - mbedtls_ssl_session *session = ssl->session; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 4); - - session->max_early_data_size = MBEDTLS_GET_UINT32_BE(buf, 0); - mbedtls_ssl_tls13_session_set_ticket_flags( - session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA); - MBEDTLS_SSL_DEBUG_MSG( - 3, ("received max_early_data_size: %u", - (unsigned int) session->max_early_data_size)); - - return 0; -} -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_new_session_ticket_exts(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - const unsigned char *p = buf; - - - handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - while (p < end) { - unsigned int extension_type; - size_t extension_data_len; - int ret; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extension_data_len); - - ret = mbedtls_ssl_tls13_check_received_extension( - ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, extension_type, - MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST); - if (ret != 0) { - return ret; - } - - switch (extension_type) { -#if defined(MBEDTLS_SSL_EARLY_DATA) - case MBEDTLS_TLS_EXT_EARLY_DATA: - ret = ssl_tls13_parse_new_session_ticket_early_data_ext( - ssl, p, p + extension_data_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_parse_new_session_ticket_early_data_ext", - ret); - } - break; -#endif /* MBEDTLS_SSL_EARLY_DATA */ - - default: - MBEDTLS_SSL_PRINT_EXT( - 3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, - extension_type, "( ignored )"); - break; - } - - p += extension_data_len; - } - - MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, - handshake->received_extensions); - - return 0; -} - -/* - * From RFC8446, page 74 - * - * struct { - * uint32 ticket_lifetime; - * uint32 ticket_age_add; - * opaque ticket_nonce<0..255>; - * opaque ticket<1..2^16-1>; - * Extension extensions<0..2^16-2>; - * } NewSessionTicket; - * - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_new_session_ticket(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - unsigned char **ticket_nonce, - size_t *ticket_nonce_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - mbedtls_ssl_session *session = ssl->session; - size_t ticket_len; - unsigned char *ticket; - size_t extensions_len; - - *ticket_nonce = NULL; - *ticket_nonce_len = 0; - /* - * ticket_lifetime 4 bytes - * ticket_age_add 4 bytes - * ticket_nonce_len 1 byte - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 9); - - session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0); - MBEDTLS_SSL_DEBUG_MSG(3, - ("ticket_lifetime: %u", - (unsigned int) session->ticket_lifetime)); - if (session->ticket_lifetime > - MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime exceeds 7 days.")); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 4); - MBEDTLS_SSL_DEBUG_MSG(3, - ("ticket_age_add: %u", - (unsigned int) session->ticket_age_add)); - - *ticket_nonce_len = p[8]; - p += 9; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, *ticket_nonce_len); - *ticket_nonce = p; - MBEDTLS_SSL_DEBUG_BUF(3, "ticket_nonce:", *ticket_nonce, *ticket_nonce_len); - p += *ticket_nonce_len; - - /* Ticket */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - ticket_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, ticket_len); - MBEDTLS_SSL_DEBUG_BUF(3, "received ticket", p, ticket_len); - - /* Check if we previously received a ticket already. */ - if (session->ticket != NULL || session->ticket_len > 0) { - mbedtls_free(session->ticket); - session->ticket = NULL; - session->ticket_len = 0; - } - - if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed")); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(ticket, p, ticket_len); - p += ticket_len; - session->ticket = ticket; - session->ticket_len = ticket_len; - - /* Clear all flags in ticket_flags */ - mbedtls_ssl_tls13_session_clear_ticket_flags( - session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK); - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); - - MBEDTLS_SSL_DEBUG_BUF(3, "ticket extension", p, extensions_len); - - ret = ssl_tls13_parse_new_session_ticket_exts(ssl, p, p + extensions_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "ssl_tls13_parse_new_session_ticket_exts", - ret); - return ret; - } - - return 0; -} - -/* Non negative return values for ssl_tls13_postprocess_new_session_ticket(). - * - POSTPROCESS_NEW_SESSION_TICKET_SIGNAL, all good, we have to signal the - * application that a valid ticket has been received. - * - POSTPROCESS_NEW_SESSION_TICKET_DISCARD, no fatal error, we keep the - * connection alive but we do not signal the ticket to the application. - */ -#define POSTPROCESS_NEW_SESSION_TICKET_SIGNAL 0 -#define POSTPROCESS_NEW_SESSION_TICKET_DISCARD 1 -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl, - unsigned char *ticket_nonce, - size_t ticket_nonce_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_session *session = ssl->session; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - psa_algorithm_t psa_hash_alg; - int hash_length; - - if (session->ticket_lifetime == 0) { - return POSTPROCESS_NEW_SESSION_TICKET_DISCARD; - } - -#if defined(MBEDTLS_HAVE_TIME) - /* Store ticket creation time */ - session->ticket_reception_time = mbedtls_ms_time(); -#endif - - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite); - if (ciphersuite_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - psa_hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); - hash_length = PSA_HASH_LENGTH(psa_hash_alg); - if (hash_length == -1 || - (size_t) hash_length > sizeof(session->resumption_key)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - - MBEDTLS_SSL_DEBUG_BUF(3, "resumption_master_secret", - session->app_secrets.resumption_master_secret, - hash_length); - - /* Compute resumption key - * - * HKDF-Expand-Label( resumption_master_secret, - * "resumption", ticket_nonce, Hash.length ) - */ - ret = mbedtls_ssl_tls13_hkdf_expand_label( - psa_hash_alg, - session->app_secrets.resumption_master_secret, - hash_length, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(resumption), - ticket_nonce, - ticket_nonce_len, - session->resumption_key, - hash_length); - - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(2, - "Creating the ticket-resumed PSK failed", - ret); - return ret; - } - - session->resumption_key_len = hash_length; - - MBEDTLS_SSL_DEBUG_BUF(3, "Ticket-resumed PSK", - session->resumption_key, - session->resumption_key_len); - - /* Set ticket_flags depends on the selected key exchange modes */ - mbedtls_ssl_tls13_session_set_ticket_flags( - session, ssl->conf->tls13_kex_modes); - MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); - - return POSTPROCESS_NEW_SESSION_TICKET_SIGNAL; -} - -/* - * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_new_session_ticket(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - size_t buf_len; - unsigned char *ticket_nonce; - size_t ticket_nonce_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, - &buf, &buf_len)); - - /* - * We are about to update (maybe only partially) ticket data thus block - * any session export for the time being. - */ - ssl->session->exported = 1; - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_new_session_ticket( - ssl, buf, buf + buf_len, - &ticket_nonce, &ticket_nonce_len)); - - MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_postprocess_new_session_ticket( - ssl, ticket_nonce, ticket_nonce_len)); - - switch (ret) { - case POSTPROCESS_NEW_SESSION_TICKET_SIGNAL: - /* - * All good, we have received a new valid ticket, session data can - * be exported now and we signal the ticket to the application. - */ - ssl->session->exported = 0; - ret = MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET; - break; - - case POSTPROCESS_NEW_SESSION_TICKET_DISCARD: - ret = 0; - MBEDTLS_SSL_DEBUG_MSG(2, ("Discard new session ticket")); - break; - - default: - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket")); - return ret; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl) -{ - int ret = 0; - - switch (ssl->state) { - case MBEDTLS_SSL_HELLO_REQUEST: - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - break; - - case MBEDTLS_SSL_CLIENT_HELLO: - ret = mbedtls_ssl_write_client_hello(ssl); - break; - - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_tls13_process_server_hello(ssl); - break; - - case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS: - ret = ssl_tls13_process_encrypted_extensions(ssl); - break; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_tls13_process_certificate_request(ssl); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = ssl_tls13_process_server_certificate(ssl); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_tls13_process_certificate_verify(ssl); - break; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = ssl_tls13_process_server_finished(ssl); - break; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - case MBEDTLS_SSL_END_OF_EARLY_DATA: - ret = ssl_tls13_write_end_of_early_data(ssl); - break; -#endif - - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = ssl_tls13_write_client_certificate(ssl); - break; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY: - ret = ssl_tls13_write_client_certificate_verify(ssl); - break; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = ssl_tls13_write_client_finished(ssl); - break; - - case MBEDTLS_SSL_FLUSH_BUFFERS: - ret = ssl_tls13_flush_buffers(ssl); - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - ret = ssl_tls13_handshake_wrapup(ssl); - break; - - /* - * Injection of dummy-CCS's for middlebox compatibility - */ -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO: - ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl); - if (ret != 0) { - break; - } - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - break; - - case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED: - ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl); - if (ret != 0) { - break; - } - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); - break; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO: - ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl); - if (ret == 0) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO); - - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Switch to early data keys for outbound traffic")); - mbedtls_ssl_set_outbound_transform( - ssl, ssl->handshake->transform_earlydata); - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE; - } - break; -#endif /* MBEDTLS_SSL_EARLY_DATA */ -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET: - ret = ssl_tls13_process_new_session_ticket(ssl); - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - default: - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - return ret; -} - -#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/vendor/mbedtls/library/ssl_tls13_generic.c b/vendor/mbedtls/library/ssl_tls13_generic.c deleted file mode 100644 index b6d09788b..000000000 --- a/vendor/mbedtls/library/ssl_tls13_generic.c +++ /dev/null @@ -1,1754 +0,0 @@ -/* - * TLS 1.3 functionality shared between client and server - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#include - -#include "mbedtls/error.h" -#include "debug_internal.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform.h" -#include "mbedtls/constant_time.h" -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" - -#include "ssl_misc.h" -#include "ssl_tls13_invasive.h" -#include "ssl_tls13_keys.h" -#include "ssl_debug_helpers.h" - -#include "psa/crypto.h" -#include "psa_util_internal.h" - -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) - -int mbedtls_ssl_tls13_crypto_init(mbedtls_ssl_context *ssl) -{ - psa_status_t status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - (void) ssl; // unused when debugging is disabled - MBEDTLS_SSL_DEBUG_RET(1, "psa_crypto_init", status); - } - return PSA_TO_MBEDTLS_ERR(status); -} - -const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[ - MBEDTLS_SERVER_HELLO_RANDOM_LEN] = -{ 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, - 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, - 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, - 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C }; - -int mbedtls_ssl_tls13_fetch_handshake_msg(mbedtls_ssl_context *ssl, - unsigned hs_type, - unsigned char **buf, - size_t *buf_len) -{ - int ret; - - if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - goto cleanup; - } - - if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || - ssl->in_msg[0] != hs_type) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Receive unexpected handshake message.")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE, - MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); - ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - goto cleanup; - } - - /* - * Jump handshake header (4 bytes, see Section 4 of RFC 8446). - * ... - * HandshakeType msg_type; - * uint24 length; - * ... - */ - *buf = ssl->in_msg + 4; - *buf_len = ssl->in_hslen - 4; - -cleanup: - - return ret; -} - -int mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( - mbedtls_ssl_context *ssl, - const unsigned char *buf, const unsigned char *end, - const unsigned char **supported_versions_data, - const unsigned char **supported_versions_data_end) -{ - const unsigned char *p = buf; - size_t extensions_len; - const unsigned char *extensions_end; - - *supported_versions_data = NULL; - *supported_versions_data_end = NULL; - - /* Case of no extension */ - if (p == end) { - return 0; - } - - /* ... - * Extension extensions; - * ... - * struct { - * ExtensionType extension_type; (2 bytes) - * opaque extension_data<0..2^16-1>; - * } Extension; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* Check extensions do not go beyond the buffer of data. */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); - extensions_end = p + extensions_len; - - while (p < extensions_end) { - unsigned int extension_type; - size_t extension_data_len; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); - - if (extension_type == MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS) { - *supported_versions_data = p; - *supported_versions_data_end = p + extension_data_len; - return 1; - } - p += extension_data_len; - } - - return 0; -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -/* - * STATE HANDLING: Read CertificateVerify - */ -/* Macro to express the maximum length of the verify structure. - * - * The structure is computed per TLS 1.3 specification as: - * - 64 bytes of octet 32, - * - 33 bytes for the context string - * (which is either "TLS 1.3, client CertificateVerify" - * or "TLS 1.3, server CertificateVerify"), - * - 1 byte for the octet 0x0, which serves as a separator, - * - 32 or 48 bytes for the Transcript-Hash(Handshake Context, Certificate) - * (depending on the size of the transcript_hash) - * - * This results in a total size of - * - 130 bytes for a SHA256-based transcript hash, or - * (64 + 33 + 1 + 32 bytes) - * - 146 bytes for a SHA384-based transcript hash. - * (64 + 33 + 1 + 48 bytes) - * - */ -#define SSL_VERIFY_STRUCT_MAX_SIZE (64 + \ - 33 + \ - 1 + \ - MBEDTLS_TLS1_3_MD_MAX_SIZE \ - ) - -/* - * The ssl_tls13_create_verify_structure() creates the verify structure. - * As input, it requires the transcript hash. - * - * The caller has to ensure that the buffer has size at least - * SSL_VERIFY_STRUCT_MAX_SIZE bytes. - */ -static void ssl_tls13_create_verify_structure(const unsigned char *transcript_hash, - size_t transcript_hash_len, - unsigned char *verify_buffer, - size_t *verify_buffer_len, - int from) -{ - size_t idx; - - /* RFC 8446, Section 4.4.3: - * - * The digital signature [in the CertificateVerify message] is then - * computed over the concatenation of: - * - A string that consists of octet 32 (0x20) repeated 64 times - * - The context string - * - A single 0 byte which serves as the separator - * - The content to be signed - */ - memset(verify_buffer, 0x20, 64); - idx = 64; - - if (from == MBEDTLS_SSL_IS_CLIENT) { - memcpy(verify_buffer + idx, mbedtls_ssl_tls13_labels.client_cv, - MBEDTLS_SSL_TLS1_3_LBL_LEN(client_cv)); - idx += MBEDTLS_SSL_TLS1_3_LBL_LEN(client_cv); - } else { /* from == MBEDTLS_SSL_IS_SERVER */ - memcpy(verify_buffer + idx, mbedtls_ssl_tls13_labels.server_cv, - MBEDTLS_SSL_TLS1_3_LBL_LEN(server_cv)); - idx += MBEDTLS_SSL_TLS1_3_LBL_LEN(server_cv); - } - - verify_buffer[idx++] = 0x0; - - memcpy(verify_buffer + idx, transcript_hash, transcript_hash_len); - idx += transcript_hash_len; - - *verify_buffer_len = idx; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_certificate_verify(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end, - const unsigned char *verify_buffer, - size_t verify_buffer_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - uint16_t algorithm; - size_t signature_len; - mbedtls_pk_type_t sig_alg; - mbedtls_md_type_t md_alg; - psa_algorithm_t hash_alg = PSA_ALG_NONE; - unsigned char verify_hash[PSA_HASH_MAX_SIZE]; - size_t verify_hash_len; - - void const *options = NULL; -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_pk_rsassa_pss_options rsassa_pss_options; -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - /* - * struct { - * SignatureScheme algorithm; - * opaque signature<0..2^16-1>; - * } CertificateVerify; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - algorithm = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* RFC 8446 section 4.4.3 - * - * If the CertificateVerify message is sent by a server, the signature - * algorithm MUST be one offered in the client's "signature_algorithms" - * extension unless no valid certificate chain can be produced without - * unsupported algorithms - * - * RFC 8446 section 4.4.2.2 - * - * If the client cannot construct an acceptable chain using the provided - * certificates and decides to abort the handshake, then it MUST abort the - * handshake with an appropriate certificate-related alert - * (by default, "unsupported_certificate"). - * - * Check if algorithm is an offered signature algorithm. - */ - if (!mbedtls_ssl_sig_alg_is_offered(ssl, algorithm)) { - /* algorithm not in offered signature algorithms list */ - MBEDTLS_SSL_DEBUG_MSG(1, ("Received signature algorithm(%04x) is not " - "offered.", - (unsigned int) algorithm)); - goto error; - } - - if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg( - algorithm, &sig_alg, &md_alg) != 0) { - goto error; - } - - hash_alg = mbedtls_md_psa_alg_from_type(md_alg); - if (hash_alg == 0) { - goto error; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate Verify: Signature algorithm ( %04x )", - (unsigned int) algorithm)); - - /* - * Check the certificate's key type matches the signature alg - */ - if (!mbedtls_pk_can_do(&ssl->session_negotiate->peer_cert->pk, sig_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("signature algorithm doesn't match cert key")); - goto error; - } - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - signature_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, signature_len); - - status = psa_hash_compute(hash_alg, - verify_buffer, - verify_buffer_len, - verify_hash, - sizeof(verify_hash), - &verify_hash_len); - if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET(1, "hash computation PSA error", status); - goto error; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "verify hash", verify_hash, verify_hash_len); -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if (sig_alg == MBEDTLS_PK_RSASSA_PSS) { - rsassa_pss_options.mgf1_hash_id = md_alg; - - rsassa_pss_options.expected_salt_len = PSA_HASH_LENGTH(hash_alg); - options = (const void *) &rsassa_pss_options; - } -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - if ((ret = mbedtls_pk_verify_ext(sig_alg, options, - &ssl->session_negotiate->peer_cert->pk, - md_alg, verify_hash, verify_hash_len, - p, signature_len)) == 0) { - return 0; - } - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify_ext", ret); - -error: - /* RFC 8446 section 4.4.3 - * - * If the verification fails, the receiver MUST terminate the handshake - * with a "decrypt_error" alert. - */ - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -int mbedtls_ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl) -{ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char verify_buffer[SSL_VERIFY_STRUCT_MAX_SIZE]; - size_t verify_buffer_len; - unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t transcript_len; - unsigned char *buf; - size_t buf_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify")); - - MBEDTLS_SSL_PROC_CHK( - mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, &buf, &buf_len)); - - /* Need to calculate the hash of the transcript first - * before reading the message since otherwise it gets - * included in the transcript - */ - ret = mbedtls_ssl_get_handshake_transcript( - ssl, - (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac, - transcript, sizeof(transcript), - &transcript_len); - if (ret != 0) { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR, - MBEDTLS_ERR_SSL_INTERNAL_ERROR); - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "handshake hash", transcript, transcript_len); - - /* Create verify structure */ - ssl_tls13_create_verify_structure(transcript, - transcript_len, - verify_buffer, - &verify_buffer_len, - (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) ? - MBEDTLS_SSL_IS_SERVER : - MBEDTLS_SSL_IS_CLIENT); - - /* Process the message contents */ - MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_verify( - ssl, buf, buf + buf_len, - verify_buffer, verify_buffer_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, - buf, buf_len)); - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify")); - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_process_certificate_verify", ret); - return ret; -#else - ((void) ssl); - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ -} - -/* - * - * STATE HANDLING: Incoming Certificate. - * - */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -/* - * Structure of Certificate message: - * - * enum { - * X509(0), - * RawPublicKey(2), - * (255) - * } CertificateType; - * - * struct { - * select (certificate_type) { - * case RawPublicKey: - * * From RFC 7250 ASN.1_subjectPublicKeyInfo * - * opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; - * case X509: - * opaque cert_data<1..2^24-1>; - * }; - * Extension extensions<0..2^16-1>; - * } CertificateEntry; - * - * struct { - * opaque certificate_request_context<0..2^8-1>; - * CertificateEntry certificate_list<0..2^24-1>; - * } Certificate; - * - */ - -/* Parse certificate chain send by the server. */ -MBEDTLS_CHECK_RETURN_CRITICAL -MBEDTLS_STATIC_TESTABLE -int mbedtls_ssl_tls13_parse_certificate(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t certificate_request_context_len = 0; - size_t certificate_list_len = 0; - const unsigned char *p = buf; - const unsigned char *certificate_list_end; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 4); - certificate_request_context_len = p[0]; - certificate_list_len = MBEDTLS_GET_UINT24_BE(p, 1); - p += 4; - - /* In theory, the certificate list can be up to 2^24 Bytes, but we don't - * support anything beyond 2^16 = 64K. - */ - if ((certificate_request_context_len != 0) || - (certificate_list_len >= 0x10000)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate message")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* In case we tried to reuse a session but it failed */ - if (ssl->session_negotiate->peer_cert != NULL) { - mbedtls_x509_crt_free(ssl->session_negotiate->peer_cert); - mbedtls_free(ssl->session_negotiate->peer_cert); - } - - /* This is used by ssl_tls13_validate_certificate() */ - if (certificate_list_len == 0) { - ssl->session_negotiate->peer_cert = NULL; - ret = 0; - goto exit; - } - - if ((ssl->session_negotiate->peer_cert = - mbedtls_calloc(1, sizeof(mbedtls_x509_crt))) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("alloc( %" MBEDTLS_PRINTF_SIZET " bytes ) failed", - sizeof(mbedtls_x509_crt))); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR, - MBEDTLS_ERR_SSL_ALLOC_FAILED); - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - mbedtls_x509_crt_init(ssl->session_negotiate->peer_cert); - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, certificate_list_len); - certificate_list_end = p + certificate_list_len; - while (p < certificate_list_end) { - size_t cert_data_len, extensions_len; - const unsigned char *extensions_end; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, certificate_list_end, 3); - cert_data_len = MBEDTLS_GET_UINT24_BE(p, 0); - p += 3; - - /* In theory, the CRT can be up to 2^24 Bytes, but we don't support - * anything beyond 2^16 = 64K. Otherwise as in the TLS 1.2 code, - * check that we have a minimum of 128 bytes of data, this is not - * clear why we need that though. - */ - if ((cert_data_len < 128) || (cert_data_len >= 0x10000)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad Certificate message")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, certificate_list_end, cert_data_len); - ret = mbedtls_x509_crt_parse_der(ssl->session_negotiate->peer_cert, - p, cert_data_len); - - switch (ret) { - case 0: /*ok*/ - break; - case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: - /* Ignore certificate with an unknown algorithm: maybe a - prior certificate was already trusted. */ - break; - - case MBEDTLS_ERR_X509_ALLOC_FAILED: - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR, - MBEDTLS_ERR_X509_ALLOC_FAILED); - MBEDTLS_SSL_DEBUG_RET(1, " mbedtls_x509_crt_parse_der", ret); - return ret; - - case MBEDTLS_ERR_X509_UNKNOWN_VERSION: - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT, - MBEDTLS_ERR_X509_UNKNOWN_VERSION); - MBEDTLS_SSL_DEBUG_RET(1, " mbedtls_x509_crt_parse_der", ret); - return ret; - - default: - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_BAD_CERT, - ret); - MBEDTLS_SSL_DEBUG_RET(1, " mbedtls_x509_crt_parse_der", ret); - return ret; - } - - p += cert_data_len; - - /* Certificate extensions length */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, certificate_list_end, 2); - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, certificate_list_end, extensions_len); - - extensions_end = p + extensions_len; - handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - while (p < extensions_end) { - unsigned int extension_type; - size_t extension_data_len; - - /* - * struct { - * ExtensionType extension_type; (2 bytes) - * opaque extension_data<0..2^16-1>; - * } Extension; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); - - ret = mbedtls_ssl_tls13_check_received_extension( - ssl, MBEDTLS_SSL_HS_CERTIFICATE, extension_type, - MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CT); - if (ret != 0) { - return ret; - } - - switch (extension_type) { - default: - MBEDTLS_SSL_PRINT_EXT( - 3, MBEDTLS_SSL_HS_CERTIFICATE, - extension_type, "( ignored )"); - break; - } - - p += extension_data_len; - } - - MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_CERTIFICATE, - handshake->received_extensions); - } - -exit: - /* Check that all the message is consumed. */ - if (p != end) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad Certificate message")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_CRT(3, "peer certificate", - ssl->session_negotiate->peer_cert); - - return ret; -} -#else -MBEDTLS_CHECK_RETURN_CRITICAL -MBEDTLS_STATIC_TESTABLE -int mbedtls_ssl_tls13_parse_certificate(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - ((void) ssl); - ((void) buf); - ((void) end); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -/* Validate certificate chain sent by the server. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl) -{ - /* Authmode: precedence order is SNI if used else configuration */ -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET - ? ssl->handshake->sni_authmode - : ssl->conf->authmode; -#else - const int authmode = ssl->conf->authmode; -#endif - - /* - * If the peer hasn't sent a certificate ( i.e. it sent - * an empty certificate chain ), this is reflected in the peer CRT - * structure being unset. - * Check for that and handle it depending on the - * authentication mode. - */ - if (ssl->session_negotiate->peer_cert == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("peer has no certificate")); - -#if defined(MBEDTLS_SSL_SRV_C) - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - /* The client was asked for a certificate but didn't send - * one. The client should know what's going on, so we - * don't send an alert. - */ - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; - if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL) { - return 0; - } else { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_NO_CERT, - MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE); - return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE; - } - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) - /* Regardless of authmode, the server is not allowed to send an empty - * certificate chain. (Last paragraph before 4.4.2.1 in RFC 8446: "The - * server's certificate_list MUST always be non-empty.") With authmode - * optional/none, we continue the handshake if we can't validate the - * server's cert, but we still break it if no certificate was sent. */ - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_NO_CERT, - MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE); - return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE; - } -#endif /* MBEDTLS_SSL_CLI_C */ - } - - return mbedtls_ssl_verify_certificate(ssl, authmode, - ssl->session_negotiate->peer_cert, - NULL, NULL); -} -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl) -{ - ((void) ssl); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -int mbedtls_ssl_tls13_process_certificate(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate")); - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - unsigned char *buf; - size_t buf_len; - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_CERTIFICATE, - &buf, &buf_len)); - - /* Parse the certificate chain sent by the peer. */ - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_parse_certificate(ssl, buf, - buf + buf_len)); - /* Validate the certificate chain and set the verification results. */ - MBEDTLS_SSL_PROC_CHK(ssl_tls13_validate_certificate(ssl)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_CERTIFICATE, buf, buf_len)); - -cleanup: -#else /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - (void) ssl; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate")); - return ret; -} -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -/* - * enum { - * X509(0), - * RawPublicKey(2), - * (255) - * } CertificateType; - * - * struct { - * select (certificate_type) { - * case RawPublicKey: - * // From RFC 7250 ASN.1_subjectPublicKeyInfo - * opaque ASN1_subjectPublicKeyInfo<1..2^24-1>; - * - * case X509: - * opaque cert_data<1..2^24-1>; - * }; - * Extension extensions<0..2^16-1>; - * } CertificateEntry; - * - * struct { - * opaque certificate_request_context<0..2^8-1>; - * CertificateEntry certificate_list<0..2^24-1>; - * } Certificate; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_certificate_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - const mbedtls_x509_crt *crt = mbedtls_ssl_own_cert(ssl); - unsigned char *p = buf; - unsigned char *certificate_request_context = - ssl->handshake->certificate_request_context; - unsigned char certificate_request_context_len = - ssl->handshake->certificate_request_context_len; - unsigned char *p_certificate_list_len; - - - /* ... - * opaque certificate_request_context<0..2^8-1>; - * ... - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, certificate_request_context_len + 1); - *p++ = certificate_request_context_len; - if (certificate_request_context_len > 0) { - memcpy(p, certificate_request_context, certificate_request_context_len); - p += certificate_request_context_len; - } - - /* ... - * CertificateEntry certificate_list<0..2^24-1>; - * ... - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 3); - p_certificate_list_len = p; - p += 3; - - MBEDTLS_SSL_DEBUG_CRT(3, "own certificate", crt); - - while (crt != NULL) { - size_t cert_data_len = crt->raw.len; - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, cert_data_len + 3 + 2); - MBEDTLS_PUT_UINT24_BE(cert_data_len, p, 0); - p += 3; - - memcpy(p, crt->raw.p, cert_data_len); - p += cert_data_len; - crt = crt->next; - - /* Currently, we don't have any certificate extensions defined. - * Hence, we are sending an empty extension with length zero. - */ - MBEDTLS_PUT_UINT16_BE(0, p, 0); - p += 2; - } - - MBEDTLS_PUT_UINT24_BE(p - p_certificate_list_len - 3, - p_certificate_list_len, 0); - - *out_len = p - buf; - - MBEDTLS_SSL_PRINT_EXTS( - 3, MBEDTLS_SSL_HS_CERTIFICATE, ssl->handshake->sent_extensions); - - return 0; -} - -int mbedtls_ssl_tls13_write_certificate(mbedtls_ssl_context *ssl) -{ - int ret; - unsigned char *buf; - size_t buf_len, msg_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_CERTIFICATE, &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_body(ssl, - buf, - buf + buf_len, - &msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_CERTIFICATE, buf, msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( - ssl, buf_len, msg_len)); -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate")); - return ret; -} - -/* - * STATE HANDLING: Output Certificate Verify - */ -int mbedtls_ssl_tls13_check_sig_alg_cert_key_match(uint16_t sig_alg, - mbedtls_pk_context *key) -{ - mbedtls_pk_type_t pk_type = (mbedtls_pk_type_t) mbedtls_ssl_sig_from_pk(key); - size_t key_size = mbedtls_pk_get_bitlen(key); - - switch (pk_type) { - case MBEDTLS_SSL_SIG_ECDSA: - switch (key_size) { - case 256: - return - sig_alg == MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256; - - case 384: - return - sig_alg == MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384; - - case 521: - return - sig_alg == MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512; - default: - break; - } - break; - - case MBEDTLS_SSL_SIG_RSA: - switch (sig_alg) { - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: /* Intentional fallthrough */ - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: /* Intentional fallthrough */ - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: - return 1; - - default: - break; - } - break; - - default: - break; - } - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_certificate_verify_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - mbedtls_pk_context *own_key; - - unsigned char handshake_hash[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t handshake_hash_len; - unsigned char verify_buffer[SSL_VERIFY_STRUCT_MAX_SIZE]; - size_t verify_buffer_len; - - uint16_t *sig_alg = ssl->handshake->received_sig_algs; - size_t signature_len = 0; - - *out_len = 0; - - own_key = mbedtls_ssl_own_key(ssl); - if (own_key == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ret = mbedtls_ssl_get_handshake_transcript( - ssl, (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac, - handshake_hash, sizeof(handshake_hash), &handshake_hash_len); - if (ret != 0) { - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "handshake hash", - handshake_hash, - handshake_hash_len); - - ssl_tls13_create_verify_structure(handshake_hash, handshake_hash_len, - verify_buffer, &verify_buffer_len, - ssl->conf->endpoint); - - /* - * struct { - * SignatureScheme algorithm; - * opaque signature<0..2^16-1>; - * } CertificateVerify; - */ - /* Check there is space for the algorithm identifier (2 bytes) and the - * signature length (2 bytes). - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); - - for (; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++) { - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_pk_type_t pk_type = MBEDTLS_PK_NONE; - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - psa_algorithm_t psa_algorithm = PSA_ALG_NONE; - unsigned char verify_hash[PSA_HASH_MAX_SIZE]; - size_t verify_hash_len; - - if (!mbedtls_ssl_sig_alg_is_offered(ssl, *sig_alg)) { - continue; - } - - if (!mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported(*sig_alg)) { - continue; - } - - if (!mbedtls_ssl_tls13_check_sig_alg_cert_key_match(*sig_alg, own_key)) { - continue; - } - - if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg( - *sig_alg, &pk_type, &md_alg) != 0) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Hash verify buffer with indicated hash function */ - psa_algorithm = mbedtls_md_psa_alg_from_type(md_alg); - status = psa_hash_compute(psa_algorithm, - verify_buffer, - verify_buffer_len, - verify_hash, sizeof(verify_hash), - &verify_hash_len); - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } - - MBEDTLS_SSL_DEBUG_BUF(3, "verify hash", verify_hash, verify_hash_len); - - if ((ret = mbedtls_pk_sign_ext(pk_type, own_key, - md_alg, verify_hash, verify_hash_len, - p + 4, (size_t) (end - (p + 4)), &signature_len, - ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("CertificateVerify signature failed with %s", - mbedtls_ssl_sig_alg_to_str(*sig_alg))); - MBEDTLS_SSL_DEBUG_RET(2, "mbedtls_pk_sign_ext", ret); - - /* The signature failed. This is possible if the private key - * was not suitable for the signature operation as purposely we - * did not check its suitability completely. Let's try with - * another signature algorithm. - */ - continue; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("CertificateVerify signature with %s", - mbedtls_ssl_sig_alg_to_str(*sig_alg))); - - break; - } - - if (*sig_alg == MBEDTLS_TLS1_3_SIG_NONE) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no suitable signature algorithm")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - MBEDTLS_PUT_UINT16_BE(*sig_alg, p, 0); - MBEDTLS_PUT_UINT16_BE(signature_len, p, 2); - - *out_len = 4 + signature_len; - - return 0; -} - -int mbedtls_ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl) -{ - int ret = 0; - unsigned char *buf; - size_t buf_len, msg_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_verify_body( - ssl, buf, buf + buf_len, &msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, - buf, msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( - ssl, buf_len, msg_len)); - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate verify")); - return ret; -} - -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -/* - * - * STATE HANDLING: Incoming Finished message. - */ -/* - * Implementation - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_preprocess_finished_message(mbedtls_ssl_context *ssl) -{ - int ret; - - ret = mbedtls_ssl_tls13_calculate_verify_data( - ssl, - ssl->handshake->state_local.finished_in.digest, - sizeof(ssl->handshake->state_local.finished_in.digest), - &ssl->handshake->state_local.finished_in.digest_len, - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ? - MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_calculate_verify_data", ret); - return ret; - } - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_finished_message(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - /* - * struct { - * opaque verify_data[Hash.length]; - * } Finished; - */ - const unsigned char *expected_verify_data = - ssl->handshake->state_local.finished_in.digest; - size_t expected_verify_data_len = - ssl->handshake->state_local.finished_in.digest_len; - /* Structural validation */ - if ((size_t) (end - buf) != expected_verify_data_len) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message")); - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "verify_data (self-computed):", - expected_verify_data, - expected_verify_data_len); - MBEDTLS_SSL_DEBUG_BUF(4, "verify_data (received message):", buf, - expected_verify_data_len); - - /* Semantic validation */ - if (mbedtls_ct_memcmp(buf, - expected_verify_data, - expected_verify_data_len) != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad finished message")); - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - return 0; -} - -int mbedtls_ssl_tls13_process_finished_message(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - size_t buf_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse finished message")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_FINISHED, &buf, &buf_len)); - - /* Preprocessing step: Compute handshake digest */ - MBEDTLS_SSL_PROC_CHK(ssl_tls13_preprocess_finished_message(ssl)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_finished_message( - ssl, buf, buf + buf_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_FINISHED, buf, buf_len)); - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse finished message")); - return ret; -} - -/* - * - * STATE HANDLING: Write and send Finished message. - * - */ -/* - * Implement - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_prepare_finished_message(mbedtls_ssl_context *ssl) -{ - int ret; - - /* Compute transcript of handshake up to now. */ - ret = mbedtls_ssl_tls13_calculate_verify_data(ssl, - ssl->handshake->state_local.finished_out.digest, - sizeof(ssl->handshake->state_local.finished_out. - digest), - &ssl->handshake->state_local.finished_out.digest_len, - ssl->conf->endpoint); - - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "calculate_verify_data failed", ret); - return ret; - } - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_finished_message_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - size_t verify_data_len = ssl->handshake->state_local.finished_out.digest_len; - /* - * struct { - * opaque verify_data[Hash.length]; - * } Finished; - */ - MBEDTLS_SSL_CHK_BUF_PTR(buf, end, verify_data_len); - - memcpy(buf, ssl->handshake->state_local.finished_out.digest, - verify_data_len); - - *out_len = verify_data_len; - return 0; -} - -/* Main entry point: orchestrates the other functions */ -int mbedtls_ssl_tls13_write_finished_message(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - size_t buf_len, msg_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write finished message")); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_prepare_finished_message(ssl)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(ssl, - MBEDTLS_SSL_HS_FINISHED, &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_finished_message_body( - ssl, buf, buf + buf_len, &msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, - MBEDTLS_SSL_HS_FINISHED, buf, msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( - ssl, buf_len, msg_len)); -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write finished message")); - return ret; -} - -void mbedtls_ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl) -{ - - MBEDTLS_SSL_DEBUG_MSG(3, ("=> handshake wrapup")); - - MBEDTLS_SSL_DEBUG_MSG(1, ("Switch to application keys for inbound traffic")); - mbedtls_ssl_set_inbound_transform(ssl, ssl->transform_application); - - MBEDTLS_SSL_DEBUG_MSG(1, ("Switch to application keys for outbound traffic")); - mbedtls_ssl_set_outbound_transform(ssl, ssl->transform_application); - - /* - * Free the previous session and switch to the current one. - */ - if (ssl->session) { - mbedtls_ssl_session_free(ssl->session); - mbedtls_free(ssl->session); - } - ssl->session = ssl->session_negotiate; - ssl->session_negotiate = NULL; - - MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup")); -} - -/* - * - * STATE HANDLING: Write ChangeCipherSpec - * - */ -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_change_cipher_spec_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *olen) -{ - ((void) ssl); - - MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 1); - buf[0] = 1; - *olen = 1; - - return 0; -} - -int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec")); - - /* Only one CCS to send. */ - if (ssl->handshake->ccs_sent) { - ret = 0; - goto cleanup; - } - - /* Write CCS message */ - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_change_cipher_spec_body( - ssl, ssl->out_msg, - ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, - &ssl->out_msglen)); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - - /* Dispatch message */ - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_record(ssl, 0)); - - ssl->handshake->ccs_sent = 1; - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec")); - return ret; -} - -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - -/* Early Data Indication Extension - * - * struct { - * select ( Handshake.msg_type ) { - * case new_session_ticket: uint32 max_early_data_size; - * case client_hello: Empty; - * case encrypted_extensions: Empty; - * }; - * } EarlyDataIndication; - */ -#if defined(MBEDTLS_SSL_EARLY_DATA) -int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, - int in_new_session_ticket, - unsigned char *buf, - const unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - -#if defined(MBEDTLS_SSL_SRV_C) - const size_t needed = in_new_session_ticket ? 8 : 4; -#else - const size_t needed = 4; - ((void) in_new_session_ticket); -#endif - - *out_len = 0; - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, needed); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EARLY_DATA, p, 0); - MBEDTLS_PUT_UINT16_BE(needed - 4, p, 2); - -#if defined(MBEDTLS_SSL_SRV_C) - if (in_new_session_ticket) { - MBEDTLS_PUT_UINT32_BE(ssl->conf->max_early_data_size, p, 4); - MBEDTLS_SSL_DEBUG_MSG( - 4, ("Sent max_early_data_size=%u", - (unsigned int) ssl->conf->max_early_data_size)); - } -#endif - - *out_len = needed; - - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_EARLY_DATA); - - return 0; -} - -#if defined(MBEDTLS_SSL_SRV_C) -int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, - size_t early_data_len) -{ - /* - * This function should be called only while an handshake is in progress - * and thus a session under negotiation. Add a sanity check to detect a - * misuse. - */ - if (ssl->session_negotiate == NULL) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* RFC 8446 section 4.6.1 - * - * A server receiving more than max_early_data_size bytes of 0-RTT data - * SHOULD terminate the connection with an "unexpected_message" alert. - * Note that if it is still possible to send early_data_len bytes of early - * data, it means that early_data_len is smaller than max_early_data_size - * (type uint32_t) and can fit in an uint32_t. We use this further - * down. - */ - if (early_data_len > - (ssl->session_negotiate->max_early_data_size - - ssl->total_early_data_size)) { - - MBEDTLS_SSL_DEBUG_MSG( - 2, ("EarlyData: Too much early data received, " - "%lu + %" MBEDTLS_PRINTF_SIZET " > %lu", - (unsigned long) ssl->total_early_data_size, - early_data_len, - (unsigned long) ssl->session_negotiate->max_early_data_size)); - - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE, - MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; - } - - /* - * early_data_len has been checked to be less than max_early_data_size - * that is uint32_t. Its cast to an uint32_t below is thus safe. We need - * the cast to appease some compilers. - */ - ssl->total_early_data_size += (uint32_t) early_data_len; - - return 0; -} -#endif /* MBEDTLS_SSL_SRV_C */ -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -/* Reset SSL context and update hash for handling HRR. - * - * Replace Transcript-Hash(X) by - * Transcript-Hash( message_hash || - * 00 00 Hash.length || - * X ) - * A few states of the handshake are preserved, including: - * - session ID - * - session ticket - * - negotiated ciphersuite - */ -int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char hash_transcript[PSA_HASH_MAX_SIZE + 4]; - size_t hash_len; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(3, ("Reset SSL session for HRR")); - - ret = mbedtls_ssl_get_handshake_transcript(ssl, (mbedtls_md_type_t) ciphersuite_info->mac, - hash_transcript + 4, - PSA_HASH_MAX_SIZE, - &hash_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_handshake_transcript", ret); - return ret; - } - - hash_transcript[0] = MBEDTLS_SSL_HS_MESSAGE_HASH; - hash_transcript[1] = 0; - hash_transcript[2] = 0; - hash_transcript[3] = (unsigned char) hash_len; - - hash_len += 4; - - MBEDTLS_SSL_DEBUG_BUF(4, "Truncated handshake transcript", - hash_transcript, hash_len); - - /* Reset running hash and replace it with a hash of the transcript */ - ret = mbedtls_ssl_reset_checksum(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_reset_checksum", ret); - return ret; - } - ret = ssl->handshake->update_checksum(ssl, hash_transcript, hash_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); - return ret; - } - - return ret; -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - -int mbedtls_ssl_tls13_read_public_xxdhe_share(mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t buf_len) -{ - uint8_t *p = (uint8_t *) buf; - const uint8_t *end = buf + buf_len; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* Get size of the TLS opaque key_exchange field of the KeyShareEntry struct. */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - uint16_t peerkey_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* Check if key size is consistent with given buffer length. */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, peerkey_len); - - /* Store peer's ECDH/FFDH public key. */ - if (peerkey_len > sizeof(handshake->xxdh_psa_peerkey)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %u > %" MBEDTLS_PRINTF_SIZET, - (unsigned) peerkey_len, - sizeof(handshake->xxdh_psa_peerkey))); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - memcpy(handshake->xxdh_psa_peerkey, p, peerkey_len); - handshake->xxdh_psa_peerkey_len = peerkey_len; - - return 0; -} - -#if defined(PSA_WANT_ALG_FFDH) -static psa_status_t mbedtls_ssl_get_psa_ffdh_info_from_tls_id( - uint16_t tls_id, size_t *bits, psa_key_type_t *key_type) -{ - switch (tls_id) { -#if defined(PSA_WANT_DH_RFC7919_2048) - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048: - *bits = 2048; - *key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919); - return PSA_SUCCESS; -#endif /* PSA_WANT_DH_RFC7919_2048 */ -#if defined(PSA_WANT_DH_RFC7919_3072) - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE3072: - *bits = 3072; - *key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919); - return PSA_SUCCESS; -#endif /* PSA_WANT_DH_RFC7919_3072 */ -#if defined(PSA_WANT_DH_RFC7919_4096) - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE4096: - *bits = 4096; - *key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919); - return PSA_SUCCESS; -#endif /* PSA_WANT_DH_RFC7919_4096 */ -#if defined(PSA_WANT_DH_RFC7919_6144) - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE6144: - *bits = 6144; - *key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919); - return PSA_SUCCESS; -#endif /* PSA_WANT_DH_RFC7919_6144 */ -#if defined(PSA_WANT_DH_RFC7919_8192) - case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192: - *bits = 8192; - *key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919); - return PSA_SUCCESS; -#endif /* PSA_WANT_DH_RFC7919_8192 */ - default: - return PSA_ERROR_NOT_SUPPORTED; - } -} -#endif /* PSA_WANT_ALG_FFDH */ - -int mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange( - mbedtls_ssl_context *ssl, - uint16_t named_group, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - psa_key_attributes_t key_attributes; - size_t own_pubkey_len; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - size_t bits = 0; - psa_key_type_t key_type = PSA_KEY_TYPE_NONE; - psa_algorithm_t alg = PSA_ALG_NONE; - size_t buf_size = (size_t) (end - buf); - - MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH/FFDH computation.")); - - /* Convert EC's TLS ID to PSA key type. */ -#if defined(PSA_WANT_ALG_ECDH) - if (mbedtls_ssl_get_psa_curve_info_from_tls_id( - named_group, &key_type, &bits) == PSA_SUCCESS) { - alg = PSA_ALG_ECDH; - } -#endif -#if defined(PSA_WANT_ALG_FFDH) - if (mbedtls_ssl_get_psa_ffdh_info_from_tls_id(named_group, &bits, - &key_type) == PSA_SUCCESS) { - alg = PSA_ALG_FFDH; - } -#endif - - if (key_type == PSA_KEY_TYPE_NONE) { - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - if (buf_size < PSA_BITS_TO_BYTES(bits)) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - handshake->xxdh_psa_type = key_type; - ssl->handshake->xxdh_psa_bits = bits; - - key_attributes = psa_key_attributes_init(); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&key_attributes, alg); - psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); - psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); - - /* Generate ECDH/FFDH private key. */ - status = psa_generate_key(&key_attributes, - &handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_generate_key", ret); - return ret; - - } - - /* Export the public part of the ECDH/FFDH private key from PSA. */ - status = psa_export_public_key(handshake->xxdh_psa_privkey, - buf, buf_size, - &own_pubkey_len); - - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_export_public_key", ret); - return ret; - } - - *out_len = own_pubkey_len; - - return 0; -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - -/* RFC 8446 section 4.2 - * - * If an implementation receives an extension which it recognizes and which is - * not specified for the message in which it appears, it MUST abort the handshake - * with an "illegal_parameter" alert. - * - */ -int mbedtls_ssl_tls13_check_received_extension( - mbedtls_ssl_context *ssl, - int hs_msg_type, - unsigned int received_extension_type, - uint32_t hs_msg_allowed_extensions_mask) -{ - uint32_t extension_mask = mbedtls_ssl_get_extension_mask( - received_extension_type); - - MBEDTLS_SSL_PRINT_EXT( - 3, hs_msg_type, received_extension_type, "received"); - - if ((extension_mask & hs_msg_allowed_extensions_mask) == 0) { - MBEDTLS_SSL_PRINT_EXT( - 3, hs_msg_type, received_extension_type, "is illegal"); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - ssl->handshake->received_extensions |= extension_mask; - /* - * If it is a message containing extension responses, check that we - * previously sent the extension. - */ - switch (hs_msg_type) { - case MBEDTLS_SSL_HS_SERVER_HELLO: - case MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST: - case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS: - case MBEDTLS_SSL_HS_CERTIFICATE: - /* Check if the received extension is sent by peer message.*/ - if ((ssl->handshake->sent_extensions & extension_mask) != 0) { - return 0; - } - break; - default: - return 0; - } - - MBEDTLS_SSL_PRINT_EXT( - 3, hs_msg_type, received_extension_type, "is unsupported"); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT, - MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION); - return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; -} - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - -/* RFC 8449, section 4: - * - * The ExtensionData of the "record_size_limit" extension is - * RecordSizeLimit: - * uint16 RecordSizeLimit; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - const unsigned char *p = buf; - uint16_t record_size_limit; - const size_t extension_data_len = end - buf; - - if (extension_data_len != - MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH) { - MBEDTLS_SSL_DEBUG_MSG(2, - ("record_size_limit extension has invalid length: %" - MBEDTLS_PRINTF_SIZET " Bytes", - extension_data_len)); - - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - record_size_limit = MBEDTLS_GET_UINT16_BE(p, 0); - - MBEDTLS_SSL_DEBUG_MSG(2, ("RecordSizeLimit: %u Bytes", record_size_limit)); - - /* RFC 8449, section 4: - * - * Endpoints MUST NOT send a "record_size_limit" extension with a value - * smaller than 64. An endpoint MUST treat receipt of a smaller value - * as a fatal error and generate an "illegal_parameter" alert. - */ - if (record_size_limit < MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid record size limit : %u Bytes", - record_size_limit)); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - ssl->session_negotiate->record_size_limit = record_size_limit; - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_write_record_size_limit_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *out_len) -{ - unsigned char *p = buf; - *out_len = 0; - - MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_IN_CONTENT_LEN >= MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN, - "MBEDTLS_SSL_IN_CONTENT_LEN is less than the " - "minimum record size limit"); - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT, p, 0); - MBEDTLS_PUT_UINT16_BE(MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH, - p, 2); - MBEDTLS_PUT_UINT16_BE(MBEDTLS_SSL_IN_CONTENT_LEN, p, 4); - - *out_len = 6; - - MBEDTLS_SSL_DEBUG_MSG(2, ("Sent RecordSizeLimit: %d Bytes", - MBEDTLS_SSL_IN_CONTENT_LEN)); - - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT); - - return 0; -} - -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#endif /* MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/vendor/mbedtls/library/ssl_tls13_invasive.h b/vendor/mbedtls/library/ssl_tls13_invasive.h deleted file mode 100644 index b4506f71c..000000000 --- a/vendor/mbedtls/library/ssl_tls13_invasive.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_SSL_TLS13_INVASIVE_H -#define MBEDTLS_SSL_TLS13_INVASIVE_H - -#include "common.h" - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#include "psa/crypto.h" - -#if defined(MBEDTLS_TEST_HOOKS) -int mbedtls_ssl_tls13_parse_certificate(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end); -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#endif /* MBEDTLS_SSL_TLS13_INVASIVE_H */ diff --git a/vendor/mbedtls/library/ssl_tls13_keys.c b/vendor/mbedtls/library/ssl_tls13_keys.c deleted file mode 100644 index 1967883b6..000000000 --- a/vendor/mbedtls/library/ssl_tls13_keys.c +++ /dev/null @@ -1,1918 +0,0 @@ -/* - * TLS 1.3 key schedule - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#include -#include - -#include "mbedtls/hkdf.h" -#include "debug_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/platform.h" - -#include "ssl_misc.h" -#include "ssl_tls13_keys.h" -#include "ssl_tls13_invasive.h" - -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" - -/* Define a local translating function to save code size by not using too many - * arguments in each translating place. */ -static int local_err_translation(psa_status_t status) -{ - return psa_status_to_mbedtls(status, psa_to_ssl_errors, - ARRAY_LENGTH(psa_to_ssl_errors), - psa_generic_status_to_mbedtls); -} -#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) - -#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ - .name = string, - -struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels = -{ - /* This seems to work in C, despite the string literal being one - * character too long due to the 0-termination. */ - MBEDTLS_SSL_TLS1_3_LABEL_LIST -}; - -#undef MBEDTLS_SSL_TLS1_3_LABEL - -/* - * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule. - * - * The HkdfLabel is specified in RFC 8446 as follows: - * - * struct HkdfLabel { - * uint16 length; // Length of expanded key material - * opaque label<7..255>; // Always prefixed by "tls13 " - * opaque context<0..255>; // Usually a communication transcript hash - * }; - * - * Parameters: - * - desired_length: Length of expanded key material. - * The length field can hold numbers up to 2**16, but HKDF - * can only generate outputs of up to 255 * HASH_LEN bytes. - * It is the caller's responsibility to ensure that this - * limit is not exceeded. In TLS 1.3, SHA256 is the hash - * function with the smallest block size, so a length - * <= 255 * 32 = 8160 is always safe. - * - (label, label_len): label + label length, without "tls13 " prefix - * The label length MUST be less than or equal to - * MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN. - * It is the caller's responsibility to ensure this. - * All (label, label length) pairs used in TLS 1.3 - * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(). - * - (ctx, ctx_len): context + context length - * The context length MUST be less than or equal to - * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN - * It is the caller's responsibility to ensure this. - * - dst: Target buffer for HkdfLabel structure, - * This MUST be a writable buffer of size - * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes. - * - dst_len: Pointer at which to store the actual length of - * the HkdfLabel structure on success. - */ - -/* We need to tell the compiler that we meant to leave out the null character. */ -static const char tls13_label_prefix[6] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "tls13 "; - -#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(label_len, context_len) \ - (2 /* expansion length */ \ - + 1 /* label length */ \ - + label_len \ - + 1 /* context length */ \ - + context_len) - -#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \ - SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \ - sizeof(tls13_label_prefix) + \ - MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN, \ - MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) - -static void ssl_tls13_hkdf_encode_label( - size_t desired_length, - const unsigned char *label, size_t label_len, - const unsigned char *ctx, size_t ctx_len, - unsigned char *dst, size_t *dst_len) -{ - size_t total_label_len = - sizeof(tls13_label_prefix) + label_len; - size_t total_hkdf_lbl_len = - SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(total_label_len, ctx_len); - - unsigned char *p = dst; - - /* Add the size of the expanded key material. */ -#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > UINT16_MAX -#error "The desired key length must fit into an uint16 but \ - MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN is greater than UINT16_MAX" -#endif - - *p++ = MBEDTLS_BYTE_1(desired_length); - *p++ = MBEDTLS_BYTE_0(desired_length); - - /* Add label incl. prefix */ - *p++ = MBEDTLS_BYTE_0(total_label_len); - memcpy(p, tls13_label_prefix, sizeof(tls13_label_prefix)); - p += sizeof(tls13_label_prefix); - memcpy(p, label, label_len); - p += label_len; - - /* Add context value */ - *p++ = MBEDTLS_BYTE_0(ctx_len); - if (ctx_len != 0) { - memcpy(p, ctx, ctx_len); - } - - /* Return total length to the caller. */ - *dst_len = total_hkdf_lbl_len; -} - -int mbedtls_ssl_tls13_hkdf_expand_label( - psa_algorithm_t hash_alg, - const unsigned char *secret, size_t secret_len, - const unsigned char *label, size_t label_len, - const unsigned char *ctx, size_t ctx_len, - unsigned char *buf, size_t buf_len) -{ - unsigned char hkdf_label[SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN]; - size_t hkdf_label_len = 0; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_derivation_operation_t operation = - PSA_KEY_DERIVATION_OPERATION_INIT; - - if (label_len > MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN) { - /* Should never happen since this is an internal - * function, and we know statically which labels - * are allowed. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if (ctx_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) { - /* Should not happen, as above. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if (buf_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN) { - /* Should not happen, as above. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - ssl_tls13_hkdf_encode_label(buf_len, - label, label_len, - ctx, ctx_len, - hkdf_label, - &hkdf_label_len); - - status = psa_key_derivation_setup(&operation, PSA_ALG_HKDF_EXPAND(hash_alg)); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = psa_key_derivation_input_bytes(&operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - secret, - secret_len); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = psa_key_derivation_input_bytes(&operation, - PSA_KEY_DERIVATION_INPUT_INFO, - hkdf_label, - hkdf_label_len); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = psa_key_derivation_output_bytes(&operation, - buf, - buf_len); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - -cleanup: - abort_status = psa_key_derivation_abort(&operation); - status = (status == PSA_SUCCESS ? abort_status : status); - mbedtls_platform_zeroize(hkdf_label, hkdf_label_len); - return PSA_TO_MBEDTLS_ERR(status); -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_make_traffic_key( - psa_algorithm_t hash_alg, - const unsigned char *secret, size_t secret_len, - unsigned char *key, size_t key_len, - unsigned char *iv, size_t iv_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_ssl_tls13_hkdf_expand_label( - hash_alg, - secret, secret_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(key), - NULL, 0, - key, key_len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_hkdf_expand_label( - hash_alg, - secret, secret_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(iv), - NULL, 0, - iv, iv_len); - return ret; -} - -/* - * The traffic keying material is generated from the following inputs: - * - * - One secret value per sender. - * - A purpose value indicating the specific value being generated - * - The desired lengths of key and IV. - * - * The expansion itself is based on HKDF: - * - * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length ) - * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length ) - * - * [sender] denotes the sending side and the Secret value is provided - * by the function caller. Note that we generate server and client side - * keys in a single function call. - */ -int mbedtls_ssl_tls13_make_traffic_keys( - psa_algorithm_t hash_alg, - const unsigned char *client_secret, - const unsigned char *server_secret, size_t secret_len, - size_t key_len, size_t iv_len, - mbedtls_ssl_key_set *keys) -{ - int ret = 0; - - ret = ssl_tls13_make_traffic_key( - hash_alg, client_secret, secret_len, - keys->client_write_key, key_len, - keys->client_write_iv, iv_len); - if (ret != 0) { - return ret; - } - - ret = ssl_tls13_make_traffic_key( - hash_alg, server_secret, secret_len, - keys->server_write_key, key_len, - keys->server_write_iv, iv_len); - if (ret != 0) { - return ret; - } - - keys->key_len = key_len; - keys->iv_len = iv_len; - - return 0; -} - -int mbedtls_ssl_tls13_derive_secret( - psa_algorithm_t hash_alg, - const unsigned char *secret, size_t secret_len, - const unsigned char *label, size_t label_len, - const unsigned char *ctx, size_t ctx_len, - int ctx_hashed, - unsigned char *dstbuf, size_t dstbuf_len) -{ - int ret; - unsigned char hashed_context[PSA_HASH_MAX_SIZE]; - if (ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED) { - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_hash_compute(hash_alg, ctx, ctx_len, hashed_context, - PSA_HASH_LENGTH(hash_alg), &ctx_len); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - return ret; - } - } else { - if (ctx_len > sizeof(hashed_context)) { - /* This should never happen since this function is internal - * and the code sets `ctx_hashed` correctly. - * Let's double-check nonetheless to not run at the risk - * of getting a stack overflow. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - memcpy(hashed_context, ctx, ctx_len); - } - - return mbedtls_ssl_tls13_hkdf_expand_label(hash_alg, - secret, secret_len, - label, label_len, - hashed_context, ctx_len, - dstbuf, dstbuf_len); - -} - -int mbedtls_ssl_tls13_evolve_secret( - psa_algorithm_t hash_alg, - const unsigned char *secret_old, - const unsigned char *input, size_t input_len, - unsigned char *secret_new) -{ - int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - size_t hlen; - unsigned char tmp_secret[PSA_MAC_MAX_SIZE] = { 0 }; - const unsigned char all_zeroes_input[MBEDTLS_TLS1_3_MD_MAX_SIZE] = { 0 }; - const unsigned char *l_input = NULL; - size_t l_input_len; - - psa_key_derivation_operation_t operation = - PSA_KEY_DERIVATION_OPERATION_INIT; - - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - hlen = PSA_HASH_LENGTH(hash_alg); - - /* For non-initial runs, call Derive-Secret( ., "derived", "") - * on the old secret. */ - if (secret_old != NULL) { - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - secret_old, hlen, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(derived), - NULL, 0, /* context */ - MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, - tmp_secret, hlen); - if (ret != 0) { - goto cleanup; - } - } - - ret = 0; - - if (input != NULL && input_len != 0) { - l_input = input; - l_input_len = input_len; - } else { - l_input = all_zeroes_input; - l_input_len = hlen; - } - - status = psa_key_derivation_setup(&operation, - PSA_ALG_HKDF_EXTRACT(hash_alg)); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = psa_key_derivation_input_bytes(&operation, - PSA_KEY_DERIVATION_INPUT_SALT, - tmp_secret, - hlen); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = psa_key_derivation_input_bytes(&operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - l_input, l_input_len); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - - status = psa_key_derivation_output_bytes(&operation, - secret_new, - PSA_HASH_LENGTH(hash_alg)); - - if (status != PSA_SUCCESS) { - goto cleanup; - } - -cleanup: - abort_status = psa_key_derivation_abort(&operation); - status = (status == PSA_SUCCESS ? abort_status : status); - ret = (ret == 0 ? PSA_TO_MBEDTLS_ERR(status) : ret); - mbedtls_platform_zeroize(tmp_secret, sizeof(tmp_secret)); - return ret; -} - -int mbedtls_ssl_tls13_derive_early_secrets( - psa_algorithm_t hash_alg, - unsigned char const *early_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_early_secrets *derived) -{ - int ret; - size_t const hash_len = PSA_HASH_LENGTH(hash_alg); - - /* We should never call this function with an unknown hash, - * but add an assertion anyway. */ - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* - * 0 - * | - * v - * PSK -> HKDF-Extract = Early Secret - * | - * +-----> Derive-Secret(., "c e traffic", ClientHello) - * | = client_early_traffic_secret - * | - * +-----> Derive-Secret(., "e exp master", ClientHello) - * | = early_exporter_master_secret - * v - */ - - /* Create client_early_traffic_secret */ - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - early_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_e_traffic), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->client_early_traffic_secret, - hash_len); - if (ret != 0) { - return ret; - } - - /* Create early exporter */ - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - early_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(e_exp_master), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->early_exporter_master_secret, - hash_len); - if (ret != 0) { - return ret; - } - - return 0; -} - -int mbedtls_ssl_tls13_derive_handshake_secrets( - psa_algorithm_t hash_alg, - unsigned char const *handshake_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_handshake_secrets *derived) -{ - int ret; - size_t const hash_len = PSA_HASH_LENGTH(hash_alg); - - /* We should never call this function with an unknown hash, - * but add an assertion anyway. */ - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* - * - * Handshake Secret - * | - * +-----> Derive-Secret( ., "c hs traffic", - * | ClientHello...ServerHello ) - * | = client_handshake_traffic_secret - * | - * +-----> Derive-Secret( ., "s hs traffic", - * | ClientHello...ServerHello ) - * | = server_handshake_traffic_secret - * - */ - - /* - * Compute client_handshake_traffic_secret with - * Derive-Secret( ., "c hs traffic", ClientHello...ServerHello ) - */ - - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - handshake_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_hs_traffic), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->client_handshake_traffic_secret, - hash_len); - if (ret != 0) { - return ret; - } - - /* - * Compute server_handshake_traffic_secret with - * Derive-Secret( ., "s hs traffic", ClientHello...ServerHello ) - */ - - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - handshake_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_hs_traffic), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->server_handshake_traffic_secret, - hash_len); - if (ret != 0) { - return ret; - } - - return 0; -} - -int mbedtls_ssl_tls13_derive_application_secrets( - psa_algorithm_t hash_alg, - unsigned char const *application_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_application_secrets *derived) -{ - int ret; - size_t const hash_len = PSA_HASH_LENGTH(hash_alg); - - /* We should never call this function with an unknown hash, - * but add an assertion anyway. */ - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* Generate {client,server}_application_traffic_secret_0 - * - * Master Secret - * | - * +-----> Derive-Secret( ., "c ap traffic", - * | ClientHello...server Finished ) - * | = client_application_traffic_secret_0 - * | - * +-----> Derive-Secret( ., "s ap traffic", - * | ClientHello...Server Finished ) - * | = server_application_traffic_secret_0 - * | - * +-----> Derive-Secret( ., "exp master", - * | ClientHello...server Finished) - * | = exporter_master_secret - * - */ - - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - application_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_ap_traffic), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->client_application_traffic_secret_N, - hash_len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - application_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_ap_traffic), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->server_application_traffic_secret_N, - hash_len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - application_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exp_master), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->exporter_master_secret, - hash_len); - if (ret != 0) { - return ret; - } - - return 0; -} - -/* Generate resumption_master_secret for use with the ticket exchange. - * - * This is not integrated with mbedtls_ssl_tls13_derive_application_secrets() - * because it uses the transcript hash up to and including ClientFinished. */ -int mbedtls_ssl_tls13_derive_resumption_master_secret( - psa_algorithm_t hash_alg, - unsigned char const *application_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_application_secrets *derived) -{ - int ret; - size_t const hash_len = PSA_HASH_LENGTH(hash_alg); - - /* We should never call this function with an unknown hash, - * but add an assertion anyway. */ - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - application_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_master), - transcript, transcript_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, - derived->resumption_master_secret, - hash_len); - - if (ret != 0) { - return ret; - } - - return 0; -} - -/** - * \brief Transition into application stage of TLS 1.3 key schedule. - * - * The TLS 1.3 key schedule can be viewed as a simple state machine - * with states Initial -> Early -> Handshake -> Application, and - * this function represents the Handshake -> Application transition. - * - * In the handshake stage, ssl_tls13_generate_application_keys() - * can be used to derive the handshake traffic keys. - * - * \param ssl The SSL context to operate on. This must be in key schedule - * stage \c Handshake. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type( - (mbedtls_md_type_t) handshake->ciphersuite_info->mac); - - /* - * Compute MasterSecret - */ - ret = mbedtls_ssl_tls13_evolve_secret( - hash_alg, - handshake->tls13_master_secrets.handshake, - NULL, 0, - handshake->tls13_master_secrets.app); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF( - 4, "Master secret", - handshake->tls13_master_secrets.app, PSA_HASH_LENGTH(hash_alg)); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_calc_finished_core(psa_algorithm_t hash_alg, - unsigned char const *base_key, - unsigned char const *transcript, - unsigned char *dst, - size_t *dst_len) -{ - mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t hash_len = PSA_HASH_LENGTH(hash_alg); - unsigned char finished_key[PSA_MAC_MAX_SIZE]; - int ret; - psa_algorithm_t alg; - - /* We should never call this function with an unknown hash, - * but add an assertion anyway. */ - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* TLS 1.3 Finished message - * - * struct { - * opaque verify_data[Hash.length]; - * } Finished; - * - * verify_data = - * HMAC( finished_key, - * Hash( Handshake Context + - * Certificate* + - * CertificateVerify* ) - * ) - * - * finished_key = - * HKDF-Expand-Label( BaseKey, "finished", "", Hash.length ) - */ - - ret = mbedtls_ssl_tls13_hkdf_expand_label( - hash_alg, base_key, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(finished), - NULL, 0, - finished_key, hash_len); - if (ret != 0) { - goto exit; - } - - alg = PSA_ALG_HMAC(hash_alg); - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); - - status = psa_import_key(&attributes, finished_key, hash_len, &key); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - - status = psa_mac_compute(key, alg, transcript, hash_len, - dst, hash_len, dst_len); - ret = PSA_TO_MBEDTLS_ERR(status); - -exit: - - status = psa_destroy_key(key); - if (ret == 0) { - ret = PSA_TO_MBEDTLS_ERR(status); - } - - mbedtls_platform_zeroize(finished_key, sizeof(finished_key)); - - return ret; -} - -int mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl, - unsigned char *dst, - size_t dst_len, - size_t *actual_len, - int from) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t transcript_len; - - unsigned char *base_key = NULL; - size_t base_key_len = 0; - mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets = - &ssl->handshake->tls13_hs_secrets; - - mbedtls_md_type_t const md_type = (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac; - - psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type( - (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac); - size_t const hash_len = PSA_HASH_LENGTH(hash_alg); - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_tls13_calculate_verify_data")); - - if (from == MBEDTLS_SSL_IS_CLIENT) { - base_key = tls13_hs_secrets->client_handshake_traffic_secret; - base_key_len = sizeof(tls13_hs_secrets->client_handshake_traffic_secret); - } else { - base_key = tls13_hs_secrets->server_handshake_traffic_secret; - base_key_len = sizeof(tls13_hs_secrets->server_handshake_traffic_secret); - } - - if (dst_len < hash_len) { - ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - goto exit; - } - - ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, - transcript, sizeof(transcript), - &transcript_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_handshake_transcript", ret); - goto exit; - } - MBEDTLS_SSL_DEBUG_BUF(4, "handshake hash", transcript, transcript_len); - - ret = ssl_tls13_calc_finished_core(hash_alg, base_key, - transcript, dst, actual_len); - if (ret != 0) { - goto exit; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "verify_data for finished message", dst, hash_len); - MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_tls13_calculate_verify_data")); - -exit: - /* Erase handshake secrets */ - mbedtls_platform_zeroize(base_key, base_key_len); - mbedtls_platform_zeroize(transcript, sizeof(transcript)); - return ret; -} - -int mbedtls_ssl_tls13_create_psk_binder(mbedtls_ssl_context *ssl, - const psa_algorithm_t hash_alg, - unsigned char const *psk, size_t psk_len, - int psk_type, - unsigned char const *transcript, - unsigned char *result) -{ - int ret = 0; - unsigned char binder_key[PSA_MAC_MAX_SIZE]; - unsigned char early_secret[PSA_MAC_MAX_SIZE]; - size_t const hash_len = PSA_HASH_LENGTH(hash_alg); - size_t actual_len; - -#if !defined(MBEDTLS_DEBUG_C) - ssl = NULL; /* make sure we don't use it except for debug */ - ((void) ssl); -#endif - - /* We should never call this function with an unknown hash, - * but add an assertion anyway. */ - if (!PSA_ALG_IS_HASH(hash_alg)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* - * 0 - * | - * v - * PSK -> HKDF-Extract = Early Secret - * | - * +-----> Derive-Secret(., "ext binder" | "res binder", "") - * | = binder_key - * v - */ - - ret = mbedtls_ssl_tls13_evolve_secret(hash_alg, - NULL, /* Old secret */ - psk, psk_len, /* Input */ - early_secret); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); - goto exit; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_create_psk_binder", - early_secret, hash_len); - - if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - early_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_binder), - NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, - binder_key, hash_len); - MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'res binder'")); - } else { - ret = mbedtls_ssl_tls13_derive_secret( - hash_alg, - early_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(ext_binder), - NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, - binder_key, hash_len); - MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'ext binder'")); - } - - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_secret", ret); - goto exit; - } - - /* - * The binding_value is computed in the same way as the Finished message - * but with the BaseKey being the binder_key. - */ - - ret = ssl_tls13_calc_finished_core(hash_alg, binder_key, transcript, - result, &actual_len); - if (ret != 0) { - goto exit; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "psk binder", result, actual_len); - -exit: - - mbedtls_platform_zeroize(early_secret, sizeof(early_secret)); - mbedtls_platform_zeroize(binder_key, sizeof(binder_key)); - return ret; -} - -int mbedtls_ssl_tls13_populate_transform( - mbedtls_ssl_transform *transform, - int endpoint, int ciphersuite, - mbedtls_ssl_key_set const *traffic_keys, - mbedtls_ssl_context *ssl /* DEBUG ONLY */) -{ -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - int ret; - mbedtls_cipher_info_t const *cipher_info; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - unsigned char const *key_enc; - unsigned char const *iv_enc; - unsigned char const *key_dec; - unsigned char const *iv_dec; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_type_t key_type; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_algorithm_t alg; - size_t key_bits; - psa_status_t status = PSA_SUCCESS; -#endif - -#if !defined(MBEDTLS_DEBUG_C) - ssl = NULL; /* make sure we don't use it except for those cases */ - (void) ssl; -#endif - - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite); - if (ciphersuite_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("ciphersuite info for %d not found", - ciphersuite)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->cipher); - if (cipher_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found", - ciphersuite_info->cipher)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* - * Setup cipher contexts in target transform - */ - if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_enc, - cipher_info)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret); - return ret; - } - - if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec, - cipher_info)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_SSL_SRV_C) - if (endpoint == MBEDTLS_SSL_IS_SERVER) { - key_enc = traffic_keys->server_write_key; - key_dec = traffic_keys->client_write_key; - iv_enc = traffic_keys->server_write_iv; - iv_dec = traffic_keys->client_write_iv; - } else -#endif /* MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_CLI_C) - if (endpoint == MBEDTLS_SSL_IS_CLIENT) { - key_enc = traffic_keys->client_write_key; - key_dec = traffic_keys->server_write_key; - iv_enc = traffic_keys->client_write_iv; - iv_dec = traffic_keys->server_write_iv; - } else -#endif /* MBEDTLS_SSL_CLI_C */ - { - /* should not happen */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - memcpy(transform->iv_enc, iv_enc, traffic_keys->iv_len); - memcpy(transform->iv_dec, iv_dec, traffic_keys->iv_len); - -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_enc, - key_enc, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info), - MBEDTLS_ENCRYPT)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret); - return ret; - } - - if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_dec, - key_dec, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info), - MBEDTLS_DECRYPT)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret); - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* - * Setup other fields in SSL transform - */ - - if ((ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) != 0) { - transform->taglen = 8; - } else { - transform->taglen = 16; - } - - transform->ivlen = traffic_keys->iv_len; - transform->maclen = 0; - transform->fixed_ivlen = transform->ivlen; - transform->tls_version = MBEDTLS_SSL_VERSION_TLS1_3; - - /* We add the true record content type (1 Byte) to the plaintext and - * then pad to the configured granularity. The minimum length of the - * type-extended and padded plaintext is therefore the padding - * granularity. */ - transform->minlen = - transform->taglen + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* - * Setup psa keys and alg - */ - if ((status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) ciphersuite_info->cipher, - transform->taglen, - &alg, - &key_type, - &key_bits)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_cipher_to_psa", PSA_TO_MBEDTLS_ERR(status)); - return PSA_TO_MBEDTLS_ERR(status); - } - - transform->psa_alg = alg; - - if (alg != MBEDTLS_SSL_NULL_CIPHER) { - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, key_type); - - if ((status = psa_import_key(&attributes, - key_enc, - PSA_BITS_TO_BYTES(key_bits), - &transform->psa_key_enc)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET( - 1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status)); - return PSA_TO_MBEDTLS_ERR(status); - } - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); - - if ((status = psa_import_key(&attributes, - key_dec, - PSA_BITS_TO_BYTES(key_bits), - &transform->psa_key_dec)) != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_RET( - 1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status)); - return PSA_TO_MBEDTLS_ERR(status); - } - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_get_cipher_key_info( - const mbedtls_ssl_ciphersuite_t *ciphersuite_info, - size_t *key_len, size_t *iv_len) -{ - psa_key_type_t key_type; - psa_algorithm_t alg; - size_t taglen; - size_t key_bits; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - if (ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) { - taglen = 8; - } else { - taglen = 16; - } - - status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) ciphersuite_info->cipher, taglen, - &alg, &key_type, &key_bits); - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } - - *key_len = PSA_BITS_TO_BYTES(key_bits); - - /* TLS 1.3 only have AEAD ciphers, IV length is unconditionally 12 bytes */ - *iv_len = 12; - - return 0; -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) -/* - * ssl_tls13_generate_early_key() generates the key necessary for protecting - * the early application data and handshake messages as described in section 7 - * of RFC 8446. - * - * NOTE: Only one key is generated, the key for the traffic from the client to - * the server. The TLS 1.3 specification does not define a secret and thus - * a key for server early traffic. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl, - mbedtls_ssl_key_set *traffic_keys) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_type_t md_type; - psa_algorithm_t hash_alg; - size_t hash_len; - unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t transcript_len; - size_t key_len = 0; - size_t iv_len = 0; - mbedtls_ssl_tls13_early_secrets tls13_early_secrets; - - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - handshake->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_early_key")); - - ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret); - goto cleanup; - } - - md_type = (mbedtls_md_type_t) ciphersuite_info->mac; - - hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); - hash_len = PSA_HASH_LENGTH(hash_alg); - - ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, - transcript, - sizeof(transcript), - &transcript_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "mbedtls_ssl_get_handshake_transcript", - ret); - goto cleanup; - } - - ret = mbedtls_ssl_tls13_derive_early_secrets( - hash_alg, handshake->tls13_master_secrets.early, - transcript, transcript_len, &tls13_early_secrets); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_derive_early_secrets", ret); - goto cleanup; - } - - MBEDTLS_SSL_DEBUG_BUF( - 4, "Client early traffic secret", - tls13_early_secrets.client_early_traffic_secret, hash_len); - - /* - * Export client handshake traffic secret - */ - if (ssl->f_export_keys != NULL) { - ssl->f_export_keys( - ssl->p_export_keys, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET, - tls13_early_secrets.client_early_traffic_secret, - hash_len, - handshake->randbytes, - handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, - MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */); - } - - ret = ssl_tls13_make_traffic_key( - hash_alg, - tls13_early_secrets.client_early_traffic_secret, - hash_len, traffic_keys->client_write_key, key_len, - traffic_keys->client_write_iv, iv_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_make_traffic_key", ret); - goto cleanup; - } - traffic_keys->key_len = key_len; - traffic_keys->iv_len = iv_len; - - MBEDTLS_SSL_DEBUG_BUF(4, "client early write_key", - traffic_keys->client_write_key, - traffic_keys->key_len); - - MBEDTLS_SSL_DEBUG_BUF(4, "client early write_iv", - traffic_keys->client_write_iv, - traffic_keys->iv_len); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_early_key")); - -cleanup: - /* Erase early secrets and transcript */ - mbedtls_platform_zeroize( - &tls13_early_secrets, sizeof(mbedtls_ssl_tls13_early_secrets)); - mbedtls_platform_zeroize(transcript, sizeof(transcript)); - return ret; -} - -int mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_key_set traffic_keys; - mbedtls_ssl_transform *transform_earlydata = NULL; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* Next evolution in key schedule: Establish early_data secret and - * key material. */ - ret = ssl_tls13_generate_early_key(ssl, &traffic_keys); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_early_key", - ret); - goto cleanup; - } - - transform_earlydata = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform)); - if (transform_earlydata == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto cleanup; - } - - ret = mbedtls_ssl_tls13_populate_transform( - transform_earlydata, - ssl->conf->endpoint, - handshake->ciphersuite_info->id, - &traffic_keys, - ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret); - goto cleanup; - } - handshake->transform_earlydata = transform_earlydata; - -cleanup: - mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys)); - if (ret != 0) { - mbedtls_free(transform_earlydata); - } - - return ret; -} -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -int mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - psa_algorithm_t hash_alg; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - unsigned char *psk = NULL; - size_t psk_len = 0; - - if (handshake->ciphersuite_info == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("cipher suite info not found")); - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) handshake->ciphersuite_info->mac); -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { - ret = mbedtls_ssl_tls13_export_handshake_psk(ssl, &psk, &psk_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_export_handshake_psk", - ret); - return ret; - } - } -#endif - - ret = mbedtls_ssl_tls13_evolve_secret(hash_alg, NULL, psk, psk_len, - handshake->tls13_master_secrets.early); -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - mbedtls_free((void *) psk); -#endif - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_key_schedule_stage_early", - handshake->tls13_master_secrets.early, - PSA_HASH_LENGTH(hash_alg)); - return 0; -} - -/** - * \brief Compute TLS 1.3 handshake traffic keys. - * - * ssl_tls13_generate_handshake_keys() generates keys necessary for - * protecting the handshake messages, as described in Section 7 of - * RFC 8446. - * - * \param ssl The SSL context to operate on. This must be in - * key schedule stage \c Handshake, see - * ssl_tls13_key_schedule_stage_handshake(). - * \param traffic_keys The address at which to store the handshake traffic - * keys. This must be writable but may be uninitialized. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl, - mbedtls_ssl_key_set *traffic_keys) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_type_t md_type; - psa_algorithm_t hash_alg; - size_t hash_len; - unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t transcript_len; - size_t key_len = 0; - size_t iv_len = 0; - - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - handshake->ciphersuite_info; - mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets = - &handshake->tls13_hs_secrets; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_handshake_keys")); - - ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret); - return ret; - } - - md_type = (mbedtls_md_type_t) ciphersuite_info->mac; - - hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); - hash_len = PSA_HASH_LENGTH(hash_alg); - - ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, - transcript, - sizeof(transcript), - &transcript_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "mbedtls_ssl_get_handshake_transcript", - ret); - return ret; - } - - ret = mbedtls_ssl_tls13_derive_handshake_secrets( - hash_alg, handshake->tls13_master_secrets.handshake, - transcript, transcript_len, tls13_hs_secrets); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_handshake_secrets", - ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "Client handshake traffic secret", - tls13_hs_secrets->client_handshake_traffic_secret, - hash_len); - MBEDTLS_SSL_DEBUG_BUF(4, "Server handshake traffic secret", - tls13_hs_secrets->server_handshake_traffic_secret, - hash_len); - - /* - * Export client handshake traffic secret - */ - if (ssl->f_export_keys != NULL) { - ssl->f_export_keys( - ssl->p_export_keys, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET, - tls13_hs_secrets->client_handshake_traffic_secret, - hash_len, - handshake->randbytes, - handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, - MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */); - - ssl->f_export_keys( - ssl->p_export_keys, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET, - tls13_hs_secrets->server_handshake_traffic_secret, - hash_len, - handshake->randbytes, - handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, - MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */); - } - - ret = mbedtls_ssl_tls13_make_traffic_keys( - hash_alg, - tls13_hs_secrets->client_handshake_traffic_secret, - tls13_hs_secrets->server_handshake_traffic_secret, - hash_len, key_len, iv_len, traffic_keys); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret); - goto exit; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_key", - traffic_keys->client_write_key, - traffic_keys->key_len); - - MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_key", - traffic_keys->server_write_key, - traffic_keys->key_len); - - MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_iv", - traffic_keys->client_write_iv, - traffic_keys->iv_len); - - MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_iv", - traffic_keys->server_write_iv, - traffic_keys->iv_len); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_handshake_keys")); - -exit: - - return ret; -} - -/** - * \brief Transition into handshake stage of TLS 1.3 key schedule. - * - * The TLS 1.3 key schedule can be viewed as a simple state machine - * with states Initial -> Early -> Handshake -> Application, and - * this function represents the Early -> Handshake transition. - * - * In the handshake stage, ssl_tls13_generate_handshake_keys() - * can be used to derive the handshake traffic keys. - * - * \param ssl The SSL context to operate on. This must be in key schedule - * stage \c Early. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type( - (mbedtls_md_type_t) handshake->ciphersuite_info->mac); - unsigned char *shared_secret = NULL; - size_t shared_secret_len = 0; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - /* - * Compute ECDHE secret used to compute the handshake secret from which - * client_handshake_traffic_secret and server_handshake_traffic_secret - * are derived in the handshake secret derivation stage. - */ - if (mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral(ssl)) { - if (mbedtls_ssl_tls13_named_group_is_ecdhe(handshake->offered_group_id) || - mbedtls_ssl_tls13_named_group_is_ffdh(handshake->offered_group_id)) { -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) - psa_algorithm_t alg = - mbedtls_ssl_tls13_named_group_is_ecdhe(handshake->offered_group_id) ? - PSA_ALG_ECDH : PSA_ALG_FFDH; - - /* Compute ECDH shared secret. */ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - - status = psa_get_key_attributes(handshake->xxdh_psa_privkey, - &key_attributes); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - } - - shared_secret_len = PSA_BITS_TO_BYTES( - psa_get_key_bits(&key_attributes)); - shared_secret = mbedtls_calloc(1, shared_secret_len); - if (shared_secret == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - status = psa_raw_key_agreement( - alg, handshake->xxdh_psa_privkey, - handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len, - shared_secret, shared_secret_len, &shared_secret_len); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret); - goto cleanup; - } - - status = psa_destroy_key(handshake->xxdh_psa_privkey); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret); - goto cleanup; - } - - handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("Group not supported.")); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - } -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - - /* - * Compute the Handshake Secret - */ - ret = mbedtls_ssl_tls13_evolve_secret( - hash_alg, handshake->tls13_master_secrets.early, - shared_secret, shared_secret_len, - handshake->tls13_master_secrets.handshake); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); - goto cleanup; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "Handshake secret", - handshake->tls13_master_secrets.handshake, - PSA_HASH_LENGTH(hash_alg)); - -cleanup: - if (shared_secret != NULL) { - mbedtls_zeroize_and_free(shared_secret, shared_secret_len); - } - - return ret; -} - -/** - * \brief Compute TLS 1.3 application traffic keys. - * - * ssl_tls13_generate_application_keys() generates application traffic - * keys, since any record following a 1-RTT Finished message MUST be - * encrypted under the application traffic key. - * - * \param ssl The SSL context to operate on. This must be in - * key schedule stage \c Application, see - * ssl_tls13_key_schedule_stage_application(). - * \param traffic_keys The address at which to store the application traffic - * keys. This must be writable but may be uninitialized. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_generate_application_keys( - mbedtls_ssl_context *ssl, - mbedtls_ssl_key_set *traffic_keys) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* Address at which to store the application secrets */ - mbedtls_ssl_tls13_application_secrets * const app_secrets = - &ssl->session_negotiate->app_secrets; - - /* Holding the transcript up to and including the ServerFinished */ - unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t transcript_len; - - /* Variables relating to the hash for the chosen ciphersuite. */ - mbedtls_md_type_t md_type; - - psa_algorithm_t hash_alg; - size_t hash_len; - - /* Variables relating to the cipher for the chosen ciphersuite. */ - size_t key_len = 0, iv_len = 0; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive application traffic keys")); - - /* Extract basic information about hash and ciphersuite */ - - ret = ssl_tls13_get_cipher_key_info(handshake->ciphersuite_info, - &key_len, &iv_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret); - goto cleanup; - } - - md_type = (mbedtls_md_type_t) handshake->ciphersuite_info->mac; - - hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) handshake->ciphersuite_info->mac); - hash_len = PSA_HASH_LENGTH(hash_alg); - - /* Compute current handshake transcript. It's the caller's responsibility - * to call this at the right time, that is, after the ServerFinished. */ - - ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, - transcript, sizeof(transcript), - &transcript_len); - if (ret != 0) { - goto cleanup; - } - - /* Compute application secrets from master secret and transcript hash. */ - - ret = mbedtls_ssl_tls13_derive_application_secrets( - hash_alg, handshake->tls13_master_secrets.app, - transcript, transcript_len, app_secrets); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_derive_application_secrets", ret); - goto cleanup; - } - - /* Derive first epoch of IV + Key for application traffic. */ - - ret = mbedtls_ssl_tls13_make_traffic_keys( - hash_alg, - app_secrets->client_application_traffic_secret_N, - app_secrets->server_application_traffic_secret_N, - hash_len, key_len, iv_len, traffic_keys); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret); - goto cleanup; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "Client application traffic secret", - app_secrets->client_application_traffic_secret_N, - hash_len); - - MBEDTLS_SSL_DEBUG_BUF(4, "Server application traffic secret", - app_secrets->server_application_traffic_secret_N, - hash_len); - - /* - * Export client/server application traffic secret 0 - */ - if (ssl->f_export_keys != NULL) { - ssl->f_export_keys( - ssl->p_export_keys, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET, - app_secrets->client_application_traffic_secret_N, hash_len, - handshake->randbytes, - handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, - MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by - a new constant for TLS 1.3! */); - - ssl->f_export_keys( - ssl->p_export_keys, - MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET, - app_secrets->server_application_traffic_secret_N, hash_len, - handshake->randbytes, - handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, - MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by - a new constant for TLS 1.3! */); - } - - MBEDTLS_SSL_DEBUG_BUF(4, "client application_write_key:", - traffic_keys->client_write_key, key_len); - MBEDTLS_SSL_DEBUG_BUF(4, "server application write key", - traffic_keys->server_write_key, key_len); - MBEDTLS_SSL_DEBUG_BUF(4, "client application write IV", - traffic_keys->client_write_iv, iv_len); - MBEDTLS_SSL_DEBUG_BUF(4, "server application write IV", - traffic_keys->server_write_iv, iv_len); - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= derive application traffic keys")); - -cleanup: - /* randbytes is not used again */ - mbedtls_platform_zeroize(ssl->handshake->randbytes, - sizeof(ssl->handshake->randbytes)); - - mbedtls_platform_zeroize(transcript, sizeof(transcript)); - return ret; -} - -int mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_key_set traffic_keys; - mbedtls_ssl_transform *transform_handshake = NULL; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* Compute handshake secret */ - ret = ssl_tls13_key_schedule_stage_handshake(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_master_secret", ret); - goto cleanup; - } - - /* Next evolution in key schedule: Establish handshake secret and - * key material. */ - ret = ssl_tls13_generate_handshake_keys(ssl, &traffic_keys); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_handshake_keys", - ret); - goto cleanup; - } - - transform_handshake = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform)); - if (transform_handshake == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto cleanup; - } - - ret = mbedtls_ssl_tls13_populate_transform( - transform_handshake, - ssl->conf->endpoint, - handshake->ciphersuite_info->id, - &traffic_keys, - ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret); - goto cleanup; - } - handshake->transform_handshake = transform_handshake; - -cleanup: - mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys)); - if (ret != 0) { - mbedtls_free(transform_handshake); - } - - return ret; -} - -int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_md_type_t md_type; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - size_t transcript_len; - - MBEDTLS_SSL_DEBUG_MSG( - 2, ("=> mbedtls_ssl_tls13_compute_resumption_master_secret")); - - md_type = (mbedtls_md_type_t) handshake->ciphersuite_info->mac; - - ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, - transcript, sizeof(transcript), - &transcript_len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_derive_resumption_master_secret( - mbedtls_md_psa_alg_from_type(md_type), - handshake->tls13_master_secrets.app, - transcript, transcript_len, - &ssl->session_negotiate->app_secrets); - if (ret != 0) { - return ret; - } - - /* Erase master secrets */ - mbedtls_platform_zeroize(&handshake->tls13_master_secrets, - sizeof(handshake->tls13_master_secrets)); - - MBEDTLS_SSL_DEBUG_BUF( - 4, "Resumption master secret", - ssl->session_negotiate->app_secrets.resumption_master_secret, - PSA_HASH_LENGTH(mbedtls_md_psa_alg_from_type(md_type))); - - MBEDTLS_SSL_DEBUG_MSG( - 2, ("<= mbedtls_ssl_tls13_compute_resumption_master_secret")); - return 0; -} - -int mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_key_set traffic_keys; - mbedtls_ssl_transform *transform_application = NULL; - - ret = ssl_tls13_key_schedule_stage_application(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "ssl_tls13_key_schedule_stage_application", ret); - goto cleanup; - } - - ret = ssl_tls13_generate_application_keys(ssl, &traffic_keys); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "ssl_tls13_generate_application_keys", ret); - goto cleanup; - } - - transform_application = - mbedtls_calloc(1, sizeof(mbedtls_ssl_transform)); - if (transform_application == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto cleanup; - } - - ret = mbedtls_ssl_tls13_populate_transform( - transform_application, - ssl->conf->endpoint, - ssl->handshake->ciphersuite_info->id, - &traffic_keys, - ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret); - goto cleanup; - } - - ssl->transform_application = transform_application; - -cleanup: - - mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys)); - if (ret != 0) { - mbedtls_free(transform_application); - } - return ret; -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, - unsigned char **psk, - size_t *psk_len) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - *psk_len = 0; - *psk = NULL; - - if (mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - status = psa_get_key_attributes(ssl->handshake->psk_opaque, &key_attributes); - if (status != PSA_SUCCESS) { - return PSA_TO_MBEDTLS_ERR(status); - } - - *psk_len = PSA_BITS_TO_BYTES(psa_get_key_bits(&key_attributes)); - *psk = mbedtls_calloc(1, *psk_len); - if (*psk == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - status = psa_export_key(ssl->handshake->psk_opaque, - (uint8_t *) *psk, *psk_len, psk_len); - if (status != PSA_SUCCESS) { - mbedtls_free((void *) *psk); - *psk = NULL; - return PSA_TO_MBEDTLS_ERR(status); - } - return 0; -#else - *psk = ssl->handshake->psk; - *psk_len = ssl->handshake->psk_len; - if (*psk == NULL) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - return 0; -#endif /* !MBEDTLS_USE_PSA_CRYPTO */ -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) -int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg, - const unsigned char *secret, const size_t secret_len, - const unsigned char *label, const size_t label_len, - const unsigned char *context_value, const size_t context_len, - unsigned char *out, const size_t out_len) -{ - size_t hash_len = PSA_HASH_LENGTH(hash_alg); - unsigned char hkdf_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - int ret = 0; - - ret = mbedtls_ssl_tls13_derive_secret(hash_alg, secret, secret_len, label, label_len, NULL, 0, - MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, hkdf_secret, - hash_len); - if (ret != 0) { - goto exit; - } - ret = mbedtls_ssl_tls13_derive_secret(hash_alg, - hkdf_secret, - hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exporter), - context_value, - context_len, - MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, - out, - out_len); - -exit: - mbedtls_platform_zeroize(hkdf_secret, sizeof(hkdf_secret)); - return ret; -} -#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */ - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/vendor/mbedtls/library/ssl_tls13_keys.h b/vendor/mbedtls/library/ssl_tls13_keys.h deleted file mode 100644 index 1509e9a4d..000000000 --- a/vendor/mbedtls/library/ssl_tls13_keys.h +++ /dev/null @@ -1,668 +0,0 @@ -/* - * TLS 1.3 key schedule - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#if !defined(MBEDTLS_SSL_TLS1_3_KEYS_H) -#define MBEDTLS_SSL_TLS1_3_KEYS_H - -/* This requires MBEDTLS_SSL_TLS1_3_LABEL( idx, name, string ) to be defined at - * the point of use. See e.g. the definition of mbedtls_ssl_tls13_labels_union - * below. */ -#define MBEDTLS_SSL_TLS1_3_LABEL_LIST \ - MBEDTLS_SSL_TLS1_3_LABEL(finished, "finished") \ - MBEDTLS_SSL_TLS1_3_LABEL(resumption, "resumption") \ - MBEDTLS_SSL_TLS1_3_LABEL(traffic_upd, "traffic upd") \ - MBEDTLS_SSL_TLS1_3_LABEL(exporter, "exporter") \ - MBEDTLS_SSL_TLS1_3_LABEL(key, "key") \ - MBEDTLS_SSL_TLS1_3_LABEL(iv, "iv") \ - MBEDTLS_SSL_TLS1_3_LABEL(c_hs_traffic, "c hs traffic") \ - MBEDTLS_SSL_TLS1_3_LABEL(c_ap_traffic, "c ap traffic") \ - MBEDTLS_SSL_TLS1_3_LABEL(c_e_traffic, "c e traffic") \ - MBEDTLS_SSL_TLS1_3_LABEL(s_hs_traffic, "s hs traffic") \ - MBEDTLS_SSL_TLS1_3_LABEL(s_ap_traffic, "s ap traffic") \ - MBEDTLS_SSL_TLS1_3_LABEL(s_e_traffic, "s e traffic") \ - MBEDTLS_SSL_TLS1_3_LABEL(e_exp_master, "e exp master") \ - MBEDTLS_SSL_TLS1_3_LABEL(res_master, "res master") \ - MBEDTLS_SSL_TLS1_3_LABEL(exp_master, "exp master") \ - MBEDTLS_SSL_TLS1_3_LABEL(ext_binder, "ext binder") \ - MBEDTLS_SSL_TLS1_3_LABEL(res_binder, "res binder") \ - MBEDTLS_SSL_TLS1_3_LABEL(derived, "derived") \ - MBEDTLS_SSL_TLS1_3_LABEL(client_cv, "TLS 1.3, client CertificateVerify") \ - MBEDTLS_SSL_TLS1_3_LABEL(server_cv, "TLS 1.3, server CertificateVerify") - -#define MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED 0 -#define MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED 1 - -#define MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL 0 -#define MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION 1 - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - -/* We need to tell the compiler that we meant to leave out the null character. */ -#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ - const unsigned char name [sizeof(string) - 1] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING; - -union mbedtls_ssl_tls13_labels_union { - MBEDTLS_SSL_TLS1_3_LABEL_LIST -}; -struct mbedtls_ssl_tls13_labels_struct { - MBEDTLS_SSL_TLS1_3_LABEL_LIST -}; -#undef MBEDTLS_SSL_TLS1_3_LABEL - -extern const struct mbedtls_ssl_tls13_labels_struct mbedtls_ssl_tls13_labels; - -#define MBEDTLS_SSL_TLS1_3_LBL_LEN(LABEL) \ - sizeof(mbedtls_ssl_tls13_labels.LABEL) - -#define MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(LABEL) \ - mbedtls_ssl_tls13_labels.LABEL, \ - MBEDTLS_SSL_TLS1_3_LBL_LEN(LABEL) - -/* Maximum length of the label field in the HkdfLabel struct defined in - * RFC 8446, Section 7.1, excluding the "tls13 " prefix. */ -#define MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN 249 - -/* The maximum length of HKDF contexts used in the TLS 1.3 standard. - * Since contexts are always hashes of message transcripts, this can - * be approximated from above by the maximum hash size. */ -#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN \ - PSA_HASH_MAX_SIZE - -/* Maximum desired length for expanded key material generated - * by HKDF-Expand-Label. This algorithm can output up to 255 * hash_size - * bytes of key material where hash_size is the output size of the - * underlying hash function. */ -#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN \ - (255 * MBEDTLS_TLS1_3_MD_MAX_SIZE) - -/** - * \brief The \c HKDF-Expand-Label function from - * the TLS 1.3 standard RFC 8446. - * - * - * HKDF-Expand-Label( Secret, Label, Context, Length ) = - * HKDF-Expand( Secret, HkdfLabel, Length ) - * - * - * \param hash_alg The identifier for the hash algorithm to use. - * \param secret The \c Secret argument to \c HKDF-Expand-Label. - * This must be a readable buffer of length - * \p secret_len Bytes. - * \param secret_len The length of \p secret in Bytes. - * \param label The \c Label argument to \c HKDF-Expand-Label. - * This must be a readable buffer of length - * \p label_len Bytes. - * \param label_len The length of \p label in Bytes. - * \param ctx The \c Context argument to \c HKDF-Expand-Label. - * This must be a readable buffer of length \p ctx_len Bytes. - * \param ctx_len The length of \p context in Bytes. - * \param buf The destination buffer to hold the expanded secret. - * This must be a writable buffer of length \p buf_len Bytes. - * \param buf_len The desired size of the expanded secret in Bytes. - * - * \returns \c 0 on success. - * \return A negative error code on failure. - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_hkdf_expand_label( - psa_algorithm_t hash_alg, - const unsigned char *secret, size_t secret_len, - const unsigned char *label, size_t label_len, - const unsigned char *ctx, size_t ctx_len, - unsigned char *buf, size_t buf_len); - -/** - * \brief This function is part of the TLS 1.3 key schedule. - * It extracts key and IV for the actual client/server traffic - * from the client/server traffic secrets. - * - * From RFC 8446: - * - * - * [sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length) - * [sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length)* - * - * - * \param hash_alg The identifier for the hash algorithm to be used - * for the HKDF-based expansion of the secret. - * \param client_secret The client traffic secret. - * This must be a readable buffer of size - * \p secret_len Bytes - * \param server_secret The server traffic secret. - * This must be a readable buffer of size - * \p secret_len Bytes - * \param secret_len Length of the secrets \p client_secret and - * \p server_secret in Bytes. - * \param key_len The desired length of the key to be extracted in Bytes. - * \param iv_len The desired length of the IV to be extracted in Bytes. - * \param keys The address of the structure holding the generated - * keys and IVs. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_make_traffic_keys( - psa_algorithm_t hash_alg, - const unsigned char *client_secret, - const unsigned char *server_secret, size_t secret_len, - size_t key_len, size_t iv_len, - mbedtls_ssl_key_set *keys); - -/** - * \brief The \c Derive-Secret function from the TLS 1.3 standard RFC 8446. - * - * - * Derive-Secret( Secret, Label, Messages ) = - * HKDF-Expand-Label( Secret, Label, - * Hash( Messages ), - * Hash.Length ) ) - * - * - * \param hash_alg The identifier for the hash function used for the - * applications of HKDF. - * \param secret The \c Secret argument to the \c Derive-Secret function. - * This must be a readable buffer of length - * \p secret_len Bytes. - * \param secret_len The length of \p secret in Bytes. - * \param label The \c Label argument to the \c Derive-Secret function. - * This must be a readable buffer of length - * \p label_len Bytes. - * \param label_len The length of \p label in Bytes. - * \param ctx The hash of the \c Messages argument to the - * \c Derive-Secret function, or the \c Messages argument - * itself, depending on \p ctx_hashed. - * \param ctx_len The length of \p ctx in Bytes. - * \param ctx_hashed This indicates whether the \p ctx contains the hash of - * the \c Messages argument in the application of the - * \c Derive-Secret function - * (value MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED), or whether - * it is the content of \c Messages itself, in which case - * the function takes care of the hashing - * (value MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED). - * \param dstbuf The target buffer to write the output of - * \c Derive-Secret to. This must be a writable buffer of - * size \p dtsbuf_len Bytes. - * \param dstbuf_len The length of \p dstbuf in Bytes. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_derive_secret( - psa_algorithm_t hash_alg, - const unsigned char *secret, size_t secret_len, - const unsigned char *label, size_t label_len, - const unsigned char *ctx, size_t ctx_len, - int ctx_hashed, - unsigned char *dstbuf, size_t dstbuf_len); - -/** - * \brief Derive TLS 1.3 early data key material from early secret. - * - * This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret() - * with the appropriate labels. - * - * - * Early Secret - * | - * +-----> Derive-Secret(., "c e traffic", ClientHello) - * | = client_early_traffic_secret - * | - * +-----> Derive-Secret(., "e exp master", ClientHello) - * . = early_exporter_master_secret - * . - * . - * - * - * \note To obtain the actual key and IV for the early data traffic, - * the client secret derived by this function need to be - * further processed by mbedtls_ssl_tls13_make_traffic_keys(). - * - * \note The binder key, which is also generated from the early secret, - * is omitted here. Its calculation is part of the separate routine - * mbedtls_ssl_tls13_create_psk_binder(). - * - * \param hash_alg The hash algorithm associated with the PSK for which - * early data key material is being derived. - * \param early_secret The early secret from which the early data key material - * should be derived. This must be a readable buffer whose - * length is the digest size of the hash algorithm - * represented by \p md_size. - * \param transcript The transcript of the handshake so far, calculated with - * respect to \p hash_alg. This must be a readable buffer - * whose length is the digest size of the hash algorithm - * represented by \p md_size. - * \param derived The address of the structure in which to store - * the early data key material. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_derive_early_secrets( - psa_algorithm_t hash_alg, - unsigned char const *early_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_early_secrets *derived); - -/** - * \brief Derive TLS 1.3 handshake key material from the handshake secret. - * - * This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret() - * with the appropriate labels from the standard. - * - * - * Handshake Secret - * | - * +-----> Derive-Secret( ., "c hs traffic", - * | ClientHello...ServerHello ) - * | = client_handshake_traffic_secret - * | - * +-----> Derive-Secret( ., "s hs traffic", - * . ClientHello...ServerHello ) - * . = server_handshake_traffic_secret - * . - * - * - * \note To obtain the actual key and IV for the encrypted handshake traffic, - * the client and server secret derived by this function need to be - * further processed by mbedtls_ssl_tls13_make_traffic_keys(). - * - * \param hash_alg The hash algorithm associated with the ciphersuite - * that's being used for the connection. - * \param handshake_secret The handshake secret from which the handshake key - * material should be derived. This must be a readable - * buffer whose length is the digest size of the hash - * algorithm represented by \p md_size. - * \param transcript The transcript of the handshake so far, calculated - * with respect to \p hash_alg. This must be a readable - * buffer whose length is the digest size of the hash - * algorithm represented by \p md_size. - * \param derived The address of the structure in which to - * store the handshake key material. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_derive_handshake_secrets( - psa_algorithm_t hash_alg, - unsigned char const *handshake_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_handshake_secrets *derived); - -/** - * \brief Derive TLS 1.3 application key material from the master secret. - * - * This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret() - * with the appropriate labels from the standard. - * - * - * Master Secret - * | - * +-----> Derive-Secret( ., "c ap traffic", - * | ClientHello...server Finished ) - * | = client_application_traffic_secret_0 - * | - * +-----> Derive-Secret( ., "s ap traffic", - * | ClientHello...Server Finished ) - * | = server_application_traffic_secret_0 - * | - * +-----> Derive-Secret( ., "exp master", - * . ClientHello...server Finished) - * . = exporter_master_secret - * . - * - * - * \note To obtain the actual key and IV for the (0-th) application traffic, - * the client and server secret derived by this function need to be - * further processed by mbedtls_ssl_tls13_make_traffic_keys(). - * - * \param hash_alg The hash algorithm associated with the ciphersuite - * that's being used for the connection. - * \param master_secret The master secret from which the application key - * material should be derived. This must be a readable - * buffer whose length is the digest size of the hash - * algorithm represented by \p md_size. - * \param transcript The transcript of the handshake up to and including - * the ServerFinished message, calculated with respect - * to \p hash_alg. This must be a readable buffer whose - * length is the digest size of the hash algorithm - * represented by \p hash_alg. - * \param derived The address of the structure in which to - * store the application key material. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_derive_application_secrets( - psa_algorithm_t hash_alg, - unsigned char const *master_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_application_secrets *derived); - -/** - * \brief Derive TLS 1.3 resumption master secret from the master secret. - * - * This is a small wrapper invoking mbedtls_ssl_tls13_derive_secret() - * with the appropriate labels from the standard. - * - * \param hash_alg The hash algorithm used in the application for which - * key material is being derived. - * \param application_secret The application secret from which the resumption master - * secret should be derived. This must be a readable - * buffer whose length is the digest size of the hash - * algorithm represented by \p md_size. - * \param transcript The transcript of the handshake up to and including - * the ClientFinished message, calculated with respect - * to \p hash_alg. This must be a readable buffer whose - * length is the digest size of the hash algorithm - * represented by \p hash_alg. - * \param transcript_len The length of \p transcript in Bytes. - * \param derived The address of the structure in which to - * store the resumption master secret. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_derive_resumption_master_secret( - psa_algorithm_t hash_alg, - unsigned char const *application_secret, - unsigned char const *transcript, size_t transcript_len, - mbedtls_ssl_tls13_application_secrets *derived); - -/** - * \brief Compute the next secret in the TLS 1.3 key schedule - * - * The TLS 1.3 key schedule proceeds as follows to compute - * the three main secrets during the handshake: The early - * secret for early data, the handshake secret for all - * other encrypted handshake messages, and the master - * secret for all application traffic. - * - * - * 0 - * | - * v - * PSK -> HKDF-Extract = Early Secret - * | - * v - * Derive-Secret( ., "derived", "" ) - * | - * v - * (EC)DHE -> HKDF-Extract = Handshake Secret - * | - * v - * Derive-Secret( ., "derived", "" ) - * | - * v - * 0 -> HKDF-Extract = Master Secret - * - * - * Each of the three secrets in turn is the basis for further - * key derivations, such as the derivation of traffic keys and IVs; - * see e.g. mbedtls_ssl_tls13_make_traffic_keys(). - * - * This function implements one step in this evolution of secrets: - * - * - * old_secret - * | - * v - * Derive-Secret( ., "derived", "" ) - * | - * v - * input -> HKDF-Extract = new_secret - * - * - * \param hash_alg The identifier for the hash function used for the - * applications of HKDF. - * \param secret_old The address of the buffer holding the old secret - * on function entry. If not \c NULL, this must be a - * readable buffer whose size matches the output size - * of the hash function represented by \p hash_alg. - * If \c NULL, an all \c 0 array will be used instead. - * \param input The address of the buffer holding the additional - * input for the key derivation (e.g., the PSK or the - * ephemeral (EC)DH secret). If not \c NULL, this must be - * a readable buffer whose size \p input_len Bytes. - * If \c NULL, an all \c 0 array will be used instead. - * \param input_len The length of \p input in Bytes. - * \param secret_new The address of the buffer holding the new secret - * on function exit. This must be a writable buffer - * whose size matches the output size of the hash - * function represented by \p hash_alg. - * This may be the same as \p secret_old. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_evolve_secret( - psa_algorithm_t hash_alg, - const unsigned char *secret_old, - const unsigned char *input, size_t input_len, - unsigned char *secret_new); - -/** - * \brief Calculate a TLS 1.3 PSK binder. - * - * \param ssl The SSL context. This is used for debugging only and may - * be \c NULL if MBEDTLS_DEBUG_C is disabled. - * \param hash_alg The hash algorithm associated to the PSK \p psk. - * \param psk The buffer holding the PSK for which to create a binder. - * \param psk_len The size of \p psk in bytes. - * \param psk_type This indicates whether the PSK \p psk is externally - * provisioned (#MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL) or a - * resumption PSK (#MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION). - * \param transcript The handshake transcript up to the point where the - * PSK binder calculation happens. This must be readable, - * and its size must be equal to the digest size of - * the hash algorithm represented by \p hash_alg. - * \param result The address at which to store the PSK binder on success. - * This must be writable, and its size must be equal to the - * digest size of the hash algorithm represented by - * \p hash_alg. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_create_psk_binder(mbedtls_ssl_context *ssl, - const psa_algorithm_t hash_alg, - unsigned char const *psk, size_t psk_len, - int psk_type, - unsigned char const *transcript, - unsigned char *result); - -/** - * \bref Setup an SSL transform structure representing the - * record protection mechanism used by TLS 1.3 - * - * \param transform The SSL transform structure to be created. This must have - * been initialized through mbedtls_ssl_transform_init() and - * not used in any other way prior to calling this function. - * In particular, this function does not clean up the - * transform structure prior to installing the new keys. - * \param endpoint Indicates whether the transform is for the client - * (value #MBEDTLS_SSL_IS_CLIENT) or the server - * (value #MBEDTLS_SSL_IS_SERVER). - * \param ciphersuite The numerical identifier for the ciphersuite to use. - * This must be one of the identifiers listed in - * ssl_ciphersuites.h. - * \param traffic_keys The key material to use. No reference is stored in - * the SSL transform being generated, and the caller - * should destroy the key material afterwards. - * \param ssl (Debug-only) The SSL context to use for debug output - * in case of failure. This parameter is only needed if - * #MBEDTLS_DEBUG_C is set, and is ignored otherwise. - * - * \return \c 0 on success. In this case, \p transform is ready to - * be used with mbedtls_ssl_transform_decrypt() and - * mbedtls_ssl_transform_encrypt(). - * \return A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform *transform, - int endpoint, - int ciphersuite, - mbedtls_ssl_key_set const *traffic_keys, - mbedtls_ssl_context *ssl); - -/* - * TLS 1.3 key schedule evolutions - * - * Early -> Handshake -> Application - * - * Small wrappers around mbedtls_ssl_tls13_evolve_secret(). - */ - -/** - * \brief Begin TLS 1.3 key schedule by calculating early secret. - * - * The TLS 1.3 key schedule can be viewed as a simple state machine - * with states Initial -> Early -> Handshake -> Application, and - * this function represents the Initial -> Early transition. - * - * \param ssl The SSL context to operate on. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl); - -/** - * \brief Compute TLS 1.3 resumption master secret. - * - * \param ssl The SSL context to operate on. This must be in - * key schedule stage \c Application, see - * mbedtls_ssl_tls13_key_schedule_stage_application(). - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl); - -/** - * \brief Calculate the verify_data value for the client or server TLS 1.3 - * Finished message. - * - * \param ssl The SSL context to operate on. This must be in - * key schedule stage \c Handshake, see - * mbedtls_ssl_tls13_key_schedule_stage_application(). - * \param dst The address at which to write the verify_data value. - * \param dst_len The size of \p dst in bytes. - * \param actual_len The address at which to store the amount of data - * actually written to \p dst upon success. - * \param which The message to calculate the `verify_data` for: - * - #MBEDTLS_SSL_IS_CLIENT for the Client's Finished message - * - #MBEDTLS_SSL_IS_SERVER for the Server's Finished message - * - * \note Both client and server call this function twice, once to - * generate their own Finished message, and once to verify the - * peer's Finished message. - - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl, - unsigned char *dst, - size_t dst_len, - size_t *actual_len, - int which); - -#if defined(MBEDTLS_SSL_EARLY_DATA) -/** - * \brief Compute TLS 1.3 early transform - * - * \param ssl The SSL context to operate on. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - * - * \warning The function does not compute the early master secret. Call - * mbedtls_ssl_tls13_key_schedule_stage_early() before to - * call this function to generate the early master secret. - * \note For a client/server endpoint, the function computes only the - * encryption/decryption part of the transform as the decryption/ - * encryption part is not defined by the specification (no early - * traffic from the server to the client). - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -/** - * \brief Compute TLS 1.3 handshake transform - * - * \param ssl The SSL context to operate on. The early secret must have been - * computed. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context *ssl); - -/** - * \brief Compute TLS 1.3 application transform - * - * \param ssl The SSL context to operate on. The early secret must have been - * computed. - * - * \returns \c 0 on success. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -/** - * \brief Export TLS 1.3 PSK from handshake context - * - * \param[in] ssl The SSL context to operate on. - * \param[out] psk PSK output pointer. - * \param[out] psk_len Length of PSK. - * - * \returns \c 0 if there is a configured PSK and it was exported - * successfully. - * \returns A negative error code on failure. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, - unsigned char **psk, - size_t *psk_len); -#endif - -/** - * \brief Calculate TLS-Exporter function as defined in RFC 8446, Section 7.5. - * - * \param[in] hash_alg The hash algorithm. - * \param[in] secret The secret to use. (Should be the exporter master secret.) - * \param[in] secret_len Length of secret. - * \param[in] label The label of the exported key. - * \param[in] label_len The length of label. - * \param[out] out The output buffer for the exported key. Must have room for at least out_len bytes. - * \param[in] out_len Length of the key to generate. - */ -int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg, - const unsigned char *secret, const size_t secret_len, - const unsigned char *label, const size_t label_len, - const unsigned char *context_value, const size_t context_len, - uint8_t *out, const size_t out_len); - -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - -#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ diff --git a/vendor/mbedtls/library/ssl_tls13_server.c b/vendor/mbedtls/library/ssl_tls13_server.c deleted file mode 100644 index a72ed25cf..000000000 --- a/vendor/mbedtls/library/ssl_tls13_server.c +++ /dev/null @@ -1,3622 +0,0 @@ -/* - * TLS 1.3 server-side functions - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) - -#include "debug_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/platform.h" -#include "mbedtls/constant_time.h" -#include "mbedtls/oid.h" -#include "mbedtls/psa_util.h" - -#include "ssl_misc.h" -#include "ssl_tls13_keys.h" -#include "ssl_debug_helpers.h" - - -static const mbedtls_ssl_ciphersuite_t *ssl_tls13_validate_peer_ciphersuite( - mbedtls_ssl_context *ssl, - unsigned int cipher_suite) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - if (!mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, cipher_suite)) { - return NULL; - } - - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(cipher_suite); - if ((mbedtls_ssl_validate_ciphersuite(ssl, ciphersuite_info, - ssl->tls_version, - ssl->tls_version) != 0)) { - return NULL; - } - return ciphersuite_info; -} - -static void ssl_tls13_select_ciphersuite( - mbedtls_ssl_context *ssl, - const unsigned char *cipher_suites, - const unsigned char *cipher_suites_end, - int psk_ciphersuite_id, - psa_algorithm_t psk_hash_alg, - const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info) -{ - *selected_ciphersuite_info = NULL; - - /* - * In a compliant ClientHello the byte-length of the list of ciphersuites - * is even and this function relies on this fact. This should have been - * checked in the main ClientHello parsing function. Double check here. - */ - if ((cipher_suites_end - cipher_suites) & 1) { - return; - } - - for (const unsigned char *p = cipher_suites; - p < cipher_suites_end; p += 2) { - /* - * "cipher_suites_end - p is even" is an invariant of the loop. As - * cipher_suites_end - p > 0, we have cipher_suites_end - p >= 2 and it - * is thus safe to read two bytes. - */ - uint16_t id = MBEDTLS_GET_UINT16_BE(p, 0); - - const mbedtls_ssl_ciphersuite_t *info = - ssl_tls13_validate_peer_ciphersuite(ssl, id); - if (info == NULL) { - continue; - } - - /* - * If a valid PSK ciphersuite identifier has been passed in, we want - * an exact match. - */ - if (psk_ciphersuite_id != 0) { - if (id != psk_ciphersuite_id) { - continue; - } - } else if (psk_hash_alg != PSA_ALG_NONE) { - if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac) != - psk_hash_alg) { - continue; - } - } - - *selected_ciphersuite_info = info; - return; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%lx", - (unsigned) psk_ciphersuite_id, - (unsigned long) psk_hash_alg)); -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -/* From RFC 8446: - * - * enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode; - * struct { - * PskKeyExchangeMode ke_modes<1..255>; - * } PskKeyExchangeModes; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - const unsigned char *p = buf; - size_t ke_modes_len; - int ke_modes = 0; - - /* Read ke_modes length (1 Byte) */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1); - ke_modes_len = *p++; - /* Currently, there are only two PSK modes, so even without looking - * at the content, something's wrong if the list has more than 2 items. */ - if (ke_modes_len > 2) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, ke_modes_len); - - while (ke_modes_len-- != 0) { - switch (*p++) { - case MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE: - ke_modes |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; - MBEDTLS_SSL_DEBUG_MSG(3, ("Found PSK KEX MODE")); - break; - case MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE: - ke_modes |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; - MBEDTLS_SSL_DEBUG_MSG(3, ("Found PSK_EPHEMERAL KEX MODE")); - break; - default: - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - } - - ssl->handshake->tls13_kex_modes = ke_modes; - return 0; -} - -/* - * Non-error return values of - * ssl_tls13_offered_psks_check_identity_match_ticket() and - * ssl_tls13_offered_psks_check_identity_match(). They are positive to - * not collide with error codes that are negative. Zero - * (SSL_TLS1_3_PSK_IDENTITY_MATCH) in case of success as it may be propagated - * up by the callers of this function as a generic success condition. - * - * The return value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE means - * that the pre-shared-key identity matches that of a ticket or an externally- - * provisioned pre-shared-key. We have thus been able to retrieve the - * attributes of the pre-shared-key but at least one of them does not meet - * some criteria and the pre-shared-key cannot be used. For example, a ticket - * is expired or its version is not TLS 1.3. Note eventually that the return - * value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE does not have - * anything to do with binder check. A binder check is done only when a - * suitable pre-shared-key has been selected and only for that selected - * pre-shared-key: if the binder check fails, we fail the handshake and we do - * not try to find another pre-shared-key for which the binder check would - * succeed as recommended by the specification. - */ -#define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH 2 -#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1 -#define SSL_TLS1_3_PSK_IDENTITY_MATCH 0 - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl); -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl); - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_offered_psks_check_identity_match_ticket( - mbedtls_ssl_context *ssl, - const unsigned char *identity, - size_t identity_len, - uint32_t obfuscated_ticket_age, - mbedtls_ssl_session *session) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *ticket_buffer; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_ms_time_t now; - mbedtls_ms_time_t server_age; - uint32_t client_age; - mbedtls_ms_time_t age_diff; -#endif - - ((void) obfuscated_ticket_age); - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> check_identity_match_ticket")); - - /* Ticket parser is not configured, Skip */ - if (ssl->conf->f_ticket_parse == NULL || identity_len == 0) { - return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; - } - - /* We create a copy of the encrypted ticket since the ticket parsing - * function is allowed to use its input buffer as an output buffer - * (in-place decryption). We do, however, need the original buffer for - * computing the PSK binder value. - */ - ticket_buffer = mbedtls_calloc(1, identity_len); - if (ticket_buffer == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(ticket_buffer, identity, identity_len); - - ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, - session, - ticket_buffer, identity_len); - switch (ret) { - case 0: - ret = SSL_TLS1_3_PSK_IDENTITY_MATCH; - break; - - case MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED: - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired")); - ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; - break; - - case MBEDTLS_ERR_SSL_INVALID_MAC: - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic")); - ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; - break; - - default: - MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret); - ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; - } - - /* We delete the temporary buffer */ - mbedtls_free(ticket_buffer); - - if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) { - goto exit; - } - - /* - * The identity matches that of a ticket. Now check that it has suitable - * attributes and bet it will not be the case. - */ - ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; - - if (session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3.")); - goto exit; - } - -#if defined(MBEDTLS_HAVE_TIME) - now = mbedtls_ms_time(); - - if (now < session->ticket_creation_time) { - MBEDTLS_SSL_DEBUG_MSG( - 3, ("Invalid ticket creation time ( now = %" MBEDTLS_PRINTF_MS_TIME - ", creation_time = %" MBEDTLS_PRINTF_MS_TIME " )", - now, session->ticket_creation_time)); - goto exit; - } - - server_age = now - session->ticket_creation_time; - - /* RFC 8446 section 4.6.1 - * - * Servers MUST NOT use any value greater than 604800 seconds (7 days). - * - * RFC 8446 section 4.2.11.1 - * - * Clients MUST NOT attempt to use tickets which have ages greater than - * the "ticket_lifetime" value which was provided with the ticket. - * - */ - if (server_age > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME * 1000) { - MBEDTLS_SSL_DEBUG_MSG( - 3, ("Ticket age exceeds limitation ticket_age = %" MBEDTLS_PRINTF_MS_TIME, - server_age)); - goto exit; - } - - /* RFC 8446 section 4.2.10 - * - * For PSKs provisioned via NewSessionTicket, a server MUST validate that - * the ticket age for the selected PSK identity (computed by subtracting - * ticket_age_add from PskIdentity.obfuscated_ticket_age modulo 2^32) is - * within a small tolerance of the time since the ticket was issued. - * - * NOTE: The typical accuracy of an RTC crystal is ±100 to ±20 parts per - * million (360 to 72 milliseconds per hour). Default tolerance - * window is 6s, thus in the worst case clients and servers must - * sync up their system time every 6000/360/2~=8 hours. - */ - client_age = obfuscated_ticket_age - session->ticket_age_add; - age_diff = server_age - (mbedtls_ms_time_t) client_age; - if (age_diff < -MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE || - age_diff > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) { - MBEDTLS_SSL_DEBUG_MSG( - 3, ("Ticket age outside tolerance window ( diff = %" - MBEDTLS_PRINTF_MS_TIME ")", - age_diff)); - goto exit; - } -#endif /* MBEDTLS_HAVE_TIME */ - - /* - * All good, we have found a suitable ticket. - */ - ret = SSL_TLS1_3_PSK_IDENTITY_MATCH; - -exit: - if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) { - mbedtls_ssl_session_free(session); - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= check_identity_match_ticket")); - return ret; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_offered_psks_check_identity_match( - mbedtls_ssl_context *ssl, - const unsigned char *identity, - size_t identity_len, - uint32_t obfuscated_ticket_age, - int *psk_type, - mbedtls_ssl_session *session) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ((void) session); - ((void) obfuscated_ticket_age); - *psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL; - - MBEDTLS_SSL_DEBUG_BUF(4, "identity", identity, identity_len); - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - ret = ssl_tls13_offered_psks_check_identity_match_ticket( - ssl, identity, identity_len, obfuscated_ticket_age, session); - if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH) { - *psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION; - ret = mbedtls_ssl_set_hs_psk(ssl, - session->resumption_key, - session->resumption_key_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF(4, "Ticket-resumed PSK:", - session->resumption_key, - session->resumption_key_len); - MBEDTLS_SSL_DEBUG_MSG(4, ("ticket: obfuscated_ticket_age: %u", - (unsigned) obfuscated_ticket_age)); - return SSL_TLS1_3_PSK_IDENTITY_MATCH; - } else if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE) { - return SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - /* Check identity with external configured function */ - if (ssl->conf->f_psk != NULL) { - if (ssl->conf->f_psk( - ssl->conf->p_psk, ssl, identity, identity_len) == 0) { - return SSL_TLS1_3_PSK_IDENTITY_MATCH; - } - return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; - } - - MBEDTLS_SSL_DEBUG_BUF(5, "identity", identity, identity_len); - /* Check identity with pre-configured psk */ - if (ssl->conf->psk_identity != NULL && - identity_len == ssl->conf->psk_identity_len && - mbedtls_ct_memcmp(ssl->conf->psk_identity, - identity, identity_len) == 0) { - ret = mbedtls_ssl_set_hs_psk(ssl, ssl->conf->psk, ssl->conf->psk_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret); - return ret; - } - return SSL_TLS1_3_PSK_IDENTITY_MATCH; - } - - return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; -} - -/* - * Non-error return values of ssl_tls13_offered_psks_check_binder_match(). - * They are positive to not collide with error codes that are negative. Zero - * (SSL_TLS1_3_BINDER_MATCH) in case of success as it may be propagated up - * by the callers of this function as a generic success condition. - */ -#define SSL_TLS1_3_BINDER_DOES_NOT_MATCH 1 -#define SSL_TLS1_3_BINDER_MATCH 0 -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_offered_psks_check_binder_match( - mbedtls_ssl_context *ssl, - const unsigned char *binder, size_t binder_len, - int psk_type, psa_algorithm_t psk_hash_alg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - unsigned char transcript[PSA_HASH_MAX_SIZE]; - size_t transcript_len; - unsigned char *psk; - size_t psk_len; - unsigned char server_computed_binder[PSA_HASH_MAX_SIZE]; - - if (binder_len != PSA_HASH_LENGTH(psk_hash_alg)) { - return SSL_TLS1_3_BINDER_DOES_NOT_MATCH; - } - - /* Get current state of handshake transcript. */ - ret = mbedtls_ssl_get_handshake_transcript( - ssl, mbedtls_md_type_from_psa_alg(psk_hash_alg), - transcript, sizeof(transcript), &transcript_len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_export_handshake_psk(ssl, &psk, &psk_len); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_create_psk_binder(ssl, psk_hash_alg, - psk, psk_len, psk_type, - transcript, - server_computed_binder); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - mbedtls_free((void *) psk); -#endif - if (ret != 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("PSK binder calculation failed.")); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "psk binder ( computed ): ", - server_computed_binder, transcript_len); - MBEDTLS_SSL_DEBUG_BUF(3, "psk binder ( received ): ", binder, binder_len); - - if (mbedtls_ct_memcmp(server_computed_binder, - binder, - PSA_HASH_LENGTH(psk_hash_alg)) == 0) { - return SSL_TLS1_3_BINDER_MATCH; - } - - mbedtls_platform_zeroize(server_computed_binder, - sizeof(server_computed_binder)); - return SSL_TLS1_3_BINDER_DOES_NOT_MATCH; -} - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst, - const mbedtls_ssl_session *src) -{ - dst->ticket_age_add = src->ticket_age_add; - dst->ticket_flags = src->ticket_flags; - dst->resumption_key_len = src->resumption_key_len; - if (src->resumption_key_len == 0) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - memcpy(dst->resumption_key, src->resumption_key, src->resumption_key_len); - -#if defined(MBEDTLS_SSL_EARLY_DATA) - dst->max_early_data_size = src->max_early_data_size; - -#if defined(MBEDTLS_SSL_ALPN) - int ret = mbedtls_ssl_session_set_ticket_alpn(dst, src->ticket_alpn); - if (ret != 0) { - return ret; - } -#endif /* MBEDTLS_SSL_ALPN */ -#endif /* MBEDTLS_SSL_EARLY_DATA*/ - - return 0; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -struct psk_attributes { - int type; - int key_exchange_mode; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; -}; -#define PSK_ATTRIBUTES_INIT { 0, 0, NULL } - -/* Parser for pre_shared_key extension in client hello - * struct { - * opaque identity<1..2^16-1>; - * uint32 obfuscated_ticket_age; - * } PskIdentity; - * - * opaque PskBinderEntry<32..255>; - * - * struct { - * PskIdentity identities<7..2^16-1>; - * PskBinderEntry binders<33..2^16-1>; - * } OfferedPsks; - * - * struct { - * select (Handshake.msg_type) { - * case client_hello: OfferedPsks; - * .... - * }; - * } PreSharedKeyExtension; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_pre_shared_key_ext( - mbedtls_ssl_context *ssl, - const unsigned char *pre_shared_key_ext, - const unsigned char *pre_shared_key_ext_end, - const unsigned char *ciphersuites, - const unsigned char *ciphersuites_end, - struct psk_attributes *psk) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *identities = pre_shared_key_ext; - const unsigned char *p_identity_len; - size_t identities_len; - const unsigned char *identities_end; - const unsigned char *binders; - const unsigned char *p_binder_len; - size_t binders_len; - const unsigned char *binders_end; - int matched_identity = -1; - int identity_id = -1; - - MBEDTLS_SSL_DEBUG_BUF(3, "pre_shared_key extension", - pre_shared_key_ext, - pre_shared_key_ext_end - pre_shared_key_ext); - - /* identities_len 2 bytes - * identities_data >= 7 bytes - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(identities, pre_shared_key_ext_end, 7 + 2); - identities_len = MBEDTLS_GET_UINT16_BE(identities, 0); - p_identity_len = identities + 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p_identity_len, pre_shared_key_ext_end, - identities_len); - identities_end = p_identity_len + identities_len; - - /* binders_len 2 bytes - * binders >= 33 bytes - */ - binders = identities_end; - MBEDTLS_SSL_CHK_BUF_READ_PTR(binders, pre_shared_key_ext_end, 33 + 2); - binders_len = MBEDTLS_GET_UINT16_BE(binders, 0); - p_binder_len = binders + 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p_binder_len, pre_shared_key_ext_end, binders_len); - binders_end = p_binder_len + binders_len; - - ret = ssl->handshake->update_checksum(ssl, pre_shared_key_ext, - identities_end - pre_shared_key_ext); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); - return ret; - } - - while (p_identity_len < identities_end && p_binder_len < binders_end) { - const unsigned char *identity; - size_t identity_len; - uint32_t obfuscated_ticket_age; - const unsigned char *binder; - size_t binder_len; - int psk_ciphersuite_id; - psa_algorithm_t psk_hash_alg; - int allowed_key_exchange_modes; - - mbedtls_ssl_session session; - mbedtls_ssl_session_init(&session); - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p_identity_len, identities_end, 2 + 1 + 4); - identity_len = MBEDTLS_GET_UINT16_BE(p_identity_len, 0); - identity = p_identity_len + 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(identity, identities_end, identity_len + 4); - obfuscated_ticket_age = MBEDTLS_GET_UINT32_BE(identity, identity_len); - p_identity_len += identity_len + 6; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p_binder_len, binders_end, 1 + 32); - binder_len = *p_binder_len; - binder = p_binder_len + 1; - MBEDTLS_SSL_CHK_BUF_READ_PTR(binder, binders_end, binder_len); - p_binder_len += binder_len + 1; - - identity_id++; - if (matched_identity != -1) { - continue; - } - - ret = ssl_tls13_offered_psks_check_identity_match( - ssl, identity, identity_len, obfuscated_ticket_age, - &psk->type, &session); - if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) { - continue; - } - - MBEDTLS_SSL_DEBUG_MSG(4, ("found matched identity")); - - switch (psk->type) { - case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL: - psk_ciphersuite_id = 0; - psk_hash_alg = PSA_ALG_SHA_256; - allowed_key_exchange_modes = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL; - break; -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION: - psk_ciphersuite_id = session.ciphersuite; - psk_hash_alg = PSA_ALG_NONE; - ssl->session_negotiate->ticket_flags = session.ticket_flags; - allowed_key_exchange_modes = - session.ticket_flags & - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL; - break; -#endif - default: - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE; - - if ((allowed_key_exchange_modes & - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) && - ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) { - psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; - } else if ((allowed_key_exchange_modes & - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) && - ssl_tls13_key_exchange_is_psk_available(ssl)) { - psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; - } - - if (psk->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE) { - MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable PSK key exchange mode")); - continue; - } - - ssl_tls13_select_ciphersuite(ssl, ciphersuites, ciphersuites_end, - psk_ciphersuite_id, psk_hash_alg, - &psk->ciphersuite_info); - - if (psk->ciphersuite_info == NULL) { -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - mbedtls_ssl_session_free(&session); -#endif - /* - * We consider finding a ciphersuite suitable for the PSK as part - * of the validation of its binder. Thus if we do not find one, we - * abort the handshake with a decrypt_error alert. - */ - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - ret = ssl_tls13_offered_psks_check_binder_match( - ssl, binder, binder_len, psk->type, - mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) psk->ciphersuite_info->mac)); - if (ret != SSL_TLS1_3_BINDER_MATCH) { - /* For security reasons, the handshake should be aborted when we - * fail to validate a binder value. See RFC 8446 section 4.2.11.2 - * and appendix E.6. */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - mbedtls_ssl_session_free(&session); -#endif - MBEDTLS_SSL_DEBUG_MSG(3, ("Invalid binder.")); - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_offered_psks_check_binder_match", ret); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return ret; - } - - matched_identity = identity_id; - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (psk->type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { - ret = ssl_tls13_session_copy_ticket(ssl->session_negotiate, - &session); - mbedtls_ssl_session_free(&session); - if (ret != 0) { - return ret; - } - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - } - - if (p_identity_len != identities_end || p_binder_len != binders_end) { - MBEDTLS_SSL_DEBUG_MSG(3, ("pre_shared_key extension decode error")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Update the handshake transcript with the binder list. */ - ret = ssl->handshake->update_checksum( - ssl, identities_end, (size_t) (binders_end - identities_end)); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); - return ret; - } - if (matched_identity == -1) { - MBEDTLS_SSL_DEBUG_MSG(3, ("No usable PSK or ticket.")); - return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - - ssl->handshake->selected_identity = (uint16_t) matched_identity; - MBEDTLS_SSL_DEBUG_MSG(3, ("Pre shared key found")); - - return 0; -} - -/* - * struct { - * select ( Handshake.msg_type ) { - * .... - * case server_hello: - * uint16 selected_identity; - * } - * } PreSharedKeyExtension; - */ -static int ssl_tls13_write_server_pre_shared_key_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *olen) -{ - unsigned char *p = (unsigned char *) buf; - - *olen = 0; - - int not_using_psk = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - not_using_psk = (mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)); -#else - not_using_psk = (ssl->handshake->psk == NULL); -#endif - if (not_using_psk) { - /* We shouldn't have called this extension writer unless we've - * chosen to use a PSK. */ - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding pre_shared_key extension")); - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_PRE_SHARED_KEY, p, 0); - MBEDTLS_PUT_UINT16_BE(2, p, 2); - - MBEDTLS_PUT_UINT16_BE(ssl->handshake->selected_identity, p, 4); - - *olen = 6; - - MBEDTLS_SSL_DEBUG_MSG(4, ("sent selected_identity: %u", - ssl->handshake->selected_identity)); - - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY); - - return 0; -} - -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - -/* From RFC 8446: - * struct { - * ProtocolVersion versions<2..254>; - * } SupportedVersions; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - const unsigned char *p = buf; - size_t versions_len; - const unsigned char *versions_end; - uint16_t tls_version; - int found_supported_version = 0; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1); - versions_len = p[0]; - p += 1; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, versions_len); - versions_end = p + versions_len; - while (p < versions_end) { - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, versions_end, 2); - tls_version = mbedtls_ssl_read_version(p, ssl->conf->transport); - p += 2; - - if (MBEDTLS_SSL_VERSION_TLS1_3 == tls_version) { - found_supported_version = 1; - break; - } - - if ((MBEDTLS_SSL_VERSION_TLS1_2 == tls_version) && - mbedtls_ssl_conf_is_tls12_enabled(ssl->conf)) { - found_supported_version = 1; - break; - } - } - - if (!found_supported_version) { - MBEDTLS_SSL_DEBUG_MSG(1, ("No supported version found.")); - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION, - MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION); - return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - } - - MBEDTLS_SSL_DEBUG_MSG(1, ("Negotiated version: [%04x]", - (unsigned int) tls_version)); - - return (int) tls_version; -} - -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) -/* - * - * From RFC 8446: - * enum { - * ... (0xFFFF) - * } NamedGroup; - * struct { - * NamedGroup named_group_list<2..2^16-1>; - * } NamedGroupList; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_supported_groups_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - const unsigned char *p = buf; - size_t named_group_list_len; - const unsigned char *named_group_list_end; - - MBEDTLS_SSL_DEBUG_BUF(3, "supported_groups extension", p, end - buf); - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - named_group_list_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, named_group_list_len); - named_group_list_end = p + named_group_list_len; - ssl->handshake->hrr_selected_group = 0; - - while (p < named_group_list_end) { - uint16_t named_group; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, named_group_list_end, 2); - named_group = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - MBEDTLS_SSL_DEBUG_MSG(2, - ("got named group: %s(%04x)", - mbedtls_ssl_named_group_to_str(named_group), - named_group)); - - if (!mbedtls_ssl_named_group_is_offered(ssl, named_group) || - !mbedtls_ssl_named_group_is_supported(named_group) || - ssl->handshake->hrr_selected_group != 0) { - continue; - } - - MBEDTLS_SSL_DEBUG_MSG(2, - ("add named group %s(%04x) into received list.", - mbedtls_ssl_named_group_to_str(named_group), - named_group)); - - ssl->handshake->hrr_selected_group = named_group; - } - - return 0; - -} -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ - -#define SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH 1 - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) -/* - * ssl_tls13_parse_key_shares_ext() verifies whether the information in the - * extension is correct and stores the first acceptable key share and its - * associated group. - * - * Possible return values are: - * - 0: Successful processing of the client provided key share extension. - * - SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH: The key shares provided by - * the client does not match a group supported by the server. A - * HelloRetryRequest will be needed. - * - A negative value for fatal errors. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_key_shares_ext(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char const *p = buf; - unsigned char const *client_shares_end; - size_t client_shares_len; - - /* From RFC 8446: - * - * struct { - * KeyShareEntry client_shares<0..2^16-1>; - * } KeyShareClientHello; - * - */ - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - client_shares_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, client_shares_len); - - ssl->handshake->offered_group_id = 0; - client_shares_end = p + client_shares_len; - - /* We try to find a suitable key share entry and copy it to the - * handshake context. Later, we have to find out whether we can do - * something with the provided key share or whether we have to - * dismiss it and send a HelloRetryRequest message. - */ - - while (p < client_shares_end) { - uint16_t group; - size_t key_exchange_len; - const unsigned char *key_exchange; - - /* - * struct { - * NamedGroup group; - * opaque key_exchange<1..2^16-1>; - * } KeyShareEntry; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, client_shares_end, 4); - group = MBEDTLS_GET_UINT16_BE(p, 0); - key_exchange_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - key_exchange = p; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, client_shares_end, key_exchange_len); - p += key_exchange_len; - - /* Continue parsing even if we have already found a match, - * for input validation purposes. - */ - if (!mbedtls_ssl_named_group_is_offered(ssl, group) || - !mbedtls_ssl_named_group_is_supported(group) || - ssl->handshake->offered_group_id != 0) { - continue; - } - - /* - * ECDHE and FFDHE groups are supported - */ - if (mbedtls_ssl_tls13_named_group_is_ecdhe(group) || - mbedtls_ssl_tls13_named_group_is_ffdh(group)) { - MBEDTLS_SSL_DEBUG_MSG(2, ("ECDH/FFDH group: %s (%04x)", - mbedtls_ssl_named_group_to_str(group), - group)); - ret = mbedtls_ssl_tls13_read_public_xxdhe_share( - ssl, key_exchange - 2, key_exchange_len + 2); - if (ret != 0) { - return ret; - } - - } else { - MBEDTLS_SSL_DEBUG_MSG(4, ("Unrecognized NamedGroup %u", - (unsigned) group)); - continue; - } - - ssl->handshake->offered_group_id = group; - } - - - if (ssl->handshake->offered_group_id == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no matching key share")); - return SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH; - } - return 0; -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_client_hello_has_exts(mbedtls_ssl_context *ssl, - int exts_mask) -{ - int masked = ssl->handshake->received_extensions & exts_mask; - return masked == exts_mask; -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange( - mbedtls_ssl_context *ssl) -{ - return ssl_tls13_client_hello_has_exts( - ssl, - MBEDTLS_SSL_EXT_MASK(SUPPORTED_GROUPS) | - MBEDTLS_SSL_EXT_MASK(KEY_SHARE) | - MBEDTLS_SSL_EXT_MASK(SIG_ALG)); -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_client_hello_has_exts_for_psk_key_exchange( - mbedtls_ssl_context *ssl) -{ - return ssl_tls13_client_hello_has_exts( - ssl, - MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | - MBEDTLS_SSL_EXT_MASK(PSK_KEY_EXCHANGE_MODES)); -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange( - mbedtls_ssl_context *ssl) -{ - return ssl_tls13_client_hello_has_exts( - ssl, - MBEDTLS_SSL_EXT_MASK(SUPPORTED_GROUPS) | - MBEDTLS_SSL_EXT_MASK(KEY_SHARE) | - MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) | - MBEDTLS_SSL_EXT_MASK(PSK_KEY_EXCHANGE_MODES)); -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) - return mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) && - mbedtls_ssl_tls13_is_psk_supported(ssl) && - ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl); -#else - ((void) ssl); - return 0; -#endif -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) - return mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) && - mbedtls_ssl_tls13_is_psk_ephemeral_supported(ssl) && - ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl); -#else - ((void) ssl); - return 0; -#endif -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_exchange_is_ephemeral_available(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - return mbedtls_ssl_conf_tls13_is_ephemeral_enabled(ssl) && - ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(ssl); -#else - ((void) ssl); - return 0; -#endif -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static psa_algorithm_t ssl_tls13_iana_sig_alg_to_psa_alg(uint16_t sig_alg) -{ - switch (sig_alg) { - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256: - return PSA_ALG_ECDSA(PSA_ALG_SHA_256); - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384: - return PSA_ALG_ECDSA(PSA_ALG_SHA_384); - case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512: - return PSA_ALG_ECDSA(PSA_ALG_SHA_512); - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: - return PSA_ALG_RSA_PSS(PSA_ALG_SHA_256); - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: - return PSA_ALG_RSA_PSS(PSA_ALG_SHA_384); - case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: - return PSA_ALG_RSA_PSS(PSA_ALG_SHA_512); - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256: - return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256); - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384: - return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_384); - case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512: - return PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512); - default: - return PSA_ALG_NONE; - } -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/* - * Pick best ( private key, certificate chain ) pair based on the signature - * algorithms supported by the client. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_pick_key_cert(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_key_cert *key_cert, *key_cert_list; - const uint16_t *sig_alg = ssl->handshake->received_sig_algs; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (ssl->handshake->sni_key_cert != NULL) { - key_cert_list = ssl->handshake->sni_key_cert; - } else -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - key_cert_list = ssl->conf->key_cert; - - if (key_cert_list == NULL) { - MBEDTLS_SSL_DEBUG_MSG(3, ("server has no certificate")); - return -1; - } - - for (; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++) { - if (!mbedtls_ssl_sig_alg_is_offered(ssl, *sig_alg)) { - continue; - } - - if (!mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported(*sig_alg)) { - continue; - } - - for (key_cert = key_cert_list; key_cert != NULL; - key_cert = key_cert->next) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_algorithm_t psa_alg = PSA_ALG_NONE; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - MBEDTLS_SSL_DEBUG_CRT(3, "certificate (chain) candidate", - key_cert->cert); - - /* - * This avoids sending the client a cert it'll reject based on - * keyUsage or other extensions. - */ - if (mbedtls_x509_crt_check_key_usage( - key_cert->cert, MBEDTLS_X509_KU_DIGITAL_SIGNATURE) != 0 || - mbedtls_x509_crt_check_extended_key_usage( - key_cert->cert, MBEDTLS_OID_SERVER_AUTH, - MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH)) != 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: " - "(extended) key usage extension")); - continue; - } - - MBEDTLS_SSL_DEBUG_MSG(3, - ("ssl_tls13_pick_key_cert:" - "check signature algorithm %s [%04x]", - mbedtls_ssl_sig_alg_to_str(*sig_alg), - *sig_alg)); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_alg = ssl_tls13_iana_sig_alg_to_psa_alg(*sig_alg); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (mbedtls_ssl_tls13_check_sig_alg_cert_key_match( - *sig_alg, &key_cert->cert->pk) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - && psa_alg != PSA_ALG_NONE && - mbedtls_pk_can_do_ext(&key_cert->cert->pk, psa_alg, - PSA_KEY_USAGE_SIGN_HASH) == 1 -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - ) { - ssl->handshake->key_cert = key_cert; - MBEDTLS_SSL_DEBUG_MSG(3, - ("ssl_tls13_pick_key_cert:" - "selected signature algorithm" - " %s [%04x]", - mbedtls_ssl_sig_alg_to_str(*sig_alg), - *sig_alg)); - MBEDTLS_SSL_DEBUG_CRT( - 3, "selected certificate (chain)", - ssl->handshake->key_cert->cert); - return 0; - } - } - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("ssl_tls13_pick_key_cert:" - "no suitable certificate found")); - return -1; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C && - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -/* - * - * STATE HANDLING: ClientHello - * - * There are three possible classes of outcomes when parsing the ClientHello: - * - * 1) The ClientHello was well-formed and matched the server's configuration. - * - * In this case, the server progresses to sending its ServerHello. - * - * 2) The ClientHello was well-formed but didn't match the server's - * configuration. - * - * For example, the client might not have offered a key share which - * the server supports, or the server might require a cookie. - * - * In this case, the server sends a HelloRetryRequest. - * - * 3) The ClientHello was ill-formed - * - * In this case, we abort the handshake. - * - */ - -/* - * Structure of this message: - * - * uint16 ProtocolVersion; - * opaque Random[32]; - * uint8 CipherSuite[2]; // Cryptographic suite selector - * - * struct { - * ProtocolVersion legacy_version = 0x0303; // TLS v1.2 - * Random random; - * opaque legacy_session_id<0..32>; - * CipherSuite cipher_suites<2..2^16-2>; - * opaque legacy_compression_methods<1..2^8-1>; - * Extension extensions<8..2^16-1>; - * } ClientHello; - */ - -#define SSL_CLIENT_HELLO_OK 0 -#define SSL_CLIENT_HELLO_HRR_REQUIRED 1 -#define SSL_CLIENT_HELLO_TLS1_2 2 - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned char *p = buf; - const unsigned char *random; - size_t legacy_session_id_len; - const unsigned char *legacy_session_id; - size_t cipher_suites_len; - const unsigned char *cipher_suites; - const unsigned char *cipher_suites_end; - size_t extensions_len; - const unsigned char *extensions_end; - const unsigned char *supported_versions_data; - const unsigned char *supported_versions_data_end; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - int hrr_required = 0; - int no_usable_share_for_key_agreement = 0; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - int got_psk = 0; - struct psk_attributes psk = PSK_ATTRIBUTES_INIT; - const unsigned char *pre_shared_key_ext = NULL; - const unsigned char *pre_shared_key_ext_end = NULL; -#endif - - /* - * ClientHello layout: - * 0 . 1 protocol version - * 2 . 33 random bytes - * 34 . 34 session id length ( 1 byte ) - * 35 . 34+x session id - * .. . .. ciphersuite list length ( 2 bytes ) - * .. . .. ciphersuite list - * .. . .. compression alg. list length ( 1 byte ) - * .. . .. compression alg. list - * .. . .. extensions length ( 2 bytes, optional ) - * .. . .. extensions ( optional ) - */ - - /* - * Minimal length ( with everything empty and extensions omitted ) is - * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can - * read at least up to session id length without worrying. - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 38); - - /* ... - * ProtocolVersion legacy_version = 0x0303; // TLS 1.2 - * ... - * with ProtocolVersion defined as: - * uint16 ProtocolVersion; - */ - if (mbedtls_ssl_read_version(p, ssl->conf->transport) != - MBEDTLS_SSL_VERSION_TLS1_2) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Unsupported version of TLS.")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION, - MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION); - return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - } - p += 2; - - /* ... - * Random random; - * ... - * with Random defined as: - * opaque Random[32]; - */ - random = p; - p += MBEDTLS_CLIENT_HELLO_RANDOM_LEN; - - /* ... - * opaque legacy_session_id<0..32>; - * ... - */ - legacy_session_id_len = *(p++); - legacy_session_id = p; - - /* - * Check we have enough data for the legacy session identifier - * and the ciphersuite list length. - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_len + 2); - p += legacy_session_id_len; - - /* ... - * CipherSuite cipher_suites<2..2^16-2>; - * ... - * with CipherSuite defined as: - * uint8 CipherSuite[2]; - */ - cipher_suites_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - cipher_suites = p; - - /* - * The length of the ciphersuite list has to be even. - */ - if (cipher_suites_len & 1) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - - /* Check we have enough data for the ciphersuite list, the legacy - * compression methods and the length of the extensions. - * - * cipher_suites cipher_suites_len bytes - * legacy_compression_methods length 1 byte - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 1); - p += cipher_suites_len; - cipher_suites_end = p; - - /* Check if we have enough data for legacy_compression_methods - * and the length of the extensions (2 bytes). - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p + 1, end, p[0] + 2); - - /* - * Search for the supported versions extension and parse it to determine - * if the client supports TLS 1.3. - */ - ret = mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( - ssl, p + 1 + p[0], end, - &supported_versions_data, &supported_versions_data_end); - if (ret < 0) { - MBEDTLS_SSL_DEBUG_RET(1, - ("mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts"), ret); - return ret; - } - - if (ret == 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("no supported_versions extension")); - return SSL_CLIENT_HELLO_TLS1_2; - } - - if (ret == 1) { - ret = ssl_tls13_parse_supported_versions_ext(ssl, - supported_versions_data, - supported_versions_data_end); - if (ret < 0) { - MBEDTLS_SSL_DEBUG_RET(1, - ("ssl_tls13_parse_supported_versions_ext"), ret); - return ret; - } - - /* - * The supported versions extension was parsed successfully as the - * value returned by ssl_tls13_parse_supported_versions_ext() is - * positive. The return value is then equal to - * MBEDTLS_SSL_VERSION_TLS1_2 or MBEDTLS_SSL_VERSION_TLS1_3, defining - * the TLS version to negotiate. - */ - if (MBEDTLS_SSL_VERSION_TLS1_2 == ret) { - MBEDTLS_SSL_DEBUG_MSG(2, ("supported_versions without 1.3")); - return SSL_CLIENT_HELLO_TLS1_2; - } - } - - /* - * We negotiate TLS 1.3. - */ - ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_3; - ssl->session_negotiate->tls_version = MBEDTLS_SSL_VERSION_TLS1_3; - ssl->session_negotiate->endpoint = ssl->conf->endpoint; - - /* Before doing any crypto, make sure we can. */ - ret = mbedtls_ssl_tls13_crypto_init(ssl); - if (ret != 0) { - return ret; - } - - /* - * We are negotiating the version 1.3 of the protocol. Do what we have - * postponed: copy of the client random bytes, copy of the legacy session - * identifier and selection of the TLS 1.3 cipher suite. - */ - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", - random, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); - memcpy(&handshake->randbytes[0], random, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); - - if (legacy_session_id_len > sizeof(ssl->session_negotiate->id)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - ssl->session_negotiate->id_len = legacy_session_id_len; - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id", - legacy_session_id, legacy_session_id_len); - memcpy(&ssl->session_negotiate->id[0], - legacy_session_id, legacy_session_id_len); - - /* - * Search for a matching ciphersuite - */ - MBEDTLS_SSL_DEBUG_BUF(3, "client hello, list of cipher suites", - cipher_suites, cipher_suites_len); - - ssl_tls13_select_ciphersuite(ssl, cipher_suites, cipher_suites_end, - 0, PSA_ALG_NONE, &handshake->ciphersuite_info); - - if (handshake->ciphersuite_info == NULL) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id; - - MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s", - ((unsigned) handshake->ciphersuite_info->id), - handshake->ciphersuite_info->name)); - - /* ... - * opaque legacy_compression_methods<1..2^8-1>; - * ... - */ - if (p[0] != 1 || p[1] != MBEDTLS_SSL_COMPRESS_NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad legacy compression method")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - p += 2; - - /* ... - * Extension extensions<8..2^16-1>; - * ... - * with Extension defined as: - * struct { - * ExtensionType extension_type; - * opaque extension_data<0..2^16-1>; - * } Extension; - */ - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); - extensions_end = p + extensions_len; - - MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", p, extensions_len); - handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - while (p < extensions_end) { - unsigned int extension_type; - size_t extension_data_len; - const unsigned char *extension_data_end; - uint32_t allowed_exts = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH; - - if (ssl->handshake->hello_retry_request_flag) { - /* Do not accept early data extension in 2nd ClientHello */ - allowed_exts &= ~MBEDTLS_SSL_EXT_MASK(EARLY_DATA); - } - - /* RFC 8446, section 4.2.11 - * - * The "pre_shared_key" extension MUST be the last extension in the - * ClientHello (this facilitates implementation as described below). - * Servers MUST check that it is the last extension and otherwise fail - * the handshake with an "illegal_parameter" alert. - */ - if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY)) { - MBEDTLS_SSL_DEBUG_MSG( - 3, ("pre_shared_key is not last extension.")); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); - extension_data_end = p + extension_data_len; - - ret = mbedtls_ssl_tls13_check_received_extension( - ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, extension_type, - allowed_exts); - if (ret != 0) { - return ret; - } - - switch (extension_type) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - case MBEDTLS_TLS_EXT_SERVERNAME: - MBEDTLS_SSL_DEBUG_MSG(3, ("found ServerName extension")); - ret = mbedtls_ssl_parse_server_name_ext(ssl, p, - extension_data_end); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_parse_servername_ext", ret); - return ret; - } - break; -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) - case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS: - MBEDTLS_SSL_DEBUG_MSG(3, ("found supported group extension")); - - /* Supported Groups Extension - * - * When sent by the client, the "supported_groups" extension - * indicates the named groups which the client supports, - * ordered from most preferred to least preferred. - */ - ret = ssl_tls13_parse_supported_groups_ext( - ssl, p, extension_data_end); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_parse_supported_groups_ext", ret); - return ret; - } - - break; -#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH*/ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - case MBEDTLS_TLS_EXT_KEY_SHARE: - MBEDTLS_SSL_DEBUG_MSG(3, ("found key share extension")); - - /* - * Key Share Extension - * - * When sent by the client, the "key_share" extension - * contains the endpoint's cryptographic parameters for - * ECDHE/DHE key establishment methods. - */ - ret = ssl_tls13_parse_key_shares_ext( - ssl, p, extension_data_end); - if (ret == SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH) { - MBEDTLS_SSL_DEBUG_MSG(2, ("No usable share for key agreement.")); - no_usable_share_for_key_agreement = 1; - } - - if (ret < 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_parse_key_shares_ext", ret); - return ret; - } - - break; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - - case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS: - /* Already parsed */ - break; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - case MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES: - MBEDTLS_SSL_DEBUG_MSG( - 3, ("found psk key exchange modes extension")); - - ret = ssl_tls13_parse_key_exchange_modes_ext( - ssl, p, extension_data_end); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_parse_key_exchange_modes_ext", ret); - return ret; - } - - break; -#endif - - case MBEDTLS_TLS_EXT_PRE_SHARED_KEY: - MBEDTLS_SSL_DEBUG_MSG(3, ("found pre_shared_key extension")); - if ((handshake->received_extensions & - MBEDTLS_SSL_EXT_MASK(PSK_KEY_EXCHANGE_MODES)) == 0) { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - /* Delay processing of the PSK identity once we have - * found out which algorithms to use. We keep a pointer - * to the buffer and the size for later processing. - */ - pre_shared_key_ext = p; - pre_shared_key_ext_end = extension_data_end; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - break; - -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension")); - - ret = mbedtls_ssl_parse_alpn_ext(ssl, p, extension_data_end); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, ("mbedtls_ssl_parse_alpn_ext"), ret); - return ret; - } - break; -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - case MBEDTLS_TLS_EXT_SIG_ALG: - MBEDTLS_SSL_DEBUG_MSG(3, ("found signature_algorithms extension")); - - ret = mbedtls_ssl_parse_sig_alg_ext( - ssl, p, extension_data_end); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_parse_sig_alg_ext", ret); - return ret; - } - break; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT: - MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension")); - - ret = mbedtls_ssl_tls13_parse_record_size_limit_ext( - ssl, p, extension_data_end); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, ("mbedtls_ssl_tls13_parse_record_size_limit_ext"), ret); - return ret; - } - break; -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - - default: - MBEDTLS_SSL_PRINT_EXT( - 3, MBEDTLS_SSL_HS_CLIENT_HELLO, - extension_type, "( ignored )"); - break; - } - - p += extension_data_len; - } - - MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_CLIENT_HELLO, - handshake->received_extensions); - - ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl, - MBEDTLS_SSL_HS_CLIENT_HELLO, - p - buf); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_add_hs_hdr_to_checksum"), ret); - return ret; - } - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - /* Update checksum with either - * - The entire content of the CH message, if no PSK extension is present - * - The content up to but excluding the PSK extension, if present. - * Always parse the pre-shared-key extension when present in the - * ClientHello even if some pre-requisites for PSK key exchange modes are - * not met. That way we always validate the syntax of the extension. - */ - if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY)) { - ret = handshake->update_checksum(ssl, buf, - pre_shared_key_ext - buf); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); - return ret; - } - ret = ssl_tls13_parse_pre_shared_key_ext(ssl, - pre_shared_key_ext, - pre_shared_key_ext_end, - cipher_suites, - cipher_suites_end, - &psk); - if (ret == 0) { - got_psk = 1; - } else if (ret != MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) { - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_parse_pre_shared_key_ext", ret); - return ret; - } - } else -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - { - ret = handshake->update_checksum(ssl, buf, p - buf); - if (0 != ret) { - MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); - return ret; - } - } - - /* - * Determine the key exchange algorithm to use. - * There are three types of key exchanges supported in TLS 1.3: - * - (EC)DH with ECDSA, - * - (EC)DH with PSK, - * - plain PSK. - * - * The PSK-based key exchanges may additionally be used with 0-RTT. - * - * Our built-in order of preference is - * 1 ) (EC)DHE-PSK Mode ( psk_ephemeral ) - * 2 ) Certificate Mode ( ephemeral ) - * 3 ) Plain PSK Mode ( psk ) - */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - if (got_psk && (psk.key_exchange_mode == - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL)) { - handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; - MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral")); - - } else -#endif - if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) { - handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL; - MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral")); - - } -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - else if (got_psk && (psk.key_exchange_mode == - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK)) { - handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; - MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk")); - } -#endif - else { - MBEDTLS_SSL_DEBUG_MSG( - 1, - ("ClientHello message misses mandatory extensions.")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - - if (handshake->key_exchange_mode != - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) { - hrr_required = (no_usable_share_for_key_agreement != 0); - } - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - if (handshake->key_exchange_mode & - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL) { - handshake->ciphersuite_info = psk.ciphersuite_info; - ssl->session_negotiate->ciphersuite = psk.ciphersuite_info->id; - - MBEDTLS_SSL_DEBUG_MSG(2, ("Select PSK ciphersuite: %04x - %s", - ((unsigned) psk.ciphersuite_info->id), - psk.ciphersuite_info->name)); - - if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION && (!hrr_required)) { - handshake->resume = 1; - } - } -#endif - - mbedtls_ssl_optimize_checksum(ssl, handshake->ciphersuite_info); - - return hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK; -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) -static int ssl_tls13_check_early_data_requirements(mbedtls_ssl_context *ssl) -{ - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) { - MBEDTLS_SSL_DEBUG_MSG( - 1, - ("EarlyData: rejected, feature disabled in server configuration.")); - return -1; - } - - if (!handshake->resume) { - /* We currently support early data only in the case of PSKs established - via a NewSessionTicket message thus in the case of a session - resumption. */ - MBEDTLS_SSL_DEBUG_MSG( - 1, ("EarlyData: rejected, not a session resumption.")); - return -1; - } - - /* RFC 8446 4.2.10 - * - * In order to accept early data, the server MUST have accepted a PSK cipher - * suite and selected the first key offered in the client's "pre_shared_key" - * extension. In addition, it MUST verify that the following values are the - * same as those associated with the selected PSK: - * - The TLS version number - * - The selected cipher suite - * - The selected ALPN [RFC7301] protocol, if any - * - * NOTE: - * - The TLS version number is checked in - * ssl_tls13_offered_psks_check_identity_match_ticket(). - */ - - if (handshake->selected_identity != 0) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("EarlyData: rejected, the selected key in " - "`pre_shared_key` is not the first one.")); - return -1; - } - - if (handshake->ciphersuite_info->id != - ssl->session_negotiate->ciphersuite) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("EarlyData: rejected, the selected ciphersuite is not the one " - "of the selected pre-shared key.")); - return -1; - - } - - if (!mbedtls_ssl_tls13_session_ticket_allow_early_data(ssl->session_negotiate)) { - MBEDTLS_SSL_DEBUG_MSG( - 1, - ("EarlyData: rejected, early_data not allowed in ticket " - "permission bits.")); - return -1; - } - -#if defined(MBEDTLS_SSL_ALPN) - const char *alpn = mbedtls_ssl_get_alpn_protocol(ssl); - size_t alpn_len; - - if (alpn == NULL && ssl->session_negotiate->ticket_alpn == NULL) { - return 0; - } - - if (alpn != NULL) { - alpn_len = strlen(alpn); - } - - if (alpn == NULL || - ssl->session_negotiate->ticket_alpn == NULL || - alpn_len != strlen(ssl->session_negotiate->ticket_alpn) || - (memcmp(alpn, ssl->session_negotiate->ticket_alpn, alpn_len) != 0)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, the selected ALPN is different " - "from the one associated with the pre-shared key.")); - return -1; - } -#endif - - return 0; -} -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -/* Update the handshake state machine */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl, - int hrr_required) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - /* - * Server certificate selection - */ - if (ssl->conf->f_cert_cb && (ret = ssl->conf->f_cert_cb(ssl)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "f_cert_cb", ret); - return ret; - } -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - ssl->handshake->sni_name = NULL; - ssl->handshake->sni_name_len = 0; -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - - ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "mbedtls_ssl_tls1_3_key_schedule_stage_early", ret); - return ret; - } - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) { - ssl->handshake->early_data_accepted = - (!hrr_required) && (ssl_tls13_check_early_data_requirements(ssl) == 0); - - if (ssl->handshake->early_data_accepted) { - ret = mbedtls_ssl_tls13_compute_early_transform(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_compute_early_transform", ret); - return ret; - } - } else { - ssl->discard_early_data_record = - hrr_required ? - MBEDTLS_SSL_EARLY_DATA_DISCARD : - MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD; - } - } -#else - ((void) hrr_required); -#endif /* MBEDTLS_SSL_EARLY_DATA */ - - return 0; -} - -/* - * Main entry point from the state machine; orchestrates the otherfunctions. - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl) -{ - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf = NULL; - size_t buflen = 0; - int parse_client_hello_ret; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, - &buf, &buflen)); - - MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_parse_client_hello(ssl, buf, - buf + buflen)); - parse_client_hello_ret = ret; /* Store positive return value of - * parse_client_hello, - * as negative error codes are handled - * by MBEDTLS_SSL_PROC_CHK_NEG. */ - - /* - * Version 1.2 of the protocol has to be used for the handshake. - * If we have sent an HRR, then the second ClientHello is inconsistent - * with the first one and we abort the handshake with an `illegal_parameter` - * fatal alert. - * If TLS 1.2 is not supported, abort the handshake. Otherwise, set the - * ssl->keep_current_message flag for the ClientHello to be kept and parsed - * as a TLS 1.2 ClientHello. We also change ssl->tls_version to - * MBEDTLS_SSL_VERSION_TLS1_2 thus from now on mbedtls_ssl_handshake_step() - * will dispatch to the TLS 1.2 state machine. - */ - if (SSL_CLIENT_HELLO_TLS1_2 == parse_client_hello_ret) { - if (ssl->handshake->hello_retry_request_flag) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Non compliant 2nd ClientHello, TLS 1.2 version")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - if (!mbedtls_ssl_conf_is_tls12_enabled(ssl->conf)) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("TLS 1.2 not supported.")); - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION, - MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION); - return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; - } - ssl->keep_current_message = 1; - ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2; - MBEDTLS_SSL_DEBUG_MSG(1, ("non-1.3 ClientHello left for later processing")); - return 0; - } - - MBEDTLS_SSL_PROC_CHK( - ssl_tls13_postprocess_client_hello(ssl, parse_client_hello_ret == - SSL_CLIENT_HELLO_HRR_REQUIRED)); - - if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO); - } else { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_RETRY_REQUEST); - } - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client hello")); - return ret; -} - -/* - * Handler for MBEDTLS_SSL_SERVER_HELLO - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_prepare_server_hello(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *server_randbytes = - ssl->handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN; - - if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, server_randbytes, - MBEDTLS_SERVER_HELLO_RANDOM_LEN)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "f_rng", ret); - return ret; - } - - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", server_randbytes, - MBEDTLS_SERVER_HELLO_RANDOM_LEN); - -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time(NULL); -#endif /* MBEDTLS_HAVE_TIME */ - - return ret; -} - -/* - * ssl_tls13_write_server_hello_supported_versions_ext (): - * - * struct { - * ProtocolVersion selected_version; - * } SupportedVersions; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_server_hello_supported_versions_ext( - mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - *out_len = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, write selected version")); - - /* Check if we have space to write the extension: - * - extension_type (2 bytes) - * - extension_data_length (2 bytes) - * - selected_version (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 6); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, buf, 0); - - MBEDTLS_PUT_UINT16_BE(2, buf, 2); - - mbedtls_ssl_write_version(buf + 4, - ssl->conf->transport, - ssl->tls_version); - - MBEDTLS_SSL_DEBUG_MSG(3, ("supported version: [%04x]", - ssl->tls_version)); - - *out_len = 6; - - mbedtls_ssl_tls13_set_hs_sent_ext_mask( - ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS); - - return 0; -} - - - -/* Generate and export a single key share. For hybrid KEMs, this can - * be called multiple times with the different components of the hybrid. */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_generate_and_write_key_share(mbedtls_ssl_context *ssl, - uint16_t named_group, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - *out_len = 0; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) - if (mbedtls_ssl_tls13_named_group_is_ecdhe(named_group) || - mbedtls_ssl_tls13_named_group_is_ffdh(named_group)) { - ret = mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange( - ssl, named_group, buf, end, out_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange", - ret); - return ret; - } - } else -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ - if (0 /* Other kinds of KEMs */) { - } else { - ((void) ssl); - ((void) named_group); - ((void) buf); - ((void) end); - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - return ret; -} - -/* - * ssl_tls13_write_key_share_ext - * - * Structure of key_share extension in ServerHello: - * - * struct { - * NamedGroup group; - * opaque key_exchange<1..2^16-1>; - * } KeyShareEntry; - * struct { - * KeyShareEntry server_share; - * } KeyShareServerHello; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - uint16_t group = ssl->handshake->offered_group_id; - unsigned char *server_share = buf + 4; - size_t key_exchange_length; - - *out_len = 0; - - MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding key share extension")); - - MBEDTLS_SSL_DEBUG_MSG(2, ("server hello, write selected_group: %s (%04x)", - mbedtls_ssl_named_group_to_str(group), - group)); - - /* Check if we have space for header and length fields: - * - extension_type (2 bytes) - * - extension_data_length (2 bytes) - * - group (2 bytes) - * - key_exchange_length (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 8); - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_KEY_SHARE, p, 0); - MBEDTLS_PUT_UINT16_BE(group, server_share, 0); - p += 8; - - /* When we introduce PQC-ECDHE hybrids, we'll want to call this - * function multiple times. */ - ret = ssl_tls13_generate_and_write_key_share( - ssl, group, server_share + 4, end, &key_exchange_length); - if (ret != 0) { - return ret; - } - p += key_exchange_length; - - MBEDTLS_PUT_UINT16_BE(key_exchange_length, server_share + 2, 0); - - MBEDTLS_PUT_UINT16_BE(p - server_share, buf, 2); - - *out_len = p - buf; - - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_KEY_SHARE); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_hrr_key_share_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - uint16_t selected_group = ssl->handshake->hrr_selected_group; - /* key_share Extension - * - * struct { - * select (Handshake.msg_type) { - * ... - * case hello_retry_request: - * NamedGroup selected_group; - * ... - * }; - * } KeyShare; - */ - - *out_len = 0; - - /* - * For a pure PSK key exchange, there is no group to agree upon. The purpose - * of the HRR is then to transmit a cookie to force the client to demonstrate - * reachability at their apparent network address (primarily useful for DTLS). - */ - if (!mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral(ssl)) { - return 0; - } - - /* We should only send the key_share extension if the client's initial - * key share was not acceptable. */ - if (ssl->handshake->offered_group_id != 0) { - MBEDTLS_SSL_DEBUG_MSG(4, ("Skip key_share extension in HRR")); - return 0; - } - - if (selected_group == 0) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no matching named group found")); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* Check if we have enough space: - * - extension_type (2 bytes) - * - extension_data_length (2 bytes) - * - selected_group (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 6); - - MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_KEY_SHARE, buf, 0); - MBEDTLS_PUT_UINT16_BE(2, buf, 2); - MBEDTLS_PUT_UINT16_BE(selected_group, buf, 4); - - MBEDTLS_SSL_DEBUG_MSG(3, - ("HRR selected_group: %s (%x)", - mbedtls_ssl_named_group_to_str(selected_group), - selected_group)); - - *out_len = 6; - - mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_KEY_SHARE); - - return 0; -} - -/* - * Structure of ServerHello message: - * - * struct { - * ProtocolVersion legacy_version = 0x0303; // TLS v1.2 - * Random random; - * opaque legacy_session_id_echo<0..32>; - * CipherSuite cipher_suite; - * uint8 legacy_compression_method = 0; - * Extension extensions<6..2^16-1>; - * } ServerHello; - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_server_hello_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len, - int is_hrr) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - unsigned char *p_extensions_len; - size_t output_len; - - *out_len = 0; - ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - /* ... - * ProtocolVersion legacy_version = 0x0303; // TLS 1.2 - * ... - * with ProtocolVersion defined as: - * uint16 ProtocolVersion; - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - MBEDTLS_PUT_UINT16_BE(0x0303, p, 0); - p += 2; - - /* ... - * Random random; - * ... - * with Random defined as: - * opaque Random[MBEDTLS_SERVER_HELLO_RANDOM_LEN]; - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN); - if (is_hrr) { - memcpy(p, mbedtls_ssl_tls13_hello_retry_request_magic, - MBEDTLS_SERVER_HELLO_RANDOM_LEN); - } else { - memcpy(p, &ssl->handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN], - MBEDTLS_SERVER_HELLO_RANDOM_LEN); - } - MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", - p, MBEDTLS_SERVER_HELLO_RANDOM_LEN); - p += MBEDTLS_SERVER_HELLO_RANDOM_LEN; - - /* ... - * opaque legacy_session_id_echo<0..32>; - * ... - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 1 + ssl->session_negotiate->id_len); - *p++ = (unsigned char) ssl->session_negotiate->id_len; - if (ssl->session_negotiate->id_len > 0) { - memcpy(p, &ssl->session_negotiate->id[0], - ssl->session_negotiate->id_len); - p += ssl->session_negotiate->id_len; - - MBEDTLS_SSL_DEBUG_BUF(3, "session id", ssl->session_negotiate->id, - ssl->session_negotiate->id_len); - } - - /* ... - * CipherSuite cipher_suite; - * ... - * with CipherSuite defined as: - * uint8 CipherSuite[2]; - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - MBEDTLS_PUT_UINT16_BE(ssl->session_negotiate->ciphersuite, p, 0); - p += 2; - MBEDTLS_SSL_DEBUG_MSG(3, - ("server hello, chosen ciphersuite: %s ( id=%d )", - mbedtls_ssl_get_ciphersuite_name( - ssl->session_negotiate->ciphersuite), - ssl->session_negotiate->ciphersuite)); - - /* ... - * uint8 legacy_compression_method = 0; - * ... - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 1); - *p++ = MBEDTLS_SSL_COMPRESS_NULL; - - /* ... - * Extension extensions<6..2^16-1>; - * ... - * struct { - * ExtensionType extension_type; (2 bytes) - * opaque extension_data<0..2^16-1>; - * } Extension; - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - p_extensions_len = p; - p += 2; - - if ((ret = ssl_tls13_write_server_hello_supported_versions_ext( - ssl, p, end, &output_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_write_server_hello_supported_versions_ext", ret); - return ret; - } - p += output_len; - - if (mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral(ssl)) { - if (is_hrr) { - ret = ssl_tls13_write_hrr_key_share_ext(ssl, p, end, &output_len); - } else { - ret = ssl_tls13_write_key_share_ext(ssl, p, end, &output_len); - } - if (ret != 0) { - return ret; - } - p += output_len; - } - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - if (!is_hrr && mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { - ret = ssl_tls13_write_server_pre_shared_key_ext(ssl, p, end, &output_len); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_write_server_pre_shared_key_ext", - ret); - return ret; - } - p += output_len; - } -#endif - - MBEDTLS_PUT_UINT16_BE(p - p_extensions_len - 2, p_extensions_len, 0); - - MBEDTLS_SSL_DEBUG_BUF(4, "server hello extensions", - p_extensions_len, p - p_extensions_len); - - *out_len = p - buf; - - MBEDTLS_SSL_DEBUG_BUF(3, "server hello", buf, *out_len); - - MBEDTLS_SSL_PRINT_EXTS( - 3, is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST : - MBEDTLS_SSL_HS_SERVER_HELLO, - ssl->handshake->sent_extensions); - - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_finalize_server_hello(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ret = mbedtls_ssl_tls13_compute_handshake_transform(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "mbedtls_ssl_tls13_compute_handshake_transform", - ret); - return ret; - } - - return ret; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - size_t buf_len, msg_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello")); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_prepare_server_hello(ssl)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_server_hello_body(ssl, buf, - buf + buf_len, - &msg_len, - 0)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( - ssl, buf_len, msg_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_finalize_server_hello(ssl)); - -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - /* The server sends a dummy change_cipher_spec record immediately - * after its first handshake message. This may either be after - * a ServerHello or a HelloRetryRequest. - */ - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO); -#else - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS); -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello")); - return ret; -} - - -/* - * Handler for MBEDTLS_SSL_HELLO_RETRY_REQUEST - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_prepare_hello_retry_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if (ssl->handshake->hello_retry_request_flag) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Too many HRRs")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - /* - * Create stateless transcript hash for HRR - */ - MBEDTLS_SSL_DEBUG_MSG(4, ("Reset transcript for HRR")); - ret = mbedtls_ssl_reset_transcript_for_hrr(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_reset_transcript_for_hrr", ret); - return ret; - } - mbedtls_ssl_session_reset_msg_layer(ssl, 0); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_hello_retry_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - size_t buf_len, msg_len; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello retry request")); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_prepare_hello_retry_request(ssl)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_server_hello_body(ssl, buf, - buf + buf_len, - &msg_len, - 1)); - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len)); - - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl, buf_len, - msg_len)); - - ssl->handshake->hello_retry_request_flag = 1; - -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - /* The server sends a dummy change_cipher_spec record immediately - * after its first handshake message. This may either be after - * a ServerHello or a HelloRetryRequest. - */ - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST); -#else - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - -cleanup: - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello retry request")); - return ret; -} - -/* - * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS - */ - -/* - * struct { - * Extension extensions<0..2 ^ 16 - 1>; - * } EncryptedExtensions; - * - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - size_t extensions_len = 0; - unsigned char *p_extensions_len; - size_t output_len; - - *out_len = 0; - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - p_extensions_len = p; - p += 2; - - ((void) ssl); - ((void) ret); - ((void) output_len); - -#if defined(MBEDTLS_SSL_ALPN) - ret = mbedtls_ssl_write_alpn_ext(ssl, p, end, &output_len); - if (ret != 0) { - return ret; - } - p += output_len; -#endif /* MBEDTLS_SSL_ALPN */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->handshake->early_data_accepted) { - ret = mbedtls_ssl_tls13_write_early_data_ext( - ssl, 0, p, end, &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - if (ssl->handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT)) { - ret = mbedtls_ssl_tls13_write_record_size_limit_ext( - ssl, p, end, &output_len); - if (ret != 0) { - return ret; - } - p += output_len; - } -#endif - - extensions_len = (p - p_extensions_len) - 2; - MBEDTLS_PUT_UINT16_BE(extensions_len, p_extensions_len, 0); - - *out_len = p - buf; - - MBEDTLS_SSL_DEBUG_BUF(4, "encrypted extensions", buf, *out_len); - - MBEDTLS_SSL_PRINT_EXTS( - 3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, ssl->handshake->sent_extensions); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *buf; - size_t buf_len, msg_len; - - mbedtls_ssl_set_outbound_transform(ssl, - ssl->handshake->transform_handshake); - MBEDTLS_SSL_DEBUG_MSG( - 3, ("switching to handshake transform for outbound data")); - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write encrypted extensions")); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_encrypted_extensions_body( - ssl, buf, buf + buf_len, &msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, - buf, msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( - ssl, buf_len, msg_len)); - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); - - /* Since we're not using a certificate, set verify_result to success */ - ssl->session_negotiate->verify_result = 0; - } else { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST); - } -#else - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); -#endif - -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write encrypted extensions")); - return ret; -} - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) -#define SSL_CERTIFICATE_REQUEST_SEND_REQUEST 0 -#define SSL_CERTIFICATE_REQUEST_SKIP 1 -/* Coordination: - * Check whether a CertificateRequest message should be written. - * Returns a negative code on failure, or - * - SSL_CERTIFICATE_REQUEST_SEND_REQUEST - * - SSL_CERTIFICATE_REQUEST_SKIP - * indicating if the writing of the CertificateRequest - * should be skipped or not. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_certificate_request_coordinate(mbedtls_ssl_context *ssl) -{ - int authmode; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) { - authmode = ssl->handshake->sni_authmode; - } else -#endif - authmode = ssl->conf->authmode; - - if (authmode == MBEDTLS_SSL_VERIFY_NONE) { - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY; - return SSL_CERTIFICATE_REQUEST_SKIP; - } - - ssl->handshake->certificate_request_sent = 1; - - return SSL_CERTIFICATE_REQUEST_SEND_REQUEST; -} - -/* - * struct { - * opaque certificate_request_context<0..2^8-1>; - * Extension extensions<2..2^16-1>; - * } CertificateRequest; - * - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_certificate_request_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - const unsigned char *end, - size_t *out_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - size_t output_len = 0; - unsigned char *p_extensions_len; - - *out_len = 0; - - /* Check if we have enough space: - * - certificate_request_context (1 byte) - * - extensions length (2 bytes) - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 3); - - /* - * Write certificate_request_context - */ - /* - * We use a zero length context for the normal handshake - * messages. For post-authentication handshake messages - * this request context would be set to a non-zero value. - */ - *p++ = 0x0; - - /* - * Write extensions - */ - /* The extensions must contain the signature_algorithms. */ - p_extensions_len = p; - p += 2; - ret = mbedtls_ssl_write_sig_alg_ext(ssl, p, end, &output_len); - if (ret != 0) { - return ret; - } - - p += output_len; - MBEDTLS_PUT_UINT16_BE(p - p_extensions_len - 2, p_extensions_len, 0); - - *out_len = p - buf; - - MBEDTLS_SSL_PRINT_EXTS( - 3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, ssl->handshake->sent_extensions); - - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_certificate_request(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request")); - - MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_certificate_request_coordinate(ssl)); - - if (ret == SSL_CERTIFICATE_REQUEST_SEND_REQUEST) { - unsigned char *buf; - size_t buf_len, msg_len; - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_request_body( - ssl, buf, buf + buf_len, &msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, - buf, msg_len)); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( - ssl, buf_len, msg_len)); - } else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) { - MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request")); - ret = 0; - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CERTIFICATE); -cleanup: - - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate request")); - return ret; -} - -/* - * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_server_certificate(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - if ((ssl_tls13_pick_key_cert(ssl) != 0) || - mbedtls_ssl_own_cert(ssl) == NULL) { - MBEDTLS_SSL_DEBUG_MSG(2, ("No certificate available.")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - ret = mbedtls_ssl_tls13_write_certificate(ssl); - if (ret != 0) { - return ret; - } - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY); - return 0; -} - -/* - * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl) -{ - int ret = mbedtls_ssl_tls13_write_certificate_verify(ssl); - if (ret != 0) { - return ret; - } - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED); - return 0; -} -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -/* - * RFC 8446 section A.2 - * - * | Send ServerHello - * | K_send = handshake - * | Send EncryptedExtensions - * | [Send CertificateRequest] - * Can send | [Send Certificate + CertificateVerify] - * app data | Send Finished - * after --> | K_send = application - * here +--------+--------+ - * No 0-RTT | | 0-RTT - * | | - * K_recv = handshake | | K_recv = early data - * [Skip decrypt errors] | +------> WAIT_EOED -+ - * | | Recv | | Recv EndOfEarlyData - * | | early data | | K_recv = handshake - * | +------------+ | - * | | - * +> WAIT_FLIGHT2 <--------+ - * | - * +--------+--------+ - * No auth | | Client auth - * | | - * | v - * | WAIT_CERT - * | Recv | | Recv Certificate - * | empty | v - * | Certificate | WAIT_CV - * | | | Recv - * | v | CertificateVerify - * +-> WAIT_FINISHED <---+ - * | Recv Finished - * - * - * The following function handles the state changes after WAIT_FLIGHT2 in the - * above diagram. We are not going to receive early data related messages - * anymore, prepare to receive the first handshake message of the client - * second flight. - */ -static void ssl_tls13_prepare_for_handshake_second_flight( - mbedtls_ssl_context *ssl) -{ - if (ssl->handshake->certificate_request_sent) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("skip parse certificate")); - MBEDTLS_SSL_DEBUG_MSG(2, ("skip parse certificate verify")); - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED); - } -} - -/* - * Handler for MBEDTLS_SSL_SERVER_FINISHED - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_ssl_tls13_write_finished_message(ssl); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_compute_application_transform(ssl); - if (ret != 0) { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, - MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - return ret; - } - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->handshake->early_data_accepted) { - /* See RFC 8446 section A.2 for more information */ - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Switch to early keys for inbound traffic. " - "( K_recv = early data )")); - mbedtls_ssl_set_inbound_transform( - ssl, ssl->handshake->transform_earlydata); - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA); - return 0; - } -#endif /* MBEDTLS_SSL_EARLY_DATA */ - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Switch to handshake keys for inbound traffic " - "( K_recv = handshake )")); - mbedtls_ssl_set_inbound_transform(ssl, ssl->handshake->transform_handshake); - - ssl_tls13_prepare_for_handshake_second_flight(ssl); - - return 0; -} - -#if defined(MBEDTLS_SSL_EARLY_DATA) -/* - * Handler for MBEDTLS_SSL_END_OF_EARLY_DATA - */ -#define SSL_GOT_END_OF_EARLY_DATA 0 -#define SSL_GOT_EARLY_DATA 1 -/* Coordination: - * Deals with the ambiguity of not knowing if the next message is an - * EndOfEarlyData message or an application message containing early data. - * Returns a negative code on failure, or - * - SSL_GOT_END_OF_EARLY_DATA - * - SSL_GOT_EARLY_DATA - * indicating which message is received. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - ssl->keep_current_message = 1; - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_END_OF_EARLY_DATA) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Received an end_of_early_data message.")); - return SSL_GOT_END_OF_EARLY_DATA; - } - - if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) { - if (ssl->in_offt == NULL) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data")); - /* Set the reading pointer */ - ssl->in_offt = ssl->in_msg; - ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen); - if (ret != 0) { - return ret; - } - } - return SSL_GOT_EARLY_DATA; - } - - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE, - MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); - return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl, - const unsigned char *buf, - const unsigned char *end) -{ - /* RFC 8446 section 4.5 - * - * struct {} EndOfEarlyData; - */ - if (buf != end) { - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR); - return MBEDTLS_ERR_SSL_DECODE_ERROR; - } - return 0; -} - -/* - * RFC 8446 section A.2 - * - * | Send ServerHello - * | K_send = handshake - * | Send EncryptedExtensions - * | [Send CertificateRequest] - * Can send | [Send Certificate + CertificateVerify] - * app data | Send Finished - * after --> | K_send = application - * here +--------+--------+ - * No 0-RTT | | 0-RTT - * | | - * K_recv = handshake | | K_recv = early data - * [Skip decrypt errors] | +------> WAIT_EOED -+ - * | | Recv | | Recv EndOfEarlyData - * | | early data | | K_recv = handshake - * | +------------+ | - * | | - * +> WAIT_FLIGHT2 <--------+ - * | - * +--------+--------+ - * No auth | | Client auth - * | | - * | v - * | WAIT_CERT - * | Recv | | Recv Certificate - * | empty | v - * | Certificate | WAIT_CV - * | | | Recv - * | v | CertificateVerify - * +-> WAIT_FINISHED <---+ - * | Recv Finished - * - * The function handles actions and state changes from 0-RTT to WAIT_FLIGHT2 in - * the above diagram. - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_process_end_of_early_data")); - - MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_end_of_early_data_coordinate(ssl)); - - if (ret == SSL_GOT_END_OF_EARLY_DATA) { - unsigned char *buf; - size_t buf_len; - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg( - ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data( - ssl, buf, buf + buf_len)); - - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Switch to handshake keys for inbound traffic" - "( K_recv = handshake )")); - mbedtls_ssl_set_inbound_transform( - ssl, ssl->handshake->transform_handshake); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, - buf, buf_len)); - - ssl_tls13_prepare_for_handshake_second_flight(ssl); - - } else if (ret == SSL_GOT_EARLY_DATA) { - ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA; - goto cleanup; - } else { - MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - -cleanup: - MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_process_end_of_early_data")); - return ret; -} -#endif /* MBEDTLS_SSL_EARLY_DATA */ - -/* - * Handler for MBEDTLS_SSL_CLIENT_FINISHED - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_client_finished(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_ssl_tls13_process_finished_message(ssl); - if (ret != 0) { - return ret; - } - - ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_compute_resumption_master_secret", ret); - } - - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); - return 0; -} - -/* - * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl) -{ - MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); - - mbedtls_ssl_tls13_handshake_wrapup(ssl); - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -/* TODO: Remove the check of SOME_PSK_ENABLED since SESSION_TICKETS requires - * SOME_PSK_ENABLED to be enabled. Here is just to make CI happy. It is - * expected to be resolved with issue#6395. - */ - /* Sent NewSessionTicket message only when client supports PSK */ - if (mbedtls_ssl_tls13_is_some_psk_supported(ssl)) { - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET); - } else -#endif - { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); - } - return 0; -} - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -/* - * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET - */ -#define SSL_NEW_SESSION_TICKET_SKIP 0 -#define SSL_NEW_SESSION_TICKET_WRITE 1 -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_new_session_ticket_coordinate(mbedtls_ssl_context *ssl) -{ - /* Check whether the use of session tickets is enabled */ - if (ssl->conf->f_ticket_write == NULL) { - MBEDTLS_SSL_DEBUG_MSG(2, ("NewSessionTicket: disabled," - " callback is not set")); - return SSL_NEW_SESSION_TICKET_SKIP; - } - if (ssl->conf->new_session_tickets_count == 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("NewSessionTicket: disabled," - " configured count is zero")); - return SSL_NEW_SESSION_TICKET_SKIP; - } - - if (ssl->handshake->new_session_tickets_count == 0) { - MBEDTLS_SSL_DEBUG_MSG(2, ("NewSessionTicket: all tickets have " - "been sent.")); - return SSL_NEW_SESSION_TICKET_SKIP; - } - - return SSL_NEW_SESSION_TICKET_WRITE; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl, - unsigned char *ticket_nonce, - size_t ticket_nonce_size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_session *session = ssl->session; - mbedtls_ssl_ciphersuite_t *ciphersuite_info; - psa_algorithm_t psa_hash_alg; - int hash_length; - - MBEDTLS_SSL_DEBUG_MSG(2, ("=> prepare NewSessionTicket msg")); - - /* Set ticket_flags depends on the advertised psk key exchange mode */ - mbedtls_ssl_tls13_session_clear_ticket_flags( - session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK); -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - mbedtls_ssl_tls13_session_set_ticket_flags( - session, ssl->handshake->tls13_kex_modes); -#endif - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED && - ssl->conf->max_early_data_size > 0) { - mbedtls_ssl_tls13_session_set_ticket_flags( - session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA); - session->max_early_data_size = ssl->conf->max_early_data_size; - } -#endif /* MBEDTLS_SSL_EARLY_DATA */ - - MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); - -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - if (session->ticket_alpn == NULL) { - ret = mbedtls_ssl_session_set_ticket_alpn(session, ssl->alpn_chosen); - if (ret != 0) { - return ret; - } - } -#endif - - /* Generate ticket_age_add */ - if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, - (unsigned char *) &session->ticket_age_add, - sizeof(session->ticket_age_add)) != 0)) { - MBEDTLS_SSL_DEBUG_RET(1, "generate_ticket_age_add", ret); - return ret; - } - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_age_add: %u", - (unsigned int) session->ticket_age_add)); - - /* Generate ticket_nonce */ - ret = ssl->conf->f_rng(ssl->conf->p_rng, ticket_nonce, ticket_nonce_size); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "generate_ticket_nonce", ret); - return ret; - } - MBEDTLS_SSL_DEBUG_BUF(3, "ticket_nonce:", - ticket_nonce, ticket_nonce_size); - - ciphersuite_info = - (mbedtls_ssl_ciphersuite_t *) ssl->handshake->ciphersuite_info; - psa_hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); - hash_length = PSA_HASH_LENGTH(psa_hash_alg); - if (hash_length == -1 || - (size_t) hash_length > sizeof(session->resumption_key)) { - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; - } - - /* In this code the psk key length equals the length of the hash */ - session->resumption_key_len = hash_length; - session->ciphersuite = ciphersuite_info->id; - - /* Compute resumption key - * - * HKDF-Expand-Label( resumption_master_secret, - * "resumption", ticket_nonce, Hash.length ) - */ - ret = mbedtls_ssl_tls13_hkdf_expand_label( - psa_hash_alg, - session->app_secrets.resumption_master_secret, - hash_length, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(resumption), - ticket_nonce, - ticket_nonce_size, - session->resumption_key, - hash_length); - - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(2, - "Creating the ticket-resumed PSK failed", - ret); - return ret; - } - MBEDTLS_SSL_DEBUG_BUF(3, "Ticket-resumed PSK", - session->resumption_key, - session->resumption_key_len); - - MBEDTLS_SSL_DEBUG_BUF(3, "resumption_master_secret", - session->app_secrets.resumption_master_secret, - hash_length); - - return 0; -} - -/* This function creates a NewSessionTicket message in the following format: - * - * struct { - * uint32 ticket_lifetime; - * uint32 ticket_age_add; - * opaque ticket_nonce<0..255>; - * opaque ticket<1..2^16-1>; - * Extension extensions<0..2^16-2>; - * } NewSessionTicket; - * - * The ticket inside the NewSessionTicket message is an encrypted container - * carrying the necessary information so that the server is later able to - * re-start the communication. - * - * The following fields are placed inside the ticket by the - * f_ticket_write() function: - * - * - creation time (ticket_creation_time) - * - flags (ticket_flags) - * - age add (ticket_age_add) - * - key (resumption_key) - * - key length (resumption_key_len) - * - ciphersuite (ciphersuite) - * - max_early_data_size (max_early_data_size) - */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl, - unsigned char *buf, - unsigned char *end, - size_t *out_len, - unsigned char *ticket_nonce, - size_t ticket_nonce_size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p = buf; - mbedtls_ssl_session *session = ssl->session; - size_t ticket_len; - uint32_t ticket_lifetime; - unsigned char *p_extensions_len; - - *out_len = 0; - MBEDTLS_SSL_DEBUG_MSG(2, ("=> write NewSessionTicket msg")); - - /* - * ticket_lifetime 4 bytes - * ticket_age_add 4 bytes - * ticket_nonce 1 + ticket_nonce_size bytes - * ticket >=2 bytes - */ - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4 + 4 + 1 + ticket_nonce_size + 2); - - /* Generate ticket and ticket_lifetime */ -#if defined(MBEDTLS_HAVE_TIME) - session->ticket_creation_time = mbedtls_ms_time(); -#endif - ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket, - session, - p + 9 + ticket_nonce_size + 2, - end, - &ticket_len, - &ticket_lifetime); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "write_ticket", ret); - return ret; - } - - /* RFC 8446 section 4.6.1 - * - * ticket_lifetime: Indicates the lifetime in seconds as a 32-bit - * unsigned integer in network byte order from the time of ticket - * issuance. Servers MUST NOT use any value greater than - * 604800 seconds (7 days) ... - */ - if (ticket_lifetime > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) { - MBEDTLS_SSL_DEBUG_MSG( - 1, ("Ticket lifetime (%u) is greater than 7 days.", - (unsigned int) ticket_lifetime)); - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0); - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u", - (unsigned int) ticket_lifetime)); - - /* Write ticket_age_add */ - MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 4); - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_age_add: %u", - (unsigned int) session->ticket_age_add)); - - /* Write ticket_nonce */ - p[8] = (unsigned char) ticket_nonce_size; - if (ticket_nonce_size > 0) { - memcpy(p + 9, ticket_nonce, ticket_nonce_size); - } - p += 9 + ticket_nonce_size; - - /* Write ticket */ - MBEDTLS_PUT_UINT16_BE(ticket_len, p, 0); - p += 2; - MBEDTLS_SSL_DEBUG_BUF(4, "ticket", p, ticket_len); - p += ticket_len; - - /* Ticket Extensions - * - * Extension extensions<0..2^16-2>; - */ - ssl->handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE; - - MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2); - p_extensions_len = p; - p += 2; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (mbedtls_ssl_tls13_session_ticket_allow_early_data(session)) { - size_t output_len; - - if ((ret = mbedtls_ssl_tls13_write_early_data_ext( - ssl, 1, p, end, &output_len)) != 0) { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_write_early_data_ext", ret); - return ret; - } - p += output_len; - } else { - MBEDTLS_SSL_DEBUG_MSG( - 4, ("early_data not allowed, " - "skip early_data extension in NewSessionTicket")); - } - -#endif /* MBEDTLS_SSL_EARLY_DATA */ - - MBEDTLS_PUT_UINT16_BE(p - p_extensions_len - 2, p_extensions_len, 0); - - *out_len = p - buf; - MBEDTLS_SSL_DEBUG_BUF(4, "ticket", buf, *out_len); - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket")); - - MBEDTLS_SSL_PRINT_EXTS( - 3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, ssl->handshake->sent_extensions); - - return 0; -} - -/* - * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET - */ -static int ssl_tls13_write_new_session_ticket(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_write_new_session_ticket_coordinate(ssl)); - - if (ret == SSL_NEW_SESSION_TICKET_WRITE) { - unsigned char ticket_nonce[MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH]; - unsigned char *buf; - size_t buf_len, msg_len; - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_prepare_new_session_ticket( - ssl, ticket_nonce, sizeof(ticket_nonce))); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg( - ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, - &buf, &buf_len)); - - MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_new_session_ticket_body( - ssl, buf, buf + buf_len, &msg_len, - ticket_nonce, sizeof(ticket_nonce))); - - MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( - ssl, buf_len, msg_len)); - - /* Limit session tickets count to one when resumption connection. - * - * See document of mbedtls_ssl_conf_new_session_tickets. - */ - if (ssl->handshake->resume == 1) { - ssl->handshake->new_session_tickets_count = 0; - } else { - ssl->handshake->new_session_tickets_count--; - } - - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH); - } else { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); - } - -cleanup: - - return ret; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -/* - * TLS 1.3 State Machine -- server side - */ -int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - MBEDTLS_SSL_DEBUG_MSG(2, ("tls13 server state: %s(%d)", - mbedtls_ssl_states_str((mbedtls_ssl_states) ssl->state), - ssl->state)); - - switch (ssl->state) { - /* start state */ - case MBEDTLS_SSL_HELLO_REQUEST: - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - ret = 0; - break; - - case MBEDTLS_SSL_CLIENT_HELLO: - ret = ssl_tls13_process_client_hello(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_process_client_hello", ret); - } - break; - - case MBEDTLS_SSL_HELLO_RETRY_REQUEST: - ret = ssl_tls13_write_hello_retry_request(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_write_hello_retry_request", ret); - return ret; - } - break; - - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_tls13_write_server_hello(ssl); - break; - - case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS: - ret = ssl_tls13_write_encrypted_extensions(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_write_encrypted_extensions", ret); - return ret; - } - break; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_tls13_write_certificate_request(ssl); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = ssl_tls13_write_server_certificate(ssl); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_tls13_write_certificate_verify(ssl); - break; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - - /* - * Injection of dummy-CCS's for middlebox compatibility - */ -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - case MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST: - ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl); - if (ret == 0) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); - } - break; - - case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO: - ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl); - if (ret != 0) { - break; - } - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS); - break; -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = ssl_tls13_write_server_finished(ssl); - break; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - case MBEDTLS_SSL_END_OF_EARLY_DATA: - ret = ssl_tls13_process_end_of_early_data(ssl); - break; -#endif /* MBEDTLS_SSL_EARLY_DATA */ - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = ssl_tls13_process_client_finished(ssl); - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - ret = ssl_tls13_handshake_wrapup(ssl); - break; - -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = mbedtls_ssl_tls13_process_certificate(ssl); - if (ret == 0) { - if (ssl->session_negotiate->peer_cert != NULL) { - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY); - } else { - MBEDTLS_SSL_DEBUG_MSG(2, ("skip parse certificate verify")); - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_CLIENT_FINISHED); - } - } - break; - - case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY: - ret = mbedtls_ssl_tls13_process_certificate_verify(ssl); - if (ret == 0) { - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_CLIENT_FINISHED); - } - break; -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET: - ret = ssl_tls13_write_new_session_ticket(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, - "ssl_tls13_write_new_session_ticket ", - ret); - } - break; - case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH: - /* This state is necessary to do the flush of the New Session - * Ticket message written in MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET - * as part of ssl_prepare_handshake_step. - */ - ret = 0; - - if (ssl->handshake->new_session_tickets_count == 0) { - mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); - } else { - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET); - } - break; - -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - default: - MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state)); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - } - - return ret; -} - -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/vendor/mbedtls/library/threading.c b/vendor/mbedtls/library/threading.c deleted file mode 100644 index 8764b3edc..000000000 --- a/vendor/mbedtls/library/threading.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Threading abstraction layer - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -/* - * Ensure gmtime_r is available even with -std=c99; must be defined before - * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms. - */ -#if !defined(_POSIX_C_SOURCE) -#define _POSIX_C_SOURCE 200112L -#endif - -#include "common.h" - -#if defined(MBEDTLS_THREADING_C) - -#include "threading_internal.h" - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) - -#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) -#include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ - -#if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \ - (defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L)) -/* - * This is a convenience shorthand macro to avoid checking the long - * preprocessor conditions above. Ideally, we could expose this macro in - * platform_util.h and simply use it in platform_util.c, threading.c and - * threading.h. However, this macro is not part of the Mbed TLS public API, so - * we keep it private by only defining it in this file - */ - -#if !(defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)) -#define THREADING_USE_GMTIME -#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ - -#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ - ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */ - -#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ - -#if defined(MBEDTLS_THREADING_PTHREAD) -static void threading_mutex_init_pthread(mbedtls_threading_mutex_t *mutex) -{ - if (mutex == NULL) { - return; - } - - /* One problem here is that calling lock on a pthread mutex without first - * having initialised it is undefined behaviour. Obviously we cannot check - * this here in a thread safe manner without a significant performance - * hit, so state transitions are checked in tests only via the state - * variable. Please make sure any new mutex that gets added is exercised in - * tests; see framework/tests/src/threading_helpers.c for more details. */ - (void) pthread_mutex_init(&mutex->mutex, NULL); -} - -static void threading_mutex_free_pthread(mbedtls_threading_mutex_t *mutex) -{ - if (mutex == NULL) { - return; - } - - (void) pthread_mutex_destroy(&mutex->mutex); -} - -static int threading_mutex_lock_pthread(mbedtls_threading_mutex_t *mutex) -{ - if (mutex == NULL) { - return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; - } - - if (pthread_mutex_lock(&mutex->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } - - return 0; -} - -static int threading_mutex_unlock_pthread(mbedtls_threading_mutex_t *mutex) -{ - if (mutex == NULL) { - return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; - } - - if (pthread_mutex_unlock(&mutex->mutex) != 0) { - return MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } - - return 0; -} - -void (*mbedtls_mutex_init)(mbedtls_threading_mutex_t *) = threading_mutex_init_pthread; -void (*mbedtls_mutex_free)(mbedtls_threading_mutex_t *) = threading_mutex_free_pthread; -int (*mbedtls_mutex_lock)(mbedtls_threading_mutex_t *) = threading_mutex_lock_pthread; -int (*mbedtls_mutex_unlock)(mbedtls_threading_mutex_t *) = threading_mutex_unlock_pthread; - -/* - * With pthreads we can statically initialize mutexes - */ -#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } - -#endif /* MBEDTLS_THREADING_PTHREAD */ - -#if defined(MBEDTLS_THREADING_ALT) -static int threading_mutex_fail(mbedtls_threading_mutex_t *mutex) -{ - ((void) mutex); - return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; -} -static void threading_mutex_dummy(mbedtls_threading_mutex_t *mutex) -{ - ((void) mutex); - return; -} - -void (*mbedtls_mutex_init)(mbedtls_threading_mutex_t *) = threading_mutex_dummy; -void (*mbedtls_mutex_free)(mbedtls_threading_mutex_t *) = threading_mutex_dummy; -int (*mbedtls_mutex_lock)(mbedtls_threading_mutex_t *) = threading_mutex_fail; -int (*mbedtls_mutex_unlock)(mbedtls_threading_mutex_t *) = threading_mutex_fail; - -/* - * Set functions pointers and initialize global mutexes - */ -void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), - void (*mutex_free)(mbedtls_threading_mutex_t *), - int (*mutex_lock)(mbedtls_threading_mutex_t *), - int (*mutex_unlock)(mbedtls_threading_mutex_t *)) -{ - mbedtls_mutex_init = mutex_init; - mbedtls_mutex_free = mutex_free; - mbedtls_mutex_lock = mutex_lock; - mbedtls_mutex_unlock = mutex_unlock; - -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_init(&mbedtls_threading_readdir_mutex); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_init(&mbedtls_threading_gmtime_mutex); -#endif -#if defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_mutex_init(&mbedtls_threading_key_slot_mutex); - mbedtls_mutex_init(&mbedtls_threading_psa_globaldata_mutex); - mbedtls_mutex_init(&mbedtls_threading_psa_rngdata_mutex); -#endif -} - -/* - * Free global mutexes - */ -void mbedtls_threading_free_alt(void) -{ -#if defined(MBEDTLS_FS_IO) - mbedtls_mutex_free(&mbedtls_threading_readdir_mutex); -#endif -#if defined(THREADING_USE_GMTIME) - mbedtls_mutex_free(&mbedtls_threading_gmtime_mutex); -#endif -#if defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_mutex_free(&mbedtls_threading_key_slot_mutex); - mbedtls_mutex_free(&mbedtls_threading_psa_globaldata_mutex); - mbedtls_mutex_free(&mbedtls_threading_psa_rngdata_mutex); -#endif -} -#endif /* MBEDTLS_THREADING_ALT */ - -/* - * Define global mutexes - */ -#ifndef MUTEX_INIT -#define MUTEX_INIT -#endif -#if defined(MBEDTLS_FS_IO) -mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; -#endif -#if defined(THREADING_USE_GMTIME) -mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; -#endif -#if defined(MBEDTLS_PSA_CRYPTO_C) -mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex MUTEX_INIT; -mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex MUTEX_INIT; -mbedtls_threading_mutex_t mbedtls_threading_psa_rngdata_mutex MUTEX_INIT; -#endif - -#endif /* MBEDTLS_THREADING_C */ diff --git a/vendor/mbedtls/library/threading_internal.h b/vendor/mbedtls/library/threading_internal.h deleted file mode 100644 index 21b57c97c..000000000 --- a/vendor/mbedtls/library/threading_internal.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * \file threading_internal.h - * - * \brief Threading interfaces used by the test framework - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef MBEDTLS_THREADING_INTERNAL_H -#define MBEDTLS_THREADING_INTERNAL_H - -#include "common.h" - -#include - -/* A version number for the internal threading interface. - * This is meant to allow the framework to remain compatible with - * multiple versions, to facilitate transitions. - * - * Conventionally, this is the Mbed TLS version number when the - * threading interface was last changed in a way that may impact the - * test framework, with the lower byte incremented as necessary - * if multiple changes happened between releases. */ -#define MBEDTLS_THREADING_INTERNAL_VERSION 0x03060000 - -#endif /* MBEDTLS_THREADING_INTERNAL_H */ diff --git a/vendor/mbedtls/library/timing.c b/vendor/mbedtls/library/timing.c deleted file mode 100644 index e3e9da52e..000000000 --- a/vendor/mbedtls/library/timing.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Portable interface to the CPU cycle counter - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_TIMING_C) - -#include "mbedtls/timing.h" - -#if !defined(MBEDTLS_TIMING_ALT) - -#if !defined(_WIN32) && !defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) -#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h" -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -#include -#include - -struct _hr_time { - LARGE_INTEGER start; -}; - -#else - -#include -#include -#include -/* time.h should be included independently of MBEDTLS_HAVE_TIME. If the - * platform matches the ifdefs above, it will be used. */ -#include -#include -struct _hr_time { - struct timeval start; -}; -#endif /* _WIN32 && !EFIX64 && !EFI32 */ - -/** - * \brief Return the elapsed time in milliseconds - * - * \warning May change without notice - * - * \param val points to a timer structure - * \param reset If 0, query the elapsed time. Otherwise (re)start the timer. - * - * \return Elapsed time since the previous reset in ms. When - * restarting, this is always 0. - * - * \note To initialize a timer, call this function with reset=1. - * - * Determining the elapsed time and resetting the timer is not - * atomic on all platforms, so after the sequence - * `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 = - * get_timer(0) }` the value time1+time2 is only approximately - * the delay since the first reset. - */ -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - -unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset) -{ - struct _hr_time *t = (struct _hr_time *) val; - - if (reset) { - QueryPerformanceCounter(&t->start); - return 0; - } else { - unsigned long delta; - LARGE_INTEGER now, hfreq; - QueryPerformanceCounter(&now); - QueryPerformanceFrequency(&hfreq); - delta = (unsigned long) ((now.QuadPart - t->start.QuadPart) * 1000ul - / hfreq.QuadPart); - return delta; - } -} - -#else /* _WIN32 && !EFIX64 && !EFI32 */ - -unsigned long mbedtls_timing_get_timer(struct mbedtls_timing_hr_time *val, int reset) -{ - struct _hr_time *t = (struct _hr_time *) val; - - if (reset) { - gettimeofday(&t->start, NULL); - return 0; - } else { - unsigned long delta; - struct timeval now; - gettimeofday(&now, NULL); - delta = (now.tv_sec - t->start.tv_sec) * 1000ul - + (now.tv_usec - t->start.tv_usec) / 1000; - return delta; - } -} - -#endif /* _WIN32 && !EFIX64 && !EFI32 */ - -/* - * Set delays to watch - */ -void mbedtls_timing_set_delay(void *data, uint32_t int_ms, uint32_t fin_ms) -{ - mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; - - ctx->int_ms = int_ms; - ctx->fin_ms = fin_ms; - - if (fin_ms != 0) { - (void) mbedtls_timing_get_timer(&ctx->timer, 1); - } -} - -/* - * Get number of delays expired - */ -int mbedtls_timing_get_delay(void *data) -{ - mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; - unsigned long elapsed_ms; - - if (ctx->fin_ms == 0) { - return -1; - } - - elapsed_ms = mbedtls_timing_get_timer(&ctx->timer, 0); - - if (elapsed_ms >= ctx->fin_ms) { - return 2; - } - - if (elapsed_ms >= ctx->int_ms) { - return 1; - } - - return 0; -} - -/* - * Get the final delay. - */ -uint32_t mbedtls_timing_get_final_delay( - const mbedtls_timing_delay_context *data) -{ - return data->fin_ms; -} -#endif /* !MBEDTLS_TIMING_ALT */ -#endif /* MBEDTLS_TIMING_C */ diff --git a/vendor/mbedtls/library/version.c b/vendor/mbedtls/library/version.c deleted file mode 100644 index 04397332b..000000000 --- a/vendor/mbedtls/library/version.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Version information - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_VERSION_C) - -#include "mbedtls/version.h" -#include - -unsigned int mbedtls_version_get_number(void) -{ - return MBEDTLS_VERSION_NUMBER; -} - -void mbedtls_version_get_string(char *string) -{ - memcpy(string, MBEDTLS_VERSION_STRING, - sizeof(MBEDTLS_VERSION_STRING)); -} - -void mbedtls_version_get_string_full(char *string) -{ - memcpy(string, MBEDTLS_VERSION_STRING_FULL, - sizeof(MBEDTLS_VERSION_STRING_FULL)); -} - -#endif /* MBEDTLS_VERSION_C */ diff --git a/vendor/mbedtls/library/version_features.c b/vendor/mbedtls/library/version_features.c deleted file mode 100644 index 4fd102991..000000000 --- a/vendor/mbedtls/library/version_features.c +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Version feature information - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_VERSION_C) - -#include "mbedtls/version.h" - -#include - -static const char * const features[] = { -#if defined(MBEDTLS_VERSION_FEATURES) - #if defined(MBEDTLS_HAVE_ASM) - "HAVE_ASM", //no-check-names -#endif /* MBEDTLS_HAVE_ASM */ -#if defined(MBEDTLS_NO_UDBL_DIVISION) - "NO_UDBL_DIVISION", //no-check-names -#endif /* MBEDTLS_NO_UDBL_DIVISION */ -#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) - "NO_64BIT_MULTIPLICATION", //no-check-names -#endif /* MBEDTLS_NO_64BIT_MULTIPLICATION */ -#if defined(MBEDTLS_HAVE_SSE2) - "HAVE_SSE2", //no-check-names -#endif /* MBEDTLS_HAVE_SSE2 */ -#if defined(MBEDTLS_HAVE_TIME) - "HAVE_TIME", //no-check-names -#endif /* MBEDTLS_HAVE_TIME */ -#if defined(MBEDTLS_HAVE_TIME_DATE) - "HAVE_TIME_DATE", //no-check-names -#endif /* MBEDTLS_HAVE_TIME_DATE */ -#if defined(MBEDTLS_PLATFORM_MEMORY) - "PLATFORM_MEMORY", //no-check-names -#endif /* MBEDTLS_PLATFORM_MEMORY */ -#if defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) - "PLATFORM_NO_STD_FUNCTIONS", //no-check-names -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ -#if defined(MBEDTLS_PLATFORM_SETBUF_ALT) - "PLATFORM_SETBUF_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */ -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) - "PLATFORM_EXIT_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ -#if defined(MBEDTLS_PLATFORM_TIME_ALT) - "PLATFORM_TIME_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) - "PLATFORM_FPRINTF_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) - "PLATFORM_PRINTF_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) - "PLATFORM_SNPRINTF_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) - "PLATFORM_VSNPRINTF_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) - "PLATFORM_NV_SEED_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) - "PLATFORM_SETUP_TEARDOWN_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ -#if defined(MBEDTLS_PLATFORM_MS_TIME_ALT) - "PLATFORM_MS_TIME_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_MS_TIME_ALT */ -#if defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) - "PLATFORM_GMTIME_R_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_GMTIME_R_ALT */ -#if defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) - "PLATFORM_ZEROIZE_ALT", //no-check-names -#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ -#if defined(MBEDTLS_DEPRECATED_WARNING) - "DEPRECATED_WARNING", //no-check-names -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#if defined(MBEDTLS_DEPRECATED_REMOVED) - "DEPRECATED_REMOVED", //no-check-names -#endif /* MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_TIMING_ALT) - "TIMING_ALT", //no-check-names -#endif /* MBEDTLS_TIMING_ALT */ -#if defined(MBEDTLS_AES_ALT) - "AES_ALT", //no-check-names -#endif /* MBEDTLS_AES_ALT */ -#if defined(MBEDTLS_ARIA_ALT) - "ARIA_ALT", //no-check-names -#endif /* MBEDTLS_ARIA_ALT */ -#if defined(MBEDTLS_CAMELLIA_ALT) - "CAMELLIA_ALT", //no-check-names -#endif /* MBEDTLS_CAMELLIA_ALT */ -#if defined(MBEDTLS_CCM_ALT) - "CCM_ALT", //no-check-names -#endif /* MBEDTLS_CCM_ALT */ -#if defined(MBEDTLS_CHACHA20_ALT) - "CHACHA20_ALT", //no-check-names -#endif /* MBEDTLS_CHACHA20_ALT */ -#if defined(MBEDTLS_CHACHAPOLY_ALT) - "CHACHAPOLY_ALT", //no-check-names -#endif /* MBEDTLS_CHACHAPOLY_ALT */ -#if defined(MBEDTLS_CMAC_ALT) - "CMAC_ALT", //no-check-names -#endif /* MBEDTLS_CMAC_ALT */ -#if defined(MBEDTLS_DES_ALT) - "DES_ALT", //no-check-names -#endif /* MBEDTLS_DES_ALT */ -#if defined(MBEDTLS_DHM_ALT) - "DHM_ALT", //no-check-names -#endif /* MBEDTLS_DHM_ALT */ -#if defined(MBEDTLS_ECJPAKE_ALT) - "ECJPAKE_ALT", //no-check-names -#endif /* MBEDTLS_ECJPAKE_ALT */ -#if defined(MBEDTLS_GCM_ALT) - "GCM_ALT", //no-check-names -#endif /* MBEDTLS_GCM_ALT */ -#if defined(MBEDTLS_NIST_KW_ALT) - "NIST_KW_ALT", //no-check-names -#endif /* MBEDTLS_NIST_KW_ALT */ -#if defined(MBEDTLS_MD5_ALT) - "MD5_ALT", //no-check-names -#endif /* MBEDTLS_MD5_ALT */ -#if defined(MBEDTLS_POLY1305_ALT) - "POLY1305_ALT", //no-check-names -#endif /* MBEDTLS_POLY1305_ALT */ -#if defined(MBEDTLS_RIPEMD160_ALT) - "RIPEMD160_ALT", //no-check-names -#endif /* MBEDTLS_RIPEMD160_ALT */ -#if defined(MBEDTLS_RSA_ALT) - "RSA_ALT", //no-check-names -#endif /* MBEDTLS_RSA_ALT */ -#if defined(MBEDTLS_SHA1_ALT) - "SHA1_ALT", //no-check-names -#endif /* MBEDTLS_SHA1_ALT */ -#if defined(MBEDTLS_SHA256_ALT) - "SHA256_ALT", //no-check-names -#endif /* MBEDTLS_SHA256_ALT */ -#if defined(MBEDTLS_SHA512_ALT) - "SHA512_ALT", //no-check-names -#endif /* MBEDTLS_SHA512_ALT */ -#if defined(MBEDTLS_ECP_ALT) - "ECP_ALT", //no-check-names -#endif /* MBEDTLS_ECP_ALT */ -#if defined(MBEDTLS_MD5_PROCESS_ALT) - "MD5_PROCESS_ALT", //no-check-names -#endif /* MBEDTLS_MD5_PROCESS_ALT */ -#if defined(MBEDTLS_RIPEMD160_PROCESS_ALT) - "RIPEMD160_PROCESS_ALT", //no-check-names -#endif /* MBEDTLS_RIPEMD160_PROCESS_ALT */ -#if defined(MBEDTLS_SHA1_PROCESS_ALT) - "SHA1_PROCESS_ALT", //no-check-names -#endif /* MBEDTLS_SHA1_PROCESS_ALT */ -#if defined(MBEDTLS_SHA256_PROCESS_ALT) - "SHA256_PROCESS_ALT", //no-check-names -#endif /* MBEDTLS_SHA256_PROCESS_ALT */ -#if defined(MBEDTLS_SHA512_PROCESS_ALT) - "SHA512_PROCESS_ALT", //no-check-names -#endif /* MBEDTLS_SHA512_PROCESS_ALT */ -#if defined(MBEDTLS_DES_SETKEY_ALT) - "DES_SETKEY_ALT", //no-check-names -#endif /* MBEDTLS_DES_SETKEY_ALT */ -#if defined(MBEDTLS_DES_CRYPT_ECB_ALT) - "DES_CRYPT_ECB_ALT", //no-check-names -#endif /* MBEDTLS_DES_CRYPT_ECB_ALT */ -#if defined(MBEDTLS_DES3_CRYPT_ECB_ALT) - "DES3_CRYPT_ECB_ALT", //no-check-names -#endif /* MBEDTLS_DES3_CRYPT_ECB_ALT */ -#if defined(MBEDTLS_AES_SETKEY_ENC_ALT) - "AES_SETKEY_ENC_ALT", //no-check-names -#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */ -#if defined(MBEDTLS_AES_SETKEY_DEC_ALT) - "AES_SETKEY_DEC_ALT", //no-check-names -#endif /* MBEDTLS_AES_SETKEY_DEC_ALT */ -#if defined(MBEDTLS_AES_ENCRYPT_ALT) - "AES_ENCRYPT_ALT", //no-check-names -#endif /* MBEDTLS_AES_ENCRYPT_ALT */ -#if defined(MBEDTLS_AES_DECRYPT_ALT) - "AES_DECRYPT_ALT", //no-check-names -#endif /* MBEDTLS_AES_DECRYPT_ALT */ -#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) - "ECDH_GEN_PUBLIC_ALT", //no-check-names -#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */ -#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) - "ECDH_COMPUTE_SHARED_ALT", //no-check-names -#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ -#if defined(MBEDTLS_ECDSA_VERIFY_ALT) - "ECDSA_VERIFY_ALT", //no-check-names -#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ -#if defined(MBEDTLS_ECDSA_SIGN_ALT) - "ECDSA_SIGN_ALT", //no-check-names -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ -#if defined(MBEDTLS_ECDSA_GENKEY_ALT) - "ECDSA_GENKEY_ALT", //no-check-names -#endif /* MBEDTLS_ECDSA_GENKEY_ALT */ -#if defined(MBEDTLS_ECP_INTERNAL_ALT) - "ECP_INTERNAL_ALT", //no-check-names -#endif /* MBEDTLS_ECP_INTERNAL_ALT */ -#if defined(MBEDTLS_ECP_NO_FALLBACK) - "ECP_NO_FALLBACK", //no-check-names -#endif /* MBEDTLS_ECP_NO_FALLBACK */ -#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) - "ECP_RANDOMIZE_JAC_ALT", //no-check-names -#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ -#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) - "ECP_ADD_MIXED_ALT", //no-check-names -#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ -#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) - "ECP_DOUBLE_JAC_ALT", //no-check-names -#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) - "ECP_NORMALIZE_JAC_MANY_ALT", //no-check-names -#endif /* MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */ -#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) - "ECP_NORMALIZE_JAC_ALT", //no-check-names -#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ -#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) - "ECP_DOUBLE_ADD_MXZ_ALT", //no-check-names -#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ -#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) - "ECP_RANDOMIZE_MXZ_ALT", //no-check-names -#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ -#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) - "ECP_NORMALIZE_MXZ_ALT", //no-check-names -#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ -#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) - "ENTROPY_HARDWARE_ALT", //no-check-names -#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ -#if defined(MBEDTLS_AES_ROM_TABLES) - "AES_ROM_TABLES", //no-check-names -#endif /* MBEDTLS_AES_ROM_TABLES */ -#if defined(MBEDTLS_AES_FEWER_TABLES) - "AES_FEWER_TABLES", //no-check-names -#endif /* MBEDTLS_AES_FEWER_TABLES */ -#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) - "AES_ONLY_128_BIT_KEY_LENGTH", //no-check-names -#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ -#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) - "AES_USE_HARDWARE_ONLY", //no-check-names -#endif /* MBEDTLS_AES_USE_HARDWARE_ONLY */ -#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) - "CAMELLIA_SMALL_MEMORY", //no-check-names -#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ -#if defined(MBEDTLS_CHECK_RETURN_WARNING) - "CHECK_RETURN_WARNING", //no-check-names -#endif /* MBEDTLS_CHECK_RETURN_WARNING */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) - "CIPHER_MODE_CBC", //no-check-names -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CIPHER_MODE_CFB) - "CIPHER_MODE_CFB", //no-check-names -#endif /* MBEDTLS_CIPHER_MODE_CFB */ -#if defined(MBEDTLS_CIPHER_MODE_CTR) - "CIPHER_MODE_CTR", //no-check-names -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#if defined(MBEDTLS_CIPHER_MODE_OFB) - "CIPHER_MODE_OFB", //no-check-names -#endif /* MBEDTLS_CIPHER_MODE_OFB */ -#if defined(MBEDTLS_CIPHER_MODE_XTS) - "CIPHER_MODE_XTS", //no-check-names -#endif /* MBEDTLS_CIPHER_MODE_XTS */ -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - "CIPHER_NULL_CIPHER", //no-check-names -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - "CIPHER_PADDING_PKCS7", //no-check-names -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) - "CIPHER_PADDING_ONE_AND_ZEROS", //no-check-names -#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) - "CIPHER_PADDING_ZEROS_AND_LEN", //no-check-names -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) - "CIPHER_PADDING_ZEROS", //no-check-names -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ -#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) - "CTR_DRBG_USE_128_BIT_KEY", //no-check-names -#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */ -#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) - "ECDH_VARIANT_EVEREST_ENABLED", //no-check-names -#endif /* MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) - "ECP_DP_SECP192R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) - "ECP_DP_SECP224R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) - "ECP_DP_SECP256R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) - "ECP_DP_SECP384R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) - "ECP_DP_SECP521R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) - "ECP_DP_SECP192K1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) - "ECP_DP_SECP224K1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) - "ECP_DP_SECP256K1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) - "ECP_DP_BP256R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) - "ECP_DP_BP384R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) - "ECP_DP_BP512R1_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) - "ECP_DP_CURVE25519_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ -#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) - "ECP_DP_CURVE448_ENABLED", //no-check-names -#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ -#if defined(MBEDTLS_ECP_NIST_OPTIM) - "ECP_NIST_OPTIM", //no-check-names -#endif /* MBEDTLS_ECP_NIST_OPTIM */ -#if defined(MBEDTLS_ECP_RESTARTABLE) - "ECP_RESTARTABLE", //no-check-names -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#if defined(MBEDTLS_ECP_WITH_MPI_UINT) - "ECP_WITH_MPI_UINT", //no-check-names -#endif /* MBEDTLS_ECP_WITH_MPI_UINT */ -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) - "ECDSA_DETERMINISTIC", //no-check-names -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - "KEY_EXCHANGE_PSK_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - "KEY_EXCHANGE_DHE_PSK_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - "KEY_EXCHANGE_ECDHE_PSK_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - "KEY_EXCHANGE_RSA_PSK_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - "KEY_EXCHANGE_RSA_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - "KEY_EXCHANGE_DHE_RSA_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) - "KEY_EXCHANGE_ECDHE_RSA_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - "KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - "KEY_EXCHANGE_ECDH_ECDSA_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) - "KEY_EXCHANGE_ECDH_RSA_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - "KEY_EXCHANGE_ECJPAKE_ENABLED", //no-check-names -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) - "PK_PARSE_EC_EXTENDED", //no-check-names -#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ -#if defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) - "PK_PARSE_EC_COMPRESSED", //no-check-names -#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */ -#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) - "ERROR_STRERROR_DUMMY", //no-check-names -#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ -#if defined(MBEDTLS_GENPRIME) - "GENPRIME", //no-check-names -#endif /* MBEDTLS_GENPRIME */ -#if defined(MBEDTLS_FS_IO) - "FS_IO", //no-check-names -#endif /* MBEDTLS_FS_IO */ -#if defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) - "NO_DEFAULT_ENTROPY_SOURCES", //no-check-names -#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ -#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) - "NO_PLATFORM_ENTROPY", //no-check-names -#endif /* MBEDTLS_NO_PLATFORM_ENTROPY */ -#if defined(MBEDTLS_ENTROPY_FORCE_SHA256) - "ENTROPY_FORCE_SHA256", //no-check-names -#endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */ -#if defined(MBEDTLS_ENTROPY_NV_SEED) - "ENTROPY_NV_SEED", //no-check-names -#endif /* MBEDTLS_ENTROPY_NV_SEED */ -#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) - "PSA_CRYPTO_KEY_ID_ENCODES_OWNER", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ -#if defined(MBEDTLS_MEMORY_DEBUG) - "MEMORY_DEBUG", //no-check-names -#endif /* MBEDTLS_MEMORY_DEBUG */ -#if defined(MBEDTLS_MEMORY_BACKTRACE) - "MEMORY_BACKTRACE", //no-check-names -#endif /* MBEDTLS_MEMORY_BACKTRACE */ -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) - "PK_RSA_ALT_SUPPORT", //no-check-names -#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ -#if defined(MBEDTLS_PKCS1_V15) - "PKCS1_V15", //no-check-names -#endif /* MBEDTLS_PKCS1_V15 */ -#if defined(MBEDTLS_PKCS1_V21) - "PKCS1_V21", //no-check-names -#endif /* MBEDTLS_PKCS1_V21 */ -#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) - "PSA_CRYPTO_BUILTIN_KEYS", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) - "PSA_CRYPTO_CLIENT", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - "PSA_CRYPTO_EXTERNAL_RNG", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ -#if defined(MBEDTLS_PSA_CRYPTO_SPM) - "PSA_CRYPTO_SPM", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_SPM */ -#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) - "PSA_KEY_STORE_DYNAMIC", //no-check-names -#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */ -#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) - "PSA_P256M_DRIVER_ENABLED", //no-check-names -#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */ -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) - "PSA_INJECT_ENTROPY", //no-check-names -#endif /* MBEDTLS_PSA_INJECT_ENTROPY */ -#if defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) - "PSA_ASSUME_EXCLUSIVE_BUFFERS", //no-check-names -#endif /* MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ -#if defined(MBEDTLS_RSA_NO_CRT) - "RSA_NO_CRT", //no-check-names -#endif /* MBEDTLS_RSA_NO_CRT */ -#if defined(MBEDTLS_SELF_TEST) - "SELF_TEST", //no-check-names -#endif /* MBEDTLS_SELF_TEST */ -#if defined(MBEDTLS_SHA256_SMALLER) - "SHA256_SMALLER", //no-check-names -#endif /* MBEDTLS_SHA256_SMALLER */ -#if defined(MBEDTLS_SHA512_SMALLER) - "SHA512_SMALLER", //no-check-names -#endif /* MBEDTLS_SHA512_SMALLER */ -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - "SSL_ALL_ALERT_MESSAGES", //no-check-names -#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - "SSL_DTLS_CONNECTION_ID", //no-check-names -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) - "SSL_DTLS_CONNECTION_ID_COMPAT", //no-check-names -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - "SSL_ASYNC_PRIVATE", //no-check-names -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ -#if defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME) - "SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME", //no-check-names -#endif /* MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME */ -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - "SSL_CONTEXT_SERIALIZATION", //no-check-names -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ -#if defined(MBEDTLS_SSL_DEBUG_ALL) - "SSL_DEBUG_ALL", //no-check-names -#endif /* MBEDTLS_SSL_DEBUG_ALL */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - "SSL_ENCRYPT_THEN_MAC", //no-check-names -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - "SSL_EXTENDED_MASTER_SECRET", //no-check-names -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - "SSL_KEEP_PEER_CERTIFICATE", //no-check-names -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) - "SSL_KEYING_MATERIAL_EXPORT", //no-check-names -#endif /* MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - "SSL_RENEGOTIATION", //no-check-names -#endif /* MBEDTLS_SSL_RENEGOTIATION */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - "SSL_MAX_FRAGMENT_LENGTH", //no-check-names -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - "SSL_RECORD_SIZE_LIMIT", //no-check-names -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - "SSL_PROTO_TLS1_2", //no-check-names -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - "SSL_PROTO_TLS1_3", //no-check-names -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - "SSL_TLS1_3_COMPATIBILITY_MODE", //no-check-names -#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) - "SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED", //no-check-names -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - "SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED", //no-check-names -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) - "SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED", //no-check-names -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED */ -#if defined(MBEDTLS_SSL_EARLY_DATA) - "SSL_EARLY_DATA", //no-check-names -#endif /* MBEDTLS_SSL_EARLY_DATA */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - "SSL_PROTO_DTLS", //no-check-names -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_ALPN) - "SSL_ALPN", //no-check-names -#endif /* MBEDTLS_SSL_ALPN */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - "SSL_DTLS_ANTI_REPLAY", //no-check-names -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - "SSL_DTLS_HELLO_VERIFY", //no-check-names -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ -#if defined(MBEDTLS_SSL_DTLS_SRTP) - "SSL_DTLS_SRTP", //no-check-names -#endif /* MBEDTLS_SSL_DTLS_SRTP */ -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) - "SSL_DTLS_CLIENT_PORT_REUSE", //no-check-names -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - "SSL_SESSION_TICKETS", //no-check-names -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - "SSL_SERVER_NAME_INDICATION", //no-check-names -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - "SSL_VARIABLE_BUFFER_LENGTH", //no-check-names -#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */ -#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) - "TEST_CONSTANT_FLOW_MEMSAN", //no-check-names -#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */ -#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) - "TEST_CONSTANT_FLOW_VALGRIND", //no-check-names -#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */ -#if defined(MBEDTLS_TEST_HOOKS) - "TEST_HOOKS", //no-check-names -#endif /* MBEDTLS_TEST_HOOKS */ -#if defined(MBEDTLS_THREADING_ALT) - "THREADING_ALT", //no-check-names -#endif /* MBEDTLS_THREADING_ALT */ -#if defined(MBEDTLS_THREADING_PTHREAD) - "THREADING_PTHREAD", //no-check-names -#endif /* MBEDTLS_THREADING_PTHREAD */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - "USE_PSA_CRYPTO", //no-check-names -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) - "PSA_CRYPTO_CONFIG", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */ -#if defined(MBEDTLS_VERSION_FEATURES) - "VERSION_FEATURES", //no-check-names -#endif /* MBEDTLS_VERSION_FEATURES */ -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - "X509_TRUSTED_CERTIFICATE_CALLBACK", //no-check-names -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -#if defined(MBEDTLS_X509_REMOVE_INFO) - "X509_REMOVE_INFO", //no-check-names -#endif /* MBEDTLS_X509_REMOVE_INFO */ -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - "X509_RSASSA_PSS_SUPPORT", //no-check-names -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ -#if defined(MBEDTLS_AESNI_C) - "AESNI_C", //no-check-names -#endif /* MBEDTLS_AESNI_C */ -#if defined(MBEDTLS_AESCE_C) - "AESCE_C", //no-check-names -#endif /* MBEDTLS_AESCE_C */ -#if defined(MBEDTLS_AES_C) - "AES_C", //no-check-names -#endif /* MBEDTLS_AES_C */ -#if defined(MBEDTLS_ASN1_PARSE_C) - "ASN1_PARSE_C", //no-check-names -#endif /* MBEDTLS_ASN1_PARSE_C */ -#if defined(MBEDTLS_ASN1_WRITE_C) - "ASN1_WRITE_C", //no-check-names -#endif /* MBEDTLS_ASN1_WRITE_C */ -#if defined(MBEDTLS_BASE64_C) - "BASE64_C", //no-check-names -#endif /* MBEDTLS_BASE64_C */ -#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) - "BLOCK_CIPHER_NO_DECRYPT", //no-check-names -#endif /* MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ -#if defined(MBEDTLS_BIGNUM_C) - "BIGNUM_C", //no-check-names -#endif /* MBEDTLS_BIGNUM_C */ -#if defined(MBEDTLS_CAMELLIA_C) - "CAMELLIA_C", //no-check-names -#endif /* MBEDTLS_CAMELLIA_C */ -#if defined(MBEDTLS_ARIA_C) - "ARIA_C", //no-check-names -#endif /* MBEDTLS_ARIA_C */ -#if defined(MBEDTLS_CCM_C) - "CCM_C", //no-check-names -#endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CHACHA20_C) - "CHACHA20_C", //no-check-names -#endif /* MBEDTLS_CHACHA20_C */ -#if defined(MBEDTLS_CHACHAPOLY_C) - "CHACHAPOLY_C", //no-check-names -#endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_CIPHER_C) - "CIPHER_C", //no-check-names -#endif /* MBEDTLS_CIPHER_C */ -#if defined(MBEDTLS_CMAC_C) - "CMAC_C", //no-check-names -#endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_CTR_DRBG_C) - "CTR_DRBG_C", //no-check-names -#endif /* MBEDTLS_CTR_DRBG_C */ -#if defined(MBEDTLS_DEBUG_C) - "DEBUG_C", //no-check-names -#endif /* MBEDTLS_DEBUG_C */ -#if defined(MBEDTLS_DES_C) - "DES_C", //no-check-names -#endif /* MBEDTLS_DES_C */ -#if defined(MBEDTLS_DHM_C) - "DHM_C", //no-check-names -#endif /* MBEDTLS_DHM_C */ -#if defined(MBEDTLS_ECDH_C) - "ECDH_C", //no-check-names -#endif /* MBEDTLS_ECDH_C */ -#if defined(MBEDTLS_ECDSA_C) - "ECDSA_C", //no-check-names -#endif /* MBEDTLS_ECDSA_C */ -#if defined(MBEDTLS_ECJPAKE_C) - "ECJPAKE_C", //no-check-names -#endif /* MBEDTLS_ECJPAKE_C */ -#if defined(MBEDTLS_ECP_C) - "ECP_C", //no-check-names -#endif /* MBEDTLS_ECP_C */ -#if defined(MBEDTLS_ENTROPY_C) - "ENTROPY_C", //no-check-names -#endif /* MBEDTLS_ENTROPY_C */ -#if defined(MBEDTLS_ERROR_C) - "ERROR_C", //no-check-names -#endif /* MBEDTLS_ERROR_C */ -#if defined(MBEDTLS_GCM_C) - "GCM_C", //no-check-names -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_GCM_LARGE_TABLE) - "GCM_LARGE_TABLE", //no-check-names -#endif /* MBEDTLS_GCM_LARGE_TABLE */ -#if defined(MBEDTLS_HKDF_C) - "HKDF_C", //no-check-names -#endif /* MBEDTLS_HKDF_C */ -#if defined(MBEDTLS_HMAC_DRBG_C) - "HMAC_DRBG_C", //no-check-names -#endif /* MBEDTLS_HMAC_DRBG_C */ -#if defined(MBEDTLS_LMS_C) - "LMS_C", //no-check-names -#endif /* MBEDTLS_LMS_C */ -#if defined(MBEDTLS_LMS_PRIVATE) - "LMS_PRIVATE", //no-check-names -#endif /* MBEDTLS_LMS_PRIVATE */ -#if defined(MBEDTLS_NIST_KW_C) - "NIST_KW_C", //no-check-names -#endif /* MBEDTLS_NIST_KW_C */ -#if defined(MBEDTLS_MD_C) - "MD_C", //no-check-names -#endif /* MBEDTLS_MD_C */ -#if defined(MBEDTLS_MD5_C) - "MD5_C", //no-check-names -#endif /* MBEDTLS_MD5_C */ -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) - "MEMORY_BUFFER_ALLOC_C", //no-check-names -#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ -#if defined(MBEDTLS_NET_C) - "NET_C", //no-check-names -#endif /* MBEDTLS_NET_C */ -#if defined(MBEDTLS_OID_C) - "OID_C", //no-check-names -#endif /* MBEDTLS_OID_C */ -#if defined(MBEDTLS_PADLOCK_C) - "PADLOCK_C", //no-check-names -#endif /* MBEDTLS_PADLOCK_C */ -#if defined(MBEDTLS_PEM_PARSE_C) - "PEM_PARSE_C", //no-check-names -#endif /* MBEDTLS_PEM_PARSE_C */ -#if defined(MBEDTLS_PEM_WRITE_C) - "PEM_WRITE_C", //no-check-names -#endif /* MBEDTLS_PEM_WRITE_C */ -#if defined(MBEDTLS_PK_C) - "PK_C", //no-check-names -#endif /* MBEDTLS_PK_C */ -#if defined(MBEDTLS_PK_PARSE_C) - "PK_PARSE_C", //no-check-names -#endif /* MBEDTLS_PK_PARSE_C */ -#if defined(MBEDTLS_PK_WRITE_C) - "PK_WRITE_C", //no-check-names -#endif /* MBEDTLS_PK_WRITE_C */ -#if defined(MBEDTLS_PKCS5_C) - "PKCS5_C", //no-check-names -#endif /* MBEDTLS_PKCS5_C */ -#if defined(MBEDTLS_PKCS7_C) - "PKCS7_C", //no-check-names -#endif /* MBEDTLS_PKCS7_C */ -#if defined(MBEDTLS_PKCS12_C) - "PKCS12_C", //no-check-names -#endif /* MBEDTLS_PKCS12_C */ -#if defined(MBEDTLS_PLATFORM_C) - "PLATFORM_C", //no-check-names -#endif /* MBEDTLS_PLATFORM_C */ -#if defined(MBEDTLS_POLY1305_C) - "POLY1305_C", //no-check-names -#endif /* MBEDTLS_POLY1305_C */ -#if defined(MBEDTLS_PSA_CRYPTO_C) - "PSA_CRYPTO_C", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_C */ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - "PSA_CRYPTO_SE_C", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - "PSA_CRYPTO_STORAGE_C", //no-check-names -#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -#if defined(MBEDTLS_PSA_ITS_FILE_C) - "PSA_ITS_FILE_C", //no-check-names -#endif /* MBEDTLS_PSA_ITS_FILE_C */ -#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) - "PSA_STATIC_KEY_SLOTS", //no-check-names -#endif /* MBEDTLS_PSA_STATIC_KEY_SLOTS */ -#if defined(MBEDTLS_RIPEMD160_C) - "RIPEMD160_C", //no-check-names -#endif /* MBEDTLS_RIPEMD160_C */ -#if defined(MBEDTLS_RSA_C) - "RSA_C", //no-check-names -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_SHA1_C) - "SHA1_C", //no-check-names -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA224_C) - "SHA224_C", //no-check-names -#endif /* MBEDTLS_SHA224_C */ -#if defined(MBEDTLS_SHA256_C) - "SHA256_C", //no-check-names -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) - "SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT", //no-check-names -#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT */ -#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) - "SHA256_USE_A64_CRYPTO_IF_PRESENT", //no-check-names -#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */ -#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) - "SHA256_USE_ARMV8_A_CRYPTO_ONLY", //no-check-names -#endif /* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY */ -#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) - "SHA256_USE_A64_CRYPTO_ONLY", //no-check-names -#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */ -#if defined(MBEDTLS_SHA384_C) - "SHA384_C", //no-check-names -#endif /* MBEDTLS_SHA384_C */ -#if defined(MBEDTLS_SHA512_C) - "SHA512_C", //no-check-names -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_SHA3_C) - "SHA3_C", //no-check-names -#endif /* MBEDTLS_SHA3_C */ -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) - "SHA512_USE_A64_CRYPTO_IF_PRESENT", //no-check-names -#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT */ -#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) - "SHA512_USE_A64_CRYPTO_ONLY", //no-check-names -#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ -#if defined(MBEDTLS_SSL_CACHE_C) - "SSL_CACHE_C", //no-check-names -#endif /* MBEDTLS_SSL_CACHE_C */ -#if defined(MBEDTLS_SSL_COOKIE_C) - "SSL_COOKIE_C", //no-check-names -#endif /* MBEDTLS_SSL_COOKIE_C */ -#if defined(MBEDTLS_SSL_TICKET_C) - "SSL_TICKET_C", //no-check-names -#endif /* MBEDTLS_SSL_TICKET_C */ -#if defined(MBEDTLS_SSL_CLI_C) - "SSL_CLI_C", //no-check-names -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - "SSL_SRV_C", //no-check-names -#endif /* MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_TLS_C) - "SSL_TLS_C", //no-check-names -#endif /* MBEDTLS_SSL_TLS_C */ -#if defined(MBEDTLS_THREADING_C) - "THREADING_C", //no-check-names -#endif /* MBEDTLS_THREADING_C */ -#if defined(MBEDTLS_TIMING_C) - "TIMING_C", //no-check-names -#endif /* MBEDTLS_TIMING_C */ -#if defined(MBEDTLS_VERSION_C) - "VERSION_C", //no-check-names -#endif /* MBEDTLS_VERSION_C */ -#if defined(MBEDTLS_X509_USE_C) - "X509_USE_C", //no-check-names -#endif /* MBEDTLS_X509_USE_C */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - "X509_CRT_PARSE_C", //no-check-names -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_X509_CRL_PARSE_C) - "X509_CRL_PARSE_C", //no-check-names -#endif /* MBEDTLS_X509_CRL_PARSE_C */ -#if defined(MBEDTLS_X509_CSR_PARSE_C) - "X509_CSR_PARSE_C", //no-check-names -#endif /* MBEDTLS_X509_CSR_PARSE_C */ -#if defined(MBEDTLS_X509_CREATE_C) - "X509_CREATE_C", //no-check-names -#endif /* MBEDTLS_X509_CREATE_C */ -#if defined(MBEDTLS_X509_CRT_WRITE_C) - "X509_CRT_WRITE_C", //no-check-names -#endif /* MBEDTLS_X509_CRT_WRITE_C */ -#if defined(MBEDTLS_X509_CSR_WRITE_C) - "X509_CSR_WRITE_C", //no-check-names -#endif /* MBEDTLS_X509_CSR_WRITE_C */ -#endif /* MBEDTLS_VERSION_FEATURES */ - NULL -}; - -int mbedtls_version_check_feature(const char *feature) -{ - const char * const *idx = features; - - if (*idx == NULL) { - return -2; - } - - if (feature == NULL) { - return -1; - } - - if (strncmp(feature, "MBEDTLS_", 8)) { - return -1; - } - - feature += 8; - - while (*idx != NULL) { - if (!strcmp(*idx, feature)) { - return 0; - } - idx++; - } - return -1; -} - -#endif /* MBEDTLS_VERSION_C */ diff --git a/vendor/mbedtls/library/x509.c b/vendor/mbedtls/library/x509.c deleted file mode 100644 index f97fb4458..000000000 --- a/vendor/mbedtls/library/x509.c +++ /dev/null @@ -1,1776 +0,0 @@ -/* - * X.509 common functions for parsing and verification - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_X509_USE_C) - -#include "x509_internal.h" -#include "mbedtls/asn1.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" - -#include -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#include "mbedtls/asn1write.h" - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "mbedtls/platform_util.h" -#include -#endif - -#define CHECK(code) \ - do { \ - if ((ret = (code)) != 0) { \ - return ret; \ - } \ - } while (0) - -#define CHECK_RANGE(min, max, val) \ - do { \ - if ((val) < (min) || (val) > (max)) { \ - return ret; \ - } \ - } while (0) - -/* - * CertificateSerialNumber ::= INTEGER - */ -int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((end - *p) < 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - if (**p != (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2) && - **p != MBEDTLS_ASN1_INTEGER) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - serial->tag = *(*p)++; - - if ((ret = mbedtls_asn1_get_len(p, end, &serial->len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL, ret); - } - - serial->p = *p; - *p += serial->len; - - return 0; -} - -/* Get an algorithm identifier without parameters (eg for signatures) - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ -int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - return 0; -} - -/* - * Parse an algorithm identifier with (optional) parameters - */ -int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_asn1_get_alg(p, end, alg, params)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - return 0; -} - -/* - * Convert md type to string - */ -#if !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - -static inline const char *md_type_to_string(mbedtls_md_type_t md_alg) -{ - switch (md_alg) { -#if defined(MBEDTLS_MD_CAN_MD5) - case MBEDTLS_MD_MD5: - return "MD5"; -#endif -#if defined(MBEDTLS_MD_CAN_SHA1) - case MBEDTLS_MD_SHA1: - return "SHA1"; -#endif -#if defined(MBEDTLS_MD_CAN_SHA224) - case MBEDTLS_MD_SHA224: - return "SHA224"; -#endif -#if defined(MBEDTLS_MD_CAN_SHA256) - case MBEDTLS_MD_SHA256: - return "SHA256"; -#endif -#if defined(MBEDTLS_MD_CAN_SHA384) - case MBEDTLS_MD_SHA384: - return "SHA384"; -#endif -#if defined(MBEDTLS_MD_CAN_SHA512) - case MBEDTLS_MD_SHA512: - return "SHA512"; -#endif -#if defined(MBEDTLS_MD_CAN_RIPEMD160) - case MBEDTLS_MD_RIPEMD160: - return "RIPEMD160"; -#endif - case MBEDTLS_MD_NONE: - return NULL; - default: - return NULL; - } -} - -#endif /* !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) */ - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -/* - * HashAlgorithm ::= AlgorithmIdentifier - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - * - * For HashAlgorithm, parameters MUST be NULL or absent. - */ -static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p; - const unsigned char *end; - mbedtls_x509_buf md_oid; - size_t len; - - /* Make sure we got a SEQUENCE and setup bounds */ - if (alg->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - p = alg->p; - end = p + alg->len; - - if (p >= end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - /* Parse md_oid */ - md_oid.tag = *p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &md_oid.len, MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - md_oid.p = p; - p += md_oid.len; - - /* Get md_alg from md_oid */ - if ((ret = mbedtls_oid_get_md_alg(&md_oid, md_alg)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - /* Make sure params is absent of NULL */ - if (p == end) { - return 0; - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_NULL)) != 0 || len != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * RSASSA-PSS-params ::= SEQUENCE { - * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, - * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, - * saltLength [2] INTEGER DEFAULT 20, - * trailerField [3] INTEGER DEFAULT 1 } - * -- Note that the tags in this Sequence are explicit. - * - * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value - * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other - * option. Enforce this at parsing time. - */ -int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params, - mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, - int *salt_len) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char *p; - const unsigned char *end, *end2; - size_t len; - mbedtls_x509_buf alg_id, alg_params; - - /* First set everything to defaults */ - *md_alg = MBEDTLS_MD_SHA1; - *mgf_md = MBEDTLS_MD_SHA1; - *salt_len = 20; - - /* Make sure params is a SEQUENCE and setup bounds */ - if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - p = (unsigned char *) params->p; - end = p + params->len; - - if (p == end) { - return 0; - } - - /* - * HashAlgorithm - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 0)) == 0) { - end2 = p + len; - - /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ - if ((ret = mbedtls_x509_get_alg_null(&p, end2, &alg_id)) != 0) { - return ret; - } - - if ((ret = mbedtls_oid_get_md_alg(&alg_id, md_alg)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p != end2) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p == end) { - return 0; - } - - /* - * MaskGenAlgorithm - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 1)) == 0) { - end2 = p + len; - - /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ - if ((ret = mbedtls_x509_get_alg(&p, end2, &alg_id, &alg_params)) != 0) { - return ret; - } - - /* Only MFG1 is recognised for now */ - if (MBEDTLS_OID_CMP(MBEDTLS_OID_MGF1, &alg_id) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE, - MBEDTLS_ERR_OID_NOT_FOUND); - } - - /* Parse HashAlgorithm */ - if ((ret = x509_get_hash_alg(&alg_params, mgf_md)) != 0) { - return ret; - } - - if (p != end2) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p == end) { - return 0; - } - - /* - * salt_len - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 2)) == 0) { - end2 = p + len; - - if ((ret = mbedtls_asn1_get_int(&p, end2, salt_len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p != end2) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p == end) { - return 0; - } - - /* - * trailer_field (if present, must be 1) - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 3)) == 0) { - int trailer_field; - - end2 = p + len; - - if ((ret = mbedtls_asn1_get_int(&p, end2, &trailer_field)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p != end2) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - if (trailer_field != 1) { - return MBEDTLS_ERR_X509_INVALID_ALG; - } - } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret); - } - - if (p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - -/* - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - */ -static int x509_get_attr_type_value(unsigned char **p, - const unsigned char *end, - mbedtls_x509_name *cur) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - mbedtls_x509_buf *oid; - mbedtls_x509_buf *val; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret); - } - - end = *p + len; - - if ((end - *p) < 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - oid = &cur->oid; - oid->tag = **p; - - if ((ret = mbedtls_asn1_get_tag(p, end, &oid->len, MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret); - } - - oid->p = *p; - *p += oid->len; - - if ((end - *p) < 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - if (**p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && - **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && - **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && - **p != MBEDTLS_ASN1_BIT_STRING) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - val = &cur->val; - val->tag = *(*p)++; - - if ((ret = mbedtls_asn1_get_len(p, end, &val->len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret); - } - - val->p = *p; - *p += val->len; - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - cur->next = NULL; - - return 0; -} - -/* - * Name ::= CHOICE { -- only one possibility for now -- - * rdnSequence RDNSequence } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - * - * RelativeDistinguishedName ::= - * SET OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - * - * The data structure is optimized for the common case where each RDN has only - * one element, which is represented as a list of AttributeTypeAndValue. - * For the general case we still use a flat list, but we mark elements of the - * same set so that they are "merged" together in the functions that consume - * this list, eg mbedtls_x509_dn_gets(). - * - * On success, this function may allocate a linked list starting at cur->next - * that must later be free'd by the caller using mbedtls_free(). In error - * cases, this function frees all allocated memory internally and the caller - * has no freeing responsibilities. - */ -int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t set_len; - const unsigned char *end_set; - mbedtls_x509_name *head = cur; - - /* don't use recursion, we'd risk stack overflow if not optimized */ - while (1) { - /* - * parse SET - */ - if ((ret = mbedtls_asn1_get_tag(p, end, &set_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret); - goto error; - } - - end_set = *p + set_len; - - while (1) { - if ((ret = x509_get_attr_type_value(p, end_set, cur)) != 0) { - goto error; - } - - if (*p == end_set) { - break; - } - - /* Mark this item as being no the only one in a set */ - cur->next_merged = 1; - - cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name)); - - if (cur->next == NULL) { - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - goto error; - } - - cur = cur->next; - } - - /* - * continue until end of SEQUENCE is reached - */ - if (*p == end) { - return 0; - } - - cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name)); - - if (cur->next == NULL) { - ret = MBEDTLS_ERR_X509_ALLOC_FAILED; - goto error; - } - - cur = cur->next; - } - -error: - /* Skip the first element as we did not allocate it */ - mbedtls_asn1_free_named_data_list_shallow(head->next); - head->next = NULL; - - return ret; -} - -static int x509_date_is_valid(const mbedtls_x509_time *t) -{ - unsigned int month_days; - unsigned int year; - switch (t->mon) { - case 1: case 3: case 5: case 7: case 8: case 10: case 12: - month_days = 31; - break; - case 4: case 6: case 9: case 11: - month_days = 30; - break; - case 2: - year = (unsigned int) t->year; - month_days = ((year & 3) || (!(year % 100) - && (year % 400))) - ? 28 : 29; - break; - default: - return MBEDTLS_ERR_X509_INVALID_DATE; - } - - if ((unsigned int) (t->day - 1) >= month_days || /* (1 - days in month) */ - /* (unsigned int) (t->mon - 1) >= 12 || */ /* (1 - 12) checked above */ - (unsigned int) t->year > 9999 || /* (0 - 9999) */ - (unsigned int) t->hour > 23 || /* (0 - 23) */ - (unsigned int) t->min > 59 || /* (0 - 59) */ - (unsigned int) t->sec > 59) { /* (0 - 59) */ - return MBEDTLS_ERR_X509_INVALID_DATE; - } - - return 0; -} - -static int x509_parse2_int(const unsigned char *p) -{ - uint32_t d1 = p[0] - '0'; - uint32_t d2 = p[1] - '0'; - return (d1 < 10 && d2 < 10) ? (int) (d1 * 10 + d2) : -1; -} - -/* - * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) - * field. - */ -static int x509_parse_time(const unsigned char *p, mbedtls_x509_time *tm, - size_t yearlen) -{ - int x; - - /* - * Parse year, month, day, hour, minute, second - */ - tm->year = x509_parse2_int(p); - if (tm->year < 0) { - return MBEDTLS_ERR_X509_INVALID_DATE; - } - - if (4 == yearlen) { - x = tm->year * 100; - p += 2; - tm->year = x509_parse2_int(p); - if (tm->year < 0) { - return MBEDTLS_ERR_X509_INVALID_DATE; - } - } else { - x = (tm->year < 50) ? 2000 : 1900; - } - tm->year += x; - - tm->mon = x509_parse2_int(p + 2); - tm->day = x509_parse2_int(p + 4); - tm->hour = x509_parse2_int(p + 6); - tm->min = x509_parse2_int(p + 8); - tm->sec = x509_parse2_int(p + 10); - - return x509_date_is_valid(tm); -} - -/* - * Time ::= CHOICE { - * utcTime UTCTime, - * generalTime GeneralizedTime } - */ -int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end, - mbedtls_x509_time *tm) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len, year_len; - unsigned char tag; - - if ((end - *p) < 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - tag = **p; - - if (tag == MBEDTLS_ASN1_UTC_TIME) { - year_len = 2; - } else if (tag == MBEDTLS_ASN1_GENERALIZED_TIME) { - year_len = 4; - } else { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - (*p)++; - ret = mbedtls_asn1_get_len(p, end, &len); - - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret); - } - - /* len is 12 or 14 depending on year_len, plus optional trailing 'Z' */ - if (len != year_len + 10 && - !(len == year_len + 11 && (*p)[(len - 1)] == 'Z')) { - return MBEDTLS_ERR_X509_INVALID_DATE; - } - - (*p) += len; - return x509_parse_time(*p - len, tm, year_len); -} - -int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - int tag_type; - - if ((end - *p) < 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE, - MBEDTLS_ERR_ASN1_OUT_OF_DATA); - } - - tag_type = **p; - - if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret); - } - - sig->tag = tag_type; - sig->len = len; - sig->p = *p; - - *p += len; - - return 0; -} - -/* - * Get signature algorithm from alg OID and optional parameters - */ -int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, - void **sig_opts) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (*sig_opts != NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_oid_get_sig_alg(sig_oid, md_alg, pk_alg)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret); - } - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if (*pk_alg == MBEDTLS_PK_RSASSA_PSS) { - mbedtls_pk_rsassa_pss_options *pss_opts; - - pss_opts = mbedtls_calloc(1, sizeof(mbedtls_pk_rsassa_pss_options)); - if (pss_opts == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - ret = mbedtls_x509_get_rsassa_pss_params(sig_params, - md_alg, - &pss_opts->mgf1_hash_id, - &pss_opts->expected_salt_len); - if (ret != 0) { - mbedtls_free(pss_opts); - return ret; - } - - *sig_opts = (void *) pss_opts; - } else -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - { - /* Make sure parameters are absent or NULL */ - if ((sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0) || - sig_params->len != 0) { - return MBEDTLS_ERR_X509_INVALID_ALG; - } - } - - return 0; -} - -/* - * X.509 Extensions (No parsing of extensions, pointer should - * be either manually updated or extensions should be parsed!) - */ -int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - /* Extension structure use EXPLICIT tagging. That is, the actual - * `Extensions` structure is wrapped by a tag-length pair using - * the respective context-specific tag. */ - ret = mbedtls_asn1_get_tag(p, end, &ext->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag; - ext->p = *p; - end = *p + ext->len; - - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (end != *p + len) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -static char nibble_to_hex_digit(int i) -{ - return (i < 10) ? (i + '0') : (i - 10 + 'A'); -} - -/* - * Store the name in printable form into buf; no more - * than size characters will be written - */ -int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, j, n, asn1_len_size, asn1_tag_size, asn1_tag_len_buf_start; - /* 6 is enough as our asn1 write functions only write one byte for the tag and at most five bytes for the length*/ - unsigned char asn1_tag_len_buf[6]; - unsigned char *asn1_len_p; - unsigned char c, merge = 0; - const mbedtls_x509_name *name; - const char *short_name = NULL; - char lowbits, highbits; - char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; - int print_hexstring; - - memset(s, 0, sizeof(s)); - - name = dn; - p = buf; - n = size; - - while (name != NULL) { - if (!name->oid.p) { - name = name->next; - continue; - } - - if (name != dn) { - ret = mbedtls_snprintf(p, n, merge ? " + " : ", "); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - print_hexstring = (name->val.tag != MBEDTLS_ASN1_UTF8_STRING) && - (name->val.tag != MBEDTLS_ASN1_PRINTABLE_STRING) && - (name->val.tag != MBEDTLS_ASN1_IA5_STRING); - - if ((ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name)) == 0) { - ret = mbedtls_snprintf(p, n, "%s=", short_name); - } else { - if ((ret = mbedtls_oid_get_numeric_string(p, n, &name->oid)) > 0) { - n -= ret; - p += ret; - ret = mbedtls_snprintf(p, n, "="); - print_hexstring = 1; - } else if (ret == MBEDTLS_ERR_OID_BUF_TOO_SMALL) { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } else { - ret = mbedtls_snprintf(p, n, "\?\?="); - } - } - MBEDTLS_X509_SAFE_SNPRINTF; - - if (print_hexstring) { - s[0] = '#'; - - asn1_len_p = asn1_tag_len_buf + sizeof(asn1_tag_len_buf); - if ((ret = mbedtls_asn1_write_len(&asn1_len_p, asn1_tag_len_buf, name->val.len)) < 0) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - asn1_len_size = ret; - if ((ret = mbedtls_asn1_write_tag(&asn1_len_p, asn1_tag_len_buf, name->val.tag)) < 0) { - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - } - asn1_tag_size = ret; - asn1_tag_len_buf_start = sizeof(asn1_tag_len_buf) - asn1_len_size - asn1_tag_size; - for (i = 0, j = 1; i < asn1_len_size + asn1_tag_size; i++) { - if (j + 1 >= sizeof(s) - 1) { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - c = asn1_tag_len_buf[asn1_tag_len_buf_start+i]; - lowbits = (c & 0x0F); - highbits = c >> 4; - s[j++] = nibble_to_hex_digit(highbits); - s[j++] = nibble_to_hex_digit(lowbits); - } - for (i = 0; i < name->val.len; i++) { - if (j + 1 >= sizeof(s) - 1) { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - c = name->val.p[i]; - lowbits = (c & 0x0F); - highbits = c >> 4; - s[j++] = nibble_to_hex_digit(highbits); - s[j++] = nibble_to_hex_digit(lowbits); - } - } else { - for (i = 0, j = 0; i < name->val.len; i++, j++) { - if (j >= sizeof(s) - 1) { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - - c = name->val.p[i]; - // Special characters requiring escaping, RFC 4514 Section 2.4 - if (c == '\0') { - return MBEDTLS_ERR_X509_INVALID_NAME; - } else { - if (strchr(",=+<>;\"\\", c) || - ((i == 0) && strchr("# ", c)) || - ((i == name->val.len-1) && (c == ' '))) { - if (j + 1 >= sizeof(s) - 1) { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - s[j++] = '\\'; - } - } - if (c < 32 || c >= 127) { - if (j + 3 >= sizeof(s) - 1) { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - s[j++] = '\\'; - lowbits = (c & 0x0F); - highbits = c >> 4; - s[j++] = nibble_to_hex_digit(highbits); - s[j] = nibble_to_hex_digit(lowbits); - } else { - s[j] = c; - } - } - } - s[j] = '\0'; - ret = mbedtls_snprintf(p, n, "%s", s); - MBEDTLS_X509_SAFE_SNPRINTF; - - merge = name->next_merged; - name = name->next; - } - - return (int) (size - n); -} - -/* - * Store the serial in printable form into buf; no more - * than size characters will be written - */ -int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, n, nr; - char *p; - - p = buf; - n = size; - - nr = (serial->len <= 32) - ? serial->len : 28; - - for (i = 0; i < nr; i++) { - if (i == 0 && nr > 1 && serial->p[i] == 0x0) { - continue; - } - - ret = mbedtls_snprintf(p, n, "%02X%s", - serial->p[i], (i < nr - 1) ? ":" : ""); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - if (nr != serial->len) { - ret = mbedtls_snprintf(p, n, "...."); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return (int) (size - n); -} - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -/* - * Helper for writing signature algorithms - */ -int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - char *p = buf; - size_t n = size; - const char *desc = NULL; - - ret = mbedtls_oid_get_sig_alg_desc(sig_oid, &desc); - if (ret != 0) { - ret = mbedtls_snprintf(p, n, "???"); - } else { - ret = mbedtls_snprintf(p, n, "%s", desc); - } - MBEDTLS_X509_SAFE_SNPRINTF; - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if (pk_alg == MBEDTLS_PK_RSASSA_PSS) { - const mbedtls_pk_rsassa_pss_options *pss_opts; - - pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; - - const char *name = md_type_to_string(md_alg); - const char *mgf_name = md_type_to_string(pss_opts->mgf1_hash_id); - - ret = mbedtls_snprintf(p, n, " (%s, MGF1-%s, 0x%02X)", - name ? name : "???", - mgf_name ? mgf_name : "???", - (unsigned int) pss_opts->expected_salt_len); - MBEDTLS_X509_SAFE_SNPRINTF; - } -#else - ((void) pk_alg); - ((void) md_alg); - ((void) sig_opts); -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - return (int) (size - n); -} -#endif /* MBEDTLS_X509_REMOVE_INFO */ - -/* - * Helper for writing "RSA key size", "EC key size", etc - */ -int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name) -{ - char *p = buf; - size_t n = buf_size; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - ret = mbedtls_snprintf(p, n, "%s key size", name); - MBEDTLS_X509_SAFE_SNPRINTF; - - return 0; -} - -int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, - const mbedtls_x509_time *t2) -{ - int x; - - x = (((t1->year << 9) | (t1->mon << 5) | (t1->day)) - - ((t2->year << 9) | (t2->mon << 5) | (t2->day))); - if (x != 0) { - return x; - } - - x = (((t1->hour << 12) | (t1->min << 6) | (t1->sec)) - - ((t2->hour << 12) | (t2->min << 6) | (t2->sec))); - return x; -} - -#if defined(MBEDTLS_HAVE_TIME_DATE) -int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now) -{ - struct tm tm; - - if (mbedtls_platform_gmtime_r(&tt, &tm) == NULL) { - return -1; - } - - now->year = tm.tm_year + 1900; - now->mon = tm.tm_mon + 1; - now->day = tm.tm_mday; - now->hour = tm.tm_hour; - now->min = tm.tm_min; - now->sec = tm.tm_sec; - return 0; -} - -static int x509_get_current_time(mbedtls_x509_time *now) -{ - return mbedtls_x509_time_gmtime(mbedtls_time(NULL), now); -} - -int mbedtls_x509_time_is_past(const mbedtls_x509_time *to) -{ - mbedtls_x509_time now; - - if (x509_get_current_time(&now) != 0) { - return 1; - } - - return mbedtls_x509_time_cmp(to, &now) < 0; -} - -int mbedtls_x509_time_is_future(const mbedtls_x509_time *from) -{ - mbedtls_x509_time now; - - if (x509_get_current_time(&now) != 0) { - return 1; - } - - return mbedtls_x509_time_cmp(from, &now) > 0; -} - -#else /* MBEDTLS_HAVE_TIME_DATE */ - -int mbedtls_x509_time_is_past(const mbedtls_x509_time *to) -{ - ((void) to); - return 0; -} - -int mbedtls_x509_time_is_future(const mbedtls_x509_time *from) -{ - ((void) from); - return 0; -} -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -/* Common functions for parsing CRT and CSR. */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C) -/* - * OtherName ::= SEQUENCE { - * type-id OBJECT IDENTIFIER, - * value [0] EXPLICIT ANY DEFINED BY type-id } - * - * HardwareModuleName ::= SEQUENCE { - * hwType OBJECT IDENTIFIER, - * hwSerialNum OCTET STRING } - * - * NOTE: we currently only parse and use otherName of type HwModuleName, - * as defined in RFC 4108. - */ -static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name, - mbedtls_x509_san_other_name *other_name) -{ - int ret = 0; - size_t len; - unsigned char *p = subject_alt_name->p; - const unsigned char *end = p + subject_alt_name->len; - mbedtls_x509_buf cur_oid; - - if ((subject_alt_name->tag & - (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) != - (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) { - /* - * The given subject alternative name is not of type "othername". - */ - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - cur_oid.tag = MBEDTLS_ASN1_OID; - cur_oid.p = p; - cur_oid.len = len; - - /* - * Only HwModuleName is currently supported. - */ - if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) { - return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } - other_name->type_id = cur_oid; - - p += len; - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) != - 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (end != p + len) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (end != p + len) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID; - other_name->value.hardware_module_name.oid.p = p; - other_name->value.hardware_module_name.oid.len = len; - - p += len; - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING; - other_name->value.hardware_module_name.val.p = p; - other_name->value.hardware_module_name.val.len = len; - p += len; - if (p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - return 0; -} - -/* Check mbedtls_x509_get_subject_alt_name for detailed description. - * - * In some cases while parsing subject alternative names the sequence tag is optional - * (e.g. CertSerialNumber). This function is designed to handle such case. - */ -int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t tag_len; - mbedtls_asn1_sequence *cur = subject_alt_name; - - while (*p < end) { - mbedtls_x509_subject_alternative_name tmp_san_name; - mbedtls_x509_buf tmp_san_buf; - memset(&tmp_san_name, 0, sizeof(tmp_san_name)); - - tmp_san_buf.tag = **p; - (*p)++; - - if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - tmp_san_buf.p = *p; - tmp_san_buf.len = tag_len; - - if ((tmp_san_buf.tag & MBEDTLS_ASN1_TAG_CLASS_MASK) != - MBEDTLS_ASN1_CONTEXT_SPECIFIC) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - - /* - * Check that the SAN is structured correctly by parsing it. - * The SAN structure is discarded afterwards. - */ - ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &tmp_san_name); - /* - * In case the extension is malformed, return an error, - * and clear the allocated sequences. - */ - if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) { - mbedtls_asn1_sequence_free(subject_alt_name->next); - subject_alt_name->next = NULL; - return ret; - } - - mbedtls_x509_free_subject_alt_name(&tmp_san_name); - /* Allocate and assign next pointer */ - if (cur->buf.p != NULL) { - if (cur->next != NULL) { - return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; - } - - cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); - - if (cur->next == NULL) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_ALLOC_FAILED); - } - - cur = cur->next; - } - - cur->buf = tmp_san_buf; - *p += tmp_san_buf.len; - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * SubjectAltName ::= GeneralNames - * - * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - * - * GeneralName ::= CHOICE { - * otherName [0] OtherName, - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * iPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER } - * - * OtherName ::= SEQUENCE { - * type-id OBJECT IDENTIFIER, - * value [0] EXPLICIT ANY DEFINED BY type-id } - * - * EDIPartyName ::= SEQUENCE { - * nameAssigner [0] DirectoryString OPTIONAL, - * partyName [1] DirectoryString } - * - * We list all types, but use the following GeneralName types from RFC 5280: - * "dnsName", "uniformResourceIdentifier" and "hardware_module_name" - * of type "otherName", as defined in RFC 4108. - */ -int mbedtls_x509_get_subject_alt_name(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - /* Get main sequence tag */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (*p + len != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return mbedtls_x509_get_subject_alt_name_ext(p, end, subject_alt_name); -} - -int mbedtls_x509_get_ns_cert_type(unsigned char **p, - const unsigned char *end, - unsigned char *ns_cert_type) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_x509_bitstring bs = { 0, 0, NULL }; - - if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - /* A bitstring with no flags set is still technically valid, as it will mean - that the certificate has no designated purpose at the time of creation. */ - if (bs.len == 0) { - *ns_cert_type = 0; - return 0; - } - - if (bs.len != 1) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_INVALID_LENGTH); - } - - /* Get actual bitstring */ - *ns_cert_type = *bs.p; - return 0; -} - -int mbedtls_x509_get_key_usage(unsigned char **p, - const unsigned char *end, - unsigned int *key_usage) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - mbedtls_x509_bitstring bs = { 0, 0, NULL }; - - if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - /* A bitstring with no flags set is still technically valid, as it will mean - that the certificate has no designated purpose at the time of creation. */ - if (bs.len == 0) { - *key_usage = 0; - return 0; - } - - /* Get actual bitstring */ - *key_usage = 0; - for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) { - *key_usage |= (unsigned int) bs.p[i] << (8*i); - } - - return 0; -} - -int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, - mbedtls_x509_subject_alternative_name *san) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - switch (san_buf->tag & - (MBEDTLS_ASN1_TAG_CLASS_MASK | - MBEDTLS_ASN1_TAG_VALUE_MASK)) { - /* - * otherName - */ - case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME): - { - mbedtls_x509_san_other_name other_name; - - ret = x509_get_other_name(san_buf, &other_name); - if (ret != 0) { - return ret; - } - - memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); - san->type = MBEDTLS_X509_SAN_OTHER_NAME; - memcpy(&san->san.other_name, - &other_name, sizeof(other_name)); - - } - break; - /* - * uniformResourceIdentifier - */ - case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER): - { - memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); - san->type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER; - - memcpy(&san->san.unstructured_name, - san_buf, sizeof(*san_buf)); - - } - break; - /* - * dNSName - */ - case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME): - { - memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); - san->type = MBEDTLS_X509_SAN_DNS_NAME; - - memcpy(&san->san.unstructured_name, - san_buf, sizeof(*san_buf)); - } - break; - /* - * IP address - */ - case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_IP_ADDRESS): - { - memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); - san->type = MBEDTLS_X509_SAN_IP_ADDRESS; - // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported - if (san_buf->len == 4 || san_buf->len == 16) { - memcpy(&san->san.unstructured_name, - san_buf, sizeof(*san_buf)); - } else { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - } - break; - /* - * rfc822Name - */ - case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME): - { - memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); - san->type = MBEDTLS_X509_SAN_RFC822_NAME; - memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf)); - } - break; - /* - * directoryName - */ - case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DIRECTORY_NAME): - { - size_t name_len; - unsigned char *p = san_buf->p; - memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); - san->type = MBEDTLS_X509_SAN_DIRECTORY_NAME; - - ret = mbedtls_asn1_get_tag(&p, p + san_buf->len, &name_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - - if (ret != 0) { - return ret; - } - - if ((ret = mbedtls_x509_get_name(&p, p + name_len, - &san->san.directory_name)) != 0) { - return ret; - } - } - break; - /* - * Type not supported - */ - default: - return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } - return 0; -} - -void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san) -{ - if (san->type == MBEDTLS_X509_SAN_DIRECTORY_NAME) { - mbedtls_asn1_free_named_data_list_shallow(san->san.directory_name.next); - } -} - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size, - const mbedtls_x509_sequence - *subject_alt_name, - const char *prefix) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - size_t n = *size; - char *p = *buf; - const mbedtls_x509_sequence *cur = subject_alt_name; - mbedtls_x509_subject_alternative_name san; - int parse_ret; - - while (cur != NULL) { - memset(&san, 0, sizeof(san)); - parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san); - if (parse_ret != 0) { - if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) { - ret = mbedtls_snprintf(p, n, "\n%s ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - } else { - ret = mbedtls_snprintf(p, n, "\n%s ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - } - cur = cur->next; - continue; - } - - switch (san.type) { - /* - * otherName - */ - case MBEDTLS_X509_SAN_OTHER_NAME: - { - mbedtls_x509_san_other_name *other_name = &san.san.other_name; - - ret = mbedtls_snprintf(p, n, "\n%s otherName :", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, - &other_name->type_id) == 0) { - ret = mbedtls_snprintf(p, n, "\n%s hardware module name :", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = - mbedtls_snprintf(p, n, "\n%s hardware type : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_oid_get_numeric_string(p, - n, - &other_name->value.hardware_module_name.oid); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = - mbedtls_snprintf(p, n, "\n%s hardware serial number : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) { - ret = mbedtls_snprintf(p, - n, - "%02X", - other_name->value.hardware_module_name.val.p[i]); - MBEDTLS_X509_SAFE_SNPRINTF; - } - }/* MBEDTLS_OID_ON_HW_MODULE_NAME */ - } - break; - /* - * uniformResourceIdentifier - */ - case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: - { - ret = mbedtls_snprintf(p, n, "\n%s uniformResourceIdentifier : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - if (san.san.unstructured_name.len >= n) { - if (n > 0) { - *p = '\0'; - } - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - - memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len); - p += san.san.unstructured_name.len; - n -= san.san.unstructured_name.len; - } - break; - /* - * dNSName - * RFC822 Name - */ - case MBEDTLS_X509_SAN_DNS_NAME: - case MBEDTLS_X509_SAN_RFC822_NAME: - { - const char *dns_name = "dNSName"; - const char *rfc822_name = "rfc822Name"; - - ret = mbedtls_snprintf(p, n, - "\n%s %s : ", - prefix, - san.type == - MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name); - MBEDTLS_X509_SAFE_SNPRINTF; - if (san.san.unstructured_name.len >= n) { - if (n > 0) { - *p = '\0'; - } - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - - memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len); - p += san.san.unstructured_name.len; - n -= san.san.unstructured_name.len; - } - break; - /* - * iPAddress - */ - case MBEDTLS_X509_SAN_IP_ADDRESS: - { - ret = mbedtls_snprintf(p, n, "\n%s %s : ", - prefix, "iPAddress"); - MBEDTLS_X509_SAFE_SNPRINTF; - if (san.san.unstructured_name.len >= n) { - if (n > 0) { - *p = '\0'; - } - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - - unsigned char *ip = san.san.unstructured_name.p; - // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported - if (san.san.unstructured_name.len == 4) { - ret = mbedtls_snprintf(p, n, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); - MBEDTLS_X509_SAFE_SNPRINTF; - } else if (san.san.unstructured_name.len == 16) { - ret = mbedtls_snprintf(p, n, - "%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X", - ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], - ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], - ip[14], ip[15]); - MBEDTLS_X509_SAFE_SNPRINTF; - } else { - if (n > 0) { - *p = '\0'; - } - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - } - break; - /* - * directoryName - */ - case MBEDTLS_X509_SAN_DIRECTORY_NAME: - { - ret = mbedtls_snprintf(p, n, "\n%s directoryName : ", prefix); - if (ret < 0 || (size_t) ret >= n) { - mbedtls_x509_free_subject_alt_name(&san); - } - - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets(p, n, &san.san.directory_name); - - if (ret < 0) { - mbedtls_x509_free_subject_alt_name(&san); - if (n > 0) { - *p = '\0'; - } - return ret; - } - - p += ret; - n -= ret; - } - break; - /* - * Type not supported, skip item. - */ - default: - ret = mbedtls_snprintf(p, n, "\n%s ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - break; - } - - /* So far memory is freed only in the case of directoryName - * parsing succeeding, as mbedtls_x509_get_name allocates memory. */ - mbedtls_x509_free_subject_alt_name(&san); - cur = cur->next; - } - - *p = '\0'; - - *size = n; - *buf = p; - - return 0; -} - -#define PRINT_ITEM(i) \ - do { \ - ret = mbedtls_snprintf(p, n, "%s" i, sep); \ - MBEDTLS_X509_SAFE_SNPRINTF; \ - sep = ", "; \ - } while (0) - -#define CERT_TYPE(type, name) \ - do { \ - if (ns_cert_type & (type)) { \ - PRINT_ITEM(name); \ - } \ - } while (0) - -int mbedtls_x509_info_cert_type(char **buf, size_t *size, - unsigned char ns_cert_type) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n = *size; - char *p = *buf; - const char *sep = ""; - - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client"); - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server"); - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email"); - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing"); - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved"); - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA"); - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA"); - CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA"); - - *size = n; - *buf = p; - - return 0; -} - -#define KEY_USAGE(code, name) \ - do { \ - if ((key_usage) & (code)) { \ - PRINT_ITEM(name); \ - } \ - } while (0) - -int mbedtls_x509_info_key_usage(char **buf, size_t *size, - unsigned int key_usage) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n = *size; - char *p = *buf; - const char *sep = ""; - - KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature"); - KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation"); - KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment"); - KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment"); - KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement"); - KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign"); - KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign"); - KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only"); - KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only"); - - *size = n; - *buf = p; - - return 0; -} -#endif /* MBEDTLS_X509_REMOVE_INFO */ -#endif /* MBEDTLS_X509_CRT_PARSE_C || MBEDTLS_X509_CSR_PARSE_C */ -#endif /* MBEDTLS_X509_USE_C */ diff --git a/vendor/mbedtls/library/x509_create.c b/vendor/mbedtls/library/x509_create.c deleted file mode 100644 index fc23fb865..000000000 --- a/vendor/mbedtls/library/x509_create.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * X.509 base functions for creating certificates / CSRs - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "common.h" - -#if defined(MBEDTLS_X509_CREATE_C) - -#include "x509_internal.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" - -#include - -#include "mbedtls/platform.h" - -#include "mbedtls/asn1.h" - -/* Structure linking OIDs for X.509 DN AttributeTypes to their - * string representations and default string encodings used by Mbed TLS. */ -typedef struct { - const char *name; /* String representation of AttributeType, e.g. - * "CN" or "emailAddress". */ - size_t name_len; /* Length of 'name', without trailing 0 byte. */ - const char *oid; /* String representation of OID of AttributeType, - * as per RFC 5280, Appendix A.1. encoded as per - * X.690 */ - int default_tag; /* The default character encoding used for the - * given attribute type, e.g. - * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */ -} x509_attr_descriptor_t; - -#define ADD_STRLEN(s) s, sizeof(s) - 1 - -/* X.509 DN attributes from RFC 5280, Appendix A.1. */ -static const x509_attr_descriptor_t x509_attrs[] = -{ - { ADD_STRLEN("CN"), - MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("commonName"), - MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("C"), - MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN("countryName"), - MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN("O"), - MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("organizationName"), - MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("L"), - MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("locality"), - MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("R"), - MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN("OU"), - MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("organizationalUnitName"), - MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("ST"), - MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("stateOrProvinceName"), - MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("emailAddress"), - MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN("serialNumber"), - MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN("postalAddress"), - MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN("postalCode"), - MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN("dnQualifier"), - MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING }, - { ADD_STRLEN("title"), - MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("surName"), - MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("SN"), - MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("givenName"), - MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("GN"), - MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("initials"), - MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("pseudonym"), - MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("generationQualifier"), - MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING }, - { ADD_STRLEN("domainComponent"), - MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, - { ADD_STRLEN("DC"), - MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING }, - { NULL, 0, NULL, MBEDTLS_ASN1_NULL } -}; - -static const x509_attr_descriptor_t *x509_attr_descr_from_name(const char *name, size_t name_len) -{ - const x509_attr_descriptor_t *cur; - - for (cur = x509_attrs; cur->name != NULL; cur++) { - if (cur->name_len == name_len && - strncmp(cur->name, name, name_len) == 0) { - break; - } - } - - if (cur->name == NULL) { - return NULL; - } - - return cur; -} - -static int hex_to_int(char c) -{ - return ('0' <= c && c <= '9') ? (c - '0') : - ('a' <= c && c <= 'f') ? (c - 'a' + 10) : - ('A' <= c && c <= 'F') ? (c - 'A' + 10) : -1; -} - -static int hexpair_to_int(const char *hexpair) -{ - int n1 = hex_to_int(*hexpair); - int n2 = hex_to_int(*(hexpair + 1)); - - if (n1 != -1 && n2 != -1) { - return (n1 << 4) | n2; - } else { - return -1; - } -} - -static int parse_attribute_value_string(const char *s, - int len, - unsigned char *data, - size_t *data_len) -{ - const char *c; - const char *end = s + len; - unsigned char *d = data; - int n; - - for (c = s; c < end; c++) { - if (*c == '\\') { - c++; - - /* Check for valid escaped characters as per RFC 4514 Section 3 */ - if (c + 1 < end && (n = hexpair_to_int(c)) != -1) { - if (n == 0) { - return MBEDTLS_ERR_X509_INVALID_NAME; - } - *(d++) = n; - c++; - } else if (c < end && strchr(" ,=+<>#;\"\\", *c)) { - *(d++) = *c; - } else { - return MBEDTLS_ERR_X509_INVALID_NAME; - } - } else { - *(d++) = *c; - } - - if (d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE) { - return MBEDTLS_ERR_X509_INVALID_NAME; - } - } - *data_len = (size_t) (d - data); - return 0; -} - -/** Parse a hexstring containing a DER-encoded string. - * - * \param s A string of \p len bytes hexadecimal digits. - * \param len Number of bytes to read from \p s. - * \param data Output buffer of size \p data_size. - * On success, it contains the payload that's DER-encoded - * in the input (content without the tag and length). - * If the DER tag is a string tag, the payload is guaranteed - * not to contain null bytes. - * \param data_size Length of the \p data buffer. - * \param data_len On success, the length of the parsed string. - * It is guaranteed to be less than - * #MBEDTLS_X509_MAX_DN_NAME_SIZE. - * \param tag The ASN.1 tag that the payload in \p data is encoded in. - * - * \retval 0 on success. - * \retval #MBEDTLS_ERR_X509_INVALID_NAME if \p s does not contain - * a valid hexstring, - * or if the decoded hexstring is not valid DER, - * or if the payload does not fit in \p data, - * or if the payload is more than - * #MBEDTLS_X509_MAX_DN_NAME_SIZE bytes, - * of if \p *tag is an ASN.1 string tag and the payload - * contains a null byte. - * \retval #MBEDTLS_ERR_X509_ALLOC_FAILED on low memory. - */ -static int parse_attribute_value_hex_der_encoded(const char *s, - size_t len, - unsigned char *data, - size_t data_size, - size_t *data_len, - int *tag) -{ - /* Step 1: preliminary length checks. */ - /* Each byte is encoded by exactly two hexadecimal digits. */ - if (len % 2 != 0) { - /* Odd number of hex digits */ - return MBEDTLS_ERR_X509_INVALID_NAME; - } - size_t const der_length = len / 2; - if (der_length > MBEDTLS_X509_MAX_DN_NAME_SIZE + 4) { - /* The payload would be more than MBEDTLS_X509_MAX_DN_NAME_SIZE - * (after subtracting the ASN.1 tag and length). Reject this early - * to avoid allocating a large intermediate buffer. */ - return MBEDTLS_ERR_X509_INVALID_NAME; - } - if (der_length < 1) { - /* Avoid empty-buffer shenanigans. A valid DER encoding is never - * empty. */ - return MBEDTLS_ERR_X509_INVALID_NAME; - } - - /* Step 2: Decode the hex string into an intermediate buffer. */ - unsigned char *der = mbedtls_calloc(1, der_length); - if (der == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - /* Beyond this point, der needs to be freed on exit. */ - for (size_t i = 0; i < der_length; i++) { - int c = hexpair_to_int(s + 2 * i); - if (c < 0) { - goto error; - } - der[i] = c; - } - - /* Step 3: decode the DER. */ - /* We've checked that der_length >= 1 above. */ - *tag = der[0]; - { - unsigned char *p = der + 1; - if (mbedtls_asn1_get_len(&p, der + der_length, data_len) != 0) { - goto error; - } - /* Now p points to the first byte of the payload inside der, - * and *data_len is the length of the payload. */ - - /* Step 4: payload validation */ - if (*data_len > MBEDTLS_X509_MAX_DN_NAME_SIZE) { - goto error; - } - /* Strings must not contain null bytes. */ - if (MBEDTLS_ASN1_IS_STRING_TAG(*tag)) { - for (size_t i = 0; i < *data_len; i++) { - if (p[i] == 0) { - goto error; - } - } - } - - /* Step 5: output the payload. */ - if (*data_len > data_size) { - goto error; - } - memcpy(data, p, *data_len); - } - mbedtls_free(der); - - return 0; - -error: - mbedtls_free(der); - return MBEDTLS_ERR_X509_INVALID_NAME; -} - -int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name) -{ - int ret = MBEDTLS_ERR_X509_INVALID_NAME; - int parse_ret = 0; - const char *s = name, *c = s; - const char *end = s + strlen(s); - mbedtls_asn1_buf oid = { .p = NULL, .len = 0, .tag = MBEDTLS_ASN1_NULL }; - const x509_attr_descriptor_t *attr_descr = NULL; - int in_attr_type = 1; - int tag; - int numericoid = 0; - unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; - size_t data_len = 0; - - /* Ensure the output parameter is not already populated. - * (If it were, overwriting it would likely cause a memory leak.) - */ - if (*head != NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - while (c <= end) { - if (in_attr_type && *c == '=') { - if ((attr_descr = x509_attr_descr_from_name(s, (size_t) (c - s))) == NULL) { - if ((mbedtls_oid_from_numeric_string(&oid, s, (size_t) (c - s))) != 0) { - return MBEDTLS_ERR_X509_INVALID_NAME; - } else { - numericoid = 1; - } - } else { - oid.len = strlen(attr_descr->oid); - oid.p = mbedtls_calloc(1, oid.len); - if (oid.p == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - memcpy(oid.p, attr_descr->oid, oid.len); - numericoid = 0; - } - - s = c + 1; - in_attr_type = 0; - } - - if (!in_attr_type && ((*c == ',' && *(c-1) != '\\') || c == end)) { - if (s == c) { - mbedtls_free(oid.p); - return MBEDTLS_ERR_X509_INVALID_NAME; - } else if (*s == '#') { - /* We know that c >= s (loop invariant) and c != s (in this - * else branch), hence c - s - 1 >= 0. */ - parse_ret = parse_attribute_value_hex_der_encoded( - s + 1, (size_t) (c - s) - 1, - data, sizeof(data), &data_len, &tag); - if (parse_ret != 0) { - mbedtls_free(oid.p); - return parse_ret; - } - } else { - if (numericoid) { - mbedtls_free(oid.p); - return MBEDTLS_ERR_X509_INVALID_NAME; - } else { - if ((parse_ret = - parse_attribute_value_string(s, (int) (c - s), data, - &data_len)) != 0) { - mbedtls_free(oid.p); - return parse_ret; - } - tag = attr_descr->default_tag; - } - } - - mbedtls_asn1_named_data *cur = - mbedtls_asn1_store_named_data(head, (char *) oid.p, oid.len, - (unsigned char *) data, - data_len); - mbedtls_free(oid.p); - oid.p = NULL; - if (cur == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - // set tagType - cur->val.tag = tag; - - while (c < end && *(c + 1) == ' ') { - c++; - } - - s = c + 1; - in_attr_type = 1; - - /* Successfully parsed one name, update ret to success */ - ret = 0; - } - c++; - } - if (oid.p != NULL) { - mbedtls_free(oid.p); - } - return ret; -} - -/* The first byte of the value in the mbedtls_asn1_named_data structure is reserved - * to store the critical boolean for us - */ -int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, - int critical, const unsigned char *val, size_t val_len) -{ - mbedtls_asn1_named_data *cur; - - if (val_len > (SIZE_MAX - 1)) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - if ((cur = mbedtls_asn1_store_named_data(head, oid, oid_len, - NULL, val_len + 1)) == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - cur->val.p[0] = critical; - memcpy(cur->val.p + 1, val, val_len); - - return 0; -} - -/* - * RelativeDistinguishedName ::= - * SET OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - */ -static int x509_write_name(unsigned char **p, - unsigned char *start, - mbedtls_asn1_named_data *cur_name) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - const char *oid = (const char *) cur_name->oid.p; - size_t oid_len = cur_name->oid.len; - const unsigned char *name = cur_name->val.p; - size_t name_len = cur_name->val.len; - - // Write correct string tag and value - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tagged_string(p, start, - cur_name->val.tag, - (const char *) name, - name_len)); - // Write OID - // - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, - oid_len)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SET)); - - return (int) len; -} - -int mbedtls_x509_write_names(unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - mbedtls_asn1_named_data *cur = first; - - while (cur != NULL) { - MBEDTLS_ASN1_CHK_ADD(len, x509_write_name(p, start, cur)); - cur = cur->next; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} - -int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - unsigned char *sig, size_t size, - mbedtls_pk_type_t pk_alg) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int write_null_par; - size_t len = 0; - - if (*p < start || (size_t) (*p - start) < size) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - len = size; - (*p) -= len; - memcpy(*p, sig, len); - - if (*p - start < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - - *--(*p) = 0; - len += 1; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_BIT_STRING)); - - // Write OID - // - if (pk_alg == MBEDTLS_PK_ECDSA) { - /* - * The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature - * algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and - * https://www.rfc-editor.org/rfc/rfc5758#section-3. - */ - write_null_par = 0; - } else { - write_null_par = 1; - } - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, - 0, write_null_par)); - - return (int) len; -} - -static int x509_write_extension(unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *ext) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, ext->val.p + 1, - ext->val.len - 1)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, ext->val.len - 1)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_OCTET_STRING)); - - if (ext->val.p[0] != 0) { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_bool(p, start, 1)); - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, ext->oid.p, - ext->oid.len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, ext->oid.len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_OID)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} - -/* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING - * -- contains the DER encoding of an ASN.1 value - * -- corresponding to the extension type identified - * -- by extnID - * } - */ -int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - mbedtls_asn1_named_data *cur_ext = first; - - while (cur_ext != NULL) { - MBEDTLS_ASN1_CHK_ADD(len, x509_write_extension(p, start, cur_ext)); - cur_ext = cur_ext->next; - } - - return (int) len; -} - -#endif /* MBEDTLS_X509_CREATE_C */ diff --git a/vendor/mbedtls/library/x509_crl.c b/vendor/mbedtls/library/x509_crl.c deleted file mode 100644 index 7901992e2..000000000 --- a/vendor/mbedtls/library/x509_crl.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * X.509 Certificate Revocation List (CRL) parsing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - -#include "mbedtls/x509_crl.h" -#include "x509_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_HAVE_TIME) -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#include -#else -#include -#endif -#endif - -#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) -#include -#endif - -/* - * Version ::= INTEGER { v1(0), v2(1) } - */ -static int x509_crl_get_version(unsigned char **p, - const unsigned char *end, - int *ver) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - *ver = 0; - return 0; - } - - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret); - } - - return 0; -} - -/* - * X.509 CRL v2 extensions - * - * We currently don't parse any extension's content, but we do check that the - * list of extensions is well-formed and abort on critical extensions (that - * are unsupported as we don't support any extension so far) - */ -static int x509_get_crl_ext(unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *ext) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (*p == end) { - return 0; - } - - /* - * crlExtensions [0] EXPLICIT Extensions OPTIONAL - * -- if present, version MUST be v2 - */ - if ((ret = mbedtls_x509_get_ext(p, end, ext, 0)) != 0) { - return ret; - } - - end = ext->p + ext->len; - - while (*p < end) { - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - int is_critical = 0; - const unsigned char *end_ext_data; - size_t len; - - /* Get enclosing sequence tag */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - end_ext_data = *p + len; - - /* Get OID (currently ignored) */ - if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len, - MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - *p += len; - - /* Get optional critical */ - if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, - &is_critical)) != 0 && - (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - /* Data should be octet string type */ - if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - /* Ignore data so far and just check its length */ - *p += len; - if (*p != end_ext_data) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* Abort on (unsupported) critical extensions */ - if (is_critical) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * X.509 CRL v2 entry extensions (no extensions parsed yet.) - */ -static int x509_get_crl_entry_ext(unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *ext) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - /* OPTIONAL */ - if (end <= *p) { - return 0; - } - - ext->tag = **p; - ext->p = *p; - - /* - * Get CRL-entry extension sequence header - * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2 - */ - if ((ret = mbedtls_asn1_get_tag(p, end, &ext->len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - ext->p = NULL; - return 0; - } - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - end = *p + ext->len; - - if (end != *p + ext->len) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - while (*p < end) { - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - *p += len; - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * X.509 CRL Entries - */ -static int x509_get_entries(unsigned char **p, - const unsigned char *end, - mbedtls_x509_crl_entry *entry) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t entry_len; - mbedtls_x509_crl_entry *cur_entry = entry; - - if (*p == end) { - return 0; - } - - if ((ret = mbedtls_asn1_get_tag(p, end, &entry_len, - MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return 0; - } - - return ret; - } - - end = *p + entry_len; - - while (*p < end) { - size_t len2; - const unsigned char *end2; - - cur_entry->raw.tag = **p; - if ((ret = mbedtls_asn1_get_tag(p, end, &len2, - MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) { - return ret; - } - - cur_entry->raw.p = *p; - cur_entry->raw.len = len2; - end2 = *p + len2; - - if ((ret = mbedtls_x509_get_serial(p, end2, &cur_entry->serial)) != 0) { - return ret; - } - - if ((ret = mbedtls_x509_get_time(p, end2, - &cur_entry->revocation_date)) != 0) { - return ret; - } - - if ((ret = x509_get_crl_entry_ext(p, end2, - &cur_entry->entry_ext)) != 0) { - return ret; - } - - if (*p < end) { - cur_entry->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl_entry)); - - if (cur_entry->next == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - cur_entry = cur_entry->next; - } - } - - return 0; -} - -/* - * Parse one CRLs in DER format and append it to the chained list - */ -int mbedtls_x509_crl_parse_der(mbedtls_x509_crl *chain, - const unsigned char *buf, size_t buflen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - unsigned char *p = NULL, *end = NULL; - mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; - mbedtls_x509_crl *crl = chain; - - /* - * Check for valid input - */ - if (crl == NULL || buf == NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - memset(&sig_params1, 0, sizeof(mbedtls_x509_buf)); - memset(&sig_params2, 0, sizeof(mbedtls_x509_buf)); - memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf)); - - /* - * Add new CRL on the end of the chain if needed. - */ - while (crl->version != 0 && crl->next != NULL) { - crl = crl->next; - } - - if (crl->version != 0 && crl->next == NULL) { - crl->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl)); - - if (crl->next == NULL) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - mbedtls_x509_crl_init(crl->next); - crl = crl->next; - } - - /* - * Copy raw DER-encoded CRL - */ - if (buflen == 0) { - return MBEDTLS_ERR_X509_INVALID_FORMAT; - } - - p = mbedtls_calloc(1, buflen); - if (p == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - memcpy(p, buf, buflen); - - crl->raw.p = p; - crl->raw.len = buflen; - - end = p + buflen; - - /* - * CertificateList ::= SEQUENCE { - * tbsCertList TBSCertList, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERR_X509_INVALID_FORMAT; - } - - if (len != (size_t) (end - p)) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* - * TBSCertList ::= SEQUENCE { - */ - crl->tbs.p = p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - end = p + len; - crl->tbs.len = (size_t) (end - crl->tbs.p); - - /* - * Version ::= INTEGER OPTIONAL { v1(0), v2(1) } - * -- if present, MUST be v2 - * - * signature AlgorithmIdentifier - */ - if ((ret = x509_crl_get_version(&p, end, &crl->version)) != 0 || - (ret = mbedtls_x509_get_alg(&p, end, &crl->sig_oid, &sig_params1)) != 0) { - mbedtls_x509_crl_free(crl); - return ret; - } - - if (crl->version < 0 || crl->version > 1) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERR_X509_UNKNOWN_VERSION; - } - - crl->version++; - - if ((ret = mbedtls_x509_get_sig_alg(&crl->sig_oid, &sig_params1, - &crl->sig_md, &crl->sig_pk, - &crl->sig_opts)) != 0) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG; - } - - /* - * issuer Name - */ - crl->issuer_raw.p = p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - if ((ret = mbedtls_x509_get_name(&p, p + len, &crl->issuer)) != 0) { - mbedtls_x509_crl_free(crl); - return ret; - } - - crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p); - - /* - * thisUpdate Time - * nextUpdate Time OPTIONAL - */ - if ((ret = mbedtls_x509_get_time(&p, end, &crl->this_update)) != 0) { - mbedtls_x509_crl_free(crl); - return ret; - } - - if ((ret = mbedtls_x509_get_time(&p, end, &crl->next_update)) != 0) { - if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) && - ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, - MBEDTLS_ERR_ASN1_OUT_OF_DATA))) { - mbedtls_x509_crl_free(crl); - return ret; - } - } - - /* - * revokedCertificates SEQUENCE OF SEQUENCE { - * userCertificate CertificateSerialNumber, - * revocationDate Time, - * crlEntryExtensions Extensions OPTIONAL - * -- if present, MUST be v2 - * } OPTIONAL - */ - if ((ret = x509_get_entries(&p, end, &crl->entry)) != 0) { - mbedtls_x509_crl_free(crl); - return ret; - } - - /* - * crlExtensions EXPLICIT Extensions OPTIONAL - * -- if present, MUST be v2 - */ - if (crl->version == 2) { - ret = x509_get_crl_ext(&p, end, &crl->crl_ext); - - if (ret != 0) { - mbedtls_x509_crl_free(crl); - return ret; - } - } - - if (p != end) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - end = crl->raw.p + crl->raw.len; - - /* - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - */ - if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) { - mbedtls_x509_crl_free(crl); - return ret; - } - - if (crl->sig_oid.len != sig_oid2.len || - memcmp(crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len) != 0 || - sig_params1.len != sig_params2.len || - (sig_params1.len != 0 && - memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERR_X509_SIG_MISMATCH; - } - - if ((ret = mbedtls_x509_get_sig(&p, end, &crl->sig)) != 0) { - mbedtls_x509_crl_free(crl); - return ret; - } - - if (p != end) { - mbedtls_x509_crl_free(crl); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Parse one or more CRLs and add them to the chained list - */ -int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen) -{ -#if defined(MBEDTLS_PEM_PARSE_C) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t use_len = 0; - mbedtls_pem_context pem; - int is_pem = 0; - - if (chain == NULL || buf == NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - do { - mbedtls_pem_init(&pem); - - // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated - // string - if (buflen == 0 || buf[buflen - 1] != '\0') { - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - } else { - ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN X509 CRL-----", - "-----END X509 CRL-----", - buf, NULL, 0, &use_len); - } - - if (ret == 0) { - /* - * Was PEM encoded - */ - is_pem = 1; - - buflen -= use_len; - buf += use_len; - - if ((ret = mbedtls_x509_crl_parse_der(chain, - pem.buf, pem.buflen)) != 0) { - mbedtls_pem_free(&pem); - return ret; - } - } else if (is_pem) { - mbedtls_pem_free(&pem); - return ret; - } - - mbedtls_pem_free(&pem); - } - /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte. - * And a valid CRL cannot be less than 1 byte anyway. */ - while (is_pem && buflen > 1); - - if (is_pem) { - return 0; - } else -#endif /* MBEDTLS_PEM_PARSE_C */ - return mbedtls_x509_crl_parse_der(chain, buf, buflen); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load one or more CRLs and add them to the chained list - */ -int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - unsigned char *buf; - - if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) { - return ret; - } - - ret = mbedtls_x509_crl_parse(chain, buf, n); - - mbedtls_zeroize_and_free(buf, n); - - return ret; -} -#endif /* MBEDTLS_FS_IO */ - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -/* - * Return an informational string about the certificate. - */ -#define BEFORE_COLON 14 -#define BC "14" -/* - * Return an informational string about the CRL. - */ -int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix, - const mbedtls_x509_crl *crl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - char *p; - const mbedtls_x509_crl_entry *entry; - - p = buf; - n = size; - - ret = mbedtls_snprintf(p, n, "%sCRL version : %d", - prefix, crl->version); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets(p, n, &crl->issuer); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%sthis update : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crl->this_update.year, crl->this_update.mon, - crl->this_update.day, crl->this_update.hour, - crl->this_update.min, crl->this_update.sec); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%snext update : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crl->next_update.year, crl->next_update.mon, - crl->next_update.day, crl->next_update.hour, - crl->next_update.min, crl->next_update.sec); - MBEDTLS_X509_SAFE_SNPRINTF; - - entry = &crl->entry; - - ret = mbedtls_snprintf(p, n, "\n%sRevoked certificates:", - prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - while (entry != NULL && entry->raw.len != 0) { - ret = mbedtls_snprintf(p, n, "\n%sserial number: ", - prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_serial_gets(p, n, &entry->serial); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, " revocation date: " \ - "%04d-%02d-%02d %02d:%02d:%02d", - entry->revocation_date.year, entry->revocation_date.mon, - entry->revocation_date.day, entry->revocation_date.hour, - entry->revocation_date.min, entry->revocation_date.sec); - MBEDTLS_X509_SAFE_SNPRINTF; - - entry = entry->next; - } - - ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_sig_alg_gets(p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md, - crl->sig_opts); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n"); - MBEDTLS_X509_SAFE_SNPRINTF; - - return (int) (size - n); -} -#endif /* MBEDTLS_X509_REMOVE_INFO */ - -/* - * Initialize a CRL chain - */ -void mbedtls_x509_crl_init(mbedtls_x509_crl *crl) -{ - memset(crl, 0, sizeof(mbedtls_x509_crl)); -} - -/* - * Unallocate all CRL data - */ -void mbedtls_x509_crl_free(mbedtls_x509_crl *crl) -{ - mbedtls_x509_crl *crl_cur = crl; - mbedtls_x509_crl *crl_prv; - mbedtls_x509_crl_entry *entry_cur; - mbedtls_x509_crl_entry *entry_prv; - - while (crl_cur != NULL) { -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free(crl_cur->sig_opts); -#endif - - mbedtls_asn1_free_named_data_list_shallow(crl_cur->issuer.next); - - entry_cur = crl_cur->entry.next; - while (entry_cur != NULL) { - entry_prv = entry_cur; - entry_cur = entry_cur->next; - mbedtls_zeroize_and_free(entry_prv, - sizeof(mbedtls_x509_crl_entry)); - } - - if (crl_cur->raw.p != NULL) { - mbedtls_zeroize_and_free(crl_cur->raw.p, crl_cur->raw.len); - } - - crl_prv = crl_cur; - crl_cur = crl_cur->next; - - mbedtls_platform_zeroize(crl_prv, sizeof(mbedtls_x509_crl)); - if (crl_prv != crl) { - mbedtls_free(crl_prv); - } - } -} - -#endif /* MBEDTLS_X509_CRL_PARSE_C */ diff --git a/vendor/mbedtls/library/x509_crt.c b/vendor/mbedtls/library/x509_crt.c deleted file mode 100644 index f15aa99d5..000000000 --- a/vendor/mbedtls/library/x509_crt.c +++ /dev/null @@ -1,3306 +0,0 @@ -/* - * X.509 certificate parsing and verification - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - * - * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - -#include "mbedtls/x509_crt.h" -#include "x509_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "psa_util_internal.h" -#include "mbedtls/psa_util.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#include "pk_internal.h" - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#else -#include -#endif -#endif - -#if defined(MBEDTLS_FS_IO) -#include -#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) -#include -#include -#if defined(__MBED__) -#include -#else -#include -#endif /* __MBED__ */ -#include -#endif /* !_WIN32 || EFIX64 || EFI32 */ -#endif - -/* - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *crt; - uint32_t flags; -} x509_crt_verify_chain_item; - -/* - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define X509_MAX_VERIFY_CHAIN_SIZE (MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2) - -/* Default profile. Do not remove items unless there are serious security - * concerns. */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = -{ - /* Hashes from SHA-256 and above. Note that this selection - * should be aligned with ssl_preset_default_hashes in ssl_tls.c. */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512), - 0xFFFFFFF, /* Any PK alg */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - /* Curves at or above 128-bit security level. Note that this selection - * should be aligned with ssl_preset_default_curves in ssl_tls.c. */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP521R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP256R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) | - 0, -#else /* MBEDTLS_PK_HAVE_ECC_KEYS */ - 0, -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - 2048, -}; - -/* Next-generation profile. Currently identical to the default, but may - * be tightened at any time. */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = -{ - /* Hashes from SHA-256 and above. */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512), - 0xFFFFFFF, /* Any PK alg */ -#if defined(MBEDTLS_ECP_C) - /* Curves at or above 128-bit security level. */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP521R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP256R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256K1), -#else - 0, -#endif - 2048, -}; - -/* - * NSA Suite B Profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = -{ - /* Only SHA-256 and 384 */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384), - /* Only ECDSA */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY), -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - /* Only NIST P-256 and P-384 */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1), -#else /* MBEDTLS_PK_HAVE_ECC_KEYS */ - 0, -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - 0, -}; - -/* - * Empty / all-forbidden profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none = -{ - 0, - 0, - 0, - (uint32_t) -1, -}; - -/* - * Check md_alg against profile - * Return 0 if md_alg is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_md_alg(const mbedtls_x509_crt_profile *profile, - mbedtls_md_type_t md_alg) -{ - if (md_alg == MBEDTLS_MD_NONE) { - return -1; - } - - if ((profile->allowed_mds & MBEDTLS_X509_ID_FLAG(md_alg)) != 0) { - return 0; - } - - return -1; -} - -/* - * Check pk_alg against profile - * Return 0 if pk_alg is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_pk_alg(const mbedtls_x509_crt_profile *profile, - mbedtls_pk_type_t pk_alg) -{ - if (pk_alg == MBEDTLS_PK_NONE) { - return -1; - } - - if ((profile->allowed_pks & MBEDTLS_X509_ID_FLAG(pk_alg)) != 0) { - return 0; - } - - return -1; -} - -/* - * Check key against profile - * Return 0 if pk is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile, - const mbedtls_pk_context *pk) -{ - const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(pk); - -#if defined(MBEDTLS_RSA_C) - if (pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) { - if (mbedtls_pk_get_bitlen(pk) >= profile->rsa_min_bitlen) { - return 0; - } - - return -1; - } -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_alg == MBEDTLS_PK_ECDSA || - pk_alg == MBEDTLS_PK_ECKEY || - pk_alg == MBEDTLS_PK_ECKEY_DH) { - const mbedtls_ecp_group_id gid = mbedtls_pk_get_ec_group_id(pk); - - if (gid == MBEDTLS_ECP_DP_NONE) { - return -1; - } - - if ((profile->allowed_curves & MBEDTLS_X509_ID_FLAG(gid)) != 0) { - return 0; - } - - return -1; - } -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - - return -1; -} - -/* - * Like memcmp, but case-insensitive and always returns -1 if different - */ -static int x509_memcasecmp(const void *s1, const void *s2, size_t len) -{ - size_t i; - unsigned char diff; - const unsigned char *n1 = s1, *n2 = s2; - - for (i = 0; i < len; i++) { - diff = n1[i] ^ n2[i]; - - if (diff == 0) { - continue; - } - - if (diff == 32 && - ((n1[i] >= 'a' && n1[i] <= 'z') || - (n1[i] >= 'A' && n1[i] <= 'Z'))) { - continue; - } - - return -1; - } - - return 0; -} - -/* - * Return 0 if name matches wildcard, -1 otherwise - */ -static int x509_check_wildcard(const char *cn, const mbedtls_x509_buf *name) -{ - size_t i; - size_t cn_idx = 0, cn_len = strlen(cn); - - /* We can't have a match if there is no wildcard to match */ - if (name->len < 3 || name->p[0] != '*' || name->p[1] != '.') { - return -1; - } - - for (i = 0; i < cn_len; ++i) { - if (cn[i] == '.') { - cn_idx = i; - break; - } - } - - if (cn_idx == 0) { - return -1; - } - - if (cn_len - cn_idx == name->len - 1 && - x509_memcasecmp(name->p + 1, cn + cn_idx, name->len - 1) == 0) { - return 0; - } - - return -1; -} - -/* - * Compare two X.509 strings, case-insensitive, and allowing for some encoding - * variations (but not all). - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_string_cmp(const mbedtls_x509_buf *a, const mbedtls_x509_buf *b) -{ - if (a->tag == b->tag && - a->len == b->len && - memcmp(a->p, b->p, b->len) == 0) { - return 0; - } - - if ((a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING) && - (b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING) && - a->len == b->len && - x509_memcasecmp(a->p, b->p, b->len) == 0) { - return 0; - } - - return -1; -} - -/* - * Compare two X.509 Names (aka rdnSequence). - * - * See RFC 5280 section 7.1, though we don't implement the whole algorithm: - * we sometimes return unequal when the full algorithm would return equal, - * but never the other way. (In particular, we don't do Unicode normalisation - * or space folding.) - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_name_cmp(const mbedtls_x509_name *a, const mbedtls_x509_name *b) -{ - /* Avoid recursion, it might not be optimised by the compiler */ - while (a != NULL || b != NULL) { - if (a == NULL || b == NULL) { - return -1; - } - - /* type */ - if (a->oid.tag != b->oid.tag || - a->oid.len != b->oid.len || - memcmp(a->oid.p, b->oid.p, b->oid.len) != 0) { - return -1; - } - - /* value */ - if (x509_string_cmp(&a->val, &b->val) != 0) { - return -1; - } - - /* structure of the list of sets */ - if (a->next_merged != b->next_merged) { - return -1; - } - - a = a->next; - b = b->next; - } - - /* a == NULL == b */ - return 0; -} - -/* - * Reset (init or clear) a verify_chain - */ -static void x509_crt_verify_chain_reset( - mbedtls_x509_crt_verify_chain *ver_chain) -{ - size_t i; - - for (i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++) { - ver_chain->items[i].crt = NULL; - ver_chain->items[i].flags = (uint32_t) -1; - } - - ver_chain->len = 0; - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - ver_chain->trust_ca_cb_result = NULL; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -} - -/* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ -static int x509_get_version(unsigned char **p, - const unsigned char *end, - int *ver) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 0)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - *ver = 0; - return 0; - } - - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - end = *p + len; - - if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret); - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - */ -static int x509_get_dates(unsigned char **p, - const unsigned char *end, - mbedtls_x509_time *from, - mbedtls_x509_time *to) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret); - } - - end = *p + len; - - if ((ret = mbedtls_x509_get_time(p, end, from)) != 0) { - return ret; - } - - if ((ret = mbedtls_x509_get_time(p, end, to)) != 0) { - return ret; - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * X.509 v2/v3 unique identifier (not parsed) - */ -static int x509_get_uid(unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *uid, int n) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (*p == end) { - return 0; - } - - uid->tag = **p; - - if ((ret = mbedtls_asn1_get_tag(p, end, &uid->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - n)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return 0; - } - - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - uid->p = *p; - *p += uid->len; - - return 0; -} - -static int x509_get_basic_constraints(unsigned char **p, - const unsigned char *end, - int *ca_istrue, - int *max_pathlen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - - /* - * BasicConstraints ::= SEQUENCE { - * cA BOOLEAN DEFAULT FALSE, - * pathLenConstraint INTEGER (0..MAX) OPTIONAL } - */ - *ca_istrue = 0; /* DEFAULT FALSE */ - *max_pathlen = 0; /* endless */ - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (*p == end) { - return 0; - } - - if ((ret = mbedtls_asn1_get_bool(p, end, ca_istrue)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - ret = mbedtls_asn1_get_int(p, end, ca_istrue); - } - - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (*ca_istrue != 0) { - *ca_istrue = 1; - } - } - - if (*p == end) { - return 0; - } - - if ((ret = mbedtls_asn1_get_int(p, end, max_pathlen)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer - * overflow, which is an undefined behavior. */ - if (*max_pathlen == INT_MAX) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_INVALID_LENGTH); - } - - (*max_pathlen)++; - - return 0; -} - -/* - * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - * - * KeyPurposeId ::= OBJECT IDENTIFIER - */ -static int x509_get_ext_key_usage(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *ext_key_usage) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_asn1_get_sequence_of(p, end, ext_key_usage, MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - /* Sequence length must be >= 1 */ - if (ext_key_usage->buf.p == NULL) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_INVALID_LENGTH); - } - - return 0; -} - -/* - * SubjectKeyIdentifier ::= KeyIdentifier - * - * KeyIdentifier ::= OCTET STRING - */ -static int x509_get_subject_key_id(unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *subject_key_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0u; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - subject_key_id->len = len; - subject_key_id->tag = MBEDTLS_ASN1_OCTET_STRING; - subject_key_id->p = *p; - *p += len; - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * AuthorityKeyIdentifier ::= SEQUENCE { - * keyIdentifier [0] KeyIdentifier OPTIONAL, - * authorityCertIssuer [1] GeneralNames OPTIONAL, - * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } - * - * KeyIdentifier ::= OCTET STRING - */ -static int x509_get_authority_key_id(unsigned char **p, - unsigned char *end, - mbedtls_x509_authority *authority_key_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0u; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (*p + len != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC); - - /* KeyIdentifier is an OPTIONAL field */ - if (ret == 0) { - authority_key_id->keyIdentifier.len = len; - authority_key_id->keyIdentifier.p = *p; - /* Setting tag of the keyIdentfier intentionally to 0x04. - * Although the .keyIdentfier field is CONTEXT_SPECIFIC ([0] OPTIONAL), - * its tag with the content is the payload of on OCTET STRING primitive */ - authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING; - - *p += len; - } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (*p < end) { - /* Getting authorityCertIssuer using the required specific class tag [1] */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 1)) != 0) { - /* authorityCertIssuer and authorityCertSerialNumber MUST both - be present or both be absent. At this point we expect to have both. */ - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - /* "end" also includes the CertSerialNumber field so "len" shall be used */ - ret = mbedtls_x509_get_subject_alt_name_ext(p, - (*p+len), - &authority_key_id->authorityCertIssuer); - if (ret != 0) { - return ret; - } - - /* Getting authorityCertSerialNumber using the required specific class tag [2] */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - authority_key_id->authorityCertSerialNumber.len = len; - authority_key_id->authorityCertSerialNumber.p = *p; - authority_key_id->authorityCertSerialNumber.tag = MBEDTLS_ASN1_INTEGER; - *p += len; - } - - if (*p != end) { - return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } - - return 0; -} - -/* - * id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } - * - * anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } - * - * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation - * - * PolicyInformation ::= SEQUENCE { - * policyIdentifier CertPolicyId, - * policyQualifiers SEQUENCE SIZE (1..MAX) OF - * PolicyQualifierInfo OPTIONAL } - * - * CertPolicyId ::= OBJECT IDENTIFIER - * - * PolicyQualifierInfo ::= SEQUENCE { - * policyQualifierId PolicyQualifierId, - * qualifier ANY DEFINED BY policyQualifierId } - * - * -- policyQualifierIds for Internet policy qualifiers - * - * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } - * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } - * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } - * - * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice ) - * - * Qualifier ::= CHOICE { - * cPSuri CPSuri, - * userNotice UserNotice } - * - * CPSuri ::= IA5String - * - * UserNotice ::= SEQUENCE { - * noticeRef NoticeReference OPTIONAL, - * explicitText DisplayText OPTIONAL } - * - * NoticeReference ::= SEQUENCE { - * organization DisplayText, - * noticeNumbers SEQUENCE OF INTEGER } - * - * DisplayText ::= CHOICE { - * ia5String IA5String (SIZE (1..200)), - * visibleString VisibleString (SIZE (1..200)), - * bmpString BMPString (SIZE (1..200)), - * utf8String UTF8String (SIZE (1..200)) } - * - * NOTE: we only parse and use anyPolicy without qualifiers at this point - * as defined in RFC 5280. - */ -static int x509_get_certificate_policies(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *certificate_policies) -{ - int ret, parse_ret = 0; - size_t len; - mbedtls_asn1_buf *buf; - mbedtls_asn1_sequence *cur = certificate_policies; - - /* Get main sequence tag */ - ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if (*p + len != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* - * Cannot be an empty sequence. - */ - if (len == 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - while (*p < end) { - mbedtls_x509_buf policy_oid; - const unsigned char *policy_end; - - /* - * Get the policy sequence - */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - policy_end = *p + len; - - if ((ret = mbedtls_asn1_get_tag(p, policy_end, &len, - MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - policy_oid.tag = MBEDTLS_ASN1_OID; - policy_oid.len = len; - policy_oid.p = *p; - - /* - * Only AnyPolicy is currently supported when enforcing policy. - */ - if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_POLICY, &policy_oid) != 0) { - /* - * Set the parsing return code but continue parsing, in case this - * extension is critical. - */ - parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } - - /* Allocate and assign next pointer */ - if (cur->buf.p != NULL) { - if (cur->next != NULL) { - return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; - } - - cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); - - if (cur->next == NULL) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_ALLOC_FAILED); - } - - cur = cur->next; - } - - buf = &(cur->buf); - buf->tag = policy_oid.tag; - buf->p = policy_oid.p; - buf->len = policy_oid.len; - - *p += len; - - /* - * If there is an optional qualifier, then *p < policy_end - * Check the Qualifier len to verify it doesn't exceed policy_end. - */ - if (*p < policy_end) { - if ((ret = mbedtls_asn1_get_tag(p, policy_end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != - 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - /* - * Skip the optional policy qualifiers. - */ - *p += len; - } - - if (*p != policy_end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return parse_ret; -} - -/* - * X.509 v3 extensions - * - */ -static int x509_get_crt_ext(unsigned char **p, - const unsigned char *end, - mbedtls_x509_crt *crt, - mbedtls_x509_crt_ext_cb_t cb, - void *p_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet; - - if (*p == end) { - return 0; - } - - if ((ret = mbedtls_x509_get_ext(p, end, &crt->v3_ext, 3)) != 0) { - return ret; - } - - end = crt->v3_ext.p + crt->v3_ext.len; - while (*p < end) { - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - mbedtls_x509_buf extn_oid = { 0, 0, NULL }; - int is_critical = 0; /* DEFAULT FALSE */ - int ext_type = 0; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - end_ext_data = *p + len; - - /* Get extension ID */ - if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len, - MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - extn_oid.tag = MBEDTLS_ASN1_OID; - extn_oid.p = *p; - *p += extn_oid.len; - - /* Get optional critical */ - if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 && - (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - /* Data should be octet string type */ - if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - start_ext_octet = *p; - end_ext_octet = *p + len; - - if (end_ext_octet != end_ext_data) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* - * Detect supported extensions - */ - ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type); - - if (ret != 0) { - /* Give the callback (if any) a chance to handle the extension */ - if (cb != NULL) { - ret = cb(p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet); - if (ret != 0 && is_critical) { - return ret; - } - *p = end_ext_octet; - continue; - } - - /* No parser found, skip extension */ - *p = end_ext_octet; - - if (is_critical) { - /* Data is marked as critical: fail */ - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - continue; - } - - /* Forbid repeated extensions */ - if ((crt->ext_types & ext_type) != 0) { - return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; - } - - crt->ext_types |= ext_type; - - switch (ext_type) { - case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: - /* Parse basic constraints */ - if ((ret = x509_get_basic_constraints(p, end_ext_octet, - &crt->ca_istrue, &crt->max_pathlen)) != 0) { - return ret; - } - break; - - case MBEDTLS_X509_EXT_KEY_USAGE: - /* Parse key usage */ - if ((ret = mbedtls_x509_get_key_usage(p, end_ext_octet, - &crt->key_usage)) != 0) { - return ret; - } - break; - - case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: - /* Parse extended key usage */ - if ((ret = x509_get_ext_key_usage(p, end_ext_octet, - &crt->ext_key_usage)) != 0) { - return ret; - } - break; - - case MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER: - /* Parse subject key identifier */ - if ((ret = x509_get_subject_key_id(p, end_ext_data, - &crt->subject_key_id)) != 0) { - return ret; - } - break; - - case MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER: - /* Parse authority key identifier */ - if ((ret = x509_get_authority_key_id(p, end_ext_octet, - &crt->authority_key_id)) != 0) { - return ret; - } - break; - case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: - /* Parse subject alt name - * SubjectAltName ::= GeneralNames - */ - if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_octet, - &crt->subject_alt_names)) != 0) { - return ret; - } - break; - - case MBEDTLS_X509_EXT_NS_CERT_TYPE: - /* Parse netscape certificate type */ - if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_octet, - &crt->ns_cert_type)) != 0) { - return ret; - } - break; - - case MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES: - /* Parse certificate policies type */ - if ((ret = x509_get_certificate_policies(p, end_ext_octet, - &crt->certificate_policies)) != 0) { - /* Give the callback (if any) a chance to handle the extension - * if it contains unsupported policies */ - if (ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE && cb != NULL && - cb(p_ctx, crt, &extn_oid, is_critical, - start_ext_octet, end_ext_octet) == 0) { - break; - } - - if (is_critical) { - return ret; - } else - /* - * If MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned, then we - * cannot interpret or enforce the policy. However, it is up to - * the user to choose how to enforce the policies, - * unless the extension is critical. - */ - if (ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) { - return ret; - } - } - break; - - default: - /* - * If this is a non-critical extension, which the oid layer - * supports, but there isn't an x509 parser for it, - * skip the extension. - */ - if (is_critical) { - return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } else { - *p = end_ext_octet; - } - } - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Parse and fill a single X.509 certificate in DER format - */ -static int x509_crt_parse_der_core(mbedtls_x509_crt *crt, - const unsigned char *buf, - size_t buflen, - int make_copy, - mbedtls_x509_crt_ext_cb_t cb, - void *p_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - unsigned char *p, *end, *crt_end; - mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; - - memset(&sig_params1, 0, sizeof(mbedtls_x509_buf)); - memset(&sig_params2, 0, sizeof(mbedtls_x509_buf)); - memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf)); - - /* - * Check for valid input - */ - if (crt == NULL || buf == NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - /* Use the original buffer until we figure out actual length. */ - p = (unsigned char *) buf; - len = buflen; - end = p + len; - - /* - * Certificate ::= SEQUENCE { - * tbsCertificate TBSCertificate, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERR_X509_INVALID_FORMAT; - } - - end = crt_end = p + len; - crt->raw.len = (size_t) (crt_end - buf); - if (make_copy != 0) { - /* Create and populate a new buffer for the raw field. */ - crt->raw.p = p = mbedtls_calloc(1, crt->raw.len); - if (crt->raw.p == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - memcpy(crt->raw.p, buf, crt->raw.len); - crt->own_buffer = 1; - - p += crt->raw.len - len; - end = crt_end = p + len; - } else { - crt->raw.p = (unsigned char *) buf; - crt->own_buffer = 0; - } - - /* - * TBSCertificate ::= SEQUENCE { - */ - crt->tbs.p = p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - end = p + len; - crt->tbs.len = (size_t) (end - crt->tbs.p); - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - * - * CertificateSerialNumber ::= INTEGER - * - * signature AlgorithmIdentifier - */ - if ((ret = x509_get_version(&p, end, &crt->version)) != 0 || - (ret = mbedtls_x509_get_serial(&p, end, &crt->serial)) != 0 || - (ret = mbedtls_x509_get_alg(&p, end, &crt->sig_oid, - &sig_params1)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - - if (crt->version < 0 || crt->version > 2) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERR_X509_UNKNOWN_VERSION; - } - - crt->version++; - - if ((ret = mbedtls_x509_get_sig_alg(&crt->sig_oid, &sig_params1, - &crt->sig_md, &crt->sig_pk, - &crt->sig_opts)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - - /* - * issuer Name - */ - crt->issuer_raw.p = p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - - crt->issuer_raw.len = (size_t) (p - crt->issuer_raw.p); - - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - * - */ - if ((ret = x509_get_dates(&p, end, &crt->valid_from, - &crt->valid_to)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - - /* - * subject Name - */ - crt->subject_raw.p = p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - if (len && (ret = mbedtls_x509_get_name(&p, p + len, &crt->subject)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - - crt->subject_raw.len = (size_t) (p - crt->subject_raw.p); - - /* - * SubjectPublicKeyInfo - */ - crt->pk_raw.p = p; - if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &crt->pk)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - crt->pk_raw.len = (size_t) (p - crt->pk_raw.p); - - /* - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * extensions [3] EXPLICIT Extensions OPTIONAL - * -- If present, version shall be v3 - */ - if (crt->version == 2 || crt->version == 3) { - ret = x509_get_uid(&p, end, &crt->issuer_id, 1); - if (ret != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - } - - if (crt->version == 2 || crt->version == 3) { - ret = x509_get_uid(&p, end, &crt->subject_id, 2); - if (ret != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - } - - if (crt->version == 3) { - ret = x509_get_crt_ext(&p, end, crt, cb, p_ctx); - if (ret != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - } - - if (p != end) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - end = crt_end; - - /* - * } - * -- end of TBSCertificate - * - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - */ - if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - - if (crt->sig_oid.len != sig_oid2.len || - memcmp(crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len) != 0 || - sig_params1.tag != sig_params2.tag || - sig_params1.len != sig_params2.len || - (sig_params1.len != 0 && - memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERR_X509_SIG_MISMATCH; - } - - if ((ret = mbedtls_x509_get_sig(&p, end, &crt->sig)) != 0) { - mbedtls_x509_crt_free(crt); - return ret; - } - - if (p != end) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Parse one X.509 certificate in DER format from a buffer and add them to a - * chained list - */ -static int mbedtls_x509_crt_parse_der_internal(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen, - int make_copy, - mbedtls_x509_crt_ext_cb_t cb, - void *p_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_x509_crt *crt = chain, *prev = NULL; - - /* - * Check for valid input - */ - if (crt == NULL || buf == NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - while (crt->version != 0 && crt->next != NULL) { - prev = crt; - crt = crt->next; - } - - /* - * Add new certificate on the end of the chain if needed. - */ - if (crt->version != 0 && crt->next == NULL) { - crt->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crt)); - - if (crt->next == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - prev = crt; - mbedtls_x509_crt_init(crt->next); - crt = crt->next; - } - - ret = x509_crt_parse_der_core(crt, buf, buflen, make_copy, cb, p_ctx); - if (ret != 0) { - if (prev) { - prev->next = NULL; - } - - if (crt != chain) { - mbedtls_free(crt); - } - - return ret; - } - - return 0; -} - -int mbedtls_x509_crt_parse_der_nocopy(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen) -{ - return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, 0, NULL, NULL); -} - -int mbedtls_x509_crt_parse_der_with_ext_cb(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen, - int make_copy, - mbedtls_x509_crt_ext_cb_t cb, - void *p_ctx) -{ - return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, make_copy, cb, p_ctx); -} - -int mbedtls_x509_crt_parse_der(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen) -{ - return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, 1, NULL, NULL); -} - -/* - * Parse one or more PEM certificates from a buffer and add them to the chained - * list - */ -int mbedtls_x509_crt_parse(mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen) -{ -#if defined(MBEDTLS_PEM_PARSE_C) - int success = 0, first_error = 0, total_failed = 0; - int buf_format = MBEDTLS_X509_FORMAT_DER; -#endif - - /* - * Check for valid input - */ - if (chain == NULL || buf == NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - /* - * Determine buffer content. Buffer contains either one DER certificate or - * one or more PEM certificates. - */ -#if defined(MBEDTLS_PEM_PARSE_C) - if (buflen != 0 && buf[buflen - 1] == '\0' && - strstr((const char *) buf, "-----BEGIN CERTIFICATE-----") != NULL) { - buf_format = MBEDTLS_X509_FORMAT_PEM; - } - - if (buf_format == MBEDTLS_X509_FORMAT_DER) { - return mbedtls_x509_crt_parse_der(chain, buf, buflen); - } -#else - return mbedtls_x509_crt_parse_der(chain, buf, buflen); -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) - if (buf_format == MBEDTLS_X509_FORMAT_PEM) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_pem_context pem; - - /* 1 rather than 0 since the terminating NULL byte is counted in */ - while (buflen > 1) { - size_t use_len; - mbedtls_pem_init(&pem); - - /* If we get there, we know the string is null-terminated */ - ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN CERTIFICATE-----", - "-----END CERTIFICATE-----", - buf, NULL, 0, &use_len); - - if (ret == 0) { - /* - * Was PEM encoded - */ - buflen -= use_len; - buf += use_len; - } else if (ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA) { - return ret; - } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - mbedtls_pem_free(&pem); - - /* - * PEM header and footer were found - */ - buflen -= use_len; - buf += use_len; - - if (first_error == 0) { - first_error = ret; - } - - total_failed++; - continue; - } else { - break; - } - - ret = mbedtls_x509_crt_parse_der(chain, pem.buf, pem.buflen); - - mbedtls_pem_free(&pem); - - if (ret != 0) { - /* - * Quit parsing on a memory error - */ - if (ret == MBEDTLS_ERR_X509_ALLOC_FAILED) { - return ret; - } - - if (first_error == 0) { - first_error = ret; - } - - total_failed++; - continue; - } - - success = 1; - } - } - - if (success) { - return total_failed; - } else if (first_error) { - return first_error; - } else { - return MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT; - } -#endif /* MBEDTLS_PEM_PARSE_C */ -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load one or more certificates and add them to the chained list - */ -int mbedtls_x509_crt_parse_file(mbedtls_x509_crt *chain, const char *path) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - unsigned char *buf; - - if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) { - return ret; - } - - ret = mbedtls_x509_crt_parse(chain, buf, n); - - mbedtls_zeroize_and_free(buf, n); - - return ret; -} - -int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path) -{ - int ret = 0; -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - int w_ret; - WCHAR szDir[MAX_PATH]; - char filename[MAX_PATH]; - char *p; - size_t len = strlen(path); - - WIN32_FIND_DATAW file_data; - HANDLE hFind; - - if (len > MAX_PATH - 3) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - memset(szDir, 0, sizeof(szDir)); - memset(filename, 0, MAX_PATH); - memcpy(filename, path, len); - filename[len++] = '\\'; - p = filename + len; - filename[len++] = '*'; - - /* - * Note this function uses the code page CP_ACP which is the system default - * ANSI codepage. The input string is always described in BYTES and the - * output length is described in WCHARs. - */ - w_ret = MultiByteToWideChar(CP_ACP, 0, filename, (int) len, szDir, - MAX_PATH - 3); - if (w_ret == 0) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - hFind = FindFirstFileW(szDir, &file_data); - if (hFind == INVALID_HANDLE_VALUE) { - return MBEDTLS_ERR_X509_FILE_IO_ERROR; - } - - len = MAX_PATH - len; - do { - memset(p, 0, len); - - if (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - continue; - } - w_ret = WideCharToMultiByte(CP_ACP, 0, file_data.cFileName, - -1, p, (int) len, NULL, NULL); - if (w_ret == 0) { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; - } - - w_ret = mbedtls_x509_crt_parse_file(chain, filename); - if (w_ret < 0) { - ret++; - } else { - ret += w_ret; - } - } while (FindNextFileW(hFind, &file_data) != 0); - - if (GetLastError() != ERROR_NO_MORE_FILES) { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - } - -cleanup: - FindClose(hFind); -#else /* _WIN32 */ - int t_ret; - int snp_ret; - struct stat sb; - struct dirent *entry; - char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; - DIR *dir = opendir(path); - - if (dir == NULL) { - return MBEDTLS_ERR_X509_FILE_IO_ERROR; - } - -#if defined(MBEDTLS_THREADING_C) - if ((ret = mbedtls_mutex_lock(&mbedtls_threading_readdir_mutex)) != 0) { - closedir(dir); - return ret; - } -#endif /* MBEDTLS_THREADING_C */ - - memset(&sb, 0, sizeof(sb)); - - while ((entry = readdir(dir)) != NULL) { - snp_ret = mbedtls_snprintf(entry_name, sizeof(entry_name), - "%s/%s", path, entry->d_name); - - if (snp_ret < 0 || (size_t) snp_ret >= sizeof(entry_name)) { - ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - goto cleanup; - } else if (stat(entry_name, &sb) == -1) { - if (errno == ENOENT) { - /* Broken symbolic link - ignore this entry. - stat(2) will return this error for either (a) a dangling - symlink or (b) a missing file. - Given that we have just obtained the filename from readdir, - assume that it does exist and therefore treat this as a - dangling symlink. */ - continue; - } else { - /* Some other file error; report the error. */ - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; - } - } - - if (!S_ISREG(sb.st_mode)) { - continue; - } - - // Ignore parse errors - // - t_ret = mbedtls_x509_crt_parse_file(chain, entry_name); - if (t_ret < 0) { - ret++; - } else { - ret += t_ret; - } - } - -cleanup: - closedir(dir); - -#if defined(MBEDTLS_THREADING_C) - if (mbedtls_mutex_unlock(&mbedtls_threading_readdir_mutex) != 0) { - ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; - } -#endif /* MBEDTLS_THREADING_C */ - -#endif /* _WIN32 */ - - return ret; -} -#endif /* MBEDTLS_FS_IO */ - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -#define PRINT_ITEM(i) \ - do { \ - ret = mbedtls_snprintf(p, n, "%s" i, sep); \ - MBEDTLS_X509_SAFE_SNPRINTF; \ - sep = ", "; \ - } while (0) - -#define CERT_TYPE(type, name) \ - do { \ - if (ns_cert_type & (type)) { \ - PRINT_ITEM(name); \ - } \ - } while (0) - -#define KEY_USAGE(code, name) \ - do { \ - if (key_usage & (code)) { \ - PRINT_ITEM(name); \ - } \ - } while (0) - -static int x509_info_ext_key_usage(char **buf, size_t *size, - const mbedtls_x509_sequence *extended_key_usage) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const char *desc; - size_t n = *size; - char *p = *buf; - const mbedtls_x509_sequence *cur = extended_key_usage; - const char *sep = ""; - - while (cur != NULL) { - if (mbedtls_oid_get_extended_key_usage(&cur->buf, &desc) != 0) { - desc = "???"; - } - - ret = mbedtls_snprintf(p, n, "%s%s", sep, desc); - MBEDTLS_X509_SAFE_SNPRINTF; - - sep = ", "; - - cur = cur->next; - } - - *size = n; - *buf = p; - - return 0; -} - -static int x509_info_cert_policies(char **buf, size_t *size, - const mbedtls_x509_sequence *certificate_policies) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const char *desc; - size_t n = *size; - char *p = *buf; - const mbedtls_x509_sequence *cur = certificate_policies; - const char *sep = ""; - - while (cur != NULL) { - if (mbedtls_oid_get_certificate_policies(&cur->buf, &desc) != 0) { - desc = "???"; - } - - ret = mbedtls_snprintf(p, n, "%s%s", sep, desc); - MBEDTLS_X509_SAFE_SNPRINTF; - - sep = ", "; - - cur = cur->next; - } - - *size = n; - *buf = p; - - return 0; -} - -/* - * Return an informational string about the certificate. - */ -#define BEFORE_COLON 18 -#define BC "18" -int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - char *p; - char key_size_str[BEFORE_COLON]; - - p = buf; - n = size; - - if (NULL == crt) { - ret = mbedtls_snprintf(p, n, "\nCertificate is uninitialised!\n"); - MBEDTLS_X509_SAFE_SNPRINTF; - - return (int) (size - n); - } - - ret = mbedtls_snprintf(p, n, "%scert. version : %d\n", - prefix, crt->version); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_snprintf(p, n, "%sserial number : ", - prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_serial_gets(p, n, &crt->serial); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets(p, n, &crt->issuer); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%ssubject name : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets(p, n, &crt->subject); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%sissued on : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_from.year, crt->valid_from.mon, - crt->valid_from.day, crt->valid_from.hour, - crt->valid_from.min, crt->valid_from.sec); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%sexpires on : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_to.year, crt->valid_to.mon, - crt->valid_to.day, crt->valid_to.hour, - crt->valid_to.min, crt->valid_to.sec); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_sig_alg_gets(p, n, &crt->sig_oid, crt->sig_pk, - crt->sig_md, crt->sig_opts); - MBEDTLS_X509_SAFE_SNPRINTF; - - /* Key size */ - if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON, - mbedtls_pk_get_name(&crt->pk))) != 0) { - return ret; - } - - ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen(&crt->pk)); - MBEDTLS_X509_SAFE_SNPRINTF; - - /* - * Optional extensions - */ - - if (crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) { - ret = mbedtls_snprintf(p, n, "\n%sbasic constraints : CA=%s", prefix, - crt->ca_istrue ? "true" : "false"); - MBEDTLS_X509_SAFE_SNPRINTF; - - if (crt->max_pathlen > 0) { - ret = mbedtls_snprintf(p, n, ", max_pathlen=%d", crt->max_pathlen - 1); - MBEDTLS_X509_SAFE_SNPRINTF; - } - } - - if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) { - ret = mbedtls_snprintf(p, n, "\n%ssubject alt name :", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n, - &crt->subject_alt_names, - prefix)) != 0) { - return ret; - } - } - - if (crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) { - ret = mbedtls_snprintf(p, n, "\n%scert. type : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = mbedtls_x509_info_cert_type(&p, &n, crt->ns_cert_type)) != 0) { - return ret; - } - } - - if (crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) { - ret = mbedtls_snprintf(p, n, "\n%skey usage : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = mbedtls_x509_info_key_usage(&p, &n, crt->key_usage)) != 0) { - return ret; - } - } - - if (crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE) { - ret = mbedtls_snprintf(p, n, "\n%sext key usage : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = x509_info_ext_key_usage(&p, &n, - &crt->ext_key_usage)) != 0) { - return ret; - } - } - - if (crt->ext_types & MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES) { - ret = mbedtls_snprintf(p, n, "\n%scertificate policies : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = x509_info_cert_policies(&p, &n, - &crt->certificate_policies)) != 0) { - return ret; - } - } - - ret = mbedtls_snprintf(p, n, "\n"); - MBEDTLS_X509_SAFE_SNPRINTF; - - return (int) (size - n); -} - -struct x509_crt_verify_string { - int code; - const char *string; -}; - -#define X509_CRT_ERROR_INFO(err, err_str, info) { err, info }, -static const struct x509_crt_verify_string x509_crt_verify_strings[] = { - MBEDTLS_X509_CRT_ERROR_INFO_LIST - { 0, NULL } -}; -#undef X509_CRT_ERROR_INFO - -int mbedtls_x509_crt_verify_info(char *buf, size_t size, const char *prefix, - uint32_t flags) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const struct x509_crt_verify_string *cur; - char *p = buf; - size_t n = size; - - for (cur = x509_crt_verify_strings; cur->string != NULL; cur++) { - if ((flags & cur->code) == 0) { - continue; - } - - ret = mbedtls_snprintf(p, n, "%s%s\n", prefix, cur->string); - MBEDTLS_X509_SAFE_SNPRINTF; - flags ^= cur->code; - } - - if (flags != 0) { - ret = mbedtls_snprintf(p, n, "%sUnknown reason " - "(this should not happen)\n", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return (int) (size - n); -} -#endif /* MBEDTLS_X509_REMOVE_INFO */ - -int mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt *crt, - unsigned int usage) -{ - unsigned int usage_must, usage_may; - unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY - | MBEDTLS_X509_KU_DECIPHER_ONLY; - - if ((crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) == 0) { - return 0; - } - - usage_must = usage & ~may_mask; - - if (((crt->key_usage & ~may_mask) & usage_must) != usage_must) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - usage_may = usage & may_mask; - - if (((crt->key_usage & may_mask) | usage_may) != usage_may) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - return 0; -} - -int mbedtls_x509_crt_check_extended_key_usage(const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len) -{ - const mbedtls_x509_sequence *cur; - - /* Extension is not mandatory, absent means no restriction */ - if ((crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE) == 0) { - return 0; - } - - /* - * Look for the requested usage (or wildcard ANY) in our list - */ - for (cur = &crt->ext_key_usage; cur != NULL; cur = cur->next) { - const mbedtls_x509_buf *cur_oid = &cur->buf; - - if (cur_oid->len == usage_len && - memcmp(cur_oid->p, usage_oid, usage_len) == 0) { - return 0; - } - - if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid) == 0) { - return 0; - } - } - - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; -} - -#if defined(MBEDTLS_X509_CRL_PARSE_C) -/* - * Return 1 if the certificate is revoked, or 0 otherwise. - */ -int mbedtls_x509_crt_is_revoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl) -{ - const mbedtls_x509_crl_entry *cur = &crl->entry; - - while (cur != NULL && cur->serial.len != 0) { - if (crt->serial.len == cur->serial.len && - memcmp(crt->serial.p, cur->serial.p, crt->serial.len) == 0) { - return 1; - } - - cur = cur->next; - } - - return 0; -} - -/* - * Check that the given certificate is not revoked according to the CRL. - * Skip validation if no CRL for the given CA is present. - */ -static int x509_crt_verifycrl(mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, - mbedtls_x509_crl *crl_list, - const mbedtls_x509_crt_profile *profile, - const mbedtls_x509_time *now) -{ - int flags = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_algorithm_t psa_algorithm; -#else - const mbedtls_md_info_t *md_info; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - size_t hash_length; - - if (ca == NULL) { - return flags; - } - - while (crl_list != NULL) { - if (crl_list->version == 0 || - x509_name_cmp(&crl_list->issuer, &ca->subject) != 0) { - crl_list = crl_list->next; - continue; - } - - /* - * Check if the CA is configured to sign CRLs - */ - if (mbedtls_x509_crt_check_key_usage(ca, - MBEDTLS_X509_KU_CRL_SIGN) != 0) { - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } - - /* - * Check if CRL is correctly signed by the trusted CA - */ - if (x509_profile_check_md_alg(profile, crl_list->sig_md) != 0) { - flags |= MBEDTLS_X509_BADCRL_BAD_MD; - } - - if (x509_profile_check_pk_alg(profile, crl_list->sig_pk) != 0) { - flags |= MBEDTLS_X509_BADCRL_BAD_PK; - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_algorithm = mbedtls_md_psa_alg_from_type(crl_list->sig_md); - if (psa_hash_compute(psa_algorithm, - crl_list->tbs.p, - crl_list->tbs.len, - hash, - sizeof(hash), - &hash_length) != PSA_SUCCESS) { - /* Note: this can't happen except after an internal error */ - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } -#else - md_info = mbedtls_md_info_from_type(crl_list->sig_md); - hash_length = mbedtls_md_get_size(md_info); - if (mbedtls_md(md_info, - crl_list->tbs.p, - crl_list->tbs.len, - hash) != 0) { - /* Note: this can't happen except after an internal error */ - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if (x509_profile_check_key(profile, &ca->pk) != 0) { - flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - } - - if (mbedtls_pk_verify_ext(crl_list->sig_pk, crl_list->sig_opts, &ca->pk, - crl_list->sig_md, hash, hash_length, - crl_list->sig.p, crl_list->sig.len) != 0) { - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } - -#if defined(MBEDTLS_HAVE_TIME_DATE) - /* - * Check for validity of CRL (Do not drop out) - */ - if (mbedtls_x509_time_cmp(&crl_list->next_update, now) < 0) { - flags |= MBEDTLS_X509_BADCRL_EXPIRED; - } - - if (mbedtls_x509_time_cmp(&crl_list->this_update, now) > 0) { - flags |= MBEDTLS_X509_BADCRL_FUTURE; - } -#else - ((void) now); -#endif - - /* - * Check if certificate is revoked - */ - if (mbedtls_x509_crt_is_revoked(crt, crl_list)) { - flags |= MBEDTLS_X509_BADCERT_REVOKED; - break; - } - - crl_list = crl_list->next; - } - - return flags; -} -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - -/* - * Check the signature of a certificate by its parent - */ -static int x509_crt_check_signature(const mbedtls_x509_crt *child, - mbedtls_x509_crt *parent, - mbedtls_x509_crt_restart_ctx *rs_ctx) -{ - size_t hash_len; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - const mbedtls_md_info_t *md_info; - md_info = mbedtls_md_info_from_type(child->sig_md); - hash_len = mbedtls_md_get_size(md_info); - - /* Note: hash errors can happen only after an internal error */ - if (mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash) != 0) { - return -1; - } -#else - psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(child->sig_md); - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - status = psa_hash_compute(hash_alg, - child->tbs.p, - child->tbs.len, - hash, - sizeof(hash), - &hash_len); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - /* Skip expensive computation on obvious mismatch */ - if (!mbedtls_pk_can_do(&parent->pk, child->sig_pk)) { - return -1; - } - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA) { - return mbedtls_pk_verify_restartable(&parent->pk, - child->sig_md, hash, hash_len, - child->sig.p, child->sig.len, &rs_ctx->pk); - } -#else - (void) rs_ctx; -#endif - - return mbedtls_pk_verify_ext(child->sig_pk, child->sig_opts, &parent->pk, - child->sig_md, hash, hash_len, - child->sig.p, child->sig.len); -} - -/* - * Check if 'parent' is a suitable parent (signing CA) for 'child'. - * Return 0 if yes, -1 if not. - * - * top means parent is a locally-trusted certificate - */ -static int x509_crt_check_parent(const mbedtls_x509_crt *child, - const mbedtls_x509_crt *parent, - int top) -{ - int need_ca_bit; - - /* Parent must be the issuer */ - if (x509_name_cmp(&child->issuer, &parent->subject) != 0) { - return -1; - } - - /* Parent must have the basicConstraints CA bit set as a general rule */ - need_ca_bit = 1; - - /* Exception: v1/v2 certificates that are locally trusted. */ - if (top && parent->version < 3) { - need_ca_bit = 0; - } - - if (need_ca_bit && !parent->ca_istrue) { - return -1; - } - - if (need_ca_bit && - mbedtls_x509_crt_check_key_usage(parent, MBEDTLS_X509_KU_KEY_CERT_SIGN) != 0) { - return -1; - } - - return 0; -} - -/* - * Find a suitable parent for child in candidates, or return NULL. - * - * Here suitable is defined as: - * 1. subject name matches child's issuer - * 2. if necessary, the CA bit is set and key usage allows signing certs - * 3. for trusted roots, the signature is correct - * (for intermediates, the signature is checked and the result reported) - * 4. pathlen constraints are satisfied - * - * If there's a suitable candidate which is also time-valid, return the first - * such. Otherwise, return the first suitable candidate (or NULL if there is - * none). - * - * The rationale for this rule is that someone could have a list of trusted - * roots with two versions on the same root with different validity periods. - * (At least one user reported having such a list and wanted it to just work.) - * The reason we don't just require time-validity is that generally there is - * only one version, and if it's expired we want the flags to state that - * rather than NOT_TRUSTED, as would be the case if we required it here. - * - * The rationale for rule 3 (signature for trusted roots) is that users might - * have two versions of the same CA with different keys in their list, and the - * way we select the correct one is by checking the signature (as we don't - * rely on key identifier extensions). (This is one way users might choose to - * handle key rollover, another relies on self-issued certs, see [SIRO].) - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent - * - [in] candidates: chained list of potential parents - * - [out] r_parent: parent found (or NULL) - * - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0 - * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top - * of the chain, 0 otherwise - * - [in] path_cnt: number of intermediates seen so far - * - [in] self_cnt: number of self-signed intermediates seen so far - * (will never be greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise - */ -static int x509_crt_find_parent_in( - mbedtls_x509_crt *child, - mbedtls_x509_crt *candidates, - mbedtls_x509_crt **r_parent, - int *r_signature_is_good, - int top, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx, - const mbedtls_x509_time *now) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_x509_crt *parent, *fallback_parent; - int signature_is_good = 0, fallback_signature_is_good; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* did we have something in progress? */ - if (rs_ctx != NULL && rs_ctx->parent != NULL) { - /* restore saved state */ - parent = rs_ctx->parent; - fallback_parent = rs_ctx->fallback_parent; - fallback_signature_is_good = rs_ctx->fallback_signature_is_good; - - /* clear saved state */ - rs_ctx->parent = NULL; - rs_ctx->fallback_parent = NULL; - rs_ctx->fallback_signature_is_good = 0; - - /* resume where we left */ - goto check_signature; - } -#endif - - fallback_parent = NULL; - fallback_signature_is_good = 0; - - for (parent = candidates; parent != NULL; parent = parent->next) { - /* basic parenting skills (name, CA bit, key usage) */ - if (x509_crt_check_parent(child, parent, top) != 0) { - continue; - } - - /* +1 because stored max_pathlen is 1 higher that the actual value */ - if (parent->max_pathlen > 0 && - (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt) { - continue; - } - - /* Signature */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -check_signature: -#endif - ret = x509_crt_check_signature(child, parent, rs_ctx); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - /* save state */ - rs_ctx->parent = parent; - rs_ctx->fallback_parent = fallback_parent; - rs_ctx->fallback_signature_is_good = fallback_signature_is_good; - - return ret; - } -#else - (void) ret; -#endif - - signature_is_good = ret == 0; - if (top && !signature_is_good) { - continue; - } - -#if defined(MBEDTLS_HAVE_TIME_DATE) - /* optional time check */ - if (mbedtls_x509_time_cmp(&parent->valid_to, now) < 0 || /* past */ - mbedtls_x509_time_cmp(&parent->valid_from, now) > 0) { /* future */ - if (fallback_parent == NULL) { - fallback_parent = parent; - fallback_signature_is_good = signature_is_good; - } - - continue; - } -#else - ((void) now); -#endif - - *r_parent = parent; - *r_signature_is_good = signature_is_good; - - break; - } - - if (parent == NULL) { - *r_parent = fallback_parent; - *r_signature_is_good = fallback_signature_is_good; - } - - return 0; -} - -/* - * Find a parent in trusted CAs or the provided chain, or return NULL. - * - * Searches in trusted CAs first, and return the first suitable parent found - * (see find_parent_in() for definition of suitable). - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent, followed - * by a chain of possible intermediates - * - [in] trust_ca: list of locally trusted certificates - * - [out] parent: parent found (or NULL) - * - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0 - * - [out] signature_is_good: 1 if child signature by parent is valid, or 0 - * - [in] path_cnt: number of links in the chain so far (EE -> ... -> child) - * - [in] self_cnt: number of self-signed certs in the chain so far - * (will always be no greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise - */ -static int x509_crt_find_parent( - mbedtls_x509_crt *child, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crt **parent, - int *parent_is_trusted, - int *signature_is_good, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx, - const mbedtls_x509_time *now) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_x509_crt *search_list; - - *parent_is_trusted = 1; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* restore then clear saved state if we have some stored */ - if (rs_ctx != NULL && rs_ctx->parent_is_trusted != -1) { - *parent_is_trusted = rs_ctx->parent_is_trusted; - rs_ctx->parent_is_trusted = -1; - } -#endif - - while (1) { - search_list = *parent_is_trusted ? trust_ca : child->next; - - ret = x509_crt_find_parent_in(child, search_list, - parent, signature_is_good, - *parent_is_trusted, - path_cnt, self_cnt, rs_ctx, now); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - /* save state */ - rs_ctx->parent_is_trusted = *parent_is_trusted; - return ret; - } -#else - (void) ret; -#endif - - /* stop here if found or already in second iteration */ - if (*parent != NULL || *parent_is_trusted == 0) { - break; - } - - /* prepare second iteration */ - *parent_is_trusted = 0; - } - - /* extra precaution against mistakes in the caller */ - if (*parent == NULL) { - *parent_is_trusted = 0; - *signature_is_good = 0; - } - - return 0; -} - -/* - * Check if an end-entity certificate is locally trusted - * - * Currently we require such certificates to be self-signed (actually only - * check for self-issued as self-signatures are not checked) - */ -static int x509_crt_check_ee_locally_trusted( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca) -{ - mbedtls_x509_crt *cur; - - /* must be self-issued */ - if (x509_name_cmp(&crt->issuer, &crt->subject) != 0) { - return -1; - } - - /* look for an exact match with trusted cert */ - for (cur = trust_ca; cur != NULL; cur = cur->next) { - if (crt->raw.len == cur->raw.len && - memcmp(crt->raw.p, cur->raw.p, crt->raw.len) == 0) { - return 0; - } - } - - /* too bad */ - return -1; -} - -/* - * Build and verify a certificate chain - * - * Given a peer-provided list of certificates EE, C1, ..., Cn and - * a list of trusted certs R1, ... Rp, try to build and verify a chain - * EE, Ci1, ... Ciq [, Rj] - * such that every cert in the chain is a child of the next one, - * jumping to a trusted root as early as possible. - * - * Verify that chain and return it with flags for all issues found. - * - * Special cases: - * - EE == Rj -> return a one-element list containing it - * - EE, Ci1, ..., Ciq cannot be continued with a trusted root - * -> return that chain with NOT_TRUSTED set on Ciq - * - * Tests for (aspects of) this function should include at least: - * - trusted EE - * - EE -> trusted root - * - EE -> intermediate CA -> trusted root - * - if relevant: EE untrusted - * - if relevant: EE -> intermediate, untrusted - * with the aspect under test checked at each relevant level (EE, int, root). - * For some aspects longer chains are required, but usually length 2 is - * enough (but length 1 is not in general). - * - * Arguments: - * - [in] crt: the cert list EE, C1, ..., Cn - * - [in] trust_ca: the trusted list R1, ..., Rp - * - [in] ca_crl, profile: as in verify_with_profile() - * - [out] ver_chain: the built and verified chain - * Only valid when return value is 0, may contain garbage otherwise! - * Restart note: need not be the same when calling again to resume. - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - non-zero if the chain could not be fully built and examined - * - 0 is the chain was successfully built and examined, - * even if it was found to be invalid - */ -static int x509_crt_verify_chain( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - mbedtls_x509_crt_verify_chain *ver_chain, - mbedtls_x509_crt_restart_ctx *rs_ctx) -{ - /* Don't initialize any of those variables here, so that the compiler can - * catch potential issues with jumping ahead when restarting */ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - uint32_t *flags; - mbedtls_x509_crt_verify_chain_item *cur; - mbedtls_x509_crt *child; - mbedtls_x509_crt *parent; - int parent_is_trusted; - int child_is_trusted; - int signature_is_good; - unsigned self_cnt; - mbedtls_x509_crt *cur_trust_ca = NULL; - mbedtls_x509_time now; - -#if defined(MBEDTLS_HAVE_TIME_DATE) - if (mbedtls_x509_time_gmtime(mbedtls_time(NULL), &now) != 0) { - return MBEDTLS_ERR_X509_FATAL_ERROR; - } -#endif - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* resume if we had an operation in progress */ - if (rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent) { - /* restore saved state */ - *ver_chain = rs_ctx->ver_chain; /* struct copy */ - self_cnt = rs_ctx->self_cnt; - - /* restore derived state */ - cur = &ver_chain->items[ver_chain->len - 1]; - child = cur->crt; - flags = &cur->flags; - - goto find_parent; - } -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - child = crt; - self_cnt = 0; - parent_is_trusted = 0; - child_is_trusted = 0; - - while (1) { - /* Add certificate to the verification chain */ - cur = &ver_chain->items[ver_chain->len]; - cur->crt = child; - cur->flags = 0; - ver_chain->len++; - flags = &cur->flags; - -#if defined(MBEDTLS_HAVE_TIME_DATE) - /* Check time-validity (all certificates) */ - if (mbedtls_x509_time_cmp(&child->valid_to, &now) < 0) { - *flags |= MBEDTLS_X509_BADCERT_EXPIRED; - } - - if (mbedtls_x509_time_cmp(&child->valid_from, &now) > 0) { - *flags |= MBEDTLS_X509_BADCERT_FUTURE; - } -#endif - - /* Stop here for trusted roots (but not for trusted EE certs) */ - if (child_is_trusted) { - return 0; - } - - /* Check signature algorithm: MD & PK algs */ - if (x509_profile_check_md_alg(profile, child->sig_md) != 0) { - *flags |= MBEDTLS_X509_BADCERT_BAD_MD; - } - - if (x509_profile_check_pk_alg(profile, child->sig_pk) != 0) { - *flags |= MBEDTLS_X509_BADCERT_BAD_PK; - } - - /* Special case: EE certs that are locally trusted */ - if (ver_chain->len == 1 && - x509_crt_check_ee_locally_trusted(child, trust_ca) == 0) { - return 0; - } - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -find_parent: -#endif - - /* Obtain list of potential trusted signers from CA callback, - * or use statically provided list. */ -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - if (f_ca_cb != NULL) { - mbedtls_x509_crt_free(ver_chain->trust_ca_cb_result); - mbedtls_free(ver_chain->trust_ca_cb_result); - ver_chain->trust_ca_cb_result = NULL; - - ret = f_ca_cb(p_ca_cb, child, &ver_chain->trust_ca_cb_result); - if (ret != 0) { - return MBEDTLS_ERR_X509_FATAL_ERROR; - } - - cur_trust_ca = ver_chain->trust_ca_cb_result; - } else -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - { - ((void) f_ca_cb); - ((void) p_ca_cb); - cur_trust_ca = trust_ca; - } - - /* Look for a parent in trusted CAs or up the chain */ - ret = x509_crt_find_parent(child, cur_trust_ca, &parent, - &parent_is_trusted, &signature_is_good, - ver_chain->len - 1, self_cnt, rs_ctx, - &now); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { - /* save state */ - rs_ctx->in_progress = x509_crt_rs_find_parent; - rs_ctx->self_cnt = self_cnt; - rs_ctx->ver_chain = *ver_chain; /* struct copy */ - - return ret; - } -#else - (void) ret; -#endif - - /* No parent? We're done here */ - if (parent == NULL) { - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - return 0; - } - - /* Count intermediate self-issued (not necessarily self-signed) certs. - * These can occur with some strategies for key rollover, see [SIRO], - * and should be excluded from max_pathlen checks. */ - if (ver_chain->len != 1 && - x509_name_cmp(&child->issuer, &child->subject) == 0) { - self_cnt++; - } - - /* path_cnt is 0 for the first intermediate CA, - * and if parent is trusted it's not an intermediate CA */ - if (!parent_is_trusted && - ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA) { - /* return immediately to avoid overflow the chain array */ - return MBEDTLS_ERR_X509_FATAL_ERROR; - } - - /* signature was checked while searching parent */ - if (!signature_is_good) { - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - } - - /* check size of signing key */ - if (x509_profile_check_key(profile, &parent->pk) != 0) { - *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - } - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - /* Check trusted CA's CRL for the given crt */ - *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile, &now); -#else - (void) ca_crl; -#endif - - /* prepare for next iteration */ - child = parent; - parent = NULL; - child_is_trusted = parent_is_trusted; - signature_is_good = 0; - } -} - -#ifdef _WIN32 -#ifdef _MSC_VER -#pragma comment(lib, "ws2_32.lib") -#include -#include -#elif (defined(__MINGW32__) || defined(__MINGW64__)) && _WIN32_WINNT >= 0x0600 -#include -#include -#else -/* inet_pton() is not supported, fallback to software version */ -#define MBEDTLS_TEST_SW_INET_PTON -#endif -#elif defined(__sun) -/* Solaris requires -lsocket -lnsl for inet_pton() */ -#elif defined(__has_include) -#if __has_include() -#include -#endif -#if __has_include() -#include -#endif -#endif - -/* Use whether or not AF_INET6 is defined to indicate whether or not to use - * the platform inet_pton() or a local implementation (below). The local - * implementation may be used even in cases where the platform provides - * inet_pton(), e.g. when there are different includes required and/or the - * platform implementation requires dependencies on additional libraries. - * Specifically, Windows requires custom includes and additional link - * dependencies, and Solaris requires additional link dependencies. - * Also, as a coarse heuristic, use the local implementation if the compiler - * does not support __has_include(), or if the definition of AF_INET6 is not - * provided by headers included (or not) via __has_include() above. - * MBEDTLS_TEST_SW_INET_PTON is a bypass define to force testing of this code //no-check-names - * despite having a platform that has inet_pton. */ -#if !defined(AF_INET6) || defined(MBEDTLS_TEST_SW_INET_PTON) //no-check-names -/* Definition located further below to possibly reduce compiler inlining */ -static int x509_inet_pton_ipv4(const char *src, void *dst); - -#define li_cton(c, n) \ - (((n) = (c) - '0') <= 9 || (((n) = ((c)&0xdf) - 'A') <= 5 ? ((n) += 10) : 0)) - -static int x509_inet_pton_ipv6(const char *src, void *dst) -{ - const unsigned char *p = (const unsigned char *) src; - int nonzero_groups = 0, num_digits, zero_group_start = -1; - uint16_t addr[8]; - do { - /* note: allows excess leading 0's, e.g. 1:0002:3:... */ - uint16_t group = num_digits = 0; - for (uint8_t digit; num_digits < 4; num_digits++) { - if (li_cton(*p, digit) == 0) { - break; - } - group = (group << 4) | digit; - p++; - } - if (num_digits != 0) { - MBEDTLS_PUT_UINT16_BE(group, addr, nonzero_groups); - nonzero_groups++; - if (*p == '\0') { - break; - } else if (*p == '.') { - /* Don't accept IPv4 too early or late: - * - The first 6 nonzero groups must be 16 bit pieces of address delimited by ':' - * - This might be fully or partially represented with compressed syntax (a zero - * group "::") - */ - if ((nonzero_groups < 6 && zero_group_start == -1) || - nonzero_groups >= 7) { - break; - } - - /* Walk back to prior ':', then parse as IPv4-mapped. - * At this point nonzero_groups == 6 or zero_group_start >= 0. Either way we have a - * ':' before the current position and still inside the buffer. Thus it is safe to - * search back for that ':' without any further checks. - */ - do { - p--; - } while (*p != ':'); - - p++; - nonzero_groups--; - if (x509_inet_pton_ipv4((const char *) p, - addr + nonzero_groups) != 0) { - break; - } - - nonzero_groups += 2; - p = (const unsigned char *) ""; - break; - } else if (*p != ':') { - return -1; - } - } else { - /* Don't accept a second zero group or an invalid delimiter */ - if (zero_group_start != -1 || *p != ':') { - return -1; - } - zero_group_start = nonzero_groups; - - /* Accept a zero group at start, but it has to be a double colon */ - if (zero_group_start == 0 && *++p != ':') { - return -1; - } - - if (p[1] == '\0') { - ++p; - break; - } - } - ++p; - } while (nonzero_groups < 8); - - if (*p != '\0') { - return -1; - } - - if (zero_group_start != -1) { - if (nonzero_groups > 6) { - return -1; - } - int zero_groups = 8 - nonzero_groups; - int groups_after_zero = nonzero_groups - zero_group_start; - - /* Move the non-zero part to after the zeroes */ - if (groups_after_zero) { - memmove(addr + zero_group_start + zero_groups, - addr + zero_group_start, - groups_after_zero * sizeof(*addr)); - } - memset(addr + zero_group_start, 0, zero_groups * sizeof(*addr)); - } else { - if (nonzero_groups != 8) { - return -1; - } - } - memcpy(dst, addr, sizeof(addr)); - return 0; -} - -static int x509_inet_pton_ipv4(const char *src, void *dst) -{ - const unsigned char *p = (const unsigned char *) src; - uint8_t *res = (uint8_t *) dst; - uint8_t digit, num_digits = 0; - uint8_t num_octets = 0; - uint16_t octet; - - do { - octet = num_digits = 0; - do { - digit = *p - '0'; - if (digit > 9) { - break; - } - - /* Don't allow leading zeroes. These might mean octal format, - * which this implementation does not support. */ - if (octet == 0 && num_digits > 0) { - return -1; - } - - octet = octet * 10 + digit; - num_digits++; - p++; - } while (num_digits < 3); - - if (octet >= 256 || num_digits > 3 || num_digits == 0) { - return -1; - } - *res++ = (uint8_t) octet; - num_octets++; - } while (num_octets < 4 && *p++ == '.'); - return num_octets == 4 && *p == '\0' ? 0 : -1; -} - -#else - -static int x509_inet_pton_ipv6(const char *src, void *dst) -{ - return inet_pton(AF_INET6, src, dst) == 1 ? 0 : -1; -} - -static int x509_inet_pton_ipv4(const char *src, void *dst) -{ - return inet_pton(AF_INET, src, dst) == 1 ? 0 : -1; -} - -#endif /* !AF_INET6 || MBEDTLS_TEST_SW_INET_PTON */ //no-check-names - -size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst) -{ - return strchr(cn, ':') == NULL - ? x509_inet_pton_ipv4(cn, dst) == 0 ? 4 : 0 - : x509_inet_pton_ipv6(cn, dst) == 0 ? 16 : 0; -} - -/* - * Check for CN match - */ -static int x509_crt_check_cn(const mbedtls_x509_buf *name, - const char *cn, size_t cn_len) -{ - /* try exact match */ - if (name->len == cn_len && - x509_memcasecmp(cn, name->p, cn_len) == 0) { - return 0; - } - - /* try wildcard match */ - if (x509_check_wildcard(cn, name) == 0) { - return 0; - } - - return -1; -} - -static int x509_crt_check_san_ip(const mbedtls_x509_sequence *san, - const char *cn, size_t cn_len) -{ - uint32_t ip[4]; - cn_len = mbedtls_x509_crt_parse_cn_inet_pton(cn, ip); - if (cn_len == 0) { - return -1; - } - - for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) { - const unsigned char san_type = (unsigned char) cur->buf.tag & - MBEDTLS_ASN1_TAG_VALUE_MASK; - if (san_type == MBEDTLS_X509_SAN_IP_ADDRESS && - cur->buf.len == cn_len && memcmp(cur->buf.p, ip, cn_len) == 0) { - return 0; - } - } - - return -1; -} - -static int x509_crt_check_san_uri(const mbedtls_x509_sequence *san, - const char *cn, size_t cn_len) -{ - for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) { - const unsigned char san_type = (unsigned char) cur->buf.tag & - MBEDTLS_ASN1_TAG_VALUE_MASK; - if (san_type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER && - cur->buf.len == cn_len && memcmp(cur->buf.p, cn, cn_len) == 0) { - return 0; - } - } - - return -1; -} - -/* - * Check for SAN match, see RFC 5280 Section 4.2.1.6 - */ -static int x509_crt_check_san(const mbedtls_x509_sequence *san, - const char *cn, size_t cn_len) -{ - int san_ip = 0; - int san_uri = 0; - /* Prioritize DNS name over other subtypes due to popularity */ - for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) { - switch ((unsigned char) cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) { - case MBEDTLS_X509_SAN_DNS_NAME: - if (x509_crt_check_cn(&cur->buf, cn, cn_len) == 0) { - return 0; - } - break; - case MBEDTLS_X509_SAN_IP_ADDRESS: - san_ip = 1; - break; - case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: - san_uri = 1; - break; - /* (We may handle other types here later.) */ - default: /* Unrecognized type */ - break; - } - } - if (san_ip) { - if (x509_crt_check_san_ip(san, cn, cn_len) == 0) { - return 0; - } - } - if (san_uri) { - if (x509_crt_check_san_uri(san, cn, cn_len) == 0) { - return 0; - } - } - - return -1; -} - -/* - * Verify the requested CN - only call this if cn is not NULL! - */ -static void x509_crt_verify_name(const mbedtls_x509_crt *crt, - const char *cn, - uint32_t *flags) -{ - const mbedtls_x509_name *name; - size_t cn_len = strlen(cn); - - if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) { - if (x509_crt_check_san(&crt->subject_alt_names, cn, cn_len) == 0) { - return; - } - } else { - for (name = &crt->subject; name != NULL; name = name->next) { - if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0 && - x509_crt_check_cn(&name->val, cn, cn_len) == 0) { - return; - } - } - - } - - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; -} - -/* - * Merge the flags for all certs in the chain, after calling callback - */ -static int x509_crt_merge_flags_with_cb( - uint32_t *flags, - const mbedtls_x509_crt_verify_chain *ver_chain, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned i; - uint32_t cur_flags; - const mbedtls_x509_crt_verify_chain_item *cur; - - for (i = ver_chain->len; i != 0; --i) { - cur = &ver_chain->items[i-1]; - cur_flags = cur->flags; - - if (NULL != f_vrfy) { - if ((ret = f_vrfy(p_vrfy, cur->crt, (int) i-1, &cur_flags)) != 0) { - return ret; - } - } - - *flags |= cur_flags; - } - - return 0; -} - -/* - * Verify the certificate validity, with profile, restartable version - * - * This function: - * - checks the requested CN (if any) - * - checks the type and size of the EE cert's key, - * as that isn't done as part of chain building/verification currently - * - builds and verifies the chain - * - then calls the callback and merges the flags - * - * The parameters pairs `trust_ca`, `ca_crl` and `f_ca_cb`, `p_ca_cb` - * are mutually exclusive: If `f_ca_cb != NULL`, it will be used by the - * verification routine to search for trusted signers, and CRLs will - * be disabled. Otherwise, `trust_ca` will be used as the static list - * of trusted signers, and `ca_crl` will be use as the static list - * of CRLs. - */ -static int x509_crt_verify_restartable_ca_cb(mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, - mbedtls_x509_crt *, - int, - uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_pk_type_t pk_type; - mbedtls_x509_crt_verify_chain ver_chain; - uint32_t ee_flags; - - *flags = 0; - ee_flags = 0; - x509_crt_verify_chain_reset(&ver_chain); - - if (profile == NULL) { - ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; - goto exit; - } - - /* check name if requested */ - if (cn != NULL) { - x509_crt_verify_name(crt, cn, &ee_flags); - } - - /* Check the type and size of the key */ - pk_type = mbedtls_pk_get_type(&crt->pk); - - if (x509_profile_check_pk_alg(profile, pk_type) != 0) { - ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK; - } - - if (x509_profile_check_key(profile, &crt->pk) != 0) { - ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - } - - /* Check the chain */ - ret = x509_crt_verify_chain(crt, trust_ca, ca_crl, - f_ca_cb, p_ca_cb, profile, - &ver_chain, rs_ctx); - - if (ret != 0) { - goto exit; - } - - /* Merge end-entity flags */ - ver_chain.items[0].flags |= ee_flags; - - /* Build final flags, calling callback on the way if any */ - ret = x509_crt_merge_flags_with_cb(flags, &ver_chain, f_vrfy, p_vrfy); - -exit: - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - mbedtls_x509_crt_free(ver_chain.trust_ca_cb_result); - mbedtls_free(ver_chain.trust_ca_cb_result); - ver_chain.trust_ca_cb_result = NULL; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if (rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS) { - mbedtls_x509_crt_restart_free(rs_ctx); - } -#endif - - /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by - * the SSL module for authmode optional, but non-zero return from the - * callback means a fatal error so it shouldn't be ignored */ - if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - } - - if (ret != 0) { - *flags = (uint32_t) -1; - return ret; - } - - if (*flags != 0) { - return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED; - } - - return 0; -} - - -/* - * Verify the certificate validity (default profile, not restartable) - */ -int mbedtls_x509_crt_verify(mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy) -{ - return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl, - NULL, NULL, - &mbedtls_x509_crt_profile_default, - cn, flags, - f_vrfy, p_vrfy, NULL); -} - -/* - * Verify the certificate validity (user-chosen profile, not restartable) - */ -int mbedtls_x509_crt_verify_with_profile(mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy) -{ - return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl, - NULL, NULL, - profile, cn, flags, - f_vrfy, p_vrfy, NULL); -} - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -/* - * Verify the certificate validity (user-chosen profile, CA callback, - * not restartable). - */ -int mbedtls_x509_crt_verify_with_ca_cb(mbedtls_x509_crt *crt, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy) -{ - return x509_crt_verify_restartable_ca_cb(crt, NULL, NULL, - f_ca_cb, p_ca_cb, - profile, cn, flags, - f_vrfy, p_vrfy, NULL); -} -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -int mbedtls_x509_crt_verify_restartable(mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx) -{ - return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl, - NULL, NULL, - profile, cn, flags, - f_vrfy, p_vrfy, rs_ctx); -} - - -/* - * Initialize a certificate chain - */ -void mbedtls_x509_crt_init(mbedtls_x509_crt *crt) -{ - memset(crt, 0, sizeof(mbedtls_x509_crt)); -} - -/* - * Unallocate all certificate data - */ -void mbedtls_x509_crt_free(mbedtls_x509_crt *crt) -{ - mbedtls_x509_crt *cert_cur = crt; - mbedtls_x509_crt *cert_prv; - - while (cert_cur != NULL) { - mbedtls_pk_free(&cert_cur->pk); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free(cert_cur->sig_opts); -#endif - - mbedtls_asn1_free_named_data_list_shallow(cert_cur->issuer.next); - mbedtls_asn1_free_named_data_list_shallow(cert_cur->subject.next); - mbedtls_asn1_sequence_free(cert_cur->ext_key_usage.next); - mbedtls_asn1_sequence_free(cert_cur->subject_alt_names.next); - mbedtls_asn1_sequence_free(cert_cur->certificate_policies.next); - mbedtls_asn1_sequence_free(cert_cur->authority_key_id.authorityCertIssuer.next); - - if (cert_cur->raw.p != NULL && cert_cur->own_buffer) { - mbedtls_zeroize_and_free(cert_cur->raw.p, cert_cur->raw.len); - } - - cert_prv = cert_cur; - cert_cur = cert_cur->next; - - mbedtls_platform_zeroize(cert_prv, sizeof(mbedtls_x509_crt)); - if (cert_prv != crt) { - mbedtls_free(cert_prv); - } - } -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_x509_crt_restart_init(mbedtls_x509_crt_restart_ctx *ctx) -{ - mbedtls_pk_restart_init(&ctx->pk); - - ctx->parent = NULL; - ctx->fallback_parent = NULL; - ctx->fallback_signature_is_good = 0; - - ctx->parent_is_trusted = -1; - - ctx->in_progress = x509_crt_rs_none; - ctx->self_cnt = 0; - x509_crt_verify_chain_reset(&ctx->ver_chain); -} - -/* - * Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_pk_restart_free(&ctx->pk); - mbedtls_x509_crt_restart_init(ctx); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt) -{ - if ((crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) != 0) { - return crt->MBEDTLS_PRIVATE(ca_istrue); - } - return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; -} - -#endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/vendor/mbedtls/library/x509_csr.c b/vendor/mbedtls/library/x509_csr.c deleted file mode 100644 index 813d64466..000000000 --- a/vendor/mbedtls/library/x509_csr.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * X.509 Certificate Signing Request (CSR) parsing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * The ITU-T X.509 standard defines a certificate format for PKI. - * - * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) - * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) - * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) - * - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf - * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf - */ - -#include "common.h" - -#if defined(MBEDTLS_X509_CSR_PARSE_C) - -#include "mbedtls/x509_csr.h" -#include "x509_internal.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#include "mbedtls/platform.h" - -#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) -#include -#endif - -/* - * Version ::= INTEGER { v1(0) } - */ -static int x509_csr_get_version(unsigned char **p, - const unsigned char *end, - int *ver) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - *ver = 0; - return 0; - } - - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret); - } - - return 0; -} - -/* - * Parse CSR extension requests in DER format - */ -static int x509_csr_parse_extensions(mbedtls_x509_csr *csr, - unsigned char **p, const unsigned char *end, - mbedtls_x509_csr_ext_cb_t cb, - void *p_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - unsigned char *end_ext_data, *end_ext_octet; - - while (*p < end) { - mbedtls_x509_buf extn_oid = { 0, 0, NULL }; - int is_critical = 0; /* DEFAULT FALSE */ - int ext_type = 0; - - /* Read sequence tag */ - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - end_ext_data = *p + len; - - /* Get extension ID */ - if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len, - MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - extn_oid.tag = MBEDTLS_ASN1_OID; - extn_oid.p = *p; - *p += extn_oid.len; - - /* Get optional critical */ - if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 && - (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - /* Data should be octet string type */ - if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - end_ext_octet = *p + len; - - if (end_ext_octet != end_ext_data) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* - * Detect supported extensions and skip unsupported extensions - */ - ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type); - - if (ret != 0) { - /* Give the callback (if any) a chance to handle the extension */ - if (cb != NULL) { - ret = cb(p_ctx, csr, &extn_oid, is_critical, *p, end_ext_octet); - if (ret != 0 && is_critical) { - return ret; - } - *p = end_ext_octet; - continue; - } - - /* No parser found, skip extension */ - *p = end_ext_octet; - - if (is_critical) { - /* Data is marked as critical: fail */ - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); - } - continue; - } - - /* Forbid repeated extensions */ - if ((csr->ext_types & ext_type) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_INVALID_DATA); - } - - csr->ext_types |= ext_type; - - switch (ext_type) { - case MBEDTLS_X509_EXT_KEY_USAGE: - /* Parse key usage */ - if ((ret = mbedtls_x509_get_key_usage(p, end_ext_data, - &csr->key_usage)) != 0) { - return ret; - } - break; - - case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: - /* Parse subject alt name */ - if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_data, - &csr->subject_alt_names)) != 0) { - return ret; - } - break; - - case MBEDTLS_X509_EXT_NS_CERT_TYPE: - /* Parse netscape certificate type */ - if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_data, - &csr->ns_cert_type)) != 0) { - return ret; - } - break; - default: - /* - * If this is a non-critical extension, which the oid layer - * supports, but there isn't an x509 parser for it, - * skip the extension. - */ - if (is_critical) { - return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } else { - *p = end_ext_octet; - } - } - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Parse CSR attributes in DER format - */ -static int x509_csr_parse_attributes(mbedtls_x509_csr *csr, - const unsigned char *start, const unsigned char *end, - mbedtls_x509_csr_ext_cb_t cb, - void *p_ctx) -{ - int ret; - size_t len; - unsigned char *end_attr_data; - unsigned char **p = (unsigned char **) &start; - - while (*p < end) { - mbedtls_x509_buf attr_oid = { 0, 0, NULL }; - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - end_attr_data = *p + len; - - /* Get attribute ID */ - if ((ret = mbedtls_asn1_get_tag(p, end_attr_data, &attr_oid.len, - MBEDTLS_ASN1_OID)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - attr_oid.tag = MBEDTLS_ASN1_OID; - attr_oid.p = *p; - *p += attr_oid.len; - - /* Check that this is an extension-request attribute */ - if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS9_CSR_EXT_REQ, &attr_oid) == 0) { - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != - 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret); - } - - if ((ret = x509_csr_parse_extensions(csr, p, *p + len, cb, p_ctx)) != 0) { - return ret; - } - - if (*p != end_attr_data) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - } - - *p = end_attr_data; - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Parse a CSR in DER format - */ -static int mbedtls_x509_csr_parse_der_internal(mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen, - mbedtls_x509_csr_ext_cb_t cb, - void *p_ctx) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; - unsigned char *p, *end; - mbedtls_x509_buf sig_params; - - memset(&sig_params, 0, sizeof(mbedtls_x509_buf)); - - /* - * Check for valid input - */ - if (csr == NULL || buf == NULL || buflen == 0) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - mbedtls_x509_csr_init(csr); - - /* - * first copy the raw DER data - */ - p = mbedtls_calloc(1, len = buflen); - - if (p == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - memcpy(p, buf, buflen); - - csr->raw.p = p; - csr->raw.len = len; - end = p + len; - - /* - * CertificationRequest ::= SEQUENCE { - * certificationRequestInfo CertificationRequestInfo, - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING - * } - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERR_X509_INVALID_FORMAT; - } - - if (len != (size_t) (end - p)) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - /* - * CertificationRequestInfo ::= SEQUENCE { - */ - csr->cri.p = p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - end = p + len; - csr->cri.len = (size_t) (end - csr->cri.p); - - /* - * Version ::= INTEGER { v1(0) } - */ - if ((ret = x509_csr_get_version(&p, end, &csr->version)) != 0) { - mbedtls_x509_csr_free(csr); - return ret; - } - - if (csr->version != 0) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERR_X509_UNKNOWN_VERSION; - } - - csr->version++; - - /* - * subject Name - */ - csr->subject_raw.p = p; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - if ((ret = mbedtls_x509_get_name(&p, p + len, &csr->subject)) != 0) { - mbedtls_x509_csr_free(csr); - return ret; - } - - csr->subject_raw.len = (size_t) (p - csr->subject_raw.p); - - /* - * subjectPKInfo SubjectPublicKeyInfo - */ - if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &csr->pk)) != 0) { - mbedtls_x509_csr_free(csr); - return ret; - } - - /* - * attributes [0] Attributes - * - * The list of possible attributes is open-ended, though RFC 2985 - * (PKCS#9) defines a few in section 5.4. We currently don't support any, - * so we just ignore them. This is a safe thing to do as the worst thing - * that could happen is that we issue a certificate that does not match - * the requester's expectations - this cannot cause a violation of our - * signature policies. - */ - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) != - 0) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); - } - - if ((ret = x509_csr_parse_attributes(csr, p, p + len, cb, p_ctx)) != 0) { - mbedtls_x509_csr_free(csr); - return ret; - } - - p += len; - - end = csr->raw.p + csr->raw.len; - - /* - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING - */ - if ((ret = mbedtls_x509_get_alg(&p, end, &csr->sig_oid, &sig_params)) != 0) { - mbedtls_x509_csr_free(csr); - return ret; - } - - if ((ret = mbedtls_x509_get_sig_alg(&csr->sig_oid, &sig_params, - &csr->sig_md, &csr->sig_pk, - &csr->sig_opts)) != 0) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG; - } - - if ((ret = mbedtls_x509_get_sig(&p, end, &csr->sig)) != 0) { - mbedtls_x509_csr_free(csr); - return ret; - } - - if (p != end) { - mbedtls_x509_csr_free(csr); - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - - return 0; -} - -/* - * Parse a CSR in DER format - */ -int mbedtls_x509_csr_parse_der(mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen) -{ - return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, NULL, NULL); -} - -/* - * Parse a CSR in DER format with callback for unknown extensions - */ -int mbedtls_x509_csr_parse_der_with_ext_cb(mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen, - mbedtls_x509_csr_ext_cb_t cb, - void *p_ctx) -{ - return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, cb, p_ctx); -} - -/* - * Parse a CSR, allowing for PEM or raw DER encoding - */ -int mbedtls_x509_csr_parse(mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen) -{ -#if defined(MBEDTLS_PEM_PARSE_C) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t use_len; - mbedtls_pem_context pem; -#endif - - /* - * Check for valid input - */ - if (csr == NULL || buf == NULL || buflen == 0) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - -#if defined(MBEDTLS_PEM_PARSE_C) - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if (buf[buflen - 1] == '\0') { - mbedtls_pem_init(&pem); - ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN CERTIFICATE REQUEST-----", - "-----END CERTIFICATE REQUEST-----", - buf, NULL, 0, &use_len); - if (ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN NEW CERTIFICATE REQUEST-----", - "-----END NEW CERTIFICATE REQUEST-----", - buf, NULL, 0, &use_len); - } - - if (ret == 0) { - /* - * Was PEM encoded, parse the result - */ - ret = mbedtls_x509_csr_parse_der(csr, pem.buf, pem.buflen); - } - - mbedtls_pem_free(&pem); - if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { - return ret; - } - } -#endif /* MBEDTLS_PEM_PARSE_C */ - return mbedtls_x509_csr_parse_der(csr, buf, buflen); -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load a CSR into the structure - */ -int mbedtls_x509_csr_parse_file(mbedtls_x509_csr *csr, const char *path) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - unsigned char *buf; - - if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) { - return ret; - } - - ret = mbedtls_x509_csr_parse(csr, buf, n); - - mbedtls_zeroize_and_free(buf, n); - - return ret; -} -#endif /* MBEDTLS_FS_IO */ - -#if !defined(MBEDTLS_X509_REMOVE_INFO) -#define BEFORE_COLON 14 -#define BC "14" -/* - * Return an informational string about the CSR. - */ -int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix, - const mbedtls_x509_csr *csr) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - char *p; - char key_size_str[BEFORE_COLON]; - - p = buf; - n = size; - - ret = mbedtls_snprintf(p, n, "%sCSR version : %d", - prefix, csr->version); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%ssubject name : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets(p, n, &csr->subject); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_sig_alg_gets(p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, - csr->sig_opts); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON, - mbedtls_pk_get_name(&csr->pk))) != 0) { - return ret; - } - - ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen(&csr->pk)); - MBEDTLS_X509_SAFE_SNPRINTF; - - /* - * Optional extensions - */ - - if (csr->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) { - ret = mbedtls_snprintf(p, n, "\n%ssubject alt name :", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n, - &csr->subject_alt_names, - prefix)) != 0) { - return ret; - } - } - - if (csr->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) { - ret = mbedtls_snprintf(p, n, "\n%scert. type : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = mbedtls_x509_info_cert_type(&p, &n, csr->ns_cert_type)) != 0) { - return ret; - } - } - - if (csr->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) { - ret = mbedtls_snprintf(p, n, "\n%skey usage : ", prefix); - MBEDTLS_X509_SAFE_SNPRINTF; - - if ((ret = mbedtls_x509_info_key_usage(&p, &n, csr->key_usage)) != 0) { - return ret; - } - } - - if (csr->ext_types != 0) { - ret = mbedtls_snprintf(p, n, "\n"); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return (int) (size - n); -} -#endif /* MBEDTLS_X509_REMOVE_INFO */ - -/* - * Initialize a CSR - */ -void mbedtls_x509_csr_init(mbedtls_x509_csr *csr) -{ - memset(csr, 0, sizeof(mbedtls_x509_csr)); -} - -/* - * Unallocate all CSR data - */ -void mbedtls_x509_csr_free(mbedtls_x509_csr *csr) -{ - if (csr == NULL) { - return; - } - - mbedtls_pk_free(&csr->pk); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free(csr->sig_opts); -#endif - - mbedtls_asn1_free_named_data_list_shallow(csr->subject.next); - mbedtls_asn1_sequence_free(csr->subject_alt_names.next); - - if (csr->raw.p != NULL) { - mbedtls_zeroize_and_free(csr->raw.p, csr->raw.len); - } - - mbedtls_platform_zeroize(csr, sizeof(mbedtls_x509_csr)); -} - -#endif /* MBEDTLS_X509_CSR_PARSE_C */ diff --git a/vendor/mbedtls/library/x509_internal.h b/vendor/mbedtls/library/x509_internal.h deleted file mode 100644 index 8a2d2ed00..000000000 --- a/vendor/mbedtls/library/x509_internal.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * \file x509.h - * - * \brief Internal part of the public "x509.h". - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#ifndef MBEDTLS_X509_INTERNAL_H -#define MBEDTLS_X509_INTERNAL_H -#include "mbedtls/private_access.h" - -#include "mbedtls/build_info.h" - -#include "mbedtls/x509.h" -#include "mbedtls/asn1.h" -#include "pk_internal.h" - -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif - -int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur); -int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg); -int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params); -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params, - mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, - int *salt_len); -#endif -int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig); -int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, - void **sig_opts); -int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end, - mbedtls_x509_time *t); -int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial); -int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag); -#if !defined(MBEDTLS_X509_REMOVE_INFO) -int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts); -#endif -int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name); -int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, - int critical, const unsigned char *val, - size_t val_len); -int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first); -int mbedtls_x509_write_names(unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first); -int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - unsigned char *sig, size_t size, - mbedtls_pk_type_t pk_alg); -int mbedtls_x509_get_ns_cert_type(unsigned char **p, - const unsigned char *end, - unsigned char *ns_cert_type); -int mbedtls_x509_get_key_usage(unsigned char **p, - const unsigned char *end, - unsigned int *key_usage); -int mbedtls_x509_get_subject_alt_name(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name); -int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name); -int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size, - const mbedtls_x509_sequence - *subject_alt_name, - const char *prefix); -int mbedtls_x509_info_cert_type(char **buf, size_t *size, - unsigned char ns_cert_type); -int mbedtls_x509_info_key_usage(char **buf, size_t *size, - unsigned int key_usage); - -int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions, - const mbedtls_x509_san_list *san_list); - -#endif /* MBEDTLS_X509_INTERNAL_H */ diff --git a/vendor/mbedtls/library/x509write.c b/vendor/mbedtls/library/x509write.c deleted file mode 100644 index 4704900d3..000000000 --- a/vendor/mbedtls/library/x509write.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * X.509 internal, common functions for writing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -#include "common.h" -#if defined(MBEDTLS_X509_CSR_WRITE_C) || defined(MBEDTLS_X509_CRT_WRITE_C) - -#include "mbedtls/x509_crt.h" -#include "x509_internal.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" - -#include -#include - -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif /* MBEDTLS_PEM_WRITE_C */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#include "md_psa.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#define CHECK_OVERFLOW_ADD(a, b) \ - do \ - { \ - if (a > SIZE_MAX - (b)) \ - { \ - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; \ - } \ - a += b; \ - } while (0) - -int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions, - const mbedtls_x509_san_list *san_list) -{ - int ret = 0; - const mbedtls_x509_san_list *cur; - unsigned char *buf; - unsigned char *p; - size_t len; - size_t buflen = 0; - - /* Determine the maximum size of the SubjectAltName list */ - for (cur = san_list; cur != NULL; cur = cur->next) { - /* Calculate size of the required buffer */ - switch (cur->node.type) { - case MBEDTLS_X509_SAN_DNS_NAME: - case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: - case MBEDTLS_X509_SAN_IP_ADDRESS: - case MBEDTLS_X509_SAN_RFC822_NAME: - /* length of value for each name entry, - * maximum 4 bytes for the length field, - * 1 byte for the tag/type. - */ - CHECK_OVERFLOW_ADD(buflen, cur->node.san.unstructured_name.len); - CHECK_OVERFLOW_ADD(buflen, 4 + 1); - break; - case MBEDTLS_X509_SAN_DIRECTORY_NAME: - { - const mbedtls_asn1_named_data *chunk = &cur->node.san.directory_name; - while (chunk != NULL) { - // Max 4 bytes for length, +1 for tag, - // additional 4 max for length, +1 for tag. - // See x509_write_name for more information. - CHECK_OVERFLOW_ADD(buflen, 4 + 1 + 4 + 1); - CHECK_OVERFLOW_ADD(buflen, chunk->oid.len); - CHECK_OVERFLOW_ADD(buflen, chunk->val.len); - chunk = chunk->next; - } - CHECK_OVERFLOW_ADD(buflen, 4 + 1); - break; - } - default: - /* Not supported - return. */ - return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } - } - - /* Add the extra length field and tag */ - CHECK_OVERFLOW_ADD(buflen, 4 + 1); - - /* Allocate buffer */ - buf = mbedtls_calloc(1, buflen); - if (buf == NULL) { - return MBEDTLS_ERR_ASN1_ALLOC_FAILED; - } - p = buf + buflen; - - /* Write ASN.1-based structure */ - cur = san_list; - len = 0; - while (cur != NULL) { - size_t single_san_len = 0; - switch (cur->node.type) { - case MBEDTLS_X509_SAN_DNS_NAME: - case MBEDTLS_X509_SAN_RFC822_NAME: - case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: - case MBEDTLS_X509_SAN_IP_ADDRESS: - { - const unsigned char *unstructured_name = - (const unsigned char *) cur->node.san.unstructured_name.p; - size_t unstructured_name_len = cur->node.san.unstructured_name.len; - - MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, - mbedtls_asn1_write_raw_buffer( - &p, buf, - unstructured_name, unstructured_name_len)); - MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, mbedtls_asn1_write_len( - &p, buf, unstructured_name_len)); - MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, - mbedtls_asn1_write_tag( - &p, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | cur->node.type)); - } - break; - case MBEDTLS_X509_SAN_DIRECTORY_NAME: - MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, - mbedtls_x509_write_names(&p, buf, - (mbedtls_asn1_named_data *) & - cur->node - .san.directory_name)); - MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, - mbedtls_asn1_write_len(&p, buf, single_san_len)); - MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, - mbedtls_asn1_write_tag(&p, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_X509_SAN_DIRECTORY_NAME)); - break; - default: - /* Error out on an unsupported SAN */ - ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - goto cleanup; - } - cur = cur->next; - /* check for overflow */ - if (len > SIZE_MAX - single_san_len) { - ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; - goto cleanup; - } - len += single_san_len; - } - - MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf, len)); - MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, - mbedtls_asn1_write_tag(&p, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - ret = mbedtls_x509_set_extension(extensions, - MBEDTLS_OID_SUBJECT_ALT_NAME, - MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME), - 0, - buf + buflen - len, len); - - /* If we exceeded the allocated buffer it means that maximum size of the SubjectAltName list - * was incorrectly calculated and memory is corrupted. */ - if (p < buf) { - ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - } -cleanup: - mbedtls_free(buf); - return ret; -} - -#endif /* MBEDTLS_X509_CSR_WRITE_C || MBEDTLS_X509_CRT_WRITE_C */ diff --git a/vendor/mbedtls/library/x509write_crt.c b/vendor/mbedtls/library/x509write_crt.c deleted file mode 100644 index d829ffe60..000000000 --- a/vendor/mbedtls/library/x509write_crt.c +++ /dev/null @@ -1,688 +0,0 @@ -/* - * X.509 certificate writing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * References: - * - certificates: RFC 5280, updated by RFC 6818 - * - CSRs: PKCS#10 v1.7 aka RFC 2986 - * - attributes: PKCS#9 v2.0 aka RFC 2985 - */ - -#include "common.h" - -#if defined(MBEDTLS_X509_CRT_WRITE_C) - -#include "mbedtls/x509_crt.h" -#include "x509_internal.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform.h" -#include "mbedtls/platform_util.h" -#include "mbedtls/md.h" - -#include -#include - -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif /* MBEDTLS_PEM_WRITE_C */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "psa_util_internal.h" -#include "mbedtls/psa_util.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_x509write_cert)); - - ctx->version = MBEDTLS_X509_CRT_VERSION_3; -} - -void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_asn1_free_named_data_list(&ctx->subject); - mbedtls_asn1_free_named_data_list(&ctx->issuer); - mbedtls_asn1_free_named_data_list(&ctx->extensions); - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_x509write_cert)); -} - -void mbedtls_x509write_crt_set_version(mbedtls_x509write_cert *ctx, - int version) -{ - ctx->version = version; -} - -void mbedtls_x509write_crt_set_md_alg(mbedtls_x509write_cert *ctx, - mbedtls_md_type_t md_alg) -{ - ctx->md_alg = md_alg; -} - -void mbedtls_x509write_crt_set_subject_key(mbedtls_x509write_cert *ctx, - mbedtls_pk_context *key) -{ - ctx->subject_key = key; -} - -void mbedtls_x509write_crt_set_issuer_key(mbedtls_x509write_cert *ctx, - mbedtls_pk_context *key) -{ - ctx->issuer_key = key; -} - -int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx, - const char *subject_name) -{ - mbedtls_asn1_free_named_data_list(&ctx->subject); - return mbedtls_x509_string_to_names(&ctx->subject, subject_name); -} - -int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx, - const char *issuer_name) -{ - mbedtls_asn1_free_named_data_list(&ctx->issuer); - return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name); -} - -#if defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_x509write_crt_set_serial(mbedtls_x509write_cert *ctx, - const mbedtls_mpi *serial) -{ - int ret; - size_t tmp_len; - - /* Ensure that the MPI value fits into the buffer */ - tmp_len = mbedtls_mpi_size(serial); - if (tmp_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - ctx->serial_len = tmp_len; - - ret = mbedtls_mpi_write_binary(serial, ctx->serial, tmp_len); - if (ret < 0) { - return ret; - } - - return 0; -} -#endif // MBEDTLS_BIGNUM_C && !MBEDTLS_DEPRECATED_REMOVED - -int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx, - unsigned char *serial, size_t serial_len) -{ - if (serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - ctx->serial_len = serial_len; - memcpy(ctx->serial, serial, serial_len); - - return 0; -} - -int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx, - const char *not_before, - const char *not_after) -{ - if (strlen(not_before) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || - strlen(not_after) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - strncpy(ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN); - strncpy(ctx->not_after, not_after, MBEDTLS_X509_RFC5280_UTC_TIME_LEN); - ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; - ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; - - return 0; -} - -int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx, - const mbedtls_x509_san_list *san_list) -{ - return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list); -} - - -int mbedtls_x509write_crt_set_extension(mbedtls_x509write_cert *ctx, - const char *oid, size_t oid_len, - int critical, - const unsigned char *val, size_t val_len) -{ - return mbedtls_x509_set_extension(&ctx->extensions, oid, oid_len, - critical, val, val_len); -} - -int mbedtls_x509write_crt_set_basic_constraints(mbedtls_x509write_cert *ctx, - int is_ca, int max_pathlen) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char buf[9]; - unsigned char *c = buf + sizeof(buf); - size_t len = 0; - - memset(buf, 0, sizeof(buf)); - - if (is_ca && max_pathlen > 127) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - if (is_ca) { - if (max_pathlen >= 0) { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, - max_pathlen)); - } - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_bool(&c, buf, 1)); - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return - mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, - MBEDTLS_OID_SIZE(MBEDTLS_OID_BASIC_CONSTRAINTS), - is_ca, buf + sizeof(buf) - len, len); -} - -#if defined(MBEDTLS_MD_CAN_SHA1) -static int mbedtls_x509write_crt_set_key_identifier(mbedtls_x509write_cert *ctx, - int is_ca, - unsigned char tag) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ - unsigned char *c = buf + sizeof(buf); - size_t len = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t hash_length; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - memset(buf, 0, sizeof(buf)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_pk_write_pubkey(&c, - buf, - is_ca ? - ctx->issuer_key : - ctx->subject_key)); - - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - status = psa_hash_compute(PSA_ALG_SHA_1, - buf + sizeof(buf) - len, - len, - buf + sizeof(buf) - 20, - 20, - &hash_length); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } -#else - ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), - buf + sizeof(buf) - len, len, - buf + sizeof(buf) - 20); - if (ret != 0) { - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - c = buf + sizeof(buf) - 20; - len = 20; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, tag)); - - if (is_ca) { // writes AuthorityKeyIdentifier sequence - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, - buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - } - - if (is_ca) { - return mbedtls_x509write_crt_set_extension(ctx, - MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE( - MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER), - 0, buf + sizeof(buf) - len, len); - } else { - return mbedtls_x509write_crt_set_extension(ctx, - MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, - MBEDTLS_OID_SIZE( - MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER), - 0, buf + sizeof(buf) - len, len); - } -} - -int mbedtls_x509write_crt_set_subject_key_identifier(mbedtls_x509write_cert *ctx) -{ - return mbedtls_x509write_crt_set_key_identifier(ctx, - 0, - MBEDTLS_ASN1_OCTET_STRING); -} - -int mbedtls_x509write_crt_set_authority_key_identifier(mbedtls_x509write_cert *ctx) -{ - return mbedtls_x509write_crt_set_key_identifier(ctx, - 1, - (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0)); -} -#endif /* MBEDTLS_MD_CAN_SHA1 */ - -int mbedtls_x509write_crt_set_key_usage(mbedtls_x509write_cert *ctx, - unsigned int key_usage) -{ - unsigned char buf[5] = { 0 }, ku[2] = { 0 }; - unsigned char *c; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE | - MBEDTLS_X509_KU_NON_REPUDIATION | - MBEDTLS_X509_KU_KEY_ENCIPHERMENT | - MBEDTLS_X509_KU_DATA_ENCIPHERMENT | - MBEDTLS_X509_KU_KEY_AGREEMENT | - MBEDTLS_X509_KU_KEY_CERT_SIGN | - MBEDTLS_X509_KU_CRL_SIGN | - MBEDTLS_X509_KU_ENCIPHER_ONLY | - MBEDTLS_X509_KU_DECIPHER_ONLY; - - /* Check that nothing other than the allowed flags is set */ - if ((key_usage & ~allowed_bits) != 0) { - return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; - } - - c = buf + 5; - MBEDTLS_PUT_UINT16_LE(key_usage, ku, 0); - ret = mbedtls_asn1_write_named_bitstring(&c, buf, ku, 9); - - if (ret < 0) { - return ret; - } else if (ret < 3 || ret > 5) { - return MBEDTLS_ERR_X509_INVALID_FORMAT; - } - - ret = mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_KEY_USAGE, - MBEDTLS_OID_SIZE(MBEDTLS_OID_KEY_USAGE), - 1, c, (size_t) ret); - if (ret != 0) { - return ret; - } - - return 0; -} - -int mbedtls_x509write_crt_set_ext_key_usage(mbedtls_x509write_cert *ctx, - const mbedtls_asn1_sequence *exts) -{ - unsigned char buf[256]; - unsigned char *c = buf + sizeof(buf); - int ret; - size_t len = 0; - const mbedtls_asn1_sequence *last_ext = NULL; - const mbedtls_asn1_sequence *ext; - - memset(buf, 0, sizeof(buf)); - - /* We need at least one extension: SEQUENCE SIZE (1..MAX) OF KeyPurposeId */ - if (exts == NULL) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - - /* Iterate over exts backwards, so we write them out in the requested order */ - while (last_ext != exts) { - for (ext = exts; ext->next != last_ext; ext = ext->next) { - } - if (ext->buf.tag != MBEDTLS_ASN1_OID) { - return MBEDTLS_ERR_X509_BAD_INPUT_DATA; - } - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, ext->buf.p, ext->buf.len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, ext->buf.len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_OID)); - last_ext = ext; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - - return mbedtls_x509write_crt_set_extension(ctx, - MBEDTLS_OID_EXTENDED_KEY_USAGE, - MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE), - 1, c, len); -} - -int mbedtls_x509write_crt_set_ns_cert_type(mbedtls_x509write_cert *ctx, - unsigned char ns_cert_type) -{ - unsigned char buf[4] = { 0 }; - unsigned char *c; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - c = buf + 4; - - ret = mbedtls_asn1_write_named_bitstring(&c, buf, &ns_cert_type, 8); - if (ret < 3 || ret > 4) { - return ret; - } - - ret = mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_NS_CERT_TYPE, - MBEDTLS_OID_SIZE(MBEDTLS_OID_NS_CERT_TYPE), - 0, c, (size_t) ret); - if (ret != 0) { - return ret; - } - - return 0; -} - -static int x509_write_time(unsigned char **p, unsigned char *start, - const char *t, size_t size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - /* - * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) - */ - if (t[0] < '2' || (t[0] == '2' && t[1] == '0' && t[2] < '5')) { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, - (const unsigned char *) t + 2, - size - 2)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, - MBEDTLS_ASN1_UTC_TIME)); - } else { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, - (const unsigned char *) t, - size)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, - MBEDTLS_ASN1_GENERALIZED_TIME)); - } - - return (int) len; -} - -int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, - unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const char *sig_oid; - size_t sig_oid_len = 0; - unsigned char *c, *c2; - unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; - size_t hash_length = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_algorithm_t psa_algorithm; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; - size_t len = 0; - mbedtls_pk_type_t pk_alg; - int write_sig_null_par; - - /* - * Prepare data to be signed at the end of the target buffer - */ - c = buf + size; - - /* Signature algorithm needed in TBS, and later for actual signature */ - - /* There's no direct way of extracting a signature algorithm - * (represented as an element of mbedtls_pk_type_t) from a PK instance. */ - if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_RSA)) { - pk_alg = MBEDTLS_PK_RSA; - } else if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_ECDSA)) { - pk_alg = MBEDTLS_PK_ECDSA; - } else { - return MBEDTLS_ERR_X509_INVALID_ALG; - } - - if ((ret = mbedtls_oid_get_oid_by_sig_alg(pk_alg, ctx->md_alg, - &sig_oid, &sig_oid_len)) != 0) { - return ret; - } - - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - */ - - /* Only for v3 */ - if (ctx->version == MBEDTLS_X509_CRT_VERSION_3) { - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_x509_write_extensions(&c, - buf, ctx->extensions)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 3)); - } - - /* - * SubjectPublicKeyInfo - */ - MBEDTLS_ASN1_CHK_ADD(pub_len, - mbedtls_pk_write_pubkey_der(ctx->subject_key, - buf, (size_t) (c - buf))); - c -= pub_len; - len += pub_len; - - /* - * Subject ::= Name - */ - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_x509_write_names(&c, buf, - ctx->subject)); - - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - */ - sub_len = 0; - - MBEDTLS_ASN1_CHK_ADD(sub_len, - x509_write_time(&c, buf, ctx->not_after, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); - - MBEDTLS_ASN1_CHK_ADD(sub_len, - x509_write_time(&c, buf, ctx->not_before, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); - - len += sub_len; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, sub_len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - /* - * Issuer ::= Name - */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf, - ctx->issuer)); - - /* - * Signature ::= AlgorithmIdentifier - */ - if (pk_alg == MBEDTLS_PK_ECDSA) { - /* - * The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature - * algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and - * https://www.rfc-editor.org/rfc/rfc5758#section-3. - */ - write_sig_null_par = 0; - } else { - write_sig_null_par = 1; - } - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_algorithm_identifier_ext(&c, buf, - sig_oid, strlen(sig_oid), - 0, write_sig_null_par)); - - /* - * Serial ::= INTEGER - * - * Written data is: - * - "ctx->serial_len" bytes for the raw serial buffer - * - if MSb of "serial" is 1, then prepend an extra 0x00 byte - * - 1 byte for the length - * - 1 byte for the TAG - */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, - ctx->serial, ctx->serial_len)); - if (*c & 0x80) { - if (c - buf < 1) { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - *(--c) = 0x0; - len++; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, - ctx->serial_len + 1)); - } else { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, - ctx->serial_len)); - } - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_INTEGER)); - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - - /* Can be omitted for v1 */ - if (ctx->version != MBEDTLS_X509_CRT_VERSION_1) { - sub_len = 0; - MBEDTLS_ASN1_CHK_ADD(sub_len, - mbedtls_asn1_write_int(&c, buf, ctx->version)); - len += sub_len; - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_len(&c, buf, sub_len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 0)); - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - /* - * Make signature - */ - - /* Compute hash of CRT. */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_algorithm = mbedtls_md_psa_alg_from_type(ctx->md_alg); - - status = psa_hash_compute(psa_algorithm, - c, - len, - hash, - sizeof(hash), - &hash_length); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } -#else - if ((ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, - len, hash)) != 0) { - return ret; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - - if ((ret = mbedtls_pk_sign(ctx->issuer_key, ctx->md_alg, - hash, hash_length, sig, sizeof(sig), &sig_len, - f_rng, p_rng)) != 0) { - return ret; - } - - /* Move CRT to the front of the buffer to have space - * for the signature. */ - memmove(buf, c, len); - c = buf + len; - - /* Add signature at the end of the buffer, - * making sure that it doesn't underflow - * into the CRT buffer. */ - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len, mbedtls_x509_write_sig(&c2, c, - sig_oid, sig_oid_len, - sig, sig_len, pk_alg)); - - /* - * Memory layout after this step: - * - * buf c=buf+len c2 buf+size - * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] - */ - - /* Move raw CRT to just before the signature. */ - c = c2 - len; - memmove(c, buf, len); - - len += sig_and_oid_len; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} - -#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" -#define PEM_END_CRT "-----END CERTIFICATE-----\n" - -#if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *crt, - unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen; - - if ((ret = mbedtls_x509write_crt_der(crt, buf, size, - f_rng, p_rng)) < 0) { - return ret; - } - - if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT, - buf + size - ret, ret, - buf, size, &olen)) != 0) { - return ret; - } - - return 0; -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_X509_CRT_WRITE_C */ diff --git a/vendor/mbedtls/library/x509write_csr.c b/vendor/mbedtls/library/x509write_csr.c deleted file mode 100644 index 75bd8f044..000000000 --- a/vendor/mbedtls/library/x509write_csr.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * X.509 Certificate Signing Request writing - * - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ -/* - * References: - * - CSRs: PKCS#10 v1.7 aka RFC 2986 - * - attributes: PKCS#9 v2.0 aka RFC 2985 - */ - -#include "common.h" - -#if defined(MBEDTLS_X509_CSR_WRITE_C) - -#include "x509_internal.h" -#include "mbedtls/x509_csr.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "psa_util_internal.h" -#include "mbedtls/psa_util.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#include -#include - -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -#include "mbedtls/platform.h" - -void mbedtls_x509write_csr_init(mbedtls_x509write_csr *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_x509write_csr)); -} - -void mbedtls_x509write_csr_free(mbedtls_x509write_csr *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_asn1_free_named_data_list(&ctx->subject); - mbedtls_asn1_free_named_data_list(&ctx->extensions); - - mbedtls_platform_zeroize(ctx, sizeof(mbedtls_x509write_csr)); -} - -void mbedtls_x509write_csr_set_md_alg(mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg) -{ - ctx->md_alg = md_alg; -} - -void mbedtls_x509write_csr_set_key(mbedtls_x509write_csr *ctx, mbedtls_pk_context *key) -{ - ctx->key = key; -} - -int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx, - const char *subject_name) -{ - mbedtls_asn1_free_named_data_list(&ctx->subject); - return mbedtls_x509_string_to_names(&ctx->subject, subject_name); -} - -int mbedtls_x509write_csr_set_extension(mbedtls_x509write_csr *ctx, - const char *oid, size_t oid_len, - int critical, - const unsigned char *val, size_t val_len) -{ - return mbedtls_x509_set_extension(&ctx->extensions, oid, oid_len, - critical, val, val_len); -} - -int mbedtls_x509write_csr_set_subject_alternative_name(mbedtls_x509write_csr *ctx, - const mbedtls_x509_san_list *san_list) -{ - return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list); -} - -int mbedtls_x509write_csr_set_key_usage(mbedtls_x509write_csr *ctx, unsigned char key_usage) -{ - unsigned char buf[4] = { 0 }; - unsigned char *c; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - c = buf + 4; - - ret = mbedtls_asn1_write_named_bitstring(&c, buf, &key_usage, 8); - if (ret < 3 || ret > 4) { - return ret; - } - - ret = mbedtls_x509write_csr_set_extension(ctx, MBEDTLS_OID_KEY_USAGE, - MBEDTLS_OID_SIZE(MBEDTLS_OID_KEY_USAGE), - 0, c, (size_t) ret); - if (ret != 0) { - return ret; - } - - return 0; -} - -int mbedtls_x509write_csr_set_ns_cert_type(mbedtls_x509write_csr *ctx, - unsigned char ns_cert_type) -{ - unsigned char buf[4] = { 0 }; - unsigned char *c; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - c = buf + 4; - - ret = mbedtls_asn1_write_named_bitstring(&c, buf, &ns_cert_type, 8); - if (ret < 3 || ret > 4) { - return ret; - } - - ret = mbedtls_x509write_csr_set_extension(ctx, MBEDTLS_OID_NS_CERT_TYPE, - MBEDTLS_OID_SIZE(MBEDTLS_OID_NS_CERT_TYPE), - 0, c, (size_t) ret); - if (ret != 0) { - return ret; - } - - return 0; -} - -static int x509write_csr_der_internal(mbedtls_x509write_csr *ctx, - unsigned char *buf, - size_t size, - unsigned char *sig, size_t sig_size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const char *sig_oid; - size_t sig_oid_len = 0; - unsigned char *c, *c2; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - size_t pub_len = 0, sig_and_oid_len = 0, sig_len; - size_t len = 0; - mbedtls_pk_type_t pk_alg; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t hash_len; - psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(ctx->md_alg); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* Write the CSR backwards starting from the end of buf */ - c = buf + size; - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_extensions(&c, buf, - ctx->extensions)); - - if (len) { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)); - - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_oid( - &c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, - MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS9_CSR_EXT_REQ))); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)); - - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_pk_write_pubkey_der(ctx->key, - buf, (size_t) (c - buf))); - c -= pub_len; - len += pub_len; - - /* - * Subject ::= Name - */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf, - ctx->subject)); - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 0)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag( - &c, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - - /* - * Sign the written CSR data into the sig buffer - * Note: hash errors can happen only after an internal error - */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (psa_hash_compute(hash_alg, - c, - len, - hash, - sizeof(hash), - &hash_len) != PSA_SUCCESS) { - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - } -#else /* MBEDTLS_USE_PSA_CRYPTO */ - ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, len, hash); - if (ret != 0) { - return ret; - } -#endif - if ((ret = mbedtls_pk_sign(ctx->key, ctx->md_alg, hash, 0, - sig, sig_size, &sig_len, - f_rng, p_rng)) != 0) { - return ret; - } - - if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_RSA)) { - pk_alg = MBEDTLS_PK_RSA; - } else if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_ECDSA)) { - pk_alg = MBEDTLS_PK_ECDSA; - } else { - return MBEDTLS_ERR_X509_INVALID_ALG; - } - - if ((ret = mbedtls_oid_get_oid_by_sig_alg(pk_alg, ctx->md_alg, - &sig_oid, &sig_oid_len)) != 0) { - return ret; - } - - /* - * Move the written CSR data to the start of buf to create space for - * writing the signature into buf. - */ - memmove(buf, c, len); - - /* - * Write sig and its OID into buf backwards from the end of buf. - * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len - * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed. - */ - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len, - mbedtls_x509_write_sig(&c2, buf + len, sig_oid, sig_oid_len, - sig, sig_len, pk_alg)); - - /* - * Compact the space between the CSR data and signature by moving the - * CSR data to the start of the signature. - */ - c2 -= len; - memmove(c2, buf, len); - - /* ASN encode the total size and tag the CSR data with it. */ - len += sig_and_oid_len; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c2, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag( - &c2, buf, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - - /* Zero the unused bytes at the start of buf */ - memset(buf, 0, (size_t) (c2 - buf)); - - return (int) len; -} - -int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, - size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret; - unsigned char *sig; - - if ((sig = mbedtls_calloc(1, MBEDTLS_PK_SIGNATURE_MAX_SIZE)) == NULL) { - return MBEDTLS_ERR_X509_ALLOC_FAILED; - } - - ret = x509write_csr_der_internal(ctx, buf, size, - sig, MBEDTLS_PK_SIGNATURE_MAX_SIZE, - f_rng, p_rng); - - mbedtls_free(sig); - - return ret; -} - -#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" -#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" - -#if defined(MBEDTLS_PEM_WRITE_C) -int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t olen = 0; - - if ((ret = mbedtls_x509write_csr_der(ctx, buf, size, - f_rng, p_rng)) < 0) { - return ret; - } - - if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CSR, PEM_END_CSR, - buf + size - ret, - ret, buf, size, &olen)) != 0) { - return ret; - } - - return 0; -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_X509_CSR_WRITE_C */ diff --git a/vendor/nghttp2.mask b/vendor/nghttp2.mask deleted file mode 100644 index 434d9fe46..000000000 --- a/vendor/nghttp2.mask +++ /dev/null @@ -1,65 +0,0 @@ -.clang-format -android-config -android-env -author.py -AUTHORS -bpf -ChangeLog -cmake -cmakeconfig.h.in -CMakeLists.txt -CMakeOptions.txt -configure.ac -contrib -CONTRIBUTION -doc -docker -Dockerfile.android -examples -fedora -fuzz -genauthoritychartbl.py -gendowncasetbl.py -genheaderfunc.py -genlibtokenlookup.py -genmethodchartbl.py -genmethodfunc.py -gennghttpxfun.py -gennmchartbl.py -genpathchartbl.py -gentokenlookup.py -genvchartbl.py -git-clang-format -go.mod -go.sum -help2rst.py -integration-tests -lib/CMakeLists.txt -lib/config.cmake.in -lib/libnghttp2.pc.in -lib/Makefile.am -lib/Makefile.msvc -lib/version.rc.in -m4 -makebashcompletion -Makefile.am -makemanpages -makerelease.sh -mkcipherlist.py -mkhufftbl.py -mkstatichdtbl.py -NEWS -nghttpx.conf.sample -pre-commit -proxy.pac.sample -README -README.rst -releasechk -SECURITY.md -src -tests -third-party -lib/.gitignore -lib/includes/CMakeLists.txt -lib/includes/Makefile.am -LICENSE diff --git a/vendor/nghttp2/COPYING b/vendor/nghttp2/COPYING deleted file mode 100644 index 80201792e..000000000 --- a/vendor/nghttp2/COPYING +++ /dev/null @@ -1,23 +0,0 @@ -The MIT License - -Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa -Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/nghttp2/lib/includes/nghttp2/nghttp2.h b/vendor/nghttp2/lib/includes/nghttp2/nghttp2.h deleted file mode 100644 index 19c1874f2..000000000 --- a/vendor/nghttp2/lib/includes/nghttp2/nghttp2.h +++ /dev/null @@ -1,6878 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2013, 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_H -#define NGHTTP2_H - -/* Define WIN32 when build target is Win32 API (borrowed from - libcurl) */ -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif - -/* Compatibility for non-Clang compilers */ -#ifndef __has_declspec_attribute -# define __has_declspec_attribute(x) 0 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#if defined(_MSC_VER) && (_MSC_VER < 1800) -/* MSVC < 2013 does not have inttypes.h because it is not C99 - compliant. See compiler macros and version number in - https://sourceforge.net/p/predef/wiki/Compilers/ */ -# include -#else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ -# include -#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ -#include -#include -#include - -#include - -#ifdef NGHTTP2_STATICLIB -# define NGHTTP2_EXTERN -#elif defined(WIN32) || \ - (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport)) -# ifdef BUILDING_NGHTTP2 -# define NGHTTP2_EXTERN __declspec(dllexport) -# else /* !BUILDING_NGHTTP2 */ -# define NGHTTP2_EXTERN __declspec(dllimport) -# endif /* !BUILDING_NGHTTP2 */ -#else /* !defined(WIN32) */ -# ifdef BUILDING_NGHTTP2 -# define NGHTTP2_EXTERN __attribute__((visibility("default"))) -# else /* !BUILDING_NGHTTP2 */ -# define NGHTTP2_EXTERN -# endif /* !BUILDING_NGHTTP2 */ -#endif /* !defined(WIN32) */ - -#ifdef BUILDING_NGHTTP2 -# undef NGHTTP2_NO_SSIZE_T -#endif /* BUILDING_NGHTTP2 */ - -/** - * @typedef - * - * :type:`nghttp2_ssize` is a signed counterpart of size_t. - */ -typedef ptrdiff_t nghttp2_ssize; - -/** - * @macro - * - * The protocol version identification string of this library - * supports. This identifier is used if HTTP/2 is used over TLS. - */ -#define NGHTTP2_PROTO_VERSION_ID "h2" -/** - * @macro - * - * The length of :macro:`NGHTTP2_PROTO_VERSION_ID`. - */ -#define NGHTTP2_PROTO_VERSION_ID_LEN 2 - -/** - * @macro - * - * The serialized form of ALPN protocol identifier this library - * supports. Notice that first byte is the length of following - * protocol identifier. This is the same wire format of `TLS ALPN - * extension `_. This is useful - * to process incoming ALPN tokens in wire format. - */ -#define NGHTTP2_PROTO_ALPN "\x2h2" - -/** - * @macro - * - * The length of :macro:`NGHTTP2_PROTO_ALPN`. - */ -#define NGHTTP2_PROTO_ALPN_LEN (sizeof(NGHTTP2_PROTO_ALPN) - 1) - -/** - * @macro - * - * The protocol version identification string of this library - * supports. This identifier is used if HTTP/2 is used over cleartext - * TCP. - */ -#define NGHTTP2_CLEARTEXT_PROTO_VERSION_ID "h2c" - -/** - * @macro - * - * The length of :macro:`NGHTTP2_CLEARTEXT_PROTO_VERSION_ID`. - */ -#define NGHTTP2_CLEARTEXT_PROTO_VERSION_ID_LEN 3 - -struct nghttp2_session; -/** - * @struct - * - * The primary structure to hold the resources needed for a HTTP/2 - * session. The details of this structure are intentionally hidden - * from the public API. - */ -typedef struct nghttp2_session nghttp2_session; - -/** - * @macro - * - * The age of :type:`nghttp2_info` - */ -#define NGHTTP2_VERSION_AGE 1 - -/** - * @struct - * - * This struct is what `nghttp2_version()` returns. It holds - * information about the particular nghttp2 version. - */ -typedef struct { - /** - * Age of this struct. This instance of nghttp2 sets it to - * :macro:`NGHTTP2_VERSION_AGE` but a future version may bump it and - * add more struct fields at the bottom - */ - int age; - /** - * the :macro:`NGHTTP2_VERSION_NUM` number (since age ==1) - */ - int version_num; - /** - * points to the :macro:`NGHTTP2_VERSION` string (since age ==1) - */ - const char *version_str; - /** - * points to the :macro:`NGHTTP2_PROTO_VERSION_ID` string this - * instance implements (since age ==1) - */ - const char *proto_str; - /* -------- the above fields all exist when age == 1 */ -} nghttp2_info; - -/** - * @macro - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * The default weight of stream dependency. - */ -#define NGHTTP2_DEFAULT_WEIGHT 16 - -/** - * @macro - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * The maximum weight of stream dependency. - */ -#define NGHTTP2_MAX_WEIGHT 256 - -/** - * @macro - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * The minimum weight of stream dependency. - */ -#define NGHTTP2_MIN_WEIGHT 1 - -/** - * @macro - * - * The maximum window size - */ -#define NGHTTP2_MAX_WINDOW_SIZE ((int32_t)((1U << 31) - 1)) - -/** - * @macro - * - * The initial window size for stream level flow control. - */ -#define NGHTTP2_INITIAL_WINDOW_SIZE ((1 << 16) - 1) -/** - * @macro - * - * The initial window size for connection level flow control. - */ -#define NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE ((1 << 16) - 1) - -/** - * @macro - * - * The default header table size. - */ -#define NGHTTP2_DEFAULT_HEADER_TABLE_SIZE (1 << 12) - -/** - * @macro - * - * The client magic string, which is the first 24 bytes byte string of - * client connection preface. - */ -#define NGHTTP2_CLIENT_MAGIC "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" - -/** - * @macro - * - * The length of :macro:`NGHTTP2_CLIENT_MAGIC`. - */ -#define NGHTTP2_CLIENT_MAGIC_LEN 24 - -/** - * @macro - * - * The default max number of settings per SETTINGS frame - */ -#define NGHTTP2_DEFAULT_MAX_SETTINGS 32 - -/** - * @enum - * - * Error codes used in this library. The code range is [-999, -500], - * inclusive. The following values are defined: - */ -typedef enum { - /** - * Invalid argument passed. - */ - NGHTTP2_ERR_INVALID_ARGUMENT = -501, - /** - * Out of buffer space. - */ - NGHTTP2_ERR_BUFFER_ERROR = -502, - /** - * The specified protocol version is not supported. - */ - NGHTTP2_ERR_UNSUPPORTED_VERSION = -503, - /** - * Used as a return value from :type:`nghttp2_send_callback2`, - * :type:`nghttp2_recv_callback` and - * :type:`nghttp2_send_data_callback` to indicate that the operation - * would block. - */ - NGHTTP2_ERR_WOULDBLOCK = -504, - /** - * General protocol error - */ - NGHTTP2_ERR_PROTO = -505, - /** - * The frame is invalid. - */ - NGHTTP2_ERR_INVALID_FRAME = -506, - /** - * The peer performed a shutdown on the connection. - */ - NGHTTP2_ERR_EOF = -507, - /** - * Used as a return value from - * :func:`nghttp2_data_source_read_callback2` to indicate that data - * transfer is postponed. See - * :func:`nghttp2_data_source_read_callback2` for details. - */ - NGHTTP2_ERR_DEFERRED = -508, - /** - * Stream ID has reached the maximum value. Therefore no stream ID - * is available. - */ - NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE = -509, - /** - * The stream is already closed; or the stream ID is invalid. - */ - NGHTTP2_ERR_STREAM_CLOSED = -510, - /** - * RST_STREAM has been added to the outbound queue. The stream is - * in closing state. - */ - NGHTTP2_ERR_STREAM_CLOSING = -511, - /** - * The transmission is not allowed for this stream (e.g., a frame - * with END_STREAM flag set has already sent). - */ - NGHTTP2_ERR_STREAM_SHUT_WR = -512, - /** - * The stream ID is invalid. - */ - NGHTTP2_ERR_INVALID_STREAM_ID = -513, - /** - * The state of the stream is not valid (e.g., DATA cannot be sent - * to the stream if response HEADERS has not been sent). - */ - NGHTTP2_ERR_INVALID_STREAM_STATE = -514, - /** - * Another DATA frame has already been deferred. - */ - NGHTTP2_ERR_DEFERRED_DATA_EXIST = -515, - /** - * Starting new stream is not allowed (e.g., GOAWAY has been sent - * and/or received). - */ - NGHTTP2_ERR_START_STREAM_NOT_ALLOWED = -516, - /** - * GOAWAY has already been sent. - */ - NGHTTP2_ERR_GOAWAY_ALREADY_SENT = -517, - /** - * The received frame contains the invalid header block (e.g., There - * are duplicate header names; or the header names are not encoded - * in US-ASCII character set and not lower cased; or the header name - * is zero-length string; or the header value contains multiple - * in-sequence NUL bytes). - */ - NGHTTP2_ERR_INVALID_HEADER_BLOCK = -518, - /** - * Indicates that the context is not suitable to perform the - * requested operation. - */ - NGHTTP2_ERR_INVALID_STATE = -519, - /** - * The user callback function failed due to the temporal error. - */ - NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE = -521, - /** - * The length of the frame is invalid, either too large or too small. - */ - NGHTTP2_ERR_FRAME_SIZE_ERROR = -522, - /** - * Header block inflate/deflate error. - */ - NGHTTP2_ERR_HEADER_COMP = -523, - /** - * Flow control error - */ - NGHTTP2_ERR_FLOW_CONTROL = -524, - /** - * Insufficient buffer size given to function. - */ - NGHTTP2_ERR_INSUFF_BUFSIZE = -525, - /** - * Callback was paused by the application - */ - NGHTTP2_ERR_PAUSE = -526, - /** - * There are too many in-flight SETTING frame and no more - * transmission of SETTINGS is allowed. - */ - NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS = -527, - /** - * The server push is disabled. - */ - NGHTTP2_ERR_PUSH_DISABLED = -528, - /** - * DATA or HEADERS frame for a given stream has been already - * submitted and has not been fully processed yet. Application - * should wait for the transmission of the previously submitted - * frame before submitting another. - */ - NGHTTP2_ERR_DATA_EXIST = -529, - /** - * The current session is closing due to a connection error or - * `nghttp2_session_terminate_session()` is called. - */ - NGHTTP2_ERR_SESSION_CLOSING = -530, - /** - * Invalid HTTP header field was received and stream is going to be - * closed. - */ - NGHTTP2_ERR_HTTP_HEADER = -531, - /** - * Violation in HTTP messaging rule. - */ - NGHTTP2_ERR_HTTP_MESSAGING = -532, - /** - * Stream was refused. - */ - NGHTTP2_ERR_REFUSED_STREAM = -533, - /** - * Unexpected internal error, but recovered. - */ - NGHTTP2_ERR_INTERNAL = -534, - /** - * Indicates that a processing was canceled. - */ - NGHTTP2_ERR_CANCEL = -535, - /** - * When a local endpoint expects to receive SETTINGS frame, it - * receives an other type of frame. - */ - NGHTTP2_ERR_SETTINGS_EXPECTED = -536, - /** - * When a local endpoint receives too many settings entries - * in a single SETTINGS frame. - */ - NGHTTP2_ERR_TOO_MANY_SETTINGS = -537, - /** - * The errors < :enum:`nghttp2_error.NGHTTP2_ERR_FATAL` mean that - * the library is under unexpected condition and processing was - * terminated (e.g., out of memory). If application receives this - * error code, it must stop using that :type:`nghttp2_session` - * object and only allowed operation for that object is deallocate - * it using `nghttp2_session_del()`. - */ - NGHTTP2_ERR_FATAL = -900, - /** - * Out of memory. This is a fatal error. - */ - NGHTTP2_ERR_NOMEM = -901, - /** - * The user callback function failed. This is a fatal error. - */ - NGHTTP2_ERR_CALLBACK_FAILURE = -902, - /** - * Invalid client magic (see :macro:`NGHTTP2_CLIENT_MAGIC`) was - * received and further processing is not possible. - */ - NGHTTP2_ERR_BAD_CLIENT_MAGIC = -903, - /** - * Possible flooding by peer was detected in this HTTP/2 session. - * Flooding is measured by how many PING and SETTINGS frames with - * ACK flag set are queued for transmission. These frames are - * response for the peer initiated frames, and peer can cause memory - * exhaustion on server side to send these frames forever and does - * not read network. - */ - NGHTTP2_ERR_FLOODED = -904, - /** - * When a local endpoint receives too many CONTINUATION frames - * following a HEADER frame. - */ - NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905, -} nghttp2_error; - -/** - * @struct - * - * The object representing single contiguous buffer. - */ -typedef struct { - /** - * The pointer to the buffer. - */ - uint8_t *base; - /** - * The length of the buffer. - */ - size_t len; -} nghttp2_vec; - -struct nghttp2_rcbuf; - -/** - * @struct - * - * The object representing reference counted buffer. The details of - * this structure are intentionally hidden from the public API. - */ -typedef struct nghttp2_rcbuf nghttp2_rcbuf; - -/** - * @function - * - * Increments the reference count of |rcbuf| by 1. - */ -NGHTTP2_EXTERN void nghttp2_rcbuf_incref(nghttp2_rcbuf *rcbuf); - -/** - * @function - * - * Decrements the reference count of |rcbuf| by 1. If the reference - * count becomes zero, the object pointed by |rcbuf| will be freed. - * In this case, application must not use |rcbuf| again. - */ -NGHTTP2_EXTERN void nghttp2_rcbuf_decref(nghttp2_rcbuf *rcbuf); - -/** - * @function - * - * Returns the underlying buffer managed by |rcbuf|. - */ -NGHTTP2_EXTERN nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf); - -/** - * @function - * - * Returns nonzero if the underlying buffer is statically allocated, - * and 0 otherwise. This can be useful for language bindings that wish - * to avoid creating duplicate strings for these buffers. - */ -NGHTTP2_EXTERN int nghttp2_rcbuf_is_static(const nghttp2_rcbuf *rcbuf); - -/** - * @enum - * - * The flags for header field name/value pair. - */ -typedef enum { - /** - * No flag set. - */ - NGHTTP2_NV_FLAG_NONE = 0, - /** - * Indicates that this name/value pair must not be indexed ("Literal - * Header Field never Indexed" representation must be used in HPACK - * encoding). Other implementation calls this bit as "sensitive". - */ - NGHTTP2_NV_FLAG_NO_INDEX = 0x01, - /** - * This flag is set solely by application. If this flag is set, the - * library does not make a copy of header field name. This could - * improve performance. - */ - NGHTTP2_NV_FLAG_NO_COPY_NAME = 0x02, - /** - * This flag is set solely by application. If this flag is set, the - * library does not make a copy of header field value. This could - * improve performance. - */ - NGHTTP2_NV_FLAG_NO_COPY_VALUE = 0x04 -} nghttp2_nv_flag; - -/** - * @struct - * - * The name/value pair, which mainly used to represent header fields. - */ -typedef struct { - /** - * The |name| byte string. If this struct is presented from library - * (e.g., :type:`nghttp2_on_frame_recv_callback`), |name| is - * guaranteed to be NULL-terminated. For some callbacks - * (:type:`nghttp2_before_frame_send_callback`, - * :type:`nghttp2_on_frame_send_callback`, and - * :type:`nghttp2_on_frame_not_send_callback`), it may not be - * NULL-terminated if header field is passed from application with - * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`). - * When application is constructing this struct, |name| is not - * required to be NULL-terminated. - */ - uint8_t *name; - /** - * The |value| byte string. If this struct is presented from - * library (e.g., :type:`nghttp2_on_frame_recv_callback`), |value| - * is guaranteed to be NULL-terminated. For some callbacks - * (:type:`nghttp2_before_frame_send_callback`, - * :type:`nghttp2_on_frame_send_callback`, and - * :type:`nghttp2_on_frame_not_send_callback`), it may not be - * NULL-terminated if header field is passed from application with - * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE`). - * When application is constructing this struct, |value| is not - * required to be NULL-terminated. - */ - uint8_t *value; - /** - * The length of the |name|, excluding terminating NULL. - */ - size_t namelen; - /** - * The length of the |value|, excluding terminating NULL. - */ - size_t valuelen; - /** - * Bitwise OR of one or more of :type:`nghttp2_nv_flag`. - */ - uint8_t flags; -} nghttp2_nv; - -/** - * @enum - * - * The frame types in HTTP/2 specification. - */ -typedef enum { - /** - * The DATA frame. - */ - NGHTTP2_DATA = 0, - /** - * The HEADERS frame. - */ - NGHTTP2_HEADERS = 0x01, - /** - * The PRIORITY frame. - */ - NGHTTP2_PRIORITY = 0x02, - /** - * The RST_STREAM frame. - */ - NGHTTP2_RST_STREAM = 0x03, - /** - * The SETTINGS frame. - */ - NGHTTP2_SETTINGS = 0x04, - /** - * The PUSH_PROMISE frame. - */ - NGHTTP2_PUSH_PROMISE = 0x05, - /** - * The PING frame. - */ - NGHTTP2_PING = 0x06, - /** - * The GOAWAY frame. - */ - NGHTTP2_GOAWAY = 0x07, - /** - * The WINDOW_UPDATE frame. - */ - NGHTTP2_WINDOW_UPDATE = 0x08, - /** - * The CONTINUATION frame. This frame type won't be passed to any - * callbacks because the library processes this frame type and its - * preceding HEADERS/PUSH_PROMISE as a single frame. - */ - NGHTTP2_CONTINUATION = 0x09, - /** - * The ALTSVC frame, which is defined in `RFC 7383 - * `_. - */ - NGHTTP2_ALTSVC = 0x0a, - /** - * The ORIGIN frame, which is defined by `RFC 8336 - * `_. - */ - NGHTTP2_ORIGIN = 0x0c, - /** - * The PRIORITY_UPDATE frame, which is defined by :rfc:`9218`. - */ - NGHTTP2_PRIORITY_UPDATE = 0x10 -} nghttp2_frame_type; - -/** - * @enum - * - * The flags for HTTP/2 frames. This enum defines all flags for all - * frames. - */ -typedef enum { - /** - * No flag set. - */ - NGHTTP2_FLAG_NONE = 0, - /** - * The END_STREAM flag. - */ - NGHTTP2_FLAG_END_STREAM = 0x01, - /** - * The END_HEADERS flag. - */ - NGHTTP2_FLAG_END_HEADERS = 0x04, - /** - * The ACK flag. - */ - NGHTTP2_FLAG_ACK = 0x01, - /** - * The PADDED flag. - */ - NGHTTP2_FLAG_PADDED = 0x08, - /** - * The PRIORITY flag. - */ - NGHTTP2_FLAG_PRIORITY = 0x20 -} nghttp2_flag; - -/** - * @enum - * The SETTINGS ID. - */ -typedef enum { - /** - * SETTINGS_HEADER_TABLE_SIZE - */ - NGHTTP2_SETTINGS_HEADER_TABLE_SIZE = 0x01, - /** - * SETTINGS_ENABLE_PUSH - */ - NGHTTP2_SETTINGS_ENABLE_PUSH = 0x02, - /** - * SETTINGS_MAX_CONCURRENT_STREAMS - */ - NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 0x03, - /** - * SETTINGS_INITIAL_WINDOW_SIZE - */ - NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 0x04, - /** - * SETTINGS_MAX_FRAME_SIZE - */ - NGHTTP2_SETTINGS_MAX_FRAME_SIZE = 0x05, - /** - * SETTINGS_MAX_HEADER_LIST_SIZE - */ - NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x06, - /** - * SETTINGS_ENABLE_CONNECT_PROTOCOL - * (`RFC 8441 `_) - */ - NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08, - /** - * SETTINGS_NO_RFC7540_PRIORITIES (:rfc:`9218`) - */ - NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES = 0x09 -} nghttp2_settings_id; -/* Note: If we add SETTINGS, update the capacity of - NGHTTP2_INBOUND_NUM_IV as well */ - -/** - * @macro - * - * .. warning:: - * - * Deprecated. The initial max concurrent streams is 0xffffffffu. - * - * Default maximum number of incoming concurrent streams. Use - * `nghttp2_submit_settings()` with - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` - * to change the maximum number of incoming concurrent streams. - * - * .. note:: - * - * The maximum number of outgoing concurrent streams is 100 by - * default. - */ -#define NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1) - -/** - * @enum - * The status codes for the RST_STREAM and GOAWAY frames. - */ -typedef enum { - /** - * No errors. - */ - NGHTTP2_NO_ERROR = 0x00, - /** - * PROTOCOL_ERROR - */ - NGHTTP2_PROTOCOL_ERROR = 0x01, - /** - * INTERNAL_ERROR - */ - NGHTTP2_INTERNAL_ERROR = 0x02, - /** - * FLOW_CONTROL_ERROR - */ - NGHTTP2_FLOW_CONTROL_ERROR = 0x03, - /** - * SETTINGS_TIMEOUT - */ - NGHTTP2_SETTINGS_TIMEOUT = 0x04, - /** - * STREAM_CLOSED - */ - NGHTTP2_STREAM_CLOSED = 0x05, - /** - * FRAME_SIZE_ERROR - */ - NGHTTP2_FRAME_SIZE_ERROR = 0x06, - /** - * REFUSED_STREAM - */ - NGHTTP2_REFUSED_STREAM = 0x07, - /** - * CANCEL - */ - NGHTTP2_CANCEL = 0x08, - /** - * COMPRESSION_ERROR - */ - NGHTTP2_COMPRESSION_ERROR = 0x09, - /** - * CONNECT_ERROR - */ - NGHTTP2_CONNECT_ERROR = 0x0a, - /** - * ENHANCE_YOUR_CALM - */ - NGHTTP2_ENHANCE_YOUR_CALM = 0x0b, - /** - * INADEQUATE_SECURITY - */ - NGHTTP2_INADEQUATE_SECURITY = 0x0c, - /** - * HTTP_1_1_REQUIRED - */ - NGHTTP2_HTTP_1_1_REQUIRED = 0x0d -} nghttp2_error_code; - -/** - * @struct - * The frame header. - */ -typedef struct { - /** - * The length field of this frame, excluding frame header. - */ - size_t length; - /** - * The stream identifier (aka, stream ID) - */ - int32_t stream_id; - /** - * The type of this frame. See `nghttp2_frame_type`. - */ - uint8_t type; - /** - * The flags. - */ - uint8_t flags; - /** - * Reserved bit in frame header. Currently, this is always set to 0 - * and application should not expect something useful in here. - */ - uint8_t reserved; -} nghttp2_frame_hd; - -/** - * @union - * - * This union represents the some kind of data source passed to - * :type:`nghttp2_data_source_read_callback2`. - */ -typedef union { - /** - * The integer field, suitable for a file descriptor. - */ - int fd; - /** - * The pointer to an arbitrary object. - */ - void *ptr; -} nghttp2_data_source; - -/** - * @enum - * - * The flags used to set in |data_flags| output parameter in - * :type:`nghttp2_data_source_read_callback2`. - */ -typedef enum { - /** - * No flag set. - */ - NGHTTP2_DATA_FLAG_NONE = 0, - /** - * Indicates EOF was sensed. - */ - NGHTTP2_DATA_FLAG_EOF = 0x01, - /** - * Indicates that END_STREAM flag must not be set even if - * NGHTTP2_DATA_FLAG_EOF is set. Usually this flag is used to send - * trailer fields with `nghttp2_submit_request2()` or - * `nghttp2_submit_response2()`. - */ - NGHTTP2_DATA_FLAG_NO_END_STREAM = 0x02, - /** - * Indicates that application will send complete DATA frame in - * :type:`nghttp2_send_data_callback`. - */ - NGHTTP2_DATA_FLAG_NO_COPY = 0x04 -} nghttp2_data_flag; - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @functypedef - * - * .. warning:: - * - * Deprecated. Use :type:`nghttp2_data_source_read_callback2` - * instead. - * - * Callback function invoked when the library wants to read data from - * the |source|. The read data is sent in the stream |stream_id|. - * The implementation of this function must read at most |length| - * bytes of data from |source| (or possibly other places) and store - * them in |buf| and return number of data stored in |buf|. If EOF is - * reached, set :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag - * in |*data_flags|. - * - * Sometime it is desirable to avoid copying data into |buf| and let - * application to send data directly. To achieve this, set - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to - * |*data_flags| (and possibly other flags, just like when we do - * copy), and return the number of bytes to send without copying data - * into |buf|. The library, seeing - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke - * :type:`nghttp2_send_data_callback`. The application must send - * complete DATA frame in that callback. - * - * If this callback is set by `nghttp2_submit_request()`, - * `nghttp2_submit_response()` or `nghttp2_submit_headers()` and - * `nghttp2_submit_data()` with flag parameter - * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to - * |*data_flags|, DATA frame will have END_STREAM flag set. Usually, - * this is expected behaviour and all are fine. One exception is send - * trailer fields. You cannot send trailer fields after sending frame - * with END_STREAM set. To avoid this problem, one can set - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along - * with :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the - * library not to set END_STREAM in DATA frame. Then application can - * use `nghttp2_submit_trailer()` to send trailer fields. - * `nghttp2_submit_trailer()` can be called inside this callback. - * - * If the application wants to postpone DATA frames (e.g., - * asynchronous I/O, or reading data blocks for long time), it is - * achieved by returning :enum:`nghttp2_error.NGHTTP2_ERR_DEFERRED` - * without reading any data in this invocation. The library removes - * DATA frame from the outgoing queue temporarily. To move back - * deferred DATA frame to outgoing queue, call - * `nghttp2_session_resume_data()`. - * - * By default, |length| is limited to 16KiB at maximum. If peer - * allows larger frames, application can enlarge transmission buffer - * size. See :type:`nghttp2_data_source_read_length_callback` for - * more details. - * - * If the application just wants to return from - * `nghttp2_session_send()` or `nghttp2_session_mem_send()` without - * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. - * - * In case of error, there are 2 choices. Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will - * close the stream by issuing RST_STREAM with - * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. If a different - * error code is desirable, use `nghttp2_submit_rst_stream()` with a - * desired error code and then return - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. - * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will - * signal the entire session failure. - */ -typedef ssize_t (*nghttp2_data_source_read_callback)( - nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, - uint32_t *data_flags, nghttp2_data_source *source, void *user_data); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @functypedef - * - * Callback function invoked when the library wants to read data from - * the |source|. The read data is sent in the stream |stream_id|. - * The implementation of this function must read at most |length| - * bytes of data from |source| (or possibly other places) and store - * them in |buf| and return number of data stored in |buf|. If EOF is - * reached, set :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag - * in |*data_flags|. - * - * Sometime it is desirable to avoid copying data into |buf| and let - * application to send data directly. To achieve this, set - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to - * |*data_flags| (and possibly other flags, just like when we do - * copy), and return the number of bytes to send without copying data - * into |buf|. The library, seeing - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke - * :type:`nghttp2_send_data_callback`. The application must send - * complete DATA frame in that callback. - * - * If this callback is set by `nghttp2_submit_request2()`, - * `nghttp2_submit_response2()` or `nghttp2_submit_headers()` and - * `nghttp2_submit_data2()` with flag parameter - * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to - * |*data_flags|, DATA frame will have END_STREAM flag set. Usually, - * this is expected behaviour and all are fine. One exception is send - * trailer fields. You cannot send trailer fields after sending frame - * with END_STREAM set. To avoid this problem, one can set - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along - * with :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the - * library not to set END_STREAM in DATA frame. Then application can - * use `nghttp2_submit_trailer()` to send trailer fields. - * `nghttp2_submit_trailer()` can be called inside this callback. - * - * If the application wants to postpone DATA frames (e.g., - * asynchronous I/O, or reading data blocks for long time), it is - * achieved by returning :enum:`nghttp2_error.NGHTTP2_ERR_DEFERRED` - * without reading any data in this invocation. The library removes - * DATA frame from the outgoing queue temporarily. To move back - * deferred DATA frame to outgoing queue, call - * `nghttp2_session_resume_data()`. - * - * By default, |length| is limited to 16KiB at maximum. If peer - * allows larger frames, application can enlarge transmission buffer - * size. See :type:`nghttp2_data_source_read_length_callback` for - * more details. - * - * If the application just wants to return from - * `nghttp2_session_send()` or `nghttp2_session_mem_send2()` without - * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. - * - * In case of error, there are 2 choices. Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will - * close the stream by issuing RST_STREAM with - * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. If a different - * error code is desirable, use `nghttp2_submit_rst_stream()` with a - * desired error code and then return - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. - * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will - * signal the entire session failure. - */ -typedef nghttp2_ssize (*nghttp2_data_source_read_callback2)( - nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, - uint32_t *data_flags, nghttp2_data_source *source, void *user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @struct - * - * .. warning:: - * - * Deprecated. Use :type:`nghttp2_data_provider2` instead. - * - * This struct represents the data source and the way to read a chunk - * of data from it. - */ -typedef struct { - /** - * The data source. - */ - nghttp2_data_source source; - /** - * The callback function to read a chunk of data from the |source|. - */ - nghttp2_data_source_read_callback read_callback; -} nghttp2_data_provider; - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @struct - * - * This struct represents the data source and the way to read a chunk - * of data from it. - */ -typedef struct { - /** - * The data source. - */ - nghttp2_data_source source; - /** - * The callback function to read a chunk of data from the |source|. - */ - nghttp2_data_source_read_callback2 read_callback; -} nghttp2_data_provider2; - -/** - * @struct - * - * The DATA frame. The received data is delivered via - * :type:`nghttp2_on_data_chunk_recv_callback`. - */ -typedef struct { - nghttp2_frame_hd hd; - /** - * The length of the padding in this frame. This includes PAD_HIGH - * and PAD_LOW. - */ - size_t padlen; -} nghttp2_data; - -/** - * @enum - * - * The category of HEADERS, which indicates the role of the frame. In - * HTTP/2 spec, request, response, push response and other arbitrary - * headers (e.g., trailer fields) are all called just HEADERS. To - * give the application the role of incoming HEADERS frame, we define - * several categories. - */ -typedef enum { - /** - * The HEADERS frame is opening new stream, which is analogous to - * SYN_STREAM in SPDY. - */ - NGHTTP2_HCAT_REQUEST = 0, - /** - * The HEADERS frame is the first response headers, which is - * analogous to SYN_REPLY in SPDY. - */ - NGHTTP2_HCAT_RESPONSE = 1, - /** - * The HEADERS frame is the first headers sent against reserved - * stream. - */ - NGHTTP2_HCAT_PUSH_RESPONSE = 2, - /** - * The HEADERS frame which does not apply for the above categories, - * which is analogous to HEADERS in SPDY. If non-final response - * (e.g., status 1xx) is used, final response HEADERS frame will be - * categorized here. - */ - NGHTTP2_HCAT_HEADERS = 3 -} nghttp2_headers_category; - -/** - * @struct - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * The structure to specify stream dependency. - */ -typedef struct { - /** - * The stream ID of the stream to depend on. Specifying 0 makes - * stream not depend any other stream. - */ - int32_t stream_id; - /** - * The weight of this dependency. - */ - int32_t weight; - /** - * nonzero means exclusive dependency - */ - uint8_t exclusive; -} nghttp2_priority_spec; - -/** - * @struct - * - * The HEADERS frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The length of the padding in this frame. This includes PAD_HIGH - * and PAD_LOW. - */ - size_t padlen; - /** - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * The priority specification - */ - nghttp2_priority_spec pri_spec; - /** - * The name/value pairs. - */ - nghttp2_nv *nva; - /** - * The number of name/value pairs in |nva|. - */ - size_t nvlen; - /** - * The category of this HEADERS frame. - */ - nghttp2_headers_category cat; -} nghttp2_headers; - -/** - * @struct - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * The PRIORITY frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The priority specification. - */ - nghttp2_priority_spec pri_spec; -} nghttp2_priority; - -/** - * @struct - * - * The RST_STREAM frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The error code. See :type:`nghttp2_error_code`. - */ - uint32_t error_code; -} nghttp2_rst_stream; - -/** - * @struct - * - * The SETTINGS ID/Value pair. It has the following members: - */ -typedef struct { - /** - * The SETTINGS ID. See :type:`nghttp2_settings_id`. - */ - int32_t settings_id; - /** - * The value of this entry. - */ - uint32_t value; -} nghttp2_settings_entry; - -/** - * @struct - * - * The SETTINGS frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The number of SETTINGS ID/Value pairs in |iv|. - */ - size_t niv; - /** - * The pointer to the array of SETTINGS ID/Value pair. - */ - nghttp2_settings_entry *iv; -} nghttp2_settings; - -/** - * @struct - * - * The PUSH_PROMISE frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The length of the padding in this frame. This includes PAD_HIGH - * and PAD_LOW. - */ - size_t padlen; - /** - * The name/value pairs. - */ - nghttp2_nv *nva; - /** - * The number of name/value pairs in |nva|. - */ - size_t nvlen; - /** - * The promised stream ID - */ - int32_t promised_stream_id; - /** - * Reserved bit. Currently this is always set to 0 and application - * should not expect something useful in here. - */ - uint8_t reserved; -} nghttp2_push_promise; - -/** - * @struct - * - * The PING frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The opaque data - */ - uint8_t opaque_data[8]; -} nghttp2_ping; - -/** - * @struct - * - * The GOAWAY frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The last stream stream ID. - */ - int32_t last_stream_id; - /** - * The error code. See :type:`nghttp2_error_code`. - */ - uint32_t error_code; - /** - * The additional debug data - */ - uint8_t *opaque_data; - /** - * The length of |opaque_data| member. - */ - size_t opaque_data_len; - /** - * Reserved bit. Currently this is always set to 0 and application - * should not expect something useful in here. - */ - uint8_t reserved; -} nghttp2_goaway; - -/** - * @struct - * - * The WINDOW_UPDATE frame. It has the following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The window size increment. - */ - int32_t window_size_increment; - /** - * Reserved bit. Currently this is always set to 0 and application - * should not expect something useful in here. - */ - uint8_t reserved; -} nghttp2_window_update; - -/** - * @struct - * - * The extension frame. It has following members: - */ -typedef struct { - /** - * The frame header. - */ - nghttp2_frame_hd hd; - /** - * The pointer to extension payload. The exact pointer type is - * determined by hd.type. - * - * Currently, no extension is supported. This is a place holder for - * the future extensions. - */ - void *payload; -} nghttp2_extension; - -/** - * @union - * - * This union includes all frames to pass them to various function - * calls as nghttp2_frame type. The CONTINUATION frame is omitted - * from here because the library deals with it internally. - */ -typedef union { - /** - * The frame header, which is convenient to inspect frame header. - */ - nghttp2_frame_hd hd; - /** - * The DATA frame. - */ - nghttp2_data data; - /** - * The HEADERS frame. - */ - nghttp2_headers headers; - /** - * The PRIORITY frame. - */ - nghttp2_priority priority; - /** - * The RST_STREAM frame. - */ - nghttp2_rst_stream rst_stream; - /** - * The SETTINGS frame. - */ - nghttp2_settings settings; - /** - * The PUSH_PROMISE frame. - */ - nghttp2_push_promise push_promise; - /** - * The PING frame. - */ - nghttp2_ping ping; - /** - * The GOAWAY frame. - */ - nghttp2_goaway goaway; - /** - * The WINDOW_UPDATE frame. - */ - nghttp2_window_update window_update; - /** - * The extension frame. - */ - nghttp2_extension ext; -} nghttp2_frame; - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @functypedef - * - * .. warning:: - * - * Deprecated. Use :type:`nghttp2_send_callback2` instead. - * - * Callback function invoked when |session| wants to send data to the - * remote peer. The implementation of this function must send at most - * |length| bytes of data stored in |data|. The |flags| is currently - * not used and always 0. It must return the number of bytes sent if - * it succeeds. If it cannot send any single byte without blocking, - * it must return :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. For - * other errors, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The - * |user_data| pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * This callback is required if the application uses - * `nghttp2_session_send()` to send data to the remote endpoint. If - * the application uses solely `nghttp2_session_mem_send()` instead, - * this callback function is unnecessary. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_send_callback()`. - * - * .. note:: - * - * The |length| may be very small. If that is the case, and - * application disables Nagle algorithm (``TCP_NODELAY``), then just - * writing |data| to the network stack leads to very small packet, - * and it is very inefficient. An application should be responsible - * to buffer up small chunks of data as necessary to avoid this - * situation. - */ -typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session, - const uint8_t *data, size_t length, - int flags, void *user_data); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @functypedef - * - * Callback function invoked when |session| wants to send data to the - * remote peer. The implementation of this function must send at most - * |length| bytes of data stored in |data|. The |flags| is currently - * not used and always 0. It must return the number of bytes sent if - * it succeeds. If it cannot send any single byte without blocking, - * it must return :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. For - * other errors, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The - * |user_data| pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * This callback is required if the application uses - * `nghttp2_session_send()` to send data to the remote endpoint. If - * the application uses solely `nghttp2_session_mem_send2()` instead, - * this callback function is unnecessary. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_send_callback2()`. - * - * .. note:: - * - * The |length| may be very small. If that is the case, and - * application disables Nagle algorithm (``TCP_NODELAY``), then just - * writing |data| to the network stack leads to very small packet, - * and it is very inefficient. An application should be responsible - * to buffer up small chunks of data as necessary to avoid this - * situation. - */ -typedef nghttp2_ssize (*nghttp2_send_callback2)(nghttp2_session *session, - const uint8_t *data, - size_t length, int flags, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in - * :type:`nghttp2_data_source_read_callback` to send complete DATA - * frame. - * - * The |frame| is a DATA frame to send. The |framehd| is the - * serialized frame header (9 bytes). The |length| is the length of - * application data to send (this does not include padding). The - * |source| is the same pointer passed to - * :type:`nghttp2_data_source_read_callback`. - * - * The application first must send frame header |framehd| of length 9 - * bytes. If ``frame->data.padlen > 0``, send 1 byte of value - * ``frame->data.padlen - 1``. Then send exactly |length| bytes of - * application data. Finally, if ``frame->data.padlen > 1``, send - * ``frame->data.padlen - 1`` bytes of zero as padding. - * - * The application has to send complete DATA frame in this callback. - * If all data were written successfully, return 0. - * - * If it cannot send any data at all, just return - * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`; the library will call - * this callback with the same parameters later (It is recommended to - * send complete DATA frame at once in this function to deal with - * error; if partial frame data has already sent, it is impossible to - * send another data in that state, and all we can do is tear down - * connection). When data is fully processed, but application wants - * to make `nghttp2_session_mem_send2()` or `nghttp2_session_send()` - * return immediately without processing next frames, return - * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. If application decided to - * reset this stream, return - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then - * the library will send RST_STREAM with INTERNAL_ERROR as error code. - * The application can also return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which will - * result in connection closure. Returning any other value is treated - * as :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. - */ -typedef int (*nghttp2_send_data_callback)(nghttp2_session *session, - nghttp2_frame *frame, - const uint8_t *framehd, size_t length, - nghttp2_data_source *source, - void *user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @functypedef - * - * .. warning:: - * - * Deprecated. Use :type:`nghttp2_recv_callback2` instead. - * - * Callback function invoked when |session| wants to receive data from - * the remote peer. The implementation of this function must read at - * most |length| bytes of data and store it in |buf|. The |flags| is - * currently not used and always 0. It must return the number of - * bytes written in |buf| if it succeeds. If it cannot read any - * single byte without blocking, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF - * before it reads any single byte, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`. For other errors, it must - * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * Returning 0 is treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. The |user_data| - * pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * This callback is required if the application uses - * `nghttp2_session_recv()` to receive data from the remote endpoint. - * If the application uses solely `nghttp2_session_mem_recv()` - * instead, this callback function is unnecessary. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_recv_callback()`. - */ -typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf, - size_t length, int flags, - void *user_data); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @functypedef - * - * Callback function invoked when |session| wants to receive data from - * the remote peer. The implementation of this function must read at - * most |length| bytes of data and store it in |buf|. The |flags| is - * currently not used and always 0. It must return the number of - * bytes written in |buf| if it succeeds. If it cannot read any - * single byte without blocking, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF - * before it reads any single byte, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`. For other errors, it must - * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * Returning 0 is treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. The |user_data| - * pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * This callback is required if the application uses - * `nghttp2_session_recv()` to receive data from the remote endpoint. - * If the application uses solely `nghttp2_session_mem_recv2()` - * instead, this callback function is unnecessary. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_recv_callback2()`. - */ -typedef nghttp2_ssize (*nghttp2_recv_callback2)(nghttp2_session *session, - uint8_t *buf, size_t length, - int flags, void *user_data); - -/** - * @functypedef - * - * Callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv2()` when a frame is received. The - * |user_data| pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * If frame is HEADERS or PUSH_PROMISE, the ``nva`` and ``nvlen`` - * member of their data structure are always ``NULL`` and 0 - * respectively. The header name/value pairs are emitted via - * :type:`nghttp2_on_header_callback`. - * - * Only HEADERS and DATA frame can signal the end of incoming data. - * If ``frame->hd.flags & NGHTTP2_FLAG_END_STREAM`` is nonzero, the - * |frame| is the last frame from the remote peer in this stream. - * - * This callback won't be called for CONTINUATION frames. - * HEADERS/PUSH_PROMISE + CONTINUATIONs are treated as single frame. - * - * The implementation of this function must return 0 if it succeeds. - * If nonzero value is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_frame_recv_callback()`. - */ -typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session, - const nghttp2_frame *frame, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv2()` when an invalid non-DATA frame is - * received. The error is indicated by the |lib_error_code|, which is - * one of the values defined in :type:`nghttp2_error`. When this - * callback function is invoked, the library automatically submits - * either RST_STREAM or GOAWAY frame. The |user_data| pointer is the - * third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * If frame is HEADERS or PUSH_PROMISE, the ``nva`` and ``nvlen`` - * member of their data structure are always ``NULL`` and 0 - * respectively. - * - * The implementation of this function must return 0 if it succeeds. - * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`. - */ -typedef int (*nghttp2_on_invalid_frame_recv_callback)( - nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when a chunk of data in DATA frame is - * received. The |stream_id| is the stream ID this DATA frame belongs - * to. The |flags| is the flags of DATA frame which this data chunk - * is contained. ``(flags & NGHTTP2_FLAG_END_STREAM) != 0`` does not - * necessarily mean this chunk of data is the last one in the stream. - * You should use :type:`nghttp2_on_frame_recv_callback` to know all - * data frames are received. The |user_data| pointer is the third - * argument passed in to the call to `nghttp2_session_client_new()` or - * `nghttp2_session_server_new()`. - * - * If the application uses `nghttp2_session_mem_recv2()`, it can - * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make - * `nghttp2_session_mem_recv2()` return without processing further - * input bytes. The memory by pointed by the |data| is retained until - * `nghttp2_session_mem_recv2()` or `nghttp2_session_recv()` is - * called. The application must retain the input bytes which was used - * to produce the |data| parameter, because it may refer to the memory - * region included in the input bytes. - * - * The implementation of this function must return 0 if it succeeds. - * If nonzero is returned, it is treated as fatal error, and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_data_chunk_recv_callback()`. - */ -typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session, - uint8_t flags, - int32_t stream_id, - const uint8_t *data, - size_t len, void *user_data); - -/** - * @functypedef - * - * Callback function invoked just before the non-DATA frame |frame| is - * sent. The |user_data| pointer is the third argument passed in to - * the call to `nghttp2_session_client_new()` or - * `nghttp2_session_server_new()`. - * - * The implementation of this function must return 0 if it succeeds. - * It can also return :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` to - * cancel the transmission of the given frame. - * - * If there is a fatal error while executing this callback, the - * implementation should return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes - * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * If the other value is returned, it is treated as if - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. - * But the implementation should not rely on this since the library - * may define new return value to extend its capability. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_before_frame_send_callback()`. - */ -typedef int (*nghttp2_before_frame_send_callback)(nghttp2_session *session, - const nghttp2_frame *frame, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked after the frame |frame| is sent. The - * |user_data| pointer is the third argument passed in to the call to - * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. - * - * The implementation of this function must return 0 if it succeeds. - * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_frame_send_callback()`. - */ -typedef int (*nghttp2_on_frame_send_callback)(nghttp2_session *session, - const nghttp2_frame *frame, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked after the non-DATA frame |frame| is not - * sent because of the error. The error is indicated by the - * |lib_error_code|, which is one of the values defined in - * :type:`nghttp2_error`. The |user_data| pointer is the third - * argument passed in to the call to `nghttp2_session_client_new()` or - * `nghttp2_session_server_new()`. - * - * The implementation of this function must return 0 if it succeeds. - * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * `nghttp2_session_get_stream_user_data()` can be used to get - * associated data. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_frame_not_send_callback()`. - */ -typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session, - const nghttp2_frame *frame, - int lib_error_code, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when the stream |stream_id| is closed. - * The reason of closure is indicated by the |error_code|. The - * |error_code| is usually one of :enum:`nghttp2_error_code`, but that - * is not guaranteed. The stream_user_data, which was specified in - * `nghttp2_submit_request2()` or `nghttp2_submit_headers()`, is still - * available in this function. The |user_data| pointer is the third - * argument passed in to the call to `nghttp2_session_client_new()` or - * `nghttp2_session_server_new()`. - * - * This function is also called for a stream in reserved state. - * - * The implementation of this function must return 0 if it succeeds. - * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_recv()`, `nghttp2_session_mem_recv2()`, - * `nghttp2_session_send()`, and `nghttp2_session_mem_send2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_stream_close_callback()`. - */ -typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session, - int32_t stream_id, - uint32_t error_code, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when the reception of header block in - * HEADERS or PUSH_PROMISE is started. Each header name/value pair - * will be emitted by :type:`nghttp2_on_header_callback`. - * - * The ``frame->hd.flags`` may not have - * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_HEADERS` flag set, which - * indicates that one or more CONTINUATION frames are involved. But - * the application does not need to care about that because the header - * name/value pairs are emitted transparently regardless of - * CONTINUATION frames. - * - * The server applications probably create an object to store - * information about new stream if ``frame->hd.type == - * NGHTTP2_HEADERS`` and ``frame->headers.cat == - * NGHTTP2_HCAT_REQUEST``. If |session| is configured as server side, - * ``frame->headers.cat`` is either ``NGHTTP2_HCAT_REQUEST`` - * containing request headers or ``NGHTTP2_HCAT_HEADERS`` containing - * trailer fields and never get PUSH_PROMISE in this callback. - * - * For the client applications, ``frame->hd.type`` is either - * ``NGHTTP2_HEADERS`` or ``NGHTTP2_PUSH_PROMISE``. In case of - * ``NGHTTP2_HEADERS``, ``frame->headers.cat == - * NGHTTP2_HCAT_RESPONSE`` means that it is the first response - * headers, but it may be non-final response which is indicated by 1xx - * status code. In this case, there may be zero or more HEADERS frame - * with ``frame->headers.cat == NGHTTP2_HCAT_HEADERS`` which has - * non-final response code and finally client gets exactly one HEADERS - * frame with ``frame->headers.cat == NGHTTP2_HCAT_HEADERS`` - * containing final response headers (non-1xx status code). The - * trailer fields also has ``frame->headers.cat == - * NGHTTP2_HCAT_HEADERS`` which does not contain any status code. - * - * Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will - * close the stream (promised stream if frame is PUSH_PROMISE) by - * issuing RST_STREAM with - * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. In this case, - * :type:`nghttp2_on_header_callback` and - * :type:`nghttp2_on_frame_recv_callback` will not be invoked. If a - * different error code is desirable, use - * `nghttp2_submit_rst_stream()` with a desired error code and then - * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. - * Again, use ``frame->push_promise.promised_stream_id`` as stream_id - * parameter in `nghttp2_submit_rst_stream()` if frame is - * PUSH_PROMISE. - * - * The implementation of this function must return 0 if it succeeds. - * It can return - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to - * reset the stream (promised stream if frame is PUSH_PROMISE). For - * critical errors, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other - * value is returned, it is treated as if - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. If - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned, - * `nghttp2_session_mem_recv2()` function will immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_begin_headers_callback()`. - */ -typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session, - const nghttp2_frame *frame, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when a header name/value pair is received - * for the |frame|. The |name| of length |namelen| is header name. - * The |value| of length |valuelen| is header value. The |flags| is - * bitwise OR of one or more of :type:`nghttp2_nv_flag`. - * - * If :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_INDEX` is set in - * |flags|, the receiver must not index this name/value pair when - * forwarding it to the next hop. More specifically, "Literal Header - * Field never Indexed" representation must be used in HPACK encoding. - * - * When this callback is invoked, ``frame->hd.type`` is either - * :enum:`nghttp2_frame_type.NGHTTP2_HEADERS` or - * :enum:`nghttp2_frame_type.NGHTTP2_PUSH_PROMISE`. After all header - * name/value pairs are processed with this callback, and no error has - * been detected, :type:`nghttp2_on_frame_recv_callback` will be - * invoked. If there is an error in decompression, - * :type:`nghttp2_on_frame_recv_callback` for the |frame| will not be - * invoked. - * - * Both |name| and |value| are guaranteed to be NULL-terminated. The - * |namelen| and |valuelen| do not include terminal NULL. If - * `nghttp2_option_set_no_http_messaging()` is used with nonzero - * value, NULL character may be included in |name| or |value| before - * terminating NULL. - * - * Please note that unless `nghttp2_option_set_no_http_messaging()` is - * used, nghttp2 library does perform validation against the |name| - * and the |value| using `nghttp2_check_header_name()` and - * `nghttp2_check_header_value()`. In addition to this, nghttp2 - * performs validation based on HTTP Messaging rule, which is briefly - * explained in :ref:`http-messaging` section. - * - * If the application uses `nghttp2_session_mem_recv2()`, it can - * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make - * `nghttp2_session_mem_recv2()` return without processing further - * input bytes. The memory pointed by |frame|, |name| and |value| - * parameters are retained until `nghttp2_session_mem_recv2()` or - * `nghttp2_session_recv()` is called. The application must retain - * the input bytes which was used to produce these parameters, because - * it may refer to the memory region included in the input bytes. - * - * Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will - * close the stream (promised stream if frame is PUSH_PROMISE) by - * issuing RST_STREAM with - * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. In this case, - * :type:`nghttp2_on_header_callback` and - * :type:`nghttp2_on_frame_recv_callback` will not be invoked. If a - * different error code is desirable, use - * `nghttp2_submit_rst_stream()` with a desired error code and then - * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. - * Again, use ``frame->push_promise.promised_stream_id`` as stream_id - * parameter in `nghttp2_submit_rst_stream()` if frame is - * PUSH_PROMISE. - * - * The implementation of this function must return 0 if it succeeds. - * It may return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` or - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. For - * other critical failures, it must return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other - * nonzero value is returned, it is treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned, - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_header_callback()`. - * - * .. warning:: - * - * Application should properly limit the total buffer size to store - * incoming header fields. Without it, peer may send large number - * of header fields or large header fields to cause out of memory in - * local endpoint. Due to how HPACK works, peer can do this - * effectively without using much memory on their own. - */ -typedef int (*nghttp2_on_header_callback)(nghttp2_session *session, - const nghttp2_frame *frame, - const uint8_t *name, size_t namelen, - const uint8_t *value, size_t valuelen, - uint8_t flags, void *user_data); - -/** - * @functypedef - * - * Callback function invoked when a header name/value pair is received - * for the |frame|. The |name| is header name. The |value| is header - * value. The |flags| is bitwise OR of one or more of - * :type:`nghttp2_nv_flag`. - * - * This callback behaves like :type:`nghttp2_on_header_callback`, - * except that |name| and |value| are stored in reference counted - * buffer. If application wishes to keep these references without - * copying them, use `nghttp2_rcbuf_incref()` to increment their - * reference count. It is the application's responsibility to call - * `nghttp2_rcbuf_decref()` if they called `nghttp2_rcbuf_incref()` so - * as not to leak memory. If the |session| is created by - * `nghttp2_session_server_new3()` or `nghttp2_session_client_new3()`, - * the function to free memory is the one belongs to the mem - * parameter. As long as this free function alives, |name| and - * |value| can live after |session| was destroyed. - */ -typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session, - const nghttp2_frame *frame, - nghttp2_rcbuf *name, - nghttp2_rcbuf *value, uint8_t flags, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when an invalid header name/value pair is - * received for the |frame|. - * - * The parameter and behaviour are similar to - * :type:`nghttp2_on_header_callback`. The difference is that this - * callback is only invoked when an invalid header name/value pair is - * received which is treated as stream error if this callback returns - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` and - * :type:`nghttp2_on_invalid_header_callback2` is not set. Only - * invalid regular header field are passed to this callback. In other - * words, invalid pseudo header field is not passed to this callback. - * Also header fields which includes upper cased latter are also - * treated as error without passing them to this callback. - * - * This callback is only considered if HTTP messaging validation is - * turned on (which is on by default, see - * `nghttp2_option_set_no_http_messaging()`). - * - * With this callback, application inspects the incoming invalid - * field, and it also can reset stream from this callback by returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By - * default, the error code is - * :enum:`nghttp2_error_code.NGHTTP2_PROTOCOL_ERROR`. To change the - * error code, call `nghttp2_submit_rst_stream()` with the error code - * of choice in addition to returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. - * - * If 0 is returned, the header field is ignored, and the stream is - * not reset. - */ -typedef int (*nghttp2_on_invalid_header_callback)( - nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, - size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when an invalid header name/value pair is - * received for the |frame|. - * - * The parameter and behaviour are similar to - * :type:`nghttp2_on_header_callback2`. The difference is that this - * callback is only invoked when an invalid header name/value pair is - * received which is silently ignored if neither this callback nor - * :type:`nghttp2_on_invalid_header_callback` is set. Only invalid - * regular header field are passed to this callback. In other words, - * invalid pseudo header field is not passed to this callback. Also - * header fields which includes upper cased latter are also treated as - * error without passing them to this callback. - * - * This callback is only considered if HTTP messaging validation is - * turned on (which is on by default, see - * `nghttp2_option_set_no_http_messaging()`). - * - * With this callback, application inspects the incoming invalid - * field, and it also can reset stream from this callback by returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By - * default, the error code is - * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. To change the - * error code, call `nghttp2_submit_rst_stream()` with the error code - * of choice in addition to returning - * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. - */ -typedef int (*nghttp2_on_invalid_header_callback2)( - nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, - nghttp2_rcbuf *value, uint8_t flags, void *user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @functypedef - * - * .. warning:: - * - * Deprecated. Use :type:`nghttp2_select_padding_callback2` - * instead. - * - * Callback function invoked when the library asks application how - * many padding bytes are required for the transmission of the - * |frame|. The application must choose the total length of payload - * including padded bytes in range [frame->hd.length, max_payloadlen], - * inclusive. Choosing number not in this range will be treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Returning - * ``frame->hd.length`` means no padding is added. Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make - * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_select_padding_callback()`. - */ -typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session, - const nghttp2_frame *frame, - size_t max_payloadlen, - void *user_data); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @functypedef - * - * Callback function invoked when the library asks application how - * many padding bytes are required for the transmission of the - * |frame|. The application must choose the total length of payload - * including padded bytes in range [frame->hd.length, max_payloadlen], - * inclusive. Choosing number not in this range will be treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Returning - * ``frame->hd.length`` means no padding is added. Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make - * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_select_padding_callback2()`. - */ -typedef nghttp2_ssize (*nghttp2_select_padding_callback2)( - nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen, - void *user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @functypedef - * - * .. warning:: - * - * Deprecated. Use - * :type:`nghttp2_data_source_read_length_callback2` instead. - * - * Callback function invoked when library wants to get max length of - * data to send data to the remote peer. The implementation of this - * function should return a value in the following range. [1, - * min(|session_remote_window_size|, |stream_remote_window_size|, - * |remote_max_frame_size|)]. If a value greater than this range is - * returned than the max allow value will be used. Returning a value - * smaller than this range is treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The - * |frame_type| is provided for future extensibility and identifies - * the type of frame (see :type:`nghttp2_frame_type`) for which to get - * the length for. Currently supported frame types are: - * :enum:`nghttp2_frame_type.NGHTTP2_DATA`. - * - * This callback can be used to control the length in bytes for which - * :type:`nghttp2_data_source_read_callback` is allowed to send to the - * remote endpoint. This callback is optional. Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the - * entire session failure. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_data_source_read_length_callback()`. - */ -typedef ssize_t (*nghttp2_data_source_read_length_callback)( - nghttp2_session *session, uint8_t frame_type, int32_t stream_id, - int32_t session_remote_window_size, int32_t stream_remote_window_size, - uint32_t remote_max_frame_size, void *user_data); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @functypedef - * - * Callback function invoked when library wants to get max length of - * data to send data to the remote peer. The implementation of this - * function should return a value in the following range. [1, - * min(|session_remote_window_size|, |stream_remote_window_size|, - * |remote_max_frame_size|)]. If a value greater than this range is - * returned than the max allow value will be used. Returning a value - * smaller than this range is treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The - * |frame_type| is provided for future extensibility and identifies - * the type of frame (see :type:`nghttp2_frame_type`) for which to get - * the length for. Currently supported frame types are: - * :enum:`nghttp2_frame_type.NGHTTP2_DATA`. - * - * This callback can be used to control the length in bytes for which - * :type:`nghttp2_data_source_read_callback` is allowed to send to the - * remote endpoint. This callback is optional. Returning - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the - * entire session failure. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_data_source_read_length_callback2()`. - */ -typedef nghttp2_ssize (*nghttp2_data_source_read_length_callback2)( - nghttp2_session *session, uint8_t frame_type, int32_t stream_id, - int32_t session_remote_window_size, int32_t stream_remote_window_size, - uint32_t remote_max_frame_size, void *user_data); - -/** - * @functypedef - * - * Callback function invoked when a frame header is received. The - * |hd| points to received frame header. - * - * Unlike :type:`nghttp2_on_frame_recv_callback`, this callback will - * also be called when frame header of CONTINUATION frame is received. - * - * If both :type:`nghttp2_on_begin_frame_callback` and - * :type:`nghttp2_on_begin_headers_callback` are set and HEADERS or - * PUSH_PROMISE is received, :type:`nghttp2_on_begin_frame_callback` - * will be called first. - * - * The implementation of this function must return 0 if it succeeds. - * If nonzero value is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * - * To set this callback to :type:`nghttp2_session_callbacks`, use - * `nghttp2_session_callbacks_set_on_begin_frame_callback()`. - */ -typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session, - const nghttp2_frame_hd *hd, - void *user_data); - -/** - * @functypedef - * - * Callback function invoked when chunk of extension frame payload is - * received. The |hd| points to frame header. The received - * chunk is |data| of length |len|. - * - * The implementation of this function must return 0 if it succeeds. - * - * To abort processing this extension frame, return - * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`. - * - * If fatal error occurred, application should return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other - * values are returned, currently they are treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - */ -typedef int (*nghttp2_on_extension_chunk_recv_callback)( - nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, - size_t len, void *user_data); - -/** - * @functypedef - * - * Callback function invoked when library asks the application to - * unpack extension payload from its wire format. The extension - * payload has been passed to the application using - * :type:`nghttp2_on_extension_chunk_recv_callback`. The frame header - * is already unpacked by the library and provided as |hd|. - * - * To receive extension frames, the application must tell desired - * extension frame type to the library using - * `nghttp2_option_set_user_recv_extension_type()`. - * - * The implementation of this function may store the pointer to the - * created object as a result of unpacking in |*payload|, and returns - * 0. The pointer stored in |*payload| is opaque to the library, and - * the library does not own its pointer. |*payload| is initialized as - * ``NULL``. The |*payload| is available as ``frame->ext.payload`` in - * :type:`nghttp2_on_frame_recv_callback`. Therefore if application - * can free that memory inside :type:`nghttp2_on_frame_recv_callback` - * callback. Of course, application has a liberty not to use - * |*payload|, and do its own mechanism to process extension frames. - * - * To abort processing this extension frame, return - * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`. - * - * If fatal error occurred, application should return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other - * values are returned, currently they are treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - */ -typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session, - void **payload, - const nghttp2_frame_hd *hd, - void *user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @functypedef - * - * .. warning:: - * - * Deprecated. Use :type:`nghttp2_pack_extension_callback2` - * instead. - * - * Callback function invoked when library asks the application to pack - * extension payload in its wire format. The frame header will be - * packed by library. Application must pack payload only. - * ``frame->ext.payload`` is the object passed to - * `nghttp2_submit_extension()` as payload parameter. Application - * must pack extension payload to the |buf| of its capacity |len| - * bytes. The |len| is at least 16KiB. - * - * The implementation of this function should return the number of - * bytes written into |buf| when it succeeds. - * - * To abort processing this extension frame, return - * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and - * :type:`nghttp2_on_frame_not_send_callback` will be invoked. - * - * If fatal error occurred, application should return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other - * values are returned, currently they are treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the return - * value is strictly larger than |len|, it is treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - */ -typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session, - uint8_t *buf, size_t len, - const nghttp2_frame *frame, - void *user_data); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @functypedef - * - * Callback function invoked when library asks the application to pack - * extension payload in its wire format. The frame header will be - * packed by library. Application must pack payload only. - * ``frame->ext.payload`` is the object passed to - * `nghttp2_submit_extension()` as payload parameter. Application - * must pack extension payload to the |buf| of its capacity |len| - * bytes. The |len| is at least 16KiB. - * - * The implementation of this function should return the number of - * bytes written into |buf| when it succeeds. - * - * To abort processing this extension frame, return - * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and - * :type:`nghttp2_on_frame_not_send_callback` will be invoked. - * - * If fatal error occurred, application should return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` - * functions immediately return - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other - * values are returned, currently they are treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the return - * value is strictly larger than |len|, it is treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - */ -typedef nghttp2_ssize (*nghttp2_pack_extension_callback2)( - nghttp2_session *session, uint8_t *buf, size_t len, - const nghttp2_frame *frame, void *user_data); - -/** - * @functypedef - * - * .. warning:: - * - * Deprecated. Use :type:`nghttp2_error_callback2` instead. - * - * Callback function invoked when library provides the error message - * intended for human consumption. This callback is solely for - * debugging purpose. The |msg| is typically NULL-terminated string - * of length |len|. |len| does not include the sentinel NULL - * character. - * - * The format of error message may change between nghttp2 library - * versions. The application should not depend on the particular - * format. - * - * Normally, application should return 0 from this callback. If fatal - * error occurred while doing something in this callback, application - * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * In this case, library will return immediately with return value - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if - * nonzero value is returned from this callback, they are treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application - * should not rely on this details. - */ -typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg, - size_t len, void *user_data); - -/** - * @functypedef - * - * Callback function invoked when library provides the error code, and - * message. This callback is solely for debugging purpose. - * |lib_error_code| is one of error code defined in - * :enum:`nghttp2_error`. The |msg| is typically NULL-terminated - * string of length |len|, and intended for human consumption. |len| - * does not include the sentinel NULL character. - * - * The format of error message may change between nghttp2 library - * versions. The application should not depend on the particular - * format. - * - * Normally, application should return 0 from this callback. If fatal - * error occurred while doing something in this callback, application - * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. - * In this case, library will return immediately with return value - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if - * nonzero value is returned from this callback, they are treated as - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application - * should not rely on this details. - */ -typedef int (*nghttp2_error_callback2)(nghttp2_session *session, - int lib_error_code, const char *msg, - size_t len, void *user_data); - -/** - * @functypedef - * - * Callback function invoked when unpredictable data of |destlen| - * bytes are needed. The implementation must write unpredictable data - * of |destlen| bytes into the buffer pointed by |dest|. - */ -typedef void (*nghttp2_rand_callback)(uint8_t *dest, size_t destlen); - -struct nghttp2_session_callbacks; - -/** - * @struct - * - * Callback functions for :type:`nghttp2_session`. The details of - * this structure are intentionally hidden from the public API. - */ -typedef struct nghttp2_session_callbacks nghttp2_session_callbacks; - -/** - * @function - * - * Initializes |*callbacks_ptr| with NULL values. - * - * The initialized object can be used when initializing multiple - * :type:`nghttp2_session` objects. - * - * When the application finished using this object, it can use - * `nghttp2_session_callbacks_del()` to free its memory. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_session_callbacks_new(nghttp2_session_callbacks **callbacks_ptr); - -/** - * @function - * - * Frees any resources allocated for |callbacks|. If |callbacks| is - * ``NULL``, this function does nothing. - */ -NGHTTP2_EXTERN void -nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_session_callbacks_set_send_callback2()` - * with :type:`nghttp2_send_callback2` instead. - * - * Sets callback function invoked when a session wants to send data to - * the remote peer. This callback is not necessary if the application - * uses solely `nghttp2_session_mem_send()` to serialize data to - * transmit. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback( - nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Sets callback function invoked when a session wants to send data to - * the remote peer. This callback is not necessary if the application - * uses solely `nghttp2_session_mem_send2()` to serialize data to - * transmit. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback2( - nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_session_callbacks_set_recv_callback2()` - * with :type:`nghttp2_recv_callback2` instead. - * - * Sets callback function invoked when the a session wants to receive - * data from the remote peer. This callback is not necessary if the - * application uses solely `nghttp2_session_mem_recv()` to process - * received data. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Sets callback function invoked when the a session wants to receive - * data from the remote peer. This callback is not necessary if the - * application uses solely `nghttp2_session_mem_recv2()` to process - * received data. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback2( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback); - -/** - * @function - * - * Sets callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv2()` when a frame is received. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_recv_callback on_frame_recv_callback); - -/** - * @function - * - * Sets callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv2()` when an invalid non-DATA frame is - * received. - */ -NGHTTP2_EXTERN void -nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback); - -/** - * @function - * - * Sets callback function invoked when a chunk of data in DATA frame - * is received. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback); - -/** - * @function - * - * Sets callback function invoked before a non-DATA frame is sent. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_before_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_before_frame_send_callback before_frame_send_callback); - -/** - * @function - * - * Sets callback function invoked after a frame is sent. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_send_callback on_frame_send_callback); - -/** - * @function - * - * Sets callback function invoked when a non-DATA frame is not sent - * because of an error. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_not_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_not_send_callback on_frame_not_send_callback); - -/** - * @function - * - * Sets callback function invoked when the stream is closed. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_stream_close_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_stream_close_callback on_stream_close_callback); - -/** - * @function - * - * Sets callback function invoked when the reception of header block - * in HEADERS or PUSH_PROMISE is started. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_headers_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_headers_callback on_begin_headers_callback); - -/** - * @function - * - * Sets callback function invoked when a header name/value pair is - * received. If both - * `nghttp2_session_callbacks_set_on_header_callback()` and - * `nghttp2_session_callbacks_set_on_header_callback2()` are used to - * set callbacks, the latter has the precedence. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback on_header_callback); - -/** - * @function - * - * Sets callback function invoked when a header name/value pair is - * received. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback2 on_header_callback2); - -/** - * @function - * - * Sets callback function invoked when an invalid header name/value - * pair is received. If both - * `nghttp2_session_callbacks_set_on_invalid_header_callback()` and - * `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are - * used to set callbacks, the latter takes the precedence. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback on_invalid_header_callback); - -/** - * @function - * - * Sets callback function invoked when an invalid header name/value - * pair is received. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback2 on_invalid_header_callback2); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use - * `nghttp2_session_callbacks_set_select_padding_callback2()` with - * :type:`nghttp2_select_padding_callback2` instead. - * - * Sets callback function invoked when the library asks application - * how many padding bytes are required for the transmission of the - * given frame. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback select_padding_callback); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Sets callback function invoked when the library asks application - * how many padding bytes are required for the transmission of the - * given frame. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback2 select_padding_callback); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use - * `nghttp2_session_callbacks_set_data_source_read_length_callback2()` - * with :type:`nghttp2_data_source_read_length_callback2` instead. - * - * Sets callback function determine the length allowed in - * :type:`nghttp2_data_source_read_callback`. - */ -NGHTTP2_EXTERN void -nghttp2_session_callbacks_set_data_source_read_length_callback( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback data_source_read_length_callback); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Sets callback function determine the length allowed in - * :type:`nghttp2_data_source_read_callback2`. - */ -NGHTTP2_EXTERN void -nghttp2_session_callbacks_set_data_source_read_length_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback2 data_source_read_length_callback); - -/** - * @function - * - * Sets callback function invoked when a frame header is received. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_frame_callback on_begin_frame_callback); - -/** - * @function - * - * Sets callback function invoked when - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in - * :type:`nghttp2_data_source_read_callback2` to avoid data copy. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback( - nghttp2_session_callbacks *cbs, - nghttp2_send_data_callback send_data_callback); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use - * `nghttp2_session_callbacks_set_pack_extension_callback2()` with - * :type:`nghttp2_pack_extension_callback2` instead. - * - * Sets callback function invoked when the library asks the - * application to pack extension frame payload in wire format. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback pack_extension_callback); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Sets callback function invoked when the library asks the - * application to pack extension frame payload in wire format. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback2 pack_extension_callback); - -/** - * @function - * - * Sets callback function invoked when the library asks the - * application to unpack extension frame payload from wire format. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_unpack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_unpack_extension_callback unpack_extension_callback); - -/** - * @function - * - * Sets callback function invoked when chunk of extension frame - * payload is received. - */ -NGHTTP2_EXTERN void -nghttp2_session_callbacks_set_on_extension_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback); - -/** - * @function - * - * .. warning:: - * - * Deprecated. Use - * `nghttp2_session_callbacks_set_error_callback2()` with - * :type:`nghttp2_error_callback2` instead. - * - * Sets callback function invoked when library tells error message to - * the application. - * - * If both :type:`nghttp2_error_callback` and - * :type:`nghttp2_error_callback2` are set, the latter takes - * precedence. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback( - nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback); - -/** - * @function - * - * Sets callback function invoked when library tells error code, and - * message to the application. - * - * If both :type:`nghttp2_error_callback` and - * :type:`nghttp2_error_callback2` are set, the latter takes - * precedence. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2( - nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2); - -/** - * @function - * - * Sets callback function invoked when unpredictable data is needed. - * Although this callback is optional due to the backward - * compatibility, it is recommended to specify it to harden the - * runtime behavior against suspicious activities of a remote - * endpoint. - */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_rand_callback( - nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback); - -/** - * @functypedef - * - * Custom memory allocator to replace malloc(). The |mem_user_data| - * is the mem_user_data member of :type:`nghttp2_mem` structure. - */ -typedef void *(*nghttp2_malloc)(size_t size, void *mem_user_data); - -/** - * @functypedef - * - * Custom memory allocator to replace free(). The |mem_user_data| is - * the mem_user_data member of :type:`nghttp2_mem` structure. - */ -typedef void (*nghttp2_free)(void *ptr, void *mem_user_data); - -/** - * @functypedef - * - * Custom memory allocator to replace calloc(). The |mem_user_data| - * is the mem_user_data member of :type:`nghttp2_mem` structure. - */ -typedef void *(*nghttp2_calloc)(size_t nmemb, size_t size, void *mem_user_data); - -/** - * @functypedef - * - * Custom memory allocator to replace realloc(). The |mem_user_data| - * is the mem_user_data member of :type:`nghttp2_mem` structure. - */ -typedef void *(*nghttp2_realloc)(void *ptr, size_t size, void *mem_user_data); - -/** - * @struct - * - * Custom memory allocator functions and user defined pointer. The - * |mem_user_data| member is passed to each allocator function. This - * can be used, for example, to achieve per-session memory pool. - * - * In the following example code, ``my_malloc``, ``my_free``, - * ``my_calloc`` and ``my_realloc`` are the replacement of the - * standard allocators ``malloc``, ``free``, ``calloc`` and - * ``realloc`` respectively:: - * - * void *my_malloc_cb(size_t size, void *mem_user_data) { - * return my_malloc(size); - * } - * - * void my_free_cb(void *ptr, void *mem_user_data) { my_free(ptr); } - * - * void *my_calloc_cb(size_t nmemb, size_t size, void *mem_user_data) { - * return my_calloc(nmemb, size); - * } - * - * void *my_realloc_cb(void *ptr, size_t size, void *mem_user_data) { - * return my_realloc(ptr, size); - * } - * - * void session_new() { - * nghttp2_session *session; - * nghttp2_session_callbacks *callbacks; - * nghttp2_mem mem = {NULL, my_malloc_cb, my_free_cb, my_calloc_cb, - * my_realloc_cb}; - * - * ... - * - * nghttp2_session_client_new3(&session, callbacks, NULL, NULL, &mem); - * - * ... - * } - */ -typedef struct { - /** - * An arbitrary user supplied data. This is passed to each - * allocator function. - */ - void *mem_user_data; - /** - * Custom allocator function to replace malloc(). - */ - nghttp2_malloc malloc; - /** - * Custom allocator function to replace free(). - */ - nghttp2_free free; - /** - * Custom allocator function to replace calloc(). - */ - nghttp2_calloc calloc; - /** - * Custom allocator function to replace realloc(). - */ - nghttp2_realloc realloc; -} nghttp2_mem; - -struct nghttp2_option; - -/** - * @struct - * - * Configuration options for :type:`nghttp2_session`. The details of - * this structure are intentionally hidden from the public API. - */ -typedef struct nghttp2_option nghttp2_option; - -/** - * @function - * - * Initializes |*option_ptr| with default values. - * - * When the application finished using this object, it can use - * `nghttp2_option_del()` to free its memory. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_option_new(nghttp2_option **option_ptr); - -/** - * @function - * - * Frees any resources allocated for |option|. If |option| is - * ``NULL``, this function does nothing. - */ -NGHTTP2_EXTERN void nghttp2_option_del(nghttp2_option *option); - -/** - * @function - * - * This option prevents the library from sending WINDOW_UPDATE for a - * connection automatically. If this option is set to nonzero, the - * library won't send WINDOW_UPDATE for DATA until application calls - * `nghttp2_session_consume()` to indicate the consumed amount of - * data. Don't use `nghttp2_submit_window_update()` for this purpose. - * By default, this option is set to zero. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_no_auto_window_update(nghttp2_option *option, int val); - -/** - * @function - * - * This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of - * remote endpoint as if it is received in SETTINGS frame. Without - * specifying this option, the maximum number of outgoing concurrent - * streams is initially limited to 100 to avoid issues when the local - * endpoint submits lots of requests before receiving initial SETTINGS - * frame from the remote endpoint, since sending them at once to the - * remote endpoint could lead to rejection of some of the requests. - * This value will be overwritten when the local endpoint receives - * initial SETTINGS frame from the remote endpoint, either to the - * value advertised in SETTINGS_MAX_CONCURRENT_STREAMS or to the - * default value (unlimited) if none was advertised. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option, - uint32_t val); - -/** - * @function - * - * By default, nghttp2 library, if configured as server, requires - * first 24 bytes of client magic byte string (MAGIC). In most cases, - * this will simplify the implementation of server. But sometimes - * server may want to detect the application protocol based on first - * few bytes on clear text communication. - * - * If this option is used with nonzero |val|, nghttp2 library does not - * handle MAGIC. It still checks following SETTINGS frame. This - * means that applications should deal with MAGIC by themselves. - * - * If this option is not used or used with zero value, if MAGIC does - * not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()` - * and `nghttp2_session_mem_recv2()` will return error - * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal - * error. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val); - -/** - * @function - * - * By default, nghttp2 library enforces subset of HTTP Messaging rules - * described in `HTTP/2 specification, section 8 - * `_. See - * :ref:`http-messaging` section for details. For those applications - * who use nghttp2 library as non-HTTP use, give nonzero to |val| to - * disable this enforcement. Please note that disabling this feature - * does not change the fundamental client and server model of HTTP. - * That is, even if the validation is disabled, only client can send - * requests. - */ -NGHTTP2_EXTERN void nghttp2_option_set_no_http_messaging(nghttp2_option *option, - int val); - -/** - * @function - * - * RFC 7540 does not enforce any limit on the number of incoming - * reserved streams (in RFC 7540 terms, streams in reserved (remote) - * state). This only affects client side, since only server can push - * streams. Malicious server can push arbitrary number of streams, - * and make client's memory exhausted. This option can set the - * maximum number of such incoming streams to avoid possible memory - * exhaustion. If this option is set, and pushed streams are - * automatically closed on reception, without calling user provided - * callback, if they exceed the given limit. The default value is - * 200. If session is configured as server side, this option has no - * effect. Server can control the number of streams to push. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option, - uint32_t val); - -/** - * @function - * - * Sets extension frame type the application is willing to handle with - * user defined callbacks (see - * :type:`nghttp2_on_extension_chunk_recv_callback` and - * :type:`nghttp2_unpack_extension_callback`). The |type| is - * extension frame type, and must be strictly greater than 0x9. - * Otherwise, this function does nothing. The application can call - * this function multiple times to set more than one frame type to - * receive. The application does not have to call this function if it - * just sends extension frames. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_user_recv_extension_type(nghttp2_option *option, - uint8_t type); - -/** - * @function - * - * Sets extension frame type the application is willing to receive - * using builtin handler. The |type| is the extension frame type to - * receive, and must be strictly greater than 0x9. Otherwise, this - * function does nothing. The application can call this function - * multiple times to set more than one frame type to receive. The - * application does not have to call this function if it just sends - * extension frames. - * - * If same frame type is passed to both - * `nghttp2_option_set_builtin_recv_extension_type()` and - * `nghttp2_option_set_user_recv_extension_type()`, the latter takes - * precedence. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option, - uint8_t type); - -/** - * @function - * - * This option prevents the library from sending PING frame with ACK - * flag set automatically when PING frame without ACK flag set is - * received. If this option is set to nonzero, the library won't send - * PING frame with ACK flag set in the response for incoming PING - * frame. The application can send PING frame with ACK flag set using - * `nghttp2_submit_ping()` with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` - * as flags parameter. - */ -NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, - int val); - -/** - * @function - * - * This option sets the maximum length of header block (a set of - * header fields per one HEADERS frame) to send. The length of a - * given set of header fields is calculated using - * `nghttp2_hd_deflate_bound()`. The default value is 64KiB. If - * application attempts to send header fields larger than this limit, - * the transmission of the frame fails with error code - * :enum:`nghttp2_error.NGHTTP2_ERR_FRAME_SIZE_ERROR`. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_max_send_header_block_length(nghttp2_option *option, - size_t val); - -/** - * @function - * - * This option sets the maximum dynamic table size for deflating - * header fields. The default value is 4KiB. In HTTP/2, receiver of - * deflated header block can specify maximum dynamic table size. The - * actual maximum size is the minimum of the size receiver specified - * and this option value. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option, - size_t val); - -/** - * @function - * - * .. warning:: - * - * Deprecated. Closed streams are not retained anymore. - * - * This function works as before, but it does not take any effect - * against :type:`nghttp2_session`. - */ -NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option, - int val); - -/** - * @function - * - * This function sets the maximum number of outgoing SETTINGS ACK and - * PING ACK frames retained in :type:`nghttp2_session` object. If - * more than those frames are retained, the peer is considered to be - * misbehaving and session will be closed. The default value is 1000. - */ -NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option, - size_t val); - -/** - * @function - * - * This function sets the maximum number of SETTINGS entries per - * SETTINGS frame that will be accepted. If more than those entries - * are received, the peer is considered to be misbehaving and session - * will be closed. The default value is 32. - */ -NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option, - size_t val); - -/** - * @function - * - * .. warning:: - * Deprecated. :rfc:`7540` priorities have been removed. - * - * This function works as before, but it does not take any effect - * against :type:`nghttp2_session`. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option, - int val); - -/** - * @function - * - * This option, if set to nonzero, turns off RFC 9113 leading and - * trailing white spaces validation against HTTP field value. Some - * important fields, such as HTTP/2 pseudo header fields, are - * validated more strictly and this option does not apply to them. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - nghttp2_option *option, int val); - -/** - * @function - * - * This function sets the rate limit for the incoming stream reset - * (RST_STREAM frame). It is server use only. It is a token-bucket - * based rate limiter. |burst| specifies the number of tokens that is - * initially available. The maximum number of tokens is capped to - * this value. |rate| specifies the number of tokens that are - * regenerated per second. An incoming RST_STREAM consumes one token. - * If there is no token available, GOAWAY is sent to tear down the - * connection. |burst| and |rate| default to 1000 and 33 - * respectively. - */ -NGHTTP2_EXTERN void -nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, - uint64_t burst, uint64_t rate); - -/** - * @function - * - * This function sets the maximum number of CONTINUATION frames - * following an incoming HEADER frame. If more than those frames are - * received, the remote endpoint is considered to be misbehaving and - * session will be closed. The default value is 8. - */ -NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option, - size_t val); - -/** - * @function - * - * This function sets the rate limit for the "glitches", the - * suspicious activities from a remote endpoint. It is a token-bucket - * based rate limiter. |burst| specifies the number of tokens that is - * initially available. The maximum number of tokens is capped to - * this value. |rate| specifies the number of tokens that are - * regenerated per second. When a suspicious activity is detected, - * some amount of tokens are consumed. If there is no token - * available, GOAWAY is sent to tear down the connection. |burst| and - * |rate| default to 1000 and 33 respectively. - */ -NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option, - uint64_t burst, - uint64_t rate); - -/** - * @function - * - * Initializes |*session_ptr| for client use. The all members of - * |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr| - * does not store |callbacks|. The |user_data| is an arbitrary user - * supplied data, which will be passed to the callback functions. - * - * The :type:`nghttp2_send_callback2` must be specified. If the - * application code uses `nghttp2_session_recv()`, the - * :type:`nghttp2_recv_callback` must be specified. The other members - * of |callbacks| can be ``NULL``. - * - * If this function fails, |*session_ptr| is left untouched. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_session_client_new(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data); - -/** - * @function - * - * Initializes |*session_ptr| for server use. The all members of - * |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr| - * does not store |callbacks|. The |user_data| is an arbitrary user - * supplied data, which will be passed to the callback functions. - * - * The :type:`nghttp2_send_callback2` must be specified. If the - * application code uses `nghttp2_session_recv()`, the - * :type:`nghttp2_recv_callback` must be specified. The other members - * of |callbacks| can be ``NULL``. - * - * If this function fails, |*session_ptr| is left untouched. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_session_server_new(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data); - -/** - * @function - * - * Like `nghttp2_session_client_new()`, but with additional options - * specified in the |option|. - * - * The |option| can be ``NULL`` and the call is equivalent to - * `nghttp2_session_client_new()`. - * - * This function does not take ownership |option|. The application is - * responsible for freeing |option| if it finishes using the object. - * - * The library code does not refer to |option| after this function - * returns. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_session_client_new2(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option); - -/** - * @function - * - * Like `nghttp2_session_server_new()`, but with additional options - * specified in the |option|. - * - * The |option| can be ``NULL`` and the call is equivalent to - * `nghttp2_session_server_new()`. - * - * This function does not take ownership |option|. The application is - * responsible for freeing |option| if it finishes using the object. - * - * The library code does not refer to |option| after this function - * returns. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_session_server_new2(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option); - -/** - * @function - * - * Like `nghttp2_session_client_new2()`, but with additional custom - * memory allocator specified in the |mem|. - * - * The |mem| can be ``NULL`` and the call is equivalent to - * `nghttp2_session_client_new2()`. - * - * This function does not take ownership |mem|. The application is - * responsible for freeing |mem|. - * - * The library code does not refer to |mem| pointer after this - * function returns, so the application can safely free it. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_session_client_new3( - nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, nghttp2_mem *mem); - -/** - * @function - * - * Like `nghttp2_session_server_new2()`, but with additional custom - * memory allocator specified in the |mem|. - * - * The |mem| can be ``NULL`` and the call is equivalent to - * `nghttp2_session_server_new2()`. - * - * This function does not take ownership |mem|. The application is - * responsible for freeing |mem|. - * - * The library code does not refer to |mem| pointer after this - * function returns, so the application can safely free it. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_session_server_new3( - nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, nghttp2_mem *mem); - -/** - * @function - * - * Frees any resources allocated for |session|. If |session| is - * ``NULL``, this function does nothing. - */ -NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session); - -/** - * @function - * - * Sends pending frames to the remote peer. - * - * This function retrieves the highest prioritized frame from the - * outbound queue and sends it to the remote peer. It does this as - * many times as possible until the user callback - * :type:`nghttp2_send_callback2` returns - * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue - * becomes empty or flow control is triggered (remote window size - * becomes depleted or maximum number of concurrent streams is - * reached). This function calls several callback functions which are - * passed when initializing the |session|. Here is the simple time - * chart which tells when each callback is invoked: - * - * 1. Get the next frame to send from outbound queue. - * - * 2. Prepare transmission of the frame. - * - * 3. If the control frame cannot be sent because some preconditions - * are not met (e.g., request HEADERS cannot be sent after GOAWAY), - * :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort - * the following steps. - * - * 4. If the frame is HEADERS, PUSH_PROMISE or DATA, - * :type:`nghttp2_select_padding_callback` is invoked. - * - * 5. If the frame is request HEADERS, the stream is opened here. - * - * 6. :type:`nghttp2_before_frame_send_callback` is invoked. - * - * 7. If :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` is returned from - * :type:`nghttp2_before_frame_send_callback`, the current frame - * transmission is canceled, and - * :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort - * the following steps. - * - * 8. :type:`nghttp2_send_callback2` is invoked one or more times to - * send the frame. - * - * 9. :type:`nghttp2_on_frame_send_callback` is invoked. - * - * 10. If the transmission of the frame triggers closure of the - * stream, the stream is closed and - * :type:`nghttp2_on_stream_close_callback` is invoked. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` - * The callback function failed. - */ -NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_session_mem_send2()` instead. - * - * Returns the serialized data to send. - * - * This function behaves like `nghttp2_session_send()` except that it - * does not use :type:`nghttp2_send_callback` to transmit data. - * Instead, it assigns the pointer to the serialized data to the - * |*data_ptr| and returns its length. The other callbacks are called - * in the same way as they are in `nghttp2_session_send()`. - * - * If no data is available to send, this function returns 0. - * - * This function may not return all serialized data in one invocation. - * To get all data, call this function repeatedly until it returns 0 - * or one of negative error codes. - * - * The assigned |*data_ptr| is valid until the next call of - * `nghttp2_session_mem_send()` or `nghttp2_session_send()`. - * - * The caller must send all data before sending the next chunk of - * data. - * - * This function returns the length of the data pointed by the - * |*data_ptr| if it succeeds, or one of the following negative error - * codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * - * .. note:: - * - * This function may produce very small byte string. If that is the - * case, and application disables Nagle algorithm (``TCP_NODELAY``), - * then writing this small chunk leads to very small packet, and it - * is very inefficient. An application should be responsible to - * buffer up small chunks of data as necessary to avoid this - * situation. - */ -NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session, - const uint8_t **data_ptr); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Returns the serialized data to send. - * - * This function behaves like `nghttp2_session_send()` except that it - * does not use :type:`nghttp2_send_callback2` to transmit data. - * Instead, it assigns the pointer to the serialized data to the - * |*data_ptr| and returns its length. The other callbacks are called - * in the same way as they are in `nghttp2_session_send()`. - * - * If no data is available to send, this function returns 0. - * - * This function may not return all serialized data in one invocation. - * To get all data, call this function repeatedly until it returns 0 - * or one of negative error codes. - * - * The assigned |*data_ptr| is valid until the next call of - * `nghttp2_session_mem_send2()` or `nghttp2_session_send()`. - * - * The caller must send all data before sending the next chunk of - * data. - * - * This function returns the length of the data pointed by the - * |*data_ptr| if it succeeds, or one of the following negative error - * codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * - * .. note:: - * - * This function may produce very small byte string. If that is the - * case, and application disables Nagle algorithm (``TCP_NODELAY``), - * then writing this small chunk leads to very small packet, and it - * is very inefficient. An application should be responsible to - * buffer up small chunks of data as necessary to avoid this - * situation. - */ -NGHTTP2_EXTERN nghttp2_ssize -nghttp2_session_mem_send2(nghttp2_session *session, const uint8_t **data_ptr); - -/** - * @function - * - * Receives frames from the remote peer. - * - * This function receives as many frames as possible until the user - * callback :type:`nghttp2_recv_callback` returns - * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. This function calls - * several callback functions which are passed when initializing the - * |session|. Here is the simple time chart which tells when each - * callback is invoked: - * - * 1. :type:`nghttp2_recv_callback` is invoked one or more times to - * receive frame header. - * - * 2. When frame header is received, - * :type:`nghttp2_on_begin_frame_callback` is invoked. - * - * 3. If the frame is DATA frame: - * - * 1. :type:`nghttp2_recv_callback` is invoked to receive DATA - * payload. For each chunk of data, - * :type:`nghttp2_on_data_chunk_recv_callback` is invoked. - * - * 2. If one DATA frame is completely received, - * :type:`nghttp2_on_frame_recv_callback` is invoked. If the - * reception of the frame triggers the closure of the stream, - * :type:`nghttp2_on_stream_close_callback` is invoked. - * - * 4. If the frame is the control frame: - * - * 1. :type:`nghttp2_recv_callback` is invoked one or more times to - * receive whole frame. - * - * 2. If the received frame is valid, then following actions are - * taken. If the frame is either HEADERS or PUSH_PROMISE, - * :type:`nghttp2_on_begin_headers_callback` is invoked. Then - * :type:`nghttp2_on_header_callback` is invoked for each header - * name/value pair. For invalid header field, - * :type:`nghttp2_on_invalid_header_callback` is called. After - * all name/value pairs are emitted successfully, - * :type:`nghttp2_on_frame_recv_callback` is invoked. For other - * frames, :type:`nghttp2_on_frame_recv_callback` is invoked. - * If the reception of the frame triggers the closure of the - * stream, :type:`nghttp2_on_stream_close_callback` is invoked. - * - * 3. If the received frame is unpacked but is interpreted as - * invalid, :type:`nghttp2_on_invalid_frame_recv_callback` is - * invoked. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_EOF` - * The remote peer did shutdown on the connection. - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` - * The callback function failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC` - * Invalid client magic was detected. This error only returns - * when |session| was configured as server and - * `nghttp2_option_set_no_recv_client_magic()` is not used with - * nonzero value. - * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED` - * Flooding was detected in this HTTP/2 session, and it must be - * closed. This is most likely caused by misbehaviour of peer. - */ -NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_session_mem_recv2()` instead. - * - * Processes data |in| as an input from the remote endpoint. The - * |inlen| indicates the number of bytes to receive in the |in|. - * - * This function behaves like `nghttp2_session_recv()` except that it - * does not use :type:`nghttp2_recv_callback` to receive data; the - * |in| is the only data for the invocation of this function. If all - * bytes are processed, this function returns. The other callbacks - * are called in the same way as they are in `nghttp2_session_recv()`. - * - * In the current implementation, this function always tries to - * processes |inlen| bytes of input data unless either an error occurs or - * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from - * :type:`nghttp2_on_header_callback` or - * :type:`nghttp2_on_data_chunk_recv_callback`. If - * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value - * includes the number of bytes which was used to produce the data or - * frame for the callback. - * - * This function returns the number of processed bytes, or one of the - * following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` - * The callback function failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC` - * Invalid client magic was detected. This error only returns - * when |session| was configured as server and - * `nghttp2_option_set_no_recv_client_magic()` is not used with - * nonzero value. - * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED` - * Flooding was detected in this HTTP/2 session, and it must be - * closed. This is most likely caused by misbehaviour of peer. - */ -NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session, - const uint8_t *in, - size_t inlen); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Processes data |in| as an input from the remote endpoint. The - * |inlen| indicates the number of bytes to receive in the |in|. - * - * This function behaves like `nghttp2_session_recv()` except that it - * does not use :type:`nghttp2_recv_callback` to receive data; the - * |in| is the only data for the invocation of this function. If all - * bytes are processed, this function returns. The other callbacks - * are called in the same way as they are in `nghttp2_session_recv()`. - * - * In the current implementation, this function always tries to - * processes |inlen| bytes of input data unless either an error occurs or - * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from - * :type:`nghttp2_on_header_callback` or - * :type:`nghttp2_on_data_chunk_recv_callback`. If - * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value - * includes the number of bytes which was used to produce the data or - * frame for the callback. - * - * This function returns the number of processed bytes, or one of the - * following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` - * The callback function failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC` - * Invalid client magic was detected. This error only returns - * when |session| was configured as server and - * `nghttp2_option_set_no_recv_client_magic()` is not used with - * nonzero value. - * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED` - * Flooding was detected in this HTTP/2 session, and it must be - * closed. This is most likely caused by misbehaviour of peer. - */ -NGHTTP2_EXTERN nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, - const uint8_t *in, - size_t inlen); - -/** - * @function - * - * Puts back previously deferred DATA frame in the stream |stream_id| - * to the outbound queue. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The stream does not exist; or no deferred data exist. - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_session_resume_data(nghttp2_session *session, - int32_t stream_id); - -/** - * @function - * - * Returns nonzero value if |session| wants to receive data from the - * remote peer. - * - * If both `nghttp2_session_want_read()` and - * `nghttp2_session_want_write()` return 0, the application should - * drop the connection. - */ -NGHTTP2_EXTERN int nghttp2_session_want_read(nghttp2_session *session); - -/** - * @function - * - * Returns nonzero value if |session| wants to send data to the remote - * peer. - * - * If both `nghttp2_session_want_read()` and - * `nghttp2_session_want_write()` return 0, the application should - * drop the connection. - */ -NGHTTP2_EXTERN int nghttp2_session_want_write(nghttp2_session *session); - -/** - * @function - * - * Returns stream_user_data for the stream |stream_id|. The - * stream_user_data is provided by `nghttp2_submit_request2()`, - * `nghttp2_submit_headers()` or - * `nghttp2_session_set_stream_user_data()`. Unless it is set using - * `nghttp2_session_set_stream_user_data()`, if the stream is - * initiated by the remote endpoint, stream_user_data is always - * ``NULL``. If the stream does not exist, this function returns - * ``NULL``. - */ -NGHTTP2_EXTERN void * -nghttp2_session_get_stream_user_data(nghttp2_session *session, - int32_t stream_id); - -/** - * @function - * - * Sets the |stream_user_data| to the stream denoted by the - * |stream_id|. If a stream user data is already set to the stream, - * it is replaced with the |stream_user_data|. It is valid to specify - * ``NULL`` in the |stream_user_data|, which nullifies the associated - * data pointer. - * - * It is valid to set the |stream_user_data| to the stream reserved by - * PUSH_PROMISE frame. - * - * This function returns 0 if it succeeds, or one of following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The stream does not exist - */ -NGHTTP2_EXTERN int -nghttp2_session_set_stream_user_data(nghttp2_session *session, - int32_t stream_id, void *stream_user_data); - -/** - * @function - * - * Sets |user_data| to |session|, overwriting the existing user data - * specified in `nghttp2_session_client_new()`, or - * `nghttp2_session_server_new()`. - */ -NGHTTP2_EXTERN void nghttp2_session_set_user_data(nghttp2_session *session, - void *user_data); - -/** - * @function - * - * Returns the number of frames in the outbound queue. This does not - * include the deferred DATA frames. - */ -NGHTTP2_EXTERN size_t -nghttp2_session_get_outbound_queue_size(nghttp2_session *session); - -/** - * @function - * - * Returns the number of DATA payload in bytes received without - * WINDOW_UPDATE transmission for the stream |stream_id|. The local - * (receive) window size can be adjusted by - * `nghttp2_submit_window_update()`. This function takes into account - * that and returns effective data length. In particular, if the - * local window size is reduced by submitting negative - * window_size_increment with `nghttp2_submit_window_update()`, this - * function returns the number of bytes less than actually received. - * - * This function returns -1 if it fails. - */ -NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length( - nghttp2_session *session, int32_t stream_id); - -/** - * @function - * - * Returns the local (receive) window size for the stream |stream_id|. - * The local window size can be adjusted by - * `nghttp2_submit_window_update()`. This function takes into account - * that and returns effective window size. - * - * This function does not take into account the amount of received - * data from the remote endpoint. Use - * `nghttp2_session_get_stream_local_window_size()` to know the amount - * of data the remote endpoint can send without receiving stream level - * WINDOW_UPDATE frame. Note that each stream is still subject to the - * connection level flow control. - * - * This function returns -1 if it fails. - */ -NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size( - nghttp2_session *session, int32_t stream_id); - -/** - * @function - * - * Returns the amount of flow-controlled payload (e.g., DATA) that the - * remote endpoint can send without receiving stream level - * WINDOW_UPDATE frame. It is also subject to the connection level - * flow control. So the actual amount of data to send is - * min(`nghttp2_session_get_stream_local_window_size()`, - * `nghttp2_session_get_local_window_size()`). - * - * This function returns -1 if it fails. - */ -NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_local_window_size( - nghttp2_session *session, int32_t stream_id); - -/** - * @function - * - * Returns the number of DATA payload in bytes received without - * WINDOW_UPDATE transmission for a connection. The local (receive) - * window size can be adjusted by `nghttp2_submit_window_update()`. - * This function takes into account that and returns effective data - * length. In particular, if the local window size is reduced by - * submitting negative window_size_increment with - * `nghttp2_submit_window_update()`, this function returns the number - * of bytes less than actually received. - * - * This function returns -1 if it fails. - */ -NGHTTP2_EXTERN int32_t -nghttp2_session_get_effective_recv_data_length(nghttp2_session *session); - -/** - * @function - * - * Returns the local (receive) window size for a connection. The - * local window size can be adjusted by - * `nghttp2_submit_window_update()`. This function takes into account - * that and returns effective window size. - * - * This function does not take into account the amount of received - * data from the remote endpoint. Use - * `nghttp2_session_get_local_window_size()` to know the amount of - * data the remote endpoint can send without receiving - * connection-level WINDOW_UPDATE frame. Note that each stream is - * still subject to the stream level flow control. - * - * This function returns -1 if it fails. - */ -NGHTTP2_EXTERN int32_t -nghttp2_session_get_effective_local_window_size(nghttp2_session *session); - -/** - * @function - * - * Returns the amount of flow-controlled payload (e.g., DATA) that the - * remote endpoint can send without receiving connection level - * WINDOW_UPDATE frame. Note that each stream is still subject to the - * stream level flow control (see - * `nghttp2_session_get_stream_local_window_size()`). - * - * This function returns -1 if it fails. - */ -NGHTTP2_EXTERN int32_t -nghttp2_session_get_local_window_size(nghttp2_session *session); - -/** - * @function - * - * Returns the remote window size for a given stream |stream_id|. - * - * This is the amount of flow-controlled payload (e.g., DATA) that the - * local endpoint can send without stream level WINDOW_UPDATE. There - * is also connection level flow control, so the effective size of - * payload that the local endpoint can actually send is - * min(`nghttp2_session_get_stream_remote_window_size()`, - * `nghttp2_session_get_remote_window_size()`). - * - * This function returns -1 if it fails. - */ -NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_remote_window_size( - nghttp2_session *session, int32_t stream_id); - -/** - * @function - * - * Returns the remote window size for a connection. - * - * This function always succeeds. - */ -NGHTTP2_EXTERN int32_t -nghttp2_session_get_remote_window_size(nghttp2_session *session); - -/** - * @function - * - * Returns 1 if local peer half closed the given stream |stream_id|. - * Returns 0 if it did not. Returns -1 if no such stream exists. - */ -NGHTTP2_EXTERN int -nghttp2_session_get_stream_local_close(nghttp2_session *session, - int32_t stream_id); - -/** - * @function - * - * Returns 1 if remote peer half closed the given stream |stream_id|. - * Returns 0 if it did not. Returns -1 if no such stream exists. - */ -NGHTTP2_EXTERN int -nghttp2_session_get_stream_remote_close(nghttp2_session *session, - int32_t stream_id); - -/** - * @function - * - * Returns the current dynamic table size of HPACK inflater, including - * the overhead 32 bytes per entry described in RFC 7541. - */ -NGHTTP2_EXTERN size_t -nghttp2_session_get_hd_inflate_dynamic_table_size(nghttp2_session *session); - -/** - * @function - * - * Returns the current dynamic table size of HPACK deflater including - * the overhead 32 bytes per entry described in RFC 7541. - */ -NGHTTP2_EXTERN size_t -nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session); - -/** - * @function - * - * Signals the session so that the connection should be terminated. - * - * The last stream ID is the minimum value between the stream ID of a - * stream for which :type:`nghttp2_on_frame_recv_callback` was called - * most recently and the last stream ID we have sent to the peer - * previously. - * - * The |error_code| is the error code of this GOAWAY frame. The - * pre-defined error code is one of :enum:`nghttp2_error_code`. - * - * After the transmission, both `nghttp2_session_want_read()` and - * `nghttp2_session_want_write()` return 0. - * - * This function should be called when the connection should be - * terminated after sending GOAWAY. If the remaining streams should - * be processed after GOAWAY, use `nghttp2_submit_goaway()` instead. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session, - uint32_t error_code); - -/** - * @function - * - * Signals the session so that the connection should be terminated. - * - * This function behaves like `nghttp2_session_terminate_session()`, - * but the last stream ID can be specified by the application for fine - * grained control of stream. The HTTP/2 specification does not allow - * last_stream_id to be increased. So the actual value sent as - * last_stream_id is the minimum value between the given - * |last_stream_id| and the last_stream_id we have previously sent to - * the peer. - * - * The |last_stream_id| is peer's stream ID or 0. So if |session| is - * initialized as client, |last_stream_id| must be even or 0. If - * |session| is initialized as server, |last_stream_id| must be odd or - * 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |last_stream_id| is invalid. - */ -NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session, - int32_t last_stream_id, - uint32_t error_code); - -/** - * @function - * - * Signals to the client that the server started graceful shutdown - * procedure. - * - * This function is only usable for server. If this function is - * called with client side session, this function returns - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. - * - * To gracefully shutdown HTTP/2 session, server should call this - * function to send GOAWAY with last_stream_id (1u << 31) - 1. And - * after some delay (e.g., 1 RTT), send another GOAWAY with the stream - * ID that the server has some processing using - * `nghttp2_submit_goaway()`. See also - * `nghttp2_session_get_last_proc_stream_id()`. - * - * Unlike `nghttp2_submit_goaway()`, this function just sends GOAWAY - * and does nothing more. This is a mere indication to the client - * that session shutdown is imminent. The application should call - * `nghttp2_submit_goaway()` with appropriate last_stream_id after - * this call. - * - * If one or more GOAWAY frame have been already sent by either - * `nghttp2_submit_goaway()` or `nghttp2_session_terminate_session()`, - * this function has no effect. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * The |session| is initialized as client. - */ -NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session); - -/** - * @function - * - * Returns the value of SETTINGS |id| notified by a remote endpoint. - * The |id| must be one of values defined in - * :enum:`nghttp2_settings_id`. - */ -NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings( - nghttp2_session *session, nghttp2_settings_id id); - -/** - * @function - * - * Returns the value of SETTINGS |id| of local endpoint acknowledged - * by the remote endpoint. The |id| must be one of the values defined - * in :enum:`nghttp2_settings_id`. - */ -NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings( - nghttp2_session *session, nghttp2_settings_id id); - -/** - * @function - * - * Tells the |session| that next stream ID is |next_stream_id|. The - * |next_stream_id| must be equal or greater than the value returned - * by `nghttp2_session_get_next_stream_id()`. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |next_stream_id| is strictly less than the value - * `nghttp2_session_get_next_stream_id()` returns; or - * |next_stream_id| is invalid (e.g., even integer for client, or - * odd integer for server). - */ -NGHTTP2_EXTERN int nghttp2_session_set_next_stream_id(nghttp2_session *session, - int32_t next_stream_id); - -/** - * @function - * - * Returns the next outgoing stream ID. Notice that return type is - * uint32_t. If we run out of stream ID for this session, this - * function returns 1 << 31. - */ -NGHTTP2_EXTERN uint32_t -nghttp2_session_get_next_stream_id(nghttp2_session *session); - -/** - * @function - * - * Tells the |session| that |size| bytes for a stream denoted by - * |stream_id| were consumed by application and are ready to - * WINDOW_UPDATE. The consumed bytes are counted towards both - * connection and stream level WINDOW_UPDATE (see - * `nghttp2_session_consume_connection()` and - * `nghttp2_session_consume_stream()` to update consumption - * independently). This function is intended to be used without - * automatic window update (see - * `nghttp2_option_set_no_auto_window_update()`). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * Automatic WINDOW_UPDATE is not disabled. - */ -NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session, - int32_t stream_id, size_t size); - -/** - * @function - * - * Like `nghttp2_session_consume()`, but this only tells library that - * |size| bytes were consumed only for connection level. Note that - * HTTP/2 maintains connection and stream level flow control windows - * independently. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * Automatic WINDOW_UPDATE is not disabled. - */ -NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session, - size_t size); - -/** - * @function - * - * Like `nghttp2_session_consume()`, but this only tells library that - * |size| bytes were consumed only for stream denoted by |stream_id|. - * Note that HTTP/2 maintains connection and stream level flow control - * windows independently. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * Automatic WINDOW_UPDATE is not disabled. - */ -NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session, - int32_t stream_id, - size_t size); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function is noop. It always returns 0. - */ -NGHTTP2_EXTERN int -nghttp2_session_change_stream_priority(nghttp2_session *session, - int32_t stream_id, - const nghttp2_priority_spec *pri_spec); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function is noop. It always returns 0. - */ -NGHTTP2_EXTERN int -nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id, - const nghttp2_priority_spec *pri_spec); - -/** - * @function - * - * .. warning:: - * - * This function is deprecated in favor of - * `nghttp2_session_upgrade2()`, because this function lacks the - * parameter to tell the library the request method used in the - * original HTTP request. This information is required for client - * to validate actual response body length against content-length - * header field (see `nghttp2_option_set_no_http_messaging()`). If - * HEAD is used in request, the length of response body must be 0 - * regardless of value included in content-length header field. - * - * Performs post-process of HTTP Upgrade request. This function can - * be called from both client and server, but the behavior is very - * different in each other. - * - * If called from client side, the |settings_payload| must be the - * value sent in ``HTTP2-Settings`` header field and must be decoded - * by base64url decoder. The |settings_payloadlen| is the length of - * |settings_payload|. The |settings_payload| is unpacked and its - * setting values will be submitted using `nghttp2_submit_settings()`. - * This means that the client application code does not need to submit - * SETTINGS by itself. The stream with stream ID=1 is opened and the - * |stream_user_data| is used for its stream_user_data. The opened - * stream becomes half-closed (local) state. - * - * If called from server side, the |settings_payload| must be the - * value received in ``HTTP2-Settings`` header field and must be - * decoded by base64url decoder. The |settings_payloadlen| is the - * length of |settings_payload|. It is treated as if the SETTINGS - * frame with that payload is received. Thus, callback functions for - * the reception of SETTINGS frame will be invoked. The stream with - * stream ID=1 is opened. The |stream_user_data| is ignored. The - * opened stream becomes half-closed (remote). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |settings_payload| is badly formed. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * The stream ID 1 is already used or closed; or is not available. - */ -NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session, - const uint8_t *settings_payload, - size_t settings_payloadlen, - void *stream_user_data); - -/** - * @function - * - * Performs post-process of HTTP Upgrade request. This function can - * be called from both client and server, but the behavior is very - * different in each other. - * - * If called from client side, the |settings_payload| must be the - * value sent in ``HTTP2-Settings`` header field and must be decoded - * by base64url decoder. The |settings_payloadlen| is the length of - * |settings_payload|. The |settings_payload| is unpacked and its - * setting values will be submitted using `nghttp2_submit_settings()`. - * This means that the client application code does not need to submit - * SETTINGS by itself. The stream with stream ID=1 is opened and the - * |stream_user_data| is used for its stream_user_data. The opened - * stream becomes half-closed (local) state. - * - * If called from server side, the |settings_payload| must be the - * value received in ``HTTP2-Settings`` header field and must be - * decoded by base64url decoder. The |settings_payloadlen| is the - * length of |settings_payload|. It is treated as if the SETTINGS - * frame with that payload is received. Thus, callback functions for - * the reception of SETTINGS frame will be invoked. The stream with - * stream ID=1 is opened. The |stream_user_data| is ignored. The - * opened stream becomes half-closed (remote). - * - * If the request method is HEAD, pass nonzero value to - * |head_request|. Otherwise, pass 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |settings_payload| is badly formed. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * The stream ID 1 is already used or closed; or is not available. - */ -NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session, - const uint8_t *settings_payload, - size_t settings_payloadlen, - int head_request, - void *stream_user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_pack_settings_payload2()` instead. - * - * Serializes the SETTINGS values |iv| in the |buf|. The size of the - * |buf| is specified by |buflen|. The number of entries in the |iv| - * array is given by |niv|. The required space in |buf| for the |niv| - * entries is ``6*niv`` bytes and if the given buffer is too small, an - * error is returned. This function is used mainly for creating a - * SETTINGS payload to be sent with the ``HTTP2-Settings`` header - * field in an HTTP Upgrade request. The data written in |buf| is NOT - * base64url encoded and the application is responsible for encoding. - * - * This function returns the number of bytes written in |buf|, or one - * of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |iv| contains duplicate settings ID or invalid value. - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` - * The provided |buflen| size is too small to hold the output. - */ -NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload( - uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Serializes the SETTINGS values |iv| in the |buf|. The size of the - * |buf| is specified by |buflen|. The number of entries in the |iv| - * array is given by |niv|. The required space in |buf| for the |niv| - * entries is ``6*niv`` bytes and if the given buffer is too small, an - * error is returned. This function is used mainly for creating a - * SETTINGS payload to be sent with the ``HTTP2-Settings`` header - * field in an HTTP Upgrade request. The data written in |buf| is NOT - * base64url encoded and the application is responsible for encoding. - * - * This function returns the number of bytes written in |buf|, or one - * of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |iv| contains duplicate settings ID or invalid value. - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` - * The provided |buflen| size is too small to hold the output. - */ -NGHTTP2_EXTERN nghttp2_ssize nghttp2_pack_settings_payload2( - uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); - -/** - * @function - * - * Returns string describing the |lib_error_code|. The - * |lib_error_code| must be one of the :enum:`nghttp2_error`. - */ -NGHTTP2_EXTERN const char *nghttp2_strerror(int lib_error_code); - -/** - * @function - * - * Returns string representation of HTTP/2 error code |error_code| - * (e.g., ``PROTOCOL_ERROR`` is returned if ``error_code == - * NGHTTP2_PROTOCOL_ERROR``). If string representation is unknown for - * given |error_code|, this function returns string ``unknown``. - */ -NGHTTP2_EXTERN const char *nghttp2_http2_strerror(uint32_t error_code); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * Initializes |pri_spec| with the |stream_id| of the stream to depend - * on with |weight| and its exclusive flag. If |exclusive| is - * nonzero, exclusive flag is set. - * - * The |weight| must be in [:macro:`NGHTTP2_MIN_WEIGHT`, - * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. - */ -NGHTTP2_EXTERN void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec, - int32_t stream_id, - int32_t weight, int exclusive); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * Initializes |pri_spec| with the default values. The default values - * are: stream_id = 0, weight = :macro:`NGHTTP2_DEFAULT_WEIGHT` and - * exclusive = 0. - */ -NGHTTP2_EXTERN void -nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * Returns nonzero if the |pri_spec| is filled with default values. - */ -NGHTTP2_EXTERN int -nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_submit_request2()` instead. - * - * Submits HEADERS frame and optionally one or more DATA frames. - * - * The |pri_spec| is ignored. - * - * The |nva| is an array of name/value pair :type:`nghttp2_nv` with - * |nvlen| elements. The application is responsible to include - * required pseudo-header fields (header field whose name starts with - * ":") in |nva| and must place pseudo-headers before regular header - * fields. - * - * This function creates copies of all name/value pairs in |nva|. It - * also lower-cases all names in |nva|. The order of elements in - * |nva| is preserved. For header fields with - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, - * header field name and value are not copied respectively. With - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application - * is responsible to pass header field name in lowercase. The - * application should maintain the references to them until - * :type:`nghttp2_on_frame_send_callback` or - * :type:`nghttp2_on_frame_not_send_callback` is called. - * - * HTTP/2 specification has requirement about header fields in the - * request HEADERS. See the specification for more details. - * - * If |data_prd| is not ``NULL``, it provides data which will be sent - * in subsequent DATA frames. In this case, a method that allows - * request message bodies - * (https://tools.ietf.org/html/rfc7231#section-4) must be specified - * with ``:method`` key in |nva| (e.g. ``POST``). This function does - * not take ownership of the |data_prd|. The function copies the - * members of the |data_prd|. If |data_prd| is ``NULL``, HEADERS have - * END_STREAM set. The |stream_user_data| is data associated to the - * stream opened by this request and can be an arbitrary pointer, - * which can be retrieved later by - * `nghttp2_session_get_stream_user_data()`. - * - * This function returns assigned stream ID if it succeeds, or one of - * the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` - * No stream ID is available because maximum stream ID was - * reached. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * The |session| is server session. - * - * .. warning:: - * - * This function returns assigned stream ID if it succeeds. But - * that stream is not created yet. The application must not submit - * frame to that stream ID before - * :type:`nghttp2_before_frame_send_callback` is called for this - * frame. This means `nghttp2_session_get_stream_user_data()` does - * not work before the callback. But - * `nghttp2_session_set_stream_user_data()` handles this situation - * specially, and it can set data to a stream during this period. - * - */ -NGHTTP2_EXTERN int32_t nghttp2_submit_request( - nghttp2_session *session, const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd, - void *stream_user_data); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Submits HEADERS frame and optionally one or more DATA frames. - * - * The |pri_spec| is ignored. - * - * The |nva| is an array of name/value pair :type:`nghttp2_nv` with - * |nvlen| elements. The application is responsible to include - * required pseudo-header fields (header field whose name starts with - * ":") in |nva| and must place pseudo-headers before regular header - * fields. - * - * This function creates copies of all name/value pairs in |nva|. It - * also lower-cases all names in |nva|. The order of elements in - * |nva| is preserved. For header fields with - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, - * header field name and value are not copied respectively. With - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application - * is responsible to pass header field name in lowercase. The - * application should maintain the references to them until - * :type:`nghttp2_on_frame_send_callback` or - * :type:`nghttp2_on_frame_not_send_callback` is called. - * - * HTTP/2 specification has requirement about header fields in the - * request HEADERS. See the specification for more details. - * - * If |data_prd| is not ``NULL``, it provides data which will be sent - * in subsequent DATA frames. In this case, a method that allows - * request message bodies - * (https://tools.ietf.org/html/rfc7231#section-4) must be specified - * with ``:method`` key in |nva| (e.g. ``POST``). This function does - * not take ownership of the |data_prd|. The function copies the - * members of the |data_prd|. If |data_prd| is ``NULL``, HEADERS have - * END_STREAM set. The |stream_user_data| is data associated to the - * stream opened by this request and can be an arbitrary pointer, - * which can be retrieved later by - * `nghttp2_session_get_stream_user_data()`. - * - * This function returns assigned stream ID if it succeeds, or one of - * the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` - * No stream ID is available because maximum stream ID was - * reached. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * The |session| is server session. - * - * .. warning:: - * - * This function returns assigned stream ID if it succeeds. But - * that stream is not created yet. The application must not submit - * frame to that stream ID before - * :type:`nghttp2_before_frame_send_callback` is called for this - * frame. This means `nghttp2_session_get_stream_user_data()` does - * not work before the callback. But - * `nghttp2_session_set_stream_user_data()` handles this situation - * specially, and it can set data to a stream during this period. - * - */ -NGHTTP2_EXTERN int32_t nghttp2_submit_request2( - nghttp2_session *session, const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider2 *data_prd, - void *stream_user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_submit_response2()` instead. - * - * Submits response HEADERS frame and optionally one or more DATA - * frames against the stream |stream_id|. - * - * The |nva| is an array of name/value pair :type:`nghttp2_nv` with - * |nvlen| elements. The application is responsible to include - * required pseudo-header fields (header field whose name starts with - * ":") in |nva| and must place pseudo-headers before regular header - * fields. - * - * This function creates copies of all name/value pairs in |nva|. It - * also lower-cases all names in |nva|. The order of elements in - * |nva| is preserved. For header fields with - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, - * header field name and value are not copied respectively. With - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application - * is responsible to pass header field name in lowercase. The - * application should maintain the references to them until - * :type:`nghttp2_on_frame_send_callback` or - * :type:`nghttp2_on_frame_not_send_callback` is called. - * - * HTTP/2 specification has requirement about header fields in the - * response HEADERS. See the specification for more details. - * - * If |data_prd| is not ``NULL``, it provides data which will be sent - * in subsequent DATA frames. This function does not take ownership - * of the |data_prd|. The function copies the members of the - * |data_prd|. If |data_prd| is ``NULL``, HEADERS will have - * END_STREAM flag set. - * - * This method can be used as normal HTTP response and push response. - * When pushing a resource using this function, the |session| must be - * configured using `nghttp2_session_server_new()` or its variants and - * the target stream denoted by the |stream_id| must be reserved using - * `nghttp2_submit_push_promise()`. - * - * To send non-final response headers (e.g., HTTP status 101), don't - * use this function because this function half-closes the outbound - * stream. Instead, use `nghttp2_submit_headers()` for this purpose. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` - * DATA or HEADERS has been already submitted and not fully - * processed yet. Normally, this does not happen, but when - * application wrongly calls `nghttp2_submit_response()` twice, - * this may happen. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * The |session| is client session. - * - * .. warning:: - * - * Calling this function twice for the same stream ID may lead to - * program crash. It is generally considered to a programming error - * to commit response twice. - */ -NGHTTP2_EXTERN int -nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider *data_prd); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Submits response HEADERS frame and optionally one or more DATA - * frames against the stream |stream_id|. - * - * The |nva| is an array of name/value pair :type:`nghttp2_nv` with - * |nvlen| elements. The application is responsible to include - * required pseudo-header fields (header field whose name starts with - * ":") in |nva| and must place pseudo-headers before regular header - * fields. - * - * This function creates copies of all name/value pairs in |nva|. It - * also lower-cases all names in |nva|. The order of elements in - * |nva| is preserved. For header fields with - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, - * header field name and value are not copied respectively. With - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application - * is responsible to pass header field name in lowercase. The - * application should maintain the references to them until - * :type:`nghttp2_on_frame_send_callback` or - * :type:`nghttp2_on_frame_not_send_callback` is called. - * - * HTTP/2 specification has requirement about header fields in the - * response HEADERS. See the specification for more details. - * - * If |data_prd| is not ``NULL``, it provides data which will be sent - * in subsequent DATA frames. This function does not take ownership - * of the |data_prd|. The function copies the members of the - * |data_prd|. If |data_prd| is ``NULL``, HEADERS will have - * END_STREAM flag set. - * - * This method can be used as normal HTTP response and push response. - * When pushing a resource using this function, the |session| must be - * configured using `nghttp2_session_server_new()` or its variants and - * the target stream denoted by the |stream_id| must be reserved using - * `nghttp2_submit_push_promise()`. - * - * To send non-final response headers (e.g., HTTP status 101), don't - * use this function because this function half-closes the outbound - * stream. Instead, use `nghttp2_submit_headers()` for this purpose. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` - * DATA or HEADERS has been already submitted and not fully - * processed yet. Normally, this does not happen, but when - * application wrongly calls `nghttp2_submit_response2()` twice, - * this may happen. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * The |session| is client session. - * - * .. warning:: - * - * Calling this function twice for the same stream ID may lead to - * program crash. It is generally considered to a programming error - * to commit response twice. - */ -NGHTTP2_EXTERN int -nghttp2_submit_response2(nghttp2_session *session, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider2 *data_prd); - -/** - * @function - * - * Submits trailer fields HEADERS against the stream |stream_id|. - * - * The |nva| is an array of name/value pair :type:`nghttp2_nv` with - * |nvlen| elements. The application must not include pseudo-header - * fields (headers whose names starts with ":") in |nva|. - * - * This function creates copies of all name/value pairs in |nva|. It - * also lower-cases all names in |nva|. The order of elements in - * |nva| is preserved. For header fields with - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, - * header field name and value are not copied respectively. With - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application - * is responsible to pass header field name in lowercase. The - * application should maintain the references to them until - * :type:`nghttp2_on_frame_send_callback` or - * :type:`nghttp2_on_frame_not_send_callback` is called. - * - * For server, trailer fields must follow response HEADERS or response - * DATA without END_STREAM flat set. The library does not enforce - * this requirement, and applications should do this for themselves. - * If `nghttp2_submit_trailer()` is called before any response HEADERS - * submission (usually by `nghttp2_submit_response2()`), the content - * of |nva| will be sent as response headers, which will result in - * error. - * - * This function has the same effect with `nghttp2_submit_headers()`, - * with flags = :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` and both - * pri_spec and stream_user_data to NULL. - * - * To submit trailer fields after `nghttp2_submit_response2()` is - * called, the application has to specify - * :type:`nghttp2_data_provider2` to `nghttp2_submit_response2()`. - * Inside of :type:`nghttp2_data_source_read_callback2`, when setting - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set - * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM`. After - * that, the application can send trailer fields using - * `nghttp2_submit_trailer()`. `nghttp2_submit_trailer()` can be used - * inside :type:`nghttp2_data_source_read_callback2`. - * - * This function returns 0 if it succeeds and |stream_id| is -1. - * Otherwise, this function returns 0 if it succeeds, or one of the - * following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - */ -NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, - int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen); - -/** - * @function - * - * Submits HEADERS frame. The |flags| is bitwise OR of the - * following values: - * - * * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` - * - * If |flags| includes :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, - * this frame has END_STREAM flag set. - * - * The library handles the CONTINUATION frame internally and it - * correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE - * or CONTINUATION frame. - * - * If the |stream_id| is -1, this frame is assumed as request (i.e., - * request HEADERS frame which opens new stream). In this case, the - * assigned stream ID will be returned. Otherwise, specify stream ID - * in |stream_id|. - * - * The |pri_spec| is ignored. - * - * The |nva| is an array of name/value pair :type:`nghttp2_nv` with - * |nvlen| elements. The application is responsible to include - * required pseudo-header fields (header field whose name starts with - * ":") in |nva| and must place pseudo-headers before regular header - * fields. - * - * This function creates copies of all name/value pairs in |nva|. It - * also lower-cases all names in |nva|. The order of elements in - * |nva| is preserved. For header fields with - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, - * header field name and value are not copied respectively. With - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application - * is responsible to pass header field name in lowercase. The - * application should maintain the references to them until - * :type:`nghttp2_on_frame_send_callback` or - * :type:`nghttp2_on_frame_not_send_callback` is called. - * - * The |stream_user_data| is a pointer to an arbitrary data which is - * associated to the stream this frame will open. Therefore it is - * only used if this frame opens streams, in other words, it changes - * stream state from idle or reserved to open. - * - * This function is low-level in a sense that the application code can - * specify flags directly. For usual HTTP request, - * `nghttp2_submit_request2()` is useful. Likewise, for HTTP - * response, prefer `nghttp2_submit_response2()`. - * - * This function returns newly assigned stream ID if it succeeds and - * |stream_id| is -1. Otherwise, this function returns 0 if it - * succeeds, or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` - * No stream ID is available because maximum stream ID was - * reached. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` - * DATA or HEADERS has been already submitted and not fully - * processed yet. This happens if stream denoted by |stream_id| - * is in reserved state. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * The |stream_id| is -1, and |session| is server session. - * - * .. warning:: - * - * This function returns assigned stream ID if it succeeds and - * |stream_id| is -1. But that stream is not opened yet. The - * application must not submit frame to that stream ID before - * :type:`nghttp2_before_frame_send_callback` is called for this - * frame. - * - */ -NGHTTP2_EXTERN int32_t nghttp2_submit_headers( - nghttp2_session *session, uint8_t flags, int32_t stream_id, - const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen, - void *stream_user_data); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_submit_data2()` instead. - * - * Submits one or more DATA frames to the stream |stream_id|. The - * data to be sent are provided by |data_prd|. If |flags| contains - * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame - * has END_STREAM flag set. - * - * This function does not take ownership of the |data_prd|. The - * function copies the members of the |data_prd|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` - * DATA or HEADERS has been already submitted and not fully - * processed yet. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED` - * The stream was already closed; or the |stream_id| is invalid. - * - * .. note:: - * - * Currently, only one DATA or HEADERS is allowed for a stream at a - * time. Submitting these frames more than once before first DATA - * or HEADERS is finished results in - * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code. The - * earliest callback which tells that previous frame is done is - * :type:`nghttp2_on_frame_send_callback`. In side that callback, - * new data can be submitted using `nghttp2_submit_data()`. Of - * course, all data except for last one must not have - * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|. - * This sounds a bit complicated, and we recommend to use - * `nghttp2_submit_request()` and `nghttp2_submit_response()` to - * avoid this cascading issue. The experience shows that for HTTP - * use, these two functions are enough to implement both client and - * server. - */ -NGHTTP2_EXTERN int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider *data_prd); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Submits one or more DATA frames to the stream |stream_id|. The - * data to be sent are provided by |data_prd|. If |flags| contains - * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame - * has END_STREAM flag set. - * - * This function does not take ownership of the |data_prd|. The - * function copies the members of the |data_prd|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` - * DATA or HEADERS has been already submitted and not fully - * processed yet. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED` - * The stream was already closed; or the |stream_id| is invalid. - * - * .. note:: - * - * Currently, only one DATA or HEADERS is allowed for a stream at a - * time. Submitting these frames more than once before first DATA - * or HEADERS is finished results in - * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code. The - * earliest callback which tells that previous frame is done is - * :type:`nghttp2_on_frame_send_callback`. In side that callback, - * new data can be submitted using `nghttp2_submit_data2()`. Of - * course, all data except for last one must not have - * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|. - * This sounds a bit complicated, and we recommend to use - * `nghttp2_submit_request2()` and `nghttp2_submit_response2()` to - * avoid this cascading issue. The experience shows that for HTTP - * use, these two functions are enough to implement both client and - * server. - */ -NGHTTP2_EXTERN int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider2 *data_prd); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function is noop. It always returns 0. - */ -NGHTTP2_EXTERN int -nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_priority_spec *pri_spec); - -/** - * @macro - * - * :macro:`NGHTTP2_EXTPRI_DEFAULT_URGENCY` is the default urgency - * level for :rfc:`9218` extensible priorities. - */ -#define NGHTTP2_EXTPRI_DEFAULT_URGENCY 3 - -/** - * @macro - * - * :macro:`NGHTTP2_EXTPRI_URGENCY_HIGH` is the highest urgency level - * for :rfc:`9218` extensible priorities. - */ -#define NGHTTP2_EXTPRI_URGENCY_HIGH 0 - -/** - * @macro - * - * :macro:`NGHTTP2_EXTPRI_URGENCY_LOW` is the lowest urgency level for - * :rfc:`9218` extensible priorities. - */ -#define NGHTTP2_EXTPRI_URGENCY_LOW 7 - -/** - * @macro - * - * :macro:`NGHTTP2_EXTPRI_URGENCY_LEVELS` is the number of urgency - * levels for :rfc:`9218` extensible priorities. - */ -#define NGHTTP2_EXTPRI_URGENCY_LEVELS (NGHTTP2_EXTPRI_URGENCY_LOW + 1) - -/** - * @struct - * - * :type:`nghttp2_extpri` is :rfc:`9218` extensible priorities - * specification for a stream. - */ -typedef struct nghttp2_extpri { - /** - * :member:`urgency` is the urgency of a stream, it must be in - * [:macro:`NGHTTP2_EXTPRI_URGENCY_HIGH`, - * :macro:`NGHTTP2_EXTPRI_URGENCY_LOW`], inclusive, and 0 is the - * highest urgency. - */ - uint32_t urgency; - /** - * :member:`inc` indicates that a content can be processed - * incrementally or not. If inc is 0, it cannot be processed - * incrementally. If inc is 1, it can be processed incrementally. - * Other value is not permitted. - */ - int inc; -} nghttp2_extpri; - -/** - * @function - * - * Submits RST_STREAM frame to cancel/reject the stream |stream_id| - * with the error code |error_code|. - * - * The pre-defined error code is one of :enum:`nghttp2_error_code`. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0. - */ -NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session, - uint8_t flags, int32_t stream_id, - uint32_t error_code); - -/** - * @function - * - * Stores local settings and submits SETTINGS frame. The |iv| is the - * pointer to the array of :type:`nghttp2_settings_entry`. The |niv| - * indicates the number of :type:`nghttp2_settings_entry`. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * This function does not take ownership of the |iv|. This function - * copies all the elements in the |iv|. - * - * While updating individual stream's local window size, if the window - * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE, - * RST_STREAM is issued against such a stream. - * - * SETTINGS with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` is - * automatically submitted by the library and application could not - * send it at its will. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |iv| contains invalid value (e.g., initial window size - * strictly greater than (1 << 31) - 1. - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session, - uint8_t flags, - const nghttp2_settings_entry *iv, - size_t niv); - -/** - * @function - * - * Submits PUSH_PROMISE frame. - * - * The |flags| is currently ignored. The library handles the - * CONTINUATION frame internally and it correctly sets END_HEADERS to - * the last sequence of the PUSH_PROMISE or CONTINUATION frame. - * - * The |stream_id| must be client initiated stream ID. - * - * The |nva| is an array of name/value pair :type:`nghttp2_nv` with - * |nvlen| elements. The application is responsible to include - * required pseudo-header fields (header field whose name starts with - * ":") in |nva| and must place pseudo-headers before regular header - * fields. - * - * This function creates copies of all name/value pairs in |nva|. It - * also lower-cases all names in |nva|. The order of elements in - * |nva| is preserved. For header fields with - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, - * header field name and value are not copied respectively. With - * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application - * is responsible to pass header field name in lowercase. The - * application should maintain the references to them until - * :type:`nghttp2_on_frame_send_callback` or - * :type:`nghttp2_on_frame_not_send_callback` is called. - * - * The |promised_stream_user_data| is a pointer to an arbitrary data - * which is associated to the promised stream this frame will open and - * make it in reserved state. It is available using - * `nghttp2_session_get_stream_user_data()`. The application can - * access it in :type:`nghttp2_before_frame_send_callback` and - * :type:`nghttp2_on_frame_send_callback` of this frame. - * - * The client side is not allowed to use this function. - * - * To submit response headers and data, use - * `nghttp2_submit_response2()`. - * - * This function returns assigned promised stream ID if it succeeds, - * or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` - * This function was invoked when |session| is initialized as - * client. - * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` - * No stream ID is available because maximum stream ID was - * reached. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0; The |stream_id| does not designate stream - * that peer initiated. - * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED` - * The stream was already closed; or the |stream_id| is invalid. - * - * .. warning:: - * - * This function returns assigned promised stream ID if it succeeds. - * As of 1.16.0, stream object for pushed resource is created when - * this function succeeds. In that case, the application can submit - * push response for the promised frame. - * - * In 1.15.0 or prior versions, pushed stream is not opened yet when - * this function succeeds. The application must not submit frame to - * that stream ID before :type:`nghttp2_before_frame_send_callback` - * is called for this frame. - * - */ -NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise( - nghttp2_session *session, uint8_t flags, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data); - -/** - * @function - * - * Submits PING frame. You don't have to send PING back when you - * received PING frame. The library automatically submits PING frame - * in this case. - * - * The |flags| is bitwise OR of 0 or more of the following value. - * - * * :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` - * - * Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the |flags| - * should be :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * If the |opaque_data| is non ``NULL``, then it should point to the 8 - * bytes array of memory to specify opaque data to send with PING - * frame. If the |opaque_data| is ``NULL``, zero-cleared 8 bytes will - * be sent as opaque data. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, - const uint8_t *opaque_data); - -/** - * @function - * - * Submits GOAWAY frame with the last stream ID |last_stream_id| and - * the error code |error_code|. - * - * The pre-defined error code is one of :enum:`nghttp2_error_code`. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * The |last_stream_id| is peer's stream ID or 0. So if |session| is - * initialized as client, |last_stream_id| must be even or 0. If - * |session| is initialized as server, |last_stream_id| must be odd or - * 0. - * - * The HTTP/2 specification says last_stream_id must not be increased - * from the value previously sent. So the actual value sent as - * last_stream_id is the minimum value between the given - * |last_stream_id| and the last_stream_id previously sent to the - * peer. - * - * If the |opaque_data| is not ``NULL`` and |opaque_data_len| is not - * zero, those data will be sent as additional debug data. The - * library makes a copy of the memory region pointed by |opaque_data| - * with the length |opaque_data_len|, so the caller does not need to - * keep this memory after the return of this function. If the - * |opaque_data_len| is 0, the |opaque_data| could be ``NULL``. - * - * After successful transmission of GOAWAY, following things happen. - * All incoming streams having strictly more than |last_stream_id| are - * closed. All incoming HEADERS which starts new stream are simply - * ignored. After all active streams are handled, both - * `nghttp2_session_want_read()` and `nghttp2_session_want_write()` - * return 0 and the application can close session. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |opaque_data_len| is too large; the |last_stream_id| is - * invalid. - */ -NGHTTP2_EXTERN int nghttp2_submit_goaway(nghttp2_session *session, - uint8_t flags, int32_t last_stream_id, - uint32_t error_code, - const uint8_t *opaque_data, - size_t opaque_data_len); - -/** - * @function - * - * Returns the last stream ID of a stream for which - * :type:`nghttp2_on_frame_recv_callback` was invoked most recently. - * The returned value can be used as last_stream_id parameter for - * `nghttp2_submit_goaway()` and - * `nghttp2_session_terminate_session2()`. - * - * This function always succeeds. - */ -NGHTTP2_EXTERN int32_t -nghttp2_session_get_last_proc_stream_id(nghttp2_session *session); - -/** - * @function - * - * Returns nonzero if new request can be sent from local endpoint. - * - * This function return 0 if request is not allowed for this session. - * There are several reasons why request is not allowed. Some of the - * reasons are: session is server; stream ID has been spent; GOAWAY - * has been sent or received. - * - * The application can call `nghttp2_submit_request2()` without - * consulting this function. In that case, - * `nghttp2_submit_request2()` may return error. Or, request is - * failed to sent, and :type:`nghttp2_on_stream_close_callback` is - * called. - */ -NGHTTP2_EXTERN int -nghttp2_session_check_request_allowed(nghttp2_session *session); - -/** - * @function - * - * Returns nonzero if |session| is initialized as server side session. - */ -NGHTTP2_EXTERN int -nghttp2_session_check_server_session(nghttp2_session *session); - -/** - * @function - * - * Submits WINDOW_UPDATE frame. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * The |stream_id| is the stream ID to send this WINDOW_UPDATE. To - * send connection level WINDOW_UPDATE, specify 0 to |stream_id|. - * - * If the |window_size_increment| is positive, the WINDOW_UPDATE with - * that value as window_size_increment is queued. If the - * |window_size_increment| is larger than the received bytes from the - * remote endpoint, the local window size is increased by that - * difference. If the sole purpose is to increase the local window - * size, consider to use `nghttp2_session_set_local_window_size()`. - * - * If the |window_size_increment| is negative, the local window size - * is decreased by -|window_size_increment|. If automatic - * WINDOW_UPDATE is enabled - * (`nghttp2_option_set_no_auto_window_update()`), and the library - * decided that the WINDOW_UPDATE should be submitted, then - * WINDOW_UPDATE is queued with the current received bytes count. If - * the sole purpose is to decrease the local window size, consider to - * use `nghttp2_session_set_local_window_size()`. - * - * If the |window_size_increment| is 0, the function does nothing and - * returns 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_FLOW_CONTROL` - * The local window size overflow or gets negative. - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session, - uint8_t flags, - int32_t stream_id, - int32_t window_size_increment); - -/** - * @function - * - * Set local window size (local endpoints's window size) to the given - * |window_size| for the given stream denoted by |stream_id|. To - * change connection level window size, specify 0 to |stream_id|. To - * increase window size, this function may submit WINDOW_UPDATE frame - * to transmission queue. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * This sounds similar to `nghttp2_submit_window_update()`, but there - * are 2 differences. The first difference is that this function - * takes the absolute value of window size to set, rather than the - * delta. To change the window size, this may be easier to use since - * the application just declares the intended window size, rather than - * calculating delta. The second difference is that - * `nghttp2_submit_window_update()` affects the received bytes count - * which has not acked yet. By the specification of - * `nghttp2_submit_window_update()`, to strictly increase the local - * window size, we have to submit delta including all received bytes - * count, which might not be desirable in some cases. On the other - * hand, this function does not affect the received bytes count. It - * just sets the local window size to the given value. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is negative. - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags, - int32_t stream_id, int32_t window_size); - -/** - * @function - * - * Submits extension frame. - * - * Application can pass arbitrary frame flags and stream ID in |flags| - * and |stream_id| respectively. The |payload| is opaque pointer, and - * it can be accessible though ``frame->ext.payload`` in - * :type:`nghttp2_pack_extension_callback2`. The library will not own - * passed |payload| pointer. - * - * The application must set :type:`nghttp2_pack_extension_callback2` - * using `nghttp2_session_callbacks_set_pack_extension_callback2()`. - * - * The application should retain the memory pointed by |payload| until - * the transmission of extension frame is done (which is indicated by - * :type:`nghttp2_on_frame_send_callback`), or transmission fails - * (which is indicated by :type:`nghttp2_on_frame_not_send_callback`). - * If application does not touch this memory region after packing it - * into a wire format, application can free it inside - * :type:`nghttp2_pack_extension_callback2`. - * - * The standard HTTP/2 frame cannot be sent with this function, so - * |type| must be strictly grater than 0x9. Otherwise, this function - * will fail with error code - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * If :type:`nghttp2_pack_extension_callback2` is not set. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * If |type| specifies standard HTTP/2 frame type. The frame - * types in the rage [0x0, 0x9], both inclusive, are standard - * HTTP/2 frame type, and cannot be sent using this function. - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory - */ -NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session, - uint8_t type, uint8_t flags, - int32_t stream_id, void *payload); - -/** - * @struct - * - * The payload of ALTSVC frame. ALTSVC frame is a non-critical - * extension to HTTP/2. If this frame is received, and - * `nghttp2_option_set_user_recv_extension_type()` is not set, and - * `nghttp2_option_set_builtin_recv_extension_type()` is set for - * :enum:`nghttp2_frame_type.NGHTTP2_ALTSVC`, - * ``nghttp2_extension.payload`` will point to this struct. - * - * It has the following members: - */ -typedef struct { - /** - * The pointer to origin which this alternative service is - * associated with. This is not necessarily NULL-terminated. - */ - uint8_t *origin; - /** - * The length of the |origin|. - */ - size_t origin_len; - /** - * The pointer to Alt-Svc field value contained in ALTSVC frame. - * This is not necessarily NULL-terminated. - */ - uint8_t *field_value; - /** - * The length of the |field_value|. - */ - size_t field_value_len; -} nghttp2_ext_altsvc; - -/** - * @function - * - * Submits ALTSVC frame. - * - * ALTSVC frame is a non-critical extension to HTTP/2, and defined in - * `RFC 7383 `_. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * The |origin| points to the origin this alternative service is - * associated with. The |origin_len| is the length of the origin. If - * |stream_id| is 0, the origin must be specified. If |stream_id| is - * not zero, the origin must be empty (in other words, |origin_len| - * must be 0). - * - * The ALTSVC frame is only usable from server side. If this function - * is invoked with client side session, this function returns - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * The function is called from client side session - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The sum of |origin_len| and |field_value_len| is larger than - * 16382; or |origin_len| is 0 while |stream_id| is 0; or - * |origin_len| is not 0 while |stream_id| is not 0. - */ -NGHTTP2_EXTERN int nghttp2_submit_altsvc(nghttp2_session *session, - uint8_t flags, int32_t stream_id, - const uint8_t *origin, - size_t origin_len, - const uint8_t *field_value, - size_t field_value_len); - -/** - * @struct - * - * The single entry of an origin. - */ -typedef struct { - /** - * The pointer to origin. No validation is made against this field - * by the library. This is not necessarily NULL-terminated. - */ - uint8_t *origin; - /** - * The length of the |origin|. - */ - size_t origin_len; -} nghttp2_origin_entry; - -/** - * @struct - * - * The payload of ORIGIN frame. ORIGIN frame is a non-critical - * extension to HTTP/2 and defined by `RFC 8336 - * `_. - * - * If this frame is received, and - * `nghttp2_option_set_user_recv_extension_type()` is not set, and - * `nghttp2_option_set_builtin_recv_extension_type()` is set for - * :enum:`nghttp2_frame_type.NGHTTP2_ORIGIN`, - * ``nghttp2_extension.payload`` will point to this struct. - * - * It has the following members: - */ -typedef struct { - /** - * The number of origins contained in |ov|. - */ - size_t nov; - /** - * The pointer to the array of origins contained in ORIGIN frame. - */ - nghttp2_origin_entry *ov; -} nghttp2_ext_origin; - -/** - * @function - * - * Submits ORIGIN frame. - * - * ORIGIN frame is a non-critical extension to HTTP/2 and defined by - * `RFC 8336 `_. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * The |ov| points to the array of origins. The |nov| specifies the - * number of origins included in |ov|. This function creates copies - * of all elements in |ov|. - * - * The ORIGIN frame is only usable by a server. If this function is - * invoked with client side session, this function returns - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * The function is called from client side session. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * There are too many origins, or an origin is too large to fit - * into a default frame payload. - */ -NGHTTP2_EXTERN int nghttp2_submit_origin(nghttp2_session *session, - uint8_t flags, - const nghttp2_origin_entry *ov, - size_t nov); - -/** - * @struct - * - * The payload of PRIORITY_UPDATE frame. PRIORITY_UPDATE frame is a - * non-critical extension to HTTP/2. If this frame is received, and - * `nghttp2_option_set_user_recv_extension_type()` is not set, and - * `nghttp2_option_set_builtin_recv_extension_type()` is set for - * :enum:`nghttp2_frame_type.NGHTTP2_PRIORITY_UPDATE`, - * ``nghttp2_extension.payload`` will point to this struct. - * - * It has the following members: - */ -typedef struct { - /** - * The stream ID of the stream whose priority is updated. - */ - int32_t stream_id; - /** - * The pointer to Priority field value. It is not necessarily - * NULL-terminated. - */ - uint8_t *field_value; - /** - * The length of the :member:`field_value`. - */ - size_t field_value_len; -} nghttp2_ext_priority_update; - -/** - * @function - * - * Submits PRIORITY_UPDATE frame. - * - * PRIORITY_UPDATE frame is a non-critical extension to HTTP/2, and - * defined in :rfc:`9218#section-7.1`. - * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * The |stream_id| is the ID of stream which is prioritized. The - * |field_value| points to the Priority field value. The - * |field_value_len| is the length of the Priority field value. - * - * If this function is called by server, - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` is returned. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 0 is received by a remote endpoint (or it is omitted), - * this function does nothing and returns 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * The function is called from server side session - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |field_value_len| is larger than 16380; or |stream_id| is - * 0. - */ -NGHTTP2_EXTERN int nghttp2_submit_priority_update(nghttp2_session *session, - uint8_t flags, - int32_t stream_id, - const uint8_t *field_value, - size_t field_value_len); - -/** - * @function - * - * Changes the priority of the existing stream denoted by |stream_id|. - * The new priority is |extpri|. This function is meant to be used by - * server for :rfc:`9218` extensible prioritization scheme. - * - * If |session| is initialized as client, this function returns - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. For client, use - * `nghttp2_submit_priority_update()` instead. - * - * If :member:`extpri->urgency ` is out of - * bound, it is set to :macro:`NGHTTP2_EXTPRI_URGENCY_LOW`. - * - * If |ignore_client_signal| is nonzero, server starts to ignore - * client priority signals for this stream. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is not submitted via `nghttp2_submit_settings()`, - * this function does nothing and returns 0. - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * The |session| is initialized as client. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * |stream_id| is zero; or a stream denoted by |stream_id| is not - * found. - */ -NGHTTP2_EXTERN int nghttp2_session_change_extpri_stream_priority( - nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri, - int ignore_client_signal); - -/** - * @function - * - * Stores the stream priority of the existing stream denoted by - * |stream_id| in the object pointed by |extpri|. This function is - * meant to be used by server for :rfc:`9218` extensible - * prioritization scheme. - * - * If |session| is initialized as client, this function returns - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is not submitted via `nghttp2_submit_settings()`, - * this function does nothing and returns 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * The |session| is initialized as client. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * |stream_id| is zero; or a stream denoted by |stream_id| is not - * found. - */ -NGHTTP2_EXTERN int nghttp2_session_get_extpri_stream_priority( - nghttp2_session *session, nghttp2_extpri *extpri, int32_t stream_id); - -/** - * @function - * - * Parses Priority header field value pointed by |value| of length - * |len|, and stores the result in the object pointed by |extpri|. - * Priority header field is defined in :rfc:`9218`. - * - * This function does not initialize the object pointed by |extpri| - * before storing the result. It only assigns the values that the - * parser correctly extracted to fields. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * Failed to parse the header field value. - */ -NGHTTP2_EXTERN int nghttp2_extpri_parse_priority(nghttp2_extpri *extpri, - const uint8_t *value, - size_t len); - -/** - * @function - * - * Compares ``lhs->name`` of length ``lhs->namelen`` bytes and - * ``rhs->name`` of length ``rhs->namelen`` bytes. Returns negative - * integer if ``lhs->name`` is found to be less than ``rhs->name``; or - * returns positive integer if ``lhs->name`` is found to be greater - * than ``rhs->name``; or returns 0 otherwise. - */ -NGHTTP2_EXTERN int nghttp2_nv_compare_name(const nghttp2_nv *lhs, - const nghttp2_nv *rhs); - -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_select_alpn` instead. - * - * A helper function for dealing with ALPN in server side. The |in| - * contains peer's protocol list in preferable order. The format of - * |in| is length-prefixed and not null-terminated. For example, - * ``h2`` and ``http/1.1`` stored in |in| like this:: - * - * in[0] = 2 - * in[1..2] = "h2" - * in[3] = 8 - * in[4..11] = "http/1.1" - * inlen = 12 - * - * The selection algorithm is as follows: - * - * 1. If peer's list contains HTTP/2 protocol the library supports, - * it is selected and returns 1. The following step is not taken. - * - * 2. If peer's list contains ``http/1.1``, this function selects - * ``http/1.1`` and returns 0. The following step is not taken. - * - * 3. This function selects nothing and returns -1 (So called - * non-overlap case). In this case, |out| and |outlen| are left - * untouched. - * - * Selecting ``h2`` means that ``h2`` is written into |*out| and its - * length (which is 2) is assigned to |*outlen|. - * - * For ALPN, refer to https://tools.ietf.org/html/rfc7301 - * - * To use this method you should do something like:: - * - * static int alpn_select_proto_cb(SSL* ssl, - * const unsigned char **out, - * unsigned char *outlen, - * const unsigned char *in, - * unsigned int inlen, - * void *arg) - * { - * int rv; - * rv = nghttp2_select_next_protocol((unsigned char**)out, outlen, - * in, inlen); - * if (rv == -1) { - * return SSL_TLSEXT_ERR_NOACK; - * } - * if (rv == 1) { - * ((MyType*)arg)->http2_selected = 1; - * } - * return SSL_TLSEXT_ERR_OK; - * } - * ... - * SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, my_obj); - * - */ -NGHTTP2_EXTERN int nghttp2_select_next_protocol(unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen); - -/** - * @function - * - * A helper function for dealing with ALPN in server side. The |in| - * contains peer's protocol list in preferable order. The format of - * |in| is length-prefixed and not null-terminated. For example, - * ``h2`` and ``http/1.1`` stored in |in| like this:: - * - * in[0] = 2 - * in[1..2] = "h2" - * in[3] = 8 - * in[4..11] = "http/1.1" - * inlen = 12 - * - * The selection algorithm is as follows: - * - * 1. If peer's list contains HTTP/2 protocol the library supports, - * it is selected and returns 1. The following step is not taken. - * - * 2. If peer's list contains ``http/1.1``, this function selects - * ``http/1.1`` and returns 0. The following step is not taken. - * - * 3. This function selects nothing and returns -1 (So called - * non-overlap case). In this case, |out| and |outlen| are left - * untouched. - * - * Selecting ``h2`` means that ``h2`` is written into |*out| and its - * length (which is 2) is assigned to |*outlen|. - * - * For ALPN, refer to https://tools.ietf.org/html/rfc7301 - * - * To use this method you should do something like:: - * - * static int alpn_select_proto_cb(SSL* ssl, - * const unsigned char **out, - * unsigned char *outlen, - * const unsigned char *in, - * unsigned int inlen, - * void *arg) - * { - * int rv; - * rv = nghttp2_select_alpn(out, outlen, in, inlen); - * if (rv == -1) { - * return SSL_TLSEXT_ERR_NOACK; - * } - * if (rv == 1) { - * ((MyType*)arg)->http2_selected = 1; - * } - * return SSL_TLSEXT_ERR_OK; - * } - * ... - * SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, my_obj); - * - */ -NGHTTP2_EXTERN int nghttp2_select_alpn(const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen); - -/** - * @function - * - * Returns a pointer to a nghttp2_info struct with version information - * about the run-time library in use. The |least_version| argument - * can be set to a 24 bit numerical value for the least accepted - * version number and if the condition is not met, this function will - * return a ``NULL``. Pass in 0 to skip the version checking. - */ -NGHTTP2_EXTERN nghttp2_info *nghttp2_version(int least_version); - -/** - * @function - * - * Returns nonzero if the :type:`nghttp2_error` library error code - * |lib_error| is fatal. - */ -NGHTTP2_EXTERN int nghttp2_is_fatal(int lib_error_code); - -/** - * @function - * - * Returns nonzero if HTTP header field name |name| of length |len| is - * valid according to http://tools.ietf.org/html/rfc7230#section-3.2 - * - * Because this is a header field name in HTTP2, the upper cased alphabet - * is treated as error. - */ -NGHTTP2_EXTERN int nghttp2_check_header_name(const uint8_t *name, size_t len); - -/** - * @function - * - * Returns nonzero if HTTP header field value |value| of length |len| - * is valid according to - * http://tools.ietf.org/html/rfc7230#section-3.2 - * - * This function is considered obsolete, and application should - * consider to use `nghttp2_check_header_value_rfc9113()` instead. - */ -NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len); - -/** - * @function - * - * Returns nonzero if HTTP header field value |value| of length |len| - * is valid according to - * http://tools.ietf.org/html/rfc7230#section-3.2, plus - * https://datatracker.ietf.org/doc/html/rfc9113#section-8.2.1 - */ -NGHTTP2_EXTERN int nghttp2_check_header_value_rfc9113(const uint8_t *value, - size_t len); - -/** - * @function - * - * Returns nonzero if the |value| which is supposed to be the value of - * the :method header field is valid according to - * https://datatracker.ietf.org/doc/html/rfc7231#section-4 and - * https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6 - */ -NGHTTP2_EXTERN int nghttp2_check_method(const uint8_t *value, size_t len); - -/** - * @function - * - * Returns nonzero if the |value| which is supposed to be the value of - * the :path header field is valid according to - * https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.3 - * - * |value| is valid if it merely consists of the allowed characters. - * In particular, it does not check whether |value| follows the syntax - * of path. The allowed characters are all characters valid by - * `nghttp2_check_header_value` minus SPC and HT. - */ -NGHTTP2_EXTERN int nghttp2_check_path(const uint8_t *value, size_t len); - -/** - * @function - * - * Returns nonzero if the |value| which is supposed to be the value of the - * :authority or host header field is valid according to - * https://tools.ietf.org/html/rfc3986#section-3.2 - * - * Note that :authority and host field values are not authority. They - * do not include userinfo in RFC 3986, see - * https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2, that - * is, it does not include '@'. This function treats '@' as a valid - * character. - * - * |value| is valid if it merely consists of the allowed characters. - * In particular, it does not check whether |value| follows the syntax - * of authority. - */ -NGHTTP2_EXTERN int nghttp2_check_authority(const uint8_t *value, size_t len); - -/* HPACK API */ - -struct nghttp2_hd_deflater; - -/** - * @struct - * - * HPACK deflater object. - */ -typedef struct nghttp2_hd_deflater nghttp2_hd_deflater; - -/** - * @function - * - * Initializes |*deflater_ptr| for deflating name/values pairs. - * - * The |max_deflate_dynamic_table_size| is the upper bound of header - * table size the deflater will use. - * - * If this function fails, |*deflater_ptr| is left untouched. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr, - size_t max_deflate_dynamic_table_size); - -/** - * @function - * - * Like `nghttp2_hd_deflate_new()`, but with additional custom memory - * allocator specified in the |mem|. - * - * The |mem| can be ``NULL`` and the call is equivalent to - * `nghttp2_hd_deflate_new()`. - * - * This function does not take ownership |mem|. The application is - * responsible for freeing |mem|. - * - * The library code does not refer to |mem| pointer after this - * function returns, so the application can safely free it. - */ -NGHTTP2_EXTERN int -nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr, - size_t max_deflate_dynamic_table_size, - nghttp2_mem *mem); - -/** - * @function - * - * Deallocates any resources allocated for |deflater|. - */ -NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater); - -/** - * @function - * - * Changes header table size of the |deflater| to - * |settings_max_dynamic_table_size| bytes. This may trigger eviction - * in the dynamic table. - * - * The |settings_max_dynamic_table_size| should be the value received - * in SETTINGS_HEADER_TABLE_SIZE. - * - * The deflater never uses more memory than - * ``max_deflate_dynamic_table_size`` bytes specified in - * `nghttp2_hd_deflate_new()`. Therefore, if - * |settings_max_dynamic_table_size| > - * ``max_deflate_dynamic_table_size``, resulting maximum table size - * becomes ``max_deflate_dynamic_table_size``. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int -nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater, - size_t settings_max_dynamic_table_size); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_hd_deflate_hd2()` instead. - * - * Deflates the |nva|, which has the |nvlen| name/value pairs, into - * the |buf| of length |buflen|. - * - * If |buf| is not large enough to store the deflated header block, - * this function fails with - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller - * should use `nghttp2_hd_deflate_bound()` to know the upper bound of - * buffer size required to deflate given header name/value pairs. - * - * Once this function fails, subsequent call of this function always - * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. - * - * After this function returns, it is safe to delete the |nva|. - * - * This function returns the number of bytes written to |buf| if it - * succeeds, or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` - * Deflation process has failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` - * The provided |buflen| size is too small to hold the output. - */ -NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, - uint8_t *buf, size_t buflen, - const nghttp2_nv *nva, - size_t nvlen); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Deflates the |nva|, which has the |nvlen| name/value pairs, into - * the |buf| of length |buflen|. - * - * If |buf| is not large enough to store the deflated header block, - * this function fails with - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller - * should use `nghttp2_hd_deflate_bound()` to know the upper bound of - * buffer size required to deflate given header name/value pairs. - * - * Once this function fails, subsequent call of this function always - * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. - * - * After this function returns, it is safe to delete the |nva|. - * - * This function returns the number of bytes written to |buf| if it - * succeeds, or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` - * Deflation process has failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` - * The provided |buflen| size is too small to hold the output. - */ -NGHTTP2_EXTERN nghttp2_ssize -nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater, uint8_t *buf, - size_t buflen, const nghttp2_nv *nva, size_t nvlen); - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_hd_deflate_hd_vec2()` instead. - * - * Deflates the |nva|, which has the |nvlen| name/value pairs, into - * the |veclen| size of buf vector |vec|. The each size of buffer - * must be set in len field of :type:`nghttp2_vec`. If and only if - * one chunk is filled up completely, next chunk will be used. If - * |vec| is not large enough to store the deflated header block, this - * function fails with - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller - * should use `nghttp2_hd_deflate_bound()` to know the upper bound of - * buffer size required to deflate given header name/value pairs. - * - * Once this function fails, subsequent call of this function always - * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. - * - * After this function returns, it is safe to delete the |nva|. - * - * This function returns the number of bytes written to |vec| if it - * succeeds, or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` - * Deflation process has failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` - * The provided |buflen| size is too small to hold the output. - */ -NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, - const nghttp2_vec *vec, - size_t veclen, - const nghttp2_nv *nva, - size_t nvlen); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Deflates the |nva|, which has the |nvlen| name/value pairs, into - * the |veclen| size of buf vector |vec|. The each size of buffer - * must be set in len field of :type:`nghttp2_vec`. If and only if - * one chunk is filled up completely, next chunk will be used. If - * |vec| is not large enough to store the deflated header block, this - * function fails with - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller - * should use `nghttp2_hd_deflate_bound()` to know the upper bound of - * buffer size required to deflate given header name/value pairs. - * - * Once this function fails, subsequent call of this function always - * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. - * - * After this function returns, it is safe to delete the |nva|. - * - * This function returns the number of bytes written to |vec| if it - * succeeds, or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` - * Deflation process has failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` - * The provided |buflen| size is too small to hold the output. - */ -NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_deflate_hd_vec2( - nghttp2_hd_deflater *deflater, const nghttp2_vec *vec, size_t veclen, - const nghttp2_nv *nva, size_t nvlen); - -/** - * @function - * - * Returns an upper bound on the compressed size after deflation of - * |nva| of length |nvlen|. - */ -NGHTTP2_EXTERN size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater, - const nghttp2_nv *nva, - size_t nvlen); - -/** - * @function - * - * Returns the number of entries that header table of |deflater| - * contains. This is the sum of the number of static table and - * dynamic table, so the return value is at least 61. - */ -NGHTTP2_EXTERN -size_t nghttp2_hd_deflate_get_num_table_entries(nghttp2_hd_deflater *deflater); - -/** - * @function - * - * Returns the table entry denoted by |idx| from header table of - * |deflater|. The |idx| is 1-based, and idx=1 returns first entry of - * static table. idx=62 returns first entry of dynamic table if it - * exists. Specifying idx=0 is error, and this function returns NULL. - * If |idx| is strictly greater than the number of entries the tables - * contain, this function returns NULL. - */ -NGHTTP2_EXTERN -const nghttp2_nv * -nghttp2_hd_deflate_get_table_entry(nghttp2_hd_deflater *deflater, size_t idx); - -/** - * @function - * - * Returns the used dynamic table size, including the overhead 32 - * bytes per entry described in RFC 7541. - */ -NGHTTP2_EXTERN -size_t nghttp2_hd_deflate_get_dynamic_table_size(nghttp2_hd_deflater *deflater); - -/** - * @function - * - * Returns the maximum dynamic table size. - */ -NGHTTP2_EXTERN -size_t -nghttp2_hd_deflate_get_max_dynamic_table_size(nghttp2_hd_deflater *deflater); - -struct nghttp2_hd_inflater; - -/** - * @struct - * - * HPACK inflater object. - */ -typedef struct nghttp2_hd_inflater nghttp2_hd_inflater; - -/** - * @function - * - * Initializes |*inflater_ptr| for inflating name/values pairs. - * - * If this function fails, |*inflater_ptr| is left untouched. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -NGHTTP2_EXTERN int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr); - -/** - * @function - * - * Like `nghttp2_hd_inflate_new()`, but with additional custom memory - * allocator specified in the |mem|. - * - * The |mem| can be ``NULL`` and the call is equivalent to - * `nghttp2_hd_inflate_new()`. - * - * This function does not take ownership |mem|. The application is - * responsible for freeing |mem|. - * - * The library code does not refer to |mem| pointer after this - * function returns, so the application can safely free it. - */ -NGHTTP2_EXTERN int nghttp2_hd_inflate_new2(nghttp2_hd_inflater **inflater_ptr, - nghttp2_mem *mem); - -/** - * @function - * - * Deallocates any resources allocated for |inflater|. - */ -NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater); - -/** - * @function - * - * Changes header table size in the |inflater|. This may trigger - * eviction in the dynamic table. - * - * The |settings_max_dynamic_table_size| should be the value - * transmitted in SETTINGS_HEADER_TABLE_SIZE. - * - * This function must not be called while header block is being - * inflated. In other words, this function must be called after - * initialization of |inflater|, but before calling - * `nghttp2_hd_inflate_hd3()`, or after - * `nghttp2_hd_inflate_end_headers()`. Otherwise, - * `NGHTTP2_ERR_INVALID_STATE` was returned. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * The function is called while header block is being inflated. - * Probably, application missed to call - * `nghttp2_hd_inflate_end_headers()`. - */ -NGHTTP2_EXTERN int -nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater, - size_t settings_max_dynamic_table_size); - -/** - * @enum - * - * The flags for header inflation. - */ -typedef enum { - /** - * No flag set. - */ - NGHTTP2_HD_INFLATE_NONE = 0, - /** - * Indicates all headers were inflated. - */ - NGHTTP2_HD_INFLATE_FINAL = 0x01, - /** - * Indicates a header was emitted. - */ - NGHTTP2_HD_INFLATE_EMIT = 0x02 -} nghttp2_hd_inflate_flag; - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_hd_inflate_hd2()` instead. - * - * Inflates name/value block stored in |in| with length |inlen|. This - * function performs decompression. For each successful emission of - * header name/value pair, - * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in - * |*inflate_flags| and name/value pair is assigned to the |nv_out| - * and the function returns. The caller must not free the members of - * |nv_out|. - * - * The |nv_out| may include pointers to the memory region in the |in|. - * The caller must retain the |in| while the |nv_out| is used. - * - * The application should call this function repeatedly until the - * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and - * return value is non-negative. This means the all input values are - * processed successfully. Then the application must call - * `nghttp2_hd_inflate_end_headers()` to prepare for the next header - * block input. - * - * The caller can feed complete compressed header block. It also can - * feed it in several chunks. The caller must set |in_final| to - * nonzero if the given input is the last block of the compressed - * header. - * - * This function returns the number of bytes processed if it succeeds, - * or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` - * Inflation process has failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR` - * The header field name or value is too large. - * - * Example follows:: - * - * int inflate_header_block(nghttp2_hd_inflater *hd_inflater, - * uint8_t *in, size_t inlen, int final) - * { - * ssize_t rv; - * - * for(;;) { - * nghttp2_nv nv; - * int inflate_flags = 0; - * - * rv = nghttp2_hd_inflate_hd(hd_inflater, &nv, &inflate_flags, - * in, inlen, final); - * - * if(rv < 0) { - * fprintf(stderr, "inflate failed with error code %zd", rv); - * return -1; - * } - * - * in += rv; - * inlen -= rv; - * - * if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) { - * fwrite(nv.name, nv.namelen, 1, stderr); - * fprintf(stderr, ": "); - * fwrite(nv.value, nv.valuelen, 1, stderr); - * fprintf(stderr, "\n"); - * } - * if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) { - * nghttp2_hd_inflate_end_headers(hd_inflater); - * break; - * } - * if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && - * inlen == 0) { - * break; - * } - * } - * - * return 0; - * } - * - */ -NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, - nghttp2_nv *nv_out, - int *inflate_flags, uint8_t *in, - size_t inlen, int in_final); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -#ifndef NGHTTP2_NO_SSIZE_T -/** - * @function - * - * .. warning:: - * - * Deprecated. Use `nghttp2_hd_inflate_hd3()` instead. - * - * Inflates name/value block stored in |in| with length |inlen|. This - * function performs decompression. For each successful emission of - * header name/value pair, - * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in - * |*inflate_flags| and name/value pair is assigned to the |nv_out| - * and the function returns. The caller must not free the members of - * |nv_out|. - * - * The |nv_out| may include pointers to the memory region in the |in|. - * The caller must retain the |in| while the |nv_out| is used. - * - * The application should call this function repeatedly until the - * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and - * return value is non-negative. If that happens, all given input - * data (|inlen| bytes) are processed successfully. Then the - * application must call `nghttp2_hd_inflate_end_headers()` to prepare - * for the next header block input. - * - * In other words, if |in_final| is nonzero, and this function returns - * |inlen|, you can assert that - * :enum:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in - * |*inflate_flags|. - * - * The caller can feed complete compressed header block. It also can - * feed it in several chunks. The caller must set |in_final| to - * nonzero if the given input is the last block of the compressed - * header. - * - * This function returns the number of bytes processed if it succeeds, - * or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` - * Inflation process has failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR` - * The header field name or value is too large. - * - * Example follows:: - * - * int inflate_header_block(nghttp2_hd_inflater *hd_inflater, - * uint8_t *in, size_t inlen, int final) - * { - * ssize_t rv; - * - * for(;;) { - * nghttp2_nv nv; - * int inflate_flags = 0; - * - * rv = nghttp2_hd_inflate_hd2(hd_inflater, &nv, &inflate_flags, - * in, inlen, final); - * - * if(rv < 0) { - * fprintf(stderr, "inflate failed with error code %zd", rv); - * return -1; - * } - * - * in += rv; - * inlen -= rv; - * - * if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) { - * fwrite(nv.name, nv.namelen, 1, stderr); - * fprintf(stderr, ": "); - * fwrite(nv.value, nv.valuelen, 1, stderr); - * fprintf(stderr, "\n"); - * } - * if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) { - * nghttp2_hd_inflate_end_headers(hd_inflater); - * break; - * } - * if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && - * inlen == 0) { - * break; - * } - * } - * - * return 0; - * } - * - */ -NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater, - nghttp2_nv *nv_out, - int *inflate_flags, - const uint8_t *in, size_t inlen, - int in_final); - -#endif /* NGHTTP2_NO_SSIZE_T */ - -/** - * @function - * - * Inflates name/value block stored in |in| with length |inlen|. This - * function performs decompression. For each successful emission of - * header name/value pair, - * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in - * |*inflate_flags| and name/value pair is assigned to the |nv_out| - * and the function returns. The caller must not free the members of - * |nv_out|. - * - * The |nv_out| may include pointers to the memory region in the |in|. - * The caller must retain the |in| while the |nv_out| is used. - * - * The application should call this function repeatedly until the - * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and - * return value is non-negative. If that happens, all given input - * data (|inlen| bytes) are processed successfully. Then the - * application must call `nghttp2_hd_inflate_end_headers()` to prepare - * for the next header block input. - * - * In other words, if |in_final| is nonzero, and this function returns - * |inlen|, you can assert that - * :enum:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in - * |*inflate_flags|. - * - * The caller can feed complete compressed header block. It also can - * feed it in several chunks. The caller must set |in_final| to - * nonzero if the given input is the last block of the compressed - * header. - * - * This function returns the number of bytes processed if it succeeds, - * or one of the following negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` - * Inflation process has failed. - * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR` - * The header field name or value is too large. - * - * Example follows:: - * - * int inflate_header_block(nghttp2_hd_inflater *hd_inflater, - * uint8_t *in, size_t inlen, int final) - * { - * nghttp2_ssize rv; - * - * for(;;) { - * nghttp2_nv nv; - * int inflate_flags = 0; - * - * rv = nghttp2_hd_inflate_hd3(hd_inflater, &nv, &inflate_flags, - * in, inlen, final); - * - * if(rv < 0) { - * fprintf(stderr, "inflate failed with error code %td", rv); - * return -1; - * } - * - * in += rv; - * inlen -= rv; - * - * if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) { - * fwrite(nv.name, nv.namelen, 1, stderr); - * fprintf(stderr, ": "); - * fwrite(nv.value, nv.valuelen, 1, stderr); - * fprintf(stderr, "\n"); - * } - * if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) { - * nghttp2_hd_inflate_end_headers(hd_inflater); - * break; - * } - * if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && - * inlen == 0) { - * break; - * } - * } - * - * return 0; - * } - * - */ -NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_inflate_hd3( - nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, int *inflate_flags, - const uint8_t *in, size_t inlen, int in_final); - -/** - * @function - * - * Signals the end of decompression for one header block. - * - * This function returns 0 if it succeeds. Currently this function - * always succeeds. - */ -NGHTTP2_EXTERN int -nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater); - -/** - * @function - * - * Returns the number of entries that header table of |inflater| - * contains. This is the sum of the number of static table and - * dynamic table, so the return value is at least 61. - */ -NGHTTP2_EXTERN -size_t nghttp2_hd_inflate_get_num_table_entries(nghttp2_hd_inflater *inflater); - -/** - * @function - * - * Returns the table entry denoted by |idx| from header table of - * |inflater|. The |idx| is 1-based, and idx=1 returns first entry of - * static table. idx=62 returns first entry of dynamic table if it - * exists. Specifying idx=0 is error, and this function returns NULL. - * If |idx| is strictly greater than the number of entries the tables - * contain, this function returns NULL. - */ -NGHTTP2_EXTERN -const nghttp2_nv * -nghttp2_hd_inflate_get_table_entry(nghttp2_hd_inflater *inflater, size_t idx); - -/** - * @function - * - * Returns the used dynamic table size, including the overhead 32 - * bytes per entry described in RFC 7541. - */ -NGHTTP2_EXTERN -size_t nghttp2_hd_inflate_get_dynamic_table_size(nghttp2_hd_inflater *inflater); - -/** - * @function - * - * Returns the maximum dynamic table size. - */ -NGHTTP2_EXTERN -size_t -nghttp2_hd_inflate_get_max_dynamic_table_size(nghttp2_hd_inflater *inflater); - -struct nghttp2_stream; - -/** - * @struct - * - * The structure to represent HTTP/2 stream. The details of this - * structure are intentionally hidden from the public API. - */ -typedef struct nghttp2_stream nghttp2_stream; - -/** - * @function - * - * Returns pointer to :type:`nghttp2_stream` object denoted by - * |stream_id|. If stream was not found, returns NULL. - * - * Returns imaginary root stream (see - * `nghttp2_session_get_root_stream()`) if 0 is given in |stream_id|. - * - * Unless |stream_id| == 0, the returned pointer is valid until next - * call of `nghttp2_session_send()`, `nghttp2_session_mem_send2()`, - * `nghttp2_session_recv()`, and `nghttp2_session_mem_recv2()`. - */ -NGHTTP2_EXTERN nghttp2_stream * -nghttp2_session_find_stream(nghttp2_session *session, int32_t stream_id); - -/** - * @enum - * - * State of stream as described in RFC 7540. - */ -typedef enum { - /** - * idle state. - */ - NGHTTP2_STREAM_STATE_IDLE = 1, - /** - * open state. - */ - NGHTTP2_STREAM_STATE_OPEN, - /** - * reserved (local) state. - */ - NGHTTP2_STREAM_STATE_RESERVED_LOCAL, - /** - * reserved (remote) state. - */ - NGHTTP2_STREAM_STATE_RESERVED_REMOTE, - /** - * half closed (local) state. - */ - NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL, - /** - * half closed (remote) state. - */ - NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE, - /** - * closed state. - */ - NGHTTP2_STREAM_STATE_CLOSED -} nghttp2_stream_proto_state; - -/** - * @function - * - * Returns state of |stream|. The root stream retrieved by - * `nghttp2_session_get_root_stream()` will have stream state - * :enum:`nghttp2_stream_proto_state.NGHTTP2_STREAM_STATE_IDLE`. - */ -NGHTTP2_EXTERN nghttp2_stream_proto_state -nghttp2_stream_get_state(nghttp2_stream *stream); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * Returns root of dependency tree, which is imaginary stream with - * stream ID 0. The returned pointer is valid until |session| is - * freed by `nghttp2_session_del()`. - */ -NGHTTP2_EXTERN nghttp2_stream * -nghttp2_session_get_root_stream(nghttp2_session *session); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function always returns NULL. - */ -NGHTTP2_EXTERN nghttp2_stream * -nghttp2_stream_get_parent(nghttp2_stream *stream); - -NGHTTP2_EXTERN int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function always returns NULL. - */ -NGHTTP2_EXTERN nghttp2_stream * -nghttp2_stream_get_next_sibling(nghttp2_stream *stream); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function always returns NULL. - */ -NGHTTP2_EXTERN nghttp2_stream * -nghttp2_stream_get_previous_sibling(nghttp2_stream *stream); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function always returns NULL. - */ -NGHTTP2_EXTERN nghttp2_stream * -nghttp2_stream_get_first_child(nghttp2_stream *stream); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function always returns :macro:`NGHTTP2_DEFAULT_WEIGHT`. - */ -NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream); - -/** - * @function - * - * .. warning:: - * - * Deprecated. :rfc:`7540` priorities are deprecated by - * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible - * prioritization scheme. - * - * This function always returns 0. - */ -NGHTTP2_EXTERN int32_t -nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream); - -/** - * @functypedef - * - * Callback function invoked when the library outputs debug logging. - * The function is called with arguments suitable for ``vfprintf(3)`` - * - * The debug output is only enabled if the library is built with - * ``DEBUGBUILD`` macro defined. - */ -typedef void (*nghttp2_debug_vprintf_callback)(const char *format, - va_list args); - -/** - * @function - * - * Sets a debug output callback called by the library when built with - * ``DEBUGBUILD`` macro defined. If this option is not used, debug - * log is written into standard error output. - * - * For builds without ``DEBUGBUILD`` macro defined, this function is - * noop. - * - * Note that building with ``DEBUGBUILD`` may cause significant - * performance penalty to libnghttp2 because of extra processing. It - * should be used for debugging purpose only. - * - * .. Warning:: - * - * Building with ``DEBUGBUILD`` may cause significant performance - * penalty to libnghttp2 because of extra processing. It should be - * used for debugging purpose only. We write this two times because - * this is important. - */ -NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback); - -#ifdef __cplusplus -} -#endif - -#endif /* NGHTTP2_H */ diff --git a/vendor/nghttp2/lib/includes/nghttp2/nghttp2ver.h.in b/vendor/nghttp2/lib/includes/nghttp2/nghttp2ver.h.in deleted file mode 100644 index 7717a647f..000000000 --- a/vendor/nghttp2/lib/includes/nghttp2/nghttp2ver.h.in +++ /dev/null @@ -1,42 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2VER_H -#define NGHTTP2VER_H - -/** - * @macro - * Version number of the nghttp2 library release - */ -#define NGHTTP2_VERSION "@PACKAGE_VERSION@" - -/** - * @macro - * Numerical representation of the version number of the nghttp2 library - * release. This is a 24 bit number with 8 bits for major number, 8 bits - * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. - */ -#define NGHTTP2_VERSION_NUM @PACKAGE_VERSION_NUM@ - -#endif /* NGHTTP2VER_H */ diff --git a/vendor/nghttp2/lib/nghttp2_alpn.c b/vendor/nghttp2/lib/nghttp2_alpn.c deleted file mode 100644 index 33c5885f8..000000000 --- a/vendor/nghttp2/lib/nghttp2_alpn.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_alpn.h" - -#include - -static int select_alpn(const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - const char *key, unsigned int keylen) { - unsigned int i; - for (i = 0; i + keylen <= inlen; i += (unsigned int)(in[i] + 1)) { - if (memcmp(&in[i], key, keylen) == 0) { - *out = (unsigned char *)&in[i + 1]; - *outlen = in[i]; - return 0; - } - } - return -1; -} - -#define NGHTTP2_HTTP_1_1_ALPN "\x8http/1.1" -#define NGHTTP2_HTTP_1_1_ALPN_LEN (sizeof(NGHTTP2_HTTP_1_1_ALPN) - 1) - -int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen) { - if (select_alpn((const unsigned char **)out, outlen, in, inlen, - NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN) == 0) { - return 1; - } - if (select_alpn((const unsigned char **)out, outlen, in, inlen, - NGHTTP2_HTTP_1_1_ALPN, NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) { - return 0; - } - return -1; -} - -int nghttp2_select_alpn(const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen) { - if (select_alpn(out, outlen, in, inlen, NGHTTP2_PROTO_ALPN, - NGHTTP2_PROTO_ALPN_LEN) == 0) { - return 1; - } - if (select_alpn(out, outlen, in, inlen, NGHTTP2_HTTP_1_1_ALPN, - NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) { - return 0; - } - return -1; -} diff --git a/vendor/nghttp2/lib/nghttp2_alpn.h b/vendor/nghttp2/lib/nghttp2_alpn.h deleted file mode 100644 index 09810fd82..000000000 --- a/vendor/nghttp2/lib/nghttp2_alpn.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_ALPN_H -#define NGHTTP2_ALPN_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -#endif /* NGHTTP2_ALPN_H */ diff --git a/vendor/nghttp2/lib/nghttp2_buf.c b/vendor/nghttp2/lib/nghttp2_buf.c deleted file mode 100644 index 15cd674a6..000000000 --- a/vendor/nghttp2/lib/nghttp2_buf.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_buf.h" - -#include - -#include "nghttp2_helper.h" -#include "nghttp2_debug.h" - -void nghttp2_buf_init(nghttp2_buf *buf) { - buf->begin = NULL; - buf->end = NULL; - buf->pos = NULL; - buf->last = NULL; - buf->mark = NULL; -} - -int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial, nghttp2_mem *mem) { - nghttp2_buf_init(buf); - return nghttp2_buf_reserve(buf, initial, mem); -} - -void nghttp2_buf_free(nghttp2_buf *buf, nghttp2_mem *mem) { - if (buf == NULL) { - return; - } - - nghttp2_mem_free(mem, buf->begin); - buf->begin = NULL; -} - -int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap, nghttp2_mem *mem) { - uint8_t *ptr; - size_t cap; - - cap = nghttp2_buf_cap(buf); - - if (cap >= new_cap) { - return 0; - } - - new_cap = nghttp2_max_size(new_cap, cap * 2); - - ptr = nghttp2_mem_realloc(mem, buf->begin, new_cap); - if (ptr == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - buf->pos = ptr + (buf->pos - buf->begin); - buf->last = ptr + (buf->last - buf->begin); - buf->mark = ptr + (buf->mark - buf->begin); - buf->begin = ptr; - buf->end = ptr + new_cap; - - return 0; -} - -void nghttp2_buf_reset(nghttp2_buf *buf) { - buf->pos = buf->last = buf->mark = buf->begin; -} - -void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len) { - buf->begin = buf->pos = buf->last = buf->mark = buf->end = begin; - if (len) { - buf->end += len; - } -} - -static int buf_chain_new(nghttp2_buf_chain **chain, size_t chunk_length, - nghttp2_mem *mem) { - int rv; - - *chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain)); - if (*chain == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - (*chain)->next = NULL; - - rv = nghttp2_buf_init2(&(*chain)->buf, chunk_length, mem); - if (rv != 0) { - nghttp2_mem_free(mem, *chain); - return NGHTTP2_ERR_NOMEM; - } - - return 0; -} - -static void buf_chain_del(nghttp2_buf_chain *chain, nghttp2_mem *mem) { - nghttp2_buf_free(&chain->buf, mem); - nghttp2_mem_free(mem, chain); -} - -int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk, - nghttp2_mem *mem) { - return nghttp2_bufs_init2(bufs, chunk_length, max_chunk, 0, mem); -} - -int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length, - size_t max_chunk, size_t offset, nghttp2_mem *mem) { - return nghttp2_bufs_init3(bufs, chunk_length, max_chunk, max_chunk, offset, - mem); -} - -int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length, - size_t max_chunk, size_t chunk_keep, size_t offset, - nghttp2_mem *mem) { - int rv; - nghttp2_buf_chain *chain; - - if (chunk_keep == 0 || max_chunk < chunk_keep || chunk_length < offset) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - rv = buf_chain_new(&chain, chunk_length, mem); - if (rv != 0) { - return rv; - } - - bufs->mem = mem; - bufs->offset = offset; - - bufs->head = chain; - bufs->cur = bufs->head; - - nghttp2_buf_shift_right(&bufs->cur->buf, offset); - - bufs->chunk_length = chunk_length; - bufs->chunk_used = 1; - bufs->max_chunk = max_chunk; - bufs->chunk_keep = chunk_keep; - - return 0; -} - -int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length) { - int rv; - nghttp2_buf_chain *chain; - - if (chunk_length < bufs->offset) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - rv = buf_chain_new(&chain, chunk_length, bufs->mem); - if (rv != 0) { - return rv; - } - - nghttp2_bufs_free(bufs); - - bufs->head = chain; - bufs->cur = bufs->head; - - nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset); - - bufs->chunk_length = chunk_length; - bufs->chunk_used = 1; - - return 0; -} - -void nghttp2_bufs_free(nghttp2_bufs *bufs) { - nghttp2_buf_chain *chain, *next_chain; - - if (bufs == NULL) { - return; - } - - for (chain = bufs->head; chain;) { - next_chain = chain->next; - - buf_chain_del(chain, bufs->mem); - - chain = next_chain; - } - - bufs->head = NULL; -} - -int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len, - nghttp2_mem *mem) { - nghttp2_buf_chain *chain; - - chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain)); - if (chain == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - chain->next = NULL; - - nghttp2_buf_wrap_init(&chain->buf, begin, len); - - bufs->mem = mem; - bufs->offset = 0; - - bufs->head = chain; - bufs->cur = bufs->head; - - bufs->chunk_length = len; - bufs->chunk_used = 1; - bufs->max_chunk = 1; - bufs->chunk_keep = 1; - - return 0; -} - -int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec, - size_t veclen, nghttp2_mem *mem) { - size_t i = 0; - nghttp2_buf_chain *cur_chain; - nghttp2_buf_chain *head_chain; - nghttp2_buf_chain **dst_chain = &head_chain; - - if (veclen == 0) { - return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem); - } - - head_chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain) * veclen); - if (head_chain == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - for (i = 0; i < veclen; ++i) { - cur_chain = &head_chain[i]; - cur_chain->next = NULL; - nghttp2_buf_wrap_init(&cur_chain->buf, vec[i].base, vec[i].len); - - *dst_chain = cur_chain; - dst_chain = &cur_chain->next; - } - - bufs->mem = mem; - bufs->offset = 0; - - bufs->head = head_chain; - bufs->cur = bufs->head; - - /* We don't use chunk_length since no allocation is expected. */ - bufs->chunk_length = 0; - bufs->chunk_used = veclen; - bufs->max_chunk = veclen; - bufs->chunk_keep = veclen; - - return 0; -} - -void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) { - if (bufs == NULL) { - return; - } - - if (bufs->head) { - nghttp2_mem_free(bufs->mem, bufs->head); - } -} - -void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) { - nghttp2_buf_chain *ci; - - for (ci = bufs->cur; ci; ci = ci->next) { - if (nghttp2_buf_len(&ci->buf) == 0) { - return; - } else { - bufs->cur = ci; - } - } -} - -size_t nghttp2_bufs_len(nghttp2_bufs *bufs) { - nghttp2_buf_chain *ci; - size_t len; - - len = 0; - for (ci = bufs->head; ci; ci = ci->next) { - len += nghttp2_buf_len(&ci->buf); - } - - return len; -} - -static int bufs_alloc_chain(nghttp2_bufs *bufs) { - int rv; - nghttp2_buf_chain *chain; - - if (bufs->cur->next) { - bufs->cur = bufs->cur->next; - - return 0; - } - - if (bufs->max_chunk == bufs->chunk_used) { - return NGHTTP2_ERR_BUFFER_ERROR; - } - - rv = buf_chain_new(&chain, bufs->chunk_length, bufs->mem); - if (rv != 0) { - return rv; - } - - DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n", - bufs->chunk_length, bufs, bufs->chunk_used); - - ++bufs->chunk_used; - - bufs->cur->next = chain; - bufs->cur = chain; - - nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset); - - return 0; -} - -int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) { - int rv; - size_t nwrite; - nghttp2_buf *buf; - const uint8_t *p; - - p = data; - - while (len) { - buf = &bufs->cur->buf; - - nwrite = nghttp2_min_size(nghttp2_buf_avail(buf), len); - if (nwrite == 0) { - rv = bufs_alloc_chain(bufs); - if (rv != 0) { - return rv; - } - continue; - } - - buf->last = nghttp2_cpymem(buf->last, p, nwrite); - p += nwrite; - len -= nwrite; - } - - return 0; -} - -static int bufs_ensure_addb(nghttp2_bufs *bufs) { - int rv; - nghttp2_buf *buf; - - buf = &bufs->cur->buf; - - if (nghttp2_buf_avail(buf) > 0) { - return 0; - } - - rv = bufs_alloc_chain(bufs); - if (rv != 0) { - return rv; - } - - return 0; -} - -int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b) { - int rv; - - rv = bufs_ensure_addb(bufs); - if (rv != 0) { - return rv; - } - - *bufs->cur->buf.last++ = b; - - return 0; -} - -int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b) { - int rv; - - rv = bufs_ensure_addb(bufs); - if (rv != 0) { - return rv; - } - - *bufs->cur->buf.last = b; - - return 0; -} - -int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b) { - int rv; - - rv = bufs_ensure_addb(bufs); - if (rv != 0) { - return rv; - } - - *bufs->cur->buf.last++ |= b; - - return 0; -} - -int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b) { - int rv; - - rv = bufs_ensure_addb(bufs); - if (rv != 0) { - return rv; - } - - *bufs->cur->buf.last |= b; - - return 0; -} - -nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) { - size_t len; - nghttp2_buf_chain *chain; - nghttp2_buf *buf; - uint8_t *res; - nghttp2_buf resbuf; - - len = 0; - - for (chain = bufs->head; chain; chain = chain->next) { - len += nghttp2_buf_len(&chain->buf); - } - - if (len == 0) { - res = NULL; - return 0; - } - - res = nghttp2_mem_malloc(bufs->mem, len); - if (res == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_buf_wrap_init(&resbuf, res, len); - - for (chain = bufs->head; chain; chain = chain->next) { - buf = &chain->buf; - resbuf.last = nghttp2_cpymem(resbuf.last, buf->pos, nghttp2_buf_len(buf)); - } - - *out = res; - - return (nghttp2_ssize)len; -} - -size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out) { - size_t len; - nghttp2_buf_chain *chain; - nghttp2_buf *buf; - nghttp2_buf resbuf; - - len = nghttp2_bufs_len(bufs); - - nghttp2_buf_wrap_init(&resbuf, out, len); - - for (chain = bufs->head; chain; chain = chain->next) { - buf = &chain->buf; - resbuf.last = nghttp2_cpymem(resbuf.last, buf->pos, nghttp2_buf_len(buf)); - } - - return len; -} - -void nghttp2_bufs_reset(nghttp2_bufs *bufs) { - nghttp2_buf_chain *chain, *ci; - size_t k; - - k = bufs->chunk_keep; - - for (ci = bufs->head; ci; ci = ci->next) { - nghttp2_buf_reset(&ci->buf); - nghttp2_buf_shift_right(&ci->buf, bufs->offset); - - if (--k == 0) { - break; - } - } - - if (ci) { - chain = ci->next; - ci->next = NULL; - - for (ci = chain; ci;) { - chain = ci->next; - - buf_chain_del(ci, bufs->mem); - - ci = chain; - } - - bufs->chunk_used = bufs->chunk_keep; - } - - bufs->cur = bufs->head; -} - -int nghttp2_bufs_advance(nghttp2_bufs *bufs) { return bufs_alloc_chain(bufs); } - -int nghttp2_bufs_next_present(nghttp2_bufs *bufs) { - nghttp2_buf_chain *chain; - - chain = bufs->cur->next; - - return chain && nghttp2_buf_len(&chain->buf); -} diff --git a/vendor/nghttp2/lib/nghttp2_buf.h b/vendor/nghttp2/lib/nghttp2_buf.h deleted file mode 100644 index 95ff3706a..000000000 --- a/vendor/nghttp2/lib/nghttp2_buf.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_BUF_H -#define NGHTTP2_BUF_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -#include "nghttp2_int.h" -#include "nghttp2_mem.h" - -typedef struct { - /* This points to the beginning of the buffer. The effective range - of buffer is [begin, end). */ - uint8_t *begin; - /* This points to the memory one byte beyond the end of the - buffer. */ - uint8_t *end; - /* The position indicator for effective start of the buffer. pos <= - last must be hold. */ - uint8_t *pos; - /* The position indicator for effective one beyond of the end of the - buffer. last <= end must be hold. */ - uint8_t *last; - /* Mark arbitrary position in buffer [begin, end) */ - uint8_t *mark; -} nghttp2_buf; - -#define nghttp2_buf_len(BUF) ((size_t)((BUF)->last - (BUF)->pos)) -#define nghttp2_buf_avail(BUF) ((size_t)((BUF)->end - (BUF)->last)) -#define nghttp2_buf_mark_avail(BUF) ((size_t)((BUF)->mark - (BUF)->last)) -#define nghttp2_buf_cap(BUF) ((size_t)((BUF)->end - (BUF)->begin)) - -#define nghttp2_buf_pos_offset(BUF) ((size_t)((BUF)->pos - (BUF)->begin)) -#define nghttp2_buf_last_offset(BUF) ((size_t)((BUF)->last - (BUF)->begin)) - -#define nghttp2_buf_shift_right(BUF, AMT) \ - do { \ - (BUF)->pos += AMT; \ - (BUF)->last += AMT; \ - } while (0) - -#define nghttp2_buf_shift_left(BUF, AMT) \ - do { \ - (BUF)->pos -= AMT; \ - (BUF)->last -= AMT; \ - } while (0) - -/* - * Initializes the |buf|. No memory is allocated in this function. Use - * nghttp2_buf_reserve() to allocate memory. - */ -void nghttp2_buf_init(nghttp2_buf *buf); - -/* - * Initializes the |buf| and allocates at least |initial| bytes of - * memory. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial, nghttp2_mem *mem); - -/* - * Frees buffer in |buf|. - */ -void nghttp2_buf_free(nghttp2_buf *buf, nghttp2_mem *mem); - -/* - * Extends buffer so that nghttp2_buf_cap() returns at least - * |new_cap|. If extensions took place, buffer pointers in |buf| will - * change. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap, nghttp2_mem *mem); - -/* - * Resets pos, last, mark member of |buf| to buf->begin. - */ -void nghttp2_buf_reset(nghttp2_buf *buf); - -/* - * Initializes |buf| using supplied buffer |begin| of length - * |len|. Semantically, the application should not call *_reserve() or - * nghttp2_free() functions for |buf|. - */ -void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len); - -struct nghttp2_buf_chain; - -typedef struct nghttp2_buf_chain nghttp2_buf_chain; - -/* Chains 2 buffers */ -struct nghttp2_buf_chain { - /* Points to the subsequent buffer. NULL if there is no such - buffer. */ - nghttp2_buf_chain *next; - nghttp2_buf buf; -}; - -typedef struct { - /* Points to the first buffer */ - nghttp2_buf_chain *head; - /* Buffer pointer where write occurs. */ - nghttp2_buf_chain *cur; - /* Memory allocator */ - nghttp2_mem *mem; - /* The buffer capacity of each buf. This field may be 0 if - nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family - functions. */ - size_t chunk_length; - /* The maximum number of nghttp2_buf_chain */ - size_t max_chunk; - /* The number of nghttp2_buf_chain allocated */ - size_t chunk_used; - /* The number of nghttp2_buf_chain to keep on reset */ - size_t chunk_keep; - /* pos offset from begin in each buffers. On initialization and - reset, buf->pos and buf->last are positioned at buf->begin + - offset. */ - size_t offset; -} nghttp2_bufs; - -/* - * This is the same as calling nghttp2_bufs_init2 with the given - * arguments and offset = 0. - */ -int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk, - nghttp2_mem *mem); - -/* - * This is the same as calling nghttp2_bufs_init3 with the given - * arguments and chunk_keep = max_chunk. - */ -int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length, - size_t max_chunk, size_t offset, nghttp2_mem *mem); - -/* - * Initializes |bufs|. Each buffer size is given in the - * |chunk_length|. The maximum number of buffers is given in the - * |max_chunk|. On reset, first |chunk_keep| buffers are kept and - * remaining buffers are deleted. Each buffer will have bufs->pos and - * bufs->last shifted to left by |offset| bytes on creation and reset. - * - * This function allocates first buffer. bufs->head and bufs->cur - * will point to the first buffer after this call. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_INVALID_ARGUMENT - * chunk_keep is 0; or max_chunk < chunk_keep; or offset is too - * long. - */ -int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length, - size_t max_chunk, size_t chunk_keep, size_t offset, - nghttp2_mem *mem); - -/* - * Frees any related resources to the |bufs|. - */ -void nghttp2_bufs_free(nghttp2_bufs *bufs); - -/* - * Initializes |bufs| using supplied buffer |begin| of length |len|. - * The first buffer bufs->head uses buffer |begin|. The buffer size - * is fixed and no extra chunk buffer is allocated. In other - * words, max_chunk = chunk_keep = 1. To free the resource allocated - * for |bufs|, use nghttp2_bufs_wrap_free(). - * - * Don't use the function which performs allocation, such as - * nghttp2_bufs_realloc(). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len, - nghttp2_mem *mem); - -/* - * Initializes |bufs| using supplied |veclen| size of buf vector - * |vec|. The number of buffers is fixed and no extra chunk buffer is - * allocated. In other words, max_chunk = chunk_keep = |in_len|. To - * free the resource allocated for |bufs|, use - * nghttp2_bufs_wrap_free(). - * - * Don't use the function which performs allocation, such as - * nghttp2_bufs_realloc(). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec, - size_t veclen, nghttp2_mem *mem); - -/* - * Frees any related resource to the |bufs|. This function does not - * free supplied buffer provided in nghttp2_bufs_wrap_init(). - */ -void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs); - -/* - * Reallocates internal buffer using |chunk_length|. The max_chunk, - * chunk_keep and offset do not change. After successful allocation - * of new buffer, previous buffers are deallocated without copying - * anything into new buffers. chunk_used is reset to 1. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_INVALID_ARGUMENT - * chunk_length < offset - */ -int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length); - -/* - * Appends the |data| of length |len| to the |bufs|. The write starts - * at bufs->cur->buf.last. A new buffers will be allocated to store - * all data. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_BUFFER_ERROR - * Out of buffer space. - */ -int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len); - -/* - * Appends a single byte |b| to the |bufs|. The write starts at - * bufs->cur->buf.last. A new buffers will be allocated to store all - * data. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_BUFFER_ERROR - * Out of buffer space. - */ -int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b); - -/* - * Behaves like nghttp2_bufs_addb(), but this does not update - * buf->last pointer. - */ -int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b); - -#define nghttp2_bufs_fast_addb(BUFS, B) \ - do { \ - *(BUFS)->cur->buf.last++ = B; \ - } while (0) - -#define nghttp2_bufs_fast_addb_hold(BUFS, B) \ - do { \ - *(BUFS)->cur->buf.last = B; \ - } while (0) - -/* - * Performs bitwise-OR of |b| at bufs->cur->buf.last. A new buffers - * will be allocated if necessary. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_BUFFER_ERROR - * Out of buffer space. - */ -int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b); - -/* - * Behaves like nghttp2_bufs_orb(), but does not update buf->last - * pointer. - */ -int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b); - -#define nghttp2_bufs_fast_orb(BUFS, B) \ - do { \ - uint8_t **p = &(BUFS)->cur->buf.last; \ - **p = (uint8_t)(**p | (B)); \ - ++(*p); \ - } while (0) - -#define nghttp2_bufs_fast_orb_hold(BUFS, B) \ - do { \ - uint8_t *p = (BUFS)->cur->buf.last; \ - *p = (uint8_t)(*p | (B)); \ - } while (0) - -/* - * Copies all data stored in |bufs| to the contiguous buffer. This - * function allocates the contiguous memory to store all data in - * |bufs| and assigns it to |*out|. - * - * The contents of |bufs| is left unchanged. - * - * This function returns the length of copied data and assigns the - * pointer to copied data to |*out| if it succeeds, or one of the - * following negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out); - -/* - * Copies all data stored in |bufs| to |out|. This function assumes - * that the buffer space pointed by |out| has at least - * nghttp2_bufs(bufs) bytes. - * - * The contents of |bufs| is left unchanged. - * - * This function returns the length of copied data. - */ -size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out); - -/* - * Resets |bufs| and makes the buffers empty. - */ -void nghttp2_bufs_reset(nghttp2_bufs *bufs); - -/* - * Moves bufs->cur to bufs->cur->next. If resulting bufs->cur is - * NULL, this function allocates new buffers and bufs->cur points to - * it. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - * NGHTTP2_ERR_BUFFER_ERROR - * Out of buffer space. - */ -int nghttp2_bufs_advance(nghttp2_bufs *bufs); - -/* Sets bufs->cur to bufs->head */ -#define nghttp2_bufs_rewind(BUFS) \ - do { \ - (BUFS)->cur = (BUFS)->head; \ - } while (0) - -/* - * Move bufs->cur, from the current position, using next member, to - * the last buf which has nghttp2_buf_len(buf) > 0 without seeing buf - * which satisfies nghttp2_buf_len(buf) == 0. If - * nghttp2_buf_len(&bufs->cur->buf) == 0 or bufs->cur->next is NULL, - * bufs->cur is unchanged. - */ -void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs); - -/* - * Returns nonzero if bufs->cur->next is not empty. - */ -int nghttp2_bufs_next_present(nghttp2_bufs *bufs); - -#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf) - -/* - * Returns the total buffer length of |bufs|. - */ -size_t nghttp2_bufs_len(nghttp2_bufs *bufs); - -#endif /* NGHTTP2_BUF_H */ diff --git a/vendor/nghttp2/lib/nghttp2_callbacks.c b/vendor/nghttp2/lib/nghttp2_callbacks.c deleted file mode 100644 index 162ca6bd4..000000000 --- a/vendor/nghttp2/lib/nghttp2_callbacks.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_callbacks.h" - -#include - -int nghttp2_session_callbacks_new(nghttp2_session_callbacks **callbacks_ptr) { - *callbacks_ptr = calloc(1, sizeof(nghttp2_session_callbacks)); - - if (*callbacks_ptr == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - return 0; -} - -void nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks) { - free(callbacks); -} - -void nghttp2_session_callbacks_set_send_callback( - nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) { - cbs->send_callback = send_callback; -} - -void nghttp2_session_callbacks_set_send_callback2( - nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback) { - cbs->send_callback2 = send_callback; -} - -void nghttp2_session_callbacks_set_recv_callback( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) { - cbs->recv_callback = recv_callback; -} - -void nghttp2_session_callbacks_set_recv_callback2( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback) { - cbs->recv_callback2 = recv_callback; -} - -void nghttp2_session_callbacks_set_on_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_recv_callback on_frame_recv_callback) { - cbs->on_frame_recv_callback = on_frame_recv_callback; -} - -void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback) { - cbs->on_invalid_frame_recv_callback = on_invalid_frame_recv_callback; -} - -void nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback) { - cbs->on_data_chunk_recv_callback = on_data_chunk_recv_callback; -} - -void nghttp2_session_callbacks_set_before_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_before_frame_send_callback before_frame_send_callback) { - cbs->before_frame_send_callback = before_frame_send_callback; -} - -void nghttp2_session_callbacks_set_on_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_send_callback on_frame_send_callback) { - cbs->on_frame_send_callback = on_frame_send_callback; -} - -void nghttp2_session_callbacks_set_on_frame_not_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_not_send_callback on_frame_not_send_callback) { - cbs->on_frame_not_send_callback = on_frame_not_send_callback; -} - -void nghttp2_session_callbacks_set_on_stream_close_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_stream_close_callback on_stream_close_callback) { - cbs->on_stream_close_callback = on_stream_close_callback; -} - -void nghttp2_session_callbacks_set_on_begin_headers_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_headers_callback on_begin_headers_callback) { - cbs->on_begin_headers_callback = on_begin_headers_callback; -} - -void nghttp2_session_callbacks_set_on_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback on_header_callback) { - cbs->on_header_callback = on_header_callback; -} - -void nghttp2_session_callbacks_set_on_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback2 on_header_callback2) { - cbs->on_header_callback2 = on_header_callback2; -} - -void nghttp2_session_callbacks_set_on_invalid_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback on_invalid_header_callback) { - cbs->on_invalid_header_callback = on_invalid_header_callback; -} - -void nghttp2_session_callbacks_set_on_invalid_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) { - cbs->on_invalid_header_callback2 = on_invalid_header_callback2; -} - -void nghttp2_session_callbacks_set_select_padding_callback( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback select_padding_callback) { - cbs->select_padding_callback = select_padding_callback; -} - -void nghttp2_session_callbacks_set_select_padding_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback2 select_padding_callback) { - cbs->select_padding_callback2 = select_padding_callback; -} - -void nghttp2_session_callbacks_set_data_source_read_length_callback( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback data_source_read_length_callback) { - cbs->read_length_callback = data_source_read_length_callback; -} - -void nghttp2_session_callbacks_set_data_source_read_length_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback2 data_source_read_length_callback) { - cbs->read_length_callback2 = data_source_read_length_callback; -} - -void nghttp2_session_callbacks_set_on_begin_frame_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_frame_callback on_begin_frame_callback) { - cbs->on_begin_frame_callback = on_begin_frame_callback; -} - -void nghttp2_session_callbacks_set_send_data_callback( - nghttp2_session_callbacks *cbs, - nghttp2_send_data_callback send_data_callback) { - cbs->send_data_callback = send_data_callback; -} - -void nghttp2_session_callbacks_set_pack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback pack_extension_callback) { - cbs->pack_extension_callback = pack_extension_callback; -} - -void nghttp2_session_callbacks_set_pack_extension_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback2 pack_extension_callback) { - cbs->pack_extension_callback2 = pack_extension_callback; -} - -void nghttp2_session_callbacks_set_unpack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_unpack_extension_callback unpack_extension_callback) { - cbs->unpack_extension_callback = unpack_extension_callback; -} - -void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) { - cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback; -} - -void nghttp2_session_callbacks_set_error_callback( - nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) { - cbs->error_callback = error_callback; -} - -void nghttp2_session_callbacks_set_error_callback2( - nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) { - cbs->error_callback2 = error_callback2; -} - -void nghttp2_session_callbacks_set_rand_callback( - nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) { - cbs->rand_callback = rand_callback; -} diff --git a/vendor/nghttp2/lib/nghttp2_callbacks.h b/vendor/nghttp2/lib/nghttp2_callbacks.h deleted file mode 100644 index ad515970c..000000000 --- a/vendor/nghttp2/lib/nghttp2_callbacks.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_CALLBACKS_H -#define NGHTTP2_CALLBACKS_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -/* - * Callback functions. - */ -struct nghttp2_session_callbacks { - /** - * Deprecated. Use send_callback2 instead. Callback function - * invoked when the session wants to send data to the remote peer. - * This callback is not necessary if the application uses solely - * `nghttp2_session_mem_send()` to serialize data to transmit. - */ - nghttp2_send_callback send_callback; - /** - * Callback function invoked when the session wants to send data to - * the remote peer. This callback is not necessary if the - * application uses solely `nghttp2_session_mem_send2()` to - * serialize data to transmit. - */ - nghttp2_send_callback2 send_callback2; - /** - * Deprecated. Use recv_callback2 instead. Callback function - * invoked when the session wants to receive data from the remote - * peer. This callback is not necessary if the application uses - * solely `nghttp2_session_mem_recv()` to process received data. - */ - nghttp2_recv_callback recv_callback; - /** - * Callback function invoked when the session wants to receive data - * from the remote peer. This callback is not necessary if the - * application uses solely `nghttp2_session_mem_recv2()` to process - * received data. - */ - nghttp2_recv_callback2 recv_callback2; - /** - * Callback function invoked by `nghttp2_session_recv()` when a - * frame is received. - */ - nghttp2_on_frame_recv_callback on_frame_recv_callback; - /** - * Callback function invoked by `nghttp2_session_recv()` when an - * invalid non-DATA frame is received. - */ - nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback; - /** - * Callback function invoked when a chunk of data in DATA frame is - * received. - */ - nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback; - /** - * Callback function invoked before a non-DATA frame is sent. - */ - nghttp2_before_frame_send_callback before_frame_send_callback; - /** - * Callback function invoked after a frame is sent. - */ - nghttp2_on_frame_send_callback on_frame_send_callback; - /** - * The callback function invoked when a non-DATA frame is not sent - * because of an error. - */ - nghttp2_on_frame_not_send_callback on_frame_not_send_callback; - /** - * Callback function invoked when the stream is closed. - */ - nghttp2_on_stream_close_callback on_stream_close_callback; - /** - * Callback function invoked when the reception of header block in - * HEADERS or PUSH_PROMISE is started. - */ - nghttp2_on_begin_headers_callback on_begin_headers_callback; - /** - * Callback function invoked when a header name/value pair is - * received. - */ - nghttp2_on_header_callback on_header_callback; - nghttp2_on_header_callback2 on_header_callback2; - /** - * Callback function invoked when a invalid header name/value pair - * is received which is silently ignored if these callbacks are not - * set. - */ - nghttp2_on_invalid_header_callback on_invalid_header_callback; - nghttp2_on_invalid_header_callback2 on_invalid_header_callback2; - /** - * Deprecated. Use select_padding_callback2 instead. Callback - * function invoked when the library asks application how many - * padding bytes are required for the transmission of the given - * frame. - */ - nghttp2_select_padding_callback select_padding_callback; - /** - * Callback function invoked when the library asks application how - * many padding bytes are required for the transmission of the given - * frame. - */ - nghttp2_select_padding_callback2 select_padding_callback2; - /** - * Deprecated. Use read_length_callback2 instead. The callback - * function used to determine the length allowed in - * `nghttp2_data_source_read_callback()` - */ - nghttp2_data_source_read_length_callback read_length_callback; - /** - * The callback function used to determine the length allowed in - * `nghttp2_data_source_read_callback2()` - */ - nghttp2_data_source_read_length_callback2 read_length_callback2; - /** - * Sets callback function invoked when a frame header is received. - */ - nghttp2_on_begin_frame_callback on_begin_frame_callback; - nghttp2_send_data_callback send_data_callback; - /** - * Deprecated. Use pack_extension_callback2 instead. - */ - nghttp2_pack_extension_callback pack_extension_callback; - nghttp2_pack_extension_callback2 pack_extension_callback2; - nghttp2_unpack_extension_callback unpack_extension_callback; - nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback; - nghttp2_error_callback error_callback; - nghttp2_error_callback2 error_callback2; - nghttp2_rand_callback rand_callback; -}; - -#endif /* NGHTTP2_CALLBACKS_H */ diff --git a/vendor/nghttp2/lib/nghttp2_debug.c b/vendor/nghttp2/lib/nghttp2_debug.c deleted file mode 100644 index 09dd2b285..000000000 --- a/vendor/nghttp2/lib/nghttp2_debug.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2016 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_debug.h" - -#include - -#ifdef DEBUGBUILD - -static void nghttp2_default_debug_vfprintf_callback(const char *fmt, - va_list args) { - vfprintf(stderr, fmt, args); -} - -static nghttp2_debug_vprintf_callback static_debug_vprintf_callback = - nghttp2_default_debug_vfprintf_callback; - -void nghttp2_debug_vprintf(const char *format, ...) { - if (static_debug_vprintf_callback) { - va_list args; - va_start(args, format); - static_debug_vprintf_callback(format, args); - va_end(args); - } -} - -void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback) { - static_debug_vprintf_callback = debug_vprintf_callback; -} - -#else /* !DEBUGBUILD */ - -void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback) { - (void)debug_vprintf_callback; -} - -#endif /* !DEBUGBUILD */ diff --git a/vendor/nghttp2/lib/nghttp2_debug.h b/vendor/nghttp2/lib/nghttp2_debug.h deleted file mode 100644 index cbb4dd575..000000000 --- a/vendor/nghttp2/lib/nghttp2_debug.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2016 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_DEBUG_H -#define NGHTTP2_DEBUG_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -#ifdef DEBUGBUILD -# define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__) -void nghttp2_debug_vprintf(const char *format, ...); -#else -# define DEBUGF(...) \ - do { \ - } while (0) -#endif - -#endif /* NGHTTP2_DEBUG_H */ diff --git a/vendor/nghttp2/lib/nghttp2_extpri.c b/vendor/nghttp2/lib/nghttp2_extpri.c deleted file mode 100644 index ba0263e7c..000000000 --- a/vendor/nghttp2/lib/nghttp2_extpri.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2022 nghttp3 contributors - * Copyright (c) 2022 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_extpri.h" -#include "nghttp2_http.h" - -uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri) { - return (uint8_t)((uint32_t)extpri->inc << 7 | extpri->urgency); -} - -void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri) { - extpri->urgency = nghttp2_extpri_uint8_urgency(u8extpri); - extpri->inc = nghttp2_extpri_uint8_inc(u8extpri); -} - -int nghttp2_extpri_parse_priority(nghttp2_extpri *extpri, const uint8_t *value, - size_t len) { - return nghttp2_http_parse_priority(extpri, value, len); -} diff --git a/vendor/nghttp2/lib/nghttp2_extpri.h b/vendor/nghttp2/lib/nghttp2_extpri.h deleted file mode 100644 index db9119720..000000000 --- a/vendor/nghttp2/lib/nghttp2_extpri.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2022 nghttp3 contributors - * Copyright (c) 2022 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_EXTPRI_H -#define NGHTTP2_EXTPRI_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -/* - * NGHTTP2_EXTPRI_INC_MASK is a bit mask to retrieve incremental bit - * from a value produced by nghttp2_extpri_to_uint8. - */ -#define NGHTTP2_EXTPRI_INC_MASK (1 << 7) - -/* - * nghttp2_extpri_to_uint8 encodes |pri| into uint8_t variable. - */ -uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri); - -/* - * nghttp2_extpri_from_uint8 decodes |u8extpri|, which is produced by - * nghttp2_extpri_to_uint8, intto |extpri|. - */ -void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri); - -/* - * nghttp2_extpri_uint8_urgency extracts urgency from |PRI| which is - * supposed to be constructed by nghttp2_extpri_to_uint8. - */ -#define nghttp2_extpri_uint8_urgency(PRI) \ - ((uint32_t)((PRI) & ~NGHTTP2_EXTPRI_INC_MASK)) - -/* - * nghttp2_extpri_uint8_inc extracts inc from |PRI| which is supposed to - * be constructed by nghttp2_extpri_to_uint8. - */ -#define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0) - -#endif /* NGHTTP2_EXTPRI_H */ diff --git a/vendor/nghttp2/lib/nghttp2_frame.c b/vendor/nghttp2/lib/nghttp2_frame.c deleted file mode 100644 index edc2aaaae..000000000 --- a/vendor/nghttp2/lib/nghttp2_frame.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_frame.h" - -#include -#include -#include -#include - -#include "nghttp2_helper.h" -#include "nghttp2_net.h" -#include "nghttp2_priority_spec.h" -#include "nghttp2_debug.h" - -void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd) { - nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8)); - buf[3] = hd->type; - buf[4] = hd->flags; - nghttp2_put_uint32be(&buf[5], (uint32_t)hd->stream_id); - /* ignore hd->reserved for now */ -} - -void nghttp2_frame_unpack_frame_hd(nghttp2_frame_hd *hd, const uint8_t *buf) { - hd->length = nghttp2_get_uint32(&buf[0]) >> 8; - hd->type = buf[3]; - hd->flags = buf[4]; - hd->stream_id = nghttp2_get_uint32(&buf[5]) & NGHTTP2_STREAM_ID_MASK; - hd->reserved = 0; -} - -void nghttp2_frame_hd_init(nghttp2_frame_hd *hd, size_t length, uint8_t type, - uint8_t flags, int32_t stream_id) { - hd->length = length; - hd->type = type; - hd->flags = flags; - hd->stream_id = stream_id; - hd->reserved = 0; -} - -void nghttp2_frame_headers_init(nghttp2_headers *frame, uint8_t flags, - int32_t stream_id, nghttp2_headers_category cat, - const nghttp2_priority_spec *pri_spec, - nghttp2_nv *nva, size_t nvlen) { - nghttp2_frame_hd_init(&frame->hd, 0, NGHTTP2_HEADERS, flags, stream_id); - frame->padlen = 0; - frame->nva = nva; - frame->nvlen = nvlen; - frame->cat = cat; - - if (pri_spec) { - frame->pri_spec = *pri_spec; - } else { - nghttp2_priority_spec_default_init(&frame->pri_spec); - } -} - -void nghttp2_frame_headers_free(nghttp2_headers *frame, nghttp2_mem *mem) { - nghttp2_nv_array_del(frame->nva, mem); -} - -void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id, - const nghttp2_priority_spec *pri_spec) { - nghttp2_frame_hd_init(&frame->hd, NGHTTP2_PRIORITY_SPECLEN, NGHTTP2_PRIORITY, - NGHTTP2_FLAG_NONE, stream_id); - frame->pri_spec = *pri_spec; -} - -void nghttp2_frame_priority_free(nghttp2_priority *frame) { (void)frame; } - -void nghttp2_frame_rst_stream_init(nghttp2_rst_stream *frame, int32_t stream_id, - uint32_t error_code) { - nghttp2_frame_hd_init(&frame->hd, 4, NGHTTP2_RST_STREAM, NGHTTP2_FLAG_NONE, - stream_id); - frame->error_code = error_code; -} - -void nghttp2_frame_rst_stream_free(nghttp2_rst_stream *frame) { (void)frame; } - -void nghttp2_frame_settings_init(nghttp2_settings *frame, uint8_t flags, - nghttp2_settings_entry *iv, size_t niv) { - nghttp2_frame_hd_init(&frame->hd, niv * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH, - NGHTTP2_SETTINGS, flags, 0); - frame->niv = niv; - frame->iv = iv; -} - -void nghttp2_frame_settings_free(nghttp2_settings *frame, nghttp2_mem *mem) { - nghttp2_mem_free(mem, frame->iv); -} - -void nghttp2_frame_push_promise_init(nghttp2_push_promise *frame, uint8_t flags, - int32_t stream_id, - int32_t promised_stream_id, - nghttp2_nv *nva, size_t nvlen) { - nghttp2_frame_hd_init(&frame->hd, 0, NGHTTP2_PUSH_PROMISE, flags, stream_id); - frame->padlen = 0; - frame->nva = nva; - frame->nvlen = nvlen; - frame->promised_stream_id = promised_stream_id; - frame->reserved = 0; -} - -void nghttp2_frame_push_promise_free(nghttp2_push_promise *frame, - nghttp2_mem *mem) { - nghttp2_nv_array_del(frame->nva, mem); -} - -void nghttp2_frame_ping_init(nghttp2_ping *frame, uint8_t flags, - const uint8_t *opaque_data) { - nghttp2_frame_hd_init(&frame->hd, 8, NGHTTP2_PING, flags, 0); - if (opaque_data) { - memcpy(frame->opaque_data, opaque_data, sizeof(frame->opaque_data)); - } else { - memset(frame->opaque_data, 0, sizeof(frame->opaque_data)); - } -} - -void nghttp2_frame_ping_free(nghttp2_ping *frame) { (void)frame; } - -void nghttp2_frame_goaway_init(nghttp2_goaway *frame, int32_t last_stream_id, - uint32_t error_code, uint8_t *opaque_data, - size_t opaque_data_len) { - nghttp2_frame_hd_init(&frame->hd, 8 + opaque_data_len, NGHTTP2_GOAWAY, - NGHTTP2_FLAG_NONE, 0); - frame->last_stream_id = last_stream_id; - frame->error_code = error_code; - frame->opaque_data = opaque_data; - frame->opaque_data_len = opaque_data_len; - frame->reserved = 0; -} - -void nghttp2_frame_goaway_free(nghttp2_goaway *frame, nghttp2_mem *mem) { - nghttp2_mem_free(mem, frame->opaque_data); -} - -void nghttp2_frame_window_update_init(nghttp2_window_update *frame, - uint8_t flags, int32_t stream_id, - int32_t window_size_increment) { - nghttp2_frame_hd_init(&frame->hd, 4, NGHTTP2_WINDOW_UPDATE, flags, stream_id); - frame->window_size_increment = window_size_increment; - frame->reserved = 0; -} - -void nghttp2_frame_window_update_free(nghttp2_window_update *frame) { - (void)frame; -} - -size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen) { - /* We have iframe->padlen == 0, but iframe->frame.hd.flags may have - NGHTTP2_FLAG_PADDED set. This happens when receiving - CONTINUATION frame, since we don't reset flags after HEADERS was - received. */ - if (padlen == 0) { - return 0; - } - return padlen - ((frame->hd.flags & NGHTTP2_FLAG_PADDED) > 0); -} - -void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags, - int32_t stream_id) { - /* At this moment, the length of DATA frame is unknown */ - nghttp2_frame_hd_init(&frame->hd, 0, NGHTTP2_DATA, flags, stream_id); - frame->padlen = 0; -} - -void nghttp2_frame_data_free(nghttp2_data *frame) { (void)frame; } - -void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type, - uint8_t flags, int32_t stream_id, - void *payload) { - nghttp2_frame_hd_init(&frame->hd, 0, type, flags, stream_id); - frame->payload = payload; -} - -void nghttp2_frame_extension_free(nghttp2_extension *frame) { (void)frame; } - -void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id, - uint8_t *origin, size_t origin_len, - uint8_t *field_value, size_t field_value_len) { - nghttp2_ext_altsvc *altsvc; - - nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len, - NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id); - - altsvc = frame->payload; - altsvc->origin = origin; - altsvc->origin_len = origin_len; - altsvc->field_value = field_value; - altsvc->field_value_len = field_value_len; -} - -void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) { - nghttp2_ext_altsvc *altsvc; - - altsvc = frame->payload; - if (altsvc == NULL) { - return; - } - /* We use the same buffer for altsvc->origin and - altsvc->field_value. */ - nghttp2_mem_free(mem, altsvc->origin); -} - -void nghttp2_frame_origin_init(nghttp2_extension *frame, - nghttp2_origin_entry *ov, size_t nov) { - nghttp2_ext_origin *origin; - size_t payloadlen = 0; - size_t i; - - for (i = 0; i < nov; ++i) { - payloadlen += 2 + ov[i].origin_len; - } - - nghttp2_frame_hd_init(&frame->hd, payloadlen, NGHTTP2_ORIGIN, - NGHTTP2_FLAG_NONE, 0); - - origin = frame->payload; - origin->ov = ov; - origin->nov = nov; -} - -void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem) { - nghttp2_ext_origin *origin; - - origin = frame->payload; - if (origin == NULL) { - return; - } - /* We use the same buffer for all resources pointed by the field of - origin directly or indirectly. */ - nghttp2_mem_free(mem, origin->ov); -} - -void nghttp2_frame_priority_update_init(nghttp2_extension *frame, - int32_t stream_id, uint8_t *field_value, - size_t field_value_len) { - nghttp2_ext_priority_update *priority_update; - - nghttp2_frame_hd_init(&frame->hd, 4 + field_value_len, - NGHTTP2_PRIORITY_UPDATE, NGHTTP2_FLAG_NONE, 0); - - priority_update = frame->payload; - priority_update->stream_id = stream_id; - priority_update->field_value = field_value; - priority_update->field_value_len = field_value_len; -} - -void nghttp2_frame_priority_update_free(nghttp2_extension *frame, - nghttp2_mem *mem) { - nghttp2_ext_priority_update *priority_update; - - priority_update = frame->payload; - if (priority_update == NULL) { - return; - } - nghttp2_mem_free(mem, priority_update->field_value); -} - -size_t nghttp2_frame_priority_len(uint8_t flags) { - if (flags & NGHTTP2_FLAG_PRIORITY) { - return NGHTTP2_PRIORITY_SPECLEN; - } - - return 0; -} - -size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame) { - return nghttp2_frame_priority_len(frame->hd.flags); -} - -/* - * Call this function after payload was serialized, but not before - * changing buf->pos and serializing frame header. - * - * This function assumes bufs->cur points to the last buf chain of the - * frame(s). - * - * This function serializes frame header for HEADERS/PUSH_PROMISE and - * handles their successive CONTINUATION frames. - * - * We don't process any padding here. - */ -static int frame_pack_headers_shared(nghttp2_bufs *bufs, - nghttp2_frame_hd *frame_hd) { - nghttp2_buf *buf; - nghttp2_buf_chain *ci, *ce; - nghttp2_frame_hd hd; - - buf = &bufs->head->buf; - - hd = *frame_hd; - hd.length = nghttp2_buf_len(buf); - - DEBUGF("send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n", hd.length); - - /* We have multiple frame buffers, which means one or more - CONTINUATION frame is involved. Remove END_HEADERS flag from the - first frame. */ - if (bufs->head != bufs->cur) { - hd.flags = (uint8_t)(hd.flags & ~NGHTTP2_FLAG_END_HEADERS); - } - - buf->pos -= NGHTTP2_FRAME_HDLEN; - nghttp2_frame_pack_frame_hd(buf->pos, &hd); - - if (bufs->head != bufs->cur) { - /* 2nd and later frames are CONTINUATION frames. */ - hd.type = NGHTTP2_CONTINUATION; - /* We don't have no flags except for last CONTINUATION */ - hd.flags = NGHTTP2_FLAG_NONE; - - ce = bufs->cur; - - for (ci = bufs->head->next; ci != ce; ci = ci->next) { - buf = &ci->buf; - - hd.length = nghttp2_buf_len(buf); - - DEBUGF("send: int CONTINUATION, payloadlen=%zu\n", hd.length); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - nghttp2_frame_pack_frame_hd(buf->pos, &hd); - } - - buf = &ci->buf; - hd.length = nghttp2_buf_len(buf); - /* Set END_HEADERS flag for last CONTINUATION */ - hd.flags = NGHTTP2_FLAG_END_HEADERS; - - DEBUGF("send: last CONTINUATION, payloadlen=%zu\n", hd.length); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - nghttp2_frame_pack_frame_hd(buf->pos, &hd); - } - - return 0; -} - -int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame, - nghttp2_hd_deflater *deflater) { - size_t nv_offset; - int rv; - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - nv_offset = nghttp2_frame_headers_payload_nv_offset(frame); - - buf = &bufs->cur->buf; - - buf->pos += nv_offset; - buf->last = buf->pos; - - /* This call will adjust buf->last to the correct position */ - rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, frame->nva, frame->nvlen); - - if (rv == NGHTTP2_ERR_BUFFER_ERROR) { - rv = NGHTTP2_ERR_HEADER_COMP; - } - - buf->pos -= nv_offset; - - if (rv != 0) { - return rv; - } - - if (frame->hd.flags & NGHTTP2_FLAG_PRIORITY) { - nghttp2_frame_pack_priority_spec(buf->pos, &frame->pri_spec); - } - - frame->padlen = 0; - frame->hd.length = nghttp2_bufs_len(bufs); - - return frame_pack_headers_shared(bufs, &frame->hd); -} - -void nghttp2_frame_pack_priority_spec(uint8_t *buf, - const nghttp2_priority_spec *pri_spec) { - nghttp2_put_uint32be(buf, (uint32_t)pri_spec->stream_id); - if (pri_spec->exclusive) { - buf[0] |= 0x80; - } - buf[4] = (uint8_t)(pri_spec->weight - 1); -} - -void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec, - const uint8_t *payload) { - int32_t dep_stream_id; - uint8_t exclusive; - int32_t weight; - - dep_stream_id = nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; - exclusive = (payload[0] & 0x80) > 0; - weight = payload[4] + 1; - - nghttp2_priority_spec_init(pri_spec, dep_stream_id, weight, exclusive); -} - -void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame, - const uint8_t *payload) { - if (frame->hd.flags & NGHTTP2_FLAG_PRIORITY) { - nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload); - } else { - nghttp2_priority_spec_default_init(&frame->pri_spec); - } - - frame->nva = NULL; - frame->nvlen = 0; -} - -void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) { - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - buf = &bufs->head->buf; - - assert(nghttp2_buf_avail(buf) >= NGHTTP2_PRIORITY_SPECLEN); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - nghttp2_frame_pack_priority_spec(buf->last, &frame->pri_spec); - - buf->last += NGHTTP2_PRIORITY_SPECLEN; -} - -void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame, - const uint8_t *payload) { - nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload); -} - -void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs, - nghttp2_rst_stream *frame) { - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - buf = &bufs->head->buf; - - assert(nghttp2_buf_avail(buf) >= 4); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - nghttp2_put_uint32be(buf->last, frame->error_code); - buf->last += 4; -} - -void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame, - const uint8_t *payload) { - frame->error_code = nghttp2_get_uint32(payload); -} - -int nghttp2_frame_pack_settings(nghttp2_bufs *bufs, nghttp2_settings *frame) { - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - buf = &bufs->head->buf; - - if (nghttp2_buf_avail(buf) < frame->hd.length) { - return NGHTTP2_ERR_FRAME_SIZE_ERROR; - } - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - buf->last += - nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv); - - return 0; -} - -size_t nghttp2_frame_pack_settings_payload(uint8_t *buf, - const nghttp2_settings_entry *iv, - size_t niv) { - size_t i; - for (i = 0; i < niv; ++i, buf += NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) { - nghttp2_put_uint16be(buf, (uint16_t)iv[i].settings_id); - nghttp2_put_uint32be(buf + 2, iv[i].value); - } - return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv; -} - -void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame, - nghttp2_settings_entry *iv, - size_t niv) { - frame->iv = iv; - frame->niv = niv; -} - -void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv, - const uint8_t *payload) { - iv->settings_id = nghttp2_get_uint16(&payload[0]); - iv->value = nghttp2_get_uint32(&payload[2]); -} - -int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr, - size_t *niv_ptr, - const uint8_t *payload, - size_t payloadlen, - nghttp2_mem *mem) { - size_t i; - - *niv_ptr = payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH; - - if (*niv_ptr == 0) { - *iv_ptr = NULL; - - return 0; - } - - *iv_ptr = - nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry)); - - if (*iv_ptr == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - for (i = 0; i < *niv_ptr; ++i) { - size_t off = i * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH; - nghttp2_frame_unpack_settings_entry(&(*iv_ptr)[i], &payload[off]); - } - - return 0; -} - -int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs, - nghttp2_push_promise *frame, - nghttp2_hd_deflater *deflater) { - size_t nv_offset = 4; - int rv; - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - buf = &bufs->cur->buf; - - buf->pos += nv_offset; - buf->last = buf->pos; - - /* This call will adjust buf->last to the correct position */ - rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, frame->nva, frame->nvlen); - - if (rv == NGHTTP2_ERR_BUFFER_ERROR) { - rv = NGHTTP2_ERR_HEADER_COMP; - } - - buf->pos -= nv_offset; - - if (rv != 0) { - return rv; - } - - nghttp2_put_uint32be(buf->pos, (uint32_t)frame->promised_stream_id); - - frame->padlen = 0; - frame->hd.length = nghttp2_bufs_len(bufs); - - return frame_pack_headers_shared(bufs, &frame->hd); -} - -void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame, - const uint8_t *payload) { - frame->promised_stream_id = - nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; - frame->nva = NULL; - frame->nvlen = 0; -} - -void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) { - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - buf = &bufs->head->buf; - - assert(nghttp2_buf_avail(buf) >= 8); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - buf->last = - nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data)); -} - -void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame, - const uint8_t *payload) { - memcpy(frame->opaque_data, payload, sizeof(frame->opaque_data)); -} - -int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame) { - int rv; - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - buf = &bufs->head->buf; - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - nghttp2_put_uint32be(buf->last, (uint32_t)frame->last_stream_id); - buf->last += 4; - - nghttp2_put_uint32be(buf->last, frame->error_code); - buf->last += 4; - - rv = nghttp2_bufs_add(bufs, frame->opaque_data, frame->opaque_data_len); - - if (rv == NGHTTP2_ERR_BUFFER_ERROR) { - return NGHTTP2_ERR_FRAME_SIZE_ERROR; - } - - if (rv != 0) { - return rv; - } - - return 0; -} - -void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame, - const uint8_t *payload, - uint8_t *var_gift_payload, - size_t var_gift_payloadlen) { - frame->last_stream_id = nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; - frame->error_code = nghttp2_get_uint32(payload + 4); - - frame->opaque_data = var_gift_payload; - frame->opaque_data_len = var_gift_payloadlen; -} - -int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame, - const uint8_t *payload, - size_t payloadlen, nghttp2_mem *mem) { - uint8_t *var_gift_payload; - size_t var_gift_payloadlen; - - if (payloadlen > 8) { - var_gift_payloadlen = payloadlen - 8; - } else { - var_gift_payloadlen = 0; - } - - if (!var_gift_payloadlen) { - var_gift_payload = NULL; - } else { - var_gift_payload = nghttp2_mem_malloc(mem, var_gift_payloadlen); - - if (var_gift_payload == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - memcpy(var_gift_payload, payload + 8, var_gift_payloadlen); - } - - nghttp2_frame_unpack_goaway_payload(frame, payload, var_gift_payload, - var_gift_payloadlen); - - return 0; -} - -void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs, - nghttp2_window_update *frame) { - nghttp2_buf *buf; - - assert(bufs->head == bufs->cur); - - buf = &bufs->head->buf; - - assert(nghttp2_buf_avail(buf) >= 4); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - nghttp2_put_uint32be(buf->last, (uint32_t)frame->window_size_increment); - buf->last += 4; -} - -void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame, - const uint8_t *payload) { - frame->window_size_increment = - nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK; -} - -void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) { - int rv; - nghttp2_buf *buf; - nghttp2_ext_altsvc *altsvc; - - /* This is required with --disable-assert. */ - (void)rv; - - altsvc = frame->payload; - - buf = &bufs->head->buf; - - assert(nghttp2_buf_avail(buf) >= - 2 + altsvc->origin_len + altsvc->field_value_len); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - nghttp2_put_uint16be(buf->last, (uint16_t)altsvc->origin_len); - buf->last += 2; - - rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len); - - assert(rv == 0); - - rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len); - - assert(rv == 0); -} - -void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame, - size_t origin_len, uint8_t *payload, - size_t payloadlen) { - nghttp2_ext_altsvc *altsvc; - uint8_t *p; - - altsvc = frame->payload; - p = payload; - - altsvc->origin = p; - - p += origin_len; - - altsvc->origin_len = origin_len; - - altsvc->field_value = p; - altsvc->field_value_len = (size_t)(payload + payloadlen - p); -} - -int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame, - const uint8_t *payload, - size_t payloadlen, nghttp2_mem *mem) { - uint8_t *buf; - size_t origin_len; - - if (payloadlen < 2) { - return NGHTTP2_FRAME_SIZE_ERROR; - } - - origin_len = nghttp2_get_uint16(payload); - - buf = nghttp2_mem_malloc(mem, payloadlen - 2); - if (!buf) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_cpymem(buf, payload + 2, payloadlen - 2); - - nghttp2_frame_unpack_altsvc_payload(frame, origin_len, buf, payloadlen - 2); - - return 0; -} - -int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *frame) { - nghttp2_buf *buf; - nghttp2_ext_origin *origin; - nghttp2_origin_entry *orig; - size_t i; - - origin = frame->payload; - - buf = &bufs->head->buf; - - if (nghttp2_buf_avail(buf) < frame->hd.length) { - return NGHTTP2_ERR_FRAME_SIZE_ERROR; - } - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - for (i = 0; i < origin->nov; ++i) { - orig = &origin->ov[i]; - nghttp2_put_uint16be(buf->last, (uint16_t)orig->origin_len); - buf->last += 2; - buf->last = nghttp2_cpymem(buf->last, orig->origin, orig->origin_len); - } - - assert(nghttp2_buf_len(buf) == NGHTTP2_FRAME_HDLEN + frame->hd.length); - - return 0; -} - -int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame, - const uint8_t *payload, - size_t payloadlen, nghttp2_mem *mem) { - nghttp2_ext_origin *origin; - const uint8_t *p, *end; - uint8_t *dst; - size_t originlen; - nghttp2_origin_entry *ov; - size_t nov = 0; - size_t len = 0; - - origin = frame->payload; - p = end = payload; - if (payloadlen) { - end += payloadlen; - } - - for (; p != end;) { - if (end - p < 2) { - return NGHTTP2_ERR_FRAME_SIZE_ERROR; - } - originlen = nghttp2_get_uint16(p); - p += 2; - if (originlen == 0) { - continue; - } - if (originlen > (size_t)(end - p)) { - return NGHTTP2_ERR_FRAME_SIZE_ERROR; - } - p += originlen; - /* 1 for terminal NULL */ - len += originlen + 1; - ++nov; - } - - if (nov == 0) { - origin->ov = NULL; - origin->nov = 0; - - return 0; - } - - len += nov * sizeof(nghttp2_origin_entry); - - ov = nghttp2_mem_malloc(mem, len); - if (ov == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - origin->ov = ov; - origin->nov = nov; - - dst = (uint8_t *)ov + nov * sizeof(nghttp2_origin_entry); - p = payload; - - for (; p != end;) { - originlen = nghttp2_get_uint16(p); - p += 2; - if (originlen == 0) { - continue; - } - ov->origin = dst; - ov->origin_len = originlen; - dst = nghttp2_cpymem(dst, p, originlen); - *dst++ = '\0'; - p += originlen; - ++ov; - } - - return 0; -} - -void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs, - nghttp2_extension *frame) { - int rv; - nghttp2_buf *buf; - nghttp2_ext_priority_update *priority_update; - - /* This is required with --disable-assert. */ - (void)rv; - - priority_update = frame->payload; - - buf = &bufs->head->buf; - - assert(nghttp2_buf_avail(buf) >= 4 + priority_update->field_value_len); - - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - nghttp2_put_uint32be(buf->last, (uint32_t)priority_update->stream_id); - buf->last += 4; - - rv = nghttp2_bufs_add(bufs, priority_update->field_value, - priority_update->field_value_len); - - assert(rv == 0); -} - -void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame, - uint8_t *payload, - size_t payloadlen) { - nghttp2_ext_priority_update *priority_update; - - assert(payloadlen >= 4); - - priority_update = frame->payload; - - priority_update->stream_id = - nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; - - if (payloadlen > 4) { - priority_update->field_value = payload + 4; - priority_update->field_value_len = payloadlen - 4; - } else { - priority_update->field_value = NULL; - priority_update->field_value_len = 0; - } -} - -nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv, - size_t niv, nghttp2_mem *mem) { - nghttp2_settings_entry *iv_copy; - size_t len = niv * sizeof(nghttp2_settings_entry); - - if (len == 0) { - return NULL; - } - - iv_copy = nghttp2_mem_malloc(mem, len); - - if (iv_copy == NULL) { - return NULL; - } - - memcpy(iv_copy, iv, len); - - return iv_copy; -} - -int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b) { - if (a->namelen != b->namelen || a->valuelen != b->valuelen) { - return 0; - } - - if (a->name == NULL || b->name == NULL) { - assert(a->namelen == 0); - assert(b->namelen == 0); - } else if (memcmp(a->name, b->name, a->namelen) != 0) { - return 0; - } - - if (a->value == NULL || b->value == NULL) { - assert(a->valuelen == 0); - assert(b->valuelen == 0); - } else if (memcmp(a->value, b->value, a->valuelen) != 0) { - return 0; - } - - return 1; -} - -void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem) { - nghttp2_mem_free(mem, nva); -} - -static int bytes_compar(const uint8_t *a, size_t alen, const uint8_t *b, - size_t blen) { - int rv; - - if (alen == blen) { - return memcmp(a, b, alen); - } - - if (alen < blen) { - rv = memcmp(a, b, alen); - - if (rv == 0) { - return -1; - } - - return rv; - } - - rv = memcmp(a, b, blen); - - if (rv == 0) { - return 1; - } - - return rv; -} - -int nghttp2_nv_compare_name(const nghttp2_nv *lhs, const nghttp2_nv *rhs) { - return bytes_compar(lhs->name, lhs->namelen, rhs->name, rhs->namelen); -} - -static int nv_compar(const void *lhs, const void *rhs) { - const nghttp2_nv *a = (const nghttp2_nv *)lhs; - const nghttp2_nv *b = (const nghttp2_nv *)rhs; - int rv; - - rv = bytes_compar(a->name, a->namelen, b->name, b->namelen); - - if (rv == 0) { - return bytes_compar(a->value, a->valuelen, b->value, b->valuelen); - } - - return rv; -} - -void nghttp2_nv_array_sort(nghttp2_nv *nva, size_t nvlen) { - qsort(nva, nvlen, sizeof(nghttp2_nv), nv_compar); -} - -int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva, - size_t nvlen, nghttp2_mem *mem) { - size_t i; - uint8_t *data = NULL; - size_t buflen = 0; - nghttp2_nv *p; - - if (nvlen == 0) { - *nva_ptr = NULL; - - return 0; - } - - for (i = 0; i < nvlen; ++i) { - /* + 1 for null-termination */ - if ((nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_NAME) == 0) { - buflen += nva[i].namelen + 1; - } - if ((nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_VALUE) == 0) { - buflen += nva[i].valuelen + 1; - } - } - - buflen += sizeof(nghttp2_nv) * nvlen; - - *nva_ptr = nghttp2_mem_malloc(mem, buflen); - - if (*nva_ptr == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - p = *nva_ptr; - data = (uint8_t *)(*nva_ptr) + sizeof(nghttp2_nv) * nvlen; - - for (i = 0; i < nvlen; ++i) { - p->flags = nva[i].flags; - - if (nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_NAME) { - p->name = nva[i].name; - p->namelen = nva[i].namelen; - } else { - if (nva[i].namelen) { - memcpy(data, nva[i].name, nva[i].namelen); - } - p->name = data; - p->namelen = nva[i].namelen; - data[p->namelen] = '\0'; - nghttp2_downcase(p->name, p->namelen); - data += nva[i].namelen + 1; - } - - if (nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_VALUE) { - p->value = nva[i].value; - p->valuelen = nva[i].valuelen; - } else { - if (nva[i].valuelen) { - memcpy(data, nva[i].value, nva[i].valuelen); - } - p->value = data; - p->valuelen = nva[i].valuelen; - data[p->valuelen] = '\0'; - data += nva[i].valuelen + 1; - } - - ++p; - } - return 0; -} - -int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) { - size_t i; - for (i = 0; i < niv; ++i) { - switch (iv[i].settings_id) { - case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: - break; - case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: - break; - case NGHTTP2_SETTINGS_ENABLE_PUSH: - if (iv[i].value != 0 && iv[i].value != 1) { - return 0; - } - break; - case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - if (iv[i].value > (uint32_t)NGHTTP2_MAX_WINDOW_SIZE) { - return 0; - } - break; - case NGHTTP2_SETTINGS_MAX_FRAME_SIZE: - if (iv[i].value < NGHTTP2_MAX_FRAME_SIZE_MIN || - iv[i].value > NGHTTP2_MAX_FRAME_SIZE_MAX) { - return 0; - } - break; - case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: - break; - case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL: - if (iv[i].value != 0 && iv[i].value != 1) { - return 0; - } - break; - case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES: - if (iv[i].value != 0 && iv[i].value != 1) { - return 0; - } - break; - } - } - return 1; -} - -static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) { - size_t trail_padlen; - size_t newlen; - - DEBUGF("send: padlen=%zu, shift left 1 bytes\n", padlen); - - memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN); - - --buf->pos; - - buf->pos[4] |= NGHTTP2_FLAG_PADDED; - - newlen = (nghttp2_get_uint32(buf->pos) >> 8) + padlen; - nghttp2_put_uint32be(buf->pos, (uint32_t)((newlen << 8) + buf->pos[3])); - - if (framehd_only) { - return; - } - - trail_padlen = padlen - 1; - buf->pos[NGHTTP2_FRAME_HDLEN] = (uint8_t)trail_padlen; - - /* zero out padding */ - memset(buf->last, 0, trail_padlen); - /* extend buffers trail_padlen bytes, since we ate previous padlen - - trail_padlen byte(s) */ - buf->last += trail_padlen; -} - -void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, - size_t padlen, int framehd_only) { - nghttp2_buf *buf; - - if (padlen == 0) { - DEBUGF("send: padlen = 0, nothing to do\n"); - - return; - } - - /* - * We have arranged bufs like this: - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | |Frame header | Frame payload... : - * +-+-----------------+-------------------------------------------+ - * | |Frame header | Frame payload... : - * +-+-----------------+-------------------------------------------+ - * | |Frame header | Frame payload... : - * +-+-----------------+-------------------------------------------+ - * - * We arranged padding so that it is included in the first frame - * completely. For padded frame, we are going to adjust buf->pos of - * frame which includes padding and serialize (memmove) frame header - * in the correct position. Also extends buf->last to include - * padding. - */ - - buf = &bufs->head->buf; - - assert(nghttp2_buf_avail(buf) >= padlen - 1); - - frame_set_pad(buf, padlen, framehd_only); - - hd->length += padlen; - hd->flags |= NGHTTP2_FLAG_PADDED; - - DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen); -} diff --git a/vendor/nghttp2/lib/nghttp2_frame.h b/vendor/nghttp2/lib/nghttp2_frame.h deleted file mode 100644 index d58668806..000000000 --- a/vendor/nghttp2/lib/nghttp2_frame.h +++ /dev/null @@ -1,637 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_FRAME_H -#define NGHTTP2_FRAME_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include "nghttp2_hd.h" -#include "nghttp2_buf.h" - -#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1) -#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1) -#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1) -#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1) -#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1) - -/* The number of bytes of frame header. */ -#define NGHTTP2_FRAME_HDLEN 9 - -#define NGHTTP2_MAX_FRAME_SIZE_MAX ((1 << 24) - 1) -#define NGHTTP2_MAX_FRAME_SIZE_MIN (1 << 14) - -#define NGHTTP2_MAX_PAYLOADLEN 16384 -/* The one frame buffer length for transmission. We may use several of - them to support CONTINUATION. To account for Pad Length field, we - allocate extra 1 byte, which saves extra large memcopying. */ -#define NGHTTP2_FRAMEBUF_CHUNKLEN \ - (NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN) - -/* The default length of DATA frame payload. */ -#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN - -/* Maximum headers block size to send, calculated using - nghttp2_hd_deflate_bound(). This is the default value, and can be - overridden by nghttp2_option_set_max_send_header_block_length(). */ -#define NGHTTP2_MAX_HEADERSLEN 65536 - -/* The number of bytes for each SETTINGS entry */ -#define NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH 6 - -/* Length of priority related fields in HEADERS/PRIORITY frames */ -#define NGHTTP2_PRIORITY_SPECLEN 5 - -/* Maximum length of padding in bytes. */ -#define NGHTTP2_MAX_PADLEN 256 - -/* Union of extension frame payload */ -typedef union { - nghttp2_ext_altsvc altsvc; - nghttp2_ext_origin origin; - nghttp2_ext_priority_update priority_update; -} nghttp2_ext_frame_payload; - -void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd); - -void nghttp2_frame_unpack_frame_hd(nghttp2_frame_hd *hd, const uint8_t *buf); - -/** - * Initializes frame header |hd| with given parameters. Reserved bit - * is set to 0. - */ -void nghttp2_frame_hd_init(nghttp2_frame_hd *hd, size_t length, uint8_t type, - uint8_t flags, int32_t stream_id); - -/** - * Returns the number of priority field depending on the |flags|. If - * |flags| has neither NGHTTP2_FLAG_PRIORITY_GROUP nor - * NGHTTP2_FLAG_PRIORITY_DEPENDENCY set, return 0. - */ -size_t nghttp2_frame_priority_len(uint8_t flags); - -/** - * Packs the |pri_spec| in |buf|. This function assumes |buf| has - * enough space for serialization. - */ -void nghttp2_frame_pack_priority_spec(uint8_t *buf, - const nghttp2_priority_spec *pri_spec); - -/** - * Unpacks the priority specification from payload |payload| of length - * |payloadlen| to |pri_spec|. The |flags| is used to determine what - * kind of priority specification is in |payload|. This function - * assumes the |payload| contains whole priority specification. - */ -void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec, - const uint8_t *payload); - -/* - * Returns the offset from the HEADERS frame payload where the - * compressed header block starts. The frame payload does not include - * frame header. - */ -size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame); - -/* - * Packs HEADERS frame |frame| in wire format and store it in |bufs|. - * This function expands |bufs| as necessary to store frame. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - * - * frame->hd.length is assigned after length is determined during - * packing process. CONTINUATION frames are also serialized in this - * function. This function does not handle padding. - * - * This function returns 0 if it succeeds, or returns one of the - * following negative error codes: - * - * NGHTTP2_ERR_HEADER_COMP - * The deflate operation failed. - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame, - nghttp2_hd_deflater *deflater); - -/* - * Unpacks HEADERS frame byte sequence into |frame|. This function - * only unapcks bytes that come before name/value header block and - * after possible Pad Length field. - */ -void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame, - const uint8_t *payload); - -/* - * Packs PRIORITY frame |frame| in wire format and store it in - * |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - */ -void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame); - -/* - * Unpacks PRIORITY wire format into |frame|. - */ -void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame, - const uint8_t *payload); - -/* - * Packs RST_STREAM frame |frame| in wire frame format and store it in - * |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - */ -void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs, - nghttp2_rst_stream *frame); - -/* - * Unpacks RST_STREAM frame byte sequence into |frame|. - */ -void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame, - const uint8_t *payload); - -/* - * Packs SETTINGS frame |frame| in wire format and store it in - * |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - * - * This function returns 0 if it succeeds, or returns one of the - * following negative error codes: - * - * NGHTTP2_ERR_FRAME_SIZE_ERROR - * The length of the frame is too large. - */ -int nghttp2_frame_pack_settings(nghttp2_bufs *bufs, nghttp2_settings *frame); - -/* - * Packs the |iv|, which includes |niv| entries, in the |buf|, - * assuming the |buf| has at least 8 * |niv| bytes. - * - * Returns the number of bytes written into the |buf|. - */ -size_t nghttp2_frame_pack_settings_payload(uint8_t *buf, - const nghttp2_settings_entry *iv, - size_t niv); - -void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv, - const uint8_t *payload); - -/* - * Initializes payload of frame->settings. The |frame| takes - * ownership of |iv|. - */ -void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame, - nghttp2_settings_entry *iv, - size_t niv); - -/* - * Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are - * assigned to the |*niv_ptr|. This function allocates enough memory - * to store the result in |*iv_ptr|. The caller is responsible to free - * |*iv_ptr| after its use. - * - * This function returns 0 if it succeeds or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr, - size_t *niv_ptr, - const uint8_t *payload, - size_t payloadlen, nghttp2_mem *mem); - -/* - * Packs PUSH_PROMISE frame |frame| in wire format and store it in - * |bufs|. This function expands |bufs| as necessary to store - * frame. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - * - * frame->hd.length is assigned after length is determined during - * packing process. CONTINUATION frames are also serialized in this - * function. This function does not handle padding. - * - * This function returns 0 if it succeeds, or returns one of the - * following negative error codes: - * - * NGHTTP2_ERR_HEADER_COMP - * The deflate operation failed. - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs, - nghttp2_push_promise *frame, - nghttp2_hd_deflater *deflater); - -/* - * Unpacks PUSH_PROMISE frame byte sequence into |frame|. This - * function only unapcks bytes that come before name/value header - * block and after possible Pad Length field. - */ -void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame, - const uint8_t *payload); - -/* - * Packs PING frame |frame| in wire format and store it in - * |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - */ -void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame); - -/* - * Unpacks PING wire format into |frame|. - */ -void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame, - const uint8_t *payload); - -/* - * Packs GOAWAY frame |frame| in wire format and store it in |bufs|. - * This function expands |bufs| as necessary to store frame. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - * - * This function returns 0 if it succeeds or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FRAME_SIZE_ERROR - * The length of the frame is too large. - */ -int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame); - -/* - * Unpacks GOAWAY wire format into |frame|. The |payload| of length - * |payloadlen| contains first 8 bytes of payload. The - * |var_gift_payload| of length |var_gift_payloadlen| contains - * remaining payload and its buffer is gifted to the function and then - * |frame|. The |var_gift_payloadlen| must be freed by - * nghttp2_frame_goaway_free(). - */ -void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame, - const uint8_t *payload, - uint8_t *var_gift_payload, - size_t var_gift_payloadlen); - -/* - * Unpacks GOAWAY wire format into |frame|. This function only exists - * for unit test. After allocating buffer for debug data, this - * function internally calls nghttp2_frame_unpack_goaway_payload(). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame, - const uint8_t *payload, - size_t payloadlen, nghttp2_mem *mem); - -/* - * Packs WINDOW_UPDATE frame |frame| in wire frame format and store it - * in |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - */ -void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs, - nghttp2_window_update *frame); - -/* - * Unpacks WINDOW_UPDATE frame byte sequence into |frame|. - */ -void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame, - const uint8_t *payload); - -/* - * Packs ALTSVC frame |frame| in wire frame format and store it in - * |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - */ -void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext); - -/* - * Unpacks ALTSVC wire format into |frame|. The |payload| of - * |payloadlen| bytes contains frame payload. This function assumes - * that frame->payload points to the nghttp2_ext_altsvc object. - */ -void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame, - size_t origin_len, uint8_t *payload, - size_t payloadlen); - -/* - * Unpacks ALTSVC wire format into |frame|. This function only exists - * for unit test. After allocating buffer for fields, this function - * internally calls nghttp2_frame_unpack_altsvc_payload(). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FRAME_SIZE_ERROR - * The payload is too small. - */ -int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame, - const uint8_t *payload, - size_t payloadlen, nghttp2_mem *mem); - -/* - * Packs ORIGIN frame |frame| in wire frame format and store it in - * |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_FRAME_SIZE_ERROR - * The length of the frame is too large. - */ -int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *ext); - -/* - * Unpacks ORIGIN wire format into |frame|. The |payload| of length - * |payloadlen| contains the frame payload. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FRAME_SIZE_ERROR - * The payload is too small. - */ -int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame, - const uint8_t *payload, - size_t payloadlen, nghttp2_mem *mem); - -/* - * Packs PRIORITY_UPDATE frame |frame| in wire frame format and store - * it in |bufs|. - * - * The caller must make sure that nghttp2_bufs_reset(bufs) is called - * before calling this function. - */ -void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs, - nghttp2_extension *ext); - -/* - * Unpacks PRIORITY_UPDATE wire format into |frame|. The |payload| of - * |payloadlen| bytes contains frame payload. This function assumes - * that frame->payload points to the nghttp2_ext_priority_update - * object. - */ -void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame, - uint8_t *payload, - size_t payloadlen); - -/* - * Initializes HEADERS frame |frame| with given values. |frame| takes - * ownership of |nva|, so caller must not free it. If |stream_id| is - * not assigned yet, it must be -1. - */ -void nghttp2_frame_headers_init(nghttp2_headers *frame, uint8_t flags, - int32_t stream_id, nghttp2_headers_category cat, - const nghttp2_priority_spec *pri_spec, - nghttp2_nv *nva, size_t nvlen); - -void nghttp2_frame_headers_free(nghttp2_headers *frame, nghttp2_mem *mem); - -void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id, - const nghttp2_priority_spec *pri_spec); - -void nghttp2_frame_priority_free(nghttp2_priority *frame); - -void nghttp2_frame_rst_stream_init(nghttp2_rst_stream *frame, int32_t stream_id, - uint32_t error_code); - -void nghttp2_frame_rst_stream_free(nghttp2_rst_stream *frame); - -/* - * Initializes PUSH_PROMISE frame |frame| with given values. |frame| - * takes ownership of |nva|, so caller must not free it. - */ -void nghttp2_frame_push_promise_init(nghttp2_push_promise *frame, uint8_t flags, - int32_t stream_id, - int32_t promised_stream_id, - nghttp2_nv *nva, size_t nvlen); - -void nghttp2_frame_push_promise_free(nghttp2_push_promise *frame, - nghttp2_mem *mem); - -/* - * Initializes SETTINGS frame |frame| with given values. |frame| takes - * ownership of |iv|, so caller must not free it. The |flags| are - * bitwise-OR of one or more of nghttp2_settings_flag. - */ -void nghttp2_frame_settings_init(nghttp2_settings *frame, uint8_t flags, - nghttp2_settings_entry *iv, size_t niv); - -void nghttp2_frame_settings_free(nghttp2_settings *frame, nghttp2_mem *mem); - -/* - * Initializes PING frame |frame| with given values. If the - * |opqeue_data| is not NULL, it must point to 8 bytes memory region - * of data. The data pointed by |opaque_data| is copied. It can be - * NULL. In this case, 8 bytes NULL is used. - */ -void nghttp2_frame_ping_init(nghttp2_ping *frame, uint8_t flags, - const uint8_t *opque_data); - -void nghttp2_frame_ping_free(nghttp2_ping *frame); - -/* - * Initializes GOAWAY frame |frame| with given values. On success, - * this function takes ownership of |opaque_data|, so caller must not - * free it. If the |opaque_data_len| is 0, opaque_data could be NULL. - */ -void nghttp2_frame_goaway_init(nghttp2_goaway *frame, int32_t last_stream_id, - uint32_t error_code, uint8_t *opaque_data, - size_t opaque_data_len); - -void nghttp2_frame_goaway_free(nghttp2_goaway *frame, nghttp2_mem *mem); - -void nghttp2_frame_window_update_init(nghttp2_window_update *frame, - uint8_t flags, int32_t stream_id, - int32_t window_size_increment); - -void nghttp2_frame_window_update_free(nghttp2_window_update *frame); - -void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type, - uint8_t flags, int32_t stream_id, - void *payload); - -void nghttp2_frame_extension_free(nghttp2_extension *frame); - -/* - * Initializes ALTSVC frame |frame| with given values. This function - * assumes that frame->payload points to nghttp2_ext_altsvc object. - * Also |origin| and |field_value| are allocated in single buffer, - * starting |origin|. On success, this function takes ownership of - * |origin|, so caller must not free it. - */ -void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id, - uint8_t *origin, size_t origin_len, - uint8_t *field_value, size_t field_value_len); - -/* - * Frees up resources under |frame|. This function does not free - * nghttp2_ext_altsvc object pointed by frame->payload. This function - * only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore, - * other fields must be allocated in the same buffer with origin. - */ -void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem); - -/* - * Initializes ORIGIN frame |frame| with given values. This function - * assumes that frame->payload points to nghttp2_ext_origin object. - * Also |ov| and the memory pointed by the field of its elements are - * allocated in single buffer, starting with |ov|. On success, this - * function takes ownership of |ov|, so caller must not free it. - */ -void nghttp2_frame_origin_init(nghttp2_extension *frame, - nghttp2_origin_entry *ov, size_t nov); - -/* - * Frees up resources under |frame|. This function does not free - * nghttp2_ext_origin object pointed by frame->payload. This function - * only frees nghttp2_ext_origin.ov. Therefore, other fields must be - * allocated in the same buffer with ov. - */ -void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem); - -/* - * Initializes PRIORITY_UPDATE frame |frame| with given values. This - * function assumes that frame->payload points to - * nghttp2_ext_priority_update object. On success, this function - * takes ownership of |field_value|, so caller must not free it. - */ -void nghttp2_frame_priority_update_init(nghttp2_extension *frame, - int32_t stream_id, uint8_t *field_value, - size_t field_value_len); - -/* - * Frees up resources under |frame|. This function does not free - * nghttp2_ext_priority_update object pointed by frame->payload. This - * function only frees field_value pointed by - * nghttp2_ext_priority_update.field_value. - */ -void nghttp2_frame_priority_update_free(nghttp2_extension *frame, - nghttp2_mem *mem); - -/* - * Returns the number of padding bytes after payload. The total - * padding length is given in the |padlen|. The returned value does - * not include the Pad Length field. If |padlen| is 0, this function - * returns 0, regardless of frame->hd.flags. - */ -size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen); - -void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags, - int32_t stream_id); - -void nghttp2_frame_data_free(nghttp2_data *frame); - -/* - * Makes copy of |iv| and return the copy. The |niv| is the number of - * entries in |iv|. This function returns the pointer to the copy if - * it succeeds, or NULL. - */ -nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv, - size_t niv, nghttp2_mem *mem); - -/* - * Sorts the |nva| in ascending order of name and value. If names are - * equivalent, sort them by value. - */ -void nghttp2_nv_array_sort(nghttp2_nv *nva, size_t nvlen); - -/* - * Copies name/value pairs from |nva|, which contains |nvlen| pairs, - * to |*nva_ptr|, which is dynamically allocated so that all items can - * be stored. The resultant name and value in nghttp2_nv are - * guaranteed to be NULL-terminated even if the input is not - * null-terminated. - * - * The |*nva_ptr| must be freed using nghttp2_nv_array_del(). - * - * This function returns 0 if it succeeds or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva, - size_t nvlen, nghttp2_mem *mem); - -/* - * Returns nonzero if the name/value pair |a| equals to |b|. The name - * is compared in case-sensitive, because we ensure that this function - * is called after the name is lower-cased. - */ -int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b); - -/* - * Frees |nva|. - */ -void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem); - -/* - * Checks that the |iv|, which includes |niv| entries, does not have - * invalid values. - * - * This function returns nonzero if it succeeds, or 0. - */ -int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv); - -/* - * Sets Pad Length field and flags and adjusts frame header position - * of each buffers in |bufs|. The number of padding is given in the - * |padlen| including Pad Length field. The |hd| is the frame header - * for the serialized data. This function fills zeros padding region - * unless framehd_only is nonzero. - */ -void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, - size_t padlen, int framehd_only); - -#endif /* NGHTTP2_FRAME_H */ diff --git a/vendor/nghttp2/lib/nghttp2_hd.c b/vendor/nghttp2/lib/nghttp2_hd.c deleted file mode 100644 index ad85eed1e..000000000 --- a/vendor/nghttp2/lib/nghttp2_hd.c +++ /dev/null @@ -1,2388 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_hd.h" - -#include -#include -#include - -#include "nghttp2_helper.h" -#include "nghttp2_int.h" -#include "nghttp2_debug.h" - -/* Make scalar initialization form of nghttp2_hd_entry */ -#define MAKE_STATIC_ENT(N, V, T, H) \ - { \ - {NULL, NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \ - {NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \ - {(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \ - T, \ - H, \ - } - -/* Generated by mkstatictbl.py */ -/* 3rd parameter is nghttp2_token value for header field name. We use - first enum value if same header names are repeated (e.g., - :status). */ -static const nghttp2_hd_static_entry static_table[] = { - MAKE_STATIC_ENT(":authority", "", 0, 3153725150u), - MAKE_STATIC_ENT(":method", "GET", 1, 695666056u), - MAKE_STATIC_ENT(":method", "POST", 1, 695666056u), - MAKE_STATIC_ENT(":path", "/", 3, 3292848686u), - MAKE_STATIC_ENT(":path", "/index.html", 3, 3292848686u), - MAKE_STATIC_ENT(":scheme", "http", 5, 2510477674u), - MAKE_STATIC_ENT(":scheme", "https", 5, 2510477674u), - MAKE_STATIC_ENT(":status", "200", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "204", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "206", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "304", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "400", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "404", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "500", 7, 4000288983u), - MAKE_STATIC_ENT("accept-charset", "", 14, 3664010344u), - MAKE_STATIC_ENT("accept-encoding", "gzip, deflate", 15, 3379649177u), - MAKE_STATIC_ENT("accept-language", "", 16, 1979086614u), - MAKE_STATIC_ENT("accept-ranges", "", 17, 1713753958u), - MAKE_STATIC_ENT("accept", "", 18, 136609321u), - MAKE_STATIC_ENT("access-control-allow-origin", "", 19, 2710797292u), - MAKE_STATIC_ENT("age", "", 20, 742476188u), - MAKE_STATIC_ENT("allow", "", 21, 2930878514u), - MAKE_STATIC_ENT("authorization", "", 22, 2436257726u), - MAKE_STATIC_ENT("cache-control", "", 23, 1355326669u), - MAKE_STATIC_ENT("content-disposition", "", 24, 3889184348u), - MAKE_STATIC_ENT("content-encoding", "", 25, 65203592u), - MAKE_STATIC_ENT("content-language", "", 26, 24973587u), - MAKE_STATIC_ENT("content-length", "", 27, 1308181789u), - MAKE_STATIC_ENT("content-location", "", 28, 2302364718u), - MAKE_STATIC_ENT("content-range", "", 29, 3555523146u), - MAKE_STATIC_ENT("content-type", "", 30, 4244048277u), - MAKE_STATIC_ENT("cookie", "", 31, 2007449791u), - MAKE_STATIC_ENT("date", "", 32, 3564297305u), - MAKE_STATIC_ENT("etag", "", 33, 113792960u), - MAKE_STATIC_ENT("expect", "", 34, 2530896728u), - MAKE_STATIC_ENT("expires", "", 35, 1049544579u), - MAKE_STATIC_ENT("from", "", 36, 2513272949u), - MAKE_STATIC_ENT("host", "", 37, 2952701295u), - MAKE_STATIC_ENT("if-match", "", 38, 3597694698u), - MAKE_STATIC_ENT("if-modified-since", "", 39, 2213050793u), - MAKE_STATIC_ENT("if-none-match", "", 40, 2536202615u), - MAKE_STATIC_ENT("if-range", "", 41, 2340978238u), - MAKE_STATIC_ENT("if-unmodified-since", "", 42, 3794814858u), - MAKE_STATIC_ENT("last-modified", "", 43, 3226950251u), - MAKE_STATIC_ENT("link", "", 44, 232457833u), - MAKE_STATIC_ENT("location", "", 45, 200649126u), - MAKE_STATIC_ENT("max-forwards", "", 46, 1826162134u), - MAKE_STATIC_ENT("proxy-authenticate", "", 47, 2709445359u), - MAKE_STATIC_ENT("proxy-authorization", "", 48, 2686392507u), - MAKE_STATIC_ENT("range", "", 49, 4208725202u), - MAKE_STATIC_ENT("referer", "", 50, 3969579366u), - MAKE_STATIC_ENT("refresh", "", 51, 3572655668u), - MAKE_STATIC_ENT("retry-after", "", 52, 3336180598u), - MAKE_STATIC_ENT("server", "", 53, 1085029842u), - MAKE_STATIC_ENT("set-cookie", "", 54, 1848371000u), - MAKE_STATIC_ENT("strict-transport-security", "", 55, 4138147361u), - MAKE_STATIC_ENT("transfer-encoding", "", 56, 3719590988u), - MAKE_STATIC_ENT("user-agent", "", 57, 606444526u), - MAKE_STATIC_ENT("vary", "", 58, 1085005381u), - MAKE_STATIC_ENT("via", "", 59, 1762798611u), - MAKE_STATIC_ENT("www-authenticate", "", 60, 779865858u), -}; - -static int memeq(const void *s1, const void *s2, size_t n) { - return memcmp(s1, s2, n) == 0; -} - -/* - * This function was generated by genlibtokenlookup.py. Inspired by - * h2o header lookup. https://github.com/h2o/h2o - */ -static int32_t lookup_token(const uint8_t *name, size_t namelen) { - switch (namelen) { - case 2: - switch (name[1]) { - case 'e': - if (memeq("t", name, 1)) { - return NGHTTP2_TOKEN_TE; - } - break; - } - break; - case 3: - switch (name[2]) { - case 'a': - if (memeq("vi", name, 2)) { - return NGHTTP2_TOKEN_VIA; - } - break; - case 'e': - if (memeq("ag", name, 2)) { - return NGHTTP2_TOKEN_AGE; - } - break; - } - break; - case 4: - switch (name[3]) { - case 'e': - if (memeq("dat", name, 3)) { - return NGHTTP2_TOKEN_DATE; - } - break; - case 'g': - if (memeq("eta", name, 3)) { - return NGHTTP2_TOKEN_ETAG; - } - break; - case 'k': - if (memeq("lin", name, 3)) { - return NGHTTP2_TOKEN_LINK; - } - break; - case 'm': - if (memeq("fro", name, 3)) { - return NGHTTP2_TOKEN_FROM; - } - break; - case 't': - if (memeq("hos", name, 3)) { - return NGHTTP2_TOKEN_HOST; - } - break; - case 'y': - if (memeq("var", name, 3)) { - return NGHTTP2_TOKEN_VARY; - } - break; - } - break; - case 5: - switch (name[4]) { - case 'e': - if (memeq("rang", name, 4)) { - return NGHTTP2_TOKEN_RANGE; - } - break; - case 'h': - if (memeq(":pat", name, 4)) { - return NGHTTP2_TOKEN__PATH; - } - break; - case 'w': - if (memeq("allo", name, 4)) { - return NGHTTP2_TOKEN_ALLOW; - } - break; - } - break; - case 6: - switch (name[5]) { - case 'e': - if (memeq("cooki", name, 5)) { - return NGHTTP2_TOKEN_COOKIE; - } - break; - case 'r': - if (memeq("serve", name, 5)) { - return NGHTTP2_TOKEN_SERVER; - } - break; - case 't': - if (memeq("accep", name, 5)) { - return NGHTTP2_TOKEN_ACCEPT; - } - if (memeq("expec", name, 5)) { - return NGHTTP2_TOKEN_EXPECT; - } - break; - } - break; - case 7: - switch (name[6]) { - case 'd': - if (memeq(":metho", name, 6)) { - return NGHTTP2_TOKEN__METHOD; - } - break; - case 'e': - if (memeq(":schem", name, 6)) { - return NGHTTP2_TOKEN__SCHEME; - } - if (memeq("upgrad", name, 6)) { - return NGHTTP2_TOKEN_UPGRADE; - } - break; - case 'h': - if (memeq("refres", name, 6)) { - return NGHTTP2_TOKEN_REFRESH; - } - break; - case 'r': - if (memeq("refere", name, 6)) { - return NGHTTP2_TOKEN_REFERER; - } - break; - case 's': - if (memeq(":statu", name, 6)) { - return NGHTTP2_TOKEN__STATUS; - } - if (memeq("expire", name, 6)) { - return NGHTTP2_TOKEN_EXPIRES; - } - break; - } - break; - case 8: - switch (name[7]) { - case 'e': - if (memeq("if-rang", name, 7)) { - return NGHTTP2_TOKEN_IF_RANGE; - } - break; - case 'h': - if (memeq("if-matc", name, 7)) { - return NGHTTP2_TOKEN_IF_MATCH; - } - break; - case 'n': - if (memeq("locatio", name, 7)) { - return NGHTTP2_TOKEN_LOCATION; - } - break; - case 'y': - if (memeq("priorit", name, 7)) { - return NGHTTP2_TOKEN_PRIORITY; - } - break; - } - break; - case 9: - switch (name[8]) { - case 'l': - if (memeq(":protoco", name, 8)) { - return NGHTTP2_TOKEN__PROTOCOL; - } - break; - } - break; - case 10: - switch (name[9]) { - case 'e': - if (memeq("keep-aliv", name, 9)) { - return NGHTTP2_TOKEN_KEEP_ALIVE; - } - if (memeq("set-cooki", name, 9)) { - return NGHTTP2_TOKEN_SET_COOKIE; - } - break; - case 'n': - if (memeq("connectio", name, 9)) { - return NGHTTP2_TOKEN_CONNECTION; - } - break; - case 't': - if (memeq("user-agen", name, 9)) { - return NGHTTP2_TOKEN_USER_AGENT; - } - break; - case 'y': - if (memeq(":authorit", name, 9)) { - return NGHTTP2_TOKEN__AUTHORITY; - } - break; - } - break; - case 11: - switch (name[10]) { - case 'r': - if (memeq("retry-afte", name, 10)) { - return NGHTTP2_TOKEN_RETRY_AFTER; - } - break; - } - break; - case 12: - switch (name[11]) { - case 'e': - if (memeq("content-typ", name, 11)) { - return NGHTTP2_TOKEN_CONTENT_TYPE; - } - break; - case 's': - if (memeq("max-forward", name, 11)) { - return NGHTTP2_TOKEN_MAX_FORWARDS; - } - break; - } - break; - case 13: - switch (name[12]) { - case 'd': - if (memeq("last-modifie", name, 12)) { - return NGHTTP2_TOKEN_LAST_MODIFIED; - } - break; - case 'e': - if (memeq("content-rang", name, 12)) { - return NGHTTP2_TOKEN_CONTENT_RANGE; - } - break; - case 'h': - if (memeq("if-none-matc", name, 12)) { - return NGHTTP2_TOKEN_IF_NONE_MATCH; - } - break; - case 'l': - if (memeq("cache-contro", name, 12)) { - return NGHTTP2_TOKEN_CACHE_CONTROL; - } - break; - case 'n': - if (memeq("authorizatio", name, 12)) { - return NGHTTP2_TOKEN_AUTHORIZATION; - } - break; - case 's': - if (memeq("accept-range", name, 12)) { - return NGHTTP2_TOKEN_ACCEPT_RANGES; - } - break; - } - break; - case 14: - switch (name[13]) { - case 'h': - if (memeq("content-lengt", name, 13)) { - return NGHTTP2_TOKEN_CONTENT_LENGTH; - } - break; - case 't': - if (memeq("accept-charse", name, 13)) { - return NGHTTP2_TOKEN_ACCEPT_CHARSET; - } - break; - } - break; - case 15: - switch (name[14]) { - case 'e': - if (memeq("accept-languag", name, 14)) { - return NGHTTP2_TOKEN_ACCEPT_LANGUAGE; - } - break; - case 'g': - if (memeq("accept-encodin", name, 14)) { - return NGHTTP2_TOKEN_ACCEPT_ENCODING; - } - break; - } - break; - case 16: - switch (name[15]) { - case 'e': - if (memeq("content-languag", name, 15)) { - return NGHTTP2_TOKEN_CONTENT_LANGUAGE; - } - if (memeq("www-authenticat", name, 15)) { - return NGHTTP2_TOKEN_WWW_AUTHENTICATE; - } - break; - case 'g': - if (memeq("content-encodin", name, 15)) { - return NGHTTP2_TOKEN_CONTENT_ENCODING; - } - break; - case 'n': - if (memeq("content-locatio", name, 15)) { - return NGHTTP2_TOKEN_CONTENT_LOCATION; - } - if (memeq("proxy-connectio", name, 15)) { - return NGHTTP2_TOKEN_PROXY_CONNECTION; - } - break; - } - break; - case 17: - switch (name[16]) { - case 'e': - if (memeq("if-modified-sinc", name, 16)) { - return NGHTTP2_TOKEN_IF_MODIFIED_SINCE; - } - break; - case 'g': - if (memeq("transfer-encodin", name, 16)) { - return NGHTTP2_TOKEN_TRANSFER_ENCODING; - } - break; - } - break; - case 18: - switch (name[17]) { - case 'e': - if (memeq("proxy-authenticat", name, 17)) { - return NGHTTP2_TOKEN_PROXY_AUTHENTICATE; - } - break; - } - break; - case 19: - switch (name[18]) { - case 'e': - if (memeq("if-unmodified-sinc", name, 18)) { - return NGHTTP2_TOKEN_IF_UNMODIFIED_SINCE; - } - break; - case 'n': - if (memeq("content-dispositio", name, 18)) { - return NGHTTP2_TOKEN_CONTENT_DISPOSITION; - } - if (memeq("proxy-authorizatio", name, 18)) { - return NGHTTP2_TOKEN_PROXY_AUTHORIZATION; - } - break; - } - break; - case 25: - switch (name[24]) { - case 'y': - if (memeq("strict-transport-securit", name, 24)) { - return NGHTTP2_TOKEN_STRICT_TRANSPORT_SECURITY; - } - break; - } - break; - case 27: - switch (name[26]) { - case 'n': - if (memeq("access-control-allow-origi", name, 26)) { - return NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN; - } - break; - } - break; - } - return -1; -} - -void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv) { - ent->nv = *nv; - ent->cnv.name = nv->name->base; - ent->cnv.namelen = nv->name->len; - ent->cnv.value = nv->value->base; - ent->cnv.valuelen = nv->value->len; - ent->cnv.flags = nv->flags; - ent->next = NULL; - ent->hash = 0; - - nghttp2_rcbuf_incref(ent->nv.name); - nghttp2_rcbuf_incref(ent->nv.value); -} - -void nghttp2_hd_entry_free(nghttp2_hd_entry *ent) { - nghttp2_rcbuf_decref(ent->nv.value); - nghttp2_rcbuf_decref(ent->nv.name); -} - -static int name_eq(const nghttp2_hd_nv *a, const nghttp2_nv *b) { - return a->name->len == b->namelen && - memeq(a->name->base, b->name, b->namelen); -} - -static int value_eq(const nghttp2_hd_nv *a, const nghttp2_nv *b) { - return a->value->len == b->valuelen && - memeq(a->value->base, b->value, b->valuelen); -} - -static uint32_t name_hash(const nghttp2_nv *nv) { - /* 32 bit FNV-1a: http://isthe.com/chongo/tech/comp/fnv/ */ - uint32_t h = 2166136261u; - size_t i; - - for (i = 0; i < nv->namelen; ++i) { - h ^= nv->name[i]; - h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24); - } - - return h; -} - -static void hd_map_init(nghttp2_hd_map *map) { - memset(map, 0, sizeof(nghttp2_hd_map)); -} - -static void hd_map_insert(nghttp2_hd_map *map, nghttp2_hd_entry *ent) { - nghttp2_hd_entry **bucket; - - bucket = &map->table[ent->hash & (HD_MAP_SIZE - 1)]; - - if (*bucket == NULL) { - *bucket = ent; - return; - } - - /* lower index is linked near the root */ - ent->next = *bucket; - *bucket = ent; -} - -static nghttp2_hd_entry *hd_map_find(nghttp2_hd_map *map, int *exact_match, - const nghttp2_nv *nv, int32_t token, - uint32_t hash, int name_only) { - nghttp2_hd_entry *p; - nghttp2_hd_entry *res = NULL; - - *exact_match = 0; - - for (p = map->table[hash & (HD_MAP_SIZE - 1)]; p; p = p->next) { - if (token != p->nv.token || - (token == -1 && (hash != p->hash || !name_eq(&p->nv, nv)))) { - continue; - } - if (!res) { - res = p; - if (name_only) { - break; - } - } - if (value_eq(&p->nv, nv)) { - res = p; - *exact_match = 1; - break; - } - } - - return res; -} - -static void hd_map_remove(nghttp2_hd_map *map, nghttp2_hd_entry *ent) { - nghttp2_hd_entry **dst; - - dst = &map->table[ent->hash & (HD_MAP_SIZE - 1)]; - - for (; *dst; dst = &(*dst)->next) { - if (*dst != ent) { - continue; - } - - *dst = ent->next; - ent->next = NULL; - return; - } -} - -static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize, - nghttp2_mem *mem) { - size_t size; - const size_t max_size = SIZE_MAX / sizeof(nghttp2_hd_entry *); - - if (bufsize > max_size) { - return NGHTTP2_ERR_NOMEM; - } - - for (size = 1; size < bufsize; size <<= 1) - ; - - if (size > max_size) { - return NGHTTP2_ERR_NOMEM; - } - - ringbuf->buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size); - if (ringbuf->buffer == NULL) { - return NGHTTP2_ERR_NOMEM; - } - ringbuf->mask = size - 1; - ringbuf->first = 0; - ringbuf->len = 0; - return 0; -} - -static nghttp2_hd_entry *hd_ringbuf_get(nghttp2_hd_ringbuf *ringbuf, - size_t idx) { - assert(idx < ringbuf->len); - return ringbuf->buffer[(ringbuf->first + idx) & ringbuf->mask]; -} - -static int hd_ringbuf_reserve(nghttp2_hd_ringbuf *ringbuf, size_t bufsize, - nghttp2_mem *mem) { - size_t i; - size_t size; - nghttp2_hd_entry **buffer; - - if (ringbuf->mask + 1 >= bufsize) { - return 0; - } - for (size = 1; size < bufsize; size <<= 1) - ; - buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size); - if (buffer == NULL) { - return NGHTTP2_ERR_NOMEM; - } - for (i = 0; i < ringbuf->len; ++i) { - buffer[i] = hd_ringbuf_get(ringbuf, i); - } - nghttp2_mem_free(mem, ringbuf->buffer); - ringbuf->buffer = buffer; - ringbuf->mask = size - 1; - ringbuf->first = 0; - return 0; -} - -static void hd_ringbuf_free(nghttp2_hd_ringbuf *ringbuf, nghttp2_mem *mem) { - size_t i; - if (ringbuf == NULL) { - return; - } - for (i = 0; i < ringbuf->len; ++i) { - nghttp2_hd_entry *ent = hd_ringbuf_get(ringbuf, i); - - nghttp2_hd_entry_free(ent); - nghttp2_mem_free(mem, ent); - } - nghttp2_mem_free(mem, ringbuf->buffer); -} - -static int hd_ringbuf_push_front(nghttp2_hd_ringbuf *ringbuf, - nghttp2_hd_entry *ent, nghttp2_mem *mem) { - int rv; - - rv = hd_ringbuf_reserve(ringbuf, ringbuf->len + 1, mem); - - if (rv != 0) { - return rv; - } - - ringbuf->buffer[--ringbuf->first & ringbuf->mask] = ent; - ++ringbuf->len; - - return 0; -} - -static void hd_ringbuf_pop_back(nghttp2_hd_ringbuf *ringbuf) { - assert(ringbuf->len > 0); - --ringbuf->len; -} - -static int hd_context_init(nghttp2_hd_context *context, nghttp2_mem *mem) { - int rv; - context->mem = mem; - context->bad = 0; - context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; - rv = hd_ringbuf_init( - &context->hd_table, - context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem); - if (rv != 0) { - return rv; - } - - context->hd_table_bufsize = 0; - context->next_seq = 0; - - return 0; -} - -static void hd_context_free(nghttp2_hd_context *context) { - hd_ringbuf_free(&context->hd_table, context->mem); -} - -int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem) { - return nghttp2_hd_deflate_init2( - deflater, NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, mem); -} - -int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater, - size_t max_deflate_dynamic_table_size, - nghttp2_mem *mem) { - int rv; - rv = hd_context_init(&deflater->ctx, mem); - if (rv != 0) { - return rv; - } - - hd_map_init(&deflater->map); - - if (max_deflate_dynamic_table_size < NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE) { - deflater->notify_table_size_change = 1; - deflater->ctx.hd_table_bufsize_max = max_deflate_dynamic_table_size; - } else { - deflater->notify_table_size_change = 0; - } - - deflater->deflate_hd_table_bufsize_max = max_deflate_dynamic_table_size; - deflater->min_hd_table_bufsize_max = UINT32_MAX; - - return 0; -} - -int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem) { - int rv; - - rv = hd_context_init(&inflater->ctx, mem); - if (rv != 0) { - goto fail; - } - - inflater->settings_hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; - inflater->min_hd_table_bufsize_max = UINT32_MAX; - - inflater->nv_name_keep = NULL; - inflater->nv_value_keep = NULL; - - inflater->opcode = NGHTTP2_HD_OPCODE_NONE; - inflater->state = NGHTTP2_HD_STATE_INFLATE_START; - - nghttp2_buf_init(&inflater->namebuf); - nghttp2_buf_init(&inflater->valuebuf); - - inflater->namercbuf = NULL; - inflater->valuercbuf = NULL; - - inflater->huffman_encoded = 0; - inflater->index = 0; - inflater->left = 0; - inflater->shift = 0; - inflater->index_required = 0; - inflater->no_index = 0; - - return 0; - -fail: - return rv; -} - -static void hd_inflate_keep_free(nghttp2_hd_inflater *inflater) { - nghttp2_rcbuf_decref(inflater->nv_value_keep); - nghttp2_rcbuf_decref(inflater->nv_name_keep); - - inflater->nv_value_keep = NULL; - inflater->nv_name_keep = NULL; -} - -void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater) { - hd_context_free(&deflater->ctx); -} - -void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater) { - hd_inflate_keep_free(inflater); - - nghttp2_rcbuf_decref(inflater->valuercbuf); - nghttp2_rcbuf_decref(inflater->namercbuf); - - hd_context_free(&inflater->ctx); -} - -static size_t entry_room(size_t namelen, size_t valuelen) { - return NGHTTP2_HD_ENTRY_OVERHEAD + namelen + valuelen; -} - -static void emit_header(nghttp2_hd_nv *nv_out, nghttp2_hd_nv *nv) { - DEBUGF("inflatehd: header emission: %s: %s\n", nv->name->base, - nv->value->base); - /* ent->ref may be 0. This happens if the encoder emits literal - block larger than header table capacity with indexing. */ - *nv_out = *nv; -} - -static size_t count_encoded_length(size_t n, size_t prefix) { - size_t k = (size_t)((1 << prefix) - 1); - size_t len = 0; - - if (n < k) { - return 1; - } - - n -= k; - ++len; - - for (; n >= 128; n >>= 7, ++len) - ; - - return len + 1; -} - -static size_t encode_length(uint8_t *buf, size_t n, size_t prefix) { - size_t k = (size_t)((1 << prefix) - 1); - uint8_t *begin = buf; - - *buf = (uint8_t)(*buf & ~k); - - if (n < k) { - *buf = (uint8_t)(*buf | n); - return 1; - } - - *buf = (uint8_t)(*buf | k); - ++buf; - - n -= k; - - for (; n >= 128; n >>= 7) { - *buf++ = (uint8_t)((1 << 7) | (n & 0x7f)); - } - - *buf++ = (uint8_t)n; - - return (size_t)(buf - begin); -} - -/* - * Decodes |prefix| prefixed integer stored from |in|. The |last| - * represents the 1 beyond the last of the valid contiguous memory - * region from |in|. The decoded integer must be less than or equal - * to UINT32_MAX. - * - * If the |initial| is nonzero, it is used as a initial value, this - * function assumes the |in| starts with intermediate data. - * - * An entire integer is decoded successfully, decoded, the |*fin| is - * set to nonzero. - * - * This function stores the decoded integer in |*res| if it succeed, - * including partial decoding (in this case, number of shift to make - * in the next call will be stored in |*shift_ptr|) and returns number - * of bytes processed, or returns -1, indicating decoding error. - */ -static nghttp2_ssize decode_length(uint32_t *res, size_t *shift_ptr, int *fin, - uint32_t initial, size_t shift, - const uint8_t *in, const uint8_t *last, - size_t prefix) { - uint32_t k = (uint8_t)((1 << prefix) - 1); - uint32_t n = initial; - const uint8_t *start = in; - - *shift_ptr = 0; - *fin = 0; - - if (n == 0) { - if ((*in & k) != k) { - *res = (*in) & k; - *fin = 1; - return 1; - } - - n = k; - - if (++in == last) { - *res = n; - return (nghttp2_ssize)(in - start); - } - } - - for (; in != last; ++in, shift += 7) { - uint32_t add = *in & 0x7f; - - if (shift >= 32) { - DEBUGF("inflate: shift exponent overflow\n"); - return -1; - } - - if ((UINT32_MAX >> shift) < add) { - DEBUGF("inflate: integer overflow on shift\n"); - return -1; - } - - add <<= shift; - - if (UINT32_MAX - add < n) { - DEBUGF("inflate: integer overflow on addition\n"); - return -1; - } - - n += add; - - if ((*in & (1 << 7)) == 0) { - break; - } - } - - *shift_ptr = shift; - - if (in == last) { - *res = n; - return (nghttp2_ssize)(in - start); - } - - *res = n; - *fin = 1; - return (nghttp2_ssize)(in + 1 - start); -} - -static int emit_table_size(nghttp2_bufs *bufs, size_t table_size) { - int rv; - uint8_t *bufp; - size_t blocklen; - uint8_t sb[16]; - - DEBUGF("deflatehd: emit table_size=%zu\n", table_size); - - blocklen = count_encoded_length(table_size, 5); - - if (sizeof(sb) < blocklen) { - return NGHTTP2_ERR_HEADER_COMP; - } - - bufp = sb; - - *bufp = 0x20u; - - encode_length(bufp, table_size, 5); - - rv = nghttp2_bufs_add(bufs, sb, blocklen); - if (rv != 0) { - return rv; - } - - return 0; -} - -static int emit_indexed_block(nghttp2_bufs *bufs, size_t idx) { - int rv; - size_t blocklen; - uint8_t sb[16]; - uint8_t *bufp; - - blocklen = count_encoded_length(idx + 1, 7); - - DEBUGF("deflatehd: emit indexed index=%zu, %zu bytes\n", idx, blocklen); - - if (sizeof(sb) < blocklen) { - return NGHTTP2_ERR_HEADER_COMP; - } - - bufp = sb; - *bufp = 0x80u; - encode_length(bufp, idx + 1, 7); - - rv = nghttp2_bufs_add(bufs, sb, blocklen); - if (rv != 0) { - return rv; - } - - return 0; -} - -static int emit_string(nghttp2_bufs *bufs, const uint8_t *str, size_t len) { - int rv; - uint8_t sb[16]; - uint8_t *bufp; - size_t blocklen; - size_t enclen; - int huffman = 0; - - enclen = nghttp2_hd_huff_encode_count(str, len); - - if (enclen < len) { - huffman = 1; - } else { - enclen = len; - } - - blocklen = count_encoded_length(enclen, 7); - - DEBUGF("deflatehd: emit string str=%.*s, length=%zu, huffman=%d, " - "encoded_length=%zu\n", - (int)len, (const char *)str, len, huffman, enclen); - - if (sizeof(sb) < blocklen) { - return NGHTTP2_ERR_HEADER_COMP; - } - - bufp = sb; - *bufp = huffman ? 1 << 7 : 0; - encode_length(bufp, enclen, 7); - - rv = nghttp2_bufs_add(bufs, sb, blocklen); - if (rv != 0) { - return rv; - } - - if (huffman) { - rv = nghttp2_hd_huff_encode(bufs, str, len); - } else { - assert(enclen == len); - rv = nghttp2_bufs_add(bufs, str, len); - } - - return rv; -} - -static uint8_t pack_first_byte(int indexing_mode) { - switch (indexing_mode) { - case NGHTTP2_HD_WITH_INDEXING: - return 0x40u; - case NGHTTP2_HD_WITHOUT_INDEXING: - return 0; - case NGHTTP2_HD_NEVER_INDEXING: - return 0x10u; - default: - assert(0); - } - /* This is required to compile with android NDK r10d + - --enable-werror */ - return 0; -} - -static int emit_indname_block(nghttp2_bufs *bufs, size_t idx, - const nghttp2_nv *nv, int indexing_mode) { - int rv; - uint8_t *bufp; - size_t blocklen; - uint8_t sb[16]; - size_t prefixlen; - - if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) { - prefixlen = 6; - } else { - prefixlen = 4; - } - - DEBUGF("deflatehd: emit indname index=%zu, valuelen=%zu, indexing_mode=%d\n", - idx, nv->valuelen, indexing_mode); - - blocklen = count_encoded_length(idx + 1, prefixlen); - - if (sizeof(sb) < blocklen) { - return NGHTTP2_ERR_HEADER_COMP; - } - - bufp = sb; - - *bufp = pack_first_byte(indexing_mode); - - encode_length(bufp, idx + 1, prefixlen); - - rv = nghttp2_bufs_add(bufs, sb, blocklen); - if (rv != 0) { - return rv; - } - - rv = emit_string(bufs, nv->value, nv->valuelen); - if (rv != 0) { - return rv; - } - - return 0; -} - -static int emit_newname_block(nghttp2_bufs *bufs, const nghttp2_nv *nv, - int indexing_mode) { - int rv; - - DEBUGF( - "deflatehd: emit newname namelen=%zu, valuelen=%zu, indexing_mode=%d\n", - nv->namelen, nv->valuelen, indexing_mode); - - rv = nghttp2_bufs_addb(bufs, pack_first_byte(indexing_mode)); - if (rv != 0) { - return rv; - } - - rv = emit_string(bufs, nv->name, nv->namelen); - if (rv != 0) { - return rv; - } - - rv = emit_string(bufs, nv->value, nv->valuelen); - if (rv != 0) { - return rv; - } - - return 0; -} - -static int add_hd_table_incremental(nghttp2_hd_context *context, - nghttp2_hd_nv *nv, nghttp2_hd_map *map, - uint32_t hash) { - int rv; - nghttp2_hd_entry *new_ent; - size_t room; - nghttp2_mem *mem; - - mem = context->mem; - room = entry_room(nv->name->len, nv->value->len); - - while (context->hd_table_bufsize + room > context->hd_table_bufsize_max && - context->hd_table.len > 0) { - size_t idx = context->hd_table.len - 1; - nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx); - - context->hd_table_bufsize -= - entry_room(ent->nv.name->len, ent->nv.value->len); - - DEBUGF("hpack: remove item from header table: %s: %s\n", - (char *)ent->nv.name->base, (char *)ent->nv.value->base); - - hd_ringbuf_pop_back(&context->hd_table); - if (map) { - hd_map_remove(map, ent); - } - - nghttp2_hd_entry_free(ent); - nghttp2_mem_free(mem, ent); - } - - if (room > context->hd_table_bufsize_max) { - /* The entry taking more than NGHTTP2_HD_MAX_BUFFER_SIZE is - immediately evicted. So we don't allocate memory for it. */ - return 0; - } - - new_ent = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry)); - if (new_ent == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_hd_entry_init(new_ent, nv); - - rv = hd_ringbuf_push_front(&context->hd_table, new_ent, mem); - - if (rv != 0) { - nghttp2_hd_entry_free(new_ent); - nghttp2_mem_free(mem, new_ent); - - return rv; - } - - new_ent->seq = context->next_seq++; - new_ent->hash = hash; - - if (map) { - hd_map_insert(map, new_ent); - } - - context->hd_table_bufsize += room; - - return 0; -} - -typedef struct { - nghttp2_ssize index; - /* Nonzero if both name and value are matched. */ - int name_value_match; -} search_result; - -static search_result search_static_table(const nghttp2_nv *nv, int32_t token, - int name_only) { - search_result res = {token, 0}; - int i; - const nghttp2_hd_static_entry *ent; - - if (name_only) { - return res; - } - - for (i = token; - i <= NGHTTP2_TOKEN_WWW_AUTHENTICATE && static_table[i].token == token; - ++i) { - ent = &static_table[i]; - if (ent->value.len == nv->valuelen && - memcmp(ent->value.base, nv->value, nv->valuelen) == 0) { - res.index = i; - res.name_value_match = 1; - return res; - } - } - return res; -} - -static search_result search_hd_table(nghttp2_hd_context *context, - const nghttp2_nv *nv, int32_t token, - int indexing_mode, nghttp2_hd_map *map, - uint32_t hash) { - search_result res = {-1, 0}; - const nghttp2_hd_entry *ent; - int exact_match; - int name_only = indexing_mode == NGHTTP2_HD_NEVER_INDEXING; - - exact_match = 0; - ent = hd_map_find(map, &exact_match, nv, token, hash, name_only); - - if (!exact_match && token >= 0 && token <= NGHTTP2_TOKEN_WWW_AUTHENTICATE) { - return search_static_table(nv, token, name_only); - } - - if (ent == NULL) { - return res; - } - - res.index = (nghttp2_ssize)(context->next_seq - 1 - ent->seq + - NGHTTP2_STATIC_TABLE_LENGTH); - res.name_value_match = exact_match; - - return res; -} - -static void hd_context_shrink_table_size(nghttp2_hd_context *context, - nghttp2_hd_map *map) { - nghttp2_mem *mem; - - mem = context->mem; - - while (context->hd_table_bufsize > context->hd_table_bufsize_max && - context->hd_table.len > 0) { - size_t idx = context->hd_table.len - 1; - nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx); - context->hd_table_bufsize -= - entry_room(ent->nv.name->len, ent->nv.value->len); - hd_ringbuf_pop_back(&context->hd_table); - if (map) { - hd_map_remove(map, ent); - } - - nghttp2_hd_entry_free(ent); - nghttp2_mem_free(mem, ent); - } -} - -int nghttp2_hd_deflate_change_table_size( - nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) { - size_t next_bufsize = nghttp2_min_size( - settings_max_dynamic_table_size, deflater->deflate_hd_table_bufsize_max); - - deflater->ctx.hd_table_bufsize_max = next_bufsize; - - deflater->min_hd_table_bufsize_max = - nghttp2_min_size(deflater->min_hd_table_bufsize_max, next_bufsize); - - deflater->notify_table_size_change = 1; - - hd_context_shrink_table_size(&deflater->ctx, &deflater->map); - return 0; -} - -int nghttp2_hd_inflate_change_table_size( - nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_table_size) { - switch (inflater->state) { - case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE: - case NGHTTP2_HD_STATE_INFLATE_START: - break; - default: - return NGHTTP2_ERR_INVALID_STATE; - } - - inflater->settings_hd_table_bufsize_max = settings_max_dynamic_table_size; - - /* It seems that encoder is not required to send dynamic table size - update if the table size is not changed after applying - SETTINGS_HEADER_TABLE_SIZE. RFC 7541 is ambiguous here, but this - is the intention of the editor. If new maximum table size is - strictly smaller than the current negotiated maximum size, - encoder must send dynamic table size update. In other cases, we - cannot expect it to do so. */ - if (inflater->ctx.hd_table_bufsize_max > settings_max_dynamic_table_size) { - inflater->state = NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE; - /* Remember minimum value, and validate that encoder sends the - value less than or equal to this. */ - inflater->min_hd_table_bufsize_max = settings_max_dynamic_table_size; - - inflater->ctx.hd_table_bufsize_max = settings_max_dynamic_table_size; - - hd_context_shrink_table_size(&inflater->ctx, NULL); - } - - return 0; -} - -#define INDEX_RANGE_VALID(context, idx) \ - ((idx) < (context)->hd_table.len + NGHTTP2_STATIC_TABLE_LENGTH) - -static size_t get_max_index(nghttp2_hd_context *context) { - return context->hd_table.len + NGHTTP2_STATIC_TABLE_LENGTH; -} - -nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t idx) { - assert(INDEX_RANGE_VALID(context, idx)); - if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) { - return hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH) - ->nv; - } else { - const nghttp2_hd_static_entry *ent = &static_table[idx]; - nghttp2_hd_nv nv = {(nghttp2_rcbuf *)&ent->name, - (nghttp2_rcbuf *)&ent->value, ent->token, - NGHTTP2_NV_FLAG_NONE}; - return nv; - } -} - -static const nghttp2_nv *nghttp2_hd_table_get2(nghttp2_hd_context *context, - size_t idx) { - assert(INDEX_RANGE_VALID(context, idx)); - if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) { - return &hd_ringbuf_get(&context->hd_table, - idx - NGHTTP2_STATIC_TABLE_LENGTH) - ->cnv; - } - - return &static_table[idx].cnv; -} - -static int hd_deflate_decide_indexing(nghttp2_hd_deflater *deflater, - const nghttp2_nv *nv, int32_t token) { - if (token == NGHTTP2_TOKEN__PATH || token == NGHTTP2_TOKEN_AGE || - token == NGHTTP2_TOKEN_CONTENT_LENGTH || token == NGHTTP2_TOKEN_ETAG || - token == NGHTTP2_TOKEN_IF_MODIFIED_SINCE || - token == NGHTTP2_TOKEN_IF_NONE_MATCH || token == NGHTTP2_TOKEN_LOCATION || - token == NGHTTP2_TOKEN_SET_COOKIE || - entry_room(nv->namelen, nv->valuelen) > - deflater->ctx.hd_table_bufsize_max * 3 / 4) { - return NGHTTP2_HD_WITHOUT_INDEXING; - } - - return NGHTTP2_HD_WITH_INDEXING; -} - -static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs, - const nghttp2_nv *nv) { - int rv; - search_result res; - nghttp2_ssize idx; - int indexing_mode; - int32_t token; - nghttp2_mem *mem; - uint32_t hash = 0; - - DEBUGF("deflatehd: deflating %.*s: %.*s\n", (int)nv->namelen, nv->name, - (int)nv->valuelen, nv->value); - - mem = deflater->ctx.mem; - - token = lookup_token(nv->name, nv->namelen); - if (token == -1) { - hash = name_hash(nv); - } else if (token <= NGHTTP2_TOKEN_WWW_AUTHENTICATE) { - hash = static_table[token].hash; - } - - /* Don't index authorization header field since it may contain low - entropy secret data (e.g., id/password). Also cookie header - field with less than 20 bytes value is also never indexed. This - is the same criteria used in Firefox codebase. */ - indexing_mode = token == NGHTTP2_TOKEN_AUTHORIZATION || - (token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) || - (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) - ? NGHTTP2_HD_NEVER_INDEXING - : hd_deflate_decide_indexing(deflater, nv, token); - - res = search_hd_table(&deflater->ctx, nv, token, indexing_mode, - &deflater->map, hash); - - idx = res.index; - - if (res.name_value_match) { - DEBUGF("deflatehd: name/value match index=%td\n", idx); - - rv = emit_indexed_block(bufs, (size_t)idx); - if (rv != 0) { - return rv; - } - - return 0; - } - - if (res.index != -1) { - DEBUGF("deflatehd: name match index=%td\n", res.index); - } - - if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) { - nghttp2_hd_nv hd_nv; - - if (idx != -1) { - hd_nv.name = nghttp2_hd_table_get(&deflater->ctx, (size_t)idx).name; - nghttp2_rcbuf_incref(hd_nv.name); - } else { - rv = nghttp2_rcbuf_new2(&hd_nv.name, nv->name, nv->namelen, mem); - if (rv != 0) { - return rv; - } - } - - rv = nghttp2_rcbuf_new2(&hd_nv.value, nv->value, nv->valuelen, mem); - - if (rv != 0) { - nghttp2_rcbuf_decref(hd_nv.name); - return rv; - } - - hd_nv.token = token; - hd_nv.flags = NGHTTP2_NV_FLAG_NONE; - - rv = add_hd_table_incremental(&deflater->ctx, &hd_nv, &deflater->map, hash); - - nghttp2_rcbuf_decref(hd_nv.value); - nghttp2_rcbuf_decref(hd_nv.name); - - if (rv != 0) { - return NGHTTP2_ERR_HEADER_COMP; - } - } - if (idx == -1) { - rv = emit_newname_block(bufs, nv, indexing_mode); - } else { - rv = emit_indname_block(bufs, (size_t)idx, nv, indexing_mode); - } - if (rv != 0) { - return rv; - } - - return 0; -} - -int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater, - nghttp2_bufs *bufs, const nghttp2_nv *nv, - size_t nvlen) { - size_t i; - int rv = 0; - - if (deflater->ctx.bad) { - return NGHTTP2_ERR_HEADER_COMP; - } - - if (deflater->notify_table_size_change) { - size_t min_hd_table_bufsize_max; - - min_hd_table_bufsize_max = deflater->min_hd_table_bufsize_max; - - deflater->notify_table_size_change = 0; - deflater->min_hd_table_bufsize_max = UINT32_MAX; - - if (deflater->ctx.hd_table_bufsize_max > min_hd_table_bufsize_max) { - rv = emit_table_size(bufs, min_hd_table_bufsize_max); - - if (rv != 0) { - goto fail; - } - } - - rv = emit_table_size(bufs, deflater->ctx.hd_table_bufsize_max); - - if (rv != 0) { - goto fail; - } - } - - for (i = 0; i < nvlen; ++i) { - rv = deflate_nv(deflater, bufs, &nv[i]); - if (rv != 0) { - goto fail; - } - } - - DEBUGF("deflatehd: all input name/value pairs were deflated\n"); - - return 0; -fail: - DEBUGF("deflatehd: error return %d\n", rv); - - deflater->ctx.bad = 1; - return rv; -} - -ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf, - size_t buflen, const nghttp2_nv *nv, - size_t nvlen) { - return (ssize_t)nghttp2_hd_deflate_hd2(deflater, buf, buflen, nv, nvlen); -} - -nghttp2_ssize nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater, - uint8_t *buf, size_t buflen, - const nghttp2_nv *nv, size_t nvlen) { - nghttp2_bufs bufs; - int rv; - nghttp2_mem *mem; - - mem = deflater->ctx.mem; - - rv = nghttp2_bufs_wrap_init(&bufs, buf, buflen, mem); - - if (rv != 0) { - return rv; - } - - rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nv, nvlen); - - buflen = nghttp2_bufs_len(&bufs); - - nghttp2_bufs_wrap_free(&bufs); - - if (rv == NGHTTP2_ERR_BUFFER_ERROR) { - return NGHTTP2_ERR_INSUFF_BUFSIZE; - } - - if (rv != 0) { - return rv; - } - - return (nghttp2_ssize)buflen; -} - -ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, - const nghttp2_vec *vec, size_t veclen, - const nghttp2_nv *nv, size_t nvlen) { - return (ssize_t)nghttp2_hd_deflate_hd_vec2(deflater, vec, veclen, nv, nvlen); -} - -nghttp2_ssize nghttp2_hd_deflate_hd_vec2(nghttp2_hd_deflater *deflater, - const nghttp2_vec *vec, size_t veclen, - const nghttp2_nv *nv, size_t nvlen) { - nghttp2_bufs bufs; - int rv; - nghttp2_mem *mem; - size_t buflen; - - mem = deflater->ctx.mem; - - rv = nghttp2_bufs_wrap_init2(&bufs, vec, veclen, mem); - - if (rv != 0) { - return rv; - } - - rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nv, nvlen); - - buflen = nghttp2_bufs_len(&bufs); - - nghttp2_bufs_wrap_free(&bufs); - - if (rv == NGHTTP2_ERR_BUFFER_ERROR) { - return NGHTTP2_ERR_INSUFF_BUFSIZE; - } - - if (rv != 0) { - return rv; - } - - return (nghttp2_ssize)buflen; -} - -size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater, - const nghttp2_nv *nva, size_t nvlen) { - size_t n = 0; - size_t i; - (void)deflater; - - /* Possible Maximum Header Table Size Change. Encoding (1u << 31) - - 1 using 4 bit prefix requires 6 bytes. We may emit this at most - twice. */ - n += 12; - - /* Use Literal Header Field without indexing - New Name, since it is - most space consuming format. Also we choose the less one between - non-huffman and huffman, so using literal byte count is - sufficient for upper bound. - - Encoding (1u << 31) - 1 using 7 bit prefix requires 6 bytes. We - need 2 of this for |nvlen| header fields. */ - n += 6 * 2 * nvlen; - - for (i = 0; i < nvlen; ++i) { - n += nva[i].namelen + nva[i].valuelen; - } - - return n; -} - -int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr, - size_t deflate_hd_table_bufsize_max) { - return nghttp2_hd_deflate_new2(deflater_ptr, deflate_hd_table_bufsize_max, - NULL); -} - -int nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr, - size_t deflate_hd_table_bufsize_max, - nghttp2_mem *mem) { - int rv; - nghttp2_hd_deflater *deflater; - - if (mem == NULL) { - mem = nghttp2_mem_default(); - } - - deflater = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_deflater)); - - if (deflater == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - rv = nghttp2_hd_deflate_init2(deflater, deflate_hd_table_bufsize_max, mem); - - if (rv != 0) { - nghttp2_mem_free(mem, deflater); - - return rv; - } - - *deflater_ptr = deflater; - - return 0; -} - -void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater) { - nghttp2_mem *mem; - - mem = deflater->ctx.mem; - - nghttp2_hd_deflate_free(deflater); - - nghttp2_mem_free(mem, deflater); -} - -static void hd_inflate_set_huffman_encoded(nghttp2_hd_inflater *inflater, - const uint8_t *in) { - inflater->huffman_encoded = (*in & (1 << 7)) != 0; -} - -/* - * Decodes the integer from the range [in, last). The result is - * assigned to |inflater->left|. If the |inflater->left| is 0, then - * it performs variable integer decoding from scratch. Otherwise, it - * uses the |inflater->left| as the initial value and continues to - * decode assuming that [in, last) begins with intermediary sequence. - * - * This function returns the number of bytes read if it succeeds, or - * one of the following negative error codes: - * - * NGHTTP2_ERR_HEADER_COMP - * Integer decoding failed - */ -static nghttp2_ssize hd_inflate_read_len(nghttp2_hd_inflater *inflater, - int *rfin, const uint8_t *in, - const uint8_t *last, size_t prefix, - size_t maxlen) { - nghttp2_ssize rv; - uint32_t out; - - *rfin = 0; - - rv = decode_length(&out, &inflater->shift, rfin, (uint32_t)inflater->left, - inflater->shift, in, last, prefix); - - if (rv == -1) { - DEBUGF("inflatehd: integer decoding failed\n"); - return NGHTTP2_ERR_HEADER_COMP; - } - - if (out > maxlen) { - DEBUGF("inflatehd: integer exceeded the maximum value %zu\n", maxlen); - return NGHTTP2_ERR_HEADER_COMP; - } - - inflater->left = out; - - DEBUGF("inflatehd: decoded integer is %u\n", out); - - return rv; -} - -/* - * Reads |inflater->left| bytes from the range [in, last) and performs - * huffman decoding against them and pushes the result into the - * |buffer|. - * - * This function returns the number of bytes read if it succeeds, or - * one of the following negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - * NGHTTP2_ERR_HEADER_COMP - * Huffman decoding failed - */ -static nghttp2_ssize hd_inflate_read_huff(nghttp2_hd_inflater *inflater, - nghttp2_buf *buf, const uint8_t *in, - const uint8_t *last) { - nghttp2_ssize readlen; - int fin = 0; - if ((size_t)(last - in) >= inflater->left) { - last = in + inflater->left; - fin = 1; - } - readlen = nghttp2_hd_huff_decode(&inflater->huff_decode_ctx, buf, in, - (size_t)(last - in), fin); - - if (readlen < 0) { - DEBUGF("inflatehd: huffman decoding failed\n"); - return readlen; - } - if (nghttp2_hd_huff_decode_failure_state(&inflater->huff_decode_ctx)) { - DEBUGF("inflatehd: huffman decoding failed\n"); - return NGHTTP2_ERR_HEADER_COMP; - } - - inflater->left -= (size_t)readlen; - return readlen; -} - -/* - * Reads |inflater->left| bytes from the range [in, last) and copies - * them into the |buffer|. - * - * This function returns the number of bytes read if it succeeds, or - * one of the following negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - * NGHTTP2_ERR_HEADER_COMP - * Header decompression failed - */ -static nghttp2_ssize hd_inflate_read(nghttp2_hd_inflater *inflater, - nghttp2_buf *buf, const uint8_t *in, - const uint8_t *last) { - size_t len = nghttp2_min_size((size_t)(last - in), inflater->left); - - buf->last = nghttp2_cpymem(buf->last, in, len); - - inflater->left -= len; - return (nghttp2_ssize)len; -} - -/* - * Finalize indexed header representation reception. The referenced - * header is always emitted, and |*nv_out| is filled with that value. - */ -static void hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater, - nghttp2_hd_nv *nv_out) { - nghttp2_hd_nv nv = nghttp2_hd_table_get(&inflater->ctx, inflater->index); - - emit_header(nv_out, &nv); -} - -/* - * Finalize literal header representation - new name- reception. If - * header is emitted, |*nv_out| is filled with that value and 0 is - * returned. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater, - nghttp2_hd_nv *nv_out) { - nghttp2_hd_nv nv; - int rv; - - if (inflater->no_index) { - nv.flags = NGHTTP2_NV_FLAG_NO_INDEX; - } else { - nv.flags = NGHTTP2_NV_FLAG_NONE; - } - - nv.name = inflater->namercbuf; - nv.value = inflater->valuercbuf; - nv.token = lookup_token(inflater->namercbuf->base, inflater->namercbuf->len); - - if (inflater->index_required) { - rv = add_hd_table_incremental(&inflater->ctx, &nv, NULL, 0); - - if (rv != 0) { - return rv; - } - } - - emit_header(nv_out, &nv); - - inflater->nv_name_keep = nv.name; - inflater->nv_value_keep = nv.value; - - inflater->namercbuf = NULL; - inflater->valuercbuf = NULL; - - return 0; -} - -/* - * Finalize literal header representation - indexed name- - * reception. If header is emitted, |*nv_out| is filled with that - * value and 0 is returned. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater, - nghttp2_hd_nv *nv_out) { - nghttp2_hd_nv nv; - int rv; - - nv = nghttp2_hd_table_get(&inflater->ctx, inflater->index); - - if (inflater->no_index) { - nv.flags = NGHTTP2_NV_FLAG_NO_INDEX; - } else { - nv.flags = NGHTTP2_NV_FLAG_NONE; - } - - nghttp2_rcbuf_incref(nv.name); - - nv.value = inflater->valuercbuf; - - if (inflater->index_required) { - rv = add_hd_table_incremental(&inflater->ctx, &nv, NULL, 0); - if (rv != 0) { - nghttp2_rcbuf_decref(nv.name); - return NGHTTP2_ERR_NOMEM; - } - } - - emit_header(nv_out, &nv); - - inflater->nv_name_keep = nv.name; - inflater->nv_value_keep = nv.value; - - inflater->valuercbuf = NULL; - - return 0; -} - -ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, - int *inflate_flags, uint8_t *in, size_t inlen, - int in_final) { - return nghttp2_hd_inflate_hd2(inflater, nv_out, inflate_flags, in, inlen, - in_final); -} - -ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater, - nghttp2_nv *nv_out, int *inflate_flags, - const uint8_t *in, size_t inlen, int in_final) { - return (nghttp2_ssize)nghttp2_hd_inflate_hd3(inflater, nv_out, inflate_flags, - in, inlen, in_final); -} - -nghttp2_ssize nghttp2_hd_inflate_hd3(nghttp2_hd_inflater *inflater, - nghttp2_nv *nv_out, int *inflate_flags, - const uint8_t *in, size_t inlen, - int in_final) { - nghttp2_ssize rv; - nghttp2_hd_nv hd_nv; - - rv = nghttp2_hd_inflate_hd_nv(inflater, &hd_nv, inflate_flags, in, inlen, - in_final); - - if (rv < 0) { - return rv; - } - - if (*inflate_flags & NGHTTP2_HD_INFLATE_EMIT) { - nv_out->name = hd_nv.name->base; - nv_out->namelen = hd_nv.name->len; - - nv_out->value = hd_nv.value->base; - nv_out->valuelen = hd_nv.value->len; - - nv_out->flags = hd_nv.flags; - } - - return rv; -} - -nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, - nghttp2_hd_nv *nv_out, - int *inflate_flags, const uint8_t *in, - size_t inlen, int in_final) { - nghttp2_ssize rv = 0; - const uint8_t *first = in; - const uint8_t *last = in + inlen; - int rfin = 0; - int busy = 0; - nghttp2_mem *mem; - - mem = inflater->ctx.mem; - - if (inflater->ctx.bad) { - return NGHTTP2_ERR_HEADER_COMP; - } - - DEBUGF("inflatehd: start state=%d\n", inflater->state); - hd_inflate_keep_free(inflater); - *inflate_flags = NGHTTP2_HD_INFLATE_NONE; - for (; in != last || busy;) { - busy = 0; - switch (inflater->state) { - case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE: - if ((*in & 0xe0u) != 0x20u) { - DEBUGF("inflatehd: header table size change was expected, but saw " - "0x%02x as first byte", - *in); - rv = NGHTTP2_ERR_HEADER_COMP; - goto fail; - } - /* fall through */ - case NGHTTP2_HD_STATE_INFLATE_START: - case NGHTTP2_HD_STATE_OPCODE: - if ((*in & 0xe0u) == 0x20u) { - DEBUGF("inflatehd: header table size change\n"); - if (inflater->state == NGHTTP2_HD_STATE_OPCODE) { - DEBUGF("inflatehd: header table size change must appear at the head " - "of header block\n"); - rv = NGHTTP2_ERR_HEADER_COMP; - goto fail; - } - inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED; - inflater->state = NGHTTP2_HD_STATE_READ_TABLE_SIZE; - } else if (*in & 0x80u) { - DEBUGF("inflatehd: indexed repr\n"); - inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED; - inflater->state = NGHTTP2_HD_STATE_READ_INDEX; - } else { - if (*in == 0x40u || *in == 0 || *in == 0x10u) { - DEBUGF("inflatehd: literal header repr - new name\n"); - inflater->opcode = NGHTTP2_HD_OPCODE_NEWNAME; - inflater->state = NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN; - } else { - DEBUGF("inflatehd: literal header repr - indexed name\n"); - inflater->opcode = NGHTTP2_HD_OPCODE_INDNAME; - inflater->state = NGHTTP2_HD_STATE_READ_INDEX; - } - inflater->index_required = (*in & 0x40) != 0; - inflater->no_index = (*in & 0xf0u) == 0x10u; - DEBUGF("inflatehd: indexing required=%d, no_index=%d\n", - inflater->index_required, inflater->no_index); - if (inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) { - ++in; - } - } - inflater->left = 0; - inflater->shift = 0; - break; - case NGHTTP2_HD_STATE_READ_TABLE_SIZE: - rfin = 0; - rv = hd_inflate_read_len( - inflater, &rfin, in, last, 5, - nghttp2_min_size(inflater->min_hd_table_bufsize_max, - inflater->settings_hd_table_bufsize_max)); - if (rv < 0) { - goto fail; - } - in += rv; - if (!rfin) { - goto almost_ok; - } - DEBUGF("inflatehd: table_size=%zu\n", inflater->left); - inflater->min_hd_table_bufsize_max = UINT32_MAX; - inflater->ctx.hd_table_bufsize_max = inflater->left; - hd_context_shrink_table_size(&inflater->ctx, NULL); - inflater->state = NGHTTP2_HD_STATE_INFLATE_START; - break; - case NGHTTP2_HD_STATE_READ_INDEX: { - size_t prefixlen; - - if (inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED) { - prefixlen = 7; - } else if (inflater->index_required) { - prefixlen = 6; - } else { - prefixlen = 4; - } - - rfin = 0; - rv = hd_inflate_read_len(inflater, &rfin, in, last, prefixlen, - get_max_index(&inflater->ctx)); - if (rv < 0) { - goto fail; - } - - in += rv; - - if (!rfin) { - goto almost_ok; - } - - if (inflater->left == 0) { - rv = NGHTTP2_ERR_HEADER_COMP; - goto fail; - } - - DEBUGF("inflatehd: index=%zu\n", inflater->left); - if (inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED) { - inflater->index = inflater->left; - --inflater->index; - - hd_inflate_commit_indexed(inflater, nv_out); - - inflater->state = NGHTTP2_HD_STATE_OPCODE; - *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT; - return (nghttp2_ssize)(in - first); - } else { - inflater->index = inflater->left; - --inflater->index; - - inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN; - } - break; - } - case NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN: - hd_inflate_set_huffman_encoded(inflater, in); - inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN; - inflater->left = 0; - inflater->shift = 0; - DEBUGF("inflatehd: huffman encoded=%d\n", inflater->huffman_encoded != 0); - /* Fall through */ - case NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN: - rfin = 0; - rv = hd_inflate_read_len(inflater, &rfin, in, last, 7, NGHTTP2_HD_MAX_NV); - if (rv < 0) { - goto fail; - } - in += rv; - if (!rfin) { - DEBUGF("inflatehd: integer not fully decoded. current=%zu\n", - inflater->left); - - goto almost_ok; - } - - if (inflater->huffman_encoded) { - nghttp2_hd_huff_decode_context_init(&inflater->huff_decode_ctx); - - inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF; - - rv = - nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, mem); - } else { - inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME; - rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left + 1, mem); - } - - if (rv != 0) { - goto fail; - } - - nghttp2_buf_wrap_init(&inflater->namebuf, inflater->namercbuf->base, - inflater->namercbuf->len); - - break; - case NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF: - rv = hd_inflate_read_huff(inflater, &inflater->namebuf, in, last); - if (rv < 0) { - goto fail; - } - - in += rv; - - DEBUGF("inflatehd: %td bytes read\n", rv); - - if (inflater->left) { - DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); - - goto almost_ok; - } - - *inflater->namebuf.last = '\0'; - inflater->namercbuf->len = nghttp2_buf_len(&inflater->namebuf); - - inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN; - - break; - case NGHTTP2_HD_STATE_NEWNAME_READ_NAME: - rv = hd_inflate_read(inflater, &inflater->namebuf, in, last); - if (rv < 0) { - goto fail; - } - - in += rv; - - DEBUGF("inflatehd: %td bytes read\n", rv); - if (inflater->left) { - DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); - - goto almost_ok; - } - - *inflater->namebuf.last = '\0'; - inflater->namercbuf->len = nghttp2_buf_len(&inflater->namebuf); - - inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN; - - break; - case NGHTTP2_HD_STATE_CHECK_VALUELEN: - hd_inflate_set_huffman_encoded(inflater, in); - inflater->state = NGHTTP2_HD_STATE_READ_VALUELEN; - inflater->left = 0; - inflater->shift = 0; - DEBUGF("inflatehd: huffman encoded=%d\n", inflater->huffman_encoded != 0); - /* Fall through */ - case NGHTTP2_HD_STATE_READ_VALUELEN: - rfin = 0; - rv = hd_inflate_read_len(inflater, &rfin, in, last, 7, NGHTTP2_HD_MAX_NV); - if (rv < 0) { - goto fail; - } - - in += rv; - - if (!rfin) { - goto almost_ok; - } - - DEBUGF("inflatehd: valuelen=%zu\n", inflater->left); - - if (inflater->huffman_encoded) { - nghttp2_hd_huff_decode_context_init(&inflater->huff_decode_ctx); - - inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF; - - rv = - nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, mem); - } else { - inflater->state = NGHTTP2_HD_STATE_READ_VALUE; - - rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left + 1, mem); - } - - if (rv != 0) { - goto fail; - } - - nghttp2_buf_wrap_init(&inflater->valuebuf, inflater->valuercbuf->base, - inflater->valuercbuf->len); - - busy = 1; - - break; - case NGHTTP2_HD_STATE_READ_VALUEHUFF: - rv = hd_inflate_read_huff(inflater, &inflater->valuebuf, in, last); - if (rv < 0) { - goto fail; - } - - in += rv; - - DEBUGF("inflatehd: %td bytes read\n", rv); - - if (inflater->left) { - DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); - - goto almost_ok; - } - - *inflater->valuebuf.last = '\0'; - inflater->valuercbuf->len = nghttp2_buf_len(&inflater->valuebuf); - - if (inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) { - rv = hd_inflate_commit_newname(inflater, nv_out); - } else { - rv = hd_inflate_commit_indname(inflater, nv_out); - } - - if (rv != 0) { - goto fail; - } - - inflater->state = NGHTTP2_HD_STATE_OPCODE; - *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT; - - return (nghttp2_ssize)(in - first); - case NGHTTP2_HD_STATE_READ_VALUE: - rv = hd_inflate_read(inflater, &inflater->valuebuf, in, last); - if (rv < 0) { - DEBUGF("inflatehd: value read failure %td: %s\n", rv, - nghttp2_strerror((int)rv)); - goto fail; - } - - in += rv; - - DEBUGF("inflatehd: %td bytes read\n", rv); - - if (inflater->left) { - DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); - goto almost_ok; - } - - *inflater->valuebuf.last = '\0'; - inflater->valuercbuf->len = nghttp2_buf_len(&inflater->valuebuf); - - if (inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) { - rv = hd_inflate_commit_newname(inflater, nv_out); - } else { - rv = hd_inflate_commit_indname(inflater, nv_out); - } - - if (rv != 0) { - goto fail; - } - - inflater->state = NGHTTP2_HD_STATE_OPCODE; - *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT; - - return (nghttp2_ssize)(in - first); - } - } - - assert(in == last); - - DEBUGF("inflatehd: all input bytes were processed\n"); - - if (in_final) { - DEBUGF("inflatehd: in_final set\n"); - - if (inflater->state != NGHTTP2_HD_STATE_OPCODE && - inflater->state != NGHTTP2_HD_STATE_INFLATE_START) { - DEBUGF("inflatehd: unacceptable state=%d\n", inflater->state); - rv = NGHTTP2_ERR_HEADER_COMP; - - goto fail; - } - *inflate_flags |= NGHTTP2_HD_INFLATE_FINAL; - } - return (nghttp2_ssize)(in - first); - -almost_ok: - if (in_final) { - DEBUGF("inflatehd: input ended prematurely\n"); - - rv = NGHTTP2_ERR_HEADER_COMP; - - goto fail; - } - return (nghttp2_ssize)(in - first); - -fail: - DEBUGF("inflatehd: error return %td\n", rv); - - inflater->ctx.bad = 1; - return rv; -} - -int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater) { - hd_inflate_keep_free(inflater); - inflater->state = NGHTTP2_HD_STATE_INFLATE_START; - return 0; -} - -int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr) { - return nghttp2_hd_inflate_new2(inflater_ptr, NULL); -} - -int nghttp2_hd_inflate_new2(nghttp2_hd_inflater **inflater_ptr, - nghttp2_mem *mem) { - int rv; - nghttp2_hd_inflater *inflater; - - if (mem == NULL) { - mem = nghttp2_mem_default(); - } - - inflater = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_inflater)); - - if (inflater == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - rv = nghttp2_hd_inflate_init(inflater, mem); - - if (rv != 0) { - nghttp2_mem_free(mem, inflater); - - return rv; - } - - *inflater_ptr = inflater; - - return 0; -} - -void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater) { - nghttp2_mem *mem; - - mem = inflater->ctx.mem; - nghttp2_hd_inflate_free(inflater); - - nghttp2_mem_free(mem, inflater); -} - -int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t idx, - nghttp2_nv *nv, int indexing_mode) { - return emit_indname_block(bufs, idx, nv, indexing_mode); -} - -int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv, - int indexing_mode) { - return emit_newname_block(bufs, nv, indexing_mode); -} - -int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size) { - return emit_table_size(bufs, table_size); -} - -nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, - int *fin, uint32_t initial, size_t shift, - uint8_t *in, uint8_t *last, - size_t prefix) { - return decode_length(res, shift_ptr, fin, initial, shift, in, last, prefix); -} - -static const nghttp2_nv *hd_get_table_entry(nghttp2_hd_context *context, - size_t idx) { - if (idx == 0) { - return NULL; - } - - --idx; - - if (!INDEX_RANGE_VALID(context, idx)) { - return NULL; - } - - return nghttp2_hd_table_get2(context, idx); -} - -size_t nghttp2_hd_deflate_get_num_table_entries(nghttp2_hd_deflater *deflater) { - return get_max_index(&deflater->ctx); -} - -const nghttp2_nv * -nghttp2_hd_deflate_get_table_entry(nghttp2_hd_deflater *deflater, size_t idx) { - return hd_get_table_entry(&deflater->ctx, idx); -} - -size_t -nghttp2_hd_deflate_get_dynamic_table_size(nghttp2_hd_deflater *deflater) { - return deflater->ctx.hd_table_bufsize; -} - -size_t -nghttp2_hd_deflate_get_max_dynamic_table_size(nghttp2_hd_deflater *deflater) { - return deflater->ctx.hd_table_bufsize_max; -} - -size_t nghttp2_hd_inflate_get_num_table_entries(nghttp2_hd_inflater *inflater) { - return get_max_index(&inflater->ctx); -} - -const nghttp2_nv * -nghttp2_hd_inflate_get_table_entry(nghttp2_hd_inflater *inflater, size_t idx) { - return hd_get_table_entry(&inflater->ctx, idx); -} - -size_t -nghttp2_hd_inflate_get_dynamic_table_size(nghttp2_hd_inflater *inflater) { - return inflater->ctx.hd_table_bufsize; -} - -size_t -nghttp2_hd_inflate_get_max_dynamic_table_size(nghttp2_hd_inflater *inflater) { - return inflater->ctx.hd_table_bufsize_max; -} diff --git a/vendor/nghttp2/lib/nghttp2_hd.h b/vendor/nghttp2/lib/nghttp2_hd.h deleted file mode 100644 index 38a31a83c..000000000 --- a/vendor/nghttp2/lib/nghttp2_hd.h +++ /dev/null @@ -1,442 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_HD_H -#define NGHTTP2_HD_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -#include "nghttp2_hd_huffman.h" -#include "nghttp2_buf.h" -#include "nghttp2_mem.h" -#include "nghttp2_rcbuf.h" - -#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE -#define NGHTTP2_HD_ENTRY_OVERHEAD 32 - -/* The maximum length of one name/value pair. This is the sum of the - length of name and value. This is not specified by the spec. We - just chose the arbitrary size */ -#define NGHTTP2_HD_MAX_NV 65536 - -/* Default size of maximum table buffer size for encoder. Even if - remote decoder notifies larger buffer size for its decoding, - encoder only uses the memory up to this value. */ -#define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12) - -/* Exported for unit test */ -#define NGHTTP2_STATIC_TABLE_LENGTH 61 - -/* Generated by genlibtokenlookup.py */ -typedef enum { - NGHTTP2_TOKEN__AUTHORITY = 0, - NGHTTP2_TOKEN__METHOD = 1, - NGHTTP2_TOKEN__PATH = 3, - NGHTTP2_TOKEN__SCHEME = 5, - NGHTTP2_TOKEN__STATUS = 7, - NGHTTP2_TOKEN_ACCEPT_CHARSET = 14, - NGHTTP2_TOKEN_ACCEPT_ENCODING = 15, - NGHTTP2_TOKEN_ACCEPT_LANGUAGE = 16, - NGHTTP2_TOKEN_ACCEPT_RANGES = 17, - NGHTTP2_TOKEN_ACCEPT = 18, - NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN = 19, - NGHTTP2_TOKEN_AGE = 20, - NGHTTP2_TOKEN_ALLOW = 21, - NGHTTP2_TOKEN_AUTHORIZATION = 22, - NGHTTP2_TOKEN_CACHE_CONTROL = 23, - NGHTTP2_TOKEN_CONTENT_DISPOSITION = 24, - NGHTTP2_TOKEN_CONTENT_ENCODING = 25, - NGHTTP2_TOKEN_CONTENT_LANGUAGE = 26, - NGHTTP2_TOKEN_CONTENT_LENGTH = 27, - NGHTTP2_TOKEN_CONTENT_LOCATION = 28, - NGHTTP2_TOKEN_CONTENT_RANGE = 29, - NGHTTP2_TOKEN_CONTENT_TYPE = 30, - NGHTTP2_TOKEN_COOKIE = 31, - NGHTTP2_TOKEN_DATE = 32, - NGHTTP2_TOKEN_ETAG = 33, - NGHTTP2_TOKEN_EXPECT = 34, - NGHTTP2_TOKEN_EXPIRES = 35, - NGHTTP2_TOKEN_FROM = 36, - NGHTTP2_TOKEN_HOST = 37, - NGHTTP2_TOKEN_IF_MATCH = 38, - NGHTTP2_TOKEN_IF_MODIFIED_SINCE = 39, - NGHTTP2_TOKEN_IF_NONE_MATCH = 40, - NGHTTP2_TOKEN_IF_RANGE = 41, - NGHTTP2_TOKEN_IF_UNMODIFIED_SINCE = 42, - NGHTTP2_TOKEN_LAST_MODIFIED = 43, - NGHTTP2_TOKEN_LINK = 44, - NGHTTP2_TOKEN_LOCATION = 45, - NGHTTP2_TOKEN_MAX_FORWARDS = 46, - NGHTTP2_TOKEN_PROXY_AUTHENTICATE = 47, - NGHTTP2_TOKEN_PROXY_AUTHORIZATION = 48, - NGHTTP2_TOKEN_RANGE = 49, - NGHTTP2_TOKEN_REFERER = 50, - NGHTTP2_TOKEN_REFRESH = 51, - NGHTTP2_TOKEN_RETRY_AFTER = 52, - NGHTTP2_TOKEN_SERVER = 53, - NGHTTP2_TOKEN_SET_COOKIE = 54, - NGHTTP2_TOKEN_STRICT_TRANSPORT_SECURITY = 55, - NGHTTP2_TOKEN_TRANSFER_ENCODING = 56, - NGHTTP2_TOKEN_USER_AGENT = 57, - NGHTTP2_TOKEN_VARY = 58, - NGHTTP2_TOKEN_VIA = 59, - NGHTTP2_TOKEN_WWW_AUTHENTICATE = 60, - NGHTTP2_TOKEN_TE, - NGHTTP2_TOKEN_CONNECTION, - NGHTTP2_TOKEN_KEEP_ALIVE, - NGHTTP2_TOKEN_PROXY_CONNECTION, - NGHTTP2_TOKEN_UPGRADE, - NGHTTP2_TOKEN__PROTOCOL, - NGHTTP2_TOKEN_PRIORITY, -} nghttp2_token; - -struct nghttp2_hd_entry; -typedef struct nghttp2_hd_entry nghttp2_hd_entry; - -typedef struct { - /* The buffer containing header field name. NULL-termination is - guaranteed. */ - nghttp2_rcbuf *name; - /* The buffer containing header field value. NULL-termination is - guaranteed. */ - nghttp2_rcbuf *value; - /* nghttp2_token value for name. It could be -1 if we have no token - for that header field name. */ - int32_t token; - /* Bitwise OR of one or more of nghttp2_nv_flag. */ - uint8_t flags; -} nghttp2_hd_nv; - -struct nghttp2_hd_entry { - /* The header field name/value pair */ - nghttp2_hd_nv nv; - /* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry - APIs to keep backward compatibility. */ - nghttp2_nv cnv; - /* The next entry which shares same bucket in hash table. */ - nghttp2_hd_entry *next; - /* The sequence number. We will increment it by one whenever we - store nghttp2_hd_entry to dynamic header table. */ - uint32_t seq; - /* The hash value for header name (nv.name). */ - uint32_t hash; -}; - -/* The entry used for static header table. */ -typedef struct { - nghttp2_rcbuf name; - nghttp2_rcbuf value; - nghttp2_nv cnv; - int32_t token; - uint32_t hash; -} nghttp2_hd_static_entry; - -typedef struct { - nghttp2_hd_entry **buffer; - size_t mask; - size_t first; - size_t len; -} nghttp2_hd_ringbuf; - -typedef enum { - NGHTTP2_HD_OPCODE_NONE, - NGHTTP2_HD_OPCODE_INDEXED, - NGHTTP2_HD_OPCODE_NEWNAME, - NGHTTP2_HD_OPCODE_INDNAME -} nghttp2_hd_opcode; - -typedef enum { - NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE, - NGHTTP2_HD_STATE_INFLATE_START, - NGHTTP2_HD_STATE_OPCODE, - NGHTTP2_HD_STATE_READ_TABLE_SIZE, - NGHTTP2_HD_STATE_READ_INDEX, - NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN, - NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN, - NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF, - NGHTTP2_HD_STATE_NEWNAME_READ_NAME, - NGHTTP2_HD_STATE_CHECK_VALUELEN, - NGHTTP2_HD_STATE_READ_VALUELEN, - NGHTTP2_HD_STATE_READ_VALUEHUFF, - NGHTTP2_HD_STATE_READ_VALUE -} nghttp2_hd_inflate_state; - -typedef enum { - NGHTTP2_HD_WITH_INDEXING, - NGHTTP2_HD_WITHOUT_INDEXING, - NGHTTP2_HD_NEVER_INDEXING -} nghttp2_hd_indexing_mode; - -typedef struct { - /* dynamic header table */ - nghttp2_hd_ringbuf hd_table; - /* Memory allocator */ - nghttp2_mem *mem; - /* Abstract buffer size of hd_table as described in the spec. This - is the sum of length of name/value in hd_table + - NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */ - size_t hd_table_bufsize; - /* The effective header table size. */ - size_t hd_table_bufsize_max; - /* Next sequence number for nghttp2_hd_entry */ - uint32_t next_seq; - /* If inflate/deflate error occurred, this value is set to 1 and - further invocation of inflate/deflate will fail with - NGHTTP2_ERR_HEADER_COMP. */ - uint8_t bad; -} nghttp2_hd_context; - -#define HD_MAP_SIZE 128 - -typedef struct { - nghttp2_hd_entry *table[HD_MAP_SIZE]; -} nghttp2_hd_map; - -struct nghttp2_hd_deflater { - nghttp2_hd_context ctx; - nghttp2_hd_map map; - /* The upper limit of the header table size the deflater accepts. */ - size_t deflate_hd_table_bufsize_max; - /* Minimum header table size notified in the next context update */ - size_t min_hd_table_bufsize_max; - /* If nonzero, send header table size using encoding context update - in the next deflate process */ - uint8_t notify_table_size_change; -}; - -struct nghttp2_hd_inflater { - nghttp2_hd_context ctx; - /* Stores current state of huffman decoding */ - nghttp2_hd_huff_decode_context huff_decode_ctx; - /* header buffer */ - nghttp2_buf namebuf, valuebuf; - nghttp2_rcbuf *namercbuf, *valuercbuf; - /* Pointer to the name/value pair which are used in the current - header emission. */ - nghttp2_rcbuf *nv_name_keep, *nv_value_keep; - /* The number of bytes to read */ - size_t left; - /* The index in indexed repr or indexed name */ - size_t index; - /* The maximum header table size the inflater supports. This is the - same value transmitted in SETTINGS_HEADER_TABLE_SIZE */ - size_t settings_hd_table_bufsize_max; - /* Minimum header table size set by nghttp2_hd_inflate_change_table_size */ - size_t min_hd_table_bufsize_max; - /* The number of next shift to decode integer */ - size_t shift; - nghttp2_hd_opcode opcode; - nghttp2_hd_inflate_state state; - /* nonzero if string is huffman encoded */ - uint8_t huffman_encoded; - /* nonzero if deflater requires that current entry is indexed */ - uint8_t index_required; - /* nonzero if deflater requires that current entry must not be - indexed */ - uint8_t no_index; -}; - -/* - * Initializes the |ent| members. The reference counts of nv->name - * and nv->value are increased by one for each. - */ -void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv); - -/* - * This function decreases the reference counts of nv->name and - * nv->value. - */ -void nghttp2_hd_entry_free(nghttp2_hd_entry *ent); - -/* - * Initializes |deflater| for deflating name/values pairs. - * - * The encoder only uses up to - * NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE bytes for header table - * even if the larger value is specified later in - * nghttp2_hd_change_table_size(). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem); - -/* - * Initializes |deflater| for deflating name/values pairs. - * - * The encoder only uses up to |max_deflate_dynamic_table_size| bytes - * for header table even if the larger value is specified later in - * nghttp2_hd_change_table_size(). - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater, - size_t max_deflate_dynamic_table_size, - nghttp2_mem *mem); - -/* - * Deallocates any resources allocated for |deflater|. - */ -void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater); - -/* - * Deflates the |nva|, which has the |nvlen| name/value pairs, into - * the |bufs|. - * - * This function expands |bufs| as necessary to store the result. If - * buffers is full and the process still requires more space, this - * function fails and returns NGHTTP2_ERR_HEADER_COMP. - * - * After this function returns, it is safe to delete the |nva|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_HEADER_COMP - * Deflation process has failed. - * NGHTTP2_ERR_BUFFER_ERROR - * Out of buffer space. - */ -int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater, - nghttp2_bufs *bufs, const nghttp2_nv *nva, - size_t nvlen); - -/* - * Initializes |inflater| for inflating name/values pairs. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`NGHTTP2_ERR_NOMEM` - * Out of memory. - */ -int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem); - -/* - * Deallocates any resources allocated for |inflater|. - */ -void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater); - -/* - * Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv - * instead of nghttp2_nv as output parameter |nv_out|. Other than - * that return values and semantics are the same as - * nghttp2_hd_inflate_hd(). - */ -nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, - nghttp2_hd_nv *nv_out, - int *inflate_flags, const uint8_t *in, - size_t inlen, int in_final); - -/* For unittesting purpose */ -int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index, - nghttp2_nv *nv, int indexing_mode); - -/* For unittesting purpose */ -int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv, - int indexing_mode); - -/* For unittesting purpose */ -int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size); - -/* For unittesting purpose */ -nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index); - -/* For unittesting purpose */ -nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, - int *fin, uint32_t initial, size_t shift, - uint8_t *in, uint8_t *last, - size_t prefix); - -/* Huffman encoding/decoding functions */ - -/* - * Counts the required bytes to encode |src| with length |len|. - * - * This function returns the number of required bytes to encode given - * data, including padding of prefix of terminal symbol code. This - * function always succeeds. - */ -size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len); - -/* - * Encodes the given data |src| with length |srclen| to the |bufs|. - * This function expands extra buffers in |bufs| if necessary. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_BUFFER_ERROR - * Out of buffer space. - */ -int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src, - size_t srclen); - -void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx); - -/* - * Decodes the given data |src| with length |srclen|. The |ctx| must - * be initialized by nghttp2_hd_huff_decode_context_init(). The result - * will be written to |buf|. This function assumes that |buf| has the - * enough room to store the decoded byte string. - * - * The caller must set the |fin| to nonzero if the given input is the - * final block. - * - * This function returns the number of read bytes from the |in|. - * - * If this function fails, it returns one of the following negative - * return codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_HEADER_COMP - * Decoding process has failed. - */ -nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, - nghttp2_buf *buf, const uint8_t *src, - size_t srclen, int fin); - -/* - * nghttp2_hd_huff_decode_failure_state returns nonzero if |ctx| - * indicates that huffman decoding context is in failure state. - */ -int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx); - -#endif /* NGHTTP2_HD_H */ diff --git a/vendor/nghttp2/lib/nghttp2_hd_huffman.c b/vendor/nghttp2/lib/nghttp2_hd_huffman.c deleted file mode 100644 index de2620076..000000000 --- a/vendor/nghttp2/lib/nghttp2_hd_huffman.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_hd_huffman.h" - -#include -#include -#include - -#include "nghttp2_hd.h" -#include "nghttp2_net.h" - -size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) { - size_t i; - size_t nbits = 0; - - for (i = 0; i < len; ++i) { - nbits += huff_sym_table[src[i]].nbits; - } - /* pad the prefix of EOS (256) */ - return (nbits + 7) / 8; -} - -int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src, - size_t srclen) { - const nghttp2_huff_sym *sym; - const uint8_t *end = src + srclen; - uint64_t code = 0; - uint32_t x; - size_t nbits = 0; - size_t avail; - int rv; - - avail = nghttp2_bufs_cur_avail(bufs); - - for (; src != end;) { - sym = &huff_sym_table[*src++]; - code |= (uint64_t)sym->code << (32 - nbits); - nbits += sym->nbits; - if (nbits < 32) { - continue; - } - if (avail >= 4) { - x = htonl((uint32_t)(code >> 32)); - memcpy(bufs->cur->buf.last, &x, 4); - bufs->cur->buf.last += 4; - avail -= 4; - code <<= 32; - nbits -= 32; - continue; - } - - for (; nbits >= 8;) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56)); - if (rv != 0) { - return rv; - } - code <<= 8; - nbits -= 8; - } - - avail = nghttp2_bufs_cur_avail(bufs); - } - - for (; nbits >= 8;) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56)); - if (rv != 0) { - return rv; - } - code <<= 8; - nbits -= 8; - } - - if (nbits) { - rv = nghttp2_bufs_addb( - bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1))); - if (rv != 0) { - return rv; - } - } - - return 0; -} - -void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) { - ctx->fstate = NGHTTP2_HUFF_ACCEPTED; -} - -nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, - nghttp2_buf *buf, const uint8_t *src, - size_t srclen, int final) { - const uint8_t *end = src + srclen; - nghttp2_huff_decode node = {ctx->fstate, 0}; - const nghttp2_huff_decode *t = &node; - uint8_t c; - - /* We use the decoding algorithm described in - - http://graphics.ics.uci.edu/pub/Prefix.pdf [!!! NO LONGER VALID !!!] - - https://ics.uci.edu/~dan/pubs/Prefix.pdf - - https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */ - for (; src != end;) { - c = *src++; - t = &huff_decode_table[t->fstate & 0x1ff][c >> 4]; - if (t->fstate & NGHTTP2_HUFF_SYM) { - *buf->last++ = t->sym; - } - - t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf]; - if (t->fstate & NGHTTP2_HUFF_SYM) { - *buf->last++ = t->sym; - } - } - - ctx->fstate = t->fstate; - - if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) { - return NGHTTP2_ERR_HEADER_COMP; - } - - return (nghttp2_ssize)srclen; -} - -int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) { - return ctx->fstate == 0x100; -} diff --git a/vendor/nghttp2/lib/nghttp2_hd_huffman.h b/vendor/nghttp2/lib/nghttp2_hd_huffman.h deleted file mode 100644 index 2bfd53181..000000000 --- a/vendor/nghttp2/lib/nghttp2_hd_huffman.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_HD_HUFFMAN_H -#define NGHTTP2_HD_HUFFMAN_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -typedef enum { - /* FSA accepts this state as the end of huffman encoding - sequence. */ - NGHTTP2_HUFF_ACCEPTED = 1 << 14, - /* This state emits symbol */ - NGHTTP2_HUFF_SYM = 1 << 15, -} nghttp2_huff_decode_flag; - -typedef struct { - /* fstate is the current huffman decoding state, which is actually - the node ID of internal huffman tree with - nghttp2_huff_decode_flag OR-ed. We have 257 leaf nodes, but they - are identical to root node other than emitting a symbol, so we - have 256 internal nodes [1..255], inclusive. The node ID 256 is - a special node and it is a terminal state that means decoding - failed. */ - uint16_t fstate; - /* symbol if NGHTTP2_HUFF_SYM flag set */ - uint8_t sym; -} nghttp2_huff_decode; - -typedef nghttp2_huff_decode huff_decode_table_type[16]; - -typedef struct { - /* fstate is the current huffman decoding state. */ - uint16_t fstate; -} nghttp2_hd_huff_decode_context; - -typedef struct { - /* The number of bits in this code */ - uint32_t nbits; - /* Huffman code aligned to LSB */ - uint32_t code; -} nghttp2_huff_sym; - -extern const nghttp2_huff_sym huff_sym_table[]; -extern const nghttp2_huff_decode huff_decode_table[][16]; - -#endif /* NGHTTP2_HD_HUFFMAN_H */ diff --git a/vendor/nghttp2/lib/nghttp2_hd_huffman_data.c b/vendor/nghttp2/lib/nghttp2_hd_huffman_data.c deleted file mode 100644 index c8f4a6fa2..000000000 --- a/vendor/nghttp2/lib/nghttp2_hd_huffman_data.c +++ /dev/null @@ -1,4980 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_hd_huffman.h" - -/* Generated by mkhufftbl.py */ - -const nghttp2_huff_sym huff_sym_table[] = { - {13, 0xffc00000u}, {23, 0xffffb000u}, {28, 0xfffffe20u}, {28, 0xfffffe30u}, - {28, 0xfffffe40u}, {28, 0xfffffe50u}, {28, 0xfffffe60u}, {28, 0xfffffe70u}, - {28, 0xfffffe80u}, {24, 0xffffea00u}, {30, 0xfffffff0u}, {28, 0xfffffe90u}, - {28, 0xfffffea0u}, {30, 0xfffffff4u}, {28, 0xfffffeb0u}, {28, 0xfffffec0u}, - {28, 0xfffffed0u}, {28, 0xfffffee0u}, {28, 0xfffffef0u}, {28, 0xffffff00u}, - {28, 0xffffff10u}, {28, 0xffffff20u}, {30, 0xfffffff8u}, {28, 0xffffff30u}, - {28, 0xffffff40u}, {28, 0xffffff50u}, {28, 0xffffff60u}, {28, 0xffffff70u}, - {28, 0xffffff80u}, {28, 0xffffff90u}, {28, 0xffffffa0u}, {28, 0xffffffb0u}, - {6, 0x50000000u}, {10, 0xfe000000u}, {10, 0xfe400000u}, {12, 0xffa00000u}, - {13, 0xffc80000u}, {6, 0x54000000u}, {8, 0xf8000000u}, {11, 0xff400000u}, - {10, 0xfe800000u}, {10, 0xfec00000u}, {8, 0xf9000000u}, {11, 0xff600000u}, - {8, 0xfa000000u}, {6, 0x58000000u}, {6, 0x5c000000u}, {6, 0x60000000u}, - {5, 0x0u}, {5, 0x8000000u}, {5, 0x10000000u}, {6, 0x64000000u}, - {6, 0x68000000u}, {6, 0x6c000000u}, {6, 0x70000000u}, {6, 0x74000000u}, - {6, 0x78000000u}, {6, 0x7c000000u}, {7, 0xb8000000u}, {8, 0xfb000000u}, - {15, 0xfff80000u}, {6, 0x80000000u}, {12, 0xffb00000u}, {10, 0xff000000u}, - {13, 0xffd00000u}, {6, 0x84000000u}, {7, 0xba000000u}, {7, 0xbc000000u}, - {7, 0xbe000000u}, {7, 0xc0000000u}, {7, 0xc2000000u}, {7, 0xc4000000u}, - {7, 0xc6000000u}, {7, 0xc8000000u}, {7, 0xca000000u}, {7, 0xcc000000u}, - {7, 0xce000000u}, {7, 0xd0000000u}, {7, 0xd2000000u}, {7, 0xd4000000u}, - {7, 0xd6000000u}, {7, 0xd8000000u}, {7, 0xda000000u}, {7, 0xdc000000u}, - {7, 0xde000000u}, {7, 0xe0000000u}, {7, 0xe2000000u}, {7, 0xe4000000u}, - {8, 0xfc000000u}, {7, 0xe6000000u}, {8, 0xfd000000u}, {13, 0xffd80000u}, - {19, 0xfffe0000u}, {13, 0xffe00000u}, {14, 0xfff00000u}, {6, 0x88000000u}, - {15, 0xfffa0000u}, {5, 0x18000000u}, {6, 0x8c000000u}, {5, 0x20000000u}, - {6, 0x90000000u}, {5, 0x28000000u}, {6, 0x94000000u}, {6, 0x98000000u}, - {6, 0x9c000000u}, {5, 0x30000000u}, {7, 0xe8000000u}, {7, 0xea000000u}, - {6, 0xa0000000u}, {6, 0xa4000000u}, {6, 0xa8000000u}, {5, 0x38000000u}, - {6, 0xac000000u}, {7, 0xec000000u}, {6, 0xb0000000u}, {5, 0x40000000u}, - {5, 0x48000000u}, {6, 0xb4000000u}, {7, 0xee000000u}, {7, 0xf0000000u}, - {7, 0xf2000000u}, {7, 0xf4000000u}, {7, 0xf6000000u}, {15, 0xfffc0000u}, - {11, 0xff800000u}, {14, 0xfff40000u}, {13, 0xffe80000u}, {28, 0xffffffc0u}, - {20, 0xfffe6000u}, {22, 0xffff4800u}, {20, 0xfffe7000u}, {20, 0xfffe8000u}, - {22, 0xffff4c00u}, {22, 0xffff5000u}, {22, 0xffff5400u}, {23, 0xffffb200u}, - {22, 0xffff5800u}, {23, 0xffffb400u}, {23, 0xffffb600u}, {23, 0xffffb800u}, - {23, 0xffffba00u}, {23, 0xffffbc00u}, {24, 0xffffeb00u}, {23, 0xffffbe00u}, - {24, 0xffffec00u}, {24, 0xffffed00u}, {22, 0xffff5c00u}, {23, 0xffffc000u}, - {24, 0xffffee00u}, {23, 0xffffc200u}, {23, 0xffffc400u}, {23, 0xffffc600u}, - {23, 0xffffc800u}, {21, 0xfffee000u}, {22, 0xffff6000u}, {23, 0xffffca00u}, - {22, 0xffff6400u}, {23, 0xffffcc00u}, {23, 0xffffce00u}, {24, 0xffffef00u}, - {22, 0xffff6800u}, {21, 0xfffee800u}, {20, 0xfffe9000u}, {22, 0xffff6c00u}, - {22, 0xffff7000u}, {23, 0xffffd000u}, {23, 0xffffd200u}, {21, 0xfffef000u}, - {23, 0xffffd400u}, {22, 0xffff7400u}, {22, 0xffff7800u}, {24, 0xfffff000u}, - {21, 0xfffef800u}, {22, 0xffff7c00u}, {23, 0xffffd600u}, {23, 0xffffd800u}, - {21, 0xffff0000u}, {21, 0xffff0800u}, {22, 0xffff8000u}, {21, 0xffff1000u}, - {23, 0xffffda00u}, {22, 0xffff8400u}, {23, 0xffffdc00u}, {23, 0xffffde00u}, - {20, 0xfffea000u}, {22, 0xffff8800u}, {22, 0xffff8c00u}, {22, 0xffff9000u}, - {23, 0xffffe000u}, {22, 0xffff9400u}, {22, 0xffff9800u}, {23, 0xffffe200u}, - {26, 0xfffff800u}, {26, 0xfffff840u}, {20, 0xfffeb000u}, {19, 0xfffe2000u}, - {22, 0xffff9c00u}, {23, 0xffffe400u}, {22, 0xffffa000u}, {25, 0xfffff600u}, - {26, 0xfffff880u}, {26, 0xfffff8c0u}, {26, 0xfffff900u}, {27, 0xfffffbc0u}, - {27, 0xfffffbe0u}, {26, 0xfffff940u}, {24, 0xfffff100u}, {25, 0xfffff680u}, - {19, 0xfffe4000u}, {21, 0xffff1800u}, {26, 0xfffff980u}, {27, 0xfffffc00u}, - {27, 0xfffffc20u}, {26, 0xfffff9c0u}, {27, 0xfffffc40u}, {24, 0xfffff200u}, - {21, 0xffff2000u}, {21, 0xffff2800u}, {26, 0xfffffa00u}, {26, 0xfffffa40u}, - {28, 0xffffffd0u}, {27, 0xfffffc60u}, {27, 0xfffffc80u}, {27, 0xfffffca0u}, - {20, 0xfffec000u}, {24, 0xfffff300u}, {20, 0xfffed000u}, {21, 0xffff3000u}, - {22, 0xffffa400u}, {21, 0xffff3800u}, {21, 0xffff4000u}, {23, 0xffffe600u}, - {22, 0xffffa800u}, {22, 0xffffac00u}, {25, 0xfffff700u}, {25, 0xfffff780u}, - {24, 0xfffff400u}, {24, 0xfffff500u}, {26, 0xfffffa80u}, {23, 0xffffe800u}, - {26, 0xfffffac0u}, {27, 0xfffffcc0u}, {26, 0xfffffb00u}, {26, 0xfffffb40u}, - {27, 0xfffffce0u}, {27, 0xfffffd00u}, {27, 0xfffffd20u}, {27, 0xfffffd40u}, - {27, 0xfffffd60u}, {28, 0xffffffe0u}, {27, 0xfffffd80u}, {27, 0xfffffda0u}, - {27, 0xfffffdc0u}, {27, 0xfffffde0u}, {27, 0xfffffe00u}, {26, 0xfffffb80u}, - {30, 0xfffffffcu}}; - -const nghttp2_huff_decode huff_decode_table[][16] = { - /* 0 */ - { - {0x04, 0}, - {0x05, 0}, - {0x07, 0}, - {0x08, 0}, - {0x0b, 0}, - {0x0c, 0}, - {0x10, 0}, - {0x13, 0}, - {0x19, 0}, - {0x1c, 0}, - {0x20, 0}, - {0x23, 0}, - {0x2a, 0}, - {0x31, 0}, - {0x39, 0}, - {0x4040, 0}, - }, - /* 1 */ - { - {0xc000, 48}, - {0xc000, 49}, - {0xc000, 50}, - {0xc000, 97}, - {0xc000, 99}, - {0xc000, 101}, - {0xc000, 105}, - {0xc000, 111}, - {0xc000, 115}, - {0xc000, 116}, - {0x0d, 0}, - {0x0e, 0}, - {0x11, 0}, - {0x12, 0}, - {0x14, 0}, - {0x15, 0}, - }, - /* 2 */ - { - {0x8001, 48}, - {0xc016, 48}, - {0x8001, 49}, - {0xc016, 49}, - {0x8001, 50}, - {0xc016, 50}, - {0x8001, 97}, - {0xc016, 97}, - {0x8001, 99}, - {0xc016, 99}, - {0x8001, 101}, - {0xc016, 101}, - {0x8001, 105}, - {0xc016, 105}, - {0x8001, 111}, - {0xc016, 111}, - }, - /* 3 */ - { - {0x8002, 48}, - {0x8009, 48}, - {0x8017, 48}, - {0xc028, 48}, - {0x8002, 49}, - {0x8009, 49}, - {0x8017, 49}, - {0xc028, 49}, - {0x8002, 50}, - {0x8009, 50}, - {0x8017, 50}, - {0xc028, 50}, - {0x8002, 97}, - {0x8009, 97}, - {0x8017, 97}, - {0xc028, 97}, - }, - /* 4 */ - { - {0x8003, 48}, - {0x8006, 48}, - {0x800a, 48}, - {0x800f, 48}, - {0x8018, 48}, - {0x801f, 48}, - {0x8029, 48}, - {0xc038, 48}, - {0x8003, 49}, - {0x8006, 49}, - {0x800a, 49}, - {0x800f, 49}, - {0x8018, 49}, - {0x801f, 49}, - {0x8029, 49}, - {0xc038, 49}, - }, - /* 5 */ - { - {0x8003, 50}, - {0x8006, 50}, - {0x800a, 50}, - {0x800f, 50}, - {0x8018, 50}, - {0x801f, 50}, - {0x8029, 50}, - {0xc038, 50}, - {0x8003, 97}, - {0x8006, 97}, - {0x800a, 97}, - {0x800f, 97}, - {0x8018, 97}, - {0x801f, 97}, - {0x8029, 97}, - {0xc038, 97}, - }, - /* 6 */ - { - {0x8002, 99}, - {0x8009, 99}, - {0x8017, 99}, - {0xc028, 99}, - {0x8002, 101}, - {0x8009, 101}, - {0x8017, 101}, - {0xc028, 101}, - {0x8002, 105}, - {0x8009, 105}, - {0x8017, 105}, - {0xc028, 105}, - {0x8002, 111}, - {0x8009, 111}, - {0x8017, 111}, - {0xc028, 111}, - }, - /* 7 */ - { - {0x8003, 99}, - {0x8006, 99}, - {0x800a, 99}, - {0x800f, 99}, - {0x8018, 99}, - {0x801f, 99}, - {0x8029, 99}, - {0xc038, 99}, - {0x8003, 101}, - {0x8006, 101}, - {0x800a, 101}, - {0x800f, 101}, - {0x8018, 101}, - {0x801f, 101}, - {0x8029, 101}, - {0xc038, 101}, - }, - /* 8 */ - { - {0x8003, 105}, - {0x8006, 105}, - {0x800a, 105}, - {0x800f, 105}, - {0x8018, 105}, - {0x801f, 105}, - {0x8029, 105}, - {0xc038, 105}, - {0x8003, 111}, - {0x8006, 111}, - {0x800a, 111}, - {0x800f, 111}, - {0x8018, 111}, - {0x801f, 111}, - {0x8029, 111}, - {0xc038, 111}, - }, - /* 9 */ - { - {0x8001, 115}, - {0xc016, 115}, - {0x8001, 116}, - {0xc016, 116}, - {0xc000, 32}, - {0xc000, 37}, - {0xc000, 45}, - {0xc000, 46}, - {0xc000, 47}, - {0xc000, 51}, - {0xc000, 52}, - {0xc000, 53}, - {0xc000, 54}, - {0xc000, 55}, - {0xc000, 56}, - {0xc000, 57}, - }, - /* 10 */ - { - {0x8002, 115}, - {0x8009, 115}, - {0x8017, 115}, - {0xc028, 115}, - {0x8002, 116}, - {0x8009, 116}, - {0x8017, 116}, - {0xc028, 116}, - {0x8001, 32}, - {0xc016, 32}, - {0x8001, 37}, - {0xc016, 37}, - {0x8001, 45}, - {0xc016, 45}, - {0x8001, 46}, - {0xc016, 46}, - }, - /* 11 */ - { - {0x8003, 115}, - {0x8006, 115}, - {0x800a, 115}, - {0x800f, 115}, - {0x8018, 115}, - {0x801f, 115}, - {0x8029, 115}, - {0xc038, 115}, - {0x8003, 116}, - {0x8006, 116}, - {0x800a, 116}, - {0x800f, 116}, - {0x8018, 116}, - {0x801f, 116}, - {0x8029, 116}, - {0xc038, 116}, - }, - /* 12 */ - { - {0x8002, 32}, - {0x8009, 32}, - {0x8017, 32}, - {0xc028, 32}, - {0x8002, 37}, - {0x8009, 37}, - {0x8017, 37}, - {0xc028, 37}, - {0x8002, 45}, - {0x8009, 45}, - {0x8017, 45}, - {0xc028, 45}, - {0x8002, 46}, - {0x8009, 46}, - {0x8017, 46}, - {0xc028, 46}, - }, - /* 13 */ - { - {0x8003, 32}, - {0x8006, 32}, - {0x800a, 32}, - {0x800f, 32}, - {0x8018, 32}, - {0x801f, 32}, - {0x8029, 32}, - {0xc038, 32}, - {0x8003, 37}, - {0x8006, 37}, - {0x800a, 37}, - {0x800f, 37}, - {0x8018, 37}, - {0x801f, 37}, - {0x8029, 37}, - {0xc038, 37}, - }, - /* 14 */ - { - {0x8003, 45}, - {0x8006, 45}, - {0x800a, 45}, - {0x800f, 45}, - {0x8018, 45}, - {0x801f, 45}, - {0x8029, 45}, - {0xc038, 45}, - {0x8003, 46}, - {0x8006, 46}, - {0x800a, 46}, - {0x800f, 46}, - {0x8018, 46}, - {0x801f, 46}, - {0x8029, 46}, - {0xc038, 46}, - }, - /* 15 */ - { - {0x8001, 47}, - {0xc016, 47}, - {0x8001, 51}, - {0xc016, 51}, - {0x8001, 52}, - {0xc016, 52}, - {0x8001, 53}, - {0xc016, 53}, - {0x8001, 54}, - {0xc016, 54}, - {0x8001, 55}, - {0xc016, 55}, - {0x8001, 56}, - {0xc016, 56}, - {0x8001, 57}, - {0xc016, 57}, - }, - /* 16 */ - { - {0x8002, 47}, - {0x8009, 47}, - {0x8017, 47}, - {0xc028, 47}, - {0x8002, 51}, - {0x8009, 51}, - {0x8017, 51}, - {0xc028, 51}, - {0x8002, 52}, - {0x8009, 52}, - {0x8017, 52}, - {0xc028, 52}, - {0x8002, 53}, - {0x8009, 53}, - {0x8017, 53}, - {0xc028, 53}, - }, - /* 17 */ - { - {0x8003, 47}, - {0x8006, 47}, - {0x800a, 47}, - {0x800f, 47}, - {0x8018, 47}, - {0x801f, 47}, - {0x8029, 47}, - {0xc038, 47}, - {0x8003, 51}, - {0x8006, 51}, - {0x800a, 51}, - {0x800f, 51}, - {0x8018, 51}, - {0x801f, 51}, - {0x8029, 51}, - {0xc038, 51}, - }, - /* 18 */ - { - {0x8003, 52}, - {0x8006, 52}, - {0x800a, 52}, - {0x800f, 52}, - {0x8018, 52}, - {0x801f, 52}, - {0x8029, 52}, - {0xc038, 52}, - {0x8003, 53}, - {0x8006, 53}, - {0x800a, 53}, - {0x800f, 53}, - {0x8018, 53}, - {0x801f, 53}, - {0x8029, 53}, - {0xc038, 53}, - }, - /* 19 */ - { - {0x8002, 54}, - {0x8009, 54}, - {0x8017, 54}, - {0xc028, 54}, - {0x8002, 55}, - {0x8009, 55}, - {0x8017, 55}, - {0xc028, 55}, - {0x8002, 56}, - {0x8009, 56}, - {0x8017, 56}, - {0xc028, 56}, - {0x8002, 57}, - {0x8009, 57}, - {0x8017, 57}, - {0xc028, 57}, - }, - /* 20 */ - { - {0x8003, 54}, - {0x8006, 54}, - {0x800a, 54}, - {0x800f, 54}, - {0x8018, 54}, - {0x801f, 54}, - {0x8029, 54}, - {0xc038, 54}, - {0x8003, 55}, - {0x8006, 55}, - {0x800a, 55}, - {0x800f, 55}, - {0x8018, 55}, - {0x801f, 55}, - {0x8029, 55}, - {0xc038, 55}, - }, - /* 21 */ - { - {0x8003, 56}, - {0x8006, 56}, - {0x800a, 56}, - {0x800f, 56}, - {0x8018, 56}, - {0x801f, 56}, - {0x8029, 56}, - {0xc038, 56}, - {0x8003, 57}, - {0x8006, 57}, - {0x800a, 57}, - {0x800f, 57}, - {0x8018, 57}, - {0x801f, 57}, - {0x8029, 57}, - {0xc038, 57}, - }, - /* 22 */ - { - {0x1a, 0}, - {0x1b, 0}, - {0x1d, 0}, - {0x1e, 0}, - {0x21, 0}, - {0x22, 0}, - {0x24, 0}, - {0x25, 0}, - {0x2b, 0}, - {0x2e, 0}, - {0x32, 0}, - {0x35, 0}, - {0x3a, 0}, - {0x3d, 0}, - {0x41, 0}, - {0x4044, 0}, - }, - /* 23 */ - { - {0xc000, 61}, - {0xc000, 65}, - {0xc000, 95}, - {0xc000, 98}, - {0xc000, 100}, - {0xc000, 102}, - {0xc000, 103}, - {0xc000, 104}, - {0xc000, 108}, - {0xc000, 109}, - {0xc000, 110}, - {0xc000, 112}, - {0xc000, 114}, - {0xc000, 117}, - {0x26, 0}, - {0x27, 0}, - }, - /* 24 */ - { - {0x8001, 61}, - {0xc016, 61}, - {0x8001, 65}, - {0xc016, 65}, - {0x8001, 95}, - {0xc016, 95}, - {0x8001, 98}, - {0xc016, 98}, - {0x8001, 100}, - {0xc016, 100}, - {0x8001, 102}, - {0xc016, 102}, - {0x8001, 103}, - {0xc016, 103}, - {0x8001, 104}, - {0xc016, 104}, - }, - /* 25 */ - { - {0x8002, 61}, - {0x8009, 61}, - {0x8017, 61}, - {0xc028, 61}, - {0x8002, 65}, - {0x8009, 65}, - {0x8017, 65}, - {0xc028, 65}, - {0x8002, 95}, - {0x8009, 95}, - {0x8017, 95}, - {0xc028, 95}, - {0x8002, 98}, - {0x8009, 98}, - {0x8017, 98}, - {0xc028, 98}, - }, - /* 26 */ - { - {0x8003, 61}, - {0x8006, 61}, - {0x800a, 61}, - {0x800f, 61}, - {0x8018, 61}, - {0x801f, 61}, - {0x8029, 61}, - {0xc038, 61}, - {0x8003, 65}, - {0x8006, 65}, - {0x800a, 65}, - {0x800f, 65}, - {0x8018, 65}, - {0x801f, 65}, - {0x8029, 65}, - {0xc038, 65}, - }, - /* 27 */ - { - {0x8003, 95}, - {0x8006, 95}, - {0x800a, 95}, - {0x800f, 95}, - {0x8018, 95}, - {0x801f, 95}, - {0x8029, 95}, - {0xc038, 95}, - {0x8003, 98}, - {0x8006, 98}, - {0x800a, 98}, - {0x800f, 98}, - {0x8018, 98}, - {0x801f, 98}, - {0x8029, 98}, - {0xc038, 98}, - }, - /* 28 */ - { - {0x8002, 100}, - {0x8009, 100}, - {0x8017, 100}, - {0xc028, 100}, - {0x8002, 102}, - {0x8009, 102}, - {0x8017, 102}, - {0xc028, 102}, - {0x8002, 103}, - {0x8009, 103}, - {0x8017, 103}, - {0xc028, 103}, - {0x8002, 104}, - {0x8009, 104}, - {0x8017, 104}, - {0xc028, 104}, - }, - /* 29 */ - { - {0x8003, 100}, - {0x8006, 100}, - {0x800a, 100}, - {0x800f, 100}, - {0x8018, 100}, - {0x801f, 100}, - {0x8029, 100}, - {0xc038, 100}, - {0x8003, 102}, - {0x8006, 102}, - {0x800a, 102}, - {0x800f, 102}, - {0x8018, 102}, - {0x801f, 102}, - {0x8029, 102}, - {0xc038, 102}, - }, - /* 30 */ - { - {0x8003, 103}, - {0x8006, 103}, - {0x800a, 103}, - {0x800f, 103}, - {0x8018, 103}, - {0x801f, 103}, - {0x8029, 103}, - {0xc038, 103}, - {0x8003, 104}, - {0x8006, 104}, - {0x800a, 104}, - {0x800f, 104}, - {0x8018, 104}, - {0x801f, 104}, - {0x8029, 104}, - {0xc038, 104}, - }, - /* 31 */ - { - {0x8001, 108}, - {0xc016, 108}, - {0x8001, 109}, - {0xc016, 109}, - {0x8001, 110}, - {0xc016, 110}, - {0x8001, 112}, - {0xc016, 112}, - {0x8001, 114}, - {0xc016, 114}, - {0x8001, 117}, - {0xc016, 117}, - {0xc000, 58}, - {0xc000, 66}, - {0xc000, 67}, - {0xc000, 68}, - }, - /* 32 */ - { - {0x8002, 108}, - {0x8009, 108}, - {0x8017, 108}, - {0xc028, 108}, - {0x8002, 109}, - {0x8009, 109}, - {0x8017, 109}, - {0xc028, 109}, - {0x8002, 110}, - {0x8009, 110}, - {0x8017, 110}, - {0xc028, 110}, - {0x8002, 112}, - {0x8009, 112}, - {0x8017, 112}, - {0xc028, 112}, - }, - /* 33 */ - { - {0x8003, 108}, - {0x8006, 108}, - {0x800a, 108}, - {0x800f, 108}, - {0x8018, 108}, - {0x801f, 108}, - {0x8029, 108}, - {0xc038, 108}, - {0x8003, 109}, - {0x8006, 109}, - {0x800a, 109}, - {0x800f, 109}, - {0x8018, 109}, - {0x801f, 109}, - {0x8029, 109}, - {0xc038, 109}, - }, - /* 34 */ - { - {0x8003, 110}, - {0x8006, 110}, - {0x800a, 110}, - {0x800f, 110}, - {0x8018, 110}, - {0x801f, 110}, - {0x8029, 110}, - {0xc038, 110}, - {0x8003, 112}, - {0x8006, 112}, - {0x800a, 112}, - {0x800f, 112}, - {0x8018, 112}, - {0x801f, 112}, - {0x8029, 112}, - {0xc038, 112}, - }, - /* 35 */ - { - {0x8002, 114}, - {0x8009, 114}, - {0x8017, 114}, - {0xc028, 114}, - {0x8002, 117}, - {0x8009, 117}, - {0x8017, 117}, - {0xc028, 117}, - {0x8001, 58}, - {0xc016, 58}, - {0x8001, 66}, - {0xc016, 66}, - {0x8001, 67}, - {0xc016, 67}, - {0x8001, 68}, - {0xc016, 68}, - }, - /* 36 */ - { - {0x8003, 114}, - {0x8006, 114}, - {0x800a, 114}, - {0x800f, 114}, - {0x8018, 114}, - {0x801f, 114}, - {0x8029, 114}, - {0xc038, 114}, - {0x8003, 117}, - {0x8006, 117}, - {0x800a, 117}, - {0x800f, 117}, - {0x8018, 117}, - {0x801f, 117}, - {0x8029, 117}, - {0xc038, 117}, - }, - /* 37 */ - { - {0x8002, 58}, - {0x8009, 58}, - {0x8017, 58}, - {0xc028, 58}, - {0x8002, 66}, - {0x8009, 66}, - {0x8017, 66}, - {0xc028, 66}, - {0x8002, 67}, - {0x8009, 67}, - {0x8017, 67}, - {0xc028, 67}, - {0x8002, 68}, - {0x8009, 68}, - {0x8017, 68}, - {0xc028, 68}, - }, - /* 38 */ - { - {0x8003, 58}, - {0x8006, 58}, - {0x800a, 58}, - {0x800f, 58}, - {0x8018, 58}, - {0x801f, 58}, - {0x8029, 58}, - {0xc038, 58}, - {0x8003, 66}, - {0x8006, 66}, - {0x800a, 66}, - {0x800f, 66}, - {0x8018, 66}, - {0x801f, 66}, - {0x8029, 66}, - {0xc038, 66}, - }, - /* 39 */ - { - {0x8003, 67}, - {0x8006, 67}, - {0x800a, 67}, - {0x800f, 67}, - {0x8018, 67}, - {0x801f, 67}, - {0x8029, 67}, - {0xc038, 67}, - {0x8003, 68}, - {0x8006, 68}, - {0x800a, 68}, - {0x800f, 68}, - {0x8018, 68}, - {0x801f, 68}, - {0x8029, 68}, - {0xc038, 68}, - }, - /* 40 */ - { - {0x2c, 0}, - {0x2d, 0}, - {0x2f, 0}, - {0x30, 0}, - {0x33, 0}, - {0x34, 0}, - {0x36, 0}, - {0x37, 0}, - {0x3b, 0}, - {0x3c, 0}, - {0x3e, 0}, - {0x3f, 0}, - {0x42, 0}, - {0x43, 0}, - {0x45, 0}, - {0x4048, 0}, - }, - /* 41 */ - { - {0xc000, 69}, - {0xc000, 70}, - {0xc000, 71}, - {0xc000, 72}, - {0xc000, 73}, - {0xc000, 74}, - {0xc000, 75}, - {0xc000, 76}, - {0xc000, 77}, - {0xc000, 78}, - {0xc000, 79}, - {0xc000, 80}, - {0xc000, 81}, - {0xc000, 82}, - {0xc000, 83}, - {0xc000, 84}, - }, - /* 42 */ - { - {0x8001, 69}, - {0xc016, 69}, - {0x8001, 70}, - {0xc016, 70}, - {0x8001, 71}, - {0xc016, 71}, - {0x8001, 72}, - {0xc016, 72}, - {0x8001, 73}, - {0xc016, 73}, - {0x8001, 74}, - {0xc016, 74}, - {0x8001, 75}, - {0xc016, 75}, - {0x8001, 76}, - {0xc016, 76}, - }, - /* 43 */ - { - {0x8002, 69}, - {0x8009, 69}, - {0x8017, 69}, - {0xc028, 69}, - {0x8002, 70}, - {0x8009, 70}, - {0x8017, 70}, - {0xc028, 70}, - {0x8002, 71}, - {0x8009, 71}, - {0x8017, 71}, - {0xc028, 71}, - {0x8002, 72}, - {0x8009, 72}, - {0x8017, 72}, - {0xc028, 72}, - }, - /* 44 */ - { - {0x8003, 69}, - {0x8006, 69}, - {0x800a, 69}, - {0x800f, 69}, - {0x8018, 69}, - {0x801f, 69}, - {0x8029, 69}, - {0xc038, 69}, - {0x8003, 70}, - {0x8006, 70}, - {0x800a, 70}, - {0x800f, 70}, - {0x8018, 70}, - {0x801f, 70}, - {0x8029, 70}, - {0xc038, 70}, - }, - /* 45 */ - { - {0x8003, 71}, - {0x8006, 71}, - {0x800a, 71}, - {0x800f, 71}, - {0x8018, 71}, - {0x801f, 71}, - {0x8029, 71}, - {0xc038, 71}, - {0x8003, 72}, - {0x8006, 72}, - {0x800a, 72}, - {0x800f, 72}, - {0x8018, 72}, - {0x801f, 72}, - {0x8029, 72}, - {0xc038, 72}, - }, - /* 46 */ - { - {0x8002, 73}, - {0x8009, 73}, - {0x8017, 73}, - {0xc028, 73}, - {0x8002, 74}, - {0x8009, 74}, - {0x8017, 74}, - {0xc028, 74}, - {0x8002, 75}, - {0x8009, 75}, - {0x8017, 75}, - {0xc028, 75}, - {0x8002, 76}, - {0x8009, 76}, - {0x8017, 76}, - {0xc028, 76}, - }, - /* 47 */ - { - {0x8003, 73}, - {0x8006, 73}, - {0x800a, 73}, - {0x800f, 73}, - {0x8018, 73}, - {0x801f, 73}, - {0x8029, 73}, - {0xc038, 73}, - {0x8003, 74}, - {0x8006, 74}, - {0x800a, 74}, - {0x800f, 74}, - {0x8018, 74}, - {0x801f, 74}, - {0x8029, 74}, - {0xc038, 74}, - }, - /* 48 */ - { - {0x8003, 75}, - {0x8006, 75}, - {0x800a, 75}, - {0x800f, 75}, - {0x8018, 75}, - {0x801f, 75}, - {0x8029, 75}, - {0xc038, 75}, - {0x8003, 76}, - {0x8006, 76}, - {0x800a, 76}, - {0x800f, 76}, - {0x8018, 76}, - {0x801f, 76}, - {0x8029, 76}, - {0xc038, 76}, - }, - /* 49 */ - { - {0x8001, 77}, - {0xc016, 77}, - {0x8001, 78}, - {0xc016, 78}, - {0x8001, 79}, - {0xc016, 79}, - {0x8001, 80}, - {0xc016, 80}, - {0x8001, 81}, - {0xc016, 81}, - {0x8001, 82}, - {0xc016, 82}, - {0x8001, 83}, - {0xc016, 83}, - {0x8001, 84}, - {0xc016, 84}, - }, - /* 50 */ - { - {0x8002, 77}, - {0x8009, 77}, - {0x8017, 77}, - {0xc028, 77}, - {0x8002, 78}, - {0x8009, 78}, - {0x8017, 78}, - {0xc028, 78}, - {0x8002, 79}, - {0x8009, 79}, - {0x8017, 79}, - {0xc028, 79}, - {0x8002, 80}, - {0x8009, 80}, - {0x8017, 80}, - {0xc028, 80}, - }, - /* 51 */ - { - {0x8003, 77}, - {0x8006, 77}, - {0x800a, 77}, - {0x800f, 77}, - {0x8018, 77}, - {0x801f, 77}, - {0x8029, 77}, - {0xc038, 77}, - {0x8003, 78}, - {0x8006, 78}, - {0x800a, 78}, - {0x800f, 78}, - {0x8018, 78}, - {0x801f, 78}, - {0x8029, 78}, - {0xc038, 78}, - }, - /* 52 */ - { - {0x8003, 79}, - {0x8006, 79}, - {0x800a, 79}, - {0x800f, 79}, - {0x8018, 79}, - {0x801f, 79}, - {0x8029, 79}, - {0xc038, 79}, - {0x8003, 80}, - {0x8006, 80}, - {0x800a, 80}, - {0x800f, 80}, - {0x8018, 80}, - {0x801f, 80}, - {0x8029, 80}, - {0xc038, 80}, - }, - /* 53 */ - { - {0x8002, 81}, - {0x8009, 81}, - {0x8017, 81}, - {0xc028, 81}, - {0x8002, 82}, - {0x8009, 82}, - {0x8017, 82}, - {0xc028, 82}, - {0x8002, 83}, - {0x8009, 83}, - {0x8017, 83}, - {0xc028, 83}, - {0x8002, 84}, - {0x8009, 84}, - {0x8017, 84}, - {0xc028, 84}, - }, - /* 54 */ - { - {0x8003, 81}, - {0x8006, 81}, - {0x800a, 81}, - {0x800f, 81}, - {0x8018, 81}, - {0x801f, 81}, - {0x8029, 81}, - {0xc038, 81}, - {0x8003, 82}, - {0x8006, 82}, - {0x800a, 82}, - {0x800f, 82}, - {0x8018, 82}, - {0x801f, 82}, - {0x8029, 82}, - {0xc038, 82}, - }, - /* 55 */ - { - {0x8003, 83}, - {0x8006, 83}, - {0x800a, 83}, - {0x800f, 83}, - {0x8018, 83}, - {0x801f, 83}, - {0x8029, 83}, - {0xc038, 83}, - {0x8003, 84}, - {0x8006, 84}, - {0x800a, 84}, - {0x800f, 84}, - {0x8018, 84}, - {0x801f, 84}, - {0x8029, 84}, - {0xc038, 84}, - }, - /* 56 */ - { - {0xc000, 85}, - {0xc000, 86}, - {0xc000, 87}, - {0xc000, 89}, - {0xc000, 106}, - {0xc000, 107}, - {0xc000, 113}, - {0xc000, 118}, - {0xc000, 119}, - {0xc000, 120}, - {0xc000, 121}, - {0xc000, 122}, - {0x46, 0}, - {0x47, 0}, - {0x49, 0}, - {0x404a, 0}, - }, - /* 57 */ - { - {0x8001, 85}, - {0xc016, 85}, - {0x8001, 86}, - {0xc016, 86}, - {0x8001, 87}, - {0xc016, 87}, - {0x8001, 89}, - {0xc016, 89}, - {0x8001, 106}, - {0xc016, 106}, - {0x8001, 107}, - {0xc016, 107}, - {0x8001, 113}, - {0xc016, 113}, - {0x8001, 118}, - {0xc016, 118}, - }, - /* 58 */ - { - {0x8002, 85}, - {0x8009, 85}, - {0x8017, 85}, - {0xc028, 85}, - {0x8002, 86}, - {0x8009, 86}, - {0x8017, 86}, - {0xc028, 86}, - {0x8002, 87}, - {0x8009, 87}, - {0x8017, 87}, - {0xc028, 87}, - {0x8002, 89}, - {0x8009, 89}, - {0x8017, 89}, - {0xc028, 89}, - }, - /* 59 */ - { - {0x8003, 85}, - {0x8006, 85}, - {0x800a, 85}, - {0x800f, 85}, - {0x8018, 85}, - {0x801f, 85}, - {0x8029, 85}, - {0xc038, 85}, - {0x8003, 86}, - {0x8006, 86}, - {0x800a, 86}, - {0x800f, 86}, - {0x8018, 86}, - {0x801f, 86}, - {0x8029, 86}, - {0xc038, 86}, - }, - /* 60 */ - { - {0x8003, 87}, - {0x8006, 87}, - {0x800a, 87}, - {0x800f, 87}, - {0x8018, 87}, - {0x801f, 87}, - {0x8029, 87}, - {0xc038, 87}, - {0x8003, 89}, - {0x8006, 89}, - {0x800a, 89}, - {0x800f, 89}, - {0x8018, 89}, - {0x801f, 89}, - {0x8029, 89}, - {0xc038, 89}, - }, - /* 61 */ - { - {0x8002, 106}, - {0x8009, 106}, - {0x8017, 106}, - {0xc028, 106}, - {0x8002, 107}, - {0x8009, 107}, - {0x8017, 107}, - {0xc028, 107}, - {0x8002, 113}, - {0x8009, 113}, - {0x8017, 113}, - {0xc028, 113}, - {0x8002, 118}, - {0x8009, 118}, - {0x8017, 118}, - {0xc028, 118}, - }, - /* 62 */ - { - {0x8003, 106}, - {0x8006, 106}, - {0x800a, 106}, - {0x800f, 106}, - {0x8018, 106}, - {0x801f, 106}, - {0x8029, 106}, - {0xc038, 106}, - {0x8003, 107}, - {0x8006, 107}, - {0x800a, 107}, - {0x800f, 107}, - {0x8018, 107}, - {0x801f, 107}, - {0x8029, 107}, - {0xc038, 107}, - }, - /* 63 */ - { - {0x8003, 113}, - {0x8006, 113}, - {0x800a, 113}, - {0x800f, 113}, - {0x8018, 113}, - {0x801f, 113}, - {0x8029, 113}, - {0xc038, 113}, - {0x8003, 118}, - {0x8006, 118}, - {0x800a, 118}, - {0x800f, 118}, - {0x8018, 118}, - {0x801f, 118}, - {0x8029, 118}, - {0xc038, 118}, - }, - /* 64 */ - { - {0x8001, 119}, - {0xc016, 119}, - {0x8001, 120}, - {0xc016, 120}, - {0x8001, 121}, - {0xc016, 121}, - {0x8001, 122}, - {0xc016, 122}, - {0xc000, 38}, - {0xc000, 42}, - {0xc000, 44}, - {0xc000, 59}, - {0xc000, 88}, - {0xc000, 90}, - {0x4b, 0}, - {0x4e, 0}, - }, - /* 65 */ - { - {0x8002, 119}, - {0x8009, 119}, - {0x8017, 119}, - {0xc028, 119}, - {0x8002, 120}, - {0x8009, 120}, - {0x8017, 120}, - {0xc028, 120}, - {0x8002, 121}, - {0x8009, 121}, - {0x8017, 121}, - {0xc028, 121}, - {0x8002, 122}, - {0x8009, 122}, - {0x8017, 122}, - {0xc028, 122}, - }, - /* 66 */ - { - {0x8003, 119}, - {0x8006, 119}, - {0x800a, 119}, - {0x800f, 119}, - {0x8018, 119}, - {0x801f, 119}, - {0x8029, 119}, - {0xc038, 119}, - {0x8003, 120}, - {0x8006, 120}, - {0x800a, 120}, - {0x800f, 120}, - {0x8018, 120}, - {0x801f, 120}, - {0x8029, 120}, - {0xc038, 120}, - }, - /* 67 */ - { - {0x8003, 121}, - {0x8006, 121}, - {0x800a, 121}, - {0x800f, 121}, - {0x8018, 121}, - {0x801f, 121}, - {0x8029, 121}, - {0xc038, 121}, - {0x8003, 122}, - {0x8006, 122}, - {0x800a, 122}, - {0x800f, 122}, - {0x8018, 122}, - {0x801f, 122}, - {0x8029, 122}, - {0xc038, 122}, - }, - /* 68 */ - { - {0x8001, 38}, - {0xc016, 38}, - {0x8001, 42}, - {0xc016, 42}, - {0x8001, 44}, - {0xc016, 44}, - {0x8001, 59}, - {0xc016, 59}, - {0x8001, 88}, - {0xc016, 88}, - {0x8001, 90}, - {0xc016, 90}, - {0x4c, 0}, - {0x4d, 0}, - {0x4f, 0}, - {0x51, 0}, - }, - /* 69 */ - { - {0x8002, 38}, - {0x8009, 38}, - {0x8017, 38}, - {0xc028, 38}, - {0x8002, 42}, - {0x8009, 42}, - {0x8017, 42}, - {0xc028, 42}, - {0x8002, 44}, - {0x8009, 44}, - {0x8017, 44}, - {0xc028, 44}, - {0x8002, 59}, - {0x8009, 59}, - {0x8017, 59}, - {0xc028, 59}, - }, - /* 70 */ - { - {0x8003, 38}, - {0x8006, 38}, - {0x800a, 38}, - {0x800f, 38}, - {0x8018, 38}, - {0x801f, 38}, - {0x8029, 38}, - {0xc038, 38}, - {0x8003, 42}, - {0x8006, 42}, - {0x800a, 42}, - {0x800f, 42}, - {0x8018, 42}, - {0x801f, 42}, - {0x8029, 42}, - {0xc038, 42}, - }, - /* 71 */ - { - {0x8003, 44}, - {0x8006, 44}, - {0x800a, 44}, - {0x800f, 44}, - {0x8018, 44}, - {0x801f, 44}, - {0x8029, 44}, - {0xc038, 44}, - {0x8003, 59}, - {0x8006, 59}, - {0x800a, 59}, - {0x800f, 59}, - {0x8018, 59}, - {0x801f, 59}, - {0x8029, 59}, - {0xc038, 59}, - }, - /* 72 */ - { - {0x8002, 88}, - {0x8009, 88}, - {0x8017, 88}, - {0xc028, 88}, - {0x8002, 90}, - {0x8009, 90}, - {0x8017, 90}, - {0xc028, 90}, - {0xc000, 33}, - {0xc000, 34}, - {0xc000, 40}, - {0xc000, 41}, - {0xc000, 63}, - {0x50, 0}, - {0x52, 0}, - {0x54, 0}, - }, - /* 73 */ - { - {0x8003, 88}, - {0x8006, 88}, - {0x800a, 88}, - {0x800f, 88}, - {0x8018, 88}, - {0x801f, 88}, - {0x8029, 88}, - {0xc038, 88}, - {0x8003, 90}, - {0x8006, 90}, - {0x800a, 90}, - {0x800f, 90}, - {0x8018, 90}, - {0x801f, 90}, - {0x8029, 90}, - {0xc038, 90}, - }, - /* 74 */ - { - {0x8001, 33}, - {0xc016, 33}, - {0x8001, 34}, - {0xc016, 34}, - {0x8001, 40}, - {0xc016, 40}, - {0x8001, 41}, - {0xc016, 41}, - {0x8001, 63}, - {0xc016, 63}, - {0xc000, 39}, - {0xc000, 43}, - {0xc000, 124}, - {0x53, 0}, - {0x55, 0}, - {0x58, 0}, - }, - /* 75 */ - { - {0x8002, 33}, - {0x8009, 33}, - {0x8017, 33}, - {0xc028, 33}, - {0x8002, 34}, - {0x8009, 34}, - {0x8017, 34}, - {0xc028, 34}, - {0x8002, 40}, - {0x8009, 40}, - {0x8017, 40}, - {0xc028, 40}, - {0x8002, 41}, - {0x8009, 41}, - {0x8017, 41}, - {0xc028, 41}, - }, - /* 76 */ - { - {0x8003, 33}, - {0x8006, 33}, - {0x800a, 33}, - {0x800f, 33}, - {0x8018, 33}, - {0x801f, 33}, - {0x8029, 33}, - {0xc038, 33}, - {0x8003, 34}, - {0x8006, 34}, - {0x800a, 34}, - {0x800f, 34}, - {0x8018, 34}, - {0x801f, 34}, - {0x8029, 34}, - {0xc038, 34}, - }, - /* 77 */ - { - {0x8003, 40}, - {0x8006, 40}, - {0x800a, 40}, - {0x800f, 40}, - {0x8018, 40}, - {0x801f, 40}, - {0x8029, 40}, - {0xc038, 40}, - {0x8003, 41}, - {0x8006, 41}, - {0x800a, 41}, - {0x800f, 41}, - {0x8018, 41}, - {0x801f, 41}, - {0x8029, 41}, - {0xc038, 41}, - }, - /* 78 */ - { - {0x8002, 63}, - {0x8009, 63}, - {0x8017, 63}, - {0xc028, 63}, - {0x8001, 39}, - {0xc016, 39}, - {0x8001, 43}, - {0xc016, 43}, - {0x8001, 124}, - {0xc016, 124}, - {0xc000, 35}, - {0xc000, 62}, - {0x56, 0}, - {0x57, 0}, - {0x59, 0}, - {0x5a, 0}, - }, - /* 79 */ - { - {0x8003, 63}, - {0x8006, 63}, - {0x800a, 63}, - {0x800f, 63}, - {0x8018, 63}, - {0x801f, 63}, - {0x8029, 63}, - {0xc038, 63}, - {0x8002, 39}, - {0x8009, 39}, - {0x8017, 39}, - {0xc028, 39}, - {0x8002, 43}, - {0x8009, 43}, - {0x8017, 43}, - {0xc028, 43}, - }, - /* 80 */ - { - {0x8003, 39}, - {0x8006, 39}, - {0x800a, 39}, - {0x800f, 39}, - {0x8018, 39}, - {0x801f, 39}, - {0x8029, 39}, - {0xc038, 39}, - {0x8003, 43}, - {0x8006, 43}, - {0x800a, 43}, - {0x800f, 43}, - {0x8018, 43}, - {0x801f, 43}, - {0x8029, 43}, - {0xc038, 43}, - }, - /* 81 */ - { - {0x8002, 124}, - {0x8009, 124}, - {0x8017, 124}, - {0xc028, 124}, - {0x8001, 35}, - {0xc016, 35}, - {0x8001, 62}, - {0xc016, 62}, - {0xc000, 0}, - {0xc000, 36}, - {0xc000, 64}, - {0xc000, 91}, - {0xc000, 93}, - {0xc000, 126}, - {0x5b, 0}, - {0x5c, 0}, - }, - /* 82 */ - { - {0x8003, 124}, - {0x8006, 124}, - {0x800a, 124}, - {0x800f, 124}, - {0x8018, 124}, - {0x801f, 124}, - {0x8029, 124}, - {0xc038, 124}, - {0x8002, 35}, - {0x8009, 35}, - {0x8017, 35}, - {0xc028, 35}, - {0x8002, 62}, - {0x8009, 62}, - {0x8017, 62}, - {0xc028, 62}, - }, - /* 83 */ - { - {0x8003, 35}, - {0x8006, 35}, - {0x800a, 35}, - {0x800f, 35}, - {0x8018, 35}, - {0x801f, 35}, - {0x8029, 35}, - {0xc038, 35}, - {0x8003, 62}, - {0x8006, 62}, - {0x800a, 62}, - {0x800f, 62}, - {0x8018, 62}, - {0x801f, 62}, - {0x8029, 62}, - {0xc038, 62}, - }, - /* 84 */ - { - {0x8001, 0}, - {0xc016, 0}, - {0x8001, 36}, - {0xc016, 36}, - {0x8001, 64}, - {0xc016, 64}, - {0x8001, 91}, - {0xc016, 91}, - {0x8001, 93}, - {0xc016, 93}, - {0x8001, 126}, - {0xc016, 126}, - {0xc000, 94}, - {0xc000, 125}, - {0x5d, 0}, - {0x5e, 0}, - }, - /* 85 */ - { - {0x8002, 0}, - {0x8009, 0}, - {0x8017, 0}, - {0xc028, 0}, - {0x8002, 36}, - {0x8009, 36}, - {0x8017, 36}, - {0xc028, 36}, - {0x8002, 64}, - {0x8009, 64}, - {0x8017, 64}, - {0xc028, 64}, - {0x8002, 91}, - {0x8009, 91}, - {0x8017, 91}, - {0xc028, 91}, - }, - /* 86 */ - { - {0x8003, 0}, - {0x8006, 0}, - {0x800a, 0}, - {0x800f, 0}, - {0x8018, 0}, - {0x801f, 0}, - {0x8029, 0}, - {0xc038, 0}, - {0x8003, 36}, - {0x8006, 36}, - {0x800a, 36}, - {0x800f, 36}, - {0x8018, 36}, - {0x801f, 36}, - {0x8029, 36}, - {0xc038, 36}, - }, - /* 87 */ - { - {0x8003, 64}, - {0x8006, 64}, - {0x800a, 64}, - {0x800f, 64}, - {0x8018, 64}, - {0x801f, 64}, - {0x8029, 64}, - {0xc038, 64}, - {0x8003, 91}, - {0x8006, 91}, - {0x800a, 91}, - {0x800f, 91}, - {0x8018, 91}, - {0x801f, 91}, - {0x8029, 91}, - {0xc038, 91}, - }, - /* 88 */ - { - {0x8002, 93}, - {0x8009, 93}, - {0x8017, 93}, - {0xc028, 93}, - {0x8002, 126}, - {0x8009, 126}, - {0x8017, 126}, - {0xc028, 126}, - {0x8001, 94}, - {0xc016, 94}, - {0x8001, 125}, - {0xc016, 125}, - {0xc000, 60}, - {0xc000, 96}, - {0xc000, 123}, - {0x5f, 0}, - }, - /* 89 */ - { - {0x8003, 93}, - {0x8006, 93}, - {0x800a, 93}, - {0x800f, 93}, - {0x8018, 93}, - {0x801f, 93}, - {0x8029, 93}, - {0xc038, 93}, - {0x8003, 126}, - {0x8006, 126}, - {0x800a, 126}, - {0x800f, 126}, - {0x8018, 126}, - {0x801f, 126}, - {0x8029, 126}, - {0xc038, 126}, - }, - /* 90 */ - { - {0x8002, 94}, - {0x8009, 94}, - {0x8017, 94}, - {0xc028, 94}, - {0x8002, 125}, - {0x8009, 125}, - {0x8017, 125}, - {0xc028, 125}, - {0x8001, 60}, - {0xc016, 60}, - {0x8001, 96}, - {0xc016, 96}, - {0x8001, 123}, - {0xc016, 123}, - {0x60, 0}, - {0x6e, 0}, - }, - /* 91 */ - { - {0x8003, 94}, - {0x8006, 94}, - {0x800a, 94}, - {0x800f, 94}, - {0x8018, 94}, - {0x801f, 94}, - {0x8029, 94}, - {0xc038, 94}, - {0x8003, 125}, - {0x8006, 125}, - {0x800a, 125}, - {0x800f, 125}, - {0x8018, 125}, - {0x801f, 125}, - {0x8029, 125}, - {0xc038, 125}, - }, - /* 92 */ - { - {0x8002, 60}, - {0x8009, 60}, - {0x8017, 60}, - {0xc028, 60}, - {0x8002, 96}, - {0x8009, 96}, - {0x8017, 96}, - {0xc028, 96}, - {0x8002, 123}, - {0x8009, 123}, - {0x8017, 123}, - {0xc028, 123}, - {0x61, 0}, - {0x65, 0}, - {0x6f, 0}, - {0x85, 0}, - }, - /* 93 */ - { - {0x8003, 60}, - {0x8006, 60}, - {0x800a, 60}, - {0x800f, 60}, - {0x8018, 60}, - {0x801f, 60}, - {0x8029, 60}, - {0xc038, 60}, - {0x8003, 96}, - {0x8006, 96}, - {0x800a, 96}, - {0x800f, 96}, - {0x8018, 96}, - {0x801f, 96}, - {0x8029, 96}, - {0xc038, 96}, - }, - /* 94 */ - { - {0x8003, 123}, - {0x8006, 123}, - {0x800a, 123}, - {0x800f, 123}, - {0x8018, 123}, - {0x801f, 123}, - {0x8029, 123}, - {0xc038, 123}, - {0x62, 0}, - {0x63, 0}, - {0x66, 0}, - {0x69, 0}, - {0x70, 0}, - {0x77, 0}, - {0x86, 0}, - {0x99, 0}, - }, - /* 95 */ - { - {0xc000, 92}, - {0xc000, 195}, - {0xc000, 208}, - {0x64, 0}, - {0x67, 0}, - {0x68, 0}, - {0x6a, 0}, - {0x6b, 0}, - {0x71, 0}, - {0x74, 0}, - {0x78, 0}, - {0x7e, 0}, - {0x87, 0}, - {0x8e, 0}, - {0x9a, 0}, - {0xa9, 0}, - }, - /* 96 */ - { - {0x8001, 92}, - {0xc016, 92}, - {0x8001, 195}, - {0xc016, 195}, - {0x8001, 208}, - {0xc016, 208}, - {0xc000, 128}, - {0xc000, 130}, - {0xc000, 131}, - {0xc000, 162}, - {0xc000, 184}, - {0xc000, 194}, - {0xc000, 224}, - {0xc000, 226}, - {0x6c, 0}, - {0x6d, 0}, - }, - /* 97 */ - { - {0x8002, 92}, - {0x8009, 92}, - {0x8017, 92}, - {0xc028, 92}, - {0x8002, 195}, - {0x8009, 195}, - {0x8017, 195}, - {0xc028, 195}, - {0x8002, 208}, - {0x8009, 208}, - {0x8017, 208}, - {0xc028, 208}, - {0x8001, 128}, - {0xc016, 128}, - {0x8001, 130}, - {0xc016, 130}, - }, - /* 98 */ - { - {0x8003, 92}, - {0x8006, 92}, - {0x800a, 92}, - {0x800f, 92}, - {0x8018, 92}, - {0x801f, 92}, - {0x8029, 92}, - {0xc038, 92}, - {0x8003, 195}, - {0x8006, 195}, - {0x800a, 195}, - {0x800f, 195}, - {0x8018, 195}, - {0x801f, 195}, - {0x8029, 195}, - {0xc038, 195}, - }, - /* 99 */ - { - {0x8003, 208}, - {0x8006, 208}, - {0x800a, 208}, - {0x800f, 208}, - {0x8018, 208}, - {0x801f, 208}, - {0x8029, 208}, - {0xc038, 208}, - {0x8002, 128}, - {0x8009, 128}, - {0x8017, 128}, - {0xc028, 128}, - {0x8002, 130}, - {0x8009, 130}, - {0x8017, 130}, - {0xc028, 130}, - }, - /* 100 */ - { - {0x8003, 128}, - {0x8006, 128}, - {0x800a, 128}, - {0x800f, 128}, - {0x8018, 128}, - {0x801f, 128}, - {0x8029, 128}, - {0xc038, 128}, - {0x8003, 130}, - {0x8006, 130}, - {0x800a, 130}, - {0x800f, 130}, - {0x8018, 130}, - {0x801f, 130}, - {0x8029, 130}, - {0xc038, 130}, - }, - /* 101 */ - { - {0x8001, 131}, - {0xc016, 131}, - {0x8001, 162}, - {0xc016, 162}, - {0x8001, 184}, - {0xc016, 184}, - {0x8001, 194}, - {0xc016, 194}, - {0x8001, 224}, - {0xc016, 224}, - {0x8001, 226}, - {0xc016, 226}, - {0xc000, 153}, - {0xc000, 161}, - {0xc000, 167}, - {0xc000, 172}, - }, - /* 102 */ - { - {0x8002, 131}, - {0x8009, 131}, - {0x8017, 131}, - {0xc028, 131}, - {0x8002, 162}, - {0x8009, 162}, - {0x8017, 162}, - {0xc028, 162}, - {0x8002, 184}, - {0x8009, 184}, - {0x8017, 184}, - {0xc028, 184}, - {0x8002, 194}, - {0x8009, 194}, - {0x8017, 194}, - {0xc028, 194}, - }, - /* 103 */ - { - {0x8003, 131}, - {0x8006, 131}, - {0x800a, 131}, - {0x800f, 131}, - {0x8018, 131}, - {0x801f, 131}, - {0x8029, 131}, - {0xc038, 131}, - {0x8003, 162}, - {0x8006, 162}, - {0x800a, 162}, - {0x800f, 162}, - {0x8018, 162}, - {0x801f, 162}, - {0x8029, 162}, - {0xc038, 162}, - }, - /* 104 */ - { - {0x8003, 184}, - {0x8006, 184}, - {0x800a, 184}, - {0x800f, 184}, - {0x8018, 184}, - {0x801f, 184}, - {0x8029, 184}, - {0xc038, 184}, - {0x8003, 194}, - {0x8006, 194}, - {0x800a, 194}, - {0x800f, 194}, - {0x8018, 194}, - {0x801f, 194}, - {0x8029, 194}, - {0xc038, 194}, - }, - /* 105 */ - { - {0x8002, 224}, - {0x8009, 224}, - {0x8017, 224}, - {0xc028, 224}, - {0x8002, 226}, - {0x8009, 226}, - {0x8017, 226}, - {0xc028, 226}, - {0x8001, 153}, - {0xc016, 153}, - {0x8001, 161}, - {0xc016, 161}, - {0x8001, 167}, - {0xc016, 167}, - {0x8001, 172}, - {0xc016, 172}, - }, - /* 106 */ - { - {0x8003, 224}, - {0x8006, 224}, - {0x800a, 224}, - {0x800f, 224}, - {0x8018, 224}, - {0x801f, 224}, - {0x8029, 224}, - {0xc038, 224}, - {0x8003, 226}, - {0x8006, 226}, - {0x800a, 226}, - {0x800f, 226}, - {0x8018, 226}, - {0x801f, 226}, - {0x8029, 226}, - {0xc038, 226}, - }, - /* 107 */ - { - {0x8002, 153}, - {0x8009, 153}, - {0x8017, 153}, - {0xc028, 153}, - {0x8002, 161}, - {0x8009, 161}, - {0x8017, 161}, - {0xc028, 161}, - {0x8002, 167}, - {0x8009, 167}, - {0x8017, 167}, - {0xc028, 167}, - {0x8002, 172}, - {0x8009, 172}, - {0x8017, 172}, - {0xc028, 172}, - }, - /* 108 */ - { - {0x8003, 153}, - {0x8006, 153}, - {0x800a, 153}, - {0x800f, 153}, - {0x8018, 153}, - {0x801f, 153}, - {0x8029, 153}, - {0xc038, 153}, - {0x8003, 161}, - {0x8006, 161}, - {0x800a, 161}, - {0x800f, 161}, - {0x8018, 161}, - {0x801f, 161}, - {0x8029, 161}, - {0xc038, 161}, - }, - /* 109 */ - { - {0x8003, 167}, - {0x8006, 167}, - {0x800a, 167}, - {0x800f, 167}, - {0x8018, 167}, - {0x801f, 167}, - {0x8029, 167}, - {0xc038, 167}, - {0x8003, 172}, - {0x8006, 172}, - {0x800a, 172}, - {0x800f, 172}, - {0x8018, 172}, - {0x801f, 172}, - {0x8029, 172}, - {0xc038, 172}, - }, - /* 110 */ - { - {0x72, 0}, - {0x73, 0}, - {0x75, 0}, - {0x76, 0}, - {0x79, 0}, - {0x7b, 0}, - {0x7f, 0}, - {0x82, 0}, - {0x88, 0}, - {0x8b, 0}, - {0x8f, 0}, - {0x92, 0}, - {0x9b, 0}, - {0xa2, 0}, - {0xaa, 0}, - {0xb4, 0}, - }, - /* 111 */ - { - {0xc000, 176}, - {0xc000, 177}, - {0xc000, 179}, - {0xc000, 209}, - {0xc000, 216}, - {0xc000, 217}, - {0xc000, 227}, - {0xc000, 229}, - {0xc000, 230}, - {0x7a, 0}, - {0x7c, 0}, - {0x7d, 0}, - {0x80, 0}, - {0x81, 0}, - {0x83, 0}, - {0x84, 0}, - }, - /* 112 */ - { - {0x8001, 176}, - {0xc016, 176}, - {0x8001, 177}, - {0xc016, 177}, - {0x8001, 179}, - {0xc016, 179}, - {0x8001, 209}, - {0xc016, 209}, - {0x8001, 216}, - {0xc016, 216}, - {0x8001, 217}, - {0xc016, 217}, - {0x8001, 227}, - {0xc016, 227}, - {0x8001, 229}, - {0xc016, 229}, - }, - /* 113 */ - { - {0x8002, 176}, - {0x8009, 176}, - {0x8017, 176}, - {0xc028, 176}, - {0x8002, 177}, - {0x8009, 177}, - {0x8017, 177}, - {0xc028, 177}, - {0x8002, 179}, - {0x8009, 179}, - {0x8017, 179}, - {0xc028, 179}, - {0x8002, 209}, - {0x8009, 209}, - {0x8017, 209}, - {0xc028, 209}, - }, - /* 114 */ - { - {0x8003, 176}, - {0x8006, 176}, - {0x800a, 176}, - {0x800f, 176}, - {0x8018, 176}, - {0x801f, 176}, - {0x8029, 176}, - {0xc038, 176}, - {0x8003, 177}, - {0x8006, 177}, - {0x800a, 177}, - {0x800f, 177}, - {0x8018, 177}, - {0x801f, 177}, - {0x8029, 177}, - {0xc038, 177}, - }, - /* 115 */ - { - {0x8003, 179}, - {0x8006, 179}, - {0x800a, 179}, - {0x800f, 179}, - {0x8018, 179}, - {0x801f, 179}, - {0x8029, 179}, - {0xc038, 179}, - {0x8003, 209}, - {0x8006, 209}, - {0x800a, 209}, - {0x800f, 209}, - {0x8018, 209}, - {0x801f, 209}, - {0x8029, 209}, - {0xc038, 209}, - }, - /* 116 */ - { - {0x8002, 216}, - {0x8009, 216}, - {0x8017, 216}, - {0xc028, 216}, - {0x8002, 217}, - {0x8009, 217}, - {0x8017, 217}, - {0xc028, 217}, - {0x8002, 227}, - {0x8009, 227}, - {0x8017, 227}, - {0xc028, 227}, - {0x8002, 229}, - {0x8009, 229}, - {0x8017, 229}, - {0xc028, 229}, - }, - /* 117 */ - { - {0x8003, 216}, - {0x8006, 216}, - {0x800a, 216}, - {0x800f, 216}, - {0x8018, 216}, - {0x801f, 216}, - {0x8029, 216}, - {0xc038, 216}, - {0x8003, 217}, - {0x8006, 217}, - {0x800a, 217}, - {0x800f, 217}, - {0x8018, 217}, - {0x801f, 217}, - {0x8029, 217}, - {0xc038, 217}, - }, - /* 118 */ - { - {0x8003, 227}, - {0x8006, 227}, - {0x800a, 227}, - {0x800f, 227}, - {0x8018, 227}, - {0x801f, 227}, - {0x8029, 227}, - {0xc038, 227}, - {0x8003, 229}, - {0x8006, 229}, - {0x800a, 229}, - {0x800f, 229}, - {0x8018, 229}, - {0x801f, 229}, - {0x8029, 229}, - {0xc038, 229}, - }, - /* 119 */ - { - {0x8001, 230}, - {0xc016, 230}, - {0xc000, 129}, - {0xc000, 132}, - {0xc000, 133}, - {0xc000, 134}, - {0xc000, 136}, - {0xc000, 146}, - {0xc000, 154}, - {0xc000, 156}, - {0xc000, 160}, - {0xc000, 163}, - {0xc000, 164}, - {0xc000, 169}, - {0xc000, 170}, - {0xc000, 173}, - }, - /* 120 */ - { - {0x8002, 230}, - {0x8009, 230}, - {0x8017, 230}, - {0xc028, 230}, - {0x8001, 129}, - {0xc016, 129}, - {0x8001, 132}, - {0xc016, 132}, - {0x8001, 133}, - {0xc016, 133}, - {0x8001, 134}, - {0xc016, 134}, - {0x8001, 136}, - {0xc016, 136}, - {0x8001, 146}, - {0xc016, 146}, - }, - /* 121 */ - { - {0x8003, 230}, - {0x8006, 230}, - {0x800a, 230}, - {0x800f, 230}, - {0x8018, 230}, - {0x801f, 230}, - {0x8029, 230}, - {0xc038, 230}, - {0x8002, 129}, - {0x8009, 129}, - {0x8017, 129}, - {0xc028, 129}, - {0x8002, 132}, - {0x8009, 132}, - {0x8017, 132}, - {0xc028, 132}, - }, - /* 122 */ - { - {0x8003, 129}, - {0x8006, 129}, - {0x800a, 129}, - {0x800f, 129}, - {0x8018, 129}, - {0x801f, 129}, - {0x8029, 129}, - {0xc038, 129}, - {0x8003, 132}, - {0x8006, 132}, - {0x800a, 132}, - {0x800f, 132}, - {0x8018, 132}, - {0x801f, 132}, - {0x8029, 132}, - {0xc038, 132}, - }, - /* 123 */ - { - {0x8002, 133}, - {0x8009, 133}, - {0x8017, 133}, - {0xc028, 133}, - {0x8002, 134}, - {0x8009, 134}, - {0x8017, 134}, - {0xc028, 134}, - {0x8002, 136}, - {0x8009, 136}, - {0x8017, 136}, - {0xc028, 136}, - {0x8002, 146}, - {0x8009, 146}, - {0x8017, 146}, - {0xc028, 146}, - }, - /* 124 */ - { - {0x8003, 133}, - {0x8006, 133}, - {0x800a, 133}, - {0x800f, 133}, - {0x8018, 133}, - {0x801f, 133}, - {0x8029, 133}, - {0xc038, 133}, - {0x8003, 134}, - {0x8006, 134}, - {0x800a, 134}, - {0x800f, 134}, - {0x8018, 134}, - {0x801f, 134}, - {0x8029, 134}, - {0xc038, 134}, - }, - /* 125 */ - { - {0x8003, 136}, - {0x8006, 136}, - {0x800a, 136}, - {0x800f, 136}, - {0x8018, 136}, - {0x801f, 136}, - {0x8029, 136}, - {0xc038, 136}, - {0x8003, 146}, - {0x8006, 146}, - {0x800a, 146}, - {0x800f, 146}, - {0x8018, 146}, - {0x801f, 146}, - {0x8029, 146}, - {0xc038, 146}, - }, - /* 126 */ - { - {0x8001, 154}, - {0xc016, 154}, - {0x8001, 156}, - {0xc016, 156}, - {0x8001, 160}, - {0xc016, 160}, - {0x8001, 163}, - {0xc016, 163}, - {0x8001, 164}, - {0xc016, 164}, - {0x8001, 169}, - {0xc016, 169}, - {0x8001, 170}, - {0xc016, 170}, - {0x8001, 173}, - {0xc016, 173}, - }, - /* 127 */ - { - {0x8002, 154}, - {0x8009, 154}, - {0x8017, 154}, - {0xc028, 154}, - {0x8002, 156}, - {0x8009, 156}, - {0x8017, 156}, - {0xc028, 156}, - {0x8002, 160}, - {0x8009, 160}, - {0x8017, 160}, - {0xc028, 160}, - {0x8002, 163}, - {0x8009, 163}, - {0x8017, 163}, - {0xc028, 163}, - }, - /* 128 */ - { - {0x8003, 154}, - {0x8006, 154}, - {0x800a, 154}, - {0x800f, 154}, - {0x8018, 154}, - {0x801f, 154}, - {0x8029, 154}, - {0xc038, 154}, - {0x8003, 156}, - {0x8006, 156}, - {0x800a, 156}, - {0x800f, 156}, - {0x8018, 156}, - {0x801f, 156}, - {0x8029, 156}, - {0xc038, 156}, - }, - /* 129 */ - { - {0x8003, 160}, - {0x8006, 160}, - {0x800a, 160}, - {0x800f, 160}, - {0x8018, 160}, - {0x801f, 160}, - {0x8029, 160}, - {0xc038, 160}, - {0x8003, 163}, - {0x8006, 163}, - {0x800a, 163}, - {0x800f, 163}, - {0x8018, 163}, - {0x801f, 163}, - {0x8029, 163}, - {0xc038, 163}, - }, - /* 130 */ - { - {0x8002, 164}, - {0x8009, 164}, - {0x8017, 164}, - {0xc028, 164}, - {0x8002, 169}, - {0x8009, 169}, - {0x8017, 169}, - {0xc028, 169}, - {0x8002, 170}, - {0x8009, 170}, - {0x8017, 170}, - {0xc028, 170}, - {0x8002, 173}, - {0x8009, 173}, - {0x8017, 173}, - {0xc028, 173}, - }, - /* 131 */ - { - {0x8003, 164}, - {0x8006, 164}, - {0x800a, 164}, - {0x800f, 164}, - {0x8018, 164}, - {0x801f, 164}, - {0x8029, 164}, - {0xc038, 164}, - {0x8003, 169}, - {0x8006, 169}, - {0x800a, 169}, - {0x800f, 169}, - {0x8018, 169}, - {0x801f, 169}, - {0x8029, 169}, - {0xc038, 169}, - }, - /* 132 */ - { - {0x8003, 170}, - {0x8006, 170}, - {0x800a, 170}, - {0x800f, 170}, - {0x8018, 170}, - {0x801f, 170}, - {0x8029, 170}, - {0xc038, 170}, - {0x8003, 173}, - {0x8006, 173}, - {0x800a, 173}, - {0x800f, 173}, - {0x8018, 173}, - {0x801f, 173}, - {0x8029, 173}, - {0xc038, 173}, - }, - /* 133 */ - { - {0x89, 0}, - {0x8a, 0}, - {0x8c, 0}, - {0x8d, 0}, - {0x90, 0}, - {0x91, 0}, - {0x93, 0}, - {0x96, 0}, - {0x9c, 0}, - {0x9f, 0}, - {0xa3, 0}, - {0xa6, 0}, - {0xab, 0}, - {0xae, 0}, - {0xb5, 0}, - {0xbe, 0}, - }, - /* 134 */ - { - {0xc000, 178}, - {0xc000, 181}, - {0xc000, 185}, - {0xc000, 186}, - {0xc000, 187}, - {0xc000, 189}, - {0xc000, 190}, - {0xc000, 196}, - {0xc000, 198}, - {0xc000, 228}, - {0xc000, 232}, - {0xc000, 233}, - {0x94, 0}, - {0x95, 0}, - {0x97, 0}, - {0x98, 0}, - }, - /* 135 */ - { - {0x8001, 178}, - {0xc016, 178}, - {0x8001, 181}, - {0xc016, 181}, - {0x8001, 185}, - {0xc016, 185}, - {0x8001, 186}, - {0xc016, 186}, - {0x8001, 187}, - {0xc016, 187}, - {0x8001, 189}, - {0xc016, 189}, - {0x8001, 190}, - {0xc016, 190}, - {0x8001, 196}, - {0xc016, 196}, - }, - /* 136 */ - { - {0x8002, 178}, - {0x8009, 178}, - {0x8017, 178}, - {0xc028, 178}, - {0x8002, 181}, - {0x8009, 181}, - {0x8017, 181}, - {0xc028, 181}, - {0x8002, 185}, - {0x8009, 185}, - {0x8017, 185}, - {0xc028, 185}, - {0x8002, 186}, - {0x8009, 186}, - {0x8017, 186}, - {0xc028, 186}, - }, - /* 137 */ - { - {0x8003, 178}, - {0x8006, 178}, - {0x800a, 178}, - {0x800f, 178}, - {0x8018, 178}, - {0x801f, 178}, - {0x8029, 178}, - {0xc038, 178}, - {0x8003, 181}, - {0x8006, 181}, - {0x800a, 181}, - {0x800f, 181}, - {0x8018, 181}, - {0x801f, 181}, - {0x8029, 181}, - {0xc038, 181}, - }, - /* 138 */ - { - {0x8003, 185}, - {0x8006, 185}, - {0x800a, 185}, - {0x800f, 185}, - {0x8018, 185}, - {0x801f, 185}, - {0x8029, 185}, - {0xc038, 185}, - {0x8003, 186}, - {0x8006, 186}, - {0x800a, 186}, - {0x800f, 186}, - {0x8018, 186}, - {0x801f, 186}, - {0x8029, 186}, - {0xc038, 186}, - }, - /* 139 */ - { - {0x8002, 187}, - {0x8009, 187}, - {0x8017, 187}, - {0xc028, 187}, - {0x8002, 189}, - {0x8009, 189}, - {0x8017, 189}, - {0xc028, 189}, - {0x8002, 190}, - {0x8009, 190}, - {0x8017, 190}, - {0xc028, 190}, - {0x8002, 196}, - {0x8009, 196}, - {0x8017, 196}, - {0xc028, 196}, - }, - /* 140 */ - { - {0x8003, 187}, - {0x8006, 187}, - {0x800a, 187}, - {0x800f, 187}, - {0x8018, 187}, - {0x801f, 187}, - {0x8029, 187}, - {0xc038, 187}, - {0x8003, 189}, - {0x8006, 189}, - {0x800a, 189}, - {0x800f, 189}, - {0x8018, 189}, - {0x801f, 189}, - {0x8029, 189}, - {0xc038, 189}, - }, - /* 141 */ - { - {0x8003, 190}, - {0x8006, 190}, - {0x800a, 190}, - {0x800f, 190}, - {0x8018, 190}, - {0x801f, 190}, - {0x8029, 190}, - {0xc038, 190}, - {0x8003, 196}, - {0x8006, 196}, - {0x800a, 196}, - {0x800f, 196}, - {0x8018, 196}, - {0x801f, 196}, - {0x8029, 196}, - {0xc038, 196}, - }, - /* 142 */ - { - {0x8001, 198}, - {0xc016, 198}, - {0x8001, 228}, - {0xc016, 228}, - {0x8001, 232}, - {0xc016, 232}, - {0x8001, 233}, - {0xc016, 233}, - {0xc000, 1}, - {0xc000, 135}, - {0xc000, 137}, - {0xc000, 138}, - {0xc000, 139}, - {0xc000, 140}, - {0xc000, 141}, - {0xc000, 143}, - }, - /* 143 */ - { - {0x8002, 198}, - {0x8009, 198}, - {0x8017, 198}, - {0xc028, 198}, - {0x8002, 228}, - {0x8009, 228}, - {0x8017, 228}, - {0xc028, 228}, - {0x8002, 232}, - {0x8009, 232}, - {0x8017, 232}, - {0xc028, 232}, - {0x8002, 233}, - {0x8009, 233}, - {0x8017, 233}, - {0xc028, 233}, - }, - /* 144 */ - { - {0x8003, 198}, - {0x8006, 198}, - {0x800a, 198}, - {0x800f, 198}, - {0x8018, 198}, - {0x801f, 198}, - {0x8029, 198}, - {0xc038, 198}, - {0x8003, 228}, - {0x8006, 228}, - {0x800a, 228}, - {0x800f, 228}, - {0x8018, 228}, - {0x801f, 228}, - {0x8029, 228}, - {0xc038, 228}, - }, - /* 145 */ - { - {0x8003, 232}, - {0x8006, 232}, - {0x800a, 232}, - {0x800f, 232}, - {0x8018, 232}, - {0x801f, 232}, - {0x8029, 232}, - {0xc038, 232}, - {0x8003, 233}, - {0x8006, 233}, - {0x800a, 233}, - {0x800f, 233}, - {0x8018, 233}, - {0x801f, 233}, - {0x8029, 233}, - {0xc038, 233}, - }, - /* 146 */ - { - {0x8001, 1}, - {0xc016, 1}, - {0x8001, 135}, - {0xc016, 135}, - {0x8001, 137}, - {0xc016, 137}, - {0x8001, 138}, - {0xc016, 138}, - {0x8001, 139}, - {0xc016, 139}, - {0x8001, 140}, - {0xc016, 140}, - {0x8001, 141}, - {0xc016, 141}, - {0x8001, 143}, - {0xc016, 143}, - }, - /* 147 */ - { - {0x8002, 1}, - {0x8009, 1}, - {0x8017, 1}, - {0xc028, 1}, - {0x8002, 135}, - {0x8009, 135}, - {0x8017, 135}, - {0xc028, 135}, - {0x8002, 137}, - {0x8009, 137}, - {0x8017, 137}, - {0xc028, 137}, - {0x8002, 138}, - {0x8009, 138}, - {0x8017, 138}, - {0xc028, 138}, - }, - /* 148 */ - { - {0x8003, 1}, - {0x8006, 1}, - {0x800a, 1}, - {0x800f, 1}, - {0x8018, 1}, - {0x801f, 1}, - {0x8029, 1}, - {0xc038, 1}, - {0x8003, 135}, - {0x8006, 135}, - {0x800a, 135}, - {0x800f, 135}, - {0x8018, 135}, - {0x801f, 135}, - {0x8029, 135}, - {0xc038, 135}, - }, - /* 149 */ - { - {0x8003, 137}, - {0x8006, 137}, - {0x800a, 137}, - {0x800f, 137}, - {0x8018, 137}, - {0x801f, 137}, - {0x8029, 137}, - {0xc038, 137}, - {0x8003, 138}, - {0x8006, 138}, - {0x800a, 138}, - {0x800f, 138}, - {0x8018, 138}, - {0x801f, 138}, - {0x8029, 138}, - {0xc038, 138}, - }, - /* 150 */ - { - {0x8002, 139}, - {0x8009, 139}, - {0x8017, 139}, - {0xc028, 139}, - {0x8002, 140}, - {0x8009, 140}, - {0x8017, 140}, - {0xc028, 140}, - {0x8002, 141}, - {0x8009, 141}, - {0x8017, 141}, - {0xc028, 141}, - {0x8002, 143}, - {0x8009, 143}, - {0x8017, 143}, - {0xc028, 143}, - }, - /* 151 */ - { - {0x8003, 139}, - {0x8006, 139}, - {0x800a, 139}, - {0x800f, 139}, - {0x8018, 139}, - {0x801f, 139}, - {0x8029, 139}, - {0xc038, 139}, - {0x8003, 140}, - {0x8006, 140}, - {0x800a, 140}, - {0x800f, 140}, - {0x8018, 140}, - {0x801f, 140}, - {0x8029, 140}, - {0xc038, 140}, - }, - /* 152 */ - { - {0x8003, 141}, - {0x8006, 141}, - {0x800a, 141}, - {0x800f, 141}, - {0x8018, 141}, - {0x801f, 141}, - {0x8029, 141}, - {0xc038, 141}, - {0x8003, 143}, - {0x8006, 143}, - {0x800a, 143}, - {0x800f, 143}, - {0x8018, 143}, - {0x801f, 143}, - {0x8029, 143}, - {0xc038, 143}, - }, - /* 153 */ - { - {0x9d, 0}, - {0x9e, 0}, - {0xa0, 0}, - {0xa1, 0}, - {0xa4, 0}, - {0xa5, 0}, - {0xa7, 0}, - {0xa8, 0}, - {0xac, 0}, - {0xad, 0}, - {0xaf, 0}, - {0xb1, 0}, - {0xb6, 0}, - {0xb9, 0}, - {0xbf, 0}, - {0xcf, 0}, - }, - /* 154 */ - { - {0xc000, 147}, - {0xc000, 149}, - {0xc000, 150}, - {0xc000, 151}, - {0xc000, 152}, - {0xc000, 155}, - {0xc000, 157}, - {0xc000, 158}, - {0xc000, 165}, - {0xc000, 166}, - {0xc000, 168}, - {0xc000, 174}, - {0xc000, 175}, - {0xc000, 180}, - {0xc000, 182}, - {0xc000, 183}, - }, - /* 155 */ - { - {0x8001, 147}, - {0xc016, 147}, - {0x8001, 149}, - {0xc016, 149}, - {0x8001, 150}, - {0xc016, 150}, - {0x8001, 151}, - {0xc016, 151}, - {0x8001, 152}, - {0xc016, 152}, - {0x8001, 155}, - {0xc016, 155}, - {0x8001, 157}, - {0xc016, 157}, - {0x8001, 158}, - {0xc016, 158}, - }, - /* 156 */ - { - {0x8002, 147}, - {0x8009, 147}, - {0x8017, 147}, - {0xc028, 147}, - {0x8002, 149}, - {0x8009, 149}, - {0x8017, 149}, - {0xc028, 149}, - {0x8002, 150}, - {0x8009, 150}, - {0x8017, 150}, - {0xc028, 150}, - {0x8002, 151}, - {0x8009, 151}, - {0x8017, 151}, - {0xc028, 151}, - }, - /* 157 */ - { - {0x8003, 147}, - {0x8006, 147}, - {0x800a, 147}, - {0x800f, 147}, - {0x8018, 147}, - {0x801f, 147}, - {0x8029, 147}, - {0xc038, 147}, - {0x8003, 149}, - {0x8006, 149}, - {0x800a, 149}, - {0x800f, 149}, - {0x8018, 149}, - {0x801f, 149}, - {0x8029, 149}, - {0xc038, 149}, - }, - /* 158 */ - { - {0x8003, 150}, - {0x8006, 150}, - {0x800a, 150}, - {0x800f, 150}, - {0x8018, 150}, - {0x801f, 150}, - {0x8029, 150}, - {0xc038, 150}, - {0x8003, 151}, - {0x8006, 151}, - {0x800a, 151}, - {0x800f, 151}, - {0x8018, 151}, - {0x801f, 151}, - {0x8029, 151}, - {0xc038, 151}, - }, - /* 159 */ - { - {0x8002, 152}, - {0x8009, 152}, - {0x8017, 152}, - {0xc028, 152}, - {0x8002, 155}, - {0x8009, 155}, - {0x8017, 155}, - {0xc028, 155}, - {0x8002, 157}, - {0x8009, 157}, - {0x8017, 157}, - {0xc028, 157}, - {0x8002, 158}, - {0x8009, 158}, - {0x8017, 158}, - {0xc028, 158}, - }, - /* 160 */ - { - {0x8003, 152}, - {0x8006, 152}, - {0x800a, 152}, - {0x800f, 152}, - {0x8018, 152}, - {0x801f, 152}, - {0x8029, 152}, - {0xc038, 152}, - {0x8003, 155}, - {0x8006, 155}, - {0x800a, 155}, - {0x800f, 155}, - {0x8018, 155}, - {0x801f, 155}, - {0x8029, 155}, - {0xc038, 155}, - }, - /* 161 */ - { - {0x8003, 157}, - {0x8006, 157}, - {0x800a, 157}, - {0x800f, 157}, - {0x8018, 157}, - {0x801f, 157}, - {0x8029, 157}, - {0xc038, 157}, - {0x8003, 158}, - {0x8006, 158}, - {0x800a, 158}, - {0x800f, 158}, - {0x8018, 158}, - {0x801f, 158}, - {0x8029, 158}, - {0xc038, 158}, - }, - /* 162 */ - { - {0x8001, 165}, - {0xc016, 165}, - {0x8001, 166}, - {0xc016, 166}, - {0x8001, 168}, - {0xc016, 168}, - {0x8001, 174}, - {0xc016, 174}, - {0x8001, 175}, - {0xc016, 175}, - {0x8001, 180}, - {0xc016, 180}, - {0x8001, 182}, - {0xc016, 182}, - {0x8001, 183}, - {0xc016, 183}, - }, - /* 163 */ - { - {0x8002, 165}, - {0x8009, 165}, - {0x8017, 165}, - {0xc028, 165}, - {0x8002, 166}, - {0x8009, 166}, - {0x8017, 166}, - {0xc028, 166}, - {0x8002, 168}, - {0x8009, 168}, - {0x8017, 168}, - {0xc028, 168}, - {0x8002, 174}, - {0x8009, 174}, - {0x8017, 174}, - {0xc028, 174}, - }, - /* 164 */ - { - {0x8003, 165}, - {0x8006, 165}, - {0x800a, 165}, - {0x800f, 165}, - {0x8018, 165}, - {0x801f, 165}, - {0x8029, 165}, - {0xc038, 165}, - {0x8003, 166}, - {0x8006, 166}, - {0x800a, 166}, - {0x800f, 166}, - {0x8018, 166}, - {0x801f, 166}, - {0x8029, 166}, - {0xc038, 166}, - }, - /* 165 */ - { - {0x8003, 168}, - {0x8006, 168}, - {0x800a, 168}, - {0x800f, 168}, - {0x8018, 168}, - {0x801f, 168}, - {0x8029, 168}, - {0xc038, 168}, - {0x8003, 174}, - {0x8006, 174}, - {0x800a, 174}, - {0x800f, 174}, - {0x8018, 174}, - {0x801f, 174}, - {0x8029, 174}, - {0xc038, 174}, - }, - /* 166 */ - { - {0x8002, 175}, - {0x8009, 175}, - {0x8017, 175}, - {0xc028, 175}, - {0x8002, 180}, - {0x8009, 180}, - {0x8017, 180}, - {0xc028, 180}, - {0x8002, 182}, - {0x8009, 182}, - {0x8017, 182}, - {0xc028, 182}, - {0x8002, 183}, - {0x8009, 183}, - {0x8017, 183}, - {0xc028, 183}, - }, - /* 167 */ - { - {0x8003, 175}, - {0x8006, 175}, - {0x800a, 175}, - {0x800f, 175}, - {0x8018, 175}, - {0x801f, 175}, - {0x8029, 175}, - {0xc038, 175}, - {0x8003, 180}, - {0x8006, 180}, - {0x800a, 180}, - {0x800f, 180}, - {0x8018, 180}, - {0x801f, 180}, - {0x8029, 180}, - {0xc038, 180}, - }, - /* 168 */ - { - {0x8003, 182}, - {0x8006, 182}, - {0x800a, 182}, - {0x800f, 182}, - {0x8018, 182}, - {0x801f, 182}, - {0x8029, 182}, - {0xc038, 182}, - {0x8003, 183}, - {0x8006, 183}, - {0x800a, 183}, - {0x800f, 183}, - {0x8018, 183}, - {0x801f, 183}, - {0x8029, 183}, - {0xc038, 183}, - }, - /* 169 */ - { - {0xc000, 188}, - {0xc000, 191}, - {0xc000, 197}, - {0xc000, 231}, - {0xc000, 239}, - {0xb0, 0}, - {0xb2, 0}, - {0xb3, 0}, - {0xb7, 0}, - {0xb8, 0}, - {0xba, 0}, - {0xbb, 0}, - {0xc0, 0}, - {0xc7, 0}, - {0xd0, 0}, - {0xdf, 0}, - }, - /* 170 */ - { - {0x8001, 188}, - {0xc016, 188}, - {0x8001, 191}, - {0xc016, 191}, - {0x8001, 197}, - {0xc016, 197}, - {0x8001, 231}, - {0xc016, 231}, - {0x8001, 239}, - {0xc016, 239}, - {0xc000, 9}, - {0xc000, 142}, - {0xc000, 144}, - {0xc000, 145}, - {0xc000, 148}, - {0xc000, 159}, - }, - /* 171 */ - { - {0x8002, 188}, - {0x8009, 188}, - {0x8017, 188}, - {0xc028, 188}, - {0x8002, 191}, - {0x8009, 191}, - {0x8017, 191}, - {0xc028, 191}, - {0x8002, 197}, - {0x8009, 197}, - {0x8017, 197}, - {0xc028, 197}, - {0x8002, 231}, - {0x8009, 231}, - {0x8017, 231}, - {0xc028, 231}, - }, - /* 172 */ - { - {0x8003, 188}, - {0x8006, 188}, - {0x800a, 188}, - {0x800f, 188}, - {0x8018, 188}, - {0x801f, 188}, - {0x8029, 188}, - {0xc038, 188}, - {0x8003, 191}, - {0x8006, 191}, - {0x800a, 191}, - {0x800f, 191}, - {0x8018, 191}, - {0x801f, 191}, - {0x8029, 191}, - {0xc038, 191}, - }, - /* 173 */ - { - {0x8003, 197}, - {0x8006, 197}, - {0x800a, 197}, - {0x800f, 197}, - {0x8018, 197}, - {0x801f, 197}, - {0x8029, 197}, - {0xc038, 197}, - {0x8003, 231}, - {0x8006, 231}, - {0x800a, 231}, - {0x800f, 231}, - {0x8018, 231}, - {0x801f, 231}, - {0x8029, 231}, - {0xc038, 231}, - }, - /* 174 */ - { - {0x8002, 239}, - {0x8009, 239}, - {0x8017, 239}, - {0xc028, 239}, - {0x8001, 9}, - {0xc016, 9}, - {0x8001, 142}, - {0xc016, 142}, - {0x8001, 144}, - {0xc016, 144}, - {0x8001, 145}, - {0xc016, 145}, - {0x8001, 148}, - {0xc016, 148}, - {0x8001, 159}, - {0xc016, 159}, - }, - /* 175 */ - { - {0x8003, 239}, - {0x8006, 239}, - {0x800a, 239}, - {0x800f, 239}, - {0x8018, 239}, - {0x801f, 239}, - {0x8029, 239}, - {0xc038, 239}, - {0x8002, 9}, - {0x8009, 9}, - {0x8017, 9}, - {0xc028, 9}, - {0x8002, 142}, - {0x8009, 142}, - {0x8017, 142}, - {0xc028, 142}, - }, - /* 176 */ - { - {0x8003, 9}, - {0x8006, 9}, - {0x800a, 9}, - {0x800f, 9}, - {0x8018, 9}, - {0x801f, 9}, - {0x8029, 9}, - {0xc038, 9}, - {0x8003, 142}, - {0x8006, 142}, - {0x800a, 142}, - {0x800f, 142}, - {0x8018, 142}, - {0x801f, 142}, - {0x8029, 142}, - {0xc038, 142}, - }, - /* 177 */ - { - {0x8002, 144}, - {0x8009, 144}, - {0x8017, 144}, - {0xc028, 144}, - {0x8002, 145}, - {0x8009, 145}, - {0x8017, 145}, - {0xc028, 145}, - {0x8002, 148}, - {0x8009, 148}, - {0x8017, 148}, - {0xc028, 148}, - {0x8002, 159}, - {0x8009, 159}, - {0x8017, 159}, - {0xc028, 159}, - }, - /* 178 */ - { - {0x8003, 144}, - {0x8006, 144}, - {0x800a, 144}, - {0x800f, 144}, - {0x8018, 144}, - {0x801f, 144}, - {0x8029, 144}, - {0xc038, 144}, - {0x8003, 145}, - {0x8006, 145}, - {0x800a, 145}, - {0x800f, 145}, - {0x8018, 145}, - {0x801f, 145}, - {0x8029, 145}, - {0xc038, 145}, - }, - /* 179 */ - { - {0x8003, 148}, - {0x8006, 148}, - {0x800a, 148}, - {0x800f, 148}, - {0x8018, 148}, - {0x801f, 148}, - {0x8029, 148}, - {0xc038, 148}, - {0x8003, 159}, - {0x8006, 159}, - {0x800a, 159}, - {0x800f, 159}, - {0x8018, 159}, - {0x801f, 159}, - {0x8029, 159}, - {0xc038, 159}, - }, - /* 180 */ - { - {0xc000, 171}, - {0xc000, 206}, - {0xc000, 215}, - {0xc000, 225}, - {0xc000, 236}, - {0xc000, 237}, - {0xbc, 0}, - {0xbd, 0}, - {0xc1, 0}, - {0xc4, 0}, - {0xc8, 0}, - {0xcb, 0}, - {0xd1, 0}, - {0xd8, 0}, - {0xe0, 0}, - {0xee, 0}, - }, - /* 181 */ - { - {0x8001, 171}, - {0xc016, 171}, - {0x8001, 206}, - {0xc016, 206}, - {0x8001, 215}, - {0xc016, 215}, - {0x8001, 225}, - {0xc016, 225}, - {0x8001, 236}, - {0xc016, 236}, - {0x8001, 237}, - {0xc016, 237}, - {0xc000, 199}, - {0xc000, 207}, - {0xc000, 234}, - {0xc000, 235}, - }, - /* 182 */ - { - {0x8002, 171}, - {0x8009, 171}, - {0x8017, 171}, - {0xc028, 171}, - {0x8002, 206}, - {0x8009, 206}, - {0x8017, 206}, - {0xc028, 206}, - {0x8002, 215}, - {0x8009, 215}, - {0x8017, 215}, - {0xc028, 215}, - {0x8002, 225}, - {0x8009, 225}, - {0x8017, 225}, - {0xc028, 225}, - }, - /* 183 */ - { - {0x8003, 171}, - {0x8006, 171}, - {0x800a, 171}, - {0x800f, 171}, - {0x8018, 171}, - {0x801f, 171}, - {0x8029, 171}, - {0xc038, 171}, - {0x8003, 206}, - {0x8006, 206}, - {0x800a, 206}, - {0x800f, 206}, - {0x8018, 206}, - {0x801f, 206}, - {0x8029, 206}, - {0xc038, 206}, - }, - /* 184 */ - { - {0x8003, 215}, - {0x8006, 215}, - {0x800a, 215}, - {0x800f, 215}, - {0x8018, 215}, - {0x801f, 215}, - {0x8029, 215}, - {0xc038, 215}, - {0x8003, 225}, - {0x8006, 225}, - {0x800a, 225}, - {0x800f, 225}, - {0x8018, 225}, - {0x801f, 225}, - {0x8029, 225}, - {0xc038, 225}, - }, - /* 185 */ - { - {0x8002, 236}, - {0x8009, 236}, - {0x8017, 236}, - {0xc028, 236}, - {0x8002, 237}, - {0x8009, 237}, - {0x8017, 237}, - {0xc028, 237}, - {0x8001, 199}, - {0xc016, 199}, - {0x8001, 207}, - {0xc016, 207}, - {0x8001, 234}, - {0xc016, 234}, - {0x8001, 235}, - {0xc016, 235}, - }, - /* 186 */ - { - {0x8003, 236}, - {0x8006, 236}, - {0x800a, 236}, - {0x800f, 236}, - {0x8018, 236}, - {0x801f, 236}, - {0x8029, 236}, - {0xc038, 236}, - {0x8003, 237}, - {0x8006, 237}, - {0x800a, 237}, - {0x800f, 237}, - {0x8018, 237}, - {0x801f, 237}, - {0x8029, 237}, - {0xc038, 237}, - }, - /* 187 */ - { - {0x8002, 199}, - {0x8009, 199}, - {0x8017, 199}, - {0xc028, 199}, - {0x8002, 207}, - {0x8009, 207}, - {0x8017, 207}, - {0xc028, 207}, - {0x8002, 234}, - {0x8009, 234}, - {0x8017, 234}, - {0xc028, 234}, - {0x8002, 235}, - {0x8009, 235}, - {0x8017, 235}, - {0xc028, 235}, - }, - /* 188 */ - { - {0x8003, 199}, - {0x8006, 199}, - {0x800a, 199}, - {0x800f, 199}, - {0x8018, 199}, - {0x801f, 199}, - {0x8029, 199}, - {0xc038, 199}, - {0x8003, 207}, - {0x8006, 207}, - {0x800a, 207}, - {0x800f, 207}, - {0x8018, 207}, - {0x801f, 207}, - {0x8029, 207}, - {0xc038, 207}, - }, - /* 189 */ - { - {0x8003, 234}, - {0x8006, 234}, - {0x800a, 234}, - {0x800f, 234}, - {0x8018, 234}, - {0x801f, 234}, - {0x8029, 234}, - {0xc038, 234}, - {0x8003, 235}, - {0x8006, 235}, - {0x800a, 235}, - {0x800f, 235}, - {0x8018, 235}, - {0x801f, 235}, - {0x8029, 235}, - {0xc038, 235}, - }, - /* 190 */ - { - {0xc2, 0}, - {0xc3, 0}, - {0xc5, 0}, - {0xc6, 0}, - {0xc9, 0}, - {0xca, 0}, - {0xcc, 0}, - {0xcd, 0}, - {0xd2, 0}, - {0xd5, 0}, - {0xd9, 0}, - {0xdc, 0}, - {0xe1, 0}, - {0xe7, 0}, - {0xef, 0}, - {0xf6, 0}, - }, - /* 191 */ - { - {0xc000, 192}, - {0xc000, 193}, - {0xc000, 200}, - {0xc000, 201}, - {0xc000, 202}, - {0xc000, 205}, - {0xc000, 210}, - {0xc000, 213}, - {0xc000, 218}, - {0xc000, 219}, - {0xc000, 238}, - {0xc000, 240}, - {0xc000, 242}, - {0xc000, 243}, - {0xc000, 255}, - {0xce, 0}, - }, - /* 192 */ - { - {0x8001, 192}, - {0xc016, 192}, - {0x8001, 193}, - {0xc016, 193}, - {0x8001, 200}, - {0xc016, 200}, - {0x8001, 201}, - {0xc016, 201}, - {0x8001, 202}, - {0xc016, 202}, - {0x8001, 205}, - {0xc016, 205}, - {0x8001, 210}, - {0xc016, 210}, - {0x8001, 213}, - {0xc016, 213}, - }, - /* 193 */ - { - {0x8002, 192}, - {0x8009, 192}, - {0x8017, 192}, - {0xc028, 192}, - {0x8002, 193}, - {0x8009, 193}, - {0x8017, 193}, - {0xc028, 193}, - {0x8002, 200}, - {0x8009, 200}, - {0x8017, 200}, - {0xc028, 200}, - {0x8002, 201}, - {0x8009, 201}, - {0x8017, 201}, - {0xc028, 201}, - }, - /* 194 */ - { - {0x8003, 192}, - {0x8006, 192}, - {0x800a, 192}, - {0x800f, 192}, - {0x8018, 192}, - {0x801f, 192}, - {0x8029, 192}, - {0xc038, 192}, - {0x8003, 193}, - {0x8006, 193}, - {0x800a, 193}, - {0x800f, 193}, - {0x8018, 193}, - {0x801f, 193}, - {0x8029, 193}, - {0xc038, 193}, - }, - /* 195 */ - { - {0x8003, 200}, - {0x8006, 200}, - {0x800a, 200}, - {0x800f, 200}, - {0x8018, 200}, - {0x801f, 200}, - {0x8029, 200}, - {0xc038, 200}, - {0x8003, 201}, - {0x8006, 201}, - {0x800a, 201}, - {0x800f, 201}, - {0x8018, 201}, - {0x801f, 201}, - {0x8029, 201}, - {0xc038, 201}, - }, - /* 196 */ - { - {0x8002, 202}, - {0x8009, 202}, - {0x8017, 202}, - {0xc028, 202}, - {0x8002, 205}, - {0x8009, 205}, - {0x8017, 205}, - {0xc028, 205}, - {0x8002, 210}, - {0x8009, 210}, - {0x8017, 210}, - {0xc028, 210}, - {0x8002, 213}, - {0x8009, 213}, - {0x8017, 213}, - {0xc028, 213}, - }, - /* 197 */ - { - {0x8003, 202}, - {0x8006, 202}, - {0x800a, 202}, - {0x800f, 202}, - {0x8018, 202}, - {0x801f, 202}, - {0x8029, 202}, - {0xc038, 202}, - {0x8003, 205}, - {0x8006, 205}, - {0x800a, 205}, - {0x800f, 205}, - {0x8018, 205}, - {0x801f, 205}, - {0x8029, 205}, - {0xc038, 205}, - }, - /* 198 */ - { - {0x8003, 210}, - {0x8006, 210}, - {0x800a, 210}, - {0x800f, 210}, - {0x8018, 210}, - {0x801f, 210}, - {0x8029, 210}, - {0xc038, 210}, - {0x8003, 213}, - {0x8006, 213}, - {0x800a, 213}, - {0x800f, 213}, - {0x8018, 213}, - {0x801f, 213}, - {0x8029, 213}, - {0xc038, 213}, - }, - /* 199 */ - { - {0x8001, 218}, - {0xc016, 218}, - {0x8001, 219}, - {0xc016, 219}, - {0x8001, 238}, - {0xc016, 238}, - {0x8001, 240}, - {0xc016, 240}, - {0x8001, 242}, - {0xc016, 242}, - {0x8001, 243}, - {0xc016, 243}, - {0x8001, 255}, - {0xc016, 255}, - {0xc000, 203}, - {0xc000, 204}, - }, - /* 200 */ - { - {0x8002, 218}, - {0x8009, 218}, - {0x8017, 218}, - {0xc028, 218}, - {0x8002, 219}, - {0x8009, 219}, - {0x8017, 219}, - {0xc028, 219}, - {0x8002, 238}, - {0x8009, 238}, - {0x8017, 238}, - {0xc028, 238}, - {0x8002, 240}, - {0x8009, 240}, - {0x8017, 240}, - {0xc028, 240}, - }, - /* 201 */ - { - {0x8003, 218}, - {0x8006, 218}, - {0x800a, 218}, - {0x800f, 218}, - {0x8018, 218}, - {0x801f, 218}, - {0x8029, 218}, - {0xc038, 218}, - {0x8003, 219}, - {0x8006, 219}, - {0x800a, 219}, - {0x800f, 219}, - {0x8018, 219}, - {0x801f, 219}, - {0x8029, 219}, - {0xc038, 219}, - }, - /* 202 */ - { - {0x8003, 238}, - {0x8006, 238}, - {0x800a, 238}, - {0x800f, 238}, - {0x8018, 238}, - {0x801f, 238}, - {0x8029, 238}, - {0xc038, 238}, - {0x8003, 240}, - {0x8006, 240}, - {0x800a, 240}, - {0x800f, 240}, - {0x8018, 240}, - {0x801f, 240}, - {0x8029, 240}, - {0xc038, 240}, - }, - /* 203 */ - { - {0x8002, 242}, - {0x8009, 242}, - {0x8017, 242}, - {0xc028, 242}, - {0x8002, 243}, - {0x8009, 243}, - {0x8017, 243}, - {0xc028, 243}, - {0x8002, 255}, - {0x8009, 255}, - {0x8017, 255}, - {0xc028, 255}, - {0x8001, 203}, - {0xc016, 203}, - {0x8001, 204}, - {0xc016, 204}, - }, - /* 204 */ - { - {0x8003, 242}, - {0x8006, 242}, - {0x800a, 242}, - {0x800f, 242}, - {0x8018, 242}, - {0x801f, 242}, - {0x8029, 242}, - {0xc038, 242}, - {0x8003, 243}, - {0x8006, 243}, - {0x800a, 243}, - {0x800f, 243}, - {0x8018, 243}, - {0x801f, 243}, - {0x8029, 243}, - {0xc038, 243}, - }, - /* 205 */ - { - {0x8003, 255}, - {0x8006, 255}, - {0x800a, 255}, - {0x800f, 255}, - {0x8018, 255}, - {0x801f, 255}, - {0x8029, 255}, - {0xc038, 255}, - {0x8002, 203}, - {0x8009, 203}, - {0x8017, 203}, - {0xc028, 203}, - {0x8002, 204}, - {0x8009, 204}, - {0x8017, 204}, - {0xc028, 204}, - }, - /* 206 */ - { - {0x8003, 203}, - {0x8006, 203}, - {0x800a, 203}, - {0x800f, 203}, - {0x8018, 203}, - {0x801f, 203}, - {0x8029, 203}, - {0xc038, 203}, - {0x8003, 204}, - {0x8006, 204}, - {0x800a, 204}, - {0x800f, 204}, - {0x8018, 204}, - {0x801f, 204}, - {0x8029, 204}, - {0xc038, 204}, - }, - /* 207 */ - { - {0xd3, 0}, - {0xd4, 0}, - {0xd6, 0}, - {0xd7, 0}, - {0xda, 0}, - {0xdb, 0}, - {0xdd, 0}, - {0xde, 0}, - {0xe2, 0}, - {0xe4, 0}, - {0xe8, 0}, - {0xeb, 0}, - {0xf0, 0}, - {0xf3, 0}, - {0xf7, 0}, - {0xfa, 0}, - }, - /* 208 */ - { - {0xc000, 211}, - {0xc000, 212}, - {0xc000, 214}, - {0xc000, 221}, - {0xc000, 222}, - {0xc000, 223}, - {0xc000, 241}, - {0xc000, 244}, - {0xc000, 245}, - {0xc000, 246}, - {0xc000, 247}, - {0xc000, 248}, - {0xc000, 250}, - {0xc000, 251}, - {0xc000, 252}, - {0xc000, 253}, - }, - /* 209 */ - { - {0x8001, 211}, - {0xc016, 211}, - {0x8001, 212}, - {0xc016, 212}, - {0x8001, 214}, - {0xc016, 214}, - {0x8001, 221}, - {0xc016, 221}, - {0x8001, 222}, - {0xc016, 222}, - {0x8001, 223}, - {0xc016, 223}, - {0x8001, 241}, - {0xc016, 241}, - {0x8001, 244}, - {0xc016, 244}, - }, - /* 210 */ - { - {0x8002, 211}, - {0x8009, 211}, - {0x8017, 211}, - {0xc028, 211}, - {0x8002, 212}, - {0x8009, 212}, - {0x8017, 212}, - {0xc028, 212}, - {0x8002, 214}, - {0x8009, 214}, - {0x8017, 214}, - {0xc028, 214}, - {0x8002, 221}, - {0x8009, 221}, - {0x8017, 221}, - {0xc028, 221}, - }, - /* 211 */ - { - {0x8003, 211}, - {0x8006, 211}, - {0x800a, 211}, - {0x800f, 211}, - {0x8018, 211}, - {0x801f, 211}, - {0x8029, 211}, - {0xc038, 211}, - {0x8003, 212}, - {0x8006, 212}, - {0x800a, 212}, - {0x800f, 212}, - {0x8018, 212}, - {0x801f, 212}, - {0x8029, 212}, - {0xc038, 212}, - }, - /* 212 */ - { - {0x8003, 214}, - {0x8006, 214}, - {0x800a, 214}, - {0x800f, 214}, - {0x8018, 214}, - {0x801f, 214}, - {0x8029, 214}, - {0xc038, 214}, - {0x8003, 221}, - {0x8006, 221}, - {0x800a, 221}, - {0x800f, 221}, - {0x8018, 221}, - {0x801f, 221}, - {0x8029, 221}, - {0xc038, 221}, - }, - /* 213 */ - { - {0x8002, 222}, - {0x8009, 222}, - {0x8017, 222}, - {0xc028, 222}, - {0x8002, 223}, - {0x8009, 223}, - {0x8017, 223}, - {0xc028, 223}, - {0x8002, 241}, - {0x8009, 241}, - {0x8017, 241}, - {0xc028, 241}, - {0x8002, 244}, - {0x8009, 244}, - {0x8017, 244}, - {0xc028, 244}, - }, - /* 214 */ - { - {0x8003, 222}, - {0x8006, 222}, - {0x800a, 222}, - {0x800f, 222}, - {0x8018, 222}, - {0x801f, 222}, - {0x8029, 222}, - {0xc038, 222}, - {0x8003, 223}, - {0x8006, 223}, - {0x800a, 223}, - {0x800f, 223}, - {0x8018, 223}, - {0x801f, 223}, - {0x8029, 223}, - {0xc038, 223}, - }, - /* 215 */ - { - {0x8003, 241}, - {0x8006, 241}, - {0x800a, 241}, - {0x800f, 241}, - {0x8018, 241}, - {0x801f, 241}, - {0x8029, 241}, - {0xc038, 241}, - {0x8003, 244}, - {0x8006, 244}, - {0x800a, 244}, - {0x800f, 244}, - {0x8018, 244}, - {0x801f, 244}, - {0x8029, 244}, - {0xc038, 244}, - }, - /* 216 */ - { - {0x8001, 245}, - {0xc016, 245}, - {0x8001, 246}, - {0xc016, 246}, - {0x8001, 247}, - {0xc016, 247}, - {0x8001, 248}, - {0xc016, 248}, - {0x8001, 250}, - {0xc016, 250}, - {0x8001, 251}, - {0xc016, 251}, - {0x8001, 252}, - {0xc016, 252}, - {0x8001, 253}, - {0xc016, 253}, - }, - /* 217 */ - { - {0x8002, 245}, - {0x8009, 245}, - {0x8017, 245}, - {0xc028, 245}, - {0x8002, 246}, - {0x8009, 246}, - {0x8017, 246}, - {0xc028, 246}, - {0x8002, 247}, - {0x8009, 247}, - {0x8017, 247}, - {0xc028, 247}, - {0x8002, 248}, - {0x8009, 248}, - {0x8017, 248}, - {0xc028, 248}, - }, - /* 218 */ - { - {0x8003, 245}, - {0x8006, 245}, - {0x800a, 245}, - {0x800f, 245}, - {0x8018, 245}, - {0x801f, 245}, - {0x8029, 245}, - {0xc038, 245}, - {0x8003, 246}, - {0x8006, 246}, - {0x800a, 246}, - {0x800f, 246}, - {0x8018, 246}, - {0x801f, 246}, - {0x8029, 246}, - {0xc038, 246}, - }, - /* 219 */ - { - {0x8003, 247}, - {0x8006, 247}, - {0x800a, 247}, - {0x800f, 247}, - {0x8018, 247}, - {0x801f, 247}, - {0x8029, 247}, - {0xc038, 247}, - {0x8003, 248}, - {0x8006, 248}, - {0x800a, 248}, - {0x800f, 248}, - {0x8018, 248}, - {0x801f, 248}, - {0x8029, 248}, - {0xc038, 248}, - }, - /* 220 */ - { - {0x8002, 250}, - {0x8009, 250}, - {0x8017, 250}, - {0xc028, 250}, - {0x8002, 251}, - {0x8009, 251}, - {0x8017, 251}, - {0xc028, 251}, - {0x8002, 252}, - {0x8009, 252}, - {0x8017, 252}, - {0xc028, 252}, - {0x8002, 253}, - {0x8009, 253}, - {0x8017, 253}, - {0xc028, 253}, - }, - /* 221 */ - { - {0x8003, 250}, - {0x8006, 250}, - {0x800a, 250}, - {0x800f, 250}, - {0x8018, 250}, - {0x801f, 250}, - {0x8029, 250}, - {0xc038, 250}, - {0x8003, 251}, - {0x8006, 251}, - {0x800a, 251}, - {0x800f, 251}, - {0x8018, 251}, - {0x801f, 251}, - {0x8029, 251}, - {0xc038, 251}, - }, - /* 222 */ - { - {0x8003, 252}, - {0x8006, 252}, - {0x800a, 252}, - {0x800f, 252}, - {0x8018, 252}, - {0x801f, 252}, - {0x8029, 252}, - {0xc038, 252}, - {0x8003, 253}, - {0x8006, 253}, - {0x800a, 253}, - {0x800f, 253}, - {0x8018, 253}, - {0x801f, 253}, - {0x8029, 253}, - {0xc038, 253}, - }, - /* 223 */ - { - {0xc000, 254}, - {0xe3, 0}, - {0xe5, 0}, - {0xe6, 0}, - {0xe9, 0}, - {0xea, 0}, - {0xec, 0}, - {0xed, 0}, - {0xf1, 0}, - {0xf2, 0}, - {0xf4, 0}, - {0xf5, 0}, - {0xf8, 0}, - {0xf9, 0}, - {0xfb, 0}, - {0xfc, 0}, - }, - /* 224 */ - { - {0x8001, 254}, - {0xc016, 254}, - {0xc000, 2}, - {0xc000, 3}, - {0xc000, 4}, - {0xc000, 5}, - {0xc000, 6}, - {0xc000, 7}, - {0xc000, 8}, - {0xc000, 11}, - {0xc000, 12}, - {0xc000, 14}, - {0xc000, 15}, - {0xc000, 16}, - {0xc000, 17}, - {0xc000, 18}, - }, - /* 225 */ - { - {0x8002, 254}, - {0x8009, 254}, - {0x8017, 254}, - {0xc028, 254}, - {0x8001, 2}, - {0xc016, 2}, - {0x8001, 3}, - {0xc016, 3}, - {0x8001, 4}, - {0xc016, 4}, - {0x8001, 5}, - {0xc016, 5}, - {0x8001, 6}, - {0xc016, 6}, - {0x8001, 7}, - {0xc016, 7}, - }, - /* 226 */ - { - {0x8003, 254}, - {0x8006, 254}, - {0x800a, 254}, - {0x800f, 254}, - {0x8018, 254}, - {0x801f, 254}, - {0x8029, 254}, - {0xc038, 254}, - {0x8002, 2}, - {0x8009, 2}, - {0x8017, 2}, - {0xc028, 2}, - {0x8002, 3}, - {0x8009, 3}, - {0x8017, 3}, - {0xc028, 3}, - }, - /* 227 */ - { - {0x8003, 2}, - {0x8006, 2}, - {0x800a, 2}, - {0x800f, 2}, - {0x8018, 2}, - {0x801f, 2}, - {0x8029, 2}, - {0xc038, 2}, - {0x8003, 3}, - {0x8006, 3}, - {0x800a, 3}, - {0x800f, 3}, - {0x8018, 3}, - {0x801f, 3}, - {0x8029, 3}, - {0xc038, 3}, - }, - /* 228 */ - { - {0x8002, 4}, - {0x8009, 4}, - {0x8017, 4}, - {0xc028, 4}, - {0x8002, 5}, - {0x8009, 5}, - {0x8017, 5}, - {0xc028, 5}, - {0x8002, 6}, - {0x8009, 6}, - {0x8017, 6}, - {0xc028, 6}, - {0x8002, 7}, - {0x8009, 7}, - {0x8017, 7}, - {0xc028, 7}, - }, - /* 229 */ - { - {0x8003, 4}, - {0x8006, 4}, - {0x800a, 4}, - {0x800f, 4}, - {0x8018, 4}, - {0x801f, 4}, - {0x8029, 4}, - {0xc038, 4}, - {0x8003, 5}, - {0x8006, 5}, - {0x800a, 5}, - {0x800f, 5}, - {0x8018, 5}, - {0x801f, 5}, - {0x8029, 5}, - {0xc038, 5}, - }, - /* 230 */ - { - {0x8003, 6}, - {0x8006, 6}, - {0x800a, 6}, - {0x800f, 6}, - {0x8018, 6}, - {0x801f, 6}, - {0x8029, 6}, - {0xc038, 6}, - {0x8003, 7}, - {0x8006, 7}, - {0x800a, 7}, - {0x800f, 7}, - {0x8018, 7}, - {0x801f, 7}, - {0x8029, 7}, - {0xc038, 7}, - }, - /* 231 */ - { - {0x8001, 8}, - {0xc016, 8}, - {0x8001, 11}, - {0xc016, 11}, - {0x8001, 12}, - {0xc016, 12}, - {0x8001, 14}, - {0xc016, 14}, - {0x8001, 15}, - {0xc016, 15}, - {0x8001, 16}, - {0xc016, 16}, - {0x8001, 17}, - {0xc016, 17}, - {0x8001, 18}, - {0xc016, 18}, - }, - /* 232 */ - { - {0x8002, 8}, - {0x8009, 8}, - {0x8017, 8}, - {0xc028, 8}, - {0x8002, 11}, - {0x8009, 11}, - {0x8017, 11}, - {0xc028, 11}, - {0x8002, 12}, - {0x8009, 12}, - {0x8017, 12}, - {0xc028, 12}, - {0x8002, 14}, - {0x8009, 14}, - {0x8017, 14}, - {0xc028, 14}, - }, - /* 233 */ - { - {0x8003, 8}, - {0x8006, 8}, - {0x800a, 8}, - {0x800f, 8}, - {0x8018, 8}, - {0x801f, 8}, - {0x8029, 8}, - {0xc038, 8}, - {0x8003, 11}, - {0x8006, 11}, - {0x800a, 11}, - {0x800f, 11}, - {0x8018, 11}, - {0x801f, 11}, - {0x8029, 11}, - {0xc038, 11}, - }, - /* 234 */ - { - {0x8003, 12}, - {0x8006, 12}, - {0x800a, 12}, - {0x800f, 12}, - {0x8018, 12}, - {0x801f, 12}, - {0x8029, 12}, - {0xc038, 12}, - {0x8003, 14}, - {0x8006, 14}, - {0x800a, 14}, - {0x800f, 14}, - {0x8018, 14}, - {0x801f, 14}, - {0x8029, 14}, - {0xc038, 14}, - }, - /* 235 */ - { - {0x8002, 15}, - {0x8009, 15}, - {0x8017, 15}, - {0xc028, 15}, - {0x8002, 16}, - {0x8009, 16}, - {0x8017, 16}, - {0xc028, 16}, - {0x8002, 17}, - {0x8009, 17}, - {0x8017, 17}, - {0xc028, 17}, - {0x8002, 18}, - {0x8009, 18}, - {0x8017, 18}, - {0xc028, 18}, - }, - /* 236 */ - { - {0x8003, 15}, - {0x8006, 15}, - {0x800a, 15}, - {0x800f, 15}, - {0x8018, 15}, - {0x801f, 15}, - {0x8029, 15}, - {0xc038, 15}, - {0x8003, 16}, - {0x8006, 16}, - {0x800a, 16}, - {0x800f, 16}, - {0x8018, 16}, - {0x801f, 16}, - {0x8029, 16}, - {0xc038, 16}, - }, - /* 237 */ - { - {0x8003, 17}, - {0x8006, 17}, - {0x800a, 17}, - {0x800f, 17}, - {0x8018, 17}, - {0x801f, 17}, - {0x8029, 17}, - {0xc038, 17}, - {0x8003, 18}, - {0x8006, 18}, - {0x800a, 18}, - {0x800f, 18}, - {0x8018, 18}, - {0x801f, 18}, - {0x8029, 18}, - {0xc038, 18}, - }, - /* 238 */ - { - {0xc000, 19}, - {0xc000, 20}, - {0xc000, 21}, - {0xc000, 23}, - {0xc000, 24}, - {0xc000, 25}, - {0xc000, 26}, - {0xc000, 27}, - {0xc000, 28}, - {0xc000, 29}, - {0xc000, 30}, - {0xc000, 31}, - {0xc000, 127}, - {0xc000, 220}, - {0xc000, 249}, - {0xfd, 0}, - }, - /* 239 */ - { - {0x8001, 19}, - {0xc016, 19}, - {0x8001, 20}, - {0xc016, 20}, - {0x8001, 21}, - {0xc016, 21}, - {0x8001, 23}, - {0xc016, 23}, - {0x8001, 24}, - {0xc016, 24}, - {0x8001, 25}, - {0xc016, 25}, - {0x8001, 26}, - {0xc016, 26}, - {0x8001, 27}, - {0xc016, 27}, - }, - /* 240 */ - { - {0x8002, 19}, - {0x8009, 19}, - {0x8017, 19}, - {0xc028, 19}, - {0x8002, 20}, - {0x8009, 20}, - {0x8017, 20}, - {0xc028, 20}, - {0x8002, 21}, - {0x8009, 21}, - {0x8017, 21}, - {0xc028, 21}, - {0x8002, 23}, - {0x8009, 23}, - {0x8017, 23}, - {0xc028, 23}, - }, - /* 241 */ - { - {0x8003, 19}, - {0x8006, 19}, - {0x800a, 19}, - {0x800f, 19}, - {0x8018, 19}, - {0x801f, 19}, - {0x8029, 19}, - {0xc038, 19}, - {0x8003, 20}, - {0x8006, 20}, - {0x800a, 20}, - {0x800f, 20}, - {0x8018, 20}, - {0x801f, 20}, - {0x8029, 20}, - {0xc038, 20}, - }, - /* 242 */ - { - {0x8003, 21}, - {0x8006, 21}, - {0x800a, 21}, - {0x800f, 21}, - {0x8018, 21}, - {0x801f, 21}, - {0x8029, 21}, - {0xc038, 21}, - {0x8003, 23}, - {0x8006, 23}, - {0x800a, 23}, - {0x800f, 23}, - {0x8018, 23}, - {0x801f, 23}, - {0x8029, 23}, - {0xc038, 23}, - }, - /* 243 */ - { - {0x8002, 24}, - {0x8009, 24}, - {0x8017, 24}, - {0xc028, 24}, - {0x8002, 25}, - {0x8009, 25}, - {0x8017, 25}, - {0xc028, 25}, - {0x8002, 26}, - {0x8009, 26}, - {0x8017, 26}, - {0xc028, 26}, - {0x8002, 27}, - {0x8009, 27}, - {0x8017, 27}, - {0xc028, 27}, - }, - /* 244 */ - { - {0x8003, 24}, - {0x8006, 24}, - {0x800a, 24}, - {0x800f, 24}, - {0x8018, 24}, - {0x801f, 24}, - {0x8029, 24}, - {0xc038, 24}, - {0x8003, 25}, - {0x8006, 25}, - {0x800a, 25}, - {0x800f, 25}, - {0x8018, 25}, - {0x801f, 25}, - {0x8029, 25}, - {0xc038, 25}, - }, - /* 245 */ - { - {0x8003, 26}, - {0x8006, 26}, - {0x800a, 26}, - {0x800f, 26}, - {0x8018, 26}, - {0x801f, 26}, - {0x8029, 26}, - {0xc038, 26}, - {0x8003, 27}, - {0x8006, 27}, - {0x800a, 27}, - {0x800f, 27}, - {0x8018, 27}, - {0x801f, 27}, - {0x8029, 27}, - {0xc038, 27}, - }, - /* 246 */ - { - {0x8001, 28}, - {0xc016, 28}, - {0x8001, 29}, - {0xc016, 29}, - {0x8001, 30}, - {0xc016, 30}, - {0x8001, 31}, - {0xc016, 31}, - {0x8001, 127}, - {0xc016, 127}, - {0x8001, 220}, - {0xc016, 220}, - {0x8001, 249}, - {0xc016, 249}, - {0xfe, 0}, - {0xff, 0}, - }, - /* 247 */ - { - {0x8002, 28}, - {0x8009, 28}, - {0x8017, 28}, - {0xc028, 28}, - {0x8002, 29}, - {0x8009, 29}, - {0x8017, 29}, - {0xc028, 29}, - {0x8002, 30}, - {0x8009, 30}, - {0x8017, 30}, - {0xc028, 30}, - {0x8002, 31}, - {0x8009, 31}, - {0x8017, 31}, - {0xc028, 31}, - }, - /* 248 */ - { - {0x8003, 28}, - {0x8006, 28}, - {0x800a, 28}, - {0x800f, 28}, - {0x8018, 28}, - {0x801f, 28}, - {0x8029, 28}, - {0xc038, 28}, - {0x8003, 29}, - {0x8006, 29}, - {0x800a, 29}, - {0x800f, 29}, - {0x8018, 29}, - {0x801f, 29}, - {0x8029, 29}, - {0xc038, 29}, - }, - /* 249 */ - { - {0x8003, 30}, - {0x8006, 30}, - {0x800a, 30}, - {0x800f, 30}, - {0x8018, 30}, - {0x801f, 30}, - {0x8029, 30}, - {0xc038, 30}, - {0x8003, 31}, - {0x8006, 31}, - {0x800a, 31}, - {0x800f, 31}, - {0x8018, 31}, - {0x801f, 31}, - {0x8029, 31}, - {0xc038, 31}, - }, - /* 250 */ - { - {0x8002, 127}, - {0x8009, 127}, - {0x8017, 127}, - {0xc028, 127}, - {0x8002, 220}, - {0x8009, 220}, - {0x8017, 220}, - {0xc028, 220}, - {0x8002, 249}, - {0x8009, 249}, - {0x8017, 249}, - {0xc028, 249}, - {0xc000, 10}, - {0xc000, 13}, - {0xc000, 22}, - {0x100, 0}, - }, - /* 251 */ - { - {0x8003, 127}, - {0x8006, 127}, - {0x800a, 127}, - {0x800f, 127}, - {0x8018, 127}, - {0x801f, 127}, - {0x8029, 127}, - {0xc038, 127}, - {0x8003, 220}, - {0x8006, 220}, - {0x800a, 220}, - {0x800f, 220}, - {0x8018, 220}, - {0x801f, 220}, - {0x8029, 220}, - {0xc038, 220}, - }, - /* 252 */ - { - {0x8003, 249}, - {0x8006, 249}, - {0x800a, 249}, - {0x800f, 249}, - {0x8018, 249}, - {0x801f, 249}, - {0x8029, 249}, - {0xc038, 249}, - {0x8001, 10}, - {0xc016, 10}, - {0x8001, 13}, - {0xc016, 13}, - {0x8001, 22}, - {0xc016, 22}, - {0x100, 0}, - {0x100, 0}, - }, - /* 253 */ - { - {0x8002, 10}, - {0x8009, 10}, - {0x8017, 10}, - {0xc028, 10}, - {0x8002, 13}, - {0x8009, 13}, - {0x8017, 13}, - {0xc028, 13}, - {0x8002, 22}, - {0x8009, 22}, - {0x8017, 22}, - {0xc028, 22}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, - /* 254 */ - { - {0x8003, 10}, - {0x8006, 10}, - {0x800a, 10}, - {0x800f, 10}, - {0x8018, 10}, - {0x801f, 10}, - {0x8029, 10}, - {0xc038, 10}, - {0x8003, 13}, - {0x8006, 13}, - {0x800a, 13}, - {0x800f, 13}, - {0x8018, 13}, - {0x801f, 13}, - {0x8029, 13}, - {0xc038, 13}, - }, - /* 255 */ - { - {0x8003, 22}, - {0x8006, 22}, - {0x800a, 22}, - {0x800f, 22}, - {0x8018, 22}, - {0x801f, 22}, - {0x8029, 22}, - {0xc038, 22}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, - /* 256 */ - { - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, -}; diff --git a/vendor/nghttp2/lib/nghttp2_helper.c b/vendor/nghttp2/lib/nghttp2_helper.c deleted file mode 100644 index f54f37c13..000000000 --- a/vendor/nghttp2/lib/nghttp2_helper.c +++ /dev/null @@ -1,805 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_helper.h" - -#include -#include - -#include "nghttp2_net.h" - -void nghttp2_put_uint16be(uint8_t *buf, uint16_t n) { - uint16_t x = htons(n); - memcpy(buf, &x, sizeof(uint16_t)); -} - -void nghttp2_put_uint32be(uint8_t *buf, uint32_t n) { - uint32_t x = htonl(n); - memcpy(buf, &x, sizeof(uint32_t)); -} - -uint16_t nghttp2_get_uint16(const uint8_t *data) { - uint16_t n; - memcpy(&n, data, sizeof(uint16_t)); - return ntohs(n); -} - -uint32_t nghttp2_get_uint32(const uint8_t *data) { - uint32_t n; - memcpy(&n, data, sizeof(uint32_t)); - return ntohl(n); -} - -/* Generated by gendowncasetbl.py */ -static const uint8_t DOWNCASE_TBL[] = { - 0 /* NUL */, 1 /* SOH */, 2 /* STX */, 3 /* ETX */, - 4 /* EOT */, 5 /* ENQ */, 6 /* ACK */, 7 /* BEL */, - 8 /* BS */, 9 /* HT */, 10 /* LF */, 11 /* VT */, - 12 /* FF */, 13 /* CR */, 14 /* SO */, 15 /* SI */, - 16 /* DLE */, 17 /* DC1 */, 18 /* DC2 */, 19 /* DC3 */, - 20 /* DC4 */, 21 /* NAK */, 22 /* SYN */, 23 /* ETB */, - 24 /* CAN */, 25 /* EM */, 26 /* SUB */, 27 /* ESC */, - 28 /* FS */, 29 /* GS */, 30 /* RS */, 31 /* US */, - 32 /* SPC */, 33 /* ! */, 34 /* " */, 35 /* # */, - 36 /* $ */, 37 /* % */, 38 /* & */, 39 /* ' */, - 40 /* ( */, 41 /* ) */, 42 /* * */, 43 /* + */, - 44 /* , */, 45 /* - */, 46 /* . */, 47 /* / */, - 48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */, - 52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */, - 56 /* 8 */, 57 /* 9 */, 58 /* : */, 59 /* ; */, - 60 /* < */, 61 /* = */, 62 /* > */, 63 /* ? */, - 64 /* @ */, 97 /* A */, 98 /* B */, 99 /* C */, - 100 /* D */, 101 /* E */, 102 /* F */, 103 /* G */, - 104 /* H */, 105 /* I */, 106 /* J */, 107 /* K */, - 108 /* L */, 109 /* M */, 110 /* N */, 111 /* O */, - 112 /* P */, 113 /* Q */, 114 /* R */, 115 /* S */, - 116 /* T */, 117 /* U */, 118 /* V */, 119 /* W */, - 120 /* X */, 121 /* Y */, 122 /* Z */, 91 /* [ */, - 92 /* \ */, 93 /* ] */, 94 /* ^ */, 95 /* _ */, - 96 /* ` */, 97 /* a */, 98 /* b */, 99 /* c */, - 100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */, - 104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */, - 108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */, - 112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */, - 116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */, - 120 /* x */, 121 /* y */, 122 /* z */, 123 /* { */, - 124 /* | */, 125 /* } */, 126 /* ~ */, 127 /* DEL */, - 128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */, - 132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */, - 136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */, - 140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */, - 144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */, - 148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */, - 152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */, - 156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */, - 160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */, - 164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */, - 168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */, - 172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */, - 176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */, - 180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */, - 184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */, - 188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */, - 192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */, - 196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */, - 200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */, - 204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */, - 208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */, - 212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */, - 216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */, - 220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */, - 224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */, - 228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */, - 232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */, - 236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */, - 240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */, - 244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */, - 248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */, - 252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */, -}; - -void nghttp2_downcase(uint8_t *s, size_t len) { - size_t i; - for (i = 0; i < len; ++i) { - s[i] = DOWNCASE_TBL[s[i]]; - } -} - -/* - * local_window_size - * ^ * - * | * recv_window_size - * | * * ^ - * | * * | - * 0+++++++++ - * | * * \ - * | * * | This rage is hidden in flow control. But it must be - * v * * / kept in order to restore it when window size is enlarged. - * recv_reduction - * (+ for negative direction) - * - * recv_window_size could be negative if we decrease - * local_window_size more than recv_window_size: - * - * local_window_size - * ^ * - * | * - * | * - * 0++++++++ - * | * ^ recv_window_size (negative) - * | * | - * v * * - * recv_reduction - */ -int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr, - int32_t *recv_window_size_ptr, - int32_t *recv_reduction_ptr, - int32_t *delta_ptr) { - if (*delta_ptr > 0) { - int32_t recv_reduction_delta; - int32_t delta; - int32_t new_recv_window_size = - nghttp2_max_int32(0, *recv_window_size_ptr) - *delta_ptr; - - if (new_recv_window_size >= 0) { - *recv_window_size_ptr = new_recv_window_size; - return 0; - } - - delta = -new_recv_window_size; - - /* The delta size is strictly more than received bytes. Increase - local_window_size by that difference |delta|. */ - if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) { - return NGHTTP2_ERR_FLOW_CONTROL; - } - *local_window_size_ptr += delta; - /* If there is recv_reduction due to earlier window_size - reduction, we have to adjust it too. */ - recv_reduction_delta = nghttp2_min_int32(*recv_reduction_ptr, delta); - *recv_reduction_ptr -= recv_reduction_delta; - if (*recv_window_size_ptr < 0) { - *recv_window_size_ptr += recv_reduction_delta; - } else { - /* If *recv_window_size_ptr > 0, then those bytes are going to - be returned to the remote peer (by WINDOW_UPDATE with the - adjusted *delta_ptr), so it is effectively 0 now. We set to - *recv_reduction_delta, because caller does not take into - account it in *delta_ptr. */ - *recv_window_size_ptr = recv_reduction_delta; - } - /* recv_reduction_delta must be paid from *delta_ptr, since it was - added in window size reduction (see below). */ - *delta_ptr -= recv_reduction_delta; - - return 0; - } - - if (*local_window_size_ptr + *delta_ptr < 0 || - *recv_window_size_ptr < INT32_MIN - *delta_ptr || - *recv_reduction_ptr > INT32_MAX + *delta_ptr) { - return NGHTTP2_ERR_FLOW_CONTROL; - } - /* Decreasing local window size. Note that we achieve this without - noticing to the remote peer. To do this, we cut - recv_window_size by -delta. This means that we don't send - WINDOW_UPDATE for -delta bytes. */ - *local_window_size_ptr += *delta_ptr; - *recv_window_size_ptr += *delta_ptr; - *recv_reduction_ptr -= *delta_ptr; - *delta_ptr = 0; - - return 0; -} - -int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr, - int32_t *recv_window_size_ptr, - int32_t *recv_reduction_ptr, - int32_t *delta_ptr) { - int32_t recv_reduction_delta; - int32_t delta; - - delta = *delta_ptr; - - assert(delta >= 0); - - /* The delta size is strictly more than received bytes. Increase - local_window_size by that difference |delta|. */ - if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) { - return NGHTTP2_ERR_FLOW_CONTROL; - } - - *local_window_size_ptr += delta; - /* If there is recv_reduction due to earlier window_size - reduction, we have to adjust it too. */ - recv_reduction_delta = nghttp2_min_int32(*recv_reduction_ptr, delta); - *recv_reduction_ptr -= recv_reduction_delta; - - *recv_window_size_ptr += recv_reduction_delta; - - /* recv_reduction_delta must be paid from *delta_ptr, since it was - added in window size reduction (see below). */ - *delta_ptr -= recv_reduction_delta; - - return 0; -} - -int nghttp2_should_send_window_update(int32_t local_window_size, - int32_t recv_window_size) { - return recv_window_size > 0 && recv_window_size >= local_window_size / 2; -} - -const char *nghttp2_strerror(int error_code) { - switch (error_code) { - case 0: - return "Success"; - case NGHTTP2_ERR_INVALID_ARGUMENT: - return "Invalid argument"; - case NGHTTP2_ERR_BUFFER_ERROR: - return "Out of buffer space"; - case NGHTTP2_ERR_UNSUPPORTED_VERSION: - return "Unsupported SPDY version"; - case NGHTTP2_ERR_WOULDBLOCK: - return "Operation would block"; - case NGHTTP2_ERR_PROTO: - return "Protocol error"; - case NGHTTP2_ERR_INVALID_FRAME: - return "Invalid frame octets"; - case NGHTTP2_ERR_EOF: - return "EOF"; - case NGHTTP2_ERR_DEFERRED: - return "Data transfer deferred"; - case NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE: - return "No more Stream ID available"; - case NGHTTP2_ERR_STREAM_CLOSED: - return "Stream was already closed or invalid"; - case NGHTTP2_ERR_STREAM_CLOSING: - return "Stream is closing"; - case NGHTTP2_ERR_STREAM_SHUT_WR: - return "The transmission is not allowed for this stream"; - case NGHTTP2_ERR_INVALID_STREAM_ID: - return "Stream ID is invalid"; - case NGHTTP2_ERR_INVALID_STREAM_STATE: - return "Invalid stream state"; - case NGHTTP2_ERR_DEFERRED_DATA_EXIST: - return "Another DATA frame has already been deferred"; - case NGHTTP2_ERR_START_STREAM_NOT_ALLOWED: - return "request HEADERS is not allowed"; - case NGHTTP2_ERR_GOAWAY_ALREADY_SENT: - return "GOAWAY has already been sent"; - case NGHTTP2_ERR_INVALID_HEADER_BLOCK: - return "Invalid header block"; - case NGHTTP2_ERR_INVALID_STATE: - return "Invalid state"; - case NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE: - return "The user callback function failed due to the temporal error"; - case NGHTTP2_ERR_FRAME_SIZE_ERROR: - return "The length of the frame is invalid"; - case NGHTTP2_ERR_HEADER_COMP: - return "Header compression/decompression error"; - case NGHTTP2_ERR_FLOW_CONTROL: - return "Flow control error"; - case NGHTTP2_ERR_INSUFF_BUFSIZE: - return "Insufficient buffer size given to function"; - case NGHTTP2_ERR_PAUSE: - return "Callback was paused by the application"; - case NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS: - return "Too many inflight SETTINGS"; - case NGHTTP2_ERR_PUSH_DISABLED: - return "Server push is disabled by peer"; - case NGHTTP2_ERR_DATA_EXIST: - return "DATA or HEADERS frame has already been submitted for the stream"; - case NGHTTP2_ERR_SESSION_CLOSING: - return "The current session is closing"; - case NGHTTP2_ERR_HTTP_HEADER: - return "Invalid HTTP header field was received"; - case NGHTTP2_ERR_HTTP_MESSAGING: - return "Violation in HTTP messaging rule"; - case NGHTTP2_ERR_REFUSED_STREAM: - return "Stream was refused"; - case NGHTTP2_ERR_INTERNAL: - return "Internal error"; - case NGHTTP2_ERR_CANCEL: - return "Cancel"; - case NGHTTP2_ERR_SETTINGS_EXPECTED: - return "When a local endpoint expects to receive SETTINGS frame, it " - "receives an other type of frame"; - case NGHTTP2_ERR_NOMEM: - return "Out of memory"; - case NGHTTP2_ERR_CALLBACK_FAILURE: - return "The user callback function failed"; - case NGHTTP2_ERR_BAD_CLIENT_MAGIC: - return "Received bad client magic byte string"; - case NGHTTP2_ERR_FLOODED: - return "Flooding was detected in this HTTP/2 session, and it must be " - "closed"; - case NGHTTP2_ERR_TOO_MANY_SETTINGS: - return "SETTINGS frame contained more than the maximum allowed entries"; - case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS: - return "Too many CONTINUATION frames following a HEADER frame"; - default: - return "Unknown error code"; - } -} - -/* Generated by gennmchartbl.py */ -static const int VALID_HD_NAME_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, - 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, - 0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */, - 0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */, - 0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */, - 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */, - 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, - 0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */, - 0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */, - 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ -}; - -int nghttp2_check_header_name(const uint8_t *name, size_t len) { - const uint8_t *last; - if (len == 0) { - return 0; - } - if (*name == ':') { - if (len == 1) { - return 0; - } - ++name; - --len; - } - for (last = name + len; name != last; ++name) { - if (!VALID_HD_NAME_CHARS[*name]) { - return 0; - } - } - return 1; -} - -/* Generated by genvchartbl.py */ -static const int VALID_HD_VALUE_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, - 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, - 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, - 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, - 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, - 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, - 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, - 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, - 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, - 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, - 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, - 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, - 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, - 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, - 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, - 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, - 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, - 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, - 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, - 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, - 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, - 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, - 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, - 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, - 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, - 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, - 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, - 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, - 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, - 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, - 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, - 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, - 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, - 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ -}; - -int nghttp2_check_header_value(const uint8_t *value, size_t len) { - const uint8_t *last; - for (last = value + len; value != last; ++value) { - if (!VALID_HD_VALUE_CHARS[*value]) { - return 0; - } - } - return 1; -} - -int nghttp2_check_header_value_rfc9113(const uint8_t *value, size_t len) { - if (len == 0) { - return 1; - } - - if (*value == ' ' || *value == '\t' || *(value + len - 1) == ' ' || - *(value + len - 1) == '\t') { - return 0; - } - - return nghttp2_check_header_value(value, len); -} - -/* Generated by genmethodchartbl.py */ -static char VALID_METHOD_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, - 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, - 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */, - 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ -}; - -int nghttp2_check_method(const uint8_t *value, size_t len) { - const uint8_t *last; - if (len == 0) { - return 0; - } - for (last = value + len; value != last; ++value) { - if (!VALID_METHOD_CHARS[*value]) { - return 0; - } - } - return 1; -} - -/* Generated by genpathchartbl.py */ -static char VALID_PATH_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, - 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, - 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, - 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, - 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, - 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, - 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, - 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, - 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, - 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, - 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, - 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, - 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, - 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, - 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, - 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, - 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, - 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, - 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, - 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, - 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, - 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, - 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, - 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, - 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, - 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, - 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, - 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, - 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, - 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, - 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, - 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, - 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, - 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ -}; - -int nghttp2_check_path(const uint8_t *value, size_t len) { - const uint8_t *last; - for (last = value + len; value != last; ++value) { - if (!VALID_PATH_CHARS[*value]) { - return 0; - } - } - return 1; -} - -/* Generated by genauthoritychartbl.py */ -static char VALID_AUTHORITY_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, - 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ -}; - -int nghttp2_check_authority(const uint8_t *value, size_t len) { - const uint8_t *last; - for (last = value + len; value != last; ++value) { - if (!VALID_AUTHORITY_CHARS[*value]) { - return 0; - } - } - return 1; -} - -uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) { - if (len == 0) { - return dest; - } - - memcpy(dest, src, len); - - return dest + len; -} - -const char *nghttp2_http2_strerror(uint32_t error_code) { - switch (error_code) { - case NGHTTP2_NO_ERROR: - return "NO_ERROR"; - case NGHTTP2_PROTOCOL_ERROR: - return "PROTOCOL_ERROR"; - case NGHTTP2_INTERNAL_ERROR: - return "INTERNAL_ERROR"; - case NGHTTP2_FLOW_CONTROL_ERROR: - return "FLOW_CONTROL_ERROR"; - case NGHTTP2_SETTINGS_TIMEOUT: - return "SETTINGS_TIMEOUT"; - case NGHTTP2_STREAM_CLOSED: - return "STREAM_CLOSED"; - case NGHTTP2_FRAME_SIZE_ERROR: - return "FRAME_SIZE_ERROR"; - case NGHTTP2_REFUSED_STREAM: - return "REFUSED_STREAM"; - case NGHTTP2_CANCEL: - return "CANCEL"; - case NGHTTP2_COMPRESSION_ERROR: - return "COMPRESSION_ERROR"; - case NGHTTP2_CONNECT_ERROR: - return "CONNECT_ERROR"; - case NGHTTP2_ENHANCE_YOUR_CALM: - return "ENHANCE_YOUR_CALM"; - case NGHTTP2_INADEQUATE_SECURITY: - return "INADEQUATE_SECURITY"; - case NGHTTP2_HTTP_1_1_REQUIRED: - return "HTTP_1_1_REQUIRED"; - default: - return "unknown"; - } -} diff --git a/vendor/nghttp2/lib/nghttp2_helper.h b/vendor/nghttp2/lib/nghttp2_helper.h deleted file mode 100644 index f5de6290d..000000000 --- a/vendor/nghttp2/lib/nghttp2_helper.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_HELPER_H -#define NGHTTP2_HELPER_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include - -#include -#include "nghttp2_mem.h" - -#define nghttp2_max_def(SUFFIX, T) \ - static inline T nghttp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; } - -nghttp2_max_def(int8, int8_t) -nghttp2_max_def(int16, int16_t) -nghttp2_max_def(int32, int32_t) -nghttp2_max_def(int64, int64_t) -nghttp2_max_def(uint8, uint8_t) -nghttp2_max_def(uint16, uint16_t) -nghttp2_max_def(uint32, uint32_t) -nghttp2_max_def(uint64, uint64_t) -nghttp2_max_def(size, size_t) - -#define nghttp2_min_def(SUFFIX, T) \ - static inline T nghttp2_min_##SUFFIX(T a, T b) { return a < b ? a : b; } - -nghttp2_min_def(int8, int8_t) -nghttp2_min_def(int16, int16_t) -nghttp2_min_def(int32, int32_t) -nghttp2_min_def(int64, int64_t) -nghttp2_min_def(uint8, uint8_t) -nghttp2_min_def(uint16, uint16_t) -nghttp2_min_def(uint32, uint32_t) -nghttp2_min_def(uint64, uint64_t) -nghttp2_min_def(size, size_t) - -#define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0) - -#define nghttp2_struct_of(ptr, type, member) \ - ((type *)(void *)((char *)(ptr) - offsetof(type, member))) - -/* - * Copies 2 byte unsigned integer |n| in host byte order to |buf| in - * network byte order. - */ -void nghttp2_put_uint16be(uint8_t *buf, uint16_t n); - -/* - * Copies 4 byte unsigned integer |n| in host byte order to |buf| in - * network byte order. - */ -void nghttp2_put_uint32be(uint8_t *buf, uint32_t n); - -/* - * Retrieves 2 byte unsigned integer stored in |data| in network byte - * order and returns it in host byte order. - */ -uint16_t nghttp2_get_uint16(const uint8_t *data); - -/* - * Retrieves 4 byte unsigned integer stored in |data| in network byte - * order and returns it in host byte order. - */ -uint32_t nghttp2_get_uint32(const uint8_t *data); - -void nghttp2_downcase(uint8_t *s, size_t len); - -/* - * Adjusts |*local_window_size_ptr|, |*recv_window_size_ptr|, - * |*recv_reduction_ptr| with |*delta_ptr| which is the - * WINDOW_UPDATE's window_size_increment sent from local side. If - * |delta| is strictly larger than |*recv_window_size_ptr|, - * |*local_window_size_ptr| is increased by delta - - * *recv_window_size_ptr. If |delta| is negative, - * |*local_window_size_ptr| is decreased by delta. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_FLOW_CONTROL - * local_window_size overflow or gets negative. - */ -int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr, - int32_t *recv_window_size_ptr, - int32_t *recv_reduction_ptr, - int32_t *delta_ptr); - -/* - * This function works like nghttp2_adjust_local_window_size(). The - * difference is that this function assumes *delta_ptr >= 0, and - * *recv_window_size_ptr is not decreased by *delta_ptr. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_FLOW_CONTROL - * local_window_size overflow or gets negative. - */ -int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr, - int32_t *recv_window_size_ptr, - int32_t *recv_reduction_ptr, - int32_t *delta_ptr); - -/* - * Returns non-zero if the function decided that WINDOW_UPDATE should - * be sent. - */ -int nghttp2_should_send_window_update(int32_t local_window_size, - int32_t recv_window_size); - -/* - * Copies the buffer |src| of length |len| to the destination pointed - * by the |dest|, assuming that the |dest| is at lest |len| bytes long - * . Returns dest + len. - */ -uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len); - -#endif /* NGHTTP2_HELPER_H */ diff --git a/vendor/nghttp2/lib/nghttp2_http.c b/vendor/nghttp2/lib/nghttp2_http.c deleted file mode 100644 index 60a0b01e6..000000000 --- a/vendor/nghttp2/lib/nghttp2_http.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2015 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_http.h" - -#include -#include -#include - -#include "nghttp2_hd.h" -#include "nghttp2_helper.h" -#include "nghttp2_extpri.h" -#include "sfparse.h" - -static uint8_t downcase(uint8_t c) { - return 'A' <= c && c <= 'Z' ? (uint8_t)(c - 'A' + 'a') : c; -} - -static int memieq(const void *a, const void *b, size_t n) { - size_t i; - const uint8_t *aa = a, *bb = b; - - for (i = 0; i < n; ++i) { - if (downcase(aa[i]) != downcase(bb[i])) { - return 0; - } - } - return 1; -} - -#define lstrieq(A, B, N) ((sizeof((A)) - 1) == (N) && memieq((A), (B), (N))) - -static int64_t parse_uint(const uint8_t *s, size_t len) { - int64_t n = 0; - size_t i; - if (len == 0) { - return -1; - } - for (i = 0; i < len; ++i) { - if ('0' <= s[i] && s[i] <= '9') { - if (n > INT64_MAX / 10) { - return -1; - } - n *= 10; - if (n > INT64_MAX - (s[i] - '0')) { - return -1; - } - n += s[i] - '0'; - continue; - } - return -1; - } - return n; -} - -static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv, - uint32_t flag) { - if ((stream->http_flags & flag) || nv->value->len == 0) { - return 0; - } - stream->http_flags = stream->http_flags | flag; - return 1; -} - -static int expect_response_body(nghttp2_stream *stream) { - return (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_HEAD) == 0 && - stream->status_code / 100 != 1 && stream->status_code != 304 && - stream->status_code != 204; -} - -/* For "http" or "https" URIs, OPTIONS request may have "*" in :path - header field to represent system-wide OPTIONS request. Otherwise, - :path header field value must start with "/". This function must - be called after ":method" header field was received. This function - returns nonzero if path is valid.*/ -static int check_path(nghttp2_stream *stream) { - return (stream->http_flags & NGHTTP2_HTTP_FLAG_SCHEME_HTTP) == 0 || - ((stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_REGULAR) || - ((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_OPTIONS) && - (stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK))); -} - -static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv, - int trailer, int connect_protocol) { - nghttp2_extpri extpri; - - if (nv->name->base[0] == ':') { - if (trailer || - (stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - } - - switch (nv->token) { - case NGHTTP2_TOKEN__AUTHORITY: - if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - case NGHTTP2_TOKEN__METHOD: - if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - switch (nv->value->len) { - case 4: - if (lstreq("HEAD", nv->value->base, nv->value->len)) { - stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD; - } - break; - case 7: - switch (nv->value->base[6]) { - case 'T': - if (lstreq("CONNECT", nv->value->base, nv->value->len)) { - if (stream->stream_id % 2 == 0) { - /* we won't allow CONNECT for push */ - return NGHTTP2_ERR_HTTP_HEADER; - } - stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_CONNECT; - } - break; - case 'S': - if (lstreq("OPTIONS", nv->value->base, nv->value->len)) { - stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS; - } - break; - } - break; - } - break; - case NGHTTP2_TOKEN__PATH: - if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - if (nv->value->base[0] == '/') { - stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR; - } else if (nv->value->len == 1 && nv->value->base[0] == '*') { - stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK; - } - break; - case NGHTTP2_TOKEN__SCHEME: - if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - if ((nv->value->len == 4 && memieq("http", nv->value->base, 4)) || - (nv->value->len == 5 && memieq("https", nv->value->base, 5))) { - stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP; - } - break; - case NGHTTP2_TOKEN__PROTOCOL: - if (!connect_protocol) { - return NGHTTP2_ERR_HTTP_HEADER; - } - - if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PROTOCOL)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - case NGHTTP2_TOKEN_HOST: - if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG_HOST)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - case NGHTTP2_TOKEN_CONTENT_LENGTH: { - if (stream->content_length != -1) { - return NGHTTP2_ERR_HTTP_HEADER; - } - stream->content_length = parse_uint(nv->value->base, nv->value->len); - if (stream->content_length == -1) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - } - /* disallowed header fields */ - case NGHTTP2_TOKEN_CONNECTION: - case NGHTTP2_TOKEN_KEEP_ALIVE: - case NGHTTP2_TOKEN_PROXY_CONNECTION: - case NGHTTP2_TOKEN_TRANSFER_ENCODING: - case NGHTTP2_TOKEN_UPGRADE: - return NGHTTP2_ERR_HTTP_HEADER; - case NGHTTP2_TOKEN_TE: - if (!lstrieq("trailers", nv->value->base, nv->value->len)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - case NGHTTP2_TOKEN_PRIORITY: - if (!trailer && - /* Do not parse the header field in PUSH_PROMISE. */ - (stream->stream_id & 1) && - !(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) { - nghttp2_extpri_from_uint8(&extpri, stream->http_extpri); - if (nghttp2_http_parse_priority(&extpri, nv->value->base, - nv->value->len) == 0) { - stream->http_extpri = nghttp2_extpri_to_uint8(&extpri); - stream->http_flags |= NGHTTP2_HTTP_FLAG_PRIORITY; - } else { - stream->http_flags &= (uint32_t)~NGHTTP2_HTTP_FLAG_PRIORITY; - stream->http_flags |= NGHTTP2_HTTP_FLAG_BAD_PRIORITY; - } - } - break; - default: - if (nv->name->base[0] == ':') { - return NGHTTP2_ERR_HTTP_HEADER; - } - } - - if (nv->name->base[0] != ':') { - stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED; - } - - return 0; -} - -static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv, - int trailer) { - if (nv->name->base[0] == ':') { - if (trailer || - (stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - } - - switch (nv->token) { - case NGHTTP2_TOKEN__STATUS: { - if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - if (nv->value->len != 3) { - return NGHTTP2_ERR_HTTP_HEADER; - } - stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len); - if (stream->status_code == -1 || stream->status_code == 101) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - } - case NGHTTP2_TOKEN_CONTENT_LENGTH: { - if (stream->status_code == 204) { - /* content-length header field in 204 response is prohibited by - RFC 7230. But some widely used servers send content-length: - 0. Until they get fixed, we ignore it. */ - if (stream->content_length != -1) { - /* Found multiple content-length field */ - return NGHTTP2_ERR_HTTP_HEADER; - } - if (!lstrieq("0", nv->value->base, nv->value->len)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - stream->content_length = 0; - return NGHTTP2_ERR_REMOVE_HTTP_HEADER; - } - if (stream->status_code / 100 == 1) { - return NGHTTP2_ERR_HTTP_HEADER; - } - /* https://tools.ietf.org/html/rfc7230#section-3.3.3 */ - if (stream->status_code / 100 == 2 && - (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT)) { - return NGHTTP2_ERR_REMOVE_HTTP_HEADER; - } - if (stream->content_length != -1) { - return NGHTTP2_ERR_HTTP_HEADER; - } - stream->content_length = parse_uint(nv->value->base, nv->value->len); - if (stream->content_length == -1) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - } - /* disallowed header fields */ - case NGHTTP2_TOKEN_CONNECTION: - case NGHTTP2_TOKEN_KEEP_ALIVE: - case NGHTTP2_TOKEN_PROXY_CONNECTION: - case NGHTTP2_TOKEN_TRANSFER_ENCODING: - case NGHTTP2_TOKEN_UPGRADE: - return NGHTTP2_ERR_HTTP_HEADER; - case NGHTTP2_TOKEN_TE: - if (!lstrieq("trailers", nv->value->base, nv->value->len)) { - return NGHTTP2_ERR_HTTP_HEADER; - } - break; - default: - if (nv->name->base[0] == ':') { - return NGHTTP2_ERR_HTTP_HEADER; - } - } - - if (nv->name->base[0] != ':') { - stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED; - } - - return 0; -} - -static int check_scheme(const uint8_t *value, size_t len) { - const uint8_t *last; - if (len == 0) { - return 0; - } - - if (!(('A' <= *value && *value <= 'Z') || ('a' <= *value && *value <= 'z'))) { - return 0; - } - - last = value + len; - ++value; - - for (; value != last; ++value) { - if (!(('A' <= *value && *value <= 'Z') || - ('a' <= *value && *value <= 'z') || - ('0' <= *value && *value <= '9') || *value == '+' || *value == '-' || - *value == '.')) { - return 0; - } - } - return 1; -} - -static int lws(const uint8_t *s, size_t n) { - size_t i; - for (i = 0; i < n; ++i) { - if (s[i] != ' ' && s[i] != '\t') { - return 0; - } - } - return 1; -} - -/* Generated by genauthoritychartbl.py, but '@' is not allowed */ -static char VALID_AUTHORITY_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, - 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, - 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ -}; - -static int check_authority(const uint8_t *value, size_t len) { - const uint8_t *last; - for (last = value + len; value != last; ++value) { - if (!VALID_AUTHORITY_CHARS[*value]) { - return 0; - } - } - return 1; -} - -int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, - nghttp2_frame *frame, nghttp2_hd_nv *nv, - int trailer) { - int rv; - - /* We are strict for pseudo header field. One bad character should - lead to fail. OTOH, we should be a bit forgiving for regular - headers, since existing public internet has so much illegal - headers floating around and if we kill the stream because of - this, we may disrupt many web sites and/or libraries. So we - become conservative here, and just ignore those illegal regular - headers. */ - if (!nghttp2_check_header_name(nv->name->base, nv->name->len)) { - size_t i; - if (nv->name->len > 0 && nv->name->base[0] == ':') { - return NGHTTP2_ERR_HTTP_HEADER; - } - /* header field name must be lower-cased without exception */ - for (i = 0; i < nv->name->len; ++i) { - uint8_t c = nv->name->base[i]; - if ('A' <= c && c <= 'Z') { - return NGHTTP2_ERR_HTTP_HEADER; - } - } - /* When ignoring regular headers, we set this flag so that we - still enforce header field ordering rule for pseudo header - fields. */ - stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED; - return NGHTTP2_ERR_IGN_HTTP_HEADER; - } - - switch (nv->token) { - case NGHTTP2_TOKEN__METHOD: - rv = nghttp2_check_method(nv->value->base, nv->value->len); - break; - case NGHTTP2_TOKEN__PATH: - rv = nghttp2_check_path(nv->value->base, nv->value->len); - break; - case NGHTTP2_TOKEN__AUTHORITY: - case NGHTTP2_TOKEN_HOST: - if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) { - rv = check_authority(nv->value->base, nv->value->len); - } else if ( - stream->flags & - NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) { - rv = nghttp2_check_header_value(nv->value->base, nv->value->len); - } else { - rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len); - } - break; - case NGHTTP2_TOKEN__SCHEME: - rv = check_scheme(nv->value->base, nv->value->len); - break; - case NGHTTP2_TOKEN__PROTOCOL: - /* Check the value consists of just white spaces, which was done - in check_pseudo_header before - nghttp2_check_header_value_rfc9113 has been introduced. */ - if ((stream->flags & - NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) && - lws(nv->value->base, nv->value->len)) { - rv = 0; - break; - } - /* fall through */ - default: - if (stream->flags & - NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) { - rv = nghttp2_check_header_value(nv->value->base, nv->value->len); - } else { - rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len); - } - } - - if (rv == 0) { - assert(nv->name->len > 0); - if (nv->name->base[0] == ':') { - return NGHTTP2_ERR_HTTP_HEADER; - } - /* When ignoring regular headers, we set this flag so that we - still enforce header field ordering rule for pseudo header - fields. */ - stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED; - return NGHTTP2_ERR_IGN_HTTP_HEADER; - } - - if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) { - return http_request_on_header(stream, nv, trailer, - session->server && - session->pending_enable_connect_protocol); - } - - return http_response_on_header(stream, nv, trailer); -} - -int nghttp2_http_on_request_headers(nghttp2_stream *stream, - nghttp2_frame *frame) { - if (!(stream->http_flags & NGHTTP2_HTTP_FLAG__PROTOCOL) && - (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT)) { - if ((stream->http_flags & - (NGHTTP2_HTTP_FLAG__SCHEME | NGHTTP2_HTTP_FLAG__PATH)) || - (stream->http_flags & NGHTTP2_HTTP_FLAG__AUTHORITY) == 0) { - return -1; - } - stream->content_length = -1; - } else { - if ((stream->http_flags & NGHTTP2_HTTP_FLAG_REQ_HEADERS) != - NGHTTP2_HTTP_FLAG_REQ_HEADERS || - (stream->http_flags & - (NGHTTP2_HTTP_FLAG__AUTHORITY | NGHTTP2_HTTP_FLAG_HOST)) == 0) { - return -1; - } - if ((stream->http_flags & NGHTTP2_HTTP_FLAG__PROTOCOL) && - ((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT) == 0 || - (stream->http_flags & NGHTTP2_HTTP_FLAG__AUTHORITY) == 0)) { - return -1; - } - if (!check_path(stream)) { - return -1; - } - } - - if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { - /* we are going to reuse data fields for upcoming response. Clear - them now, except for method flags. */ - stream->http_flags &= NGHTTP2_HTTP_FLAG_METH_ALL; - stream->content_length = -1; - } - - return 0; -} - -int nghttp2_http_on_response_headers(nghttp2_stream *stream) { - if ((stream->http_flags & NGHTTP2_HTTP_FLAG__STATUS) == 0) { - return -1; - } - - if (stream->status_code / 100 == 1) { - /* non-final response */ - stream->http_flags = (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_ALL) | - NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE; - stream->content_length = -1; - stream->status_code = -1; - return 0; - } - - stream->http_flags = - stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE; - - if (!expect_response_body(stream)) { - stream->content_length = 0; - } else if (stream->http_flags & (NGHTTP2_HTTP_FLAG_METH_CONNECT | - NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND)) { - stream->content_length = -1; - } - - return 0; -} - -int nghttp2_http_on_trailer_headers(nghttp2_stream *stream, - nghttp2_frame *frame) { - (void)stream; - - if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { - return -1; - } - - return 0; -} - -int nghttp2_http_on_remote_end_stream(nghttp2_stream *stream) { - if (stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) { - return -1; - } - - if (stream->content_length != -1 && - stream->content_length != stream->recv_content_length) { - return -1; - } - - return 0; -} - -int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n) { - stream->recv_content_length += (int64_t)n; - - if ((stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) || - (stream->content_length != -1 && - stream->recv_content_length > stream->content_length)) { - return -1; - } - - return 0; -} - -void nghttp2_http_record_request_method(nghttp2_stream *stream, - nghttp2_frame *frame) { - const nghttp2_nv *nva; - size_t nvlen; - size_t i; - - switch (frame->hd.type) { - case NGHTTP2_HEADERS: - nva = frame->headers.nva; - nvlen = frame->headers.nvlen; - break; - case NGHTTP2_PUSH_PROMISE: - nva = frame->push_promise.nva; - nvlen = frame->push_promise.nvlen; - break; - default: - return; - } - - /* TODO we should do this strictly. */ - for (i = 0; i < nvlen; ++i) { - const nghttp2_nv *nv = &nva[i]; - if (!(nv->namelen == 7 && nv->name[6] == 'd' && - memcmp(":metho", nv->name, nv->namelen - 1) == 0)) { - continue; - } - if (lstreq("CONNECT", nv->value, nv->valuelen)) { - stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_CONNECT; - return; - } - if (lstreq("HEAD", nv->value, nv->valuelen)) { - stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD; - return; - } - return; - } -} - -int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, - size_t valuelen) { - nghttp2_extpri pri = *dest; - sfparse_parser sfp; - sfparse_vec key; - sfparse_value val; - int rv; - - sfparse_parser_init(&sfp, value, valuelen); - - for (;;) { - rv = sfparse_parser_dict(&sfp, &key, &val); - if (rv != 0) { - if (rv == SFPARSE_ERR_EOF) { - break; - } - - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (key.len != 1) { - continue; - } - - switch (key.base[0]) { - case 'i': - if (val.type != SFPARSE_TYPE_BOOLEAN) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - pri.inc = val.boolean; - - break; - case 'u': - if (val.type != SFPARSE_TYPE_INTEGER || - val.integer < NGHTTP2_EXTPRI_URGENCY_HIGH || - NGHTTP2_EXTPRI_URGENCY_LOW < val.integer) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - pri.urgency = (uint32_t)val.integer; - - break; - } - } - - *dest = pri; - - return 0; -} diff --git a/vendor/nghttp2/lib/nghttp2_http.h b/vendor/nghttp2/lib/nghttp2_http.h deleted file mode 100644 index d9992fe69..000000000 --- a/vendor/nghttp2/lib/nghttp2_http.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2015 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_HTTP_H -#define NGHTTP2_HTTP_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include "nghttp2_session.h" -#include "nghttp2_stream.h" - -/* - * This function is called when HTTP header field |nv| in |frame| is - * received for |stream|. This function will validate |nv| against - * the current state of stream. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_HTTP_HEADER - * Invalid HTTP header field was received. - * NGHTTP2_ERR_IGN_HTTP_HEADER - * Invalid HTTP header field was received but it can be treated as - * if it was not received because of compatibility reasons. - */ -int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, - nghttp2_frame *frame, nghttp2_hd_nv *nv, - int trailer); - -/* - * This function is called when request header is received. This - * function performs validation and returns 0 if it succeeds, or -1. - */ -int nghttp2_http_on_request_headers(nghttp2_stream *stream, - nghttp2_frame *frame); - -/* - * This function is called when response header is received. This - * function performs validation and returns 0 if it succeeds, or -1. - */ -int nghttp2_http_on_response_headers(nghttp2_stream *stream); - -/* - * This function is called trailer header (for both request and - * response) is received. This function performs validation and - * returns 0 if it succeeds, or -1. - */ -int nghttp2_http_on_trailer_headers(nghttp2_stream *stream, - nghttp2_frame *frame); - -/* - * This function is called when END_STREAM flag is seen in incoming - * frame. This function performs validation and returns 0 if it - * succeeds, or -1. - */ -int nghttp2_http_on_remote_end_stream(nghttp2_stream *stream); - -/* - * This function is called when chunk of data is received. This - * function performs validation and returns 0 if it succeeds, or -1. - */ -int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n); - -/* - * This function inspects header field in |frame| and records its - * method in stream->http_flags. If frame->hd.type is neither - * NGHTTP2_HEADERS nor NGHTTP2_PUSH_PROMISE, this function does - * nothing. - */ -void nghttp2_http_record_request_method(nghttp2_stream *stream, - nghttp2_frame *frame); - -int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, - size_t valuelen); - -#endif /* NGHTTP2_HTTP_H */ diff --git a/vendor/nghttp2/lib/nghttp2_int.h b/vendor/nghttp2/lib/nghttp2_int.h deleted file mode 100644 index 5ee6b313a..000000000 --- a/vendor/nghttp2/lib/nghttp2_int.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_INT_H -#define NGHTTP2_INT_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -/* Macros, types and constants for internal use */ - -/* "less" function, return nonzero if |lhs| is less than |rhs|. */ -typedef int (*nghttp2_less)(const void *lhs, const void *rhs); - -/* Internal error code. They must be in the range [-499, -100], - inclusive. */ -typedef enum { - NGHTTP2_ERR_CREDENTIAL_PENDING = -101, - NGHTTP2_ERR_IGN_HEADER_BLOCK = -103, - NGHTTP2_ERR_IGN_PAYLOAD = -104, - /* - * Invalid HTTP header field was received but it can be treated as - * if it was not received because of compatibility reasons. - */ - NGHTTP2_ERR_IGN_HTTP_HEADER = -105, - /* - * Invalid HTTP header field was received, and it is ignored. - * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke - * nghttp2_on_invalid_header_callback. - */ - NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106, - /* - * Cancel pushed stream. - */ - NGHTTP2_ERR_PUSH_CANCEL = -107, -} nghttp2_internal_error; - -#endif /* NGHTTP2_INT_H */ diff --git a/vendor/nghttp2/lib/nghttp2_map.c b/vendor/nghttp2/lib/nghttp2_map.c deleted file mode 100644 index f89f31031..000000000 --- a/vendor/nghttp2/lib/nghttp2_map.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2017 ngtcp2 contributors - * Copyright (c) 2012 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_map.h" - -#include -#include -#include - -#include "nghttp2_helper.h" - -#define NGHTTP2_INITIAL_HASHBITS 4 - -void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem) { - map->mem = mem; - map->hashbits = 0; - map->table = NULL; - map->seed = seed; - map->size = 0; -} - -void nghttp2_map_free(nghttp2_map *map) { - if (!map) { - return; - } - - nghttp2_mem_free(map->mem, map->table); -} - -int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), - void *ptr) { - int rv; - size_t i; - nghttp2_map_bucket *bkt; - size_t tablelen; - - if (map->size == 0) { - return 0; - } - - tablelen = 1u << map->hashbits; - - for (i = 0; i < tablelen; ++i) { - bkt = &map->table[i]; - - if (bkt->data == NULL) { - continue; - } - - rv = func(bkt->data, ptr); - if (rv != 0) { - return rv; - } - } - - return 0; -} - -static size_t map_hash(const nghttp2_map *map, nghttp2_map_key_type key) { - /* hasher from - https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs - We do not perform finalization here because we use top bits - anyway. */ - uint32_t h = ((uint32_t)key + map->seed) * 0x93d765dd; - return (size_t)((h * 2654435769u) >> (32 - map->hashbits)); -} - -static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) { - nghttp2_map_bucket c = *a; - - *a = *b; - *b = c; -} - -#ifndef WIN32 -void nghttp2_map_print_distance(const nghttp2_map *map) { - size_t i; - size_t idx; - nghttp2_map_bucket *bkt; - size_t tablelen; - - if (map->size == 0) { - return; - } - - tablelen = 1u << map->hashbits; - - for (i = 0; i < tablelen; ++i) { - bkt = &map->table[i]; - - if (bkt->data == NULL) { - fprintf(stderr, "@%zu \n", i); - continue; - } - - idx = map_hash(map, bkt->key); - fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i, - map_hash(map, bkt->key), bkt->key, idx, bkt->psl); - } -} -#endif /* !defined(WIN32) */ - -static int map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) { - size_t idx = map_hash(map, key); - nghttp2_map_bucket b = { - .key = key, - .data = data, - }; - nghttp2_map_bucket *bkt; - size_t mask = (1u << map->hashbits) - 1; - - for (;;) { - bkt = &map->table[idx]; - - if (bkt->data == NULL) { - *bkt = b; - ++map->size; - return 0; - } - - if (b.psl > bkt->psl) { - map_bucket_swap(bkt, &b); - } else if (bkt->key == key) { - /* TODO This check is just a waste after first swap or if this - function is called from map_resize. That said, there is no - difference with or without this conditional in performance - wise. */ - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - ++b.psl; - idx = (idx + 1) & mask; - } -} - -static int map_resize(nghttp2_map *map, size_t new_hashbits) { - size_t i; - nghttp2_map_bucket *bkt; - size_t tablelen; - int rv; - nghttp2_map new_map = { - .table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits, - sizeof(nghttp2_map_bucket)), - .mem = map->mem, - .seed = map->seed, - .hashbits = new_hashbits, - }; - (void)rv; - - if (new_map.table == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - if (map->size) { - tablelen = 1u << map->hashbits; - - for (i = 0; i < tablelen; ++i) { - bkt = &map->table[i]; - if (bkt->data == NULL) { - continue; - } - - rv = map_insert(&new_map, bkt->key, bkt->data); - - assert(0 == rv); - } - } - - nghttp2_mem_free(map->mem, map->table); - map->table = new_map.table; - map->hashbits = new_hashbits; - - return 0; -} - -int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) { - int rv; - - assert(data); - - /* Load factor is 7/8 */ - /* Under the very initial condition, that is map->size == 0 and - map->hashbits == 0, 8 > 7 still holds nicely. */ - if ((map->size + 1) * 8 > (1u << map->hashbits) * 7) { - if (map->hashbits) { - rv = map_resize(map, map->hashbits + 1); - if (rv != 0) { - return rv; - } - } else { - rv = map_resize(map, NGHTTP2_INITIAL_HASHBITS); - if (rv != 0) { - return rv; - } - } - } - - rv = map_insert(map, key, data); - if (rv != 0) { - return rv; - } - - return 0; -} - -void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) { - size_t idx; - nghttp2_map_bucket *bkt; - size_t psl = 0; - size_t mask; - - if (map->size == 0) { - return NULL; - } - - idx = map_hash(map, key); - mask = (1u << map->hashbits) - 1; - - for (;;) { - bkt = &map->table[idx]; - - if (bkt->data == NULL || psl > bkt->psl) { - return NULL; - } - - if (bkt->key == key) { - return bkt->data; - } - - ++psl; - idx = (idx + 1) & mask; - } -} - -int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) { - size_t idx; - nghttp2_map_bucket *b, *bkt; - size_t psl = 0; - size_t mask; - - if (map->size == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - idx = map_hash(map, key); - mask = (1u << map->hashbits) - 1; - - for (;;) { - bkt = &map->table[idx]; - - if (bkt->data == NULL || psl > bkt->psl) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (bkt->key == key) { - b = bkt; - idx = (idx + 1) & mask; - - for (;;) { - bkt = &map->table[idx]; - if (bkt->data == NULL || bkt->psl == 0) { - b->data = NULL; - break; - } - - --bkt->psl; - *b = *bkt; - b = bkt; - - idx = (idx + 1) & mask; - } - - --map->size; - - return 0; - } - - ++psl; - idx = (idx + 1) & mask; - } -} - -void nghttp2_map_clear(nghttp2_map *map) { - if (map->size == 0) { - return; - } - - memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits)); - map->size = 0; -} - -size_t nghttp2_map_size(const nghttp2_map *map) { return map->size; } diff --git a/vendor/nghttp2/lib/nghttp2_map.h b/vendor/nghttp2/lib/nghttp2_map.h deleted file mode 100644 index e45685bce..000000000 --- a/vendor/nghttp2/lib/nghttp2_map.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2017 ngtcp2 contributors - * Copyright (c) 2012 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_MAP_H -#define NGHTTP2_MAP_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* defined(HAVE_CONFIG_H) */ - -#include - -#include "nghttp2_mem.h" - -/* Implementation of unordered map */ - -typedef int32_t nghttp2_map_key_type; - -typedef struct nghttp2_map_bucket { - uint32_t psl; - nghttp2_map_key_type key; - void *data; -} nghttp2_map_bucket; - -typedef struct nghttp2_map { - nghttp2_map_bucket *table; - nghttp2_mem *mem; - uint32_t seed; - size_t size; - size_t hashbits; -} nghttp2_map; - -/* - * nghttp2_map_init initializes the map |map|. - */ -void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem); - -/* - * nghttp2_map_free deallocates any resources allocated for |map|. - * The stored entries are not freed by this function. Use - * nghttp2_map_each() to free each entry. - */ -void nghttp2_map_free(nghttp2_map *map); - -/* - * nghttp2_map_insert inserts the new |data| with the |key| to the map - * |map|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_INVALID_ARGUMENT - * The item associated by |key| already exists. - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data); - -/* - * nghttp2_map_find returns the entry associated by the key |key|. If - * there is no such entry, this function returns NULL. - */ -void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key); - -/* - * nghttp2_map_remove removes the entry associated by the key |key| - * from the |map|. The removed entry is not freed by this function. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_INVALID_ARGUMENT - * The entry associated by |key| does not exist. - */ -int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key); - -/* - * nghttp2_map_clear removes all entries from |map|. The removed - * entry is not freed by this function. - */ -void nghttp2_map_clear(nghttp2_map *map); - -/* - * nghttp2_map_size returns the number of items stored in the map - * |map|. - */ -size_t nghttp2_map_size(const nghttp2_map *map); - -/* - * nghttp2_map_each applies the function |func| to each entry in the - * |map| with the optional user supplied pointer |ptr|. - * - * If the |func| returns 0, this function calls the |func| with the - * next entry. If the |func| returns nonzero, it will not call the - * |func| for further entries and return the return value of the - * |func| immediately. Thus, this function returns 0 if all the - * invocations of the |func| return 0, or nonzero value which the last - * invocation of |func| returns. - */ -int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), - void *ptr); - -#ifndef WIN32 -void nghttp2_map_print_distance(const nghttp2_map *map); -#endif /* !defined(WIN32) */ - -#endif /* !defined(NGHTTP2_MAP_H) */ diff --git a/vendor/nghttp2/lib/nghttp2_mem.c b/vendor/nghttp2/lib/nghttp2_mem.c deleted file mode 100644 index 6a449cffd..000000000 --- a/vendor/nghttp2/lib/nghttp2_mem.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_mem.h" - -static void *default_malloc(size_t size, void *mem_user_data) { - (void)mem_user_data; - - return malloc(size); -} - -static void default_free(void *ptr, void *mem_user_data) { - (void)mem_user_data; - - free(ptr); -} - -static void *default_calloc(size_t nmemb, size_t size, void *mem_user_data) { - (void)mem_user_data; - - return calloc(nmemb, size); -} - -static void *default_realloc(void *ptr, size_t size, void *mem_user_data) { - (void)mem_user_data; - - return realloc(ptr, size); -} - -static nghttp2_mem mem_default = {NULL, default_malloc, default_free, - default_calloc, default_realloc}; - -nghttp2_mem *nghttp2_mem_default(void) { return &mem_default; } - -void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size) { - return mem->malloc(size, mem->mem_user_data); -} - -void nghttp2_mem_free(nghttp2_mem *mem, void *ptr) { - mem->free(ptr, mem->mem_user_data); -} - -void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data) { - free_func(ptr, mem_user_data); -} - -void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size) { - return mem->calloc(nmemb, size, mem->mem_user_data); -} - -void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size) { - return mem->realloc(ptr, size, mem->mem_user_data); -} diff --git a/vendor/nghttp2/lib/nghttp2_mem.h b/vendor/nghttp2/lib/nghttp2_mem.h deleted file mode 100644 index f83dbcb8f..000000000 --- a/vendor/nghttp2/lib/nghttp2_mem.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_MEM_H -#define NGHTTP2_MEM_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -/* The default, system standard memory allocator */ -nghttp2_mem *nghttp2_mem_default(void); - -/* Convenient wrapper functions to call allocator function in - |mem|. */ -void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size); -void nghttp2_mem_free(nghttp2_mem *mem, void *ptr); -void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data); -void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size); -void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size); - -#endif /* NGHTTP2_MEM_H */ diff --git a/vendor/nghttp2/lib/nghttp2_net.h b/vendor/nghttp2/lib/nghttp2_net.h deleted file mode 100644 index 521f98143..000000000 --- a/vendor/nghttp2/lib/nghttp2_net.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_NET_H -#define NGHTTP2_NET_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#ifdef HAVE_ARPA_INET_H -# include -#endif /* HAVE_ARPA_INET_H */ - -#ifdef HAVE_NETINET_IN_H -# include -#endif /* HAVE_NETINET_IN_H */ - -#include - -#if defined(WIN32) -/* Windows requires ws2_32 library for ntonl family functions. We - define inline functions for those function so that we don't have - dependency on that lib. */ - -# ifdef _MSC_VER -# define STIN static __inline -# else -# define STIN static inline -# endif - -STIN uint32_t htonl(uint32_t hostlong) { - uint32_t res; - unsigned char *p = (unsigned char *)&res; - *p++ = (unsigned char)(hostlong >> 24); - *p++ = (hostlong >> 16) & 0xffu; - *p++ = (hostlong >> 8) & 0xffu; - *p = hostlong & 0xffu; - return res; -} - -STIN uint16_t htons(uint16_t hostshort) { - uint16_t res; - unsigned char *p = (unsigned char *)&res; - *p++ = (unsigned char)(hostshort >> 8); - *p = hostshort & 0xffu; - return res; -} - -STIN uint32_t ntohl(uint32_t netlong) { - uint32_t res; - unsigned char *p = (unsigned char *)&netlong; - res = (uint32_t)(*p++ << 24); - res += (uint32_t)(*p++ << 16); - res += (uint32_t)(*p++ << 8); - res += *p; - return res; -} - -STIN uint16_t ntohs(uint16_t netshort) { - uint16_t res; - unsigned char *p = (unsigned char *)&netshort; - res = (uint16_t)(*p++ << 8); - res += *p; - return res; -} - -#endif /* WIN32 */ - -#endif /* NGHTTP2_NET_H */ diff --git a/vendor/nghttp2/lib/nghttp2_option.c b/vendor/nghttp2/lib/nghttp2_option.c deleted file mode 100644 index 7e44a241b..000000000 --- a/vendor/nghttp2/lib/nghttp2_option.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_option.h" - -#include "nghttp2_session.h" - -int nghttp2_option_new(nghttp2_option **option_ptr) { - *option_ptr = calloc(1, sizeof(nghttp2_option)); - - if (*option_ptr == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - return 0; -} - -void nghttp2_option_del(nghttp2_option *option) { free(option); } - -void nghttp2_option_set_no_auto_window_update(nghttp2_option *option, int val) { - option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE; - option->no_auto_window_update = val; -} - -void nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option, - uint32_t val) { - option->opt_set_mask |= NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS; - option->peer_max_concurrent_streams = val; -} - -void nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val) { - option->opt_set_mask |= NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC; - option->no_recv_client_magic = val; -} - -void nghttp2_option_set_no_http_messaging(nghttp2_option *option, int val) { - option->opt_set_mask |= NGHTTP2_OPT_NO_HTTP_MESSAGING; - option->no_http_messaging = val; -} - -void nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option, - uint32_t val) { - option->opt_set_mask |= NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS; - option->max_reserved_remote_streams = val; -} - -static void set_ext_type(uint8_t *ext_types, uint8_t type) { - ext_types[type / 8] = (uint8_t)(ext_types[type / 8] | (1 << (type & 0x7))); -} - -void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option, - uint8_t type) { - if (type < 10) { - return; - } - - option->opt_set_mask |= NGHTTP2_OPT_USER_RECV_EXT_TYPES; - set_ext_type(option->user_recv_ext_types, type); -} - -void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option, - uint8_t type) { - switch (type) { - case NGHTTP2_ALTSVC: - option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; - option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ALTSVC; - return; - case NGHTTP2_ORIGIN: - option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; - option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ORIGIN; - return; - case NGHTTP2_PRIORITY_UPDATE: - option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; - option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_PRIORITY_UPDATE; - return; - default: - return; - } -} - -void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val) { - option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_PING_ACK; - option->no_auto_ping_ack = val; -} - -void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option, - size_t val) { - option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH; - option->max_send_header_block_length = val; -} - -void nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option, - size_t val) { - option->opt_set_mask |= NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE; - option->max_deflate_dynamic_table_size = val; -} - -void nghttp2_option_set_no_closed_streams(nghttp2_option *option, int val) { - option->opt_set_mask |= NGHTTP2_OPT_NO_CLOSED_STREAMS; - option->no_closed_streams = val; -} - -void nghttp2_option_set_max_outbound_ack(nghttp2_option *option, size_t val) { - option->opt_set_mask |= NGHTTP2_OPT_MAX_OUTBOUND_ACK; - option->max_outbound_ack = val; -} - -void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) { - option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS; - option->max_settings = val; -} - -void nghttp2_option_set_server_fallback_rfc7540_priorities( - nghttp2_option *option, int val) { - option->opt_set_mask |= NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES; - option->server_fallback_rfc7540_priorities = val; -} - -void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - nghttp2_option *option, int val) { - option->opt_set_mask |= - NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; - option->no_rfc9113_leading_and_trailing_ws_validation = val; -} - -void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, - uint64_t burst, uint64_t rate) { - option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT; - option->stream_reset_burst = burst; - option->stream_reset_rate = rate; -} - -void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) { - option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS; - option->max_continuations = val; -} - -void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option, - uint64_t burst, uint64_t rate) { - option->opt_set_mask |= NGHTTP2_OPT_GLITCH_RATE_LIMIT; - option->glitch_burst = burst; - option->glitch_rate = rate; -} diff --git a/vendor/nghttp2/lib/nghttp2_option.h b/vendor/nghttp2/lib/nghttp2_option.h deleted file mode 100644 index 78fa21e4a..000000000 --- a/vendor/nghttp2/lib/nghttp2_option.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_OPTION_H -#define NGHTTP2_OPTION_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -/** - * Configuration options - */ -typedef enum { - /** - * This option prevents the library from sending WINDOW_UPDATE for a - * connection automatically. If this option is set to nonzero, the - * library won't send WINDOW_UPDATE for DATA until application calls - * nghttp2_session_consume() to indicate the amount of consumed - * DATA. By default, this option is set to zero. - */ - NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE = 1, - /** - * This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of - * remote endpoint as if it is received in SETTINGS frame. Without - * specifying this option, before the local endpoint receives - * SETTINGS_MAX_CONCURRENT_STREAMS in SETTINGS frame from remote - * endpoint, SETTINGS_MAX_CONCURRENT_STREAMS is unlimited. This may - * cause problem if local endpoint submits lots of requests - * initially and sending them at once to the remote peer may lead to - * the rejection of some requests. Specifying this option to the - * sensible value, say 100, may avoid this kind of issue. This value - * will be overwritten if the local endpoint receives - * SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint. - */ - NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1, - NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2, - NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3, - NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4, - NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5, - NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6, - NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7, - NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8, - NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9, - NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10, - NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11, - NGHTTP2_OPT_MAX_SETTINGS = 1 << 12, - NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 13, - NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14, - NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15, - NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16, - NGHTTP2_OPT_GLITCH_RATE_LIMIT = 1 << 17, -} nghttp2_option_flag; - -/** - * Struct to store option values for nghttp2_session. - */ -struct nghttp2_option { - /** - * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT - */ - uint64_t stream_reset_burst; - uint64_t stream_reset_rate; - /** - * NGHTTP2_OPT_GLITCH_RATE_LIMIT - */ - uint64_t glitch_burst; - uint64_t glitch_rate; - /** - * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH - */ - size_t max_send_header_block_length; - /** - * NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE - */ - size_t max_deflate_dynamic_table_size; - /** - * NGHTTP2_OPT_MAX_OUTBOUND_ACK - */ - size_t max_outbound_ack; - /** - * NGHTTP2_OPT_MAX_SETTINGS - */ - size_t max_settings; - /** - * NGHTTP2_OPT_MAX_CONTINUATIONS - */ - size_t max_continuations; - /** - * Bitwise OR of nghttp2_option_flag to determine that which fields - * are specified. - */ - uint32_t opt_set_mask; - /** - * NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS - */ - uint32_t peer_max_concurrent_streams; - /** - * NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS - */ - uint32_t max_reserved_remote_streams; - /** - * NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES - */ - uint32_t builtin_recv_ext_types; - /** - * NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE - */ - int no_auto_window_update; - /** - * NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC - */ - int no_recv_client_magic; - /** - * NGHTTP2_OPT_NO_HTTP_MESSAGING - */ - int no_http_messaging; - /** - * NGHTTP2_OPT_NO_AUTO_PING_ACK - */ - int no_auto_ping_ack; - /** - * NGHTTP2_OPT_NO_CLOSED_STREAMS - */ - int no_closed_streams; - /** - * NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES - */ - int server_fallback_rfc7540_priorities; - /** - * NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION - */ - int no_rfc9113_leading_and_trailing_ws_validation; - /** - * NGHTTP2_OPT_USER_RECV_EXT_TYPES - */ - uint8_t user_recv_ext_types[32]; -}; - -#endif /* NGHTTP2_OPTION_H */ diff --git a/vendor/nghttp2/lib/nghttp2_outbound_item.c b/vendor/nghttp2/lib/nghttp2_outbound_item.c deleted file mode 100644 index a9e9f7693..000000000 --- a/vendor/nghttp2/lib/nghttp2_outbound_item.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_outbound_item.h" - -#include -#include - -nghttp2_data_provider_wrap * -nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw, - const nghttp2_data_provider *data_prd) { - if (!data_prd) { - return NULL; - } - - dpw->version = NGHTTP2_DATA_PROVIDER_V1; - dpw->data_prd.v1 = *data_prd; - - return dpw; -} - -nghttp2_data_provider_wrap * -nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw, - const nghttp2_data_provider2 *data_prd) { - if (!data_prd) { - return NULL; - } - - dpw->version = NGHTTP2_DATA_PROVIDER_V2; - dpw->data_prd.v2 = *data_prd; - - return dpw; -} - -void nghttp2_outbound_item_init(nghttp2_outbound_item *item) { - item->cycle = 0; - item->qnext = NULL; - item->queued = 0; - - memset(&item->aux_data, 0, sizeof(nghttp2_aux_data)); -} - -void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) { - nghttp2_frame *frame; - - if (item == NULL) { - return; - } - - frame = &item->frame; - - switch (frame->hd.type) { - case NGHTTP2_DATA: - nghttp2_frame_data_free(&frame->data); - break; - case NGHTTP2_HEADERS: - nghttp2_frame_headers_free(&frame->headers, mem); - break; - case NGHTTP2_PRIORITY: - nghttp2_frame_priority_free(&frame->priority); - break; - case NGHTTP2_RST_STREAM: - nghttp2_frame_rst_stream_free(&frame->rst_stream); - break; - case NGHTTP2_SETTINGS: - nghttp2_frame_settings_free(&frame->settings, mem); - break; - case NGHTTP2_PUSH_PROMISE: - nghttp2_frame_push_promise_free(&frame->push_promise, mem); - break; - case NGHTTP2_PING: - nghttp2_frame_ping_free(&frame->ping); - break; - case NGHTTP2_GOAWAY: - nghttp2_frame_goaway_free(&frame->goaway, mem); - break; - case NGHTTP2_WINDOW_UPDATE: - nghttp2_frame_window_update_free(&frame->window_update); - break; - default: { - nghttp2_ext_aux_data *aux_data; - - aux_data = &item->aux_data.ext; - - if (aux_data->builtin == 0) { - nghttp2_frame_extension_free(&frame->ext); - break; - } - - switch (frame->hd.type) { - case NGHTTP2_ALTSVC: - nghttp2_frame_altsvc_free(&frame->ext, mem); - break; - case NGHTTP2_ORIGIN: - nghttp2_frame_origin_free(&frame->ext, mem); - break; - case NGHTTP2_PRIORITY_UPDATE: - nghttp2_frame_priority_update_free(&frame->ext, mem); - break; - default: - assert(0); - break; - } - } - } -} - -void nghttp2_outbound_queue_init(nghttp2_outbound_queue *q) { - q->head = q->tail = NULL; - q->n = 0; -} - -void nghttp2_outbound_queue_push(nghttp2_outbound_queue *q, - nghttp2_outbound_item *item) { - if (q->tail) { - q->tail = q->tail->qnext = item; - } else { - q->head = q->tail = item; - } - ++q->n; -} - -void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q) { - nghttp2_outbound_item *item; - if (!q->head) { - return; - } - item = q->head; - q->head = q->head->qnext; - item->qnext = NULL; - if (!q->head) { - q->tail = NULL; - } - --q->n; -} diff --git a/vendor/nghttp2/lib/nghttp2_outbound_item.h b/vendor/nghttp2/lib/nghttp2_outbound_item.h deleted file mode 100644 index 4e9175008..000000000 --- a/vendor/nghttp2/lib/nghttp2_outbound_item.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_OUTBOUND_ITEM_H -#define NGHTTP2_OUTBOUND_ITEM_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include "nghttp2_frame.h" -#include "nghttp2_mem.h" - -#define NGHTTP2_DATA_PROVIDER_V1 1 -#define NGHTTP2_DATA_PROVIDER_V2 2 - -typedef struct nghttp2_data_provider_wrap { - int version; - union { - struct { - nghttp2_data_source source; - void *read_callback; - }; - nghttp2_data_provider v1; - nghttp2_data_provider2 v2; - } data_prd; -} nghttp2_data_provider_wrap; - -nghttp2_data_provider_wrap * -nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw, - const nghttp2_data_provider *data_prd); - -nghttp2_data_provider_wrap * -nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw, - const nghttp2_data_provider2 *data_prd); - -/* struct used for HEADERS and PUSH_PROMISE frame */ -typedef struct { - nghttp2_data_provider_wrap dpw; - void *stream_user_data; - /* error code when request HEADERS is canceled by RST_STREAM while - it is in queue. */ - uint32_t error_code; - /* nonzero if request HEADERS is canceled. The error code is stored - in |error_code|. */ - uint8_t canceled; -} nghttp2_headers_aux_data; - -/* struct used for DATA frame */ -typedef struct { - /** - * The data to be sent for this DATA frame. - */ - nghttp2_data_provider_wrap dpw; - /** - * The flags of DATA frame. We use separate flags here and - * nghttp2_data frame. The latter contains flags actually sent to - * peer. This |flags| may contain NGHTTP2_FLAG_END_STREAM and only - * when |eof| becomes nonzero, flags in nghttp2_data has - * NGHTTP2_FLAG_END_STREAM set. - */ - uint8_t flags; - /** - * The flag to indicate whether EOF was reached or not. Initially - * |eof| is 0. It becomes 1 after all data were read. - */ - uint8_t eof; - /** - * The flag to indicate that NGHTTP2_DATA_FLAG_NO_COPY is used. - */ - uint8_t no_copy; -} nghttp2_data_aux_data; - -typedef enum { - NGHTTP2_GOAWAY_AUX_NONE = 0x0, - /* indicates that session should be terminated after the - transmission of this frame. */ - NGHTTP2_GOAWAY_AUX_TERM_ON_SEND = 0x1, - /* indicates that this GOAWAY is just a notification for graceful - shutdown. No nghttp2_session.goaway_flags should be updated on - the reaction to this frame. */ - NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE = 0x2 -} nghttp2_goaway_aux_flag; - -/* struct used for GOAWAY frame */ -typedef struct { - /* bitwise-OR of one or more of nghttp2_goaway_aux_flag. */ - uint8_t flags; -} nghttp2_goaway_aux_data; - -/* struct used for extension frame */ -typedef struct { - /* nonzero if this extension frame is serialized by library - function, instead of user-defined callbacks. */ - uint8_t builtin; -} nghttp2_ext_aux_data; - -/* Additional data which cannot be stored in nghttp2_frame struct */ -typedef union { - nghttp2_data_aux_data data; - nghttp2_headers_aux_data headers; - nghttp2_goaway_aux_data goaway; - nghttp2_ext_aux_data ext; -} nghttp2_aux_data; - -struct nghttp2_outbound_item; -typedef struct nghttp2_outbound_item nghttp2_outbound_item; - -struct nghttp2_outbound_item { - nghttp2_frame frame; - /* Storage for extension frame payload. frame->ext.payload points - to this structure to avoid frequent memory allocation. */ - nghttp2_ext_frame_payload ext_frame_payload; - nghttp2_aux_data aux_data; - /* The priority used in priority comparison. Smaller is served - earlier. For PING, SETTINGS and non-DATA frames (excluding - response HEADERS frame) have dedicated cycle value defined above. - For DATA frame, cycle is computed by taking into account of - effective weight and frame payload length previously sent, so - that the amount of transmission is distributed across streams - proportional to effective weight (inside a tree). */ - uint64_t cycle; - nghttp2_outbound_item *qnext; - /* nonzero if this object is queued, except for DATA or HEADERS - which are attached to stream as item. */ - uint8_t queued; -}; - -/* - * Initializes |item|. No memory allocation is done in this function. - * Don't call nghttp2_outbound_item_free() until frame member is - * initialized. - */ -void nghttp2_outbound_item_init(nghttp2_outbound_item *item); - -/* - * Deallocates resource for |item|. If |item| is NULL, this function - * does nothing. - */ -void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem); - -/* - * queue for nghttp2_outbound_item. - */ -typedef struct { - nghttp2_outbound_item *head, *tail; - /* number of items in this queue. */ - size_t n; -} nghttp2_outbound_queue; - -void nghttp2_outbound_queue_init(nghttp2_outbound_queue *q); - -/* Pushes |item| into |q| */ -void nghttp2_outbound_queue_push(nghttp2_outbound_queue *q, - nghttp2_outbound_item *item); - -/* Pops |item| at the top from |q|. If |q| is empty, nothing - happens. */ -void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q); - -/* Returns the top item. */ -#define nghttp2_outbound_queue_top(Q) ((Q)->head) - -/* Returns the size of the queue */ -#define nghttp2_outbound_queue_size(Q) ((Q)->n) - -#endif /* NGHTTP2_OUTBOUND_ITEM_H */ diff --git a/vendor/nghttp2/lib/nghttp2_pq.c b/vendor/nghttp2/lib/nghttp2_pq.c deleted file mode 100644 index e79ba8365..000000000 --- a/vendor/nghttp2/lib/nghttp2_pq.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_pq.h" - -#include -#include - -#include "nghttp2_helper.h" - -void nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem) { - pq->mem = mem; - pq->capacity = 0; - pq->q = NULL; - pq->length = 0; - pq->less = less; -} - -void nghttp2_pq_free(nghttp2_pq *pq) { - nghttp2_mem_free(pq->mem, pq->q); - pq->q = NULL; -} - -static void swap(nghttp2_pq *pq, size_t i, size_t j) { - nghttp2_pq_entry *a = pq->q[i]; - nghttp2_pq_entry *b = pq->q[j]; - - pq->q[i] = b; - b->index = i; - pq->q[j] = a; - a->index = j; -} - -static void bubble_up(nghttp2_pq *pq, size_t index) { - size_t parent; - while (index != 0) { - parent = (index - 1) / 2; - if (!pq->less(pq->q[index], pq->q[parent])) { - return; - } - swap(pq, parent, index); - index = parent; - } -} - -int nghttp2_pq_push(nghttp2_pq *pq, nghttp2_pq_entry *item) { - if (pq->capacity <= pq->length) { - void *nq; - size_t ncapacity; - - ncapacity = nghttp2_max_size(4, (pq->capacity * 2)); - - nq = nghttp2_mem_realloc(pq->mem, pq->q, - ncapacity * sizeof(nghttp2_pq_entry *)); - if (nq == NULL) { - return NGHTTP2_ERR_NOMEM; - } - pq->capacity = ncapacity; - pq->q = nq; - } - pq->q[pq->length] = item; - item->index = pq->length; - ++pq->length; - bubble_up(pq, pq->length - 1); - return 0; -} - -nghttp2_pq_entry *nghttp2_pq_top(nghttp2_pq *pq) { - if (pq->length == 0) { - return NULL; - } else { - return pq->q[0]; - } -} - -static void bubble_down(nghttp2_pq *pq, size_t index) { - size_t i, j, minindex; - for (;;) { - j = index * 2 + 1; - minindex = index; - for (i = 0; i < 2; ++i, ++j) { - if (j >= pq->length) { - break; - } - if (pq->less(pq->q[j], pq->q[minindex])) { - minindex = j; - } - } - if (minindex == index) { - return; - } - swap(pq, index, minindex); - index = minindex; - } -} - -void nghttp2_pq_pop(nghttp2_pq *pq) { - if (pq->length > 0) { - pq->q[0] = pq->q[pq->length - 1]; - pq->q[0]->index = 0; - --pq->length; - bubble_down(pq, 0); - } -} - -void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item) { - assert(pq->q[item->index] == item); - - if (item->index == 0) { - nghttp2_pq_pop(pq); - return; - } - - if (item->index == pq->length - 1) { - --pq->length; - return; - } - - pq->q[item->index] = pq->q[pq->length - 1]; - pq->q[item->index]->index = item->index; - --pq->length; - - if (pq->less(item, pq->q[item->index])) { - bubble_down(pq, item->index); - } else { - bubble_up(pq, item->index); - } -} - -int nghttp2_pq_empty(nghttp2_pq *pq) { return pq->length == 0; } - -size_t nghttp2_pq_size(nghttp2_pq *pq) { return pq->length; } - -void nghttp2_pq_update(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg) { - size_t i; - int rv = 0; - if (pq->length == 0) { - return; - } - for (i = 0; i < pq->length; ++i) { - rv |= (*fun)(pq->q[i], arg); - } - if (rv) { - for (i = pq->length; i > 0; --i) { - bubble_down(pq, i - 1); - } - } -} - -int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg) { - size_t i; - - if (pq->length == 0) { - return 0; - } - for (i = 0; i < pq->length; ++i) { - if ((*fun)(pq->q[i], arg)) { - return 1; - } - } - return 0; -} diff --git a/vendor/nghttp2/lib/nghttp2_pq.h b/vendor/nghttp2/lib/nghttp2_pq.h deleted file mode 100644 index c8d90ef2c..000000000 --- a/vendor/nghttp2/lib/nghttp2_pq.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_PQ_H -#define NGHTTP2_PQ_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include "nghttp2_int.h" -#include "nghttp2_mem.h" - -/* Implementation of priority queue */ - -typedef struct { - size_t index; -} nghttp2_pq_entry; - -typedef struct { - /* The pointer to the pointer to the item stored */ - nghttp2_pq_entry **q; - /* Memory allocator */ - nghttp2_mem *mem; - /* The number of items stored */ - size_t length; - /* The maximum number of items this pq can store. This is - automatically extended when length is reached to this value. */ - size_t capacity; - /* The less function between items */ - nghttp2_less less; -} nghttp2_pq; - -/* - * Initializes priority queue |pq| with compare function |cmp|. - */ -void nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem); - -/* - * Deallocates any resources allocated for |pq|. The stored items are - * not freed by this function. - */ -void nghttp2_pq_free(nghttp2_pq *pq); - -/* - * Adds |item| to the priority queue |pq|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_pq_push(nghttp2_pq *pq, nghttp2_pq_entry *item); - -/* - * Returns item at the top of the queue |pq|. If the queue is empty, - * this function returns NULL. - */ -nghttp2_pq_entry *nghttp2_pq_top(nghttp2_pq *pq); - -/* - * Pops item at the top of the queue |pq|. The popped item is not - * freed by this function. - */ -void nghttp2_pq_pop(nghttp2_pq *pq); - -/* - * Returns nonzero if the queue |pq| is empty. - */ -int nghttp2_pq_empty(nghttp2_pq *pq); - -/* - * Returns the number of items in the queue |pq|. - */ -size_t nghttp2_pq_size(nghttp2_pq *pq); - -typedef int (*nghttp2_pq_item_cb)(nghttp2_pq_entry *item, void *arg); - -/* - * Updates each item in |pq| using function |fun| and re-construct - * priority queue. The |fun| must return non-zero if it modifies the - * item in a way that it affects ordering in the priority queue. The - * |arg| is passed to the 2nd parameter of |fun|. - */ -void nghttp2_pq_update(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg); - -/* - * Applies |fun| to each item in |pq|. The |arg| is passed as arg - * parameter to callback function. This function must not change the - * ordering key. If the return value from callback is nonzero, this - * function returns 1 immediately without iterating remaining items. - * Otherwise this function returns 0. - */ -int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg); - -/* - * Removes |item| from priority queue. - */ -void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item); - -#endif /* NGHTTP2_PQ_H */ diff --git a/vendor/nghttp2/lib/nghttp2_priority_spec.c b/vendor/nghttp2/lib/nghttp2_priority_spec.c deleted file mode 100644 index c2196e306..000000000 --- a/vendor/nghttp2/lib/nghttp2_priority_spec.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_priority_spec.h" - -void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec, - int32_t stream_id, int32_t weight, - int exclusive) { - pri_spec->stream_id = stream_id; - pri_spec->weight = weight; - pri_spec->exclusive = exclusive != 0; -} - -void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec) { - pri_spec->stream_id = 0; - pri_spec->weight = NGHTTP2_DEFAULT_WEIGHT; - pri_spec->exclusive = 0; -} - -int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec) { - return pri_spec->stream_id == 0 && - pri_spec->weight == NGHTTP2_DEFAULT_WEIGHT && pri_spec->exclusive == 0; -} - -void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec) { - if (pri_spec->weight < NGHTTP2_MIN_WEIGHT) { - pri_spec->weight = NGHTTP2_MIN_WEIGHT; - } else if (pri_spec->weight > NGHTTP2_MAX_WEIGHT) { - pri_spec->weight = NGHTTP2_MAX_WEIGHT; - } -} diff --git a/vendor/nghttp2/lib/nghttp2_priority_spec.h b/vendor/nghttp2/lib/nghttp2_priority_spec.h deleted file mode 100644 index 92ece822a..000000000 --- a/vendor/nghttp2/lib/nghttp2_priority_spec.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_PRIORITY_SPEC_H -#define NGHTTP2_PRIORITY_SPEC_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -/* - * This function normalizes pri_spec->weight if it is out of range. - * If pri_spec->weight is less than NGHTTP2_MIN_WEIGHT, it is set to - * NGHTTP2_MIN_WEIGHT. If pri_spec->weight is larger than - * NGHTTP2_MAX_WEIGHT, it is set to NGHTTP2_MAX_WEIGHT. - */ -void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec); - -#endif /* NGHTTP2_PRIORITY_SPEC_H */ diff --git a/vendor/nghttp2/lib/nghttp2_queue.c b/vendor/nghttp2/lib/nghttp2_queue.c deleted file mode 100644 index 3b6315852..000000000 --- a/vendor/nghttp2/lib/nghttp2_queue.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_queue.h" - -#include -#include - -void nghttp2_queue_init(nghttp2_queue *queue) { - queue->front = queue->back = NULL; -} - -void nghttp2_queue_free(nghttp2_queue *queue) { - if (!queue) { - return; - } else { - nghttp2_queue_cell *p = queue->front; - while (p) { - nghttp2_queue_cell *next = p->next; - free(p); - p = next; - } - } -} - -int nghttp2_queue_push(nghttp2_queue *queue, void *data) { - nghttp2_queue_cell *new_cell = - (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell)); - if (!new_cell) { - return NGHTTP2_ERR_NOMEM; - } - new_cell->data = data; - new_cell->next = NULL; - if (queue->back) { - queue->back->next = new_cell; - queue->back = new_cell; - - } else { - queue->front = queue->back = new_cell; - } - return 0; -} - -void nghttp2_queue_pop(nghttp2_queue *queue) { - nghttp2_queue_cell *front = queue->front; - assert(front); - queue->front = front->next; - if (front == queue->back) { - queue->back = NULL; - } - free(front); -} - -void *nghttp2_queue_front(nghttp2_queue *queue) { - assert(queue->front); - return queue->front->data; -} - -void *nghttp2_queue_back(nghttp2_queue *queue) { - assert(queue->back); - return queue->back->data; -} - -int nghttp2_queue_empty(nghttp2_queue *queue) { return queue->front == NULL; } diff --git a/vendor/nghttp2/lib/nghttp2_queue.h b/vendor/nghttp2/lib/nghttp2_queue.h deleted file mode 100644 index a06fa6c7a..000000000 --- a/vendor/nghttp2/lib/nghttp2_queue.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_QUEUE_H -#define NGHTTP2_QUEUE_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include - -typedef struct nghttp2_queue_cell { - void *data; - struct nghttp2_queue_cell *next; -} nghttp2_queue_cell; - -typedef struct { - nghttp2_queue_cell *front, *back; -} nghttp2_queue; - -void nghttp2_queue_init(nghttp2_queue *queue); -void nghttp2_queue_free(nghttp2_queue *queue); -int nghttp2_queue_push(nghttp2_queue *queue, void *data); -void nghttp2_queue_pop(nghttp2_queue *queue); -void *nghttp2_queue_front(nghttp2_queue *queue); -void *nghttp2_queue_back(nghttp2_queue *queue); -int nghttp2_queue_empty(nghttp2_queue *queue); - -#endif /* NGHTTP2_QUEUE_H */ diff --git a/vendor/nghttp2/lib/nghttp2_ratelim.c b/vendor/nghttp2/lib/nghttp2_ratelim.c deleted file mode 100644 index 604ac0801..000000000 --- a/vendor/nghttp2/lib/nghttp2_ratelim.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2023 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_ratelim.h" -#include "nghttp2_helper.h" - -void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) { - rl->val = rl->burst = burst; - rl->rate = rate; - rl->tstamp = 0; -} - -void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) { - uint64_t d, gain; - - if (tstamp == rl->tstamp) { - return; - } - - if (tstamp > rl->tstamp) { - d = tstamp - rl->tstamp; - } else { - d = 1; - } - - rl->tstamp = tstamp; - - if (UINT64_MAX / d < rl->rate) { - rl->val = rl->burst; - - return; - } - - gain = rl->rate * d; - - if (UINT64_MAX - gain < rl->val) { - rl->val = rl->burst; - - return; - } - - rl->val += gain; - rl->val = nghttp2_min_uint64(rl->val, rl->burst); -} - -int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) { - if (rl->val < n) { - return -1; - } - - rl->val -= n; - - return 0; -} diff --git a/vendor/nghttp2/lib/nghttp2_ratelim.h b/vendor/nghttp2/lib/nghttp2_ratelim.h deleted file mode 100644 index 866ed3f00..000000000 --- a/vendor/nghttp2/lib/nghttp2_ratelim.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2023 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_RATELIM_H -#define NGHTTP2_RATELIM_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -typedef struct nghttp2_ratelim { - /* burst is the maximum value of val. */ - uint64_t burst; - /* rate is the amount of value that is regenerated per 1 tstamp. */ - uint64_t rate; - /* val is the amount of value available to drain. */ - uint64_t val; - /* tstamp is the last timestamp in second resolution that is known - to this object. */ - uint64_t tstamp; -} nghttp2_ratelim; - -/* nghttp2_ratelim_init initializes |rl| with the given parameters. */ -void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate); - -/* nghttp2_ratelim_update updates rl->val with the current |tstamp| - given in second resolution. */ -void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp); - -/* nghttp2_ratelim_drain drains |n| from rl->val. It returns 0 if it - succeeds, or -1. */ -int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n); - -#endif /* NGHTTP2_RATELIM_H */ diff --git a/vendor/nghttp2/lib/nghttp2_rcbuf.c b/vendor/nghttp2/lib/nghttp2_rcbuf.c deleted file mode 100644 index 7e7814d2d..000000000 --- a/vendor/nghttp2/lib/nghttp2_rcbuf.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2016 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_rcbuf.h" - -#include -#include - -#include "nghttp2_mem.h" -#include "nghttp2_helper.h" - -int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size, - nghttp2_mem *mem) { - uint8_t *p; - - p = nghttp2_mem_malloc(mem, sizeof(nghttp2_rcbuf) + size); - if (p == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - *rcbuf_ptr = (void *)p; - - (*rcbuf_ptr)->mem_user_data = mem->mem_user_data; - (*rcbuf_ptr)->free = mem->free; - (*rcbuf_ptr)->base = p + sizeof(nghttp2_rcbuf); - (*rcbuf_ptr)->len = size; - (*rcbuf_ptr)->ref = 1; - - return 0; -} - -int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src, - size_t srclen, nghttp2_mem *mem) { - int rv; - - rv = nghttp2_rcbuf_new(rcbuf_ptr, srclen + 1, mem); - if (rv != 0) { - return rv; - } - - (*rcbuf_ptr)->len = srclen; - *nghttp2_cpymem((*rcbuf_ptr)->base, src, srclen) = '\0'; - - return 0; -} - -/* - * Frees |rcbuf| itself, regardless of its reference cout. - */ -void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf) { - nghttp2_mem_free2(rcbuf->free, rcbuf, rcbuf->mem_user_data); -} - -void nghttp2_rcbuf_incref(nghttp2_rcbuf *rcbuf) { - if (rcbuf->ref == -1) { - return; - } - - ++rcbuf->ref; -} - -void nghttp2_rcbuf_decref(nghttp2_rcbuf *rcbuf) { - if (rcbuf == NULL || rcbuf->ref == -1) { - return; - } - - assert(rcbuf->ref > 0); - - if (--rcbuf->ref == 0) { - nghttp2_rcbuf_del(rcbuf); - } -} - -nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf) { - nghttp2_vec res = {rcbuf->base, rcbuf->len}; - return res; -} - -int nghttp2_rcbuf_is_static(const nghttp2_rcbuf *rcbuf) { - return rcbuf->ref == -1; -} diff --git a/vendor/nghttp2/lib/nghttp2_rcbuf.h b/vendor/nghttp2/lib/nghttp2_rcbuf.h deleted file mode 100644 index 6814e709f..000000000 --- a/vendor/nghttp2/lib/nghttp2_rcbuf.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2016 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_RCBUF_H -#define NGHTTP2_RCBUF_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -struct nghttp2_rcbuf { - /* custom memory allocator belongs to the mem parameter when - creating this object. */ - void *mem_user_data; - nghttp2_free free; - /* The pointer to the underlying buffer */ - uint8_t *base; - /* Size of buffer pointed by |base|. */ - size_t len; - /* Reference count */ - int32_t ref; -}; - -/* - * Allocates nghttp2_rcbuf object with |size| as initial buffer size. - * When the function succeeds, the reference count becomes 1. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM: - * Out of memory. - */ -int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size, nghttp2_mem *mem); - -/* - * Like nghttp2_rcbuf_new(), but initializes the buffer with |src| of - * length |srclen|. This function allocates additional byte at the - * end and puts '\0' into it, so that the resulting buffer could be - * used as NULL-terminated string. Still (*rcbuf_ptr)->len equals to - * |srclen|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM: - * Out of memory. - */ -int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src, - size_t srclen, nghttp2_mem *mem); - -/* - * Frees |rcbuf| itself, regardless of its reference cout. - */ -void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf); - -#endif /* NGHTTP2_RCBUF_H */ diff --git a/vendor/nghttp2/lib/nghttp2_session.c b/vendor/nghttp2/lib/nghttp2_session.c deleted file mode 100644 index a7ab61d29..000000000 --- a/vendor/nghttp2/lib/nghttp2_session.c +++ /dev/null @@ -1,7970 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_session.h" - -#include -#include -#include -#include -#include - -#include "nghttp2_helper.h" -#include "nghttp2_net.h" -#include "nghttp2_priority_spec.h" -#include "nghttp2_option.h" -#include "nghttp2_http.h" -#include "nghttp2_pq.h" -#include "nghttp2_extpri.h" -#include "nghttp2_time.h" -#include "nghttp2_debug.h" -#include "nghttp2_submit.h" - -nghttp2_stream nghttp2_stream_root; - -/* - * Returns non-zero if the number of outgoing opened streams is larger - * than or equal to - * remote_settings.max_concurrent_streams. - */ -static int -session_is_outgoing_concurrent_streams_max(nghttp2_session *session) { - return session->remote_settings.max_concurrent_streams <= - session->num_outgoing_streams; -} - -/* - * Returns non-zero if the number of incoming opened streams is larger - * than or equal to - * local_settings.max_concurrent_streams. - */ -static int -session_is_incoming_concurrent_streams_max(nghttp2_session *session) { - return session->local_settings.max_concurrent_streams <= - session->num_incoming_streams; -} - -/* - * Returns non-zero if the number of incoming opened streams is larger - * than or equal to - * session->pending_local_max_concurrent_stream. - */ -static int -session_is_incoming_concurrent_streams_pending_max(nghttp2_session *session) { - return session->pending_local_max_concurrent_stream <= - session->num_incoming_streams; -} - -/* - * Returns non-zero if |lib_error| is non-fatal error. - */ -static int is_non_fatal(int lib_error_code) { - return lib_error_code < 0 && lib_error_code > NGHTTP2_ERR_FATAL; -} - -int nghttp2_is_fatal(int lib_error_code) { - return lib_error_code < NGHTTP2_ERR_FATAL; -} - -static int session_enforce_http_messaging(nghttp2_session *session) { - return (session->opt_flags & NGHTTP2_OPTMASK_NO_HTTP_MESSAGING) == 0; -} - -/* - * Returns nonzero if |frame| is trailer headers. - */ -static int session_trailer_headers(nghttp2_session *session, - nghttp2_stream *stream, - nghttp2_frame *frame) { - if (!stream || frame->hd.type != NGHTTP2_HEADERS) { - return 0; - } - if (session->server) { - return frame->headers.cat == NGHTTP2_HCAT_HEADERS; - } - - return frame->headers.cat == NGHTTP2_HCAT_HEADERS && - (stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) == 0; -} - -/* Returns nonzero if the |stream| is in reserved(remote) state */ -static int state_reserved_remote(nghttp2_session *session, - nghttp2_stream *stream) { - return stream->state == NGHTTP2_STREAM_RESERVED && - !nghttp2_session_is_my_stream_id(session, stream->stream_id); -} - -/* Returns nonzero if the |stream| is in reserved(local) state */ -static int state_reserved_local(nghttp2_session *session, - nghttp2_stream *stream) { - return stream->state == NGHTTP2_STREAM_RESERVED && - nghttp2_session_is_my_stream_id(session, stream->stream_id); -} - -/* - * Checks whether received stream_id is valid. This function returns - * 1 if it succeeds, or 0. - */ -static int session_is_new_peer_stream_id(nghttp2_session *session, - int32_t stream_id) { - return stream_id != 0 && - !nghttp2_session_is_my_stream_id(session, stream_id) && - session->last_recv_stream_id < stream_id; -} - -static int session_detect_idle_stream(nghttp2_session *session, - int32_t stream_id) { - /* Assume that stream object with stream_id does not exist */ - if (nghttp2_session_is_my_stream_id(session, stream_id)) { - if (session->last_sent_stream_id < stream_id) { - return 1; - } - return 0; - } - if (session_is_new_peer_stream_id(session, stream_id)) { - return 1; - } - return 0; -} - -static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) { - return (ext_types[type / 8] & (1 << (type & 0x7))) > 0; -} - -static int session_call_error_callback(nghttp2_session *session, - int lib_error_code, const char *fmt, - ...) { - size_t bufsize; - va_list ap; - char *buf; - int rv; - nghttp2_mem *mem; - - if (!session->callbacks.error_callback && - !session->callbacks.error_callback2) { - return 0; - } - - mem = &session->mem; - - va_start(ap, fmt); - rv = vsnprintf(NULL, 0, fmt, ap); - va_end(ap); - - if (rv < 0) { - return NGHTTP2_ERR_NOMEM; - } - - bufsize = (size_t)(rv + 1); - - buf = nghttp2_mem_malloc(mem, bufsize); - if (buf == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - va_start(ap, fmt); - rv = vsnprintf(buf, bufsize, fmt, ap); - va_end(ap); - - if (rv < 0) { - nghttp2_mem_free(mem, buf); - /* vsnprintf may return error because of various things we can - imagine, but typically we don't want to drop session just for - debug callback. */ - DEBUGF("error_callback: vsnprintf failed. The template was %s\n", fmt); - return 0; - } - - if (session->callbacks.error_callback2) { - rv = session->callbacks.error_callback2(session, lib_error_code, buf, - (size_t)rv, session->user_data); - } else { - rv = session->callbacks.error_callback(session, buf, (size_t)rv, - session->user_data); - } - - nghttp2_mem_free(mem, buf); - - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int session_terminate_session(nghttp2_session *session, - int32_t last_stream_id, - uint32_t error_code, const char *reason) { - int rv; - const uint8_t *debug_data; - size_t debug_datalen; - - if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) { - return 0; - } - - /* Ignore all incoming frames because we are going to tear down the - session. */ - session->iframe.state = NGHTTP2_IB_IGN_ALL; - - if (reason == NULL) { - debug_data = NULL; - debug_datalen = 0; - } else { - debug_data = (const uint8_t *)reason; - debug_datalen = strlen(reason); - } - - rv = - nghttp2_session_add_goaway(session, last_stream_id, error_code, debug_data, - debug_datalen, NGHTTP2_GOAWAY_AUX_TERM_ON_SEND); - - if (rv != 0) { - return rv; - } - - session->goaway_flags |= NGHTTP2_GOAWAY_TERM_ON_SEND; - - return 0; -} - -int nghttp2_session_terminate_session(nghttp2_session *session, - uint32_t error_code) { - return session_terminate_session(session, session->last_proc_stream_id, - error_code, NULL); -} - -int nghttp2_session_terminate_session2(nghttp2_session *session, - int32_t last_stream_id, - uint32_t error_code) { - return session_terminate_session(session, last_stream_id, error_code, NULL); -} - -int nghttp2_session_terminate_session_with_reason(nghttp2_session *session, - uint32_t error_code, - const char *reason) { - return session_terminate_session(session, session->last_proc_stream_id, - error_code, reason); -} - -int nghttp2_session_is_my_stream_id(nghttp2_session *session, - int32_t stream_id) { - int rem; - if (stream_id == 0) { - return 0; - } - rem = stream_id & 0x1; - if (session->server) { - return rem == 0; - } - return rem == 1; -} - -nghttp2_stream *nghttp2_session_get_stream(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - - stream = (nghttp2_stream *)nghttp2_map_find(&session->streams, stream_id); - - if (stream == NULL || (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) || - stream->state == NGHTTP2_STREAM_IDLE) { - return NULL; - } - - return stream; -} - -nghttp2_stream *nghttp2_session_get_stream_raw(nghttp2_session *session, - int32_t stream_id) { - return (nghttp2_stream *)nghttp2_map_find(&session->streams, stream_id); -} - -static void session_inbound_frame_reset(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_mem *mem = &session->mem; - /* A bit risky code, since if this function is called from - nghttp2_session_new(), we rely on the fact that - iframe->frame.hd.type is 0, so that no free is performed. */ - switch (iframe->frame.hd.type) { - case NGHTTP2_DATA: - break; - case NGHTTP2_HEADERS: - nghttp2_frame_headers_free(&iframe->frame.headers, mem); - break; - case NGHTTP2_PRIORITY: - nghttp2_frame_priority_free(&iframe->frame.priority); - break; - case NGHTTP2_RST_STREAM: - nghttp2_frame_rst_stream_free(&iframe->frame.rst_stream); - break; - case NGHTTP2_SETTINGS: - nghttp2_frame_settings_free(&iframe->frame.settings, mem); - - nghttp2_mem_free(mem, iframe->iv); - - iframe->iv = NULL; - iframe->niv = 0; - iframe->max_niv = 0; - - break; - case NGHTTP2_PUSH_PROMISE: - nghttp2_frame_push_promise_free(&iframe->frame.push_promise, mem); - break; - case NGHTTP2_PING: - nghttp2_frame_ping_free(&iframe->frame.ping); - break; - case NGHTTP2_GOAWAY: - nghttp2_frame_goaway_free(&iframe->frame.goaway, mem); - break; - case NGHTTP2_WINDOW_UPDATE: - nghttp2_frame_window_update_free(&iframe->frame.window_update); - break; - default: - /* extension frame */ - if (check_ext_type_set(session->user_recv_ext_types, - iframe->frame.hd.type)) { - nghttp2_frame_extension_free(&iframe->frame.ext); - } else { - switch (iframe->frame.hd.type) { - case NGHTTP2_ALTSVC: - if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == 0) { - break; - } - nghttp2_frame_altsvc_free(&iframe->frame.ext, mem); - break; - case NGHTTP2_ORIGIN: - if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN) == 0) { - break; - } - nghttp2_frame_origin_free(&iframe->frame.ext, mem); - break; - case NGHTTP2_PRIORITY_UPDATE: - if ((session->builtin_recv_ext_types & - NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) { - break; - } - /* Do not call nghttp2_frame_priority_update_free, because all - fields point to sbuf. */ - break; - } - } - - break; - } - - memset(&iframe->frame, 0, sizeof(nghttp2_frame)); - memset(&iframe->ext_frame_payload, 0, sizeof(nghttp2_ext_frame_payload)); - - iframe->state = NGHTTP2_IB_READ_HEAD; - - nghttp2_buf_wrap_init(&iframe->sbuf, iframe->raw_sbuf, - sizeof(iframe->raw_sbuf)); - iframe->sbuf.mark += NGHTTP2_FRAME_HDLEN; - - nghttp2_buf_free(&iframe->lbuf, mem); - nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0); - - iframe->raw_lbuf = NULL; - - iframe->payloadleft = 0; - iframe->padlen = 0; -} - -static void init_settings(nghttp2_settings_storage *settings) { - settings->header_table_size = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; - settings->enable_push = 1; - settings->max_concurrent_streams = NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; - settings->initial_window_size = NGHTTP2_INITIAL_WINDOW_SIZE; - settings->max_frame_size = NGHTTP2_MAX_FRAME_SIZE_MIN; - settings->max_header_list_size = UINT32_MAX; - settings->no_rfc7540_priorities = UINT32_MAX; -} - -static void active_outbound_item_reset(nghttp2_active_outbound_item *aob, - nghttp2_mem *mem) { - DEBUGF("send: reset nghttp2_active_outbound_item\n"); - DEBUGF("send: aob->item = %p\n", aob->item); - nghttp2_outbound_item_free(aob->item, mem); - nghttp2_mem_free(mem, aob->item); - aob->item = NULL; - nghttp2_bufs_reset(&aob->framebufs); - aob->state = NGHTTP2_OB_POP_ITEM; -} - -#define NGHTTP2_STREAM_MAX_CYCLE_GAP ((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX) - -static int stream_less(const void *lhsx, const void *rhsx) { - const nghttp2_stream *lhs, *rhs; - - lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry); - rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry); - - if (lhs->cycle == rhs->cycle) { - return lhs->seq < rhs->seq; - } - - return rhs->cycle - lhs->cycle <= NGHTTP2_STREAM_MAX_CYCLE_GAP; -} - -int nghttp2_enable_strict_preface = 1; - -static int session_new(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data, int server, - const nghttp2_option *option, nghttp2_mem *mem) { - int rv; - size_t nbuffer; - size_t max_deflate_dynamic_table_size = - NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE; - size_t i; - uint32_t map_seed; - - if (mem == NULL) { - mem = nghttp2_mem_default(); - } - - *session_ptr = nghttp2_mem_calloc(mem, 1, sizeof(nghttp2_session)); - if (*session_ptr == NULL) { - rv = NGHTTP2_ERR_NOMEM; - goto fail_session; - } - - (*session_ptr)->mem = *mem; - mem = &(*session_ptr)->mem; - - /* next_stream_id is initialized in either - nghttp2_session_client_new2 or nghttp2_session_server_new2 */ - - (*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE; - (*session_ptr)->recv_window_size = 0; - (*session_ptr)->consumed_size = 0; - (*session_ptr)->recv_reduction = 0; - (*session_ptr)->local_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE; - - (*session_ptr)->goaway_flags = NGHTTP2_GOAWAY_NONE; - (*session_ptr)->local_last_stream_id = (1u << 31) - 1; - (*session_ptr)->remote_last_stream_id = (1u << 31) - 1; - - (*session_ptr)->pending_local_max_concurrent_stream = - NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; - (*session_ptr)->pending_enable_push = 1; - (*session_ptr)->pending_no_rfc7540_priorities = UINT8_MAX; - - nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, - NGHTTP2_DEFAULT_STREAM_RESET_BURST, - NGHTTP2_DEFAULT_STREAM_RESET_RATE); - - nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim, - NGHTTP2_DEFAULT_GLITCH_BURST, - NGHTTP2_DEFAULT_GLITCH_RATE); - - if (server) { - (*session_ptr)->server = 1; - } - - init_settings(&(*session_ptr)->remote_settings); - init_settings(&(*session_ptr)->local_settings); - - (*session_ptr)->max_incoming_reserved_streams = - NGHTTP2_MAX_INCOMING_RESERVED_STREAMS; - - /* Limit max outgoing concurrent streams to sensible value */ - (*session_ptr)->remote_settings.max_concurrent_streams = 100; - - (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN; - (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM; - (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS; - (*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS; - - if (option) { - if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) && - option->no_auto_window_update) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE; - } - - if (option->opt_set_mask & NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS) { - (*session_ptr)->remote_settings.max_concurrent_streams = - option->peer_max_concurrent_streams; - } - - if (option->opt_set_mask & NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS) { - (*session_ptr)->max_incoming_reserved_streams = - option->max_reserved_remote_streams; - } - - if ((option->opt_set_mask & NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC) && - option->no_recv_client_magic) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC; - } - - if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) && - option->no_http_messaging) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_HTTP_MESSAGING; - } - - if (option->opt_set_mask & NGHTTP2_OPT_USER_RECV_EXT_TYPES) { - memcpy((*session_ptr)->user_recv_ext_types, option->user_recv_ext_types, - sizeof((*session_ptr)->user_recv_ext_types)); - } - - if (option->opt_set_mask & NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES) { - (*session_ptr)->builtin_recv_ext_types = option->builtin_recv_ext_types; - } - - if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_PING_ACK) && - option->no_auto_ping_ack) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_PING_ACK; - } - - if (option->opt_set_mask & NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH) { - (*session_ptr)->max_send_header_block_length = - option->max_send_header_block_length; - } - - if (option->opt_set_mask & NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE) { - max_deflate_dynamic_table_size = option->max_deflate_dynamic_table_size; - } - - if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) { - (*session_ptr)->max_outbound_ack = option->max_outbound_ack; - } - - if ((option->opt_set_mask & NGHTTP2_OPT_MAX_SETTINGS) && - option->max_settings) { - (*session_ptr)->max_settings = option->max_settings; - } - - if ((option->opt_set_mask & - NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) && - option->no_rfc9113_leading_and_trailing_ws_validation) { - (*session_ptr)->opt_flags |= - NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; - } - - if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) { - nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, - option->stream_reset_burst, - option->stream_reset_rate); - } - - if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) { - (*session_ptr)->max_continuations = option->max_continuations; - } - - if (option->opt_set_mask & NGHTTP2_OPT_GLITCH_RATE_LIMIT) { - nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim, - option->glitch_burst, option->glitch_rate); - } - } - - rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater, - max_deflate_dynamic_table_size, mem); - if (rv != 0) { - goto fail_hd_deflater; - } - rv = nghttp2_hd_inflate_init(&(*session_ptr)->hd_inflater, mem); - if (rv != 0) { - goto fail_hd_inflater; - } - - nbuffer = ((*session_ptr)->max_send_header_block_length + - NGHTTP2_FRAMEBUF_CHUNKLEN - 1) / - NGHTTP2_FRAMEBUF_CHUNKLEN; - - if (nbuffer == 0) { - nbuffer = 1; - } - - /* 1 for Pad Field. */ - rv = nghttp2_bufs_init3(&(*session_ptr)->aob.framebufs, - NGHTTP2_FRAMEBUF_CHUNKLEN, nbuffer, 1, - NGHTTP2_FRAME_HDLEN + 1, mem); - if (rv != 0) { - goto fail_aob_framebuf; - } - - if (callbacks->rand_callback) { - callbacks->rand_callback((uint8_t *)&map_seed, sizeof(map_seed)); - } else { - map_seed = 0; - } - - nghttp2_map_init(&(*session_ptr)->streams, map_seed, mem); - - active_outbound_item_reset(&(*session_ptr)->aob, mem); - - (*session_ptr)->callbacks = *callbacks; - (*session_ptr)->user_data = user_data; - - session_inbound_frame_reset(*session_ptr); - - if (nghttp2_enable_strict_preface) { - nghttp2_inbound_frame *iframe = &(*session_ptr)->iframe; - - if (server && ((*session_ptr)->opt_flags & - NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC) == 0) { - iframe->state = NGHTTP2_IB_READ_CLIENT_MAGIC; - iframe->payloadleft = NGHTTP2_CLIENT_MAGIC_LEN; - } else { - iframe->state = NGHTTP2_IB_READ_FIRST_SETTINGS; - } - - if (!server) { - (*session_ptr)->aob.state = NGHTTP2_OB_SEND_CLIENT_MAGIC; - nghttp2_bufs_add(&(*session_ptr)->aob.framebufs, NGHTTP2_CLIENT_MAGIC, - NGHTTP2_CLIENT_MAGIC_LEN); - } - } - - for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) { - nghttp2_pq_init(&(*session_ptr)->sched[i].ob_data, stream_less, mem); - } - - return 0; - -fail_aob_framebuf: - nghttp2_hd_inflate_free(&(*session_ptr)->hd_inflater); -fail_hd_inflater: - nghttp2_hd_deflate_free(&(*session_ptr)->hd_deflater); -fail_hd_deflater: - nghttp2_mem_free(mem, *session_ptr); -fail_session: - return rv; -} - -int nghttp2_session_client_new(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data) { - return nghttp2_session_client_new3(session_ptr, callbacks, user_data, NULL, - NULL); -} - -int nghttp2_session_client_new2(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option) { - return nghttp2_session_client_new3(session_ptr, callbacks, user_data, option, - NULL); -} - -int nghttp2_session_client_new3(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, - nghttp2_mem *mem) { - int rv; - nghttp2_session *session; - - rv = session_new(&session, callbacks, user_data, 0, option, mem); - - if (rv != 0) { - return rv; - } - /* IDs for use in client */ - session->next_stream_id = 1; - - *session_ptr = session; - - return 0; -} - -int nghttp2_session_server_new(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data) { - return nghttp2_session_server_new3(session_ptr, callbacks, user_data, NULL, - NULL); -} - -int nghttp2_session_server_new2(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option) { - return nghttp2_session_server_new3(session_ptr, callbacks, user_data, option, - NULL); -} - -int nghttp2_session_server_new3(nghttp2_session **session_ptr, - const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, - nghttp2_mem *mem) { - int rv; - nghttp2_session *session; - - rv = session_new(&session, callbacks, user_data, 1, option, mem); - - if (rv != 0) { - return rv; - } - /* IDs for use in client */ - session->next_stream_id = 2; - - *session_ptr = session; - - return 0; -} - -static int free_streams(void *entry, void *ptr) { - nghttp2_session *session; - nghttp2_stream *stream; - nghttp2_outbound_item *item; - nghttp2_mem *mem; - - session = (nghttp2_session *)ptr; - mem = &session->mem; - stream = (nghttp2_stream *)entry; - item = stream->item; - - if (item && !item->queued && item != session->aob.item) { - nghttp2_outbound_item_free(item, mem); - nghttp2_mem_free(mem, item); - } - - nghttp2_stream_free(stream); - nghttp2_mem_free(mem, stream); - - return 0; -} - -static void ob_q_free(nghttp2_outbound_queue *q, nghttp2_mem *mem) { - nghttp2_outbound_item *item, *next; - for (item = q->head; item;) { - next = item->qnext; - nghttp2_outbound_item_free(item, mem); - nghttp2_mem_free(mem, item); - item = next; - } -} - -static int inflight_settings_new(nghttp2_inflight_settings **settings_ptr, - const nghttp2_settings_entry *iv, size_t niv, - nghttp2_mem *mem) { - *settings_ptr = nghttp2_mem_malloc(mem, sizeof(nghttp2_inflight_settings)); - if (!*settings_ptr) { - return NGHTTP2_ERR_NOMEM; - } - - if (niv > 0) { - (*settings_ptr)->iv = nghttp2_frame_iv_copy(iv, niv, mem); - if (!(*settings_ptr)->iv) { - nghttp2_mem_free(mem, *settings_ptr); - return NGHTTP2_ERR_NOMEM; - } - } else { - (*settings_ptr)->iv = NULL; - } - - (*settings_ptr)->niv = niv; - (*settings_ptr)->next = NULL; - - return 0; -} - -static void inflight_settings_del(nghttp2_inflight_settings *settings, - nghttp2_mem *mem) { - if (!settings) { - return; - } - - nghttp2_mem_free(mem, settings->iv); - nghttp2_mem_free(mem, settings); -} - -void nghttp2_session_del(nghttp2_session *session) { - nghttp2_mem *mem; - nghttp2_inflight_settings *settings; - size_t i; - - if (session == NULL) { - return; - } - - mem = &session->mem; - - for (settings = session->inflight_settings_head; settings;) { - nghttp2_inflight_settings *next = settings->next; - inflight_settings_del(settings, mem); - settings = next; - } - - for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) { - nghttp2_pq_free(&session->sched[i].ob_data); - } - - /* Have to free streams first, so that we can check - stream->item->queued */ - nghttp2_map_each(&session->streams, free_streams, session); - nghttp2_map_free(&session->streams); - - ob_q_free(&session->ob_urgent, mem); - ob_q_free(&session->ob_reg, mem); - ob_q_free(&session->ob_syn, mem); - - active_outbound_item_reset(&session->aob, mem); - session_inbound_frame_reset(session); - nghttp2_hd_deflate_free(&session->hd_deflater); - nghttp2_hd_inflate_free(&session->hd_inflater); - nghttp2_bufs_free(&session->aob.framebufs); - nghttp2_mem_free(mem, session); -} - -static uint64_t pq_get_first_cycle(nghttp2_pq *pq) { - nghttp2_stream *stream; - - if (nghttp2_pq_empty(pq)) { - return 0; - } - - stream = nghttp2_struct_of(nghttp2_pq_top(pq), nghttp2_stream, pq_entry); - return stream->cycle; -} - -static int session_ob_data_push(nghttp2_session *session, - nghttp2_stream *stream) { - int rv; - uint32_t urgency; - int inc; - nghttp2_pq *pq; - - assert(stream->queued == 0); - - urgency = nghttp2_extpri_uint8_urgency(stream->extpri); - inc = nghttp2_extpri_uint8_inc(stream->extpri); - - assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS); - - pq = &session->sched[urgency].ob_data; - - stream->cycle = pq_get_first_cycle(pq); - if (inc) { - stream->cycle += stream->last_writelen; - } - - rv = nghttp2_pq_push(pq, &stream->pq_entry); - if (rv != 0) { - return rv; - } - - stream->queued = 1; - - return 0; -} - -static void session_ob_data_remove(nghttp2_session *session, - nghttp2_stream *stream) { - uint32_t urgency; - - assert(stream->queued == 1); - - urgency = nghttp2_extpri_uint8_urgency(stream->extpri); - - assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS); - - nghttp2_pq_remove(&session->sched[urgency].ob_data, &stream->pq_entry); - - stream->queued = 0; -} - -static int session_attach_stream_item(nghttp2_session *session, - nghttp2_stream *stream, - nghttp2_outbound_item *item) { - int rv; - - nghttp2_stream_attach_item(stream, item); - - rv = session_ob_data_push(session, stream); - if (rv != 0) { - nghttp2_stream_detach_item(stream); - - return rv; - } - - return 0; -} - -static void session_detach_stream_item(nghttp2_session *session, - nghttp2_stream *stream) { - nghttp2_stream_detach_item(stream); - - if (!stream->queued) { - return; - } - - session_ob_data_remove(session, stream); -} - -static void session_defer_stream_item(nghttp2_session *session, - nghttp2_stream *stream, uint8_t flags) { - nghttp2_stream_defer_item(stream, flags); - - if (!stream->queued) { - return; - } - - session_ob_data_remove(session, stream); -} - -static int session_resume_deferred_stream_item(nghttp2_session *session, - nghttp2_stream *stream, - uint8_t flags) { - nghttp2_stream_resume_deferred_item(stream, flags); - - if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) { - return 0; - } - - return session_ob_data_push(session, stream); -} - -static nghttp2_outbound_item * -session_sched_get_next_outbound_item(nghttp2_session *session) { - size_t i; - nghttp2_pq_entry *ent; - nghttp2_stream *stream; - - for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) { - ent = nghttp2_pq_top(&session->sched[i].ob_data); - if (!ent) { - continue; - } - - stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry); - return stream->item; - } - - return NULL; -} - -static int session_sched_empty(nghttp2_session *session) { - size_t i; - - for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) { - if (!nghttp2_pq_empty(&session->sched[i].ob_data)) { - return 0; - } - } - - return 1; -} - -static void session_sched_reschedule_stream(nghttp2_session *session, - nghttp2_stream *stream) { - nghttp2_pq *pq; - uint32_t urgency = nghttp2_extpri_uint8_urgency(stream->extpri); - int inc = nghttp2_extpri_uint8_inc(stream->extpri); - uint64_t penalty = (uint64_t)stream->last_writelen; - int rv; - - (void)rv; - - assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS); - - pq = &session->sched[urgency].ob_data; - - if (!inc || nghttp2_pq_size(pq) == 1) { - return; - } - - nghttp2_pq_remove(pq, &stream->pq_entry); - - stream->cycle += penalty; - - rv = nghttp2_pq_push(pq, &stream->pq_entry); - - assert(0 == rv); -} - -static int session_update_stream_priority(nghttp2_session *session, - nghttp2_stream *stream, - uint8_t u8extpri) { - if (stream->extpri == u8extpri) { - return 0; - } - - if (stream->queued) { - session_ob_data_remove(session, stream); - - stream->extpri = u8extpri; - - return session_ob_data_push(session, stream); - } - - stream->extpri = u8extpri; - - return 0; -} - -int nghttp2_session_add_item(nghttp2_session *session, - nghttp2_outbound_item *item) { - /* TODO Return error if stream is not found for the frame requiring - stream presence. */ - int rv = 0; - nghttp2_stream *stream; - nghttp2_frame *frame; - - frame = &item->frame; - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - - switch (frame->hd.type) { - case NGHTTP2_DATA: - if (!stream) { - return NGHTTP2_ERR_STREAM_CLOSED; - } - - if (stream->item) { - return NGHTTP2_ERR_DATA_EXIST; - } - - rv = session_attach_stream_item(session, stream, item); - - if (rv != 0) { - return rv; - } - - return 0; - case NGHTTP2_HEADERS: - /* We push request HEADERS and push response HEADERS to - dedicated queue because their transmission is affected by - SETTINGS_MAX_CONCURRENT_STREAMS */ - /* TODO If 2 HEADERS are submitted for reserved stream, then - both of them are queued into ob_syn, which is not - desirable. */ - if (frame->headers.cat == NGHTTP2_HCAT_REQUEST || - (stream && stream->state == NGHTTP2_STREAM_RESERVED)) { - nghttp2_outbound_queue_push(&session->ob_syn, item); - item->queued = 1; - return 0; - ; - } - - nghttp2_outbound_queue_push(&session->ob_reg, item); - item->queued = 1; - return 0; - case NGHTTP2_SETTINGS: - case NGHTTP2_PING: - nghttp2_outbound_queue_push(&session->ob_urgent, item); - item->queued = 1; - return 0; - case NGHTTP2_RST_STREAM: - if (stream) { - stream->state = NGHTTP2_STREAM_CLOSING; - } - nghttp2_outbound_queue_push(&session->ob_reg, item); - item->queued = 1; - return 0; - case NGHTTP2_PUSH_PROMISE: { - nghttp2_headers_aux_data *aux_data; - - aux_data = &item->aux_data.headers; - - if (!stream) { - return NGHTTP2_ERR_STREAM_CLOSED; - } - - if (!nghttp2_session_open_stream( - session, frame->push_promise.promised_stream_id, - NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_RESERVED, - aux_data->stream_user_data)) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_queue_push(&session->ob_reg, item); - item->queued = 1; - - return 0; - } - case NGHTTP2_WINDOW_UPDATE: - if (stream) { - stream->window_update_queued = 1; - } else if (frame->hd.stream_id == 0) { - session->window_update_queued = 1; - } - nghttp2_outbound_queue_push(&session->ob_reg, item); - item->queued = 1; - return 0; - default: - nghttp2_outbound_queue_push(&session->ob_reg, item); - item->queued = 1; - return 0; - } -} - -int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, - uint32_t error_code) { - return nghttp2_session_add_rst_stream_continue( - session, stream_id, error_code, - /* continue_without_stream = */ 1); -} - -int nghttp2_session_add_rst_stream_continue(nghttp2_session *session, - int32_t stream_id, - uint32_t error_code, - int continue_without_stream) { - int rv; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_stream *stream; - nghttp2_mem *mem; - - mem = &session->mem; - stream = nghttp2_session_get_stream(session, stream_id); - if (stream && stream->state == NGHTTP2_STREAM_CLOSING) { - return 0; - } - - /* Sending RST_STREAM to an idle stream is subject to protocol - violation. Historically, nghttp2 allows this. In order not to - disrupt the existing applications, we don't error out this case - and simply ignore it. */ - if (nghttp2_session_is_my_stream_id(session, stream_id)) { - if ((uint32_t)stream_id >= session->next_stream_id) { - return 0; - } - } else if (session->last_recv_stream_id < stream_id) { - return 0; - } - - /* Cancel pending request HEADERS in ob_syn if this RST_STREAM - refers to that stream. */ - if (!session->server && nghttp2_session_is_my_stream_id(session, stream_id) && - nghttp2_outbound_queue_top(&session->ob_syn)) { - nghttp2_headers_aux_data *aux_data; - nghttp2_frame *headers_frame; - - headers_frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame; - assert(headers_frame->hd.type == NGHTTP2_HEADERS); - - if (headers_frame->hd.stream_id <= stream_id) { - for (item = session->ob_syn.head; item; item = item->qnext) { - aux_data = &item->aux_data.headers; - - if (item->frame.hd.stream_id < stream_id) { - continue; - } - - /* stream_id in ob_syn queue must be strictly increasing. If - we found larger ID, then we can break here. */ - if (item->frame.hd.stream_id > stream_id || aux_data->canceled) { - break; - } - - aux_data->error_code = error_code; - aux_data->canceled = 1; - - return 0; - } - } - } - - /* To keep the old behaviour, do not fail if stream was not - found. */ - if (!continue_without_stream && !stream) { - return 0; - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - - nghttp2_frame_rst_stream_init(&frame->rst_stream, stream_id, error_code); - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - nghttp2_frame_rst_stream_free(&frame->rst_stream); - nghttp2_mem_free(mem, item); - return rv; - } - return 0; -} - -nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, - int32_t stream_id, uint8_t flags, - nghttp2_stream_state initial_state, - void *stream_user_data) { - int rv; - nghttp2_stream *stream; - int stream_alloc = 0; - nghttp2_mem *mem; - - mem = &session->mem; - stream = nghttp2_session_get_stream_raw(session, stream_id); - - if (session->opt_flags & - NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) { - flags |= NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; - } - - if (stream) { - assert(stream->state == NGHTTP2_STREAM_IDLE); - assert(initial_state != NGHTTP2_STREAM_IDLE); - - --session->num_idle_streams; - } else { - stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream)); - if (stream == NULL) { - return NULL; - } - - stream_alloc = 1; - } - - if (initial_state == NGHTTP2_STREAM_RESERVED) { - flags |= NGHTTP2_STREAM_FLAG_PUSH; - } - - if (stream_alloc) { - nghttp2_stream_init(stream, stream_id, flags, initial_state, - (int32_t)session->remote_settings.initial_window_size, - (int32_t)session->local_settings.initial_window_size, - stream_user_data); - stream->seq = session->stream_seq++; - - rv = nghttp2_map_insert(&session->streams, stream_id, stream); - if (rv != 0) { - nghttp2_stream_free(stream); - nghttp2_mem_free(mem, stream); - return NULL; - } - } else { - stream->flags = flags; - stream->state = initial_state; - stream->stream_user_data = stream_user_data; - } - - switch (initial_state) { - case NGHTTP2_STREAM_RESERVED: - if (nghttp2_session_is_my_stream_id(session, stream_id)) { - /* reserved (local) */ - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - } else { - /* reserved (remote) */ - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR); - ++session->num_incoming_reserved_streams; - } - /* Reserved stream does not count in the concurrent streams - limit. That is one of the DOS vector. */ - break; - case NGHTTP2_STREAM_IDLE: - ++session->num_idle_streams; - break; - default: - if (nghttp2_session_is_my_stream_id(session, stream_id)) { - ++session->num_outgoing_streams; - } else { - ++session->num_incoming_streams; - } - } - - return stream; -} - -int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, - uint32_t error_code) { - nghttp2_stream *stream; - nghttp2_mem *mem; - int is_my_stream_id; - - mem = &session->mem; - stream = nghttp2_session_get_stream(session, stream_id); - - if (!stream) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - DEBUGF("stream: stream(%p)=%d close\n", stream, stream->stream_id); - - /* We call on_stream_close_callback even if stream->state is - NGHTTP2_STREAM_INITIAL. This will happen while sending request - HEADERS, a local endpoint receives RST_STREAM for that stream. It - may be PROTOCOL_ERROR, but without notifying stream closure will - hang the stream in a local endpoint. - */ - - if (session->callbacks.on_stream_close_callback) { - if (session->callbacks.on_stream_close_callback( - session, stream_id, error_code, session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - - if (stream->item) { - nghttp2_outbound_item *item; - - item = stream->item; - - session_detach_stream_item(session, stream); - - /* If item is queued, it will be deleted when it is popped - (nghttp2_session_prep_frame() will fail). If session->aob.item - points to this item, let active_outbound_item_reset() - free the item. */ - if (!item->queued && item != session->aob.item) { - nghttp2_outbound_item_free(item, mem); - nghttp2_mem_free(mem, item); - } - } - - is_my_stream_id = nghttp2_session_is_my_stream_id(session, stream_id); - - /* pushed streams which is not opened yet is not counted toward max - concurrent limits */ - if ((stream->flags & NGHTTP2_STREAM_FLAG_PUSH)) { - if (!is_my_stream_id) { - --session->num_incoming_reserved_streams; - } - } else { - if (is_my_stream_id) { - --session->num_outgoing_streams; - } else { - --session->num_incoming_streams; - } - } - - /* Closes both directions just in case they are not closed yet */ - stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED; - - nghttp2_session_destroy_stream(session, stream); - - return 0; -} - -void nghttp2_session_destroy_stream(nghttp2_session *session, - nghttp2_stream *stream) { - nghttp2_mem *mem; - - DEBUGF("stream: destroy closed stream(%p)=%d\n", stream, stream->stream_id); - - mem = &session->mem; - - if (stream->queued) { - session_ob_data_remove(session, stream); - } - - nghttp2_map_remove(&session->streams, stream->stream_id); - nghttp2_stream_free(stream); - nghttp2_mem_free(mem, stream); -} - -/* - * Closes stream with stream ID |stream_id| if both transmission and - * reception of the stream were disallowed. The |error_code| indicates - * the reason of the closure. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_INVALID_ARGUMENT - * The stream is not found. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_close_stream_if_shut_rdwr(nghttp2_session *session, - nghttp2_stream *stream) { - if ((stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR) { - return nghttp2_session_close_stream(session, stream->stream_id, - NGHTTP2_NO_ERROR); - } - return 0; -} - -/* - * Returns nonzero if local endpoint allows reception of new stream - * from remote. - */ -static int session_allow_incoming_new_stream(nghttp2_session *session) { - return (session->goaway_flags & - (NGHTTP2_GOAWAY_TERM_ON_SEND | NGHTTP2_GOAWAY_SENT)) == 0; -} - -/* - * This function returns nonzero if session is closing. - */ -static int session_is_closing(nghttp2_session *session) { - return (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) != 0 || - (nghttp2_session_want_read(session) == 0 && - nghttp2_session_want_write(session) == 0); -} - -/* - * Check that we can send a frame to the |stream|. This function - * returns 0 if we can send a frame to the |frame|, or one of the - * following negative error codes: - * - * NGHTTP2_ERR_STREAM_CLOSED - * The stream is already closed. - * NGHTTP2_ERR_STREAM_SHUT_WR - * The stream is half-closed for transmission. - * NGHTTP2_ERR_SESSION_CLOSING - * This session is closing. - */ -static int session_predicate_for_stream_send(nghttp2_session *session, - nghttp2_stream *stream) { - if (stream == NULL) { - return NGHTTP2_ERR_STREAM_CLOSED; - } - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - if (stream->shut_flags & NGHTTP2_SHUT_WR) { - return NGHTTP2_ERR_STREAM_SHUT_WR; - } - return 0; -} - -int nghttp2_session_check_request_allowed(nghttp2_session *session) { - return !session->server && session->next_stream_id <= INT32_MAX && - (session->goaway_flags & NGHTTP2_GOAWAY_RECV) == 0 && - !session_is_closing(session); -} - -/* - * This function checks request HEADERS frame, which opens stream, can - * be sent at this time. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_START_STREAM_NOT_ALLOWED - * New stream cannot be created because of GOAWAY: session is - * going down or received last_stream_id is strictly less than - * frame->hd.stream_id. - * NGHTTP2_ERR_STREAM_CLOSING - * request HEADERS was canceled by RST_STREAM while it is in queue. - */ -static int session_predicate_request_headers_send(nghttp2_session *session, - nghttp2_outbound_item *item) { - if (item->aux_data.headers.canceled) { - return NGHTTP2_ERR_STREAM_CLOSING; - } - /* If we are terminating session (NGHTTP2_GOAWAY_TERM_ON_SEND), - GOAWAY was received from peer, or session is about to close, new - request is not allowed. */ - if ((session->goaway_flags & NGHTTP2_GOAWAY_RECV) || - session_is_closing(session)) { - return NGHTTP2_ERR_START_STREAM_NOT_ALLOWED; - } - return 0; -} - -/* - * This function checks HEADERS, which is the first frame from the - * server, with the |stream| can be sent at this time. The |stream| - * can be NULL. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_STREAM_CLOSED - * The stream is already closed or does not exist. - * NGHTTP2_ERR_STREAM_SHUT_WR - * The transmission is not allowed for this stream (e.g., a frame - * with END_STREAM flag set has already sent) - * NGHTTP2_ERR_INVALID_STREAM_ID - * The stream ID is invalid. - * NGHTTP2_ERR_STREAM_CLOSING - * RST_STREAM was queued for this stream. - * NGHTTP2_ERR_INVALID_STREAM_STATE - * The state of the stream is not valid. - * NGHTTP2_ERR_SESSION_CLOSING - * This session is closing. - * NGHTTP2_ERR_PROTO - * Client side attempted to send response. - */ -static int session_predicate_response_headers_send(nghttp2_session *session, - nghttp2_stream *stream) { - int rv; - rv = session_predicate_for_stream_send(session, stream); - if (rv != 0) { - return rv; - } - assert(stream); - if (!session->server) { - return NGHTTP2_ERR_PROTO; - } - if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) { - return NGHTTP2_ERR_INVALID_STREAM_ID; - } - switch (stream->state) { - case NGHTTP2_STREAM_OPENING: - return 0; - case NGHTTP2_STREAM_CLOSING: - return NGHTTP2_ERR_STREAM_CLOSING; - default: - return NGHTTP2_ERR_INVALID_STREAM_STATE; - } -} - -/* - * This function checks HEADERS for reserved stream can be sent. The - * |stream| must be reserved state and the |session| is server side. - * The |stream| can be NULL. - * - * This function returns 0 if it succeeds, or one of the following - * error codes: - * - * NGHTTP2_ERR_STREAM_CLOSED - * The stream is already closed. - * NGHTTP2_ERR_STREAM_SHUT_WR - * The stream is half-closed for transmission. - * NGHTTP2_ERR_PROTO - * The stream is not reserved state - * NGHTTP2_ERR_STREAM_CLOSED - * RST_STREAM was queued for this stream. - * NGHTTP2_ERR_SESSION_CLOSING - * This session is closing. - * NGHTTP2_ERR_START_STREAM_NOT_ALLOWED - * New stream cannot be created because GOAWAY is already sent or - * received. - * NGHTTP2_ERR_PROTO - * Client side attempted to send push response. - */ -static int -session_predicate_push_response_headers_send(nghttp2_session *session, - nghttp2_stream *stream) { - int rv; - /* TODO Should disallow HEADERS if GOAWAY has already been issued? */ - rv = session_predicate_for_stream_send(session, stream); - if (rv != 0) { - return rv; - } - assert(stream); - if (!session->server) { - return NGHTTP2_ERR_PROTO; - } - if (stream->state != NGHTTP2_STREAM_RESERVED) { - return NGHTTP2_ERR_PROTO; - } - if (session->goaway_flags & NGHTTP2_GOAWAY_RECV) { - return NGHTTP2_ERR_START_STREAM_NOT_ALLOWED; - } - return 0; -} - -/* - * This function checks HEADERS, which is neither stream-opening nor - * first response header, with the |stream| can be sent at this time. - * The |stream| can be NULL. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_STREAM_CLOSED - * The stream is already closed or does not exist. - * NGHTTP2_ERR_STREAM_SHUT_WR - * The transmission is not allowed for this stream (e.g., a frame - * with END_STREAM flag set has already sent) - * NGHTTP2_ERR_STREAM_CLOSING - * RST_STREAM was queued for this stream. - * NGHTTP2_ERR_INVALID_STREAM_STATE - * The state of the stream is not valid. - * NGHTTP2_ERR_SESSION_CLOSING - * This session is closing. - */ -static int session_predicate_headers_send(nghttp2_session *session, - nghttp2_stream *stream) { - int rv; - rv = session_predicate_for_stream_send(session, stream); - if (rv != 0) { - return rv; - } - assert(stream); - - switch (stream->state) { - case NGHTTP2_STREAM_OPENED: - return 0; - case NGHTTP2_STREAM_CLOSING: - return NGHTTP2_ERR_STREAM_CLOSING; - default: - if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) { - return 0; - } - return NGHTTP2_ERR_INVALID_STREAM_STATE; - } -} - -/* - * This function checks PUSH_PROMISE frame |frame| with the |stream| - * can be sent at this time. The |stream| can be NULL. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_START_STREAM_NOT_ALLOWED - * New stream cannot be created because GOAWAY is already sent or - * received. - * NGHTTP2_ERR_PROTO - * The client side attempts to send PUSH_PROMISE, or the server - * sends PUSH_PROMISE for the stream not initiated by the client. - * NGHTTP2_ERR_STREAM_CLOSED - * The stream is already closed or does not exist. - * NGHTTP2_ERR_STREAM_CLOSING - * RST_STREAM was queued for this stream. - * NGHTTP2_ERR_STREAM_SHUT_WR - * The transmission is not allowed for this stream (e.g., a frame - * with END_STREAM flag set has already sent) - * NGHTTP2_ERR_PUSH_DISABLED - * The remote peer disabled reception of PUSH_PROMISE. - * NGHTTP2_ERR_SESSION_CLOSING - * This session is closing. - */ -static int session_predicate_push_promise_send(nghttp2_session *session, - nghttp2_stream *stream) { - int rv; - - if (!session->server) { - return NGHTTP2_ERR_PROTO; - } - - rv = session_predicate_for_stream_send(session, stream); - if (rv != 0) { - return rv; - } - - assert(stream); - - if (session->remote_settings.enable_push == 0) { - return NGHTTP2_ERR_PUSH_DISABLED; - } - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_STREAM_CLOSING; - } - if (session->goaway_flags & NGHTTP2_GOAWAY_RECV) { - return NGHTTP2_ERR_START_STREAM_NOT_ALLOWED; - } - return 0; -} - -/* - * This function checks WINDOW_UPDATE with the stream ID |stream_id| - * can be sent at this time. Note that END_STREAM flag of the previous - * frame does not affect the transmission of the WINDOW_UPDATE frame. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_STREAM_CLOSED - * The stream is already closed or does not exist. - * NGHTTP2_ERR_STREAM_CLOSING - * RST_STREAM was queued for this stream. - * NGHTTP2_ERR_INVALID_STREAM_STATE - * The state of the stream is not valid. - * NGHTTP2_ERR_SESSION_CLOSING - * This session is closing. - */ -static int session_predicate_window_update_send(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - - if (stream_id == 0) { - /* Connection-level window update */ - return 0; - } - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL) { - return NGHTTP2_ERR_STREAM_CLOSED; - } - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_STREAM_CLOSING; - } - if (state_reserved_local(session, stream)) { - return NGHTTP2_ERR_INVALID_STREAM_STATE; - } - return 0; -} - -static int session_predicate_altsvc_send(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - - if (stream_id == 0) { - return 0; - } - - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL) { - return NGHTTP2_ERR_STREAM_CLOSED; - } - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_STREAM_CLOSING; - } - - return 0; -} - -static int session_predicate_origin_send(nghttp2_session *session) { - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - return 0; -} - -static int session_predicate_priority_update_send(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL) { - return 0; - } - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_STREAM_CLOSING; - } - if (stream->shut_flags & NGHTTP2_SHUT_RD) { - return NGHTTP2_ERR_INVALID_STREAM_STATE; - } - - return 0; -} - -/* Take into account settings max frame size and both connection-level - flow control here */ -static nghttp2_ssize nghttp2_session_enforce_flow_control_limits( - nghttp2_session *session, nghttp2_stream *stream, - nghttp2_ssize requested_window_size) { - DEBUGF("send: remote windowsize connection=%d, remote maxframsize=%u, " - "stream(id %d)=%d\n", - session->remote_window_size, session->remote_settings.max_frame_size, - stream->stream_id, stream->remote_window_size); - - return nghttp2_min_int32( - nghttp2_min_int32(nghttp2_min_int32((int32_t)requested_window_size, - stream->remote_window_size), - session->remote_window_size), - (int32_t)session->remote_settings.max_frame_size); -} - -/* - * Returns the maximum length of next data read. If the - * connection-level and/or stream-wise flow control are enabled, the - * return value takes into account those current window sizes. The remote - * settings for max frame size is also taken into account. - */ -static size_t nghttp2_session_next_data_read(nghttp2_session *session, - nghttp2_stream *stream) { - nghttp2_ssize window_size; - - window_size = nghttp2_session_enforce_flow_control_limits( - session, stream, NGHTTP2_DATA_PAYLOADLEN); - - DEBUGF("send: available window=%td\n", window_size); - - return window_size > 0 ? (size_t)window_size : 0; -} - -/* - * This function checks DATA with the |stream| can be sent at this - * time. The |stream| can be NULL. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_STREAM_CLOSED - * The stream is already closed or does not exist. - * NGHTTP2_ERR_STREAM_SHUT_WR - * The transmission is not allowed for this stream (e.g., a frame - * with END_STREAM flag set has already sent) - * NGHTTP2_ERR_STREAM_CLOSING - * RST_STREAM was queued for this stream. - * NGHTTP2_ERR_INVALID_STREAM_STATE - * The state of the stream is not valid. - * NGHTTP2_ERR_SESSION_CLOSING - * This session is closing. - */ -static int nghttp2_session_predicate_data_send(nghttp2_session *session, - nghttp2_stream *stream) { - int rv; - rv = session_predicate_for_stream_send(session, stream); - if (rv != 0) { - return rv; - } - assert(stream); - if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) { - /* Request body data */ - /* If stream->state is NGHTTP2_STREAM_CLOSING, RST_STREAM was - queued but not yet sent. In this case, we won't send DATA - frames. */ - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_STREAM_CLOSING; - } - if (stream->state == NGHTTP2_STREAM_RESERVED) { - return NGHTTP2_ERR_INVALID_STREAM_STATE; - } - return 0; - } - /* Response body data */ - if (stream->state == NGHTTP2_STREAM_OPENED) { - return 0; - } - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_STREAM_CLOSING; - } - return NGHTTP2_ERR_INVALID_STREAM_STATE; -} - -static nghttp2_ssize session_call_select_padding(nghttp2_session *session, - const nghttp2_frame *frame, - size_t max_payloadlen) { - nghttp2_ssize rv; - size_t max_paddedlen; - - if (frame->hd.length >= max_payloadlen || - (!session->callbacks.select_padding_callback2 && - !session->callbacks.select_padding_callback)) { - return (nghttp2_ssize)frame->hd.length; - } - - max_paddedlen = - nghttp2_min_size(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen); - - if (session->callbacks.select_padding_callback2) { - rv = session->callbacks.select_padding_callback2( - session, frame, max_paddedlen, session->user_data); - } else { - rv = (nghttp2_ssize)session->callbacks.select_padding_callback( - session, frame, max_paddedlen, session->user_data); - } - if (rv < (nghttp2_ssize)frame->hd.length || - rv > (nghttp2_ssize)max_paddedlen) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - return rv; -} - -/* Add padding to HEADERS or PUSH_PROMISE. We use - frame->headers.padlen in this function to use the fact that - frame->push_promise has also padlen in the same position. */ -static int session_headers_add_pad(nghttp2_session *session, - nghttp2_frame *frame) { - nghttp2_ssize padded_payloadlen; - nghttp2_active_outbound_item *aob; - nghttp2_bufs *framebufs; - size_t padlen; - size_t max_payloadlen; - - aob = &session->aob; - framebufs = &aob->framebufs; - - max_payloadlen = nghttp2_min_size(NGHTTP2_MAX_PAYLOADLEN, - frame->hd.length + NGHTTP2_MAX_PADLEN); - - padded_payloadlen = - session_call_select_padding(session, frame, max_payloadlen); - - if (nghttp2_is_fatal((int)padded_payloadlen)) { - return (int)padded_payloadlen; - } - - padlen = (size_t)padded_payloadlen - frame->hd.length; - - DEBUGF("send: padding selected: payloadlen=%td, padlen=%zu\n", - padded_payloadlen, padlen); - - nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0); - - frame->headers.padlen = padlen; - - return 0; -} - -static size_t session_estimate_headers_payload(nghttp2_session *session, - const nghttp2_nv *nva, - size_t nvlen, - size_t additional) { - return nghttp2_hd_deflate_bound(&session->hd_deflater, nva, nvlen) + - additional; -} - -static int session_pack_extension(nghttp2_session *session, nghttp2_bufs *bufs, - nghttp2_frame *frame) { - nghttp2_ssize rv; - nghttp2_buf *buf; - size_t buflen; - size_t framelen; - - assert(session->callbacks.pack_extension_callback2 || - session->callbacks.pack_extension_callback); - - buf = &bufs->head->buf; - buflen = nghttp2_min_size(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN); - - if (session->callbacks.pack_extension_callback2) { - rv = session->callbacks.pack_extension_callback2(session, buf->last, buflen, - frame, session->user_data); - } else { - rv = (nghttp2_ssize)session->callbacks.pack_extension_callback( - session, buf->last, buflen, frame, session->user_data); - } - if (rv == NGHTTP2_ERR_CANCEL) { - return (int)rv; - } - - if (rv < 0 || (size_t)rv > buflen) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - framelen = (size_t)rv; - - frame->hd.length = framelen; - - assert(buf->pos == buf->last); - buf->last += framelen; - buf->pos -= NGHTTP2_FRAME_HDLEN; - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - return 0; -} - -/* - * This function serializes frame for transmission. - * - * This function returns 0 if it succeeds, or one of negative error - * codes, including both fatal and non-fatal ones. - */ -static int session_prep_frame(nghttp2_session *session, - nghttp2_outbound_item *item) { - int rv; - nghttp2_frame *frame; - nghttp2_mem *mem; - - mem = &session->mem; - frame = &item->frame; - - switch (frame->hd.type) { - case NGHTTP2_DATA: { - size_t next_readmax; - nghttp2_stream *stream; - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - - if (stream) { - assert(stream->item == item); - } - - rv = nghttp2_session_predicate_data_send(session, stream); - if (rv != 0) { - // If stream was already closed, nghttp2_session_get_stream() - // returns NULL, but item is still attached to the stream. - // Search stream including closed again. - stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); - if (stream) { - session_detach_stream_item(session, stream); - } - - return rv; - } - /* Assuming stream is not NULL */ - assert(stream); - next_readmax = nghttp2_session_next_data_read(session, stream); - - if (next_readmax == 0) { - /* This must be true since we only pop DATA frame item from - queue when session->remote_window_size > 0 */ - assert(session->remote_window_size > 0); - - session_defer_stream_item(session, stream, - NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); - - session->aob.item = NULL; - active_outbound_item_reset(&session->aob, mem); - return NGHTTP2_ERR_DEFERRED; - } - - rv = - nghttp2_session_pack_data(session, &session->aob.framebufs, next_readmax, - frame, &item->aux_data.data, stream); - if (rv == NGHTTP2_ERR_PAUSE) { - return rv; - } - if (rv == NGHTTP2_ERR_DEFERRED) { - session_defer_stream_item(session, stream, - NGHTTP2_STREAM_FLAG_DEFERRED_USER); - - session->aob.item = NULL; - active_outbound_item_reset(&session->aob, mem); - return NGHTTP2_ERR_DEFERRED; - } - if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - session_detach_stream_item(session, stream); - - rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id, - NGHTTP2_INTERNAL_ERROR); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } - if (rv != 0) { - session_detach_stream_item(session, stream); - - return rv; - } - return 0; - } - case NGHTTP2_HEADERS: { - nghttp2_headers_aux_data *aux_data; - size_t estimated_payloadlen; - - aux_data = &item->aux_data.headers; - - if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) { - /* initial HEADERS, which opens stream */ - nghttp2_stream *stream; - - stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, - NGHTTP2_STREAM_INITIAL, aux_data->stream_user_data); - - if (stream == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - rv = session_predicate_request_headers_send(session, item); - if (rv != 0) { - return rv; - } - - if (session_enforce_http_messaging(session)) { - nghttp2_http_record_request_method(stream, frame); - } - } else { - nghttp2_stream *stream; - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - - if (stream && stream->state == NGHTTP2_STREAM_RESERVED) { - rv = session_predicate_push_response_headers_send(session, stream); - if (rv == 0) { - frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE; - - if (aux_data->stream_user_data) { - stream->stream_user_data = aux_data->stream_user_data; - } - } - } else if (session_predicate_response_headers_send(session, stream) == - 0) { - frame->headers.cat = NGHTTP2_HCAT_RESPONSE; - rv = 0; - } else { - frame->headers.cat = NGHTTP2_HCAT_HEADERS; - - rv = session_predicate_headers_send(session, stream); - } - - if (rv != 0) { - return rv; - } - } - - estimated_payloadlen = session_estimate_headers_payload( - session, frame->headers.nva, frame->headers.nvlen, - NGHTTP2_PRIORITY_SPECLEN); - - if (estimated_payloadlen > session->max_send_header_block_length) { - return NGHTTP2_ERR_FRAME_SIZE_ERROR; - } - - rv = nghttp2_frame_pack_headers(&session->aob.framebufs, &frame->headers, - &session->hd_deflater); - - if (rv != 0) { - return rv; - } - - DEBUGF("send: before padding, HEADERS serialized in %zu bytes\n", - nghttp2_bufs_len(&session->aob.framebufs)); - - rv = session_headers_add_pad(session, frame); - - if (rv != 0) { - return rv; - } - - DEBUGF("send: HEADERS finally serialized in %zu bytes\n", - nghttp2_bufs_len(&session->aob.framebufs)); - - if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) { - assert(session->last_sent_stream_id < frame->hd.stream_id); - session->last_sent_stream_id = frame->hd.stream_id; - } - - return 0; - } - case NGHTTP2_PRIORITY: { - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - /* PRIORITY frame can be sent at any time and to any stream - ID. */ - nghttp2_frame_pack_priority(&session->aob.framebufs, &frame->priority); - - /* Peer can send PRIORITY frame against idle stream to create - "anchor" in dependency tree. Only client can do this in - nghttp2. In nghttp2, only server retains non-active (closed - or idle) streams in memory, so we don't open stream here. */ - return 0; - } - case NGHTTP2_RST_STREAM: - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - nghttp2_frame_pack_rst_stream(&session->aob.framebufs, &frame->rst_stream); - return 0; - case NGHTTP2_SETTINGS: { - if (frame->hd.flags & NGHTTP2_FLAG_ACK) { - assert(session->obq_flood_counter_ > 0); - --session->obq_flood_counter_; - /* When session is about to close, don't send SETTINGS ACK. - We are required to send SETTINGS without ACK though; for - example, we have to send SETTINGS as a part of connection - preface. */ - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - } - - rv = nghttp2_frame_pack_settings(&session->aob.framebufs, &frame->settings); - if (rv != 0) { - return rv; - } - return 0; - } - case NGHTTP2_PUSH_PROMISE: { - nghttp2_stream *stream; - size_t estimated_payloadlen; - - /* stream could be NULL if associated stream was already - closed. */ - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - - /* predicate should fail if stream is NULL. */ - rv = session_predicate_push_promise_send(session, stream); - if (rv != 0) { - return rv; - } - - assert(stream); - - estimated_payloadlen = session_estimate_headers_payload( - session, frame->push_promise.nva, frame->push_promise.nvlen, 0); - - if (estimated_payloadlen > session->max_send_header_block_length) { - return NGHTTP2_ERR_FRAME_SIZE_ERROR; - } - - rv = nghttp2_frame_pack_push_promise( - &session->aob.framebufs, &frame->push_promise, &session->hd_deflater); - if (rv != 0) { - return rv; - } - rv = session_headers_add_pad(session, frame); - if (rv != 0) { - return rv; - } - - assert(session->last_sent_stream_id + 2 <= - frame->push_promise.promised_stream_id); - session->last_sent_stream_id = frame->push_promise.promised_stream_id; - - return 0; - } - case NGHTTP2_PING: - if (frame->hd.flags & NGHTTP2_FLAG_ACK) { - assert(session->obq_flood_counter_ > 0); - --session->obq_flood_counter_; - } - /* PING frame is allowed to be sent unless termination GOAWAY is - sent */ - if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - nghttp2_frame_pack_ping(&session->aob.framebufs, &frame->ping); - return 0; - case NGHTTP2_GOAWAY: - rv = nghttp2_frame_pack_goaway(&session->aob.framebufs, &frame->goaway); - if (rv != 0) { - return rv; - } - session->local_last_stream_id = frame->goaway.last_stream_id; - - return 0; - case NGHTTP2_WINDOW_UPDATE: - rv = session_predicate_window_update_send(session, frame->hd.stream_id); - if (rv != 0) { - return rv; - } - nghttp2_frame_pack_window_update(&session->aob.framebufs, - &frame->window_update); - return 0; - case NGHTTP2_CONTINUATION: - /* We never handle CONTINUATION here. */ - assert(0); - return 0; - default: { - nghttp2_ext_aux_data *aux_data; - - /* extension frame */ - - aux_data = &item->aux_data.ext; - - if (aux_data->builtin == 0) { - if (session_is_closing(session)) { - return NGHTTP2_ERR_SESSION_CLOSING; - } - - return session_pack_extension(session, &session->aob.framebufs, frame); - } - - switch (frame->hd.type) { - case NGHTTP2_ALTSVC: - rv = session_predicate_altsvc_send(session, frame->hd.stream_id); - if (rv != 0) { - return rv; - } - - nghttp2_frame_pack_altsvc(&session->aob.framebufs, &frame->ext); - - return 0; - case NGHTTP2_ORIGIN: - rv = session_predicate_origin_send(session); - if (rv != 0) { - return rv; - } - - rv = nghttp2_frame_pack_origin(&session->aob.framebufs, &frame->ext); - if (rv != 0) { - return rv; - } - - return 0; - case NGHTTP2_PRIORITY_UPDATE: { - nghttp2_ext_priority_update *priority_update = frame->ext.payload; - rv = session_predicate_priority_update_send(session, - priority_update->stream_id); - if (rv != 0) { - return rv; - } - - nghttp2_frame_pack_priority_update(&session->aob.framebufs, &frame->ext); - - return 0; - } - default: - /* Unreachable here */ - assert(0); - return 0; - } - } - } -} - -nghttp2_outbound_item * -nghttp2_session_get_next_ob_item(nghttp2_session *session) { - if (nghttp2_outbound_queue_top(&session->ob_urgent)) { - return nghttp2_outbound_queue_top(&session->ob_urgent); - } - - if (nghttp2_outbound_queue_top(&session->ob_reg)) { - return nghttp2_outbound_queue_top(&session->ob_reg); - } - - if (!session_is_outgoing_concurrent_streams_max(session)) { - if (nghttp2_outbound_queue_top(&session->ob_syn)) { - return nghttp2_outbound_queue_top(&session->ob_syn); - } - } - - if (session->remote_window_size > 0) { - return session_sched_get_next_outbound_item(session); - } - - return NULL; -} - -nghttp2_outbound_item * -nghttp2_session_pop_next_ob_item(nghttp2_session *session) { - nghttp2_outbound_item *item; - - item = nghttp2_outbound_queue_top(&session->ob_urgent); - if (item) { - nghttp2_outbound_queue_pop(&session->ob_urgent); - item->queued = 0; - return item; - } - - item = nghttp2_outbound_queue_top(&session->ob_reg); - if (item) { - nghttp2_outbound_queue_pop(&session->ob_reg); - item->queued = 0; - return item; - } - - if (!session_is_outgoing_concurrent_streams_max(session)) { - item = nghttp2_outbound_queue_top(&session->ob_syn); - if (item) { - nghttp2_outbound_queue_pop(&session->ob_syn); - item->queued = 0; - return item; - } - } - - if (session->remote_window_size > 0) { - return session_sched_get_next_outbound_item(session); - } - - return NULL; -} - -static int session_call_before_frame_send(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - if (session->callbacks.before_frame_send_callback) { - rv = session->callbacks.before_frame_send_callback(session, frame, - session->user_data); - if (rv == NGHTTP2_ERR_CANCEL) { - return rv; - } - - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - return 0; -} - -static int session_call_on_frame_send(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - if (session->callbacks.on_frame_send_callback) { - rv = session->callbacks.on_frame_send_callback(session, frame, - session->user_data); - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - return 0; -} - -static int find_stream_on_goaway_func(void *entry, void *ptr) { - nghttp2_close_stream_on_goaway_arg *arg; - nghttp2_stream *stream; - - arg = (nghttp2_close_stream_on_goaway_arg *)ptr; - stream = (nghttp2_stream *)entry; - - if (nghttp2_session_is_my_stream_id(arg->session, stream->stream_id)) { - if (arg->incoming) { - return 0; - } - } else if (!arg->incoming) { - return 0; - } - - if (stream->state != NGHTTP2_STREAM_IDLE && - (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) == 0 && - stream->stream_id > arg->last_stream_id) { - /* We are collecting streams to close because we cannot call - nghttp2_session_close_stream() inside nghttp2_map_each(). - Reuse closed_next member.. bad choice? */ - assert(stream->closed_next == NULL); - - if (arg->head) { - stream->closed_next = arg->head; - arg->head = stream; - } else { - arg->head = stream; - } - } - - return 0; -} - -/* Closes non-idle and non-closed streams whose stream ID > - last_stream_id. If incoming is nonzero, we are going to close - incoming streams. Otherwise, close outgoing streams. */ -static int session_close_stream_on_goaway(nghttp2_session *session, - int32_t last_stream_id, - int incoming) { - int rv; - nghttp2_stream *stream, *next_stream; - nghttp2_close_stream_on_goaway_arg arg = {session, NULL, last_stream_id, - incoming}; - - rv = nghttp2_map_each(&session->streams, find_stream_on_goaway_func, &arg); - assert(rv == 0); - - stream = arg.head; - while (stream) { - next_stream = stream->closed_next; - stream->closed_next = NULL; - rv = nghttp2_session_close_stream(session, stream->stream_id, - NGHTTP2_REFUSED_STREAM); - - /* stream may be deleted here */ - - stream = next_stream; - - if (nghttp2_is_fatal(rv)) { - /* Clean up closed_next member just in case */ - while (stream) { - next_stream = stream->closed_next; - stream->closed_next = NULL; - stream = next_stream; - } - return rv; - } - } - - return 0; -} - -static void session_reschedule_stream(nghttp2_session *session, - nghttp2_stream *stream) { - stream->last_writelen = stream->item->frame.hd.length; - - if (!session->server) { - return; - } - - session_sched_reschedule_stream(session, stream); -} - -static int session_update_stream_consumed_size(nghttp2_session *session, - nghttp2_stream *stream, - size_t delta_size); - -static int session_update_connection_consumed_size(nghttp2_session *session, - size_t delta_size); - -/* - * Called after a frame is sent. This function runs - * on_frame_send_callback and handles stream closure upon END_STREAM - * or RST_STREAM. This function does not reset session->aob. It is a - * responsibility of session_after_frame_sent2. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -static int session_after_frame_sent1(nghttp2_session *session) { - int rv; - nghttp2_active_outbound_item *aob = &session->aob; - nghttp2_outbound_item *item = aob->item; - nghttp2_bufs *framebufs = &aob->framebufs; - nghttp2_frame *frame; - nghttp2_stream *stream; - - frame = &item->frame; - - if (frame->hd.type == NGHTTP2_DATA) { - nghttp2_data_aux_data *aux_data; - - aux_data = &item->aux_data.data; - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - /* We update flow control window after a frame was completely - sent. This is possible because we choose payload length not to - exceed the window */ - session->remote_window_size -= (int32_t)frame->hd.length; - if (stream) { - stream->remote_window_size -= (int32_t)frame->hd.length; - } - - if (stream && aux_data->eof) { - session_detach_stream_item(session, stream); - - /* Call on_frame_send_callback after - nghttp2_stream_detach_item(), so that application can issue - nghttp2_submit_data2() in the callback. */ - if (session->callbacks.on_frame_send_callback) { - rv = session_call_on_frame_send(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - - if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { - int stream_closed; - - stream_closed = - (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR; - - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR); - - rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream); - if (nghttp2_is_fatal(rv)) { - return rv; - } - /* stream may be NULL if it was closed */ - if (stream_closed) { - stream = NULL; - } - } - return 0; - } - - if (session->callbacks.on_frame_send_callback) { - rv = session_call_on_frame_send(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - - return 0; - } - - /* non-DATA frame */ - - if (frame->hd.type == NGHTTP2_HEADERS || - frame->hd.type == NGHTTP2_PUSH_PROMISE) { - if (nghttp2_bufs_next_present(framebufs)) { - DEBUGF("send: CONTINUATION exists, just return\n"); - return 0; - } - } - rv = session_call_on_frame_send(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } - switch (frame->hd.type) { - case NGHTTP2_HEADERS: { - nghttp2_headers_aux_data *aux_data; - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream) { - return 0; - } - - switch (frame->headers.cat) { - case NGHTTP2_HCAT_REQUEST: { - stream->state = NGHTTP2_STREAM_OPENING; - if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR); - } - rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream); - if (nghttp2_is_fatal(rv)) { - return rv; - } - /* We assume aux_data is a pointer to nghttp2_headers_aux_data */ - aux_data = &item->aux_data.headers; - if (aux_data->dpw.data_prd.read_callback) { - /* nghttp2_submit_data_shared() makes a copy of - aux_data->dpw */ - rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM, - frame->hd.stream_id, &aux_data->dpw); - if (nghttp2_is_fatal(rv)) { - return rv; - } - /* TODO nghttp2_submit_data_shared() may fail if stream has - already DATA frame item. We might have to handle it - here. */ - } - return 0; - } - case NGHTTP2_HCAT_PUSH_RESPONSE: - stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH); - ++session->num_outgoing_streams; - /* Fall through */ - case NGHTTP2_HCAT_RESPONSE: - stream->state = NGHTTP2_STREAM_OPENED; - /* Fall through */ - case NGHTTP2_HCAT_HEADERS: - if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR); - } - rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream); - if (nghttp2_is_fatal(rv)) { - return rv; - } - /* We assume aux_data is a pointer to nghttp2_headers_aux_data */ - aux_data = &item->aux_data.headers; - if (aux_data->dpw.data_prd.read_callback) { - rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM, - frame->hd.stream_id, &aux_data->dpw); - if (nghttp2_is_fatal(rv)) { - return rv; - } - /* TODO nghttp2_submit_data_shared() may fail if stream has - already DATA frame item. We might have to handle it - here. */ - } - return 0; - default: - /* Unreachable */ - assert(0); - return 0; - } - } - case NGHTTP2_PRIORITY: - return 0; - case NGHTTP2_RST_STREAM: - rv = nghttp2_session_close_stream(session, frame->hd.stream_id, - frame->rst_stream.error_code); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return 0; - case NGHTTP2_GOAWAY: { - nghttp2_goaway_aux_data *aux_data; - - aux_data = &item->aux_data.goaway; - - if ((aux_data->flags & NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE) == 0) { - if (aux_data->flags & NGHTTP2_GOAWAY_AUX_TERM_ON_SEND) { - session->goaway_flags |= NGHTTP2_GOAWAY_TERM_SENT; - } - - session->goaway_flags |= NGHTTP2_GOAWAY_SENT; - - rv = session_close_stream_on_goaway(session, frame->goaway.last_stream_id, - 1); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - - return 0; - } - case NGHTTP2_WINDOW_UPDATE: - if (frame->hd.stream_id == 0) { - session->window_update_queued = 0; - if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - rv = session_update_connection_consumed_size(session, 0); - } else { - rv = nghttp2_session_update_recv_connection_window_size(session, 0); - } - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return 0; - } - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream) { - return 0; - } - - stream->window_update_queued = 0; - - /* We don't have to send WINDOW_UPDATE if END_STREAM from peer - is seen. */ - if (stream->shut_flags & NGHTTP2_SHUT_RD) { - return 0; - } - - if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - rv = session_update_stream_consumed_size(session, stream, 0); - } else { - rv = - nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1); - } - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return 0; - default: - return 0; - } -} - -/* - * Called after a frame is sent and session_after_frame_sent1. This - * function is responsible to reset session->aob. - */ -static void session_after_frame_sent2(nghttp2_session *session) { - nghttp2_active_outbound_item *aob = &session->aob; - nghttp2_outbound_item *item = aob->item; - nghttp2_bufs *framebufs = &aob->framebufs; - nghttp2_frame *frame; - nghttp2_mem *mem; - nghttp2_stream *stream; - nghttp2_data_aux_data *aux_data; - - mem = &session->mem; - frame = &item->frame; - - if (frame->hd.type != NGHTTP2_DATA) { - if (frame->hd.type == NGHTTP2_HEADERS || - frame->hd.type == NGHTTP2_PUSH_PROMISE) { - if (nghttp2_bufs_next_present(framebufs)) { - framebufs->cur = framebufs->cur->next; - - DEBUGF("send: next CONTINUATION frame, %zu bytes\n", - nghttp2_buf_len(&framebufs->cur->buf)); - - return; - } - } - - active_outbound_item_reset(&session->aob, mem); - - return; - } - - /* DATA frame */ - - aux_data = &item->aux_data.data; - - /* On EOF, we have already detached data. Please note that - application may issue nghttp2_submit_data2() in - on_frame_send_callback (call from session_after_frame_sent1), - which attach data to stream. We don't want to detach it. */ - if (aux_data->eof) { - active_outbound_item_reset(aob, mem); - - return; - } - - /* Reset no_copy here because next write may not use this. */ - aux_data->no_copy = 0; - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - - /* If session is closed or RST_STREAM was queued, we won't send - further data. */ - if (nghttp2_session_predicate_data_send(session, stream) != 0) { - if (stream) { - session_detach_stream_item(session, stream); - } - - active_outbound_item_reset(aob, mem); - - return; - } - - aob->item = NULL; - active_outbound_item_reset(&session->aob, mem); - - return; -} - -static int session_call_send_data(nghttp2_session *session, - nghttp2_outbound_item *item, - nghttp2_bufs *framebufs) { - int rv; - nghttp2_buf *buf; - size_t length; - nghttp2_frame *frame; - nghttp2_data_aux_data *aux_data; - - buf = &framebufs->cur->buf; - frame = &item->frame; - length = frame->hd.length - frame->data.padlen; - aux_data = &item->aux_data.data; - - rv = session->callbacks.send_data_callback(session, frame, buf->pos, length, - &aux_data->dpw.data_prd.source, - session->user_data); - - switch (rv) { - case 0: - case NGHTTP2_ERR_WOULDBLOCK: - case NGHTTP2_ERR_PAUSE: - case NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE: - return rv; - default: - return NGHTTP2_ERR_CALLBACK_FAILURE; - } -} - -static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session, - const uint8_t **data_ptr, - int fast_cb) { - int rv; - nghttp2_active_outbound_item *aob; - nghttp2_bufs *framebufs; - nghttp2_mem *mem; - - mem = &session->mem; - aob = &session->aob; - framebufs = &aob->framebufs; - - for (;;) { - switch (aob->state) { - case NGHTTP2_OB_POP_ITEM: { - nghttp2_outbound_item *item; - - item = nghttp2_session_pop_next_ob_item(session); - if (item == NULL) { - return 0; - } - - rv = session_prep_frame(session, item); - if (rv == NGHTTP2_ERR_PAUSE) { - return 0; - } - if (rv == NGHTTP2_ERR_DEFERRED) { - DEBUGF("send: frame transmission deferred\n"); - break; - } - if (rv < 0) { - int32_t opened_stream_id = 0; - uint32_t error_code = NGHTTP2_INTERNAL_ERROR; - int rv2 = 0; - - DEBUGF("send: frame preparation failed with %s\n", - nghttp2_strerror(rv)); - /* TODO If the error comes from compressor, the connection - must be closed. */ - if (item->frame.hd.type != NGHTTP2_DATA && - session->callbacks.on_frame_not_send_callback && is_non_fatal(rv)) { - nghttp2_frame *frame = &item->frame; - /* The library is responsible for the transmission of - WINDOW_UPDATE frame, so we don't call error callback for - it. */ - if (frame->hd.type != NGHTTP2_WINDOW_UPDATE && - session->callbacks.on_frame_not_send_callback( - session, frame, rv, session->user_data) != 0) { - nghttp2_outbound_item_free(item, mem); - nghttp2_mem_free(mem, item); - - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - /* We have to close stream opened by failed request HEADERS - or PUSH_PROMISE. */ - switch (item->frame.hd.type) { - case NGHTTP2_HEADERS: - if (item->frame.headers.cat == NGHTTP2_HCAT_REQUEST) { - opened_stream_id = item->frame.hd.stream_id; - if (item->aux_data.headers.canceled) { - error_code = item->aux_data.headers.error_code; - } else { - /* Set error_code to REFUSED_STREAM so that application - can send request again. */ - error_code = NGHTTP2_REFUSED_STREAM; - } - } - break; - case NGHTTP2_PUSH_PROMISE: - opened_stream_id = item->frame.push_promise.promised_stream_id; - break; - } - if (opened_stream_id) { - /* careful not to override rv */ - rv2 = - nghttp2_session_close_stream(session, opened_stream_id, error_code); - } - - nghttp2_outbound_item_free(item, mem); - nghttp2_mem_free(mem, item); - active_outbound_item_reset(aob, mem); - - if (nghttp2_is_fatal(rv2)) { - return rv2; - } - - if (rv == NGHTTP2_ERR_HEADER_COMP) { - /* If header compression error occurred, should terminate - connection. */ - rv = - nghttp2_session_terminate_session(session, NGHTTP2_INTERNAL_ERROR); - } - if (nghttp2_is_fatal(rv)) { - return rv; - } - break; - } - - aob->item = item; - - nghttp2_bufs_rewind(framebufs); - - if (item->frame.hd.type != NGHTTP2_DATA) { - nghttp2_frame *frame; - - frame = &item->frame; - - DEBUGF("send: next frame: payloadlen=%zu, type=%u, flags=0x%02x, " - "stream_id=%d\n", - frame->hd.length, frame->hd.type, frame->hd.flags, - frame->hd.stream_id); - - rv = session_call_before_frame_send(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (rv == NGHTTP2_ERR_CANCEL) { - int32_t opened_stream_id = 0; - uint32_t error_code = NGHTTP2_INTERNAL_ERROR; - - if (session->callbacks.on_frame_not_send_callback) { - if (session->callbacks.on_frame_not_send_callback( - session, frame, rv, session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - - /* We have to close stream opened by canceled request - HEADERS or PUSH_PROMISE. */ - switch (item->frame.hd.type) { - case NGHTTP2_HEADERS: - if (item->frame.headers.cat == NGHTTP2_HCAT_REQUEST) { - opened_stream_id = item->frame.hd.stream_id; - /* We don't have to check - item->aux_data.headers.canceled since it has already - been checked. */ - /* Set error_code to REFUSED_STREAM so that application - can send request again. */ - error_code = NGHTTP2_REFUSED_STREAM; - } - break; - case NGHTTP2_PUSH_PROMISE: - opened_stream_id = item->frame.push_promise.promised_stream_id; - break; - } - if (opened_stream_id) { - /* careful not to override rv */ - int rv2; - rv2 = nghttp2_session_close_stream(session, opened_stream_id, - error_code); - - if (nghttp2_is_fatal(rv2)) { - return rv2; - } - } - - active_outbound_item_reset(aob, mem); - - break; - } - } else { - DEBUGF("send: next frame: DATA\n"); - - if (item->aux_data.data.no_copy) { - aob->state = NGHTTP2_OB_SEND_NO_COPY; - break; - } - } - - DEBUGF("send: start transmitting frame type=%u, length=%td\n", - framebufs->cur->buf.pos[3], - framebufs->cur->buf.last - framebufs->cur->buf.pos); - - aob->state = NGHTTP2_OB_SEND_DATA; - - break; - } - case NGHTTP2_OB_SEND_DATA: { - size_t datalen; - nghttp2_buf *buf; - - buf = &framebufs->cur->buf; - - if (buf->pos == buf->last) { - DEBUGF("send: end transmission of a frame\n"); - - /* Frame has completely sent */ - if (fast_cb) { - session_after_frame_sent2(session); - } else { - rv = session_after_frame_sent1(session); - if (rv < 0) { - /* FATAL */ - assert(nghttp2_is_fatal(rv)); - return rv; - } - session_after_frame_sent2(session); - } - /* We have already adjusted the next state */ - break; - } - - *data_ptr = buf->pos; - datalen = nghttp2_buf_len(buf); - - /* We increment the offset here. If send_callback does not send - everything, we will adjust it. */ - buf->pos += datalen; - - return (nghttp2_ssize)datalen; - } - case NGHTTP2_OB_SEND_NO_COPY: { - nghttp2_stream *stream; - nghttp2_frame *frame; - int pause; - - DEBUGF("send: no copy DATA\n"); - - frame = &aob->item->frame; - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (stream == NULL) { - DEBUGF("send: no copy DATA cancelled because stream was closed\n"); - - active_outbound_item_reset(aob, mem); - - break; - } - - rv = session_call_send_data(session, aob->item, framebufs); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - session_detach_stream_item(session, stream); - - rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id, - NGHTTP2_INTERNAL_ERROR); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - active_outbound_item_reset(aob, mem); - - break; - } - - if (rv == NGHTTP2_ERR_WOULDBLOCK) { - return 0; - } - - pause = (rv == NGHTTP2_ERR_PAUSE); - - rv = session_after_frame_sent1(session); - if (rv < 0) { - assert(nghttp2_is_fatal(rv)); - return rv; - } - session_after_frame_sent2(session); - - /* We have already adjusted the next state */ - - if (pause) { - return 0; - } - - break; - } - case NGHTTP2_OB_SEND_CLIENT_MAGIC: { - size_t datalen; - nghttp2_buf *buf; - - buf = &framebufs->cur->buf; - - if (buf->pos == buf->last) { - DEBUGF("send: end transmission of client magic\n"); - active_outbound_item_reset(aob, mem); - break; - } - - *data_ptr = buf->pos; - datalen = nghttp2_buf_len(buf); - - buf->pos += datalen; - - return (nghttp2_ssize)datalen; - } - } - } -} - -ssize_t nghttp2_session_mem_send(nghttp2_session *session, - const uint8_t **data_ptr) { - return (ssize_t)nghttp2_session_mem_send2(session, data_ptr); -} - -nghttp2_ssize nghttp2_session_mem_send2(nghttp2_session *session, - const uint8_t **data_ptr) { - int rv; - nghttp2_ssize len; - - *data_ptr = NULL; - - len = nghttp2_session_mem_send_internal(session, data_ptr, 1); - if (len <= 0) { - return len; - } - - if (session->aob.item) { - /* We have to call session_after_frame_sent1 here to handle stream - closure upon transmission of frames. Otherwise, END_STREAM may - be reached to client before we call nghttp2_session_mem_send - again and we may get exceeding number of incoming streams. */ - rv = session_after_frame_sent1(session); - if (rv < 0) { - assert(nghttp2_is_fatal(rv)); - return (nghttp2_ssize)rv; - } - } - - return len; -} - -int nghttp2_session_send(nghttp2_session *session) { - const uint8_t *data = NULL; - nghttp2_ssize datalen; - nghttp2_ssize sentlen; - nghttp2_bufs *framebufs; - - framebufs = &session->aob.framebufs; - - for (;;) { - datalen = nghttp2_session_mem_send_internal(session, &data, 0); - if (datalen <= 0) { - return (int)datalen; - } - if (session->callbacks.send_callback2) { - sentlen = session->callbacks.send_callback2( - session, data, (size_t)datalen, 0, session->user_data); - } else { - sentlen = (nghttp2_ssize)session->callbacks.send_callback( - session, data, (size_t)datalen, 0, session->user_data); - } - if (sentlen < 0) { - if (sentlen == NGHTTP2_ERR_WOULDBLOCK) { - /* Transmission canceled. Rewind the offset */ - framebufs->cur->buf.pos -= datalen; - - return 0; - } - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - /* Rewind the offset to the amount of unsent bytes */ - framebufs->cur->buf.pos -= datalen - sentlen; - } -} - -static nghttp2_ssize session_recv(nghttp2_session *session, uint8_t *buf, - size_t len) { - nghttp2_ssize rv; - - if (session->callbacks.recv_callback2) { - rv = session->callbacks.recv_callback2(session, buf, len, 0, - session->user_data); - } else { - rv = (nghttp2_ssize)session->callbacks.recv_callback(session, buf, len, 0, - session->user_data); - } - if (rv > 0) { - if ((size_t)rv > len) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } else if (rv < 0 && rv != NGHTTP2_ERR_WOULDBLOCK && rv != NGHTTP2_ERR_EOF) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - return rv; -} - -static int session_call_on_begin_frame(nghttp2_session *session, - const nghttp2_frame_hd *hd) { - int rv; - - if (session->callbacks.on_begin_frame_callback) { - rv = session->callbacks.on_begin_frame_callback(session, hd, - session->user_data); - - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - - return 0; -} - -static int session_call_on_frame_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - if (session->callbacks.on_frame_recv_callback) { - rv = session->callbacks.on_frame_recv_callback(session, frame, - session->user_data); - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - return 0; -} - -static int session_call_on_begin_headers(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - DEBUGF("recv: call on_begin_headers callback stream_id=%d\n", - frame->hd.stream_id); - if (session->callbacks.on_begin_headers_callback) { - rv = session->callbacks.on_begin_headers_callback(session, frame, - session->user_data); - if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - return rv; - } - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - return 0; -} - -static int session_call_on_header(nghttp2_session *session, - const nghttp2_frame *frame, - const nghttp2_hd_nv *nv) { - int rv = 0; - if (session->callbacks.on_header_callback2) { - rv = session->callbacks.on_header_callback2( - session, frame, nv->name, nv->value, nv->flags, session->user_data); - } else if (session->callbacks.on_header_callback) { - rv = session->callbacks.on_header_callback( - session, frame, nv->name->base, nv->name->len, nv->value->base, - nv->value->len, nv->flags, session->user_data); - } - - if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - return rv; - } - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int session_call_on_invalid_header(nghttp2_session *session, - const nghttp2_frame *frame, - const nghttp2_hd_nv *nv) { - int rv; - if (session->callbacks.on_invalid_header_callback2) { - rv = session->callbacks.on_invalid_header_callback2( - session, frame, nv->name, nv->value, nv->flags, session->user_data); - } else if (session->callbacks.on_invalid_header_callback) { - rv = session->callbacks.on_invalid_header_callback( - session, frame, nv->name->base, nv->name->len, nv->value->base, - nv->value->len, nv->flags, session->user_data); - } else { - /* If both callbacks are not set, the invalid field nv is - ignored. */ - return 0; - } - - if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - return rv; - } - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - return 0; -} - -static int -session_call_on_extension_chunk_recv_callback(nghttp2_session *session, - const uint8_t *data, size_t len) { - int rv; - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - if (session->callbacks.on_extension_chunk_recv_callback) { - rv = session->callbacks.on_extension_chunk_recv_callback( - session, &frame->hd, data, len, session->user_data); - if (rv == NGHTTP2_ERR_CANCEL) { - return rv; - } - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - - return 0; -} - -static int session_call_unpack_extension_callback(nghttp2_session *session) { - int rv; - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - void *payload = NULL; - - rv = session->callbacks.unpack_extension_callback( - session, &payload, &frame->hd, session->user_data); - if (rv == NGHTTP2_ERR_CANCEL) { - return rv; - } - if (rv != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - frame->ext.payload = payload; - - return 0; -} - -/* - * Handles frame size error. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -static int session_handle_frame_size_error(nghttp2_session *session) { - /* TODO Currently no callback is called for this error, because we - call this callback before reading any payload */ - return nghttp2_session_terminate_session(session, NGHTTP2_FRAME_SIZE_ERROR); -} - -static uint32_t get_error_code_from_lib_error_code(int lib_error_code) { - switch (lib_error_code) { - case NGHTTP2_ERR_STREAM_CLOSED: - return NGHTTP2_STREAM_CLOSED; - case NGHTTP2_ERR_HEADER_COMP: - return NGHTTP2_COMPRESSION_ERROR; - case NGHTTP2_ERR_FRAME_SIZE_ERROR: - return NGHTTP2_FRAME_SIZE_ERROR; - case NGHTTP2_ERR_FLOW_CONTROL: - return NGHTTP2_FLOW_CONTROL_ERROR; - case NGHTTP2_ERR_REFUSED_STREAM: - return NGHTTP2_REFUSED_STREAM; - case NGHTTP2_ERR_PROTO: - case NGHTTP2_ERR_HTTP_HEADER: - case NGHTTP2_ERR_HTTP_MESSAGING: - return NGHTTP2_PROTOCOL_ERROR; - case NGHTTP2_ERR_INTERNAL: - return NGHTTP2_INTERNAL_ERROR; - case NGHTTP2_ERR_PUSH_CANCEL: - return NGHTTP2_CANCEL; - default: - return NGHTTP2_INTERNAL_ERROR; - } -} - -/* - * Calls on_invalid_frame_recv_callback if it is set to |session|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_CALLBACK_FAILURE - * User defined callback function fails. - */ -static int session_call_on_invalid_frame_recv_callback(nghttp2_session *session, - nghttp2_frame *frame, - int lib_error_code) { - if (session->callbacks.on_invalid_frame_recv_callback) { - if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - return 0; -} - -static int session_update_glitch_ratelim(nghttp2_session *session) { - if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) { - return 0; - } - - nghttp2_ratelim_update(&session->glitch_ratelim, nghttp2_time_now_sec()); - - if (nghttp2_ratelim_drain(&session->glitch_ratelim, 1) == 0) { - return 0; - } - - return nghttp2_session_terminate_session(session, NGHTTP2_ENHANCE_YOUR_CALM); -} - -static int session_handle_invalid_stream2(nghttp2_session *session, - int32_t stream_id, - nghttp2_frame *frame, - int lib_error_code) { - int rv; - - rv = nghttp2_session_add_rst_stream( - session, stream_id, get_error_code_from_lib_error_code(lib_error_code)); - if (rv != 0) { - return rv; - } - if (frame && session->callbacks.on_invalid_frame_recv_callback) { - if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - return 0; -} - -static int session_handle_invalid_stream(nghttp2_session *session, - nghttp2_frame *frame, - int lib_error_code) { - return session_handle_invalid_stream2(session, frame->hd.stream_id, frame, - lib_error_code); -} - -static int session_inflate_handle_invalid_stream(nghttp2_session *session, - nghttp2_frame *frame, - int lib_error_code) { - int rv; - rv = session_handle_invalid_stream(session, frame, lib_error_code); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return NGHTTP2_ERR_IGN_HEADER_BLOCK; -} - -/* - * Handles invalid frame which causes connection error. - */ -static int session_handle_invalid_connection(nghttp2_session *session, - nghttp2_frame *frame, - int lib_error_code, - const char *reason) { - if (session->callbacks.on_invalid_frame_recv_callback) { - if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - return nghttp2_session_terminate_session_with_reason( - session, get_error_code_from_lib_error_code(lib_error_code), reason); -} - -static int session_inflate_handle_invalid_connection(nghttp2_session *session, - nghttp2_frame *frame, - int lib_error_code, - const char *reason) { - int rv; - rv = - session_handle_invalid_connection(session, frame, lib_error_code, reason); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return NGHTTP2_ERR_IGN_HEADER_BLOCK; -} - -/* - * Inflates header block in the memory pointed by |in| with |inlen| - * bytes. If this function returns NGHTTP2_ERR_PAUSE, the caller must - * call this function again, until it returns 0 or one of negative - * error code. If |call_header_cb| is zero, the on_header_callback - * are not invoked and the function never return NGHTTP2_ERR_PAUSE. If - * the given |in| is the last chunk of header block, the |final| must - * be nonzero. If header block is successfully processed (which is - * indicated by the return value 0, NGHTTP2_ERR_PAUSE or - * NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE), the number of processed - * input bytes is assigned to the |*readlen_ptr|. - * - * This function return 0 if it succeeds, or one of the negative error - * codes: - * - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - * NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE - * The callback returns this error code, indicating that this - * stream should be RST_STREAMed. - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_PAUSE - * The callback function returned NGHTTP2_ERR_PAUSE - * NGHTTP2_ERR_HEADER_COMP - * Header decompression failed - */ -static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, - size_t *readlen_ptr, uint8_t *in, size_t inlen, - int final, int call_header_cb) { - nghttp2_ssize proclen; - int rv; - int inflate_flags; - nghttp2_hd_nv nv; - nghttp2_stream *stream; - nghttp2_stream *subject_stream; - int trailer = 0; - - *readlen_ptr = 0; - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - - if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { - subject_stream = nghttp2_session_get_stream( - session, frame->push_promise.promised_stream_id); - } else { - subject_stream = stream; - trailer = session_trailer_headers(session, stream, frame); - } - - DEBUGF("recv: decoding header block %zu bytes\n", inlen); - for (;;) { - inflate_flags = 0; - proclen = nghttp2_hd_inflate_hd_nv(&session->hd_inflater, &nv, - &inflate_flags, in, inlen, final); - if (nghttp2_is_fatal((int)proclen)) { - return (int)proclen; - } - if (proclen < 0) { - if (session->iframe.state == NGHTTP2_IB_READ_HEADER_BLOCK) { - if (subject_stream && subject_stream->state != NGHTTP2_STREAM_CLOSING) { - /* Adding RST_STREAM here is very important. It prevents - from invoking subsequent callbacks for the same stream - ID. */ - rv = nghttp2_session_add_rst_stream( - session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - } - rv = - nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return NGHTTP2_ERR_HEADER_COMP; - } - in += proclen; - inlen -= (size_t)proclen; - *readlen_ptr += (size_t)proclen; - - DEBUGF("recv: proclen=%td\n", proclen); - - if (call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) { - rv = 0; - if (subject_stream) { - if (session_enforce_http_messaging(session)) { - rv = nghttp2_http_on_header(session, subject_stream, frame, &nv, - trailer); - - if (rv == NGHTTP2_ERR_IGN_HTTP_HEADER) { - /* Don't overwrite rv here */ - int rv2; - - rv2 = session_call_on_invalid_header(session, frame, &nv); - if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - rv = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Invalid HTTP header field was received: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - rv = session_handle_invalid_stream2( - session, subject_stream->stream_id, frame, - NGHTTP2_ERR_HTTP_HEADER); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } else { - if (rv2 != 0) { - return rv2; - } - - /* header is ignored */ - DEBUGF("recv: HTTP ignored: type=%u, id=%d, header %.*s: %.*s\n", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - rv2 = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Ignoring received invalid HTTP header field: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - if (nghttp2_is_fatal(rv2)) { - return rv2; - } - } - } - - if (rv == NGHTTP2_ERR_HTTP_HEADER) { - DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - rv = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Invalid HTTP header field was received: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return nghttp2_session_terminate_session(session, - NGHTTP2_PROTOCOL_ERROR); - } - } - if (rv == 0) { - rv = session_call_on_header(session, frame, &nv); - /* This handles NGHTTP2_ERR_PAUSE and - NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE as well */ - if (rv != 0) { - return rv; - } - } - } - } - if (inflate_flags & NGHTTP2_HD_INFLATE_FINAL) { - nghttp2_hd_inflate_end_headers(&session->hd_inflater); - break; - } - if ((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && inlen == 0) { - break; - } - } - return 0; -} - -/* - * Call this function when HEADERS frame was completely received. - * - * This function returns 0 if it succeeds, or one of negative error - * codes: - * - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -static int session_end_stream_headers_received(nghttp2_session *session, - nghttp2_frame *frame, - nghttp2_stream *stream) { - int rv; - - assert(frame->hd.type == NGHTTP2_HEADERS); - - if (session->server && session_enforce_http_messaging(session) && - frame->headers.cat == NGHTTP2_HCAT_REQUEST && - !(stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) && - (stream->http_flags & NGHTTP2_HTTP_FLAG_PRIORITY)) { - rv = session_update_stream_priority(session, stream, stream->http_extpri); - if (rv != 0) { - assert(nghttp2_is_fatal(rv)); - return rv; - } - } - - if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { - return 0; - } - - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return 0; -} - -static int session_after_header_block_received(nghttp2_session *session) { - int rv = 0; - nghttp2_frame *frame = &session->iframe.frame; - nghttp2_stream *stream; - - /* We don't call on_frame_recv_callback if stream has been closed - already or being closed. */ - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream || stream->state == NGHTTP2_STREAM_CLOSING) { - return 0; - } - - if (session_enforce_http_messaging(session)) { - if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { - nghttp2_stream *subject_stream; - - subject_stream = nghttp2_session_get_stream( - session, frame->push_promise.promised_stream_id); - if (subject_stream) { - rv = nghttp2_http_on_request_headers(subject_stream, frame); - } - } else { - assert(frame->hd.type == NGHTTP2_HEADERS); - switch (frame->headers.cat) { - case NGHTTP2_HCAT_REQUEST: - rv = nghttp2_http_on_request_headers(stream, frame); - break; - case NGHTTP2_HCAT_RESPONSE: - case NGHTTP2_HCAT_PUSH_RESPONSE: - rv = nghttp2_http_on_response_headers(stream); - break; - case NGHTTP2_HCAT_HEADERS: - if (stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) { - assert(!session->server); - rv = nghttp2_http_on_response_headers(stream); - } else { - rv = nghttp2_http_on_trailer_headers(stream, frame); - } - break; - default: - assert(0); - } - if (rv == 0 && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { - rv = nghttp2_http_on_remote_end_stream(stream); - } - } - if (rv != 0) { - return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); - } - } - - rv = session_call_on_frame_received(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (frame->hd.type != NGHTTP2_HEADERS) { - return 0; - } - - return session_end_stream_headers_received(session, frame, stream); -} - -int nghttp2_session_on_request_headers_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv = 0; - nghttp2_stream *stream; - if (frame->hd.stream_id == 0) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: stream_id == 0"); - } - - /* If client receives idle stream from server, it is invalid - regardless stream ID is even or odd. This is because client is - not expected to receive request from server. */ - if (!session->server) { - if (session_detect_idle_stream(session, frame->hd.stream_id)) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: client received request"); - } - - return NGHTTP2_ERR_IGN_HEADER_BLOCK; - } - - assert(session->server); - - if (!session_is_new_peer_stream_id(session, frame->hd.stream_id)) { - if (frame->hd.stream_id == 0 || - nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: invalid stream_id"); - } - - /* RFC 7540 says if an endpoint receives a HEADERS with invalid - * stream ID (e.g, numerically smaller than previous), it MUST - * issue connection error with error code PROTOCOL_ERROR. It is a - * bit hard to detect this, since we cannot remember all streams - * we observed so far. - * - * You might imagine this is really easy. But no. HTTP/2 is - * asynchronous protocol, and usually client and server do not - * share the complete picture of open/closed stream status. For - * example, after server sends RST_STREAM for a stream, client may - * send trailer HEADERS for that stream. If naive server detects - * that, and issued connection error, then it is a bug of server - * implementation since client is not wrong if it did not get - * RST_STREAM when it issued trailer HEADERS. - * - * At the moment, we are very conservative here. We only use - * connection error if stream ID refers idle stream, or we are - * sure that stream is half-closed(remote) or closed. Otherwise - * we just ignore HEADERS for now. - */ - stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); - if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); - } - - return NGHTTP2_ERR_IGN_HEADER_BLOCK; - } - session->last_recv_stream_id = frame->hd.stream_id; - - if (session_is_incoming_concurrent_streams_max(session)) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: max concurrent streams exceeded"); - } - - if (!session_allow_incoming_new_stream(session)) { - /* We just ignore stream after GOAWAY was sent */ - return NGHTTP2_ERR_IGN_HEADER_BLOCK; - } - - if (frame->headers.pri_spec.stream_id == frame->hd.stream_id) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: depend on itself"); - } - - if (session_is_incoming_concurrent_streams_pending_max(session)) { - return session_inflate_handle_invalid_stream(session, frame, - NGHTTP2_ERR_REFUSED_STREAM); - } - - stream = nghttp2_session_open_stream(session, frame->hd.stream_id, - NGHTTP2_STREAM_FLAG_NONE, - NGHTTP2_STREAM_OPENING, NULL); - if (!stream) { - return NGHTTP2_ERR_NOMEM; - } - - session->last_proc_stream_id = session->last_recv_stream_id; - - rv = session_call_on_begin_headers(session, frame); - if (rv != 0) { - return rv; - } - return 0; -} - -int nghttp2_session_on_response_headers_received(nghttp2_session *session, - nghttp2_frame *frame, - nghttp2_stream *stream) { - int rv; - /* This function is only called if stream->state == - NGHTTP2_STREAM_OPENING and stream_id is local side initiated. */ - assert(stream->state == NGHTTP2_STREAM_OPENING && - nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)); - if (frame->hd.stream_id == 0) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "response HEADERS: stream_id == 0"); - } - if (stream->shut_flags & NGHTTP2_SHUT_RD) { - /* half closed (remote): from the spec: - - If an endpoint receives additional frames for a stream that is - in this state it MUST respond with a stream error (Section - 5.4.2) of type STREAM_CLOSED. - - We go further, and make it connection error. - */ - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); - } - stream->state = NGHTTP2_STREAM_OPENED; - rv = session_call_on_begin_headers(session, frame); - if (rv != 0) { - return rv; - } - return 0; -} - -int nghttp2_session_on_push_response_headers_received(nghttp2_session *session, - nghttp2_frame *frame, - nghttp2_stream *stream) { - int rv = 0; - assert(stream->state == NGHTTP2_STREAM_RESERVED); - if (frame->hd.stream_id == 0) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "push response HEADERS: stream_id == 0"); - } - - if (session->server) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "HEADERS: no HEADERS allowed from client in reserved state"); - } - - if (session_is_incoming_concurrent_streams_max(session)) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "push response HEADERS: max concurrent streams exceeded"); - } - - if (!session_allow_incoming_new_stream(session)) { - /* We don't accept new stream after GOAWAY was sent. */ - return NGHTTP2_ERR_IGN_HEADER_BLOCK; - } - - if (session_is_incoming_concurrent_streams_pending_max(session)) { - return session_inflate_handle_invalid_stream(session, frame, - NGHTTP2_ERR_REFUSED_STREAM); - } - - nghttp2_stream_promise_fulfilled(stream); - if (!nghttp2_session_is_my_stream_id(session, stream->stream_id)) { - --session->num_incoming_reserved_streams; - } - ++session->num_incoming_streams; - rv = session_call_on_begin_headers(session, frame); - if (rv != 0) { - return rv; - } - return 0; -} - -int nghttp2_session_on_headers_received(nghttp2_session *session, - nghttp2_frame *frame, - nghttp2_stream *stream) { - int rv = 0; - if (frame->hd.stream_id == 0) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0"); - } - if ((stream->shut_flags & NGHTTP2_SHUT_RD)) { - /* half closed (remote): from the spec: - - If an endpoint receives additional frames for a stream that is - in this state it MUST respond with a stream error (Section - 5.4.2) of type STREAM_CLOSED. - - we go further, and make it connection error. - */ - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); - } - if (nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { - if (stream->state == NGHTTP2_STREAM_OPENED) { - rv = session_call_on_begin_headers(session, frame); - if (rv != 0) { - return rv; - } - return 0; - } - - return NGHTTP2_ERR_IGN_HEADER_BLOCK; - } - /* If this is remote peer initiated stream, it is OK unless it - has sent END_STREAM frame already. But if stream is in - NGHTTP2_STREAM_CLOSING, we discard the frame. This is a race - condition. */ - if (stream->state != NGHTTP2_STREAM_CLOSING) { - rv = session_call_on_begin_headers(session, frame); - if (rv != 0) { - return rv; - } - return 0; - } - return NGHTTP2_ERR_IGN_HEADER_BLOCK; -} - -static int session_process_headers_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - nghttp2_stream *stream; - - nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos); - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream) { - frame->headers.cat = NGHTTP2_HCAT_REQUEST; - return nghttp2_session_on_request_headers_received(session, frame); - } - - if (stream->state == NGHTTP2_STREAM_RESERVED) { - frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE; - return nghttp2_session_on_push_response_headers_received(session, frame, - stream); - } - - if (stream->state == NGHTTP2_STREAM_OPENING && - nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { - frame->headers.cat = NGHTTP2_HCAT_RESPONSE; - return nghttp2_session_on_response_headers_received(session, frame, stream); - } - - frame->headers.cat = NGHTTP2_HCAT_HEADERS; - return nghttp2_session_on_headers_received(session, frame, stream); -} - -static int session_update_stream_reset_ratelim(nghttp2_session *session) { - if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) { - return 0; - } - - nghttp2_ratelim_update(&session->stream_reset_ratelim, - nghttp2_time_now_sec()); - - if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) { - return 0; - } - - return nghttp2_session_add_goaway(session, session->last_recv_stream_id, - NGHTTP2_INTERNAL_ERROR, NULL, 0, - NGHTTP2_GOAWAY_AUX_NONE); -} - -int nghttp2_session_on_rst_stream_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - nghttp2_stream *stream; - if (frame->hd.stream_id == 0) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "RST_STREAM: stream_id == 0"); - } - - if (session_detect_idle_stream(session, frame->hd.stream_id)) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "RST_STREAM: stream in idle"); - } - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (stream) { - /* We may use stream->shut_flags for strict error checking. */ - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - } - - rv = session_call_on_frame_received(session, frame); - if (rv != 0) { - return rv; - } - rv = nghttp2_session_close_stream(session, frame->hd.stream_id, - frame->rst_stream.error_code); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return session_update_stream_reset_ratelim(session); -} - -static int session_process_rst_stream_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - nghttp2_frame_unpack_rst_stream_payload(&frame->rst_stream, iframe->sbuf.pos); - - return nghttp2_session_on_rst_stream_received(session, frame); -} - -static int update_remote_initial_window_size_func(void *entry, void *ptr) { - int rv; - nghttp2_update_window_size_arg *arg; - nghttp2_stream *stream; - - arg = (nghttp2_update_window_size_arg *)ptr; - stream = (nghttp2_stream *)entry; - - rv = nghttp2_stream_update_remote_initial_window_size( - stream, arg->new_window_size, arg->old_window_size); - if (rv != 0) { - return NGHTTP2_ERR_FLOW_CONTROL; - } - - /* If window size gets positive, push deferred DATA frame to - outbound queue. */ - if (stream->remote_window_size > 0 && - nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = session_resume_deferred_stream_item( - arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - return 0; -} - -/* - * Updates the remote initial window size of all active streams. If - * error occurs, all streams may not be updated. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FLOW_CONTROL - * Window size gets out of range. - */ -static int -session_update_remote_initial_window_size(nghttp2_session *session, - int32_t new_initial_window_size) { - nghttp2_update_window_size_arg arg; - - arg.session = session; - arg.new_window_size = new_initial_window_size; - arg.old_window_size = (int32_t)session->remote_settings.initial_window_size; - - return nghttp2_map_each(&session->streams, - update_remote_initial_window_size_func, &arg); -} - -static int update_local_initial_window_size_func(void *entry, void *ptr) { - int rv; - nghttp2_update_window_size_arg *arg; - nghttp2_stream *stream; - arg = (nghttp2_update_window_size_arg *)ptr; - stream = (nghttp2_stream *)entry; - rv = nghttp2_stream_update_local_initial_window_size( - stream, arg->new_window_size, arg->old_window_size); - if (rv != 0) { - return NGHTTP2_ERR_FLOW_CONTROL; - } - - if (stream->window_update_queued) { - return 0; - } - - if (arg->session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - return session_update_stream_consumed_size(arg->session, stream, 0); - } - - if (nghttp2_should_send_window_update(stream->local_window_size, - stream->recv_window_size)) { - rv = nghttp2_session_add_window_update(arg->session, NGHTTP2_FLAG_NONE, - stream->stream_id, - stream->recv_window_size); - if (rv != 0) { - return rv; - } - - stream->recv_window_size = 0; - } - return 0; -} - -/* - * Updates the local initial window size of all active streams. If - * error occurs, all streams may not be updated. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FLOW_CONTROL - * Window size gets out of range. - */ -static int -session_update_local_initial_window_size(nghttp2_session *session, - int32_t new_initial_window_size, - int32_t old_initial_window_size) { - nghttp2_update_window_size_arg arg; - arg.session = session; - arg.new_window_size = new_initial_window_size; - arg.old_window_size = old_initial_window_size; - return nghttp2_map_each(&session->streams, - update_local_initial_window_size_func, &arg); -} - -/* - * Apply SETTINGS values |iv| having |niv| elements to the local - * settings. We assumes that all values in |iv| is correct, since we - * validated them in nghttp2_session_add_settings() already. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_HEADER_COMP - * The header table size is out of range - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_session_update_local_settings(nghttp2_session *session, - nghttp2_settings_entry *iv, - size_t niv) { - int rv; - size_t i; - int32_t new_initial_window_size = -1; - uint32_t header_table_size = 0; - uint32_t min_header_table_size = UINT32_MAX; - uint8_t header_table_size_seen = 0; - /* For NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, use the value last - seen. For NGHTTP2_SETTINGS_HEADER_TABLE_SIZE, use both minimum - value and last seen value. */ - for (i = 0; i < niv; ++i) { - switch (iv[i].settings_id) { - case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: - header_table_size_seen = 1; - header_table_size = iv[i].value; - min_header_table_size = - nghttp2_min_uint32(min_header_table_size, iv[i].value); - break; - case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - new_initial_window_size = (int32_t)iv[i].value; - break; - } - } - if (header_table_size_seen) { - if (min_header_table_size < header_table_size) { - rv = nghttp2_hd_inflate_change_table_size(&session->hd_inflater, - min_header_table_size); - if (rv != 0) { - return rv; - } - } - - rv = nghttp2_hd_inflate_change_table_size(&session->hd_inflater, - header_table_size); - if (rv != 0) { - return rv; - } - } - if (new_initial_window_size != -1) { - rv = session_update_local_initial_window_size( - session, new_initial_window_size, - (int32_t)session->local_settings.initial_window_size); - if (rv != 0) { - return rv; - } - } - - for (i = 0; i < niv; ++i) { - switch (iv[i].settings_id) { - case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: - session->local_settings.header_table_size = iv[i].value; - break; - case NGHTTP2_SETTINGS_ENABLE_PUSH: - session->local_settings.enable_push = iv[i].value; - break; - case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: - session->local_settings.max_concurrent_streams = iv[i].value; - break; - case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - session->local_settings.initial_window_size = iv[i].value; - break; - case NGHTTP2_SETTINGS_MAX_FRAME_SIZE: - session->local_settings.max_frame_size = iv[i].value; - break; - case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: - session->local_settings.max_header_list_size = iv[i].value; - break; - case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL: - session->local_settings.enable_connect_protocol = iv[i].value; - break; - case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES: - session->local_settings.no_rfc7540_priorities = iv[i].value; - break; - } - } - - return 0; -} - -int nghttp2_session_on_settings_received(nghttp2_session *session, - nghttp2_frame *frame, int noack) { - int rv; - size_t i; - nghttp2_mem *mem; - nghttp2_inflight_settings *settings; - - mem = &session->mem; - - if (frame->hd.stream_id != 0) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: stream_id != 0"); - } - if (frame->hd.flags & NGHTTP2_FLAG_ACK) { - if (frame->settings.niv != 0) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FRAME_SIZE_ERROR, - "SETTINGS: ACK and payload != 0"); - } - - settings = session->inflight_settings_head; - - if (!settings) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "SETTINGS: unexpected ACK"); - } - - rv = nghttp2_session_update_local_settings(session, settings->iv, - settings->niv); - - session->inflight_settings_head = settings->next; - - inflight_settings_del(settings, mem); - - if (rv != 0) { - if (nghttp2_is_fatal(rv)) { - return rv; - } - return session_handle_invalid_connection(session, frame, rv, NULL); - } - return session_call_on_frame_received(session, frame); - } - - if (!session->remote_settings_received) { - session->remote_settings.max_concurrent_streams = - NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; - session->remote_settings_received = 1; - } - - for (i = 0; i < frame->settings.niv; ++i) { - nghttp2_settings_entry *entry = &frame->settings.iv[i]; - - switch (entry->settings_id) { - case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: - - rv = nghttp2_hd_deflate_change_table_size(&session->hd_deflater, - entry->value); - if (rv != 0) { - if (nghttp2_is_fatal(rv)) { - return rv; - } else { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_HEADER_COMP, NULL); - } - } - - session->remote_settings.header_table_size = entry->value; - - break; - case NGHTTP2_SETTINGS_ENABLE_PUSH: - - if (entry->value != 0 && entry->value != 1) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_ENBLE_PUSH"); - } - - if (!session->server && entry->value != 0) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: server attempted to enable push"); - } - - session->remote_settings.enable_push = entry->value; - - break; - case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: - - session->remote_settings.max_concurrent_streams = entry->value; - - break; - case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - - /* Update the initial window size of the all active streams */ - /* Check that initial_window_size < (1u << 31) */ - if (entry->value > NGHTTP2_MAX_WINDOW_SIZE) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, - "SETTINGS: too large SETTINGS_INITIAL_WINDOW_SIZE"); - } - - rv = session_update_remote_initial_window_size(session, - (int32_t)entry->value); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (rv != 0) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL); - } - - session->remote_settings.initial_window_size = entry->value; - - break; - case NGHTTP2_SETTINGS_MAX_FRAME_SIZE: - - if (entry->value < NGHTTP2_MAX_FRAME_SIZE_MIN || - entry->value > NGHTTP2_MAX_FRAME_SIZE_MAX) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_MAX_FRAME_SIZE"); - } - - session->remote_settings.max_frame_size = entry->value; - - break; - case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: - - session->remote_settings.max_header_list_size = entry->value; - - break; - case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL: - - if (entry->value != 0 && entry->value != 1) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL"); - } - - if (!session->server && - session->remote_settings.enable_connect_protocol && - entry->value == 0) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: server attempted to disable " - "SETTINGS_ENABLE_CONNECT_PROTOCOL"); - } - - session->remote_settings.enable_connect_protocol = entry->value; - - break; - case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES: - - if (entry->value != 0 && entry->value != 1) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES"); - } - - if (session->remote_settings.no_rfc7540_priorities != UINT32_MAX && - session->remote_settings.no_rfc7540_priorities != entry->value) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed"); - } - - session->remote_settings.no_rfc7540_priorities = entry->value; - - break; - } - } - - if (session->remote_settings.no_rfc7540_priorities == UINT32_MAX) { - session->remote_settings.no_rfc7540_priorities = 0; - } - - if (!noack && !session_is_closing(session)) { - rv = nghttp2_session_add_settings(session, NGHTTP2_FLAG_ACK, NULL, 0); - - if (rv != 0) { - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return session_handle_invalid_connection(session, frame, - NGHTTP2_ERR_INTERNAL, NULL); - } - } - - return session_call_on_frame_received(session, frame); -} - -static int session_process_settings_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - size_t i; - nghttp2_settings_entry min_header_size_entry; - - if (iframe->max_niv) { - min_header_size_entry = iframe->iv[iframe->max_niv - 1]; - - if (min_header_size_entry.value < UINT32_MAX) { - /* If we have less value, then we must have - SETTINGS_HEADER_TABLE_SIZE in i < iframe->niv */ - for (i = 0; i < iframe->niv; ++i) { - if (iframe->iv[i].settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) { - break; - } - } - - assert(i < iframe->niv); - - if (min_header_size_entry.value != iframe->iv[i].value) { - iframe->iv[iframe->niv++] = iframe->iv[i]; - iframe->iv[i] = min_header_size_entry; - } - } - } - - nghttp2_frame_unpack_settings_payload(&frame->settings, iframe->iv, - iframe->niv); - - iframe->iv = NULL; - iframe->niv = 0; - iframe->max_niv = 0; - - return nghttp2_session_on_settings_received(session, frame, 0 /* ACK */); -} - -int nghttp2_session_on_push_promise_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - nghttp2_stream *stream; - nghttp2_stream *promised_stream; - - if (frame->hd.stream_id == 0) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream_id == 0"); - } - if (session->server || session->local_settings.enable_push == 0) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: push disabled"); - } - - if (!nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: invalid stream_id"); - } - - if (!session_allow_incoming_new_stream(session)) { - /* We just discard PUSH_PROMISE after GOAWAY was sent */ - return NGHTTP2_ERR_IGN_HEADER_BLOCK; - } - - if (!session_is_new_peer_stream_id(session, - frame->push_promise.promised_stream_id)) { - /* The spec says if an endpoint receives a PUSH_PROMISE with - illegal stream ID is subject to a connection error of type - PROTOCOL_ERROR. */ - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PUSH_PROMISE: invalid promised_stream_id"); - } - - if (session_detect_idle_stream(session, frame->hd.stream_id)) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle"); - } - - session->last_recv_stream_id = frame->push_promise.promised_stream_id; - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream || stream->state == NGHTTP2_STREAM_CLOSING || - !session->pending_enable_push || - session->num_incoming_reserved_streams >= - session->max_incoming_reserved_streams) { - /* Currently, client does not retain closed stream, so we don't - check NGHTTP2_SHUT_RD condition here. */ - rv = session_handle_invalid_stream2(session, - frame->push_promise.promised_stream_id, - NULL, NGHTTP2_ERR_PUSH_CANCEL); - if (rv != 0) { - return rv; - } - return NGHTTP2_ERR_IGN_HEADER_BLOCK; - } - - if (stream->shut_flags & NGHTTP2_SHUT_RD) { - return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "PUSH_PROMISE: stream closed"); - } - - promised_stream = nghttp2_session_open_stream( - session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE, - NGHTTP2_STREAM_RESERVED, NULL); - - if (!promised_stream) { - return NGHTTP2_ERR_NOMEM; - } - - session->last_proc_stream_id = session->last_recv_stream_id; - rv = session_call_on_begin_headers(session, frame); - if (rv != 0) { - return rv; - } - return 0; -} - -static int session_process_push_promise_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - nghttp2_frame_unpack_push_promise_payload(&frame->push_promise, - iframe->sbuf.pos); - - return nghttp2_session_on_push_promise_received(session, frame); -} - -int nghttp2_session_on_ping_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv = 0; - if (frame->hd.stream_id != 0) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "PING: stream_id != 0"); - } - if ((session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_PING_ACK) == 0 && - (frame->hd.flags & NGHTTP2_FLAG_ACK) == 0 && - !session_is_closing(session)) { - /* Peer sent ping, so ping it back */ - rv = nghttp2_session_add_ping(session, NGHTTP2_FLAG_ACK, - frame->ping.opaque_data); - if (rv != 0) { - return rv; - } - } - return session_call_on_frame_received(session, frame); -} - -static int session_process_ping_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - nghttp2_frame_unpack_ping_payload(&frame->ping, iframe->sbuf.pos); - - return nghttp2_session_on_ping_received(session, frame); -} - -int nghttp2_session_on_goaway_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - - if (frame->hd.stream_id != 0) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "GOAWAY: stream_id != 0"); - } - /* Spec says Endpoints MUST NOT increase the value they send in the - last stream identifier. */ - if ((frame->goaway.last_stream_id > 0 && - !nghttp2_session_is_my_stream_id(session, - frame->goaway.last_stream_id)) || - session->remote_last_stream_id < frame->goaway.last_stream_id) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "GOAWAY: invalid last_stream_id"); - } - - session->goaway_flags |= NGHTTP2_GOAWAY_RECV; - - session->remote_last_stream_id = frame->goaway.last_stream_id; - - rv = session_call_on_frame_received(session, frame); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return session_close_stream_on_goaway(session, frame->goaway.last_stream_id, - 0); -} - -static int session_process_goaway_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - nghttp2_frame_unpack_goaway_payload(&frame->goaway, iframe->sbuf.pos, - iframe->lbuf.pos, - nghttp2_buf_len(&iframe->lbuf)); - - nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0); - - return nghttp2_session_on_goaway_received(session, frame); -} - -static int -session_on_connection_window_update_received(nghttp2_session *session, - nghttp2_frame *frame) { - /* Handle connection-level flow control */ - if (frame->window_update.window_size_increment == 0) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "WINDOW_UPDATE: window_size_increment == 0"); - } - - if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < - session->remote_window_size) { - return session_handle_invalid_connection(session, frame, - NGHTTP2_ERR_FLOW_CONTROL, NULL); - } - session->remote_window_size += frame->window_update.window_size_increment; - - return session_call_on_frame_received(session, frame); -} - -static int session_on_stream_window_update_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - nghttp2_stream *stream; - - if (session_detect_idle_stream(session, frame->hd.stream_id)) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "WINDOW_UPDATE to idle stream"); - } - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream) { - return 0; - } - if (state_reserved_remote(session, stream)) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPADATE to reserved stream"); - } - if (frame->window_update.window_size_increment == 0) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "WINDOW_UPDATE: window_size_increment == 0"); - } - if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < - stream->remote_window_size) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, - "WINDOW_UPDATE: window size overflow"); - } - stream->remote_window_size += frame->window_update.window_size_increment; - - if (stream->remote_window_size > 0 && - nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = session_resume_deferred_stream_item( - session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - return session_call_on_frame_received(session, frame); -} - -int nghttp2_session_on_window_update_received(nghttp2_session *session, - nghttp2_frame *frame) { - if (frame->hd.stream_id == 0) { - return session_on_connection_window_update_received(session, frame); - } else { - return session_on_stream_window_update_received(session, frame); - } -} - -static int session_process_window_update_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - nghttp2_frame_unpack_window_update_payload(&frame->window_update, - iframe->sbuf.pos); - - return nghttp2_session_on_window_update_received(session, frame); -} - -int nghttp2_session_on_altsvc_received(nghttp2_session *session, - nghttp2_frame *frame) { - nghttp2_ext_altsvc *altsvc; - nghttp2_stream *stream; - - altsvc = frame->ext.payload; - - /* session->server case has been excluded */ - - if (frame->hd.stream_id == 0) { - if (altsvc->origin_len == 0) { - return session_call_on_invalid_frame_recv_callback(session, frame, - NGHTTP2_ERR_PROTO); - } - } else { - if (altsvc->origin_len > 0) { - return session_call_on_invalid_frame_recv_callback(session, frame, - NGHTTP2_ERR_PROTO); - } - - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream) { - return 0; - } - - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return 0; - } - } - - if (altsvc->field_value_len == 0) { - return session_call_on_invalid_frame_recv_callback(session, frame, - NGHTTP2_ERR_PROTO); - } - - return session_call_on_frame_received(session, frame); -} - -int nghttp2_session_on_origin_received(nghttp2_session *session, - nghttp2_frame *frame) { - return session_call_on_frame_received(session, frame); -} - -int nghttp2_session_on_priority_update_received(nghttp2_session *session, - nghttp2_frame *frame) { - nghttp2_ext_priority_update *priority_update; - nghttp2_stream *stream; - nghttp2_extpri extpri; - int rv; - - assert(session->server); - - priority_update = frame->ext.payload; - - if (frame->hd.stream_id != 0) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY_UPDATE: stream_id == 0"); - } - - if (nghttp2_session_is_my_stream_id(session, priority_update->stream_id)) { - if (session_detect_idle_stream(session, priority_update->stream_id)) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY_UPDATE: prioritizing idle push is not allowed"); - } - - /* TODO Ignore priority signal to a push stream for now */ - return session_call_on_frame_received(session, frame); - } - - stream = nghttp2_session_get_stream_raw(session, priority_update->stream_id); - if (stream) { - /* Stream already exists. */ - if (stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) { - return session_call_on_frame_received(session, frame); - } - } else if (session_detect_idle_stream(session, priority_update->stream_id)) { - if (session->num_idle_streams + session->num_incoming_streams >= - session->local_settings.max_concurrent_streams) { - return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY_UPDATE: max concurrent streams exceeded"); - } - - stream = - nghttp2_session_open_stream(session, priority_update->stream_id, - NGHTTP2_FLAG_NONE, NGHTTP2_STREAM_IDLE, NULL); - if (!stream) { - return NGHTTP2_ERR_NOMEM; - } - } else { - return session_call_on_frame_received(session, frame); - } - - extpri.urgency = NGHTTP2_EXTPRI_DEFAULT_URGENCY; - extpri.inc = 0; - - rv = nghttp2_http_parse_priority(&extpri, priority_update->field_value, - priority_update->field_value_len); - if (rv != 0) { - /* Just ignore field_value if it cannot be parsed. */ - return session_call_on_frame_received(session, frame); - } - - rv = session_update_stream_priority(session, stream, - nghttp2_extpri_to_uint8(&extpri)); - if (rv != 0) { - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - - return session_call_on_frame_received(session, frame); -} - -static int session_process_altsvc_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - nghttp2_frame_unpack_altsvc_payload( - &frame->ext, nghttp2_get_uint16(iframe->sbuf.pos), iframe->lbuf.pos, - nghttp2_buf_len(&iframe->lbuf)); - - /* nghttp2_frame_unpack_altsvc_payload steals buffer from - iframe->lbuf */ - nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0); - - return nghttp2_session_on_altsvc_received(session, frame); -} - -static int session_process_origin_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - nghttp2_mem *mem = &session->mem; - int rv; - - rv = nghttp2_frame_unpack_origin_payload(&frame->ext, iframe->lbuf.pos, - nghttp2_buf_len(&iframe->lbuf), mem); - if (rv != 0) { - if (nghttp2_is_fatal(rv)) { - return rv; - } - /* Ignore ORIGIN frame which cannot be parsed. */ - return 0; - } - - return nghttp2_session_on_origin_received(session, frame); -} - -static int session_process_priority_update_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - nghttp2_frame_unpack_priority_update_payload(&frame->ext, iframe->sbuf.pos, - nghttp2_buf_len(&iframe->sbuf)); - - return nghttp2_session_on_priority_update_received(session, frame); -} - -static int session_process_extension_frame(nghttp2_session *session) { - int rv; - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - rv = session_call_unpack_extension_callback(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - /* This handles the case where rv == NGHTTP2_ERR_CANCEL as well */ - if (rv != 0) { - return 0; - } - - return session_call_on_frame_received(session, frame); -} - -int nghttp2_session_on_data_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv = 0; - nghttp2_stream *stream; - - /* We don't call on_frame_recv_callback if stream has been closed - already or being closed. */ - stream = nghttp2_session_get_stream(session, frame->hd.stream_id); - if (!stream || stream->state == NGHTTP2_STREAM_CLOSING) { - /* This should be treated as stream error, but it results in lots - of RST_STREAM. So just ignore frame against nonexistent stream - for now. */ - return 0; - } - - if (session_enforce_http_messaging(session) && - (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { - if (nghttp2_http_on_remote_end_stream(stream) != 0) { - return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); - } - } - - rv = session_call_on_frame_received(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream); - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - return 0; -} - -/* For errors, this function only returns FATAL error. */ -static int session_process_data_frame(nghttp2_session *session) { - int rv; - nghttp2_frame *public_data_frame = &session->iframe.frame; - rv = nghttp2_session_on_data_received(session, public_data_frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return 0; -} - -/* - * Now we have SETTINGS synchronization, flow control error can be - * detected strictly. If DATA frame is received with length > 0 and - * current received window size + delta length is strictly larger than - * local window size, it is subject to FLOW_CONTROL_ERROR, so return - * -1. Note that local_window_size is calculated after SETTINGS ACK is - * received from peer, so peer must honor this limit. If the resulting - * recv_window_size is strictly larger than NGHTTP2_MAX_WINDOW_SIZE, - * return -1 too. - */ -static int adjust_recv_window_size(int32_t *recv_window_size_ptr, size_t delta, - int32_t local_window_size) { - if (*recv_window_size_ptr > local_window_size - (int32_t)delta || - *recv_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - (int32_t)delta) { - return -1; - } - *recv_window_size_ptr += (int32_t)delta; - return 0; -} - -int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, - nghttp2_stream *stream, - size_t delta_size, - int send_window_update) { - int rv; - rv = adjust_recv_window_size(&stream->recv_window_size, delta_size, - stream->local_window_size); - if (rv != 0) { - return nghttp2_session_terminate_session(session, - NGHTTP2_FLOW_CONTROL_ERROR); - } - /* We don't have to send WINDOW_UPDATE if the data received is the - last chunk in the incoming stream. */ - /* We have to use local_settings here because it is the constraint - the remote endpoint should honor. */ - if (send_window_update && - !(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) && - stream->window_update_queued == 0 && - nghttp2_should_send_window_update(stream->local_window_size, - stream->recv_window_size)) { - rv = nghttp2_session_add_window_update( - session, NGHTTP2_FLAG_NONE, stream->stream_id, stream->recv_window_size); - if (rv != 0) { - return rv; - } - - stream->recv_window_size = 0; - } - return 0; -} - -int nghttp2_session_update_recv_connection_window_size(nghttp2_session *session, - size_t delta_size) { - int rv; - rv = adjust_recv_window_size(&session->recv_window_size, delta_size, - session->local_window_size); - if (rv != 0) { - return nghttp2_session_terminate_session(session, - NGHTTP2_FLOW_CONTROL_ERROR); - } - if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) && - session->window_update_queued == 0 && - nghttp2_should_send_window_update(session->local_window_size, - session->recv_window_size)) { - /* Use stream ID 0 to update connection-level flow control - window */ - rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE, 0, - session->recv_window_size); - if (rv != 0) { - return rv; - } - - session->recv_window_size = 0; - } - return 0; -} - -static int session_update_consumed_size(nghttp2_session *session, - int32_t *consumed_size_ptr, - int32_t *recv_window_size_ptr, - uint8_t window_update_queued, - int32_t stream_id, size_t delta_size, - int32_t local_window_size) { - int32_t recv_size; - int rv; - - if ((size_t)*consumed_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta_size) { - return nghttp2_session_terminate_session(session, - NGHTTP2_FLOW_CONTROL_ERROR); - } - - *consumed_size_ptr += (int32_t)delta_size; - - if (window_update_queued == 0) { - /* recv_window_size may be smaller than consumed_size, because it - may be decreased by negative value with - nghttp2_submit_window_update(). */ - recv_size = nghttp2_min_int32(*consumed_size_ptr, *recv_window_size_ptr); - - if (nghttp2_should_send_window_update(local_window_size, recv_size)) { - rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE, - stream_id, recv_size); - - if (rv != 0) { - return rv; - } - - *recv_window_size_ptr -= recv_size; - *consumed_size_ptr -= recv_size; - } - } - - return 0; -} - -static int session_update_stream_consumed_size(nghttp2_session *session, - nghttp2_stream *stream, - size_t delta_size) { - return session_update_consumed_size( - session, &stream->consumed_size, &stream->recv_window_size, - stream->window_update_queued, stream->stream_id, delta_size, - stream->local_window_size); -} - -static int session_update_connection_consumed_size(nghttp2_session *session, - size_t delta_size) { - return session_update_consumed_size( - session, &session->consumed_size, &session->recv_window_size, - session->window_update_queued, 0, delta_size, session->local_window_size); -} - -/* - * Checks that we can receive the DATA frame for stream, which is - * indicated by |session->iframe.frame.hd.stream_id|. If it is a - * connection error situation, GOAWAY frame will be issued by this - * function. - * - * If the DATA frame is allowed, returns 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_IGN_PAYLOAD - * The reception of DATA frame is connection error; or should be - * ignored. - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -static int session_on_data_received_fail_fast(nghttp2_session *session) { - int rv; - nghttp2_stream *stream; - nghttp2_inbound_frame *iframe; - int32_t stream_id; - const char *failure_reason; - uint32_t error_code = NGHTTP2_PROTOCOL_ERROR; - - iframe = &session->iframe; - stream_id = iframe->frame.hd.stream_id; - - if (stream_id == 0) { - /* The spec says that if a DATA frame is received whose stream ID - is 0, the recipient MUST respond with a connection error of - type PROTOCOL_ERROR. */ - failure_reason = "DATA: stream_id == 0"; - goto fail; - } - - if (session_detect_idle_stream(session, stream_id)) { - failure_reason = "DATA: stream in idle"; - error_code = NGHTTP2_PROTOCOL_ERROR; - goto fail; - } - - stream = nghttp2_session_get_stream(session, stream_id); - if (!stream) { - stream = nghttp2_session_get_stream_raw(session, stream_id); - if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) { - failure_reason = "DATA: stream closed"; - error_code = NGHTTP2_STREAM_CLOSED; - goto fail; - } - - return NGHTTP2_ERR_IGN_PAYLOAD; - } - if (stream->shut_flags & NGHTTP2_SHUT_RD) { - failure_reason = "DATA: stream in half-closed(remote)"; - error_code = NGHTTP2_STREAM_CLOSED; - goto fail; - } - - if (nghttp2_session_is_my_stream_id(session, stream_id)) { - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_IGN_PAYLOAD; - } - if (stream->state != NGHTTP2_STREAM_OPENED) { - failure_reason = "DATA: stream not opened"; - goto fail; - } - return 0; - } - if (stream->state == NGHTTP2_STREAM_RESERVED) { - failure_reason = "DATA: stream in reserved"; - goto fail; - } - if (stream->state == NGHTTP2_STREAM_CLOSING) { - return NGHTTP2_ERR_IGN_PAYLOAD; - } - return 0; -fail: - rv = nghttp2_session_terminate_session_with_reason(session, error_code, - failure_reason); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return NGHTTP2_ERR_IGN_PAYLOAD; -} - -static size_t inbound_frame_payload_readlen(nghttp2_inbound_frame *iframe, - const uint8_t *in, - const uint8_t *last) { - return nghttp2_min_size((size_t)(last - in), iframe->payloadleft); -} - -/* - * Resets iframe->sbuf and advance its mark pointer by |left| bytes. - */ -static void inbound_frame_set_mark(nghttp2_inbound_frame *iframe, size_t left) { - nghttp2_buf_reset(&iframe->sbuf); - iframe->sbuf.mark += left; -} - -static size_t inbound_frame_buf_read(nghttp2_inbound_frame *iframe, - const uint8_t *in, const uint8_t *last) { - size_t readlen; - - readlen = nghttp2_min_size((size_t)(last - in), - nghttp2_buf_mark_avail(&iframe->sbuf)); - - iframe->sbuf.last = nghttp2_cpymem(iframe->sbuf.last, in, readlen); - - return readlen; -} - -/* - * Unpacks SETTINGS entry in iframe->sbuf. - */ -static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) { - nghttp2_settings_entry iv; - nghttp2_settings_entry *min_header_table_size_entry; - size_t i; - - nghttp2_frame_unpack_settings_entry(&iv, iframe->sbuf.pos); - - switch (iv.settings_id) { - case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: - case NGHTTP2_SETTINGS_ENABLE_PUSH: - case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: - case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - case NGHTTP2_SETTINGS_MAX_FRAME_SIZE: - case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: - case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL: - case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES: - break; - default: - DEBUGF("recv: unknown settings id=0x%02x\n", iv.settings_id); - - iframe->iv[iframe->niv++] = iv; - - return; - } - - for (i = 0; i < iframe->niv; ++i) { - if (iframe->iv[i].settings_id == iv.settings_id) { - iframe->iv[i] = iv; - break; - } - } - - if (i == iframe->niv) { - iframe->iv[iframe->niv++] = iv; - } - - if (iv.settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) { - /* Keep track of minimum value of SETTINGS_HEADER_TABLE_SIZE */ - min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1]; - - if (iv.value < min_header_table_size_entry->value) { - min_header_table_size_entry->value = iv.value; - } - } -} - -/* - * Checks PADDED flags and set iframe->sbuf to read them accordingly. - * If padding is set, this function returns 1. If no padding is set, - * this function returns 0. On error, returns -1. - */ -static int inbound_frame_handle_pad(nghttp2_inbound_frame *iframe, - nghttp2_frame_hd *hd) { - if (hd->flags & NGHTTP2_FLAG_PADDED) { - if (hd->length < 1) { - return -1; - } - inbound_frame_set_mark(iframe, 1); - return 1; - } - DEBUGF("recv: no padding in payload\n"); - return 0; -} - -/* - * Computes number of padding based on flags. This function returns - * the calculated length if it succeeds, or -1. - */ -static nghttp2_ssize inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) { - size_t padlen; - - /* 1 for Pad Length field */ - padlen = (size_t)(iframe->sbuf.pos[0] + 1); - - DEBUGF("recv: padlen=%zu\n", padlen); - - /* We cannot use iframe->frame.hd.length because of CONTINUATION */ - if (padlen - 1 > iframe->payloadleft) { - return -1; - } - - iframe->padlen = padlen; - - return (nghttp2_ssize)padlen; -} - -/* - * This function returns the effective payload length in the data of - * length |readlen| when the remaining payload is |payloadleft|. The - * |payloadleft| does not include |readlen|. If padding was started - * strictly before this data chunk, this function returns -1. - */ -static nghttp2_ssize -inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe, - size_t payloadleft, size_t readlen) { - size_t trail_padlen = - nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen); - - if (trail_padlen > payloadleft) { - size_t padlen; - padlen = trail_padlen - payloadleft; - if (readlen < padlen) { - return -1; - } - return (nghttp2_ssize)(readlen - padlen); - } - return (nghttp2_ssize)(readlen); -} - -static const uint8_t static_in[] = {0}; - -ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, - size_t inlen) { - return (ssize_t)nghttp2_session_mem_recv2(session, in, inlen); -} - -nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, - const uint8_t *in, size_t inlen) { - const uint8_t *first, *last; - nghttp2_inbound_frame *iframe = &session->iframe; - size_t readlen; - nghttp2_ssize padlen; - int rv; - int busy = 0; - nghttp2_frame_hd cont_hd; - nghttp2_stream *stream; - size_t pri_fieldlen; - nghttp2_mem *mem; - - if (in == NULL) { - assert(inlen == 0); - in = static_in; - } - - first = in; - last = in + inlen; - - DEBUGF("recv: connection recv_window_size=%d, local_window=%d\n", - session->recv_window_size, session->local_window_size); - - mem = &session->mem; - - if (!nghttp2_session_want_read(session)) { - return (nghttp2_ssize)inlen; - } - - for (;;) { - switch (iframe->state) { - case NGHTTP2_IB_READ_CLIENT_MAGIC: - readlen = nghttp2_min_size(inlen, iframe->payloadleft); - - if (memcmp(&NGHTTP2_CLIENT_MAGIC[NGHTTP2_CLIENT_MAGIC_LEN - - iframe->payloadleft], - in, readlen) != 0) { - return NGHTTP2_ERR_BAD_CLIENT_MAGIC; - } - - iframe->payloadleft -= readlen; - in += readlen; - - if (iframe->payloadleft == 0) { - session_inbound_frame_reset(session); - iframe->state = NGHTTP2_IB_READ_FIRST_SETTINGS; - } - - break; - case NGHTTP2_IB_READ_FIRST_SETTINGS: - DEBUGF("recv: [IB_READ_FIRST_SETTINGS]\n"); - - readlen = inbound_frame_buf_read(iframe, in, last); - in += readlen; - - if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return (nghttp2_ssize)(in - first); - } - - if (iframe->sbuf.pos[3] != NGHTTP2_SETTINGS || - (iframe->sbuf.pos[4] & NGHTTP2_FLAG_ACK)) { - rv = session_call_error_callback( - session, NGHTTP2_ERR_SETTINGS_EXPECTED, - "Remote peer returned unexpected data while we expected " - "SETTINGS frame. Perhaps, peer does not support HTTP/2 " - "properly."); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected"); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return (nghttp2_ssize)inlen; - } - - iframe->state = NGHTTP2_IB_READ_HEAD; - - /* Fall through */ - case NGHTTP2_IB_READ_HEAD: { - int on_begin_frame_called = 0; - - DEBUGF("recv: [IB_READ_HEAD]\n"); - - readlen = inbound_frame_buf_read(iframe, in, last); - in += readlen; - - if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return (nghttp2_ssize)(in - first); - } - - nghttp2_frame_unpack_frame_hd(&iframe->frame.hd, iframe->sbuf.pos); - iframe->payloadleft = iframe->frame.hd.length; - - DEBUGF("recv: payloadlen=%zu, type=%u, flags=0x%02x, stream_id=%d\n", - iframe->frame.hd.length, iframe->frame.hd.type, - iframe->frame.hd.flags, iframe->frame.hd.stream_id); - - if (iframe->frame.hd.length > session->local_settings.max_frame_size) { - DEBUGF("recv: length is too large %zu > %u\n", iframe->frame.hd.length, - session->local_settings.max_frame_size); - - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size"); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return (nghttp2_ssize)inlen; - } - - switch (iframe->frame.hd.type) { - case NGHTTP2_DATA: { - DEBUGF("recv: DATA\n"); - - iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PADDED); - /* Check stream is open. If it is not open or closing, - ignore payload. */ - busy = 1; - - rv = session_on_data_received_fail_fast(session); - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - if (rv == NGHTTP2_ERR_IGN_PAYLOAD) { - DEBUGF("recv: DATA not allowed stream_id=%d\n", - iframe->frame.hd.stream_id); - - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - iframe->state = NGHTTP2_IB_IGN_DATA; - break; - } - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); - if (rv < 0) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "DATA: insufficient padding space"); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - - if (rv == 1) { - iframe->state = NGHTTP2_IB_READ_PAD_DATA; - break; - } - - /* Empty DATA frame without END_STREAM flag set is - suspicious. */ - if (iframe->payloadleft == 0 && - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - } - - iframe->state = NGHTTP2_IB_READ_DATA; - break; - } - case NGHTTP2_HEADERS: - - DEBUGF("recv: HEADERS\n"); - - iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS | - NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_PRIORITY); - - rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); - if (rv < 0) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "HEADERS: insufficient padding space"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - - if (rv == 1) { - iframe->state = NGHTTP2_IB_READ_NBYTE; - break; - } - - pri_fieldlen = nghttp2_frame_priority_len(iframe->frame.hd.flags); - - if (pri_fieldlen > 0) { - if (iframe->payloadleft < pri_fieldlen) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - iframe->state = NGHTTP2_IB_READ_NBYTE; - - inbound_frame_set_mark(iframe, pri_fieldlen); - - break; - } - - /* Call on_begin_frame_callback here because - session_process_headers_frame() may call - on_begin_headers_callback */ - rv = session_call_on_begin_frame(session, &iframe->frame.hd); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - on_begin_frame_called = 1; - - rv = session_process_headers_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - busy = 1; - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_handle_invalid_stream2( - session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); - if (nghttp2_is_fatal(rv)) { - return rv; - } - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - break; - } - - if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) { - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - break; - } - - iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK; - - break; - case NGHTTP2_PRIORITY: - DEBUGF("recv: PRIORITY\n"); - - iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; - - if (iframe->payloadleft != NGHTTP2_PRIORITY_SPECLEN) { - busy = 1; - - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - - break; - } - - /* This is deprecated RFC 7540 priorities mechanism which is - very unpopular. We do not expect it is received so - frequently. */ - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - iframe->state = NGHTTP2_IB_READ_NBYTE; - - inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN); - - break; - case NGHTTP2_RST_STREAM: - case NGHTTP2_WINDOW_UPDATE: -#ifdef DEBUGBUILD - switch (iframe->frame.hd.type) { - case NGHTTP2_RST_STREAM: - DEBUGF("recv: RST_STREAM\n"); - break; - case NGHTTP2_WINDOW_UPDATE: - DEBUGF("recv: WINDOW_UPDATE\n"); - break; - } -#endif /* DEBUGBUILD */ - - iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; - - if (iframe->payloadleft != 4) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - iframe->state = NGHTTP2_IB_READ_NBYTE; - - inbound_frame_set_mark(iframe, 4); - - break; - case NGHTTP2_SETTINGS: - DEBUGF("recv: SETTINGS\n"); - - iframe->frame.hd.flags &= NGHTTP2_FLAG_ACK; - - if ((iframe->frame.hd.length % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) || - ((iframe->frame.hd.flags & NGHTTP2_FLAG_ACK) && - iframe->payloadleft > 0)) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - /* Check the settings flood counter early to be safe */ - if (session->obq_flood_counter_ >= session->max_outbound_ack && - !(iframe->frame.hd.flags & NGHTTP2_FLAG_ACK)) { - return NGHTTP2_ERR_FLOODED; - } - - iframe->state = NGHTTP2_IB_READ_SETTINGS; - - if (iframe->payloadleft) { - nghttp2_settings_entry *min_header_table_size_entry; - - /* We allocate iv with additional one entry, to store the - minimum header table size. */ - iframe->max_niv = - iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1; - - if (iframe->max_niv - 1 > session->max_settings) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_ENHANCE_YOUR_CALM, - "SETTINGS: too many setting entries"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - - iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) * - iframe->max_niv); - - if (!iframe->iv) { - return NGHTTP2_ERR_NOMEM; - } - - min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1]; - min_header_table_size_entry->settings_id = - NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; - min_header_table_size_entry->value = UINT32_MAX; - - inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH); - break; - } - - busy = 1; - - inbound_frame_set_mark(iframe, 0); - - break; - case NGHTTP2_PUSH_PROMISE: - DEBUGF("recv: PUSH_PROMISE\n"); - - iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED); - - rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); - if (rv < 0) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PUSH_PROMISE: insufficient padding space"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - - if (rv == 1) { - iframe->state = NGHTTP2_IB_READ_NBYTE; - break; - } - - if (iframe->payloadleft < 4) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - iframe->state = NGHTTP2_IB_READ_NBYTE; - - inbound_frame_set_mark(iframe, 4); - - break; - case NGHTTP2_PING: - DEBUGF("recv: PING\n"); - - iframe->frame.hd.flags &= NGHTTP2_FLAG_ACK; - - if (iframe->payloadleft != 8) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - iframe->state = NGHTTP2_IB_READ_NBYTE; - inbound_frame_set_mark(iframe, 8); - - break; - case NGHTTP2_GOAWAY: - DEBUGF("recv: GOAWAY\n"); - - iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; - - if (iframe->payloadleft < 8) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - iframe->state = NGHTTP2_IB_READ_NBYTE; - inbound_frame_set_mark(iframe, 8); - - break; - case NGHTTP2_CONTINUATION: - DEBUGF("recv: unexpected CONTINUATION\n"); - - /* Receiving CONTINUATION in this state are subject to - connection error of type PROTOCOL_ERROR */ - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "CONTINUATION: unexpected"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return (nghttp2_ssize)inlen; - default: - DEBUGF("recv: extension frame\n"); - - if (check_ext_type_set(session->user_recv_ext_types, - iframe->frame.hd.type)) { - if (!session->callbacks.unpack_extension_callback) { - /* Receiving too frequent unknown frames is suspicious. */ - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - /* Silently ignore unknown frame type. */ - busy = 1; - - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - - break; - } - - busy = 1; - - iframe->state = NGHTTP2_IB_READ_EXTENSION_PAYLOAD; - - break; - } else { - switch (iframe->frame.hd.type) { - case NGHTTP2_ALTSVC: - if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == - 0) { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - break; - } - - DEBUGF("recv: ALTSVC\n"); - - iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; - iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc; - - if (session->server) { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - break; - } - - if (iframe->payloadleft < 2) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - busy = 1; - - iframe->state = NGHTTP2_IB_READ_NBYTE; - inbound_frame_set_mark(iframe, 2); - - break; - case NGHTTP2_ORIGIN: - if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - break; - } - - DEBUGF("recv: ORIGIN\n"); - - iframe->frame.ext.payload = &iframe->ext_frame_payload.origin; - - if (session->server || iframe->frame.hd.stream_id || - (iframe->frame.hd.flags & 0xf0)) { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - break; - } - - iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; - - if (iframe->payloadleft) { - iframe->raw_lbuf = nghttp2_mem_malloc(mem, iframe->payloadleft); - - if (iframe->raw_lbuf == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf, - iframe->payloadleft); - } else { - busy = 1; - } - - iframe->state = NGHTTP2_IB_READ_ORIGIN_PAYLOAD; - - break; - case NGHTTP2_PRIORITY_UPDATE: - if ((session->builtin_recv_ext_types & - NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - break; - } - - DEBUGF("recv: PRIORITY_UPDATE\n"); - - iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; - iframe->frame.ext.payload = - &iframe->ext_frame_payload.priority_update; - - if (!session->server) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PRIORITY_UPDATE is received from server"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - - if (iframe->payloadleft < 4) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - /* Receiving too frequent PRIORITY_UPDATE is - suspicious. */ - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - break; - } - - busy = 1; - - iframe->state = NGHTTP2_IB_READ_NBYTE; - inbound_frame_set_mark(iframe, iframe->payloadleft); - - break; - default: - /* Receiving too frequent unknown frames is suspicious. */ - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - busy = 1; - - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - - break; - } - } - } - - if (!on_begin_frame_called) { - switch (iframe->state) { - case NGHTTP2_IB_IGN_HEADER_BLOCK: - case NGHTTP2_IB_IGN_PAYLOAD: - case NGHTTP2_IB_FRAME_SIZE_ERROR: - case NGHTTP2_IB_IGN_DATA: - case NGHTTP2_IB_IGN_ALL: - break; - default: - rv = session_call_on_begin_frame(session, &iframe->frame.hd); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - } - - break; - } - case NGHTTP2_IB_READ_NBYTE: - DEBUGF("recv: [IB_READ_NBYTE]\n"); - - readlen = inbound_frame_buf_read(iframe, in, last); - in += readlen; - iframe->payloadleft -= readlen; - - DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zu\n", readlen, - iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf)); - - if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return (nghttp2_ssize)(in - first); - } - - switch (iframe->frame.hd.type) { - case NGHTTP2_HEADERS: - if (iframe->padlen == 0 && - (iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) { - pri_fieldlen = nghttp2_frame_priority_len(iframe->frame.hd.flags); - padlen = inbound_frame_compute_pad(iframe); - if (padlen < 0 || - (size_t)padlen + pri_fieldlen > 1 + iframe->payloadleft) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - iframe->frame.headers.padlen = (size_t)padlen; - - if (pri_fieldlen > 0) { - if (iframe->payloadleft < pri_fieldlen) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - iframe->state = NGHTTP2_IB_READ_NBYTE; - inbound_frame_set_mark(iframe, pri_fieldlen); - break; - } else { - /* Truncate buffers used for padding spec */ - inbound_frame_set_mark(iframe, 0); - } - } - - rv = session_process_headers_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - busy = 1; - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_handle_invalid_stream2( - session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); - if (nghttp2_is_fatal(rv)) { - return rv; - } - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - break; - } - - if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) { - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - break; - } - - iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK; - - break; - case NGHTTP2_PRIORITY: - session_inbound_frame_reset(session); - - break; - case NGHTTP2_RST_STREAM: - rv = session_process_rst_stream_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_PUSH_PROMISE: - if (iframe->padlen == 0 && - (iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) { - padlen = inbound_frame_compute_pad(iframe); - if (padlen < 0 || (size_t)padlen + 4 /* promised stream id */ - > 1 + iframe->payloadleft) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: invalid padding"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - - iframe->frame.push_promise.padlen = (size_t)padlen; - - if (iframe->payloadleft < 4) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - iframe->state = NGHTTP2_IB_READ_NBYTE; - - inbound_frame_set_mark(iframe, 4); - - break; - } - - rv = session_process_push_promise_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - busy = 1; - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_handle_invalid_stream2( - session, iframe->frame.push_promise.promised_stream_id, NULL, - NGHTTP2_ERR_INTERNAL); - if (nghttp2_is_fatal(rv)) { - return rv; - } - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - break; - } - - if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) { - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - break; - } - - iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK; - - break; - case NGHTTP2_PING: - rv = session_process_ping_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_GOAWAY: { - size_t debuglen; - - /* 8 is Last-stream-ID + Error Code */ - debuglen = iframe->frame.hd.length - 8; - - if (debuglen > 0) { - iframe->raw_lbuf = nghttp2_mem_malloc(mem, debuglen); - - if (iframe->raw_lbuf == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf, debuglen); - } - - busy = 1; - - iframe->state = NGHTTP2_IB_READ_GOAWAY_DEBUG; - - break; - } - case NGHTTP2_WINDOW_UPDATE: - rv = session_process_window_update_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_ALTSVC: { - size_t origin_len; - - origin_len = nghttp2_get_uint16(iframe->sbuf.pos); - - DEBUGF("recv: origin_len=%zu\n", origin_len); - - if (origin_len > iframe->payloadleft) { - busy = 1; - iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR; - break; - } - - if (iframe->frame.hd.length > 2) { - iframe->raw_lbuf = - nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2); - - if (iframe->raw_lbuf == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf, - iframe->frame.hd.length); - } - - busy = 1; - - iframe->state = NGHTTP2_IB_READ_ALTSVC_PAYLOAD; - - break; - case NGHTTP2_PRIORITY_UPDATE: - DEBUGF("recv: prioritized_stream_id=%d\n", - nghttp2_get_uint32(iframe->sbuf.pos) & NGHTTP2_STREAM_ID_MASK); - - rv = session_process_priority_update_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - session_inbound_frame_reset(session); - - break; - } - default: - /* This is unknown frame */ - session_inbound_frame_reset(session); - - break; - } - break; - case NGHTTP2_IB_READ_HEADER_BLOCK: - case NGHTTP2_IB_IGN_HEADER_BLOCK: { - nghttp2_ssize data_readlen; - size_t trail_padlen; - int final; -#ifdef DEBUGBUILD - if (iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK) { - DEBUGF("recv: [IB_READ_HEADER_BLOCK]\n"); - } else { - DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n"); - } -#endif /* DEBUGBUILD */ - - readlen = inbound_frame_payload_readlen(iframe, in, last); - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft - readlen); - - data_readlen = inbound_frame_effective_readlen( - iframe, iframe->payloadleft - readlen, readlen); - - if (data_readlen == -1) { - /* everything is padding */ - data_readlen = 0; - } - - trail_padlen = nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen); - - final = (iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) && - iframe->payloadleft - (size_t)data_readlen == trail_padlen; - - if (data_readlen > 0 || (data_readlen == 0 && final)) { - size_t hd_proclen = 0; - - DEBUGF("recv: block final=%d\n", final); - - rv = - inflate_header_block(session, &iframe->frame, &hd_proclen, - (uint8_t *)in, (size_t)data_readlen, final, - iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - if (rv == NGHTTP2_ERR_PAUSE) { - in += hd_proclen; - iframe->payloadleft -= hd_proclen; - - return (nghttp2_ssize)(in - first); - } - - if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - /* The application says no more headers. We decompress the - rest of the header block but not invoke on_header_callback - and on_frame_recv_callback. */ - in += hd_proclen; - iframe->payloadleft -= hd_proclen; - - /* Use promised stream ID for PUSH_PROMISE */ - rv = session_handle_invalid_stream2( - session, - iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE - ? iframe->frame.push_promise.promised_stream_id - : iframe->frame.hd.stream_id, - NULL, NGHTTP2_ERR_INTERNAL); - if (nghttp2_is_fatal(rv)) { - return rv; - } - busy = 1; - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - break; - } - - in += readlen; - iframe->payloadleft -= readlen; - - if (rv == NGHTTP2_ERR_HEADER_COMP) { - /* GOAWAY is already issued */ - if (iframe->payloadleft == 0) { - session_inbound_frame_reset(session); - } else { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - } - break; - } - } else { - in += readlen; - iframe->payloadleft -= readlen; - } - - if (iframe->payloadleft) { - break; - } - - if ((iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) == 0) { - inbound_frame_set_mark(iframe, NGHTTP2_FRAME_HDLEN); - - iframe->padlen = 0; - - if (iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK) { - iframe->state = NGHTTP2_IB_EXPECT_CONTINUATION; - } else { - iframe->state = NGHTTP2_IB_IGN_CONTINUATION; - } - } else { - if (iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK) { - rv = session_after_header_block_received(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - } - session_inbound_frame_reset(session); - - session->num_continuations = 0; - } - break; - } - case NGHTTP2_IB_IGN_PAYLOAD: - DEBUGF("recv: [IB_IGN_PAYLOAD]\n"); - - readlen = inbound_frame_payload_readlen(iframe, in, last); - iframe->payloadleft -= readlen; - in += readlen; - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (iframe->payloadleft) { - break; - } - - switch (iframe->frame.hd.type) { - case NGHTTP2_HEADERS: - case NGHTTP2_PUSH_PROMISE: - case NGHTTP2_CONTINUATION: - /* Mark inflater bad so that we won't perform further decoding */ - session->hd_inflater.ctx.bad = 1; - break; - default: - break; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_IB_FRAME_SIZE_ERROR: - DEBUGF("recv: [IB_FRAME_SIZE_ERROR]\n"); - - rv = session_handle_frame_size_error(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - assert(iframe->state == NGHTTP2_IB_IGN_ALL); - - return (nghttp2_ssize)inlen; - case NGHTTP2_IB_READ_SETTINGS: - DEBUGF("recv: [IB_READ_SETTINGS]\n"); - - readlen = inbound_frame_buf_read(iframe, in, last); - iframe->payloadleft -= readlen; - in += readlen; - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - break; - } - - if (readlen > 0) { - inbound_frame_set_settings_entry(iframe); - } - if (iframe->payloadleft) { - inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH); - break; - } - - rv = session_process_settings_frame(session); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_IB_READ_GOAWAY_DEBUG: - DEBUGF("recv: [IB_READ_GOAWAY_DEBUG]\n"); - - readlen = inbound_frame_payload_readlen(iframe, in, last); - - if (readlen > 0) { - iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen); - - iframe->payloadleft -= readlen; - in += readlen; - } - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (iframe->payloadleft) { - assert(nghttp2_buf_avail(&iframe->lbuf) > 0); - - break; - } - - rv = session_process_goaway_frame(session); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_IB_EXPECT_CONTINUATION: - case NGHTTP2_IB_IGN_CONTINUATION: -#ifdef DEBUGBUILD - if (iframe->state == NGHTTP2_IB_EXPECT_CONTINUATION) { - fprintf(stderr, "recv: [IB_EXPECT_CONTINUATION]\n"); - } else { - fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n"); - } -#endif /* DEBUGBUILD */ - - if (++session->num_continuations > session->max_continuations) { - return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS; - } - - readlen = inbound_frame_buf_read(iframe, in, last); - in += readlen; - - if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return (nghttp2_ssize)(in - first); - } - - nghttp2_frame_unpack_frame_hd(&cont_hd, iframe->sbuf.pos); - iframe->payloadleft = cont_hd.length; - - DEBUGF("recv: payloadlen=%zu, type=%u, flags=0x%02x, stream_id=%d\n", - cont_hd.length, cont_hd.type, cont_hd.flags, cont_hd.stream_id); - - if (cont_hd.type != NGHTTP2_CONTINUATION || - cont_hd.stream_id != iframe->frame.hd.stream_id) { - DEBUGF("recv: expected stream_id=%d, type=%d, but got stream_id=%d, " - "type=%u\n", - iframe->frame.hd.stream_id, NGHTTP2_CONTINUATION, - cont_hd.stream_id, cont_hd.type); - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "unexpected non-CONTINUATION frame or stream_id is invalid"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return (nghttp2_ssize)inlen; - } - - /* CONTINUATION won't bear NGHTTP2_PADDED flag */ - - iframe->frame.hd.flags = - (uint8_t)(iframe->frame.hd.flags | - (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS)); - iframe->frame.hd.length += cont_hd.length; - - busy = 1; - - if (iframe->state == NGHTTP2_IB_EXPECT_CONTINUATION) { - iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK; - - rv = session_call_on_begin_frame(session, &cont_hd); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - } else { - iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; - } - - break; - case NGHTTP2_IB_READ_PAD_DATA: - DEBUGF("recv: [IB_READ_PAD_DATA]\n"); - - readlen = inbound_frame_buf_read(iframe, in, last); - in += readlen; - iframe->payloadleft -= readlen; - - DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zu\n", readlen, - iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf)); - - if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return (nghttp2_ssize)(in - first); - } - - /* Pad Length field is subject to flow control */ - rv = nghttp2_session_update_recv_connection_window_size(session, readlen); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - /* Pad Length field is consumed immediately */ - rv = - nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id); - if (stream) { - rv = nghttp2_session_update_recv_stream_window_size( - session, stream, readlen, - iframe->payloadleft || - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - } - - busy = 1; - - padlen = inbound_frame_compute_pad(iframe); - if (padlen < 0) { - rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding"); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return (nghttp2_ssize)inlen; - } - - iframe->frame.data.padlen = (size_t)padlen; - - /* Empty DATA frame without END_STREAM flag set is - suspicious. */ - if (iframe->payloadleft == 0 && - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { - rv = session_update_glitch_ratelim(session); - if (rv != 0) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - } - - iframe->state = NGHTTP2_IB_READ_DATA; - - break; - case NGHTTP2_IB_READ_DATA: - stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id); - - if (!stream) { - busy = 1; - iframe->state = NGHTTP2_IB_IGN_DATA; - break; - } - - DEBUGF("recv: [IB_READ_DATA]\n"); - - readlen = inbound_frame_payload_readlen(iframe, in, last); - iframe->payloadleft -= readlen; - in += readlen; - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (readlen > 0) { - nghttp2_ssize data_readlen; - - rv = - nghttp2_session_update_recv_connection_window_size(session, readlen); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - rv = nghttp2_session_update_recv_stream_window_size( - session, stream, readlen, - iframe->payloadleft || - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - data_readlen = - inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen); - - if (data_readlen == -1) { - /* everything is padding */ - data_readlen = 0; - } - - padlen = (nghttp2_ssize)readlen - data_readlen; - - if (padlen > 0) { - /* Padding is considered as "consumed" immediately */ - rv = nghttp2_session_consume(session, iframe->frame.hd.stream_id, - (size_t)padlen); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - } - - DEBUGF("recv: data_readlen=%td\n", data_readlen); - - if (data_readlen > 0) { - if (session_enforce_http_messaging(session)) { - if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) { - rv = nghttp2_session_terminate_session(session, - NGHTTP2_PROTOCOL_ERROR); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return (nghttp2_ssize)inlen; - } - } - if (session->callbacks.on_data_chunk_recv_callback) { - rv = session->callbacks.on_data_chunk_recv_callback( - session, iframe->frame.hd.flags, iframe->frame.hd.stream_id, - in - readlen, (size_t)data_readlen, session->user_data); - if (rv == NGHTTP2_ERR_PAUSE) { - return (nghttp2_ssize)(in - first); - } - - if (nghttp2_is_fatal(rv)) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - } - } - - if (iframe->payloadleft) { - break; - } - - rv = session_process_data_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_IB_IGN_DATA: - DEBUGF("recv: [IB_IGN_DATA]\n"); - - readlen = inbound_frame_payload_readlen(iframe, in, last); - iframe->payloadleft -= readlen; - in += readlen; - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (readlen > 0) { - /* Update connection-level flow control window for ignored - DATA frame too */ - rv = - nghttp2_session_update_recv_connection_window_size(session, readlen); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - /* Ignored DATA is considered as "consumed" immediately. */ - rv = session_update_connection_consumed_size(session, readlen); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - } - } - - if (iframe->payloadleft) { - break; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_IB_IGN_ALL: - return (nghttp2_ssize)inlen; - case NGHTTP2_IB_READ_EXTENSION_PAYLOAD: - DEBUGF("recv: [IB_READ_EXTENSION_PAYLOAD]\n"); - - readlen = inbound_frame_payload_readlen(iframe, in, last); - iframe->payloadleft -= readlen; - in += readlen; - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (readlen > 0) { - rv = session_call_on_extension_chunk_recv_callback( - session, in - readlen, readlen); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (rv != 0) { - busy = 1; - - iframe->state = NGHTTP2_IB_IGN_PAYLOAD; - - break; - } - } - - if (iframe->payloadleft > 0) { - break; - } - - rv = session_process_extension_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_IB_READ_ALTSVC_PAYLOAD: - DEBUGF("recv: [IB_READ_ALTSVC_PAYLOAD]\n"); - - readlen = inbound_frame_payload_readlen(iframe, in, last); - if (readlen > 0) { - iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen); - - iframe->payloadleft -= readlen; - in += readlen; - } - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (iframe->payloadleft) { - assert(nghttp2_buf_avail(&iframe->lbuf) > 0); - - break; - } - - rv = session_process_altsvc_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - session_inbound_frame_reset(session); - - break; - case NGHTTP2_IB_READ_ORIGIN_PAYLOAD: - DEBUGF("recv: [IB_READ_ORIGIN_PAYLOAD]\n"); - - readlen = inbound_frame_payload_readlen(iframe, in, last); - - if (readlen > 0) { - iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen); - - iframe->payloadleft -= readlen; - in += readlen; - } - - DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen, - iframe->payloadleft); - - if (iframe->payloadleft) { - assert(nghttp2_buf_avail(&iframe->lbuf) > 0); - - break; - } - - rv = session_process_origin_frame(session); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (nghttp2_ssize)inlen; - } - - session_inbound_frame_reset(session); - - break; - } - - if (!busy && in == last) { - break; - } - - busy = 0; - } - - assert(in == last); - - return (nghttp2_ssize)(in - first); -} - -int nghttp2_session_recv(nghttp2_session *session) { - uint8_t buf[NGHTTP2_INBOUND_BUFFER_LENGTH]; - while (1) { - nghttp2_ssize readlen; - readlen = session_recv(session, buf, sizeof(buf)); - if (readlen > 0) { - nghttp2_ssize proclen = - nghttp2_session_mem_recv2(session, buf, (size_t)readlen); - if (proclen < 0) { - return (int)proclen; - } - assert(proclen == readlen); - } else if (readlen == 0 || readlen == NGHTTP2_ERR_WOULDBLOCK) { - return 0; - } else if (readlen == NGHTTP2_ERR_EOF) { - return NGHTTP2_ERR_EOF; - } else if (readlen < 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } -} - -/* - * Returns the number of active streams, which includes streams in - * reserved state. - */ -static size_t session_get_num_active_streams(nghttp2_session *session) { - return nghttp2_map_size(&session->streams) - session->num_closed_streams - - session->num_idle_streams; -} - -int nghttp2_session_want_read(nghttp2_session *session) { - size_t num_active_streams; - - /* If this flag is set, we don't want to read. The application - should drop the connection. */ - if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_SENT) { - return 0; - } - - num_active_streams = session_get_num_active_streams(session); - - /* Unless termination GOAWAY is sent or received, we always want to - read incoming frames. */ - - if (num_active_streams > 0) { - return 1; - } - - /* If there is no active streams and GOAWAY has been sent or - received, we are done with this session. */ - return (session->goaway_flags & - (NGHTTP2_GOAWAY_SENT | NGHTTP2_GOAWAY_RECV)) == 0; -} - -int nghttp2_session_want_write(nghttp2_session *session) { - /* If these flag is set, we don't want to write any data. The - application should drop the connection. */ - if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_SENT) { - return 0; - } - - /* - * Unless termination GOAWAY is sent or received, we want to write - * frames if there is pending ones. If pending frame is request/push - * response HEADERS and concurrent stream limit is reached, we don't - * want to write them. - */ - return session->aob.item || nghttp2_outbound_queue_top(&session->ob_urgent) || - nghttp2_outbound_queue_top(&session->ob_reg) || - (!session_sched_empty(session) && session->remote_window_size > 0) || - (nghttp2_outbound_queue_top(&session->ob_syn) && - !session_is_outgoing_concurrent_streams_max(session)); -} - -int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags, - const uint8_t *opaque_data) { - int rv; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_mem *mem; - - mem = &session->mem; - - if ((flags & NGHTTP2_FLAG_ACK) && - session->obq_flood_counter_ >= session->max_outbound_ack) { - return NGHTTP2_ERR_FLOODED; - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - - nghttp2_frame_ping_init(&frame->ping, flags, opaque_data); - - rv = nghttp2_session_add_item(session, item); - - if (rv != 0) { - nghttp2_frame_ping_free(&frame->ping); - nghttp2_mem_free(mem, item); - return rv; - } - - if (flags & NGHTTP2_FLAG_ACK) { - ++session->obq_flood_counter_; - } - - return 0; -} - -int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id, - uint32_t error_code, const uint8_t *opaque_data, - size_t opaque_data_len, uint8_t aux_flags) { - int rv; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - uint8_t *opaque_data_copy = NULL; - nghttp2_goaway_aux_data *aux_data; - nghttp2_mem *mem; - - mem = &session->mem; - - if (nghttp2_session_is_my_stream_id(session, last_stream_id)) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (opaque_data_len) { - if (opaque_data_len + 8 > NGHTTP2_MAX_PAYLOADLEN) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - opaque_data_copy = nghttp2_mem_malloc(mem, opaque_data_len); - if (opaque_data_copy == NULL) { - return NGHTTP2_ERR_NOMEM; - } - memcpy(opaque_data_copy, opaque_data, opaque_data_len); - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - nghttp2_mem_free(mem, opaque_data_copy); - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - - /* last_stream_id must not be increased from the value previously - sent */ - last_stream_id = - nghttp2_min_int32(last_stream_id, session->local_last_stream_id); - - nghttp2_frame_goaway_init(&frame->goaway, last_stream_id, error_code, - opaque_data_copy, opaque_data_len); - - aux_data = &item->aux_data.goaway; - aux_data->flags = aux_flags; - - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - nghttp2_frame_goaway_free(&frame->goaway, mem); - nghttp2_mem_free(mem, item); - return rv; - } - - session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED; - - return 0; -} - -int nghttp2_session_add_window_update(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - int32_t window_size_increment) { - int rv; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_mem *mem; - - mem = &session->mem; - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - - nghttp2_frame_window_update_init(&frame->window_update, flags, stream_id, - window_size_increment); - - rv = nghttp2_session_add_item(session, item); - - if (rv != 0) { - nghttp2_frame_window_update_free(&frame->window_update); - nghttp2_mem_free(mem, item); - return rv; - } - return 0; -} - -static void -session_append_inflight_settings(nghttp2_session *session, - nghttp2_inflight_settings *settings) { - nghttp2_inflight_settings **i; - - for (i = &session->inflight_settings_head; *i; i = &(*i)->next) - ; - - *i = settings; -} - -int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags, - const nghttp2_settings_entry *iv, size_t niv) { - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_settings_entry *iv_copy; - size_t i; - int rv; - nghttp2_mem *mem; - nghttp2_inflight_settings *inflight_settings = NULL; - uint8_t no_rfc7540_pri = session->pending_no_rfc7540_priorities; - - mem = &session->mem; - - if (flags & NGHTTP2_FLAG_ACK) { - if (niv != 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (session->obq_flood_counter_ >= session->max_outbound_ack) { - return NGHTTP2_ERR_FLOODED; - } - } - - if (!nghttp2_iv_check(iv, niv)) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - for (i = 0; i < niv; ++i) { - if (iv[i].settings_id != NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES) { - continue; - } - - if (no_rfc7540_pri == UINT8_MAX) { - no_rfc7540_pri = (uint8_t)iv[i].value; - continue; - } - - if (iv[i].value != (uint32_t)no_rfc7540_pri) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - if (niv > 0) { - iv_copy = nghttp2_frame_iv_copy(iv, niv, mem); - if (iv_copy == NULL) { - nghttp2_mem_free(mem, item); - return NGHTTP2_ERR_NOMEM; - } - } else { - iv_copy = NULL; - } - - if ((flags & NGHTTP2_FLAG_ACK) == 0) { - rv = inflight_settings_new(&inflight_settings, iv, niv, mem); - if (rv != 0) { - assert(nghttp2_is_fatal(rv)); - nghttp2_mem_free(mem, iv_copy); - nghttp2_mem_free(mem, item); - return rv; - } - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - - nghttp2_frame_settings_init(&frame->settings, flags, iv_copy, niv); - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - /* The only expected error is fatal one */ - assert(nghttp2_is_fatal(rv)); - - inflight_settings_del(inflight_settings, mem); - - nghttp2_frame_settings_free(&frame->settings, mem); - nghttp2_mem_free(mem, item); - - return rv; - } - - if (flags & NGHTTP2_FLAG_ACK) { - ++session->obq_flood_counter_; - } else { - session_append_inflight_settings(session, inflight_settings); - } - - /* Extract NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS and ENABLE_PUSH - here. We use it to refuse the incoming stream and PUSH_PROMISE - with RST_STREAM. */ - - for (i = niv; i > 0; --i) { - if (iv[i - 1].settings_id == NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS) { - session->pending_local_max_concurrent_stream = iv[i - 1].value; - break; - } - } - - for (i = niv; i > 0; --i) { - if (iv[i - 1].settings_id == NGHTTP2_SETTINGS_ENABLE_PUSH) { - session->pending_enable_push = (uint8_t)iv[i - 1].value; - break; - } - } - - for (i = niv; i > 0; --i) { - if (iv[i - 1].settings_id == NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL) { - session->pending_enable_connect_protocol = (uint8_t)iv[i - 1].value; - break; - } - } - - if (no_rfc7540_pri == UINT8_MAX) { - session->pending_no_rfc7540_priorities = 0; - } else { - session->pending_no_rfc7540_priorities = no_rfc7540_pri; - } - - return 0; -} - -int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs, - size_t datamax, nghttp2_frame *frame, - nghttp2_data_aux_data *aux_data, - nghttp2_stream *stream) { - int rv; - uint32_t data_flags; - nghttp2_ssize payloadlen; - nghttp2_ssize padded_payloadlen; - nghttp2_buf *buf; - size_t max_payloadlen; - - assert(bufs->head == bufs->cur); - - buf = &bufs->cur->buf; - - if (session->callbacks.read_length_callback2 || - session->callbacks.read_length_callback) { - if (session->callbacks.read_length_callback2) { - payloadlen = session->callbacks.read_length_callback2( - session, frame->hd.type, stream->stream_id, session->remote_window_size, - stream->remote_window_size, session->remote_settings.max_frame_size, - session->user_data); - } else { - payloadlen = (nghttp2_ssize)session->callbacks.read_length_callback( - session, frame->hd.type, stream->stream_id, session->remote_window_size, - stream->remote_window_size, session->remote_settings.max_frame_size, - session->user_data); - } - - DEBUGF("send: read_length_callback=%td\n", payloadlen); - - payloadlen = - nghttp2_session_enforce_flow_control_limits(session, stream, payloadlen); - - DEBUGF("send: read_length_callback after flow control=%td\n", payloadlen); - - if (payloadlen <= 0) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - if ((size_t)payloadlen > nghttp2_buf_avail(buf)) { - /* Resize the current buffer(s). The reason why we do +1 for - buffer size is for possible padding field. */ - rv = nghttp2_bufs_realloc(&session->aob.framebufs, - (size_t)(NGHTTP2_FRAME_HDLEN + 1 + payloadlen)); - - if (rv != 0) { - DEBUGF("send: realloc buffer failed rv=%d", rv); - /* If reallocation failed, old buffers are still in tact. So - use safe limit. */ - payloadlen = (nghttp2_ssize)datamax; - - DEBUGF("send: use safe limit payloadlen=%td", payloadlen); - } else { - assert(&session->aob.framebufs == bufs); - - buf = &bufs->cur->buf; - } - } - datamax = (size_t)payloadlen; - } - - /* Current max DATA length is less then buffer chunk size */ - assert(nghttp2_buf_avail(buf) >= datamax); - - data_flags = NGHTTP2_DATA_FLAG_NONE; - switch (aux_data->dpw.version) { - case NGHTTP2_DATA_PROVIDER_V1: - payloadlen = (nghttp2_ssize)aux_data->dpw.data_prd.v1.read_callback( - session, frame->hd.stream_id, buf->pos, datamax, &data_flags, - &aux_data->dpw.data_prd.source, session->user_data); - - break; - case NGHTTP2_DATA_PROVIDER_V2: - payloadlen = aux_data->dpw.data_prd.v2.read_callback( - session, frame->hd.stream_id, buf->pos, datamax, &data_flags, - &aux_data->dpw.data_prd.source, session->user_data); - - break; - default: - assert(0); - abort(); - } - - if (payloadlen == NGHTTP2_ERR_DEFERRED || - payloadlen == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE || - payloadlen == NGHTTP2_ERR_PAUSE) { - DEBUGF("send: DATA postponed due to %s\n", - nghttp2_strerror((int)payloadlen)); - - return (int)payloadlen; - } - - if (payloadlen < 0 || datamax < (size_t)payloadlen) { - /* This is the error code when callback is failed. */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - buf->last = buf->pos + payloadlen; - buf->pos -= NGHTTP2_FRAME_HDLEN; - - /* Clear flags, because this may contain previous flags of previous - DATA */ - frame->hd.flags = NGHTTP2_FLAG_NONE; - - if (data_flags & NGHTTP2_DATA_FLAG_EOF) { - aux_data->eof = 1; - /* If NGHTTP2_DATA_FLAG_NO_END_STREAM is set, don't set - NGHTTP2_FLAG_END_STREAM */ - if ((aux_data->flags & NGHTTP2_FLAG_END_STREAM) && - (data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM) == 0) { - frame->hd.flags |= NGHTTP2_FLAG_END_STREAM; - } - } - - if (data_flags & NGHTTP2_DATA_FLAG_NO_COPY) { - if (session->callbacks.send_data_callback == NULL) { - DEBUGF("NGHTTP2_DATA_FLAG_NO_COPY requires send_data_callback set\n"); - - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - aux_data->no_copy = 1; - } - - frame->hd.length = (size_t)payloadlen; - frame->data.padlen = 0; - - max_payloadlen = - nghttp2_min_size(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN); - - padded_payloadlen = - session_call_select_padding(session, frame, max_payloadlen); - - if (nghttp2_is_fatal((int)padded_payloadlen)) { - return (int)padded_payloadlen; - } - - frame->data.padlen = (size_t)(padded_payloadlen - payloadlen); - - nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - - nghttp2_frame_add_pad(bufs, &frame->hd, frame->data.padlen, - aux_data->no_copy); - - session_reschedule_stream(session, stream); - - if (frame->hd.length == 0 && (data_flags & NGHTTP2_DATA_FLAG_EOF) && - (data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM)) { - /* DATA payload length is 0, and DATA frame does not bear - END_STREAM. In this case, there is no point to send 0 length - DATA frame. */ - return NGHTTP2_ERR_CANCEL; - } - - return 0; -} - -void *nghttp2_session_get_stream_user_data(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - stream = nghttp2_session_get_stream(session, stream_id); - if (stream) { - return stream->stream_user_data; - } else { - return NULL; - } -} - -int nghttp2_session_set_stream_user_data(nghttp2_session *session, - int32_t stream_id, - void *stream_user_data) { - nghttp2_stream *stream; - nghttp2_frame *frame; - nghttp2_outbound_item *item; - - stream = nghttp2_session_get_stream(session, stream_id); - if (stream) { - stream->stream_user_data = stream_user_data; - return 0; - } - - if (session->server || !nghttp2_session_is_my_stream_id(session, stream_id) || - !nghttp2_outbound_queue_top(&session->ob_syn)) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame; - assert(frame->hd.type == NGHTTP2_HEADERS); - - if (frame->hd.stream_id > stream_id || - (uint32_t)stream_id >= session->next_stream_id) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - for (item = session->ob_syn.head; item; item = item->qnext) { - if (item->frame.hd.stream_id < stream_id) { - continue; - } - - if (item->frame.hd.stream_id > stream_id) { - break; - } - - item->aux_data.headers.stream_user_data = stream_user_data; - return 0; - } - - return NGHTTP2_ERR_INVALID_ARGUMENT; -} - -int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id) { - int rv; - nghttp2_stream *stream; - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL || !nghttp2_stream_check_deferred_item(stream)) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - rv = session_resume_deferred_stream_item(session, stream, - NGHTTP2_STREAM_FLAG_DEFERRED_USER); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return 0; -} - -size_t nghttp2_session_get_outbound_queue_size(nghttp2_session *session) { - return nghttp2_outbound_queue_size(&session->ob_urgent) + - nghttp2_outbound_queue_size(&session->ob_reg) + - nghttp2_outbound_queue_size(&session->ob_syn); - /* TODO account for item attached to stream */ -} - -int32_t -nghttp2_session_get_stream_effective_recv_data_length(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL) { - return -1; - } - return stream->recv_window_size < 0 ? 0 : stream->recv_window_size; -} - -int32_t -nghttp2_session_get_stream_effective_local_window_size(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL) { - return -1; - } - return stream->local_window_size; -} - -int32_t nghttp2_session_get_stream_local_window_size(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - int32_t size; - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL) { - return -1; - } - - size = stream->local_window_size - stream->recv_window_size; - - /* size could be negative if local endpoint reduced - SETTINGS_INITIAL_WINDOW_SIZE */ - if (size < 0) { - return 0; - } - - return size; -} - -int32_t -nghttp2_session_get_effective_recv_data_length(nghttp2_session *session) { - return session->recv_window_size < 0 ? 0 : session->recv_window_size; -} - -int32_t -nghttp2_session_get_effective_local_window_size(nghttp2_session *session) { - return session->local_window_size; -} - -int32_t nghttp2_session_get_local_window_size(nghttp2_session *session) { - return session->local_window_size - session->recv_window_size; -} - -int32_t nghttp2_session_get_stream_remote_window_size(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - - stream = nghttp2_session_get_stream(session, stream_id); - if (stream == NULL) { - return -1; - } - - /* stream->remote_window_size can be negative when - SETTINGS_INITIAL_WINDOW_SIZE is changed. */ - return nghttp2_max_int32(0, stream->remote_window_size); -} - -int32_t nghttp2_session_get_remote_window_size(nghttp2_session *session) { - return session->remote_window_size; -} - -uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session, - nghttp2_settings_id id) { - switch (id) { - case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: - return session->remote_settings.header_table_size; - case NGHTTP2_SETTINGS_ENABLE_PUSH: - return session->remote_settings.enable_push; - case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: - return session->remote_settings.max_concurrent_streams; - case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - return session->remote_settings.initial_window_size; - case NGHTTP2_SETTINGS_MAX_FRAME_SIZE: - return session->remote_settings.max_frame_size; - case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: - return session->remote_settings.max_header_list_size; - case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL: - return session->remote_settings.enable_connect_protocol; - case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES: - return session->remote_settings.no_rfc7540_priorities; - } - - assert(0); - abort(); /* if NDEBUG is set */ -} - -uint32_t nghttp2_session_get_local_settings(nghttp2_session *session, - nghttp2_settings_id id) { - switch (id) { - case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: - return session->local_settings.header_table_size; - case NGHTTP2_SETTINGS_ENABLE_PUSH: - return session->local_settings.enable_push; - case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: - return session->local_settings.max_concurrent_streams; - case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: - return session->local_settings.initial_window_size; - case NGHTTP2_SETTINGS_MAX_FRAME_SIZE: - return session->local_settings.max_frame_size; - case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: - return session->local_settings.max_header_list_size; - case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL: - return session->local_settings.enable_connect_protocol; - case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES: - return session->local_settings.no_rfc7540_priorities; - } - - assert(0); - abort(); /* if NDEBUG is set */ -} - -static int nghttp2_session_upgrade_internal(nghttp2_session *session, - const uint8_t *settings_payload, - size_t settings_payloadlen, - void *stream_user_data) { - nghttp2_stream *stream; - nghttp2_frame frame; - nghttp2_settings_entry *iv; - size_t niv; - int rv; - nghttp2_mem *mem; - - mem = &session->mem; - - if ((!session->server && session->next_stream_id != 1) || - (session->server && session->last_recv_stream_id >= 1)) { - return NGHTTP2_ERR_PROTO; - } - if (settings_payloadlen % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - /* SETTINGS frame contains too many settings */ - if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH > - session->max_settings) { - return NGHTTP2_ERR_TOO_MANY_SETTINGS; - } - rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload, - settings_payloadlen, mem); - if (rv != 0) { - return rv; - } - - if (session->server) { - nghttp2_frame_hd_init(&frame.hd, settings_payloadlen, NGHTTP2_SETTINGS, - NGHTTP2_FLAG_NONE, 0); - frame.settings.iv = iv; - frame.settings.niv = niv; - rv = nghttp2_session_on_settings_received(session, &frame, 1 /* No ACK */); - } else { - rv = nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, niv); - } - nghttp2_mem_free(mem, iv); - if (rv != 0) { - return rv; - } - - stream = nghttp2_session_open_stream( - session, 1, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_OPENING, - session->server ? NULL : stream_user_data); - if (stream == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - if (session->server) { - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - session->last_recv_stream_id = 1; - session->last_proc_stream_id = 1; - } else { - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR); - session->last_sent_stream_id = 1; - session->next_stream_id += 2; - } - return 0; -} - -int nghttp2_session_upgrade(nghttp2_session *session, - const uint8_t *settings_payload, - size_t settings_payloadlen, - void *stream_user_data) { - int rv; - nghttp2_stream *stream; - - rv = nghttp2_session_upgrade_internal(session, settings_payload, - settings_payloadlen, stream_user_data); - if (rv != 0) { - return rv; - } - - stream = nghttp2_session_get_stream(session, 1); - assert(stream); - - /* We have no information about request header fields when Upgrade - was happened. So we don't know the request method here. If - request method is HEAD, we have a trouble because we may have - nonzero content-length header field in response headers, and we - will going to check it against the actual DATA frames, but we may - get mismatch because HEAD response body must be empty. Because - of this reason, nghttp2_session_upgrade() was deprecated in favor - of nghttp2_session_upgrade2(), which has |head_request| parameter - to indicate that request method is HEAD or not. */ - stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND; - return 0; -} - -int nghttp2_session_upgrade2(nghttp2_session *session, - const uint8_t *settings_payload, - size_t settings_payloadlen, int head_request, - void *stream_user_data) { - int rv; - nghttp2_stream *stream; - - rv = nghttp2_session_upgrade_internal(session, settings_payload, - settings_payloadlen, stream_user_data); - if (rv != 0) { - return rv; - } - - stream = nghttp2_session_get_stream(session, 1); - assert(stream); - - if (head_request) { - stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD; - } - - return 0; -} - -int nghttp2_session_get_stream_local_close(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - - stream = nghttp2_session_get_stream(session, stream_id); - - if (!stream) { - return -1; - } - - return (stream->shut_flags & NGHTTP2_SHUT_WR) != 0; -} - -int nghttp2_session_get_stream_remote_close(nghttp2_session *session, - int32_t stream_id) { - nghttp2_stream *stream; - - stream = nghttp2_session_get_stream(session, stream_id); - - if (!stream) { - return -1; - } - - return (stream->shut_flags & NGHTTP2_SHUT_RD) != 0; -} - -int nghttp2_session_consume(nghttp2_session *session, int32_t stream_id, - size_t size) { - int rv; - nghttp2_stream *stream; - - if (stream_id == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) { - return NGHTTP2_ERR_INVALID_STATE; - } - - rv = session_update_connection_consumed_size(session, size); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - stream = nghttp2_session_get_stream(session, stream_id); - - if (!stream) { - return 0; - } - - rv = session_update_stream_consumed_size(session, stream, size); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return 0; -} - -int nghttp2_session_consume_connection(nghttp2_session *session, size_t size) { - int rv; - - if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) { - return NGHTTP2_ERR_INVALID_STATE; - } - - rv = session_update_connection_consumed_size(session, size); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return 0; -} - -int nghttp2_session_consume_stream(nghttp2_session *session, int32_t stream_id, - size_t size) { - int rv; - nghttp2_stream *stream; - - if (stream_id == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) { - return NGHTTP2_ERR_INVALID_STATE; - } - - stream = nghttp2_session_get_stream(session, stream_id); - - if (!stream) { - return 0; - } - - rv = session_update_stream_consumed_size(session, stream, size); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - return 0; -} - -int nghttp2_session_set_next_stream_id(nghttp2_session *session, - int32_t next_stream_id) { - if (next_stream_id <= 0 || - session->next_stream_id > (uint32_t)next_stream_id) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (session->server) { - if (next_stream_id % 2) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - } else if (next_stream_id % 2 == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - session->next_stream_id = (uint32_t)next_stream_id; - return 0; -} - -uint32_t nghttp2_session_get_next_stream_id(nghttp2_session *session) { - return session->next_stream_id; -} - -int32_t nghttp2_session_get_last_proc_stream_id(nghttp2_session *session) { - return session->last_proc_stream_id; -} - -nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session, - int32_t stream_id) { - if (stream_id == 0) { - return &nghttp2_stream_root; - } - - return nghttp2_session_get_stream_raw(session, stream_id); -} - -nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) { - (void)session; - - return &nghttp2_stream_root; -} - -int nghttp2_session_check_server_session(nghttp2_session *session) { - return session->server; -} - -int nghttp2_session_change_stream_priority( - nghttp2_session *session, int32_t stream_id, - const nghttp2_priority_spec *pri_spec) { - (void)session; - (void)stream_id; - (void)pri_spec; - - return 0; -} - -int nghttp2_session_create_idle_stream(nghttp2_session *session, - int32_t stream_id, - const nghttp2_priority_spec *pri_spec) { - (void)session; - (void)stream_id; - (void)pri_spec; - - return 0; -} - -size_t -nghttp2_session_get_hd_inflate_dynamic_table_size(nghttp2_session *session) { - return nghttp2_hd_inflate_get_dynamic_table_size(&session->hd_inflater); -} - -size_t -nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session) { - return nghttp2_hd_deflate_get_dynamic_table_size(&session->hd_deflater); -} - -void nghttp2_session_set_user_data(nghttp2_session *session, void *user_data) { - session->user_data = user_data; -} - -int nghttp2_session_change_extpri_stream_priority( - nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri_in, - int ignore_client_signal) { - nghttp2_stream *stream; - nghttp2_extpri extpri = *extpri_in; - - if (!session->server) { - return NGHTTP2_ERR_INVALID_STATE; - } - - if (session->pending_no_rfc7540_priorities != 1) { - return 0; - } - - if (stream_id == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - stream = nghttp2_session_get_stream_raw(session, stream_id); - if (!stream) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (extpri.urgency > NGHTTP2_EXTPRI_URGENCY_LOW) { - extpri.urgency = NGHTTP2_EXTPRI_URGENCY_LOW; - } - - if (ignore_client_signal) { - stream->flags |= NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES; - } - - return session_update_stream_priority(session, stream, - nghttp2_extpri_to_uint8(&extpri)); -} - -int nghttp2_session_get_extpri_stream_priority(nghttp2_session *session, - nghttp2_extpri *extpri, - int32_t stream_id) { - nghttp2_stream *stream; - - if (!session->server) { - return NGHTTP2_ERR_INVALID_STATE; - } - - if (session->pending_no_rfc7540_priorities != 1) { - return 0; - } - - if (stream_id == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - stream = nghttp2_session_get_stream_raw(session, stream_id); - if (!stream) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - nghttp2_extpri_from_uint8(extpri, stream->extpri); - - return 0; -} diff --git a/vendor/nghttp2/lib/nghttp2_session.h b/vendor/nghttp2/lib/nghttp2_session.h deleted file mode 100644 index 25f300d23..000000000 --- a/vendor/nghttp2/lib/nghttp2_session.h +++ /dev/null @@ -1,895 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_SESSION_H -#define NGHTTP2_SESSION_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include "nghttp2_map.h" -#include "nghttp2_frame.h" -#include "nghttp2_hd.h" -#include "nghttp2_stream.h" -#include "nghttp2_outbound_item.h" -#include "nghttp2_int.h" -#include "nghttp2_buf.h" -#include "nghttp2_callbacks.h" -#include "nghttp2_mem.h" -#include "nghttp2_ratelim.h" - -/* The global variable for tests where we want to disable strict - preface handling. */ -extern int nghttp2_enable_strict_preface; - -extern nghttp2_stream nghttp2_stream_root; - -/* - * Option flags. - */ -typedef enum { - NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0, - NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1, - NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2, - NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3, - NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 6, -} nghttp2_optmask; - -/* - * bitmask for built-in type to enable the default handling for that - * type of the frame. - */ -typedef enum { - NGHTTP2_TYPEMASK_NONE = 0, - NGHTTP2_TYPEMASK_ALTSVC = 1 << 0, - NGHTTP2_TYPEMASK_ORIGIN = 1 << 1, - NGHTTP2_TYPEMASK_PRIORITY_UPDATE = 1 << 2 -} nghttp2_typemask; - -typedef enum { - NGHTTP2_OB_POP_ITEM, - NGHTTP2_OB_SEND_DATA, - NGHTTP2_OB_SEND_NO_COPY, - NGHTTP2_OB_SEND_CLIENT_MAGIC -} nghttp2_outbound_state; - -typedef struct { - nghttp2_outbound_item *item; - nghttp2_bufs framebufs; - nghttp2_outbound_state state; -} nghttp2_active_outbound_item; - -/* Buffer length for inbound raw byte stream used in - nghttp2_session_recv(). */ -#define NGHTTP2_INBOUND_BUFFER_LENGTH 16384 - -/* The default maximum number of incoming reserved streams */ -#define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200 - -/* The maximum number of items in outbound queue, which is considered - as flooding caused by peer. All frames are not considered here. - We only consider PING + ACK and SETTINGS + ACK. This is because - they both are response to the frame initiated by peer and peer can - send as many of them as they want. If peer does not read network, - response frames are stacked up, which leads to memory exhaustion. - The value selected here is arbitrary, but safe value and if we have - these frames in this number, it is considered suspicious. */ -#define NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM 1000 - -/* The default value of maximum number of concurrent streams. */ -#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu - -/* The default values for stream reset rate limiter. */ -#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000 -#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33 - -/* The default values for glitch rate limiter. */ -#define NGHTTP2_DEFAULT_GLITCH_BURST 1000 -#define NGHTTP2_DEFAULT_GLITCH_RATE 33 - -/* The default max number of CONTINUATION frames following an incoming - HEADER frame. */ -#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8 - -/* Internal state when receiving incoming frame */ -typedef enum { - /* Receiving frame header */ - NGHTTP2_IB_READ_CLIENT_MAGIC, - NGHTTP2_IB_READ_FIRST_SETTINGS, - NGHTTP2_IB_READ_HEAD, - NGHTTP2_IB_READ_NBYTE, - NGHTTP2_IB_READ_HEADER_BLOCK, - NGHTTP2_IB_IGN_HEADER_BLOCK, - NGHTTP2_IB_IGN_PAYLOAD, - NGHTTP2_IB_FRAME_SIZE_ERROR, - NGHTTP2_IB_READ_SETTINGS, - NGHTTP2_IB_READ_GOAWAY_DEBUG, - NGHTTP2_IB_EXPECT_CONTINUATION, - NGHTTP2_IB_IGN_CONTINUATION, - NGHTTP2_IB_READ_PAD_DATA, - NGHTTP2_IB_READ_DATA, - NGHTTP2_IB_IGN_DATA, - NGHTTP2_IB_IGN_ALL, - NGHTTP2_IB_READ_ALTSVC_PAYLOAD, - NGHTTP2_IB_READ_ORIGIN_PAYLOAD, - NGHTTP2_IB_READ_EXTENSION_PAYLOAD -} nghttp2_inbound_state; - -typedef struct { - nghttp2_frame frame; - /* Storage for extension frame payload. frame->ext.payload points - to this structure to avoid frequent memory allocation. */ - nghttp2_ext_frame_payload ext_frame_payload; - /* The received SETTINGS entry. For the standard settings entries, - we only keep the last seen value. For - SETTINGS_HEADER_TABLE_SIZE, we also keep minimum value in the - last index. */ - nghttp2_settings_entry *iv; - /* buffer pointers to small buffer, raw_sbuf */ - nghttp2_buf sbuf; - /* buffer pointers to large buffer, raw_lbuf */ - nghttp2_buf lbuf; - /* Large buffer, malloced on demand */ - uint8_t *raw_lbuf; - /* The number of entry filled in |iv| */ - size_t niv; - /* The number of entries |iv| can store. */ - size_t max_niv; - /* How many bytes we still need to receive for current frame */ - size_t payloadleft; - /* padding length for the current frame */ - size_t padlen; - nghttp2_inbound_state state; - /* Small fixed sized buffer. */ - uint8_t raw_sbuf[32]; -} nghttp2_inbound_frame; - -typedef struct { - uint32_t header_table_size; - uint32_t enable_push; - uint32_t max_concurrent_streams; - uint32_t initial_window_size; - uint32_t max_frame_size; - uint32_t max_header_list_size; - uint32_t enable_connect_protocol; - uint32_t no_rfc7540_priorities; -} nghttp2_settings_storage; - -typedef enum { - NGHTTP2_GOAWAY_NONE = 0, - /* Flag means that connection should be terminated after sending GOAWAY. */ - NGHTTP2_GOAWAY_TERM_ON_SEND = 0x1, - /* Flag means GOAWAY to terminate session has been sent */ - NGHTTP2_GOAWAY_TERM_SENT = 0x2, - /* Flag means GOAWAY was sent */ - NGHTTP2_GOAWAY_SENT = 0x4, - /* Flag means GOAWAY was received */ - NGHTTP2_GOAWAY_RECV = 0x8, - /* Flag means GOAWAY has been submitted at least once */ - NGHTTP2_GOAWAY_SUBMITTED = 0x10 -} nghttp2_goaway_flag; - -/* nghttp2_inflight_settings stores the SETTINGS entries which local - endpoint has sent to the remote endpoint, and has not received ACK - yet. */ -struct nghttp2_inflight_settings { - struct nghttp2_inflight_settings *next; - nghttp2_settings_entry *iv; - size_t niv; -}; - -typedef struct nghttp2_inflight_settings nghttp2_inflight_settings; - -struct nghttp2_session { - nghttp2_map /* */ streams; - /* Queue for outbound urgent frames (PING and SETTINGS) */ - nghttp2_outbound_queue ob_urgent; - /* Queue for non-DATA frames */ - nghttp2_outbound_queue ob_reg; - /* Queue for outbound stream-creating HEADERS (request or push - response) frame, which are subject to - SETTINGS_MAX_CONCURRENT_STREAMS limit. */ - nghttp2_outbound_queue ob_syn; - /* Queues for DATA frames which is used when - SETTINGS_NO_RFC7540_PRIORITIES is enabled. This implements RFC - 9218 extensible prioritization scheme. */ - struct { - nghttp2_pq ob_data; - } sched[NGHTTP2_EXTPRI_URGENCY_LEVELS]; - nghttp2_active_outbound_item aob; - nghttp2_inbound_frame iframe; - nghttp2_hd_deflater hd_deflater; - nghttp2_hd_inflater hd_inflater; - nghttp2_session_callbacks callbacks; - /* Memory allocator */ - nghttp2_mem mem; - void *user_data; - /* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not - considered as in-flight. */ - nghttp2_inflight_settings *inflight_settings_head; - /* Stream reset rate limiter. If receiving excessive amount of - stream resets, GOAWAY will be sent. */ - nghttp2_ratelim stream_reset_ratelim; - /* Rate limiter for all kinds of glitches. */ - nghttp2_ratelim glitch_ratelim; - /* Sequential number across all streams to process streams in - FIFO. */ - uint64_t stream_seq; - /* The number of outgoing streams. This will be capped by - remote_settings.max_concurrent_streams. */ - size_t num_outgoing_streams; - /* The number of incoming streams. This will be capped by - local_settings.max_concurrent_streams. */ - size_t num_incoming_streams; - /* The number of incoming reserved streams. This is the number of - streams in reserved (remote) state. RFC 7540 does not limit this - number. nghttp2 offers - nghttp2_option_set_max_reserved_remote_streams() to achieve this. - If it is used, num_incoming_streams is capped by - max_incoming_reserved_streams. Client application should - consider to set this because without that server can send - arbitrary number of PUSH_PROMISE, and exhaust client's memory. */ - size_t num_incoming_reserved_streams; - /* The maximum number of incoming reserved streams (reserved - (remote) state). RST_STREAM will be sent for the pushed stream - which exceeds this limit. */ - size_t max_incoming_reserved_streams; - /* The number of closed streams still kept in |streams| hash. The - closed streams can be accessed through single linked list - |closed_stream_head|. The current implementation only keeps - incoming streams and session is initialized as server. */ - size_t num_closed_streams; - /* The number of idle streams kept in |streams| hash. The current - implementation only keeps idle streams if session is initialized - as server. */ - size_t num_idle_streams; - /* The number of bytes allocated for nvbuf */ - size_t nvbuflen; - /* Counter for detecting flooding in outbound queue. If it exceeds - max_outbound_ack, session will be closed. */ - size_t obq_flood_counter_; - /* The maximum number of outgoing SETTINGS ACK and PING ACK in - outbound queue. */ - size_t max_outbound_ack; - /* The maximum length of header block to send. Calculated by the - same way as nghttp2_hd_deflate_bound() does. */ - size_t max_send_header_block_length; - /* The maximum number of settings accepted per SETTINGS frame. */ - size_t max_settings; - /* The maximum number of CONTINUATION frames following an incoming - HEADER frame. */ - size_t max_continuations; - /* The number of CONTINUATION frames following an incoming HEADER - frame. This variable is reset when END_HEADERS flag is seen. */ - size_t num_continuations; - /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */ - uint32_t next_stream_id; - /* The last stream ID this session initiated. For client session, - this is the last stream ID it has sent. For server session, it - is the last promised stream ID sent in PUSH_PROMISE. */ - int32_t last_sent_stream_id; - /* The largest stream ID received so far */ - int32_t last_recv_stream_id; - /* The largest stream ID which has been processed in some way. This - value will be used as last-stream-id when sending GOAWAY - frame. */ - int32_t last_proc_stream_id; - /* Counter of unique ID of PING. Wraps when it exceeds - NGHTTP2_MAX_UNIQUE_ID */ - uint32_t next_unique_id; - /* This is the last-stream-ID we have sent in GOAWAY */ - int32_t local_last_stream_id; - /* This is the value in GOAWAY frame received from remote endpoint. */ - int32_t remote_last_stream_id; - /* Current sender window size. This value is computed against the - current initial window size of remote endpoint. */ - int32_t remote_window_size; - /* Keep track of the number of bytes received without - WINDOW_UPDATE. This could be negative after submitting negative - value to WINDOW_UPDATE. */ - int32_t recv_window_size; - /* The number of bytes consumed by the application and now is - subject to WINDOW_UPDATE. This is only used when auto - WINDOW_UPDATE is turned off. */ - int32_t consumed_size; - /* The amount of recv_window_size cut using submitting negative - value to WINDOW_UPDATE */ - int32_t recv_reduction; - /* window size for local flow control. It is initially set to - NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE and could be - increased/decreased by submitting WINDOW_UPDATE. See - nghttp2_submit_window_update(). */ - int32_t local_window_size; - /* This flag is used to indicate that the local endpoint received initial - SETTINGS frame from the remote endpoint. */ - uint8_t remote_settings_received; - /* Settings value received from the remote endpoint. */ - nghttp2_settings_storage remote_settings; - /* Settings value of the local endpoint. */ - nghttp2_settings_storage local_settings; - /* Option flags. This is bitwise-OR of 0 or more of nghttp2_optmask. */ - uint32_t opt_flags; - /* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this - to refuse the incoming stream if it exceeds this value. */ - uint32_t pending_local_max_concurrent_stream; - /* The bitwise OR of zero or more of nghttp2_typemask to indicate - that the default handling of extension frame is enabled. */ - uint32_t builtin_recv_ext_types; - /* Unacked local ENABLE_PUSH value. We use this to refuse - PUSH_PROMISE before SETTINGS ACK is received. */ - uint8_t pending_enable_push; - /* Unacked local ENABLE_CONNECT_PROTOCOL value. We use this to - accept :protocol header field before SETTINGS_ACK is received. */ - uint8_t pending_enable_connect_protocol; - /* Unacked local SETTINGS_NO_RFC7540_PRIORITIES value, which is - effective before it is acknowledged. */ - uint8_t pending_no_rfc7540_priorities; - /* Nonzero if the session is server side. */ - uint8_t server; - /* Flags indicating GOAWAY is sent and/or received. The flags are - composed by bitwise OR-ing nghttp2_goaway_flag. */ - uint8_t goaway_flags; - /* This flag is used to reduce excessive queuing of WINDOW_UPDATE to - this session. The nonzero does not necessarily mean - WINDOW_UPDATE is not queued. */ - uint8_t window_update_queued; - /* Bitfield of extension frame types that application is willing to - receive. To designate the bit of given frame type i, use - user_recv_ext_types[i / 8] & (1 << (i & 0x7)). First 10 frame - types are standard frame types and not used in this bitfield. If - bit is set, it indicates that incoming frame with that type is - passed to user defined callbacks, otherwise they are ignored. */ - uint8_t user_recv_ext_types[32]; -}; - -/* Struct used when updating initial window size of each active - stream. */ -typedef struct { - nghttp2_session *session; - int32_t new_window_size, old_window_size; -} nghttp2_update_window_size_arg; - -typedef struct { - nghttp2_session *session; - /* linked list of streams to close */ - nghttp2_stream *head; - int32_t last_stream_id; - /* nonzero if GOAWAY is sent to peer, which means we are going to - close incoming streams. zero if GOAWAY is received from peer and - we are going to close outgoing streams. */ - int incoming; -} nghttp2_close_stream_on_goaway_arg; - -/* TODO stream timeout etc */ - -/* - * Returns nonzero value if |stream_id| is initiated by local - * endpoint. - */ -int nghttp2_session_is_my_stream_id(nghttp2_session *session, - int32_t stream_id); - -/* - * Adds |item| to the outbound queue in |session|. When this function - * succeeds, it takes ownership of |item|. So caller must not free it - * on success. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_STREAM_CLOSED - * Stream already closed (DATA and PUSH_PROMISE frame only) - */ -int nghttp2_session_add_item(nghttp2_session *session, - nghttp2_outbound_item *item); - -/* - * This function wraps around nghttp2_session_add_rst_stream_continue - * with continue_without_stream = 1. - */ -int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, - uint32_t error_code); - -/* - * Adds RST_STREAM frame for the stream |stream_id| with the error - * code |error_code|. This is a convenient function built on top of - * nghttp2_session_add_frame() to add RST_STREAM easily. - * - * This function simply returns 0 without adding RST_STREAM frame if - * given stream is in NGHTTP2_STREAM_CLOSING state, because multiple - * RST_STREAM for a stream is redundant. It also returns 0 without - * adding the frame if |continue_without_stream| is nonzero, and - * stream was already gone. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_session_add_rst_stream_continue(nghttp2_session *session, - int32_t stream_id, - uint32_t error_code, - int continue_without_stream); - -/* - * Adds PING frame. This is a convenient function built on top of - * nghttp2_session_add_frame() to add PING easily. - * - * If the |opaque_data| is not NULL, it must point to 8 bytes memory - * region of data. The data pointed by |opaque_data| is copied. It can - * be NULL. In this case, 8 bytes NULL is used. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FLOODED - * There are too many items in outbound queue; this only happens - * if NGHTTP2_FLAG_ACK is set in |flags| - */ -int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags, - const uint8_t *opaque_data); - -/* - * Adds GOAWAY frame with the last-stream-ID |last_stream_id| and the - * error code |error_code|. This is a convenient function built on top - * of nghttp2_session_add_frame() to add GOAWAY easily. The - * |aux_flags| are bitwise-OR of one or more of - * nghttp2_goaway_aux_flag. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_INVALID_ARGUMENT - * The |opaque_data_len| is too large. - */ -int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id, - uint32_t error_code, const uint8_t *opaque_data, - size_t opaque_data_len, uint8_t aux_flags); - -/* - * Adds WINDOW_UPDATE frame with stream ID |stream_id| and - * window-size-increment |window_size_increment|. This is a convenient - * function built on top of nghttp2_session_add_frame() to add - * WINDOW_UPDATE easily. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_session_add_window_update(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - int32_t window_size_increment); - -/* - * Adds SETTINGS frame. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FLOODED - * There are too many items in outbound queue; this only happens - * if NGHTTP2_FLAG_ACK is set in |flags| - */ -int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags, - const nghttp2_settings_entry *iv, size_t niv); - -/* - * Creates new stream in |session| with stream ID |stream_id|, - * priority |pri_spec| and flags |flags|. The |flags| is bitwise OR - * of nghttp2_stream_flag. Since this function is called when initial - * HEADERS is sent or received, these flags are taken from it. The - * state of stream is set to |initial_state|. The |stream_user_data| - * is a pointer to the arbitrary user supplied data to be associated - * to this stream. - * - * If |initial_state| is NGHTTP2_STREAM_RESERVED, this function sets - * NGHTTP2_STREAM_FLAG_PUSH flag set. - * - * This function returns a pointer to created new stream object, or - * NULL. - */ -nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, - int32_t stream_id, uint8_t flags, - nghttp2_stream_state initial_state, - void *stream_user_data); - -/* - * Closes stream whose stream ID is |stream_id|. The reason of closure - * is indicated by the |error_code|. When closing the stream, - * on_stream_close_callback will be called. - * - * This function returns 0 if it succeeds, or one the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - * NGHTTP2_ERR_INVALID_ARGUMENT - * The specified stream does not exist. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, - uint32_t error_code); - -/* - * Deletes |stream| from memory. After this function returns, stream - * cannot be accessed. - */ -void nghttp2_session_destroy_stream(nghttp2_session *session, - nghttp2_stream *stream); - -/* - * If further receptions and transmissions over the stream |stream_id| - * are disallowed, close the stream with error code NGHTTP2_NO_ERROR. - * - * This function returns 0 if it - * succeeds, or one of the following negative error codes: - * - * NGHTTP2_ERR_INVALID_ARGUMENT - * The specified stream does not exist. - */ -int nghttp2_session_close_stream_if_shut_rdwr(nghttp2_session *session, - nghttp2_stream *stream); - -int nghttp2_session_on_request_headers_received(nghttp2_session *session, - nghttp2_frame *frame); - -int nghttp2_session_on_response_headers_received(nghttp2_session *session, - nghttp2_frame *frame, - nghttp2_stream *stream); - -int nghttp2_session_on_push_response_headers_received(nghttp2_session *session, - nghttp2_frame *frame, - nghttp2_stream *stream); - -/* - * Called when HEADERS is received, assuming |frame| is properly - * initialized. This function does first validate received frame and - * then open stream and call callback functions. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_IGN_HEADER_BLOCK - * Frame was rejected and header block must be decoded but - * result must be ignored. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The read_callback failed - */ -int nghttp2_session_on_headers_received(nghttp2_session *session, - nghttp2_frame *frame, - nghttp2_stream *stream); - -/* - * Called when PRIORITY is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The read_callback failed - */ -int nghttp2_session_on_priority_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when RST_STREAM is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - * NGHTTP2_ERR_CALLBACK_FAILURE - * The read_callback failed - */ -int nghttp2_session_on_rst_stream_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when SETTINGS is received, assuming |frame| is properly - * initialized. If |noack| is non-zero, SETTINGS with ACK will not be - * submitted. If |frame| has NGHTTP2_FLAG_ACK flag set, no SETTINGS - * with ACK will not be submitted regardless of |noack|. - * - * This function returns 0 if it succeeds, or one the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - * NGHTTP2_ERR_CALLBACK_FAILURE - * The read_callback failed - * NGHTTP2_ERR_FLOODED - * There are too many items in outbound queue, and this is most - * likely caused by misbehaviour of peer. - */ -int nghttp2_session_on_settings_received(nghttp2_session *session, - nghttp2_frame *frame, int noack); - -/* - * Called when PUSH_PROMISE is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_IGN_HEADER_BLOCK - * Frame was rejected and header block must be decoded but - * result must be ignored. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The read_callback failed - */ -int nghttp2_session_on_push_promise_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when PING is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - * NGHTTP2_ERR_FLOODED - * There are too many items in outbound queue, and this is most - * likely caused by misbehaviour of peer. - */ -int nghttp2_session_on_ping_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when GOAWAY is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_on_goaway_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when WINDOW_UPDATE is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_on_window_update_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when ALTSVC is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_on_altsvc_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when ORIGIN is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_on_origin_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when PRIORITY_UPDATE is received, assuming |frame| is - * properly initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_on_priority_update_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Called when DATA is received, assuming |frame| is properly - * initialized. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. - */ -int nghttp2_session_on_data_received(nghttp2_session *session, - nghttp2_frame *frame); - -/* - * Returns nghttp2_stream* object whose stream ID is |stream_id|. It - * could be NULL if such stream does not exist. This function returns - * NULL if stream is marked as closed. - */ -nghttp2_stream *nghttp2_session_get_stream(nghttp2_session *session, - int32_t stream_id); - -/* - * This function behaves like nghttp2_session_get_stream(), but it - * returns stream object even if it is marked as closed or in - * NGHTTP2_STREAM_IDLE state. - */ -nghttp2_stream *nghttp2_session_get_stream_raw(nghttp2_session *session, - int32_t stream_id); - -/* - * Packs DATA frame |frame| in wire frame format and stores it in - * |bufs|. Payload will be read using |aux_data->data_prd|. The - * length of payload is at most |datamax| bytes. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_DEFERRED - * The DATA frame is postponed. - * NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE - * The read_callback failed (stream error). - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The read_callback failed (session error). - */ -int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs, - size_t datamax, nghttp2_frame *frame, - nghttp2_data_aux_data *aux_data, - nghttp2_stream *stream); - -/* - * Pops and returns next item to send. If there is no such item, - * returns NULL. This function takes into account max concurrent - * streams. That means if session->ob_syn has item and max concurrent - * streams is reached, the even if other queues contain items, then - * this function returns NULL. - */ -nghttp2_outbound_item * -nghttp2_session_pop_next_ob_item(nghttp2_session *session); - -/* - * Returns next item to send. If there is no such item, this function - * returns NULL. This function takes into account max concurrent - * streams. That means if session->ob_syn has item and max concurrent - * streams is reached, the even if other queues contain items, then - * this function returns NULL. - */ -nghttp2_outbound_item * -nghttp2_session_get_next_ob_item(nghttp2_session *session); - -/* - * Updates local settings with the |iv|. The number of elements in the - * array pointed by the |iv| is given by the |niv|. This function - * assumes that the all settings_id member in |iv| are in range 1 to - * NGHTTP2_SETTINGS_MAX, inclusive. - * - * While updating individual stream's local window size, if the window - * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE, - * RST_STREAM is issued against such a stream. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_session_update_local_settings(nghttp2_session *session, - nghttp2_settings_entry *iv, - size_t niv); - -/* - * Terminates current |session| with the |error_code|. The |reason| - * is NULL-terminated debug string. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_INVALID_ARGUMENT - * The |reason| is too long. - */ -int nghttp2_session_terminate_session_with_reason(nghttp2_session *session, - uint32_t error_code, - const char *reason); - -/* - * Accumulates received bytes |delta_size| for connection-level flow - * control and decides whether to send WINDOW_UPDATE to the - * connection. If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, - * WINDOW_UPDATE will not be sent. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_session_update_recv_connection_window_size(nghttp2_session *session, - size_t delta_size); - -/* - * Accumulates received bytes |delta_size| for stream-level flow - * control and decides whether to send WINDOW_UPDATE to that stream. - * If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE will not - * be sent. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, - nghttp2_stream *stream, - size_t delta_size, - int send_window_update); - -#endif /* NGHTTP2_SESSION_H */ diff --git a/vendor/nghttp2/lib/nghttp2_stream.c b/vendor/nghttp2/lib/nghttp2_stream.c deleted file mode 100644 index 0f2d36587..000000000 --- a/vendor/nghttp2/lib/nghttp2_stream.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_stream.h" - -#include - -#include "nghttp2_session.h" -#include "nghttp2_helper.h" -#include "nghttp2_debug.h" -#include "nghttp2_frame.h" - -void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, - uint8_t flags, nghttp2_stream_state initial_state, - int32_t remote_initial_window_size, - int32_t local_initial_window_size, - void *stream_user_data) { - stream->stream_id = stream_id; - stream->flags = flags; - stream->state = initial_state; - stream->shut_flags = NGHTTP2_SHUT_NONE; - stream->stream_user_data = stream_user_data; - stream->item = NULL; - stream->remote_window_size = remote_initial_window_size; - stream->local_window_size = local_initial_window_size; - stream->recv_window_size = 0; - stream->consumed_size = 0; - stream->recv_reduction = 0; - stream->window_update_queued = 0; - - stream->closed_next = NULL; - - stream->http_flags = NGHTTP2_HTTP_FLAG_NONE; - stream->content_length = -1; - stream->recv_content_length = 0; - stream->status_code = -1; - - stream->queued = 0; - stream->cycle = 0; - stream->pending_penalty = 0; - stream->seq = 0; - stream->last_writelen = 0; - - stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY; -} - -void nghttp2_stream_free(nghttp2_stream *stream) { (void)stream; } - -void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) { - stream->shut_flags = (uint8_t)(stream->shut_flags | flag); -} - -void nghttp2_stream_attach_item(nghttp2_stream *stream, - nghttp2_outbound_item *item) { - assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0); - assert(stream->item == NULL); - - DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item); - - stream->item = item; -} - -void nghttp2_stream_detach_item(nghttp2_stream *stream) { - DEBUGF("stream: stream=%d detach item=%p\n", stream->stream_id, stream->item); - - stream->item = NULL; - stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL); -} - -void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) { - assert(stream->item); - - DEBUGF("stream: stream=%d defer item=%p cause=%02x\n", stream->stream_id, - stream->item, flags); - - stream->flags |= flags; -} - -void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, - uint8_t flags) { - assert(stream->item); - - DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id, - stream->item, flags); - - stream->flags = (uint8_t)(stream->flags & ~flags); -} - -int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) { - return stream->item && (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL); -} - -int nghttp2_stream_check_deferred_by_flow_control(nghttp2_stream *stream) { - return stream->item && - (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); -} - -static int update_initial_window_size(int32_t *window_size_ptr, - int32_t new_initial_window_size, - int32_t old_initial_window_size) { - int64_t new_window_size = (int64_t)(*window_size_ptr) + - new_initial_window_size - old_initial_window_size; - if (INT32_MIN > new_window_size || - new_window_size > NGHTTP2_MAX_WINDOW_SIZE) { - return -1; - } - *window_size_ptr = (int32_t)new_window_size; - return 0; -} - -int nghttp2_stream_update_remote_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size) { - return update_initial_window_size(&stream->remote_window_size, - new_initial_window_size, - old_initial_window_size); -} - -int nghttp2_stream_update_local_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size) { - return update_initial_window_size(&stream->local_window_size, - new_initial_window_size, - old_initial_window_size); -} - -void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) { - stream->state = NGHTTP2_STREAM_OPENED; - stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH); -} - -nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) { - if (stream == &nghttp2_stream_root) { - return NGHTTP2_STREAM_STATE_IDLE; - } - - if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) { - return NGHTTP2_STREAM_STATE_CLOSED; - } - - if (stream->flags & NGHTTP2_STREAM_FLAG_PUSH) { - if (stream->shut_flags & NGHTTP2_SHUT_RD) { - return NGHTTP2_STREAM_STATE_RESERVED_LOCAL; - } - - if (stream->shut_flags & NGHTTP2_SHUT_WR) { - return NGHTTP2_STREAM_STATE_RESERVED_REMOTE; - } - } - - if (stream->shut_flags & NGHTTP2_SHUT_RD) { - return NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE; - } - - if (stream->shut_flags & NGHTTP2_SHUT_WR) { - return NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL; - } - - if (stream->state == NGHTTP2_STREAM_IDLE) { - return NGHTTP2_STREAM_STATE_IDLE; - } - - return NGHTTP2_STREAM_STATE_OPEN; -} - -nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) { - (void)stream; - - return NULL; -} - -nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) { - (void)stream; - - return NULL; -} - -nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) { - (void)stream; - - return NULL; -} - -nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) { - (void)stream; - - return NULL; -} - -int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) { - (void)stream; - - return NGHTTP2_DEFAULT_WEIGHT; -} - -int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) { - (void)stream; - - return 0; -} - -int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) { - return stream->stream_id; -} diff --git a/vendor/nghttp2/lib/nghttp2_stream.h b/vendor/nghttp2/lib/nghttp2_stream.h deleted file mode 100644 index e73cd283b..000000000 --- a/vendor/nghttp2/lib/nghttp2_stream.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_STREAM_H -#define NGHTTP2_STREAM_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include "nghttp2_outbound_item.h" -#include "nghttp2_map.h" -#include "nghttp2_pq.h" -#include "nghttp2_int.h" - -/* - * If local peer is stream initiator: - * NGHTTP2_STREAM_OPENING : upon sending request HEADERS - * NGHTTP2_STREAM_OPENED : upon receiving response HEADERS - * NGHTTP2_STREAM_CLOSING : upon queuing RST_STREAM - * - * If remote peer is stream initiator: - * NGHTTP2_STREAM_OPENING : upon receiving request HEADERS - * NGHTTP2_STREAM_OPENED : upon sending response HEADERS - * NGHTTP2_STREAM_CLOSING : upon queuing RST_STREAM - */ -typedef enum { - /* Initial state */ - NGHTTP2_STREAM_INITIAL, - /* For stream initiator: request HEADERS has been sent, but response - HEADERS has not been received yet. For receiver: request HEADERS - has been received, but it does not send response HEADERS yet. */ - NGHTTP2_STREAM_OPENING, - /* For stream initiator: response HEADERS is received. For receiver: - response HEADERS is sent. */ - NGHTTP2_STREAM_OPENED, - /* RST_STREAM is received, but somehow we need to keep stream in - memory. */ - NGHTTP2_STREAM_CLOSING, - /* PUSH_PROMISE is received or sent */ - NGHTTP2_STREAM_RESERVED, - /* Stream is created in this state if it is used as anchor in - dependency tree. */ - NGHTTP2_STREAM_IDLE -} nghttp2_stream_state; - -typedef enum { - NGHTTP2_SHUT_NONE = 0, - /* Indicates further receptions will be disallowed. */ - NGHTTP2_SHUT_RD = 0x01, - /* Indicates further transmissions will be disallowed. */ - NGHTTP2_SHUT_WR = 0x02, - /* Indicates both further receptions and transmissions will be - disallowed. */ - NGHTTP2_SHUT_RDWR = NGHTTP2_SHUT_RD | NGHTTP2_SHUT_WR -} nghttp2_shut_flag; - -typedef enum { - NGHTTP2_STREAM_FLAG_NONE = 0, - /* Indicates that this stream is pushed stream and not opened - yet. */ - NGHTTP2_STREAM_FLAG_PUSH = 0x01, - /* Indicates that this stream was closed */ - NGHTTP2_STREAM_FLAG_CLOSED = 0x02, - /* Indicates the item is deferred due to flow control. */ - NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL = 0x04, - /* Indicates the item is deferred by user callback */ - NGHTTP2_STREAM_FLAG_DEFERRED_USER = 0x08, - /* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and - NGHTTP2_STREAM_FLAG_DEFERRED_USER. */ - NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c, - /* Ignore client RFC 9218 priority signal. */ - NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20, - /* Indicates that RFC 9113 leading and trailing white spaces - validation against a field value is not performed. */ - NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 0x40, -} nghttp2_stream_flag; - -/* HTTP related flags to enforce HTTP semantics */ -typedef enum { - NGHTTP2_HTTP_FLAG_NONE = 0, - /* header field seen so far */ - NGHTTP2_HTTP_FLAG__AUTHORITY = 1, - NGHTTP2_HTTP_FLAG__PATH = 1 << 1, - NGHTTP2_HTTP_FLAG__METHOD = 1 << 2, - NGHTTP2_HTTP_FLAG__SCHEME = 1 << 3, - /* host is not pseudo header, but we require either host or - :authority */ - NGHTTP2_HTTP_FLAG_HOST = 1 << 4, - NGHTTP2_HTTP_FLAG__STATUS = 1 << 5, - /* required header fields for HTTP request except for CONNECT - method. */ - NGHTTP2_HTTP_FLAG_REQ_HEADERS = NGHTTP2_HTTP_FLAG__METHOD | - NGHTTP2_HTTP_FLAG__PATH | - NGHTTP2_HTTP_FLAG__SCHEME, - NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED = 1 << 6, - /* HTTP method flags */ - NGHTTP2_HTTP_FLAG_METH_CONNECT = 1 << 7, - NGHTTP2_HTTP_FLAG_METH_HEAD = 1 << 8, - NGHTTP2_HTTP_FLAG_METH_OPTIONS = 1 << 9, - NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND = 1 << 10, - NGHTTP2_HTTP_FLAG_METH_ALL = - NGHTTP2_HTTP_FLAG_METH_CONNECT | NGHTTP2_HTTP_FLAG_METH_HEAD | - NGHTTP2_HTTP_FLAG_METH_OPTIONS | NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND, - /* :path category */ - /* path starts with "/" */ - NGHTTP2_HTTP_FLAG_PATH_REGULAR = 1 << 11, - /* path "*" */ - NGHTTP2_HTTP_FLAG_PATH_ASTERISK = 1 << 12, - /* scheme */ - /* "http" or "https" scheme */ - NGHTTP2_HTTP_FLAG_SCHEME_HTTP = 1 << 13, - /* set if final response is expected */ - NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE = 1 << 14, - NGHTTP2_HTTP_FLAG__PROTOCOL = 1 << 15, - /* set if priority header field is received */ - NGHTTP2_HTTP_FLAG_PRIORITY = 1 << 16, - /* set if an error is encountered while parsing priority header - field */ - NGHTTP2_HTTP_FLAG_BAD_PRIORITY = 1 << 17, -} nghttp2_http_flag; - -struct nghttp2_stream { - nghttp2_stream_state state; - nghttp2_pq_entry pq_entry; - /* Content-Length of request/response body. -1 if unknown. */ - int64_t content_length; - /* Received body so far */ - int64_t recv_content_length; - /* Next scheduled time to sent item */ - uint64_t cycle; - /* Secondary key for prioritization to break a tie for cycle. This - value is monotonically increased for single parent stream. */ - uint64_t seq; - nghttp2_stream *closed_next; - /* The arbitrary data provided by user for this stream. */ - void *stream_user_data; - /* Item to send */ - nghttp2_outbound_item *item; - /* Last written length of frame payload */ - size_t last_writelen; - /* stream ID */ - int32_t stream_id; - /* Current remote window size. This value is computed against the - current initial window size of remote endpoint. */ - int32_t remote_window_size; - /* Keep track of the number of bytes received without - WINDOW_UPDATE. This could be negative after submitting negative - value to WINDOW_UPDATE */ - int32_t recv_window_size; - /* The number of bytes consumed by the application and now is - subject to WINDOW_UPDATE. This is only used when auto - WINDOW_UPDATE is turned off. */ - int32_t consumed_size; - /* The amount of recv_window_size cut using submitting negative - value to WINDOW_UPDATE */ - int32_t recv_reduction; - /* window size for local flow control. It is initially set to - NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by - submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */ - int32_t local_window_size; - /* This is unpaid penalty (offset) when calculating cycle. */ - uint32_t pending_penalty; - /* status code from remote server */ - int16_t status_code; - /* Bitwise OR of zero or more nghttp2_http_flag values */ - uint32_t http_flags; - /* This is bitwise-OR of 0 or more of nghttp2_stream_flag. */ - uint8_t flags; - /* Bitwise OR of zero or more nghttp2_shut_flag values */ - uint8_t shut_flags; - /* Nonzero if this stream has been queued to stream pointed by - dep_prev. We maintain the invariant that if a stream is queued, - then its ancestors, except for root, are also queued. This - invariant may break in fatal error condition. */ - uint8_t queued; - /* This flag is used to reduce excessive queuing of WINDOW_UPDATE to - this stream. The nonzero does not necessarily mean WINDOW_UPDATE - is not queued. */ - uint8_t window_update_queued; - /* extpri is a stream priority produced by nghttp2_extpri_to_uint8 - used by RFC 9218 extensible priorities. */ - uint8_t extpri; - /* http_extpri is a stream priority received in HTTP request header - fields and produced by nghttp2_extpri_to_uint8. */ - uint8_t http_extpri; -}; - -void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, - uint8_t flags, nghttp2_stream_state initial_state, - int32_t remote_initial_window_size, - int32_t local_initial_window_size, - void *stream_user_data); - -void nghttp2_stream_free(nghttp2_stream *stream); - -/* - * Disallow either further receptions or transmissions, or both. - * |flag| is bitwise OR of one or more of nghttp2_shut_flag. - */ -void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag); - -/* - * Defer |stream->item|. We won't call this function in the situation - * where |stream->item| == NULL. The |flags| is bitwise OR of zero or - * more of NGHTTP2_STREAM_FLAG_DEFERRED_USER and - * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL. The |flags| indicates - * the reason of this action. - */ -void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags); - -/* - * Put back deferred data in this stream to active state. The |flags| - * are one or more of bitwise OR of the following values: - * NGHTTP2_STREAM_FLAG_DEFERRED_USER and - * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are - * cleared if they are set. So even if this function is called, if - * one of flag is still set, data does not become active. - */ -void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags); - -/* - * Returns nonzero if item is deferred by whatever reason. - */ -int nghttp2_stream_check_deferred_item(nghttp2_stream *stream); - -/* - * Returns nonzero if item is deferred by flow control. - */ -int nghttp2_stream_check_deferred_by_flow_control(nghttp2_stream *stream); - -/* - * Updates the remote window size with the new value - * |new_initial_window_size|. The |old_initial_window_size| is used to - * calculate the current window size. - * - * This function returns 0 if it succeeds or -1. The failure is due to - * overflow. - */ -int nghttp2_stream_update_remote_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size); - -/* - * Updates the local window size with the new value - * |new_initial_window_size|. The |old_initial_window_size| is used to - * calculate the current window size. - * - * This function returns 0 if it succeeds or -1. The failure is due to - * overflow. - */ -int nghttp2_stream_update_local_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size); - -/* - * Call this function if promised stream |stream| is replied with - * HEADERS. This function makes the state of the |stream| to - * NGHTTP2_STREAM_OPENED. - */ -void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream); - -/* - * Attaches |item| to |stream|. - */ -void nghttp2_stream_attach_item(nghttp2_stream *stream, - nghttp2_outbound_item *item); - -/* - * Detaches |stream->item|. This function does not free - * |stream->item|. The caller must free it. - */ -void nghttp2_stream_detach_item(nghttp2_stream *stream); - -#endif /* NGHTTP2_STREAM */ diff --git a/vendor/nghttp2/lib/nghttp2_submit.c b/vendor/nghttp2/lib/nghttp2_submit.c deleted file mode 100644 index 8a90f714e..000000000 --- a/vendor/nghttp2/lib/nghttp2_submit.c +++ /dev/null @@ -1,864 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_submit.h" - -#include -#include - -#include "nghttp2_session.h" -#include "nghttp2_frame.h" -#include "nghttp2_helper.h" -#include "nghttp2_priority_spec.h" - -/* This function takes ownership of |nva_copy|. Regardless of the - return value, the caller must not free |nva_copy| after this - function returns. */ -static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags, - int32_t stream_id, nghttp2_nv *nva_copy, - size_t nvlen, - const nghttp2_data_provider_wrap *dpw, - void *stream_user_data) { - int rv; - uint8_t flags_copy; - nghttp2_outbound_item *item = NULL; - nghttp2_frame *frame = NULL; - nghttp2_headers_category hcat; - nghttp2_mem *mem; - - mem = &session->mem; - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - rv = NGHTTP2_ERR_NOMEM; - goto fail; - } - - nghttp2_outbound_item_init(item); - - if (dpw != NULL && dpw->data_prd.read_callback != NULL) { - item->aux_data.headers.dpw = *dpw; - } - - item->aux_data.headers.stream_user_data = stream_user_data; - - flags_copy = - (uint8_t)((flags & (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PRIORITY)) | - NGHTTP2_FLAG_END_HEADERS); - - if (stream_id == -1) { - if (session->next_stream_id > INT32_MAX) { - rv = NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE; - goto fail; - } - - stream_id = (int32_t)session->next_stream_id; - session->next_stream_id += 2; - - hcat = NGHTTP2_HCAT_REQUEST; - } else { - /* More specific categorization will be done later. */ - hcat = NGHTTP2_HCAT_HEADERS; - } - - frame = &item->frame; - - nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, NULL, - nva_copy, nvlen); - - rv = nghttp2_session_add_item(session, item); - - if (rv != 0) { - nghttp2_frame_headers_free(&frame->headers, mem); - goto fail2; - } - - if (hcat == NGHTTP2_HCAT_REQUEST) { - return stream_id; - } - - return 0; - -fail: - /* nghttp2_frame_headers_init() takes ownership of nva_copy. */ - nghttp2_nv_array_del(nva_copy, mem); -fail2: - nghttp2_mem_free(mem, item); - - return rv; -} - -static int32_t submit_headers_shared_nva(nghttp2_session *session, - uint8_t flags, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider_wrap *dpw, - void *stream_user_data) { - int rv; - nghttp2_nv *nva_copy; - nghttp2_mem *mem; - - mem = &session->mem; - - rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem); - if (rv < 0) { - return rv; - } - - return submit_headers_shared(session, flags, stream_id, nva_copy, nvlen, dpw, - stream_user_data); -} - -int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen) { - if (stream_id <= 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM, - stream_id, nva, nvlen, NULL, NULL); -} - -int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, - void *stream_user_data) { - (void)pri_spec; - - if (stream_id == -1) { - if (session->server) { - return NGHTTP2_ERR_PROTO; - } - } else if (stream_id <= 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - flags &= NGHTTP2_FLAG_END_STREAM; - - return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, NULL, - stream_user_data); -} - -int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, - const uint8_t *opaque_data) { - flags &= NGHTTP2_FLAG_ACK; - return nghttp2_session_add_ping(session, flags, opaque_data); -} - -int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_priority_spec *pri_spec) { - (void)session; - (void)flags; - (void)stream_id; - (void)pri_spec; - - return 0; -} - -int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags, - int32_t stream_id, uint32_t error_code) { - (void)flags; - - if (stream_id == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - return nghttp2_session_add_rst_stream_continue( - session, stream_id, error_code, /* continue_without_stream = */ 0); -} - -int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags, - int32_t last_stream_id, uint32_t error_code, - const uint8_t *opaque_data, size_t opaque_data_len) { - (void)flags; - - if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) { - return 0; - } - return nghttp2_session_add_goaway(session, last_stream_id, error_code, - opaque_data, opaque_data_len, - NGHTTP2_GOAWAY_AUX_NONE); -} - -int nghttp2_submit_shutdown_notice(nghttp2_session *session) { - if (!session->server) { - return NGHTTP2_ERR_INVALID_STATE; - } - if (session->goaway_flags) { - return 0; - } - return nghttp2_session_add_goaway(session, (1u << 31) - 1, NGHTTP2_NO_ERROR, - NULL, 0, - NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE); -} - -int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags, - const nghttp2_settings_entry *iv, size_t niv) { - (void)flags; - return nghttp2_session_add_settings(session, NGHTTP2_FLAG_NONE, iv, niv); -} - -int32_t nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags, - int32_t stream_id, const nghttp2_nv *nva, - size_t nvlen, - void *promised_stream_user_data) { - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_nv *nva_copy; - uint8_t flags_copy; - int32_t promised_stream_id; - int rv; - nghttp2_mem *mem; - (void)flags; - - mem = &session->mem; - - if (stream_id <= 0 || nghttp2_session_is_my_stream_id(session, stream_id)) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (!session->server) { - return NGHTTP2_ERR_PROTO; - } - - /* All 32bit signed stream IDs are spent. */ - if (session->next_stream_id > INT32_MAX) { - return NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE; - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - item->aux_data.headers.stream_user_data = promised_stream_user_data; - - frame = &item->frame; - - rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem); - if (rv < 0) { - nghttp2_mem_free(mem, item); - return rv; - } - - flags_copy = NGHTTP2_FLAG_END_HEADERS; - - promised_stream_id = (int32_t)session->next_stream_id; - session->next_stream_id += 2; - - nghttp2_frame_push_promise_init(&frame->push_promise, flags_copy, stream_id, - promised_stream_id, nva_copy, nvlen); - - rv = nghttp2_session_add_item(session, item); - - if (rv != 0) { - nghttp2_frame_push_promise_free(&frame->push_promise, mem); - nghttp2_mem_free(mem, item); - - return rv; - } - - return promised_stream_id; -} - -int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - int32_t window_size_increment) { - int rv; - nghttp2_stream *stream = 0; - (void)flags; - - if (window_size_increment == 0) { - return 0; - } - if (stream_id == 0) { - rv = nghttp2_adjust_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); - if (rv != 0) { - return rv; - } - } else { - stream = nghttp2_session_get_stream(session, stream_id); - if (!stream) { - return 0; - } - - rv = nghttp2_adjust_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); - if (rv != 0) { - return rv; - } - } - - if (window_size_increment > 0) { - if (stream_id == 0) { - session->consumed_size = - nghttp2_max_int32(0, session->consumed_size - window_size_increment); - } else { - stream->consumed_size = - nghttp2_max_int32(0, stream->consumed_size - window_size_increment); - } - - return nghttp2_session_add_window_update(session, 0, stream_id, - window_size_increment); - } - return 0; -} - -int nghttp2_session_set_local_window_size(nghttp2_session *session, - uint8_t flags, int32_t stream_id, - int32_t window_size) { - int32_t window_size_increment; - nghttp2_stream *stream; - int rv; - (void)flags; - - if (window_size < 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (stream_id == 0) { - window_size_increment = window_size - session->local_window_size; - - if (window_size_increment == 0) { - return 0; - } - - if (window_size_increment < 0) { - return nghttp2_adjust_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); - } - - rv = nghttp2_increase_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); - - if (rv != 0) { - return rv; - } - - if (window_size_increment > 0) { - return nghttp2_session_add_window_update(session, 0, stream_id, - window_size_increment); - } - - return nghttp2_session_update_recv_connection_window_size(session, 0); - } else { - stream = nghttp2_session_get_stream(session, stream_id); - - if (stream == NULL) { - return 0; - } - - window_size_increment = window_size - stream->local_window_size; - - if (window_size_increment == 0) { - return 0; - } - - if (window_size_increment < 0) { - return nghttp2_adjust_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); - } - - rv = nghttp2_increase_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); - - if (rv != 0) { - return rv; - } - - if (window_size_increment > 0) { - return nghttp2_session_add_window_update(session, 0, stream_id, - window_size_increment); - } - - return nghttp2_session_update_recv_stream_window_size(session, stream, 0, - 1); - } -} - -int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags, - int32_t stream_id, const uint8_t *origin, - size_t origin_len, const uint8_t *field_value, - size_t field_value_len) { - nghttp2_mem *mem; - uint8_t *buf, *p; - uint8_t *origin_copy; - uint8_t *field_value_copy; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_ext_altsvc *altsvc; - int rv; - (void)flags; - - mem = &session->mem; - - if (!session->server) { - return NGHTTP2_ERR_INVALID_STATE; - } - - if (2 + origin_len + field_value_len > NGHTTP2_MAX_PAYLOADLEN) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (stream_id == 0) { - if (origin_len == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - } else if (origin_len != 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - buf = nghttp2_mem_malloc(mem, origin_len + field_value_len + 2); - if (buf == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - p = buf; - - origin_copy = p; - if (origin_len) { - p = nghttp2_cpymem(p, origin, origin_len); - } - *p++ = '\0'; - - field_value_copy = p; - if (field_value_len) { - p = nghttp2_cpymem(p, field_value, field_value_len); - } - *p++ = '\0'; - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - rv = NGHTTP2_ERR_NOMEM; - goto fail_item_malloc; - } - - nghttp2_outbound_item_init(item); - - item->aux_data.ext.builtin = 1; - - altsvc = &item->ext_frame_payload.altsvc; - - frame = &item->frame; - frame->ext.payload = altsvc; - - nghttp2_frame_altsvc_init(&frame->ext, stream_id, origin_copy, origin_len, - field_value_copy, field_value_len); - - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - nghttp2_frame_altsvc_free(&frame->ext, mem); - nghttp2_mem_free(mem, item); - - return rv; - } - - return 0; - -fail_item_malloc: - nghttp2_mem_free(mem, buf); - - return rv; -} - -int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags, - const nghttp2_origin_entry *ov, size_t nov) { - nghttp2_mem *mem; - uint8_t *p; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_ext_origin *origin; - nghttp2_origin_entry *ov_copy; - size_t len = 0; - size_t i; - int rv; - (void)flags; - - mem = &session->mem; - - if (!session->server) { - return NGHTTP2_ERR_INVALID_STATE; - } - - if (nov) { - for (i = 0; i < nov; ++i) { - len += ov[i].origin_len; - } - - if (2 * nov + len > NGHTTP2_MAX_PAYLOADLEN) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - /* The last nov is added for terminal NULL character. */ - ov_copy = - nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov); - if (ov_copy == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - p = (uint8_t *)ov_copy + nov * sizeof(nghttp2_origin_entry); - - for (i = 0; i < nov; ++i) { - ov_copy[i].origin = p; - ov_copy[i].origin_len = ov[i].origin_len; - p = nghttp2_cpymem(p, ov[i].origin, ov[i].origin_len); - *p++ = '\0'; - } - - assert((size_t)(p - (uint8_t *)ov_copy) == - nov * sizeof(nghttp2_origin_entry) + len + nov); - } else { - ov_copy = NULL; - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - rv = NGHTTP2_ERR_NOMEM; - goto fail_item_malloc; - } - - nghttp2_outbound_item_init(item); - - item->aux_data.ext.builtin = 1; - - origin = &item->ext_frame_payload.origin; - - frame = &item->frame; - frame->ext.payload = origin; - - nghttp2_frame_origin_init(&frame->ext, ov_copy, nov); - - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - nghttp2_frame_origin_free(&frame->ext, mem); - nghttp2_mem_free(mem, item); - - return rv; - } - - return 0; - -fail_item_malloc: - nghttp2_mem_free(mem, ov_copy); - - return rv; -} - -int nghttp2_submit_priority_update(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const uint8_t *field_value, - size_t field_value_len) { - nghttp2_mem *mem; - uint8_t *buf, *p; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_ext_priority_update *priority_update; - int rv; - (void)flags; - - mem = &session->mem; - - if (session->server) { - return NGHTTP2_ERR_INVALID_STATE; - } - - if (session->remote_settings.no_rfc7540_priorities == 0) { - return 0; - } - - if (stream_id == 0 || 4 + field_value_len > NGHTTP2_MAX_PAYLOADLEN) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (field_value_len) { - buf = nghttp2_mem_malloc(mem, field_value_len + 1); - if (buf == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - p = nghttp2_cpymem(buf, field_value, field_value_len); - *p = '\0'; - } else { - buf = NULL; - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - rv = NGHTTP2_ERR_NOMEM; - goto fail_item_malloc; - } - - nghttp2_outbound_item_init(item); - - item->aux_data.ext.builtin = 1; - - priority_update = &item->ext_frame_payload.priority_update; - - frame = &item->frame; - frame->ext.payload = priority_update; - - nghttp2_frame_priority_update_init(&frame->ext, stream_id, buf, - field_value_len); - - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - nghttp2_frame_priority_update_free(&frame->ext, mem); - nghttp2_mem_free(mem, item); - - return rv; - } - - return 0; - -fail_item_malloc: - nghttp2_mem_free(mem, buf); - - return rv; -} - -static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) { - uint8_t flags = NGHTTP2_FLAG_NONE; - if (dpw == NULL || dpw->data_prd.read_callback == NULL) { - flags |= NGHTTP2_FLAG_END_STREAM; - } - - return flags; -} - -static int32_t submit_request_shared(nghttp2_session *session, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider_wrap *dpw, - void *stream_user_data) { - uint8_t flags; - - if (session->server) { - return NGHTTP2_ERR_PROTO; - } - - flags = set_request_flags(dpw); - - return submit_headers_shared_nva(session, flags, -1, nva, nvlen, dpw, - stream_user_data); -} - -int32_t nghttp2_submit_request(nghttp2_session *session, - const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider *data_prd, - void *stream_user_data) { - nghttp2_data_provider_wrap dpw; - (void)pri_spec; - - return submit_request_shared(session, nva, nvlen, - nghttp2_data_provider_wrap_v1(&dpw, data_prd), - stream_user_data); -} - -int32_t nghttp2_submit_request2(nghttp2_session *session, - const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider2 *data_prd, - void *stream_user_data) { - nghttp2_data_provider_wrap dpw; - (void)pri_spec; - - return submit_request_shared(session, nva, nvlen, - nghttp2_data_provider_wrap_v2(&dpw, data_prd), - stream_user_data); -} - -static uint8_t set_response_flags(const nghttp2_data_provider_wrap *dpw) { - uint8_t flags = NGHTTP2_FLAG_NONE; - if (dpw == NULL || dpw->data_prd.read_callback == NULL) { - flags |= NGHTTP2_FLAG_END_STREAM; - } - return flags; -} - -static int submit_response_shared(nghttp2_session *session, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider_wrap *dpw) { - uint8_t flags; - - if (stream_id <= 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (!session->server) { - return NGHTTP2_ERR_PROTO; - } - - flags = set_response_flags(dpw); - return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, dpw, - NULL); -} - -int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider *data_prd) { - nghttp2_data_provider_wrap dpw; - - return submit_response_shared(session, stream_id, nva, nvlen, - nghttp2_data_provider_wrap_v1(&dpw, data_prd)); -} - -int nghttp2_submit_response2(nghttp2_session *session, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider2 *data_prd) { - nghttp2_data_provider_wrap dpw; - - return submit_response_shared(session, stream_id, nva, nvlen, - nghttp2_data_provider_wrap_v2(&dpw, data_prd)); -} - -int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider_wrap *dpw) { - int rv; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_data_aux_data *aux_data; - uint8_t nflags = flags & NGHTTP2_FLAG_END_STREAM; - nghttp2_mem *mem; - - mem = &session->mem; - - if (stream_id == 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - aux_data = &item->aux_data.data; - aux_data->dpw = *dpw; - aux_data->eof = 0; - aux_data->flags = nflags; - - /* flags are sent on transmission */ - nghttp2_frame_data_init(&frame->data, NGHTTP2_FLAG_NONE, stream_id); - - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - nghttp2_frame_data_free(&frame->data); - nghttp2_mem_free(mem, item); - return rv; - } - return 0; -} - -int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider *data_prd) { - nghttp2_data_provider_wrap dpw; - - assert(data_prd); - - return nghttp2_submit_data_shared( - session, flags, stream_id, nghttp2_data_provider_wrap_v1(&dpw, data_prd)); -} - -int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider2 *data_prd) { - nghttp2_data_provider_wrap dpw; - - assert(data_prd); - - return nghttp2_submit_data_shared( - session, flags, stream_id, nghttp2_data_provider_wrap_v2(&dpw, data_prd)); -} - -ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen, - const nghttp2_settings_entry *iv, - size_t niv) { - return (ssize_t)nghttp2_pack_settings_payload2(buf, buflen, iv, niv); -} - -nghttp2_ssize nghttp2_pack_settings_payload2(uint8_t *buf, size_t buflen, - const nghttp2_settings_entry *iv, - size_t niv) { - if (!nghttp2_iv_check(iv, niv)) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (buflen < (niv * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH)) { - return NGHTTP2_ERR_INSUFF_BUFSIZE; - } - - return (nghttp2_ssize)nghttp2_frame_pack_settings_payload(buf, iv, niv); -} - -int nghttp2_submit_extension(nghttp2_session *session, uint8_t type, - uint8_t flags, int32_t stream_id, void *payload) { - int rv; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_mem *mem; - - mem = &session->mem; - - if (type <= NGHTTP2_CONTINUATION) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (!session->callbacks.pack_extension_callback2 && - !session->callbacks.pack_extension_callback) { - return NGHTTP2_ERR_INVALID_STATE; - } - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - nghttp2_frame_extension_init(&frame->ext, type, flags, stream_id, payload); - - rv = nghttp2_session_add_item(session, item); - if (rv != 0) { - nghttp2_frame_extension_free(&frame->ext); - nghttp2_mem_free(mem, item); - return rv; - } - - return 0; -} diff --git a/vendor/nghttp2/lib/nghttp2_submit.h b/vendor/nghttp2/lib/nghttp2_submit.h deleted file mode 100644 index 350ee0227..000000000 --- a/vendor/nghttp2/lib/nghttp2_submit.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_SUBMIT_H -#define NGHTTP2_SUBMIT_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -#include "nghttp2_outbound_item.h" - -int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider_wrap *dpw); - -#endif /* NGHTTP2_SUBMIT_H */ diff --git a/vendor/nghttp2/lib/nghttp2_time.c b/vendor/nghttp2/lib/nghttp2_time.c deleted file mode 100644 index 148ccfdce..000000000 --- a/vendor/nghttp2/lib/nghttp2_time.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2023 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_time.h" - -#ifdef HAVE_WINDOWS_H -# include -#endif /* HAVE_WINDOWS_H */ - -#include - -#if !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) -static uint64_t time_now_sec(void) { - time_t t = time(NULL); - - if (t == -1) { - return 0; - } - - return (uint64_t)t; -} -#endif /* !HAVE_GETTICKCOUNT64 || __CYGWIN__ */ - -#if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__) -uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } -#elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_DECL_CLOCK_MONOTONIC) && \ - HAVE_DECL_CLOCK_MONOTONIC -uint64_t nghttp2_time_now_sec(void) { - struct timespec tp; - int rv = clock_gettime(CLOCK_MONOTONIC, &tp); - - if (rv == -1) { - return time_now_sec(); - } - - return (uint64_t)tp.tv_sec; -} -#else /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \ - (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */ -uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); } -#endif /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \ - (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */ diff --git a/vendor/nghttp2/lib/nghttp2_time.h b/vendor/nghttp2/lib/nghttp2_time.h deleted file mode 100644 index 03c0bbe94..000000000 --- a/vendor/nghttp2/lib/nghttp2_time.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2023 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_TIME_H -#define NGHTTP2_TIME_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -/* nghttp2_time_now_sec returns seconds from implementation-specific - timepoint. If it is unable to get seconds, it returns 0. */ -uint64_t nghttp2_time_now_sec(void); - -#endif /* NGHTTP2_TIME_H */ diff --git a/vendor/nghttp2/lib/nghttp2_version.c b/vendor/nghttp2/lib/nghttp2_version.c deleted file mode 100644 index 4211f2cf8..000000000 --- a/vendor/nghttp2/lib/nghttp2_version.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -static nghttp2_info version = {NGHTTP2_VERSION_AGE, NGHTTP2_VERSION_NUM, - NGHTTP2_VERSION, NGHTTP2_PROTO_VERSION_ID}; - -nghttp2_info *nghttp2_version(int least_version) { - if (least_version > NGHTTP2_VERSION_NUM) - return NULL; - return &version; -} diff --git a/vendor/nghttp2/lib/sfparse.c b/vendor/nghttp2/lib/sfparse.c deleted file mode 100644 index cee089d39..000000000 --- a/vendor/nghttp2/lib/sfparse.c +++ /dev/null @@ -1,1787 +0,0 @@ -/* - * sfparse - * - * Copyright (c) 2023 sfparse contributors - * Copyright (c) 2019 nghttp3 contributors - * Copyright (c) 2015 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "sfparse.h" - -#include -#include -#include - -#ifdef __AVX2__ -# include -#endif /* __AVX2__ */ - -#define SFPARSE_STATE_DICT 0x08u -#define SFPARSE_STATE_LIST 0x10u -#define SFPARSE_STATE_ITEM 0x18u - -#define SFPARSE_STATE_INNER_LIST 0x04u - -#define SFPARSE_STATE_BEFORE 0x00u -#define SFPARSE_STATE_BEFORE_PARAMS 0x01u -#define SFPARSE_STATE_PARAMS 0x02u -#define SFPARSE_STATE_AFTER 0x03u - -#define SFPARSE_STATE_OP_MASK 0x03u - -#define SFPARSE_SET_STATE_AFTER(NAME) \ - (SFPARSE_STATE_##NAME | SFPARSE_STATE_AFTER) -#define SFPARSE_SET_STATE_BEFORE_PARAMS(NAME) \ - (SFPARSE_STATE_##NAME | SFPARSE_STATE_BEFORE_PARAMS) -#define SFPARSE_SET_STATE_INNER_LIST_BEFORE(NAME) \ - (SFPARSE_STATE_##NAME | SFPARSE_STATE_INNER_LIST | SFPARSE_STATE_BEFORE) - -#define SFPARSE_STATE_DICT_AFTER SFPARSE_SET_STATE_AFTER(DICT) -#define SFPARSE_STATE_DICT_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(DICT) -#define SFPARSE_STATE_DICT_INNER_LIST_BEFORE \ - SFPARSE_SET_STATE_INNER_LIST_BEFORE(DICT) - -#define SFPARSE_STATE_LIST_AFTER SFPARSE_SET_STATE_AFTER(LIST) -#define SFPARSE_STATE_LIST_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(LIST) -#define SFPARSE_STATE_LIST_INNER_LIST_BEFORE \ - SFPARSE_SET_STATE_INNER_LIST_BEFORE(LIST) - -#define SFPARSE_STATE_ITEM_AFTER SFPARSE_SET_STATE_AFTER(ITEM) -#define SFPARSE_STATE_ITEM_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(ITEM) -#define SFPARSE_STATE_ITEM_INNER_LIST_BEFORE \ - SFPARSE_SET_STATE_INNER_LIST_BEFORE(ITEM) - -#define SFPARSE_STATE_INITIAL 0x00u - -#define DIGIT_CASES \ - case '0': \ - case '1': \ - case '2': \ - case '3': \ - case '4': \ - case '5': \ - case '6': \ - case '7': \ - case '8': \ - case '9' - -#define LCALPHA_CASES \ - case 'a': \ - case 'b': \ - case 'c': \ - case 'd': \ - case 'e': \ - case 'f': \ - case 'g': \ - case 'h': \ - case 'i': \ - case 'j': \ - case 'k': \ - case 'l': \ - case 'm': \ - case 'n': \ - case 'o': \ - case 'p': \ - case 'q': \ - case 'r': \ - case 's': \ - case 't': \ - case 'u': \ - case 'v': \ - case 'w': \ - case 'x': \ - case 'y': \ - case 'z' - -#define UCALPHA_CASES \ - case 'A': \ - case 'B': \ - case 'C': \ - case 'D': \ - case 'E': \ - case 'F': \ - case 'G': \ - case 'H': \ - case 'I': \ - case 'J': \ - case 'K': \ - case 'L': \ - case 'M': \ - case 'N': \ - case 'O': \ - case 'P': \ - case 'Q': \ - case 'R': \ - case 'S': \ - case 'T': \ - case 'U': \ - case 'V': \ - case 'W': \ - case 'X': \ - case 'Y': \ - case 'Z' - -#define ALPHA_CASES \ - UCALPHA_CASES: \ - LCALPHA_CASES - -#define TOKEN_CASES \ - case '!': \ - case '#': \ - case '$': \ - case '%': \ - case '&': \ - case '\'': \ - case '*': \ - case '+': \ - case '-': \ - case '.': \ - case '/': \ - DIGIT_CASES: \ - case ':': \ - UCALPHA_CASES: \ - case '^': \ - case '_': \ - case '`': \ - LCALPHA_CASES: \ - case '|': \ - case '~' - -#define LCHEXALPHA_CASES \ - case 'a': \ - case 'b': \ - case 'c': \ - case 'd': \ - case 'e': \ - case 'f' - -#define X00_1F_CASES \ - case 0x00: \ - case 0x01: \ - case 0x02: \ - case 0x03: \ - case 0x04: \ - case 0x05: \ - case 0x06: \ - case 0x07: \ - case 0x08: \ - case 0x09: \ - case 0x0a: \ - case 0x0b: \ - case 0x0c: \ - case 0x0d: \ - case 0x0e: \ - case 0x0f: \ - case 0x10: \ - case 0x11: \ - case 0x12: \ - case 0x13: \ - case 0x14: \ - case 0x15: \ - case 0x16: \ - case 0x17: \ - case 0x18: \ - case 0x19: \ - case 0x1a: \ - case 0x1b: \ - case 0x1c: \ - case 0x1d: \ - case 0x1e: \ - case 0x1f - -#define X20_21_CASES \ - case ' ': \ - case '!' - -#define X23_5B_CASES \ - case '#': \ - case '$': \ - case '%': \ - case '&': \ - case '\'': \ - case '(': \ - case ')': \ - case '*': \ - case '+': \ - case ',': \ - case '-': \ - case '.': \ - case '/': \ - DIGIT_CASES: \ - case ':': \ - case ';': \ - case '<': \ - case '=': \ - case '>': \ - case '?': \ - case '@': \ - UCALPHA_CASES: \ - case '[' - -#define X5D_7E_CASES \ - case ']': \ - case '^': \ - case '_': \ - case '`': \ - LCALPHA_CASES: \ - case '{': \ - case '|': \ - case '}': \ - case '~' - -#define X7F_FF_CASES \ - case 0x7f: \ - case 0x80: \ - case 0x81: \ - case 0x82: \ - case 0x83: \ - case 0x84: \ - case 0x85: \ - case 0x86: \ - case 0x87: \ - case 0x88: \ - case 0x89: \ - case 0x8a: \ - case 0x8b: \ - case 0x8c: \ - case 0x8d: \ - case 0x8e: \ - case 0x8f: \ - case 0x90: \ - case 0x91: \ - case 0x92: \ - case 0x93: \ - case 0x94: \ - case 0x95: \ - case 0x96: \ - case 0x97: \ - case 0x98: \ - case 0x99: \ - case 0x9a: \ - case 0x9b: \ - case 0x9c: \ - case 0x9d: \ - case 0x9e: \ - case 0x9f: \ - case 0xa0: \ - case 0xa1: \ - case 0xa2: \ - case 0xa3: \ - case 0xa4: \ - case 0xa5: \ - case 0xa6: \ - case 0xa7: \ - case 0xa8: \ - case 0xa9: \ - case 0xaa: \ - case 0xab: \ - case 0xac: \ - case 0xad: \ - case 0xae: \ - case 0xaf: \ - case 0xb0: \ - case 0xb1: \ - case 0xb2: \ - case 0xb3: \ - case 0xb4: \ - case 0xb5: \ - case 0xb6: \ - case 0xb7: \ - case 0xb8: \ - case 0xb9: \ - case 0xba: \ - case 0xbb: \ - case 0xbc: \ - case 0xbd: \ - case 0xbe: \ - case 0xbf: \ - case 0xc0: \ - case 0xc1: \ - case 0xc2: \ - case 0xc3: \ - case 0xc4: \ - case 0xc5: \ - case 0xc6: \ - case 0xc7: \ - case 0xc8: \ - case 0xc9: \ - case 0xca: \ - case 0xcb: \ - case 0xcc: \ - case 0xcd: \ - case 0xce: \ - case 0xcf: \ - case 0xd0: \ - case 0xd1: \ - case 0xd2: \ - case 0xd3: \ - case 0xd4: \ - case 0xd5: \ - case 0xd6: \ - case 0xd7: \ - case 0xd8: \ - case 0xd9: \ - case 0xda: \ - case 0xdb: \ - case 0xdc: \ - case 0xdd: \ - case 0xde: \ - case 0xdf: \ - case 0xe0: \ - case 0xe1: \ - case 0xe2: \ - case 0xe3: \ - case 0xe4: \ - case 0xe5: \ - case 0xe6: \ - case 0xe7: \ - case 0xe8: \ - case 0xe9: \ - case 0xea: \ - case 0xeb: \ - case 0xec: \ - case 0xed: \ - case 0xee: \ - case 0xef: \ - case 0xf0: \ - case 0xf1: \ - case 0xf2: \ - case 0xf3: \ - case 0xf4: \ - case 0xf5: \ - case 0xf6: \ - case 0xf7: \ - case 0xf8: \ - case 0xf9: \ - case 0xfa: \ - case 0xfb: \ - case 0xfc: \ - case 0xfd: \ - case 0xfe: \ - case 0xff - -static int is_ws(uint8_t c) { - switch (c) { - case ' ': - case '\t': - return 1; - default: - return 0; - } -} - -#ifdef __AVX2__ -# ifdef _MSC_VER -# include - -static int ctz(unsigned int v) { - unsigned long n; - - /* Assume that v is not 0. */ - _BitScanForward(&n, v); - - return (int)n; -} -# else /* !_MSC_VER */ -# define ctz __builtin_ctz -# endif /* !_MSC_VER */ -#endif /* __AVX2__ */ - -static int parser_eof(sfparse_parser *sfp) { return sfp->pos == sfp->end; } - -static void parser_discard_ows(sfparse_parser *sfp) { - for (; !parser_eof(sfp) && is_ws(*sfp->pos); ++sfp->pos) - ; -} - -static void parser_discard_sp(sfparse_parser *sfp) { - for (; !parser_eof(sfp) && *sfp->pos == ' '; ++sfp->pos) - ; -} - -static void parser_set_op_state(sfparse_parser *sfp, uint32_t op) { - sfp->state &= ~SFPARSE_STATE_OP_MASK; - sfp->state |= op; -} - -static void parser_unset_inner_list_state(sfparse_parser *sfp) { - sfp->state &= ~SFPARSE_STATE_INNER_LIST; -} - -#ifdef __AVX2__ -static const uint8_t *find_char_key(const uint8_t *first, const uint8_t *last) { - const __m256i us = _mm256_set1_epi8('_'); - const __m256i ds = _mm256_set1_epi8('-'); - const __m256i dot = _mm256_set1_epi8('.'); - const __m256i ast = _mm256_set1_epi8('*'); - const __m256i r0l = _mm256_set1_epi8('0' - 1); - const __m256i r0r = _mm256_set1_epi8('9' + 1); - const __m256i r1l = _mm256_set1_epi8('a' - 1); - const __m256i r1r = _mm256_set1_epi8('z' + 1); - __m256i s, x; - uint32_t m; - - for (; first != last; first += 32) { - s = _mm256_loadu_si256((void *)first); - - x = _mm256_cmpeq_epi8(s, us); - x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ds), x); - x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dot), x); - x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ast), x); - x = _mm256_or_si256( - _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)), - x); - x = _mm256_or_si256( - _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), - x); - - m = ~(uint32_t)_mm256_movemask_epi8(x); - if (m) { - return first + ctz(m); - } - } - - return last; -} -#endif /* __AVX2__ */ - -static int parser_key(sfparse_parser *sfp, sfparse_vec *dest) { - const uint8_t *base; -#ifdef __AVX2__ - const uint8_t *last; -#endif /* __AVX2__ */ - - switch (*sfp->pos) { - case '*': - LCALPHA_CASES: - break; - default: - return SFPARSE_ERR_PARSE; - } - - base = sfp->pos++; - -#ifdef __AVX2__ - if (sfp->end - sfp->pos >= 32) { - last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); - - sfp->pos = find_char_key(sfp->pos, last); - if (sfp->pos != last) { - goto fin; - } - } -#endif /* __AVX2__ */ - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - case '_': - case '-': - case '.': - case '*': - DIGIT_CASES: - LCALPHA_CASES: - continue; - } - - break; - } - -#ifdef __AVX2__ -fin: -#endif /* __AVX2__ */ - if (dest) { - dest->base = (uint8_t *)base; - dest->len = (size_t)(sfp->pos - dest->base); - } - - return 0; -} - -static int parser_number(sfparse_parser *sfp, sfparse_value *dest) { - int sign = 1; - int64_t value = 0; - size_t len = 0; - size_t fpos = 0; - - if (*sfp->pos == '-') { - ++sfp->pos; - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - sign = -1; - } - - assert(!parser_eof(sfp)); - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - DIGIT_CASES: - if (++len > 15) { - return SFPARSE_ERR_PARSE; - } - - value *= 10; - value += *sfp->pos - '0'; - - continue; - } - - break; - } - - if (len == 0) { - return SFPARSE_ERR_PARSE; - } - - if (parser_eof(sfp) || *sfp->pos != '.') { - if (dest) { - dest->type = SFPARSE_TYPE_INTEGER; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - dest->integer = value * sign; - } - - return 0; - } - - /* decimal */ - - if (len > 12) { - return SFPARSE_ERR_PARSE; - } - - fpos = len; - - ++sfp->pos; - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - DIGIT_CASES: - if (++len > 15) { - return SFPARSE_ERR_PARSE; - } - - value *= 10; - value += *sfp->pos - '0'; - - continue; - } - - break; - } - - if (fpos == len || len - fpos > 3) { - return SFPARSE_ERR_PARSE; - } - - if (dest) { - dest->type = SFPARSE_TYPE_DECIMAL; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - dest->decimal.numer = value * sign; - - switch (len - fpos) { - case 1: - dest->decimal.denom = 10; - - break; - case 2: - dest->decimal.denom = 100; - - break; - case 3: - dest->decimal.denom = 1000; - - break; - } - } - - return 0; -} - -static int parser_date(sfparse_parser *sfp, sfparse_value *dest) { - int rv; - sfparse_value val; - - /* The first byte has already been validated by the caller. */ - assert('@' == *sfp->pos); - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - rv = parser_number(sfp, &val); - if (rv != 0) { - return rv; - } - - if (val.type != SFPARSE_TYPE_INTEGER) { - return SFPARSE_ERR_PARSE; - } - - if (dest) { - *dest = val; - dest->type = SFPARSE_TYPE_DATE; - } - - return 0; -} - -#ifdef __AVX2__ -static const uint8_t *find_char_string(const uint8_t *first, - const uint8_t *last) { - const __m256i bs = _mm256_set1_epi8('\\'); - const __m256i dq = _mm256_set1_epi8('"'); - const __m256i del = _mm256_set1_epi8(0x7f); - const __m256i sp = _mm256_set1_epi8(' '); - __m256i s, x; - uint32_t m; - - for (; first != last; first += 32) { - s = _mm256_loadu_si256((void *)first); - - x = _mm256_cmpgt_epi8(sp, s); - x = _mm256_or_si256(_mm256_cmpeq_epi8(s, bs), x); - x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dq), x); - x = _mm256_or_si256(_mm256_cmpeq_epi8(s, del), x); - - m = (uint32_t)_mm256_movemask_epi8(x); - if (m) { - return first + ctz(m); - } - } - - return last; -} -#endif /* __AVX2__ */ - -static int parser_string(sfparse_parser *sfp, sfparse_value *dest) { - const uint8_t *base; -#ifdef __AVX2__ - const uint8_t *last; -#endif /* __AVX2__ */ - uint32_t flags = SFPARSE_VALUE_FLAG_NONE; - - /* The first byte has already been validated by the caller. */ - assert('"' == *sfp->pos); - - base = ++sfp->pos; - -#ifdef __AVX2__ - for (; sfp->end - sfp->pos >= 32; ++sfp->pos) { - last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); - - sfp->pos = find_char_string(sfp->pos, last); - if (sfp->pos == last) { - break; - } - - switch (*sfp->pos) { - case '\\': - ++sfp->pos; - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - switch (*sfp->pos) { - case '"': - case '\\': - flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING; - - break; - default: - return SFPARSE_ERR_PARSE; - } - - break; - case '"': - goto fin; - default: - return SFPARSE_ERR_PARSE; - } - } -#endif /* __AVX2__ */ - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - X20_21_CASES: - X23_5B_CASES: - X5D_7E_CASES: - break; - case '\\': - ++sfp->pos; - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - switch (*sfp->pos) { - case '"': - case '\\': - flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING; - - break; - default: - return SFPARSE_ERR_PARSE; - } - - break; - case '"': - goto fin; - default: - return SFPARSE_ERR_PARSE; - } - } - - return SFPARSE_ERR_PARSE; - -fin: - if (dest) { - dest->type = SFPARSE_TYPE_STRING; - dest->flags = flags; - dest->vec.len = (size_t)(sfp->pos - base); - dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; - } - - ++sfp->pos; - - return 0; -} - -#ifdef __AVX2__ -static const uint8_t *find_char_token(const uint8_t *first, - const uint8_t *last) { - /* r0: !..:, excluding "(), - r1: A..Z - r2: ^..~, excluding {} */ - const __m256i r0l = _mm256_set1_epi8('!' - 1); - const __m256i r0r = _mm256_set1_epi8(':' + 1); - const __m256i dq = _mm256_set1_epi8('"'); - const __m256i prl = _mm256_set1_epi8('('); - const __m256i prr = _mm256_set1_epi8(')'); - const __m256i comma = _mm256_set1_epi8(','); - const __m256i r1l = _mm256_set1_epi8('A' - 1); - const __m256i r1r = _mm256_set1_epi8('Z' + 1); - const __m256i r2l = _mm256_set1_epi8('^' - 1); - const __m256i r2r = _mm256_set1_epi8('~' + 1); - const __m256i cbl = _mm256_set1_epi8('{'); - const __m256i cbr = _mm256_set1_epi8('}'); - __m256i s, x; - uint32_t m; - - for (; first != last; first += 32) { - s = _mm256_loadu_si256((void *)first); - - x = _mm256_andnot_si256( - _mm256_cmpeq_epi8(s, comma), - _mm256_andnot_si256( - _mm256_cmpeq_epi8(s, prr), - _mm256_andnot_si256( - _mm256_cmpeq_epi8(s, prl), - _mm256_andnot_si256(_mm256_cmpeq_epi8(s, dq), - _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), - _mm256_cmpgt_epi8(r0r, s)))))); - x = _mm256_or_si256( - _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), - x); - x = _mm256_or_si256( - _mm256_andnot_si256( - _mm256_cmpeq_epi8(s, cbr), - _mm256_andnot_si256(_mm256_cmpeq_epi8(s, cbl), - _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), - _mm256_cmpgt_epi8(r2r, s)))), - x); - - m = ~(uint32_t)_mm256_movemask_epi8(x); - if (m) { - return first + ctz(m); - } - } - - return last; -} -#endif /* __AVX2__ */ - -static int parser_token(sfparse_parser *sfp, sfparse_value *dest) { - const uint8_t *base; -#ifdef __AVX2__ - const uint8_t *last; -#endif /* __AVX2__ */ - - /* The first byte has already been validated by the caller. */ - base = sfp->pos++; - -#ifdef __AVX2__ - if (sfp->end - sfp->pos >= 32) { - last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); - - sfp->pos = find_char_token(sfp->pos, last); - if (sfp->pos != last) { - goto fin; - } - } -#endif /* __AVX2__ */ - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - TOKEN_CASES: - continue; - } - - break; - } - -#ifdef __AVX2__ -fin: -#endif /* __AVX2__ */ - if (dest) { - dest->type = SFPARSE_TYPE_TOKEN; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - dest->vec.base = (uint8_t *)base; - dest->vec.len = (size_t)(sfp->pos - base); - } - - return 0; -} - -#ifdef __AVX2__ -static const uint8_t *find_char_byteseq(const uint8_t *first, - const uint8_t *last) { - const __m256i pls = _mm256_set1_epi8('+'); - const __m256i fs = _mm256_set1_epi8('/'); - const __m256i r0l = _mm256_set1_epi8('0' - 1); - const __m256i r0r = _mm256_set1_epi8('9' + 1); - const __m256i r1l = _mm256_set1_epi8('A' - 1); - const __m256i r1r = _mm256_set1_epi8('Z' + 1); - const __m256i r2l = _mm256_set1_epi8('a' - 1); - const __m256i r2r = _mm256_set1_epi8('z' + 1); - __m256i s, x; - uint32_t m; - - for (; first != last; first += 32) { - s = _mm256_loadu_si256((void *)first); - - x = _mm256_cmpeq_epi8(s, pls); - x = _mm256_or_si256(_mm256_cmpeq_epi8(s, fs), x); - x = _mm256_or_si256( - _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)), - x); - x = _mm256_or_si256( - _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), - x); - x = _mm256_or_si256( - _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), _mm256_cmpgt_epi8(r2r, s)), - x); - - m = ~(uint32_t)_mm256_movemask_epi8(x); - if (m) { - return first + ctz(m); - } - } - - return last; -} -#endif /* __AVX2__ */ - -static int parser_byteseq(sfparse_parser *sfp, sfparse_value *dest) { - const uint8_t *base; -#ifdef __AVX2__ - const uint8_t *last; -#endif /* __AVX2__ */ - - /* The first byte has already been validated by the caller. */ - assert(':' == *sfp->pos); - - base = ++sfp->pos; - -#ifdef __AVX2__ - if (sfp->end - sfp->pos >= 32) { - last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); - sfp->pos = find_char_byteseq(sfp->pos, last); - } -#endif /* __AVX2__ */ - - for (; !parser_eof(sfp); ++sfp->pos) { - switch (*sfp->pos) { - case '+': - case '/': - DIGIT_CASES: - ALPHA_CASES: - continue; - case '=': - switch ((sfp->pos - base) & 0x3) { - case 0: - case 1: - return SFPARSE_ERR_PARSE; - case 2: - ++sfp->pos; - - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - if (*sfp->pos == '=') { - ++sfp->pos; - } - - break; - case 3: - ++sfp->pos; - - break; - } - - if (parser_eof(sfp) || *sfp->pos != ':') { - return SFPARSE_ERR_PARSE; - } - - goto fin; - case ':': - if (((sfp->pos - base) & 0x3) == 1) { - return SFPARSE_ERR_PARSE; - } - - goto fin; - default: - return SFPARSE_ERR_PARSE; - } - } - - return SFPARSE_ERR_PARSE; - -fin: - if (dest) { - dest->type = SFPARSE_TYPE_BYTESEQ; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - dest->vec.len = (size_t)(sfp->pos - base); - dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; - } - - ++sfp->pos; - - return 0; -} - -static int parser_boolean(sfparse_parser *sfp, sfparse_value *dest) { - int b; - - /* The first byte has already been validated by the caller. */ - assert('?' == *sfp->pos); - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - switch (*sfp->pos) { - case '0': - b = 0; - - break; - case '1': - b = 1; - - break; - default: - return SFPARSE_ERR_PARSE; - } - - ++sfp->pos; - - if (dest) { - dest->type = SFPARSE_TYPE_BOOLEAN; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - dest->boolean = b; - } - - return 0; -} - -static int pctdecode(uint8_t *pc, const uint8_t **ppos) { - uint8_t c, b = **ppos; - - switch (b) { - DIGIT_CASES: - c = (uint8_t)((b - '0') << 4); - - break; - LCHEXALPHA_CASES: - c = (uint8_t)((b - 'a' + 10) << 4); - - break; - default: - return -1; - } - - b = *++*ppos; - - switch (b) { - DIGIT_CASES: - c |= (uint8_t)(b - '0'); - - break; - LCHEXALPHA_CASES: - c |= (uint8_t)(b - 'a' + 10); - - break; - default: - return -1; - } - - *pc = c; - ++*ppos; - - return 0; -} - -/* Start of utf8 dfa */ -/* Copyright (c) 2008-2010 Bjoern Hoehrmann - * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. - * - * Copyright (c) 2008-2009 Bjoern Hoehrmann - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#define UTF8_ACCEPT 0 -#define UTF8_REJECT 12 - -/* clang-format off */ -static const uint8_t utf8d[] = { - /* - * The first part of the table maps bytes to character classes that - * to reduce the size of the transition table and create bitmasks. - */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, - - /* - * The second part is a transition table that maps a combination - * of a state of the automaton and a character class to a state. - */ - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, - 12,36,12,12,12,12,12,12,12,12,12,12, -}; -/* clang-format on */ - -static void utf8_decode(uint32_t *state, uint8_t byte) { - *state = utf8d[256 + *state + utf8d[byte]]; -} - -/* End of utf8 dfa */ - -static int parser_dispstring(sfparse_parser *sfp, sfparse_value *dest) { - const uint8_t *base; - uint8_t c; - uint32_t utf8state = UTF8_ACCEPT; - - assert('%' == *sfp->pos); - - ++sfp->pos; - - if (parser_eof(sfp) || *sfp->pos != '"') { - return SFPARSE_ERR_PARSE; - } - - base = ++sfp->pos; - - for (; !parser_eof(sfp);) { - switch (*sfp->pos) { - X00_1F_CASES: - X7F_FF_CASES: - return SFPARSE_ERR_PARSE; - case '%': - ++sfp->pos; - - if (sfp->pos + 2 > sfp->end) { - return SFPARSE_ERR_PARSE; - } - - if (pctdecode(&c, &sfp->pos) != 0) { - return SFPARSE_ERR_PARSE; - } - - utf8_decode(&utf8state, c); - if (utf8state == UTF8_REJECT) { - return SFPARSE_ERR_PARSE; - } - - break; - case '"': - if (utf8state != UTF8_ACCEPT) { - return SFPARSE_ERR_PARSE; - } - - if (dest) { - dest->type = SFPARSE_TYPE_DISPSTRING; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - dest->vec.len = (size_t)(sfp->pos - base); - dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; - } - - ++sfp->pos; - - return 0; - default: - if (utf8state != UTF8_ACCEPT) { - return SFPARSE_ERR_PARSE; - } - - ++sfp->pos; - } - } - - return SFPARSE_ERR_PARSE; -} - -static int parser_bare_item(sfparse_parser *sfp, sfparse_value *dest) { - switch (*sfp->pos) { - case '"': - return parser_string(sfp, dest); - case '-': - DIGIT_CASES: - return parser_number(sfp, dest); - case '@': - return parser_date(sfp, dest); - case ':': - return parser_byteseq(sfp, dest); - case '?': - return parser_boolean(sfp, dest); - case '*': - ALPHA_CASES: - return parser_token(sfp, dest); - case '%': - return parser_dispstring(sfp, dest); - default: - return SFPARSE_ERR_PARSE; - } -} - -static int parser_skip_inner_list(sfparse_parser *sfp); - -int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key, - sfparse_value *dest_value) { - int rv; - - switch (sfp->state & SFPARSE_STATE_OP_MASK) { - case SFPARSE_STATE_BEFORE: - rv = parser_skip_inner_list(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SFPARSE_STATE_BEFORE_PARAMS: - parser_set_op_state(sfp, SFPARSE_STATE_PARAMS); - - break; - case SFPARSE_STATE_PARAMS: - break; - default: - assert(0); - abort(); - } - - if (parser_eof(sfp) || *sfp->pos != ';') { - parser_set_op_state(sfp, SFPARSE_STATE_AFTER); - - return SFPARSE_ERR_EOF; - } - - ++sfp->pos; - - parser_discard_sp(sfp); - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - rv = parser_key(sfp, dest_key); - if (rv != 0) { - return rv; - } - - if (parser_eof(sfp) || *sfp->pos != '=') { - if (dest_value) { - dest_value->type = SFPARSE_TYPE_BOOLEAN; - dest_value->flags = SFPARSE_VALUE_FLAG_NONE; - dest_value->boolean = 1; - } - - return 0; - } - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - return parser_bare_item(sfp, dest_value); -} - -static int parser_skip_params(sfparse_parser *sfp) { - int rv; - - for (;;) { - rv = sfparse_parser_param(sfp, NULL, NULL); - switch (rv) { - case 0: - break; - case SFPARSE_ERR_EOF: - return 0; - case SFPARSE_ERR_PARSE: - return rv; - default: - assert(0); - abort(); - } - } -} - -int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest) { - int rv; - - switch (sfp->state & SFPARSE_STATE_OP_MASK) { - case SFPARSE_STATE_BEFORE: - parser_discard_sp(sfp); - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - break; - case SFPARSE_STATE_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* Technically, we are entering SFPARSE_STATE_AFTER, but we will set - another state without reading the state. */ - /* parser_set_op_state(sfp, SFPARSE_STATE_AFTER); */ - - /* fall through */ - case SFPARSE_STATE_AFTER: - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - switch (*sfp->pos) { - case ' ': - parser_discard_sp(sfp); - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - break; - case ')': - break; - default: - return SFPARSE_ERR_PARSE; - } - - break; - default: - assert(0); - abort(); - } - - if (*sfp->pos == ')') { - ++sfp->pos; - - parser_unset_inner_list_state(sfp); - parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS); - - return SFPARSE_ERR_EOF; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS); - - return 0; -} - -static int parser_skip_inner_list(sfparse_parser *sfp) { - int rv; - - for (;;) { - rv = sfparse_parser_inner_list(sfp, NULL); - switch (rv) { - case 0: - break; - case SFPARSE_ERR_EOF: - return 0; - case SFPARSE_ERR_PARSE: - return rv; - default: - assert(0); - abort(); - } - } -} - -static int parser_next_key_or_item(sfparse_parser *sfp) { - parser_discard_ows(sfp); - - if (parser_eof(sfp)) { - return SFPARSE_ERR_EOF; - } - - if (*sfp->pos != ',') { - return SFPARSE_ERR_PARSE; - } - - ++sfp->pos; - - parser_discard_ows(sfp); - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - return 0; -} - -static int parser_dict_value(sfparse_parser *sfp, sfparse_value *dest) { - int rv; - - if (parser_eof(sfp) || *(sfp->pos) != '=') { - /* Boolean true */ - if (dest) { - dest->type = SFPARSE_TYPE_BOOLEAN; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - dest->boolean = 1; - } - - sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS; - - return 0; - } - - ++sfp->pos; - - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - if (*sfp->pos == '(') { - if (dest) { - dest->type = SFPARSE_TYPE_INNER_LIST; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - } - - ++sfp->pos; - - sfp->state = SFPARSE_STATE_DICT_INNER_LIST_BEFORE; - - return 0; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS; - - return 0; -} - -int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key, - sfparse_value *dest_value) { - int rv; - - switch (sfp->state) { - case SFPARSE_STATE_DICT_INNER_LIST_BEFORE: - rv = parser_skip_inner_list(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SFPARSE_STATE_DICT_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SFPARSE_STATE_DICT_AFTER: - rv = parser_next_key_or_item(sfp); - if (rv != 0) { - return rv; - } - - break; - case SFPARSE_STATE_INITIAL: - parser_discard_sp(sfp); - - if (parser_eof(sfp)) { - return SFPARSE_ERR_EOF; - } - - break; - default: - assert(0); - abort(); - } - - rv = parser_key(sfp, dest_key); - if (rv != 0) { - return rv; - } - - return parser_dict_value(sfp, dest_value); -} - -int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest) { - int rv; - - switch (sfp->state) { - case SFPARSE_STATE_LIST_INNER_LIST_BEFORE: - rv = parser_skip_inner_list(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SFPARSE_STATE_LIST_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SFPARSE_STATE_LIST_AFTER: - rv = parser_next_key_or_item(sfp); - if (rv != 0) { - return rv; - } - - break; - case SFPARSE_STATE_INITIAL: - parser_discard_sp(sfp); - - if (parser_eof(sfp)) { - return SFPARSE_ERR_EOF; - } - - break; - default: - assert(0); - abort(); - } - - if (*sfp->pos == '(') { - if (dest) { - dest->type = SFPARSE_TYPE_INNER_LIST; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - } - - ++sfp->pos; - - sfp->state = SFPARSE_STATE_LIST_INNER_LIST_BEFORE; - - return 0; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - sfp->state = SFPARSE_STATE_LIST_BEFORE_PARAMS; - - return 0; -} - -int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest) { - int rv; - - switch (sfp->state) { - case SFPARSE_STATE_INITIAL: - parser_discard_sp(sfp); - - if (parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - break; - case SFPARSE_STATE_ITEM_INNER_LIST_BEFORE: - rv = parser_skip_inner_list(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SFPARSE_STATE_ITEM_BEFORE_PARAMS: - rv = parser_skip_params(sfp); - if (rv != 0) { - return rv; - } - - /* fall through */ - case SFPARSE_STATE_ITEM_AFTER: - parser_discard_sp(sfp); - - if (!parser_eof(sfp)) { - return SFPARSE_ERR_PARSE; - } - - return SFPARSE_ERR_EOF; - default: - assert(0); - abort(); - } - - if (*sfp->pos == '(') { - if (dest) { - dest->type = SFPARSE_TYPE_INNER_LIST; - dest->flags = SFPARSE_VALUE_FLAG_NONE; - } - - ++sfp->pos; - - sfp->state = SFPARSE_STATE_ITEM_INNER_LIST_BEFORE; - - return 0; - } - - rv = parser_bare_item(sfp, dest); - if (rv != 0) { - return rv; - } - - sfp->state = SFPARSE_STATE_ITEM_BEFORE_PARAMS; - - return 0; -} - -void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data, - size_t datalen) { - if (datalen == 0) { - sfp->pos = sfp->end = NULL; - } else { - sfp->pos = data; - sfp->end = data + datalen; - } - - sfp->state = SFPARSE_STATE_INITIAL; -} - -void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src) { - const uint8_t *p, *q; - uint8_t *o; - size_t len, slen; - - if (src->len == 0) { - dest->len = 0; - - return; - } - - o = dest->base; - p = src->base; - len = src->len; - - for (;;) { - q = memchr(p, '\\', len); - if (q == NULL) { - memcpy(o, p, len); - o += len; - - dest->len = (size_t)(o - dest->base); - - return; - } - - slen = (size_t)(q - p); - memcpy(o, p, slen); - o += slen; - - p = q + 1; - *o++ = *p++; - len -= slen + 2; - } -} - -void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src) { - static const int index_tbl[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, - -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}; - uint8_t *o; - const uint8_t *p, *end; - uint32_t n; - size_t i, left; - int idx; - - if (src->len == 0) { - dest->len = 0; - - return; - } - - o = dest->base; - p = src->base; - left = src->len & 0x3; - if (left == 0 && src->base[src->len - 1] == '=') { - left = 4; - } - end = src->base + src->len - left; - - for (; p != end;) { - n = 0; - - for (i = 1; i <= 4; ++i, ++p) { - idx = index_tbl[*p]; - - assert(idx != -1); - - n += (uint32_t)(idx << (24 - i * 6)); - } - - *o++ = (uint8_t)(n >> 16); - *o++ = (n >> 8) & 0xffu; - *o++ = n & 0xffu; - } - - switch (left) { - case 0: - goto fin; - case 1: - assert(0); - abort(); - case 3: - if (src->base[src->len - 1] == '=') { - left = 2; - } - - break; - case 4: - assert('=' == src->base[src->len - 1]); - - if (src->base[src->len - 2] == '=') { - left = 2; - } else { - left = 3; - } - - break; - } - - switch (left) { - case 2: - *o = (uint8_t)(index_tbl[*p++] << 2); - *o++ |= (uint8_t)(index_tbl[*p++] >> 4); - - break; - case 3: - n = (uint32_t)(index_tbl[*p++] << 10); - n += (uint32_t)(index_tbl[*p++] << 4); - n += (uint32_t)(index_tbl[*p++] >> 2); - *o++ = (n >> 8) & 0xffu; - *o++ = n & 0xffu; - - break; - } - -fin: - dest->len = (size_t)(o - dest->base); -} - -void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src) { - const uint8_t *p, *q; - uint8_t *o; - size_t len, slen; - - if (src->len == 0) { - dest->len = 0; - - return; - } - - o = dest->base; - p = src->base; - len = src->len; - - for (;;) { - q = memchr(p, '%', len); - if (q == NULL) { - memcpy(o, p, len); - o += len; - - dest->len = (size_t)(o - dest->base); - - return; - } - - slen = (size_t)(q - p); - memcpy(o, p, slen); - o += slen; - - p = q + 1; - - pctdecode(o++, &p); - - len -= slen + 3; - } -} diff --git a/vendor/nghttp2/lib/sfparse.h b/vendor/nghttp2/lib/sfparse.h deleted file mode 100644 index 9341221a0..000000000 --- a/vendor/nghttp2/lib/sfparse.h +++ /dev/null @@ -1,442 +0,0 @@ -/* - * sfparse - * - * Copyright (c) 2023 sfparse contributors - * Copyright (c) 2019 nghttp3 contributors - * Copyright (c) 2015 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef SFPARSE_H -#define SFPARSE_H - -/* Define WIN32 when build target is Win32 API (borrowed from - libcurl) */ -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */ - -#ifdef __cplusplus -extern "C" { -#endif /* defined(__cplusplus) */ - -#if defined(_MSC_VER) && (_MSC_VER < 1800) -/* MSVC < 2013 does not have inttypes.h because it is not C99 - compliant. See compiler macros and version number in - https://sourceforge.net/p/predef/wiki/Compilers/ */ -# include -#else /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */ -# include -#endif /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */ -#include -#include - -/** - * @enum - * - * :type:`sfparse_type` defines value type. - */ -typedef enum sfparse_type { - /** - * :enum:`SFPARSE_TYPE_BOOLEAN` indicates boolean type. - */ - SFPARSE_TYPE_BOOLEAN, - /** - * :enum:`SFPARSE_TYPE_INTEGER` indicates integer type. - */ - SFPARSE_TYPE_INTEGER, - /** - * :enum:`SFPARSE_TYPE_DECIMAL` indicates decimal type. - */ - SFPARSE_TYPE_DECIMAL, - /** - * :enum:`SFPARSE_TYPE_STRING` indicates string type. - */ - SFPARSE_TYPE_STRING, - /** - * :enum:`SFPARSE_TYPE_TOKEN` indicates token type. - */ - SFPARSE_TYPE_TOKEN, - /** - * :enum:`SFPARSE_TYPE_BYTESEQ` indicates byte sequence type. - */ - SFPARSE_TYPE_BYTESEQ, - /** - * :enum:`SFPARSE_TYPE_INNER_LIST` indicates inner list type. - */ - SFPARSE_TYPE_INNER_LIST, - /** - * :enum:`SFPARSE_TYPE_DATE` indicates date type. - */ - SFPARSE_TYPE_DATE, - /** - * :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string type. - */ - SFPARSE_TYPE_DISPSTRING -} sfparse_type; - -/** - * @macro - * - * :macro:`SFPARSE_ERR_PARSE` indicates fatal parse error has - * occurred, and it is not possible to continue the processing. - */ -#define SFPARSE_ERR_PARSE -1 - -/** - * @macro - * - * :macro:`SFPARSE_ERR_EOF` indicates that there is nothing left to - * read. The context of this error varies depending on the function - * that returns this error code. - */ -#define SFPARSE_ERR_EOF -2 - -/** - * @struct - * - * :type:`sfparse_vec` stores sequence of bytes. - */ -typedef struct sfparse_vec { - /** - * :member:`base` points to the beginning of the sequence of bytes. - */ - uint8_t *base; - /** - * :member:`len` is the number of bytes contained in this sequence. - */ - size_t len; -} sfparse_vec; - -/** - * @macro - * - * :macro:`SFPARSE_VALUE_FLAG_NONE` indicates no flag set. - */ -#define SFPARSE_VALUE_FLAG_NONE 0x0u - -/** - * @macro - * - * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` indicates that a string - * contains escaped character(s). - */ -#define SFPARSE_VALUE_FLAG_ESCAPED_STRING 0x1u - -/** - * @struct - * - * :type:`sfparse_decimal` contains decimal value. - */ -typedef struct sfparse_decimal { - /** - * :member:`numer` contains numerator of the decimal value. - */ - int64_t numer; - /** - * :member:`denom` contains denominator of the decimal value. - */ - int64_t denom; -} sfparse_decimal; - -/** - * @struct - * - * :type:`sfparse_value` stores a Structured Field item. For Inner - * List, only type is set to - * :enum:`sfparse_type.SFPARSE_TYPE_INNER_LIST`. In order to read the - * items contained in an inner list, call `sfparse_parser_inner_list`. - */ -typedef struct sfparse_value { - /** - * :member:`type` is the type of the value contained in this - * particular object. - */ - sfparse_type type; - /** - * :member:`flags` is bitwise OR of one or more of - * :macro:`SFPARSE_VALUE_FLAG_* `. - */ - uint32_t flags; - /** - * @anonunion_start - * - * @sfparse_value_value - */ - union { - /** - * :member:`boolean` contains boolean value if :member:`type` == - * :enum:`sfparse_type.SFPARSE_TYPE_BOOLEAN`. 1 indicates true, - * and 0 indicates false. - */ - int boolean; - /** - * :member:`integer` contains integer value if :member:`type` is - * either :enum:`sfparse_type.SFPARSE_TYPE_INTEGER` or - * :enum:`sfparse_type.SFPARSE_TYPE_DATE`. - */ - int64_t integer; - /** - * :member:`decimal` contains decimal value if :member:`type` == - * :enum:`sfparse_type.SFPARSE_TYPE_DECIMAL`. - */ - sfparse_decimal decimal; - /** - * :member:`vec` contains sequence of bytes if :member:`type` is - * either :enum:`sfparse_type.SFPARSE_TYPE_STRING`, - * :enum:`sfparse_type.SFPARSE_TYPE_TOKEN`, - * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, or - * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`. - * - * For :enum:`sfparse_type.SFPARSE_TYPE_STRING`, this field - * contains one or more escaped characters if :member:`flags` has - * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` set. To unescape - * the string, use `sfparse_unescape`. - * - * For :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, this field - * contains base64 encoded string. To decode this byte string, - * use `sfparse_base64decode`. - * - * For :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`, this field - * may contain percent-encoded UTF-8 byte sequences. To decode - * it, use `sfparse_pctdecode`. - * - * If :member:`vec.len ` == 0, :member:`vec.base - * ` is guaranteed to be NULL. - */ - sfparse_vec vec; - /** - * @anonunion_end - */ - }; -} sfparse_value; - -/** - * @struct - * - * :type:`sfparse_parser` is the Structured Field Values parser. Use - * `sfparse_parser_init` to initialize it. - */ -typedef struct sfparse_parser { - /* all fields are private */ - const uint8_t *pos; - const uint8_t *end; - uint32_t state; -} sfparse_parser; - -/** - * @function - * - * `sfparse_parser_init` initializes |sfp| with the given data encoded - * in Structured Field Values pointed by |data| of length |datalen|. - */ -void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data, - size_t datalen); - -/** - * @function - * - * `sfparse_parser_param` reads a parameter. If this function returns - * 0, it stores parameter key and value in |dest_key| and |dest_value| - * respectively, if they are not NULL. - * - * This function does no effort to find duplicated keys. Same key may - * be reported more than once. - * - * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all parameters - * have read, and caller can continue to read rest of the values. If - * it returns :macro:`SFPARSE_ERR_PARSE`, it encountered fatal error - * while parsing field value. - */ -int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key, - sfparse_value *dest_value); - -/** - * @function - * - * `sfparse_parser_dict` reads the next dictionary key and value pair. - * If this function returns 0, it stores the key and value in - * |dest_key| and |dest_value| respectively, if they are not NULL. - * - * Caller can optionally read parameters attached to the pair by - * calling `sfparse_parser_param`. - * - * This function does no effort to find duplicated keys. Same key may - * be reported more than once. - * - * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all key and - * value pairs have been read, and there is nothing left to read. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :macro:`SFPARSE_ERR_EOF` - * All values in the dictionary have read. - * :macro:`SFPARSE_ERR_PARSE` - * It encountered fatal error while parsing field value. - */ -int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key, - sfparse_value *dest_value); - -/** - * @function - * - * `sfparse_parser_list` reads the next list item. If this function - * returns 0, it stores the item in |dest| if it is not NULL. - * - * Caller can optionally read parameters attached to the item by - * calling `sfparse_parser_param`. - * - * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in - * the list have been read, and there is nothing left to read. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :macro:`SFPARSE_ERR_EOF` - * All values in the list have read. - * :macro:`SFPARSE_ERR_PARSE` - * It encountered fatal error while parsing field value. - */ -int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest); - -/** - * @function - * - * `sfparse_parser_item` reads a single item. If this function - * returns 0, it stores the item in |dest| if it is not NULL. - * - * This function is only used for the field value that consists of a - * single item. - * - * Caller can optionally read parameters attached to the item by - * calling `sfparse_parser_param`. - * - * Caller should call this function again to make sure that there is - * nothing left to read. If this 2nd function call returns - * :macro:`SFPARSE_ERR_EOF`, all data have been processed - * successfully. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :macro:`SFPARSE_ERR_EOF` - * There is nothing left to read. - * :macro:`SFPARSE_ERR_PARSE` - * It encountered fatal error while parsing field value. - */ -int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest); - -/** - * @function - * - * `sfparse_parser_inner_list` reads the next inner list item. If - * this function returns 0, it stores the item in |dest| if it is not - * NULL. - * - * Caller can optionally read parameters attached to the item by - * calling `sfparse_parser_param`. - * - * Caller should keep calling this function until it returns negative - * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in - * this inner list have been read, and caller can optionally read - * parameters attached to this inner list by calling - * `sfparse_parser_param`. Then caller can continue to read rest of - * the values. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :macro:`SFPARSE_ERR_EOF` - * All values in the inner list have read. - * :macro:`SFPARSE_ERR_PARSE` - * It encountered fatal error while parsing field value. - */ -int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest); - -/** - * @function - * - * `sfparse_unescape` copies |src| to |dest| by removing escapes - * (``\``). |src| should be the pointer to - * :member:`sfparse_value.vec` of type - * :enum:`sfparse_type.SFPARSE_TYPE_STRING` produced by either - * `sfparse_parser_dict`, `sfparse_parser_list`, - * `sfparse_parser_inner_list`, `sfparse_parser_item`, or - * `sfparse_parser_param`, otherwise the behavior is undefined. - * - * :member:`dest->base ` must point to the buffer - * that has sufficient space to store the unescaped string. The - * memory areas pointed by :member:`dest->base ` and - * :member:`src->base ` must not overlap. - * - * This function sets the length of unescaped string to - * :member:`dest->len `. - */ -void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src); - -/** - * @function - * - * `sfparse_base64decode` decodes Base64 encoded string |src| and - * writes the result into |dest|. |src| should be the pointer to - * :member:`sfparse_value.vec` of type - * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ` produced by either - * `sfparse_parser_dict`, `sfparse_parser_list`, - * `sfparse_parser_inner_list`, `sfparse_parser_item`, or - * `sfparse_parser_param`, otherwise the behavior is undefined. - * - * :member:`dest->base ` must point to the buffer - * that has sufficient space to store the decoded byte string. - * - * This function sets the length of decoded byte string to - * :member:`dest->len `. - */ -void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src); - -/** - * @function - * - * `sfparse_pctdecode` decodes percent-encoded string |src| and writes - * the result into |dest|. |src| should be the pointer to - * :member:`sfparse_value.vec` of type - * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING` produced by either - * `sfparse_parser_dict`, `sfparse_parser_list`, - * `sfparse_parser_inner_list`, `sfparse_parser_item`, or - * `sfparse_parser_param`, otherwise the behavior is undefined. - * - * :member:`dest->base ` must point to the buffer - * that has sufficient space to store the decoded byte string. The - * memory areas pointed by :member:`dest->base ` and - * :member:`src->base ` must not overlap. - * - * This function sets the length of decoded byte string to - * :member:`dest->len `. - */ -void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src); - -#ifdef __cplusplus -} -#endif /* defined(__cplusplus) */ - -#endif /* !defined(SFPARSE_H) */ diff --git a/vendor/zlib.mask b/vendor/zlib.mask deleted file mode 100644 index 9c1ba816a..000000000 --- a/vendor/zlib.mask +++ /dev/null @@ -1,33 +0,0 @@ -amiga -contrib -doc -examples -msdos -nintendods -old -os400 -qnx -test -watcom -win32 -ChangeLog -configure -FAQ -INDEX -make_vms.com -CMakeLists.txt -Makefile -Makefile.in -zconf.h.in -README -treebuild.xml -zlib.3 -zlib.3.pdf -zlib.map -zlib.pc.cmakein -zlib.pc.in -.cmake-format.yaml -BUILD.bazel -MODULE.bazel -README-cmake.md -zlibConfig.cmake.in diff --git a/vendor/zlib/LICENSE b/vendor/zlib/LICENSE deleted file mode 100644 index b7a69d058..000000000 --- a/vendor/zlib/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright notice: - - (C) 1995-2026 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu diff --git a/vendor/zlib/adler32.c b/vendor/zlib/adler32.c deleted file mode 100644 index 04b81d29b..000000000 --- a/vendor/zlib/adler32.c +++ /dev/null @@ -1,164 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { - return adler32_z(adler, buf, len); -} - -/* ========================================================================= */ -local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { - return adler32_combine_(adler1, adler2, len2); -} diff --git a/vendor/zlib/compress.c b/vendor/zlib/compress.c deleted file mode 100644 index bd74b9488..000000000 --- a/vendor/zlib/compress.c +++ /dev/null @@ -1,99 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. - - The _z versions of the functions take size_t length arguments. -*/ -int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, - z_size_t sourceLen, int level) { - z_stream stream; - int err; - const uInt max = (uInt)-1; - z_size_t left; - - if ((sourceLen > 0 && source == NULL) || - destLen == NULL || (*destLen > 0 && dest == NULL)) - return Z_STREAM_ERROR; - - left = *destLen; - *destLen = 0; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (z_size_t)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (z_size_t)max ? max : - (uInt)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = (z_size_t)(stream.next_out - dest); - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} -int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen, int level) { - int ret; - z_size_t got = *destLen; - ret = compress2_z(dest, &got, source, sourceLen, level); - *destLen = (uLong)got; - return ret; -} -/* =========================================================================== - */ -int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, - z_size_t sourceLen) { - return compress2_z(dest, destLen, source, sourceLen, - Z_DEFAULT_COMPRESSION); -} -int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) { - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -z_size_t ZEXPORT compressBound_z(z_size_t sourceLen) { - z_size_t bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; - return bound < sourceLen ? (z_size_t)-1 : bound; -} -uLong ZEXPORT compressBound(uLong sourceLen) { - z_size_t bound = compressBound_z(sourceLen); - return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; -} diff --git a/vendor/zlib/crc32.c b/vendor/zlib/crc32.c deleted file mode 100644 index d9ade5150..000000000 --- a/vendor/zlib/crc32.c +++ /dev/null @@ -1,983 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * This interleaved implementation of a CRC makes use of pipelined multiple - * arithmetic-logic units, commonly found in modern CPU cores. It is due to - * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - MAKECRCH can be #defined to write out crc32.h. A main() routine is also - produced, so that this one source file can be compiled to an executable. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif -#endif -#ifdef DYNAMIC_CRC_TABLE -# define Z_ONCE -#endif - -#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ - -#ifdef HAVE_S390X_VX -# include "contrib/crc32vx/crc32_vx_hooks.h" -#endif - - /* - A CRC of a message is computed on N braids of words in the message, where - each word consists of W bytes (4 or 8). If N is 3, for example, then three - running sparse CRCs are calculated respectively on each braid, at these - indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... - This is done starting at a word boundary, and continues until as many blocks - of N * W bytes as are available have been processed. The results are combined - into a single CRC at the end. For this code, N must be in the range 1..6 and - W must be 4 or 8. The upper limit on N can be increased if desired by adding - more #if blocks, extending the patterns apparent in the code. In addition, - crc32.h would need to be regenerated, if the maximum N value is increased. - - N and W are chosen empirically by benchmarking the execution time on a given - processor. The choices for N and W below were based on testing on Intel Kaby - Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 - Octeon II processors. The Intel, AMD, and ARM processors were all fastest - with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. - They were all tested with either gcc or clang, all using the -O3 optimization - level. Your mileage may vary. - */ - -/* Define N */ -#ifdef Z_TESTN -# define N Z_TESTN -#else -# define N 5 -#endif -#if N < 1 || N > 6 -# error N must be in 1..6 -#endif - -/* - z_crc_t must be at least 32 bits. z_word_t must be at least as long as - z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and - that bytes are eight bits. - */ - -/* - Define W and the associated z_word_t type. If W is not defined, then a - braided calculation is not used, and the associated tables and code are not - compiled. - */ -#ifdef Z_TESTW -# if Z_TESTW-1 != -1 -# define W Z_TESTW -# endif -#else -# ifdef MAKECRCH -# define W 8 /* required for MAKECRCH */ -# else -# if defined(__x86_64__) || defined(__aarch64__) -# define W 8 -# else -# define W 4 -# endif -# endif -#endif -#ifdef W -# if W == 8 && defined(Z_U8) - typedef Z_U8 z_word_t; -# elif defined(Z_U4) -# undef W -# define W 4 - typedef Z_U4 z_word_t; -# else -# undef W -# endif -#endif - -/* If available, use the ARM processor CRC32 instruction. */ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && \ - defined(W) && W == 8 -# define ARMCRC32 -#endif - -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) -/* - Swap the bytes in a z_word_t to convert between little and big endian. Any - self-respecting compiler will optimize this to a single machine byte-swap - instruction, if one is available. This assumes that word_t is either 32 bits - or 64 bits. - */ -local z_word_t byte_swap(z_word_t word) { -# if W == 8 - return - (word & 0xff00000000000000) >> 56 | - (word & 0xff000000000000) >> 40 | - (word & 0xff0000000000) >> 24 | - (word & 0xff00000000) >> 8 | - (word & 0xff000000) << 8 | - (word & 0xff0000) << 24 | - (word & 0xff00) << 40 | - (word & 0xff) << 56; -# else /* W == 4 */ - return - (word & 0xff000000) >> 24 | - (word & 0xff0000) >> 8 | - (word & 0xff00) << 8 | - (word & 0xff) << 24; -# endif -} -#endif - -#ifdef DYNAMIC_CRC_TABLE -/* ========================================================================= - * Table of powers of x for combining CRC-32s, filled in by make_crc_table() - * below. - */ - local z_crc_t FAR x2n_table[32]; -#else -/* ========================================================================= - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -# include "crc32.h" -#endif - -/* CRC polynomial. */ -#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local uLong multmodp(uLong a, uLong b) { - uLong m, p; - - m = (uLong)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. n must not be negative. - */ -local uLong x2nmodp(z_off64_t n, unsigned k) { - uLong p; - - p = (uLong)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - -#ifdef DYNAMIC_CRC_TABLE -/* ========================================================================= - * Build the tables for byte-wise and braided CRC-32 calculations, and a table - * of powers of x for combining CRC-32s. - */ -local z_crc_t FAR crc_table[256]; -#ifdef W - local z_word_t FAR crc_big_table[256]; - local z_crc_t FAR crc_braid_table[W][256]; - local z_word_t FAR crc_braid_big_table[W][256]; - local void braid(z_crc_t [][256], z_word_t [][256], int, int); -#endif -#ifdef MAKECRCH - local void write_table(FILE *, const z_crc_t FAR *, int); - local void write_table32hi(FILE *, const z_word_t FAR *, int); - local void write_table64(FILE *, const z_word_t FAR *, int); -#endif /* MAKECRCH */ - -/* State for once(). */ -local z_once_t made = Z_ONCE_INIT; - -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x - (which is shifting right by one and adding x^32 mod p if the bit shifted out - is a one). We start with the highest power (least significant bit) of q and - repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all the - information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. - */ - -local void make_crc_table(void) { - unsigned i, j, n; - z_crc_t p; - - /* initialize the CRC of bytes tables */ - for (i = 0; i < 256; i++) { - p = i; - for (j = 0; j < 8; j++) - p = p & 1 ? (p >> 1) ^ POLY : p >> 1; - crc_table[i] = p; -#ifdef W - crc_big_table[i] = byte_swap(p); -#endif - } - - /* initialize the x^2^n mod p(x) table */ - p = (z_crc_t)1 << 30; /* x^1 */ - x2n_table[0] = p; - for (n = 1; n < 32; n++) - x2n_table[n] = p = (z_crc_t)multmodp(p, p); - -#ifdef W - /* initialize the braiding tables -- needs x2n_table[] */ - braid(crc_braid_table, crc_braid_big_table, N, W); -#endif - -#ifdef MAKECRCH - { - /* - The crc32.h header file contains tables for both 32-bit and 64-bit - z_word_t's, and so requires a 64-bit type be available. In that case, - z_word_t must be defined to be 64-bits. This code then also generates - and writes out the tables for the case that z_word_t is 32 bits. - */ -#if !defined(W) || W != 8 -# error Need a 64-bit integer type in order to generate crc32.h. -#endif - FILE *out; - int k, n; - z_crc_t ltl[8][256]; - z_word_t big[8][256]; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - - /* write out little-endian CRC table to crc32.h */ - fprintf(out, - "/* crc32.h -- tables for rapid CRC calculation\n" - " * Generated automatically by crc32.c\n */\n" - "\n" - "local const z_crc_t FAR crc_table[] = {\n" - " "); - write_table(out, crc_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#ifdef W\n" - "\n" - "#if W == 8\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table64(out, crc_big_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table32hi(out, crc_big_table, 256); - fprintf(out, - "};\n" - "\n" - "#endif\n"); - - /* write out braid tables for each value of N */ - for (n = 1; n <= 6; n++) { - fprintf(out, - "\n" - "#if N == %d\n", n); - - /* compute braid tables for this N and 64-bit word_t */ - braid(ltl, big, n, 8); - - /* write out braid tables for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#if W == 8\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table64(out, big[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n"); - - /* compute braid tables for this N and 32-bit word_t */ - braid(ltl, big, n, 4); - - /* write out braid tables for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table32hi(out, big[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "#endif\n" - "\n" - "#endif\n"); - } - fprintf(out, - "\n" - "#endif\n"); - - /* write out zeros operator table to crc32.h */ - fprintf(out, - "\n" - "local const z_crc_t FAR x2n_table[] = {\n" - " "); - write_table(out, x2n_table, 32); - fprintf(out, - "};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH - -/* - Write the 32-bit values in table[0..k-1] to out, five per line in - hexadecimal separated by commas. - */ -local void write_table(FILE *out, const z_crc_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the high 32-bits of each value in table[0..k-1] to out, five per line - in hexadecimal separated by commas. - */ -local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n] >> 32), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the 64-bit values in table[0..k-1] to out, three per line in - hexadecimal separated by commas. This assumes that if there is a 64-bit - type, then there is also a long long integer type, and it is at least 64 - bits. If not, then the type cast and format string can be adjusted - accordingly. - */ -local void write_table64(FILE *out, const z_word_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", - (unsigned long long)(table[n]), - n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); -} - -/* Actually do the deed. */ -int main(void) { - make_crc_table(); - return 0; -} - -#endif /* MAKECRCH */ - -#ifdef W -/* - Generate the little and big-endian braid tables for the given n and z_word_t - size w. Each array must have room for w blocks of 256 elements. - */ -local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { - int k; - z_crc_t i, p, q; - for (k = 0; k < w; k++) { - p = (z_crc_t)x2nmodp((n * w + 3 - k) << 3, 0); - ltl[k][0] = 0; - big[w - 1 - k][0] = 0; - for (i = 1; i < 256; i++) { - ltl[k][i] = q = (z_crc_t)multmodp(i << 24, p); - big[w - 1 - k][i] = byte_swap(q); - } - } -} -#endif - -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32(), and to force the - * generation of the CRC tables in a threaded application. - */ -const z_crc_t FAR * ZEXPORT get_crc_table(void) { -#ifdef DYNAMIC_CRC_TABLE - z_once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= - * Use ARM machine instructions if available. This will compute the CRC about - * ten times faster than the braided calculation. This code does not check for - * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will - * only be defined if the compilation specifies an ARM processor architecture - * that has the instructions. For example, compiling with -march=armv8.1-a or - * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 - * instructions. - */ -#ifdef ARMCRC32 - -/* - Constants empirically determined to maximize speed. These values are from - measurements on a Cortex-A57. Your mileage may vary. - */ -#define Z_BATCH 3990 /* number of words in a batch */ -#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ -#define Z_BATCH_MIN 800 /* fewest words in a final batch */ - -uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { - uLong val; - z_word_t crc1, crc2; - const z_word_t *word; - z_word_t val0, val1, val2; - z_size_t last, last2, i; - z_size_t num; - - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - z_once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc = (~crc) & 0xffffffff; - - /* Compute the CRC up to a word boundary. */ - while (len && ((z_size_t)buf & 7) != 0) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ - word = (z_word_t const *)buf; - num = len >> 3; - len &= 7; - - /* Do three interleaved CRCs to realize the throughput of one crc32x - instruction per cycle. Each CRC is calculated on Z_BATCH words. The - three CRCs are combined into a single CRC after each set of batches. */ - while (num >= 3 * Z_BATCH) { - crc1 = 0; - crc2 = 0; - for (i = 0; i < Z_BATCH; i++) { - val0 = word[i]; - val1 = word[i + Z_BATCH]; - val2 = word[i + 2 * Z_BATCH]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * Z_BATCH; - num -= 3 * Z_BATCH; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; - } - - /* Do one last smaller batch with the remaining words, if there are enough - to pay for the combination of CRCs. */ - last = num / 3; - if (last >= Z_BATCH_MIN) { - last2 = last << 1; - crc1 = 0; - crc2 = 0; - for (i = 0; i < last; i++) { - val0 = word[i]; - val1 = word[i + last]; - val2 = word[i + last2]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * last; - num -= 3 * last; - val = x2nmodp((int)last, 6); - crc = multmodp(val, crc) ^ crc1; - crc = multmodp(val, crc) ^ crc2; - } - - /* Compute the CRC on any remaining words. */ - for (i = 0; i < num; i++) { - val0 = word[i]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - } - word += num; - - /* Complete the CRC on any remaining bytes. */ - buf = (const unsigned char FAR *)word; - while (len) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#else - -#ifdef W - -/* - Return the CRC of the W bytes in the word_t data, taking the - least-significant byte of the word as the first byte of data, without any pre - or post conditioning. This is used to combine the CRCs of each braid. - */ -local z_crc_t crc_word(z_word_t data) { - int k; - for (k = 0; k < W; k++) - data = (data >> 8) ^ crc_table[data & 0xff]; - return (z_crc_t)data; -} - -local z_word_t crc_word_big(z_word_t data) { - int k; - for (k = 0; k < W; k++) - data = (data << 8) ^ - crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; - return data; -} - -#endif - -/* ========================================================================= */ -uLong ZEXPORT crc32_z(uLong crc, const unsigned char FAR *buf, z_size_t len) { - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - z_once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc = (~crc) & 0xffffffff; - -#ifdef W - - /* If provided enough bytes, do a braided CRC calculation. */ - if (len >= N * W + W - 1) { - z_size_t blks; - z_word_t const *words; - unsigned endian; - int k; - - /* Compute the CRC up to a z_word_t boundary. */ - while (len && ((z_size_t)buf & (W - 1)) != 0) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Compute the CRC on as many N z_word_t blocks as are available. */ - blks = len / (N * W); - len -= blks * N * W; - words = (z_word_t const *)buf; - - /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianness at execution time. If the - compiler knows what the endianness will be, it can optimize out the - check and the unused branch. */ - endian = 1; - if (*(unsigned char *)&endian) { - /* Little endian. */ - - z_crc_t crc0; - z_word_t word0; -#if N > 1 - z_crc_t crc1; - z_word_t word1; -#if N > 2 - z_crc_t crc2; - z_word_t word2; -#if N > 3 - z_crc_t crc3; - z_word_t word3; -#if N > 4 - z_crc_t crc4; - z_word_t word4; -#if N > 5 - z_crc_t crc5; - z_word_t word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = crc; -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - crc = crc_word(crc0 ^ words[0]); -#if N > 1 - crc = crc_word(crc1 ^ words[1] ^ crc); -#if N > 2 - crc = crc_word(crc2 ^ words[2] ^ crc); -#if N > 3 - crc = crc_word(crc3 ^ words[3] ^ crc); -#if N > 4 - crc = crc_word(crc4 ^ words[4] ^ crc); -#if N > 5 - crc = crc_word(crc5 ^ words[5] ^ crc); -#endif -#endif -#endif -#endif -#endif - words += N; - } - else { - /* Big endian. */ - - z_word_t crc0, word0, comb; -#if N > 1 - z_word_t crc1, word1; -#if N > 2 - z_word_t crc2, word2; -#if N > 3 - z_word_t crc3, word3; -#if N > 4 - z_word_t crc4, word4; -#if N > 5 - z_word_t crc5, word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = byte_swap(crc); -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_big_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_big_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_big_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_big_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_big_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_big_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - comb = crc_word_big(crc0 ^ words[0]); -#if N > 1 - comb = crc_word_big(crc1 ^ words[1] ^ comb); -#if N > 2 - comb = crc_word_big(crc2 ^ words[2] ^ comb); -#if N > 3 - comb = crc_word_big(crc3 ^ words[3] ^ comb); -#if N > 4 - comb = crc_word_big(crc4 ^ words[4] ^ comb); -#if N > 5 - comb = crc_word_big(crc5 ^ words[5] ^ comb); -#endif -#endif -#endif -#endif -#endif - words += N; - crc = byte_swap(comb); - } - - /* - Update the pointer to the remaining bytes to process. - */ - buf = (unsigned char const *)words; - } - -#endif /* W */ - - /* Complete the computation of the CRC on any remaining bytes. */ - while (len >= 8) { - len -= 8; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - while (len) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#endif - -/* ========================================================================= */ -uLong ZEXPORT crc32(uLong crc, const unsigned char FAR *buf, uInt len) { - #ifdef HAVE_S390X_VX - return crc32_z_hook(crc, buf, len); - #endif - return crc32_z(crc, buf, len); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { - if (len2 < 0) - return 0; -#ifdef DYNAMIC_CRC_TABLE - z_once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return x2nmodp(len2, 3); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(z_off_t len2) { - return crc32_combine_gen64((z_off64_t)len2); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { - if (op == 0) - return 0; - return multmodp(op, crc1 & 0xffffffff) ^ (crc2 & 0xffffffff); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { - return crc32_combine_op(crc1, crc2, crc32_combine_gen64(len2)); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { - return crc32_combine64(crc1, crc2, (z_off64_t)len2); -} diff --git a/vendor/zlib/crc32.h b/vendor/zlib/crc32.h deleted file mode 100644 index 137df68d6..000000000 --- a/vendor/zlib/crc32.h +++ /dev/null @@ -1,9446 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}; - -#ifdef W - -#if W == 8 - -local const z_word_t FAR crc_big_table[] = { - 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}; - -#else /* W == 4 */ - -local const z_word_t FAR crc_big_table[] = { - 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}; - -#endif - -#if N == 1 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}, - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}, - {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, - 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, - 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, - 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, - 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, - 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, - 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, - 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, - 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, - 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, - 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, - 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, - 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, - 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, - 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, - 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, - 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, - 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, - 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, - 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, - 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, - 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, - 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, - 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, - 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, - 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, - 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, - 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, - 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, - 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, - 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, - 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, - 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, - 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, - 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, - 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, - 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, - 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, - 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, - 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, - 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, - 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, - 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, - 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, - 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, - 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, - 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, - 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, - 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, - 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, - 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, - 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, - 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, - 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, - 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, - 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, - 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, - 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, - 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, - 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, - 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, - 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, - 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, - 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, - 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, - 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, - 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, - 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, - 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, - 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, - 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, - 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, - 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, - 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, - 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, - 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, - 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, - 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, - 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, - 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, - 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, - 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, - 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, - 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, - 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, - 0x72fd249300000000}, - {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, - 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, - 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, - 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, - 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, - 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, - 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, - 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, - 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, - 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, - 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, - 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, - 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, - 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, - 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, - 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, - 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, - 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, - 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, - 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, - 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, - 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, - 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, - 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, - 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, - 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, - 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, - 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, - 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, - 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, - 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, - 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, - 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, - 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, - 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, - 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, - 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, - 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, - 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, - 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, - 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, - 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, - 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, - 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, - 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, - 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, - 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, - 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, - 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, - 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, - 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, - 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, - 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, - 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, - 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, - 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, - 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, - 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, - 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, - 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, - 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, - 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, - 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, - 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, - 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, - 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, - 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, - 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, - 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, - 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, - 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, - 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, - 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, - 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, - 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, - 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, - 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, - 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, - 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, - 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, - 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, - 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, - 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, - 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, - 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, - 0xed3498be00000000}, - {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, - 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, - 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, - 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, - 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, - 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, - 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, - 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, - 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, - 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, - 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, - 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, - 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, - 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, - 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, - 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, - 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, - 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, - 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, - 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, - 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, - 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, - 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, - 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, - 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, - 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, - 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, - 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, - 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, - 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, - 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, - 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, - 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, - 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, - 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, - 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, - 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, - 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, - 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, - 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, - 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, - 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, - 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, - 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, - 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, - 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, - 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, - 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, - 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, - 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, - 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, - 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, - 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, - 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, - 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, - 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, - 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, - 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, - 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, - 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, - 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, - 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, - 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, - 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, - 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, - 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, - 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, - 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, - 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, - 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, - 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, - 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, - 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, - 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, - 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, - 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, - 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, - 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, - 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, - 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, - 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, - 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, - 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, - 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, - 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, - 0xf10605de00000000}, - {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, - 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, - 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, - 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, - 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, - 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, - 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, - 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, - 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, - 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, - 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, - 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, - 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, - 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, - 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, - 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, - 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, - 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, - 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, - 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, - 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, - 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, - 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, - 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, - 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, - 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, - 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, - 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, - 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, - 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, - 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, - 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, - 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, - 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, - 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, - 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, - 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, - 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, - 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, - 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, - 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, - 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, - 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, - 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, - 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, - 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, - 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, - 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, - 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, - 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, - 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, - 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, - 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, - 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, - 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, - 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, - 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, - 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, - 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, - 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, - 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, - 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, - 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, - 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, - 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, - 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, - 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, - 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, - 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, - 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, - 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, - 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, - 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, - 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, - 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, - 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, - 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, - 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, - 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, - 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, - 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, - 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, - 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, - 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, - 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, - 0x8cc764ca00000000}, - {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, - 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, - 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, - 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, - 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, - 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, - 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, - 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, - 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, - 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, - 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, - 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, - 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, - 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, - 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, - 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, - 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, - 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, - 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, - 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, - 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, - 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, - 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, - 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, - 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, - 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, - 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, - 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, - 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, - 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, - 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, - 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, - 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, - 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, - 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, - 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, - 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, - 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, - 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, - 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, - 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, - 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, - 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, - 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, - 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, - 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, - 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, - 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, - 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, - 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, - 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, - 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, - 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, - 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, - 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, - 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, - 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, - 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, - 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, - 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, - 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, - 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, - 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, - 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, - 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, - 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, - 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, - 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, - 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, - 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, - 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, - 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, - 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, - 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, - 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, - 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, - 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, - 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, - 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, - 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, - 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, - 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, - 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, - 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, - 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, - 0xccabc4e400000000}, - {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, - 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, - 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, - 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, - 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, - 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, - 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, - 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, - 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, - 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, - 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, - 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, - 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, - 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, - 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, - 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, - 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, - 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, - 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, - 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, - 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, - 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, - 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, - 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, - 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, - 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, - 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, - 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, - 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, - 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, - 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, - 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, - 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, - 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, - 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, - 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, - 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, - 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, - 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, - 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, - 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, - 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, - 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, - 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, - 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, - 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, - 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, - 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, - 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, - 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, - 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, - 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, - 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, - 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, - 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, - 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, - 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, - 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, - 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, - 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, - 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, - 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, - 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, - 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, - 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, - 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, - 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, - 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, - 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, - 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, - 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, - 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, - 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, - 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, - 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, - 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, - 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, - 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, - 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, - 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, - 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, - 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, - 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, - 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, - 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, - 0x304a369200000000}, - {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, - 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, - 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, - 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, - 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, - 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, - 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, - 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, - 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, - 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, - 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, - 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, - 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, - 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, - 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, - 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, - 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, - 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, - 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, - 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, - 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, - 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, - 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, - 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, - 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, - 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, - 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, - 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, - 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, - 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, - 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, - 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, - 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, - 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, - 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, - 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, - 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, - 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, - 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, - 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, - 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, - 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, - 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, - 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, - 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, - 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, - 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, - 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, - 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, - 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, - 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, - 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, - 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, - 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, - 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, - 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, - 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, - 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, - 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, - 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, - 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, - 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, - 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, - 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, - 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, - 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, - 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, - 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, - 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, - 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, - 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, - 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, - 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, - 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, - 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, - 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, - 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, - 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, - 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, - 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, - 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, - 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, - 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, - 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, - 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, - 0xe6064b2600000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}, - {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, - 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, - 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, - 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, - 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, - 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, - 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, - 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, - 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, - 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, - 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, - 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, - 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, - 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, - 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, - 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, - 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, - 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, - 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, - 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, - 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, - 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, - 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, - 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, - 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, - 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, - 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, - 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, - 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, - 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, - 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, - 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, - 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, - 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, - 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, - 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, - 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, - 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, - 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, - 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, - 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, - 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, - 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, - 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, - 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, - 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, - 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, - 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, - 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, - 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, - 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, - 0x72fd2493}, - {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, - 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, - 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, - 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, - 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, - 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, - 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, - 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, - 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, - 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, - 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, - 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, - 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, - 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, - 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, - 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, - 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, - 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, - 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, - 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, - 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, - 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, - 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, - 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, - 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, - 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, - 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, - 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, - 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, - 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, - 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, - 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, - 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, - 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, - 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, - 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, - 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, - 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, - 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, - 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, - 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, - 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, - 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, - 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, - 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, - 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, - 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, - 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, - 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, - 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, - 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, - 0xed3498be}, - {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, - 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, - 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, - 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, - 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, - 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, - 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, - 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, - 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, - 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, - 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, - 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, - 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, - 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, - 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, - 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, - 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, - 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, - 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, - 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, - 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, - 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, - 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, - 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, - 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, - 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, - 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, - 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, - 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, - 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, - 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, - 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, - 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, - 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, - 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, - 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, - 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, - 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, - 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, - 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, - 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, - 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, - 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, - 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, - 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, - 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, - 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, - 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, - 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, - 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, - 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, - 0xf10605de}}; - -#endif - -#endif - -#if N == 2 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}, - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, - 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, - 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, - 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, - 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, - 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, - 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, - 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, - 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, - 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, - 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, - 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, - 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, - 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, - 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, - 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, - 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, - 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, - 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, - 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, - 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, - 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, - 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, - 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, - 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, - 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, - 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, - 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, - 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, - 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, - 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, - 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, - 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, - 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, - 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, - 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, - 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, - 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, - 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, - 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, - 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, - 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, - 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, - 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, - 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, - 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, - 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, - 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, - 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, - 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, - 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, - 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, - 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, - 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, - 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, - 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, - 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, - 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, - 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, - 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, - 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, - 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, - 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, - 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, - 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, - 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, - 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, - 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, - 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, - 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, - 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, - 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, - 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, - 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, - 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, - 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, - 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, - 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, - 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, - 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, - 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, - 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, - 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, - 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, - 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, - 0x4b0c4f4900000000}, - {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, - 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, - 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, - 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, - 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, - 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, - 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, - 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, - 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, - 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, - 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, - 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, - 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, - 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, - 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, - 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, - 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, - 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, - 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, - 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, - 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, - 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, - 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, - 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, - 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, - 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, - 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, - 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, - 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, - 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, - 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, - 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, - 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, - 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, - 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, - 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, - 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, - 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, - 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, - 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, - 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, - 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, - 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, - 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, - 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, - 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, - 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, - 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, - 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, - 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, - 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, - 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, - 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, - 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, - 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, - 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, - 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, - 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, - 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, - 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, - 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, - 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, - 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, - 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, - 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, - 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, - 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, - 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, - 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, - 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, - 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, - 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, - 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, - 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, - 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, - 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, - 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, - 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, - 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, - 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, - 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, - 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, - 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, - 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, - 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, - 0x14d747e100000000}, - {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, - 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, - 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, - 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, - 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, - 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, - 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, - 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, - 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, - 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, - 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, - 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, - 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, - 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, - 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, - 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, - 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, - 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, - 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, - 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, - 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, - 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, - 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, - 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, - 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, - 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, - 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, - 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, - 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, - 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, - 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, - 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, - 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, - 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, - 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, - 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, - 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, - 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, - 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, - 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, - 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, - 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, - 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, - 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, - 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, - 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, - 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, - 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, - 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, - 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, - 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, - 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, - 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, - 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, - 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, - 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, - 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, - 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, - 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, - 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, - 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, - 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, - 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, - 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, - 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, - 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, - 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, - 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, - 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, - 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, - 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, - 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, - 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, - 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, - 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, - 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, - 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, - 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, - 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, - 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, - 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, - 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, - 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, - 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, - 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, - 0xaa933b1a00000000}, - {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, - 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, - 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, - 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, - 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, - 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, - 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, - 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, - 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, - 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, - 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, - 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, - 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, - 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, - 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, - 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, - 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, - 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, - 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, - 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, - 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, - 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, - 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, - 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, - 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, - 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, - 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, - 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, - 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, - 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, - 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, - 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, - 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, - 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, - 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, - 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, - 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, - 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, - 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, - 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, - 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, - 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, - 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, - 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, - 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, - 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, - 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, - 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, - 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, - 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, - 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, - 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, - 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, - 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, - 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, - 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, - 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, - 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, - 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, - 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, - 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, - 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, - 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, - 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, - 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, - 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, - 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, - 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, - 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, - 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, - 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, - 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, - 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, - 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, - 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, - 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, - 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, - 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, - 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, - 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, - 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, - 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, - 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, - 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, - 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, - 0x6571193600000000}, - {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, - 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, - 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, - 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, - 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, - 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, - 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, - 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, - 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, - 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, - 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, - 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, - 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, - 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, - 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, - 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, - 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, - 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, - 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, - 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, - 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, - 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, - 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, - 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, - 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, - 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, - 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, - 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, - 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, - 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, - 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, - 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, - 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, - 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, - 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, - 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, - 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, - 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, - 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, - 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, - 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, - 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, - 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, - 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, - 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, - 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, - 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, - 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, - 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, - 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, - 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, - 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, - 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, - 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, - 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, - 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, - 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, - 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, - 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, - 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, - 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, - 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, - 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, - 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, - 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, - 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, - 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, - 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, - 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, - 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, - 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, - 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, - 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, - 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, - 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, - 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, - 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, - 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, - 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, - 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, - 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, - 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, - 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, - 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, - 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, - 0xa68cee3d00000000}, - {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, - 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, - 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, - 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, - 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, - 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, - 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, - 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, - 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, - 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, - 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, - 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, - 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, - 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, - 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, - 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, - 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, - 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, - 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, - 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, - 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, - 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, - 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, - 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, - 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, - 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, - 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, - 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, - 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, - 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, - 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, - 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, - 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, - 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, - 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, - 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, - 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, - 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, - 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, - 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, - 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, - 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, - 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, - 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, - 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, - 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, - 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, - 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, - 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, - 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, - 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, - 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, - 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, - 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, - 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, - 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, - 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, - 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, - 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, - 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, - 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, - 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, - 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, - 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, - 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, - 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, - 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, - 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, - 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, - 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, - 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, - 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, - 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, - 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, - 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, - 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, - 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, - 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, - 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, - 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, - 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, - 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, - 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, - 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, - 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, - 0x51e8883f00000000}, - {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, - 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, - 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, - 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, - 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, - 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, - 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, - 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, - 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, - 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, - 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, - 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, - 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, - 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, - 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, - 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, - 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, - 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, - 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, - 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, - 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, - 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, - 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, - 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, - 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, - 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, - 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, - 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, - 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, - 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, - 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, - 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, - 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, - 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, - 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, - 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, - 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, - 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, - 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, - 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, - 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, - 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, - 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, - 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, - 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, - 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, - 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, - 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, - 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, - 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, - 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, - 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, - 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, - 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, - 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, - 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, - 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, - 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, - 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, - 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, - 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, - 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, - 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, - 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, - 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, - 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, - 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, - 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, - 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, - 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, - 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, - 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, - 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, - 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, - 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, - 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, - 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, - 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, - 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, - 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, - 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, - 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, - 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, - 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, - 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, - 0x8ae9531c00000000}, - {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, - 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, - 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, - 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, - 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, - 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, - 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, - 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, - 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, - 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, - 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, - 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, - 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, - 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, - 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, - 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, - 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, - 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, - 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, - 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, - 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, - 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, - 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, - 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, - 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, - 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, - 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, - 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, - 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, - 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, - 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, - 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, - 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, - 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, - 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, - 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, - 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, - 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, - 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, - 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, - 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, - 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, - 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, - 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, - 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, - 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, - 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, - 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, - 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, - 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, - 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, - 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, - 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, - 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, - 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, - 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, - 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, - 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, - 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, - 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, - 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, - 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, - 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, - 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, - 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, - 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, - 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, - 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, - 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, - 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, - 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, - 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, - 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, - 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, - 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, - 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, - 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, - 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, - 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, - 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, - 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, - 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, - 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, - 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, - 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, - 0xd739710d00000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, - 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, - 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, - 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, - 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, - 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, - 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, - 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, - 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, - 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, - 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, - 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, - 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, - 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, - 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, - 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, - 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, - 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, - 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, - 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, - 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, - 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, - 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, - 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, - 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, - 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, - 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, - 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, - 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, - 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, - 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, - 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, - 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, - 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, - 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, - 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, - 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, - 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, - 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, - 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, - 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, - 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, - 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, - 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, - 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, - 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, - 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, - 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, - 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, - 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, - 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, - 0x8cc764ca}, - {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, - 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, - 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, - 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, - 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, - 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, - 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, - 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, - 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, - 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, - 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, - 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, - 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, - 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, - 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, - 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, - 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, - 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, - 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, - 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, - 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, - 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, - 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, - 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, - 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, - 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, - 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, - 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, - 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, - 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, - 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, - 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, - 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, - 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, - 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, - 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, - 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, - 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, - 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, - 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, - 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, - 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, - 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, - 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, - 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, - 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, - 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, - 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, - 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, - 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, - 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, - 0xccabc4e4}, - {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, - 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, - 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, - 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, - 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, - 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, - 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, - 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, - 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, - 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, - 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, - 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, - 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, - 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, - 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, - 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, - 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, - 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, - 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, - 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, - 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, - 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, - 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, - 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, - 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, - 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, - 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, - 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, - 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, - 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, - 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, - 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, - 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, - 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, - 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, - 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, - 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, - 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, - 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, - 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, - 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, - 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, - 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, - 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, - 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, - 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, - 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, - 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, - 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, - 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, - 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, - 0x304a3692}, - {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, - 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, - 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, - 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, - 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, - 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, - 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, - 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, - 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, - 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, - 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, - 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, - 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, - 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, - 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, - 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, - 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, - 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, - 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, - 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, - 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, - 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, - 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, - 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, - 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, - 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, - 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, - 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, - 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, - 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, - 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, - 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, - 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, - 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, - 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, - 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, - 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, - 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, - 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, - 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, - 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, - 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, - 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, - 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, - 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, - 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, - 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, - 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, - 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, - 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, - 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, - 0xe6064b26}}; - -#endif - -#endif - -#if N == 3 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}, - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, - 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, - 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, - 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, - 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, - 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, - 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, - 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, - 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, - 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, - 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, - 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, - 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, - 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, - 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, - 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, - 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, - 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, - 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, - 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, - 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, - 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, - 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, - 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, - 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, - 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, - 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, - 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, - 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, - 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, - 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, - 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, - 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, - 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, - 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, - 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, - 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, - 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, - 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, - 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, - 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, - 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, - 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, - 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, - 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, - 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, - 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, - 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, - 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, - 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, - 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, - 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, - 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, - 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, - 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, - 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, - 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, - 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, - 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, - 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, - 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, - 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, - 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, - 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, - 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, - 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, - 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, - 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, - 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, - 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, - 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, - 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, - 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, - 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, - 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, - 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, - 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, - 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, - 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, - 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, - 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, - 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, - 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, - 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, - 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, - 0x4e36ba1800000000}, - {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, - 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, - 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, - 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, - 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, - 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, - 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, - 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, - 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, - 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, - 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, - 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, - 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, - 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, - 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, - 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, - 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, - 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, - 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, - 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, - 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, - 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, - 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, - 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, - 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, - 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, - 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, - 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, - 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, - 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, - 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, - 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, - 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, - 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, - 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, - 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, - 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, - 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, - 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, - 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, - 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, - 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, - 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, - 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, - 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, - 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, - 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, - 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, - 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, - 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, - 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, - 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, - 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, - 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, - 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, - 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, - 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, - 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, - 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, - 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, - 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, - 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, - 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, - 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, - 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, - 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, - 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, - 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, - 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, - 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, - 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, - 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, - 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, - 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, - 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, - 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, - 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, - 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, - 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, - 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, - 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, - 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, - 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, - 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, - 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, - 0xa1d67c9100000000}, - {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, - 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, - 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, - 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, - 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, - 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, - 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, - 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, - 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, - 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, - 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, - 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, - 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, - 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, - 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, - 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, - 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, - 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, - 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, - 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, - 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, - 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, - 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, - 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, - 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, - 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, - 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, - 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, - 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, - 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, - 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, - 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, - 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, - 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, - 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, - 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, - 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, - 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, - 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, - 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, - 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, - 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, - 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, - 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, - 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, - 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, - 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, - 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, - 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, - 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, - 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, - 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, - 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, - 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, - 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, - 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, - 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, - 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, - 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, - 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, - 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, - 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, - 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, - 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, - 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, - 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, - 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, - 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, - 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, - 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, - 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, - 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, - 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, - 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, - 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, - 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, - 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, - 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, - 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, - 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, - 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, - 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, - 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, - 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, - 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, - 0xa8ef40a100000000}, - {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, - 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, - 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, - 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, - 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, - 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, - 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, - 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, - 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, - 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, - 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, - 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, - 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, - 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, - 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, - 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, - 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, - 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, - 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, - 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, - 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, - 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, - 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, - 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, - 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, - 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, - 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, - 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, - 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, - 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, - 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, - 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, - 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, - 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, - 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, - 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, - 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, - 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, - 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, - 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, - 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, - 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, - 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, - 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, - 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, - 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, - 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, - 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, - 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, - 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, - 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, - 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, - 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, - 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, - 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, - 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, - 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, - 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, - 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, - 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, - 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, - 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, - 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, - 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, - 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, - 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, - 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, - 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, - 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, - 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, - 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, - 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, - 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, - 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, - 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, - 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, - 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, - 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, - 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, - 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, - 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, - 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, - 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, - 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, - 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, - 0x356bacd800000000}, - {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, - 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, - 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, - 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, - 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, - 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, - 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, - 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, - 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, - 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, - 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, - 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, - 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, - 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, - 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, - 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, - 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, - 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, - 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, - 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, - 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, - 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, - 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, - 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, - 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, - 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, - 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, - 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, - 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, - 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, - 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, - 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, - 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, - 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, - 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, - 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, - 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, - 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, - 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, - 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, - 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, - 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, - 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, - 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, - 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, - 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, - 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, - 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, - 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, - 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, - 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, - 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, - 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, - 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, - 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, - 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, - 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, - 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, - 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, - 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, - 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, - 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, - 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, - 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, - 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, - 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, - 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, - 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, - 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, - 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, - 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, - 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, - 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, - 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, - 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, - 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, - 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, - 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, - 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, - 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, - 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, - 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, - 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, - 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, - 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, - 0x48686b5600000000}, - {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, - 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, - 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, - 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, - 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, - 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, - 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, - 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, - 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, - 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, - 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, - 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, - 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, - 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, - 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, - 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, - 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, - 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, - 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, - 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, - 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, - 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, - 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, - 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, - 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, - 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, - 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, - 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, - 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, - 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, - 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, - 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, - 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, - 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, - 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, - 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, - 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, - 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, - 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, - 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, - 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, - 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, - 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, - 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, - 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, - 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, - 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, - 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, - 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, - 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, - 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, - 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, - 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, - 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, - 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, - 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, - 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, - 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, - 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, - 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, - 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, - 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, - 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, - 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, - 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, - 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, - 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, - 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, - 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, - 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, - 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, - 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, - 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, - 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, - 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, - 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, - 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, - 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, - 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, - 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, - 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, - 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, - 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, - 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, - 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, - 0xcaa2517800000000}, - {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, - 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, - 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, - 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, - 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, - 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, - 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, - 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, - 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, - 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, - 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, - 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, - 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, - 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, - 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, - 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, - 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, - 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, - 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, - 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, - 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, - 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, - 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, - 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, - 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, - 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, - 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, - 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, - 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, - 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, - 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, - 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, - 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, - 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, - 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, - 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, - 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, - 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, - 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, - 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, - 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, - 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, - 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, - 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, - 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, - 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, - 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, - 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, - 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, - 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, - 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, - 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, - 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, - 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, - 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, - 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, - 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, - 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, - 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, - 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, - 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, - 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, - 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, - 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, - 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, - 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, - 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, - 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, - 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, - 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, - 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, - 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, - 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, - 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, - 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, - 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, - 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, - 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, - 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, - 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, - 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, - 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, - 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, - 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, - 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, - 0x0c7ac97b00000000}, - {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, - 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, - 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, - 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, - 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, - 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, - 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, - 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, - 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, - 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, - 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, - 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, - 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, - 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, - 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, - 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, - 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, - 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, - 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, - 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, - 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, - 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, - 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, - 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, - 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, - 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, - 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, - 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, - 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, - 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, - 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, - 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, - 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, - 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, - 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, - 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, - 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, - 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, - 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, - 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, - 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, - 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, - 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, - 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, - 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, - 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, - 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, - 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, - 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, - 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, - 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, - 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, - 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, - 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, - 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, - 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, - 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, - 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, - 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, - 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, - 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, - 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, - 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, - 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, - 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, - 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, - 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, - 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, - 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, - 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, - 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, - 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, - 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, - 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, - 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, - 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, - 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, - 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, - 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, - 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, - 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, - 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, - 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, - 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, - 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, - 0x5185cd0900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, - 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, - 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, - 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, - 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, - 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, - 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, - 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, - 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, - 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, - 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, - 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, - 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, - 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, - 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, - 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, - 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, - 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, - 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, - 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, - 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, - 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, - 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, - 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, - 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, - 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, - 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, - 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, - 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, - 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, - 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, - 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, - 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, - 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, - 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, - 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, - 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, - 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, - 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, - 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, - 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, - 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, - 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, - 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, - 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, - 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, - 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, - 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, - 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, - 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, - 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, - 0x4b0c4f49}, - {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, - 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, - 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, - 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, - 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, - 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, - 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, - 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, - 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, - 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, - 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, - 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, - 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, - 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, - 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, - 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, - 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, - 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, - 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, - 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, - 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, - 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, - 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, - 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, - 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, - 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, - 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, - 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, - 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, - 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, - 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, - 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, - 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, - 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, - 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, - 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, - 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, - 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, - 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, - 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, - 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, - 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, - 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, - 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, - 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, - 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, - 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, - 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, - 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, - 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, - 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, - 0x14d747e1}, - {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, - 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, - 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, - 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, - 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, - 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, - 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, - 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, - 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, - 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, - 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, - 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, - 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, - 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, - 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, - 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, - 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, - 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, - 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, - 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, - 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, - 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, - 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, - 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, - 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, - 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, - 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, - 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, - 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, - 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, - 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, - 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, - 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, - 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, - 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, - 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, - 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, - 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, - 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, - 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, - 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, - 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, - 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, - 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, - 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, - 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, - 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, - 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, - 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, - 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, - 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, - 0xaa933b1a}, - {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, - 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, - 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, - 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, - 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, - 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, - 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, - 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, - 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, - 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, - 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, - 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, - 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, - 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, - 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, - 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, - 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, - 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, - 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, - 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, - 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, - 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, - 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, - 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, - 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, - 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, - 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, - 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, - 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, - 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, - 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, - 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, - 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, - 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, - 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, - 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, - 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, - 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, - 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, - 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, - 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, - 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, - 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, - 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, - 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, - 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, - 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, - 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, - 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, - 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, - 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, - 0x65711936}}; - -#endif - -#endif - -#if N == 4 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, - 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, - 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, - 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, - 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, - 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, - 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, - 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, - 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, - 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, - 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, - 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, - 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, - 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, - 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, - 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, - 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, - 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, - 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, - 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, - 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, - 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, - 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, - 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, - 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, - 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, - 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, - 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, - 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, - 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, - 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, - 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, - 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, - 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, - 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, - 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, - 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, - 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, - 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, - 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, - 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, - 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, - 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, - 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, - 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, - 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, - 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, - 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, - 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, - 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, - 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, - 0xe3c45916}, - {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, - 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, - 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, - 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, - 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, - 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, - 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, - 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, - 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, - 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, - 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, - 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, - 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, - 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, - 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, - 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, - 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, - 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, - 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, - 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, - 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, - 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, - 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, - 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, - 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, - 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, - 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, - 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, - 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, - 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, - 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, - 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, - 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, - 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, - 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, - 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, - 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, - 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, - 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, - 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, - 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, - 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, - 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, - 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, - 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, - 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, - 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, - 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, - 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, - 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, - 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, - 0xa7520488}, - {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, - 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, - 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, - 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, - 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, - 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, - 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, - 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, - 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, - 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, - 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, - 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, - 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, - 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, - 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, - 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, - 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, - 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, - 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, - 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, - 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, - 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, - 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, - 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, - 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, - 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, - 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, - 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, - 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, - 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, - 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, - 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, - 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, - 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, - 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, - 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, - 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, - 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, - 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, - 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, - 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, - 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, - 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, - 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, - 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, - 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, - 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, - 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, - 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, - 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, - 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, - 0x3522e9e4}, - {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, - 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, - 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, - 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, - 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, - 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, - 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, - 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, - 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, - 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, - 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, - 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, - 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, - 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, - 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, - 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, - 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, - 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, - 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, - 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, - 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, - 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, - 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, - 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, - 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, - 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, - 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, - 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, - 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, - 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, - 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, - 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, - 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, - 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, - 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, - 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, - 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, - 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, - 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, - 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, - 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, - 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, - 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, - 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, - 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, - 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, - 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, - 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, - 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, - 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, - 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, - 0x97411e28}, - {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, - 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, - 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, - 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, - 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, - 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, - 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, - 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, - 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, - 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, - 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, - 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, - 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, - 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, - 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, - 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, - 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, - 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, - 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, - 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, - 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, - 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, - 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, - 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, - 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, - 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, - 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, - 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, - 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, - 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, - 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, - 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, - 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, - 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, - 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, - 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, - 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, - 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, - 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, - 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, - 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, - 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, - 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, - 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, - 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, - 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, - 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, - 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, - 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, - 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, - 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, - 0x93c7a00b}, - {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, - 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, - 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, - 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, - 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, - 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, - 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, - 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, - 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, - 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, - 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, - 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, - 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, - 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, - 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, - 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, - 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, - 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, - 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, - 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, - 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, - 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, - 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, - 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, - 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, - 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, - 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, - 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, - 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, - 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, - 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, - 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, - 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, - 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, - 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, - 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, - 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, - 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, - 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, - 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, - 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, - 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, - 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, - 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, - 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, - 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, - 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, - 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, - 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, - 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, - 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, - 0xce5f968d}, - {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, - 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, - 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, - 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, - 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, - 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, - 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, - 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, - 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, - 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, - 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, - 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, - 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, - 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, - 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, - 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, - 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, - 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, - 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, - 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, - 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, - 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, - 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, - 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, - 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, - 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, - 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, - 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, - 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, - 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, - 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, - 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, - 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, - 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, - 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, - 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, - 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, - 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, - 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, - 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, - 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, - 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, - 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, - 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, - 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, - 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, - 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, - 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, - 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, - 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, - 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, - 0x3e721277}, - {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, - 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, - 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, - 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, - 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, - 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, - 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, - 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, - 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, - 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, - 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, - 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, - 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, - 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, - 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, - 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, - 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, - 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, - 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, - 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, - 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, - 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, - 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, - 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, - 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, - 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, - 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, - 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, - 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, - 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, - 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, - 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, - 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, - 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, - 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, - 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, - 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, - 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, - 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, - 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, - 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, - 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, - 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, - 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, - 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, - 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, - 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, - 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, - 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, - 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, - 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, - 0x1c65ace7}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, - 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, - 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, - 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, - 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, - 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, - 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, - 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, - 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, - 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, - 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, - 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, - 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, - 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, - 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, - 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, - 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, - 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, - 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, - 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, - 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, - 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, - 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, - 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, - 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, - 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, - 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, - 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, - 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, - 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, - 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, - 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, - 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, - 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, - 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, - 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, - 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, - 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, - 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, - 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, - 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, - 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, - 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, - 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, - 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, - 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, - 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, - 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, - 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, - 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, - 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, - 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, - 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, - 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, - 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, - 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, - 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, - 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, - 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, - 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, - 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, - 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, - 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, - 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, - 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, - 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, - 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, - 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, - 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, - 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, - 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, - 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, - 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, - 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, - 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, - 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, - 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, - 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, - 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, - 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, - 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, - 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, - 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, - 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, - 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, - 0xe7ac651c00000000}, - {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, - 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, - 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, - 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, - 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, - 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, - 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, - 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, - 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, - 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, - 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, - 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, - 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, - 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, - 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, - 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, - 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, - 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, - 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, - 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, - 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, - 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, - 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, - 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, - 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, - 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, - 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, - 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, - 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, - 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, - 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, - 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, - 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, - 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, - 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, - 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, - 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, - 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, - 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, - 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, - 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, - 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, - 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, - 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, - 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, - 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, - 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, - 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, - 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, - 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, - 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, - 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, - 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, - 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, - 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, - 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, - 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, - 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, - 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, - 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, - 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, - 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, - 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, - 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, - 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, - 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, - 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, - 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, - 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, - 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, - 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, - 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, - 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, - 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, - 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, - 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, - 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, - 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, - 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, - 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, - 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, - 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, - 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, - 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, - 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, - 0x7712723e00000000}, - {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, - 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, - 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, - 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, - 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, - 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, - 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, - 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, - 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, - 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, - 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, - 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, - 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, - 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, - 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, - 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, - 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, - 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, - 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, - 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, - 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, - 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, - 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, - 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, - 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, - 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, - 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, - 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, - 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, - 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, - 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, - 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, - 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, - 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, - 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, - 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, - 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, - 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, - 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, - 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, - 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, - 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, - 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, - 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, - 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, - 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, - 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, - 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, - 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, - 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, - 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, - 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, - 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, - 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, - 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, - 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, - 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, - 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, - 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, - 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, - 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, - 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, - 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, - 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, - 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, - 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, - 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, - 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, - 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, - 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, - 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, - 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, - 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, - 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, - 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, - 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, - 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, - 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, - 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, - 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, - 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, - 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, - 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, - 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, - 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, - 0x8d965fce00000000}, - {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, - 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, - 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, - 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, - 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, - 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, - 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, - 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, - 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, - 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, - 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, - 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, - 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, - 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, - 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, - 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, - 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, - 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, - 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, - 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, - 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, - 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, - 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, - 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, - 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, - 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, - 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, - 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, - 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, - 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, - 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, - 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, - 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, - 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, - 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, - 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, - 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, - 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, - 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, - 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, - 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, - 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, - 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, - 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, - 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, - 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, - 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, - 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, - 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, - 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, - 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, - 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, - 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, - 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, - 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, - 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, - 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, - 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, - 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, - 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, - 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, - 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, - 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, - 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, - 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, - 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, - 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, - 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, - 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, - 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, - 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, - 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, - 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, - 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, - 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, - 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, - 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, - 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, - 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, - 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, - 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, - 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, - 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, - 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, - 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, - 0x0ba0c79300000000}, - {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, - 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, - 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, - 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, - 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, - 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, - 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, - 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, - 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, - 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, - 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, - 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, - 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, - 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, - 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, - 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, - 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, - 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, - 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, - 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, - 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, - 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, - 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, - 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, - 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, - 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, - 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, - 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, - 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, - 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, - 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, - 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, - 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, - 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, - 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, - 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, - 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, - 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, - 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, - 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, - 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, - 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, - 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, - 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, - 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, - 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, - 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, - 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, - 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, - 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, - 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, - 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, - 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, - 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, - 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, - 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, - 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, - 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, - 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, - 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, - 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, - 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, - 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, - 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, - 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, - 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, - 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, - 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, - 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, - 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, - 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, - 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, - 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, - 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, - 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, - 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, - 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, - 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, - 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, - 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, - 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, - 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, - 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, - 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, - 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, - 0x281e419700000000}, - {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, - 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, - 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, - 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, - 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, - 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, - 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, - 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, - 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, - 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, - 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, - 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, - 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, - 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, - 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, - 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, - 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, - 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, - 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, - 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, - 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, - 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, - 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, - 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, - 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, - 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, - 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, - 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, - 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, - 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, - 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, - 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, - 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, - 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, - 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, - 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, - 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, - 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, - 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, - 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, - 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, - 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, - 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, - 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, - 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, - 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, - 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, - 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, - 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, - 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, - 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, - 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, - 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, - 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, - 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, - 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, - 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, - 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, - 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, - 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, - 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, - 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, - 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, - 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, - 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, - 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, - 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, - 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, - 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, - 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, - 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, - 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, - 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, - 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, - 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, - 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, - 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, - 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, - 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, - 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, - 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, - 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, - 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, - 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, - 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, - 0xe4e9223500000000}, - {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, - 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, - 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, - 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, - 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, - 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, - 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, - 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, - 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, - 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, - 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, - 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, - 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, - 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, - 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, - 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, - 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, - 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, - 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, - 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, - 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, - 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, - 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, - 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, - 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, - 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, - 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, - 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, - 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, - 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, - 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, - 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, - 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, - 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, - 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, - 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, - 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, - 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, - 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, - 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, - 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, - 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, - 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, - 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, - 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, - 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, - 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, - 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, - 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, - 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, - 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, - 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, - 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, - 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, - 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, - 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, - 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, - 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, - 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, - 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, - 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, - 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, - 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, - 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, - 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, - 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, - 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, - 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, - 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, - 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, - 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, - 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, - 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, - 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, - 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, - 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, - 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, - 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, - 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, - 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, - 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, - 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, - 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, - 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, - 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, - 0x880452a700000000}, - {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, - 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, - 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, - 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, - 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, - 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, - 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, - 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, - 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, - 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, - 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, - 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, - 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, - 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, - 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, - 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, - 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, - 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, - 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, - 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, - 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, - 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, - 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, - 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, - 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, - 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, - 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, - 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, - 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, - 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, - 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, - 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, - 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, - 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, - 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, - 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, - 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, - 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, - 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, - 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, - 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, - 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, - 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, - 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, - 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, - 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, - 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, - 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, - 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, - 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, - 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, - 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, - 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, - 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, - 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, - 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, - 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, - 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, - 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, - 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, - 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, - 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, - 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, - 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, - 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, - 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, - 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, - 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, - 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, - 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, - 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, - 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, - 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, - 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, - 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, - 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, - 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, - 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, - 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, - 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, - 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, - 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, - 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, - 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, - 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, - 0x1659c4e300000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, - 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, - 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, - 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, - 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, - 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, - 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, - 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, - 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, - 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, - 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, - 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, - 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, - 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, - 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, - 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, - 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, - 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, - 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, - 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, - 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, - 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, - 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, - 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, - 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, - 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, - 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, - 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, - 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, - 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, - 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, - 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, - 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, - 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, - 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, - 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, - 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, - 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, - 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, - 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, - 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, - 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, - 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, - 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, - 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, - 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, - 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, - 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, - 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, - 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, - 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, - 0xa68cee3d}, - {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, - 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, - 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, - 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, - 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, - 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, - 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, - 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, - 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, - 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, - 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, - 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, - 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, - 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, - 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, - 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, - 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, - 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, - 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, - 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, - 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, - 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, - 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, - 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, - 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, - 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, - 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, - 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, - 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, - 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, - 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, - 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, - 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, - 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, - 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, - 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, - 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, - 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, - 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, - 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, - 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, - 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, - 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, - 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, - 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, - 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, - 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, - 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, - 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, - 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, - 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, - 0x51e8883f}, - {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, - 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, - 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, - 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, - 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, - 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, - 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, - 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, - 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, - 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, - 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, - 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, - 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, - 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, - 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, - 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, - 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, - 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, - 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, - 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, - 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, - 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, - 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, - 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, - 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, - 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, - 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, - 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, - 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, - 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, - 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, - 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, - 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, - 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, - 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, - 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, - 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, - 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, - 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, - 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, - 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, - 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, - 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, - 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, - 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, - 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, - 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, - 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, - 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, - 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, - 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, - 0x8ae9531c}, - {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, - 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, - 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, - 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, - 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, - 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, - 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, - 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, - 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, - 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, - 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, - 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, - 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, - 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, - 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, - 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, - 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, - 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, - 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, - 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, - 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, - 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, - 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, - 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, - 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, - 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, - 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, - 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, - 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, - 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, - 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, - 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, - 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, - 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, - 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, - 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, - 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, - 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, - 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, - 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, - 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, - 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, - 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, - 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, - 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, - 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, - 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, - 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, - 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, - 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, - 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, - 0xd739710d}}; - -#endif - -#endif - -#if N == 5 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, - 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, - 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, - 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, - 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, - 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, - 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, - 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, - 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, - 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, - 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, - 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, - 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, - 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, - 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, - 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, - 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, - 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, - 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, - 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, - 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, - 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, - 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, - 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, - 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, - 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, - 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, - 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, - 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, - 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, - 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, - 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, - 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, - 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, - 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, - 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, - 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, - 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, - 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, - 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, - 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, - 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, - 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, - 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, - 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, - 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, - 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, - 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, - 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, - 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, - 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, - 0xe9947565}, - {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, - 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, - 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, - 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, - 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, - 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, - 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, - 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, - 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, - 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, - 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, - 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, - 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, - 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, - 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, - 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, - 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, - 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, - 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, - 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, - 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, - 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, - 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, - 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, - 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, - 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, - 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, - 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, - 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, - 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, - 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, - 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, - 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, - 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, - 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, - 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, - 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, - 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, - 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, - 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, - 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, - 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, - 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, - 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, - 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, - 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, - 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, - 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, - 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, - 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, - 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, - 0xf7d05006}, - {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, - 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, - 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, - 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, - 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, - 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, - 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, - 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, - 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, - 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, - 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, - 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, - 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, - 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, - 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, - 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, - 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, - 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, - 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, - 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, - 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, - 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, - 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, - 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, - 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, - 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, - 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, - 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, - 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, - 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, - 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, - 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, - 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, - 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, - 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, - 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, - 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, - 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, - 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, - 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, - 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, - 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, - 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, - 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, - 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, - 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, - 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, - 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, - 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, - 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, - 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, - 0xb2075b94}, - {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, - 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, - 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, - 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, - 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, - 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, - 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, - 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, - 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, - 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, - 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, - 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, - 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, - 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, - 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, - 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, - 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, - 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, - 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, - 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, - 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, - 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, - 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, - 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, - 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, - 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, - 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, - 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, - 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, - 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, - 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, - 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, - 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, - 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, - 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, - 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, - 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, - 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, - 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, - 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, - 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, - 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, - 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, - 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, - 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, - 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, - 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, - 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, - 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, - 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, - 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, - 0xba50bcb9}, - {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, - 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, - 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, - 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, - 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, - 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, - 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, - 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, - 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, - 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, - 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, - 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, - 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, - 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, - 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, - 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, - 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, - 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, - 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, - 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, - 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, - 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, - 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, - 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, - 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, - 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, - 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, - 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, - 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, - 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, - 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, - 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, - 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, - 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, - 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, - 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, - 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, - 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, - 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, - 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, - 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, - 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, - 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, - 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, - 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, - 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, - 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, - 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, - 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, - 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, - 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, - 0x808abcf4}, - {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, - 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, - 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, - 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, - 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, - 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, - 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, - 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, - 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, - 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, - 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, - 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, - 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, - 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, - 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, - 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, - 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, - 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, - 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, - 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, - 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, - 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, - 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, - 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, - 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, - 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, - 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, - 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, - 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, - 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, - 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, - 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, - 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, - 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, - 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, - 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, - 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, - 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, - 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, - 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, - 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, - 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, - 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, - 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, - 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, - 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, - 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, - 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, - 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, - 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, - 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, - 0xefdb3f95}, - {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, - 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, - 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, - 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, - 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, - 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, - 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, - 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, - 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, - 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, - 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, - 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, - 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, - 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, - 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, - 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, - 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, - 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, - 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, - 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, - 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, - 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, - 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, - 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, - 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, - 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, - 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, - 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, - 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, - 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, - 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, - 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, - 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, - 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, - 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, - 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, - 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, - 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, - 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, - 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, - 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, - 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, - 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, - 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, - 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, - 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, - 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, - 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, - 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, - 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, - 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, - 0x0e2fbf43}, - {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, - 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, - 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, - 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, - 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, - 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, - 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, - 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, - 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, - 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, - 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, - 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, - 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, - 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, - 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, - 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, - 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, - 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, - 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, - 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, - 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, - 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, - 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, - 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, - 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, - 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, - 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, - 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, - 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, - 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, - 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, - 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, - 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, - 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, - 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, - 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, - 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, - 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, - 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, - 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, - 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, - 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, - 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, - 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, - 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, - 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, - 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, - 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, - 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, - 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, - 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, - 0xf4377108}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, - 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, - 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, - 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, - 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, - 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, - 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, - 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, - 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, - 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, - 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, - 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, - 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, - 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, - 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, - 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, - 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, - 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, - 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, - 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, - 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, - 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, - 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, - 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, - 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, - 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, - 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, - 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, - 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, - 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, - 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, - 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, - 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, - 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, - 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, - 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, - 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, - 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, - 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, - 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, - 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, - 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, - 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, - 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, - 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, - 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, - 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, - 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, - 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, - 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, - 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, - 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, - 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, - 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, - 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, - 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, - 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, - 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, - 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, - 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, - 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, - 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, - 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, - 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, - 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, - 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, - 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, - 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, - 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, - 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, - 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, - 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, - 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, - 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, - 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, - 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, - 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, - 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, - 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, - 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, - 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, - 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, - 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, - 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, - 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, - 0x087137f400000000}, - {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, - 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, - 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, - 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, - 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, - 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, - 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, - 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, - 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, - 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, - 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, - 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, - 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, - 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, - 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, - 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, - 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, - 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, - 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, - 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, - 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, - 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, - 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, - 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, - 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, - 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, - 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, - 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, - 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, - 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, - 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, - 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, - 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, - 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, - 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, - 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, - 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, - 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, - 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, - 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, - 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, - 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, - 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, - 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, - 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, - 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, - 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, - 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, - 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, - 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, - 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, - 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, - 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, - 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, - 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, - 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, - 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, - 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, - 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, - 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, - 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, - 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, - 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, - 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, - 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, - 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, - 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, - 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, - 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, - 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, - 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, - 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, - 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, - 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, - 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, - 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, - 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, - 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, - 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, - 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, - 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, - 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, - 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, - 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, - 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, - 0x43bf2f0e00000000}, - {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, - 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, - 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, - 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, - 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, - 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, - 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, - 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, - 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, - 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, - 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, - 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, - 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, - 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, - 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, - 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, - 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, - 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, - 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, - 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, - 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, - 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, - 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, - 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, - 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, - 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, - 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, - 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, - 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, - 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, - 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, - 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, - 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, - 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, - 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, - 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, - 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, - 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, - 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, - 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, - 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, - 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, - 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, - 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, - 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, - 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, - 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, - 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, - 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, - 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, - 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, - 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, - 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, - 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, - 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, - 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, - 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, - 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, - 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, - 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, - 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, - 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, - 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, - 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, - 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, - 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, - 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, - 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, - 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, - 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, - 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, - 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, - 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, - 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, - 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, - 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, - 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, - 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, - 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, - 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, - 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, - 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, - 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, - 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, - 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, - 0x953fdbef00000000}, - {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, - 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, - 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, - 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, - 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, - 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, - 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, - 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, - 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, - 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, - 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, - 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, - 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, - 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, - 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, - 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, - 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, - 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, - 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, - 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, - 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, - 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, - 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, - 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, - 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, - 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, - 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, - 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, - 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, - 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, - 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, - 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, - 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, - 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, - 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, - 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, - 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, - 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, - 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, - 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, - 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, - 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, - 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, - 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, - 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, - 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, - 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, - 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, - 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, - 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, - 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, - 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, - 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, - 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, - 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, - 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, - 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, - 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, - 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, - 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, - 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, - 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, - 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, - 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, - 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, - 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, - 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, - 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, - 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, - 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, - 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, - 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, - 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, - 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, - 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, - 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, - 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, - 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, - 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, - 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, - 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, - 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, - 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, - 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, - 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, - 0xf4bc8a8000000000}, - {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, - 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, - 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, - 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, - 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, - 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, - 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, - 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, - 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, - 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, - 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, - 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, - 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, - 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, - 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, - 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, - 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, - 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, - 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, - 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, - 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, - 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, - 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, - 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, - 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, - 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, - 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, - 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, - 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, - 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, - 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, - 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, - 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, - 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, - 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, - 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, - 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, - 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, - 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, - 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, - 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, - 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, - 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, - 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, - 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, - 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, - 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, - 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, - 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, - 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, - 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, - 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, - 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, - 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, - 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, - 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, - 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, - 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, - 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, - 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, - 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, - 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, - 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, - 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, - 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, - 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, - 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, - 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, - 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, - 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, - 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, - 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, - 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, - 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, - 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, - 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, - 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, - 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, - 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, - 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, - 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, - 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, - 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, - 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, - 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, - 0xb9bc50ba00000000}, - {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, - 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, - 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, - 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, - 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, - 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, - 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, - 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, - 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, - 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, - 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, - 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, - 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, - 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, - 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, - 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, - 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, - 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, - 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, - 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, - 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, - 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, - 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, - 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, - 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, - 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, - 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, - 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, - 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, - 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, - 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, - 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, - 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, - 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, - 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, - 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, - 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, - 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, - 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, - 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, - 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, - 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, - 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, - 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, - 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, - 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, - 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, - 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, - 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, - 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, - 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, - 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, - 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, - 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, - 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, - 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, - 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, - 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, - 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, - 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, - 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, - 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, - 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, - 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, - 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, - 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, - 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, - 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, - 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, - 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, - 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, - 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, - 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, - 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, - 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, - 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, - 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, - 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, - 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, - 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, - 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, - 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, - 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, - 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, - 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, - 0x945b07b200000000}, - {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, - 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, - 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, - 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, - 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, - 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, - 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, - 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, - 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, - 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, - 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, - 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, - 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, - 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, - 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, - 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, - 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, - 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, - 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, - 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, - 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, - 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, - 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, - 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, - 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, - 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, - 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, - 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, - 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, - 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, - 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, - 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, - 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, - 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, - 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, - 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, - 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, - 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, - 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, - 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, - 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, - 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, - 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, - 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, - 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, - 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, - 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, - 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, - 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, - 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, - 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, - 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, - 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, - 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, - 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, - 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, - 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, - 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, - 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, - 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, - 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, - 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, - 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, - 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, - 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, - 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, - 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, - 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, - 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, - 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, - 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, - 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, - 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, - 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, - 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, - 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, - 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, - 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, - 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, - 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, - 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, - 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, - 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, - 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, - 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, - 0x0650d0f700000000}, - {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, - 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, - 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, - 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, - 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, - 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, - 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, - 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, - 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, - 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, - 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, - 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, - 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, - 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, - 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, - 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, - 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, - 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, - 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, - 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, - 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, - 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, - 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, - 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, - 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, - 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, - 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, - 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, - 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, - 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, - 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, - 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, - 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, - 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, - 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, - 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, - 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, - 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, - 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, - 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, - 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, - 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, - 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, - 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, - 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, - 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, - 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, - 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, - 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, - 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, - 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, - 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, - 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, - 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, - 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, - 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, - 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, - 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, - 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, - 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, - 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, - 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, - 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, - 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, - 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, - 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, - 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, - 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, - 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, - 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, - 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, - 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, - 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, - 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, - 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, - 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, - 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, - 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, - 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, - 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, - 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, - 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, - 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, - 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, - 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, - 0x657594e900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, - 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, - 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, - 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, - 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, - 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, - 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, - 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, - 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, - 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, - 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, - 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, - 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, - 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, - 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, - 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, - 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, - 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, - 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, - 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, - 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, - 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, - 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, - 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, - 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, - 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, - 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, - 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, - 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, - 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, - 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, - 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, - 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, - 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, - 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, - 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, - 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, - 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, - 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, - 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, - 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, - 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, - 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, - 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, - 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, - 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, - 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, - 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, - 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, - 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, - 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, - 0x4e36ba18}, - {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, - 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, - 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, - 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, - 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, - 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, - 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, - 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, - 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, - 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, - 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, - 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, - 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, - 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, - 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, - 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, - 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, - 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, - 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, - 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, - 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, - 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, - 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, - 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, - 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, - 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, - 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, - 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, - 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, - 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, - 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, - 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, - 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, - 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, - 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, - 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, - 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, - 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, - 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, - 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, - 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, - 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, - 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, - 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, - 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, - 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, - 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, - 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, - 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, - 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, - 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, - 0xa1d67c91}, - {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, - 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, - 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, - 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, - 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, - 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, - 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, - 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, - 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, - 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, - 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, - 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, - 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, - 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, - 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, - 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, - 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, - 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, - 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, - 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, - 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, - 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, - 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, - 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, - 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, - 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, - 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, - 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, - 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, - 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, - 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, - 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, - 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, - 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, - 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, - 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, - 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, - 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, - 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, - 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, - 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, - 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, - 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, - 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, - 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, - 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, - 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, - 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, - 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, - 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, - 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, - 0xa8ef40a1}, - {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, - 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, - 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, - 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, - 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, - 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, - 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, - 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, - 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, - 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, - 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, - 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, - 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, - 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, - 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, - 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, - 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, - 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, - 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, - 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, - 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, - 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, - 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, - 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, - 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, - 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, - 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, - 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, - 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, - 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, - 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, - 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, - 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, - 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, - 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, - 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, - 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, - 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, - 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, - 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, - 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, - 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, - 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, - 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, - 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, - 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, - 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, - 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, - 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, - 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, - 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, - 0x356bacd8}}; - -#endif - -#endif - -#if N == 6 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, - 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, - 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, - 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, - 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, - 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, - 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, - 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, - 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, - 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, - 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, - 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, - 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, - 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, - 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, - 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, - 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, - 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, - 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, - 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, - 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, - 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, - 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, - 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, - 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, - 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, - 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, - 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, - 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, - 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, - 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, - 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, - 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, - 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, - 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, - 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, - 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, - 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, - 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, - 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, - 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, - 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, - 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, - 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, - 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, - 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, - 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, - 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, - 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, - 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, - 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, - 0x8568a0a8}, - {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, - 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, - 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, - 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, - 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, - 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, - 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, - 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, - 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, - 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, - 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, - 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, - 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, - 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, - 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, - 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, - 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, - 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, - 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, - 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, - 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, - 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, - 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, - 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, - 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, - 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, - 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, - 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, - 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, - 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, - 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, - 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, - 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, - 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, - 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, - 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, - 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, - 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, - 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, - 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, - 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, - 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, - 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, - 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, - 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, - 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, - 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, - 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, - 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, - 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, - 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, - 0x0d907052}, - {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, - 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, - 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, - 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, - 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, - 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, - 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, - 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, - 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, - 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, - 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, - 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, - 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, - 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, - 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, - 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, - 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, - 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, - 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, - 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, - 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, - 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, - 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, - 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, - 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, - 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, - 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, - 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, - 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, - 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, - 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, - 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, - 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, - 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, - 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, - 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, - 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, - 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, - 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, - 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, - 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, - 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, - 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, - 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, - 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, - 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, - 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, - 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, - 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, - 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, - 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, - 0xfd1a6c8a}, - {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, - 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, - 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, - 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, - 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, - 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, - 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, - 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, - 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, - 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, - 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, - 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, - 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, - 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, - 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, - 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, - 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, - 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, - 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, - 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, - 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, - 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, - 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, - 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, - 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, - 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, - 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, - 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, - 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, - 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, - 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, - 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, - 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, - 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, - 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, - 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, - 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, - 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, - 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, - 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, - 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, - 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, - 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, - 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, - 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, - 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, - 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, - 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, - 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, - 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, - 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, - 0x7895f01a}, - {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, - 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, - 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, - 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, - 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, - 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, - 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, - 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, - 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, - 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, - 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, - 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, - 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, - 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, - 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, - 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, - 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, - 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, - 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, - 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, - 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, - 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, - 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, - 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, - 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, - 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, - 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, - 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, - 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, - 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, - 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, - 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, - 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, - 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, - 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, - 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, - 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, - 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, - 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, - 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, - 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, - 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, - 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, - 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, - 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, - 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, - 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, - 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, - 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, - 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, - 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, - 0x9239b848}, - {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, - 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, - 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, - 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, - 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, - 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, - 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, - 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, - 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, - 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, - 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, - 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, - 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, - 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, - 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, - 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, - 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, - 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, - 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, - 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, - 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, - 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, - 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, - 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, - 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, - 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, - 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, - 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, - 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, - 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, - 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, - 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, - 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, - 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, - 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, - 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, - 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, - 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, - 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, - 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, - 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, - 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, - 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, - 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, - 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, - 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, - 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, - 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, - 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, - 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, - 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, - 0xeb36d3cc}, - {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, - 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, - 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, - 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, - 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, - 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, - 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, - 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, - 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, - 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, - 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, - 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, - 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, - 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, - 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, - 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, - 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, - 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, - 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, - 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, - 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, - 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, - 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, - 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, - 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, - 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, - 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, - 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, - 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, - 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, - 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, - 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, - 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, - 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, - 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, - 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, - 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, - 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, - 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, - 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, - 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, - 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, - 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, - 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, - 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, - 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, - 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, - 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, - 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, - 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, - 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, - 0x38e5f3c5}, - {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, - 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, - 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, - 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, - 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, - 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, - 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, - 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, - 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, - 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, - 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, - 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, - 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, - 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, - 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, - 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, - 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, - 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, - 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, - 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, - 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, - 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, - 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, - 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, - 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, - 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, - 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, - 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, - 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, - 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, - 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, - 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, - 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, - 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, - 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, - 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, - 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, - 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, - 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, - 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, - 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, - 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, - 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, - 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, - 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, - 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, - 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, - 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, - 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, - 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, - 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, - 0x3d3101a2}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, - 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, - 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, - 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, - 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, - 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, - 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, - 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, - 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, - 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, - 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, - 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, - 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, - 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, - 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, - 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, - 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, - 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, - 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, - 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, - 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, - 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, - 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, - 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, - 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, - 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, - 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, - 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, - 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, - 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, - 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, - 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, - 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, - 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, - 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, - 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, - 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, - 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, - 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, - 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, - 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, - 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, - 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, - 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, - 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, - 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, - 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, - 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, - 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, - 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, - 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, - 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, - 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, - 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, - 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, - 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, - 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, - 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, - 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, - 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, - 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, - 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, - 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, - 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, - 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, - 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, - 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, - 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, - 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, - 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, - 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, - 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, - 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, - 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, - 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, - 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, - 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, - 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, - 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, - 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, - 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, - 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, - 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, - 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, - 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, - 0xa201313d00000000}, - {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, - 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, - 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, - 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, - 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, - 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, - 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, - 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, - 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, - 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, - 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, - 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, - 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, - 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, - 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, - 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, - 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, - 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, - 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, - 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, - 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, - 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, - 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, - 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, - 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, - 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, - 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, - 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, - 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, - 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, - 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, - 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, - 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, - 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, - 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, - 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, - 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, - 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, - 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, - 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, - 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, - 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, - 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, - 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, - 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, - 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, - 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, - 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, - 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, - 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, - 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, - 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, - 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, - 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, - 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, - 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, - 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, - 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, - 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, - 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, - 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, - 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, - 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, - 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, - 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, - 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, - 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, - 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, - 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, - 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, - 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, - 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, - 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, - 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, - 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, - 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, - 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, - 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, - 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, - 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, - 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, - 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, - 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, - 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, - 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, - 0xc5f3e53800000000}, - {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, - 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, - 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, - 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, - 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, - 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, - 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, - 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, - 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, - 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, - 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, - 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, - 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, - 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, - 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, - 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, - 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, - 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, - 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, - 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, - 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, - 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, - 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, - 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, - 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, - 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, - 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, - 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, - 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, - 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, - 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, - 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, - 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, - 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, - 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, - 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, - 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, - 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, - 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, - 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, - 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, - 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, - 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, - 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, - 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, - 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, - 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, - 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, - 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, - 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, - 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, - 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, - 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, - 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, - 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, - 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, - 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, - 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, - 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, - 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, - 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, - 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, - 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, - 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, - 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, - 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, - 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, - 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, - 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, - 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, - 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, - 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, - 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, - 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, - 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, - 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, - 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, - 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, - 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, - 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, - 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, - 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, - 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, - 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, - 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, - 0xccd336eb00000000}, - {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, - 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, - 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, - 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, - 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, - 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, - 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, - 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, - 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, - 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, - 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, - 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, - 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, - 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, - 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, - 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, - 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, - 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, - 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, - 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, - 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, - 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, - 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, - 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, - 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, - 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, - 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, - 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, - 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, - 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, - 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, - 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, - 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, - 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, - 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, - 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, - 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, - 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, - 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, - 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, - 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, - 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, - 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, - 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, - 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, - 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, - 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, - 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, - 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, - 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, - 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, - 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, - 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, - 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, - 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, - 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, - 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, - 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, - 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, - 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, - 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, - 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, - 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, - 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, - 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, - 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, - 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, - 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, - 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, - 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, - 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, - 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, - 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, - 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, - 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, - 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, - 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, - 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, - 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, - 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, - 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, - 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, - 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, - 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, - 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, - 0x48b8399200000000}, - {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, - 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, - 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, - 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, - 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, - 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, - 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, - 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, - 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, - 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, - 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, - 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, - 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, - 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, - 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, - 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, - 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, - 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, - 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, - 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, - 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, - 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, - 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, - 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, - 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, - 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, - 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, - 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, - 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, - 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, - 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, - 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, - 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, - 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, - 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, - 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, - 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, - 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, - 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, - 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, - 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, - 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, - 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, - 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, - 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, - 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, - 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, - 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, - 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, - 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, - 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, - 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, - 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, - 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, - 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, - 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, - 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, - 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, - 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, - 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, - 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, - 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, - 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, - 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, - 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, - 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, - 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, - 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, - 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, - 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, - 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, - 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, - 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, - 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, - 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, - 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, - 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, - 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, - 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, - 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, - 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, - 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, - 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, - 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, - 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, - 0x1af0957800000000}, - {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, - 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, - 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, - 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, - 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, - 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, - 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, - 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, - 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, - 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, - 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, - 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, - 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, - 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, - 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, - 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, - 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, - 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, - 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, - 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, - 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, - 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, - 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, - 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, - 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, - 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, - 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, - 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, - 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, - 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, - 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, - 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, - 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, - 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, - 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, - 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, - 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, - 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, - 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, - 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, - 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, - 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, - 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, - 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, - 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, - 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, - 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, - 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, - 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, - 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, - 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, - 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, - 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, - 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, - 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, - 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, - 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, - 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, - 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, - 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, - 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, - 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, - 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, - 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, - 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, - 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, - 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, - 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, - 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, - 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, - 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, - 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, - 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, - 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, - 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, - 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, - 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, - 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, - 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, - 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, - 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, - 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, - 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, - 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, - 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, - 0x8a6c1afd00000000}, - {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, - 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, - 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, - 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, - 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, - 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, - 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, - 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, - 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, - 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, - 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, - 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, - 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, - 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, - 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, - 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, - 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, - 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, - 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, - 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, - 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, - 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, - 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, - 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, - 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, - 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, - 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, - 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, - 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, - 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, - 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, - 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, - 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, - 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, - 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, - 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, - 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, - 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, - 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, - 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, - 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, - 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, - 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, - 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, - 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, - 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, - 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, - 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, - 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, - 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, - 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, - 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, - 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, - 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, - 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, - 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, - 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, - 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, - 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, - 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, - 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, - 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, - 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, - 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, - 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, - 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, - 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, - 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, - 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, - 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, - 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, - 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, - 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, - 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, - 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, - 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, - 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, - 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, - 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, - 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, - 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, - 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, - 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, - 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, - 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, - 0x5270900d00000000}, - {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, - 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, - 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, - 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, - 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, - 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, - 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, - 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, - 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, - 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, - 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, - 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, - 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, - 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, - 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, - 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, - 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, - 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, - 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, - 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, - 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, - 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, - 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, - 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, - 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, - 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, - 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, - 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, - 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, - 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, - 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, - 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, - 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, - 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, - 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, - 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, - 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, - 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, - 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, - 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, - 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, - 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, - 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, - 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, - 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, - 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, - 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, - 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, - 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, - 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, - 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, - 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, - 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, - 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, - 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, - 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, - 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, - 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, - 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, - 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, - 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, - 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, - 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, - 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, - 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, - 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, - 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, - 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, - 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, - 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, - 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, - 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, - 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, - 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, - 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, - 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, - 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, - 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, - 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, - 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, - 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, - 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, - 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, - 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, - 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, - 0xa8a0688500000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, - 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, - 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, - 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, - 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, - 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, - 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, - 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, - 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, - 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, - 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, - 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, - 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, - 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, - 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, - 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, - 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, - 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, - 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, - 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, - 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, - 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, - 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, - 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, - 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, - 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, - 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, - 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, - 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, - 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, - 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, - 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, - 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, - 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, - 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, - 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, - 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, - 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, - 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, - 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, - 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, - 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, - 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, - 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, - 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, - 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, - 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, - 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, - 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, - 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, - 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, - 0x48686b56}, - {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, - 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, - 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, - 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, - 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, - 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, - 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, - 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, - 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, - 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, - 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, - 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, - 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, - 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, - 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, - 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, - 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, - 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, - 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, - 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, - 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, - 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, - 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, - 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, - 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, - 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, - 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, - 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, - 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, - 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, - 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, - 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, - 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, - 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, - 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, - 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, - 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, - 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, - 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, - 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, - 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, - 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, - 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, - 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, - 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, - 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, - 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, - 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, - 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, - 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, - 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, - 0xcaa25178}, - {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, - 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, - 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, - 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, - 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, - 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, - 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, - 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, - 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, - 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, - 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, - 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, - 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, - 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, - 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, - 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, - 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, - 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, - 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, - 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, - 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, - 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, - 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, - 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, - 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, - 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, - 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, - 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, - 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, - 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, - 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, - 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, - 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, - 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, - 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, - 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, - 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, - 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, - 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, - 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, - 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, - 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, - 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, - 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, - 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, - 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, - 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, - 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, - 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, - 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, - 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, - 0x0c7ac97b}, - {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, - 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, - 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, - 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, - 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, - 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, - 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, - 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, - 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, - 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, - 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, - 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, - 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, - 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, - 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, - 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, - 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, - 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, - 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, - 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, - 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, - 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, - 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, - 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, - 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, - 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, - 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, - 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, - 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, - 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, - 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, - 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, - 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, - 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, - 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, - 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, - 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, - 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, - 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, - 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, - 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, - 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, - 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, - 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, - 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, - 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, - 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, - 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, - 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, - 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, - 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, - 0x5185cd09}}; - -#endif - -#endif - -#endif - -local const z_crc_t FAR x2n_table[] = { - 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, - 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, - 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, - 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, - 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, - 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, - 0xc40ba6d0, 0xc4e22c3c}; diff --git a/vendor/zlib/deflate.c b/vendor/zlib/deflate.c deleted file mode 100644 index d7d2c7c1e..000000000 --- a/vendor/zlib/deflate.c +++ /dev/null @@ -1,2185 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available at https://datatracker.ietf.org/doc/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.3.2 Copyright 1995-2026 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func)(deflate_state *s, int flush); -/* Compression function. Returns the block state after the call. */ - -local block_state deflate_stored(deflate_state *s, int flush); -local block_state deflate_fast(deflate_state *s, int flush); -#ifndef FASTEST -local block_state deflate_slow(deflate_state *s, int flush); -#endif -local block_state deflate_rle(deflate_state *s, int flush); -local block_state deflate_huff(deflate_state *s, int flush); - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive input - * characters, so that a running hash key can be computed from the previous - * key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to INSERT_STRING are made with consecutive input - * characters and the first MIN_MATCH bytes of str are valid (except for - * the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - do { \ - s->head[s->hash_size - 1] = NIL; \ - zmemzero(s->head, (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ - s->slid = 0; \ - } while (0) - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -#if defined(__has_feature) -# if __has_feature(memory_sanitizer) - __attribute__((no_sanitize("memory"))) -# endif -#endif -local void slide_hash(deflate_state *s) { - unsigned n, m; - Posf *p; - uInt wsize = s->w_size; - - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); -#ifndef FASTEST - n = wsize; - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - s->slid = 1; -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(deflate_state *s) { - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4127) -#endif - if (sizeof(int) <= 2) { -#ifdef _MSC_VER -#pragma warning(pop) -#endif - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize + MAX_DIST(s)) { - - zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - if (s->insert > s->strstart) - s->insert = s->strstart; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* ========================================================================= */ -int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, - int stream_size) { - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, - int windowBits, int memLevel, int strategy, - const char *version, int stream_size) { - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - if (windowBits < -15) - return Z_STREAM_ERROR; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - zmemzero(s, sizeof(deflate_state)); - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - s->status = INIT_STATE; /* to pass state test in deflateReset() */ - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = (uInt)windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = (uInt)memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n - 2) bits have been written, just - * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 - * symbols are written.) The closest the writing gets to what is unread is - * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); - s->pending_buf_size = (ulg)s->lit_bufsize * 4; - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } -#ifdef LIT_MEM - s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); - s->l_buf = s->pending_buf + (s->lit_bufsize << 2); - s->sym_end = s->lit_bufsize - 1; -#else - s->sym_buf = s->pending_buf + s->lit_bufsize; - s->sym_end = (s->lit_bufsize - 1) * 3; -#endif - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -local int deflateStateCheck(z_streamp strm) { - deflate_state *s; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - s = strm->state; - if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && -#ifdef GZIP - s->status != GZIP_STATE && -#endif - s->status != EXTRA_STATE && - s->status != NAME_STATE && - s->status != COMMENT_STATE && - s->status != HCRC_STATE && - s->status != BUSY_STATE && - s->status != FINISH_STATE)) - return 1; - return 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, - uInt dictLength) { - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; - - if (deflateStateCheck(strm) || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, - uInt *dictLength) { - deflate_state *s; - uInt len; - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) - len = s->w_size; - if (dictionary != Z_NULL && len) - zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); - if (dictLength != Z_NULL) - *dictLength = len; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep(z_streamp strm) { - deflate_state *s; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = -#ifdef GZIP - s->wrap == 2 ? GZIP_STATE : -#endif - INIT_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = -2; - - _tr_init(s); - - return Z_OK; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(deflate_state *s) { - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset(z_streamp strm) { - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { - if (deflateStateCheck(strm) || strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - if (pending != Z_NULL) { - *pending = (unsigned)strm->state->pending; - if (*pending != strm->state->pending) { - *pending = (unsigned)-1; - return Z_BUF_ERROR; - } - } - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateUsed(z_streamp strm, int *bits) { - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (bits != Z_NULL) - *bits = strm->state->bi_used; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { - deflate_state *s; - int put; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; -#ifdef LIT_MEM - if (bits < 0 || bits > 16 || - (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; -#else - if (bits < 0 || bits > 16 || - s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; -#endif - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { - deflate_state *s; - compress_func func; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - s->last_flush != -2) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) - return Z_BUF_ERROR; - } - if (s->level != level) { - if (s->level == 0 && s->matches != 0) { - if (s->matches == 1) - slide_hash(s); - else - CLEAR_HASH(s); - s->matches = 0; - } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, - int nice_length, int max_chain) { - deflate_state *s; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = (uInt)good_length; - s->max_lazy_match = (uInt)max_lazy; - s->nice_match = nice_length; - s->max_chain_length = (uInt)max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns a - * close to exact, as well as small, upper bound on the compressed size. This - * is an expansion of ~0.03%, plus a small constant. - * - * For any setting other than those defaults for windowBits and memLevel, one - * of two worst case bounds is returned. This is at most an expansion of ~4% or - * ~13%, plus a small constant. - * - * Both the 0.03% and 4% derive from the overhead of stored blocks. The first - * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second - * is for stored blocks of 127 bytes (the worst case memLevel == 1). The - * expansion results from five bytes of header for each stored block. - * - * The larger expansion of 13% results from a window size less than or equal to - * the symbols buffer size (windowBits <= memLevel + 7). In that case some of - * the data being compressed may have slid out of the sliding window, impeding - * a stored block from being emitted. Then the only choice is a fixed or - * dynamic block, where a fixed block limits the maximum expansion to 9 bits - * per 8-bit byte, plus 10 bits for every block. The smallest block size for - * which this can occur is 255 (memLevel == 2). - * - * Shifts are used to approximate divisions, for speed. - */ -z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen) { - deflate_state *s; - z_size_t fixedlen, storelen, wraplen, bound; - - /* upper bound for fixed blocks with 9-bit literals and length 255 - (memLevel == 2, which is the lowest that may not use stored blocks) -- - ~13% overhead plus a small constant */ - fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + - (sourceLen >> 9) + 4; - if (fixedlen < sourceLen) - fixedlen = (z_size_t)-1; - - /* upper bound for stored blocks with length 127 (memLevel == 1) -- - ~4% overhead plus a small constant */ - storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + - (sourceLen >> 11) + 7; - if (storelen < sourceLen) - storelen = (z_size_t)-1; - - /* if can't get parameters, return larger bound plus a wrapper */ - if (deflateStateCheck(strm)) { - bound = fixedlen > storelen ? fixedlen : storelen; - return bound + 18 < bound ? (z_size_t)-1 : bound + 18; - } - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap < 0 ? -s->wrap : s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; -#ifdef GZIP - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - Bytef *str; - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; -#endif - default: /* for compiler happiness */ - wraplen = 18; - } - - /* if not default parameters, return one of the conservative bounds */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) { - bound = s->w_bits <= s->hash_bits && s->level ? fixedlen : - storelen; - return bound + wraplen < bound ? (z_size_t)-1 : bound + wraplen; - } - - /* default settings: return tight bound for that case -- ~0.03% overhead - plus a small constant */ - bound = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; - return bound < sourceLen ? (z_size_t)-1 : bound; -} -uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { - z_size_t bound = deflateBound_z(strm, sourceLen); - return (uLong)bound != bound ? (uLong)-1 : (uLong)bound; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB(deflate_state *s, uInt b) { - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -local void flush_pending(z_streamp strm) { - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending > strm->avail_out ? strm->avail_out : - (unsigned)s->pending; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* =========================================================================== - * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. - */ -#define HCRC_UPDATE(beg) \ - do { \ - if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32_z(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ - } while (0) - -/* ========================================================================= */ -int ZEXPORT deflate(z_streamp strm, int flush) { - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - old_flush = s->last_flush; - s->last_flush = flush; - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Write the header */ - if (s->status == INIT_STATE && s->wrap == 0) - s->status = BUSY_STATE; - if (s->status == INIT_STATE) { - /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#ifdef GZIP - if (s->status == GZIP_STATE) { - /* gzip header */ - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32_z(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - ulg left = (s->gzhead->extra_len & 0xffff) - s->gzindex; - while (s->pending + left > s->pending_buf_size) { - ulg copy = s->pending_buf_size - s->pending; - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, copy); - s->pending = s->pending_buf_size; - HCRC_UPDATE(beg); - s->gzindex += copy; - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - left -= copy; - } - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, left); - s->pending += left; - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - } - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) { - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - } - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#endif - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd(z_streamp strm) { - int status; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - - status = strm->state->status; - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { -#ifdef MAXSEG_64K - (void)dest; - (void)source; - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - - - if (deflateStateCheck(source) || dest == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - zmemzero(ds, sizeof(deflate_state)); - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy's do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ss->high_water); - zmemcpy(ds->prev, ss->prev, - (ss->slid || ss->strstart - ss->insert > ds->w_size ? ds->w_size : - ss->strstart - ss->insert) * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - zmemcpy(ds->pending_out, ss->pending_out, ss->pending); -#ifdef LIT_MEM - ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); - ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); - zmemcpy(ds->d_buf, ss->d_buf, ss->sym_next * sizeof(ush)); - zmemcpy(ds->l_buf, ss->l_buf, ss->sym_next); -#else - ds->sym_buf = ds->pending_buf + ds->lit_bufsize; - zmemcpy(ds->sym_buf, ss->sym_buf, ss->sym_next); -#endif - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -local uInt longest_match(deflate_state *s, IPos cur_match) { - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - Bytef *scan = s->window + s->strstart; /* current string */ - Bytef *match; /* matched string */ - int len; /* length of current match */ - int best_len = (int)s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - ush scan_start = *(ushf*)scan; - ush scan_end = *(ushf*)(scan + best_len - 1); -#else - Bytef *strend = s->window + s->strstart + MAX_MATCH; - Byte scan_end1 = scan[best_len - 1]; - Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match + best_len - 1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart + 3, + 5, up to strstart + 257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window + strstart + 257 */ - Assert(scan <= s->window + (unsigned)(s->window_size - 1), - "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend - scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len - 1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len - 1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart + 258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), - "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan + best_len - 1); -#else - scan_end1 = scan[best_len - 1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(deflate_state *s, IPos cur_match) { - Bytef *scan = s->window + s->strstart; /* current string */ - Bytef *match; /* matched string */ - int len; /* length of current match */ - Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len - 1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart + 258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef ZLIB_DEBUG - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(deflate_state *s, IPos start, IPos match, int length) { - /* check that the match is indeed a match */ - Bytef *back = s->window + (int)match, *here = s->window + start; - IPos len = (IPos)length; - if (match == (IPos)-1) { - /* match starts one byte before the current window -- just compare the - subsequent length-1 bytes */ - back++; - here++; - len--; - } - if (zmemcmp(back, here, len) != EQUAL) { - fprintf(stderr, " start %u, match %d, length %d\n", - start, (int)match, length); - do { - fprintf(stderr, "(%02x %02x)", *back++, *here++); - } while (--len != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start - match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* ZLIB_DEBUG */ - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* Maximum stored block length in deflate format (not including header). */ -#define MAX_STORED 65535 - -/* Minimum of a and b. */ -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunities to have a single copy from next_in to next_out. - */ -local block_state deflate_stored(deflate_state *s, int flush) { - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - unsigned min_block = (unsigned)(MIN(s->pending_buf_size - 5, s->w_size)); - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - int last = 0; - unsigned len, left, have; - unsigned used = s->strm->avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = MAX_STORED; /* maximum deflate stored block length */ - have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ - if (s->strm->avail_out < have) /* need room for header */ - break; - /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out - have; - left = (unsigned)(s->strstart - s->block_start); /* window bytes */ - if (len > (ulg)left + s->strm->avail_in) - len = left + s->strm->avail_in; /* limit len to the input */ - if (len > have) - len = have; /* limit len to the output */ - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len == 0 && flush != Z_FINISH) || - flush == Z_NO_FLUSH || - len != left + s->strm->avail_in)) - break; - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; - _tr_stored_block(s, (char *)0, 0L, last); - - /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = (Bytef)len; - s->pending_buf[s->pending - 3] = (Bytef)(len >> 8); - s->pending_buf[s->pending - 2] = (Bytef)~len; - s->pending_buf[s->pending - 1] = (Bytef)(~len >> 8); - - /* Write the stored block header bytes. */ - flush_pending(s->strm); - -#ifdef ZLIB_DEBUG - /* Update debugging counts for the data about to be copied. */ - s->compressed_len += len << 3; - s->bits_sent += len << 3; -#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) - left = len; - zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s->strm->next_out += left; - s->strm->avail_out -= left; - s->strm->total_out += left; - s->block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s->strm, s->strm->next_out, len); - s->strm->next_out += len; - s->strm->avail_out -= len; - s->strm->total_out += len; - } - } while (last == 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s->strm->avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s->w_size) { /* supplant the previous history */ - s->matches = 2; /* clear hash */ - zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s->strstart = s->w_size; - s->insert = s->strstart; - } - else { - if (s->window_size - s->strstart <= used) { - /* Slide the window down. */ - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s->strstart += used; - s->insert += MIN(used, s->w_size - s->insert); - } - s->block_start = s->strstart; - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* If the last block was written to next_out, then done. */ - if (last) { - s->bi_used = 8; - return finish_done; - } - - /* If flushing and all input has been consumed, then done. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH && - s->strm->avail_in == 0 && (long)s->strstart == s->block_start) - return block_done; - - /* Fill the window with any remaining input. */ - have = (unsigned)(s->window_size - s->strstart); - if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { - /* Slide the window down. */ - s->block_start -= s->w_size; - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - have += s->w_size; /* more space now */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - if (have > s->strm->avail_in) - have = s->strm->avail_in; - if (have) { - read_buf(s->strm, s->window + s->strstart, have); - s->strstart += have; - s->insert += MIN(have, s->w_size - s->insert); - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = ((unsigned)s->bi_valid + 42) >> 3; /* bytes in header */ - /* maximum stored block length that will fit in pending: */ - have = (unsigned)MIN(s->pending_buf_size - have, MAX_STORED); - min_block = MIN(have, s->w_size); - left = (unsigned)(s->strstart - s->block_start); - if (left >= min_block || - ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && - s->strm->avail_in == 0 && left <= have)) { - len = MIN(left, have); - last = flush == Z_FINISH && s->strm->avail_in == 0 && - len == left ? 1 : 0; - _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); - s->block_start += len; - flush_pending(s->strm); - } - - /* We've done all we can with the available input and output. */ - if (last) - s->bi_used = 8; - return last ? finish_started : need_more; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(deflate_state *s, int flush) { - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart + 2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, (int)s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(deflate_state *s, int flush) { - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart + 2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart - 1, s->prev_match, (int)s->prev_length); - - _tr_tally_dist(s, s->strstart - 1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart - 1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length - 1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (uInt)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window + (uInt)(s->window_size - 1), - "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, (int)s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/vendor/zlib/deflate.h b/vendor/zlib/deflate.h deleted file mode 100644 index 0732ba83a..000000000 --- a/vendor/zlib/deflate.h +++ /dev/null @@ -1,383 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2026 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at - the cost of a larger memory footprint */ -/* #define LIT_MEM */ - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ -#ifdef GZIP -# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ -#endif -#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ -#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ -#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ -#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ -#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ -#define FINISH_STATE 666 /* stream complete */ -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - const static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - ulg pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - ulg gzindex; /* where in extra, name, or comment */ - Byte method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - -#ifdef LIT_MEM -# define LIT_BUFS 5 - ushf *d_buf; /* buffer for distances */ - uchf *l_buf; /* buffer for literals/lengths */ -#else -# define LIT_BUFS 4 - uchf *sym_buf; /* buffer for distances and literals/lengths */ -#endif - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt sym_next; /* running index in symbol buffer */ - uInt sym_end; /* symbol table full when sym_next reaches this */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef ZLIB_DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - int bi_used; - /* Last number of used bits when going to a byte boundary. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - - int slid; - /* True if the hash table has been slid since it was cleared. */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init(deflate_state *s); -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, - ulg stored_len, int last); -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); -void ZLIB_INTERNAL _tr_align(deflate_state *s); -void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, - ulg stored_len, int last); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef ZLIB_DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -#ifdef LIT_MEM -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->sym_next] = 0; \ - s->l_buf[s->sym_next++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->d_buf[s->sym_next] = dist; \ - s->l_buf[s->sym_next++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -#else -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->sym_buf[s->sym_next++] = (uch)dist; \ - s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ - s->sym_buf[s->sym_next++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -#endif -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/vendor/zlib/gzclose.c b/vendor/zlib/gzclose.c deleted file mode 100644 index 48d6a86f0..000000000 --- a/vendor/zlib/gzclose.c +++ /dev/null @@ -1,23 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(gzFile file) { -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/vendor/zlib/gzguts.h b/vendor/zlib/gzguts.h deleted file mode 100644 index 266305deb..000000000 --- a/vendor/zlib/gzguts.h +++ /dev/null @@ -1,216 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# undef _FILE_OFFSET_BITS -# undef _TIME_BITS -#endif - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#if defined(_WIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# ifndef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS -# endif -# ifndef _CRT_NONSTDC_NO_DEPRECATE -# define _CRT_NONSTDC_NO_DEPRECATE -# endif -#endif - -#include -#include "zlib.h" -#ifdef STDC -# include -# include -# include -#endif - -#ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200112L -#endif -#include - -#ifdef _WIN32 -# include -#endif - -#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include -# include -#endif - -#if defined(_WIN32) && !defined(WIDECHAR) -# define WIDECHAR -#endif - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#ifndef HAVE_VSNPRINTF -# if !defined(NO_vsnprintf) && \ - (defined(MSDOS) || defined(__TURBOC__) || defined(__SASC) || \ - defined(VMS) || defined(__OS400) || defined(__MVS__)) -/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef WIN32 -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# ifndef vsnprintf -# define vsnprintf _vsnprintf -# endif -# endif -# elif !defined(__STDC_VERSION__) || __STDC_VERSION__-0 < 199901L -/* Otherwise if C89/90, assume no C99 snprintf() or vsnprintf() */ -# ifndef NO_snprintf -# define NO_snprintf -# endif -# ifndef NO_vsnprintf -# define NO_vsnprintf -# endif -# endif -#endif - -/* unlike snprintf (which is required in C99), _snprintf does not guarantee - null termination of the result -- however this is only used in gzlib.c where - the result is assured to fit in the space provided */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc(uInt size); - extern void free(voidpf ptr); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifndef NO_STRERROR -# include -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading (this and - twice this must be able to fit in an unsigned type) */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer (double-sized when writing) */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int junk; /* -1 = start, 1 = junk candidate, 0 = in gzip */ - int how; /* 0: get header, 1: copy, 2: decompress */ - int again; /* true if EAGAIN or EWOULDBLOCK on last i/o */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - int reset; /* true if a reset is pending after a Z_FINISH */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state FAR *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror(DWORD error); -#endif - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -unsigned ZLIB_INTERNAL gz_intmax(void); -#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/vendor/zlib/gzlib.c b/vendor/zlib/gzlib.c deleted file mode 100644 index 7a37a96cf..000000000 --- a/vendor/zlib/gzlib.c +++ /dev/null @@ -1,609 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(__DJGPP__) -# define LSEEK llseek -#elif defined(_WIN32) && !defined(__BORLANDC__) && !defined(UNDER_CE) -# define LSEEK _lseeki64 -#elif defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); /* assumes buf is big enough */ - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(gz_statep state) { - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - state->junk = -1; /* mark first member */ - } - else /* for writing ... */ - state->reset = 0; /* no deflateReset pending */ - state->again = 0; /* no stalled i/o yet */ - state->skip = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(const void *path, int fd, const char *mode) { - gz_statep state; - z_size_t len; - int oflag = 0; -#ifdef O_EXCL - int exclusive = 0; -#endif - - /* check input */ - if (path == NULL || mode == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->err = Z_OK; /* no error yet */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; -#ifdef O_CLOEXEC - case 'e': - oflag |= O_CLOEXEC; - break; -#endif -#ifdef O_EXCL - case 'x': - exclusive = 1; - break; -#endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - break; - case 'G': - state->direct = -1; - break; -#ifdef O_NONBLOCK - case 'N': - oflag |= O_NONBLOCK; - break; -#endif - case 'T': - state->direct = 1; - break; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* direct is 0, 1 if "T", or -1 if "G" (last "G" or "T" wins) */ - if (state->mode == GZ_READ) { - if (state->direct == 1) { - /* can't force a transparent read */ - free(state); - return NULL; - } - if (state->direct == 0) - /* default when reading is auto-detect of gzip vs. transparent -- - start with a transparent assumption in case of an empty file */ - state->direct = 1; - } - else if (state->direct == -1) { - /* "G" has no meaning when writing -- disallow it */ - free(state); - return NULL; - } - /* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or - appending, direct == 0 for gzip, 1 for transparent (copy in to out) */ - - /* save the path name for error messages */ -#ifdef WIDECHAR - if (fd == -2) - len = wcstombs(NULL, path, 0); - else -#endif - len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } -#ifdef WIDECHAR - if (fd == -2) { - if (len) - wcstombs(state->path, path, len + 1); - else - *(state->path) = 0; - } - else -#endif - { -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->path, len + 1, "%s", (const char *)path); -#else - strcpy(state->path, path); -#endif - } - - /* compute the flags for open() */ - oflag |= -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | -#ifdef O_EXCL - (exclusive ? O_EXCL : 0) | -#endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); - - /* open the file with the appropriate flags (or just use fd) */ - if (fd == -1) - state->fd = open((const char *)path, oflag, 0666); -#ifdef WIDECHAR - else if (fd == -2) - state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE); -#endif - else { -#ifdef O_NONBLOCK - if (oflag & O_NONBLOCK) - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); -#endif -#ifdef O_CLOEXEC - if (oflag & O_CLOEXEC) - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC); -#endif - state->fd = fd; - } - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) { - LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ - state->mode = GZ_WRITE; /* simplify later checks */ - } - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(int fd, const char *mode) { - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); -#else - sprintf(path, "", fd); /* for debugging */ -#endif - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -#ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { - return gz_open(path, -2, mode); -} -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(gzFile file, unsigned size) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if ((size << 1) < size) - return -1; /* need to be able to double it */ - if (size < 8) - size = 8; /* needed to behave well with flushing */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else { - offset += state->past ? 0 : state->skip; - state->skip = 0; - } - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->skip = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - state->skip = offset; - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->past ? 0 : state->skip); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(gzFile file) { - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(gzFile file) { - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(gzFile file) { - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(gzFile file, int *errnum) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR && !state->again) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, return literal string when requested */ - if (err == Z_MEM_ERROR) - return; - - /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == - NULL) { - state->err = Z_MEM_ERROR; - return; - } -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); -#else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); -#endif -} - -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax(void) { -#ifdef INT_MAX - return INT_MAX; -#else - unsigned p = 1, q; - - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -#endif -} diff --git a/vendor/zlib/gzread.c b/vendor/zlib/gzread.c deleted file mode 100644 index 8b3e369da..000000000 --- a/vendor/zlib/gzread.c +++ /dev/null @@ -1,668 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. It - also needs to loop to manage the fact that read() returns an int. If the - descriptor is non-blocking and read() returns with no data in order to avoid - blocking, then gz_load() will return 0 if some data has been read, or -1 if - no data has been read. Either way, state->again is set true to indicate a - non-blocking event. If errno is non-zero on return, then there was an error - signaled from read(). *have is set to the number of bytes read. */ -local int gz_load(gz_statep state, unsigned char *buf, unsigned len, - unsigned *have) { - int ret; - unsigned get, max = ((unsigned)-1 >> 2) + 1; - - state->again = 0; - errno = 0; - *have = 0; - do { - get = len - *have; - if (get > max) - get = max; - ret = (int)read(state->fd, buf + *have, get); - if (ret <= 0) - break; - *have += (unsigned)ret; - } while (*have < len); - if (ret < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - state->again = 1; - if (*have != 0) - return 0; - } - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(gz_statep state) { - unsigned got; - z_streamp strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; - unsigned const char *q = strm->next_in; - - if (q != p) { - unsigned n = strm->avail_in; - - do { - *p++ = *q++; - } while (--n); - } - } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(gz_statep state) { - z_streamp strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* if transparent reading is disabled, which would only be at the start, or - if we're looking for a gzip member after the first one, which is not at - the start, then proceed directly to look for a gzip member next */ - if (state->direct == -1 || state->junk == 0) { - inflateReset(strm); - state->how = GZIP; - state->junk = state->junk != -1; - state->direct = 0; - return 0; - } - - /* otherwise we're at the start with auto-detect -- we check to see if the - first four bytes could be gzip header in order to decide whether or not - this will be a transparent read */ - - /* load any header bytes into the input buffer -- if the input is empty, - then it's not an error as this is a transparent read of zero bytes */ - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0 || (state->again && strm->avail_in < 4)) - /* if non-blocking input stalled before getting four bytes, then - return and wait until a later call has accumulated enough */ - return 0; - - /* see if this is (likely) gzip input -- if the first four bytes are - consistent with a gzip header, then go look for the first gzip member, - otherwise proceed to copy the input transparently */ - if (strm->avail_in > 3 && - strm->next_in[0] == 31 && strm->next_in[1] == 139 && - strm->next_in[2] == 8 && strm->next_in[3] < 32) { - inflateReset(strm); - state->how = GZIP; - state->junk = 1; - state->direct = 0; - return 0; - } - - /* doing raw i/o: copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - state->how = COPY; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. If EOF is reached when looking for more input to - complete the gzip member, then an unexpected end of file error is raised. - If there is no more input, but state->again is true, then EOF has not been - reached, and no error is raised. */ -local int gz_decomp(gz_statep state) { - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) { - ret = state->err; - break; - } - if (strm->avail_in == 0) { - if (!state->again) - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (strm->avail_out < had) - /* any decompressed data marks this as a real gzip stream */ - state->junk = 0; - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - break; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - break; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - if (state->junk == 1) { /* trailing garbage is ok */ - strm->avail_in = 0; - state->eof = 1; - state->how = LOOK; - ret = Z_OK; - break; - } - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - break; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) { - state->junk = 0; - state->how = LOOK; - return 0; - } - - /* return decompression status */ - return ret != Z_OK ? -1 : 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(gz_statep state) { - z_streamp strm = &(state->strm); - - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - break; - default: - gz_error(state, Z_STREAM_ERROR, "state corrupt"); - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip state->skip (> 0) uncompressed bytes of output. Return -1 on error, 0 - on success. */ -local int gz_skip(gz_statep state) { - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - do { - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || - (z_off64_t)state->x.have > state->skip ? - (unsigned)state->skip : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - state->skip -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - } while (state->skip); - return 0; -} - -/* Read len bytes into buf from file, or less than len up to the end of the - input. Return the number of bytes read. If zero is returned, either the end - of file was reached, or there was an error. state->err must be consulted in - that case to determine which. If there was an error, but some uncompressed - bytes were read before the error, then that count is returned. The error is - still recorded, and so is deferred until the next call. */ -local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { - z_size_t got; - unsigned n; - int err; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->skip && gz_skip(state) == -1) - return 0; - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - err = 0; - do { - /* set n to the maximum amount of len that fits in an unsigned int */ - n = (unsigned)-1; - if (n > len) - n = (unsigned)len; - - /* first just try copying data from the output buffer */ - if (state->x.have) { - if (state->x.have < n) - n = state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - if (state->err != Z_OK) - /* caught deferred error from gz_fetch() */ - err = -1; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need output data -- for small len or new stream load up our output - buffer, so that gzgetc() can be fast */ - else if (state->how == LOOK || n < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1 && state->x.have == 0) - /* if state->x.have != 0, error will be caught after copy */ - err = -1; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) /* read directly */ - err = gz_load(state, (unsigned char *)buf, n, &n); - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - state->strm.avail_out = n; - state->strm.next_out = (unsigned char *)buf; - err = gz_decomp(state); - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len && !err); - - /* note read past eof */ - if (len && state->eof) - state->past = 1; - - /* return number of bytes read into user buffer */ - return got; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { - gz_statep state; - - /* get internal structure and check that it's for reading */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ) - return -1; - - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) - return -1; - gz_error(state, Z_OK, NULL); - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); - return -1; - } - - /* read len or fewer bytes to buf */ - len = (unsigned)gz_read(state, buf, len); - - /* check for an error */ - if (len == 0) { - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->again) { - /* non-blocking input stalled after some input was read, but no - uncompressed bytes were produced -- let the application know - this isn't EOF */ - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - } - - /* return the number of bytes read */ - return (int)len; -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, - gzFile file) { - z_size_t len; - gz_statep state; - - /* get internal structure and check that it's for reading */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ) - return 0; - - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) - return 0; - gz_error(state, Z_OK, NULL); - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* read len or fewer bytes to buf, return the number of full items read */ - return len ? gz_read(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -#else -# undef gzgetc -#endif -int ZEXPORT gzgetc(gzFile file) { - unsigned char buf[1]; - gz_statep state; - - /* get internal structure and check that it's for reading */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ) - return -1; - - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) - return -1; - gz_error(state, Z_OK, NULL); - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gz_read() */ - return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; -} - -int ZEXPORT gzgetc_(gzFile file) { - return gzgetc(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(int c, gzFile file) { - gz_statep state; - - /* get internal structure and check that it's for reading */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ) - return -1; - - /* in case this was just opened, set up the input buffer */ - if (state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) - return -1; - gz_error(state, Z_OK, NULL); - - /* process a skip request */ - if (state->skip && gz_skip(state) == -1) - return -1; - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(gzFile file, char *buf, int len) { - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters, get internal structure, and check that it's for - reading */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ) - return NULL; - - /* check that there was no (serious) error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again) - return NULL; - gz_error(state, Z_OK, NULL); - - /* process a skip request */ - if (state->skip && gz_skip(state) == -1) - return NULL; - - /* copy output up to a new line, len-1 bytes, or there is no more output, - whichever comes first */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - break; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) -- return the terminated - string, or if nothing was read, NULL */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct == 1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(gzFile file) { - int ret, err; - gz_statep state; - - /* get internal structure and check that it's for reading */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/vendor/zlib/gzwrite.c b/vendor/zlib/gzwrite.c deleted file mode 100644 index 13a3700a8..000000000 --- a/vendor/zlib/gzwrite.c +++ /dev/null @@ -1,700 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on a memory allocation failure, or 0 on - success. */ -local int gz_init(gz_statep state) { - int ret; - z_streamp strm = &(state->strm); - - /* allocate input buffer (double size for gzprintf) */ - state->in = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - strm->next_in = NULL; - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file or if gz_init() - fails to allocate memory, otherwise 0. flush is assumed to be a valid - deflate() flush value. If flush is Z_FINISH, then the deflate() state is - reset to start a new gzip stream. If gz->direct is true, then simply write - to the output file without compressing, and ignore flush. */ -local int gz_comp(gz_statep state, int flush) { - int ret, writ; - unsigned have, put, max = ((unsigned)-1 >> 2) + 1; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - while (strm->avail_in) { - errno = 0; - state->again = 0; - put = strm->avail_in > max ? max : strm->avail_in; - writ = (int)write(state->fd, strm->next_in, put); - if (writ < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - state->again = 1; - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in -= (unsigned)writ; - strm->next_in += writ; - } - return 0; - } - - /* check for a pending reset */ - if (state->reset) { - /* don't start a new gzip member unless there is data to write and - we're not flushing */ - if (strm->avail_in == 0 && flush == Z_NO_FLUSH) - return 0; - deflateReset(strm); - state->reset = 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - while (strm->next_out > state->x.next) { - errno = 0; - state->again = 0; - put = strm->next_out - state->x.next > (int)max ? max : - (unsigned)(strm->next_out - state->x.next); - writ = (int)write(state->fd, state->x.next, put); - if (writ < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - state->again = 1; - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - state->x.next += writ; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = state->out; - } - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - state->reset = 1; - - /* all done, no errors */ - return 0; -} - -/* Compress state->skip (> 0) zeros to output. Return -1 on a write error or - memory allocation failure by gz_comp(), or 0 on success. state->skip is - updated with the number of successfully written zeros, in case there is a - stall on a non-blocking write destination. */ -local int gz_zero(gz_statep state) { - int first, ret; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress state->skip zeros */ - first = 1; - do { - n = GT_OFF(state->size) || (z_off64_t)state->size > state->skip ? - (unsigned)state->skip : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - ret = gz_comp(state, Z_NO_FLUSH); - n -= strm->avail_in; - state->x.pos += n; - state->skip -= n; - if (ret == -1) - return -1; - } while (state->skip); - return 0; -} - -/* Write len bytes from buf to file. Return the number of bytes written. If - the returned value is less than len, then there was an error. If the error - was a non-blocking stall, then the number of bytes consumed is returned. - For any other error, 0 is returned. */ -local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { - z_size_t put = len; - int ret; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->skip && gz_zero(state) == -1) - return 0; - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - for (;;) { - unsigned have, copy; - - if (state->strm.avail_in == 0) - state->strm.next_in = state->in; - have = (unsigned)((state->strm.next_in + state->strm.avail_in) - - state->in); - copy = state->size - have; - if (copy > len) - copy = (unsigned)len; - memcpy(state->in + have, buf, copy); - state->strm.avail_in += copy; - state->x.pos += copy; - buf = (const char *)buf + copy; - len -= copy; - if (len == 0) - break; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->again ? put - len : 0; - } - } - else { - /* consume whatever's left in the input buffer */ - if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - state->strm.next_in = (z_const Bytef *)buf; - do { - unsigned n = (unsigned)-1; - - if (n > len) - n = (unsigned)len; - state->strm.avail_in = n; - ret = gz_comp(state, Z_NO_FLUSH); - n -= state->strm.avail_in; - state->x.pos += n; - len -= n; - if (ret == -1) - return state->again ? put - len : 0; - } while (len); - } - - /* input was all buffered or compressed */ - return put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) - return 0; - gz_error(state, Z_OK, NULL); - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* write len bytes from buf (the return value will fit in an int) */ - return (int)gz_write(state, buf, len); -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, - gzFile file) { - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) - return 0; - gz_error(state, Z_OK, NULL); - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* write len bytes to buf, return the number of full items written */ - return len ? gz_write(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(gzFile file, int c) { - unsigned have; - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) - return -1; - gz_error(state, Z_OK, NULL); - - /* check for seek request */ - if (state->skip && gz_zero(state) == -1) - return -1; - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = (unsigned char)c; - strm->avail_in++; - state->x.pos++; - return c & 0xff; - } - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = (unsigned char)c; - if (gz_write(state, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(gzFile file, const char *s) { - z_size_t len, put; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) - return -1; - gz_error(state, Z_OK, NULL); - - /* write string */ - len = strlen(s); - if ((int)len < 0 || (unsigned)len != len) { - gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); - return -1; - } - put = gz_write(state, s, len); - return len && put == 0 ? -1 : (int)put; -} - -#if (((!defined(STDC) && !defined(Z_HAVE_STDARG_H)) || !defined(NO_vsnprintf)) && \ - (defined(STDC) || defined(Z_HAVE_STDARG_H) || !defined(NO_snprintf))) || \ - defined(ZLIB_INSECURE) -/* If the second half of the input buffer is occupied, write out the contents. - If there is any input remaining due to a non-blocking stall on write, move - it to the start of the buffer. Return true if this did not open up the - second half of the buffer. state->err should be checked after this to - handle a gz_comp() error. */ -local int gz_vacate(gz_statep state) { - z_streamp strm; - - strm = &(state->strm); - if (strm->next_in + strm->avail_in <= state->in + state->size) - return 0; - (void)gz_comp(state, Z_NO_FLUSH); - if (strm->avail_in == 0) { - strm->next_in = state->in; - return 0; - } - memmove(state->in, strm->next_in, strm->avail_in); - strm->next_in = state->in; - return strm->avail_in > state->size; -} -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -#include - -/* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { -#if defined(NO_vsnprintf) && !defined(ZLIB_INSECURE) -#warning "vsnprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR" -#warning "you can recompile with ZLIB_INSECURE defined to use vsprintf()" - /* prevent use of insecure vsprintf(), unless purposefully requested */ - (void)file, (void)format, (void)va; - return Z_STREAM_ERROR; -#else - int len, ret; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) - return Z_STREAM_ERROR; - gz_error(state, Z_OK, NULL); - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->err; - - /* check for seek request */ - if (state->skip && gz_zero(state) == -1) - return state->err; - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there should be - state->size bytes available after the current contents */ - ret = gz_vacate(state); - if (state->err) { - if (ret && state->again) { - /* There was a non-blocking stall on write, resulting in the part - of the second half of the output buffer being occupied. Return - a Z_BUF_ERROR to let the application know that this gzprintf() - needs to be retried. */ - gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); - } - if (!state->again) - return state->err; - } - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(next, format, va); - for (len = 0; len < state->size; len++) - if (next[len] == 0) break; -# else - len = vsprintf(next, format, va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(next, state->size, format, va); - len = strlen(next); -# else - len = vsnprintf(next, state->size, format, va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position */ - strm->avail_in += (unsigned)len; - state->x.pos += len; - - /* write out buffer if more than half is occupied */ - ret = gz_vacate(state); - if (state->err && !state->again) - return state->err; - return len; -#endif -} - -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = gzvprintf(file, format, va); - va_end(va); - return ret; -} - -#else /* !STDC && !Z_HAVE_STDARG_H */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, - int a4, int a5, int a6, int a7, int a8, int a9, int a10, - int a11, int a12, int a13, int a14, int a15, int a16, - int a17, int a18, int a19, int a20) { -#if defined(NO_snprintf) && !defined(ZLIB_INSECURE) -#warning "snprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR" -#warning "you can recompile with ZLIB_INSECURE defined to use sprintf()" - /* prevent use of insecure sprintf(), unless purposefully requested */ - (void)file, (void)format, (void)a1, (void)a2, (void)a3, (void)a4, (void)a5, - (void)a6, (void)a7, (void)a8, (void)a9, (void)a10, (void)a11, (void)a12, - (void)a13, (void)a14, (void)a15, (void)a16, (void)a17, (void)a18, - (void)a19, (void)a20; - return Z_STREAM_ERROR; -#else - int ret; - unsigned len, left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return Z_STREAM_ERROR; - - /* check that we're writing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) - return Z_STREAM_ERROR; - gz_error(state, Z_OK, NULL); - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->err; - - /* check for seek request */ - if (state->skip && gz_zero(state) == -1) - return state->err; - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - ret = gz_vacate(state); - if (state->err) { - if (ret && state->again) { - /* There was a non-blocking stall on write, resulting in the part - of the second half of the output buffer being occupied. Return - a Z_BUF_ERROR to let the application know that this gzprintf() - needs to be retried. */ - gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf"); - } - if (!state->again) - return state->err; - } - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(strm->next_in + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, - a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (next[len] == 0) - break; -# else - len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, - a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(next); -# else - len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += len; - state->x.pos += len; - - /* write out buffer if more than half is occupied */ - ret = gz_vacate(state); - if (state->err && !state->again) - return state->err; - return (int)len; -#endif -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(gzFile file, int flush) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again)) - return Z_STREAM_ERROR; - gz_error(state, Z_OK, NULL); - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->skip && gz_zero(state) == -1) - return state->err; - - /* compress remaining data with requested flush */ - (void)gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're compressing and that there's no (serious) error */ - if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again) || - state->direct) - return Z_STREAM_ERROR; - gz_error(state, Z_OK, NULL); - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->skip && gz_zero(state) == -1) - return state->err; - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(gzFile file) { - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->skip && gz_zero(state) == -1) - ret = state->err; - - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} diff --git a/vendor/zlib/infback.c b/vendor/zlib/infback.c deleted file mode 100644 index e6443feb4..000000000 --- a/vendor/zlib/infback.c +++ /dev/null @@ -1,581 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, - unsigned char FAR *window, const char *version, - int stream_size) { - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - state->sane = 1; - return Z_OK; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc) { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - inflate_fixed(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - default: - strm->msg = (z_const char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (z_const char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (z_const char *) - "too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (z_const char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (z_const char *) - "invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (z_const char *) - "invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (z_const char *) - "invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (z_const char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (z_const char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - /* fallthrough */ - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (z_const char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (z_const char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (z_const char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly */ - ret = Z_STREAM_END; - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: - /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Write leftover output and return unused input */ - inf_leave: - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left) && - ret == Z_STREAM_END) - ret = Z_BUF_ERROR; - } - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(z_streamp strm) { - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/vendor/zlib/inffast.c b/vendor/zlib/inffast.c deleted file mode 100644 index d1657f3f3..000000000 --- a/vendor/zlib/inffast.c +++ /dev/null @@ -1,321 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") -#else - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code const *here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode + (hold & lmask); - dolen: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op == 0) { /* literal */ - Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here->val)); - *out++ = (unsigned char)(here->val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode + (hold & dmask); - dodist: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (z_const char *) - "invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = (z_const char *) - "invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode + here->val + (hold & ((1U << op) - 1)); - goto dodist; - } - else { - strm->msg = (z_const char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode + here->val + (hold & ((1U << op) - 1)); - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (z_const char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/vendor/zlib/inffast.h b/vendor/zlib/inffast.h deleted file mode 100644 index 49c6d156c..000000000 --- a/vendor/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/vendor/zlib/inffixed.h b/vendor/zlib/inffixed.h deleted file mode 100644 index 05ce88e4f..000000000 --- a/vendor/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ -/* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - -/* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - -static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} -}; - -static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} -}; diff --git a/vendor/zlib/inflate.c b/vendor/zlib/inflate.c deleted file mode 100644 index 5f5d4922b..000000000 --- a/vendor/zlib/inflate.c +++ /dev/null @@ -1,1413 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -local int inflateStateCheck(z_streamp strm) { - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->data_type = 0; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->flags = -1; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - if (windowBits < -15) - return Z_STREAM_ERROR; - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, - const char *version, int stream_size) { - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - zmemzero(state, sizeof(struct inflate_state)); - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(z_streamp strm, const char *version, - int stream_size) { - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - if (bits == 0) - return Z_OK; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned long)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE_CHECK(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(z_streamp strm, int flush) { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (z_const char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (z_const char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (z_const char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - state->flags = 0; /* indicate zlib header */ - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (z_const char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (z_const char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - /* fallthrough */ - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - /* fallthrough */ - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - /* fallthrough */ - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - /* fallthrough */ - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL && - (len = state->head->extra_len - state->length) < - state->head->extra_max) { - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - /* fallthrough */ - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - /* fallthrough */ - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - /* fallthrough */ - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (z_const char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - /* fallthrough */ - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - /* fallthrough */ - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - inflate_fixed(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - default: - strm->msg = (z_const char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (z_const char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case COPY_: - state->mode = COPY; - /* fallthrough */ - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (z_const char *) - "too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - /* fallthrough */ - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = state->distcode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (z_const char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - /* fallthrough */ - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (z_const char *) - "invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (z_const char *) - "invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (z_const char *) - "invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (z_const char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (z_const char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case LEN_: - state->mode = LEN; - /* fallthrough */ - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (z_const char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - /* fallthrough */ - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - /* fallthrough */ - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (z_const char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - /* fallthrough */ - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (z_const char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - /* fallthrough */ - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (z_const char *) - "invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, put - out, out); - out = left; - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (z_const char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - /* fallthrough */ - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { - strm->msg = (z_const char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - /* fallthrough */ - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - /* fallthrough */ - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(z_streamp strm) { - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, - uInt *dictLength) { - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, - uInt dictLength) { - struct inflate_state FAR *state; - unsigned long dictid; - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, - unsigned len) { - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(z_streamp strm) { - unsigned len; /* number of bytes to look at or looked at */ - int flags; /* temporary to save header status */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold >>= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - if (state->flags == -1) - state->wrap = 0; /* if no header yet, treat as raw */ - else - state->wrap &= ~4; /* no point in computing a check value now */ - flags = state->flags; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->flags = flags; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - zmemzero(copy, sizeof(struct inflate_state)); - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) - zmemcpy(window, state->window, state->whave); - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate(z_streamp strm, int check) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check && state->wrap) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -long ZEXPORT inflateMark(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} diff --git a/vendor/zlib/inflate.h b/vendor/zlib/inflate.h deleted file mode 100644 index f758e0dcc..000000000 --- a/vendor/zlib/inflate.h +++ /dev/null @@ -1,126 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2019 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags, 0 if zlib, or - -1 if raw or no header yet */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in hold */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/vendor/zlib/inftrees.c b/vendor/zlib/inftrees.c deleted file mode 100644 index dcbc64e05..000000000 --- a/vendor/zlib/inftrees.c +++ /dev/null @@ -1,424 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif -#ifdef BUILDFIXED -# define Z_ONCE -#endif - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" - -#ifndef NULL -# define NULL 0 -#endif - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.3.2 Copyright 1995-2026 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work) { - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base = NULL; /* base value table to use */ - const unsigned short FAR *extra = NULL; /* extra bits table to use */ - unsigned match = 0; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 75}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - case DISTS: - base = dbase; - extra = dext; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} - -#ifdef BUILDFIXED -/* - If this is compiled with BUILDFIXED defined, and if inflate will be used in - multiple threads, and if atomics are not available, then inflate() must be - called with a fixed block (e.g. 0x03 0x00) to initialize the tables and must - return before any other threads are allowed to call inflate. - */ - -static code *lenfix, *distfix; -static code fixed[544]; - -/* State for z_once(). */ -local z_once_t built = Z_ONCE_INIT; - -local void buildtables(void) { - unsigned sym, bits; - static code *next; - unsigned short lens[288], work[288]; - - /* literal/length table */ - sym = 0; - while (sym < 144) lens[sym++] = 8; - while (sym < 256) lens[sym++] = 9; - while (sym < 280) lens[sym++] = 7; - while (sym < 288) lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, lens, 288, &(next), &(bits), work); - - /* distance table */ - sym = 0; - while (sym < 32) lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, lens, 32, &(next), &(bits), work); -} -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications if atomics are not available, as it will - not be thread-safe. - */ -void inflate_fixed(struct inflate_state FAR *state) { -#ifdef BUILDFIXED - z_once(&built, buildtables); -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that will be #include'd above. Defining MAKEFIXED - also defines BUILDFIXED, so the tables are built on the fly. main() writes - those tables to stdout, which would directed to inffixed.h. Compile this - along with zutil.c: - - cc -DMAKEFIXED -o fix inftrees.c zutil.c - ./fix > inffixed.h - */ -int main(void) { - unsigned low, size; - struct inflate_state state; - - inflate_fixed(&state); - puts("/* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts("/* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf("static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n};"); - size = 1U << 5; - printf("\nstatic const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n};"); - return 0; -} -#endif /* MAKEFIXED */ diff --git a/vendor/zlib/inftrees.h b/vendor/zlib/inftrees.h deleted file mode 100644 index 84d053697..000000000 --- a/vendor/zlib/inftrees.h +++ /dev/null @@ -1,64 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2026 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns 852, and "enough 30 6 15" for distance codes returns 592. The - initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work); -struct inflate_state; -void ZLIB_INTERNAL inflate_fixed(struct inflate_state FAR *state); diff --git a/vendor/zlib/trees.c b/vendor/zlib/trees.c deleted file mode 100644 index 8e4da01e9..000000000 --- a/vendor/zlib/trees.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2026 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef ZLIB_DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -#ifdef NO_INIT_GLOBAL_POINTERS -# define TCONST -#else -# define TCONST const -#endif - -local TCONST static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local TCONST static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local TCONST static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(unsigned code, int len) { - unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(deflate_state *s) { - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(deflate_state *s) { - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_used = ((s->bi_valid - 1) & 7) + 1; - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~(ulg)7; -#endif -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = (ush)bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); - } -} - -#ifdef GEN_TREES_H -local void gen_trees_header(void); -#endif - -#ifndef ZLIB_DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* !ZLIB_DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef ZLIB_DEBUG -local void send_bits(deflate_state *s, int value, int length) { - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !ZLIB_DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = (int)value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* ZLIB_DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init(void) { -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = (uch)code; - } - } - Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256 + dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Generate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width) - 1 ? ",\n" : ", ")) - -void gen_trees_header(void) { - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(deflate_state *s) { - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->sym_next = s->matches = 0; -} - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(deflate_state *s) { - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->bi_used = 0; -#ifdef ZLIB_DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(deflate_state *s, ct_data *tree, int k) { - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(deflate_state *s, tree_desc *desc) { - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n - base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (unsigned)(bits + xbits); - if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); - } - if (overflow == 0) return; - - Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -#ifdef DUMP_BL_TREE -# include -#endif - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(deflate_state *s, tree_desc *desc) { - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code + 1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += (ush)count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree(deflate_state *s, ct_data *tree, int max_code) { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code + 1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(deflate_state *s) { - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except the - * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; - Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(deflate_state *s, int lcodes, int dcodes, - int blcodes) { - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, - ulg stored_len, int last) { - send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, (ush)stored_len); - put_short(s, (ush)~stored_len); - if (stored_len) - zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); - s->pending += stored_len; -#ifdef ZLIB_DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - s->bits_sent += 2*16; - s->bits_sent += stored_len << 3; -#endif -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(deflate_state *s) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef ZLIB_DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(deflate_state *s, const ct_data *ltree, - const ct_data *dtree) { - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in symbol buffers */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->sym_next != 0) do { -#ifdef LIT_MEM - dist = s->d_buf[sx]; - lc = s->l_buf[sx++]; -#else - dist = s->sym_buf[sx++] & 0xff; - dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; - lc = s->sym_buf[sx++]; -#endif - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, (int)dist, extra); /* send the extra bits */ - } - } /* literal or match pair ? */ - - /* Check for no overlay of pending_buf on needed symbols */ -#ifdef LIT_MEM - Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); -#else - Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); -#endif - - } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(deflate_state *s) { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long block_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>= 1) - if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("allow-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, - ulg stored_len, int last) { - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len + 3 + 7) >> 3; - static_lenb = (s->static_len + 3 + 7) >> 3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->sym_next / 3)); - -#ifndef FORCE_STATIC - if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) -#endif - opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len + 4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - - } else if (static_lenb == opt_lenb) { - send_bits(s, (STATIC_TREES<<1) + last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1) + last, 3); - send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, - max_blindex + 1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef ZLIB_DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, - s->compressed_len - 7*(ulg)last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { -#ifdef LIT_MEM - s->d_buf[s->sym_next] = (ush)dist; - s->l_buf[s->sym_next++] = (uch)lc; -#else - s->sym_buf[s->sym_next++] = (uch)dist; - s->sym_buf[s->sym_next++] = (uch)(dist >> 8); - s->sym_buf[s->sym_next++] = (uch)lc; -#endif - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - return (s->sym_next == s->sym_end); -} diff --git a/vendor/zlib/trees.h b/vendor/zlib/trees.h deleted file mode 100644 index d35639d82..000000000 --- a/vendor/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/vendor/zlib/uncompr.c b/vendor/zlib/uncompr.c deleted file mode 100644 index 2195e7855..000000000 --- a/vendor/zlib/uncompr.c +++ /dev/null @@ -1,101 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. *sourceLen is - the byte length of the source buffer. Upon entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, - *destLen is the size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, or - Z_DATA_ERROR if the input data was corrupted, including if the input data is - an incomplete zlib stream. - - The _z versions of the functions take size_t length arguments. -*/ -int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, - z_size_t *sourceLen) { - z_stream stream; - int err; - const uInt max = (uInt)-1; - z_size_t len, left; - - if (sourceLen == NULL || (*sourceLen > 0 && source == NULL) || - destLen == NULL || (*destLen > 0 && dest == NULL)) - return Z_STREAM_ERROR; - - len = *sourceLen; - left = *destLen; - if (left == 0 && dest == Z_NULL) - dest = (Bytef *)&stream.reserved; /* next_out cannot be NULL */ - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (z_size_t)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (z_size_t)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - /* Set len and left to the unused input data and unused output space. Set - *sourceLen to the amount of input consumed. Set *destLen to the amount - of data produced. */ - len += stream.avail_in; - left += stream.avail_out; - *sourceLen -= len; - *destLen -= left; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && len == 0 ? Z_DATA_ERROR : - err; -} -int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong *sourceLen) { - int ret; - z_size_t got = *destLen, used = *sourceLen; - ret = uncompress2_z(dest, &got, source, &used); - *sourceLen = (uLong)used; - *destLen = (uLong)got; - return ret; -} -int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, - z_size_t sourceLen) { - z_size_t used = sourceLen; - return uncompress2_z(dest, destLen, source, &used); -} -int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) { - uLong used = sourceLen; - return uncompress2(dest, destLen, source, &used); -} diff --git a/vendor/zlib/zconf.h b/vendor/zlib/zconf.h deleted file mode 100644 index 828ca617e..000000000 --- a/vendor/zlib/zconf.h +++ /dev/null @@ -1,551 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compress_z z_compress_z -# define compress2_z z_compress2_z -# define compressBound z_compressBound -# define compressBound_z z_compressBound_z -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_combine_gen z_crc32_combine_gen -# define crc32_combine_gen64 z_crc32_combine_gen64 -# define crc32_combine_op z_crc32_combine_op -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateBound_z z_deflateBound_z -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflateUsed z_deflateUsed -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# define inflate_fixed z_inflate_fixed -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# define uncompress_z z_uncompress_z -# define uncompress2_z z_uncompress2_z -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#ifndef z_const -# ifdef ZLIB_CONST -# define z_const const -# else -# define z_const -# endif -#endif - -#ifdef Z_SOLO -# ifdef _WIN64 - typedef unsigned long long z_size_t; -# else - typedef unsigned long z_size_t; -# endif -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#if HAVE_UNISTD_H-0 /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#if HAVE_STDARG_H-0 /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#ifndef Z_HAVE_UNISTD_H -# if defined(__WATCOMC__) || defined(__GO32__) || \ - (defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)) -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#elif defined(__MINGW32__) -# define z_off64_t long long -#elif defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -#elif defined(__GO32__) -# define z_off64_t offset_t -#else -# define z_off64_t z_off_t -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/vendor/zlib/zlib.h b/vendor/zlib/zlib.h deleted file mode 100644 index a57d33613..000000000 --- a/vendor/zlib/zlib.h +++ /dev/null @@ -1,2057 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3.2, February 17th, 2026 - - Copyright (C) 1995-2026 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 at https://datatracker.ietf.org/doc/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#ifdef ZLIB_BUILD -# include -#else -# include "zconf.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.3.2" -#define ZLIB_VERNUM 0x1320 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 2 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); -typedef void (*free_func)(voidpf opaque, voidpf address); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion(void); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. total_in, total_out, adler, and msg are initialized. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more output - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six when the flush marker begins, in order to avoid - repeated flush markers upon calling deflate() again when avail_out == 0. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit(z_streamp strm); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provided input is not - read or consumed. The allocation of a sliding window will be deferred to - the first call of inflate (if the decompression does not complete on the - first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. total_in, total_out, adler, and - msg are initialized. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_in are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the input taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy); - - This is another version of deflateInit with more compression options. The - fields zalloc, zfree and opaque must be initialized before by the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_RLE to limit match distances to one (run-length - encoding), or Z_HUFFMAN_ONLY to force Huffman encoding only (no string - matching). Filtered data consists mostly of small values with a somewhat - random distribution, as produced by the PNG filters. In this case, the - compression algorithm is tuned to compress them better. The effect of - Z_FILTERED is to force more Huffman coding and less string matching than the - default; it is intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. - Z_RLE is almost as fast as Z_HUFFMAN_ONLY, but should give better - compression for PNG image data than Huffman only. The degree of string - matching from most to none is: Z_DEFAULT_STRATEGY, Z_FILTERED, Z_RLE, then - Z_HUFFMAN_ONLY. The strategy parameter affects the compression ratio but - never the correctness of the compressed output, even if it is not set - optimally for the given data. Z_FIXED uses the default string matching, but - prevents the use of dynamic Huffman codes, allowing for a simpler decoder - for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, - const Bytef *dictionary, - uInt dictLength); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, - Bytef *dictionary, - uInt *dictLength); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similarly, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, - z_streamp source); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset(z_streamp strm); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. total_in, total_out, adler, and msg are initialized. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams(z_streamp strm, - int level, - int strategy); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, and if there have been any deflate() calls since the - state was initialized or reset, then the input available so far is - compressed with the old level and strategy using deflate(strm, Z_BLOCK). - There are three approaches for the compression levels 0, 1..3, and 4..9 - respectively. The new level and strategy will take effect at the next call - of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune(z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen); -ZEXTERN z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. - - delfateBound_z() is the same, but takes and returns a size_t length. Note - that a long is 32 bits on Windows. -*/ - -ZEXTERN int ZEXPORT deflatePending(z_streamp strm, - unsigned *pending, - int *bits); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. If an int is 16 bits and memLevel is 9, then - it is possible for the number of pending bytes to not fit in an unsigned. In - that case Z_BUF_ERROR is returned and *pending is set to the maximum value - of an unsigned. - */ - -ZEXTERN int ZEXPORT deflateUsed(z_streamp strm, - int *bits); -/* - deflateUsed() returns in *bits the most recent number of deflate bits used - in the last byte when flushing to a byte boundary. The result is in 1..8, or - 0 if there has not yet been a flush. This helps determine the location of - the last bit of a deflate stream. - - deflateUsed returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, - int bits, - int value); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, - gz_headerp head); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to the current operating system, with no - extra, name, or comment fields. The gzip header is returned to the default - state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, - int windowBits); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will *not* automatically decode concatenated gzip members. - inflate() will return Z_STREAM_END at the end of the gzip member. The state - would need to be reset to continue decoding a subsequent gzip member. This - *must* be done if there is more data after a gzip member, in order for the - decompression to be compliant with the gzip standard (RFC 1952). - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, - const Bytef *dictionary, - uInt dictLength); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, - Bytef *dictionary, - uInt *dictLength); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similarly, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync(z_streamp strm); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, - z_streamp source); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset(z_streamp strm); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - total_in, total_out, adler, and msg are initialized. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, - int windowBits); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, - int bits, - int value); -/* - This function inserts bits in the inflate input stream. The intent is to - use inflatePrime() to start inflating at a bit position in the middle of a - byte. The provided bits will be used before any bytes are used from - next_in. This function should be used with raw inflate, before the first - inflate() call, after inflateInit2() or inflateReset(). It can also be used - after an inflate() return indicates the end of a deflate block or header - when using Z_BLOCK. bits must be less than or equal to 16, and that many of - the least significant bits of value will be inserted in the input. The - other bits in value can be non-zero, and will be ignored. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent, or if bits is out of range. If inflate was - in the middle of processing a header, trailer, or stored block lengths, then - it is possible for there to be only eight bits available in the bit buffer. - In that case, bits > 8 is considered out of range. However, when used as - outlined above, there will always be 16 bits available in the buffer for - insertion. As noted in its documentation above, inflate records the number - of bits in the bit buffer on return in data_type. 32 minus that is the - number of bits available for insertion. inflatePrime does not update - data_type with the new number of bits in buffer. -*/ - -ZEXTERN long ZEXPORT inflateMark(z_streamp strm); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, - gz_headerp head); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) The extra, name, and comment pointers - much each be either Z_NULL or point to space to store that information from - the header. If extra is not Z_NULL, then extra_max contains the maximum - number of bytes that can be written to extra. Once done is true, extra_len - contains the actual extra field length, and extra contains the extra field, - or that field truncated if extra_max is less than extra_len. If name is not - Z_NULL, then up to name_max characters, including the terminating zero, are - written there. If comment is not Z_NULL, then up to comm_max characters, - including the terminating zero, are written there. The application can tell - that the name or comment did not fit in the provided space by the absence of - a terminating zero. If any of extra, name, or comment are not present in - the header, then that field's pointer is set to Z_NULL. This allows the use - of deflateSetHeader() with the returned structure to duplicate the header. - Note that if those fields initially pointed to allocated memory, then the - application will need to save them elsewhere so that they can be eventually - freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, - unsigned char FAR *window); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func)(void FAR *, - z_const unsigned char FAR * FAR *); -typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); - -ZEXTERN int ZEXPORT inflateBack(z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags(void); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (all zeros is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() is not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - 27: 0 = gzprintf() present, 1 = not -- 1 means gzprintf() returns an error - - Remainder: - 28-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. The _z versions of the functions use the size_t - type for lengths. Note that a long is 32 bits on Windows. -*/ - -ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen); -ZEXTERN int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, - const Bytef *source, z_size_t sourceLen); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level); -ZEXTERN int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, - const Bytef *source, z_size_t sourceLen, - int level); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); -ZEXTERN z_size_t ZEXPORT compressBound_z(z_size_t sourceLen); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen); -ZEXTERN int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, - const Bytef *source, z_size_t sourceLen); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. On entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) On exit, *destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen); -ZEXTERN int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, - const Bytef *source, z_size_t *sourceLen); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); - - Open the gzip (.gz) file at path for reading and decompressing, or - compressing and writing. The mode parameter is as in fopen ("rb" or "wb") - but can also include a compression level ("wb9") or a strategy: 'f' for - filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", - 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression - as in "wb9F". (See the description of deflateInit2 for more information - about the strategy parameter.) 'T' will request transparent writing or - appending with no compression and not using the gzip format. 'T' cannot be - used to force transparent reading. Transparent reading is automatically - performed if there is no gzip header at the start. Transparent reading can - be disabled with the 'G' option, which will instead return an error if there - is no gzip header. 'N' will open the file in non-blocking mode. - - 'a' can be used instead of 'w' to request that the gzip stream that will - be written be appended to the file. '+' will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - 'x' when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of 'e' when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. Note that if 'N' is in mode for non-blocking, the - open() itself can fail in order to not block. In that case gzopen() will - return NULL and errno will be EAGAIN or ENONBLOCK. The call to gzopen() can - then be re-tried. If the application would like to block on opening the - file, then it can use open() without O_NONBLOCK, and then gzdopen() with the - resulting file descriptor and 'N' in the mode, which will set it to non- - blocking. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); -/* - Associate a gzFile with the file descriptor fd. File descriptors are - obtained from calls like open, dup, creat, pipe or fileno (if the file has - been previously opened with fopen). The mode parameter is as in gzopen. An - 'e' in mode will set fd's flag to close the file on an execve() call. An 'N' - in mode will set fd's non-blocking flag. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); -/* - Set the internal buffer size used by this library's functions for file to - size. The default buffer size is 8192 bytes. This function must be called - after gzopen() or gzdopen(), and before any other calls that read or write - the file. The buffer memory allocation is always deferred to the first read - or write. Three times that size in buffer space is allocated. A larger - buffer size of, for example, 64K or 128K bytes will noticeably increase the - speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); -/* - Dynamically update the compression level and strategy for file. See the - description of deflateInit2 for the meaning of these parameters. Previously - provided data is flushed before applying the parameter changes. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); -/* - Read and decompress up to len uncompressed bytes from file into buf. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread can be used to read a gzip file on a non-blocking device. If the - input stalls and there is no uncompressed data to return, then gzread() will - return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be - called again. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. If some data was read before an error, then that data is - returned until exhausted, after which the next call will signal the error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, - gzFile file); -/* - Read and decompress up to nitems items of size size from file into buf, - otherwise operating as gzread() does. This duplicates the interface of - stdio's fread(), with size_t request and return types. If the library - defines size_t, then z_size_t is identical to size_t. If not, then z_size_t - is an unsigned integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevertheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as that of fread() implementations in common libraries. This - could result in data loss if used with size != 1 when reading a concurrently - written file or a non-blocking file. In that case, use size == 1 or gzread() - instead. -*/ - -ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); -/* - Compress and write the len uncompressed bytes at buf to file. gzwrite - returns the number of uncompressed bytes written, or 0 in case of error or - if len is 0. If the write destination is non-blocking, then gzwrite() may - return a number of bytes written that is not 0 and less than len. - - If len does not fit in an int, then 0 is returned and nothing is written. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, - z_size_t nitems, gzFile file); -/* - Compress and write nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. - - If writing a concurrently read file or a non-blocking file with size != 1, - a partial item could be written, with no way of knowing how much of it was - not written, resulting in data loss. In that case, use size == 1 or - gzwrite() instead. -*/ - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); -#else -ZEXTERN int ZEXPORTVA gzprintf(); -#endif -/* - Convert, format, compress, and write the arguments (...) to file under - control of the string format, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. - - In that last case, there may also be a buffer overflow with unpredictable - consequences, which is possible only if zlib was compiled with the insecure - functions sprintf() or vsprintf(), because the secure snprintf() and - vsnprintf() functions were not available. That would only be the case for - a non-ANSI C compiler. zlib may have been built without gzprintf() because - secure functions were not available and having gzprintf() be insecure was - not an option, in which case, gzprintf() returns Z_STREAM_ERROR. All of - these possibilities can be determined using zlibCompileFlags(). - - If a Z_BUF_ERROR is returned, then nothing was written due to a stall on - the non-blocking write destination. -*/ - -ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); -/* - Compress and write the given null-terminated string s to file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. - The number of characters written may be less than the length of the string - if the write destination is non-blocking. - - If the length of the string does not fit in an int, then -1 is returned - and nothing is written. -*/ - -ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); -/* - Read and decompress bytes from file into buf, until len-1 characters are - read, or until a newline character is read and transferred to buf, or an - end-of-file condition is encountered. If any characters are read or if len - is one, the string is terminated with a null character. If no characters - are read due to an end-of-file or len is less than one, then the buffer is - left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If some data was read before an error, - then that data is returned until exhausted, after which the next call will - return NULL to signal the error. - - gzgets can be used on a file being concurrently written, and on a non- - blocking device, both as for gzread(). However lines may be broken in the - middle, leaving it up to the application to reassemble them as needed. -*/ - -ZEXTERN int ZEXPORT gzputc(gzFile file, int c); -/* - Compress and write c, converted to an unsigned char, into file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc(gzFile file); -/* - Read and decompress one byte from file. gzgetc returns this byte or -1 in - case of end of file or error. If some data was read before an error, then - that data is returned until exhausted, after which the next call will return - -1 to signal the error. - - This is implemented as a macro for speed. As such, it does not do all of - the checking the other functions do. I.e. it does not check to see if file - is NULL, nor whether the structure file points to has been clobbered or not. - - gzgetc can be used to read a gzip file on a non-blocking device. If the - input stalls and there is no uncompressed data to return, then gzgetc() will - return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be - called again. -*/ - -ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); -/* - Push c back onto the stream for file to be read as the first character on - the next read. At least one character of push-back is always allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). - - gzungetc(-1, file) will force any pending seek to execute. Then gztell() - will report the position, even if the requested seek reached end of file. - This can be used to determine the number of uncompressed bytes in a gzip - file without having to read it into a buffer. -*/ - -ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); -/* - Flush all pending output to file. The parameter flush is as in the - deflate() function. The return value is the zlib error number (see function - gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, - z_off_t offset, int whence); - - Set the starting position to offset relative to whence for the next gzread - or gzwrite on file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. For reading or writing, any actual seeking is deferred - until the next read or write operation, or close operation when writing. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind(gzFile file); -/* - Rewind file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell(gzFile file); - - Return the starting position for the next gzread or gzwrite on file. - This position represents a number of bytes in the uncompressed data stream, - and is zero when starting, even if appending or reading a gzip stream from - the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); - - Return the current compressed (actual) read or write offset of file. This - offset includes the count of bytes that precede the gzip stream, for example - when appending or when using gzdopen() for reading. When reading, the - offset does not include as yet unused buffered input. This information can - be used for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof(gzFile file); -/* - Return true (1) if the end-of-file indicator for file has been set while - reading, false (0) otherwise. Note that the end-of-file indicator is set - only if the read tried to go past the end of the input, but came up short. - Therefore, just like feof(), gzeof() may return false even if there is no - more data to read, in the event that the last read request was for the exact - number of bytes remaining in the input file. This will happen if the input - file size is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect(gzFile file); -/* - Return true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). If the input is being written concurrently or the device is non- - blocking, then gzdirect() may give a different answer once four bytes of - input have been accumulated, which is what is needed to confirm or deny a - gzip header. Before this, gzdirect() will return true (1). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose(gzFile file); -/* - Flush all pending output for file, if necessary, close file and - deallocate the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r(gzFile file); -ZEXTERN int ZEXPORT gzclose_w(gzFile file); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); -/* - Return the error message for the last error which occurred on file. - If errnum is not NULL, *errnum is set to zlib error number. If an error - occurred in the file system and not in the compression library, *errnum is - set to Z_ERRNO and the application may consult errno to get the exact error - code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr(gzFile file); -/* - Clear the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. An Adler-32 value is in the range of a 32-bit - unsigned integer. If buf is Z_NULL, this function returns the required - initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, - z_size_t len); -/* - Same as adler32(), but with a size_t length. Note that a long is 32 bits - on Windows. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, - z_off_t len2); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. - If buf is Z_NULL, this function returns the required initial value for the - crc. Pre- and post-conditioning (one's complement) is performed within this - function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, - z_size_t len); -/* - Same as crc32(), but with a size_t length. Note that a long is 32 bits on - Windows. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. len2 must be non-negative, otherwise zero is returned. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); - - Return the operator corresponding to length len2, to be used with - crc32_combine_op(). len2 must be non-negative, otherwise zero is returned. -*/ - -ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); -/* - Give the same result as crc32_combine(), using op in place of len2. op is - is generated from len2 by crc32_combine_gen(). This will be faster than - crc32_combine() if the generated op is used more than once. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, - const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, - const char *version, int stream_size); -ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size); -ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, - const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# define z_crc32_combine_gen z_crc32_combine_gen64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# define crc32_combine_gen crc32_combine_gen64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError(int); -ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); -ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); -ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); -ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); -ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); -#if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, - const char *mode); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, - const char *format, - va_list va); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/vendor/zlib/zutil.c b/vendor/zlib/zutil.c deleted file mode 100644 index 4ea02a9c3..000000000 --- a/vendor/zlib/zutil.c +++ /dev/null @@ -1,313 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2026 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -z_const char * const z_errmsg[10] = { - (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ - (z_const char *)"stream end", /* Z_STREAM_END 1 */ - (z_const char *)"", /* Z_OK 0 */ - (z_const char *)"file error", /* Z_ERRNO (-1) */ - (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ - (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ - (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ - (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ - (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ - (z_const char *)"" -}; - - -const char * ZEXPORT zlibVersion(void) { - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags(void) { - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef ZLIB_DEBUG - flags += 1 << 8; -#endif - /* -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif - */ -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf -# ifdef ZLIB_INSECURE - flags += 1L << 25; -# else - flags += 1L << 27; -# endif -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf -# ifdef ZLIB_INSECURE - flags += 1L << 25; -# else - flags += 1L << 27; -# endif -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef ZLIB_DEBUG -#include -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error(char *m) { - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(int err) { - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 - /* The older Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(void FAR *dst, const void FAR *src, z_size_t n) { - uchf *p = dst; - const uchf *q = src; - while (n) { - *p++ = *q++; - n--; - } -} - -int ZLIB_INTERNAL zmemcmp(const void FAR *s1, const void FAR *s2, z_size_t n) { - const uchf *p = s1, *q = s2; - while (n) { - if (*p++ != *q++) - return (int)p[-1] - (int)q[-1]; - n--; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(void FAR *b, z_size_t len) { - uchf *p = b; - if (len == 0) return; - while (len) { - *p++ = 0; - len--; - } -} - -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - voidpf buf; - ulg bsize = (ulg)items*size; - - (void)opaque; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - int n; - - (void)opaque; - - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { - (void)opaque; - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - (void)opaque; - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc(uInt size); -extern voidp calloc(uInt items, uInt size); -extern void free(voidpf ptr); -#endif - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - (void)opaque; - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/vendor/zlib/zutil.h b/vendor/zlib/zutil.h deleted file mode 100644 index a9bc23ca6..000000000 --- a/vendor/zlib/zutil.h +++ /dev/null @@ -1,331 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -extern const char deflate_copyright[]; -extern const char inflate_copyright[]; -extern const char inflate9_copyright[]; - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) -# include -# if (ULONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long -# elif (ULLONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long long -# elif (ULONG_LONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long long -# elif (UINT_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned -# endif -#endif - -extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ -#if MAX_WBITS < 9 || MAX_WBITS > 15 -# error MAX_WBITS must be in 9..15 -#endif -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 1 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 2 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef __370__ -# if __TARGET_LIB__ < 0x20000000 -# define OS_CODE 4 -# elif __TARGET_LIB__ < 0x40000000 -# define OS_CODE 11 -# else -# define OS_CODE 8 -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 5 -#endif - -#ifdef OS2 -# define OS_CODE 6 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) -# define OS_CODE 7 -#endif - -#if defined(__acorn) || defined(__riscos) -# define OS_CODE 13 -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -# define OS_CODE 10 -#endif - -#ifdef _BEOS_ -# define OS_CODE 16 -#endif - -#ifdef __TOS_OS400__ -# define OS_CODE 18 -#endif - -#ifdef __APPLE__ -# define OS_CODE 19 -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#ifndef Z_LARGE64 - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 3 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy(void FAR *, const void FAR *, z_size_t); - int ZLIB_INTERNAL zmemcmp(const void FAR *, const void FAR *, z_size_t); - void ZLIB_INTERNAL zmemzero(void FAR *, z_size_t); -#endif - -/* Diagnostic functions */ -#ifdef ZLIB_DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error(char *m); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, - unsigned size); - void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#ifdef Z_ONCE -/* - Create a local z_once() function depending on the availability of atomics. - */ - -/* Check for the availability of atomics. */ -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ - !defined(__STDC_NO_ATOMICS__) - -#include -typedef struct { - atomic_flag begun; - atomic_int done; -} z_once_t; -#define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0} - -/* - Run the provided init() function exactly once, even if multiple threads - invoke once() at the same time. The state must be a once_t initialized with - Z_ONCE_INIT. - */ -local void z_once(z_once_t *state, void (*init)(void)) { - if (!atomic_load(&state->done)) { - if (atomic_flag_test_and_set(&state->begun)) - while (!atomic_load(&state->done)) - ; - else { - init(); - atomic_store(&state->done, 1); - } - } -} - -#else /* no atomics */ - -#warning zlib not thread-safe - -typedef struct z_once_s { - volatile int begun; - volatile int done; -} z_once_t; -#define Z_ONCE_INIT {0, 0} - -/* Test and set. Alas, not atomic, but tries to limit the period of - vulnerability. */ -local int test_and_set(int volatile *flag) { - int was; - - was = *flag; - *flag = 1; - return was; -} - -/* Run the provided init() function once. This is not thread-safe. */ -local void z_once(z_once_t *state, void (*init)(void)) { - if (!state->done) { - if (test_and_set(&state->begun)) - while (!state->done) - ; - else { - init(); - state->done = 1; - } - } -} - -#endif /* ?atomics */ - -#endif /* Z_ONCE */ - -#endif /* ZUTIL_H */